From 32caf0d1fe14eb69191e7828701e381b1edb340d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 5 Oct 2012 14:02:13 +0900 Subject: perf trace: Validate target task/user/cpu argument Those target options are mutually exclusive so check it before setting up target thread/cpu maps. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1349413336-26936-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index dec8ced61fb..f01fa6f736e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -323,14 +323,21 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) OPT_END() }; int err; + char bf[BUFSIZ]; argc = parse_options(argc, argv, trace_options, trace_usage, 0); if (argc) usage_with_options(trace_usage, trace_options); + err = perf_target__validate(&trace.opts.target); + if (err) { + perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf)); + printf("%s", bf); + return err; + } + err = perf_target__parse_uid(&trace.opts.target); if (err) { - char bf[BUFSIZ]; perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf)); printf("%s", bf); return err; -- cgit v1.2.3 From ee76120e2d13a2d4eb0cc88da8a8e7f7909cc276 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 5 Oct 2012 14:02:14 +0900 Subject: perf trace: Explicitly enable system-wide mode if no option is given When no target cpu/user/task option is given, perf trace will do its job system wide for all online cpus. Make it explicit to reduce possible confusion when reading code. No functional changes intended. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1349413336-26936-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index f01fa6f736e..da1183fa105 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -343,5 +343,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) return err; } + if (perf_target__none(&trace.opts.target)) + trace.opts.target.system_wide = true; + return trace__run(&trace); } -- cgit v1.2.3 From f15eb531d351163f1ea697c2dd8f15b66b01d289 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 5 Oct 2012 14:02:16 +0900 Subject: perf trace: Add support for tracing workload given by command line Now perf trace is able to trace specified workload by forking it like perf record does. And also finish the tracing if the workload quits or gets SIGINT. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1349413336-26936-5-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index da1183fa105..4e9320bf11e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -52,6 +52,13 @@ struct trace { struct perf_record_opts opts; }; +static bool done = false; + +static void sig_handler(int sig __maybe_unused) +{ + done = true; +} + static int trace__read_syscall_info(struct trace *trace, int id) { char tp_name[128]; @@ -189,11 +196,12 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, return 0; } -static int trace__run(struct trace *trace) +static int trace__run(struct trace *trace, int argc, const char **argv) { struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); struct perf_evsel *evsel; int err = -1, i, nr_events = 0, before; + const bool forks = argc > 0; if (evlist == NULL) { printf("Not enough memory to run!\n"); @@ -214,6 +222,17 @@ static int trace__run(struct trace *trace) perf_evlist__config_attrs(evlist, &trace->opts); + signal(SIGCHLD, sig_handler); + signal(SIGINT, sig_handler); + + if (forks) { + err = perf_evlist__prepare_workload(evlist, &trace->opts, argv); + if (err < 0) { + printf("Couldn't run the workload!\n"); + goto out_delete_evlist; + } + } + err = perf_evlist__open(evlist); if (err < 0) { printf("Couldn't create the events: %s\n", strerror(errno)); @@ -227,6 +246,10 @@ static int trace__run(struct trace *trace) } perf_evlist__enable(evlist); + + if (forks) + perf_evlist__start_workload(evlist); + again: before = nr_events; @@ -272,8 +295,15 @@ again: } } - if (nr_events == before) + if (nr_events == before) { + if (done) + goto out_delete_evlist; + poll(evlist->pollfd, evlist->nr_fds, -1); + } + + if (done) + perf_evlist__disable(evlist); goto again; @@ -286,7 +316,8 @@ out: int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) { const char * const trace_usage[] = { - "perf trace []", + "perf trace [] []", + "perf trace [] -- []", NULL }; struct trace trace = { @@ -326,8 +357,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) char bf[BUFSIZ]; argc = parse_options(argc, argv, trace_options, trace_usage, 0); - if (argc) - usage_with_options(trace_usage, trace_options); err = perf_target__validate(&trace.opts.target); if (err) { @@ -343,8 +372,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) return err; } - if (perf_target__none(&trace.opts.target)) + if (!argc && perf_target__none(&trace.opts.target)) trace.opts.target.system_wide = true; - return trace__run(&trace); + return trace__run(&trace, argc, argv); } -- cgit v1.2.3 From a06d143e7cfaa10626f3ad0127a9b9169f900add Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 5 Oct 2012 16:44:40 +0200 Subject: perf diff: Add -b option for perf diff to display paired entries only Adding -b option to perf diff command to display only entries with match in the baseline. Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1349448287-18919-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-diff.txt | 4 ++++ tools/perf/builtin-diff.c | 31 +++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index ab7f667de1b..6ce95858cd4 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt @@ -72,6 +72,10 @@ OPTIONS --symfs=:: Look for files with symbols relative to this directory. +-b:: +--baseline-only:: + Show only items with match in baseline. + SEE ALSO -------- linkperf:perf-record[1] diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index a0b531c14b9..1063c31e507 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -24,6 +24,7 @@ static char const *input_old = "perf.data.old", static char diff__default_sort_order[] = "dso,symbol"; static bool force; static bool show_displacement; +static bool show_baseline_only; static int hists__add_entry(struct hists *self, struct addr_location *al, u64 period) @@ -172,6 +173,31 @@ static void perf_evlist__resort_hists(struct perf_evlist *evlist, bool name) } } +static void hists__baseline_only(struct hists *hists) +{ + struct rb_node *next = rb_first(&hists->entries); + + while (next != NULL) { + struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node); + + next = rb_next(&he->rb_node); + if (!he->pair) { + rb_erase(&he->rb_node, &hists->entries); + hist_entry__free(he); + } + } +} + +static void hists__process(struct hists *old, struct hists *new) +{ + hists__match(old, new); + + if (show_baseline_only) + hists__baseline_only(new); + + hists__fprintf(new, true, 0, 0, stdout); +} + static int __cmd_diff(void) { int ret, i; @@ -213,8 +239,7 @@ static int __cmd_diff(void) first = false; - hists__match(&evsel_old->hists, &evsel->hists); - hists__fprintf(&evsel->hists, true, 0, 0, stdout); + hists__process(&evsel_old->hists, &evsel->hists); } out_delete: @@ -235,6 +260,8 @@ static const struct option options[] = { "be more verbose (show symbol address, etc)"), OPT_BOOLEAN('M', "displacement", &show_displacement, "Show position displacement relative to baseline"), + OPT_BOOLEAN('b', "baseline-only", &show_baseline_only, + "Show only items with match in baseline"), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), -- cgit v1.2.3 From 7aaf6b35512382329c5b2dd46b42f2bf12a5fff0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 5 Oct 2012 16:44:41 +0200 Subject: perf diff: Add ratio computation way to compare hist entries Adding -c option to select computation method with the current 'Delta' computation as default. Current possible values are of this option are: 'delta' and 'ratio'. Adding 'ratio' as new computation way to compare hist entries. If specified the 'Ratio' column is displayed with value 'r' computed as: r = A->period / B->period with: - A/B being matching hist entry from first/second file specified (or perf.data/perf.data.old) respectively. - period being the hist entry period value Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1349448287-18919-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-diff.txt | 33 +++++++++++++++++++++ tools/perf/builtin-diff.c | 52 ++++++++++++++++++++++++++++++++-- tools/perf/ui/hist.c | 28 ++++++++++++++++++ tools/perf/util/hist.h | 1 + 4 files changed, 112 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index 6ce95858cd4..8fff0618c59 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt @@ -76,6 +76,39 @@ OPTIONS --baseline-only:: Show only items with match in baseline. +-c:: +--compute:: + Differential computation selection - delta,ratio (default is delta). + See COMPARISON METHODS section for more info. + +COMPARISON METHODS +------------------ +delta +~~~~~ +If specified the 'Delta' column is displayed with value 'd' computed as: + + d = A->period_percent - B->period_percent + +with: + - A/B being matching hist entry from first/second file specified + (or perf.data/perf.data.old) respectively. + + - period_percent being the % of the hist entry period value within + single data file + +ratio +~~~~~ +If specified the 'Ratio' column is displayed with value 'r' computed as: + + r = A->period / B->period + +with: + - A/B being matching hist entry from first/second file specified + (or perf.data/perf.data.old) respectively. + + - period being the hist entry period value + + SEE ALSO -------- linkperf:perf-record[1] diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 1063c31e507..e90c06aea4d 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -26,6 +26,41 @@ static bool force; static bool show_displacement; static bool show_baseline_only; +enum { + COMPUTE_DELTA, + COMPUTE_RATIO, + COMPUTE_MAX, +}; + +const char *compute_names[COMPUTE_MAX] = { + [COMPUTE_DELTA] = "delta", + [COMPUTE_RATIO] = "ratio", +}; + +static int compute; + +static int setup_compute(const struct option *opt, const char *str, + int unset __maybe_unused) +{ + int *cp = (int *) opt->value; + unsigned i; + + if (!str) { + *cp = COMPUTE_DELTA; + return 0; + } + + for (i = 0; i < COMPUTE_MAX; i++) + if (!strcmp(str, compute_names[i])) { + *cp = i; + return 0; + } + + pr_err("Failed: '%s' is not computation method " + "(use 'delta' or 'ratio').\n", str); + return -EINVAL; +} + static int hists__add_entry(struct hists *self, struct addr_location *al, u64 period) { @@ -262,6 +297,9 @@ static const struct option options[] = { "Show position displacement relative to baseline"), OPT_BOOLEAN('b', "baseline-only", &show_baseline_only, "Show only items with match in baseline"), + OPT_CALLBACK('c', "compute", &compute, "delta,ratio (default delta)", + "Entries differential computation selection", + setup_compute), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), @@ -290,9 +328,19 @@ static void ui_init(void) /* No overhead column. */ perf_hpp__column_enable(PERF_HPP__OVERHEAD, false); - /* Display baseline/delta/displacement columns. */ + /* Display baseline/delta/ratio/displacement columns. */ perf_hpp__column_enable(PERF_HPP__BASELINE, true); - perf_hpp__column_enable(PERF_HPP__DELTA, true); + + switch (compute) { + case COMPUTE_DELTA: + perf_hpp__column_enable(PERF_HPP__DELTA, true); + break; + case COMPUTE_RATIO: + perf_hpp__column_enable(PERF_HPP__RATIO, true); + break; + default: + BUG_ON(1); + }; if (show_displacement) perf_hpp__column_enable(PERF_HPP__DISPL, true); diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index f5a1e4f6526..1b633a4b5c4 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -266,6 +266,33 @@ static int hpp__entry_delta(struct perf_hpp *hpp, struct hist_entry *he) return scnprintf(hpp->buf, hpp->size, fmt, buf); } +static int hpp__header_ratio(struct perf_hpp *hpp) +{ + const char *fmt = symbol_conf.field_sep ? "%s" : "%14s"; + + return scnprintf(hpp->buf, hpp->size, fmt, "Ratio"); +} + +static int hpp__width_ratio(struct perf_hpp *hpp __maybe_unused) +{ + return 14; +} + +static int hpp__entry_ratio(struct perf_hpp *hpp, struct hist_entry *he) +{ + struct hist_entry *pair = he->pair; + double new_period = he->stat.period; + double old_period = pair ? pair->stat.period : 0; + double ratio = pair ? new_period / old_period : 0; + const char *fmt = symbol_conf.field_sep ? "%s" : "%14s"; + char buf[32] = " "; + + if (ratio > 0.0) + scnprintf(buf, sizeof(buf), "%+14.6F", ratio); + + return scnprintf(hpp->buf, hpp->size, fmt, buf); +} + static int hpp__header_displ(struct perf_hpp *hpp) { return scnprintf(hpp->buf, hpp->size, "Displ."); @@ -311,6 +338,7 @@ struct perf_hpp_fmt perf_hpp__format[] = { { .cond = false, HPP__PRINT_FNS(samples) }, { .cond = false, HPP__PRINT_FNS(period) }, { .cond = false, HPP__PRINT_FNS(delta) }, + { .cond = false, HPP__PRINT_FNS(ratio) }, { .cond = false, HPP__PRINT_FNS(displ) } }; diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 66cb31fe81d..7e4d4c26221 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -141,6 +141,7 @@ enum { PERF_HPP__SAMPLES, PERF_HPP__PERIOD, PERF_HPP__DELTA, + PERF_HPP__RATIO, PERF_HPP__DISPL, PERF_HPP__MAX_INDEX -- cgit v1.2.3 From 96c47f19846742bdfa3c153c8d26ccca5945586b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 5 Oct 2012 16:44:42 +0200 Subject: perf diff: Add option to sort entries based on diff computation Adding support to sort hist entries based on the outcome of selected computation. It's now possible to specify '+' as a first character of '-c' option value to make such sort. Example: $ perf diff -c ratio -b # Event 'cache-misses' # # Baseline Ratio Shared Object Symbol # ........ .............. ................. ................................ # 19.64% 0.69 [kernel.kallsyms] [k] clear_page 0.30% 0.17 [kernel.kallsyms] [k] mm_alloc 0.04% 0.20 [kernel.kallsyms] [k] kmem_cache_alloc $ perf diff -c +ratio -b # Event 'cache-misses' # # Baseline Ratio Shared Object Symbol # ........ .............. ................. ................................ # 19.64% 0.69 [kernel.kallsyms] [k] clear_page 0.04% 0.20 [kernel.kallsyms] [k] kmem_cache_alloc 0.30% 0.17 [kernel.kallsyms] [k] mm_alloc Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1349448287-18919-4-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-diff.txt | 2 + tools/perf/builtin-diff.c | 137 +++++++++++++++++++++++++++++++++ tools/perf/ui/hist.c | 29 +++---- tools/perf/util/hist.h | 2 + tools/perf/util/sort.h | 15 ++++ 5 files changed, 167 insertions(+), 18 deletions(-) diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index 8fff0618c59..cff3d9b6e4a 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt @@ -79,6 +79,8 @@ OPTIONS -c:: --compute:: Differential computation selection - delta,ratio (default is delta). + If '+' is specified as a first character, the output is sorted based + on the computation results. See COMPARISON METHODS section for more info. COMPARISON METHODS diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index e90c06aea4d..e13cfac0b06 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -25,6 +25,7 @@ static char diff__default_sort_order[] = "dso,symbol"; static bool force; static bool show_displacement; static bool show_baseline_only; +static bool sort_compute; enum { COMPUTE_DELTA, @@ -50,6 +51,13 @@ static int setup_compute(const struct option *opt, const char *str, return 0; } + if (*str == '+') { + sort_compute = true; + str++; + if (!*str) + return 0; + } + for (i = 0; i < COMPUTE_MAX; i++) if (!strcmp(str, compute_names[i])) { *cp = i; @@ -61,6 +69,34 @@ static int setup_compute(const struct option *opt, const char *str, return -EINVAL; } +static double get_period_percent(struct hist_entry *he, u64 period) +{ + u64 total = he->hists->stats.total_period; + return (period * 100.0) / total; +} + +double perf_diff__compute_delta(struct hist_entry *he) +{ + struct hist_entry *pair = he->pair; + double new_percent = get_period_percent(he, he->stat.period); + double old_percent = pair ? get_period_percent(pair, pair->stat.period) : 0.0; + + he->diff.period_ratio_delta = new_percent - old_percent; + he->diff.computed = true; + return he->diff.period_ratio_delta; +} + +double perf_diff__compute_ratio(struct hist_entry *he) +{ + struct hist_entry *pair = he->pair; + double new_period = he->stat.period; + double old_period = pair ? pair->stat.period : 0; + + he->diff.computed = true; + he->diff.period_ratio = pair ? (new_period / old_period) : 0; + return he->diff.period_ratio; +} + static int hists__add_entry(struct hists *self, struct addr_location *al, u64 period) { @@ -223,6 +259,102 @@ static void hists__baseline_only(struct hists *hists) } } +static void hists__precompute(struct hists *hists) +{ + struct rb_node *next = rb_first(&hists->entries); + + while (next != NULL) { + struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node); + + next = rb_next(&he->rb_node); + + switch (compute) { + case COMPUTE_DELTA: + perf_diff__compute_delta(he); + break; + case COMPUTE_RATIO: + perf_diff__compute_ratio(he); + break; + default: + BUG_ON(1); + } + } +} + +static int64_t cmp_doubles(double l, double r) +{ + if (l > r) + return -1; + else if (l < r) + return 1; + else + return 0; +} + +static int64_t +hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right, + int c) +{ + switch (c) { + case COMPUTE_DELTA: + { + double l = left->diff.period_ratio_delta; + double r = right->diff.period_ratio_delta; + + return cmp_doubles(l, r); + } + case COMPUTE_RATIO: + { + double l = left->diff.period_ratio; + double r = right->diff.period_ratio; + + return cmp_doubles(l, r); + } + default: + BUG_ON(1); + } + + return 0; +} + +static void insert_hist_entry_by_compute(struct rb_root *root, + struct hist_entry *he, + int c) +{ + struct rb_node **p = &root->rb_node; + struct rb_node *parent = NULL; + struct hist_entry *iter; + + while (*p != NULL) { + parent = *p; + iter = rb_entry(parent, struct hist_entry, rb_node); + if (hist_entry__cmp_compute(he, iter, c) < 0) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + + rb_link_node(&he->rb_node, parent, p); + rb_insert_color(&he->rb_node, root); +} + +static void hists__compute_resort(struct hists *hists) +{ + struct rb_root tmp = RB_ROOT; + struct rb_node *next = rb_first(&hists->entries); + + while (next != NULL) { + struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node); + + next = rb_next(&he->rb_node); + + rb_erase(&he->rb_node, &hists->entries); + insert_hist_entry_by_compute(&tmp, he, compute); + } + + hists->entries = tmp; +} + static void hists__process(struct hists *old, struct hists *new) { hists__match(old, new); @@ -230,6 +362,11 @@ static void hists__process(struct hists *old, struct hists *new) if (show_baseline_only) hists__baseline_only(new); + if (sort_compute) { + hists__precompute(new); + hists__compute_resort(new); + } + hists__fprintf(new, true, 0, 0, stdout); } diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 1b633a4b5c4..659f2a25e99 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -242,24 +242,15 @@ static int hpp__width_delta(struct perf_hpp *hpp __maybe_unused) static int hpp__entry_delta(struct perf_hpp *hpp, struct hist_entry *he) { - struct hist_entry *pair = he->pair; - struct hists *pair_hists = pair ? pair->hists : NULL; - struct hists *hists = he->hists; - u64 old_total, new_total; - double old_percent = 0, new_percent = 0; - double diff; const char *fmt = symbol_conf.field_sep ? "%s" : "%7.7s"; char buf[32] = " "; + double diff; - old_total = pair_hists ? pair_hists->stats.total_period : 0; - if (old_total > 0 && pair) - old_percent = 100.0 * pair->stat.period / old_total; - - new_total = hists->stats.total_period; - if (new_total > 0) - new_percent = 100.0 * he->stat.period / new_total; + if (he->diff.computed) + diff = he->diff.period_ratio_delta; + else + diff = perf_diff__compute_delta(he); - diff = new_percent - old_percent; if (fabs(diff) >= 0.01) scnprintf(buf, sizeof(buf), "%+4.2F%%", diff); @@ -280,12 +271,14 @@ static int hpp__width_ratio(struct perf_hpp *hpp __maybe_unused) static int hpp__entry_ratio(struct perf_hpp *hpp, struct hist_entry *he) { - struct hist_entry *pair = he->pair; - double new_period = he->stat.period; - double old_period = pair ? pair->stat.period : 0; - double ratio = pair ? new_period / old_period : 0; const char *fmt = symbol_conf.field_sep ? "%s" : "%14s"; char buf[32] = " "; + double ratio; + + if (he->diff.computed) + ratio = he->diff.period_ratio; + else + ratio = perf_diff__compute_ratio(he); if (ratio > 0.0) scnprintf(buf, sizeof(buf), "%+14.6F", ratio); diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 7e4d4c26221..a7ea28a1d50 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -205,4 +205,6 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused, unsigned int hists__sort_list_width(struct hists *self); +double perf_diff__compute_delta(struct hist_entry *he); +double perf_diff__compute_ratio(struct hist_entry *he); #endif /* __PERF_HIST_H */ diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 5786f323b59..337aeefa245 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -52,6 +52,19 @@ struct he_stat { u32 nr_events; }; +struct hist_entry_diff { + bool computed; + + /* PERF_HPP__DISPL */ + int displacement; + + /* PERF_HPP__DELTA */ + double period_ratio_delta; + + /* PERF_HPP__RATIO */ + double period_ratio; +}; + /** * struct hist_entry - histogram entry * @@ -67,6 +80,8 @@ struct hist_entry { u64 ip; s32 cpu; + struct hist_entry_diff diff; + /* XXX These two should move to some tree widget lib */ u16 row_offset; u16 nr_rows; -- cgit v1.2.3 From 81d5f95819953321a2557b0656b24ea10af9629c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 5 Oct 2012 16:44:43 +0200 Subject: perf diff: Add weighted diff computation way to compare hist entries Adding 'wdiff' as new computation way to compare hist entries. If specified the 'Weighted diff' column is displayed with value 'd' computed as: d = B->period * WEIGHT-A - A->period * WEIGHT-B - A/B being matching hist entry from first/second file specified (or perf.data/perf.data.old) respectively. - period being the hist entry period value - WEIGHT-A/WEIGHT-B being user suplied weights in the the '-c' option behind ':' separator like '-c wdiff:1,2'. Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1349448287-18919-5-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-diff.txt | 15 ++++- tools/perf/builtin-diff.c | 116 +++++++++++++++++++++++++++++++-- tools/perf/ui/hist.c | 30 +++++++++ tools/perf/util/hist.h | 2 + tools/perf/util/sort.h | 3 + 5 files changed, 160 insertions(+), 6 deletions(-) diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index cff3d9b6e4a..fa413ac914f 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt @@ -78,7 +78,7 @@ OPTIONS -c:: --compute:: - Differential computation selection - delta,ratio (default is delta). + Differential computation selection - delta,ratio,wdiff (default is delta). If '+' is specified as a first character, the output is sorted based on the computation results. See COMPARISON METHODS section for more info. @@ -110,6 +110,19 @@ with: - period being the hist entry period value +wdiff +~~~~~ +If specified the 'Weighted diff' column is displayed with value 'd' computed as: + + d = B->period * WEIGHT-A - A->period * WEIGHT-B + + - A/B being matching hist entry from first/second file specified + (or perf.data/perf.data.old) respectively. + + - period being the hist entry period value + + - WEIGHT-A/WEIGHT-B being user suplied weights in the the '-c' option + behind ':' separator like '-c wdiff:1,2'. SEE ALSO -------- diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index e13cfac0b06..d78e8386e1a 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -27,24 +27,81 @@ static bool show_displacement; static bool show_baseline_only; static bool sort_compute; +static s64 compute_wdiff_w1; +static s64 compute_wdiff_w2; + enum { COMPUTE_DELTA, COMPUTE_RATIO, + COMPUTE_WEIGHTED_DIFF, COMPUTE_MAX, }; const char *compute_names[COMPUTE_MAX] = { [COMPUTE_DELTA] = "delta", [COMPUTE_RATIO] = "ratio", + [COMPUTE_WEIGHTED_DIFF] = "wdiff", }; static int compute; +static int setup_compute_opt_wdiff(char *opt) +{ + char *w1_str = opt; + char *w2_str; + + int ret = -EINVAL; + + if (!opt) + goto out; + + w2_str = strchr(opt, ','); + if (!w2_str) + goto out; + + *w2_str++ = 0x0; + if (!*w2_str) + goto out; + + compute_wdiff_w1 = strtol(w1_str, NULL, 10); + compute_wdiff_w2 = strtol(w2_str, NULL, 10); + + if (!compute_wdiff_w1 || !compute_wdiff_w2) + goto out; + + pr_debug("compute wdiff w1(%" PRId64 ") w2(%" PRId64 ")\n", + compute_wdiff_w1, compute_wdiff_w2); + + ret = 0; + + out: + if (ret) + pr_err("Failed: wrong weight data, use 'wdiff:w1,w2'\n"); + + return ret; +} + +static int setup_compute_opt(char *opt) +{ + if (compute == COMPUTE_WEIGHTED_DIFF) + return setup_compute_opt_wdiff(opt); + + if (opt) { + pr_err("Failed: extra option specified '%s'", opt); + return -EINVAL; + } + + return 0; +} + static int setup_compute(const struct option *opt, const char *str, int unset __maybe_unused) { int *cp = (int *) opt->value; + char *cstr = (char *) str; + char buf[50]; unsigned i; + char *option; if (!str) { *cp = COMPUTE_DELTA; @@ -53,19 +110,37 @@ static int setup_compute(const struct option *opt, const char *str, if (*str == '+') { sort_compute = true; - str++; + cstr = (char *) ++str; if (!*str) return 0; } + option = strchr(str, ':'); + if (option) { + unsigned len = option++ - str; + + /* + * The str data are not writeable, so we need + * to use another buffer. + */ + + /* No option value is longer. */ + if (len >= sizeof(buf)) + return -EINVAL; + + strncpy(buf, str, len); + buf[len] = 0x0; + cstr = buf; + } + for (i = 0; i < COMPUTE_MAX; i++) - if (!strcmp(str, compute_names[i])) { + if (!strcmp(cstr, compute_names[i])) { *cp = i; - return 0; + return setup_compute_opt(option); } pr_err("Failed: '%s' is not computation method " - "(use 'delta' or 'ratio').\n", str); + "(use 'delta','ratio' or 'wdiff')\n", str); return -EINVAL; } @@ -97,6 +172,23 @@ double perf_diff__compute_ratio(struct hist_entry *he) return he->diff.period_ratio; } +s64 perf_diff__compute_wdiff(struct hist_entry *he) +{ + struct hist_entry *pair = he->pair; + u64 new_period = he->stat.period; + u64 old_period = pair ? pair->stat.period : 0; + + he->diff.computed = true; + + if (!pair) + he->diff.wdiff = 0; + else + he->diff.wdiff = new_period * compute_wdiff_w2 - + old_period * compute_wdiff_w1; + + return he->diff.wdiff; +} + static int hists__add_entry(struct hists *self, struct addr_location *al, u64 period) { @@ -275,6 +367,9 @@ static void hists__precompute(struct hists *hists) case COMPUTE_RATIO: perf_diff__compute_ratio(he); break; + case COMPUTE_WEIGHTED_DIFF: + perf_diff__compute_wdiff(he); + break; default: BUG_ON(1); } @@ -310,6 +405,13 @@ hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right, return cmp_doubles(l, r); } + case COMPUTE_WEIGHTED_DIFF: + { + s64 l = left->diff.wdiff; + s64 r = right->diff.wdiff; + + return r - l; + } default: BUG_ON(1); } @@ -434,7 +536,8 @@ static const struct option options[] = { "Show position displacement relative to baseline"), OPT_BOOLEAN('b', "baseline-only", &show_baseline_only, "Show only items with match in baseline"), - OPT_CALLBACK('c', "compute", &compute, "delta,ratio (default delta)", + OPT_CALLBACK('c', "compute", &compute, + "delta,ratio,wdiff:w1,w2 (default delta)", "Entries differential computation selection", setup_compute), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, @@ -475,6 +578,9 @@ static void ui_init(void) case COMPUTE_RATIO: perf_hpp__column_enable(PERF_HPP__RATIO, true); break; + case COMPUTE_WEIGHTED_DIFF: + perf_hpp__column_enable(PERF_HPP__WEIGHTED_DIFF, true); + break; default: BUG_ON(1); }; diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 659f2a25e99..522b4ec051d 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -286,6 +286,35 @@ static int hpp__entry_ratio(struct perf_hpp *hpp, struct hist_entry *he) return scnprintf(hpp->buf, hpp->size, fmt, buf); } +static int hpp__header_wdiff(struct perf_hpp *hpp) +{ + const char *fmt = symbol_conf.field_sep ? "%s" : "%14s"; + + return scnprintf(hpp->buf, hpp->size, fmt, "Weighted diff"); +} + +static int hpp__width_wdiff(struct perf_hpp *hpp __maybe_unused) +{ + return 14; +} + +static int hpp__entry_wdiff(struct perf_hpp *hpp, struct hist_entry *he) +{ + const char *fmt = symbol_conf.field_sep ? "%s" : "%14s"; + char buf[32] = " "; + s64 wdiff; + + if (he->diff.computed) + wdiff = he->diff.wdiff; + else + wdiff = perf_diff__compute_wdiff(he); + + if (wdiff != 0) + scnprintf(buf, sizeof(buf), "%14ld", wdiff); + + return scnprintf(hpp->buf, hpp->size, fmt, buf); +} + static int hpp__header_displ(struct perf_hpp *hpp) { return scnprintf(hpp->buf, hpp->size, "Displ."); @@ -332,6 +361,7 @@ struct perf_hpp_fmt perf_hpp__format[] = { { .cond = false, HPP__PRINT_FNS(period) }, { .cond = false, HPP__PRINT_FNS(delta) }, { .cond = false, HPP__PRINT_FNS(ratio) }, + { .cond = false, HPP__PRINT_FNS(wdiff) }, { .cond = false, HPP__PRINT_FNS(displ) } }; diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index a7ea28a1d50..ce76f36aeb0 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -142,6 +142,7 @@ enum { PERF_HPP__PERIOD, PERF_HPP__DELTA, PERF_HPP__RATIO, + PERF_HPP__WEIGHTED_DIFF, PERF_HPP__DISPL, PERF_HPP__MAX_INDEX @@ -207,4 +208,5 @@ unsigned int hists__sort_list_width(struct hists *self); double perf_diff__compute_delta(struct hist_entry *he); double perf_diff__compute_ratio(struct hist_entry *he); +s64 perf_diff__compute_wdiff(struct hist_entry *he); #endif /* __PERF_HIST_H */ diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 337aeefa245..13761d83a5a 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -63,6 +63,9 @@ struct hist_entry_diff { /* PERF_HPP__RATIO */ double period_ratio; + + /* HISTC_WEIGHTED_DIFF */ + s64 wdiff; }; /** -- cgit v1.2.3 From 61949b212e7f6f8f31891236ba24033f9b7af8c3 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 5 Oct 2012 16:44:44 +0200 Subject: perf diff: Add -p option to display period values for hist entries Adding -p option to show period values for both compared hist entries. Showing hist column PERF_HPP__PERIOD and newly added hist column PERF_HPP__PERIOD_BASELINE. Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1349448287-18919-6-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-diff.txt | 4 ++++ tools/perf/builtin-diff.c | 10 +++++++++- tools/perf/ui/hist.c | 21 +++++++++++++++++++++ tools/perf/util/hist.h | 1 + 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index fa413ac914f..21cc2ef7756 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt @@ -83,6 +83,10 @@ OPTIONS on the computation results. See COMPARISON METHODS section for more info. +-p:: +--period:: + Show period values for both compared hist entries. + COMPARISON METHODS ------------------ delta diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index d78e8386e1a..2411dd18c55 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -24,6 +24,7 @@ static char const *input_old = "perf.data.old", static char diff__default_sort_order[] = "dso,symbol"; static bool force; static bool show_displacement; +static bool show_period; static bool show_baseline_only; static bool sort_compute; @@ -540,6 +541,8 @@ static const struct option options[] = { "delta,ratio,wdiff:w1,w2 (default delta)", "Entries differential computation selection", setup_compute), + OPT_BOOLEAN('p', "period", &show_period, + "Show period values."), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), @@ -568,7 +571,7 @@ static void ui_init(void) /* No overhead column. */ perf_hpp__column_enable(PERF_HPP__OVERHEAD, false); - /* Display baseline/delta/ratio/displacement columns. */ + /* Display baseline/delta/ratio/displacement/periods columns. */ perf_hpp__column_enable(PERF_HPP__BASELINE, true); switch (compute) { @@ -587,6 +590,11 @@ static void ui_init(void) if (show_displacement) perf_hpp__column_enable(PERF_HPP__DISPL, true); + + if (show_period) { + perf_hpp__column_enable(PERF_HPP__PERIOD, true); + perf_hpp__column_enable(PERF_HPP__PERIOD_BASELINE, true); + } } int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 522b4ec051d..2fadaff6312 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -228,6 +228,26 @@ static int hpp__entry_period(struct perf_hpp *hpp, struct hist_entry *he) return scnprintf(hpp->buf, hpp->size, fmt, he->stat.period); } +static int hpp__header_period_baseline(struct perf_hpp *hpp) +{ + const char *fmt = symbol_conf.field_sep ? "%s" : "%12s"; + + return scnprintf(hpp->buf, hpp->size, fmt, "Period Base"); +} + +static int hpp__width_period_baseline(struct perf_hpp *hpp __maybe_unused) +{ + return 12; +} + +static int hpp__entry_period_baseline(struct perf_hpp *hpp, struct hist_entry *he) +{ + struct hist_entry *pair = he->pair; + u64 period = pair ? pair->stat.period : 0; + const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%12" PRIu64; + + return scnprintf(hpp->buf, hpp->size, fmt, period); +} static int hpp__header_delta(struct perf_hpp *hpp) { const char *fmt = symbol_conf.field_sep ? "%s" : "%7s"; @@ -359,6 +379,7 @@ struct perf_hpp_fmt perf_hpp__format[] = { { .cond = false, HPP__COLOR_PRINT_FNS(overhead_guest_us) }, { .cond = false, HPP__PRINT_FNS(samples) }, { .cond = false, HPP__PRINT_FNS(period) }, + { .cond = false, HPP__PRINT_FNS(period_baseline) }, { .cond = false, HPP__PRINT_FNS(delta) }, { .cond = false, HPP__PRINT_FNS(ratio) }, { .cond = false, HPP__PRINT_FNS(wdiff) }, diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index ce76f36aeb0..5604791e5ed 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -140,6 +140,7 @@ enum { PERF_HPP__OVERHEAD_GUEST_US, PERF_HPP__SAMPLES, PERF_HPP__PERIOD, + PERF_HPP__PERIOD_BASELINE, PERF_HPP__DELTA, PERF_HPP__RATIO, PERF_HPP__WEIGHTED_DIFF, -- cgit v1.2.3 From ed279da2fc9774b4c0dc9fd513fa89a11cae3f56 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 5 Oct 2012 16:44:45 +0200 Subject: perf diff: Add -F option to display formula for computation Adding -F option to display the formula for specified computation. This is mainly to facilitate debugging, but can be useful anyway. Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1349448287-18919-7-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-diff.txt | 4 ++ tools/perf/builtin-diff.c | 67 +++++++++++++++++++++++++++++++++- tools/perf/ui/hist.c | 24 +++++++++++- tools/perf/ui/stdio/hist.c | 2 +- tools/perf/util/hist.h | 2 + 5 files changed, 96 insertions(+), 3 deletions(-) diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index 21cc2ef7756..194f37d635d 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt @@ -87,6 +87,10 @@ OPTIONS --period:: Show period values for both compared hist entries. +-F:: +--formula:: + Show formula for given computation. + COMPARISON METHODS ------------------ delta diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 2411dd18c55..dd9c064514f 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -25,6 +25,7 @@ static char diff__default_sort_order[] = "dso,symbol"; static bool force; static bool show_displacement; static bool show_period; +static bool show_formula; static bool show_baseline_only; static bool sort_compute; @@ -190,6 +191,62 @@ s64 perf_diff__compute_wdiff(struct hist_entry *he) return he->diff.wdiff; } +static int formula_delta(struct hist_entry *he, char *buf, size_t size) +{ + struct hist_entry *pair = he->pair; + + if (!pair) + return -1; + + return scnprintf(buf, size, + "(%" PRIu64 " * 100 / %" PRIu64 ") - " + "(%" PRIu64 " * 100 / %" PRIu64 ")", + he->stat.period, he->hists->stats.total_period, + pair->stat.period, pair->hists->stats.total_period); +} + +static int formula_ratio(struct hist_entry *he, char *buf, size_t size) +{ + struct hist_entry *pair = he->pair; + double new_period = he->stat.period; + double old_period = pair ? pair->stat.period : 0; + + if (!pair) + return -1; + + return scnprintf(buf, size, "%.0F / %.0F", new_period, old_period); +} + +static int formula_wdiff(struct hist_entry *he, char *buf, size_t size) +{ + struct hist_entry *pair = he->pair; + u64 new_period = he->stat.period; + u64 old_period = pair ? pair->stat.period : 0; + + if (!pair) + return -1; + + return scnprintf(buf, size, + "(%" PRIu64 " * " "%" PRId64 ") - (%" PRIu64 " * " "%" PRId64 ")", + new_period, compute_wdiff_w2, old_period, compute_wdiff_w1); +} + +int perf_diff__formula(char *buf, size_t size, struct hist_entry *he) +{ + switch (compute) { + case COMPUTE_DELTA: + return formula_delta(he, buf, size); + case COMPUTE_RATIO: + return formula_ratio(he, buf, size); + case COMPUTE_WEIGHTED_DIFF: + return formula_wdiff(he, buf, size); + default: + BUG_ON(1); + } + + return -1; +} + static int hists__add_entry(struct hists *self, struct addr_location *al, u64 period) { @@ -543,6 +600,8 @@ static const struct option options[] = { setup_compute), OPT_BOOLEAN('p', "period", &show_period, "Show period values."), + OPT_BOOLEAN('F', "formula", &show_formula, + "Show formula."), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), @@ -571,7 +630,10 @@ static void ui_init(void) /* No overhead column. */ perf_hpp__column_enable(PERF_HPP__OVERHEAD, false); - /* Display baseline/delta/ratio/displacement/periods columns. */ + /* + * Display baseline/delta/ratio/displacement/ + * formula/periods columns. + */ perf_hpp__column_enable(PERF_HPP__BASELINE, true); switch (compute) { @@ -591,6 +653,9 @@ static void ui_init(void) if (show_displacement) perf_hpp__column_enable(PERF_HPP__DISPL, true); + if (show_formula) + perf_hpp__column_enable(PERF_HPP__FORMULA, true); + if (show_period) { perf_hpp__column_enable(PERF_HPP__PERIOD, true); perf_hpp__column_enable(PERF_HPP__PERIOD_BASELINE, true); diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 2fadaff6312..305eb79f4af 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -359,6 +359,27 @@ static int hpp__entry_displ(struct perf_hpp *hpp, return scnprintf(hpp->buf, hpp->size, fmt, buf); } +static int hpp__header_formula(struct perf_hpp *hpp) +{ + const char *fmt = symbol_conf.field_sep ? "%s" : "%70s"; + + return scnprintf(hpp->buf, hpp->size, fmt, "Formula"); +} + +static int hpp__width_formula(struct perf_hpp *hpp __maybe_unused) +{ + return 70; +} + +static int hpp__entry_formula(struct perf_hpp *hpp, struct hist_entry *he) +{ + const char *fmt = symbol_conf.field_sep ? "%s" : "%-70s"; + char buf[96] = " "; + + perf_diff__formula(buf, sizeof(buf), he); + return scnprintf(hpp->buf, hpp->size, fmt, buf); +} + #define HPP__COLOR_PRINT_FNS(_name) \ .header = hpp__header_ ## _name, \ .width = hpp__width_ ## _name, \ @@ -383,7 +404,8 @@ struct perf_hpp_fmt perf_hpp__format[] = { { .cond = false, HPP__PRINT_FNS(delta) }, { .cond = false, HPP__PRINT_FNS(ratio) }, { .cond = false, HPP__PRINT_FNS(wdiff) }, - { .cond = false, HPP__PRINT_FNS(displ) } + { .cond = false, HPP__PRINT_FNS(displ) }, + { .cond = false, HPP__PRINT_FNS(formula) } }; #undef HPP__COLOR_PRINT_FNS diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index fbd4e32d074..f0ee204f99b 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -342,7 +342,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, const char *sep = symbol_conf.field_sep; const char *col_width = symbol_conf.col_width_list_str; int idx, nr_rows = 0; - char bf[64]; + char bf[96]; struct perf_hpp dummy_hpp = { .buf = bf, .size = sizeof(bf), diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 5604791e5ed..c751624d415 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -145,6 +145,7 @@ enum { PERF_HPP__RATIO, PERF_HPP__WEIGHTED_DIFF, PERF_HPP__DISPL, + PERF_HPP__FORMULA, PERF_HPP__MAX_INDEX }; @@ -210,4 +211,5 @@ unsigned int hists__sort_list_width(struct hists *self); double perf_diff__compute_delta(struct hist_entry *he); double perf_diff__compute_ratio(struct hist_entry *he); s64 perf_diff__compute_wdiff(struct hist_entry *he); +int perf_diff__formula(char *buf, size_t size, struct hist_entry *he); #endif /* __PERF_HIST_H */ -- cgit v1.2.3 From d88c48f9b5bfcbd2e296b2d240e8cb0aec99f042 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 5 Oct 2012 16:44:46 +0200 Subject: perf diff: Include samples without symbol in overall stats Currently we omit samples without symbols. This way we get different and confusing numbers for samples than from report command. Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1349448287-18919-8-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-diff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index dd9c064514f..b4db5137519 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -269,7 +269,7 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused, return -1; } - if (al.filtered || al.sym == NULL) + if (al.filtered) return 0; if (hists__add_entry(&evsel->hists, &al, sample->period)) { -- cgit v1.2.3 From 6e92349d5a814a3f633a43d9d6bd3b199ef3ad72 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 5 Oct 2012 16:44:47 +0200 Subject: perf diff: Display empty space for non paired samples Currently in 'Baseline' and 'Period Base' columns zero values are displayed in case no pair is found for the sample. This might be confusing, using empty space instead. Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1349448287-18919-9-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/hist.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 305eb79f4af..4f5f4756faa 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -179,7 +179,10 @@ static int hpp__color_baseline(struct perf_hpp *hpp, struct hist_entry *he) { double percent = baseline_percent(he); - return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent); + if (he->pair) + return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent); + else + return scnprintf(hpp->buf, hpp->size, " "); } static int hpp__entry_baseline(struct perf_hpp *hpp, struct hist_entry *he) @@ -187,7 +190,10 @@ static int hpp__entry_baseline(struct perf_hpp *hpp, struct hist_entry *he) double percent = baseline_percent(he); const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%%"; - return scnprintf(hpp->buf, hpp->size, fmt, percent); + if (he->pair || symbol_conf.field_sep) + return scnprintf(hpp->buf, hpp->size, fmt, percent); + else + return scnprintf(hpp->buf, hpp->size, " "); } static int hpp__header_samples(struct perf_hpp *hpp) -- cgit v1.2.3 From 0c1fe6b2f30fa275d939071293b6e28771283f6d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 6 Oct 2012 14:57:10 -0300 Subject: perf tools: Have the page size value available for all tools Its such a common need that we might as well have a global with that value. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-mwfqji9f17k5j81l1404dk3q@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-test.c | 2 -- tools/perf/perf.c | 2 ++ tools/perf/util/evlist.c | 3 --- tools/perf/util/session.c | 4 +--- tools/perf/util/trace-event-read.c | 2 -- tools/perf/util/util.c | 2 ++ tools/perf/util/util.h | 2 ++ 7 files changed, 7 insertions(+), 10 deletions(-) diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 484f26cc0c0..e2d9872de3d 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c @@ -35,7 +35,6 @@ static int test__vmlinux_matches_kallsyms(void) struct map *kallsyms_map, *vmlinux_map; struct machine kallsyms, vmlinux; enum map_type type = MAP__FUNCTION; - long page_size = sysconf(_SC_PAGE_SIZE); struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", }; /* @@ -1007,7 +1006,6 @@ static void segfault_handler(int sig __maybe_unused, static int __test__rdpmc(void) { - long page_size = sysconf(_SC_PAGE_SIZE); volatile int tmp = 0; u64 i, loops = 1000; int n; diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 6d50eb0b425..d480d8a412b 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -440,6 +440,8 @@ int main(int argc, const char **argv) { const char *cmd; + page_size = sysconf(_SC_PAGE_SIZE); + cmd = perf_extract_argv0_path(argv[0]); if (!cmd) cmd = "perf-help"; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 186b8773039..a41dc4a5c2d 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -325,8 +325,6 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id) union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) { - /* XXX Move this to perf.c, making it generally available */ - unsigned int page_size = sysconf(_SC_PAGE_SIZE); struct perf_mmap *md = &evlist->mmap[idx]; unsigned int head = perf_mmap__read_head(md); unsigned int old = md->prev; @@ -528,7 +526,6 @@ out_unmap: int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, bool overwrite) { - unsigned int page_size = sysconf(_SC_PAGE_SIZE); struct perf_evsel *evsel; const struct cpu_map *cpus = evlist->cpus; const struct thread_map *threads = evlist->threads; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 8cdd23239c9..15abe40dc70 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1375,15 +1375,13 @@ int __perf_session__process_events(struct perf_session *session, { u64 head, page_offset, file_offset, file_pos, progress_next; int err, mmap_prot, mmap_flags, map_idx = 0; - size_t page_size, mmap_size; + size_t mmap_size; char *buf, *mmaps[8]; union perf_event *event; uint32_t size; perf_tool__fill_defaults(tool); - page_size = sysconf(_SC_PAGESIZE); - page_offset = page_size * (data_offset / page_size); file_offset = page_offset; head = data_offset - page_offset; diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c index 719ed74a856..3741572696a 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c @@ -47,8 +47,6 @@ int file_bigendian; int host_bigendian; static int long_size; -static unsigned long page_size; - static ssize_t calc_data_size; static bool repipe; diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 99664598bc1..637b5cc5436 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -10,6 +10,8 @@ /* * XXX We need to find a better place for these things... */ +unsigned int page_size; + bool perf_host = true; bool perf_guest = false; diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 70fa70b535b..a6b83f8ebef 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -263,4 +263,6 @@ char *rtrim(char *s); void dump_stack(void); +extern unsigned int page_size; + #endif -- cgit v1.2.3 From 9d2f8e22fc965bcdd5561d000d234fe2d23657ba Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 6 Oct 2012 15:43:20 -0300 Subject: perf machine: Introduce find_thread method There are cases where we want just to find a thread if it exists already, so provide a method for that. While doing that start moving 'machine' methods to a separate file. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-8wpzqs9kfupng6xq8hx6lnxa@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 2 ++ tools/perf/util/machine.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/machine.h | 11 +++++++++ tools/perf/util/thread.c | 41 +--------------------------------- tools/perf/util/thread.h | 2 ++ 5 files changed, 73 insertions(+), 40 deletions(-) create mode 100644 tools/perf/util/machine.c create mode 100644 tools/perf/util/machine.h diff --git a/tools/perf/Makefile b/tools/perf/Makefile index f9126f89efe..d80a3332478 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -300,6 +300,7 @@ LIB_H += util/evlist.h LIB_H += util/exec_cmd.h LIB_H += util/types.h LIB_H += util/levenshtein.h +LIB_H += util/machine.h LIB_H += util/map.h LIB_H += util/parse-options.h LIB_H += util/parse-events.h @@ -383,6 +384,7 @@ LIB_OBJS += $(OUTPUT)util/header.o LIB_OBJS += $(OUTPUT)util/callchain.o LIB_OBJS += $(OUTPUT)util/values.o LIB_OBJS += $(OUTPUT)util/debug.o +LIB_OBJS += $(OUTPUT)util/machine.o LIB_OBJS += $(OUTPUT)util/map.o LIB_OBJS += $(OUTPUT)util/pstack.o LIB_OBJS += $(OUTPUT)util/session.o diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c new file mode 100644 index 00000000000..9d36d7eeda9 --- /dev/null +++ b/tools/perf/util/machine.c @@ -0,0 +1,57 @@ +#include "machine.h" +#include "map.h" +#include "thread.h" +#include + +static struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, + bool create) +{ + struct rb_node **p = &machine->threads.rb_node; + struct rb_node *parent = NULL; + struct thread *th; + + /* + * Font-end cache - PID lookups come in blocks, + * so most of the time we dont have to look up + * the full rbtree: + */ + if (machine->last_match && machine->last_match->pid == pid) + return machine->last_match; + + while (*p != NULL) { + parent = *p; + th = rb_entry(parent, struct thread, rb_node); + + if (th->pid == pid) { + machine->last_match = th; + return th; + } + + if (pid < th->pid) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + + if (!create) + return NULL; + + th = thread__new(pid); + if (th != NULL) { + rb_link_node(&th->rb_node, parent, p); + rb_insert_color(&th->rb_node, &machine->threads); + machine->last_match = th; + } + + return th; +} + +struct thread *machine__findnew_thread(struct machine *machine, pid_t pid) +{ + return __machine__findnew_thread(machine, pid, true); +} + +struct thread *machine__find_thread(struct machine *machine, pid_t pid) +{ + return __machine__findnew_thread(machine, pid, false); +} diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h new file mode 100644 index 00000000000..54df0cdd300 --- /dev/null +++ b/tools/perf/util/machine.h @@ -0,0 +1,11 @@ +#ifndef __PERF_MACHINE_H +#define __PERF_MACHINE_H + +#include + +struct thread; +struct machine; + +struct thread *machine__find_thread(struct machine *machine, pid_t pid); + +#endif /* __PERF_MACHINE_H */ diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index fb4b7ea6752..fe3bb1ec188 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -7,7 +7,7 @@ #include "util.h" #include "debug.h" -static struct thread *thread__new(pid_t pid) +struct thread *thread__new(pid_t pid) { struct thread *self = zalloc(sizeof(*self)); @@ -61,45 +61,6 @@ static size_t thread__fprintf(struct thread *self, FILE *fp) map_groups__fprintf(&self->mg, verbose, fp); } -struct thread *machine__findnew_thread(struct machine *self, pid_t pid) -{ - struct rb_node **p = &self->threads.rb_node; - struct rb_node *parent = NULL; - struct thread *th; - - /* - * Font-end cache - PID lookups come in blocks, - * so most of the time we dont have to look up - * the full rbtree: - */ - if (self->last_match && self->last_match->pid == pid) - return self->last_match; - - while (*p != NULL) { - parent = *p; - th = rb_entry(parent, struct thread, rb_node); - - if (th->pid == pid) { - self->last_match = th; - return th; - } - - if (pid < th->pid) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; - } - - th = thread__new(pid); - if (th != NULL) { - rb_link_node(&th->rb_node, parent, p); - rb_insert_color(&th->rb_node, &self->threads); - self->last_match = th; - } - - return th; -} - void thread__insert_map(struct thread *self, struct map *map) { map_groups__fixup_overlappings(&self->mg, map, verbose, stderr); diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index f66610b7bac..f2fa17caa7d 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -3,6 +3,7 @@ #include #include +#include #include "symbol.h" struct thread { @@ -22,6 +23,7 @@ struct thread { struct machine; +struct thread *thread__new(pid_t pid); void thread__delete(struct thread *self); int thread__set_comm(struct thread *self, const char *comm); -- cgit v1.2.3 From f62d3f0f4596f983ec00495d91c8ddb30268d878 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 6 Oct 2012 15:44:59 -0300 Subject: perf event: No need to create a thread when handling PERF_RECORD_EXIT When we were processing a PERF_RECORD_EXIT event we first used machine__findnew_thread for both the thread exiting and for its parent, only to use just the thread struct associated with the one exiting, and to just delete it. If it existed, i.e. not created at this very moment in machine__findnew_thread, it will be moved to the machine->dead_threads linked list, because we may have hist_entries pointing to it, but if it was created just do be deleted, it will just sit there with no references at all. Use the new machine__find_thread() method so that if it is not there, we don't create it. As a bonus the parent thread will also not be created at this point. Create process_fork() and process_exit() helpers to use this and make the builtins use it instead of the generic process_task(), ditched by this patch. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-z7n2y98ebjyrvmytaope4vdl@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-diff.c | 4 ++-- tools/perf/builtin-inject.c | 6 +++--- tools/perf/builtin-report.c | 4 ++-- tools/perf/builtin-sched.c | 2 +- tools/perf/builtin-script.c | 4 ++-- tools/perf/util/build-id.c | 2 +- tools/perf/util/event.c | 30 ++++++++++++++++++++++-------- tools/perf/util/event.h | 6 +++++- 9 files changed, 39 insertions(+), 21 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 9ea38540b87..cca2fb5c436 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -246,7 +246,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) .sample = process_sample_event, .mmap = perf_event__process_mmap, .comm = perf_event__process_comm, - .fork = perf_event__process_task, + .fork = perf_event__process_fork, .ordered_samples = true, .ordering_requires_timestamps = true, }, diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index b4db5137519..380683de1df 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -285,8 +285,8 @@ static struct perf_tool tool = { .sample = diff__process_sample_event, .mmap = perf_event__process_mmap, .comm = perf_event__process_comm, - .exit = perf_event__process_task, - .fork = perf_event__process_task, + .exit = perf_event__process_exit, + .fork = perf_event__process_fork, .lost = perf_event__process_lost, .ordered_samples = true, .ordering_requires_timestamps = true, diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 4688bea95c1..386a5c0013f 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -102,14 +102,14 @@ static int perf_event__repipe_mmap(struct perf_tool *tool, return err; } -static int perf_event__repipe_task(struct perf_tool *tool, +static int perf_event__repipe_fork(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine) { int err; - err = perf_event__process_task(tool, event, sample, machine); + err = perf_event__process_fork(tool, event, sample, machine); perf_event__repipe(tool, event, sample, machine); return err; @@ -227,7 +227,7 @@ static int __cmd_inject(struct perf_inject *inject) if (inject->build_ids) { inject->tool.sample = perf_event__inject_buildid; inject->tool.mmap = perf_event__repipe_mmap; - inject->tool.fork = perf_event__repipe_task; + inject->tool.fork = perf_event__repipe_fork; inject->tool.tracing_data = perf_event__repipe_tracing_data; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index a61725d89d3..5104a40af56 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -556,8 +556,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) .sample = process_sample_event, .mmap = perf_event__process_mmap, .comm = perf_event__process_comm, - .exit = perf_event__process_task, - .fork = perf_event__process_task, + .exit = perf_event__process_exit, + .fork = perf_event__process_fork, .lost = perf_event__process_lost, .read = process_read_event, .attr = perf_event__process_attr, diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 3488ead3b60..3a25cd83b56 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1672,7 +1672,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) .sample = perf_sched__process_tracepoint_sample, .comm = perf_event__process_comm, .lost = perf_event__process_lost, - .fork = perf_event__process_task, + .fork = perf_event__process_fork, .ordered_samples = true, }, .cmp_pid = LIST_HEAD_INIT(sched.cmp_pid), diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index fb9625083a2..04ceb0779d3 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -520,8 +520,8 @@ static struct perf_tool perf_script = { .sample = process_sample_event, .mmap = perf_event__process_mmap, .comm = perf_event__process_comm, - .exit = perf_event__process_task, - .fork = perf_event__process_task, + .exit = perf_event__process_exit, + .fork = perf_event__process_fork, .attr = perf_event__process_attr, .event_type = perf_event__process_event_type, .tracing_data = perf_event__process_tracing_data, diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 8e3a740ddbd..6a6399955ef 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -64,7 +64,7 @@ static int perf_event__exit_del_thread(struct perf_tool *tool __maybe_unused, struct perf_tool build_id__mark_dso_hit_ops = { .sample = build_id__mark_dso_hit, .mmap = perf_event__process_mmap, - .fork = perf_event__process_task, + .fork = perf_event__process_fork, .exit = perf_event__exit_del_thread, .attr = perf_event__process_attr, .build_id = perf_event__process_build_id, diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 6715b193872..eaaee22628e 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1,6 +1,7 @@ #include #include "event.h" #include "debug.h" +#include "machine.h" #include "sort.h" #include "string.h" #include "strlist.h" @@ -702,10 +703,10 @@ size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) event->fork.ppid, event->fork.ptid); } -int perf_event__process_task(struct perf_tool *tool __maybe_unused, +int perf_event__process_fork(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused, - struct machine *machine) + struct machine *machine) { struct thread *thread = machine__findnew_thread(machine, event->fork.tid); struct thread *parent = machine__findnew_thread(machine, event->fork.ptid); @@ -713,11 +714,6 @@ int perf_event__process_task(struct perf_tool *tool __maybe_unused, if (dump_trace) perf_event__fprintf_task(event, stdout); - if (event->header.type == PERF_RECORD_EXIT) { - machine__remove_thread(machine, thread); - return 0; - } - if (thread == NULL || parent == NULL || thread__fork(thread, parent) < 0) { dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n"); @@ -727,6 +723,22 @@ int perf_event__process_task(struct perf_tool *tool __maybe_unused, return 0; } +int perf_event__process_exit(struct perf_tool *tool __maybe_unused, + union perf_event *event, + struct perf_sample *sample __maybe_unused, + struct machine *machine) +{ + struct thread *thread = machine__find_thread(machine, event->fork.tid); + + if (dump_trace) + perf_event__fprintf_task(event, stdout); + + if (thread != NULL) + machine__remove_thread(machine, thread); + + return 0; +} + size_t perf_event__fprintf(union perf_event *event, FILE *fp) { size_t ret = fprintf(fp, "PERF_RECORD_%s", @@ -761,8 +773,10 @@ int perf_event__process(struct perf_tool *tool, union perf_event *event, perf_event__process_mmap(tool, event, sample, machine); break; case PERF_RECORD_FORK: + perf_event__process_fork(tool, event, sample, machine); + break; case PERF_RECORD_EXIT: - perf_event__process_task(tool, event, sample, machine); + perf_event__process_exit(tool, event, sample, machine); break; case PERF_RECORD_LOST: perf_event__process_lost(tool, event, sample, machine); diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 21b99e741a8..da97aff5bd7 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -191,7 +191,11 @@ int perf_event__process_mmap(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine); -int perf_event__process_task(struct perf_tool *tool, +int perf_event__process_fork(struct perf_tool *tool, + union perf_event *event, + struct perf_sample *sample, + struct machine *machine); +int perf_event__process_exit(struct perf_tool *tool, union perf_event *event, struct perf_sample *sample, struct machine *machine); -- cgit v1.2.3 From ec4622f5fdfa2467befa6d750675db3d3258edc5 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 6 Oct 2012 15:53:41 -0300 Subject: perf annotate: Handle PERF_RECORD_EXIT events Noticed annotate wasn't handling those events while introducing perf_event__process_{fork,exit}. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-of7tc8eqeuk3cupc6f7jtuq6@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index cca2fb5c436..690fa9a5465 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -246,6 +246,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) .sample = process_sample_event, .mmap = perf_event__process_mmap, .comm = perf_event__process_comm, + .exit = perf_event__process_exit, .fork = perf_event__process_fork, .ordered_samples = true, .ordering_requires_timestamps = true, -- cgit v1.2.3 From 0439539f72ea222fbfe511b47318b9c1815a7108 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 6 Oct 2012 15:53:41 -0300 Subject: perf sched: Handle PERF_RECORD_EXIT events Noticed sched wasn't handling those events while introducing perf_event__process_{fork,exit}. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-035rzjtnv9ri8sssi7ojjjq0@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-sched.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 3a25cd83b56..30e53360d3c 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1672,6 +1672,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) .sample = perf_sched__process_tracepoint_sample, .comm = perf_event__process_comm, .lost = perf_event__process_lost, + .exit = perf_event__process_exit, .fork = perf_event__process_fork, .ordered_samples = true, }, -- cgit v1.2.3 From b0a7d1a0cd2e228dc06d099db2e1bb02f1b7d591 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 6 Oct 2012 16:26:02 -0300 Subject: perf machine: Carve up event processing specific from perf_tool The perf_tool vtable expects methods that receive perf_tool and perf_sample entries, but for tools not interested in doing any special processing on non PERF_RECORD_SAMPLE events, like 'perf top', and for those not using perf_session, like 'perf trace', they were using perf_event__process passing tool and sample paramenters that were just not used. Provide 'machine' methods for this purpose and make the perf_event ones use them. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ot9cc6mt025o8kbngzckcrx9@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 3 +- tools/perf/util/event.c | 211 +++----------------------------------------- tools/perf/util/machine.c | 220 ++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/machine.h | 8 ++ 4 files changed, 242 insertions(+), 200 deletions(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index ff6db808680..fb9da71eba1 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -26,6 +26,7 @@ #include "util/color.h" #include "util/evlist.h" #include "util/evsel.h" +#include "util/machine.h" #include "util/session.h" #include "util/symbol.h" #include "util/thread.h" @@ -871,7 +872,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) &sample, machine); } else if (event->header.type < PERF_RECORD_MAX) { hists__inc_nr_events(&evsel->hists, event->header.type); - perf_event__process(&top->tool, event, &sample, machine); + machine__process_event(machine, event); } else ++session->hists.stats.nr_unknown_events; } diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index eaaee22628e..0ae444ef142 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -520,134 +520,15 @@ int perf_event__process_comm(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine) { - struct thread *thread = machine__findnew_thread(machine, event->comm.tid); - - if (dump_trace) - perf_event__fprintf_comm(event, stdout); - - if (thread == NULL || thread__set_comm(thread, event->comm.comm)) { - dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); - return -1; - } - - return 0; + return machine__process_comm_event(machine, event); } int perf_event__process_lost(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused, - struct machine *machine __maybe_unused) -{ - dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", - event->lost.id, event->lost.lost); - return 0; -} - -static void perf_event__set_kernel_mmap_len(union perf_event *event, - struct map **maps) -{ - maps[MAP__FUNCTION]->start = event->mmap.start; - maps[MAP__FUNCTION]->end = event->mmap.start + event->mmap.len; - /* - * Be a bit paranoid here, some perf.data file came with - * a zero sized synthesized MMAP event for the kernel. - */ - if (maps[MAP__FUNCTION]->end == 0) - maps[MAP__FUNCTION]->end = ~0ULL; -} - -static int perf_event__process_kernel_mmap(struct perf_tool *tool - __maybe_unused, - union perf_event *event, - struct machine *machine) + struct machine *machine) { - struct map *map; - char kmmap_prefix[PATH_MAX]; - enum dso_kernel_type kernel_type; - bool is_kernel_mmap; - - machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix)); - if (machine__is_host(machine)) - kernel_type = DSO_TYPE_KERNEL; - else - kernel_type = DSO_TYPE_GUEST_KERNEL; - - is_kernel_mmap = memcmp(event->mmap.filename, - kmmap_prefix, - strlen(kmmap_prefix) - 1) == 0; - if (event->mmap.filename[0] == '/' || - (!is_kernel_mmap && event->mmap.filename[0] == '[')) { - - char short_module_name[1024]; - char *name, *dot; - - if (event->mmap.filename[0] == '/') { - name = strrchr(event->mmap.filename, '/'); - if (name == NULL) - goto out_problem; - - ++name; /* skip / */ - dot = strrchr(name, '.'); - if (dot == NULL) - goto out_problem; - snprintf(short_module_name, sizeof(short_module_name), - "[%.*s]", (int)(dot - name), name); - strxfrchar(short_module_name, '-', '_'); - } else - strcpy(short_module_name, event->mmap.filename); - - map = machine__new_module(machine, event->mmap.start, - event->mmap.filename); - if (map == NULL) - goto out_problem; - - name = strdup(short_module_name); - if (name == NULL) - goto out_problem; - - map->dso->short_name = name; - map->dso->sname_alloc = 1; - map->end = map->start + event->mmap.len; - } else if (is_kernel_mmap) { - const char *symbol_name = (event->mmap.filename + - strlen(kmmap_prefix)); - /* - * Should be there already, from the build-id table in - * the header. - */ - struct dso *kernel = __dsos__findnew(&machine->kernel_dsos, - kmmap_prefix); - if (kernel == NULL) - goto out_problem; - - kernel->kernel = kernel_type; - if (__machine__create_kernel_maps(machine, kernel) < 0) - goto out_problem; - - perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); - - /* - * Avoid using a zero address (kptr_restrict) for the ref reloc - * symbol. Effectively having zero here means that at record - * time /proc/sys/kernel/kptr_restrict was non zero. - */ - if (event->mmap.pgoff != 0) { - maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, - symbol_name, - event->mmap.pgoff); - } - - if (machine__is_default_guest(machine)) { - /* - * preload dso of guest kernel and modules - */ - dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION], - NULL); - } - } - return 0; -out_problem: - return -1; + return machine__process_lost_event(machine, event); } size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) @@ -657,43 +538,12 @@ size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) event->mmap.len, event->mmap.pgoff, event->mmap.filename); } -int perf_event__process_mmap(struct perf_tool *tool, +int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample __maybe_unused, struct machine *machine) { - struct thread *thread; - struct map *map; - u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; - int ret = 0; - - if (dump_trace) - perf_event__fprintf_mmap(event, stdout); - - if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || - cpumode == PERF_RECORD_MISC_KERNEL) { - ret = perf_event__process_kernel_mmap(tool, event, machine); - if (ret < 0) - goto out_problem; - return 0; - } - - thread = machine__findnew_thread(machine, event->mmap.pid); - if (thread == NULL) - goto out_problem; - map = map__new(&machine->user_dsos, event->mmap.start, - event->mmap.len, event->mmap.pgoff, - event->mmap.pid, event->mmap.filename, - MAP__FUNCTION); - if (map == NULL) - goto out_problem; - - thread__insert_map(thread, map); - return 0; - -out_problem: - dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n"); - return 0; + return machine__process_mmap_event(machine, event); } size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) @@ -708,19 +558,7 @@ int perf_event__process_fork(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine) { - struct thread *thread = machine__findnew_thread(machine, event->fork.tid); - struct thread *parent = machine__findnew_thread(machine, event->fork.ptid); - - if (dump_trace) - perf_event__fprintf_task(event, stdout); - - if (thread == NULL || parent == NULL || - thread__fork(thread, parent) < 0) { - dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n"); - return -1; - } - - return 0; + return machine__process_fork_event(machine, event); } int perf_event__process_exit(struct perf_tool *tool __maybe_unused, @@ -728,15 +566,7 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine) { - struct thread *thread = machine__find_thread(machine, event->fork.tid); - - if (dump_trace) - perf_event__fprintf_task(event, stdout); - - if (thread != NULL) - machine__remove_thread(machine, thread); - - return 0; + return machine__process_exit_event(machine, event); } size_t perf_event__fprintf(union perf_event *event, FILE *fp) @@ -762,29 +592,12 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp) return ret; } -int perf_event__process(struct perf_tool *tool, union perf_event *event, - struct perf_sample *sample, struct machine *machine) +int perf_event__process(struct perf_tool *tool __maybe_unused, + union perf_event *event, + struct perf_sample *sample __maybe_unused, + struct machine *machine) { - switch (event->header.type) { - case PERF_RECORD_COMM: - perf_event__process_comm(tool, event, sample, machine); - break; - case PERF_RECORD_MMAP: - perf_event__process_mmap(tool, event, sample, machine); - break; - case PERF_RECORD_FORK: - perf_event__process_fork(tool, event, sample, machine); - break; - case PERF_RECORD_EXIT: - perf_event__process_exit(tool, event, sample, machine); - break; - case PERF_RECORD_LOST: - perf_event__process_lost(tool, event, sample, machine); - default: - break; - } - - return 0; + return machine__process_event(machine, event); } void thread__find_addr_map(struct thread *self, diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 9d36d7eeda9..502eec0d477 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1,3 +1,5 @@ +#include "debug.h" +#include "event.h" #include "machine.h" #include "map.h" #include "thread.h" @@ -55,3 +57,221 @@ struct thread *machine__find_thread(struct machine *machine, pid_t pid) { return __machine__findnew_thread(machine, pid, false); } + +int machine__process_comm_event(struct machine *machine, union perf_event *event) +{ + struct thread *thread = machine__findnew_thread(machine, event->comm.tid); + + if (dump_trace) + perf_event__fprintf_comm(event, stdout); + + if (thread == NULL || thread__set_comm(thread, event->comm.comm)) { + dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); + return -1; + } + + return 0; +} + +int machine__process_lost_event(struct machine *machine __maybe_unused, + union perf_event *event) +{ + dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", + event->lost.id, event->lost.lost); + return 0; +} + +static void machine__set_kernel_mmap_len(struct machine *machine, + union perf_event *event) +{ + machine->vmlinux_maps[MAP__FUNCTION]->start = event->mmap.start; + machine->vmlinux_maps[MAP__FUNCTION]->end = (event->mmap.start + + event->mmap.len); + /* + * Be a bit paranoid here, some perf.data file came with + * a zero sized synthesized MMAP event for the kernel. + */ + if (machine->vmlinux_maps[MAP__FUNCTION]->end == 0) + machine->vmlinux_maps[MAP__FUNCTION]->end = ~0ULL; +} + +static int machine__process_kernel_mmap_event(struct machine *machine, + union perf_event *event) +{ + struct map *map; + char kmmap_prefix[PATH_MAX]; + enum dso_kernel_type kernel_type; + bool is_kernel_mmap; + + machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix)); + if (machine__is_host(machine)) + kernel_type = DSO_TYPE_KERNEL; + else + kernel_type = DSO_TYPE_GUEST_KERNEL; + + is_kernel_mmap = memcmp(event->mmap.filename, + kmmap_prefix, + strlen(kmmap_prefix) - 1) == 0; + if (event->mmap.filename[0] == '/' || + (!is_kernel_mmap && event->mmap.filename[0] == '[')) { + + char short_module_name[1024]; + char *name, *dot; + + if (event->mmap.filename[0] == '/') { + name = strrchr(event->mmap.filename, '/'); + if (name == NULL) + goto out_problem; + + ++name; /* skip / */ + dot = strrchr(name, '.'); + if (dot == NULL) + goto out_problem; + snprintf(short_module_name, sizeof(short_module_name), + "[%.*s]", (int)(dot - name), name); + strxfrchar(short_module_name, '-', '_'); + } else + strcpy(short_module_name, event->mmap.filename); + + map = machine__new_module(machine, event->mmap.start, + event->mmap.filename); + if (map == NULL) + goto out_problem; + + name = strdup(short_module_name); + if (name == NULL) + goto out_problem; + + map->dso->short_name = name; + map->dso->sname_alloc = 1; + map->end = map->start + event->mmap.len; + } else if (is_kernel_mmap) { + const char *symbol_name = (event->mmap.filename + + strlen(kmmap_prefix)); + /* + * Should be there already, from the build-id table in + * the header. + */ + struct dso *kernel = __dsos__findnew(&machine->kernel_dsos, + kmmap_prefix); + if (kernel == NULL) + goto out_problem; + + kernel->kernel = kernel_type; + if (__machine__create_kernel_maps(machine, kernel) < 0) + goto out_problem; + + machine__set_kernel_mmap_len(machine, event); + + /* + * Avoid using a zero address (kptr_restrict) for the ref reloc + * symbol. Effectively having zero here means that at record + * time /proc/sys/kernel/kptr_restrict was non zero. + */ + if (event->mmap.pgoff != 0) { + maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, + symbol_name, + event->mmap.pgoff); + } + + if (machine__is_default_guest(machine)) { + /* + * preload dso of guest kernel and modules + */ + dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION], + NULL); + } + } + return 0; +out_problem: + return -1; +} + +int machine__process_mmap_event(struct machine *machine, union perf_event *event) +{ + u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; + struct thread *thread; + struct map *map; + int ret = 0; + + if (dump_trace) + perf_event__fprintf_mmap(event, stdout); + + if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || + cpumode == PERF_RECORD_MISC_KERNEL) { + ret = machine__process_kernel_mmap_event(machine, event); + if (ret < 0) + goto out_problem; + return 0; + } + + thread = machine__findnew_thread(machine, event->mmap.pid); + if (thread == NULL) + goto out_problem; + map = map__new(&machine->user_dsos, event->mmap.start, + event->mmap.len, event->mmap.pgoff, + event->mmap.pid, event->mmap.filename, + MAP__FUNCTION); + if (map == NULL) + goto out_problem; + + thread__insert_map(thread, map); + return 0; + +out_problem: + dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n"); + return 0; +} + +int machine__process_fork_event(struct machine *machine, union perf_event *event) +{ + struct thread *thread = machine__findnew_thread(machine, event->fork.tid); + struct thread *parent = machine__findnew_thread(machine, event->fork.ptid); + + if (dump_trace) + perf_event__fprintf_task(event, stdout); + + if (thread == NULL || parent == NULL || + thread__fork(thread, parent) < 0) { + dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n"); + return -1; + } + + return 0; +} + +int machine__process_exit_event(struct machine *machine, union perf_event *event) +{ + struct thread *thread = machine__find_thread(machine, event->fork.tid); + + if (dump_trace) + perf_event__fprintf_task(event, stdout); + + if (thread != NULL) + machine__remove_thread(machine, thread); + + return 0; +} + +int machine__process_event(struct machine *machine, union perf_event *event) +{ + int ret; + + switch (event->header.type) { + case PERF_RECORD_COMM: + ret = machine__process_comm_event(machine, event); break; + case PERF_RECORD_MMAP: + ret = machine__process_mmap_event(machine, event); break; + case PERF_RECORD_FORK: + ret = machine__process_fork_event(machine, event); break; + case PERF_RECORD_EXIT: + ret = machine__process_exit_event(machine, event); break; + case PERF_RECORD_LOST: + ret = machine__process_lost_event(machine, event); break; + default: + ret = -1; + break; + } + + return ret; +} diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 54df0cdd300..df152f1768b 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -5,7 +5,15 @@ struct thread; struct machine; +union perf_event; struct thread *machine__find_thread(struct machine *machine, pid_t pid); +int machine__process_comm_event(struct machine *machine, union perf_event *event); +int machine__process_exit_event(struct machine *machine, union perf_event *event); +int machine__process_fork_event(struct machine *machine, union perf_event *event); +int machine__process_lost_event(struct machine *machine, union perf_event *event); +int machine__process_mmap_event(struct machine *machine, union perf_event *event); +int machine__process_event(struct machine *machine, union perf_event *event); + #endif /* __PERF_MACHINE_H */ -- cgit v1.2.3 From ae86912f48b624540b886187e169bcf47a14e42a Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 7 Oct 2012 22:09:12 +0800 Subject: perf tools: Remove duplicated include from trace-event-python.c Remove duplicated include. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Wei Yongjun Link: http://lkml.kernel.org/r/CAPgLHd8fz+TznMVRdhzPb45WtZQXhVxadRQcLxUC4O9aX+SUbA@mail.gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/scripting-engines/trace-event-python.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 730c6630cba..14683dfca2e 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -32,7 +32,6 @@ #include "../event.h" #include "../thread.h" #include "../trace-event.h" -#include "../evsel.h" PyMODINIT_FUNC initperf_trace_context(void); -- cgit v1.2.3 From 2aa8eab029b319b2b458b3ba393bbba31961ea96 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 8 Oct 2012 11:17:35 -0600 Subject: perf kvm: Only process events for vcpus of interest Minimizing processing overhead for each sample - which becomes important for the upcoming live mode when it has to deal with 100+k events per second. Signed-off-by: David Ahern Cc: Dong Hao Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Xiao Guangrong Link: http://lkml.kernel.org/r/1349716656-48165-12-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 260abc535b5..b98095edf1f 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -416,7 +416,10 @@ static double kvm_event_rel_stddev(int vcpu_id, struct kvm_event *event) static bool update_kvm_event(struct kvm_event *event, int vcpu_id, u64 time_diff) { - kvm_update_event_stats(&event->total, time_diff); + if (vcpu_id == -1) { + kvm_update_event_stats(&event->total, time_diff); + return true; + } if (!kvm_event_expand(event, vcpu_id)) return false; @@ -432,6 +435,12 @@ static bool handle_end_event(struct perf_kvm *kvm, { struct kvm_event *event; u64 time_begin, time_diff; + int vcpu; + + if (kvm->trace_vcpu == -1) + vcpu = -1; + else + vcpu = vcpu_record->vcpu_id; event = vcpu_record->last_event; time_begin = vcpu_record->start_time; @@ -461,7 +470,7 @@ static bool handle_end_event(struct perf_kvm *kvm, BUG_ON(timestamp < time_begin); time_diff = timestamp - time_begin; - return update_kvm_event(event, vcpu_record->vcpu_id, time_diff); + return update_kvm_event(event, vcpu, time_diff); } static @@ -498,6 +507,11 @@ static bool handle_kvm_event(struct perf_kvm *kvm, if (!vcpu_record) return true; + /* only process events for vcpus user cares about */ + if ((kvm->trace_vcpu != -1) && + (kvm->trace_vcpu != vcpu_record->vcpu_id)) + return true; + if (kvm->events_ops->is_begin_event(evsel, sample, &key)) return handle_begin_event(kvm, vcpu_record, &key, sample->time); -- cgit v1.2.3 From b880deeaffd9df0cec9a4496447d0d7fd78086f2 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 8 Oct 2012 11:17:30 -0600 Subject: perf kvm: Remove typecast in init_kvm_event_record Not needed after changing i to unsigned int. Signed-off-by: David Ahern Cc: Dong Hao Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Xiao Guangrong Link: http://lkml.kernel.org/r/1349716656-48165-7-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index b98095edf1f..8416754b2bc 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -313,9 +313,9 @@ struct vcpu_event_record { static void init_kvm_event_record(struct perf_kvm *kvm) { - int i; + unsigned int i; - for (i = 0; i < (int)EVENTS_CACHE_SIZE; i++) + for (i = 0; i < EVENTS_CACHE_SIZE; i++) INIT_LIST_HEAD(&kvm->kvm_events_cache[i]); } -- cgit v1.2.3 From e4f7637f8aefa2ad5159a1cda46fedea6eaf64fc Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 8 Oct 2012 11:17:34 -0600 Subject: perf kvm: Total count is a u64, print as so remove cast and use proper type in format. Signed-off-by: David Ahern Cc: Dong Hao Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Xiao Guangrong Link: http://lkml.kernel.org/r/1349716656-48165-11-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 8416754b2bc..72a302e7807 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -673,8 +673,8 @@ static void print_result(struct perf_kvm *kvm) pr_info("\n"); } - pr_info("\nTotal Samples:%lld, Total events handled time:%.2fus.\n\n", - (unsigned long long)kvm->total_count, kvm->total_time / 1e3); + pr_info("\nTotal Samples:%" PRIu64 ", Total events handled time:%.2fus.\n\n", + kvm->total_count, kvm->total_time / 1e3); } static int process_sample_event(struct perf_tool *tool, -- cgit v1.2.3 From 355afe816312faf20d81fdcade29e0361d72a7b4 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 8 Oct 2012 11:17:32 -0600 Subject: perf kvm: Add braces around multi-line statements Multi-line statements should have braces. Improves readability. Signed-off-by: David Ahern Cc: Dong Hao Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Xiao Guangrong Link: http://lkml.kernel.org/r/1349716656-48165-9-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 72a302e7807..836c82f0137 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -369,9 +369,10 @@ static struct kvm_event *find_create_kvm_event(struct perf_kvm *kvm, BUG_ON(key->key == INVALID_KEY); head = &kvm->kvm_events_cache[kvm_events_hash_fn(key->key)]; - list_for_each_entry(event, head, hash_entry) + list_for_each_entry(event, head, hash_entry) { if (event->key.key == key->key && event->key.info == key->info) return event; + } event = kvm_alloc_init_event(key); if (!event) @@ -610,13 +611,15 @@ static void sort_result(struct perf_kvm *kvm) int vcpu = kvm->trace_vcpu; struct kvm_event *event; - for (i = 0; i < EVENTS_CACHE_SIZE; i++) - list_for_each_entry(event, &kvm->kvm_events_cache[i], hash_entry) + for (i = 0; i < EVENTS_CACHE_SIZE; i++) { + list_for_each_entry(event, &kvm->kvm_events_cache[i], hash_entry) { if (event_is_valid(event, vcpu)) { update_total_count(kvm, event); insert_to_result(&kvm->result, event, kvm->compare, vcpu); } + } + } } /* returns left most element of result, and erase it */ -- cgit v1.2.3 From 78da39faf7c903bb6e3c20a726fde1bf98d10af8 Mon Sep 17 00:00:00 2001 From: Bernhard Rosenkraenzer Date: Mon, 8 Oct 2012 09:43:26 +0300 Subject: perf tools: Add on_exit implementation on_exit() is only available in new versions of glibc. It is not implemented in Bionic and will lead to linking errors when compiling for Android. Implement a wrapper for on_exit using atexit. The implementation for on_exit is the one sent by Bernhard Rosenkraenzer in https://lkml.org/lkml/2012/8/23/316. The configuration part from the Makefile is different than the one from the original patch. Signed-off-by: Bernhard Rosenkraenzer Signed-off-by: Irina Tirdea Cc: David Ahern Cc: Ingo Molnar Cc: Irina Tirdea Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1349678613-7045-2-git-send-email-irina.tirdea@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 6 ++++++ tools/perf/builtin-record.c | 32 ++++++++++++++++++++++++++++++++ tools/perf/config/feature-tests.mak | 11 ++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index d80a3332478..a7d8745e0ab 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -753,6 +753,12 @@ ifndef NO_STRLCPY endif endif +ifndef NO_ON_EXIT + ifeq ($(call try-cc,$(SOURCE_ON_EXIT),),y) + BASIC_CFLAGS += -DHAVE_ON_EXIT + endif +endif + ifndef NO_BACKTRACE ifeq ($(call try-cc,$(SOURCE_BACKTRACE),),y) BASIC_CFLAGS += -DBACKTRACE_SUPPORT diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e9231659754..73b5d7f9119 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -31,6 +31,38 @@ #include #include +#ifndef HAVE_ON_EXIT +#ifndef ATEXIT_MAX +#define ATEXIT_MAX 32 +#endif +static int __on_exit_count = 0; +typedef void (*on_exit_func_t) (int, void *); +static on_exit_func_t __on_exit_funcs[ATEXIT_MAX]; +static void *__on_exit_args[ATEXIT_MAX]; +static int __exitcode = 0; +static void __handle_on_exit_funcs(void); +static int on_exit(on_exit_func_t function, void *arg); +#define exit(x) (exit)(__exitcode = (x)) + +static int on_exit(on_exit_func_t function, void *arg) +{ + if (__on_exit_count == ATEXIT_MAX) + return -ENOMEM; + else if (__on_exit_count == 0) + atexit(__handle_on_exit_funcs); + __on_exit_funcs[__on_exit_count] = function; + __on_exit_args[__on_exit_count++] = arg; + return 0; +} + +static void __handle_on_exit_funcs(void) +{ + int i; + for (i = 0; i < __on_exit_count; i++) + __on_exit_funcs[i] (__exitcode, __on_exit_args[i]); +} +#endif + enum write_mode_t { WRITE_FORCE, WRITE_APPEND diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index 4add41bb0c7..eaeb0fd6f39 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak @@ -203,4 +203,13 @@ int main(void) return audit_open(); } endef -endif \ No newline at end of file +endif + +define SOURCE_ON_EXIT +#include + +int main(void) +{ + return on_exit(NULL, NULL); +} +endef -- cgit v1.2.3 From d816ec2d1bea55cfeac373f0ab0ab8a3105e49b4 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Mon, 8 Oct 2012 09:43:27 +0300 Subject: perf tools: Update Makefile for Android For cross-compiling on Android, some specific changes are needed in the Makefile. Update the Makefile to support cross-compiling for Android. The original ideea for this was send by Bernhard Rosenkraenzer in https://lkml.org/lkml/2012/8/23/316, but this is a rewrite. Changes: () support bionic in addition to glibc () remove rt and pthread libraries that do not exist in Android () use $(CFLAGS) when detecting initial compiler flags. This is needed when setting CFLAGS as an argument of make (e.g. for setting --sysroot). () include perf's local directory when building for Android to be able to find relative paths if using --sysroot (e.g.: ../../include/linux/perf_event.h) Signed-off-by: Irina Tirdea Cc: Bernhard Rosenkraenzer Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1349678613-7045-3-git-send-email-irina.tirdea@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 25 +++++++++++++++++++------ tools/perf/config/feature-tests.mak | 9 +++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index a7d8745e0ab..318bec8e14e 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -155,15 +155,15 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ -include config/feature-tests.mak -ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -fstack-protector-all),y) +ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all),y) CFLAGS := $(CFLAGS) -fstack-protector-all endif -ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -Wstack-protector),y) +ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector),y) CFLAGS := $(CFLAGS) -Wstack-protector endif -ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -Wvolatile-register-var),y) +ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var),y) CFLAGS := $(CFLAGS) -Wvolatile-register-var endif @@ -172,6 +172,13 @@ endif BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE BASIC_LDFLAGS = +ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS)),y) + BIONIC := 1 + EXTLIBS := $(filter-out -lrt,$(EXTLIBS)) + EXTLIBS := $(filter-out -lpthread,$(EXTLIBS)) + BASIC_CFLAGS += -I. +endif + # Guard against environment variables BUILTIN_OBJS = LIB_H = @@ -469,12 +476,18 @@ else FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y) FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS) - ifneq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y) - msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static); - else + ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y) + LIBC_SUPPORT := 1 + endif + ifeq ($(BIONIC),1) + LIBC_SUPPORT := 1 + endif + ifeq ($(LIBC_SUPPORT),1) NO_LIBELF := 1 NO_DWARF := 1 NO_DEMANGLE := 1 + else + msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static); endif else FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS) diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index eaeb0fd6f39..3ef5ec9cdff 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak @@ -43,6 +43,15 @@ int main(void) } endef +define SOURCE_BIONIC +#include + +int main(void) +{ + return __ANDROID_API__; +} +endef + define SOURCE_ELF_MMAP #include int main(void) -- cgit v1.2.3 From 7747e2f4fb5fb840994613dd1474c17cddb7836b Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Mon, 8 Oct 2012 09:43:28 +0300 Subject: Documentation: add documentation on compiling for Android Add documentation for cross-compiling on Android including: () instructions on how to set the Android NDK environment () how to cross-compile perf for Android () how to install on an Android device/emulator, set the runtime environment and run it Signed-off-by: Irina Tirdea Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1349678613-7045-4-git-send-email-irina.tirdea@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/android.txt | 75 ++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 tools/perf/Documentation/android.txt diff --git a/tools/perf/Documentation/android.txt b/tools/perf/Documentation/android.txt new file mode 100644 index 00000000000..a39dbbb44c4 --- /dev/null +++ b/tools/perf/Documentation/android.txt @@ -0,0 +1,75 @@ +How to compile perf for Android +========================================= + +I. Set the Android NDK environment +------------------------------------------------ + +(a). Use the Android NDK +------------------------------------------------ +1. You need to download and install the Android Native Development Kit (NDK). +Set the NDK variable to point to the path where you installed the NDK: + export NDK=/path/to/android-ndk + +2. Set cross-compiling environment variables for NDK toolchain and sysroot. +For arm: + export NDK_TOOLCHAIN=${NDK}/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi- + export NDK_SYSROOT=${NDK}/platforms/android-9/arch-arm +For x86: + export NDK_TOOLCHAIN=${NDK}/toolchains/x86-4.6/prebuilt/linux-x86/bin/i686-linux-android- + export NDK_SYSROOT=${NDK}/platforms/android-9/arch-x86 + +This method is not working for Android NDK versions up to Revision 8b. +perf uses some bionic enhancements that are not included in these NDK versions. +You can use method (b) described below instead. + +(b). Use the Android source tree +----------------------------------------------- +1. Download the master branch of the Android source tree. +Set the environment for the target you want using: + source build/envsetup.sh + lunch + +2. Build your own NDK sysroot to contain latest bionic changes and set the +NDK sysroot environment variable. + cd ${ANDROID_BUILD_TOP}/ndk +For arm: + ./build/tools/build-ndk-sysroot.sh --abi=arm + export NDK_SYSROOT=${ANDROID_BUILD_TOP}/ndk/build/platforms/android-3/arch-arm +For x86: + ./build/tools/build-ndk-sysroot.sh --abi=x86 + export NDK_SYSROOT=${ANDROID_BUILD_TOP}/ndk/build/platforms/android-3/arch-x86 + +3. Set the NDK toolchain environment variable. +For arm: + export NDK_TOOLCHAIN=${ANDROID_TOOLCHAIN}/arm-linux-androideabi- +For x86: + export NDK_TOOLCHAIN=${ANDROID_TOOLCHAIN}/i686-linux-android- + +II. Compile perf for Android +------------------------------------------------ +You need to run make with the NDK toolchain and sysroot defined above: + make CROSS_COMPILE=${NDK_TOOLCHAIN} CFLAGS="--sysroot=${NDK_SYSROOT}" + +III. Install perf +----------------------------------------------- +You need to connect to your Android device/emulator using adb. +Install perf using: + adb push perf /data/perf + +If you also want to use perf-archive you need busybox tools for Android. +For installing perf-archive, you first need to replace #!/bin/bash with #!/system/bin/sh: + sed 's/#!\/bin\/bash/#!\/system\/bin\/sh/g' perf-archive >> /tmp/perf-archive + chmod +x /tmp/perf-archive + adb push /tmp/perf-archive /data/perf-archive + +IV. Environment settings for running perf +------------------------------------------------ +Some perf features need environment variables to run properly. +You need to set these before running perf on the target: + adb shell + # PERF_PAGER=cat + +IV. Run perf +------------------------------------------------ +Run perf on your device/emulator to which you previously connected using adb: + # ./data/perf -- cgit v1.2.3 From bc86cf7af2ebda88056538e8edff852ee627f76a Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 9 Oct 2012 23:26:06 -0700 Subject: mtd: nand: fix Samsung SLC NAND identification regression A combination of the following two commits caused a regression in 3.7-rc1 when identifying some Samsung NAND, so that some previously working NAND were no longer detected properly: commit e3b88bd604283ef83ae6e8f53622d5b1ffe9d43a mtd: nand: add generic READ ID length calculation functions commit e2d3a35ee427aaba99b6c68a56609ce276c51270 mtd: nand: detect Samsung K9GBG08U0A, K9GAG08U0F ID Particularly, a regression was seen on Samsung K9F2G08U0B, with the following full 8-byte READ ID string: ec da 10 95 44 00 ec da The basic problem is that Samsung manufactures both SLC and MLC NAND that use a non-standard decoding table for deriving information from their IDs. I have heuristically determined that all the chips that use the new table have ID strings which wrap around after the 6th byte. Unfortunately, I overlooked the fact that some older Samsung SLC (which use a different decoding table) have "5 byte ID strings" which also wrap around after the 6th byte. This patch re-introduces a distinction between these old and new Samsung NAND by checking that the 6th byte is non-zero, allowing both old and new Samsung NAND to be detected properly. Signed-off-by: Brian Norris Tested-by: Brian Norris Reported-by: Marek Vasut Tested-by: Marek Vasut Signed-off-by: David Woodhouse --- drivers/mtd/nand/nand_base.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ec6841d8e95..d5ece6ea6f9 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2983,13 +2983,14 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, /* * Field definitions are in the following datasheets: * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) - * New style (6 byte ID): Samsung K9GAG08U0F (p.44) + * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) * - * Check for ID length, cell type, and Hynix/Samsung ID to decide what - * to do. + * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung + * ID to decide what to do. */ - if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) { + if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && + id_data[5] != 0x00) { /* Calc pagesize */ mtd->writesize = 2048 << (extid & 0x03); extid >>= 2; -- cgit v1.2.3 From 5a6ea4af0907f995dc06df21a9c9ef764c7cd3bc Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 25 Sep 2012 15:27:13 +0530 Subject: mtd: ofpart: Fix incorrect NULL check in parse_ofoldpart_partitions() The pointer returned by kzalloc should be tested for NULL to avoid potential NULL pointer dereference later. Incorrect pointer was being tested for NULL. Bug introduced by commit fbcf62a3 (mtd: physmap_of: move parse_obsolete_partitions to become separate parser). This patch fixes this bug. Cc: Dmitry Eremin-Solenikov Cc: Artem Bityutskiy Cc: stable@kernel.org Signed-off-by: Sachin Kamat Signed-off-by: David Woodhouse --- drivers/mtd/ofpart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index 64be8f0848b..d9127e2ed80 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c @@ -121,7 +121,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, nr_parts = plen / sizeof(part[0]); *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL); - if (!pparts) + if (!*pparts) return -ENOMEM; names = of_get_property(dp, "partition-names", &plen); -- cgit v1.2.3 From 8d39e0fd080fbc2287bca3f596741a38281634da Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 16 Aug 2012 17:36:55 +0800 Subject: arm: at91: use macro to declare soc boot data Instead of check the pointer of the init function, check the new builtin bool to known if the soc is enabled. This is needed as with the switch to the pinctrl the init will be NULL on pure DT SoC. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/at91rm9200.c | 4 ++-- arch/arm/mach-at91/at91sam9260.c | 4 ++-- arch/arm/mach-at91/at91sam9261.c | 4 ++-- arch/arm/mach-at91/at91sam9263.c | 4 ++-- arch/arm/mach-at91/at91sam9g45.c | 4 ++-- arch/arm/mach-at91/at91sam9n12.c | 4 ++-- arch/arm/mach-at91/at91sam9rl.c | 4 ++-- arch/arm/mach-at91/at91sam9x5.c | 4 ++-- arch/arm/mach-at91/soc.h | 12 +++++++++++- 9 files changed, 27 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index b4f0565aff6..a45473425f5 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -361,10 +361,10 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { 0 /* Advanced Interrupt Controller (IRQ6) */ }; -struct at91_init_soc __initdata at91rm9200_soc = { +AT91_SOC_START(rm9200) .map_io = at91rm9200_map_io, .default_irq_priority = at91rm9200_default_irq_priority, .ioremap_registers = at91rm9200_ioremap_registers, .register_clocks = at91rm9200_register_clocks, .init = at91rm9200_initialize, -}; +AT91_SOC_END diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index ad29f93f20c..1dc40620ccf 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -390,10 +390,10 @@ static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller */ }; -struct at91_init_soc __initdata at91sam9260_soc = { +AT91_SOC_START(sam9260) .map_io = at91sam9260_map_io, .default_irq_priority = at91sam9260_default_irq_priority, .ioremap_registers = at91sam9260_ioremap_registers, .register_clocks = at91sam9260_register_clocks, .init = at91sam9260_initialize, -}; +AT91_SOC_END diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c index 8d999eb1a13..93a24e921af 100644 --- a/arch/arm/mach-at91/at91sam9261.c +++ b/arch/arm/mach-at91/at91sam9261.c @@ -334,10 +334,10 @@ static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller */ }; -struct at91_init_soc __initdata at91sam9261_soc = { +AT91_SOC_START(sam9261) .map_io = at91sam9261_map_io, .default_irq_priority = at91sam9261_default_irq_priority, .ioremap_registers = at91sam9261_ioremap_registers, .register_clocks = at91sam9261_register_clocks, .init = at91sam9261_initialize, -}; +AT91_SOC_END diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 6a01d0360df..03cac586e36 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -365,10 +365,10 @@ static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller (IRQ1) */ }; -struct at91_init_soc __initdata at91sam9263_soc = { +AT91_SOC_START(sam9263) .map_io = at91sam9263_map_io, .default_irq_priority = at91sam9263_default_irq_priority, .ioremap_registers = at91sam9263_ioremap_registers, .register_clocks = at91sam9263_register_clocks, .init = at91sam9263_initialize, -}; +AT91_SOC_END diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 84af1b506d9..32504b9eed9 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -409,10 +409,10 @@ static unsigned int at91sam9g45_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller (IRQ0) */ }; -struct at91_init_soc __initdata at91sam9g45_soc = { +AT91_SOC_START(sam9g45) .map_io = at91sam9g45_map_io, .default_irq_priority = at91sam9g45_default_irq_priority, .ioremap_registers = at91sam9g45_ioremap_registers, .register_clocks = at91sam9g45_register_clocks, .init = at91sam9g45_initialize, -}; +AT91_SOC_END diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c index 732d3d3f4ec..3905465f3ab 100644 --- a/arch/arm/mach-at91/at91sam9n12.c +++ b/arch/arm/mach-at91/at91sam9n12.c @@ -228,8 +228,8 @@ void __init at91sam9n12_initialize(void) at91_gpio_init(NULL, 0); } -struct at91_init_soc __initdata at91sam9n12_soc = { +AT91_SOC_START(sam9n12) .map_io = at91sam9n12_map_io, .register_clocks = at91sam9n12_register_clocks, .init = at91sam9n12_initialize, -}; +AT91_SOC_END diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c index 72e90841222..cbe72e44c13 100644 --- a/arch/arm/mach-at91/at91sam9rl.c +++ b/arch/arm/mach-at91/at91sam9rl.c @@ -338,10 +338,10 @@ static unsigned int at91sam9rl_default_irq_priority[NR_AIC_IRQS] __initdata = { 0, /* Advanced Interrupt Controller */ }; -struct at91_init_soc __initdata at91sam9rl_soc = { +AT91_SOC_START(sam9rl) .map_io = at91sam9rl_map_io, .default_irq_priority = at91sam9rl_default_irq_priority, .ioremap_registers = at91sam9rl_ioremap_registers, .register_clocks = at91sam9rl_register_clocks, .init = at91sam9rl_initialize, -}; +AT91_SOC_END diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index e5035380dcb..f31d3a065d5 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c @@ -323,8 +323,8 @@ void __init at91sam9x5_initialize(void) * Interrupt initialization * -------------------------------------------------------------------- */ -struct at91_init_soc __initdata at91sam9x5_soc = { +AT91_SOC_START(sam9x5) .map_io = at91sam9x5_map_io, .register_clocks = at91sam9x5_register_clocks, .init = at91sam9x5_initialize, -}; +AT91_SOC_END diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h index a9cfeb15371..9c6d3d4f9a2 100644 --- a/arch/arm/mach-at91/soc.h +++ b/arch/arm/mach-at91/soc.h @@ -5,6 +5,7 @@ */ struct at91_init_soc { + int builtin; unsigned int *default_irq_priority; void (*map_io)(void); void (*ioremap_registers)(void); @@ -22,9 +23,18 @@ extern struct at91_init_soc at91sam9rl_soc; extern struct at91_init_soc at91sam9x5_soc; extern struct at91_init_soc at91sam9n12_soc; +#define AT91_SOC_START(_name) \ +struct at91_init_soc __initdata at91##_name##_soc \ + __used \ + = { \ + .builtin = 1, \ + +#define AT91_SOC_END \ +}; + static inline int at91_soc_is_enabled(void) { - return at91_boot_soc.init != NULL; + return at91_boot_soc.builtin; } #if !defined(CONFIG_SOC_AT91RM9200) -- cgit v1.2.3 From c18486e10d5801b832b34708f6d2bd266c704793 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 6 Jul 2012 06:48:33 +0800 Subject: ARM: at91: gpio: implement request Configure the pin as pio when requested. It is needed to configure the pin as PIO at "request time" when we are using DT. Indeed, the muxing via old AT91 API is not allowed anymore if we are using the plain gpiolib. Acked-by: Nicolas Ferre Acked-by: Linus Walleij Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/gpio.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index be42cf0e74b..3b8f463bfa1 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -46,6 +46,7 @@ struct at91_gpio_chip { #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) +static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset); static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip); static void at91_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val); static int at91_gpiolib_get(struct gpio_chip *chip, unsigned offset); @@ -59,6 +60,7 @@ static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); { \ .chip = { \ .label = name, \ + .request = at91_gpiolib_request, \ .direction_input = at91_gpiolib_direction_input, \ .direction_output = at91_gpiolib_direction_output, \ .get = at91_gpiolib_get, \ @@ -862,6 +864,16 @@ void __init at91_gpio_irq_setup(void) } /* gpiolib support */ +static int at91_gpiolib_request(struct gpio_chip *chip, unsigned offset) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << offset; + + __raw_writel(mask, pio + PIO_PER); + return 0; +} + static int at91_gpiolib_direction_input(struct gpio_chip *chip, unsigned offset) { -- cgit v1.2.3 From e4541ff21284e5f2208473b39b535fcd50318c92 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 4 Jul 2012 17:20:46 +0800 Subject: at91: regroup gpio and pinctrl under the same ranges Fix also the reg size as we have 512 bytes bank not 256 bytes per gpio/mux controller Acked-by: Linus Walleij Acked-by: Nicolas Ferre Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9260.dtsi | 59 +++++++++++---------- arch/arm/boot/dts/at91sam9263.dtsi | 102 ++++++++++++++++++++----------------- arch/arm/boot/dts/at91sam9g45.dtsi | 95 ++++++++++++++++++---------------- arch/arm/boot/dts/at91sam9n12.dtsi | 83 ++++++++++++++++-------------- arch/arm/boot/dts/at91sam9x5.dtsi | 77 +++++++++++++++------------- 5 files changed, 225 insertions(+), 191 deletions(-) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index d410581a5a8..425da936051 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -98,34 +98,41 @@ interrupts = <26 4 0 27 4 0 28 4 0>; }; - pioA: gpio@fffff400 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff400 0x100>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pinctrl@fffff400 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; + ranges = <0xfffff400 0xfffff400 0x600>; + + pioA: gpio@fffff400 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x200>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioB: gpio@fffff600 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff600 0x100>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioB: gpio@fffff600 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x200>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioC: gpio@fffff800 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff800 0x100>; - interrupts = <4 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; + pioC: gpio@fffff800 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x200>; + interrupts = <4 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; }; dbgu: serial@fffff200 { diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 3e6e5c1abbf..5b619c9255b 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -89,54 +89,60 @@ reg = <0xfffffd10 0x10>; }; - pioA: gpio@fffff200 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff200 0x100>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pioB: gpio@fffff400 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff400 0x100>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pioC: gpio@fffff600 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff600 0x100>; - interrupts = <4 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pioD: gpio@fffff800 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff800 0x100>; - interrupts = <4 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pioE: gpio@fffffa00 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffffa00 0x100>; - interrupts = <4 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; + pinctrl@fffff200 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; + ranges = <0xfffff200 0xfffff200 0xa00>; + + pioA: gpio@fffff200 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff200 0x200>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pioB: gpio@fffff400 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x200>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pioC: gpio@fffff600 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x200>; + interrupts = <4 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pioD: gpio@fffff800 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x200>; + interrupts = <4 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pioE: gpio@fffffa00 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x200>; + interrupts = <4 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; }; dbgu: serial@ffffee00 { diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 3add030d61f..f2b0f93c049 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -108,54 +108,61 @@ interrupts = <21 4 0>; }; - pioA: gpio@fffff200 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff200 0x100>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pinctrl@fffff200 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; + ranges = <0xfffff200 0xfffff200 0xa00>; + + pioA: gpio@fffff200 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff200 0x200>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioB: gpio@fffff400 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff400 0x100>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioB: gpio@fffff400 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x200>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioC: gpio@fffff600 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff600 0x100>; - interrupts = <4 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioC: gpio@fffff600 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x200>; + interrupts = <4 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioD: gpio@fffff800 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffff800 0x100>; - interrupts = <5 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioD: gpio@fffff800 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x200>; + interrupts = <5 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioE: gpio@fffffa00 { - compatible = "atmel,at91rm9200-gpio"; - reg = <0xfffffa00 0x100>; - interrupts = <5 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; + pioE: gpio@fffffa00 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x200>; + interrupts = <5 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; }; dbgu: serial@ffffee00 { diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 82508d68aa7..b061c062602 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -102,44 +102,51 @@ interrupts = <20 4 0>; }; - pioA: gpio@fffff400 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffff400 0x100>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pioB: gpio@fffff600 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffff600 0x100>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pioC: gpio@fffff800 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffff800 0x100>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; - - pioD: gpio@fffffa00 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffffa00 0x100>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; + pinctrl@fffff400 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; + ranges = <0xfffff400 0xfffff400 0x800>; + + pioA: gpio@fffff400 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x200>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pioB: gpio@fffff600 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x200>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pioC: gpio@fffff800 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x200>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pioD: gpio@fffffa00 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x200>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; }; dbgu: serial@fffff200 { diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 03fc136421c..507a84d2a5d 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -111,44 +111,51 @@ interrupts = <21 4 0>; }; - pioA: gpio@fffff400 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffff400 0x100>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pinctrl@fffff200 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; + ranges = <0xfffff400 0xfffff400 0x800>; + + pioA: gpio@fffff400 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x200>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioB: gpio@fffff600 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffff600 0x100>; - interrupts = <2 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioB: gpio@fffff600 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x200>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioC: gpio@fffff800 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffff800 0x100>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; - }; + pioC: gpio@fffff800 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x200>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; - pioD: gpio@fffffa00 { - compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; - reg = <0xfffffa00 0x100>; - interrupts = <3 4 1>; - #gpio-cells = <2>; - gpio-controller; - interrupt-controller; - #interrupt-cells = <2>; + pioD: gpio@fffffa00 { + compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x200>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; }; dbgu: serial@fffff200 { -- cgit v1.2.3 From fc33ff43134790ef3cb997ed90048a50b4d1b15e Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 14 Jul 2012 15:26:08 +0800 Subject: arm: at91: at91sam9x5: fix gpio number per bank On the at91sam9x5 SoC series, GPIO banks B and D only have 19 and 22 pins. So add a property to set this parameter. Acked-by: Nicolas Ferre Acked-by: Linus Walleij Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- .../devicetree/bindings/gpio/gpio_atmel.txt | 5 ++++ arch/arm/boot/dts/at91sam9x5.dtsi | 2 ++ arch/arm/mach-at91/gpio.c | 33 ++++++++++++++-------- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/gpio/gpio_atmel.txt b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt index 66efc804806..85f8c0d084f 100644 --- a/Documentation/devicetree/bindings/gpio/gpio_atmel.txt +++ b/Documentation/devicetree/bindings/gpio/gpio_atmel.txt @@ -9,6 +9,10 @@ Required properties: unused). - gpio-controller: Marks the device node as a GPIO controller. +optional properties: +- #gpio-lines: Number of gpio if absent 32. + + Example: pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; @@ -16,5 +20,6 @@ Example: interrupts = <2 4>; #gpio-cells = <2>; gpio-controller; + #gpio-lines = <19>; }; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 507a84d2a5d..065698ac4de 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -133,6 +133,7 @@ interrupts = <2 4 1>; #gpio-cells = <2>; gpio-controller; + #gpio-lines = <19>; interrupt-controller; #interrupt-cells = <2>; }; @@ -153,6 +154,7 @@ interrupts = <3 4 1>; #gpio-cells = <2>; gpio-controller; + #gpio-lines = <22>; interrupt-controller; #interrupt-cells = <2>; }; diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 3b8f463bfa1..a34f0ed291c 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -33,6 +33,8 @@ #include "generic.h" +#define MAX_NB_GPIO_PER_BANK 32 + struct at91_gpio_chip { struct gpio_chip chip; struct at91_gpio_chip *next; /* Bank sharing same clock */ @@ -56,7 +58,7 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip, unsigned offset); static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); -#define AT91_GPIO_CHIP(name, nr_gpio) \ +#define AT91_GPIO_CHIP(name) \ { \ .chip = { \ .label = name, \ @@ -67,16 +69,16 @@ static int at91_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset); .set = at91_gpiolib_set, \ .dbg_show = at91_gpiolib_dbg_show, \ .to_irq = at91_gpiolib_to_irq, \ - .ngpio = nr_gpio, \ + .ngpio = MAX_NB_GPIO_PER_BANK, \ }, \ } static struct at91_gpio_chip gpio_chip[] = { - AT91_GPIO_CHIP("pioA", 32), - AT91_GPIO_CHIP("pioB", 32), - AT91_GPIO_CHIP("pioC", 32), - AT91_GPIO_CHIP("pioD", 32), - AT91_GPIO_CHIP("pioE", 32), + AT91_GPIO_CHIP("pioA"), + AT91_GPIO_CHIP("pioB"), + AT91_GPIO_CHIP("pioC"), + AT91_GPIO_CHIP("pioD"), + AT91_GPIO_CHIP("pioE"), }; static int gpio_banks; @@ -91,7 +93,7 @@ static unsigned long at91_gpio_caps; static inline void __iomem *pin_to_controller(unsigned pin) { - pin /= 32; + pin /= MAX_NB_GPIO_PER_BANK; if (likely(pin < gpio_banks)) return gpio_chip[pin].regbase; @@ -100,7 +102,7 @@ static inline void __iomem *pin_to_controller(unsigned pin) static inline unsigned pin_to_mask(unsigned pin) { - return 1 << (pin % 32); + return 1 << (pin % MAX_NB_GPIO_PER_BANK); } @@ -992,6 +994,7 @@ static void __init of_at91_gpio_init_one(struct device_node *np) { int alias_idx; struct at91_gpio_chip *at91_gpio; + uint32_t ngpio; if (!np) return; @@ -1004,7 +1007,7 @@ static void __init of_at91_gpio_init_one(struct device_node *np) } at91_gpio = &gpio_chip[alias_idx]; - at91_gpio->chip.base = alias_idx * at91_gpio->chip.ngpio; + at91_gpio->chip.base = alias_idx * MAX_NB_GPIO_PER_BANK; at91_gpio->regbase = of_iomap(np, 0); if (!at91_gpio->regbase) { @@ -1024,6 +1027,14 @@ static void __init of_at91_gpio_init_one(struct device_node *np) if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio")) at91_gpio_caps |= AT91_GPIO_CAP_PIO3; + if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) { + if (ngpio >= MAX_NB_GPIO_PER_BANK) + pr_err("at91_gpio.%d, gpio-nb >= %d failback to %d\n", + alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK); + else + at91_gpio->chip.ngpio = ngpio; + } + /* Setup clock */ if (at91_gpio_setup_clk(alias_idx)) goto ioremap_err; @@ -1061,7 +1072,7 @@ static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq) { struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; - at91_gpio->chip.base = idx * at91_gpio->chip.ngpio; + at91_gpio->chip.base = idx * MAX_NB_GPIO_PER_BANK; at91_gpio->pioc_hwirq = pioc_hwirq; at91_gpio->pioc_idx = idx; -- cgit v1.2.3 From 97e5e625248e588de234aa5134cebbf969618dcf Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 12 Jul 2012 23:35:02 +0800 Subject: ARM: at91: add dummies pinctrl for non dt platform Acked-by: Nicolas Ferre Acked-by: Linus Walleij Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/setup.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index da9881b161e..e228d7377b6 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -463,4 +464,6 @@ void __init at91_initialize(unsigned long main_clock) at91_boot_soc.register_clocks(); at91_boot_soc.init(); + + pinctrl_provide_dummies(); } -- cgit v1.2.3 From 6732ae5cb47c4f9a72727585956f2a5e069d1637 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 12 Jul 2012 23:35:02 +0800 Subject: ARM: at91: add pinctrl support This is also include the gpio controller as the IP share both. Each soc will have to describe the SoC limitation and pin configuration via DT. This will allow to do not need to touch the C code when adding new SoC if the IP version is supported. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- .../bindings/pinctrl/atmel,at91-pinctrl.txt | 136 ++ arch/arm/Kconfig | 2 + arch/arm/mach-at91/board-dt.c | 2 - arch/arm/mach-at91/gpio.c | 165 +-- drivers/pinctrl/Kconfig | 9 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-at91.c | 1490 ++++++++++++++++++++ 7 files changed, 1643 insertions(+), 162 deletions(-) create mode 100644 Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt create mode 100644 drivers/pinctrl/pinctrl-at91.c diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt new file mode 100644 index 00000000000..20a987e55a2 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt @@ -0,0 +1,136 @@ +* Atmel AT91 Pinmux Controller + +The AT91 Pinmux Controler, enables the IC +to share one PAD to several functional blocks. The sharing is done by +multiplexing the PAD input/output signals. For each PAD there are up to +8 muxing options (called periph modes). Since different modules require +different PAD settings (like pull up, keeper, etc) the contoller controls +also the PAD settings parameters. + +Please refer to pinctrl-bindings.txt in this directory for details of the +common pinctrl bindings used by client devices, including the meaning of the +phrase "pin configuration node". + +Atmel AT91 pin configuration node is a node of a group of pins which can be +used for a specific device or function. This node represents both mux and config +of the pins in that group. The 'pins' selects the function mode(also named pin +mode) this pin can work on and the 'config' configures various pad settings +such as pull-up, multi drive, etc. + +Required properties for iomux controller: +- compatible: "atmel,at91rm9200-pinctrl" +- atmel,mux-mask: array of mask (periph per bank) to describe if a pin can be + configured in this periph mode. All the periph and bank need to be describe. + +How to create such array: + +Each column will represent the possible peripheral of the pinctrl +Each line will represent a pio bank + +Take an example on the 9260 +Peripheral: 2 ( A and B) +Bank: 3 (A, B and C) +=> + + /* A B */ + 0xffffffff 0xffc00c3b /* pioA */ + 0xffffffff 0x7fff3ccf /* pioB */ + 0xffffffff 0x007fffff /* pioC */ + +For each peripheral/bank we will descibe in a u32 if a pin can can be +configured in it by putting 1 to the pin bit (1 << pin) + +Let's take the pioA on peripheral B +From the datasheet Table 10-2. +Peripheral B +PA0 MCDB0 +PA1 MCCDB +PA2 +PA3 MCDB3 +PA4 MCDB2 +PA5 MCDB1 +PA6 +PA7 +PA8 +PA9 +PA10 ETX2 +PA11 ETX3 +PA12 +PA13 +PA14 +PA15 +PA16 +PA17 +PA18 +PA19 +PA20 +PA21 +PA22 ETXER +PA23 ETX2 +PA24 ETX3 +PA25 ERX2 +PA26 ERX3 +PA27 ERXCK +PA28 ECRS +PA29 ECOL +PA30 RXD4 +PA31 TXD4 + +=> 0xffc00c3b + +Required properties for pin configuration node: +- atmel,pins: 4 integers array, represents a group of pins mux and config + setting. The format is atmel,pins = . + The PERIPH 0 means gpio. + +Bits used for CONFIG: +PULL_UP(1 << 0): indicate this pin need a pull up. +MULTIDRIVE(1 << 1): indicate this pin need to be configured as multidrive. + +NOTE: +Some requirements for using atmel,at91rm9200-pinctrl binding: +1. We have pin function node defined under at91 controller node to represent + what pinmux functions this SoC supports. +2. The driver can use the function node's name and pin configuration node's + name describe the pin function and group hierarchy. + For example, Linux at91 pinctrl driver takes the function node's name + as the function name and pin configuration node's name as group name to + create the map table. +3. Each pin configuration node should have a phandle, devices can set pins + configurations by referring to the phandle of that pin configuration node. +4. The gpio controller must be describe in the pinctrl simple-bus. + +Examples: + +pinctrl@fffff400 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; + reg = <0xfffff400 0x600>; + + atmel,mux-mask = < + /* A B */ + 0xffffffff 0xffc00c3b /* pioA */ + 0xffffffff 0x7fff3ccf /* pioB */ + 0xffffffff 0x007fffff /* pioC */ + >; + + /* shared pinctrl settings */ + dbgu { + pinctrl_dbgu: dbgu-0 { + atmel,pins = + <1 14 0x1 0x0 /* PB14 periph A */ + 1 15 0x1 0x1>; /* PB15 periph with pullup */ + }; + }; +}; + +dbgu: serial@fffff200 { + compatible = "atmel,at91sam9260-usart"; + reg = <0xfffff200 0x200>; + interrupts = <1 4 7>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_dbgu>; + status = "disabled"; +}; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 431c3753145..3d7f11fe610 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -329,6 +329,8 @@ config ARCH_AT91 select IRQ_DOMAIN select NEED_MACH_GPIO_H select NEED_MACH_IO_H if PCCARD + select PINCTRL + select PINCTRL_AT91 if USE_OF help This enables support for systems based on Atmel AT91RM9200 and AT91SAM9* processors. diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c index e8f45c4e0ea..3b6a94820fa 100644 --- a/arch/arm/mach-at91/board-dt.c +++ b/arch/arm/mach-at91/board-dt.c @@ -30,8 +30,6 @@ static const struct of_device_id irq_of_match[] __initconst = { { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, - { .compatible = "atmel,at91rm9200-gpio", .data = at91_gpio_of_irq_setup }, - { .compatible = "atmel,at91sam9x5-gpio", .data = at91_gpio_of_irq_setup }, { /*sentinel*/ } }; diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index a34f0ed291c..c5d7e1e9d75 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include #include @@ -717,80 +715,6 @@ postcore_initcall(at91_gpio_debugfs_init); */ static struct lock_class_key gpio_lock_class; -#if defined(CONFIG_OF) -static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct at91_gpio_chip *at91_gpio = h->host_data; - - irq_set_lockdep_class(virq, &gpio_lock_class); - - /* - * Can use the "simple" and not "edge" handler since it's - * shorter, and the AIC handles interrupts sanely. - */ - irq_set_chip_and_handler(virq, &gpio_irqchip, - handle_simple_irq); - set_irq_flags(virq, IRQF_VALID); - irq_set_chip_data(virq, at91_gpio); - - return 0; -} - -static struct irq_domain_ops at91_gpio_ops = { - .map = at91_gpio_irq_map, - .xlate = irq_domain_xlate_twocell, -}; - -int __init at91_gpio_of_irq_setup(struct device_node *node, - struct device_node *parent) -{ - struct at91_gpio_chip *prev = NULL; - int alias_idx = of_alias_get_id(node, "gpio"); - struct at91_gpio_chip *at91_gpio = &gpio_chip[alias_idx]; - - /* Setup proper .irq_set_type function */ - if (has_pio3()) - gpio_irqchip.irq_set_type = alt_gpio_irq_type; - else - gpio_irqchip.irq_set_type = gpio_irq_type; - - /* Disable irqs of this PIO controller */ - __raw_writel(~0, at91_gpio->regbase + PIO_IDR); - - /* Setup irq domain */ - at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio, - &at91_gpio_ops, at91_gpio); - if (!at91_gpio->domain) - panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n", - at91_gpio->pioc_idx); - - /* Setup chained handler */ - if (at91_gpio->pioc_idx) - prev = &gpio_chip[at91_gpio->pioc_idx - 1]; - - /* The toplevel handler handles one bank of GPIOs, except - * on some SoC it can handles up to three... - * We only set up the handler for the first of the list. - */ - if (prev && prev->next == at91_gpio) - return 0; - - at91_gpio->pioc_virq = irq_create_mapping(irq_find_host(parent), - at91_gpio->pioc_hwirq); - irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio); - irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler); - - return 0; -} -#else -int __init at91_gpio_of_irq_setup(struct device_node *node, - struct device_node *parent) -{ - return -EINVAL; -} -#endif - /* * irqdomain initialization: pile up irqdomains on top of AIC range */ @@ -989,85 +913,6 @@ err: return -EINVAL; } -#ifdef CONFIG_OF_GPIO -static void __init of_at91_gpio_init_one(struct device_node *np) -{ - int alias_idx; - struct at91_gpio_chip *at91_gpio; - uint32_t ngpio; - - if (!np) - return; - - alias_idx = of_alias_get_id(np, "gpio"); - if (alias_idx >= MAX_GPIO_BANKS) { - pr_err("at91_gpio, failed alias idx(%d) > MAX_GPIO_BANKS(%d), ignoring.\n", - alias_idx, MAX_GPIO_BANKS); - return; - } - - at91_gpio = &gpio_chip[alias_idx]; - at91_gpio->chip.base = alias_idx * MAX_NB_GPIO_PER_BANK; - - at91_gpio->regbase = of_iomap(np, 0); - if (!at91_gpio->regbase) { - pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", - alias_idx); - return; - } - - /* Get the interrupts property */ - if (of_property_read_u32(np, "interrupts", &at91_gpio->pioc_hwirq)) { - pr_err("at91_gpio.%d, failed to get interrupts property, ignoring.\n", - alias_idx); - goto ioremap_err; - } - - /* Get capabilities from compatibility property */ - if (of_device_is_compatible(np, "atmel,at91sam9x5-gpio")) - at91_gpio_caps |= AT91_GPIO_CAP_PIO3; - - if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) { - if (ngpio >= MAX_NB_GPIO_PER_BANK) - pr_err("at91_gpio.%d, gpio-nb >= %d failback to %d\n", - alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK); - else - at91_gpio->chip.ngpio = ngpio; - } - - /* Setup clock */ - if (at91_gpio_setup_clk(alias_idx)) - goto ioremap_err; - - at91_gpio->chip.of_node = np; - gpio_banks = max(gpio_banks, alias_idx + 1); - at91_gpio->pioc_idx = alias_idx; - return; - -ioremap_err: - iounmap(at91_gpio->regbase); -} - -static int __init of_at91_gpio_init(void) -{ - struct device_node *np = NULL; - - /* - * This isn't ideal, but it gets things hooked up until this - * driver is converted into a platform_device - */ - for_each_compatible_node(np, NULL, "atmel,at91rm9200-gpio") - of_at91_gpio_init_one(np); - - return gpio_banks > 0 ? 0 : -EINVAL; -} -#else -static int __init of_at91_gpio_init(void) -{ - return -EINVAL; -} -#endif - static void __init at91_gpio_init_one(int idx, u32 regbase, int pioc_hwirq) { struct at91_gpio_chip *at91_gpio = &gpio_chip[idx]; @@ -1102,11 +947,11 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) BUG_ON(nr_banks > MAX_GPIO_BANKS); - if (of_at91_gpio_init() < 0) { - /* No GPIO controller found in device tree */ - for (i = 0; i < nr_banks; i++) - at91_gpio_init_one(i, data[i].regbase, data[i].id); - } + if (of_have_populated_dt()) + return; + + for (i = 0; i < nr_banks; i++) + at91_gpio_init_one(i, data[i].regbase, data[i].id); for (i = 0; i < gpio_banks; i++) { at91_gpio = &gpio_chip[i]; diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 7bf914df6e9..4787f0e4597 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -26,6 +26,15 @@ config DEBUG_PINCTRL help Say Y here to add some extra checks and diagnostics to PINCTRL calls. +config PINCTRL_AT91 + bool "AT91 pinctrl driver" + depends on OF + depends on ARCH_AT91 + select PINMUX + select PINCONF + help + Say Y here to enable the at91 pinctrl driver + config PINCTRL_BCM2835 bool select PINMUX diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index f395ba5cec2..78a191c85ad 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -9,6 +9,7 @@ ifeq ($(CONFIG_OF),y) obj-$(CONFIG_PINCTRL) += devicetree.o endif obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o +obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o obj-$(CONFIG_PINCTRL_IMX35) += pinctrl-imx35.o diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c new file mode 100644 index 00000000000..01bf92459fd --- /dev/null +++ b/drivers/pinctrl/pinctrl-at91.c @@ -0,0 +1,1490 @@ +/* + * at91 pinctrl driver based on at91 pinmux core + * + * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD + * + * Under GPLv2 only + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* Since we request GPIOs from ourself */ +#include + +#include + +#include +#include + +#include "core.h" + +#define MAX_NB_GPIO_PER_BANK 32 + +struct at91_pinctrl_mux_ops; + +struct at91_gpio_chip { + struct gpio_chip chip; + struct pinctrl_gpio_range range; + struct at91_gpio_chip *next; /* Bank sharing same clock */ + int pioc_hwirq; /* PIO bank interrupt identifier on AIC */ + int pioc_virq; /* PIO bank Linux virtual interrupt */ + int pioc_idx; /* PIO bank index */ + void __iomem *regbase; /* PIO bank virtual address */ + struct clk *clock; /* associated clock */ + struct irq_domain *domain; /* associated irq domain */ + struct at91_pinctrl_mux_ops *ops; /* ops */ +}; + +#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip) + +static struct at91_gpio_chip *gpio_chips[MAX_GPIO_BANKS]; + +static int gpio_banks; + +#define PULL_UP (0 << 1) +#define MULTI_DRIVE (1 << 1) + +/** + * struct at91_pmx_func - describes AT91 pinmux functions + * @name: the name of this specific function + * @groups: corresponding pin groups + * @ngroups: the number of groups + */ +struct at91_pmx_func { + const char *name; + const char **groups; + unsigned ngroups; +}; + +enum at91_mux { + AT91_MUX_GPIO = 0, + AT91_MUX_PERIPH_A = 1, + AT91_MUX_PERIPH_B = 2, + AT91_MUX_PERIPH_C = 3, + AT91_MUX_PERIPH_D = 4, +}; + +/** + * struct at91_pmx_pin - describes an At91 pin mux + * @bank: the bank of the pin + * @pin: the pin number in the @bank + * @mux: the mux mode : gpio or periph_x of the pin i.e. alternate function. + * @conf: the configuration of the pin: PULL_UP, MULTIDRIVE etc... + */ +struct at91_pmx_pin { + uint32_t bank; + uint32_t pin; + enum at91_mux mux; + unsigned long conf; +}; + +/** + * struct at91_pin_group - describes an At91 pin group + * @name: the name of this specific pin group + * @pins_conf: the mux mode for each pin in this group. The size of this + * array is the same as pins. + * @pins: an array of discrete physical pins used in this group, taken + * from the driver-local pin enumeration space + * @npins: the number of pins in this group array, i.e. the number of + * elements in .pins so we can iterate over that array + */ +struct at91_pin_group { + const char *name; + struct at91_pmx_pin *pins_conf; + unsigned int *pins; + unsigned npins; +}; + +/** + * struct at91_pinctrl_mux_ops - describes an At91 mux ops group + * on new IP with support for periph C and D the way to mux in + * periph A and B has changed + * So provide the right call back + * if not present means the IP does not support it + * @get_periph: return the periph mode configured + * @mux_A_periph: mux as periph A + * @mux_B_periph: mux as periph B + * @mux_C_periph: mux as periph C + * @mux_D_periph: mux as periph D + * @irq_type: return irq type + */ +struct at91_pinctrl_mux_ops { + enum at91_mux (*get_periph)(void __iomem *pio, unsigned mask); + void (*mux_A_periph)(void __iomem *pio, unsigned mask); + void (*mux_B_periph)(void __iomem *pio, unsigned mask); + void (*mux_C_periph)(void __iomem *pio, unsigned mask); + void (*mux_D_periph)(void __iomem *pio, unsigned mask); + /* irq */ + int (*irq_type)(struct irq_data *d, unsigned type); +}; + +static int gpio_irq_type(struct irq_data *d, unsigned type); +static int alt_gpio_irq_type(struct irq_data *d, unsigned type); + +struct at91_pinctrl { + struct device *dev; + struct pinctrl_dev *pctl; + + int nbanks; + + uint32_t *mux_mask; + int nmux; + + struct at91_pmx_func *functions; + int nfunctions; + + struct at91_pin_group *groups; + int ngroups; + + struct at91_pinctrl_mux_ops *ops; +}; + +static const inline struct at91_pin_group *at91_pinctrl_find_group_by_name( + const struct at91_pinctrl *info, + const char *name) +{ + const struct at91_pin_group *grp = NULL; + int i; + + for (i = 0; i < info->ngroups; i++) { + if (strcmp(info->groups[i].name, name)) + continue; + + grp = &info->groups[i]; + dev_dbg(info->dev, "%s: %d 0:%d\n", name, grp->npins, grp->pins[0]); + break; + } + + return grp; +} + +static int at91_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + return info->ngroups; +} + +static const char *at91_get_group_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + return info->groups[selector].name; +} + +static int at91_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, + const unsigned **pins, + unsigned *npins) +{ + struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + if (selector >= info->ngroups) + return -EINVAL; + + *pins = info->groups[selector].pins; + *npins = info->groups[selector].npins; + + return 0; +} + +static void at91_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned offset) +{ + seq_printf(s, "%s", dev_name(pctldev->dev)); +} + +static int at91_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np, + struct pinctrl_map **map, unsigned *num_maps) +{ + struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + const struct at91_pin_group *grp; + struct pinctrl_map *new_map; + struct device_node *parent; + int map_num = 1; + int i; + struct at91_pmx_pin *pin; + + /* + * first find the group of this node and check if we need create + * config maps for pins + */ + grp = at91_pinctrl_find_group_by_name(info, np->name); + if (!grp) { + dev_err(info->dev, "unable to find group for node %s\n", + np->name); + return -EINVAL; + } + + map_num += grp->npins; + new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num, GFP_KERNEL); + if (!new_map) + return -ENOMEM; + + *map = new_map; + *num_maps = map_num; + + /* create mux map */ + parent = of_get_parent(np); + if (!parent) { + kfree(new_map); + return -EINVAL; + } + new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; + new_map[0].data.mux.function = parent->name; + new_map[0].data.mux.group = np->name; + of_node_put(parent); + + /* create config map */ + new_map++; + for (i = 0; i < grp->npins; i++) { + pin = &grp->pins_conf[i]; + + new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; + new_map[i].data.configs.group_or_pin = + pin_get_name(pctldev, grp->pins[i]); + new_map[i].data.configs.configs = &grp->pins_conf[i].conf; + new_map[i].data.configs.num_configs = 1; + } + + dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", + (*map)->data.mux.function, (*map)->data.mux.group, map_num); + + return 0; +} + +static void at91_dt_free_map(struct pinctrl_dev *pctldev, + struct pinctrl_map *map, unsigned num_maps) +{ +} + +static struct pinctrl_ops at91_pctrl_ops = { + .get_groups_count = at91_get_groups_count, + .get_group_name = at91_get_group_name, + .get_group_pins = at91_get_group_pins, + .pin_dbg_show = at91_pin_dbg_show, + .dt_node_to_map = at91_dt_node_to_map, + .dt_free_map = at91_dt_free_map, +}; + +static void __iomem * pin_to_controller(struct at91_pinctrl *info, + unsigned int bank) +{ + return gpio_chips[bank]->regbase; +} + +static inline int pin_to_bank(unsigned pin) +{ + return pin /= MAX_NB_GPIO_PER_BANK; +} + +static unsigned pin_to_mask(unsigned int pin) +{ + return 1 << pin; +} + +static void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask) +{ + writel_relaxed(mask, pio + PIO_IDR); +} + +static unsigned at91_mux_get_pullup(void __iomem *pio, unsigned pin) +{ + return (readl_relaxed(pio + PIO_PUSR) >> pin) & 0x1; +} + +static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on) +{ + writel_relaxed(mask, pio + (on ? PIO_PUER : PIO_PUDR)); +} + +static unsigned at91_mux_get_multidrive(void __iomem *pio, unsigned pin) +{ + return (readl_relaxed(pio + PIO_MDSR) >> pin) & 0x1; +} + +static void at91_mux_set_multidrive(void __iomem *pio, unsigned mask, bool on) +{ + writel_relaxed(mask, pio + (on ? PIO_MDER : PIO_MDDR)); +} + +static void at91_mux_set_A_periph(void __iomem *pio, unsigned mask) +{ + writel_relaxed(mask, pio + PIO_ASR); +} + +static void at91_mux_set_B_periph(void __iomem *pio, unsigned mask) +{ + writel_relaxed(mask, pio + PIO_BSR); +} + +static void at91_mux_pio3_set_A_periph(void __iomem *pio, unsigned mask) +{ + + writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) & ~mask, + pio + PIO_ABCDSR1); + writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) & ~mask, + pio + PIO_ABCDSR2); +} + +static void at91_mux_pio3_set_B_periph(void __iomem *pio, unsigned mask) +{ + writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) | mask, + pio + PIO_ABCDSR1); + writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) & ~mask, + pio + PIO_ABCDSR2); +} + +static void at91_mux_pio3_set_C_periph(void __iomem *pio, unsigned mask) +{ + writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) & ~mask, pio + PIO_ABCDSR1); + writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); +} + +static void at91_mux_pio3_set_D_periph(void __iomem *pio, unsigned mask) +{ + writel_relaxed(readl_relaxed(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1); + writel_relaxed(readl_relaxed(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2); +} + +static enum at91_mux at91_mux_pio3_get_periph(void __iomem *pio, unsigned mask) +{ + unsigned select; + + if (readl_relaxed(pio + PIO_PSR) & mask) + return AT91_MUX_GPIO; + + select = !!(readl_relaxed(pio + PIO_ABCDSR1) & mask); + select |= (!!(readl_relaxed(pio + PIO_ABCDSR2) & mask) << 1); + + return select + 1; +} + +static enum at91_mux at91_mux_get_periph(void __iomem *pio, unsigned mask) +{ + unsigned select; + + if (readl_relaxed(pio + PIO_PSR) & mask) + return AT91_MUX_GPIO; + + select = readl_relaxed(pio + PIO_ABSR) & mask; + + return select + 1; +} + +static struct at91_pinctrl_mux_ops at91rm9200_ops = { + .get_periph = at91_mux_get_periph, + .mux_A_periph = at91_mux_set_A_periph, + .mux_B_periph = at91_mux_set_B_periph, + .irq_type = gpio_irq_type, +}; + +static struct at91_pinctrl_mux_ops at91sam9x5_ops = { + .get_periph = at91_mux_pio3_get_periph, + .mux_A_periph = at91_mux_pio3_set_A_periph, + .mux_B_periph = at91_mux_pio3_set_B_periph, + .mux_C_periph = at91_mux_pio3_set_C_periph, + .mux_D_periph = at91_mux_pio3_set_D_periph, + .irq_type = alt_gpio_irq_type, +}; + +static void at91_pin_dbg(const struct device *dev, const struct at91_pmx_pin *pin) +{ + if (pin->mux) { + dev_dbg(dev, "pio%c%d configured as periph%c with conf = 0x%lu\n", + pin->bank + 'A', pin->pin, pin->mux - 1 + 'A', pin->conf); + } else { + dev_dbg(dev, "pio%c%d configured as gpio with conf = 0x%lu\n", + pin->bank + 'A', pin->pin, pin->conf); + } +} + +static int pin_check_config(struct at91_pinctrl *info, const char* name, + int index, const struct at91_pmx_pin *pin) +{ + int mux; + + /* check if it's a valid config */ + if (pin->bank >= info->nbanks) { + dev_err(info->dev, "%s: pin conf %d bank_id %d >= nbanks %d\n", + name, index, pin->bank, info->nbanks); + return -EINVAL; + } + + if (pin->pin >= MAX_NB_GPIO_PER_BANK) { + dev_err(info->dev, "%s: pin conf %d pin_bank_id %d >= %d\n", + name, index, pin->pin, MAX_NB_GPIO_PER_BANK); + return -EINVAL; + } + + if (!pin->mux) + return 0; + + mux = pin->mux - 1; + + if (mux >= info->nmux) { + dev_err(info->dev, "%s: pin conf %d mux_id %d >= nmux %d\n", + name, index, mux, info->nmux); + return -EINVAL; + } + + if (!(info->mux_mask[pin->bank * info->nmux + mux] & 1 << pin->pin)) { + dev_err(info->dev, "%s: pin conf %d mux_id %d not supported for pio%c%d\n", + name, index, mux, pin->bank + 'A', pin->pin); + return -EINVAL; + } + + return 0; +} + +static void at91_mux_gpio_disable(void __iomem *pio, unsigned mask) +{ + writel_relaxed(mask, pio + PIO_PDR); +} + +static void at91_mux_gpio_enable(void __iomem *pio, unsigned mask, bool input) +{ + writel_relaxed(mask, pio + PIO_PER); + writel_relaxed(mask, pio + (input ? PIO_ODR : PIO_OER)); +} + +static int at91_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, + unsigned group) +{ + struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf; + const struct at91_pmx_pin *pin; + uint32_t npins = info->groups[group].npins; + int i, ret; + unsigned mask; + void __iomem *pio; + + dev_dbg(info->dev, "enable function %s group %s\n", + info->functions[selector].name, info->groups[group].name); + + /* first check that all the pins of the group are valid with a valid + * paramter */ + for (i = 0; i < npins; i++) { + pin = &pins_conf[i]; + ret = pin_check_config(info, info->groups[group].name, i, pin); + if (ret) + return ret; + } + + for (i = 0; i < npins; i++) { + pin = &pins_conf[i]; + at91_pin_dbg(info->dev, pin); + pio = pin_to_controller(info, pin->bank); + mask = pin_to_mask(pin->pin); + at91_mux_disable_interrupt(pio, mask); + switch(pin->mux) { + case AT91_MUX_GPIO: + at91_mux_gpio_enable(pio, mask, 1); + break; + case AT91_MUX_PERIPH_A: + info->ops->mux_A_periph(pio, mask); + break; + case AT91_MUX_PERIPH_B: + info->ops->mux_B_periph(pio, mask); + break; + case AT91_MUX_PERIPH_C: + if (!info->ops->mux_C_periph) + return -EINVAL; + info->ops->mux_C_periph(pio, mask); + break; + case AT91_MUX_PERIPH_D: + if (!info->ops->mux_D_periph) + return -EINVAL; + info->ops->mux_D_periph(pio, mask); + break; + } + if (pin->mux) + at91_mux_gpio_disable(pio, mask); + } + + return 0; +} + +static void at91_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector, + unsigned group) +{ + struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + const struct at91_pmx_pin *pins_conf = info->groups[group].pins_conf; + const struct at91_pmx_pin *pin; + uint32_t npins = info->groups[group].npins; + int i; + unsigned mask; + void __iomem *pio; + + for (i = 0; i < npins; i++) { + pin = &pins_conf[i]; + at91_pin_dbg(info->dev, pin); + pio = pin_to_controller(info, pin->bank); + mask = pin_to_mask(pin->pin); + at91_mux_gpio_enable(pio, mask, 1); + } +} + +static int at91_pmx_get_funcs_count(struct pinctrl_dev *pctldev) +{ + struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + return info->nfunctions; +} + +static const char *at91_pmx_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + return info->functions[selector].name; +} + +static int at91_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + + *groups = info->functions[selector].groups; + *num_groups = info->functions[selector].ngroups; + + return 0; +} + +int at91_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct at91_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); + struct at91_gpio_chip *at91_chip; + struct gpio_chip *chip; + unsigned mask; + + if (!range) { + dev_err(npct->dev, "invalid range\n"); + return -EINVAL; + } + if (!range->gc) { + dev_err(npct->dev, "missing GPIO chip in range\n"); + return -EINVAL; + } + chip = range->gc; + at91_chip = container_of(chip, struct at91_gpio_chip, chip); + + dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset); + + mask = 1 << (offset - chip->base); + + dev_dbg(npct->dev, "enable pin %u as PIO%c%d 0x%x\n", + offset, 'A' + range->id, offset - chip->base, mask); + + writel_relaxed(mask, at91_chip->regbase + PIO_PER); + + return 0; +} + +void at91_gpio_disable_free(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) +{ + struct at91_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); + + dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset); + /* Set the pin to some default state, GPIO is usually default */ +} + +static struct pinmux_ops at91_pmx_ops = { + .get_functions_count = at91_pmx_get_funcs_count, + .get_function_name = at91_pmx_get_func_name, + .get_function_groups = at91_pmx_get_groups, + .enable = at91_pmx_enable, + .disable = at91_pmx_disable, + .gpio_request_enable = at91_gpio_request_enable, + .gpio_disable_free = at91_gpio_disable_free, +}; + +static int at91_pinconf_get(struct pinctrl_dev *pctldev, + unsigned pin_id, unsigned long *config) +{ + struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + void __iomem *pio; + unsigned pin; + + dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, *config); + pio = pin_to_controller(info, pin_to_bank(pin_id)); + pin = pin_id % MAX_NB_GPIO_PER_BANK; + + if (at91_mux_get_multidrive(pio, pin)) + *config |= MULTI_DRIVE; + + if (at91_mux_get_pullup(pio, pin)) + *config |= PULL_UP; + + return 0; +} + +static int at91_pinconf_set(struct pinctrl_dev *pctldev, + unsigned pin_id, unsigned long config) +{ + struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); + unsigned mask; + void __iomem *pio; + + dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, config); + pio = pin_to_controller(info, pin_to_bank(pin_id)); + mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK); + + at91_mux_set_pullup(pio, mask, config & PULL_UP); + at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE); + return 0; +} + +static void at91_pinconf_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, unsigned pin_id) +{ + +} + +static void at91_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, unsigned group) +{ +} + +struct pinconf_ops at91_pinconf_ops = { + .pin_config_get = at91_pinconf_get, + .pin_config_set = at91_pinconf_set, + .pin_config_dbg_show = at91_pinconf_dbg_show, + .pin_config_group_dbg_show = at91_pinconf_group_dbg_show, +}; + +static struct pinctrl_desc at91_pinctrl_desc = { + .pctlops = &at91_pctrl_ops, + .pmxops = &at91_pmx_ops, + .confops = &at91_pinconf_ops, + .owner = THIS_MODULE, +}; + +static const char *gpio_compat = "atmel,at91rm9200-gpio"; + +static void __devinit at91_pinctrl_child_count(struct at91_pinctrl *info, + struct device_node *np) +{ + struct device_node *child; + + for_each_child_of_node(np, child) { + if (of_device_is_compatible(child, gpio_compat)) { + info->nbanks++; + } else { + info->nfunctions++; + info->ngroups += of_get_child_count(child); + } + } +} + +static int __devinit at91_pinctrl_mux_mask(struct at91_pinctrl *info, + struct device_node *np) +{ + int ret = 0; + int size; + const const __be32 *list; + + list = of_get_property(np, "atmel,mux-mask", &size); + if (!list) { + dev_err(info->dev, "can not read the mux-mask of %d\n", size); + return -EINVAL; + } + + size /= sizeof(*list); + if (!size || size % info->nbanks) { + dev_err(info->dev, "wrong mux mask array should be by %d\n", info->nbanks); + return -EINVAL; + } + info->nmux = size / info->nbanks; + + info->mux_mask = devm_kzalloc(info->dev, sizeof(u32) * size, GFP_KERNEL); + if (!info->mux_mask) { + dev_err(info->dev, "could not alloc mux_mask\n"); + return -ENOMEM; + } + + ret = of_property_read_u32_array(np, "atmel,mux-mask", + info->mux_mask, size); + if (ret) + dev_err(info->dev, "can not read the mux-mask of %d\n", size); + return ret; +} + +static int __devinit at91_pinctrl_parse_groups(struct device_node *np, + struct at91_pin_group *grp, + struct at91_pinctrl *info, + u32 index) +{ + struct at91_pmx_pin *pin; + int size; + const const __be32 *list; + int i, j; + + dev_dbg(info->dev, "group(%d): %s\n", index, np->name); + + /* Initialise group */ + grp->name = np->name; + + /* + * the binding format is atmel,pins = , + * do sanity check and calculate pins number + */ + list = of_get_property(np, "atmel,pins", &size); + /* we do not check return since it's safe node passed down */ + size /= sizeof(*list); + if (!size || size % 4) { + dev_err(info->dev, "wrong pins number or pins and configs should be by 4\n"); + return -EINVAL; + } + + grp->npins = size / 4; + pin = grp->pins_conf = devm_kzalloc(info->dev, grp->npins * sizeof(struct at91_pmx_pin), + GFP_KERNEL); + grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int), + GFP_KERNEL); + if (!grp->pins_conf || !grp->pins) + return -ENOMEM; + + for (i = 0, j = 0; i < size; i += 4, j++) { + pin->bank = be32_to_cpu(*list++); + pin->pin = be32_to_cpu(*list++); + grp->pins[j] = pin->bank * MAX_NB_GPIO_PER_BANK + pin->pin; + pin->mux = be32_to_cpu(*list++); + pin->conf = be32_to_cpu(*list++); + + at91_pin_dbg(info->dev, pin); + pin++; + } + + return 0; +} + +static int __devinit at91_pinctrl_parse_functions(struct device_node *np, + struct at91_pinctrl *info, u32 index) +{ + struct device_node *child; + struct at91_pmx_func *func; + struct at91_pin_group *grp; + int ret; + static u32 grp_index; + u32 i = 0; + + dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name); + + func = &info->functions[index]; + + /* Initialise function */ + func->name = np->name; + func->ngroups = of_get_child_count(np); + if (func->ngroups <= 0) { + dev_err(info->dev, "no groups defined\n"); + return -EINVAL; + } + func->groups = devm_kzalloc(info->dev, + func->ngroups * sizeof(char *), GFP_KERNEL); + if (!func->groups) + return -ENOMEM; + + for_each_child_of_node(np, child) { + func->groups[i] = child->name; + grp = &info->groups[grp_index++]; + ret = at91_pinctrl_parse_groups(child, grp, info, i++); + if (ret) + return ret; + } + + return 0; +} + +static struct of_device_id at91_pinctrl_of_match[] __devinitdata = { + { .compatible = "atmel,at91sam9x5-pinctrl", .data = &at91sam9x5_ops }, + { .compatible = "atmel,at91rm9200-pinctrl", .data = &at91rm9200_ops }, + { /* sentinel */ } +}; + +static int __devinit at91_pinctrl_probe_dt(struct platform_device *pdev, + struct at91_pinctrl *info) +{ + int ret = 0; + int i, j; + uint32_t *tmp; + struct device_node *np = pdev->dev.of_node; + struct device_node *child; + + if (!np) + return -ENODEV; + + info->dev = &pdev->dev; + info->ops = + of_match_device(at91_pinctrl_of_match, &pdev->dev)->data; + at91_pinctrl_child_count(info, np); + + if (info->nbanks < 1) { + dev_err(&pdev->dev, "you need to specify atleast one gpio-controller\n"); + return -EINVAL; + } + + ret = at91_pinctrl_mux_mask(info, np); + if (ret) + return ret; + + dev_dbg(&pdev->dev, "nmux = %d\n", info->nmux); + + dev_dbg(&pdev->dev, "mux-mask\n"); + tmp = info->mux_mask; + for (i = 0; i < info->nbanks; i++) { + for (j = 0; j < info->nmux; j++, tmp++) { + dev_dbg(&pdev->dev, "%d:%d\t0x%x\n", i, j, tmp[0]); + } + } + + dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); + dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); + info->functions = devm_kzalloc(&pdev->dev, info->nfunctions * sizeof(struct at91_pmx_func), + GFP_KERNEL); + if (!info->functions) + return -ENOMEM; + + info->groups = devm_kzalloc(&pdev->dev, info->ngroups * sizeof(struct at91_pin_group), + GFP_KERNEL); + if (!info->groups) + return -ENOMEM; + + dev_dbg(&pdev->dev, "nbanks = %d\n", info->nbanks); + dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); + dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); + + i = 0; + + for_each_child_of_node(np, child) { + if (of_device_is_compatible(child, gpio_compat)) + continue; + ret = at91_pinctrl_parse_functions(child, info, i++); + if (ret) { + dev_err(&pdev->dev, "failed to parse function\n"); + return ret; + } + } + + return 0; +} + +static int __devinit at91_pinctrl_probe(struct platform_device *pdev) +{ + struct at91_pinctrl *info; + struct pinctrl_pin_desc *pdesc; + int ret, i, j ,k; + + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + ret = at91_pinctrl_probe_dt(pdev, info); + if (ret) + return ret; + + /* + * We need all the GPIO drivers to probe FIRST, or we will not be able + * to obtain references to the struct gpio_chip * for them, and we + * need this to proceed. + */ + for (i = 0; i < info->nbanks; i++) { + if (!gpio_chips[i]) { + dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); + devm_kfree(&pdev->dev, info); + return -EPROBE_DEFER; + } + } + + at91_pinctrl_desc.name = dev_name(&pdev->dev); + at91_pinctrl_desc.npins = info->nbanks * MAX_NB_GPIO_PER_BANK; + at91_pinctrl_desc.pins = pdesc = + devm_kzalloc(&pdev->dev, sizeof(*pdesc) * at91_pinctrl_desc.npins, GFP_KERNEL); + + if (!at91_pinctrl_desc.pins) + return -ENOMEM; + + for (i = 0 , k = 0; i < info->nbanks; i++) { + for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) { + pdesc->number = k; + pdesc->name = kasprintf(GFP_KERNEL, "pio%c%d", i + 'A', j); + pdesc++; + } + } + + platform_set_drvdata(pdev, info); + info->pctl = pinctrl_register(&at91_pinctrl_desc, &pdev->dev, info); + + if (!info->pctl) { + dev_err(&pdev->dev, "could not register AT91 pinctrl driver\n"); + ret = -EINVAL; + goto err; + } + + /* We will handle a range of GPIO pins */ + for (i = 0; i < info->nbanks; i++) + pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range); + + dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n"); + + return 0; + +err: + return ret; +} + +int __devexit at91_pinctrl_remove(struct platform_device *pdev) +{ + struct at91_pinctrl *info = platform_get_drvdata(pdev); + + pinctrl_unregister(info->pctl); + + return 0; +} + +static int at91_gpio_request(struct gpio_chip *chip, unsigned offset) +{ + /* + * Map back to global GPIO space and request muxing, the direction + * parameter does not matter for this controller. + */ + int gpio = chip->base + offset; + int bank = chip->base / chip->ngpio; + + dev_dbg(chip->dev, "%s:%d pio%c%d(%d)\n", __func__, __LINE__, + 'A' + bank, offset, gpio); + + return pinctrl_request_gpio(gpio); +} + +static void at91_gpio_free(struct gpio_chip *chip, unsigned offset) +{ + int gpio = chip->base + offset; + + pinctrl_free_gpio(gpio); +} + +static int at91_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << offset; + + writel_relaxed(mask, pio + PIO_ODR); + return 0; +} + +static int at91_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << offset; + u32 pdsr; + + pdsr = readl_relaxed(pio + PIO_PDSR); + return (pdsr & mask) != 0; +} + +static void at91_gpio_set(struct gpio_chip *chip, unsigned offset, + int val) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << offset; + + writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR)); +} + +static int at91_gpio_direction_output(struct gpio_chip *chip, unsigned offset, + int val) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << offset; + + writel_relaxed(mask, pio + (val ? PIO_SODR : PIO_CODR)); + writel_relaxed(mask, pio + PIO_OER); + + return 0; +} + +static int at91_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + int virq; + + if (offset < chip->ngpio) + virq = irq_create_mapping(at91_gpio->domain, offset); + else + virq = -ENXIO; + + dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n", + chip->label, offset + chip->base, virq); + return virq; +} + +#ifdef CONFIG_DEBUG_FS +static void at91_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) +{ + enum at91_mux mode; + int i; + struct at91_gpio_chip *at91_gpio = to_at91_gpio_chip(chip); + void __iomem *pio = at91_gpio->regbase; + + for (i = 0; i < chip->ngpio; i++) { + unsigned pin = chip->base + i; + unsigned mask = pin_to_mask(pin); + const char *gpio_label; + u32 pdsr; + + gpio_label = gpiochip_is_requested(chip, i); + if (!gpio_label) + continue; + mode = at91_gpio->ops->get_periph(pio, mask); + seq_printf(s, "[%s] GPIO%s%d: ", + gpio_label, chip->label, i); + if (mode == AT91_MUX_GPIO) { + pdsr = readl_relaxed(pio + PIO_PDSR); + + seq_printf(s, "[gpio] %s\n", + pdsr & mask ? + "set" : "clear"); + } else { + seq_printf(s, "[periph %c]\n", + mode + 'A' - 1); + } + } +} +#else +#define at91_gpio_dbg_show NULL +#endif + +/* Several AIC controller irqs are dispatched through this GPIO handler. + * To use any AT91_PIN_* as an externally triggered IRQ, first call + * at91_set_gpio_input() then maybe enable its glitch filter. + * Then just request_irq() with the pin ID; it works like any ARM IRQ + * handler. + * First implementation always triggers on rising and falling edges + * whereas the newer PIO3 can be additionally configured to trigger on + * level, edge with any polarity. + * + * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after + * configuring them with at91_set_a_periph() or at91_set_b_periph(). + * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering. + */ + +static void gpio_irq_mask(struct irq_data *d) +{ + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << d->hwirq; + + if (pio) + writel_relaxed(mask, pio + PIO_IDR); +} + +static void gpio_irq_unmask(struct irq_data *d) +{ + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << d->hwirq; + + if (pio) + writel_relaxed(mask, pio + PIO_IER); +} + +static int gpio_irq_type(struct irq_data *d, unsigned type) +{ + switch (type) { + case IRQ_TYPE_NONE: + case IRQ_TYPE_EDGE_BOTH: + return 0; + default: + return -EINVAL; + } +} + +/* Alternate irq type for PIO3 support */ +static int alt_gpio_irq_type(struct irq_data *d, unsigned type) +{ + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + void __iomem *pio = at91_gpio->regbase; + unsigned mask = 1 << d->hwirq; + + switch (type) { + case IRQ_TYPE_EDGE_RISING: + writel_relaxed(mask, pio + PIO_ESR); + writel_relaxed(mask, pio + PIO_REHLSR); + break; + case IRQ_TYPE_EDGE_FALLING: + writel_relaxed(mask, pio + PIO_ESR); + writel_relaxed(mask, pio + PIO_FELLSR); + break; + case IRQ_TYPE_LEVEL_LOW: + writel_relaxed(mask, pio + PIO_LSR); + writel_relaxed(mask, pio + PIO_FELLSR); + break; + case IRQ_TYPE_LEVEL_HIGH: + writel_relaxed(mask, pio + PIO_LSR); + writel_relaxed(mask, pio + PIO_REHLSR); + break; + case IRQ_TYPE_EDGE_BOTH: + /* + * disable additional interrupt modes: + * fall back to default behavior + */ + writel_relaxed(mask, pio + PIO_AIMDR); + return 0; + case IRQ_TYPE_NONE: + default: + pr_warn("AT91: No type for irq %d\n", gpio_to_irq(d->irq)); + return -EINVAL; + } + + /* enable additional interrupt modes */ + writel_relaxed(mask, pio + PIO_AIMER); + + return 0; +} + +#ifdef CONFIG_PM +static int gpio_irq_set_wake(struct irq_data *d, unsigned state) +{ + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); + unsigned bank = at91_gpio->pioc_idx; + + if (unlikely(bank >= MAX_GPIO_BANKS)) + return -EINVAL; + + irq_set_irq_wake(at91_gpio->pioc_virq, state); + + return 0; +} +#else +#define gpio_irq_set_wake NULL +#endif + +static struct irq_chip gpio_irqchip = { + .name = "GPIO", + .irq_disable = gpio_irq_mask, + .irq_mask = gpio_irq_mask, + .irq_unmask = gpio_irq_unmask, + /* .irq_set_type is set dynamically */ + .irq_set_wake = gpio_irq_set_wake, +}; + +static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) +{ + struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_data *idata = irq_desc_get_irq_data(desc); + struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata); + void __iomem *pio = at91_gpio->regbase; + unsigned long isr; + int n; + + chained_irq_enter(chip, desc); + for (;;) { + /* Reading ISR acks pending (edge triggered) GPIO interrupts. + * When there none are pending, we're finished unless we need + * to process multiple banks (like ID_PIOCDE on sam9263). + */ + isr = readl_relaxed(pio + PIO_ISR) & readl_relaxed(pio + PIO_IMR); + if (!isr) { + if (!at91_gpio->next) + break; + at91_gpio = at91_gpio->next; + pio = at91_gpio->regbase; + continue; + } + + n = find_first_bit(&isr, BITS_PER_LONG); + while (n < BITS_PER_LONG) { + generic_handle_irq(irq_find_mapping(at91_gpio->domain, n)); + n = find_next_bit(&isr, BITS_PER_LONG, n + 1); + } + } + chained_irq_exit(chip, desc); + /* now it may re-trigger */ +} + +/* + * This lock class tells lockdep that GPIO irqs are in a different + * category than their parents, so it won't report false recursion. + */ +static struct lock_class_key gpio_lock_class; + +static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct at91_gpio_chip *at91_gpio = h->host_data; + + irq_set_lockdep_class(virq, &gpio_lock_class); + + /* + * Can use the "simple" and not "edge" handler since it's + * shorter, and the AIC handles interrupts sanely. + */ + irq_set_chip_and_handler(virq, &gpio_irqchip, + handle_simple_irq); + set_irq_flags(virq, IRQF_VALID); + irq_set_chip_data(virq, at91_gpio); + + return 0; +} + +static struct irq_domain_ops at91_gpio_ops = { + .map = at91_gpio_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +static int at91_gpio_of_irq_setup(struct device_node *node, + struct at91_gpio_chip *at91_gpio) +{ + struct at91_gpio_chip *prev = NULL; + struct irq_data *d = irq_get_irq_data(at91_gpio->pioc_virq); + + at91_gpio->pioc_hwirq = irqd_to_hwirq(d); + + /* Setup proper .irq_set_type function */ + gpio_irqchip.irq_set_type = at91_gpio->ops->irq_type; + + /* Disable irqs of this PIO controller */ + writel_relaxed(~0, at91_gpio->regbase + PIO_IDR); + + /* Setup irq domain */ + at91_gpio->domain = irq_domain_add_linear(node, at91_gpio->chip.ngpio, + &at91_gpio_ops, at91_gpio); + if (!at91_gpio->domain) + panic("at91_gpio.%d: couldn't allocate irq domain (DT).\n", + at91_gpio->pioc_idx); + + /* Setup chained handler */ + if (at91_gpio->pioc_idx) + prev = gpio_chips[at91_gpio->pioc_idx - 1]; + + /* The toplevel handler handles one bank of GPIOs, except + * on some SoC it can handles up to three... + * We only set up the handler for the first of the list. + */ + if (prev && prev->next == at91_gpio) + return 0; + + irq_set_chip_data(at91_gpio->pioc_virq, at91_gpio); + irq_set_chained_handler(at91_gpio->pioc_virq, gpio_irq_handler); + + return 0; +} + +/* This structure is replicated for each GPIO block allocated at probe time */ +static struct gpio_chip at91_gpio_template = { + .request = at91_gpio_request, + .free = at91_gpio_free, + .direction_input = at91_gpio_direction_input, + .get = at91_gpio_get, + .direction_output = at91_gpio_direction_output, + .set = at91_gpio_set, + .to_irq = at91_gpio_to_irq, + .dbg_show = at91_gpio_dbg_show, + .can_sleep = 0, + .ngpio = MAX_NB_GPIO_PER_BANK, +}; + +static void __devinit at91_gpio_probe_fixup(void) +{ + unsigned i; + struct at91_gpio_chip *at91_gpio, *last = NULL; + + for (i = 0; i < gpio_banks; i++) { + at91_gpio = gpio_chips[i]; + + /* + * GPIO controller are grouped on some SoC: + * PIOC, PIOD and PIOE can share the same IRQ line + */ + if (last && last->pioc_virq == at91_gpio->pioc_virq) + last->next = at91_gpio; + last = at91_gpio; + } +} + +static struct of_device_id at91_gpio_of_match[] __devinitdata = { + { .compatible = "atmel,at91sam9x5-gpio", .data = &at91sam9x5_ops, }, + { .compatible = "atmel,at91rm9200-gpio", .data = &at91rm9200_ops }, + { /* sentinel */ } +}; + +static int __devinit at91_gpio_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct resource *res; + struct at91_gpio_chip *at91_chip = NULL; + struct gpio_chip *chip; + struct pinctrl_gpio_range *range; + int ret = 0; + int irq; + int alias_idx = of_alias_get_id(np, "gpio"); + uint32_t ngpio; + + BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips)); + if (gpio_chips[alias_idx]) { + ret = -EBUSY; + goto err; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENOENT; + goto err; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + ret = irq; + goto err; + } + + at91_chip = devm_kzalloc(&pdev->dev, sizeof(*at91_chip), GFP_KERNEL); + if (!at91_chip) { + ret = -ENOMEM; + goto err; + } + + at91_chip->regbase = devm_request_and_ioremap(&pdev->dev, res); + if (!at91_chip->regbase) { + dev_err(&pdev->dev, "failed to map registers, ignoring.\n"); + ret = -EBUSY; + goto err; + } + + at91_chip->ops = + of_match_device(at91_gpio_of_match, &pdev->dev)->data; + at91_chip->pioc_virq = irq; + at91_chip->pioc_idx = alias_idx; + + at91_chip->clock = clk_get(&pdev->dev, NULL); + if (IS_ERR(at91_chip->clock)) { + dev_err(&pdev->dev, "failed to get clock, ignoring.\n"); + goto err; + } + + if (clk_prepare(at91_chip->clock)) + goto clk_prep_err; + + /* enable PIO controller's clock */ + if (clk_enable(at91_chip->clock)) { + dev_err(&pdev->dev, "failed to enable clock, ignoring.\n"); + goto clk_err; + } + + at91_chip->chip = at91_gpio_template; + + chip = &at91_chip->chip; + chip->of_node = np; + chip->label = dev_name(&pdev->dev); + chip->dev = &pdev->dev; + chip->owner = THIS_MODULE; + chip->base = alias_idx * MAX_NB_GPIO_PER_BANK; + + if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) { + if (ngpio >= MAX_NB_GPIO_PER_BANK) + pr_err("at91_gpio.%d, gpio-nb >= %d failback to %d\n", + alias_idx, MAX_NB_GPIO_PER_BANK, MAX_NB_GPIO_PER_BANK); + else + chip->ngpio = ngpio; + } + + range = &at91_chip->range; + range->name = chip->label; + range->id = alias_idx; + range->pin_base = range->base = range->id * MAX_NB_GPIO_PER_BANK; + + range->npins = chip->ngpio; + range->gc = chip; + + ret = gpiochip_add(chip); + if (ret) + goto clk_err; + + gpio_chips[alias_idx] = at91_chip; + gpio_banks = max(gpio_banks, alias_idx + 1); + + at91_gpio_probe_fixup(); + + at91_gpio_of_irq_setup(np, at91_chip); + + dev_info(&pdev->dev, "at address %p\n", at91_chip->regbase); + + return 0; + +clk_err: + clk_unprepare(at91_chip->clock); +clk_prep_err: + clk_put(at91_chip->clock); +err: + dev_err(&pdev->dev, "Failure %i for GPIO %i\n", ret, alias_idx); + + return ret; +} + +static struct platform_driver at91_gpio_driver = { + .driver = { + .name = "gpio-at91", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(at91_gpio_of_match), + }, + .probe = at91_gpio_probe, +}; + +static struct platform_driver at91_pinctrl_driver = { + .driver = { + .name = "pinctrl-at91", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(at91_pinctrl_of_match), + }, + .probe = at91_pinctrl_probe, + .remove = __devexit_p(at91_pinctrl_remove), +}; + +static int __init at91_pinctrl_init(void) +{ + int ret; + + ret = platform_driver_register(&at91_gpio_driver); + if (ret) + return ret; + return platform_driver_register(&at91_pinctrl_driver); +} +arch_initcall(at91_pinctrl_init); + +static void __exit at91_pinctrl_exit(void) +{ + platform_driver_unregister(&at91_pinctrl_driver); +} + +module_exit(at91_pinctrl_exit); +MODULE_AUTHOR("Jean-Christophe PLAGNIOL-VILLARD "); +MODULE_DESCRIPTION("Atmel AT91 pinctrl driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 5314ec8e52263b56edd6a37d089b3b675d50e3f1 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 5 Jul 2012 16:56:09 +0800 Subject: arm: at91: dt: at91sam9 add pinctrl support Acked-by: Nicolas Ferre Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9260.dtsi | 9 +++++++++ arch/arm/boot/dts/at91sam9263.dtsi | 12 ++++++++++++ arch/arm/boot/dts/at91sam9g45.dtsi | 11 +++++++++++ arch/arm/boot/dts/at91sam9n12.dtsi | 12 +++++++++++- arch/arm/boot/dts/at91sam9x5.dtsi | 12 +++++++++++- arch/arm/configs/at91_dt_defconfig | 1 + arch/arm/mach-at91/at91sam9260.c | 3 +++ arch/arm/mach-at91/at91sam9263.c | 5 +++++ arch/arm/mach-at91/at91sam9g45.c | 6 ++++++ arch/arm/mach-at91/at91sam9n12.c | 11 ++++------- arch/arm/mach-at91/at91sam9x5.c | 15 ++++----------- arch/arm/mach-at91/setup.c | 3 ++- 12 files changed, 79 insertions(+), 21 deletions(-) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 425da936051..0b72ae3d825 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -104,6 +104,15 @@ compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; ranges = <0xfffff400 0xfffff400 0x600>; + atmel,mux-mask = < + /* A B */ + 0xffffffff 0xffc00c3b /* pioA */ + 0xffffffff 0x7fff3ccf /* pioB */ + 0xffffffff 0x007fffff /* pioC */ + >; + + /* shared pinctrl settings */ + pioA: gpio@fffff400 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 5b619c9255b..c8028fc9ec8 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -95,6 +95,17 @@ compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; ranges = <0xfffff200 0xfffff200 0xa00>; + atmel,mux-mask = < + /* A B */ + 0xfffffffb 0xffffe07f /* pioA */ + 0x0007ffff 0x39072fff /* pioB */ + 0xffffffff 0x3ffffff8 /* pioC */ + 0xfffffbff 0xffffffff /* pioD */ + 0xffe00fff 0xfbfcff00 /* pioE */ + >; + + /* shared pinctrl settings */ + pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff200 0x200>; @@ -143,6 +154,7 @@ gpio-controller; interrupt-controller; #interrupt-cells = <2>; + }; }; dbgu: serial@ffffee00 { diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index f2b0f93c049..5222625b6ce 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -114,6 +114,17 @@ compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; ranges = <0xfffff200 0xfffff200 0xa00>; + atmel,mux-mask = < + /* A B */ + 0xffffffff 0xffc003ff /* pioA */ + 0xffffffff 0x800f8f00 /* pioB */ + 0xffffffff 0x00000e00 /* pioC */ + 0xffffffff 0xff0c1381 /* pioD */ + 0xffffffff 0x81ffff81 /* pioE */ + >; + + /* shared pinctrl settings */ + pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff200 0x200>; diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index b061c062602..8b5276499aa 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -105,9 +105,19 @@ pinctrl@fffff400 { #address-cells = <1>; #size-cells = <1>; - compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; + compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus"; ranges = <0xfffff400 0xfffff400 0x800>; + atmel,mux-mask = < + /* A B C */ + 0xffffffff 0xffe07983 0x00000000 /* pioA */ + 0x00040000 0x00047e0f 0x00000000 /* pioB */ + 0xfdffffff 0x07c00000 0xb83fffff /* pioC */ + 0x003fffff 0x003f8000 0x00000000 /* pioD */ + >; + + /* shared pinctrl settings */ + pioA: gpio@fffff400 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 065698ac4de..34d4d5c8c58 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -114,9 +114,19 @@ pinctrl@fffff200 { #address-cells = <1>; #size-cells = <1>; - compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; + compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus"; ranges = <0xfffff400 0xfffff400 0x800>; + atmel,mux-mask = < + /* A B C */ + 0xffffffff 0xffe0399f 0xc000001c /* pioA */ + 0xffffffff 0xffc003ff 0xffc003ff /* pioB */ + 0xffffffff 0xffc003ff 0xffc003ff /* pioC */ + 0xffffffff 0xffc003ff 0xffc003ff /* pioD */ + >; + + /* shared pinctrl settings */ + pioA: gpio@fffff400 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>; diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig index 67bc571ed0c..b175577d7ab 100644 --- a/arch/arm/configs/at91_dt_defconfig +++ b/arch/arm/configs/at91_dt_defconfig @@ -111,6 +111,7 @@ CONFIG_I2C=y CONFIG_I2C_GPIO=y CONFIG_SPI=y CONFIG_SPI_ATMEL=y +CONFIG_PINCTRL_AT91=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_AT91SAM9X_WATCHDOG=y diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 1dc40620ccf..46d30831c9a 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -235,6 +235,9 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_ID("pioA", &pioA_clk), CLKDEV_CON_ID("pioB", &pioB_clk), CLKDEV_CON_ID("pioC", &pioC_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk), }; static struct clk_lookup usart_clocks_lookups[] = { diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 03cac586e36..f8ea0013623 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -212,6 +212,11 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk), CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk), CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioCDE_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCDE_clk), + CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCDE_clk), }; static struct clk_lookup usart_clocks_lookups[] = { diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index 32504b9eed9..e6dd371d9f5 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -260,6 +260,12 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioC_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioDE_clk), + CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioDE_clk), + CLKDEV_CON_ID("pioA", &pioA_clk), CLKDEV_CON_ID("pioB", &pioB_clk), CLKDEV_CON_ID("pioC", &pioC_clk), diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c index 3905465f3ab..bf8a083a02a 100644 --- a/arch/arm/mach-at91/at91sam9n12.c +++ b/arch/arm/mach-at91/at91sam9n12.c @@ -171,10 +171,10 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma_clk), CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), - CLKDEV_CON_ID("pioA", &pioAB_clk), - CLKDEV_CON_ID("pioB", &pioAB_clk), - CLKDEV_CON_ID("pioC", &pioCD_clk), - CLKDEV_CON_ID("pioD", &pioCD_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk), + CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCD_clk), /* additional fake clock for macb_hclk */ CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &uhp_clk), CLKDEV_CON_DEV_ID("ohci_clk", "500000.ohci", &uhp_clk), @@ -223,9 +223,6 @@ static void __init at91sam9n12_map_io(void) void __init at91sam9n12_initialize(void) { at91_extern_irq = (1 << AT91SAM9N12_ID_IRQ0); - - /* Register GPIO subsystem (using DT) */ - at91_gpio_init(NULL, 0); } AT91_SOC_START(sam9n12) diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index f31d3a065d5..56d13a4950a 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c @@ -234,10 +234,10 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk), - CLKDEV_CON_ID("pioA", &pioAB_clk), - CLKDEV_CON_ID("pioB", &pioAB_clk), - CLKDEV_CON_ID("pioC", &pioCD_clk), - CLKDEV_CON_ID("pioD", &pioCD_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk), + CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCD_clk), /* additional fake clock for macb_hclk */ CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk), CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk), @@ -313,12 +313,6 @@ static void __init at91sam9x5_map_io(void) at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE); } -void __init at91sam9x5_initialize(void) -{ - /* Register GPIO subsystem (using DT) */ - at91_gpio_init(NULL, 0); -} - /* -------------------------------------------------------------------- * Interrupt initialization * -------------------------------------------------------------------- */ @@ -326,5 +320,4 @@ void __init at91sam9x5_initialize(void) AT91_SOC_START(sam9x5) .map_io = at91sam9x5_map_io, .register_clocks = at91sam9x5_register_clocks, - .init = at91sam9x5_initialize, AT91_SOC_END diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index e228d7377b6..523daa92be1 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -449,7 +449,8 @@ void __init at91_dt_initialize(void) /* Register the processor-specific clocks */ at91_boot_soc.register_clocks(); - at91_boot_soc.init(); + if (at91_boot_soc.init) + at91_boot_soc.init(); } #endif -- cgit v1.2.3 From ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 5 Jul 2012 16:56:09 +0800 Subject: arm: at91: dt: at91sam9 add serial pinctrl support Set the dbgu pinctrl config by default as we have only one possible config For other uart set the rxd/txd by default. For at91sam9x5ek create soc based dts as we need to include specific soc dtsi. Acked-by: Nicolas Ferre Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/Makefile | 44 +++++++++------ arch/arm/boot/dts/at91sam9260.dtsi | 109 ++++++++++++++++++++++++++++++++++++ arch/arm/boot/dts/at91sam9263.dtsi | 57 +++++++++++++++++++ arch/arm/boot/dts/at91sam9g15.dtsi | 28 +++++++++ arch/arm/boot/dts/at91sam9g15ek.dts | 16 ++++++ arch/arm/boot/dts/at91sam9g25.dtsi | 28 +++++++++ arch/arm/boot/dts/at91sam9g25ek.dts | 49 +--------------- arch/arm/boot/dts/at91sam9g35.dtsi | 28 +++++++++ arch/arm/boot/dts/at91sam9g35ek.dts | 16 ++++++ arch/arm/boot/dts/at91sam9g45.dtsi | 73 ++++++++++++++++++++++++ arch/arm/boot/dts/at91sam9n12.dtsi | 83 +++++++++++++++++++++++++++ arch/arm/boot/dts/at91sam9x25.dtsi | 28 +++++++++ arch/arm/boot/dts/at91sam9x25ek.dts | 16 ++++++ arch/arm/boot/dts/at91sam9x35.dtsi | 28 +++++++++ arch/arm/boot/dts/at91sam9x35ek.dts | 16 ++++++ arch/arm/boot/dts/at91sam9x5.dtsi | 97 +++++++++++++++++++++++++++++--- arch/arm/boot/dts/at91sam9x5ek.dtsi | 59 +++++++++++++++++++ 17 files changed, 703 insertions(+), 72 deletions(-) create mode 100644 arch/arm/boot/dts/at91sam9g15.dtsi create mode 100644 arch/arm/boot/dts/at91sam9g15ek.dts create mode 100644 arch/arm/boot/dts/at91sam9g25.dtsi create mode 100644 arch/arm/boot/dts/at91sam9g35.dtsi create mode 100644 arch/arm/boot/dts/at91sam9g35ek.dts create mode 100644 arch/arm/boot/dts/at91sam9x25.dtsi create mode 100644 arch/arm/boot/dts/at91sam9x25ek.dts create mode 100644 arch/arm/boot/dts/at91sam9x35.dtsi create mode 100644 arch/arm/boot/dts/at91sam9x35ek.dts create mode 100644 arch/arm/boot/dts/at91sam9x5ek.dtsi diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index c1ce813fcc4..a9b051a8f70 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1,21 +1,33 @@ ifeq ($(CONFIG_OF),y) -dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb \ - at91sam9263ek.dtb \ - at91sam9g20ek_2mmc.dtb \ - at91sam9g20ek.dtb \ - at91sam9g25ek.dtb \ - at91sam9m10g45ek.dtb \ - at91sam9n12ek.dtb \ - ethernut5.dtb \ - evk-pro3.dtb \ - kizbox.dtb \ - tny_a9260.dtb \ - tny_a9263.dtb \ - tny_a9g20.dtb \ - usb_a9260.dtb \ - usb_a9263.dtb \ - usb_a9g20.dtb +# Keep at91 dtb files sorted alphabetically for each SoC +# sam9260 +dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb +dtb-$(CONFIG_ARCH_AT91) += ethernut5.dtb +dtb-$(CONFIG_ARCH_AT91) += evk-pro3.dtb +dtb-$(CONFIG_ARCH_AT91) += tny_a9260.dtb +dtb-$(CONFIG_ARCH_AT91) += usb_a9260.dtb +# sam9263 +dtb-$(CONFIG_ARCH_AT91) += at91sam9263ek.dtb +dtb-$(CONFIG_ARCH_AT91) += tny_a9263.dtb +dtb-$(CONFIG_ARCH_AT91) += usb_a9263.dtb +# sam9g20 +dtb-$(CONFIG_ARCH_AT91) += at91sam9g20ek.dtb +dtb-$(CONFIG_ARCH_AT91) += at91sam9g20ek_2mmc.dtb +dtb-$(CONFIG_ARCH_AT91) += kizbox.dtb +dtb-$(CONFIG_ARCH_AT91) += tny_a9g20.dtb +dtb-$(CONFIG_ARCH_AT91) += usb_a9g20.dtb +# sam9g45 +dtb-$(CONFIG_ARCH_AT91) += at91sam9m10g45ek.dtb +# sam9n12 +dtb-$(CONFIG_ARCH_AT91) += at91sam9n12ek.dtb +# sam9x5 +dtb-$(CONFIG_ARCH_AT91) += at91sam9g15ek.dtb +dtb-$(CONFIG_ARCH_AT91) += at91sam9g25ek.dtb +dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb +dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek.dtb +dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \ dove-cubox.dtb \ diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 0b72ae3d825..838328a1829 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -112,6 +112,101 @@ >; /* shared pinctrl settings */ + dbgu { + pinctrl_dbgu: dbgu-0 { + atmel,pins = + <1 14 0x1 0x0 /* PB14 periph A */ + 1 15 0x1 0x1>; /* PB15 periph with pullup */ + }; + }; + + uart0 { + pinctrl_uart0: uart0-0 { + atmel,pins = + <1 4 0x1 0x0 /* PB4 periph A */ + 1 5 0x1 0x0>; /* PB5 periph A */ + }; + + pinctrl_uart0_rts_cts: uart0_rts_cts-0 { + atmel,pins = + <1 26 0x1 0x0 /* PB26 periph A */ + 1 27 0x1 0x0>; /* PB27 periph A */ + }; + + pinctrl_uart0_dtr_dsr: uart0_dtr_dsr-0 { + atmel,pins = + <1 24 0x1 0x0 /* PB24 periph A */ + 1 22 0x1 0x0>; /* PB22 periph A */ + }; + + pinctrl_uart0_dcd: uart0_dcd-0 { + atmel,pins = + <1 23 0x1 0x0>; /* PB23 periph A */ + }; + + pinctrl_uart0_ri: uart0_ri-0 { + atmel,pins = + <1 25 0x1 0x0>; /* PB25 periph A */ + }; + }; + + uart1 { + pinctrl_uart1: uart1-0 { + atmel,pins = + <2 6 0x1 0x1 /* PB6 periph A with pullup */ + 2 7 0x1 0x0>; /* PB7 periph A */ + }; + + pinctrl_uart1_rts_cts: uart1_rts_cts-0 { + atmel,pins = + <1 28 0x1 0x0 /* PB28 periph A */ + 1 29 0x1 0x0>; /* PB29 periph A */ + }; + }; + + uart2 { + pinctrl_uart2: uart2-0 { + atmel,pins = + <1 8 0x1 0x1 /* PB8 periph A with pullup */ + 1 9 0x1 0x0>; /* PB9 periph A */ + }; + + pinctrl_uart2_rts_cts: uart2_rts_cts-0 { + atmel,pins = + <0 4 0x1 0x0 /* PA4 periph A */ + 0 5 0x1 0x0>; /* PA5 periph A */ + }; + }; + + uart3 { + pinctrl_uart3: uart3-0 { + atmel,pins = + <2 10 0x1 0x1 /* PB10 periph A with pullup */ + 2 11 0x1 0x0>; /* PB11 periph A */ + }; + + pinctrl_uart3_rts_cts: uart3_rts_cts-0 { + atmel,pins = + <3 8 0x2 0x0 /* PB8 periph B */ + 3 10 0x2 0x0>; /* PB10 periph B */ + }; + }; + + uart4 { + pinctrl_uart4: uart4-0 { + atmel,pins = + <0 31 0x2 0x1 /* PA31 periph B with pullup */ + 0 30 0x2 0x0>; /* PA30 periph B */ + }; + }; + + uart5 { + pinctrl_uart5: uart5-0 { + atmel,pins = + <2 12 0x1 0x1 /* PB12 periph A with pullup */ + 2 13 0x1 0x0>; /* PB13 periph A */ + }; + }; pioA: gpio@fffff400 { compatible = "atmel,at91rm9200-gpio"; @@ -148,6 +243,8 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xfffff200 0x200>; interrupts = <1 4 7>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_dbgu>; status = "disabled"; }; @@ -157,6 +254,8 @@ interrupts = <6 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0>; status = "disabled"; }; @@ -166,6 +265,8 @@ interrupts = <7 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; status = "disabled"; }; @@ -175,6 +276,8 @@ interrupts = <8 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; status = "disabled"; }; @@ -184,6 +287,8 @@ interrupts = <23 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; status = "disabled"; }; @@ -193,6 +298,8 @@ interrupts = <24 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; status = "disabled"; }; @@ -202,6 +309,8 @@ interrupts = <25 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart5>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index c8028fc9ec8..579f82d23d3 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -105,6 +105,55 @@ >; /* shared pinctrl settings */ + dbgu { + pinctrl_dbgu: dbgu-0 { + atmel,pins = + <2 30 0x1 0x0 /* PC30 periph A */ + 2 31 0x1 0x1>; /* PC31 periph with pullup */ + }; + }; + + uart0 { + pinctrl_uart0: uart0-0 { + atmel,pins = + <0 26 0x1 0x1 /* PA26 periph A with pullup */ + 0 27 0x1 0x0>; /* PA27 periph A */ + }; + + pinctrl_uart0_rts_cts: uart0_rts_cts-0 { + atmel,pins = + <0 28 0x1 0x0 /* PA28 periph A */ + 0 29 0x1 0x0>; /* PA29 periph A */ + }; + }; + + uart1 { + pinctrl_uart1: uart1-0 { + atmel,pins = + <3 0 0x1 0x1 /* PD0 periph A with pullup */ + 3 1 0x1 0x0>; /* PD1 periph A */ + }; + + pinctrl_uart1_rts_cts: uart1_rts_cts-0 { + atmel,pins = + <3 7 0x2 0x0 /* PD7 periph B */ + 3 8 0x2 0x0>; /* PD8 periph B */ + }; + }; + + uart2 { + pinctrl_uart2: uart2-0 { + atmel,pins = + <3 2 0x1 0x1 /* PD2 periph A with pullup */ + 3 3 0x1 0x0>; /* PD3 periph A */ + }; + + pinctrl_uart2_rts_cts: uart2_rts_cts-0 { + atmel,pins = + <3 5 0x2 0x0 /* PD5 periph B */ + 4 6 0x2 0x0>; /* PD6 periph B */ + }; + }; pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; @@ -161,6 +210,8 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xffffee00 0x200>; interrupts = <1 4 7>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_dbgu>; status = "disabled"; }; @@ -170,6 +221,8 @@ interrupts = <7 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0>; status = "disabled"; }; @@ -179,6 +232,8 @@ interrupts = <8 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; status = "disabled"; }; @@ -188,6 +243,8 @@ interrupts = <9 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9g15.dtsi b/arch/arm/boot/dts/at91sam9g15.dtsi new file mode 100644 index 00000000000..fbe7a7089c2 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9g15.dtsi @@ -0,0 +1,28 @@ +/* + * at91sam9g15.dtsi - Device Tree Include file for AT91SAM9G15 SoC + * + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD + * + * Licensed under GPLv2. + */ + +/include/ "at91sam9x5.dtsi" + +/ { + model = "Atmel AT91SAM9G15 SoC"; + compatible = "atmel, at91sam9g15, atmel,at91sam9x5"; + + ahb { + apb { + pinctrl@fffff400 { + atmel,mux-mask = < + /* A B C */ + 0xffffffff 0xffe0399f 0x00000000 /* pioA */ + 0x00040000 0x00047e3f 0x00000000 /* pioB */ + 0xfdffffff 0x00000000 0xb83fffff /* pioC */ + 0x003fffff 0x003f8000 0x00000000 /* pioD */ + >; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9g15ek.dts b/arch/arm/boot/dts/at91sam9g15ek.dts new file mode 100644 index 00000000000..86dd3f6d938 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9g15ek.dts @@ -0,0 +1,16 @@ +/* + * at91sam9g15ek.dts - Device Tree file for AT91SAM9G15-EK board + * + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +/include/ "at91sam9g15.dtsi" +/include/ "at91sam9x5ek.dtsi" + +/ { + model = "Atmel AT91SAM9G25-EK"; + compatible = "atmel,at91sam9g15ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; +}; diff --git a/arch/arm/boot/dts/at91sam9g25.dtsi b/arch/arm/boot/dts/at91sam9g25.dtsi new file mode 100644 index 00000000000..05a718fb83c --- /dev/null +++ b/arch/arm/boot/dts/at91sam9g25.dtsi @@ -0,0 +1,28 @@ +/* + * at91sam9g25.dtsi - Device Tree Include file for AT91SAM9G25 SoC + * + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD + * + * Licensed under GPLv2. + */ + +/include/ "at91sam9x5.dtsi" + +/ { + model = "Atmel AT91SAM9G25 SoC"; + compatible = "atmel, at91sam9g25, atmel,at91sam9x5"; + + ahb { + apb { + pinctrl@fffff400 { + atmel,mux-mask = < + /* A B C */ + 0xffffffff 0xffe0399f 0xc000001c /* pioA */ + 0x0007ffff 0x8000fe3f 0x00000000 /* pioB */ + 0x80000000 0x07c0ffff 0xb83fffff /* pioC */ + 0x003fffff 0x003f8000 0x00000000 /* pioD */ + >; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts index 877c08f0676..c5ab16fba05 100644 --- a/arch/arm/boot/dts/at91sam9g25ek.dts +++ b/arch/arm/boot/dts/at91sam9g25ek.dts @@ -7,55 +7,10 @@ * Licensed under GPLv2 or later. */ /dts-v1/; -/include/ "at91sam9x5.dtsi" -/include/ "at91sam9x5cm.dtsi" +/include/ "at91sam9g25.dtsi" +/include/ "at91sam9x5ek.dtsi" / { model = "Atmel AT91SAM9G25-EK"; compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; - - chosen { - bootargs = "console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs"; - }; - - ahb { - apb { - dbgu: serial@fffff200 { - status = "okay"; - }; - - usart0: serial@f801c000 { - status = "okay"; - }; - - macb0: ethernet@f802c000 { - phy-mode = "rmii"; - status = "okay"; - }; - - i2c0: i2c@f8010000 { - status = "okay"; - }; - - i2c1: i2c@f8014000 { - status = "okay"; - }; - - i2c2: i2c@f8018000 { - status = "okay"; - }; - }; - - usb0: ohci@00600000 { - status = "okay"; - num-ports = <2>; - atmel,vbus-gpio = <&pioD 19 1 - &pioD 20 1 - >; - }; - - usb1: ehci@00700000 { - status = "okay"; - }; - }; }; diff --git a/arch/arm/boot/dts/at91sam9g35.dtsi b/arch/arm/boot/dts/at91sam9g35.dtsi new file mode 100644 index 00000000000..f9d14a72279 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9g35.dtsi @@ -0,0 +1,28 @@ +/* + * at91sam9g35.dtsi - Device Tree Include file for AT91SAM9G35 SoC + * + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD + * + * Licensed under GPLv2. + */ + +/include/ "at91sam9x5.dtsi" + +/ { + model = "Atmel AT91SAM9G35 SoC"; + compatible = "atmel, at91sam9g35, atmel,at91sam9x5"; + + ahb { + apb { + pinctrl@fffff400 { + atmel,mux-mask = < + /* A B C */ + 0xffffffff 0xffe0399f 0xc000000c /* pioA */ + 0x000406ff 0x00047e3f 0x00000000 /* pioB */ + 0xfdffffff 0x00000000 0xb83fffff /* pioC */ + 0x003fffff 0x003f8000 0x00000000 /* pioD */ + >; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9g35ek.dts b/arch/arm/boot/dts/at91sam9g35ek.dts new file mode 100644 index 00000000000..95944bdd798 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9g35ek.dts @@ -0,0 +1,16 @@ +/* + * at91sam9g35ek.dts - Device Tree file for AT91SAM9G35-EK board + * + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +/include/ "at91sam9g35.dtsi" +/include/ "at91sam9x5ek.dtsi" + +/ { + model = "Atmel AT91SAM9G35-EK"; + compatible = "atmel,at91sam9g35ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; +}; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 5222625b6ce..48a2ed72fea 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -124,6 +124,69 @@ >; /* shared pinctrl settings */ + dbgu { + pinctrl_dbgu: dbgu-0 { + atmel,pins = + <1 12 0x1 0x0 /* PB12 periph A */ + 1 13 0x1 0x0>; /* PB13 periph A */ + }; + }; + + uart0 { + pinctrl_uart0: uart0-0 { + atmel,pins = + <1 19 0x1 0x1 /* PB19 periph A with pullup */ + 1 18 0x1 0x0>; /* PB18 periph A */ + }; + + pinctrl_uart0_rts_cts: uart0_rts_cts-0 { + atmel,pins = + <1 17 0x2 0x0 /* PB17 periph B */ + 1 15 0x2 0x0>; /* PB15 periph B */ + }; + }; + + uart1 { + pinctrl_uart1: uart1-0 { + atmel,pins = + <1 4 0x1 0x1 /* PB4 periph A with pullup */ + 1 5 0x1 0x0>; /* PB5 periph A */ + }; + + pinctrl_uart1_rts_cts: uart1_rts_cts-0 { + atmel,pins = + <3 16 0x1 0x0 /* PD16 periph A */ + 3 17 0x1 0x0>; /* PD17 periph A */ + }; + }; + + uart2 { + pinctrl_uart2: uart2-0 { + atmel,pins = + <1 6 0x1 0x1 /* PB6 periph A with pullup */ + 1 7 0x1 0x0>; /* PB7 periph A */ + }; + + pinctrl_uart2_rts_cts: uart2_rts_cts-0 { + atmel,pins = + <2 9 0x2 0x0 /* PC9 periph B */ + 2 11 0x2 0x0>; /* PC11 periph B */ + }; + }; + + uart3 { + pinctrl_uart3: uart3-0 { + atmel,pins = + <1 8 0x1 0x1 /* PB9 periph A with pullup */ + 1 9 0x1 0x0>; /* PB8 periph A */ + }; + + pinctrl_uart3_rts_cts: uart3_rts_cts-0 { + atmel,pins = + <0 23 0x2 0x0 /* PA23 periph B */ + 0 24 0x2 0x0>; /* PA24 periph B */ + }; + }; pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; @@ -180,6 +243,8 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xffffee00 0x200>; interrupts = <1 4 7>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_dbgu>; status = "disabled"; }; @@ -189,6 +254,8 @@ interrupts = <7 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0>; status = "disabled"; }; @@ -198,6 +265,8 @@ interrupts = <8 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; status = "disabled"; }; @@ -207,6 +276,8 @@ interrupts = <9 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; status = "disabled"; }; @@ -216,6 +287,8 @@ interrupts = <10 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 8b5276499aa..e057f660296 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -117,6 +117,79 @@ >; /* shared pinctrl settings */ + dbgu { + pinctrl_dbgu: dbgu-0 { + atmel,pins = + <0 9 0x1 0x0 /* PA9 periph A */ + 0 10 0x1 0x1>; /* PA10 periph with pullup */ + }; + }; + + uart0 { + pinctrl_uart0: uart0-0 { + atmel,pins = + <0 1 0x1 0x1 /* PA1 periph A with pullup */ + 0 0 0x1 0x0>; /* PA0 periph A */ + }; + + pinctrl_uart0_rts_cts: uart0_rts_cts-0 { + atmel,pins = + <0 2 0x1 0x0 /* PA2 periph A */ + 0 3 0x1 0x0>; /* PA3 periph A */ + }; + }; + + uart1 { + pinctrl_uart1: uart1-0 { + atmel,pins = + <0 6 0x1 0x1 /* PA6 periph A with pullup */ + 0 5 0x1 0x0>; /* PA5 periph A */ + }; + }; + + uart2 { + pinctrl_uart2: uart2-0 { + atmel,pins = + <0 8 0x1 0x1 /* PA8 periph A with pullup */ + 0 7 0x1 0x0>; /* PA7 periph A */ + }; + + pinctrl_uart2_rts_cts: uart2_rts_cts-0 { + atmel,pins = + <1 0 0x2 0x0 /* PB0 periph B */ + 1 1 0x2 0x0>; /* PB1 periph B */ + }; + }; + + uart3 { + pinctrl_uart3: uart3-0 { + atmel,pins = + <2 23 0x2 0x1 /* PC23 periph B with pullup */ + 2 22 0x2 0x0>; /* PC22 periph B */ + }; + + pinctrl_uart3_rts_cts: uart3_rts_cts-0 { + atmel,pins = + <2 24 0x2 0x0 /* PC24 periph B */ + 2 25 0x2 0x0>; /* PC25 periph B */ + }; + }; + + usart0 { + pinctrl_usart0: usart0-0 { + atmel,pins = + <2 9 0x3 0x1 /* PC9 periph C with pullup */ + 2 8 0x3 0x0>; /* PC8 periph C */ + }; + }; + + usart1 { + pinctrl_usart1: usart1-0 { + atmel,pins = + <2 16 0x3 0x1 /* PC17 periph C with pullup */ + 2 17 0x3 0x0>; /* PC16 periph C */ + }; + }; pioA: gpio@fffff400 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; @@ -163,6 +236,8 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xfffff200 0x200>; interrupts = <1 4 7>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_dbgu>; status = "disabled"; }; @@ -172,6 +247,8 @@ interrupts = <5 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0>; status = "disabled"; }; @@ -181,6 +258,8 @@ interrupts = <6 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; status = "disabled"; }; @@ -190,6 +269,8 @@ interrupts = <7 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; status = "disabled"; }; @@ -199,6 +280,8 @@ interrupts = <8 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9x25.dtsi b/arch/arm/boot/dts/at91sam9x25.dtsi new file mode 100644 index 00000000000..956c65f7c39 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9x25.dtsi @@ -0,0 +1,28 @@ +/* + * at91sam9x25.dtsi - Device Tree Include file for AT91SAM9X25 SoC + * + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD + * + * Licensed under GPLv2. + */ + +/include/ "at91sam9x5.dtsi" + +/ { + model = "Atmel AT91SAM9X25 SoC"; + compatible = "atmel, at91sam9x25, atmel,at91sam9x5"; + + ahb { + apb { + pinctrl@fffff400 { + atmel,mux-mask = < + /* A B C */ + 0xffffffff 0xffe03fff 0xc000001c /* pioA */ + 0x0007ffff 0x00047e3f 0x00000000 /* pioB */ + 0x80000000 0xfffd0000 0xb83fffff /* pioC */ + 0x003fffff 0x003f8000 0x00000000 /* pioD */ + >; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9x25ek.dts b/arch/arm/boot/dts/at91sam9x25ek.dts new file mode 100644 index 00000000000..af907eaa1f2 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9x25ek.dts @@ -0,0 +1,16 @@ +/* + * at91sam9x25ek.dts - Device Tree file for AT91SAM9X25-EK board + * + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +/include/ "at91sam9x25.dtsi" +/include/ "at91sam9x5ek.dtsi" + +/ { + model = "Atmel AT91SAM9G25-EK"; + compatible = "atmel,at91sam9x25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; +}; diff --git a/arch/arm/boot/dts/at91sam9x35.dtsi b/arch/arm/boot/dts/at91sam9x35.dtsi new file mode 100644 index 00000000000..fb102d6126c --- /dev/null +++ b/arch/arm/boot/dts/at91sam9x35.dtsi @@ -0,0 +1,28 @@ +/* + * at91sam9x35.dtsi - Device Tree Include file for AT91SAM9X35 SoC + * + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD + * + * Licensed under GPLv2. + */ + +/include/ "at91sam9x5.dtsi" + +/ { + model = "Atmel AT91SAM9X35 SoC"; + compatible = "atmel, at91sam9x35, atmel,at91sam9x5"; + + ahb { + apb { + pinctrl@fffff400 { + atmel,mux-mask = < + /* A B C */ + 0xffffffff 0xffe03fff 0xc000000c /* pioA */ + 0x000406ff 0x00047e3f 0x00000000 /* pioB */ + 0xfdffffff 0x00000000 0xb83fffff /* pioC */ + 0x003fffff 0x003f8000 0x00000000 /* pioD */ + >; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91sam9x35ek.dts b/arch/arm/boot/dts/at91sam9x35ek.dts new file mode 100644 index 00000000000..5ccb607b541 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9x35ek.dts @@ -0,0 +1,16 @@ +/* + * at91sam9x35ek.dts - Device Tree file for AT91SAM9X35-EK board + * + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre + * + * Licensed under GPLv2 or later. + */ +/dts-v1/; +/include/ "at91sam9x35.dtsi" +/include/ "at91sam9x5ek.dtsi" + +/ { + model = "Atmel AT91SAM9X35-EK"; + compatible = "atmel,at91sam9x35ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; +}; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 34d4d5c8c58..1a68e41bbcd 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -111,21 +111,92 @@ interrupts = <21 4 0>; }; - pinctrl@fffff200 { + pinctrl@fffff400 { #address-cells = <1>; #size-cells = <1>; compatible = "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus"; ranges = <0xfffff400 0xfffff400 0x800>; - atmel,mux-mask = < - /* A B C */ - 0xffffffff 0xffe0399f 0xc000001c /* pioA */ - 0xffffffff 0xffc003ff 0xffc003ff /* pioB */ - 0xffffffff 0xffc003ff 0xffc003ff /* pioC */ - 0xffffffff 0xffc003ff 0xffc003ff /* pioD */ - >; - /* shared pinctrl settings */ + dbgu { + pinctrl_dbgu: dbgu-0 { + atmel,pins = + <0 9 0x1 0x0 /* PA9 periph A */ + 0 10 0x1 0x1>; /* PA10 periph A with pullup */ + }; + }; + + uart0 { + pinctrl_uart0: uart0-0 { + atmel,pins = + <0 0 0x1 0x1 /* PA0 periph A with pullup */ + 0 1 0x1 0x0>; /* PA1 periph A */ + }; + + pinctrl_uart0_rts_cts: uart0_rts_cts-0 { + atmel,pins = + <0 2 0x1 0x0 /* PA2 periph A */ + 0 3 0x1 0x0>; /* PA3 periph A */ + }; + }; + + uart1 { + pinctrl_uart1: uart1-0 { + atmel,pins = + <0 5 0x1 0x1 /* PA5 periph A with pullup */ + 0 6 0x1 0x0>; /* PA6 periph A */ + }; + + pinctrl_uart1_rts_cts: uart1_rts_cts-0 { + atmel,pins = + <3 27 0x3 0x0 /* PC27 periph C */ + 3 28 0x3 0x0>; /* PC28 periph C */ + }; + }; + + uart2 { + pinctrl_uart2: uart2-0 { + atmel,pins = + <0 7 0x1 0x1 /* PA7 periph A with pullup */ + 0 8 0x1 0x0>; /* PA8 periph A */ + }; + + pinctrl_uart2_rts_cts: uart2_rts_cts-0 { + atmel,pins = + <0 0 0x2 0x0 /* PB0 periph B */ + 0 1 0x2 0x0>; /* PB1 periph B */ + }; + }; + + uart3 { + pinctrl_uart3: uart3-0 { + atmel,pins = + <3 23 0x2 0x1 /* PC22 periph B with pullup */ + 3 23 0x2 0x0>; /* PC23 periph B */ + }; + + pinctrl_uart3_rts_cts: uart3_rts_cts-0 { + atmel,pins = + <3 24 0x2 0x0 /* PC24 periph B */ + 3 25 0x2 0x0>; /* PC25 periph B */ + }; + }; + + usart0 { + pinctrl_usart0: usart0-0 { + atmel,pins = + <3 8 0x3 0x0 /* PC8 periph C */ + 3 9 0x3 0x1>; /* PC9 periph C with pullup */ + }; + }; + + usart1 { + pinctrl_usart1: usart1-0 { + atmel,pins = + <3 16 0x3 0x0 /* PC16 periph C */ + 3 17 0x3 0x1>; /* PC17 periph C with pullup */ + }; + }; pioA: gpio@fffff400 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; @@ -174,6 +245,8 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xfffff200 0x200>; interrupts = <1 4 7>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_dbgu>; status = "disabled"; }; @@ -183,6 +256,8 @@ interrupts = <5 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0>; status = "disabled"; }; @@ -192,6 +267,8 @@ interrupts = <6 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; status = "disabled"; }; @@ -201,6 +278,8 @@ interrupts = <7 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi new file mode 100644 index 00000000000..cc9730c6018 --- /dev/null +++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi @@ -0,0 +1,59 @@ +/* + * at91sam9x5ek.dtsi - Device Tree file for AT91SAM9x5CM Base board + * + * Copyright (C) 2012 Atmel, + * 2012 Nicolas Ferre + * + * Licensed under GPLv2 or later. + */ +/include/ "at91sam9x5cm.dtsi" + +/ { + model = "Atmel AT91SAM9X5-EK"; + compatible = "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9"; + + chosen { + bootargs = "128M console=ttyS0,115200 root=/dev/mtdblock1 rw rootfstype=ubifs ubi.mtd=1 root=ubi0:rootfs"; + }; + + ahb { + apb { + dbgu: serial@fffff200 { + status = "okay"; + }; + + usart0: serial@f801c000 { + status = "okay"; + }; + + macb0: ethernet@f802c000 { + phy-mode = "rmii"; + status = "okay"; + }; + + i2c0: i2c@f8010000 { + status = "okay"; + }; + + i2c1: i2c@f8014000 { + status = "okay"; + }; + + i2c2: i2c@f8018000 { + status = "okay"; + }; + }; + + usb0: ohci@00600000 { + status = "okay"; + num-ports = <2>; + atmel,vbus-gpio = <&pioD 19 1 + &pioD 20 1 + >; + }; + + usb1: ehci@00700000 { + status = "okay"; + }; + }; +}; -- cgit v1.2.3 From 784557decc48432c389b3d2ec1cbde515a4b2d9f Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 6 Jul 2012 00:41:57 +0800 Subject: tty: atmel_serial: add pinctrl support Acked-by: Nicolas Ferre Acked-by: Greg Kroah-Hartman Acked-by: Linus Walleij Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/tty/serial/atmel_serial.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 3d7e1ee2fa5..65f891be12d 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -1773,6 +1774,7 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) struct atmel_uart_data *pdata = pdev->dev.platform_data; void *data; int ret = -ENODEV; + struct pinctrl *pinctrl; BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1)); @@ -1805,6 +1807,12 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) atmel_init_port(port, pdev); + pinctrl = devm_pinctrl_get_select_default(&pdev->dev); + if (IS_ERR(pinctrl)) { + ret = PTR_ERR(pinctrl); + goto err; + } + if (!atmel_use_dma_rx(&port->uart)) { ret = -ENOMEM; data = kmalloc(sizeof(struct atmel_uart_char) -- cgit v1.2.3 From ea45f743dec94c47399fdb443439dc75a5005e05 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 6 Jul 2012 00:41:57 +0800 Subject: arm: at91: dt: sam9m10g45ek: use rts/cts pinctrl group for uart1 Acked-by: Nicolas Ferre Acked-by: Linus Walleij Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9m10g45ek.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index 15e1dd43f62..6aa28b94190 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -39,6 +39,7 @@ }; usart1: serial@fff90000 { + pinctrl-0 = <&pinctrl_uart0 &pinctrl_uart1_rts_cts>; status = "okay"; }; -- cgit v1.2.3 From 4b20d98cf2a3edd34c2f7a19e0b948e1655900c9 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 10 Aug 2012 03:38:36 +0800 Subject: arm: at91: dt: sam9263ek: use rts/cts pinctrl group for uart0 Acked-by: Nicolas Ferre Acked-by: Linus Walleij Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9263ek.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts index f86ac4b609f..7cfe9d521f1 100644 --- a/arch/arm/boot/dts/at91sam9263ek.dts +++ b/arch/arm/boot/dts/at91sam9263ek.dts @@ -38,6 +38,7 @@ }; usart0: serial@fff8c000 { + pinctrl-0 = <&pinctrl_uart0 &pinctrl_uart0_rts_cts>; status = "okay"; }; -- cgit v1.2.3 From 0cdc7e8e113634992d1b2ee6f14cbf9850a9c35e Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 10 Aug 2012 13:07:57 +0800 Subject: arm: at91: dt: sam9g20ek: use rts/cts/dtr/dsr/dcd/ri pinctrl group for uart0 Acked-by: Linus Walleij Acked-by: Nicolas Ferre Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index b06c0db273b..e33ab0a88d0 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -35,6 +35,12 @@ }; usart0: serial@fffb0000 { + pinctrl-0 = + <&pinctrl_uart0 + &pinctrl_uart0_rts_cts + &pinctrl_uart0_dtr_dsr + &pinctrl_uart0_dcd + &pinctrl_uart0_ri>; status = "okay"; }; -- cgit v1.2.3 From 7a38d450b62e7b27b350352c0ab08b66bea00131 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 12 Jul 2012 23:36:52 +0800 Subject: arm: at91: dt: at91sam9 add nand pinctrl support Acked-by: Nicolas Ferre Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9260.dtsi | 10 ++++++++++ arch/arm/boot/dts/at91sam9263.dtsi | 10 ++++++++++ arch/arm/boot/dts/at91sam9g45.dtsi | 10 ++++++++++ arch/arm/boot/dts/at91sam9n12.dtsi | 10 ++++++++++ arch/arm/boot/dts/at91sam9x5.dtsi | 10 ++++++++++ 5 files changed, 50 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 838328a1829..9a24ffbb723 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -208,6 +208,14 @@ }; }; + nand { + pinctrl_nand: nand-0 { + atmel,pins = + <2 13 0x0 0x1 /* PC13 gpio RDY pin pull_up */ + 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */ + }; + }; + pioA: gpio@fffff400 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>; @@ -382,6 +390,8 @@ >; atmel,nand-addr-offset = <21>; atmel,nand-cmd-offset = <22>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; gpios = <&pioC 13 0 &pioC 14 0 0 diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 579f82d23d3..251ccec430a 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -155,6 +155,14 @@ }; }; + nand { + pinctrl_nand: nand-0 { + atmel,pins = + <0 22 0x0 0x1 /* PA22 gpio RDY pin pull_up*/ + 3 15 0x0 0x1>; /* PD15 gpio enable pin pull_up */ + }; + }; + pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff200 0x200>; @@ -281,6 +289,8 @@ >; atmel,nand-addr-offset = <21>; atmel,nand-cmd-offset = <22>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; gpios = <&pioA 22 0 &pioD 15 0 0 diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 48a2ed72fea..c340f6635d8 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -188,6 +188,14 @@ }; }; + nand { + pinctrl_nand: nand-0 { + atmel,pins = + <2 8 0x0 0x1 /* PC8 gpio RDY pin pull_up*/ + 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */ + }; + }; + pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff200 0x200>; @@ -364,6 +372,8 @@ >; atmel,nand-addr-offset = <21>; atmel,nand-cmd-offset = <22>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; gpios = <&pioC 8 0 &pioC 14 0 0 diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index e057f660296..7b644c5b0be 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -191,6 +191,14 @@ }; }; + nand { + pinctrl_nand: nand-0 { + atmel,pins = + <3 5 0x0 0x1 /* PD5 gpio RDY pin pull_up*/ + 3 4 0x0 0x1>; /* PD4 gpio enable pin pull_up */ + }; + }; + pioA: gpio@fffff400 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>; @@ -315,6 +323,8 @@ >; atmel,nand-addr-offset = <21>; atmel,nand-cmd-offset = <22>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; gpios = <&pioD 5 0 &pioD 4 0 0 diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 1a68e41bbcd..6a40b777ea4 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -198,6 +198,14 @@ }; }; + nand { + pinctrl_nand: nand-0 { + atmel,pins = + <3 4 0x0 0x1 /* PD5 gpio RDY pin pull_up */ + 3 5 0x0 0x1>; /* PD4 gpio enable pin pull_up */ + }; + }; + pioA: gpio@fffff400 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>; @@ -371,6 +379,8 @@ >; atmel,nand-addr-offset = <21>; atmel,nand-cmd-offset = <22>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; gpios = <&pioD 5 0 &pioD 4 0 0 -- cgit v1.2.3 From 251e783ad0375470fa4fd3848645a38c5d3ee6c3 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 12 Jul 2012 23:31:39 +0800 Subject: MTD: atmel_nand: add pinctrl consumer support Acked-by: Nicolas Ferre Acked-by: Artem Bityutskiy Acked-by: Linus Walleij Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/mtd/nand/atmel_nand.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 91445578330..92623ac2015 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -1370,6 +1371,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev) struct resource *mem; struct mtd_part_parser_data ppdata = {}; int res; + struct pinctrl *pinctrl; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { @@ -1414,6 +1416,13 @@ static int __init atmel_nand_probe(struct platform_device *pdev) nand_chip->IO_ADDR_W = host->io_base; nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl; + pinctrl = devm_pinctrl_get_select_default(&pdev->dev); + if (IS_ERR(pinctrl)) { + dev_err(host->dev, "Failed to request pinctrl\n"); + res = PTR_ERR(pinctrl); + goto err_ecc_ioremap; + } + if (gpio_is_valid(host->board.rdy_pin)) { res = gpio_request(host->board.rdy_pin, "nand_rdy"); if (res < 0) { -- cgit v1.2.3 From 380f0d28431e852e07e3fa0d5f6e36cf9ea5aa5a Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 11 Oct 2012 13:48:36 +0300 Subject: usb: dwc3: core: switch event buffer allocation to devm_kzalloc() The rest of the driver is using devm_kzalloc() where possible and this patch is just making event buffer allocation follow the example. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b415c0c859d..8d543ea4352 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -169,7 +169,6 @@ static void dwc3_free_one_event_buffer(struct dwc3 *dwc, struct dwc3_event_buffer *evt) { dma_free_coherent(dwc->dev, evt->length, evt->buf, evt->dma); - kfree(evt); } /** @@ -185,7 +184,7 @@ dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length) { struct dwc3_event_buffer *evt; - evt = kzalloc(sizeof(*evt), GFP_KERNEL); + evt = devm_kzalloc(dwc->dev, sizeof(*evt), GFP_KERNEL); if (!evt) return ERR_PTR(-ENOMEM); @@ -215,8 +214,6 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc) if (evt) dwc3_free_one_event_buffer(dwc, evt); } - - kfree(dwc->ev_buffs); } /** @@ -235,7 +232,8 @@ static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) num = DWC3_NUM_INT(dwc->hwparams.hwparams1); dwc->num_event_buffers = num; - dwc->ev_buffs = kzalloc(sizeof(*dwc->ev_buffs) * num, GFP_KERNEL); + dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num, + GFP_KERNEL); if (!dwc->ev_buffs) { dev_err(dwc->dev, "can't allocate event buffers array\n"); return -ENOMEM; -- cgit v1.2.3 From 3921426b13b1e0b2db6872a8d22d9fe2a4afe332 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 11 Oct 2012 13:54:36 +0300 Subject: usb: dwc3: core: move event buffer allocation out of dwc3_core_init() This patch is in preparation for adding PM support dwc3 driver. We want to re-use dwc3_core_init and dwc3_core_exit() functions on resume() and suspend() callbacks respectively. Moving even buffer allocation away from dwc3_core_init() will allow us to reuse the event buffer which was allocated long ago on our probe() routine. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 8d543ea4352..b923183c43c 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -381,24 +381,14 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GCTL, reg); - ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); - if (ret) { - dev_err(dwc->dev, "failed to allocate event buffers\n"); - ret = -ENOMEM; - goto err1; - } - ret = dwc3_event_buffers_setup(dwc); if (ret) { dev_err(dwc->dev, "failed to setup event buffers\n"); - goto err1; + goto err0; } return 0; -err1: - dwc3_free_event_buffers(dwc); - err0: return ret; } @@ -406,7 +396,6 @@ err0: static void dwc3_core_exit(struct dwc3 *dwc) { dwc3_event_buffers_cleanup(dwc); - dwc3_free_event_buffers(dwc); } #define DWC3_ALIGN_MASK (16 - 1) @@ -509,10 +498,17 @@ static int __devinit dwc3_probe(struct platform_device *pdev) pm_runtime_get_sync(dev); pm_runtime_forbid(dev); + ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); + if (ret) { + dev_err(dwc->dev, "failed to allocate event buffers\n"); + ret = -ENOMEM; + goto err0; + } + ret = dwc3_core_init(dwc); if (ret) { dev_err(dev, "failed to initialize core\n"); - return ret; + goto err0; } mode = DWC3_MODE(dwc->hwparams.hwparams0); @@ -584,6 +580,9 @@ err2: err1: dwc3_core_exit(dwc); +err0: + dwc3_free_event_buffers(dwc); + return ret; } -- cgit v1.2.3 From a0a83eb407ef17dae9a286d86ee2a437f6adb4c2 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 10 Oct 2012 19:36:46 +0100 Subject: usb: musb: am35x: use module_platform_driver macro This patch removes some code duplication by using module_platform_driver. Signed-off-by: Srinivas Kandagatla Signed-off-by: Felipe Balbi --- drivers/usb/musb/am35x.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 457f25e62c5..89b128bdbca 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -648,15 +648,4 @@ static struct platform_driver am35x_driver = { MODULE_DESCRIPTION("AM35x MUSB Glue Layer"); MODULE_AUTHOR("Ajay Kumar Gupta "); MODULE_LICENSE("GPL v2"); - -static int __init am35x_init(void) -{ - return platform_driver_register(&am35x_driver); -} -module_init(am35x_init); - -static void __exit am35x_exit(void) -{ - platform_driver_unregister(&am35x_driver); -} -module_exit(am35x_exit); +module_platform_driver(am35x_driver); -- cgit v1.2.3 From 692373e128f16da708ec6ddf80ee5b5bb3761ef9 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 10 Oct 2012 19:36:52 +0100 Subject: usb: musb: blackfin: use module_platform_driver macro This patch removes some code duplication by using module_platform_driver. Signed-off-by: Srinivas Kandagatla Signed-off-by: Felipe Balbi --- drivers/usb/musb/blackfin.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index e8cff9bb9d2..8c16a22e171 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -585,15 +585,4 @@ static struct platform_driver bfin_driver = { MODULE_DESCRIPTION("Blackfin MUSB Glue Layer"); MODULE_AUTHOR("Bryan Wy "); MODULE_LICENSE("GPL v2"); - -static int __init bfin_init(void) -{ - return platform_driver_register(&bfin_driver); -} -module_init(bfin_init); - -static void __exit bfin_exit(void) -{ - platform_driver_unregister(&bfin_driver); -} -module_exit(bfin_exit); +module_platform_driver(bfin_driver); -- cgit v1.2.3 From 0b07734d5e0096458acf19b2e6b0585ad5006b86 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 10 Oct 2012 19:36:59 +0100 Subject: usb: musb: da8xx: use module_platform_driver macro This patch removes some code duplication by using module_platform_driver. Signed-off-by: Srinivas Kandagatla Signed-off-by: Felipe Balbi --- drivers/usb/musb/da8xx.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 8bc44b76eec..2366b818443 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -593,15 +593,4 @@ static struct platform_driver da8xx_driver = { MODULE_DESCRIPTION("DA8xx/OMAP-L1x MUSB Glue Layer"); MODULE_AUTHOR("Sergei Shtylyov "); MODULE_LICENSE("GPL v2"); - -static int __init da8xx_init(void) -{ - return platform_driver_register(&da8xx_driver); -} -module_init(da8xx_init); - -static void __exit da8xx_exit(void) -{ - platform_driver_unregister(&da8xx_driver); -} -module_exit(da8xx_exit); +module_platform_driver(da8xx_driver); -- cgit v1.2.3 From 8d92f6d46c73bbc10310a38784f130527dfcf8a1 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 10 Oct 2012 19:37:07 +0100 Subject: usb: musb: davinci: use module_platform_driver macro This patch removes some code duplication by using module_platform_driver. Signed-off-by: Srinivas Kandagatla Signed-off-by: Felipe Balbi --- drivers/usb/musb/davinci.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 606bfd00cde..62785bf0f95 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -625,15 +625,4 @@ static struct platform_driver davinci_driver = { MODULE_DESCRIPTION("DaVinci MUSB Glue Layer"); MODULE_AUTHOR("Felipe Balbi "); MODULE_LICENSE("GPL v2"); - -static int __init davinci_init(void) -{ - return platform_driver_register(&davinci_driver); -} -module_init(davinci_init); - -static void __exit davinci_exit(void) -{ - platform_driver_unregister(&davinci_driver); -} -module_exit(davinci_exit); +module_platform_driver(davinci_driver); -- cgit v1.2.3 From 01380c081eada4fa4a2e52ef9ea2b16eaddbfc46 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 10 Oct 2012 19:37:14 +0100 Subject: usb: musb: tusb6010: use module_platform_driver macro This patch removes some code duplication by using module_platform_driver. Signed-off-by: Srinivas Kandagatla Signed-off-by: Felipe Balbi --- drivers/usb/musb/tusb6010.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index dc4d75ea13a..39ece28019f 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1251,15 +1251,4 @@ static struct platform_driver tusb_driver = { MODULE_DESCRIPTION("TUSB6010 MUSB Glue Layer"); MODULE_AUTHOR("Felipe Balbi "); MODULE_LICENSE("GPL v2"); - -static int __init tusb_init(void) -{ - return platform_driver_register(&tusb_driver); -} -module_init(tusb_init); - -static void __exit tusb_exit(void) -{ - platform_driver_unregister(&tusb_driver); -} -module_exit(tusb_exit); +module_platform_driver(tusb_driver); -- cgit v1.2.3 From 0e7090a626eb6205c123f735a879065702a08cb8 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 10 Oct 2012 19:37:21 +0100 Subject: usb: musb: ux500: use module_platform_driver macro This patch removes some code duplication by using module_platform_driver. Signed-off-by: Srinivas Kandagatla Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index d62a91fedc2..be1430ad60e 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -219,15 +219,4 @@ static struct platform_driver ux500_driver = { MODULE_DESCRIPTION("UX500 MUSB Glue Layer"); MODULE_AUTHOR("Mian Yousaf Kaukab "); MODULE_LICENSE("GPL v2"); - -static int __init ux500_init(void) -{ - return platform_driver_register(&ux500_driver); -} -module_init(ux500_init); - -static void __exit ux500_exit(void) -{ - platform_driver_unregister(&ux500_driver); -} -module_exit(ux500_exit); +module_platform_driver(ux500_driver); -- cgit v1.2.3 From 5bb962269c29cbb878414cddf0ebdff8c5cdef0a Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Mon, 15 Oct 2012 02:03:27 +0200 Subject: tick: Consolidate timekeeping handling code Unify the duplicated timekeeping handling code of low and high res tick sched handlers. Signed-off-by: Frederic Weisbecker Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Peter Zijlstra --- kernel/time/tick-sched.c | 54 +++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index a4026088526..360674c485f 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -98,6 +98,28 @@ static ktime_t tick_init_jiffy_update(void) return period; } + +static void tick_sched_do_timer(ktime_t now) +{ + int cpu = smp_processor_id(); + +#ifdef CONFIG_NO_HZ + /* + * Check if the do_timer duty was dropped. We don't care about + * concurrency: This happens only when the cpu in charge went + * into a long sleep. If two cpus happen to assign themself to + * this duty, then the jiffies update is still serialized by + * xtime_lock. + */ + if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) + tick_do_timer_cpu = cpu; +#endif + + /* Check, if the jiffies need an update */ + if (tick_do_timer_cpu == cpu) + tick_do_update_jiffies64(now); +} + /* * NOHZ - aka dynamic tick functionality */ @@ -648,24 +670,11 @@ static void tick_nohz_handler(struct clock_event_device *dev) { struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); struct pt_regs *regs = get_irq_regs(); - int cpu = smp_processor_id(); ktime_t now = ktime_get(); dev->next_event.tv64 = KTIME_MAX; - /* - * Check if the do_timer duty was dropped. We don't care about - * concurrency: This happens only when the cpu in charge went - * into a long sleep. If two cpus happen to assign themself to - * this duty, then the jiffies update is still serialized by - * xtime_lock. - */ - if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) - tick_do_timer_cpu = cpu; - - /* Check, if the jiffies need an update */ - if (tick_do_timer_cpu == cpu) - tick_do_update_jiffies64(now); + tick_sched_do_timer(now); /* * When we are idle and the tick is stopped, we have to touch @@ -802,23 +811,8 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) container_of(timer, struct tick_sched, sched_timer); struct pt_regs *regs = get_irq_regs(); ktime_t now = ktime_get(); - int cpu = smp_processor_id(); -#ifdef CONFIG_NO_HZ - /* - * Check if the do_timer duty was dropped. We don't care about - * concurrency: This happens only when the cpu in charge went - * into a long sleep. If two cpus happen to assign themself to - * this duty, then the jiffies update is still serialized by - * xtime_lock. - */ - if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) - tick_do_timer_cpu = cpu; -#endif - - /* Check, if the jiffies need an update */ - if (tick_do_timer_cpu == cpu) - tick_do_update_jiffies64(now); + tick_sched_do_timer(now); /* * Do not call, when we are not in irq context and have -- cgit v1.2.3 From 9e8f559b08cbc1cfcbf093840a2a760a946cb90f Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Mon, 15 Oct 2012 02:43:03 +0200 Subject: tick: Consolidate tick handling for high and low res handlers Besides unifying code, this also adds the idle check before processing idle accounting specifics on the low res handler. This way we also generalize this part of the nohz code for !CONFIG_HIGH_RES_TIMERS to prepare for the adaptive tickless features. Signed-off-by: Frederic Weisbecker Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Peter Zijlstra --- kernel/time/tick-sched.c | 55 +++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 360674c485f..68a873af09a 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -120,6 +120,25 @@ static void tick_sched_do_timer(ktime_t now) tick_do_update_jiffies64(now); } +static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs) +{ + /* + * When we are idle and the tick is stopped, we have to touch + * the watchdog as we might not schedule for a really long + * time. This happens on complete idle SMP systems while + * waiting on the login prompt. We also increment the "start of + * idle" jiffy stamp so the idle accounting adjustment we do + * when we go busy again does not account too much ticks. + */ + if (ts->tick_stopped) { + touch_softlockup_watchdog(); + if (is_idle_task(current)) + ts->idle_jiffies++; + } + update_process_times(user_mode(regs)); + profile_tick(CPU_PROFILING); +} + /* * NOHZ - aka dynamic tick functionality */ @@ -675,22 +694,7 @@ static void tick_nohz_handler(struct clock_event_device *dev) dev->next_event.tv64 = KTIME_MAX; tick_sched_do_timer(now); - - /* - * When we are idle and the tick is stopped, we have to touch - * the watchdog as we might not schedule for a really long - * time. This happens on complete idle SMP systems while - * waiting on the login prompt. We also increment the "start - * of idle" jiffy stamp so the idle accounting adjustment we - * do when we go busy again does not account too much ticks. - */ - if (ts->tick_stopped) { - touch_softlockup_watchdog(); - ts->idle_jiffies++; - } - - update_process_times(user_mode(regs)); - profile_tick(CPU_PROFILING); + tick_sched_handle(ts, regs); while (tick_nohz_reprogram(ts, now)) { now = ktime_get(); @@ -818,23 +822,8 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) * Do not call, when we are not in irq context and have * no valid regs pointer */ - if (regs) { - /* - * When we are idle and the tick is stopped, we have to touch - * the watchdog as we might not schedule for a really long - * time. This happens on complete idle SMP systems while - * waiting on the login prompt. We also increment the "start of - * idle" jiffy stamp so the idle accounting adjustment we do - * when we go busy again does not account too much ticks. - */ - if (ts->tick_stopped) { - touch_softlockup_watchdog(); - if (is_idle_task(current)) - ts->idle_jiffies++; - } - update_process_times(user_mode(regs)); - profile_tick(CPU_PROFILING); - } + if (regs) + tick_sched_handle(ts, regs); hrtimer_forward(timer, now, tick_period); -- cgit v1.2.3 From 94a571402012e0dfaa23bbbdd64d033f48477d86 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Mon, 15 Oct 2012 16:17:16 +0200 Subject: tick: Conditionally build nohz specific code in tick handler This optimize a bit the high res tick sched handler. Signed-off-by: Frederic Weisbecker Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Peter Zijlstra --- kernel/time/tick-sched.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 68a873af09a..766d4c47a4a 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -122,6 +122,7 @@ static void tick_sched_do_timer(ktime_t now) static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs) { +#ifdef CONFIG_NO_HZ /* * When we are idle and the tick is stopped, we have to touch * the watchdog as we might not schedule for a really long @@ -135,6 +136,7 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs) if (is_idle_task(current)) ts->idle_jiffies++; } +#endif update_process_times(user_mode(regs)); profile_tick(CPU_PROFILING); } -- cgit v1.2.3 From 8944df726c7d2916764d18be8e944bd7ea3f2f51 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 5 Oct 2012 11:45:28 +0200 Subject: gpio/gpio-pl061: Covert to use devm_* functions Use the devm_* family of functions during probe to reduce the error handling code footprint. Signed-off-by: Tobias Klauser Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pl061.c | 59 ++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index b4b5da4fd2c..31d9c9e79ea 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -216,39 +216,34 @@ static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base) IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); } -static int pl061_probe(struct amba_device *dev, const struct amba_id *id) +static int pl061_probe(struct amba_device *adev, const struct amba_id *id) { - struct pl061_platform_data *pdata; + struct device *dev = &adev->dev; + struct pl061_platform_data *pdata = dev->platform_data; struct pl061_gpio *chip; int ret, irq, i; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); if (chip == NULL) return -ENOMEM; - pdata = dev->dev.platform_data; if (pdata) { chip->gc.base = pdata->gpio_base; chip->irq_base = pdata->irq_base; - } else if (dev->dev.of_node) { + } else if (adev->dev.of_node) { chip->gc.base = -1; chip->irq_base = 0; - } else { - ret = -ENODEV; - goto free_mem; - } + } else + return -ENODEV; - if (!request_mem_region(dev->res.start, - resource_size(&dev->res), "pl061")) { - ret = -EBUSY; - goto free_mem; - } + if (!devm_request_mem_region(dev, adev->res.start, + resource_size(&adev->res), "pl061")) + return -EBUSY; - chip->base = ioremap(dev->res.start, resource_size(&dev->res)); - if (chip->base == NULL) { - ret = -ENOMEM; - goto release_region; - } + chip->base = devm_ioremap(dev, adev->res.start, + resource_size(&adev->res)); + if (chip->base == NULL) + return -ENOMEM; spin_lock_init(&chip->lock); @@ -258,13 +253,13 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) chip->gc.set = pl061_set_value; chip->gc.to_irq = pl061_to_irq; chip->gc.ngpio = PL061_GPIO_NR; - chip->gc.label = dev_name(&dev->dev); - chip->gc.dev = &dev->dev; + chip->gc.label = dev_name(dev); + chip->gc.dev = dev; chip->gc.owner = THIS_MODULE; ret = gpiochip_add(&chip->gc); if (ret) - goto iounmap; + return ret; /* * irq_chip support @@ -276,11 +271,10 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) pl061_init_gc(chip, chip->irq_base); writeb(0, chip->base + GPIOIE); /* disable irqs */ - irq = dev->irq[0]; - if (irq < 0) { - ret = -ENODEV; - goto iounmap; - } + irq = adev->irq[0]; + if (irq < 0) + return -ENODEV; + irq_set_chained_handler(irq, pl061_irq_handler); irq_set_handler_data(irq, chip); @@ -294,18 +288,9 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) } } - amba_set_drvdata(dev, chip); + amba_set_drvdata(adev, chip); return 0; - -iounmap: - iounmap(chip->base); -release_region: - release_mem_region(dev->res.start, resource_size(&dev->res)); -free_mem: - kfree(chip); - - return ret; } #ifdef CONFIG_PM -- cgit v1.2.3 From 086d585f13542de205c25fd225a37aa0cadc3be0 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 5 Oct 2012 11:37:38 +0200 Subject: gpio/gpio-omap: Use existing pointer to struct device A pointer to "pdev->dev" is already stored in "dev", so use it in devm_kzalloc. Signed-off-by: Tobias Klauser Acked-by: Kevin Hilman Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 94cbc842fbc..eb73dee0ab3 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1070,7 +1070,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) if (!pdata) return -EINVAL; - bank = devm_kzalloc(&pdev->dev, sizeof(struct gpio_bank), GFP_KERNEL); + bank = devm_kzalloc(dev, sizeof(struct gpio_bank), GFP_KERNEL); if (!bank) { dev_err(dev, "Memory alloc failed\n"); return -ENOMEM; -- cgit v1.2.3 From 04ed4279715f685857b8d5b84a48bf7bd43a36c5 Mon Sep 17 00:00:00 2001 From: Ashish Jangam Date: Fri, 14 Sep 2012 19:00:16 +0530 Subject: DA9055 GPIO driver This is the GPIO patch for the DA9055 PMIC. This patch has got dependency on the DA9055 MFD core. This patch is functionally tested on SMDK6410 board. Signed-off-by: David Dajun Chen Signed-off-by: Ashish Jangam Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 11 +++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-da9055.c | 204 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 drivers/gpio/gpio-da9055.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d055cee3694..150eeb705fb 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -86,6 +86,17 @@ config GPIO_DA9052 help Say yes here to enable the GPIO driver for the DA9052 chip. +config GPIO_DA9055 + tristate "Dialog Semiconductor DA9055 GPIO" + depends on MFD_DA9055 + help + Say yes here to enable the GPIO driver for the DA9055 chip. + + The Dialog DA9055 PMIC chip has 3 GPIO pins that can be + be controller by this driver. + + If driver is built as a module it will be called gpio-da9055. + config GPIO_MAX730X tristate diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 9aeed670732..e6f8e379a2e 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o +obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o obj-$(CONFIG_GPIO_EM) += gpio-em.o obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o diff --git a/drivers/gpio/gpio-da9055.c b/drivers/gpio/gpio-da9055.c new file mode 100644 index 00000000000..55d83c7d9c7 --- /dev/null +++ b/drivers/gpio/gpio-da9055.c @@ -0,0 +1,204 @@ +/* + * GPIO Driver for Dialog DA9055 PMICs. + * + * Copyright(c) 2012 Dialog Semiconductor Ltd. + * + * Author: David Dajun Chen + * + * 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 +#include +#include + +#include +#include +#include + +#define DA9055_VDD_IO 0x0 +#define DA9055_PUSH_PULL 0x3 +#define DA9055_ACT_LOW 0x0 +#define DA9055_GPI 0x1 +#define DA9055_PORT_MASK 0x3 +#define DA9055_PORT_SHIFT(offset) (4 * (offset % 2)) + +#define DA9055_INPUT DA9055_GPI +#define DA9055_OUTPUT DA9055_PUSH_PULL +#define DA9055_IRQ_GPI0 3 + +struct da9055_gpio { + struct da9055 *da9055; + struct gpio_chip gp; +}; + +static inline struct da9055_gpio *to_da9055_gpio(struct gpio_chip *chip) +{ + return container_of(chip, struct da9055_gpio, gp); +} + +static int da9055_gpio_get(struct gpio_chip *gc, unsigned offset) +{ + struct da9055_gpio *gpio = to_da9055_gpio(gc); + int gpio_direction = 0; + int ret; + + /* Get GPIO direction */ + ret = da9055_reg_read(gpio->da9055, (offset >> 1) + DA9055_REG_GPIO0_1); + if (ret < 0) + return ret; + + gpio_direction = ret & (DA9055_PORT_MASK) << DA9055_PORT_SHIFT(offset); + gpio_direction >>= DA9055_PORT_SHIFT(offset); + switch (gpio_direction) { + case DA9055_INPUT: + ret = da9055_reg_read(gpio->da9055, DA9055_REG_STATUS_B); + if (ret < 0) + return ret; + break; + case DA9055_OUTPUT: + ret = da9055_reg_read(gpio->da9055, DA9055_REG_GPIO_MODE0_2); + if (ret < 0) + return ret; + } + + return ret & (1 << offset); + +} + +static void da9055_gpio_set(struct gpio_chip *gc, unsigned offset, int value) +{ + struct da9055_gpio *gpio = to_da9055_gpio(gc); + + da9055_reg_update(gpio->da9055, + DA9055_REG_GPIO_MODE0_2, + 1 << offset, + value << offset); +} + +static int da9055_gpio_direction_input(struct gpio_chip *gc, unsigned offset) +{ + struct da9055_gpio *gpio = to_da9055_gpio(gc); + unsigned char reg_byte; + + reg_byte = (DA9055_ACT_LOW | DA9055_GPI) + << DA9055_PORT_SHIFT(offset); + + return da9055_reg_update(gpio->da9055, (offset >> 1) + + DA9055_REG_GPIO0_1, + DA9055_PORT_MASK << + DA9055_PORT_SHIFT(offset), + reg_byte); +} + +static int da9055_gpio_direction_output(struct gpio_chip *gc, + unsigned offset, int value) +{ + struct da9055_gpio *gpio = to_da9055_gpio(gc); + unsigned char reg_byte; + int ret; + + reg_byte = (DA9055_VDD_IO | DA9055_PUSH_PULL) + << DA9055_PORT_SHIFT(offset); + + ret = da9055_reg_update(gpio->da9055, (offset >> 1) + + DA9055_REG_GPIO0_1, + DA9055_PORT_MASK << + DA9055_PORT_SHIFT(offset), + reg_byte); + if (ret < 0) + return ret; + + da9055_gpio_set(gc, offset, value); + + return 0; +} + +static int da9055_gpio_to_irq(struct gpio_chip *gc, u32 offset) +{ + struct da9055_gpio *gpio = to_da9055_gpio(gc); + struct da9055 *da9055 = gpio->da9055; + + return regmap_irq_get_virq(da9055->irq_data, + DA9055_IRQ_GPI0 + offset); +} + +static struct gpio_chip reference_gp __devinitdata = { + .label = "da9055-gpio", + .owner = THIS_MODULE, + .get = da9055_gpio_get, + .set = da9055_gpio_set, + .direction_input = da9055_gpio_direction_input, + .direction_output = da9055_gpio_direction_output, + .to_irq = da9055_gpio_to_irq, + .can_sleep = 1, + .ngpio = 3, + .base = -1, +}; + +static int __devinit da9055_gpio_probe(struct platform_device *pdev) +{ + struct da9055_gpio *gpio; + struct da9055_pdata *pdata; + int ret; + + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (gpio == NULL) + return -ENOMEM; + + gpio->da9055 = dev_get_drvdata(pdev->dev.parent); + pdata = gpio->da9055->dev->platform_data; + + gpio->gp = reference_gp; + if (pdata && pdata->gpio_base) + gpio->gp.base = pdata->gpio_base; + + ret = gpiochip_add(&gpio->gp); + if (ret < 0) { + dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); + goto err_mem; + } + + platform_set_drvdata(pdev, gpio); + + return 0; + +err_mem: + return ret; +} + +static int __devexit da9055_gpio_remove(struct platform_device *pdev) +{ + struct da9055_gpio *gpio = platform_get_drvdata(pdev); + + return gpiochip_remove(&gpio->gp); +} + +static struct platform_driver da9055_gpio_driver = { + .probe = da9055_gpio_probe, + .remove = __devexit_p(da9055_gpio_remove), + .driver = { + .name = "da9055-gpio", + .owner = THIS_MODULE, + }, +}; + +static int __init da9055_gpio_init(void) +{ + return platform_driver_register(&da9055_gpio_driver); +} +subsys_initcall(da9055_gpio_init); + +static void __exit da9055_gpio_exit(void) +{ + platform_driver_unregister(&da9055_gpio_driver); +} +module_exit(da9055_gpio_exit); + +MODULE_AUTHOR("David Dajun Chen "); +MODULE_DESCRIPTION("DA9055 GPIO Device Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:da9055-gpio"); -- cgit v1.2.3 From a3b8d4a513574e6adf76bcacad21c95ee6b8ce4b Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Tue, 9 Oct 2012 20:05:56 +0400 Subject: GPIO: Add support for GPIO on CLPS711X-target platform The CLPS711X CPUs provide some GPIOs for use in the system. This driver provides support for these via gpiolib. Due to platform limitations, driver does not support interrupts, only inputs and outputs. Signed-off-by: Alexander Shiyan Acked-by: Russell King Signed-off-by: Linus Walleij --- arch/arm/Kconfig | 1 + arch/arm/mach-clps711x/include/mach/gpio.h | 13 +++ drivers/gpio/Kconfig | 4 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-clps711x.c | 163 +++++++++++++++++++++++++++++ 5 files changed, 182 insertions(+) create mode 100644 arch/arm/mach-clps711x/include/mach/gpio.h create mode 100644 drivers/gpio/gpio-clps711x.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 73067efd484..f456cf4ae3c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -364,6 +364,7 @@ config ARCH_CNS3XXX config ARCH_CLPS711X bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" + select ARCH_REQUIRE_GPIOLIB select ARCH_USES_GETTIMEOFFSET select CLKDEV_LOOKUP select COMMON_CLK diff --git a/arch/arm/mach-clps711x/include/mach/gpio.h b/arch/arm/mach-clps711x/include/mach/gpio.h new file mode 100644 index 00000000000..8ac6889fabc --- /dev/null +++ b/arch/arm/mach-clps711x/include/mach/gpio.h @@ -0,0 +1,13 @@ +/* + * This file contains the CLPS711X GPIO definitions. + * + * Copyright (C) 2012 Alexander Shiyan + * + * 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. + */ + +/* Simple helper for convert port & pin to GPIO number */ +#define CLPS711X_GPIO(port, bit) ((port) * 8 + (bit)) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 150eeb705fb..9e3fb343871 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -102,6 +102,10 @@ config GPIO_MAX730X comment "Memory mapped GPIO drivers:" +config GPIO_CLPS711X + def_bool y + depends on ARCH_CLPS711X + config GPIO_GENERIC_PLATFORM tristate "Generic memory-mapped GPIO controller support (MMIO platform device)" select GPIO_GENERIC diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index e6f8e379a2e..1c1b63fcaeb 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o +obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c new file mode 100644 index 00000000000..ea21822b3de --- /dev/null +++ b/drivers/gpio/gpio-clps711x.c @@ -0,0 +1,163 @@ +/* + * CLPS711X GPIO driver + * + * Copyright (C) 2012 Alexander Shiyan + * + * 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 +#include +#include +#include +#include +#include + +#include + +#define CLPS711X_GPIO_PORTS 5 +#define CLPS711X_GPIO_NAME "gpio-clps711x" + +struct clps711x_gpio { + struct gpio_chip chip[CLPS711X_GPIO_PORTS]; + spinlock_t lock; +}; + +static void __iomem *clps711x_ports[] = { + CLPS711X_VIRT_BASE + PADR, + CLPS711X_VIRT_BASE + PBDR, + CLPS711X_VIRT_BASE + PCDR, + CLPS711X_VIRT_BASE + PDDR, + CLPS711X_VIRT_BASE + PEDR, +}; + +static void __iomem *clps711x_pdirs[] = { + CLPS711X_VIRT_BASE + PADDR, + CLPS711X_VIRT_BASE + PBDDR, + CLPS711X_VIRT_BASE + PCDDR, + CLPS711X_VIRT_BASE + PDDDR, + CLPS711X_VIRT_BASE + PEDDR, +}; + +#define clps711x_port(x) clps711x_ports[x->base / 8] +#define clps711x_pdir(x) clps711x_pdirs[x->base / 8] + +static int gpio_clps711x_get(struct gpio_chip *chip, unsigned offset) +{ + return !!readb(clps711x_port(chip)) & (1 << offset); +} + +static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset, + int value) +{ + int tmp; + unsigned long flags; + struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); + + spin_lock_irqsave(&gpio->lock, flags); + tmp = readb(clps711x_port(chip)) & ~(1 << offset); + if (value) + tmp |= 1 << offset; + writeb(tmp, clps711x_port(chip)); + spin_unlock_irqrestore(&gpio->lock, flags); +} + +static int gpio_clps711x_direction_in(struct gpio_chip *chip, unsigned offset) +{ + int tmp; + unsigned long flags; + struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); + + spin_lock_irqsave(&gpio->lock, flags); + tmp = readb(clps711x_pdir(chip)) & ~(1 << offset); + writeb(tmp, clps711x_pdir(chip)); + spin_unlock_irqrestore(&gpio->lock, flags); + + return 0; +} + +static int gpio_clps711x_direction_out(struct gpio_chip *chip, unsigned offset, + int value) +{ + int tmp; + unsigned long flags; + struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); + + spin_lock_irqsave(&gpio->lock, flags); + tmp = readb(clps711x_pdir(chip)) | (1 << offset); + writeb(tmp, clps711x_pdir(chip)); + tmp = readb(clps711x_port(chip)) & ~(1 << offset); + if (value) + tmp |= 1 << offset; + writeb(tmp, clps711x_port(chip)); + spin_unlock_irqrestore(&gpio->lock, flags); + + return 0; +} + +struct clps711x_gpio_port { + char *name; + int nr; +}; + +static const struct clps711x_gpio_port clps711x_gpio_ports[] __initconst = { + { "PORTA", 8, }, + { "PORTB", 8, }, + { "PORTC", 8, }, + { "PORTD", 8, }, + { "PORTE", 3, }, +}; + +static int __init gpio_clps711x_init(void) +{ + int i; + struct platform_device *pdev; + struct clps711x_gpio *gpio; + + pdev = platform_device_alloc(CLPS711X_GPIO_NAME, 0); + if (!pdev) { + pr_err("Cannot create platform device: %s\n", + CLPS711X_GPIO_NAME); + return -ENOMEM; + } + + platform_device_add(pdev); + + gpio = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_gpio), + GFP_KERNEL); + if (!gpio) { + dev_err(&pdev->dev, "GPIO allocating memory error\n"); + platform_device_del(pdev); + platform_device_put(pdev); + return -ENOMEM; + } + + platform_set_drvdata(pdev, gpio); + + spin_lock_init(&gpio->lock); + + for (i = 0; i < CLPS711X_GPIO_PORTS; i++) { + gpio->chip[i].owner = THIS_MODULE; + gpio->chip[i].dev = &pdev->dev; + gpio->chip[i].label = clps711x_gpio_ports[i].name; + gpio->chip[i].base = i * 8; + gpio->chip[i].ngpio = clps711x_gpio_ports[i].nr; + gpio->chip[i].direction_input = gpio_clps711x_direction_in; + gpio->chip[i].get = gpio_clps711x_get; + gpio->chip[i].direction_output = gpio_clps711x_direction_out; + gpio->chip[i].set = gpio_clps711x_set; + WARN_ON(gpiochip_add(&gpio->chip[i])); + } + + dev_info(&pdev->dev, "GPIO driver initialized\n"); + + return 0; +} +arch_initcall(gpio_clps711x_init); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Alexander Shiyan "); +MODULE_DESCRIPTION("CLPS711X GPIO driver"); -- cgit v1.2.3 From a6d7092a3460ebb32a63d691c5c3a1ff2a656424 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 15 Oct 2012 22:32:37 +0200 Subject: gpio: clps711x: delete local header This header file is unused and we shall not add new headers to the namespace. The macro may be reintroduced when there is a user for it. Cc: Alexander Shiyan Cc: Arnd Bergmann Cc: Russell King Signed-off-by: Linus Walleij --- arch/arm/mach-clps711x/include/mach/gpio.h | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 arch/arm/mach-clps711x/include/mach/gpio.h diff --git a/arch/arm/mach-clps711x/include/mach/gpio.h b/arch/arm/mach-clps711x/include/mach/gpio.h deleted file mode 100644 index 8ac6889fabc..00000000000 --- a/arch/arm/mach-clps711x/include/mach/gpio.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * This file contains the CLPS711X GPIO definitions. - * - * Copyright (C) 2012 Alexander Shiyan - * - * 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. - */ - -/* Simple helper for convert port & pin to GPIO number */ -#define CLPS711X_GPIO(port, bit) ((port) * 8 + (bit)) -- cgit v1.2.3 From 8ed92e51f99c2199c64cb33b4ba95ab12940a94c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Oct 2012 14:28:50 +0200 Subject: sched: Add WAKEUP_PREEMPTION feature flag, on by default As per the recent discussion with Mike and Linus, make it easier to test with/without this feature. No change in default behavior. Signed-off-by: Ingo Molnar Cc: Peter Zijlstra Cc: Mike Galbraith Cc: Linus Torvalds Link: http://lkml.kernel.org/n/tip-izoxq4haeg4mTognnDbwcevt@git.kernel.org --- kernel/sched/fair.c | 2 +- kernel/sched/features.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 6b800a14b99..f936552b3db 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2907,7 +2907,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_ * Batch and idle tasks do not preempt non-idle tasks (their preemption * is driven by the tick): */ - if (unlikely(p->policy != SCHED_NORMAL)) + if (unlikely(p->policy != SCHED_NORMAL) || !sched_feat(WAKEUP_PREEMPTION)) return; find_matching_se(&se, &pse); diff --git a/kernel/sched/features.h b/kernel/sched/features.h index eebefcad702..e68e69ab917 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h @@ -31,6 +31,11 @@ SCHED_FEAT(LAST_BUDDY, true) */ SCHED_FEAT(CACHE_HOT_BUDDY, true) +/* + * Allow wakeup-time preemption of the current task: + */ +SCHED_FEAT(WAKEUP_PREEMPTION, true) + /* * Use arch dependent cpu power functions */ -- cgit v1.2.3 From 8355b0208a44904741dbd78fea6f203c3556699a Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 15 Oct 2012 12:16:36 -0600 Subject: usb: phy: tegra remove include of Almost nothing from this file is used, and the file will hopefully be deleted soon. Copy the tiny portions that are used directly into tegra_usb_phy.c. I believe that Venu Byravarasu is working on cleaning up our USB driver, and those cleanups will remove the need for these constants. Signed-off-by: Stephen Warren Acked-by: Venu Byravarasu Signed-off-by: Felipe Balbi --- drivers/usb/phy/tegra_usb_phy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/phy/tegra_usb_phy.c b/drivers/usb/phy/tegra_usb_phy.c index 987116f9efc..9d13c81754e 100644 --- a/drivers/usb/phy/tegra_usb_phy.c +++ b/drivers/usb/phy/tegra_usb_phy.c @@ -29,7 +29,9 @@ #include #include #include -#include + +#define TEGRA_USB_BASE 0xC5000000 +#define TEGRA_USB_SIZE SZ_16K #define ULPI_VIEWPORT 0x170 -- cgit v1.2.3 From ca21dda64b756d6fe965dfe8fd0a1f320874b4b5 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 10 Oct 2012 19:37:28 +0100 Subject: usb: phy: mv_otg: use module_platform_driver macro This patch removes some code duplication by using module_platform_driver. Signed-off-by: Srinivas Kandagatla Signed-off-by: Felipe Balbi --- drivers/usb/otg/mv_otg.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/usb/otg/mv_otg.c b/drivers/usb/otg/mv_otg.c index 3f124e8f579..1dd57504186 100644 --- a/drivers/usb/otg/mv_otg.c +++ b/drivers/usb/otg/mv_otg.c @@ -958,16 +958,4 @@ static struct platform_driver mv_otg_driver = { .resume = mv_otg_resume, #endif }; - -static int __init mv_otg_init(void) -{ - return platform_driver_register(&mv_otg_driver); -} - -static void __exit mv_otg_exit(void) -{ - platform_driver_unregister(&mv_otg_driver); -} - -module_init(mv_otg_init); -module_exit(mv_otg_exit); +module_platform_driver(mv_otg_driver); -- cgit v1.2.3 From 4cd2f5998757a41038deb55a0cb8319bdf67575a Mon Sep 17 00:00:00 2001 From: "kuninori.morimoto.gx@renesas.com" Date: Mon, 15 Oct 2012 23:24:19 -0700 Subject: usb: renesas_usbhs: gadget: add usb_gadget_ops :: pullup support This patch adds usbhs_sys_function_pullup() to control D+ line for USB function, and enabled pullup support on mod_gadget. Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/common.c | 5 +++++ drivers/usb/renesas_usbhs/common.h | 1 + drivers/usb/renesas_usbhs/mod_gadget.c | 11 +++++++++++ 3 files changed, 17 insertions(+) diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 072edc1cc55..3bf922ab045 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -132,6 +132,11 @@ void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable) usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); } +void usbhs_sys_function_pullup(struct usbhs_priv *priv, int enable) +{ + usbhs_bset(priv, SYSCFG, DPRPU, enable ? DPRPU : 0); +} + void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode) { usbhs_write(priv, TESTMODE, mode); diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index dddf40a59de..c69dd2fba36 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -285,6 +285,7 @@ void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data); */ void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable); void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable); +void usbhs_sys_function_pullup(struct usbhs_priv *priv, int enable); void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode); /* diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 28478ce26c3..dd41f61893e 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -883,6 +883,16 @@ static int usbhsg_get_frame(struct usb_gadget *gadget) return usbhs_frame_get_num(priv); } +static int usbhsg_pullup(struct usb_gadget *gadget, int is_on) +{ + struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); + struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); + + usbhs_sys_function_pullup(priv, is_on); + + return 0; +} + static int usbhsg_set_selfpowered(struct usb_gadget *gadget, int is_self) { struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); @@ -900,6 +910,7 @@ static struct usb_gadget_ops usbhsg_gadget_ops = { .set_selfpowered = usbhsg_set_selfpowered, .udc_start = usbhsg_gadget_start, .udc_stop = usbhsg_gadget_stop, + .pullup = usbhsg_pullup, }; static int usbhsg_start(struct usbhs_priv *priv) -- cgit v1.2.3 From 0696f92970abeb5586eb11cabd2a41909b4dee71 Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Mon, 15 Oct 2012 09:47:36 -0300 Subject: usb: gadget: lpc32xx_udc: Disable setup request error This message is an debugging message. It's useful for finding protocol details but it's not necessarily an error. Acked-by: Roland Stigge Signed-off-by: Alexandre Pereira da Silva Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index f696fb9b136..ba18b479d9f 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -2399,7 +2399,7 @@ static void udc_handle_ep0_setup(struct lpc32xx_udc *udc) if (i < 0) { /* setup processing failed, force stall */ - dev_err(udc->dev, + dev_dbg(udc->dev, "req %02x.%02x protocol STALL; stat %d\n", reqtype, req, i); udc->ep0state = WAIT_FOR_SETUP; -- cgit v1.2.3 From 6f115e45a09846ae84154735e6215622e2e8e535 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 22 May 2012 14:02:26 +0300 Subject: usb: dwc3: drop HAVE_CLK dependency from Exynos glue layer commit 93abe8e (clk: add non CONFIG_HAVE_CLK routines) added clk API stubs when !defined(CONFIG_HAVE_CLK). This allows us to remove the HAVE_CLK dependency from Exynos' glue layer and let it compile always. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/Makefile | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index d441fe4c180..4502648b817 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -27,19 +27,7 @@ endif ## obj-$(CONFIG_USB_DWC3) += dwc3-omap.o - -## -# REVISIT Samsung Exynos platform needs the clk API which isn't -# defined on all architectures. If we allow dwc3-exynos.c compile -# always we will fail the linking phase on those architectures -# which don't provide clk api implementation and that's unnaceptable. -# -# When Samsung's platform start supporting pm_runtime, this check -# for HAVE_CLK should be removed. -## -ifneq ($(CONFIG_HAVE_CLK),) - obj-$(CONFIG_USB_DWC3) += dwc3-exynos.o -endif +obj-$(CONFIG_USB_DWC3) += dwc3-exynos.o ifneq ($(CONFIG_PCI),) obj-$(CONFIG_USB_DWC3) += dwc3-pci.o -- cgit v1.2.3 From 67a0d4993d85ee2f42c9909127794553df69dd59 Mon Sep 17 00:00:00 2001 From: Tony Prisk Date: Thu, 18 Oct 2012 07:18:13 +1300 Subject: GPIO: vt8500: Add extended gpio bank for WM8505/WM8650 These SoC's have an extended bank of GPIO's seperate to the main GPIO block. This patch adds the additional 5 GPIO's located in this block which control I2C and PWMOUT. Signed-off-by: Tony Prisk Signed-off-by: Linus Walleij --- drivers/gpio/gpio-vt8500.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpio/gpio-vt8500.c b/drivers/gpio/gpio-vt8500.c index bcd8e4aa7c7..9ed2a2b347f 100644 --- a/drivers/gpio/gpio-vt8500.c +++ b/drivers/gpio/gpio-vt8500.c @@ -96,6 +96,7 @@ static struct vt8500_gpio_data wm8505_data = { VT8500_BANK(0x5C, 0x84, 0xAC, 0xD4, 12), VT8500_BANK(0x60, 0x88, 0xB0, 0xD8, 16), VT8500_BANK(0x64, 0x8C, 0xB4, 0xDC, 22), + VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6), }, }; @@ -115,6 +116,7 @@ static struct vt8500_gpio_data wm8650_data = { VT8500_BANK(0x58, 0x98, 0xD8, 0x18, 32), VT8500_BANK(0x5C, 0x9C, 0xDC, 0x1C, 32), VT8500_BANK(0x7C, 0xBC, 0xFC, 0x3C, 32), + VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6), }, }; -- cgit v1.2.3 From 73327b4c80713da3a854fb04ef7e9739fe006709 Mon Sep 17 00:00:00 2001 From: Peter Senna Tschudin Date: Fri, 28 Sep 2012 10:57:00 +0100 Subject: drivers/staging/iio: Remove unnecessary semicolon A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r1@ statement S; position p,p1; @@ S@p1;@p @script:python r2@ p << r1.p; p1 << r1.p1; @@ if p[0].line != p1[0].line_end: cocci.include_match(False) @@ position r1.p; @@ -;@p // Signed-off-by: Peter Senna Tschudin Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/adis16201_core.c | 4 ++-- drivers/staging/iio/accel/adis16204_core.c | 2 +- drivers/staging/iio/accel/adis16209_core.c | 4 ++-- drivers/staging/iio/accel/kxsd9.c | 2 +- drivers/staging/iio/adc/mxs-lradc.c | 2 +- drivers/staging/iio/cdc/ad7150.c | 12 ++++++------ drivers/staging/iio/cdc/ad7152.c | 2 +- drivers/staging/iio/cdc/ad7746.c | 2 +- drivers/staging/iio/gyro/adis16260_core.c | 4 ++-- drivers/staging/iio/magnetometer/hmc5843.c | 2 +- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 8e37d6e0427..5d2ae5dc380 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -345,7 +345,7 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, break; default: return -EINVAL; - }; + } mutex_lock(&indio_dev->mlock); addr = adis16201_addresses[chan->address][1]; ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16); @@ -382,7 +382,7 @@ static int adis16201_write_raw(struct iio_dev *indio_dev, break; default: return -EINVAL; - }; + } val16 = val & ((1 << bits) - 1); addr = adis16201_addresses[chan->address][1]; return adis16201_spi_write_reg_16(indio_dev, addr, val16); diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 05bdb7c2c8e..c6bf6419743 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -389,7 +389,7 @@ static int adis16204_write_raw(struct iio_dev *indio_dev, break; default: return -EINVAL; - }; + } val16 = val & ((1 << bits) - 1); addr = adis16204_addresses[chan->address][1]; return adis16204_spi_write_reg_16(indio_dev, addr, val16); diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index b7333bfe0b2..4f70efd4ed9 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -295,7 +295,7 @@ static int adis16209_write_raw(struct iio_dev *indio_dev, break; default: return -EINVAL; - }; + } val16 = val & ((1 << bits) - 1); addr = adis16209_addresses[chan->address][1]; return adis16209_spi_write_reg_16(indio_dev, addr, val16); @@ -373,7 +373,7 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, break; default: return -EINVAL; - }; + } mutex_lock(&indio_dev->mlock); addr = adis16209_addresses[chan->address][1]; ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16); diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index fdd5fbded66..e8e6e3fbcec 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -171,7 +171,7 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev, *val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK]; ret = IIO_VAL_INT_PLUS_MICRO; break; - }; + } error_ret: return ret; diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index ca7c1fa88e7..df5bba284b7 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -351,7 +351,7 @@ static int mxs_lradc_buffer_preenable(struct iio_dev *iio) writel(chan_value, lradc->base + LRADC_CH(ofs)); enable |= 1 << ofs; ofs++; - }; + } writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK, lradc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR); diff --git a/drivers/staging/iio/cdc/ad7150.c b/drivers/staging/iio/cdc/ad7150.c index 6a4041417d4..c72a6c074b4 100644 --- a/drivers/staging/iio/cdc/ad7150.c +++ b/drivers/staging/iio/cdc/ad7150.c @@ -156,7 +156,7 @@ static int ad7150_read_event_config(struct iio_dev *indio_dev, u64 event_code) return !adaptive && (threshtype == 0x1); else return !adaptive && (threshtype == 0x0); - }; + } return -EINVAL; } @@ -194,7 +194,7 @@ static int ad7150_write_event_params(struct iio_dev *indio_dev, u64 event_code) break; default: return -EINVAL; - }; + } ret = i2c_smbus_write_byte_data(chip->client, ad7150_addresses[chan][4], sens); @@ -257,7 +257,7 @@ static int ad7150_write_event_config(struct iio_dev *indio_dev, default: ret = -EINVAL; goto error_ret; - }; + } cfg |= (!adaptive << 7) | (thresh_type << 5); @@ -327,7 +327,7 @@ static int ad7150_write_event_value(struct iio_dev *indio_dev, default: ret = -EINVAL; goto error_ret; - }; + } /* write back if active */ ret = ad7150_write_event_params(indio_dev, event_code); @@ -360,7 +360,7 @@ static ssize_t ad7150_show_timeout(struct device *dev, break; default: return -EINVAL; - }; + } return sprintf(buf, "%d\n", value); } @@ -394,7 +394,7 @@ static ssize_t ad7150_store_timeout(struct device *dev, default: ret = -EINVAL; goto error_ret; - }; + } ret = ad7150_write_event_params(indio_dev, this_attr->address); error_ret: diff --git a/drivers/staging/iio/cdc/ad7152.c b/drivers/staging/iio/cdc/ad7152.c index 98c3015116a..288b33e8dad 100644 --- a/drivers/staging/iio/cdc/ad7152.c +++ b/drivers/staging/iio/cdc/ad7152.c @@ -405,7 +405,7 @@ static int ad7152_read_raw(struct iio_dev *indio_dev, break; default: ret = -EINVAL; - }; + } out: mutex_unlock(&indio_dev->mlock); return ret; diff --git a/drivers/staging/iio/cdc/ad7746.c b/drivers/staging/iio/cdc/ad7746.c index 754e11e8719..e6c11d934ad 100644 --- a/drivers/staging/iio/cdc/ad7746.c +++ b/drivers/staging/iio/cdc/ad7746.c @@ -677,7 +677,7 @@ static int ad7746_read_raw(struct iio_dev *indio_dev, break; default: ret = -EINVAL; - }; + } out: mutex_unlock(&indio_dev->mlock); return ret; diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 9571c03aa4c..ff16430a0d2 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -528,7 +528,7 @@ static int adis16260_read_raw(struct iio_dev *indio_dev, break; default: return -EINVAL; - }; + } mutex_lock(&indio_dev->mlock); addr = adis16260_addresses[chan->address][1]; ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16); @@ -548,7 +548,7 @@ static int adis16260_read_raw(struct iio_dev *indio_dev, break; default: return -EINVAL; - }; + } mutex_lock(&indio_dev->mlock); addr = adis16260_addresses[chan->address][2]; ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16); diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index 10e095486e5..f7edf69a3bc 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -555,7 +555,7 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev, *val = 0; *val2 = data->variant->regval_to_nanoscale[data->range]; return IIO_VAL_INT_PLUS_NANO; - }; + } return -EINVAL; } -- cgit v1.2.3 From e1562ef30438d4850e3f4ea0fc5711ea658a1f69 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sat, 13 Oct 2012 09:06:00 +0100 Subject: iio: remove useless irq_enabled variable in at91 irq_enabled is only set, but never read Signed-off-by: Peter Meerwald Acked-by: Maxime Ripard Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91_adc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 3ed94bf8059..b3ba8af4f26 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -46,7 +46,6 @@ struct at91_adc_state { struct clk *clk; bool done; int irq; - bool irq_enabled; u16 last_value; struct mutex lock; u8 num_channels; @@ -85,7 +84,6 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) buffer->access->store_to(buffer, (u8 *)st->buffer); iio_trigger_notify_done(idev->trig); - st->irq_enabled = true; /* Needed to ACK the DRDY interruption */ at91_adc_readl(st, AT91_ADC_LCDR); @@ -106,7 +104,6 @@ static irqreturn_t at91_adc_eoc_trigger(int irq, void *private) if (iio_buffer_enabled(idev)) { disable_irq_nosync(irq); - st->irq_enabled = false; iio_trigger_poll(idev->trig, iio_get_time_ns()); } else { st->last_value = at91_adc_readl(st, AT91_ADC_LCDR); -- cgit v1.2.3 From 1217c48f51704d01019581cb1baa1b9124eaa0a7 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sat, 13 Oct 2012 09:06:00 +0100 Subject: iio: use iio_push_to_buffer() in at91 driver Signed-off-by: Peter Meerwald Acked-by: Maxime Ripard Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index b3ba8af4f26..2e2c9a80aa3 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -81,7 +81,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) *timestamp = pf->timestamp; } - buffer->access->store_to(buffer, (u8 *)st->buffer); + iio_push_to_buffer(buffer, st->buffer); iio_trigger_notify_done(idev->trig); -- cgit v1.2.3 From ace43fcefb1f7078cc19ab07df9d877eefffa57f Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sat, 13 Oct 2012 09:06:00 +0100 Subject: iio: fix spelling of Accelerometer in Kconfig Signed-off-by: Peter Meerwald Acked-by: Srinivas pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/accel/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index b2510c4d9a5..fe4bcd7c5b1 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -8,7 +8,7 @@ config HID_SENSOR_ACCEL_3D select IIO_BUFFER select IIO_TRIGGERED_BUFFER select HID_SENSOR_IIO_COMMON - tristate "HID Acelerometers 3D" + tristate "HID Accelerometers 3D" help Say yes here to build support for the HID SENSOR accelerometers 3D. -- cgit v1.2.3 From 231a7c5f5f9c95803dc84b1b311204ef55f7d8f6 Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sat, 13 Oct 2012 09:06:00 +0100 Subject: staging iio: use iio_trigger_generic_data_rdy_poll() in accel/adis16209,adis16240 driver Signed-off-by: Peter Meerwald Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/adis16209_trigger.c | 11 +---------- drivers/staging/iio/accel/adis16240_trigger.c | 11 +---------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c index 2ad93dcaf40..112280346eb 100644 --- a/drivers/staging/iio/accel/adis16209_trigger.c +++ b/drivers/staging/iio/accel/adis16209_trigger.c @@ -7,15 +7,6 @@ #include #include "adis16209.h" -/** - * adis16209_data_rdy_trig_poll() the event handler for the data rdy trig - **/ -static irqreturn_t adis16209_data_rdy_trig_poll(int irq, void *trig) -{ - iio_trigger_poll(trig, iio_get_time_ns()); - return IRQ_HANDLED; -} - /** * adis16209_data_rdy_trigger_set_state() set datardy interrupt state **/ @@ -45,7 +36,7 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev) } ret = request_irq(st->us->irq, - adis16209_data_rdy_trig_poll, + iio_trigger_generic_data_rdy_poll, IRQF_TRIGGER_RISING, "adis16209", st->trig); diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c index fa90a22b143..f3caf09dcb8 100644 --- a/drivers/staging/iio/accel/adis16240_trigger.c +++ b/drivers/staging/iio/accel/adis16240_trigger.c @@ -7,15 +7,6 @@ #include #include "adis16240.h" -/** - * adis16240_data_rdy_trig_poll() the event handler for the data rdy trig - **/ -static irqreturn_t adis16240_data_rdy_trig_poll(int irq, void *trig) -{ - iio_trigger_poll(trig, iio_get_time_ns()); - return IRQ_HANDLED; -} - /** * adis16240_data_rdy_trigger_set_state() set datardy interrupt state **/ @@ -45,7 +36,7 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev) } ret = request_irq(st->us->irq, - adis16240_data_rdy_trig_poll, + iio_trigger_generic_data_rdy_poll, IRQF_TRIGGER_RISING, "adis16240", st->trig); -- cgit v1.2.3 From 48edf8eb53daf98b1fc4498ac54b27c08b955248 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 4 Oct 2012 14:33:00 +0100 Subject: staging:iio: Remove unused DRIVER_NAME defines Some drivers define a DRIVER_NAME, but never use the define. This patch removes defines. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/adis16203_core.c | 2 -- drivers/staging/iio/accel/adis16204_core.c | 2 -- drivers/staging/iio/accel/adis16209_core.c | 2 -- drivers/staging/iio/accel/adis16220_core.c | 2 -- drivers/staging/iio/accel/adis16240_core.c | 2 -- drivers/staging/iio/gyro/adis16260_core.c | 2 -- drivers/staging/iio/meter/ade7753.h | 2 -- drivers/staging/iio/meter/ade7754.h | 2 -- drivers/staging/iio/meter/ade7758.h | 3 --- drivers/staging/iio/meter/ade7759.h | 2 -- drivers/staging/iio/meter/ade7854.h | 2 -- 11 files changed, 23 deletions(-) diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 002fa9dfc37..2064710a6b8 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -21,8 +21,6 @@ #include "adis16203.h" -#define DRIVER_NAME "adis16203" - /** * adis16203_spi_write_reg_8() - write single byte to a register * @indio_dev: iio device associated with child of actual device diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index c6bf6419743..d0828d97f50 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -24,8 +24,6 @@ #include "adis16204.h" -#define DRIVER_NAME "adis16204" - /** * adis16204_spi_write_reg_8() - write single byte to a register * @dev: device associated with child of actual device (iio_dev or iio_trig) diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index 4f70efd4ed9..420256e2e61 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -22,8 +22,6 @@ #include "adis16209.h" -#define DRIVER_NAME "adis16209" - /** * adis16209_spi_write_reg_8() - write single byte to a register * @indio_dev: iio device associated with actual device diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index c755089c711..adf70b7d032 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -20,8 +20,6 @@ #include "adis16220.h" -#define DRIVER_NAME "adis16220" - /** * adis16220_spi_write_reg_8() - write single byte to a register * @indio_dev: iio device associated with child of actual device diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 0fc26a49d68..9f486114ed5 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -25,8 +25,6 @@ #include "adis16240.h" -#define DRIVER_NAME "adis16240" - static int adis16240_check_status(struct iio_dev *indio_dev); /** diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index ff16430a0d2..2753333a02b 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -24,8 +24,6 @@ #include "adis16260.h" -#define DRIVER_NAME "adis16260" - static int adis16260_check_status(struct iio_dev *indio_dev); /** diff --git a/drivers/staging/iio/meter/ade7753.h b/drivers/staging/iio/meter/ade7753.h index 3f059d3d939..a9d93cc1c41 100644 --- a/drivers/staging/iio/meter/ade7753.h +++ b/drivers/staging/iio/meter/ade7753.h @@ -55,8 +55,6 @@ #define ADE7753_SPI_BURST (u32)(1000 * 1000) #define ADE7753_SPI_FAST (u32)(2000 * 1000) -#define DRIVER_NAME "ade7753" - /** * struct ade7753_state - device instance specific data * @us: actual spi_device diff --git a/drivers/staging/iio/meter/ade7754.h b/drivers/staging/iio/meter/ade7754.h index 6121125520f..e42ffc387a1 100644 --- a/drivers/staging/iio/meter/ade7754.h +++ b/drivers/staging/iio/meter/ade7754.h @@ -73,8 +73,6 @@ #define ADE7754_SPI_BURST (u32)(1000 * 1000) #define ADE7754_SPI_FAST (u32)(2000 * 1000) -#define DRIVER_NAME "ade7754" - /** * struct ade7754_state - device instance specific data * @us: actual spi_device diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h index 1e11ad5ae5a..07318203a83 100644 --- a/drivers/staging/iio/meter/ade7758.h +++ b/drivers/staging/iio/meter/ade7758.h @@ -105,9 +105,6 @@ #define AD7758_APP_PWR 4 #define AD7758_WT(p, w) (((w) << 2) | (p)) -#define DRIVER_NAME "ade7758" - - /** * struct ade7758_state - device instance specific data * @us: actual spi_device diff --git a/drivers/staging/iio/meter/ade7759.h b/drivers/staging/iio/meter/ade7759.h index c81d23d730d..f9ff1f8e737 100644 --- a/drivers/staging/iio/meter/ade7759.h +++ b/drivers/staging/iio/meter/ade7759.h @@ -36,8 +36,6 @@ #define ADE7759_SPI_BURST (u32)(1000 * 1000) #define ADE7759_SPI_FAST (u32)(2000 * 1000) -#define DRIVER_NAME "ade7759" - /** * struct ade7759_state - device instance specific data * @us: actual spi_device diff --git a/drivers/staging/iio/meter/ade7854.h b/drivers/staging/iio/meter/ade7854.h index 2c96e8695d5..06534577f6c 100644 --- a/drivers/staging/iio/meter/ade7854.h +++ b/drivers/staging/iio/meter/ade7854.h @@ -142,8 +142,6 @@ #define ADE7854_SPI_BURST (u32)(1000 * 1000) #define ADE7854_SPI_FAST (u32)(2000 * 1000) -#define DRIVER_NAME "ade7854" - /** * struct ade7854_state - device instance specific data * @spi: actual spi_device -- cgit v1.2.3 From 65cb587d7058441c8c910e8766ee86538c7274d8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 28 Sep 2012 22:36:00 +0100 Subject: staging/iio/lis3l02dq: fix building without irq_to_gpio The driver has not been building for some time after the irq_to_gpio function has been removed from the kernel. The only board in the upstream kernel that provides this device is the "Stargate 2", which is also maintained by Jonathan Cameron. Rather than working around the problem by adding new platform data for this driver, this patch uses the of_gpio framework to get to the gpio number. However, the stargate2 code does not (yet) use DT based probing, so it is still broken, but at least building allyesconfig works again. Signed-off-by: Arnd Bergmann Cc: Lars-Peter Clausen Cc: Jonathan Cameron Cc: Greg Kroah-Hartman Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/lis3l02dq.h | 1 + drivers/staging/iio/accel/lis3l02dq_core.c | 10 ++++++---- drivers/staging/iio/accel/lis3l02dq_ring.c | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/staging/iio/accel/lis3l02dq.h b/drivers/staging/iio/accel/lis3l02dq.h index f9bcd41f718..2bac7221837 100644 --- a/drivers/staging/iio/accel/lis3l02dq.h +++ b/drivers/staging/iio/accel/lis3l02dq.h @@ -158,6 +158,7 @@ struct lis3l02dq_state { struct spi_device *us; struct iio_trigger *trig; struct mutex buf_lock; + int gpio; bool trigger_on; u8 tx[LIS3L02DQ_MAX_RX] ____cacheline_aligned; diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 21b0469f8bc..d13c7e98978 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -690,6 +691,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) spi_set_drvdata(spi, indio_dev); st->us = spi; + st->gpio = of_get_gpio(spi->dev.of_node, 0); mutex_init(&st->buf_lock); indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; @@ -711,7 +713,7 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) goto error_unreg_buffer_funcs; } - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { + if (spi->irq) { ret = request_threaded_irq(st->us->irq, &lis3l02dq_th, &lis3l02dq_event_handler, @@ -738,10 +740,10 @@ static int __devinit lis3l02dq_probe(struct spi_device *spi) return 0; error_remove_trigger: - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq))) + if (spi->irq) lis3l02dq_remove_trigger(indio_dev); error_free_interrupt: - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + if (spi->irq) free_irq(st->us->irq, indio_dev); error_uninitialize_buffer: iio_buffer_unregister(indio_dev); @@ -790,7 +792,7 @@ static int __devexit lis3l02dq_remove(struct spi_device *spi) lis3l02dq_disable_all_events(indio_dev); lis3l02dq_stop_device(indio_dev); - if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + if (spi->irq) free_irq(st->us->irq, indio_dev); lis3l02dq_remove_trigger(indio_dev); diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index fa4190d9624..13c0b4bd5ba 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -263,7 +263,7 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig) /* If gpio still high (or high again) * In theory possible we will need to do this several times */ for (i = 0; i < 5; i++) - if (gpio_get_value(irq_to_gpio(st->us->irq))) + if (gpio_get_value(st->gpio)) lis3l02dq_read_all(indio_dev, NULL); else break; -- cgit v1.2.3 From cdf71c7f6d6208cea8dd83c78b49a9a646e3208e Mon Sep 17 00:00:00 2001 From: Peter Meerwald Date: Sun, 30 Sep 2012 11:05:00 +0100 Subject: staging iio: consistent commas in adis16400 channel spec probably not the most important patch in the world Signed-off-by: Peter Meerwald Cc: manuel.stahl@iis.fraunhofer.de Signed-off-by: Jonathan Cameron --- drivers/staging/iio/imu/adis16400_core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index b302c9ba271..5eab327a09d 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -622,7 +622,7 @@ static const struct iio_chan_spec adis16400_channels[] = { IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16400_SCAN_SUPPLY, - .scan_type = IIO_ST('u', 14, 16, 0) + .scan_type = IIO_ST('u', 14, 16, 0), }, { .type = IIO_ANGL_VEL, .modified = 1, @@ -633,7 +633,7 @@ static const struct iio_chan_spec adis16400_channels[] = { IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_x, .scan_index = ADIS16400_SCAN_GYRO_X, - .scan_type = IIO_ST('s', 14, 16, 0) + .scan_type = IIO_ST('s', 14, 16, 0), }, { .type = IIO_ANGL_VEL, .modified = 1, @@ -752,7 +752,7 @@ static const struct iio_chan_spec adis16350_channels[] = { IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16400_SCAN_SUPPLY, - .scan_type = IIO_ST('u', 12, 16, 0) + .scan_type = IIO_ST('u', 12, 16, 0), }, { .type = IIO_ANGL_VEL, .modified = 1, @@ -763,7 +763,7 @@ static const struct iio_chan_spec adis16350_channels[] = { IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, .address = gyro_x, .scan_index = ADIS16400_SCAN_GYRO_X, - .scan_type = IIO_ST('s', 14, 16, 0) + .scan_type = IIO_ST('s', 14, 16, 0), }, { .type = IIO_ANGL_VEL, .modified = 1, @@ -877,7 +877,7 @@ static const struct iio_chan_spec adis16300_channels[] = { IIO_CHAN_INFO_SCALE_SEPARATE_BIT, .address = in_supply, .scan_index = ADIS16400_SCAN_SUPPLY, - .scan_type = IIO_ST('u', 12, 16, 0) + .scan_type = IIO_ST('u', 12, 16, 0), }, { .type = IIO_ANGL_VEL, .modified = 1, -- cgit v1.2.3 From 6fae58f39207d03ae78b0b03347810d0f8452ab6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 18 Oct 2012 15:43:00 +0100 Subject: staging:iio: Don't compare boolean values with true/false Fixes the following coccicheck warnings: drivers/staging/iio/accel/lis3l02dq_ring.c:240:5-10: WARNING: Comparison to bool drivers/staging/iio/iio_dummy_evgen.c:111:6-25: WARNING: Comparison to bool Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/lis3l02dq_ring.c | 2 +- drivers/staging/iio/iio_dummy_evgen.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 13c0b4bd5ba..24635271653 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -237,7 +237,7 @@ static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig, u8 t; __lis3l02dq_write_data_ready_config(indio_dev, state); - if (state == false) { + if (!state) { /* * A possible quirk with the handler is currently worked around * by ensuring outstanding read events are cleared. diff --git a/drivers/staging/iio/iio_dummy_evgen.c b/drivers/staging/iio/iio_dummy_evgen.c index 74e24e8aa87..132d278c501 100644 --- a/drivers/staging/iio/iio_dummy_evgen.c +++ b/drivers/staging/iio/iio_dummy_evgen.c @@ -108,7 +108,7 @@ int iio_dummy_evgen_get_irq(void) mutex_lock(&iio_evgen->lock); for (i = 0; i < IIO_EVENTGEN_NO; i++) - if (iio_evgen->inuse[i] == false) { + if (!iio_evgen->inuse[i]) { ret = iio_evgen->base + i; iio_evgen->inuse[i] = true; break; -- cgit v1.2.3 From 6c724cb0ad772ae43928467f0a44731848eb22b2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 18 Oct 2012 15:43:00 +0100 Subject: staging:iio:lpc32xx_adc: Use resource_size instead of opencoding it Fixes the following error from coccicheck: drivers/staging/iio/adc/lpc32xx_adc.c:153:43-46: ERROR: Missing resource_size with res Signed-off-by: Lars-Peter Clausen Acked-by: Roland Stigge Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/lpc32xx_adc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/lpc32xx_adc.c b/drivers/staging/iio/adc/lpc32xx_adc.c index 7e9bd0001cc..10c59622671 100644 --- a/drivers/staging/iio/adc/lpc32xx_adc.c +++ b/drivers/staging/iio/adc/lpc32xx_adc.c @@ -150,7 +150,7 @@ static int __devinit lpc32xx_adc_probe(struct platform_device *pdev) info = iio_priv(iodev); - info->adc_base = ioremap(res->start, res->end - res->start + 1); + info->adc_base = ioremap(res->start, resource_size(res)); if (!info->adc_base) { dev_err(&pdev->dev, "failed mapping memory\n"); retval = -EBUSY; -- cgit v1.2.3 From 7737fa6d1ea3385428bd36a0dddcb33c526f7d74 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 18 Oct 2012 15:43:00 +0100 Subject: iio: Don't compare boolean values to true/false Fixes the following warnings from coccicheck: drivers/iio/inkern.c:81:6-14: WARNING: Comparison to bool drivers/iio/dac/ad5686.c:191:5-11: WARNING: Comparison to bool Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5686.c | 2 +- drivers/iio/inkern.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/dac/ad5686.c b/drivers/iio/dac/ad5686.c index 6948d75e103..bc92ff9309c 100644 --- a/drivers/iio/dac/ad5686.c +++ b/drivers/iio/dac/ad5686.c @@ -188,7 +188,7 @@ static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev, if (ret) return ret; - if (readin == true) + if (readin) st->pwr_down_mask |= (0x3 << (chan->channel * 2)); else st->pwr_down_mask &= ~(0x3 << (chan->channel * 2)); diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index f2b78d4fe45..5230a33886c 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -78,7 +78,7 @@ int iio_map_array_unregister(struct iio_dev *indio_dev, found_it = true; break; } - if (found_it == false) { + if (!found_it) { ret = -ENODEV; goto error_ret; } -- cgit v1.2.3 From 45259859492812c8b700ae1d157be01a8d2babfe Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 18 Oct 2012 15:43:00 +0100 Subject: iio: at91_adc: Use devm_kcalloc to allocate arrays Use dev_kcalloc instead of devm_kzalloc to allocate arrays since it is semantically more appropriate. While we are at it the patch also fixes the following coccinelle warning: drivers/iio/adc/at91_adc.c:277:25-31: ERROR: application of sizeof to pointer Signed-off-by: Lars-Peter Clausen Acked-By: Maxime Ripard Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91_adc.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 2e2c9a80aa3..a9176722042 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -123,10 +123,8 @@ static int at91_adc_channel_init(struct iio_dev *idev) idev->num_channels = bitmap_weight(&st->channels_mask, st->num_channels) + 1; - chan_array = devm_kzalloc(&idev->dev, - ((idev->num_channels + 1) * - sizeof(struct iio_chan_spec)), - GFP_KERNEL); + chan_array = devm_kcalloc(&idev->dev, idev->num_channels + 1, + sizeof(*chan_array), GFP_KERNEL); if (!chan_array) return -ENOMEM; @@ -270,9 +268,8 @@ static int at91_adc_trigger_init(struct iio_dev *idev) struct at91_adc_state *st = iio_priv(idev); int i, ret; - st->trig = devm_kzalloc(&idev->dev, - st->trigger_number * sizeof(st->trig), - GFP_KERNEL); + st->trig = devm_kcalloc(&idev->dev, st->trigger_number, + sizeof(*st->trig), GFP_KERNEL); if (st->trig == NULL) { ret = -ENOMEM; @@ -454,9 +451,8 @@ static int at91_adc_probe_dt(struct at91_adc_state *st, st->registers->trigger_register = prop; st->trigger_number = of_get_child_count(node); - st->trigger_list = devm_kzalloc(&idev->dev, st->trigger_number * - sizeof(struct at91_adc_trigger), - GFP_KERNEL); + st->trigger_list = devm_kcalloc(&idev->dev, st->trigger_number, + sizeof(*st->trigger_list), GFP_KERNEL); if (!st->trigger_list) { dev_err(&idev->dev, "Could not allocate trigger list memory.\n"); ret = -ENOMEM; -- cgit v1.2.3 From 948ad20504894436c008c8a50f74e277edeff9a1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 18 Oct 2012 14:47:00 +0100 Subject: iio: Use strict_strtouint instead of kstrtoul strict_strto* has been deprecated in favor of kstrto*. Use strict_strtouint respective strict_strtoint, since that is what the functions we pass the converted values to expect. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 6 +++--- drivers/iio/industrialio-event.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index d4ad37455a6..722a83fd8d8 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -371,12 +371,12 @@ ssize_t iio_buffer_write_length(struct device *dev, const char *buf, size_t len) { - int ret; - ulong val; struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_buffer *buffer = indio_dev->buffer; + unsigned int val; + int ret; - ret = strict_strtoul(buf, 10, &val); + ret = kstrtouint(buf, 10, &val); if (ret) return ret; diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index fa6543bf673..857e6306c5c 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -239,13 +239,13 @@ static ssize_t iio_ev_value_store(struct device *dev, { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - unsigned long val; + int val; int ret; if (!indio_dev->info->write_event_value) return -EINVAL; - ret = strict_strtoul(buf, 10, &val); + ret = kstrtoint(buf, 10, &val); if (ret) return ret; -- cgit v1.2.3 From 103d9fb907058e4eb052f4f7302d1b07eb6a7792 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 16 Oct 2012 17:29:00 +0100 Subject: iio: Add a logarithmic fractional value type For ADCs or DACs the denominator for fractional types often is a power of two. In this case we can use a shift operation instead of the rather expensive 64 bit division. This patch adds a new fractional type which expects the denominator to be specified as the log2 of the actual denominator. E.g. for ADCs and DACs this will usually be the number of significant bits. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 5 +++++ drivers/iio/inkern.c | 3 +++ include/linux/iio/types.h | 1 + 3 files changed, 9 insertions(+) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 6eb24dbc081..37650a72b31 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -397,6 +397,11 @@ static ssize_t iio_read_channel_info(struct device *dev, val2 = do_div(tmp, 1000000000LL); val = tmp; return sprintf(buf, "%d.%09u\n", val, val2); + case IIO_VAL_FRACTIONAL_LOG2: + tmp = (s64)val * 1000000000LL >> val2; + val2 = do_div(tmp, 1000000000LL); + val = tmp; + return sprintf(buf, "%d.%09u\n", val, val2); default: return 0; } diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 5230a33886c..b394621d362 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -314,6 +314,9 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, *processed = div_s64(raw64 * (s64)scale_val * scale, scale_val2); break; + case IIO_VAL_FRACTIONAL_LOG2: + *processed = (raw64 * (s64)scale_val * scale) >> scale_val2; + break; default: return -EINVAL; } diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index 5c647ecfd5b..87b196a2d69 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -58,5 +58,6 @@ enum iio_modifier { #define IIO_VAL_INT_PLUS_NANO 3 #define IIO_VAL_INT_PLUS_MICRO_DB 4 #define IIO_VAL_FRACTIONAL 10 +#define IIO_VAL_FRACTIONAL_LOG2 11 #endif /* _IIO_TYPES_H_ */ -- cgit v1.2.3 From 8341dc04dfb33fbae71727ae648e20c51abc40e3 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 16 Oct 2012 17:29:00 +0100 Subject: iio:dac: Add support for the ad5449 This patch adds support for the AD5415, AD5426, AD5429, AD5432, AD5439, AD5443 and AD5449 single and dual channel DACs. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/dac/Kconfig | 10 + drivers/iio/dac/Makefile | 1 + drivers/iio/dac/ad5449.c | 375 +++++++++++++++++++++++++++++++++++ include/linux/platform_data/ad5449.h | 40 ++++ 4 files changed, 426 insertions(+) create mode 100644 drivers/iio/dac/ad5449.c create mode 100644 include/linux/platform_data/ad5449.h diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index b1c0ee5294c..f68756e6dd6 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -67,6 +67,16 @@ config AD5446 To compile this driver as a module, choose M here: the module will be called ad5446. +config AD5449 + tristate "Analog Device AD5449 and similar DACs driver" + depends on SPI_MASTER + help + Say yes here to build support for Analog Devices AD5415, AD5426, AD5429, + AD5432, AD5439, AD5443, AD5449 Digital to Analog Converters. + + To compile this driver as a module, choose M here: the + module will be called ad5449. + config AD5504 tristate "Analog Devices AD5504/AD5501 DAC SPI driver" depends on SPI diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index c0d333b23ba..5b528ebb334 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o obj-$(CONFIG_AD5064) += ad5064.o obj-$(CONFIG_AD5504) += ad5504.o obj-$(CONFIG_AD5446) += ad5446.o +obj-$(CONFIG_AD5449) += ad5449.o obj-$(CONFIG_AD5755) += ad5755.o obj-$(CONFIG_AD5764) += ad5764.o obj-$(CONFIG_AD5791) += ad5791.o diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c new file mode 100644 index 00000000000..5b43030fe6e --- /dev/null +++ b/drivers/iio/dac/ad5449.c @@ -0,0 +1,375 @@ +/* + * AD5415, AD5426, AD5429, AD5432, AD5439, AD5443, AD5449 Digital to Analog + * Converter driver. + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define AD5449_MAX_CHANNELS 2 +#define AD5449_MAX_VREFS 2 + +#define AD5449_CMD_NOOP 0x0 +#define AD5449_CMD_LOAD_AND_UPDATE(x) (0x1 + (x) * 3) +#define AD5449_CMD_READ(x) (0x2 + (x) * 3) +#define AD5449_CMD_LOAD(x) (0x3 + (x) * 3) +#define AD5449_CMD_CTRL 13 + +#define AD5449_CTRL_SDO_OFFSET 10 +#define AD5449_CTRL_DAISY_CHAIN BIT(9) +#define AD5449_CTRL_HCLR_TO_MIDSCALE BIT(8) +#define AD5449_CTRL_SAMPLE_RISING BIT(7) + +/** + * struct ad5449_chip_info - chip specific information + * @channels: Channel specification + * @num_channels: Number of channels + * @has_ctrl: Chip has a control register + */ +struct ad5449_chip_info { + const struct iio_chan_spec *channels; + unsigned int num_channels; + bool has_ctrl; +}; + +/** + * struct ad5449 - driver instance specific data + * @spi: the SPI device for this driver instance + * @chip_info: chip model specific constants, available modes etc + * @vref_reg: vref supply regulators + * @has_sdo: whether the SDO line is connected + * @dac_cache: Cache for the DAC values + * @data: spi transfer buffers + */ +struct ad5449 { + struct spi_device *spi; + const struct ad5449_chip_info *chip_info; + struct regulator_bulk_data vref_reg[AD5449_MAX_VREFS]; + + bool has_sdo; + uint16_t dac_cache[AD5449_MAX_CHANNELS]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + __be16 data[2] ____cacheline_aligned; +}; + +enum ad5449_type { + ID_AD5426, + ID_AD5429, + ID_AD5432, + ID_AD5439, + ID_AD5443, + ID_AD5449, +}; + +static int ad5449_write(struct iio_dev *indio_dev, unsigned int addr, + unsigned int val) +{ + struct ad5449 *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&indio_dev->mlock); + st->data[0] = cpu_to_be16((addr << 12) | val); + ret = spi_write(st->spi, st->data, 2); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr, + unsigned int *val) +{ + struct ad5449 *st = iio_priv(indio_dev); + int ret; + struct spi_message msg; + struct spi_transfer t[] = { + { + .tx_buf = &st->data[0], + .len = 2, + .cs_change = 1, + }, { + .tx_buf = &st->data[1], + .rx_buf = &st->data[1], + .len = 2, + }, + }; + + spi_message_init(&msg); + spi_message_add_tail(&t[0], &msg); + spi_message_add_tail(&t[1], &msg); + + mutex_lock(&indio_dev->mlock); + st->data[0] = cpu_to_be16(addr << 12); + st->data[1] = cpu_to_be16(AD5449_CMD_NOOP); + + ret = spi_sync(st->spi, &msg); + if (ret < 0) + return ret; + + *val = be16_to_cpu(st->data[1]); + mutex_unlock(&indio_dev->mlock); + + return 0; +} + +static int ad5449_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, int *val2, long info) +{ + struct ad5449 *st = iio_priv(indio_dev); + struct regulator_bulk_data *reg; + int scale_uv; + int ret; + + switch (info) { + case IIO_CHAN_INFO_RAW: + if (st->has_sdo) { + ret = ad5449_read(indio_dev, + AD5449_CMD_READ(chan->address), val); + if (ret) + return ret; + *val &= 0xfff; + } else { + *val = st->dac_cache[chan->address]; + } + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + reg = &st->vref_reg[chan->channel]; + scale_uv = regulator_get_voltage(reg->consumer); + if (scale_uv < 0) + return scale_uv; + + *val = scale_uv / 1000; + *val2 = chan->scan_type.realbits; + + return IIO_VAL_FRACTIONAL_LOG2; + default: + break; + } + + return -EINVAL; +} + +static int ad5449_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, long info) +{ + struct ad5449 *st = iio_priv(indio_dev); + int ret; + + switch (info) { + case IIO_CHAN_INFO_RAW: + if (val < 0 || val >= (1 << chan->scan_type.realbits)) + return -EINVAL; + + ret = ad5449_write(indio_dev, + AD5449_CMD_LOAD_AND_UPDATE(chan->address), + val << chan->scan_type.shift); + if (ret == 0) + st->dac_cache[chan->address] = val; + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static const struct iio_info ad5449_info = { + .read_raw = ad5449_read_raw, + .write_raw = ad5449_write_raw, + .driver_module = THIS_MODULE, +}; + +#define AD5449_CHANNEL(chan, bits) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .output = 1, \ + .channel = (chan), \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .address = (chan), \ + .scan_type = IIO_ST('u', (bits), 16, 12 - (bits)), \ +} + +#define DECLARE_AD5449_CHANNELS(name, bits) \ +const struct iio_chan_spec name[] = { \ + AD5449_CHANNEL(0, bits), \ + AD5449_CHANNEL(1, bits), \ +} + +static DECLARE_AD5449_CHANNELS(ad5429_channels, 8); +static DECLARE_AD5449_CHANNELS(ad5439_channels, 10); +static DECLARE_AD5449_CHANNELS(ad5449_channels, 12); + +static const struct ad5449_chip_info ad5449_chip_info[] = { + [ID_AD5426] = { + .channels = ad5429_channels, + .num_channels = 1, + .has_ctrl = false, + }, + [ID_AD5429] = { + .channels = ad5429_channels, + .num_channels = 2, + .has_ctrl = true, + }, + [ID_AD5432] = { + .channels = ad5439_channels, + .num_channels = 1, + .has_ctrl = false, + }, + [ID_AD5439] = { + .channels = ad5439_channels, + .num_channels = 2, + .has_ctrl = true, + }, + [ID_AD5443] = { + .channels = ad5449_channels, + .num_channels = 1, + .has_ctrl = false, + }, + [ID_AD5449] = { + .channels = ad5449_channels, + .num_channels = 2, + .has_ctrl = true, + }, +}; + +static const char *ad5449_vref_name(struct ad5449 *st, int n) +{ + if (st->chip_info->num_channels == 1) + return "VREF"; + + if (n == 0) + return "VREFA"; + else + return "VREFB"; +} + +static int __devinit ad5449_spi_probe(struct spi_device *spi) +{ + struct ad5449_platform_data *pdata = spi->dev.platform_data; + const struct spi_device_id *id = spi_get_device_id(spi); + struct iio_dev *indio_dev; + struct ad5449 *st; + unsigned int i; + int ret; + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + spi_set_drvdata(spi, indio_dev); + + st->chip_info = &ad5449_chip_info[id->driver_data]; + st->spi = spi; + + for (i = 0; i < st->chip_info->num_channels; ++i) + st->vref_reg[i].supply = ad5449_vref_name(st, i); + + ret = regulator_bulk_get(&spi->dev, st->chip_info->num_channels, + st->vref_reg); + if (ret) + goto error_free; + + ret = regulator_bulk_enable(st->chip_info->num_channels, st->vref_reg); + if (ret) + goto error_free_reg; + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = id->name; + indio_dev->info = &ad5449_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->chip_info->channels; + indio_dev->num_channels = st->chip_info->num_channels; + + if (st->chip_info->has_ctrl) { + unsigned int ctrl = 0x00; + if (pdata) { + if (pdata->hardware_clear_to_midscale) + ctrl |= AD5449_CTRL_HCLR_TO_MIDSCALE; + ctrl |= pdata->sdo_mode << AD5449_CTRL_SDO_OFFSET; + st->has_sdo = pdata->sdo_mode != AD5449_SDO_DISABLED; + } else { + st->has_sdo = true; + } + ad5449_write(indio_dev, AD5449_CMD_CTRL, ctrl); + } + + ret = iio_device_register(indio_dev); + if (ret) + goto error_disable_reg; + + return 0; + +error_disable_reg: + regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg); +error_free_reg: + regulator_bulk_free(st->chip_info->num_channels, st->vref_reg); +error_free: + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit ad5449_spi_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad5449 *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + + regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg); + regulator_bulk_free(st->chip_info->num_channels, st->vref_reg); + + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad5449_spi_ids[] = { + { "ad5415", ID_AD5449 }, + { "ad5426", ID_AD5426 }, + { "ad5429", ID_AD5429 }, + { "ad5432", ID_AD5432 }, + { "ad5439", ID_AD5439 }, + { "ad5443", ID_AD5443 }, + { "ad5449", ID_AD5449 }, + {} +}; +MODULE_DEVICE_TABLE(spi, ad5449_spi_ids); + +static struct spi_driver ad5449_spi_driver = { + .driver = { + .name = "ad5449", + .owner = THIS_MODULE, + }, + .probe = ad5449_spi_probe, + .remove = __devexit_p(ad5449_spi_remove), + .id_table = ad5449_spi_ids, +}; +module_spi_driver(ad5449_spi_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Analog Devices AD5449 and similar DACs"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/platform_data/ad5449.h b/include/linux/platform_data/ad5449.h new file mode 100644 index 00000000000..bd712bd4b94 --- /dev/null +++ b/include/linux/platform_data/ad5449.h @@ -0,0 +1,40 @@ +/* + * AD5415, AD5426, AD5429, AD5432, AD5439, AD5443, AD5449 Digital to Analog + * Converter driver. + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ + +#ifndef __LINUX_PLATFORM_DATA_AD5449_H__ +#define __LINUX_PLATFORM_DATA_AD5449_H__ + +/** + * enum ad5449_sdo_mode - AD5449 SDO pin configuration + * @AD5449_SDO_DRIVE_FULL: Drive the SDO pin with full strength. + * @AD5449_SDO_DRIVE_WEAK: Drive the SDO pin with not full strength. + * @AD5449_SDO_OPEN_DRAIN: Operate the SDO pin in open-drain mode. + * @AD5449_SDO_DISABLED: Disable the SDO pin, in this mode it is not possible to + * read back from the device. + */ +enum ad5449_sdo_mode { + AD5449_SDO_DRIVE_FULL = 0x0, + AD5449_SDO_DRIVE_WEAK = 0x1, + AD5449_SDO_OPEN_DRAIN = 0x2, + AD5449_SDO_DISABLED = 0x3, +}; + +/** + * struct ad5449_platform_data - Platform data for the ad5449 DAC driver + * @sdo_mode: SDO pin mode + * @hardware_clear_to_midscale: Whether asserting the hardware CLR pin sets the + * outputs to midscale (true) or to zero scale(false). + */ +struct ad5449_platform_data { + enum ad5449_sdo_mode sdo_mode; + bool hardware_clear_to_midscale; +}; + +#endif -- cgit v1.2.3 From f9e314d2bf78816ea839cb1042d7dcd0da2821dc Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:25 +0200 Subject: Staging: ipack: get rid of ipack_device->bus_nr. It is replicating information contained in ipack_device->bus->bus_nr. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 18 +++++++++--------- drivers/staging/ipack/devices/ipoctal.c | 2 +- drivers/staging/ipack/ipack.c | 5 ++--- drivers/staging/ipack/ipack.h | 2 -- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index bb8aa70281c..2f48dd583a4 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -46,7 +46,7 @@ static struct tpci200_board *check_slot(struct ipack_device *dev) if (dev->slot >= TPCI200_NB_SLOT) { dev_info(&dev->dev, "Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n", - dev->bus_nr, dev->slot, TPCI200_NB_SLOT-1); + dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1); return NULL; } @@ -206,7 +206,7 @@ static int tpci200_request_irq(struct ipack_device *dev, if (tpci200->slots[dev->slot].irq != NULL) { dev_err(&dev->dev, - "Slot [%d:%d] IRQ already registered !\n", dev->bus_nr, + "Slot [%d:%d] IRQ already registered !\n", dev->bus->bus_nr, dev->slot); res = -EINVAL; goto out_unlock; @@ -216,7 +216,7 @@ static int tpci200_request_irq(struct ipack_device *dev, if (slot_irq == NULL) { dev_err(&dev->dev, "Slot [%d:%d] unable to allocate memory for IRQ !\n", - dev->bus_nr, dev->slot); + dev->bus->bus_nr, dev->slot); res = -ENOMEM; goto out_unlock; } @@ -379,7 +379,7 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) if (dev->io_space.address == NULL) { dev_info(&dev->dev, "Slot [%d:%d] IO space not mapped !\n", - dev->bus_nr, dev->slot); + dev->bus->bus_nr, dev->slot); goto out_unlock; } virt_addr_space = &dev->io_space; @@ -388,7 +388,7 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) if (dev->id_space.address == NULL) { dev_info(&dev->dev, "Slot [%d:%d] ID space not mapped !\n", - dev->bus_nr, dev->slot); + dev->bus->bus_nr, dev->slot); goto out_unlock; } virt_addr_space = &dev->id_space; @@ -397,7 +397,7 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) if (dev->int_space.address == NULL) { dev_info(&dev->dev, "Slot [%d:%d] INT space not mapped !\n", - dev->bus_nr, dev->slot); + dev->bus->bus_nr, dev->slot); goto out_unlock; } virt_addr_space = &dev->int_space; @@ -406,7 +406,7 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) if (dev->mem_space.address == NULL) { dev_info(&dev->dev, "Slot [%d:%d] MEM space not mapped !\n", - dev->bus_nr, dev->slot); + dev->bus->bus_nr, dev->slot); goto out_unlock; } virt_addr_space = &dev->mem_space; @@ -414,7 +414,7 @@ static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) default: dev_err(&dev->dev, "Slot [%d:%d] space number %d doesn't exist !\n", - dev->bus_nr, dev->slot, space); + dev->bus->bus_nr, dev->slot, space); mutex_unlock(&tpci200->mutex); return -EINVAL; } @@ -497,7 +497,7 @@ static int tpci200_slot_map_space(struct ipack_device *dev, if (memory_size > tpci200->slots[dev->slot].mem_phys.size) { dev_err(&dev->dev, "Slot [%d:%d] request is 0x%X memory, only 0x%X available !\n", - dev->bus_nr, dev->slot, memory_size, + dev->bus->bus_nr, dev->slot, memory_size, tpci200->slots[dev->slot].mem_phys.size); res = -EINVAL; goto out_unlock; diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index d751edfda83..15477891220 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -719,7 +719,7 @@ static int ipoctal_probe(struct ipack_device *dev) return -ENOMEM; ipoctal->dev = dev; - res = ipoctal_inst_slot(ipoctal, dev->bus_nr, dev->slot); + res = ipoctal_inst_slot(ipoctal, dev->bus->bus_nr, dev->slot); if (res) goto out_uninst; diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index d1e0651592a..ca8cb327df5 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -234,7 +234,7 @@ static int ipack_unregister_bus_member(struct device *dev, void *data) struct ipack_device *idev = to_ipack_dev(dev); struct ipack_bus_device *bus = data; - if (idev->bus_nr == bus->bus_nr) + if (idev->bus == bus) ipack_device_unregister(idev); return 1; @@ -440,10 +440,9 @@ struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, dev->dev.release = ipack_device_release; dev->dev.parent = bus->parent; dev->slot = slot; - dev->bus_nr = bus->bus_nr; dev->bus = bus; dev_set_name(&dev->dev, - "ipack-dev.%u.%u", dev->bus_nr, dev->slot); + "ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot); if (bus->ops->set_clockrate(dev, 8)) dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n"); diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index d8e3bb6feac..33fdea5e52f 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -52,7 +52,6 @@ struct ipack_addr_space { /** * struct ipack_device * - * @bus_nr: IP bus number where the device is plugged * @slot: Slot where the device is plugged in the carrier board * @bus: ipack_bus_device where the device is plugged to. * @id_space: Virtual address to ID space. @@ -65,7 +64,6 @@ struct ipack_addr_space { * by the carrier board throught bus->ops. */ struct ipack_device { - unsigned int bus_nr; unsigned int slot; struct ipack_bus_device *bus; struct ipack_addr_space id_space; -- cgit v1.2.3 From 1e91795c8cea4287b155862793271fe6a7737d20 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:26 +0200 Subject: Staging: ipack: Make ipack_device_register() analogous to device_register(). ipack_device_register() is no longer creating the struct ipack_device but only registering it. Instead of releasing memory directly the new ipack_device->release callback is called. This is preparational work for later patches. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 19 ++++++++++++++++++- drivers/staging/ipack/ipack.c | 30 +++++++++--------------------- drivers/staging/ipack/ipack.h | 15 +++++++++------ 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 2f48dd583a4..ee66129f0b8 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -640,6 +640,23 @@ static int tpci200_install(struct tpci200_board *tpci200) return 0; } +static void tpci200_release_device(struct ipack_device *dev) +{ + kfree(dev); +} + +static int tpci200_create_device(struct tpci200_board *tpci200, int i) +{ + struct ipack_device *dev = + kzalloc(sizeof(struct ipack_device), GFP_KERNEL); + if (!dev) + return -ENOMEM; + dev->slot = i; + dev->bus = tpci200->info->ipack_bus; + dev->release = tpci200_release_device; + return ipack_device_register(dev); +} + static int tpci200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -715,7 +732,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev, dev_set_drvdata(&pdev->dev, tpci200); for (i = 0; i < TPCI200_NB_SLOT; i++) - ipack_device_register(tpci200->info->ipack_bus, i); + tpci200_create_device(tpci200, i); return 0; out_err_bus_register: diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index ca8cb327df5..d2ed9f546fe 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -24,7 +24,7 @@ static void ipack_device_release(struct device *dev) { struct ipack_device *device = to_ipack_dev(dev); kfree(device->id); - kfree(device); + device->release(device); } static inline const struct ipack_device_id * @@ -426,51 +426,39 @@ out: return ret; } -struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, - int slot) +int ipack_device_register(struct ipack_device *dev) { int ret; - struct ipack_device *dev; - - dev = kzalloc(sizeof(struct ipack_device), GFP_KERNEL); - if (!dev) - return NULL; dev->dev.bus = &ipack_bus_type; dev->dev.release = ipack_device_release; - dev->dev.parent = bus->parent; - dev->slot = slot; - dev->bus = bus; + dev->dev.parent = dev->bus->parent; dev_set_name(&dev->dev, "ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot); - if (bus->ops->set_clockrate(dev, 8)) + if (dev->bus->ops->set_clockrate(dev, 8)) dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n"); - if (bus->ops->reset_timeout(dev)) + if (dev->bus->ops->reset_timeout(dev)) dev_warn(&dev->dev, "failed to reset potential timeout."); ret = ipack_device_read_id(dev); if (ret < 0) { dev_err(&dev->dev, "error reading device id section.\n"); - kfree(dev); - return NULL; + return ret; } /* if the device supports 32 MHz operation, use it. */ if (dev->speed_32mhz) { - ret = bus->ops->set_clockrate(dev, 32); + ret = dev->bus->ops->set_clockrate(dev, 32); if (ret < 0) dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n"); } ret = device_register(&dev->dev); - if (ret < 0) { + if (ret < 0) kfree(dev->id); - kfree(dev); - return NULL; - } - return dev; + return ret; } EXPORT_SYMBOL_GPL(ipack_device_register); diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 33fdea5e52f..e2987d58714 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -71,6 +71,7 @@ struct ipack_device { struct ipack_addr_space int_space; struct ipack_addr_space mem_space; struct device dev; + void (*release) (struct ipack_device *dev); u8 *id; size_t id_avail; u32 id_vendor; @@ -179,15 +180,17 @@ int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, void ipack_driver_unregister(struct ipack_driver *edrv); /** - * ipack_device_register -- register a new mezzanine device + * ipack_device_register -- register an IPack device with the kernel + * @dev: the new device to register. * - * @bus: ipack bus device it is plugged to. - * @slot: slot position in the bus device. + * Register a new IPack device ("module" in IndustryPack jargon). The call + * is done by the carrier driver. The carrier should populate the fields + * bus and slot of @dev prior to calling this function. The rest of the + * fields will be allocated and populated during registration. * - * Register a new ipack device (mezzanine device). The call is done by - * the carrier device driver. + * Return zero on success or error code on failure. */ -struct ipack_device *ipack_device_register(struct ipack_bus_device *bus, int slot); +int ipack_device_register(struct ipack_device *dev); void ipack_device_unregister(struct ipack_device *dev); /** -- cgit v1.2.3 From b412e893974126467f2241a044e1850d703643bb Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:27 +0200 Subject: Staging: ipack/bridges/tpci200: Don't map memory spaces that are not used later on. Remove the unused pointers to these spaces. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 10 ---------- drivers/staging/ipack/bridges/tpci200.h | 2 -- 2 files changed, 12 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index ee66129f0b8..a8042900355 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -78,8 +78,6 @@ static void tpci200_unregister(struct tpci200_board *tpci200) free_irq(tpci200->info->pdev->irq, (void *) tpci200); pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); - pci_iounmap(tpci200->info->pdev, tpci200->info->ioidint_space); - pci_iounmap(tpci200->info->pdev, tpci200->info->mem8_space); pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs); pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); @@ -289,14 +287,6 @@ static int tpci200_register(struct tpci200_board *tpci200) ioremap_nocache(pci_resource_start(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR), TPCI200_IFACE_SIZE); - tpci200->info->ioidint_space = - ioremap_nocache(pci_resource_start(tpci200->info->pdev, - TPCI200_IO_ID_INT_SPACES_BAR), - TPCI200_IOIDINT_SIZE); - tpci200->info->mem8_space = - ioremap_nocache(pci_resource_start(tpci200->info->pdev, - TPCI200_MEM8_SPACE_BAR), - TPCI200_MEM8_SIZE); /* Initialize lock that protects interface_regs */ spin_lock_init(&tpci200->regs_lock); diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index 235d1fe4f48..e4ed0a38ceb 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -156,8 +156,6 @@ struct tpci200_infos { struct pci_dev *pdev; struct pci_device_id *id_table; struct tpci200_regs __iomem *interface_regs; - void __iomem *ioidint_space; - void __iomem *mem8_space; void __iomem *cfg_regs; struct ipack_bus_device *ipack_bus; }; -- cgit v1.2.3 From bb29ab86d18da68e5c7f05814c07d5eb8bdb4652 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:28 +0200 Subject: Staging: ipack/bridges/tpci200: change tpci200_slot->*_phys type. Previously the *_phys fields were of type ipack_addr_space, which use void pointers to refer to memory addresses. Since the *_phys fields refer to unmapped memory, this is not correct. Introduce a new struct ipack_region (which uses phys_addr_t to refer to the start of a region) and use that as a replacement for struct ipack_addr_space. struct ipack_region is defined in ipack.h because it is planned to later expose the physical addressed to the IPack Module drivers. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 41 +++++++++++++++------------------ drivers/staging/ipack/bridges/tpci200.h | 10 ++++---- drivers/staging/ipack/ipack.h | 9 +++++++- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index a8042900355..47b8a1b4177 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -89,13 +89,13 @@ static void tpci200_unregister(struct tpci200_board *tpci200) pci_dev_put(tpci200->info->pdev); for (i = 0; i < TPCI200_NB_SLOT; i++) { - tpci200->slots[i].io_phys.address = NULL; + tpci200->slots[i].io_phys.start = 0; tpci200->slots[i].io_phys.size = 0; - tpci200->slots[i].id_phys.address = NULL; + tpci200->slots[i].id_phys.start = 0; tpci200->slots[i].id_phys.size = 0; - tpci200->slots[i].int_phys.address = NULL; + tpci200->slots[i].int_phys.start = 0; tpci200->slots[i].int_phys.size = 0; - tpci200->slots[i].mem_phys.address = NULL; + tpci200->slots[i].mem_phys.start = 0; tpci200->slots[i].mem_phys.size = 0; } } @@ -241,8 +241,8 @@ static int tpci200_register(struct tpci200_board *tpci200) { int i; int res; - unsigned long ioidint_base; - unsigned long mem_base; + phys_addr_t ioidint_base; + phys_addr_t mem_base; unsigned short slot_ctrl; if (pci_enable_device(tpci200->info->pdev) < 0) @@ -308,23 +308,20 @@ static int tpci200_register(struct tpci200_board *tpci200) /* Set all slot physical address space */ for (i = 0; i < TPCI200_NB_SLOT; i++) { - tpci200->slots[i].io_phys.address = - (void __iomem *)ioidint_base + + tpci200->slots[i].io_phys.start = ioidint_base + TPCI200_IO_SPACE_OFF + TPCI200_IO_SPACE_GAP*i; tpci200->slots[i].io_phys.size = TPCI200_IO_SPACE_SIZE; - tpci200->slots[i].id_phys.address = - (void __iomem *)ioidint_base + + tpci200->slots[i].id_phys.start = ioidint_base + TPCI200_ID_SPACE_OFF + TPCI200_ID_SPACE_GAP*i; tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE; - tpci200->slots[i].int_phys.address = - (void __iomem *)ioidint_base + + tpci200->slots[i].int_phys.start = ioidint_base + TPCI200_INT_SPACE_OFF + TPCI200_INT_SPACE_GAP * i; tpci200->slots[i].int_phys.size = TPCI200_INT_SPACE_SIZE; - tpci200->slots[i].mem_phys.address = - (void __iomem *)mem_base + TPCI200_MEM8_GAP*i; + tpci200->slots[i].mem_phys.start = mem_base + + TPCI200_MEM8_GAP * i; tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE; writew(slot_ctrl, &tpci200->info->interface_regs->control[i]); @@ -419,11 +416,11 @@ out_unlock: } static int tpci200_slot_map_space(struct ipack_device *dev, - unsigned int memory_size, int space) + ssize_t memory_size, int space) { int res = 0; - unsigned int size_to_map; - void __iomem *phys_address; + size_t size_to_map; + phys_addr_t phys_address; struct ipack_addr_space *virt_addr_space; struct tpci200_board *tpci200; @@ -445,7 +442,7 @@ static int tpci200_slot_map_space(struct ipack_device *dev, } virt_addr_space = &dev->io_space; - phys_address = tpci200->slots[dev->slot].io_phys.address; + phys_address = tpci200->slots[dev->slot].io_phys.start; size_to_map = tpci200->slots[dev->slot].io_phys.size; break; case IPACK_ID_SPACE: @@ -458,7 +455,7 @@ static int tpci200_slot_map_space(struct ipack_device *dev, } virt_addr_space = &dev->id_space; - phys_address = tpci200->slots[dev->slot].id_phys.address; + phys_address = tpci200->slots[dev->slot].id_phys.start; size_to_map = tpci200->slots[dev->slot].id_phys.size; break; case IPACK_INT_SPACE: @@ -471,7 +468,7 @@ static int tpci200_slot_map_space(struct ipack_device *dev, } virt_addr_space = &dev->int_space; - phys_address = tpci200->slots[dev->slot].int_phys.address; + phys_address = tpci200->slots[dev->slot].int_phys.start; size_to_map = tpci200->slots[dev->slot].int_phys.size; break; case IPACK_MEM_SPACE: @@ -486,14 +483,14 @@ static int tpci200_slot_map_space(struct ipack_device *dev, if (memory_size > tpci200->slots[dev->slot].mem_phys.size) { dev_err(&dev->dev, - "Slot [%d:%d] request is 0x%X memory, only 0x%X available !\n", + "Slot [%d:%d] request is 0x%zX memory, only 0x%zX available !\n", dev->bus->bus_nr, dev->slot, memory_size, tpci200->slots[dev->slot].mem_phys.size); res = -EINVAL; goto out_unlock; } - phys_address = tpci200->slots[dev->slot].mem_phys.address; + phys_address = tpci200->slots[dev->slot].mem_phys.start; size_to_map = memory_size; break; default: diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index e4ed0a38ceb..59cb5b7dbc4 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -137,11 +137,11 @@ struct slot_irq { * */ struct tpci200_slot { - struct slot_irq *irq; - struct ipack_addr_space io_phys; - struct ipack_addr_space id_phys; - struct ipack_addr_space int_phys; - struct ipack_addr_space mem_phys; + struct slot_irq *irq; + struct ipack_region io_phys; + struct ipack_region id_phys; + struct ipack_region int_phys; + struct ipack_region mem_phys; }; /** diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index e2987d58714..9e543a585fd 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -49,6 +49,13 @@ struct ipack_addr_space { unsigned int size; }; +/** + */ +struct ipack_region { + phys_addr_t start; + size_t size; +}; + /** * struct ipack_device * @@ -124,7 +131,7 @@ struct ipack_driver { * @reset_timeout: Resets the state returned by get_timeout. */ struct ipack_bus_ops { - int (*map_space) (struct ipack_device *dev, unsigned int memory_size, int space); + int (*map_space) (struct ipack_device *dev, ssize_t memory_size, int space); int (*unmap_space) (struct ipack_device *dev, int space); int (*request_irq) (struct ipack_device *dev, irqreturn_t (*handler)(void *), void *arg); -- cgit v1.2.3 From 84a08fa9eb330969b661305bd5a5fcae06d98cba Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:29 +0200 Subject: Staging: ipack/bridges/tpci200: Store beginning of module memory regions in struct tpci200. tpci200_register is converted to use this. A later patch will build on this. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 26 +++++++++++++++++--------- drivers/staging/ipack/bridges/tpci200.h | 1 + drivers/staging/ipack/ipack.h | 7 +++++-- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 47b8a1b4177..5acaea2e8f4 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -242,7 +242,6 @@ static int tpci200_register(struct tpci200_board *tpci200) int i; int res; phys_addr_t ioidint_base; - phys_addr_t mem_base; unsigned short slot_ctrl; if (pci_enable_device(tpci200->info->pdev) < 0) @@ -293,7 +292,12 @@ static int tpci200_register(struct tpci200_board *tpci200) ioidint_base = pci_resource_start(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); - mem_base = pci_resource_start(tpci200->info->pdev, + tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF; + tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF; + tpci200->mod_mem[IPACK_INT_SPACE] = + ioidint_base + TPCI200_INT_SPACE_OFF; + tpci200->mod_mem[IPACK_MEM_SPACE] = + pci_resource_start(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); /* Set the default parameters of the slot @@ -308,19 +312,23 @@ static int tpci200_register(struct tpci200_board *tpci200) /* Set all slot physical address space */ for (i = 0; i < TPCI200_NB_SLOT; i++) { - tpci200->slots[i].io_phys.start = ioidint_base + - TPCI200_IO_SPACE_OFF + TPCI200_IO_SPACE_GAP*i; + tpci200->slots[i].io_phys.start = + tpci200->mod_mem[IPACK_IO_SPACE] + + TPCI200_IO_SPACE_GAP * i; tpci200->slots[i].io_phys.size = TPCI200_IO_SPACE_SIZE; - tpci200->slots[i].id_phys.start = ioidint_base + - TPCI200_ID_SPACE_OFF + TPCI200_ID_SPACE_GAP*i; + tpci200->slots[i].id_phys.start = + tpci200->mod_mem[IPACK_ID_SPACE] + + TPCI200_ID_SPACE_GAP * i; tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE; - tpci200->slots[i].int_phys.start = ioidint_base + - TPCI200_INT_SPACE_OFF + TPCI200_INT_SPACE_GAP * i; + tpci200->slots[i].int_phys.start = + tpci200->mod_mem[IPACK_INT_SPACE] + + TPCI200_INT_SPACE_GAP * i; tpci200->slots[i].int_phys.size = TPCI200_INT_SPACE_SIZE; - tpci200->slots[i].mem_phys.start = mem_base + + tpci200->slots[i].mem_phys.start = + tpci200->mod_mem[IPACK_MEM_SPACE] + TPCI200_MEM8_GAP * i; tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE; diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index 59cb5b7dbc4..6b7c7003f6c 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -165,6 +165,7 @@ struct tpci200_board { spinlock_t regs_lock; struct tpci200_slot *slots; struct tpci200_infos *info; + phys_addr_t mod_mem[IPACK_SPACE_COUNT]; }; #endif /* _TPCI200_H_ */ diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 9e543a585fd..a842eeaf534 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -33,9 +33,12 @@ struct ipack_driver; enum ipack_space { IPACK_IO_SPACE = 0, - IPACK_ID_SPACE = 1, - IPACK_MEM_SPACE = 2, + IPACK_ID_SPACE, + IPACK_MEM_SPACE, IPACK_INT_SPACE, + /* Dummy for counting the number of entries. Must remain the last + * entry */ + IPACK_SPACE_COUNT, }; /** -- cgit v1.2.3 From 6114aeaa731a489420912faee758e6af363be595 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:30 +0200 Subject: Staging: ipack/bridges/tpci200: Cleanups. Constant renames: - Rename TPCI200_*_GAP to TPCI200_*_INTERVAL. - Rename TPCI200_MEM*_* to TPCI200_MEM*_SPACE_* (to match the other SPACE constants. Make tpci200_status_timeout and tpci200_status_error const. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 24 ++++++++++++------------ drivers/staging/ipack/bridges/tpci200.h | 14 +++++++------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 5acaea2e8f4..84e1c273fd6 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -14,14 +14,14 @@ #include #include "tpci200.h" -static u16 tpci200_status_timeout[] = { +static const u16 tpci200_status_timeout[] = { TPCI200_A_TIMEOUT, TPCI200_B_TIMEOUT, TPCI200_C_TIMEOUT, TPCI200_D_TIMEOUT, }; -static u16 tpci200_status_error[] = { +static const u16 tpci200_status_error[] = { TPCI200_A_ERROR, TPCI200_B_ERROR, TPCI200_C_ERROR, @@ -298,7 +298,7 @@ static int tpci200_register(struct tpci200_board *tpci200) ioidint_base + TPCI200_INT_SPACE_OFF; tpci200->mod_mem[IPACK_MEM_SPACE] = pci_resource_start(tpci200->info->pdev, - TPCI200_MEM8_SPACE_BAR); + TPCI200_MEM8_SPACE_BAR); /* Set the default parameters of the slot * INT0 disabled, level sensitive @@ -313,24 +313,24 @@ static int tpci200_register(struct tpci200_board *tpci200) /* Set all slot physical address space */ for (i = 0; i < TPCI200_NB_SLOT; i++) { tpci200->slots[i].io_phys.start = - tpci200->mod_mem[IPACK_IO_SPACE] + - TPCI200_IO_SPACE_GAP * i; + tpci200->mod_mem[IPACK_IO_SPACE] + + TPCI200_IO_SPACE_INTERVAL * i; tpci200->slots[i].io_phys.size = TPCI200_IO_SPACE_SIZE; tpci200->slots[i].id_phys.start = - tpci200->mod_mem[IPACK_ID_SPACE] + - TPCI200_ID_SPACE_GAP * i; + tpci200->mod_mem[IPACK_ID_SPACE] + + TPCI200_ID_SPACE_INTERVAL * i; tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE; tpci200->slots[i].int_phys.start = - tpci200->mod_mem[IPACK_INT_SPACE] + - TPCI200_INT_SPACE_GAP * i; + tpci200->mod_mem[IPACK_INT_SPACE] + + TPCI200_INT_SPACE_INTERVAL * i; tpci200->slots[i].int_phys.size = TPCI200_INT_SPACE_SIZE; tpci200->slots[i].mem_phys.start = - tpci200->mod_mem[IPACK_MEM_SPACE] + - TPCI200_MEM8_GAP * i; - tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SIZE; + tpci200->mod_mem[IPACK_MEM_SPACE] + + TPCI200_MEM8_SPACE_INTERVAL * i; + tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SPACE_SIZE; writew(slot_ctrl, &tpci200->info->interface_regs->control[i]); } diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index 6b7c7003f6c..fe8e97e92c8 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -49,20 +49,20 @@ struct tpci200_regs { #define TPCI200_IFACE_SIZE 0x100 #define TPCI200_IO_SPACE_OFF 0x0000 -#define TPCI200_IO_SPACE_GAP 0x0100 +#define TPCI200_IO_SPACE_INTERVAL 0x0100 #define TPCI200_IO_SPACE_SIZE 0x0080 #define TPCI200_ID_SPACE_OFF 0x0080 -#define TPCI200_ID_SPACE_GAP 0x0100 +#define TPCI200_ID_SPACE_INTERVAL 0x0100 #define TPCI200_ID_SPACE_SIZE 0x0040 #define TPCI200_INT_SPACE_OFF 0x00C0 -#define TPCI200_INT_SPACE_GAP 0x0100 +#define TPCI200_INT_SPACE_INTERVAL 0x0100 #define TPCI200_INT_SPACE_SIZE 0x0040 #define TPCI200_IOIDINT_SIZE 0x0400 -#define TPCI200_MEM8_GAP 0x00400000 -#define TPCI200_MEM8_SIZE 0x00400000 -#define TPCI200_MEM16_GAP 0x00800000 -#define TPCI200_MEM16_SIZE 0x00800000 +#define TPCI200_MEM8_SPACE_INTERVAL 0x00400000 +#define TPCI200_MEM8_SPACE_SIZE 0x00400000 +#define TPCI200_MEM16_SPACE_INTERVAL 0x00800000 +#define TPCI200_MEM16_SPACE_SIZE 0x00800000 /* control field in tpci200_regs */ #define TPCI200_INT0_EN 0x0040 -- cgit v1.2.3 From a19ad7d08744bd3ea6efeccbcddcc4a992bc6ac9 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:31 +0200 Subject: Staging: ipack: Provide physical memory regions to IPack devices. This will allow us to use the regular ioremop functions. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 22 ++++++++++++++++++++++ drivers/staging/ipack/ipack.h | 6 ++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 84e1c273fd6..8428e3bfd1a 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -28,6 +28,20 @@ static const u16 tpci200_status_error[] = { TPCI200_D_ERROR, }; +static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = { + [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE, + [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE, + [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE, + [IPACK_MEM_SPACE] = TPCI200_MEM8_SPACE_SIZE, +}; + +static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = { + [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL, + [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL, + [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL, + [IPACK_MEM_SPACE] = TPCI200_MEM8_SPACE_INTERVAL, +}; + static struct tpci200_board *check_slot(struct ipack_device *dev) { struct tpci200_board *tpci200; @@ -642,6 +656,7 @@ static void tpci200_release_device(struct ipack_device *dev) static int tpci200_create_device(struct tpci200_board *tpci200, int i) { + enum ipack_space space; struct ipack_device *dev = kzalloc(sizeof(struct ipack_device), GFP_KERNEL); if (!dev) @@ -649,6 +664,13 @@ static int tpci200_create_device(struct tpci200_board *tpci200, int i) dev->slot = i; dev->bus = tpci200->info->ipack_bus; dev->release = tpci200_release_device; + + for (space = 0; space < IPACK_SPACE_COUNT; space++) { + dev->region[space].start = + tpci200->mod_mem[space] + + tpci200_space_interval[space] * i; + dev->region[space].size = tpci200_space_size[space]; + } return ipack_device_register(dev); } diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index a842eeaf534..43d152a6e0e 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -82,6 +82,7 @@ struct ipack_device { struct ipack_addr_space mem_space; struct device dev; void (*release) (struct ipack_device *dev); + struct ipack_region region[IPACK_SPACE_COUNT]; u8 *id; size_t id_avail; u32 id_vendor; @@ -195,8 +196,9 @@ void ipack_driver_unregister(struct ipack_driver *edrv); * * Register a new IPack device ("module" in IndustryPack jargon). The call * is done by the carrier driver. The carrier should populate the fields - * bus and slot of @dev prior to calling this function. The rest of the - * fields will be allocated and populated during registration. + * bus and slot as well as the region array of @dev prior to calling this + * function. The rest of the fields will be allocated and populated + * during registration. * * Return zero on success or error code on failure. */ -- cgit v1.2.3 From 295beb7127e683977cf9af438f5cf8419aa480c6 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:32 +0200 Subject: staging: ipack/devices/ipoctal: fix ipoctal_inst_slot error path. The ordering was wrong. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/devices/ipoctal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 15477891220..dbe02fe05af 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -460,13 +460,13 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, return 0; out_unregister_slot_unmap: - ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE); + ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE); out_unregister_int_space: ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE); out_unregister_io_space: ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE); out_unregister_id_space: - ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE); + ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE); return res; } -- cgit v1.2.3 From 2ec678d132020f8312a27227d4fb9a3de92d8545 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:33 +0200 Subject: staging: ipack/devices/ipoctal: obtain model from dev->id_device. By doing so we can remove ipoctal_check_model() and we also no longer need to map the IPACK_ID_SPACE. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/devices/ipoctal.c | 46 ++------------------------------- 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index dbe02fe05af..e6d165457e1 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -258,29 +258,6 @@ static irqreturn_t ipoctal_irq_handler(void *arg) return IRQ_HANDLED; } -static int ipoctal_check_model(struct ipack_device *dev, unsigned char *id) -{ - unsigned char manufacturerID; - unsigned char board_id; - - - manufacturerID = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MANUFACTURER_ID); - if (manufacturerID != IPACK1_VENDOR_ID_SBS) - return -ENODEV; - board_id = ioread8(dev->id_space.address + IPACK_IDPROM_OFFSET_MODEL); - switch (board_id) { - case IPACK1_DEVICE_ID_SBS_OCTAL_232: - case IPACK1_DEVICE_ID_SBS_OCTAL_422: - case IPACK1_DEVICE_ID_SBS_OCTAL_485: - *id = board_id; - break; - default: - return -ENODEV; - } - - return 0; -} - static const struct tty_port_operations ipoctal_tty_port_ops = { .dtr_rts = NULL, .activate = ipoctal_port_activate, @@ -293,27 +270,11 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, int i; struct tty_driver *tty; char name[20]; - unsigned char board_id; struct ipoctal_channel *channel; union scc2698_channel __iomem *chan_regs; union scc2698_block __iomem *block_regs; - res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0, - IPACK_ID_SPACE); - if (res) { - dev_err(&ipoctal->dev->dev, - "Unable to map slot [%d:%d] ID space!\n", - bus_nr, slot); - return res; - } - - res = ipoctal_check_model(ipoctal->dev, &board_id); - if (res) { - ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, - IPACK_ID_SPACE); - goto out_unregister_id_space; - } - ipoctal->board_id = board_id; + ipoctal->board_id = ipoctal->dev->id_device; res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0, IPACK_IO_SPACE); @@ -321,7 +282,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, dev_err(&ipoctal->dev->dev, "Unable to map slot [%d:%d] IO space!\n", bus_nr, slot); - goto out_unregister_id_space; + return res; } res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0, @@ -465,8 +426,6 @@ out_unregister_int_space: ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE); out_unregister_io_space: ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE); -out_unregister_id_space: - ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE); return res; } @@ -748,7 +707,6 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE); ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE); ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE); - ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_ID_SPACE); kfree(ipoctal); } -- cgit v1.2.3 From 402228dbe395bf17e38d5a23a9d6aa18f8705899 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:34 +0200 Subject: staging: ipack: swich to regular ioremap and friends. Use the regular ioremap functions and their managed counterparts instead of the ones provided through IPack callbacks. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/devices/ipoctal.c | 70 ++++++++++++++++----------------- drivers/staging/ipack/ipack.c | 8 ++-- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index e6d165457e1..5ed57950b67 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -53,6 +53,8 @@ struct ipoctal { struct ipoctal_channel channel[NR_CHANNELS]; unsigned char write; struct tty_driver *tty_drv; + u8 __iomem *mem_space; + u8 __iomem *int_space; }; static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) @@ -252,8 +254,8 @@ static irqreturn_t ipoctal_irq_handler(void *arg) ipoctal_irq_channel(&ipoctal->channel[i]); /* Clear the IPack device interrupt */ - readw(ipoctal->dev->int_space.address + ACK_INT_REQ0); - readw(ipoctal->dev->int_space.address + ACK_INT_REQ1); + readw(ipoctal->int_space + ACK_INT_REQ0); + readw(ipoctal->int_space + ACK_INT_REQ1); return IRQ_HANDLED; } @@ -266,48 +268,55 @@ static const struct tty_port_operations ipoctal_tty_port_ops = { static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, unsigned int slot) { - int res = 0; + int res; int i; struct tty_driver *tty; char name[20]; struct ipoctal_channel *channel; + struct ipack_region *region; + void __iomem *addr; union scc2698_channel __iomem *chan_regs; union scc2698_block __iomem *block_regs; ipoctal->board_id = ipoctal->dev->id_device; - res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0, - IPACK_IO_SPACE); - if (res) { + region = &ipoctal->dev->region[IPACK_IO_SPACE]; + addr = devm_ioremap_nocache(&ipoctal->dev->dev, + region->start, region->size); + if (!addr) { dev_err(&ipoctal->dev->dev, "Unable to map slot [%d:%d] IO space!\n", bus_nr, slot); - return res; + return -EADDRNOTAVAIL; } + /* Save the virtual address to access the registers easily */ + chan_regs = + (union scc2698_channel __iomem *) addr; + block_regs = + (union scc2698_block __iomem *) addr; - res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, 0, - IPACK_INT_SPACE); - if (res) { + region = &ipoctal->dev->region[IPACK_INT_SPACE]; + ipoctal->int_space = + devm_ioremap_nocache(&ipoctal->dev->dev, + region->start, region->size); + if (!ipoctal->int_space) { dev_err(&ipoctal->dev->dev, "Unable to map slot [%d:%d] INT space!\n", bus_nr, slot); - goto out_unregister_io_space; + return -EADDRNOTAVAIL; } - res = ipoctal->dev->bus->ops->map_space(ipoctal->dev, - 0x8000, IPACK_MEM_SPACE); - if (res) { + region = &ipoctal->dev->region[IPACK_MEM_SPACE]; + ipoctal->mem_space = + devm_ioremap_nocache(&ipoctal->dev->dev, + region->start, 0x8000); + if (!addr) { dev_err(&ipoctal->dev->dev, "Unable to map slot [%d:%d] MEM space!\n", bus_nr, slot); - goto out_unregister_int_space; + return -EADDRNOTAVAIL; } - /* Save the virtual address to access the registers easily */ - chan_regs = - (union scc2698_channel __iomem *) ipoctal->dev->io_space.address; - block_regs = - (union scc2698_block __iomem *) ipoctal->dev->io_space.address; /* Disable RX and TX before touching anything */ for (i = 0; i < NR_CHANNELS ; i++) { @@ -350,17 +359,15 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, ipoctal->dev->bus->ops->request_irq(ipoctal->dev, ipoctal_irq_handler, ipoctal); /* Dummy write */ - iowrite8(1, ipoctal->dev->mem_space.address + 1); + iowrite8(1, ipoctal->mem_space + 1); /* Register the TTY device */ /* Each IP-OCTAL channel is a TTY port */ tty = alloc_tty_driver(NR_CHANNELS); - if (!tty) { - res = -ENOMEM; - goto out_unregister_slot_unmap; - } + if (!tty) + return -ENOMEM; /* Fill struct tty_driver with ipoctal data */ tty->owner = THIS_MODULE; @@ -383,7 +390,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, if (res) { dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n"); put_tty_driver(tty); - goto out_unregister_slot_unmap; + return res; } /* Save struct tty_driver for use it when uninstalling the device */ @@ -419,14 +426,6 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, } return 0; - -out_unregister_slot_unmap: - ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE); -out_unregister_int_space: - ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE); -out_unregister_io_space: - ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE); - return res; } static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, @@ -704,9 +703,6 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) tty_unregister_driver(ipoctal->tty_drv); put_tty_driver(ipoctal->tty_drv); - ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_MEM_SPACE); - ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_INT_SPACE); - ipoctal->dev->bus->ops->unmap_space(ipoctal->dev, IPACK_IO_SPACE); kfree(ipoctal); } diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index d2ed9f546fe..5bd462b9e38 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -351,12 +351,12 @@ static int ipack_device_read_id(struct ipack_device *dev) int i; int ret = 0; - ret = dev->bus->ops->map_space(dev, 0, IPACK_ID_SPACE); - if (ret) { + idmem = ioremap(dev->region[IPACK_ID_SPACE].start, + dev->region[IPACK_ID_SPACE].size); + if (!idmem) { dev_err(&dev->dev, "error mapping memory\n"); return ret; } - idmem = dev->id_space.address; /* Determine ID PROM Data Format. If we find the ids "IPAC" or "IPAH" * we are dealing with a IndustryPack format 1 device. If we detect @@ -421,7 +421,7 @@ static int ipack_device_read_id(struct ipack_device *dev) } out: - dev->bus->ops->unmap_space(dev, IPACK_ID_SPACE); + iounmap(idmem); return ret; } -- cgit v1.2.3 From a93963ab01519cf56c5a5d36eebb077db4059eac Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:35 +0200 Subject: Staging: ipack: remove memory mapping callbacks. Now that we have the infrastructure to use the regular function in place and all existing users are converted, remove the map and unmap callbacks from the ipack_bus_device->ops. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 200 +------------------------------- drivers/staging/ipack/bridges/tpci200.h | 4 - drivers/staging/ipack/ipack.h | 17 --- 3 files changed, 1 insertion(+), 220 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 8428e3bfd1a..901f6577406 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -87,8 +87,6 @@ static void tpci200_set_mask(struct tpci200_board *tpci200, static void tpci200_unregister(struct tpci200_board *tpci200) { - int i; - free_irq(tpci200->info->pdev->irq, (void *) tpci200); pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); @@ -101,17 +99,6 @@ static void tpci200_unregister(struct tpci200_board *tpci200) pci_disable_device(tpci200->info->pdev); pci_dev_put(tpci200->info->pdev); - - for (i = 0; i < TPCI200_NB_SLOT; i++) { - tpci200->slots[i].io_phys.start = 0; - tpci200->slots[i].io_phys.size = 0; - tpci200->slots[i].id_phys.start = 0; - tpci200->slots[i].id_phys.size = 0; - tpci200->slots[i].int_phys.start = 0; - tpci200->slots[i].int_phys.size = 0; - tpci200->slots[i].mem_phys.start = 0; - tpci200->slots[i].mem_phys.size = 0; - } } static void tpci200_enable_irq(struct tpci200_board *tpci200, @@ -323,31 +310,8 @@ static int tpci200_register(struct tpci200_board *tpci200) * clock rate 8 MHz */ slot_ctrl = 0; - - /* Set all slot physical address space */ - for (i = 0; i < TPCI200_NB_SLOT; i++) { - tpci200->slots[i].io_phys.start = - tpci200->mod_mem[IPACK_IO_SPACE] - + TPCI200_IO_SPACE_INTERVAL * i; - tpci200->slots[i].io_phys.size = TPCI200_IO_SPACE_SIZE; - - tpci200->slots[i].id_phys.start = - tpci200->mod_mem[IPACK_ID_SPACE] - + TPCI200_ID_SPACE_INTERVAL * i; - tpci200->slots[i].id_phys.size = TPCI200_ID_SPACE_SIZE; - - tpci200->slots[i].int_phys.start = - tpci200->mod_mem[IPACK_INT_SPACE] - + TPCI200_INT_SPACE_INTERVAL * i; - tpci200->slots[i].int_phys.size = TPCI200_INT_SPACE_SIZE; - - tpci200->slots[i].mem_phys.start = - tpci200->mod_mem[IPACK_MEM_SPACE] - + TPCI200_MEM8_SPACE_INTERVAL * i; - tpci200->slots[i].mem_phys.size = TPCI200_MEM8_SPACE_SIZE; - + for (i = 0; i < TPCI200_NB_SLOT; i++) writew(slot_ctrl, &tpci200->info->interface_regs->control[i]); - } res = request_irq(tpci200->info->pdev->irq, tpci200_interrupt, IRQF_SHARED, @@ -371,166 +335,6 @@ out_disable_pci: return res; } -static int tpci200_slot_unmap_space(struct ipack_device *dev, int space) -{ - struct ipack_addr_space *virt_addr_space; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - if (mutex_lock_interruptible(&tpci200->mutex)) - return -ERESTARTSYS; - - switch (space) { - case IPACK_IO_SPACE: - if (dev->io_space.address == NULL) { - dev_info(&dev->dev, - "Slot [%d:%d] IO space not mapped !\n", - dev->bus->bus_nr, dev->slot); - goto out_unlock; - } - virt_addr_space = &dev->io_space; - break; - case IPACK_ID_SPACE: - if (dev->id_space.address == NULL) { - dev_info(&dev->dev, - "Slot [%d:%d] ID space not mapped !\n", - dev->bus->bus_nr, dev->slot); - goto out_unlock; - } - virt_addr_space = &dev->id_space; - break; - case IPACK_INT_SPACE: - if (dev->int_space.address == NULL) { - dev_info(&dev->dev, - "Slot [%d:%d] INT space not mapped !\n", - dev->bus->bus_nr, dev->slot); - goto out_unlock; - } - virt_addr_space = &dev->int_space; - break; - case IPACK_MEM_SPACE: - if (dev->mem_space.address == NULL) { - dev_info(&dev->dev, - "Slot [%d:%d] MEM space not mapped !\n", - dev->bus->bus_nr, dev->slot); - goto out_unlock; - } - virt_addr_space = &dev->mem_space; - break; - default: - dev_err(&dev->dev, - "Slot [%d:%d] space number %d doesn't exist !\n", - dev->bus->bus_nr, dev->slot, space); - mutex_unlock(&tpci200->mutex); - return -EINVAL; - } - - iounmap(virt_addr_space->address); - - virt_addr_space->address = NULL; - virt_addr_space->size = 0; -out_unlock: - mutex_unlock(&tpci200->mutex); - return 0; -} - -static int tpci200_slot_map_space(struct ipack_device *dev, - ssize_t memory_size, int space) -{ - int res = 0; - size_t size_to_map; - phys_addr_t phys_address; - struct ipack_addr_space *virt_addr_space; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - if (mutex_lock_interruptible(&tpci200->mutex)) - return -ERESTARTSYS; - - switch (space) { - case IPACK_IO_SPACE: - if (dev->io_space.address != NULL) { - dev_err(&dev->dev, - "Slot [%d:%d] IO space already mapped !\n", - tpci200->number, dev->slot); - res = -EINVAL; - goto out_unlock; - } - virt_addr_space = &dev->io_space; - - phys_address = tpci200->slots[dev->slot].io_phys.start; - size_to_map = tpci200->slots[dev->slot].io_phys.size; - break; - case IPACK_ID_SPACE: - if (dev->id_space.address != NULL) { - dev_err(&dev->dev, - "Slot [%d:%d] ID space already mapped !\n", - tpci200->number, dev->slot); - res = -EINVAL; - goto out_unlock; - } - virt_addr_space = &dev->id_space; - - phys_address = tpci200->slots[dev->slot].id_phys.start; - size_to_map = tpci200->slots[dev->slot].id_phys.size; - break; - case IPACK_INT_SPACE: - if (dev->int_space.address != NULL) { - dev_err(&dev->dev, - "Slot [%d:%d] INT space already mapped !\n", - tpci200->number, dev->slot); - res = -EINVAL; - goto out_unlock; - } - virt_addr_space = &dev->int_space; - - phys_address = tpci200->slots[dev->slot].int_phys.start; - size_to_map = tpci200->slots[dev->slot].int_phys.size; - break; - case IPACK_MEM_SPACE: - if (dev->mem_space.address != NULL) { - dev_err(&dev->dev, - "Slot [%d:%d] MEM space already mapped !\n", - tpci200->number, dev->slot); - res = -EINVAL; - goto out_unlock; - } - virt_addr_space = &dev->mem_space; - - if (memory_size > tpci200->slots[dev->slot].mem_phys.size) { - dev_err(&dev->dev, - "Slot [%d:%d] request is 0x%zX memory, only 0x%zX available !\n", - dev->bus->bus_nr, dev->slot, memory_size, - tpci200->slots[dev->slot].mem_phys.size); - res = -EINVAL; - goto out_unlock; - } - - phys_address = tpci200->slots[dev->slot].mem_phys.start; - size_to_map = memory_size; - break; - default: - dev_err(&dev->dev, "Slot [%d:%d] space %d doesn't exist !\n", - tpci200->number, dev->slot, space); - res = -EINVAL; - goto out_unlock; - } - - virt_addr_space->size = size_to_map; - virt_addr_space->address = - ioremap_nocache((unsigned long)phys_address, size_to_map); - -out_unlock: - mutex_unlock(&tpci200->mutex); - return res; -} - static int tpci200_get_clockrate(struct ipack_device *dev) { struct tpci200_board *tpci200 = check_slot(dev); @@ -618,8 +422,6 @@ static void tpci200_uninstall(struct tpci200_board *tpci200) } static const struct ipack_bus_ops tpci200_bus_ops = { - .map_space = tpci200_slot_map_space, - .unmap_space = tpci200_slot_unmap_space, .request_irq = tpci200_request_irq, .free_irq = tpci200_free_irq, .get_clockrate = tpci200_get_clockrate, diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h index fe8e97e92c8..982f31920af 100644 --- a/drivers/staging/ipack/bridges/tpci200.h +++ b/drivers/staging/ipack/bridges/tpci200.h @@ -138,10 +138,6 @@ struct slot_irq { */ struct tpci200_slot { struct slot_irq *irq; - struct ipack_region io_phys; - struct ipack_region id_phys; - struct ipack_region int_phys; - struct ipack_region mem_phys; }; /** diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 43d152a6e0e..af950281506 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -41,17 +41,6 @@ enum ipack_space { IPACK_SPACE_COUNT, }; -/** - * struct ipack_addr_space - Virtual address space mapped for a specified type. - * - * @address: virtual address - * @size: size of the mapped space - */ -struct ipack_addr_space { - void __iomem *address; - unsigned int size; -}; - /** */ struct ipack_region { @@ -76,10 +65,6 @@ struct ipack_region { struct ipack_device { unsigned int slot; struct ipack_bus_device *bus; - struct ipack_addr_space id_space; - struct ipack_addr_space io_space; - struct ipack_addr_space int_space; - struct ipack_addr_space mem_space; struct device dev; void (*release) (struct ipack_device *dev); struct ipack_region region[IPACK_SPACE_COUNT]; @@ -135,8 +120,6 @@ struct ipack_driver { * @reset_timeout: Resets the state returned by get_timeout. */ struct ipack_bus_ops { - int (*map_space) (struct ipack_device *dev, ssize_t memory_size, int space); - int (*unmap_space) (struct ipack_device *dev, int space); int (*request_irq) (struct ipack_device *dev, irqreturn_t (*handler)(void *), void *arg); int (*free_irq) (struct ipack_device *dev); -- cgit v1.2.3 From fe4a3ed0d5ce09de5b61335ce51c74caa2a92911 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:36 +0200 Subject: staging: ipack: Rename IPACK_MEM_SPACE to IPACK_MEM8_SPACE. There also is a MEM16 space. This will make it clear which one is which, once support for MEM16 space is added. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 24 ++++++++++++------------ drivers/staging/ipack/devices/ipoctal.c | 10 +++++----- drivers/staging/ipack/ipack.h | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 901f6577406..7127a3b60b0 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -29,17 +29,17 @@ static const u16 tpci200_status_error[] = { }; static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = { - [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE, - [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE, - [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE, - [IPACK_MEM_SPACE] = TPCI200_MEM8_SPACE_SIZE, + [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE, + [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE, + [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE, + [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE, }; static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = { - [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL, - [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL, - [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL, - [IPACK_MEM_SPACE] = TPCI200_MEM8_SPACE_INTERVAL, + [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL, + [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL, + [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL, + [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL, }; static struct tpci200_board *check_slot(struct ipack_device *dev) @@ -271,12 +271,12 @@ static int tpci200_register(struct tpci200_board *tpci200) goto out_release_ip_space; } - /* Request MEM space (Bar 4) */ + /* Request MEM8 space (Bar 5) */ res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR, - "Carrier MEM space"); + "Carrier MEM8 space"); if (res) { dev_err(&tpci200->info->pdev->dev, - "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!", + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); goto out_release_ioid_int_space; @@ -297,7 +297,7 @@ static int tpci200_register(struct tpci200_board *tpci200) tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF; tpci200->mod_mem[IPACK_INT_SPACE] = ioidint_base + TPCI200_INT_SPACE_OFF; - tpci200->mod_mem[IPACK_MEM_SPACE] = + tpci200->mod_mem[IPACK_MEM8_SPACE] = pci_resource_start(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index 5ed57950b67..b6a72e6c106 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -53,7 +53,7 @@ struct ipoctal { struct ipoctal_channel channel[NR_CHANNELS]; unsigned char write; struct tty_driver *tty_drv; - u8 __iomem *mem_space; + u8 __iomem *mem8_space; u8 __iomem *int_space; }; @@ -306,13 +306,13 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, return -EADDRNOTAVAIL; } - region = &ipoctal->dev->region[IPACK_MEM_SPACE]; - ipoctal->mem_space = + region = &ipoctal->dev->region[IPACK_MEM8_SPACE]; + ipoctal->mem8_space = devm_ioremap_nocache(&ipoctal->dev->dev, region->start, 0x8000); if (!addr) { dev_err(&ipoctal->dev->dev, - "Unable to map slot [%d:%d] MEM space!\n", + "Unable to map slot [%d:%d] MEM8 space!\n", bus_nr, slot); return -EADDRNOTAVAIL; } @@ -359,7 +359,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, ipoctal->dev->bus->ops->request_irq(ipoctal->dev, ipoctal_irq_handler, ipoctal); /* Dummy write */ - iowrite8(1, ipoctal->mem_space + 1); + iowrite8(1, ipoctal->mem8_space + 1); /* Register the TTY device */ diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index af950281506..e35fe540ef0 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -34,8 +34,8 @@ struct ipack_driver; enum ipack_space { IPACK_IO_SPACE = 0, IPACK_ID_SPACE, - IPACK_MEM_SPACE, IPACK_INT_SPACE, + IPACK_MEM8_SPACE, /* Dummy for counting the number of entries. Must remain the last * entry */ IPACK_SPACE_COUNT, -- cgit v1.2.3 From 48a97352e18f6ec90355ce1ea70a3f750664adfc Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:37 +0200 Subject: staging: ipack: Add support for IPACK_MEM16_SPACE. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/tpci200.c | 19 +++++++++++++++++++ drivers/staging/ipack/ipack.h | 1 + 2 files changed, 20 insertions(+) diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c index 7127a3b60b0..376e79410e9 100644 --- a/drivers/staging/ipack/bridges/tpci200.c +++ b/drivers/staging/ipack/bridges/tpci200.c @@ -33,6 +33,7 @@ static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = { [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE, [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE, [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE, + [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE, }; static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = { @@ -40,6 +41,7 @@ static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = { [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL, [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL, [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL, + [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL, }; static struct tpci200_board *check_slot(struct ipack_device *dev) @@ -94,6 +96,7 @@ static void tpci200_unregister(struct tpci200_board *tpci200) pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR); pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR); @@ -282,6 +285,17 @@ static int tpci200_register(struct tpci200_board *tpci200) goto out_release_ioid_int_space; } + /* Request MEM16 space (Bar 4) */ + res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR, + "Carrier MEM16 space"); + if (res) { + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_mem8_space; + } + /* Map internal tpci200 driver user space */ tpci200->info->interface_regs = ioremap_nocache(pci_resource_start(tpci200->info->pdev, @@ -300,6 +314,9 @@ static int tpci200_register(struct tpci200_board *tpci200) tpci200->mod_mem[IPACK_MEM8_SPACE] = pci_resource_start(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); + tpci200->mod_mem[IPACK_MEM16_SPACE] = + pci_resource_start(tpci200->info->pdev, + TPCI200_MEM16_SPACE_BAR); /* Set the default parameters of the slot * INT0 disabled, level sensitive @@ -326,6 +343,8 @@ static int tpci200_register(struct tpci200_board *tpci200) return 0; +out_release_mem8_space: + pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); out_release_ioid_int_space: pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); out_release_ip_space: diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index e35fe540ef0..689af9239dc 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -36,6 +36,7 @@ enum ipack_space { IPACK_ID_SPACE, IPACK_INT_SPACE, IPACK_MEM8_SPACE, + IPACK_MEM16_SPACE, /* Dummy for counting the number of entries. Must remain the last * entry */ IPACK_SPACE_COUNT, -- cgit v1.2.3 From 341c92d74bd2055a6bcbb8a9f638510fe8480728 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Thu, 27 Sep 2012 12:37:38 +0200 Subject: Staging: ipack: remove blank line at EOF warning in Kconfig files Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/bridges/Kconfig | 1 - drivers/staging/ipack/devices/Kconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/staging/ipack/bridges/Kconfig b/drivers/staging/ipack/bridges/Kconfig index 97c837ea7a0..33fdc2456c0 100644 --- a/drivers/staging/ipack/bridges/Kconfig +++ b/drivers/staging/ipack/bridges/Kconfig @@ -5,4 +5,3 @@ config BOARD_TPCI200 help This driver supports the TEWS TPCI200 device for the IndustryPack bus. default n - diff --git a/drivers/staging/ipack/devices/Kconfig b/drivers/staging/ipack/devices/Kconfig index 39f71888a58..0b82fdc198c 100644 --- a/drivers/staging/ipack/devices/Kconfig +++ b/drivers/staging/ipack/devices/Kconfig @@ -4,4 +4,3 @@ config SERIAL_IPOCTAL help This driver supports the IPOCTAL serial port device for the IndustryPack bus. default n - -- cgit v1.2.3 From 052c4cfc92f5ce6334fdaf6926e7c177bc1cc099 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:39 +0200 Subject: staging: ipack: Rename bridges to carriers. This is the name used by the standard. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/Kconfig | 2 +- drivers/staging/ipack/Makefile | 2 +- drivers/staging/ipack/bridges/Kconfig | 7 - drivers/staging/ipack/bridges/Makefile | 1 - drivers/staging/ipack/bridges/tpci200.c | 634 ------------------------------- drivers/staging/ipack/bridges/tpci200.h | 167 -------- drivers/staging/ipack/carriers/Kconfig | 7 + drivers/staging/ipack/carriers/Makefile | 1 + drivers/staging/ipack/carriers/tpci200.c | 634 +++++++++++++++++++++++++++++++ drivers/staging/ipack/carriers/tpci200.h | 167 ++++++++ 10 files changed, 811 insertions(+), 811 deletions(-) delete mode 100644 drivers/staging/ipack/bridges/Kconfig delete mode 100644 drivers/staging/ipack/bridges/Makefile delete mode 100644 drivers/staging/ipack/bridges/tpci200.c delete mode 100644 drivers/staging/ipack/bridges/tpci200.h create mode 100644 drivers/staging/ipack/carriers/Kconfig create mode 100644 drivers/staging/ipack/carriers/Makefile create mode 100644 drivers/staging/ipack/carriers/tpci200.c create mode 100644 drivers/staging/ipack/carriers/tpci200.h diff --git a/drivers/staging/ipack/Kconfig b/drivers/staging/ipack/Kconfig index 4cf47066140..9b4495a35f9 100644 --- a/drivers/staging/ipack/Kconfig +++ b/drivers/staging/ipack/Kconfig @@ -14,7 +14,7 @@ menuconfig IPACK_BUS if IPACK_BUS -source "drivers/staging/ipack/bridges/Kconfig" +source "drivers/staging/ipack/carriers/Kconfig" source "drivers/staging/ipack/devices/Kconfig" diff --git a/drivers/staging/ipack/Makefile b/drivers/staging/ipack/Makefile index 85ff223616f..6f14ade0f8f 100644 --- a/drivers/staging/ipack/Makefile +++ b/drivers/staging/ipack/Makefile @@ -3,4 +3,4 @@ # obj-$(CONFIG_IPACK_BUS) += ipack.o obj-y += devices/ -obj-y += bridges/ +obj-y += carriers/ diff --git a/drivers/staging/ipack/bridges/Kconfig b/drivers/staging/ipack/bridges/Kconfig deleted file mode 100644 index 33fdc2456c0..00000000000 --- a/drivers/staging/ipack/bridges/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -config BOARD_TPCI200 - tristate "TEWS TPCI-200 support for IndustryPack bus" - depends on IPACK_BUS - depends on PCI - help - This driver supports the TEWS TPCI200 device for the IndustryPack bus. - default n diff --git a/drivers/staging/ipack/bridges/Makefile b/drivers/staging/ipack/bridges/Makefile deleted file mode 100644 index d8b76459300..00000000000 --- a/drivers/staging/ipack/bridges/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_BOARD_TPCI200) += tpci200.o diff --git a/drivers/staging/ipack/bridges/tpci200.c b/drivers/staging/ipack/bridges/tpci200.c deleted file mode 100644 index 376e79410e9..00000000000 --- a/drivers/staging/ipack/bridges/tpci200.c +++ /dev/null @@ -1,634 +0,0 @@ -/** - * tpci200.c - * - * driver for the TEWS TPCI-200 device - * Copyright (c) 2009 Nicolas Serafini, EIC2 SA - * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN - * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia - * - * 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; version 2 of the License. - */ - -#include -#include "tpci200.h" - -static const u16 tpci200_status_timeout[] = { - TPCI200_A_TIMEOUT, - TPCI200_B_TIMEOUT, - TPCI200_C_TIMEOUT, - TPCI200_D_TIMEOUT, -}; - -static const u16 tpci200_status_error[] = { - TPCI200_A_ERROR, - TPCI200_B_ERROR, - TPCI200_C_ERROR, - TPCI200_D_ERROR, -}; - -static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = { - [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE, - [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE, - [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE, - [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE, - [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE, -}; - -static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = { - [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL, - [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL, - [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL, - [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL, - [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL, -}; - -static struct tpci200_board *check_slot(struct ipack_device *dev) -{ - struct tpci200_board *tpci200; - - if (dev == NULL) - return NULL; - - - tpci200 = dev_get_drvdata(dev->bus->parent); - - if (tpci200 == NULL) { - dev_info(&dev->dev, "carrier board not found\n"); - return NULL; - } - - if (dev->slot >= TPCI200_NB_SLOT) { - dev_info(&dev->dev, - "Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n", - dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1); - return NULL; - } - - return tpci200; -} - -static void tpci200_clear_mask(struct tpci200_board *tpci200, - __le16 __iomem *addr, u16 mask) -{ - unsigned long flags; - spin_lock_irqsave(&tpci200->regs_lock, flags); - iowrite16(ioread16(addr) & (~mask), addr); - spin_unlock_irqrestore(&tpci200->regs_lock, flags); -} - -static void tpci200_set_mask(struct tpci200_board *tpci200, - __le16 __iomem *addr, u16 mask) -{ - unsigned long flags; - spin_lock_irqsave(&tpci200->regs_lock, flags); - iowrite16(ioread16(addr) | mask, addr); - spin_unlock_irqrestore(&tpci200->regs_lock, flags); -} - -static void tpci200_unregister(struct tpci200_board *tpci200) -{ - free_irq(tpci200->info->pdev->irq, (void *) tpci200); - - pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); - pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs); - - pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); - pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); - pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR); - pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); - pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR); - - pci_disable_device(tpci200->info->pdev); - pci_dev_put(tpci200->info->pdev); -} - -static void tpci200_enable_irq(struct tpci200_board *tpci200, - int islot) -{ - tpci200_set_mask(tpci200, - &tpci200->info->interface_regs->control[islot], - TPCI200_INT0_EN | TPCI200_INT1_EN); -} - -static void tpci200_disable_irq(struct tpci200_board *tpci200, - int islot) -{ - tpci200_clear_mask(tpci200, - &tpci200->info->interface_regs->control[islot], - TPCI200_INT0_EN | TPCI200_INT1_EN); -} - -static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq) -{ - irqreturn_t ret; - - if (!slot_irq) - return -ENODEV; - ret = slot_irq->handler(slot_irq->arg); - - return ret; -} - -static irqreturn_t tpci200_interrupt(int irq, void *dev_id) -{ - struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; - struct slot_irq *slot_irq; - irqreturn_t ret; - u16 status_reg; - int i; - - /* Read status register */ - status_reg = ioread16(&tpci200->info->interface_regs->status); - - /* Did we cause the interrupt? */ - if (!(status_reg & TPCI200_SLOT_INT_MASK)) - return IRQ_NONE; - - /* callback to the IRQ handler for the corresponding slot */ - rcu_read_lock(); - for (i = 0; i < TPCI200_NB_SLOT; i++) { - if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2 * i)))) - continue; - slot_irq = rcu_dereference(tpci200->slots[i].irq); - ret = tpci200_slot_irq(slot_irq); - if (ret == -ENODEV) { - dev_info(&tpci200->info->pdev->dev, - "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", - tpci200->number, i); - tpci200_disable_irq(tpci200, i); - } - } - rcu_read_unlock(); - - return IRQ_HANDLED; -} - -static int tpci200_free_irq(struct ipack_device *dev) -{ - struct slot_irq *slot_irq; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - if (mutex_lock_interruptible(&tpci200->mutex)) - return -ERESTARTSYS; - - if (tpci200->slots[dev->slot].irq == NULL) { - mutex_unlock(&tpci200->mutex); - return -EINVAL; - } - - tpci200_disable_irq(tpci200, dev->slot); - slot_irq = tpci200->slots[dev->slot].irq; - /* uninstall handler */ - RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL); - synchronize_rcu(); - kfree(slot_irq); - mutex_unlock(&tpci200->mutex); - return 0; -} - -static int tpci200_request_irq(struct ipack_device *dev, - irqreturn_t (*handler)(void *), void *arg) -{ - int res = 0; - struct slot_irq *slot_irq; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - if (mutex_lock_interruptible(&tpci200->mutex)) - return -ERESTARTSYS; - - if (tpci200->slots[dev->slot].irq != NULL) { - dev_err(&dev->dev, - "Slot [%d:%d] IRQ already registered !\n", dev->bus->bus_nr, - dev->slot); - res = -EINVAL; - goto out_unlock; - } - - slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL); - if (slot_irq == NULL) { - dev_err(&dev->dev, - "Slot [%d:%d] unable to allocate memory for IRQ !\n", - dev->bus->bus_nr, dev->slot); - res = -ENOMEM; - goto out_unlock; - } - - /* - * WARNING: Setup Interrupt Vector in the IndustryPack device - * before an IRQ request. - * Read the User Manual of your IndustryPack device to know - * where to write the vector in memory. - */ - slot_irq->handler = handler; - slot_irq->arg = arg; - slot_irq->holder = dev; - - rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq); - tpci200_enable_irq(tpci200, dev->slot); - -out_unlock: - mutex_unlock(&tpci200->mutex); - return res; -} - -static int tpci200_register(struct tpci200_board *tpci200) -{ - int i; - int res; - phys_addr_t ioidint_base; - unsigned short slot_ctrl; - - if (pci_enable_device(tpci200->info->pdev) < 0) - return -ENODEV; - - /* Request IP interface register (Bar 2) */ - res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR, - "Carrier IP interface registers"); - if (res) { - dev_err(&tpci200->info->pdev->dev, - "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); - goto out_disable_pci; - } - - /* Request IO ID INT space (Bar 3) */ - res = pci_request_region(tpci200->info->pdev, - TPCI200_IO_ID_INT_SPACES_BAR, - "Carrier IO ID INT space"); - if (res) { - dev_err(&tpci200->info->pdev->dev, - "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); - goto out_release_ip_space; - } - - /* Request MEM8 space (Bar 5) */ - res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR, - "Carrier MEM8 space"); - if (res) { - dev_err(&tpci200->info->pdev->dev, - "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); - goto out_release_ioid_int_space; - } - - /* Request MEM16 space (Bar 4) */ - res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR, - "Carrier MEM16 space"); - if (res) { - dev_err(&tpci200->info->pdev->dev, - "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); - goto out_release_mem8_space; - } - - /* Map internal tpci200 driver user space */ - tpci200->info->interface_regs = - ioremap_nocache(pci_resource_start(tpci200->info->pdev, - TPCI200_IP_INTERFACE_BAR), - TPCI200_IFACE_SIZE); - - /* Initialize lock that protects interface_regs */ - spin_lock_init(&tpci200->regs_lock); - - ioidint_base = pci_resource_start(tpci200->info->pdev, - TPCI200_IO_ID_INT_SPACES_BAR); - tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF; - tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF; - tpci200->mod_mem[IPACK_INT_SPACE] = - ioidint_base + TPCI200_INT_SPACE_OFF; - tpci200->mod_mem[IPACK_MEM8_SPACE] = - pci_resource_start(tpci200->info->pdev, - TPCI200_MEM8_SPACE_BAR); - tpci200->mod_mem[IPACK_MEM16_SPACE] = - pci_resource_start(tpci200->info->pdev, - TPCI200_MEM16_SPACE_BAR); - - /* Set the default parameters of the slot - * INT0 disabled, level sensitive - * INT1 disabled, level sensitive - * error interrupt disabled - * timeout interrupt disabled - * recover time disabled - * clock rate 8 MHz - */ - slot_ctrl = 0; - for (i = 0; i < TPCI200_NB_SLOT; i++) - writew(slot_ctrl, &tpci200->info->interface_regs->control[i]); - - res = request_irq(tpci200->info->pdev->irq, - tpci200_interrupt, IRQF_SHARED, - KBUILD_MODNAME, (void *) tpci200); - if (res) { - dev_err(&tpci200->info->pdev->dev, - "(bn 0x%X, sn 0x%X) unable to register IRQ !", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); - goto out_release_ioid_int_space; - } - - return 0; - -out_release_mem8_space: - pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); -out_release_ioid_int_space: - pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); -out_release_ip_space: - pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); -out_disable_pci: - pci_disable_device(tpci200->info->pdev); - return res; -} - -static int tpci200_get_clockrate(struct ipack_device *dev) -{ - struct tpci200_board *tpci200 = check_slot(dev); - __le16 __iomem *addr; - - if (!tpci200) - return -ENODEV; - - addr = &tpci200->info->interface_regs->control[dev->slot]; - return (ioread16(addr) & TPCI200_CLK32) ? 32 : 8; -} - -static int tpci200_set_clockrate(struct ipack_device *dev, int mherz) -{ - struct tpci200_board *tpci200 = check_slot(dev); - __le16 __iomem *addr; - - if (!tpci200) - return -ENODEV; - - addr = &tpci200->info->interface_regs->control[dev->slot]; - - switch (mherz) { - case 8: - tpci200_clear_mask(tpci200, addr, TPCI200_CLK32); - break; - case 32: - tpci200_set_mask(tpci200, addr, TPCI200_CLK32); - break; - default: - return -EINVAL; - } - return 0; -} - -static int tpci200_get_error(struct ipack_device *dev) -{ - struct tpci200_board *tpci200 = check_slot(dev); - __le16 __iomem *addr; - u16 mask; - - if (!tpci200) - return -ENODEV; - - addr = &tpci200->info->interface_regs->status; - mask = tpci200_status_error[dev->slot]; - return (ioread16(addr) & mask) ? 1 : 0; -} - -static int tpci200_get_timeout(struct ipack_device *dev) -{ - struct tpci200_board *tpci200 = check_slot(dev); - __le16 __iomem *addr; - u16 mask; - - if (!tpci200) - return -ENODEV; - - addr = &tpci200->info->interface_regs->status; - mask = tpci200_status_timeout[dev->slot]; - - return (ioread16(addr) & mask) ? 1 : 0; -} - -static int tpci200_reset_timeout(struct ipack_device *dev) -{ - struct tpci200_board *tpci200 = check_slot(dev); - __le16 __iomem *addr; - u16 mask; - - if (!tpci200) - return -ENODEV; - - addr = &tpci200->info->interface_regs->status; - mask = tpci200_status_timeout[dev->slot]; - - iowrite16(mask, addr); - return 0; -} - -static void tpci200_uninstall(struct tpci200_board *tpci200) -{ - tpci200_unregister(tpci200); - kfree(tpci200->slots); -} - -static const struct ipack_bus_ops tpci200_bus_ops = { - .request_irq = tpci200_request_irq, - .free_irq = tpci200_free_irq, - .get_clockrate = tpci200_get_clockrate, - .set_clockrate = tpci200_set_clockrate, - .get_error = tpci200_get_error, - .get_timeout = tpci200_get_timeout, - .reset_timeout = tpci200_reset_timeout, -}; - -static int tpci200_install(struct tpci200_board *tpci200) -{ - int res; - - tpci200->slots = kzalloc( - TPCI200_NB_SLOT * sizeof(struct tpci200_slot), GFP_KERNEL); - if (tpci200->slots == NULL) - return -ENOMEM; - - res = tpci200_register(tpci200); - if (res) { - kfree(tpci200->slots); - tpci200->slots = NULL; - return res; - } - - mutex_init(&tpci200->mutex); - return 0; -} - -static void tpci200_release_device(struct ipack_device *dev) -{ - kfree(dev); -} - -static int tpci200_create_device(struct tpci200_board *tpci200, int i) -{ - enum ipack_space space; - struct ipack_device *dev = - kzalloc(sizeof(struct ipack_device), GFP_KERNEL); - if (!dev) - return -ENOMEM; - dev->slot = i; - dev->bus = tpci200->info->ipack_bus; - dev->release = tpci200_release_device; - - for (space = 0; space < IPACK_SPACE_COUNT; space++) { - dev->region[space].start = - tpci200->mod_mem[space] - + tpci200_space_interval[space] * i; - dev->region[space].size = tpci200_space_size[space]; - } - return ipack_device_register(dev); -} - -static int tpci200_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - int ret, i; - struct tpci200_board *tpci200; - u32 reg32; - - tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL); - if (!tpci200) - return -ENOMEM; - - tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL); - if (!tpci200->info) { - ret = -ENOMEM; - goto out_err_info; - } - - pci_dev_get(pdev); - - /* Obtain a mapping of the carrier's PCI configuration registers */ - ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR, - KBUILD_MODNAME " Configuration Memory"); - if (ret) { - dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory"); - ret = -EBUSY; - goto out_err_pci_request; - } - tpci200->info->cfg_regs = ioremap_nocache( - pci_resource_start(pdev, TPCI200_CFG_MEM_BAR), - pci_resource_len(pdev, TPCI200_CFG_MEM_BAR)); - if (!tpci200->info->cfg_regs) { - dev_err(&pdev->dev, "Failed to map PCI Configuration Memory"); - ret = -EFAULT; - goto out_err_ioremap; - } - - /* Disable byte swapping for 16 bit IP module access. This will ensure - * that the Industrypack big endian byte order is preserved by the - * carrier. */ - reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC); - reg32 |= 1 << LAS_BIT_BIGENDIAN; - iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC); - - reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC); - reg32 |= 1 << LAS_BIT_BIGENDIAN; - iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC); - - /* Save struct pci_dev pointer */ - tpci200->info->pdev = pdev; - tpci200->info->id_table = (struct pci_device_id *)id; - - /* register the device and initialize it */ - ret = tpci200_install(tpci200); - if (ret) { - dev_err(&pdev->dev, "error during tpci200 install\n"); - ret = -ENODEV; - goto out_err_install; - } - - /* Register the carrier in the industry pack bus driver */ - tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev, - TPCI200_NB_SLOT, - &tpci200_bus_ops); - if (!tpci200->info->ipack_bus) { - dev_err(&pdev->dev, - "error registering the carrier on ipack driver\n"); - ret = -EFAULT; - goto out_err_bus_register; - } - - /* save the bus number given by ipack to logging purpose */ - tpci200->number = tpci200->info->ipack_bus->bus_nr; - dev_set_drvdata(&pdev->dev, tpci200); - - for (i = 0; i < TPCI200_NB_SLOT; i++) - tpci200_create_device(tpci200, i); - return 0; - -out_err_bus_register: - tpci200_uninstall(tpci200); -out_err_install: - iounmap(tpci200->info->cfg_regs); -out_err_ioremap: - pci_release_region(pdev, TPCI200_CFG_MEM_BAR); -out_err_pci_request: - pci_dev_put(pdev); - kfree(tpci200->info); -out_err_info: - kfree(tpci200); - return ret; -} - -static void __tpci200_pci_remove(struct tpci200_board *tpci200) -{ - ipack_bus_unregister(tpci200->info->ipack_bus); - tpci200_uninstall(tpci200); - - kfree(tpci200->info); - kfree(tpci200); -} - -static void __devexit tpci200_pci_remove(struct pci_dev *dev) -{ - struct tpci200_board *tpci200 = pci_get_drvdata(dev); - - __tpci200_pci_remove(tpci200); -} - -static DEFINE_PCI_DEVICE_TABLE(tpci200_idtable) = { - { TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID, - TPCI200_SUBDEVICE_ID }, - { 0, }, -}; - -MODULE_DEVICE_TABLE(pci, tpci200_idtable); - -static struct pci_driver tpci200_pci_drv = { - .name = "tpci200", - .id_table = tpci200_idtable, - .probe = tpci200_pci_probe, - .remove = __devexit_p(tpci200_pci_remove), -}; - -static int __init tpci200_drvr_init_module(void) -{ - return pci_register_driver(&tpci200_pci_drv); -} - -static void __exit tpci200_drvr_exit_module(void) -{ - pci_unregister_driver(&tpci200_pci_drv); -} - -MODULE_DESCRIPTION("TEWS TPCI-200 device driver"); -MODULE_LICENSE("GPL"); -module_init(tpci200_drvr_init_module); -module_exit(tpci200_drvr_exit_module); diff --git a/drivers/staging/ipack/bridges/tpci200.h b/drivers/staging/ipack/bridges/tpci200.h deleted file mode 100644 index 982f31920af..00000000000 --- a/drivers/staging/ipack/bridges/tpci200.h +++ /dev/null @@ -1,167 +0,0 @@ -/** - * tpci200.h - * - * driver for the carrier TEWS TPCI-200 - * Copyright (c) 2009 Nicolas Serafini, EIC2 SA - * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN - * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia - * - * 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; version 2 of the License. - */ - -#ifndef _TPCI200_H_ -#define _TPCI200_H_ - -#include -#include -#include -#include -#include - -#include "../ipack.h" - -#define TPCI200_NB_SLOT 0x4 -#define TPCI200_NB_BAR 0x6 - -#define TPCI200_VENDOR_ID 0x1498 -#define TPCI200_DEVICE_ID 0x30C8 -#define TPCI200_SUBVENDOR_ID 0x1498 -#define TPCI200_SUBDEVICE_ID 0x300A - -#define TPCI200_CFG_MEM_BAR 0 -#define TPCI200_IP_INTERFACE_BAR 2 -#define TPCI200_IO_ID_INT_SPACES_BAR 3 -#define TPCI200_MEM16_SPACE_BAR 4 -#define TPCI200_MEM8_SPACE_BAR 5 - -struct tpci200_regs { - __le16 revision; - /* writes to control should occur with the mutex held to protect - * read-modify-write operations */ - __le16 control[4]; - __le16 reset; - __le16 status; - u8 reserved[242]; -} __packed; - -#define TPCI200_IFACE_SIZE 0x100 - -#define TPCI200_IO_SPACE_OFF 0x0000 -#define TPCI200_IO_SPACE_INTERVAL 0x0100 -#define TPCI200_IO_SPACE_SIZE 0x0080 -#define TPCI200_ID_SPACE_OFF 0x0080 -#define TPCI200_ID_SPACE_INTERVAL 0x0100 -#define TPCI200_ID_SPACE_SIZE 0x0040 -#define TPCI200_INT_SPACE_OFF 0x00C0 -#define TPCI200_INT_SPACE_INTERVAL 0x0100 -#define TPCI200_INT_SPACE_SIZE 0x0040 -#define TPCI200_IOIDINT_SIZE 0x0400 - -#define TPCI200_MEM8_SPACE_INTERVAL 0x00400000 -#define TPCI200_MEM8_SPACE_SIZE 0x00400000 -#define TPCI200_MEM16_SPACE_INTERVAL 0x00800000 -#define TPCI200_MEM16_SPACE_SIZE 0x00800000 - -/* control field in tpci200_regs */ -#define TPCI200_INT0_EN 0x0040 -#define TPCI200_INT1_EN 0x0080 -#define TPCI200_INT0_EDGE 0x0010 -#define TPCI200_INT1_EDGE 0x0020 -#define TPCI200_ERR_INT_EN 0x0008 -#define TPCI200_TIME_INT_EN 0x0004 -#define TPCI200_RECOVER_EN 0x0002 -#define TPCI200_CLK32 0x0001 - -/* reset field in tpci200_regs */ -#define TPCI200_A_RESET 0x0001 -#define TPCI200_B_RESET 0x0002 -#define TPCI200_C_RESET 0x0004 -#define TPCI200_D_RESET 0x0008 - -/* status field in tpci200_regs */ -#define TPCI200_A_TIMEOUT 0x1000 -#define TPCI200_B_TIMEOUT 0x2000 -#define TPCI200_C_TIMEOUT 0x4000 -#define TPCI200_D_TIMEOUT 0x8000 - -#define TPCI200_A_ERROR 0x0100 -#define TPCI200_B_ERROR 0x0200 -#define TPCI200_C_ERROR 0x0400 -#define TPCI200_D_ERROR 0x0800 - -#define TPCI200_A_INT0 0x0001 -#define TPCI200_A_INT1 0x0002 -#define TPCI200_B_INT0 0x0004 -#define TPCI200_B_INT1 0x0008 -#define TPCI200_C_INT0 0x0010 -#define TPCI200_C_INT1 0x0020 -#define TPCI200_D_INT0 0x0040 -#define TPCI200_D_INT1 0x0080 - -#define TPCI200_SLOT_INT_MASK 0x00FF - -/* PCI Configuration registers. The PCI bridge is a PLX Technology PCI9030. */ -#define LAS1_DESC 0x2C -#define LAS2_DESC 0x30 - -/* Bits in the LAS?_DESC registers */ -#define LAS_BIT_BIGENDIAN 24 - -#define VME_IOID_SPACE "IOID" -#define VME_MEM_SPACE "MEM" - -/** - * struct slot_irq - slot IRQ definition. - * @vector Vector number - * @handler Handler called when IRQ arrives - * @arg Handler argument - * - */ -struct slot_irq { - struct ipack_device *holder; - int vector; - irqreturn_t (*handler)(void *); - void *arg; -}; - -/** - * struct tpci200_slot - data specific to the tpci200 slot. - * @slot_id Slot identification gived to external interface - * @irq Slot IRQ infos - * @io_phys IO physical base address register of the slot - * @id_phys ID physical base address register of the slot - * @int_phys INT physical base address register of the slot - * @mem_phys MEM physical base address register of the slot - * - */ -struct tpci200_slot { - struct slot_irq *irq; -}; - -/** - * struct tpci200_infos - informations specific of the TPCI200 tpci200. - * @pci_dev PCI device - * @interface_regs Pointer to IP interface space (Bar 2) - * @ioidint_space Pointer to IP ID, IO and INT space (Bar 3) - * @mem8_space Pointer to MEM space (Bar 4) - * - */ -struct tpci200_infos { - struct pci_dev *pdev; - struct pci_device_id *id_table; - struct tpci200_regs __iomem *interface_regs; - void __iomem *cfg_regs; - struct ipack_bus_device *ipack_bus; -}; -struct tpci200_board { - unsigned int number; - struct mutex mutex; - spinlock_t regs_lock; - struct tpci200_slot *slots; - struct tpci200_infos *info; - phys_addr_t mod_mem[IPACK_SPACE_COUNT]; -}; - -#endif /* _TPCI200_H_ */ diff --git a/drivers/staging/ipack/carriers/Kconfig b/drivers/staging/ipack/carriers/Kconfig new file mode 100644 index 00000000000..33fdc2456c0 --- /dev/null +++ b/drivers/staging/ipack/carriers/Kconfig @@ -0,0 +1,7 @@ +config BOARD_TPCI200 + tristate "TEWS TPCI-200 support for IndustryPack bus" + depends on IPACK_BUS + depends on PCI + help + This driver supports the TEWS TPCI200 device for the IndustryPack bus. + default n diff --git a/drivers/staging/ipack/carriers/Makefile b/drivers/staging/ipack/carriers/Makefile new file mode 100644 index 00000000000..d8b76459300 --- /dev/null +++ b/drivers/staging/ipack/carriers/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_BOARD_TPCI200) += tpci200.o diff --git a/drivers/staging/ipack/carriers/tpci200.c b/drivers/staging/ipack/carriers/tpci200.c new file mode 100644 index 00000000000..376e79410e9 --- /dev/null +++ b/drivers/staging/ipack/carriers/tpci200.c @@ -0,0 +1,634 @@ +/** + * tpci200.c + * + * driver for the TEWS TPCI-200 device + * Copyright (c) 2009 Nicolas Serafini, EIC2 SA + * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN + * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * 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; version 2 of the License. + */ + +#include +#include "tpci200.h" + +static const u16 tpci200_status_timeout[] = { + TPCI200_A_TIMEOUT, + TPCI200_B_TIMEOUT, + TPCI200_C_TIMEOUT, + TPCI200_D_TIMEOUT, +}; + +static const u16 tpci200_status_error[] = { + TPCI200_A_ERROR, + TPCI200_B_ERROR, + TPCI200_C_ERROR, + TPCI200_D_ERROR, +}; + +static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = { + [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE, + [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE, + [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE, + [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE, + [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE, +}; + +static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = { + [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL, + [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL, + [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL, + [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL, + [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL, +}; + +static struct tpci200_board *check_slot(struct ipack_device *dev) +{ + struct tpci200_board *tpci200; + + if (dev == NULL) + return NULL; + + + tpci200 = dev_get_drvdata(dev->bus->parent); + + if (tpci200 == NULL) { + dev_info(&dev->dev, "carrier board not found\n"); + return NULL; + } + + if (dev->slot >= TPCI200_NB_SLOT) { + dev_info(&dev->dev, + "Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n", + dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1); + return NULL; + } + + return tpci200; +} + +static void tpci200_clear_mask(struct tpci200_board *tpci200, + __le16 __iomem *addr, u16 mask) +{ + unsigned long flags; + spin_lock_irqsave(&tpci200->regs_lock, flags); + iowrite16(ioread16(addr) & (~mask), addr); + spin_unlock_irqrestore(&tpci200->regs_lock, flags); +} + +static void tpci200_set_mask(struct tpci200_board *tpci200, + __le16 __iomem *addr, u16 mask) +{ + unsigned long flags; + spin_lock_irqsave(&tpci200->regs_lock, flags); + iowrite16(ioread16(addr) | mask, addr); + spin_unlock_irqrestore(&tpci200->regs_lock, flags); +} + +static void tpci200_unregister(struct tpci200_board *tpci200) +{ + free_irq(tpci200->info->pdev->irq, (void *) tpci200); + + pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); + pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs); + + pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR); + + pci_disable_device(tpci200->info->pdev); + pci_dev_put(tpci200->info->pdev); +} + +static void tpci200_enable_irq(struct tpci200_board *tpci200, + int islot) +{ + tpci200_set_mask(tpci200, + &tpci200->info->interface_regs->control[islot], + TPCI200_INT0_EN | TPCI200_INT1_EN); +} + +static void tpci200_disable_irq(struct tpci200_board *tpci200, + int islot) +{ + tpci200_clear_mask(tpci200, + &tpci200->info->interface_regs->control[islot], + TPCI200_INT0_EN | TPCI200_INT1_EN); +} + +static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq) +{ + irqreturn_t ret; + + if (!slot_irq) + return -ENODEV; + ret = slot_irq->handler(slot_irq->arg); + + return ret; +} + +static irqreturn_t tpci200_interrupt(int irq, void *dev_id) +{ + struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; + struct slot_irq *slot_irq; + irqreturn_t ret; + u16 status_reg; + int i; + + /* Read status register */ + status_reg = ioread16(&tpci200->info->interface_regs->status); + + /* Did we cause the interrupt? */ + if (!(status_reg & TPCI200_SLOT_INT_MASK)) + return IRQ_NONE; + + /* callback to the IRQ handler for the corresponding slot */ + rcu_read_lock(); + for (i = 0; i < TPCI200_NB_SLOT; i++) { + if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2 * i)))) + continue; + slot_irq = rcu_dereference(tpci200->slots[i].irq); + ret = tpci200_slot_irq(slot_irq); + if (ret == -ENODEV) { + dev_info(&tpci200->info->pdev->dev, + "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", + tpci200->number, i); + tpci200_disable_irq(tpci200, i); + } + } + rcu_read_unlock(); + + return IRQ_HANDLED; +} + +static int tpci200_free_irq(struct ipack_device *dev) +{ + struct slot_irq *slot_irq; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + if (mutex_lock_interruptible(&tpci200->mutex)) + return -ERESTARTSYS; + + if (tpci200->slots[dev->slot].irq == NULL) { + mutex_unlock(&tpci200->mutex); + return -EINVAL; + } + + tpci200_disable_irq(tpci200, dev->slot); + slot_irq = tpci200->slots[dev->slot].irq; + /* uninstall handler */ + RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL); + synchronize_rcu(); + kfree(slot_irq); + mutex_unlock(&tpci200->mutex); + return 0; +} + +static int tpci200_request_irq(struct ipack_device *dev, + irqreturn_t (*handler)(void *), void *arg) +{ + int res = 0; + struct slot_irq *slot_irq; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + if (mutex_lock_interruptible(&tpci200->mutex)) + return -ERESTARTSYS; + + if (tpci200->slots[dev->slot].irq != NULL) { + dev_err(&dev->dev, + "Slot [%d:%d] IRQ already registered !\n", dev->bus->bus_nr, + dev->slot); + res = -EINVAL; + goto out_unlock; + } + + slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL); + if (slot_irq == NULL) { + dev_err(&dev->dev, + "Slot [%d:%d] unable to allocate memory for IRQ !\n", + dev->bus->bus_nr, dev->slot); + res = -ENOMEM; + goto out_unlock; + } + + /* + * WARNING: Setup Interrupt Vector in the IndustryPack device + * before an IRQ request. + * Read the User Manual of your IndustryPack device to know + * where to write the vector in memory. + */ + slot_irq->handler = handler; + slot_irq->arg = arg; + slot_irq->holder = dev; + + rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq); + tpci200_enable_irq(tpci200, dev->slot); + +out_unlock: + mutex_unlock(&tpci200->mutex); + return res; +} + +static int tpci200_register(struct tpci200_board *tpci200) +{ + int i; + int res; + phys_addr_t ioidint_base; + unsigned short slot_ctrl; + + if (pci_enable_device(tpci200->info->pdev) < 0) + return -ENODEV; + + /* Request IP interface register (Bar 2) */ + res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR, + "Carrier IP interface registers"); + if (res) { + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_disable_pci; + } + + /* Request IO ID INT space (Bar 3) */ + res = pci_request_region(tpci200->info->pdev, + TPCI200_IO_ID_INT_SPACES_BAR, + "Carrier IO ID INT space"); + if (res) { + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_ip_space; + } + + /* Request MEM8 space (Bar 5) */ + res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR, + "Carrier MEM8 space"); + if (res) { + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_ioid_int_space; + } + + /* Request MEM16 space (Bar 4) */ + res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR, + "Carrier MEM16 space"); + if (res) { + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_mem8_space; + } + + /* Map internal tpci200 driver user space */ + tpci200->info->interface_regs = + ioremap_nocache(pci_resource_start(tpci200->info->pdev, + TPCI200_IP_INTERFACE_BAR), + TPCI200_IFACE_SIZE); + + /* Initialize lock that protects interface_regs */ + spin_lock_init(&tpci200->regs_lock); + + ioidint_base = pci_resource_start(tpci200->info->pdev, + TPCI200_IO_ID_INT_SPACES_BAR); + tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF; + tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF; + tpci200->mod_mem[IPACK_INT_SPACE] = + ioidint_base + TPCI200_INT_SPACE_OFF; + tpci200->mod_mem[IPACK_MEM8_SPACE] = + pci_resource_start(tpci200->info->pdev, + TPCI200_MEM8_SPACE_BAR); + tpci200->mod_mem[IPACK_MEM16_SPACE] = + pci_resource_start(tpci200->info->pdev, + TPCI200_MEM16_SPACE_BAR); + + /* Set the default parameters of the slot + * INT0 disabled, level sensitive + * INT1 disabled, level sensitive + * error interrupt disabled + * timeout interrupt disabled + * recover time disabled + * clock rate 8 MHz + */ + slot_ctrl = 0; + for (i = 0; i < TPCI200_NB_SLOT; i++) + writew(slot_ctrl, &tpci200->info->interface_regs->control[i]); + + res = request_irq(tpci200->info->pdev->irq, + tpci200_interrupt, IRQF_SHARED, + KBUILD_MODNAME, (void *) tpci200); + if (res) { + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) unable to register IRQ !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_ioid_int_space; + } + + return 0; + +out_release_mem8_space: + pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); +out_release_ioid_int_space: + pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); +out_release_ip_space: + pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); +out_disable_pci: + pci_disable_device(tpci200->info->pdev); + return res; +} + +static int tpci200_get_clockrate(struct ipack_device *dev) +{ + struct tpci200_board *tpci200 = check_slot(dev); + __le16 __iomem *addr; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->control[dev->slot]; + return (ioread16(addr) & TPCI200_CLK32) ? 32 : 8; +} + +static int tpci200_set_clockrate(struct ipack_device *dev, int mherz) +{ + struct tpci200_board *tpci200 = check_slot(dev); + __le16 __iomem *addr; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->control[dev->slot]; + + switch (mherz) { + case 8: + tpci200_clear_mask(tpci200, addr, TPCI200_CLK32); + break; + case 32: + tpci200_set_mask(tpci200, addr, TPCI200_CLK32); + break; + default: + return -EINVAL; + } + return 0; +} + +static int tpci200_get_error(struct ipack_device *dev) +{ + struct tpci200_board *tpci200 = check_slot(dev); + __le16 __iomem *addr; + u16 mask; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->status; + mask = tpci200_status_error[dev->slot]; + return (ioread16(addr) & mask) ? 1 : 0; +} + +static int tpci200_get_timeout(struct ipack_device *dev) +{ + struct tpci200_board *tpci200 = check_slot(dev); + __le16 __iomem *addr; + u16 mask; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->status; + mask = tpci200_status_timeout[dev->slot]; + + return (ioread16(addr) & mask) ? 1 : 0; +} + +static int tpci200_reset_timeout(struct ipack_device *dev) +{ + struct tpci200_board *tpci200 = check_slot(dev); + __le16 __iomem *addr; + u16 mask; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->status; + mask = tpci200_status_timeout[dev->slot]; + + iowrite16(mask, addr); + return 0; +} + +static void tpci200_uninstall(struct tpci200_board *tpci200) +{ + tpci200_unregister(tpci200); + kfree(tpci200->slots); +} + +static const struct ipack_bus_ops tpci200_bus_ops = { + .request_irq = tpci200_request_irq, + .free_irq = tpci200_free_irq, + .get_clockrate = tpci200_get_clockrate, + .set_clockrate = tpci200_set_clockrate, + .get_error = tpci200_get_error, + .get_timeout = tpci200_get_timeout, + .reset_timeout = tpci200_reset_timeout, +}; + +static int tpci200_install(struct tpci200_board *tpci200) +{ + int res; + + tpci200->slots = kzalloc( + TPCI200_NB_SLOT * sizeof(struct tpci200_slot), GFP_KERNEL); + if (tpci200->slots == NULL) + return -ENOMEM; + + res = tpci200_register(tpci200); + if (res) { + kfree(tpci200->slots); + tpci200->slots = NULL; + return res; + } + + mutex_init(&tpci200->mutex); + return 0; +} + +static void tpci200_release_device(struct ipack_device *dev) +{ + kfree(dev); +} + +static int tpci200_create_device(struct tpci200_board *tpci200, int i) +{ + enum ipack_space space; + struct ipack_device *dev = + kzalloc(sizeof(struct ipack_device), GFP_KERNEL); + if (!dev) + return -ENOMEM; + dev->slot = i; + dev->bus = tpci200->info->ipack_bus; + dev->release = tpci200_release_device; + + for (space = 0; space < IPACK_SPACE_COUNT; space++) { + dev->region[space].start = + tpci200->mod_mem[space] + + tpci200_space_interval[space] * i; + dev->region[space].size = tpci200_space_size[space]; + } + return ipack_device_register(dev); +} + +static int tpci200_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int ret, i; + struct tpci200_board *tpci200; + u32 reg32; + + tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL); + if (!tpci200) + return -ENOMEM; + + tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL); + if (!tpci200->info) { + ret = -ENOMEM; + goto out_err_info; + } + + pci_dev_get(pdev); + + /* Obtain a mapping of the carrier's PCI configuration registers */ + ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR, + KBUILD_MODNAME " Configuration Memory"); + if (ret) { + dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory"); + ret = -EBUSY; + goto out_err_pci_request; + } + tpci200->info->cfg_regs = ioremap_nocache( + pci_resource_start(pdev, TPCI200_CFG_MEM_BAR), + pci_resource_len(pdev, TPCI200_CFG_MEM_BAR)); + if (!tpci200->info->cfg_regs) { + dev_err(&pdev->dev, "Failed to map PCI Configuration Memory"); + ret = -EFAULT; + goto out_err_ioremap; + } + + /* Disable byte swapping for 16 bit IP module access. This will ensure + * that the Industrypack big endian byte order is preserved by the + * carrier. */ + reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC); + reg32 |= 1 << LAS_BIT_BIGENDIAN; + iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC); + + reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC); + reg32 |= 1 << LAS_BIT_BIGENDIAN; + iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC); + + /* Save struct pci_dev pointer */ + tpci200->info->pdev = pdev; + tpci200->info->id_table = (struct pci_device_id *)id; + + /* register the device and initialize it */ + ret = tpci200_install(tpci200); + if (ret) { + dev_err(&pdev->dev, "error during tpci200 install\n"); + ret = -ENODEV; + goto out_err_install; + } + + /* Register the carrier in the industry pack bus driver */ + tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev, + TPCI200_NB_SLOT, + &tpci200_bus_ops); + if (!tpci200->info->ipack_bus) { + dev_err(&pdev->dev, + "error registering the carrier on ipack driver\n"); + ret = -EFAULT; + goto out_err_bus_register; + } + + /* save the bus number given by ipack to logging purpose */ + tpci200->number = tpci200->info->ipack_bus->bus_nr; + dev_set_drvdata(&pdev->dev, tpci200); + + for (i = 0; i < TPCI200_NB_SLOT; i++) + tpci200_create_device(tpci200, i); + return 0; + +out_err_bus_register: + tpci200_uninstall(tpci200); +out_err_install: + iounmap(tpci200->info->cfg_regs); +out_err_ioremap: + pci_release_region(pdev, TPCI200_CFG_MEM_BAR); +out_err_pci_request: + pci_dev_put(pdev); + kfree(tpci200->info); +out_err_info: + kfree(tpci200); + return ret; +} + +static void __tpci200_pci_remove(struct tpci200_board *tpci200) +{ + ipack_bus_unregister(tpci200->info->ipack_bus); + tpci200_uninstall(tpci200); + + kfree(tpci200->info); + kfree(tpci200); +} + +static void __devexit tpci200_pci_remove(struct pci_dev *dev) +{ + struct tpci200_board *tpci200 = pci_get_drvdata(dev); + + __tpci200_pci_remove(tpci200); +} + +static DEFINE_PCI_DEVICE_TABLE(tpci200_idtable) = { + { TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID, + TPCI200_SUBDEVICE_ID }, + { 0, }, +}; + +MODULE_DEVICE_TABLE(pci, tpci200_idtable); + +static struct pci_driver tpci200_pci_drv = { + .name = "tpci200", + .id_table = tpci200_idtable, + .probe = tpci200_pci_probe, + .remove = __devexit_p(tpci200_pci_remove), +}; + +static int __init tpci200_drvr_init_module(void) +{ + return pci_register_driver(&tpci200_pci_drv); +} + +static void __exit tpci200_drvr_exit_module(void) +{ + pci_unregister_driver(&tpci200_pci_drv); +} + +MODULE_DESCRIPTION("TEWS TPCI-200 device driver"); +MODULE_LICENSE("GPL"); +module_init(tpci200_drvr_init_module); +module_exit(tpci200_drvr_exit_module); diff --git a/drivers/staging/ipack/carriers/tpci200.h b/drivers/staging/ipack/carriers/tpci200.h new file mode 100644 index 00000000000..982f31920af --- /dev/null +++ b/drivers/staging/ipack/carriers/tpci200.h @@ -0,0 +1,167 @@ +/** + * tpci200.h + * + * driver for the carrier TEWS TPCI-200 + * Copyright (c) 2009 Nicolas Serafini, EIC2 SA + * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN + * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * 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; version 2 of the License. + */ + +#ifndef _TPCI200_H_ +#define _TPCI200_H_ + +#include +#include +#include +#include +#include + +#include "../ipack.h" + +#define TPCI200_NB_SLOT 0x4 +#define TPCI200_NB_BAR 0x6 + +#define TPCI200_VENDOR_ID 0x1498 +#define TPCI200_DEVICE_ID 0x30C8 +#define TPCI200_SUBVENDOR_ID 0x1498 +#define TPCI200_SUBDEVICE_ID 0x300A + +#define TPCI200_CFG_MEM_BAR 0 +#define TPCI200_IP_INTERFACE_BAR 2 +#define TPCI200_IO_ID_INT_SPACES_BAR 3 +#define TPCI200_MEM16_SPACE_BAR 4 +#define TPCI200_MEM8_SPACE_BAR 5 + +struct tpci200_regs { + __le16 revision; + /* writes to control should occur with the mutex held to protect + * read-modify-write operations */ + __le16 control[4]; + __le16 reset; + __le16 status; + u8 reserved[242]; +} __packed; + +#define TPCI200_IFACE_SIZE 0x100 + +#define TPCI200_IO_SPACE_OFF 0x0000 +#define TPCI200_IO_SPACE_INTERVAL 0x0100 +#define TPCI200_IO_SPACE_SIZE 0x0080 +#define TPCI200_ID_SPACE_OFF 0x0080 +#define TPCI200_ID_SPACE_INTERVAL 0x0100 +#define TPCI200_ID_SPACE_SIZE 0x0040 +#define TPCI200_INT_SPACE_OFF 0x00C0 +#define TPCI200_INT_SPACE_INTERVAL 0x0100 +#define TPCI200_INT_SPACE_SIZE 0x0040 +#define TPCI200_IOIDINT_SIZE 0x0400 + +#define TPCI200_MEM8_SPACE_INTERVAL 0x00400000 +#define TPCI200_MEM8_SPACE_SIZE 0x00400000 +#define TPCI200_MEM16_SPACE_INTERVAL 0x00800000 +#define TPCI200_MEM16_SPACE_SIZE 0x00800000 + +/* control field in tpci200_regs */ +#define TPCI200_INT0_EN 0x0040 +#define TPCI200_INT1_EN 0x0080 +#define TPCI200_INT0_EDGE 0x0010 +#define TPCI200_INT1_EDGE 0x0020 +#define TPCI200_ERR_INT_EN 0x0008 +#define TPCI200_TIME_INT_EN 0x0004 +#define TPCI200_RECOVER_EN 0x0002 +#define TPCI200_CLK32 0x0001 + +/* reset field in tpci200_regs */ +#define TPCI200_A_RESET 0x0001 +#define TPCI200_B_RESET 0x0002 +#define TPCI200_C_RESET 0x0004 +#define TPCI200_D_RESET 0x0008 + +/* status field in tpci200_regs */ +#define TPCI200_A_TIMEOUT 0x1000 +#define TPCI200_B_TIMEOUT 0x2000 +#define TPCI200_C_TIMEOUT 0x4000 +#define TPCI200_D_TIMEOUT 0x8000 + +#define TPCI200_A_ERROR 0x0100 +#define TPCI200_B_ERROR 0x0200 +#define TPCI200_C_ERROR 0x0400 +#define TPCI200_D_ERROR 0x0800 + +#define TPCI200_A_INT0 0x0001 +#define TPCI200_A_INT1 0x0002 +#define TPCI200_B_INT0 0x0004 +#define TPCI200_B_INT1 0x0008 +#define TPCI200_C_INT0 0x0010 +#define TPCI200_C_INT1 0x0020 +#define TPCI200_D_INT0 0x0040 +#define TPCI200_D_INT1 0x0080 + +#define TPCI200_SLOT_INT_MASK 0x00FF + +/* PCI Configuration registers. The PCI bridge is a PLX Technology PCI9030. */ +#define LAS1_DESC 0x2C +#define LAS2_DESC 0x30 + +/* Bits in the LAS?_DESC registers */ +#define LAS_BIT_BIGENDIAN 24 + +#define VME_IOID_SPACE "IOID" +#define VME_MEM_SPACE "MEM" + +/** + * struct slot_irq - slot IRQ definition. + * @vector Vector number + * @handler Handler called when IRQ arrives + * @arg Handler argument + * + */ +struct slot_irq { + struct ipack_device *holder; + int vector; + irqreturn_t (*handler)(void *); + void *arg; +}; + +/** + * struct tpci200_slot - data specific to the tpci200 slot. + * @slot_id Slot identification gived to external interface + * @irq Slot IRQ infos + * @io_phys IO physical base address register of the slot + * @id_phys ID physical base address register of the slot + * @int_phys INT physical base address register of the slot + * @mem_phys MEM physical base address register of the slot + * + */ +struct tpci200_slot { + struct slot_irq *irq; +}; + +/** + * struct tpci200_infos - informations specific of the TPCI200 tpci200. + * @pci_dev PCI device + * @interface_regs Pointer to IP interface space (Bar 2) + * @ioidint_space Pointer to IP ID, IO and INT space (Bar 3) + * @mem8_space Pointer to MEM space (Bar 4) + * + */ +struct tpci200_infos { + struct pci_dev *pdev; + struct pci_device_id *id_table; + struct tpci200_regs __iomem *interface_regs; + void __iomem *cfg_regs; + struct ipack_bus_device *ipack_bus; +}; +struct tpci200_board { + unsigned int number; + struct mutex mutex; + spinlock_t regs_lock; + struct tpci200_slot *slots; + struct tpci200_infos *info; + phys_addr_t mod_mem[IPACK_SPACE_COUNT]; +}; + +#endif /* _TPCI200_H_ */ -- cgit v1.2.3 From 26c295cb4bd2a18f943a9962c6f954c8daee90f7 Mon Sep 17 00:00:00 2001 From: Jens Taprogge Date: Thu, 27 Sep 2012 12:37:40 +0200 Subject: staging: ipack: Documentation cleanups. Signed-off-by: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/Kconfig | 13 ++++++++----- drivers/staging/ipack/carriers/Kconfig | 4 ++-- drivers/staging/ipack/ipack.h | 15 ++++++++------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/staging/ipack/Kconfig b/drivers/staging/ipack/Kconfig index 9b4495a35f9..5cf43b3364e 100644 --- a/drivers/staging/ipack/Kconfig +++ b/drivers/staging/ipack/Kconfig @@ -6,11 +6,14 @@ menuconfig IPACK_BUS tristate "IndustryPack bus support" depends on HAS_IOMEM ---help--- - If you say Y here you get support for the IndustryPack Framework - for drivers for many types of boards that support this industrial - bus. The IndustryPack Framework is a virtual bus allowing to - communicate between carrier and mezzanine cards connected through - this bus. + This option provides support for the IndustryPack framework. There + are IndustryPack carrier boards, which interface another bus (such as + PCI) to an IndustryPack bus, and IndustryPack modules, that are + hosted on these buses. While IndustryPack modules can provide a + large variety of functionality, they are most often found in + industrial control applications. + + Say N if unsure. if IPACK_BUS diff --git a/drivers/staging/ipack/carriers/Kconfig b/drivers/staging/ipack/carriers/Kconfig index 33fdc2456c0..922ff5c35ac 100644 --- a/drivers/staging/ipack/carriers/Kconfig +++ b/drivers/staging/ipack/carriers/Kconfig @@ -1,7 +1,7 @@ config BOARD_TPCI200 - tristate "TEWS TPCI-200 support for IndustryPack bus" + tristate "Support for the TEWS TPCI-200 IndustryPack carrier board" depends on IPACK_BUS depends on PCI help - This driver supports the TEWS TPCI200 device for the IndustryPack bus. + This driver adds support for the TEWS TPCI200 IndustryPack carrier board. default n diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 689af9239dc..7ca8789459e 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -80,10 +80,11 @@ struct ipack_device { }; /** - * struct ipack_driver_ops -- callbacks to mezzanine driver for installing/removing one device + * struct ipack_driver_ops -- Callbacks to IPack device driver * - * @probe: Probe function - * @remove: tell the driver that the carrier board wants to remove one device + * @probe: Probe function + * @remove: Prepare imminent removal of the device. Services provided by the + * device should be revoked. */ struct ipack_driver_ops { @@ -92,10 +93,10 @@ struct ipack_driver_ops { }; /** - * struct ipack_driver -- Specific data to each ipack board driver + * struct ipack_driver -- Specific data to each ipack device driver * - * @driver: Device driver kernel representation - * @ops: Mezzanine driver operations specific for the ipack bus. + * @driver: Device driver kernel representation + * @ops: Callbacks provided by the IPack device driver */ struct ipack_driver { struct device_driver driver; @@ -165,7 +166,7 @@ struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, int ipack_bus_unregister(struct ipack_bus_device *bus); /** - * ipack_driver_register -- Register a new driver + * ipack_driver_register -- Register a new ipack device driver * * Called by a ipack driver to register itself as a driver * that can manage ipack devices. -- cgit v1.2.3 From 58b2c0ca0bd16ddefd1d981fe8748ca8083294c6 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Thu, 27 Sep 2012 12:37:41 +0200 Subject: Staging: ipack: fix wrong return value. In case it is not possible to remap the memory, it returns 0 and the driver thinks that everything went fine. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/ipack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index 5bd462b9e38..75bfecfe362 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -355,7 +355,7 @@ static int ipack_device_read_id(struct ipack_device *dev) dev->region[IPACK_ID_SPACE].size); if (!idmem) { dev_err(&dev->dev, "error mapping memory\n"); - return ret; + return -ENOMEM; } /* Determine ID PROM Data Format. If we find the ids "IPAC" or "IPAH" -- cgit v1.2.3 From 1bc7c1c71d7f84baff254868222312bf14915128 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 18 Oct 2012 23:18:46 +0800 Subject: Staging: ipack/bridges/tpci200: use module_pci_driver to simplify the code Use the module_pci_driver() macro to make the code simpler by eliminating module_init and module_exit calls. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/carriers/tpci200.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/staging/ipack/carriers/tpci200.c b/drivers/staging/ipack/carriers/tpci200.c index 376e79410e9..829fd1ac8f8 100644 --- a/drivers/staging/ipack/carriers/tpci200.c +++ b/drivers/staging/ipack/carriers/tpci200.c @@ -618,17 +618,7 @@ static struct pci_driver tpci200_pci_drv = { .remove = __devexit_p(tpci200_pci_remove), }; -static int __init tpci200_drvr_init_module(void) -{ - return pci_register_driver(&tpci200_pci_drv); -} - -static void __exit tpci200_drvr_exit_module(void) -{ - pci_unregister_driver(&tpci200_pci_drv); -} +module_pci_driver(tpci200_pci_drv); MODULE_DESCRIPTION("TEWS TPCI-200 device driver"); MODULE_LICENSE("GPL"); -module_init(tpci200_drvr_init_module); -module_exit(tpci200_drvr_exit_module); -- cgit v1.2.3 From ce833d36c63c6aeb0ab9c271c56cb246f0bb82cd Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Thu, 27 Sep 2012 22:59:34 +0900 Subject: staging/sbe-2t3e3: Use netdev_ printks in cpld.c fixed below checkpatch warning. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sbe-2t3e3/cpld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/sbe-2t3e3/cpld.c b/drivers/staging/sbe-2t3e3/cpld.c index cc2b54d52b1..27365f9bc0b 100644 --- a/drivers/staging/sbe-2t3e3/cpld.c +++ b/drivers/staging/sbe-2t3e3/cpld.c @@ -338,7 +338,7 @@ void cpld_set_fractional_mode(struct channel *sc, u32 mode, SBE_2T3E3_CPLD_VAL_FRACTIONAL_MODE_2); break; default: - printk(KERN_ERR "wrong mode in set_fractional_mode\n"); + netdev_err(sc->dev, "wrong mode in set_fractional_mode\n"); return; } -- cgit v1.2.3 From 1917e7f916352d82f0a88f769b7c6ac7bc76f5af Mon Sep 17 00:00:00 2001 From: Pranav Ravichandran Date: Mon, 15 Oct 2012 23:08:26 +0530 Subject: Staging: sbe-2t3e3: fix coding style issues in netdev.c This patch fixes a POINTER_LOCATION error(changed foo* bar to foo *bar) and an ASSIGN_IN_IF error(moved assignment out of if condition). Signed-off-by: Pranav Ravichandran Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sbe-2t3e3/netdev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/sbe-2t3e3/netdev.c b/drivers/staging/sbe-2t3e3/netdev.c index 180c96327b9..1f5088b3c10 100644 --- a/drivers/staging/sbe-2t3e3/netdev.c +++ b/drivers/staging/sbe-2t3e3/netdev.c @@ -57,7 +57,7 @@ static int t3e3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return 0; } -static struct net_device_stats* t3e3_get_stats(struct net_device *dev) +static struct net_device_stats *t3e3_get_stats(struct net_device *dev) { struct net_device_stats *nstats = &dev->stats; struct channel *sc = dev_to_priv(dev); @@ -134,7 +134,8 @@ int setup_device(struct net_device *dev, struct channel *sc) dev->tx_queue_len = 100; hdlc->xmit = t3e3_if_start_xmit; hdlc->attach = t3e3_attach; - if ((retval = register_hdlc_device(dev))) { + retval = register_hdlc_device(dev); + if (retval) { dev_err(&sc->pdev->dev, "error registering HDLC device\n"); return retval; } -- cgit v1.2.3 From 7c7509597a3193a840311cece78c37ab545e884c Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Fri, 5 Oct 2012 21:33:04 -0400 Subject: Staging: bcm: Rename all local variables in function GetNextTargetBufferLocation. This patch renames all local variables in function GetNextTargetBufferLocation for readability purposes. Signed-off-by: Kevin McKinney Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 325b592fd41..48302ee7ebf 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1573,36 +1573,36 @@ ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter) static ULONG GetNextTargetBufferLocation(struct bcm_mini_adapter *Adapter, B_UINT16 tid) { - ULONG ulTargetDSXBufferAddress; - ULONG ulTargetDsxBufferIndexToUse, ulMaxTry; + ULONG dsx_buf; + ULONG idx, max_try; if ((Adapter->ulTotalTargetBuffersAvailable == 0) || (Adapter->ulFreeTargetBufferCnt == 0)) { ClearTargetDSXBuffer(Adapter, tid, FALSE); return 0; } - ulTargetDsxBufferIndexToUse = Adapter->ulCurrentTargetBuffer; - ulMaxTry = Adapter->ulTotalTargetBuffersAvailable; - while ((ulMaxTry) && (Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid != 1)) { - ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1) % Adapter->ulTotalTargetBuffersAvailable; - ulMaxTry--; + idx = Adapter->ulCurrentTargetBuffer; + max_try = Adapter->ulTotalTargetBuffersAvailable; + while ((max_try) && (Adapter->astTargetDsxBuffer[idx].valid != 1)) { + idx = (idx+1) % Adapter->ulTotalTargetBuffersAvailable; + max_try--; } - if (ulMaxTry == 0) { + if (max_try == 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "\n GetNextTargetBufferLocation : Error No Free Target DSX Buffers FreeCnt : %lx ", Adapter->ulFreeTargetBufferCnt); ClearTargetDSXBuffer(Adapter, tid, FALSE); return 0; } - ulTargetDSXBufferAddress = Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].ulTargetDsxBuffer; - Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].valid = 0; - Adapter->astTargetDsxBuffer[ulTargetDsxBufferIndexToUse].tid = tid; + dsx_buf = Adapter->astTargetDsxBuffer[idx].ulTargetDsxBuffer; + Adapter->astTargetDsxBuffer[idx].valid = 0; + Adapter->astTargetDsxBuffer[idx].tid = tid; Adapter->ulFreeTargetBufferCnt--; - ulTargetDsxBufferIndexToUse = (ulTargetDsxBufferIndexToUse+1)%Adapter->ulTotalTargetBuffersAvailable; - Adapter->ulCurrentTargetBuffer = ulTargetDsxBufferIndexToUse; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GetNextTargetBufferLocation :Returning address %lx tid %d\n", ulTargetDSXBufferAddress, tid); + idx = (idx+1)%Adapter->ulTotalTargetBuffersAvailable; + Adapter->ulCurrentTargetBuffer = idx; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "GetNextTargetBufferLocation :Returning address %lx tid %d\n", dsx_buf, tid); - return ulTargetDSXBufferAddress; + return dsx_buf; } int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter) -- cgit v1.2.3 From ecbe90e143412b814464ad9ff67534961099fb5e Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Fri, 12 Oct 2012 23:49:29 -0400 Subject: Staging: bcm: Rename INT to int in InterfaceMisc.c This patch renames uppercase INT to int in InterfaceMisc.c. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceMisc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index bbe90994609..5806aede8fd 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -1,9 +1,9 @@ #include "headers.h" -INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, +int InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, UINT addr, PVOID buff, - INT len) + int len) { int bytes; USHORT usRetries = 0; @@ -57,10 +57,10 @@ INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, return bytes; } -INT InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, +int InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, UINT addr, PVOID buff, - INT len) + int len) { int retval = 0; USHORT usRetries = 0; @@ -117,26 +117,26 @@ INT InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, } } -INT BcmRDM(PVOID arg, +int BcmRDM(PVOID arg, UINT addr, PVOID buff, - INT len) + int len) { return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); } -INT BcmWRM(PVOID arg, +int BcmWRM(PVOID arg, UINT addr, PVOID buff, - INT len) + int len) { return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); } -INT Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter) +int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter) { PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter); - INT status = STATUS_SUCCESS; + int status = STATUS_SUCCESS; /* * usb_clear_halt - tells device to clear endpoint halt/stall condition -- cgit v1.2.3 From 021cbd755e2c63bba840ecfd9ae55dafbe6838fb Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Fri, 12 Oct 2012 23:49:30 -0400 Subject: Staging: bcm: Rename UINT to unsigned int in InterfaceMisc.c This patch renames uppercase UINT to unsigned int in InterfaceMisc.c. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceMisc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index 5806aede8fd..793a492e64b 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -1,7 +1,7 @@ #include "headers.h" int InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, - UINT addr, + unsigned int addr, PVOID buff, int len) { @@ -58,7 +58,7 @@ int InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, } int InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, - UINT addr, + unsigned int addr, PVOID buff, int len) { @@ -118,7 +118,7 @@ int InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, } int BcmRDM(PVOID arg, - UINT addr, + unsigned int addr, PVOID buff, int len) { @@ -126,7 +126,7 @@ int BcmRDM(PVOID arg, } int BcmWRM(PVOID arg, - UINT addr, + unsigned int addr, PVOID buff, int len) { @@ -175,7 +175,7 @@ int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter) VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) { struct urb *tempUrb = NULL; - UINT i; + unsigned int i; /* * usb_kill_urb - cancel a transfer request and wait for it to finish -- cgit v1.2.3 From 306a7acd2a5038aa9e0e75d03b000aaadbf2218d Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Fri, 12 Oct 2012 23:49:31 -0400 Subject: Staging: bcm: Rename USHORT to unsigned short in InterfaceMisc.c This patch renames uppercase USHORT to unsigned short in InterfaceMisc.c. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceMisc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index 793a492e64b..fd482a29ead 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -6,7 +6,7 @@ int InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, int len) { int bytes; - USHORT usRetries = 0; + unsigned short usRetries = 0; if (psIntfAdapter == NULL) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL"); @@ -63,7 +63,7 @@ int InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, int len) { int retval = 0; - USHORT usRetries = 0; + unsigned short usRetries = 0; if (psIntfAdapter == NULL) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL"); -- cgit v1.2.3 From 5f997ee89a33f664e18222d6ab9bfbf242c31dd5 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Fri, 12 Oct 2012 23:49:32 -0400 Subject: Staging: bcm: Rename PVOID to void * in InterfaceMisc.c This patch renames uppercase PVOID to "void *" in InterfaceMisc.c. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceMisc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index fd482a29ead..5a4768ddd1c 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -2,7 +2,7 @@ int InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, unsigned int addr, - PVOID buff, + void *buff, int len) { int bytes; @@ -59,7 +59,7 @@ int InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, int InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, unsigned int addr, - PVOID buff, + void *buff, int len) { int retval = 0; @@ -117,17 +117,17 @@ int InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, } } -int BcmRDM(PVOID arg, +int BcmRDM(void *arg, unsigned int addr, - PVOID buff, + void *buff, int len) { return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); } -int BcmWRM(PVOID arg, +int BcmWRM(void *arg, unsigned int addr, - PVOID buff, + void *buff, int len) { return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); -- cgit v1.2.3 From de3615f46cc5892a82f18324e62ec2c5c99e959f Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Fri, 12 Oct 2012 23:49:33 -0400 Subject: Staging: bcm: Change the style of comparing structures to null in InterfaceMisc.c. This patch changes the style of comparing structures to null. Instead of this: "if (foo == NULL) {" or "if (foo != NULL) {", the new logic uses: "if (!foo) {" or "if (foo) {". Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceMisc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index 5a4768ddd1c..f7166f1be5f 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -8,7 +8,7 @@ int InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, int bytes; unsigned short usRetries = 0; - if (psIntfAdapter == NULL) { + if (!psIntfAdapter) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL"); return -EINVAL; } @@ -65,7 +65,7 @@ int InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, int retval = 0; unsigned short usRetries = 0; - if (psIntfAdapter == NULL) { + if (!psIntfAdapter) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL"); return -EINVAL; } @@ -193,7 +193,7 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) */ /* Cancel submitted Interrupt-URB's */ - if (psIntfAdapter->psInterruptUrb != NULL) { + if (psIntfAdapter->psInterruptUrb) { if (psIntfAdapter->psInterruptUrb->status == -EINPROGRESS) usb_kill_urb(psIntfAdapter->psInterruptUrb); } -- cgit v1.2.3 From f637035c680b67d15bddfc293ddee3214c23e2e1 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Fri, 12 Oct 2012 23:49:34 -0400 Subject: Staging: bcm: Rename VOID to void in InterfaceMisc.c This patch renames uppercase VOID to void in InterfaceMisc.c. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceMisc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index f7166f1be5f..8c9cf2d38a5 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -172,7 +172,7 @@ int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter) return status; } -VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) +void Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) { struct urb *tempUrb = NULL; unsigned int i; @@ -222,7 +222,7 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) atomic_set(&psIntfAdapter->uCurrRcb, 0); } -VOID putUsbSuspend(struct work_struct *work) +void putUsbSuspend(struct work_struct *work) { PS_INTERFACE_ADAPTER psIntfAdapter = NULL; struct usb_interface *intf = NULL; -- cgit v1.2.3 From 7878626e14cb30df9bc1c9f38293bfa8a887e806 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Fri, 12 Oct 2012 23:49:35 -0400 Subject: Staging: bcm: Remove unneeded do while loop in InterfaceRDM. This patch removes an unneeded do while loop which sends a control message to bcm usb device. In this case, the loop executes once because usRetries is initialized to zero. After the first iteration this variable will be 1. Therefore, the statement: "usRetries < MAX_RDM_WRM_RETIRES" will evaluate to false causing the do while statement to execute once because MAX_RDM_WRM_RETIRES is equal to 1. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceMisc.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index 8c9cf2d38a5..f43e644752a 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -6,7 +6,6 @@ int InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, int len) { int bytes; - unsigned short usRetries = 0; if (!psIntfAdapter) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL"); @@ -29,27 +28,21 @@ int InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, } psIntfAdapter->psAdapter->DeviceAccess = TRUE; - do { - bytes = usb_control_msg(psIntfAdapter->udev, - usb_rcvctrlpipe(psIntfAdapter->udev, 0), - 0x02, - 0xC2, - (addr & 0xFFFF), - ((addr >> 16) & 0xFFFF), - buff, - len, - 5000); - - usRetries++; - if (-ENODEV == bytes) { - psIntfAdapter->psAdapter->device_removed = TRUE; - break; - } + bytes = usb_control_msg(psIntfAdapter->udev, + usb_rcvctrlpipe(psIntfAdapter->udev, 0), + 0x02, + 0xC2, + (addr & 0xFFFF), + ((addr >> 16) & 0xFFFF), + buff, + len, + 5000); - } while ((bytes < 0) && (usRetries < MAX_RDM_WRM_RETIRES)); + if (-ENODEV == bytes) + psIntfAdapter->psAdapter->device_removed = TRUE; if (bytes < 0) - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", bytes, usRetries); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d", bytes); else BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", bytes); -- cgit v1.2.3 From 1e2731eb503e7ddb09fe02d955918e466ad1b0a4 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Fri, 12 Oct 2012 23:49:36 -0400 Subject: Staging: bcm: Remove unneeded do while loop in InterfaceWRM. This patch removes an unneeded do while loop which sends a control message to bcm usb device. In this case, the loop executes once because usRetries is initialized to zero. After the first iteration this variable will be 1. Therefore, the statement: "usRetries < MAX_RDM_WRM_RETIRES" will evaluate to false causing the do while statement to execute once because MAX_RDM_WRM_RETIRES is equal to 1. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceMisc.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index f43e644752a..a101f8f9376 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -56,7 +56,6 @@ int InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, int len) { int retval = 0; - unsigned short usRetries = 0; if (!psIntfAdapter) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL"); @@ -80,27 +79,21 @@ int InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, psIntfAdapter->psAdapter->DeviceAccess = TRUE; - do { - retval = usb_control_msg(psIntfAdapter->udev, - usb_sndctrlpipe(psIntfAdapter->udev, 0), - 0x01, - 0x42, - (addr & 0xFFFF), - ((addr >> 16) & 0xFFFF), - buff, - len, - 5000); - - usRetries++; - if (-ENODEV == retval) { - psIntfAdapter->psAdapter->device_removed = TRUE; - break; - } + retval = usb_control_msg(psIntfAdapter->udev, + usb_sndctrlpipe(psIntfAdapter->udev, 0), + 0x01, + 0x42, + (addr & 0xFFFF), + ((addr >> 16) & 0xFFFF), + buff, + len, + 5000); - } while ((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES)); + if (-ENODEV == retval) + psIntfAdapter->psAdapter->device_removed = TRUE; if (retval < 0) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d", retval); psIntfAdapter->psAdapter->DeviceAccess = FALSE; return retval; } else { -- cgit v1.2.3 From 68f7457d064f4c1972b0a58900a5dabcfd6bbb2e Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Fri, 12 Oct 2012 23:49:37 -0400 Subject: Staging: bcm: Remove null dereference from InterfaceRDM. This patch removes a potential null dereference from InterfaceMisc.c, function InterfaceRDM. This error was reported by Smatch. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceMisc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index a101f8f9376..179bcc2126a 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -7,10 +7,8 @@ int InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, { int bytes; - if (!psIntfAdapter) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL"); + if (!psIntfAdapter) return -EINVAL; - } if (psIntfAdapter->psAdapter->device_removed == TRUE) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed"); -- cgit v1.2.3 From 2807dbe1ce231a077460c05f4badf165d6e08a03 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Fri, 12 Oct 2012 23:49:38 -0400 Subject: Staging: bcm: Remove null dereference from InterfaceWRM. This patch removes a potential null dereference from InterfaceMisc.c, function InterfaceWRM. This error was reported by Smatch. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceMisc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index 179bcc2126a..9c832b32383 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -55,10 +55,8 @@ int InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, { int retval = 0; - if (!psIntfAdapter) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Interface Adapter is NULL"); + if (!psIntfAdapter) return -EINVAL; - } if (psIntfAdapter->psAdapter->device_removed == TRUE) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Device got removed"); -- cgit v1.2.3 From fe671fefebea7af6e9db13582e0dd9be26334616 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 18 Oct 2012 22:40:07 -0400 Subject: Staging: bcm: Rename PVOID to "void *" in Misc.c This patch renames uppercase PVOID to "void *" in Misc.c. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index f13a9582a82..9f3302ab825 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -216,7 +216,7 @@ exit_download: * Logical Adapter * Control Packet Buffer */ -INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, PVOID ioBuffer) +INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer) { struct bcm_leader *pLeader = NULL; INT Status = 0; @@ -448,7 +448,7 @@ VOID LinkMessage(struct bcm_mini_adapter *Adapter) * * Returns - None. ************************************************************************/ -VOID StatisticsResponse(struct bcm_mini_adapter *Adapter, PVOID pvBuffer) +VOID StatisticsResponse(struct bcm_mini_adapter *Adapter, void *pvBuffer) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>", __func__); Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer); -- cgit v1.2.3 From 7a15b79bdba2af69c41d205700de9d7cce97aafd Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 18 Oct 2012 22:40:08 -0400 Subject: Staging: bcm: Rename VOID to void in Misc.c This patch renames uppercase VOID to void in Misc.c. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Misc.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 9f3302ab825..862c6795651 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -1,12 +1,12 @@ #include "headers.h" static int BcmFileDownload(struct bcm_mini_adapter *Adapter, const char *path, unsigned int loc); -static VOID doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter); +static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter); static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer); static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter); static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter); -static VOID default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter) +static void default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter) { UINT uiLoopIndex; @@ -93,7 +93,7 @@ INT InitAdapter(struct bcm_mini_adapter *psAdapter) return STATUS_SUCCESS; } -VOID AdapterFree(struct bcm_mini_adapter *Adapter) +void AdapterFree(struct bcm_mini_adapter *Adapter) { int count; beceem_protocol_reset(Adapter); @@ -397,7 +397,7 @@ INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer) * * Returns - None. *******************************************************************/ -VOID LinkMessage(struct bcm_mini_adapter *Adapter) +void LinkMessage(struct bcm_mini_adapter *Adapter) { struct bcm_link_request *pstLinkRequest = NULL; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "=====>"); @@ -448,7 +448,7 @@ VOID LinkMessage(struct bcm_mini_adapter *Adapter) * * Returns - None. ************************************************************************/ -VOID StatisticsResponse(struct bcm_mini_adapter *Adapter, void *pvBuffer) +void StatisticsResponse(struct bcm_mini_adapter *Adapter, void *pvBuffer) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>", __func__); Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer); @@ -467,7 +467,7 @@ VOID StatisticsResponse(struct bcm_mini_adapter *Adapter, void *pvBuffer) * * Returns - None. ***********************************************************************/ -VOID LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer) +void LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "=====>"); @@ -640,7 +640,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter) * * Returns - None. *******************************************************************/ -VOID DumpPackInfo(struct bcm_mini_adapter *Adapter) +void DumpPackInfo(struct bcm_mini_adapter *Adapter) { UINT uiLoopIndex = 0; UINT uiIndex = 0; @@ -1144,7 +1144,7 @@ void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter) doPowerAutoCorrection(Adapter); } -static VOID doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter) +static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter) { UINT reporting_mode; @@ -1277,7 +1277,7 @@ exit: return uiRetVal; } -static VOID HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter) +static void HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter) { int clear_abort_pattern = 0, Status = 0; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); @@ -1306,7 +1306,7 @@ static VOID HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); } -static VOID SendShutModeResponse(struct bcm_mini_adapter *Adapter) +static void SendShutModeResponse(struct bcm_mini_adapter *Adapter) { struct bcm_link_request stShutdownResponse; UINT NVMAccess = 0, lowPwrAbortMsg = 0; @@ -1419,7 +1419,7 @@ static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR p return; } -VOID ResetCounters(struct bcm_mini_adapter *Adapter) +void ResetCounters(struct bcm_mini_adapter *Adapter) { beceem_protocol_reset(Adapter); Adapter->CurrNumRecvDescs = 0; -- cgit v1.2.3 From b23f7f6f570b6001d58328a1e73a8d5699b7b5d4 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 18 Oct 2012 22:40:09 -0400 Subject: Staging: bcm: Rename PUINT to "unsigned int *" in Misc.c This patch renames uppercase PUINT to "unsigned int *" in Misc.c. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Misc.c | 16 ++++++++-------- drivers/staging/bcm/Prototypes.h | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 862c6795651..4eca8cb92b3 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -1175,7 +1175,7 @@ static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter) } } -static void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount) +static void convertEndian(B_UINT8 rwFlag, unsigned int *puiBuffer, UINT uiByteCount) { UINT uiIndex = 0; @@ -1203,18 +1203,18 @@ int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t return iRetVal; } -int wrmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size) +int wrmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t size) { convertEndian(RWM_WRITE, pucBuff, size); return wrm(Adapter, uiAddress, (PUCHAR)pucBuff, size); } -int rdmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size) +int rdmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t size) { INT uiRetVal = 0; uiRetVal = rdm(Adapter, uiAddress, (PUCHAR)pucBuff, size); - convertEndian(RWM_READ, (PUINT)pucBuff, size); + convertEndian(RWM_READ, (unsigned int *)pucBuff, size); return uiRetVal; } @@ -1238,7 +1238,7 @@ exit: return status; } -int wrmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size) +int wrmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t size) { int iRetVal = STATUS_SUCCESS; @@ -1258,7 +1258,7 @@ exit: return iRetVal; } -int rdmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t size) +int rdmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t size) { INT uiRetVal = STATUS_SUCCESS; @@ -1283,7 +1283,7 @@ static void HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); /* target has woken up From Shut Down */ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "Clearing Shut Down Software abort pattern\n"); - Status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, (PUINT)&clear_abort_pattern, sizeof(clear_abort_pattern)); + Status = wrmalt(Adapter, SW_ABORT_IDLEMODE_LOC, (unsigned int *)&clear_abort_pattern, sizeof(clear_abort_pattern)); if (Status) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "WRM to SW_ABORT_IDLEMODE_LOC failed with err:%d", Status); return; @@ -1505,7 +1505,7 @@ void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter) if (!atomic_read(&Adapter->uiMBupdate)) return; - bytes = rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS); + bytes = rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (unsigned int *)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS); if (bytes < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed\n"); return; diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index 3ec8f800a5b..e3f01cbe51f 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -79,9 +79,9 @@ int rdm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t size); -int wrmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize); +int wrmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize); -int rdmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize); +int rdmalt (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize); int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, UINT uiSFId, void __user * user_buffer); @@ -203,8 +203,8 @@ BOOLEAN IsNonCDLessDevice(struct bcm_mini_adapter *Adapter); VOID OverrideServiceFlowParams(struct bcm_mini_adapter *Adapter,PUINT puiBuffer); -int wrmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize); -int rdmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, PUINT pucBuff, size_t sSize); +int wrmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize); +int rdmaltWithLock (struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t sSize); int wrmWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t size); INT buffDnldVerify(struct bcm_mini_adapter *Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, -- cgit v1.2.3 From 4216faf7cb77f16869423c52335adf6bf83ff911 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 18 Oct 2012 22:40:10 -0400 Subject: Staging: bcm: Rename B_UINT8 to "unsigned char" in Misc.c This patch renames uppercase B_UINT8 to "unsigned char" in Misc.c. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 4eca8cb92b3..943ef84c13b 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -1175,7 +1175,7 @@ static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter) } } -static void convertEndian(B_UINT8 rwFlag, unsigned int *puiBuffer, UINT uiByteCount) +static void convertEndian(unsigned char rwFlag, unsigned int *puiBuffer, UINT uiByteCount) { UINT uiIndex = 0; -- cgit v1.2.3 From 7052208bf50e7fe7f7184e8e5ad969b065aeb9d8 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 18 Oct 2012 22:40:11 -0400 Subject: Staging: bcm: Rename B_UINT32 to "unsigned int" in Misc.c This patch renames uppercase B_UINT32 to "unsigned int" in Misc.c. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 943ef84c13b..77e4a51c4d2 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -1392,7 +1392,7 @@ static void SendShutModeResponse(struct bcm_mini_adapter *Adapter) static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR pucBuffer) { - B_UINT32 uiResetValue = 0; + unsigned int uiResetValue = 0; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "====>\n"); -- cgit v1.2.3 From 9ef0760fceda3f11d771fa007f43d6716b8139fc Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 18 Oct 2012 22:40:12 -0400 Subject: Staging: bcm: Rename UINT to "unsigned int" in Misc.c This patch renames uppercase UINT to "unsigned int" in Misc.c. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Misc.c | 56 +++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 77e4a51c4d2..0c9270d8ca4 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -8,7 +8,7 @@ static void beceem_protocol_reset(struct bcm_mini_adapter *Adapter); static void default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter) { - UINT uiLoopIndex; + unsigned int uiLoopIndex; for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES-1; uiLoopIndex++) { Adapter->PackInfo[uiLoopIndex].uiThreshold = TX_PACKET_THRESHOLD; @@ -221,7 +221,7 @@ INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer) struct bcm_leader *pLeader = NULL; INT Status = 0; unsigned char *ctrl_buff = NULL; - UINT pktlen = 0; + unsigned int pktlen = 0; struct bcm_link_request *pLinkReq = NULL; PUCHAR pucAddIndication = NULL; @@ -452,7 +452,7 @@ void StatisticsResponse(struct bcm_mini_adapter *Adapter, void *pvBuffer) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>", __func__); Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (UINT)Adapter->StatisticsPointer); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (unsigned int)Adapter->StatisticsPointer); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====", __func__); return; } @@ -642,9 +642,9 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter) *******************************************************************/ void DumpPackInfo(struct bcm_mini_adapter *Adapter) { - UINT uiLoopIndex = 0; - UINT uiIndex = 0; - UINT uiClsfrIndex = 0; + unsigned int uiLoopIndex = 0; + unsigned int uiIndex = 0; + unsigned int uiClsfrIndex = 0; struct bcm_classifier_rule *pstClassifierEntry = NULL; for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) { @@ -920,7 +920,7 @@ int run_card_proc(struct bcm_mini_adapter *ps_adapter) int InitCardAndDownloadFirmware(struct bcm_mini_adapter *ps_adapter) { int status; - UINT value = 0; + unsigned int value = 0; /* * Create the threads first and then download the * Firm/DDR Settings.. @@ -1088,7 +1088,7 @@ static int bcm_parse_target_params(struct bcm_mini_adapter *Adapter) void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter) { - UINT uiHostDrvrCfg6 = 0, uiEEPROMFlag = 0; + unsigned int uiHostDrvrCfg6 = 0, uiEEPROMFlag = 0; if (ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE) { pr_info(DRV_NAME ": AutoSyncup is Disabled\n"); @@ -1146,7 +1146,7 @@ void beceem_parse_target_struct(struct bcm_mini_adapter *Adapter) static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter) { - UINT reporting_mode; + unsigned int reporting_mode; reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) & 0x02; psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1); @@ -1175,26 +1175,26 @@ static void doPowerAutoCorrection(struct bcm_mini_adapter *psAdapter) } } -static void convertEndian(unsigned char rwFlag, unsigned int *puiBuffer, UINT uiByteCount) +static void convertEndian(unsigned char rwFlag, unsigned int *puiBuffer, unsigned int uiByteCount) { - UINT uiIndex = 0; + unsigned int uiIndex = 0; if (RWM_WRITE == rwFlag) { - for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++) + for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(unsigned int)); uiIndex++) puiBuffer[uiIndex] = htonl(puiBuffer[uiIndex]); } else { - for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(UINT)); uiIndex++) + for (uiIndex = 0; uiIndex < (uiByteCount/sizeof(unsigned int)); uiIndex++) puiBuffer[uiIndex] = ntohl(puiBuffer[uiIndex]); } } -int rdm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) +int rdm(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize) { return Adapter->interface_rdm(Adapter->pvInterfaceAdapter, uiAddress, pucBuff, sSize); } -int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) +int wrm(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize) { int iRetVal; @@ -1203,13 +1203,13 @@ int wrm(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t return iRetVal; } -int wrmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t size) +int wrmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) { convertEndian(RWM_WRITE, pucBuff, size); return wrm(Adapter, uiAddress, (PUCHAR)pucBuff, size); } -int rdmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t size) +int rdmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) { INT uiRetVal = 0; @@ -1219,7 +1219,7 @@ int rdmalt(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBu return uiRetVal; } -int wrmWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) +int wrmWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize) { INT status = STATUS_SUCCESS; down(&Adapter->rdmwrmsync); @@ -1238,7 +1238,7 @@ exit: return status; } -int wrmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t size) +int wrmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) { int iRetVal = STATUS_SUCCESS; @@ -1258,7 +1258,7 @@ exit: return iRetVal; } -int rdmaltWithLock(struct bcm_mini_adapter *Adapter, UINT uiAddress, unsigned int *pucBuff, size_t size) +int rdmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) { INT uiRetVal = STATUS_SUCCESS; @@ -1309,8 +1309,8 @@ static void HandleShutDownModeWakeup(struct bcm_mini_adapter *Adapter) static void SendShutModeResponse(struct bcm_mini_adapter *Adapter) { struct bcm_link_request stShutdownResponse; - UINT NVMAccess = 0, lowPwrAbortMsg = 0; - UINT Status = 0; + unsigned int NVMAccess = 0, lowPwrAbortMsg = 0; + unsigned int Status = 0; memset(&stShutdownResponse, 0, sizeof(struct bcm_link_request)); stShutdownResponse.Leader.Status = LINK_UP_CONTROL_REQ; @@ -1437,7 +1437,7 @@ void ResetCounters(struct bcm_mini_adapter *Adapter) struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIP) { - UINT uiIndex = 0; + unsigned int uiIndex = 0; for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) && (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) && @@ -1451,7 +1451,7 @@ struct bcm_classifier_rule *GetFragIPClsEntry(struct bcm_mini_adapter *Adapter, void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_packet_info *psFragPktInfo) { - UINT uiIndex = 0; + unsigned int uiIndex = 0; for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { if (!Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) { memcpy(&Adapter->astFragmentedPktClassifierTable[uiIndex], psFragPktInfo, sizeof(struct bcm_fragmented_packet_info)); @@ -1462,7 +1462,7 @@ void AddFragIPClsEntry(struct bcm_mini_adapter *Adapter, struct bcm_fragmented_p void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentification, ULONG SrcIp) { - UINT uiIndex = 0; + unsigned int uiIndex = 0; for (uiIndex = 0; uiIndex < MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES; uiIndex++) { if ((Adapter->astFragmentedPktClassifierTable[uiIndex].bUsed) && (Adapter->astFragmentedPktClassifierTable[uiIndex].usIpIdentification == usIpIdentification) && @@ -1474,7 +1474,7 @@ void DelFragIPClsEntry(struct bcm_mini_adapter *Adapter, USHORT usIpIdentificati void update_per_cid_rx(struct bcm_mini_adapter *Adapter) { - UINT qindex = 0; + unsigned int qindex = 0; if ((jiffies - Adapter->liDrainCalculated) < XSECONDS) return; @@ -1505,7 +1505,7 @@ void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter) if (!atomic_read(&Adapter->uiMBupdate)) return; - bytes = rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (unsigned int *)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS); + bytes = rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (unsigned int *)uibuff, sizeof(unsigned int) * MAX_TARGET_DSX_BUFFERS); if (bytes < 0) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "rdm failed\n"); return; @@ -1522,7 +1522,7 @@ void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter) atomic_set(&Adapter->uiMBupdate, FALSE); } -void flush_queue(struct bcm_mini_adapter *Adapter, UINT iQIndex) +void flush_queue(struct bcm_mini_adapter *Adapter, unsigned int iQIndex) { struct sk_buff *PacketToDrop = NULL; struct net_device_stats *netstats = &Adapter->dev->stats; -- cgit v1.2.3 From 7af1413446b8e842412932f0b8634f107412b63c Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 18 Oct 2012 22:40:13 -0400 Subject: Staging: bcm: Rename INT to "int" in Misc.c This patch renames uppercase INT to "int" in Misc.c, and removes one white space issue. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Misc.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 0c9270d8ca4..10af3512296 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -24,10 +24,10 @@ static void default_wimax_protocol_initialize(struct bcm_mini_adapter *Adapter) return; } -INT InitAdapter(struct bcm_mini_adapter *psAdapter) +int InitAdapter(struct bcm_mini_adapter *psAdapter) { int i = 0; - INT Status = STATUS_SUCCESS; + int Status = STATUS_SUCCESS; BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Initialising Adapter = %p", psAdapter); if (psAdapter == NULL) { @@ -216,10 +216,10 @@ exit_download: * Logical Adapter * Control Packet Buffer */ -INT CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer) +int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer) { struct bcm_leader *pLeader = NULL; - INT Status = 0; + int Status = 0; unsigned char *ctrl_buff = NULL; unsigned int pktlen = 0; struct bcm_link_request *pLinkReq = NULL; @@ -543,7 +543,7 @@ void LinkControlResponseMessage(struct bcm_mini_adapter *Adapter, PUCHAR pucBuff void SendIdleModeResponse(struct bcm_mini_adapter *Adapter) { - INT status = 0, NVMAccess = 0, lowPwrAbortMsg = 0; + int status = 0, NVMAccess = 0, lowPwrAbortMsg = 0; struct timeval tv; struct bcm_link_request stIdleResponse = {{0} }; memset(&tv, 0, sizeof(tv)); @@ -583,7 +583,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter) /* Wait for the LED to TURN OFF before sending ACK response */ if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - INT iRetVal = 0; + int iRetVal = 0; /* Wake the LED Thread with IDLEMODE_ENTER State */ Adapter->DriverState = LOWPOWER_MODE_ENTER; @@ -1211,7 +1211,7 @@ int wrmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned in int rdmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) { - INT uiRetVal = 0; + int uiRetVal = 0; uiRetVal = rdm(Adapter, uiAddress, (PUCHAR)pucBuff, size); convertEndian(RWM_READ, (unsigned int *)pucBuff, size); @@ -1221,7 +1221,7 @@ int rdmalt(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned in int wrmWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, PCHAR pucBuff, size_t sSize) { - INT status = STATUS_SUCCESS; + int status = STATUS_SUCCESS; down(&Adapter->rdmwrmsync); if ((Adapter->IdleMode == TRUE) || @@ -1260,7 +1260,7 @@ exit: int rdmaltWithLock(struct bcm_mini_adapter *Adapter, unsigned int uiAddress, unsigned int *pucBuff, size_t size) { - INT uiRetVal = STATUS_SUCCESS; + int uiRetVal = STATUS_SUCCESS; down(&Adapter->rdmwrmsync); if ((Adapter->IdleMode == TRUE) || @@ -1346,7 +1346,7 @@ static void SendShutModeResponse(struct bcm_mini_adapter *Adapter) /* Wait for the LED to TURN OFF before sending ACK response */ if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { - INT iRetVal = 0; + int iRetVal = 0; /* Wake the LED Thread with LOWPOWER_MODE_ENTER State */ Adapter->DriverState = LOWPOWER_MODE_ENTER; @@ -1412,7 +1412,7 @@ static void HandleShutDownModeRequest(struct bcm_mini_adapter *Adapter, PUCHAR p } SendShutModeResponse(Adapter); - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "ShutDownModeResponse:Notification received: Sending the response(Ack/Nack)\n"); } BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "<====\n"); @@ -1498,7 +1498,7 @@ void update_per_cid_rx(struct bcm_mini_adapter *Adapter) void update_per_sf_desc_cnts(struct bcm_mini_adapter *Adapter) { - INT iIndex = 0; + int iIndex = 0; u32 uibuff[MAX_TARGET_DSX_BUFFERS]; int bytes; -- cgit v1.2.3 From 895b1fb81c9e71cac0f8787359035d177c12b5b6 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 18 Oct 2012 22:40:14 -0400 Subject: Staging: bcm: Clean up function CopyBufferToControlPacket in Misc.c This patch cleans up the code in function CopyBufferToControlPacket. Several things are being done here: (1) remove the null initialization from variable cntrl_buff, (2) reverse the if statement to check if cntrl_buff is null; if so, then write debug statement and return -ENOMEM error code, and (3) indent the code properly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Misc.c | 110 +++++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 54 deletions(-) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 10af3512296..d8053934567 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -220,7 +220,7 @@ int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer) { struct bcm_leader *pLeader = NULL; int Status = 0; - unsigned char *ctrl_buff = NULL; + unsigned char *ctrl_buff; unsigned int pktlen = 0; struct bcm_link_request *pLinkReq = NULL; PUCHAR pucAddIndication = NULL; @@ -325,64 +325,66 @@ int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer) pktlen = pLeader->PLength; ctrl_buff = (char *)Adapter->txctlpacket[atomic_read(&Adapter->index_wr_txcntrlpkt)%MAX_CNTRL_PKTS]; + if (!ctrl_buff) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed"); + return -ENOMEM; + } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Control packet to be taken =%d and address is =%pincoming address is =%p and packet len=%x", atomic_read(&Adapter->index_wr_txcntrlpkt), ctrl_buff, ioBuffer, pktlen); - if (ctrl_buff) { - if (pLeader) { - if ((pLeader->Status == 0x80) || - (pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ)) { - /* - * Restructure the DSX message to handle Multiple classifier Support - * Write the Service Flow param Structures directly to the target - * and embed the pointers in the DSX messages sent to target. - */ - /* Lets store the current length of the control packet we are transmitting */ - pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE; - pktlen = pLeader->PLength; - Status = StoreCmControlResponseMessage(Adapter, pucAddIndication, &pktlen); - if (Status != 1) { - ClearTargetDSXBuffer(Adapter, ((stLocalSFAddIndicationAlt *)pucAddIndication)->u16TID, FALSE); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly "); - return STATUS_FAILURE; - } - /* - * update the leader to use the new length - * The length of the control packet is length of message being sent + Leader length - */ - pLeader->PLength = pktlen; + + if (pLeader) { + if ((pLeader->Status == 0x80) || + (pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ)) { + /* + * Restructure the DSX message to handle Multiple classifier Support + * Write the Service Flow param Structures directly to the target + * and embed the pointers in the DSX messages sent to target. + */ + /* Lets store the current length of the control packet we are transmitting */ + pucAddIndication = (PUCHAR)ioBuffer + LEADER_SIZE; + pktlen = pLeader->PLength; + Status = StoreCmControlResponseMessage(Adapter, pucAddIndication, &pktlen); + if (Status != 1) { + ClearTargetDSXBuffer(Adapter, ((stLocalSFAddIndicationAlt *)pucAddIndication)->u16TID, FALSE); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly "); + return STATUS_FAILURE; } + /* + * update the leader to use the new length + * The length of the control packet is length of message being sent + Leader length + */ + pLeader->PLength = pktlen; } - - if (pktlen + LEADER_SIZE > MAX_CNTL_PKT_SIZE) - return -EINVAL; - - memset(ctrl_buff, 0, pktlen+LEADER_SIZE); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength); - *(struct bcm_leader *)ctrl_buff = *pLeader; - memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet"); - - /* Update the statistics counters */ - spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock); - Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost += pLeader->PLength; - Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++; - atomic_inc(&Adapter->TotalPacketCount); - spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock); - Adapter->PackInfo[HiPriority].bValid = TRUE; - - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x", - Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost, - Adapter->PackInfo[HiPriority].bValid); - Status = STATUS_SUCCESS; - /*Queue the packet for transmission */ - atomic_inc(&Adapter->index_wr_txcntrlpkt); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Calling transmit_packets"); - atomic_set(&Adapter->TxPktAvail, 1); - wake_up(&Adapter->tx_packet_wait_queue); - } else { - Status = -ENOMEM; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "mem allocation Failed"); } + + if (pktlen + LEADER_SIZE > MAX_CNTL_PKT_SIZE) + return -EINVAL; + + memset(ctrl_buff, 0, pktlen+LEADER_SIZE); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Copying the Control Packet Buffer with length=%d\n", pLeader->PLength); + *(struct bcm_leader *)ctrl_buff = *pLeader; + memcpy(ctrl_buff + LEADER_SIZE, ((PUCHAR)ioBuffer + LEADER_SIZE), pLeader->PLength); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Enqueuing the Control Packet"); + + /* Update the statistics counters */ + spin_lock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock); + Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost += pLeader->PLength; + Adapter->PackInfo[HiPriority].uiCurrentPacketsOnHost++; + atomic_inc(&Adapter->TotalPacketCount); + spin_unlock_bh(&Adapter->PackInfo[HiPriority].SFQueueLock); + Adapter->PackInfo[HiPriority].bValid = TRUE; + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "CurrBytesOnHost: %x bValid: %x", + Adapter->PackInfo[HiPriority].uiCurrentBytesOnHost, + Adapter->PackInfo[HiPriority].bValid); + Status = STATUS_SUCCESS; + /*Queue the packet for transmission */ + atomic_inc(&Adapter->index_wr_txcntrlpkt); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Calling transmit_packets"); + atomic_set(&Adapter->TxPktAvail, 1); + wake_up(&Adapter->tx_packet_wait_queue); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<===="); return Status; } -- cgit v1.2.3 From b64c84628533667aab302a693bb20a9017aeaa01 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 18 Oct 2012 22:40:15 -0400 Subject: Staging: bcm: Reverse condition in if statement in Misc.c This patch reverses the condition in two if statements in CopyBufferToControlPacket to place Adapter->bShutStatus and Adapter->idleMode to the left of the equal "==" sign, and TRUE to the right of the equal "==" sign. This was done for readability purposes. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index d8053934567..c3866d9f358 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -253,7 +253,7 @@ int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer) return STATUS_FAILURE; } - if (TRUE == Adapter->bShutStatus) { + if (Adapter->bShutStatus == TRUE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "SYNC UP IN SHUTDOWN..Device WakeUp\n"); if (Adapter->bTriedToWakeUpFromlowPowerMode == FALSE) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Waking up for the First Time..\n"); @@ -275,7 +275,7 @@ int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer) } } - if (TRUE == Adapter->IdleMode) { + if (Adapter->IdleMode == TRUE) { /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle mode ... hence\n"); */ if (pLeader->Status == LINK_UP_CONTROL_REQ || pLeader->Status == 0x80 || pLeader->Status == CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ) { -- cgit v1.2.3 From 62da1921292ef789c23a7bf01d671d7572baf377 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 20 Sep 2012 16:02:49 -0700 Subject: rcu: Accelerate callbacks for CPU initiating a grace period Because grace-period initialization is carried out by a separate kthread, it might happen on a different CPU than the one that had the callback needing a grace period -- which is where the callback acceleration needs to happen. Fortunately, rcu_start_gp() holds the root rcu_node structure's ->lock, which prevents a new grace period from starting. This allows this function to safely determine that a grace period has not yet started, which in turn allows it to fully accelerate any callbacks that it has pending. This commit adds this acceleration. Signed-off-by: Paul E. McKenney --- kernel/rcutree.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 74df86bd920..93d6871bf7f 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -1404,15 +1404,37 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags) !cpu_needs_another_gp(rsp, rdp)) { /* * Either we have not yet spawned the grace-period - * task or this CPU does not need another grace period. + * task, this CPU does not need another grace period, + * or a grace period is already in progress. * Either way, don't start a new grace period. */ raw_spin_unlock_irqrestore(&rnp->lock, flags); return; } + /* + * Because there is no grace period in progress right now, + * any callbacks we have up to this point will be satisfied + * by the next grace period. So promote all callbacks to be + * handled after the end of the next grace period. If the + * CPU is not yet aware of the end of the previous grace period, + * we need to allow for the callback advancement that will + * occur when it does become aware. Deadlock prevents us from + * making it aware at this point: We cannot acquire a leaf + * rcu_node ->lock while holding the root rcu_node ->lock. + */ + rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL]; + if (rdp->completed == rsp->completed) + rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL]; + rsp->gp_flags = RCU_GP_FLAG_INIT; - raw_spin_unlock_irqrestore(&rnp->lock, flags); + raw_spin_unlock(&rnp->lock); /* Interrupts remain disabled. */ + + /* Ensure that CPU is aware of completion of last grace period. */ + rcu_process_gp_end(rsp, rdp); + local_irq_restore(flags); + + /* Wake up rcu_gp_kthread() to start the grace period. */ wake_up(&rsp->gp_wq); } -- cgit v1.2.3 From a736427fa1103158338839813139b20763c7b13e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 20 Oct 2012 21:39:44 -0400 Subject: missing const in alpha callers of do_mount() Signed-off-by: Al Viro --- arch/alpha/kernel/osf_sys.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 9eb090582cf..ac2ae13bd04 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -445,7 +445,7 @@ struct procfs_args { * unhappy with OSF UFS. [CHECKME] */ static int -osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) +osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags) { int retval; struct cdfs_args tmp; @@ -465,7 +465,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) } static int -osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) +osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags) { int retval; struct cdfs_args tmp; @@ -485,7 +485,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) } static int -osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags) +osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags) { struct procfs_args tmp; -- cgit v1.2.3 From 2874762b31d8d0eebcfdf189ec9906be9c1460f6 Mon Sep 17 00:00:00 2001 From: Macpaul Lin Date: Sat, 29 Sep 2012 18:08:06 +0800 Subject: staging/gdm72xx: gdm_wimax: fix compile error when enable debug Fix compile error when enable DEBUG_SDU and DEBUG_HCI. Replace deprecated NIPQUAD marco to C code. Signed-off-by: Macpaul Lin Cc: Macpaul Lin Cc: Paul Stewart Cc: Ben Chan Cc: Sage Ahn Cc: Greg Kroah-Hartman Cc: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_wimax.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index 6cb810701a3..dad6fd3e0a7 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -170,7 +170,10 @@ static void dump_eth_packet(const char *title, u8 *data, int len) if (!(data[0] == 0xff && data[1] == 0xff)) { if (protocol == ETH_P_IP) { printk(KERN_DEBUG " src=%u.%u.%u.%u\n", - NIPQUAD(ih->saddr)); + ((unsigned char *)&(ih->saddr))[0], + ((unsigned char *)&(ih->saddr))[1], + ((unsigned char *)&(ih->saddr))[2], + ((unsigned char *)&(ih->saddr))[3]); } else if (protocol == ETH_P_IPV6) { #ifdef NIP6 printk(KERN_DEBUG " src=%x:%x:%x:%x:%x:%x:%x:%x\n", -- cgit v1.2.3 From 9e412a0a581e07cf1551bbd9b4ae69654e474a3c Mon Sep 17 00:00:00 2001 From: Macpaul Lin Date: Fri, 28 Sep 2012 08:40:57 +0800 Subject: staging/gdm72xx: sdio_boot: replace firmware upgrade API Replace firmware upgrade API in download_image(). Signed-off-by: Macpaul Lin Cc: Macpaul Lin Cc: Paul Stewart Cc: Ben Chan Cc: Sage Ahn Cc: Greg Kroah-Hartman Cc: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/sdio_boot.c | 81 +++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/drivers/staging/gdm72xx/sdio_boot.c b/drivers/staging/gdm72xx/sdio_boot.c index 65624bca8b3..38feb1acd8e 100644 --- a/drivers/staging/gdm72xx/sdio_boot.c +++ b/drivers/staging/gdm72xx/sdio_boot.c @@ -24,15 +24,18 @@ #include #include +#include + #include "gdm_sdio.h" #define TYPE_A_HEADER_SIZE 4 #define TYPE_A_LOOKAHEAD_SIZE 16 -#define YMEM0_SIZE 0x8000 /* 32kbytes */ +#define YMEM0_SIZE 0x8000 /* 32kbytes */ #define DOWNLOAD_SIZE (YMEM0_SIZE - TYPE_A_HEADER_SIZE) -#define KRN_PATH "/lib/firmware/gdm72xx/gdmskrn.bin" -#define RFS_PATH "/lib/firmware/gdm72xx/gdmsrfs.bin" +#define FW_DIR "gdm72xx/" +#define FW_KRN "gdmskrn.bin" +#define FW_RFS "gdmsrfs.bin" static u8 *tx_buf; @@ -52,57 +55,57 @@ static int ack_ready(struct sdio_func *func) return 0; } -static int download_image(struct sdio_func *func, char *img_name) +static int download_image(struct sdio_func *func, const char *img_name) { - int ret = 0, len, size, pno; - struct file *filp = NULL; - struct inode *inode = NULL; + int ret = 0, len, pno; u8 *buf = tx_buf; loff_t pos = 0; - - filp = filp_open(img_name, O_RDONLY | O_LARGEFILE, 0); - if (IS_ERR(filp)) { - printk(KERN_ERR "Can't find %s.\n", img_name); - return -ENOENT; + int img_len; + const struct firmware *firm; + + ret = request_firmware(&firm, img_name, &func->dev); + if (ret < 0) { + printk(KERN_ERR + "requesting firmware %s failed with error %d\n", + img_name, ret); + return ret; } - inode = filp->f_dentry->d_inode; - if (!S_ISREG(inode->i_mode)) { - printk(KERN_ERR "Invalid file type: %s\n", img_name); - ret = -EINVAL; - goto out; + buf = kmalloc(DOWNLOAD_SIZE + TYPE_A_HEADER_SIZE, GFP_KERNEL); + if (buf == NULL) { + printk(KERN_ERR "Error: kmalloc\n"); + return -ENOMEM; } - size = i_size_read(inode->i_mapping->host); - if (size <= 0) { - printk(KERN_ERR "Unable to find file size: %s\n", img_name); - ret = size; + img_len = firm->size; + + if (img_len <= 0) { + ret = -1; goto out; } pno = 0; - while ((len = filp->f_op->read(filp, buf + TYPE_A_HEADER_SIZE, - DOWNLOAD_SIZE, &pos))) { - if (len < 0) { - ret = -1; - goto out; + while (img_len > 0) { + if (img_len > DOWNLOAD_SIZE) { + len = DOWNLOAD_SIZE; + buf[3] = 0; + } else { + len = img_len; /* the last packet */ + buf[3] = 2; } buf[0] = len & 0xff; buf[1] = (len >> 8) & 0xff; buf[2] = (len >> 16) & 0xff; - if (pos >= size) /* The last packet */ - buf[3] = 2; - else - buf[3] = 0; - + memcpy(buf+TYPE_A_HEADER_SIZE, firm->data + pos, len); ret = sdio_memcpy_toio(func, 0, buf, len + TYPE_A_HEADER_SIZE); if (ret < 0) { printk(KERN_ERR "gdmwm: send image error: " "packet number = %d ret = %d\n", pno, ret); goto out; } + if (buf[3] == 2) /* The last packet */ break; if (!ack_ready(func)) { @@ -119,17 +122,21 @@ static int download_image(struct sdio_func *func, char *img_name) sdio_writeb(func, 0x01, 0x13, &ret); sdio_writeb(func, 0x00, 0x10, &ret); /* PCRRT */ + img_len -= DOWNLOAD_SIZE; + pos += DOWNLOAD_SIZE; pno++; } + out: - filp_close(filp, NULL); + kfree(buf); return ret; } int sdio_boot(struct sdio_func *func) { - static mm_segment_t fs; int ret; + const char *krn_name = FW_DIR FW_KRN; + const char *rfs_name = FW_DIR FW_RFS; tx_buf = kmalloc(YMEM0_SIZE, GFP_KERNEL); if (tx_buf == NULL) { @@ -137,21 +144,17 @@ int sdio_boot(struct sdio_func *func) return -ENOMEM; } - fs = get_fs(); - set_fs(get_ds()); - - ret = download_image(func, KRN_PATH); + ret = download_image(func, krn_name); if (ret) goto restore_fs; printk(KERN_INFO "GCT: Kernel download success.\n"); - ret = download_image(func, RFS_PATH); + ret = download_image(func, rfs_name); if (ret) goto restore_fs; printk(KERN_INFO "GCT: Filesystem download success.\n"); restore_fs: - set_fs(fs); kfree(tx_buf); return ret; } -- cgit v1.2.3 From c3ee9b76aa93fbf59727e02fac9914c7355108f3 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 28 Sep 2012 16:01:23 -0400 Subject: EHCI: improved logic for isochronous scheduling This patch (as1608) reworks the logic used by ehci-hcd for scheduling isochronous transfers. Now the modular calculations are all based on a window that starts at the last frame scanned for isochronous completions. No transfer descriptors for any earlier frames can possibly remain on the schedule, so there can be no confusion from schedule wrap-around. This removes the need for a "slop" region of arbitrary size. There's no need to check for URBs that are longer than the schedule length. With the old code they could throw things off by wrapping around and appearing to end in the near future rather than the distant future. Now such confusion isn't possible, and the existing test for submissions that extend too far into the future will also catch those that exceed the schedule length. (But there still has to be an initial test to handle the case where the schedule already extends as far into the future as possible.) Delays caused by IRQ latency won't confuse the algorithm unless they are ridiculously long (over 250 ms); they will merely reduce how far into the future new transfers can be scheduled. A few people have reported problems caused by delays of 50 ms or so. Now instead of failing completely, isochronous transfers will experience a brief glitch and then continue normally. (Whether this is truly a good thing is debatable. A latency as large as 50 ms generally indicates a bug is present, and complete failure of audio or video transfers draws people's attention pretty vividly. Making the transfers more robust also makes it easier for such bugs to remain undetected.) Finally, ehci->next_frame is renamed to ehci->last_iso_frame, because that better describes what it is: the last frame to have been scanned for isochronous completions. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 70 ++++++++++++++++++++----------------------- drivers/usb/host/ehci.h | 2 +- 2 files changed, 33 insertions(+), 39 deletions(-) diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 7cf3da7babf..7eb242f27c0 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1361,7 +1361,7 @@ sitd_slot_ok ( * given EHCI_TUNE_FLS and the slop). Or, write a smarter scheduler! */ -#define SCHEDULE_SLOP 80 /* microframes */ +#define SCHEDULING_DELAY 40 /* microframes */ static int iso_stream_schedule ( @@ -1370,7 +1370,7 @@ iso_stream_schedule ( struct ehci_iso_stream *stream ) { - u32 now, next, start, period, span; + u32 now, base, next, start, period, span; int status; unsigned mod = ehci->periodic_size << 3; struct ehci_iso_sched *sched = urb->hcpriv; @@ -1382,12 +1382,6 @@ iso_stream_schedule ( span <<= 3; } - if (span > mod - SCHEDULE_SLOP) { - ehci_dbg (ehci, "iso request %p too long\n", urb); - status = -EFBIG; - goto fail; - } - now = ehci_read_frame_index(ehci) & (mod - 1); /* Typical case: reuse current schedule, stream is still active. @@ -1396,7 +1390,6 @@ iso_stream_schedule ( * slot in the schedule, implicitly assuming URB_ISO_ASAP. */ if (likely (!list_empty (&stream->td_list))) { - u32 excess; /* For high speed devices, allow scheduling within the * isochronous scheduling threshold. For full speed devices @@ -1408,36 +1401,41 @@ iso_stream_schedule ( else next = now; - /* Fell behind (by up to twice the slop amount)? - * We decide based on the time of the last currently-scheduled - * slot, not the time of the next available slot. + /* + * Use ehci->last_iso_frame as the base. There can't be any + * TDs scheduled for earlier than that. */ - excess = (stream->next_uframe - period - next) & (mod - 1); - if (excess >= mod - 2 * SCHEDULE_SLOP) - start = next + excess - mod + period * - DIV_ROUND_UP(mod - excess, period); - else - start = next + excess + period; - if (start - now >= mod) { - ehci_dbg(ehci, "request %p would overflow (%d+%d >= %d)\n", - urb, start - now - period, period, - mod); - status = -EFBIG; + base = ehci->last_iso_frame << 3; + next = (next - base) & (mod - 1); + start = (stream->next_uframe - base) & (mod - 1); + + /* Is the schedule already full? */ + if (unlikely(start < period)) { + ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n", + urb, stream->next_uframe, base, + period, mod); + status = -ENOSPC; goto fail; } + + /* Behind the scheduling threshold? Assume URB_ISO_ASAP. */ + if (unlikely(start < next)) + start += period * DIV_ROUND_UP(next - start, period); + + start += base; } /* need to schedule; when's the next (u)frame we could start? * this is bigger than ehci->i_thresh allows; scheduling itself - * isn't free, the slop should handle reasonably slow cpus. it + * isn't free, the delay should handle reasonably slow cpus. it * can also help high bandwidth if the dma and irq loads don't * jump until after the queue is primed. */ else { int done = 0; - start = SCHEDULE_SLOP + (now & ~0x07); - /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ + base = now & ~0x07; + start = base + SCHEDULING_DELAY; /* find a uframe slot with enough bandwidth. * Early uframes are more precious because full-speed @@ -1464,19 +1462,16 @@ iso_stream_schedule ( /* no room in the schedule */ if (!done) { - ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n", - urb, now, now + mod); + ehci_dbg(ehci, "iso sched full %p", urb); status = -ENOSPC; goto fail; } } /* Tried to schedule too far into the future? */ - if (unlikely(start - now + span - period - >= mod - 2 * SCHEDULE_SLOP)) { - ehci_dbg(ehci, "request %p would overflow (%d+%d >= %d)\n", - urb, start - now, span - period, - mod - 2 * SCHEDULE_SLOP); + if (unlikely(start - base + span - period >= mod)) { + ehci_dbg(ehci, "request %p would overflow (%u+%u >= %u)\n", + urb, start - base, span - period, mod); status = -EFBIG; goto fail; } @@ -1490,7 +1485,7 @@ iso_stream_schedule ( /* Make sure scan_isoc() sees these */ if (ehci->isoc_count == 0) - ehci->next_frame = now >> 3; + ehci->last_iso_frame = now >> 3; return 0; fail: @@ -2220,16 +2215,16 @@ static void scan_isoc(struct ehci_hcd *ehci) now_frame = (uf >> 3) & fmask; live = true; } else { - now_frame = (ehci->next_frame - 1) & fmask; + now_frame = (ehci->last_iso_frame - 1) & fmask; live = false; } ehci->now_frame = now_frame; - frame = ehci->next_frame; for (;;) { union ehci_shadow q, *q_p; __hc32 type, *hw_p; + frame = ehci->last_iso_frame; restart: /* scan each element in frame's queue for completions */ q_p = &ehci->pshadow [frame]; @@ -2334,7 +2329,6 @@ restart: /* Stop when we have reached the current frame */ if (frame == now_frame) break; - frame = (frame + 1) & fmask; + ehci->last_iso_frame = (frame + 1) & fmask; } - ehci->next_frame = now_frame; } diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index da07d98f7d1..0564a63f5eb 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -143,7 +143,7 @@ struct ehci_hcd { /* one per controller */ struct ehci_qh *intr_unlink_last; unsigned intr_unlink_cycle; unsigned now_frame; /* frame from HC hardware */ - unsigned next_frame; /* scan periodic, start here */ + unsigned last_iso_frame; /* last frame scanned for iso */ unsigned intr_count; /* intr activity count */ unsigned isoc_count; /* isoc activity count */ unsigned periodic_count; /* periodic activity count */ -- cgit v1.2.3 From 98cae42d82fe9c9e2b5dacdf391edaa007e147e5 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 28 Sep 2012 16:01:34 -0400 Subject: EHCI: use the isochronous scheduling threshold This patch (as1609) changes the way ehci-hcd uses the "Isochronous Scheduling Threshold" in its calculations. Until now the code has ignored the threshold except for certain Intel PCI-based controllers. This violates the EHCI spec. The new code takes the threshold into account always, removing the need for the fs_i_thresh quirk flag. In addition it implements the "full frame cache" setting more efficiently, moving forward only as far as the next frame boundary instead of always moving forward 8 microframes. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/host/ehci-pci.c | 1 - drivers/usb/host/ehci-sched.c | 12 ++++-------- drivers/usb/host/ehci.h | 1 - 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 6bf6c42481e..61eac96441d 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -503,7 +503,7 @@ static int ehci_init(struct usb_hcd *hcd) /* controllers may cache some of the periodic schedule ... */ if (HCC_ISOC_CACHE(hcc_params)) // full frame cache - ehci->i_thresh = 2 + 8; + ehci->i_thresh = 0; else // N microframes cached ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 2cb7d370c4e..d1407f8d42b 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -103,7 +103,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) } break; case PCI_VENDOR_ID_INTEL: - ehci->fs_i_thresh = 1; if (pdev->device == PCI_DEVICE_ID_INTEL_CE4100_USB) hcd->has_tt = 1; break; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 7eb242f27c0..b764cab2ab9 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1391,15 +1391,11 @@ iso_stream_schedule ( */ if (likely (!list_empty (&stream->td_list))) { - /* For high speed devices, allow scheduling within the - * isochronous scheduling threshold. For full speed devices - * and Intel PCI-based controllers, don't (work around for - * Intel ICH9 bug). - */ - if (!stream->highspeed && ehci->fs_i_thresh) - next = now + ehci->i_thresh; + /* Take the isochronous scheduling threshold into account */ + if (ehci->i_thresh) + next = now + ehci->i_thresh; /* uframe cache */ else - next = now; + next = (now + 2 + 7) & ~0x07; /* full frame cache */ /* * Use ehci->last_iso_frame as the base. There can't be any diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 0564a63f5eb..4ddf7c51616 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -193,7 +193,6 @@ struct ehci_hcd { /* one per controller */ unsigned has_amcc_usb23:1; unsigned need_io_watchdog:1; unsigned amd_pll_fix:1; - unsigned fs_i_thresh:1; /* Intel iso scheduling */ unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ unsigned has_synopsys_hc_bug:1; /* Synopsys HC */ unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */ -- cgit v1.2.3 From 72675479925f53af051ae8a78bcfafeaa47b3eef Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 28 Sep 2012 16:01:40 -0400 Subject: EHCI: replace mult/div with bit-mask operation This patch (as1610) replaces multiplication and divison operations in ehci-hcd's isochronous scheduling code with a bit-mask operation, taking advantage of the fact that isochronous periods are always powers of 2. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index b764cab2ab9..e08e65d8e00 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1416,7 +1416,7 @@ iso_stream_schedule ( /* Behind the scheduling threshold? Assume URB_ISO_ASAP. */ if (unlikely(start < next)) - start += period * DIV_ROUND_UP(next - start, period); + start += (next - start + period - 1) & (- period); start += base; } -- cgit v1.2.3 From a03bede5c73a6876fa891cfe82a65460dc9f4698 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 1 Oct 2012 10:31:53 -0400 Subject: USB: update documentation for URB_ISO_ASAP This patch (as1611) updates the USB documentation and kerneldoc to give a more precise meaning for the URB_ISO_ASAP flag and to explain more of the details of scheduling for isochronous URBs. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/error-codes.txt | 5 ++--- drivers/usb/core/urb.c | 22 +++++++++++++++++++--- include/linux/usb.h | 27 ++++++++++++++++----------- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt index b3f606b81a0..8d1e2a9ebbb 100644 --- a/Documentation/usb/error-codes.txt +++ b/Documentation/usb/error-codes.txt @@ -35,9 +35,8 @@ USB-specific: d) ISO: number_of_packets is < 0 e) various other cases --EAGAIN a) specified ISO start frame too early - b) (using ISO-ASAP) too much scheduled for the future - wait some time and try again. +-EXDEV ISO: URB_ISO_ASAP wasn't specified and all the frames + the URB would be scheduled in have already expired. -EFBIG Host controller driver can't schedule that many ISO frames. diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 9d912bfdcff..3662287e2f4 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -214,9 +214,25 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb); * urb->interval is modified to reflect the actual transfer period used * (normally some power of two units). And for isochronous urbs, * urb->start_frame is modified to reflect when the URB's transfers were - * scheduled to start. Not all isochronous transfer scheduling policies - * will work, but most host controller drivers should easily handle ISO - * queues going from now until 10-200 msec into the future. + * scheduled to start. + * + * Not all isochronous transfer scheduling policies will work, but most + * host controller drivers should easily handle ISO queues going from now + * until 10-200 msec into the future. Drivers should try to keep at + * least one or two msec of data in the queue; many controllers require + * that new transfers start at least 1 msec in the future when they are + * added. If the driver is unable to keep up and the queue empties out, + * the behavior for new submissions is governed by the URB_ISO_ASAP flag. + * If the flag is set, or if the queue is idle, then the URB is always + * assigned to the first available (and not yet expired) slot in the + * endpoint's schedule. If the flag is not set and the queue is active + * then the URB is always assigned to the next slot in the schedule + * following the end of the endpoint's previous URB, even if that slot is + * in the past. When a packet is assigned in this way to a slot that has + * already expired, the packet is not transmitted and the corresponding + * usb_iso_packet_descriptor's status field will return -EXDEV. If this + * would happen to all the packets in the URB, submission fails with a + * -EXDEV error code. * * For control endpoints, the synchronous usb_control_msg() call is * often used (in non-interrupt context) instead of this call. diff --git a/include/linux/usb.h b/include/linux/usb.h index 10278d18709..f92cdf0c145 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1129,8 +1129,8 @@ extern int usb_disabled(void); * Note: URB_DIR_IN/OUT is automatically set in usb_submit_urb(). */ #define URB_SHORT_NOT_OK 0x0001 /* report short reads as errors */ -#define URB_ISO_ASAP 0x0002 /* iso-only, urb->start_frame - * ignored */ +#define URB_ISO_ASAP 0x0002 /* iso-only; use the first unexpired + * slot in the schedule */ #define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */ #define URB_NO_FSBR 0x0020 /* UHCI-specific */ #define URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */ @@ -1309,15 +1309,20 @@ typedef void (*usb_complete_t)(struct urb *); * the transfer interval in the endpoint descriptor is logarithmic. * Device drivers must convert that value to linear units themselves.) * - * Isochronous URBs normally use the URB_ISO_ASAP transfer flag, telling - * the host controller to schedule the transfer as soon as bandwidth - * utilization allows, and then set start_frame to reflect the actual frame - * selected during submission. Otherwise drivers must specify the start_frame - * and handle the case where the transfer can't begin then. However, drivers - * won't know how bandwidth is currently allocated, and while they can - * find the current frame using usb_get_current_frame_number () they can't - * know the range for that frame number. (Ranges for frame counter values - * are HC-specific, and can go from 256 to 65536 frames from "now".) + * If an isochronous endpoint queue isn't already running, the host + * controller will schedule a new URB to start as soon as bandwidth + * utilization allows. If the queue is running then a new URB will be + * scheduled to start in the first transfer slot following the end of the + * preceding URB, if that slot has not already expired. If the slot has + * expired (which can happen when IRQ delivery is delayed for a long time), + * the scheduling behavior depends on the URB_ISO_ASAP flag. If the flag + * is clear then the URB will be scheduled to start in the expired slot, + * implying that some of its packets will not be transferred; if the flag + * is set then the URB will be scheduled in the first unexpired slot, + * breaking the queue's synchronization. Upon URB completion, the + * start_frame field will be set to the (micro)frame number in which the + * transfer was scheduled. Ranges for frame counter values are HC-specific + * and can go from as low as 256 to as high as 65536 frames. * * Isochronous URBs have a different data transfer model, in part because * the quality of service is only "best effort". Callers provide specially -- cgit v1.2.3 From 4005ad4390bf698e3bdae9567e79242ec0584097 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 1 Oct 2012 10:32:01 -0400 Subject: EHCI: implement new semantics for URB_ISO_ASAP This patch (as1612) updates the isochronous scheduling and processing in ehci-hcd to match the new semantics for URB_ISO_ASAP. It also adds a missing "unlikely" in sitd_complete() to match the corresponding statement in itd_complete(), and it increments urb->error_count in a couple of places that had been overlooked. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index e08e65d8e00..b538a4d62d5 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1386,8 +1386,8 @@ iso_stream_schedule ( /* Typical case: reuse current schedule, stream is still active. * Hopefully there are no gaps from the host falling behind - * (irq delays etc), but if there are we'll take the next - * slot in the schedule, implicitly assuming URB_ISO_ASAP. + * (irq delays etc). If there are, the behavior depends on + * whether URB_ISO_ASAP is set. */ if (likely (!list_empty (&stream->td_list))) { @@ -1414,9 +1414,25 @@ iso_stream_schedule ( goto fail; } - /* Behind the scheduling threshold? Assume URB_ISO_ASAP. */ - if (unlikely(start < next)) - start += (next - start + period - 1) & (- period); + /* Behind the scheduling threshold? */ + if (unlikely(start < next)) { + + /* USB_ISO_ASAP: Round up to the first available slot */ + if (urb->transfer_flags & URB_ISO_ASAP) + start += (next - start + period - 1) & -period; + + /* + * Not ASAP: Use the next slot in the stream. If + * the entire URB falls before the threshold, fail. + */ + else if (start + span - period < next) { + ehci_dbg(ehci, "iso urb late %p (%u+%u < %u)\n", + urb, start + base, + span - period, next + base); + status = -EXDEV; + goto fail; + } + } start += base; } @@ -1699,7 +1715,7 @@ static bool itd_complete(struct ehci_hcd *ehci, struct ehci_itd *itd) urb->actual_length += desc->actual_length; } else { /* URB was too late */ - desc->status = -EXDEV; + urb->error_count++; } } @@ -2072,7 +2088,7 @@ static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd) t = hc32_to_cpup(ehci, &sitd->hw_results); /* report transfer status */ - if (t & SITD_ERRS) { + if (unlikely(t & SITD_ERRS)) { urb->error_count++; if (t & SITD_STS_DBE) desc->status = usb_pipein (urb->pipe) @@ -2082,6 +2098,9 @@ static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd) desc->status = -EOVERFLOW; else /* XACT, MMF, etc */ desc->status = -EPROTO; + } else if (unlikely(t & SITD_STS_ACTIVE)) { + /* URB was too late */ + urb->error_count++; } else { desc->status = 0; desc->actual_length = desc->length - SITD_LENGTH(t); -- cgit v1.2.3 From c44b225077bb1fb25ed5cd5c4f226897b91bedd4 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 1 Oct 2012 10:32:09 -0400 Subject: UHCI: implement new semantics for URB_ISO_ASAP This patch (as1613) updates the isochronous scheduling in uhci-hcd to match the new semantics for URB_ISO_ASAP. The amount of code alteration is smaller than it looks because of a change in the indentation level. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-q.c | 73 +++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index d2c6f5ac462..15921fd5504 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -1256,7 +1256,8 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, struct uhci_qh *qh) { struct uhci_td *td = NULL; /* Since urb->number_of_packets > 0 */ - int i, frame; + int i; + unsigned frame, next; unsigned long destination, status; struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; @@ -1265,37 +1266,29 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, urb->number_of_packets >= UHCI_NUMFRAMES) return -EFBIG; + uhci_get_current_frame_number(uhci); + /* Check the period and figure out the starting frame number */ if (!qh->bandwidth_reserved) { qh->period = urb->interval; - if (urb->transfer_flags & URB_ISO_ASAP) { - qh->phase = -1; /* Find the best phase */ - i = uhci_check_bandwidth(uhci, qh); - if (i) - return i; - - /* Allow a little time to allocate the TDs */ - uhci_get_current_frame_number(uhci); - frame = uhci->frame_number + 10; - - /* Move forward to the first frame having the - * correct phase */ - urb->start_frame = frame + ((qh->phase - frame) & - (qh->period - 1)); - } else { - i = urb->start_frame - uhci->last_iso_frame; - if (i <= 0 || i >= UHCI_NUMFRAMES) - return -EINVAL; - qh->phase = urb->start_frame & (qh->period - 1); - i = uhci_check_bandwidth(uhci, qh); - if (i) - return i; - } + qh->phase = -1; /* Find the best phase */ + i = uhci_check_bandwidth(uhci, qh); + if (i) + return i; + + /* Allow a little time to allocate the TDs */ + next = uhci->frame_number + 10; + frame = qh->phase; + + /* Round up to the first available slot */ + frame += (next - frame + qh->period - 1) & -qh->period; } else if (qh->period != urb->interval) { return -EINVAL; /* Can't change the period */ } else { + next = uhci->frame_number + 2; + /* Find the next unused frame */ if (list_empty(&qh->queue)) { frame = qh->iso_frame; @@ -1308,25 +1301,31 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, lurb->number_of_packets * lurb->interval; } - if (urb->transfer_flags & URB_ISO_ASAP) { - /* Skip some frames if necessary to insure - * the start frame is in the future. + + /* Fell behind? */ + if (uhci_frame_before_eq(frame, next)) { + + /* USB_ISO_ASAP: Round up to the first available slot */ + if (urb->transfer_flags & URB_ISO_ASAP) + frame += (next - frame + qh->period - 1) & + -qh->period; + + /* + * Not ASAP: Use the next slot in the stream. If + * the entire URB falls before the threshold, fail. */ - uhci_get_current_frame_number(uhci); - if (uhci_frame_before_eq(frame, uhci->frame_number)) { - frame = uhci->frame_number + 1; - frame += ((qh->phase - frame) & - (qh->period - 1)); - } - } /* Otherwise pick up where the last URB leaves off */ - urb->start_frame = frame; + else if (!uhci_frame_before_eq(next, + frame + (urb->number_of_packets - 1) * + qh->period)) + return -EXDEV; + } } /* Make sure we won't have to go too far into the future */ if (uhci_frame_before_eq(uhci->last_iso_frame + UHCI_NUMFRAMES, - urb->start_frame + urb->number_of_packets * - urb->interval)) + frame + urb->number_of_packets * urb->interval)) return -EFBIG; + urb->start_frame = frame; status = TD_CTRL_ACTIVE | TD_CTRL_IOS; destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); -- cgit v1.2.3 From 6a41b4d3fe8cd4cc95181516fc6fba7b1747a27c Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 1 Oct 2012 10:32:15 -0400 Subject: OHCI: implement new semantics for URB_ISO_ASAP This patch (as1614) updates the isochronous scheduling in ohci-hcd to match the new semantics for URB_ISO_ASAP. Testing revealed a hardware bug in the way my OHCI controller handles expired isochronous TDs; consequently the patch tries hard to avoid creating them (unlike the ehci-hcd and uhci-hcd drivers). Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hcd.c | 36 ++++++++++++++++++++++++++++++++---- drivers/usb/host/ohci-q.c | 4 ++-- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 4a1d64d9233..cfc1da30667 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -231,13 +231,41 @@ static int ohci_urb_enqueue ( frame &= ~(ed->interval - 1); frame |= ed->branch; urb->start_frame = frame; + } + } else if (ed->type == PIPE_ISOCHRONOUS) { + u16 next = ohci_frame_no(ohci) + 2; + u16 frame = ed->last_iso + ed->interval; + + /* Behind the scheduling threshold? */ + if (unlikely(tick_before(frame, next))) { - /* yes, only URB_ISO_ASAP is supported, and - * urb->start_frame is never used as input. + /* USB_ISO_ASAP: Round up to the first available slot */ + if (urb->transfer_flags & URB_ISO_ASAP) + frame += (next - frame + ed->interval - 1) & + -ed->interval; + + /* + * Not ASAP: Use the next slot in the stream. If + * the entire URB falls before the threshold, fail. */ + else if (tick_before(frame + ed->interval * + (urb->number_of_packets - 1), next)) { + retval = -EXDEV; + usb_hcd_unlink_urb_from_ep(hcd, urb); + goto fail; + } + + /* + * Some OHCI hardware doesn't handle late TDs + * correctly. After retiring them it proceeds to + * the next ED instead of the next TD. Therefore + * we have to omit the late TDs entirely. + */ + urb_priv->td_cnt = DIV_ROUND_UP(next - frame, + ed->interval); } - } else if (ed->type == PIPE_ISOCHRONOUS) - urb->start_frame = ed->last_iso + ed->interval; + urb->start_frame = frame; + } /* fill the TDs and link them to the ed; and * enable that part of the schedule, if needed diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index c5a1ea9145f..177a213790d 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -596,7 +596,6 @@ static void td_submit_urb ( urb_priv->ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_C); } - urb_priv->td_cnt = 0; list_add (&urb_priv->pending, &ohci->pending); if (data_len) @@ -672,7 +671,8 @@ static void td_submit_urb ( * we could often reduce the number of TDs here. */ case PIPE_ISOCHRONOUS: - for (cnt = 0; cnt < urb->number_of_packets; cnt++) { + for (cnt = urb_priv->td_cnt; cnt < urb->number_of_packets; + cnt++) { int frame = urb->start_frame; // FIXME scheduling should handle frame counter -- cgit v1.2.3 From 6efd0f73cc8d748bfcccb23a5ee0b7e000441940 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:15 +0200 Subject: USB: EHCI: remove IXP4xx EHCI driver This driver is not registered by any in-tree user. If needed it the EHCI driver can be reinstatied using the ehci-platform driver with caps_offset to 0x100. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 5 -- drivers/usb/host/ehci-ixp4xx.c | 139 ----------------------------------------- 2 files changed, 144 deletions(-) delete mode 100644 drivers/usb/host/ehci-ixp4xx.c diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 61eac96441d..01227000c3e 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1249,11 +1249,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_orion_driver #endif -#ifdef CONFIG_ARCH_IXP4XX -#include "ehci-ixp4xx.c" -#define PLATFORM_DRIVER ixp4xx_ehci_driver -#endif - #ifdef CONFIG_USB_W90X900_EHCI #include "ehci-w90x900.c" #define PLATFORM_DRIVER ehci_hcd_w90x900_driver diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c deleted file mode 100644 index f224c0a48be..00000000000 --- a/drivers/usb/host/ehci-ixp4xx.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * IXP4XX EHCI Host Controller Driver - * - * Author: Vladimir Barinov - * - * Based on "ehci-fsl.c" by Randy Vinson - * - * 2007 (c) MontaVista Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ - -#include - -static int ixp4xx_ehci_init(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval = 0; - - ehci->big_endian_desc = 1; - ehci->big_endian_mmio = 1; - - ehci->caps = hcd->regs + 0x100; - - hcd->has_tt = 1; - - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 0); - - return retval; -} - -static const struct hc_driver ixp4xx_ehci_hc_driver = { - .description = hcd_name, - .product_desc = "IXP4XX EHCI Host Controller", - .hcd_priv_size = sizeof(struct ehci_hcd), - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - .reset = ixp4xx_ehci_init, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - .get_frame_number = ehci_get_frame, - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, -#if defined(CONFIG_PM) - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, -#endif - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static int ixp4xx_ehci_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - const struct hc_driver *driver = &ixp4xx_ehci_hc_driver; - struct resource *res; - int irq; - int retval; - - if (usb_disabled()) - return -ENODEV; - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no IRQ. Check %s setup!\n", - dev_name(&pdev->dev)); - return -ENODEV; - } - irq = res->start; - - hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); - if (!hcd) { - retval = -ENOMEM; - goto fail_create_hcd; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no register addr. Check %s setup!\n", - dev_name(&pdev->dev)); - retval = -ENODEV; - goto fail_request_resource; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - hcd->regs = devm_request_and_ioremap(&pdev->dev, res); - if (hcd->regs == NULL) { - dev_dbg(&pdev->dev, "error mapping memory\n"); - retval = -EFAULT; - goto fail_request_resource; - } - - retval = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (retval) - goto fail_request_resource; - - return retval; - -fail_request_resource: - usb_put_hcd(hcd); -fail_create_hcd: - dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval); - return retval; -} - -static int ixp4xx_ehci_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - usb_put_hcd(hcd); - - return 0; -} - -MODULE_ALIAS("platform:ixp4xx-ehci"); - -static struct platform_driver ixp4xx_ehci_driver = { - .probe = ixp4xx_ehci_probe, - .remove = ixp4xx_ehci_remove, - .driver = { - .name = "ixp4xx-ehci", - }, -}; -- cgit v1.2.3 From 7bccfcd2eb09297e0406b38cfac8e1f3001964f3 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:16 +0200 Subject: USB: OHCI: remove ohci-pcc-soc driver. This driver is not registered by any in-tree users, and if really needed by some out of tree user, the same functionnality can be restored using the ohci-platform driver using the following platform_data parameters: big_endian_desc = 1 big_endian_mmio = 1 no_big_frame_no = 1 Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 10 -- drivers/usb/host/ohci-hcd.c | 5 - drivers/usb/host/ohci-ppc-soc.c | 216 ---------------------------------------- 3 files changed, 231 deletions(-) delete mode 100644 drivers/usb/host/ohci-ppc-soc.c diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 3f1431d37e1..e6b64f60608 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -333,16 +333,6 @@ config USB_OHCI_ATH79 Enables support for the built-in OHCI controller present on the Atheros AR71XX/AR7240 SoCs. -config USB_OHCI_HCD_PPC_SOC - bool "OHCI support for on-chip PPC USB controller" - depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) - default y - select USB_OHCI_BIG_ENDIAN_DESC - select USB_OHCI_BIG_ENDIAN_MMIO - ---help--- - Enables support for the USB controller on the MPC52xx or - STB03xxx processor chip. If unsure, say Y. - config USB_OHCI_HCD_PPC_OF_BE bool "OHCI support for OF platform bus (big endian)" depends on USB_OHCI_HCD && PPC_OF diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index cfc1da30667..4c4d652a446 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1067,11 +1067,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ohci_hcd_pnx8550_driver #endif -#ifdef CONFIG_USB_OHCI_HCD_PPC_SOC -#include "ohci-ppc-soc.c" -#define PLATFORM_DRIVER ohci_hcd_ppc_soc_driver -#endif - #ifdef CONFIG_ARCH_AT91 #include "ohci-at91.c" #define PLATFORM_DRIVER ohci_hcd_at91_driver diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c deleted file mode 100644 index 185c39ed81b..00000000000 --- a/drivers/usb/host/ohci-ppc-soc.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber - * (C) Copyright 2000-2002 David Brownell - * (C) Copyright 2002 Hewlett-Packard Company - * (C) Copyright 2003-2005 MontaVista Software Inc. - * - * Bus Glue for PPC On-Chip OHCI driver - * Tested on Freescale MPC5200 and IBM STB04xxx - * - * Modified by Dale Farnsworth from ohci-sa1111.c - * - * This file is licenced under the GPL. - */ - -#include -#include - -/* configure so an HC device and id are always provided */ -/* always called with process context; sleeping is OK */ - -/** - * usb_hcd_ppc_soc_probe - initialize On-Chip HCDs - * Context: !in_interrupt() - * - * Allocates basic resources for this USB host controller. - * - * Store this function in the HCD's struct pci_driver as probe(). - */ -static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, - struct platform_device *pdev) -{ - int retval; - struct usb_hcd *hcd; - struct ohci_hcd *ohci; - struct resource *res; - int irq; - - pr_debug("initializing PPC-SOC USB Controller\n"); - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - pr_debug("%s: no irq\n", __FILE__); - return -ENODEV; - } - irq = res->start; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - pr_debug("%s: no reg addr\n", __FILE__); - return -ENODEV; - } - - hcd = usb_create_hcd(driver, &pdev->dev, "PPC-SOC USB"); - if (!hcd) - return -ENOMEM; - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - pr_debug("%s: request_mem_region failed\n", __FILE__); - retval = -EBUSY; - goto err1; - } - - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - pr_debug("%s: ioremap failed\n", __FILE__); - retval = -ENOMEM; - goto err2; - } - - ohci = hcd_to_ohci(hcd); - ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; - -#ifdef CONFIG_PPC_MPC52xx - /* MPC52xx doesn't need frame_no shift */ - ohci->flags |= OHCI_QUIRK_FRAME_NO; -#endif - ohci_hcd_init(ohci); - - retval = usb_add_hcd(hcd, irq, 0); - if (retval == 0) - return retval; - - pr_debug("Removing PPC-SOC USB Controller\n"); - - iounmap(hcd->regs); - err2: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - err1: - usb_put_hcd(hcd); - return retval; -} - - -/* may be called without controller electrically present */ -/* may be called with controller, bus, and devices active */ - -/** - * usb_hcd_ppc_soc_remove - shutdown processing for On-Chip HCDs - * @pdev: USB Host Controller being removed - * Context: !in_interrupt() - * - * Reverses the effect of usb_hcd_ppc_soc_probe(). - * It is always called from a thread - * context, normally "rmmod", "apmd", or something similar. - * - */ -static void usb_hcd_ppc_soc_remove(struct usb_hcd *hcd, - struct platform_device *pdev) -{ - usb_remove_hcd(hcd); - - pr_debug("stopping PPC-SOC USB Controller\n"); - - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); -} - -static int __devinit -ohci_ppc_soc_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int ret; - - if ((ret = ohci_init(ohci)) < 0) - return ret; - - if ((ret = ohci_run(ohci)) < 0) { - dev_err(hcd->self.controller, "can't start %s\n", - hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - - return 0; -} - -static const struct hc_driver ohci_ppc_soc_hc_driver = { - .description = hcd_name, - .hcd_priv_size = sizeof(struct ohci_hcd), - - /* - * generic hardware linkage - */ - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .start = ohci_ppc_soc_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ohci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif - .start_port_reset = ohci_start_port_reset, -}; - -static int ohci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) -{ - int ret; - - if (usb_disabled()) - return -ENODEV; - - ret = usb_hcd_ppc_soc_probe(&ohci_ppc_soc_hc_driver, pdev); - return ret; -} - -static int ohci_hcd_ppc_soc_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_hcd_ppc_soc_remove(hcd, pdev); - return 0; -} - -static struct platform_driver ohci_hcd_ppc_soc_driver = { - .probe = ohci_hcd_ppc_soc_drv_probe, - .remove = ohci_hcd_ppc_soc_drv_remove, - .shutdown = usb_hcd_platform_shutdown, -#ifdef CONFIG_PM - /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ - /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ -#endif - .driver = { - .name = "ppc-soc-ohci", - .owner = THIS_MODULE, - }, -}; - -MODULE_ALIAS("platform:ppc-soc-ohci"); -- cgit v1.2.3 From afe046be983f7da53c4bdcfa9a7689d163f08196 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:17 +0200 Subject: MIPS: Loongson 1B: use ehci-platform instead of ehci-ls1x. The Loongson 1B EHCI driver does nothing more than what the EHCI platform driver already does, so use the generic implementation. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/mips/configs/ls1b_defconfig | 1 + arch/mips/loongson1/common/platform.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/mips/configs/ls1b_defconfig b/arch/mips/configs/ls1b_defconfig index 80cff8bea8e..7eb75543ca1 100644 --- a/arch/mips/configs/ls1b_defconfig +++ b/arch/mips/configs/ls1b_defconfig @@ -76,6 +76,7 @@ CONFIG_HID_GENERIC=m CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y # CONFIG_USB_EHCI_TT_NEWSCHED is not set CONFIG_USB_STORAGE=m CONFIG_USB_SERIAL=m diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c index e92d59c4bd7..2874bf22441 100644 --- a/arch/mips/loongson1/common/platform.c +++ b/arch/mips/loongson1/common/platform.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -107,13 +108,18 @@ static struct resource ls1x_ehci_resources[] = { }, }; +static struct usb_ehci_pdata ls1x_ehci_pdata = { + .port_power_off = 1, +}; + struct platform_device ls1x_ehci_device = { - .name = "ls1x-ehci", + .name = "ehci-platform", .id = -1, .num_resources = ARRAY_SIZE(ls1x_ehci_resources), .resource = ls1x_ehci_resources, .dev = { .dma_mask = &ls1x_ehci_dmamask, + .platform_data = &ls1x_ehci_pdata, }, }; -- cgit v1.2.3 From ead92fae12902e3cfb79e8747c20b85c4b1f5414 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:18 +0200 Subject: USB: EHCI: remove Loongson 1B EHCI driver. The platform code registering the Loongson 1B EHCI driver has now been converted to register the ehci-platform driver instead, thus obsoleting the ehci-ls1x driver, which can be removed. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 5 -- drivers/usb/host/ehci-ls1x.c | 147 ------------------------------------------- 2 files changed, 152 deletions(-) delete mode 100644 drivers/usb/host/ehci-ls1x.c diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 01227000c3e..1f7c14b8a32 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1319,11 +1319,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_mv_driver #endif -#ifdef CONFIG_MACH_LOONGSON1 -#include "ehci-ls1x.c" -#define PLATFORM_DRIVER ehci_ls1x_driver -#endif - #ifdef CONFIG_MIPS_SEAD3 #include "ehci-sead3.c" #define PLATFORM_DRIVER ehci_hcd_sead3_driver diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c deleted file mode 100644 index ca759652626..00000000000 --- a/drivers/usb/host/ehci-ls1x.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Bus Glue for Loongson LS1X built-in EHCI controller. - * - * Copyright (c) 2012 Zhang, Keguang - * - * 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. - */ - - -#include - -static int ehci_ls1x_reset(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int ret; - - ehci->caps = hcd->regs; - - ret = ehci_setup(hcd); - if (ret) - return ret; - - ehci_port_power(ehci, 0); - - return 0; -} - -static const struct hc_driver ehci_ls1x_hc_driver = { - .description = hcd_name, - .product_desc = "LOONGSON1 EHCI", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - - /* - * basic lifecycle operations - */ - .reset = ehci_ls1x_reset, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static int ehci_hcd_ls1x_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct resource *res; - int irq; - int ret; - - pr_debug("initializing loongson1 ehci USB Controller\n"); - - if (usb_disabled()) - return -ENODEV; - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no IRQ. Check %s setup!\n", - dev_name(&pdev->dev)); - return -ENODEV; - } - irq = res->start; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, - "Found HC with no register addr. Check %s setup!\n", - dev_name(&pdev->dev)); - return -ENODEV; - } - - hcd = usb_create_hcd(&ehci_ls1x_hc_driver, &pdev->dev, - dev_name(&pdev->dev)); - if (!hcd) - return -ENOMEM; - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - hcd->regs = devm_request_and_ioremap(&pdev->dev, res); - if (hcd->regs == NULL) { - dev_dbg(&pdev->dev, "error mapping memory\n"); - ret = -EFAULT; - goto err_put_hcd; - } - - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (ret) - goto err_put_hcd; - - return ret; - -err_put_hcd: - usb_put_hcd(hcd); - return ret; -} - -static int ehci_hcd_ls1x_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - usb_put_hcd(hcd); - - return 0; -} - -static struct platform_driver ehci_ls1x_driver = { - .probe = ehci_hcd_ls1x_probe, - .remove = ehci_hcd_ls1x_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = "ls1x-ehci", - .owner = THIS_MODULE, - }, -}; - -MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ls1x-ehci"); -- cgit v1.2.3 From 1bee8d4a23f25b87c58df81656300f741d711b19 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:19 +0200 Subject: MIPS: Netlogic: use ehci-platform driver The EHCI platform driver is suitable for use by the Netlogic XLR platform since there is nothing specific that the EHCI XLR platform driver does. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/mips/netlogic/xlr/platform.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/mips/netlogic/xlr/platform.c b/arch/mips/netlogic/xlr/platform.c index 71b44d82621..144c5c60984 100644 --- a/arch/mips/netlogic/xlr/platform.c +++ b/arch/mips/netlogic/xlr/platform.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -123,8 +124,12 @@ static u64 xls_usb_dmamask = ~(u32)0; }, \ } +static struct usb_ehci_pdata xls_usb_ehci_pdata = { + .caps_offset = 0, +}; + static struct platform_device xls_usb_ehci_device = - USB_PLATFORM_DEV("ehci-xls", 0, PIC_USB_IRQ); + USB_PLATFORM_DEV("ehci-platform", 0, PIC_USB_IRQ); static struct platform_device xls_usb_ohci_device_0 = USB_PLATFORM_DEV("ohci-xls-0", 1, PIC_USB_IRQ); static struct platform_device xls_usb_ohci_device_1 = @@ -172,6 +177,7 @@ int xls_platform_usb_init(void) memres = CPHYSADDR((unsigned long)usb_mmio); xls_usb_ehci_device.resource[0].start = memres; xls_usb_ehci_device.resource[0].end = memres + 0x400 - 1; + xls_usb_ehci_device.dev.platform_data = &xls_usb_ehci_pdata; memres += 0x400; xls_usb_ohci_device_0.resource[0].start = memres; -- cgit v1.2.3 From 6d39944ee85fb46cd499b16231cbb10a00e3d878 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:20 +0200 Subject: USB: EHCI: remove Netlogic XLS EHCI driver The platform code has been migrated to register the ehci-platform driver, thus obsoleting the ehci-xls driver, which can be removed. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 5 -- drivers/usb/host/ehci-xls.c | 142 -------------------------------------------- 2 files changed, 147 deletions(-) delete mode 100644 drivers/usb/host/ehci-xls.c diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 1f7c14b8a32..6202407b2a6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1309,11 +1309,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_grlib_driver #endif -#ifdef CONFIG_CPU_XLR -#include "ehci-xls.c" -#define PLATFORM_DRIVER ehci_xls_driver -#endif - #ifdef CONFIG_USB_EHCI_MV #include "ehci-mv.c" #define PLATFORM_DRIVER ehci_mv_driver diff --git a/drivers/usb/host/ehci-xls.c b/drivers/usb/host/ehci-xls.c deleted file mode 100644 index 8dc6a22d90b..00000000000 --- a/drivers/usb/host/ehci-xls.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * EHCI HCD for Netlogic XLS processors. - * - * (C) Copyright 2011 Netlogic Microsystems Inc. - * - * Based on various ehci-*.c drivers - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - */ - -#include - -static int ehci_xls_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - - ehci->caps = hcd->regs; - - return ehci_setup(hcd); -} - -int ehci_xls_probe_internal(const struct hc_driver *driver, - struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct resource *res; - int retval, irq; - - /* Get our IRQ from an earlier registered Platform Resource */ - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "Found HC with no IRQ. Check %s setup!\n", - dev_name(&pdev->dev)); - return -ENODEV; - } - - /* Get our Memory Handle */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Error: MMIO Handle %s setup!\n", - dev_name(&pdev->dev)); - return -ENODEV; - } - hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); - if (!hcd) { - retval = -ENOMEM; - goto err1; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, - driver->description)) { - dev_dbg(&pdev->dev, "controller already in use\n"); - retval = -EBUSY; - goto err2; - } - hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); - - if (hcd->regs == NULL) { - dev_dbg(&pdev->dev, "error mapping memory\n"); - retval = -EFAULT; - goto err3; - } - - retval = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (retval != 0) - goto err4; - return retval; - -err4: - iounmap(hcd->regs); -err3: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err2: - usb_put_hcd(hcd); -err1: - dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), - retval); - return retval; -} - -static struct hc_driver ehci_xls_hc_driver = { - .description = hcd_name, - .product_desc = "XLS EHCI Host Controller", - .hcd_priv_size = sizeof(struct ehci_hcd), - .irq = ehci_irq, - .flags = HCD_USB2 | HCD_MEMORY, - .reset = ehci_xls_setup, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - - .get_frame_number = ehci_get_frame, - - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static int ehci_xls_probe(struct platform_device *pdev) -{ - if (usb_disabled()) - return -ENODEV; - - return ehci_xls_probe_internal(&ehci_xls_hc_driver, pdev); -} - -static int ehci_xls_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); - return 0; -} - -MODULE_ALIAS("ehci-xls"); - -static struct platform_driver ehci_xls_driver = { - .probe = ehci_xls_probe, - .remove = ehci_xls_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = "ehci-xls", - }, -}; -- cgit v1.2.3 From 4534874a8720a361845dce47d310a98e9aac8aeb Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:21 +0200 Subject: USB: EHCI: add no_io_watchdog platform_data parameter to ehci-platform Enhance the ehci-platform driver to also accept no_io_watchdog as a platform data parameter. When no_io_watchdog is set to 1, the ehci controller will set ehci->need_io_watchdog to 0. Since most EHCI controllers do need the I/O watchdog to be on, only let those which need it to turn the watchdog off. Make sure that we change need_io_watchdog after the call to ehci_setup() because ehci_setup() will unconditionnaly set need_io_watchdog to 1. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-platform.c | 2 ++ include/linux/usb/ehci_pdriver.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 764e0100b6f..607adf9adb8 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -38,6 +38,8 @@ static int ehci_platform_reset(struct usb_hcd *hcd) if (retval) return retval; + if (pdata->no_io_watchdog) + ehci->need_io_watchdog = 0; if (pdata->port_power_on) ehci_port_power(ehci, 1); if (pdata->port_power_off) diff --git a/include/linux/usb/ehci_pdriver.h b/include/linux/usb/ehci_pdriver.h index c9d09f8b7ff..67ac74bde6d 100644 --- a/include/linux/usb/ehci_pdriver.h +++ b/include/linux/usb/ehci_pdriver.h @@ -29,6 +29,8 @@ * initialization. * @port_power_off: set to 1 if the controller needs to be powered down * after initialization. + * @no_io_watchdog: set to 1 if the controller does not need the I/O + * watchdog to run. * * These are general configuration options for the EHCI controller. All of * these options are activating more or less workarounds for some hardware. @@ -41,6 +43,7 @@ struct usb_ehci_pdata { unsigned big_endian_mmio:1; unsigned port_power_on:1; unsigned port_power_off:1; + unsigned no_io_watchdog:1; /* Turn on all power and clocks */ int (*power_on)(struct platform_device *pdev); -- cgit v1.2.3 From 2be350fafe3fe09765026f41d250dc5d3f000b1a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:22 +0200 Subject: MIPS: Alchemy: use the ehci platform driver Use the ehci platform driver power_{on,suspend,off} callbacks to perform the USB block gate enabling/disabling as what the ehci-au1xxx.c driver does. Update the db1200 and db1300 defconfigs to now select the EHCI platform driver. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/mips/alchemy/common/platform.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index c0f3ce6dcb5..b9a5f6dd30d 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -122,6 +123,25 @@ static void __init alchemy_setup_uarts(int ctype) static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32); static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32); +/* Power on callback for the ehci platform driver */ +static int alchemy_ehci_power_on(struct platform_device *pdev) +{ + return alchemy_usb_control(ALCHEMY_USB_EHCI0, 1); +} + +/* Power off/suspend callback for the ehci platform driver */ +static void alchemy_ehci_power_off(struct platform_device *pdev) +{ + alchemy_usb_control(ALCHEMY_USB_EHCI0, 0); +} + +static struct usb_ehci_pdata alchemy_ehci_pdata = { + .no_io_watchdog = 1, + .power_on = alchemy_ehci_power_on, + .power_off = alchemy_ehci_power_off, + .power_suspend = alchemy_ehci_power_off, +}; + static unsigned long alchemy_ohci_data[][2] __initdata = { [ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT }, [ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT }, @@ -188,9 +208,10 @@ static void __init alchemy_setup_usb(int ctype) res[1].start = alchemy_ehci_data[ctype][1]; res[1].end = res[1].start; res[1].flags = IORESOURCE_IRQ; - pdev->name = "au1xxx-ehci"; + pdev->name = "ehci-platform"; pdev->id = 0; pdev->dev.dma_mask = &alchemy_ehci_dmamask; + pdev->dev.platform_data = &alchemy_ehci_pdata; if (platform_device_register(pdev)) printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n"); -- cgit v1.2.3 From 1de7d89c76350de456143503d52447a466b4025e Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:23 +0200 Subject: USB: EHCI: remove Alchemy EHCI driver The platform code has been converted to use the ehci-platform driver instead thus obsoleting the ehci-au1xxx driver, which can be removed. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-au1xxx.c | 184 ----------------------------------------- drivers/usb/host/ehci-hcd.c | 5 -- 2 files changed, 189 deletions(-) delete mode 100644 drivers/usb/host/ehci-au1xxx.c diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c deleted file mode 100644 index 65c945eb414..00000000000 --- a/drivers/usb/host/ehci-au1xxx.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * EHCI HCD (Host Controller Driver) for USB. - * - * Bus Glue for AMD Alchemy Au1xxx - * - * Based on "ohci-au1xxx.c" by Matt Porter - * - * Modified for AMD Alchemy Au1200 EHC - * by K.Boge - * - * This file is licenced under the GPL. - */ - -#include -#include - - -extern int usb_disabled(void); - -static int au1xxx_ehci_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int ret; - - ehci->caps = hcd->regs; - ret = ehci_setup(hcd); - - ehci->need_io_watchdog = 0; - return ret; -} - -static const struct hc_driver ehci_au1xxx_hc_driver = { - .description = hcd_name, - .product_desc = "Au1xxx EHCI", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - - /* - * basic lifecycle operations - * - * FIXME -- ehci_init() doesn't do enough here. - * See ehci-ppc-soc for a complete implementation. - */ - .reset = au1xxx_ehci_setup, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct resource *res; - int ret; - - if (usb_disabled()) - return -ENODEV; - - if (pdev->resource[1].flags != IORESOURCE_IRQ) { - pr_debug("resource[1] is not IORESOURCE_IRQ"); - return -ENOMEM; - } - hcd = usb_create_hcd(&ehci_au1xxx_hc_driver, &pdev->dev, "Au1xxx"); - if (!hcd) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - hcd->regs = devm_request_and_ioremap(&pdev->dev, res); - if (!hcd->regs) { - pr_debug("devm_request_and_ioremap failed"); - ret = -ENOMEM; - goto err1; - } - - if (alchemy_usb_control(ALCHEMY_USB_EHCI0, 1)) { - printk(KERN_INFO "%s: controller init failed!\n", pdev->name); - ret = -ENODEV; - goto err1; - } - - ret = usb_add_hcd(hcd, pdev->resource[1].start, - IRQF_SHARED); - if (ret == 0) { - platform_set_drvdata(pdev, hcd); - return ret; - } - - alchemy_usb_control(ALCHEMY_USB_EHCI0, 0); -err1: - usb_put_hcd(hcd); - return ret; -} - -static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - alchemy_usb_control(ALCHEMY_USB_EHCI0, 0); - usb_put_hcd(hcd); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -#ifdef CONFIG_PM -static int ehci_hcd_au1xxx_drv_suspend(struct device *dev) -{ - struct usb_hcd *hcd = dev_get_drvdata(dev); - bool do_wakeup = device_may_wakeup(dev); - int rc; - - rc = ehci_suspend(hcd, do_wakeup); - alchemy_usb_control(ALCHEMY_USB_EHCI0, 0); - - return rc; -} - -static int ehci_hcd_au1xxx_drv_resume(struct device *dev) -{ - struct usb_hcd *hcd = dev_get_drvdata(dev); - - alchemy_usb_control(ALCHEMY_USB_EHCI0, 1); - ehci_resume(hcd, false); - - return 0; -} - -static const struct dev_pm_ops au1xxx_ehci_pmops = { - .suspend = ehci_hcd_au1xxx_drv_suspend, - .resume = ehci_hcd_au1xxx_drv_resume, -}; - -#define AU1XXX_EHCI_PMOPS &au1xxx_ehci_pmops - -#else -#define AU1XXX_EHCI_PMOPS NULL -#endif - -static struct platform_driver ehci_hcd_au1xxx_driver = { - .probe = ehci_hcd_au1xxx_drv_probe, - .remove = ehci_hcd_au1xxx_drv_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = "au1xxx-ehci", - .owner = THIS_MODULE, - .pm = AU1XXX_EHCI_PMOPS, - } -}; - -MODULE_ALIAS("platform:au1xxx-ehci"); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 6202407b2a6..add37bc4bc1 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1219,11 +1219,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_hcd_sh_driver #endif -#ifdef CONFIG_MIPS_ALCHEMY -#include "ehci-au1xxx.c" -#define PLATFORM_DRIVER ehci_hcd_au1xxx_driver -#endif - #ifdef CONFIG_USB_EHCI_HCD_OMAP #include "ehci-omap.c" #define PLATFORM_DRIVER ehci_hcd_omap_driver -- cgit v1.2.3 From b898f5fa39f8606d64f1760ac09400e9323fed83 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:24 +0200 Subject: ARM: cns3xxx: use ehci platform driver This patch converts the cns3xxx platform to use the ehci-platform driver instead of the ehci-cns3xxx platform driver. The ehci-platform driver is provided with power_{on,off} callbacks to ensure proper block gating and USB configuration of the EHCI controller. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-cns3xxx/cns3420vb.c | 44 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c index 2c5fb4c7e50..906094cb23f 100644 --- a/arch/arm/mach-cns3xxx/cns3420vb.c +++ b/arch/arm/mach-cns3xxx/cns3420vb.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include #include "core.h" #include "devices.h" @@ -125,13 +127,53 @@ static struct resource cns3xxx_usb_ehci_resources[] = { static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32); +static int csn3xxx_usb_ehci_power_on(struct platform_device *pdev) +{ + /* + * EHCI and OHCI share the same clock and power, + * resetting twice would cause the 1st controller been reset. + * Therefore only do power up at the first up device, and + * power down at the last down device. + * + * Set USB AHB INCR length to 16 + */ + if (atomic_inc_return(&usb_pwr_ref) == 1) { + cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB); + cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); + cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST); + __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)), + MISC_CHIP_CONFIG_REG); + } + + return 0; +} + +static void csn3xxx_usb_ehci_power_off(struct platform_device *pdev) +{ + /* + * EHCI and OHCI share the same clock and power, + * resetting twice would cause the 1st controller been reset. + * Therefore only do power up at the first up device, and + * power down at the last down device. + */ + if (atomic_dec_return(&usb_pwr_ref) == 0) + cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); +} + +static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = { + .port_power_off = 1, + .power_on = csn3xxx_usb_ehci_power_on, + .power_off = csn3xxx_usb_ehci_power_off, +}; + static struct platform_device cns3xxx_usb_ehci_device = { - .name = "cns3xxx-ehci", + .name = "ehci-platform", .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources), .resource = cns3xxx_usb_ehci_resources, .dev = { .dma_mask = &cns3xxx_usb_ehci_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &cns3xxx_usb_ehci_pdata, }, }; -- cgit v1.2.3 From f3a958d30dd1ceac83a3b82b5260475c7697d53a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:25 +0200 Subject: USB: EHCI: remove CNS3xxx EHCI platform driver The users have been converted to use the ehci platform driver instead, thus making the ehci-cns3xxx driver obsolete, so remove it. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 6 +- drivers/usb/host/ehci-cns3xxx.c | 155 ---------------------------------------- drivers/usb/host/ehci-hcd.c | 5 -- 3 files changed, 5 insertions(+), 161 deletions(-) delete mode 100644 drivers/usb/host/ehci-cns3xxx.c diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index e6b64f60608..d21c0070b05 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -215,9 +215,13 @@ config USB_W90X900_EHCI Enables support for the W90X900 USB controller config USB_CNS3XXX_EHCI - bool "Cavium CNS3XXX EHCI Module" + bool "Cavium CNS3XXX EHCI Module (DEPRECATED)" depends on USB_EHCI_HCD && ARCH_CNS3XXX + select USB_EHCI_HCD_PLATFORM ---help--- + This option is deprecated now and the driver was removed, use + USB_EHCI_HCD_PLATFORM instead. + Enable support for the CNS3XXX SOC's on-chip EHCI controller. It is needed for high-speed (480Mbit/sec) USB 2.0 device support. diff --git a/drivers/usb/host/ehci-cns3xxx.c b/drivers/usb/host/ehci-cns3xxx.c deleted file mode 100644 index d91708d2e72..00000000000 --- a/drivers/usb/host/ehci-cns3xxx.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2008 Cavium Networks - * - * This file 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. - */ - -#include -#include -#include -#include - -static int cns3xxx_ehci_init(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; - - /* - * EHCI and OHCI share the same clock and power, - * resetting twice would cause the 1st controller been reset. - * Therefore only do power up at the first up device, and - * power down at the last down device. - * - * Set USB AHB INCR length to 16 - */ - if (atomic_inc_return(&usb_pwr_ref) == 1) { - cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB); - cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); - cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST); - __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)), - MISC_CHIP_CONFIG_REG); - } - - ehci->caps = hcd->regs; - - hcd->has_tt = 0; - - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 0); - - return retval; -} - -static const struct hc_driver cns3xxx_ehci_hc_driver = { - .description = hcd_name, - .product_desc = "CNS3XXX EHCI Host Controller", - .hcd_priv_size = sizeof(struct ehci_hcd), - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - .reset = cns3xxx_ehci_init, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - .get_frame_number = ehci_get_frame, - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, -#ifdef CONFIG_PM - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, -#endif - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static int cns3xxx_ehci_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct usb_hcd *hcd; - const struct hc_driver *driver = &cns3xxx_ehci_hc_driver; - struct resource *res; - int irq; - int retval; - - if (usb_disabled()) - return -ENODEV; - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(dev, "Found HC with no IRQ.\n"); - return -ENODEV; - } - irq = res->start; - - hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); - if (!hcd) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "Found HC with no register addr.\n"); - retval = -ENODEV; - goto err1; - } - - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - hcd->regs = devm_request_and_ioremap(&pdev->dev, res); - if (hcd->regs == NULL) { - dev_dbg(dev, "error mapping memory\n"); - retval = -EFAULT; - goto err1; - } - - retval = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (retval == 0) - return retval; - -err1: - usb_put_hcd(hcd); - - return retval; -} - -static int cns3xxx_ehci_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - - /* - * EHCI and OHCI share the same clock and power, - * resetting twice would cause the 1st controller been reset. - * Therefore only do power up at the first up device, and - * power down at the last down device. - */ - if (atomic_dec_return(&usb_pwr_ref) == 0) - cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); - - usb_put_hcd(hcd); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -MODULE_ALIAS("platform:cns3xxx-ehci"); - -static struct platform_driver cns3xxx_ehci_driver = { - .probe = cns3xxx_ehci_probe, - .remove = cns3xxx_ehci_remove, - .driver = { - .name = "cns3xxx-ehci", - }, -}; diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index add37bc4bc1..28fb5ddaf78 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1259,11 +1259,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_octeon_driver #endif -#ifdef CONFIG_USB_CNS3XXX_EHCI -#include "ehci-cns3xxx.c" -#define PLATFORM_DRIVER cns3xxx_ehci_driver -#endif - #ifdef CONFIG_ARCH_VT8500 #include "ehci-vt8500.c" #define PLATFORM_DRIVER vt8500_ehci_driver -- cgit v1.2.3 From 2b16e39ee0a431d6cf6e6ca33bb08ec7dc82073f Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:26 +0200 Subject: USB: ohci: allow platform driver to specify the number of ports This patch modifies the ohci platform driver to accept the num_ports parameter to be set via platform_data. Setting the number of ports must be done after the call to ohci_hcd_init(). Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-platform.c | 4 ++++ include/linux/usb/ohci_pdriver.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index e24ec9f7916..1caaf657c5e 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -31,6 +31,10 @@ static int ohci_platform_reset(struct usb_hcd *hcd) ohci->flags |= OHCI_QUIRK_FRAME_NO; ohci_hcd_init(ohci); + + if (pdata->num_ports) + ohci->num_ports = pdata->num_ports; + err = ohci_init(ohci); return err; diff --git a/include/linux/usb/ohci_pdriver.h b/include/linux/usb/ohci_pdriver.h index 74e7755168b..012f2b7eb2b 100644 --- a/include/linux/usb/ohci_pdriver.h +++ b/include/linux/usb/ohci_pdriver.h @@ -25,6 +25,7 @@ * @big_endian_desc: BE descriptors * @big_endian_mmio: BE registers * @no_big_frame_no: no big endian frame_no shift + * @num_ports: number of ports * * These are general configuration options for the OHCI controller. All of * these options are activating more or less workarounds for some hardware. @@ -33,6 +34,7 @@ struct usb_ohci_pdata { unsigned big_endian_desc:1; unsigned big_endian_mmio:1; unsigned no_big_frame_no:1; + unsigned int num_ports; /* Turn on all power and clocks */ int (*power_on)(struct platform_device *pdev); -- cgit v1.2.3 From cd1965db054eeace344487b9c8560439961f5f55 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:27 +0200 Subject: USB: ohci: move ohci_pci_{suspend,resume} to ohci-hcd.c As suggested by Alan Stern, move the ohci-pci.c ohci_pci_{suspend,resume} routines to ohci-hcd.c. Due to their move, also rename them to ohci_{suspend,resume} to make it clear they operate on ohci_hcd. Since they are not necessarily called, annotate them with __maybe_unused, and make them enclosed within an #ifdef CONFIG_PM / #endif section. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hcd.c | 43 +++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/ohci-pci.c | 47 ++------------------------------------------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 4c4d652a446..1382689b31d 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1011,6 +1011,49 @@ static int ohci_restart (struct ohci_hcd *ohci) #endif +#ifdef CONFIG_PM + +static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) +{ + struct ohci_hcd *ohci = hcd_to_ohci (hcd); + unsigned long flags; + int rc = 0; + + /* Root hub was already suspended. Disable irq emission and + * mark HW unaccessible, bail out if RH has been resumed. Use + * the spinlock to properly synchronize with possible pending + * RH suspend or resume activity. + */ + spin_lock_irqsave (&ohci->lock, flags); + if (ohci->rh_state != OHCI_RH_SUSPENDED) { + rc = -EINVAL; + goto bail; + } + ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); + (void)ohci_readl(ohci, &ohci->regs->intrdisable); + + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + bail: + spin_unlock_irqrestore (&ohci->lock, flags); + + return rc; +} + + +static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated) +{ + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + + /* Make sure resume from hibernation re-enumerates everything */ + if (hibernated) + ohci_usb_reset(hcd_to_ohci(hcd)); + + ohci_finish_controller_resume(hcd); + return 0; +} + +#endif + /*-------------------------------------------------------------------------*/ MODULE_AUTHOR (DRIVER_AUTHOR); diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 1843bb68ac7..6afa7dc4e4c 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -296,49 +296,6 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd) return ret; } -#ifdef CONFIG_PM - -static int ohci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) -{ - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - unsigned long flags; - int rc = 0; - - /* Root hub was already suspended. Disable irq emission and - * mark HW unaccessible, bail out if RH has been resumed. Use - * the spinlock to properly synchronize with possible pending - * RH suspend or resume activity. - */ - spin_lock_irqsave (&ohci->lock, flags); - if (ohci->rh_state != OHCI_RH_SUSPENDED) { - rc = -EINVAL; - goto bail; - } - ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); - (void)ohci_readl(ohci, &ohci->regs->intrdisable); - - clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - bail: - spin_unlock_irqrestore (&ohci->lock, flags); - - return rc; -} - - -static int ohci_pci_resume(struct usb_hcd *hcd, bool hibernated) -{ - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - - /* Make sure resume from hibernation re-enumerates everything */ - if (hibernated) - ohci_usb_reset(hcd_to_ohci(hcd)); - - ohci_finish_controller_resume(hcd); - return 0; -} - -#endif /* CONFIG_PM */ - /*-------------------------------------------------------------------------*/ @@ -362,8 +319,8 @@ static const struct hc_driver ohci_pci_hc_driver = { .shutdown = ohci_shutdown, #ifdef CONFIG_PM - .pci_suspend = ohci_pci_suspend, - .pci_resume = ohci_pci_resume, + .pci_suspend = ohci_suspend, + .pci_resume = ohci_resume, #endif /* -- cgit v1.2.3 From d4ae47dc5670efecd2214110caf33dfc0ff7191f Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:28 +0200 Subject: USB: ohci: remove check for RH already suspended in ohci_suspend As suggested by Alan Stern, the code checking for the OHCI RH already suspended is no longer required since the bug it fixes has not been seen in ages. Remove that check making ohci_suspend much simpler. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hcd.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 1382689b31d..76663295e1c 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1017,26 +1017,19 @@ static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); unsigned long flags; - int rc = 0; - /* Root hub was already suspended. Disable irq emission and - * mark HW unaccessible, bail out if RH has been resumed. Use + /* Disable irq emission and mark HW unaccessible. Use * the spinlock to properly synchronize with possible pending * RH suspend or resume activity. */ spin_lock_irqsave (&ohci->lock, flags); - if (ohci->rh_state != OHCI_RH_SUSPENDED) { - rc = -EINVAL; - goto bail; - } ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); (void)ohci_readl(ohci, &ohci->regs->intrdisable); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - bail: spin_unlock_irqrestore (&ohci->lock, flags); - return rc; + return 0; } -- cgit v1.2.3 From cfa49b4b88fe14d2b5792f2ea7ba5b88c8cd1d15 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:29 +0200 Subject: USB: ohci: merge ohci_finish_controller_resume with ohci_resume Merge ohci_finish_controller_resume with ohci_resume as suggested by Alan Stern. Since ohci_finish_controller_resume no longer exists, update the various OHCI drivers to call ohci_resume() instead. Some drivers used to set themselves the bit HCD_FLAG_HW_ACCESSIBLE, which is now handled by ohci_resume(). Acked-by: Jingoo Han Acked-by: Nicolas Ferre Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-at91.c | 2 +- drivers/usb/host/ohci-ep93xx.c | 2 +- drivers/usb/host/ohci-exynos.c | 5 +---- drivers/usb/host/ohci-hcd.c | 41 +++++++++++++++++++++++++++++++++++++-- drivers/usb/host/ohci-hub.c | 42 ---------------------------------------- drivers/usb/host/ohci-omap.c | 2 +- drivers/usb/host/ohci-platform.c | 2 +- drivers/usb/host/ohci-pxa27x.c | 2 +- drivers/usb/host/ohci-s3c2410.c | 3 +-- drivers/usb/host/ohci-spear.c | 2 +- drivers/usb/host/ohci-tmio.c | 2 +- 11 files changed, 48 insertions(+), 57 deletions(-) diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 0bf72f943b0..908d84af1dd 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -705,7 +705,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) if (!clocked) at91_start_clock(); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } #else diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index dbfbd1dfd2e..a982f04ed78 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -194,7 +194,7 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev) ep93xx_start_hc(&pdev->dev); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } #endif diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index 20a50081f92..929a49437e2 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -252,10 +252,7 @@ static int exynos_ohci_resume(struct device *dev) if (pdata && pdata->phy_init) pdata->phy_init(pdev, S5P_USB_PHY_HOST); - /* Mark hardware accessible again as we are out of D3 state by now */ - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 76663295e1c..bac66263696 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1035,13 +1035,50 @@ static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup) static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated) { + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + int port; + bool need_reinit = false; + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); /* Make sure resume from hibernation re-enumerates everything */ if (hibernated) - ohci_usb_reset(hcd_to_ohci(hcd)); + ohci_usb_reset(ohci); + + /* See if the controller is already running or has been reset */ + ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); + if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { + need_reinit = true; + } else { + switch (ohci->hc_control & OHCI_CTRL_HCFS) { + case OHCI_USB_OPER: + case OHCI_USB_RESET: + need_reinit = true; + } + } + + /* If needed, reinitialize and suspend the root hub */ + if (need_reinit) { + spin_lock_irq(&ohci->lock); + ohci_rh_resume(ohci); + ohci_rh_suspend(ohci, 0); + spin_unlock_irq(&ohci->lock); + } + + /* Normally just turn on port power and enable interrupts */ + else { + ohci_dbg(ohci, "powerup ports\n"); + for (port = 0; port < ohci->num_ports; port++) + ohci_writel(ohci, RH_PS_PPS, + &ohci->regs->roothub.portstatus[port]); + + ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable); + ohci_readl(ohci, &ohci->regs->intrenable); + msleep(20); + } + + usb_hcd_resume_root_hub(hcd); - ohci_finish_controller_resume(hcd); return 0; } diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 2f3619eefef..db09dae7b55 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -316,48 +316,6 @@ static int ohci_bus_resume (struct usb_hcd *hcd) return rc; } -/* Carry out the final steps of resuming the controller device */ -static void __maybe_unused ohci_finish_controller_resume(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int port; - bool need_reinit = false; - - /* See if the controller is already running or has been reset */ - ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); - if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { - need_reinit = true; - } else { - switch (ohci->hc_control & OHCI_CTRL_HCFS) { - case OHCI_USB_OPER: - case OHCI_USB_RESET: - need_reinit = true; - } - } - - /* If needed, reinitialize and suspend the root hub */ - if (need_reinit) { - spin_lock_irq(&ohci->lock); - ohci_rh_resume(ohci); - ohci_rh_suspend(ohci, 0); - spin_unlock_irq(&ohci->lock); - } - - /* Normally just turn on port power and enable interrupts */ - else { - ohci_dbg(ohci, "powerup ports\n"); - for (port = 0; port < ohci->num_ports; port++) - ohci_writel(ohci, RH_PS_PPS, - &ohci->regs->roothub.portstatus[port]); - - ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable); - ohci_readl(ohci, &ohci->regs->intrenable); - msleep(20); - } - - usb_hcd_resume_root_hub(hcd); -} - /* Carry out polling-, autostop-, and autoresume-related state changes */ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, int any_connected, int rhsc_status) diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 4531d03503c..733c77c3635 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -530,7 +530,7 @@ static int ohci_omap_resume(struct platform_device *dev) ohci->next_statechange = jiffies; omap_ohci_clock_power(1); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 1caaf657c5e..99d17552d80 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -203,7 +203,7 @@ static int ohci_platform_resume(struct device *dev) return err; } - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 2bf11440b01..156d289d3bb 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -591,7 +591,7 @@ static int ohci_hcd_pxa27x_drv_resume(struct device *dev) /* Select Power Management Mode */ pxa27x_ohci_select_pmm(ohci, inf->port_mode); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 0d2309ca471..281d5c658e3 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -524,8 +524,7 @@ static int ohci_hcd_s3c2410_drv_resume(struct device *dev) s3c2410_start_hc(pdev, hcd); - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index fc7305ee3c9..d607be33c03 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -231,7 +231,7 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev) ohci->next_statechange = jiffies; spear_start_ohci(ohci_p); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } #endif diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index 60c2b0722f2..2c9ab8f126d 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c @@ -352,7 +352,7 @@ static int ohci_hcd_tmio_drv_resume(struct platform_device *dev) spin_unlock_irqrestore(&tmio->lock, flags); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } -- cgit v1.2.3 From f2028bdf06f45955f93cbba8d0a5b5e47be0f359 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:30 +0200 Subject: MIPS: PNX8550: use OHCI platform driver Change the PNX8550 platform code to register an ohci-platform driver instead of ohci-pnx8550 since the ohci-platform is suitable for use. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/mips/pnx8550/common/platform.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/arch/mips/pnx8550/common/platform.c b/arch/mips/pnx8550/common/platform.c index 5264cc09a27..0a8faeaa7b7 100644 --- a/arch/mips/pnx8550/common/platform.c +++ b/arch/mips/pnx8550/common/platform.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -96,12 +97,40 @@ static u64 ohci_dmamask = DMA_BIT_MASK(32); static u64 uart_dmamask = DMA_BIT_MASK(32); +static int pnx8550_usb_ohci_power_on(struct platform_device *pdev) +{ + /* + * Set register CLK48CTL to enable and 48MHz + */ + outl(0x00000003, PCI_BASE | 0x0004770c); + + /* + * Set register CLK12CTL to enable and 48MHz + */ + outl(0x00000003, PCI_BASE | 0x00047710); + + udelay(100); + + return 0; +} + +static void pnx8550_usb_ohci_power_off(struct platform_device *pdev) +{ + udelay(10); +} + +static struct usb_ohci_pdata pnx8550_usb_ohci_pdata = { + .power_on = pnx8550_usb_ohci_power_on, + .power_off = pnx8550_usb_ohci_power_off, +}; + static struct platform_device pnx8550_usb_ohci_device = { - .name = "pnx8550-ohci", + .name = "ohci-platform", .id = -1, .dev = { .dma_mask = &ohci_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &pnx8550_usb_ohci_pdata, }, .num_resources = ARRAY_SIZE(pnx8550_usb_ohci_resources), .resource = pnx8550_usb_ohci_resources, -- cgit v1.2.3 From 60da65f966437d1212c99df89deb479b0697620a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:31 +0200 Subject: USB: OHCI: remove PNX8550 OHCI driver The users have been converted to use the platform OHCI driver instead, thus making the ohci-pnx8550 driver obsolete, so remove it. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hcd.c | 5 - drivers/usb/host/ohci-pnx8550.c | 243 ---------------------------------------- 2 files changed, 248 deletions(-) delete mode 100644 drivers/usb/host/ohci-pnx8550.c diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index bac66263696..b8f2ead7e5c 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1135,11 +1135,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ohci_hcd_au1xxx_driver #endif -#ifdef CONFIG_PNX8550 -#include "ohci-pnx8550.c" -#define PLATFORM_DRIVER ohci_hcd_pnx8550_driver -#endif - #ifdef CONFIG_ARCH_AT91 #include "ohci-at91.c" #define PLATFORM_DRIVER ohci_hcd_at91_driver diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c deleted file mode 100644 index 148d27d6a67..00000000000 --- a/drivers/usb/host/ohci-pnx8550.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber - * (C) Copyright 2000-2002 David Brownell - * (C) Copyright 2002 Hewlett-Packard Company - * (C) Copyright 2005 Embedded Alley Solutions, Inc. - * - * Bus Glue for PNX8550 - * - * Written by Christopher Hoover - * Based on fragments of previous driver by Russell King et al. - * - * Modified for LH7A404 from ohci-sa1111.c - * by Durgesh Pattamatta - * - * Modified for PNX8550 from ohci-sa1111.c and sa-omap.c - * by Vitaly Wool - * - * This file is licenced under the GPL. - */ - -#include -#include -#include -#include -#include - -#ifndef CONFIG_PNX8550 -#error "This file is PNX8550 bus glue. CONFIG_PNX8550 must be defined." -#endif - -extern int usb_disabled(void); - -/*-------------------------------------------------------------------------*/ - -static void pnx8550_start_hc(struct platform_device *dev) -{ - /* - * Set register CLK48CTL to enable and 48MHz - */ - outl(0x00000003, PCI_BASE | 0x0004770c); - - /* - * Set register CLK12CTL to enable and 48MHz - */ - outl(0x00000003, PCI_BASE | 0x00047710); - - udelay(100); -} - -static void pnx8550_stop_hc(struct platform_device *dev) -{ - udelay(10); -} - - -/*-------------------------------------------------------------------------*/ - -/* configure so an HC device and id are always provided */ -/* always called with process context; sleeping is OK */ - - -/** - * usb_hcd_pnx8550_probe - initialize pnx8550-based HCDs - * Context: !in_interrupt() - * - * Allocates basic resources for this USB host controller, and - * then invokes the start() method for the HCD associated with it - * through the hotplug entry's driver_data. - * - */ -int usb_hcd_pnx8550_probe (const struct hc_driver *driver, - struct platform_device *dev) -{ - int retval; - struct usb_hcd *hcd; - - if (dev->resource[0].flags != IORESOURCE_MEM || - dev->resource[1].flags != IORESOURCE_IRQ) { - dev_err (&dev->dev,"invalid resource type\n"); - return -ENOMEM; - } - - hcd = usb_create_hcd (driver, &dev->dev, "pnx8550"); - if (!hcd) - return -ENOMEM; - hcd->rsrc_start = dev->resource[0].start; - hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - dev_err(&dev->dev, "request_mem_region [0x%08llx, 0x%08llx] " - "failed\n", hcd->rsrc_start, hcd->rsrc_len); - retval = -EBUSY; - goto err1; - } - - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - dev_err(&dev->dev, "ioremap [[0x%08llx, 0x%08llx] failed\n", - hcd->rsrc_start, hcd->rsrc_len); - retval = -ENOMEM; - goto err2; - } - - pnx8550_start_hc(dev); - - ohci_hcd_init(hcd_to_ohci(hcd)); - - retval = usb_add_hcd(hcd, dev->resource[1].start, 0); - if (retval == 0) - return retval; - - pnx8550_stop_hc(dev); - iounmap(hcd->regs); - err2: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - err1: - usb_put_hcd(hcd); - return retval; -} - - -/* may be called without controller electrically present */ -/* may be called with controller, bus, and devices active */ - -/** - * usb_hcd_pnx8550_remove - shutdown processing for pnx8550-based HCDs - * @dev: USB Host Controller being removed - * Context: !in_interrupt() - * - * Reverses the effect of usb_hcd_pnx8550_probe(), first invoking - * the HCD's stop() method. It is always called from a thread - * context, normally "rmmod", "apmd", or something similar. - * - */ -void usb_hcd_pnx8550_remove (struct usb_hcd *hcd, struct platform_device *dev) -{ - usb_remove_hcd(hcd); - pnx8550_stop_hc(dev); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); -} - -/*-------------------------------------------------------------------------*/ - -static int __devinit -ohci_pnx8550_start (struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci (hcd); - int ret; - - ohci_dbg (ohci, "ohci_pnx8550_start, ohci:%p", ohci); - - if ((ret = ohci_init(ohci)) < 0) - return ret; - - if ((ret = ohci_run (ohci)) < 0) { - dev_err(hcd->self.controller, "can't start %s", - hcd->self.bus_name); - ohci_stop (hcd); - return ret; - } - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static const struct hc_driver ohci_pnx8550_hc_driver = { - .description = hcd_name, - .product_desc = "PNX8550 OHCI", - .hcd_priv_size = sizeof(struct ohci_hcd), - - /* - * generic hardware linkage - */ - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .start = ohci_pnx8550_start, - .stop = ohci_stop, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ohci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif - .start_port_reset = ohci_start_port_reset, -}; - -/*-------------------------------------------------------------------------*/ - -static int ohci_hcd_pnx8550_drv_probe(struct platform_device *pdev) -{ - int ret; - - if (usb_disabled()) - return -ENODEV; - - ret = usb_hcd_pnx8550_probe(&ohci_pnx8550_hc_driver, pdev); - return ret; -} - -static int ohci_hcd_pnx8550_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_hcd_pnx8550_remove(hcd, pdev); - return 0; -} - -MODULE_ALIAS("platform:pnx8550-ohci"); - -static struct platform_driver ohci_hcd_pnx8550_driver = { - .driver = { - .name = "pnx8550-ohci", - .owner = THIS_MODULE, - }, - .probe = ohci_hcd_pnx8550_drv_probe, - .remove = ohci_hcd_pnx8550_drv_remove, -}; - -- cgit v1.2.3 From 6da00dd7b4c2e6678c3eab3573fb94a0c14ec1cf Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:32 +0200 Subject: ARM: cns3xxx: use OHCI platform driver This patch converts the cns3xxx platform to use the ohci-platform driver which is now suitable for use. A previous patch converted the cns3xxx platform to use the ehci-platform driver, and thus introduced the need to have power_{on,off} callbacks. Since both the EHCI and OHCI platform drivers use the same same power_{on,off} callbacks now, rename them to cns3xx_usb_power_{on,off} to show that they are shared. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-cns3xxx/cns3420vb.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c index 906094cb23f..8a00cee8222 100644 --- a/arch/arm/mach-cns3xxx/cns3420vb.c +++ b/arch/arm/mach-cns3xxx/cns3420vb.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -127,7 +128,7 @@ static struct resource cns3xxx_usb_ehci_resources[] = { static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32); -static int csn3xxx_usb_ehci_power_on(struct platform_device *pdev) +static int csn3xxx_usb_power_on(struct platform_device *pdev) { /* * EHCI and OHCI share the same clock and power, @@ -148,7 +149,7 @@ static int csn3xxx_usb_ehci_power_on(struct platform_device *pdev) return 0; } -static void csn3xxx_usb_ehci_power_off(struct platform_device *pdev) +static void csn3xxx_usb_power_off(struct platform_device *pdev) { /* * EHCI and OHCI share the same clock and power, @@ -162,8 +163,8 @@ static void csn3xxx_usb_ehci_power_off(struct platform_device *pdev) static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = { .port_power_off = 1, - .power_on = csn3xxx_usb_ehci_power_on, - .power_off = csn3xxx_usb_ehci_power_off, + .power_on = csn3xxx_usb_power_on, + .power_off = csn3xxx_usb_power_off, }; static struct platform_device cns3xxx_usb_ehci_device = { @@ -191,13 +192,20 @@ static struct resource cns3xxx_usb_ohci_resources[] = { static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32); +static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = { + .num_ports = 1, + .power_on = csn3xxx_usb_power_on, + .power_off = csn3xxx_usb_power_off, +}; + static struct platform_device cns3xxx_usb_ohci_device = { - .name = "cns3xxx-ohci", + .name = "ohci-platform", .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources), .resource = cns3xxx_usb_ohci_resources, .dev = { .dma_mask = &cns3xxx_usb_ohci_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &cns3xxx_usb_ohci_pdata, }, }; -- cgit v1.2.3 From c23920b05be41998dc8e5796eb874df098a97e9f Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:33 +0200 Subject: USB: OHCI: remove CNS3xxx OHCI platform driver All users have been converted to use the OHCI platform driver instead, thus making ohci-cns3xxx, so remove it. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 6 +- drivers/usb/host/ohci-cns3xxx.c | 166 ---------------------------------------- drivers/usb/host/ohci-hcd.c | 5 -- 3 files changed, 5 insertions(+), 172 deletions(-) delete mode 100644 drivers/usb/host/ohci-cns3xxx.c diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index d21c0070b05..e43c9c8c185 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -400,9 +400,13 @@ config USB_OHCI_EXYNOS Enable support for the Samsung Exynos SOC's on-chip OHCI controller. config USB_CNS3XXX_OHCI - bool "Cavium CNS3XXX OHCI Module" + bool "Cavium CNS3XXX OHCI Module (DEPRECATED)" depends on USB_OHCI_HCD && ARCH_CNS3XXX + select USB_OHCI_HCD_PLATFORM ---help--- + This option is deprecated now and the driver was removed, use + USB_OHCI_HCD_PLATFORM instead. + Enable support for the CNS3XXX SOC's on-chip OHCI controller. It is needed for low-speed USB 1.0 device support. diff --git a/drivers/usb/host/ohci-cns3xxx.c b/drivers/usb/host/ohci-cns3xxx.c deleted file mode 100644 index 2c9f233047b..00000000000 --- a/drivers/usb/host/ohci-cns3xxx.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2008 Cavium Networks - * - * This file 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. - */ - -#include -#include -#include -#include - -static int __devinit -cns3xxx_ohci_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int ret; - - /* - * EHCI and OHCI share the same clock and power, - * resetting twice would cause the 1st controller been reset. - * Therefore only do power up at the first up device, and - * power down at the last down device. - * - * Set USB AHB INCR length to 16 - */ - if (atomic_inc_return(&usb_pwr_ref) == 1) { - cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB); - cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); - cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST); - __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)), - MISC_CHIP_CONFIG_REG); - } - - ret = ohci_init(ohci); - if (ret < 0) - return ret; - - ohci->num_ports = 1; - - ret = ohci_run(ohci); - if (ret < 0) { - dev_err(hcd->self.controller, "can't start %s\n", - hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - return 0; -} - -static const struct hc_driver cns3xxx_ohci_hc_driver = { - .description = hcd_name, - .product_desc = "CNS3XXX OHCI Host controller", - .hcd_priv_size = sizeof(struct ohci_hcd), - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - .start = cns3xxx_ohci_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - .get_frame_number = ohci_get_frame, - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif - .start_port_reset = ohci_start_port_reset, -}; - -static int cns3xxx_ohci_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct usb_hcd *hcd; - const struct hc_driver *driver = &cns3xxx_ohci_hc_driver; - struct resource *res; - int irq; - int retval; - - if (usb_disabled()) - return -ENODEV; - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(dev, "Found HC with no IRQ.\n"); - return -ENODEV; - } - irq = res->start; - - hcd = usb_create_hcd(driver, dev, dev_name(dev)); - if (!hcd) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "Found HC with no register addr.\n"); - retval = -ENODEV; - goto err1; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, - driver->description)) { - dev_dbg(dev, "controller already in use\n"); - retval = -EBUSY; - goto err1; - } - - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - dev_dbg(dev, "error mapping memory\n"); - retval = -EFAULT; - goto err2; - } - - ohci_hcd_init(hcd_to_ohci(hcd)); - - retval = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (retval == 0) - return retval; - - iounmap(hcd->regs); -err2: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err1: - usb_put_hcd(hcd); - return retval; -} - -static int cns3xxx_ohci_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - - /* - * EHCI and OHCI share the same clock and power, - * resetting twice would cause the 1st controller been reset. - * Therefore only do power up at the first up device, and - * power down at the last down device. - */ - if (atomic_dec_return(&usb_pwr_ref) == 0) - cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST); - - usb_put_hcd(hcd); - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -MODULE_ALIAS("platform:cns3xxx-ohci"); - -static struct platform_driver ohci_hcd_cns3xxx_driver = { - .probe = cns3xxx_ohci_probe, - .remove = cns3xxx_ohci_remove, - .driver = { - .name = "cns3xxx-ohci", - }, -}; diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index b8f2ead7e5c..d35fc1e788d 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1196,11 +1196,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ohci_hcd_tilegx_driver #endif -#ifdef CONFIG_USB_CNS3XXX_OHCI -#include "ohci-cns3xxx.c" -#define PLATFORM_DRIVER ohci_hcd_cns3xxx_driver -#endif - #ifdef CONFIG_CPU_XLR #include "ohci-xls.c" #define PLATFORM_DRIVER ohci_xls_driver -- cgit v1.2.3 From ee2ef6b89a8f6fa20848d7ef6df4bffa6d9ab146 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:34 +0200 Subject: MIPS: Netlogic: convert to use OHCI platform driver The OHCI platform driver is suitable for use by the Netlogic XLR platform so use this driver instead of the OHCI XLS platform driver. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/mips/netlogic/xlr/platform.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/mips/netlogic/xlr/platform.c b/arch/mips/netlogic/xlr/platform.c index 144c5c60984..507230eeb76 100644 --- a/arch/mips/netlogic/xlr/platform.c +++ b/arch/mips/netlogic/xlr/platform.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -128,12 +129,14 @@ static struct usb_ehci_pdata xls_usb_ehci_pdata = { .caps_offset = 0, }; +static struct usb_ohci_pdata xls_usb_ohci_pdata; + static struct platform_device xls_usb_ehci_device = USB_PLATFORM_DEV("ehci-platform", 0, PIC_USB_IRQ); static struct platform_device xls_usb_ohci_device_0 = - USB_PLATFORM_DEV("ohci-xls-0", 1, PIC_USB_IRQ); + USB_PLATFORM_DEV("ohci-platform", 1, PIC_USB_IRQ); static struct platform_device xls_usb_ohci_device_1 = - USB_PLATFORM_DEV("ohci-xls-1", 2, PIC_USB_IRQ); + USB_PLATFORM_DEV("ohci-platform", 2, PIC_USB_IRQ); static struct platform_device *xls_platform_devices[] = { &xls_usb_ehci_device, @@ -182,10 +185,12 @@ int xls_platform_usb_init(void) memres += 0x400; xls_usb_ohci_device_0.resource[0].start = memres; xls_usb_ohci_device_0.resource[0].end = memres + 0x400 - 1; + xls_usb_ohci_device_0.dev.platform_data = &xls_usb_ohci_pdata; memres += 0x400; xls_usb_ohci_device_1.resource[0].start = memres; xls_usb_ohci_device_1.resource[0].end = memres + 0x400 - 1; + xls_usb_ohci_device_1.dev.platform_data = &xls_usb_ohci_pdata; return platform_add_devices(xls_platform_devices, ARRAY_SIZE(xls_platform_devices)); -- cgit v1.2.3 From c2e91e046df67efa401f77ebe13478e124bc50f7 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:35 +0200 Subject: USB: OHCI: remove Netlogic XLS OHCI platform driver All users have been converted to use the OHCI platform driver instead, thus making ohci-xls obsolete, remove it. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hcd.c | 5 -- drivers/usb/host/ohci-xls.c | 152 -------------------------------------------- 2 files changed, 157 deletions(-) delete mode 100644 drivers/usb/host/ohci-xls.c diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index d35fc1e788d..61d3ddd6b30 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1196,11 +1196,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ohci_hcd_tilegx_driver #endif -#ifdef CONFIG_CPU_XLR -#include "ohci-xls.c" -#define PLATFORM_DRIVER ohci_xls_driver -#endif - #ifdef CONFIG_USB_OHCI_HCD_PLATFORM #include "ohci-platform.c" #define PLATFORM_DRIVER ohci_platform_driver diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c deleted file mode 100644 index 84201cd1a47..00000000000 --- a/drivers/usb/host/ohci-xls.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * OHCI HCD for Netlogic XLS processors. - * - * (C) Copyright 2011 Netlogic Microsystems Inc. - * - * Based on ohci-au1xxx.c, and other Linux OHCI drivers. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - */ - -#include -#include - -static int ohci_xls_probe_internal(const struct hc_driver *driver, - struct platform_device *dev) -{ - struct resource *res; - struct usb_hcd *hcd; - int retval, irq; - - /* Get our IRQ from an earlier registered Platform Resource */ - irq = platform_get_irq(dev, 0); - if (irq < 0) { - dev_err(&dev->dev, "Found HC with no IRQ\n"); - return -ENODEV; - } - - /* Get our Memory Handle */ - res = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&dev->dev, "MMIO Handle incorrect!\n"); - return -ENODEV; - } - - hcd = usb_create_hcd(driver, &dev->dev, "XLS"); - if (!hcd) { - retval = -ENOMEM; - goto err1; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, - driver->description)) { - dev_dbg(&dev->dev, "Controller already in use\n"); - retval = -EBUSY; - goto err2; - } - - hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); - if (hcd->regs == NULL) { - dev_dbg(&dev->dev, "error mapping memory\n"); - retval = -EFAULT; - goto err3; - } - - retval = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (retval != 0) - goto err4; - return retval; - -err4: - iounmap(hcd->regs); -err3: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err2: - usb_put_hcd(hcd); -err1: - dev_err(&dev->dev, "init fail, %d\n", retval); - return retval; -} - -static int ohci_xls_reset(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - - ohci_hcd_init(ohci); - return ohci_init(ohci); -} - -static int __devinit ohci_xls_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci; - int ret; - - ohci = hcd_to_ohci(hcd); - ret = ohci_run(ohci); - if (ret < 0) { - dev_err(hcd->self.controller, "can't start %s\n", - hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - return 0; -} - -static struct hc_driver ohci_xls_hc_driver = { - .description = hcd_name, - .product_desc = "XLS OHCI Host Controller", - .hcd_priv_size = sizeof(struct ohci_hcd), - .irq = ohci_irq, - .flags = HCD_MEMORY | HCD_USB11, - .reset = ohci_xls_reset, - .start = ohci_xls_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - .get_frame_number = ohci_get_frame, - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif - .start_port_reset = ohci_start_port_reset, -}; - -static int ohci_xls_probe(struct platform_device *dev) -{ - int ret; - - pr_debug("In ohci_xls_probe"); - if (usb_disabled()) - return -ENODEV; - ret = ohci_xls_probe_internal(&ohci_xls_hc_driver, dev); - return ret; -} - -static int ohci_xls_remove(struct platform_device *dev) -{ - struct usb_hcd *hcd = platform_get_drvdata(dev); - - usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); - return 0; -} - -static struct platform_driver ohci_xls_driver = { - .probe = ohci_xls_probe, - .remove = ohci_xls_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = "ohci-xls-0", - .owner = THIS_MODULE, - }, -}; -- cgit v1.2.3 From 7518f0763ecd6232ccad379e56e45b799d2d1a4c Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:36 +0200 Subject: sh: convert boards to use the OHCI platform driver This patch makes all SuperH boards using the ohci-sh platform driver to use the ohci-platform driver instead, which is suitable for use by these boards. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/sh/kernel/cpu/sh3/setup-sh7720.c | 6 +++++- arch/sh/kernel/cpu/sh4a/setup-sh7757.c | 6 +++++- arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 6 +++++- arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 6 +++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 0c2f1b2c2e1..42d991f632b 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -103,12 +104,15 @@ static struct resource usb_ohci_resources[] = { static u64 usb_ohci_dma_mask = 0xffffffffUL; +static struct usb_ohci_pdata usb_ohci_pdata; + static struct platform_device usb_ohci_device = { - .name = "sh_ohci", + .name = "ohci-platform", .id = -1, .dev = { .dma_mask = &usb_ohci_dma_mask, .coherent_dma_mask = 0xffffffff, + .platform_data = &usb_ohci_pdata, }, .num_resources = ARRAY_SIZE(usb_ohci_resources), .resource = usb_ohci_resources, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index 4a2f357f4df..9079a0f9ea9 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -750,12 +751,15 @@ static struct resource usb_ohci_resources[] = { }, }; +static struct usb_ohci_pdata usb_ohci_pdata; + static struct platform_device usb_ohci_device = { - .name = "sh_ohci", + .name = "ohci-platform", .id = -1, .dev = { .dma_mask = &usb_ohci_device.dev.coherent_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &usb_ohci_pdata, }, .num_resources = ARRAY_SIZE(usb_ohci_resources), .resource = usb_ohci_resources, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index bd0a8fbe610..1686acaaf45 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -16,6 +16,7 @@ #include #include #include +#include static struct plat_sci_port scif0_platform_data = { .mapbase = 0xffe00000, @@ -106,12 +107,15 @@ static struct resource usb_ohci_resources[] = { static u64 usb_ohci_dma_mask = 0xffffffffUL; +static struct usb_ohci_pdata usb_ohci_pdata; + static struct platform_device usb_ohci_device = { - .name = "sh_ohci", + .name = "ohci-platform", .id = -1, .dev = { .dma_mask = &usb_ohci_dma_mask, .coherent_dma_mask = 0xffffffff, + .platform_data = &usb_ohci_pdata, }, .num_resources = ARRAY_SIZE(usb_ohci_resources), .resource = usb_ohci_resources, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 2e6952f8784..ab52d4d4484 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -583,12 +584,15 @@ static struct resource usb_ohci_resources[] = { }, }; +static struct usb_ohci_pdata usb_ohci_pdata; + static struct platform_device usb_ohci_device = { - .name = "sh_ohci", + .name = "ohci-platform", .id = -1, .dev = { .dma_mask = &usb_ohci_device.dev.coherent_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &usb_ohci_pdata, }, .num_resources = ARRAY_SIZE(usb_ohci_resources), .resource = usb_ohci_resources, -- cgit v1.2.3 From 231a72e03af68f791e3f34dbc22117ebb18bdbb0 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:37 +0200 Subject: USB: OHCI: remove OHCI SH platform driver All users have been converted to use the OHCI platform driver instead, thus making ohci-sh obsolete, so remove it. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 6 +- drivers/usb/host/ohci-hcd.c | 5 -- drivers/usb/host/ohci-sh.c | 141 -------------------------------------------- 3 files changed, 5 insertions(+), 147 deletions(-) delete mode 100644 drivers/usb/host/ohci-sh.c diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index e43c9c8c185..8cc06f054c6 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -387,9 +387,13 @@ config USB_OHCI_HCD_SSB If unsure, say N. config USB_OHCI_SH - bool "OHCI support for SuperH USB controller" + bool "OHCI support for SuperH USB controller (DEPRECATED)" depends on USB_OHCI_HCD && SUPERH + select USB_OHCI_HCD_PLATFORM ---help--- + This option is deprecated now and the driver was removed, use + USB_OHCI_HCD_PLATFORM instead. + Enables support for the on-chip OHCI controller on the SuperH. If you use the PCI OHCI controller, this option is not necessary. diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 61d3ddd6b30..ecff612ad3b 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1150,11 +1150,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ohci_hcd_da8xx_driver #endif -#ifdef CONFIG_USB_OHCI_SH -#include "ohci-sh.c" -#define PLATFORM_DRIVER ohci_hcd_sh_driver -#endif - #ifdef CONFIG_USB_OHCI_HCD_PPC_OF #include "ohci-ppc-of.c" diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c deleted file mode 100644 index 76a20c27836..00000000000 --- a/drivers/usb/host/ohci-sh.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * OHCI HCD (Host Controller Driver) for USB. - * - * Copyright (C) 2008 Renesas Solutions Corp. - * - * Author : Yoshihiro Shimoda - * - * 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; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include - -static int ohci_sh_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - - ohci_hcd_init(ohci); - ohci_init(ohci); - ohci_run(ohci); - return 0; -} - -static const struct hc_driver ohci_sh_hc_driver = { - .description = hcd_name, - .product_desc = "SuperH OHCI", - .hcd_priv_size = sizeof(struct ohci_hcd), - - /* - * generic hardware linkage - */ - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .start = ohci_sh_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ohci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif - .start_port_reset = ohci_start_port_reset, -}; - -/*-------------------------------------------------------------------------*/ - -static int ohci_hcd_sh_probe(struct platform_device *pdev) -{ - struct resource *res = NULL; - struct usb_hcd *hcd = NULL; - int irq = -1; - int ret; - - if (usb_disabled()) - return -ENODEV; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "platform_get_resource error.\n"); - return -ENODEV; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "platform_get_irq error.\n"); - return -ENODEV; - } - - /* initialize hcd */ - hcd = usb_create_hcd(&ohci_sh_hc_driver, &pdev->dev, (char *)hcd_name); - if (!hcd) { - dev_err(&pdev->dev, "Failed to create hcd\n"); - return -ENOMEM; - } - - hcd->regs = (void __iomem *)res->start; - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (ret != 0) { - dev_err(&pdev->dev, "Failed to add hcd\n"); - usb_put_hcd(hcd); - return ret; - } - - return ret; -} - -static int ohci_hcd_sh_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - usb_put_hcd(hcd); - - return 0; -} - -static struct platform_driver ohci_hcd_sh_driver = { - .probe = ohci_hcd_sh_probe, - .remove = ohci_hcd_sh_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = "sh_ohci", - .owner = THIS_MODULE, - }, -}; - -MODULE_ALIAS("platform:sh_ohci"); -- cgit v1.2.3 From e223a4cca70fb6d3954abab7e96a5f54d64d79d4 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:38 +0200 Subject: MIPS: Alchemy: use the OHCI platform driver Convert the Alchemy platform to register the ohci-platform driver, now that the ohci-platform driver properly handles the specific ohci-au1xxx resume from suspend case. This also greatly simplifies the power_{on,off} callbacks and make them work on platform device id instead of checking the OHCI controller base address like what was done in ohci-au1xxx.c. Impacted defconfigs are also updated accordingly to select the OHCI platform driver. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/mips/alchemy/common/platform.c | 35 +++++++++++++++++++++++++++++++++-- arch/mips/configs/db1000_defconfig | 1 + arch/mips/configs/gpr_defconfig | 1 + arch/mips/configs/mtx1_defconfig | 1 + 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index b9a5f6dd30d..7af941d8e71 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -142,6 +143,34 @@ static struct usb_ehci_pdata alchemy_ehci_pdata = { .power_suspend = alchemy_ehci_power_off, }; +/* Power on callback for the ohci platform driver */ +static int alchemy_ohci_power_on(struct platform_device *pdev) +{ + int unit; + + unit = (pdev->id == 1) ? + ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; + + return alchemy_usb_control(unit, 1); +} + +/* Power off/suspend callback for the ohci platform driver */ +static void alchemy_ohci_power_off(struct platform_device *pdev) +{ + int unit; + + unit = (pdev->id == 1) ? + ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; + + alchemy_usb_control(unit, 0); +} + +static struct usb_ohci_pdata alchemy_ohci_pdata = { + .power_on = alchemy_ohci_power_on, + .power_off = alchemy_ohci_power_off, + .power_suspend = alchemy_ohci_power_off, +}; + static unsigned long alchemy_ohci_data[][2] __initdata = { [ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT }, [ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT }, @@ -189,9 +218,10 @@ static void __init alchemy_setup_usb(int ctype) res[1].start = alchemy_ohci_data[ctype][1]; res[1].end = res[1].start; res[1].flags = IORESOURCE_IRQ; - pdev->name = "au1xxx-ohci"; + pdev->name = "ohci-platform"; pdev->id = 0; pdev->dev.dma_mask = &alchemy_ohci_dmamask; + pdev->dev.platform_data = &alchemy_ohci_pdata; if (platform_device_register(pdev)) printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n"); @@ -228,9 +258,10 @@ static void __init alchemy_setup_usb(int ctype) res[1].start = AU1300_USB_INT; res[1].end = res[1].start; res[1].flags = IORESOURCE_IRQ; - pdev->name = "au1xxx-ohci"; + pdev->name = "ohci-platform"; pdev->id = 1; pdev->dev.dma_mask = &alchemy_ohci_dmamask; + pdev->dev.platform_data = &alchemy_ohci_pdata; if (platform_device_register(pdev)) printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n"); diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index 17a36c12517..face9d26e6d 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -233,6 +233,7 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_UHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_NEW_LEDS=y diff --git a/arch/mips/configs/gpr_defconfig b/arch/mips/configs/gpr_defconfig index 48a40aefaf5..fb64589015f 100644 --- a/arch/mips/configs/gpr_defconfig +++ b/arch/mips/configs/gpr_defconfig @@ -291,6 +291,7 @@ CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_STORAGE=m CONFIG_USB_LIBUSUAL=y CONFIG_USB_SERIAL=y diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index 46c61edcdf7..459018acb61 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -581,6 +581,7 @@ CONFIG_USB_MON=m CONFIG_USB_EHCI_HCD=m CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_OHCI_HCD=m +CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_UHCI_HCD=m CONFIG_USB_U132_HCD=m CONFIG_USB_SL811_HCD=m -- cgit v1.2.3 From bb5da43e4525d3338f51edb980e3067b111b78aa Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:39 +0200 Subject: USB: OHCI: remove Alchemy OHCI platform driver. All users have been converted to use the OHCI platform driver instead, thus making ohci-au1xxx obsolete, remove it. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-au1xxx.c | 234 ----------------------------------------- drivers/usb/host/ohci-hcd.c | 5 - 2 files changed, 239 deletions(-) delete mode 100644 drivers/usb/host/ohci-au1xxx.c diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c deleted file mode 100644 index c611699b4aa..00000000000 --- a/drivers/usb/host/ohci-au1xxx.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber - * (C) Copyright 2000-2002 David Brownell - * (C) Copyright 2002 Hewlett-Packard Company - * - * Bus Glue for AMD Alchemy Au1xxx - * - * Written by Christopher Hoover - * Based on fragments of previous driver by Russell King et al. - * - * Modified for LH7A404 from ohci-sa1111.c - * by Durgesh Pattamatta - * Modified for AMD Alchemy Au1xxx - * by Matt Porter - * - * This file is licenced under the GPL. - */ - -#include -#include - -#include - - -extern int usb_disabled(void); - -static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd) -{ - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - int ret; - - ohci_dbg(ohci, "ohci_au1xxx_start, ohci:%p", ohci); - - if ((ret = ohci_init(ohci)) < 0) - return ret; - - if ((ret = ohci_run(ohci)) < 0) { - dev_err(hcd->self.controller, "can't start %s", - hcd->self.bus_name); - ohci_stop(hcd); - return ret; - } - - return 0; -} - -static const struct hc_driver ohci_au1xxx_hc_driver = { - .description = hcd_name, - .product_desc = "Au1xxx OHCI", - .hcd_priv_size = sizeof(struct ohci_hcd), - - /* - * generic hardware linkage - */ - .irq = ohci_irq, - .flags = HCD_USB11 | HCD_MEMORY, - - /* - * basic lifecycle operations - */ - .start = ohci_au1xxx_start, - .stop = ohci_stop, - .shutdown = ohci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ohci_urb_enqueue, - .urb_dequeue = ohci_urb_dequeue, - .endpoint_disable = ohci_endpoint_disable, - - /* - * scheduling support - */ - .get_frame_number = ohci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ohci_hub_status_data, - .hub_control = ohci_hub_control, -#ifdef CONFIG_PM - .bus_suspend = ohci_bus_suspend, - .bus_resume = ohci_bus_resume, -#endif - .start_port_reset = ohci_start_port_reset, -}; - -static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) -{ - int ret, unit; - struct usb_hcd *hcd; - - if (usb_disabled()) - return -ENODEV; - - if (pdev->resource[1].flags != IORESOURCE_IRQ) { - pr_debug("resource[1] is not IORESOURCE_IRQ\n"); - return -ENOMEM; - } - - hcd = usb_create_hcd(&ohci_au1xxx_hc_driver, &pdev->dev, "au1xxx"); - if (!hcd) - return -ENOMEM; - - hcd->rsrc_start = pdev->resource[0].start; - hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; - - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - pr_debug("request_mem_region failed\n"); - ret = -EBUSY; - goto err1; - } - - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - pr_debug("ioremap failed\n"); - ret = -ENOMEM; - goto err2; - } - - unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ? - ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; - if (alchemy_usb_control(unit, 1)) { - printk(KERN_INFO "%s: controller init failed!\n", pdev->name); - ret = -ENODEV; - goto err3; - } - - ohci_hcd_init(hcd_to_ohci(hcd)); - - ret = usb_add_hcd(hcd, pdev->resource[1].start, - IRQF_SHARED); - if (ret == 0) { - platform_set_drvdata(pdev, hcd); - return ret; - } - - alchemy_usb_control(unit, 0); -err3: - iounmap(hcd->regs); -err2: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err1: - usb_put_hcd(hcd); - return ret; -} - -static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - int unit; - - unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ? - ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; - usb_remove_hcd(hcd); - alchemy_usb_control(unit, 0); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - usb_put_hcd(hcd); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -#ifdef CONFIG_PM -static int ohci_hcd_au1xxx_drv_suspend(struct device *dev) -{ - struct usb_hcd *hcd = dev_get_drvdata(dev); - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - unsigned long flags; - int rc; - - rc = 0; - - /* Root hub was already suspended. Disable irq emission and - * mark HW unaccessible, bail out if RH has been resumed. Use - * the spinlock to properly synchronize with possible pending - * RH suspend or resume activity. - */ - spin_lock_irqsave(&ohci->lock, flags); - if (ohci->rh_state != OHCI_RH_SUSPENDED) { - rc = -EINVAL; - goto bail; - } - ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); - (void)ohci_readl(ohci, &ohci->regs->intrdisable); - - clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - - alchemy_usb_control(ALCHEMY_USB_OHCI0, 0); -bail: - spin_unlock_irqrestore(&ohci->lock, flags); - - return rc; -} - -static int ohci_hcd_au1xxx_drv_resume(struct device *dev) -{ - struct usb_hcd *hcd = dev_get_drvdata(dev); - - alchemy_usb_control(ALCHEMY_USB_OHCI0, 1); - - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - ohci_finish_controller_resume(hcd); - - return 0; -} - -static const struct dev_pm_ops au1xxx_ohci_pmops = { - .suspend = ohci_hcd_au1xxx_drv_suspend, - .resume = ohci_hcd_au1xxx_drv_resume, -}; - -#define AU1XXX_OHCI_PMOPS &au1xxx_ohci_pmops - -#else -#define AU1XXX_OHCI_PMOPS NULL -#endif - -static struct platform_driver ohci_hcd_au1xxx_driver = { - .probe = ohci_hcd_au1xxx_drv_probe, - .remove = ohci_hcd_au1xxx_drv_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = "au1xxx-ohci", - .owner = THIS_MODULE, - .pm = AU1XXX_OHCI_PMOPS, - }, -}; - -MODULE_ALIAS("platform:au1xxx-ohci"); diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index ecff612ad3b..180a2b01db5 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1130,11 +1130,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ohci_hcd_ep93xx_driver #endif -#ifdef CONFIG_MIPS_ALCHEMY -#include "ohci-au1xxx.c" -#define PLATFORM_DRIVER ohci_hcd_au1xxx_driver -#endif - #ifdef CONFIG_ARCH_AT91 #include "ohci-at91.c" #define PLATFORM_DRIVER ohci_hcd_at91_driver -- cgit v1.2.3 From 216d0fded417d26a19049038788813af126b9d66 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:40 +0200 Subject: USB: move common alchemy USB routines to arch/mips/alchemy/common.c A previous patch converted the Alchemy platform to use the OHCI and EHCI platform drivers. As a result, all the common logic to handle USB present in drivers/usb/host/alchemy-common.c has no reason to remain here, so we move it to arch/mips/alchemy/common/usb.c which is a more appropriate place. This change was suggested by Manuel Lauss. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/mips/alchemy/common/Makefile | 2 +- arch/mips/alchemy/common/usb.c | 614 ++++++++++++++++++++++++++++++++++++++ drivers/usb/host/Makefile | 1 - drivers/usb/host/alchemy-common.c | 614 -------------------------------------- 4 files changed, 615 insertions(+), 616 deletions(-) create mode 100644 arch/mips/alchemy/common/usb.c delete mode 100644 drivers/usb/host/alchemy-common.c diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile index 407ebc00e66..cb83d8d21ae 100644 --- a/arch/mips/alchemy/common/Makefile +++ b/arch/mips/alchemy/common/Makefile @@ -6,7 +6,7 @@ # obj-y += prom.o time.o clocks.o platform.o power.o setup.o \ - sleeper.o dma.o dbdma.o vss.o irq.o + sleeper.o dma.o dbdma.o vss.o irq.o usb.o # optional gpiolib support ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) diff --git a/arch/mips/alchemy/common/usb.c b/arch/mips/alchemy/common/usb.c new file mode 100644 index 00000000000..936af8359fb --- /dev/null +++ b/arch/mips/alchemy/common/usb.c @@ -0,0 +1,614 @@ +/* + * USB block power/access management abstraction. + * + * Au1000+: The OHCI block control register is at the far end of the OHCI memory + * area. Au1550 has OHCI on different base address. No need to handle + * UDC here. + * Au1200: one register to control access and clocks to O/EHCI, UDC and OTG + * as well as the PHY for EHCI and UDC. + * + */ + +#include +#include +#include +#include +#include +#include + +/* control register offsets */ +#define AU1000_OHCICFG 0x7fffc +#define AU1550_OHCICFG 0x07ffc +#define AU1200_USBCFG 0x04 + +/* Au1000 USB block config bits */ +#define USBHEN_RD (1 << 4) /* OHCI reset-done indicator */ +#define USBHEN_CE (1 << 3) /* OHCI block clock enable */ +#define USBHEN_E (1 << 2) /* OHCI block enable */ +#define USBHEN_C (1 << 1) /* OHCI block coherency bit */ +#define USBHEN_BE (1 << 0) /* OHCI Big-Endian */ + +/* Au1200 USB config bits */ +#define USBCFG_PFEN (1 << 31) /* prefetch enable (undoc) */ +#define USBCFG_RDCOMB (1 << 30) /* read combining (undoc) */ +#define USBCFG_UNKNOWN (5 << 20) /* unknown, leave this way */ +#define USBCFG_SSD (1 << 23) /* serial short detect en */ +#define USBCFG_PPE (1 << 19) /* HS PHY PLL */ +#define USBCFG_UCE (1 << 18) /* UDC clock enable */ +#define USBCFG_ECE (1 << 17) /* EHCI clock enable */ +#define USBCFG_OCE (1 << 16) /* OHCI clock enable */ +#define USBCFG_FLA(x) (((x) & 0x3f) << 8) +#define USBCFG_UCAM (1 << 7) /* coherent access (undoc) */ +#define USBCFG_GME (1 << 6) /* OTG mem access */ +#define USBCFG_DBE (1 << 5) /* UDC busmaster enable */ +#define USBCFG_DME (1 << 4) /* UDC mem enable */ +#define USBCFG_EBE (1 << 3) /* EHCI busmaster enable */ +#define USBCFG_EME (1 << 2) /* EHCI mem enable */ +#define USBCFG_OBE (1 << 1) /* OHCI busmaster enable */ +#define USBCFG_OME (1 << 0) /* OHCI mem enable */ +#define USBCFG_INIT_AU1200 (USBCFG_PFEN | USBCFG_RDCOMB | USBCFG_UNKNOWN |\ + USBCFG_SSD | USBCFG_FLA(0x20) | USBCFG_UCAM | \ + USBCFG_GME | USBCFG_DBE | USBCFG_DME | \ + USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \ + USBCFG_OME) + +/* Au1300 USB config registers */ +#define USB_DWC_CTRL1 0x00 +#define USB_DWC_CTRL2 0x04 +#define USB_VBUS_TIMER 0x10 +#define USB_SBUS_CTRL 0x14 +#define USB_MSR_ERR 0x18 +#define USB_DWC_CTRL3 0x1C +#define USB_DWC_CTRL4 0x20 +#define USB_OTG_STATUS 0x28 +#define USB_DWC_CTRL5 0x2C +#define USB_DWC_CTRL6 0x30 +#define USB_DWC_CTRL7 0x34 +#define USB_PHY_STATUS 0xC0 +#define USB_INT_STATUS 0xC4 +#define USB_INT_ENABLE 0xC8 + +#define USB_DWC_CTRL1_OTGD 0x04 /* set to DISable OTG */ +#define USB_DWC_CTRL1_HSTRS 0x02 /* set to ENable EHCI */ +#define USB_DWC_CTRL1_DCRS 0x01 /* set to ENable UDC */ + +#define USB_DWC_CTRL2_PHY1RS 0x04 /* set to enable PHY1 */ +#define USB_DWC_CTRL2_PHY0RS 0x02 /* set to enable PHY0 */ +#define USB_DWC_CTRL2_PHYRS 0x01 /* set to enable PHY */ + +#define USB_DWC_CTRL3_OHCI1_CKEN (1 << 19) +#define USB_DWC_CTRL3_OHCI0_CKEN (1 << 18) +#define USB_DWC_CTRL3_EHCI0_CKEN (1 << 17) +#define USB_DWC_CTRL3_OTG0_CKEN (1 << 16) + +#define USB_SBUS_CTRL_SBCA 0x04 /* coherent access */ + +#define USB_INTEN_FORCE 0x20 +#define USB_INTEN_PHY 0x10 +#define USB_INTEN_UDC 0x08 +#define USB_INTEN_EHCI 0x04 +#define USB_INTEN_OHCI1 0x02 +#define USB_INTEN_OHCI0 0x01 + +static DEFINE_SPINLOCK(alchemy_usb_lock); + +static inline void __au1300_usb_phyctl(void __iomem *base, int enable) +{ + unsigned long r, s; + + r = __raw_readl(base + USB_DWC_CTRL2); + s = __raw_readl(base + USB_DWC_CTRL3); + + s &= USB_DWC_CTRL3_OHCI1_CKEN | USB_DWC_CTRL3_OHCI0_CKEN | + USB_DWC_CTRL3_EHCI0_CKEN | USB_DWC_CTRL3_OTG0_CKEN; + + if (enable) { + /* simply enable all PHYs */ + r |= USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS | + USB_DWC_CTRL2_PHYRS; + __raw_writel(r, base + USB_DWC_CTRL2); + wmb(); + } else if (!s) { + /* no USB block active, do disable all PHYs */ + r &= ~(USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS | + USB_DWC_CTRL2_PHYRS); + __raw_writel(r, base + USB_DWC_CTRL2); + wmb(); + } +} + +static inline void __au1300_ohci_control(void __iomem *base, int enable, int id) +{ + unsigned long r; + + if (enable) { + __raw_writel(1, base + USB_DWC_CTRL7); /* start OHCI clock */ + wmb(); + + r = __raw_readl(base + USB_DWC_CTRL3); /* enable OHCI block */ + r |= (id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN + : USB_DWC_CTRL3_OHCI1_CKEN; + __raw_writel(r, base + USB_DWC_CTRL3); + wmb(); + + __au1300_usb_phyctl(base, enable); /* power up the PHYs */ + + r = __raw_readl(base + USB_INT_ENABLE); + r |= (id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1; + __raw_writel(r, base + USB_INT_ENABLE); + wmb(); + + /* reset the OHCI start clock bit */ + __raw_writel(0, base + USB_DWC_CTRL7); + wmb(); + } else { + r = __raw_readl(base + USB_INT_ENABLE); + r &= ~((id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1); + __raw_writel(r, base + USB_INT_ENABLE); + wmb(); + + r = __raw_readl(base + USB_DWC_CTRL3); + r &= ~((id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN + : USB_DWC_CTRL3_OHCI1_CKEN); + __raw_writel(r, base + USB_DWC_CTRL3); + wmb(); + + __au1300_usb_phyctl(base, enable); + } +} + +static inline void __au1300_ehci_control(void __iomem *base, int enable) +{ + unsigned long r; + + if (enable) { + r = __raw_readl(base + USB_DWC_CTRL3); + r |= USB_DWC_CTRL3_EHCI0_CKEN; + __raw_writel(r, base + USB_DWC_CTRL3); + wmb(); + + r = __raw_readl(base + USB_DWC_CTRL1); + r |= USB_DWC_CTRL1_HSTRS; + __raw_writel(r, base + USB_DWC_CTRL1); + wmb(); + + __au1300_usb_phyctl(base, enable); + + r = __raw_readl(base + USB_INT_ENABLE); + r |= USB_INTEN_EHCI; + __raw_writel(r, base + USB_INT_ENABLE); + wmb(); + } else { + r = __raw_readl(base + USB_INT_ENABLE); + r &= ~USB_INTEN_EHCI; + __raw_writel(r, base + USB_INT_ENABLE); + wmb(); + + r = __raw_readl(base + USB_DWC_CTRL1); + r &= ~USB_DWC_CTRL1_HSTRS; + __raw_writel(r, base + USB_DWC_CTRL1); + wmb(); + + r = __raw_readl(base + USB_DWC_CTRL3); + r &= ~USB_DWC_CTRL3_EHCI0_CKEN; + __raw_writel(r, base + USB_DWC_CTRL3); + wmb(); + + __au1300_usb_phyctl(base, enable); + } +} + +static inline void __au1300_udc_control(void __iomem *base, int enable) +{ + unsigned long r; + + if (enable) { + r = __raw_readl(base + USB_DWC_CTRL1); + r |= USB_DWC_CTRL1_DCRS; + __raw_writel(r, base + USB_DWC_CTRL1); + wmb(); + + __au1300_usb_phyctl(base, enable); + + r = __raw_readl(base + USB_INT_ENABLE); + r |= USB_INTEN_UDC; + __raw_writel(r, base + USB_INT_ENABLE); + wmb(); + } else { + r = __raw_readl(base + USB_INT_ENABLE); + r &= ~USB_INTEN_UDC; + __raw_writel(r, base + USB_INT_ENABLE); + wmb(); + + r = __raw_readl(base + USB_DWC_CTRL1); + r &= ~USB_DWC_CTRL1_DCRS; + __raw_writel(r, base + USB_DWC_CTRL1); + wmb(); + + __au1300_usb_phyctl(base, enable); + } +} + +static inline void __au1300_otg_control(void __iomem *base, int enable) +{ + unsigned long r; + if (enable) { + r = __raw_readl(base + USB_DWC_CTRL3); + r |= USB_DWC_CTRL3_OTG0_CKEN; + __raw_writel(r, base + USB_DWC_CTRL3); + wmb(); + + r = __raw_readl(base + USB_DWC_CTRL1); + r &= ~USB_DWC_CTRL1_OTGD; + __raw_writel(r, base + USB_DWC_CTRL1); + wmb(); + + __au1300_usb_phyctl(base, enable); + } else { + r = __raw_readl(base + USB_DWC_CTRL1); + r |= USB_DWC_CTRL1_OTGD; + __raw_writel(r, base + USB_DWC_CTRL1); + wmb(); + + r = __raw_readl(base + USB_DWC_CTRL3); + r &= ~USB_DWC_CTRL3_OTG0_CKEN; + __raw_writel(r, base + USB_DWC_CTRL3); + wmb(); + + __au1300_usb_phyctl(base, enable); + } +} + +static inline int au1300_usb_control(int block, int enable) +{ + void __iomem *base = + (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); + int ret = 0; + + switch (block) { + case ALCHEMY_USB_OHCI0: + __au1300_ohci_control(base, enable, 0); + break; + case ALCHEMY_USB_OHCI1: + __au1300_ohci_control(base, enable, 1); + break; + case ALCHEMY_USB_EHCI0: + __au1300_ehci_control(base, enable); + break; + case ALCHEMY_USB_UDC0: + __au1300_udc_control(base, enable); + break; + case ALCHEMY_USB_OTG0: + __au1300_otg_control(base, enable); + break; + default: + ret = -ENODEV; + } + return ret; +} + +static inline void au1300_usb_init(void) +{ + void __iomem *base = + (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); + + /* set some sane defaults. Note: we don't fiddle with DWC_CTRL4 + * here at all: Port 2 routing (EHCI or UDC) must be set either + * by boot firmware or platform init code; I can't autodetect + * a sane setting. + */ + __raw_writel(0, base + USB_INT_ENABLE); /* disable all USB irqs */ + wmb(); + __raw_writel(0, base + USB_DWC_CTRL3); /* disable all clocks */ + wmb(); + __raw_writel(~0, base + USB_MSR_ERR); /* clear all errors */ + wmb(); + __raw_writel(~0, base + USB_INT_STATUS); /* clear int status */ + wmb(); + /* set coherent access bit */ + __raw_writel(USB_SBUS_CTRL_SBCA, base + USB_SBUS_CTRL); + wmb(); +} + +static inline void __au1200_ohci_control(void __iomem *base, int enable) +{ + unsigned long r = __raw_readl(base + AU1200_USBCFG); + if (enable) { + __raw_writel(r | USBCFG_OCE, base + AU1200_USBCFG); + wmb(); + udelay(2000); + } else { + __raw_writel(r & ~USBCFG_OCE, base + AU1200_USBCFG); + wmb(); + udelay(1000); + } +} + +static inline void __au1200_ehci_control(void __iomem *base, int enable) +{ + unsigned long r = __raw_readl(base + AU1200_USBCFG); + if (enable) { + __raw_writel(r | USBCFG_ECE | USBCFG_PPE, base + AU1200_USBCFG); + wmb(); + udelay(1000); + } else { + if (!(r & USBCFG_UCE)) /* UDC also off? */ + r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */ + __raw_writel(r & ~USBCFG_ECE, base + AU1200_USBCFG); + wmb(); + udelay(1000); + } +} + +static inline void __au1200_udc_control(void __iomem *base, int enable) +{ + unsigned long r = __raw_readl(base + AU1200_USBCFG); + if (enable) { + __raw_writel(r | USBCFG_UCE | USBCFG_PPE, base + AU1200_USBCFG); + wmb(); + } else { + if (!(r & USBCFG_ECE)) /* EHCI also off? */ + r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */ + __raw_writel(r & ~USBCFG_UCE, base + AU1200_USBCFG); + wmb(); + } +} + +static inline int au1200_coherency_bug(void) +{ +#if defined(CONFIG_DMA_COHERENT) + /* Au1200 AB USB does not support coherent memory */ + if (!(read_c0_prid() & 0xff)) { + printk(KERN_INFO "Au1200 USB: this is chip revision AB !!\n"); + printk(KERN_INFO "Au1200 USB: update your board or re-configure" + " the kernel\n"); + return -ENODEV; + } +#endif + return 0; +} + +static inline int au1200_usb_control(int block, int enable) +{ + void __iomem *base = + (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR); + int ret = 0; + + switch (block) { + case ALCHEMY_USB_OHCI0: + ret = au1200_coherency_bug(); + if (ret && enable) + goto out; + __au1200_ohci_control(base, enable); + break; + case ALCHEMY_USB_UDC0: + __au1200_udc_control(base, enable); + break; + case ALCHEMY_USB_EHCI0: + ret = au1200_coherency_bug(); + if (ret && enable) + goto out; + __au1200_ehci_control(base, enable); + break; + default: + ret = -ENODEV; + } +out: + return ret; +} + + +/* initialize USB block(s) to a known working state */ +static inline void au1200_usb_init(void) +{ + void __iomem *base = + (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR); + __raw_writel(USBCFG_INIT_AU1200, base + AU1200_USBCFG); + wmb(); + udelay(1000); +} + +static inline void au1000_usb_init(unsigned long rb, int reg) +{ + void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg); + unsigned long r = __raw_readl(base); + +#if defined(__BIG_ENDIAN) + r |= USBHEN_BE; +#endif + r |= USBHEN_C; + + __raw_writel(r, base); + wmb(); + udelay(1000); +} + + +static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg) +{ + void __iomem *base = (void __iomem *)KSEG1ADDR(rb); + unsigned long r = __raw_readl(base + creg); + + if (enable) { + __raw_writel(r | USBHEN_CE, base + creg); + wmb(); + udelay(1000); + __raw_writel(r | USBHEN_CE | USBHEN_E, base + creg); + wmb(); + udelay(1000); + + /* wait for reset complete (read reg twice: au1500 erratum) */ + while (__raw_readl(base + creg), + !(__raw_readl(base + creg) & USBHEN_RD)) + udelay(1000); + } else { + __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg); + wmb(); + } +} + +static inline int au1000_usb_control(int block, int enable, unsigned long rb, + int creg) +{ + int ret = 0; + + switch (block) { + case ALCHEMY_USB_OHCI0: + __au1xx0_ohci_control(enable, rb, creg); + break; + default: + ret = -ENODEV; + } + return ret; +} + +/* + * alchemy_usb_control - control Alchemy on-chip USB blocks + * @block: USB block to target + * @enable: set 1 to enable a block, 0 to disable + */ +int alchemy_usb_control(int block, int enable) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&alchemy_usb_lock, flags); + switch (alchemy_get_cputype()) { + case ALCHEMY_CPU_AU1000: + case ALCHEMY_CPU_AU1500: + case ALCHEMY_CPU_AU1100: + ret = au1000_usb_control(block, enable, + AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); + break; + case ALCHEMY_CPU_AU1550: + ret = au1000_usb_control(block, enable, + AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); + break; + case ALCHEMY_CPU_AU1200: + ret = au1200_usb_control(block, enable); + break; + case ALCHEMY_CPU_AU1300: + ret = au1300_usb_control(block, enable); + break; + default: + ret = -ENODEV; + } + spin_unlock_irqrestore(&alchemy_usb_lock, flags); + return ret; +} +EXPORT_SYMBOL_GPL(alchemy_usb_control); + + +static unsigned long alchemy_usb_pmdata[2]; + +static void au1000_usb_pm(unsigned long br, int creg, int susp) +{ + void __iomem *base = (void __iomem *)KSEG1ADDR(br); + + if (susp) { + alchemy_usb_pmdata[0] = __raw_readl(base + creg); + /* There appears to be some undocumented reset register.... */ + __raw_writel(0, base + 0x04); + wmb(); + __raw_writel(0, base + creg); + wmb(); + } else { + __raw_writel(alchemy_usb_pmdata[0], base + creg); + wmb(); + } +} + +static void au1200_usb_pm(int susp) +{ + void __iomem *base = + (void __iomem *)KSEG1ADDR(AU1200_USB_OTG_PHYS_ADDR); + if (susp) { + /* save OTG_CAP/MUX registers which indicate port routing */ + /* FIXME: write an OTG driver to do that */ + alchemy_usb_pmdata[0] = __raw_readl(base + 0x00); + alchemy_usb_pmdata[1] = __raw_readl(base + 0x04); + } else { + /* restore access to all MMIO areas */ + au1200_usb_init(); + + /* restore OTG_CAP/MUX registers */ + __raw_writel(alchemy_usb_pmdata[0], base + 0x00); + __raw_writel(alchemy_usb_pmdata[1], base + 0x04); + wmb(); + } +} + +static void au1300_usb_pm(int susp) +{ + void __iomem *base = + (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); + /* remember Port2 routing */ + if (susp) { + alchemy_usb_pmdata[0] = __raw_readl(base + USB_DWC_CTRL4); + } else { + au1300_usb_init(); + __raw_writel(alchemy_usb_pmdata[0], base + USB_DWC_CTRL4); + wmb(); + } +} + +static void alchemy_usb_pm(int susp) +{ + switch (alchemy_get_cputype()) { + case ALCHEMY_CPU_AU1000: + case ALCHEMY_CPU_AU1500: + case ALCHEMY_CPU_AU1100: + au1000_usb_pm(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG, susp); + break; + case ALCHEMY_CPU_AU1550: + au1000_usb_pm(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG, susp); + break; + case ALCHEMY_CPU_AU1200: + au1200_usb_pm(susp); + break; + case ALCHEMY_CPU_AU1300: + au1300_usb_pm(susp); + break; + } +} + +static int alchemy_usb_suspend(void) +{ + alchemy_usb_pm(1); + return 0; +} + +static void alchemy_usb_resume(void) +{ + alchemy_usb_pm(0); +} + +static struct syscore_ops alchemy_usb_pm_ops = { + .suspend = alchemy_usb_suspend, + .resume = alchemy_usb_resume, +}; + +static int __init alchemy_usb_init(void) +{ + switch (alchemy_get_cputype()) { + case ALCHEMY_CPU_AU1000: + case ALCHEMY_CPU_AU1500: + case ALCHEMY_CPU_AU1100: + au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); + break; + case ALCHEMY_CPU_AU1550: + au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); + break; + case ALCHEMY_CPU_AU1200: + au1200_usb_init(); + break; + case ALCHEMY_CPU_AU1300: + au1300_usb_init(); + break; + } + + register_syscore_ops(&alchemy_usb_pm_ops); + + return 0; +} +arch_initcall(alchemy_usb_init); diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 9e0a89ced15..332ed897a6f 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -40,6 +40,5 @@ obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o -obj-$(CONFIG_MIPS_ALCHEMY) += alchemy-common.o obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o diff --git a/drivers/usb/host/alchemy-common.c b/drivers/usb/host/alchemy-common.c deleted file mode 100644 index 936af8359fb..00000000000 --- a/drivers/usb/host/alchemy-common.c +++ /dev/null @@ -1,614 +0,0 @@ -/* - * USB block power/access management abstraction. - * - * Au1000+: The OHCI block control register is at the far end of the OHCI memory - * area. Au1550 has OHCI on different base address. No need to handle - * UDC here. - * Au1200: one register to control access and clocks to O/EHCI, UDC and OTG - * as well as the PHY for EHCI and UDC. - * - */ - -#include -#include -#include -#include -#include -#include - -/* control register offsets */ -#define AU1000_OHCICFG 0x7fffc -#define AU1550_OHCICFG 0x07ffc -#define AU1200_USBCFG 0x04 - -/* Au1000 USB block config bits */ -#define USBHEN_RD (1 << 4) /* OHCI reset-done indicator */ -#define USBHEN_CE (1 << 3) /* OHCI block clock enable */ -#define USBHEN_E (1 << 2) /* OHCI block enable */ -#define USBHEN_C (1 << 1) /* OHCI block coherency bit */ -#define USBHEN_BE (1 << 0) /* OHCI Big-Endian */ - -/* Au1200 USB config bits */ -#define USBCFG_PFEN (1 << 31) /* prefetch enable (undoc) */ -#define USBCFG_RDCOMB (1 << 30) /* read combining (undoc) */ -#define USBCFG_UNKNOWN (5 << 20) /* unknown, leave this way */ -#define USBCFG_SSD (1 << 23) /* serial short detect en */ -#define USBCFG_PPE (1 << 19) /* HS PHY PLL */ -#define USBCFG_UCE (1 << 18) /* UDC clock enable */ -#define USBCFG_ECE (1 << 17) /* EHCI clock enable */ -#define USBCFG_OCE (1 << 16) /* OHCI clock enable */ -#define USBCFG_FLA(x) (((x) & 0x3f) << 8) -#define USBCFG_UCAM (1 << 7) /* coherent access (undoc) */ -#define USBCFG_GME (1 << 6) /* OTG mem access */ -#define USBCFG_DBE (1 << 5) /* UDC busmaster enable */ -#define USBCFG_DME (1 << 4) /* UDC mem enable */ -#define USBCFG_EBE (1 << 3) /* EHCI busmaster enable */ -#define USBCFG_EME (1 << 2) /* EHCI mem enable */ -#define USBCFG_OBE (1 << 1) /* OHCI busmaster enable */ -#define USBCFG_OME (1 << 0) /* OHCI mem enable */ -#define USBCFG_INIT_AU1200 (USBCFG_PFEN | USBCFG_RDCOMB | USBCFG_UNKNOWN |\ - USBCFG_SSD | USBCFG_FLA(0x20) | USBCFG_UCAM | \ - USBCFG_GME | USBCFG_DBE | USBCFG_DME | \ - USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \ - USBCFG_OME) - -/* Au1300 USB config registers */ -#define USB_DWC_CTRL1 0x00 -#define USB_DWC_CTRL2 0x04 -#define USB_VBUS_TIMER 0x10 -#define USB_SBUS_CTRL 0x14 -#define USB_MSR_ERR 0x18 -#define USB_DWC_CTRL3 0x1C -#define USB_DWC_CTRL4 0x20 -#define USB_OTG_STATUS 0x28 -#define USB_DWC_CTRL5 0x2C -#define USB_DWC_CTRL6 0x30 -#define USB_DWC_CTRL7 0x34 -#define USB_PHY_STATUS 0xC0 -#define USB_INT_STATUS 0xC4 -#define USB_INT_ENABLE 0xC8 - -#define USB_DWC_CTRL1_OTGD 0x04 /* set to DISable OTG */ -#define USB_DWC_CTRL1_HSTRS 0x02 /* set to ENable EHCI */ -#define USB_DWC_CTRL1_DCRS 0x01 /* set to ENable UDC */ - -#define USB_DWC_CTRL2_PHY1RS 0x04 /* set to enable PHY1 */ -#define USB_DWC_CTRL2_PHY0RS 0x02 /* set to enable PHY0 */ -#define USB_DWC_CTRL2_PHYRS 0x01 /* set to enable PHY */ - -#define USB_DWC_CTRL3_OHCI1_CKEN (1 << 19) -#define USB_DWC_CTRL3_OHCI0_CKEN (1 << 18) -#define USB_DWC_CTRL3_EHCI0_CKEN (1 << 17) -#define USB_DWC_CTRL3_OTG0_CKEN (1 << 16) - -#define USB_SBUS_CTRL_SBCA 0x04 /* coherent access */ - -#define USB_INTEN_FORCE 0x20 -#define USB_INTEN_PHY 0x10 -#define USB_INTEN_UDC 0x08 -#define USB_INTEN_EHCI 0x04 -#define USB_INTEN_OHCI1 0x02 -#define USB_INTEN_OHCI0 0x01 - -static DEFINE_SPINLOCK(alchemy_usb_lock); - -static inline void __au1300_usb_phyctl(void __iomem *base, int enable) -{ - unsigned long r, s; - - r = __raw_readl(base + USB_DWC_CTRL2); - s = __raw_readl(base + USB_DWC_CTRL3); - - s &= USB_DWC_CTRL3_OHCI1_CKEN | USB_DWC_CTRL3_OHCI0_CKEN | - USB_DWC_CTRL3_EHCI0_CKEN | USB_DWC_CTRL3_OTG0_CKEN; - - if (enable) { - /* simply enable all PHYs */ - r |= USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS | - USB_DWC_CTRL2_PHYRS; - __raw_writel(r, base + USB_DWC_CTRL2); - wmb(); - } else if (!s) { - /* no USB block active, do disable all PHYs */ - r &= ~(USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS | - USB_DWC_CTRL2_PHYRS); - __raw_writel(r, base + USB_DWC_CTRL2); - wmb(); - } -} - -static inline void __au1300_ohci_control(void __iomem *base, int enable, int id) -{ - unsigned long r; - - if (enable) { - __raw_writel(1, base + USB_DWC_CTRL7); /* start OHCI clock */ - wmb(); - - r = __raw_readl(base + USB_DWC_CTRL3); /* enable OHCI block */ - r |= (id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN - : USB_DWC_CTRL3_OHCI1_CKEN; - __raw_writel(r, base + USB_DWC_CTRL3); - wmb(); - - __au1300_usb_phyctl(base, enable); /* power up the PHYs */ - - r = __raw_readl(base + USB_INT_ENABLE); - r |= (id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1; - __raw_writel(r, base + USB_INT_ENABLE); - wmb(); - - /* reset the OHCI start clock bit */ - __raw_writel(0, base + USB_DWC_CTRL7); - wmb(); - } else { - r = __raw_readl(base + USB_INT_ENABLE); - r &= ~((id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1); - __raw_writel(r, base + USB_INT_ENABLE); - wmb(); - - r = __raw_readl(base + USB_DWC_CTRL3); - r &= ~((id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN - : USB_DWC_CTRL3_OHCI1_CKEN); - __raw_writel(r, base + USB_DWC_CTRL3); - wmb(); - - __au1300_usb_phyctl(base, enable); - } -} - -static inline void __au1300_ehci_control(void __iomem *base, int enable) -{ - unsigned long r; - - if (enable) { - r = __raw_readl(base + USB_DWC_CTRL3); - r |= USB_DWC_CTRL3_EHCI0_CKEN; - __raw_writel(r, base + USB_DWC_CTRL3); - wmb(); - - r = __raw_readl(base + USB_DWC_CTRL1); - r |= USB_DWC_CTRL1_HSTRS; - __raw_writel(r, base + USB_DWC_CTRL1); - wmb(); - - __au1300_usb_phyctl(base, enable); - - r = __raw_readl(base + USB_INT_ENABLE); - r |= USB_INTEN_EHCI; - __raw_writel(r, base + USB_INT_ENABLE); - wmb(); - } else { - r = __raw_readl(base + USB_INT_ENABLE); - r &= ~USB_INTEN_EHCI; - __raw_writel(r, base + USB_INT_ENABLE); - wmb(); - - r = __raw_readl(base + USB_DWC_CTRL1); - r &= ~USB_DWC_CTRL1_HSTRS; - __raw_writel(r, base + USB_DWC_CTRL1); - wmb(); - - r = __raw_readl(base + USB_DWC_CTRL3); - r &= ~USB_DWC_CTRL3_EHCI0_CKEN; - __raw_writel(r, base + USB_DWC_CTRL3); - wmb(); - - __au1300_usb_phyctl(base, enable); - } -} - -static inline void __au1300_udc_control(void __iomem *base, int enable) -{ - unsigned long r; - - if (enable) { - r = __raw_readl(base + USB_DWC_CTRL1); - r |= USB_DWC_CTRL1_DCRS; - __raw_writel(r, base + USB_DWC_CTRL1); - wmb(); - - __au1300_usb_phyctl(base, enable); - - r = __raw_readl(base + USB_INT_ENABLE); - r |= USB_INTEN_UDC; - __raw_writel(r, base + USB_INT_ENABLE); - wmb(); - } else { - r = __raw_readl(base + USB_INT_ENABLE); - r &= ~USB_INTEN_UDC; - __raw_writel(r, base + USB_INT_ENABLE); - wmb(); - - r = __raw_readl(base + USB_DWC_CTRL1); - r &= ~USB_DWC_CTRL1_DCRS; - __raw_writel(r, base + USB_DWC_CTRL1); - wmb(); - - __au1300_usb_phyctl(base, enable); - } -} - -static inline void __au1300_otg_control(void __iomem *base, int enable) -{ - unsigned long r; - if (enable) { - r = __raw_readl(base + USB_DWC_CTRL3); - r |= USB_DWC_CTRL3_OTG0_CKEN; - __raw_writel(r, base + USB_DWC_CTRL3); - wmb(); - - r = __raw_readl(base + USB_DWC_CTRL1); - r &= ~USB_DWC_CTRL1_OTGD; - __raw_writel(r, base + USB_DWC_CTRL1); - wmb(); - - __au1300_usb_phyctl(base, enable); - } else { - r = __raw_readl(base + USB_DWC_CTRL1); - r |= USB_DWC_CTRL1_OTGD; - __raw_writel(r, base + USB_DWC_CTRL1); - wmb(); - - r = __raw_readl(base + USB_DWC_CTRL3); - r &= ~USB_DWC_CTRL3_OTG0_CKEN; - __raw_writel(r, base + USB_DWC_CTRL3); - wmb(); - - __au1300_usb_phyctl(base, enable); - } -} - -static inline int au1300_usb_control(int block, int enable) -{ - void __iomem *base = - (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); - int ret = 0; - - switch (block) { - case ALCHEMY_USB_OHCI0: - __au1300_ohci_control(base, enable, 0); - break; - case ALCHEMY_USB_OHCI1: - __au1300_ohci_control(base, enable, 1); - break; - case ALCHEMY_USB_EHCI0: - __au1300_ehci_control(base, enable); - break; - case ALCHEMY_USB_UDC0: - __au1300_udc_control(base, enable); - break; - case ALCHEMY_USB_OTG0: - __au1300_otg_control(base, enable); - break; - default: - ret = -ENODEV; - } - return ret; -} - -static inline void au1300_usb_init(void) -{ - void __iomem *base = - (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); - - /* set some sane defaults. Note: we don't fiddle with DWC_CTRL4 - * here at all: Port 2 routing (EHCI or UDC) must be set either - * by boot firmware or platform init code; I can't autodetect - * a sane setting. - */ - __raw_writel(0, base + USB_INT_ENABLE); /* disable all USB irqs */ - wmb(); - __raw_writel(0, base + USB_DWC_CTRL3); /* disable all clocks */ - wmb(); - __raw_writel(~0, base + USB_MSR_ERR); /* clear all errors */ - wmb(); - __raw_writel(~0, base + USB_INT_STATUS); /* clear int status */ - wmb(); - /* set coherent access bit */ - __raw_writel(USB_SBUS_CTRL_SBCA, base + USB_SBUS_CTRL); - wmb(); -} - -static inline void __au1200_ohci_control(void __iomem *base, int enable) -{ - unsigned long r = __raw_readl(base + AU1200_USBCFG); - if (enable) { - __raw_writel(r | USBCFG_OCE, base + AU1200_USBCFG); - wmb(); - udelay(2000); - } else { - __raw_writel(r & ~USBCFG_OCE, base + AU1200_USBCFG); - wmb(); - udelay(1000); - } -} - -static inline void __au1200_ehci_control(void __iomem *base, int enable) -{ - unsigned long r = __raw_readl(base + AU1200_USBCFG); - if (enable) { - __raw_writel(r | USBCFG_ECE | USBCFG_PPE, base + AU1200_USBCFG); - wmb(); - udelay(1000); - } else { - if (!(r & USBCFG_UCE)) /* UDC also off? */ - r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */ - __raw_writel(r & ~USBCFG_ECE, base + AU1200_USBCFG); - wmb(); - udelay(1000); - } -} - -static inline void __au1200_udc_control(void __iomem *base, int enable) -{ - unsigned long r = __raw_readl(base + AU1200_USBCFG); - if (enable) { - __raw_writel(r | USBCFG_UCE | USBCFG_PPE, base + AU1200_USBCFG); - wmb(); - } else { - if (!(r & USBCFG_ECE)) /* EHCI also off? */ - r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */ - __raw_writel(r & ~USBCFG_UCE, base + AU1200_USBCFG); - wmb(); - } -} - -static inline int au1200_coherency_bug(void) -{ -#if defined(CONFIG_DMA_COHERENT) - /* Au1200 AB USB does not support coherent memory */ - if (!(read_c0_prid() & 0xff)) { - printk(KERN_INFO "Au1200 USB: this is chip revision AB !!\n"); - printk(KERN_INFO "Au1200 USB: update your board or re-configure" - " the kernel\n"); - return -ENODEV; - } -#endif - return 0; -} - -static inline int au1200_usb_control(int block, int enable) -{ - void __iomem *base = - (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR); - int ret = 0; - - switch (block) { - case ALCHEMY_USB_OHCI0: - ret = au1200_coherency_bug(); - if (ret && enable) - goto out; - __au1200_ohci_control(base, enable); - break; - case ALCHEMY_USB_UDC0: - __au1200_udc_control(base, enable); - break; - case ALCHEMY_USB_EHCI0: - ret = au1200_coherency_bug(); - if (ret && enable) - goto out; - __au1200_ehci_control(base, enable); - break; - default: - ret = -ENODEV; - } -out: - return ret; -} - - -/* initialize USB block(s) to a known working state */ -static inline void au1200_usb_init(void) -{ - void __iomem *base = - (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR); - __raw_writel(USBCFG_INIT_AU1200, base + AU1200_USBCFG); - wmb(); - udelay(1000); -} - -static inline void au1000_usb_init(unsigned long rb, int reg) -{ - void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg); - unsigned long r = __raw_readl(base); - -#if defined(__BIG_ENDIAN) - r |= USBHEN_BE; -#endif - r |= USBHEN_C; - - __raw_writel(r, base); - wmb(); - udelay(1000); -} - - -static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg) -{ - void __iomem *base = (void __iomem *)KSEG1ADDR(rb); - unsigned long r = __raw_readl(base + creg); - - if (enable) { - __raw_writel(r | USBHEN_CE, base + creg); - wmb(); - udelay(1000); - __raw_writel(r | USBHEN_CE | USBHEN_E, base + creg); - wmb(); - udelay(1000); - - /* wait for reset complete (read reg twice: au1500 erratum) */ - while (__raw_readl(base + creg), - !(__raw_readl(base + creg) & USBHEN_RD)) - udelay(1000); - } else { - __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg); - wmb(); - } -} - -static inline int au1000_usb_control(int block, int enable, unsigned long rb, - int creg) -{ - int ret = 0; - - switch (block) { - case ALCHEMY_USB_OHCI0: - __au1xx0_ohci_control(enable, rb, creg); - break; - default: - ret = -ENODEV; - } - return ret; -} - -/* - * alchemy_usb_control - control Alchemy on-chip USB blocks - * @block: USB block to target - * @enable: set 1 to enable a block, 0 to disable - */ -int alchemy_usb_control(int block, int enable) -{ - unsigned long flags; - int ret; - - spin_lock_irqsave(&alchemy_usb_lock, flags); - switch (alchemy_get_cputype()) { - case ALCHEMY_CPU_AU1000: - case ALCHEMY_CPU_AU1500: - case ALCHEMY_CPU_AU1100: - ret = au1000_usb_control(block, enable, - AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); - break; - case ALCHEMY_CPU_AU1550: - ret = au1000_usb_control(block, enable, - AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); - break; - case ALCHEMY_CPU_AU1200: - ret = au1200_usb_control(block, enable); - break; - case ALCHEMY_CPU_AU1300: - ret = au1300_usb_control(block, enable); - break; - default: - ret = -ENODEV; - } - spin_unlock_irqrestore(&alchemy_usb_lock, flags); - return ret; -} -EXPORT_SYMBOL_GPL(alchemy_usb_control); - - -static unsigned long alchemy_usb_pmdata[2]; - -static void au1000_usb_pm(unsigned long br, int creg, int susp) -{ - void __iomem *base = (void __iomem *)KSEG1ADDR(br); - - if (susp) { - alchemy_usb_pmdata[0] = __raw_readl(base + creg); - /* There appears to be some undocumented reset register.... */ - __raw_writel(0, base + 0x04); - wmb(); - __raw_writel(0, base + creg); - wmb(); - } else { - __raw_writel(alchemy_usb_pmdata[0], base + creg); - wmb(); - } -} - -static void au1200_usb_pm(int susp) -{ - void __iomem *base = - (void __iomem *)KSEG1ADDR(AU1200_USB_OTG_PHYS_ADDR); - if (susp) { - /* save OTG_CAP/MUX registers which indicate port routing */ - /* FIXME: write an OTG driver to do that */ - alchemy_usb_pmdata[0] = __raw_readl(base + 0x00); - alchemy_usb_pmdata[1] = __raw_readl(base + 0x04); - } else { - /* restore access to all MMIO areas */ - au1200_usb_init(); - - /* restore OTG_CAP/MUX registers */ - __raw_writel(alchemy_usb_pmdata[0], base + 0x00); - __raw_writel(alchemy_usb_pmdata[1], base + 0x04); - wmb(); - } -} - -static void au1300_usb_pm(int susp) -{ - void __iomem *base = - (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); - /* remember Port2 routing */ - if (susp) { - alchemy_usb_pmdata[0] = __raw_readl(base + USB_DWC_CTRL4); - } else { - au1300_usb_init(); - __raw_writel(alchemy_usb_pmdata[0], base + USB_DWC_CTRL4); - wmb(); - } -} - -static void alchemy_usb_pm(int susp) -{ - switch (alchemy_get_cputype()) { - case ALCHEMY_CPU_AU1000: - case ALCHEMY_CPU_AU1500: - case ALCHEMY_CPU_AU1100: - au1000_usb_pm(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG, susp); - break; - case ALCHEMY_CPU_AU1550: - au1000_usb_pm(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG, susp); - break; - case ALCHEMY_CPU_AU1200: - au1200_usb_pm(susp); - break; - case ALCHEMY_CPU_AU1300: - au1300_usb_pm(susp); - break; - } -} - -static int alchemy_usb_suspend(void) -{ - alchemy_usb_pm(1); - return 0; -} - -static void alchemy_usb_resume(void) -{ - alchemy_usb_pm(0); -} - -static struct syscore_ops alchemy_usb_pm_ops = { - .suspend = alchemy_usb_suspend, - .resume = alchemy_usb_resume, -}; - -static int __init alchemy_usb_init(void) -{ - switch (alchemy_get_cputype()) { - case ALCHEMY_CPU_AU1000: - case ALCHEMY_CPU_AU1500: - case ALCHEMY_CPU_AU1100: - au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); - break; - case ALCHEMY_CPU_AU1550: - au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); - break; - case ALCHEMY_CPU_AU1200: - au1200_usb_init(); - break; - case ALCHEMY_CPU_AU1300: - au1300_usb_init(); - break; - } - - register_syscore_ops(&alchemy_usb_pm_ops); - - return 0; -} -arch_initcall(alchemy_usb_init); -- cgit v1.2.3 From 2350cb0cc1303d47b43fc60cf06c19dd145b2eb5 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:41 +0200 Subject: USB: EHCI: make ehci-platform use dev_err() instead of pr_err() This patch converts the ehci-platform driver to make use of the dev_err() functions instead of pr_err(). Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-platform.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 607adf9adb8..6516717edbf 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -98,12 +98,12 @@ static int __devinit ehci_platform_probe(struct platform_device *dev) irq = platform_get_irq(dev, 0); if (irq < 0) { - pr_err("no irq provided"); + dev_err(&dev->dev, "no irq provided"); return irq; } res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res_mem) { - pr_err("no memory recourse provided"); + dev_err(&dev->dev, "no memory recourse provided"); return -ENXIO; } @@ -124,7 +124,7 @@ static int __devinit ehci_platform_probe(struct platform_device *dev) hcd->rsrc_len = resource_size(res_mem); if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - pr_err("controller already in use"); + dev_err(&dev->dev, "controller already in use"); err = -EBUSY; goto err_put_hcd; } -- cgit v1.2.3 From 976baf6e96569b1e253233061b074dbe5a7f2ca9 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:42 +0200 Subject: USB: OHCI: make ohci-platform use dev_err() instead of pr_err() This patch converts the ohci-platform driver to use dev_err() functions instead of pr_err(). Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-platform.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 99d17552d80..8a606f4b2d3 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -101,13 +101,13 @@ static int __devinit ohci_platform_probe(struct platform_device *dev) irq = platform_get_irq(dev, 0); if (irq < 0) { - pr_err("no irq provided"); + dev_err(&dev->dev, "no irq provided"); return irq; } res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res_mem) { - pr_err("no memory recourse provided"); + dev_err(&dev->dev, "no memory recourse provided"); return -ENXIO; } @@ -128,7 +128,7 @@ static int __devinit ohci_platform_probe(struct platform_device *dev) hcd->rsrc_len = resource_size(res_mem); if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - pr_err("controller already in use"); + dev_err(&dev->dev, "controller already in use"); err = -EBUSY; goto err_put_hcd; } -- cgit v1.2.3 From 5c9b2b28e5385614169ec133f7b0cbfbeb38dc22 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:43 +0200 Subject: USB: EHCI: fix typo in ehci-platform driver on the word "resource" Fix the obvious typo in the error message, we meant to write "resource" instead of "recourse". Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 6516717edbf..3cb0b1bf9ac 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -103,7 +103,7 @@ static int __devinit ehci_platform_probe(struct platform_device *dev) } res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res_mem) { - dev_err(&dev->dev, "no memory recourse provided"); + dev_err(&dev->dev, "no memory resource provided"); return -ENXIO; } -- cgit v1.2.3 From ac0e3c04eb7dbf093032b72020951f9b92ede3d7 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:44 +0200 Subject: USB: OHCI: fix typo in ohci-platform driver on the word "resource" We meant to write "resource" instead of "recourse", this patch fixes this typo. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 8a606f4b2d3..1344426b05a 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -107,7 +107,7 @@ static int __devinit ohci_platform_probe(struct platform_device *dev) res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res_mem) { - dev_err(&dev->dev, "no memory recourse provided"); + dev_err(&dev->dev, "no memory resource provided"); return -ENXIO; } -- cgit v1.2.3 From 61ff2745e53512adf22625f9194e83e471882523 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:45 +0200 Subject: USB: EHCI: make ehci-platform use devm_request_and_ioremap helper This patch changes the ehci-platform driver to use the device managed helper function for requesting memory region and ioremapping memory resources. As a result the error path in the probe function is simplified, and the platform driver remove callback does no longer need to release and iounmap memory resources. devm_request_and_ioremap() will use either the ioremap() or ioremap_nocache() handler depending on the resource's CACHEABLE flag, so we are good with this change. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-platform.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 3cb0b1bf9ac..272728c48c9 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -123,29 +123,19 @@ static int __devinit ehci_platform_probe(struct platform_device *dev) hcd->rsrc_start = res_mem->start; hcd->rsrc_len = resource_size(res_mem); - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - dev_err(&dev->dev, "controller already in use"); - err = -EBUSY; - goto err_put_hcd; - } - - hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); + hcd->regs = devm_request_and_ioremap(&dev->dev, res_mem); if (!hcd->regs) { err = -ENOMEM; - goto err_release_region; + goto err_put_hcd; } err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) - goto err_iounmap; + goto err_put_hcd; platform_set_drvdata(dev, hcd); return err; -err_iounmap: - iounmap(hcd->regs); -err_release_region: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err_put_hcd: usb_put_hcd(hcd); err_power: @@ -161,8 +151,6 @@ static int __devexit ehci_platform_remove(struct platform_device *dev) struct usb_ehci_pdata *pdata = dev->dev.platform_data; usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); platform_set_drvdata(dev, NULL); -- cgit v1.2.3 From be7ac70b9b1cb49758d52abb554c92c03acd6f08 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 8 Oct 2012 15:11:46 +0200 Subject: USB: OHCI: make ohci-platform use devm_request_and_ioremap helper This patch changes the ohci-platform driver to use the device managed helper function for requesting memory region and ioremapping memory resources. As a result the error path in the probe function is simplified, and the platform driver remove callback does no longer need to release and iounmap memory resources. devm_request_and_ioremap() will use either the ioremap() or ioremap_nocache() handler depending on the resource's CACHEABLE flag, so we are good with this change. Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-platform.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index 1344426b05a..bda4e0bb8ab 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -127,29 +127,19 @@ static int __devinit ohci_platform_probe(struct platform_device *dev) hcd->rsrc_start = res_mem->start; hcd->rsrc_len = resource_size(res_mem); - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - dev_err(&dev->dev, "controller already in use"); - err = -EBUSY; - goto err_put_hcd; - } - - hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); + hcd->regs = devm_request_and_ioremap(&dev->dev, res_mem); if (!hcd->regs) { err = -ENOMEM; - goto err_release_region; + goto err_put_hcd; } err = usb_add_hcd(hcd, irq, IRQF_SHARED); if (err) - goto err_iounmap; + goto err_put_hcd; platform_set_drvdata(dev, hcd); return err; -err_iounmap: - iounmap(hcd->regs); -err_release_region: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err_put_hcd: usb_put_hcd(hcd); err_power: @@ -165,8 +155,6 @@ static int __devexit ohci_platform_remove(struct platform_device *dev) struct usb_ohci_pdata *pdata = dev->dev.platform_data; usb_remove_hcd(hcd); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); platform_set_drvdata(dev, NULL); -- cgit v1.2.3 From da31fe451a7a717c01ae26fa1e9e46fa43921b7d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Oct 2012 11:28:18 +0300 Subject: WUSB: remove an unnused variable The "wusb_cap_descr_default" is never used. GCC doesn't complain about it because we have that line ".bLength = sizeof(wusb_cap_descr_default)" inside the definition itself. Clang complains though. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/usb/wusbcore/devconnect.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index 231009af65a..1d365316960 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c @@ -847,19 +847,6 @@ static void wusb_dev_bos_rm(struct wusb_dev *wusb_dev) wusb_dev->wusb_cap_descr = NULL; }; -static struct usb_wireless_cap_descriptor wusb_cap_descr_default = { - .bLength = sizeof(wusb_cap_descr_default), - .bDescriptorType = USB_DT_DEVICE_CAPABILITY, - .bDevCapabilityType = USB_CAP_TYPE_WIRELESS_USB, - - .bmAttributes = USB_WIRELESS_BEACON_NONE, - .wPHYRates = cpu_to_le16(USB_WIRELESS_PHY_53), - .bmTFITXPowerInfo = 0, - .bmFFITXPowerInfo = 0, - .bmBandGroup = cpu_to_le16(0x0001), /* WUSB1.0[7.4.1] bottom */ - .bReserved = 0 -}; - /* * USB stack's device addition Notifier Callback * -- cgit v1.2.3 From 802562807af61fc8b6f830725e127bf53e0a7f1c Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 1 Oct 2012 14:45:37 -0700 Subject: staging/olpc_dcon: drop useaa module arg The 'useaa' module parameter was a workaround for a buggy DCON prototype not supporting the optional anti-aliasing mode properly. There's no reason to disable it any more, so drop the option. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index d49c32a9569..7dcd0603318 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -39,10 +39,6 @@ static ushort resumeline = 898; module_param(resumeline, ushort, 0444); -/* Default off since it doesn't work on DCON ASIC in B-test OLPC board */ -static int useaa = 1; -module_param(useaa, int, 0444); - static struct dcon_platform_data *pdata; /* I2C structures */ @@ -103,9 +99,7 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init) /* Colour swizzle, AA, no passthrough, backlight */ if (is_init) { dcon->disp_mode = MODE_PASSTHRU | MODE_BL_ENABLE | - MODE_CSWIZZLE; - if (useaa) - dcon->disp_mode |= MODE_COL_AA; + MODE_CSWIZZLE | MODE_COL_AA; } dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode); @@ -191,9 +185,7 @@ static int dcon_set_mono_mode(struct dcon_priv *dcon, bool enable_mono) dcon->disp_mode |= MODE_MONO_LUMA; } else { dcon->disp_mode &= ~(MODE_MONO_LUMA); - dcon->disp_mode |= MODE_CSWIZZLE; - if (useaa) - dcon->disp_mode |= MODE_COL_AA; + dcon->disp_mode |= MODE_CSWIZZLE | MODE_COL_AA; } dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode); -- cgit v1.2.3 From c40f20da3b3f0738ced45533c743217e00090062 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 1 Oct 2012 14:45:50 -0700 Subject: staging/olpc_dcon: move wait queue into dcon_priv struct Another global variable (dcon_wait_queue) moved into the dcon_priv struct. In the process, replace an instance of a manually implemented wait_event_timeout. This code came from Jordan's original gxfb_dcon.c driver waaaay back in 2006; well past time for a replacement. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 22 ++++++---------------- drivers/staging/olpc_dcon/olpc_dcon.h | 1 + 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 7dcd0603318..38f988b7f16 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -46,8 +46,6 @@ static struct dcon_platform_data *pdata; /* Platform devices */ static struct platform_device *dcon_device; -static DECLARE_WAIT_QUEUE_HEAD(dcon_wait_queue); - static unsigned short normal_i2c[] = { 0x0d, I2C_CLIENT_END }; static s32 dcon_write(struct dcon_priv *dcon, u8 reg, u16 val) @@ -280,7 +278,6 @@ static void dcon_source_switch(struct work_struct *work) { struct dcon_priv *dcon = container_of(work, struct dcon_priv, switch_source); - DECLARE_WAITQUEUE(wait, current); int source = dcon->pending_src; if (dcon->curr_src == source) @@ -297,11 +294,9 @@ static void dcon_source_switch(struct work_struct *work) if (dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode | MODE_SCAN_INT)) pr_err("couldn't enable scanline interrupt!\n"); - else { + else /* Wait up to one second for the scanline interrupt */ - wait_event_timeout(dcon_wait_queue, - dcon->switched == true, HZ); - } + wait_event_timeout(dcon->waitq, dcon->switched, HZ); if (!dcon->switched) pr_err("Timeout entering CPU mode; expect a screen glitch.\n"); @@ -332,21 +327,15 @@ static void dcon_source_switch(struct work_struct *work) break; case DCON_SOURCE_DCON: { - int t; struct timespec delta_t; pr_info("dcon_source_switch to DCON\n"); - add_wait_queue(&dcon_wait_queue, &wait); - set_current_state(TASK_UNINTERRUPTIBLE); - /* Clear DCONLOAD - this implies that the DCON is in control */ pdata->set_dconload(0); getnstimeofday(&dcon->load_time); - t = schedule_timeout(HZ/2); - remove_wait_queue(&dcon_wait_queue, &wait); - set_current_state(TASK_RUNNING); + wait_event_timeout(dcon->waitq, dcon->switched, HZ/2); if (!dcon->switched) { pr_err("Timeout entering DCON mode; expect a screen glitch.\n"); @@ -614,6 +603,7 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) return -ENOMEM; dcon->client = client; + init_waitqueue_head(&dcon->waitq); INIT_WORK(&dcon->switch_source, dcon_source_switch); dcon->reboot_nb.notifier_call = dcon_reboot_notify; dcon->reboot_nb.priority = -1; @@ -756,7 +746,7 @@ irqreturn_t dcon_interrupt(int irq, void *id) case 1: /* switch to CPU mode */ dcon->switched = true; getnstimeofday(&dcon->irq_time); - wake_up(&dcon_wait_queue); + wake_up(&dcon->waitq); break; case 0: @@ -770,7 +760,7 @@ irqreturn_t dcon_interrupt(int irq, void *id) if (dcon->curr_src != dcon->pending_src && !dcon->switched) { dcon->switched = true; getnstimeofday(&dcon->irq_time); - wake_up(&dcon_wait_queue); + wake_up(&dcon->waitq); pr_debug("switching w/ status 0/0\n"); } else { pr_debug("scanline interrupt w/CPU\n"); diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h index 167a41778be..e3f8437a8ac 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.h +++ b/drivers/staging/olpc_dcon/olpc_dcon.h @@ -52,6 +52,7 @@ struct dcon_priv { struct fb_info *fbinfo; struct backlight_device *bl_dev; + wait_queue_head_t waitq; struct work_struct switch_source; struct notifier_block reboot_nb; struct notifier_block fbevent_nb; -- cgit v1.2.3 From 20b27c61b714537a4cd6d93679e9d8a5947f1769 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 1 Oct 2012 14:46:01 -0700 Subject: staging/olpc_dcon: drop fb_notifier code Previously we registered a notifier block to inform us of any framebuffer device changes; if the screen was blanked or unblanked, we'd put the DCON to sleep or wake it up. Turns out that the backlight code registers a notifier block as well and calls the update_status hook, so we can just use that to put the DCON to sleep. For those status updates where the blanking isn't changed, dcon_sleep will do nothing. Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 25 ++++--------------------- drivers/staging/olpc_dcon/olpc_dcon.h | 1 - 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 38f988b7f16..2b0bbaccbd3 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -520,6 +520,10 @@ static int dcon_bl_update(struct backlight_device *dev) if (level != dcon->bl_val) dcon_set_backlight(dcon, level); + /* power down the DCON when the screen is blanked */ + if (!dcon->ignore_fb_events) + dcon_sleep(dcon, !!(dev->props.state & BL_CORE_FBBLANK)); + return 0; } @@ -565,24 +569,6 @@ static struct notifier_block dcon_panic_nb = { .notifier_call = unfreeze_on_panic, }; -/* - * When the framebuffer sleeps due to external sources (e.g. user idle), power - * down the DCON as well. Power it back up when the fb comes back to life. - */ -static int dcon_fb_notifier(struct notifier_block *self, - unsigned long event, void *data) -{ - struct fb_event *evdata = data; - struct dcon_priv *dcon = container_of(self, struct dcon_priv, - fbevent_nb); - int *blank = (int *)evdata->data; - if (((event != FB_EVENT_BLANK) && (event != FB_EVENT_CONBLANK)) || - dcon->ignore_fb_events) - return 0; - dcon_sleep(dcon, *blank ? true : false); - return 0; -} - static int dcon_detect(struct i2c_client *client, struct i2c_board_info *info) { strlcpy(info->type, "olpc_dcon", I2C_NAME_SIZE); @@ -607,7 +593,6 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) INIT_WORK(&dcon->switch_source, dcon_source_switch); dcon->reboot_nb.notifier_call = dcon_reboot_notify; dcon->reboot_nb.priority = -1; - dcon->fbevent_nb.notifier_call = dcon_fb_notifier; i2c_set_clientdata(client, dcon); @@ -662,7 +647,6 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) register_reboot_notifier(&dcon->reboot_nb); atomic_notifier_chain_register(&panic_notifier_list, &dcon_panic_nb); - fb_register_client(&dcon->fbevent_nb); return 0; @@ -683,7 +667,6 @@ static int dcon_remove(struct i2c_client *client) { struct dcon_priv *dcon = i2c_get_clientdata(client); - fb_unregister_client(&dcon->fbevent_nb); unregister_reboot_notifier(&dcon->reboot_nb); atomic_notifier_chain_unregister(&panic_notifier_list, &dcon_panic_nb); diff --git a/drivers/staging/olpc_dcon/olpc_dcon.h b/drivers/staging/olpc_dcon/olpc_dcon.h index e3f8437a8ac..997bded2949 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.h +++ b/drivers/staging/olpc_dcon/olpc_dcon.h @@ -55,7 +55,6 @@ struct dcon_priv { wait_queue_head_t waitq; struct work_struct switch_source; struct notifier_block reboot_nb; - struct notifier_block fbevent_nb; /* Shadow register for the DCON_REG_MODE register */ u8 disp_mode; -- cgit v1.2.3 From 6c98274cba3b68e6d87ddb3b0be2bec449106181 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 1 Oct 2012 14:46:11 -0700 Subject: staging/olpc_dcon: drop pin frobbing code for xo1.5 This code looks in the PCI config space for pin addresses and sets up some stuff. However, Openfirmware has already done this for us, so there's no need to ever do it in Linux. According to Mitch Bradley, this OFW has been doing this for us since at least B3 builds (pre-mass production). Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c | 30 ---------------------------- 1 file changed, 30 deletions(-) diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c index 352dd3db013..6a4d379c16a 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c @@ -10,7 +10,6 @@ #include #include -#include #include #include @@ -62,33 +61,6 @@ static int dcon_was_irq(void) static int dcon_init_xo_1_5(struct dcon_priv *dcon) { unsigned int irq; - u_int8_t tmp; - struct pci_dev *pdev; - - pdev = pci_get_device(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VX855, NULL); - if (!pdev) { - pr_err("cannot find VX855 PCI ID\n"); - return 1; - } - - pci_read_config_byte(pdev, 0x95, &tmp); - pci_write_config_byte(pdev, 0x95, tmp|0x0c); - - /* Set GPIO8 to GPIO mode, not SSPICLK */ - pci_read_config_byte(pdev, 0xe3, &tmp); - pci_write_config_byte(pdev, 0xe3, tmp | 0x04); - - /* Set GPI10/GPI11 to GPI mode, not SSPISDI/SSPISS */ - pci_read_config_byte(pdev, 0xe4, &tmp); - pci_write_config_byte(pdev, 0xe4, tmp|0x08); - - /* clear PMU_RxE1[6] to select SCI on GPIO12 */ - /* clear PMU_RxE0[6] to choose falling edge */ - pci_read_config_byte(pdev, 0xe1, &tmp); - pci_write_config_byte(pdev, 0xe1, tmp & ~BIT_GPIO12); - pci_read_config_byte(pdev, 0xe0, &tmp); - pci_write_config_byte(pdev, 0xe0, tmp & ~BIT_GPIO12); dcon_clear_irq(); @@ -101,8 +73,6 @@ static int dcon_init_xo_1_5(struct dcon_priv *dcon) DCON_SOURCE_CPU : DCON_SOURCE_DCON; dcon->pending_src = dcon->curr_src; - pci_dev_put(pdev); - /* we're sharing the IRQ with ACPI */ irq = acpi_gbl_FADT.sci_interrupt; if (request_irq(irq, &dcon_interrupt, IRQF_SHARED, "DCON", dcon)) { -- cgit v1.2.3 From 3e5e624bfda39417cc76e716a350a318049dbd39 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 1 Oct 2012 14:46:21 -0700 Subject: staging/olpc_dcon: use s/r hooks from device_driver->pm ..instead of the i2c_driver hooks. This should silence the following runtime warnings: [ 17.820321] i2c-core: driver [olpc_dcon] using legacy suspend method [ 17.846082] i2c-core: driver [olpc_dcon] using legacy resume method Signed-off-by: Andres Salomon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/olpc_dcon/olpc_dcon.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 2b0bbaccbd3..3fe209ca38c 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -685,8 +685,9 @@ static int dcon_remove(struct i2c_client *client) } #ifdef CONFIG_PM -static int dcon_suspend(struct i2c_client *client, pm_message_t state) +static int dcon_suspend(struct device *dev) { + struct i2c_client *client = to_i2c_client(dev); struct dcon_priv *dcon = i2c_get_clientdata(client); if (!dcon->asleep) { @@ -697,8 +698,9 @@ static int dcon_suspend(struct i2c_client *client, pm_message_t state) return 0; } -static int dcon_resume(struct i2c_client *client) +static int dcon_resume(struct device *dev) { + struct i2c_client *client = to_i2c_client(dev); struct dcon_priv *dcon = i2c_get_clientdata(client); if (!dcon->asleep) { @@ -709,7 +711,12 @@ static int dcon_resume(struct i2c_client *client) return 0; } -#endif +#else + +#define dcon_suspend NULL +#define dcon_resume NULL + +#endif /* CONFIG_PM */ irqreturn_t dcon_interrupt(int irq, void *id) @@ -753,16 +760,21 @@ irqreturn_t dcon_interrupt(int irq, void *id) return IRQ_HANDLED; } +static const struct dev_pm_ops dcon_pm_ops = { + .suspend = dcon_suspend, + .resume = dcon_resume, +}; + static const struct i2c_device_id dcon_idtable[] = { { "olpc_dcon", 0 }, { } }; - MODULE_DEVICE_TABLE(i2c, dcon_idtable); struct i2c_driver dcon_driver = { .driver = { .name = "olpc_dcon", + .pm = &dcon_pm_ops, }, .class = I2C_CLASS_DDC | I2C_CLASS_HWMON, .id_table = dcon_idtable, @@ -770,10 +782,6 @@ struct i2c_driver dcon_driver = { .remove = __devexit_p(dcon_remove), .detect = dcon_detect, .address_list = normal_i2c, -#ifdef CONFIG_PM - .suspend = dcon_suspend, - .resume = dcon_resume, -#endif }; static int __init olpc_dcon_init(void) -- cgit v1.2.3 From cbf2f545d7adf9841d4b6ee7fbfa9b1706e369d4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 2 Oct 2012 11:26:04 +0300 Subject: staging: rtl8192u: fix a macro expansion bug Clang detected this macro expansion bug: drivers/staging/rtl8192u/r8192U_core.c:2384:76: warning: operator '?:' has lower precedence than '+'; '+' will be evaluated first [-Wparentheses] The line from the .c file looks like this: u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime; We need to put parenthesis around the entire macro to fix the bug. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 13f45c3125c..502bfdbcc84 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -235,7 +235,10 @@ enum _ReasonCode{ -#define aSifsTime ((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 10 +#define aSifsTime ((priv->ieee80211->current_network.mode == IEEE_A || \ + priv->ieee80211->current_network.mode == IEEE_N_24G || \ + priv->ieee80211->current_network.mode == IEEE_N_5G) ? \ + 16 : 10) #define MGMT_QUEUE_NUM 5 -- cgit v1.2.3 From 558f758bd23447373841554d3394236420c2e0e0 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Tue, 2 Oct 2012 21:17:11 -0700 Subject: staging "xgifb" Fix typos. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/TODO | 2 +- drivers/staging/xgifb/vb_setmode.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/xgifb/TODO b/drivers/staging/xgifb/TODO index 13d9bc25797..392b29d8f13 100644 --- a/drivers/staging/xgifb/TODO +++ b/drivers/staging/xgifb/TODO @@ -1,4 +1,4 @@ -This drivers still need a lot of work. I can list all cleanups to do but it's +This drivers still needs a lot of work. I can list all cleanups to do but it's going to be long. So, I'm writing "cleanups" and not the list. Arnaud diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index e95a1655a6c..c8561a0b386 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -2501,7 +2501,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, } else { temp = 0x017C; } - } else { /* 3nd party chip */ + } else { /* 3rd party chip */ temp = SetCRT2ToLCD; } @@ -4390,7 +4390,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_and_or(pVBInfo->Part2Port, 0x17, 0xFB, 0x00); xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00); - /* Customized LCDB Des no add */ + /* Customized LCDB Does not add */ tempbx = 5; LCDBDesPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); -- cgit v1.2.3 From 4aef37caf5914dece3aa7af9e744d13c4a4680fc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Oct 2012 10:38:08 -0700 Subject: staging: comedi: mpc8260cpm: remove driver This driver is incomplete and seriously broken. It can't be enabled in the Kconfig and it's not even set up to be compiled. Just remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/mpc8260cpm.c | 164 ---------------------------- 1 file changed, 164 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/mpc8260cpm.c diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c deleted file mode 100644 index c0c33299b7f..00000000000 --- a/drivers/staging/comedi/drivers/mpc8260cpm.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - comedi/drivers/mpc8260.c - driver for digital I/O pins on the MPC 8260 CPM module - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 2000,2001 David A. Schleef - - 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. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -/* -Driver: mpc8260cpm -Description: MPC8260 CPM module generic digital I/O lines -Devices: [Motorola] MPC8260 CPM (mpc8260cpm) -Author: ds -Status: experimental -Updated: Sat, 16 Mar 2002 17:34:48 -0800 - -This driver is specific to the Motorola MPC8260 processor, allowing -you to access the processor's generic digital I/O lines. - -It is apparently missing some code. -*/ - -#include "../comedidev.h" - -extern unsigned long mpc8260_dio_reserved[4]; - -struct mpc8260cpm_private { - - int data; - -}; - -#define devpriv ((struct mpc8260cpm_private *)dev->private) - -static unsigned long *cpm_pdat(int port) -{ - switch (port) { - case 0: - return &io->iop_pdata; - case 1: - return &io->iop_pdatb; - case 2: - return &io->iop_pdatc; - case 3: - return &io->iop_pdatd; - } -} - -static int mpc8260cpm_dio_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int n; - unsigned int d; - unsigned int mask; - int port; - - port = (int)s->private; - mask = 1 << CR_CHAN(insn->chanspec); - if (mask & cpm_reserved_bits[port]) { - return -EINVAL; - } - - switch (data[0]) { - case INSN_CONFIG_DIO_OUTPUT: - s->io_bits |= mask; - break; - case INSN_CONFIG_DIO_INPUT: - s->io_bits &= ~mask; - break; - case INSN_CONFIG_DIO_QUERY: - data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; - return insn->n; - break; - default: - return -EINVAL; - } - - switch (port) { - case 0: - return &io->iop_pdira; - case 1: - return &io->iop_pdirb; - case 2: - return &io->iop_pdirc; - case 3: - return &io->iop_pdird; - } - - return 1; -} - -static int mpc8260cpm_dio_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - int port; - unsigned long *p; - - p = cpm_pdat((int)s->private); - - return insn->n; -} - -static int mpc8260cpm_attach(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - struct comedi_subdevice *s; - int i; - int ret; - - printk("comedi%d: mpc8260cpm: ", dev->minor); - - dev->board_ptr = mpc8260cpm_boards + dev->board; - - dev->board_name = thisboard->name; - - if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0) - return -ENOMEM; - - ret =comedi_alloc_subdevices(dev, 4); - if (ret) - return ret; - - for (i = 0; i < 4; i++) { - s = &dev->subdevices[i]; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 32; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_config = mpc8260cpm_dio_config; - s->insn_bits = mpc8260cpm_dio_bits; - } - - return 1; -} - -static void mpc8260cpm_detach(struct comedi_device *dev) -{ - /* Nothing to cleanup */ -} - -static struct comedi_driver mpc8260cpm_driver = { - .driver_name = "mpc8260cpm", - .module = THIS_MODULE, - .attach = mpc8260cpm_attach, - .detach = mpc8260cpm_detach, -}; -module_comedi_driver(mpc8260cpm_driver); -- cgit v1.2.3 From b25e09232ca22b9dcebe51078011d18b3aea7c3a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Oct 2012 10:42:34 -0700 Subject: staging: comedi: ssv_dnp: remove boardinfo This driver only supports a single "boardtype". Remove the unneeded boardinfo struct and its use in the driver. Change the "driver_name" to match what the boardinfo supplied. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ssv_dnp.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c index ae3aa1c5cae..afa4016f906 100644 --- a/drivers/staging/comedi/drivers/ssv_dnp.c +++ b/drivers/staging/comedi/drivers/ssv_dnp.c @@ -50,15 +50,6 @@ Status: unknown #define PCMR 0xa3 /* Port C Mode Register */ #define PCDR 0xa7 /* Port C Data Register */ -/* This data structure holds information about the supported boards -------- */ - -struct dnp_board { - const char *name; - int ai_chans; - int ai_bits; - int have_dio; -}; - /* ------------------------------------------------------------------------- */ /* The insn_bits interface allows packed reading/writing of DIO channels. */ /* The comedi core can convert between insn_bits and insn_read/write, so you */ @@ -173,11 +164,10 @@ static int dnp_dio_insn_config(struct comedi_device *dev, static int dnp_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct dnp_board *board = comedi_board(dev); struct comedi_subdevice *s; int ret; - dev->board_name = board->name; + dev->board_name = dev->driver->driver_name; ret = comedi_alloc_subdevices(dev, 1); if (ret) @@ -219,23 +209,11 @@ static void dnp_detach(struct comedi_device *dev) outb((inb(CSCDR) & 0xAA), CSCDR); } -static const struct dnp_board dnp_boards[] = { - { - .name = "dnp-1486", - .ai_chans = 16, - .ai_bits = 12, - .have_dio = 1, - }, -}; - static struct comedi_driver dnp_driver = { - .driver_name = "ssv_dnp", + .driver_name = "dnp-1486", .module = THIS_MODULE, .attach = dnp_attach, .detach = dnp_detach, - .board_name = &dnp_boards[0].name, - .offset = sizeof(struct dnp_board), - .num_names = ARRAY_SIZE(dnp_boards), }; module_comedi_driver(dnp_driver); -- cgit v1.2.3 From 04a542d4f7a32abaf71d50fe3c9d338a0815fadb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Oct 2012 10:43:06 -0700 Subject: staging: comedi: serial2002: remove boardinfo This driver only supports a single "boardtype". Remove the unneeded boardinfo struct and its use in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/serial2002.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 5bf84cfbdce..9ed6a7eef01 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -43,10 +43,6 @@ Status: in development #include #include -struct serial2002_board { - const char *name; -}; - struct serial2002_range_table_t { /* HACK... */ @@ -780,12 +776,11 @@ static int serial2002_ei_rinsn(struct comedi_device *dev, static int serial2002_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct serial2002_board *board = comedi_board(dev); struct comedi_subdevice *s; int ret; dev_dbg(dev->class_dev, "serial2002: attach\n"); - dev->board_name = board->name; + dev->board_name = dev->driver->driver_name; if (alloc_private(dev, sizeof(struct serial2002_private)) < 0) return -ENOMEM; dev->open = serial_2002_open; @@ -860,20 +855,11 @@ static void serial2002_detach(struct comedi_device *dev) } } -static const struct serial2002_board serial2002_boards[] = { - { - .name = "serial2002" - }, -}; - static struct comedi_driver serial2002_driver = { .driver_name = "serial2002", .module = THIS_MODULE, .attach = serial2002_attach, .detach = serial2002_detach, - .board_name = &serial2002_boards[0].name, - .offset = sizeof(struct serial2002_board), - .num_names = ARRAY_SIZE(serial2002_boards), }; module_comedi_driver(serial2002_driver); -- cgit v1.2.3 From 16339125416f9d41f24f4ea1e10819ccdb3c8937 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Oct 2012 10:43:43 -0700 Subject: staging: comedi: pcmmio: remove boardinfo This driver only supports a single "boardtype". Remove the unneeded boardinfo struct and its use in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcmmio.c | 101 +++++++------------------------- 1 file changed, 20 insertions(+), 81 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index a10bf0a2987..6ab45dfe68f 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -145,35 +145,6 @@ Configuration Options: #define PAGE_ENAB 2 #define PAGE_INT_ID 3 -/* - * Board descriptions for two imaginary boards. Describing the - * boards in this way is optional, and completely driver-dependent. - * Some drivers use arrays such as this, other do not. - */ -struct pcmmio_board { - const char *name; - const int dio_num_asics; - const int dio_num_ports; - const int total_iosize; - const int ai_bits; - const int ao_bits; - const int n_ai_chans; - const int n_ao_chans; - const struct comedi_lrange *ai_range_table, *ao_range_table; - int (*ai_rinsn) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*ao_rinsn) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - int (*ao_winsn) (struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -}; - static const struct comedi_lrange ranges_ai = { 4, {RANGE(-5., 5.), RANGE(-10., 10.), RANGE(0., 5.), RANGE(0., 10.)} }; @@ -416,9 +387,7 @@ static int pcmmio_dio_insn_config(struct comedi_device *dev, static void switch_page(struct comedi_device *dev, int asic, int page) { - const struct pcmmio_board *board = comedi_board(dev); - - if (asic < 0 || asic >= board->dio_num_asics) + if (asic < 0 || asic >= 1) return; /* paranoia */ if (page < 0 || page >= NUM_PAGES) return; /* more paranoia */ @@ -434,10 +403,9 @@ static void switch_page(struct comedi_device *dev, int asic, int page) static void init_asics(struct comedi_device *dev) { /* sets up an ASIC chip to defaults */ - const struct pcmmio_board *board = comedi_board(dev); int asic; - for (asic = 0; asic < board->dio_num_asics; ++asic) { + for (asic = 0; asic < 1; ++asic) { int port, page; unsigned long baseaddr = devpriv->asics[asic].iobase; @@ -472,9 +440,7 @@ static void init_asics(struct comedi_device *dev) #ifdef notused static void lock_port(struct comedi_device *dev, int asic, int port) { - const struct pcmmio_board *board = comedi_board(dev); - - if (asic < 0 || asic >= board->dio_num_asics) + if (asic < 0 || asic >= 1) return; /* paranoia */ if (port < 0 || port >= PORTS_PER_ASIC) return; /* more paranoia */ @@ -488,9 +454,7 @@ static void lock_port(struct comedi_device *dev, int asic, int port) static void unlock_port(struct comedi_device *dev, int asic, int port) { - const struct pcmmio_board *board = comedi_board(dev); - - if (asic < 0 || asic >= board->dio_num_asics) + if (asic < 0 || asic >= 1) return; /* paranoia */ if (port < 0 || port >= PORTS_PER_ASIC) return; /* more paranoia */ @@ -1012,7 +976,6 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct pcmmio_board *board = comedi_board(dev); struct comedi_subdevice *s; int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic, thisasic_chanct = 0; @@ -1020,23 +983,21 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned int irq[MAX_ASICS]; int ret; + dev->board_name = dev->driver->driver_name; + iobase = it->options[0]; irq[0] = it->options[1]; printk(KERN_INFO "comedi%d: %s: io: %lx attaching...\n", dev->minor, - dev->driver->driver_name, iobase); + dev->board_name, iobase); dev->iobase = iobase; - if (!iobase || !request_region(iobase, - board->total_iosize, - dev->driver->driver_name)) { + if (!iobase || !request_region(iobase, 32, dev->board_name)) { printk(KERN_ERR "comedi%d: I/O port conflict\n", dev->minor); return -EIO; } - dev->board_name = board->name; - /* * Allocate the private structure area. alloc_private() is a * convenient macro defined in comedidev.h. @@ -1059,7 +1020,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) spin_lock_init(&devpriv->asics[asic].spinlock); } - chans_left = CHANS_PER_ASIC * board->dio_num_asics; + chans_left = CHANS_PER_ASIC * 1; n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left); n_subdevs = n_dio_subdevs + 2; devpriv->sprivs = @@ -1078,13 +1039,13 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* First, AI */ s = &dev->subdevices[0]; s->private = &devpriv->sprivs[0]; - s->maxdata = (1 << board->ai_bits) - 1; - s->range_table = board->ai_range_table; + s->maxdata = 0xffff; + s->range_table = &ranges_ai; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; s->type = COMEDI_SUBD_AI; - s->n_chan = board->n_ai_chans; + s->n_chan = 16; s->len_chanlist = s->n_chan; - s->insn_read = board->ai_rinsn; + s->insn_read = ai_rinsn; subpriv->iobase = dev->iobase + 0; /* initialize the resource enable register by clearing it */ outb(0, subpriv->iobase + 3); @@ -1093,14 +1054,14 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Next, AO */ s = &dev->subdevices[1]; s->private = &devpriv->sprivs[1]; - s->maxdata = (1 << board->ao_bits) - 1; - s->range_table = board->ao_range_table; + s->maxdata = 0xffff; + s->range_table = &ranges_ao; s->subdev_flags = SDF_READABLE; s->type = COMEDI_SUBD_AO; - s->n_chan = board->n_ao_chans; + s->n_chan = 8; s->len_chanlist = s->n_chan; - s->insn_read = board->ao_rinsn; - s->insn_write = board->ao_winsn; + s->insn_read = ao_rinsn; + s->insn_write = ao_winsn; subpriv->iobase = dev->iobase + 8; /* initialize the resource enable register by clearing it */ outb(0, subpriv->iobase + 3); @@ -1180,7 +1141,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) { if (irq[asic] && request_irq(irq[asic], interrupt_pcmmio, - IRQF_SHARED, board->name, dev)) { + IRQF_SHARED, dev->board_name, dev)) { int i; /* unroll the allocated irqs.. */ for (i = asic - 1; i >= 0; --i) { @@ -1204,11 +1165,10 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcmmio_detach(struct comedi_device *dev) { - const struct pcmmio_board *board = comedi_board(dev); int i; if (dev->iobase) - release_region(dev->iobase, board->total_iosize); + release_region(dev->iobase, 32); for (i = 0; i < MAX_ASICS; ++i) { if (devpriv && devpriv->asics[i].irq) free_irq(devpriv->asics[i].irq, dev); @@ -1217,32 +1177,11 @@ static void pcmmio_detach(struct comedi_device *dev) kfree(devpriv->sprivs); } -static const struct pcmmio_board pcmmio_boards[] = { - { - .name = "pcmmio", - .dio_num_asics = 1, - .dio_num_ports = 6, - .total_iosize = 32, - .ai_bits = 16, - .ao_bits = 16, - .n_ai_chans = 16, - .n_ao_chans = 8, - .ai_range_table = &ranges_ai, - .ao_range_table = &ranges_ao, - .ai_rinsn = ai_rinsn, - .ao_rinsn = ao_rinsn, - .ao_winsn = ao_winsn - }, -}; - static struct comedi_driver pcmmio_driver = { .driver_name = "pcmmio", .module = THIS_MODULE, .attach = pcmmio_attach, .detach = pcmmio_detach, - .board_name = &pcmmio_boards[0].name, - .offset = sizeof(struct pcmmio_board), - .num_names = ARRAY_SIZE(pcmmio_boards), }; module_comedi_driver(pcmmio_driver); -- cgit v1.2.3 From 43fc365f2418b995aef11ca1281399c981448718 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Oct 2012 10:44:10 -0700 Subject: staging: comedi: pcmda12: remove boardinfo This driver only supports a single "boardtype". Remove the unneeded boardinfo struct and its use in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcmda12.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index 28af8f6873e..f2984f15506 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -64,13 +64,6 @@ Configuration Options: #define MSB_PORT(chan) (LSB_PORT(chan)+1) #define BITS 12 -/* - * Bords - */ -struct pcmda12_board { - const char *name; -}; - /* note these have no effect and are merely here for reference.. these are configured by jumpering the board! */ static const struct comedi_lrange pcmda12_ranges = { @@ -162,7 +155,6 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int pcmda12_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct pcmda12_board *board = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase; int ret; @@ -178,7 +170,7 @@ static int pcmda12_attach(struct comedi_device *dev, } dev->iobase = iobase; - dev->board_name = board->name; + dev->board_name = dev->driver->driver_name; /* * Allocate the private structure area. alloc_private() is a @@ -218,20 +210,11 @@ static void pcmda12_detach(struct comedi_device *dev) release_region(dev->iobase, IOSIZE); } -static const struct pcmda12_board pcmda12_boards[] = { - { - .name = "pcmda12", - }, -}; - static struct comedi_driver pcmda12_driver = { .driver_name = "pcmda12", .module = THIS_MODULE, .attach = pcmda12_attach, .detach = pcmda12_detach, - .board_name = &pcmda12_boards[0].name, - .offset = sizeof(struct pcmda12_board), - .num_names = ARRAY_SIZE(pcmda12_boards), }; module_comedi_driver(pcmda12_driver); -- cgit v1.2.3 From 5f1514bfd2ffa5e4333c037378a0b0d8db79ce23 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Oct 2012 10:44:55 -0700 Subject: staging: comedi: pcm3724: remove boardinfo This driver only supports a single "boardtype". Remove the unneeded boardinfo struct and its use in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcm3724.c | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index 4102547dc6a..cbb344a0f72 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -62,14 +62,6 @@ Copy/pasted/hacked from pcm724.c #define CR_A_MODE(a) ((a)<<5) #define CR_CW 0x80 -struct pcm3724_board { - const char *name; /* driver name */ - int dio; /* num of DIO */ - int numofports; /* num of 8255 subdevices */ - unsigned int IRQbits; /* allowed interrupts */ - unsigned int io_range; /* len of IO space */ -}; - /* used to track configured dios */ struct priv_pcm3724 { int dio_1; @@ -233,14 +225,15 @@ static int subdev_3724_insn_config(struct comedi_device *dev, static int pcm3724_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct pcm3724_board *board = comedi_board(dev); struct comedi_subdevice *s; unsigned long iobase; unsigned int iorange; - int ret, i, n_subdevices; + int ret, i; + + dev->board_name = dev->driver->driver_name; iobase = it->options[0]; - iorange = board->io_range; + iorange = PCM3724_SIZE; ret = alloc_private(dev, sizeof(struct priv_pcm3724)); if (ret < 0) @@ -250,19 +243,16 @@ static int pcm3724_attach(struct comedi_device *dev, ((struct priv_pcm3724 *)(dev->private))->dio_2 = 0; printk(KERN_INFO "comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor, - board->name, iobase); + dev->board_name, iobase); if (!iobase || !request_region(iobase, iorange, "pcm3724")) { printk("I/O port conflict\n"); return -EIO; } dev->iobase = iobase; - dev->board_name = board->name; printk(KERN_INFO "\n"); - n_subdevices = board->numofports; - - ret = comedi_alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; @@ -277,7 +267,6 @@ static int pcm3724_attach(struct comedi_device *dev, static void pcm3724_detach(struct comedi_device *dev) { - const struct pcm3724_board *board = comedi_board(dev); struct comedi_subdevice *s; int i; @@ -288,21 +277,14 @@ static void pcm3724_detach(struct comedi_device *dev) } } if (dev->iobase) - release_region(dev->iobase, board->io_range); + release_region(dev->iobase, PCM3724_SIZE); } -static const struct pcm3724_board boardtypes[] = { - { "pcm3724", 48, 2, 0x00fc, PCM3724_SIZE, }, -}; - static struct comedi_driver pcm3724_driver = { .driver_name = "pcm3724", .module = THIS_MODULE, .attach = pcm3724_attach, .detach = pcm3724_detach, - .board_name = &boardtypes[0].name, - .num_names = ARRAY_SIZE(boardtypes), - .offset = sizeof(struct pcm3724_board), }; module_comedi_driver(pcm3724_driver); -- cgit v1.2.3 From c937876787c4f7aaca421fbb07d0e763e70ff6fa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Oct 2012 10:45:22 -0700 Subject: staging: comedi: ke_counter: remove boardinfo This driver only supports a single "boardtype". Remove the unneeded boardinfo struct and its use in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ke_counter.c | 44 ++--------------------------- 1 file changed, 3 insertions(+), 41 deletions(-) diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index e867b720f66..8e37cff1bd8 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -36,28 +36,9 @@ Kolter Electronic PCI Counter Card. #include "../comedidev.h" -#define CNT_DRIVER_NAME "ke_counter" #define PCI_VENDOR_ID_KOLTER 0x1001 #define CNT_CARD_DEVICE_ID 0x0014 -/*-- board specification structure ------------------------------------------*/ - -struct cnt_board_struct { - - const char *name; - int device_id; - int cnt_channel_nbr; - int cnt_bits; -}; - -static const struct cnt_board_struct cnt_boards[] = { - { - .name = CNT_DRIVER_NAME, - .device_id = CNT_CARD_DEVICE_ID, - .cnt_channel_nbr = 3, - .cnt_bits = 24} -}; - /*-- counter write ----------------------------------------------------------*/ /* This should be used only for resetting the counters; maybe it is better @@ -107,34 +88,15 @@ static int cnt_rinsn(struct comedi_device *dev, return 1; } -static const void *cnt_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct cnt_board_struct *board; - int i; - - for (i = 0; i < ARRAY_SIZE(cnt_boards); i++) { - board = &cnt_boards[i]; - if (board->device_id == pcidev->device) - return board; - } - return NULL; -} - static int cnt_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { - const struct cnt_board_struct *board; struct comedi_subdevice *s; int ret; comedi_set_hw_dev(dev, &pcidev->dev); - board = cnt_find_boardinfo(dev, pcidev); - if (!board) - return -ENODEV; - dev->board_ptr = board; - dev->board_name = board->name; + dev->board_name = dev->driver->driver_name; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -150,8 +112,8 @@ static int cnt_attach_pci(struct comedi_device *dev, s->type = COMEDI_SUBD_COUNTER; s->subdev_flags = SDF_READABLE /* | SDF_COMMON */ ; - s->n_chan = board->cnt_channel_nbr; - s->maxdata = (1 << board->cnt_bits) - 1; + s->n_chan = 3; + s->maxdata = 0x00ffffff; s->insn_read = cnt_rinsn; s->insn_write = cnt_winsn; -- cgit v1.2.3 From 4e9cd21340a11240ca4ff8a437e6442bc8fc90eb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Oct 2012 10:45:47 -0700 Subject: staging: comedi: dmm32at: remove boardinfo This driver only supports a single "boardtype". Remove the unneeded boardinfo struct and its use in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dmm32at.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 4d5c33c4750..824b692db5f 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -158,10 +158,6 @@ static const struct comedi_lrange dmm32at_aoranges = { } }; -struct dmm32at_board { - const char *name; -}; - struct dmm32at_private { int data; @@ -718,7 +714,6 @@ static int dmm32at_dio_insn_config(struct comedi_device *dev, static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct dmm32at_board *board = comedi_board(dev); struct dmm32at_private *devpriv; int ret; struct comedi_subdevice *s; @@ -726,6 +721,8 @@ static int dmm32at_attach(struct comedi_device *dev, unsigned long iobase; unsigned int irq; + dev->board_name = dev->driver->driver_name; + iobase = it->options[0]; irq = it->options[1]; @@ -734,7 +731,7 @@ static int dmm32at_attach(struct comedi_device *dev, iobase, irq); /* register address space */ - if (!request_region(iobase, DMM32AT_MEMSIZE, board->name)) { + if (!request_region(iobase, DMM32AT_MEMSIZE, dev->board_name)) { printk(KERN_ERR "comedi%d: dmm32at: I/O port conflict\n", dev->minor); return -EIO; @@ -788,7 +785,7 @@ static int dmm32at_attach(struct comedi_device *dev, /* board is there, register interrupt */ if (irq) { - ret = request_irq(irq, dmm32at_isr, 0, board->name, dev); + ret = request_irq(irq, dmm32at_isr, 0, dev->board_name, dev); if (ret < 0) { printk(KERN_ERR "dmm32at: irq conflict\n"); return ret; @@ -796,8 +793,6 @@ static int dmm32at_attach(struct comedi_device *dev, dev->irq = irq; } - dev->board_name = board->name; - if (alloc_private(dev, sizeof(*devpriv)) < 0) return -ENOMEM; devpriv = dev->private; @@ -867,20 +862,11 @@ static void dmm32at_detach(struct comedi_device *dev) release_region(dev->iobase, DMM32AT_MEMSIZE); } -static const struct dmm32at_board dmm32at_boards[] = { - { - .name = "dmm32at", - }, -}; - static struct comedi_driver dmm32at_driver = { .driver_name = "dmm32at", .module = THIS_MODULE, .attach = dmm32at_attach, .detach = dmm32at_detach, - .board_name = &dmm32at_boards[0].name, - .offset = sizeof(struct dmm32at_board), - .num_names = ARRAY_SIZE(dmm32at_boards), }; module_comedi_driver(dmm32at_driver); -- cgit v1.2.3 From 34702518a62dce8df67cdc3902788b80d6ed401c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Oct 2012 10:46:12 -0700 Subject: staging: comedi: das16m1: remove boardinfo This driver only supports a single "boardtype". Remove the unneeded boardinfo struct and its use in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16m1.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index 3f87d7598e5..c43172750ab 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -28,7 +28,7 @@ Driver: das16m1 Description: CIO-DAS16/M1 Author: Frank Mori Hess -Devices: [Measurement Computing] CIO-DAS16/M1 (cio-das16/m1) +Devices: [Measurement Computing] CIO-DAS16/M1 (das16m1) Status: works This driver supports a single board - the CIO-DAS16/M1. @@ -132,11 +132,6 @@ static const struct comedi_lrange range_das16m1 = { 9, } }; -struct das16m1_board { - const char *name; - unsigned int ai_speed; -}; - struct das16m1_private_struct { unsigned int control_state; volatile unsigned int adc_count; /* number of samples completed */ @@ -167,7 +162,6 @@ static void munge_sample_array(short *array, unsigned int num_elements) static int das16m1_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - const struct das16m1_board *board = comedi_board(dev); unsigned int err = 0, tmp, i; /* Step 1 : check if triggers are trivially valid */ @@ -207,8 +201,8 @@ static int das16m1_cmd_test(struct comedi_device *dev, } if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < board->ai_speed) { - cmd->convert_arg = board->ai_speed; + if (cmd->convert_arg < 1000) { + cmd->convert_arg = 1000; err++; } } @@ -582,26 +576,25 @@ static int das16m1_irq_bits(unsigned int irq) static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct das16m1_board *board = comedi_board(dev); struct comedi_subdevice *s; int ret; unsigned int irq; unsigned long iobase; + dev->board_name = dev->driver->driver_name; + iobase = it->options[0]; ret = alloc_private(dev, sizeof(struct das16m1_private_struct)); if (ret < 0) return ret; - dev->board_name = board->name; - - if (!request_region(iobase, DAS16M1_SIZE, dev->driver->driver_name)) { + if (!request_region(iobase, DAS16M1_SIZE, dev->board_name)) { comedi_error(dev, "I/O port conflict\n"); return -EIO; } if (!request_region(iobase + DAS16M1_82C55, DAS16M1_SIZE2, - dev->driver->driver_name)) { + dev->board_name)) { release_region(iobase, DAS16M1_SIZE); comedi_error(dev, "I/O port conflict\n"); return -EIO; @@ -698,21 +691,11 @@ static void das16m1_detach(struct comedi_device *dev) } } -static const struct das16m1_board das16m1_boards[] = { - { - .name = "cio-das16/m1", /* CIO-DAS16_M1.pdf */ - .ai_speed = 1000, /* 1MHz max speed */ - }, -}; - static struct comedi_driver das16m1_driver = { .driver_name = "das16m1", .module = THIS_MODULE, .attach = das16m1_attach, .detach = das16m1_detach, - .board_name = &das16m1_boards[0].name, - .num_names = ARRAY_SIZE(das16m1_boards), - .offset = sizeof(das16m1_boards[0]), }; module_comedi_driver(das16m1_driver); -- cgit v1.2.3 From 0f90460479d45f7abbe985ea470edb25e46e2ef9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Oct 2012 10:46:45 -0700 Subject: staging: comedi: cb_pcimdas: remove boardinfo This driver only supports a single "boardtype". Remove the unneeded boardinfo struct and its use in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcimdas.c | 94 +++-------------------------- 1 file changed, 9 insertions(+), 85 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 9515b692666..d1c7220c0b7 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -80,44 +80,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. #define RESID_COUNT_H 13 #define RESID_COUNT_L 14 -/* Board description */ -struct cb_pcimdas_board { - const char *name; - unsigned short device_id; - int ai_se_chans; /* Inputs in single-ended mode */ - int ai_diff_chans; /* Inputs in differential mode */ - int ai_bits; /* analog input resolution */ - int ai_speed; /* fastest conversion period in ns */ - int ao_nchan; /* number of analog out channels */ - int ao_bits; /* analogue output resolution */ - int has_ao_fifo; /* analog output has fifo */ - int ao_scan_speed; /* analog output speed for 1602 series (for a scan, not conversion) */ - int fifo_size; /* number of samples fifo can hold */ - int dio_bits; /* number of dio bits */ - int has_dio; /* has DIO */ - const struct comedi_lrange *ranges; -}; - -static const struct cb_pcimdas_board cb_pcimdas_boards[] = { - { - .name = "PCIM-DAS1602/16", - .device_id = 0x56, - .ai_se_chans = 16, - .ai_diff_chans = 8, - .ai_bits = 16, - .ai_speed = 10000, /* ?? */ - .ao_nchan = 2, - .ao_bits = 12, - .has_ao_fifo = 0, /* ?? */ - .ao_scan_speed = 10000, - /* ?? */ - .fifo_size = 1024, - .dio_bits = 24, - .has_dio = 1, -/* .ranges = &cb_pcimdas_ranges, */ - }, -}; - /* * this structure is for data unique to this hardware driver. If * several hardware drivers keep similar information in this structure, @@ -140,7 +102,6 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - const struct cb_pcimdas_board *thisboard = comedi_board(dev); struct cb_pcimdas_private *devpriv = dev->private; int n, i; unsigned int d; @@ -153,9 +114,9 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, /* check channel number */ if ((inb(devpriv->BADR3 + 2) & 0x20) == 0) /* differential mode */ - maxchans = thisboard->ai_diff_chans; + maxchans = s->n_chan / 2; else - maxchans = thisboard->ai_se_chans; + maxchans = s->n_chan; if (chan > (maxchans - 1)) return -ETIMEDOUT; /* *** Wrong error code. Fixme. */ @@ -195,12 +156,7 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, return -ETIMEDOUT; } /* read data */ - d = inw(dev->iobase + 0); - - /* mangle the data as necessary */ - /* d ^= 1<<(thisboard->ai_bits-1); // 16 bit data from ADC, so no mangle needed. */ - - data[n] = d; + data[n] = inw(dev->iobase + 0); } /* return the number of samples read/written */ @@ -251,24 +207,9 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, return i; } -static const void *cb_pcimdas_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const struct cb_pcimdas_board *thisboard; - int i; - - for (i = 0; i < ARRAY_SIZE(cb_pcimdas_boards); i++) { - thisboard = &cb_pcimdas_boards[i]; - if (thisboard->device_id == pcidev->device) - return thisboard; - } - return NULL; -} - static int cb_pcimdas_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { - const struct cb_pcimdas_board *thisboard; struct cb_pcimdas_private *devpriv; struct comedi_subdevice *s; unsigned long iobase_8255; @@ -276,27 +217,13 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev, comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = cb_pcimdas_find_boardinfo(dev, pcidev); - if (!thisboard) - return -ENODEV; - dev->board_ptr = thisboard; - dev->board_name = thisboard->name; + dev->board_name = dev->driver->driver_name; ret = alloc_private(dev, sizeof(*devpriv)); if (ret) return ret; devpriv = dev->private; - /* Warn about non-tested features */ - switch (thisboard->device_id) { - case 0x56: - break; - default: - dev_dbg(dev->class_dev, "THIS CARD IS UNSUPPORTED.\n"); - dev_dbg(dev->class_dev, - "PLEASE REPORT USAGE TO \n"); - } - ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; @@ -323,8 +250,8 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev, /* analog input subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND; - s->n_chan = thisboard->ai_se_chans; - s->maxdata = (1 << thisboard->ai_bits) - 1; + s->n_chan = 16; + s->maxdata = 0xffff; s->range_table = &range_unknown; s->len_chanlist = 1; /* This is the maximum chanlist length that */ /* the board can handle */ @@ -334,8 +261,8 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev, /* analog output subdevice */ s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->ao_nchan; - s->maxdata = 1 << thisboard->ao_bits; + s->n_chan = 2; + s->maxdata = 0xfff; /* ranges are hardware settable, but not software readable. */ s->range_table = &range_unknown; s->insn_write = &cb_pcimdas_ao_winsn; @@ -343,10 +270,7 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev, s = &dev->subdevices[2]; /* digital i/o subdevice */ - if (thisboard->has_dio) - subdev_8255_init(dev, s, NULL, iobase_8255); - else - s->type = COMEDI_SUBD_UNUSED; + subdev_8255_init(dev, s, NULL, iobase_8255); dev_info(dev->class_dev, "%s attached\n", dev->board_name); -- cgit v1.2.3 From bee1ef89723595cf3202525c45d40d259465ff3b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Oct 2012 10:47:24 -0700 Subject: staging: comedi: aio_iiro_16: remove boardinfo This driver only supports a single "boardtype". Remove the unneeded boardinfo struct and its use in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/aio_iiro_16.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c index b2cb8b02b2a..64c1ae58ce7 100644 --- a/drivers/staging/comedi/drivers/aio_iiro_16.c +++ b/drivers/staging/comedi/drivers/aio_iiro_16.c @@ -44,19 +44,6 @@ Configuration Options: #define AIO_IIRO_16_RELAY_8_15 0x04 #define AIO_IIRO_16_INPUT_8_15 0x05 -struct aio_iiro_16_board { - const char *name; - int do_; - int di; -}; - -static const struct aio_iiro_16_board aio_iiro_16_boards[] = { - { - .name = "aio_iiro_16", - .di = 16, - .do_ = 16}, -}; - static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -90,14 +77,13 @@ static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev, static int aio_iiro_16_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct aio_iiro_16_board *board = comedi_board(dev); int iobase; struct comedi_subdevice *s; int ret; printk(KERN_INFO "comedi%d: aio_iiro_16: ", dev->minor); - dev->board_name = board->name; + dev->board_name = dev->driver->driver_name; iobase = it->options[0]; @@ -144,9 +130,6 @@ static struct comedi_driver aio_iiro_16_driver = { .module = THIS_MODULE, .attach = aio_iiro_16_attach, .detach = aio_iiro_16_detach, - .board_name = &aio_iiro_16_boards[0].name, - .offset = sizeof(struct aio_iiro_16_board), - .num_names = ARRAY_SIZE(aio_iiro_16_boards), }; module_comedi_driver(aio_iiro_16_driver); -- cgit v1.2.3 From 7195ea042cc2021a76bb83057850b703dc921ebb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 8 Oct 2012 10:47:49 -0700 Subject: staging: comedi: adq12b: remove boardinfo This driver only supports a single "boardtype". Remove the unneeded boardinfo struct and its use in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adq12b.c | 38 ++++++--------------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index 3a2aa5628be..bdc5ebce877 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -116,15 +116,6 @@ static const struct comedi_lrange range_adq12b_ai_unipolar = { 4, { } }; -struct adq12b_board { - const char *name; - int ai_se_chans; - int ai_diff_chans; - int ai_bits; - int di_chans; - int do_chans; -}; - struct adq12b_private { int unipolar; /* option 2 of comedi_config (1 is iobase) */ int differential; /* option 3 of comedi_config */ @@ -220,13 +211,14 @@ static int adq12b_do_insn_bits(struct comedi_device *dev, static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct adq12b_board *board = comedi_board(dev); struct adq12b_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; int unipolar, differential; int ret; + dev->board_name = dev->driver->driver_name; + iobase = it->options[0]; unipolar = it->options[1]; differential = it->options[2]; @@ -251,8 +243,6 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - dev->board_name = board->name; - ret = alloc_private(dev, sizeof(*devpriv)); if (ret) return ret; @@ -277,10 +267,10 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_AI; if (differential) { s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; - s->n_chan = board->ai_diff_chans; + s->n_chan = 8; } else { s->subdev_flags = SDF_READABLE | SDF_GROUND; - s->n_chan = board->ai_se_chans; + s->n_chan = 16; } if (unipolar) @@ -288,7 +278,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) else s->range_table = &range_adq12b_ai_bipolar; - s->maxdata = (1 << board->ai_bits) - 1; + s->maxdata = 0xfff; s->len_chanlist = 4; /* This is the maximum chanlist length that the board can handle */ @@ -298,7 +288,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* digital input subdevice */ s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; - s->n_chan = board->di_chans; + s->n_chan = 5; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = adq12b_di_insn_bits; @@ -307,7 +297,7 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* digital output subdevice */ s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = board->do_chans; + s->n_chan = 8; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = adq12b_do_insn_bits; @@ -323,25 +313,11 @@ static void adq12b_detach(struct comedi_device *dev) release_region(dev->iobase, ADQ12B_SIZE); } -static const struct adq12b_board adq12b_boards[] = { - { - .name = "adq12b", - .ai_se_chans = 16, - .ai_diff_chans = 8, - .ai_bits = 12, - .di_chans = 5, - .do_chans = 8, - }, -}; - static struct comedi_driver adq12b_driver = { .driver_name = "adq12b", .module = THIS_MODULE, .attach = adq12b_attach, .detach = adq12b_detach, - .board_name = &adq12b_boards[0].name, - .offset = sizeof(struct adq12b_board), - .num_names = ARRAY_SIZE(adq12b_boards), }; module_comedi_driver(adq12b_driver); -- cgit v1.2.3 From 95b24682d6a7e584f69615e36ee304caba20e38f Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 15 Oct 2012 12:20:00 +0100 Subject: staging: comedi: jr3_pci: add __iomem tags Tag pointers to remapped I/O memory with `__iomem` and remove the `volatile` qualifiers. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/jr3_pci.c | 30 +++++++++++++++--------------- drivers/staging/comedi/drivers/jr3_pci.h | 12 ++++++------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 4a108ea8a9a..a5ab490571b 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -62,7 +62,7 @@ struct jr3_pci_dev_private { struct pci_dev *pci_dev; int pci_enabled; - volatile struct jr3_t *iobase; + struct jr3_t __iomem *iobase; int n_channels; struct timer_list timer; }; @@ -74,7 +74,7 @@ struct poll_delay_t { }; struct jr3_pci_subdev_private { - volatile struct jr3_channel *channel; + struct jr3_channel __iomem *channel; unsigned long next_time_min; unsigned long next_time_max; enum { state_jr3_poll, @@ -138,7 +138,7 @@ static struct poll_delay_t poll_delay_min_max(int min, int max) return result; } -static int is_complete(volatile struct jr3_channel *channel) +static int is_complete(struct jr3_channel __iomem *channel) { return get_s16(&channel->command_word0) == 0; } @@ -150,7 +150,7 @@ struct transform_t { } link[8]; }; -static void set_transforms(volatile struct jr3_channel *channel, +static void set_transforms(struct jr3_channel __iomem *channel, struct transform_t transf, short num) { int i; @@ -169,18 +169,18 @@ static void set_transforms(volatile struct jr3_channel *channel, } } -static void use_transform(volatile struct jr3_channel *channel, +static void use_transform(struct jr3_channel __iomem *channel, short transf_num) { set_s16(&channel->command_word0, 0x0500 + (transf_num & 0x000f)); } -static void use_offset(volatile struct jr3_channel *channel, short offset_num) +static void use_offset(struct jr3_channel __iomem *channel, short offset_num) { set_s16(&channel->command_word0, 0x0600 + (offset_num & 0x000f)); } -static void set_offset(volatile struct jr3_channel *channel) +static void set_offset(struct jr3_channel __iomem *channel) { set_s16(&channel->command_word0, 0x0700); } @@ -194,7 +194,7 @@ struct six_axis_t { s16 mz; }; -static void set_full_scales(volatile struct jr3_channel *channel, +static void set_full_scales(struct jr3_channel __iomem *channel, struct six_axis_t full_scale) { printk("%d %d %d %d %d %d\n", @@ -210,7 +210,7 @@ static void set_full_scales(volatile struct jr3_channel *channel, set_s16(&channel->command_word0, 0x0a00); } -static struct six_axis_t get_min_full_scales(volatile struct jr3_channel +static struct six_axis_t get_min_full_scales(struct jr3_channel __iomem *channel) { struct six_axis_t result; @@ -223,7 +223,7 @@ static struct six_axis_t get_min_full_scales(volatile struct jr3_channel return result; } -static struct six_axis_t get_max_full_scales(volatile struct jr3_channel +static struct six_axis_t get_max_full_scales(struct jr3_channel __iomem *channel) { struct six_axis_t result; @@ -492,7 +492,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s) int i; if (p) { - volatile struct jr3_channel *channel = p->channel; + struct jr3_channel __iomem *channel = p->channel; int errors = get_u16(&channel->errors); if (errors != p->errors) { @@ -607,7 +607,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s) is_complete(channel)); result = poll_delay_min_max(20, 100); } else { - volatile struct force_array *full_scale; + struct force_array __iomem *full_scale; /* Use ranges in kN or we will overflow arount 2000N! */ full_scale = &channel->full_scale; @@ -849,8 +849,8 @@ static int jr3_pci_attach(struct comedi_device *dev, p->channel = &devpriv->iobase->channel[i].data; dev_dbg(dev->class_dev, "p->channel %p %p (%tx)\n", p->channel, devpriv->iobase, - ((char *)(p->channel) - - (char *)(devpriv->iobase))); + ((char __iomem *)p->channel - + (char __iomem *)devpriv->iobase)); p->channel_no = i; for (j = 0; j < 8; j++) { int k; @@ -941,7 +941,7 @@ static void jr3_pci_detach(struct comedi_device *dev) kfree(dev->subdevices[i].private); } if (devpriv->iobase) - iounmap((void *)devpriv->iobase); + iounmap(devpriv->iobase); if (devpriv->pci_enabled) comedi_pci_disable(devpriv->pci_dev); if (devpriv->pci_dev) diff --git a/drivers/staging/comedi/drivers/jr3_pci.h b/drivers/staging/comedi/drivers/jr3_pci.h index 9c42653d8f1..3317f7a04c4 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.h +++ b/drivers/staging/comedi/drivers/jr3_pci.h @@ -2,22 +2,22 @@ * is 16 bits, but aligned on a 32 bit PCI boundary */ -static inline u16 get_u16(volatile const u32 * p) +static inline u16 get_u16(const u32 __iomem *p) { - return (u16) readl(p); + return (u16)readl(p); } -static inline void set_u16(volatile u32 * p, u16 val) +static inline void set_u16(u32 __iomem *p, u16 val) { writel(val, p); } -static inline s16 get_s16(volatile const s32 * p) +static inline s16 get_s16(const s32 __iomem *p) { - return (s16) readl(p); + return (s16)readl(p); } -static inline void set_s16(volatile s32 * p, s16 val) +static inline void set_s16(s32 __iomem *p, s16 val) { writel(val, p); } -- cgit v1.2.3 From b776d05b9307972f079b56b6cbf74349a6451a53 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 15 Oct 2012 11:58:34 +0100 Subject: staging: comedi: gsc_hpdi: make internal functions static This module does not export any symbols so declare all the functions as `static` and remove the unused ones. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 87 ++----------------------------- 1 file changed, 5 insertions(+), 82 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index abff6603952..517ba3a40fe 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -104,35 +104,11 @@ enum hpdi_registers { INTERRUPT_POLARITY_REG = 0x54, }; -int command_channel_valid(unsigned int channel) -{ - if (channel == 0 || channel > 6) { - printk(KERN_WARNING - "gsc_hpdi: bug! invalid cable command channel\n"); - return 0; - } - return 1; -} - /* bit definitions */ enum firmware_revision_bits { FEATURES_REG_PRESENT_BIT = 0x8000, }; -int firmware_revision(uint32_t fwr_bits) -{ - return fwr_bits & 0xff; -} - -int pcb_revision(uint32_t fwr_bits) -{ - return (fwr_bits >> 8) & 0xff; -} - -int hpdi_subid(uint32_t fwr_bits) -{ - return (fwr_bits >> 16) & 0xff; -} enum board_control_bits { BOARD_RESET_BIT = 0x1, /* wait 10usec before accessing fifos */ @@ -147,22 +123,6 @@ enum board_control_bits { CABLE_THROTTLE_ENABLE_BIT = 0x20, TEST_MODE_ENABLE_BIT = 0x80000000, }; -uint32_t command_discrete_output_bits(unsigned int channel, int output, - int output_value) -{ - uint32_t bits = 0; - - if (command_channel_valid(channel) == 0) - return 0; - if (output) { - bits |= 0x1 << (16 + channel); - if (output_value) - bits |= 0x1 << (24 + channel); - } else - bits |= 0x1 << (24 + channel); - - return bits; -} enum board_status_bits { COMMAND_LINE_STATUS_MASK = 0x7f, @@ -182,28 +142,17 @@ enum board_status_bits { RX_OVERRUN_BIT = 0x800000, }; -uint32_t almost_full_bits(unsigned int num_words) +static uint32_t almost_full_bits(unsigned int num_words) { -/* XXX need to add or subtract one? */ + /* XXX need to add or subtract one? */ return (num_words << 16) & 0xff0000; } -uint32_t almost_empty_bits(unsigned int num_words) +static uint32_t almost_empty_bits(unsigned int num_words) { return num_words & 0xffff; } -unsigned int almost_full_num_words(uint32_t bits) -{ -/* XXX need to add or subtract one? */ - return (bits >> 16) & 0xffff; -} - -unsigned int almost_empty_num_words(uint32_t bits) -{ - return bits & 0xffff; -} - enum features_bits { FIFO_SIZE_PRESENT_BIT = 0x1, FIFO_WORDS_PRESENT_BIT = 0x2, @@ -225,43 +174,17 @@ enum interrupt_sources { RX_ALMOST_FULL_INTR = 14, RX_FULL_INTR = 15, }; -int command_intr_source(unsigned int channel) -{ - if (command_channel_valid(channel) == 0) - channel = 1; - return channel + 1; -} -uint32_t intr_bit(int interrupt_source) +static uint32_t intr_bit(int interrupt_source) { return 0x1 << interrupt_source; } -uint32_t tx_clock_divisor_bits(unsigned int divisor) -{ - return divisor & 0xff; -} - -unsigned int fifo_size(uint32_t fifo_size_bits) +static unsigned int fifo_size(uint32_t fifo_size_bits) { return fifo_size_bits & 0xfffff; } -unsigned int fifo_words(uint32_t fifo_words_bits) -{ - return fifo_words_bits & 0xfffff; -} - -uint32_t intr_edge_bit(int interrupt_source) -{ - return 0x1 << interrupt_source; -} - -uint32_t intr_active_high_bit(int interrupt_source) -{ - return 0x1 << interrupt_source; -} - struct hpdi_board { char *name; -- cgit v1.2.3 From 681d335ab5819a5cca8b74bea06f2804d2cb5a81 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 15 Oct 2012 10:13:12 -0700 Subject: staging: comedi: cb_pcidas64: remove inline priv() function The inline priv() function simply returns the dev->private pointer to the private data. Remove the inline funciton and just use a local variable where the private data is used. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 877 ++++++++++++++------------- 1 file changed, 466 insertions(+), 411 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 0472a9088ab..08546a1091a 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -119,7 +119,7 @@ enum base_address_regions { DIO_COUNTER_BADDRINDEX = 3, }; -/* priv(dev)->main_iobase registers */ +/* devpriv->main_iobase registers */ enum write_only_registers { INTR_ENABLE_REG = 0x0, /* interrupt enable register */ HW_CONFIG_REG = 0x2, /* hardware config register */ @@ -179,7 +179,7 @@ enum read_write_registers { DAC_FIFO_REG = 0x300, /* dac data fifo, has weird interactions with external channel queue */ }; -/* priv(dev)->dio_counter_iobase registers */ +/* devpriv->dio_counter_iobase registers */ enum dio_counter_registers { DIO_8255_OFFSET = 0x0, DO_REG = 0x20, @@ -1091,14 +1091,6 @@ struct pcidas64_private { short ao_bounce_buffer[DAC_FIFO_SIZE]; }; -/* inline function that makes it easier to - * access the private structure. - */ -static inline struct pcidas64_private *priv(struct comedi_device *dev) -{ - return dev->private; -} - static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data); static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, @@ -1249,17 +1241,18 @@ static inline int ao_cmd_is_supported(const struct pcidas64_board *board) /* initialize plx9080 chip */ static void init_plx9080(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; uint32_t bits; - void __iomem *plx_iobase = priv(dev)->plx9080_iobase; + void __iomem *plx_iobase = devpriv->plx9080_iobase; - priv(dev)->plx_control_bits = - readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG); + devpriv->plx_control_bits = + readl(devpriv->plx9080_iobase + PLX_CONTROL_REG); /* plx9080 dump */ DEBUG_PRINT(" plx interrupt status 0x%x\n", readl(plx_iobase + PLX_INTRCS_REG)); DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG)); - DEBUG_PRINT(" plx control reg 0x%x\n", priv(dev)->plx_control_bits); + DEBUG_PRINT(" plx control reg 0x%x\n", devpriv->plx_control_bits); DEBUG_PRINT(" plx mode/arbitration reg 0x%x\n", readl(plx_iobase + PLX_MARB_REG)); DEBUG_PRINT(" plx region0 reg 0x%x\n", @@ -1292,7 +1285,7 @@ static void init_plx9080(struct comedi_device *dev) #else bits = 0; #endif - writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG); + writel(bits, devpriv->plx9080_iobase + PLX_BIGEND_REG); disable_plx_interrupts(dev); @@ -1328,17 +1321,18 @@ static void init_plx9080(struct comedi_device *dev) writel(bits, plx_iobase + PLX_DMA0_MODE_REG); /* enable interrupts on plx 9080 */ - priv(dev)->plx_intcsr_bits |= + devpriv->plx_intcsr_bits |= ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE | ICS_DMA0_E | ICS_DMA1_E; - writel(priv(dev)->plx_intcsr_bits, - priv(dev)->plx9080_iobase + PLX_INTRCS_REG); + writel(devpriv->plx_intcsr_bits, + devpriv->plx9080_iobase + PLX_INTRCS_REG); } /* Allocate and initialize the subdevice structures. */ static int setup_subdevices(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s; void __iomem *dio_8255_iobase; int i; @@ -1370,11 +1364,11 @@ static int setup_subdevices(struct comedi_device *dev) if (board(dev)->layout == LAYOUT_4020) { uint8_t data; /* set adc to read from inputs (not internal calibration sources) */ - priv(dev)->i2c_cal_range_bits = adc_src_4020_bits(4); + devpriv->i2c_cal_range_bits = adc_src_4020_bits(4); /* set channels to +-5 volt input ranges */ for (i = 0; i < s->n_chan; i++) - priv(dev)->i2c_cal_range_bits |= attenuate_bit(i); - data = priv(dev)->i2c_cal_range_bits; + devpriv->i2c_cal_range_bits |= attenuate_bit(i); + data = devpriv->i2c_cal_range_bits; i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data)); } @@ -1429,12 +1423,12 @@ static int setup_subdevices(struct comedi_device *dev) if (board(dev)->has_8255) { if (board(dev)->layout == LAYOUT_4020) { dio_8255_iobase = - priv(dev)->main_iobase + I8255_4020_REG; + devpriv->main_iobase + I8255_4020_REG; subdev_8255_init(dev, s, dio_callback_4020, (unsigned long)dio_8255_iobase); } else { dio_8255_iobase = - priv(dev)->dio_counter_iobase + DIO_8255_OFFSET; + devpriv->dio_counter_iobase + DIO_8255_OFFSET; subdev_8255_init(dev, s, dio_callback, (unsigned long)dio_8255_iobase); } @@ -1484,7 +1478,7 @@ static int setup_subdevices(struct comedi_device *dev) /* serial EEPROM, if present */ s = &dev->subdevices[8]; - if (readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) { + if (readl(devpriv->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) { s->type = COMEDI_SUBD_MEMORY; s->subdev_flags = SDF_READABLE | SDF_INTERNAL; s->n_chan = 128; @@ -1502,13 +1496,16 @@ static int setup_subdevices(struct comedi_device *dev) static void disable_plx_interrupts(struct comedi_device *dev) { - priv(dev)->plx_intcsr_bits = 0; - writel(priv(dev)->plx_intcsr_bits, - priv(dev)->plx9080_iobase + PLX_INTRCS_REG); + struct pcidas64_private *devpriv = dev->private; + + devpriv->plx_intcsr_bits = 0; + writel(devpriv->plx_intcsr_bits, + devpriv->plx9080_iobase + PLX_INTRCS_REG); } static void init_stc_registers(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; uint16_t bits; unsigned long flags; @@ -1516,35 +1513,35 @@ static void init_stc_registers(struct comedi_device *dev) /* bit should be set for 6025, although docs say boards with <= 16 chans should be cleared XXX */ if (1) - priv(dev)->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT; - writew(priv(dev)->adc_control1_bits, - priv(dev)->main_iobase + ADC_CONTROL1_REG); + devpriv->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT; + writew(devpriv->adc_control1_bits, + devpriv->main_iobase + ADC_CONTROL1_REG); /* 6402/16 manual says this register must be initialized to 0xff? */ - writew(0xff, priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); + writew(0xff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT; if (board(dev)->layout == LAYOUT_4020) bits |= INTERNAL_CLOCK_4020_BITS; - priv(dev)->hw_config_bits |= bits; - writew(priv(dev)->hw_config_bits, - priv(dev)->main_iobase + HW_CONFIG_REG); + devpriv->hw_config_bits |= bits; + writew(devpriv->hw_config_bits, + devpriv->main_iobase + HW_CONFIG_REG); - writew(0, priv(dev)->main_iobase + DAQ_SYNC_REG); - writew(0, priv(dev)->main_iobase + CALIBRATION_REG); + writew(0, devpriv->main_iobase + DAQ_SYNC_REG); + writew(0, devpriv->main_iobase + CALIBRATION_REG); spin_unlock_irqrestore(&dev->spinlock, flags); /* set fifos to maximum size */ - priv(dev)->fifo_size_bits |= DAC_FIFO_BITS; + devpriv->fifo_size_bits |= DAC_FIFO_BITS; set_ai_fifo_segment_length(dev, board(dev)->ai_fifo->max_segment_length); - priv(dev)->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT; - priv(dev)->intr_enable_bits = /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */ + devpriv->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT; + devpriv->intr_enable_bits = /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */ EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT; - writew(priv(dev)->intr_enable_bits, - priv(dev)->main_iobase + INTR_ENABLE_REG); + writew(devpriv->intr_enable_bits, + devpriv->main_iobase + INTR_ENABLE_REG); disable_ai_pacing(dev); }; @@ -1552,88 +1549,89 @@ static void init_stc_registers(struct comedi_device *dev) static int alloc_and_init_dma_members(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pcidas64_private *devpriv = dev->private; int i; /* alocate pci dma buffers */ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { - priv(dev)->ai_buffer[i] = + devpriv->ai_buffer[i] = pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, - &priv(dev)->ai_buffer_bus_addr[i]); - if (priv(dev)->ai_buffer[i] == NULL) + &devpriv->ai_buffer_bus_addr[i]); + if (devpriv->ai_buffer[i] == NULL) return -ENOMEM; } for (i = 0; i < AO_DMA_RING_COUNT; i++) { if (ao_cmd_is_supported(board(dev))) { - priv(dev)->ao_buffer[i] = + devpriv->ao_buffer[i] = pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, - &priv(dev)-> + &devpriv-> ao_buffer_bus_addr[i]); - if (priv(dev)->ao_buffer[i] == NULL) + if (devpriv->ao_buffer[i] == NULL) return -ENOMEM; } } /* allocate dma descriptors */ - priv(dev)->ai_dma_desc = + devpriv->ai_dma_desc = pci_alloc_consistent(pcidev, sizeof(struct plx_dma_desc) * ai_dma_ring_count(board(dev)), - &priv(dev)->ai_dma_desc_bus_addr); - if (priv(dev)->ai_dma_desc == NULL) + &devpriv->ai_dma_desc_bus_addr); + if (devpriv->ai_dma_desc == NULL) return -ENOMEM; DEBUG_PRINT("ai dma descriptors start at bus addr 0x%x\n", - priv(dev)->ai_dma_desc_bus_addr); + devpriv->ai_dma_desc_bus_addr); if (ao_cmd_is_supported(board(dev))) { - priv(dev)->ao_dma_desc = + devpriv->ao_dma_desc = pci_alloc_consistent(pcidev, sizeof(struct plx_dma_desc) * AO_DMA_RING_COUNT, - &priv(dev)->ao_dma_desc_bus_addr); - if (priv(dev)->ao_dma_desc == NULL) + &devpriv->ao_dma_desc_bus_addr); + if (devpriv->ao_dma_desc == NULL) return -ENOMEM; DEBUG_PRINT("ao dma descriptors start at bus addr 0x%x\n", - priv(dev)->ao_dma_desc_bus_addr); + devpriv->ao_dma_desc_bus_addr); } /* initialize dma descriptors */ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { - priv(dev)->ai_dma_desc[i].pci_start_addr = - cpu_to_le32(priv(dev)->ai_buffer_bus_addr[i]); + devpriv->ai_dma_desc[i].pci_start_addr = + cpu_to_le32(devpriv->ai_buffer_bus_addr[i]); if (board(dev)->layout == LAYOUT_4020) - priv(dev)->ai_dma_desc[i].local_start_addr = - cpu_to_le32(priv(dev)->local1_iobase + + devpriv->ai_dma_desc[i].local_start_addr = + cpu_to_le32(devpriv->local1_iobase + ADC_FIFO_REG); else - priv(dev)->ai_dma_desc[i].local_start_addr = - cpu_to_le32(priv(dev)->local0_iobase + + devpriv->ai_dma_desc[i].local_start_addr = + cpu_to_le32(devpriv->local0_iobase + ADC_FIFO_REG); - priv(dev)->ai_dma_desc[i].transfer_size = cpu_to_le32(0); - priv(dev)->ai_dma_desc[i].next = - cpu_to_le32((priv(dev)->ai_dma_desc_bus_addr + ((i + + devpriv->ai_dma_desc[i].transfer_size = cpu_to_le32(0); + devpriv->ai_dma_desc[i].next = + cpu_to_le32((devpriv->ai_dma_desc_bus_addr + ((i + 1) % ai_dma_ring_count (board (dev))) * - sizeof(priv(dev)->ai_dma_desc[0])) | + sizeof(devpriv->ai_dma_desc[0])) | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI); } if (ao_cmd_is_supported(board(dev))) { for (i = 0; i < AO_DMA_RING_COUNT; i++) { - priv(dev)->ao_dma_desc[i].pci_start_addr = - cpu_to_le32(priv(dev)->ao_buffer_bus_addr[i]); - priv(dev)->ao_dma_desc[i].local_start_addr = - cpu_to_le32(priv(dev)->local0_iobase + + devpriv->ao_dma_desc[i].pci_start_addr = + cpu_to_le32(devpriv->ao_buffer_bus_addr[i]); + devpriv->ao_dma_desc[i].local_start_addr = + cpu_to_le32(devpriv->local0_iobase + DAC_FIFO_REG); - priv(dev)->ao_dma_desc[i].transfer_size = + devpriv->ao_dma_desc[i].transfer_size = cpu_to_le32(0); - priv(dev)->ao_dma_desc[i].next = - cpu_to_le32((priv(dev)->ao_dma_desc_bus_addr + + devpriv->ao_dma_desc[i].next = + cpu_to_le32((devpriv->ao_dma_desc_bus_addr + ((i + 1) % (AO_DMA_RING_COUNT)) * - sizeof(priv(dev)->ao_dma_desc[0])) | + sizeof(devpriv->ao_dma_desc[0])) | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT); } @@ -1685,15 +1683,15 @@ static struct pci_dev *cb_pcidas64_find_pci_dev(struct comedi_device *dev, */ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct pcidas64_private *devpriv; struct pci_dev *pcidev; uint32_t local_range, local_decode; int retval; -/* - * Allocate the private structure area. - */ - if (alloc_private(dev, sizeof(struct pcidas64_private)) < 0) - return -ENOMEM; + retval = alloc_private(dev, sizeof(*devpriv)); + if (retval) + return retval; + devpriv = dev->private; pcidev = cb_pcidas64_find_pci_dev(dev, it); if (!pcidev) @@ -1712,63 +1710,63 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX); - priv(dev)->plx9080_phys_iobase = + devpriv->plx9080_phys_iobase = pci_resource_start(pcidev, PLX9080_BADDRINDEX); - priv(dev)->main_phys_iobase = dev->iobase; - priv(dev)->dio_counter_phys_iobase = + devpriv->main_phys_iobase = dev->iobase; + devpriv->dio_counter_phys_iobase = pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX); /* remap, won't work with 2.0 kernels but who cares */ - priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase, + devpriv->plx9080_iobase = ioremap(devpriv->plx9080_phys_iobase, pci_resource_len(pcidev, PLX9080_BADDRINDEX)); - priv(dev)->main_iobase = - ioremap(priv(dev)->main_phys_iobase, + devpriv->main_iobase = + ioremap(devpriv->main_phys_iobase, pci_resource_len(pcidev, MAIN_BADDRINDEX)); - priv(dev)->dio_counter_iobase = - ioremap(priv(dev)->dio_counter_phys_iobase, + devpriv->dio_counter_iobase = + ioremap(devpriv->dio_counter_phys_iobase, pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX)); - if (!priv(dev)->plx9080_iobase || !priv(dev)->main_iobase - || !priv(dev)->dio_counter_iobase) { + if (!devpriv->plx9080_iobase || !devpriv->main_iobase + || !devpriv->dio_counter_iobase) { dev_warn(dev->class_dev, "failed to remap io memory\n"); return -ENOMEM; } - DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase); - DEBUG_PRINT(" main remapped to 0x%p\n", priv(dev)->main_iobase); + DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase); + DEBUG_PRINT(" main remapped to 0x%p\n", devpriv->main_iobase); DEBUG_PRINT(" diocounter remapped to 0x%p\n", - priv(dev)->dio_counter_iobase); + devpriv->dio_counter_iobase); /* figure out what local addresses are */ local_range = - readl(priv(dev)->plx9080_iobase + PLX_LAS0RNG_REG) & LRNG_MEM_MASK; + readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) & LRNG_MEM_MASK; local_decode = - readl(priv(dev)->plx9080_iobase + + readl(devpriv->plx9080_iobase + PLX_LAS0MAP_REG) & local_range & LMAP_MEM_MASK; - priv(dev)->local0_iobase = - ((uint32_t) priv(dev)->main_phys_iobase & ~local_range) | + devpriv->local0_iobase = + ((uint32_t) devpriv->main_phys_iobase & ~local_range) | local_decode; local_range = - readl(priv(dev)->plx9080_iobase + PLX_LAS1RNG_REG) & LRNG_MEM_MASK; + readl(devpriv->plx9080_iobase + PLX_LAS1RNG_REG) & LRNG_MEM_MASK; local_decode = - readl(priv(dev)->plx9080_iobase + + readl(devpriv->plx9080_iobase + PLX_LAS1MAP_REG) & local_range & LMAP_MEM_MASK; - priv(dev)->local1_iobase = - ((uint32_t) priv(dev)->dio_counter_phys_iobase & ~local_range) | + devpriv->local1_iobase = + ((uint32_t) devpriv->dio_counter_phys_iobase & ~local_range) | local_decode; - DEBUG_PRINT(" local 0 io addr 0x%x\n", priv(dev)->local0_iobase); - DEBUG_PRINT(" local 1 io addr 0x%x\n", priv(dev)->local1_iobase); + DEBUG_PRINT(" local 0 io addr 0x%x\n", devpriv->local0_iobase); + DEBUG_PRINT(" local 1 io addr 0x%x\n", devpriv->local1_iobase); retval = alloc_and_init_dma_members(dev); if (retval < 0) return retval; - priv(dev)->hw_revision = - hw_revision(dev, readw(priv(dev)->main_iobase + HW_STATUS_REG)); + devpriv->hw_revision = + hw_revision(dev, readw(devpriv->main_iobase + HW_STATUS_REG)); dev_dbg(dev->class_dev, "stc hardware revision %i\n", - priv(dev)->hw_revision); + devpriv->hw_revision); init_plx9080(dev); init_stc_registers(dev); /* get irq */ @@ -1792,58 +1790,49 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) static void detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pcidas64_private *devpriv = dev->private; unsigned int i; if (dev->irq) free_irq(dev->irq, dev); - if (priv(dev)) { + if (devpriv) { if (pcidev) { - if (priv(dev)->plx9080_iobase) { + if (devpriv->plx9080_iobase) { disable_plx_interrupts(dev); - iounmap(priv(dev)->plx9080_iobase); + iounmap(devpriv->plx9080_iobase); } - if (priv(dev)->main_iobase) - iounmap(priv(dev)->main_iobase); - if (priv(dev)->dio_counter_iobase) - iounmap(priv(dev)->dio_counter_iobase); + if (devpriv->main_iobase) + iounmap(devpriv->main_iobase); + if (devpriv->dio_counter_iobase) + iounmap(devpriv->dio_counter_iobase); /* free pci dma buffers */ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { - if (priv(dev)->ai_buffer[i]) + if (devpriv->ai_buffer[i]) pci_free_consistent(pcidev, - DMA_BUFFER_SIZE, - priv(dev)-> - ai_buffer[i], - priv - (dev)->ai_buffer_bus_addr - [i]); + DMA_BUFFER_SIZE, + devpriv->ai_buffer[i], + devpriv->ai_buffer_bus_addr[i]); } for (i = 0; i < AO_DMA_RING_COUNT; i++) { - if (priv(dev)->ao_buffer[i]) + if (devpriv->ao_buffer[i]) pci_free_consistent(pcidev, - DMA_BUFFER_SIZE, - priv(dev)-> - ao_buffer[i], - priv - (dev)->ao_buffer_bus_addr - [i]); + DMA_BUFFER_SIZE, + devpriv->ao_buffer[i], + devpriv->ao_buffer_bus_addr[i]); } /* free dma descriptors */ - if (priv(dev)->ai_dma_desc) + if (devpriv->ai_dma_desc) pci_free_consistent(pcidev, - sizeof(struct plx_dma_desc) - * - ai_dma_ring_count(board - (dev)), - priv(dev)->ai_dma_desc, - priv(dev)-> - ai_dma_desc_bus_addr); - if (priv(dev)->ao_dma_desc) + sizeof(struct plx_dma_desc) * + ai_dma_ring_count(board(dev)), + devpriv->ai_dma_desc, + devpriv->ai_dma_desc_bus_addr); + if (devpriv->ao_dma_desc) pci_free_consistent(pcidev, - sizeof(struct plx_dma_desc) - * AO_DMA_RING_COUNT, - priv(dev)->ao_dma_desc, - priv(dev)-> - ao_dma_desc_bus_addr); + sizeof(struct plx_dma_desc) * + AO_DMA_RING_COUNT, + devpriv->ao_dma_desc, + devpriv->ao_dma_desc_bus_addr); } } if (dev->subdevices) @@ -1859,6 +1848,7 @@ static void detach(struct comedi_device *dev) static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; unsigned int bits = 0, n, i; unsigned int channel, range, aref; unsigned long flags; @@ -1875,18 +1865,18 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, spin_lock_irqsave(&dev->spinlock, flags); if (insn->chanspec & CR_ALT_FILTER) - priv(dev)->adc_control1_bits |= ADC_DITHER_BIT; + devpriv->adc_control1_bits |= ADC_DITHER_BIT; else - priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT; - writew(priv(dev)->adc_control1_bits, - priv(dev)->main_iobase + ADC_CONTROL1_REG); + devpriv->adc_control1_bits &= ~ADC_DITHER_BIT; + writew(devpriv->adc_control1_bits, + devpriv->main_iobase + ADC_CONTROL1_REG); spin_unlock_irqrestore(&dev->spinlock, flags); if (board(dev)->layout != LAYOUT_4020) { /* use internal queue */ - priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT; - writew(priv(dev)->hw_config_bits, - priv(dev)->main_iobase + HW_CONFIG_REG); + devpriv->hw_config_bits &= ~EXT_QUEUE_BIT; + writew(devpriv->hw_config_bits, + devpriv->main_iobase + HW_CONFIG_REG); /* ALT_SOURCE is internal calibration reference */ if (insn->chanspec & CR_ALT_SOURCE) { @@ -1899,11 +1889,11 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, cal_en_bit = CAL_EN_64XX_BIT; /* select internal reference source to connect to channel 0 */ writew(cal_en_bit | - adc_src_bits(priv(dev)->calibration_source), - priv(dev)->main_iobase + CALIBRATION_REG); + adc_src_bits(devpriv->calibration_source), + devpriv->main_iobase + CALIBRATION_REG); } else { /* make sure internal calibration source is turned off */ - writew(0, priv(dev)->main_iobase + CALIBRATION_REG); + writew(0, devpriv->main_iobase + CALIBRATION_REG); } /* load internal queue */ bits = 0; @@ -1916,29 +1906,29 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, bits |= adc_chan_bits(channel); /* set stop channel */ writew(adc_chan_bits(channel), - priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG); + devpriv->main_iobase + ADC_QUEUE_HIGH_REG); /* set start channel, and rest of settings */ - writew(bits, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG); + writew(bits, devpriv->main_iobase + ADC_QUEUE_LOAD_REG); } else { - uint8_t old_cal_range_bits = priv(dev)->i2c_cal_range_bits; + uint8_t old_cal_range_bits = devpriv->i2c_cal_range_bits; - priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; + devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; if (insn->chanspec & CR_ALT_SOURCE) { DEBUG_PRINT("reading calibration source\n"); - priv(dev)->i2c_cal_range_bits |= - adc_src_4020_bits(priv(dev)->calibration_source); + devpriv->i2c_cal_range_bits |= + adc_src_4020_bits(devpriv->calibration_source); } else { /* select BNC inputs */ - priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4); + devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4); } /* select range */ if (range == 0) - priv(dev)->i2c_cal_range_bits |= attenuate_bit(channel); + devpriv->i2c_cal_range_bits |= attenuate_bit(channel); else - priv(dev)->i2c_cal_range_bits &= + devpriv->i2c_cal_range_bits &= ~attenuate_bit(channel); /* update calibration/range i2c register only if necessary, as it is very slow */ - if (old_cal_range_bits != priv(dev)->i2c_cal_range_bits) { - uint8_t i2c_data = priv(dev)->i2c_cal_range_bits; + if (old_cal_range_bits != devpriv->i2c_cal_range_bits) { + uint8_t i2c_data = devpriv->i2c_cal_range_bits; i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data, sizeof(i2c_data)); } @@ -1946,26 +1936,26 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, /* 4020 manual asks that sample interval register to be set before writing to convert register. * Using somewhat arbitrary setting of 4 master clock ticks = 0.1 usec */ writew(0, - priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); + devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); writew(2, - priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); + devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); } for (n = 0; n < insn->n; n++) { /* clear adc buffer (inside loop for 4020 sake) */ - writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG); + writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG); /* trigger conversion, bits sent only matter for 4020 */ writew(adc_convert_chan_4020_bits(CR_CHAN(insn->chanspec)), - priv(dev)->main_iobase + ADC_CONVERT_REG); + devpriv->main_iobase + ADC_CONVERT_REG); /* wait for data */ for (i = 0; i < timeout; i++) { - bits = readw(priv(dev)->main_iobase + HW_STATUS_REG); + bits = readw(devpriv->main_iobase + HW_STATUS_REG); DEBUG_PRINT(" pipe bits 0x%x\n", pipe_full_bits(bits)); if (board(dev)->layout == LAYOUT_4020) { - if (readw(priv(dev)->main_iobase + + if (readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG)) break; } else { @@ -1982,11 +1972,11 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, } if (board(dev)->layout == LAYOUT_4020) data[n] = - readl(priv(dev)->dio_counter_iobase + + readl(devpriv->dio_counter_iobase + ADC_FIFO_REG) & 0xffff; else data[n] = - readw(priv(dev)->main_iobase + PIPE1_READ_REG); + readw(devpriv->main_iobase + PIPE1_READ_REG); } return n; @@ -1995,6 +1985,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int ai_config_calibration_source(struct comedi_device *dev, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; unsigned int source = data[1]; int num_calibration_sources; @@ -2009,7 +2000,7 @@ static int ai_config_calibration_source(struct comedi_device *dev, } DEBUG_PRINT("setting calibration source to %i\n", source); - priv(dev)->calibration_source = source; + devpriv->calibration_source = source; return 2; } @@ -2043,6 +2034,7 @@ static int ai_config_block_size(struct comedi_device *dev, unsigned int *data) static int ai_config_master_clock_4020(struct comedi_device *dev, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; unsigned int divisor = data[4]; int retval = 0; @@ -2053,8 +2045,8 @@ static int ai_config_master_clock_4020(struct comedi_device *dev, switch (data[1]) { case COMEDI_EV_SCAN_BEGIN: - priv(dev)->ext_clock.divisor = divisor; - priv(dev)->ext_clock.chanspec = data[2]; + devpriv->ext_clock.divisor = divisor; + devpriv->ext_clock.chanspec = data[2]; break; default: return -EINVAL; @@ -2279,27 +2271,30 @@ static int use_hw_sample_counter(struct comedi_cmd *cmd) static void setup_sample_counters(struct comedi_device *dev, struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; + if (cmd->stop_src == TRIG_COUNT) { /* set software count */ - priv(dev)->ai_count = cmd->stop_arg * cmd->chanlist_len; + devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len; } /* load hardware conversion counter */ if (use_hw_sample_counter(cmd)) { writew(cmd->stop_arg & 0xffff, - priv(dev)->main_iobase + ADC_COUNT_LOWER_REG); + devpriv->main_iobase + ADC_COUNT_LOWER_REG); writew((cmd->stop_arg >> 16) & 0xff, - priv(dev)->main_iobase + ADC_COUNT_UPPER_REG); + devpriv->main_iobase + ADC_COUNT_UPPER_REG); } else { - writew(1, priv(dev)->main_iobase + ADC_COUNT_LOWER_REG); + writew(1, devpriv->main_iobase + ADC_COUNT_LOWER_REG); } } static inline unsigned int dma_transfer_size(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; unsigned int num_samples; num_samples = - priv(dev)->ai_fifo_segment_length * + devpriv->ai_fifo_segment_length * board(dev)->ai_fifo->sample_packing_ratio; if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t)) num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t); @@ -2309,40 +2304,43 @@ static inline unsigned int dma_transfer_size(struct comedi_device *dev) static void disable_ai_pacing(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; unsigned long flags; disable_ai_interrupts(dev); spin_lock_irqsave(&dev->spinlock, flags); - priv(dev)->adc_control1_bits &= ~ADC_SW_GATE_BIT; - writew(priv(dev)->adc_control1_bits, - priv(dev)->main_iobase + ADC_CONTROL1_REG); + devpriv->adc_control1_bits &= ~ADC_SW_GATE_BIT; + writew(devpriv->adc_control1_bits, + devpriv->main_iobase + ADC_CONTROL1_REG); spin_unlock_irqrestore(&dev->spinlock, flags); /* disable pacing, triggering, etc */ writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT, - priv(dev)->main_iobase + ADC_CONTROL0_REG); + devpriv->main_iobase + ADC_CONTROL0_REG); } static void disable_ai_interrupts(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&dev->spinlock, flags); - priv(dev)->intr_enable_bits &= + devpriv->intr_enable_bits &= ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT & ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT & ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK; - writew(priv(dev)->intr_enable_bits, - priv(dev)->main_iobase + INTR_ENABLE_REG); + writew(devpriv->intr_enable_bits, + devpriv->main_iobase + INTR_ENABLE_REG); spin_unlock_irqrestore(&dev->spinlock, flags); - DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits); + DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); } static void enable_ai_interrupts(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; uint32_t bits; unsigned long flags; @@ -2355,10 +2353,10 @@ static void enable_ai_interrupts(struct comedi_device *dev, bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT; } spin_lock_irqsave(&dev->spinlock, flags); - priv(dev)->intr_enable_bits |= bits; - writew(priv(dev)->intr_enable_bits, - priv(dev)->main_iobase + INTR_ENABLE_REG); - DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits); + devpriv->intr_enable_bits |= bits; + writew(devpriv->intr_enable_bits, + devpriv->main_iobase + INTR_ENABLE_REG); + DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); spin_unlock_irqrestore(&dev->spinlock, flags); } @@ -2393,6 +2391,7 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev, static uint32_t ai_convert_counter_4020(struct comedi_device *dev, struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; unsigned int divisor; switch (cmd->scan_begin_src) { @@ -2400,7 +2399,7 @@ static uint32_t ai_convert_counter_4020(struct comedi_device *dev, divisor = cmd->scan_begin_arg / TIMER_BASE; break; case TRIG_OTHER: - divisor = priv(dev)->ext_clock.divisor; + divisor = devpriv->ext_clock.divisor; break; default: /* should never happen */ comedi_error(dev, "bug! failed to set ai pacing!"); @@ -2415,20 +2414,22 @@ static uint32_t ai_convert_counter_4020(struct comedi_device *dev, static void select_master_clock_4020(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; + /* select internal/external master clock */ - priv(dev)->hw_config_bits &= ~MASTER_CLOCK_4020_MASK; + devpriv->hw_config_bits &= ~MASTER_CLOCK_4020_MASK; if (cmd->scan_begin_src == TRIG_OTHER) { - int chanspec = priv(dev)->ext_clock.chanspec; + int chanspec = devpriv->ext_clock.chanspec; if (CR_CHAN(chanspec)) - priv(dev)->hw_config_bits |= BNC_CLOCK_4020_BITS; + devpriv->hw_config_bits |= BNC_CLOCK_4020_BITS; else - priv(dev)->hw_config_bits |= EXT_CLOCK_4020_BITS; + devpriv->hw_config_bits |= EXT_CLOCK_4020_BITS; } else { - priv(dev)->hw_config_bits |= INTERNAL_CLOCK_4020_BITS; + devpriv->hw_config_bits |= INTERNAL_CLOCK_4020_BITS; } - writew(priv(dev)->hw_config_bits, - priv(dev)->main_iobase + HW_CONFIG_REG); + writew(devpriv->hw_config_bits, + devpriv->main_iobase + HW_CONFIG_REG); } static void select_master_clock(struct comedi_device *dev, @@ -2446,6 +2447,7 @@ static void select_master_clock(struct comedi_device *dev, static inline void dma_start_sync(struct comedi_device *dev, unsigned int channel) { + struct pcidas64_private *devpriv = dev->private; unsigned long flags; /* spinlock for plx dma control/status reg */ @@ -2453,16 +2455,17 @@ static inline void dma_start_sync(struct comedi_device *dev, if (channel) writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); + devpriv->plx9080_iobase + PLX_DMA1_CS_REG); else writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + devpriv->plx9080_iobase + PLX_DMA0_CS_REG); spin_unlock_irqrestore(&dev->spinlock, flags); } static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; uint32_t convert_counter = 0, scan_counter = 0; check_adc_timing(dev, cmd); @@ -2478,17 +2481,17 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) /* load lower 16 bits of convert interval */ writew(convert_counter & 0xffff, - priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); + devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); DEBUG_PRINT("convert counter 0x%x\n", convert_counter); /* load upper 8 bits of convert interval */ writew((convert_counter >> 16) & 0xff, - priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); + devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); /* load lower 16 bits of scan delay */ writew(scan_counter & 0xffff, - priv(dev)->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG); + devpriv->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG); /* load upper 8 bits of scan delay */ writew((scan_counter >> 16) & 0xff, - priv(dev)->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG); + devpriv->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG); DEBUG_PRINT("scan counter 0x%x\n", scan_counter); } @@ -2511,14 +2514,15 @@ static int use_internal_queue_6xxx(const struct comedi_cmd *cmd) static int setup_channel_queue(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; unsigned short bits; int i; if (board(dev)->layout != LAYOUT_4020) { if (use_internal_queue_6xxx(cmd)) { - priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT; - writew(priv(dev)->hw_config_bits, - priv(dev)->main_iobase + HW_CONFIG_REG); + devpriv->hw_config_bits &= ~EXT_QUEUE_BIT; + writew(devpriv->hw_config_bits, + devpriv->main_iobase + HW_CONFIG_REG); bits = 0; /* set channel */ bits |= adc_chan_bits(CR_CHAN(cmd->chanlist[0])); @@ -2534,24 +2538,24 @@ static int setup_channel_queue(struct comedi_device *dev, /* set stop channel */ writew(adc_chan_bits (CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])), - priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG); + devpriv->main_iobase + ADC_QUEUE_HIGH_REG); /* set start channel, and rest of settings */ writew(bits, - priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG); + devpriv->main_iobase + ADC_QUEUE_LOAD_REG); } else { /* use external queue */ if (dev->write_subdev && dev->write_subdev->busy) { warn_external_queue(dev); return -EBUSY; } - priv(dev)->hw_config_bits |= EXT_QUEUE_BIT; - writew(priv(dev)->hw_config_bits, - priv(dev)->main_iobase + HW_CONFIG_REG); + devpriv->hw_config_bits |= EXT_QUEUE_BIT; + writew(devpriv->hw_config_bits, + devpriv->main_iobase + HW_CONFIG_REG); /* clear DAC buffer to prevent weird interactions */ writew(0, - priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG); + devpriv->main_iobase + DAC_BUFFER_CLEAR_REG); /* clear queue pointer */ - writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG); + writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG); /* load external queue */ for (i = 0; i < cmd->chanlist_len; i++) { bits = 0; @@ -2575,7 +2579,7 @@ static int setup_channel_queue(struct comedi_device *dev, bits |= QUEUE_EOSCAN_BIT | QUEUE_EOSEQ_BIT; writew(bits, - priv(dev)->main_iobase + + devpriv->main_iobase + ADC_QUEUE_FIFO_REG); DEBUG_PRINT ("wrote 0x%x to external channel queue\n", @@ -2583,32 +2587,32 @@ static int setup_channel_queue(struct comedi_device *dev, } /* doing a queue clear is not specified in board docs, * but required for reliable operation */ - writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG); + writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG); /* prime queue holding register */ - writew(0, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG); + writew(0, devpriv->main_iobase + ADC_QUEUE_LOAD_REG); } } else { unsigned short old_cal_range_bits = - priv(dev)->i2c_cal_range_bits; + devpriv->i2c_cal_range_bits; - priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; + devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; /* select BNC inputs */ - priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4); + devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4); /* select ranges */ for (i = 0; i < cmd->chanlist_len; i++) { unsigned int channel = CR_CHAN(cmd->chanlist[i]); unsigned int range = CR_RANGE(cmd->chanlist[i]); if (range == 0) - priv(dev)->i2c_cal_range_bits |= + devpriv->i2c_cal_range_bits |= attenuate_bit(channel); else - priv(dev)->i2c_cal_range_bits &= + devpriv->i2c_cal_range_bits &= ~attenuate_bit(channel); } /* update calibration/range i2c register only if necessary, as it is very slow */ - if (old_cal_range_bits != priv(dev)->i2c_cal_range_bits) { - uint8_t i2c_data = priv(dev)->i2c_cal_range_bits; + if (old_cal_range_bits != devpriv->i2c_cal_range_bits) { + uint8_t i2c_data = devpriv->i2c_cal_range_bits; i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data, sizeof(i2c_data)); } @@ -2620,6 +2624,8 @@ static inline void load_first_dma_descriptor(struct comedi_device *dev, unsigned int dma_channel, unsigned int descriptor_bits) { + struct pcidas64_private *devpriv = dev->private; + /* The transfer size, pci address, and local address registers * are supposedly unused during chained dma, * but I have found that left over values from last operation @@ -2627,25 +2633,26 @@ static inline void load_first_dma_descriptor(struct comedi_device *dev, * block. Initializing them to zero seems to fix the problem. */ if (dma_channel) { writel(0, - priv(dev)->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG); - writel(0, priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG); + devpriv->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG); + writel(0, devpriv->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG); writel(0, - priv(dev)->plx9080_iobase + PLX_DMA1_LOCAL_ADDRESS_REG); + devpriv->plx9080_iobase + PLX_DMA1_LOCAL_ADDRESS_REG); writel(descriptor_bits, - priv(dev)->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG); + devpriv->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG); } else { writel(0, - priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG); - writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); + devpriv->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG); + writel(0, devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); writel(0, - priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG); + devpriv->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG); writel(descriptor_bits, - priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); + devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); } } static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcidas64_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; uint32_t bits; @@ -2661,7 +2668,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return retval; /* make sure internal calibration source is turned off */ - writew(0, priv(dev)->main_iobase + CALIBRATION_REG); + writew(0, devpriv->main_iobase + CALIBRATION_REG); set_ai_pacing(dev, cmd); @@ -2671,50 +2678,50 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) spin_lock_irqsave(&dev->spinlock, flags); /* set mode, allow conversions through software gate */ - priv(dev)->adc_control1_bits |= ADC_SW_GATE_BIT; - priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT; + devpriv->adc_control1_bits |= ADC_SW_GATE_BIT; + devpriv->adc_control1_bits &= ~ADC_DITHER_BIT; if (board(dev)->layout != LAYOUT_4020) { - priv(dev)->adc_control1_bits &= ~ADC_MODE_MASK; + devpriv->adc_control1_bits &= ~ADC_MODE_MASK; if (cmd->convert_src == TRIG_EXT) - priv(dev)->adc_control1_bits |= adc_mode_bits(13); /* good old mode 13 */ + devpriv->adc_control1_bits |= adc_mode_bits(13); /* good old mode 13 */ else - priv(dev)->adc_control1_bits |= adc_mode_bits(8); /* mode 8. What else could you need? */ + devpriv->adc_control1_bits |= adc_mode_bits(8); /* mode 8. What else could you need? */ } else { - priv(dev)->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK; + devpriv->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK; if (cmd->chanlist_len == 4) - priv(dev)->adc_control1_bits |= FOUR_CHANNEL_4020_BITS; + devpriv->adc_control1_bits |= FOUR_CHANNEL_4020_BITS; else if (cmd->chanlist_len == 2) - priv(dev)->adc_control1_bits |= TWO_CHANNEL_4020_BITS; - priv(dev)->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK; - priv(dev)->adc_control1_bits |= + devpriv->adc_control1_bits |= TWO_CHANNEL_4020_BITS; + devpriv->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK; + devpriv->adc_control1_bits |= adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0])); - priv(dev)->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK; - priv(dev)->adc_control1_bits |= + devpriv->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK; + devpriv->adc_control1_bits |= adc_hi_chan_4020_bits(CR_CHAN (cmd-> chanlist[cmd->chanlist_len - 1])); } - writew(priv(dev)->adc_control1_bits, - priv(dev)->main_iobase + ADC_CONTROL1_REG); - DEBUG_PRINT("control1 bits 0x%x\n", priv(dev)->adc_control1_bits); + writew(devpriv->adc_control1_bits, + devpriv->main_iobase + ADC_CONTROL1_REG); + DEBUG_PRINT("control1 bits 0x%x\n", devpriv->adc_control1_bits); spin_unlock_irqrestore(&dev->spinlock, flags); /* clear adc buffer */ - writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG); + writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG); if ((cmd->flags & TRIG_WAKE_EOS) == 0 || board(dev)->layout == LAYOUT_4020) { - priv(dev)->ai_dma_index = 0; + devpriv->ai_dma_index = 0; /* set dma transfer size */ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) - priv(dev)->ai_dma_desc[i].transfer_size = + devpriv->ai_dma_desc[i].transfer_size = cpu_to_le32(dma_transfer_size(dev) * sizeof(uint16_t)); /* give location of first dma descriptor */ load_first_dma_descriptor(dev, 1, - priv(dev)->ai_dma_desc_bus_addr | + devpriv->ai_dma_desc_bus_addr | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI); @@ -2729,7 +2736,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) bits |= EXT_START_TRIG_BNC_BIT; if (cmd->stop_src == TRIG_EXT && CR_CHAN(cmd->stop_arg)) bits |= EXT_STOP_TRIG_BNC_BIT; - writew(bits, priv(dev)->main_iobase + DAQ_ATRIG_LOW_4020_REG); + writew(bits, devpriv->main_iobase + DAQ_ATRIG_LOW_4020_REG); } spin_lock_irqsave(&dev->spinlock, flags); @@ -2747,16 +2754,16 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) bits |= ADC_START_TRIG_SOFT_BITS; if (use_hw_sample_counter(cmd)) bits |= ADC_SAMPLE_COUNTER_EN_BIT; - writew(bits, priv(dev)->main_iobase + ADC_CONTROL0_REG); + writew(bits, devpriv->main_iobase + ADC_CONTROL0_REG); DEBUG_PRINT("control0 bits 0x%x\n", bits); - priv(dev)->ai_cmd_running = 1; + devpriv->ai_cmd_running = 1; spin_unlock_irqrestore(&dev->spinlock, flags); /* start acquisition */ if (cmd->start_src == TRIG_NOW) { - writew(0, priv(dev)->main_iobase + ADC_START_REG); + writew(0, devpriv->main_iobase + ADC_START_REG); DEBUG_PRINT("soft trig\n"); } @@ -2766,6 +2773,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* read num_samples from 16 bit wide ai fifo */ static void pio_drain_ai_fifo_16(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; @@ -2777,14 +2785,14 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) do { /* get least significant 15 bits */ read_index = - readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; + readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; write_index = - readw(priv(dev)->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; + readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; /* Get most significant bits (grey code). Different boards use different code * so use a scheme that doesn't depend on encoding. This read must * occur after reading least significant 15 bits to avoid race * with fifo switching to next segment. */ - prepost_bits = readw(priv(dev)->main_iobase + PREPOST_REG); + prepost_bits = readw(devpriv->main_iobase + PREPOST_REG); /* if read and write pointers are not on the same fifo segment, read to the * end of the read segment */ @@ -2797,17 +2805,17 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) if (read_segment != write_segment) num_samples = - priv(dev)->ai_fifo_segment_length - read_index; + devpriv->ai_fifo_segment_length - read_index; else num_samples = write_index - read_index; if (cmd->stop_src == TRIG_COUNT) { - if (priv(dev)->ai_count == 0) + if (devpriv->ai_count == 0) break; - if (num_samples > priv(dev)->ai_count) - num_samples = priv(dev)->ai_count; + if (num_samples > devpriv->ai_count) + num_samples = devpriv->ai_count; - priv(dev)->ai_count -= num_samples; + devpriv->ai_count -= num_samples; } if (num_samples < 0) { @@ -2820,7 +2828,7 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) for (i = 0; i < num_samples; i++) { cfc_write_to_buffer(s, - readw(priv(dev)->main_iobase + + readw(devpriv->main_iobase + ADC_FIFO_REG)); } @@ -2834,6 +2842,7 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) */ static void pio_drain_ai_fifo_32(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; @@ -2841,17 +2850,17 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) unsigned int max_transfer = 100000; uint32_t fifo_data; int write_code = - readw(priv(dev)->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; + readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; int read_code = - readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; + readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; if (cmd->stop_src == TRIG_COUNT) { - if (max_transfer > priv(dev)->ai_count) - max_transfer = priv(dev)->ai_count; + if (max_transfer > devpriv->ai_count) + max_transfer = devpriv->ai_count; } for (i = 0; read_code != write_code && i < max_transfer;) { - fifo_data = readl(priv(dev)->dio_counter_iobase + ADC_FIFO_REG); + fifo_data = readl(devpriv->dio_counter_iobase + ADC_FIFO_REG); cfc_write_to_buffer(s, fifo_data & 0xffff); i++; if (i < max_transfer) { @@ -2859,9 +2868,9 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) i++; } read_code = - readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; + readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; } - priv(dev)->ai_count -= i; + devpriv->ai_count -= i; } /* empty fifo */ @@ -2875,6 +2884,7 @@ static void pio_drain_ai_fifo(struct comedi_device *dev) static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) { + struct pcidas64_private *devpriv = dev->private; struct comedi_async *async = dev->read_subdev->async; uint32_t next_transfer_addr; int j; @@ -2883,36 +2893,36 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) if (channel) pci_addr_reg = - priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG; + devpriv->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG; else pci_addr_reg = - priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; + devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; /* loop until we have read all the full buffers */ for (j = 0, next_transfer_addr = readl(pci_addr_reg); (next_transfer_addr < - priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index] + devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] || next_transfer_addr >= - priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index] + + devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] + DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board(dev)); j++) { /* transfer data from dma buffer to comedi buffer */ num_samples = dma_transfer_size(dev); if (async->cmd.stop_src == TRIG_COUNT) { - if (num_samples > priv(dev)->ai_count) - num_samples = priv(dev)->ai_count; - priv(dev)->ai_count -= num_samples; + if (num_samples > devpriv->ai_count) + num_samples = devpriv->ai_count; + devpriv->ai_count -= num_samples; } cfc_write_array_to_buffer(dev->read_subdev, - priv(dev)->ai_buffer[priv(dev)-> + devpriv->ai_buffer[devpriv-> ai_dma_index], num_samples * sizeof(uint16_t)); - priv(dev)->ai_dma_index = - (priv(dev)->ai_dma_index + + devpriv->ai_dma_index = + (devpriv->ai_dma_index + 1) % ai_dma_ring_count(board(dev)); DEBUG_PRINT("next buffer addr 0x%lx\n", - (unsigned long)priv(dev)-> - ai_buffer_bus_addr[priv(dev)->ai_dma_index]); + (unsigned long)devpriv-> + ai_buffer_bus_addr[devpriv->ai_dma_index]); DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr); } /* XXX check for dma ring buffer overrun (use end-of-chain bit to mark last @@ -2923,6 +2933,7 @@ static void handle_ai_interrupt(struct comedi_device *dev, unsigned short status, unsigned int plx_status) { + struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; @@ -2936,10 +2947,10 @@ static void handle_ai_interrupt(struct comedi_device *dev, } /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); - dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); + dma1_status = readb(devpriv->plx9080_iobase + PLX_DMA1_CS_REG); if (plx_status & ICS_DMA1_A) { /* dma chan 1 interrupt */ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); + devpriv->plx9080_iobase + PLX_DMA1_CS_REG); DEBUG_PRINT("dma1 status 0x%x\n", dma1_status); if (dma1_status & PLX_DMA_EN_BIT) @@ -2959,14 +2970,14 @@ static void handle_ai_interrupt(struct comedi_device *dev, (board(dev)->layout != LAYOUT_4020))) { DEBUG_PRINT("pio fifo drain\n"); spin_lock_irqsave(&dev->spinlock, flags); - if (priv(dev)->ai_cmd_running) { + if (devpriv->ai_cmd_running) { spin_unlock_irqrestore(&dev->spinlock, flags); pio_drain_ai_fifo(dev); } else spin_unlock_irqrestore(&dev->spinlock, flags); } /* if we are have all the data, then quit */ - if ((cmd->stop_src == TRIG_COUNT && (int)priv(dev)->ai_count <= 0) || + if ((cmd->stop_src == TRIG_COUNT && (int)devpriv->ai_count <= 0) || (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) { async->events |= COMEDI_CB_EOA; } @@ -2976,29 +2987,31 @@ static void handle_ai_interrupt(struct comedi_device *dev, static inline unsigned int prev_ao_dma_index(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; unsigned int buffer_index; - if (priv(dev)->ao_dma_index == 0) + if (devpriv->ao_dma_index == 0) buffer_index = AO_DMA_RING_COUNT - 1; else - buffer_index = priv(dev)->ao_dma_index - 1; + buffer_index = devpriv->ao_dma_index - 1; return buffer_index; } static int last_ao_dma_load_completed(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; unsigned int buffer_index; unsigned int transfer_address; unsigned short dma_status; buffer_index = prev_ao_dma_index(dev); - dma_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + dma_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG); if ((dma_status & PLX_DMA_DONE_BIT) == 0) return 0; transfer_address = - readl(priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); - if (transfer_address != priv(dev)->ao_buffer_bus_addr[buffer_index]) + readl(devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); + if (transfer_address != devpriv->ao_buffer_bus_addr[buffer_index]) return 0; return 1; @@ -3007,10 +3020,12 @@ static int last_ao_dma_load_completed(struct comedi_device *dev) static int ao_stopped_by_error(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; + if (cmd->stop_src == TRIG_NONE) return 1; if (cmd->stop_src == TRIG_COUNT) { - if (priv(dev)->ao_count) + if (devpriv->ao_count) return 1; if (last_ao_dma_load_completed(dev) == 0) return 1; @@ -3032,10 +3047,11 @@ static inline int ao_dma_needs_restart(struct comedi_device *dev, static void restart_ao_dma(struct comedi_device *dev) { + struct pcidas64_private *devpriv = dev->private; unsigned int dma_desc_bits; dma_desc_bits = - readl(priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); + readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT; DEBUG_PRINT("restarting ao dma, descriptor reg 0x%x\n", dma_desc_bits); load_first_dma_descriptor(dev, 0, dma_desc_bits); @@ -3046,6 +3062,7 @@ static void restart_ao_dma(struct comedi_device *dev) static void handle_ao_interrupt(struct comedi_device *dev, unsigned short status, unsigned int plx_status) { + struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s = dev->write_subdev; struct comedi_async *async; struct comedi_cmd *cmd; @@ -3060,15 +3077,15 @@ static void handle_ao_interrupt(struct comedi_device *dev, /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); - dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + dma0_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG); if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */ if ((dma0_status & PLX_DMA_EN_BIT) && !(dma0_status & PLX_DMA_DONE_BIT)) writeb(PLX_DMA_EN_BIT | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + devpriv->plx9080_iobase + PLX_DMA0_CS_REG); else writeb(PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + devpriv->plx9080_iobase + PLX_DMA0_CS_REG); spin_unlock_irqrestore(&dev->spinlock, flags); DEBUG_PRINT("dma0 status 0x%x\n", dma0_status); if (dma0_status & PLX_DMA_EN_BIT) { @@ -3086,10 +3103,10 @@ static void handle_ao_interrupt(struct comedi_device *dev, if (ao_stopped_by_error(dev, cmd)) async->events |= COMEDI_CB_ERROR; DEBUG_PRINT("plx dma0 desc reg 0x%x\n", - readl(priv(dev)->plx9080_iobase + + readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG)); DEBUG_PRINT("plx dma0 address reg 0x%x\n", - readl(priv(dev)->plx9080_iobase + + readl(devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG)); } cfc_handle_events(dev, s); @@ -3098,12 +3115,13 @@ static void handle_ao_interrupt(struct comedi_device *dev, static irqreturn_t handle_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct pcidas64_private *devpriv = dev->private; unsigned short status; uint32_t plx_status; uint32_t plx_bits; - plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG); - status = readw(priv(dev)->main_iobase + HW_STATUS_REG); + plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG); + status = readw(devpriv->main_iobase + HW_STATUS_REG); DEBUG_PRINT("cb_pcidas64: hw status 0x%x ", status); DEBUG_PRINT("plx status 0x%x\n", plx_status); @@ -3121,8 +3139,8 @@ static irqreturn_t handle_interrupt(int irq, void *d) /* clear possible plx9080 interrupt sources */ if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */ - plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG); - writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG); + plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG); + writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG); DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits); } @@ -3133,26 +3151,28 @@ static irqreturn_t handle_interrupt(int irq, void *d) static void abort_dma(struct comedi_device *dev, unsigned int channel) { + struct pcidas64_private *devpriv = dev->private; unsigned long flags; /* spinlock for plx dma control/status reg */ spin_lock_irqsave(&dev->spinlock, flags); - plx9080_abort_dma(priv(dev)->plx9080_iobase, channel); + plx9080_abort_dma(devpriv->plx9080_iobase, channel); spin_unlock_irqrestore(&dev->spinlock, flags); } static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcidas64_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&dev->spinlock, flags); - if (priv(dev)->ai_cmd_running == 0) { + if (devpriv->ai_cmd_running == 0) { spin_unlock_irqrestore(&dev->spinlock, flags); return 0; } - priv(dev)->ai_cmd_running = 0; + devpriv->ai_cmd_running = 0; spin_unlock_irqrestore(&dev->spinlock, flags); disable_ai_pacing(dev); @@ -3166,29 +3186,30 @@ static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); int range = CR_RANGE(insn->chanspec); /* do some initializing */ - writew(0, priv(dev)->main_iobase + DAC_CONTROL0_REG); + writew(0, devpriv->main_iobase + DAC_CONTROL0_REG); /* set range */ - set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, chan, range); - writew(priv(dev)->dac_control1_bits, - priv(dev)->main_iobase + DAC_CONTROL1_REG); + set_dac_range_bits(dev, &devpriv->dac_control1_bits, chan, range); + writew(devpriv->dac_control1_bits, + devpriv->main_iobase + DAC_CONTROL1_REG); /* write to channel */ if (board(dev)->layout == LAYOUT_4020) { writew(data[0] & 0xff, - priv(dev)->main_iobase + dac_lsb_4020_reg(chan)); + devpriv->main_iobase + dac_lsb_4020_reg(chan)); writew((data[0] >> 8) & 0xf, - priv(dev)->main_iobase + dac_msb_4020_reg(chan)); + devpriv->main_iobase + dac_msb_4020_reg(chan)); } else { - writew(data[0], priv(dev)->main_iobase + dac_convert_reg(chan)); + writew(data[0], devpriv->main_iobase + dac_convert_reg(chan)); } /* remember output value */ - priv(dev)->ao_value[chan] = data[0]; + devpriv->ao_value[chan] = data[0]; return 1; } @@ -3197,7 +3218,9 @@ static int ao_readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - data[0] = priv(dev)->ao_value[CR_CHAN(insn->chanspec)]; + struct pcidas64_private *devpriv = dev->private; + + data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)]; return 1; } @@ -3205,6 +3228,7 @@ static int ao_readback_insn(struct comedi_device *dev, static void set_dac_control0_reg(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; unsigned int bits = DAC_ENABLE_BIT | WAVEFORM_GATE_LEVEL_BIT | WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT; @@ -3220,12 +3244,13 @@ static void set_dac_control0_reg(struct comedi_device *dev, if (cmd->scan_begin_arg & CR_INVERT) bits |= DAC_EXT_UPDATE_FALLING_BIT; } - writew(bits, priv(dev)->main_iobase + DAC_CONTROL0_REG); + writew(bits, devpriv->main_iobase + DAC_CONTROL0_REG); } static void set_dac_control1_reg(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; int i; for (i = 0; i < cmd->chanlist_len; i++) { @@ -3233,17 +3258,18 @@ static void set_dac_control1_reg(struct comedi_device *dev, channel = CR_CHAN(cmd->chanlist[i]); range = CR_RANGE(cmd->chanlist[i]); - set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, channel, + set_dac_range_bits(dev, &devpriv->dac_control1_bits, channel, range); } - priv(dev)->dac_control1_bits |= DAC_SW_GATE_BIT; - writew(priv(dev)->dac_control1_bits, - priv(dev)->main_iobase + DAC_CONTROL1_REG); + devpriv->dac_control1_bits |= DAC_SW_GATE_BIT; + writew(devpriv->dac_control1_bits, + devpriv->main_iobase + DAC_CONTROL1_REG); } static void set_dac_select_reg(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; uint16_t bits; unsigned int first_channel, last_channel; @@ -3254,12 +3280,13 @@ static void set_dac_select_reg(struct comedi_device *dev, bits = (first_channel & 0x7) | (last_channel & 0x7) << 3; - writew(bits, priv(dev)->main_iobase + DAC_SELECT_REG); + writew(bits, devpriv->main_iobase + DAC_SELECT_REG); } static void set_dac_interval_regs(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; unsigned int divisor; if (cmd->scan_begin_src != TRIG_TIMER) @@ -3271,28 +3298,29 @@ static void set_dac_interval_regs(struct comedi_device *dev, divisor = max_counter_value; } writew(divisor & 0xffff, - priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG); + devpriv->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG); writew((divisor >> 16) & 0xff, - priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG); + devpriv->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG); } static unsigned int load_ao_dma_buffer(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; unsigned int num_bytes, buffer_index, prev_buffer_index; unsigned int next_bits; - buffer_index = priv(dev)->ao_dma_index; + buffer_index = devpriv->ao_dma_index; prev_buffer_index = prev_ao_dma_index(dev); DEBUG_PRINT("attempting to load ao buffer %i (0x%x)\n", buffer_index, - priv(dev)->ao_buffer_bus_addr[buffer_index]); + devpriv->ao_buffer_bus_addr[buffer_index]); num_bytes = comedi_buf_read_n_available(dev->write_subdev->async); if (num_bytes > DMA_BUFFER_SIZE) num_bytes = DMA_BUFFER_SIZE; - if (cmd->stop_src == TRIG_COUNT && num_bytes > priv(dev)->ao_count) - num_bytes = priv(dev)->ao_count; + if (cmd->stop_src == TRIG_COUNT && num_bytes > devpriv->ao_count) + num_bytes = devpriv->ao_count; num_bytes -= num_bytes % bytes_in_sample; if (num_bytes == 0) @@ -3301,43 +3329,44 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev, DEBUG_PRINT("loading %i bytes\n", num_bytes); num_bytes = cfc_read_array_from_buffer(dev->write_subdev, - priv(dev)-> + devpriv-> ao_buffer[buffer_index], num_bytes); - priv(dev)->ao_dma_desc[buffer_index].transfer_size = + devpriv->ao_dma_desc[buffer_index].transfer_size = cpu_to_le32(num_bytes); /* set end of chain bit so we catch underruns */ - next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[buffer_index].next); + next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next); next_bits |= PLX_END_OF_CHAIN_BIT; - priv(dev)->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits); + devpriv->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits); /* clear end of chain bit on previous buffer now that we have set it * for the last buffer */ - next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[prev_buffer_index].next); + next_bits = le32_to_cpu(devpriv->ao_dma_desc[prev_buffer_index].next); next_bits &= ~PLX_END_OF_CHAIN_BIT; - priv(dev)->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits); + devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits); - priv(dev)->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT; - priv(dev)->ao_count -= num_bytes; + devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT; + devpriv->ao_count -= num_bytes; return num_bytes; } static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; unsigned int num_bytes; unsigned int next_transfer_addr; void __iomem *pci_addr_reg = - priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; + devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; unsigned int buffer_index; do { - buffer_index = priv(dev)->ao_dma_index; + buffer_index = devpriv->ao_dma_index; /* don't overwrite data that hasn't been transferred yet */ next_transfer_addr = readl(pci_addr_reg); if (next_transfer_addr >= - priv(dev)->ao_buffer_bus_addr[buffer_index] + devpriv->ao_buffer_bus_addr[buffer_index] && next_transfer_addr < - priv(dev)->ao_buffer_bus_addr[buffer_index] + + devpriv->ao_buffer_bus_addr[buffer_index] + DMA_BUFFER_SIZE) return; num_bytes = load_ao_dma_buffer(dev, cmd); @@ -3346,27 +3375,28 @@ static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct pcidas64_private *devpriv = dev->private; unsigned int num_bytes; int i; /* clear queue pointer too, since external queue has * weird interactions with ao fifo */ - writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG); - writew(0, priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG); + writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG); + writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG); num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample; if (cmd->stop_src == TRIG_COUNT && - num_bytes / bytes_in_sample > priv(dev)->ao_count) - num_bytes = priv(dev)->ao_count * bytes_in_sample; + num_bytes / bytes_in_sample > devpriv->ao_count) + num_bytes = devpriv->ao_count * bytes_in_sample; num_bytes = cfc_read_array_from_buffer(dev->write_subdev, - priv(dev)->ao_bounce_buffer, + devpriv->ao_bounce_buffer, num_bytes); for (i = 0; i < num_bytes / bytes_in_sample; i++) { - writew(priv(dev)->ao_bounce_buffer[i], - priv(dev)->main_iobase + DAC_FIFO_REG); + writew(devpriv->ao_bounce_buffer[i], + devpriv->main_iobase + DAC_FIFO_REG); } - priv(dev)->ao_count -= num_bytes / bytes_in_sample; - if (cmd->stop_src == TRIG_COUNT && priv(dev)->ao_count == 0) + devpriv->ao_count -= num_bytes / bytes_in_sample; + if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count == 0) return 0; num_bytes = load_ao_dma_buffer(dev, cmd); if (num_bytes == 0) @@ -3392,6 +3422,7 @@ static inline int external_ai_queue_in_use(struct comedi_device *dev) static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcidas64_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; if (external_ai_queue_in_use(dev)) { @@ -3399,14 +3430,14 @@ static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return -EBUSY; } /* disable analog output system during setup */ - writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG); + writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG); - priv(dev)->ao_dma_index = 0; - priv(dev)->ao_count = cmd->stop_arg * cmd->chanlist_len; + devpriv->ao_dma_index = 0; + devpriv->ao_count = cmd->stop_arg * cmd->chanlist_len; set_dac_select_reg(dev, cmd); set_dac_interval_regs(dev, cmd); - load_first_dma_descriptor(dev, 0, priv(dev)->ao_dma_desc_bus_addr | + load_first_dma_descriptor(dev, 0, devpriv->ao_dma_desc_bus_addr | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT); set_dac_control1_reg(dev, cmd); @@ -3418,6 +3449,7 @@ static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trig_num) { + struct pcidas64_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int retval; @@ -3431,7 +3463,7 @@ static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, set_dac_control0_reg(dev, cmd); if (cmd->start_src == TRIG_INT) - writew(0, priv(dev)->main_iobase + DAC_START_REG); + writew(0, devpriv->main_iobase + DAC_START_REG); s->async->inttrig = NULL; @@ -3533,7 +3565,9 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG); + struct pcidas64_private *devpriv = dev->private; + + writew(0x0, devpriv->main_iobase + DAC_CONTROL0_REG); abort_dma(dev, 0); return 0; } @@ -3564,9 +3598,10 @@ static int dio_callback_4020(int dir, int port, int data, unsigned long arg) static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; unsigned int bits; - bits = readb(priv(dev)->dio_counter_iobase + DI_REG); + bits = readb(devpriv->dio_counter_iobase + DI_REG); bits &= 0xf; data[1] = bits; data[0] = 0; @@ -3577,13 +3612,15 @@ static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; + data[0] &= 0xf; /* zero bits we are going to change */ s->state &= ~data[0]; /* set new bits */ s->state |= data[0] & data[1]; - writeb(s->state, priv(dev)->dio_counter_iobase + DO_REG); + writeb(s->state, devpriv->dio_counter_iobase + DO_REG); data[1] = s->state; @@ -3594,6 +3631,7 @@ static int dio_60xx_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; unsigned int mask; mask = 1 << CR_CHAN(insn->chanspec); @@ -3613,7 +3651,7 @@ static int dio_60xx_config_insn(struct comedi_device *dev, } writeb(s->io_bits, - priv(dev)->dio_counter_iobase + DIO_DIRECTION_60XX_REG); + devpriv->dio_counter_iobase + DIO_DIRECTION_60XX_REG); return 1; } @@ -3621,14 +3659,16 @@ static int dio_60xx_config_insn(struct comedi_device *dev, static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; + if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); writeb(s->state, - priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG); + devpriv->dio_counter_iobase + DIO_DATA_60XX_REG); } - data[1] = readb(priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG); + data[1] = readb(devpriv->dio_counter_iobase + DIO_DATA_60XX_REG); return insn->n; } @@ -3636,7 +3676,9 @@ static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s, static void caldac_write(struct comedi_device *dev, unsigned int channel, unsigned int value) { - priv(dev)->caldac_state[channel] = value; + struct pcidas64_private *devpriv = dev->private; + + devpriv->caldac_state[channel] = value; switch (board(dev)->layout) { case LAYOUT_60XX: @@ -3655,11 +3697,12 @@ static int calib_write_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; int channel = CR_CHAN(insn->chanspec); /* return immediately if setting hasn't changed, since * programming these things is slow */ - if (priv(dev)->caldac_state[channel] == data[0]) + if (devpriv->caldac_state[channel] == data[0]) return 1; caldac_write(dev, channel, data[0]); @@ -3671,9 +3714,10 @@ static int calib_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; unsigned int channel = CR_CHAN(insn->chanspec); - data[0] = priv(dev)->caldac_state[channel]; + data[0] = devpriv->caldac_state[channel]; return 1; } @@ -3681,16 +3725,17 @@ static int calib_read_insn(struct comedi_device *dev, static void ad8402_write(struct comedi_device *dev, unsigned int channel, unsigned int value) { + struct pcidas64_private *devpriv = dev->private; static const int bitstream_length = 10; unsigned int bit, register_bits; unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff); static const int ad8402_udelay = 1; - priv(dev)->ad8402_state[channel] = value; + devpriv->ad8402_state[channel] = value; register_bits = SELECT_8402_64XX_BIT; udelay(ad8402_udelay); - writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG); + writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { if (bitstream & bit) @@ -3698,14 +3743,14 @@ static void ad8402_write(struct comedi_device *dev, unsigned int channel, else register_bits &= ~SERIAL_DATA_IN_BIT; udelay(ad8402_udelay); - writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG); + writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); udelay(ad8402_udelay); writew(register_bits | SERIAL_CLOCK_BIT, - priv(dev)->main_iobase + CALIBRATION_REG); + devpriv->main_iobase + CALIBRATION_REG); } udelay(ad8402_udelay); - writew(0, priv(dev)->main_iobase + CALIBRATION_REG); + writew(0, devpriv->main_iobase + CALIBRATION_REG); } /* for pci-das6402/16, channel 0 is analog input gain and channel 1 is offset */ @@ -3713,14 +3758,15 @@ static int ad8402_write_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; int channel = CR_CHAN(insn->chanspec); /* return immediately if setting hasn't changed, since * programming these things is slow */ - if (priv(dev)->ad8402_state[channel] == data[0]) + if (devpriv->ad8402_state[channel] == data[0]) return 1; - priv(dev)->ad8402_state[channel] = data[0]; + devpriv->ad8402_state[channel] = data[0]; ad8402_write(dev, channel, data[0]); @@ -3731,62 +3777,64 @@ static int ad8402_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcidas64_private *devpriv = dev->private; unsigned int channel = CR_CHAN(insn->chanspec); - data[0] = priv(dev)->ad8402_state[channel]; + data[0] = devpriv->ad8402_state[channel]; return 1; } static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address) { + struct pcidas64_private *devpriv = dev->private; static const int bitstream_length = 11; static const int read_command = 0x6; unsigned int bitstream = (read_command << 8) | address; unsigned int bit; void __iomem * const plx_control_addr = - priv(dev)->plx9080_iobase + PLX_CONTROL_REG; + devpriv->plx9080_iobase + PLX_CONTROL_REG; uint16_t value; static const int value_length = 16; static const int eeprom_udelay = 1; udelay(eeprom_udelay); - priv(dev)->plx_control_bits &= ~CTL_EE_CLK & ~CTL_EE_CS; + devpriv->plx_control_bits &= ~CTL_EE_CLK & ~CTL_EE_CS; /* make sure we don't send anything to the i2c bus on 4020 */ - priv(dev)->plx_control_bits |= CTL_USERO; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits |= CTL_USERO; + writel(devpriv->plx_control_bits, plx_control_addr); /* activate serial eeprom */ udelay(eeprom_udelay); - priv(dev)->plx_control_bits |= CTL_EE_CS; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits |= CTL_EE_CS; + writel(devpriv->plx_control_bits, plx_control_addr); /* write read command and desired memory address */ for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { /* set bit to be written */ udelay(eeprom_udelay); if (bitstream & bit) - priv(dev)->plx_control_bits |= CTL_EE_W; + devpriv->plx_control_bits |= CTL_EE_W; else - priv(dev)->plx_control_bits &= ~CTL_EE_W; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits &= ~CTL_EE_W; + writel(devpriv->plx_control_bits, plx_control_addr); /* clock in bit */ udelay(eeprom_udelay); - priv(dev)->plx_control_bits |= CTL_EE_CLK; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits |= CTL_EE_CLK; + writel(devpriv->plx_control_bits, plx_control_addr); udelay(eeprom_udelay); - priv(dev)->plx_control_bits &= ~CTL_EE_CLK; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits &= ~CTL_EE_CLK; + writel(devpriv->plx_control_bits, plx_control_addr); } /* read back value from eeprom memory location */ value = 0; for (bit = 1 << (value_length - 1); bit; bit >>= 1) { /* clock out bit */ udelay(eeprom_udelay); - priv(dev)->plx_control_bits |= CTL_EE_CLK; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits |= CTL_EE_CLK; + writel(devpriv->plx_control_bits, plx_control_addr); udelay(eeprom_udelay); - priv(dev)->plx_control_bits &= ~CTL_EE_CLK; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits &= ~CTL_EE_CLK; + writel(devpriv->plx_control_bits, plx_control_addr); udelay(eeprom_udelay); if (readl(plx_control_addr) & CTL_EE_R) value |= bit; @@ -3794,8 +3842,8 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address) /* deactivate eeprom serial input */ udelay(eeprom_udelay); - priv(dev)->plx_control_bits &= ~CTL_EE_CS; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits &= ~CTL_EE_CS; + writel(devpriv->plx_control_bits, plx_control_addr); return value; } @@ -3911,7 +3959,9 @@ static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples) /* query length of fifo */ static unsigned int ai_fifo_size(struct comedi_device *dev) { - return priv(dev)->ai_fifo_segment_length * + struct pcidas64_private *devpriv = dev->private; + + return devpriv->ai_fifo_segment_length * board(dev)->ai_fifo->num_segments * board(dev)->ai_fifo->sample_packing_ratio; } @@ -3919,6 +3969,7 @@ static unsigned int ai_fifo_size(struct comedi_device *dev) static int set_ai_fifo_segment_length(struct comedi_device *dev, unsigned int num_entries) { + struct pcidas64_private *devpriv = dev->private; static const int increment_size = 0x100; const struct hw_fifo_info *const fifo = board(dev)->ai_fifo; unsigned int num_increments; @@ -3933,17 +3984,17 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev, num_increments = (num_entries + increment_size / 2) / increment_size; bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask; - priv(dev)->fifo_size_bits &= ~fifo->fifo_size_reg_mask; - priv(dev)->fifo_size_bits |= bits; - writew(priv(dev)->fifo_size_bits, - priv(dev)->main_iobase + FIFO_SIZE_REG); + devpriv->fifo_size_bits &= ~fifo->fifo_size_reg_mask; + devpriv->fifo_size_bits |= bits; + writew(devpriv->fifo_size_bits, + devpriv->main_iobase + FIFO_SIZE_REG); - priv(dev)->ai_fifo_segment_length = num_increments * increment_size; + devpriv->ai_fifo_segment_length = num_increments * increment_size; DEBUG_PRINT("set hardware fifo segment length to %i\n", - priv(dev)->ai_fifo_segment_length); + devpriv->ai_fifo_segment_length); - return priv(dev)->ai_fifo_segment_length; + return devpriv->ai_fifo_segment_length; } /* pci-6025 8800 caldac: @@ -3970,6 +4021,7 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev, static int caldac_8800_write(struct comedi_device *dev, unsigned int address, uint8_t value) { + struct pcidas64_private *devpriv = dev->private; static const int num_caldac_channels = 8; static const int bitstream_length = 11; unsigned int bitstream = ((address & 0x7) << 8) | value; @@ -3985,15 +4037,15 @@ static int caldac_8800_write(struct comedi_device *dev, unsigned int address, if (bitstream & bit) register_bits |= SERIAL_DATA_IN_BIT; udelay(caldac_8800_udelay); - writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG); + writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); register_bits |= SERIAL_CLOCK_BIT; udelay(caldac_8800_udelay); - writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG); + writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); } udelay(caldac_8800_udelay); - writew(SELECT_8800_BIT, priv(dev)->main_iobase + CALIBRATION_REG); + writew(SELECT_8800_BIT, devpriv->main_iobase + CALIBRATION_REG); udelay(caldac_8800_udelay); - writew(0, priv(dev)->main_iobase + CALIBRATION_REG); + writew(0, devpriv->main_iobase + CALIBRATION_REG); udelay(caldac_8800_udelay); return 0; } @@ -4066,19 +4118,20 @@ static const int i2c_low_udelay = 10; /* set i2c data line high or low */ static void i2c_set_sda(struct comedi_device *dev, int state) { + struct pcidas64_private *devpriv = dev->private; static const int data_bit = CTL_EE_W; - void __iomem *plx_control_addr = priv(dev)->plx9080_iobase + + void __iomem *plx_control_addr = devpriv->plx9080_iobase + PLX_CONTROL_REG; if (state) { /* set data line high */ - priv(dev)->plx_control_bits &= ~data_bit; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits &= ~data_bit; + writel(devpriv->plx_control_bits, plx_control_addr); udelay(i2c_high_udelay); } else { /* set data line low */ - priv(dev)->plx_control_bits |= data_bit; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits |= data_bit; + writel(devpriv->plx_control_bits, plx_control_addr); udelay(i2c_low_udelay); } } @@ -4086,19 +4139,20 @@ static void i2c_set_sda(struct comedi_device *dev, int state) /* set i2c clock line high or low */ static void i2c_set_scl(struct comedi_device *dev, int state) { + struct pcidas64_private *devpriv = dev->private; static const int clock_bit = CTL_USERO; - void __iomem *plx_control_addr = priv(dev)->plx9080_iobase + + void __iomem *plx_control_addr = devpriv->plx9080_iobase + PLX_CONTROL_REG; if (state) { /* set clock line high */ - priv(dev)->plx_control_bits &= ~clock_bit; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits &= ~clock_bit; + writel(devpriv->plx_control_bits, plx_control_addr); udelay(i2c_high_udelay); } else { /* set clock line low */ - priv(dev)->plx_control_bits |= clock_bit; - writel(priv(dev)->plx_control_bits, plx_control_addr); + devpriv->plx_control_bits |= clock_bit; + writel(devpriv->plx_control_bits, plx_control_addr); udelay(i2c_low_udelay); } } @@ -4150,6 +4204,7 @@ static void i2c_stop(struct comedi_device *dev) static void i2c_write(struct comedi_device *dev, unsigned int address, const uint8_t *data, unsigned int length) { + struct pcidas64_private *devpriv = dev->private; unsigned int i; uint8_t bitstream; static const int read_bit = 0x1; @@ -4157,7 +4212,7 @@ static void i2c_write(struct comedi_device *dev, unsigned int address, /* XXX need mutex to prevent simultaneous attempts to access eeprom and i2c bus */ /* make sure we dont send anything to eeprom */ - priv(dev)->plx_control_bits &= ~CTL_EE_CS; + devpriv->plx_control_bits &= ~CTL_EE_CS; i2c_stop(dev); i2c_start(dev); -- cgit v1.2.3 From aa3d94732f80d65a0d0a8a1eef6a0c1d291002bc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 15 Oct 2012 10:13:50 -0700 Subject: staging: comedi: gsc_hpdi: remove inline priv() function The inline priv() function simply returns the dev->private pointer to the private data. Remove the inline function and just use a local variable where the private data is used. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 258 ++++++++++++++++-------------- 1 file changed, 136 insertions(+), 122 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 517ba3a40fe..550f458cb59 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -244,27 +244,24 @@ struct hpdi_private { unsigned dio_config_output:1; }; -static inline struct hpdi_private *priv(struct comedi_device *dev) -{ - return dev->private; -} - static int dio_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct hpdi_private *devpriv = dev->private; + switch (data[0]) { case INSN_CONFIG_DIO_OUTPUT: - priv(dev)->dio_config_output = 1; + devpriv->dio_config_output = 1; return insn->n; break; case INSN_CONFIG_DIO_INPUT: - priv(dev)->dio_config_output = 0; + devpriv->dio_config_output = 0; return insn->n; break; case INSN_CONFIG_DIO_QUERY: data[1] = - priv(dev)->dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT; + devpriv->dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT; return insn->n; break; case INSN_CONFIG_BLOCK_SIZE: @@ -279,21 +276,24 @@ static int dio_config_insn(struct comedi_device *dev, static void disable_plx_interrupts(struct comedi_device *dev) { - writel(0, priv(dev)->plx9080_iobase + PLX_INTRCS_REG); + struct hpdi_private *devpriv = dev->private; + + writel(0, devpriv->plx9080_iobase + PLX_INTRCS_REG); } /* initialize plx9080 chip */ static void init_plx9080(struct comedi_device *dev) { + struct hpdi_private *devpriv = dev->private; uint32_t bits; - void __iomem *plx_iobase = priv(dev)->plx9080_iobase; + void __iomem *plx_iobase = devpriv->plx9080_iobase; /* plx9080 dump */ DEBUG_PRINT(" plx interrupt status 0x%x\n", readl(plx_iobase + PLX_INTRCS_REG)); DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG)); DEBUG_PRINT(" plx control reg 0x%x\n", - readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG)); + readl(devpriv->plx9080_iobase + PLX_CONTROL_REG)); DEBUG_PRINT(" plx revision 0x%x\n", readl(plx_iobase + PLX_REVISION_REG)); @@ -319,7 +319,7 @@ static void init_plx9080(struct comedi_device *dev) #else bits = 0; #endif - writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG); + writel(bits, devpriv->plx9080_iobase + PLX_BIGEND_REG); disable_plx_interrupts(dev); @@ -380,28 +380,29 @@ static int setup_subdevices(struct comedi_device *dev) static int init_hpdi(struct comedi_device *dev) { + struct hpdi_private *devpriv = dev->private; uint32_t plx_intcsr_bits; - writel(BOARD_RESET_BIT, priv(dev)->hpdi_iobase + BOARD_CONTROL_REG); + writel(BOARD_RESET_BIT, devpriv->hpdi_iobase + BOARD_CONTROL_REG); udelay(10); writel(almost_empty_bits(32) | almost_full_bits(32), - priv(dev)->hpdi_iobase + RX_PROG_ALMOST_REG); + devpriv->hpdi_iobase + RX_PROG_ALMOST_REG); writel(almost_empty_bits(32) | almost_full_bits(32), - priv(dev)->hpdi_iobase + TX_PROG_ALMOST_REG); + devpriv->hpdi_iobase + TX_PROG_ALMOST_REG); - priv(dev)->tx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase + + devpriv->tx_fifo_size = fifo_size(readl(devpriv->hpdi_iobase + TX_FIFO_SIZE_REG)); - priv(dev)->rx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase + + devpriv->rx_fifo_size = fifo_size(readl(devpriv->hpdi_iobase + RX_FIFO_SIZE_REG)); - writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG); + writel(0, devpriv->hpdi_iobase + INTERRUPT_CONTROL_REG); /* enable interrupts */ plx_intcsr_bits = ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE | ICS_DMA0_E; - writel(plx_intcsr_bits, priv(dev)->plx9080_iobase + PLX_INTRCS_REG); + writel(plx_intcsr_bits, devpriv->plx9080_iobase + PLX_INTRCS_REG); return 0; } @@ -410,6 +411,7 @@ static int init_hpdi(struct comedi_device *dev) static int setup_dma_descriptors(struct comedi_device *dev, unsigned int transfer_size) { + struct hpdi_private *devpriv = dev->private; unsigned int buffer_index, buffer_offset; uint32_t next_bits = PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI; @@ -423,25 +425,25 @@ static int setup_dma_descriptors(struct comedi_device *dev, DEBUG_PRINT(" transfer_size %i\n", transfer_size); DEBUG_PRINT(" descriptors at 0x%lx\n", - (unsigned long)priv(dev)->dma_desc_phys_addr); + (unsigned long)devpriv->dma_desc_phys_addr); buffer_offset = 0; buffer_index = 0; for (i = 0; i < NUM_DMA_DESCRIPTORS && buffer_index < NUM_DMA_BUFFERS; i++) { - priv(dev)->dma_desc[i].pci_start_addr = - cpu_to_le32(priv(dev)->dio_buffer_phys_addr[buffer_index] + + devpriv->dma_desc[i].pci_start_addr = + cpu_to_le32(devpriv->dio_buffer_phys_addr[buffer_index] + buffer_offset); - priv(dev)->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG); - priv(dev)->dma_desc[i].transfer_size = + devpriv->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG); + devpriv->dma_desc[i].transfer_size = cpu_to_le32(transfer_size); - priv(dev)->dma_desc[i].next = - cpu_to_le32((priv(dev)->dma_desc_phys_addr + (i + + devpriv->dma_desc[i].next = + cpu_to_le32((devpriv->dma_desc_phys_addr + (i + 1) * - sizeof(priv(dev)->dma_desc[0])) | next_bits); + sizeof(devpriv->dma_desc[0])) | next_bits); - priv(dev)->desc_dio_buffer[i] = - priv(dev)->dio_buffer[buffer_index] + + devpriv->desc_dio_buffer[i] = + devpriv->dio_buffer[buffer_index] + (buffer_offset / sizeof(uint32_t)); buffer_offset += transfer_size; @@ -452,34 +454,37 @@ static int setup_dma_descriptors(struct comedi_device *dev, DEBUG_PRINT(" desc %i\n", i); DEBUG_PRINT(" start addr virt 0x%p, phys 0x%lx\n", - priv(dev)->desc_dio_buffer[i], - (unsigned long)priv(dev)->dma_desc[i]. + devpriv->desc_dio_buffer[i], + (unsigned long)devpriv->dma_desc[i]. pci_start_addr); DEBUG_PRINT(" next 0x%lx\n", - (unsigned long)priv(dev)->dma_desc[i].next); + (unsigned long)devpriv->dma_desc[i].next); } - priv(dev)->num_dma_descriptors = i; + devpriv->num_dma_descriptors = i; /* fix last descriptor to point back to first */ - priv(dev)->dma_desc[i - 1].next = - cpu_to_le32(priv(dev)->dma_desc_phys_addr | next_bits); + devpriv->dma_desc[i - 1].next = + cpu_to_le32(devpriv->dma_desc_phys_addr | next_bits); DEBUG_PRINT(" desc %i next fixup 0x%lx\n", i - 1, - (unsigned long)priv(dev)->dma_desc[i - 1].next); + (unsigned long)devpriv->dma_desc[i - 1].next); - priv(dev)->block_size = transfer_size; + devpriv->block_size = transfer_size; return transfer_size; } static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct hpdi_private *devpriv; struct pci_dev *pcidev; int i; int retval; printk(KERN_WARNING "comedi%d: gsc_hpdi\n", dev->minor); - if (alloc_private(dev, sizeof(struct hpdi_private)) < 0) - return -ENOMEM; + retval = alloc_private(dev, sizeof(*devpriv)); + if (retval) + return retval; + devpriv = dev->private; pcidev = NULL; for (i = 0; i < ARRAY_SIZE(hpdi_boards) && @@ -498,7 +503,7 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) continue; } if (pcidev) { - priv(dev)->hw_dev = pcidev; + devpriv->hw_dev = pcidev; dev->board_ptr = hpdi_boards + i; break; } @@ -523,25 +528,25 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Initialize dev->board_name */ dev->board_name = board(dev)->name; - priv(dev)->plx9080_phys_iobase = + devpriv->plx9080_phys_iobase = pci_resource_start(pcidev, PLX9080_BADDRINDEX); - priv(dev)->hpdi_phys_iobase = + devpriv->hpdi_phys_iobase = pci_resource_start(pcidev, HPDI_BADDRINDEX); /* remap, won't work with 2.0 kernels but who cares */ - priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase, + devpriv->plx9080_iobase = ioremap(devpriv->plx9080_phys_iobase, pci_resource_len(pcidev, PLX9080_BADDRINDEX)); - priv(dev)->hpdi_iobase = - ioremap(priv(dev)->hpdi_phys_iobase, + devpriv->hpdi_iobase = + ioremap(devpriv->hpdi_phys_iobase, pci_resource_len(pcidev, HPDI_BADDRINDEX)); - if (!priv(dev)->plx9080_iobase || !priv(dev)->hpdi_iobase) { + if (!devpriv->plx9080_iobase || !devpriv->hpdi_iobase) { printk(KERN_WARNING " failed to remap io memory\n"); return -ENOMEM; } - DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase); - DEBUG_PRINT(" hpdi remapped to 0x%p\n", priv(dev)->hpdi_iobase); + DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase); + DEBUG_PRINT(" hpdi remapped to 0x%p\n", devpriv->hpdi_iobase); init_plx9080(dev); @@ -558,20 +563,20 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* allocate pci dma buffers */ for (i = 0; i < NUM_DMA_BUFFERS; i++) { - priv(dev)->dio_buffer[i] = - pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE, - &priv(dev)->dio_buffer_phys_addr[i]); + devpriv->dio_buffer[i] = + pci_alloc_consistent(devpriv->hw_dev, DMA_BUFFER_SIZE, + &devpriv->dio_buffer_phys_addr[i]); DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n", - priv(dev)->dio_buffer[i], - (unsigned long)priv(dev)->dio_buffer_phys_addr[i]); + devpriv->dio_buffer[i], + (unsigned long)devpriv->dio_buffer_phys_addr[i]); } /* allocate dma descriptors */ - priv(dev)->dma_desc = pci_alloc_consistent(priv(dev)->hw_dev, + devpriv->dma_desc = pci_alloc_consistent(devpriv->hw_dev, sizeof(struct plx_dma_desc) * NUM_DMA_DESCRIPTORS, - &priv(dev)-> + &devpriv-> dma_desc_phys_addr); - if (priv(dev)->dma_desc_phys_addr & 0xf) { + if (devpriv->dma_desc_phys_addr & 0xf) { printk(KERN_WARNING " dma descriptors not quad-word aligned (bug)\n"); return -EIO; @@ -590,39 +595,36 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void hpdi_detach(struct comedi_device *dev) { + struct hpdi_private *devpriv = dev->private; unsigned int i; if (dev->irq) free_irq(dev->irq, dev); - if ((priv(dev)) && (priv(dev)->hw_dev)) { - if (priv(dev)->plx9080_iobase) { + if (devpriv && devpriv->hw_dev) { + if (devpriv->plx9080_iobase) { disable_plx_interrupts(dev); - iounmap(priv(dev)->plx9080_iobase); + iounmap(devpriv->plx9080_iobase); } - if (priv(dev)->hpdi_iobase) - iounmap(priv(dev)->hpdi_iobase); + if (devpriv->hpdi_iobase) + iounmap(devpriv->hpdi_iobase); /* free pci dma buffers */ for (i = 0; i < NUM_DMA_BUFFERS; i++) { - if (priv(dev)->dio_buffer[i]) - pci_free_consistent(priv(dev)->hw_dev, - DMA_BUFFER_SIZE, - priv(dev)-> - dio_buffer[i], - priv - (dev)->dio_buffer_phys_addr - [i]); + if (devpriv->dio_buffer[i]) + pci_free_consistent(devpriv->hw_dev, + DMA_BUFFER_SIZE, + devpriv->dio_buffer[i], + devpriv->dio_buffer_phys_addr[i]); } /* free dma descriptors */ - if (priv(dev)->dma_desc) - pci_free_consistent(priv(dev)->hw_dev, - sizeof(struct plx_dma_desc) - * NUM_DMA_DESCRIPTORS, - priv(dev)->dma_desc, - priv(dev)-> - dma_desc_phys_addr); - if (priv(dev)->hpdi_phys_iobase) - comedi_pci_disable(priv(dev)->hw_dev); - pci_dev_put(priv(dev)->hw_dev); + if (devpriv->dma_desc) + pci_free_consistent(devpriv->hw_dev, + sizeof(struct plx_dma_desc) * + NUM_DMA_DESCRIPTORS, + devpriv->dma_desc, + devpriv-> dma_desc_phys_addr); + if (devpriv->hpdi_phys_iobase) + comedi_pci_disable(devpriv->hw_dev); + pci_dev_put(devpriv->hw_dev); } } @@ -726,7 +728,9 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - if (priv(dev)->dio_config_output) + struct hpdi_private *devpriv = dev->private; + + if (devpriv->dio_config_output) return -EINVAL; else return di_cmd_test(dev, s, cmd); @@ -735,12 +739,15 @@ static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, static inline void hpdi_writel(struct comedi_device *dev, uint32_t bits, unsigned int offset) { - writel(bits | priv(dev)->bits[offset / sizeof(uint32_t)], - priv(dev)->hpdi_iobase + offset); + struct hpdi_private *devpriv = dev->private; + + writel(bits | devpriv->bits[offset / sizeof(uint32_t)], + devpriv->hpdi_iobase + offset); } static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct hpdi_private *devpriv = dev->private; uint32_t bits; unsigned long flags; struct comedi_async *async = s->async; @@ -752,39 +759,39 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s) abort_dma(dev, 0); - priv(dev)->dma_desc_index = 0; + devpriv->dma_desc_index = 0; /* These register are supposedly unused during chained dma, * but I have found that left over values from last operation * occasionally cause problems with transfer of first dma * block. Initializing them to zero seems to fix the problem. */ - writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG); - writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); - writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG); + writel(0, devpriv->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG); + writel(0, devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); + writel(0, devpriv->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG); /* give location of first dma descriptor */ bits = - priv(dev)->dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT | + devpriv->dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI; - writel(bits, priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); + writel(bits, devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); /* spinlock for plx dma control/status reg */ spin_lock_irqsave(&dev->spinlock, flags); /* enable dma transfer */ writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + devpriv->plx9080_iobase + PLX_DMA0_CS_REG); spin_unlock_irqrestore(&dev->spinlock, flags); if (cmd->stop_src == TRIG_COUNT) - priv(dev)->dio_count = cmd->stop_arg; + devpriv->dio_count = cmd->stop_arg; else - priv(dev)->dio_count = 1; + devpriv->dio_count = 1; /* clear over/under run status flags */ writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT, - priv(dev)->hpdi_iobase + BOARD_STATUS_REG); + devpriv->hpdi_iobase + BOARD_STATUS_REG); /* enable interrupts */ writel(intr_bit(RX_FULL_INTR), - priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG); + devpriv->hpdi_iobase + INTERRUPT_CONTROL_REG); DEBUG_PRINT("hpdi: starting rx\n"); hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG); @@ -794,7 +801,9 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - if (priv(dev)->dio_config_output) + struct hpdi_private *devpriv = dev->private; + + if (devpriv->dio_config_output) return -EINVAL; else return di_cmd(dev, s); @@ -802,6 +811,7 @@ static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) { + struct hpdi_private *devpriv = dev->private; struct comedi_async *async = dev->read_subdev->async; uint32_t next_transfer_addr; int j; @@ -810,37 +820,37 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) if (channel) pci_addr_reg = - priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG; + devpriv->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG; else pci_addr_reg = - priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; + devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; /* loop until we have read all the full buffers */ j = 0; for (next_transfer_addr = readl(pci_addr_reg); (next_transfer_addr < - le32_to_cpu(priv(dev)->dma_desc[priv(dev)->dma_desc_index]. + le32_to_cpu(devpriv->dma_desc[devpriv->dma_desc_index]. pci_start_addr) || next_transfer_addr >= - le32_to_cpu(priv(dev)->dma_desc[priv(dev)->dma_desc_index]. - pci_start_addr) + priv(dev)->block_size) - && j < priv(dev)->num_dma_descriptors; j++) { + le32_to_cpu(devpriv->dma_desc[devpriv->dma_desc_index]. + pci_start_addr) + devpriv->block_size) + && j < devpriv->num_dma_descriptors; j++) { /* transfer data from dma buffer to comedi buffer */ - num_samples = priv(dev)->block_size / sizeof(uint32_t); + num_samples = devpriv->block_size / sizeof(uint32_t); if (async->cmd.stop_src == TRIG_COUNT) { - if (num_samples > priv(dev)->dio_count) - num_samples = priv(dev)->dio_count; - priv(dev)->dio_count -= num_samples; + if (num_samples > devpriv->dio_count) + num_samples = devpriv->dio_count; + devpriv->dio_count -= num_samples; } cfc_write_array_to_buffer(dev->read_subdev, - priv(dev)->desc_dio_buffer[priv(dev)-> + devpriv->desc_dio_buffer[devpriv-> dma_desc_index], num_samples * sizeof(uint32_t)); - priv(dev)->dma_desc_index++; - priv(dev)->dma_desc_index %= priv(dev)->num_dma_descriptors; + devpriv->dma_desc_index++; + devpriv->dma_desc_index %= devpriv->num_dma_descriptors; DEBUG_PRINT("next desc addr 0x%lx\n", (unsigned long) - priv(dev)->dma_desc[priv(dev)->dma_desc_index]. + devpriv->dma_desc[devpriv->dma_desc_index]. next); DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr); } @@ -850,6 +860,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) static irqreturn_t handle_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct hpdi_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; uint32_t hpdi_intr_status, hpdi_board_status; @@ -861,26 +872,26 @@ static irqreturn_t handle_interrupt(int irq, void *d) if (!dev->attached) return IRQ_NONE; - plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG); + plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG); if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0) return IRQ_NONE; - hpdi_intr_status = readl(priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG); - hpdi_board_status = readl(priv(dev)->hpdi_iobase + BOARD_STATUS_REG); + hpdi_intr_status = readl(devpriv->hpdi_iobase + INTERRUPT_STATUS_REG); + hpdi_board_status = readl(devpriv->hpdi_iobase + BOARD_STATUS_REG); async->events = 0; if (hpdi_intr_status) { DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status); writel(hpdi_intr_status, - priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG); + devpriv->hpdi_iobase + INTERRUPT_STATUS_REG); } /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); - dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + dma0_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG); if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */ writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG); + devpriv->plx9080_iobase + PLX_DMA0_CS_REG); DEBUG_PRINT("dma0 status 0x%x\n", dma0_status); if (dma0_status & PLX_DMA_EN_BIT) @@ -891,10 +902,10 @@ static irqreturn_t handle_interrupt(int irq, void *d) /* spin lock makes sure no one else changes plx dma control reg */ spin_lock_irqsave(&dev->spinlock, flags); - dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); + dma1_status = readb(devpriv->plx9080_iobase + PLX_DMA1_CS_REG); if (plx_status & ICS_DMA1_A) { /* XXX *//* dma chan 1 interrupt */ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT, - priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG); + devpriv->plx9080_iobase + PLX_DMA1_CS_REG); DEBUG_PRINT("dma1 status 0x%x\n", dma1_status); DEBUG_PRINT(" cleared dma ch1 interrupt\n"); @@ -903,8 +914,8 @@ static irqreturn_t handle_interrupt(int irq, void *d) /* clear possible plx9080 interrupt sources */ if (plx_status & ICS_LDIA) { /* clear local doorbell interrupt */ - plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG); - writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG); + plx_bits = readl(devpriv->plx9080_iobase + PLX_DBR_OUT_REG); + writel(plx_bits, devpriv->plx9080_iobase + PLX_DBR_OUT_REG); DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits); } @@ -912,7 +923,7 @@ static irqreturn_t handle_interrupt(int irq, void *d) comedi_error(dev, "rx fifo overrun"); async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; DEBUG_PRINT("dma0_status 0x%x\n", - (int)readb(priv(dev)->plx9080_iobase + + (int)readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG)); } @@ -921,7 +932,7 @@ static irqreturn_t handle_interrupt(int irq, void *d) async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; } - if (priv(dev)->dio_count == 0) + if (devpriv->dio_count == 0) async->events |= COMEDI_CB_EOA; DEBUG_PRINT("board status 0x%x, ", hpdi_board_status); @@ -936,21 +947,24 @@ static irqreturn_t handle_interrupt(int irq, void *d) static void abort_dma(struct comedi_device *dev, unsigned int channel) { + struct hpdi_private *devpriv = dev->private; unsigned long flags; /* spinlock for plx dma control/status reg */ spin_lock_irqsave(&dev->spinlock, flags); - plx9080_abort_dma(priv(dev)->plx9080_iobase, channel); + plx9080_abort_dma(devpriv->plx9080_iobase, channel); spin_unlock_irqrestore(&dev->spinlock, flags); } static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct hpdi_private *devpriv = dev->private; + hpdi_writel(dev, 0, BOARD_CONTROL_REG); - writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG); + writel(0, devpriv->hpdi_iobase + INTERRUPT_CONTROL_REG); abort_dma(dev, 0); -- cgit v1.2.3 From 7e6c9bf696fbec8bf73cdee4d9f16b46608cd4c9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 15 Oct 2012 10:14:12 -0700 Subject: staging: comedi: ni_65xx: remove inline private() function The inline private() function simply returns the dev->private pointer to the private data. Remove the inline function and just use a local variable where the private data is used. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_65xx.c | 120 ++++++++++++++++--------------- 1 file changed, 63 insertions(+), 57 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 2a73ff57a2f..1881f334625 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -291,11 +291,6 @@ struct ni_65xx_private { unsigned short dio_direction[NI_65XX_MAX_NUM_PORTS]; }; -static inline struct ni_65xx_private *private(struct comedi_device *dev) -{ - return dev->private; -} - struct ni_65xx_subdevice_private { unsigned base_port; }; @@ -319,6 +314,7 @@ static int ni_65xx_config_filter(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_65xx_private *devpriv = dev->private; const unsigned chan = CR_CHAN(insn->chanspec); const unsigned port = sprivate(s)->base_port + ni_65xx_port_by_channel(chan); @@ -335,22 +331,22 @@ static int ni_65xx_config_filter(struct comedi_device *dev, interval = max_filter_interval; data[1] = interval * filter_resolution_ns; - if (interval != private(dev)->filter_interval) { + if (interval != devpriv->filter_interval) { writeb(interval, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Filter_Interval); - private(dev)->filter_interval = interval; + devpriv->filter_interval = interval; } - private(dev)->filter_enable[port] |= + devpriv->filter_enable[port] |= 1 << (chan % ni_65xx_channels_per_port); } else { - private(dev)->filter_enable[port] &= + devpriv->filter_enable[port] &= ~(1 << (chan % ni_65xx_channels_per_port)); } - writeb(private(dev)->filter_enable[port], - private(dev)->mite->daq_io_addr + Filter_Enable(port)); + writeb(devpriv->filter_enable[port], + devpriv->mite->daq_io_addr + Filter_Enable(port)); return 2; } @@ -359,6 +355,7 @@ static int ni_65xx_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_65xx_private *devpriv = dev->private; unsigned port; if (insn->n < 1) @@ -372,21 +369,21 @@ static int ni_65xx_dio_insn_config(struct comedi_device *dev, case INSN_CONFIG_DIO_OUTPUT: if (s->type != COMEDI_SUBD_DIO) return -EINVAL; - private(dev)->dio_direction[port] = COMEDI_OUTPUT; - writeb(0, private(dev)->mite->daq_io_addr + Port_Select(port)); + devpriv->dio_direction[port] = COMEDI_OUTPUT; + writeb(0, devpriv->mite->daq_io_addr + Port_Select(port)); return 1; break; case INSN_CONFIG_DIO_INPUT: if (s->type != COMEDI_SUBD_DIO) return -EINVAL; - private(dev)->dio_direction[port] = COMEDI_INPUT; - writeb(1, private(dev)->mite->daq_io_addr + Port_Select(port)); + devpriv->dio_direction[port] = COMEDI_INPUT; + writeb(1, devpriv->mite->daq_io_addr + Port_Select(port)); return 1; break; case INSN_CONFIG_DIO_QUERY: if (s->type != COMEDI_SUBD_DIO) return -EINVAL; - data[1] = private(dev)->dio_direction[port]; + data[1] = devpriv->dio_direction[port]; return insn->n; break; default: @@ -399,6 +396,7 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_65xx_private *devpriv = dev->private; unsigned base_bitfield_channel; const unsigned max_ports_per_bitfield = 5; unsigned read_bits = 0; @@ -432,18 +430,18 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, port_data &= 0xff; if (port_mask) { unsigned bits; - private(dev)->output_bits[port] &= ~port_mask; - private(dev)->output_bits[port] |= + devpriv->output_bits[port] &= ~port_mask; + devpriv->output_bits[port] |= port_data & port_mask; - bits = private(dev)->output_bits[port]; + bits = devpriv->output_bits[port]; if (board(dev)->invert_outputs) bits = ~bits; writeb(bits, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Port_Data(port)); } port_read_bits = - readb(private(dev)->mite->daq_io_addr + Port_Data(port)); + readb(devpriv->mite->daq_io_addr + Port_Data(port)); if (s->type == COMEDI_SUBD_DO && board(dev)->invert_outputs) { /* Outputs inverted, so invert value read back from * DO subdevice. (Does not apply to boards with DIO @@ -464,17 +462,18 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, static irqreturn_t ni_65xx_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct ni_65xx_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[2]; unsigned int status; - status = readb(private(dev)->mite->daq_io_addr + Change_Status); + status = readb(devpriv->mite->daq_io_addr + Change_Status); if ((status & MasterInterruptStatus) == 0) return IRQ_NONE; if ((status & EdgeStatus) == 0) return IRQ_NONE; writeb(ClrEdge | ClrOverflow, - private(dev)->mite->daq_io_addr + Clear_Register); + devpriv->mite->daq_io_addr + Clear_Register); comedi_buf_put(s->async, 0); s->async->events |= COMEDI_CB_EOS; @@ -543,13 +542,14 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev, static int ni_65xx_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_65xx_private *devpriv = dev->private; /* struct comedi_cmd *cmd = &s->async->cmd; */ writeb(ClrEdge | ClrOverflow, - private(dev)->mite->daq_io_addr + Clear_Register); + devpriv->mite->daq_io_addr + Clear_Register); writeb(FallingEdgeIntEnable | RisingEdgeIntEnable | MasterInterruptEnable | EdgeIntEnable, - private(dev)->mite->daq_io_addr + Master_Interrupt_Control); + devpriv->mite->daq_io_addr + Master_Interrupt_Control); return 0; } @@ -557,8 +557,9 @@ static int ni_65xx_intr_cmd(struct comedi_device *dev, static int ni_65xx_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { - writeb(0x00, - private(dev)->mite->daq_io_addr + Master_Interrupt_Control); + struct ni_65xx_private *devpriv = dev->private; + + writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control); return 0; } @@ -576,35 +577,37 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct ni_65xx_private *devpriv = dev->private; + if (insn->n < 1) return -EINVAL; if (data[0] != INSN_CONFIG_CHANGE_NOTIFY) return -EINVAL; writeb(data[1], - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0)); writeb(data[1] >> 8, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0x10)); writeb(data[1] >> 16, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0x20)); writeb(data[1] >> 24, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0x30)); writeb(data[2], - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0)); writeb(data[2] >> 8, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0x10)); writeb(data[2] >> 16, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0x20)); writeb(data[2] >> 24, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0x30)); return 2; @@ -627,32 +630,34 @@ ni_65xx_find_boardinfo(struct pci_dev *pcidev) static int __devinit ni_65xx_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { + struct ni_65xx_private *devpriv; struct comedi_subdevice *s; unsigned i; int ret; - ret = alloc_private(dev, sizeof(struct ni_65xx_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; dev->board_ptr = ni_65xx_find_boardinfo(pcidev); if (!dev->board_ptr) return -ENODEV; - private(dev)->mite = mite_alloc(pcidev); - if (!private(dev)->mite) + devpriv->mite = mite_alloc(pcidev); + if (!devpriv->mite) return -ENOMEM; - ret = mite_setup(private(dev)->mite); + ret = mite_setup(devpriv->mite); if (ret < 0) { dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } dev->board_name = board(dev)->name; - dev->irq = mite_irq(private(dev)->mite); + dev->irq = mite_irq(devpriv->mite); dev_info(dev->class_dev, "board: %s, ID=0x%02x", dev->board_name, - readb(private(dev)->mite->daq_io_addr + ID_Register)); + readb(devpriv->mite->daq_io_addr + ID_Register)); ret = comedi_alloc_subdevices(dev, 4); if (ret) @@ -710,7 +715,7 @@ static int __devinit ni_65xx_attach_pci(struct comedi_device *dev, for (i = 0; i < board(dev)->num_dio_ports; ++i) { /* configure all ports for input */ writeb(0x1, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Port_Select(i)); } } else { @@ -732,21 +737,21 @@ static int __devinit ni_65xx_attach_pci(struct comedi_device *dev, for (i = 0; i < ni_65xx_total_num_ports(board(dev)); ++i) { writeb(0x00, - private(dev)->mite->daq_io_addr + Filter_Enable(i)); + devpriv->mite->daq_io_addr + Filter_Enable(i)); if (board(dev)->invert_outputs) writeb(0x01, - private(dev)->mite->daq_io_addr + Port_Data(i)); + devpriv->mite->daq_io_addr + Port_Data(i)); else writeb(0x00, - private(dev)->mite->daq_io_addr + Port_Data(i)); + devpriv->mite->daq_io_addr + Port_Data(i)); } writeb(ClrEdge | ClrOverflow, - private(dev)->mite->daq_io_addr + Clear_Register); + devpriv->mite->daq_io_addr + Clear_Register); writeb(0x00, - private(dev)->mite->daq_io_addr + Master_Interrupt_Control); + devpriv->mite->daq_io_addr + Master_Interrupt_Control); /* Set filter interval to 0 (32bit reg) */ - writeb(0x00000000, private(dev)->mite->daq_io_addr + Filter_Interval); + writeb(0x00000000, devpriv->mite->daq_io_addr + Filter_Interval); ret = request_irq(dev->irq, ni_65xx_interrupt, IRQF_SHARED, "ni_65xx", dev); @@ -760,15 +765,16 @@ static int __devinit ni_65xx_attach_pci(struct comedi_device *dev, static void ni_65xx_detach(struct comedi_device *dev) { - if (private(dev) && private(dev)->mite - && private(dev)->mite->daq_io_addr) { + struct ni_65xx_private *devpriv = dev->private; + + if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) { writeb(0x00, - private(dev)->mite->daq_io_addr + + devpriv->mite->daq_io_addr + Master_Interrupt_Control); } if (dev->irq) free_irq(dev->irq, dev); - if (private(dev)) { + if (devpriv) { struct comedi_subdevice *s; unsigned i; @@ -777,9 +783,9 @@ static void ni_65xx_detach(struct comedi_device *dev) kfree(s->private); s->private = NULL; } - if (private(dev)->mite) { - mite_unsetup(private(dev)->mite); - mite_free(private(dev)->mite); + if (devpriv->mite) { + mite_unsetup(devpriv->mite); + mite_free(devpriv->mite); } } } -- cgit v1.2.3 From 8c12ec2616d18e9c6f6a6884a8738586be5a15d9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 15 Oct 2012 10:14:32 -0700 Subject: staging: comedi: ni_660x: remove inline private() function The inline private() function simply returns the dev->private pointer to the private data. Remove the inline function and just use a local variable where the private data is used. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 164 +++++++++++++++++-------------- 1 file changed, 90 insertions(+), 74 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index df2f3b0bab4..d8684072744 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -443,11 +443,6 @@ struct ni_660x_private { unsigned short pfi_output_selects[NUM_PFI_CHANNELS]; }; -static inline struct ni_660x_private *private(struct comedi_device *dev) -{ - return dev->private; -} - /* initialized in ni_660x_attach_pci() */ static inline const struct ni_660x_board *board(struct comedi_device *dev) { @@ -737,8 +732,9 @@ static inline void ni_660x_write_register(struct comedi_device *dev, unsigned chip_index, unsigned bits, enum NI_660x_Register reg) { + struct ni_660x_private *devpriv = dev->private; void __iomem *write_address = - private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] + + devpriv->mite->daq_io_addr + GPCT_OFFSET[chip_index] + registerData[reg].offset; switch (registerData[reg].size) { @@ -758,8 +754,9 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev, unsigned chip_index, enum NI_660x_Register reg) { + struct ni_660x_private *devpriv = dev->private; void __iomem *read_address = - private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] + + devpriv->mite->daq_io_addr + GPCT_OFFSET[chip_index] + registerData[reg].offset; switch (registerData[reg].size) { @@ -806,54 +803,56 @@ static inline void ni_660x_set_dma_channel(struct comedi_device *dev, unsigned mite_channel, struct ni_gpct *counter) { + struct ni_660x_private *devpriv = dev->private; unsigned long flags; - spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags); - private(dev)->dma_configuration_soft_copies[counter->chip_index] &= + + spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); + devpriv->dma_configuration_soft_copies[counter->chip_index] &= ~dma_select_mask(mite_channel); - private(dev)->dma_configuration_soft_copies[counter->chip_index] |= + devpriv->dma_configuration_soft_copies[counter->chip_index] |= dma_select_bits(mite_channel, dma_selection_counter(counter->counter_index)); ni_660x_write_register(dev, counter->chip_index, - private(dev)-> - dma_configuration_soft_copies + devpriv->dma_configuration_soft_copies [counter->chip_index] | dma_reset_bit(mite_channel), DMAConfigRegister); mmiowb(); - spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags); + spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); } static inline void ni_660x_unset_dma_channel(struct comedi_device *dev, unsigned mite_channel, struct ni_gpct *counter) { + struct ni_660x_private *devpriv = dev->private; unsigned long flags; - spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags); - private(dev)->dma_configuration_soft_copies[counter->chip_index] &= + + spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); + devpriv->dma_configuration_soft_copies[counter->chip_index] &= ~dma_select_mask(mite_channel); - private(dev)->dma_configuration_soft_copies[counter->chip_index] |= + devpriv->dma_configuration_soft_copies[counter->chip_index] |= dma_select_bits(mite_channel, dma_selection_none); ni_660x_write_register(dev, counter->chip_index, - private(dev)-> - dma_configuration_soft_copies + devpriv->dma_configuration_soft_copies [counter->chip_index], DMAConfigRegister); mmiowb(); - spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags); + spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags); } static int ni_660x_request_mite_channel(struct comedi_device *dev, struct ni_gpct *counter, enum comedi_io_direction direction) { + struct ni_660x_private *devpriv = dev->private; unsigned long flags; struct mite_channel *mite_chan; - spin_lock_irqsave(&private(dev)->mite_channel_lock, flags); + spin_lock_irqsave(&devpriv->mite_channel_lock, flags); BUG_ON(counter->mite_chan); - mite_chan = - mite_request_channel(private(dev)->mite, mite_ring(private(dev), - counter)); + mite_chan = mite_request_channel(devpriv->mite, + mite_ring(devpriv, counter)); if (mite_chan == NULL) { - spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags); + spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); comedi_error(dev, "failed to reserve mite dma channel for counter."); return -EBUSY; @@ -861,16 +860,17 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev, mite_chan->dir = direction; ni_tio_set_mite_channel(counter, mite_chan); ni_660x_set_dma_channel(dev, mite_chan->channel, counter); - spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags); + spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); return 0; } static void ni_660x_release_mite_channel(struct comedi_device *dev, struct ni_gpct *counter) { + struct ni_660x_private *devpriv = dev->private; unsigned long flags; - spin_lock_irqsave(&private(dev)->mite_channel_lock, flags); + spin_lock_irqsave(&devpriv->mite_channel_lock, flags); if (counter->mite_chan) { struct mite_channel *mite_chan = counter->mite_chan; @@ -878,7 +878,7 @@ static void ni_660x_release_mite_channel(struct comedi_device *dev, ni_tio_set_mite_channel(counter, NULL); mite_release_channel(mite_chan); } - spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags); + spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags); } static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s) @@ -947,6 +947,7 @@ static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev, static irqreturn_t ni_660x_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct ni_660x_private *devpriv = dev->private; struct comedi_subdevice *s; unsigned i; unsigned long flags; @@ -954,24 +955,26 @@ static irqreturn_t ni_660x_interrupt(int irq, void *d) if (dev->attached == 0) return IRQ_NONE; /* lock to avoid race with comedi_poll */ - spin_lock_irqsave(&private(dev)->interrupt_lock, flags); + spin_lock_irqsave(&devpriv->interrupt_lock, flags); smp_mb(); for (i = 0; i < ni_660x_num_counters(dev); ++i) { s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; ni_660x_handle_gpct_interrupt(dev, s); } - spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags); + spin_unlock_irqrestore(&devpriv->interrupt_lock, flags); return IRQ_HANDLED; } static int ni_660x_input_poll(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_660x_private *devpriv = dev->private; unsigned long flags; + /* lock to avoid race with comedi_poll */ - spin_lock_irqsave(&private(dev)->interrupt_lock, flags); + spin_lock_irqsave(&devpriv->interrupt_lock, flags); mite_sync_input_dma(subdev_to_counter(s)->mite_chan, s->async); - spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags); + spin_unlock_irqrestore(&devpriv->interrupt_lock, flags); return comedi_buf_read_n_available(s->async); } @@ -979,9 +982,10 @@ static int ni_660x_buf_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct ni_660x_private *devpriv = dev->private; int ret; - ret = mite_buf_change(mite_ring(private(dev), subdev_to_counter(s)), + ret = mite_buf_change(mite_ring(devpriv, subdev_to_counter(s)), s->async); if (ret < 0) return ret; @@ -991,32 +995,35 @@ static int ni_660x_buf_change(struct comedi_device *dev, static int ni_660x_allocate_private(struct comedi_device *dev) { + struct ni_660x_private *devpriv; int retval; unsigned i; - retval = alloc_private(dev, sizeof(struct ni_660x_private)); - if (retval < 0) + retval = alloc_private(dev, sizeof(*devpriv)); + if (retval) return retval; + devpriv = dev->private; - spin_lock_init(&private(dev)->mite_channel_lock); - spin_lock_init(&private(dev)->interrupt_lock); - spin_lock_init(&private(dev)->soft_reg_copy_lock); + spin_lock_init(&devpriv->mite_channel_lock); + spin_lock_init(&devpriv->interrupt_lock); + spin_lock_init(&devpriv->soft_reg_copy_lock); for (i = 0; i < NUM_PFI_CHANNELS; ++i) - private(dev)->pfi_output_selects[i] = pfi_output_select_counter; + devpriv->pfi_output_selects[i] = pfi_output_select_counter; return 0; } static int ni_660x_alloc_mite_rings(struct comedi_device *dev) { + struct ni_660x_private *devpriv = dev->private; unsigned i; unsigned j; for (i = 0; i < board(dev)->n_chips; ++i) { for (j = 0; j < counters_per_chip; ++j) { - private(dev)->mite_rings[i][j] = - mite_alloc_ring(private(dev)->mite); - if (private(dev)->mite_rings[i][j] == NULL) + devpriv->mite_rings[i][j] = + mite_alloc_ring(devpriv->mite); + if (devpriv->mite_rings[i][j] == NULL) return -ENOMEM; } } @@ -1025,12 +1032,13 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev) static void ni_660x_free_mite_rings(struct comedi_device *dev) { + struct ni_660x_private *devpriv = dev->private; unsigned i; unsigned j; for (i = 0; i < board(dev)->n_chips; ++i) { for (j = 0; j < counters_per_chip; ++j) - mite_free_ring(private(dev)->mite_rings[i][j]); + mite_free_ring(devpriv->mite_rings[i][j]); } } @@ -1051,6 +1059,7 @@ ni_660x_find_boardinfo(struct pci_dev *pcidev) static int __devinit ni_660x_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { + struct ni_660x_private *devpriv; struct comedi_subdevice *s; int ret; unsigned i; @@ -1059,21 +1068,23 @@ static int __devinit ni_660x_attach_pci(struct comedi_device *dev, ret = ni_660x_allocate_private(dev); if (ret < 0) return ret; + devpriv = dev->private; + dev->board_ptr = ni_660x_find_boardinfo(pcidev); if (!dev->board_ptr) return -ENODEV; - private(dev)->mite = mite_alloc(pcidev); - if (!private(dev)->mite) + devpriv->mite = mite_alloc(pcidev); + if (!devpriv->mite) return -ENOMEM; dev->board_name = board(dev)->name; - ret = mite_setup2(private(dev)->mite, 1); + ret = mite_setup2(devpriv->mite, 1); if (ret < 0) { dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } - comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev); + comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev); ret = ni_660x_alloc_mite_rings(dev); if (ret < 0) return ret; @@ -1100,13 +1111,13 @@ static int __devinit ni_660x_attach_pci(struct comedi_device *dev, output enables in stc dio control reg */ ni_660x_write_register(dev, 0, 0, STCDIOControl); - private(dev)->counter_dev = ni_gpct_device_construct(dev, + devpriv->counter_dev = ni_gpct_device_construct(dev, &ni_gpct_write_register, &ni_gpct_read_register, ni_gpct_variant_660x, ni_660x_num_counters (dev)); - if (private(dev)->counter_dev == NULL) + if (devpriv->counter_dev == NULL) return -ENOMEM; for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; @@ -1127,11 +1138,11 @@ static int __devinit ni_660x_attach_pci(struct comedi_device *dev, s->poll = &ni_660x_input_poll; s->async_dma_dir = DMA_BIDIRECTIONAL; s->buf_change = &ni_660x_buf_change; - s->private = &private(dev)->counter_dev->counters[i]; + s->private = &devpriv->counter_dev->counters[i]; - private(dev)->counter_dev->counters[i].chip_index = + devpriv->counter_dev->counters[i].chip_index = i / counters_per_chip; - private(dev)->counter_dev->counters[i].counter_index = + devpriv->counter_dev->counters[i].counter_index = i % counters_per_chip; } else { s->type = COMEDI_SUBD_UNUSED; @@ -1141,7 +1152,7 @@ static int __devinit ni_660x_attach_pci(struct comedi_device *dev, init_tio_chip(dev, i); for (i = 0; i < ni_660x_num_counters(dev); ++i) - ni_tio_init_counter(&private(dev)->counter_dev->counters[i]); + ni_tio_init_counter(&devpriv->counter_dev->counters[i]); for (i = 0; i < NUM_PFI_CHANNELS; ++i) { if (i < min_counter_pfi_chan) @@ -1156,13 +1167,13 @@ static int __devinit ni_660x_attach_pci(struct comedi_device *dev, for (i = 0; i < board(dev)->n_chips; ++i) set_tio_counterswap(dev, i); - ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt, + ret = request_irq(mite_irq(devpriv->mite), ni_660x_interrupt, IRQF_SHARED, "ni_660x", dev); if (ret < 0) { dev_warn(dev->class_dev, " irq not available\n"); return ret; } - dev->irq = mite_irq(private(dev)->mite); + dev->irq = mite_irq(devpriv->mite); global_interrupt_config_bits = Global_Int_Enable_Bit; if (board(dev)->n_chips > 1) global_interrupt_config_bits |= Cascade_Int_Enable_Bit; @@ -1174,15 +1185,17 @@ static int __devinit ni_660x_attach_pci(struct comedi_device *dev, static void ni_660x_detach(struct comedi_device *dev) { + struct ni_660x_private *devpriv = dev->private; + if (dev->irq) free_irq(dev->irq, dev); - if (dev->private) { - if (private(dev)->counter_dev) - ni_gpct_device_destroy(private(dev)->counter_dev); - if (private(dev)->mite) { + if (devpriv) { + if (devpriv->counter_dev) + ni_gpct_device_destroy(devpriv->counter_dev); + if (devpriv->mite) { ni_660x_free_mite_rings(dev); - mite_unsetup(private(dev)->mite); - mite_free(private(dev)->mite); + mite_unsetup(devpriv->mite); + mite_free(devpriv->mite); } } } @@ -1196,17 +1209,17 @@ ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static void init_tio_chip(struct comedi_device *dev, int chipset) { + struct ni_660x_private *devpriv = dev->private; unsigned i; /* init dma configuration register */ - private(dev)->dma_configuration_soft_copies[chipset] = 0; + devpriv->dma_configuration_soft_copies[chipset] = 0; for (i = 0; i < MAX_DMA_CHANNEL; ++i) { - private(dev)->dma_configuration_soft_copies[chipset] |= + devpriv->dma_configuration_soft_copies[chipset] |= dma_select_bits(i, dma_selection_none) & dma_select_mask(i); } ni_660x_write_register(dev, chipset, - private(dev)-> - dma_configuration_soft_copies[chipset], + devpriv->dma_configuration_soft_copies[chipset], DMAConfigRegister); for (i = 0; i < NUM_PFI_CHANNELS; ++i) ni_660x_write_register(dev, chipset, 0, IOConfigReg(i)); @@ -1294,6 +1307,8 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, unsigned source) { + struct ni_660x_private *devpriv = dev->private; + if (source > num_pfi_output_selects) return -EINVAL; if (source == pfi_output_select_high_Z) @@ -1307,19 +1322,20 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, } BUG_ON(chan >= NUM_PFI_CHANNELS); - private(dev)->pfi_output_selects[chan] = source; - if (private(dev)->pfi_direction_bits & (((uint64_t) 1) << chan)) + devpriv->pfi_output_selects[chan] = source; + if (devpriv->pfi_direction_bits & (((uint64_t) 1) << chan)) ni_660x_select_pfi_output(dev, chan, - private(dev)-> - pfi_output_selects[chan]); + devpriv->pfi_output_selects[chan]); return 0; } static unsigned ni_660x_get_pfi_routing(struct comedi_device *dev, unsigned chan) { + struct ni_660x_private *devpriv = dev->private; + BUG_ON(chan >= NUM_PFI_CHANNELS); - return private(dev)->pfi_output_selects[chan]; + return devpriv->pfi_output_selects[chan]; } static void ni660x_config_filter(struct comedi_device *dev, @@ -1336,6 +1352,7 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_660x_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); /* The input or output configuration of each digital line is @@ -1345,18 +1362,17 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, switch (data[0]) { case INSN_CONFIG_DIO_OUTPUT: - private(dev)->pfi_direction_bits |= ((uint64_t) 1) << chan; + devpriv->pfi_direction_bits |= ((uint64_t) 1) << chan; ni_660x_select_pfi_output(dev, chan, - private(dev)-> - pfi_output_selects[chan]); + devpriv->pfi_output_selects[chan]); break; case INSN_CONFIG_DIO_INPUT: - private(dev)->pfi_direction_bits &= ~(((uint64_t) 1) << chan); + devpriv->pfi_direction_bits &= ~(((uint64_t) 1) << chan); ni_660x_select_pfi_output(dev, chan, pfi_output_select_high_Z); break; case INSN_CONFIG_DIO_QUERY: data[1] = - (private(dev)->pfi_direction_bits & + (devpriv->pfi_direction_bits & (((uint64_t) 1) << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; return 0; case INSN_CONFIG_SET_ROUTING: -- cgit v1.2.3 From 22201ceaeb4f8c3a97b27cd421d9318566089b8c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 15 Oct 2012 10:14:48 -0700 Subject: staging: comedi: poc: introduce struct poc_private Wrap the private data used by this driver in a struct. This makes the use of that data clearer and gets rid of the need for the casts. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/poc.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index 78dfe167b14..8e70affb331 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -57,13 +57,18 @@ struct boarddef_struct { const struct comedi_lrange *range; }; +struct poc_private { + unsigned int ao_readback[32]; +}; + static int readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct poc_private *devpriv = dev->private; int chan; chan = CR_CHAN(insn->chanspec); - data[0] = ((unsigned int *)dev->private)[chan]; + data[0] = devpriv->ao_readback[chan]; return 1; } @@ -75,12 +80,13 @@ static int readback_insn(struct comedi_device *dev, struct comedi_subdevice *s, static int dac02_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct poc_private *devpriv = dev->private; int temp; int chan; int output; chan = CR_CHAN(insn->chanspec); - ((unsigned int *)dev->private)[chan] = data[0]; + devpriv->ao_readback[chan] = data[0]; output = data[0]; #ifdef wrong /* convert to complementary binary if range is bipolar */ @@ -131,6 +137,7 @@ static int pcl734_insn_bits(struct comedi_device *dev, static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct boarddef_struct *board = comedi_board(dev); + struct poc_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; unsigned int iosize; @@ -160,8 +167,10 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - if (alloc_private(dev, sizeof(unsigned int) * board->n_chan) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; /* analog output subdevice */ s = &dev->subdevices[0]; -- cgit v1.2.3 From 843690b7d9c9cd4a2cc77e04ed610d100e599a15 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 15 Oct 2012 10:15:05 -0700 Subject: staging: comedi: addi-data: remove devpriv macro This macro relies on a local variable having a specific name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_82x54.c | 8 ++++- .../comedi/drivers/addi-data/APCI1710_Chrono.c | 7 ++++ .../comedi/drivers/addi-data/APCI1710_Dig_io.c | 4 +++ .../comedi/drivers/addi-data/APCI1710_INCCPT.c | 42 ++++++++++++++++++++++ .../comedi/drivers/addi-data/APCI1710_Inp_cpt.c | 5 ++- .../comedi/drivers/addi-data/APCI1710_Pwm.c | 9 ++++- .../comedi/drivers/addi-data/APCI1710_Ssi.c | 4 +++ .../comedi/drivers/addi-data/APCI1710_Tor.c | 5 ++- .../comedi/drivers/addi-data/APCI1710_Ttl.c | 4 +++ .../staging/comedi/drivers/addi-data/addi_common.c | 14 +++++--- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 1 + .../comedi/drivers/addi-data/hwdrv_APCI1710.c | 2 ++ .../comedi/drivers/addi-data/hwdrv_apci035.c | 14 ++++++++ .../comedi/drivers/addi-data/hwdrv_apci1032.c | 11 ++++-- .../comedi/drivers/addi-data/hwdrv_apci1500.c | 19 +++++++++- .../comedi/drivers/addi-data/hwdrv_apci1516.c | 17 ++++++++- .../comedi/drivers/addi-data/hwdrv_apci1564.c | 16 +++++++++ .../comedi/drivers/addi-data/hwdrv_apci16xx.c | 4 +++ .../comedi/drivers/addi-data/hwdrv_apci2016.c | 12 +++++++ .../comedi/drivers/addi-data/hwdrv_apci2032.c | 14 ++++++++ .../comedi/drivers/addi-data/hwdrv_apci2200.c | 19 ++++++++-- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 37 +++++++++++++++---- .../comedi/drivers/addi-data/hwdrv_apci3200.c | 28 +++++++++++++-- .../comedi/drivers/addi-data/hwdrv_apci3501.c | 18 ++++++++++ .../comedi/drivers/addi-data/hwdrv_apci3xxx.c | 16 +++++++++ 25 files changed, 306 insertions(+), 24 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c index b59f2d484fd..8656d0ef2c8 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c @@ -222,7 +222,7 @@ int i_InsnConfig_InitTimer(struct comedi_device *dev,struct comedi_subdevice *s, int i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_ModulNbr; unsigned char b_TimerNbr; @@ -452,6 +452,7 @@ int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_DummyRead; unsigned char b_ModulNbr; @@ -593,6 +594,7 @@ int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,struct comedi_sub int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_ModulNbr, b_ReadType; unsigned int *pul_TimerValueArray; @@ -764,6 +766,7 @@ int i_APCI1710_ReadTimerValue(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_TimerNbr, unsigned int *pul_TimerValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /* Test the module number */ @@ -852,6 +855,7 @@ int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_TimerNbr, unsigned char *pb_OutputLevel) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_TimerStatus; @@ -931,6 +935,7 @@ int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_TimerNbr, unsigned char *pb_TimerStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_TimerStatus; @@ -1010,6 +1015,7 @@ int i_APCI1710_WriteTimerValue(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_TimerNbr, unsigned int ul_WriteValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /* Test the module number */ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c index 482a412aa65..a30fb0ddb74 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c @@ -134,6 +134,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ul_TimerValue = 0; unsigned int ul_TimingInterval = 0; @@ -843,6 +844,7 @@ struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_ModulNbr, b_CycleMode, b_InterruptEnable, b_Action; b_ModulNbr = CR_AREF(insn->chanspec); @@ -1093,6 +1095,7 @@ struct comedi_insn *insn,unsigned int *data) | int i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned char b_ReadType; int i_ReturnValue = insn->n; @@ -1197,6 +1200,7 @@ int i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char *pb_ChronoStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; @@ -1359,6 +1363,7 @@ int i_APCI1710_ReadChronoValue(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned int ui_TimeOut, unsigned char *pb_ChronoStatus, unsigned int *pul_ChronoValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; unsigned int dw_TimeOut = 0; @@ -1626,6 +1631,7 @@ int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, unsigned char *pb_Second, unsigned int *pui_MilliSecond, unsigned int *pui_MicroSecond, unsigned int *pui_NanoSecond) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; double d_Hour; double d_Minute; @@ -1878,6 +1884,7 @@ int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_ModulNbr, b_OutputChannel, b_InputChannel, b_IOType; unsigned int dw_Status; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c index 07108f9f4a4..96ca3d26ae6 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c @@ -102,6 +102,7 @@ Activates and deactivates the digital output memory. int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned char b_ModulNbr, b_ChannelAMode, b_ChannelBMode; unsigned char b_MemoryOnOff, b_ConfigType; int i_ReturnValue = 0; @@ -296,6 +297,7 @@ int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subd int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg; unsigned char b_ModulNbr, b_InputChannel; @@ -484,6 +486,7 @@ int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev, int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_WriteValue = 0; unsigned char b_ModulNbr, b_OutputChannel; @@ -734,6 +737,7 @@ int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev, int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_WriteValue = 0; unsigned int dw_StatusReg; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c index 14b13eae4c5..834685b1885 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c @@ -78,8 +78,10 @@ struct comedi_insn *insn,unsigned int *data) int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_ConfigType; int i_ReturnValue = 0; + ui_ConfigType = CR_CHAN(insn->chanspec); printk("\nINC_CPT"); @@ -306,6 +308,7 @@ int i_APCI1710_InitCounter(struct comedi_device *dev, unsigned char b_FirstCounterOption, unsigned char b_SecondCounterModus, unsigned char b_SecondCounterOption) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /*******************************/ @@ -547,6 +550,7 @@ int i_APCI1710_InitCounter(struct comedi_device *dev, int i_APCI1710_CounterAutoTest(struct comedi_device *dev, unsigned char *pb_TestStatus) { + struct addi_private *devpriv = dev->private; unsigned char b_ModulCpt = 0; int i_ReturnValue = 0; unsigned int dw_LathchValue; @@ -713,6 +717,7 @@ int i_APCI1710_InitIndex(struct comedi_device *dev, unsigned char b_ReferenceAction, unsigned char b_IndexOperation, unsigned char b_AutoMode, unsigned char b_InterruptEnable) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -1155,6 +1160,7 @@ int i_APCI1710_InitIndex(struct comedi_device *dev, int i_APCI1710_InitReference(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_ReferenceLevel) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -1280,6 +1286,7 @@ int i_APCI1710_InitReference(struct comedi_device *dev, int i_APCI1710_InitExternalStrobe(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_ExternalStrobe, unsigned char b_ExternalStrobeLevel) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -1394,6 +1401,7 @@ int i_APCI1710_InitExternalStrobe(struct comedi_device *dev, int i_APCI1710_InitCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned int ui_CompareValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -1493,6 +1501,7 @@ int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev, unsigned char b_TimingUnity, unsigned int ul_TimingInterval, unsigned int *pul_RealTimingInterval) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ul_TimerValue = 0; double d_RealTimingInterval; @@ -2018,8 +2027,10 @@ struct comedi_insn *insn,unsigned int *data) | int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_BitsType; int i_ReturnValue = 0; + ui_BitsType = CR_CHAN(insn->chanspec); devpriv->tsk_Current = current; /* Save the current process task structure */ @@ -2093,6 +2104,7 @@ int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice int i_APCI1710_ClearCounterValue(struct comedi_device *dev, unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -2153,6 +2165,7 @@ int i_APCI1710_ClearCounterValue(struct comedi_device *dev, unsigned char b_Modu int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; unsigned char b_ModulCpt = 0; int i_ReturnValue = 0; @@ -2300,6 +2313,7 @@ int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev) int i_APCI1710_SetInputFilter(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_PCIInputClock, unsigned char b_Filter) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status = 0; @@ -2564,6 +2578,7 @@ int i_APCI1710_SetInputFilter(struct comedi_device *dev, int i_APCI1710_LatchCounter(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_LatchReg) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -2661,6 +2676,7 @@ int i_APCI1710_LatchCounter(struct comedi_device *dev, int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_SourceSelection) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -2797,6 +2813,7 @@ int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev, int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -2877,6 +2894,7 @@ int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, unsigned char b_ModulN int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -2954,6 +2972,7 @@ struct comedi_insn *insn,unsigned int *data) | int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_WriteType; int i_ReturnValue = 0; @@ -3049,6 +3068,7 @@ int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevic int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3135,6 +3155,7 @@ int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, unsigned char b_M int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3234,6 +3255,7 @@ int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, unsigned char b_ int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_SelectedCounter, unsigned int ui_WriteValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3319,6 +3341,7 @@ int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev, int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned int ul_WriteValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3385,6 +3408,7 @@ int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev, int i_APCI1710_EnableIndex(struct comedi_device *dev, unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ul_InterruptLatchReg; @@ -3483,6 +3507,7 @@ int i_APCI1710_EnableIndex(struct comedi_device *dev, unsigned char b_ModulNbr) int i_APCI1710_DisableIndex(struct comedi_device *dev, unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3582,6 +3607,7 @@ int i_APCI1710_DisableIndex(struct comedi_device *dev, unsigned char b_ModulNbr) int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3682,6 +3708,7 @@ int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, unsigned char b_Mod int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3792,6 +3819,7 @@ int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, unsigned char b_Mo int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_InterruptEnable) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -3938,6 +3966,7 @@ int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev, int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev, unsigned char b_ModulNbr) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -4052,6 +4081,7 @@ struct comedi_insn *insn,unsigned int *data) | int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_ReadType; int i_ReturnValue = 0; @@ -4196,6 +4226,7 @@ int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_LatchReg, unsigned char *pb_LatchStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_LatchReg; @@ -4283,6 +4314,7 @@ int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev, int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_LatchReg, unsigned int *pul_LatchValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -4367,6 +4399,7 @@ int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev, int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_SelectedCounter, unsigned int *pui_CounterValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_LathchValue = 0; @@ -4462,6 +4495,7 @@ int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev, int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned int *pul_CounterValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; /**************************/ @@ -4538,6 +4572,7 @@ int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev, int i_APCI1710_GetIndexStatus(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char *pb_IndexStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -4622,6 +4657,7 @@ int i_APCI1710_GetIndexStatus(struct comedi_device *dev, int i_APCI1710_GetReferenceStatus(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char *pb_ReferenceStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -4706,6 +4742,7 @@ int i_APCI1710_GetReferenceStatus(struct comedi_device *dev, int i_APCI1710_GetUASStatus(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char *pb_UASStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -4774,6 +4811,7 @@ int i_APCI1710_GetUASStatus(struct comedi_device *dev, int i_APCI1710_GetCBStatus(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char *pb_CBStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -4856,6 +4894,7 @@ int i_APCI1710_GetCBStatus(struct comedi_device *dev, int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char *pb_CBStatusCounter0, unsigned char *pb_CBStatusCounter1) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -4969,6 +5008,7 @@ int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev, int i_APCI1710_GetUDStatus(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char *pb_UDStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -5043,6 +5083,7 @@ int i_APCI1710_GetUDStatus(struct comedi_device *dev, int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char *pb_UDStatus) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; @@ -5149,6 +5190,7 @@ int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char *pb_Status, unsigned char *pb_UDStatus, unsigned int *pul_ReadValue) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ui_16BitValue; unsigned int dw_StatusReg; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c index 3f9cfa20d88..3aa80090a07 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c @@ -126,9 +126,9 @@ You should also find the complete GPL in the COPYING file accompanying this sour int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_IntRegister; - unsigned char b_ModulNbr; unsigned char b_PulseEncoderNbr; unsigned char b_InputLevelSelection; @@ -417,6 +417,7 @@ int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev, int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_ModulNbr; unsigned char b_PulseEncoderNbr; @@ -711,6 +712,7 @@ int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev, int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusRegister; unsigned char b_ModulNbr; @@ -837,6 +839,7 @@ int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev, int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; data[0] = devpriv->s_InterruptParameters. s_FIFOInterruptParameters[devpriv-> diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c index 8883e666211..9a01ea05b40 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c @@ -188,6 +188,7 @@ int i_APCI1710_InitPWM(struct comedi_device *dev, unsigned int ul_HighTiming, unsigned int *pul_RealLowTiming, unsigned int *pul_RealHighTiming) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ul_LowTimerValue = 0; unsigned int ul_HighTimerValue = 0; @@ -1545,6 +1546,7 @@ int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev, unsigned char *pb_StopLevel, unsigned char *pb_ExternGate, unsigned char *pb_InterruptEnable, unsigned char *pb_Enable) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; unsigned int dw_Command; @@ -1813,6 +1815,7 @@ int i_APCI1710_EnablePWM(struct comedi_device *dev, unsigned char b_StopMode, unsigned char b_StopLevel, unsigned char b_ExternGate, unsigned char b_InterruptEnable) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; unsigned int dw_Command; @@ -2064,6 +2067,7 @@ int i_APCI1710_EnablePWM(struct comedi_device *dev, int i_APCI1710_DisablePWM(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_PWM) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; @@ -2193,6 +2197,7 @@ int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_PWM, unsigned char b_TimingUnit, unsigned int ul_LowTiming, unsigned int ul_HighTiming) { + struct addi_private *devpriv = dev->private; unsigned char b_ClockSelection; int i_ReturnValue = 0; unsigned int ul_LowTimerValue = 0; @@ -3463,9 +3468,9 @@ int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev, int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; - unsigned char b_ModulNbr; unsigned char b_PWM; unsigned char *pb_PWMOutputStatus; @@ -3564,6 +3569,8 @@ int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_sub int i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + data[0] = devpriv->s_InterruptParameters. s_FIFOInterruptParameters[devpriv-> s_InterruptParameters.ui_Read].b_OldModuleMask; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c index c13b0027492..298ea485da9 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c @@ -122,6 +122,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ui_TimerValue; unsigned char b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength, @@ -389,6 +390,7 @@ pul_Position = (unsigned int *) &data[0]; int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_Cpt; unsigned char b_Length; @@ -722,6 +724,7 @@ int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevi int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg; unsigned char b_ModulNbr; @@ -729,6 +732,7 @@ int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_sub unsigned char *pb_ChannelStatus; unsigned char *pb_InputStatus; unsigned char b_IOType; + i_ReturnValue = insn->n; b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec); b_IOType = (unsigned char) data[0]; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c index 0e6affd9596..28322fbfc1d 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c @@ -133,6 +133,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int ul_TimerValue = 0; unsigned int dw_Command; @@ -990,6 +991,7 @@ int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev, int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; unsigned int dw_DummyRead; @@ -1463,6 +1465,7 @@ int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev, int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; unsigned char b_ModulNbr; @@ -1703,10 +1706,10 @@ int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev, int i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_Status; unsigned int dw_TimeOut = 0; - unsigned char b_ModulNbr; unsigned char b_TorCounter; unsigned char b_ReadType; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c index 9e177f4af86..4f71a4ce3fb 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c @@ -103,6 +103,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour int i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned char b_ModulNbr; unsigned char b_InitType; @@ -409,6 +410,7 @@ APCI1710_TTL_READCHANNEL int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg; unsigned char b_ModulNbr; @@ -658,6 +660,7 @@ int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdev int i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg; unsigned char b_ModulNbr; @@ -828,6 +831,7 @@ int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,struct comedi int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; unsigned int dw_StatusReg = 0; unsigned char b_ModulNbr; diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 99a96bd9671..1d4ecfec447 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -76,7 +76,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour /* Update-0.7.57->0.7.68MODULE_DESCRIPTION("Comedi ADDI-DATA module"); */ /* Update-0.7.57->0.7.68MODULE_LICENSE("GPL"); */ -#define devpriv ((struct addi_private *)dev->private) #define this_board ((const struct addi_board *)dev->board_ptr) #if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300) @@ -1472,6 +1471,7 @@ module_exit(driver_addi_cleanup_module); static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct addi_private *devpriv; struct comedi_subdevice *s; int ret, pages, i, n_subdevices; unsigned int dw_Dummy; @@ -1482,9 +1482,10 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned char pci_bus, pci_slot, pci_func; int i_Dma = 0; - ret = alloc_private(dev, sizeof(struct addi_private)); - if (ret < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; if (!pci_list_builded) { v_pci_card_list_init(this_board->i_VendorId, 1); /* 1 for displaying the list.. */ @@ -1817,7 +1818,9 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) static void i_ADDI_Detach(struct comedi_device *dev) { - if (dev->private) { + struct addi_private *devpriv = dev->private; + + if (devpriv) { if (devpriv->b_ValidDriver) i_ADDI_Reset(dev); if (dev->irq) @@ -1923,6 +1926,7 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned short w_Data; unsigned short w_Address; w_Address = CR_CHAN(insn->chanspec); /* address to be read as 0,1,2,3...255 */ diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 3a9339b9261..0883fe0a930 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -805,6 +805,7 @@ void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; unsigned short w_Temp, i, w_Count = 0; unsigned int ui_Temp; struct str_MainHeader s_MainHeader; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c index f9a8937be8e..057ef4eb8db 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c @@ -201,6 +201,7 @@ void v_APCI1710_Interrupt(int irq, void *d); int i_APCI1710_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; int ret; unsigned int dw_Dummy; @@ -250,6 +251,7 @@ int i_APCI1710_Reset(struct comedi_device *dev) void v_APCI1710_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned char b_ModuleCpt = 0; unsigned char b_InterruptFlag = 0; unsigned char b_PWMCpt = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c index 5997b2f504a..0fde7a39302 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c @@ -112,9 +112,11 @@ static int i_Flag = 1; int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Status = 0; unsigned int ui_Command = 0; unsigned int ui_Mode = 0; + i_Temp = 0; devpriv->tsk_Current = current; devpriv->b_TimerSelectMode = data[0]; @@ -281,8 +283,10 @@ int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subde int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Command = 0; int i_Count = 0; + if (data[0] == 1) { ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12); @@ -396,7 +400,9 @@ int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev, int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Status = 0; /* Status register */ + i_WatchdogNbr = insn->unused[0]; /******************/ @@ -456,6 +462,8 @@ int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevi int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + devpriv->tsk_Current = current; outl(0x200 | 0, devpriv->iobase + 128 + 0x4); outl(0, devpriv->iobase + 128 + 0); @@ -493,7 +501,9 @@ int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevi int i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_CommandRegister = 0; + /******************/ /* Set the start */ /******************/ @@ -527,7 +537,9 @@ int i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice */ int i_APCI035_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; int i_Count = 0; + for (i_Count = 1; i_Count <= 4; i_Count++) { i_WatchdogNbr = i_Count; outl(0x0, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0); /* stop all timers */ @@ -557,11 +569,13 @@ int i_APCI035_Reset(struct comedi_device *dev) static void v_APCI035_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned int ui_StatusRegister1 = 0; unsigned int ui_StatusRegister2 = 0; unsigned int ui_ReadCommand = 0; unsigned int ui_ChannelNumber = 0; unsigned int ui_DigitalTemperature = 0; + if (i_Temp == 1) { i_WatchdogNbr = i_Flag; i_Flag = i_Flag + 1; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index bab7b61a53b..b209cfa0374 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -87,10 +87,11 @@ static unsigned int ui_InterruptStatus; int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue; - unsigned int ul_Command1 = 0; unsigned int ul_Command2 = 0; + devpriv->tsk_Current = current; /*******************************/ @@ -147,9 +148,11 @@ int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subde int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue = 0; unsigned int ui_Channel; ui_Channel = CR_CHAN(insn->chanspec); + if (ui_Channel <= 31) { ui_TmpValue = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP); /* @@ -188,6 +191,7 @@ int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdev int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_PortValue = data[0]; unsigned int ui_Mask = 0; unsigned int ui_NoOfChannels; @@ -248,8 +252,9 @@ int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub static void v_APCI1032_Interrupt(int irq, void *d) { struct comedi_device *dev = d; - + struct addi_private *devpriv = dev->private; unsigned int ui_Temp; + /* disable the interrupt */ ui_Temp = inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); outl(ui_Temp & APCI1032_DIGITAL_IP_INTERRUPT_DISABLE, @@ -279,6 +284,8 @@ static void v_APCI1032_Interrupt(int irq, void *d) int i_APCI1032_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); /* disable the interrupts */ inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); /* Reset the interrupt status register */ outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); /* Disable the and/or interrupt */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c index 62f421a06f0..cc47821a745 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c @@ -141,6 +141,7 @@ static int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0; int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0; int i_PatternTransitionCount = 0, i_RegValue; @@ -525,8 +526,10 @@ static int i_APCI1500_StartStopInputEvent(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_Event1InterruptStatus = 0, i_Event2InterruptStatus = 0, i_RegValue; + switch (data[0]) { case START: /*************************/ @@ -792,7 +795,9 @@ static int i_APCI1500_Initialisation(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_DummyRead = 0; + /******************/ /* Software reset */ /******************/ @@ -966,6 +971,7 @@ static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_PortValue = data[1]; unsigned int ui_Mask = 0; unsigned int ui_Channel; @@ -1051,6 +1057,8 @@ static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *de struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + devpriv->b_OutputMemoryStatus = data[0]; return insn->n; } @@ -1079,9 +1087,9 @@ static int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; static unsigned int ui_Temp = 0; unsigned int ui_Temp1; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ if (!devpriv->b_OutputMemoryStatus) { @@ -1274,6 +1282,7 @@ static int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_TimerCounterMode, i_MasterConfiguration; devpriv->tsk_Current = current; @@ -1875,6 +1884,7 @@ static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_CommandAndStatusValue; switch (data[0]) { @@ -2198,7 +2208,9 @@ static int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_CommandAndStatusValue; + switch (data[0]) { case COUNTER1: /* Read counter/timer1 */ @@ -2421,9 +2433,11 @@ static int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Status; int i_RegValue; int i_Constant; + devpriv->tsk_Current = current; outl(0x0, devpriv->i_IobaseAmcc + 0x38); if (data[0] == 1) { @@ -2597,6 +2611,7 @@ static void v_APCI1500_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned int ui_InterruptStatus = 0; int i_RegValue = 0; i_InterruptMask = 0; @@ -2840,7 +2855,9 @@ static void v_APCI1500_Interrupt(int irq, void *d) */ static int i_APCI1500_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; int i_DummyRead = 0; + i_TimerCounter1Init = 0; i_TimerCounter2Init = 0; i_WatchdogCounter3Init = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index 8a584a014b0..04a87453818 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -76,8 +76,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour int i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue = 0; unsigned int ui_Channel; + ui_Channel = CR_CHAN(insn->chanspec); if (ui_Channel <= 7) { ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI1516_DIGITAL_IP); @@ -117,7 +119,7 @@ int i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdev int i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + struct addi_private *devpriv = dev->private; unsigned int ui_PortValue = data[0]; unsigned int ui_Mask = 0; unsigned int ui_NoOfChannels; @@ -174,6 +176,8 @@ int i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + devpriv->b_OutputMemoryStatus = data[0]; return insn->n; } @@ -202,6 +206,7 @@ int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd int i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp, ui_Temp1; unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ @@ -363,8 +368,10 @@ int i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp; unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ + ui_Temp = data[0]; *data = inw(devpriv->iobase + APCI1516_DIGITAL_OP_RW); if (ui_Temp == 0) { @@ -422,6 +429,8 @@ int i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + if (data[0] == 0) { /* Disable the watchdog */ outw(0x0, @@ -468,6 +477,8 @@ int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + switch (data[0]) { case 0: /* stop the watchdog */ outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */ @@ -513,6 +524,8 @@ int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_s int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + data[0] = inw(devpriv->i_IobaseAddon + APCI1516_WATCHDOG_STATUS) & 0x1; return insn->n; } @@ -534,6 +547,8 @@ int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice * int i_APCI1516_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + outw(0x0, devpriv->iobase + APCI1516_DIGITAL_OP); /* RESETS THE DIGITAL OUTPUTS */ outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE); outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 5b92e45c9ae..393d6d19802 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -89,6 +89,8 @@ static unsigned int ui_InterruptData, ui_Type; int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + devpriv->tsk_Current = current; /*******************************/ /* Set the digital input logic */ @@ -150,6 +152,7 @@ int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subde int i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue = 0; unsigned int ui_Channel; @@ -192,6 +195,7 @@ int i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdev int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_PortValue = data[0]; unsigned int ui_Mask = 0; unsigned int ui_NoOfChannels; @@ -260,6 +264,7 @@ int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command = 0; if ((data[0] != 0) && (data[0] != 1)) { @@ -317,6 +322,7 @@ int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp, ui_Temp1; unsigned int ui_NoOfChannel; @@ -491,6 +497,7 @@ int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp; unsigned int ui_NoOfChannel; @@ -569,7 +576,9 @@ int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; + devpriv->tsk_Current = current; if (data[0] == ADDIDATA_WATCHDOG) { devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG; @@ -723,7 +732,9 @@ int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; + if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { switch (data[1]) { case 0: /* stop the watchdog */ @@ -818,6 +829,7 @@ int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { @@ -921,10 +933,12 @@ int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subd static void v_APCI1564_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned int ui_DO, ui_DI; unsigned int ui_Timer; unsigned int ui_C1, ui_C2, ui_C3, ui_C4; unsigned int ul_Command2 = 0; + ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ) & 0x01; ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + @@ -1106,6 +1120,8 @@ static void v_APCI1564_Interrupt(int irq, void *d) int i_APCI1564_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_IRQ); /* disable the interrupts */ inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_STATUS); /* Reset the interrupt status register */ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE1); /* Disable the and/or interrupt */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c index 00a088f820a..859c593f95a 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c @@ -93,6 +93,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Command = 0; unsigned char b_Cpt = 0; @@ -286,6 +287,7 @@ int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev, int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Command = 0; unsigned char b_NumberOfPort = @@ -433,6 +435,7 @@ int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev, int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned char b_Command = (unsigned char) CR_AREF(insn->chanspec); int i_ReturnValue = insn->n; unsigned char b_Cpt = 0; @@ -573,6 +576,7 @@ int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev, int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Command = 0; unsigned char b_NumberOfPort = diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c index 49dcbe24fcd..b8721dd16cb 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c @@ -78,6 +78,8 @@ You should also find the complete GPL in the COPYING file accompanying this sour int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + if ((data[0] != 0) && (data[0] != 1)) { comedi_error(dev, "Not a valid Data !!! ,Data should be 1 or 0\n"); @@ -114,8 +116,10 @@ int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_NoOfChannel; unsigned int ui_Temp, ui_Temp1; + ui_NoOfChannel = CR_CHAN(insn->chanspec); if (ui_NoOfChannel > 15) { comedi_error(dev, @@ -269,8 +273,10 @@ int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp; unsigned int ui_NoOfChannel; + ui_NoOfChannel = CR_CHAN(insn->chanspec); if (ui_NoOfChannel > 15) { comedi_error(dev, @@ -340,6 +346,7 @@ int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdev int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; if (data[0] == 0) { /* Disable the watchdog */ @@ -383,6 +390,7 @@ int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; switch (data[0]) { case 0: /* stop the watchdog */ @@ -430,6 +438,8 @@ int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_s int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + udelay(5); data[0] = inw(devpriv->i_IobaseAddon + APCI2016_WATCHDOG_STATUS) & 0x1; return insn->n; @@ -452,6 +462,8 @@ int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice * int i_APCI2016_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + outw(0x0, devpriv->iobase + APCI2016_DIGITAL_OP); /* Resets the digital output channels */ outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE); outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c index 002297dfe33..ad57f02b5b2 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c @@ -82,7 +82,9 @@ static unsigned int ui_InterruptData, ui_Type; int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command = 0; + devpriv->tsk_Current = current; if ((data[0] != 0) && (data[0] != 1)) { @@ -137,8 +139,10 @@ int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp, ui_Temp1; unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ + if (devpriv->b_OutputMemoryStatus) { ui_Temp = inl(devpriv->iobase + APCI2032_DIGITAL_OP); @@ -316,8 +320,10 @@ int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde int i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp; unsigned int ui_NoOfChannel; + ui_NoOfChannel = CR_CHAN(insn->chanspec); ui_Temp = data[0]; *data = inl(devpriv->iobase + APCI2032_DIGITAL_OP_RW); @@ -383,6 +389,8 @@ int i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev int i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + if (data[0] == 0) { /* Disable the watchdog */ outl(0x0, @@ -424,6 +432,8 @@ int i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + switch (data[0]) { case 0: /* stop the watchdog */ outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); /* disable the watchdog */ @@ -469,6 +479,7 @@ int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_s int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; data[0] = inl(devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + @@ -496,6 +507,7 @@ int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice * void v_APCI2032_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned int ui_DO; ui_DO = inl(devpriv->iobase + APCI2032_DIGITAL_OP_IRQ) & 0x1; /* Check if VCC OR CC interrupt has occurred. */ @@ -569,6 +581,8 @@ int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subd int i_APCI2032_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + devpriv->b_DigitalOutputRegister = 0; ui_Type = 0; outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP); /* Resets the output channels */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c index 3d378b5ecbc..db74f774a91 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c @@ -76,8 +76,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour int i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue = 0; unsigned int ui_Channel; + ui_Channel = CR_CHAN(insn->chanspec); if (ui_Channel <= 7) { ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP); @@ -115,7 +117,7 @@ int i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdev int i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + struct addi_private *devpriv = dev->private; unsigned int ui_PortValue = data[0]; unsigned int ui_Mask = 0; unsigned int ui_NoOfChannels; @@ -172,6 +174,8 @@ int i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + devpriv->b_OutputMemoryStatus = data[0]; return insn->n; } @@ -200,8 +204,10 @@ int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd int i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp, ui_Temp1; unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ + if (devpriv->b_OutputMemoryStatus) { ui_Temp = inw(devpriv->iobase + APCI2200_DIGITAL_OP); @@ -357,9 +363,10 @@ int i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + struct addi_private *devpriv = dev->private; unsigned int ui_Temp; unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ + ui_Temp = data[0]; *data = inw(devpriv->iobase + APCI2200_DIGITAL_OP); if (ui_Temp == 0) { @@ -421,6 +428,8 @@ int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + if (data[0] == 0) { /* Disable the watchdog */ outw(0x0, @@ -467,6 +476,8 @@ int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + switch (data[0]) { case 0: /* stop the watchdog */ outw(0x0, devpriv->iobase + APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */ @@ -512,6 +523,8 @@ int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_s int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + data[0] = inw(devpriv->iobase + APCI2200_WATCHDOG + APCI2200_WATCHDOG_STATUS) & 0x1; @@ -535,6 +548,8 @@ int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice * int i_APCI2200_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + outw(0x0, devpriv->iobase + APCI2200_DIGITAL_OP); /* RESETS THE DIGITAL OUTPUTS */ outw(0x0, devpriv->iobase + APCI2200_WATCHDOG + diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index f406dfb2a67..0f7c8260264 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -77,6 +77,7 @@ static unsigned int ui_Temp; int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int i; if ((data[0] != APCI3120_EOC_MODE) && (data[0] != APCI3120_EOS_MODE)) @@ -146,6 +147,7 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned short us_ConvertTiming, us_TmpValue, i; unsigned char b_Tmp; @@ -407,6 +409,8 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s) { + struct addi_private *devpriv = dev->private; + /* Disable A2P Fifo write and AMWEN signal */ outw(0, devpriv->i_IobaseAddon + 4); @@ -478,6 +482,7 @@ int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_su int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct addi_private *devpriv = dev->private; int err = 0; /* Step 1 : check if triggers are trivially valid */ @@ -604,6 +609,7 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s) { + struct addi_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; /* loading private structure with cmd structure inputs */ @@ -678,6 +684,7 @@ int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, struct comedi_subdevice *s) { + struct addi_private *devpriv = dev->private; unsigned char b_Tmp; unsigned int ui_Tmp, ui_DelayTiming = 0, ui_TimerValue1 = 0, dmalen0 = 0, dmalen1 = 0, ui_TimerValue2 = @@ -1211,6 +1218,7 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, int i_APCI3120_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; unsigned int i; unsigned short us_TmpValue; @@ -1292,6 +1300,7 @@ int i_APCI3120_Reset(struct comedi_device *dev) int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevice *s, int n_chan, unsigned int *chanlist, char check) { + struct addi_private *devpriv = dev->private; unsigned int i; /* , differencial=0, bipolar=0; */ unsigned int gain; unsigned short us_TmpValue; @@ -1354,6 +1363,7 @@ int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevi int i_APCI3120_ExttrigEnable(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER; outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); @@ -1379,6 +1389,8 @@ int i_APCI3120_ExttrigEnable(struct comedi_device *dev) int i_APCI3120_ExttrigDisable(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER; outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); return 0; @@ -1414,13 +1426,13 @@ int i_APCI3120_ExttrigDisable(struct comedi_device *dev) void v_APCI3120_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned short int_daq; - unsigned int int_amcc, ui_Check, i; unsigned short us_TmpValue; unsigned char b_DummyRead; - struct comedi_subdevice *s = &dev->subdevices[0]; + ui_Check = 1; int_daq = inw(dev->iobase + APCI3120_RD_STATUS) & 0xf000; /* get IRQ reasons */ @@ -1624,6 +1636,7 @@ void v_APCI3120_Interrupt(int irq, void *d) int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; int n_chan, i; struct comedi_subdevice *s = &dev->subdevices[0]; int err = 1; @@ -1667,11 +1680,12 @@ int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) void v_APCI3120_InterruptDma(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; unsigned int next_dma_buf, samplesinbuf; unsigned long low_word, high_word, var; - unsigned int ui_Tmp; + samplesinbuf = devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] - inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC); @@ -1837,6 +1851,8 @@ void v_APCI3120_InterruptDma(int irq, void *d) void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, struct comedi_subdevice *s, short *dma_buffer, unsigned int num_samples) { + struct addi_private *devpriv = dev->private; + devpriv->ui_AiActualScan += (s->async->cur_chan + num_samples) / devpriv->ui_AiScanLength; s->async->cur_chan += num_samples; @@ -1879,7 +1895,7 @@ void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + struct addi_private *devpriv = dev->private; unsigned int ui_Timervalue2; unsigned short us_TmpValue; unsigned char b_Tmp; @@ -2037,7 +2053,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + struct addi_private *devpriv = dev->private; unsigned int ui_Timervalue2 = 0; unsigned short us_TmpValue; unsigned char b_Tmp; @@ -2221,6 +2237,7 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned char b_Tmp; unsigned short us_TmpValue, us_TmpValue_2, us_StatusValue; @@ -2296,6 +2313,7 @@ int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Chan, ui_TmpValue; ui_Chan = CR_CHAN(insn->chanspec); /* channel specified */ @@ -2340,7 +2358,9 @@ int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue; + ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI3120_RD_STATUS); /***** state of 4 channels in the 11, 10, 9, 8 bits of status reg rotated right 8 times to bring them to last four bits @@ -2379,6 +2399,7 @@ int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_sub int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; if ((data[0] != 0) && (data[0] != 1)) { comedi_error(dev, @@ -2426,6 +2447,8 @@ int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + if ((data[0] > devpriv->s_EeParameters.i_DoMaxdata) || (data[0] < 0)) { comedi_error(dev, "Data is not valid !!! \n"); @@ -2479,9 +2502,8 @@ int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - + struct addi_private *devpriv = dev->private; unsigned int ui_Temp1; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ if ((data[0] != 0) && (data[0] != 1)) { @@ -2558,6 +2580,7 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Range, ui_Channel; unsigned short us_TmpValue; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index 38ab49917d7..7f5efa39cb7 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -548,8 +548,10 @@ int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev, int i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp = 0; unsigned int ui_NoOfChannel = 0; + ui_NoOfChannel = CR_CHAN(insn->chanspec); ui_Temp = data[0]; *data = inl(devpriv->i_IobaseReserved); @@ -606,6 +608,7 @@ int i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevi int i_APCI3200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; if ((data[0] != 0) && (data[0] != 1)) { comedi_error(dev, @@ -651,8 +654,10 @@ int i_APCI3200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd int i_APCI3200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp = 0, ui_Temp1 = 0; unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ + if (devpriv->b_OutputMemoryStatus) { ui_Temp = inl(devpriv->i_IobaseAddon); @@ -764,8 +769,10 @@ int i_APCI3200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde int i_APCI3200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp; unsigned int ui_NoOfChannel; + ui_NoOfChannel = CR_CHAN(insn->chanspec); ui_Temp = data[0]; *data = inl(devpriv->i_IobaseAddon); @@ -872,7 +879,7 @@ int i_APCI3200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev int i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + struct addi_private *devpriv = dev->private; unsigned int ul_Config = 0, ul_Temp = 0; unsigned int ui_ChannelNo = 0; unsigned int ui_Dummy = 0; @@ -1649,6 +1656,7 @@ int i_APCI3200_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevic int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_EOC = 0; unsigned int ui_ChannelNo = 0; unsigned int ui_CommandRegister = 0; @@ -1773,6 +1781,7 @@ int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, */ int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp = 0, ui_EOC = 0; unsigned int ui_CommandRegister = 0; @@ -1909,6 +1918,7 @@ int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned in */ int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_EOC = 0; int ui_CommandRegister = 0; @@ -2045,6 +2055,7 @@ int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_EOC = 0; int ui_CommandRegister = 0; @@ -2164,8 +2175,10 @@ int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data) */ int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_EOC = 0; int ui_CommandRegister = 0; + /*******************************************/ /*Read calibration offset value for the CJC */ /*******************************************/ @@ -2280,8 +2293,10 @@ int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data) */ int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_EOC = 0; int ui_CommandRegister = 0; + /*******************************/ /* Set the convert timing unit */ /*******************************/ @@ -2402,8 +2417,10 @@ int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data) int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Configuration = 0; int i_Temp; /* ,i_TimeUnit; */ + /* if(i_Initialised==0) */ if (s_BoardInfos[dev->minor].i_Initialised == 0) { @@ -2736,7 +2753,9 @@ int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s) { + struct addi_private *devpriv = dev->private; unsigned int ui_Configuration = 0; + /* i_InterruptFlag=0; */ /* i_Initialised=0; */ /* i_Count=0; */ @@ -2786,6 +2805,7 @@ int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_su int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s) { + struct addi_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned int ui_Configuration = 0; /* INT i_CurrentSource = 0; */ @@ -2798,6 +2818,7 @@ int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde unsigned int ui_DelayTime = 0; unsigned int ui_DelayTimeBase = 0; unsigned int ui_DelayMode = 0; + /* i_FirstChannel=cmd->chanlist[0]; */ /* i_LastChannel=cmd->chanlist[1]; */ s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0]; @@ -2973,8 +2994,10 @@ int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde int i_APCI3200_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; int i_Temp; unsigned int dw_Dummy; + /* i_InterruptFlag=0; */ /* i_Initialised==0; */ /* i_Count=0; */ @@ -3030,6 +3053,7 @@ int i_APCI3200_Reset(struct comedi_device *dev) void v_APCI3200_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned int ui_StatusRegister = 0; unsigned int ui_ChannelNumber = 0; int i_CalibrationFlag = 0; @@ -3038,7 +3062,6 @@ void v_APCI3200_Interrupt(int irq, void *d) unsigned int ui_DigitalTemperature = 0; unsigned int ui_DigitalInput = 0; int i_ConvertCJCCalibration; - /* BEGIN JK TEST */ int i_ReturnValue = 0; /* END JK TEST */ @@ -3471,6 +3494,7 @@ void v_APCI3200_Interrupt(int irq, void *d) */ int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; unsigned int ui_StatusRegister = 0; struct comedi_subdevice *s = &dev->subdevices[0]; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c index acaceb01629..a730a4a52cb 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c @@ -76,8 +76,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour int i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp; unsigned int ui_NoOfChannel; + ui_NoOfChannel = CR_CHAN(insn->chanspec); ui_Temp = data[0]; *data = inl(devpriv->iobase + APCI3501_DIGITAL_IP); @@ -124,6 +126,7 @@ int i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevi int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; if ((data[0] != 0) && (data[0] != 1)) { comedi_error(dev, @@ -164,8 +167,10 @@ int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd int i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp, ui_Temp1; unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ + if (devpriv->b_OutputMemoryStatus) { ui_Temp = inl(devpriv->iobase + APCI3501_DIGITAL_OP); } /* if(devpriv->b_OutputMemoryStatus ) */ @@ -251,6 +256,7 @@ int i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ui_Temp; unsigned int ui_NoOfChannel; @@ -301,6 +307,8 @@ int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; + outl(data[0], devpriv->iobase + APCI3501_ANALOG_OUTPUT + APCI3501_AO_VOLT_MODE); @@ -339,6 +347,7 @@ int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subde int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0; ul_Channel_no = CR_CHAN(insn->chanspec); @@ -413,7 +422,9 @@ int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdev int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; + devpriv->tsk_Current = current; if (data[0] == ADDIDATA_WATCHDOG) { @@ -514,8 +525,10 @@ int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev, int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; int i_Temp; + if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { if (data[1] == 1) { @@ -616,6 +629,7 @@ int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { data[0] = @@ -656,8 +670,10 @@ int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev, int i_APCI3501_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; int i_Count = 0, i_temp = 0; unsigned int ul_Command1 = 0, ul_Polarity, ul_DAC_Ready = 0; + outl(0x0, devpriv->iobase + APCI3501_DIGITAL_OP); outl(1, devpriv->iobase + APCI3501_ANALOG_OUTPUT + APCI3501_AO_VOLT_MODE); @@ -709,8 +725,10 @@ void v_APCI3501_Interrupt(int irq, void *d) { int i_temp; struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned int ui_Timer_AOWatchdog; unsigned long ul_Command1; + /* Disable Interrupt */ ul_Command1 = inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c index fff99df51e9..431df5c90ce 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c @@ -69,6 +69,8 @@ You should also find the complete GPL in the COPYING file accompanying this sour */ static int i_APCI3XXX_TestConversionStarted(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; + if ((readl(devpriv->dw_AiBase + 8) & 0x80000UL) == 0x80000UL) return 1; else @@ -108,6 +110,7 @@ static int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_TimeBase = 0; unsigned char b_SingleDiff = 0; @@ -358,6 +361,7 @@ static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec); unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); @@ -571,6 +575,7 @@ static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev, static void v_APCI3XXX_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; unsigned char b_CopyCpt = 0; unsigned int dw_Status = 0; @@ -651,6 +656,7 @@ static int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec); unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); unsigned int dw_Status = 0; @@ -755,6 +761,7 @@ static int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Command = 0; @@ -884,6 +891,7 @@ static int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_ChannelCpt = 0; unsigned int dw_ChannelMask = 0; @@ -1040,6 +1048,7 @@ static int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); int i_ReturnValue = insn->n; unsigned int *pls_ReadData = data; @@ -1154,6 +1163,7 @@ static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); unsigned char b_State = 0; @@ -1267,6 +1277,7 @@ static int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); unsigned int dw_Temp = 0; @@ -1327,6 +1338,7 @@ static int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned int dw_Temp = 0; @@ -1382,6 +1394,7 @@ static int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_ChannelCpt = 0; unsigned int dw_ChannelMask = 0; @@ -1480,6 +1493,7 @@ static int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Channel = CR_CHAN(insn->chanspec); unsigned char b_State = 0; @@ -1557,6 +1571,7 @@ static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Channel = CR_CHAN(insn->chanspec); unsigned int dw_Status = 0; @@ -1614,6 +1629,7 @@ static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev, static int i_APCI3XXX_Reset(struct comedi_device *dev) { + struct addi_private *devpriv = dev->private; unsigned char b_Cpt = 0; /*************************/ -- cgit v1.2.3 From 0e05c55226bffcdd3f1393d5ab74cd0d9faff385 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 15 Oct 2012 10:19:06 -0700 Subject: staging: comedi: ni_mio_common: remove devpriv macro The ni_mio_common.c file is #include'd by the ni_atmio, ni_mio_cs, and ni_pcimio drivers. Those drivers all have a devpriv macro of this type: This macro relies on a local variable having a specific name. Remove its use in all the files by replacing it with a local variable. Some of the functions in ni_mio_common.c don't always use the devpriv variable due to differences in how the low-level i/o is handled by the driver. Tag the variable in those functions with __maybe_unused to avoid compile warnings. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_atmio.c | 11 +- drivers/staging/comedi/drivers/ni_mio_common.c | 147 ++++++++++++++++++++++++- drivers/staging/comedi/drivers/ni_mio_cs.c | 9 +- drivers/staging/comedi/drivers/ni_pcimio.c | 27 ++++- 4 files changed, 180 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c index cac25572f6b..2cc29965e15 100644 --- a/drivers/staging/comedi/drivers/ni_atmio.c +++ b/drivers/staging/comedi/drivers/ni_atmio.c @@ -284,8 +284,6 @@ struct ni_private { }; -#define devpriv ((struct ni_private *)dev->private) - /* How we access registers */ #define ni_writel(a, b) (outl((a), (b)+dev->iobase)) @@ -303,6 +301,7 @@ struct ni_private { static void ni_atmio_win_out(struct comedi_device *dev, uint16_t data, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->window_lock, flags); @@ -317,6 +316,7 @@ static void ni_atmio_win_out(struct comedi_device *dev, uint16_t data, int addr) static uint16_t ni_atmio_win_in(struct comedi_device *dev, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; uint16_t ret; @@ -406,16 +406,17 @@ static int ni_getboardtype(struct comedi_device *dev) static int ni_atmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct ni_private *devpriv; struct pnp_dev *isapnp_dev; int ret; unsigned long iobase; int board; unsigned int irq; - /* allocate private area */ ret = ni_alloc_private(dev); - if (ret < 0) + if (ret) return ret; + devpriv = dev->private; devpriv->stc_writew = &ni_atmio_win_out; devpriv->stc_readw = &ni_atmio_win_in; @@ -499,6 +500,8 @@ static int ni_atmio_attach(struct comedi_device *dev, static void ni_atmio_detach(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; + mio_common_detach(dev); if (dev->iobase) release_region(dev->iobase, NI_SIZE); diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 3e5fdae9316..b096c4647b1 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -410,6 +410,7 @@ static void get_last_sample_6143(struct comedi_device *dev); static inline void ni_set_bitfield(struct comedi_device *dev, int reg, unsigned bit_mask, unsigned bit_values) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); @@ -506,6 +507,7 @@ static inline void ni_set_gpct_dma_channel(struct comedi_device *dev, static inline void ni_set_cdo_dma_channel(struct comedi_device *dev, int mite_channel) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags); @@ -525,6 +527,7 @@ static inline void ni_set_cdo_dma_channel(struct comedi_device *dev, static int ni_request_ai_mite_channel(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); @@ -545,6 +548,7 @@ static int ni_request_ai_mite_channel(struct comedi_device *dev) static int ni_request_ao_mite_channel(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); @@ -567,6 +571,7 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev, unsigned gpct_index, enum comedi_io_direction direction) { + struct ni_private *devpriv = dev->private; unsigned long flags; struct mite_channel *mite_chan; @@ -595,6 +600,7 @@ static int ni_request_gpct_mite_channel(struct comedi_device *dev, static int ni_request_cdo_mite_channel(struct comedi_device *dev) { #ifdef PCIDMA + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); @@ -617,6 +623,7 @@ static int ni_request_cdo_mite_channel(struct comedi_device *dev) static void ni_release_ai_mite_channel(struct comedi_device *dev) { #ifdef PCIDMA + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); @@ -632,6 +639,7 @@ static void ni_release_ai_mite_channel(struct comedi_device *dev) static void ni_release_ao_mite_channel(struct comedi_device *dev) { #ifdef PCIDMA + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); @@ -648,6 +656,7 @@ static void ni_release_ao_mite_channel(struct comedi_device *dev) static void ni_release_gpct_mite_channel(struct comedi_device *dev, unsigned gpct_index) { + struct ni_private *devpriv = dev->private; unsigned long flags; BUG_ON(gpct_index >= NUM_GPCT); @@ -669,6 +678,7 @@ static void ni_release_gpct_mite_channel(struct comedi_device *dev, static void ni_release_cdo_mite_channel(struct comedi_device *dev) { #ifdef PCIDMA + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); @@ -686,6 +696,8 @@ static void ni_release_cdo_mite_channel(struct comedi_device *dev) static void ni_e_series_enable_second_irq(struct comedi_device *dev, unsigned gpct_index, short enable) { + struct ni_private *devpriv = dev->private; + if (boardtype.reg_type & ni_reg_m_series_mask) return; switch (gpct_index) { @@ -716,6 +728,8 @@ static void ni_e_series_enable_second_irq(struct comedi_device *dev, static void ni_clear_ai_fifo(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; + if (boardtype.reg_type == ni_reg_6143) { /* Flush the 6143 data FIFO */ ni_writel(0x10, AIFIFO_Control_6143); /* Flush fifo */ @@ -742,13 +756,17 @@ static void ni_clear_ai_fifo(struct comedi_device *dev) static void win_out2(struct comedi_device *dev, uint32_t data, int reg) { + struct ni_private *devpriv = dev->private; + devpriv->stc_writew(dev, data >> 16, reg); devpriv->stc_writew(dev, data & 0xffff, reg + 1); } static uint32_t win_in2(struct comedi_device *dev, int reg) { + struct ni_private *devpriv = dev->private; uint32_t bits; + bits = devpriv->stc_readw(dev, reg) << 16; bits |= devpriv->stc_readw(dev, reg + 1); return bits; @@ -758,6 +776,7 @@ static uint32_t win_in2(struct comedi_device *dev, int reg) static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->window_lock, flags); @@ -769,6 +788,7 @@ static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data, static inline void ni_ao_win_outl(struct comedi_device *dev, uint32_t data, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->window_lock, flags); @@ -779,6 +799,7 @@ static inline void ni_ao_win_outl(struct comedi_device *dev, uint32_t data, static inline unsigned short ni_ao_win_inw(struct comedi_device *dev, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; unsigned short data; @@ -814,6 +835,7 @@ static inline void ni_set_bits(struct comedi_device *dev, int reg, static irqreturn_t ni_E_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct ni_private *devpriv = dev->private; unsigned short a_status; unsigned short b_status; unsigned int ai_mite_status = 0; @@ -872,6 +894,7 @@ static irqreturn_t ni_E_interrupt(int irq, void *d) #ifdef PCIDMA static void ni_sync_ai_dma(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; unsigned long flags; @@ -884,6 +907,7 @@ static void ni_sync_ai_dma(struct comedi_device *dev) static void mite_handle_b_linkc(struct mite_struct *mite, struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV]; unsigned long flags; @@ -896,6 +920,7 @@ static void mite_handle_b_linkc(struct mite_struct *mite, static int ni_ao_wait_for_dma_load(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; static const int timeout = 10000; int i; for (i = 0; i < timeout; i++) { @@ -918,6 +943,8 @@ static int ni_ao_wait_for_dma_load(struct comedi_device *dev) #endif /* PCIDMA */ static void ni_handle_eos(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv = dev->private; + if (devpriv->aimode == AIMODE_SCAN) { #ifdef PCIDMA static const int timeout = 10; @@ -984,6 +1011,7 @@ static void handle_gpct_interrupt(struct comedi_device *dev, unsigned short counter_index) { #ifdef PCIDMA + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s; s = &dev->subdevices[NI_GPCT_SUBDEV(counter_index)]; @@ -997,6 +1025,7 @@ static void handle_gpct_interrupt(struct comedi_device *dev, static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status) { + struct ni_private *devpriv = dev->private; unsigned short ack = 0; if (a_status & AI_SC_TC_St) { @@ -1019,6 +1048,7 @@ static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status) static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, unsigned ai_mite_status) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; /* 67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt */ @@ -1122,7 +1152,9 @@ static void handle_a_interrupt(struct comedi_device *dev, unsigned short status, static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status) { + struct ni_private *devpriv = dev->private; unsigned short ack = 0; + if (b_status & AO_BC_TC_St) { ack |= AO_BC_TC_Interrupt_Ack; } @@ -1151,8 +1183,10 @@ static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status) static void handle_b_interrupt(struct comedi_device *dev, unsigned short b_status, unsigned ao_mite_status) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV]; /* unsigned short ack=0; */ + #ifdef DEBUG_INTERRUPT printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n", b_status, ao_mite_status); @@ -1340,6 +1374,7 @@ static int ni_ao_fifo_half_empty(struct comedi_device *dev, static int ni_ao_prep_fifo(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv = dev->private; int n; /* reset fifo */ @@ -1364,6 +1399,7 @@ static int ni_ao_prep_fifo(struct comedi_device *dev, static void ni_ai_fifo_read(struct comedi_device *dev, struct comedi_subdevice *s, int n) { + struct ni_private *devpriv = dev->private; struct comedi_async *async = s->async; int i; @@ -1434,6 +1470,7 @@ static void ni_handle_fifo_half_full(struct comedi_device *dev) #ifdef PCIDMA static int ni_ai_drain_dma(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; int i; static const int timeout = 10000; unsigned long flags; @@ -1471,6 +1508,7 @@ static int ni_ai_drain_dma(struct comedi_device *dev) */ static void ni_handle_fifo_dregs(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; short data[2]; u32 dl; @@ -1535,6 +1573,7 @@ static void ni_handle_fifo_dregs(struct comedi_device *dev) static void get_last_sample_611x(struct comedi_device *dev) { + struct ni_private *devpriv __maybe_unused = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; short data; u32 dl; @@ -1552,6 +1591,7 @@ static void get_last_sample_611x(struct comedi_device *dev) static void get_last_sample_6143(struct comedi_device *dev) { + struct ni_private *devpriv __maybe_unused = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; short data; u32 dl; @@ -1574,11 +1614,13 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s, void *data, unsigned int num_bytes, unsigned int chan_index) { + struct ni_private *devpriv = dev->private; struct comedi_async *async = s->async; unsigned int i; unsigned int length = num_bytes / bytes_per_sample(s); short *array = data; unsigned int *larray = data; + for (i = 0; i < length; i++) { #ifdef PCIDMA if (s->subdev_flags & SDF_LSAMPL) @@ -1599,6 +1641,7 @@ static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_ai_setup_MITE_dma(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AI_SUBDEV]; int retval; unsigned long flags; @@ -1638,6 +1681,7 @@ static int ni_ai_setup_MITE_dma(struct comedi_device *dev) static int ni_ao_setup_MITE_dma(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[NI_AO_SUBDEV]; int retval; unsigned long flags; @@ -1676,6 +1720,8 @@ static int ni_ao_setup_MITE_dma(struct comedi_device *dev) static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv = dev->private; + ni_release_ai_mite_channel(dev); /* ai configuration */ devpriv->stc_writew(dev, AI_Configuration_Start | AI_Reset, @@ -1786,6 +1832,7 @@ static int ni_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; int i, n; const unsigned int mask = (1 << boardtype.adbits) - 1; unsigned signbits; @@ -1881,7 +1928,9 @@ static int ni_ai_insn_read(struct comedi_device *dev, static void ni_prime_channelgain_list(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; int i; + devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register); for (i = 0; i < NI_TIMEOUT; ++i) { if (!(devpriv->stc_readw(dev, @@ -1899,6 +1948,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev, unsigned int n_chan, unsigned int *list) { + struct ni_private *devpriv = dev->private; unsigned int chan, range, aref; unsigned int i; unsigned offset; @@ -2004,6 +2054,7 @@ static void ni_m_series_load_channelgain_list(struct comedi_device *dev, static void ni_load_channelgain_list(struct comedi_device *dev, unsigned int n_chan, unsigned int *list) { + struct ni_private *devpriv = dev->private; unsigned int chan, range, aref; unsigned int i; unsigned int hi, lo; @@ -2122,7 +2173,9 @@ static void ni_load_channelgain_list(struct comedi_device *dev, static int ni_ns_to_timer(const struct comedi_device *dev, unsigned nanosec, int round_mode) { + struct ni_private *devpriv = dev->private; int divider; + switch (round_mode) { case TRIG_ROUND_NEAREST: default: @@ -2140,6 +2193,8 @@ static int ni_ns_to_timer(const struct comedi_device *dev, unsigned nanosec, static unsigned ni_timer_to_ns(const struct comedi_device *dev, int timer) { + struct ni_private *devpriv = dev->private; + return devpriv->clock_ns * (timer + 1); } @@ -2162,6 +2217,7 @@ static unsigned ni_min_ai_scan_period_ns(struct comedi_device *dev, static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct ni_private *devpriv = dev->private; int err = 0; int tmp; unsigned int sources; @@ -2356,6 +2412,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv = dev->private; const struct comedi_cmd *cmd = &s->async->cmd; int timer; int mode1 = 0; /* mode1 is needed for both stop and convert */ @@ -2662,6 +2719,8 @@ static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { + struct ni_private *devpriv = dev->private; + if (trignum != 0) return -EINVAL; @@ -2681,6 +2740,8 @@ static int ni_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; + if (insn->n < 1) return -EINVAL; @@ -2734,6 +2795,7 @@ static int ni_ai_config_analog_trig(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; unsigned int a, b, modebits; int err = 0; @@ -2857,6 +2919,7 @@ static int ni_m_series_ao_config_chanlist(struct comedi_device *dev, unsigned int chanspec[], unsigned int n_chans, int timed) { + struct ni_private *devpriv = dev->private; unsigned int range; unsigned int chan; unsigned int conf; @@ -2928,6 +2991,7 @@ static int ni_old_ao_config_chanlist(struct comedi_device *dev, unsigned int chanspec[], unsigned int n_chans) { + struct ni_private *devpriv = dev->private; unsigned int range; unsigned int chan; unsigned int conf; @@ -2984,6 +3048,8 @@ static int ni_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; + data[0] = devpriv->ao[CR_CHAN(insn->chanspec)]; return 1; @@ -2993,6 +3059,7 @@ static int ni_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); unsigned int invert; @@ -3013,6 +3080,7 @@ static int ni_ao_insn_write_671x(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); unsigned int invert; @@ -3031,6 +3099,8 @@ static int ni_ao_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; + switch (data[0]) { case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE: switch (data[1]) { @@ -3057,6 +3127,7 @@ static int ni_ao_insn_config(struct comedi_device *dev, static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { + struct ni_private *devpriv = dev->private; int ret; int interrupt_b_bits; int i; @@ -3126,6 +3197,7 @@ static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv = dev->private; const struct comedi_cmd *cmd = &s->async->cmd; int bits; int i; @@ -3330,6 +3402,7 @@ static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct ni_private *devpriv = dev->private; int err = 0; int tmp; @@ -3438,6 +3511,8 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv = dev->private; + /* devpriv->ao0p=0x0000; */ /* ni_writew(devpriv->ao0p,AO_Configuration); */ @@ -3491,6 +3566,8 @@ static int ni_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; + #ifdef DEBUG_DIO printk("ni_dio_insn_config() chan=%d io=%d\n", CR_CHAN(insn->chanspec), data[0]); @@ -3524,6 +3601,8 @@ static int ni_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; + #ifdef DEBUG_DIO printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]); #endif @@ -3552,6 +3631,8 @@ static int ni_m_series_dio_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv __maybe_unused = dev->private; + #ifdef DEBUG_DIO printk("ni_m_series_dio_insn_config() chan=%d io=%d\n", CR_CHAN(insn->chanspec), data[0]); @@ -3584,6 +3665,8 @@ static int ni_m_series_dio_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv __maybe_unused = dev->private; + #ifdef DEBUG_DIO printk("ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]); @@ -3680,6 +3763,7 @@ static int ni_cdio_cmdtest(struct comedi_device *dev, static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv __maybe_unused = dev->private; const struct comedi_cmd *cmd = &s->async->cmd; unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit; int retval; @@ -3719,6 +3803,7 @@ static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { #ifdef PCIDMA + struct ni_private *devpriv = dev->private; unsigned long flags; #endif int retval = 0; @@ -3766,6 +3851,8 @@ static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv __maybe_unused = dev->private; + ni_writel(CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit | CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit | CDO_FIFO_Request_Interrupt_Enable_Clear_Bit, @@ -3781,6 +3868,7 @@ static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static void handle_cdio_interrupt(struct comedi_device *dev) { + struct ni_private *devpriv __maybe_unused = dev->private; unsigned cdio_status; struct comedi_subdevice *s = &dev->subdevices[NI_DIO_SUBDEV]; #ifdef PCIDMA @@ -3824,6 +3912,7 @@ static int ni_serial_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; int err = insn->n; unsigned char byte_out, byte_in = 0; @@ -3920,6 +4009,7 @@ static int ni_serial_hw_readwrite8(struct comedi_device *dev, unsigned char data_out, unsigned char *data_in) { + struct ni_private *devpriv = dev->private; unsigned int status1; int err = 0, count = 20; @@ -3978,6 +4068,7 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, unsigned char data_out, unsigned char *data_in) { + struct ni_private *devpriv = dev->private; unsigned char mask, input = 0; #ifdef DEBUG_DIO @@ -4031,9 +4122,10 @@ static int ni_serial_sw_readwrite8(struct comedi_device *dev, static void mio_common_detach(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s; - if (dev->private) { + if (devpriv) { if (devpriv->counter_dev) { ni_gpct_device_destroy(devpriv->counter_dev); } @@ -4151,6 +4243,7 @@ static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; + struct ni_private *devpriv = dev->private; unsigned stc_register; /* bits in the join reset register which are relevant to counters */ static const unsigned gpct_joint_reset_mask = G0_Reset | G1_Reset; @@ -4219,7 +4312,9 @@ static unsigned ni_gpct_read_register(struct ni_gpct *counter, enum ni_gpct_register reg) { struct comedi_device *dev = counter->counter_dev->dev; + struct ni_private *devpriv = dev->private; unsigned stc_register; + switch (reg) { /* m-series only registers */ case NITIO_G0_DMA_Status_Reg: @@ -4251,6 +4346,8 @@ static int ni_freq_out_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; + data[0] = devpriv->clock_and_fout & FOUT_Divider_mask; return 1; } @@ -4259,6 +4356,8 @@ static int ni_freq_out_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; + devpriv->clock_and_fout &= ~FOUT_Enable; devpriv->stc_writew(dev, devpriv->clock_and_fout, Clock_and_FOUT_Register); @@ -4273,6 +4372,8 @@ static int ni_freq_out_insn_write(struct comedi_device *dev, static int ni_set_freq_out_clock(struct comedi_device *dev, unsigned int clock_source) { + struct ni_private *devpriv = dev->private; + switch (clock_source) { case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC: devpriv->clock_and_fout &= ~FOUT_Timebase_Select; @@ -4292,6 +4393,8 @@ static void ni_get_freq_out_clock(struct comedi_device *dev, unsigned int *clock_source, unsigned int *clock_period_ns) { + struct ni_private *devpriv = dev->private; + if (devpriv->clock_and_fout & FOUT_Timebase_Select) { *clock_source = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC; *clock_period_ns = TIMEBASE_2_NS; @@ -4320,11 +4423,13 @@ static int ni_freq_out_insn_config(struct comedi_device *dev, static int ni_alloc_private(struct comedi_device *dev) { + struct ni_private *devpriv; int ret; - ret = alloc_private(dev, sizeof(struct ni_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; spin_lock_init(&devpriv->window_lock); spin_lock_init(&devpriv->soft_reg_copy_lock); @@ -4335,6 +4440,7 @@ static int ni_alloc_private(struct comedi_device *dev) static int ni_E_init(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; struct comedi_subdevice *s; unsigned j; enum ni_gpct_variant counter_variant; @@ -4661,6 +4767,7 @@ static int ni_E_init(struct comedi_device *dev) static int ni_8255_callback(int dir, int port, int data, unsigned long arg) { struct comedi_device *dev = (struct comedi_device *)arg; + struct ni_private *devpriv __maybe_unused = dev->private; if (dir) { ni_writeb(data, Port_A + 2 * port); @@ -4689,6 +4796,7 @@ static int ni_eeprom_insn_read(struct comedi_device *dev, static int ni_read_eeprom(struct comedi_device *dev, int addr) { + struct ni_private *devpriv __maybe_unused = dev->private; int bit; int bitstring; @@ -4716,6 +4824,8 @@ static int ni_m_series_eeprom_insn_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; + data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)]; return 1; @@ -4723,6 +4833,8 @@ static int ni_m_series_eeprom_insn_read(struct comedi_device *dev, static int ni_get_pwm_config(struct comedi_device *dev, unsigned int *data) { + struct ni_private *devpriv = dev->private; + data[1] = devpriv->pwm_up_count * devpriv->clock_ns; data[2] = devpriv->pwm_down_count * devpriv->clock_ns; return 3; @@ -4732,7 +4844,9 @@ static int ni_m_series_pwm_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; unsigned up_count, down_count; + switch (data[0]) { case INSN_CONFIG_PWM_OUTPUT: switch (data[1]) { @@ -4798,7 +4912,9 @@ static int ni_6143_pwm_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; unsigned up_count, down_count; + switch (data[0]) { case INSN_CONFIG_PWM_OUTPUT: switch (data[1]) { @@ -4875,6 +4991,8 @@ static int ni_calib_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; + data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)]; return 1; @@ -4905,6 +5023,7 @@ static struct caldac_struct caldacs[] = { static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni_private *devpriv = dev->private; int i, j; int n_dacs; int n_chans = 0; @@ -4958,6 +5077,7 @@ static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s) static void ni_write_caldac(struct comedi_device *dev, int addr, int val) { + struct ni_private *devpriv = dev->private; unsigned int loadbit = 0, bits = 0, bit, bitstring = 0; int i; int type; @@ -5211,8 +5331,10 @@ static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_m_series_set_pfi_routing(struct comedi_device *dev, unsigned chan, unsigned source) { + struct ni_private *devpriv = dev->private; unsigned pfi_reg_index; unsigned array_offset; + if ((source & 0x1f) != source) return -EINVAL; pfi_reg_index = 1 + chan / 3; @@ -5247,7 +5369,9 @@ static int ni_set_pfi_routing(struct comedi_device *dev, unsigned chan, static unsigned ni_m_series_get_pfi_routing(struct comedi_device *dev, unsigned chan) { + struct ni_private *devpriv = dev->private; const unsigned array_offset = chan / 3; + return MSeries_PFI_Output_Select_Source(chan, devpriv-> pfi_output_select_reg @@ -5306,7 +5430,9 @@ static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan) static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel, enum ni_pfi_filter_select filter) { + struct ni_private *devpriv __maybe_unused = dev->private; unsigned bits; + if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) { return -ENOTSUPP; } @@ -5321,6 +5447,8 @@ static int ni_pfi_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv __maybe_unused = dev->private; + if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) { return -ENOTSUPP; } @@ -5337,6 +5465,7 @@ static int ni_pfi_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; unsigned int chan; if (insn->n < 1) @@ -5379,6 +5508,8 @@ static int ni_pfi_insn_config(struct comedi_device *dev, */ static void ni_rtsi_init(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; + /* Initialises the RTSI bus signal switch to a default state */ /* Set clock mode to internal */ @@ -5480,6 +5611,7 @@ static inline unsigned num_configurable_rtsi_channels(struct comedi_device *dev) static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, unsigned source, unsigned period_ns) { + struct ni_private *devpriv = dev->private; static const unsigned min_period_ns = 50; static const unsigned max_period_ns = 1000; static const unsigned timeout = 1000; @@ -5488,6 +5620,7 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, unsigned freq_multiplier; unsigned i; int retval; + if (source == NI_MIO_PLL_PXI10_CLOCK) period_ns = 100; /* these limits are somewhat arbitrary, but NI advertises 1 to 20MHz range so we'll use that */ @@ -5581,6 +5714,8 @@ static int ni_mseries_set_pll_master_clock(struct comedi_device *dev, static int ni_set_master_clock(struct comedi_device *dev, unsigned source, unsigned period_ns) { + struct ni_private *devpriv = dev->private; + if (source == NI_MIO_INTERNAL_CLOCK) { devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit; devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg, @@ -5666,6 +5801,8 @@ static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan, static int ni_set_rtsi_routing(struct comedi_device *dev, unsigned chan, unsigned source) { + struct ni_private *devpriv = dev->private; + if (ni_valid_rtsi_output_source(dev, chan, source) == 0) return -EINVAL; if (chan < 4) { @@ -5686,6 +5823,8 @@ static int ni_set_rtsi_routing(struct comedi_device *dev, unsigned chan, static unsigned ni_get_rtsi_routing(struct comedi_device *dev, unsigned chan) { + struct ni_private *devpriv = dev->private; + if (chan < 4) { return RTSI_Trig_Output_Source(chan, devpriv->rtsi_trig_a_output_reg); @@ -5704,7 +5843,9 @@ static int ni_rtsi_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); + switch (data[0]) { case INSN_CONFIG_DIO_OUTPUT: if (chan < num_configurable_rtsi_channels(dev)) { diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index ca4f8e06e75..b5b43e41f3f 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -177,8 +177,6 @@ struct ni_private { NI_PRIVATE_COMMON}; -#define devpriv ((struct ni_private *)dev->private) - /* How we access registers */ #define ni_writel(a, b) (outl((a), (b)+dev->iobase)) @@ -196,6 +194,7 @@ struct ni_private { static void mio_cs_win_out(struct comedi_device *dev, uint16_t data, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->window_lock, flags); @@ -210,6 +209,7 @@ static void mio_cs_win_out(struct comedi_device *dev, uint16_t data, int addr) static uint16_t mio_cs_win_in(struct comedi_device *dev, int addr) { + struct ni_private *devpriv = dev->private; unsigned long flags; uint16_t ret; @@ -324,6 +324,7 @@ static void mio_cs_config(struct pcmcia_device *link) static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct ni_private *devpriv; struct pcmcia_device *link; unsigned int irq; int ret; @@ -372,10 +373,10 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->irq = irq; - /* allocate private area */ ret = ni_alloc_private(dev); - if (ret < 0) + if (ret) return ret; + devpriv = dev->private; devpriv->stc_writew = &mio_cs_win_out; devpriv->stc_readw = &mio_cs_win_in; diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index f284a90720e..8723e84826c 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1190,7 +1190,6 @@ static const struct ni_board_struct ni_boards[] = { struct ni_private { NI_PRIVATE_COMMON}; -#define devpriv ((struct ni_private *)dev->private) /* How we access registers */ @@ -1213,6 +1212,7 @@ NI_PRIVATE_COMMON}; static void e_series_win_out(struct comedi_device *dev, uint16_t data, int reg) { + struct ni_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->window_lock, flags); @@ -1223,6 +1223,7 @@ static void e_series_win_out(struct comedi_device *dev, uint16_t data, int reg) static uint16_t e_series_win_in(struct comedi_device *dev, int reg) { + struct ni_private *devpriv = dev->private; unsigned long flags; uint16_t ret; @@ -1237,7 +1238,9 @@ static uint16_t e_series_win_in(struct comedi_device *dev, int reg) static void m_series_stc_writew(struct comedi_device *dev, uint16_t data, int reg) { + struct ni_private *devpriv = dev->private; unsigned offset; + switch (reg) { case ADC_FIFO_Clear: offset = M_Offset_AI_FIFO_Clear; @@ -1392,7 +1395,9 @@ static void m_series_stc_writew(struct comedi_device *dev, uint16_t data, static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg) { + struct ni_private *devpriv = dev->private; unsigned offset; + switch (reg) { case AI_Status_1_Register: offset = M_Offset_AI_Status_1; @@ -1428,7 +1433,9 @@ static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg) static void m_series_stc_writel(struct comedi_device *dev, uint32_t data, int reg) { + struct ni_private *devpriv = dev->private; unsigned offset; + switch (reg) { case AI_SC_Load_A_Registers: offset = M_Offset_AI_SC_Load_A; @@ -1469,7 +1476,9 @@ static void m_series_stc_writel(struct comedi_device *dev, uint32_t data, static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg) { + struct ni_private *devpriv = dev->private; unsigned offset; + switch (reg) { case G_HW_Save_Register(0): offset = M_Offset_G0_HW_Save; @@ -1516,6 +1525,7 @@ static int pcimio_dio_change(struct comedi_device *dev, static void m_series_init_eeprom_buffer(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; static const int Start_Cal_EEPROM = 0x400; static const unsigned window_size = 10; static const int serial_number_eeprom_offset = 0x4; @@ -1553,6 +1563,8 @@ static void m_series_init_eeprom_buffer(struct comedi_device *dev) static void init_6143(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; + /* Disable interrupts */ devpriv->stc_writew(dev, 0, Interrupt_Control_Register); @@ -1572,10 +1584,12 @@ static void init_6143(struct comedi_device *dev) static void pcimio_detach(struct comedi_device *dev) { + struct ni_private *devpriv = dev->private; + mio_common_detach(dev); if (dev->irq) free_irq(dev->irq, dev); - if (dev->private) { + if (devpriv) { mite_free_ring(devpriv->ai_mite_ring); mite_free_ring(devpriv->ao_mite_ring); mite_free_ring(devpriv->cdo_mite_ring); @@ -1605,13 +1619,15 @@ pcimio_find_boardinfo(struct pci_dev *pcidev) static int __devinit pcimio_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { + struct ni_private *devpriv; int ret; dev_info(dev->class_dev, "ni_pcimio: attach %s\n", pci_name(pcidev)); ret = ni_alloc_private(dev); - if (ret < 0) + if (ret) return ret; + devpriv = dev->private; dev->board_ptr = pcimio_find_boardinfo(pcidev); if (!dev->board_ptr) @@ -1693,6 +1709,7 @@ static int __devinit pcimio_attach_pci(struct comedi_device *dev, static int pcimio_ai_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct ni_private *devpriv = dev->private; int ret; ret = mite_buf_change(devpriv->ai_mite_ring, s->async); @@ -1705,6 +1722,7 @@ static int pcimio_ai_change(struct comedi_device *dev, static int pcimio_ao_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct ni_private *devpriv = dev->private; int ret; ret = mite_buf_change(devpriv->ao_mite_ring, s->async); @@ -1718,6 +1736,7 @@ static int pcimio_gpct0_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct ni_private *devpriv = dev->private; int ret; ret = mite_buf_change(devpriv->gpct_mite_ring[0], s->async); @@ -1731,6 +1750,7 @@ static int pcimio_gpct1_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct ni_private *devpriv = dev->private; int ret; ret = mite_buf_change(devpriv->gpct_mite_ring[1], s->async); @@ -1743,6 +1763,7 @@ static int pcimio_gpct1_change(struct comedi_device *dev, static int pcimio_dio_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct ni_private *devpriv = dev->private; int ret; ret = mite_buf_change(devpriv->cdo_mite_ring, s->async); -- cgit v1.2.3 From 9a1a6cf8ae5ca58171e117335b9983e3cfa2185c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 15 Oct 2012 10:15:52 -0700 Subject: staging: comedi: drivers: remove remaining devpriv macros The remaining comedi drivers that still have a devpriv macro are all pretty straight forward for removing the devpriv macro. This macro relies on a local variable having a specific name. Remove its use by replacing it with a local variable where used. The inline function alloc_private(), used to kzalloc the dev->private memory, returns non-zero if there is an error. Fix all the alloc_private() calls accordingly and remove any kernel messages or obvious comments that still exist in the drivers. Leave a comment in the skel driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255_pci.c | 2 +- drivers/staging/comedi/drivers/adl_pci6208.c | 2 +- drivers/staging/comedi/drivers/adl_pci9118.c | 6 ++-- drivers/staging/comedi/drivers/adv_pci1710.c | 2 +- drivers/staging/comedi/drivers/adv_pci1723.c | 2 +- drivers/staging/comedi/drivers/adv_pci_dio.c | 2 +- drivers/staging/comedi/drivers/amplc_dio200.c | 18 +++++----- drivers/staging/comedi/drivers/amplc_pc236.c | 20 ++++++----- drivers/staging/comedi/drivers/amplc_pci224.c | 16 ++++----- drivers/staging/comedi/drivers/amplc_pci230.c | 16 +++++---- drivers/staging/comedi/drivers/cb_das16_cs.c | 7 ++-- drivers/staging/comedi/drivers/comedi_parport.c | 2 +- drivers/staging/comedi/drivers/comedi_test.c | 2 +- drivers/staging/comedi/drivers/daqboard2000.c | 4 +-- drivers/staging/comedi/drivers/das08.c | 12 ++++--- drivers/staging/comedi/drivers/das08_cs.c | 6 ++-- drivers/staging/comedi/drivers/das16.c | 21 +++++++++-- drivers/staging/comedi/drivers/das16m1.c | 16 +++++++-- drivers/staging/comedi/drivers/das1800.c | 30 ++++++++++++---- drivers/staging/comedi/drivers/das6402.c | 14 ++++++-- drivers/staging/comedi/drivers/das800.c | 20 ++++++++--- drivers/staging/comedi/drivers/dmm32at.c | 5 +-- drivers/staging/comedi/drivers/dt2801.c | 12 ++++--- drivers/staging/comedi/drivers/dt2811.c | 11 +++--- drivers/staging/comedi/drivers/dt2814.c | 10 +++--- drivers/staging/comedi/drivers/dt2815.c | 11 +++--- drivers/staging/comedi/drivers/dt282x.c | 31 ++++++++++++++-- drivers/staging/comedi/drivers/dt3000.c | 23 +++++++++--- drivers/staging/comedi/drivers/dt9812.c | 16 ++++++--- drivers/staging/comedi/drivers/fl512.c | 12 ++++--- drivers/staging/comedi/drivers/icp_multi.c | 2 +- drivers/staging/comedi/drivers/ii_pci20kc.c | 14 +++++--- drivers/staging/comedi/drivers/jr3_pci.c | 9 ++--- drivers/staging/comedi/drivers/me_daq.c | 22 +++++++++--- drivers/staging/comedi/drivers/mpc624.c | 12 ++++--- drivers/staging/comedi/drivers/multiq3.c | 9 +++-- drivers/staging/comedi/drivers/ni_6527.c | 21 ++++++++--- drivers/staging/comedi/drivers/ni_670x.c | 3 +- drivers/staging/comedi/drivers/ni_at_a2150.c | 22 +++++++++--- drivers/staging/comedi/drivers/ni_at_ao.c | 15 +++++--- drivers/staging/comedi/drivers/ni_atmio16d.c | 13 +++++-- drivers/staging/comedi/drivers/ni_daq_dio24.c | 10 +++--- drivers/staging/comedi/drivers/ni_labpc.c | 48 +++++++++++++++++++++---- drivers/staging/comedi/drivers/ni_labpc_cs.c | 9 +++-- drivers/staging/comedi/drivers/ni_pcidio.c | 32 +++++++++++++++-- drivers/staging/comedi/drivers/pcl711.c | 13 ++++--- drivers/staging/comedi/drivers/pcl726.c | 12 ++++--- drivers/staging/comedi/drivers/pcl812.c | 27 ++++++++++---- drivers/staging/comedi/drivers/pcl816.c | 21 ++++++++--- drivers/staging/comedi/drivers/pcl818.c | 32 +++++++++++++---- drivers/staging/comedi/drivers/pcm3724.c | 14 ++++---- drivers/staging/comedi/drivers/pcmad.c | 8 +++-- drivers/staging/comedi/drivers/pcmda12.c | 17 ++++----- drivers/staging/comedi/drivers/pcmmio.c | 31 ++++++++-------- drivers/staging/comedi/drivers/pcmuio.c | 27 +++++++------- drivers/staging/comedi/drivers/rtd520.c | 9 ++--- drivers/staging/comedi/drivers/rti800.c | 11 +++--- drivers/staging/comedi/drivers/rti802.c | 11 +++--- drivers/staging/comedi/drivers/serial2002.c | 24 ++++++++----- drivers/staging/comedi/drivers/skel.c | 20 +++++------ 60 files changed, 597 insertions(+), 272 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 7dff3c01dc2..af76e4e3e40 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -236,7 +236,7 @@ static int pci_8255_attach_pci(struct comedi_device *dev, dev->board_name = board->name; ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) + if (ret) return ret; devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 3492ce1156e..de3625224c8 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -192,7 +192,7 @@ static int pci6208_attach_pci(struct comedi_device *dev, dev->board_name = boardinfo->name; ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) + if (ret) return ret; devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 06ff65c85c9..4eca8764685 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -1924,10 +1924,8 @@ static int pci9118_attach(struct comedi_device *dev, master = 1; ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) { - printk(" - Allocation failed!\n"); - return -ENOMEM; - } + if (ret) + return ret; devpriv = dev->private; pcidev = pci9118_find_pci(dev, it); diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index def37bcc2a6..322d0118dcc 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1274,7 +1274,7 @@ static int pci1710_attach_pci(struct comedi_device *dev, dev->board_name = this_board->name; ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) + if (ret) return ret; devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index df4efc0606d..3c932e7309b 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -245,7 +245,7 @@ static int pci1723_attach_pci(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) + if (ret) return ret; devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index a3c22419cd5..8fa61592bbf 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1109,7 +1109,7 @@ static int pci_dio_attach_pci(struct comedi_device *dev, dev->board_name = this_board->name; ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) + if (ret) return ret; devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 08f305210a6..556c6330432 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1334,15 +1334,15 @@ static int dio200_pci_common_attach(struct comedi_device *dev, static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv; int ret; dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach\n"); - ret = alloc_private(dev, sizeof(struct dio200_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; - } + devpriv = dev->private; /* Process options and reserve resources according to bus type. */ if (is_isa_board(thisboard)) { @@ -1377,6 +1377,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int __devinit dio200_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { + struct dio200_private *devpriv; int ret; if (!DO_PCI) @@ -1384,11 +1385,12 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach pci %s\n", pci_name(pci_dev)); - ret = alloc_private(dev, sizeof(struct dio200_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); + + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; - } + devpriv = dev->private; + dev->board_ptr = dio200_find_pci_board(pci_dev); if (dev->board_ptr == NULL) { dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index eacb5e4735d..56354aa2708 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -505,14 +505,16 @@ static int pc236_pci_common_attach(struct comedi_device *dev, static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pc236_board *thisboard = comedi_board(dev); + struct pc236_private *devpriv; int ret; dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach\n"); - ret = alloc_private(dev, sizeof(struct pc236_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); + + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; - } + devpriv = dev->private; + /* Process options according to bus type. */ if (is_isa_board(thisboard)) { unsigned long iobase = it->options[0]; @@ -543,6 +545,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int __devinit pc236_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { + struct pc236_private *devpriv; int ret; if (!DO_PCI) @@ -550,11 +553,12 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach pci %s\n", pci_name(pci_dev)); - ret = alloc_private(dev, sizeof(struct pc236_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); + + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; - } + devpriv = dev->private; + dev->board_ptr = pc236_find_pci_board(pci_dev); if (dev->board_ptr == NULL) { dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 1f65ec4d261..5d73082adfc 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1443,16 +1443,16 @@ static int pci224_attach_common(struct comedi_device *dev, static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct pci224_private *devpriv; struct pci_dev *pci_dev; int ret; dev_info(dev->class_dev, DRIVER_NAME ": attach\n"); - ret = alloc_private(dev, sizeof(struct pci224_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; - } + devpriv = dev->private; pci_dev = pci224_find_pci_dev(dev, it); if (!pci_dev) @@ -1464,16 +1464,16 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int __devinit pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { + struct pci224_private *devpriv; int ret; dev_info(dev->class_dev, DRIVER_NAME ": attach_pci %s\n", pci_name(pci_dev)); - ret = alloc_private(dev, sizeof(struct pci224_private)); - if (ret < 0) { - dev_err(dev->class_dev, "error! out of memory!\n"); + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; - } + devpriv = dev->private; dev->board_ptr = pci224_find_pci_board(pci_dev); if (dev->board_ptr == NULL) { diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index bd8fb876ce2..cf454b9cb29 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2662,13 +2662,11 @@ static int pci230_alloc_private(struct comedi_device *dev) struct pci230_private *devpriv; int err; - /* sets dev->private to allocated memory */ - err = alloc_private(dev, sizeof(struct pci230_private)); - if (err) { - dev_err(dev->class_dev, "error! out of memory!\n"); + err = alloc_private(dev, sizeof(*devpriv)); + if (err) return err; - } devpriv = dev->private; + spin_lock_init(&devpriv->isr_spinlock); spin_lock_init(&devpriv->res_spinlock); spin_lock_init(&devpriv->ai_stop_spinlock); @@ -2836,9 +2834,11 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_info(dev->class_dev, "amplc_pci230: attach %s %d,%d\n", thisboard->name, it->options[0], it->options[1]); - rc = pci230_alloc_private(dev); /* sets dev->private */ + + rc = pci230_alloc_private(dev); if (rc) return rc; + pci_dev = pci230_find_pci_dev(dev, it); if (!pci_dev) return -EIO; @@ -2852,9 +2852,11 @@ static int __devinit pci230_attach_pci(struct comedi_device *dev, dev_info(dev->class_dev, "amplc_pci230: attach pci %s\n", pci_name(pci_dev)); - rc = pci230_alloc_private(dev); /* sets dev->private */ + + rc = pci230_alloc_private(dev); if (rc) return rc; + dev->board_ptr = pci230_find_pci_board(pci_dev); if (dev->board_ptr == NULL) { dev_err(dev->class_dev, diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 6d81d8b40cc..64442b36066 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -428,6 +428,7 @@ static int das16cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das16cs_board *thisboard; + struct das16cs_private *devpriv; struct pcmcia_device *link; struct comedi_subdevice *s; int ret; @@ -451,8 +452,10 @@ static int das16cs_attach(struct comedi_device *dev, return ret; dev->irq = link->irq; - if (alloc_private(dev, sizeof(struct das16cs_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; ret = comedi_alloc_subdevices(dev, 3); if (ret) diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 22ef9424259..a1371c5a7d8 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -306,7 +306,7 @@ static int parport_attach(struct comedi_device *dev, return ret; ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) + if (ret) return ret; devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 7817def1556..788a5cc89e2 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -415,7 +415,7 @@ static int waveform_attach(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) + if (ret) return ret; devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index d13c8c5822b..6bc51fcc688 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -707,8 +707,8 @@ static int daqboard2000_attach_pci(struct comedi_device *dev, dev->board_name = board->name; result = alloc_private(dev, sizeof(*devpriv)); - if (result < 0) - return -ENOMEM; + if (result) + return result; devpriv = dev->private; result = comedi_pci_enable(pcidev, dev->driver->driver_name); diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 5fd21fa6c1c..19c2907c384 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -778,14 +778,18 @@ das08_find_pci_board(struct pci_dev *pdev) static int __devinit __maybe_unused das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) { + struct das08_private_struct *devpriv; unsigned long iobase; int ret; if (!DO_PCI) return -EINVAL; - ret = alloc_private(dev, sizeof(struct das08_private_struct)); - if (ret < 0) + + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; + dev_info(dev->class_dev, "attach pci %s\n", pci_name(pdev)); dev->board_ptr = das08_find_pci_board(pdev); if (dev->board_ptr == NULL) { @@ -812,8 +816,8 @@ das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) int ret; unsigned long iobase; - ret = alloc_private(dev, sizeof(struct das08_private_struct)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index e4c91e67537..d908d2d04f8 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -90,13 +90,15 @@ static int das08_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das08_board_struct *thisboard = comedi_board(dev); + struct das08_private_struct *devpriv; int ret; unsigned long iobase; struct pcmcia_device *link = cur_dev; /* XXX hack */ - ret = alloc_private(dev, sizeof(struct das08_private_struct)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; dev_info(dev->class_dev, "das08_cs: attach\n"); /* deal with a pci board */ diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index fcb8a32adb2..3f614dcde8b 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -392,12 +392,12 @@ struct das16_private_struct { volatile short timer_running; volatile short timer_mode; /* true if using timer mode */ }; -#define devpriv ((struct das16_private_struct *)(dev->private)) static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; int err = 0, tmp; int gain, start_chan, i; int mask; @@ -540,6 +540,7 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, static unsigned int das16_suggest_transfer_size(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct das16_private_struct *devpriv = dev->private; unsigned int size; unsigned int freq; @@ -581,6 +582,8 @@ static unsigned int das16_suggest_transfer_size(struct comedi_device *dev, static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns, int rounding_flags) { + struct das16_private_struct *devpriv = dev->private; + i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1), &(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK); @@ -595,6 +598,7 @@ static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns, static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int byte; @@ -701,6 +705,7 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&dev->spinlock, flags); @@ -738,6 +743,7 @@ static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; int i, n; int range; int chan; @@ -848,10 +854,12 @@ static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, */ static int disable_dma_on_even(struct comedi_device *dev) { + struct das16_private_struct *devpriv = dev->private; int residue; int i; static const int disable_limit = 100; static const int enable_timeout = 100; + disable_dma(devpriv->dma_chan); residue = get_dma_residue(devpriv->dma_chan); for (i = 0; i < disable_limit && (residue % 2); ++i) { @@ -877,6 +885,7 @@ static int disable_dma_on_even(struct comedi_device *dev) static void das16_interrupt(struct comedi_device *dev) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; unsigned long dma_flags, spin_flags; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async; @@ -973,6 +982,7 @@ static irqreturn_t das16_dma_interrupt(int irq, void *d) static void das16_timer_interrupt(unsigned long arg) { struct comedi_device *dev = (struct comedi_device *)arg; + struct das16_private_struct *devpriv = dev->private; das16_interrupt(dev); @@ -1001,6 +1011,7 @@ static void reg_dump(struct comedi_device *dev) static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; int status; int diobits; @@ -1035,6 +1046,7 @@ static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it) static int das1600_mode_detect(struct comedi_device *dev) { + struct das16_private_struct *devpriv = dev->private; int status = 0; status = inb(dev->iobase + DAS1600_STATUS_B); @@ -1080,6 +1092,7 @@ static void das16_ai_munge(struct comedi_device *dev, static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv; struct comedi_subdevice *s; int ret; unsigned int irq; @@ -1114,9 +1127,10 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } - ret = alloc_private(dev, sizeof(struct das16_private_struct)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; if (board->size < 0x400) { printk(" 0x%04lx-0x%04lx\n", iobase, iobase + board->size); @@ -1353,6 +1367,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void das16_detach(struct comedi_device *dev) { const struct das16_board *board = comedi_board(dev); + struct das16_private_struct *devpriv = dev->private; das16_reset(dev); if (dev->subdevices) diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index c43172750ab..b06f2b8aad6 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -144,7 +144,6 @@ struct das16m1_private_struct { unsigned int divisor1; /* divides master clock to obtain conversion speed */ unsigned int divisor2; /* divides master clock to obtain conversion speed */ }; -#define devpriv ((struct das16m1_private_struct *)(dev->private)) static inline short munge_sample(short data) { @@ -162,6 +161,7 @@ static void munge_sample_array(short *array, unsigned int num_elements) static int das16m1_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct das16m1_private_struct *devpriv = dev->private; unsigned int err = 0, tmp, i; /* Step 1 : check if triggers are trivially valid */ @@ -271,6 +271,8 @@ static int das16m1_cmd_test(struct comedi_device *dev, static unsigned int das16m1_set_pacer(struct comedi_device *dev, unsigned int ns, int rounding_flags) { + struct das16m1_private_struct *devpriv = dev->private; + i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL, &(devpriv->divisor1), &(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK); @@ -287,6 +289,7 @@ static unsigned int das16m1_set_pacer(struct comedi_device *dev, static int das16m1_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das16m1_private_struct *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned int byte, i; @@ -350,6 +353,8 @@ static int das16m1_cmd_exec(struct comedi_device *dev, static int das16m1_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das16m1_private_struct *devpriv = dev->private; + devpriv->control_state &= ~INTE & ~PACER_MASK; outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL); @@ -360,6 +365,7 @@ static int das16m1_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das16m1_private_struct *devpriv = dev->private; int i, n; int byte; const int timeout = 1000; @@ -411,6 +417,7 @@ static int das16m1_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das16m1_private_struct *devpriv = dev->private; unsigned int wbits; /* only set bits that have been masked */ @@ -430,6 +437,7 @@ static int das16m1_do_wbits(struct comedi_device *dev, static void das16m1_handler(struct comedi_device *dev, unsigned int status) { + struct das16m1_private_struct *devpriv = dev->private; struct comedi_subdevice *s; struct comedi_async *async; struct comedi_cmd *cmd; @@ -576,6 +584,7 @@ static int das16m1_irq_bits(unsigned int irq) static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct das16m1_private_struct *devpriv; struct comedi_subdevice *s; int ret; unsigned int irq; @@ -585,9 +594,10 @@ static int das16m1_attach(struct comedi_device *dev, iobase = it->options[0]; - ret = alloc_private(dev, sizeof(struct das16m1_private_struct)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; if (!request_region(iobase, DAS16M1_SIZE, dev->board_name)) { comedi_error(dev, "I/O port conflict\n"); diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 2555f3297d7..3754fcb8353 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -454,8 +454,6 @@ struct das1800_private { short ao_update_bits; /* remembers the last write to the 'update' dac */ }; -#define devpriv ((struct das1800_private *)dev->private) - /* analog out range for boards with basic analog out */ static const struct comedi_lrange range_ao_1 = { 1, @@ -501,6 +499,7 @@ static void munge_data(struct comedi_device *dev, uint16_t * array, static void das1800_handle_fifo_half_full(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das1800_private *devpriv = dev->private; int numPoints = 0; /* number of points to read */ struct comedi_cmd *cmd = &s->async->cmd; @@ -520,6 +519,7 @@ static void das1800_handle_fifo_half_full(struct comedi_device *dev, static void das1800_handle_fifo_not_empty(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das1800_private *devpriv = dev->private; short dpnt; int unipolar; struct comedi_cmd *cmd = &s->async->cmd; @@ -548,6 +548,7 @@ static void das1800_flush_dma_channel(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int channel, uint16_t *buffer) { + struct das1800_private *devpriv = dev->private; unsigned int num_bytes, num_samples; struct comedi_cmd *cmd = &s->async->cmd; @@ -578,6 +579,7 @@ static void das1800_flush_dma_channel(struct comedi_device *dev, static void das1800_flush_dma(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das1800_private *devpriv = dev->private; unsigned long flags; const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; @@ -609,6 +611,7 @@ static void das1800_flush_dma(struct comedi_device *dev, static void das1800_handle_dma(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int status) { + struct das1800_private *devpriv = dev->private; unsigned long flags; const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; @@ -643,6 +646,8 @@ static void das1800_handle_dma(struct comedi_device *dev, static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das1800_private *devpriv = dev->private; + outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ @@ -656,6 +661,7 @@ static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) /* the guts of the interrupt handler, that is shared with das1800_ai_poll */ static void das1800_ai_handler(struct comedi_device *dev) { + struct das1800_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; @@ -783,6 +789,7 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct das1800_private *devpriv = dev->private; int err = 0; unsigned int tmp_arg; int i; @@ -1006,6 +1013,7 @@ static int control_c_bits(const struct comedi_cmd *cmd) /* loads counters with divisor1, divisor2 from private structure */ static int das1800_set_frequency(struct comedi_device *dev) { + struct das1800_private *devpriv = dev->private; int err = 0; /* counter 1, mode 2 */ @@ -1026,6 +1034,7 @@ static int das1800_set_frequency(struct comedi_device *dev) static int setup_counters(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct das1800_private *devpriv = dev->private; unsigned int period; /* setup cascaded counters for conversion/scan frequency */ @@ -1107,6 +1116,7 @@ static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd) /* sets up dma */ static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) { + struct das1800_private *devpriv = dev->private; unsigned long lock_flags; const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; @@ -1174,6 +1184,7 @@ static void program_chanlist(struct comedi_device *dev, static int das1800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das1800_private *devpriv = dev->private; int ret; int control_a, control_c; struct comedi_async *async = s->async; @@ -1300,6 +1311,7 @@ static int das1800_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das1800_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); /* int range = CR_RANGE(insn->chanspec); */ int update_chan = thisboard->ao_n_chan - 1; @@ -1342,6 +1354,7 @@ static int das1800_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das1800_private *devpriv = dev->private; unsigned int wbits; /* only set bits that have been masked */ @@ -1361,6 +1374,7 @@ static int das1800_do_wbits(struct comedi_device *dev, static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, unsigned int dma1) { + struct das1800_private *devpriv = dev->private; unsigned long flags; /* need an irq to do dma */ @@ -1518,6 +1532,7 @@ static int das1800_probe(struct comedi_device *dev) static int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct das1800_private *devpriv; struct comedi_subdevice *s; unsigned long iobase = it->options[0]; unsigned int irq = it->options[1]; @@ -1527,9 +1542,10 @@ static int das1800_attach(struct comedi_device *dev, int board; int retval; - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct das1800_private)) < 0) - return -ENOMEM; + retval = alloc_private(dev, sizeof(*devpriv)); + if (retval) + return retval; + devpriv = dev->private; printk(KERN_DEBUG "comedi%d: %s: io 0x%lx", dev->minor, dev->driver->driver_name, iobase); @@ -1699,11 +1715,13 @@ static int das1800_attach(struct comedi_device *dev, static void das1800_detach(struct comedi_device *dev) { + struct das1800_private *devpriv = dev->private; + if (dev->iobase) release_region(dev->iobase, DAS1800_SIZE); if (dev->irq) free_irq(dev->irq, dev); - if (dev->private) { + if (devpriv) { if (devpriv->iobase2) release_region(devpriv->iobase2, DAS1800_SIZE); if (devpriv->dma0) diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index e134c46dedf..8029e370b2d 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -104,7 +104,6 @@ struct das6402_private { int das6402_ignoreirq; }; -#define devpriv ((struct das6402_private *)dev->private) static void das6402_ai_fifo_dregs(struct comedi_device *dev, struct comedi_subdevice *s) @@ -152,6 +151,7 @@ static void das6402_setcounter(struct comedi_device *dev) static irqreturn_t intr_handler(int irq, void *d) { struct comedi_device *dev = d; + struct das6402_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; if (!dev->attached || devpriv->das6402_ignoreirq) { @@ -196,6 +196,8 @@ static void das6402_ai_fifo_read(struct comedi_device *dev, short *data, int n) static int das6402_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das6402_private *devpriv = dev->private; + /* * This function should reset the board from whatever condition it * is in (i.e., acquiring data), to a non-active state. @@ -217,6 +219,8 @@ static int das6402_ai_cancel(struct comedi_device *dev, static int das6402_ai_mode2(struct comedi_device *dev, struct comedi_subdevice *s, comedi_trig * it) { + struct das6402_private *devpriv = dev->private; + devpriv->das6402_ignoreirq = 1; dev_dbg(dev->class_dev, "Starting acquisition\n"); outb_p(0x03, dev->iobase + 10); /* enable external trigging */ @@ -236,6 +240,7 @@ static int das6402_ai_mode2(struct comedi_device *dev, static int board_init(struct comedi_device *dev) { + struct das6402_private *devpriv = dev->private; BYTE b; devpriv->das6402_ignoreirq = 1; @@ -277,6 +282,7 @@ static int board_init(struct comedi_device *dev) static int das6402_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct das6402_private *devpriv; unsigned int irq; unsigned long iobase; int ret; @@ -303,9 +309,11 @@ static int das6402_attach(struct comedi_device *dev, return ret; dev->irq = irq; - ret = alloc_private(dev, sizeof(struct das6402_private)); - if (ret < 0) + + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; ret = comedi_alloc_subdevices(dev, 1); if (ret) diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 215deac0a39..2a6df6b6ae3 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -241,8 +241,6 @@ struct das800_private { volatile int do_bits; /* digital output bits */ }; -#define devpriv ((struct das800_private *)dev->private) - static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it); static void das800_detach(struct comedi_device *dev); @@ -367,6 +365,7 @@ static irqreturn_t das800_interrupt(int irq, void *d) short i; /* loop index */ short dataPoint = 0; struct comedi_device *dev = d; + struct das800_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; /* analog input subdevice */ struct comedi_async *async; int status; @@ -461,6 +460,7 @@ static irqreturn_t das800_interrupt(int irq, void *d) static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct das800_private *devpriv; struct comedi_subdevice *s; unsigned long iobase = it->options[0]; unsigned int irq = it->options[1]; @@ -472,9 +472,10 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (irq) dev_dbg(dev->class_dev, "irq %u\n", irq); - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct das800_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; if (iobase == 0) { dev_err(dev->class_dev, @@ -569,6 +570,8 @@ static void das800_detach(struct comedi_device *dev) static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das800_private *devpriv = dev->private; + devpriv->forever = 0; devpriv->count = 0; disable_das800(dev); @@ -578,7 +581,9 @@ static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) /* enable_das800 makes the card start taking hardware triggered conversions */ static void enable_das800(struct comedi_device *dev) { + struct das800_private *devpriv = dev->private; unsigned long irq_flags; + spin_lock_irqsave(&dev->spinlock, irq_flags); /* enable fifo-half full interrupts for cio-das802/16 */ if (thisboard->resolution == 16) @@ -604,6 +609,7 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct das800_private *devpriv = dev->private; int err = 0; int tmp; int gain, startChan; @@ -710,6 +716,7 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, static int das800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct das800_private *devpriv = dev->private; int startChan, endChan, scan, gain; int conv_bits; unsigned long irq_flags; @@ -793,6 +800,7 @@ static int das800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das800_private *devpriv = dev->private; int i, n; int chan; int range; @@ -862,6 +870,7 @@ static int das800_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct das800_private *devpriv = dev->private; int wbits; unsigned long irq_flags; @@ -885,6 +894,7 @@ static int das800_do_wbits(struct comedi_device *dev, /* loads counters with divisor1, divisor2 from private structure */ static int das800_set_frequency(struct comedi_device *dev) { + struct das800_private *devpriv = dev->private; int err = 0; if (i8254_load(dev->iobase + DAS800_8254, 0, 1, devpriv->divisor1, 2)) diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index 824b692db5f..c8b7a031c48 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -793,8 +793,9 @@ static int dmm32at_attach(struct comedi_device *dev, dev->irq = irq; } - if (alloc_private(dev, sizeof(*devpriv)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; devpriv = dev->private; ret = comedi_alloc_subdevices(dev, 3); diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index c59a652a119..da139d212ce 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -233,8 +233,6 @@ struct dt2801_private { unsigned int ao_readback[2]; }; -#define devpriv ((struct dt2801_private *)dev->private) - /* These are the low-level routines: writecommand: write a command to the board writedata: write data byte @@ -508,6 +506,8 @@ static int dt2801_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt2801_private *devpriv = dev->private; + data[0] = devpriv->ao_readback[CR_CHAN(insn->chanspec)]; return 1; @@ -517,6 +517,8 @@ static int dt2801_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt2801_private *devpriv = dev->private; + dt2801_writecmd(dev, DT_C_WRITE_DAIM); dt2801_writedata(dev, CR_CHAN(insn->chanspec)); dt2801_writedata2(dev, data[0]); @@ -590,6 +592,7 @@ static int dt2801_dio_insn_config(struct comedi_device *dev, */ static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct dt2801_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; int board_code, type; @@ -630,9 +633,10 @@ havetype: if (ret) goto out; - ret = alloc_private(dev, sizeof(struct dt2801_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; dev->board_name = boardtype.name; diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index d3a8c1aec9d..c4a7768971d 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -226,8 +226,6 @@ struct dt2811_private { unsigned int ao_readback[2]; }; -#define devpriv ((struct dt2811_private *)dev->private) - static const struct comedi_lrange *dac_range_types[] = { &range_bipolar5, &range_bipolar2_5, @@ -242,6 +240,7 @@ static irqreturn_t dt2811_interrupt(int irq, void *d) int lo, hi; int data; struct comedi_device *dev = d; + struct dt2811_private *devpriv = dev->private; if (!dev->attached) { comedi_error(dev, "spurious interrupt"); @@ -318,6 +317,7 @@ int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig) static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt2811_private *devpriv = dev->private; int i; int chan; @@ -337,6 +337,7 @@ static int dt2811_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt2811_private *devpriv = dev->private; int i; int chan; @@ -397,6 +398,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* long flags; */ const struct dt2811_board *board = comedi_board(dev); + struct dt2811_private *devpriv; int ret; struct comedi_subdevice *s; unsigned long iobase; @@ -463,9 +465,10 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(struct dt2811_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; switch (it->options[2]) { case 0: diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 064a8f215e4..4b81ae33ca0 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -68,8 +68,6 @@ struct dt2814_private { int curadchan; }; -#define devpriv ((struct dt2814_private *)dev->private) - #define DT2814_TIMEOUT 10 #define DT2814_MAX_SPEED 100000 /* Arbitrary 10 khz limit */ @@ -200,6 +198,7 @@ static int dt2814_ai_cmdtest(struct comedi_device *dev, static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct dt2814_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int chan; int trigvar; @@ -221,6 +220,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) { int lo, hi; struct comedi_device *dev = d; + struct dt2814_private *devpriv = dev->private; struct comedi_subdevice *s; int data; @@ -258,6 +258,7 @@ static irqreturn_t dt2814_interrupt(int irq, void *d) static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct dt2814_private *devpriv; int i, irq; int ret; struct comedi_subdevice *s; @@ -324,9 +325,10 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(struct dt2814_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; s = &dev->subdevices[0]; dev->read_subdev = s; diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index b9692ef64c4..1f1998f3d24 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -78,8 +78,6 @@ struct dt2815_private { unsigned int ao_readback[8]; }; -#define devpriv ((struct dt2815_private *)dev->private) - static int dt2815_wait_for_status(struct comedi_device *dev, int status) { int i; @@ -95,6 +93,7 @@ static int dt2815_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt2815_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -107,6 +106,7 @@ static int dt2815_ao_insn_read(struct comedi_device *dev, static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt2815_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); unsigned int status; @@ -162,6 +162,7 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct dt2815_private *devpriv; struct comedi_subdevice *s; int i; const struct comedi_lrange *current_range_type, *voltage_range_type; @@ -182,8 +183,10 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - if (alloc_private(dev, sizeof(struct dt2815_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; s = &dev->subdevices[0]; /* ao subdevice */ diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 78d340716d1..f2524683321 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -248,7 +248,6 @@ struct dt282x_private { int dma_dir; }; -#define devpriv ((struct dt282x_private *)dev->private) #define boardtype (*(const struct dt282x_board *)dev->board_ptr) /* @@ -290,6 +289,7 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2); static void dt282x_munge(struct comedi_device *dev, short *buf, unsigned int nbytes) { + struct dt282x_private *devpriv = dev->private; unsigned int i; unsigned short mask = (1 << boardtype.adbits) - 1; unsigned short sign = 1 << (boardtype.adbits - 1); @@ -309,6 +309,7 @@ static void dt282x_munge(struct comedi_device *dev, short *buf, static void dt282x_ao_dma_interrupt(struct comedi_device *dev) { + struct dt282x_private *devpriv = dev->private; void *ptr; int size; int i; @@ -341,6 +342,7 @@ static void dt282x_ao_dma_interrupt(struct comedi_device *dev) static void dt282x_ai_dma_interrupt(struct comedi_device *dev) { + struct dt282x_private *devpriv = dev->private; void *ptr; int size; int i; @@ -393,6 +395,7 @@ static void dt282x_ai_dma_interrupt(struct comedi_device *dev) static int prep_ai_dma(struct comedi_device *dev, int dma_index, int n) { + struct dt282x_private *devpriv = dev->private; int dma_chan; unsigned long dma_ptr; unsigned long flags; @@ -424,6 +427,7 @@ static int prep_ai_dma(struct comedi_device *dev, int dma_index, int n) static int prep_ao_dma(struct comedi_device *dev, int dma_index, int n) { + struct dt282x_private *devpriv = dev->private; int dma_chan; unsigned long dma_ptr; unsigned long flags; @@ -447,6 +451,7 @@ static int prep_ao_dma(struct comedi_device *dev, int dma_index, int n) static irqreturn_t dt282x_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct dt282x_private *devpriv = dev->private; struct comedi_subdevice *s; struct comedi_subdevice *s_ao; unsigned int supcsr, adcsr, dacsr; @@ -525,6 +530,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d) static void dt282x_load_changain(struct comedi_device *dev, int n, unsigned int *chanlist) { + struct dt282x_private *devpriv = dev->private; unsigned int i; unsigned int chan, range; @@ -548,6 +554,7 @@ static int dt282x_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt282x_private *devpriv = dev->private; int i; /* XXX should we really be enabling the ad clock here? */ @@ -671,6 +678,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev, static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { const struct dt282x_board *board = comedi_board(dev); + struct dt282x_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int timer; @@ -733,6 +741,8 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static void dt282x_disable_dma(struct comedi_device *dev) { + struct dt282x_private *devpriv = dev->private; + if (devpriv->usedma) { disable_dma(devpriv->dma[0].chan); disable_dma(devpriv->dma[1].chan); @@ -742,6 +752,8 @@ static void dt282x_disable_dma(struct comedi_device *dev) static int dt282x_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct dt282x_private *devpriv = dev->private; + dt282x_disable_dma(dev); devpriv->adcsr = 0; @@ -794,6 +806,8 @@ static int dt282x_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt282x_private *devpriv = dev->private; + data[0] = devpriv->ao[CR_CHAN(insn->chanspec)]; return 1; @@ -803,6 +817,7 @@ static int dt282x_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt282x_private *devpriv = dev->private; short d; unsigned int chan; @@ -908,6 +923,7 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev, static int dt282x_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int x) { + struct dt282x_private *devpriv = dev->private; int size; if (x != 0) @@ -937,6 +953,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct dt282x_private *devpriv = dev->private; int timer; struct comedi_cmd *cmd = &s->async->cmd; @@ -973,6 +990,8 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int dt282x_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct dt282x_private *devpriv = dev->private; + dt282x_disable_dma(dev); devpriv->dacsr = 0; @@ -1003,6 +1022,7 @@ static int dt282x_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt282x_private *devpriv = dev->private; int mask; mask = (CR_CHAN(insn->chanspec) < 8) ? 0x00ff : 0xff00; @@ -1074,6 +1094,7 @@ enum { /* i/o base, irq, dma channels */ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) { + struct dt282x_private *devpriv = dev->private; int ret; devpriv->usedma = 0; @@ -1135,6 +1156,7 @@ static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2) static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct dt282x_board *board = comedi_board(dev); + struct dt282x_private *devpriv; int i, irq; int ret; struct comedi_subdevice *s; @@ -1217,9 +1239,10 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif } - ret = alloc_private(dev, sizeof(struct dt282x_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; ret = dt282x_grab_dma(dev, it->options[opt_dma1], it->options[opt_dma2]); @@ -1292,6 +1315,8 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void dt282x_detach(struct comedi_device *dev) { + struct dt282x_private *devpriv = dev->private; + if (dev->irq) free_irq(dev->irq, dev); if (dev->iobase) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 43d05ef9715..e71d880bdda 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -257,8 +257,6 @@ struct dt3k_private { unsigned int ai_rear; }; -#define devpriv ((struct dt3k_private *)dev->private) - static void dt3k_ai_empty_fifo(struct comedi_device *dev, struct comedi_subdevice *s); static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *arg, @@ -273,6 +271,7 @@ static void debug_intr_flags(unsigned int flags); static int dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd) { + struct dt3k_private *devpriv = dev->private; int i; unsigned int status = 0; @@ -297,6 +296,8 @@ static unsigned int dt3k_readsingle(struct comedi_device *dev, unsigned int subsys, unsigned int chan, unsigned int gain) { + struct dt3k_private *devpriv = dev->private; + writew(subsys, devpriv->io_addr + DPR_SubSys); writew(chan, devpriv->io_addr + DPR_Params(0)); @@ -310,6 +311,8 @@ static unsigned int dt3k_readsingle(struct comedi_device *dev, static void dt3k_writesingle(struct comedi_device *dev, unsigned int subsys, unsigned int chan, unsigned int data) { + struct dt3k_private *devpriv = dev->private; + writew(subsys, devpriv->io_addr + DPR_SubSys); writew(chan, devpriv->io_addr + DPR_Params(0)); @@ -326,6 +329,7 @@ static int debug_n_ints; static irqreturn_t dt3k_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct dt3k_private *devpriv = dev->private; struct comedi_subdevice *s; unsigned int status; @@ -377,6 +381,7 @@ static void debug_intr_flags(unsigned int flags) static void dt3k_ai_empty_fifo(struct comedi_device *dev, struct comedi_subdevice *s) { + struct dt3k_private *devpriv = dev->private; int front; int rear; int count; @@ -550,6 +555,7 @@ static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec, static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct dt3k_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int i; unsigned int chan, range, aref; @@ -618,6 +624,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct dt3k_private *devpriv = dev->private; int ret; writew(SUBS_AI, devpriv->io_addr + DPR_SubSys); @@ -648,6 +655,7 @@ static int dt3k_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, static int dt3k_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt3k_private *devpriv = dev->private; int i; unsigned int chan; @@ -664,6 +672,7 @@ static int dt3k_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt3k_private *devpriv = dev->private; int i; unsigned int chan; @@ -676,6 +685,8 @@ static int dt3k_ao_insn_read(struct comedi_device *dev, static void dt3k_dio_config(struct comedi_device *dev, int bits) { + struct dt3k_private *devpriv = dev->private; + /* XXX */ writew(SUBS_DOUT, devpriv->io_addr + DPR_SubSys); @@ -739,6 +750,7 @@ static int dt3k_mem_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct dt3k_private *devpriv = dev->private; unsigned int addr = CR_CHAN(insn->chanspec); int i; @@ -786,6 +798,7 @@ static struct pci_dev *dt3000_find_pci_dev(struct comedi_device *dev, static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct dt3k_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; resource_size_t pci_base; @@ -793,9 +806,10 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_dbg(dev->class_dev, "dt3000:\n"); - ret = alloc_private(dev, sizeof(struct dt3k_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; pcidev = dt3000_find_pci_dev(dev, it); if (!pcidev) @@ -885,6 +899,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void dt3000_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct dt3k_private *devpriv = dev->private; if (dev->irq) free_irq(dev->irq, dev); diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index bc6f409b7e1..71d38fc5c16 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -323,9 +323,6 @@ static const struct comedi_lrange dt9812_2pt5_aout_range = { 1, { static struct slot_dt9812 dt9812[DT9812_NUM_SLOTS]; -/* Useful shorthand access to private data */ -#define devpriv ((struct comedi_dt9812 *)dev->private) - static inline struct usb_dt9812 *to_dt9812_dev(struct kref *d) { return container_of(d, struct usb_dt9812, kref); @@ -893,6 +890,7 @@ static struct usb_driver dt9812_usb_driver = { static int dt9812_comedi_open(struct comedi_device *dev) { + struct comedi_dt9812 *devpriv = dev->private; int result = -ENODEV; down(&devpriv->slot->mutex); @@ -947,6 +945,7 @@ static int dt9812_di_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct comedi_dt9812 *devpriv = dev->private; int n; u8 bits = 0; @@ -960,6 +959,7 @@ static int dt9812_do_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct comedi_dt9812 *devpriv = dev->private; int n; u8 bits = 0; @@ -979,6 +979,7 @@ static int dt9812_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct comedi_dt9812 *devpriv = dev->private; int n; for (n = 0; n < insn->n; n++) { @@ -995,6 +996,7 @@ static int dt9812_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct comedi_dt9812 *devpriv = dev->private; int n; u16 value; @@ -1010,6 +1012,7 @@ static int dt9812_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct comedi_dt9812 *devpriv = dev->private; int n; for (n = 0; n < insn->n; n++) @@ -1019,14 +1022,17 @@ static int dt9812_ao_winsn(struct comedi_device *dev, static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct comedi_dt9812 *devpriv; int i; struct comedi_subdevice *s; int ret; dev->board_name = "dt9812"; - if (alloc_private(dev, sizeof(struct comedi_dt9812)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; /* * Special open routine, since USB unit may be unattached at diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index ae8e8f46029..c1c24b06255 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -29,8 +29,6 @@ struct fl512_private { short ao_readback[2]; }; -#define devpriv ((struct fl512_private *) dev->private) - static const struct comedi_lrange range_fl512 = { 4, { BIP_RANGE(0.5), BIP_RANGE(1), @@ -75,6 +73,7 @@ static int fl512_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct fl512_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); /* get chan to write */ unsigned long iobase = dev->iobase; /* get base address */ @@ -99,6 +98,7 @@ static int fl512_ao_insn_readback(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct fl512_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); @@ -110,6 +110,7 @@ static int fl512_ao_insn_readback(struct comedi_device *dev, static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct fl512_private *devpriv; unsigned long iobase; int ret; @@ -125,8 +126,11 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; dev->board_name = "fl512"; - if (alloc_private(dev, sizeof(struct fl512_private)) < 0) - return -ENOMEM; + + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; #if DEBUG printk(KERN_DEBUG "malloc ok\n"); diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index d696d4d51e2..8eb3a87b5b8 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -506,7 +506,7 @@ static int icp_multi_attach_pci(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) + if (ret) return ret; devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index 65ff1c9b973..64a4acd0aa5 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -156,7 +156,6 @@ struct pci20xxx_private { union pci20xxx_subdev_private subdev_private[PCI20000_MODULES]; }; -#define devpriv ((struct pci20xxx_private *)dev->private) #define CHAN (CR_CHAN(it->chanlist[0])) static int pci20006_init(struct comedi_device *dev, struct comedi_subdevice *s, @@ -196,6 +195,7 @@ static int pci20xxx_dio_init(struct comedi_device *dev, static int pci20xxx_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct pci20xxx_private *devpriv; unsigned char i; int ret; int id; @@ -206,9 +206,10 @@ static int pci20xxx_attach(struct comedi_device *dev, if (ret) return ret; - ret = alloc_private(dev, sizeof(struct pci20xxx_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; devpriv->ioaddr = (void __iomem *)(unsigned long)it->options[0]; dev->board_name = "pci20kc"; @@ -541,6 +542,7 @@ static int pci20xxx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pci20xxx_private *devpriv = dev->private; unsigned int mask = data[0]; s->state &= ~mask; @@ -571,6 +573,7 @@ static int pci20xxx_dio_insn_bits(struct comedi_device *dev, static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci20xxx_private *devpriv = dev->private; unsigned char control_01; unsigned char control_23; unsigned char buffer; @@ -627,6 +630,8 @@ static void pci20xxx_dio_config(struct comedi_device *dev, #if 0 static void pci20xxx_do(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pci20xxx_private *devpriv = dev->private; + /* XXX if the channel is configured for input, does this do bad things? */ /* XXX it would be a good idea to only update the registers @@ -641,9 +646,10 @@ static void pci20xxx_do(struct comedi_device *dev, struct comedi_subdevice *s) static unsigned int pci20xxx_di(struct comedi_device *dev, struct comedi_subdevice *s) { - /* XXX same note as above */ + struct pci20xxx_private *devpriv = dev->private; unsigned int bits; + /* XXX same note as above */ bits = readb(devpriv->ioaddr + PCI20000_DIO_0); bits |= readb(devpriv->ioaddr + PCI20000_DIO_1) << 8; bits |= readb(devpriv->ioaddr + PCI20000_DIO_2) << 16; diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index a5ab490571b..69378dd90e2 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -762,11 +762,12 @@ static int jr3_pci_attach(struct comedi_device *dev, return -EINVAL; } - result = alloc_private(dev, sizeof(struct jr3_pci_dev_private)); - if (result < 0) - return -ENOMEM; - card = NULL; + result = alloc_private(dev, sizeof(*devpriv)); + if (result) + return result; devpriv = dev->private; + + card = NULL; init_timer(&devpriv->timer); while (1) { card = pci_get_device(PCI_VENDOR_ID_JR3, PCI_ANY_ID, card); diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 2ce0b14af58..c1bc5c6ce0c 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -234,8 +234,6 @@ struct me_private_data { int ao_readback[4]; /* Mirror of analog output data */ }; -#define dev_private ((struct me_private_data *)dev->private) - /* * ------------------------------------------------------------------ * @@ -260,6 +258,7 @@ static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct me_private_data *dev_private = dev->private; int bits; int mask = 1 << CR_CHAN(insn->chanspec); @@ -297,7 +296,9 @@ static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct me_private_data *dev_private = dev->private; unsigned int mask = data[0]; + s->state &= ~mask; s->state |= (mask & data[1]); @@ -334,6 +335,7 @@ static int me_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct me_private_data *dev_private = dev->private; unsigned short value; int chan = CR_CHAN((&insn->chanspec)[0]); int rang = CR_RANGE((&insn->chanspec)[0]); @@ -407,6 +409,8 @@ static int me_ai_insn_read(struct comedi_device *dev, /* Cancel analog input autoscan */ static int me_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct me_private_data *dev_private = dev->private; + /* disable interrupts */ /* stop any running conversion */ @@ -443,6 +447,7 @@ static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct me_private_data *dev_private = dev->private; int chan; int rang; int i; @@ -494,6 +499,7 @@ static int me_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct me_private_data *dev_private = dev->private; int i; for (i = 0; i < insn->n; i++) { @@ -516,6 +522,7 @@ static int me_ao_insn_read(struct comedi_device *dev, static int me2600_xilinx_download(struct comedi_device *dev, const u8 *data, size_t size) { + struct me_private_data *dev_private = dev->private; unsigned int value; unsigned int file_length; unsigned int i; @@ -599,6 +606,8 @@ static int me2600_upload_firmware(struct comedi_device *dev) /* Reset device */ static int me_reset(struct comedi_device *dev) { + struct me_private_data *dev_private = dev->private; + /* Reset board */ writew(0x00, dev_private->me_regbase + ME_CONTROL_1); writew(0x00, dev_private->me_regbase + ME_CONTROL_2); @@ -630,6 +639,7 @@ static const void *me_find_boardinfo(struct comedi_device *dev, static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { const struct me_board *board; + struct me_private_data *dev_private; struct comedi_subdevice *s; resource_size_t plx_regbase_tmp; unsigned long plx_regbase_size_tmp; @@ -648,9 +658,10 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) dev->board_ptr = board; dev->board_name = board->name; - /* Allocate private memory */ - if (alloc_private(dev, sizeof(struct me_private_data)) < 0) - return -ENOMEM; + error = alloc_private(dev, sizeof(*dev_private)); + if (error) + return error; + dev_private = dev->private; /* Enable PCI device and request PCI regions */ if (comedi_pci_enable(pcidev, dev->board_name) < 0) { @@ -775,6 +786,7 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) static void me_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct me_private_data *dev_private = dev->private; if (dev_private) { if (dev_private->me_regbase) { diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index f8b7faefc96..3e8892c8209 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -122,13 +122,12 @@ Configuration Options: #define MPC624_SPEED_6_875_Hz \ (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0) /* -------------------------------------------------------------------------- */ -struct skel_private { +struct mpc624_private { /* set by mpc624_attach() from driver's parameters */ unsigned long int ulConvertionRate; }; -#define devpriv ((struct skel_private *)dev->private) /* -------------------------------------------------------------------------- */ static const struct comedi_lrange range_mpc624_bipolar1 = { 1, @@ -155,6 +154,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct mpc624_private *devpriv = dev->private; int n, i; unsigned long int data_in, data_out; unsigned char ucPort; @@ -283,6 +283,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct mpc624_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; int ret; @@ -297,9 +298,10 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; dev->board_name = "mpc624"; - /* Private structure initialization */ - if (alloc_private(dev, sizeof(struct skel_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; switch (it->options[1]) { case 0: diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index 4625cb4d07c..f707ee02dcc 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c @@ -86,7 +86,6 @@ Devices: [Quanser Consulting] MultiQ-3 (multiq3) struct multiq3_private { unsigned int ao_readback[2]; }; -#define devpriv ((struct multiq3_private *)dev->private) static int multiq3_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, @@ -129,6 +128,7 @@ static int multiq3_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct multiq3_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -142,6 +142,7 @@ static int multiq3_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct multiq3_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -230,6 +231,7 @@ static void encoder_reset(struct comedi_device *dev) static int multiq3_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct multiq3_private *devpriv; int result = 0; unsigned long iobase; unsigned int irq; @@ -256,9 +258,10 @@ static int multiq3_attach(struct comedi_device *dev, if (result) return result; - result = alloc_private(dev, sizeof(struct multiq3_private)); - if (result < 0) + result = alloc_private(dev, sizeof(*devpriv)); + if (result) return result; + devpriv = dev->private; s = &dev->subdevices[0]; /* ai subdevice */ diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 51295f32ee8..4f5624a3a1b 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -112,12 +112,11 @@ struct ni6527_private { unsigned int filter_enable; }; -#define devpriv ((struct ni6527_private *)dev->private) - static int ni6527_di_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni6527_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); unsigned int interval; @@ -164,6 +163,8 @@ static int ni6527_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni6527_private *devpriv = dev->private; + data[1] = readb(devpriv->mite->daq_io_addr + Port_Register(0)); data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(1)) << 8; data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(2)) << 16; @@ -175,6 +176,8 @@ static int ni6527_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni6527_private *devpriv = dev->private; + if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -202,6 +205,7 @@ static int ni6527_do_insn_bits(struct comedi_device *dev, static irqreturn_t ni6527_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct ni6527_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[2]; unsigned int status; @@ -281,6 +285,7 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev, static int ni6527_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni6527_private *devpriv = dev->private; /* struct comedi_cmd *cmd = &s->async->cmd; */ writeb(ClrEdge | ClrOverflow, @@ -295,6 +300,8 @@ static int ni6527_intr_cmd(struct comedi_device *dev, static int ni6527_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct ni6527_private *devpriv = dev->private; + writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control); return 0; @@ -312,6 +319,8 @@ static int ni6527_intr_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct ni6527_private *devpriv = dev->private; + if (insn->n < 1) return -EINVAL; if (data[0] != INSN_CONFIG_CHANGE_NOTIFY) @@ -351,12 +360,14 @@ ni6527_find_boardinfo(struct pci_dev *pcidev) static int __devinit ni6527_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { + struct ni6527_private *devpriv; struct comedi_subdevice *s; int ret; - ret = alloc_private(dev, sizeof(struct ni6527_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; dev->board_ptr = ni6527_find_boardinfo(pcidev); if (!dev->board_ptr) @@ -430,6 +441,8 @@ static int __devinit ni6527_attach_pci(struct comedi_device *dev, static void ni6527_detach(struct comedi_device *dev) { + struct ni6527_private *devpriv = dev->private; + if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control); diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index eac6dc047bb..e7ccf0423b0 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -211,9 +211,10 @@ static int __devinit ni_670x_attach_pci(struct comedi_device *dev, int i; ret = alloc_private(dev, sizeof(*devpriv)); - if (ret < 0) + if (ret) return ret; devpriv = dev->private; + dev->board_ptr = ni_670x_find_boardinfo(pcidev); if (!dev->board_ptr) return -ENODEV; diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 83950807b67..34c186b9dce 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -169,8 +169,6 @@ struct a2150_private { int config_bits; /* config register bits */ }; -#define devpriv ((struct a2150_private *)dev->private) - static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s); static int a2150_get_timing(struct comedi_device *dev, unsigned int *period, @@ -182,6 +180,8 @@ static int a2150_set_chanlist(struct comedi_device *dev, static void ni_dump_regs(struct comedi_device *dev) { + struct a2150_private *devpriv = dev->private; + printk("config bits 0x%x\n", devpriv->config_bits); printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits); printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG)); @@ -196,6 +196,7 @@ static irqreturn_t a2150_interrupt(int irq, void *d) int status; unsigned long flags; struct comedi_device *dev = d; + struct a2150_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async; struct comedi_cmd *cmd; @@ -300,6 +301,8 @@ static irqreturn_t a2150_interrupt(int irq, void *d) static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct a2150_private *devpriv = dev->private; + /* disable dma on card */ devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT; outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG); @@ -425,6 +428,7 @@ static int a2150_ai_cmdtest(struct comedi_device *dev, static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct a2150_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; unsigned long lock_flags; @@ -536,6 +540,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct a2150_private *devpriv = dev->private; unsigned int i, n; static const int timeout = 100000; static const int filter_delay = 36; @@ -615,6 +620,7 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int a2150_get_timing(struct comedi_device *dev, unsigned int *period, int flags) { + struct a2150_private *devpriv = dev->private; int lub, glb, temp; int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index; int i, j; @@ -689,6 +695,8 @@ static int a2150_set_chanlist(struct comedi_device *dev, unsigned int start_channel, unsigned int num_channels) { + struct a2150_private *devpriv = dev->private; + if (start_channel + num_channels > 4) return -1; @@ -727,6 +735,7 @@ static int a2150_probe(struct comedi_device *dev) static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct a2150_private *devpriv; struct comedi_subdevice *s; unsigned long iobase = it->options[0]; unsigned int irq = it->options[1]; @@ -749,9 +758,10 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) } printk("\n"); - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct a2150_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; if (iobase == 0) { printk(" io base address required\n"); @@ -855,6 +865,8 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void a2150_detach(struct comedi_device *dev) { + struct a2150_private *devpriv = dev->private; + if (dev->iobase) { outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG); release_region(dev->iobase, A2150_SIZE); diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index 93938cec93e..66071600de0 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -167,10 +167,10 @@ struct atao_private { unsigned int ao_readback[10]; }; -#define devpriv ((struct atao_private *)dev->private) - static void atao_reset(struct comedi_device *dev) { + struct atao_private *devpriv = dev->private; + /* This is the reset sequence described in the manual */ devpriv->cfg1 = 0; @@ -202,6 +202,7 @@ static void atao_reset(struct comedi_device *dev) static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct atao_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); short bits; @@ -226,6 +227,7 @@ static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct atao_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -254,6 +256,7 @@ static int atao_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct atao_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); unsigned int mask, bit; @@ -309,6 +312,7 @@ static int atao_calib_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct atao_private *devpriv = dev->private; unsigned int bitstring, bit; unsigned int chan = CR_CHAN(insn->chanspec); @@ -331,6 +335,7 @@ static int atao_calib_insn_write(struct comedi_device *dev, static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct atao_board *board = comedi_board(dev); + struct atao_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; int ao_unipolar; @@ -351,8 +356,10 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; - if (alloc_private(dev, sizeof(struct atao_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index e91a620f9db..93969865b35 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -102,7 +102,6 @@ Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d) #define CLOCK_100_HZ 0x8F25 /* Other miscellaneous defines */ #define ATMIO16D_SIZE 32 /* bus address range */ -#define devpriv ((struct atmio16d_private *)dev->private) #define ATMIO16D_TIMEOUT 10 struct atmio16_board_t { @@ -202,6 +201,7 @@ static void reset_counters(struct comedi_device *dev) static void reset_atmio16d(struct comedi_device *dev) { + struct atmio16d_private *devpriv = dev->private; int i; /* now we need to initialize the board */ @@ -327,6 +327,7 @@ static int atmio16d_ai_cmdtest(struct comedi_device *dev, static int atmio16d_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct atmio16d_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned int timer, base_clock; unsigned int sample_count, tmp, chan, gain; @@ -486,6 +487,7 @@ static int atmio16d_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct atmio16d_private *devpriv = dev->private; int i, t; int chan; int gain; @@ -539,6 +541,7 @@ static int atmio16d_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct atmio16d_private *devpriv = dev->private; int i; for (i = 0; i < insn->n; i++) @@ -550,6 +553,7 @@ static int atmio16d_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct atmio16d_private *devpriv = dev->private; int i; int chan; int d; @@ -596,6 +600,7 @@ static int atmio16d_dio_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + struct atmio16d_private *devpriv = dev->private; int i; int mask; @@ -651,6 +656,7 @@ static int atmio16d_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct atmio16_board_t *board = comedi_board(dev); + struct atmio16d_private *devpriv; unsigned int irq; unsigned long iobase; int ret; @@ -672,9 +678,10 @@ static int atmio16d_attach(struct comedi_device *dev, if (ret) return ret; - ret = alloc_private(dev, sizeof(struct atmio16d_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; /* reset the atmio16d hardware */ reset_atmio16d(dev); diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index 0ca222bbcbe..1984c5fa3af 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -96,8 +96,6 @@ struct dio24_private { int data; /* number of data points left to be taken */ }; -#define devpriv ((struct dio24_private *)dev->private) - static struct comedi_driver driver_dio24 = { .driver_name = "ni_daq_dio24", .module = THIS_MODULE, @@ -110,6 +108,7 @@ static struct comedi_driver driver_dio24 = { static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct dio24_private *devpriv; struct comedi_subdevice *s; unsigned long iobase = 0; #ifdef incomplete @@ -118,9 +117,10 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct pcmcia_device *link; int ret; - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct dio24_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; /* get base address, irq etc. based on bustype */ switch (thisboard->bustype) { diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 28b91a6c378..d3b386e51bf 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -487,8 +487,6 @@ static const int dma_buffer_size = 0xff00; /* 2 bytes per sample */ static const int sample_size = 2; -#define devpriv ((struct labpc_private *)dev->private) - static inline int labpc_counter_load(struct comedi_device *dev, unsigned long base_address, unsigned int counter_number, @@ -504,6 +502,7 @@ static inline int labpc_counter_load(struct comedi_device *dev, int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, unsigned int irq, unsigned int dma_chan) { + struct labpc_private *devpriv = dev->private; struct comedi_subdevice *s; int i; unsigned long isr_flags; @@ -700,15 +699,19 @@ labpc_pci_find_boardinfo(struct pci_dev *pcidev) static int __devinit labpc_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { + struct labpc_private *devpriv; unsigned long iobase; unsigned int irq; int ret; if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS)) return -ENODEV; - ret = alloc_private(dev, sizeof(struct labpc_private)); - if (ret < 0) + + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; + dev->board_ptr = labpc_pci_find_boardinfo(pcidev); if (!dev->board_ptr) return -ENODEV; @@ -725,13 +728,16 @@ static int __devinit labpc_attach_pci(struct comedi_device *dev, static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct labpc_private *devpriv; unsigned long iobase = 0; unsigned int irq = 0; unsigned int dma_chan = 0; + int ret; - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct labpc_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; /* get base address, irq etc. based on bustype */ switch (thisboard->bustype) { @@ -770,6 +776,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) void labpc_common_detach(struct comedi_device *dev) { + struct labpc_private *devpriv = dev->private; struct comedi_subdevice *s; if (dev->subdevices) { @@ -797,6 +804,8 @@ EXPORT_SYMBOL_GPL(labpc_common_detach); static void labpc_clear_adc_fifo(const struct comedi_device *dev) { + struct labpc_private *devpriv = dev->private; + devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG); devpriv->read_byte(dev->iobase + ADC_FIFO_REG); devpriv->read_byte(dev->iobase + ADC_FIFO_REG); @@ -804,6 +813,7 @@ static void labpc_clear_adc_fifo(const struct comedi_device *dev) static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct labpc_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&dev->spinlock, flags); @@ -1096,6 +1106,7 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct labpc_private *devpriv = dev->private; int channel, range, aref; #ifdef CONFIG_ISA_DMA_API unsigned long irq_flags; @@ -1363,6 +1374,7 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static irqreturn_t labpc_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct labpc_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async; struct comedi_cmd *cmd; @@ -1451,6 +1463,7 @@ static irqreturn_t labpc_interrupt(int irq, void *d) /* read all available samples from ai fifo */ static int labpc_drain_fifo(struct comedi_device *dev) { + struct labpc_private *devpriv = dev->private; unsigned int lsb, msb; short data; struct comedi_async *async = dev->read_subdev->async; @@ -1486,6 +1499,7 @@ static int labpc_drain_fifo(struct comedi_device *dev) #ifdef CONFIG_ISA_DMA_API static void labpc_drain_dma(struct comedi_device *dev) { + struct labpc_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; int status; @@ -1539,6 +1553,8 @@ static void labpc_drain_dma(struct comedi_device *dev) static void handle_isa_dma(struct comedi_device *dev) { + struct labpc_private *devpriv = dev->private; + labpc_drain_dma(dev); enable_dma(devpriv->dma_chan); @@ -1553,6 +1569,8 @@ static void handle_isa_dma(struct comedi_device *dev) static void labpc_drain_dregs(struct comedi_device *dev) { #ifdef CONFIG_ISA_DMA_API + struct labpc_private *devpriv = dev->private; + if (devpriv->current_transfer == isa_dma_transfer) labpc_drain_dma(dev); #endif @@ -1563,6 +1581,7 @@ static void labpc_drain_dregs(struct comedi_device *dev) static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct labpc_private *devpriv = dev->private; int i, n; int chan, range; int lsb, msb; @@ -1652,6 +1671,7 @@ static int labpc_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct labpc_private *devpriv = dev->private; int channel, range; unsigned long flags; int lsb, msb; @@ -1693,6 +1713,8 @@ static int labpc_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int labpc_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct labpc_private *devpriv = dev->private; + data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)]; return 1; @@ -1702,6 +1724,8 @@ static int labpc_calib_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct labpc_private *devpriv = dev->private; + data[0] = devpriv->caldac[CR_CHAN(insn->chanspec)]; return 1; @@ -1721,6 +1745,8 @@ static int labpc_eeprom_read_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct labpc_private *devpriv = dev->private; + data[0] = devpriv->eeprom_data[CR_CHAN(insn->chanspec)]; return 1; @@ -1777,6 +1803,7 @@ static unsigned int labpc_suggest_transfer_size(const struct comedi_cmd *cmd) static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd, enum scan_mode mode) { + struct labpc_private *devpriv = dev->private; /* max value for 16 bit counter in mode 2 */ const int max_counter_value = 0x10000; /* min value for 16 bit counter in mode 2 */ @@ -1883,6 +1910,7 @@ static int labpc_dio_mem_callback(int dir, int port, int data, static void labpc_serial_out(struct comedi_device *dev, unsigned int value, unsigned int value_width) { + struct labpc_private *devpriv = dev->private; int i; for (i = 1; i <= value_width; i++) { @@ -1907,6 +1935,7 @@ static void labpc_serial_out(struct comedi_device *dev, unsigned int value, /* lowlevel read from eeprom */ static unsigned int labpc_serial_in(struct comedi_device *dev) { + struct labpc_private *devpriv = dev->private; unsigned int value = 0; int i; const int value_width = 8; /* number of bits wide values are */ @@ -1936,6 +1965,7 @@ static unsigned int labpc_serial_in(struct comedi_device *dev) static unsigned int labpc_eeprom_read(struct comedi_device *dev, unsigned int address) { + struct labpc_private *devpriv = dev->private; unsigned int value; /* bits to tell eeprom to expect a read */ const int read_instruction = 0x3; @@ -1968,6 +1998,7 @@ static unsigned int labpc_eeprom_read(struct comedi_device *dev, static int labpc_eeprom_write(struct comedi_device *dev, unsigned int address, unsigned int value) { + struct labpc_private *devpriv = dev->private; const int write_enable_instruction = 0x6; const int write_instruction = 0x2; const int write_length = 8; /* 8 bit write lengths to eeprom */ @@ -2025,6 +2056,7 @@ static int labpc_eeprom_write(struct comedi_device *dev, static unsigned int labpc_eeprom_read_status(struct comedi_device *dev) { + struct labpc_private *devpriv = dev->private; unsigned int value; const int read_status_instruction = 0x5; const int write_length = 8; /* 8 bit write lengths to eeprom */ @@ -2054,6 +2086,8 @@ static unsigned int labpc_eeprom_read_status(struct comedi_device *dev) static void write_caldac(struct comedi_device *dev, unsigned int channel, unsigned int value) { + struct labpc_private *devpriv = dev->private; + if (value == devpriv->caldac[channel]) return; devpriv->caldac[channel] = value; diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index eb0417eb6d7..791a66ff65a 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -127,13 +127,16 @@ static struct comedi_driver driver_labpc_cs = { static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct labpc_private *devpriv; unsigned long iobase = 0; unsigned int irq = 0; struct pcmcia_device *link; + int ret; - /* allocate and initialize dev->private */ - if (alloc_private(dev, sizeof(struct labpc_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; /* get base address, irq etc. based on bustype */ switch (thisboard->bustype) { diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index bc9313ec985..233a2d350e8 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -310,7 +310,6 @@ struct nidio96_private { struct mite_dma_descriptor_ring *di_mite_ring; spinlock_t mite_channel_lock; }; -#define devpriv ((struct nidio96_private *)dev->private) static int ni_pcidio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, @@ -332,6 +331,7 @@ static void ni_pcidio_print_status(unsigned int status); static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev) { + struct nidio96_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); @@ -355,6 +355,7 @@ static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev) static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev) { + struct nidio96_private *devpriv = dev->private; unsigned long flags; spin_lock_irqsave(&devpriv->mite_channel_lock, flags); @@ -384,6 +385,7 @@ static void ni_pcidio_event(struct comedi_device *dev, static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s) { + struct nidio96_private *devpriv = dev->private; unsigned long irq_flags; int count; @@ -400,6 +402,7 @@ static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s) static irqreturn_t nidio_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct nidio96_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; struct comedi_async *async = s->async; struct mite_struct *mite = devpriv->mite; @@ -609,6 +612,7 @@ static void ni_pcidio_print_status(unsigned int flags) #ifdef unused static void debug_int(struct comedi_device *dev) { + struct nidio96_private *devpriv = dev->private; int a, b; static int n_int; struct timeval tv; @@ -640,6 +644,8 @@ static int ni_pcidio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct nidio96_private *devpriv = dev->private; + if (insn->n != 1) return -EINVAL; switch (data[0]) { @@ -668,6 +674,8 @@ static int ni_pcidio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct nidio96_private *devpriv = dev->private; + if (data[0]) { s->state &= ~data[0]; s->state |= (data[0] & data[1]); @@ -793,6 +801,7 @@ static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode) static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct nidio96_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; /* XXX configure ports for input */ @@ -910,6 +919,7 @@ static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s) { + struct nidio96_private *devpriv = dev->private; int retval; unsigned long flags; @@ -934,6 +944,8 @@ static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s) static int ni_pcidio_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { + struct nidio96_private *devpriv = dev->private; + if (trignum != 0) return -EINVAL; @@ -946,6 +958,8 @@ static int ni_pcidio_inttrig(struct comedi_device *dev, static int ni_pcidio_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct nidio96_private *devpriv = dev->private; + writeb(0x00, devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control); ni_pcidio_release_di_mite_channel(dev); @@ -956,6 +970,7 @@ static int ni_pcidio_cancel(struct comedi_device *dev, static int ni_pcidio_change(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long new_size) { + struct nidio96_private *devpriv = dev->private; int ret; ret = mite_buf_change(devpriv->di_mite_ring, s->async); @@ -970,6 +985,7 @@ static int ni_pcidio_change(struct comedi_device *dev, static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index, const u8 *data, size_t data_len) { + struct nidio96_private *devpriv = dev->private; static const int timeout = 1000; int i; size_t j; @@ -1033,8 +1049,10 @@ static int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index) static int pci_6534_reset_fpgas(struct comedi_device *dev) { + struct nidio96_private *devpriv = dev->private; int ret; int i; + writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register); for (i = 0; i < 3; ++i) { ret = pci_6534_reset_fpga(dev, i); @@ -1047,6 +1065,8 @@ static int pci_6534_reset_fpgas(struct comedi_device *dev) static void pci_6534_init_main_fpga(struct comedi_device *dev) { + struct nidio96_private *devpriv = dev->private; + writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register); writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register); writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register); @@ -1057,6 +1077,7 @@ static void pci_6534_init_main_fpga(struct comedi_device *dev) static int pci_6534_upload_firmware(struct comedi_device *dev) { + struct nidio96_private *devpriv = dev->private; int ret; const struct firmware *fw; static const char *const fw_file[3] = { @@ -1102,13 +1123,16 @@ nidio_find_boardinfo(struct pci_dev *pcidev) static int __devinit nidio_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { + struct nidio96_private *devpriv; struct comedi_subdevice *s; int ret; unsigned int irq; - ret = alloc_private(dev, sizeof(struct nidio96_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; + spin_lock_init(&devpriv->mite_channel_lock); dev->board_ptr = nidio_find_boardinfo(pcidev); @@ -1184,6 +1208,8 @@ static int __devinit nidio_attach_pci(struct comedi_device *dev, static void nidio_detach(struct comedi_device *dev) { + struct nidio96_private *devpriv = dev->private; + if (dev->irq) free_irq(dev->irq, dev); if (devpriv) { diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index 89305a14eb5..33bda31392d 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -161,14 +161,13 @@ struct pcl711_private { unsigned int divisor2; }; -#define devpriv ((struct pcl711_private *)dev->private) - static irqreturn_t pcl711_interrupt(int irq, void *d) { int lo, hi; int data; struct comedi_device *dev = d; const struct pcl711_board *board = comedi_board(dev); + struct pcl711_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; if (!dev->attached) { @@ -264,6 +263,7 @@ ok: static int pcl711_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + struct pcl711_private *devpriv = dev->private; int tmp; int err = 0; @@ -349,6 +349,7 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev, static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl711_private *devpriv = dev->private; int timer1, timer2; struct comedi_cmd *cmd = &s->async->cmd; @@ -398,6 +399,7 @@ static int pcl711_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int pcl711_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl711_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); @@ -417,6 +419,7 @@ static int pcl711_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl711_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); @@ -460,6 +463,7 @@ static int pcl711_do_insn_bits(struct comedi_device *dev, static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl711_board *board = comedi_board(dev); + struct pcl711_private *devpriv; int ret; unsigned long iobase; unsigned int irq; @@ -499,9 +503,10 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(struct pcl711_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; s = &dev->subdevices[0]; /* AI subdevice */ diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index 07e72de982a..22f907a0704 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -152,11 +152,10 @@ struct pcl726_private { unsigned int ao_readback[12]; }; -#define devpriv ((struct pcl726_private *)dev->private) - static int pcl726_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl726_private *devpriv = dev->private; int hi, lo; int n; int chan = CR_CHAN(insn->chanspec); @@ -183,6 +182,7 @@ static int pcl726_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl726_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); int n; @@ -226,6 +226,7 @@ static int pcl726_do_insn_bits(struct comedi_device *dev, static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl726_board *board = comedi_board(dev); + struct pcl726_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; unsigned int iorange; @@ -247,9 +248,10 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; - ret = alloc_private(dev, sizeof(struct pcl726_private)); - if (ret < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; for (i = 0; i < 12; i++) { devpriv->bipolar[i] = 0; diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 3cf55ff9308..0d825915d46 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -369,8 +369,6 @@ struct pcl812_private { unsigned int ao_readback[2]; /* data for AO readback */ }; -#define devpriv ((struct pcl812_private *)dev->private) - /* ============================================================================== */ @@ -388,6 +386,7 @@ static int pcl812_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl812_private *devpriv = dev->private; int n; int timeout, hi; @@ -465,6 +464,7 @@ static int pcl812_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl812_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); int i; @@ -486,6 +486,7 @@ static int pcl812_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl812_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); int i; @@ -533,6 +534,7 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { const struct pcl812_board *board = comedi_board(dev); + struct pcl812_private *devpriv = dev->private; int err = 0; unsigned int flags; int tmp, divisor1, divisor2; @@ -639,6 +641,7 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, static int pcl812_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { const struct pcl812_board *board = comedi_board(dev); + struct pcl812_private *devpriv = dev->private; unsigned int divisor1 = 0, divisor2 = 0, i, dma_flags, bytes; struct comedi_cmd *cmd = &s->async->cmd; @@ -789,6 +792,7 @@ static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d) char err = 1; unsigned int mask, timeout; struct comedi_device *dev = d; + struct pcl812_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; unsigned int next_chan; @@ -862,6 +866,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev, struct comedi_subdevice *s, short *ptr, unsigned int bufptr, unsigned int len) { + struct pcl812_private *devpriv = dev->private; unsigned int i; s->async->events = 0; @@ -892,6 +897,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev, static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d) { struct comedi_device *dev = d; + struct pcl812_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; unsigned long dma_flags; int len, bufptr; @@ -938,6 +944,7 @@ static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d) static irqreturn_t interrupt_pcl812(int irq, void *d) { struct comedi_device *dev = d; + struct pcl812_private *devpriv = dev->private; if (!dev->attached) { comedi_error(dev, "spurious interrupt"); @@ -954,6 +961,7 @@ static irqreturn_t interrupt_pcl812(int irq, void *d) */ static int pcl812_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl812_private *devpriv = dev->private; unsigned long flags; unsigned int top1, top2, i; @@ -1002,6 +1010,7 @@ static void setup_range_channel(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int rangechan, char wait) { + struct pcl812_private *devpriv = dev->private; unsigned char chan_reg = CR_CHAN(rangechan); /* normal board */ /* gain index */ unsigned char gain_reg = CR_RANGE(rangechan) + @@ -1063,8 +1072,9 @@ static void start_pacer(struct comedi_device *dev, int mode, static void free_resources(struct comedi_device *dev) { const struct pcl812_board *board = comedi_board(dev); + struct pcl812_private *devpriv = dev->private; - if (dev->private) { + if (devpriv) { if (devpriv->dmabuf[0]) free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]); if (devpriv->dmabuf[1]) @@ -1084,6 +1094,8 @@ static void free_resources(struct comedi_device *dev) static int pcl812_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl812_private *devpriv = dev->private; + if (devpriv->ai_dma) disable_dma(devpriv->dma); outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */ @@ -1100,6 +1112,7 @@ static int pcl812_ai_cancel(struct comedi_device *dev, static void pcl812_reset(struct comedi_device *dev) { const struct pcl812_board *board = comedi_board(dev); + struct pcl812_private *devpriv = dev->private; outb(0, dev->iobase + PCL812_MUX); outb(0 + devpriv->range_correction, dev->iobase + PCL812_GAIN); @@ -1135,6 +1148,7 @@ static void pcl812_reset(struct comedi_device *dev) static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl812_board *board = comedi_board(dev); + struct pcl812_private *devpriv; int ret, subdev; unsigned long iobase; unsigned int irq; @@ -1153,11 +1167,12 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - ret = alloc_private(dev, sizeof(struct pcl812_private)); - if (ret < 0) { + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) { free_resources(dev); - return ret; /* Can't alloc mem */ + return ret; } + devpriv = dev->private; dev->board_name = board->name; diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 0822de058e4..4cdb3c915f5 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -126,8 +126,6 @@ struct pcl816_board { int i8254_osc_base; /* 1/frequency of on board oscilator in ns */ }; -#define devpriv ((struct pcl816_private *)dev->private) - #ifdef unused static int RTC_lock; /* RTC lock */ static int RTC_timer_lock; /* RTC int lock */ @@ -259,6 +257,7 @@ static int pcl816_ai_insn_read(struct comedi_device *dev, static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d) { struct comedi_device *dev = d; + struct pcl816_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; int low, hi; int timeout = 50; /* wait max 50us */ @@ -315,6 +314,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev, struct comedi_subdevice *s, short *ptr, unsigned int bufptr, unsigned int len) { + struct pcl816_private *devpriv = dev->private; int i; s->async->events = 0; @@ -350,6 +350,7 @@ static void transfer_from_dma_buf(struct comedi_device *dev, static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d) { struct comedi_device *dev = d; + struct pcl816_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; int len, bufptr, this_dma_buf; unsigned long dma_flags; @@ -398,6 +399,8 @@ static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d) static irqreturn_t interrupt_pcl816(int irq, void *d) { struct comedi_device *dev = d; + struct pcl816_private *devpriv = dev->private; + DPRINTK(""); if (!dev->attached) { @@ -554,6 +557,7 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { const struct pcl816_board *board = comedi_board(dev); + struct pcl816_private *devpriv = dev->private; unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq; struct comedi_cmd *cmd = &s->async->cmd; unsigned int seglen; @@ -682,6 +686,7 @@ static int pcl816_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl816_private *devpriv = dev->private; unsigned long flags; unsigned int top1, top2, i; @@ -727,6 +732,8 @@ static int pcl816_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) static int pcl816_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl816_private *devpriv = dev->private; + /* DEBUG(printk("pcl816_ai_cancel()\n");) */ if (devpriv->irq_blocked > 0) { @@ -932,6 +939,7 @@ setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int *chanlist, unsigned int seglen) { + struct pcl816_private *devpriv = dev->private; unsigned int i; devpriv->ai_act_chanlist_len = seglen; @@ -991,6 +999,7 @@ static int set_rtc_irq_bit(unsigned char bit) static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl816_board *board = comedi_board(dev); + struct pcl816_private *devpriv; int ret; unsigned long iobase; unsigned int irq, dma; @@ -1015,9 +1024,10 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; } - ret = alloc_private(dev, sizeof(struct pcl816_private)); - if (ret < 0) - return ret; /* Can't alloc mem */ + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; dev->board_name = board->name; @@ -1216,6 +1226,7 @@ case COMEDI_SUBD_DO: static void pcl816_detach(struct comedi_device *dev) { const struct pcl816_board *board = comedi_board(dev); + struct pcl816_private *devpriv = dev->private; if (dev->private) { pcl816_ai_cancel(dev, devpriv->sub_ai); diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index d4b0859d81f..9dcddea3f61 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -326,8 +326,6 @@ static const unsigned int muxonechan[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -#define devpriv ((struct pcl818_private *)dev->private) - /* ============================================================================== */ @@ -406,6 +404,7 @@ static int pcl818_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl818_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); @@ -419,6 +418,7 @@ static int pcl818_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcl818_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); @@ -478,6 +478,7 @@ static int pcl818_do_insn_bits(struct comedi_device *dev, static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d) { struct comedi_device *dev = d; + struct pcl818_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; int low; int timeout = 50; /* wait max 50us */ @@ -537,6 +538,7 @@ conv_finish: static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) { struct comedi_device *dev = d; + struct pcl818_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; int i, len, bufptr; unsigned long flags; @@ -616,6 +618,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d) { struct comedi_device *dev = d; + struct pcl818_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; unsigned long tmp; unsigned int top1, top2, i, bufptr; @@ -721,6 +724,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d) static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) { struct comedi_device *dev = d; + struct pcl818_private *devpriv = dev->private; struct comedi_subdevice *s = &dev->subdevices[0]; int i, len, lo; @@ -795,6 +799,7 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) static irqreturn_t interrupt_pcl818(int irq, void *d) { struct comedi_device *dev = d; + struct pcl818_private *devpriv = dev->private; if (!dev->attached) { comedi_error(dev, "premature interrupt"); @@ -861,6 +866,7 @@ static irqreturn_t interrupt_pcl818(int irq, void *d) static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl818_private *devpriv = dev->private; unsigned int flags; unsigned int bytes; @@ -902,6 +908,7 @@ static void pcl818_ai_mode13dma_int(int mode, struct comedi_device *dev, static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl818_private *devpriv = dev->private; unsigned int flags; short *pole; @@ -943,6 +950,7 @@ static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device *dev, static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl818_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int divisor1 = 0, divisor2 = 0; unsigned int seglen; @@ -1063,6 +1071,7 @@ static int pcl818_ai_cmd_mode(int mode, struct comedi_device *dev, static int pcl818_ao_mode13(int mode, struct comedi_device *dev, struct comedi_subdevice *s, comedi_trig * it) { + struct pcl818_private *devpriv = dev->private; int divisor1 = 0, divisor2 = 0; if (!dev->irq) { @@ -1222,6 +1231,7 @@ static void setup_channel_list(struct comedi_device *dev, unsigned int *chanlist, unsigned int n_chan, unsigned int seglen) { + struct pcl818_private *devpriv = dev->private; int i; devpriv->act_chanlist_len = seglen; @@ -1259,6 +1269,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { const struct pcl818_board *board = comedi_board(dev); + struct pcl818_private *devpriv = dev->private; int err = 0; int tmp, divisor1 = 0, divisor2 = 0; @@ -1358,6 +1369,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, */ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl818_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int retval; @@ -1397,6 +1409,8 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) static int pcl818_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcl818_private *devpriv = dev->private; + if (devpriv->irq_blocked > 0) { dev_dbg(dev->class_dev, "pcl818_ai_cancel()\n"); devpriv->irq_was_now_closed = 1; @@ -1482,6 +1496,7 @@ static int pcl818_check(unsigned long iobase) static void pcl818_reset(struct comedi_device *dev) { const struct pcl818_board *board = comedi_board(dev); + struct pcl818_private *devpriv = dev->private; if (devpriv->usefifo) { /* FIFO shutdown */ outb(0, dev->iobase + PCL818_FI_INTCLR); @@ -1552,6 +1567,7 @@ static int set_rtc_irq_bit(unsigned char bit) static void rtc_dropped_irq(unsigned long data) { struct comedi_device *dev = (void *)data; + struct pcl818_private *devpriv = dev->private; unsigned long flags, tmp; switch (devpriv->int818_mode) { @@ -1601,6 +1617,7 @@ static int rtc_setfreq_irq(int freq) static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcl818_board *board = comedi_board(dev); + struct pcl818_private *devpriv; int ret; unsigned long iobase; unsigned int irq; @@ -1608,9 +1625,10 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long pages; struct comedi_subdevice *s; - ret = alloc_private(dev, sizeof(struct pcl818_private)); - if (ret < 0) - return ret; /* Can't alloc mem */ + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; /* claim our I/O space */ iobase = it->options[0]; @@ -1892,7 +1910,9 @@ no_dma: static void pcl818_detach(struct comedi_device *dev) { - if (dev->private) { + struct pcl818_private *devpriv = dev->private; + + if (devpriv) { pcl818_ai_cancel(dev, devpriv->sub_ai); pcl818_reset(dev); if (devpriv->dma) diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index cbb344a0f72..6e9a4ec9e85 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -148,13 +148,12 @@ static void do_3724_config(struct comedi_device *dev, static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s, int chanspec) { + struct priv_pcm3724 *priv = dev->private; struct comedi_subdevice *s_dio1 = &dev->subdevices[0]; unsigned int mask; int gatecfg; - struct priv_pcm3724 *priv; gatecfg = 0; - priv = dev->private; mask = 1 << CR_CHAN(chanspec); if (s == s_dio1) @@ -225,6 +224,7 @@ static int subdev_3724_insn_config(struct comedi_device *dev, static int pcm3724_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct priv_pcm3724 *priv; struct comedi_subdevice *s; unsigned long iobase; unsigned int iorange; @@ -235,12 +235,10 @@ static int pcm3724_attach(struct comedi_device *dev, iobase = it->options[0]; iorange = PCM3724_SIZE; - ret = alloc_private(dev, sizeof(struct priv_pcm3724)); - if (ret < 0) - return -ENOMEM; - - ((struct priv_pcm3724 *)(dev->private))->dio_1 = 0; - ((struct priv_pcm3724 *)(dev->private))->dio_2 = 0; + ret = alloc_private(dev, sizeof(*priv)); + if (ret) + return ret; + priv = dev->private; printk(KERN_INFO "comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor, dev->board_name, iobase); diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index 5efeb9205c2..5d5fc519d82 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -62,7 +62,6 @@ struct pcmad_priv_struct { int differential; int twos_comp; }; -#define devpriv ((struct pcmad_priv_struct *)dev->private) #define TIMEOUT 100 @@ -71,6 +70,7 @@ static int pcmad_ai_insn_read(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { const struct pcmad_board_struct *board = comedi_board(dev); + struct pcmad_priv_struct *devpriv = dev->private; int i; int chan; int n; @@ -104,6 +104,7 @@ static int pcmad_ai_insn_read(struct comedi_device *dev, static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcmad_board_struct *board = comedi_board(dev); + struct pcmad_priv_struct *devpriv; int ret; struct comedi_subdevice *s; unsigned long iobase; @@ -121,9 +122,10 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(struct pcmad_priv_struct)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; dev->board_name = board->name; diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index f2984f15506..c3009211026 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -79,8 +79,6 @@ struct pcmda12_private { int simultaneous_xfer_mode; }; -#define devpriv ((struct pcmda12_private *)(dev->private)) - static void zero_chans(struct comedi_device *dev) { /* sets up an ASIC chip to defaults */ @@ -97,6 +95,7 @@ static void zero_chans(struct comedi_device *dev) static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcmda12_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -139,6 +138,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct pcmda12_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -155,6 +155,7 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int pcmda12_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct pcmda12_private *devpriv; struct comedi_subdevice *s; unsigned long iobase; int ret; @@ -172,14 +173,10 @@ static int pcmda12_attach(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct pcmda12_private)) < 0) { - printk(KERN_ERR "cannot allocate private data structure\n"); - return -ENOMEM; - } + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; devpriv->simultaneous_xfer_mode = it->options[1]; diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 6ab45dfe68f..616652e00ef 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -229,11 +229,6 @@ struct pcmmio_private { struct pcmmio_subdev_private *sprivs; }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct pcmmio_private *)dev->private) #define subpriv ((struct pcmmio_subdev_private *)s->private) /* DIO devices are slightly special. Although it is possible to @@ -387,6 +382,8 @@ static int pcmmio_dio_insn_config(struct comedi_device *dev, static void switch_page(struct comedi_device *dev, int asic, int page) { + struct pcmmio_private *devpriv = dev->private; + if (asic < 0 || asic >= 1) return; /* paranoia */ if (page < 0 || page >= NUM_PAGES) @@ -403,6 +400,7 @@ static void switch_page(struct comedi_device *dev, int asic, int page) static void init_asics(struct comedi_device *dev) { /* sets up an ASIC chip to defaults */ + struct pcmmio_private *devpriv = dev->private; int asic; for (asic = 0; asic < 1; ++asic) { @@ -440,6 +438,8 @@ static void init_asics(struct comedi_device *dev) #ifdef notused static void lock_port(struct comedi_device *dev, int asic, int port) { + struct pcmmio_private *devpriv = dev->private; + if (asic < 0 || asic >= 1) return; /* paranoia */ if (port < 0 || port >= PORTS_PER_ASIC) @@ -454,6 +454,8 @@ static void lock_port(struct comedi_device *dev, int asic, int port) static void unlock_port(struct comedi_device *dev, int asic, int port) { + struct pcmmio_private *devpriv = dev->private; + if (asic < 0 || asic >= 1) return; /* paranoia */ if (port < 0 || port >= PORTS_PER_ASIC) @@ -468,6 +470,7 @@ static void unlock_port(struct comedi_device *dev, int asic, int port) static void pcmmio_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcmmio_private *devpriv = dev->private; int nports, firstport, asic, port; asic = subpriv->dio.intr.asic; @@ -490,6 +493,7 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) { int asic, got1 = 0; struct comedi_device *dev = (struct comedi_device *)d; + struct pcmmio_private *devpriv = dev->private; int i; for (asic = 0; asic < MAX_ASICS; ++asic) { @@ -649,6 +653,8 @@ static irqreturn_t interrupt_pcmmio(int irq, void *d) static int pcmmio_start_intr(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcmmio_private *devpriv = dev->private; + if (!subpriv->dio.intr.continuous && subpriv->dio.intr.stop_count == 0) { /* An empty acquisition! */ s->async->events |= COMEDI_CB_EOA; @@ -976,6 +982,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct pcmmio_private *devpriv; struct comedi_subdevice *s; int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic, thisasic_chanct = 0; @@ -998,15 +1005,10 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; } -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct pcmmio_private)) < 0) { - printk(KERN_ERR "comedi%d: cannot allocate private data structure\n", - dev->minor); - return -ENOMEM; - } + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; for (asic = 0; asic < MAX_ASICS; ++asic) { devpriv->asics[asic].num = asic; @@ -1165,6 +1167,7 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcmmio_detach(struct comedi_device *dev) { + struct pcmmio_private *devpriv = dev->private; int i; if (dev->iobase) diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 0e32119bc3f..360180438b3 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -194,11 +194,6 @@ struct pcmuio_private { struct pcmuio_subdev_private *sprivs; }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct pcmuio_private *)dev->private) #define subpriv ((struct pcmuio_subdev_private *)s->private) /* DIO devices are slightly special. Although it is possible to @@ -348,6 +343,7 @@ static int pcmuio_dio_insn_config(struct comedi_device *dev, static void switch_page(struct comedi_device *dev, int asic, int page) { const struct pcmuio_board *board = comedi_board(dev); + struct pcmuio_private *devpriv = dev->private; if (asic < 0 || asic >= board->num_asics) return; /* paranoia */ @@ -404,6 +400,7 @@ static void init_asics(struct comedi_device *dev) static void lock_port(struct comedi_device *dev, int asic, int port) { const struct pcmuio_board *board = comedi_board(dev); + struct pcmuio_private *devpriv = dev->private; if (asic < 0 || asic >= board->num_asics) return; /* paranoia */ @@ -419,6 +416,7 @@ static void lock_port(struct comedi_device *dev, int asic, int port) static void unlock_port(struct comedi_device *dev, int asic, int port) { const struct pcmuio_board *board = comedi_board(dev); + struct pcmuio_private *devpriv = dev->private; if (asic < 0 || asic >= board->num_asics) return; /* paranoia */ @@ -435,6 +433,7 @@ static void pcmuio_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s) { int nports, firstport, asic, port; + struct pcmuio_private *devpriv = dev->private; asic = subpriv->intr.asic; if (asic < 0) @@ -456,6 +455,7 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d) { int asic, got1 = 0; struct comedi_device *dev = (struct comedi_device *)d; + struct pcmuio_private *devpriv = dev->private; int i; for (asic = 0; asic < MAX_ASICS; ++asic) { @@ -607,6 +607,8 @@ static irqreturn_t interrupt_pcmuio(int irq, void *d) static int pcmuio_start_intr(struct comedi_device *dev, struct comedi_subdevice *s) { + struct pcmuio_private *devpriv = dev->private; + if (!subpriv->intr.continuous && subpriv->intr.stop_count == 0) { /* An empty acquisition! */ s->async->events |= COMEDI_CB_EOA; @@ -748,6 +750,7 @@ pcmuio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcmuio_board *board = comedi_board(dev); + struct pcmuio_private *devpriv; struct comedi_subdevice *s; int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0; unsigned long iobase; @@ -772,15 +775,10 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct pcmuio_private)) < 0) { - dev_warn(dev->class_dev, - "cannot allocate private data structure\n"); - return -ENOMEM; - } + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; for (asic = 0; asic < MAX_ASICS; ++asic) { devpriv->asics[asic].num = asic; @@ -905,6 +903,7 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) static void pcmuio_detach(struct comedi_device *dev) { const struct pcmuio_board *board = comedi_board(dev); + struct pcmuio_private *devpriv = dev->private; int i; if (dev->iobase) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 41d24b08913..b9fd16494d2 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1608,12 +1608,9 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) comedi_debug = 1; #endif - /* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct rtdPrivate)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; devpriv = dev->private; pcidev = rtd_find_pci(dev, it); diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index 137885b1681..82dae22b081 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -161,8 +161,6 @@ struct rti800_private { int muxgain_bits; }; -#define devpriv ((struct rti800_private *)dev->private) - #define RTI800_TIMEOUT 100 static irqreturn_t rti800_interrupt(int irq, void *dev) @@ -177,6 +175,7 @@ static int rti800_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct rti800_private *devpriv = dev->private; int i, t; int status; int chan = CR_CHAN(insn->chanspec); @@ -229,6 +228,7 @@ static int rti800_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct rti800_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -242,6 +242,7 @@ static int rti800_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct rti800_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); int d; int i; @@ -303,6 +304,7 @@ static int rti800_do_insn_bits(struct comedi_device *dev, static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct rti800_board *board = comedi_board(dev); + struct rti800_private *devpriv; unsigned int irq; unsigned long iobase; int ret; @@ -347,9 +349,10 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(struct rti800_private)); - if (ret < 0) + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) return ret; + devpriv = dev->private; devpriv->adc_mux = it->options[2]; devpriv->adc_range = it->options[3]; diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c index 3f9d0278be5..844e75ee9c4 100644 --- a/drivers/staging/comedi/drivers/rti802.c +++ b/drivers/staging/comedi/drivers/rti802.c @@ -55,12 +55,11 @@ struct rti802_private { unsigned int ao_readback[8]; }; -#define devpriv ((struct rti802_private *)dev->private) - static int rti802_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct rti802_private *devpriv = dev->private; int i; for (i = 0; i < insn->n; i++) @@ -73,6 +72,7 @@ static int rti802_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct rti802_private *devpriv = dev->private; int i, d; int chan = CR_CHAN(insn->chanspec); @@ -89,6 +89,7 @@ static int rti802_ao_insn_write(struct comedi_device *dev, static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct rti802_private *devpriv; struct comedi_subdevice *s; int i; unsigned long iobase; @@ -104,8 +105,10 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = "rti802"; - if (alloc_private(dev, sizeof(struct rti802_private))) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; ret = comedi_alloc_subdevices(dev, 1); if (ret) diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 9ed6a7eef01..3f9221d4918 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -64,12 +64,6 @@ struct serial2002_private { struct serial2002_range_table_t in_range[32], out_range[32]; }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct serial2002_private *)dev->private) - struct serial_data { enum { is_invalid, is_digital, is_channel } kind; int index; @@ -344,6 +338,7 @@ static void serial_write(struct file *f, struct serial_data data) static int serial_2002_open(struct comedi_device *dev) { + struct serial2002_private *devpriv = dev->private; int result; char port[20]; @@ -651,6 +646,8 @@ err_alloc_configs: static void serial_2002_close(struct comedi_device *dev) { + struct serial2002_private *devpriv = dev->private; + if (!IS_ERR(devpriv->tty) && devpriv->tty) filp_close(devpriv->tty, NULL); } @@ -659,6 +656,7 @@ static int serial2002_di_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct serial2002_private *devpriv = dev->private; int n; int chan; @@ -681,6 +679,7 @@ static int serial2002_do_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct serial2002_private *devpriv = dev->private; int n; int chan; @@ -700,6 +699,7 @@ static int serial2002_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct serial2002_private *devpriv = dev->private; int n; int chan; @@ -722,6 +722,7 @@ static int serial2002_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct serial2002_private *devpriv = dev->private; int n; int chan; @@ -742,6 +743,7 @@ static int serial2002_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct serial2002_private *devpriv = dev->private; int n; int chan = CR_CHAN(insn->chanspec); @@ -755,6 +757,7 @@ static int serial2002_ei_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct serial2002_private *devpriv = dev->private; int n; int chan; @@ -776,13 +779,18 @@ static int serial2002_ei_rinsn(struct comedi_device *dev, static int serial2002_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct serial2002_private *devpriv; struct comedi_subdevice *s; int ret; dev_dbg(dev->class_dev, "serial2002: attach\n"); dev->board_name = dev->driver->driver_name; - if (alloc_private(dev, sizeof(struct serial2002_private)) < 0) - return -ENOMEM; + + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; + dev->open = serial_2002_open; dev->close = serial_2002_close; devpriv->port = it->options[0]; diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index b70cdf300bb..d2ef7db6247 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -145,12 +145,6 @@ struct skel_private { unsigned int ao_readback[2]; }; -/* - * most drivers define the following macro to make it easy to - * access the private structure. - */ -#define devpriv ((struct skel_private *)dev->private) - /* * The struct comedi_driver structure tells the Comedi core module * which functions to call to configure/deconfigure (attach/detach) @@ -211,6 +205,7 @@ static int skel_ns_to_timer(unsigned int *ns, int round); */ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + struct skel_private *devpriv; struct comedi_subdevice *s; int ret; @@ -229,12 +224,11 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) */ dev->board_name = thisboard->name; -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if (alloc_private(dev, sizeof(struct skel_private)) < 0) - return -ENOMEM; + /* Allocate the private data */ + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; ret = comedi_alloc_subdevices(dev, 3); if (ret) @@ -504,6 +498,7 @@ static int skel_ns_to_timer(unsigned int *ns, int round) static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct skel_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); @@ -525,6 +520,7 @@ static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int skel_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct skel_private *devpriv = dev->private; int i; int chan = CR_CHAN(insn->chanspec); -- cgit v1.2.3 From 7f2f7e050bea242735880b7876d9771efb580213 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 15 Oct 2012 10:16:38 -0700 Subject: staging: comedi: s626: remove devpriv macro Missed one... This macro relies on a local variable having a specific name. Remove its use by replacing it with a local variable where used. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 40 ++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 551d68b7837..511183da0ee 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -161,7 +161,6 @@ static struct dio_private *dio_private_word[]={ }; */ -#define devpriv ((struct s626_private *)dev->private) #define diopriv ((struct dio_private *)s->private) /* COUNTER OBJECT ------------------------------------------------ */ @@ -232,6 +231,8 @@ static const struct comedi_lrange s626_range_table = { 2, { /* critical section. */ static void DEBItransfer(struct comedi_device *dev) { + struct s626_private *devpriv = dev->private; + /* Initiate upload of shadow RAM to DEBI control register. */ MC_ENABLE(P_MC2, MC2_UPLD_DEBI); @@ -249,6 +250,7 @@ static void DEBItransfer(struct comedi_device *dev) static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr) { + struct s626_private *devpriv = dev->private; uint16_t retval; /* Set up DEBI control register value in shadow RAM. */ @@ -267,6 +269,7 @@ static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr) /* Write a value to a gate array register. */ static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata) { + struct s626_private *devpriv = dev->private; /* Set up DEBI control register value in shadow RAM. */ WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); @@ -283,6 +286,7 @@ static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata) static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask, uint16_t wdata) { + struct s626_private *devpriv = dev->private; /* Copy target gate array register into P_DEBIAD register. */ WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); @@ -302,6 +306,8 @@ static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask, static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val) { + struct s626_private *devpriv = dev->private; + /* Write I2C command to I2C Transfer Control shadow register. */ WR7146(P_I2CCTRL, val); @@ -324,6 +330,7 @@ static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val) /* Read uint8_t from EEPROM. */ static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr) { + struct s626_private *devpriv = dev->private; uint8_t rtnval; /* Send EEPROM target address. */ @@ -375,6 +382,7 @@ static uint8_t trimadrs[] = { 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x */ static void SendDAC(struct comedi_device *dev, uint32_t val) { + struct s626_private *devpriv = dev->private; /* START THE SERIAL CLOCK RUNNING ------------- */ @@ -496,6 +504,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val) /* Private helper function: Write setpoint to an application DAC channel. */ static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata) { + struct s626_private *devpriv = dev->private; register uint16_t signmask; register uint32_t WSImage; @@ -553,6 +562,7 @@ static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata) static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan, uint8_t DacData) { + struct s626_private *devpriv = dev->private; uint32_t chan; /* Save the new setpoint in case the application needs to read it back later. */ @@ -735,6 +745,7 @@ static int s626_dio_clear_irq(struct comedi_device *dev) static irqreturn_t s626_irq_handler(int irq, void *d) { struct comedi_device *dev = d; + struct s626_private *devpriv = dev->private; struct comedi_subdevice *s; struct comedi_cmd *cmd; struct enc_private *k; @@ -968,6 +979,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d) */ static void ResetADC(struct comedi_device *dev, uint8_t *ppl) { + struct s626_private *devpriv = dev->private; register uint32_t *pRPS; uint32_t JmpAdrs; uint16_t i; @@ -1163,6 +1175,7 @@ static int s626_ai_insn_config(struct comedi_device *dev, /* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) */ /* { */ +/* struct s626_private *devpriv = dev->private; */ /* register uint8_t i; */ /* register int32_t *readaddr; */ @@ -1191,6 +1204,7 @@ static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct s626_private *devpriv = dev->private; uint16_t chan = CR_CHAN(insn->chanspec); uint16_t range = CR_RANGE(insn->chanspec); uint16_t AdcSpec = 0; @@ -1302,6 +1316,8 @@ static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd) static int s626_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { + struct s626_private *devpriv = dev->private; + if (trignum != 0) return -EINVAL; @@ -1378,7 +1394,7 @@ static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, /* TO COMPLETE */ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { - + struct s626_private *devpriv = dev->private; uint8_t ppl[16]; struct comedi_cmd *cmd = &s->async->cmd; struct enc_private *k; @@ -1643,6 +1659,8 @@ static int s626_ai_cmdtest(struct comedi_device *dev, static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { + struct s626_private *devpriv = dev->private; + /* Stop RPS program in case it is currently running. */ MC_DISABLE(P_MC1, MC1_ERPS1); @@ -1657,7 +1675,7 @@ static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - + struct s626_private *devpriv = dev->private; int i; uint16_t chan = CR_CHAN(insn->chanspec); int16_t dacdata; @@ -1676,6 +1694,7 @@ static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + struct s626_private *devpriv = dev->private; int i; for (i = 0; i < insn->n; i++) @@ -1974,6 +1993,7 @@ static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k) static void SetMode_A(struct comedi_device *dev, struct enc_private *k, uint16_t Setup, uint16_t DisableIntSrc) { + struct s626_private *devpriv = dev->private; register uint16_t cra; register uint16_t crb; register uint16_t setup = Setup; /* Cache the Standard Setup. */ @@ -2032,6 +2052,7 @@ static void SetMode_A(struct comedi_device *dev, struct enc_private *k, static void SetMode_B(struct comedi_device *dev, struct enc_private *k, uint16_t Setup, uint16_t DisableIntSrc) { + struct s626_private *devpriv = dev->private; register uint16_t cra; register uint16_t crb; register uint16_t setup = Setup; /* Cache the Standard Setup. */ @@ -2165,6 +2186,8 @@ static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k) static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k, uint16_t IntSource) { + struct s626_private *devpriv = dev->private; + /* Reset any pending counter overflow or index captures. */ DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL), CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A); @@ -2182,6 +2205,7 @@ static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k, static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k, uint16_t IntSource) { + struct s626_private *devpriv = dev->private; uint16_t crb; /* Cache writeable CRB register image. */ @@ -2412,6 +2436,7 @@ static void CountersInit(struct comedi_device *dev) static int s626_allocate_dma_buffers(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct s626_private *devpriv = dev->private; void *addr; dma_addr_t appdma; @@ -2432,6 +2457,7 @@ static int s626_allocate_dma_buffers(struct comedi_device *dev) static void s626_initialize(struct comedi_device *dev) { + struct s626_private *devpriv = dev->private; dma_addr_t pPhysBuf; uint16_t chan; int i; @@ -2667,14 +2693,17 @@ static void s626_initialize(struct comedi_device *dev) static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { + struct s626_private *devpriv; struct comedi_subdevice *s; int ret; comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; - if (alloc_private(dev, sizeof(struct s626_private)) < 0) - return -ENOMEM; + ret = alloc_private(dev, sizeof(*devpriv)); + if (ret) + return ret; + devpriv = dev->private; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) @@ -2794,6 +2823,7 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) static void s626_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct s626_private *devpriv = dev->private; if (devpriv) { /* stop ai_command */ -- cgit v1.2.3 From 0a7717dfe097d7a0a08e824ed39547c3e6e9d7e8 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 15 Oct 2012 13:07:31 +0100 Subject: staging: comedi: avoid a put_device(), get_device() sequence In `comedi_set_hw_dev()`, if there is no change to `dev->hw_dev` (and it is not `NULL`), don't bother putting and getting the device. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index cb67a5cb9c8..100ea0b0772 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -436,9 +436,10 @@ into comedi's buffer */ static inline void comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev) { + if (dev->hw_dev == hw_dev) + return; if (dev->hw_dev) put_device(dev->hw_dev); - dev->hw_dev = hw_dev; if (dev->hw_dev) { dev->hw_dev = get_device(dev->hw_dev); -- cgit v1.2.3 From 26cbd46529c07b50e92861f06497a5f327c48e69 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 15 Oct 2012 13:07:32 +0100 Subject: staging: comedi: always set hw_dev during auto-config Auto-configuration (auto-attachment) of USB and PCI comedi devices all goes through `comedi_auto_config_helper()`. That is a good place to set the comedi device's `hw_dev` pointer to the hardware `struct device` via a call to `comedi_set_hw_dev(comedi_device, hardware_device)` as it may obviate the need for the low-level comedi driver to make this call. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 1db6bfdbf13..09e1daf9576 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -860,6 +860,7 @@ comedi_auto_config_helper(struct device *hardware_device, else if (!try_module_get(driver->module)) ret = -EIO; else { + comedi_set_hw_dev(comedi_dev, hardware_device); /* set comedi_dev->driver here for attach wrapper */ comedi_dev->driver = driver; ret = (*attach_wrapper)(comedi_dev, context); -- cgit v1.2.3 From 49e8e44bcf3832a7fbe383a6e715b85ee2c7b2e6 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Fri, 5 Oct 2012 09:07:00 +0900 Subject: staging/comedi: Use dev_ printks in kcomedilib/kcomedilib_main.c fixed below checkpatch warning. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/kcomedilib/kcomedilib_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c index 3f20ea55b8d..944ba9d718d 100644 --- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c +++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c @@ -95,7 +95,8 @@ static int comedi_do_insn(struct comedi_device *dev, s = &dev->subdevices[insn->subdev]; if (s->type == COMEDI_SUBD_UNUSED) { - printk(KERN_ERR "%d not useable subdevice\n", insn->subdev); + dev_err(dev->class_dev, + "%d not useable subdevice\n", insn->subdev); ret = -EIO; goto error; } @@ -104,7 +105,7 @@ static int comedi_do_insn(struct comedi_device *dev, ret = comedi_check_chanlist(s, 1, &insn->chanspec); if (ret < 0) { - printk(KERN_ERR "bad chanspec\n"); + dev_err(dev->class_dev, "bad chanspec\n"); ret = -EINVAL; goto error; } -- cgit v1.2.3 From a74b5c515c2ce0883998ceaac6e35d14b4aaa709 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sat, 6 Oct 2012 14:31:43 +0900 Subject: staging/comedi: Use dev_ printks in drivers/me_daq.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: quoted string split across lines Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index c1bc5c6ce0c..3eac3ef8d79 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -386,8 +386,7 @@ static int me_ai_insn_read(struct comedi_device *dev, (readw(dev_private->me_regbase + ME_READ_AD_FIFO) ^ 0x800) & 0x0FFF; } else { - printk(KERN_ERR "comedi%d: Cannot get single value\n", - dev->minor); + dev_err(dev->class_dev, "Cannot get single value\n"); return -EIO; } @@ -573,8 +572,7 @@ static int me2600_xilinx_download(struct comedi_device *dev, if (value & 0x20) { /* Disable interrupt */ writel(0x00, dev_private->plx_regbase + PLX_INTCSR); - printk(KERN_ERR "comedi%d: Xilinx download failed\n", - dev->minor); + dev_err(dev->class_dev, "Xilinx download failed\n"); return -EIO; } @@ -665,8 +663,8 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) /* Enable PCI device and request PCI regions */ if (comedi_pci_enable(pcidev, dev->board_name) < 0) { - printk(KERN_ERR "comedi%d: Failed to enable PCI device and " - "request regions\n", dev->minor); + dev_err(dev->class_dev, + "Failed to enable PCI device and request regions\n"); return -EIO; } @@ -677,7 +675,7 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) ioremap(plx_regbase_tmp, plx_regbase_size_tmp); dev_private->plx_regbase_size = plx_regbase_size_tmp; if (!dev_private->plx_regbase) { - printk("comedi%d: Failed to remap I/O memory\n", dev->minor); + dev_err(dev->class_dev, "Failed to remap I/O memory\n"); return -ENOMEM; } @@ -687,11 +685,11 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) swap_regbase_size_tmp = pci_resource_len(pcidev, 5); if (!swap_regbase_tmp) - printk(KERN_ERR "comedi%d: Swap not present\n", dev->minor); + dev_err(dev->class_dev, "Swap not present\n"); /*---------------------------------------------- Workaround start ---*/ if (plx_regbase_tmp & 0x0080) { - printk(KERN_ERR "comedi%d: PLX-Bug detected\n", dev->minor); + dev_err(dev->class_dev, "PLX-Bug detected\n"); if (swap_regbase_tmp) { regbase_tmp = plx_regbase_tmp; @@ -727,8 +725,7 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) dev_private->me_regbase_size = me_regbase_size_tmp; dev_private->me_regbase = ioremap(me_regbase_tmp, me_regbase_size_tmp); if (!dev_private->me_regbase) { - printk(KERN_ERR "comedi%d: Failed to remap I/O memory\n", - dev->minor); + dev_err(dev->class_dev, "Failed to remap I/O memory\n"); return -ENOMEM; } -- cgit v1.2.3 From 89a3f111a0e7f922fced2a38035f3419a3da9307 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sat, 6 Oct 2012 14:32:40 +0900 Subject: staging/comedi: Use dev_ printks in drivers/adl_pci8164.c fixed below checkpatch warning. - WARNING: Prefer netdev_dbg(netdev, ... then dev_dbg(dev, ... then pr_debug(... to printk(KERN_DEBUG ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci8164.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 05e06e7ba9f..5a6d6d2e21b 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -89,9 +89,9 @@ static void adl_pci8164_insn_read(struct comedi_device *dev, } data[0] = inw(dev->iobase + axis_reg + offset); - printk(KERN_DEBUG "comedi: pci8164 %s read -> " - "%04X:%04X on axis %s\n", - action, data[0], data[1], axisname); + dev_dbg(dev->class_dev, + "pci8164 %s read -> %04X:%04X on axis %s\n", + action, data[0], data[1], axisname); } static int adl_pci8164_insn_read_msts(struct comedi_device *dev, @@ -170,9 +170,9 @@ static void adl_pci8164_insn_out(struct comedi_device *dev, outw(data[0], dev->iobase + axis_reg + offset); - printk(KERN_DEBUG "comedi: pci8164 %s write -> " - "%04X:%04X on axis %s\n", - action, data[0], data[1], axisname); + dev_dbg(dev->class_dev, + "pci8164 %s write -> %04X:%04X on axis %s\n", + action, data[0], data[1], axisname); } -- cgit v1.2.3 From ce3ed9f0cefac1b0e16640100928a6abacabc39b Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sat, 6 Oct 2012 14:52:34 +0900 Subject: staging/comedi: Use dev_ printks in drivers/quatech_daqp_cs.c fixed below checkpatch warnings. - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... - WARNING: Prefer netdev_warn(netdev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ... - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... - WARNING: Prefer netdev_notice(netdev, ... then dev_notice(dev, ... then pr_notice(... to printk(KERN_NOTICE ... and added pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 34 +++++++++++------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 3e276f7a338..d15bd8ac3d4 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -47,6 +47,8 @@ Status: works Devices: [Quatech] DAQP-208 (daqp), DAQP-308 */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "../comedidev.h" #include @@ -195,8 +197,8 @@ static struct comedi_driver driver_daqp = { static void daqp_dump(struct comedi_device *dev) { - printk(KERN_INFO "DAQP: status %02x; aux status %02x\n", - inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX)); + dev_info(dev->class_dev, "status %02x; aux status %02x\n", + inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX)); } static void hex_dump(char *str, void *ptr, int len) @@ -255,33 +257,29 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) int status; if (local == NULL) { - printk(KERN_WARNING - "daqp_interrupt(): irq %d for unknown device.\n", irq); + pr_warn("irq %d for unknown device.\n", irq); return IRQ_NONE; } dev = local->dev; if (dev == NULL) { - printk(KERN_WARNING "daqp_interrupt(): NULL comedi_device.\n"); + pr_warn("NULL comedi_device.\n"); return IRQ_NONE; } if (!dev->attached) { - printk(KERN_WARNING - "daqp_interrupt(): struct comedi_device not yet attached.\n"); + pr_warn("struct comedi_device not yet attached.\n"); return IRQ_NONE; } s = local->s; if (s == NULL) { - printk(KERN_WARNING - "daqp_interrupt(): NULL comedi_subdevice.\n"); + pr_warn("NULL comedi_subdevice.\n"); return IRQ_NONE; } if ((struct local_info_t *)s->private != local) { - printk(KERN_WARNING - "daqp_interrupt(): invalid comedi_subdevice.\n"); + pr_warn("invalid comedi_subdevice.\n"); return IRQ_NONE; } @@ -331,8 +329,8 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) } if (loop_limit <= 0) { - printk(KERN_WARNING - "loop_limit reached in daqp_interrupt()\n"); + dev_warn(dev->class_dev, + "loop_limit reached in daqp_interrupt()\n"); daqp_ai_cancel(dev, s); s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; } @@ -736,8 +734,8 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) while (--counter && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ; if (!counter) { - printk(KERN_ERR - "daqp: couldn't clear interrupts in status register\n"); + dev_err(dev->class_dev, + "couldn't clear interrupts in status register\n"); return -1; } @@ -852,8 +850,8 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - printk(KERN_INFO "comedi%d: attaching daqp%d (io 0x%04lx)\n", - dev->minor, it->options[0], dev->iobase); + dev_info(dev->class_dev, "attaching daqp%d (io 0x%04lx)\n", + it->options[0], dev->iobase); s = &dev->subdevices[0]; dev->read_subdev = s; @@ -958,7 +956,7 @@ static int daqp_cs_attach(struct pcmcia_device *link) if (dev_table[i] == NULL) break; if (i == MAX_DEV) { - printk(KERN_NOTICE "daqp_cs: no devices available\n"); + dev_notice(&link->dev, "no devices available\n"); return -ENODEV; } -- cgit v1.2.3 From 4370e80f4d1347288b4963e9bbebc02342be98b7 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sat, 6 Oct 2012 14:53:02 +0900 Subject: staging/comedi: Use dev_ printks in rtd520.c fixed below checkpatch warning. -Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index b9fd16494d2..b867470cc3e 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -507,15 +507,14 @@ static int rtd520_probe_fifo_depth(struct comedi_device *dev) } } if (i == limit) { - printk(KERN_INFO "\ncomedi: %s: failed to probe fifo size.\n", - DRV_NAME); + dev_info(dev->class_dev, "failed to probe fifo size.\n"); return -EIO; } writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR); if (fifo_size != 0x400 && fifo_size != 0x2000) { - printk - (KERN_INFO "\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n", - DRV_NAME, fifo_size); + dev_info(dev->class_dev, + "unexpected fifo size of %i, expected 1024 or 8192.\n", + fifo_size); return -EIO; } return fifo_size; @@ -1600,7 +1599,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) int index; #endif - printk(KERN_INFO "comedi%d: rtd520 attaching.\n", dev->minor); + dev_info(dev->class_dev, "rtd520 attaching.\n"); #if defined(CONFIG_COMEDI_DEBUG) && defined(USE_DMA) /* You can set this a load time: modprobe comedi comedi_debug=1 */ @@ -1623,7 +1622,8 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = comedi_pci_enable(pcidev, DRV_NAME); if (ret < 0) { - printk(KERN_INFO "Failed to enable PCI device and request regions.\n"); + dev_info(dev->class_dev, + "Failed to enable PCI device and request regions.\n"); return ret; } dev->iobase = 1; /* the "detach" needs this */ @@ -1650,8 +1650,9 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency); if (pci_latency < 32) { - printk(KERN_INFO "%s: PCI latency changed from %d to %d\n", - dev->board_name, pci_latency, 32); + dev_info(dev->class_dev, + "PCI latency changed from %d to %d\n", + pci_latency, 32); pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32); } else { @@ -1672,7 +1673,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* Show board configuration */ - printk(KERN_INFO "%s:", dev->board_name); + dev_info(dev->class_dev, "%s:", dev->board_name); ret = comedi_alloc_subdevices(dev, 4); if (ret) @@ -1764,7 +1765,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; } dev->irq = pcidev->irq; - printk(KERN_INFO "( irq=%u )", dev->irq); + dev_info(dev->class_dev, "( irq=%u )", dev->irq); ret = rtd520_probe_fifo_depth(dev); if (ret < 0) @@ -1841,7 +1842,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* set DMA trigger source */ writel(DMAS_ADFIFO_HALF_FULL, devpriv->las0 + LAS0_DMA0_SRC); } else { - printk(KERN_INFO "( no IRQ->no DMA )"); + dev_info(dev->class_dev, "( no IRQ->no DMA )"); } #endif /* USE_DMA */ -- cgit v1.2.3 From 3818a1427125c3f7fb408201eb9af826e93bdc42 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Mon, 8 Oct 2012 21:25:37 +0900 Subject: staging/comedi: Use dev_ printks in drivers/usbdux.c fixed below checkpatch warning. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index b536bba7435..e89f4e2927b 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2386,14 +2386,12 @@ static int usbdux_attach_usb(struct comedi_device *dev, down(&start_stop_sem); this_usbduxsub = usb_get_intfdata(uinterf); if (!this_usbduxsub || !this_usbduxsub->probed) { - printk(KERN_ERR - "comedi%d: usbdux: error: attach_usb failed, not connected\n", - dev->minor); + dev_err(dev->class_dev, + "usbdux: error: attach_usb failed, not connected\n"); ret = -ENODEV; } else if (this_usbduxsub->attached) { - printk(KERN_ERR - "comedi%d: usbdux: error: attach_usb failed, already attached\n", - dev->minor); + dev_err(dev->class_dev, + "error: attach_usb failed, already attached\n"); ret = -ENODEV; } else ret = usbdux_attach_common(dev, this_usbduxsub); -- cgit v1.2.3 From 351be7c9facb78b5b0f0d93fb70cd28180b61970 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Mon, 8 Oct 2012 21:25:58 +0900 Subject: staging/comedi: Use dev_ printks in drivers/ni_daq_dio24.c fixed below checkpatch warning. - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_daq_dio24.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index 1984c5fa3af..8df5bfe721f 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -202,7 +202,7 @@ static int dio24_cs_attach(struct pcmcia_device *link) { struct local_info_t *local; - printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n"); + dev_info(&link->dev, "ni_daq_dio24: HOLA SOY YO - CS-attach!\n"); dev_dbg(&link->dev, "dio24_cs_attach()\n"); @@ -242,7 +242,7 @@ static void dio24_config(struct pcmcia_device *link) { int ret; - printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n"); + dev_info(&link->dev, "ni_daq_dio24: HOLA SOY YO! - config\n"); dev_dbg(&link->dev, "dio24_config\n"); @@ -265,7 +265,7 @@ static void dio24_config(struct pcmcia_device *link) return; failed: - printk(KERN_INFO "Fallo"); + dev_info(&link->dev, "Fallo"); dio24_release(link); } /* dio24_config */ -- cgit v1.2.3 From 66ae18fa13c2925fbfb31fcdf00b45a76547cb5b Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Mon, 8 Oct 2012 21:26:17 +0900 Subject: staging/comedi: Use dev_ printks in drivers/ni_pcimio.c fixed below checkpatch warning. - WARNING: Prefer netdev_warn(netdev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcimio.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 8723e84826c..2e6dbeec9a9 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1384,8 +1384,9 @@ static void m_series_stc_writew(struct comedi_device *dev, uint16_t data, /* FIXME: DIO_Output_Register (16 bit reg) is replaced by M_Offset_Static_Digital_Output (32 bit) and M_Offset_SCXI_Serial_Data_Out (8 bit) */ default: - printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n", - __func__, reg); + dev_warn(dev->class_dev, + "%s: bug! unhandled register=0x%x in switch.\n", + __func__, reg); BUG(); return; break; @@ -1421,8 +1422,9 @@ static uint16_t m_series_stc_readw(struct comedi_device *dev, int reg) offset = M_Offset_G01_Status; break; default: - printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n", - __func__, reg); + dev_warn(dev->class_dev, + "%s: bug! unhandled register=0x%x in switch.\n", + __func__, reg); BUG(); return 0; break; @@ -1465,8 +1467,9 @@ static void m_series_stc_writel(struct comedi_device *dev, uint32_t data, offset = M_Offset_G1_Load_B; break; default: - printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n", - __func__, reg); + dev_warn(dev->class_dev, + "%s: bug! unhandled register=0x%x in switch.\n", + __func__, reg); BUG(); return; break; @@ -1493,8 +1496,9 @@ static uint32_t m_series_stc_readl(struct comedi_device *dev, int reg) offset = M_Offset_G1_Save; break; default: - printk(KERN_WARNING "%s: bug! unhandled register=0x%x in switch.\n", - __func__, reg); + dev_warn(dev->class_dev, + "%s: bug! unhandled register=0x%x in switch.\n", + __func__, reg); BUG(); return 0; break; -- cgit v1.2.3 From e209939f31736b00e816e10d4a93af5c5fefb0e0 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Mon, 8 Oct 2012 21:26:33 +0900 Subject: staging/comedi: Use dev_ printks in drivers/ii_pci20kc.c fixed below checkpatch warnings. - WARNING: Prefer netdev_warn(netdev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ii_pci20kc.c | 35 +++++++++++++---------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index 64a4acd0aa5..972a09fa753 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -216,13 +216,13 @@ static int pci20xxx_attach(struct comedi_device *dev, /* Check PCI-20001 C-2A Carrier Board ID */ if ((readb(devpriv->ioaddr) & PCI20000_ID) != PCI20000_ID) { - printk(KERN_WARNING "comedi%d: ii_pci20kc PCI-20001" - " C-2A Carrier Board at base=0x%p not found !\n", - dev->minor, devpriv->ioaddr); + dev_warn(dev->class_dev, + "PCI-20001 C-2A Carrier Board at base=0x%p not found !\n", + devpriv->ioaddr); return -EINVAL; } - printk(KERN_INFO "comedi%d: ii_pci20kc: PCI-20001 C-2A at base=0x%p\n", - dev->minor, devpriv->ioaddr); + dev_info(dev->class_dev, "PCI-20001 C-2A at base=0x%p\n", + devpriv->ioaddr); for (i = 0; i < PCI20000_MODULES; i++) { s = &dev->subdevices[i]; @@ -235,23 +235,21 @@ static int pci20xxx_attach(struct comedi_device *dev, devpriv->ioaddr + (i + 1) * PCI20000_OFFSET; pci20006_init(dev, s, it->options[2 * i + 2], it->options[2 * i + 3]); - printk(KERN_INFO "comedi%d: " - "ii_pci20kc PCI-20006 module in slot %d\n", - dev->minor, i + 1); + dev_info(dev->class_dev, + "PCI-20006 module in slot %d\n", i + 1); break; case PCI20341_ID: sdp->pci20341.iobase = devpriv->ioaddr + (i + 1) * PCI20000_OFFSET; pci20341_init(dev, s, it->options[2 * i + 2], it->options[2 * i + 3]); - printk(KERN_INFO "comedi%d: " - "ii_pci20kc PCI-20341 module in slot %d\n", - dev->minor, i + 1); + dev_info(dev->class_dev, + "PCI-20341 module in slot %d\n", i + 1); break; default: - printk(KERN_WARNING "ii_pci20kc: unknown module " - "code 0x%02x in slot %d: module disabled\n", - id, i); /* XXX this looks like a bug! i + 1 ?? */ + dev_warn(dev->class_dev, + "unknown module code 0x%02x in slot %d: module disabled\n", + id, i); /* XXX this looks like a bug! i + 1 ?? */ /* fall through */ case PCI20xxx_EMPTY_ID: s->type = COMEDI_SUBD_UNUSED; @@ -347,8 +345,7 @@ static int pci20006_insn_write(struct comedi_device *dev, writeb(0x00, sdp->iobase + PCI20006_STROBE1); break; default: - printk(KERN_WARNING - " comedi%d: pci20xxx: ao channel Error!\n", dev->minor); + dev_warn(dev->class_dev, "ao channel Error!\n"); return -EINVAL; } @@ -463,10 +460,8 @@ static int pci20341_insn_read(struct comedi_device *dev, eoc = readb(sdp->iobase + PCI20341_STATUS_REG); } if (j >= 100) { - printk(KERN_WARNING - "comedi%d: pci20xxx: " - "AI interrupt channel %i polling exit !\n", - dev->minor, i); + dev_warn(dev->class_dev, + "AI interrupt channel %i polling exit !\n", i); return -EINVAL; } lo = readb(sdp->iobase + PCI20341_LDATA); -- cgit v1.2.3 From 509f3f78c99e89c83714f0cad40ea09e18f21d03 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 9 Oct 2012 22:07:27 +0900 Subject: staging/comedi: Use pr_ or dev_ printks in drivers/dt9812.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... and added pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt9812.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 71d38fc5c16..02b5394d7bd 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -43,6 +43,8 @@ for my needs. * says P1). */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -1083,8 +1085,7 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->insn_write = &dt9812_ao_winsn; s->insn_read = &dt9812_ao_rinsn; - printk(KERN_INFO "comedi%d: successfully attached to dt9812.\n", - dev->minor); + dev_info(dev->class_dev, "successfully attached to dt9812.\n"); down(&dt9812_mutex); /* Find a slot for the comedi device */ @@ -1146,17 +1147,15 @@ static int __init usb_dt9812_init(void) /* register with the USB subsystem */ result = usb_register(&dt9812_usb_driver); if (result) { - printk(KERN_ERR KBUILD_MODNAME - ": usb_register failed. Error number %d\n", result); + pr_err("usb_register failed. Error number %d\n", result); return result; } /* register with comedi */ result = comedi_driver_register(&dt9812_comedi_driver); if (result) { usb_deregister(&dt9812_usb_driver); - printk(KERN_ERR KBUILD_MODNAME - ": comedi_driver_register failed. Error number %d\n", - result); + pr_err("comedi_driver_register failed. Error number %d\n", + result); } return result; -- cgit v1.2.3 From 89334ab4d389c008d291eb8682914c759851ee34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Tue, 16 Oct 2012 15:29:52 -0700 Subject: Staging: android: binder: Add some missing binder_stat_br calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cached thread return errors, death notifications and new looper requests were not included in the stats. Signed-off-by: Arve Hjønnevåg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/binder.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 7b0ba92e7e4..9e852d0bef3 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -2135,6 +2135,7 @@ retry: if (put_user(thread->return_error2, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); + binder_stat_br(proc, thread, thread->return_error2); if (ptr == end) goto done; thread->return_error2 = BR_OK; @@ -2142,6 +2143,7 @@ retry: if (put_user(thread->return_error, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); + binder_stat_br(proc, thread, thread->return_error); thread->return_error = BR_OK; goto done; } @@ -2297,6 +2299,7 @@ retry: if (put_user(death->cookie, (void * __user *)ptr)) return -EFAULT; ptr += sizeof(void *); + binder_stat_br(proc, thread, cmd); binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, "binder: %d:%d %s %p\n", proc->pid, thread->pid, @@ -2404,6 +2407,7 @@ done: proc->pid, thread->pid); if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer)) return -EFAULT; + binder_stat_br(proc, thread, BR_SPAWN_LOOPER); } return 0; } -- cgit v1.2.3 From 975a1ac9a9fe65d66ee1726c0db6dc58e53d232a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Tue, 16 Oct 2012 15:29:53 -0700 Subject: Staging: android: binder: Add some tracepoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add tracepoints: - ioctl entry and exit - Main binder lock: lock, locked and unlock - Command and return buffer opcodes - Transaction: create and receive - Transaction buffer: create and free - Object and file descriptor transfer - binder_update_page_range Signed-off-by: Arve Hjønnevåg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/Makefile | 2 + drivers/staging/android/binder.c | 91 +++++++-- drivers/staging/android/binder_trace.h | 327 +++++++++++++++++++++++++++++++++ 3 files changed, 400 insertions(+), 20 deletions(-) create mode 100644 drivers/staging/android/binder_trace.h diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index e16fcd51716..b35a631734d 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -1,3 +1,5 @@ +ccflags-y += -I$(src) # needed for trace events + obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o obj-$(CONFIG_ASHMEM) += ashmem.o obj-$(CONFIG_ANDROID_LOGGER) += logger.o diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 9e852d0bef3..b7cfcdbcbeb 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -35,8 +35,9 @@ #include #include "binder.h" +#include "binder_trace.h" -static DEFINE_MUTEX(binder_lock); +static DEFINE_MUTEX(binder_main_lock); static DEFINE_MUTEX(binder_deferred_lock); static DEFINE_MUTEX(binder_mmap_lock); @@ -411,6 +412,19 @@ static long task_close_fd(struct binder_proc *proc, unsigned int fd) return retval; } +static inline void binder_lock(const char *tag) +{ + trace_binder_lock(tag); + mutex_lock(&binder_main_lock); + trace_binder_locked(tag); +} + +static inline void binder_unlock(const char *tag) +{ + trace_binder_unlock(tag); + mutex_unlock(&binder_main_lock); +} + static void binder_set_nice(long nice) { long min_nice; @@ -537,6 +551,8 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, if (end <= start) return 0; + trace_binder_update_page_range(proc, allocate, start, end); + if (vma) mm = NULL; else @@ -1461,6 +1477,9 @@ static void binder_transaction(struct binder_proc *proc, t->code = tr->code; t->flags = tr->flags; t->priority = task_nice(current); + + trace_binder_transaction(reply, t, target_node); + t->buffer = binder_alloc_buf(target_proc, tr->data_size, tr->offsets_size, !reply && (t->flags & TF_ONE_WAY)); if (t->buffer == NULL) { @@ -1471,6 +1490,7 @@ static void binder_transaction(struct binder_proc *proc, t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; t->buffer->target_node = target_node; + trace_binder_transaction_alloc_buf(t->buffer); if (target_node) binder_inc_node(target_node, 1, 0, NULL); @@ -1543,6 +1563,7 @@ static void binder_transaction(struct binder_proc *proc, binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE, &thread->todo); + trace_binder_transaction_node_to_ref(t, node, ref); binder_debug(BINDER_DEBUG_TRANSACTION, " node %d u%p -> ref %d desc %d\n", node->debug_id, node->ptr, ref->debug_id, @@ -1567,6 +1588,7 @@ static void binder_transaction(struct binder_proc *proc, fp->binder = ref->node->ptr; fp->cookie = ref->node->cookie; binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL); + trace_binder_transaction_ref_to_node(t, ref); binder_debug(BINDER_DEBUG_TRANSACTION, " ref %d desc %d -> node %d u%p\n", ref->debug_id, ref->desc, ref->node->debug_id, @@ -1580,6 +1602,8 @@ static void binder_transaction(struct binder_proc *proc, } fp->handle = new_ref->desc; binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); + trace_binder_transaction_ref_to_ref(t, ref, + new_ref); binder_debug(BINDER_DEBUG_TRANSACTION, " ref %d desc %d -> ref %d desc %d (node %d)\n", ref->debug_id, ref->desc, new_ref->debug_id, @@ -1619,6 +1643,7 @@ static void binder_transaction(struct binder_proc *proc, goto err_get_unused_fd_failed; } task_fd_install(target_proc, target_fd, file); + trace_binder_transaction_fd(t, fp->handle, target_fd); binder_debug(BINDER_DEBUG_TRANSACTION, " fd %ld -> %d\n", fp->handle, target_fd); /* TODO: fput? */ @@ -1667,6 +1692,7 @@ err_binder_new_node_failed: err_bad_object_type: err_bad_offset: err_copy_data_failed: + trace_binder_transaction_failed_buffer_release(t->buffer); binder_transaction_buffer_release(target_proc, t->buffer, offp); t->buffer->transaction = NULL; binder_free_buf(target_proc, t->buffer); @@ -1712,6 +1738,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, if (get_user(cmd, (uint32_t __user *)ptr)) return -EFAULT; ptr += sizeof(uint32_t); + trace_binder_command(cmd); if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.bc)) { binder_stats.bc[_IOC_NR(cmd)]++; proc->stats.bc[_IOC_NR(cmd)]++; @@ -1881,6 +1908,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, else list_move_tail(buffer->target_node->async_todo.next, &thread->todo); } + trace_binder_transaction_buffer_release(buffer); binder_transaction_buffer_release(proc, buffer, NULL); binder_free_buf(proc, buffer); break; @@ -2089,6 +2117,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, void binder_stat_br(struct binder_proc *proc, struct binder_thread *thread, uint32_t cmd) { + trace_binder_return(cmd); if (_IOC_NR(cmd) < ARRAY_SIZE(binder_stats.br)) { binder_stats.br[_IOC_NR(cmd)]++; proc->stats.br[_IOC_NR(cmd)]++; @@ -2152,7 +2181,12 @@ retry: thread->looper |= BINDER_LOOPER_STATE_WAITING; if (wait_for_proc_work) proc->ready_threads++; - mutex_unlock(&binder_lock); + + binder_unlock(__func__); + + trace_binder_wait_for_work(wait_for_proc_work, + !!thread->transaction_stack, + !list_empty(&thread->todo)); if (wait_for_proc_work) { if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED))) { @@ -2176,7 +2210,9 @@ retry: } else ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread)); } - mutex_lock(&binder_lock); + + binder_lock(__func__); + if (wait_for_proc_work) proc->ready_threads--; thread->looper &= ~BINDER_LOOPER_STATE_WAITING; @@ -2367,6 +2403,7 @@ retry: return -EFAULT; ptr += sizeof(tr); + trace_binder_transaction_received(t); binder_stat_br(proc, thread, cmd); binder_debug(BINDER_DEBUG_TRANSACTION, "binder: %d:%d %s %d %d:%d, cmd %d" @@ -2520,12 +2557,14 @@ static unsigned int binder_poll(struct file *filp, struct binder_thread *thread = NULL; int wait_for_proc_work; - mutex_lock(&binder_lock); + binder_lock(__func__); + thread = binder_get_thread(proc); wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo) && thread->return_error == BR_OK; - mutex_unlock(&binder_lock); + + binder_unlock(__func__); if (wait_for_proc_work) { if (binder_has_proc_work(proc, thread)) @@ -2553,11 +2592,13 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) /*pr_info("binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/ + trace_binder_ioctl(cmd, arg); + ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); if (ret) - return ret; + goto err_unlocked; - mutex_lock(&binder_lock); + binder_lock(__func__); thread = binder_get_thread(proc); if (thread == NULL) { ret = -ENOMEM; @@ -2582,6 +2623,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (bwr.write_size > 0) { ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed); + trace_binder_write_done(ret); if (ret < 0) { bwr.read_consumed = 0; if (copy_to_user(ubuf, &bwr, sizeof(bwr))) @@ -2591,6 +2633,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } if (bwr.read_size > 0) { ret = binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK); + trace_binder_read_done(ret); if (!list_empty(&proc->todo)) wake_up_interruptible(&proc->wait); if (ret < 0) { @@ -2666,10 +2709,12 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) err: if (thread) thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN; - mutex_unlock(&binder_lock); + binder_unlock(__func__); wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); if (ret && ret != -ERESTARTSYS) pr_info("binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); +err_unlocked: + trace_binder_ioctl_done(ret); return ret; } @@ -2815,13 +2860,16 @@ static int binder_open(struct inode *nodp, struct file *filp) INIT_LIST_HEAD(&proc->todo); init_waitqueue_head(&proc->wait); proc->default_priority = task_nice(current); - mutex_lock(&binder_lock); + + binder_lock(__func__); + binder_stats_created(BINDER_STAT_PROC); hlist_add_head(&proc->proc_node, &binder_procs); proc->pid = current->group_leader->pid; INIT_LIST_HEAD(&proc->delivered_death); filp->private_data = proc; - mutex_unlock(&binder_lock); + + binder_unlock(__func__); if (binder_debugfs_dir_entry_proc) { char strbuf[11]; @@ -3001,7 +3049,7 @@ static void binder_deferred_func(struct work_struct *work) int defer; do { - mutex_lock(&binder_lock); + binder_lock(__func__); mutex_lock(&binder_deferred_lock); if (!hlist_empty(&binder_deferred_list)) { proc = hlist_entry(binder_deferred_list.first, @@ -3028,7 +3076,7 @@ static void binder_deferred_func(struct work_struct *work) if (defer & BINDER_DEFERRED_RELEASE) binder_deferred_release(proc); /* frees proc */ - mutex_unlock(&binder_lock); + binder_unlock(__func__); if (files) put_files_struct(files); } while (proc); @@ -3369,7 +3417,7 @@ static int binder_state_show(struct seq_file *m, void *unused) int do_lock = !binder_debug_no_lock; if (do_lock) - mutex_lock(&binder_lock); + binder_lock(__func__); seq_puts(m, "binder state:\n"); @@ -3381,7 +3429,7 @@ static int binder_state_show(struct seq_file *m, void *unused) hlist_for_each_entry(proc, pos, &binder_procs, proc_node) print_binder_proc(m, proc, 1); if (do_lock) - mutex_unlock(&binder_lock); + binder_unlock(__func__); return 0; } @@ -3392,7 +3440,7 @@ static int binder_stats_show(struct seq_file *m, void *unused) int do_lock = !binder_debug_no_lock; if (do_lock) - mutex_lock(&binder_lock); + binder_lock(__func__); seq_puts(m, "binder stats:\n"); @@ -3401,7 +3449,7 @@ static int binder_stats_show(struct seq_file *m, void *unused) hlist_for_each_entry(proc, pos, &binder_procs, proc_node) print_binder_proc_stats(m, proc); if (do_lock) - mutex_unlock(&binder_lock); + binder_unlock(__func__); return 0; } @@ -3412,13 +3460,13 @@ static int binder_transactions_show(struct seq_file *m, void *unused) int do_lock = !binder_debug_no_lock; if (do_lock) - mutex_lock(&binder_lock); + binder_lock(__func__); seq_puts(m, "binder transactions:\n"); hlist_for_each_entry(proc, pos, &binder_procs, proc_node) print_binder_proc(m, proc, 0); if (do_lock) - mutex_unlock(&binder_lock); + binder_unlock(__func__); return 0; } @@ -3428,11 +3476,11 @@ static int binder_proc_show(struct seq_file *m, void *unused) int do_lock = !binder_debug_no_lock; if (do_lock) - mutex_lock(&binder_lock); + binder_lock(__func__); seq_puts(m, "binder proc state:\n"); print_binder_proc(m, proc, 1); if (do_lock) - mutex_unlock(&binder_lock); + binder_unlock(__func__); return 0; } @@ -3527,4 +3575,7 @@ static int __init binder_init(void) device_initcall(binder_init); +#define CREATE_TRACE_POINTS +#include "binder_trace.h" + MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/android/binder_trace.h b/drivers/staging/android/binder_trace.h new file mode 100644 index 00000000000..82a567c2af6 --- /dev/null +++ b/drivers/staging/android/binder_trace.h @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2012 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM binder + +#if !defined(_BINDER_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _BINDER_TRACE_H + +#include + +struct binder_buffer; +struct binder_node; +struct binder_proc; +struct binder_ref; +struct binder_thread; +struct binder_transaction; + +TRACE_EVENT(binder_ioctl, + TP_PROTO(unsigned int cmd, unsigned long arg), + TP_ARGS(cmd, arg), + + TP_STRUCT__entry( + __field(unsigned int, cmd) + __field(unsigned long, arg) + ), + TP_fast_assign( + __entry->cmd = cmd; + __entry->arg = arg; + ), + TP_printk("cmd=0x%x arg=0x%lx", __entry->cmd, __entry->arg) +); + +DECLARE_EVENT_CLASS(binder_lock_class, + TP_PROTO(const char *tag), + TP_ARGS(tag), + TP_STRUCT__entry( + __field(const char *, tag) + ), + TP_fast_assign( + __entry->tag = tag; + ), + TP_printk("tag=%s", __entry->tag) +); + +#define DEFINE_BINDER_LOCK_EVENT(name) \ +DEFINE_EVENT(binder_lock_class, name, \ + TP_PROTO(const char *func), \ + TP_ARGS(func)) + +DEFINE_BINDER_LOCK_EVENT(binder_lock); +DEFINE_BINDER_LOCK_EVENT(binder_locked); +DEFINE_BINDER_LOCK_EVENT(binder_unlock); + +DECLARE_EVENT_CLASS(binder_function_return_class, + TP_PROTO(int ret), + TP_ARGS(ret), + TP_STRUCT__entry( + __field(int, ret) + ), + TP_fast_assign( + __entry->ret = ret; + ), + TP_printk("ret=%d", __entry->ret) +); + +#define DEFINE_BINDER_FUNCTION_RETURN_EVENT(name) \ +DEFINE_EVENT(binder_function_return_class, name, \ + TP_PROTO(int ret), \ + TP_ARGS(ret)) + +DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_ioctl_done); +DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_write_done); +DEFINE_BINDER_FUNCTION_RETURN_EVENT(binder_read_done); + +TRACE_EVENT(binder_wait_for_work, + TP_PROTO(bool proc_work, bool transaction_stack, bool thread_todo), + TP_ARGS(proc_work, transaction_stack, thread_todo), + + TP_STRUCT__entry( + __field(bool, proc_work) + __field(bool, transaction_stack) + __field(bool, thread_todo) + ), + TP_fast_assign( + __entry->proc_work = proc_work; + __entry->transaction_stack = transaction_stack; + __entry->thread_todo = thread_todo; + ), + TP_printk("proc_work=%d transaction_stack=%d thread_todo=%d", + __entry->proc_work, __entry->transaction_stack, + __entry->thread_todo) +); + +TRACE_EVENT(binder_transaction, + TP_PROTO(bool reply, struct binder_transaction *t, + struct binder_node *target_node), + TP_ARGS(reply, t, target_node), + TP_STRUCT__entry( + __field(int, debug_id) + __field(int, target_node) + __field(int, to_proc) + __field(int, to_thread) + __field(int, reply) + __field(unsigned int, code) + __field(unsigned int, flags) + ), + TP_fast_assign( + __entry->debug_id = t->debug_id; + __entry->target_node = target_node ? target_node->debug_id : 0; + __entry->to_proc = t->to_proc->pid; + __entry->to_thread = t->to_thread ? t->to_thread->pid : 0; + __entry->reply = reply; + __entry->code = t->code; + __entry->flags = t->flags; + ), + TP_printk("transaction=%d dest_node=%d dest_proc=%d dest_thread=%d reply=%d flags=0x%x code=0x%x", + __entry->debug_id, __entry->target_node, + __entry->to_proc, __entry->to_thread, + __entry->reply, __entry->flags, __entry->code) +); + +TRACE_EVENT(binder_transaction_received, + TP_PROTO(struct binder_transaction *t), + TP_ARGS(t), + + TP_STRUCT__entry( + __field(int, debug_id) + ), + TP_fast_assign( + __entry->debug_id = t->debug_id; + ), + TP_printk("transaction=%d", __entry->debug_id) +); + +TRACE_EVENT(binder_transaction_node_to_ref, + TP_PROTO(struct binder_transaction *t, struct binder_node *node, + struct binder_ref *ref), + TP_ARGS(t, node, ref), + + TP_STRUCT__entry( + __field(int, debug_id) + __field(int, node_debug_id) + __field(void __user *, node_ptr) + __field(int, ref_debug_id) + __field(uint32_t, ref_desc) + ), + TP_fast_assign( + __entry->debug_id = t->debug_id; + __entry->node_debug_id = node->debug_id; + __entry->node_ptr = node->ptr; + __entry->ref_debug_id = ref->debug_id; + __entry->ref_desc = ref->desc; + ), + TP_printk("transaction=%d node=%d src_ptr=0x%p ==> dest_ref=%d dest_desc=%d", + __entry->debug_id, __entry->node_debug_id, __entry->node_ptr, + __entry->ref_debug_id, __entry->ref_desc) +); + +TRACE_EVENT(binder_transaction_ref_to_node, + TP_PROTO(struct binder_transaction *t, struct binder_ref *ref), + TP_ARGS(t, ref), + + TP_STRUCT__entry( + __field(int, debug_id) + __field(int, ref_debug_id) + __field(uint32_t, ref_desc) + __field(int, node_debug_id) + __field(void __user *, node_ptr) + ), + TP_fast_assign( + __entry->debug_id = t->debug_id; + __entry->ref_debug_id = ref->debug_id; + __entry->ref_desc = ref->desc; + __entry->node_debug_id = ref->node->debug_id; + __entry->node_ptr = ref->node->ptr; + ), + TP_printk("transaction=%d node=%d src_ref=%d src_desc=%d ==> dest_ptr=0x%p", + __entry->debug_id, __entry->node_debug_id, + __entry->ref_debug_id, __entry->ref_desc, __entry->node_ptr) +); + +TRACE_EVENT(binder_transaction_ref_to_ref, + TP_PROTO(struct binder_transaction *t, struct binder_ref *src_ref, + struct binder_ref *dest_ref), + TP_ARGS(t, src_ref, dest_ref), + + TP_STRUCT__entry( + __field(int, debug_id) + __field(int, node_debug_id) + __field(int, src_ref_debug_id) + __field(uint32_t, src_ref_desc) + __field(int, dest_ref_debug_id) + __field(uint32_t, dest_ref_desc) + ), + TP_fast_assign( + __entry->debug_id = t->debug_id; + __entry->node_debug_id = src_ref->node->debug_id; + __entry->src_ref_debug_id = src_ref->debug_id; + __entry->src_ref_desc = src_ref->desc; + __entry->dest_ref_debug_id = dest_ref->debug_id; + __entry->dest_ref_desc = dest_ref->desc; + ), + TP_printk("transaction=%d node=%d src_ref=%d src_desc=%d ==> dest_ref=%d dest_desc=%d", + __entry->debug_id, __entry->node_debug_id, + __entry->src_ref_debug_id, __entry->src_ref_desc, + __entry->dest_ref_debug_id, __entry->dest_ref_desc) +); + +TRACE_EVENT(binder_transaction_fd, + TP_PROTO(struct binder_transaction *t, int src_fd, int dest_fd), + TP_ARGS(t, src_fd, dest_fd), + + TP_STRUCT__entry( + __field(int, debug_id) + __field(int, src_fd) + __field(int, dest_fd) + ), + TP_fast_assign( + __entry->debug_id = t->debug_id; + __entry->src_fd = src_fd; + __entry->dest_fd = dest_fd; + ), + TP_printk("transaction=%d src_fd=%d ==> dest_fd=%d", + __entry->debug_id, __entry->src_fd, __entry->dest_fd) +); + +DECLARE_EVENT_CLASS(binder_buffer_class, + TP_PROTO(struct binder_buffer *buf), + TP_ARGS(buf), + TP_STRUCT__entry( + __field(int, debug_id) + __field(size_t, data_size) + __field(size_t, offsets_size) + ), + TP_fast_assign( + __entry->debug_id = buf->debug_id; + __entry->data_size = buf->data_size; + __entry->offsets_size = buf->offsets_size; + ), + TP_printk("transaction=%d data_size=%zd offsets_size=%zd", + __entry->debug_id, __entry->data_size, __entry->offsets_size) +); + +DEFINE_EVENT(binder_buffer_class, binder_transaction_alloc_buf, + TP_PROTO(struct binder_buffer *buffer), + TP_ARGS(buffer)); + +DEFINE_EVENT(binder_buffer_class, binder_transaction_buffer_release, + TP_PROTO(struct binder_buffer *buffer), + TP_ARGS(buffer)); + +DEFINE_EVENT(binder_buffer_class, binder_transaction_failed_buffer_release, + TP_PROTO(struct binder_buffer *buffer), + TP_ARGS(buffer)); + +TRACE_EVENT(binder_update_page_range, + TP_PROTO(struct binder_proc *proc, bool allocate, + void *start, void *end), + TP_ARGS(proc, allocate, start, end), + TP_STRUCT__entry( + __field(int, proc) + __field(bool, allocate) + __field(size_t, offset) + __field(size_t, size) + ), + TP_fast_assign( + __entry->proc = proc->pid; + __entry->allocate = allocate; + __entry->offset = start - proc->buffer; + __entry->size = end - start; + ), + TP_printk("proc=%d allocate=%d offset=%zu size=%zu", + __entry->proc, __entry->allocate, + __entry->offset, __entry->size) +); + +TRACE_EVENT(binder_command, + TP_PROTO(uint32_t cmd), + TP_ARGS(cmd), + TP_STRUCT__entry( + __field(uint32_t, cmd) + ), + TP_fast_assign( + __entry->cmd = cmd; + ), + TP_printk("cmd=0x%x %s", + __entry->cmd, + _IOC_NR(__entry->cmd) < ARRAY_SIZE(binder_command_strings) ? + binder_command_strings[_IOC_NR(__entry->cmd)] : + "unknown") +); + +TRACE_EVENT(binder_return, + TP_PROTO(uint32_t cmd), + TP_ARGS(cmd), + TP_STRUCT__entry( + __field(uint32_t, cmd) + ), + TP_fast_assign( + __entry->cmd = cmd; + ), + TP_printk("cmd=0x%x %s", + __entry->cmd, + _IOC_NR(__entry->cmd) < ARRAY_SIZE(binder_return_strings) ? + binder_return_strings[_IOC_NR(__entry->cmd)] : + "unknown") +); + +#endif /* _BINDER_TRACE_H */ + +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE binder_trace +#include -- cgit v1.2.3 From ab1dd9963137a1e122004d5378a581bf16ae9bc8 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 7 Oct 2012 08:27:00 +0100 Subject: staging: vt6656: [BUG] out of bound array reference in RFbSetPower. Calling RFbSetPower with uCH zero value will cause out of bound array reference. This causes 64 bit kernels to oops on boot. Note: Driver does not function on 64 bit kernels and should be blacklisted on them. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/rf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/vt6656/rf.c b/drivers/staging/vt6656/rf.c index 593cdc713b0..74c0598e37b 100644 --- a/drivers/staging/vt6656/rf.c +++ b/drivers/staging/vt6656/rf.c @@ -769,6 +769,9 @@ BYTE byPwr = pDevice->byCCKPwr; return TRUE; } + if (uCH == 0) + return -EINVAL; + switch (uRATE) { case RATE_1M: case RATE_2M: -- cgit v1.2.3 From f20fbdf829c11c3c29ee94c0c10ec6195ac4c362 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 7 Oct 2012 11:41:31 +0100 Subject: staging: vt6656: Keep firmware loading local and release firware. Firmware is retained unreleased for the entire duration of the driver. When done release firmware and if the need be request firmware again. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/device.h | 1 - drivers/staging/vt6656/firmware.c | 22 ++++++++++------------ drivers/staging/vt6656/main_usb.c | 1 - 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index 6370d103910..8d9b9c1a2d5 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -418,7 +418,6 @@ typedef struct __device_info { struct net_device* dev; struct net_device_stats stats; - const struct firmware *firmware; OPTIONS sOpts; diff --git a/drivers/staging/vt6656/firmware.c b/drivers/staging/vt6656/firmware.c index 8c8126a3540..8831ea03c00 100644 --- a/drivers/staging/vt6656/firmware.c +++ b/drivers/staging/vt6656/firmware.c @@ -61,28 +61,24 @@ FIRMWAREbDownload( PSDevice pDevice ) { + struct device *dev = &pDevice->usb->dev; const struct firmware *fw; int NdisStatus; void *pBuffer = NULL; BOOL result = FALSE; u16 wLength; - int ii; + int ii, rc; + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Download firmware\n"); spin_unlock_irq(&pDevice->lock); - if (!pDevice->firmware) { - struct device *dev = &pDevice->usb->dev; - int rc; - - rc = request_firmware(&pDevice->firmware, FIRMWARE_NAME, dev); - if (rc) { - dev_err(dev, "firmware file %s request failed (%d)\n", - FIRMWARE_NAME, rc); + rc = request_firmware(&fw, FIRMWARE_NAME, dev); + if (rc) { + dev_err(dev, "firmware file %s request failed (%d)\n", + FIRMWARE_NAME, rc); goto out; - } } - fw = pDevice->firmware; pBuffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); if (!pBuffer) @@ -103,10 +99,12 @@ FIRMWAREbDownload( DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Download firmware...%d %zu\n", ii, fw->size); if (NdisStatus != STATUS_SUCCESS) - goto out; + goto free_fw; } result = TRUE; +free_fw: + release_firmware(fw); out: kfree(pBuffer); diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index ad422dea702..d402df9161e 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1219,7 +1219,6 @@ static void __devexit vt6656_disconnect(struct usb_interface *intf) } device_release_WPADEV(device); - release_firmware(device->firmware); usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf)); -- cgit v1.2.3 From ff4573a7afc53ccf6c66622b884d60208d04db2b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 11 Oct 2012 09:54:05 +0300 Subject: Staging: vt6655-6: shift wrap buf in s_vFillTxKey() byKeyIndex is an unsigned char between 0 and 0xf. If it is any value higher than 1, then we will hit an integer wrap issue here. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rxtx.c | 2 +- drivers/staging/vt6656/rxtx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 4972e57845c..875ee444238 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -242,7 +242,7 @@ s_vFillTxKey ( } // Append IV after Mac Header *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111 - *pdwIV |= (byKeyIndex << 30); + *pdwIV |= (unsigned long)byKeyIndex << 30; *pdwIV = cpu_to_le32(*pdwIV); pDevice->dwIVCounter++; if (pDevice->dwIVCounter > WEP_IV_MASK) { diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 33908387988..a54c0c1de2e 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -355,7 +355,7 @@ s_vFillTxKey ( } // Append IV after Mac Header *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111 - *pdwIV |= (pDevice->byKeyIndex << 30); + *pdwIV |= (unsigned long)pDevice->byKeyIndex << 30; *pdwIV = cpu_to_le32(*pdwIV); pDevice->dwIVCounter++; if (pDevice->dwIVCounter > WEP_IV_MASK) { -- cgit v1.2.3 From c25015c1184e7e54c02e0dfd5044eec38dec482c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 11 Oct 2012 09:55:25 +0300 Subject: Staging: vt6655-6: shift wrap in hostap_set_encryption() abySeq is an unsigned char so shifting more than 31 bits will lead to a shift wrapping bug. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/hostap.c | 6 +++--- drivers/staging/vt6656/hostap.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c index 67b1b88b1b8..5f13890cf12 100644 --- a/drivers/staging/vt6655/hostap.c +++ b/drivers/staging/vt6655/hostap.c @@ -596,9 +596,9 @@ static int hostap_set_encryption(PSDevice pDevice, if (param->u.crypt.seq) { memcpy(&abySeq, param->u.crypt.seq, 8); - for (ii = 0 ; ii < 8 ; ii++) { - KeyRSC |= (abySeq[ii] << (ii * 8)); - } + for (ii = 0 ; ii < 8 ; ii++) + KeyRSC |= (unsigned long)abySeq[ii] << (ii * 8); + dwKeyIndex |= 1 << 29; pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC; } diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index 0a73d4060ee..26a7d0e4b04 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -542,9 +542,9 @@ static int hostap_set_encryption(PSDevice pDevice, if (param->u.crypt.seq) { memcpy(&abySeq, param->u.crypt.seq, 8); - for (ii = 0 ; ii < 8 ; ii++) { - KeyRSC |= (abySeq[ii] << (ii * 8)); - } + for (ii = 0 ; ii < 8 ; ii++) + KeyRSC |= (unsigned long)abySeq[ii] << (ii * 8); + dwKeyIndex |= 1 << 29; pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC; } -- cgit v1.2.3 From 02560efe697e58cde85e7c8002dab8b0ff57bb2e Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Fri, 12 Oct 2012 09:49:15 +0100 Subject: staging: vt6656: [BUG] PIPEnsSendBulkOut free bBoolInUse Eventually, when there is enough errors we run out of free TX urbs and connection stalls. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/usbpipe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index 609e8fa10b9..b5259db6e36 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -660,6 +660,7 @@ PIPEnsSendBulkOut( if (status != 0) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Submit Tx URB failed %d\n", status); + pContext->bBoolInUse = FALSE; return STATUS_FAILURE; } return STATUS_PENDING; -- cgit v1.2.3 From 96a031a2dac72a54cbbd5edca7de4cd5b5ea1d44 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 22 Oct 2012 13:07:35 +0800 Subject: Staging: vt6655: fix missing unlock on error in vCommandTimer() Add the missing unlock on the error handle path in function vCommandTimer. Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wcmd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index 94bd1fc42c9..6d0b87a1426 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -412,6 +412,7 @@ vCommandTimer ( if (!is_channel_valid(pMgmt->uScanChannel)) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d \n",pMgmt->uScanChannel); s_bCommandComplete(pDevice); + spin_unlock_irq(&pDevice->lock); return; } //printk("chester-pMgmt->uScanChannel=%d,pDevice->byMaxChannel=%d\n",pMgmt->uScanChannel,pDevice->byMaxChannel); -- cgit v1.2.3 From ff549e4772c8bcb787077fbf67006bff5961f149 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Mon, 22 Oct 2012 11:49:06 -0400 Subject: staging: ced1401: remove an obvious commit about the minor number in disconnect we assign the device minor number from the interface pointer to the localvarible minor, and then print it at the end, this code seems self explanatory so remove the comment of assigning the minor number to a local variable. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ced1401/usb1401.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c index 6ba0ef65256..6000861d20a 100644 --- a/drivers/staging/ced1401/usb1401.c +++ b/drivers/staging/ced1401/usb1401.c @@ -1537,7 +1537,7 @@ error: static void ced_disconnect(struct usb_interface *interface) { DEVICE_EXTENSION *pdx = usb_get_intfdata(interface); - int minor = interface->minor; // save for message at the end + int minor = interface->minor; int i; usb_set_intfdata(interface, NULL); // remove the pdx from the interface -- cgit v1.2.3 From 0965be39641589a66fd0ea5745d11a11ed0d3335 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Mon, 22 Oct 2012 11:49:28 -0400 Subject: staging: ced1401: fix some style warnings this fixes: comments to in kernel comment style the opening brace of if statement must be beside the if not below to it Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ced1401/usb1401.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c index 6000861d20a..226b893c312 100644 --- a/drivers/staging/ced1401/usb1401.c +++ b/drivers/staging/ced1401/usb1401.c @@ -1572,8 +1572,7 @@ void ced_draw_down(DEVICE_EXTENSION * pdx) pdx->bInDrawDown = true; time = usb_wait_anchor_empty_timeout(&pdx->submitted, 3000); - if (!time) // if we timed out we kill the urbs - { + if (!time) { // if we timed out we kill the urbs usb_kill_anchored_urbs(&pdx->submitted); dev_err(&pdx->interface->dev, "%s timed out", __func__); } -- cgit v1.2.3 From 7d82c65f04b00093088002a1d8c147006c98f960 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Mon, 22 Oct 2012 11:49:47 -0400 Subject: staging: ced1401: remove kernel version ifdef 's We dont need these kernel versioning checks anyways. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ced1401/usb1401.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c index 226b893c312..88e2cc0e2a2 100644 --- a/drivers/staging/ced1401/usb1401.c +++ b/drivers/staging/ced1401/usb1401.c @@ -90,13 +90,11 @@ synchronous non-Urb based transfers. #include #include #include -#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) ) #include #include #include #include #include -#endif #include "usb1401.h" @@ -123,19 +121,6 @@ MODULE_DEVICE_TABLE(usb, ced_table); #define WRITES_IN_FLIGHT 8 /* arbitrarily chosen */ -/* -The cause for these errors is that the driver makes use of the functions usb_buffer_alloc() and usb_buffer_free() which got renamed in kernel 2.6.35. This is stated in the Changelog: USB: rename usb_buffer_alloc() and usb_buffer_free() users - For more clearance what the functions actually do, - usb_buffer_alloc() is renamed to usb_alloc_coherent() - usb_buffer_free() is renamed to usb_free_coherent() - This is needed on Debian 2.6.32-5-amd64 -*/ -#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ) -#define usb_alloc_coherent usb_buffer_alloc -#define usb_free_coherent usb_buffer_free -#define noop_llseek NULL -#endif - static struct usb_driver ced_driver; static void ced_delete(struct kref *kref) @@ -1252,12 +1237,7 @@ int Allowi(DEVICE_EXTENSION * pdx, bool bInCallback) ** ulArg The argument passed in. Note that long is 64-bits in 64-bit system, i.e. it is big ** enough for a 64-bit pointer. *****************************************************************************/ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) static long ced_ioctl(struct file *file, unsigned int cmd, unsigned long ulArg) -#else -static int ced_ioctl(struct inode *node, struct file *file, unsigned int cmd, - unsigned long ulArg) -#endif { int err = 0; DEVICE_EXTENSION *pdx = file->private_data; @@ -1388,11 +1368,7 @@ static const struct file_operations ced_fops = { .release = ced_release, .flush = ced_flush, .llseek = noop_llseek, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) .unlocked_ioctl = ced_ioctl, -#else - .ioctl = ced_ioctl, -#endif }; /* -- cgit v1.2.3 From a5e0f69c983a142daa95b70f709a3dabf76cb55f Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 22 Oct 2012 13:22:15 +0800 Subject: Staging: ced1401: fix missing unlock on error in FreeCircBlock() Add the missing unlock on the error handle path in function FreeCircBlock(). Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ced1401/ced_ioc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c index c9492edaadd..5813aee6b34 100644 --- a/drivers/staging/ced1401/ced_ioc.c +++ b/drivers/staging/ced1401/ced_ioc.c @@ -1508,7 +1508,7 @@ int FreeCircBlock(DEVICE_EXTENSION * pdx, TCIRCBLOCK __user * pCB) iReturn = U14ERR_BADAREA; if (copy_to_user(pCB, &cb, sizeof(cb))) - return -EFAULT; + iReturn = -EFAULT; mutex_unlock(&pdx->io_mutex); return iReturn; -- cgit v1.2.3 From 605fba82a2d6f8e19b7530805b792487562429a7 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 8 Oct 2012 08:43:45 +0800 Subject: staging: r8712u: fix potential NULL pointer dereference in r871x_wps_start() The dereference should be moved below the NULL test. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Acked-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index c9a6a7fbb89..3a647906451 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -2110,10 +2110,10 @@ static int r871x_wps_start(struct net_device *dev, struct iw_point *pdata = &wrqu->data; u32 u32wps_start = 0; - if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4)) - return -EFAULT; if ((padapter->bDriverStopped) || (pdata == NULL)) return -EINVAL; + if (copy_from_user((void *)&u32wps_start, pdata->pointer, 4)) + return -EFAULT; if (u32wps_start == 0) u32wps_start = *extra; if (u32wps_start == 1) /* WPS Start */ -- cgit v1.2.3 From a297ad936ebd6d22b59bbed7d77caa6ff045caa6 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Mon, 15 Oct 2012 13:29:18 -0400 Subject: staging: crystalhd: fix a style warning we dont need braces around a single statement blocks style WARNINGS: drivers/staging/crystalhd/crystalhd_cmds.c:311: WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/crystalhd_cmds.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/crystalhd/crystalhd_cmds.c b/drivers/staging/crystalhd/crystalhd_cmds.c index 05fe78748df..8b71131732d 100644 --- a/drivers/staging/crystalhd/crystalhd_cmds.c +++ b/drivers/staging/crystalhd/crystalhd_cmds.c @@ -308,9 +308,9 @@ static enum BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx, sts = crystalhd_download_fw(ctx->adp, (uint8_t *)idata->add_cdata, idata->add_cdata_sz); - if (sts != BC_STS_SUCCESS) { + if (sts != BC_STS_SUCCESS) BCMLOG_ERR("Firmware Download Failure!! - %d\n", sts); - } else + else ctx->state |= BC_LINK_INIT; return sts; -- cgit v1.2.3 From 36ac9b055fa49b9a0097ec8dfd59c5ffc812a60d Mon Sep 17 00:00:00 2001 From: Bart Westgeest Date: Wed, 10 Oct 2012 13:34:25 -0400 Subject: staging: usbip: replaced pointer arithmetic, and strongly type function return. Replaced pointer arithmetic by using array indexing, and changed function return type for usbip_alloc_iso_desc_pdu from 'void*' to 'struct usbip_iso_packet_descriptor'. Signed-off-by: Bart Westgeest Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/stub_tx.c | 2 +- drivers/staging/usbip/usbip_common.c | 23 ++++++++++------------- drivers/staging/usbip/usbip_common.h | 4 +++- drivers/staging/usbip/vhci_tx.c | 2 +- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c index 023fda305be..1c37b5d888b 100644 --- a/drivers/staging/usbip/stub_tx.c +++ b/drivers/staging/usbip/stub_tx.c @@ -166,7 +166,7 @@ static int stub_send_ret_submit(struct stub_device *sdev) int ret; struct urb *urb = priv->urb; struct usbip_header pdu_header; - void *iso_buffer = NULL; + struct usbip_iso_packet_descriptor *iso_buffer = NULL; struct kvec *iov = NULL; int iovnum = 0; diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index 57f11f9cd8a..ec7a8853d07 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -639,28 +639,26 @@ static void usbip_pack_iso(struct usbip_iso_packet_descriptor *iso, } /* must free buffer */ -void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen) +struct usbip_iso_packet_descriptor* +usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen) { - void *buff; struct usbip_iso_packet_descriptor *iso; int np = urb->number_of_packets; ssize_t size = np * sizeof(*iso); int i; - buff = kzalloc(size, GFP_KERNEL); - if (!buff) + iso = kzalloc(size, GFP_KERNEL); + if (!iso) return NULL; for (i = 0; i < np; i++) { - iso = buff + (i * sizeof(*iso)); - - usbip_pack_iso(iso, &urb->iso_frame_desc[i], 1); - usbip_iso_packet_correct_endian(iso, 1); + usbip_pack_iso(&iso[i], &urb->iso_frame_desc[i], 1); + usbip_iso_packet_correct_endian(&iso[i], 1); } *bufflen = size; - return buff; + return iso; } EXPORT_SYMBOL_GPL(usbip_alloc_iso_desc_pdu); @@ -703,11 +701,10 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) return -EPIPE; } + iso = (struct usbip_iso_packet_descriptor *) buff; for (i = 0; i < np; i++) { - iso = buff + (i * sizeof(*iso)); - - usbip_iso_packet_correct_endian(iso, 0); - usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0); + usbip_iso_packet_correct_endian(&iso[i], 0); + usbip_pack_iso(&iso[i], &urb->iso_frame_desc[i], 0); total_length += urb->iso_frame_desc[i].actual_length; } diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h index 5d89c0fd6f7..7e6c5436d97 100644 --- a/drivers/staging/usbip/usbip_common.h +++ b/drivers/staging/usbip/usbip_common.h @@ -320,7 +320,9 @@ void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, int pack); void usbip_header_correct_endian(struct usbip_header *pdu, int send); -void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen); +struct usbip_iso_packet_descriptor* +usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen); + /* some members of urb must be substituted before. */ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb); void usbip_pad_iso(struct usbip_device *ud, struct urb *urb); diff --git a/drivers/staging/usbip/vhci_tx.c b/drivers/staging/usbip/vhci_tx.c index 9b437e7ef1a..b1f0dcd68f5 100644 --- a/drivers/staging/usbip/vhci_tx.c +++ b/drivers/staging/usbip/vhci_tx.c @@ -76,7 +76,7 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev) int ret; struct urb *urb = priv->urb; struct usbip_header pdu_header; - void *iso_buffer = NULL; + struct usbip_iso_packet_descriptor *iso_buffer = NULL; txsize = 0; memset(&pdu_header, 0, sizeof(pdu_header)); -- cgit v1.2.3 From 20960faca5a0b3acb05a619bd5bfa6dd9bee111a Mon Sep 17 00:00:00 2001 From: Bart Westgeest Date: Wed, 10 Oct 2012 13:34:26 -0400 Subject: staging: usbip: make rh_port_disconnect static Signed-off-by: Bart Westgeest Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci.h | 1 - drivers/staging/usbip/vhci_hcd.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/usbip/vhci.h b/drivers/staging/usbip/vhci.h index c66b8b3f97b..5dddc4d4b6a 100644 --- a/drivers/staging/usbip/vhci.h +++ b/drivers/staging/usbip/vhci.h @@ -99,7 +99,6 @@ extern const struct attribute_group dev_attr_group; /* vhci_hcd.c */ void rh_port_connect(int rhport, enum usb_device_speed speed); -void rh_port_disconnect(int rhport); /* vhci_rx.c */ struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum); diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 620d1beb458..f6ba22d0950 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -149,7 +149,7 @@ void rh_port_connect(int rhport, enum usb_device_speed speed) usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); } -void rh_port_disconnect(int rhport) +static void rh_port_disconnect(int rhport) { unsigned long flags; -- cgit v1.2.3 From c7f0089931dfaefba81001c88449250867582ba6 Mon Sep 17 00:00:00 2001 From: Bart Westgeest Date: Wed, 10 Oct 2012 13:34:27 -0400 Subject: staging: usbip: cleanup of comments Removed commented-out code, obsolete comments, and fixed comment typos. Signed-off-by: Bart Westgeest Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/stub_dev.c | 10 ++++------ drivers/staging/usbip/stub_rx.c | 5 ++--- drivers/staging/usbip/stub_tx.c | 1 - drivers/staging/usbip/usbip_common.c | 13 +------------ drivers/staging/usbip/vhci_hcd.c | 36 ++++-------------------------------- drivers/staging/usbip/vhci_rx.c | 2 +- 6 files changed, 12 insertions(+), 55 deletions(-) diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c index c8d79a7f0e0..1e1eb4c14d7 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@ -477,19 +477,17 @@ static void stub_disconnect(struct usb_interface *interface) /* get stub_device */ if (!sdev) { dev_err(&interface->dev, "could not get device"); - /* BUG(); */ return; } usb_set_intfdata(interface, NULL); /* - * NOTE: - * rx/tx threads are invoked for each usb_device. + * NOTE: rx/tx threads are invoked for each usb_device. */ stub_remove_files(&interface->dev); - /*If usb reset called from event handler*/ + /* If usb reset is called from event handler */ if (busid_priv->sdev->ud.eh == current) { busid_priv->interf_count--; return; @@ -504,13 +502,13 @@ static void stub_disconnect(struct usb_interface *interface) busid_priv->interf_count = 0; - /* 1. shutdown the current connection */ + /* shutdown the current connection */ shutdown_busid(busid_priv); usb_put_dev(sdev->udev); usb_put_intf(interface); - /* 3. free sdev */ + /* free sdev */ busid_priv->sdev = NULL; stub_device_free(sdev); diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c index 694cfd7596f..0572a15242b 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -164,7 +164,6 @@ static int tweak_set_configuration_cmd(struct urb *urb) config, dev_name(&urb->dev->dev)); return 0; - /* return usb_driver_set_configuration(urb->dev, config); */ } static int tweak_reset_device_cmd(struct urb *urb) @@ -480,7 +479,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, return; } - /* set priv->urb->transfer_buffer */ + /* allocate urb transfer buffer, if needed */ if (pdu->u.cmd_submit.transfer_buffer_length > 0) { priv->urb->transfer_buffer = kzalloc(pdu->u.cmd_submit.transfer_buffer_length, @@ -492,7 +491,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, } } - /* set priv->urb->setup_packet */ + /* copy urb setup packet */ priv->urb->setup_packet = kmemdup(&pdu->u.cmd_submit.setup, 8, GFP_KERNEL); if (!priv->urb->setup_packet) { diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c index 1c37b5d888b..513961fef05 100644 --- a/drivers/staging/usbip/stub_tx.c +++ b/drivers/staging/usbip/stub_tx.c @@ -192,7 +192,6 @@ static int stub_send_ret_submit(struct stub_device *sdev) setup_ret_submit_pdu(&pdu_header, urb); usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n", pdu_header.base.seqnum, urb); - /*usbip_dump_header(pdu_header);*/ usbip_header_correct_endian(&pdu_header, 1); iov[iovnum].iov_base = &pdu_header; diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index ec7a8853d07..4a10034ff2c 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -439,7 +439,6 @@ static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb, * will be discussed when usbip is ported to other operating systems. */ if (pack) { - /* vhci_tx.c */ spdu->transfer_flags = tweak_transfer_flags(urb->transfer_flags); spdu->transfer_buffer_length = urb->transfer_buffer_length; @@ -447,9 +446,7 @@ static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb, spdu->number_of_packets = urb->number_of_packets; spdu->interval = urb->interval; } else { - /* stub_rx.c */ urb->transfer_flags = spdu->transfer_flags; - urb->transfer_buffer_length = spdu->transfer_buffer_length; urb->start_frame = spdu->start_frame; urb->number_of_packets = spdu->number_of_packets; @@ -463,16 +460,12 @@ static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb, struct usbip_header_ret_submit *rpdu = &pdu->u.ret_submit; if (pack) { - /* stub_tx.c */ - rpdu->status = urb->status; rpdu->actual_length = urb->actual_length; rpdu->start_frame = urb->start_frame; rpdu->number_of_packets = urb->number_of_packets; rpdu->error_count = urb->error_count; } else { - /* vhci_rx.c */ - urb->status = rpdu->status; urb->actual_length = rpdu->actual_length; urb->start_frame = rpdu->start_frame; @@ -678,8 +671,6 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) /* my Bluetooth dongle gets ISO URBs which are np = 0 */ if (np == 0) { - /* pr_info("iso np == 0\n"); */ - /* usbip_dump_urb(urb); */ return 0; } @@ -751,7 +742,7 @@ void usbip_pad_iso(struct usbip_device *ud, struct urb *urb) /* * if actual_length is transfer_buffer_length then no padding is * present. - */ + */ if (urb->actual_length == urb->transfer_buffer_length) return; @@ -775,14 +766,12 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb) int size; if (ud->side == USBIP_STUB) { - /* stub_rx.c */ /* the direction of urb must be OUT. */ if (usb_pipein(urb->pipe)) return 0; size = urb->transfer_buffer_length; } else { - /* vhci_rx.c */ /* the direction of urb must be IN. */ if (usb_pipeout(urb->pipe)) return 0; diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index f6ba22d0950..a6143781e2a 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -140,10 +140,6 @@ void rh_port_connect(int rhport, enum usb_device_speed speed) break; } - /* spin_lock(&the_controller->vdev[rhport].ud.lock); - * the_controller->vdev[rhport].ud.status = VDEV_CONNECT; - * spin_unlock(&the_controller->vdev[rhport].ud.lock); */ - spin_unlock_irqrestore(&the_controller->lock, flags); usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); @@ -156,16 +152,11 @@ static void rh_port_disconnect(int rhport) usbip_dbg_vhci_rh("rh_port_disconnect %d\n", rhport); spin_lock_irqsave(&the_controller->lock, flags); - /* stop_activity(dum, driver); */ + the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION; the_controller->port_status[rhport] |= (1 << USB_PORT_FEAT_C_CONNECTION); - /* not yet complete the disconnection - * spin_lock(&vdev->ud.lock); - * vdev->ud.status = VHC_ST_DISCONNECT; - * spin_unlock(&vdev->ud.lock); */ - spin_unlock_irqrestore(&the_controller->lock, flags); usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); } @@ -228,7 +219,6 @@ done: return changed ? retval : 0; } -/* See hub_configure in hub.c */ static inline void hub_descriptor(struct usb_hub_descriptor *desc) { memset(desc, 0, sizeof(*desc)); @@ -292,8 +282,6 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, usbip_dbg_vhci_rh(" ClearPortFeature: " "USB_PORT_FEAT_POWER\n"); dum->port_status[rhport] = 0; - /* dum->address = 0; */ - /* dum->hdev = 0; */ dum->resuming = 0; break; case USB_PORT_FEAT_C_RESET: @@ -333,11 +321,11 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, retval = -EPIPE; } - /* we do no care of resume. */ + /* we do not care about resume. */ /* whoever resets or resumes must GetPortStatus to * complete it!! - * */ + */ if (dum->resuming && time_after(jiffies, dum->re_timeout)) { dum->port_status[rhport] |= (1 << USB_PORT_FEAT_C_SUSPEND); @@ -345,11 +333,6 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ~(1 << USB_PORT_FEAT_SUSPEND); dum->resuming = 0; dum->re_timeout = 0; - /* if (dum->driver && dum->driver->resume) { - * spin_unlock (&dum->lock); - * dum->driver->resume (&dum->gadget); - * spin_lock (&dum->lock); - * } */ } if ((dum->port_status[rhport] & (1 << USB_PORT_FEAT_RESET)) != @@ -411,9 +394,6 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, default: pr_err("default: no such request\n"); - /* dev_dbg (hardware, - * "hub control req%04x v%04x i%04x l%d\n", - * typeReq, wValue, wIndex, wLength); */ /* "protocol stall" on error */ retval = -EPIPE; @@ -456,7 +436,6 @@ static void vhci_tx_urb(struct urb *urb) if (!vdev) { pr_err("could not get virtual device"); - /* BUG(); */ return; } @@ -813,7 +792,7 @@ static void vhci_shutdown_connection(struct usbip_device *ud) kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); } - /* kill threads related to this sdev, if v.c. exists */ + /* kill threads related to this sdev */ if (vdev->ud.tcp_rx) { kthread_stop_put(vdev->ud.tcp_rx); vdev->ud.tcp_rx = NULL; @@ -976,8 +955,6 @@ static int vhci_bus_suspend(struct usb_hcd *hcd) dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); spin_lock_irq(&vhci->lock); - /* vhci->rh_state = DUMMY_RH_SUSPENDED; - * set_link_state(vhci); */ hcd->state = HC_STATE_SUSPENDED; spin_unlock_irq(&vhci->lock); @@ -995,10 +972,6 @@ static int vhci_bus_resume(struct usb_hcd *hcd) if (!HCD_HW_ACCESSIBLE(hcd)) { rc = -ESHUTDOWN; } else { - /* vhci->rh_state = DUMMY_RH_RUNNING; - * set_link_state(vhci); - * if (!list_empty(&vhci->urbp_list)) - * mod_timer(&vhci->timer, jiffies); */ hcd->state = HC_STATE_RUNNING; } spin_unlock_irq(&vhci->lock); @@ -1175,7 +1148,6 @@ static struct platform_device the_pdev = { .name = (char *) driver_name, .id = -1, .dev = { - /* .driver = &vhci_driver, */ .release = the_pdev_release, }, }; diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c index f0eaf04fa25..ba5f1c079b6 100644 --- a/drivers/staging/usbip/vhci_rx.c +++ b/drivers/staging/usbip/vhci_rx.c @@ -167,7 +167,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, } else { usbip_dbg_vhci_rx("now giveback urb %p\n", urb); - /* If unlink is succeed, status is -ECONNRESET */ + /* If unlink is successful, status is -ECONNRESET */ urb->status = pdu->u.ret_unlink.status; pr_info("urb->status %d\n", urb->status); -- cgit v1.2.3 From 3d0a2a22c91e58bfe933115d63cdce60ad2b3a11 Mon Sep 17 00:00:00 2001 From: Bernard Blackham Date: Mon, 22 Oct 2012 06:45:00 +1100 Subject: staging: usbip: Don't leak struct file. usbip takes a reference on a struct file which is passed in via sysfs. Previously, this reference was never cleaned up, although the socket it referred to was. This patch drops the corresponding reference (found with the socket's ->file backpointer) instead of just closing the socket. Signed-off-by: Bernard Blackham Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/stub_dev.c | 3 ++- drivers/staging/usbip/usbip_common.c | 4 +++- drivers/staging/usbip/vhci_hcd.c | 10 +++++++--- drivers/staging/usbip/vhci_sysfs.c | 6 +++++- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c index 1e1eb4c14d7..79298d06863 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@ -18,6 +18,7 @@ */ #include +#include #include #include @@ -203,7 +204,7 @@ static void stub_shutdown_connection(struct usbip_device *ud) * not touch NULL socket. */ if (ud->tcp_socket) { - sock_release(ud->tcp_socket); + fput(ud->tcp_socket->file); ud->tcp_socket = NULL; } diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index 4a10034ff2c..75189feac38 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -413,8 +413,10 @@ struct socket *sockfd_to_socket(unsigned int sockfd) inode = file->f_dentry->d_inode; - if (!inode || !S_ISSOCK(inode->i_mode)) + if (!inode || !S_ISSOCK(inode->i_mode)) { + fput(file); return NULL; + } socket = SOCKET_I(inode); diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index a6143781e2a..77d77f72cb1 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -804,8 +805,8 @@ static void vhci_shutdown_connection(struct usbip_device *ud) pr_info("stop threads\n"); /* active connection is closed */ - if (vdev->ud.tcp_socket != NULL) { - sock_release(vdev->ud.tcp_socket); + if (vdev->ud.tcp_socket) { + fput(vdev->ud.tcp_socket->file); vdev->ud.tcp_socket = NULL; } pr_info("release socket\n"); @@ -851,7 +852,10 @@ static void vhci_device_reset(struct usbip_device *ud) usb_put_dev(vdev->udev); vdev->udev = NULL; - ud->tcp_socket = NULL; + if (ud->tcp_socket) { + fput(ud->tcp_socket->file); + ud->tcp_socket = NULL; + } ud->status = VDEV_ST_NULL; spin_unlock(&ud->lock); diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c index 7ce9c2f7e44..c66e9c05c76 100644 --- a/drivers/staging/usbip/vhci_sysfs.c +++ b/drivers/staging/usbip/vhci_sysfs.c @@ -18,6 +18,7 @@ */ #include +#include #include #include "usbip_common.h" @@ -189,7 +190,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, if (valid_args(rhport, speed) < 0) return -EINVAL; - /* check sockfd */ + /* Extract socket from fd. */ + /* The correct way to clean this up is to fput(socket->file). */ socket = sockfd_to_socket(sockfd); if (!socket) return -EINVAL; @@ -206,6 +208,8 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, spin_unlock(&vdev->ud.lock); spin_unlock(&the_controller->lock); + fput(socket->file); + dev_err(dev, "port %d already used\n", rhport); return -EINVAL; } -- cgit v1.2.3 From 9e1b6cb9dc0a149e270dc62c095c6e9c01a99c44 Mon Sep 17 00:00:00 2001 From: Bernard Blackham Date: Mon, 22 Oct 2012 06:45:26 +1100 Subject: staging: usbip: Avoid superfluous set HC_STATE_RUNNING in vhci_start HC_STATE_RUNNING is already set by the usb core. Signed-off-by: Bernard Blackham Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci_hcd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 77d77f72cb1..7dc8bbaee18 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -911,7 +911,6 @@ static int vhci_start(struct usb_hcd *hcd) spin_lock_init(&vhci->lock); hcd->power_budget = 0; /* no limit */ - hcd->state = HC_STATE_RUNNING; hcd->uses_new_polling = 1; /* vhci_hcd is now ready to be controlled through sysfs */ -- cgit v1.2.3 From 1055d6279056ba782ce441e2d8024f80ef592ed0 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 8 Oct 2012 22:15:44 +0800 Subject: staging: ste_rmi4: use module_i2c_driver to simplify the code Use the module_i2c_driver() macro to make the code smaller and a bit simpler. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Acked-by: Linus Walleij Acked-by: Henrik Rydberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c index 277491a877e..37d19c696ea 100644 --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c @@ -1143,30 +1143,8 @@ static struct i2c_driver synaptics_rmi4_driver = { .remove = __devexit_p(synaptics_rmi4_remove), .id_table = synaptics_rmi4_id_table, }; -/** - * synaptics_rmi4_init() - Initialize the touchscreen driver - * - * This function uses to initializes the synaptics - * touchscreen driver and returns integer. - */ -static int __init synaptics_rmi4_init(void) -{ - return i2c_add_driver(&synaptics_rmi4_driver); -} -/** - * synaptics_rmi4_exit() - De-initialize the touchscreen driver - * - * This function uses to de-initialize the synaptics - * touchscreen driver and returns none. - */ -static void __exit synaptics_rmi4_exit(void) -{ - i2c_del_driver(&synaptics_rmi4_driver); -} - -module_init(synaptics_rmi4_init); -module_exit(synaptics_rmi4_exit); +module_i2c_driver(synaptics_rmi4_driver); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("naveen.gaddipati@stericsson.com, js.ha@stericsson.com"); -- cgit v1.2.3 From 55dcbbb1bf7eef83bcd3e0ba8de0b359a45804ed Mon Sep 17 00:00:00 2001 From: Minchan Kim Date: Wed, 10 Oct 2012 08:49:52 +0900 Subject: staging: zram: correct obsolete comment on max_zpage_size Zram doesn't use xv_malloc any more so it doesn't have limitation about zobj_header. Signed-off-by: Minchan Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h index 572c0b1551d..df2eec407db 100644 --- a/drivers/staging/zram/zram_drv.h +++ b/drivers/staging/zram/zram_drv.h @@ -39,8 +39,8 @@ static const size_t max_zpage_size = PAGE_SIZE / 4 * 3; /* * NOTE: max_zpage_size must be less than or equal to: - * ZS_MAX_ALLOC_SIZE - sizeof(struct zobj_header) - * otherwise, xv_malloc() would always return failure. + * ZS_MAX_ALLOC_SIZE. Otherwise, zs_malloc() would + * always return failure. */ /*-- End of configurable params */ -- cgit v1.2.3 From 36dab6e5f0d9ccd374740cf71f8cb7ea3029c0ab Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 7 Oct 2012 21:43:26 +0800 Subject: staging: csr: remove unused including Remove including that don't need it. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext.c | 1 - drivers/staging/csr/csr_time.c | 1 - drivers/staging/csr/io.c | 1 - drivers/staging/csr/monitor.c | 1 - drivers/staging/csr/netdev.c | 1 - drivers/staging/csr/sdio_mmc.c | 1 - drivers/staging/csr/sme_native.c | 1 - drivers/staging/csr/sme_sys.c | 1 - drivers/staging/csr/ul_int.c | 1 - drivers/staging/csr/unifi_pdu_processing.c | 1 - drivers/staging/csr/unifi_priv.h | 1 - drivers/staging/csr/unifi_wext.h | 1 - 12 files changed, 12 deletions(-) diff --git a/drivers/staging/csr/csr_framework_ext.c b/drivers/staging/csr/csr_framework_ext.c index f91a4bf4e68..e203f606de3 100644 --- a/drivers/staging/csr/csr_framework_ext.c +++ b/drivers/staging/csr/csr_framework_ext.c @@ -9,7 +9,6 @@ *****************************************************************************/ #include -#include #include #include #include diff --git a/drivers/staging/csr/csr_time.c b/drivers/staging/csr/csr_time.c index 7b597f7622a..f4ff98c71cc 100644 --- a/drivers/staging/csr/csr_time.c +++ b/drivers/staging/csr/csr_time.c @@ -9,7 +9,6 @@ *****************************************************************************/ #include -#include #include #include diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c index caf48e3120c..5206cbafff7 100644 --- a/drivers/staging/csr/io.c +++ b/drivers/staging/csr/io.c @@ -31,7 +31,6 @@ * --------------------------------------------------------------------------- */ #include -#include #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_unifiversion.h" diff --git a/drivers/staging/csr/monitor.c b/drivers/staging/csr/monitor.c index 7c524a18958..7b76f07ff33 100644 --- a/drivers/staging/csr/monitor.c +++ b/drivers/staging/csr/monitor.c @@ -10,7 +10,6 @@ * --------------------------------------------------------------------------- */ -#include #include "unifi_priv.h" #ifdef UNIFI_SNIFF_ARPHRD diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 9a52ab408e1..8a5317159f8 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_conversions.h" diff --git a/drivers/staging/csr/sdio_mmc.c b/drivers/staging/csr/sdio_mmc.c index af3e40bb501..6b96df11baa 100644 --- a/drivers/staging/csr/sdio_mmc.c +++ b/drivers/staging/csr/sdio_mmc.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/csr/sme_native.c b/drivers/staging/csr/sme_native.c index d7a5125d9a8..26f10bcbe03 100644 --- a/drivers/staging/csr/sme_native.c +++ b/drivers/staging/csr/sme_native.c @@ -12,7 +12,6 @@ */ #include -#include #include "unifi_priv.h" #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_conversions.h" diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c index 5b26c41c01f..90a30dc1c00 100644 --- a/drivers/staging/csr/sme_sys.c +++ b/drivers/staging/csr/sme_sys.c @@ -14,7 +14,6 @@ * --------------------------------------------------------------------------- */ -#include #include "csr_wifi_hip_unifiversion.h" #include "unifi_priv.h" #include "csr_wifi_hip_conversions.h" diff --git a/drivers/staging/csr/ul_int.c b/drivers/staging/csr/ul_int.c index 4013d021ebb..0fae6f48f79 100644 --- a/drivers/staging/csr/ul_int.c +++ b/drivers/staging/csr/ul_int.c @@ -12,7 +12,6 @@ * * *************************************************************************** */ -#include #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_conversions.h" #include "unifi_priv.h" diff --git a/drivers/staging/csr/unifi_pdu_processing.c b/drivers/staging/csr/unifi_pdu_processing.c index ae7c8fc9409..a762939a6ac 100644 --- a/drivers/staging/csr/unifi_pdu_processing.c +++ b/drivers/staging/csr/unifi_pdu_processing.c @@ -14,7 +14,6 @@ * --------------------------------------------------------------------------- */ -#include #include #include #include diff --git a/drivers/staging/csr/unifi_priv.h b/drivers/staging/csr/unifi_priv.h index aec8e28fb60..f25b92ab4e2 100644 --- a/drivers/staging/csr/unifi_priv.h +++ b/drivers/staging/csr/unifi_priv.h @@ -17,7 +17,6 @@ #ifndef __LINUX_UNIFI_PRIV_H__ #define __LINUX_UNIFI_PRIV_H__ 1 -#include #include #include #include diff --git a/drivers/staging/csr/unifi_wext.h b/drivers/staging/csr/unifi_wext.h index 6834c43abfb..beba089e2e3 100644 --- a/drivers/staging/csr/unifi_wext.h +++ b/drivers/staging/csr/unifi_wext.h @@ -16,7 +16,6 @@ #define __LINUX_UNIFI_WEXT_H__ 1 #include -#include #include #include "csr_wifi_sme_prim.h" -- cgit v1.2.3 From 60ac2e9f7f76f90ba714b46332459eba397989b6 Mon Sep 17 00:00:00 2001 From: Homin Lee Date: Sun, 14 Oct 2012 10:32:26 +0900 Subject: Staging: csr: csr_log_configure.h: clean up tab mess Signed-off-by: Homin Lee Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_log_configure.h | 100 ++++++++++++++++---------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/drivers/staging/csr/csr_log_configure.h b/drivers/staging/csr/csr_log_configure.h index 8842e4bf461..08fc0807cb7 100644 --- a/drivers/staging/csr/csr_log_configure.h +++ b/drivers/staging/csr/csr_log_configure.h @@ -2,13 +2,13 @@ #define CSR_LOG_CONFIGURE_H__ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2010 - All rights reserved and confidential information of CSR + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR - Refer to LICENSE.txt included with this source for details - on the license terms. + Refer to LICENSE.txt included with this source for details + on the license terms. -*****************************************************************************/ + *****************************************************************************/ #include "csr_log.h" @@ -37,7 +37,7 @@ void CsrLogLevelTaskSetAll(CsrLogLevelTask tasksLogLevelMask); /* Set the logging level for a given Task */ /* This function can be used as a complement to CsrLogLevelTaskSetAll() to add more _or_ less log from a given task than what is set -generally with CsrLogLevelTaskSetAll(). */ + generally with CsrLogLevelTaskSetAll(). */ void CsrLogLevelTaskSetSpecific(CsrSchedQid taskId, CsrLogLevelTask taskLogLevelMask); @@ -81,51 +81,51 @@ void CsrLogLevelTextSetTaskSubOrigin(CsrLogTextTaskId taskId, u16 subOrigin, Csr /******************************************************************************* - NAME - CsrLogLevelTextSet - - DESCRIPTION - Set the text logging level for a given origin and optionally sub origin - by name. If either string is NULL or zero length, it is interpreted as - all origins and/or all sub origins respectively. If originName is NULL - or zero length, subOriginName is ignored. - - Passing NULL or zero length strings in both originName and subOriginName - is equivalent to calling CsrLogLevelTextSetAll, and overrides all - previous filter configurations for all origins and sub origins. - - Passing NULL or a zero length string in subOriginName overrides all - previous filter configurations for all sub origins of the specified - origin. - - Note: the supplied strings may be accessed after the function returns - and must remain valid and constant until CsrLogDeinit is called. - - Note: when specifying an origin (originName is not NULL and not zero - length), this function can only be used for origins that use the - csr_log_text_2.h interface for registration and logging. Filtering for - origins that use the legacy csr_log_text.h interface must be be - configured using the legacy filter configuration functions that accept - a CsrLogTextTaskId as origin specifier. However, when not specifying an - origin this function also affects origins that have been registered with - the legacy csr_log_text.h interface. Furthermore, using this function - and the legacy filter configuration functions on the same origin is not - allowed. - - PARAMETERS - originName - a string containing the name of the origin. Can be NULL or - zero length to set the log level for all origins. In this case, the - subOriginName parameter will be ignored. - subOriginName - a string containing the name of the sub origin. Can be - NULL or zero length to set the log level for all sub origins of the - specified origin. - warningLevelMask - The desired log level for the specified origin(s) and - sub origin(s). - -*******************************************************************************/ + NAME + CsrLogLevelTextSet + + DESCRIPTION + Set the text logging level for a given origin and optionally sub origin + by name. If either string is NULL or zero length, it is interpreted as + all origins and/or all sub origins respectively. If originName is NULL + or zero length, subOriginName is ignored. + + Passing NULL or zero length strings in both originName and subOriginName + is equivalent to calling CsrLogLevelTextSetAll, and overrides all + previous filter configurations for all origins and sub origins. + + Passing NULL or a zero length string in subOriginName overrides all + previous filter configurations for all sub origins of the specified + origin. + +Note: the supplied strings may be accessed after the function returns +and must remain valid and constant until CsrLogDeinit is called. + +Note: when specifying an origin (originName is not NULL and not zero +length), this function can only be used for origins that use the +csr_log_text_2.h interface for registration and logging. Filtering for +origins that use the legacy csr_log_text.h interface must be be +configured using the legacy filter configuration functions that accept +a CsrLogTextTaskId as origin specifier. However, when not specifying an +origin this function also affects origins that have been registered with +the legacy csr_log_text.h interface. Furthermore, using this function +and the legacy filter configuration functions on the same origin is not +allowed. + +PARAMETERS +originName - a string containing the name of the origin. Can be NULL or +zero length to set the log level for all origins. In this case, the +subOriginName parameter will be ignored. +subOriginName - a string containing the name of the sub origin. Can be +NULL or zero length to set the log level for all sub origins of the +specified origin. +warningLevelMask - The desired log level for the specified origin(s) and +sub origin(s). + + *******************************************************************************/ void CsrLogLevelTextSet(const char *originName, - const char *subOriginName, - CsrLogLevelText warningLevelMask); + const char *subOriginName, + CsrLogLevelText warningLevelMask); #ifdef __cplusplus } -- cgit v1.2.3 From 7c5745cc0859b5a628d7c39530a953e3983e6c1c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 12 Oct 2012 14:58:39 +0900 Subject: Staging: csr: data_tx: clean up tab mess This patch converts spaces to tabs. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/data_tx.c | 48 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/staging/csr/data_tx.c b/drivers/staging/csr/data_tx.c index 8ed7a7845cc..d2c29545058 100644 --- a/drivers/staging/csr/data_tx.c +++ b/drivers/staging/csr/data_tx.c @@ -18,33 +18,33 @@ int uf_verify_m4(unifi_priv_t *priv, const unsigned char *packet, unsigned int length) { - const unsigned char *p = packet; - u16 keyinfo; + const unsigned char *p = packet; + u16 keyinfo; - if (length < (4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1 + 8)) { - return 1; - } + if (length < (4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1 + 8)) { + return 1; + } - p += 8; - keyinfo = p[5] << 8 | p[6]; /* big-endian */ - if ( - (p[0] == 1 || p[0] == 2) /* protocol version 802.1X-2001 (WPA) or -2004 (WPA2) */ && - p[1] == 3 /* EAPOL-Key */ && - /* don't bother checking p[2] p[3] (hh ll, packet body length) */ - (p[4] == 254 || p[4] == 2) /* descriptor type P802.1i-D3.0 (WPA) or 802.11i-2004 (WPA2) */ && - ((keyinfo & 0x0007) == 1 || (keyinfo & 0x0007) == 2) /* key descriptor version */ && - (keyinfo & ~0x0207U) == 0x0108 && /* key info for 4/4 or 4/2 -- ignore key desc version and sec bit (since varies in WPA 4/4) */ - (p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 0] == 0 && /* key data length (2 octets) 0 for 4/4 only */ - p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1] == 0) - ) { - unifi_trace(priv, UDBG1, "uf_verify_m4: M4 detected \n"); - return 0; - } - else - { - return 1; - } + p += 8; + keyinfo = p[5] << 8 | p[6]; /* big-endian */ + if ( + (p[0] == 1 || p[0] == 2) /* protocol version 802.1X-2001 (WPA) or -2004 (WPA2) */ && + p[1] == 3 /* EAPOL-Key */ && + /* don't bother checking p[2] p[3] (hh ll, packet body length) */ + (p[4] == 254 || p[4] == 2) /* descriptor type P802.1i-D3.0 (WPA) or 802.11i-2004 (WPA2) */ && + ((keyinfo & 0x0007) == 1 || (keyinfo & 0x0007) == 2) /* key descriptor version */ && + (keyinfo & ~0x0207U) == 0x0108 && /* key info for 4/4 or 4/2 -- ignore key desc version and sec bit (since varies in WPA 4/4) */ + (p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 0] == 0 && /* key data length (2 octets) 0 for 4/4 only */ + p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1] == 0) + ) { + unifi_trace(priv, UDBG1, "uf_verify_m4: M4 detected \n"); + return 0; + } + else + { + return 1; + } } /* -- cgit v1.2.3 From dbff11c9d35ebd41268cf5137e0619509effd461 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 12 Oct 2012 14:58:40 +0900 Subject: Staging: csr: data_tx: fix up brace placement This cleans up the brace placement coding issues. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/data_tx.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/csr/data_tx.c b/drivers/staging/csr/data_tx.c index d2c29545058..878f59f06e2 100644 --- a/drivers/staging/csr/data_tx.c +++ b/drivers/staging/csr/data_tx.c @@ -22,9 +22,8 @@ uf_verify_m4(unifi_priv_t *priv, const unsigned char *packet, unsigned int lengt u16 keyinfo; - if (length < (4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1 + 8)) { + if (length < (4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1 + 8)) return 1; - } p += 8; keyinfo = p[5] << 8 | p[6]; /* big-endian */ @@ -40,9 +39,7 @@ uf_verify_m4(unifi_priv_t *priv, const unsigned char *packet, unsigned int lengt ) { unifi_trace(priv, UDBG1, "uf_verify_m4: M4 detected \n"); return 0; - } - else - { + } else { return 1; } } -- cgit v1.2.3 From 0567e1ec43c60e449673bb391edd05e5e49398be Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 12 Oct 2012 14:58:41 +0900 Subject: Staging: csr: data_tx: remove extra space in printk This saves us 1 byte! Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/data_tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/csr/data_tx.c b/drivers/staging/csr/data_tx.c index 878f59f06e2..9e3d8b8ab02 100644 --- a/drivers/staging/csr/data_tx.c +++ b/drivers/staging/csr/data_tx.c @@ -37,7 +37,7 @@ uf_verify_m4(unifi_priv_t *priv, const unsigned char *packet, unsigned int lengt (p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 0] == 0 && /* key data length (2 octets) 0 for 4/4 only */ p[4 + 5 + 8 + 32 + 16 + 8 + 8 + 16 + 1] == 0) ) { - unifi_trace(priv, UDBG1, "uf_verify_m4: M4 detected \n"); + unifi_trace(priv, UDBG1, "uf_verify_m4: M4 detected\n"); return 0; } else { return 1; -- cgit v1.2.3 From 717757255665a1aae58752f1d8cf7625b6fe9d9e Mon Sep 17 00:00:00 2001 From: Sangho Yi Date: Sun, 14 Oct 2012 23:50:01 +0900 Subject: Staging: CSR: csr_time.h: fixed indentation warnings based on coding style I fixed the indentation warnings on csr_time.h. Signed-off-by: Sangho Yi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_time.h | 63 +++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/drivers/staging/csr/csr_time.h b/drivers/staging/csr/csr_time.h index 2a45f3e4024..7ded6dd474b 100644 --- a/drivers/staging/csr/csr_time.h +++ b/drivers/staging/csr/csr_time.h @@ -2,11 +2,11 @@ #define CSR_TIME_H__ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2010 - All rights reserved and confidential information of CSR +(c) Cambridge Silicon Radio Limited 2010 +All rights reserved and confidential information of CSR - Refer to LICENSE.txt included with this source for details - on the license terms. +Refer to LICENSE.txt included with this source for details +on the license terms. *****************************************************************************/ @@ -18,13 +18,13 @@ extern "C" { /******************************************************************************* - NAME - CsrTime +NAME + CsrTime - DESCRIPTION - Type to hold a value describing the current system time, which is a - measure of time elapsed since some arbitrarily defined fixed time - reference, usually associated with system startup. +DESCRIPTION + Type to hold a value describing the current system time, which is a + measure of time elapsed since some arbitrarily defined fixed time + reference, usually associated with system startup. *******************************************************************************/ typedef u32 CsrTime; @@ -32,12 +32,12 @@ typedef u32 CsrTime; /******************************************************************************* - NAME - CsrTimeUtc +NAME + CsrTimeUtc - DESCRIPTION - Type to hold a value describing a UTC wallclock time expressed in - seconds and milliseconds elapsed since midnight January 1st 1970. +DESCRIPTION + Type to hold a value describing a UTC wallclock time expressed in + seconds and milliseconds elapsed since midnight January 1st 1970. *******************************************************************************/ typedef struct @@ -49,27 +49,28 @@ typedef struct /******************************************************************************* - NAME - CsrTimeGet +NAME + CsrTimeGet - DESCRIPTION - Returns the current system time in a low and a high part. The low part - is expressed in microseconds. The high part is incremented when the low - part wraps to provide an extended range. +DESCRIPTION + Returns the current system time in a low and a high part. The low part + is expressed in microseconds. The high part is incremented when the low + part wraps to provide an extended range. - The caller may provide a NULL pointer as the high parameter. In this case - the function just returns the low part and ignores the high parameter. + The caller may provide a NULL pointer as the high parameter. + In this case the function just returns the low part and ignores the + high parameter. - Although the time is expressed in microseconds the actual resolution is - platform dependent and can be less. It is recommended that the - resolution is at least 10 milliseconds. + Although the time is expressed in microseconds the actual resolution is + platform dependent and can be less. It is recommended that the + resolution is at least 10 milliseconds. - PARAMETERS - high - Pointer to variable that will receive the high part of the - current system time. Passing NULL is valid. +PARAMETERS + high - Pointer to variable that will receive the high part of the + current system time. Passing NULL is valid. - RETURNS - Low part of current system time in microseconds. +RETURNS + Low part of current system time in microseconds. *******************************************************************************/ CsrTime CsrTimeGet(CsrTime *high); -- cgit v1.2.3 From 3f38ea7de4eb36dcb7eb05827d9ffb8a817b6563 Mon Sep 17 00:00:00 2001 From: Sangho Yi Date: Sun, 14 Oct 2012 23:50:02 +0900 Subject: Staging: CSR: csr_time.h: Removed unnecessary typedef struct I removed the unnecessary typedef struct from the csr_time.h. There is no actual usage of the typedef definition. Signed-off-by: Sangho Yi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_time.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/staging/csr/csr_time.h b/drivers/staging/csr/csr_time.h index 7ded6dd474b..d8561541901 100644 --- a/drivers/staging/csr/csr_time.h +++ b/drivers/staging/csr/csr_time.h @@ -29,24 +29,6 @@ DESCRIPTION *******************************************************************************/ typedef u32 CsrTime; - -/******************************************************************************* - -NAME - CsrTimeUtc - -DESCRIPTION - Type to hold a value describing a UTC wallclock time expressed in - seconds and milliseconds elapsed since midnight January 1st 1970. - -*******************************************************************************/ -typedef struct -{ - u32 sec; - u16 msec; -} CsrTimeUtc; - - /******************************************************************************* NAME -- cgit v1.2.3 From cf174b0ef52ad8184779e1da4132e2d9d17247e5 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Tue, 16 Oct 2012 16:47:50 +0900 Subject: staging: csr: csr_framework_ext_types.h: fix coding style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix coding style of csr_framework_ext_types.h     Signed-off-by: SeongJae Park Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext_types.h | 33 ++++++++++++--------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/drivers/staging/csr/csr_framework_ext_types.h b/drivers/staging/csr/csr_framework_ext_types.h index 57194ee911e..0d06d95d04f 100644 --- a/drivers/staging/csr/csr_framework_ext_types.h +++ b/drivers/staging/csr/csr_framework_ext_types.h @@ -2,11 +2,11 @@ #define CSR_FRAMEWORK_EXT_TYPES_H__ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2010 - All rights reserved and confidential information of CSR + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR - Refer to LICENSE.txt included with this source for details - on the license terms. + Refer to LICENSE.txt included with this source for details + on the license terms. *****************************************************************************/ @@ -24,17 +24,15 @@ extern "C" { #ifdef __KERNEL__ -struct CsrThread -{ - struct task_struct *thread_task; - char name[16]; +struct CsrThread { + struct task_struct *thread_task; + char name[16]; }; -struct CsrEvent -{ - /* wait_queue for waking the kernel thread */ - wait_queue_head_t wakeup_q; - unsigned int wakeup_flag; +struct CsrEvent { + /* wait_queue for waking the kernel thread */ + wait_queue_head_t wakeup_q; + unsigned int wakeup_flag; }; typedef struct CsrEvent CsrEventHandle; @@ -43,11 +41,10 @@ typedef struct CsrThread CsrThreadHandle; #else /* __KERNEL __ */ -struct CsrEvent -{ - pthread_cond_t event; - pthread_mutex_t mutex; - u32 eventBits; +struct CsrEvent { + pthread_cond_t event; + pthread_mutex_t mutex; + u32 eventBits; }; typedef struct CsrEvent CsrEventHandle; -- cgit v1.2.3 From ae485c27c71fea5a90503676c7d491f46db48f33 Mon Sep 17 00:00:00 2001 From: Sunhee Hwang Date: Thu, 18 Oct 2012 10:52:50 +0900 Subject: Staging: csr: fix pointer(asterisk) position coding style issue in sme_userspace.h This is a patch in the sme_userspace.h that fixes up a pointer(asterisk) position warning found by checkpatch.pl tool Signed-off-by: Sunhee Hwang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/sme_userspace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/csr/sme_userspace.h b/drivers/staging/csr/sme_userspace.h index 7816b15b4b5..ebe371c732b 100644 --- a/drivers/staging/csr/sme_userspace.h +++ b/drivers/staging/csr/sme_userspace.h @@ -32,7 +32,7 @@ int uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length); #include "csr_wifi_sme_lib.h" void CsrWifiRouterTransportInit(unifi_priv_t *priv); -void CsrWifiRouterTransportRecv(unifi_priv_t *priv, u8* buffer, size_t bufferLength); +void CsrWifiRouterTransportRecv(unifi_priv_t *priv, u8 *buffer, size_t bufferLength); void CsrWifiRouterTransportDeInit(unifi_priv_t *priv); #endif /* __LINUX_SME_USERSPACE_H__ */ -- cgit v1.2.3 From 936a8b4c29e2db3db7cb6109d5be15b71a05acb5 Mon Sep 17 00:00:00 2001 From: Sangho Yi Date: Sun, 14 Oct 2012 21:35:32 +0900 Subject: Drivers: Staging: CSR: fixed coding style errors in csr_wifi_router_free_upstream_contents.c Originally there were a lot of coding style errors so, I cleaned up the coding style errors including braces and indentations. Signed-off-by: Sangho Yi Signed-off-by: Greg Kroah-Hartman --- .../csr/csr_wifi_router_free_upstream_contents.c | 46 ++++++++++------------ 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c b/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c index de1086d7158..4cd126338e2 100644 --- a/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c +++ b/drivers/staging/csr/csr_wifi_router_free_upstream_contents.c @@ -1,10 +1,10 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 - All rights reserved and confidential information of CSR + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR - Refer to LICENSE.txt included with this source for details - on the license terms. + Refer to LICENSE.txt included with this source for details + on the license terms. *****************************************************************************/ @@ -26,28 +26,22 @@ *----------------------------------------------------------------------------*/ void CsrWifiRouterFreeUpstreamMessageContents(u16 eventClass, void *message) { - if (eventClass != CSR_WIFI_ROUTER_PRIM) - { - return; - } - if (NULL == message) - { - return; - } - - switch (*((CsrWifiRouterPrim *) message)) - { - case CSR_WIFI_ROUTER_MA_PACKET_IND: - { - CsrWifiRouterMaPacketInd *p = (CsrWifiRouterMaPacketInd *)message; - kfree(p->frame); - p->frame = NULL; - break; - } - - default: - break; - } + if (eventClass != CSR_WIFI_ROUTER_PRIM) + return; + if (NULL == message) + return; + switch (*((CsrWifiRouterPrim *) message)) { + case CSR_WIFI_ROUTER_MA_PACKET_IND: + { + CsrWifiRouterMaPacketInd *p = + (CsrWifiRouterMaPacketInd *) message; + kfree(p->frame); + p->frame = NULL; + break; + } + default: + break; + } } -- cgit v1.2.3 From 9851c29c7fa1708b13e14361c50091287d3d9ba4 Mon Sep 17 00:00:00 2001 From: Sangho Yi Date: Wed, 17 Oct 2012 19:11:01 +0900 Subject: staging: csr: csr_wifi_sme_task.h: fixed indentation coding style Removed coding style warnings occurred on the comments. Signed-off-by: Sangho Yi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_sme_task.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_sme_task.h b/drivers/staging/csr/csr_wifi_sme_task.h index 0f725e45493..a94fe88fa41 100644 --- a/drivers/staging/csr/csr_wifi_sme_task.h +++ b/drivers/staging/csr/csr_wifi_sme_task.h @@ -1,10 +1,10 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 - All rights reserved and confidential information of CSR + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR - Refer to LICENSE.txt included with this source for details - on the license terms. + Refer to LICENSE.txt included with this source for details + on the license terms. *****************************************************************************/ -- cgit v1.2.3 From 095cc7143da28bff9f44a484ddcc3622585f1937 Mon Sep 17 00:00:00 2001 From: Sangho Yi Date: Wed, 17 Oct 2012 19:11:03 +0900 Subject: staging: csr: csr_wifi_sme_serialize.h: Fixed from foo* bar to foo *bar Fixed the coding style convention warnings for the statements of the pointer variable declaration. Signed-off-by: Sangho Yi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_sme_serialize.h | 316 +++++++++++++-------------- 1 file changed, 158 insertions(+), 158 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_sme_serialize.h b/drivers/staging/csr/csr_wifi_sme_serialize.h index 4f3af0a6be7..64c9bd00bc3 100644 --- a/drivers/staging/csr/csr_wifi_sme_serialize.h +++ b/drivers/staging/csr/csr_wifi_sme_serialize.h @@ -32,13 +32,13 @@ extern void CsrWifiSmePfree(void *ptr); #define CsrWifiSmeAdhocConfigGetReqSizeof CsrWifiEventSizeof #define CsrWifiSmeAdhocConfigGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeAdhocConfigSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeAdhocConfigSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeAdhocConfigSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeAdhocConfigSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeAdhocConfigSetReqSizeof(void *msg); #define CsrWifiSmeAdhocConfigSetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeBlacklistReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeBlacklistReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeBlacklistReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeBlacklistReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeBlacklistReqSizeof(void *msg); extern void CsrWifiSmeBlacklistReqSerFree(void *msg); @@ -47,8 +47,8 @@ extern void CsrWifiSmeBlacklistReqSerFree(void *msg); #define CsrWifiSmeCalibrationDataGetReqSizeof CsrWifiEventSizeof #define CsrWifiSmeCalibrationDataGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeCalibrationDataSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeCalibrationDataSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeCalibrationDataSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeCalibrationDataSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeCalibrationDataSetReqSizeof(void *msg); extern void CsrWifiSmeCalibrationDataSetReqSerFree(void *msg); @@ -57,8 +57,8 @@ extern void CsrWifiSmeCalibrationDataSetReqSerFree(void *msg); #define CsrWifiSmeCcxConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeCcxConfigGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeCcxConfigSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeCcxConfigSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeCcxConfigSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeCcxConfigSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeCcxConfigSetReqSizeof(void *msg); #define CsrWifiSmeCcxConfigSetReqSerFree CsrWifiSmePfree @@ -67,8 +67,8 @@ extern size_t CsrWifiSmeCcxConfigSetReqSizeof(void *msg); #define CsrWifiSmeCoexConfigGetReqSizeof CsrWifiEventSizeof #define CsrWifiSmeCoexConfigGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeCoexConfigSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeCoexConfigSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeCoexConfigSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeCoexConfigSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeCoexConfigSetReqSizeof(void *msg); #define CsrWifiSmeCoexConfigSetReqSerFree CsrWifiSmePfree @@ -77,8 +77,8 @@ extern size_t CsrWifiSmeCoexConfigSetReqSizeof(void *msg); #define CsrWifiSmeCoexInfoGetReqSizeof CsrWifiEventSizeof #define CsrWifiSmeCoexInfoGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeConnectReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeConnectReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeConnectReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeConnectReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeConnectReqSizeof(void *msg); extern void CsrWifiSmeConnectReqSerFree(void *msg); @@ -117,13 +117,13 @@ extern void CsrWifiSmeConnectReqSerFree(void *msg); #define CsrWifiSmeHostConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeHostConfigGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeHostConfigSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeHostConfigSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeHostConfigSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeHostConfigSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeHostConfigSetReqSizeof(void *msg); #define CsrWifiSmeHostConfigSetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeKeyReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeKeyReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeKeyReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeKeyReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeKeyReqSizeof(void *msg); #define CsrWifiSmeKeyReqSerFree CsrWifiSmePfree @@ -137,33 +137,33 @@ extern size_t CsrWifiSmeKeyReqSizeof(void *msg); #define CsrWifiSmeMibConfigGetReqSizeof CsrWifiEventSizeof #define CsrWifiSmeMibConfigGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeMibConfigSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeMibConfigSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeMibConfigSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeMibConfigSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeMibConfigSetReqSizeof(void *msg); #define CsrWifiSmeMibConfigSetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeMibGetNextReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeMibGetNextReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeMibGetNextReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeMibGetNextReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeMibGetNextReqSizeof(void *msg); extern void CsrWifiSmeMibGetNextReqSerFree(void *msg); -extern u8* CsrWifiSmeMibGetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeMibGetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeMibGetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeMibGetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeMibGetReqSizeof(void *msg); extern void CsrWifiSmeMibGetReqSerFree(void *msg); -extern u8* CsrWifiSmeMibSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeMibSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeMibSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeMibSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeMibSetReqSizeof(void *msg); extern void CsrWifiSmeMibSetReqSerFree(void *msg); -extern u8* CsrWifiSmeMulticastAddressReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeMulticastAddressReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeMulticastAddressReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeMulticastAddressReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeMulticastAddressReqSizeof(void *msg); extern void CsrWifiSmeMulticastAddressReqSerFree(void *msg); -extern u8* CsrWifiSmePacketFilterSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmePacketFilterSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmePacketFilterSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmePacketFilterSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmePacketFilterSetReqSizeof(void *msg); extern void CsrWifiSmePacketFilterSetReqSerFree(void *msg); @@ -172,8 +172,8 @@ extern void CsrWifiSmePacketFilterSetReqSerFree(void *msg); #define CsrWifiSmePermanentMacAddressGetReqSizeof CsrWifiEventSizeof #define CsrWifiSmePermanentMacAddressGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmePmkidReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmePmkidReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmePmkidReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmePmkidReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmePmkidReqSizeof(void *msg); extern void CsrWifiSmePmkidReqSerFree(void *msg); @@ -182,8 +182,8 @@ extern void CsrWifiSmePmkidReqSerFree(void *msg); #define CsrWifiSmePowerConfigGetReqSizeof CsrWifiEventSizeof #define CsrWifiSmePowerConfigGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmePowerConfigSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmePowerConfigSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmePowerConfigSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmePowerConfigSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmePowerConfigSetReqSizeof(void *msg); #define CsrWifiSmePowerConfigSetReqSerFree CsrWifiSmePfree @@ -197,8 +197,8 @@ extern size_t CsrWifiSmePowerConfigSetReqSizeof(void *msg); #define CsrWifiSmeRoamingConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeRoamingConfigGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeRoamingConfigSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeRoamingConfigSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeRoamingConfigSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeRoamingConfigSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeRoamingConfigSetReqSizeof(void *msg); #define CsrWifiSmeRoamingConfigSetReqSerFree CsrWifiSmePfree @@ -207,13 +207,13 @@ extern size_t CsrWifiSmeRoamingConfigSetReqSizeof(void *msg); #define CsrWifiSmeScanConfigGetReqSizeof CsrWifiEventSizeof #define CsrWifiSmeScanConfigGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeScanConfigSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeScanConfigSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeScanConfigSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeScanConfigSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeScanConfigSetReqSizeof(void *msg); extern void CsrWifiSmeScanConfigSetReqSerFree(void *msg); -extern u8* CsrWifiSmeScanFullReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeScanFullReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeScanFullReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeScanFullReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeScanFullReqSizeof(void *msg); extern void CsrWifiSmeScanFullReqSerFree(void *msg); @@ -232,8 +232,8 @@ extern void CsrWifiSmeScanFullReqSerFree(void *msg); #define CsrWifiSmeSmeStaConfigGetReqSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeSmeStaConfigGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeSmeStaConfigSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeSmeStaConfigSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeSmeStaConfigSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeSmeStaConfigSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeSmeStaConfigSetReqSizeof(void *msg); #define CsrWifiSmeSmeStaConfigSetReqSerFree CsrWifiSmePfree @@ -242,8 +242,8 @@ extern size_t CsrWifiSmeSmeStaConfigSetReqSizeof(void *msg); #define CsrWifiSmeStationMacAddressGetReqSizeof CsrWifiEventSizeof #define CsrWifiSmeStationMacAddressGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeTspecReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeTspecReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeTspecReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeTspecReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeTspecReqSizeof(void *msg); extern void CsrWifiSmeTspecReqSerFree(void *msg); @@ -252,8 +252,8 @@ extern void CsrWifiSmeTspecReqSerFree(void *msg); #define CsrWifiSmeVersionsGetReqSizeof CsrWifiEventSizeof #define CsrWifiSmeVersionsGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeWifiFlightmodeReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeWifiFlightmodeReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeWifiFlightmodeReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeWifiFlightmodeReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeWifiFlightmodeReqSizeof(void *msg); extern void CsrWifiSmeWifiFlightmodeReqSerFree(void *msg); @@ -262,13 +262,13 @@ extern void CsrWifiSmeWifiFlightmodeReqSerFree(void *msg); #define CsrWifiSmeWifiOffReqSizeof CsrWifiEventSizeof #define CsrWifiSmeWifiOffReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeWifiOnReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeWifiOnReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeWifiOnReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeWifiOnReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeWifiOnReqSizeof(void *msg); extern void CsrWifiSmeWifiOnReqSerFree(void *msg); -extern u8* CsrWifiSmeCloakedSsidsSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeCloakedSsidsSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeCloakedSsidsSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeCloakedSsidsSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeCloakedSsidsSetReqSizeof(void *msg); extern void CsrWifiSmeCloakedSsidsSetReqSerFree(void *msg); @@ -282,8 +282,8 @@ extern void CsrWifiSmeCloakedSsidsSetReqSerFree(void *msg); #define CsrWifiSmeSmeCommonConfigGetReqSizeof CsrWifiEventSizeof #define CsrWifiSmeSmeCommonConfigGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeSmeCommonConfigSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeSmeCommonConfigSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeSmeCommonConfigSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeSmeCommonConfigSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeSmeCommonConfigSetReqSizeof(void *msg); #define CsrWifiSmeSmeCommonConfigSetReqSerFree CsrWifiSmePfree @@ -292,13 +292,13 @@ extern size_t CsrWifiSmeSmeCommonConfigSetReqSizeof(void *msg); #define CsrWifiSmeInterfaceCapabilityGetReqSizeof CsrWifiEventSizeof #define CsrWifiSmeInterfaceCapabilityGetReqSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeWpsConfigurationReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeWpsConfigurationReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeWpsConfigurationReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeWpsConfigurationReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeWpsConfigurationReqSizeof(void *msg); extern void CsrWifiSmeWpsConfigurationReqSerFree(void *msg); -extern u8* CsrWifiSmeSetReqSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeSetReqDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeSetReqSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeSetReqDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeSetReqSizeof(void *msg); extern void CsrWifiSmeSetReqSerFree(void *msg); @@ -307,8 +307,8 @@ extern void CsrWifiSmeSetReqSerFree(void *msg); #define CsrWifiSmeActivateCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeActivateCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeAdhocConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeAdhocConfigGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeAdhocConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeAdhocConfigGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeAdhocConfigGetCfmSizeof(void *msg); #define CsrWifiSmeAdhocConfigGetCfmSerFree CsrWifiSmePfree @@ -317,23 +317,23 @@ extern size_t CsrWifiSmeAdhocConfigGetCfmSizeof(void *msg); #define CsrWifiSmeAdhocConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeAdhocConfigSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeAssociationCompleteIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeAssociationCompleteIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeAssociationCompleteIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeAssociationCompleteIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeAssociationCompleteIndSizeof(void *msg); extern void CsrWifiSmeAssociationCompleteIndSerFree(void *msg); -extern u8* CsrWifiSmeAssociationStartIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeAssociationStartIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeAssociationStartIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeAssociationStartIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeAssociationStartIndSizeof(void *msg); #define CsrWifiSmeAssociationStartIndSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeBlacklistCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeBlacklistCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeBlacklistCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeBlacklistCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeBlacklistCfmSizeof(void *msg); extern void CsrWifiSmeBlacklistCfmSerFree(void *msg); -extern u8* CsrWifiSmeCalibrationDataGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeCalibrationDataGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeCalibrationDataGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeCalibrationDataGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeCalibrationDataGetCfmSizeof(void *msg); extern void CsrWifiSmeCalibrationDataGetCfmSerFree(void *msg); @@ -342,18 +342,18 @@ extern void CsrWifiSmeCalibrationDataGetCfmSerFree(void *msg); #define CsrWifiSmeCalibrationDataSetCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeCalibrationDataSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeCcxConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeCcxConfigGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeCcxConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeCcxConfigGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeCcxConfigGetCfmSizeof(void *msg); #define CsrWifiSmeCcxConfigGetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeCcxConfigSetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeCcxConfigSetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeCcxConfigSetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeCcxConfigSetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeCcxConfigSetCfmSizeof(void *msg); #define CsrWifiSmeCcxConfigSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeCoexConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeCoexConfigGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeCoexConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeCoexConfigGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeCoexConfigGetCfmSizeof(void *msg); #define CsrWifiSmeCoexConfigGetCfmSerFree CsrWifiSmePfree @@ -362,33 +362,33 @@ extern size_t CsrWifiSmeCoexConfigGetCfmSizeof(void *msg); #define CsrWifiSmeCoexConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeCoexConfigSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeCoexInfoGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeCoexInfoGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeCoexInfoGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeCoexInfoGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeCoexInfoGetCfmSizeof(void *msg); #define CsrWifiSmeCoexInfoGetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeConnectCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeConnectCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeConnectCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeConnectCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeConnectCfmSizeof(void *msg); #define CsrWifiSmeConnectCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeConnectionConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeConnectionConfigGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeConnectionConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeConnectionConfigGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeConnectionConfigGetCfmSizeof(void *msg); extern void CsrWifiSmeConnectionConfigGetCfmSerFree(void *msg); -extern u8* CsrWifiSmeConnectionInfoGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeConnectionInfoGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeConnectionInfoGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeConnectionInfoGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeConnectionInfoGetCfmSizeof(void *msg); extern void CsrWifiSmeConnectionInfoGetCfmSerFree(void *msg); -extern u8* CsrWifiSmeConnectionQualityIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeConnectionQualityIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeConnectionQualityIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeConnectionQualityIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeConnectionQualityIndSizeof(void *msg); #define CsrWifiSmeConnectionQualityIndSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeConnectionStatsGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeConnectionStatsGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeConnectionStatsGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeConnectionStatsGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeConnectionStatsGetCfmSizeof(void *msg); #define CsrWifiSmeConnectionStatsGetCfmSerFree CsrWifiSmePfree @@ -397,8 +397,8 @@ extern size_t CsrWifiSmeConnectionStatsGetCfmSizeof(void *msg); #define CsrWifiSmeDeactivateCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeDeactivateCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeDisconnectCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeDisconnectCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeDisconnectCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeDisconnectCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeDisconnectCfmSizeof(void *msg); #define CsrWifiSmeDisconnectCfmSerFree CsrWifiSmePfree @@ -407,38 +407,38 @@ extern size_t CsrWifiSmeDisconnectCfmSizeof(void *msg); #define CsrWifiSmeEventMaskSetCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeEventMaskSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeHostConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeHostConfigGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeHostConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeHostConfigGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeHostConfigGetCfmSizeof(void *msg); #define CsrWifiSmeHostConfigGetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeHostConfigSetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeHostConfigSetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeHostConfigSetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeHostConfigSetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeHostConfigSetCfmSizeof(void *msg); #define CsrWifiSmeHostConfigSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeIbssStationIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeIbssStationIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeIbssStationIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeIbssStationIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeIbssStationIndSizeof(void *msg); #define CsrWifiSmeIbssStationIndSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeKeyCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeKeyCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeKeyCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeKeyCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeKeyCfmSizeof(void *msg); #define CsrWifiSmeKeyCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeLinkQualityGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeLinkQualityGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeLinkQualityGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeLinkQualityGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeLinkQualityGetCfmSizeof(void *msg); #define CsrWifiSmeLinkQualityGetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeMediaStatusIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeMediaStatusIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeMediaStatusIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeMediaStatusIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeMediaStatusIndSizeof(void *msg); extern void CsrWifiSmeMediaStatusIndSerFree(void *msg); -extern u8* CsrWifiSmeMibConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeMibConfigGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeMibConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeMibConfigGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeMibConfigGetCfmSizeof(void *msg); #define CsrWifiSmeMibConfigGetCfmSerFree CsrWifiSmePfree @@ -447,13 +447,13 @@ extern size_t CsrWifiSmeMibConfigGetCfmSizeof(void *msg); #define CsrWifiSmeMibConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeMibConfigSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeMibGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeMibGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeMibGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeMibGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeMibGetCfmSizeof(void *msg); extern void CsrWifiSmeMibGetCfmSerFree(void *msg); -extern u8* CsrWifiSmeMibGetNextCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeMibGetNextCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeMibGetNextCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeMibGetNextCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeMibGetNextCfmSizeof(void *msg); extern void CsrWifiSmeMibGetNextCfmSerFree(void *msg); @@ -462,38 +462,38 @@ extern void CsrWifiSmeMibGetNextCfmSerFree(void *msg); #define CsrWifiSmeMibSetCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeMibSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeMicFailureIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeMicFailureIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeMicFailureIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeMicFailureIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeMicFailureIndSizeof(void *msg); #define CsrWifiSmeMicFailureIndSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeMulticastAddressCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeMulticastAddressCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeMulticastAddressCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeMulticastAddressCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeMulticastAddressCfmSizeof(void *msg); extern void CsrWifiSmeMulticastAddressCfmSerFree(void *msg); -extern u8* CsrWifiSmePacketFilterSetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmePacketFilterSetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmePacketFilterSetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmePacketFilterSetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmePacketFilterSetCfmSizeof(void *msg); #define CsrWifiSmePacketFilterSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmePermanentMacAddressGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmePermanentMacAddressGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmePermanentMacAddressGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmePermanentMacAddressGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmePermanentMacAddressGetCfmSizeof(void *msg); #define CsrWifiSmePermanentMacAddressGetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmePmkidCandidateListIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmePmkidCandidateListIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmePmkidCandidateListIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmePmkidCandidateListIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmePmkidCandidateListIndSizeof(void *msg); extern void CsrWifiSmePmkidCandidateListIndSerFree(void *msg); -extern u8* CsrWifiSmePmkidCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmePmkidCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmePmkidCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmePmkidCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmePmkidCfmSizeof(void *msg); extern void CsrWifiSmePmkidCfmSerFree(void *msg); -extern u8* CsrWifiSmePowerConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmePowerConfigGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmePowerConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmePowerConfigGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmePowerConfigGetCfmSizeof(void *msg); #define CsrWifiSmePowerConfigGetCfmSerFree CsrWifiSmePfree @@ -502,33 +502,33 @@ extern size_t CsrWifiSmePowerConfigGetCfmSizeof(void *msg); #define CsrWifiSmePowerConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmePowerConfigSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeRegulatoryDomainInfoGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeRegulatoryDomainInfoGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeRegulatoryDomainInfoGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeRegulatoryDomainInfoGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeRegulatoryDomainInfoGetCfmSizeof(void *msg); #define CsrWifiSmeRegulatoryDomainInfoGetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeRoamCompleteIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeRoamCompleteIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeRoamCompleteIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeRoamCompleteIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeRoamCompleteIndSizeof(void *msg); #define CsrWifiSmeRoamCompleteIndSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeRoamStartIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeRoamStartIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeRoamStartIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeRoamStartIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeRoamStartIndSizeof(void *msg); #define CsrWifiSmeRoamStartIndSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeRoamingConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeRoamingConfigGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeRoamingConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeRoamingConfigGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeRoamingConfigGetCfmSizeof(void *msg); #define CsrWifiSmeRoamingConfigGetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeRoamingConfigSetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeRoamingConfigSetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeRoamingConfigSetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeRoamingConfigSetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeRoamingConfigSetCfmSizeof(void *msg); #define CsrWifiSmeRoamingConfigSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeScanConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeScanConfigGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeScanConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeScanConfigGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeScanConfigGetCfmSizeof(void *msg); extern void CsrWifiSmeScanConfigGetCfmSerFree(void *msg); @@ -542,8 +542,8 @@ extern void CsrWifiSmeScanConfigGetCfmSerFree(void *msg); #define CsrWifiSmeScanFullCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeScanFullCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeScanResultIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeScanResultIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeScanResultIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeScanResultIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeScanResultIndSizeof(void *msg); extern void CsrWifiSmeScanResultIndSerFree(void *msg); @@ -552,38 +552,38 @@ extern void CsrWifiSmeScanResultIndSerFree(void *msg); #define CsrWifiSmeScanResultsFlushCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeScanResultsFlushCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeScanResultsGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeScanResultsGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeScanResultsGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeScanResultsGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeScanResultsGetCfmSizeof(void *msg); extern void CsrWifiSmeScanResultsGetCfmSerFree(void *msg); -extern u8* CsrWifiSmeSmeStaConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeSmeStaConfigGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeSmeStaConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeSmeStaConfigGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeSmeStaConfigGetCfmSizeof(void *msg); #define CsrWifiSmeSmeStaConfigGetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeSmeStaConfigSetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeSmeStaConfigSetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeSmeStaConfigSetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeSmeStaConfigSetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeSmeStaConfigSetCfmSizeof(void *msg); #define CsrWifiSmeSmeStaConfigSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeStationMacAddressGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeStationMacAddressGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeStationMacAddressGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeStationMacAddressGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeStationMacAddressGetCfmSizeof(void *msg); #define CsrWifiSmeStationMacAddressGetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeTspecIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeTspecIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeTspecIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeTspecIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeTspecIndSizeof(void *msg); extern void CsrWifiSmeTspecIndSerFree(void *msg); -extern u8* CsrWifiSmeTspecCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeTspecCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeTspecCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeTspecCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeTspecCfmSizeof(void *msg); extern void CsrWifiSmeTspecCfmSerFree(void *msg); -extern u8* CsrWifiSmeVersionsGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeVersionsGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeVersionsGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeVersionsGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeVersionsGetCfmSizeof(void *msg); extern void CsrWifiSmeVersionsGetCfmSerFree(void *msg); @@ -612,18 +612,18 @@ extern void CsrWifiSmeVersionsGetCfmSerFree(void *msg); #define CsrWifiSmeCloakedSsidsSetCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeCloakedSsidsSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeCloakedSsidsGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeCloakedSsidsGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeCloakedSsidsGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeCloakedSsidsGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeCloakedSsidsGetCfmSizeof(void *msg); extern void CsrWifiSmeCloakedSsidsGetCfmSerFree(void *msg); -extern u8* CsrWifiSmeWifiOnIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeWifiOnIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeWifiOnIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeWifiOnIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeWifiOnIndSizeof(void *msg); #define CsrWifiSmeWifiOnIndSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeSmeCommonConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeSmeCommonConfigGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeSmeCommonConfigGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeSmeCommonConfigGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeSmeCommonConfigGetCfmSizeof(void *msg); #define CsrWifiSmeSmeCommonConfigGetCfmSerFree CsrWifiSmePfree @@ -632,23 +632,23 @@ extern size_t CsrWifiSmeSmeCommonConfigGetCfmSizeof(void *msg); #define CsrWifiSmeSmeCommonConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeSmeCommonConfigSetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeInterfaceCapabilityGetCfmSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeInterfaceCapabilityGetCfmDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeInterfaceCapabilityGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeInterfaceCapabilityGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeInterfaceCapabilityGetCfmSizeof(void *msg); #define CsrWifiSmeInterfaceCapabilityGetCfmSerFree CsrWifiSmePfree -extern u8* CsrWifiSmeErrorIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeErrorIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeErrorIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeErrorIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeErrorIndSizeof(void *msg); extern void CsrWifiSmeErrorIndSerFree(void *msg); -extern u8* CsrWifiSmeInfoIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeInfoIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeInfoIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeInfoIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeInfoIndSizeof(void *msg); extern void CsrWifiSmeInfoIndSerFree(void *msg); -extern u8* CsrWifiSmeCoreDumpIndSer(u8 *ptr, size_t *len, void *msg); -extern void* CsrWifiSmeCoreDumpIndDes(u8 *buffer, size_t len); +extern u8 *CsrWifiSmeCoreDumpIndSer(u8 *ptr, size_t *len, void *msg); +extern void *CsrWifiSmeCoreDumpIndDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeCoreDumpIndSizeof(void *msg); extern void CsrWifiSmeCoreDumpIndSerFree(void *msg); -- cgit v1.2.3 From 6b74b192f62fb5f97e0f4c4d79ef787e3061d664 Mon Sep 17 00:00:00 2001 From: Sangho Yi Date: Wed, 17 Oct 2012 19:11:04 +0900 Subject: staging: csr: csr_wifi_sme_serialize.h: fixed over 80 char lines Appropriately modified the lines over 80 characters. Signed-off-by: Sangho Yi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_sme_serialize.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_sme_serialize.h b/drivers/staging/csr/csr_wifi_sme_serialize.h index 64c9bd00bc3..33e5b7d6867 100644 --- a/drivers/staging/csr/csr_wifi_sme_serialize.h +++ b/drivers/staging/csr/csr_wifi_sme_serialize.h @@ -477,7 +477,8 @@ extern void *CsrWifiSmePacketFilterSetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmePacketFilterSetCfmSizeof(void *msg); #define CsrWifiSmePacketFilterSetCfmSerFree CsrWifiSmePfree -extern u8 *CsrWifiSmePermanentMacAddressGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern u8 *CsrWifiSmePermanentMacAddressGetCfmSer(u8 *ptr, size_t *len, + void *msg); extern void *CsrWifiSmePermanentMacAddressGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmePermanentMacAddressGetCfmSizeof(void *msg); #define CsrWifiSmePermanentMacAddressGetCfmSerFree CsrWifiSmePfree @@ -502,7 +503,8 @@ extern size_t CsrWifiSmePowerConfigGetCfmSizeof(void *msg); #define CsrWifiSmePowerConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmePowerConfigSetCfmSerFree CsrWifiSmePfree -extern u8 *CsrWifiSmeRegulatoryDomainInfoGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern u8 *CsrWifiSmeRegulatoryDomainInfoGetCfmSer(u8 *ptr, size_t *len, + void *msg); extern void *CsrWifiSmeRegulatoryDomainInfoGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeRegulatoryDomainInfoGetCfmSizeof(void *msg); #define CsrWifiSmeRegulatoryDomainInfoGetCfmSerFree CsrWifiSmePfree @@ -567,7 +569,8 @@ extern void *CsrWifiSmeSmeStaConfigSetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeSmeStaConfigSetCfmSizeof(void *msg); #define CsrWifiSmeSmeStaConfigSetCfmSerFree CsrWifiSmePfree -extern u8 *CsrWifiSmeStationMacAddressGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern u8 *CsrWifiSmeStationMacAddressGetCfmSer(u8 *ptr, size_t *len, + void *msg); extern void *CsrWifiSmeStationMacAddressGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeStationMacAddressGetCfmSizeof(void *msg); #define CsrWifiSmeStationMacAddressGetCfmSerFree CsrWifiSmePfree @@ -632,7 +635,8 @@ extern size_t CsrWifiSmeSmeCommonConfigGetCfmSizeof(void *msg); #define CsrWifiSmeSmeCommonConfigSetCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeSmeCommonConfigSetCfmSerFree CsrWifiSmePfree -extern u8 *CsrWifiSmeInterfaceCapabilityGetCfmSer(u8 *ptr, size_t *len, void *msg); +extern u8 *CsrWifiSmeInterfaceCapabilityGetCfmSer(u8 *ptr, size_t *len, + void *msg); extern void *CsrWifiSmeInterfaceCapabilityGetCfmDes(u8 *buffer, size_t len); extern size_t CsrWifiSmeInterfaceCapabilityGetCfmSizeof(void *msg); #define CsrWifiSmeInterfaceCapabilityGetCfmSerFree CsrWifiSmePfree -- cgit v1.2.3 From 1ac80e498a67191a95fdaf7a97e2b317a984aacd Mon Sep 17 00:00:00 2001 From: Sangho Yi Date: Wed, 17 Oct 2012 19:11:06 +0900 Subject: staging: csr: csr_wifi_sme_sef.h: Fixed from foo* bar to foo *bar Fixed coding style errors like foo* bar to foo *bar for the definition of input and output variables of the function interfaces. Signed-off-by: Sangho Yi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_sme_sef.h | 144 ++++++++++++++++----------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_sme_sef.h b/drivers/staging/csr/csr_wifi_sme_sef.h index c8741811b2e..1e853467301 100644 --- a/drivers/staging/csr/csr_wifi_sme_sef.h +++ b/drivers/staging/csr/csr_wifi_sme_sef.h @@ -17,82 +17,82 @@ extern "C" { #endif -typedef void (*CsrWifiSmeStateHandlerType)(void* drvpriv, CsrWifiFsmEvent* msg); +typedef void (*CsrWifiSmeStateHandlerType)(void *drvpriv, CsrWifiFsmEvent *msg); extern const CsrWifiSmeStateHandlerType CsrWifiSmeUpstreamStateHandlers[CSR_WIFI_SME_PRIM_UPSTREAM_COUNT]; -extern void CsrWifiSmeActivateCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeAdhocConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeAdhocConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeAssociationCompleteIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeAssociationStartIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeBlacklistCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeCalibrationDataGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeCalibrationDataSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeCcxConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeCcxConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeCoexConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeCoexConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeCoexInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeConnectCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeConnectionConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeConnectionInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeConnectionQualityIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeConnectionStatsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeDeactivateCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeDisconnectCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeEventMaskSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeHostConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeHostConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeIbssStationIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeKeyCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeLinkQualityGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeMediaStatusIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeMibConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeMibConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeMibGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeMibGetNextCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeMibSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeMicFailureIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeMulticastAddressCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmePacketFilterSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmePermanentMacAddressGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmePmkidCandidateListIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmePmkidCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmePowerConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmePowerConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeRegulatoryDomainInfoGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeRoamCompleteIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeRoamStartIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeRoamingConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeRoamingConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeScanConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeScanConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeScanFullCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeScanResultIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeScanResultsFlushCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeScanResultsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeSmeStaConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeSmeStaConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeStationMacAddressGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeTspecIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeTspecCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeVersionsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeWifiFlightmodeCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeWifiOffIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeWifiOffCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeWifiOnCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeCloakedSsidsSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeCloakedSsidsGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeWifiOnIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeSmeCommonConfigGetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeSmeCommonConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeGetInterfaceCapabilityCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeErrorIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeInfoIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeCoreDumpIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); -extern void CsrWifiSmeAmpStatusChangeIndHandler(void* drvpriv, CsrWifiFsmEvent* msg); +extern void CsrWifiSmeActivateCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeAdhocConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeAdhocConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeAssociationCompleteIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeAssociationStartIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeBlacklistCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCalibrationDataGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCalibrationDataSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCcxConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCcxConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCoexConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCoexConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCoexInfoGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeConnectCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeConnectionConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeConnectionInfoGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeConnectionQualityIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeConnectionStatsGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeDeactivateCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeDisconnectCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeEventMaskSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeHostConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeHostConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeIbssStationIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeKeyCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeLinkQualityGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeMediaStatusIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeMibConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeMibConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeMibGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeMibGetNextCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeMibSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeMicFailureIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeMulticastAddressCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmePacketFilterSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmePermanentMacAddressGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmePmkidCandidateListIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmePmkidCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmePowerConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmePowerConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeRegulatoryDomainInfoGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeRoamCompleteIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeRoamStartIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeRoamingConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeRoamingConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeScanConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeScanConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeScanFullCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeScanResultIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeScanResultsFlushCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeScanResultsGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeSmeStaConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeSmeStaConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeStationMacAddressGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeTspecIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeTspecCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeVersionsGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeWifiFlightmodeCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeWifiOffIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeWifiOffCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeWifiOnCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCloakedSsidsSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCloakedSsidsGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeWifiOnIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeSmeCommonConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeSmeCommonConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeGetInterfaceCapabilityCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeErrorIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeInfoIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCoreDumpIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeAmpStatusChangeIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); #ifdef __cplusplus } -- cgit v1.2.3 From f0dbd1dcb19ec14ec93838349372bb7fd4735475 Mon Sep 17 00:00:00 2001 From: Sangho Yi Date: Wed, 17 Oct 2012 19:11:07 +0900 Subject: staging: csr: csr_wifi_sme_sef.h: Fixed lines over 80 chars per line Fixed lines over 80 characters per line. Signed-off-by: Sangho Yi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_sme_sef.h | 150 ++++++++++++++++++++++----------- 1 file changed, 100 insertions(+), 50 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_sme_sef.h b/drivers/staging/csr/csr_wifi_sme_sef.h index 1e853467301..12aae800e81 100644 --- a/drivers/staging/csr/csr_wifi_sme_sef.h +++ b/drivers/staging/csr/csr_wifi_sme_sef.h @@ -19,80 +19,130 @@ extern "C" { typedef void (*CsrWifiSmeStateHandlerType)(void *drvpriv, CsrWifiFsmEvent *msg); -extern const CsrWifiSmeStateHandlerType CsrWifiSmeUpstreamStateHandlers[CSR_WIFI_SME_PRIM_UPSTREAM_COUNT]; +extern const CsrWifiSmeStateHandlerType + CsrWifiSmeUpstreamStateHandlers[CSR_WIFI_SME_PRIM_UPSTREAM_COUNT]; extern void CsrWifiSmeActivateCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeAdhocConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeAdhocConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeAssociationCompleteIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeAssociationStartIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeBlacklistCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeCalibrationDataGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeCalibrationDataSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeCcxConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeCcxConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeCoexConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeCoexConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeCoexInfoGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeAdhocConfigGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeAdhocConfigSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeAssociationCompleteIndHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeAssociationStartIndHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeBlacklistCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCalibrationDataGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCalibrationDataSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCcxConfigGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCcxConfigSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCoexConfigGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCoexConfigSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCoexInfoGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); extern void CsrWifiSmeConnectCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeConnectionConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeConnectionInfoGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeConnectionQualityIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeConnectionStatsGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeConnectionConfigGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeConnectionInfoGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeConnectionQualityIndHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeConnectionStatsGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); extern void CsrWifiSmeDeactivateCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); extern void CsrWifiSmeDisconnectCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeEventMaskSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeHostConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeHostConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeIbssStationIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeEventMaskSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeHostConfigGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeHostConfigSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeIbssStationIndHandler(void *drvpriv, + CsrWifiFsmEvent *msg); extern void CsrWifiSmeKeyCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeLinkQualityGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeMediaStatusIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeMibConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeMibConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeLinkQualityGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeMediaStatusIndHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeMibConfigGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeMibConfigSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); extern void CsrWifiSmeMibGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); extern void CsrWifiSmeMibGetNextCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); extern void CsrWifiSmeMibSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); extern void CsrWifiSmeMicFailureIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeMulticastAddressCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmePacketFilterSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmePermanentMacAddressGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmePmkidCandidateListIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeMulticastAddressCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmePacketFilterSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmePermanentMacAddressGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmePmkidCandidateListIndHandler(void *drvpriv, + CsrWifiFsmEvent *msg); extern void CsrWifiSmePmkidCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmePowerConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmePowerConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeRegulatoryDomainInfoGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeRoamCompleteIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmePowerConfigGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmePowerConfigSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeRegulatoryDomainInfoGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeRoamCompleteIndHandler(void *drvpriv, + CsrWifiFsmEvent *msg); extern void CsrWifiSmeRoamStartIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeRoamingConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeRoamingConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeScanConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeScanConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeRoamingConfigGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeRoamingConfigSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeScanConfigGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeScanConfigSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); extern void CsrWifiSmeScanFullCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); extern void CsrWifiSmeScanResultIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeScanResultsFlushCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeScanResultsGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeSmeStaConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeSmeStaConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeStationMacAddressGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeScanResultsFlushCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeScanResultsGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeSmeStaConfigGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeSmeStaConfigSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeStationMacAddressGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); extern void CsrWifiSmeTspecIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); extern void CsrWifiSmeTspecCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeVersionsGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeWifiFlightmodeCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeVersionsGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeWifiFlightmodeCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); extern void CsrWifiSmeWifiOffIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); extern void CsrWifiSmeWifiOffCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); extern void CsrWifiSmeWifiOnCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeCloakedSsidsSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeCloakedSsidsGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCloakedSsidsSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeCloakedSsidsGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); extern void CsrWifiSmeWifiOnIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeSmeCommonConfigGetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeSmeCommonConfigSetCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeGetInterfaceCapabilityCfmHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeSmeCommonConfigGetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeSmeCommonConfigSetCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); +extern void CsrWifiSmeGetInterfaceCapabilityCfmHandler(void *drvpriv, + CsrWifiFsmEvent *msg); extern void CsrWifiSmeErrorIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); extern void CsrWifiSmeInfoIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); extern void CsrWifiSmeCoreDumpIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); -extern void CsrWifiSmeAmpStatusChangeIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); +extern void CsrWifiSmeAmpStatusChangeIndHandler(void *drvpriv, + CsrWifiFsmEvent *msg); #ifdef __cplusplus } -- cgit v1.2.3 From 9bf8ff7f18e40130630439ad49e5fc84d148eaad Mon Sep 17 00:00:00 2001 From: Sangho Yi Date: Wed, 17 Oct 2012 19:11:02 +0900 Subject: staging: csr: csr_wifi_sme_serialize.h: fixed indentation warnings Fixed indentation warnings from the comments. Signed-off-by: Sangho Yi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_sme_serialize.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_sme_serialize.h b/drivers/staging/csr/csr_wifi_sme_serialize.h index 33e5b7d6867..e34ae66d2f5 100644 --- a/drivers/staging/csr/csr_wifi_sme_serialize.h +++ b/drivers/staging/csr/csr_wifi_sme_serialize.h @@ -1,10 +1,10 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2012 - All rights reserved and confidential information of CSR + (c) Cambridge Silicon Radio Limited 2012 + All rights reserved and confidential information of CSR - Refer to LICENSE.txt included with this source for details - on the license terms. + Refer to LICENSE.txt included with this source for details + on the license terms. *****************************************************************************/ -- cgit v1.2.3 From 0288f91dbbdc7d0b44fac538deacc18afb78e822 Mon Sep 17 00:00:00 2001 From: Sangho Yi Date: Wed, 17 Oct 2012 19:11:05 +0900 Subject: staging: csr: csr_wifi_sme_sef.h: fixed indentation warnings Fixed indentation warnings on comments Signed-off-by: Sangho Yi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_sme_sef.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_sme_sef.h b/drivers/staging/csr/csr_wifi_sme_sef.h index 12aae800e81..89650c7fb6f 100644 --- a/drivers/staging/csr/csr_wifi_sme_sef.h +++ b/drivers/staging/csr/csr_wifi_sme_sef.h @@ -1,10 +1,10 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2010 - Confidential information of CSR + (c) Cambridge Silicon Radio Limited 2010 + Confidential information of CSR - Refer to LICENSE.txt included with this source for details - on the license terms. + Refer to LICENSE.txt included with this source for details + on the license terms. *****************************************************************************/ #ifndef CSR_WIFI_ROUTER_SEF_CSR_WIFI_SME_H__ -- cgit v1.2.3 From 86a598cd866dc0964b339f2b152198ab51d81af2 Mon Sep 17 00:00:00 2001 From: Jugwan Eom Date: Thu, 18 Oct 2012 22:00:40 +0900 Subject: Staging: csr: csr_wifi_router_ctrl_sef.c: fix up brace placement This patch fixes a brace placement error found by checkpatch.pl tool. Signed-off-by: Jugwan Eom Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_router_ctrl_sef.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c index 33d92b698c5..45422b98201 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c +++ b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c @@ -9,8 +9,7 @@ *****************************************************************************/ #include "csr_wifi_router_ctrl_sef.h" -const CsrWifiRouterCtrlStateHandlerType CsrWifiRouterCtrlDownstreamStateHandlers[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT] = -{ +const CsrWifiRouterCtrlStateHandlerType CsrWifiRouterCtrlDownstreamStateHandlers[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT] = { /* 0x0000 */ CsrWifiRouterCtrlConfigurePowerModeReqHandler, /* 0x0001 */ CsrWifiRouterCtrlHipReqHandler, /* 0x0002 */ CsrWifiRouterCtrlMediaStatusReqHandler, -- cgit v1.2.3 From 057ed6717021c4f46157af861ac09b432bff9f55 Mon Sep 17 00:00:00 2001 From: Jugwan Eom Date: Thu, 18 Oct 2012 22:00:41 +0900 Subject: Staging: csr: csr_wifi_router_ctrl_sef.c: fix tab mess This patch converts spaces to tabs. Signed-off-by: Jugwan Eom Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_router_ctrl_sef.c | 62 +++++++++++++------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c index 45422b98201..75b80ad33d8 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c +++ b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c @@ -10,35 +10,35 @@ #include "csr_wifi_router_ctrl_sef.h" const CsrWifiRouterCtrlStateHandlerType CsrWifiRouterCtrlDownstreamStateHandlers[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT] = { - /* 0x0000 */ CsrWifiRouterCtrlConfigurePowerModeReqHandler, - /* 0x0001 */ CsrWifiRouterCtrlHipReqHandler, - /* 0x0002 */ CsrWifiRouterCtrlMediaStatusReqHandler, - /* 0x0003 */ CsrWifiRouterCtrlMulticastAddressResHandler, - /* 0x0004 */ CsrWifiRouterCtrlPortConfigureReqHandler, - /* 0x0005 */ CsrWifiRouterCtrlQosControlReqHandler, - /* 0x0006 */ CsrWifiRouterCtrlSuspendResHandler, - /* 0x0007 */ CsrWifiRouterCtrlTclasAddReqHandler, - /* 0x0008 */ CsrWifiRouterCtrlResumeResHandler, - /* 0x0009 */ CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler, - /* 0x000A */ CsrWifiRouterCtrlRawSdioInitialiseReqHandler, - /* 0x000B */ CsrWifiRouterCtrlTclasDelReqHandler, - /* 0x000C */ CsrWifiRouterCtrlTrafficClassificationReqHandler, - /* 0x000D */ CsrWifiRouterCtrlTrafficConfigReqHandler, - /* 0x000E */ CsrWifiRouterCtrlWifiOffReqHandler, - /* 0x000F */ CsrWifiRouterCtrlWifiOffResHandler, - /* 0x0010 */ CsrWifiRouterCtrlWifiOnReqHandler, - /* 0x0011 */ CsrWifiRouterCtrlWifiOnResHandler, - /* 0x0012 */ CsrWifiRouterCtrlM4TransmitReqHandler, - /* 0x0013 */ CsrWifiRouterCtrlModeSetReqHandler, - /* 0x0014 */ CsrWifiRouterCtrlPeerAddReqHandler, - /* 0x0015 */ CsrWifiRouterCtrlPeerDelReqHandler, - /* 0x0016 */ CsrWifiRouterCtrlPeerUpdateReqHandler, - /* 0x0017 */ CsrWifiRouterCtrlCapabilitiesReqHandler, - /* 0x0018 */ CsrWifiRouterCtrlBlockAckEnableReqHandler, - /* 0x0019 */ CsrWifiRouterCtrlBlockAckDisableReqHandler, - /* 0x001A */ CsrWifiRouterCtrlWapiRxPktReqHandler, - /* 0x001B */ CsrWifiRouterCtrlWapiMulticastFilterReqHandler, - /* 0x001C */ CsrWifiRouterCtrlWapiUnicastFilterReqHandler, - /* 0x001D */ CsrWifiRouterCtrlWapiUnicastTxPktReqHandler, - /* 0x001E */ CsrWifiRouterCtrlWapiFilterReqHandler, + /* 0x0000 */ CsrWifiRouterCtrlConfigurePowerModeReqHandler, + /* 0x0001 */ CsrWifiRouterCtrlHipReqHandler, + /* 0x0002 */ CsrWifiRouterCtrlMediaStatusReqHandler, + /* 0x0003 */ CsrWifiRouterCtrlMulticastAddressResHandler, + /* 0x0004 */ CsrWifiRouterCtrlPortConfigureReqHandler, + /* 0x0005 */ CsrWifiRouterCtrlQosControlReqHandler, + /* 0x0006 */ CsrWifiRouterCtrlSuspendResHandler, + /* 0x0007 */ CsrWifiRouterCtrlTclasAddReqHandler, + /* 0x0008 */ CsrWifiRouterCtrlResumeResHandler, + /* 0x0009 */ CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler, + /* 0x000A */ CsrWifiRouterCtrlRawSdioInitialiseReqHandler, + /* 0x000B */ CsrWifiRouterCtrlTclasDelReqHandler, + /* 0x000C */ CsrWifiRouterCtrlTrafficClassificationReqHandler, + /* 0x000D */ CsrWifiRouterCtrlTrafficConfigReqHandler, + /* 0x000E */ CsrWifiRouterCtrlWifiOffReqHandler, + /* 0x000F */ CsrWifiRouterCtrlWifiOffResHandler, + /* 0x0010 */ CsrWifiRouterCtrlWifiOnReqHandler, + /* 0x0011 */ CsrWifiRouterCtrlWifiOnResHandler, + /* 0x0012 */ CsrWifiRouterCtrlM4TransmitReqHandler, + /* 0x0013 */ CsrWifiRouterCtrlModeSetReqHandler, + /* 0x0014 */ CsrWifiRouterCtrlPeerAddReqHandler, + /* 0x0015 */ CsrWifiRouterCtrlPeerDelReqHandler, + /* 0x0016 */ CsrWifiRouterCtrlPeerUpdateReqHandler, + /* 0x0017 */ CsrWifiRouterCtrlCapabilitiesReqHandler, + /* 0x0018 */ CsrWifiRouterCtrlBlockAckEnableReqHandler, + /* 0x0019 */ CsrWifiRouterCtrlBlockAckDisableReqHandler, + /* 0x001A */ CsrWifiRouterCtrlWapiRxPktReqHandler, + /* 0x001B */ CsrWifiRouterCtrlWapiMulticastFilterReqHandler, + /* 0x001C */ CsrWifiRouterCtrlWapiUnicastFilterReqHandler, + /* 0x001D */ CsrWifiRouterCtrlWapiUnicastTxPktReqHandler, + /* 0x001E */ CsrWifiRouterCtrlWapiFilterReqHandler, }; -- cgit v1.2.3 From 906836f6e3ebed0e6a51b8f3aff0a5b2885c9ca9 Mon Sep 17 00:00:00 2001 From: Jugwan Eom Date: Thu, 18 Oct 2012 22:00:42 +0900 Subject: Staging: csr: csr_wifi_router_ctrl_sef.c: fix line over 80 characters This patch fixes line over 80 characters problem found by checkpatch.pl tool. Signed-off-by: Jugwan Eom Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_router_ctrl_sef.c | 66 +++++++++++++------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c index 75b80ad33d8..99cf93061d1 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_sef.c +++ b/drivers/staging/csr/csr_wifi_router_ctrl_sef.c @@ -9,36 +9,38 @@ *****************************************************************************/ #include "csr_wifi_router_ctrl_sef.h" -const CsrWifiRouterCtrlStateHandlerType CsrWifiRouterCtrlDownstreamStateHandlers[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT] = { - /* 0x0000 */ CsrWifiRouterCtrlConfigurePowerModeReqHandler, - /* 0x0001 */ CsrWifiRouterCtrlHipReqHandler, - /* 0x0002 */ CsrWifiRouterCtrlMediaStatusReqHandler, - /* 0x0003 */ CsrWifiRouterCtrlMulticastAddressResHandler, - /* 0x0004 */ CsrWifiRouterCtrlPortConfigureReqHandler, - /* 0x0005 */ CsrWifiRouterCtrlQosControlReqHandler, - /* 0x0006 */ CsrWifiRouterCtrlSuspendResHandler, - /* 0x0007 */ CsrWifiRouterCtrlTclasAddReqHandler, - /* 0x0008 */ CsrWifiRouterCtrlResumeResHandler, - /* 0x0009 */ CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler, - /* 0x000A */ CsrWifiRouterCtrlRawSdioInitialiseReqHandler, - /* 0x000B */ CsrWifiRouterCtrlTclasDelReqHandler, - /* 0x000C */ CsrWifiRouterCtrlTrafficClassificationReqHandler, - /* 0x000D */ CsrWifiRouterCtrlTrafficConfigReqHandler, - /* 0x000E */ CsrWifiRouterCtrlWifiOffReqHandler, - /* 0x000F */ CsrWifiRouterCtrlWifiOffResHandler, - /* 0x0010 */ CsrWifiRouterCtrlWifiOnReqHandler, - /* 0x0011 */ CsrWifiRouterCtrlWifiOnResHandler, - /* 0x0012 */ CsrWifiRouterCtrlM4TransmitReqHandler, - /* 0x0013 */ CsrWifiRouterCtrlModeSetReqHandler, - /* 0x0014 */ CsrWifiRouterCtrlPeerAddReqHandler, - /* 0x0015 */ CsrWifiRouterCtrlPeerDelReqHandler, - /* 0x0016 */ CsrWifiRouterCtrlPeerUpdateReqHandler, - /* 0x0017 */ CsrWifiRouterCtrlCapabilitiesReqHandler, - /* 0x0018 */ CsrWifiRouterCtrlBlockAckEnableReqHandler, - /* 0x0019 */ CsrWifiRouterCtrlBlockAckDisableReqHandler, - /* 0x001A */ CsrWifiRouterCtrlWapiRxPktReqHandler, - /* 0x001B */ CsrWifiRouterCtrlWapiMulticastFilterReqHandler, - /* 0x001C */ CsrWifiRouterCtrlWapiUnicastFilterReqHandler, - /* 0x001D */ CsrWifiRouterCtrlWapiUnicastTxPktReqHandler, - /* 0x001E */ CsrWifiRouterCtrlWapiFilterReqHandler, +const CsrWifiRouterCtrlStateHandlerType + CsrWifiRouterCtrlDownstreamStateHandlers + [CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT] = { + /* 0x0000 */ CsrWifiRouterCtrlConfigurePowerModeReqHandler, + /* 0x0001 */ CsrWifiRouterCtrlHipReqHandler, + /* 0x0002 */ CsrWifiRouterCtrlMediaStatusReqHandler, + /* 0x0003 */ CsrWifiRouterCtrlMulticastAddressResHandler, + /* 0x0004 */ CsrWifiRouterCtrlPortConfigureReqHandler, + /* 0x0005 */ CsrWifiRouterCtrlQosControlReqHandler, + /* 0x0006 */ CsrWifiRouterCtrlSuspendResHandler, + /* 0x0007 */ CsrWifiRouterCtrlTclasAddReqHandler, + /* 0x0008 */ CsrWifiRouterCtrlResumeResHandler, + /* 0x0009 */ CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler, + /* 0x000A */ CsrWifiRouterCtrlRawSdioInitialiseReqHandler, + /* 0x000B */ CsrWifiRouterCtrlTclasDelReqHandler, + /* 0x000C */ CsrWifiRouterCtrlTrafficClassificationReqHandler, + /* 0x000D */ CsrWifiRouterCtrlTrafficConfigReqHandler, + /* 0x000E */ CsrWifiRouterCtrlWifiOffReqHandler, + /* 0x000F */ CsrWifiRouterCtrlWifiOffResHandler, + /* 0x0010 */ CsrWifiRouterCtrlWifiOnReqHandler, + /* 0x0011 */ CsrWifiRouterCtrlWifiOnResHandler, + /* 0x0012 */ CsrWifiRouterCtrlM4TransmitReqHandler, + /* 0x0013 */ CsrWifiRouterCtrlModeSetReqHandler, + /* 0x0014 */ CsrWifiRouterCtrlPeerAddReqHandler, + /* 0x0015 */ CsrWifiRouterCtrlPeerDelReqHandler, + /* 0x0016 */ CsrWifiRouterCtrlPeerUpdateReqHandler, + /* 0x0017 */ CsrWifiRouterCtrlCapabilitiesReqHandler, + /* 0x0018 */ CsrWifiRouterCtrlBlockAckEnableReqHandler, + /* 0x0019 */ CsrWifiRouterCtrlBlockAckDisableReqHandler, + /* 0x001A */ CsrWifiRouterCtrlWapiRxPktReqHandler, + /* 0x001B */ CsrWifiRouterCtrlWapiMulticastFilterReqHandler, + /* 0x001C */ CsrWifiRouterCtrlWapiUnicastFilterReqHandler, + /* 0x001D */ CsrWifiRouterCtrlWapiUnicastTxPktReqHandler, + /* 0x001E */ CsrWifiRouterCtrlWapiFilterReqHandler, }; -- cgit v1.2.3 From 9385f21b293d6bd37078154bc9d4f193c106176b Mon Sep 17 00:00:00 2001 From: Sunhee Hwang Date: Thu, 18 Oct 2012 23:10:09 +0900 Subject: Staging: csr: fix code indent coding style issues in csr_wifi_hip_signals.h This is a patch that fixes up code indent coding style warnings in the csr_wifi_hip_signals.h found by checkpatch.pl tool. Signed-off-by: Sunhee Hwang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_hip_signals.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_hip_signals.h b/drivers/staging/csr/csr_wifi_hip_signals.h index 5f841556bbe..ebe2f6d9ea8 100644 --- a/drivers/staging/csr/csr_wifi_hip_signals.h +++ b/drivers/staging/csr/csr_wifi_hip_signals.h @@ -1,10 +1,10 @@ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2011 - All rights reserved and confidential information of CSR + (c) Cambridge Silicon Radio Limited 2011 + All rights reserved and confidential information of CSR - Refer to LICENSE.txt included with this source for details - on the license terms. + Refer to LICENSE.txt included with this source for details + on the license terms. *****************************************************************************/ -- cgit v1.2.3 From fc4e2514995d9cd7f3e1a67098ce65d72acf8ec7 Mon Sep 17 00:00:00 2001 From: Ryan Mallon Date: Mon, 22 Oct 2012 11:39:12 +1100 Subject: gpiolib: Refactor gpio_export The gpio_export function uses nested if statements and the status variable to handle the failure cases. This makes the function logic difficult to follow. Refactor the code to abort immediately on failure using goto. This makes the code slightly longer, but significantly reduces the nesting and number of split lines and makes the code easier to read. Signed-off-by: Ryan Mallon Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 85 +++++++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5d6c71edc73..d5f9742d9ac 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -702,8 +702,9 @@ int gpio_export(unsigned gpio, bool direction_may_change) { unsigned long flags; struct gpio_desc *desc; - int status = -EINVAL; + int status; const char *ioname = NULL; + struct device *dev; /* can't export until sysfs is available ... */ if (!gpio_class.p) { @@ -711,59 +712,65 @@ int gpio_export(unsigned gpio, bool direction_may_change) return -ENOENT; } - if (!gpio_is_valid(gpio)) - goto done; + if (!gpio_is_valid(gpio)) { + pr_debug("%s: gpio %d is not valid\n", __func__, gpio); + return -EINVAL; + } mutex_lock(&sysfs_lock); spin_lock_irqsave(&gpio_lock, flags); desc = &gpio_desc[gpio]; - if (test_bit(FLAG_REQUESTED, &desc->flags) - && !test_bit(FLAG_EXPORT, &desc->flags)) { - status = 0; - if (!desc->chip->direction_input - || !desc->chip->direction_output) - direction_may_change = false; + if (!test_bit(FLAG_REQUESTED, &desc->flags) || + test_bit(FLAG_EXPORT, &desc->flags)) { + spin_unlock_irqrestore(&gpio_lock, flags); + pr_debug("%s: gpio %d unavailable (requested=%d, exported=%d)\n", + __func__, gpio, + test_bit(FLAG_REQUESTED, &desc->flags), + test_bit(FLAG_EXPORT, &desc->flags)); + return -EPERM; } + + if (!desc->chip->direction_input || !desc->chip->direction_output) + direction_may_change = false; spin_unlock_irqrestore(&gpio_lock, flags); if (desc->chip->names && desc->chip->names[gpio - desc->chip->base]) ioname = desc->chip->names[gpio - desc->chip->base]; - if (status == 0) { - struct device *dev; - - dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), - desc, ioname ? ioname : "gpio%u", gpio); - if (!IS_ERR(dev)) { - status = sysfs_create_group(&dev->kobj, - &gpio_attr_group); - - if (!status && direction_may_change) - status = device_create_file(dev, - &dev_attr_direction); - - if (!status && gpio_to_irq(gpio) >= 0 - && (direction_may_change - || !test_bit(FLAG_IS_OUT, - &desc->flags))) - status = device_create_file(dev, - &dev_attr_edge); - - if (status != 0) - device_unregister(dev); - } else - status = PTR_ERR(dev); - if (status == 0) - set_bit(FLAG_EXPORT, &desc->flags); + dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), + desc, ioname ? ioname : "gpio%u", gpio); + if (IS_ERR(dev)) { + status = PTR_ERR(dev); + goto fail_unlock; } - mutex_unlock(&sysfs_lock); - -done: + status = sysfs_create_group(&dev->kobj, &gpio_attr_group); if (status) - pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); + goto fail_unregister_device; + + if (direction_may_change) { + status = device_create_file(dev, &dev_attr_direction); + if (status) + goto fail_unregister_device; + } + if (gpio_to_irq(gpio) >= 0 && (direction_may_change || + !test_bit(FLAG_IS_OUT, &desc->flags))) { + status = device_create_file(dev, &dev_attr_edge); + if (status) + goto fail_unregister_device; + } + + set_bit(FLAG_EXPORT, &desc->flags); + mutex_unlock(&sysfs_lock); + return 0; + +fail_unregister_device: + device_unregister(dev); +fail_unlock: + mutex_unlock(&sysfs_lock); + pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); return status; } EXPORT_SYMBOL_GPL(gpio_export); -- cgit v1.2.3 From 720a9bece0c132a9095e997969f07d8694816bbc Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 11 Oct 2012 17:21:03 +0100 Subject: staging: dgrp: fix some warnings Just squashing these to get them out of the analysis queue. nd_ps_desc is an array not a pointer so comparing it with NULL is silly (be nice if gcc shouted about this). And there are some slightly pointless comparisons too. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgrp/dgrp_dpa_ops.c | 2 +- drivers/staging/dgrp/dgrp_net_ops.c | 3 +++ drivers/staging/dgrp/dgrp_sysfs.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/staging/dgrp/dgrp_dpa_ops.c b/drivers/staging/dgrp/dgrp_dpa_ops.c index 49e670915e5..021cca498f2 100644 --- a/drivers/staging/dgrp/dgrp_dpa_ops.c +++ b/drivers/staging/dgrp/dgrp_dpa_ops.c @@ -387,7 +387,7 @@ static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd, port = getchan.ch_port; - if (port < 0 || port > nd->nd_chan_count) + if (port > nd->nd_chan_count) return -EINVAL; ch = nd->nd_chan + port; diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index ab839ea3b44..067d9755544 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c @@ -1671,6 +1671,9 @@ static int dgrp_send(struct nd_struct *nd, long tmax) * do the job. */ + /* FIXME: jiffies - ch->ch_waketime can never + be < 0. Someone needs to work out what is + actually intended here */ if (ch->ch_pun.un_open_count && (ch->ch_pun.un_flag & (UN_EMPTY|UN_TIME|UN_LOW|UN_PWAIT)) != 0) { diff --git a/drivers/staging/dgrp/dgrp_sysfs.c b/drivers/staging/dgrp/dgrp_sysfs.c index e5a3c88d016..129be3caa97 100644 --- a/drivers/staging/dgrp/dgrp_sysfs.c +++ b/drivers/staging/dgrp/dgrp_sysfs.c @@ -177,7 +177,7 @@ static ssize_t dgrp_node_description_show(struct device *c, if (!nd) return 0; - if (nd->nd_state == NS_READY && nd->nd_ps_desc) + if (nd->nd_state == NS_READY) return snprintf(buf, PAGE_SIZE, "%s\n", nd->nd_ps_desc); return 0; } -- cgit v1.2.3 From b1a4fddea0eeceacc15cb53a920cfbf4754b6ad2 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 11 Oct 2012 17:23:18 +0100 Subject: staging: silicom: pointless check removal bus_info is an array not a pointer. Fix silly if check Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bp_mod.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index 3cfd0516adf..f579f143f85 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -5454,8 +5454,6 @@ static void if_scan_init(void) dev->ethtool_ops->get_drvinfo(dev, &drvinfo); } else continue; - if (!drvinfo.bus_info) - continue; if (!strcmp(drvinfo.bus_info, "N/A")) continue; memcpy(&cbuf, drvinfo.bus_info, 32); @@ -7703,13 +7701,8 @@ get_bypass_slave_pfs(char *page, char **start, off_t off, int count, return len; } net_slave_dev = pbp_device_block_slave->ndev; - if (net_slave_dev) { - if (net_slave_dev) - len = sprintf(page, "%s\n", net_slave_dev->name); - else - len = sprintf(page, "fail\n"); - - } + if (net_slave_dev) + len = sprintf(page, "%s\n", net_slave_dev->name); *eof = 1; return len; -- cgit v1.2.3 From 0f562d16460ef80cb05e4fc4f6a8a1e772c901da Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Thu, 11 Oct 2012 23:06:43 -0500 Subject: drm/omap: Remove shadow lut usage Removing extraneous shadow lut maintenance. There is no need for this to be in place until power management is added to the driver, and this extra copy degrades performance for no gain. Signed-off-by: Andy Gross Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_dmm_priv.h | 6 ------ drivers/staging/omapdrm/omap_dmm_tiler.c | 24 +----------------------- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h b/drivers/staging/omapdrm/omap_dmm_priv.h index 08b22e9f0ed..09ebc50784d 100644 --- a/drivers/staging/omapdrm/omap_dmm_priv.h +++ b/drivers/staging/omapdrm/omap_dmm_priv.h @@ -141,9 +141,6 @@ struct refill_engine { /* only one trans per engine for now */ struct dmm_txn txn; - /* offset to lut associated with container */ - u32 *lut_offset; - wait_queue_head_t wait_for_refill; struct list_head idle_node; @@ -176,9 +173,6 @@ struct dmm { /* array of LUT - TCM containers */ struct tcm **tcm; - /* LUT table storage */ - u32 *lut; - /* allocation list and lock */ struct list_head alloc_head; }; diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index 3ae39554df1..fda9efc7bd0 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -184,9 +184,6 @@ static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area, int columns = (1 + area->x1 - area->x0); int rows = (1 + area->y1 - area->y0); int i = columns*rows; - u32 *lut = omap_dmm->lut + (engine->tcm->lut_id * omap_dmm->lut_width * - omap_dmm->lut_height) + - (area->y0 * omap_dmm->lut_width) + area->x0; pat = alloc_dma(txn, sizeof(struct pat), &pat_pa); @@ -209,10 +206,6 @@ static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area, page_to_phys(pages[n]) : engine->dmm->dummy_pa; } - /* fill in lut with new addresses */ - for (i = 0; i < rows; i++, lut += omap_dmm->lut_width) - memcpy(lut, &data[i*columns], columns * sizeof(u32)); - txn->last_pat = pat; return 0; @@ -539,8 +532,6 @@ static int omap_dmm_remove(struct platform_device *dev) if (omap_dmm->dummy_page) __free_page(omap_dmm->dummy_page); - vfree(omap_dmm->lut); - if (omap_dmm->irq > 0) free_irq(omap_dmm->irq, omap_dmm); @@ -556,7 +547,7 @@ static int omap_dmm_probe(struct platform_device *dev) { int ret = -EFAULT, i; struct tcm_area area = {0}; - u32 hwinfo, pat_geom, lut_table_size; + u32 hwinfo, pat_geom; struct resource *mem; omap_dmm = kzalloc(sizeof(*omap_dmm), GFP_KERNEL); @@ -628,16 +619,6 @@ static int omap_dmm_probe(struct platform_device *dev) */ writel(0x7e7e7e7e, omap_dmm->base + DMM_PAT_IRQENABLE_SET); - lut_table_size = omap_dmm->lut_width * omap_dmm->lut_height * - omap_dmm->num_lut; - - omap_dmm->lut = vmalloc(lut_table_size * sizeof(*omap_dmm->lut)); - if (!omap_dmm->lut) { - dev_err(&dev->dev, "could not allocate lut table\n"); - ret = -ENOMEM; - goto fail; - } - omap_dmm->dummy_page = alloc_page(GFP_KERNEL | __GFP_DMA32); if (!omap_dmm->dummy_page) { dev_err(&dev->dev, "could not allocate dummy page\n"); @@ -720,9 +701,6 @@ static int omap_dmm_probe(struct platform_device *dev) .p1.y = omap_dmm->container_height - 1, }; - for (i = 0; i < lut_table_size; i++) - omap_dmm->lut[i] = omap_dmm->dummy_pa; - /* initialize all LUTs to dummy page entries */ for (i = 0; i < omap_dmm->num_lut; i++) { area.tcm = omap_dmm->tcm[i]; -- cgit v1.2.3 From fe4fc163dfe246f6dccb003eda7a8238fbc574e1 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Thu, 11 Oct 2012 23:07:36 -0500 Subject: drm/omap: Use writecombine for descriptors Use writecombine for descriptor and PAT programming memory. Signed-off-by: Andy Gross Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_dmm_tiler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index fda9efc7bd0..7c19c5c7832 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -525,7 +525,7 @@ static int omap_dmm_remove(struct platform_device *dev) kfree(omap_dmm->engines); if (omap_dmm->refill_va) - dma_free_coherent(omap_dmm->dev, + dma_free_writecombine(omap_dmm->dev, REFILL_BUFFER_SIZE * omap_dmm->num_engines, omap_dmm->refill_va, omap_dmm->refill_pa); @@ -633,7 +633,7 @@ static int omap_dmm_probe(struct platform_device *dev) omap_dmm->dummy_pa = page_to_phys(omap_dmm->dummy_page); /* alloc refill memory */ - omap_dmm->refill_va = dma_alloc_coherent(&dev->dev, + omap_dmm->refill_va = dma_alloc_writecombine(&dev->dev, REFILL_BUFFER_SIZE * omap_dmm->num_engines, &omap_dmm->refill_pa, GFP_KERNEL); if (!omap_dmm->refill_va) { -- cgit v1.2.3 From faaa054036e395d4e847d1dac49a55b7ef85f500 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Fri, 12 Oct 2012 11:18:11 -0500 Subject: drm/omap: Fix release of refill engine During asynchronous refills, we don't wait for the refill to finish. However, we cannot release the engine back to the idle list until it has actually completed the refill operation. The engine release will now be done in the IRQ handler, but only for asynchronous refill operations. Synchronous refills will continue to release the engine after they unblock from waiting on the refill. v2: Fixed review comments on async variable and bool type Signed-off-by: Andy Gross Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_dmm_priv.h | 5 ++- drivers/staging/omapdrm/omap_dmm_tiler.c | 76 ++++++++++++++++++++++---------- 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/drivers/staging/omapdrm/omap_dmm_priv.h b/drivers/staging/omapdrm/omap_dmm_priv.h index 09ebc50784d..273ec12c028 100644 --- a/drivers/staging/omapdrm/omap_dmm_priv.h +++ b/drivers/staging/omapdrm/omap_dmm_priv.h @@ -141,6 +141,8 @@ struct refill_engine { /* only one trans per engine for now */ struct dmm_txn txn; + bool async; + wait_queue_head_t wait_for_refill; struct list_head idle_node; @@ -158,10 +160,11 @@ struct dmm { dma_addr_t refill_pa; /* refill engines */ - struct semaphore engine_sem; + wait_queue_head_t engine_queue; struct list_head idle_head; struct refill_engine *engines; int num_engines; + atomic_t engine_counter; /* container information */ int container_width; diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index 7c19c5c7832..7d3b7d441c6 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -29,7 +29,6 @@ #include #include #include -#include #include "omap_dmm_tiler.h" #include "omap_dmm_priv.h" @@ -120,6 +119,18 @@ static int wait_status(struct refill_engine *engine, uint32_t wait_mask) return 0; } +static void release_engine(struct refill_engine *engine) +{ + unsigned long flags; + + spin_lock_irqsave(&list_lock, flags); + list_add(&engine->idle_node, &omap_dmm->idle_head); + spin_unlock_irqrestore(&list_lock, flags); + + atomic_inc(&omap_dmm->engine_counter); + wake_up_interruptible(&omap_dmm->engine_queue); +} + static irqreturn_t omap_dmm_irq_handler(int irq, void *arg) { struct dmm *dmm = arg; @@ -130,9 +141,13 @@ static irqreturn_t omap_dmm_irq_handler(int irq, void *arg) writel(status, dmm->base + DMM_PAT_IRQSTATUS); for (i = 0; i < dmm->num_engines; i++) { - if (status & DMM_IRQSTAT_LST) + if (status & DMM_IRQSTAT_LST) { wake_up_interruptible(&dmm->engines[i].wait_for_refill); + if (dmm->engines[i].async) + release_engine(&dmm->engines[i]); + } + status >>= 8; } @@ -146,17 +161,24 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm) { struct dmm_txn *txn = NULL; struct refill_engine *engine = NULL; + int ret; + unsigned long flags; - down(&dmm->engine_sem); + + /* wait until an engine is available */ + ret = wait_event_interruptible(omap_dmm->engine_queue, + atomic_add_unless(&omap_dmm->engine_counter, -1, 0)); + if (ret) + return ERR_PTR(ret); /* grab an idle engine */ - spin_lock(&list_lock); + spin_lock_irqsave(&list_lock, flags); if (!list_empty(&dmm->idle_head)) { engine = list_entry(dmm->idle_head.next, struct refill_engine, idle_node); list_del(&engine->idle_node); } - spin_unlock(&list_lock); + spin_unlock_irqrestore(&list_lock, flags); BUG_ON(!engine); @@ -174,7 +196,7 @@ static struct dmm_txn *dmm_txn_init(struct dmm *dmm, struct tcm *tcm) * Add region to DMM transaction. If pages or pages[i] is NULL, then the * corresponding slot is cleared (ie. dummy_pa is programmed) */ -static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area, +static void dmm_txn_append(struct dmm_txn *txn, struct pat_area *area, struct page **pages, uint32_t npages, uint32_t roll) { dma_addr_t pat_pa = 0; @@ -208,7 +230,7 @@ static int dmm_txn_append(struct dmm_txn *txn, struct pat_area *area, txn->last_pat = pat; - return 0; + return; } /** @@ -238,6 +260,9 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait) goto cleanup; } + /* mark whether it is async to denote list management in IRQ handler */ + engine->async = wait ? false : true; + /* kick reload */ writel(engine->refill_pa, dmm->base + reg[PAT_DESCR][engine->id]); @@ -252,11 +277,10 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait) } cleanup: - spin_lock(&list_lock); - list_add(&engine->idle_node, &dmm->idle_head); - spin_unlock(&list_lock); + /* only place engine back on list if we are done with it */ + if (ret || wait) + release_engine(engine); - up(&omap_dmm->engine_sem); return ret; } @@ -280,16 +304,13 @@ static int fill(struct tcm_area *area, struct page **pages, .x1 = slice.p1.x, .y1 = slice.p1.y, }; - ret = dmm_txn_append(txn, &p_area, pages, npages, roll); - if (ret) - goto fail; + dmm_txn_append(txn, &p_area, pages, npages, roll); roll += tcm_sizeof(slice); } ret = dmm_txn_commit(txn, wait); -fail: return ret; } @@ -326,6 +347,7 @@ struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, uint16_t w, struct tiler_block *block = kzalloc(sizeof(*block), GFP_KERNEL); u32 min_align = 128; int ret; + unsigned long flags; BUG_ON(!validfmt(fmt)); @@ -347,9 +369,9 @@ struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, uint16_t w, } /* add to allocation list */ - spin_lock(&list_lock); + spin_lock_irqsave(&list_lock, flags); list_add(&block->alloc_node, &omap_dmm->alloc_head); - spin_unlock(&list_lock); + spin_unlock_irqrestore(&list_lock, flags); return block; } @@ -358,6 +380,7 @@ struct tiler_block *tiler_reserve_1d(size_t size) { struct tiler_block *block = kzalloc(sizeof(*block), GFP_KERNEL); int num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; + unsigned long flags; if (!block) return ERR_PTR(-ENOMEM); @@ -370,9 +393,9 @@ struct tiler_block *tiler_reserve_1d(size_t size) return ERR_PTR(-ENOMEM); } - spin_lock(&list_lock); + spin_lock_irqsave(&list_lock, flags); list_add(&block->alloc_node, &omap_dmm->alloc_head); - spin_unlock(&list_lock); + spin_unlock_irqrestore(&list_lock, flags); return block; } @@ -381,13 +404,14 @@ struct tiler_block *tiler_reserve_1d(size_t size) int tiler_release(struct tiler_block *block) { int ret = tcm_free(&block->area); + unsigned long flags; if (block->area.tcm) dev_err(omap_dmm->dev, "failed to release block\n"); - spin_lock(&list_lock); + spin_lock_irqsave(&list_lock, flags); list_del(&block->alloc_node); - spin_unlock(&list_lock); + spin_unlock_irqrestore(&list_lock, flags); kfree(block); return ret; @@ -507,16 +531,17 @@ static int omap_dmm_remove(struct platform_device *dev) { struct tiler_block *block, *_block; int i; + unsigned long flags; if (omap_dmm) { /* free all area regions */ - spin_lock(&list_lock); + spin_lock_irqsave(&list_lock, flags); list_for_each_entry_safe(block, _block, &omap_dmm->alloc_head, alloc_node) { list_del(&block->alloc_node); kfree(block); } - spin_unlock(&list_lock); + spin_unlock_irqrestore(&list_lock, flags); for (i = 0; i < omap_dmm->num_lut; i++) if (omap_dmm->tcm && omap_dmm->tcm[i]) @@ -560,6 +585,8 @@ static int omap_dmm_probe(struct platform_device *dev) INIT_LIST_HEAD(&omap_dmm->alloc_head); INIT_LIST_HEAD(&omap_dmm->idle_head); + init_waitqueue_head(&omap_dmm->engine_queue); + /* lookup hwmod data - base address and irq */ mem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!mem) { @@ -588,6 +615,8 @@ static int omap_dmm_probe(struct platform_device *dev) omap_dmm->container_width = 256; omap_dmm->container_height = 128; + atomic_set(&omap_dmm->engine_counter, omap_dmm->num_engines); + /* read out actual LUT width and height */ pat_geom = readl(omap_dmm->base + DMM_PAT_GEOMETRY); omap_dmm->lut_width = ((pat_geom >> 16) & 0xF) << 5; @@ -651,7 +680,6 @@ static int omap_dmm_probe(struct platform_device *dev) goto fail; } - sema_init(&omap_dmm->engine_sem, omap_dmm->num_engines); for (i = 0; i < omap_dmm->num_engines; i++) { omap_dmm->engines[i].id = i; omap_dmm->engines[i].dmm = omap_dmm; -- cgit v1.2.3 From b74af83dd289270e1486cf5d9f0e3e894c76bd30 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 12 Oct 2012 18:58:02 -0500 Subject: drm/omap: fix issue w/ fb attached to multiple CRTCs When the fb is detached from one CRTC/plane, paddr was set back to zero. But really we don't want to do this because the fb could still be attached to other CRTC/plane(s). This originally worked like this to catch cases of freeing a pinned fb (but with the refcnt'ing this should no longer be needed). Also, there is checking in the GEM code for freeing a pinned GEM object, so this extra level of checking is redundant. Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_fb.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/omapdrm/omap_fb.c b/drivers/staging/omapdrm/omap_fb.c index 446801d6300..75d2ff1bf8a 100644 --- a/drivers/staging/omapdrm/omap_fb.c +++ b/drivers/staging/omapdrm/omap_fb.c @@ -253,6 +253,7 @@ int omap_framebuffer_replace(struct drm_framebuffer *a, int ret = 0, i, na, nb; struct omap_framebuffer *ofba = to_omap_framebuffer(a); struct omap_framebuffer *ofbb = to_omap_framebuffer(b); + uint32_t pinned_mask = 0; na = a ? drm_format_num_planes(a->pixel_format) : 0; nb = b ? drm_format_num_planes(b->pixel_format) : 0; @@ -263,25 +264,24 @@ int omap_framebuffer_replace(struct drm_framebuffer *a, pa = (i < na) ? &ofba->planes[i] : NULL; pb = (i < nb) ? &ofbb->planes[i] : NULL; - if (pa) { + if (pa) unpin(arg, pa->bo); - pa->paddr = 0; - } if (pb && !ret) { ret = omap_gem_get_paddr(pb->bo, &pb->paddr, true); - if (!ret) + if (!ret) { omap_gem_dma_sync(pb->bo, DMA_TO_DEVICE); + pinned_mask |= (1 << i); + } } } if (ret) { /* something went wrong.. unpin what has been pinned */ for (i = 0; i < nb; i++) { - struct plane *pb = &ofba->planes[i]; - if (pb->paddr) { + if (pinned_mask & (1 << i)) { + struct plane *pb = &ofba->planes[i]; unpin(arg, pb->bo); - pb->paddr = 0; } } } -- cgit v1.2.3 From 19c1fb1375b97bd7d6904aaef3dc8cf6d433450c Mon Sep 17 00:00:00 2001 From: Chad Williamson Date: Mon, 15 Oct 2012 05:30:35 -0500 Subject: staging: silicom: fix whitespace in bp_proc.c Remove superfluous spaces in bp_proc.c to resolve checkpatch.pl errors. Signed-off-by: Chad Williamson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bp_proc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/silicom/bp_proc.c b/drivers/staging/silicom/bp_proc.c index 6ad4b27472e..f7b4699e574 100644 --- a/drivers/staging/silicom/bp_proc.c +++ b/drivers/staging/silicom/bp_proc.c @@ -11,7 +11,7 @@ /******************************************************************************/ #include -#if defined(CONFIG_SMP) && ! defined(__SMP__) +#if defined(CONFIG_SMP) && !defined(__SMP__) #define __SMP__ #endif @@ -24,7 +24,7 @@ #define BP_PROC_DIR "bypass" //#define BYPASS_SUPPORT "bypass" -#ifdef BYPASS_SUPPORT +#ifdef BYPASS_SUPPORT #define GPIO6_SET_ENTRY_SD "gpio6_set" #define GPIO6_CLEAR_ENTRY_SD "gpio6_clear" @@ -98,8 +98,8 @@ static struct proc_dir_entry *proc_getdir(char *name, int bypass_proc_create_entry_sd(struct pfs_unit *pfs_unit_curr, char *proc_name, - write_proc_t * write_proc, - read_proc_t * read_proc, + write_proc_t *write_proc, + read_proc_t *read_proc, struct proc_dir_entry *parent_pfs, void *data) { strcpy(pfs_unit_curr->proc_name, proc_name); @@ -1147,7 +1147,7 @@ set_hw_reset_pfs(struct file *file, const char *buffer, #endif /*PMC_FIX_FLAG */ -int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block) +int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block) { struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set); static struct proc_dir_entry *procfs_dir = NULL; @@ -1327,7 +1327,7 @@ int bypass_proc_create_dev_sd(bpctl_dev_t * pbp_device_block) return ret; } -int bypass_proc_remove_dev_sd(bpctl_dev_t * pbp_device_block) +int bypass_proc_remove_dev_sd(bpctl_dev_t *pbp_device_block) { struct bypass_pfs_sd *current_pfs = &pbp_device_block->bypass_pfs_set; -- cgit v1.2.3 From 1713eaf7fc12e19cfdec10a0ef6fa6d7907e6630 Mon Sep 17 00:00:00 2001 From: Chad Williamson Date: Mon, 15 Oct 2012 05:30:36 -0500 Subject: staging: silicom: fix C99 comments in bp_proc.c Fix C99 // comments in bp_proc.c to resolve checkpatch.pl errors. Signed-off-by: Chad Williamson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bp_proc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/silicom/bp_proc.c b/drivers/staging/silicom/bp_proc.c index f7b4699e574..4599cc930f6 100644 --- a/drivers/staging/silicom/bp_proc.c +++ b/drivers/staging/silicom/bp_proc.c @@ -18,11 +18,11 @@ #include #include #include -//#include +/* #include */ #include "bp_mod.h" #define BP_PROC_DIR "bypass" -//#define BYPASS_SUPPORT "bypass" +/* #define BYPASS_SUPPORT "bypass" */ #ifdef BYPASS_SUPPORT @@ -70,7 +70,7 @@ #define DISC_CHANGE_ENTRY_SD "disc_change" #define DIS_DISC_ENTRY_SD "dis_disc" #define DISC_PWUP_ENTRY_SD "disc_pwup" -#endif //bypass_support +#endif /* bypass_support */ static struct proc_dir_entry *bp_procfs_dir; static struct proc_dir_entry *proc_getdir(char *name, -- cgit v1.2.3 From ed5054b6f395b5524e2a9d5e0e6302fc7ac2481a Mon Sep 17 00:00:00 2001 From: Chad Williamson Date: Mon, 15 Oct 2012 05:30:37 -0500 Subject: staging: silicom: remove parentheses from return statements in bg_proc.c Remove unnecessary parentheses from return statements in bg_proc.c to resolve checkpatch.pl errors. Signed-off-by: Chad Williamson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bp_proc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/silicom/bp_proc.c b/drivers/staging/silicom/bp_proc.c index 4599cc930f6..aa084ef279e 100644 --- a/drivers/staging/silicom/bp_proc.c +++ b/drivers/staging/silicom/bp_proc.c @@ -87,10 +87,10 @@ static struct proc_dir_entry *proc_getdir(char *name, /* create the directory */ pde = create_proc_entry(name, S_IFDIR, proc_dir); if (pde == (struct proc_dir_entry *)0) { - return (pde); + return pde; } } - return (pde); + return pde; } #ifdef BYPASS_SUPPORT -- cgit v1.2.3 From c460c7d9469624c44d2df9ee09a4141135fb2145 Mon Sep 17 00:00:00 2001 From: Chad Williamson Date: Mon, 15 Oct 2012 05:30:38 -0500 Subject: staging: silicom: remove unnecessary braces in bp_proc.c Remove unnecessary braces from single statement blocks in bp_proc.c, resolving checkpatch.pl warnings. Signed-off-by: Chad Williamson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bp_proc.c | 58 +++++++++++++-------------------------- 1 file changed, 19 insertions(+), 39 deletions(-) diff --git a/drivers/staging/silicom/bp_proc.c b/drivers/staging/silicom/bp_proc.c index aa084ef279e..0f110aa38dd 100644 --- a/drivers/staging/silicom/bp_proc.c +++ b/drivers/staging/silicom/bp_proc.c @@ -86,9 +86,8 @@ static struct proc_dir_entry *proc_getdir(char *name, if (pde == (struct proc_dir_entry *)0) { /* create the directory */ pde = create_proc_entry(name, S_IFDIR, proc_dir); - if (pde == (struct proc_dir_entry *)0) { + if (pde == (struct proc_dir_entry *)0) return pde; - } } return pde; } @@ -107,10 +106,8 @@ bypass_proc_create_entry_sd(struct pfs_unit *pfs_unit_curr, S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, parent_pfs); - if (pfs_unit_curr->proc_entry == 0) { - + if (pfs_unit_curr->proc_entry == 0) return -1; - } pfs_unit_curr->proc_entry->read_proc = read_proc; pfs_unit_curr->proc_entry->write_proc = write_proc; @@ -207,9 +204,8 @@ set_bypass_pfs(struct file *file, const char *buffer, if (count > (sizeof(kbuf) - 1)) return -1; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -239,9 +235,8 @@ set_tap_pfs(struct file *file, const char *buffer, if (count > (sizeof(kbuf) - 1)) return -1; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -271,9 +266,8 @@ set_disc_pfs(struct file *file, const char *buffer, if (count > (sizeof(kbuf) - 1)) return -1; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -421,9 +415,8 @@ set_bypass_wd_pfs(struct file *file, const char *buffer, unsigned int timeout = 0; char *timeout_ptr = kbuf; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } timeout_ptr = kbuf; timeout = atoi(&timeout_ptr); @@ -570,9 +563,8 @@ set_dis_bypass_pfs(struct file *file, const char *buffer, int bypass_param = 0, length = 0; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -599,9 +591,8 @@ set_dis_tap_pfs(struct file *file, const char *buffer, int tap_param = 0, length = 0; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -628,9 +619,8 @@ set_dis_disc_pfs(struct file *file, const char *buffer, int tap_param = 0, length = 0; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -717,9 +707,8 @@ set_bypass_pwup_pfs(struct file *file, const char *buffer, int bypass_param = 0, length = 0; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -746,9 +735,8 @@ set_bypass_pwoff_pfs(struct file *file, const char *buffer, int bypass_param = 0, length = 0; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -775,9 +763,8 @@ set_tap_pwup_pfs(struct file *file, const char *buffer, int tap_param = 0, length = 0; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -804,9 +791,8 @@ set_disc_pwup_pfs(struct file *file, const char *buffer, int tap_param = 0, length = 0; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -913,9 +899,8 @@ set_std_nic_pfs(struct file *file, const char *buffer, int bypass_param = 0, length = 0; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -988,9 +973,8 @@ set_wd_exp_mode_pfs(struct file *file, const char *buffer, if (count > (sizeof(kbuf) - 1)) return -1; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -1036,9 +1020,8 @@ set_wd_autoreset_pfs(struct file *file, const char *buffer, u32 timeout = 0; char *timeout_ptr = kbuf; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } timeout_ptr = kbuf; timeout = atoi(&timeout_ptr); @@ -1061,9 +1044,8 @@ set_tpl_pfs(struct file *file, const char *buffer, if (count > (sizeof(kbuf) - 1)) return -1; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -1094,9 +1076,8 @@ set_wait_at_pwup_pfs(struct file *file, const char *buffer, if (count > (sizeof(kbuf) - 1)) return -1; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); @@ -1126,9 +1107,8 @@ set_hw_reset_pfs(struct file *file, const char *buffer, if (count > (sizeof(kbuf) - 1)) return -1; - if (copy_from_user(&kbuf, buffer, count)) { + if (copy_from_user(&kbuf, buffer, count)) return -1; - } kbuf[count] = '\0'; length = strlen(kbuf); -- cgit v1.2.3 From 6b8c8773dcbb4f718e05596739e02abb5b29d7da Mon Sep 17 00:00:00 2001 From: Chad Williamson Date: Mon, 15 Oct 2012 05:30:39 -0500 Subject: staging: silicom: fix explicit intialization of procfs_dir in bp_proc.c Remove explicit intialization of static procfs_dir to NULL, resolving a checkpatch.pl error. Signed-off-by: Chad Williamson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bp_proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/silicom/bp_proc.c b/drivers/staging/silicom/bp_proc.c index 0f110aa38dd..37f998c1c83 100644 --- a/drivers/staging/silicom/bp_proc.c +++ b/drivers/staging/silicom/bp_proc.c @@ -1130,7 +1130,7 @@ set_hw_reset_pfs(struct file *file, const char *buffer, int bypass_proc_create_dev_sd(bpctl_dev_t *pbp_device_block) { struct bypass_pfs_sd *current_pfs = &(pbp_device_block->bypass_pfs_set); - static struct proc_dir_entry *procfs_dir = NULL; + static struct proc_dir_entry *procfs_dir; int ret = 0; sprintf(current_pfs->dir_name, "bypass_%s", dev->name); -- cgit v1.2.3 From 8d64c32b9b2dcf6b647987a04587e55be70c3676 Mon Sep 17 00:00:00 2001 From: Constantine Shulyupin Date: Mon, 15 Oct 2012 18:54:41 +0200 Subject: staging: ccg: rename ccg init and exit functions to conventional names Previous names of init and exit functions "init" and "cleanup" are unconventional and are not friendly for source navigation with tags. New names "ccg_init" and "ccg_exit" are conveninal and source navigation friendly. Signed-off-by: Constantine Shulyupin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ccg/ccg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/ccg/ccg.c b/drivers/staging/ccg/ccg.c index 93e1e2ffca0..ffc5f73a5b5 100644 --- a/drivers/staging/ccg/ccg.c +++ b/drivers/staging/ccg/ccg.c @@ -1239,7 +1239,7 @@ static int ccg_create_device(struct ccg_dev *dev) } -static int __init init(void) +static int __init ccg_init(void) { struct ccg_dev *dev; int err; @@ -1280,13 +1280,13 @@ static int __init init(void) return err; } -module_init(init); +module_init(ccg_init); -static void __exit cleanup(void) +static void __exit ccg_exit(void) { usb_composite_unregister(&ccg_usb_driver); class_destroy(ccg_class); kfree(_ccg_dev); _ccg_dev = NULL; } -module_exit(cleanup); +module_exit(ccg_exit); -- cgit v1.2.3 From b430b3dbdb74e86ee7da7a335cbca2c630167528 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Mon, 15 Oct 2012 20:26:46 +0200 Subject: staging: line6: drop unused line6_devices[] array There is no reason to limit the number of line6 devices. Drop the static array. Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 20 +------------------- drivers/staging/line6/driver.h | 2 -- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index b8358ca71bd..ac11a3bd1bb 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -96,8 +96,6 @@ static const char line6_request_version[] = { 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 }; -struct usb_line6 *line6_devices[LINE6_MAX_DEVICES]; - /** Class for asynchronous messages. */ @@ -740,7 +738,6 @@ static int line6_probe(struct usb_interface *interface, struct usb_device *usbdev; struct usb_line6 *line6; const struct line6_properties *properties; - int devnum; int interface_number, alternate = 0; int product; int size = 0; @@ -774,16 +771,6 @@ static int line6_probe(struct usb_interface *interface, goto err_put; } - /* find free slot in device table: */ - for (devnum = 0; devnum < LINE6_MAX_DEVICES; ++devnum) - if (line6_devices[devnum] == NULL) - break; - - if (devnum == LINE6_MAX_DEVICES) { - ret = -ENODEV; - goto err_put; - } - /* initialize device info: */ properties = &line6_properties_table[devtype]; dev_info(&interface->dev, "Line6 %s found\n", properties->name); @@ -1112,7 +1099,6 @@ static int line6_probe(struct usb_interface *interface, dev_info(&interface->dev, "Line6 %s now attached\n", line6->properties->name); - line6_devices[devnum] = line6; switch (product) { case LINE6_DEVID_PODX3: @@ -1141,7 +1127,7 @@ static void line6_disconnect(struct usb_interface *interface) { struct usb_line6 *line6; struct usb_device *usbdev; - int interface_number, i; + int interface_number; if (interface == NULL) return; @@ -1214,10 +1200,6 @@ static void line6_disconnect(struct usb_interface *interface) dev_info(&interface->dev, "Line6 %s now disconnected\n", line6->properties->name); - - for (i = LINE6_MAX_DEVICES; i--;) - if (line6_devices[i] == line6) - line6_devices[i] = NULL; } line6_destruct(interface); diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h index a3029eb223d..35246cfcd91 100644 --- a/drivers/staging/line6/driver.h +++ b/drivers/staging/line6/driver.h @@ -25,7 +25,6 @@ #endif #define LINE6_TIMEOUT 1 -#define LINE6_MAX_DEVICES 8 #define LINE6_BUFSIZE_LISTEN 32 #define LINE6_MESSAGE_MAXLEN 256 @@ -78,7 +77,6 @@ do { \ } while (0) extern const unsigned char line6_midi_id[3]; -extern struct usb_line6 *line6_devices[LINE6_MAX_DEVICES]; static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3; static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4; -- cgit v1.2.3 From 54cd1e42f31040c74694a3b2de83cd2cbb2fff55 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Mon, 15 Oct 2012 20:52:27 +0200 Subject: staging: line6: drop unused line6_index and line6_id arrays The line6 driver does not support 'index' and 'id' module parameters so there is no need to keep arrays for these values. Do what other sound drivers do and use the scalar constants instead of dummy arrays. Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/audio.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c index 8e7398393a5..a92e21f7d55 100644 --- a/drivers/staging/line6/audio.c +++ b/drivers/staging/line6/audio.c @@ -16,20 +16,16 @@ #include "driver.h" #include "audio.h" -static int line6_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static char *line6_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; - /* Initialize the Line6 USB audio system. */ int line6_init_audio(struct usb_line6 *line6) { - static int dev; struct snd_card *card; int err; - err = snd_card_create(line6_index[dev], line6_id[dev], THIS_MODULE, 0, - &card); + err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, + THIS_MODULE, 0, &card); if (err < 0) return err; -- cgit v1.2.3 From b9ed9f0ecf1b5675c64d069e9b53effe276b6f01 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Tue, 16 Oct 2012 00:17:40 -0500 Subject: staging: drm/omap: Fix include error during make Fixed include error for drm_mode.h Signed-off-by: Andy Gross Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/omapdrm/omap_crtc.c b/drivers/staging/omapdrm/omap_crtc.c index 732f2ad3403..52492232903 100644 --- a/drivers/staging/omapdrm/omap_crtc.c +++ b/drivers/staging/omapdrm/omap_crtc.c @@ -19,7 +19,7 @@ #include "omap_drv.h" -#include "drm_mode.h" +#include #include "drm_crtc.h" #include "drm_crtc_helper.h" -- cgit v1.2.3 From 41c66e06219c645a1fae94811591ad964804f443 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 22 Oct 2012 15:52:46 -0700 Subject: Staging: silicom: fix up compiler warnings in bp_proc.c This removes the compiler warnings for unused variables and functions in the bp_proc.c file. Cc: Chad Williamson Cc: Daniel Cotey Cc: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bp_proc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/silicom/bp_proc.c b/drivers/staging/silicom/bp_proc.c index 37f998c1c83..8188b9d66b8 100644 --- a/drivers/staging/silicom/bp_proc.c +++ b/drivers/staging/silicom/bp_proc.c @@ -70,7 +70,7 @@ #define DISC_CHANGE_ENTRY_SD "disc_change" #define DIS_DISC_ENTRY_SD "dis_disc" #define DISC_PWUP_ENTRY_SD "disc_pwup" -#endif /* bypass_support */ + static struct proc_dir_entry *bp_procfs_dir; static struct proc_dir_entry *proc_getdir(char *name, @@ -92,8 +92,6 @@ static struct proc_dir_entry *proc_getdir(char *name, return pde; } -#ifdef BYPASS_SUPPORT - int bypass_proc_create_entry_sd(struct pfs_unit *pfs_unit_curr, char *proc_name, -- cgit v1.2.3 From e5e4e9b70c7dfd3ba98d3e8a3951ee3b3cd2a0f9 Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Wed, 17 Oct 2012 00:30:03 -0500 Subject: drm/omap: Remove cpu_is_omapXXXX usage in DMM Removed usage of the cpu_is_omapXXXX in the DMM driver. This is no longer necessary as we can key off of the omap_dmm pointer that is only non-NULL if the device has been probed successfully. Signed-off-by: Andy Gross Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_dmm_tiler.c | 2 +- drivers/staging/omapdrm/omap_dmm_tiler.h | 7 +------ drivers/staging/omapdrm/omap_gem.c | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index 7d3b7d441c6..4d138df369b 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -522,7 +522,7 @@ size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h) return round_up(geom[fmt].cpp * w, PAGE_SIZE) * h; } -bool dmm_is_initialized(void) +bool dmm_is_available(void) { return omap_dmm ? true : false; } diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.h b/drivers/staging/omapdrm/omap_dmm_tiler.h index 740911df5fc..c0271a2ac87 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.h +++ b/drivers/staging/omapdrm/omap_dmm_tiler.h @@ -107,7 +107,7 @@ uint32_t tiler_stride(enum tiler_fmt fmt, uint32_t orient); size_t tiler_size(enum tiler_fmt fmt, uint16_t w, uint16_t h); size_t tiler_vsize(enum tiler_fmt fmt, uint16_t w, uint16_t h); void tiler_align(enum tiler_fmt fmt, uint16_t *w, uint16_t *h); -bool dmm_is_initialized(void); +bool dmm_is_available(void); extern struct platform_driver omap_dmm_driver; @@ -139,9 +139,4 @@ static inline bool validfmt(enum tiler_fmt fmt) } } -static inline int dmm_is_available(void) -{ - return cpu_is_omap44xx(); -} - #endif diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c index 3434e6ec014..0e4a6b70663 100644 --- a/drivers/staging/omapdrm/omap_gem.c +++ b/drivers/staging/omapdrm/omap_gem.c @@ -1435,7 +1435,7 @@ void omap_gem_init(struct drm_device *dev) }; int i, j; - if (!dmm_is_initialized()) { + if (!dmm_is_available()) { /* DMM only supported on OMAP4 and later, so this isn't fatal */ dev_warn(dev->dev, "DMM not available, disable DMM support\n"); return; -- cgit v1.2.3 From bd25e92df8d585b49835d7f8c908a16a62afc66e Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 18 Oct 2012 21:34:38 +0200 Subject: staging: remove version.h include from dgrp/dgrp_sysfs.c The file uses nothing from linux/version.h, so the include is pointless - remove it. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgrp/dgrp_sysfs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/dgrp/dgrp_sysfs.c b/drivers/staging/dgrp/dgrp_sysfs.c index 129be3caa97..43ab9f4d934 100644 --- a/drivers/staging/dgrp/dgrp_sysfs.c +++ b/drivers/staging/dgrp/dgrp_sysfs.c @@ -17,7 +17,6 @@ #include "dgrp_common.h" #include -#include #include #include #include -- cgit v1.2.3 From 4c0a655387cae593569d004e0f8d58f2eac0b3cb Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 18 Oct 2012 21:43:55 +0200 Subject: Staging: silicom: Fix up version.h includes drivers/staging/silicom/bypasslib/bplibk.h actually uses stuff from version.h so it should include the header. drivers/staging/silicom/bp_proc.c and drivers/staging/silicom/bypasslib/bypass.c currently include the header but use nothing from it so they don't need to. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bp_proc.c | 1 - drivers/staging/silicom/bypasslib/bplibk.h | 1 + drivers/staging/silicom/bypasslib/bypass.c | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/silicom/bp_proc.c b/drivers/staging/silicom/bp_proc.c index 8188b9d66b8..a01ca97b766 100644 --- a/drivers/staging/silicom/bp_proc.c +++ b/drivers/staging/silicom/bp_proc.c @@ -10,7 +10,6 @@ /* */ /******************************************************************************/ -#include #if defined(CONFIG_SMP) && !defined(__SMP__) #define __SMP__ #endif diff --git a/drivers/staging/silicom/bypasslib/bplibk.h b/drivers/staging/silicom/bypasslib/bplibk.h index a1c85eec02f..e9db2d114ba 100644 --- a/drivers/staging/silicom/bypasslib/bplibk.h +++ b/drivers/staging/silicom/bypasslib/bplibk.h @@ -15,6 +15,7 @@ #include "bp_ioctl.h" #include "libbp_sd.h" +#include #define IF_NAME "eth" #define SILICOM_VID 0x1374 diff --git a/drivers/staging/silicom/bypasslib/bypass.c b/drivers/staging/silicom/bypasslib/bypass.c index 527829d5813..95a1f1815d9 100644 --- a/drivers/staging/silicom/bypasslib/bypass.c +++ b/drivers/staging/silicom/bypasslib/bypass.c @@ -11,7 +11,6 @@ /* */ /******************************************************************************/ -#include #if defined(CONFIG_SMP) && ! defined(__SMP__) #define __SMP__ #endif -- cgit v1.2.3 From 9f3059c91b44b4c2bde1a1d706856d79fc5ea14c Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Mon, 22 Oct 2012 09:36:48 +0200 Subject: Staging: ipack/carriers: fix missing include linux/slab.h Kernel build failed for parisc architecture: drivers/staging/ipack/carriers/tpci200.c: In function 'tpci200_free_irq': drivers/staging/ipack/carriers/tpci200.c:190:2: error: implicit declaration of function 'kfree' [-Werror=implicit-function-declaration] drivers/staging/ipack/carriers/tpci200.c: In function 'tpci200_request_irq': drivers/staging/ipack/carriers/tpci200.c:217:2: error: implicit declaration of function 'kzalloc' [-Werror=implicit-function-declaration] Reported-by: Fengguang Wu Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/carriers/tpci200.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/ipack/carriers/tpci200.c b/drivers/staging/ipack/carriers/tpci200.c index 829fd1ac8f8..24e8e6d63f2 100644 --- a/drivers/staging/ipack/carriers/tpci200.c +++ b/drivers/staging/ipack/carriers/tpci200.c @@ -12,6 +12,7 @@ */ #include +#include #include "tpci200.h" static const u16 tpci200_status_timeout[] = { -- cgit v1.2.3 From 355d8ae57be9d3a2fe5764f75e394063022b7866 Mon Sep 17 00:00:00 2001 From: Roger Tseng Date: Fri, 19 Oct 2012 17:43:34 +0800 Subject: staging: rts5139: fixed issues when config to built-in object Fixed two issues when CONFIG_RTS5139=y : - Makefile doesn't take $(CONFIG_RTS5139). It always uses obj-m and built as a loadable module. - Rename some symbols with prefix 'rts51x_' to prevent symbol name collisions with drivers/staging/rts_pstor when both are configured to be built-in objects. drivers/staging/rts5139/built-in.o: In function `xd_cleanup_work': (.text+0x1435d): multiple definition of `xd_cleanup_work' drivers/staging/rts_pstor/built-in.o:(.text+0x2b96a): first defined here drivers/staging/rts5139/built-in.o: In function `release_xd_card': (.text+0x14393): multiple definition of `release_xd_card' drivers/staging/rts_pstor/built-in.o:(.text+0x2c491): first defined here drivers/staging/rts5139/built-in.o: In function `set_sense_data': (.text+0x1e02): multiple definition of `set_sense_data' drivers/staging/rts_pstor/built-in.o:(.text+0xa79f): first defined here drivers/staging/rts5139/built-in.o: In function `ms_delay_write': ... Signed-off-by: Roger Tseng Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5139/Makefile | 22 ++-- drivers/staging/rts5139/ms.c | 96 +++++++------- drivers/staging/rts5139/ms.h | 18 +-- drivers/staging/rts5139/ms_mg.c | 104 +++++++-------- drivers/staging/rts5139/ms_mg.h | 14 +- drivers/staging/rts5139/rts51x.c | 10 +- drivers/staging/rts5139/rts51x_card.c | 80 ++++++------ drivers/staging/rts5139/rts51x_card.h | 30 ++--- drivers/staging/rts5139/rts51x_chip.c | 24 ++-- drivers/staging/rts5139/rts51x_chip.h | 16 +-- drivers/staging/rts5139/rts51x_fop.c | 6 +- drivers/staging/rts5139/rts51x_scsi.c | 238 +++++++++++++++++----------------- drivers/staging/rts5139/rts51x_scsi.h | 6 +- drivers/staging/rts5139/sd.c | 36 ++--- drivers/staging/rts5139/sd.h | 12 +- drivers/staging/rts5139/sd_cprm.c | 124 +++++++++--------- drivers/staging/rts5139/sd_cprm.h | 18 +-- drivers/staging/rts5139/xd.c | 58 ++++----- drivers/staging/rts5139/xd.h | 10 +- 19 files changed, 464 insertions(+), 458 deletions(-) diff --git a/drivers/staging/rts5139/Makefile b/drivers/staging/rts5139/Makefile index 82b8958e8d3..75dd31224e6 100644 --- a/drivers/staging/rts5139/Makefile +++ b/drivers/staging/rts5139/Makefile @@ -25,13 +25,19 @@ # Makefile for the RTS51xx USB Card Reader drivers. # -TARGET_MODULE := rts5139 +obj-$(CONFIG_RTS5139) := rts5139.o -EXTRA_CFLAGS := -Idrivers/scsi -I$(PWD) +ccflags-y := -Idrivers/scsi -obj-m += $(TARGET_MODULE).o - -common-obj := rts51x_transport.o rts51x_scsi.o rts51x_fop.o - -$(TARGET_MODULE)-objs := $(common-obj) rts51x.o rts51x_chip.o rts51x_card.o \ - xd.o sd.o ms.o sd_cprm.o ms_mg.o +rts5139-y := \ + rts51x_transport.o \ + rts51x_scsi.o \ + rts51x_fop.o \ + rts51x.o \ + rts51x_chip.o \ + rts51x_card.o \ + xd.o \ + sd.o \ + ms.o \ + sd_cprm.o \ + ms_mg.o diff --git a/drivers/staging/rts5139/ms.c b/drivers/staging/rts5139/ms.c index 6eef33b03f5..a27f7e224e0 100644 --- a/drivers/staging/rts5139/ms.c +++ b/drivers/staging/rts5139/ms.c @@ -160,7 +160,7 @@ int ms_transfer_data(struct rts51x_chip *chip, u8 trans_mode, u8 tpc, rts51x_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE, 0); - trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512); + rts51x_trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512); rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | trans_mode); @@ -602,7 +602,7 @@ static int ms_prepare_reset(struct rts51x_chip *chip) if (!chip->option.FT2_fast_mode) { wait_timeout(250); - card_power_on(chip, MS_CARD); + rts51x_card_power_on(chip, MS_CARD); wait_timeout(150); #ifdef SUPPORT_OCP @@ -872,7 +872,7 @@ static int msxc_change_power(struct rts51x_chip *chip, u8 mode) int retval; u8 buf[6]; - ms_cleanup_work(chip); + rts51x_ms_cleanup_work(chip); /* Set Parameter Register */ retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); @@ -2600,14 +2600,14 @@ BUILD_FAIL: return STATUS_FAIL; } -int reset_ms_card(struct rts51x_chip *chip) +int rts51x_reset_ms_card(struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); int retval; memset(ms_card, 0, sizeof(struct ms_info)); - enable_card_clock(chip, MS_CARD); + rts51x_enable_card_clock(chip, MS_CARD); retval = rts51x_select_card(chip, MS_CARD); if (retval != STATUS_SUCCESS) @@ -2936,7 +2936,7 @@ static int mspro_read_format_progress(struct rts51x_chip *chip, return STATUS_SUCCESS; } -void mspro_polling_format_status(struct rts51x_chip *chip) +void rts51x_mspro_polling_format_status(struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); int i; @@ -2952,25 +2952,25 @@ void mspro_polling_format_status(struct rts51x_chip *chip) return; } -void mspro_format_sense(struct rts51x_chip *chip, unsigned int lun) +void rts51x_mspro_format_sense(struct rts51x_chip *chip, unsigned int lun) { struct ms_info *ms_card = &(chip->ms_card); if (CHK_FORMAT_STATUS(ms_card, FORMAT_SUCCESS)) { - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); ms_card->pro_under_formatting = 0; ms_card->progress = 0; } else if (CHK_FORMAT_STATUS(ms_card, FORMAT_IN_PROGRESS)) { - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, (u16) (ms_card->progress)); } else { - set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); ms_card->pro_under_formatting = 0; ms_card->progress = 0; } } -int mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip, +int rts51x_mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip, int short_data_len, int quick_format) { struct ms_info *ms_card = &(chip->ms_card); @@ -3035,7 +3035,7 @@ int mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip, ms_card->pro_under_formatting = 0; ms_card->progress = 0; ms_card->format_status = FORMAT_SUCCESS; - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE); + rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE); return STATUS_SUCCESS; } @@ -3103,7 +3103,7 @@ static int ms_read_multiple_pages(struct rts51x_chip *chip, u16 phy_blk, rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_H, 0xFF, 0); rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, READ_PAGE_DATA); - trans_dma_enable(DMA_FROM_DEVICE, chip, 512 * page_cnt, DMA_512); + rts51x_trans_dma_enable(DMA_FROM_DEVICE, chip, 512 * page_cnt, DMA_512); rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_MULTI_READ); @@ -3307,7 +3307,7 @@ static int ms_write_multiple_pages(struct rts51x_chip *chip, u16 old_blk, rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - trans_dma_enable(DMA_TO_DEVICE, chip, 512 * page_cnt, DMA_512); + rts51x_trans_dma_enable(DMA_TO_DEVICE, chip, 512 * page_cnt, DMA_512); rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_MULTI_WRITE); @@ -3467,7 +3467,7 @@ static int ms_read_multiple_pages(struct rts51x_chip *chip, u16 phy_blk, rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, trans_cfg); - trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512); + rts51x_trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512); rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_NORMAL_READ); @@ -3670,7 +3670,7 @@ static int ms_write_multiple_pages(struct rts51x_chip *chip, u16 old_blk, rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, WAIT_INT); - trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); + rts51x_trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_NORMAL_WRITE); @@ -3803,10 +3803,10 @@ static int ms_prepare_write(struct rts51x_chip *chip, u16 old_blk, u16 new_blk, return STATUS_SUCCESS; } -int ms_delay_write(struct rts51x_chip *chip) +int rts51x_ms_delay_write(struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); - struct ms_delay_write_tag *delay_write = &(ms_card->delay_write); + struct rts51x_ms_delay_write_tag *delay_write = &(ms_card->delay_write); int retval; if (delay_write->delay_write_flag) { @@ -3827,16 +3827,16 @@ int ms_delay_write(struct rts51x_chip *chip) return STATUS_SUCCESS; } -static inline void ms_rw_fail(struct scsi_cmnd *srb, struct rts51x_chip *chip) +static inline void rts51x_ms_rw_fail(struct scsi_cmnd *srb, struct rts51x_chip *chip) { if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, SCSI_LUN(srb), + rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); else - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); + rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); } -static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, +static int rts51x_ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt) { struct ms_info *ms_card = &(chip->ms_card); @@ -3847,7 +3847,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, u8 start_page, end_page = 0, page_cnt; u8 *buf; void *ptr = NULL; - struct ms_delay_write_tag *delay_write = &(ms_card->delay_write); + struct rts51x_ms_delay_write_tag *delay_write = &(ms_card->delay_write); ms_set_err_code(chip, MS_NO_ERROR); @@ -3857,7 +3857,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, retval = ms_switch_clock(chip); if (retval != STATUS_SUCCESS) { - ms_rw_fail(srb, chip); + rts51x_ms_rw_fail(srb, chip); TRACE_RET(chip, retval); } @@ -3873,7 +3873,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, retval = ms_build_l2p_tbl(chip, seg_no); if (retval != STATUS_SUCCESS) { chip->card_fail |= MS_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, retval); } } @@ -3898,7 +3898,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, start_page); #endif if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, retval); } @@ -3911,9 +3911,9 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, old_blk = delay_write->old_phyblock; new_blk = delay_write->new_phyblock; } else { - retval = ms_delay_write(chip); + retval = rts51x_ms_delay_write(chip); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, retval); } @@ -3922,7 +3922,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, log_blk - ms_start_idx[seg_no]); new_blk = ms_get_unused_block(chip, seg_no); if ((old_blk == 0xFFFF) || (new_blk == 0xFFFF)) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, STATUS_FAIL); } @@ -3933,26 +3933,26 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, if (retval != STATUS_SUCCESS) { if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, STATUS_FAIL); } - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, retval); } } } else { - retval = ms_delay_write(chip); + retval = rts51x_ms_delay_write(chip); if (retval != STATUS_SUCCESS) { if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, STATUS_FAIL); } - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_RET(chip, retval); } @@ -3960,7 +3960,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, ms_get_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no]); if (old_blk == 0xFFFF) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_RET(chip, STATUS_FAIL); } @@ -3993,12 +3993,12 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, if (retval != STATUS_SUCCESS) { if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, STATUS_FAIL); } - ms_rw_fail(srb, chip); + rts51x_ms_rw_fail(srb, chip); TRACE_RET(chip, retval); } /* Update L2P table if need */ @@ -4030,7 +4030,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, retval = ms_build_l2p_tbl(chip, seg_no); if (retval != STATUS_SUCCESS) { chip->card_fail |= MS_CARD; - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, retval); } @@ -4040,14 +4040,14 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, ms_get_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no]); if (old_blk == 0xFFFF) { - ms_rw_fail(srb, chip); + rts51x_ms_rw_fail(srb, chip); TRACE_RET(chip, STATUS_FAIL); } if (srb->sc_data_direction == DMA_TO_DEVICE) { new_blk = ms_get_unused_block(chip, seg_no); if (new_blk == 0xFFFF) { - ms_rw_fail(srb, chip); + rts51x_ms_rw_fail(srb, chip); TRACE_RET(chip, STATUS_FAIL); } } @@ -4073,7 +4073,7 @@ static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, return STATUS_SUCCESS; } -int ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, +int rts51x_ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt) { struct ms_info *ms_card = &(chip->ms_card); @@ -4084,12 +4084,12 @@ int ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, mspro_rw_multi_sector(srb, chip, start_sector, sector_cnt); else retval = - ms_rw_multi_sector(srb, chip, start_sector, sector_cnt); + rts51x_ms_rw_multi_sector(srb, chip, start_sector, sector_cnt); return retval; } -void ms_free_l2p_tbl(struct rts51x_chip *chip) +void rts51x_ms_free_l2p_tbl(struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); int i = 0; @@ -4110,7 +4110,7 @@ void ms_free_l2p_tbl(struct rts51x_chip *chip) } } -void ms_cleanup_work(struct rts51x_chip *chip) +void rts51x_ms_cleanup_work(struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); @@ -4130,7 +4130,7 @@ void ms_cleanup_work(struct rts51x_chip *chip) } else if ((!CHK_MSPRO(ms_card)) && ms_card->delay_write.delay_write_flag) { RTS51X_DEBUGP("MS: delay write\n"); - ms_delay_write(chip); + rts51x_ms_delay_write(chip); ms_card->counter = 0; } } @@ -4161,12 +4161,12 @@ static int ms_power_off_card3v3(struct rts51x_chip *chip) return STATUS_SUCCESS; } -int release_ms_card(struct rts51x_chip *chip) +int rts51x_release_ms_card(struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); int retval; - RTS51X_DEBUGP("release_ms_card\n"); + RTS51X_DEBUGP("rts51x_release_ms_card\n"); ms_card->delay_write.delay_write_flag = 0; ms_card->pro_under_formatting = 0; @@ -4175,7 +4175,7 @@ int release_ms_card(struct rts51x_chip *chip) chip->card_fail &= ~MS_CARD; chip->card_wp &= ~MS_CARD; - ms_free_l2p_tbl(chip); + rts51x_ms_free_l2p_tbl(chip); rts51x_write_register(chip, SFSM_ED, HW_CMD_STOP, HW_CMD_STOP); diff --git a/drivers/staging/rts5139/ms.h b/drivers/staging/rts5139/ms.h index 0321d06e776..857c1974ef2 100644 --- a/drivers/staging/rts5139/ms.h +++ b/drivers/staging/rts5139/ms.h @@ -231,18 +231,18 @@ (((retval) != STATUS_SUCCESS) || \ (chip->rsp_buf[0] & MS_TRANSFER_ERR)) -void mspro_polling_format_status(struct rts51x_chip *chip); -void mspro_format_sense(struct rts51x_chip *chip, unsigned int lun); +void rts51x_mspro_polling_format_status(struct rts51x_chip *chip); +void rts51x_mspro_format_sense(struct rts51x_chip *chip, unsigned int lun); -int reset_ms_card(struct rts51x_chip *chip); -int ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, +int rts51x_reset_ms_card(struct rts51x_chip *chip); +int rts51x_ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt); -int mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip, +int rts51x_mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip, int short_data_len, int quick_format); -void ms_free_l2p_tbl(struct rts51x_chip *chip); -void ms_cleanup_work(struct rts51x_chip *chip); -int release_ms_card(struct rts51x_chip *chip); -int ms_delay_write(struct rts51x_chip *chip); +void rts51x_ms_free_l2p_tbl(struct rts51x_chip *chip); +void rts51x_ms_cleanup_work(struct rts51x_chip *chip); +int rts51x_release_ms_card(struct rts51x_chip *chip); +int rts51x_ms_delay_write(struct rts51x_chip *chip); #ifdef SUPPORT_MAGIC_GATE diff --git a/drivers/staging/rts5139/ms_mg.c b/drivers/staging/rts5139/ms_mg.c index 057d96c1a93..54cfd85259a 100644 --- a/drivers/staging/rts5139/ms_mg.c +++ b/drivers/staging/rts5139/ms_mg.c @@ -119,7 +119,7 @@ int mg_set_tpc_para_sub(struct rts51x_chip *chip, int type, u8 mg_entry_num) * 2. send SET_ID TPC command to medium with Leaf ID released by host * in this SCSI CMD. */ -int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip) { int retval; int i; @@ -129,10 +129,10 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip) RTS51X_DEBUGP("--%s--\n", __func__); if (scsi_bufflen(srb) < 12) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, STATUS_FAIL); } - ms_cleanup_work(chip); + rts51x_ms_cleanup_work(chip); retval = ms_switch_clock(chip); if (retval != STATUS_SUCCESS) @@ -140,7 +140,7 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = mg_send_ex_cmd(chip, MG_SET_LID, 0); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); TRACE_RET(chip, retval); } @@ -151,12 +151,12 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf1, 32); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); TRACE_RET(chip, retval); } retval = mg_check_int_error(chip); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); TRACE_RET(chip, retval); } @@ -170,7 +170,7 @@ int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip) * data(1536 bytes totally) from medium by using READ_LONG_DATA TPC * for 3 times, and report data to host with data-length is 1052 bytes. */ -int mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip) { int retval = STATUS_FAIL; int bufflen; @@ -179,7 +179,7 @@ int mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip) RTS51X_DEBUGP("--%s--\n", __func__); - ms_cleanup_work(chip); + rts51x_ms_cleanup_work(chip); retval = ms_switch_clock(chip); if (retval != STATUS_SUCCESS) @@ -196,21 +196,21 @@ int mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = mg_send_ex_cmd(chip, MG_GET_LEKB, 0); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); TRACE_GOTO(chip, GetEKBFinish); } retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, 3, WAIT_INT, 0, 0, buf + 4, 1536); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); rts51x_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR); TRACE_GOTO(chip, GetEKBFinish); } retval = mg_check_int_error(chip); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); TRACE_GOTO(chip, GetEKBFinish); } @@ -229,7 +229,7 @@ GetEKBFinish: * TPC commands to the medium for writing 8-bytes data as challenge * by host within a short data packet. */ -int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); int retval; @@ -240,7 +240,7 @@ int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) RTS51X_DEBUGP("--%s--\n", __func__); - ms_cleanup_work(chip); + rts51x_ms_cleanup_work(chip); retval = ms_switch_clock(chip); if (retval != STATUS_SUCCESS) @@ -248,19 +248,19 @@ int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = mg_send_ex_cmd(chip, MG_GET_ID, 0); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); TRACE_RET(chip, retval); } retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf, 32); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); TRACE_RET(chip, retval); } retval = mg_check_int_error(chip); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); TRACE_RET(chip, retval); } @@ -276,13 +276,13 @@ int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) } if (i == 2500) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); TRACE_RET(chip, STATUS_FAIL); } retval = mg_send_ex_cmd(chip, MG_SET_RD, 0); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); TRACE_RET(chip, retval); } @@ -296,12 +296,12 @@ int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); TRACE_RET(chip, retval); } retval = mg_check_int_error(chip); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); TRACE_RET(chip, retval); } @@ -320,7 +320,7 @@ int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) * The paremeter MagicGateID is the one that adapter has obtained from * the medium by TPC commands in Set Leaf ID command phase previously. */ -int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); int retval, i; @@ -330,7 +330,7 @@ int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) RTS51X_DEBUGP("--%s--\n", __func__); - ms_cleanup_work(chip); + rts51x_ms_cleanup_work(chip); retval = ms_switch_clock(chip); if (retval != STATUS_SUCCESS) @@ -338,19 +338,19 @@ int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); TRACE_RET(chip, retval); } retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf1, 32); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); TRACE_RET(chip, retval); } retval = mg_check_int_error(chip); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); TRACE_RET(chip, retval); } @@ -375,7 +375,7 @@ int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) } if (i == 2500) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); TRACE_RET(chip, STATUS_FAIL); } @@ -389,7 +389,7 @@ int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) * issues TPC commands to the medium for writing 8-bytes data as * challenge by host within a short data packet. */ -int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); int retval; @@ -400,7 +400,7 @@ int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) RTS51X_DEBUGP("--%s--\n", __func__); - ms_cleanup_work(chip); + rts51x_ms_cleanup_work(chip); retval = ms_switch_clock(chip); if (retval != STATUS_SUCCESS) @@ -408,7 +408,7 @@ int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); TRACE_RET(chip, retval); } @@ -422,12 +422,12 @@ int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); TRACE_RET(chip, retval); } retval = mg_check_int_error(chip); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); TRACE_RET(chip, retval); } @@ -447,7 +447,7 @@ int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) * precedes data transmission from medium to Ring buffer by DMA mechanism * in order to get maximum performance and minimum code size simultaneously. */ -int mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); int retval; @@ -457,7 +457,7 @@ int mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) RTS51X_DEBUGP("--%s--\n", __func__); - ms_cleanup_work(chip); + rts51x_ms_cleanup_work(chip); retval = ms_switch_clock(chip); if (retval != STATUS_SUCCESS) @@ -474,21 +474,21 @@ int mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = mg_send_ex_cmd(chip, MG_GET_IBD, ms_card->mg_entry_num); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_GOTO(chip, GetICVFinish); } retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, 2, WAIT_INT, 0, 0, buf + 4, 1024); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); rts51x_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR); TRACE_GOTO(chip, GetICVFinish); } retval = mg_check_int_error(chip); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_GOTO(chip, GetICVFinish); } @@ -511,7 +511,7 @@ GetICVFinish: * that sent by host, and it should be skipped by shifting DMA pointer * before writing 1024 bytes to medium. */ -int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct ms_info *ms_card = &(chip->ms_card); int retval; @@ -524,7 +524,7 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) RTS51X_DEBUGP("--%s--\n", __func__); - ms_cleanup_work(chip); + rts51x_ms_cleanup_work(chip); retval = ms_switch_clock(chip); if (retval != STATUS_SUCCESS) @@ -541,13 +541,13 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) if (retval != STATUS_SUCCESS) { if (ms_card->mg_auth == 0) { if ((buf[5] & 0xC0) != 0) - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); else - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); } else { - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); } TRACE_GOTO(chip, SetICVFinish); } @@ -563,7 +563,7 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, WAIT_INT); - trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); + rts51x_trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_NORMAL_WRITE); @@ -572,7 +572,7 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = rts51x_send_cmd(chip, MODE_CDOR, 100); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); TRACE_GOTO(chip, SetICVFinish); } @@ -583,13 +583,13 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_clear_ms_error(chip); if (ms_card->mg_auth == 0) { if ((buf[5] & 0xC0) != 0) - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); else - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); } else { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); } retval = STATUS_FAIL; @@ -602,13 +602,13 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_clear_ms_error(chip); if (ms_card->mg_auth == 0) { if ((buf[5] & 0xC0) != 0) - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); else - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); } else { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); } retval = STATUS_FAIL; @@ -622,13 +622,13 @@ int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_clear_ms_error(chip); if (ms_card->mg_auth == 0) { if ((buf[5] & 0xC0) != 0) - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); else - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); } else { - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); } TRACE_GOTO(chip, SetICVFinish); } diff --git a/drivers/staging/rts5139/ms_mg.h b/drivers/staging/rts5139/ms_mg.h index e2ca55085f9..d15733a992a 100644 --- a/drivers/staging/rts5139/ms_mg.h +++ b/drivers/staging/rts5139/ms_mg.h @@ -30,12 +30,12 @@ #include "rts51x_chip.h" #include "ms.h" -int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip); #endif /* __RTS51X_MS_MG_H */ diff --git a/drivers/staging/rts5139/rts51x.c b/drivers/staging/rts5139/rts51x.c index c3fe7dda1f4..04213463123 100644 --- a/drivers/staging/rts5139/rts51x.c +++ b/drivers/staging/rts5139/rts51x.c @@ -306,7 +306,7 @@ static int rts51x_control_thread(void *__chip) /* we've got a command, let's do it! */ else { - RTS51X_DEBUG(scsi_show_command(chip->srb)); + RTS51X_DEBUG(rts51x_scsi_show_command(chip->srb)); rts51x_invoke_transport(chip->srb, chip); } @@ -397,7 +397,7 @@ static int rts51x_polling_thread(void *__chip) } #endif - mspro_polling_format_status(chip); + rts51x_mspro_polling_format_status(chip); /* lock the device pointers */ mutex_lock(&(chip->usb->dev_mutex)); @@ -478,7 +478,7 @@ static void rts51x_init_options(struct rts51x_chip *chip) { struct rts51x_option *option = &(chip->option); - option->mspro_formatter_enable = 1; + option->rts51x_mspro_formatter_enable = 1; option->fpga_sd_sdr104_clk = CLK_100; option->fpga_sd_sdr50_clk = CLK_100; @@ -510,7 +510,7 @@ static void rts51x_init_options(struct rts51x_chip *chip) option->FT2_fast_mode = 0; option->pwr_delay = 800; - option->xd_rw_step = 0; + option->rts51x_xd_rw_step = 0; option->D3318_off_delay = 50; option->delink_delay = 100; option->rts5129_D3318_off_enable = 0; @@ -518,7 +518,7 @@ static void rts51x_init_options(struct rts51x_chip *chip) option->reset_or_rw_fail_set_pad_drive = 1; option->debounce_num = 2; option->led_toggle_interval = 6; - option->xd_rwn_step = 0; + option->rts51x_xd_rwn_step = 0; option->sd_send_status_en = 0; option->sdr50_tx_phase = 0x01; option->sdr50_rx_phase = 0x05; diff --git a/drivers/staging/rts5139/rts51x_card.c b/drivers/staging/rts5139/rts51x_card.c index 50be42ac592..509d83e623a 100644 --- a/drivers/staging/rts5139/rts51x_card.c +++ b/drivers/staging/rts5139/rts51x_card.c @@ -41,7 +41,7 @@ #include "sd.h" #include "ms.h" -void do_remaining_work(struct rts51x_chip *chip) +void rts51x_do_remaining_work(struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); struct xd_info *xd_card = &(chip->xd_card); @@ -84,27 +84,27 @@ void do_remaining_work(struct rts51x_chip *chip) } if (sd_card->counter > POLLING_WAIT_CNT) - sd_cleanup_work(chip); + rts51x_sd_cleanup_work(chip); if (xd_card->counter > POLLING_WAIT_CNT) - xd_cleanup_work(chip); + rts51x_xd_cleanup_work(chip); if (ms_card->counter > POLLING_WAIT_CNT) - ms_cleanup_work(chip); + rts51x_ms_cleanup_work(chip); } -static void do_reset_xd_card(struct rts51x_chip *chip) +static void do_rts51x_reset_xd_card(struct rts51x_chip *chip) { int retval; if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT) return; - retval = reset_xd_card(chip); + retval = rts51x_reset_xd_card(chip); if (retval == STATUS_SUCCESS) { chip->card_ready |= XD_CARD; chip->card_fail &= ~XD_CARD; - chip->rw_card[chip->card2lun[XD_CARD]] = xd_rw; + chip->rw_card[chip->card2lun[XD_CARD]] = rts51x_xd_rw; } else { chip->card_ready &= ~XD_CARD; chip->card_fail |= XD_CARD; @@ -120,18 +120,18 @@ static void do_reset_xd_card(struct rts51x_chip *chip) } } -void do_reset_sd_card(struct rts51x_chip *chip) +void rts51x_do_rts51x_reset_sd_card(struct rts51x_chip *chip) { int retval; if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) return; - retval = reset_sd_card(chip); + retval = rts51x_reset_sd_card(chip); if (retval == STATUS_SUCCESS) { chip->card_ready |= SD_CARD; chip->card_fail &= ~SD_CARD; - chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw; + chip->rw_card[chip->card2lun[SD_CARD]] = rts51x_sd_rw; } else { chip->card_ready &= ~SD_CARD; chip->card_fail |= SD_CARD; @@ -147,18 +147,18 @@ void do_reset_sd_card(struct rts51x_chip *chip) } } -static void do_reset_ms_card(struct rts51x_chip *chip) +static void do_rts51x_reset_ms_card(struct rts51x_chip *chip) { int retval; if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) return; - retval = reset_ms_card(chip); + retval = rts51x_reset_ms_card(chip); if (retval == STATUS_SUCCESS) { chip->card_ready |= MS_CARD; chip->card_fail &= ~MS_CARD; - chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw; + chip->rw_card[chip->card2lun[MS_CARD]] = rts51x_ms_rw; } else { chip->card_ready &= ~MS_CARD; chip->card_fail |= MS_CARD; @@ -301,7 +301,7 @@ void rts51x_init_cards(struct rts51x_chip *chip) chip->card_exist &= ~XD_CARD; chip->card_ejected = 0; if (chip->card_ready & XD_CARD) { - release_xd_card(chip); + rts51x_release_xd_card(chip); chip->rw_card[chip->card2lun[XD_CARD]] = NULL; clear_bit(chip->card2lun[XD_CARD], &(chip->lun_mc)); @@ -312,7 +312,7 @@ void rts51x_init_cards(struct rts51x_chip *chip) chip->card_exist &= ~SD_CARD; chip->card_ejected = 0; if (chip->card_ready & SD_CARD) { - release_sd_card(chip); + rts51x_release_sd_card(chip); chip->rw_card[chip->card2lun[SD_CARD]] = NULL; clear_bit(chip->card2lun[SD_CARD], &(chip->lun_mc)); @@ -323,7 +323,7 @@ void rts51x_init_cards(struct rts51x_chip *chip) chip->card_exist &= ~MS_CARD; chip->card_ejected = 0; if (chip->card_ready & MS_CARD) { - release_ms_card(chip); + rts51x_release_ms_card(chip); chip->rw_card[chip->card2lun[MS_CARD]] = NULL; clear_bit(chip->card2lun[MS_CARD], &(chip->lun_mc)); @@ -339,13 +339,13 @@ void rts51x_init_cards(struct rts51x_chip *chip) if (need_reset & XD_CARD) { chip->card_exist |= XD_CARD; - do_reset_xd_card(chip); + do_rts51x_reset_xd_card(chip); } else if (need_reset & SD_CARD) { chip->card_exist |= SD_CARD; - do_reset_sd_card(chip); + rts51x_do_rts51x_reset_sd_card(chip); } else if (need_reset & MS_CARD) { chip->card_exist |= MS_CARD; - do_reset_ms_card(chip); + do_rts51x_reset_ms_card(chip); } } } @@ -353,20 +353,20 @@ void rts51x_init_cards(struct rts51x_chip *chip) void rts51x_release_cards(struct rts51x_chip *chip) { if (chip->card_ready & SD_CARD) { - sd_cleanup_work(chip); - release_sd_card(chip); + rts51x_sd_cleanup_work(chip); + rts51x_release_sd_card(chip); chip->card_ready &= ~SD_CARD; } if (chip->card_ready & XD_CARD) { - xd_cleanup_work(chip); - release_xd_card(chip); + rts51x_xd_cleanup_work(chip); + rts51x_release_xd_card(chip); chip->card_ready &= ~XD_CARD; } if (chip->card_ready & MS_CARD) { - ms_cleanup_work(chip); - release_ms_card(chip); + rts51x_ms_cleanup_work(chip); + rts51x_release_ms_card(chip); chip->card_ready &= ~MS_CARD; } } @@ -376,7 +376,7 @@ static inline u8 double_depth(u8 depth) return ((depth > 1) ? (depth - 1) : depth); } -int switch_ssc_clock(struct rts51x_chip *chip, int clk) +int rts51x_switch_ssc_clock(struct rts51x_chip *chip, int clk) { struct sd_info *sd_card = &(chip->sd_card); struct ms_info *ms_card = &(chip->ms_card); @@ -513,7 +513,7 @@ int switch_ssc_clock(struct rts51x_chip *chip, int clk) return STATUS_SUCCESS; } -int switch_normal_clock(struct rts51x_chip *chip, int clk) +int rts51x_switch_normal_clock(struct rts51x_chip *chip, int clk) { int retval; u8 sel, div, mcu_cnt; @@ -653,7 +653,7 @@ int switch_normal_clock(struct rts51x_chip *chip, int clk) return STATUS_SUCCESS; } -int card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr, +int rts51x_card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr, u16 sec_cnt) { int retval; @@ -688,7 +688,7 @@ int card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr, return retval; } -u8 get_lun_card(struct rts51x_chip *chip, unsigned int lun) +u8 rts51x_get_lun_card(struct rts51x_chip *chip, unsigned int lun) { if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) return (u8) XD_CARD; @@ -744,24 +744,24 @@ int rts51x_select_card(struct rts51x_chip *chip, int card) return STATUS_SUCCESS; } -void eject_card(struct rts51x_chip *chip, unsigned int lun) +void rts51x_eject_card(struct rts51x_chip *chip, unsigned int lun) { RTS51X_DEBUGP("eject card\n"); RTS51X_SET_STAT(chip, STAT_RUN); - do_remaining_work(chip); + rts51x_do_remaining_work(chip); if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) { - release_sd_card(chip); + rts51x_release_sd_card(chip); chip->card_ejected |= SD_CARD; chip->card_ready &= ~SD_CARD; chip->capacity[lun] = 0; } else if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) { - release_xd_card(chip); + rts51x_release_xd_card(chip); chip->card_ejected |= XD_CARD; chip->card_ready &= ~XD_CARD; chip->capacity[lun] = 0; } else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) { - release_ms_card(chip); + rts51x_release_ms_card(chip); chip->card_ejected |= MS_CARD; chip->card_ready &= ~MS_CARD; chip->capacity[lun] = 0; @@ -770,7 +770,7 @@ void eject_card(struct rts51x_chip *chip, unsigned int lun) XD_INT | MS_INT | SD_INT); } -void trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip, +void rts51x_trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip, u32 byte_cnt, u8 pack_size) { if (pack_size > DMA_1024) @@ -798,7 +798,7 @@ void trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip, } } -int enable_card_clock(struct rts51x_chip *chip, u8 card) +int rts51x_enable_card_clock(struct rts51x_chip *chip, u8 card) { u8 clk_en = 0; @@ -814,7 +814,7 @@ int enable_card_clock(struct rts51x_chip *chip, u8 card) return STATUS_SUCCESS; } -int card_power_on(struct rts51x_chip *chip, u8 card) +int rts51x_card_power_on(struct rts51x_chip *chip, u8 card) { u8 mask, val1, val2; @@ -863,7 +863,7 @@ int monitor_card_cd(struct rts51x_chip *chip, u8 card) return CD_NOT_EXIST; } -int toggle_gpio(struct rts51x_chip *chip, u8 gpio) +int rts51x_toggle_gpio(struct rts51x_chip *chip, u8 gpio) { int retval; u8 temp_reg; @@ -898,7 +898,7 @@ int toggle_gpio(struct rts51x_chip *chip, u8 gpio) return STATUS_SUCCESS; } -int turn_on_led(struct rts51x_chip *chip, u8 gpio) +int rts51x_turn_on_led(struct rts51x_chip *chip, u8 gpio) { int retval; u8 gpio_oe[4] = { @@ -917,7 +917,7 @@ int turn_on_led(struct rts51x_chip *chip, u8 gpio) return STATUS_SUCCESS; } -int turn_off_led(struct rts51x_chip *chip, u8 gpio) +int rts51x_turn_off_led(struct rts51x_chip *chip, u8 gpio) { int retval; u8 gpio_output[4] = { diff --git a/drivers/staging/rts5139/rts51x_card.h b/drivers/staging/rts5139/rts51x_card.h index c5c03cce98b..e62b25c3141 100644 --- a/drivers/staging/rts5139/rts51x_card.h +++ b/drivers/staging/rts5139/rts51x_card.h @@ -737,24 +737,24 @@ int monitor_card_cd(struct rts51x_chip *chip, u8 card); -void do_remaining_work(struct rts51x_chip *chip); -void do_reset_sd_card(struct rts51x_chip *chip); +void rts51x_do_remaining_work(struct rts51x_chip *chip); +void rts51x_do_rts51x_reset_sd_card(struct rts51x_chip *chip); void rts51x_init_cards(struct rts51x_chip *chip); void rts51x_release_cards(struct rts51x_chip *chip); -int switch_ssc_clock(struct rts51x_chip *chip, int clk); -int switch_normal_clock(struct rts51x_chip *chip, int clk); -int card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr, +int rts51x_switch_ssc_clock(struct rts51x_chip *chip, int clk); +int rts51x_switch_normal_clock(struct rts51x_chip *chip, int clk); +int rts51x_card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr, u16 sec_cnt); -u8 get_lun_card(struct rts51x_chip *chip, unsigned int lun); +u8 rts51x_get_lun_card(struct rts51x_chip *chip, unsigned int lun); int rts51x_select_card(struct rts51x_chip *chip, int card); -void eject_card(struct rts51x_chip *chip, unsigned int lun); -void trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip, +void rts51x_eject_card(struct rts51x_chip *chip, unsigned int lun); +void rts51x_trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip, u32 byte_cnt, u8 pack_size); -int enable_card_clock(struct rts51x_chip *chip, u8 card); -int card_power_on(struct rts51x_chip *chip, u8 card); -int toggle_gpio(struct rts51x_chip *chip, u8 gpio); -int turn_on_led(struct rts51x_chip *chip, u8 gpio); -int turn_off_led(struct rts51x_chip *chip, u8 gpio); +int rts51x_enable_card_clock(struct rts51x_chip *chip, u8 card); +int rts51x_card_power_on(struct rts51x_chip *chip, u8 card); +int rts51x_toggle_gpio(struct rts51x_chip *chip, u8 gpio); +int rts51x_turn_on_led(struct rts51x_chip *chip, u8 gpio); +int rts51x_turn_off_led(struct rts51x_chip *chip, u8 gpio); static inline int check_card_ready(struct rts51x_chip *chip, unsigned int lun) { @@ -830,9 +830,9 @@ static inline int switch_clock(struct rts51x_chip *chip, int clk) int retval = 0; if (chip->asic_code) - retval = switch_ssc_clock(chip, clk); + retval = rts51x_switch_ssc_clock(chip, clk); else - retval = switch_normal_clock(chip, clk); + retval = rts51x_switch_normal_clock(chip, clk); return retval; } diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c index 08dcae8db63..7d7510de170 100644 --- a/drivers/staging/rts5139/rts51x_chip.c +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -132,7 +132,7 @@ int rts51x_reset_chip(struct rts51x_chip *chip) } #endif if (chip->option.FT2_fast_mode) { - card_power_on(chip, SD_CARD | MS_CARD | XD_CARD); + rts51x_card_power_on(chip, SD_CARD | MS_CARD | XD_CARD); wait_timeout(10); } @@ -212,8 +212,8 @@ int rts51x_init_chip(struct rts51x_chip *chip) int rts51x_release_chip(struct rts51x_chip *chip) { - xd_free_l2p_tbl(chip); - ms_free_l2p_tbl(chip); + rts51x_xd_free_l2p_tbl(chip); + rts51x_ms_free_l2p_tbl(chip); chip->card_ready = 0; return STATUS_SUCCESS; } @@ -227,7 +227,7 @@ static inline void rts51x_blink_led(struct rts51x_chip *chip) chip->led_toggle_counter++; } else { chip->led_toggle_counter = 0; - toggle_gpio(chip, LED_GPIO); + rts51x_toggle_gpio(chip, LED_GPIO); } } } @@ -325,14 +325,14 @@ void rts51x_polling_func(struct rts51x_chip *chip) && (chip->card_exist & (SD_CARD | MS_CARD | XD_CARD)) && (!chip->card_ejected)) { - turn_on_led(chip, LED_GPIO); + rts51x_turn_on_led(chip, LED_GPIO); } else { if (chip->rts5179) { rts51x_ep0_write_register(chip, CARD_GPIO, 0x03, 0x00); } else { - turn_off_led(chip, LED_GPIO); + rts51x_turn_off_led(chip, LED_GPIO); } } @@ -353,7 +353,7 @@ void rts51x_polling_func(struct rts51x_chip *chip) switch (RTS51X_GET_STAT(chip)) { case STAT_RUN: rts51x_blink_led(chip); - do_remaining_work(chip); + rts51x_do_remaining_work(chip); break; case STAT_IDLE: @@ -707,7 +707,7 @@ void rts51x_do_before_power_down(struct rts51x_chip *chip) if (chip->rts5179) rts51x_ep0_write_register(chip, CARD_GPIO, 0x03, 0x00); else - turn_off_led(chip, LED_GPIO); + rts51x_turn_off_led(chip, LED_GPIO); chip->cur_clk = 0; chip->card_exist = 0; @@ -797,7 +797,7 @@ void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 *status, { struct sd_info *sd_card = &(chip->sd_card); struct ms_info *ms_card = &(chip->ms_card); - u8 card = get_lun_card(chip, lun); + u8 card = rts51x_get_lun_card(chip, lun); #ifdef SUPPORT_OC u8 oc_now_mask = 0, oc_ever_mask = 0; #endif @@ -958,9 +958,9 @@ void rts51x_read_status(struct rts51x_chip *chip, unsigned int lun, rts51x_status[12] = 0; /* Detailed Type */ - if (get_lun_card(chip, lun) == XD_CARD) { + if (rts51x_get_lun_card(chip, lun) == XD_CARD) { rts51x_status[13] = 0x40; - } else if (get_lun_card(chip, lun) == SD_CARD) { + } else if (rts51x_get_lun_card(chip, lun) == SD_CARD) { struct sd_info *sd_card = &(chip->sd_card); rts51x_status[13] = 0x20; @@ -976,7 +976,7 @@ void rts51x_read_status(struct rts51x_chip *chip, unsigned int lun, if (CHK_MMC_SECTOR_MODE(sd_card)) rts51x_status[13] |= 0x04; /* Hi capacity */ } - } else if (get_lun_card(chip, lun) == MS_CARD) { + } else if (rts51x_get_lun_card(chip, lun) == MS_CARD) { struct ms_info *ms_card = &(chip->ms_card); if (CHK_MSPRO(ms_card)) { diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h index 64257caf2f3..12deb24cfbb 100644 --- a/drivers/staging/rts5139/rts51x_chip.h +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -253,7 +253,7 @@ struct sense_data_t { #define SUPPORT_UHS50_MMC44 0x40 struct rts51x_option { - int mspro_formatter_enable; + int rts51x_mspro_formatter_enable; /* card clock expected by user for fpga platform */ int fpga_sd_sdr104_clk; @@ -308,7 +308,7 @@ struct rts51x_option { * add for config delay between 1/4 PMOS and 3/4 PMOS */ int pwr_delay; - int xd_rw_step; /* add to tune xd tRP */ + int rts51x_xd_rw_step; /* add to tune xd tRP */ int D3318_off_delay; /* add to tune D3318 off delay time */ int delink_delay; /* add to tune delink delay time */ /* add for rts5129 to enable/disable D3318 off */ @@ -320,7 +320,7 @@ struct rts51x_option { u8 debounce_num; /* debounce number */ u8 led_toggle_interval; /* used to control led toggle speed */ - int xd_rwn_step; + int rts51x_xd_rwn_step; u8 sd_send_status_en; /* used to store default phase which is * used when phase tune all pass. */ @@ -337,11 +337,11 @@ struct rts51x_option { u8 dv18_voltage; /* add to tune dv18 voltage */ }; -#define MS_FORMATTER_ENABLED(chip) ((chip)->option.mspro_formatter_enable) +#define MS_FORMATTER_ENABLED(chip) ((chip)->option.rts51x_mspro_formatter_enable) struct rts51x_chip; -typedef int (*card_rw_func) (struct scsi_cmnd *srb, struct rts51x_chip *chip, +typedef int (*rts51x_card_rw_func) (struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr, u16 sec_cnt); /* For MS Card */ @@ -564,7 +564,7 @@ struct sd_info { #define CHK_MS8BIT(ms_card) (((ms_card)->ms_type & MS_8BIT)) #define CHK_MS4BIT(ms_card) (((ms_card)->ms_type & MS_4BIT)) -struct ms_delay_write_tag { +struct rts51x_ms_delay_write_tag { u16 old_phyblock; u16 new_phyblock; u16 logblock; @@ -605,7 +605,7 @@ struct ms_info { u32 total_sec_cnt; u8 last_rw_int; - struct ms_delay_write_tag delay_write; + struct rts51x_ms_delay_write_tag delay_write; int counter; @@ -671,7 +671,7 @@ struct rts51x_chip { u32 capacity[MAX_ALLOWED_LUN_CNT]; /* read/write card function pointer */ - card_rw_func rw_card[MAX_ALLOWED_LUN_CNT]; + rts51x_card_rw_func rw_card[MAX_ALLOWED_LUN_CNT]; /* read/write capacity, used for GPIO Toggle */ u32 rw_cap[MAX_ALLOWED_LUN_CNT]; /* card to lun mapping table */ diff --git a/drivers/staging/rts5139/rts51x_fop.c b/drivers/staging/rts5139/rts51x_fop.c index bf1a9e64e87..dee7d8af564 100644 --- a/drivers/staging/rts5139/rts51x_fop.c +++ b/drivers/staging/rts5139/rts51x_fop.c @@ -70,7 +70,7 @@ static int rts51x_sd_direct_cmnd(struct rts51x_chip *chip, switch (dir) { case 0: /* No data */ - retval = ext_sd_execute_no_data(chip, chip->card2lun[SD_CARD], + retval = ext_rts51x_sd_execute_no_data(chip, chip->card2lun[SD_CARD], cmd_idx, standby, acmd, rsp_code, arg); if (retval != TRANSPORT_GOOD) @@ -83,7 +83,7 @@ static int rts51x_sd_direct_cmnd(struct rts51x_chip *chip, if (!buf) TRACE_RET(chip, STATUS_NOMEM); - retval = ext_sd_execute_read_data(chip, chip->card2lun[SD_CARD], + retval = ext_rts51x_sd_execute_read_data(chip, chip->card2lun[SD_CARD], cmd_idx, cmd12, standby, acmd, rsp_code, arg, len, buf, cmnd->buf_len, 0); @@ -117,7 +117,7 @@ static int rts51x_sd_direct_cmnd(struct rts51x_chip *chip, } retval = - ext_sd_execute_write_data(chip, chip->card2lun[SD_CARD], + ext_rts51x_sd_execute_write_data(chip, chip->card2lun[SD_CARD], cmd_idx, cmd12, standby, acmd, rsp_code, arg, len, buf, cmnd->buf_len, 0); diff --git a/drivers/staging/rts5139/rts51x_scsi.c b/drivers/staging/rts5139/rts51x_scsi.c index e07a1f4f58c..052911c9310 100644 --- a/drivers/staging/rts5139/rts51x_scsi.c +++ b/drivers/staging/rts5139/rts51x_scsi.c @@ -44,7 +44,7 @@ #include "ms_mg.h" #include "trace.h" -void scsi_show_command(struct scsi_cmnd *srb) +void rts51x_scsi_show_command(struct scsi_cmnd *srb) { char *what = NULL; int i, unknown_cmd = 0; @@ -333,72 +333,72 @@ void scsi_show_command(struct scsi_cmnd *srb) } } -void set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type) +void rts51x_set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type) { switch (sense_type) { case SENSE_TYPE_MEDIA_CHANGE: - set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0); break; case SENSE_TYPE_MEDIA_NOT_PRESENT: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0); break; case SENSE_TYPE_MEDIA_LBA_OVER_RANGE: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0); break; case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0); break; case SENSE_TYPE_MEDIA_WRITE_PROTECT: - set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0); break; case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0); break; case SENSE_TYPE_MEDIA_WRITE_ERR: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0); break; case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD: - set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0, + rts51x_set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0, ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1); break; case SENSE_TYPE_FORMAT_CMD_FAILED: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0); break; #ifdef SUPPORT_MAGIC_GATE case SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0); break; case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0); break; case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0); break; case SENSE_TYPE_MG_WRITE_ERR: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0); break; #endif case SENSE_TYPE_NO_SENSE: default: - set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0); + rts51x_set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0); break; } } -void set_sense_data(struct rts51x_chip *chip, unsigned int lun, u8 err_code, +void rts51x_set_sense_data(struct rts51x_chip *chip, unsigned int lun, u8 err_code, u8 sense_key, u32 info, u8 asc, u8 ascq, u8 sns_key_info0, u16 sns_key_info1) { @@ -428,13 +428,13 @@ static int test_unit_ready(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_init_cards(chip); if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); return TRANSPORT_FAILED; } if (!check_lun_mc(chip, lun)) { set_lun_mc(chip, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); return TRANSPORT_FAILED; } @@ -457,7 +457,7 @@ static int inquiry(struct scsi_cmnd *srb, struct rts51x_chip *chip) char *inquiry_string; unsigned char sendbytes; unsigned char *buf; - u8 card = get_lun_card(chip, lun); + u8 card = rts51x_get_lun_card(chip, lun); int pro_formatter_flag = 0; unsigned char inquiry_buf[] = { QULIFIRE | DRCT_ACCESS_DEV, @@ -532,7 +532,7 @@ static int start_stop_unit(struct scsi_cmnd *srb, struct rts51x_chip *chip) case UNLOAD_MEDIUM: /* Media shall be unload */ if (check_card_ready(chip, lun)) - eject_card(chip, lun); + rts51x_eject_card(chip, lun); return TRANSPORT_GOOD; case MAKE_MEDIUM_READY: @@ -540,7 +540,7 @@ static int start_stop_unit(struct scsi_cmnd *srb, struct rts51x_chip *chip) if (check_card_ready(chip, lun)) { return TRANSPORT_GOOD; } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -559,7 +559,7 @@ static int allow_medium_removal(struct scsi_cmnd *srb, struct rts51x_chip *chip) scsi_set_resid(srb, 0); if (prevent) { - set_sense_type(chip, SCSI_LUN(srb), + rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -663,10 +663,10 @@ static int mode_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip) int status; int pro_formatter_flag; unsigned char pageCode, *buf; - u8 card = get_lun_card(chip, lun); + u8 card = rts51x_get_lun_card(chip, lun); if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); scsi_set_resid(srb, scsi_bufflen(srb)); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -678,7 +678,7 @@ static int mode_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip) if ((get_lun2card(chip, lun) & MS_CARD)) { if (!card || (card == MS_CARD)) { dataSize = 108; - if (chip->option.mspro_formatter_enable) + if (chip->option.rts51x_mspro_formatter_enable) pro_formatter_flag = 1; } } @@ -725,7 +725,7 @@ static int mode_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip) } status = TRANSPORT_GOOD; } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); scsi_set_resid(srb, scsi_bufflen(srb)); status = TRANSPORT_FAILED; } @@ -749,9 +749,9 @@ static int request_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip) sense = &(chip->sense_buffer[lun]); - if ((get_lun_card(chip, lun) == MS_CARD) + if ((rts51x_get_lun_card(chip, lun) == MS_CARD) && PRO_UNDER_FORMATTING(ms_card)) { - mspro_format_sense(chip, lun); + rts51x_mspro_format_sense(chip, lun); } buf = vmalloc(scsi_bufflen(srb)); @@ -766,7 +766,7 @@ static int request_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip) scsi_set_resid(srb, 0); /* Reset Sense Data */ - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); return TRANSPORT_GOOD; } @@ -778,13 +778,13 @@ static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip) u16 sec_cnt; if (!check_card_ready(chip, lun) || (chip->capacity[lun] == 0)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } if (!check_lun_mc(chip, lun)) { set_lun_mc(chip, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); return TRANSPORT_FAILED; } @@ -812,13 +812,13 @@ static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip) ((u32) srb->cmnd[7]); sec_cnt = ((u16) (srb->cmnd[9]) << 8) | srb->cmnd[10]; } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } if ((start_sec > chip->capacity[lun]) || ((start_sec + sec_cnt) > chip->capacity[lun])) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -830,17 +830,17 @@ static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip) if ((srb->sc_data_direction == DMA_TO_DEVICE) && check_card_wp(chip, lun)) { RTS51X_DEBUGP("Write protected card!\n"); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); TRACE_RET(chip, TRANSPORT_FAILED); } - retval = card_rw(srb, chip, start_sec, sec_cnt); + retval = rts51x_card_rw(srb, chip, start_sec, sec_cnt); if (retval != STATUS_SUCCESS) { if (srb->sc_data_direction == DMA_FROM_DEVICE) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); } TRACE_RET(chip, TRANSPORT_FAILED); } @@ -855,13 +855,13 @@ static int read_format_capacity(struct scsi_cmnd *srb, struct rts51x_chip *chip) unsigned char *buf; unsigned int lun = SCSI_LUN(srb); unsigned int buf_len; - u8 card = get_lun_card(chip, lun); + u8 card = rts51x_get_lun_card(chip, lun); int desc_cnt; int i = 0; if (!check_card_ready(chip, lun)) { - if (!chip->option.mspro_formatter_enable) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + if (!chip->option.rts51x_mspro_formatter_enable) { + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } } @@ -877,7 +877,7 @@ static int read_format_capacity(struct scsi_cmnd *srb, struct rts51x_chip *chip) buf[i++] = 0; /* Capacity List Length */ - if ((buf_len > 12) && chip->option.mspro_formatter_enable && + if ((buf_len > 12) && chip->option.rts51x_mspro_formatter_enable && (chip->lun2card[lun] & MS_CARD) && (!card || (card == MS_CARD))) { buf[i++] = 0x10; desc_cnt = 2; @@ -933,13 +933,13 @@ static int read_capacity(struct scsi_cmnd *srb, struct rts51x_chip *chip) unsigned int lun = SCSI_LUN(srb); if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } if (!check_lun_mc(chip, lun)) { set_lun_mc(chip, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); return TRANSPORT_FAILED; } @@ -1021,7 +1021,7 @@ static int read_mem(struct scsi_cmnd *srb, struct rts51x_chip *chip) retval = rts51x_ep0_read_register(chip, addr + i, buf + i); if (retval != STATUS_SUCCESS) { vfree(buf); - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1066,7 +1066,7 @@ static int write_mem(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_ep0_write_register(chip, addr + i, 0xFF, buf[i]); if (retval != STATUS_SUCCESS) { vfree(buf); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, TRANSPORT_FAILED); } } @@ -1083,12 +1083,12 @@ static int get_sd_csd(struct scsi_cmnd *srb, struct rts51x_chip *chip) unsigned int lun = SCSI_LUN(srb); if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } - if (get_lun_card(chip, lun) != SD_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + if (rts51x_get_lun_card(chip, lun) != SD_CARD) { + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1120,7 +1120,7 @@ static int read_phy_register(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_read_phy_register(chip, addr + i, buf + i); if (retval != STATUS_SUCCESS) { vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), + rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1163,7 +1163,7 @@ static int write_phy_register(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_write_phy_register(chip, addr + i, buf[i]); if (retval != STATUS_SUCCESS) { vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), + rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1181,15 +1181,15 @@ static int get_card_bus_width(struct scsi_cmnd *srb, struct rts51x_chip *chip) u8 card, bus_width; if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } - card = get_lun_card(chip, lun); + card = rts51x_get_lun_card(chip, lun); if ((card == SD_CARD) || (card == MS_CARD)) { bus_width = chip->card_bus_width[lun]; } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1211,7 +1211,7 @@ static int trace_msg_cmd(struct scsi_cmnd *srb, struct rts51x_chip *chip) ((2 + MSG_FUNC_LEN + MSG_FILE_LEN + TIME_VAL_LEN) * TRACE_ITEM_CNT); if ((scsi_bufflen(srb) < buf_len) || (scsi_sglist(srb) == NULL)) { - set_sense_type(chip, SCSI_LUN(srb), + rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1251,7 +1251,7 @@ static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rts51x_chip *chip) case ADD_BATCHCMD: cmd_type = srb->cmnd[4]; if (cmd_type > 2) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1274,13 +1274,13 @@ static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rts51x_chip *chip) [9]); retval = rts51x_send_cmd(chip, mode, 1000); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, TRANSPORT_FAILED); } if (mode & STAGE_R) { retval = rts51x_get_rsp(chip, len, timeout); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1291,7 +1291,7 @@ static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rts51x_chip *chip) idx = srb->cmnd[4]; value = chip->rsp_buf[idx]; if (scsi_bufflen(srb) < 1) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1300,12 +1300,12 @@ static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rts51x_chip *chip) break; default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1357,7 +1357,7 @@ static int app_cmd(struct scsi_cmnd *srb, struct rts51x_chip *chip) break; default: - set_sense_type(chip, SCSI_LUN(srb), + rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1401,7 +1401,7 @@ static int vendor_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) break; default: - set_sense_type(chip, SCSI_LUN(srb), + rts51x_set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1415,15 +1415,15 @@ static int ms_format_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) unsigned int lun = SCSI_LUN(srb); int retval, quick_format; - if (get_lun_card(chip, lun) != MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + if (rts51x_get_lun_card(chip, lun) != MS_CARD) { + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); TRACE_RET(chip, TRANSPORT_FAILED); } if ((srb->cmnd[3] != 0x4D) || (srb->cmnd[4] != 0x47) || (srb->cmnd[5] != 0x66) || (srb->cmnd[6] != 0x6D) || (srb->cmnd[7] != 0x74)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1433,26 +1433,26 @@ static int ms_format_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) quick_format = 1; if (!(chip->card_ready & MS_CARD)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } if (chip->card_wp & MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); TRACE_RET(chip, TRANSPORT_FAILED); } if (!CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); TRACE_RET(chip, TRANSPORT_FAILED); } rts51x_prepare_run(chip); RTS51X_SET_STAT(chip, STAT_RUN); - retval = mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format); + retval = rts51x_mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1471,18 +1471,18 @@ static int get_ms_information(struct scsi_cmnd *srb, struct rts51x_chip *chip) int i; if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } - if ((get_lun_card(chip, lun) != MS_CARD)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + if ((rts51x_get_lun_card(chip, lun) != MS_CARD)) { + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); TRACE_RET(chip, TRANSPORT_FAILED); } if ((srb->cmnd[2] != 0xB0) || (srb->cmnd[4] != 0x4D) || (srb->cmnd[5] != 0x53) || (srb->cmnd[6] != 0x49) || (srb->cmnd[7] != 0x44)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1490,7 +1490,7 @@ static int get_ms_information(struct scsi_cmnd *srb, struct rts51x_chip *chip) if ((CHK_MSXC(ms_card) && (dev_info_id == 0x10)) || (!CHK_MSXC(ms_card) && (dev_info_id == 0x13)) || !CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1576,44 +1576,44 @@ static int sd_extention_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_prepare_run(chip); RTS51X_SET_STAT(chip, STAT_RUN); - sd_cleanup_work(chip); + rts51x_sd_cleanup_work(chip); if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } - if ((get_lun_card(chip, lun) != SD_CARD)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + if ((rts51x_get_lun_card(chip, lun) != SD_CARD)) { + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); TRACE_RET(chip, TRANSPORT_FAILED); } switch (srb->cmnd[0]) { case SD_PASS_THRU_MODE: - result = sd_pass_thru_mode(srb, chip); + result = rts51x_sd_pass_thru_mode(srb, chip); break; case SD_EXECUTE_NO_DATA: - result = sd_execute_no_data(srb, chip); + result = rts51x_sd_execute_no_data(srb, chip); break; case SD_EXECUTE_READ: - result = sd_execute_read_data(srb, chip); + result = rts51x_sd_execute_read_data(srb, chip); break; case SD_EXECUTE_WRITE: - result = sd_execute_write_data(srb, chip); + result = rts51x_sd_execute_write_data(srb, chip); break; case SD_GET_RSP: - result = sd_get_cmd_rsp(srb, chip); + result = rts51x_sd_get_cmd_rsp(srb, chip); break; case SD_HW_RST: - result = sd_hw_rst(srb, chip); + result = rts51x_sd_hw_rst(srb, chip); break; default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1632,24 +1632,24 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_prepare_run(chip); RTS51X_SET_STAT(chip, STAT_RUN); - ms_cleanup_work(chip); + rts51x_ms_cleanup_work(chip); if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } - if ((get_lun_card(chip, lun) != MS_CARD)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + if ((rts51x_get_lun_card(chip, lun) != MS_CARD)) { + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); TRACE_RET(chip, TRANSPORT_FAILED); } if (srb->cmnd[7] != KC_MG_R_PRO) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } if (!CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1659,11 +1659,11 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) case KF_GET_LOC_EKB: if ((scsi_bufflen(srb) == 0x41C) && (srb->cmnd[8] == 0x04) && (srb->cmnd[9] == 0x1C)) { - retval = mg_get_local_EKB(srb, chip); + retval = rts51x_mg_get_local_EKB(srb, chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); } else { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1672,11 +1672,11 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) case KF_RSP_CHG: if ((scsi_bufflen(srb) == 0x24) && (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x24)) { - retval = mg_get_rsp_chg(srb, chip); + retval = rts51x_mg_get_rsp_chg(srb, chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); } else { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1690,18 +1690,18 @@ static int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) (srb->cmnd[2] == 0x00) && (srb->cmnd[3] == 0x00) && (srb->cmnd[4] == 0x00) && (srb->cmnd[5] < 32)) { - retval = mg_get_ICV(srb, chip); + retval = rts51x_mg_get_ICV(srb, chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); } else { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } break; default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1719,28 +1719,28 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) rts51x_prepare_run(chip); RTS51X_SET_STAT(chip, STAT_RUN); - ms_cleanup_work(chip); + rts51x_ms_cleanup_work(chip); if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } if (check_card_wp(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); TRACE_RET(chip, TRANSPORT_FAILED); } - if ((get_lun_card(chip, lun) != MS_CARD)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + if ((rts51x_get_lun_card(chip, lun) != MS_CARD)) { + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); TRACE_RET(chip, TRANSPORT_FAILED); } if (srb->cmnd[7] != KC_MG_R_PRO) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } if (!CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1750,11 +1750,11 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) case KF_SET_LEAF_ID: if ((scsi_bufflen(srb) == 0x0C) && (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) { - retval = mg_set_leaf_id(srb, chip); + retval = rts51x_mg_set_leaf_id(srb, chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); } else { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1763,11 +1763,11 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) case KF_CHG_HOST: if ((scsi_bufflen(srb) == 0x0C) && (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) { - retval = mg_chg(srb, chip); + retval = rts51x_mg_chg(srb, chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); } else { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1776,11 +1776,11 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) case KF_RSP_HOST: if ((scsi_bufflen(srb) == 0x0C) && (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) { - retval = mg_rsp(srb, chip); + retval = rts51x_mg_rsp(srb, chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); } else { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1794,18 +1794,18 @@ static int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) (srb->cmnd[2] == 0x00) && (srb->cmnd[3] == 0x00) && (srb->cmnd[4] == 0x00) && (srb->cmnd[5] < 32)) { - retval = mg_set_ICV(srb, chip); + retval = rts51x_mg_set_ICV(srb, chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); } else { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } break; default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1820,12 +1820,12 @@ int rts51x_scsi_handler(struct scsi_cmnd *srb, struct rts51x_chip *chip) unsigned int lun = SCSI_LUN(srb); int result = TRANSPORT_GOOD; - if ((get_lun_card(chip, lun) == MS_CARD) && + if ((rts51x_get_lun_card(chip, lun) == MS_CARD) && (ms_card->format_status == FORMAT_IN_PROGRESS)) { if ((srb->cmnd[0] != REQUEST_SENSE) && (srb->cmnd[0] != INQUIRY)) { /* Logical Unit Not Ready Format in Progress */ - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, + rts51x_set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, (u16) (ms_card->progress)); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1908,7 +1908,7 @@ int rts51x_scsi_handler(struct scsi_cmnd *srb, struct rts51x_chip *chip) break; default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); result = TRANSPORT_FAILED; } diff --git a/drivers/staging/rts5139/rts51x_scsi.h b/drivers/staging/rts5139/rts51x_scsi.h index 9042bc98a9a..cdfe550371c 100644 --- a/drivers/staging/rts5139/rts51x_scsi.h +++ b/drivers/staging/rts5139/rts51x_scsi.h @@ -133,9 +133,9 @@ struct rts51x_chip; #define SCSI 0x00 /* Interface ID */ -void scsi_show_command(struct scsi_cmnd *srb); -void set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type); -void set_sense_data(struct rts51x_chip *chip, unsigned int lun, u8 err_code, +void rts51x_scsi_show_command(struct scsi_cmnd *srb); +void rts51x_set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type); +void rts51x_set_sense_data(struct rts51x_chip *chip, unsigned int lun, u8 err_code, u8 sense_key, u32 info, u8 asc, u8 ascq, u8 sns_key_info0, u16 sns_key_info1); diff --git a/drivers/staging/rts5139/sd.c b/drivers/staging/rts5139/sd.c index b739f26f78c..4283b0917f2 100644 --- a/drivers/staging/rts5139/sd.c +++ b/drivers/staging/rts5139/sd.c @@ -680,7 +680,7 @@ static int sd_set_init_para(struct rts51x_chip *chip) return STATUS_SUCCESS; } -int sd_select_card(struct rts51x_chip *chip, int select) +int rts51x_sd_select_card(struct rts51x_chip *chip, int select) { struct sd_info *sd_card = &(chip->sd_card); int retval; @@ -1747,7 +1747,7 @@ static int mmc_ddr_tuning(struct rts51x_chip *chip) return STATUS_SUCCESS; } -int sd_switch_clock(struct rts51x_chip *chip) +int rts51x_sd_switch_clock(struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); int retval; @@ -1913,7 +1913,7 @@ static int sd_init_power(struct rts51x_chip *chip) #endif /* Power on card */ - retval = card_power_on(chip, SD_CARD); + retval = rts51x_card_power_on(chip, SD_CARD); if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); @@ -2139,7 +2139,7 @@ RTY_CMD55: if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); /* Select SD card */ - retval = sd_select_card(chip, 1); + retval = rts51x_sd_select_card(chip, 1); if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); @@ -2656,7 +2656,7 @@ RTY_MMC_RST: spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2; /* Select MMC card */ - retval = sd_select_card(chip, 1); + retval = rts51x_sd_select_card(chip, 1); if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); @@ -2748,7 +2748,7 @@ RTY_MMC_RST: return STATUS_SUCCESS; } -int reset_sd_card(struct rts51x_chip *chip) +int rts51x_reset_sd_card(struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); int retval; @@ -2764,7 +2764,7 @@ int reset_sd_card(struct rts51x_chip *chip) sd_card->sd_switch_fail = 0; sd_clear_reset_fail(chip); - enable_card_clock(chip, SD_CARD); + rts51x_enable_card_clock(chip, SD_CARD); sd_init_power(chip); @@ -2891,7 +2891,7 @@ static void sd_stop_seq_mode(struct rts51x_chip *chip) int retval; if (sd_card->seq_mode) { - retval = sd_switch_clock(chip); + retval = rts51x_sd_switch_clock(chip); if (retval != STATUS_SUCCESS) return; @@ -2923,14 +2923,14 @@ static inline int sd_auto_tune_clock(struct rts51x_chip *chip) sd_card->sd_clock = CLK_50; } - retval = sd_switch_clock(chip); + retval = rts51x_sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); return STATUS_SUCCESS; } -int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, +int rts51x_sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt) { struct sd_info *sd_card = &(chip->sd_card); @@ -2947,11 +2947,11 @@ int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, else data_addr = start_sector; - RTS51X_DEBUGP("sd_rw, data_addr = 0x%x\n", data_addr); + RTS51X_DEBUGP("rts51x_sd_rw, data_addr = 0x%x\n", data_addr); sd_clr_err_code(chip); - retval = sd_switch_clock(chip); + retval = rts51x_sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); @@ -3020,7 +3020,7 @@ int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0); - trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, + rts51x_trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, DMA_512); if (srb->sc_data_direction == DMA_FROM_DEVICE) { @@ -3058,7 +3058,7 @@ int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); - trans_dma_enable(srb->sc_data_direction, chip, + rts51x_trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, DMA_512); rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, @@ -3099,7 +3099,7 @@ int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0); - trans_dma_enable(srb->sc_data_direction, chip, + rts51x_trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, DMA_512); rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, @@ -3168,7 +3168,7 @@ int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, return STATUS_SUCCESS; } -void sd_cleanup_work(struct rts51x_chip *chip) +void rts51x_sd_cleanup_work(struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); @@ -3220,12 +3220,12 @@ static int sd_power_off_card3v3(struct rts51x_chip *chip) return STATUS_SUCCESS; } -int release_sd_card(struct rts51x_chip *chip) +int rts51x_release_sd_card(struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); int retval; - RTS51X_DEBUGP("release_sd_card\n"); + RTS51X_DEBUGP("rts51x_release_sd_card\n"); chip->card_ready &= ~SD_CARD; chip->card_fail &= ~SD_CARD; diff --git a/drivers/staging/rts5139/sd.h b/drivers/staging/rts5139/sd.h index de155d8e682..7dd943f54c7 100644 --- a/drivers/staging/rts5139/sd.h +++ b/drivers/staging/rts5139/sd.h @@ -256,13 +256,13 @@ struct timing_phase_path { int len; }; -int sd_select_card(struct rts51x_chip *chip, int select); -int reset_sd_card(struct rts51x_chip *chip); -int sd_switch_clock(struct rts51x_chip *chip); -int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, +int rts51x_sd_select_card(struct rts51x_chip *chip, int select); +int rts51x_reset_sd_card(struct rts51x_chip *chip); +int rts51x_sd_switch_clock(struct rts51x_chip *chip); +int rts51x_sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt); -void sd_cleanup_work(struct rts51x_chip *chip); -int release_sd_card(struct rts51x_chip *chip); +void rts51x_sd_cleanup_work(struct rts51x_chip *chip); +int rts51x_release_sd_card(struct rts51x_chip *chip); #ifdef SUPPORT_CPRM extern int reset_sd(struct rts51x_chip *chip); diff --git a/drivers/staging/rts5139/sd_cprm.c b/drivers/staging/rts5139/sd_cprm.c index 0167f7f35c2..d4689839e15 100644 --- a/drivers/staging/rts5139/sd_cprm.c +++ b/drivers/staging/rts5139/sd_cprm.c @@ -269,7 +269,7 @@ static int ext_sd_get_rsp(struct rts51x_chip *chip, int len, return STATUS_SUCCESS; } -int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, +int ext_rts51x_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, u8 cmd_idx, u8 standby, u8 acmd, u8 rsp_code, u32 arg) { @@ -277,30 +277,30 @@ int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, int retval, rsp_len; u8 rsp_type; - retval = sd_switch_clock(chip); + retval = rts51x_sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); if (sd_card->pre_cmd_err) { sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); TRACE_RET(chip, TRANSPORT_FAILED); } retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } sd_card->last_rsp_type = rsp_type; - retval = sd_switch_clock(chip); + retval = rts51x_sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); /* Set H/W SD/MMC Bus Width */ rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4); if (standby) { - retval = sd_select_card(chip, 0); + retval = rts51x_sd_select_card(chip, 0); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Cmd_Failed); } @@ -319,7 +319,7 @@ int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, TRACE_GOTO(chip, SD_Execute_Cmd_Failed); if (standby) { - retval = sd_select_card(chip, 1); + retval = rts51x_sd_select_card(chip, 1); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Cmd_Failed); } @@ -328,16 +328,16 @@ int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, SD_Execute_Cmd_Failed: sd_card->pre_cmd_err = 1; - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - release_sd_card(chip); - do_reset_sd_card(chip); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + rts51x_release_sd_card(chip); + rts51x_do_rts51x_reset_sd_card(chip); if (!(chip->card_ready & SD_CARD)) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } -int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, +int ext_rts51x_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd, u8 rsp_code, u32 arg, u32 data_len, void *data_buf, unsigned int buf_len, int use_sg) @@ -349,21 +349,21 @@ int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, if (sd_card->pre_cmd_err) { sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); TRACE_RET(chip, TRANSPORT_FAILED); } - retval = sd_switch_clock(chip); + retval = rts51x_sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } sd_card->last_rsp_type = rsp_type; - retval = sd_switch_clock(chip); + retval = rts51x_sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); bus_width = SD_BUS_WIDTH_4; @@ -376,7 +376,7 @@ int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, } if (standby) { - retval = sd_select_card(chip, 0); + retval = rts51x_sd_select_card(chip, 0); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); } @@ -448,7 +448,7 @@ int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8) arg); rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, bus_width); rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); - trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512); + rts51x_trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512); rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, SD_TM_AUTO_READ_2 | SD_TRANSFER_START); rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, @@ -490,7 +490,7 @@ int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); if (standby) { - retval = sd_select_card(chip, 1); + retval = rts51x_sd_select_card(chip, 1); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); } @@ -531,18 +531,18 @@ int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, SD_Execute_Read_Cmd_Failed: sd_card->pre_cmd_err = 1; - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); if (read_err) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - release_sd_card(chip); - do_reset_sd_card(chip); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + rts51x_release_sd_card(chip); + rts51x_do_rts51x_reset_sd_card(chip); if (!(chip->card_ready & SD_CARD)) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } -int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, +int ext_rts51x_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd, u8 rsp_code, u32 arg, u32 data_len, void *data_buf, unsigned int buf_len, int use_sg) @@ -555,22 +555,22 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, if (sd_card->pre_cmd_err) { sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); TRACE_RET(chip, TRANSPORT_FAILED); } - retval = sd_switch_clock(chip); + retval = rts51x_sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, STATUS_FAIL); retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } sd_card->last_rsp_type = rsp_type; - retval = sd_switch_clock(chip); + retval = rts51x_sd_switch_clock(chip); if (retval != STATUS_SUCCESS) TRACE_RET(chip, TRANSPORT_FAILED); rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4); @@ -583,7 +583,7 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, } if (standby) { - retval = sd_select_card(chip, 0); + retval = rts51x_sd_select_card(chip, 0); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); } @@ -690,7 +690,7 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, (u8) ((data_len & 0x0001FE00) >> 9)); - trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512); + rts51x_trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512); rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); @@ -724,7 +724,7 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, } if (standby) { - retval = sd_select_card(chip, 1); + retval = rts51x_sd_select_card(chip, 1); if (retval != STATUS_SUCCESS) TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); } @@ -767,18 +767,18 @@ int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, SD_Execute_Write_Cmd_Failed: sd_card->pre_cmd_err = 1; - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); if (write_err) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - release_sd_card(chip); - do_reset_sd_card(chip); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + rts51x_release_sd_card(chip); + rts51x_do_rts51x_reset_sd_card(chip); if (!(chip->card_ready & SD_CARD)) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, TRANSPORT_FAILED); } -int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); unsigned int lun = SCSI_LUN(srb); @@ -808,7 +808,7 @@ int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip) if (!(CHK_BIT(chip->lun_mc, lun))) { SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -816,7 +816,7 @@ int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip) || (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5]) || (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7]) || (0x64 != srb->cmnd[8])) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -830,7 +830,7 @@ int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip) break; default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -850,7 +850,7 @@ int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip) return TRANSPORT_GOOD; } -int sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); unsigned int lun = SCSI_LUN(srb); @@ -860,7 +860,7 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) u32 arg; if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -876,13 +876,13 @@ int sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) rsp_code = srb->cmnd[10]; retval = - ext_sd_execute_no_data(chip, lun, cmd_idx, standby, acmd, rsp_code, + ext_rts51x_sd_execute_no_data(chip, lun, cmd_idx, standby, acmd, rsp_code, arg); scsi_set_resid(srb, 0); return retval; } -int sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); int retval; @@ -891,7 +891,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) u32 arg, data_len; if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -912,7 +912,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) rsp_code = srb->cmnd[10]; retval = - ext_sd_execute_read_data(chip, lun, cmd_idx, send_cmd12, standby, + ext_rts51x_sd_execute_read_data(chip, lun, cmd_idx, send_cmd12, standby, acmd, rsp_code, arg, data_len, scsi_sglist(srb), scsi_bufflen(srb), scsi_sg_count(srb)); @@ -920,7 +920,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) return retval; } -int sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); int retval; @@ -929,7 +929,7 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) u32 data_len, arg; if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -950,7 +950,7 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) rsp_code = srb->cmnd[10]; retval = - ext_sd_execute_write_data(chip, lun, cmd_idx, send_cmd12, standby, + ext_rts51x_sd_execute_write_data(chip, lun, cmd_idx, send_cmd12, standby, acmd, rsp_code, arg, data_len, scsi_sglist(srb), scsi_bufflen(srb), scsi_sg_count(srb)); @@ -958,7 +958,7 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) return retval; } -int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); unsigned int lun = SCSI_LUN(srb); @@ -966,20 +966,20 @@ int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) u16 data_len; if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } if (sd_card->pre_cmd_err) { sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); TRACE_RET(chip, TRANSPORT_FAILED); } data_len = ((u16) srb->cmnd[7] << 8) | srb->cmnd[8]; if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) { count = (data_len < 17) ? data_len : 17; @@ -997,20 +997,20 @@ int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) return TRANSPORT_GOOD; } -int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip) +int rts51x_sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip) { struct sd_info *sd_card = &(chip->sd_card); unsigned int lun = SCSI_LUN(srb); int retval; if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } if (sd_card->pre_cmd_err) { sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1018,16 +1018,16 @@ int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip) || (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5]) || (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7]) || (0x64 != srb->cmnd[8])) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } switch (srb->cmnd[1] & 0x0F) { case 0: /* SD Card Power Off -> ON and Initialization */ - retval = reset_sd_card(chip); + retval = rts51x_reset_sd_card(chip); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); sd_card->pre_cmd_err = 1; TRACE_RET(chip, TRANSPORT_FAILED); } @@ -1038,14 +1038,14 @@ int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip) * (without SD Card Power Off -> ON) */ retval = reset_sd(chip); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); sd_card->pre_cmd_err = 1; TRACE_RET(chip, TRANSPORT_FAILED); } break; default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); TRACE_RET(chip, TRANSPORT_FAILED); } diff --git a/drivers/staging/rts5139/sd_cprm.h b/drivers/staging/rts5139/sd_cprm.h index 75e263b6594..79dfd27db41 100644 --- a/drivers/staging/rts5139/sd_cprm.h +++ b/drivers/staging/rts5139/sd_cprm.h @@ -31,24 +31,24 @@ #include "sd.h" #ifdef SUPPORT_CPRM -int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, +int ext_rts51x_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, u8 cmd_idx, u8 standby, u8 acmd, u8 rsp_code, u32 arg); -int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, +int ext_rts51x_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd, u8 rsp_code, u32 arg, u32 data_len, void *data_buf, unsigned int buf_len, int use_sg); -int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, +int ext_rts51x_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd, u8 rsp_code, u32 arg, u32 data_len, void *data_buf, unsigned int buf_len, int use_sg); -int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip); -int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int rts51x_sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip); #endif #endif /* __RTS51X_SD_CPRM_H */ diff --git a/drivers/staging/rts5139/xd.c b/drivers/staging/rts5139/xd.c index 58f8ba24cae..10fea7e16ac 100644 --- a/drivers/staging/rts5139/xd.c +++ b/drivers/staging/rts5139/xd.c @@ -425,7 +425,7 @@ static int reset_xd(struct rts51x_chip *chip) } #endif - retval = card_power_on(chip, XD_CARD); + retval = rts51x_card_power_on(chip, XD_CARD); if (retval != STATUS_SUCCESS) TRACE_RET(chip, retval); #ifdef SUPPORT_OCP @@ -472,8 +472,8 @@ static int reset_xd(struct rts51x_chip *chip) rts51x_init_cmd(chip); rts51x_add_cmd(chip, WRITE_REG_CMD, XD_DTCTL, 0xFF, XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * - (2 + i + chip->option.xd_rw_step) - + XD_TIME_RWN_STEP * (i + chip->option.xd_rwn_step)); + (2 + i + chip->option.rts51x_xd_rw_step) + + XD_TIME_RWN_STEP * (i + chip->option.rts51x_xd_rwn_step)); rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CATCTL, 0xFF, XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * (4 + i) + XD_TIME_RWN_STEP * (3 + i)); @@ -905,7 +905,7 @@ static u32 xd_get_l2p_tbl(struct rts51x_chip *chip, int zone_no, u16 log_off) return (u32) zone->l2p_table[log_off] + ((u32) (zone_no) << 10); } -int reset_xd_card(struct rts51x_chip *chip) +int rts51x_reset_xd_card(struct rts51x_chip *chip) { struct xd_info *xd_card = &(chip->xd_card); int retval; @@ -920,7 +920,7 @@ int reset_xd_card(struct rts51x_chip *chip) xd_card->cis_block = 0xFFFF; xd_card->delay_write.delay_write_flag = 0; - enable_card_clock(chip, XD_CARD); + rts51x_enable_card_clock(chip, XD_CARD); retval = reset_xd(chip); if (retval != STATUS_SUCCESS) { @@ -1526,7 +1526,7 @@ static int xd_read_multiple_pages(struct rts51x_chip *chip, u32 phy_blk, rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); - trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512, + rts51x_trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512, DMA_512); rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, @@ -1745,7 +1745,7 @@ static int xd_write_multiple_pages(struct rts51x_chip *chip, u32 old_blk, rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512, + rts51x_trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512, DMA_512); rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, @@ -1842,7 +1842,7 @@ static int xd_delay_write(struct rts51x_chip *chip) return STATUS_SUCCESS; } -int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, +int rts51x_xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt) { struct xd_info *xd_card = &(chip->xd_card); @@ -1860,7 +1860,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, xd_card->counter = 0; - RTS51X_DEBUGP("xd_rw: scsi_bufflen = %d, scsi_sg_count = %d\n", + RTS51X_DEBUGP("rts51x_xd_rw: scsi_bufflen = %d, scsi_sg_count = %d\n", scsi_bufflen(srb), scsi_sg_count(srb)); RTS51X_DEBUGP("Data direction: %s\n", (srb->sc_data_direction == @@ -1883,7 +1883,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, retval = xd_build_l2p_tbl(chip, zone_no); if (retval != STATUS_SUCCESS) { chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, retval); } } @@ -1900,7 +1900,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, delay_write->pageoff, start_page); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, retval); } @@ -1916,7 +1916,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, } else { retval = xd_delay_write(chip); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, retval); } @@ -1924,7 +1924,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, new_blk = xd_get_unused_block(chip, zone_no); if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, retval); } @@ -1935,11 +1935,11 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, if (retval != STATUS_SUCCESS) { if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, STATUS_FAIL); } - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, retval); } @@ -1948,18 +1948,18 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, retval = xd_delay_write(chip); if (retval != STATUS_SUCCESS) { if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, STATUS_FAIL); } - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_RET(chip, retval); } old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); if (old_blk == BLK_NOT_FOUND) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_RET(chip, STATUS_FAIL); } @@ -1980,7 +1980,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, start_page, end_page, buf, &ptr, &offset); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); TRACE_RET(chip, STATUS_FAIL); } @@ -1991,7 +1991,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, end_page, buf, &ptr, &offset); if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, STATUS_FAIL); } @@ -2010,7 +2010,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, retval = xd_build_l2p_tbl(chip, zone_no); if (retval != STATUS_SUCCESS) { chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); TRACE_RET(chip, retval); } @@ -2019,10 +2019,10 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); if (old_blk == BLK_NOT_FOUND) { if (srb->sc_data_direction == DMA_FROM_DEVICE) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); } else { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); } TRACE_RET(chip, STATUS_FAIL); @@ -2031,7 +2031,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, if (srb->sc_data_direction == DMA_TO_DEVICE) { new_blk = xd_get_unused_block(chip, zone_no); if (new_blk == BLK_NOT_FOUND) { - set_sense_type(chip, lun, + rts51x_set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); TRACE_RET(chip, STATUS_FAIL); } @@ -2054,7 +2054,7 @@ int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, return STATUS_SUCCESS; } -void xd_free_l2p_tbl(struct rts51x_chip *chip) +void rts51x_xd_free_l2p_tbl(struct rts51x_chip *chip) { struct xd_info *xd_card = &(chip->xd_card); int i = 0; @@ -2075,7 +2075,7 @@ void xd_free_l2p_tbl(struct rts51x_chip *chip) } } -void xd_cleanup_work(struct rts51x_chip *chip) +void rts51x_xd_cleanup_work(struct rts51x_chip *chip) { struct xd_info *xd_card = &(chip->xd_card); @@ -2115,12 +2115,12 @@ static int xd_power_off_card3v3(struct rts51x_chip *chip) return STATUS_SUCCESS; } -int release_xd_card(struct rts51x_chip *chip) +int rts51x_release_xd_card(struct rts51x_chip *chip) { struct xd_info *xd_card = &(chip->xd_card); int retval; - RTS51X_DEBUGP("release_xd_card\n"); + RTS51X_DEBUGP("rts51x_release_xd_card\n"); chip->card_ready &= ~XD_CARD; chip->card_fail &= ~XD_CARD; @@ -2128,7 +2128,7 @@ int release_xd_card(struct rts51x_chip *chip) xd_card->delay_write.delay_write_flag = 0; - xd_free_l2p_tbl(chip); + rts51x_xd_free_l2p_tbl(chip); rts51x_write_register(chip, SFSM_ED, HW_CMD_STOP, HW_CMD_STOP); diff --git a/drivers/staging/rts5139/xd.h b/drivers/staging/rts5139/xd.h index 55e4205e23f..695a0b4d7e5 100644 --- a/drivers/staging/rts5139/xd.h +++ b/drivers/staging/rts5139/xd.h @@ -181,11 +181,11 @@ #define CIS1_8 (256 + 8) #define CIS1_9 (256 + 9) -int reset_xd_card(struct rts51x_chip *chip); -int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, +int rts51x_reset_xd_card(struct rts51x_chip *chip); +int rts51x_xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, u16 sector_cnt); -void xd_free_l2p_tbl(struct rts51x_chip *chip); -void xd_cleanup_work(struct rts51x_chip *chip); -int release_xd_card(struct rts51x_chip *chip); +void rts51x_xd_free_l2p_tbl(struct rts51x_chip *chip); +void rts51x_xd_cleanup_work(struct rts51x_chip *chip); +int rts51x_release_xd_card(struct rts51x_chip *chip); #endif /* __RTS51X_XD_H */ -- cgit v1.2.3 From f1b540b92c54531484d00bb790ad47f3f44b2798 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Wed, 17 Oct 2012 22:15:11 +0100 Subject: staging: et131x: Use skb_headlen() where appropriate (skb->len - skb->data_len) is used in several places in the et131x driver code. Converted all instances of this to use skb_headlen() which is more readable. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 413da0d6b9f..9d258a3f54d 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -3313,12 +3313,11 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) * This will work until we determine why the hardware * doesn't seem to like large fragments. */ - if ((skb->len - skb->data_len) <= 1514) { + if (skb_headlen(skb) <= 1514) { desc[frag].addr_hi = 0; /* Low 16bits are length, high is vlan and unused currently so zero */ - desc[frag].len_vlan = - skb->len - skb->data_len; + desc[frag].len_vlan = skb_headlen(skb); /* NOTE: Here, the dma_addr_t returned from * dma_map_single() is implicitly cast as a @@ -3331,13 +3330,11 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) desc[frag++].addr_lo = dma_map_single(&adapter->pdev->dev, skb->data, - skb->len - - skb->data_len, + skb_headlen(skb), DMA_TO_DEVICE); } else { desc[frag].addr_hi = 0; - desc[frag].len_vlan = - (skb->len - skb->data_len) / 2; + desc[frag].len_vlan = skb_headlen(skb) / 2; /* NOTE: Here, the dma_addr_t returned from * dma_map_single() is implicitly cast as a @@ -3350,13 +3347,11 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) desc[frag++].addr_lo = dma_map_single(&adapter->pdev->dev, skb->data, - ((skb->len - - skb->data_len) / 2), + (skb_headlen(skb) / 2), DMA_TO_DEVICE); desc[frag].addr_hi = 0; - desc[frag].len_vlan = - (skb->len - skb->data_len) / 2; + desc[frag].len_vlan = skb_headlen(skb) / 2; /* NOTE: Here, the dma_addr_t returned from * dma_map_single() is implicitly cast as a @@ -3369,10 +3364,8 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) desc[frag++].addr_lo = dma_map_single(&adapter->pdev->dev, skb->data + - ((skb->len - - skb->data_len) / 2), - ((skb->len - - skb->data_len) / 2), + (skb_headlen(skb) / 2), + (skb_headlen(skb) / 2), DMA_TO_DEVICE); } } else { @@ -3521,7 +3514,7 @@ static int send_packet(struct sk_buff *skb, struct et131x_adapter *adapter) tcb->skb = skb; - if (skb->data != NULL && skb->len - skb->data_len >= 6) { + if (skb->data != NULL && skb_headlen(skb) >= 6) { shbufva = (u16 *) skb->data; if ((shbufva[0] == 0xffff) && -- cgit v1.2.3 From 998f6dfb61e52e1f42d97f9fab1bf7c8077bc293 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Thu, 18 Oct 2012 21:34:22 +0100 Subject: staging: et131x: Fix 64bit tx dma address handling The driver checks that the device can handle 64bit DMA addressing in et131x_pci_setup(), but then assumes that the top dword of a tx dma address is always zero when creating a dma mapping in nic_send_packet(). Fix the mapping to use the higher dword of the dma_addr_t returned by dma_map_single() and skb_frag_dma_map(). Also remove incorrect comments stating that dma_map_single() only returns a 32 bit address. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 102 +++++++++++++++------------------------- 1 file changed, 39 insertions(+), 63 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 9d258a3f54d..23d166b2d02 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -3285,6 +3285,7 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) struct skb_frag_struct *frags = &skb_shinfo(skb)->frags[0]; unsigned long flags; struct phy_device *phydev = adapter->phydev; + dma_addr_t dma_addr; /* Part of the optimizations of this send routine restrict us to * sending 24 fragments at a pass. In practice we should never see @@ -3314,77 +3315,46 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) * doesn't seem to like large fragments. */ if (skb_headlen(skb) <= 1514) { - desc[frag].addr_hi = 0; /* Low 16bits are length, high is vlan and unused currently so zero */ desc[frag].len_vlan = skb_headlen(skb); - - /* NOTE: Here, the dma_addr_t returned from - * dma_map_single() is implicitly cast as a - * u32. Although dma_addr_t can be - * 64-bit, the address returned by - * dma_map_single() is always 32-bit - * addressable (as defined by the pci/dma - * subsystem) - */ - desc[frag++].addr_lo = - dma_map_single(&adapter->pdev->dev, - skb->data, - skb_headlen(skb), - DMA_TO_DEVICE); + dma_addr = dma_map_single(&adapter->pdev->dev, + skb->data, + skb_headlen(skb), + DMA_TO_DEVICE); + desc[frag].addr_lo = lower_32_bits(dma_addr); + desc[frag].addr_hi = upper_32_bits(dma_addr); + frag++; } else { - desc[frag].addr_hi = 0; desc[frag].len_vlan = skb_headlen(skb) / 2; - - /* NOTE: Here, the dma_addr_t returned from - * dma_map_single() is implicitly cast as a - * u32. Although dma_addr_t can be - * 64-bit, the address returned by - * dma_map_single() is always 32-bit - * addressable (as defined by the pci/dma - * subsystem) - */ - desc[frag++].addr_lo = - dma_map_single(&adapter->pdev->dev, - skb->data, - (skb_headlen(skb) / 2), - DMA_TO_DEVICE); - desc[frag].addr_hi = 0; + dma_addr = dma_map_single(&adapter->pdev->dev, + skb->data, + (skb_headlen(skb) / 2), + DMA_TO_DEVICE); + desc[frag].addr_lo = lower_32_bits(dma_addr); + desc[frag].addr_hi = upper_32_bits(dma_addr); + frag++; desc[frag].len_vlan = skb_headlen(skb) / 2; - - /* NOTE: Here, the dma_addr_t returned from - * dma_map_single() is implicitly cast as a - * u32. Although dma_addr_t can be - * 64-bit, the address returned by - * dma_map_single() is always 32-bit - * addressable (as defined by the pci/dma - * subsystem) - */ - desc[frag++].addr_lo = - dma_map_single(&adapter->pdev->dev, - skb->data + - (skb_headlen(skb) / 2), - (skb_headlen(skb) / 2), - DMA_TO_DEVICE); + dma_addr = dma_map_single(&adapter->pdev->dev, + skb->data + + (skb_headlen(skb) / 2), + (skb_headlen(skb) / 2), + DMA_TO_DEVICE); + desc[frag].addr_lo = lower_32_bits(dma_addr); + desc[frag].addr_hi = upper_32_bits(dma_addr); + frag++; } } else { - desc[frag].addr_hi = 0; - desc[frag].len_vlan = - frags[i - 1].size; - - /* NOTE: Here, the dma_addr_t returned from - * dma_map_page() is implicitly cast as a u32. - * Although dma_addr_t can be 64-bit, the address - * returned by dma_map_page() is always 32-bit - * addressable (as defined by the pci/dma subsystem) - */ - desc[frag++].addr_lo = skb_frag_dma_map( - &adapter->pdev->dev, - &frags[i - 1], - 0, - frags[i - 1].size, - DMA_TO_DEVICE); + desc[frag].len_vlan = frags[i - 1].size; + dma_addr = skb_frag_dma_map(&adapter->pdev->dev, + &frags[i - 1], + 0, + frags[i - 1].size, + DMA_TO_DEVICE); + desc[frag].addr_lo = lower_32_bits(dma_addr); + desc[frag].addr_hi = upper_32_bits(dma_addr); + frag++; } } @@ -3611,6 +3581,7 @@ static inline void free_send_packet(struct et131x_adapter *adapter, unsigned long flags; struct tx_desc *desc = NULL; struct net_device_stats *stats = &adapter->net_stats; + dma_addr_t dma_addr; if (tcb->flags & fMP_DEST_BROAD) atomic_inc(&adapter->stats.broadcast_pkts_xmtd); @@ -3631,8 +3602,13 @@ static inline void free_send_packet(struct et131x_adapter *adapter, (adapter->tx_ring.tx_desc_ring + INDEX10(tcb->index_start)); + dma_addr = desc->addr_lo; + + if (sizeof(dma_addr_t) == sizeof(u64)) + dma_addr |= ((dma_addr_t)desc->addr_hi) << 32; + dma_unmap_single(&adapter->pdev->dev, - desc->addr_lo, + dma_addr, desc->len_vlan, DMA_TO_DEVICE); add_10bit(&tcb->index_start, 1); -- cgit v1.2.3 From 55b45b8ef1f83178c4c87644b87481675909aa3e Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Fri, 19 Oct 2012 23:08:14 +0100 Subject: staging: et131x: Remove fbr_lookup.real_physaddr fbr_lookup.real_physaddr is only being used as a pseudonym for fbr_lookup.ring_physaddr, so remove it and rename all instances to ring_physaddr. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 23d166b2d02..3fd8142742e 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -299,7 +299,6 @@ struct fbr_lookup { dma_addr_t ring_physaddr; void *mem_virtaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; dma_addr_t mem_physaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; - u64 real_physaddr; u64 offset; u32 local_full; u32 num_entries; @@ -1903,9 +1902,9 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) /* Set the address and parameters of Free buffer ring 1 (and 0 if * required) into the 1310's registers */ - writel((u32) (rx_local->fbr[0]->real_physaddr >> 32), + writel((u32) (rx_local->fbr[0]->ring_physaddr >> 32), &rx_dma->fbr1_base_hi); - writel((u32) rx_local->fbr[0]->real_physaddr, &rx_dma->fbr1_base_lo); + writel((u32) rx_local->fbr[0]->ring_physaddr, &rx_dma->fbr1_base_lo); writel(rx_local->fbr[0]->num_entries - 1, &rx_dma->fbr1_num_des); writel(ET_DMA10_WRAP, &rx_dma->fbr1_full_offset); @@ -1927,9 +1926,9 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) fbr_entry++; } - writel((u32) (rx_local->fbr[1]->real_physaddr >> 32), + writel((u32) (rx_local->fbr[1]->ring_physaddr >> 32), &rx_dma->fbr0_base_hi); - writel((u32) rx_local->fbr[1]->real_physaddr, &rx_dma->fbr0_base_lo); + writel((u32) rx_local->fbr[1]->ring_physaddr, &rx_dma->fbr0_base_lo); writel(rx_local->fbr[1]->num_entries - 1, &rx_dma->fbr0_num_des); writel(ET_DMA10_WRAP, &rx_dma->fbr0_full_offset); @@ -2378,18 +2377,9 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) return -ENOMEM; } - /* Save physical address - * - * NOTE: dma_alloc_coherent(), used above to alloc DMA regions, - * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses - * are ever returned, make sure the high part is retrieved here - * before storing the adjusted address. - */ - rx_ring->fbr[0]->real_physaddr = rx_ring->fbr[0]->ring_physaddr; - /* Align Free Buffer Ring 1 on a 4K boundary */ et131x_align_allocated_memory(adapter, - &rx_ring->fbr[0]->real_physaddr, + &rx_ring->fbr[0]->ring_physaddr, &rx_ring->fbr[0]->offset, 0x0FFF); rx_ring->fbr[0]->ring_virtaddr = @@ -2410,18 +2400,9 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) return -ENOMEM; } - /* Save physical address - * - * NOTE: dma_alloc_coherent(), used above to alloc DMA regions, - * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses - * are ever returned, make sure the high part is retrieved here before - * storing the adjusted address. - */ - rx_ring->fbr[1]->real_physaddr = rx_ring->fbr[1]->ring_physaddr; - /* Align Free Buffer Ring 0 on a 4K boundary */ et131x_align_allocated_memory(adapter, - &rx_ring->fbr[1]->real_physaddr, + &rx_ring->fbr[1]->ring_physaddr, &rx_ring->fbr[1]->offset, 0x0FFF); rx_ring->fbr[1]->ring_virtaddr = -- cgit v1.2.3 From 25e8e8ab55c86f61f8c3bf3e361d881895317f80 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Fri, 19 Oct 2012 23:08:15 +0100 Subject: staging: et131x: Use upper_32_bits() instead of '>> 32' '>> 32 of a 32bit value is undefined in C. The compiler is free to do what it likes with this...' Change all uses of '>> 32' to use upper_32_bits() and use the corresponding lower_32_bits() to match. Also remove an incorrect comment about dma alloc always returning 32bit addresses. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 55 +++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 3fd8142742e..32f909aa634 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -1859,25 +1859,17 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) /* Halt RXDMA to perform the reconfigure. */ et131x_rx_dma_disable(adapter); - /* Load the completion writeback physical address - * - * NOTE : dma_alloc_coherent(), used above to alloc DMA regions, - * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses - * are ever returned, make sure the high part is retrieved here - * before storing the adjusted address. - */ - writel((u32) ((u64)rx_local->rx_status_bus >> 32), - &rx_dma->dma_wb_base_hi); - writel((u32) rx_local->rx_status_bus, &rx_dma->dma_wb_base_lo); + /* Load the completion writeback physical address */ + writel(upper_32_bits(rx_local->rx_status_bus), &rx_dma->dma_wb_base_hi); + writel(lower_32_bits(rx_local->rx_status_bus), &rx_dma->dma_wb_base_lo); memset(rx_local->rx_status_block, 0, sizeof(struct rx_status_block)); /* Set the address and parameters of the packet status ring into the * 1310's registers */ - writel((u32) ((u64)rx_local->ps_ring_physaddr >> 32), - &rx_dma->psr_base_hi); - writel((u32) rx_local->ps_ring_physaddr, &rx_dma->psr_base_lo); + writel(upper_32_bits(rx_local->ps_ring_physaddr), &rx_dma->psr_base_hi); + writel(lower_32_bits(rx_local->ps_ring_physaddr), &rx_dma->psr_base_lo); writel(rx_local->psr_num_entries - 1, &rx_dma->psr_num_des); writel(0, &rx_dma->psr_full_offset); @@ -1902,9 +1894,10 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) /* Set the address and parameters of Free buffer ring 1 (and 0 if * required) into the 1310's registers */ - writel((u32) (rx_local->fbr[0]->ring_physaddr >> 32), + writel(upper_32_bits(rx_local->fbr[0]->ring_physaddr), &rx_dma->fbr1_base_hi); - writel((u32) rx_local->fbr[0]->ring_physaddr, &rx_dma->fbr1_base_lo); + writel(lower_32_bits(rx_local->fbr[0]->ring_physaddr), + &rx_dma->fbr1_base_lo); writel(rx_local->fbr[0]->num_entries - 1, &rx_dma->fbr1_num_des); writel(ET_DMA10_WRAP, &rx_dma->fbr1_full_offset); @@ -1926,9 +1919,10 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) fbr_entry++; } - writel((u32) (rx_local->fbr[1]->ring_physaddr >> 32), + writel(upper_32_bits(rx_local->fbr[1]->ring_physaddr), &rx_dma->fbr0_base_hi); - writel((u32) rx_local->fbr[1]->ring_physaddr, &rx_dma->fbr0_base_lo); + writel(lower_32_bits(rx_local->fbr[1]->ring_physaddr), + &rx_dma->fbr0_base_lo); writel(rx_local->fbr[1]->num_entries - 1, &rx_dma->fbr0_num_des); writel(ET_DMA10_WRAP, &rx_dma->fbr0_full_offset); @@ -1970,18 +1964,19 @@ static void et131x_config_tx_dma_regs(struct et131x_adapter *adapter) struct txdma_regs __iomem *txdma = &adapter->regs->txdma; /* Load the hardware with the start of the transmit descriptor ring. */ - writel((u32) ((u64)adapter->tx_ring.tx_desc_ring_pa >> 32), + writel(upper_32_bits(adapter->tx_ring.tx_desc_ring_pa), &txdma->pr_base_hi); - writel((u32) adapter->tx_ring.tx_desc_ring_pa, + writel(lower_32_bits(adapter->tx_ring.tx_desc_ring_pa), &txdma->pr_base_lo); /* Initialise the transmit DMA engine */ writel(NUM_DESC_PER_RING_TX - 1, &txdma->pr_num_des); /* Load the completion writeback physical address */ - writel((u32)((u64)adapter->tx_ring.tx_status_pa >> 32), - &txdma->dma_wb_base_hi); - writel((u32)adapter->tx_ring.tx_status_pa, &txdma->dma_wb_base_lo); + writel(upper_32_bits(adapter->tx_ring.tx_status_pa), + &txdma->dma_wb_base_hi); + writel(lower_32_bits(adapter->tx_ring.tx_status_pa), + &txdma->dma_wb_base_lo); *adapter->tx_ring.tx_status = 0; @@ -2460,16 +2455,16 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) * so the device can access it */ rx_ring->fbr[0]->bus_high[index] = - (u32) (fbr1_tmp_physaddr >> 32); + upper_32_bits(fbr1_tmp_physaddr); rx_ring->fbr[0]->bus_low[index] = - (u32) fbr1_tmp_physaddr; + lower_32_bits(fbr1_tmp_physaddr); fbr1_tmp_physaddr += rx_ring->fbr[0]->buffsize; rx_ring->fbr[0]->buffer1[index] = - rx_ring->fbr[0]->virt[index]; + rx_ring->fbr[0]->virt[index]; rx_ring->fbr[0]->buffer2[index] = - rx_ring->fbr[0]->virt[index] - 4; + rx_ring->fbr[0]->virt[index] - 4; } } @@ -2508,16 +2503,16 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) (j * rx_ring->fbr[1]->buffsize) + fbr0_offset; rx_ring->fbr[1]->bus_high[index] = - (u32) (fbr0_tmp_physaddr >> 32); + upper_32_bits(fbr0_tmp_physaddr); rx_ring->fbr[1]->bus_low[index] = - (u32) fbr0_tmp_physaddr; + lower_32_bits(fbr0_tmp_physaddr); fbr0_tmp_physaddr += rx_ring->fbr[1]->buffsize; rx_ring->fbr[1]->buffer1[index] = - rx_ring->fbr[1]->virt[index]; + rx_ring->fbr[1]->virt[index]; rx_ring->fbr[1]->buffer2[index] = - rx_ring->fbr[1]->virt[index] - 4; + rx_ring->fbr[1]->virt[index] - 4; } } #endif -- cgit v1.2.3 From b5254867f941efa7a621362a98f1349f59473c61 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Fri, 19 Oct 2012 23:08:16 +0100 Subject: staging: et131x: Remove USE_FBR0 define and #ifdefs USE_FBR0 has always been defined, even in the original driver code. Remove the define and #ifdef code to leave the code in the same state. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 58 +++++------------------------------------ 1 file changed, 7 insertions(+), 51 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 32f909aa634..c33cafd5c11 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -176,20 +176,13 @@ MODULE_DESCRIPTION("10/100/1000 Base-T Ethernet Driver for the ET1310 by Agere S #define PARM_DMA_CACHE_DEF 0 /* RX defines */ -#define USE_FBR0 1 #define FBR_CHUNKS 32 #define MAX_DESC_PER_RING_RX 1024 /* number of RFDs - default and min */ -#ifdef USE_FBR0 #define RFD_LOW_WATER_MARK 40 #define NIC_DEFAULT_NUM_RFD 1024 #define NUM_FBRS 2 -#else -#define RFD_LOW_WATER_MARK 20 -#define NIC_DEFAULT_NUM_RFD 256 -#define NUM_FBRS 1 -#endif #define NIC_MIN_NUM_RFD 64 #define NUM_PACKETS_HANDLED 256 @@ -871,7 +864,7 @@ static void et131x_rx_dma_enable(struct et131x_adapter *adapter) csr |= 0x1000; else if (adapter->rx_ring.fbr[0]->buffsize == 16384) csr |= 0x1800; -#ifdef USE_FBR0 + csr |= 0x0400; /* FBR0 enable */ if (adapter->rx_ring.fbr[1]->buffsize == 256) csr |= 0x0100; @@ -879,7 +872,6 @@ static void et131x_rx_dma_enable(struct et131x_adapter *adapter) csr |= 0x0200; else if (adapter->rx_ring.fbr[1]->buffsize == 1024) csr |= 0x0300; -#endif writel(csr, &adapter->regs->rxdma.csr); csr = readl(&adapter->regs->rxdma.csr); @@ -1909,7 +1901,6 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) ((rx_local->fbr[0]->num_entries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, &rx_dma->fbr1_min_des); -#ifdef USE_FBR0 /* Now's the best time to initialize FBR0 contents */ fbr_entry = (struct fbr_desc *) rx_local->fbr[1]->ring_virtaddr; for (entry = 0; entry < rx_local->fbr[1]->num_entries; entry++) { @@ -1933,7 +1924,6 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) writel( ((rx_local->fbr[1]->num_entries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, &rx_dma->fbr0_min_des); -#endif /* Program the number of packets we will receive before generating an * interrupt. @@ -2305,9 +2295,7 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) rx_ring = &adapter->rx_ring; /* Alloc memory for the lookup table */ -#ifdef USE_FBR0 rx_ring->fbr[1] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL); -#endif rx_ring->fbr[0] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL); /* The first thing we will do is configure the sizes of the buffer @@ -2329,35 +2317,25 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) */ if (adapter->registry_jumbo_packet < 2048) { -#ifdef USE_FBR0 rx_ring->fbr[1]->buffsize = 256; rx_ring->fbr[1]->num_entries = 512; -#endif rx_ring->fbr[0]->buffsize = 2048; rx_ring->fbr[0]->num_entries = 512; } else if (adapter->registry_jumbo_packet < 4096) { -#ifdef USE_FBR0 rx_ring->fbr[1]->buffsize = 512; rx_ring->fbr[1]->num_entries = 1024; -#endif rx_ring->fbr[0]->buffsize = 4096; rx_ring->fbr[0]->num_entries = 512; } else { -#ifdef USE_FBR0 rx_ring->fbr[1]->buffsize = 1024; rx_ring->fbr[1]->num_entries = 768; -#endif rx_ring->fbr[0]->buffsize = 16384; rx_ring->fbr[0]->num_entries = 128; } -#ifdef USE_FBR0 adapter->rx_ring.psr_num_entries = adapter->rx_ring.fbr[1]->num_entries + adapter->rx_ring.fbr[0]->num_entries; -#else - adapter->rx_ring.psr_num_entries = adapter->rx_ring.fbr[0]->num_entries; -#endif /* Allocate an area of memory for Free Buffer Ring 1 */ bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr[0]->num_entries) + @@ -2381,7 +2359,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) (void *)((u8 *) rx_ring->fbr[0]->ring_virtaddr + rx_ring->fbr[0]->offset); -#ifdef USE_FBR0 /* Allocate an area of memory for Free Buffer Ring 0 */ bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr[1]->num_entries) + 0xfff; @@ -2403,7 +2380,7 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) rx_ring->fbr[1]->ring_virtaddr = (void *)((u8 *) rx_ring->fbr[1]->ring_virtaddr + rx_ring->fbr[1]->offset); -#endif + for (i = 0; i < (rx_ring->fbr[0]->num_entries / FBR_CHUNKS); i++) { u64 fbr1_tmp_physaddr; u64 fbr1_offset; @@ -2468,7 +2445,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) } } -#ifdef USE_FBR0 /* Same for FBR0 (if in use) */ for (i = 0; i < (rx_ring->fbr[1]->num_entries / FBR_CHUNKS); i++) { u64 fbr0_tmp_physaddr; @@ -2515,7 +2491,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) rx_ring->fbr[1]->virt[index] - 4; } } -#endif /* Allocate an area of memory for FIFO of Packet Status ring entries */ pktstat_ringsize = @@ -2644,7 +2619,6 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) rx_ring->fbr[0]->ring_virtaddr = NULL; } -#ifdef USE_FBR0 /* Now the same for Free Buffer Ring 0 */ if (rx_ring->fbr[1]->ring_virtaddr) { /* First the packet memory */ @@ -2679,7 +2653,6 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) rx_ring->fbr[1]->ring_virtaddr = NULL; } -#endif /* Free Packet Status Ring */ if (rx_ring->ps_ring_virtaddr) { @@ -2709,10 +2682,7 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) } /* Free the FBR Lookup Table */ -#ifdef USE_FBR0 kfree(rx_ring->fbr[1]); -#endif - kfree(rx_ring->fbr[0]); /* Reset Counters */ @@ -2808,9 +2778,7 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) * need to clean up OOB data */ if ( -#ifdef USE_FBR0 (ring_index == 0 && buff_index < rx_local->fbr[1]->num_entries) || -#endif (ring_index == 1 && buff_index < rx_local->fbr[0]->num_entries)) { spin_lock_irqsave(&adapter->fbr_lock, flags); @@ -2831,9 +2799,7 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) &rx_local->fbr[0]->local_full, rx_local->fbr[0]->num_entries - 1), &rx_dma->fbr1_full_offset); - } -#ifdef USE_FBR0 - else { + } else { struct fbr_desc *next = (struct fbr_desc *) rx_local->fbr[1]->ring_virtaddr + INDEX10(rx_local->fbr[1]->local_full); @@ -2851,7 +2817,6 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) rx_local->fbr[1]->num_entries - 1), &rx_dma->fbr0_full_offset); } -#endif spin_unlock_irqrestore(&adapter->fbr_lock, flags); } else { dev_err(&adapter->pdev->dev, @@ -2934,20 +2899,11 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) writel(rx_local->local_psr_full, &adapter->regs->rxdma.psr_full_offset); -#ifndef USE_FBR0 - if (ring_index != 1) - return NULL; -#endif - -#ifdef USE_FBR0 if (ring_index > 1 || - (ring_index == 0 && - buff_index > rx_local->fbr[1]->num_entries - 1) || - (ring_index == 1 && - buff_index > rx_local->fbr[0]->num_entries - 1)) { -#else - if (ring_index != 1 || buff_index > rx_local->fbr[0]->num_entries - 1) { -#endif + (ring_index == 0 && + buff_index > rx_local->fbr[1]->num_entries - 1) || + (ring_index == 1 && + buff_index > rx_local->fbr[0]->num_entries - 1)) { /* Illegal buffer or ring index cannot be used by S/W*/ dev_err(&adapter->pdev->dev, "NICRxPkts PSR Entry %d indicates " -- cgit v1.2.3 From 670d145aa005c4ee024d79615147527a0371c1e4 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Mon, 22 Oct 2012 18:15:41 -0400 Subject: staging: slicoss: fail out if we dont have a valid firmware file fail instead calling request_firmware with filename as a null string and return -ENOENT Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index cd920dad85c..6af8fb49a4a 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -593,8 +593,7 @@ static int slic_card_download(struct adapter *adapter) file = "slicoss/gbdownload.sys"; break; default: - ASSERT(0); - break; + return -ENOENT; } ret = request_firmware(&fw, file, &adapter->pcidev->dev); if (ret) { -- cgit v1.2.3 From 40991e4fa6a91363ee45e8ee774a3c178f8c4159 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Mon, 22 Oct 2012 18:16:07 -0400 Subject: staging: slicoss: remove ASSERT macro altogether remove ASSERT and remove all its callers altogether in the code Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 140 +------------------------------------- 1 file changed, 2 insertions(+), 138 deletions(-) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 6af8fb49a4a..94542808491 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -142,39 +142,12 @@ static DEFINE_PCI_DEVICE_TABLE(slic_pci_tbl) = { MODULE_DEVICE_TABLE(pci, slic_pci_tbl); -#ifdef ASSERT -#undef ASSERT -#endif - -static void slic_assert_fail(void) -{ - u32 cpuid; - u32 curr_pid; - cpuid = smp_processor_id(); - curr_pid = current->pid; - - printk(KERN_ERR "%s CPU # %d ---- PID # %d\n", - __func__, cpuid, curr_pid); -} - -#ifndef ASSERT -#define ASSERT(a) do { \ - if (!(a)) { \ - printk(KERN_ERR "slicoss ASSERT() Failure: function %s" \ - "line %d\n", __func__, __LINE__); \ - slic_assert_fail(); \ - } \ -} while (0) -#endif - - #define SLIC_GET_SLIC_HANDLE(_adapter, _pslic_handle) \ { \ spin_lock_irqsave(&_adapter->handle_lock.lock, \ _adapter->handle_lock.flags); \ _pslic_handle = _adapter->pfree_slic_handles; \ if (_pslic_handle) { \ - ASSERT(_pslic_handle->type == SLIC_HANDLE_FREE); \ _adapter->pfree_slic_handles = _pslic_handle->next; \ } \ spin_unlock_irqrestore(&_adapter->handle_lock.lock, \ @@ -325,11 +298,8 @@ static void slic_timer_ping(ulong dev) struct adapter *adapter; struct sliccard *card; - ASSERT(dev); adapter = netdev_priv((struct net_device *)dev); - ASSERT(adapter); card = adapter->card; - ASSERT(card); adapter->pingtimer.expires = jiffies + (PING_TIMER_INTERVAL * HZ); add_timer(&adapter->pingtimer); @@ -361,9 +331,6 @@ static void slic_link_config(struct adapter *adapter, if (adapter->state != ADAPT_UP) return; - ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID) - || (adapter->devid == SLIC_2GB_DEVICE_ID)); - if (linkspeed > LINK_1000MB) linkspeed = LINK_AUTOSPEED; if (linkduplex > LINK_AUTOD) @@ -603,7 +570,6 @@ static int slic_card_download(struct adapter *adapter) } numsects = *(u32 *)(fw->data + index); index += 4; - ASSERT(numsects <= 3); for (i = 0; i < numsects; i++) { sectsize[i] = *(u32 *)(fw->data + index); index += 4; @@ -1059,8 +1025,6 @@ static void slic_upr_start(struct adapter *adapter) case SLIC_UPR_PING: slic_reg32_write(&slic_regs->slic_ping, 1, FLUSH); break; - default: - ASSERT(0); } } @@ -1115,9 +1079,6 @@ static void slic_link_upr_complete(struct adapter *adapter, u32 isr) if (adapter->state != ADAPT_UP) return; - ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID) - || (adapter->devid == SLIC_2GB_DEVICE_ID)); - linkup = linkstatus & GIG_LINKUP ? LINK_UP : LINK_DOWN; if (linkstatus & GIG_SPEED_1000) linkspeed = LINK_1000MB; @@ -1169,7 +1130,6 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr) spin_lock_irqsave(&adapter->upr_lock.lock, adapter->upr_lock.flags); upr = adapter->upr_list; if (!upr) { - ASSERT(0); spin_unlock_irqrestore(&adapter->upr_lock.lock, adapter->upr_lock.flags); return; @@ -1177,7 +1137,6 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr) adapter->upr_list = upr->next; upr->next = NULL; adapter->upr_busy = 0; - ASSERT(adapter->port == upr->adapter); switch (upr->upr_request) { case SLIC_UPR_STATS: { @@ -1259,23 +1218,9 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr) break; case SLIC_UPR_RCONFIG: break; - case SLIC_UPR_RPHY: - ASSERT(0); - break; - case SLIC_UPR_ENLB: - ASSERT(0); - break; - case SLIC_UPR_ENCT: - ASSERT(0); - break; - case SLIC_UPR_PDWN: - ASSERT(0); - break; case SLIC_UPR_PING: card->pingstatus |= (isr & ISR_PINGDSMASK); break; - default: - ASSERT(0); } kfree(upr); slic_upr_start(adapter); @@ -1291,7 +1236,6 @@ static void slic_config_get(struct adapter *adapter, u32 config, status = slic_upr_request(adapter, SLIC_UPR_RCONFIG, (u32) config, (u32) config_h, 0, 0); - ASSERT(status == 0); } /* @@ -1421,7 +1365,6 @@ static int slic_rspqueue_init(struct adapter *adapter) __iomem struct slic_regs *slic_regs = adapter->slic_regs; u32 paddrh = 0; - ASSERT(adapter->state == ADAPT_DOWN); memset(rspq, 0, sizeof(struct slic_rspqueue)); rspq->num_pages = SLIC_RSPQ_PAGES_GB; @@ -1438,14 +1381,6 @@ static int slic_rspqueue_init(struct adapter *adapter) } /* FIXME: * do we really need this assertions (4K PAGE_SIZE aligned addr)? */ -#if 0 -#ifndef CONFIG_X86_64 - ASSERT(((u32) rspq->vaddr[i] & 0xFFFFF000) == - (u32) rspq->vaddr[i]); - ASSERT(((u32) rspq->paddr[i] & 0xFFFFF000) == - (u32) rspq->paddr[i]); -#endif -#endif memset(rspq->vaddr[i], 0, PAGE_SIZE); if (paddrh == 0) { @@ -1474,18 +1409,9 @@ static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter) return NULL; buf = rspq->rspbuf; -#if BITS_PER_LONG == 32 - ASSERT((buf->status & 0xFFFFFFE0) == 0); -#endif - ASSERT(buf->hosthandle); if (++rspq->offset < SLIC_RSPQ_BUFSINPAGE) { rspq->rspbuf++; -#if BITS_PER_LONG == 32 - ASSERT(((u32) rspq->rspbuf & 0xFFFFFFE0) == - (u32) rspq->rspbuf); -#endif } else { - ASSERT(rspq->offset == SLIC_RSPQ_BUFSINPAGE); slic_reg64_write(adapter, &adapter->slic_regs->slic_rbar64, (rspq->paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE), &adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH); @@ -1493,14 +1419,8 @@ static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter) rspq->offset = 0; rspq->rspbuf = (struct slic_rspbuf *) rspq->vaddr[rspq->pageindex]; -#if BITS_PER_LONG == 32 - ASSERT(((u32) rspq->rspbuf & 0xFFFFF000) == - (u32) rspq->rspbuf); -#endif } -#if BITS_PER_LONG == 32 - ASSERT(((u32) buf & 0xFFFFFFE0) == (u32) buf); -#endif + return buf; } @@ -1539,9 +1459,7 @@ static u32 *slic_cmdqmem_addpage(struct adapter *adapter) &cmdqmem->dma_pages[cmdqmem->pagecnt]); if (!pageaddr) return NULL; -#if BITS_PER_LONG == 32 - ASSERT(((u32) pageaddr & 0xFFFFF000) == (u32) pageaddr); -#endif + cmdqmem->pages[cmdqmem->pagecnt] = pageaddr; cmdqmem->pagecnt++; return pageaddr; @@ -1597,11 +1515,6 @@ static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page) (adapter->slic_handle_ix < 256)) { /* Allocate and initialize a SLIC_HANDLE for this command */ SLIC_GET_SLIC_HANDLE(adapter, pslic_handle); - if (pslic_handle == NULL) - ASSERT(0); - ASSERT(pslic_handle == - &adapter->slic_handles[pslic_handle->token. - handle_index]); pslic_handle->type = SLIC_HANDLE_CMD; pslic_handle->address = (void *) cmd; pslic_handle->offset = (ushort) adapter->slic_handle_ix++; @@ -1640,7 +1553,6 @@ static int slic_cmdq_init(struct adapter *adapter) int i; u32 *pageaddr; - ASSERT(adapter->state == ADAPT_DOWN); memset(&adapter->cmdq_all, 0, sizeof(struct slic_cmdqueue)); memset(&adapter->cmdq_free, 0, sizeof(struct slic_cmdqueue)); memset(&adapter->cmdq_done, 0, sizeof(struct slic_cmdqueue)); @@ -1651,9 +1563,6 @@ static int slic_cmdq_init(struct adapter *adapter) adapter->slic_handle_ix = 1; for (i = 0; i < SLIC_CMDQ_INITPAGES; i++) { pageaddr = slic_cmdqmem_addpage(adapter); -#if BITS_PER_LONG == 32 - ASSERT(((u32) pageaddr & 0xFFFFF000) == (u32) pageaddr); -#endif if (!pageaddr) { slic_cmdq_free(adapter); return -ENOMEM; @@ -1681,7 +1590,6 @@ static void slic_cmdq_reset(struct adapter *adapter) while (hcmd) { if (hcmd->busy) { skb = hcmd->skb; - ASSERT(skb); hcmd->busy = 0; hcmd->skb = NULL; dev_kfree_skb_irq(skb); @@ -1717,7 +1625,6 @@ static void slic_cmdq_getdone(struct adapter *adapter) struct slic_cmdqueue *done_cmdq = &adapter->cmdq_done; struct slic_cmdqueue *free_cmdq = &adapter->cmdq_free; - ASSERT(free_cmdq->head == NULL); spin_lock_irqsave(&done_cmdq->lock.lock, done_cmdq->lock.flags); free_cmdq->head = done_cmdq->head; @@ -1883,7 +1790,6 @@ static int slic_rcvqueue_init(struct adapter *adapter) int i, count; struct slic_rcvqueue *rcvq = &adapter->rcvqueue; - ASSERT(adapter->state == ADAPT_DOWN); rcvq->tail = NULL; rcvq->head = NULL; rcvq->size = SLIC_RCVQ_ENTRIES; @@ -1912,7 +1818,6 @@ static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter) if (rcvq->count) { skb = rcvq->head; rcvbuf = (struct slic_rcvbuf *)skb->head; - ASSERT(rcvbuf); if (rcvbuf->status & IRHDDR_SVALID) { rcvq->head = rcvq->head->next; @@ -1945,8 +1850,6 @@ static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb) struct slic_rcvbuf *rcvbuf = (struct slic_rcvbuf *)skb->head; struct device *dev; - ASSERT(skb->len == SLIC_RCVBUF_HEADSIZE); - paddr = (void *)pci_map_single(adapter->pcidev, skb->head, SLIC_RCVQ_RCVBUFSIZE, PCI_DMA_FROMDEVICE); rcvbuf->status = 0; @@ -2018,7 +1921,6 @@ static int slic_debug_card_show(struct seq_file *seq, void *v) card->adapters_activated); seq_printf(seq, " Allocated : %d\n", card->adapters_allocated); - ASSERT(card->card_size <= SLIC_NBR_MACS); for (i = 0; i < card->card_size; i++) { seq_printf(seq, " MAC%d : %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n", @@ -2459,7 +2361,6 @@ static void slic_link_event_handler(struct adapter *adapter) (u32) &pshmem->linkstatus, /* no 4GB wrap guaranteed */ 0, 0, 0); #endif - ASSERT(status == 0); } static void slic_init_cleanup(struct adapter *adapter) @@ -2523,8 +2424,6 @@ static void slic_mcast_set_list(struct net_device *dev) char *addresses; struct netdev_hw_addr *ha; - ASSERT(adapter); - netdev_for_each_mc_addr(ha, dev) { addresses = (char *) &ha->addr; status = slic_mcast_add_list(adapter, addresses); @@ -2611,8 +2510,6 @@ static void slic_xmit_fail(struct adapter *adapter, "xmit_start skb[%p] type[%x] No host commands " "available\n", skb, skb->pkt_type); break; - default: - ASSERT(0); } } dev_kfree_skb(skb); @@ -2724,7 +2621,6 @@ static void slic_rcv_handler(struct adapter *adapter) while ((skb = slic_rcvqueue_getnext(adapter))) { u32 rx_bytes; - ASSERT(skb->head); rcvbuf = (struct slic_rcvbuf *)skb->head; adapter->card->events++; if (rcvbuf->status & IRHDDR_ERR) { @@ -2780,16 +2676,11 @@ static void slic_xmit_complete(struct adapter *adapter) Get the complete host command buffer */ slic_handle_word.handle_token = rspbuf->hosthandle; - ASSERT(slic_handle_word.handle_index); - ASSERT(slic_handle_word.handle_index <= SLIC_CMDQ_MAXCMDS); hcmd = (struct slic_hostcmd *) adapter->slic_handles[slic_handle_word.handle_index]. address; /* hcmd = (struct slic_hostcmd *) rspbuf->hosthandle; */ - ASSERT(hcmd); - ASSERT(hcmd->pslic_handle == - &adapter->slic_handles[slic_handle_word.handle_index]); if (hcmd->type == SLIC_CMD_DUMB) { if (hcmd->skb) dev_kfree_skb_irq(hcmd->skb); @@ -2910,7 +2801,6 @@ static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev) void *offloadcmd = NULL; card = adapter->card; - ASSERT(card); if ((adapter->linkstate != LINK_UP) || (adapter->state != ADAPT_UP) || (card->state != CARD_UP)) { status = XMIT_FAIL_LINK_STATE; @@ -2928,9 +2818,6 @@ static netdev_tx_t slic_xmit_start(struct sk_buff *skb, struct net_device *dev) status = XMIT_FAIL_HOSTCMD_FAIL; goto xmit_fail; } - ASSERT(hcmd->pslic_handle); - ASSERT(hcmd->cmd64.hosthandle == - hcmd->pslic_handle->token.handle_token); hcmd->skb = skb; hcmd->busy = 1; hcmd->type = SLIC_CMD_DUMB; @@ -3023,8 +2910,6 @@ static int slic_if_init(struct adapter *adapter) struct slic_shmem *pshmem; int rc; - ASSERT(card); - /* adapter should be down at this point */ if (adapter->state != ADAPT_DOWN) { dev_err(&dev->dev, "%s: adapter->state != ADAPT_DOWN\n", @@ -3032,7 +2917,6 @@ static int slic_if_init(struct adapter *adapter) rc = -EIO; goto err; } - ASSERT(adapter->linkstate == LINK_DOWN); adapter->devflags_prev = dev->flags; adapter->macopts = MAC_DIRECTED; @@ -3132,9 +3016,6 @@ static int slic_entry_open(struct net_device *dev) struct sliccard *card = adapter->card; int status; - ASSERT(adapter); - ASSERT(card); - netif_stop_queue(adapter->netdev); spin_lock_irqsave(&slic_global.driver_lock.lock, @@ -3201,9 +3082,7 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev) mlist = mlist->next; kfree(mcaddr); } - ASSERT(adapter->card); card = adapter->card; - ASSERT(card->adapters_allocated); card->adapters_allocated--; adapter->allocated = 0; if (!card->adapters_allocated) { @@ -3213,10 +3092,8 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev) } else { while (curr_card->next != card) curr_card = curr_card->next; - ASSERT(curr_card); curr_card->next = card->next; } - ASSERT(slic_global.num_slic_cards); slic_global.num_slic_cards--; slic_card_cleanup(card); } @@ -3233,14 +3110,12 @@ static int slic_entry_halt(struct net_device *dev) spin_lock_irqsave(&slic_global.driver_lock.lock, slic_global.driver_lock.flags); - ASSERT(card); netif_stop_queue(adapter->netdev); adapter->state = ADAPT_DOWN; adapter->linkstate = LINK_DOWN; adapter->upr_list = NULL; adapter->upr_busy = 0; adapter->devflags_prev = 0; - ASSERT(card->adapter[adapter->cardindex] == adapter); slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH); adapter->all_reg_writes++; adapter->icr_reg_writes++; @@ -3272,7 +3147,6 @@ static struct net_device_stats *slic_get_stats(struct net_device *dev) { struct adapter *adapter = netdev_priv(dev); - ASSERT(adapter); dev->stats.collisions = adapter->slic_stats.iface.xmit_collisions; dev->stats.rx_errors = adapter->slic_stats.iface.rcv_errors; dev->stats.tx_errors = adapter->slic_stats.iface.xmt_errors; @@ -3295,7 +3169,6 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) u32 data[7]; u32 intagg; - ASSERT(rq); switch (cmd) { case SIOCSLICSETINTAGG: if (copy_from_user(data, rq->ifr_data, 28)) @@ -3341,7 +3214,6 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } #endif case SIOCETHTOOL: - ASSERT(adapter); if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd))) return -EFAULT; @@ -3681,7 +3553,6 @@ static void slic_init_adapter(struct net_device *netdev, /* Initialize slic_handle array */ - ASSERT(SLIC_CMDQ_MAXCMDS <= 0xFFFF); /* Start with 1. 0 is an invalid host handle. */ @@ -3698,8 +3569,6 @@ static void slic_init_adapter(struct net_device *netdev, sizeof(struct slic_shmem), &adapter-> phys_shmem); - ASSERT(adapter->pshmem); - if (adapter->pshmem) memset(adapter->pshmem, 0, sizeof(struct slic_shmem)); } @@ -3774,11 +3643,9 @@ static u32 slic_card_locate(struct adapter *adapter) } } - ASSERT(card); if (!card) return -ENXIO; /* Put the adapter in the card's adapter list */ - ASSERT(card->adapter[adapter->port] == NULL); if (!card->adapter[adapter->port]) { card->adapter[adapter->port] = adapter; adapter->card = card; @@ -3793,7 +3660,6 @@ static u32 slic_card_locate(struct adapter *adapter) else break; } - ASSERT(i != SLIC_MAX_PORTS); if (physcard->adapter[i]->slotnumber == adapter->slotnumber) break; physcard = physcard->next; @@ -3801,7 +3667,6 @@ static u32 slic_card_locate(struct adapter *adapter) if (!physcard) { /* no structure allocated for this physical card yet */ physcard = kzalloc(sizeof(struct physcard), GFP_ATOMIC); - ASSERT(physcard); physcard->next = slic_global.phys_card; slic_global.phys_card = physcard; @@ -3812,7 +3677,6 @@ static u32 slic_card_locate(struct adapter *adapter) /* Note - this is ZERO relative */ adapter->physport = physcard->adapters_allocd - 1; - ASSERT(physcard->adapter[adapter->physport] == NULL); physcard->adapter[adapter->physport] = adapter; adapter->physcard = physcard; -- cgit v1.2.3 From 5f986c590fcf4284924fcda991cf14ab32bff49f Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 23 Oct 2012 01:07:27 +0200 Subject: PM / QoS: Prepare device structure for adding more constraint types Currently struct dev_pm_info contains only one PM QoS constraints pointer reserved for latency requirements. Since one more device constraints type (i.e. flags) will be necessary, introduce a new structure, struct dev_pm_qos, that eventually will contain all of the available device PM QoS constraints and replace the "constraints" pointer in struct dev_pm_info with a pointer to the new structure called "qos". Signed-off-by: Rafael J. Wysocki Reviewed-by: Jean Pihet --- drivers/base/power/qos.c | 42 ++++++++++++++++++++++-------------------- include/linux/pm.h | 2 +- include/linux/pm_qos.h | 4 ++++ 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 74a67e0019a..40ff1b02a7c 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -55,9 +55,7 @@ static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers); */ s32 __dev_pm_qos_read_value(struct device *dev) { - struct pm_qos_constraints *c = dev->power.constraints; - - return c ? pm_qos_read_value(c) : 0; + return dev->power.qos ? pm_qos_read_value(&dev->power.qos->latency) : 0; } /** @@ -91,12 +89,12 @@ static int apply_constraint(struct dev_pm_qos_request *req, { int ret, curr_value; - ret = pm_qos_update_target(req->dev->power.constraints, + ret = pm_qos_update_target(&req->dev->power.qos->latency, &req->node, action, value); if (ret) { /* Call the global callbacks if needed */ - curr_value = pm_qos_read_value(req->dev->power.constraints); + curr_value = pm_qos_read_value(&req->dev->power.qos->latency); blocking_notifier_call_chain(&dev_pm_notifiers, (unsigned long)curr_value, req); @@ -114,20 +112,22 @@ static int apply_constraint(struct dev_pm_qos_request *req, */ static int dev_pm_qos_constraints_allocate(struct device *dev) { + struct dev_pm_qos *qos; struct pm_qos_constraints *c; struct blocking_notifier_head *n; - c = kzalloc(sizeof(*c), GFP_KERNEL); - if (!c) + qos = kzalloc(sizeof(*qos), GFP_KERNEL); + if (!qos) return -ENOMEM; n = kzalloc(sizeof(*n), GFP_KERNEL); if (!n) { - kfree(c); + kfree(qos); return -ENOMEM; } BLOCKING_INIT_NOTIFIER_HEAD(n); + c = &qos->latency; plist_head_init(&c->list); c->target_value = PM_QOS_DEV_LAT_DEFAULT_VALUE; c->default_value = PM_QOS_DEV_LAT_DEFAULT_VALUE; @@ -135,7 +135,7 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) c->notifiers = n; spin_lock_irq(&dev->power.lock); - dev->power.constraints = c; + dev->power.qos = qos; spin_unlock_irq(&dev->power.lock); return 0; @@ -151,7 +151,7 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) void dev_pm_qos_constraints_init(struct device *dev) { mutex_lock(&dev_pm_qos_mtx); - dev->power.constraints = NULL; + dev->power.qos = NULL; dev->power.power_state = PMSG_ON; mutex_unlock(&dev_pm_qos_mtx); } @@ -164,6 +164,7 @@ void dev_pm_qos_constraints_init(struct device *dev) */ void dev_pm_qos_constraints_destroy(struct device *dev) { + struct dev_pm_qos *qos; struct dev_pm_qos_request *req, *tmp; struct pm_qos_constraints *c; @@ -176,10 +177,11 @@ void dev_pm_qos_constraints_destroy(struct device *dev) mutex_lock(&dev_pm_qos_mtx); dev->power.power_state = PMSG_INVALID; - c = dev->power.constraints; - if (!c) + qos = dev->power.qos; + if (!qos) goto out; + c = &qos->latency; /* Flush the constraints list for the device */ plist_for_each_entry_safe(req, tmp, &c->list, node) { /* @@ -191,7 +193,7 @@ void dev_pm_qos_constraints_destroy(struct device *dev) } spin_lock_irq(&dev->power.lock); - dev->power.constraints = NULL; + dev->power.qos = NULL; spin_unlock_irq(&dev->power.lock); kfree(c->notifiers); @@ -235,7 +237,7 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, mutex_lock(&dev_pm_qos_mtx); - if (!dev->power.constraints) { + if (!dev->power.qos) { if (dev->power.power_state.event == PM_EVENT_INVALID) { /* The device has been removed from the system. */ req->dev = NULL; @@ -290,7 +292,7 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, mutex_lock(&dev_pm_qos_mtx); - if (req->dev->power.constraints) { + if (req->dev->power.qos) { if (new_value != req->node.prio) ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value); @@ -329,7 +331,7 @@ int dev_pm_qos_remove_request(struct dev_pm_qos_request *req) mutex_lock(&dev_pm_qos_mtx); - if (req->dev->power.constraints) { + if (req->dev->power.qos) { ret = apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); memset(req, 0, sizeof(*req)); @@ -362,13 +364,13 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier) mutex_lock(&dev_pm_qos_mtx); - if (!dev->power.constraints) + if (!dev->power.qos) ret = dev->power.power_state.event != PM_EVENT_INVALID ? dev_pm_qos_constraints_allocate(dev) : -ENODEV; if (!ret) ret = blocking_notifier_chain_register( - dev->power.constraints->notifiers, notifier); + dev->power.qos->latency.notifiers, notifier); mutex_unlock(&dev_pm_qos_mtx); return ret; @@ -393,9 +395,9 @@ int dev_pm_qos_remove_notifier(struct device *dev, mutex_lock(&dev_pm_qos_mtx); /* Silently return if the constraints object is not present. */ - if (dev->power.constraints) + if (dev->power.qos) retval = blocking_notifier_chain_unregister( - dev->power.constraints->notifiers, + dev->power.qos->latency.notifiers, notifier); mutex_unlock(&dev_pm_qos_mtx); diff --git a/include/linux/pm.h b/include/linux/pm.h index 007e687c4f6..0ce6df94221 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -549,7 +549,7 @@ struct dev_pm_info { struct dev_pm_qos_request *pq_req; #endif struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */ - struct pm_qos_constraints *constraints; + struct dev_pm_qos *qos; }; extern void update_pm_runtime_accounting(struct device *dev); diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 9924ea1f22e..30e9ad72e79 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -57,6 +57,10 @@ struct pm_qos_constraints { struct blocking_notifier_head *notifiers; }; +struct dev_pm_qos { + struct pm_qos_constraints latency; +}; + /* Action requested to pm_qos_update_target */ enum pm_qos_req_action { PM_QOS_ADD_REQ, /* Add a new request */ -- cgit v1.2.3 From 5efbe4279f959a3f5ed26adf5f05cb78dd1ffa7e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 23 Oct 2012 01:07:46 +0200 Subject: PM / QoS: Introduce request and constraint data types for PM QoS flags Introduce struct pm_qos_flags_request and struct pm_qos_flags representing PM QoS flags request type and PM QoS flags constraint type, respectively. With these definitions the data structures will be arranged so that the list member of a struct pm_qos_flags object will contain the head of a list of struct pm_qos_flags_request objects representing all of the "flags" requests present for the given device. Then, the effective_flags member of a struct pm_qos_flags object will contain the bitwise OR of the flags members of all the struct pm_qos_flags_request objects in the list. Additionally, introduce helper function pm_qos_update_flags() allowing the caller to manage the list of struct pm_qos_flags_request pointed to by the list member of struct pm_qos_flags. The flags are of type s32 so that the request's "value" field is always of the same type regardless of what kind of request it is (latency requests already have value fields of type s32). Signed-off-by: Rafael J. Wysocki Reviewed-by: Jean Pihet Acked-by: mark gross --- include/linux/pm_qos.h | 17 ++++++++++++-- kernel/power/qos.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 30e9ad72e79..413ada3c7c9 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -33,6 +33,11 @@ struct pm_qos_request { struct delayed_work work; /* for pm_qos_update_request_timeout */ }; +struct pm_qos_flags_request { + struct list_head node; + s32 flags; /* Do not change to 64 bit */ +}; + struct dev_pm_qos_request { struct plist_node node; struct device *dev; @@ -45,8 +50,8 @@ enum pm_qos_type { }; /* - * Note: The lockless read path depends on the CPU accessing - * target_value atomically. Atomic access is only guaranteed on all CPU + * Note: The lockless read path depends on the CPU accessing target_value + * or effective_flags atomically. Atomic access is only guaranteed on all CPU * types linux supports for 32 bit quantites */ struct pm_qos_constraints { @@ -57,6 +62,11 @@ struct pm_qos_constraints { struct blocking_notifier_head *notifiers; }; +struct pm_qos_flags { + struct list_head list; + s32 effective_flags; /* Do not change to 64 bit */ +}; + struct dev_pm_qos { struct pm_qos_constraints latency; }; @@ -75,6 +85,9 @@ static inline int dev_pm_qos_request_active(struct dev_pm_qos_request *req) int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, enum pm_qos_req_action action, int value); +bool pm_qos_update_flags(struct pm_qos_flags *pqf, + struct pm_qos_flags_request *req, + enum pm_qos_req_action action, s32 val); void pm_qos_add_request(struct pm_qos_request *req, int pm_qos_class, s32 value); void pm_qos_update_request(struct pm_qos_request *req, diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 846bd42c7ed..2ab2819aee6 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -212,6 +212,69 @@ int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node, } } +/** + * pm_qos_flags_remove_req - Remove device PM QoS flags request. + * @pqf: Device PM QoS flags set to remove the request from. + * @req: Request to remove from the set. + */ +static void pm_qos_flags_remove_req(struct pm_qos_flags *pqf, + struct pm_qos_flags_request *req) +{ + s32 val = 0; + + list_del(&req->node); + list_for_each_entry(req, &pqf->list, node) + val |= req->flags; + + pqf->effective_flags = val; +} + +/** + * pm_qos_update_flags - Update a set of PM QoS flags. + * @pqf: Set of flags to update. + * @req: Request to add to the set, to modify, or to remove from the set. + * @action: Action to take on the set. + * @val: Value of the request to add or modify. + * + * Update the given set of PM QoS flags and call notifiers if the aggregate + * value has changed. Returns 1 if the aggregate constraint value has changed, + * 0 otherwise. + */ +bool pm_qos_update_flags(struct pm_qos_flags *pqf, + struct pm_qos_flags_request *req, + enum pm_qos_req_action action, s32 val) +{ + unsigned long irqflags; + s32 prev_value, curr_value; + + spin_lock_irqsave(&pm_qos_lock, irqflags); + + prev_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags; + + switch (action) { + case PM_QOS_REMOVE_REQ: + pm_qos_flags_remove_req(pqf, req); + break; + case PM_QOS_UPDATE_REQ: + pm_qos_flags_remove_req(pqf, req); + case PM_QOS_ADD_REQ: + req->flags = val; + INIT_LIST_HEAD(&req->node); + list_add_tail(&req->node, &pqf->list); + pqf->effective_flags |= val; + break; + default: + /* no action */ + ; + } + + curr_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags; + + spin_unlock_irqrestore(&pm_qos_lock, irqflags); + + return prev_value != curr_value; +} + /** * pm_qos_request - returns current system wide qos expectation * @pm_qos_class: identification of which qos value is requested -- cgit v1.2.3 From 021c870ba4ab4bc9a23d5db4e324f50f26d8ab24 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 23 Oct 2012 01:09:00 +0200 Subject: PM / QoS: Prepare struct dev_pm_qos_request for more request types The subsequent patches will use struct dev_pm_qos_request for representing both latency requests and flags requests. To make that easier, put the node member of struct dev_pm_qos_request (under the name "pnode") into a union called "data" that will represent the request's value and list node depending on its type. Signed-off-by: Rafael J. Wysocki Reviewed-by: Jean Pihet Reviewed-by: mark gross --- drivers/base/power/qos.c | 6 +++--- drivers/base/power/sysfs.c | 2 +- include/linux/pm_qos.h | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 40ff1b02a7c..96d27b821bb 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -90,7 +90,7 @@ static int apply_constraint(struct dev_pm_qos_request *req, int ret, curr_value; ret = pm_qos_update_target(&req->dev->power.qos->latency, - &req->node, action, value); + &req->data.pnode, action, value); if (ret) { /* Call the global callbacks if needed */ @@ -183,7 +183,7 @@ void dev_pm_qos_constraints_destroy(struct device *dev) c = &qos->latency; /* Flush the constraints list for the device */ - plist_for_each_entry_safe(req, tmp, &c->list, node) { + plist_for_each_entry_safe(req, tmp, &c->list, data.pnode) { /* * Update constraints list and call the notification * callbacks if needed @@ -293,7 +293,7 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, mutex_lock(&dev_pm_qos_mtx); if (req->dev->power.qos) { - if (new_value != req->node.prio) + if (new_value != req->data.pnode.prio) ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value); } else { diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index b91dc6f1e91..54c61ffa204 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -221,7 +221,7 @@ static DEVICE_ATTR(autosuspend_delay_ms, 0644, autosuspend_delay_ms_show, static ssize_t pm_qos_latency_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", dev->power.pq_req->node.prio); + return sprintf(buf, "%d\n", dev->power.pq_req->data.pnode.prio); } static ssize_t pm_qos_latency_store(struct device *dev, diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 413ada3c7c9..3b9d14964d2 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -39,7 +39,9 @@ struct pm_qos_flags_request { }; struct dev_pm_qos_request { - struct plist_node node; + union { + struct plist_node pnode; + } data; struct device *dev; }; -- cgit v1.2.3 From ae0fb4b72c8db7e6c4ef32bc58a43a759ad414b9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 23 Oct 2012 01:09:12 +0200 Subject: PM / QoS: Introduce PM QoS device flags support Modify the device PM QoS core code to support PM QoS flags requests. First, add a new field of type struct pm_qos_flags called "flags" to struct dev_pm_qos for representing the list of PM QoS flags requests for the given device. Accordingly, add a new "type" field to struct dev_pm_qos_request (along with an enum for representing request types) and a new member called "flr" to its data union for representig flags requests. Second, modify dev_pm_qos_add_request(), dev_pm_qos_update_request(), the internal routine apply_constraint() used by them and their existing callers to cover flags requests as well as latency requests. In particular, dev_pm_qos_add_request() gets a new argument called "type" for specifying the type of a request to be added. Finally, introduce two routines, __dev_pm_qos_flags() and dev_pm_qos_flags(), allowing their callers to check which PM QoS flags have been requested for the given device (the caller is supposed to pass the mask of flags to check as the routine's second argument and examine its return value for the result). Signed-off-by: Rafael J. Wysocki Reviewed-by: Jean Pihet Reviewed-by: mark gross --- Documentation/power/pm_qos_interface.txt | 2 +- drivers/base/power/qos.c | 124 ++++++++++++++++++++++++------- drivers/mtd/nand/sh_flctl.c | 4 +- include/linux/pm_qos.h | 26 ++++++- 4 files changed, 127 insertions(+), 29 deletions(-) diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt index 17e130a8034..79a2a58425e 100644 --- a/Documentation/power/pm_qos_interface.txt +++ b/Documentation/power/pm_qos_interface.txt @@ -99,7 +99,7 @@ reading the aggregated value does not require any locking mechanism. From kernel mode the use of this interface is the following: -int dev_pm_qos_add_request(device, handle, value): +int dev_pm_qos_add_request(device, handle, type, value): Will insert an element into the list for that identified device with the target value. Upon change to this list the new target is recomputed and any registered notifiers are called only if the target value is now different. diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 96d27b821bb..3c66f75d14b 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -47,6 +47,50 @@ static DEFINE_MUTEX(dev_pm_qos_mtx); static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers); +/** + * __dev_pm_qos_flags - Check PM QoS flags for a given device. + * @dev: Device to check the PM QoS flags for. + * @mask: Flags to check against. + * + * This routine must be called with dev->power.lock held. + */ +enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask) +{ + struct dev_pm_qos *qos = dev->power.qos; + struct pm_qos_flags *pqf; + s32 val; + + if (!qos) + return PM_QOS_FLAGS_UNDEFINED; + + pqf = &qos->flags; + if (list_empty(&pqf->list)) + return PM_QOS_FLAGS_UNDEFINED; + + val = pqf->effective_flags & mask; + if (val) + return (val == mask) ? PM_QOS_FLAGS_ALL : PM_QOS_FLAGS_SOME; + + return PM_QOS_FLAGS_NONE; +} + +/** + * dev_pm_qos_flags - Check PM QoS flags for a given device (locked). + * @dev: Device to check the PM QoS flags for. + * @mask: Flags to check against. + */ +enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, s32 mask) +{ + unsigned long irqflags; + enum pm_qos_flags_status ret; + + spin_lock_irqsave(&dev->power.lock, irqflags); + ret = __dev_pm_qos_flags(dev, mask); + spin_unlock_irqrestore(&dev->power.lock, irqflags); + + return ret; +} + /** * __dev_pm_qos_read_value - Get PM QoS constraint for a given device. * @dev: Device to get the PM QoS constraint value for. @@ -74,30 +118,39 @@ s32 dev_pm_qos_read_value(struct device *dev) return ret; } -/* - * apply_constraint - * @req: constraint request to apply - * @action: action to perform add/update/remove, of type enum pm_qos_req_action - * @value: defines the qos request +/** + * apply_constraint - Add/modify/remove device PM QoS request. + * @req: Constraint request to apply + * @action: Action to perform (add/update/remove). + * @value: Value to assign to the QoS request. * * Internal function to update the constraints list using the PM QoS core * code and if needed call the per-device and the global notification * callbacks */ static int apply_constraint(struct dev_pm_qos_request *req, - enum pm_qos_req_action action, int value) + enum pm_qos_req_action action, s32 value) { - int ret, curr_value; - - ret = pm_qos_update_target(&req->dev->power.qos->latency, - &req->data.pnode, action, value); + struct dev_pm_qos *qos = req->dev->power.qos; + int ret; - if (ret) { - /* Call the global callbacks if needed */ - curr_value = pm_qos_read_value(&req->dev->power.qos->latency); - blocking_notifier_call_chain(&dev_pm_notifiers, - (unsigned long)curr_value, - req); + switch(req->type) { + case DEV_PM_QOS_LATENCY: + ret = pm_qos_update_target(&qos->latency, &req->data.pnode, + action, value); + if (ret) { + value = pm_qos_read_value(&qos->latency); + blocking_notifier_call_chain(&dev_pm_notifiers, + (unsigned long)value, + req); + } + break; + case DEV_PM_QOS_FLAGS: + ret = pm_qos_update_flags(&qos->flags, &req->data.flr, + action, value); + break; + default: + ret = -EINVAL; } return ret; @@ -134,6 +187,8 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) c->type = PM_QOS_MIN; c->notifiers = n; + INIT_LIST_HEAD(&qos->flags.list); + spin_lock_irq(&dev->power.lock); dev->power.qos = qos; spin_unlock_irq(&dev->power.lock); @@ -207,6 +262,7 @@ void dev_pm_qos_constraints_destroy(struct device *dev) * dev_pm_qos_add_request - inserts new qos request into the list * @dev: target device for the constraint * @req: pointer to a preallocated handle + * @type: type of the request * @value: defines the qos request * * This function inserts a new entry in the device constraints list of @@ -222,7 +278,7 @@ void dev_pm_qos_constraints_destroy(struct device *dev) * from the system. */ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, - s32 value) + enum dev_pm_qos_req_type type, s32 value) { int ret = 0; @@ -253,8 +309,10 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, } } - if (!ret) + if (!ret) { + req->type = type; ret = apply_constraint(req, PM_QOS_ADD_REQ, value); + } out: mutex_unlock(&dev_pm_qos_mtx); @@ -281,6 +339,7 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_add_request); int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value) { + s32 curr_value; int ret = 0; if (!req) /*guard against callers passing in null */ @@ -292,15 +351,27 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, mutex_lock(&dev_pm_qos_mtx); - if (req->dev->power.qos) { - if (new_value != req->data.pnode.prio) - ret = apply_constraint(req, PM_QOS_UPDATE_REQ, - new_value); - } else { - /* Return if the device has been removed */ + if (!req->dev->power.qos) { ret = -ENODEV; + goto out; } + switch(req->type) { + case DEV_PM_QOS_LATENCY: + curr_value = req->data.pnode.prio; + break; + case DEV_PM_QOS_FLAGS: + curr_value = req->data.flr.flags; + break; + default: + ret = -EINVAL; + goto out; + } + + if (curr_value != new_value) + ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value); + + out: mutex_unlock(&dev_pm_qos_mtx); return ret; } @@ -451,7 +522,8 @@ int dev_pm_qos_add_ancestor_request(struct device *dev, ancestor = ancestor->parent; if (ancestor) - error = dev_pm_qos_add_request(ancestor, req, value); + error = dev_pm_qos_add_request(ancestor, req, + DEV_PM_QOS_LATENCY, value); if (error) req->dev = NULL; @@ -487,7 +559,7 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) if (!req) return -ENOMEM; - ret = dev_pm_qos_add_request(dev, req, value); + ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_LATENCY, value); if (ret < 0) return ret; diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index 4fbfe96e37a..f48ac5d80bb 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c @@ -727,7 +727,9 @@ static void flctl_select_chip(struct mtd_info *mtd, int chipnr) if (!flctl->qos_request) { ret = dev_pm_qos_add_request(&flctl->pdev->dev, - &flctl->pm_qos, 100); + &flctl->pm_qos, + DEV_PM_QOS_LATENCY, + 100); if (ret < 0) dev_err(&flctl->pdev->dev, "PM QoS request failed: %d\n", ret); diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 3b9d14964d2..3af7d8573c2 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -20,6 +20,13 @@ enum { PM_QOS_NUM_CLASSES, }; +enum pm_qos_flags_status { + PM_QOS_FLAGS_UNDEFINED = -1, + PM_QOS_FLAGS_NONE, + PM_QOS_FLAGS_SOME, + PM_QOS_FLAGS_ALL, +}; + #define PM_QOS_DEFAULT_VALUE -1 #define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) @@ -38,9 +45,16 @@ struct pm_qos_flags_request { s32 flags; /* Do not change to 64 bit */ }; +enum dev_pm_qos_req_type { + DEV_PM_QOS_LATENCY = 1, + DEV_PM_QOS_FLAGS, +}; + struct dev_pm_qos_request { + enum dev_pm_qos_req_type type; union { struct plist_node pnode; + struct pm_qos_flags_request flr; } data; struct device *dev; }; @@ -71,6 +85,7 @@ struct pm_qos_flags { struct dev_pm_qos { struct pm_qos_constraints latency; + struct pm_qos_flags flags; }; /* Action requested to pm_qos_update_target */ @@ -105,10 +120,12 @@ int pm_qos_request_active(struct pm_qos_request *req); s32 pm_qos_read_value(struct pm_qos_constraints *c); #ifdef CONFIG_PM +enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask); +enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, s32 mask); s32 __dev_pm_qos_read_value(struct device *dev); s32 dev_pm_qos_read_value(struct device *dev); int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, - s32 value); + enum dev_pm_qos_req_type type, s32 value); int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value); int dev_pm_qos_remove_request(struct dev_pm_qos_request *req); int dev_pm_qos_add_notifier(struct device *dev, @@ -122,12 +139,19 @@ void dev_pm_qos_constraints_destroy(struct device *dev); int dev_pm_qos_add_ancestor_request(struct device *dev, struct dev_pm_qos_request *req, s32 value); #else +static inline enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, + s32 mask) + { return PM_QOS_FLAGS_UNDEFINED; } +static inline enum pm_qos_flags_status dev_pm_qos_flags(struct device *dev, + s32 mask) + { return PM_QOS_FLAGS_UNDEFINED; } static inline s32 __dev_pm_qos_read_value(struct device *dev) { return 0; } static inline s32 dev_pm_qos_read_value(struct device *dev) { return 0; } static inline int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, + enum dev_pm_qos_req_type type, s32 value) { return 0; } static inline int dev_pm_qos_update_request(struct dev_pm_qos_request *req, -- cgit v1.2.3 From daee779718a319ff9f83e1ba3339334ac650bb22 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 22 Sep 2012 19:52:11 +0200 Subject: console: implement lockdep support for console_lock Dave Airlie recently discovered a locking bug in the fbcon layer, where a timer_del_sync (for the blinking cursor) deadlocks with the timer itself, since both (want to) hold the console_lock: https://lkml.org/lkml/2012/8/21/36 Unfortunately the console_lock isn't a plain mutex and hence has no lockdep support. Which resulted in a few days wasted of tracking down this bug (complicated by the fact that printk doesn't show anything when the console is locked) instead of noticing the bug much earlier with the lockdep splat. Hence I've figured I need to fix that for the next deadlock involving console_lock - and with kms/drm growing ever more complex locking that'll eventually happen. Now the console_lock has rather funky semantics, so after a quick irc discussion with Thomas Gleixner and Dave Airlie I've quickly ditched the original idead of switching to a real mutex (since it won't work) and instead opted to annotate the console_lock with lockdep information manually. There are a few special cases: - The console_lock state is protected by the console_sem, and usually grabbed/dropped at _lock/_unlock time. But the suspend/resume code drops the semaphore without dropping the console_lock (see suspend_console/resume_console). But since the same thread that did the suspend will do the resume, we don't need to fix up anything. - In the printk code there's a special trylock, only used to kick off the logbuffer printk'ing in console_unlock. But all that happens while lockdep is disable (since printk does a few other evil tricks). So no issue there, either. - The console_lock can also be acquired form irq context (but only with a trylock). lockdep already handles that. This all leaves us with annotating the normal console_lock, _unlock and _trylock functions. And yes, it works - simply unloading a drm kms driver resulted in lockdep complaining about the deadlock in fbcon_deinit: ====================================================== [ INFO: possible circular locking dependency detected ] 3.6.0-rc2+ #552 Not tainted ------------------------------------------------------- kms-reload/3577 is trying to acquire lock: ((&info->queue)){+.+...}, at: [] wait_on_work+0x0/0xa7 but task is already holding lock: (console_lock){+.+.+.}, at: [] bind_con_driver+0x38/0x263 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (console_lock){+.+.+.}: [] lock_acquire+0x95/0x105 [] console_lock+0x59/0x5b [] fb_flashcursor+0x2e/0x12c [] process_one_work+0x1d9/0x3b4 [] worker_thread+0x1a7/0x24b [] kthread+0x7f/0x87 [] kernel_thread_helper+0x4/0x10 -> #0 ((&info->queue)){+.+...}: [] __lock_acquire+0x999/0xcf6 [] lock_acquire+0x95/0x105 [] wait_on_work+0x3b/0xa7 [] __cancel_work_timer+0xbf/0x102 [] cancel_work_sync+0xb/0xd [] fbcon_deinit+0x11c/0x1dc [] bind_con_driver+0x145/0x263 [] unbind_con_driver+0x14f/0x195 [] store_bind+0x1ad/0x1c1 [] dev_attr_store+0x13/0x1f [] sysfs_write_file+0xe9/0x121 [] vfs_write+0x9b/0xfd [] sys_write+0x3e/0x6b [] system_call_fastpath+0x16/0x1b other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(console_lock); lock((&info->queue)); lock(console_lock); lock((&info->queue)); *** DEADLOCK *** v2: Mark the lockdep_map static, noticed by Jani Nikula. Cc: Dave Airlie Cc: Thomas Gleixner Cc: Alan Cox Cc: Peter Zijlstra Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- kernel/printk.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/kernel/printk.c b/kernel/printk.c index 2d607f4d179..ee79f14db35 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -87,6 +87,12 @@ static DEFINE_SEMAPHORE(console_sem); struct console *console_drivers; EXPORT_SYMBOL_GPL(console_drivers); +#ifdef CONFIG_LOCKDEP +static struct lockdep_map console_lock_dep_map = { + .name = "console_lock" +}; +#endif + /* * This is used for debugging the mess that is the VT code by * keeping track if we have the console semaphore held. It's @@ -1914,6 +1920,7 @@ void console_lock(void) return; console_locked = 1; console_may_schedule = 1; + mutex_acquire(&console_lock_dep_map, 0, 0, _RET_IP_); } EXPORT_SYMBOL(console_lock); @@ -1935,6 +1942,7 @@ int console_trylock(void) } console_locked = 1; console_may_schedule = 0; + mutex_acquire(&console_lock_dep_map, 0, 1, _RET_IP_); return 1; } EXPORT_SYMBOL(console_trylock); @@ -2095,6 +2103,7 @@ skip: local_irq_restore(flags); } console_locked = 0; + mutex_release(&console_lock_dep_map, 1, _RET_IP_); /* Release the exclusive_console once it is used */ if (unlikely(exclusive_console)) -- cgit v1.2.3 From cee4ad1ed90a0959fc29f9d30a2526e5e9522cfa Mon Sep 17 00:00:00 2001 From: Ivo Sieben Date: Thu, 27 Sep 2012 14:02:05 +0200 Subject: tty: prevent unnecessary work queue lock checking on flip buffer copy When low_latency flag is set the TTY receive flip buffer is copied to the line discipline directly instead of using a work queue in the background. Therefor only in case a workqueue is actually used for copying data to the line discipline we'll have to flush the workqueue. This prevents unnecessary spin lock/unlock on the workqueue spin lock that can cause additional scheduling overhead on a PREEMPT_RT system. On a 200 MHz AT91SAM9261 processor setup this fixes about 100us of scheduling overhead on the TTY read call. Signed-off-by: Ivo Sieben Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 91e326ffe7d..8b00f6a34a7 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -342,6 +342,8 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); * Takes any pending buffers and transfers their ownership to the * ldisc side of the queue. It then schedules those characters for * processing by the line discipline. + * Note that this function can only be used when the low_latency flag + * is unset. Otherwise the workqueue won't be flushed. * * Locking: Takes tty->buf.lock */ @@ -514,7 +516,8 @@ static void flush_to_ldisc(struct work_struct *work) */ void tty_flush_to_ldisc(struct tty_struct *tty) { - flush_work(&tty->buf.work); + if (!tty->low_latency) + flush_work(&tty->buf.work); } /** -- cgit v1.2.3 From 8fcbaa2b7f5b70dba9ed1c7f91d0a270ce752e2c Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:27 +0200 Subject: TTY: devpts, don't care about TTY in devpts_get_tty The goal is to stop setting and using tty->driver_data in devpts code. It should be used solely by the driver's code, pty in this case. First, here we remove TTY from devpts_get_tty and rename it to devpts_get_priv. Note we do not remove type safety, we just shift the [implicit] (void *) cast one layer up. index was unused in devpts_get_tty, so remove that from the prototype too. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 2 +- fs/devpts/inode.c | 9 ++++----- include/linux/devpts_fs.h | 7 +++---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index a82b39939a9..65f767154d1 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -547,7 +547,7 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, struct tty_struct *tty; mutex_lock(&devpts_mutex); - tty = devpts_get_tty(pts_inode, idx); + tty = devpts_get_priv(pts_inode); mutex_unlock(&devpts_mutex); /* Master must be open before slave */ if (!tty) diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 14afbabe654..47965807884 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -593,10 +593,10 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) return ret; } -struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number) +void *devpts_get_priv(struct inode *pts_inode) { struct dentry *dentry; - struct tty_struct *tty; + void *priv = NULL; BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); @@ -605,13 +605,12 @@ struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number) if (!dentry) return NULL; - tty = NULL; if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) - tty = (struct tty_struct *)pts_inode->i_private; + priv = pts_inode->i_private; dput(dentry); - return tty; + return priv; } void devpts_pty_kill(struct tty_struct *tty) diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h index 5ce0e5fd712..de635a5505e 100644 --- a/include/linux/devpts_fs.h +++ b/include/linux/devpts_fs.h @@ -21,8 +21,8 @@ int devpts_new_index(struct inode *ptmx_inode); void devpts_kill_index(struct inode *ptmx_inode, int idx); /* mknod in devpts */ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty); -/* get tty structure */ -struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number); +/* get private structure */ +void *devpts_get_priv(struct inode *pts_inode); /* unlink */ void devpts_pty_kill(struct tty_struct *tty); @@ -36,8 +36,7 @@ static inline int devpts_pty_new(struct inode *ptmx_inode, { return -EINVAL; } -static inline struct tty_struct *devpts_get_tty(struct inode *pts_inode, - int number) +static inline void *devpts_get_priv(struct inode *pts_inode) { return NULL; } -- cgit v1.2.3 From 162b97cfa21f816f39ede1944f2a4220e3cf8969 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:28 +0200 Subject: TTY: devpts, return created inode from devpts_pty_new The goal is to stop setting and using tty->driver_data in devpts code. It should be used solely by the driver's code, pty in this case. For the cleanup of layering, we will need the inode created in devpts_pty_new to be stored into slave's driver_data. So we convert devpts_pty_new to return the inode or an ERR_PTR-encoded error in case of failure. The move of 'inode = new_inode(sb);' from declarators to the code is only cosmetical, but it makes the code easier to read. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 7 +++++-- fs/devpts/inode.c | 12 ++++++------ include/linux/devpts_fs.h | 8 ++++---- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 65f767154d1..9985b451e93 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -614,6 +614,7 @@ static const struct tty_operations pty_unix98_ops = { static int ptmx_open(struct inode *inode, struct file *filp) { struct tty_struct *tty; + struct inode *slave_inode; int retval; int index; @@ -650,9 +651,11 @@ static int ptmx_open(struct inode *inode, struct file *filp) tty_add_file(tty, filp); - retval = devpts_pty_new(inode, tty->link); - if (retval) + slave_inode = devpts_pty_new(inode, tty->link); + if (IS_ERR(slave_inode)) { + retval = PTR_ERR(slave_inode); goto err_release; + } retval = ptm_driver->ops->open(tty, filp); if (retval) diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 47965807884..ec3bab716c0 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -545,7 +545,7 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx) mutex_unlock(&allocated_ptys_lock); } -int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) +struct inode *devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) { /* tty layer puts index from devpts_new_index() in here */ int number = tty->index; @@ -553,19 +553,19 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) dev_t device = MKDEV(driver->major, driver->minor_start+number); struct dentry *dentry; struct super_block *sb = pts_sb_from_inode(ptmx_inode); - struct inode *inode = new_inode(sb); + struct inode *inode; struct dentry *root = sb->s_root; struct pts_fs_info *fsi = DEVPTS_SB(sb); struct pts_mount_opts *opts = &fsi->mount_opts; - int ret = 0; char s[12]; /* We're supposed to be given the slave end of a pty */ BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY); BUG_ON(driver->subtype != PTY_TYPE_SLAVE); + inode = new_inode(sb); if (!inode) - return -ENOMEM; + return ERR_PTR(-ENOMEM); inode->i_ino = number + 3; inode->i_uid = opts->setuid ? opts->uid : current_fsuid(); @@ -585,12 +585,12 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) fsnotify_create(root->d_inode, dentry); } else { iput(inode); - ret = -ENOMEM; + inode = ERR_PTR(-ENOMEM); } mutex_unlock(&root->d_inode->i_mutex); - return ret; + return inode; } void *devpts_get_priv(struct inode *pts_inode) diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h index de635a5505e..4ca846f16fe 100644 --- a/include/linux/devpts_fs.h +++ b/include/linux/devpts_fs.h @@ -20,7 +20,7 @@ int devpts_new_index(struct inode *ptmx_inode); void devpts_kill_index(struct inode *ptmx_inode, int idx); /* mknod in devpts */ -int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty); +struct inode *devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty); /* get private structure */ void *devpts_get_priv(struct inode *pts_inode); /* unlink */ @@ -31,10 +31,10 @@ void devpts_pty_kill(struct tty_struct *tty); /* Dummy stubs in the no-pty case */ static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; } static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { } -static inline int devpts_pty_new(struct inode *ptmx_inode, - struct tty_struct *tty) +static inline struct inode *devpts_pty_new(struct inode *ptmx_inode, + struct tty_struct *tty) { - return -EINVAL; + return ERR_PTR(-EINVAL); } static inline void *devpts_get_priv(struct inode *pts_inode) { -- cgit v1.2.3 From f11afb61247016162aa92225a337c1575556c9d9 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:29 +0200 Subject: TTY: devpts, do not set driver_data The goal is to stop setting and using tty->driver_data in devpts code. It should be used solely by the driver's code, pty in this case. Now driver_data are managed only in the pty driver. devpts_pty_new is switched to accept what we used to dig out of tty_struct, i.e. device node number and index. This also removes a note about driver_data being set outside of the driver. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 10 +++++----- fs/devpts/inode.c | 21 ++++++--------------- include/linux/devpts_fs.h | 9 +++++---- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 9985b451e93..559e5b27941 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -4,9 +4,6 @@ * Added support for a Unix98-style ptmx device. * -- C. Scott Ananian , 14-Jan-1998 * - * When reading this code see also fs/devpts. In particular note that the - * driver_data field is used by the devpts side as a binding to the devpts - * inode. */ #include @@ -59,7 +56,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) #ifdef CONFIG_UNIX98_PTYS if (tty->driver == ptm_driver) { mutex_lock(&devpts_mutex); - devpts_pty_kill(tty->link); + devpts_pty_kill(tty->link->driver_data); mutex_unlock(&devpts_mutex); } #endif @@ -651,7 +648,9 @@ static int ptmx_open(struct inode *inode, struct file *filp) tty_add_file(tty, filp); - slave_inode = devpts_pty_new(inode, tty->link); + slave_inode = devpts_pty_new(inode, + MKDEV(UNIX98_PTY_SLAVE_MAJOR, index), index, + tty->link); if (IS_ERR(slave_inode)) { retval = PTR_ERR(slave_inode); goto err_release; @@ -662,6 +661,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) goto err_release; tty_unlock(tty); + tty->link->driver_data = slave_inode; return 0; err_release: tty_unlock(tty); diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index ec3bab716c0..7a20d673bb8 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -545,12 +545,9 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx) mutex_unlock(&allocated_ptys_lock); } -struct inode *devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) +struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index, + void *priv) { - /* tty layer puts index from devpts_new_index() in here */ - int number = tty->index; - struct tty_driver *driver = tty->driver; - dev_t device = MKDEV(driver->major, driver->minor_start+number); struct dentry *dentry; struct super_block *sb = pts_sb_from_inode(ptmx_inode); struct inode *inode; @@ -559,23 +556,18 @@ struct inode *devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) struct pts_mount_opts *opts = &fsi->mount_opts; char s[12]; - /* We're supposed to be given the slave end of a pty */ - BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY); - BUG_ON(driver->subtype != PTY_TYPE_SLAVE); - inode = new_inode(sb); if (!inode) return ERR_PTR(-ENOMEM); - inode->i_ino = number + 3; + inode->i_ino = index + 3; inode->i_uid = opts->setuid ? opts->uid : current_fsuid(); inode->i_gid = opts->setgid ? opts->gid : current_fsgid(); inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; init_special_inode(inode, S_IFCHR|opts->mode, device); - inode->i_private = tty; - tty->driver_data = inode; + inode->i_private = priv; - sprintf(s, "%d", number); + sprintf(s, "%d", index); mutex_lock(&root->d_inode->i_mutex); @@ -613,9 +605,8 @@ void *devpts_get_priv(struct inode *pts_inode) return priv; } -void devpts_pty_kill(struct tty_struct *tty) +void devpts_pty_kill(struct inode *inode) { - struct inode *inode = tty->driver_data; struct super_block *sb = pts_sb_from_inode(inode); struct dentry *root = sb->s_root; struct dentry *dentry; diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h index 4ca846f16fe..251a2090a55 100644 --- a/include/linux/devpts_fs.h +++ b/include/linux/devpts_fs.h @@ -20,11 +20,12 @@ int devpts_new_index(struct inode *ptmx_inode); void devpts_kill_index(struct inode *ptmx_inode, int idx); /* mknod in devpts */ -struct inode *devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty); +struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index, + void *priv); /* get private structure */ void *devpts_get_priv(struct inode *pts_inode); /* unlink */ -void devpts_pty_kill(struct tty_struct *tty); +void devpts_pty_kill(struct inode *inode); #else @@ -32,7 +33,7 @@ void devpts_pty_kill(struct tty_struct *tty); static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; } static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { } static inline struct inode *devpts_pty_new(struct inode *ptmx_inode, - struct tty_struct *tty) + dev_t device, int index, void *priv) { return ERR_PTR(-EINVAL); } @@ -40,7 +41,7 @@ static inline void *devpts_get_priv(struct inode *pts_inode) { return NULL; } -static inline void devpts_pty_kill(struct tty_struct *tty) { } +static inline void devpts_pty_kill(struct inode *inode) { } #endif -- cgit v1.2.3 From 1dcb8e6d1c23f2e021639199fdf64d5b42689207 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:30 +0200 Subject: TTY: devpts, document devpts inode operations Add kernel-doc texts for some devpts functions, i.e. document them. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- fs/devpts/inode.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 7a20d673bb8..472e6befc54 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -545,6 +545,15 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx) mutex_unlock(&allocated_ptys_lock); } +/** + * devpts_pty_new -- create a new inode in /dev/pts/ + * @ptmx_inode: inode of the master + * @device: major+minor of the node to be created + * @index: used as a name of the node + * @priv: what's given back by devpts_get_priv + * + * The created inode is returned. Remove it from /dev/pts/ by devpts_pty_kill. + */ struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index, void *priv) { @@ -585,6 +594,12 @@ struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index, return inode; } +/** + * devpts_get_priv -- get private data for a slave + * @pts_inode: inode of the slave + * + * Returns whatever was passed as priv in devpts_pty_new for a given inode. + */ void *devpts_get_priv(struct inode *pts_inode) { struct dentry *dentry; @@ -605,6 +620,12 @@ void *devpts_get_priv(struct inode *pts_inode) return priv; } +/** + * devpts_pty_kill -- remove inode form /dev/pts/ + * @inode: inode of the slave to be removed + * + * This is an inverse operation of devpts_pty_new. + */ void devpts_pty_kill(struct inode *inode) { struct super_block *sb = pts_sb_from_inode(inode); -- cgit v1.2.3 From fa2ecfc5a68d85624bbd84f7d010860776b7e602 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:31 +0200 Subject: TTY: move devpts kill to pty Now that we have control over tty->driver_data in pty, we can just kill the /dev/pts/ in pty code too. Namely, in ->shutdown hook of tty. For pty, this is called only once, for whichever end is closed last. But we don't care, both driver_data are the inode as it used to be till now. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 9 +++++++++ drivers/tty/tty_io.c | 5 ----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 559e5b27941..2728afe52ee 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -363,6 +363,12 @@ err: return retval; } +/* this is called once with whichever end is closed last */ +static void pty_unix98_shutdown(struct tty_struct *tty) +{ + devpts_kill_index(tty->driver_data, tty->index); +} + static void pty_cleanup(struct tty_struct *tty) { kfree(tty->port); @@ -578,6 +584,7 @@ static const struct tty_operations ptm_unix98_ops = { .set_termios = pty_set_termios, .ioctl = pty_unix98_ioctl, .resize = pty_resize, + .shutdown = pty_unix98_shutdown, .cleanup = pty_cleanup }; @@ -593,6 +600,7 @@ static const struct tty_operations pty_unix98_ops = { .chars_in_buffer = pty_chars_in_buffer, .unthrottle = pty_unthrottle, .set_termios = pty_set_termios, + .shutdown = pty_unix98_shutdown, .cleanup = pty_cleanup, }; @@ -661,6 +669,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) goto err_release; tty_unlock(tty); + tty->driver_data = inode; tty->link->driver_data = slave_inode; return 0; err_release: diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 2ea176b2280..e835a5b8d08 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1625,7 +1625,6 @@ int tty_release(struct inode *inode, struct file *filp) struct tty_struct *tty = file_tty(filp); struct tty_struct *o_tty; int pty_master, tty_closing, o_tty_closing, do_sleep; - int devpts; int idx; char buf[64]; @@ -1640,7 +1639,6 @@ int tty_release(struct inode *inode, struct file *filp) idx = tty->index; pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER); - devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; /* Review: parallel close */ o_tty = tty->link; @@ -1799,9 +1797,6 @@ int tty_release(struct inode *inode, struct file *filp) release_tty(tty, idx); mutex_unlock(&tty_mutex); - /* Make this pty number available for reallocation */ - if (devpts) - devpts_kill_index(inode, idx); return 0; } -- cgit v1.2.3 From 7ee00fdb16418dd5078ec73e4a631c278a366501 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:32 +0200 Subject: TTY: vt, fix paste_selection ldisc handling There used to be a single tty_ldisc_ref_wait. But then, when a big-tty-mutex (BTM) was introduced, it has to be tty_ldisc_ref + tty_unlock + tty_ldisc_ref_wait + tty_lock. Later, BTM was removed from that path and tty_ldisc_ref + tty_ldisc_ref_wait remained there. But it makes no sense now. So leave there only tty_ldisc_ref_wait. And when we have a reference to an ldisc, actually use it in the loop. Otherwise it may be racy. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/selection.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 8e9b4be97a2..60b7b692605 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -341,15 +341,11 @@ int paste_selection(struct tty_struct *tty) struct tty_ldisc *ld; DECLARE_WAITQUEUE(wait, current); - console_lock(); poke_blanked_console(); console_unlock(); - /* FIXME: wtf is this supposed to achieve ? */ - ld = tty_ldisc_ref(tty); - if (!ld) - ld = tty_ldisc_ref_wait(tty); + ld = tty_ldisc_ref_wait(tty); /* FIXME: this is completely unsafe */ add_wait_queue(&vc->paste_wait, &wait); @@ -361,8 +357,7 @@ int paste_selection(struct tty_struct *tty) } count = sel_buffer_lth - pasted; count = min(count, tty->receive_room); - tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, - NULL, count); + ld->ops->receive_buf(tty, sel_buffer + pasted, NULL, count); pasted += count; } remove_wait_queue(&vc->paste_wait, &wait); -- cgit v1.2.3 From 31e121284f90bf559618330e230b286f969b6b7f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:33 +0200 Subject: TTY: ldisc, wait for idle ldisc in release We reintroduced tty_ldisc_wait_idle in 100eeae2c5c (TTY: restore tty_ldisc_wait_idle) and used in set_ldisc. Then we added it also to the hangup path in 92f6fa09bd453 (TTY: ldisc, do not close until there are readers). And we noted that there is one more path: ~ Before 65b770468e98 tty_ldisc_wait_idle was called also from ~ tty_ldisc_release. It is called from tty_release, so I don't think ~ we need to restore that one. Well, I was wrong. There might still be holders of an ldisc reference. Not from userspace, but drivers. If they take a reference and a user closes the device immediately after that, we have a problem. ldisc is halted and closed by TTY, but the driver still may call some ldisc's operation and cause a crash. So restore the tty_ldisc_wait_idle call also to the third location where it was before 65b770468e98 (tty-ldisc: turn ldisc user count into a proper refcount). Now we should be safe with respect to the ldisc reference counting as all* tty_ldisc_close paths are safely called with reference count of one. * Not the one in tty_ldisc_setup's fail path. But that is called before the first open finishes. So userspace does not see it yet. Even thought the driver is given the TTY already via ->install, it should not take a reference to the ldisc yet. If some driver is to do this, we should put one tty_ldisc_wait_idle also in the setup. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 0f2a2c5e704..47e3968df10 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -897,6 +897,11 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) static void tty_ldisc_kill(struct tty_struct *tty) { + /* There cannot be users from userspace now. But there still might be + * drivers holding a reference via tty_ldisc_ref. Do not steal them the + * ldisc until they are done. */ + tty_ldisc_wait_idle(tty, MAX_SCHEDULE_TIMEOUT); + mutex_lock(&tty->ldisc_mutex); /* * Now kill off the ldisc -- cgit v1.2.3 From f327b340e35b210c936cd109544e672aa7a0e49d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:34 +0200 Subject: TTY: hci_ldisc, remove invalid check in open hci_ldisc's open checks if tty_struct->disc_data is set. And if so it returns with an error. But nothing ensures disc_data to be NULL. And since ld->ops->open shall be called only once, we do not need the check at all. So remove it. Note that this is not an issue now, but n_tty will start using the disc_data pointer and this invalid 'if' would trigger then rendering TTYs over BT unusable. Signed-off-by: Jiri Slaby Acked-by: Marcel Holtmann Cc: Gustavo Padovan Cc: Johan Hedberg Cc: linux-bluetooth@vger.kernel.org Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/hci_ldisc.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index c8abce3d2d9..ed0fade46ae 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -270,15 +270,10 @@ static int hci_uart_send_frame(struct sk_buff *skb) */ static int hci_uart_tty_open(struct tty_struct *tty) { - struct hci_uart *hu = (void *) tty->disc_data; + struct hci_uart *hu; BT_DBG("tty %p", tty); - /* FIXME: This btw is bogus, nothing requires the old ldisc to clear - the pointer */ - if (hu) - return -EEXIST; - /* Error if the tty has no write op instead of leaving an exploitable hole */ if (tty->ops->write == NULL) -- cgit v1.2.3 From b91939f528fa80e95a7e9592425dd1026d159b2a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:35 +0200 Subject: TTY: n_tty, simplify read_buf+echo_buf allocation ldisc->open and close are called only once and cannot cross. So the tests in open and close are superfluous. Remove them. (But leave sets to NULL to ensure there is not a bug somewhere.) And when the tests are gone, handle properly failures in open. We leaked read_buf if allocation of echo_buf failed before. Now this is not the case anymore. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 8c0b7b42319..f27289d910b 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1561,14 +1561,10 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) static void n_tty_close(struct tty_struct *tty) { n_tty_flush_buffer(tty); - if (tty->read_buf) { - kfree(tty->read_buf); - tty->read_buf = NULL; - } - if (tty->echo_buf) { - kfree(tty->echo_buf); - tty->echo_buf = NULL; - } + kfree(tty->read_buf); + kfree(tty->echo_buf); + tty->read_buf = NULL; + tty->echo_buf = NULL; } /** @@ -1587,17 +1583,11 @@ static int n_tty_open(struct tty_struct *tty) return -EINVAL; /* These are ugly. Currently a malloc failure here can panic */ - if (!tty->read_buf) { - tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); - if (!tty->read_buf) - return -ENOMEM; - } - if (!tty->echo_buf) { - tty->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); + tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); + tty->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); + if (!tty->read_buf || !tty->echo_buf) + goto err_free_bufs; - if (!tty->echo_buf) - return -ENOMEM; - } reset_buffer_flags(tty); tty_unthrottle(tty); tty->column = 0; @@ -1605,6 +1595,11 @@ static int n_tty_open(struct tty_struct *tty) tty->minimum_to_wake = 1; tty->closing = 0; return 0; +err_free_bufs: + kfree(tty->read_buf); + kfree(tty->echo_buf); + + return -ENOMEM; } static inline int input_available_p(struct tty_struct *tty, int amt) -- cgit v1.2.3 From 3383427a7b325e50af03d6f42b9587ca66d941a6 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:36 +0200 Subject: TTY: n_tty, remove bogus checks * BUG_ON(!tty) in n_tty_set_termios -- it cannot be called with tty == NULL. It is called from two call sites. First, from n_tty_open where we have a valid tty. Second, as ld->ops->set_termios from tty_set_termios. But there we have a valid tty too. * if (!tty) in n_tty_open -- why would the TTY layer call ldisc's open with an invalid TTY? No it indeed does not. All call sites have a tty and dereference that. * BUG_ON(!tty->read_buf) in n_tty_read -- this used to be a valid check. The ldisc handling was broken some time ago when I added the check to ensure everything is OK. It still can catch the case, but no later than we move the buffer to ldisc data. Then there will be no read_buf in tty_struct, i.e. nothing to check for. * if (!tty->read_buf) in n_tty_receive_buf -- this should never happen. All callers of ldisc->ops->receive_ops should hold a reference to an ldisc and close (which frees read_buf) cannot be called until the reference is dropped. * if (WARN_ON(!tty->read_buf)) in n_tty_read -- the same as in the previous case. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index f27289d910b..ceae0744cbb 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1375,9 +1375,6 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, char buf[64]; unsigned long cpuflags; - if (!tty->read_buf) - return; - if (tty->real_raw) { spin_lock_irqsave(&tty->read_lock, cpuflags); i = min(N_TTY_BUF_SIZE - tty->read_cnt, @@ -1471,7 +1468,6 @@ int is_ignored(int sig) static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) { int canon_change = 1; - BUG_ON(!tty); if (old) canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON; @@ -1579,9 +1575,6 @@ static void n_tty_close(struct tty_struct *tty) static int n_tty_open(struct tty_struct *tty) { - if (!tty) - return -EINVAL; - /* These are ugly. Currently a malloc failure here can panic */ tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); tty->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); @@ -1736,10 +1729,6 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, int packet; do_it_again: - - if (WARN_ON(!tty->read_buf)) - return -EAGAIN; - c = job_control(tty, file); if (c < 0) return c; @@ -1825,7 +1814,6 @@ do_it_again: /* FIXME: does n_tty_set_room need locking ? */ n_tty_set_room(tty); timeout = schedule_timeout(timeout); - BUG_ON(!tty->read_buf); continue; } __set_current_state(TASK_RUNNING); -- cgit v1.2.3 From 6c633f27ccf783e9a782b84e34aeaeb7949a3359 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:37 +0200 Subject: TTY: audit, stop accessing tty->icount This is a private member of n_tty. Stop accessing it. Instead, take is as an argument. This is needed to allow clean switch of the private members to a separate private structure of n_tty. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 5 +++-- drivers/tty/tty_audit.c | 15 ++++++++------- include/linux/tty.h | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index ceae0744cbb..3ebab0cfceb 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -76,7 +76,7 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, unsigned char __user *ptr) { - tty_audit_add_data(tty, &x, 1); + tty_audit_add_data(tty, &x, 1, tty->icanon); return put_user(x, ptr); } @@ -1644,7 +1644,8 @@ static int copy_from_read_buf(struct tty_struct *tty, n -= retval; is_eof = n == 1 && tty->read_buf[tty->read_tail] == EOF_CHAR(tty); - tty_audit_add_data(tty, &tty->read_buf[tty->read_tail], n); + tty_audit_add_data(tty, &tty->read_buf[tty->read_tail], n, + tty->icanon); spin_lock_irqsave(&tty->read_lock, flags); tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); tty->read_cnt -= n; diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c index b0b39b823cc..6953dc82850 100644 --- a/drivers/tty/tty_audit.c +++ b/drivers/tty/tty_audit.c @@ -23,7 +23,7 @@ struct tty_audit_buf { }; static struct tty_audit_buf *tty_audit_buf_alloc(int major, int minor, - int icanon) + unsigned icanon) { struct tty_audit_buf *buf; @@ -239,7 +239,8 @@ int tty_audit_push_task(struct task_struct *tsk, kuid_t loginuid, u32 sessionid) * if TTY auditing is disabled or out of memory. Otherwise, return a new * reference to the buffer. */ -static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty) +static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, + unsigned icanon) { struct tty_audit_buf *buf, *buf2; @@ -257,7 +258,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty) buf2 = tty_audit_buf_alloc(tty->driver->major, tty->driver->minor_start + tty->index, - tty->icanon); + icanon); if (buf2 == NULL) { audit_log_lost("out of memory in TTY auditing"); return NULL; @@ -287,7 +288,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty) * Audit @data of @size from @tty, if necessary. */ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, - size_t size) + size_t size, unsigned icanon) { struct tty_audit_buf *buf; int major, minor; @@ -299,7 +300,7 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, && tty->driver->subtype == PTY_TYPE_MASTER) return; - buf = tty_audit_buf_get(tty); + buf = tty_audit_buf_get(tty, icanon); if (!buf) return; @@ -307,11 +308,11 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, major = tty->driver->major; minor = tty->driver->minor_start + tty->index; if (buf->major != major || buf->minor != minor - || buf->icanon != tty->icanon) { + || buf->icanon != icanon) { tty_audit_buf_push_current(buf); buf->major = major; buf->minor = minor; - buf->icanon = tty->icanon; + buf->icanon = icanon; } do { size_t run; diff --git a/include/linux/tty.h b/include/linux/tty.h index f0b4eb47297..f02712da5d8 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -535,7 +535,7 @@ extern void n_tty_inherit_ops(struct tty_ldisc_ops *ops); /* tty_audit.c */ #ifdef CONFIG_AUDIT extern void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, - size_t size); + size_t size, unsigned icanon); extern void tty_audit_exit(void); extern void tty_audit_fork(struct signal_struct *sig); extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); @@ -544,7 +544,7 @@ extern int tty_audit_push_task(struct task_struct *tsk, kuid_t loginuid, u32 sessionid); #else static inline void tty_audit_add_data(struct tty_struct *tty, - unsigned char *data, size_t size) + unsigned char *data, size_t size, unsigned icanon) { } static inline void tty_audit_tiocsti(struct tty_struct *tty, char ch) -- cgit v1.2.3 From 70ece7a731598ac760c2a34421fcb2de18d2713f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:38 +0200 Subject: TTY: n_tty, add ldisc data to n_tty All n_tty related members from tty_struct will be moved here. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 3ebab0cfceb..3d1594e10d0 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -73,6 +73,10 @@ #define ECHO_OP_SET_CANON_COL 0x81 #define ECHO_OP_ERASE_TAB 0x82 +struct n_tty_data { + char dummy; +}; + static inline int tty_put_user(struct tty_struct *tty, unsigned char x, unsigned char __user *ptr) { @@ -1556,11 +1560,15 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) static void n_tty_close(struct tty_struct *tty) { + struct n_tty_data *ldata = tty->disc_data; + n_tty_flush_buffer(tty); kfree(tty->read_buf); kfree(tty->echo_buf); + kfree(ldata); tty->read_buf = NULL; tty->echo_buf = NULL; + tty->disc_data = NULL; } /** @@ -1575,23 +1583,32 @@ static void n_tty_close(struct tty_struct *tty) static int n_tty_open(struct tty_struct *tty) { + struct n_tty_data *ldata; + + ldata = kzalloc(sizeof(*ldata), GFP_KERNEL); + if (!ldata) + goto err; + /* These are ugly. Currently a malloc failure here can panic */ tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); tty->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); if (!tty->read_buf || !tty->echo_buf) goto err_free_bufs; + tty->disc_data = ldata; reset_buffer_flags(tty); tty_unthrottle(tty); tty->column = 0; n_tty_set_termios(tty, NULL); tty->minimum_to_wake = 1; tty->closing = 0; + return 0; err_free_bufs: kfree(tty->read_buf); kfree(tty->echo_buf); - + kfree(ldata); +err: return -ENOMEM; } -- cgit v1.2.3 From 53c5ee2cfb4dadc4f5c24fe671e2fbfc034c875e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:39 +0200 Subject: TTY: move ldisc data from tty_struct: simple members Here we start moving all the n_tty related bits from tty_struct to the newly defined n_tty_data struct in n_tty proper. In this patch primitive members and bits are moved. The rest will be done per-partes in the next patches. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 160 ++++++++++++++++++++++++++++++--------------------- drivers/tty/tty_io.c | 1 - include/linux/tty.h | 5 -- 3 files changed, 93 insertions(+), 73 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 3d1594e10d0..bd775a7c062 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -74,13 +74,20 @@ #define ECHO_OP_ERASE_TAB 0x82 struct n_tty_data { - char dummy; + unsigned int column; + unsigned long overrun_time; + int num_overrun; + + unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1; + unsigned char echo_overrun:1; }; static inline int tty_put_user(struct tty_struct *tty, unsigned char x, unsigned char __user *ptr) { - tty_audit_add_data(tty, &x, 1, tty->icanon); + struct n_tty_data *ldata = tty->disc_data; + + tty_audit_add_data(tty, &x, 1, ldata->icanon); return put_user(x, ptr); } @@ -96,6 +103,7 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, static void n_tty_set_room(struct tty_struct *tty) { + struct n_tty_data *ldata = tty->disc_data; int left; int old_left; @@ -115,7 +123,7 @@ static void n_tty_set_room(struct tty_struct *tty) * characters will be beeped. */ if (left <= 0) - left = tty->icanon && !tty->canon_data; + left = ldata->icanon && !tty->canon_data; old_left = tty->receive_room; tty->receive_room = left; @@ -183,6 +191,7 @@ static void check_unthrottle(struct tty_struct *tty) static void reset_buffer_flags(struct tty_struct *tty) { + struct n_tty_data *ldata = tty->disc_data; unsigned long flags; spin_lock_irqsave(&tty->read_lock, flags); @@ -190,10 +199,10 @@ static void reset_buffer_flags(struct tty_struct *tty) spin_unlock_irqrestore(&tty->read_lock, flags); mutex_lock(&tty->echo_lock); - tty->echo_pos = tty->echo_cnt = tty->echo_overrun = 0; + tty->echo_pos = tty->echo_cnt = ldata->echo_overrun = 0; mutex_unlock(&tty->echo_lock); - tty->canon_head = tty->canon_data = tty->erasing = 0; + tty->canon_head = tty->canon_data = ldata->erasing = 0; memset(&tty->read_flags, 0, sizeof tty->read_flags); n_tty_set_room(tty); } @@ -239,11 +248,12 @@ static void n_tty_flush_buffer(struct tty_struct *tty) static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) { + struct n_tty_data *ldata = tty->disc_data; unsigned long flags; ssize_t n = 0; spin_lock_irqsave(&tty->read_lock, flags); - if (!tty->icanon) { + if (!ldata->icanon) { n = tty->read_cnt; } else if (tty->canon_data) { n = (tty->canon_head > tty->read_tail) ? @@ -305,6 +315,7 @@ static inline int is_continuation(unsigned char c, struct tty_struct *tty) static int do_output_char(unsigned char c, struct tty_struct *tty, int space) { + struct n_tty_data *ldata = tty->disc_data; int spaces; if (!space) @@ -313,48 +324,48 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space) switch (c) { case '\n': if (O_ONLRET(tty)) - tty->column = 0; + ldata->column = 0; if (O_ONLCR(tty)) { if (space < 2) return -1; - tty->canon_column = tty->column = 0; + tty->canon_column = ldata->column = 0; tty->ops->write(tty, "\r\n", 2); return 2; } - tty->canon_column = tty->column; + tty->canon_column = ldata->column; break; case '\r': - if (O_ONOCR(tty) && tty->column == 0) + if (O_ONOCR(tty) && ldata->column == 0) return 0; if (O_OCRNL(tty)) { c = '\n'; if (O_ONLRET(tty)) - tty->canon_column = tty->column = 0; + tty->canon_column = ldata->column = 0; break; } - tty->canon_column = tty->column = 0; + tty->canon_column = ldata->column = 0; break; case '\t': - spaces = 8 - (tty->column & 7); + spaces = 8 - (ldata->column & 7); if (O_TABDLY(tty) == XTABS) { if (space < spaces) return -1; - tty->column += spaces; + ldata->column += spaces; tty->ops->write(tty, " ", spaces); return spaces; } - tty->column += spaces; + ldata->column += spaces; break; case '\b': - if (tty->column > 0) - tty->column--; + if (ldata->column > 0) + ldata->column--; break; default: if (!iscntrl(c)) { if (O_OLCUC(tty)) c = toupper(c); if (!is_continuation(c, tty)) - tty->column++; + ldata->column++; } break; } @@ -415,6 +426,7 @@ static int process_output(unsigned char c, struct tty_struct *tty) static ssize_t process_output_block(struct tty_struct *tty, const unsigned char *buf, unsigned int nr) { + struct n_tty_data *ldata = tty->disc_data; int space; int i; const unsigned char *cp; @@ -435,30 +447,30 @@ static ssize_t process_output_block(struct tty_struct *tty, switch (c) { case '\n': if (O_ONLRET(tty)) - tty->column = 0; + ldata->column = 0; if (O_ONLCR(tty)) goto break_out; - tty->canon_column = tty->column; + tty->canon_column = ldata->column; break; case '\r': - if (O_ONOCR(tty) && tty->column == 0) + if (O_ONOCR(tty) && ldata->column == 0) goto break_out; if (O_OCRNL(tty)) goto break_out; - tty->canon_column = tty->column = 0; + tty->canon_column = ldata->column = 0; break; case '\t': goto break_out; case '\b': - if (tty->column > 0) - tty->column--; + if (ldata->column > 0) + ldata->column--; break; default: if (!iscntrl(c)) { if (O_OLCUC(tty)) goto break_out; if (!is_continuation(c, tty)) - tty->column++; + ldata->column++; } break; } @@ -498,6 +510,7 @@ break_out: static void process_echoes(struct tty_struct *tty) { + struct n_tty_data *ldata = tty->disc_data; int space, nr; unsigned char c; unsigned char *cp, *buf_end; @@ -559,22 +572,22 @@ static void process_echoes(struct tty_struct *tty) space -= num_bs; while (num_bs--) { tty_put_char(tty, '\b'); - if (tty->column > 0) - tty->column--; + if (ldata->column > 0) + ldata->column--; } cp += 3; nr -= 3; break; case ECHO_OP_SET_CANON_COL: - tty->canon_column = tty->column; + tty->canon_column = ldata->column; cp += 2; nr -= 2; break; case ECHO_OP_MOVE_BACK_COL: - if (tty->column > 0) - tty->column--; + if (ldata->column > 0) + ldata->column--; cp += 2; nr -= 2; break; @@ -586,7 +599,7 @@ static void process_echoes(struct tty_struct *tty) break; } tty_put_char(tty, ECHO_OP_START); - tty->column++; + ldata->column++; space--; cp += 2; nr -= 2; @@ -608,7 +621,7 @@ static void process_echoes(struct tty_struct *tty) } tty_put_char(tty, '^'); tty_put_char(tty, op ^ 0100); - tty->column += 2; + ldata->column += 2; space -= 2; cp += 2; nr -= 2; @@ -641,14 +654,14 @@ static void process_echoes(struct tty_struct *tty) if (nr == 0) { tty->echo_pos = 0; tty->echo_cnt = 0; - tty->echo_overrun = 0; + ldata->echo_overrun = 0; } else { int num_processed = tty->echo_cnt - nr; tty->echo_pos += num_processed; tty->echo_pos &= N_TTY_BUF_SIZE - 1; tty->echo_cnt = nr; if (num_processed > 0) - tty->echo_overrun = 0; + ldata->echo_overrun = 0; } mutex_unlock(&tty->echo_lock); @@ -670,6 +683,7 @@ static void process_echoes(struct tty_struct *tty) static void add_echo_byte(unsigned char c, struct tty_struct *tty) { + struct n_tty_data *ldata = tty->disc_data; int new_byte_pos; if (tty->echo_cnt == N_TTY_BUF_SIZE) { @@ -695,7 +709,7 @@ static void add_echo_byte(unsigned char c, struct tty_struct *tty) } tty->echo_pos &= N_TTY_BUF_SIZE - 1; - tty->echo_overrun = 1; + ldata->echo_overrun = 1; } else { new_byte_pos = tty->echo_pos + tty->echo_cnt; new_byte_pos &= N_TTY_BUF_SIZE - 1; @@ -845,9 +859,10 @@ static void echo_char(unsigned char c, struct tty_struct *tty) static inline void finish_erasing(struct tty_struct *tty) { - if (tty->erasing) { + struct n_tty_data *ldata = tty->disc_data; + if (ldata->erasing) { echo_char_raw('/', tty); - tty->erasing = 0; + ldata->erasing = 0; } } @@ -865,6 +880,7 @@ static inline void finish_erasing(struct tty_struct *tty) static void eraser(unsigned char c, struct tty_struct *tty) { + struct n_tty_data *ldata = tty->disc_data; enum { ERASE, WERASE, KILL } kill_type; int head, seen_alnums, cnt; unsigned long flags; @@ -932,9 +948,9 @@ static void eraser(unsigned char c, struct tty_struct *tty) spin_unlock_irqrestore(&tty->read_lock, flags); if (L_ECHO(tty)) { if (L_ECHOPRT(tty)) { - if (!tty->erasing) { + if (!ldata->erasing) { echo_char_raw('\\', tty); - tty->erasing = 1; + ldata->erasing = 1; } /* if cnt > 1, output a multi-byte character */ echo_char(c, tty); @@ -1056,16 +1072,17 @@ static inline void n_tty_receive_break(struct tty_struct *tty) static inline void n_tty_receive_overrun(struct tty_struct *tty) { + struct n_tty_data *ldata = tty->disc_data; char buf[64]; - tty->num_overrun++; - if (time_before(tty->overrun_time, jiffies - HZ) || - time_after(tty->overrun_time, jiffies)) { + ldata->num_overrun++; + if (time_after(jiffies, ldata->overrun_time + HZ) || + time_after(ldata->overrun_time, jiffies)) { printk(KERN_WARNING "%s: %d input overrun(s)\n", tty_name(tty, buf), - tty->num_overrun); - tty->overrun_time = jiffies; - tty->num_overrun = 0; + ldata->num_overrun); + ldata->overrun_time = jiffies; + ldata->num_overrun = 0; } } @@ -1105,10 +1122,11 @@ static inline void n_tty_receive_parity_error(struct tty_struct *tty, static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) { + struct n_tty_data *ldata = tty->disc_data; unsigned long flags; int parmrk; - if (tty->raw) { + if (ldata->raw) { put_tty_queue(c, tty); return; } @@ -1147,8 +1165,8 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) * handle specially, do shortcut processing to speed things * up. */ - if (!test_bit(c, tty->process_char_map) || tty->lnext) { - tty->lnext = 0; + if (!test_bit(c, tty->process_char_map) || ldata->lnext) { + ldata->lnext = 0; parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { /* beep if no space */ @@ -1222,7 +1240,7 @@ send_signal: } else if (c == '\n' && I_INLCR(tty)) c = '\r'; - if (tty->icanon) { + if (ldata->icanon) { if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) || (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) { eraser(c, tty); @@ -1230,7 +1248,7 @@ send_signal: return; } if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) { - tty->lnext = 1; + ldata->lnext = 1; if (L_ECHO(tty)) { finish_erasing(tty); if (L_ECHOCTL(tty)) { @@ -1373,13 +1391,14 @@ static void n_tty_write_wakeup(struct tty_struct *tty) static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { + struct n_tty_data *ldata = tty->disc_data; const unsigned char *p; char *f, flags = TTY_NORMAL; int i; char buf[64]; unsigned long cpuflags; - if (tty->real_raw) { + if (ldata->real_raw) { spin_lock_irqsave(&tty->read_lock, cpuflags); i = min(N_TTY_BUF_SIZE - tty->read_cnt, N_TTY_BUF_SIZE - tty->read_head); @@ -1427,7 +1446,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, n_tty_set_room(tty); - if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || + if ((!ldata->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || L_EXTPROC(tty)) { kill_fasync(&tty->fasync, SIGIO, POLL_IN); if (waitqueue_active(&tty->read_wait)) @@ -1471,6 +1490,7 @@ int is_ignored(int sig) static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) { + struct n_tty_data *ldata = tty->disc_data; int canon_change = 1; if (old) @@ -1479,16 +1499,16 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) memset(&tty->read_flags, 0, sizeof tty->read_flags); tty->canon_head = tty->read_tail; tty->canon_data = 0; - tty->erasing = 0; + ldata->erasing = 0; } if (canon_change && !L_ICANON(tty) && tty->read_cnt) wake_up_interruptible(&tty->read_wait); - tty->icanon = (L_ICANON(tty) != 0); + ldata->icanon = (L_ICANON(tty) != 0); if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { - tty->raw = 1; - tty->real_raw = 1; + ldata->raw = 1; + ldata->real_raw = 1; n_tty_set_room(tty); return; } @@ -1531,16 +1551,16 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) set_bit(SUSP_CHAR(tty), tty->process_char_map); } clear_bit(__DISABLED_CHAR, tty->process_char_map); - tty->raw = 0; - tty->real_raw = 0; + ldata->raw = 0; + ldata->real_raw = 0; } else { - tty->raw = 1; + ldata->raw = 1; if ((I_IGNBRK(tty) || (!I_BRKINT(tty) && !I_PARMRK(tty))) && (I_IGNPAR(tty) || !I_INPCK(tty)) && (tty->driver->flags & TTY_DRIVER_REAL_RAW)) - tty->real_raw = 1; + ldata->real_raw = 1; else - tty->real_raw = 0; + ldata->real_raw = 0; } n_tty_set_room(tty); /* The termios change make the tty ready for I/O */ @@ -1589,6 +1609,8 @@ static int n_tty_open(struct tty_struct *tty) if (!ldata) goto err; + ldata->overrun_time = jiffies; + /* These are ugly. Currently a malloc failure here can panic */ tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); tty->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); @@ -1598,7 +1620,7 @@ static int n_tty_open(struct tty_struct *tty) tty->disc_data = ldata; reset_buffer_flags(tty); tty_unthrottle(tty); - tty->column = 0; + ldata->column = 0; n_tty_set_termios(tty, NULL); tty->minimum_to_wake = 1; tty->closing = 0; @@ -1614,8 +1636,10 @@ err: static inline int input_available_p(struct tty_struct *tty, int amt) { + struct n_tty_data *ldata = tty->disc_data; + tty_flush_to_ldisc(tty); - if (tty->icanon && !L_EXTPROC(tty)) { + if (ldata->icanon && !L_EXTPROC(tty)) { if (tty->canon_data) return 1; } else if (tty->read_cnt >= (amt ? amt : 1)) @@ -1646,6 +1670,7 @@ static int copy_from_read_buf(struct tty_struct *tty, size_t *nr) { + struct n_tty_data *ldata = tty->disc_data; int retval; size_t n; unsigned long flags; @@ -1662,12 +1687,12 @@ static int copy_from_read_buf(struct tty_struct *tty, is_eof = n == 1 && tty->read_buf[tty->read_tail] == EOF_CHAR(tty); tty_audit_add_data(tty, &tty->read_buf[tty->read_tail], n, - tty->icanon); + ldata->icanon); spin_lock_irqsave(&tty->read_lock, flags); tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); tty->read_cnt -= n; /* Turn single EOF into zero-length read */ - if (L_EXTPROC(tty) && tty->icanon && is_eof && !tty->read_cnt) + if (L_EXTPROC(tty) && ldata->icanon && is_eof && !tty->read_cnt) n = 0; spin_unlock_irqrestore(&tty->read_lock, flags); *b += n; @@ -1736,6 +1761,7 @@ static int job_control(struct tty_struct *tty, struct file *file) static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, unsigned char __user *buf, size_t nr) { + struct n_tty_data *ldata = tty->disc_data; unsigned char __user *b = buf; DECLARE_WAITQUEUE(wait, current); int c; @@ -1753,7 +1779,7 @@ do_it_again: minimum = time = 0; timeout = MAX_SCHEDULE_TIMEOUT; - if (!tty->icanon) { + if (!ldata->icanon) { time = (HZ / 10) * TIME_CHAR(tty); minimum = MIN_CHAR(tty); if (minimum) { @@ -1846,7 +1872,7 @@ do_it_again: nr--; } - if (tty->icanon && !L_EXTPROC(tty)) { + if (ldata->icanon && !L_EXTPROC(tty)) { /* N.B. avoid overrun if nr == 0 */ spin_lock_irqsave(&tty->read_lock, flags); while (nr && tty->read_cnt) { diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index e835a5b8d08..67b024ca16e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2932,7 +2932,6 @@ void initialize_tty_struct(struct tty_struct *tty, tty_ldisc_init(tty); tty->session = NULL; tty->pgrp = NULL; - tty->overrun_time = jiffies; tty_buffer_init(tty); mutex_init(&tty->legacy_mutex); mutex_init(&tty->termios_mutex); diff --git a/include/linux/tty.h b/include/linux/tty.h index f02712da5d8..de590cec973 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -270,13 +270,8 @@ struct tty_struct { * historical reasons, this is included in the tty structure. * Mostly locked by the BKL. */ - unsigned int column; - unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1; unsigned char closing:1; - unsigned char echo_overrun:1; unsigned short minimum_to_wake; - unsigned long overrun_time; - int num_overrun; unsigned long process_char_map[256/(8*sizeof(unsigned long))]; char *read_buf; int read_head; -- cgit v1.2.3 From 3fe780b379fac2e1eeb5907ee7c864756ce7ec83 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:40 +0200 Subject: TTY: move ldisc data from tty_struct: bitmaps Here we move bitmaps and use DECLARE_BITMAP to declare them in the new structure. And instead of memset, we use bitmap_zero as it is more appropriate. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 52 ++++++++++++++++++++++++++++------------------------ include/linux/tty.h | 2 -- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index bd775a7c062..702dd4adbdc 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -80,6 +80,9 @@ struct n_tty_data { unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1; unsigned char echo_overrun:1; + + DECLARE_BITMAP(process_char_map, 256); + DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE); }; static inline int tty_put_user(struct tty_struct *tty, unsigned char x, @@ -203,7 +206,7 @@ static void reset_buffer_flags(struct tty_struct *tty) mutex_unlock(&tty->echo_lock); tty->canon_head = tty->canon_data = ldata->erasing = 0; - memset(&tty->read_flags, 0, sizeof tty->read_flags); + bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); n_tty_set_room(tty); } @@ -1165,7 +1168,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) * handle specially, do shortcut processing to speed things * up. */ - if (!test_bit(c, tty->process_char_map) || ldata->lnext) { + if (!test_bit(c, ldata->process_char_map) || ldata->lnext) { ldata->lnext = 0; parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { @@ -1321,7 +1324,7 @@ send_signal: handle_newline: spin_lock_irqsave(&tty->read_lock, flags); - set_bit(tty->read_head, tty->read_flags); + set_bit(tty->read_head, ldata->read_flags); put_tty_queue_nolock(c, tty); tty->canon_head = tty->read_head; tty->canon_data++; @@ -1496,7 +1499,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) if (old) canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON; if (canon_change) { - memset(&tty->read_flags, 0, sizeof tty->read_flags); + bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); tty->canon_head = tty->read_tail; tty->canon_data = 0; ldata->erasing = 0; @@ -1516,41 +1519,41 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) || I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) || I_PARMRK(tty)) { - memset(tty->process_char_map, 0, 256/8); + bitmap_zero(ldata->process_char_map, 256); if (I_IGNCR(tty) || I_ICRNL(tty)) - set_bit('\r', tty->process_char_map); + set_bit('\r', ldata->process_char_map); if (I_INLCR(tty)) - set_bit('\n', tty->process_char_map); + set_bit('\n', ldata->process_char_map); if (L_ICANON(tty)) { - set_bit(ERASE_CHAR(tty), tty->process_char_map); - set_bit(KILL_CHAR(tty), tty->process_char_map); - set_bit(EOF_CHAR(tty), tty->process_char_map); - set_bit('\n', tty->process_char_map); - set_bit(EOL_CHAR(tty), tty->process_char_map); + set_bit(ERASE_CHAR(tty), ldata->process_char_map); + set_bit(KILL_CHAR(tty), ldata->process_char_map); + set_bit(EOF_CHAR(tty), ldata->process_char_map); + set_bit('\n', ldata->process_char_map); + set_bit(EOL_CHAR(tty), ldata->process_char_map); if (L_IEXTEN(tty)) { set_bit(WERASE_CHAR(tty), - tty->process_char_map); + ldata->process_char_map); set_bit(LNEXT_CHAR(tty), - tty->process_char_map); + ldata->process_char_map); set_bit(EOL2_CHAR(tty), - tty->process_char_map); + ldata->process_char_map); if (L_ECHO(tty)) set_bit(REPRINT_CHAR(tty), - tty->process_char_map); + ldata->process_char_map); } } if (I_IXON(tty)) { - set_bit(START_CHAR(tty), tty->process_char_map); - set_bit(STOP_CHAR(tty), tty->process_char_map); + set_bit(START_CHAR(tty), ldata->process_char_map); + set_bit(STOP_CHAR(tty), ldata->process_char_map); } if (L_ISIG(tty)) { - set_bit(INTR_CHAR(tty), tty->process_char_map); - set_bit(QUIT_CHAR(tty), tty->process_char_map); - set_bit(SUSP_CHAR(tty), tty->process_char_map); + set_bit(INTR_CHAR(tty), ldata->process_char_map); + set_bit(QUIT_CHAR(tty), ldata->process_char_map); + set_bit(SUSP_CHAR(tty), ldata->process_char_map); } - clear_bit(__DISABLED_CHAR, tty->process_char_map); + clear_bit(__DISABLED_CHAR, ldata->process_char_map); ldata->raw = 0; ldata->real_raw = 0; } else { @@ -1879,7 +1882,7 @@ do_it_again: int eol; eol = test_and_clear_bit(tty->read_tail, - tty->read_flags); + ldata->read_flags); c = tty->read_buf[tty->read_tail]; tty->read_tail = ((tty->read_tail+1) & (N_TTY_BUF_SIZE-1)); @@ -2105,6 +2108,7 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, static unsigned long inq_canon(struct tty_struct *tty) { + struct n_tty_data *ldata = tty->disc_data; int nr, head, tail; if (!tty->canon_data) @@ -2114,7 +2118,7 @@ static unsigned long inq_canon(struct tty_struct *tty) nr = (head - tail) & (N_TTY_BUF_SIZE-1); /* Skip EOF-chars.. */ while (head != tail) { - if (test_bit(tail, tty->read_flags) && + if (test_bit(tail, ldata->read_flags) && tty->read_buf[tail] == __DISABLED_CHAR) nr--; tail = (tail+1) & (N_TTY_BUF_SIZE-1); diff --git a/include/linux/tty.h b/include/linux/tty.h index de590cec973..2161e6b5a94 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -272,12 +272,10 @@ struct tty_struct { */ unsigned char closing:1; unsigned short minimum_to_wake; - unsigned long process_char_map[256/(8*sizeof(unsigned long))]; char *read_buf; int read_head; int read_tail; int read_cnt; - unsigned long read_flags[N_TTY_BUF_SIZE/(8*sizeof(unsigned long))]; unsigned char *echo_buf; unsigned int echo_pos; unsigned int echo_cnt; -- cgit v1.2.3 From ba2e68ac6157004ee4922fb39ebd9459bbae883e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:41 +0200 Subject: TTY: move ldisc data from tty_struct: read_* and echo_* and canon_* stuff All the ring-buffers... Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 260 +++++++++++++++++++++++++++------------------------- include/linux/tty.h | 10 -- 2 files changed, 137 insertions(+), 133 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 702dd4adbdc..4794537a50f 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -83,6 +83,19 @@ struct n_tty_data { DECLARE_BITMAP(process_char_map, 256); DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE); + + char *read_buf; + int read_head; + int read_tail; + int read_cnt; + + unsigned char *echo_buf; + unsigned int echo_pos; + unsigned int echo_cnt; + + int canon_data; + unsigned long canon_head; + unsigned int canon_column; }; static inline int tty_put_user(struct tty_struct *tty, unsigned char x, @@ -110,14 +123,14 @@ static void n_tty_set_room(struct tty_struct *tty) int left; int old_left; - /* tty->read_cnt is not read locked ? */ + /* ldata->read_cnt is not read locked ? */ if (I_PARMRK(tty)) { /* Multiply read_cnt by 3, since each byte might take up to * three times as many spaces when PARMRK is set (depending on * its flags, e.g. parity error). */ - left = N_TTY_BUF_SIZE - tty->read_cnt * 3 - 1; + left = N_TTY_BUF_SIZE - ldata->read_cnt * 3 - 1; } else - left = N_TTY_BUF_SIZE - tty->read_cnt - 1; + left = N_TTY_BUF_SIZE - ldata->read_cnt - 1; /* * If we are doing input canonicalization, and there are no @@ -126,7 +139,7 @@ static void n_tty_set_room(struct tty_struct *tty) * characters will be beeped. */ if (left <= 0) - left = ldata->icanon && !tty->canon_data; + left = ldata->icanon && !ldata->canon_data; old_left = tty->receive_room; tty->receive_room = left; @@ -137,10 +150,12 @@ static void n_tty_set_room(struct tty_struct *tty) static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) { - if (tty->read_cnt < N_TTY_BUF_SIZE) { - tty->read_buf[tty->read_head] = c; - tty->read_head = (tty->read_head + 1) & (N_TTY_BUF_SIZE-1); - tty->read_cnt++; + struct n_tty_data *ldata = tty->disc_data; + + if (ldata->read_cnt < N_TTY_BUF_SIZE) { + ldata->read_buf[ldata->read_head] = c; + ldata->read_head = (ldata->read_head + 1) & (N_TTY_BUF_SIZE-1); + ldata->read_cnt++; } } @@ -198,14 +213,14 @@ static void reset_buffer_flags(struct tty_struct *tty) unsigned long flags; spin_lock_irqsave(&tty->read_lock, flags); - tty->read_head = tty->read_tail = tty->read_cnt = 0; + ldata->read_head = ldata->read_tail = ldata->read_cnt = 0; spin_unlock_irqrestore(&tty->read_lock, flags); mutex_lock(&tty->echo_lock); - tty->echo_pos = tty->echo_cnt = ldata->echo_overrun = 0; + ldata->echo_pos = ldata->echo_cnt = ldata->echo_overrun = 0; mutex_unlock(&tty->echo_lock); - tty->canon_head = tty->canon_data = ldata->erasing = 0; + ldata->canon_head = ldata->canon_data = ldata->erasing = 0; bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); n_tty_set_room(tty); } @@ -257,11 +272,11 @@ static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) spin_lock_irqsave(&tty->read_lock, flags); if (!ldata->icanon) { - n = tty->read_cnt; - } else if (tty->canon_data) { - n = (tty->canon_head > tty->read_tail) ? - tty->canon_head - tty->read_tail : - tty->canon_head + (N_TTY_BUF_SIZE - tty->read_tail); + n = ldata->read_cnt; + } else if (ldata->canon_data) { + n = (ldata->canon_head > ldata->read_tail) ? + ldata->canon_head - ldata->read_tail : + ldata->canon_head + (N_TTY_BUF_SIZE - ldata->read_tail); } spin_unlock_irqrestore(&tty->read_lock, flags); return n; @@ -331,11 +346,11 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space) if (O_ONLCR(tty)) { if (space < 2) return -1; - tty->canon_column = ldata->column = 0; + ldata->canon_column = ldata->column = 0; tty->ops->write(tty, "\r\n", 2); return 2; } - tty->canon_column = ldata->column; + ldata->canon_column = ldata->column; break; case '\r': if (O_ONOCR(tty) && ldata->column == 0) @@ -343,10 +358,10 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space) if (O_OCRNL(tty)) { c = '\n'; if (O_ONLRET(tty)) - tty->canon_column = ldata->column = 0; + ldata->canon_column = ldata->column = 0; break; } - tty->canon_column = ldata->column = 0; + ldata->canon_column = ldata->column = 0; break; case '\t': spaces = 8 - (ldata->column & 7); @@ -453,14 +468,14 @@ static ssize_t process_output_block(struct tty_struct *tty, ldata->column = 0; if (O_ONLCR(tty)) goto break_out; - tty->canon_column = ldata->column; + ldata->canon_column = ldata->column; break; case '\r': if (O_ONOCR(tty) && ldata->column == 0) goto break_out; if (O_OCRNL(tty)) goto break_out; - tty->canon_column = ldata->column = 0; + ldata->canon_column = ldata->column = 0; break; case '\t': goto break_out; @@ -518,7 +533,7 @@ static void process_echoes(struct tty_struct *tty) unsigned char c; unsigned char *cp, *buf_end; - if (!tty->echo_cnt) + if (!ldata->echo_cnt) return; mutex_lock(&tty->output_lock); @@ -526,9 +541,9 @@ static void process_echoes(struct tty_struct *tty) space = tty_write_room(tty); - buf_end = tty->echo_buf + N_TTY_BUF_SIZE; - cp = tty->echo_buf + tty->echo_pos; - nr = tty->echo_cnt; + buf_end = ldata->echo_buf + N_TTY_BUF_SIZE; + cp = ldata->echo_buf + ldata->echo_pos; + nr = ldata->echo_cnt; while (nr > 0) { c = *cp; if (c == ECHO_OP_START) { @@ -565,7 +580,7 @@ static void process_echoes(struct tty_struct *tty) * Otherwise, tab spacing is normal. */ if (!(num_chars & 0x80)) - num_chars += tty->canon_column; + num_chars += ldata->canon_column; num_bs = 8 - (num_chars & 7); if (num_bs > space) { @@ -583,7 +598,7 @@ static void process_echoes(struct tty_struct *tty) break; case ECHO_OP_SET_CANON_COL: - tty->canon_column = ldata->column; + ldata->canon_column = ldata->column; cp += 2; nr -= 2; break; @@ -655,14 +670,14 @@ static void process_echoes(struct tty_struct *tty) } if (nr == 0) { - tty->echo_pos = 0; - tty->echo_cnt = 0; + ldata->echo_pos = 0; + ldata->echo_cnt = 0; ldata->echo_overrun = 0; } else { - int num_processed = tty->echo_cnt - nr; - tty->echo_pos += num_processed; - tty->echo_pos &= N_TTY_BUF_SIZE - 1; - tty->echo_cnt = nr; + int num_processed = ldata->echo_cnt - nr; + ldata->echo_pos += num_processed; + ldata->echo_pos &= N_TTY_BUF_SIZE - 1; + ldata->echo_cnt = nr; if (num_processed > 0) ldata->echo_overrun = 0; } @@ -689,37 +704,37 @@ static void add_echo_byte(unsigned char c, struct tty_struct *tty) struct n_tty_data *ldata = tty->disc_data; int new_byte_pos; - if (tty->echo_cnt == N_TTY_BUF_SIZE) { + if (ldata->echo_cnt == N_TTY_BUF_SIZE) { /* Circular buffer is already at capacity */ - new_byte_pos = tty->echo_pos; + new_byte_pos = ldata->echo_pos; /* * Since the buffer start position needs to be advanced, * be sure to step by a whole operation byte group. */ - if (tty->echo_buf[tty->echo_pos] == ECHO_OP_START) { - if (tty->echo_buf[(tty->echo_pos + 1) & + if (ldata->echo_buf[ldata->echo_pos] == ECHO_OP_START) { + if (ldata->echo_buf[(ldata->echo_pos + 1) & (N_TTY_BUF_SIZE - 1)] == ECHO_OP_ERASE_TAB) { - tty->echo_pos += 3; - tty->echo_cnt -= 2; + ldata->echo_pos += 3; + ldata->echo_cnt -= 2; } else { - tty->echo_pos += 2; - tty->echo_cnt -= 1; + ldata->echo_pos += 2; + ldata->echo_cnt -= 1; } } else { - tty->echo_pos++; + ldata->echo_pos++; } - tty->echo_pos &= N_TTY_BUF_SIZE - 1; + ldata->echo_pos &= N_TTY_BUF_SIZE - 1; ldata->echo_overrun = 1; } else { - new_byte_pos = tty->echo_pos + tty->echo_cnt; + new_byte_pos = ldata->echo_pos + ldata->echo_cnt; new_byte_pos &= N_TTY_BUF_SIZE - 1; - tty->echo_cnt++; + ldata->echo_cnt++; } - tty->echo_buf[new_byte_pos] = c; + ldata->echo_buf[new_byte_pos] = c; } /** @@ -889,7 +904,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) unsigned long flags; /* FIXME: locking needed ? */ - if (tty->read_head == tty->canon_head) { + if (ldata->read_head == ldata->canon_head) { /* process_output('\a', tty); */ /* what do you think? */ return; } @@ -900,17 +915,17 @@ static void eraser(unsigned char c, struct tty_struct *tty) else { if (!L_ECHO(tty)) { spin_lock_irqsave(&tty->read_lock, flags); - tty->read_cnt -= ((tty->read_head - tty->canon_head) & + ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & (N_TTY_BUF_SIZE - 1)); - tty->read_head = tty->canon_head; + ldata->read_head = ldata->canon_head; spin_unlock_irqrestore(&tty->read_lock, flags); return; } if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) { spin_lock_irqsave(&tty->read_lock, flags); - tty->read_cnt -= ((tty->read_head - tty->canon_head) & + ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & (N_TTY_BUF_SIZE - 1)); - tty->read_head = tty->canon_head; + ldata->read_head = ldata->canon_head; spin_unlock_irqrestore(&tty->read_lock, flags); finish_erasing(tty); echo_char(KILL_CHAR(tty), tty); @@ -924,14 +939,14 @@ static void eraser(unsigned char c, struct tty_struct *tty) seen_alnums = 0; /* FIXME: Locking ?? */ - while (tty->read_head != tty->canon_head) { - head = tty->read_head; + while (ldata->read_head != ldata->canon_head) { + head = ldata->read_head; /* erase a single possibly multibyte character */ do { head = (head - 1) & (N_TTY_BUF_SIZE-1); - c = tty->read_buf[head]; - } while (is_continuation(c, tty) && head != tty->canon_head); + c = ldata->read_buf[head]; + } while (is_continuation(c, tty) && head != ldata->canon_head); /* do not partially erase */ if (is_continuation(c, tty)) @@ -944,10 +959,10 @@ static void eraser(unsigned char c, struct tty_struct *tty) else if (seen_alnums) break; } - cnt = (tty->read_head - head) & (N_TTY_BUF_SIZE-1); + cnt = (ldata->read_head - head) & (N_TTY_BUF_SIZE-1); spin_lock_irqsave(&tty->read_lock, flags); - tty->read_head = head; - tty->read_cnt -= cnt; + ldata->read_head = head; + ldata->read_cnt -= cnt; spin_unlock_irqrestore(&tty->read_lock, flags); if (L_ECHO(tty)) { if (L_ECHOPRT(tty)) { @@ -959,7 +974,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) echo_char(c, tty); while (--cnt > 0) { head = (head+1) & (N_TTY_BUF_SIZE-1); - echo_char_raw(tty->read_buf[head], tty); + echo_char_raw(ldata->read_buf[head], tty); echo_move_back_col(tty); } } else if (kill_type == ERASE && !L_ECHOE(tty)) { @@ -967,7 +982,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) } else if (c == '\t') { unsigned int num_chars = 0; int after_tab = 0; - unsigned long tail = tty->read_head; + unsigned long tail = ldata->read_head; /* * Count the columns used for characters @@ -976,9 +991,9 @@ static void eraser(unsigned char c, struct tty_struct *tty) * This info is used to go back the correct * number of columns. */ - while (tail != tty->canon_head) { + while (tail != ldata->canon_head) { tail = (tail-1) & (N_TTY_BUF_SIZE-1); - c = tty->read_buf[tail]; + c = ldata->read_buf[tail]; if (c == '\t') { after_tab = 1; break; @@ -1006,7 +1021,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) if (kill_type == ERASE) break; } - if (tty->read_head == tty->canon_head && L_ECHO(tty)) + if (ldata->read_head == ldata->canon_head && L_ECHO(tty)) finish_erasing(tty); } @@ -1171,7 +1186,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) if (!test_bit(c, ldata->process_char_map) || ldata->lnext) { ldata->lnext = 0; parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; - if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { + if (ldata->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { /* beep if no space */ if (L_ECHO(tty)) process_output('\a', tty); @@ -1180,7 +1195,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) if (L_ECHO(tty)) { finish_erasing(tty); /* Record the column of first canon char. */ - if (tty->canon_head == tty->read_head) + if (ldata->canon_head == ldata->read_head) echo_set_canon_col(tty); echo_char(c, tty); process_echoes(tty); @@ -1264,20 +1279,20 @@ send_signal: } if (c == REPRINT_CHAR(tty) && L_ECHO(tty) && L_IEXTEN(tty)) { - unsigned long tail = tty->canon_head; + unsigned long tail = ldata->canon_head; finish_erasing(tty); echo_char(c, tty); echo_char_raw('\n', tty); - while (tail != tty->read_head) { - echo_char(tty->read_buf[tail], tty); + while (tail != ldata->read_head) { + echo_char(ldata->read_buf[tail], tty); tail = (tail+1) & (N_TTY_BUF_SIZE-1); } process_echoes(tty); return; } if (c == '\n') { - if (tty->read_cnt >= N_TTY_BUF_SIZE) { + if (ldata->read_cnt >= N_TTY_BUF_SIZE) { if (L_ECHO(tty)) process_output('\a', tty); return; @@ -1289,9 +1304,9 @@ send_signal: goto handle_newline; } if (c == EOF_CHAR(tty)) { - if (tty->read_cnt >= N_TTY_BUF_SIZE) + if (ldata->read_cnt >= N_TTY_BUF_SIZE) return; - if (tty->canon_head != tty->read_head) + if (ldata->canon_head != ldata->read_head) set_bit(TTY_PUSH, &tty->flags); c = __DISABLED_CHAR; goto handle_newline; @@ -1300,7 +1315,7 @@ send_signal: (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) { parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; - if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk)) { + if (ldata->read_cnt >= (N_TTY_BUF_SIZE - parmrk)) { if (L_ECHO(tty)) process_output('\a', tty); return; @@ -1310,7 +1325,7 @@ send_signal: */ if (L_ECHO(tty)) { /* Record the column of first canon char. */ - if (tty->canon_head == tty->read_head) + if (ldata->canon_head == ldata->read_head) echo_set_canon_col(tty); echo_char(c, tty); process_echoes(tty); @@ -1324,10 +1339,10 @@ send_signal: handle_newline: spin_lock_irqsave(&tty->read_lock, flags); - set_bit(tty->read_head, ldata->read_flags); + set_bit(ldata->read_head, ldata->read_flags); put_tty_queue_nolock(c, tty); - tty->canon_head = tty->read_head; - tty->canon_data++; + ldata->canon_head = ldata->read_head; + ldata->canon_data++; spin_unlock_irqrestore(&tty->read_lock, flags); kill_fasync(&tty->fasync, SIGIO, POLL_IN); if (waitqueue_active(&tty->read_wait)) @@ -1337,7 +1352,7 @@ handle_newline: } parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; - if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { + if (ldata->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) { /* beep if no space */ if (L_ECHO(tty)) process_output('\a', tty); @@ -1349,7 +1364,7 @@ handle_newline: echo_char_raw('\n', tty); else { /* Record the column of first canon char. */ - if (tty->canon_head == tty->read_head) + if (ldata->canon_head == ldata->read_head) echo_set_canon_col(tty); echo_char(c, tty); } @@ -1403,21 +1418,21 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, if (ldata->real_raw) { spin_lock_irqsave(&tty->read_lock, cpuflags); - i = min(N_TTY_BUF_SIZE - tty->read_cnt, - N_TTY_BUF_SIZE - tty->read_head); + i = min(N_TTY_BUF_SIZE - ldata->read_cnt, + N_TTY_BUF_SIZE - ldata->read_head); i = min(count, i); - memcpy(tty->read_buf + tty->read_head, cp, i); - tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); - tty->read_cnt += i; + memcpy(ldata->read_buf + ldata->read_head, cp, i); + ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1); + ldata->read_cnt += i; cp += i; count -= i; - i = min(N_TTY_BUF_SIZE - tty->read_cnt, - N_TTY_BUF_SIZE - tty->read_head); + i = min(N_TTY_BUF_SIZE - ldata->read_cnt, + N_TTY_BUF_SIZE - ldata->read_head); i = min(count, i); - memcpy(tty->read_buf + tty->read_head, cp, i); - tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); - tty->read_cnt += i; + memcpy(ldata->read_buf + ldata->read_head, cp, i); + ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1); + ldata->read_cnt += i; spin_unlock_irqrestore(&tty->read_lock, cpuflags); } else { for (i = count, p = cp, f = fp; i; i--, p++) { @@ -1449,7 +1464,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, n_tty_set_room(tty); - if ((!ldata->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || + if ((!ldata->icanon && (ldata->read_cnt >= tty->minimum_to_wake)) || L_EXTPROC(tty)) { kill_fasync(&tty->fasync, SIGIO, POLL_IN); if (waitqueue_active(&tty->read_wait)) @@ -1500,12 +1515,12 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON; if (canon_change) { bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); - tty->canon_head = tty->read_tail; - tty->canon_data = 0; + ldata->canon_head = ldata->read_tail; + ldata->canon_data = 0; ldata->erasing = 0; } - if (canon_change && !L_ICANON(tty) && tty->read_cnt) + if (canon_change && !L_ICANON(tty) && ldata->read_cnt) wake_up_interruptible(&tty->read_wait); ldata->icanon = (L_ICANON(tty) != 0); @@ -1586,11 +1601,9 @@ static void n_tty_close(struct tty_struct *tty) struct n_tty_data *ldata = tty->disc_data; n_tty_flush_buffer(tty); - kfree(tty->read_buf); - kfree(tty->echo_buf); + kfree(ldata->read_buf); + kfree(ldata->echo_buf); kfree(ldata); - tty->read_buf = NULL; - tty->echo_buf = NULL; tty->disc_data = NULL; } @@ -1615,9 +1628,9 @@ static int n_tty_open(struct tty_struct *tty) ldata->overrun_time = jiffies; /* These are ugly. Currently a malloc failure here can panic */ - tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); - tty->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); - if (!tty->read_buf || !tty->echo_buf) + ldata->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); + ldata->echo_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); + if (!ldata->read_buf || !ldata->echo_buf) goto err_free_bufs; tty->disc_data = ldata; @@ -1630,8 +1643,8 @@ static int n_tty_open(struct tty_struct *tty) return 0; err_free_bufs: - kfree(tty->read_buf); - kfree(tty->echo_buf); + kfree(ldata->read_buf); + kfree(ldata->echo_buf); kfree(ldata); err: return -ENOMEM; @@ -1643,9 +1656,9 @@ static inline int input_available_p(struct tty_struct *tty, int amt) tty_flush_to_ldisc(tty); if (ldata->icanon && !L_EXTPROC(tty)) { - if (tty->canon_data) + if (ldata->canon_data) return 1; - } else if (tty->read_cnt >= (amt ? amt : 1)) + } else if (ldata->read_cnt >= (amt ? amt : 1)) return 1; return 0; @@ -1681,21 +1694,21 @@ static int copy_from_read_buf(struct tty_struct *tty, retval = 0; spin_lock_irqsave(&tty->read_lock, flags); - n = min(tty->read_cnt, N_TTY_BUF_SIZE - tty->read_tail); + n = min(ldata->read_cnt, N_TTY_BUF_SIZE - ldata->read_tail); n = min(*nr, n); spin_unlock_irqrestore(&tty->read_lock, flags); if (n) { - retval = copy_to_user(*b, &tty->read_buf[tty->read_tail], n); + retval = copy_to_user(*b, &ldata->read_buf[ldata->read_tail], n); n -= retval; is_eof = n == 1 && - tty->read_buf[tty->read_tail] == EOF_CHAR(tty); - tty_audit_add_data(tty, &tty->read_buf[tty->read_tail], n, + ldata->read_buf[ldata->read_tail] == EOF_CHAR(tty); + tty_audit_add_data(tty, &ldata->read_buf[ldata->read_tail], n, ldata->icanon); spin_lock_irqsave(&tty->read_lock, flags); - tty->read_tail = (tty->read_tail + n) & (N_TTY_BUF_SIZE-1); - tty->read_cnt -= n; + ldata->read_tail = (ldata->read_tail + n) & (N_TTY_BUF_SIZE-1); + ldata->read_cnt -= n; /* Turn single EOF into zero-length read */ - if (L_EXTPROC(tty) && ldata->icanon && is_eof && !tty->read_cnt) + if (L_EXTPROC(tty) && ldata->icanon && is_eof && !ldata->read_cnt) n = 0; spin_unlock_irqrestore(&tty->read_lock, flags); *b += n; @@ -1878,22 +1891,22 @@ do_it_again: if (ldata->icanon && !L_EXTPROC(tty)) { /* N.B. avoid overrun if nr == 0 */ spin_lock_irqsave(&tty->read_lock, flags); - while (nr && tty->read_cnt) { + while (nr && ldata->read_cnt) { int eol; - eol = test_and_clear_bit(tty->read_tail, + eol = test_and_clear_bit(ldata->read_tail, ldata->read_flags); - c = tty->read_buf[tty->read_tail]; - tty->read_tail = ((tty->read_tail+1) & + c = ldata->read_buf[ldata->read_tail]; + ldata->read_tail = ((ldata->read_tail+1) & (N_TTY_BUF_SIZE-1)); - tty->read_cnt--; + ldata->read_cnt--; if (eol) { /* this test should be redundant: * we shouldn't be reading data if * canon_data is 0 */ - if (--tty->canon_data < 0) - tty->canon_data = 0; + if (--ldata->canon_data < 0) + ldata->canon_data = 0; } spin_unlock_irqrestore(&tty->read_lock, flags); @@ -2111,15 +2124,15 @@ static unsigned long inq_canon(struct tty_struct *tty) struct n_tty_data *ldata = tty->disc_data; int nr, head, tail; - if (!tty->canon_data) + if (!ldata->canon_data) return 0; - head = tty->canon_head; - tail = tty->read_tail; + head = ldata->canon_head; + tail = ldata->read_tail; nr = (head - tail) & (N_TTY_BUF_SIZE-1); /* Skip EOF-chars.. */ while (head != tail) { if (test_bit(tail, ldata->read_flags) && - tty->read_buf[tail] == __DISABLED_CHAR) + ldata->read_buf[tail] == __DISABLED_CHAR) nr--; tail = (tail+1) & (N_TTY_BUF_SIZE-1); } @@ -2129,6 +2142,7 @@ static unsigned long inq_canon(struct tty_struct *tty) static int n_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { + struct n_tty_data *ldata = tty->disc_data; int retval; switch (cmd) { @@ -2136,7 +2150,7 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file, return put_user(tty_chars_in_buffer(tty), (int __user *) arg); case TIOCINQ: /* FIXME: Locking */ - retval = tty->read_cnt; + retval = ldata->read_cnt; if (L_ICANON(tty)) retval = inq_canon(tty); return put_user(retval, (unsigned int __user *) arg); diff --git a/include/linux/tty.h b/include/linux/tty.h index 2161e6b5a94..226cf20e015 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -272,16 +272,6 @@ struct tty_struct { */ unsigned char closing:1; unsigned short minimum_to_wake; - char *read_buf; - int read_head; - int read_tail; - int read_cnt; - unsigned char *echo_buf; - unsigned int echo_pos; - unsigned int echo_cnt; - int canon_data; - unsigned long canon_head; - unsigned int canon_column; struct mutex atomic_read_lock; struct mutex atomic_write_lock; struct mutex output_lock; -- cgit v1.2.3 From bddc7152f68bc1e0ee1f55a8055e33531f384101 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:42 +0200 Subject: TTY: move ldisc data from tty_struct: locks atomic_write_lock is not n_tty specific, so move it up in the tty_struct. And since these are the last ones to move, remove also the comment saying there are some ldisc' members. There are none now. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 123 ++++++++++++++++++++++++++++++--------------------- drivers/tty/tty_io.c | 4 -- include/linux/tty.h | 11 +---- 3 files changed, 73 insertions(+), 65 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 4794537a50f..0a6fcda9615 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -96,6 +96,11 @@ struct n_tty_data { int canon_data; unsigned long canon_head; unsigned int canon_column; + + struct mutex atomic_read_lock; + struct mutex output_lock; + struct mutex echo_lock; + spinlock_t read_lock; }; static inline int tty_put_user(struct tty_struct *tty, unsigned char x, @@ -171,14 +176,15 @@ static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) static void put_tty_queue(unsigned char c, struct tty_struct *tty) { + struct n_tty_data *ldata = tty->disc_data; unsigned long flags; /* * The problem of stomping on the buffers ends here. * Why didn't anyone see this one coming? --AJK */ - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); put_tty_queue_nolock(c, tty); - spin_unlock_irqrestore(&tty->read_lock, flags); + spin_unlock_irqrestore(&ldata->read_lock, flags); } /** @@ -212,13 +218,13 @@ static void reset_buffer_flags(struct tty_struct *tty) struct n_tty_data *ldata = tty->disc_data; unsigned long flags; - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); ldata->read_head = ldata->read_tail = ldata->read_cnt = 0; - spin_unlock_irqrestore(&tty->read_lock, flags); + spin_unlock_irqrestore(&ldata->read_lock, flags); - mutex_lock(&tty->echo_lock); + mutex_lock(&ldata->echo_lock); ldata->echo_pos = ldata->echo_cnt = ldata->echo_overrun = 0; - mutex_unlock(&tty->echo_lock); + mutex_unlock(&ldata->echo_lock); ldata->canon_head = ldata->canon_data = ldata->erasing = 0; bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); @@ -270,7 +276,7 @@ static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) unsigned long flags; ssize_t n = 0; - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); if (!ldata->icanon) { n = ldata->read_cnt; } else if (ldata->canon_data) { @@ -278,7 +284,7 @@ static ssize_t n_tty_chars_in_buffer(struct tty_struct *tty) ldata->canon_head - ldata->read_tail : ldata->canon_head + (N_TTY_BUF_SIZE - ldata->read_tail); } - spin_unlock_irqrestore(&tty->read_lock, flags); + spin_unlock_irqrestore(&ldata->read_lock, flags); return n; } @@ -408,14 +414,15 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space) static int process_output(unsigned char c, struct tty_struct *tty) { + struct n_tty_data *ldata = tty->disc_data; int space, retval; - mutex_lock(&tty->output_lock); + mutex_lock(&ldata->output_lock); space = tty_write_room(tty); retval = do_output_char(c, tty, space); - mutex_unlock(&tty->output_lock); + mutex_unlock(&ldata->output_lock); if (retval < 0) return -1; else @@ -449,11 +456,11 @@ static ssize_t process_output_block(struct tty_struct *tty, int i; const unsigned char *cp; - mutex_lock(&tty->output_lock); + mutex_lock(&ldata->output_lock); space = tty_write_room(tty); if (!space) { - mutex_unlock(&tty->output_lock); + mutex_unlock(&ldata->output_lock); return 0; } if (nr > space) @@ -496,7 +503,7 @@ static ssize_t process_output_block(struct tty_struct *tty, break_out: i = tty->ops->write(tty, buf, i); - mutex_unlock(&tty->output_lock); + mutex_unlock(&ldata->output_lock); return i; } @@ -536,8 +543,8 @@ static void process_echoes(struct tty_struct *tty) if (!ldata->echo_cnt) return; - mutex_lock(&tty->output_lock); - mutex_lock(&tty->echo_lock); + mutex_lock(&ldata->output_lock); + mutex_lock(&ldata->echo_lock); space = tty_write_room(tty); @@ -682,8 +689,8 @@ static void process_echoes(struct tty_struct *tty) ldata->echo_overrun = 0; } - mutex_unlock(&tty->echo_lock); - mutex_unlock(&tty->output_lock); + mutex_unlock(&ldata->echo_lock); + mutex_unlock(&ldata->output_lock); if (tty->ops->flush_chars) tty->ops->flush_chars(tty); @@ -748,12 +755,14 @@ static void add_echo_byte(unsigned char c, struct tty_struct *tty) static void echo_move_back_col(struct tty_struct *tty) { - mutex_lock(&tty->echo_lock); + struct n_tty_data *ldata = tty->disc_data; + + mutex_lock(&ldata->echo_lock); add_echo_byte(ECHO_OP_START, tty); add_echo_byte(ECHO_OP_MOVE_BACK_COL, tty); - mutex_unlock(&tty->echo_lock); + mutex_unlock(&ldata->echo_lock); } /** @@ -768,12 +777,14 @@ static void echo_move_back_col(struct tty_struct *tty) static void echo_set_canon_col(struct tty_struct *tty) { - mutex_lock(&tty->echo_lock); + struct n_tty_data *ldata = tty->disc_data; + + mutex_lock(&ldata->echo_lock); add_echo_byte(ECHO_OP_START, tty); add_echo_byte(ECHO_OP_SET_CANON_COL, tty); - mutex_unlock(&tty->echo_lock); + mutex_unlock(&ldata->echo_lock); } /** @@ -796,7 +807,9 @@ static void echo_set_canon_col(struct tty_struct *tty) static void echo_erase_tab(unsigned int num_chars, int after_tab, struct tty_struct *tty) { - mutex_lock(&tty->echo_lock); + struct n_tty_data *ldata = tty->disc_data; + + mutex_lock(&ldata->echo_lock); add_echo_byte(ECHO_OP_START, tty); add_echo_byte(ECHO_OP_ERASE_TAB, tty); @@ -810,7 +823,7 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab, add_echo_byte(num_chars, tty); - mutex_unlock(&tty->echo_lock); + mutex_unlock(&ldata->echo_lock); } /** @@ -828,7 +841,9 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab, static void echo_char_raw(unsigned char c, struct tty_struct *tty) { - mutex_lock(&tty->echo_lock); + struct n_tty_data *ldata = tty->disc_data; + + mutex_lock(&ldata->echo_lock); if (c == ECHO_OP_START) { add_echo_byte(ECHO_OP_START, tty); @@ -837,7 +852,7 @@ static void echo_char_raw(unsigned char c, struct tty_struct *tty) add_echo_byte(c, tty); } - mutex_unlock(&tty->echo_lock); + mutex_unlock(&ldata->echo_lock); } /** @@ -856,7 +871,9 @@ static void echo_char_raw(unsigned char c, struct tty_struct *tty) static void echo_char(unsigned char c, struct tty_struct *tty) { - mutex_lock(&tty->echo_lock); + struct n_tty_data *ldata = tty->disc_data; + + mutex_lock(&ldata->echo_lock); if (c == ECHO_OP_START) { add_echo_byte(ECHO_OP_START, tty); @@ -867,7 +884,7 @@ static void echo_char(unsigned char c, struct tty_struct *tty) add_echo_byte(c, tty); } - mutex_unlock(&tty->echo_lock); + mutex_unlock(&ldata->echo_lock); } /** @@ -914,19 +931,19 @@ static void eraser(unsigned char c, struct tty_struct *tty) kill_type = WERASE; else { if (!L_ECHO(tty)) { - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & (N_TTY_BUF_SIZE - 1)); ldata->read_head = ldata->canon_head; - spin_unlock_irqrestore(&tty->read_lock, flags); + spin_unlock_irqrestore(&ldata->read_lock, flags); return; } if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) { - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); ldata->read_cnt -= ((ldata->read_head - ldata->canon_head) & (N_TTY_BUF_SIZE - 1)); ldata->read_head = ldata->canon_head; - spin_unlock_irqrestore(&tty->read_lock, flags); + spin_unlock_irqrestore(&ldata->read_lock, flags); finish_erasing(tty); echo_char(KILL_CHAR(tty), tty); /* Add a newline if ECHOK is on and ECHOKE is off. */ @@ -960,10 +977,10 @@ static void eraser(unsigned char c, struct tty_struct *tty) break; } cnt = (ldata->read_head - head) & (N_TTY_BUF_SIZE-1); - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); ldata->read_head = head; ldata->read_cnt -= cnt; - spin_unlock_irqrestore(&tty->read_lock, flags); + spin_unlock_irqrestore(&ldata->read_lock, flags); if (L_ECHO(tty)) { if (L_ECHOPRT(tty)) { if (!ldata->erasing) { @@ -1338,12 +1355,12 @@ send_signal: put_tty_queue(c, tty); handle_newline: - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); set_bit(ldata->read_head, ldata->read_flags); put_tty_queue_nolock(c, tty); ldata->canon_head = ldata->read_head; ldata->canon_data++; - spin_unlock_irqrestore(&tty->read_lock, flags); + spin_unlock_irqrestore(&ldata->read_lock, flags); kill_fasync(&tty->fasync, SIGIO, POLL_IN); if (waitqueue_active(&tty->read_wait)) wake_up_interruptible(&tty->read_wait); @@ -1417,7 +1434,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, unsigned long cpuflags; if (ldata->real_raw) { - spin_lock_irqsave(&tty->read_lock, cpuflags); + spin_lock_irqsave(&ldata->read_lock, cpuflags); i = min(N_TTY_BUF_SIZE - ldata->read_cnt, N_TTY_BUF_SIZE - ldata->read_head); i = min(count, i); @@ -1433,7 +1450,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, memcpy(ldata->read_buf + ldata->read_head, cp, i); ldata->read_head = (ldata->read_head + i) & (N_TTY_BUF_SIZE-1); ldata->read_cnt += i; - spin_unlock_irqrestore(&tty->read_lock, cpuflags); + spin_unlock_irqrestore(&ldata->read_lock, cpuflags); } else { for (i = count, p = cp, f = fp; i; i--, p++) { if (f) @@ -1626,6 +1643,10 @@ static int n_tty_open(struct tty_struct *tty) goto err; ldata->overrun_time = jiffies; + mutex_init(&ldata->atomic_read_lock); + mutex_init(&ldata->output_lock); + mutex_init(&ldata->echo_lock); + spin_lock_init(&ldata->read_lock); /* These are ugly. Currently a malloc failure here can panic */ ldata->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); @@ -1677,7 +1698,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) * buffer, and once to drain the space from the (physical) beginning of * the buffer to head pointer. * - * Called under the tty->atomic_read_lock sem + * Called under the ldata->atomic_read_lock sem * */ @@ -1693,10 +1714,10 @@ static int copy_from_read_buf(struct tty_struct *tty, bool is_eof; retval = 0; - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); n = min(ldata->read_cnt, N_TTY_BUF_SIZE - ldata->read_tail); n = min(*nr, n); - spin_unlock_irqrestore(&tty->read_lock, flags); + spin_unlock_irqrestore(&ldata->read_lock, flags); if (n) { retval = copy_to_user(*b, &ldata->read_buf[ldata->read_tail], n); n -= retval; @@ -1704,13 +1725,13 @@ static int copy_from_read_buf(struct tty_struct *tty, ldata->read_buf[ldata->read_tail] == EOF_CHAR(tty); tty_audit_add_data(tty, &ldata->read_buf[ldata->read_tail], n, ldata->icanon); - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); ldata->read_tail = (ldata->read_tail + n) & (N_TTY_BUF_SIZE-1); ldata->read_cnt -= n; /* Turn single EOF into zero-length read */ if (L_EXTPROC(tty) && ldata->icanon && is_eof && !ldata->read_cnt) n = 0; - spin_unlock_irqrestore(&tty->read_lock, flags); + spin_unlock_irqrestore(&ldata->read_lock, flags); *b += n; *nr -= n; } @@ -1818,10 +1839,10 @@ do_it_again: * Internal serialization of reads. */ if (file->f_flags & O_NONBLOCK) { - if (!mutex_trylock(&tty->atomic_read_lock)) + if (!mutex_trylock(&ldata->atomic_read_lock)) return -EAGAIN; } else { - if (mutex_lock_interruptible(&tty->atomic_read_lock)) + if (mutex_lock_interruptible(&ldata->atomic_read_lock)) return -ERESTARTSYS; } packet = tty->packet; @@ -1890,7 +1911,7 @@ do_it_again: if (ldata->icanon && !L_EXTPROC(tty)) { /* N.B. avoid overrun if nr == 0 */ - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); while (nr && ldata->read_cnt) { int eol; @@ -1908,25 +1929,25 @@ do_it_again: if (--ldata->canon_data < 0) ldata->canon_data = 0; } - spin_unlock_irqrestore(&tty->read_lock, flags); + spin_unlock_irqrestore(&ldata->read_lock, flags); if (!eol || (c != __DISABLED_CHAR)) { if (tty_put_user(tty, c, b++)) { retval = -EFAULT; b--; - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); break; } nr--; } if (eol) { tty_audit_push(tty); - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); break; } - spin_lock_irqsave(&tty->read_lock, flags); + spin_lock_irqsave(&ldata->read_lock, flags); } - spin_unlock_irqrestore(&tty->read_lock, flags); + spin_unlock_irqrestore(&ldata->read_lock, flags); if (retval) break; } else { @@ -1958,7 +1979,7 @@ do_it_again: if (time) timeout = time; } - mutex_unlock(&tty->atomic_read_lock); + mutex_unlock(&ldata->atomic_read_lock); remove_wait_queue(&tty->read_wait, &wait); if (!waitqueue_active(&tty->read_wait)) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 67b024ca16e..f90b6217b3b 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2939,11 +2939,7 @@ void initialize_tty_struct(struct tty_struct *tty, init_waitqueue_head(&tty->write_wait); init_waitqueue_head(&tty->read_wait); INIT_WORK(&tty->hangup_work, do_tty_hangup); - mutex_init(&tty->atomic_read_lock); mutex_init(&tty->atomic_write_lock); - mutex_init(&tty->output_lock); - mutex_init(&tty->echo_lock); - spin_lock_init(&tty->read_lock); spin_lock_init(&tty->ctrl_lock); INIT_LIST_HEAD(&tty->tty_files); INIT_WORK(&tty->SAK_work, do_SAK_work); diff --git a/include/linux/tty.h b/include/linux/tty.h index 226cf20e015..08787ece3fd 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -235,6 +235,7 @@ struct tty_struct { struct mutex ldisc_mutex; struct tty_ldisc *ldisc; + struct mutex atomic_write_lock; struct mutex legacy_mutex; struct mutex termios_mutex; spinlock_t ctrl_lock; @@ -265,20 +266,10 @@ struct tty_struct { #define N_TTY_BUF_SIZE 4096 - /* - * The following is data for the N_TTY line discipline. For - * historical reasons, this is included in the tty structure. - * Mostly locked by the BKL. - */ unsigned char closing:1; unsigned short minimum_to_wake; - struct mutex atomic_read_lock; - struct mutex atomic_write_lock; - struct mutex output_lock; - struct mutex echo_lock; unsigned char *write_buf; int write_cnt; - spinlock_t read_lock; /* If the tty has a pending do_SAK, queue it here - akpm */ struct work_struct SAK_work; struct tty_port *port; -- cgit v1.2.3 From 57c941212d203979720081198ebda41f51812635 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:43 +0200 Subject: TTY: n_tty, propagate n_tty_data In some funtions we need only n_tty_data, so pass it down directly in case tty is not needed there. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 171 ++++++++++++++++++++++++---------------------------- 1 file changed, 78 insertions(+), 93 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 0a6fcda9615..531e539dbfc 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -153,10 +153,8 @@ static void n_tty_set_room(struct tty_struct *tty) schedule_work(&tty->buf.work); } -static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) +static void put_tty_queue_nolock(unsigned char c, struct n_tty_data *ldata) { - struct n_tty_data *ldata = tty->disc_data; - if (ldata->read_cnt < N_TTY_BUF_SIZE) { ldata->read_buf[ldata->read_head] = c; ldata->read_head = (ldata->read_head + 1) & (N_TTY_BUF_SIZE-1); @@ -167,23 +165,22 @@ static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) /** * put_tty_queue - add character to tty * @c: character - * @tty: tty device + * @ldata: n_tty data * * Add a character to the tty read_buf queue. This is done under the * read_lock to serialize character addition and also to protect us * against parallel reads or flushes */ -static void put_tty_queue(unsigned char c, struct tty_struct *tty) +static void put_tty_queue(unsigned char c, struct n_tty_data *ldata) { - struct n_tty_data *ldata = tty->disc_data; unsigned long flags; /* * The problem of stomping on the buffers ends here. * Why didn't anyone see this one coming? --AJK */ spin_lock_irqsave(&ldata->read_lock, flags); - put_tty_queue_nolock(c, tty); + put_tty_queue_nolock(c, ldata); spin_unlock_irqrestore(&ldata->read_lock, flags); } @@ -699,16 +696,15 @@ static void process_echoes(struct tty_struct *tty) /** * add_echo_byte - add a byte to the echo buffer * @c: unicode byte to echo - * @tty: terminal device + * @ldata: n_tty data * * Add a character or operation byte to the echo buffer. * * Should be called under the echo lock to protect the echo buffer. */ -static void add_echo_byte(unsigned char c, struct tty_struct *tty) +static void add_echo_byte(unsigned char c, struct n_tty_data *ldata) { - struct n_tty_data *ldata = tty->disc_data; int new_byte_pos; if (ldata->echo_cnt == N_TTY_BUF_SIZE) { @@ -746,28 +742,24 @@ static void add_echo_byte(unsigned char c, struct tty_struct *tty) /** * echo_move_back_col - add operation to move back a column - * @tty: terminal device + * @ldata: n_tty data * * Add an operation to the echo buffer to move back one column. * * Locking: echo_lock to protect the echo buffer */ -static void echo_move_back_col(struct tty_struct *tty) +static void echo_move_back_col(struct n_tty_data *ldata) { - struct n_tty_data *ldata = tty->disc_data; - mutex_lock(&ldata->echo_lock); - - add_echo_byte(ECHO_OP_START, tty); - add_echo_byte(ECHO_OP_MOVE_BACK_COL, tty); - + add_echo_byte(ECHO_OP_START, ldata); + add_echo_byte(ECHO_OP_MOVE_BACK_COL, ldata); mutex_unlock(&ldata->echo_lock); } /** * echo_set_canon_col - add operation to set the canon column - * @tty: terminal device + * @ldata: n_tty data * * Add an operation to the echo buffer to set the canon column * to the current column. @@ -775,15 +767,11 @@ static void echo_move_back_col(struct tty_struct *tty) * Locking: echo_lock to protect the echo buffer */ -static void echo_set_canon_col(struct tty_struct *tty) +static void echo_set_canon_col(struct n_tty_data *ldata) { - struct n_tty_data *ldata = tty->disc_data; - mutex_lock(&ldata->echo_lock); - - add_echo_byte(ECHO_OP_START, tty); - add_echo_byte(ECHO_OP_SET_CANON_COL, tty); - + add_echo_byte(ECHO_OP_START, ldata); + add_echo_byte(ECHO_OP_SET_CANON_COL, ldata); mutex_unlock(&ldata->echo_lock); } @@ -791,7 +779,7 @@ static void echo_set_canon_col(struct tty_struct *tty) * echo_erase_tab - add operation to erase a tab * @num_chars: number of character columns already used * @after_tab: true if num_chars starts after a previous tab - * @tty: terminal device + * @ldata: n_tty data * * Add an operation to the echo buffer to erase a tab. * @@ -805,14 +793,12 @@ static void echo_set_canon_col(struct tty_struct *tty) */ static void echo_erase_tab(unsigned int num_chars, int after_tab, - struct tty_struct *tty) + struct n_tty_data *ldata) { - struct n_tty_data *ldata = tty->disc_data; - mutex_lock(&ldata->echo_lock); - add_echo_byte(ECHO_OP_START, tty); - add_echo_byte(ECHO_OP_ERASE_TAB, tty); + add_echo_byte(ECHO_OP_START, ldata); + add_echo_byte(ECHO_OP_ERASE_TAB, ldata); /* We only need to know this modulo 8 (tab spacing) */ num_chars &= 7; @@ -821,7 +807,7 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab, if (after_tab) num_chars |= 0x80; - add_echo_byte(num_chars, tty); + add_echo_byte(num_chars, ldata); mutex_unlock(&ldata->echo_lock); } @@ -839,19 +825,15 @@ static void echo_erase_tab(unsigned int num_chars, int after_tab, * Locking: echo_lock to protect the echo buffer */ -static void echo_char_raw(unsigned char c, struct tty_struct *tty) +static void echo_char_raw(unsigned char c, struct n_tty_data *ldata) { - struct n_tty_data *ldata = tty->disc_data; - mutex_lock(&ldata->echo_lock); - if (c == ECHO_OP_START) { - add_echo_byte(ECHO_OP_START, tty); - add_echo_byte(ECHO_OP_START, tty); + add_echo_byte(ECHO_OP_START, ldata); + add_echo_byte(ECHO_OP_START, ldata); } else { - add_echo_byte(c, tty); + add_echo_byte(c, ldata); } - mutex_unlock(&ldata->echo_lock); } @@ -876,12 +858,12 @@ static void echo_char(unsigned char c, struct tty_struct *tty) mutex_lock(&ldata->echo_lock); if (c == ECHO_OP_START) { - add_echo_byte(ECHO_OP_START, tty); - add_echo_byte(ECHO_OP_START, tty); + add_echo_byte(ECHO_OP_START, ldata); + add_echo_byte(ECHO_OP_START, ldata); } else { if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t') - add_echo_byte(ECHO_OP_START, tty); - add_echo_byte(c, tty); + add_echo_byte(ECHO_OP_START, ldata); + add_echo_byte(c, ldata); } mutex_unlock(&ldata->echo_lock); @@ -889,14 +871,13 @@ static void echo_char(unsigned char c, struct tty_struct *tty) /** * finish_erasing - complete erase - * @tty: tty doing the erase + * @ldata: n_tty data */ -static inline void finish_erasing(struct tty_struct *tty) +static inline void finish_erasing(struct n_tty_data *ldata) { - struct n_tty_data *ldata = tty->disc_data; if (ldata->erasing) { - echo_char_raw('/', tty); + echo_char_raw('/', ldata); ldata->erasing = 0; } } @@ -944,11 +925,11 @@ static void eraser(unsigned char c, struct tty_struct *tty) (N_TTY_BUF_SIZE - 1)); ldata->read_head = ldata->canon_head; spin_unlock_irqrestore(&ldata->read_lock, flags); - finish_erasing(tty); + finish_erasing(ldata); echo_char(KILL_CHAR(tty), tty); /* Add a newline if ECHOK is on and ECHOKE is off. */ if (L_ECHOK(tty)) - echo_char_raw('\n', tty); + echo_char_raw('\n', ldata); return; } kill_type = KILL; @@ -984,15 +965,16 @@ static void eraser(unsigned char c, struct tty_struct *tty) if (L_ECHO(tty)) { if (L_ECHOPRT(tty)) { if (!ldata->erasing) { - echo_char_raw('\\', tty); + echo_char_raw('\\', ldata); ldata->erasing = 1; } /* if cnt > 1, output a multi-byte character */ echo_char(c, tty); while (--cnt > 0) { head = (head+1) & (N_TTY_BUF_SIZE-1); - echo_char_raw(ldata->read_buf[head], tty); - echo_move_back_col(tty); + echo_char_raw(ldata->read_buf[head], + ldata); + echo_move_back_col(ldata); } } else if (kill_type == ERASE && !L_ECHOE(tty)) { echo_char(ERASE_CHAR(tty), tty); @@ -1021,17 +1003,17 @@ static void eraser(unsigned char c, struct tty_struct *tty) num_chars++; } } - echo_erase_tab(num_chars, after_tab, tty); + echo_erase_tab(num_chars, after_tab, ldata); } else { if (iscntrl(c) && L_ECHOCTL(tty)) { - echo_char_raw('\b', tty); - echo_char_raw(' ', tty); - echo_char_raw('\b', tty); + echo_char_raw('\b', ldata); + echo_char_raw(' ', ldata); + echo_char_raw('\b', ldata); } if (!iscntrl(c) || L_ECHOCTL(tty)) { - echo_char_raw('\b', tty); - echo_char_raw(' ', tty); - echo_char_raw('\b', tty); + echo_char_raw('\b', ldata); + echo_char_raw(' ', ldata); + echo_char_raw('\b', ldata); } } } @@ -1039,7 +1021,7 @@ static void eraser(unsigned char c, struct tty_struct *tty) break; } if (ldata->read_head == ldata->canon_head && L_ECHO(tty)) - finish_erasing(tty); + finish_erasing(ldata); } /** @@ -1078,6 +1060,8 @@ static inline void isig(int sig, struct tty_struct *tty, int flush) static inline void n_tty_receive_break(struct tty_struct *tty) { + struct n_tty_data *ldata = tty->disc_data; + if (I_IGNBRK(tty)) return; if (I_BRKINT(tty)) { @@ -1085,10 +1069,10 @@ static inline void n_tty_receive_break(struct tty_struct *tty) return; } if (I_PARMRK(tty)) { - put_tty_queue('\377', tty); - put_tty_queue('\0', tty); + put_tty_queue('\377', ldata); + put_tty_queue('\0', ldata); } - put_tty_queue('\0', tty); + put_tty_queue('\0', ldata); wake_up_interruptible(&tty->read_wait); } @@ -1132,16 +1116,18 @@ static inline void n_tty_receive_overrun(struct tty_struct *tty) static inline void n_tty_receive_parity_error(struct tty_struct *tty, unsigned char c) { + struct n_tty_data *ldata = tty->disc_data; + if (I_IGNPAR(tty)) return; if (I_PARMRK(tty)) { - put_tty_queue('\377', tty); - put_tty_queue('\0', tty); - put_tty_queue(c, tty); + put_tty_queue('\377', ldata); + put_tty_queue('\0', ldata); + put_tty_queue(c, ldata); } else if (I_INPCK(tty)) - put_tty_queue('\0', tty); + put_tty_queue('\0', ldata); else - put_tty_queue(c, tty); + put_tty_queue(c, ldata); wake_up_interruptible(&tty->read_wait); } @@ -1162,7 +1148,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) int parmrk; if (ldata->raw) { - put_tty_queue(c, tty); + put_tty_queue(c, ldata); return; } @@ -1172,7 +1158,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) c = tolower(c); if (L_EXTPROC(tty)) { - put_tty_queue(c, tty); + put_tty_queue(c, ldata); return; } @@ -1210,16 +1196,16 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) return; } if (L_ECHO(tty)) { - finish_erasing(tty); + finish_erasing(ldata); /* Record the column of first canon char. */ if (ldata->canon_head == ldata->read_head) - echo_set_canon_col(tty); + echo_set_canon_col(ldata); echo_char(c, tty); process_echoes(tty); } if (parmrk) - put_tty_queue(c, tty); - put_tty_queue(c, tty); + put_tty_queue(c, ldata); + put_tty_queue(c, ldata); return; } @@ -1285,10 +1271,10 @@ send_signal: if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) { ldata->lnext = 1; if (L_ECHO(tty)) { - finish_erasing(tty); + finish_erasing(ldata); if (L_ECHOCTL(tty)) { - echo_char_raw('^', tty); - echo_char_raw('\b', tty); + echo_char_raw('^', ldata); + echo_char_raw('\b', ldata); process_echoes(tty); } } @@ -1298,9 +1284,9 @@ send_signal: L_IEXTEN(tty)) { unsigned long tail = ldata->canon_head; - finish_erasing(tty); + finish_erasing(ldata); echo_char(c, tty); - echo_char_raw('\n', tty); + echo_char_raw('\n', ldata); while (tail != ldata->read_head) { echo_char(ldata->read_buf[tail], tty); tail = (tail+1) & (N_TTY_BUF_SIZE-1); @@ -1315,7 +1301,7 @@ send_signal: return; } if (L_ECHO(tty) || L_ECHONL(tty)) { - echo_char_raw('\n', tty); + echo_char_raw('\n', ldata); process_echoes(tty); } goto handle_newline; @@ -1343,7 +1329,7 @@ send_signal: if (L_ECHO(tty)) { /* Record the column of first canon char. */ if (ldata->canon_head == ldata->read_head) - echo_set_canon_col(tty); + echo_set_canon_col(ldata); echo_char(c, tty); process_echoes(tty); } @@ -1352,12 +1338,12 @@ send_signal: * EOL_CHAR and EOL2_CHAR? */ if (parmrk) - put_tty_queue(c, tty); + put_tty_queue(c, ldata); handle_newline: spin_lock_irqsave(&ldata->read_lock, flags); set_bit(ldata->read_head, ldata->read_flags); - put_tty_queue_nolock(c, tty); + put_tty_queue_nolock(c, ldata); ldata->canon_head = ldata->read_head; ldata->canon_data++; spin_unlock_irqrestore(&ldata->read_lock, flags); @@ -1376,22 +1362,22 @@ handle_newline: return; } if (L_ECHO(tty)) { - finish_erasing(tty); + finish_erasing(ldata); if (c == '\n') - echo_char_raw('\n', tty); + echo_char_raw('\n', ldata); else { /* Record the column of first canon char. */ if (ldata->canon_head == ldata->read_head) - echo_set_canon_col(tty); + echo_set_canon_col(ldata); echo_char(c, tty); } process_echoes(tty); } if (parmrk) - put_tty_queue(c, tty); + put_tty_queue(c, ldata); - put_tty_queue(c, tty); + put_tty_queue(c, ldata); } @@ -2140,9 +2126,8 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file, return mask; } -static unsigned long inq_canon(struct tty_struct *tty) +static unsigned long inq_canon(struct n_tty_data *ldata) { - struct n_tty_data *ldata = tty->disc_data; int nr, head, tail; if (!ldata->canon_data) @@ -2173,7 +2158,7 @@ static int n_tty_ioctl(struct tty_struct *tty, struct file *file, /* FIXME: Locking */ retval = ldata->read_cnt; if (L_ICANON(tty)) - retval = inq_canon(tty); + retval = inq_canon(ldata); return put_user(retval, (unsigned int __user *) arg); default: return n_tty_ioctl_helper(tty, file, cmd, arg); -- cgit v1.2.3 From 2fc20661e3171d45e8e58a61eb5c6b7d8d614fde Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:44 +0200 Subject: TTY: move TTY_FLUSH* flags to tty_port They are only TTY buffers specific. And the buffers will go to tty_port in the next patches. So to remove the need to have both tty_port and tty_struct at some places, let us move the flags to tty_port. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 18 ++++++++++-------- include/linux/tty.h | 5 +++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 8b00f6a34a7..6f366f257fb 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -134,17 +134,18 @@ static void __tty_buffer_flush(struct tty_struct *tty) void tty_buffer_flush(struct tty_struct *tty) { + struct tty_port *port = tty->port; unsigned long flags; spin_lock_irqsave(&tty->buf.lock, flags); /* If the data is being pushed to the tty layer then we can't process it here. Instead set a flag and the flush_to_ldisc path will process the flush request before it exits */ - if (test_bit(TTY_FLUSHING, &tty->flags)) { - set_bit(TTY_FLUSHPENDING, &tty->flags); + if (test_bit(TTYP_FLUSHING, &port->iflags)) { + set_bit(TTYP_FLUSHPENDING, &port->iflags); spin_unlock_irqrestore(&tty->buf.lock, flags); wait_event(tty->read_wait, - test_bit(TTY_FLUSHPENDING, &tty->flags) == 0); + test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0); return; } else __tty_buffer_flush(tty); @@ -450,6 +451,7 @@ static void flush_to_ldisc(struct work_struct *work) { struct tty_struct *tty = container_of(work, struct tty_struct, buf.work); + struct tty_port *port = tty->port; unsigned long flags; struct tty_ldisc *disc; @@ -459,7 +461,7 @@ static void flush_to_ldisc(struct work_struct *work) spin_lock_irqsave(&tty->buf.lock, flags); - if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) { + if (!test_and_set_bit(TTYP_FLUSHING, &port->iflags)) { struct tty_buffer *head; while ((head = tty->buf.head) != NULL) { int count; @@ -477,7 +479,7 @@ static void flush_to_ldisc(struct work_struct *work) /* Ldisc or user is trying to flush the buffers we are feeding to the ldisc, stop feeding the line discipline as we want to empty the queue */ - if (test_bit(TTY_FLUSHPENDING, &tty->flags)) + if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) break; if (!tty->receive_room) break; @@ -491,14 +493,14 @@ static void flush_to_ldisc(struct work_struct *work) flag_buf, count); spin_lock_irqsave(&tty->buf.lock, flags); } - clear_bit(TTY_FLUSHING, &tty->flags); + clear_bit(TTYP_FLUSHING, &port->iflags); } /* We may have a deferred request to flush the input buffer, if so pull the chain under the lock and empty the queue */ - if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { + if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) { __tty_buffer_flush(tty); - clear_bit(TTY_FLUSHPENDING, &tty->flags); + clear_bit(TTYP_FLUSHPENDING, &port->iflags); wake_up(&tty->read_wait); } spin_unlock_irqrestore(&tty->buf.lock, flags); diff --git a/include/linux/tty.h b/include/linux/tty.h index 08787ece3fd..b4b3c568d24 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -197,6 +197,9 @@ struct tty_port { wait_queue_head_t close_wait; /* Close waiters */ wait_queue_head_t delta_msr_wait; /* Modem status change */ unsigned long flags; /* TTY flags ASY_*/ + unsigned long iflags; /* TTYP_ internal flags */ +#define TTYP_FLUSHING 1 /* Flushing to ldisc in progress */ +#define TTYP_FLUSHPENDING 2 /* Queued buffer flush pending */ unsigned char console:1; /* port is a console */ struct mutex mutex; /* Locking */ struct mutex buf_mutex; /* Buffer alloc lock */ @@ -309,8 +312,6 @@ struct tty_file_private { #define TTY_PTY_LOCK 16 /* pty private */ #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ #define TTY_HUPPED 18 /* Post driver->hangup() */ -#define TTY_FLUSHING 19 /* Flushing to ldisc in progress */ -#define TTY_FLUSHPENDING 20 /* Queued buffer flush pending */ #define TTY_HUPPING 21 /* ->hangup() in progress */ #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) -- cgit v1.2.3 From 5cff39c69b57df6d7bf4e87f2963571aa4ea6336 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:45 +0200 Subject: TTY: tty_buffer, cache pointer to tty->buf During the move of tty buffers from tty_struct to tty_port, we will need to switch all users of buf to tty->port->buf. There are many functions where this is accessed directly in their code many times. Cache the tty->buf pointer in such functions now and change only single lines in each function in the next patch. Not that it is convenient for the next patch, but the code is now also more readable. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 132 +++++++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 56 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 6f366f257fb..ddd74d41cbb 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -29,17 +29,19 @@ void tty_buffer_free_all(struct tty_struct *tty) { + struct tty_bufhead *buf = &tty->buf; struct tty_buffer *thead; - while ((thead = tty->buf.head) != NULL) { - tty->buf.head = thead->next; + + while ((thead = buf->head) != NULL) { + buf->head = thead->next; kfree(thead); } - while ((thead = tty->buf.free) != NULL) { - tty->buf.free = thead->next; + while ((thead = buf->free) != NULL) { + buf->free = thead->next; kfree(thead); } - tty->buf.tail = NULL; - tty->buf.memory_used = 0; + buf->tail = NULL; + buf->memory_used = 0; } /** @@ -87,15 +89,17 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) { + struct tty_bufhead *buf = &tty->buf; + /* Dumb strategy for now - should keep some stats */ - tty->buf.memory_used -= b->size; - WARN_ON(tty->buf.memory_used < 0); + buf->memory_used -= b->size; + WARN_ON(buf->memory_used < 0); if (b->size >= 512) kfree(b); else { - b->next = tty->buf.free; - tty->buf.free = b; + b->next = buf->free; + buf->free = b; } } @@ -112,13 +116,14 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) static void __tty_buffer_flush(struct tty_struct *tty) { + struct tty_bufhead *buf = &tty->buf; struct tty_buffer *thead; - while ((thead = tty->buf.head) != NULL) { - tty->buf.head = thead->next; + while ((thead = buf->head) != NULL) { + buf->head = thead->next; tty_buffer_free(tty, thead); } - tty->buf.tail = NULL; + buf->tail = NULL; } /** @@ -135,21 +140,23 @@ static void __tty_buffer_flush(struct tty_struct *tty) void tty_buffer_flush(struct tty_struct *tty) { struct tty_port *port = tty->port; + struct tty_bufhead *buf = &tty->buf; unsigned long flags; - spin_lock_irqsave(&tty->buf.lock, flags); + + spin_lock_irqsave(&buf->lock, flags); /* If the data is being pushed to the tty layer then we can't process it here. Instead set a flag and the flush_to_ldisc path will process the flush request before it exits */ if (test_bit(TTYP_FLUSHING, &port->iflags)) { set_bit(TTYP_FLUSHPENDING, &port->iflags); - spin_unlock_irqrestore(&tty->buf.lock, flags); + spin_unlock_irqrestore(&buf->lock, flags); wait_event(tty->read_wait, test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0); return; } else __tty_buffer_flush(tty); - spin_unlock_irqrestore(&tty->buf.lock, flags); + spin_unlock_irqrestore(&buf->lock, flags); } /** @@ -197,12 +204,14 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) */ static int __tty_buffer_request_room(struct tty_struct *tty, size_t size) { + struct tty_bufhead *buf = &tty->buf; struct tty_buffer *b, *n; int left; /* OPTIMISATION: We could keep a per tty "zero" sized buffer to remove this conditional if its worth it. This would be invisible to the callers */ - if ((b = tty->buf.tail) != NULL) + b = buf->tail; + if (b != NULL) left = b->size - b->used; else left = 0; @@ -214,8 +223,8 @@ static int __tty_buffer_request_room(struct tty_struct *tty, size_t size) b->next = n; b->commit = b->used; } else - tty->buf.head = n; - tty->buf.tail = n; + buf->head = n; + buf->tail = n; } else size = left; } @@ -262,6 +271,7 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room); int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, const unsigned char *chars, char flag, size_t size) { + struct tty_bufhead *buf = &tty->buf; int copied = 0; do { int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); @@ -269,18 +279,18 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, unsigned long flags; struct tty_buffer *tb; - spin_lock_irqsave(&tty->buf.lock, flags); + spin_lock_irqsave(&buf->lock, flags); space = __tty_buffer_request_room(tty, goal); - tb = tty->buf.tail; + tb = buf->tail; /* If there is no space then tb may be NULL */ if (unlikely(space == 0)) { - spin_unlock_irqrestore(&tty->buf.lock, flags); + spin_unlock_irqrestore(&buf->lock, flags); break; } memcpy(tb->char_buf_ptr + tb->used, chars, space); memset(tb->flag_buf_ptr + tb->used, flag, space); tb->used += space; - spin_unlock_irqrestore(&tty->buf.lock, flags); + spin_unlock_irqrestore(&buf->lock, flags); copied += space; chars += space; /* There is a small chance that we need to split the data over @@ -307,6 +317,7 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag); int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size) { + struct tty_bufhead *buf = &tty->buf; int copied = 0; do { int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); @@ -314,18 +325,18 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, unsigned long __flags; struct tty_buffer *tb; - spin_lock_irqsave(&tty->buf.lock, __flags); + spin_lock_irqsave(&buf->lock, __flags); space = __tty_buffer_request_room(tty, goal); - tb = tty->buf.tail; + tb = buf->tail; /* If there is no space then tb may be NULL */ if (unlikely(space == 0)) { - spin_unlock_irqrestore(&tty->buf.lock, __flags); + spin_unlock_irqrestore(&buf->lock, __flags); break; } memcpy(tb->char_buf_ptr + tb->used, chars, space); memcpy(tb->flag_buf_ptr + tb->used, flags, space); tb->used += space; - spin_unlock_irqrestore(&tty->buf.lock, __flags); + spin_unlock_irqrestore(&buf->lock, __flags); copied += space; chars += space; flags += space; @@ -351,12 +362,14 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); void tty_schedule_flip(struct tty_struct *tty) { + struct tty_bufhead *buf = &tty->buf; unsigned long flags; - spin_lock_irqsave(&tty->buf.lock, flags); - if (tty->buf.tail != NULL) - tty->buf.tail->commit = tty->buf.tail->used; - spin_unlock_irqrestore(&tty->buf.lock, flags); - schedule_work(&tty->buf.work); + + spin_lock_irqsave(&buf->lock, flags); + if (buf->tail != NULL) + buf->tail->commit = buf->tail->used; + spin_unlock_irqrestore(&buf->lock, flags); + schedule_work(&buf->work); } EXPORT_SYMBOL(tty_schedule_flip); @@ -378,20 +391,21 @@ EXPORT_SYMBOL(tty_schedule_flip); int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size) { + struct tty_bufhead *buf = &tty->buf; int space; unsigned long flags; struct tty_buffer *tb; - spin_lock_irqsave(&tty->buf.lock, flags); + spin_lock_irqsave(&buf->lock, flags); space = __tty_buffer_request_room(tty, size); - tb = tty->buf.tail; + tb = buf->tail; if (likely(space)) { *chars = tb->char_buf_ptr + tb->used; memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); tb->used += space; } - spin_unlock_irqrestore(&tty->buf.lock, flags); + spin_unlock_irqrestore(&buf->lock, flags); return space; } EXPORT_SYMBOL_GPL(tty_prepare_flip_string); @@ -415,20 +429,21 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size) { + struct tty_bufhead *buf = &tty->buf; int space; unsigned long __flags; struct tty_buffer *tb; - spin_lock_irqsave(&tty->buf.lock, __flags); + spin_lock_irqsave(&buf->lock, __flags); space = __tty_buffer_request_room(tty, size); - tb = tty->buf.tail; + tb = buf->tail; if (likely(space)) { *chars = tb->char_buf_ptr + tb->used; *flags = tb->flag_buf_ptr + tb->used; tb->used += space; } - spin_unlock_irqrestore(&tty->buf.lock, __flags); + spin_unlock_irqrestore(&buf->lock, __flags); return space; } EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); @@ -452,6 +467,7 @@ static void flush_to_ldisc(struct work_struct *work) struct tty_struct *tty = container_of(work, struct tty_struct, buf.work); struct tty_port *port = tty->port; + struct tty_bufhead *buf = &tty->buf; unsigned long flags; struct tty_ldisc *disc; @@ -459,11 +475,11 @@ static void flush_to_ldisc(struct work_struct *work) if (disc == NULL) /* !TTY_LDISC */ return; - spin_lock_irqsave(&tty->buf.lock, flags); + spin_lock_irqsave(&buf->lock, flags); if (!test_and_set_bit(TTYP_FLUSHING, &port->iflags)) { struct tty_buffer *head; - while ((head = tty->buf.head) != NULL) { + while ((head = buf->head) != NULL) { int count; char *char_buf; unsigned char *flag_buf; @@ -472,7 +488,7 @@ static void flush_to_ldisc(struct work_struct *work) if (!count) { if (head->next == NULL) break; - tty->buf.head = head->next; + buf->head = head->next; tty_buffer_free(tty, head); continue; } @@ -488,10 +504,10 @@ static void flush_to_ldisc(struct work_struct *work) char_buf = head->char_buf_ptr + head->read; flag_buf = head->flag_buf_ptr + head->read; head->read += count; - spin_unlock_irqrestore(&tty->buf.lock, flags); + spin_unlock_irqrestore(&buf->lock, flags); disc->ops->receive_buf(tty, char_buf, flag_buf, count); - spin_lock_irqsave(&tty->buf.lock, flags); + spin_lock_irqsave(&buf->lock, flags); } clear_bit(TTYP_FLUSHING, &port->iflags); } @@ -503,7 +519,7 @@ static void flush_to_ldisc(struct work_struct *work) clear_bit(TTYP_FLUSHPENDING, &port->iflags); wake_up(&tty->read_wait); } - spin_unlock_irqrestore(&tty->buf.lock, flags); + spin_unlock_irqrestore(&buf->lock, flags); tty_ldisc_deref(disc); } @@ -537,16 +553,18 @@ void tty_flush_to_ldisc(struct tty_struct *tty) void tty_flip_buffer_push(struct tty_struct *tty) { + struct tty_bufhead *buf = &tty->buf; unsigned long flags; - spin_lock_irqsave(&tty->buf.lock, flags); - if (tty->buf.tail != NULL) - tty->buf.tail->commit = tty->buf.tail->used; - spin_unlock_irqrestore(&tty->buf.lock, flags); + + spin_lock_irqsave(&buf->lock, flags); + if (buf->tail != NULL) + buf->tail->commit = buf->tail->used; + spin_unlock_irqrestore(&buf->lock, flags); if (tty->low_latency) - flush_to_ldisc(&tty->buf.work); + flush_to_ldisc(&buf->work); else - schedule_work(&tty->buf.work); + schedule_work(&buf->work); } EXPORT_SYMBOL(tty_flip_buffer_push); @@ -562,11 +580,13 @@ EXPORT_SYMBOL(tty_flip_buffer_push); void tty_buffer_init(struct tty_struct *tty) { - spin_lock_init(&tty->buf.lock); - tty->buf.head = NULL; - tty->buf.tail = NULL; - tty->buf.free = NULL; - tty->buf.memory_used = 0; - INIT_WORK(&tty->buf.work, flush_to_ldisc); + struct tty_bufhead *buf = &tty->buf; + + spin_lock_init(&buf->lock); + buf->head = NULL; + buf->tail = NULL; + buf->free = NULL; + buf->memory_used = 0; + INIT_WORK(&buf->work, flush_to_ldisc); } -- cgit v1.2.3 From 967fab6916681e5ab131fdef1226327b02454f19 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:46 +0200 Subject: TTY: add port -> tty link For that purpose we have to temporarily introduce a second tty back pointer into tty_port. It is because serial layer, and maybe others, still do not use tty_port_tty_set/get. So that we cannot set the tty_port->tty to NULL at will now. Yes, the fix would be to convert whole serial layer and all its users to tty_port_tty_set/get. However we are in the process of removing the need of tty in most of the call sites, so this would lead to a duplicated work. Instead we have now tty_port->itty (internal tty) which will be used only in flush_to_ldisc. For that one it is ensured that itty is valid wherever the work is run. IOW, the work is synchronously cancelled before we set itty to NULL and also before hangup is processed. After we need only tty_port and not tty_struct in most code, this shall be changed to tty_port_tty_set/get and itty removed completely. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 2 ++ drivers/tty/tty_io.c | 3 +++ include/linux/tty.h | 1 + 3 files changed, 6 insertions(+) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 2728afe52ee..c3269086267 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -345,6 +345,7 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, tty_port_init(ports[1]); o_tty->port = ports[0]; tty->port = ports[1]; + o_tty->port->itty = o_tty; tty_driver_kref_get(driver); tty->count++; @@ -371,6 +372,7 @@ static void pty_unix98_shutdown(struct tty_struct *tty) static void pty_cleanup(struct tty_struct *tty) { + tty->port->itty = NULL; kfree(tty->port); } diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index f90b6217b3b..202008f38ca 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1417,6 +1417,8 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) "%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n", __func__, tty->driver->name); + tty->port->itty = tty; + /* * Structures all installed ... call the ldisc open routines. * If we fail here just call release_tty to clean up. No need @@ -1552,6 +1554,7 @@ static void release_tty(struct tty_struct *tty, int idx) tty->ops->shutdown(tty); tty_free_termios(tty); tty_driver_remove_tty(tty->driver, tty); + tty->port->itty = NULL; if (tty->link) tty_kref_put(tty->link); diff --git a/include/linux/tty.h b/include/linux/tty.h index b4b3c568d24..9be74d649a5 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -189,6 +189,7 @@ struct tty_port_operations { struct tty_port { struct tty_struct *tty; /* Back pointer */ + struct tty_struct *itty; /* internal back ptr */ const struct tty_port_operations *ops; /* Port operations */ spinlock_t lock; /* Lock protecting tty field */ int blocked_open; /* Waiting to open */ -- cgit v1.2.3 From ecbbfd44a08fa80e0d664814efd4c187721b85f6 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Oct 2012 22:26:47 +0200 Subject: TTY: move tty buffers to tty_port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So this is it. The big step why we did all the work over the past kernel releases. Now everything is prepared, so nothing protects us from doing that big step. | | \ \ nnnn/^l | | | | \ / / | | | '-,.__ => \/ ,-` => | '-,.__ | O __.´´) ( .` | O __.´´) ~~~ ~~ `` ~~~ ~~ The buffers are now in the tty_port structure and we can start teaching the buffer helpers (insert char/string, flip etc.) to use tty_port instead of tty_struct all around. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 7 +++- drivers/tty/pty.c | 2 +- drivers/tty/tty_buffer.c | 102 ++++++++++++++++++++++++----------------------- drivers/tty/tty_io.c | 2 - drivers/tty/tty_ldisc.c | 10 ++--- drivers/tty/tty_port.c | 2 + include/linux/tty.h | 6 +-- include/linux/tty_flip.h | 2 +- 8 files changed, 70 insertions(+), 63 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 531e539dbfc..60b076cc4e2 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -149,8 +149,11 @@ static void n_tty_set_room(struct tty_struct *tty) tty->receive_room = left; /* Did this open up the receive buffer? We may need to flip */ - if (left && !old_left) - schedule_work(&tty->buf.work); + if (left && !old_left) { + WARN_RATELIMIT(tty->port->itty == NULL, + "scheduling with invalid itty"); + schedule_work(&tty->port->buf.work); + } } static void put_tty_queue_nolock(unsigned char c, struct n_tty_data *ldata) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index c3269086267..4219f040adb 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -93,7 +93,7 @@ static void pty_unthrottle(struct tty_struct *tty) static int pty_space(struct tty_struct *to) { - int n = 8192 - to->buf.memory_used; + int n = 8192 - to->port->buf.memory_used; if (n < 0) return 0; return n; diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index ddd74d41cbb..06725f5cc81 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -27,9 +27,9 @@ * Locking: none */ -void tty_buffer_free_all(struct tty_struct *tty) +void tty_buffer_free_all(struct tty_port *port) { - struct tty_bufhead *buf = &tty->buf; + struct tty_bufhead *buf = &port->buf; struct tty_buffer *thead; while ((thead = buf->head) != NULL) { @@ -56,11 +56,11 @@ void tty_buffer_free_all(struct tty_struct *tty) * Locking: Caller must hold tty->buf.lock */ -static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) +static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size) { struct tty_buffer *p; - if (tty->buf.memory_used + size > 65536) + if (port->buf.memory_used + size > 65536) return NULL; p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); if (p == NULL) @@ -72,7 +72,7 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) p->read = 0; p->char_buf_ptr = (char *)(p->data); p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; - tty->buf.memory_used += size; + port->buf.memory_used += size; return p; } @@ -87,9 +87,9 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) * Locking: Caller must hold tty->buf.lock */ -static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) +static void tty_buffer_free(struct tty_port *port, struct tty_buffer *b) { - struct tty_bufhead *buf = &tty->buf; + struct tty_bufhead *buf = &port->buf; /* Dumb strategy for now - should keep some stats */ buf->memory_used -= b->size; @@ -114,14 +114,14 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) * Locking: Caller must hold tty->buf.lock */ -static void __tty_buffer_flush(struct tty_struct *tty) +static void __tty_buffer_flush(struct tty_port *port) { - struct tty_bufhead *buf = &tty->buf; + struct tty_bufhead *buf = &port->buf; struct tty_buffer *thead; while ((thead = buf->head) != NULL) { buf->head = thead->next; - tty_buffer_free(tty, thead); + tty_buffer_free(port, thead); } buf->tail = NULL; } @@ -140,7 +140,7 @@ static void __tty_buffer_flush(struct tty_struct *tty) void tty_buffer_flush(struct tty_struct *tty) { struct tty_port *port = tty->port; - struct tty_bufhead *buf = &tty->buf; + struct tty_bufhead *buf = &port->buf; unsigned long flags; spin_lock_irqsave(&buf->lock, flags); @@ -155,7 +155,7 @@ void tty_buffer_flush(struct tty_struct *tty) test_bit(TTYP_FLUSHPENDING, &port->iflags) == 0); return; } else - __tty_buffer_flush(tty); + __tty_buffer_flush(port); spin_unlock_irqrestore(&buf->lock, flags); } @@ -171,9 +171,9 @@ void tty_buffer_flush(struct tty_struct *tty) * Locking: Caller must hold tty->buf.lock */ -static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) +static struct tty_buffer *tty_buffer_find(struct tty_port *port, size_t size) { - struct tty_buffer **tbh = &tty->buf.free; + struct tty_buffer **tbh = &port->buf.free; while ((*tbh) != NULL) { struct tty_buffer *t = *tbh; if (t->size >= size) { @@ -182,14 +182,14 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) t->used = 0; t->commit = 0; t->read = 0; - tty->buf.memory_used += t->size; + port->buf.memory_used += t->size; return t; } tbh = &((*tbh)->next); } /* Round the buffer size out */ size = (size + 0xFF) & ~0xFF; - return tty_buffer_alloc(tty, size); + return tty_buffer_alloc(port, size); /* Should possibly check if this fails for the largest buffer we have queued and recycle that ? */ } @@ -200,11 +200,11 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) * * Make at least size bytes of linear space available for the tty * buffer. If we fail return the size we managed to find. - * Locking: Caller must hold tty->buf.lock + * Locking: Caller must hold port->buf.lock */ -static int __tty_buffer_request_room(struct tty_struct *tty, size_t size) +static int __tty_buffer_request_room(struct tty_port *port, size_t size) { - struct tty_bufhead *buf = &tty->buf; + struct tty_bufhead *buf = &port->buf; struct tty_buffer *b, *n; int left; /* OPTIMISATION: We could keep a per tty "zero" sized buffer to @@ -218,7 +218,7 @@ static int __tty_buffer_request_room(struct tty_struct *tty, size_t size) if (left < size) { /* This is the slow path - looking for new buffers to use */ - if ((n = tty_buffer_find(tty, size)) != NULL) { + if ((n = tty_buffer_find(port, size)) != NULL) { if (b != NULL) { b->next = n; b->commit = b->used; @@ -241,16 +241,17 @@ static int __tty_buffer_request_room(struct tty_struct *tty, size_t size) * Make at least size bytes of linear space available for the tty * buffer. If we fail return the size we managed to find. * - * Locking: Takes tty->buf.lock + * Locking: Takes port->buf.lock */ int tty_buffer_request_room(struct tty_struct *tty, size_t size) { + struct tty_port *port = tty->port; unsigned long flags; int length; - spin_lock_irqsave(&tty->buf.lock, flags); - length = __tty_buffer_request_room(tty, size); - spin_unlock_irqrestore(&tty->buf.lock, flags); + spin_lock_irqsave(&port->buf.lock, flags); + length = __tty_buffer_request_room(port, size); + spin_unlock_irqrestore(&port->buf.lock, flags); return length; } EXPORT_SYMBOL_GPL(tty_buffer_request_room); @@ -265,13 +266,13 @@ EXPORT_SYMBOL_GPL(tty_buffer_request_room); * Queue a series of bytes to the tty buffering. All the characters * passed are marked with the supplied flag. Returns the number added. * - * Locking: Called functions may take tty->buf.lock + * Locking: Called functions may take port->buf.lock */ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, const unsigned char *chars, char flag, size_t size) { - struct tty_bufhead *buf = &tty->buf; + struct tty_bufhead *buf = &tty->port->buf; int copied = 0; do { int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); @@ -280,7 +281,7 @@ int tty_insert_flip_string_fixed_flag(struct tty_struct *tty, struct tty_buffer *tb; spin_lock_irqsave(&buf->lock, flags); - space = __tty_buffer_request_room(tty, goal); + space = __tty_buffer_request_room(tty->port, goal); tb = buf->tail; /* If there is no space then tb may be NULL */ if (unlikely(space == 0)) { @@ -311,13 +312,13 @@ EXPORT_SYMBOL(tty_insert_flip_string_fixed_flag); * the flags array indicates the status of the character. Returns the * number added. * - * Locking: Called functions may take tty->buf.lock + * Locking: Called functions may take port->buf.lock */ int tty_insert_flip_string_flags(struct tty_struct *tty, const unsigned char *chars, const char *flags, size_t size) { - struct tty_bufhead *buf = &tty->buf; + struct tty_bufhead *buf = &tty->port->buf; int copied = 0; do { int goal = min_t(size_t, size - copied, TTY_BUFFER_PAGE); @@ -326,7 +327,7 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, struct tty_buffer *tb; spin_lock_irqsave(&buf->lock, __flags); - space = __tty_buffer_request_room(tty, goal); + space = __tty_buffer_request_room(tty->port, goal); tb = buf->tail; /* If there is no space then tb may be NULL */ if (unlikely(space == 0)) { @@ -357,12 +358,12 @@ EXPORT_SYMBOL(tty_insert_flip_string_flags); * Note that this function can only be used when the low_latency flag * is unset. Otherwise the workqueue won't be flushed. * - * Locking: Takes tty->buf.lock + * Locking: Takes port->buf.lock */ void tty_schedule_flip(struct tty_struct *tty) { - struct tty_bufhead *buf = &tty->buf; + struct tty_bufhead *buf = &tty->port->buf; unsigned long flags; spin_lock_irqsave(&buf->lock, flags); @@ -385,19 +386,19 @@ EXPORT_SYMBOL(tty_schedule_flip); * that need their own block copy routines into the buffer. There is no * guarantee the buffer is a DMA target! * - * Locking: May call functions taking tty->buf.lock + * Locking: May call functions taking port->buf.lock */ int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, - size_t size) + size_t size) { - struct tty_bufhead *buf = &tty->buf; + struct tty_bufhead *buf = &tty->port->buf; int space; unsigned long flags; struct tty_buffer *tb; spin_lock_irqsave(&buf->lock, flags); - space = __tty_buffer_request_room(tty, size); + space = __tty_buffer_request_room(tty->port, size); tb = buf->tail; if (likely(space)) { @@ -423,19 +424,19 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); * that need their own block copy routines into the buffer. There is no * guarantee the buffer is a DMA target! * - * Locking: May call functions taking tty->buf.lock + * Locking: May call functions taking port->buf.lock */ int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size) { - struct tty_bufhead *buf = &tty->buf; + struct tty_bufhead *buf = &tty->port->buf; int space; unsigned long __flags; struct tty_buffer *tb; spin_lock_irqsave(&buf->lock, __flags); - space = __tty_buffer_request_room(tty, size); + space = __tty_buffer_request_room(tty->port, size); tb = buf->tail; if (likely(space)) { @@ -464,13 +465,16 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); static void flush_to_ldisc(struct work_struct *work) { - struct tty_struct *tty = - container_of(work, struct tty_struct, buf.work); - struct tty_port *port = tty->port; - struct tty_bufhead *buf = &tty->buf; + struct tty_port *port = container_of(work, struct tty_port, buf.work); + struct tty_bufhead *buf = &port->buf; + struct tty_struct *tty; unsigned long flags; struct tty_ldisc *disc; + tty = port->itty; + if (WARN_RATELIMIT(tty == NULL, "tty is NULL")) + return; + disc = tty_ldisc_ref(tty); if (disc == NULL) /* !TTY_LDISC */ return; @@ -489,7 +493,7 @@ static void flush_to_ldisc(struct work_struct *work) if (head->next == NULL) break; buf->head = head->next; - tty_buffer_free(tty, head); + tty_buffer_free(port, head); continue; } /* Ldisc or user is trying to flush the buffers @@ -515,7 +519,7 @@ static void flush_to_ldisc(struct work_struct *work) /* We may have a deferred request to flush the input buffer, if so pull the chain under the lock and empty the queue */ if (test_bit(TTYP_FLUSHPENDING, &port->iflags)) { - __tty_buffer_flush(tty); + __tty_buffer_flush(port); clear_bit(TTYP_FLUSHPENDING, &port->iflags); wake_up(&tty->read_wait); } @@ -535,7 +539,7 @@ static void flush_to_ldisc(struct work_struct *work) void tty_flush_to_ldisc(struct tty_struct *tty) { if (!tty->low_latency) - flush_work(&tty->buf.work); + flush_work(&tty->port->buf.work); } /** @@ -553,7 +557,7 @@ void tty_flush_to_ldisc(struct tty_struct *tty) void tty_flip_buffer_push(struct tty_struct *tty) { - struct tty_bufhead *buf = &tty->buf; + struct tty_bufhead *buf = &tty->port->buf; unsigned long flags; spin_lock_irqsave(&buf->lock, flags); @@ -578,9 +582,9 @@ EXPORT_SYMBOL(tty_flip_buffer_push); * Locking: none */ -void tty_buffer_init(struct tty_struct *tty) +void tty_buffer_init(struct tty_port *port) { - struct tty_bufhead *buf = &tty->buf; + struct tty_bufhead *buf = &port->buf; spin_lock_init(&buf->lock); buf->head = NULL; diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 202008f38ca..a3eba7f359e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -186,7 +186,6 @@ void free_tty_struct(struct tty_struct *tty) if (tty->dev) put_device(tty->dev); kfree(tty->write_buf); - tty_buffer_free_all(tty); tty->magic = 0xDEADDEAD; kfree(tty); } @@ -2935,7 +2934,6 @@ void initialize_tty_struct(struct tty_struct *tty, tty_ldisc_init(tty); tty->session = NULL; tty->pgrp = NULL; - tty_buffer_init(tty); mutex_init(&tty->legacy_mutex); mutex_init(&tty->termios_mutex); mutex_init(&tty->ldisc_mutex); diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 47e3968df10..f4e6754525d 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -512,7 +512,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) static int tty_ldisc_halt(struct tty_struct *tty) { clear_bit(TTY_LDISC, &tty->flags); - return cancel_work_sync(&tty->buf.work); + return cancel_work_sync(&tty->port->buf.work); } /** @@ -525,7 +525,7 @@ static void tty_ldisc_flush_works(struct tty_struct *tty) { flush_work(&tty->hangup_work); flush_work(&tty->SAK_work); - flush_work(&tty->buf.work); + flush_work(&tty->port->buf.work); } /** @@ -704,9 +704,9 @@ enable: /* Restart the work queue in case no characters kick it off. Safe if already running */ if (work) - schedule_work(&tty->buf.work); + schedule_work(&tty->port->buf.work); if (o_work) - schedule_work(&o_tty->buf.work); + schedule_work(&o_tty->port->buf.work); mutex_unlock(&tty->ldisc_mutex); tty_unlock(tty); return retval; @@ -817,7 +817,7 @@ void tty_ldisc_hangup(struct tty_struct *tty) */ clear_bit(TTY_LDISC, &tty->flags); tty_unlock(tty); - cancel_work_sync(&tty->buf.work); + cancel_work_sync(&tty->port->buf.work); mutex_unlock(&tty->ldisc_mutex); retry: tty_lock(tty); diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index d7bdd8d0c23..416b42f7c34 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -21,6 +21,7 @@ void tty_port_init(struct tty_port *port) { memset(port, 0, sizeof(*port)); + tty_buffer_init(port); init_waitqueue_head(&port->open_wait); init_waitqueue_head(&port->close_wait); init_waitqueue_head(&port->delta_msr_wait); @@ -126,6 +127,7 @@ static void tty_port_destructor(struct kref *kref) struct tty_port *port = container_of(kref, struct tty_port, kref); if (port->xmit_buf) free_page((unsigned long)port->xmit_buf); + tty_buffer_free_all(port); if (port->ops->destruct) port->ops->destruct(port); else diff --git a/include/linux/tty.h b/include/linux/tty.h index 9be74d649a5..d7ff88fb896 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -188,6 +188,7 @@ struct tty_port_operations { }; struct tty_port { + struct tty_bufhead buf; /* Locked internally */ struct tty_struct *tty; /* Back pointer */ struct tty_struct *itty; /* internal back ptr */ const struct tty_port_operations *ops; /* Port operations */ @@ -259,7 +260,6 @@ struct tty_struct { struct tty_struct *link; struct fasync_struct *fasync; - struct tty_bufhead buf; /* Locked internally */ int alt_speed; /* For magic substitution of 38400 bps */ wait_queue_head_t write_wait; wait_queue_head_t read_wait; @@ -388,9 +388,9 @@ extern void disassociate_ctty(int priv); extern void no_tty(void); extern void tty_flip_buffer_push(struct tty_struct *tty); extern void tty_flush_to_ldisc(struct tty_struct *tty); -extern void tty_buffer_free_all(struct tty_struct *tty); +extern void tty_buffer_free_all(struct tty_port *port); extern void tty_buffer_flush(struct tty_struct *tty); -extern void tty_buffer_init(struct tty_struct *tty); +extern void tty_buffer_init(struct tty_port *port); extern speed_t tty_get_baud_rate(struct tty_struct *tty); extern speed_t tty_termios_baud_rate(struct ktermios *termios); extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index 9239d033a0a..2002344ed36 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h @@ -11,7 +11,7 @@ void tty_schedule_flip(struct tty_struct *tty); static inline int tty_insert_flip_char(struct tty_struct *tty, unsigned char ch, char flag) { - struct tty_buffer *tb = tty->buf.tail; + struct tty_buffer *tb = tty->port->buf.tail; if (tb && tb->used < tb->size) { tb->flag_buf_ptr[tb->used] = flag; tb->char_buf_ptr[tb->used++] = ch; -- cgit v1.2.3 From 5843de34e2abd6b66ac6cebf2ce4739d404616dc Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 23 Oct 2012 12:16:08 +0200 Subject: MIPS: Alchemy: update development boards defconfigs with USB platform drivers Commit 2be350fa (MIPS: Alchemy: use the ehci platform driver) and commit e223a4cc (MIPS: Alchemy: use the OHCI platform driver) have change the Alchemy platform code to register an EHCI and OHCI platform driver, the defconfig file must thus be accordingly updated to build these drivers by default. Signed-off-by: Florian Fainelli Signed-off-by: Greg Kroah-Hartman --- arch/mips/configs/db1235_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/mips/configs/db1235_defconfig b/arch/mips/configs/db1235_defconfig index c48998ffd19..14752dde754 100644 --- a/arch/mips/configs/db1235_defconfig +++ b/arch/mips/configs/db1235_defconfig @@ -346,8 +346,10 @@ CONFIG_USB=y CONFIG_USB_DYNAMIC_MINORS=y CONFIG_USB_SUSPEND=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_STORAGE=y CONFIG_MMC=y CONFIG_MMC_CLKGATE=y -- cgit v1.2.3 From 068b054fde5cc0516717b4ec4d58d0659e1ca43b Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 23 Oct 2012 12:14:37 +0200 Subject: USB: OHCI: sm501: fix build failure after ohci_finish_controller_resume removal Commit cfa49b4b (USB: ohci: merge ohci_finish_controller_resume with ohci_resume) merged ohci_finish_controller_resume with ohci_resume but forgot to update the ohci-sm501 driver accordingly, thus causing the folllowing build failure: drivers/usb/host/ohci-sm501.c: In function 'ohci_sm501_resume': drivers/usb/host/ohci-sm501.c:241:2: error: implicit declaration of function 'ohci_finish_controller_resume' [-Werror=implicit-function-declaration] Reported-by: Fengguang Wu Signed-off-by: Florian Fainelli Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-sm501.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 5596ac2ba1c..3b5b908fd47 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -238,7 +238,7 @@ static int ohci_sm501_resume(struct platform_device *pdev) ohci->next_statechange = jiffies; sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1); - ohci_finish_controller_resume(hcd); + ohci_resume(hcd, false); return 0; } #else -- cgit v1.2.3 From f191eec58803e1e16c3421638cdcc9195c425851 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 3 Oct 2012 10:28:30 -0700 Subject: Documentation: Fix memory-barriers.txt example This commit fixes a broken example of overlapping stores in the Documentation/memory-barriers.txt file. Reported-by: Nikunj A Dadhania Signed-off-by: Paul E. McKenney --- Documentation/memory-barriers.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index 2759f7c188f..3c4e1b3b80a 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -251,12 +251,13 @@ And there are a number of things that _must_ or _must_not_ be assumed: And for: - *A = X; Y = *A; + *A = X; *(A + 4) = Y; - we may get either of: + we may get any of: - STORE *A = X; Y = LOAD *A; - STORE *A = Y = X; + STORE *A = X; STORE *(A + 4) = Y; + STORE *(A + 4) = Y; STORE *A = X; + STORE {*A, *(A + 4) } = {X, Y}; ========================= -- cgit v1.2.3 From 0f9574d83234274c4d8f8f742b45022e5718b16e Mon Sep 17 00:00:00 2001 From: Dhaval Giani Date: Wed, 17 Oct 2012 14:46:13 -0700 Subject: rcu: Correct the name of a reference in list of RCU papers Trying to go through the history of RCU (not for the weak minded) led me to search for a non-existent paper. Correct it to the actual reference Signed-off-by: Dhaval Giani Cc: Peter Zijlstra Signed-off-by: Paul E. McKenney --- Documentation/RCU/RTFP.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/RCU/RTFP.txt b/Documentation/RCU/RTFP.txt index 7c1dfb19fc4..7f40c72a9c5 100644 --- a/Documentation/RCU/RTFP.txt +++ b/Documentation/RCU/RTFP.txt @@ -186,7 +186,7 @@ Bibtex Entries @article{Kung80 ,author="H. T. Kung and Q. Lehman" -,title="Concurrent Maintenance of Binary Search Trees" +,title="Concurrent Manipulation of Binary Search Trees" ,Year="1980" ,Month="September" ,journal="ACM Transactions on Database Systems" -- cgit v1.2.3 From abfd6e58aed4f89fd69b9b17bc4b4527efe3a645 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 20 Sep 2012 16:59:47 -0700 Subject: rcu: Fix comment about _rcu_barrier()/orphanage exclusion In the old days, _rcu_barrier() acquired ->onofflock to exclude rcu_send_cbs_to_orphanage(), which allowed the latter to avoid memory barriers in callback handling. However, _rcu_barrier() recently started doing get_online_cpus() to lock out CPU-hotplug operations entirely, which means that the comment in rcu_send_cbs_to_orphanage() that talks about ->onofflock is now obsolete. This commit therefore fixes the comment. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutree.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 74df86bd920..ac8aed8ee41 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -1581,8 +1581,8 @@ rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp, { /* * Orphan the callbacks. First adjust the counts. This is safe - * because ->onofflock excludes _rcu_barrier()'s adoption of - * the callbacks, thus no memory barrier is required. + * because _rcu_barrier() excludes CPU-hotplug operations, so it + * cannot be running now. Thus no memory barrier is required. */ if (rdp->nxtlist != NULL) { rsp->qlen_lazy += rdp->qlen_lazy; -- cgit v1.2.3 From 489832609a1ad7189d11715d8cefb457d90182c5 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 24 Sep 2012 16:08:31 -0700 Subject: rcu: Make rcutorture give diagnostics if CPU offline fails This commit causes rcutorture to print the errno if cpu_down() fails when the rcutorture "verbose" module parameter is specified. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutorture.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index aaa7b9f3532..9900f560f1b 100644 --- a/kernel/rcutorture.c +++ b/kernel/rcutorture.c @@ -1502,6 +1502,7 @@ rcu_torture_onoff(void *arg) unsigned long delta; int maxcpu = -1; DEFINE_RCU_RANDOM(rand); + int ret; unsigned long starttime; VERBOSE_PRINTK_STRING("rcu_torture_onoff task started"); @@ -1522,7 +1523,13 @@ rcu_torture_onoff(void *arg) torture_type, cpu); starttime = jiffies; n_offline_attempts++; - if (cpu_down(cpu) == 0) { + ret = cpu_down(cpu); + if (ret) { + if (verbose) + pr_alert("%s" TORTURE_FLAG + "rcu_torture_onoff task: offline %d failed: errno %d\n", + torture_type, cpu, ret); + } else { if (verbose) pr_alert("%s" TORTURE_FLAG "rcu_torture_onoff task: offlined %d\n", -- cgit v1.2.3 From 4d9a5d4319e22670ec6d6227e12b54f361c46d0f Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 11 Oct 2012 01:47:16 +0200 Subject: rcu: Remove rcu_switch() It's only there to call rcu_user_hooks_switch(). Let's just call rcu_user_hooks_switch() directly, we don't need this function in the middle. Signed-off-by: Frederic Weisbecker Cc: Josh Triplett Cc: Peter Zijlstra Cc: Richard Weinberger Signed-off-by: Paul E. McKenney --- arch/um/drivers/mconsole_kern.c | 2 +- include/linux/rcupdate.h | 2 ++ include/linux/sched.h | 8 -------- kernel/sched/core.c | 2 +- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 79ccfe6c707..49e3b49e552 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -648,7 +648,7 @@ static void stack_proc(void *arg) struct task_struct *from = current, *to = arg; to->thread.saved_task = from; - rcu_switch(from, to); + rcu_user_hooks_switch(from, to); switch_to(from, to, from); } diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 7c968e4f929..5d009def7c0 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -204,6 +204,8 @@ static inline void rcu_user_enter(void) { } static inline void rcu_user_exit(void) { } static inline void rcu_user_enter_after_irq(void) { } static inline void rcu_user_exit_after_irq(void) { } +static inline void rcu_user_hooks_switch(struct task_struct *prev, + struct task_struct *next) { } #endif /* CONFIG_RCU_USER_QS */ extern void exit_rcu(void); diff --git a/include/linux/sched.h b/include/linux/sched.h index 0dd42a02df2..432cc5e1bbe 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1844,14 +1844,6 @@ static inline void rcu_copy_process(struct task_struct *p) #endif -static inline void rcu_switch(struct task_struct *prev, - struct task_struct *next) -{ -#ifdef CONFIG_RCU_USER_QS - rcu_user_hooks_switch(prev, next); -#endif -} - static inline void tsk_restore_flags(struct task_struct *task, unsigned long orig_flags, unsigned long flags) { diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 2d8927fda71..68414fa4cd2 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1887,7 +1887,7 @@ context_switch(struct rq *rq, struct task_struct *prev, #endif /* Here we just switch the register state and the stack. */ - rcu_switch(prev, next); + rcu_user_hooks_switch(prev, next); switch_to(prev, next, prev); barrier(); -- cgit v1.2.3 From ba49df4767d4fa5bbd2af3a51709fb81f94264ec Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sun, 7 Oct 2012 09:26:13 -0700 Subject: rcu: Update RCU_FAST_NO_HZ help text The RCU_FAST_NO_HZ help text included a warning about overhead on large systems, but that issue has since been resolved. The main remaining issue with RCU_FAST_NO_HZ is increased real-time latency. This commit therefore updates the help text accordingly. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- init/Kconfig | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index 6fdd6e33932..b63e7982c1c 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -582,14 +582,13 @@ config RCU_FAST_NO_HZ depends on NO_HZ && SMP default n help - This option causes RCU to attempt to accelerate grace periods - in order to allow CPUs to enter dynticks-idle state more - quickly. On the other hand, this option increases the overhead - of the dynticks-idle checking, particularly on systems with - large numbers of CPUs. - - Say Y if energy efficiency is critically important, particularly - if you have relatively few CPUs. + This option causes RCU to attempt to accelerate grace periods in + order to allow CPUs to enter dynticks-idle state more quickly. + On the other hand, this option increases the overhead of the + dynticks-idle checking, thus degrading scheduling latency. + + Say Y if energy efficiency is critically important, and you don't + care about real-time response. Say N if you are unsure. -- cgit v1.2.3 From 3705b88db0d7cc4a097c32d9e554054103d3f807 Mon Sep 17 00:00:00 2001 From: Antti P Miettinen Date: Fri, 5 Oct 2012 09:59:15 +0300 Subject: rcu: Add a module parameter to force use of expedited RCU primitives There have been some embedded applications that would benefit from use of expedited grace-period primitives. In some ways, this is similar to synchronize_net() doing either a normal or an expedited grace period depending on lock state, but with control outside of the kernel. This commit therefore adds rcu_expedited boot and sysfs parameters that cause the kernel to substitute expedited primitives for the normal grace-period primitives. [ paulmck: Add trace/event/rcu.h to kernel/srcu.c to avoid build error. Get rid of infinite loop through contention path.] Signed-off-by: Antti P Miettinen Signed-off-by: Paul E. McKenney --- kernel/ksysfs.c | 18 ++++++++++++++++++ kernel/rcu.h | 2 ++ kernel/rcupdate.c | 3 +++ kernel/rcutiny_plugin.h | 5 ++++- kernel/rcutree.c | 12 +++++++++--- kernel/rcutree_plugin.h | 7 +++++-- kernel/srcu.c | 8 +++++++- 7 files changed, 48 insertions(+), 7 deletions(-) diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index 4e316e1acf5..8715a798aa7 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -141,6 +141,23 @@ static ssize_t fscaps_show(struct kobject *kobj, } KERNEL_ATTR_RO(fscaps); +int rcu_expedited; +static ssize_t rcu_expedited_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", rcu_expedited); +} +static ssize_t rcu_expedited_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + if (kstrtoint(buf, 0, &rcu_expedited)) + return -EINVAL; + + return count; +} +KERNEL_ATTR_RW(rcu_expedited); + /* * Make /sys/kernel/notes give the raw contents of our kernel .notes section. */ @@ -182,6 +199,7 @@ static struct attribute * kernel_attrs[] = { &kexec_crash_size_attr.attr, &vmcoreinfo_attr.attr, #endif + &rcu_expedited_attr.attr, NULL }; diff --git a/kernel/rcu.h b/kernel/rcu.h index 8ba99cdc651..20dfba576c2 100644 --- a/kernel/rcu.h +++ b/kernel/rcu.h @@ -109,4 +109,6 @@ static inline bool __rcu_reclaim(char *rn, struct rcu_head *head) } } +extern int rcu_expedited; + #endif /* __LINUX_RCU_H */ diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 29ca1c6da59..a2cf76177b4 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -46,12 +46,15 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include #include "rcu.h" +module_param(rcu_expedited, int, 0); + #ifdef CONFIG_PREEMPT_RCU /* diff --git a/kernel/rcutiny_plugin.h b/kernel/rcutiny_plugin.h index 3d019028220..f85016a2309 100644 --- a/kernel/rcutiny_plugin.h +++ b/kernel/rcutiny_plugin.h @@ -706,7 +706,10 @@ void synchronize_rcu(void) return; /* Once we get past the fastpath checks, same code as rcu_barrier(). */ - rcu_barrier(); + if (rcu_expedited) + synchronize_rcu_expedited(); + else + rcu_barrier(); } EXPORT_SYMBOL_GPL(synchronize_rcu); diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 74df86bd920..f9c17c39953 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -2224,7 +2224,10 @@ void synchronize_sched(void) "Illegal synchronize_sched() in RCU-sched read-side critical section"); if (rcu_blocking_is_gp()) return; - wait_rcu_gp(call_rcu_sched); + if (rcu_expedited) + synchronize_sched_expedited(); + else + wait_rcu_gp(call_rcu_sched); } EXPORT_SYMBOL_GPL(synchronize_sched); @@ -2245,7 +2248,10 @@ void synchronize_rcu_bh(void) "Illegal synchronize_rcu_bh() in RCU-bh read-side critical section"); if (rcu_blocking_is_gp()) return; - wait_rcu_gp(call_rcu_bh); + if (rcu_expedited) + synchronize_rcu_bh_expedited(); + else + wait_rcu_gp(call_rcu_bh); } EXPORT_SYMBOL_GPL(synchronize_rcu_bh); @@ -2328,7 +2334,7 @@ void synchronize_sched_expedited(void) if (trycount++ < 10) { udelay(trycount * num_online_cpus()); } else { - synchronize_sched(); + wait_rcu_gp(call_rcu_sched); return; } diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index f9211548818..c177ba0cce9 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h @@ -679,7 +679,10 @@ void synchronize_rcu(void) "Illegal synchronize_rcu() in RCU read-side critical section"); if (!rcu_scheduler_active) return; - wait_rcu_gp(call_rcu); + if (rcu_expedited) + synchronize_rcu_expedited(); + else + wait_rcu_gp(call_rcu); } EXPORT_SYMBOL_GPL(synchronize_rcu); @@ -831,7 +834,7 @@ void synchronize_rcu_expedited(void) udelay(trycount * num_online_cpus()); } else { put_online_cpus(); - synchronize_rcu(); + wait_rcu_gp(call_rcu); return; } } diff --git a/kernel/srcu.c b/kernel/srcu.c index 97c465ebd84..de9074047c9 100644 --- a/kernel/srcu.c +++ b/kernel/srcu.c @@ -34,6 +34,10 @@ #include #include +#include + +#include "rcu.h" + /* * Initialize an rcu_batch structure to empty. */ @@ -464,7 +468,9 @@ static void __synchronize_srcu(struct srcu_struct *sp, int trycount) */ void synchronize_srcu(struct srcu_struct *sp) { - __synchronize_srcu(sp, SYNCHRONIZE_SRCU_TRYCOUNT); + __synchronize_srcu(sp, rcu_expedited + ? SYNCHRONIZE_SRCU_EXP_TRYCOUNT + : SYNCHRONIZE_SRCU_TRYCOUNT); } EXPORT_SYMBOL_GPL(synchronize_srcu); -- cgit v1.2.3 From 340f588bbaed6cb518aa65e7a330dcc3fff911f8 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 15 Oct 2012 08:24:54 -0700 Subject: rcu: Fix precedence error in cpu_needs_another_gp() The fix introduced by a10d206e (rcu: Fix day-one dyntick-idle stall-warning bug) has a C-language precedence error. It turns out that this error is harmless in that the same result is computed for all inputs, but the code is nevertheless a potential source of confusion. This commit therefore introduces parentheses in order to force the execution of the code to reflect the intent. Reported-by: Ben Hutchings Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rcutree.c b/kernel/rcutree.c index f9c17c39953..effd47a54b3 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -313,7 +313,7 @@ static int cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp) { return *rdp->nxttail[RCU_DONE_TAIL + - ACCESS_ONCE(rsp->completed) != rdp->completed] && + (ACCESS_ONCE(rsp->completed) != rdp->completed)] && !rcu_gp_in_progress(rsp); } -- cgit v1.2.3 From 4e87b2d7e887df3fe251dd7f702591a3acf369ca Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Sat, 13 Oct 2012 01:14:14 +0800 Subject: srcu: Credit Lai Jiangshan with SRCU rewrite Lai Jiangshan rewrote SRCU, so this commit ensures that he gets his proper share of blame^Wcredit. Signed-off-by: Lai Jiangshan Signed-off-by: Paul E. McKenney --- include/linux/srcu.h | 2 ++ kernel/srcu.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/linux/srcu.h b/include/linux/srcu.h index 55a5c52cbb2..a55ddb19053 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h @@ -16,8 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Copyright (C) IBM Corporation, 2006 + * Copyright (C) Fujitsu, 2012 * * Author: Paul McKenney + * Lai Jiangshan * * For detailed explanation of Read-Copy Update mechanism see - * Documentation/RCU/ *.txt diff --git a/kernel/srcu.c b/kernel/srcu.c index 97c465ebd84..0b99f27fa2f 100644 --- a/kernel/srcu.c +++ b/kernel/srcu.c @@ -16,8 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Copyright (C) IBM Corporation, 2006 + * Copyright (C) Fujitsu, 2012 * * Author: Paul McKenney + * Lai Jiangshan * * For detailed explanation of Read-Copy Update mechanism see - * Documentation/RCU/ *.txt -- cgit v1.2.3 From f2ebfbc991044fd5b89d4529741d7500feb37fbd Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Sat, 13 Oct 2012 01:14:15 +0800 Subject: srcu: Export process_srcu() Because process_srcu() will be used in DEFINE_SRCU(), which is a macro that could be expanded pretty much anywhere, it can no longer be static. Note that process_srcu() is still internal to srcu.h. Signed-off-by: Lai Jiangshan Signed-off-by: Paul E. McKenney --- include/linux/srcu.h | 2 ++ kernel/srcu.c | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/srcu.h b/include/linux/srcu.h index a55ddb19053..5cce128f196 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h @@ -78,6 +78,8 @@ int init_srcu_struct(struct srcu_struct *sp); #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ +void process_srcu(struct work_struct *work); + /** * call_srcu() - Queue a callback for invocation after an SRCU grace period * @sp: srcu_struct in queue the callback diff --git a/kernel/srcu.c b/kernel/srcu.c index 0b99f27fa2f..b363b092456 100644 --- a/kernel/srcu.c +++ b/kernel/srcu.c @@ -94,9 +94,6 @@ static inline void rcu_batch_move(struct rcu_batch *to, struct rcu_batch *from) } } -/* single-thread state-machine */ -static void process_srcu(struct work_struct *work); - static int init_srcu_struct_fields(struct srcu_struct *sp) { sp->completed = 0; @@ -639,7 +636,7 @@ static void srcu_reschedule(struct srcu_struct *sp) /* * This is the work-queue function that handles SRCU grace periods. */ -static void process_srcu(struct work_struct *work) +void process_srcu(struct work_struct *work) { struct srcu_struct *sp; @@ -650,3 +647,4 @@ static void process_srcu(struct work_struct *work) srcu_invoke_callbacks(sp); srcu_reschedule(sp); } +EXPORT_SYMBOL_GPL(process_srcu); -- cgit v1.2.3 From b637a328bd4f43a0e146d1eef0142b650ba0d644 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 19 Sep 2012 16:58:38 -0700 Subject: rcu: Print remote CPU's stacks in stall warnings The RCU CPU stall warnings rely on trigger_all_cpu_backtrace() to do NMI-based dump of the stack traces of all CPUs. Unfortunately, a number of architectures do not implement trigger_all_cpu_backtrace(), in which case RCU falls back to just dumping the stack of the running CPU. This is unhelpful in the case where the running CPU has detected that some other CPU has stalled. This commit therefore makes the running CPU dump the stacks of the tasks running on the stalled CPUs. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- include/linux/sched.h | 2 ++ kernel/rcutree.c | 25 ++++++++++++++++++++++++- kernel/sched/core.c | 6 ++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 0dd42a02df2..ba69b5adea3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -109,6 +109,8 @@ extern void update_cpu_load_nohz(void); extern unsigned long get_parent_ip(unsigned long addr); +extern void dump_cpu_task(int cpu); + struct seq_file; struct cfs_rq; struct task_group; diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 74df86bd920..e78538712df 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -873,6 +873,29 @@ static void record_gp_stall_check_time(struct rcu_state *rsp) rsp->jiffies_stall = jiffies + jiffies_till_stall_check(); } +/* + * Dump stacks of all tasks running on stalled CPUs. This is a fallback + * for architectures that do not implement trigger_all_cpu_backtrace(). + * The NMI-triggered stack traces are more accurate because they are + * printed by the target CPU. + */ +static void rcu_dump_cpu_stacks(struct rcu_state *rsp) +{ + int cpu; + unsigned long flags; + struct rcu_node *rnp; + + rcu_for_each_leaf_node(rsp, rnp) { + raw_spin_lock_irqsave(&rnp->lock, flags); + if (rnp->qsmask != 0) { + for (cpu = 0; cpu <= rnp->grphi - rnp->grplo; cpu++) + if (rnp->qsmask & (1UL << cpu)) + dump_cpu_task(rnp->grplo + cpu); + } + raw_spin_unlock_irqrestore(&rnp->lock, flags); + } +} + static void print_other_cpu_stall(struct rcu_state *rsp) { int cpu; @@ -929,7 +952,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp) if (ndetected == 0) printk(KERN_ERR "INFO: Stall ended before state dump start\n"); else if (!trigger_all_cpu_backtrace()) - dump_stack(); + rcu_dump_cpu_stacks(rsp); /* Complain about tasks blocking the grace period. */ diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 2d8927fda71..59d08fb1a9e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -8076,3 +8076,9 @@ struct cgroup_subsys cpuacct_subsys = { .base_cftypes = files, }; #endif /* CONFIG_CGROUP_CPUACCT */ + +void dump_cpu_task(int cpu) +{ + pr_info("Task dump for CPU %d:\n", cpu); + sched_show_task(cpu_curr(cpu)); +} -- cgit v1.2.3 From eee058826100e5a344f11601e0c47baeaf07c77b Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 21 Sep 2012 14:15:05 -0700 Subject: rcu: Add grace-period information to RCU CPU stall warnings This commit causes the last grace period started and completed to be printed on RCU CPU stall warning messages in order to aid diagnosis. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutree.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kernel/rcutree.c b/kernel/rcutree.c index e78538712df..8f4de3a7c1f 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -947,8 +947,9 @@ static void print_other_cpu_stall(struct rcu_state *rsp) raw_spin_unlock_irqrestore(&rnp->lock, flags); print_cpu_stall_info_end(); - printk(KERN_CONT "(detected by %d, t=%ld jiffies)\n", - smp_processor_id(), (long)(jiffies - rsp->gp_start)); + pr_cont("(detected by %d, t=%ld jiffies, g=%lu, c=%lu)\n", + smp_processor_id(), (long)(jiffies - rsp->gp_start), + rsp->gpnum, rsp->completed); if (ndetected == 0) printk(KERN_ERR "INFO: Stall ended before state dump start\n"); else if (!trigger_all_cpu_backtrace()) @@ -975,7 +976,8 @@ static void print_cpu_stall(struct rcu_state *rsp) print_cpu_stall_info_begin(); print_cpu_stall_info(rsp, smp_processor_id()); print_cpu_stall_info_end(); - printk(KERN_CONT " (t=%lu jiffies)\n", jiffies - rsp->gp_start); + pr_cont(" (t=%lu jiffies g=%lu c=%lu)\n", + jiffies - rsp->gp_start, rsp->gpnum, rsp->completed); if (!trigger_all_cpu_backtrace()) dump_stack(); -- cgit v1.2.3 From 53bb857c373d6b7936f8a7b4451f0a99703c308e Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 21 Sep 2012 16:35:25 -0700 Subject: rcu: Dump number of callbacks in stall warning messages In theory, if a grace period manages to get started despite there being no callbacks on any of the CPUs, all CPUs could go into dyntick-idle mode, so that the grace period would never end. This commit updates the RCU CPU stall warning messages to detect this condition by summing up the number of callbacks on all CPUs. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutree.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 8f4de3a7c1f..24b21cba2cc 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -903,6 +903,7 @@ static void print_other_cpu_stall(struct rcu_state *rsp) unsigned long flags; int ndetected = 0; struct rcu_node *rnp = rcu_get_root(rsp); + long totqlen = 0; /* Only let one CPU complain about others per time interval. */ @@ -947,9 +948,11 @@ static void print_other_cpu_stall(struct rcu_state *rsp) raw_spin_unlock_irqrestore(&rnp->lock, flags); print_cpu_stall_info_end(); - pr_cont("(detected by %d, t=%ld jiffies, g=%lu, c=%lu)\n", + for_each_possible_cpu(cpu) + totqlen += per_cpu_ptr(rsp->rda, cpu)->qlen; + pr_cont("(detected by %d, t=%ld jiffies, g=%lu, c=%lu, q=%lu)\n", smp_processor_id(), (long)(jiffies - rsp->gp_start), - rsp->gpnum, rsp->completed); + rsp->gpnum, rsp->completed, totqlen); if (ndetected == 0) printk(KERN_ERR "INFO: Stall ended before state dump start\n"); else if (!trigger_all_cpu_backtrace()) @@ -964,8 +967,10 @@ static void print_other_cpu_stall(struct rcu_state *rsp) static void print_cpu_stall(struct rcu_state *rsp) { + int cpu; unsigned long flags; struct rcu_node *rnp = rcu_get_root(rsp); + long totqlen = 0; /* * OK, time to rat on ourselves... @@ -976,8 +981,10 @@ static void print_cpu_stall(struct rcu_state *rsp) print_cpu_stall_info_begin(); print_cpu_stall_info(rsp, smp_processor_id()); print_cpu_stall_info_end(); - pr_cont(" (t=%lu jiffies g=%lu c=%lu)\n", - jiffies - rsp->gp_start, rsp->gpnum, rsp->completed); + for_each_possible_cpu(cpu) + totqlen += per_cpu_ptr(rsp->rda, cpu)->qlen; + pr_cont(" (t=%lu jiffies g=%lu c=%lu q=%lu)\n", + jiffies - rsp->gp_start, rsp->gpnum, rsp->completed, totqlen); if (!trigger_all_cpu_backtrace()) dump_stack(); -- cgit v1.2.3 From e39473d0b9448e770f49b0b15e514be884264438 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 24 Oct 2012 02:08:18 +0200 Subject: PM / QoS: Make it possible to expose PM QoS device flags to user space Define two device PM QoS flags, PM_QOS_FLAG_NO_POWER_OFF and PM_QOS_FLAG_REMOTE_WAKEUP, and introduce routines dev_pm_qos_expose_flags() and dev_pm_qos_hide_flags() allowing the caller to expose those two flags to user space or to hide them from it, respectively. After the flags have been exposed, user space will see two additional sysfs attributes, pm_qos_no_power_off and pm_qos_remote_wakeup, under the device's /sys/devices/.../power/ directory. Then, writing 1 to one of them will update the PM QoS flags request owned by user space so that the corresponding flag is requested to be set. In turn, writing 0 to one of them will cause the corresponding flag in the user space's request to be cleared (however, the owners of the other PM QoS flags requests for the same device may still request the flag to be set and it may be effectively set even if user space doesn't request that). Signed-off-by: Rafael J. Wysocki Reviewed-by: Jean Pihet Acked-by: mark gross --- Documentation/ABI/testing/sysfs-devices-power | 31 +++++ drivers/base/power/power.h | 6 +- drivers/base/power/qos.c | 168 ++++++++++++++++++++------ drivers/base/power/sysfs.c | 94 ++++++++++++-- include/linux/pm.h | 1 - include/linux/pm_qos.h | 26 ++++ 6 files changed, 278 insertions(+), 48 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-devices-power b/Documentation/ABI/testing/sysfs-devices-power index 45000f0db4d..7fc2997b23a 100644 --- a/Documentation/ABI/testing/sysfs-devices-power +++ b/Documentation/ABI/testing/sysfs-devices-power @@ -204,3 +204,34 @@ Description: This attribute has no effect on system-wide suspend/resume and hibernation. + +What: /sys/devices/.../power/pm_qos_no_power_off +Date: September 2012 +Contact: Rafael J. Wysocki +Description: + The /sys/devices/.../power/pm_qos_no_power_off attribute + is used for manipulating the PM QoS "no power off" flag. If + set, this flag indicates to the kernel that power should not + be removed entirely from the device. + + Not all drivers support this attribute. If it isn't supported, + it is not present. + + This attribute has no effect on system-wide suspend/resume and + hibernation. + +What: /sys/devices/.../power/pm_qos_remote_wakeup +Date: September 2012 +Contact: Rafael J. Wysocki +Description: + The /sys/devices/.../power/pm_qos_remote_wakeup attribute + is used for manipulating the PM QoS "remote wakeup required" + flag. If set, this flag indicates to the kernel that the + device is a source of user events that have to be signaled from + its low-power states. + + Not all drivers support this attribute. If it isn't supported, + it is not present. + + This attribute has no effect on system-wide suspend/resume and + hibernation. diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 0dbfdf4419a..b16686a0a5a 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -93,8 +93,10 @@ extern void dpm_sysfs_remove(struct device *dev); extern void rpm_sysfs_remove(struct device *dev); extern int wakeup_sysfs_add(struct device *dev); extern void wakeup_sysfs_remove(struct device *dev); -extern int pm_qos_sysfs_add(struct device *dev); -extern void pm_qos_sysfs_remove(struct device *dev); +extern int pm_qos_sysfs_add_latency(struct device *dev); +extern void pm_qos_sysfs_remove_latency(struct device *dev); +extern int pm_qos_sysfs_add_flags(struct device *dev); +extern void pm_qos_sysfs_remove_flags(struct device *dev); #else /* CONFIG_PM */ diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 3c66f75d14b..167834dcc82 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "power.h" @@ -321,6 +322,37 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, } EXPORT_SYMBOL_GPL(dev_pm_qos_add_request); +/** + * __dev_pm_qos_update_request - Modify an existing device PM QoS request. + * @req : PM QoS request to modify. + * @new_value: New value to request. + */ +static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req, + s32 new_value) +{ + s32 curr_value; + int ret = 0; + + if (!req->dev->power.qos) + return -ENODEV; + + switch(req->type) { + case DEV_PM_QOS_LATENCY: + curr_value = req->data.pnode.prio; + break; + case DEV_PM_QOS_FLAGS: + curr_value = req->data.flr.flags; + break; + default: + return -EINVAL; + } + + if (curr_value != new_value) + ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value); + + return ret; +} + /** * dev_pm_qos_update_request - modifies an existing qos request * @req : handle to list element holding a dev_pm_qos request to use @@ -336,11 +368,9 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_add_request); * -EINVAL in case of wrong parameters, -ENODEV if the device has been * removed from the system */ -int dev_pm_qos_update_request(struct dev_pm_qos_request *req, - s32 new_value) +int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value) { - s32 curr_value; - int ret = 0; + int ret; if (!req) /*guard against callers passing in null */ return -EINVAL; @@ -350,29 +380,9 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, return -EINVAL; mutex_lock(&dev_pm_qos_mtx); - - if (!req->dev->power.qos) { - ret = -ENODEV; - goto out; - } - - switch(req->type) { - case DEV_PM_QOS_LATENCY: - curr_value = req->data.pnode.prio; - break; - case DEV_PM_QOS_FLAGS: - curr_value = req->data.flr.flags; - break; - default: - ret = -EINVAL; - goto out; - } - - if (curr_value != new_value) - ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value); - - out: + __dev_pm_qos_update_request(req, new_value); mutex_unlock(&dev_pm_qos_mtx); + return ret; } EXPORT_SYMBOL_GPL(dev_pm_qos_update_request); @@ -533,10 +543,19 @@ int dev_pm_qos_add_ancestor_request(struct device *dev, EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request); #ifdef CONFIG_PM_RUNTIME -static void __dev_pm_qos_drop_user_request(struct device *dev) +static void __dev_pm_qos_drop_user_request(struct device *dev, + enum dev_pm_qos_req_type type) { - dev_pm_qos_remove_request(dev->power.pq_req); - dev->power.pq_req = NULL; + switch(type) { + case DEV_PM_QOS_LATENCY: + dev_pm_qos_remove_request(dev->power.qos->latency_req); + dev->power.qos->latency_req = NULL; + break; + case DEV_PM_QOS_FLAGS: + dev_pm_qos_remove_request(dev->power.qos->flags_req); + dev->power.qos->flags_req = NULL; + break; + } } /** @@ -552,7 +571,7 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) if (!device_is_registered(dev) || value < 0) return -EINVAL; - if (dev->power.pq_req) + if (dev->power.qos && dev->power.qos->latency_req) return -EEXIST; req = kzalloc(sizeof(*req), GFP_KERNEL); @@ -563,10 +582,10 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) if (ret < 0) return ret; - dev->power.pq_req = req; - ret = pm_qos_sysfs_add(dev); + dev->power.qos->latency_req = req; + ret = pm_qos_sysfs_add_latency(dev); if (ret) - __dev_pm_qos_drop_user_request(dev); + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); return ret; } @@ -578,10 +597,87 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit); */ void dev_pm_qos_hide_latency_limit(struct device *dev) { - if (dev->power.pq_req) { - pm_qos_sysfs_remove(dev); - __dev_pm_qos_drop_user_request(dev); + if (dev->power.qos && dev->power.qos->latency_req) { + pm_qos_sysfs_remove_latency(dev); + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); } } EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit); + +/** + * dev_pm_qos_expose_flags - Expose PM QoS flags of a device to user space. + * @dev: Device whose PM QoS flags are to be exposed to user space. + * @val: Initial values of the flags. + */ +int dev_pm_qos_expose_flags(struct device *dev, s32 val) +{ + struct dev_pm_qos_request *req; + int ret; + + if (!device_is_registered(dev)) + return -EINVAL; + + if (dev->power.qos && dev->power.qos->flags_req) + return -EEXIST; + + req = kzalloc(sizeof(*req), GFP_KERNEL); + if (!req) + return -ENOMEM; + + ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_FLAGS, val); + if (ret < 0) + return ret; + + dev->power.qos->flags_req = req; + ret = pm_qos_sysfs_add_flags(dev); + if (ret) + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); + + return ret; +} +EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags); + +/** + * dev_pm_qos_hide_flags - Hide PM QoS flags of a device from user space. + * @dev: Device whose PM QoS flags are to be hidden from user space. + */ +void dev_pm_qos_hide_flags(struct device *dev) +{ + if (dev->power.qos && dev->power.qos->flags_req) { + pm_qos_sysfs_remove_flags(dev); + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); + } +} +EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags); + +/** + * dev_pm_qos_update_flags - Update PM QoS flags request owned by user space. + * @dev: Device to update the PM QoS flags request for. + * @mask: Flags to set/clear. + * @set: Whether to set or clear the flags (true means set). + */ +int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set) +{ + s32 value; + int ret; + + if (!dev->power.qos || !dev->power.qos->flags_req) + return -EINVAL; + + pm_runtime_get_sync(dev); + mutex_lock(&dev_pm_qos_mtx); + + value = dev_pm_qos_requested_flags(dev); + if (set) + value |= mask; + else + value &= ~mask; + + ret = __dev_pm_qos_update_request(dev->power.qos->flags_req, value); + + mutex_unlock(&dev_pm_qos_mtx); + pm_runtime_put(dev); + + return ret; +} #endif /* CONFIG_PM_RUNTIME */ diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 54c61ffa204..50d16e3cb0a 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -221,7 +221,7 @@ static DEVICE_ATTR(autosuspend_delay_ms, 0644, autosuspend_delay_ms_show, static ssize_t pm_qos_latency_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", dev->power.pq_req->data.pnode.prio); + return sprintf(buf, "%d\n", dev_pm_qos_requested_latency(dev)); } static ssize_t pm_qos_latency_store(struct device *dev, @@ -237,12 +237,66 @@ static ssize_t pm_qos_latency_store(struct device *dev, if (value < 0) return -EINVAL; - ret = dev_pm_qos_update_request(dev->power.pq_req, value); + ret = dev_pm_qos_update_request(dev->power.qos->latency_req, value); return ret < 0 ? ret : n; } static DEVICE_ATTR(pm_qos_resume_latency_us, 0644, pm_qos_latency_show, pm_qos_latency_store); + +static ssize_t pm_qos_no_power_off_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", !!(dev_pm_qos_requested_flags(dev) + & PM_QOS_FLAG_NO_POWER_OFF)); +} + +static ssize_t pm_qos_no_power_off_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t n) +{ + int ret; + + if (kstrtoint(buf, 0, &ret)) + return -EINVAL; + + if (ret != 0 && ret != 1) + return -EINVAL; + + ret = dev_pm_qos_update_flags(dev, PM_QOS_FLAG_NO_POWER_OFF, ret); + return ret < 0 ? ret : n; +} + +static DEVICE_ATTR(pm_qos_no_power_off, 0644, + pm_qos_no_power_off_show, pm_qos_no_power_off_store); + +static ssize_t pm_qos_remote_wakeup_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", !!(dev_pm_qos_requested_flags(dev) + & PM_QOS_FLAG_REMOTE_WAKEUP)); +} + +static ssize_t pm_qos_remote_wakeup_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t n) +{ + int ret; + + if (kstrtoint(buf, 0, &ret)) + return -EINVAL; + + if (ret != 0 && ret != 1) + return -EINVAL; + + ret = dev_pm_qos_update_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP, ret); + return ret < 0 ? ret : n; +} + +static DEVICE_ATTR(pm_qos_remote_wakeup, 0644, + pm_qos_remote_wakeup_show, pm_qos_remote_wakeup_store); #endif /* CONFIG_PM_RUNTIME */ #ifdef CONFIG_PM_SLEEP @@ -564,15 +618,27 @@ static struct attribute_group pm_runtime_attr_group = { .attrs = runtime_attrs, }; -static struct attribute *pm_qos_attrs[] = { +static struct attribute *pm_qos_latency_attrs[] = { #ifdef CONFIG_PM_RUNTIME &dev_attr_pm_qos_resume_latency_us.attr, #endif /* CONFIG_PM_RUNTIME */ NULL, }; -static struct attribute_group pm_qos_attr_group = { +static struct attribute_group pm_qos_latency_attr_group = { .name = power_group_name, - .attrs = pm_qos_attrs, + .attrs = pm_qos_latency_attrs, +}; + +static struct attribute *pm_qos_flags_attrs[] = { +#ifdef CONFIG_PM_RUNTIME + &dev_attr_pm_qos_no_power_off.attr, + &dev_attr_pm_qos_remote_wakeup.attr, +#endif /* CONFIG_PM_RUNTIME */ + NULL, +}; +static struct attribute_group pm_qos_flags_attr_group = { + .name = power_group_name, + .attrs = pm_qos_flags_attrs, }; int dpm_sysfs_add(struct device *dev) @@ -615,14 +681,24 @@ void wakeup_sysfs_remove(struct device *dev) sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group); } -int pm_qos_sysfs_add(struct device *dev) +int pm_qos_sysfs_add_latency(struct device *dev) +{ + return sysfs_merge_group(&dev->kobj, &pm_qos_latency_attr_group); +} + +void pm_qos_sysfs_remove_latency(struct device *dev) +{ + sysfs_unmerge_group(&dev->kobj, &pm_qos_latency_attr_group); +} + +int pm_qos_sysfs_add_flags(struct device *dev) { - return sysfs_merge_group(&dev->kobj, &pm_qos_attr_group); + return sysfs_merge_group(&dev->kobj, &pm_qos_flags_attr_group); } -void pm_qos_sysfs_remove(struct device *dev) +void pm_qos_sysfs_remove_flags(struct device *dev) { - sysfs_unmerge_group(&dev->kobj, &pm_qos_attr_group); + sysfs_unmerge_group(&dev->kobj, &pm_qos_flags_attr_group); } void rpm_sysfs_remove(struct device *dev) diff --git a/include/linux/pm.h b/include/linux/pm.h index 0ce6df94221..03d7bb14531 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -546,7 +546,6 @@ struct dev_pm_info { unsigned long active_jiffies; unsigned long suspended_jiffies; unsigned long accounting_timestamp; - struct dev_pm_qos_request *pq_req; #endif struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */ struct dev_pm_qos *qos; diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 3af7d8573c2..5a95013905c 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -34,6 +34,9 @@ enum pm_qos_flags_status { #define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 #define PM_QOS_DEV_LAT_DEFAULT_VALUE 0 +#define PM_QOS_FLAG_NO_POWER_OFF (1 << 0) +#define PM_QOS_FLAG_REMOTE_WAKEUP (1 << 1) + struct pm_qos_request { struct plist_node node; int pm_qos_class; @@ -86,6 +89,8 @@ struct pm_qos_flags { struct dev_pm_qos { struct pm_qos_constraints latency; struct pm_qos_flags flags; + struct dev_pm_qos_request *latency_req; + struct dev_pm_qos_request *flags_req; }; /* Action requested to pm_qos_update_target */ @@ -187,10 +192,31 @@ static inline int dev_pm_qos_add_ancestor_request(struct device *dev, #ifdef CONFIG_PM_RUNTIME int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value); void dev_pm_qos_hide_latency_limit(struct device *dev); +int dev_pm_qos_expose_flags(struct device *dev, s32 value); +void dev_pm_qos_hide_flags(struct device *dev); +int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set); + +static inline s32 dev_pm_qos_requested_latency(struct device *dev) +{ + return dev->power.qos->latency_req->data.pnode.prio; +} + +static inline s32 dev_pm_qos_requested_flags(struct device *dev) +{ + return dev->power.qos->flags_req->data.flr.flags; +} #else static inline int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) { return 0; } static inline void dev_pm_qos_hide_latency_limit(struct device *dev) {} +static inline int dev_pm_qos_expose_flags(struct device *dev, s32 value) + { return 0; } +static inline void dev_pm_qos_hide_flags(struct device *dev) {} +static inline int dev_pm_qos_update_flags(struct device *dev, s32 m, bool set) + { return 0; } + +static inline s32 dev_pm_qos_requested_latency(struct device *dev) { return 0; } +static inline s32 dev_pm_qos_requested_flags(struct device *dev) { return 0; } #endif #endif -- cgit v1.2.3 From 34b1f76275a2cb8c1ce8e00095d200552b235122 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 24 Oct 2012 02:08:30 +0200 Subject: PM / Domains: Check device PM QoS flags in pm_genpd_poweroff() Make the generic PM domains pm_genpd_poweroff() function take device PM QoS flags into account when deciding whether or not to remove power from the domain. After this change the routine will return -EBUSY without executing the domain's .power_off() callback if there is at least one PM QoS flags request for at least one device in the domain and at least of those request has at least one of the NO_POWER_OFF and REMOTE_WAKEUP flags set. Signed-off-by: Rafael J. Wysocki Reviewed-by: Jean Pihet Reviewed-by: mark gross --- drivers/base/power/domain.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index c22b869245d..e2cf392d99d 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -470,10 +470,19 @@ static int pm_genpd_poweroff(struct generic_pm_domain *genpd) return -EBUSY; not_suspended = 0; - list_for_each_entry(pdd, &genpd->dev_list, list_node) + list_for_each_entry(pdd, &genpd->dev_list, list_node) { + enum pm_qos_flags_status stat; + + stat = dev_pm_qos_flags(pdd->dev, + PM_QOS_FLAG_NO_POWER_OFF + | PM_QOS_FLAG_REMOTE_WAKEUP); + if (stat > PM_QOS_FLAGS_NONE) + return -EBUSY; + if (pdd->dev->driver && (!pm_runtime_suspended(pdd->dev) || pdd->dev->power.irq_safe)) not_suspended++; + } if (not_suspended > genpd->in_progress) return -EBUSY; -- cgit v1.2.3 From 8b713a88cc8b746f975958183fa641e9f1c8086d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 24 Oct 2012 02:08:38 +0200 Subject: PM / ACPI: Take device PM QoS flags into account Make ACPI power management routines and PCI power management routines depending on ACPI take device PM QoS flags into account when deciding what power state to put the device into. In particular, after this change acpi_pm_device_sleep_state() will not return ACPI_STATE_D3_COLD as the deepest available low-power state if PM_QOS_FLAG_NO_POWER_OFF is requested for the device and it will not require remote wakeup to work for the device in the returned low-power state if there is at least one PM QoS flags request for the device, but PM_QOS_FLAG_REMOTE_WAKEUP is not requested for it. Accordingly, acpi_pci_set_power_state() will refuse to put the device into D3cold if PM_QOS_FLAG_NO_POWER_OFF is requested for it. Signed-off-by: Rafael J. Wysocki Reviewed-by: Jean Pihet Reviewed-by: Huang Ying --- drivers/acpi/sleep.c | 21 +++++++++++++++++---- drivers/pci/pci-acpi.c | 8 +++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index fdcdbb65291..69134653909 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -711,6 +712,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) struct acpi_device *adev; char acpi_method[] = "_SxD"; unsigned long long d_min, d_max; + bool wakeup = false; if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3) return -EINVAL; @@ -718,6 +720,13 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) printk(KERN_DEBUG "ACPI handle has no context!\n"); return -ENODEV; } + if (d_max_in > ACPI_STATE_D3_HOT) { + enum pm_qos_flags_status stat; + + stat = dev_pm_qos_flags(dev, PM_QOS_FLAG_NO_POWER_OFF); + if (stat == PM_QOS_FLAGS_ALL) + d_max_in = ACPI_STATE_D3_HOT; + } acpi_method[2] = '0' + acpi_target_sleep_state; /* @@ -737,8 +746,14 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer * provided -- that's our fault recovery, we ignore retval. */ - if (acpi_target_sleep_state > ACPI_STATE_S0) + if (acpi_target_sleep_state > ACPI_STATE_S0) { acpi_evaluate_integer(handle, acpi_method, NULL, &d_min); + wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid + && adev->wakeup.sleep_state >= acpi_target_sleep_state; + } else if (dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) != + PM_QOS_FLAGS_NONE) { + wakeup = adev->wakeup.flags.valid; + } /* * If _PRW says we can wake up the system from the target sleep state, @@ -747,9 +762,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) * (ACPI 3.x), it should return the maximum (lowest power) D-state that * can wake the system. _S0W may be valid, too. */ - if (acpi_target_sleep_state == ACPI_STATE_S0 || - (device_may_wakeup(dev) && adev->wakeup.flags.valid && - adev->wakeup.sleep_state >= acpi_target_sleep_state)) { + if (wakeup) { acpi_status status; acpi_method[3] = 'W'; diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index c5792d622dc..63d6618a480 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -17,6 +17,7 @@ #include #include +#include #include "pci.h" static DEFINE_MUTEX(pci_acpi_pm_notify_mtx); @@ -257,11 +258,16 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) return -ENODEV; switch (state) { + case PCI_D3cold: + if (dev_pm_qos_flags(&dev->dev, PM_QOS_FLAG_NO_POWER_OFF) == + PM_QOS_FLAGS_ALL) { + error = -EBUSY; + break; + } case PCI_D0: case PCI_D1: case PCI_D2: case PCI_D3hot: - case PCI_D3cold: error = acpi_bus_set_power(handle, state_conv[state]); } -- cgit v1.2.3 From 983e4b3566d73e8532b172a12608b2bebc68e5c4 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Tue, 23 Oct 2012 23:34:15 +0100 Subject: staging: et131x: Fix i386 build warnings from use of dma_addr_t MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dma_addr_t can be of size 64 or 32bits, depending on the architecture. This fixes these build warnings for ARCH=i386, and also tested on x86_64: drivers/staging/et131x/et131x.c: In function ‘et131x_rx_dma_memory_alloc’: drivers/staging/et131x/et131x.c:2356:11: warning: passing argument 2 of ‘et131x_align_allocated_memory’ from incompatible pointer type [enabled by default] drivers/staging/et131x/et131x.c:2260:13: note: expected ‘u64 *’ but argument is of type ‘dma_addr_t *’ drivers/staging/et131x/et131x.c:2378:11: warning: passing argument 2 of ‘et131x_align_allocated_memory’ from incompatible pointer type [enabled by default] drivers/staging/et131x/et131x.c:2260:13: note: expected ‘u64 *’ but argument is of type ‘dma_addr_t *’ drivers/staging/et131x/et131x.c: In function ‘free_send_packet’: drivers/staging/et131x/et131x.c:3540:5: warning: left shift count >= width of type [enabled by default] Reported-by: Fengguang Wu Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index c33cafd5c11..70fe33b5781 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -292,10 +292,10 @@ struct fbr_lookup { dma_addr_t ring_physaddr; void *mem_virtaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; dma_addr_t mem_physaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; - u64 offset; + dma_addr_t offset; u32 local_full; u32 num_entries; - u32 buffsize; + dma_addr_t buffsize; }; /* @@ -2258,7 +2258,7 @@ static inline u32 bump_free_buff_ring(u32 *free_buff_ring, u32 limit) * @mask: correct mask */ static void et131x_align_allocated_memory(struct et131x_adapter *adapter, - u64 *phys_addr, u64 *offset, + dma_addr_t *phys_addr, dma_addr_t *offset, u64 mask) { u64 new_addr = *phys_addr & ~mask; @@ -2382,8 +2382,8 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) rx_ring->fbr[1]->offset); for (i = 0; i < (rx_ring->fbr[0]->num_entries / FBR_CHUNKS); i++) { - u64 fbr1_tmp_physaddr; - u64 fbr1_offset; + dma_addr_t fbr1_tmp_physaddr; + dma_addr_t fbr1_offset; u32 fbr1_align; /* This code allocates an area of memory big enough for N @@ -2447,8 +2447,8 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) /* Same for FBR0 (if in use) */ for (i = 0; i < (rx_ring->fbr[1]->num_entries / FBR_CHUNKS); i++) { - u64 fbr0_tmp_physaddr; - u64 fbr0_offset; + dma_addr_t fbr0_tmp_physaddr; + dma_addr_t fbr0_offset; fbr_chunksize = ((FBR_CHUNKS + 1) * rx_ring->fbr[1]->buffsize) - 1; @@ -3513,7 +3513,7 @@ static inline void free_send_packet(struct et131x_adapter *adapter, unsigned long flags; struct tx_desc *desc = NULL; struct net_device_stats *stats = &adapter->net_stats; - dma_addr_t dma_addr; + u64 dma_addr; if (tcb->flags & fMP_DEST_BROAD) atomic_inc(&adapter->stats.broadcast_pkts_xmtd); @@ -3535,9 +3535,7 @@ static inline void free_send_packet(struct et131x_adapter *adapter, INDEX10(tcb->index_start)); dma_addr = desc->addr_lo; - - if (sizeof(dma_addr_t) == sizeof(u64)) - dma_addr |= ((dma_addr_t)desc->addr_hi) << 32; + dma_addr |= (u64)desc->addr_hi << 32; dma_unmap_single(&adapter->pdev->dev, dma_addr, -- cgit v1.2.3 From 6b898c07cb1d5bd8344a8044288bb4ae3873da74 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 17 Sep 2012 23:03:31 +0000 Subject: console: use might_sleep in console_lock Instead of BUG_ON(in_interrupt()), since that doesn't check for all the newfangled stuff like preempt. Note that this is valid since the console_sem is essentially used like a real mutex with only two twists: - we allow trylock from hardirq context - across suspend/resume we lock the logical console_lock, but drop the semaphore protecting the locking state. Now that doesn't guarantee that no one is playing tricks in single-thread atomic contexts at suspend/resume/boot time, but - I couldn't find anything suspicious with some grepping, - might_sleep shouldn't die, - and I think the upside of catching more potential issues is worth the risk of getting a might_sleep backtrace that would have been save (and then dealing with that fallout). Cc: Dave Airlie Cc: Thomas Gleixner Cc: Alan Cox Cc: Peter Zijlstra Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- kernel/printk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/printk.c b/kernel/printk.c index ee79f14db35..22e070f3470 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -1914,7 +1914,8 @@ static int __cpuinit console_cpu_notify(struct notifier_block *self, */ void console_lock(void) { - BUG_ON(in_interrupt()); + might_sleep(); + down(&console_sem); if (console_suspended) return; -- cgit v1.2.3 From 89babccccb575e5ca67757c874a62f2c67e1365c Mon Sep 17 00:00:00 2001 From: Ceri James Date: Tue, 23 Oct 2012 13:51:56 +0100 Subject: Staging: bcm: LeakyBucket.c: Checkpatch fixes This fixes the following checkpatch issues: WARNING: line over 80 characters + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n"); ERROR: space required after that ',' (ctx:VxV) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n"); ^ WARNING: line over 80 characters + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n"); ERROR: space required after that ',' (ctx:VxV) + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n"); ^ Signed-off-by: Ceri James Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/LeakyBucket.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c index 6e8a3279698..877cf0b2bee 100644 --- a/drivers/staging/bcm/LeakyBucket.c +++ b/drivers/staging/bcm/LeakyBucket.c @@ -21,10 +21,12 @@ static VOID UpdateTokenCount(register struct bcm_mini_adapter *Adapter) INT i = 0; struct timeval tv; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "=====>\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, + "=====>\n"); if(NULL == Adapter) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Adapter found NULL!\n"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TOKEN_COUNTS, + DBG_LVL_ALL, "Adapter found NULL!\n"); return; } -- cgit v1.2.3 From 05b371964049be1f15dec46caa63f106dd22d20d Mon Sep 17 00:00:00 2001 From: Ceri James Date: Tue, 23 Oct 2012 15:50:33 +0100 Subject: Staging: bcm: InterfaceIdleMode.h: Checkpatch fixes This fixes the following checkpatch issues: WARNING: line over 80 characters +INT InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, unsigned int *puiBuffer); ERROR: "foo * bar" should be "foo *bar" +INT InterfaceWakeUp(struct bcm_mini_adapter * Adapter); Signed-off-by: Ceri James Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceIdleMode.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/InterfaceIdleMode.h b/drivers/staging/bcm/InterfaceIdleMode.h index c3338c8a1dc..2ef64003aa8 100644 --- a/drivers/staging/bcm/InterfaceIdleMode.h +++ b/drivers/staging/bcm/InterfaceIdleMode.h @@ -3,11 +3,12 @@ INT InterfaceIdleModeWakeup(struct bcm_mini_adapter *Adapter); -INT InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, unsigned int *puiBuffer); +INT InterfaceIdleModeRespond(struct bcm_mini_adapter *Adapter, + unsigned int *puiBuffer); VOID InterfaceWriteIdleModeWakePattern(struct bcm_mini_adapter *Adapter); -INT InterfaceWakeUp(struct bcm_mini_adapter * Adapter); +INT InterfaceWakeUp(struct bcm_mini_adapter *Adapter); VOID InterfaceHandleShutdownModeWakeup(struct bcm_mini_adapter *Adapter); #endif -- cgit v1.2.3 From a51d02067efc069aab14b221b625bd82d8e659dd Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 23 Oct 2012 13:03:17 -0700 Subject: drivers/staging/wlags49_h2/man: remove CONFIG_EXPERIMENTAL This config item has not carried much meaning for a while now and is almost always enabled by default. As agreed during the Linux kernel summit, remove it. CC: Henk de Groot CC: Greg Kroah-Hartman Signed-off-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/man/wlags49.4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wlags49_h2/man/wlags49.4 b/drivers/staging/wlags49_h2/man/wlags49.4 index a3458853074..37df9987918 100644 --- a/drivers/staging/wlags49_h2/man/wlags49.4 +++ b/drivers/staging/wlags49_h2/man/wlags49.4 @@ -108,7 +108,7 @@ with the I/O base address and MAC address used by the card. \- Card power management \- Support for Hermes-II & Hermes-II.5 based PCMCIA, Mini PCI, and CardBus cards \- Wired Equivalent Privacy (WEP) - \- WPA-PSK support (EXPERIMENTAL) + \- WPA-PSK support \- Driver utility interface (UIL) \- Wireless Extensions \- Software AP mode -- cgit v1.2.3 From c34fa261b0ac3a862ccd3f71ee55a16b920dfc83 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 23 Oct 2012 13:22:37 -0700 Subject: staging: comedi: remove inline alloc_private() This inline function has a very generic name and it's only a wrapper around a simple kzalloc(). Since the inline function does not save any lines-of-code, instead of renaming it just remove it and do the kzalloc() directly. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 8 -------- drivers/staging/comedi/drivers/8255_pci.c | 8 ++++---- drivers/staging/comedi/drivers/addi-data/addi_common.c | 8 ++++---- drivers/staging/comedi/drivers/adl_pci6208.c | 8 ++++---- drivers/staging/comedi/drivers/adl_pci9111.c | 8 ++++---- drivers/staging/comedi/drivers/adl_pci9118.c | 8 ++++---- drivers/staging/comedi/drivers/adq12b.c | 8 ++++---- drivers/staging/comedi/drivers/adv_pci1710.c | 8 ++++---- drivers/staging/comedi/drivers/adv_pci1723.c | 8 ++++---- drivers/staging/comedi/drivers/adv_pci_dio.c | 8 ++++---- drivers/staging/comedi/drivers/aio_aio12_8.c | 8 ++++---- drivers/staging/comedi/drivers/amplc_dio200.c | 17 ++++++++--------- drivers/staging/comedi/drivers/amplc_pc236.c | 17 ++++++++--------- drivers/staging/comedi/drivers/amplc_pci224.c | 18 ++++++++---------- drivers/staging/comedi/drivers/amplc_pci230.c | 9 ++++----- drivers/staging/comedi/drivers/cb_das16_cs.c | 8 ++++---- drivers/staging/comedi/drivers/cb_pcidas.c | 8 ++++---- drivers/staging/comedi/drivers/cb_pcidas64.c | 8 ++++---- drivers/staging/comedi/drivers/cb_pcidda.c | 8 ++++---- drivers/staging/comedi/drivers/cb_pcimdas.c | 8 ++++---- drivers/staging/comedi/drivers/cb_pcimdda.c | 8 ++++---- drivers/staging/comedi/drivers/comedi_bond.c | 8 ++++---- drivers/staging/comedi/drivers/comedi_parport.c | 8 ++++---- drivers/staging/comedi/drivers/comedi_test.c | 8 ++++---- drivers/staging/comedi/drivers/daqboard2000.c | 8 ++++---- drivers/staging/comedi/drivers/das08.c | 18 ++++++++---------- drivers/staging/comedi/drivers/das08_cs.c | 9 ++++----- drivers/staging/comedi/drivers/das16.c | 8 ++++---- drivers/staging/comedi/drivers/das16m1.c | 8 ++++---- drivers/staging/comedi/drivers/das1800.c | 8 ++++---- drivers/staging/comedi/drivers/das6402.c | 8 ++++---- drivers/staging/comedi/drivers/das800.c | 8 ++++---- drivers/staging/comedi/drivers/dmm32at.c | 8 ++++---- drivers/staging/comedi/drivers/dt2801.c | 8 ++++---- drivers/staging/comedi/drivers/dt2811.c | 8 ++++---- drivers/staging/comedi/drivers/dt2814.c | 8 ++++---- drivers/staging/comedi/drivers/dt2815.c | 8 ++++---- drivers/staging/comedi/drivers/dt282x.c | 8 ++++---- drivers/staging/comedi/drivers/dt3000.c | 8 ++++---- drivers/staging/comedi/drivers/dt9812.c | 8 ++++---- drivers/staging/comedi/drivers/dyna_pci10xx.c | 8 ++++---- drivers/staging/comedi/drivers/fl512.c | 8 ++++---- drivers/staging/comedi/drivers/gsc_hpdi.c | 8 ++++---- drivers/staging/comedi/drivers/icp_multi.c | 8 ++++---- drivers/staging/comedi/drivers/ii_pci20kc.c | 8 ++++---- drivers/staging/comedi/drivers/jr3_pci.c | 8 ++++---- drivers/staging/comedi/drivers/me4000.c | 8 ++++---- drivers/staging/comedi/drivers/me_daq.c | 8 ++++---- drivers/staging/comedi/drivers/mpc624.c | 8 ++++---- drivers/staging/comedi/drivers/multiq3.c | 8 ++++---- drivers/staging/comedi/drivers/ni_6527.c | 8 ++++---- drivers/staging/comedi/drivers/ni_65xx.c | 8 ++++---- drivers/staging/comedi/drivers/ni_660x.c | 9 ++++----- drivers/staging/comedi/drivers/ni_670x.c | 8 ++++---- drivers/staging/comedi/drivers/ni_at_a2150.c | 8 ++++---- drivers/staging/comedi/drivers/ni_at_ao.c | 8 ++++---- drivers/staging/comedi/drivers/ni_atmio16d.c | 8 ++++---- drivers/staging/comedi/drivers/ni_daq_dio24.c | 8 ++++---- drivers/staging/comedi/drivers/ni_labpc.c | 17 ++++++++--------- drivers/staging/comedi/drivers/ni_labpc_cs.c | 9 ++++----- drivers/staging/comedi/drivers/ni_mio_common.c | 9 ++++----- drivers/staging/comedi/drivers/ni_pcidio.c | 8 ++++---- drivers/staging/comedi/drivers/pcl711.c | 8 ++++---- drivers/staging/comedi/drivers/pcl726.c | 8 ++++---- drivers/staging/comedi/drivers/pcl812.c | 8 ++++---- drivers/staging/comedi/drivers/pcl816.c | 8 ++++---- drivers/staging/comedi/drivers/pcl818.c | 8 ++++---- drivers/staging/comedi/drivers/pcm3724.c | 8 ++++---- drivers/staging/comedi/drivers/pcmad.c | 8 ++++---- drivers/staging/comedi/drivers/pcmda12.c | 8 ++++---- drivers/staging/comedi/drivers/pcmmio.c | 8 ++++---- drivers/staging/comedi/drivers/pcmuio.c | 8 ++++---- drivers/staging/comedi/drivers/poc.c | 8 ++++---- drivers/staging/comedi/drivers/rtd520.c | 8 ++++---- drivers/staging/comedi/drivers/rti800.c | 8 ++++---- drivers/staging/comedi/drivers/rti802.c | 8 ++++---- drivers/staging/comedi/drivers/s526.c | 8 ++++---- drivers/staging/comedi/drivers/s626.c | 8 ++++---- drivers/staging/comedi/drivers/serial2002.c | 8 ++++---- drivers/staging/comedi/drivers/skel.c | 8 ++++---- 80 files changed, 336 insertions(+), 356 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 100ea0b0772..78a44fc46ef 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -415,14 +415,6 @@ struct comedi_lrange { /* some silly little inline functions */ -static inline int alloc_private(struct comedi_device *dev, int size) -{ - dev->private = kzalloc(size, GFP_KERNEL); - if (!dev->private) - return -ENOMEM; - return 0; -} - static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd) { if (subd->subdev_flags & SDF_LSAMPL) diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index af76e4e3e40..6a4f2a1ea66 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -235,10 +235,10 @@ static int pci_8255_attach_pci(struct comedi_device *dev, dev->board_ptr = board; dev->board_name = board->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 1d4ecfec447..10ae752f21c 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -1482,10 +1482,10 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned char pci_bus, pci_slot, pci_func; int i_Dma = 0; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; if (!pci_list_builded) { v_pci_card_list_init(this_board->i_VendorId, 1); /* 1 for displaying the list.. */ diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index de3625224c8..343422abcd3 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -191,10 +191,10 @@ static int pci6208_attach_pci(struct comedi_device *dev, dev->board_ptr = boardinfo; dev->board_name = boardinfo->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index a87192ac284..aa55443742c 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -889,10 +889,10 @@ static int pci9111_attach_pci(struct comedi_device *dev, comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*dev_private)); - if (ret) - return ret; - dev_private = dev->private; + dev_private = kzalloc(sizeof(*dev_private), GFP_KERNEL); + if (!dev_private) + return -ENOMEM; + dev->private = dev_private; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 4eca8764685..4bcc5b1171d 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -1923,10 +1923,10 @@ static int pci9118_attach(struct comedi_device *dev, else master = 1; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; pcidev = pci9118_find_pci(dev, it); if (!pcidev) diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c index bdc5ebce877..f7950dfe2dd 100644 --- a/drivers/staging/comedi/drivers/adq12b.c +++ b/drivers/staging/comedi/drivers/adq12b.c @@ -243,10 +243,10 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; devpriv->unipolar = unipolar; devpriv->differential = differential; diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 322d0118dcc..4161cb6be48 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1273,10 +1273,10 @@ static int pci1710_attach_pci(struct comedi_device *dev, dev->board_ptr = this_board; dev->board_name = this_board->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 3c932e7309b..d14ddcb1752 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -244,10 +244,10 @@ static int pci1723_attach_pci(struct comedi_device *dev, comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 8fa61592bbf..47a7584d291 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1108,10 +1108,10 @@ static int pci_dio_attach_pci(struct comedi_device *dev, dev->board_ptr = this_board; dev->board_name = this_board->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index 8acf60d0f20..601f03d5897 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -212,10 +212,10 @@ static int aio_aio12_8_attach(struct comedi_device *dev, } dev->iobase = iobase; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 556c6330432..35cd3cbb3be 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1339,10 +1339,10 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach\n"); - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* Process options and reserve resources according to bus type. */ if (is_isa_board(thisboard)) { @@ -1378,7 +1378,6 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { struct dio200_private *devpriv; - int ret; if (!DO_PCI) return -EINVAL; @@ -1386,10 +1385,10 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, dev_info(dev->class_dev, DIO200_DRIVER_NAME ": attach pci %s\n", pci_name(pci_dev)); - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_ptr = dio200_find_pci_board(pci_dev); if (dev->board_ptr == NULL) { diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 56354aa2708..52541c95ba6 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -510,10 +510,10 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach\n"); - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* Process options according to bus type. */ if (is_isa_board(thisboard)) { @@ -546,7 +546,6 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { struct pc236_private *devpriv; - int ret; if (!DO_PCI) return -EINVAL; @@ -554,10 +553,10 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, dev_info(dev->class_dev, PC236_DRIVER_NAME ": attach pci %s\n", pci_name(pci_dev)); - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_ptr = pc236_find_pci_board(pci_dev); if (dev->board_ptr == NULL) { diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 5d73082adfc..6a9ec11c4f0 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1445,14 +1445,13 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct pci224_private *devpriv; struct pci_dev *pci_dev; - int ret; dev_info(dev->class_dev, DRIVER_NAME ": attach\n"); - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; pci_dev = pci224_find_pci_dev(dev, it); if (!pci_dev) @@ -1465,15 +1464,14 @@ static int __devinit pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { struct pci224_private *devpriv; - int ret; dev_info(dev->class_dev, DRIVER_NAME ": attach_pci %s\n", pci_name(pci_dev)); - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_ptr = pci224_find_pci_board(pci_dev); if (dev->board_ptr == NULL) { diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index cf454b9cb29..2675eefe8b5 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2660,12 +2660,11 @@ static struct pci_dev *pci230_find_pci_dev(struct comedi_device *dev, static int pci230_alloc_private(struct comedi_device *dev) { struct pci230_private *devpriv; - int err; - err = alloc_private(dev, sizeof(*devpriv)); - if (err) - return err; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; spin_lock_init(&devpriv->isr_spinlock); spin_lock_init(&devpriv->res_spinlock); diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 64442b36066..8b091c61cbc 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -452,10 +452,10 @@ static int das16cs_attach(struct comedi_device *dev, return ret; dev->irq = link->irq; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 3); if (ret) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index de21a261ff4..3f4f8bef692 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1486,10 +1486,10 @@ static int cb_pcidas_attach_pci(struct comedi_device *dev, dev->board_ptr = thisboard; dev->board_name = thisboard->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 08546a1091a..a6f5e5e92c8 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1688,10 +1688,10 @@ static int attach(struct comedi_device *dev, struct comedi_devconfig *it) uint32_t local_range, local_decode; int retval; - retval = alloc_private(dev, sizeof(*devpriv)); - if (retval) - return retval; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; pcidev = cb_pcidas64_find_pci_dev(dev, it); if (!pcidev) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index aef946df27e..07a8969c891 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -664,10 +664,10 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, dev->board_ptr = thisboard; dev->board_name = thisboard->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index d1c7220c0b7..9df9a02553c 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -219,10 +219,10 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index ba9f0599be2..651cf18cd60 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -162,10 +162,10 @@ static int cb_pcimdda_attach_pci(struct comedi_device *dev, comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index 5c768bc76eb..31515999bb9 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -304,10 +304,10 @@ static int bonding_attach(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* * Setup our bonding from config params.. sets up our private struct.. diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index a1371c5a7d8..6d3b56a70aa 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -305,10 +305,10 @@ static int parport_attach(struct comedi_device *dev, if (ret) return ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DIO; diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 788a5cc89e2..1be345518b6 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -414,10 +414,10 @@ static int waveform_attach(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* set default amplitude and period */ if (amplitude <= 0) diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 6bc51fcc688..513056d232f 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -706,10 +706,10 @@ static int daqboard2000_attach_pci(struct comedi_device *dev, dev->board_ptr = board; dev->board_name = board->name; - result = alloc_private(dev, sizeof(*devpriv)); - if (result) - return result; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; result = comedi_pci_enable(pcidev, dev->driver->driver_name); if (result < 0) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 19c2907c384..4fa8f0baa4a 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -780,15 +780,14 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) { struct das08_private_struct *devpriv; unsigned long iobase; - int ret; if (!DO_PCI) return -EINVAL; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev_info(dev->class_dev, "attach pci %s\n", pci_name(pdev)); dev->board_ptr = das08_find_pci_board(pdev); @@ -813,13 +812,12 @@ das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das08_board_struct *thisboard = comedi_board(dev); struct das08_private_struct *devpriv; - int ret; unsigned long iobase; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev_info(dev->class_dev, "attach\n"); if (is_pci_board(thisboard)) { diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c index d908d2d04f8..024262375e3 100644 --- a/drivers/staging/comedi/drivers/das08_cs.c +++ b/drivers/staging/comedi/drivers/das08_cs.c @@ -91,14 +91,13 @@ static int das08_cs_attach(struct comedi_device *dev, { const struct das08_board_struct *thisboard = comedi_board(dev); struct das08_private_struct *devpriv; - int ret; unsigned long iobase; struct pcmcia_device *link = cur_dev; /* XXX hack */ - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev_info(dev->class_dev, "das08_cs: attach\n"); /* deal with a pci board */ diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 3f614dcde8b..2ceadcb9740 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -1127,10 +1127,10 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) } } - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; if (board->size < 0x400) { printk(" 0x%04lx-0x%04lx\n", iobase, iobase + board->size); diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index b06f2b8aad6..d93d95102af 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -594,10 +594,10 @@ static int das16m1_attach(struct comedi_device *dev, iobase = it->options[0]; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; if (!request_region(iobase, DAS16M1_SIZE, dev->board_name)) { comedi_error(dev, "I/O port conflict\n"); diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 3754fcb8353..2495cd91479 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -1542,10 +1542,10 @@ static int das1800_attach(struct comedi_device *dev, int board; int retval; - retval = alloc_private(dev, sizeof(*devpriv)); - if (retval) - return retval; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; printk(KERN_DEBUG "comedi%d: %s: io 0x%lx", dev->minor, dev->driver->driver_name, iobase); diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index 8029e370b2d..2efddb89bbc 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -310,10 +310,10 @@ static int das6402_attach(struct comedi_device *dev, dev->irq = irq; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 1); if (ret) diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 2a6df6b6ae3..1ba26b46fd9 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -472,10 +472,10 @@ static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (irq) dev_dbg(dev->class_dev, "irq %u\n", irq); - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; if (iobase == 0) { dev_err(dev->class_dev, diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index c8b7a031c48..a526c6770bb 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -793,10 +793,10 @@ static int dmm32at_attach(struct comedi_device *dev, dev->irq = irq; } - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 3); if (ret) diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c index da139d212ce..f6942aaf0ec 100644 --- a/drivers/staging/comedi/drivers/dt2801.c +++ b/drivers/staging/comedi/drivers/dt2801.c @@ -633,10 +633,10 @@ havetype: if (ret) goto out; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_name = boardtype.name; diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c index c4a7768971d..f90ecf494aa 100644 --- a/drivers/staging/comedi/drivers/dt2811.c +++ b/drivers/staging/comedi/drivers/dt2811.c @@ -465,10 +465,10 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; switch (it->options[2]) { case 0: diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 4b81ae33ca0..35cb2b55236 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -325,10 +325,10 @@ static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; s = &dev->subdevices[0]; dev->read_subdev = s; diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c index 1f1998f3d24..1e0cfe4972a 100644 --- a/drivers/staging/comedi/drivers/dt2815.c +++ b/drivers/staging/comedi/drivers/dt2815.c @@ -183,10 +183,10 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; s = &dev->subdevices[0]; /* ao subdevice */ diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index f2524683321..9746294efc9 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -1239,10 +1239,10 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif } - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = dt282x_grab_dma(dev, it->options[opt_dma1], it->options[opt_dma2]); diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index e71d880bdda..46645759781 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -806,10 +806,10 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev_dbg(dev->class_dev, "dt3000:\n"); - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; pcidev = dt3000_find_pci_dev(dev, it); if (!pcidev) diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 02b5394d7bd..176799849d2 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -1031,10 +1031,10 @@ static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = "dt9812"; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* * Special open routine, since USB unit may be unattached at diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 6f612be1b0a..98e2ffb1992 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -190,10 +190,10 @@ static int dyna_pci10xx_attach_pci(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c index c1c24b06255..019c96eda6f 100644 --- a/drivers/staging/comedi/drivers/fl512.c +++ b/drivers/staging/comedi/drivers/fl512.c @@ -127,10 +127,10 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; dev->board_name = "fl512"; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; #if DEBUG printk(KERN_DEBUG "malloc ok\n"); diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 550f458cb59..17aec51343b 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -481,10 +481,10 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) printk(KERN_WARNING "comedi%d: gsc_hpdi\n", dev->minor); - retval = alloc_private(dev, sizeof(*devpriv)); - if (retval) - return retval; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; pcidev = NULL; for (i = 0; i < ARRAY_SIZE(hpdi_boards) && diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 8eb3a87b5b8..8a3f6348437 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -505,10 +505,10 @@ static int icp_multi_attach_pci(struct comedi_device *dev, comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index 972a09fa753..93584e2be35 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -206,10 +206,10 @@ static int pci20xxx_attach(struct comedi_device *dev, if (ret) return ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; devpriv->ioaddr = (void __iomem *)(unsigned long)it->options[0]; dev->board_name = "pci20kc"; diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 69378dd90e2..68400f13af0 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -762,10 +762,10 @@ static int jr3_pci_attach(struct comedi_device *dev, return -EINVAL; } - result = alloc_private(dev, sizeof(*devpriv)); - if (result) - return result; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; card = NULL; init_timer(&devpriv->timer); diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 22db35d091f..ae91837fe7e 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1586,10 +1586,10 @@ static int me4000_attach_pci(struct comedi_device *dev, dev->board_ptr = thisboard; dev->board_name = thisboard->name; - result = alloc_private(dev, sizeof(*info)); - if (result) - return result; - info = dev->private; + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + dev->private = info; result = comedi_pci_enable(pcidev, dev->board_name); if (result) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 3eac3ef8d79..33b13aedfc0 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -656,10 +656,10 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) dev->board_ptr = board; dev->board_name = board->name; - error = alloc_private(dev, sizeof(*dev_private)); - if (error) - return error; - dev_private = dev->private; + dev_private = kzalloc(sizeof(*dev_private), GFP_KERNEL); + if (!dev_private) + return -ENOMEM; + dev->private = dev_private; /* Enable PCI device and request PCI regions */ if (comedi_pci_enable(pcidev, dev->board_name) < 0) { diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c index 3e8892c8209..67dc5ad81b0 100644 --- a/drivers/staging/comedi/drivers/mpc624.c +++ b/drivers/staging/comedi/drivers/mpc624.c @@ -298,10 +298,10 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = iobase; dev->board_name = "mpc624"; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; switch (it->options[1]) { case 0: diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c index f707ee02dcc..1f5f402f3d1 100644 --- a/drivers/staging/comedi/drivers/multiq3.c +++ b/drivers/staging/comedi/drivers/multiq3.c @@ -258,10 +258,10 @@ static int multiq3_attach(struct comedi_device *dev, if (result) return result; - result = alloc_private(dev, sizeof(*devpriv)); - if (result) - return result; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; s = &dev->subdevices[0]; /* ai subdevice */ diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 4f5624a3a1b..d853e75be79 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -364,10 +364,10 @@ static int __devinit ni6527_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_ptr = ni6527_find_boardinfo(pcidev); if (!dev->board_ptr) diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 1881f334625..19d5e8c96e8 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -635,10 +635,10 @@ static int __devinit ni_65xx_attach_pci(struct comedi_device *dev, unsigned i; int ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_ptr = ni_65xx_find_boardinfo(pcidev); if (!dev->board_ptr) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index d8684072744..3cff208de8a 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -996,13 +996,12 @@ static int ni_660x_buf_change(struct comedi_device *dev, static int ni_660x_allocate_private(struct comedi_device *dev) { struct ni_660x_private *devpriv; - int retval; unsigned i; - retval = alloc_private(dev, sizeof(*devpriv)); - if (retval) - return retval; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; spin_lock_init(&devpriv->mite_channel_lock); spin_lock_init(&devpriv->interrupt_lock); diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index e7ccf0423b0..2cf4907c366 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -210,10 +210,10 @@ static int __devinit ni_670x_attach_pci(struct comedi_device *dev, int ret; int i; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_ptr = ni_670x_find_boardinfo(pcidev); if (!dev->board_ptr) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 34c186b9dce..0222def373c 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -758,10 +758,10 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it) } printk("\n"); - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; if (iobase == 0) { printk(" io base address required\n"); diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c index 66071600de0..907f65cdbdc 100644 --- a/drivers/staging/comedi/drivers/ni_at_ao.c +++ b/drivers/staging/comedi/drivers/ni_at_ao.c @@ -356,10 +356,10 @@ static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 93969865b35..a3884b4d90c 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -678,10 +678,10 @@ static int atmio16d_attach(struct comedi_device *dev, if (ret) return ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* reset the atmio16d hardware */ reset_atmio16d(dev); diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index 8df5bfe721f..7b333353c5d 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -117,10 +117,10 @@ static int dio24_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct pcmcia_device *link; int ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* get base address, irq etc. based on bustype */ switch (thisboard->bustype) { diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index d3b386e51bf..40012506334 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -707,10 +707,10 @@ static int __devinit labpc_attach_pci(struct comedi_device *dev, if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS)) return -ENODEV; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_ptr = labpc_pci_find_boardinfo(pcidev); if (!dev->board_ptr) @@ -732,12 +732,11 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long iobase = 0; unsigned int irq = 0; unsigned int dma_chan = 0; - int ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* get base address, irq etc. based on bustype */ switch (thisboard->bustype) { diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c index 791a66ff65a..bfe19fa7d66 100644 --- a/drivers/staging/comedi/drivers/ni_labpc_cs.c +++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c @@ -131,12 +131,11 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long iobase = 0; unsigned int irq = 0; struct pcmcia_device *link; - int ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* get base address, irq etc. based on bustype */ switch (thisboard->bustype) { diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index b096c4647b1..743a9016e07 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -4424,12 +4424,11 @@ static int ni_freq_out_insn_config(struct comedi_device *dev, static int ni_alloc_private(struct comedi_device *dev) { struct ni_private *devpriv; - int ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; spin_lock_init(&devpriv->window_lock); spin_lock_init(&devpriv->soft_reg_copy_lock); diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 233a2d350e8..fcf56cf4811 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1128,10 +1128,10 @@ static int __devinit nidio_attach_pci(struct comedi_device *dev, int ret; unsigned int irq; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; spin_lock_init(&devpriv->mite_channel_lock); diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index 33bda31392d..f9c15aa45fe 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -503,10 +503,10 @@ static int pcl711_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; s = &dev->subdevices[0]; /* AI subdevice */ diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index 22f907a0704..50e01968f19 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -248,10 +248,10 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; for (i = 0; i < 12; i++) { devpriv->bipolar[i] = 0; diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index 0d825915d46..d94c9dc7832 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -1167,12 +1167,12 @@ static int pcl812_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) { + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) { free_resources(dev); - return ret; + return -ENOMEM; } - devpriv = dev->private; + dev->private = devpriv; dev->board_name = board->name; diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 4cdb3c915f5..858600a753b 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -1024,10 +1024,10 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; } - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_name = board->name; diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index 9dcddea3f61..c94f289e3f3 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -1625,10 +1625,10 @@ static int pcl818_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long pages; struct comedi_subdevice *s; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* claim our I/O space */ iobase = it->options[0]; diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index 6e9a4ec9e85..5f062df1ead 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -235,10 +235,10 @@ static int pcm3724_attach(struct comedi_device *dev, iobase = it->options[0]; iorange = PCM3724_SIZE; - ret = alloc_private(dev, sizeof(*priv)); - if (ret) - return ret; - priv = dev->private; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + dev->private = priv; printk(KERN_INFO "comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor, dev->board_name, iobase); diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index 5d5fc519d82..13e84215fac 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -122,10 +122,10 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->board_name = board->name; diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c index c3009211026..0882dafaf57 100644 --- a/drivers/staging/comedi/drivers/pcmda12.c +++ b/drivers/staging/comedi/drivers/pcmda12.c @@ -173,10 +173,10 @@ static int pcmda12_attach(struct comedi_device *dev, dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; devpriv->simultaneous_xfer_mode = it->options[1]; diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c index 616652e00ef..7522bfb6db0 100644 --- a/drivers/staging/comedi/drivers/pcmmio.c +++ b/drivers/staging/comedi/drivers/pcmmio.c @@ -1005,10 +1005,10 @@ static int pcmmio_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EIO; } - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; for (asic = 0; asic < MAX_ASICS; ++asic) { devpriv->asics[asic].num = asic; diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 360180438b3..31ea20c2d39 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -775,10 +775,10 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = board->name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; for (asic = 0; asic < MAX_ASICS; ++asic) { devpriv->asics[asic].num = asic; diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c index 8e70affb331..d7842c95d98 100644 --- a/drivers/staging/comedi/drivers/poc.c +++ b/drivers/staging/comedi/drivers/poc.c @@ -167,10 +167,10 @@ static int poc_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; /* analog output subdevice */ s = &dev->subdevices[0]; diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index b867470cc3e..0a91738eae3 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1607,10 +1607,10 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) comedi_debug = 1; #endif - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; pcidev = rtd_find_pci(dev, it); if (!pcidev) diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c index 82dae22b081..7e577e44490 100644 --- a/drivers/staging/comedi/drivers/rti800.c +++ b/drivers/staging/comedi/drivers/rti800.c @@ -349,10 +349,10 @@ static int rti800_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; devpriv->adc_mux = it->options[2]; devpriv->adc_range = it->options[3]; diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c index 844e75ee9c4..2185ca1bcf0 100644 --- a/drivers/staging/comedi/drivers/rti802.c +++ b/drivers/staging/comedi/drivers/rti802.c @@ -105,10 +105,10 @@ static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = "rti802"; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 1); if (ret) diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index a1e256293bd..39232b35945 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -564,10 +564,10 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = iobase; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 4); if (ret) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 511183da0ee..7c50b01f6a6 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2700,10 +2700,10 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 3f9221d4918..4b3b9b02947 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -786,10 +786,10 @@ static int serial2002_attach(struct comedi_device *dev, dev_dbg(dev->class_dev, "serial2002: attach\n"); dev->board_name = dev->driver->driver_name; - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; dev->open = serial_2002_open; dev->close = serial_2002_close; diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index d2ef7db6247..f292d798f31 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -225,10 +225,10 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; /* Allocate the private data */ - ret = alloc_private(dev, sizeof(*devpriv)); - if (ret) - return ret; - devpriv = dev->private; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; ret = comedi_alloc_subdevices(dev, 3); if (ret) -- cgit v1.2.3 From 7fc465b106b40a598d83a0c98d0e8c2a1b4653ff Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 23 Oct 2012 13:43:11 -0700 Subject: staging: comedi: auto-config drivers do not need to set hw_dev The comedi core now sets the 'hw_dev' pointer in the function comedi_auto_config_helper() before calling the auto attach function in the driver. Remove the now unnecessary call to comedi_set_hw_dev() in the drivers that use the auto-config attach mechanism. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255_pci.c | 2 -- drivers/staging/comedi/drivers/adl_pci6208.c | 2 -- drivers/staging/comedi/drivers/adl_pci7x3x.c | 2 -- drivers/staging/comedi/drivers/adl_pci8164.c | 2 -- drivers/staging/comedi/drivers/adl_pci9111.c | 1 - drivers/staging/comedi/drivers/adv_pci1710.c | 2 -- drivers/staging/comedi/drivers/adv_pci1723.c | 1 - drivers/staging/comedi/drivers/adv_pci_dio.c | 2 -- drivers/staging/comedi/drivers/cb_pcidas.c | 2 -- drivers/staging/comedi/drivers/cb_pcidda.c | 2 -- drivers/staging/comedi/drivers/cb_pcimdas.c | 2 -- drivers/staging/comedi/drivers/cb_pcimdda.c | 1 - drivers/staging/comedi/drivers/contec_pci_dio.c | 2 -- drivers/staging/comedi/drivers/daqboard2000.c | 2 -- drivers/staging/comedi/drivers/das08.c | 2 +- drivers/staging/comedi/drivers/dyna_pci10xx.c | 2 -- drivers/staging/comedi/drivers/icp_multi.c | 1 - drivers/staging/comedi/drivers/ke_counter.c | 2 -- drivers/staging/comedi/drivers/me4000.c | 2 -- drivers/staging/comedi/drivers/me_daq.c | 2 -- drivers/staging/comedi/drivers/ni_660x.c | 2 +- drivers/staging/comedi/drivers/ni_pcidio.c | 2 +- drivers/staging/comedi/drivers/ni_pcimio.c | 2 +- drivers/staging/comedi/drivers/s626.c | 1 - 24 files changed, 4 insertions(+), 39 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 6a4f2a1ea66..6191a82f89a 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -227,8 +227,6 @@ static int pci_8255_attach_pci(struct comedi_device *dev, int ret; int i; - comedi_set_hw_dev(dev, &pcidev->dev); - board = pci_8255_find_boardinfo(dev, pcidev); if (!board) return -ENODEV; diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 343422abcd3..350e87dd04d 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -183,8 +183,6 @@ static int pci6208_attach_pci(struct comedi_device *dev, unsigned int val; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - boardinfo = pci6208_find_boardinfo(dev, pcidev); if (!boardinfo) return -ENODEV; diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index 599714e978b..8eee2fa0bf0 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -177,8 +177,6 @@ static int adl_pci7x3x_attach_pci(struct comedi_device *dev, int nchan; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - board = adl_pci7x3x_find_boardinfo(dev, pcidev); if (!board) return -ENODEV; diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 5a6d6d2e21b..9999f938745 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -218,8 +218,6 @@ static int adl_pci8164_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = dev->driver->driver_name; ret = comedi_pci_enable(pcidev, dev->board_name); diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index aa55443742c..236a88946d0 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -886,7 +886,6 @@ static int pci9111_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; dev_private = kzalloc(sizeof(*dev_private), GFP_KERNEL); diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 4161cb6be48..6131a0a7aa9 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1265,8 +1265,6 @@ static int pci1710_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int ret, subdev, n_subdevices; - comedi_set_hw_dev(dev, &pcidev->dev); - this_board = pci1710_find_boardinfo(dev, pcidev); if (!this_board) return -ENODEV; diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index d14ddcb1752..2eaf56dcc95 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -241,7 +241,6 @@ static int pci1723_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 47a7584d291..4b29f6d0505 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1100,8 +1100,6 @@ static int pci_dio_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int ret, subdev, i, j; - comedi_set_hw_dev(dev, &pcidev->dev); - this_board = pci_dio_find_boardinfo(dev, pcidev); if (!this_board) return -ENODEV; diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 3f4f8bef692..0e4d189d195 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1478,8 +1478,6 @@ static int cb_pcidas_attach_pci(struct comedi_device *dev, int i; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = cb_pcidas_find_boardinfo(dev, pcidev); if (!thisboard) return -ENODEV; diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 07a8969c891..798374fe8da 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -656,8 +656,6 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, int index; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = cb_pcidda_find_boardinfo(dev, pcidev); if (!pcidev) return -ENODEV; diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 9df9a02553c..138cfb15814 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -215,8 +215,6 @@ static int cb_pcimdas_attach_pci(struct comedi_device *dev, unsigned long iobase_8255; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = dev->driver->driver_name; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 651cf18cd60..9c015004924 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -159,7 +159,6 @@ static int cb_pcimdda_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 178a6a4bb7d..70a9243cf33 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -74,8 +74,6 @@ static int contec_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = dev->driver->driver_name; ret = comedi_pci_enable(pcidev, dev->board_name); diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 513056d232f..87b9cd572f8 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -698,8 +698,6 @@ static int daqboard2000_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int result; - comedi_set_hw_dev(dev, &pcidev->dev); - board = daqboard2000_find_boardinfo(dev, pcidev); if (!board) return -ENODEV; diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 4fa8f0baa4a..fe5cf77a6aa 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -795,7 +795,7 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); return -EINVAL; } - comedi_set_hw_dev(dev, &pdev->dev); + /* enable PCI device and reserve I/O spaces */ if (comedi_pci_enable(pdev, dev->driver->driver_name)) { dev_err(dev->class_dev, diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 98e2ffb1992..c345660d781 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -186,8 +186,6 @@ static int dyna_pci10xx_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = dev->driver->driver_name; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 8a3f6348437..51af903773e 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -502,7 +502,6 @@ static int icp_multi_attach_pci(struct comedi_device *dev, resource_size_t iobase; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 8e37cff1bd8..355af553ed5 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -94,8 +94,6 @@ static int cnt_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); - dev->board_name = dev->driver->driver_name; ret = comedi_pci_enable(pcidev, dev->board_name); diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index ae91837fe7e..ba7fd9d53d1 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1578,8 +1578,6 @@ static int me4000_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int result; - comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = me4000_find_boardinfo(dev, pcidev); if (!thisboard) return -ENODEV; diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 33b13aedfc0..271db1cb607 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -648,8 +648,6 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) resource_size_t regbase_tmp; int result, error; - comedi_set_hw_dev(dev, &pcidev->dev); - board = me_find_boardinfo(dev, pcidev); if (!board) return -ENODEV; diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 3cff208de8a..5e1d8308faa 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1083,7 +1083,7 @@ static int __devinit ni_660x_attach_pci(struct comedi_device *dev, dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } - comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev); + ret = ni_660x_alloc_mite_rings(dev); if (ret < 0) return ret; diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index fcf56cf4811..0a556c7f9bc 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1147,7 +1147,7 @@ static int __devinit nidio_attach_pci(struct comedi_device *dev, dev_warn(dev->class_dev, "error setting up mite\n"); return ret; } - comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev); + devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite); if (devpriv->di_mite_ring == NULL) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 2e6dbeec9a9..4adb4ba545c 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1661,7 +1661,7 @@ static int __devinit pcimio_attach_pci(struct comedi_device *dev, pr_warn("error setting up mite\n"); return ret; } - comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev); + devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite); if (devpriv->ai_mite_ring == NULL) return -ENOMEM; diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 7c50b01f6a6..15755325121 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2697,7 +2697,6 @@ static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) struct comedi_subdevice *s; int ret; - comedi_set_hw_dev(dev, &pcidev->dev); dev->board_name = dev->driver->driver_name; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); -- cgit v1.2.3 From 0608882d01671983be20097e3ffd6be20c9a7724 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 23 Oct 2012 18:04:32 -0400 Subject: staging: slicoss: return -ENOMEM if kzalloc fail this takes up the error path cleanup, fixes a crash too due to null deref Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 94542808491..f6af3fe46c5 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -3667,6 +3667,8 @@ static u32 slic_card_locate(struct adapter *adapter) if (!physcard) { /* no structure allocated for this physical card yet */ physcard = kzalloc(sizeof(struct physcard), GFP_ATOMIC); + if (!physcard) + return -ENOMEM; physcard->next = slic_global.phys_card; slic_global.phys_card = physcard; -- cgit v1.2.3 From 1ffa3b91a2a155c26da43495bab01a12d946b253 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 23 Oct 2012 18:05:14 -0400 Subject: staging: slicoss: remove default case in irqhandler this default statement does nothing in the irqhandler, so remove it Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index f6af3fe46c5..86c8c8e0557 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -2774,9 +2774,6 @@ static irqreturn_t slic_interrupt(int irq, void *dev_id) slic_upr_request_complete(adapter, isr); } break; - - default: - break; } adapter->isrcopy = 0; -- cgit v1.2.3 From bae5c3d1427a9e685e4e9f7fc74f1c46aec2de62 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 23 Oct 2012 18:08:43 -0400 Subject: staging: slicoss: get rid of slic_cmdqmem_init function this function memset's the cmdqmem, instead do it in slic_cmdq_init. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index 86c8c8e0557..f08f4593b18 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -1424,13 +1424,6 @@ static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter) return buf; } -static void slic_cmdqmem_init(struct adapter *adapter) -{ - struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem; - - memset(cmdqmem, 0, sizeof(struct slic_cmdqmem)); -} - static void slic_cmdqmem_free(struct adapter *adapter) { struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem; @@ -1559,7 +1552,7 @@ static int slic_cmdq_init(struct adapter *adapter) spin_lock_init(&adapter->cmdq_all.lock.lock); spin_lock_init(&adapter->cmdq_free.lock.lock); spin_lock_init(&adapter->cmdq_done.lock.lock); - slic_cmdqmem_init(adapter); + memset(&adapter->cmdqmem, 0, sizeof(struct slic_cmdqmem)); adapter->slic_handle_ix = 1; for (i = 0; i < SLIC_CMDQ_INITPAGES; i++) { pageaddr = slic_cmdqmem_addpage(adapter); -- cgit v1.2.3 From 990b9eeda07b3f0c72dd2afa28e25067752e5222 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 23 Oct 2012 16:27:42 -0700 Subject: staging: comedi: ni_660x: move module init code to EOF Move the module init code to the end of the file. This removes the need for all the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 391 ++++++++++++++----------------- 1 file changed, 179 insertions(+), 212 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 5e1d8308faa..2cd7e10a8ca 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -419,16 +419,6 @@ static const struct ni_660x_board ni_660x_boards[] = { #define NI_660X_MAX_NUM_CHIPS 2 #define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip) -static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = { - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c60)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1310)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1360)}, - {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2cc0)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, ni_660x_pci_table); - struct ni_660x_private { struct mite_struct *mite; struct ni_gpct_device *counter_dev; @@ -449,64 +439,6 @@ static inline const struct ni_660x_board *board(struct comedi_device *dev) return dev->board_ptr; } -static int ni_660x_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev); -static void ni_660x_detach(struct comedi_device *dev); -static void init_tio_chip(struct comedi_device *dev, int chipset); -static void ni_660x_select_pfi_output(struct comedi_device *dev, - unsigned pfi_channel, - unsigned output_select); - -static struct comedi_driver ni_660x_driver = { - .driver_name = "ni_660x", - .module = THIS_MODULE, - .attach_pci = ni_660x_attach_pci, - .detach = ni_660x_detach, -}; - -static int __devinit ni_660x_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &ni_660x_driver); -} - -static void __devexit ni_660x_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver ni_660x_pci_driver = { - .name = "ni_660x", - .id_table = ni_660x_pci_table, - .probe = ni_660x_pci_probe, - .remove = __devexit_p(ni_660x_pci_remove) -}; -module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver); - -static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, - unsigned source); - -/* Possible instructions for a GPCT */ -static int ni_660x_GPCT_rinsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ni_660x_GPCT_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int ni_660x_GPCT_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Possible instructions for Digital IO */ -static int ni_660x_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int ni_660x_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - static inline unsigned ni_660x_num_counters(struct comedi_device *dev) { return board(dev)->n_chips * counters_per_chip; @@ -1055,150 +987,6 @@ ni_660x_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit ni_660x_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - struct ni_660x_private *devpriv; - struct comedi_subdevice *s; - int ret; - unsigned i; - unsigned global_interrupt_config_bits; - - ret = ni_660x_allocate_private(dev); - if (ret < 0) - return ret; - devpriv = dev->private; - - dev->board_ptr = ni_660x_find_boardinfo(pcidev); - if (!dev->board_ptr) - return -ENODEV; - devpriv->mite = mite_alloc(pcidev); - if (!devpriv->mite) - return -ENOMEM; - - dev->board_name = board(dev)->name; - - ret = mite_setup2(devpriv->mite, 1); - if (ret < 0) { - dev_warn(dev->class_dev, "error setting up mite\n"); - return ret; - } - - ret = ni_660x_alloc_mite_rings(dev); - if (ret < 0) - return ret; - - ret = comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS); - if (ret) - return ret; - - s = &dev->subdevices[0]; - /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */ - s->type = COMEDI_SUBD_UNUSED; - - s = &dev->subdevices[NI_660X_DIO_SUBDEV]; - /* DIGITAL I/O SUBDEVICE */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = NUM_PFI_CHANNELS; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = ni_660x_dio_insn_bits; - s->insn_config = ni_660x_dio_insn_config; - s->io_bits = 0; /* all bits default to input */ - /* we use the ioconfig registers to control dio direction, so zero - output enables in stc dio control reg */ - ni_660x_write_register(dev, 0, 0, STCDIOControl); - - devpriv->counter_dev = ni_gpct_device_construct(dev, - &ni_gpct_write_register, - &ni_gpct_read_register, - ni_gpct_variant_660x, - ni_660x_num_counters - (dev)); - if (devpriv->counter_dev == NULL) - return -ENOMEM; - for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { - s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; - if (i < ni_660x_num_counters(dev)) { - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = - SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | - SDF_CMD_READ /* | SDF_CMD_WRITE */ ; - s->n_chan = 3; - s->maxdata = 0xffffffff; - s->insn_read = ni_660x_GPCT_rinsn; - s->insn_write = ni_660x_GPCT_winsn; - s->insn_config = ni_660x_GPCT_insn_config; - s->do_cmd = &ni_660x_cmd; - s->len_chanlist = 1; - s->do_cmdtest = &ni_660x_cmdtest; - s->cancel = &ni_660x_cancel; - s->poll = &ni_660x_input_poll; - s->async_dma_dir = DMA_BIDIRECTIONAL; - s->buf_change = &ni_660x_buf_change; - s->private = &devpriv->counter_dev->counters[i]; - - devpriv->counter_dev->counters[i].chip_index = - i / counters_per_chip; - devpriv->counter_dev->counters[i].counter_index = - i % counters_per_chip; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - } - for (i = 0; i < board(dev)->n_chips; ++i) - init_tio_chip(dev, i); - - for (i = 0; i < ni_660x_num_counters(dev); ++i) - ni_tio_init_counter(&devpriv->counter_dev->counters[i]); - - for (i = 0; i < NUM_PFI_CHANNELS; ++i) { - if (i < min_counter_pfi_chan) - ni_660x_set_pfi_routing(dev, i, pfi_output_select_do); - else - ni_660x_set_pfi_routing(dev, i, - pfi_output_select_counter); - ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z); - } - /* to be safe, set counterswap bits on tio chips after all the counter - outputs have been set to high impedance mode */ - for (i = 0; i < board(dev)->n_chips; ++i) - set_tio_counterswap(dev, i); - - ret = request_irq(mite_irq(devpriv->mite), ni_660x_interrupt, - IRQF_SHARED, "ni_660x", dev); - if (ret < 0) { - dev_warn(dev->class_dev, " irq not available\n"); - return ret; - } - dev->irq = mite_irq(devpriv->mite); - global_interrupt_config_bits = Global_Int_Enable_Bit; - if (board(dev)->n_chips > 1) - global_interrupt_config_bits |= Cascade_Int_Enable_Bit; - ni_660x_write_register(dev, 0, global_interrupt_config_bits, - GlobalInterruptConfigRegister); - dev_info(dev->class_dev, "ni_660x: %s attached\n", dev->board_name); - return 0; -} - -static void ni_660x_detach(struct comedi_device *dev) -{ - struct ni_660x_private *devpriv = dev->private; - - if (dev->irq) - free_irq(dev->irq, dev); - if (devpriv) { - if (devpriv->counter_dev) - ni_gpct_device_destroy(devpriv->counter_dev); - if (devpriv->mite) { - ni_660x_free_mite_rings(dev); - mite_unsetup(devpriv->mite); - mite_free(devpriv->mite); - } - } -} - static int ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) @@ -1390,6 +1178,185 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, return 0; } +static int __devinit ni_660x_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + struct ni_660x_private *devpriv; + struct comedi_subdevice *s; + int ret; + unsigned i; + unsigned global_interrupt_config_bits; + + ret = ni_660x_allocate_private(dev); + if (ret < 0) + return ret; + devpriv = dev->private; + + dev->board_ptr = ni_660x_find_boardinfo(pcidev); + if (!dev->board_ptr) + return -ENODEV; + devpriv->mite = mite_alloc(pcidev); + if (!devpriv->mite) + return -ENOMEM; + + dev->board_name = board(dev)->name; + + ret = mite_setup2(devpriv->mite, 1); + if (ret < 0) { + dev_warn(dev->class_dev, "error setting up mite\n"); + return ret; + } + + ret = ni_660x_alloc_mite_rings(dev); + if (ret < 0) + return ret; + + ret = comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS); + if (ret) + return ret; + + s = &dev->subdevices[0]; + /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */ + s->type = COMEDI_SUBD_UNUSED; + + s = &dev->subdevices[NI_660X_DIO_SUBDEV]; + /* DIGITAL I/O SUBDEVICE */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = NUM_PFI_CHANNELS; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = ni_660x_dio_insn_bits; + s->insn_config = ni_660x_dio_insn_config; + s->io_bits = 0; /* all bits default to input */ + /* we use the ioconfig registers to control dio direction, so zero + output enables in stc dio control reg */ + ni_660x_write_register(dev, 0, 0, STCDIOControl); + + devpriv->counter_dev = ni_gpct_device_construct(dev, + &ni_gpct_write_register, + &ni_gpct_read_register, + ni_gpct_variant_660x, + ni_660x_num_counters + (dev)); + if (devpriv->counter_dev == NULL) + return -ENOMEM; + for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { + s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)]; + if (i < ni_660x_num_counters(dev)) { + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = + SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | + SDF_CMD_READ /* | SDF_CMD_WRITE */ ; + s->n_chan = 3; + s->maxdata = 0xffffffff; + s->insn_read = ni_660x_GPCT_rinsn; + s->insn_write = ni_660x_GPCT_winsn; + s->insn_config = ni_660x_GPCT_insn_config; + s->do_cmd = &ni_660x_cmd; + s->len_chanlist = 1; + s->do_cmdtest = &ni_660x_cmdtest; + s->cancel = &ni_660x_cancel; + s->poll = &ni_660x_input_poll; + s->async_dma_dir = DMA_BIDIRECTIONAL; + s->buf_change = &ni_660x_buf_change; + s->private = &devpriv->counter_dev->counters[i]; + + devpriv->counter_dev->counters[i].chip_index = + i / counters_per_chip; + devpriv->counter_dev->counters[i].counter_index = + i % counters_per_chip; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + } + for (i = 0; i < board(dev)->n_chips; ++i) + init_tio_chip(dev, i); + + for (i = 0; i < ni_660x_num_counters(dev); ++i) + ni_tio_init_counter(&devpriv->counter_dev->counters[i]); + + for (i = 0; i < NUM_PFI_CHANNELS; ++i) { + if (i < min_counter_pfi_chan) + ni_660x_set_pfi_routing(dev, i, pfi_output_select_do); + else + ni_660x_set_pfi_routing(dev, i, + pfi_output_select_counter); + ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z); + } + /* to be safe, set counterswap bits on tio chips after all the counter + outputs have been set to high impedance mode */ + for (i = 0; i < board(dev)->n_chips; ++i) + set_tio_counterswap(dev, i); + + ret = request_irq(mite_irq(devpriv->mite), ni_660x_interrupt, + IRQF_SHARED, "ni_660x", dev); + if (ret < 0) { + dev_warn(dev->class_dev, " irq not available\n"); + return ret; + } + dev->irq = mite_irq(devpriv->mite); + global_interrupt_config_bits = Global_Int_Enable_Bit; + if (board(dev)->n_chips > 1) + global_interrupt_config_bits |= Cascade_Int_Enable_Bit; + ni_660x_write_register(dev, 0, global_interrupt_config_bits, + GlobalInterruptConfigRegister); + dev_info(dev->class_dev, "ni_660x: %s attached\n", dev->board_name); + return 0; +} + +static void ni_660x_detach(struct comedi_device *dev) +{ + struct ni_660x_private *devpriv = dev->private; + + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv) { + if (devpriv->counter_dev) + ni_gpct_device_destroy(devpriv->counter_dev); + if (devpriv->mite) { + ni_660x_free_mite_rings(dev); + mite_unsetup(devpriv->mite); + mite_free(devpriv->mite); + } + } +} + +static struct comedi_driver ni_660x_driver = { + .driver_name = "ni_660x", + .module = THIS_MODULE, + .attach_pci = ni_660x_attach_pci, + .detach = ni_660x_detach, +}; + +static int __devinit ni_660x_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &ni_660x_driver); +} + +static void __devexit ni_660x_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = { + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2c60)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1310)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1360)}, + {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2cc0)}, + {0} +}; +MODULE_DEVICE_TABLE(pci, ni_660x_pci_table); + +static struct pci_driver ni_660x_pci_driver = { + .name = "ni_660x", + .id_table = ni_660x_pci_table, + .probe = ni_660x_pci_probe, + .remove = __devexit_p(ni_660x_pci_remove), +}; +module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver); + MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 9186ccdec5b60220e9f10b0ee68f13156d099a10 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 23 Oct 2012 16:27:57 -0700 Subject: staging: comedi: ni_660x: remove inline function board() This function is used to get the dev->board_ptr from the comedi_device. Remove the function and use a local variable to hold the pointer where used. Use the comedi_board() helper to get the pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 2cd7e10a8ca..25459860b46 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -433,15 +433,11 @@ struct ni_660x_private { unsigned short pfi_output_selects[NUM_PFI_CHANNELS]; }; -/* initialized in ni_660x_attach_pci() */ -static inline const struct ni_660x_board *board(struct comedi_device *dev) -{ - return dev->board_ptr; -} - static inline unsigned ni_660x_num_counters(struct comedi_device *dev) { - return board(dev)->n_chips * counters_per_chip; + const struct ni_660x_board *board = comedi_board(dev); + + return board->n_chips * counters_per_chip; } static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg) @@ -946,11 +942,12 @@ static int ni_660x_allocate_private(struct comedi_device *dev) static int ni_660x_alloc_mite_rings(struct comedi_device *dev) { + const struct ni_660x_board *board = comedi_board(dev); struct ni_660x_private *devpriv = dev->private; unsigned i; unsigned j; - for (i = 0; i < board(dev)->n_chips; ++i) { + for (i = 0; i < board->n_chips; ++i) { for (j = 0; j < counters_per_chip; ++j) { devpriv->mite_rings[i][j] = mite_alloc_ring(devpriv->mite); @@ -963,11 +960,12 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev) static void ni_660x_free_mite_rings(struct comedi_device *dev) { + const struct ni_660x_board *board = comedi_board(dev); struct ni_660x_private *devpriv = dev->private; unsigned i; unsigned j; - for (i = 0; i < board(dev)->n_chips; ++i) { + for (i = 0; i < board->n_chips; ++i) { for (j = 0; j < counters_per_chip; ++j) mite_free_ring(devpriv->mite_rings[i][j]); } @@ -1051,6 +1049,7 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned pfi_channel, unsigned output_select) { + const struct ni_660x_board *board = comedi_board(dev); static const unsigned counter_4_7_first_pfi = 8; static const unsigned counter_4_7_last_pfi = 23; unsigned active_chipset = 0; @@ -1058,7 +1057,7 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned active_bits; unsigned idle_bits; - if (board(dev)->n_chips > 1) { + if (board->n_chips > 1) { if (output_select == pfi_output_select_counter && pfi_channel >= counter_4_7_first_pfi && pfi_channel <= counter_4_7_last_pfi) { @@ -1181,6 +1180,7 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, static int __devinit ni_660x_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { + const struct ni_660x_board *board; struct ni_660x_private *devpriv; struct comedi_subdevice *s; int ret; @@ -1195,11 +1195,13 @@ static int __devinit ni_660x_attach_pci(struct comedi_device *dev, dev->board_ptr = ni_660x_find_boardinfo(pcidev); if (!dev->board_ptr) return -ENODEV; + board = comedi_board(dev); + devpriv->mite = mite_alloc(pcidev); if (!devpriv->mite) return -ENOMEM; - dev->board_name = board(dev)->name; + dev->board_name = board->name; ret = mite_setup2(devpriv->mite, 1); if (ret < 0) { @@ -1270,7 +1272,7 @@ static int __devinit ni_660x_attach_pci(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } } - for (i = 0; i < board(dev)->n_chips; ++i) + for (i = 0; i < board->n_chips; ++i) init_tio_chip(dev, i); for (i = 0; i < ni_660x_num_counters(dev); ++i) @@ -1286,7 +1288,7 @@ static int __devinit ni_660x_attach_pci(struct comedi_device *dev, } /* to be safe, set counterswap bits on tio chips after all the counter outputs have been set to high impedance mode */ - for (i = 0; i < board(dev)->n_chips; ++i) + for (i = 0; i < board->n_chips; ++i) set_tio_counterswap(dev, i); ret = request_irq(mite_irq(devpriv->mite), ni_660x_interrupt, @@ -1297,7 +1299,7 @@ static int __devinit ni_660x_attach_pci(struct comedi_device *dev, } dev->irq = mite_irq(devpriv->mite); global_interrupt_config_bits = Global_Int_Enable_Bit; - if (board(dev)->n_chips > 1) + if (board->n_chips > 1) global_interrupt_config_bits |= Cascade_Int_Enable_Bit; ni_660x_write_register(dev, 0, global_interrupt_config_bits, GlobalInterruptConfigRegister); -- cgit v1.2.3 From e0f6959fbb318c1fb08c79503815b2cdd79d7554 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 23 Oct 2012 16:28:14 -0700 Subject: staging: comedi: ni_660x: remove BUG_ON(chan >= NUM_PFI_CHANNELS) This BUG_ON can never happen. The 'chan' value comes from the comedi core in the insn->chanspec and will always be in range for the subdevice number of channels (s->n_chan = NUM_PFI_CHANNELS). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 25459860b46..3f8ac566825 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1106,7 +1106,6 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, if (source == pfi_output_select_do) return -EINVAL; } - BUG_ON(chan >= NUM_PFI_CHANNELS); devpriv->pfi_output_selects[chan] = source; if (devpriv->pfi_direction_bits & (((uint64_t) 1) << chan)) @@ -1120,7 +1119,6 @@ static unsigned ni_660x_get_pfi_routing(struct comedi_device *dev, { struct ni_660x_private *devpriv = dev->private; - BUG_ON(chan >= NUM_PFI_CHANNELS); return devpriv->pfi_output_selects[chan]; } -- cgit v1.2.3 From 32bd027dd700744b29b89c38353b5597e70ce802 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 23 Oct 2012 16:28:30 -0700 Subject: staging: comedi: ni_660x: remove ni_660x_get_pfi_routing() This simple function is only called by ni_660x_dio_insn_config(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 3f8ac566825..cdadc0be962 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1114,14 +1114,6 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, return 0; } -static unsigned ni_660x_get_pfi_routing(struct comedi_device *dev, - unsigned chan) -{ - struct ni_660x_private *devpriv = dev->private; - - return devpriv->pfi_output_selects[chan]; -} - static void ni660x_config_filter(struct comedi_device *dev, unsigned pfi_channel, enum ni_gpct_filter_select filter) @@ -1163,7 +1155,7 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, return ni_660x_set_pfi_routing(dev, chan, data[1]); break; case INSN_CONFIG_GET_ROUTING: - data[1] = ni_660x_get_pfi_routing(dev, chan); + data[1] = devpriv->pfi_output_selects[chan]; break; case INSN_CONFIG_FILTER: ni660x_config_filter(dev, chan, data[1]); -- cgit v1.2.3 From 82327aaf2e9fada01c972b296cbfc46a2ca9d85c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 23 Oct 2012 16:28:45 -0700 Subject: staging: comedi: ni_660x: remove ni660x_config_filter() This simple function is only called by ni_660x_dio_insn_config(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index cdadc0be962..360d873e57e 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1114,22 +1114,13 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, return 0; } -static void ni660x_config_filter(struct comedi_device *dev, - unsigned pfi_channel, - enum ni_gpct_filter_select filter) -{ - unsigned bits = ni_660x_read_register(dev, 0, IOConfigReg(pfi_channel)); - bits &= ~pfi_input_select_mask(pfi_channel); - bits |= pfi_input_select_bits(pfi_channel, filter); - ni_660x_write_register(dev, 0, bits, IOConfigReg(pfi_channel)); -} - static int ni_660x_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { struct ni_660x_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); + unsigned int val; /* The input or output configuration of each digital line is * configured by a special insn_config instruction. chanspec @@ -1158,7 +1149,10 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, data[1] = devpriv->pfi_output_selects[chan]; break; case INSN_CONFIG_FILTER: - ni660x_config_filter(dev, chan, data[1]); + val = ni_660x_read_register(dev, 0, IOConfigReg(chan)); + val &= ~pfi_input_select_mask(chan); + val |= pfi_input_select_bits(chan, data[1]); + ni_660x_write_register(dev, 0, val, IOConfigReg(chan)); break; default: return -EINVAL; -- cgit v1.2.3 From 56c645ff7f1d57781a2231071be858cba5107678 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 23 Oct 2012 16:29:07 -0700 Subject: staging: comedi: ni_660x: cleanup ni_660x_dio_insn_config() This function handles all the insn_config instructions for the digital i/o subdevice. These functions are supposed to return the number of instruction parameters used (insn->n) or an -errno. Fix the switch() so that the correct result is returned for all INSN_CONFIG_* cases. To clarify the code, add a local variable for the 'bit' used with the instructions used to configure and query the input/output setting of a channel. For aesthetic reasons, add a whitespace between each case to improve readability. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_660x.c | 37 ++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 360d873e57e..31805754648 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1116,49 +1116,54 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan, static int ni_660x_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { struct ni_660x_private *devpriv = dev->private; - int chan = CR_CHAN(insn->chanspec); + unsigned int chan = CR_CHAN(insn->chanspec); + uint64_t bit = 1ULL << chan; unsigned int val; - - /* The input or output configuration of each digital line is - * configured by a special insn_config instruction. chanspec - * contains the channel to be changed, and data[0] contains the - * value COMEDI_INPUT or COMEDI_OUTPUT. */ + int ret; switch (data[0]) { case INSN_CONFIG_DIO_OUTPUT: - devpriv->pfi_direction_bits |= ((uint64_t) 1) << chan; + devpriv->pfi_direction_bits |= bit; ni_660x_select_pfi_output(dev, chan, devpriv->pfi_output_selects[chan]); break; + case INSN_CONFIG_DIO_INPUT: - devpriv->pfi_direction_bits &= ~(((uint64_t) 1) << chan); + devpriv->pfi_direction_bits &= ~bit; ni_660x_select_pfi_output(dev, chan, pfi_output_select_high_Z); break; + case INSN_CONFIG_DIO_QUERY: - data[1] = - (devpriv->pfi_direction_bits & - (((uint64_t) 1) << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; - return 0; + data[1] = (devpriv->pfi_direction_bits & bit) ? COMEDI_OUTPUT + : COMEDI_INPUT; + break; + case INSN_CONFIG_SET_ROUTING: - return ni_660x_set_pfi_routing(dev, chan, data[1]); + ret = ni_660x_set_pfi_routing(dev, chan, data[1]); + if (ret) + return ret; break; + case INSN_CONFIG_GET_ROUTING: data[1] = devpriv->pfi_output_selects[chan]; break; + case INSN_CONFIG_FILTER: val = ni_660x_read_register(dev, 0, IOConfigReg(chan)); val &= ~pfi_input_select_mask(chan); val |= pfi_input_select_bits(chan, data[1]); ni_660x_write_register(dev, 0, val, IOConfigReg(chan)); break; + default: return -EINVAL; - break; } - return 0; + + return insn->n; } static int __devinit ni_660x_attach_pci(struct comedi_device *dev, -- cgit v1.2.3 From 5ee60a7038c79d2276ae315ac6d6764391ed386f Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 22 Oct 2012 23:22:22 -0700 Subject: staging: "winbond" Fix typos. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds.c | 2 +- drivers/staging/winbond/wbhal.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index 1b8b8ace39e..43990e87d64 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -315,7 +315,7 @@ static void Mds_HeaderCopy(struct wbsoft_priv *adapter, struct wb35_descriptor * pT00->T00_tx_packet_id = pDes->Descriptor_ID; /* Set packet ID */ pT00->T00_header_length = 24; /* Set header length */ - pT01->T01_retry_abort_ebable = 1; /* 921013 931130.5.h */ + pT01->T01_retry_abort_enable = 1; /* 921013 931130.5.h */ /* Key ID setup */ pT01->T01_wep_id = 0; diff --git a/drivers/staging/winbond/wbhal.h b/drivers/staging/winbond/wbhal.h index 39e84a0d972..289ee549146 100644 --- a/drivers/staging/winbond/wbhal.h +++ b/drivers/staging/winbond/wbhal.h @@ -226,11 +226,11 @@ struct T01_descriptor { u32 T01_add_challenge_text:1; u32 T01_inhibit_crc:1; u32 T01_loop_back_wep_mode:1; - u32 T01_retry_abort_ebable:1; + u32 T01_retry_abort_enable:1; }; #else struct { - u32 T01_retry_abort_ebable:1; + u32 T01_retry_abort_enable:1; u32 T01_loop_back_wep_mode:1; u32 T01_inhibit_crc:1; u32 T01_add_challenge_text:1; -- cgit v1.2.3 From 5c092f41fdb636859a20f57372f8dd25633adbef Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Mon, 22 Oct 2012 17:22:20 -0400 Subject: staging: ced1401: fix a frame size warning gcc/sparse complain about the following: drivers/staging/ced1401/ced_ioc.c:931:1: warning: the frame size of 4144 bytes is larger than 2048 bytes [-Wframe-larger-than=] Fix it by dynamically allocating it. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ced1401/ced_ioc.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c index 5813aee6b34..0adba75be8b 100644 --- a/drivers/staging/ced1401/ced_ioc.c +++ b/drivers/staging/ced1401/ced_ioc.c @@ -913,18 +913,24 @@ int GetTransfer(DEVICE_EXTENSION * pdx, TGET_TX_BLOCK __user * pTX) iReturn = U14ERR_BADAREA; else { // Return the best information we have - we don't have physical addresses - TGET_TX_BLOCK tx; - memset(&tx, 0, sizeof(tx)); // clean out local work structure - tx.size = pdx->rTransDef[dwIdent].dwLength; - tx.linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff); - tx.avail = GET_TX_MAXENTRIES; // how many blocks we could return - tx.used = 1; // number we actually return - tx.entries[0].physical = - (long long)(tx.linear + pdx->StagedOffset); - tx.entries[0].size = tx.size; - - if (copy_to_user(pTX, &tx, sizeof(tx))) + TGET_TX_BLOCK *tx; + + tx = kzalloc(sizeof(*tx), GFP_KERNEL); + if (!tx) { + mutex_unlock(&pdx->io_mutex); + return -ENOMEM; + } + tx->size = pdx->rTransDef[dwIdent].dwLength; + tx->linear = (long long)((long)pdx->rTransDef[dwIdent].lpvBuff); + tx->avail = GET_TX_MAXENTRIES; // how many blocks we could return + tx->used = 1; // number we actually return + tx->entries[0].physical = + (long long)(tx->linear + pdx->StagedOffset); + tx->entries[0].size = tx->size; + + if (copy_to_user(pTX, tx, sizeof(*tx))) iReturn = -EFAULT; + kfree(tx); } mutex_unlock(&pdx->io_mutex); return iReturn; -- cgit v1.2.3 From 272bf3146f0ae35b17f2f27f4d63fa0392d0eeda Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Tue, 23 Oct 2012 15:00:06 +0900 Subject: staging: csr: Remove struct CsrThread Nobody use struct CsrThread. So, remove it. Signed-off-by: SeongJae Park Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext_types.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/csr/csr_framework_ext_types.h b/drivers/staging/csr/csr_framework_ext_types.h index 0d06d95d04f..2bf854af78c 100644 --- a/drivers/staging/csr/csr_framework_ext_types.h +++ b/drivers/staging/csr/csr_framework_ext_types.h @@ -24,11 +24,6 @@ extern "C" { #ifdef __KERNEL__ -struct CsrThread { - struct task_struct *thread_task; - char name[16]; -}; - struct CsrEvent { /* wait_queue for waking the kernel thread */ wait_queue_head_t wakeup_q; -- cgit v1.2.3 From ad2d25595870a33d3e38e0bc6960fad144539164 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Tue, 23 Oct 2012 15:00:07 +0900 Subject: staging: csr: Remove CsrThreadHandle CsrThreadHandle is typedef of struct CsrThread. Some functions in csr_framework_ext.h use it as parameter. But, nobody call them. Signed-off-by: SeongJae Park Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext.h | 49 --------------------------- drivers/staging/csr/csr_framework_ext_types.h | 2 -- 2 files changed, 51 deletions(-) diff --git a/drivers/staging/csr/csr_framework_ext.h b/drivers/staging/csr/csr_framework_ext.h index 66973e93a6b..16635a9717b 100644 --- a/drivers/staging/csr/csr_framework_ext.h +++ b/drivers/staging/csr/csr_framework_ext.h @@ -179,55 +179,6 @@ void CsrGlobalMutexLock(void); *----------------------------------------------------------------------------*/ void CsrGlobalMutexUnlock(void); -/*----------------------------------------------------------------------------* - * NAME - * CsrThreadCreate - * - * DESCRIPTION - * Create thread function and return a handle to the created thread. - * - * RETURNS - * Possible values: - * CSR_RESULT_SUCCESS in case of success - * CSR_FE_RESULT_NO_MORE_THREADS in case of out of thread resources - * CSR_FE_RESULT_INVALID_POINTER in case one of the supplied pointers is invalid - * - *----------------------------------------------------------------------------*/ -CsrResult CsrThreadCreate(void (*threadFunction)(void *pointer), void *pointer, - u32 stackSize, u16 priority, - const char *threadName, CsrThreadHandle *threadHandle); - -/*----------------------------------------------------------------------------* - * NAME - * CsrThreadGetHandle - * - * DESCRIPTION - * Return thread handle of calling thread. - * - * RETURNS - * Possible values: - * CSR_RESULT_SUCCESS in case of success - * CSR_FE_RESULT_INVALID_POINTER in case the threadHandle pointer is invalid - * - *----------------------------------------------------------------------------*/ -CsrResult CsrThreadGetHandle(CsrThreadHandle *threadHandle); - -/*----------------------------------------------------------------------------* - * NAME - * CsrThreadEqual - * - * DESCRIPTION - * Compare thread handles - * - * RETURNS - * Possible values: - * CSR_RESULT_SUCCESS in case thread handles are identical - * CSR_FE_RESULT_INVALID_POINTER in case either threadHandle pointer is invalid - * CSR_RESULT_FAILURE otherwise - * - *----------------------------------------------------------------------------*/ -CsrResult CsrThreadEqual(CsrThreadHandle *threadHandle1, CsrThreadHandle *threadHandle2); - /*----------------------------------------------------------------------------* * NAME * CsrThreadSleep diff --git a/drivers/staging/csr/csr_framework_ext_types.h b/drivers/staging/csr/csr_framework_ext_types.h index 2bf854af78c..cd1f8771922 100644 --- a/drivers/staging/csr/csr_framework_ext_types.h +++ b/drivers/staging/csr/csr_framework_ext_types.h @@ -32,7 +32,6 @@ struct CsrEvent { typedef struct CsrEvent CsrEventHandle; typedef struct semaphore CsrMutexHandle; -typedef struct CsrThread CsrThreadHandle; #else /* __KERNEL __ */ @@ -44,7 +43,6 @@ struct CsrEvent { typedef struct CsrEvent CsrEventHandle; typedef pthread_mutex_t CsrMutexHandle; -typedef pthread_t CsrThreadHandle; #endif /* __KERNEL__ */ -- cgit v1.2.3 From 2a837ccdf348aa448134b5858d6bfc8782d2d2f2 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 24 Oct 2012 12:05:28 +0900 Subject: staging/sbe-2t3e3: Use netdev_ printks in main.c fixed below checkpatch warning. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sbe-2t3e3/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/sbe-2t3e3/main.c b/drivers/staging/sbe-2t3e3/main.c index f3dbef6b0ee..c8e039860dc 100644 --- a/drivers/staging/sbe-2t3e3/main.c +++ b/drivers/staging/sbe-2t3e3/main.c @@ -135,9 +135,10 @@ void t3e3_read_card_serial_number(struct channel *sc) for (i = 0; i < 3; i++) sc->ether.card_serial_number[i] = t3e3_eeprom_read_word(sc, 10 + i); - printk(KERN_INFO "SBE wanPMC-2T3E3 serial number: %04X%04X%04X\n", - sc->ether.card_serial_number[0], sc->ether.card_serial_number[1], - sc->ether.card_serial_number[2]); + netdev_info(sc->dev, "SBE wanPMC-2T3E3 serial number: %04X%04X%04X\n", + sc->ether.card_serial_number[0], + sc->ether.card_serial_number[1], + sc->ether.card_serial_number[2]); } /* -- cgit v1.2.3 From a17d23de9c5391e1651ae77d4e88d3c7bd55d1d6 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 24 Oct 2012 11:52:58 +0900 Subject: staging/sbe-2t3e3: Use netdev_ or dev_ or pr_ printks in module.c fixed below checkpatch warning. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_warn(netdev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ... and add pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sbe-2t3e3/module.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/staging/sbe-2t3e3/module.c b/drivers/staging/sbe-2t3e3/module.c index 8adb17816ad..8e1a043b6b9 100644 --- a/drivers/staging/sbe-2t3e3/module.c +++ b/drivers/staging/sbe-2t3e3/module.c @@ -10,6 +10,8 @@ * This code is based on a driver written by SBE Inc. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -66,7 +68,7 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev * dev = alloc_hdlcdev(channel); if (!dev) { - printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n"); + pr_err("Out of memory\n"); err = -ENOMEM; goto free_regions; } @@ -96,7 +98,8 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev * err = request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev); if (err) { - printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq); + netdev_warn(channel->dev, "%s: could not get irq: %d\n", + dev->name, dev->irq); goto unregister_dev; } @@ -144,7 +147,7 @@ static int __devinit t3e3_init_card(struct pci_dev *pdev, const struct pci_devic break; /* found the second channel */ if (!pdev1) { - printk(KERN_ERR "SBE 2T3E3" ": Can't find the second channel\n"); + dev_err(&pdev->dev, "Can't find the second channel\n"); return -EFAULT; } channels = 2; @@ -153,7 +156,7 @@ static int __devinit t3e3_init_card(struct pci_dev *pdev, const struct pci_devic card = kzalloc(sizeof(struct card) + channels * sizeof(struct channel), GFP_KERNEL); if (!card) { - printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n"); + dev_err(&pdev->dev, "Out of memory\n"); return -ENOBUFS; } -- cgit v1.2.3 From 41b3996e3b6825bd3a0624d62fde53fbad092ed0 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Wed, 24 Oct 2012 10:58:57 +0400 Subject: GPIO: clps711x: Fix return value for gpio_clps711x_get Signed-off-by: Alexander Shiyan Signed-off-by: Linus Walleij --- drivers/gpio/gpio-clps711x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c index ea21822b3de..0753b3a9a34 100644 --- a/drivers/gpio/gpio-clps711x.c +++ b/drivers/gpio/gpio-clps711x.c @@ -47,7 +47,7 @@ static void __iomem *clps711x_pdirs[] = { static int gpio_clps711x_get(struct gpio_chip *chip, unsigned offset) { - return !!readb(clps711x_port(chip)) & (1 << offset); + return !!(readb(clps711x_port(chip)) & (1 << offset)); } static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset, -- cgit v1.2.3 From 351f181f9134d71efd46ddf0c0abca31b58cd79b Mon Sep 17 00:00:00 2001 From: Chuansheng Liu Date: Thu, 25 Oct 2012 01:07:35 +0800 Subject: timers, sched: Correct the comments for tick_sched_timer() In the comments of function tick_sched_timer(), the sentence "timer->base->cpu_base->lock held" is not right. In function __run_hrtimer(), before call timer->function(), the cpu_base->lock has been unlocked. Signed-off-by: liu chuansheng Cc: fei.li@intel.com Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351098455.15558.1421.camel@cliu38-desktop-build Signed-off-by: Ingo Molnar --- kernel/time/tick-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index a4026088526..2bc73d3bf7f 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -794,7 +794,7 @@ void tick_check_idle(int cpu) #ifdef CONFIG_HIGH_RES_TIMERS /* * We rearm the timer until we get disabled by the idle code. - * Called with interrupts disabled and timer->base->cpu_base->lock held. + * Called with interrupts disabled. */ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) { -- cgit v1.2.3 From 9d85f21c94f7f7a84d0ba686c58aa6d9da58fdbb Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:29 +0200 Subject: sched: Track the runnable average on a per-task entity basis Instead of tracking averaging the load parented by a cfs_rq, we can track entity load directly. With the load for a given cfs_rq then being the sum of its children. To do this we represent the historical contribution to runnable average within each trailing 1024us of execution as the coefficients of a geometric series. We can express this for a given task t as: runnable_sum(t) = \Sum u_i * y^i, runnable_avg_period(t) = \Sum 1024 * y^i load(t) = weight_t * runnable_sum(t) / runnable_avg_period(t) Where: u_i is the usage in the last i`th 1024us period (approximately 1ms) ~ms and y is chosen such that y^k = 1/2. We currently choose k to be 32 which roughly translates to about a sched period. Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141506.372695337@google.com Signed-off-by: Ingo Molnar --- include/linux/sched.h | 13 +++++ kernel/sched/core.c | 5 ++ kernel/sched/debug.c | 4 ++ kernel/sched/fair.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+) diff --git a/include/linux/sched.h b/include/linux/sched.h index 0dd42a02df2..418fc6d8a4d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1095,6 +1095,16 @@ struct load_weight { unsigned long weight, inv_weight; }; +struct sched_avg { + /* + * These sums represent an infinite geometric series and so are bound + * above by 1024/(1-y). Thus we only need a u32 to store them for for all + * choices of y < 1-2^(-32)*1024. + */ + u32 runnable_avg_sum, runnable_avg_period; + u64 last_runnable_update; +}; + #ifdef CONFIG_SCHEDSTATS struct sched_statistics { u64 wait_start; @@ -1155,6 +1165,9 @@ struct sched_entity { /* rq "owned" by this entity/group: */ struct cfs_rq *my_q; #endif +#ifdef CONFIG_SMP + struct sched_avg avg; +#endif }; struct sched_rt_entity { diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 2d8927fda71..fd9d0859350 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1524,6 +1524,11 @@ static void __sched_fork(struct task_struct *p) p->se.vruntime = 0; INIT_LIST_HEAD(&p->se.group_node); +#ifdef CONFIG_SMP + p->se.avg.runnable_avg_period = 0; + p->se.avg.runnable_avg_sum = 0; +#endif + #ifdef CONFIG_SCHEDSTATS memset(&p->se.statistics, 0, sizeof(p->se.statistics)); #endif diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 6f79596e0ea..61f70979153 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -85,6 +85,10 @@ static void print_cfs_group_stats(struct seq_file *m, int cpu, struct task_group P(se->statistics.wait_count); #endif P(se->load.weight); +#ifdef CONFIG_SMP + P(se->avg.runnable_avg_sum); + P(se->avg.runnable_avg_period); +#endif #undef PN #undef P } diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 6b800a14b99..16d67f9b695 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -971,6 +971,126 @@ static inline void update_entity_shares_tick(struct cfs_rq *cfs_rq) } #endif /* CONFIG_FAIR_GROUP_SCHED */ +#ifdef CONFIG_SMP +/* + * Approximate: + * val * y^n, where y^32 ~= 0.5 (~1 scheduling period) + */ +static __always_inline u64 decay_load(u64 val, u64 n) +{ + for (; n && val; n--) { + val *= 4008; + val >>= 12; + } + + return val; +} + +/* + * We can represent the historical contribution to runnable average as the + * coefficients of a geometric series. To do this we sub-divide our runnable + * history into segments of approximately 1ms (1024us); label the segment that + * occurred N-ms ago p_N, with p_0 corresponding to the current period, e.g. + * + * [<- 1024us ->|<- 1024us ->|<- 1024us ->| ... + * p0 p1 p2 + * (now) (~1ms ago) (~2ms ago) + * + * Let u_i denote the fraction of p_i that the entity was runnable. + * + * We then designate the fractions u_i as our co-efficients, yielding the + * following representation of historical load: + * u_0 + u_1*y + u_2*y^2 + u_3*y^3 + ... + * + * We choose y based on the with of a reasonably scheduling period, fixing: + * y^32 = 0.5 + * + * This means that the contribution to load ~32ms ago (u_32) will be weighted + * approximately half as much as the contribution to load within the last ms + * (u_0). + * + * When a period "rolls over" and we have new u_0`, multiplying the previous + * sum again by y is sufficient to update: + * load_avg = u_0` + y*(u_0 + u_1*y + u_2*y^2 + ... ) + * = u_0 + u_1*y + u_2*y^2 + ... [re-labeling u_i --> u_{i+1}] + */ +static __always_inline int __update_entity_runnable_avg(u64 now, + struct sched_avg *sa, + int runnable) +{ + u64 delta; + int delta_w, decayed = 0; + + delta = now - sa->last_runnable_update; + /* + * This should only happen when time goes backwards, which it + * unfortunately does during sched clock init when we swap over to TSC. + */ + if ((s64)delta < 0) { + sa->last_runnable_update = now; + return 0; + } + + /* + * Use 1024ns as the unit of measurement since it's a reasonable + * approximation of 1us and fast to compute. + */ + delta >>= 10; + if (!delta) + return 0; + sa->last_runnable_update = now; + + /* delta_w is the amount already accumulated against our next period */ + delta_w = sa->runnable_avg_period % 1024; + if (delta + delta_w >= 1024) { + /* period roll-over */ + decayed = 1; + + /* + * Now that we know we're crossing a period boundary, figure + * out how much from delta we need to complete the current + * period and accrue it. + */ + delta_w = 1024 - delta_w; + BUG_ON(delta_w > delta); + do { + if (runnable) + sa->runnable_avg_sum += delta_w; + sa->runnable_avg_period += delta_w; + + /* + * Remainder of delta initiates a new period, roll over + * the previous. + */ + sa->runnable_avg_sum = + decay_load(sa->runnable_avg_sum, 1); + sa->runnable_avg_period = + decay_load(sa->runnable_avg_period, 1); + + delta -= delta_w; + /* New period is empty */ + delta_w = 1024; + } while (delta >= 1024); + } + + /* Remainder of delta accrued against u_0` */ + if (runnable) + sa->runnable_avg_sum += delta; + sa->runnable_avg_period += delta; + + return decayed; +} + +/* Update a sched_entity's runnable average */ +static inline void update_entity_load_avg(struct sched_entity *se) +{ + __update_entity_runnable_avg(rq_of(cfs_rq_of(se))->clock_task, &se->avg, + se->on_rq); +} +#else +static inline void update_entity_load_avg(struct sched_entity *se) {} +#endif + static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) { #ifdef CONFIG_SCHEDSTATS @@ -1097,6 +1217,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) */ update_curr(cfs_rq); update_cfs_load(cfs_rq, 0); + update_entity_load_avg(se); account_entity_enqueue(cfs_rq, se); update_cfs_shares(cfs_rq); @@ -1171,6 +1292,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) * Update run-time statistics of the 'current'. */ update_curr(cfs_rq); + update_entity_load_avg(se); update_stats_dequeue(cfs_rq, se); if (flags & DEQUEUE_SLEEP) { @@ -1340,6 +1462,8 @@ static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev) update_stats_wait_start(cfs_rq, prev); /* Put 'current' back into the tree. */ __enqueue_entity(cfs_rq, prev); + /* in !on_rq case, update occurred at dequeue */ + update_entity_load_avg(prev); } cfs_rq->curr = NULL; } @@ -1352,6 +1476,11 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued) */ update_curr(cfs_rq); + /* + * Ensure that runnable average is periodically updated. + */ + update_entity_load_avg(curr); + /* * Update share accounting for long-running entities. */ -- cgit v1.2.3 From 18bf2805d9b30cb823d4919b42cd230f59c7ce1f Mon Sep 17 00:00:00 2001 From: Ben Segall Date: Thu, 4 Oct 2012 12:51:20 +0200 Subject: sched: Maintain per-rq runnable averages Since runqueues do not have a corresponding sched_entity we instead embed a sched_avg structure directly. Signed-off-by: Ben Segall Reviewed-by: Paul Turner Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141506.442637130@google.com Signed-off-by: Ingo Molnar --- kernel/sched/debug.c | 10 ++++++++-- kernel/sched/fair.c | 18 ++++++++++++++++-- kernel/sched/sched.h | 2 ++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 61f70979153..4240abce411 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -61,14 +61,20 @@ static unsigned long nsec_low(unsigned long long nsec) static void print_cfs_group_stats(struct seq_file *m, int cpu, struct task_group *tg) { struct sched_entity *se = tg->se[cpu]; - if (!se) - return; #define P(F) \ SEQ_printf(m, " .%-30s: %lld\n", #F, (long long)F) #define PN(F) \ SEQ_printf(m, " .%-30s: %lld.%06ld\n", #F, SPLIT_NS((long long)F)) + if (!se) { + struct sched_avg *avg = &cpu_rq(cpu)->avg; + P(avg->runnable_avg_sum); + P(avg->runnable_avg_period); + return; + } + + PN(se->exec_start); PN(se->vruntime); PN(se->sum_exec_runtime); diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 16d67f9b695..8c5468fcf10 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1087,8 +1087,14 @@ static inline void update_entity_load_avg(struct sched_entity *se) __update_entity_runnable_avg(rq_of(cfs_rq_of(se))->clock_task, &se->avg, se->on_rq); } + +static inline void update_rq_runnable_avg(struct rq *rq, int runnable) +{ + __update_entity_runnable_avg(rq->clock_task, &rq->avg, runnable); +} #else static inline void update_entity_load_avg(struct sched_entity *se) {} +static inline void update_rq_runnable_avg(struct rq *rq, int runnable) {} #endif static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) @@ -2340,8 +2346,10 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) update_cfs_shares(cfs_rq); } - if (!se) + if (!se) { + update_rq_runnable_avg(rq, rq->nr_running); inc_nr_running(rq); + } hrtick_update(rq); } @@ -2399,8 +2407,10 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags) update_cfs_shares(cfs_rq); } - if (!se) + if (!se) { dec_nr_running(rq); + update_rq_runnable_avg(rq, 1); + } hrtick_update(rq); } @@ -4586,6 +4596,8 @@ void idle_balance(int this_cpu, struct rq *this_rq) if (this_rq->avg_idle < sysctl_sched_migration_cost) return; + update_rq_runnable_avg(this_rq, 1); + /* * Drop the rq->lock, but keep IRQ/preempt disabled. */ @@ -5083,6 +5095,8 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr, int queued) cfs_rq = cfs_rq_of(se); entity_tick(cfs_rq, se, queued); } + + update_rq_runnable_avg(rq, 1); } /* diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 7a7db09cfab..14b57196871 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -467,6 +467,8 @@ struct rq { #ifdef CONFIG_SMP struct llist_head wake_list; #endif + + struct sched_avg avg; }; static inline int cpu_of(struct rq *rq) -- cgit v1.2.3 From 2dac754e10a5d41d94d2d2365c0345d4f215a266 Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:30 +0200 Subject: sched: Aggregate load contributed by task entities on parenting cfs_rq For a given task t, we can compute its contribution to load as: task_load(t) = runnable_avg(t) * weight(t) On a parenting cfs_rq we can then aggregate: runnable_load(cfs_rq) = \Sum task_load(t), for all runnable children t Maintain this bottom up, with task entities adding their contributed load to the parenting cfs_rq sum. When a task entity's load changes we add the same delta to the maintained sum. Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141506.514678907@google.com Signed-off-by: Ingo Molnar --- include/linux/sched.h | 1 + kernel/sched/debug.c | 3 +++ kernel/sched/fair.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- kernel/sched/sched.h | 10 +++++++++- 4 files changed, 60 insertions(+), 5 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 418fc6d8a4d..81d8b1ba410 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1103,6 +1103,7 @@ struct sched_avg { */ u32 runnable_avg_sum, runnable_avg_period; u64 last_runnable_update; + unsigned long load_avg_contrib; }; #ifdef CONFIG_SCHEDSTATS diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 4240abce411..c953a89f94a 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -94,6 +94,7 @@ static void print_cfs_group_stats(struct seq_file *m, int cpu, struct task_group #ifdef CONFIG_SMP P(se->avg.runnable_avg_sum); P(se->avg.runnable_avg_period); + P(se->avg.load_avg_contrib); #endif #undef PN #undef P @@ -224,6 +225,8 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) cfs_rq->load_contribution); SEQ_printf(m, " .%-30s: %d\n", "load_tg", atomic_read(&cfs_rq->tg->load_weight)); + SEQ_printf(m, " .%-30s: %lld\n", "runnable_load_avg", + cfs_rq->runnable_load_avg); #endif print_cfs_group_stats(m, cpu, cfs_rq->tg); diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 8c5468fcf10..77af759e567 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1081,20 +1081,63 @@ static __always_inline int __update_entity_runnable_avg(u64 now, return decayed; } +/* Compute the current contribution to load_avg by se, return any delta */ +static long __update_entity_load_avg_contrib(struct sched_entity *se) +{ + long old_contrib = se->avg.load_avg_contrib; + + if (!entity_is_task(se)) + return 0; + + se->avg.load_avg_contrib = div64_u64(se->avg.runnable_avg_sum * + se->load.weight, + se->avg.runnable_avg_period + 1); + + return se->avg.load_avg_contrib - old_contrib; +} + /* Update a sched_entity's runnable average */ static inline void update_entity_load_avg(struct sched_entity *se) { - __update_entity_runnable_avg(rq_of(cfs_rq_of(se))->clock_task, &se->avg, - se->on_rq); + struct cfs_rq *cfs_rq = cfs_rq_of(se); + long contrib_delta; + + if (!__update_entity_runnable_avg(rq_of(cfs_rq)->clock_task, &se->avg, + se->on_rq)) + return; + + contrib_delta = __update_entity_load_avg_contrib(se); + if (se->on_rq) + cfs_rq->runnable_load_avg += contrib_delta; } static inline void update_rq_runnable_avg(struct rq *rq, int runnable) { __update_entity_runnable_avg(rq->clock_task, &rq->avg, runnable); } + +/* Add the load generated by se into cfs_rq's child load-average */ +static inline void enqueue_entity_load_avg(struct cfs_rq *cfs_rq, + struct sched_entity *se) +{ + update_entity_load_avg(se); + cfs_rq->runnable_load_avg += se->avg.load_avg_contrib; +} + +/* Remove se's load from this cfs_rq child load-average */ +static inline void dequeue_entity_load_avg(struct cfs_rq *cfs_rq, + struct sched_entity *se) +{ + update_entity_load_avg(se); + cfs_rq->runnable_load_avg -= se->avg.load_avg_contrib; +} #else static inline void update_entity_load_avg(struct sched_entity *se) {} static inline void update_rq_runnable_avg(struct rq *rq, int runnable) {} +static inline void enqueue_entity_load_avg(struct cfs_rq *cfs_rq, + struct sched_entity *se) {} +static inline void dequeue_entity_load_avg(struct cfs_rq *cfs_rq, + struct sched_entity *se) {} #endif static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) @@ -1223,7 +1266,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) */ update_curr(cfs_rq); update_cfs_load(cfs_rq, 0); - update_entity_load_avg(se); + enqueue_entity_load_avg(cfs_rq, se); account_entity_enqueue(cfs_rq, se); update_cfs_shares(cfs_rq); @@ -1298,7 +1341,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) * Update run-time statistics of the 'current'. */ update_curr(cfs_rq); - update_entity_load_avg(se); + dequeue_entity_load_avg(cfs_rq, se); update_stats_dequeue(cfs_rq, se); if (flags & DEQUEUE_SLEEP) { diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 14b57196871..e6539736af5 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -222,6 +222,15 @@ struct cfs_rq { unsigned int nr_spread_over; #endif +#ifdef CONFIG_SMP + /* + * CFS Load tracking + * Under CFS, load is tracked on a per-entity basis and aggregated up. + * This allows for the description of both thread and group usage (in + * the FAIR_GROUP_SCHED case). + */ + u64 runnable_load_avg; +#endif #ifdef CONFIG_FAIR_GROUP_SCHED struct rq *rq; /* cpu runqueue to which this cfs_rq is attached */ @@ -1214,4 +1223,3 @@ static inline u64 irq_time_read(int cpu) } #endif /* CONFIG_64BIT */ #endif /* CONFIG_IRQ_TIME_ACCOUNTING */ - -- cgit v1.2.3 From 9ee474f55664ff63111c843099d365e7ecffb56f Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:30 +0200 Subject: sched: Maintain the load contribution of blocked entities We are currently maintaining: runnable_load(cfs_rq) = \Sum task_load(t) For all running children t of cfs_rq. While this can be naturally updated for tasks in a runnable state (as they are scheduled); this does not account for the load contributed by blocked task entities. This can be solved by introducing a separate accounting for blocked load: blocked_load(cfs_rq) = \Sum runnable(b) * weight(b) Obviously we do not want to iterate over all blocked entities to account for their decay, we instead observe that: runnable_load(t) = \Sum p_i*y^i and that to account for an additional idle period we only need to compute: y*runnable_load(t). This means that we can compute all blocked entities at once by evaluating: blocked_load(cfs_rq)` = y * blocked_load(cfs_rq) Finally we maintain a decay counter so that when a sleeping entity re-awakens we can determine how much of its load should be removed from the blocked sum. Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141506.585389902@google.com Signed-off-by: Ingo Molnar --- include/linux/sched.h | 1 + kernel/sched/core.c | 1 - kernel/sched/debug.c | 3 ++ kernel/sched/fair.c | 128 +++++++++++++++++++++++++++++++++++++++++++++----- kernel/sched/sched.h | 4 +- 5 files changed, 122 insertions(+), 15 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 81d8b1ba410..b1831accfd8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1103,6 +1103,7 @@ struct sched_avg { */ u32 runnable_avg_sum, runnable_avg_period; u64 last_runnable_update; + s64 decay_count; unsigned long load_avg_contrib; }; diff --git a/kernel/sched/core.c b/kernel/sched/core.c index fd9d0859350..00898f1fb69 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1528,7 +1528,6 @@ static void __sched_fork(struct task_struct *p) p->se.avg.runnable_avg_period = 0; p->se.avg.runnable_avg_sum = 0; #endif - #ifdef CONFIG_SCHEDSTATS memset(&p->se.statistics, 0, sizeof(p->se.statistics)); #endif diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index c953a89f94a..2d2e2b3c1be 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -95,6 +95,7 @@ static void print_cfs_group_stats(struct seq_file *m, int cpu, struct task_group P(se->avg.runnable_avg_sum); P(se->avg.runnable_avg_period); P(se->avg.load_avg_contrib); + P(se->avg.decay_count); #endif #undef PN #undef P @@ -227,6 +228,8 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) atomic_read(&cfs_rq->tg->load_weight)); SEQ_printf(m, " .%-30s: %lld\n", "runnable_load_avg", cfs_rq->runnable_load_avg); + SEQ_printf(m, " .%-30s: %lld\n", "blocked_load_avg", + cfs_rq->blocked_load_avg); #endif print_cfs_group_stats(m, cpu, cfs_rq->tg); diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 77af759e567..83194175e84 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -259,6 +259,8 @@ static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp) return grp->my_q; } +static void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq); + static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq) { if (!cfs_rq->on_list) { @@ -278,6 +280,8 @@ static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq) } cfs_rq->on_list = 1; + /* We should have no load, but we need to update last_decay. */ + update_cfs_rq_blocked_load(cfs_rq); } } @@ -1081,6 +1085,20 @@ static __always_inline int __update_entity_runnable_avg(u64 now, return decayed; } +/* Synchronize an entity's decay with its parenting cfs_rq.*/ +static inline void __synchronize_entity_decay(struct sched_entity *se) +{ + struct cfs_rq *cfs_rq = cfs_rq_of(se); + u64 decays = atomic64_read(&cfs_rq->decay_counter); + + decays -= se->avg.decay_count; + if (!decays) + return; + + se->avg.load_avg_contrib = decay_load(se->avg.load_avg_contrib, decays); + se->avg.decay_count = 0; +} + /* Compute the current contribution to load_avg by se, return any delta */ static long __update_entity_load_avg_contrib(struct sched_entity *se) { @@ -1096,8 +1114,18 @@ static long __update_entity_load_avg_contrib(struct sched_entity *se) return se->avg.load_avg_contrib - old_contrib; } +static inline void subtract_blocked_load_contrib(struct cfs_rq *cfs_rq, + long load_contrib) +{ + if (likely(load_contrib < cfs_rq->blocked_load_avg)) + cfs_rq->blocked_load_avg -= load_contrib; + else + cfs_rq->blocked_load_avg = 0; +} + /* Update a sched_entity's runnable average */ -static inline void update_entity_load_avg(struct sched_entity *se) +static inline void update_entity_load_avg(struct sched_entity *se, + int update_cfs_rq) { struct cfs_rq *cfs_rq = cfs_rq_of(se); long contrib_delta; @@ -1107,8 +1135,34 @@ static inline void update_entity_load_avg(struct sched_entity *se) return; contrib_delta = __update_entity_load_avg_contrib(se); + + if (!update_cfs_rq) + return; + if (se->on_rq) cfs_rq->runnable_load_avg += contrib_delta; + else + subtract_blocked_load_contrib(cfs_rq, -contrib_delta); +} + +/* + * Decay the load contributed by all blocked children and account this so that + * their contribution may appropriately discounted when they wake up. + */ +static void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq) +{ + u64 now = rq_of(cfs_rq)->clock_task >> 20; + u64 decays; + + decays = now - cfs_rq->last_decay; + if (!decays) + return; + + cfs_rq->blocked_load_avg = decay_load(cfs_rq->blocked_load_avg, + decays); + atomic64_add(decays, &cfs_rq->decay_counter); + + cfs_rq->last_decay = now; } static inline void update_rq_runnable_avg(struct rq *rq, int runnable) @@ -1118,26 +1172,53 @@ static inline void update_rq_runnable_avg(struct rq *rq, int runnable) /* Add the load generated by se into cfs_rq's child load-average */ static inline void enqueue_entity_load_avg(struct cfs_rq *cfs_rq, - struct sched_entity *se) + struct sched_entity *se, + int wakeup) { - update_entity_load_avg(se); + /* we track migrations using entity decay_count == 0 */ + if (unlikely(!se->avg.decay_count)) { + se->avg.last_runnable_update = rq_of(cfs_rq)->clock_task; + wakeup = 0; + } else { + __synchronize_entity_decay(se); + } + + if (wakeup) + subtract_blocked_load_contrib(cfs_rq, se->avg.load_avg_contrib); + + update_entity_load_avg(se, 0); cfs_rq->runnable_load_avg += se->avg.load_avg_contrib; + update_cfs_rq_blocked_load(cfs_rq); } -/* Remove se's load from this cfs_rq child load-average */ +/* + * Remove se's load from this cfs_rq child load-average, if the entity is + * transitioning to a blocked state we track its projected decay using + * blocked_load_avg. + */ static inline void dequeue_entity_load_avg(struct cfs_rq *cfs_rq, - struct sched_entity *se) + struct sched_entity *se, + int sleep) { - update_entity_load_avg(se); + update_entity_load_avg(se, 1); + cfs_rq->runnable_load_avg -= se->avg.load_avg_contrib; + if (sleep) { + cfs_rq->blocked_load_avg += se->avg.load_avg_contrib; + se->avg.decay_count = atomic64_read(&cfs_rq->decay_counter); + } /* migrations, e.g. sleep=0 leave decay_count == 0 */ } #else -static inline void update_entity_load_avg(struct sched_entity *se) {} +static inline void update_entity_load_avg(struct sched_entity *se, + int update_cfs_rq) {} static inline void update_rq_runnable_avg(struct rq *rq, int runnable) {} static inline void enqueue_entity_load_avg(struct cfs_rq *cfs_rq, - struct sched_entity *se) {} + struct sched_entity *se, + int wakeup) {} static inline void dequeue_entity_load_avg(struct cfs_rq *cfs_rq, - struct sched_entity *se) {} + struct sched_entity *se, + int sleep) {} +static inline void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq) {} #endif static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) @@ -1266,7 +1347,7 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) */ update_curr(cfs_rq); update_cfs_load(cfs_rq, 0); - enqueue_entity_load_avg(cfs_rq, se); + enqueue_entity_load_avg(cfs_rq, se, flags & ENQUEUE_WAKEUP); account_entity_enqueue(cfs_rq, se); update_cfs_shares(cfs_rq); @@ -1341,7 +1422,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) * Update run-time statistics of the 'current'. */ update_curr(cfs_rq); - dequeue_entity_load_avg(cfs_rq, se); + dequeue_entity_load_avg(cfs_rq, se, flags & DEQUEUE_SLEEP); update_stats_dequeue(cfs_rq, se); if (flags & DEQUEUE_SLEEP) { @@ -1512,7 +1593,7 @@ static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev) /* Put 'current' back into the tree. */ __enqueue_entity(cfs_rq, prev); /* in !on_rq case, update occurred at dequeue */ - update_entity_load_avg(prev); + update_entity_load_avg(prev, 1); } cfs_rq->curr = NULL; } @@ -1528,7 +1609,8 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued) /* * Ensure that runnable average is periodically updated. */ - update_entity_load_avg(curr); + update_entity_load_avg(curr, 1); + update_cfs_rq_blocked_load(cfs_rq); /* * Update share accounting for long-running entities. @@ -2387,6 +2469,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) update_cfs_load(cfs_rq, 0); update_cfs_shares(cfs_rq); + update_entity_load_avg(se, 1); } if (!se) { @@ -2448,6 +2531,7 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags) update_cfs_load(cfs_rq, 0); update_cfs_shares(cfs_rq); + update_entity_load_avg(se, 1); } if (!se) { @@ -3498,6 +3582,7 @@ static int update_shares_cpu(struct task_group *tg, int cpu) update_rq_clock(rq); update_cfs_load(cfs_rq, 1); + update_cfs_rq_blocked_load(cfs_rq); /* * We need to update shares after updating tg->load_weight in @@ -5232,6 +5317,20 @@ static void switched_from_fair(struct rq *rq, struct task_struct *p) place_entity(cfs_rq, se, 0); se->vruntime -= cfs_rq->min_vruntime; } + +#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) + /* + * Remove our load from contribution when we leave sched_fair + * and ensure we don't carry in an old decay_count if we + * switch back. + */ + if (p->se.avg.decay_count) { + struct cfs_rq *cfs_rq = cfs_rq_of(&p->se); + __synchronize_entity_decay(&p->se); + subtract_blocked_load_contrib(cfs_rq, + p->se.avg.load_avg_contrib); + } +#endif } /* @@ -5278,6 +5377,9 @@ void init_cfs_rq(struct cfs_rq *cfs_rq) #ifndef CONFIG_64BIT cfs_rq->min_vruntime_copy = cfs_rq->min_vruntime; #endif +#if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) + atomic64_set(&cfs_rq->decay_counter, 1); +#endif } #ifdef CONFIG_FAIR_GROUP_SCHED diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index e6539736af5..664ff39195f 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -229,7 +229,9 @@ struct cfs_rq { * This allows for the description of both thread and group usage (in * the FAIR_GROUP_SCHED case). */ - u64 runnable_load_avg; + u64 runnable_load_avg, blocked_load_avg; + atomic64_t decay_counter; + u64 last_decay; #endif #ifdef CONFIG_FAIR_GROUP_SCHED struct rq *rq; /* cpu runqueue to which this cfs_rq is attached */ -- cgit v1.2.3 From 0a74bef8bed18dc6889e9bc37ea1050a50c86c89 Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:30 +0200 Subject: sched: Add an rq migration call-back to sched_class Since we are now doing bottom up load accumulation we need explicit notification when a task has been re-parented so that the old hierarchy can be updated. Adds: migrate_task_rq(struct task_struct *p, int next_cpu) (The alternative is to do this out of __set_task_cpu, but it was suggested that this would be a cleaner encapsulation.) Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141506.660023400@google.com Signed-off-by: Ingo Molnar --- include/linux/sched.h | 1 + kernel/sched/core.c | 2 ++ kernel/sched/fair.c | 12 ++++++++++++ 3 files changed, 15 insertions(+) diff --git a/include/linux/sched.h b/include/linux/sched.h index b1831accfd8..e483ccb08ce 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1061,6 +1061,7 @@ struct sched_class { #ifdef CONFIG_SMP int (*select_task_rq)(struct task_struct *p, int sd_flag, int flags); + void (*migrate_task_rq)(struct task_struct *p, int next_cpu); void (*pre_schedule) (struct rq *this_rq, struct task_struct *task); void (*post_schedule) (struct rq *this_rq); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 00898f1fb69..f26860074ef 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -952,6 +952,8 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) trace_sched_migrate_task(p, new_cpu); if (task_cpu(p) != new_cpu) { + if (p->sched_class->migrate_task_rq) + p->sched_class->migrate_task_rq(p, new_cpu); p->se.nr_migrations++; perf_sw_event(PERF_COUNT_SW_CPU_MIGRATIONS, 1, NULL, 0); } diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 83194175e84..5e602e6ba0c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3047,6 +3047,17 @@ unlock: return new_cpu; } + +/* + * Called immediately before a task is migrated to a new cpu; task_cpu(p) and + * cfs_rq_of(p) references at time of call are still valid and identify the + * previous cpu. However, the caller only guarantees p->pi_lock is held; no + * other assumptions, including the state of rq->lock, should be made. + */ +static void +migrate_task_rq_fair(struct task_struct *p, int next_cpu) +{ +} #endif /* CONFIG_SMP */ static unsigned long @@ -5607,6 +5618,7 @@ const struct sched_class fair_sched_class = { #ifdef CONFIG_SMP .select_task_rq = select_task_rq_fair, + .migrate_task_rq = migrate_task_rq_fair, .rq_online = rq_online_fair, .rq_offline = rq_offline_fair, -- cgit v1.2.3 From aff3e498844441fa71c5ee1bbc470e1dff9548d9 Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:30 +0200 Subject: sched: Account for blocked load waking back up When a running entity blocks we migrate its tracked load to cfs_rq->blocked_runnable_avg. In the sleep case this occurs while holding rq->lock and so is a natural transition. Wake-ups however, are potentially asynchronous in the presence of migration and so special care must be taken. We use an atomic counter to track such migrated load, taking care to match this with the previously introduced decay counters so that we don't migrate too much load. Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141506.726077467@google.com Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 100 ++++++++++++++++++++++++++++++++++++++++----------- kernel/sched/sched.h | 2 +- 2 files changed, 81 insertions(+), 21 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 5e602e6ba0c..74dc29ba1ad 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -259,7 +259,8 @@ static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp) return grp->my_q; } -static void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq); +static void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq, + int force_update); static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq) { @@ -281,7 +282,7 @@ static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq) cfs_rq->on_list = 1; /* We should have no load, but we need to update last_decay. */ - update_cfs_rq_blocked_load(cfs_rq); + update_cfs_rq_blocked_load(cfs_rq, 0); } } @@ -1086,17 +1087,19 @@ static __always_inline int __update_entity_runnable_avg(u64 now, } /* Synchronize an entity's decay with its parenting cfs_rq.*/ -static inline void __synchronize_entity_decay(struct sched_entity *se) +static inline u64 __synchronize_entity_decay(struct sched_entity *se) { struct cfs_rq *cfs_rq = cfs_rq_of(se); u64 decays = atomic64_read(&cfs_rq->decay_counter); decays -= se->avg.decay_count; if (!decays) - return; + return 0; se->avg.load_avg_contrib = decay_load(se->avg.load_avg_contrib, decays); se->avg.decay_count = 0; + + return decays; } /* Compute the current contribution to load_avg by se, return any delta */ @@ -1149,20 +1152,26 @@ static inline void update_entity_load_avg(struct sched_entity *se, * Decay the load contributed by all blocked children and account this so that * their contribution may appropriately discounted when they wake up. */ -static void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq) +static void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq, int force_update) { u64 now = rq_of(cfs_rq)->clock_task >> 20; u64 decays; decays = now - cfs_rq->last_decay; - if (!decays) + if (!decays && !force_update) return; - cfs_rq->blocked_load_avg = decay_load(cfs_rq->blocked_load_avg, - decays); - atomic64_add(decays, &cfs_rq->decay_counter); + if (atomic64_read(&cfs_rq->removed_load)) { + u64 removed_load = atomic64_xchg(&cfs_rq->removed_load, 0); + subtract_blocked_load_contrib(cfs_rq, removed_load); + } - cfs_rq->last_decay = now; + if (decays) { + cfs_rq->blocked_load_avg = decay_load(cfs_rq->blocked_load_avg, + decays); + atomic64_add(decays, &cfs_rq->decay_counter); + cfs_rq->last_decay = now; + } } static inline void update_rq_runnable_avg(struct rq *rq, int runnable) @@ -1175,20 +1184,42 @@ static inline void enqueue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se, int wakeup) { - /* we track migrations using entity decay_count == 0 */ - if (unlikely(!se->avg.decay_count)) { + /* + * We track migrations using entity decay_count <= 0, on a wake-up + * migration we use a negative decay count to track the remote decays + * accumulated while sleeping. + */ + if (unlikely(se->avg.decay_count <= 0)) { se->avg.last_runnable_update = rq_of(cfs_rq)->clock_task; + if (se->avg.decay_count) { + /* + * In a wake-up migration we have to approximate the + * time sleeping. This is because we can't synchronize + * clock_task between the two cpus, and it is not + * guaranteed to be read-safe. Instead, we can + * approximate this using our carried decays, which are + * explicitly atomically readable. + */ + se->avg.last_runnable_update -= (-se->avg.decay_count) + << 20; + update_entity_load_avg(se, 0); + /* Indicate that we're now synchronized and on-rq */ + se->avg.decay_count = 0; + } wakeup = 0; } else { __synchronize_entity_decay(se); } - if (wakeup) + /* migrated tasks did not contribute to our blocked load */ + if (wakeup) { subtract_blocked_load_contrib(cfs_rq, se->avg.load_avg_contrib); + update_entity_load_avg(se, 0); + } - update_entity_load_avg(se, 0); cfs_rq->runnable_load_avg += se->avg.load_avg_contrib; - update_cfs_rq_blocked_load(cfs_rq); + /* we force update consideration on load-balancer moves */ + update_cfs_rq_blocked_load(cfs_rq, !wakeup); } /* @@ -1201,6 +1232,8 @@ static inline void dequeue_entity_load_avg(struct cfs_rq *cfs_rq, int sleep) { update_entity_load_avg(se, 1); + /* we force update consideration on load-balancer moves */ + update_cfs_rq_blocked_load(cfs_rq, !sleep); cfs_rq->runnable_load_avg -= se->avg.load_avg_contrib; if (sleep) { @@ -1218,7 +1251,8 @@ static inline void enqueue_entity_load_avg(struct cfs_rq *cfs_rq, static inline void dequeue_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep) {} -static inline void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq) {} +static inline void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq, + int force_update) {} #endif static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) @@ -1610,7 +1644,7 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued) * Ensure that runnable average is periodically updated. */ update_entity_load_avg(curr, 1); - update_cfs_rq_blocked_load(cfs_rq); + update_cfs_rq_blocked_load(cfs_rq, 1); /* * Update share accounting for long-running entities. @@ -3057,6 +3091,19 @@ unlock: static void migrate_task_rq_fair(struct task_struct *p, int next_cpu) { + struct sched_entity *se = &p->se; + struct cfs_rq *cfs_rq = cfs_rq_of(se); + + /* + * Load tracking: accumulate removed load so that it can be processed + * when we next update owning cfs_rq under rq->lock. Tasks contribute + * to blocked load iff they have a positive decay-count. It can never + * be negative here since on-rq tasks have decay-count == 0. + */ + if (se->avg.decay_count) { + se->avg.decay_count = -__synchronize_entity_decay(se); + atomic64_add(se->avg.load_avg_contrib, &cfs_rq->removed_load); + } } #endif /* CONFIG_SMP */ @@ -3593,7 +3640,7 @@ static int update_shares_cpu(struct task_group *tg, int cpu) update_rq_clock(rq); update_cfs_load(cfs_rq, 1); - update_cfs_rq_blocked_load(cfs_rq); + update_cfs_rq_blocked_load(cfs_rq, 1); /* * We need to update shares after updating tg->load_weight in @@ -5390,12 +5437,14 @@ void init_cfs_rq(struct cfs_rq *cfs_rq) #endif #if defined(CONFIG_FAIR_GROUP_SCHED) && defined(CONFIG_SMP) atomic64_set(&cfs_rq->decay_counter, 1); + atomic64_set(&cfs_rq->removed_load, 0); #endif } #ifdef CONFIG_FAIR_GROUP_SCHED static void task_move_group_fair(struct task_struct *p, int on_rq) { + struct cfs_rq *cfs_rq; /* * If the task was not on the rq at the time of this cgroup movement * it must have been asleep, sleeping tasks keep their ->vruntime @@ -5427,8 +5476,19 @@ static void task_move_group_fair(struct task_struct *p, int on_rq) if (!on_rq) p->se.vruntime -= cfs_rq_of(&p->se)->min_vruntime; set_task_rq(p, task_cpu(p)); - if (!on_rq) - p->se.vruntime += cfs_rq_of(&p->se)->min_vruntime; + if (!on_rq) { + cfs_rq = cfs_rq_of(&p->se); + p->se.vruntime += cfs_rq->min_vruntime; +#ifdef CONFIG_SMP + /* + * migrate_task_rq_fair() will have removed our previous + * contribution, but we must synchronize for ongoing future + * decay. + */ + p->se.avg.decay_count = atomic64_read(&cfs_rq->decay_counter); + cfs_rq->blocked_load_avg += p->se.avg.load_avg_contrib; +#endif + } } void free_fair_sched_group(struct task_group *tg) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 664ff39195f..30236ab4edc 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -230,7 +230,7 @@ struct cfs_rq { * the FAIR_GROUP_SCHED case). */ u64 runnable_load_avg, blocked_load_avg; - atomic64_t decay_counter; + atomic64_t decay_counter, removed_load; u64 last_decay; #endif #ifdef CONFIG_FAIR_GROUP_SCHED -- cgit v1.2.3 From c566e8e9e44b72b53091da20e2dedefc730f2ee2 Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:30 +0200 Subject: sched: Aggregate total task_group load Maintain a global running sum of the average load seen on each cfs_rq belonging to each task group so that it may be used in calculating an appropriate shares:weight distribution. Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141506.792901086@google.com Signed-off-by: Ingo Molnar --- kernel/sched/debug.c | 4 ++++ kernel/sched/fair.c | 22 ++++++++++++++++++++++ kernel/sched/sched.h | 4 ++++ 3 files changed, 30 insertions(+) diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 2d2e2b3c1be..290892361a0 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -230,6 +230,10 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) cfs_rq->runnable_load_avg); SEQ_printf(m, " .%-30s: %lld\n", "blocked_load_avg", cfs_rq->blocked_load_avg); + SEQ_printf(m, " .%-30s: %ld\n", "tg_load_avg", + atomic64_read(&cfs_rq->tg->load_avg)); + SEQ_printf(m, " .%-30s: %lld\n", "tg_load_contrib", + cfs_rq->tg_load_contrib); #endif print_cfs_group_stats(m, cpu, cfs_rq->tg); diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 74dc29ba1ad..db788222f19 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1102,6 +1102,26 @@ static inline u64 __synchronize_entity_decay(struct sched_entity *se) return decays; } +#ifdef CONFIG_FAIR_GROUP_SCHED +static inline void __update_cfs_rq_tg_load_contrib(struct cfs_rq *cfs_rq, + int force_update) +{ + struct task_group *tg = cfs_rq->tg; + s64 tg_contrib; + + tg_contrib = cfs_rq->runnable_load_avg + cfs_rq->blocked_load_avg; + tg_contrib -= cfs_rq->tg_load_contrib; + + if (force_update || abs64(tg_contrib) > cfs_rq->tg_load_contrib / 8) { + atomic64_add(tg_contrib, &tg->load_avg); + cfs_rq->tg_load_contrib += tg_contrib; + } +} +#else +static inline void __update_cfs_rq_tg_load_contrib(struct cfs_rq *cfs_rq, + int force_update) {} +#endif + /* Compute the current contribution to load_avg by se, return any delta */ static long __update_entity_load_avg_contrib(struct sched_entity *se) { @@ -1172,6 +1192,8 @@ static void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq, int force_update) atomic64_add(decays, &cfs_rq->decay_counter); cfs_rq->last_decay = now; } + + __update_cfs_rq_tg_load_contrib(cfs_rq, force_update); } static inline void update_rq_runnable_avg(struct rq *rq, int runnable) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 30236ab4edc..924a9909488 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -112,6 +112,7 @@ struct task_group { unsigned long shares; atomic_t load_weight; + atomic64_t load_avg; #endif #ifdef CONFIG_RT_GROUP_SCHED @@ -232,6 +233,9 @@ struct cfs_rq { u64 runnable_load_avg, blocked_load_avg; atomic64_t decay_counter, removed_load; u64 last_decay; +#ifdef CONFIG_FAIR_GROUP_SCHED + u64 tg_load_contrib; +#endif #endif #ifdef CONFIG_FAIR_GROUP_SCHED struct rq *rq; /* cpu runqueue to which this cfs_rq is attached */ -- cgit v1.2.3 From 8165e145ceb62fc338e099c9b12b3239c83d2f8e Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:31 +0200 Subject: sched: Compute load contribution by a group entity Unlike task entities who have a fixed weight, group entities instead own a fraction of their parenting task_group's shares as their contributed weight. Compute this fraction so that we can correctly account hierarchies and shared entity nodes. Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141506.855074415@google.com Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index db788222f19..e20cb2693ef 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1117,22 +1117,43 @@ static inline void __update_cfs_rq_tg_load_contrib(struct cfs_rq *cfs_rq, cfs_rq->tg_load_contrib += tg_contrib; } } + +static inline void __update_group_entity_contrib(struct sched_entity *se) +{ + struct cfs_rq *cfs_rq = group_cfs_rq(se); + struct task_group *tg = cfs_rq->tg; + u64 contrib; + + contrib = cfs_rq->tg_load_contrib * tg->shares; + se->avg.load_avg_contrib = div64_u64(contrib, + atomic64_read(&tg->load_avg) + 1); +} #else static inline void __update_cfs_rq_tg_load_contrib(struct cfs_rq *cfs_rq, int force_update) {} +static inline void __update_group_entity_contrib(struct sched_entity *se) {} #endif +static inline void __update_task_entity_contrib(struct sched_entity *se) +{ + u32 contrib; + + /* avoid overflowing a 32-bit type w/ SCHED_LOAD_SCALE */ + contrib = se->avg.runnable_avg_sum * scale_load_down(se->load.weight); + contrib /= (se->avg.runnable_avg_period + 1); + se->avg.load_avg_contrib = scale_load(contrib); +} + /* Compute the current contribution to load_avg by se, return any delta */ static long __update_entity_load_avg_contrib(struct sched_entity *se) { long old_contrib = se->avg.load_avg_contrib; - if (!entity_is_task(se)) - return 0; - - se->avg.load_avg_contrib = div64_u64(se->avg.runnable_avg_sum * - se->load.weight, - se->avg.runnable_avg_period + 1); + if (entity_is_task(se)) { + __update_task_entity_contrib(se); + } else { + __update_group_entity_contrib(se); + } return se->avg.load_avg_contrib - old_contrib; } -- cgit v1.2.3 From bb17f65571e97a7ec0297571fb1154fbd107ad00 Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:31 +0200 Subject: sched: Normalize tg load contributions against runnable time Entities of equal weight should receive equitable distribution of cpu time. This is challenging in the case of a task_group's shares as execution may be occurring on multiple cpus simultaneously. To handle this we divide up the shares into weights proportionate with the load on each cfs_rq. This does not however, account for the fact that the sum of the parts may be less than one cpu and so we need to normalize: load(tg) = min(runnable_avg(tg), 1) * tg->shares Where runnable_avg is the aggregate time in which the task_group had runnable children. Signed-off-by: Paul Turner Reviewed-by: Ben Segall . Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141506.930124292@google.com Signed-off-by: Ingo Molnar --- kernel/sched/debug.c | 4 ++++ kernel/sched/fair.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/sched/sched.h | 2 ++ 3 files changed, 62 insertions(+) diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 290892361a0..71b0ea325e9 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -234,6 +234,10 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) atomic64_read(&cfs_rq->tg->load_avg)); SEQ_printf(m, " .%-30s: %lld\n", "tg_load_contrib", cfs_rq->tg_load_contrib); + SEQ_printf(m, " .%-30s: %d\n", "tg_runnable_contrib", + cfs_rq->tg_runnable_contrib); + SEQ_printf(m, " .%-30s: %d\n", "tg->runnable_avg", + atomic_read(&cfs_rq->tg->runnable_avg)); #endif print_cfs_group_stats(m, cpu, cfs_rq->tg); diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index e20cb2693ef..9e49722da03 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1118,19 +1118,73 @@ static inline void __update_cfs_rq_tg_load_contrib(struct cfs_rq *cfs_rq, } } +/* + * Aggregate cfs_rq runnable averages into an equivalent task_group + * representation for computing load contributions. + */ +static inline void __update_tg_runnable_avg(struct sched_avg *sa, + struct cfs_rq *cfs_rq) +{ + struct task_group *tg = cfs_rq->tg; + long contrib; + + /* The fraction of a cpu used by this cfs_rq */ + contrib = div_u64(sa->runnable_avg_sum << NICE_0_SHIFT, + sa->runnable_avg_period + 1); + contrib -= cfs_rq->tg_runnable_contrib; + + if (abs(contrib) > cfs_rq->tg_runnable_contrib / 64) { + atomic_add(contrib, &tg->runnable_avg); + cfs_rq->tg_runnable_contrib += contrib; + } +} + static inline void __update_group_entity_contrib(struct sched_entity *se) { struct cfs_rq *cfs_rq = group_cfs_rq(se); struct task_group *tg = cfs_rq->tg; + int runnable_avg; + u64 contrib; contrib = cfs_rq->tg_load_contrib * tg->shares; se->avg.load_avg_contrib = div64_u64(contrib, atomic64_read(&tg->load_avg) + 1); + + /* + * For group entities we need to compute a correction term in the case + * that they are consuming <1 cpu so that we would contribute the same + * load as a task of equal weight. + * + * Explicitly co-ordinating this measurement would be expensive, but + * fortunately the sum of each cpus contribution forms a usable + * lower-bound on the true value. + * + * Consider the aggregate of 2 contributions. Either they are disjoint + * (and the sum represents true value) or they are disjoint and we are + * understating by the aggregate of their overlap. + * + * Extending this to N cpus, for a given overlap, the maximum amount we + * understand is then n_i(n_i+1)/2 * w_i where n_i is the number of + * cpus that overlap for this interval and w_i is the interval width. + * + * On a small machine; the first term is well-bounded which bounds the + * total error since w_i is a subset of the period. Whereas on a + * larger machine, while this first term can be larger, if w_i is the + * of consequential size guaranteed to see n_i*w_i quickly converge to + * our upper bound of 1-cpu. + */ + runnable_avg = atomic_read(&tg->runnable_avg); + if (runnable_avg < NICE_0_LOAD) { + se->avg.load_avg_contrib *= runnable_avg; + se->avg.load_avg_contrib >>= NICE_0_SHIFT; + } } #else static inline void __update_cfs_rq_tg_load_contrib(struct cfs_rq *cfs_rq, int force_update) {} +static inline void __update_tg_runnable_avg(struct sched_avg *sa, + struct cfs_rq *cfs_rq) {} static inline void __update_group_entity_contrib(struct sched_entity *se) {} #endif @@ -1152,6 +1206,7 @@ static long __update_entity_load_avg_contrib(struct sched_entity *se) if (entity_is_task(se)) { __update_task_entity_contrib(se); } else { + __update_tg_runnable_avg(&se->avg, group_cfs_rq(se)); __update_group_entity_contrib(se); } @@ -1220,6 +1275,7 @@ static void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq, int force_update) static inline void update_rq_runnable_avg(struct rq *rq, int runnable) { __update_entity_runnable_avg(rq->clock_task, &rq->avg, runnable); + __update_tg_runnable_avg(&rq->avg, &rq->cfs); } /* Add the load generated by se into cfs_rq's child load-average */ diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 924a9909488..134928dc6f0 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -113,6 +113,7 @@ struct task_group { atomic_t load_weight; atomic64_t load_avg; + atomic_t runnable_avg; #endif #ifdef CONFIG_RT_GROUP_SCHED @@ -234,6 +235,7 @@ struct cfs_rq { atomic64_t decay_counter, removed_load; u64 last_decay; #ifdef CONFIG_FAIR_GROUP_SCHED + u32 tg_runnable_contrib; u64 tg_load_contrib; #endif #endif -- cgit v1.2.3 From f1b17280efbd21873d1db8631117bdbccbcb39a2 Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:31 +0200 Subject: sched: Maintain runnable averages across throttled periods With bandwidth control tracked entities may cease execution according to user specified bandwidth limits. Charging this time as either throttled or blocked however, is incorrect and would falsely skew in either direction. What we actually want is for any throttled periods to be "invisible" to load-tracking as they are removed from the system for that interval and contribute normally otherwise. Do this by moderating the progression of time to omit any periods in which the entity belonged to a throttled hierarchy. Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141506.998912151@google.com Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 50 ++++++++++++++++++++++++++++++++++++++++---------- kernel/sched/sched.h | 3 ++- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 9e49722da03..873c9f5c579 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1222,15 +1222,26 @@ static inline void subtract_blocked_load_contrib(struct cfs_rq *cfs_rq, cfs_rq->blocked_load_avg = 0; } +static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq); + /* Update a sched_entity's runnable average */ static inline void update_entity_load_avg(struct sched_entity *se, int update_cfs_rq) { struct cfs_rq *cfs_rq = cfs_rq_of(se); long contrib_delta; + u64 now; - if (!__update_entity_runnable_avg(rq_of(cfs_rq)->clock_task, &se->avg, - se->on_rq)) + /* + * For a group entity we need to use their owned cfs_rq_clock_task() in + * case they are the parent of a throttled hierarchy. + */ + if (entity_is_task(se)) + now = cfs_rq_clock_task(cfs_rq); + else + now = cfs_rq_clock_task(group_cfs_rq(se)); + + if (!__update_entity_runnable_avg(now, &se->avg, se->on_rq)) return; contrib_delta = __update_entity_load_avg_contrib(se); @@ -1250,7 +1261,7 @@ static inline void update_entity_load_avg(struct sched_entity *se, */ static void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq, int force_update) { - u64 now = rq_of(cfs_rq)->clock_task >> 20; + u64 now = cfs_rq_clock_task(cfs_rq) >> 20; u64 decays; decays = now - cfs_rq->last_decay; @@ -1841,6 +1852,15 @@ static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg) return &tg->cfs_bandwidth; } +/* rq->task_clock normalized against any time this cfs_rq has spent throttled */ +static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq) +{ + if (unlikely(cfs_rq->throttle_count)) + return cfs_rq->throttled_clock_task; + + return rq_of(cfs_rq)->clock_task - cfs_rq->throttled_clock_task_time; +} + /* returns 0 on failure to allocate runtime */ static int assign_cfs_rq_runtime(struct cfs_rq *cfs_rq) { @@ -1991,6 +2011,10 @@ static int tg_unthrottle_up(struct task_group *tg, void *data) cfs_rq->load_stamp += delta; cfs_rq->load_last += delta; + /* adjust cfs_rq_clock_task() */ + cfs_rq->throttled_clock_task_time += rq->clock_task - + cfs_rq->throttled_clock_task; + /* update entity weight now that we are on_rq again */ update_cfs_shares(cfs_rq); } @@ -2005,8 +2029,10 @@ static int tg_throttle_down(struct task_group *tg, void *data) struct cfs_rq *cfs_rq = tg->cfs_rq[cpu_of(rq)]; /* group is entering throttled state, record last load */ - if (!cfs_rq->throttle_count) + if (!cfs_rq->throttle_count) { update_cfs_load(cfs_rq, 0); + cfs_rq->throttled_clock_task = rq->clock_task; + } cfs_rq->throttle_count++; return 0; @@ -2021,7 +2047,7 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq) se = cfs_rq->tg->se[cpu_of(rq_of(cfs_rq))]; - /* account load preceding throttle */ + /* freeze hierarchy runnable averages while throttled */ rcu_read_lock(); walk_tg_tree_from(cfs_rq->tg, tg_throttle_down, tg_nop, (void *)rq); rcu_read_unlock(); @@ -2045,7 +2071,7 @@ static void throttle_cfs_rq(struct cfs_rq *cfs_rq) rq->nr_running -= task_delta; cfs_rq->throttled = 1; - cfs_rq->throttled_timestamp = rq->clock; + cfs_rq->throttled_clock = rq->clock; raw_spin_lock(&cfs_b->lock); list_add_tail_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq); raw_spin_unlock(&cfs_b->lock); @@ -2063,10 +2089,9 @@ void unthrottle_cfs_rq(struct cfs_rq *cfs_rq) cfs_rq->throttled = 0; raw_spin_lock(&cfs_b->lock); - cfs_b->throttled_time += rq->clock - cfs_rq->throttled_timestamp; + cfs_b->throttled_time += rq->clock - cfs_rq->throttled_clock; list_del_rcu(&cfs_rq->throttled_list); raw_spin_unlock(&cfs_b->lock); - cfs_rq->throttled_timestamp = 0; update_rq_clock(rq); /* update hierarchical throttle state */ @@ -2466,8 +2491,13 @@ static void unthrottle_offline_cfs_rqs(struct rq *rq) } #else /* CONFIG_CFS_BANDWIDTH */ -static __always_inline -void account_cfs_rq_runtime(struct cfs_rq *cfs_rq, unsigned long delta_exec) {} +static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq) +{ + return rq_of(cfs_rq)->clock_task; +} + +static void account_cfs_rq_runtime(struct cfs_rq *cfs_rq, + unsigned long delta_exec) {} static void check_cfs_rq_runtime(struct cfs_rq *cfs_rq) {} static void check_enqueue_throttle(struct cfs_rq *cfs_rq) {} static __always_inline void return_cfs_rq_runtime(struct cfs_rq *cfs_rq) {} diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 134928dc6f0..d13bce7a44e 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -281,7 +281,8 @@ struct cfs_rq { u64 runtime_expires; s64 runtime_remaining; - u64 throttled_timestamp; + u64 throttled_clock, throttled_clock_task; + u64 throttled_clock_task_time; int throttled, throttle_count; struct list_head throttled_list; #endif /* CONFIG_CFS_BANDWIDTH */ -- cgit v1.2.3 From 82958366cfea1a50e7e90907b2d55ae29ed69974 Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:31 +0200 Subject: sched: Replace update_shares weight distribution with per-entity computation Now that the machinery in place is in place to compute contributed load in a bottom up fashion; replace the shares distribution code within update_shares() accordingly. Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141507.061208672@google.com Signed-off-by: Ingo Molnar --- kernel/sched/debug.c | 8 --- kernel/sched/fair.c | 157 ++++++++------------------------------------------- kernel/sched/sched.h | 36 ++++-------- 3 files changed, 36 insertions(+), 165 deletions(-) diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 71b0ea325e9..2cd3c1b4e58 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -218,14 +218,6 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) SEQ_printf(m, " .%-30s: %ld\n", "load", cfs_rq->load.weight); #ifdef CONFIG_FAIR_GROUP_SCHED #ifdef CONFIG_SMP - SEQ_printf(m, " .%-30s: %Ld.%06ld\n", "load_avg", - SPLIT_NS(cfs_rq->load_avg)); - SEQ_printf(m, " .%-30s: %Ld.%06ld\n", "load_period", - SPLIT_NS(cfs_rq->load_period)); - SEQ_printf(m, " .%-30s: %ld\n", "load_contrib", - cfs_rq->load_contribution); - SEQ_printf(m, " .%-30s: %d\n", "load_tg", - atomic_read(&cfs_rq->tg->load_weight)); SEQ_printf(m, " .%-30s: %lld\n", "runnable_load_avg", cfs_rq->runnable_load_avg); SEQ_printf(m, " .%-30s: %lld\n", "blocked_load_avg", diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 873c9f5c579..57fae95eed9 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -658,9 +658,6 @@ static u64 sched_vslice(struct cfs_rq *cfs_rq, struct sched_entity *se) return calc_delta_fair(sched_slice(cfs_rq, se), se); } -static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update); -static void update_cfs_shares(struct cfs_rq *cfs_rq); - /* * Update the current task's runtime statistics. Skip current tasks that * are not in our scheduling class. @@ -680,10 +677,6 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, curr->vruntime += delta_exec_weighted; update_min_vruntime(cfs_rq); - -#if defined CONFIG_SMP && defined CONFIG_FAIR_GROUP_SCHED - cfs_rq->load_unacc_exec_time += delta_exec; -#endif } static void update_curr(struct cfs_rq *cfs_rq) @@ -806,72 +799,7 @@ account_entity_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se) } #ifdef CONFIG_FAIR_GROUP_SCHED -/* we need this in update_cfs_load and load-balance functions below */ -static inline int throttled_hierarchy(struct cfs_rq *cfs_rq); # ifdef CONFIG_SMP -static void update_cfs_rq_load_contribution(struct cfs_rq *cfs_rq, - int global_update) -{ - struct task_group *tg = cfs_rq->tg; - long load_avg; - - load_avg = div64_u64(cfs_rq->load_avg, cfs_rq->load_period+1); - load_avg -= cfs_rq->load_contribution; - - if (global_update || abs(load_avg) > cfs_rq->load_contribution / 8) { - atomic_add(load_avg, &tg->load_weight); - cfs_rq->load_contribution += load_avg; - } -} - -static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update) -{ - u64 period = sysctl_sched_shares_window; - u64 now, delta; - unsigned long load = cfs_rq->load.weight; - - if (cfs_rq->tg == &root_task_group || throttled_hierarchy(cfs_rq)) - return; - - now = rq_of(cfs_rq)->clock_task; - delta = now - cfs_rq->load_stamp; - - /* truncate load history at 4 idle periods */ - if (cfs_rq->load_stamp > cfs_rq->load_last && - now - cfs_rq->load_last > 4 * period) { - cfs_rq->load_period = 0; - cfs_rq->load_avg = 0; - delta = period - 1; - } - - cfs_rq->load_stamp = now; - cfs_rq->load_unacc_exec_time = 0; - cfs_rq->load_period += delta; - if (load) { - cfs_rq->load_last = now; - cfs_rq->load_avg += delta * load; - } - - /* consider updating load contribution on each fold or truncate */ - if (global_update || cfs_rq->load_period > period - || !cfs_rq->load_period) - update_cfs_rq_load_contribution(cfs_rq, global_update); - - while (cfs_rq->load_period > period) { - /* - * Inline assembly required to prevent the compiler - * optimising this loop into a divmod call. - * See __iter_div_u64_rem() for another example of this. - */ - asm("" : "+rm" (cfs_rq->load_period)); - cfs_rq->load_period /= 2; - cfs_rq->load_avg /= 2; - } - - if (!cfs_rq->curr && !cfs_rq->nr_running && !cfs_rq->load_avg) - list_del_leaf_cfs_rq(cfs_rq); -} - static inline long calc_tg_weight(struct task_group *tg, struct cfs_rq *cfs_rq) { long tg_weight; @@ -881,8 +809,8 @@ static inline long calc_tg_weight(struct task_group *tg, struct cfs_rq *cfs_rq) * to gain a more accurate current total weight. See * update_cfs_rq_load_contribution(). */ - tg_weight = atomic_read(&tg->load_weight); - tg_weight -= cfs_rq->load_contribution; + tg_weight = atomic64_read(&tg->load_avg); + tg_weight -= cfs_rq->tg_load_contrib; tg_weight += cfs_rq->load.weight; return tg_weight; @@ -906,27 +834,11 @@ static long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg) return shares; } - -static void update_entity_shares_tick(struct cfs_rq *cfs_rq) -{ - if (cfs_rq->load_unacc_exec_time > sysctl_sched_shares_window) { - update_cfs_load(cfs_rq, 0); - update_cfs_shares(cfs_rq); - } -} # else /* CONFIG_SMP */ -static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update) -{ -} - static inline long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg) { return tg->shares; } - -static inline void update_entity_shares_tick(struct cfs_rq *cfs_rq) -{ -} # endif /* CONFIG_SMP */ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, unsigned long weight) @@ -944,6 +856,8 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, account_entity_enqueue(cfs_rq, se); } +static inline int throttled_hierarchy(struct cfs_rq *cfs_rq); + static void update_cfs_shares(struct cfs_rq *cfs_rq) { struct task_group *tg; @@ -963,17 +877,9 @@ static void update_cfs_shares(struct cfs_rq *cfs_rq) reweight_entity(cfs_rq_of(se), se, shares); } #else /* CONFIG_FAIR_GROUP_SCHED */ -static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update) -{ -} - static inline void update_cfs_shares(struct cfs_rq *cfs_rq) { } - -static inline void update_entity_shares_tick(struct cfs_rq *cfs_rq) -{ -} #endif /* CONFIG_FAIR_GROUP_SCHED */ #ifdef CONFIG_SMP @@ -1490,7 +1396,6 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) * Update run-time statistics of the 'current'. */ update_curr(cfs_rq); - update_cfs_load(cfs_rq, 0); enqueue_entity_load_avg(cfs_rq, se, flags & ENQUEUE_WAKEUP); account_entity_enqueue(cfs_rq, se); update_cfs_shares(cfs_rq); @@ -1587,7 +1492,6 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) if (se != cfs_rq->curr) __dequeue_entity(cfs_rq, se); se->on_rq = 0; - update_cfs_load(cfs_rq, 0); account_entity_dequeue(cfs_rq, se); /* @@ -1756,11 +1660,6 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued) update_entity_load_avg(curr, 1); update_cfs_rq_blocked_load(cfs_rq, 1); - /* - * Update share accounting for long-running entities. - */ - update_entity_shares_tick(cfs_rq); - #ifdef CONFIG_SCHED_HRTICK /* * queued ticks are scheduled to match the slice, so don't bother @@ -2005,18 +1904,9 @@ static int tg_unthrottle_up(struct task_group *tg, void *data) cfs_rq->throttle_count--; #ifdef CONFIG_SMP if (!cfs_rq->throttle_count) { - u64 delta = rq->clock_task - cfs_rq->load_stamp; - - /* leaving throttled state, advance shares averaging windows */ - cfs_rq->load_stamp += delta; - cfs_rq->load_last += delta; - /* adjust cfs_rq_clock_task() */ cfs_rq->throttled_clock_task_time += rq->clock_task - cfs_rq->throttled_clock_task; - - /* update entity weight now that we are on_rq again */ - update_cfs_shares(cfs_rq); } #endif @@ -2028,11 +1918,9 @@ static int tg_throttle_down(struct task_group *tg, void *data) struct rq *rq = data; struct cfs_rq *cfs_rq = tg->cfs_rq[cpu_of(rq)]; - /* group is entering throttled state, record last load */ - if (!cfs_rq->throttle_count) { - update_cfs_load(cfs_rq, 0); + /* group is entering throttled state, stop time */ + if (!cfs_rq->throttle_count) cfs_rq->throttled_clock_task = rq->clock_task; - } cfs_rq->throttle_count++; return 0; @@ -2630,7 +2518,6 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) if (cfs_rq_throttled(cfs_rq)) break; - update_cfs_load(cfs_rq, 0); update_cfs_shares(cfs_rq); update_entity_load_avg(se, 1); } @@ -2692,7 +2579,6 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags) if (cfs_rq_throttled(cfs_rq)) break; - update_cfs_load(cfs_rq, 0); update_cfs_shares(cfs_rq); update_entity_load_avg(se, 1); } @@ -3755,27 +3641,36 @@ next: */ static int update_shares_cpu(struct task_group *tg, int cpu) { + struct sched_entity *se; struct cfs_rq *cfs_rq; unsigned long flags; struct rq *rq; - if (!tg->se[cpu]) - return 0; - rq = cpu_rq(cpu); + se = tg->se[cpu]; cfs_rq = tg->cfs_rq[cpu]; raw_spin_lock_irqsave(&rq->lock, flags); update_rq_clock(rq); - update_cfs_load(cfs_rq, 1); update_cfs_rq_blocked_load(cfs_rq, 1); - /* - * We need to update shares after updating tg->load_weight in - * order to adjust the weight of groups with long running tasks. - */ - update_cfs_shares(cfs_rq); + if (se) { + update_entity_load_avg(se, 1); + /* + * We pivot on our runnable average having decayed to zero for + * list removal. This generally implies that all our children + * have also been removed (modulo rounding error or bandwidth + * control); however, such cases are rare and we can fix these + * at enqueue. + * + * TODO: fix up out-of-order children on enqueue. + */ + if (!se->avg.runnable_avg_sum && !cfs_rq->nr_running) + list_del_leaf_cfs_rq(cfs_rq); + } else { + update_rq_runnable_avg(rq, rq->nr_running); + } raw_spin_unlock_irqrestore(&rq->lock, flags); @@ -5702,10 +5597,6 @@ void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq, cfs_rq->tg = tg; cfs_rq->rq = rq; -#ifdef CONFIG_SMP - /* allow initial update_cfs_load() to truncate */ - cfs_rq->load_stamp = 1; -#endif init_cfs_rq_runtime(cfs_rq); tg->cfs_rq[cpu] = cfs_rq; diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index d13bce7a44e..0a75a430ca7 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -234,11 +234,21 @@ struct cfs_rq { u64 runnable_load_avg, blocked_load_avg; atomic64_t decay_counter, removed_load; u64 last_decay; + #ifdef CONFIG_FAIR_GROUP_SCHED u32 tg_runnable_contrib; u64 tg_load_contrib; -#endif -#endif +#endif /* CONFIG_FAIR_GROUP_SCHED */ + + /* + * h_load = weight * f(tg) + * + * Where f(tg) is the recursive weight fraction assigned to + * this group. + */ + unsigned long h_load; +#endif /* CONFIG_SMP */ + #ifdef CONFIG_FAIR_GROUP_SCHED struct rq *rq; /* cpu runqueue to which this cfs_rq is attached */ @@ -254,28 +264,6 @@ struct cfs_rq { struct list_head leaf_cfs_rq_list; struct task_group *tg; /* group that "owns" this runqueue */ -#ifdef CONFIG_SMP - /* - * h_load = weight * f(tg) - * - * Where f(tg) is the recursive weight fraction assigned to - * this group. - */ - unsigned long h_load; - - /* - * Maintaining per-cpu shares distribution for group scheduling - * - * load_stamp is the last time we updated the load average - * load_last is the last time we updated the load average and saw load - * load_unacc_exec_time is currently unaccounted execution time - */ - u64 load_avg; - u64 load_period; - u64 load_stamp, load_last, load_unacc_exec_time; - - unsigned long load_contribution; -#endif /* CONFIG_SMP */ #ifdef CONFIG_CFS_BANDWIDTH int runtime_enabled; u64 runtime_expires; -- cgit v1.2.3 From 48a1675323fa1b7844e479ad2a4469f4558c0f79 Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:31 +0200 Subject: sched: Refactor update_shares_cpu() -> update_blocked_avgs() Now that running entities maintain their own load-averages the work we must do in update_shares() is largely restricted to the periodic decay of blocked entities. This allows us to be a little less pessimistic regarding our occupancy on rq->lock and the associated rq->clock updates required. Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141507.133999170@google.com Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 50 +++++++++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 57fae95eed9..dcc27d8ae6b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3639,20 +3639,15 @@ next: /* * update tg->load_weight by folding this cpu's load_avg */ -static int update_shares_cpu(struct task_group *tg, int cpu) +static void __update_blocked_averages_cpu(struct task_group *tg, int cpu) { - struct sched_entity *se; - struct cfs_rq *cfs_rq; - unsigned long flags; - struct rq *rq; - - rq = cpu_rq(cpu); - se = tg->se[cpu]; - cfs_rq = tg->cfs_rq[cpu]; + struct sched_entity *se = tg->se[cpu]; + struct cfs_rq *cfs_rq = tg->cfs_rq[cpu]; - raw_spin_lock_irqsave(&rq->lock, flags); + /* throttled entities do not contribute to load */ + if (throttled_hierarchy(cfs_rq)) + return; - update_rq_clock(rq); update_cfs_rq_blocked_load(cfs_rq, 1); if (se) { @@ -3669,32 +3664,33 @@ static int update_shares_cpu(struct task_group *tg, int cpu) if (!se->avg.runnable_avg_sum && !cfs_rq->nr_running) list_del_leaf_cfs_rq(cfs_rq); } else { + struct rq *rq = rq_of(cfs_rq); update_rq_runnable_avg(rq, rq->nr_running); } - - raw_spin_unlock_irqrestore(&rq->lock, flags); - - return 0; } -static void update_shares(int cpu) +static void update_blocked_averages(int cpu) { - struct cfs_rq *cfs_rq; struct rq *rq = cpu_rq(cpu); + struct cfs_rq *cfs_rq; + unsigned long flags; - rcu_read_lock(); + raw_spin_lock_irqsave(&rq->lock, flags); + update_rq_clock(rq); /* * Iterates the task_group tree in a bottom up fashion, see * list_add_leaf_cfs_rq() for details. */ for_each_leaf_cfs_rq(rq, cfs_rq) { - /* throttled entities do not contribute to load */ - if (throttled_hierarchy(cfs_rq)) - continue; - - update_shares_cpu(cfs_rq->tg, cpu); + /* + * Note: We may want to consider periodically releasing + * rq->lock about these updates so that creating many task + * groups does not result in continually extending hold time. + */ + __update_blocked_averages_cpu(cfs_rq->tg, rq->cpu); } - rcu_read_unlock(); + + raw_spin_unlock_irqrestore(&rq->lock, flags); } /* @@ -3746,7 +3742,7 @@ static unsigned long task_h_load(struct task_struct *p) return load; } #else -static inline void update_shares(int cpu) +static inline void update_blocked_averages(int cpu) { } @@ -4813,7 +4809,7 @@ void idle_balance(int this_cpu, struct rq *this_rq) */ raw_spin_unlock(&this_rq->lock); - update_shares(this_cpu); + update_blocked_averages(this_cpu); rcu_read_lock(); for_each_domain(this_cpu, sd) { unsigned long interval; @@ -5068,7 +5064,7 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle) int update_next_balance = 0; int need_serialize; - update_shares(cpu); + update_blocked_averages(cpu); rcu_read_lock(); for_each_domain(cpu, sd) { -- cgit v1.2.3 From f269ae0469fc882332bdfb5db15d3c1315fe2a10 Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:31 +0200 Subject: sched: Update_cfs_shares at period edge Now that our measurement intervals are small (~1ms) we can amortize the posting of update_shares() to be about each period overflow. This is a large cost saving for frequently switching tasks. Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141507.200772172@google.com Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index dcc27d8ae6b..002a7697f43 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1187,6 +1187,7 @@ static void update_cfs_rq_blocked_load(struct cfs_rq *cfs_rq, int force_update) } __update_cfs_rq_tg_load_contrib(cfs_rq, force_update); + update_cfs_shares(cfs_rq); } static inline void update_rq_runnable_avg(struct rq *rq, int runnable) @@ -1396,9 +1397,8 @@ enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) * Update run-time statistics of the 'current'. */ update_curr(cfs_rq); - enqueue_entity_load_avg(cfs_rq, se, flags & ENQUEUE_WAKEUP); account_entity_enqueue(cfs_rq, se); - update_cfs_shares(cfs_rq); + enqueue_entity_load_avg(cfs_rq, se, flags & ENQUEUE_WAKEUP); if (flags & ENQUEUE_WAKEUP) { place_entity(cfs_rq, se, 0); @@ -1471,7 +1471,6 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) * Update run-time statistics of the 'current'. */ update_curr(cfs_rq); - dequeue_entity_load_avg(cfs_rq, se, flags & DEQUEUE_SLEEP); update_stats_dequeue(cfs_rq, se); if (flags & DEQUEUE_SLEEP) { @@ -1491,8 +1490,8 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) if (se != cfs_rq->curr) __dequeue_entity(cfs_rq, se); - se->on_rq = 0; account_entity_dequeue(cfs_rq, se); + dequeue_entity_load_avg(cfs_rq, se, flags & DEQUEUE_SLEEP); /* * Normalize the entity after updating the min_vruntime because the @@ -1506,7 +1505,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) return_cfs_rq_runtime(cfs_rq); update_min_vruntime(cfs_rq); - update_cfs_shares(cfs_rq); + se->on_rq = 0; } /* @@ -2518,8 +2517,8 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) if (cfs_rq_throttled(cfs_rq)) break; - update_cfs_shares(cfs_rq); update_entity_load_avg(se, 1); + update_cfs_rq_blocked_load(cfs_rq, 0); } if (!se) { @@ -2579,8 +2578,8 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags) if (cfs_rq_throttled(cfs_rq)) break; - update_cfs_shares(cfs_rq); update_entity_load_avg(se, 1); + update_cfs_rq_blocked_load(cfs_rq, 0); } if (!se) { @@ -5639,8 +5638,11 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares) se = tg->se[i]; /* Propagate contribution to hierarchy */ raw_spin_lock_irqsave(&rq->lock, flags); - for_each_sched_entity(se) + for_each_sched_entity(se) { update_cfs_shares(group_cfs_rq(se)); + /* update contribution to parent */ + update_entity_load_avg(se, 1); + } raw_spin_unlock_irqrestore(&rq->lock, flags); } -- cgit v1.2.3 From 5b51f2f80b3b906ce59bd4dce6eca3c7f34cb1b9 Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:32 +0200 Subject: sched: Make __update_entity_runnable_avg() fast __update_entity_runnable_avg forms the core of maintaining an entity's runnable load average. In this function we charge the accumulated run-time since last update and handle appropriate decay. In some cases, e.g. a waking task, this time interval may be much larger than our period unit. Fortunately we can exploit some properties of our series to perform decay for a blocked update in constant time and account the contribution for a running update in essentially-constant* time. [*]: For any running entity they should be performing updates at the tick which gives us a soft limit of 1 jiffy between updates, and we can compute up to a 32 jiffy update in a single pass. C program to generate the magic constants in the arrays: #include #include #define N 32 #define WMULT_SHIFT 32 const long WMULT_CONST = ((1UL << N) - 1); double y; long runnable_avg_yN_inv[N]; void calc_mult_inv() { int i; double yn = 0; printf("inverses\n"); for (i = 0; i < N; i++) { yn = (double)WMULT_CONST * pow(y, i); runnable_avg_yN_inv[i] = yn; printf("%2d: 0x%8lx\n", i, runnable_avg_yN_inv[i]); } printf("\n"); } long mult_inv(long c, int n) { return (c * runnable_avg_yN_inv[n]) >> WMULT_SHIFT; } void calc_yn_sum(int n) { int i; double sum = 0, sum_fl = 0, diff = 0; /* * We take the floored sum to ensure the sum of partial sums is never * larger than the actual sum. */ printf("sum y^n\n"); printf(" %8s %8s %8s\n", "exact", "floor", "error"); for (i = 1; i <= n; i++) { sum = (y * sum + y * 1024); sum_fl = floor(y * sum_fl+ y * 1024); printf("%2d: %8.0f %8.0f %8.0f\n", i, sum, sum_fl, sum_fl - sum); } printf("\n"); } void calc_conv(long n) { long old_n; int i = -1; printf("convergence (LOAD_AVG_MAX, LOAD_AVG_MAX_N)\n"); do { old_n = n; n = mult_inv(n, 1) + 1024; i++; } while (n != old_n); printf("%d> %ld\n", i - 1, n); printf("\n"); } void main() { y = pow(0.5, 1/(double)N); calc_mult_inv(); calc_conv(1024); calc_yn_sum(N); } [ Compile with -lm ] Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141507.277808946@google.com Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 125 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 101 insertions(+), 24 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 002a7697f43..6ecf455fd95 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -883,18 +883,93 @@ static inline void update_cfs_shares(struct cfs_rq *cfs_rq) #endif /* CONFIG_FAIR_GROUP_SCHED */ #ifdef CONFIG_SMP +/* + * We choose a half-life close to 1 scheduling period. + * Note: The tables below are dependent on this value. + */ +#define LOAD_AVG_PERIOD 32 +#define LOAD_AVG_MAX 47742 /* maximum possible load avg */ +#define LOAD_AVG_MAX_N 345 /* number of full periods to produce LOAD_MAX_AVG */ + +/* Precomputed fixed inverse multiplies for multiplication by y^n */ +static const u32 runnable_avg_yN_inv[] = { + 0xffffffff, 0xfa83b2da, 0xf5257d14, 0xefe4b99a, 0xeac0c6e6, 0xe5b906e6, + 0xe0ccdeeb, 0xdbfbb796, 0xd744fcc9, 0xd2a81d91, 0xce248c14, 0xc9b9bd85, + 0xc5672a10, 0xc12c4cc9, 0xbd08a39e, 0xb8fbaf46, 0xb504f333, 0xb123f581, + 0xad583ee9, 0xa9a15ab4, 0xa5fed6a9, 0xa2704302, 0x9ef5325f, 0x9b8d39b9, + 0x9837f050, 0x94f4efa8, 0x91c3d373, 0x8ea4398a, 0x8b95c1e3, 0x88980e80, + 0x85aac367, 0x82cd8698, +}; + +/* + * Precomputed \Sum y^k { 1<=k<=n }. These are floor(true_value) to prevent + * over-estimates when re-combining. + */ +static const u32 runnable_avg_yN_sum[] = { + 0, 1002, 1982, 2941, 3880, 4798, 5697, 6576, 7437, 8279, 9103, + 9909,10698,11470,12226,12966,13690,14398,15091,15769,16433,17082, + 17718,18340,18949,19545,20128,20698,21256,21802,22336,22859,23371, +}; + /* * Approximate: * val * y^n, where y^32 ~= 0.5 (~1 scheduling period) */ static __always_inline u64 decay_load(u64 val, u64 n) { - for (; n && val; n--) { - val *= 4008; - val >>= 12; + unsigned int local_n; + + if (!n) + return val; + else if (unlikely(n > LOAD_AVG_PERIOD * 63)) + return 0; + + /* after bounds checking we can collapse to 32-bit */ + local_n = n; + + /* + * As y^PERIOD = 1/2, we can combine + * y^n = 1/2^(n/PERIOD) * k^(n%PERIOD) + * With a look-up table which covers k^n (n= LOAD_AVG_PERIOD)) { + val >>= local_n / LOAD_AVG_PERIOD; + local_n %= LOAD_AVG_PERIOD; } - return val; + val *= runnable_avg_yN_inv[local_n]; + /* We don't use SRR here since we always want to round down. */ + return val >> 32; +} + +/* + * For updates fully spanning n periods, the contribution to runnable + * average will be: \Sum 1024*y^n + * + * We can compute this reasonably efficiently by combining: + * y^PERIOD = 1/2 with precomputed \Sum 1024*y^n {for n = LOAD_AVG_MAX_N)) + return LOAD_AVG_MAX; + + /* Compute \Sum k^n combining precomputed values for k^i, \Sum k^j */ + do { + contrib /= 2; /* y^LOAD_AVG_PERIOD = 1/2 */ + contrib += runnable_avg_yN_sum[LOAD_AVG_PERIOD]; + + n -= LOAD_AVG_PERIOD; + } while (n > LOAD_AVG_PERIOD); + + contrib = decay_load(contrib, n); + return contrib + runnable_avg_yN_sum[n]; } /* @@ -929,7 +1004,8 @@ static __always_inline int __update_entity_runnable_avg(u64 now, struct sched_avg *sa, int runnable) { - u64 delta; + u64 delta, periods; + u32 runnable_contrib; int delta_w, decayed = 0; delta = now - sa->last_runnable_update; @@ -963,25 +1039,26 @@ static __always_inline int __update_entity_runnable_avg(u64 now, * period and accrue it. */ delta_w = 1024 - delta_w; - BUG_ON(delta_w > delta); - do { - if (runnable) - sa->runnable_avg_sum += delta_w; - sa->runnable_avg_period += delta_w; - - /* - * Remainder of delta initiates a new period, roll over - * the previous. - */ - sa->runnable_avg_sum = - decay_load(sa->runnable_avg_sum, 1); - sa->runnable_avg_period = - decay_load(sa->runnable_avg_period, 1); - - delta -= delta_w; - /* New period is empty */ - delta_w = 1024; - } while (delta >= 1024); + if (runnable) + sa->runnable_avg_sum += delta_w; + sa->runnable_avg_period += delta_w; + + delta -= delta_w; + + /* Figure out how many additional periods this update spans */ + periods = delta / 1024; + delta %= 1024; + + sa->runnable_avg_sum = decay_load(sa->runnable_avg_sum, + periods + 1); + sa->runnable_avg_period = decay_load(sa->runnable_avg_period, + periods + 1); + + /* Efficiently calculate \sum (1..n_period) 1024*y^i */ + runnable_contrib = __compute_runnable_contrib(periods); + if (runnable) + sa->runnable_avg_sum += runnable_contrib; + sa->runnable_avg_period += runnable_contrib; } /* Remainder of delta accrued against u_0` */ -- cgit v1.2.3 From f4e26b120b9de84cb627bc7361ba43cfdc51341f Mon Sep 17 00:00:00 2001 From: Paul Turner Date: Thu, 4 Oct 2012 13:18:32 +0200 Subject: sched: Introduce temporary FAIR_GROUP_SCHED dependency for load-tracking While per-entity load-tracking is generally useful, beyond computing shares distribution, e.g. runnable based load-balance (in progress), governors, power-management, etc. These facilities are not yet consumers of this data. This may be trivially reverted when the information is required; but avoid paying the overhead for calculations we will not use until then. Signed-off-by: Paul Turner Reviewed-by: Ben Segall Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20120823141507.422162369@google.com Signed-off-by: Ingo Molnar --- include/linux/sched.h | 8 +++++++- kernel/sched/core.c | 7 ++++++- kernel/sched/fair.c | 13 +++++++++++-- kernel/sched/sched.h | 9 ++++++++- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index e483ccb08ce..e1581a029e3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1168,7 +1168,13 @@ struct sched_entity { /* rq "owned" by this entity/group: */ struct cfs_rq *my_q; #endif -#ifdef CONFIG_SMP +/* + * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be + * removed when useful for applications beyond shares distribution (e.g. + * load-balance). + */ +#if defined(CONFIG_SMP) && defined(CONFIG_FAIR_GROUP_SCHED) + /* Per-entity load-tracking */ struct sched_avg avg; #endif }; diff --git a/kernel/sched/core.c b/kernel/sched/core.c index f26860074ef..5dae0d252ff 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1526,7 +1526,12 @@ static void __sched_fork(struct task_struct *p) p->se.vruntime = 0; INIT_LIST_HEAD(&p->se.group_node); -#ifdef CONFIG_SMP +/* + * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be + * removed when useful for applications beyond shares distribution (e.g. + * load-balance). + */ +#if defined(CONFIG_SMP) && defined(CONFIG_FAIR_GROUP_SCHED) p->se.avg.runnable_avg_period = 0; p->se.avg.runnable_avg_sum = 0; #endif diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 6ecf455fd95..3e6a3531fa9 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -882,7 +882,8 @@ static inline void update_cfs_shares(struct cfs_rq *cfs_rq) } #endif /* CONFIG_FAIR_GROUP_SCHED */ -#ifdef CONFIG_SMP +/* Only depends on SMP, FAIR_GROUP_SCHED may be removed when useful in lb */ +#if defined(CONFIG_SMP) && defined(CONFIG_FAIR_GROUP_SCHED) /* * We choose a half-life close to 1 scheduling period. * Note: The tables below are dependent on this value. @@ -3173,6 +3174,12 @@ unlock: return new_cpu; } +/* + * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be + * removed when useful for applications beyond shares distribution (e.g. + * load-balance). + */ +#ifdef CONFIG_FAIR_GROUP_SCHED /* * Called immediately before a task is migrated to a new cpu; task_cpu(p) and * cfs_rq_of(p) references at time of call are still valid and identify the @@ -3196,6 +3203,7 @@ migrate_task_rq_fair(struct task_struct *p, int next_cpu) atomic64_add(se->avg.load_avg_contrib, &cfs_rq->removed_load); } } +#endif #endif /* CONFIG_SMP */ static unsigned long @@ -5773,8 +5781,9 @@ const struct sched_class fair_sched_class = { #ifdef CONFIG_SMP .select_task_rq = select_task_rq_fair, +#ifdef CONFIG_FAIR_GROUP_SCHED .migrate_task_rq = migrate_task_rq_fair, - +#endif .rq_online = rq_online_fair, .rq_offline = rq_offline_fair, diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 0a75a430ca7..5eca173b563 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -225,6 +225,12 @@ struct cfs_rq { #endif #ifdef CONFIG_SMP +/* + * Load-tracking only depends on SMP, FAIR_GROUP_SCHED dependency below may be + * removed when useful for applications beyond shares distribution (e.g. + * load-balance). + */ +#ifdef CONFIG_FAIR_GROUP_SCHED /* * CFS Load tracking * Under CFS, load is tracked on a per-entity basis and aggregated up. @@ -234,7 +240,8 @@ struct cfs_rq { u64 runnable_load_avg, blocked_load_avg; atomic64_t decay_counter, removed_load; u64 last_decay; - +#endif /* CONFIG_FAIR_GROUP_SCHED */ +/* These always depend on CONFIG_FAIR_GROUP_SCHED */ #ifdef CONFIG_FAIR_GROUP_SCHED u32 tg_runnable_contrib; u64 tg_load_contrib; -- cgit v1.2.3 From e9c84cb8d5f1b1ea6fcbe6190d51dc84b6975938 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 3 Jul 2012 13:53:26 +0200 Subject: sched: Describe CFS load-balancer Add some scribbles on how and why the load-balancer works.. Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1341316406.23484.64.camel@twins Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 3e6a3531fa9..a319d56c760 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -3456,8 +3456,122 @@ static bool yield_to_task_fair(struct rq *rq, struct task_struct *p, bool preemp #ifdef CONFIG_SMP /************************************************** - * Fair scheduling class load-balancing methods: - */ + * Fair scheduling class load-balancing methods. + * + * BASICS + * + * The purpose of load-balancing is to achieve the same basic fairness the + * per-cpu scheduler provides, namely provide a proportional amount of compute + * time to each task. This is expressed in the following equation: + * + * W_i,n/P_i == W_j,n/P_j for all i,j (1) + * + * Where W_i,n is the n-th weight average for cpu i. The instantaneous weight + * W_i,0 is defined as: + * + * W_i,0 = \Sum_j w_i,j (2) + * + * Where w_i,j is the weight of the j-th runnable task on cpu i. This weight + * is derived from the nice value as per prio_to_weight[]. + * + * The weight average is an exponential decay average of the instantaneous + * weight: + * + * W'_i,n = (2^n - 1) / 2^n * W_i,n + 1 / 2^n * W_i,0 (3) + * + * P_i is the cpu power (or compute capacity) of cpu i, typically it is the + * fraction of 'recent' time available for SCHED_OTHER task execution. But it + * can also include other factors [XXX]. + * + * To achieve this balance we define a measure of imbalance which follows + * directly from (1): + * + * imb_i,j = max{ avg(W/P), W_i/P_i } - min{ avg(W/P), W_j/P_j } (4) + * + * We them move tasks around to minimize the imbalance. In the continuous + * function space it is obvious this converges, in the discrete case we get + * a few fun cases generally called infeasible weight scenarios. + * + * [XXX expand on: + * - infeasible weights; + * - local vs global optima in the discrete case. ] + * + * + * SCHED DOMAINS + * + * In order to solve the imbalance equation (4), and avoid the obvious O(n^2) + * for all i,j solution, we create a tree of cpus that follows the hardware + * topology where each level pairs two lower groups (or better). This results + * in O(log n) layers. Furthermore we reduce the number of cpus going up the + * tree to only the first of the previous level and we decrease the frequency + * of load-balance at each level inv. proportional to the number of cpus in + * the groups. + * + * This yields: + * + * log_2 n 1 n + * \Sum { --- * --- * 2^i } = O(n) (5) + * i = 0 2^i 2^i + * `- size of each group + * | | `- number of cpus doing load-balance + * | `- freq + * `- sum over all levels + * + * Coupled with a limit on how many tasks we can migrate every balance pass, + * this makes (5) the runtime complexity of the balancer. + * + * An important property here is that each CPU is still (indirectly) connected + * to every other cpu in at most O(log n) steps: + * + * The adjacency matrix of the resulting graph is given by: + * + * log_2 n + * A_i,j = \Union (i % 2^k == 0) && i / 2^(k+1) == j / 2^(k+1) (6) + * k = 0 + * + * And you'll find that: + * + * A^(log_2 n)_i,j != 0 for all i,j (7) + * + * Showing there's indeed a path between every cpu in at most O(log n) steps. + * The task movement gives a factor of O(m), giving a convergence complexity + * of: + * + * O(nm log n), n := nr_cpus, m := nr_tasks (8) + * + * + * WORK CONSERVING + * + * In order to avoid CPUs going idle while there's still work to do, new idle + * balancing is more aggressive and has the newly idle cpu iterate up the domain + * tree itself instead of relying on other CPUs to bring it work. + * + * This adds some complexity to both (5) and (8) but it reduces the total idle + * time. + * + * [XXX more?] + * + * + * CGROUPS + * + * Cgroups make a horror show out of (2), instead of a simple sum we get: + * + * s_k,i + * W_i,0 = \Sum_j \Prod_k w_k * ----- (9) + * S_k + * + * Where + * + * s_k,i = \Sum_j w_i,j,k and S_k = \Sum_i s_k,i (10) + * + * w_i,j,k is the weight of the j-th runnable task in the k-th cgroup on cpu i. + * + * The big problem is S_k, its a global sum needed to compute a local (W_i) + * property. + * + * [XXX write more on how we solve this.. _after_ merging pjt's patches that + * rewrite all of this once again.] + */ static unsigned long __read_mostly max_load_balance_interval = HZ/10; -- cgit v1.2.3 From a47473939db20e3961b200eb00acf5fcf084d755 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 10 Oct 2012 14:53:11 +0200 Subject: perf/x86: Make hardware event translations available in sysfs Add support to display hardware events translations available through the sysfs. Add 'events' group attribute under the sysfs x86 PMU record with attribute/file for each hardware event. This patch adds only backbone for PMUs to display config under 'events' directory. The specific PMU support itself will come in next patches, however this is how the sysfs group will look like: # ls /sys/devices/cpu/events/ branch-instructions branch-misses bus-cycles cache-misses cache-references cpu-cycles instructions ref-cycles stalled-cycles-backend stalled-cycles-frontend The file - hw event ID mapping is: file hw event ID --------------------------------------------------------------- cpu-cycles PERF_COUNT_HW_CPU_CYCLES instructions PERF_COUNT_HW_INSTRUCTIONS cache-references PERF_COUNT_HW_CACHE_REFERENCES cache-misses PERF_COUNT_HW_CACHE_MISSES branch-instructions PERF_COUNT_HW_BRANCH_INSTRUCTIONS branch-misses PERF_COUNT_HW_BRANCH_MISSES bus-cycles PERF_COUNT_HW_BUS_CYCLES stalled-cycles-frontend PERF_COUNT_HW_STALLED_CYCLES_FRONTEND stalled-cycles-backend PERF_COUNT_HW_STALLED_CYCLES_BACKEND ref-cycles PERF_COUNT_HW_REF_CPU_CYCLES Each file in the 'events' directory contains the term translation for the symbolic hw event for the currently running cpu model. # cat /sys/devices/cpu/events/stalled-cycles-backend event=0xb1,umask=0x01,inv,cmask=0x01 Suggested-by: Peter Zijlstra Signed-off-by: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Stephane Eranian Cc: Linus Torvalds Cc: Andrew Morton Cc: Thomas Gleixner Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1349873598-12583-2-git-send-email-jolsa@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 60 ++++++++++++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/perf_event.h | 2 ++ 2 files changed, 62 insertions(+) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 4a3374e61a9..9fa4c45ecad 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1316,6 +1316,62 @@ static struct attribute_group x86_pmu_format_group = { .attrs = NULL, }; +struct perf_pmu_events_attr { + struct device_attribute attr; + u64 id; +}; + +ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, + char *page) +{ + struct perf_pmu_events_attr *pmu_attr = \ + container_of(attr, struct perf_pmu_events_attr, attr); + + u64 config = x86_pmu.event_map(pmu_attr->id); + return x86_pmu.events_sysfs_show(page, config); +} + +#define EVENT_VAR(_id) event_attr_##_id +#define EVENT_PTR(_id) &event_attr_##_id.attr.attr + +#define EVENT_ATTR(_name, _id) \ +static struct perf_pmu_events_attr EVENT_VAR(_id) = { \ + .attr = __ATTR(_name, 0444, events_sysfs_show, NULL), \ + .id = PERF_COUNT_HW_##_id, \ +}; + +EVENT_ATTR(cpu-cycles, CPU_CYCLES ); +EVENT_ATTR(instructions, INSTRUCTIONS ); +EVENT_ATTR(cache-references, CACHE_REFERENCES ); +EVENT_ATTR(cache-misses, CACHE_MISSES ); +EVENT_ATTR(branch-instructions, BRANCH_INSTRUCTIONS ); +EVENT_ATTR(branch-misses, BRANCH_MISSES ); +EVENT_ATTR(bus-cycles, BUS_CYCLES ); +EVENT_ATTR(stalled-cycles-frontend, STALLED_CYCLES_FRONTEND ); +EVENT_ATTR(stalled-cycles-backend, STALLED_CYCLES_BACKEND ); +EVENT_ATTR(ref-cycles, REF_CPU_CYCLES ); + +static struct attribute *empty_attrs; + +struct attribute *events_attr[] = { + EVENT_PTR(CPU_CYCLES), + EVENT_PTR(INSTRUCTIONS), + EVENT_PTR(CACHE_REFERENCES), + EVENT_PTR(CACHE_MISSES), + EVENT_PTR(BRANCH_INSTRUCTIONS), + EVENT_PTR(BRANCH_MISSES), + EVENT_PTR(BUS_CYCLES), + EVENT_PTR(STALLED_CYCLES_FRONTEND), + EVENT_PTR(STALLED_CYCLES_BACKEND), + EVENT_PTR(REF_CPU_CYCLES), + NULL, +}; + +static struct attribute_group x86_pmu_events_group = { + .name = "events", + .attrs = events_attr, +}; + static int __init init_hw_perf_events(void) { struct x86_pmu_quirk *quirk; @@ -1362,6 +1418,9 @@ static int __init init_hw_perf_events(void) x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ x86_pmu_format_group.attrs = x86_pmu.format_attrs; + if (!x86_pmu.events_sysfs_show) + x86_pmu_events_group.attrs = &empty_attrs; + pr_info("... version: %d\n", x86_pmu.version); pr_info("... bit width: %d\n", x86_pmu.cntval_bits); pr_info("... generic registers: %d\n", x86_pmu.num_counters); @@ -1651,6 +1710,7 @@ static struct attribute_group x86_pmu_attr_group = { static const struct attribute_group *x86_pmu_attr_groups[] = { &x86_pmu_attr_group, &x86_pmu_format_group, + &x86_pmu_events_group, NULL, }; diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 271d2570029..6f75b6a7f37 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -354,6 +354,8 @@ struct x86_pmu { int attr_rdpmc; struct attribute **format_attrs; + ssize_t (*events_sysfs_show)(char *page, u64 config); + /* * CPU Hotplug hooks */ -- cgit v1.2.3 From 8300daa26755c9a194776778bd822acf1fa2dbf6 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 10 Oct 2012 14:53:12 +0200 Subject: perf/x86: Filter out undefined events from sysfs events attribute The sysfs events group attribute currently shows all hw events, including also undefined ones. This patch filters out all undefined events out of the sysfs events group attribute, so they don't even show up. Suggested-by: Peter Zijlstra Signed-off-by: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1349873598-12583-3-git-send-email-jolsa@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 9fa4c45ecad..39737a678a8 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1321,6 +1321,26 @@ struct perf_pmu_events_attr { u64 id; }; +/* + * Remove all undefined events (x86_pmu.event_map(id) == 0) + * out of events_attr attributes. + */ +static void __init filter_events(struct attribute **attrs) +{ + int i, j; + + for (i = 0; attrs[i]; i++) { + if (x86_pmu.event_map(i)) + continue; + + for (j = i; attrs[j]; j++) + attrs[j] = attrs[j + 1]; + + /* Check the shifted attr. */ + i--; + } +} + ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, char *page) { @@ -1420,6 +1440,8 @@ static int __init init_hw_perf_events(void) if (!x86_pmu.events_sysfs_show) x86_pmu_events_group.attrs = &empty_attrs; + else + filter_events(x86_pmu_events_group.attrs); pr_info("... version: %d\n", x86_pmu.version); pr_info("... bit width: %d\n", x86_pmu.cntval_bits); -- cgit v1.2.3 From 43c032febde48aabcf6d59f47cdcb7b5debbdc63 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 10 Oct 2012 14:53:13 +0200 Subject: perf/x86: Add hardware events translations for Intel cpus Add support for Intel processors to display 'events' sysfs directory (/sys/devices/cpu/events/) with hw event translations: # ls /sys/devices/cpu/events/ branch-instructions branch-misses bus-cycles cache-misses cache-references cpu-cycles instructions ref-cycles stalled-cycles-backend stalled-cycles-frontend Suggested-by: Peter Zijlstra Signed-off-by: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Stephane Eranian Cc: Linus Torvalds Cc: Andrew Morton Cc: Thomas Gleixner Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1349873598-12583-4-git-send-email-jolsa@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 40 ++++++++++++++++++++++++++++++++++ arch/x86/kernel/cpu/perf_event.h | 2 ++ arch/x86/kernel/cpu/perf_event_intel.c | 2 ++ 3 files changed, 44 insertions(+) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 39737a678a8..8a1fa23452d 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1392,6 +1392,46 @@ static struct attribute_group x86_pmu_events_group = { .attrs = events_attr, }; +ssize_t x86_event_sysfs_show(char *page, u64 config) +{ + u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT); + u64 umask = (config & ARCH_PERFMON_EVENTSEL_UMASK) >> 8; + u64 cmask = (config & ARCH_PERFMON_EVENTSEL_CMASK) >> 24; + bool edge = (config & ARCH_PERFMON_EVENTSEL_EDGE); + bool pc = (config & ARCH_PERFMON_EVENTSEL_PIN_CONTROL); + bool any = (config & ARCH_PERFMON_EVENTSEL_ANY); + bool inv = (config & ARCH_PERFMON_EVENTSEL_INV); + ssize_t ret; + + /* + * We have whole page size to spend and just little data + * to write, so we can safely use sprintf. + */ + ret = sprintf(page, "event=0x%02llx", event); + + if (umask) + ret += sprintf(page + ret, ",umask=0x%02llx", umask); + + if (edge) + ret += sprintf(page + ret, ",edge"); + + if (pc) + ret += sprintf(page + ret, ",pc"); + + if (any) + ret += sprintf(page + ret, ",any"); + + if (inv) + ret += sprintf(page + ret, ",inv"); + + if (cmask) + ret += sprintf(page + ret, ",cmask=0x%02llx", cmask); + + ret += sprintf(page + ret, "\n"); + + return ret; +} + static int __init init_hw_perf_events(void) { struct x86_pmu_quirk *quirk; diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 6f75b6a7f37..f8aa2f6677f 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -538,6 +538,8 @@ static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip) regs->ip = ip; } +ssize_t x86_event_sysfs_show(char *page, u64 config); + #ifdef CONFIG_CPU_SUP_AMD int amd_pmu_init(void); diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 324bb523d9d..6106d3b44aa 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1628,6 +1628,7 @@ static __initconst const struct x86_pmu core_pmu = { .event_constraints = intel_core_event_constraints, .guest_get_msrs = core_guest_get_msrs, .format_attrs = intel_arch_formats_attr, + .events_sysfs_show = x86_event_sysfs_show, }; struct intel_shared_regs *allocate_shared_regs(int cpu) @@ -1766,6 +1767,7 @@ static __initconst const struct x86_pmu intel_pmu = { .pebs_aliases = intel_pebs_aliases_core2, .format_attrs = intel_arch3_formats_attr, + .events_sysfs_show = x86_event_sysfs_show, .cpu_prepare = intel_pmu_cpu_prepare, .cpu_starting = intel_pmu_cpu_starting, -- cgit v1.2.3 From 0bf79d44133de42af01a70a1700b8bb4b6d3fb92 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 10 Oct 2012 14:53:14 +0200 Subject: perf/x86: Add hardware events translations for AMD cpus Add support for AMD processors to display 'events' sysfs directory (/sys/devices/cpu/events/) with hw event translations: # ls /sys/devices/cpu/events/ branch-instructions branch-misses bus-cycles cache-misses cache-references cpu-cycles instructions ref-cycles stalled-cycles-backend stalled-cycles-frontend Suggested-by: Peter Zijlstra Signed-off-by: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Stephane Eranian Cc: Linus Torvalds Cc: Andrew Morton Cc: Thomas Gleixner Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1349873598-12583-5-git-send-email-jolsa@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 3 +-- arch/x86/kernel/cpu/perf_event.h | 2 +- arch/x86/kernel/cpu/perf_event_amd.c | 9 +++++++++ arch/x86/kernel/cpu/perf_event_intel.c | 11 +++++++++-- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 8a1fa23452d..0a55ab2ff84 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1392,9 +1392,8 @@ static struct attribute_group x86_pmu_events_group = { .attrs = events_attr, }; -ssize_t x86_event_sysfs_show(char *page, u64 config) +ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event) { - u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT); u64 umask = (config & ARCH_PERFMON_EVENTSEL_UMASK) >> 8; u64 cmask = (config & ARCH_PERFMON_EVENTSEL_CMASK) >> 24; bool edge = (config & ARCH_PERFMON_EVENTSEL_EDGE); diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index f8aa2f6677f..21419b9178b 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -538,7 +538,7 @@ static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip) regs->ip = ip; } -ssize_t x86_event_sysfs_show(char *page, u64 config); +ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event); #ifdef CONFIG_CPU_SUP_AMD diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 4528ae7b6ec..c93bc4e813a 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -568,6 +568,14 @@ amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, struct perf_event *ev } } +static ssize_t amd_event_sysfs_show(char *page, u64 config) +{ + u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT) | + (config & AMD64_EVENTSEL_EVENT) >> 24; + + return x86_event_sysfs_show(page, config, event); +} + static __initconst const struct x86_pmu amd_pmu = { .name = "AMD", .handle_irq = x86_pmu_handle_irq, @@ -591,6 +599,7 @@ static __initconst const struct x86_pmu amd_pmu = { .put_event_constraints = amd_put_event_constraints, .format_attrs = amd_format_attr, + .events_sysfs_show = amd_event_sysfs_show, .cpu_prepare = amd_pmu_cpu_prepare, .cpu_starting = amd_pmu_cpu_starting, diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 6106d3b44aa..93b9e1181f8 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -1603,6 +1603,13 @@ static struct attribute *intel_arch_formats_attr[] = { NULL, }; +ssize_t intel_event_sysfs_show(char *page, u64 config) +{ + u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT); + + return x86_event_sysfs_show(page, config, event); +} + static __initconst const struct x86_pmu core_pmu = { .name = "core", .handle_irq = x86_pmu_handle_irq, @@ -1628,7 +1635,7 @@ static __initconst const struct x86_pmu core_pmu = { .event_constraints = intel_core_event_constraints, .guest_get_msrs = core_guest_get_msrs, .format_attrs = intel_arch_formats_attr, - .events_sysfs_show = x86_event_sysfs_show, + .events_sysfs_show = intel_event_sysfs_show, }; struct intel_shared_regs *allocate_shared_regs(int cpu) @@ -1767,7 +1774,7 @@ static __initconst const struct x86_pmu intel_pmu = { .pebs_aliases = intel_pebs_aliases_core2, .format_attrs = intel_arch3_formats_attr, - .events_sysfs_show = x86_event_sysfs_show, + .events_sysfs_show = intel_event_sysfs_show, .cpu_prepare = intel_pmu_cpu_prepare, .cpu_starting = intel_pmu_cpu_starting, -- cgit v1.2.3 From 20550a434583c78f8ff9a2819639e2bacbe58574 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 10 Oct 2012 14:53:15 +0200 Subject: perf/x86: Add hardware events translations for Intel P6 cpus Add support for Intel P6 processors to display 'events' sysfs directory (/sys/devices/cpu/events/) with hw event translations: # ls /sys/devices/cpu/events/ branch-instructions branch-misses bus-cycles cache-misses cache-references cpu-cycles instructions ref-cycles stalled-cycles-backend stalled-cycles-frontend Suggested-by: Peter Zijlstra Signed-off-by: Jiri Olsa Cc: Vince Weaver Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1349873598-12583-6-git-send-email-jolsa@redhat.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.h | 1 + arch/x86/kernel/cpu/perf_event_p6.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 21419b9178b..115c1ea9774 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -539,6 +539,7 @@ static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip) } ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event); +ssize_t intel_event_sysfs_show(char *page, u64 config); #ifdef CONFIG_CPU_SUP_AMD diff --git a/arch/x86/kernel/cpu/perf_event_p6.c b/arch/x86/kernel/cpu/perf_event_p6.c index e4dd0f7a045..900b76b5d6e 100644 --- a/arch/x86/kernel/cpu/perf_event_p6.c +++ b/arch/x86/kernel/cpu/perf_event_p6.c @@ -134,6 +134,8 @@ static __initconst const struct x86_pmu p6_pmu = { .event_constraints = p6_event_constraints, .format_attrs = intel_p6_formats_attr, + .events_sysfs_show = intel_event_sysfs_show, + }; __init int p6_pmu_init(void) -- cgit v1.2.3 From 3fded963cdae12ff891a55efc866437506c3f912 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 10 Oct 2012 14:53:16 +0200 Subject: perf tools: Fix PMU object alias initialization The pmu_lookup should return pmus that do not expose the 'events' group attribute in sysfs. Also it should fail when any other error during 'events' lookup is hit (pmu_aliases fails). Signed-off-by: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1349873598-12583-7-git-send-email-jolsa@redhat.com Signed-off-by: Ingo Molnar --- tools/perf/util/pmu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 8a2229da594..18e84801d4d 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -164,7 +164,7 @@ static int pmu_aliases(char *name, struct list_head *head) "%s/bus/event_source/devices/%s/events", sysfs, name); if (stat(path, &st) < 0) - return -1; + return 0; /* no error if 'events' does not exist */ if (pmu_aliases_parse(path, head)) return -1; @@ -296,6 +296,9 @@ static struct perf_pmu *pmu_lookup(char *name) if (pmu_format(name, &format)) return NULL; + if (pmu_aliases(name, &aliases)) + return NULL; + if (pmu_type(name, &type)) return NULL; @@ -305,8 +308,6 @@ static struct perf_pmu *pmu_lookup(char *name) pmu->cpus = pmu_cpumask(name); - pmu_aliases(name, &aliases); - INIT_LIST_HEAD(&pmu->format); INIT_LIST_HEAD(&pmu->aliases); list_splice(&format, &pmu->format); -- cgit v1.2.3 From 1d33d6dce11e2c900daeca8110d56b95f1174188 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 10 Oct 2012 14:53:17 +0200 Subject: perf tools: Add support to specify hw event as PMU event term Add a way to specify hw event as PMU event term like: 'cpu/event=cpu-cycles/u' 'cpu/event=instructions,.../u' 'cpu/cycles,.../u' The 'event=cpu-cycles' term is replaced/translated by the hw events term translation, which is exposed by sysfs 'events' group attribute. Add parser bits, the rest is already handled by the PMU alias code. Signed-off-by: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1349873598-12583-8-git-send-email-jolsa@redhat.com Signed-off-by: Ingo Molnar --- tools/perf/util/parse-events.c | 18 ++++++++++++++++++ tools/perf/util/parse-events.h | 2 ++ tools/perf/util/parse-events.y | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 75c7b0fca6d..2fe15874e46 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1142,6 +1142,24 @@ int parse_events__term_str(struct parse_events__term **term, config, str, 0); } +int parse_events__term_sym_hw(struct parse_events__term **term, + char *config, unsigned idx) +{ + struct event_symbol *sym; + + BUG_ON(idx >= PERF_COUNT_HW_MAX); + sym = &event_symbols_hw[idx]; + + if (config) + return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, + PARSE_EVENTS__TERM_TYPE_USER, config, + (char *) sym->symbol, 0); + else + return new_term(term, PARSE_EVENTS__TERM_TYPE_STR, + PARSE_EVENTS__TERM_TYPE_USER, + (char *) "event", (char *) sym->symbol, 0); +} + int parse_events__term_clone(struct parse_events__term **new, struct parse_events__term *term) { diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 839230ceb18..ac9a6aacf2f 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -76,6 +76,8 @@ int parse_events__term_num(struct parse_events__term **_term, int type_term, char *config, u64 num); int parse_events__term_str(struct parse_events__term **_term, int type_term, char *config, char *str); +int parse_events__term_sym_hw(struct parse_events__term **term, + char *config, unsigned idx); int parse_events__term_clone(struct parse_events__term **new, struct parse_events__term *term); void parse_events__free_terms(struct list_head *terms); diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index cd88209e3c5..0f9914ae6ba 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -352,6 +352,15 @@ PE_NAME '=' PE_VALUE $$ = term; } | +PE_NAME '=' PE_VALUE_SYM_HW +{ + struct parse_events__term *term; + int config = $3 & 255; + + ABORT_ON(parse_events__term_sym_hw(&term, $1, config)); + $$ = term; +} +| PE_NAME { struct parse_events__term *term; @@ -361,6 +370,15 @@ PE_NAME $$ = term; } | +PE_VALUE_SYM_HW +{ + struct parse_events__term *term; + int config = $1 & 255; + + ABORT_ON(parse_events__term_sym_hw(&term, NULL, config)); + $$ = term; +} +| PE_TERM '=' PE_NAME { struct parse_events__term *term; -- cgit v1.2.3 From 3f3a20648797c3ff49c6ebfe10747ef0acd37c50 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 10 Oct 2012 14:53:18 +0200 Subject: perf test: Add automated tests for pmu sysfs translated events Add automated tests for all events found under PMU/events directory. Tested events are in the 'cpu/event=xxx/u' format, where 'xxx' is substituted by every event found. The 'event=xxx' term is translated to the cpu specific term. We only check that the event is created (not the real config numbers) and that the modifier is properly set. Signed-off-by: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Stephane Eranian Cc: Linus Torvalds Cc: Andrew Morton Cc: Thomas Gleixner Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1349873598-12583-9-git-send-email-jolsa@redhat.com Signed-off-by: Ingo Molnar --- tools/perf/util/parse-events-test.c | 68 +++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c index 516ecd9ddd6..b49c2eebff3 100644 --- a/tools/perf/util/parse-events-test.c +++ b/tools/perf/util/parse-events-test.c @@ -443,6 +443,23 @@ static int test__checkevent_pmu_name(struct perf_evlist *evlist) return 0; } +static int test__checkevent_pmu_events(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel; + + evsel = list_entry(evlist->entries.next, struct perf_evsel, node); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); + TEST_ASSERT_VAL("wrong exclude_user", + !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", + evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + + return 0; +} + static int test__checkterms_simple(struct list_head *terms) { struct parse_events__term *term; @@ -1024,6 +1041,51 @@ static int test_pmu(void) return !ret; } +static int test_pmu_events(void) +{ + struct stat st; + char path[PATH_MAX]; + struct dirent *ent; + DIR *dir; + int ret; + + snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/events/", + sysfs_find_mountpoint()); + + ret = stat(path, &st); + if (ret) { + pr_debug("ommiting PMU cpu events tests\n"); + return 0; + } + + dir = opendir(path); + if (!dir) { + pr_debug("can't open pmu event dir"); + return -1; + } + + while (!ret && (ent = readdir(dir))) { +#define MAX_NAME 100 + struct test__event_st e; + char name[MAX_NAME]; + + if (!strcmp(ent->d_name, ".") || + !strcmp(ent->d_name, "..")) + continue; + + snprintf(name, MAX_NAME, "cpu/event=%s/u", ent->d_name); + + e.name = name; + e.check = test__checkevent_pmu_events; + + ret = test_event(&e); +#undef MAX_NAME + } + + closedir(dir); + return ret; +} + int parse_events__test(void) { int ret1, ret2 = 0; @@ -1040,6 +1102,12 @@ do { \ if (test_pmu()) TEST_EVENTS(test__events_pmu); + if (test_pmu()) { + int ret = test_pmu_events(); + if (ret) + return ret; + } + ret1 = test_terms(test__terms, ARRAY_SIZE(test__terms)); if (!ret2) ret2 = ret1; -- cgit v1.2.3 From 99fb4a122e96203dfd6c67d99d908aafd20f4753 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 20 Oct 2012 23:05:19 +0400 Subject: lockdep: Use KSYM_NAME_LEN'ed buffer for __get_key_name() Not a big deal, but since other __get_key_name() callers use it lets be consistent. Signed-off-by: Cyrill Gorcunov Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20121020190519.GH25467@moon Signed-off-by: Ingo Molnar --- kernel/lockdep_proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/lockdep_proc.c b/kernel/lockdep_proc.c index 91c32a0b612..b2c71c5873e 100644 --- a/kernel/lockdep_proc.c +++ b/kernel/lockdep_proc.c @@ -39,7 +39,7 @@ static void l_stop(struct seq_file *m, void *v) static void print_name(struct seq_file *m, struct lock_class *class) { - char str[128]; + char str[KSYM_NAME_LEN]; const char *name = class->name; if (!name) { -- cgit v1.2.3 From 269833bd5a0f4443873da358b71675a890b47c3c Mon Sep 17 00:00:00 2001 From: Ma Ling Date: Thu, 18 Oct 2012 03:52:45 +0800 Subject: x86/asm: Clean up copy_page_*() comments and code Modern CPUs use fast-string instruction to accelerate copy performance, by combining data into 128 bit chunks. Modify comments and coding style to match it. Signed-off-by: Ma Ling Cc: iant@google.com Link: http://lkml.kernel.org/r/1350503565-19167-1-git-send-email-ling.ma@intel.com [ Cleaned up the clean up. ] Signed-off-by: Ingo Molnar --- arch/x86/lib/copy_page_64.S | 120 ++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 61 deletions(-) diff --git a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S index 6b34d04d096..176cca67212 100644 --- a/arch/x86/lib/copy_page_64.S +++ b/arch/x86/lib/copy_page_64.S @@ -5,91 +5,89 @@ #include ALIGN -copy_page_c: +copy_page_rep: CFI_STARTPROC - movl $4096/8,%ecx - rep movsq + movl $4096/8, %ecx + rep movsq ret CFI_ENDPROC -ENDPROC(copy_page_c) +ENDPROC(copy_page_rep) -/* Don't use streaming store because it's better when the target - ends up in cache. */ - -/* Could vary the prefetch distance based on SMP/UP */ +/* + * Don't use streaming copy unless the CPU indicates X86_FEATURE_REP_GOOD. + * Could vary the prefetch distance based on SMP/UP. +*/ ENTRY(copy_page) CFI_STARTPROC - subq $2*8,%rsp + subq $2*8, %rsp CFI_ADJUST_CFA_OFFSET 2*8 - movq %rbx,(%rsp) + movq %rbx, (%rsp) CFI_REL_OFFSET rbx, 0 - movq %r12,1*8(%rsp) + movq %r12, 1*8(%rsp) CFI_REL_OFFSET r12, 1*8 - movl $(4096/64)-5,%ecx + movl $(4096/64)-5, %ecx .p2align 4 .Loop64: - dec %rcx - - movq (%rsi), %rax - movq 8 (%rsi), %rbx - movq 16 (%rsi), %rdx - movq 24 (%rsi), %r8 - movq 32 (%rsi), %r9 - movq 40 (%rsi), %r10 - movq 48 (%rsi), %r11 - movq 56 (%rsi), %r12 + dec %rcx + movq 0x8*0(%rsi), %rax + movq 0x8*1(%rsi), %rbx + movq 0x8*2(%rsi), %rdx + movq 0x8*3(%rsi), %r8 + movq 0x8*4(%rsi), %r9 + movq 0x8*5(%rsi), %r10 + movq 0x8*6(%rsi), %r11 + movq 0x8*7(%rsi), %r12 prefetcht0 5*64(%rsi) - movq %rax, (%rdi) - movq %rbx, 8 (%rdi) - movq %rdx, 16 (%rdi) - movq %r8, 24 (%rdi) - movq %r9, 32 (%rdi) - movq %r10, 40 (%rdi) - movq %r11, 48 (%rdi) - movq %r12, 56 (%rdi) + movq %rax, 0x8*0(%rdi) + movq %rbx, 0x8*1(%rdi) + movq %rdx, 0x8*2(%rdi) + movq %r8, 0x8*3(%rdi) + movq %r9, 0x8*4(%rdi) + movq %r10, 0x8*5(%rdi) + movq %r11, 0x8*6(%rdi) + movq %r12, 0x8*7(%rdi) - leaq 64 (%rsi), %rsi - leaq 64 (%rdi), %rdi + leaq 64 (%rsi), %rsi + leaq 64 (%rdi), %rdi - jnz .Loop64 + jnz .Loop64 - movl $5,%ecx + movl $5, %ecx .p2align 4 .Loop2: - decl %ecx - - movq (%rsi), %rax - movq 8 (%rsi), %rbx - movq 16 (%rsi), %rdx - movq 24 (%rsi), %r8 - movq 32 (%rsi), %r9 - movq 40 (%rsi), %r10 - movq 48 (%rsi), %r11 - movq 56 (%rsi), %r12 - - movq %rax, (%rdi) - movq %rbx, 8 (%rdi) - movq %rdx, 16 (%rdi) - movq %r8, 24 (%rdi) - movq %r9, 32 (%rdi) - movq %r10, 40 (%rdi) - movq %r11, 48 (%rdi) - movq %r12, 56 (%rdi) - - leaq 64(%rdi),%rdi - leaq 64(%rsi),%rsi - + decl %ecx + + movq 0x8*0(%rsi), %rax + movq 0x8*1(%rsi), %rbx + movq 0x8*2(%rsi), %rdx + movq 0x8*3(%rsi), %r8 + movq 0x8*4(%rsi), %r9 + movq 0x8*5(%rsi), %r10 + movq 0x8*6(%rsi), %r11 + movq 0x8*7(%rsi), %r12 + + movq %rax, 0x8*0(%rdi) + movq %rbx, 0x8*1(%rdi) + movq %rdx, 0x8*2(%rdi) + movq %r8, 0x8*3(%rdi) + movq %r9, 0x8*4(%rdi) + movq %r10, 0x8*5(%rdi) + movq %r11, 0x8*6(%rdi) + movq %r12, 0x8*7(%rdi) + + leaq 64(%rdi), %rdi + leaq 64(%rsi), %rsi jnz .Loop2 - movq (%rsp),%rbx + movq (%rsp), %rbx CFI_RESTORE rbx - movq 1*8(%rsp),%r12 + movq 1*8(%rsp), %r12 CFI_RESTORE r12 - addq $2*8,%rsp + addq $2*8, %rsp CFI_ADJUST_CFA_OFFSET -2*8 ret .Lcopy_page_end: @@ -103,7 +101,7 @@ ENDPROC(copy_page) .section .altinstr_replacement,"ax" 1: .byte 0xeb /* jmp */ - .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */ + .byte (copy_page_rep - copy_page) - (2f - 1b) /* offset */ 2: .previous .section .altinstructions,"a" -- cgit v1.2.3 From ce37f400336a34bb6e72c4700f9dcc2a41ff7163 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Mon, 8 Oct 2012 13:07:30 +0100 Subject: x86: Allow tracing of functions in arch/x86/kernel/rtc.c Move native_read_tsc() to tsc.c to allow profiling to be re-enabled for rtc.c. Signed-off-by: David Vrabel Cc: Peter Zijlstra Cc: Frederic Weisbecker Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1349698050-6560-1-git-send-email-david.vrabel@citrix.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/Makefile | 1 - arch/x86/kernel/rtc.c | 6 ------ arch/x86/kernel/tsc.c | 6 ++++++ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 91ce48f05f9..9fd5eed3f8f 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -9,7 +9,6 @@ CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE) ifdef CONFIG_FUNCTION_TRACER # Do not profile debug and lowlevel utilities CFLAGS_REMOVE_tsc.o = -pg -CFLAGS_REMOVE_rtc.o = -pg CFLAGS_REMOVE_paravirt-spinlocks.o = -pg CFLAGS_REMOVE_pvclock.o = -pg CFLAGS_REMOVE_kvmclock.o = -pg diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index 4929c1be0ac..801602b5d74 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c @@ -195,12 +195,6 @@ void read_persistent_clock(struct timespec *ts) ts->tv_nsec = 0; } -unsigned long long native_read_tsc(void) -{ - return __native_read_tsc(); -} -EXPORT_SYMBOL(native_read_tsc); - static struct resource rtc_resources[] = { [0] = { diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index cfa5d4f7ca5..06ccb5073a3 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -77,6 +77,12 @@ unsigned long long sched_clock(void) __attribute__((alias("native_sched_clock"))); #endif +unsigned long long native_read_tsc(void) +{ + return __native_read_tsc(); +} +EXPORT_SYMBOL(native_read_tsc); + int check_tsc_unstable(void) { return tsc_unstable; -- cgit v1.2.3 From 525fae21317658ae556ca850f3004319004641d1 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 23 Oct 2012 18:28:00 +0200 Subject: pinctrl: at91: fix typo on PULL_UP Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: Ludovic Desroches Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 01bf92459fd..f10fad2079c 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -58,7 +58,7 @@ static struct at91_gpio_chip *gpio_chips[MAX_GPIO_BANKS]; static int gpio_banks; -#define PULL_UP (0 << 1) +#define PULL_UP (1 << 0) #define MULTI_DRIVE (1 << 1) /** -- cgit v1.2.3 From a728c7cdd033f0cbeacc302d2409a2428e68e1be Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 23 Oct 2012 15:56:41 +0200 Subject: gpio/at91: auto request and configure the pio as input when the interrupt is used via DT If we do this interrupt-parent = <&pioA>; interrupts = <7 0x0>; The current core map the irq correctly but the gpio is not configured as input. The pinctrl configure the pin as gpio with the correct mux parameter but is not responsible to configure it as input. So do it during the xlate Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index f10fad2079c..676b199d6d2 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1255,9 +1255,33 @@ static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq, return 0; } +int at91_gpio_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_type) +{ + struct at91_gpio_chip *at91_gpio = d->host_data; + int ret; + int pin = at91_gpio->chip.base + intspec[0]; + + if (WARN_ON(intsize < 2)) + return -EINVAL; + *out_hwirq = intspec[0]; + *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; + + ret = gpio_request(pin, ctrlr->full_name); + if (ret) + return ret; + + ret = gpio_direction_input(pin); + if (ret) + return ret; + + return 0; +} + static struct irq_domain_ops at91_gpio_ops = { .map = at91_gpio_irq_map, - .xlate = irq_domain_xlate_twocell, + .xlate = at91_gpio_irq_domain_xlate, }; static int at91_gpio_of_irq_setup(struct device_node *node, -- cgit v1.2.3 From 28d213bac4649a1868fa78dab2d3b1ef09235171 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 9 Oct 2012 17:50:01 +0200 Subject: perf tools: Diplays more output on features check for make V=1 Adding more verbose output for compile time features checking, to ease up debuging of feature detection failures. Suggested-by: Ingo Molnar Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-fbjha6xs5soyaiek8j4142xg@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 46 ++++++++++++++++++++--------------------- tools/perf/config/utilities.mak | 11 ++++++++-- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index f530502630a..6790cb441a6 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -155,15 +155,15 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ -include config/feature-tests.mak -ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all),y) +ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y) CFLAGS := $(CFLAGS) -fstack-protector-all endif -ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector),y) +ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y) CFLAGS := $(CFLAGS) -Wstack-protector endif -ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var),y) +ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y) CFLAGS := $(CFLAGS) -Wvolatile-register-var endif @@ -172,7 +172,7 @@ endif BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE BASIC_LDFLAGS = -ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS)),y) +ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y) BIONIC := 1 EXTLIBS := $(filter-out -lrt,$(EXTLIBS)) EXTLIBS := $(filter-out -lpthread,$(EXTLIBS)) @@ -477,9 +477,9 @@ ifdef NO_LIBELF NO_LIBUNWIND := 1 else FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y) +ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y) FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS) - ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y) + ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y) LIBC_SUPPORT := 1 endif ifeq ($(BIONIC),1) @@ -494,7 +494,7 @@ ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y) endif else FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS) - ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y) + ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y) msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev); NO_DWARF := 1 endif # Dwarf support @@ -510,7 +510,7 @@ ifdef LIBUNWIND_DIR endif FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS) -ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND)),y) +ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y) msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99); NO_LIBUNWIND := 1 endif # Libunwind support @@ -539,7 +539,7 @@ LIB_OBJS += $(OUTPUT)util/symbol-minimal.o else # NO_LIBELF BASIC_CFLAGS += -DLIBELF_SUPPORT -ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON)),y) +ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON),-DLIBELF_MMAP),y) BASIC_CFLAGS += -DLIBELF_MMAP endif @@ -565,7 +565,7 @@ endif ifndef NO_LIBAUDIT FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit - ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT)),y) + ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y) msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev); else BASIC_CFLAGS += -DLIBAUDIT_SUPPORT @@ -576,7 +576,7 @@ endif ifndef NO_NEWT FLAGS_NEWT=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lnewt - ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT)),y) + ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT),libnewt),y) msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev); else # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h @@ -605,10 +605,10 @@ endif ifndef NO_GTK2 FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) - ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y) + ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y) msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); else - ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2)),y) + ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y) BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR endif BASIC_CFLAGS += -DGTK2_SUPPORT @@ -635,7 +635,7 @@ else PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) - ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED)),y) + ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y) BASIC_CFLAGS += -DNO_LIBPERL else ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS) @@ -689,11 +689,11 @@ else PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) - ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED)),y) + ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y) $(call disable-python,Python.h (for Python 2.x)) else - ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED)),y) + ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y) $(warning Python 3 is not yet supported; please set) $(warning PYTHON and/or PYTHON_CONFIG appropriately.) $(warning If you also have Python 2 installed, then) @@ -727,22 +727,22 @@ else BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE else FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd - has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD)) + has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd) ifeq ($(has_bfd),y) EXTLIBS += -lbfd else FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty - has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY)) + has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty) ifeq ($(has_bfd_iberty),y) EXTLIBS += -lbfd -liberty else FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz - has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z)) + has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz) ifeq ($(has_bfd_iberty_z),y) EXTLIBS += -lbfd -liberty -lz else FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty - has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE)) + has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle) ifeq ($(has_cplus_demangle),y) EXTLIBS += -liberty BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE @@ -764,19 +764,19 @@ ifeq ($(NO_PERF_REGS),0) endif ifndef NO_STRLCPY - ifeq ($(call try-cc,$(SOURCE_STRLCPY),),y) + ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y) BASIC_CFLAGS += -DHAVE_STRLCPY endif endif ifndef NO_ON_EXIT - ifeq ($(call try-cc,$(SOURCE_ON_EXIT),),y) + ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y) BASIC_CFLAGS += -DHAVE_ON_EXIT endif endif ifndef NO_BACKTRACE - ifeq ($(call try-cc,$(SOURCE_BACKTRACE),),y) + ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y) BASIC_CFLAGS += -DBACKTRACE_SUPPORT endif endif diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak index 8046182a19e..ea853c279b3 100644 --- a/tools/perf/config/utilities.mak +++ b/tools/perf/config/utilities.mak @@ -180,9 +180,16 @@ _gea_warn = $(warning The path '$(1)' is not executable.) _gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) # try-cc -# Usage: option = $(call try-cc, source-to-build, cc-options) +# Usage: option = $(call try-cc, source-to-build, cc-options, msg) +ifndef V +TRY_CC_OUTPUT= > /dev/null 2>&1 +else +TRY_CC_MSG=echo "CHK $(3)" 1>&2; +endif + try-cc = $(shell sh -c \ 'TMP="$(OUTPUT)$(TMPOUT).$$$$"; \ + $(TRY_CC_MSG) \ echo "$(1)" | \ - $(CC) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \ + $(CC) -x c - $(2) -o "$$TMP" $(TRY_CC_OUTPUT) && echo y; \ rm -f "$$TMP"') -- cgit v1.2.3 From feb8ada4ea5540ee986b23abd95597118729704c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 9 Oct 2012 15:15:25 -0300 Subject: perf tools: Remove noise in python version feature test Now that the feature tests honours the V=1 make verbosity switch, add a return to the main() routine in the python version test, to avoid this distraction: CHK python version : In function 'main': :5: warning: control reaches end of non-void function Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-999no5yxlc2oqo9xjeez5zmv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/config/feature-tests.mak | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index 3ef5ec9cdff..f5ac77485a4 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak @@ -121,7 +121,10 @@ define SOURCE_PYTHON_VERSION #if PY_VERSION_HEX >= 0x03000000 #error #endif -int main(void){} +int main(void) +{ + return 0; +} endef define SOURCE_PYTHON_EMBED #include -- cgit v1.2.3 From 68e94f4eb56d92ccb617a98fcac5e575702ec4fd Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Tue, 16 Oct 2012 02:33:38 +0300 Subject: perf tools: Try to find cross-built objdump path As we have architecture information of saved perf.data file, we can try to find cross-built objdump path. The triplets include support for Android (arm, x86 and mips architectures). Signed-off-by: Irina Tirdea Originally-by: Namhyung Kim Acked-by: Namhyung Kim Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1350344020-8071-5-git-send-email-irina.tirdea@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 2 + tools/perf/arch/common.c | 178 ++++++++++++++++++++++++++++++++++++++++++ tools/perf/arch/common.h | 10 +++ tools/perf/builtin-annotate.c | 7 ++ tools/perf/builtin-report.c | 7 ++ tools/perf/util/annotate.h | 1 - 6 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 tools/perf/arch/common.c create mode 100644 tools/perf/arch/common.h diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 6790cb441a6..78a81eda127 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -426,6 +426,8 @@ LIB_OBJS += $(OUTPUT)ui/helpline.o LIB_OBJS += $(OUTPUT)ui/hist.o LIB_OBJS += $(OUTPUT)ui/stdio/hist.o +LIB_OBJS += $(OUTPUT)arch/common.o + BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o BUILTIN_OBJS += $(OUTPUT)builtin-bench.o # Benchmark modules diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c new file mode 100644 index 00000000000..2367b253f03 --- /dev/null +++ b/tools/perf/arch/common.c @@ -0,0 +1,178 @@ +#include +#include +#include "common.h" +#include "../util/debug.h" + +const char *const arm_triplets[] = { + "arm-eabi-", + "arm-linux-androideabi-", + "arm-unknown-linux-", + "arm-unknown-linux-gnu-", + "arm-unknown-linux-gnueabi-", + NULL +}; + +const char *const powerpc_triplets[] = { + "powerpc-unknown-linux-gnu-", + "powerpc64-unknown-linux-gnu-", + NULL +}; + +const char *const s390_triplets[] = { + "s390-ibm-linux-", + NULL +}; + +const char *const sh_triplets[] = { + "sh-unknown-linux-gnu-", + "sh64-unknown-linux-gnu-", + NULL +}; + +const char *const sparc_triplets[] = { + "sparc-unknown-linux-gnu-", + "sparc64-unknown-linux-gnu-", + NULL +}; + +const char *const x86_triplets[] = { + "x86_64-pc-linux-gnu-", + "x86_64-unknown-linux-gnu-", + "i686-pc-linux-gnu-", + "i586-pc-linux-gnu-", + "i486-pc-linux-gnu-", + "i386-pc-linux-gnu-", + "i686-linux-android-", + "i686-android-linux-", + NULL +}; + +const char *const mips_triplets[] = { + "mips-unknown-linux-gnu-", + "mipsel-linux-android-", + NULL +}; + +static bool lookup_path(char *name) +{ + bool found = false; + char *path, *tmp; + char buf[PATH_MAX]; + char *env = getenv("PATH"); + + if (!env) + return false; + + env = strdup(env); + if (!env) + return false; + + path = strtok_r(env, ":", &tmp); + while (path) { + scnprintf(buf, sizeof(buf), "%s/%s", path, name); + if (access(buf, F_OK) == 0) { + found = true; + break; + } + path = strtok_r(NULL, ":", &tmp); + } + free(env); + return found; +} + +static int lookup_triplets(const char *const *triplets, const char *name) +{ + int i; + char buf[PATH_MAX]; + + for (i = 0; triplets[i] != NULL; i++) { + scnprintf(buf, sizeof(buf), "%s%s", triplets[i], name); + if (lookup_path(buf)) + return i; + } + return -1; +} + +static int perf_session_env__lookup_binutils_path(struct perf_session_env *env, + const char *name, + const char **path) +{ + int idx; + char *arch, *cross_env; + struct utsname uts; + const char *const *path_list; + char *buf = NULL; + + if (uname(&uts) < 0) + goto out; + + /* + * We don't need to try to find objdump path for native system. + * Just use default binutils path (e.g.: "objdump"). + */ + if (!strcmp(uts.machine, env->arch)) + goto out; + + cross_env = getenv("CROSS_COMPILE"); + if (cross_env) { + if (asprintf(&buf, "%s%s", cross_env, name) < 0) + goto out_error; + if (buf[0] == '/') { + if (access(buf, F_OK) == 0) + goto out; + goto out_error; + } + if (lookup_path(buf)) + goto out; + free(buf); + } + + arch = env->arch; + + if (!strcmp(arch, "arm")) + path_list = arm_triplets; + else if (!strcmp(arch, "powerpc")) + path_list = powerpc_triplets; + else if (!strcmp(arch, "sh")) + path_list = sh_triplets; + else if (!strcmp(arch, "s390")) + path_list = s390_triplets; + else if (!strcmp(arch, "sparc")) + path_list = sparc_triplets; + else if (!strcmp(arch, "x86") || !strcmp(arch, "i386") || + !strcmp(arch, "i486") || !strcmp(arch, "i586") || + !strcmp(arch, "i686")) + path_list = x86_triplets; + else if (!strcmp(arch, "mips")) + path_list = mips_triplets; + else { + ui__error("binutils for %s not supported.\n", arch); + goto out_error; + } + + idx = lookup_triplets(path_list, name); + if (idx < 0) { + ui__error("Please install %s for %s.\n" + "You can add it to PATH, set CROSS_COMPILE or " + "override the default using --%s.\n", + name, arch, name); + goto out_error; + } + + if (asprintf(&buf, "%s%s", path_list[idx], name) < 0) + goto out_error; + +out: + *path = buf; + return 0; +out_error: + free(buf); + *path = NULL; + return -1; +} + +int perf_session_env__lookup_objdump(struct perf_session_env *env) +{ + return perf_session_env__lookup_binutils_path(env, "objdump", + &objdump_path); +} diff --git a/tools/perf/arch/common.h b/tools/perf/arch/common.h new file mode 100644 index 00000000000..ede246eda9b --- /dev/null +++ b/tools/perf/arch/common.h @@ -0,0 +1,10 @@ +#ifndef ARCH_PERF_COMMON_H +#define ARCH_PERF_COMMON_H + +#include "../util/session.h" + +extern const char *objdump_path; + +int perf_session_env__lookup_objdump(struct perf_session_env *env); + +#endif /* ARCH_PERF_COMMON_H */ diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 690fa9a5465..c4bb6457b19 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -28,6 +28,7 @@ #include "util/hist.h" #include "util/session.h" #include "util/tool.h" +#include "arch/common.h" #include @@ -186,6 +187,12 @@ static int __cmd_annotate(struct perf_annotate *ann) goto out_delete; } + if (!objdump_path) { + ret = perf_session_env__lookup_objdump(&session->header.env); + if (ret) + goto out_delete; + } + ret = perf_session__process_events(session, &ann->tool); if (ret) goto out_delete; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 5104a40af56..90d1162bb8b 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -33,6 +33,7 @@ #include "util/thread.h" #include "util/sort.h" #include "util/hist.h" +#include "arch/common.h" #include @@ -672,6 +673,12 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) has_br_stack = perf_header__has_feat(&session->header, HEADER_BRANCH_STACK); + if (!objdump_path) { + ret = perf_session_env__lookup_objdump(&session->header.env); + if (ret) + goto error; + } + if (sort__branch_mode == -1 && has_br_stack) sort__branch_mode = 1; diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 39242dcee8f..a4dd25a61a0 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -154,6 +154,5 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused, #endif extern const char *disassembler_style; -extern const char *objdump_path; #endif /* __PERF_ANNOTATE_H */ -- cgit v1.2.3 From 03f2f93ae00762eb881424df1c688d034fd341ee Mon Sep 17 00:00:00 2001 From: "Suzuki K. Poulose" Date: Fri, 31 Aug 2012 12:39:18 +0530 Subject: Account the nr_entries in rblist properly The nr_entries in rblist is never decremented when an element is deleted. Also, use rblist__remove_node to delete a node in rblist__delete(). This would keep the nr_entries sane. Signed-off-by: Suzuki K. Poulose Acked-by: David S. Ahern Cc: David S. Ahern Link: http://lkml.kernel.org/r/20120831070834.14806.87398.stgit@suzukikp.in.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/rblist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/rblist.c b/tools/perf/util/rblist.c index 0171fb61100..a16cdd2625a 100644 --- a/tools/perf/util/rblist.c +++ b/tools/perf/util/rblist.c @@ -44,6 +44,7 @@ int rblist__add_node(struct rblist *rblist, const void *new_entry) void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node) { rb_erase(rb_node, &rblist->entries); + --rblist->nr_entries; rblist->node_delete(rblist, rb_node); } @@ -87,8 +88,7 @@ void rblist__delete(struct rblist *rblist) while (next) { pos = next; next = rb_next(pos); - rb_erase(pos, &rblist->entries); - rblist->node_delete(rblist, pos); + rblist__remove_node(rblist, pos); } free(rblist); } -- cgit v1.2.3 From 2305c82fb35dd2c8c9533303bb1693f1636c66e4 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Thu, 13 Sep 2012 14:59:15 -0600 Subject: perf tools: Give user better message if precise is not supported Platforms (e.g., VM's) without support for precise mode get a confusing error message. e.g., $ perf record -e cycles:p -a -- sleep 1 Error: sys_perf_event_open() syscall returned with 95 (Operation not supported). /bin/dmesg may provide additional information. No hardware sampling interrupt available. No APIC? If so then you can boot the kernel with the "lapic" boot parameter to force-enable it. sleep: Terminated which is not clear that precise mode might be the root problem. With this patch: $ perf record -e cycles:p -fo /tmp/perf.data -- sleep 1 Error: 'precise' request may not be supported. Try removing 'p' modifier sleep: Terminated v2: softened message to 'may not be' supported per Robert's suggestion Signed-off-by: David Ahern Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Robert Richter Link: http://lkml.kernel.org/r/1347569955-54626-4-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 5 +++++ tools/perf/builtin-top.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 73b5d7f9119..53c9892e96d 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -317,6 +317,11 @@ try_again: perf_evsel__name(pos)); rc = -err; goto out; + } else if ((err == EOPNOTSUPP) && (attr->precise_ip)) { + ui__error("\'precise\' request may not be supported. " + "Try removing 'p' modifier\n"); + rc = -err; + goto out; } printf("\n"); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index fb9da71eba1..f2ecd498c72 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -977,6 +977,10 @@ try_again: ui__error("Too many events are opened.\n" "Try again after reducing the number of events\n"); goto out_err; + } else if ((err == EOPNOTSUPP) && (attr->precise_ip)) { + ui__error("\'precise\' request may not be supported. " + "Try removing 'p' modifier\n"); + goto out_err; } ui__error("The sys_perf_event_open() syscall " -- cgit v1.2.3 From 9a8e85ad0b61ec0720df7d24392163c2a12626d0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 24 Oct 2012 15:44:41 -0200 Subject: perf test: Align the 'Ok'/'FAILED!' test results And also print 'FAILED!' in red. Suggested-by: Ingo Molnar Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-rkisq85w24il3e2yl3nzumhu@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-test.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index e2d9872de3d..a04276e81f4 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c @@ -6,6 +6,7 @@ #include "builtin.h" #include "util/cache.h" +#include "util/color.h" #include "util/debug.h" #include "util/debugfs.h" #include "util/evlist.h" @@ -1485,18 +1486,31 @@ static bool perf_test__matches(int curr, int argc, const char *argv[]) static int __cmd_test(int argc, const char *argv[]) { int i = 0; + int width = 0; + while (tests[i].func) { + int len = strlen(tests[i].desc); + + if (width < len) + width = len; + ++i; + } + + i = 0; while (tests[i].func) { int curr = i++, err; if (!perf_test__matches(curr, argc, argv)) continue; - pr_info("%2d: %s:", i, tests[curr].desc); + pr_info("%2d: %-*s:", i, width, tests[curr].desc); pr_debug("\n--- start ---\n"); err = tests[curr].func(); pr_debug("---- end ----\n%s:", tests[curr].desc); - pr_info(" %s\n", err ? "FAILED!\n" : "Ok"); + if (err) + color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n"); + else + pr_info(" Ok\n"); } return 0; -- cgit v1.2.3 From af71befa282ddf51c09509978abe1e83de8fe7eb Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 24 Oct 2012 11:07:09 -0700 Subject: rcu: Wordsmith help text for RCU_USER_QS kernel parameter This commit adds a "try" missing from the end of the first paragraph of the RCU_USER_QS help text. [ paulmck: Also fix up the last paragraph a bit. ] Signed-off-by: Paul Gortmaker Signed-off-by: Paul E. McKenney --- init/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index b63e7982c1c..ec62139207d 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -494,11 +494,11 @@ config RCU_USER_QS puts RCU in extended quiescent state when the CPU runs in userspace. It means that when a CPU runs in userspace, it is excluded from the global RCU state machine and thus doesn't - to keep the timer tick on for RCU. + try to keep the timer tick on for RCU. Unless you want to hack and help the development of the full - tickless feature, you shouldn't enable this option. It adds - unnecessary overhead. + tickless feature, you shouldn't enable this option. It also + adds unnecessary overhead. If unsure say N -- cgit v1.2.3 From b8b345bae8cb6745f2afdd28bb2d93f9cf0d7f2c Mon Sep 17 00:00:00 2001 From: Ivo Sieben Date: Wed, 24 Oct 2012 14:35:42 +0200 Subject: TTY: Report warning when low_latency flag is wrongly used When a driver has the low_latency flag set and uses the schedule_flip() function to initiate copying data to the line discipline, a workqueue is scheduled in but never actually flushed. This is incorrect use of the low_latency flag (driver should not support the low_latency flag, or use the tty_flip_buffer_push() function instead). Make sure a warning is reported to catch incorrect use of the low_latency flag. This patch goes with: cee4ad1ed90a0959fc29f9d30a2526e5e9522cfa Signed-off-by: Ivo Sieben Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 06725f5cc81..6cf87d7afb7 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -365,6 +365,7 @@ void tty_schedule_flip(struct tty_struct *tty) { struct tty_bufhead *buf = &tty->port->buf; unsigned long flags; + WARN_ON(tty->low_latency); spin_lock_irqsave(&buf->lock, flags); if (buf->tail != NULL) -- cgit v1.2.3 From 9484b009b57b6523a5c7477a899f4438942febde Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Wed, 3 Oct 2012 07:40:04 +0900 Subject: serial: samsung: use clk_prepare_enable and clk_disable_unprepare Convert clk_enable/clk_disable to clk_prepare_enable/clk_disable_unprepare calls as required by common clock framework. Signed-off-by: Thomas Abraham Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 7f04717176a..740458ca62c 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -530,16 +530,16 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, switch (level) { case 3: if (!IS_ERR(ourport->baudclk)) - clk_disable(ourport->baudclk); + clk_disable_unprepare(ourport->baudclk); - clk_disable(ourport->clk); + clk_disable_unprepare(ourport->clk); break; case 0: - clk_enable(ourport->clk); + clk_prepare_enable(ourport->clk); if (!IS_ERR(ourport->baudclk)) - clk_enable(ourport->baudclk); + clk_prepare_enable(ourport->baudclk); break; default: @@ -713,11 +713,11 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, s3c24xx_serial_setsource(port, clk_sel); if (!IS_ERR(ourport->baudclk)) { - clk_disable(ourport->baudclk); + clk_disable_unprepare(ourport->baudclk); ourport->baudclk = ERR_PTR(-EINVAL); } - clk_enable(clk); + clk_prepare_enable(clk); ourport->baudclk = clk; ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; @@ -1287,9 +1287,9 @@ static int s3c24xx_serial_resume(struct device *dev) struct s3c24xx_uart_port *ourport = to_ourport(port); if (port) { - clk_enable(ourport->clk); + clk_prepare_enable(ourport->clk); s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port)); - clk_disable(ourport->clk); + clk_disable_unprepare(ourport->clk); uart_resume_port(&s3c24xx_uart_drv, port); } -- cgit v1.2.3 From b15d5380e471f9ce27180b14d5080abc2e2f30ec Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Wed, 3 Oct 2012 16:27:43 +0400 Subject: serial/8250/8250_early: Prevent rounding error in uartclk Modify divisor to select the nearest baud rate divider rather than the lowest. It minimizes baud rate errors especially on low UART clock frequencies. For example, if uartclk is 33000000 and baud is 115200 the ratio is about 17.9 The current code selects 17 (5% error) but should select 18 (0.5% error). This 5% error in baud rate leads to garbage on receiving end, while 0.5% doesn't. The issue showed up when using the stock 8250 driver for Synopsys DW UART. This was on a FPGA with ~12MHz UART clock. When we enabled early serial, we saw garbage which was narrowed down to the rounding error. So the bug had been latent and it only showed up with such low clock rates. Signed-off-by: Alexey Brodkin Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_early.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index eaafb98debe..843a150ba10 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -140,7 +140,7 @@ static void __init init_port(struct early_serial8250_device *device) serial_out(port, UART_FCR, 0); /* no fifo */ serial_out(port, UART_MCR, 0x3); /* DTR + RTS */ - divisor = port->uartclk / (16 * device->baud); + divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud); c = serial_in(port, UART_LCR); serial_out(port, UART_LCR, c | UART_LCR_DLAB); serial_out(port, UART_DLL, divisor & 0xff); -- cgit v1.2.3 From 54ec52b6dd3b0ba4bc4eb97e7e1b2534705b326c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 3 Oct 2012 15:31:58 -0700 Subject: tty/serial/8250: Make omap hardware workarounds local to 8250.h This allows us to get rid of the ifdefs in 8250.c. Cc: Alan Cox Signed-off-by: Tony Lindgren Signed-off-by: Greg Kroah-Hartman --- arch/arm/plat-omap/include/plat/serial.h | 9 -------- drivers/tty/serial/8250/8250.c | 9 +++----- drivers/tty/serial/8250/8250.h | 36 ++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h index 65fce44dce3..b780470d03e 100644 --- a/arch/arm/plat-omap/include/plat/serial.h +++ b/arch/arm/plat-omap/include/plat/serial.h @@ -109,15 +109,6 @@ #define OMAP5UART4 OMAP4UART4 #define ZOOM_UART 95 /* Only on zoom2/3 */ -/* This is only used by 8250.c for omap1510 */ -#define is_omap_port(pt) ({int __ret = 0; \ - if ((pt)->port.mapbase == OMAP1_UART1_BASE || \ - (pt)->port.mapbase == OMAP1_UART2_BASE || \ - (pt)->port.mapbase == OMAP1_UART3_BASE) \ - __ret = 1; \ - __ret; \ - }) - #ifndef __ASSEMBLER__ struct omap_board_data; diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 3ba4234592b..5ccbd90540c 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c @@ -2349,16 +2349,14 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, serial_port_out(port, UART_EFR, efr); } -#ifdef CONFIG_ARCH_OMAP1 /* Workaround to enable 115200 baud on OMAP1510 internal ports */ - if (cpu_is_omap1510() && is_omap_port(up)) { + if (is_omap1510_8250(up)) { if (baud == 115200) { quot = 1; serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1); } else serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0); } -#endif /* * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2, @@ -2439,10 +2437,9 @@ static unsigned int serial8250_port_size(struct uart_8250_port *pt) { if (pt->port.iotype == UPIO_AU) return 0x1000; -#ifdef CONFIG_ARCH_OMAP1 - if (is_omap_port(pt)) + if (is_omap1_8250(pt)) return 0x16 << pt->port.regshift; -#endif + return 8 << pt->port.regshift; } diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 5a76f9c8d36..3b4ea84898c 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -106,3 +106,39 @@ static inline int serial8250_pnp_init(void) { return 0; } static inline void serial8250_pnp_exit(void) { } #endif +#ifdef CONFIG_ARCH_OMAP1 +static inline int is_omap1_8250(struct uart_8250_port *pt) +{ + int res; + + switch (pt->port.mapbase) { + case OMAP1_UART1_BASE: + case OMAP1_UART2_BASE: + case OMAP1_UART3_BASE: + res = 1; + break; + default: + res = 0; + break; + } + + return res; +} + +static inline int is_omap1510_8250(struct uart_8250_port *pt) +{ + if (!cpu_is_omap1510()) + return 0; + + return is_omap1_8250(pt); +} +#else +static inline int is_omap1_8250(struct uart_8250_port *pt) +{ + return 0; +} +static inline int is_omap1510_8250(struct uart_8250_port *pt) +{ + return 0; +} +#endif -- cgit v1.2.3 From 59c2e855e43735f4ab93b8b8db96206219f6c1d4 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 8 Oct 2012 10:35:46 +0800 Subject: serial: vt8500: fix possible memory leak in vt8500_serial_probe() vt8500_port is malloced in vt8500_serial_probe() and should be freed before leaving from the error handling cases, otherwise it will cause memory leak. Fix it by move the allocation of vt8500_port after those test. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Acked-by: Tony Prisk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/vt8500_serial.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index 205d4cf4a06..4354fe565f6 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -567,10 +567,6 @@ static int __devinit vt8500_serial_probe(struct platform_device *pdev) if (!mmres || !irqres) return -ENODEV; - vt8500_port = kzalloc(sizeof(struct vt8500_port), GFP_KERNEL); - if (!vt8500_port) - return -ENOMEM; - if (np) port = of_alias_get_id(np, "serial"); if (port > VT8500_MAX_PORTS) @@ -593,6 +589,10 @@ static int __devinit vt8500_serial_probe(struct platform_device *pdev) return -EBUSY; } + vt8500_port = kzalloc(sizeof(struct vt8500_port), GFP_KERNEL); + if (!vt8500_port) + return -ENOMEM; + vt8500_port->uart.type = PORT_VT8500; vt8500_port->uart.iotype = UPIO_MEM; vt8500_port->uart.mapbase = mmres->start; -- cgit v1.2.3 From b61c5ed57195ec97006d8d3ede1f583f6618b79e Mon Sep 17 00:00:00 2001 From: James Hogan Date: Mon, 15 Oct 2012 10:25:58 +0100 Subject: tty: serial: 8250_dw: Implement suspend/resume Implement suspend and resume callbacks for DesignWare 8250 driver. They're simple wrappers around serial8250_{suspend,resume}_port. Signed-off-by: James Hogan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dw.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index c3b2ec0c8c0..b19b8c54780 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -161,6 +161,29 @@ static int __devexit dw8250_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM +static int dw8250_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct dw8250_data *data = platform_get_drvdata(pdev); + + serial8250_suspend_port(data->line); + + return 0; +} + +static int dw8250_resume(struct platform_device *pdev) +{ + struct dw8250_data *data = platform_get_drvdata(pdev); + + serial8250_resume_port(data->line); + + return 0; +} +#else +#define dw8250_suspend NULL +#define dw8250_resume NULL +#endif /* CONFIG_PM */ + static const struct of_device_id dw8250_match[] = { { .compatible = "snps,dw-apb-uart" }, { /* Sentinel */ } @@ -175,6 +198,8 @@ static struct platform_driver dw8250_platform_driver = { }, .probe = dw8250_probe, .remove = __devexit_p(dw8250_remove), + .suspend = dw8250_suspend, + .resume = dw8250_resume, }; module_platform_driver(dw8250_platform_driver); -- cgit v1.2.3 From 8ae763cd7e88a6bc552a6615ba6c1dcaa4828cbf Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 16 Oct 2012 11:53:44 +0100 Subject: audit: remove bogus tty name check tty name is an array not a pointer Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- kernel/auditsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 2f186ed80c4..fc7376bf86e 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -1159,7 +1159,7 @@ void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) cred = current_cred(); spin_lock_irq(&tsk->sighand->siglock); - if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) + if (tsk->signal && tsk->signal->tty) tty = tsk->signal->tty->name; else tty = "(none)"; -- cgit v1.2.3 From 7a0c4edae99da6ab3d402deb0d88410251c6ac63 Mon Sep 17 00:00:00 2001 From: Sangho Yi Date: Thu, 18 Oct 2012 00:15:13 +0900 Subject: tty: tty_mutex.c: Fixed coding style warning (using printk) Here I fixed from printk(KERN_ERR, ... to pr_err(... on tty_mutex.c Signed-off-by: Sangho Yi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_mutex.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index 67feac9e6eb..2e41abebbcb 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c @@ -19,7 +19,7 @@ static void __lockfunc tty_lock_nested(struct tty_struct *tty, unsigned int subclass) { if (tty->magic != TTY_MAGIC) { - printk(KERN_ERR "L Bad %p\n", tty); + pr_err("L Bad %p\n", tty); WARN_ON(1); return; } @@ -36,7 +36,7 @@ EXPORT_SYMBOL(tty_lock); void __lockfunc tty_unlock(struct tty_struct *tty) { if (tty->magic != TTY_MAGIC) { - printk(KERN_ERR "U Bad %p\n", tty); + pr_err("U Bad %p\n", tty); WARN_ON(1); return; } -- cgit v1.2.3 From 08ec212c0f92cbf30e3ecc7349f18151714041d6 Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Fri, 19 Oct 2012 10:45:07 +0200 Subject: x86: ce4100: allow second UART usage The current CE4100 and 8250_pci code have both a limitation preventing the registration and usage of CE4100's second UART. This patch changes the platform code fixing up the UART port to work on a relative UART port base address, as well as the 8250_pci code to make it register 2 UART ports for CE4100 and pass the port index down to all consumers. Signed-off-by: Florian Fainelli Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- arch/x86/platform/ce4100/ce4100.c | 3 +++ drivers/tty/serial/8250/8250_pci.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c index 4c61b52191e..0dcc30e9df8 100644 --- a/arch/x86/platform/ce4100/ce4100.c +++ b/arch/x86/platform/ce4100/ce4100.c @@ -92,8 +92,11 @@ static void ce4100_serial_fixup(int port, struct uart_port *up, up->membase = (void __iomem *)__fix_to_virt(FIX_EARLYCON_MEM_BASE); up->membase += up->mapbase & ~PAGE_MASK; + up->mapbase += port * 0x100; + up->membase += port * 0x100; up->iotype = UPIO_MEM32; up->regshift = 2; + up->irq = 4; } #endif up->iobase = 0; diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 17b7d26abf4..cec8852dd1b 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1068,7 +1068,7 @@ ce4100_serial_setup(struct serial_private *priv, { int ret; - ret = setup_port(priv, port, 0, 0, board->reg_shift); + ret = setup_port(priv, port, idx, 0, board->reg_shift); port->port.iotype = UPIO_MEM32; port->port.type = PORT_XSCALE; port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); @@ -2658,8 +2658,8 @@ static struct pciserial_board pci_boards[] __devinitdata = { .first_offset = 0x1000, }, [pbn_ce4100_1_115200] = { - .flags = FL_BASE0, - .num_ports = 1, + .flags = FL_BASE_BARS, + .num_ports = 2, .base_baud = 921600, .reg_shift = 2, }, -- cgit v1.2.3 From ad3d1e5fc94e1d617298cf9b8fb522e2d219521a Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 22 Oct 2012 12:42:59 +0800 Subject: TTY: hvcs: fix missing unlock on error in hvcs_initialize() Add the missing unlock on the error handling path in function hvcs_initialize(). Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvcs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index cab5c7adf8e..744c3b8eea4 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1496,8 +1496,10 @@ static int __devinit hvcs_initialize(void) num_ttys_to_alloc = hvcs_parm_num_devs; hvcs_tty_driver = alloc_tty_driver(num_ttys_to_alloc); - if (!hvcs_tty_driver) + if (!hvcs_tty_driver) { + mutex_unlock(&hvcs_init_mutex); return -ENOMEM; + } if (hvcs_alloc_index_list(num_ttys_to_alloc)) { rc = -ENOMEM; -- cgit v1.2.3 From c97399418a25b18943c9910fb28e0ee5ecc3c316 Mon Sep 17 00:00:00 2001 From: Ivo Sieben Date: Wed, 17 Oct 2012 14:03:14 +0200 Subject: tty: Use raw spin lock to protect TTY ldisc administration The global "normal" spin lock that guards the line discipline administration is replaced by a raw spin lock. On a PREEMPT_RT system this prevents unwanted scheduling overhead around the line discipline administration. On a 200 MHz AT91SAM9261 processor setup this fixes about 100us of scheduling overhead on a TTY read or write call. Signed-off-by: Ivo Sieben Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index f4e6754525d..c5782294e53 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -26,7 +26,7 @@ * callers who will do ldisc lookups and cannot sleep. */ -static DEFINE_SPINLOCK(tty_ldisc_lock); +static DEFINE_RAW_SPINLOCK(tty_ldisc_lock); static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); /* Line disc dispatch table */ static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; @@ -49,21 +49,21 @@ static void put_ldisc(struct tty_ldisc *ld) * If this is the last user, free the ldisc, and * release the ldisc ops. * - * We really want an "atomic_dec_and_lock_irqsave()", + * We really want an "atomic_dec_and_raw_lock_irqsave()", * but we don't have it, so this does it by hand. */ - local_irq_save(flags); - if (atomic_dec_and_lock(&ld->users, &tty_ldisc_lock)) { + raw_spin_lock_irqsave(&tty_ldisc_lock, flags); + if (atomic_dec_and_test(&ld->users)) { struct tty_ldisc_ops *ldo = ld->ops; ldo->refcount--; module_put(ldo->owner); - spin_unlock_irqrestore(&tty_ldisc_lock, flags); + raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); kfree(ld); return; } - local_irq_restore(flags); + raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); wake_up(&ld->wq_idle); } @@ -88,11 +88,11 @@ int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc) if (disc < N_TTY || disc >= NR_LDISCS) return -EINVAL; - spin_lock_irqsave(&tty_ldisc_lock, flags); + raw_spin_lock_irqsave(&tty_ldisc_lock, flags); tty_ldiscs[disc] = new_ldisc; new_ldisc->num = disc; new_ldisc->refcount = 0; - spin_unlock_irqrestore(&tty_ldisc_lock, flags); + raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); return ret; } @@ -118,12 +118,12 @@ int tty_unregister_ldisc(int disc) if (disc < N_TTY || disc >= NR_LDISCS) return -EINVAL; - spin_lock_irqsave(&tty_ldisc_lock, flags); + raw_spin_lock_irqsave(&tty_ldisc_lock, flags); if (tty_ldiscs[disc]->refcount) ret = -EBUSY; else tty_ldiscs[disc] = NULL; - spin_unlock_irqrestore(&tty_ldisc_lock, flags); + raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); return ret; } @@ -134,7 +134,7 @@ static struct tty_ldisc_ops *get_ldops(int disc) unsigned long flags; struct tty_ldisc_ops *ldops, *ret; - spin_lock_irqsave(&tty_ldisc_lock, flags); + raw_spin_lock_irqsave(&tty_ldisc_lock, flags); ret = ERR_PTR(-EINVAL); ldops = tty_ldiscs[disc]; if (ldops) { @@ -144,7 +144,7 @@ static struct tty_ldisc_ops *get_ldops(int disc) ret = ldops; } } - spin_unlock_irqrestore(&tty_ldisc_lock, flags); + raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); return ret; } @@ -152,10 +152,10 @@ static void put_ldops(struct tty_ldisc_ops *ldops) { unsigned long flags; - spin_lock_irqsave(&tty_ldisc_lock, flags); + raw_spin_lock_irqsave(&tty_ldisc_lock, flags); ldops->refcount--; module_put(ldops->owner); - spin_unlock_irqrestore(&tty_ldisc_lock, flags); + raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); } /** @@ -287,11 +287,11 @@ static struct tty_ldisc *tty_ldisc_try(struct tty_struct *tty) unsigned long flags; struct tty_ldisc *ld; - spin_lock_irqsave(&tty_ldisc_lock, flags); + raw_spin_lock_irqsave(&tty_ldisc_lock, flags); ld = NULL; if (test_bit(TTY_LDISC, &tty->flags)) ld = get_ldisc(tty->ldisc); - spin_unlock_irqrestore(&tty_ldisc_lock, flags); + raw_spin_unlock_irqrestore(&tty_ldisc_lock, flags); return ld; } -- cgit v1.2.3 From e1a9c17969f0aa60cb00f1f777b33a07f4e84883 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Sun, 21 Oct 2012 12:00:30 +0800 Subject: tty: serial: KGDB support for PXA Actually, in order to support KGDB over serial console one must implement two callbacks for character polling. Clone them from 8250 driver with a bit of tuning. Signed-off-by: Denis V. Lunev Signed-off-by: Marko Katic CC: Eric Miao CC: Russell King Acked-by: Haojian Zhuang drivers/tty/serial/pxa.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 55 insertions(+), 0 deletions(-) Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pxa.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 9033fc6e0e4..2764828251f 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -705,6 +705,57 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) clk_disable_unprepare(up->clk); } +#ifdef CONFIG_CONSOLE_POLL +/* + * Console polling routines for writing and reading from the uart while + * in an interrupt or debug context. + */ + +static int serial_pxa_get_poll_char(struct uart_port *port) +{ + struct uart_pxa_port *up = (struct uart_pxa_port *)port; + unsigned char lsr = serial_in(up, UART_LSR); + + while (!(lsr & UART_LSR_DR)) + lsr = serial_in(up, UART_LSR); + + return serial_in(up, UART_RX); +} + + +static void serial_pxa_put_poll_char(struct uart_port *port, + unsigned char c) +{ + unsigned int ier; + struct uart_pxa_port *up = (struct uart_pxa_port *)port; + + /* + * First save the IER then disable the interrupts + */ + ier = serial_in(up, UART_IER); + serial_out(up, UART_IER, UART_IER_UUE); + + wait_for_xmitr(up); + /* + * Send the character out. + * If a LF, also do CR... + */ + serial_out(up, UART_TX, c); + if (c == 10) { + wait_for_xmitr(up); + serial_out(up, UART_TX, 13); + } + + /* + * Finally, wait for transmitter to become empty + * and restore the IER + */ + wait_for_xmitr(up); + serial_out(up, UART_IER, ier); +} + +#endif /* CONFIG_CONSOLE_POLL */ + static int __init serial_pxa_console_setup(struct console *co, char *options) { @@ -759,6 +810,10 @@ struct uart_ops serial_pxa_pops = { .request_port = serial_pxa_request_port, .config_port = serial_pxa_config_port, .verify_port = serial_pxa_verify_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_get_char = serial_pxa_get_poll_char, + .poll_put_char = serial_pxa_put_poll_char, +#endif }; static struct uart_driver serial_pxa_reg = { -- cgit v1.2.3 From 95113728f03cc6775ae895133c7fc420221cc8a4 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 14 Oct 2012 11:05:23 +0400 Subject: serial: clps711x: Add platform_driver interface to clps711x driver Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index d0f719fafc8..07fef1cbc11 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -37,10 +37,13 @@ #include #include #include +#include #include #include +#define UART_CLPS711X_NAME "uart-clps711x" + #define UART_NR 2 #define SERIAL_CLPS711X_MAJOR 204 @@ -543,7 +546,7 @@ static struct uart_driver clps711x_reg = { .cons = CLPS711X_CONSOLE, }; -static int __init clps711xuart_init(void) +static int __devinit uart_clps711x_probe(struct platform_device *pdev) { int ret, i; @@ -559,7 +562,7 @@ static int __init clps711xuart_init(void) return 0; } -static void __exit clps711xuart_exit(void) +static int __devexit uart_clps711x_remove(struct platform_device *pdev) { int i; @@ -567,12 +570,36 @@ static void __exit clps711xuart_exit(void) uart_remove_one_port(&clps711x_reg, &clps711x_ports[i]); uart_unregister_driver(&clps711x_reg); + + return 0; } -module_init(clps711xuart_init); -module_exit(clps711xuart_exit); +static struct platform_driver clps711x_uart_driver = { + .driver = { + .name = UART_CLPS711X_NAME, + .owner = THIS_MODULE, + }, + .probe = uart_clps711x_probe, + .remove = __devexit_p(uart_clps711x_remove), +}; +module_platform_driver(clps711x_uart_driver); + +static struct platform_device clps711x_uart_device = { + .name = UART_CLPS711X_NAME, +}; + +static int __init uart_clps711x_init(void) +{ + return platform_device_register(&clps711x_uart_device); +} +module_init(uart_clps711x_init); + +static void __exit uart_clps711x_exit(void) +{ + platform_device_unregister(&clps711x_uart_device); +} +module_exit(uart_clps711x_exit); MODULE_AUTHOR("Deep Blue Solutions Ltd"); -MODULE_DESCRIPTION("CLPS-711x generic serial driver"); +MODULE_DESCRIPTION("CLPS711X serial driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS_CHARDEV(SERIAL_CLPS711X_MAJOR, SERIAL_CLPS711X_MINOR); -- cgit v1.2.3 From 117d5d424a1ee7aedaf6ad8b0ba6eff163c57815 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 14 Oct 2012 11:05:24 +0400 Subject: serial: clps711x: Convert all static variables to dynamic This patch converts all static variables of clps711x serial driver to dynamic allocating. In this case we are should remove console_initcall() and declare console during driver registration. Early kernel messages can be retrieved by add "earlyprintk" option to the kernel command line. Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 211 ++++++++++++++++++------------------------ 1 file changed, 89 insertions(+), 122 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 07fef1cbc11..de6aa33c305 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -43,28 +43,29 @@ #include #define UART_CLPS711X_NAME "uart-clps711x" +#define UART_CLPS711X_NR 2 +#define UART_CLPS711X_MAJOR 204 +#define UART_CLPS711X_MINOR 40 -#define UART_NR 2 - -#define SERIAL_CLPS711X_MAJOR 204 -#define SERIAL_CLPS711X_MINOR 40 -#define SERIAL_CLPS711X_NR UART_NR - -/* - * We use the relevant SYSCON register as a base address for these ports. - */ -#define UBRLCR(port) ((port)->iobase + UBRLCR1 - SYSCON1) -#define UARTDR(port) ((port)->iobase + UARTDR1 - SYSCON1) -#define SYSFLG(port) ((port)->iobase + SYSFLG1 - SYSCON1) -#define SYSCON(port) ((port)->iobase + SYSCON1 - SYSCON1) - -#define TX_IRQ(port) ((port)->irq) -#define RX_IRQ(port) ((port)->irq + 1) +#define UBRLCR(port) ((port)->line ? UBRLCR2 : UBRLCR1) +#define UARTDR(port) ((port)->line ? UARTDR2 : UARTDR1) +#define SYSFLG(port) ((port)->line ? SYSFLG2 : SYSFLG1) +#define SYSCON(port) ((port)->line ? SYSCON2 : SYSCON1) +#define TX_IRQ(port) ((port)->line ? IRQ_UTXINT2 : IRQ_UTXINT1) +#define RX_IRQ(port) ((port)->line ? IRQ_URXINT2 : IRQ_URXINT1) #define UART_ANY_ERR (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR) #define tx_enabled(port) ((port)->unused[0]) +struct clps711x_port { + struct uart_driver uart; + struct uart_port port[UART_CLPS711X_NR]; +#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE + struct console console; +#endif +}; + static void clps711xuart_stop_tx(struct uart_port *port) { if (tx_enabled(port)) { @@ -382,7 +383,7 @@ static int clps711xuart_request_port(struct uart_port *port) return 0; } -static struct uart_ops clps711x_pops = { +static struct uart_ops uart_clps711x_ops = { .tx_empty = clps711xuart_tx_empty, .set_mctrl = clps711xuart_set_mctrl_null, .get_mctrl = clps711xuart_get_mctrl, @@ -400,72 +401,39 @@ static struct uart_ops clps711x_pops = { .request_port = clps711xuart_request_port, }; -static struct uart_port clps711x_ports[UART_NR] = { - { - .iobase = SYSCON1, - .irq = IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */ - .uartclk = 3686400, - .fifosize = 16, - .ops = &clps711x_pops, - .line = 0, - .flags = UPF_BOOT_AUTOCONF, - }, - { - .iobase = SYSCON2, - .irq = IRQ_UTXINT2, /* IRQ_URXINT2 */ - .uartclk = 3686400, - .fifosize = 16, - .ops = &clps711x_pops, - .line = 1, - .flags = UPF_BOOT_AUTOCONF, - } -}; - #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE -static void clps711xuart_console_putchar(struct uart_port *port, int ch) +static void uart_clps711x_console_putchar(struct uart_port *port, int ch) { while (clps_readl(SYSFLG(port)) & SYSFLG_UTXFF) barrier(); - clps_writel(ch, UARTDR(port)); + + clps_writew(ch, UARTDR(port)); } -/* - * Print a string to the serial port trying not to disturb - * any possible real use of the port... - * - * The console_lock must be held when we get here. - * - * Note that this is called with interrupts already disabled - */ -static void -clps711xuart_console_write(struct console *co, const char *s, - unsigned int count) +static void uart_clps711x_console_write(struct console *co, const char *c, + unsigned n) { - struct uart_port *port = clps711x_ports + co->index; - unsigned int status, syscon; + struct clps711x_port *s = (struct clps711x_port *)co->data; + struct uart_port *port = &s->port[co->index]; + u32 syscon; - /* - * Ensure that the port is enabled. - */ + /* Ensure that the port is enabled */ syscon = clps_readl(SYSCON(port)); clps_writel(syscon | SYSCON_UARTEN, SYSCON(port)); - uart_console_write(port, s, count, clps711xuart_console_putchar); + uart_console_write(port, c, n, uart_clps711x_console_putchar); - /* - * Finally, wait for transmitter to become empty - * and restore the uart state. - */ - do { - status = clps_readl(SYSFLG(port)); - } while (status & SYSFLG_UBUSY); + /* Wait for transmitter to become empty */ + while (clps_readl(SYSFLG(port)) & SYSFLG_UBUSY) + barrier(); + /* Restore the uart state */ clps_writel(syscon, SYSCON(port)); } -static void __init -clps711xuart_console_get_options(struct uart_port *port, int *baud, - int *parity, int *bits) +static void uart_clps711x_console_get_options(struct uart_port *port, + int *baud, int *parity, + int *bits) { if (clps_readl(SYSCON(port)) & SYSCON_UARTEN) { unsigned int ubrlcr, quot; @@ -490,86 +458,85 @@ clps711xuart_console_get_options(struct uart_port *port, int *baud, } } -static int __init clps711xuart_console_setup(struct console *co, char *options) +static int uart_clps711x_console_setup(struct console *co, char *options) { - struct uart_port *port; - int baud = 38400; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - - /* - * Check whether an invalid uart number has been specified, and - * if so, search for the first available port that does have - * console support. - */ - port = uart_get_console(clps711x_ports, UART_NR, co); + int baud = 38400, bits = 8, parity = 'n', flow = 'n'; + struct clps711x_port *s = (struct clps711x_port *)co->data; + struct uart_port *port = &s->port[(co->index > 0) ? co->index : 0]; if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); else - clps711xuart_console_get_options(port, &baud, &parity, &bits); + uart_clps711x_console_get_options(port, &baud, &parity, &bits); return uart_set_options(port, co, baud, parity, bits, flow); } - -static struct uart_driver clps711x_reg; -static struct console clps711x_console = { - .name = "ttyCL", - .write = clps711xuart_console_write, - .device = uart_console_device, - .setup = clps711xuart_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &clps711x_reg, -}; - -static int __init clps711xuart_console_init(void) -{ - register_console(&clps711x_console); - return 0; -} -console_initcall(clps711xuart_console_init); - -#define CLPS711X_CONSOLE &clps711x_console -#else -#define CLPS711X_CONSOLE NULL #endif -static struct uart_driver clps711x_reg = { - .driver_name = "ttyCL", - .dev_name = "ttyCL", - .major = SERIAL_CLPS711X_MAJOR, - .minor = SERIAL_CLPS711X_MINOR, - .nr = UART_NR, - - .cons = CLPS711X_CONSOLE, -}; - static int __devinit uart_clps711x_probe(struct platform_device *pdev) { + struct clps711x_port *s; int ret, i; - printk(KERN_INFO "Serial: CLPS711x driver\n"); + s = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_port), GFP_KERNEL); + if (!s) { + dev_err(&pdev->dev, "Error allocating port structure\n"); + return -ENOMEM; + } + platform_set_drvdata(pdev, s); - ret = uart_register_driver(&clps711x_reg); - if (ret) - return ret; + s->uart.owner = THIS_MODULE; + s->uart.dev_name = "ttyCL"; + s->uart.major = UART_CLPS711X_MAJOR; + s->uart.minor = UART_CLPS711X_MINOR; + s->uart.nr = UART_CLPS711X_NR; +#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE + s->uart.cons = &s->console; + s->uart.cons->device = uart_console_device; + s->uart.cons->write = uart_clps711x_console_write; + s->uart.cons->setup = uart_clps711x_console_setup; + s->uart.cons->flags = CON_PRINTBUFFER; + s->uart.cons->index = -1; + s->uart.cons->data = s; + strcpy(s->uart.cons->name, "ttyCL"); +#endif + ret = uart_register_driver(&s->uart); + if (ret) { + dev_err(&pdev->dev, "Registering UART driver failed\n"); + goto err_out; + } - for (i = 0; i < UART_NR; i++) - uart_add_one_port(&clps711x_reg, &clps711x_ports[i]); + for (i = 0; i < UART_CLPS711X_NR; i++) { + s->port[i].line = i; + s->port[i].dev = &pdev->dev; + s->port[i].irq = TX_IRQ(&s->port[i]); + s->port[i].iobase = SYSCON(&s->port[i]); + s->port[i].type = PORT_CLPS711X; + s->port[i].fifosize = 16; + s->port[i].flags = UPF_SKIP_TEST | UPF_FIXED_TYPE; + s->port[i].uartclk = 3686400; + s->port[i].ops = &uart_clps711x_ops; + WARN_ON(uart_add_one_port(&s->uart, &s->port[i])); + } return 0; + +err_out: + platform_set_drvdata(pdev, NULL); + + return ret; } static int __devexit uart_clps711x_remove(struct platform_device *pdev) { + struct clps711x_port *s = platform_get_drvdata(pdev); int i; - for (i = 0; i < UART_NR; i++) - uart_remove_one_port(&clps711x_reg, &clps711x_ports[i]); + for (i = 0; i < UART_CLPS711X_NR; i++) + uart_remove_one_port(&s->uart, &s->port[i]); - uart_unregister_driver(&clps711x_reg); + uart_unregister_driver(&s->uart); + platform_set_drvdata(pdev, NULL); return 0; } -- cgit v1.2.3 From 3c7e9eb1603d21659a38b92f5b764d41d88fa652 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 14 Oct 2012 11:05:25 +0400 Subject: serial: clps711x: Do not use "uart_port->unused" field Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index de6aa33c305..3b17d193248 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -56,11 +56,10 @@ #define UART_ANY_ERR (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR) -#define tx_enabled(port) ((port)->unused[0]) - struct clps711x_port { struct uart_driver uart; struct uart_port port[UART_CLPS711X_NR]; + int tx_enabled[UART_CLPS711X_NR]; #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE struct console console; #endif @@ -68,17 +67,21 @@ struct clps711x_port { static void clps711xuart_stop_tx(struct uart_port *port) { - if (tx_enabled(port)) { + struct clps711x_port *s = dev_get_drvdata(port->dev); + + if (s->tx_enabled[port->line]) { disable_irq(TX_IRQ(port)); - tx_enabled(port) = 0; + s->tx_enabled[port->line] = 0; } } static void clps711xuart_start_tx(struct uart_port *port) { - if (!tx_enabled(port)) { + struct clps711x_port *s = dev_get_drvdata(port->dev); + + if (!s->tx_enabled[port->line]) { enable_irq(TX_IRQ(port)); - tx_enabled(port) = 1; + s->tx_enabled[port->line] = 1; } } @@ -148,6 +151,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id) static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) { struct uart_port *port = dev_id; + struct clps711x_port *s = dev_get_drvdata(port->dev); struct circ_buf *xmit = &port->state->xmit; int count; @@ -158,8 +162,11 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) return IRQ_HANDLED; } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - goto disable_tx_irq; + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + disable_irq_nosync(TX_IRQ(port)); + s->tx_enabled[port->line] = 0; + return IRQ_HANDLED; + } count = port->fifosize >> 1; do { @@ -173,12 +180,6 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); - if (uart_circ_empty(xmit)) { - disable_tx_irq: - disable_irq_nosync(TX_IRQ(port)); - tx_enabled(port) = 0; - } - return IRQ_HANDLED; } @@ -230,10 +231,11 @@ static void clps711xuart_break_ctl(struct uart_port *port, int break_state) static int clps711xuart_startup(struct uart_port *port) { + struct clps711x_port *s = dev_get_drvdata(port->dev); unsigned int syscon; int retval; - tx_enabled(port) = 1; + s->tx_enabled[port->line] = 1; /* * Allocate the IRQs -- cgit v1.2.3 From c08f0153f54ee0a7f3eeaf7f48dce1a71b3f8c7d Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 14 Oct 2012 11:05:26 +0400 Subject: serial: clps711x: Using CPU clock subsystem for getting base UART speed Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 3b17d193248..0884939d29c 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -58,6 +59,7 @@ struct clps711x_port { struct uart_driver uart; + struct clk *uart_clk; struct uart_port port[UART_CLPS711X_NR]; int tx_enabled[UART_CLPS711X_NR]; #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE @@ -299,10 +301,9 @@ clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios, */ termios->c_cflag |= CREAD; - /* - * Ask the core to calculate the divisor for us. - */ - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); + /* Ask the core to calculate the divisor for us */ + baud = uart_get_baud_rate(port, termios, old, port->uartclk / 4096, + port->uartclk / 16); quot = uart_get_divisor(port, baud); switch (termios->c_cflag & CSIZE) { @@ -487,6 +488,13 @@ static int __devinit uart_clps711x_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, s); + s->uart_clk = devm_clk_get(&pdev->dev, "uart"); + if (IS_ERR(s->uart_clk)) { + dev_err(&pdev->dev, "Can't get UART clocks\n"); + ret = PTR_ERR(s->uart_clk); + goto err_out; + } + s->uart.owner = THIS_MODULE; s->uart.dev_name = "ttyCL"; s->uart.major = UART_CLPS711X_MAJOR; @@ -505,6 +513,7 @@ static int __devinit uart_clps711x_probe(struct platform_device *pdev) ret = uart_register_driver(&s->uart); if (ret) { dev_err(&pdev->dev, "Registering UART driver failed\n"); + devm_clk_put(&pdev->dev, s->uart_clk); goto err_out; } @@ -516,7 +525,7 @@ static int __devinit uart_clps711x_probe(struct platform_device *pdev) s->port[i].type = PORT_CLPS711X; s->port[i].fifosize = 16; s->port[i].flags = UPF_SKIP_TEST | UPF_FIXED_TYPE; - s->port[i].uartclk = 3686400; + s->port[i].uartclk = clk_get_rate(s->uart_clk); s->port[i].ops = &uart_clps711x_ops; WARN_ON(uart_add_one_port(&s->uart, &s->port[i])); } @@ -537,6 +546,7 @@ static int __devexit uart_clps711x_remove(struct platform_device *pdev) for (i = 0; i < UART_CLPS711X_NR; i++) uart_remove_one_port(&s->uart, &s->port[i]); + devm_clk_put(&pdev->dev, s->uart_clk); uart_unregister_driver(&s->uart); platform_set_drvdata(pdev, NULL); -- cgit v1.2.3 From cf03a884b9f4a63d4bcf29614fe03ca3f8299138 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 14 Oct 2012 11:05:27 +0400 Subject: serial: clps711x: Improved TX FIFO handling Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 0884939d29c..d37460965ba 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -155,7 +155,6 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) struct uart_port *port = dev_id; struct clps711x_port *s = dev_get_drvdata(port->dev); struct circ_buf *xmit = &port->state->xmit; - int count; if (port->x_char) { clps_writel(port->x_char, UARTDR(port)); @@ -170,14 +169,13 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) return IRQ_HANDLED; } - count = port->fifosize >> 1; - do { - clps_writel(xmit->buf[xmit->tail], UARTDR(port)); + while (!uart_circ_empty(xmit)) { + clps_writew(xmit->buf[xmit->tail], UARTDR(port)); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; - if (uart_circ_empty(xmit)) + if (clps_readl(SYSFLG(port) & SYSFLG_UTXFF)) break; - } while (--count > 0); + } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); @@ -327,8 +325,9 @@ clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios, if (!(termios->c_cflag & PARODD)) ubrlcr |= UBRLCR_EVENPRT; } - if (port->fifosize > 1) - ubrlcr |= UBRLCR_FIFOEN; + + /* Enable FIFO */ + ubrlcr |= UBRLCR_FIFOEN; spin_lock_irqsave(&port->lock, flags); -- cgit v1.2.3 From 1593daf9a84f4b29e90027e0999c93da1d25478b Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 14 Oct 2012 11:05:28 +0400 Subject: serial: clps711x: Return valid modem controls for port that not support it Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index d37460965ba..7b0e539ee9c 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -191,12 +191,9 @@ static unsigned int clps711xuart_tx_empty(struct uart_port *port) static unsigned int clps711xuart_get_mctrl(struct uart_port *port) { - unsigned int port_addr; - unsigned int result = 0; - unsigned int status; + unsigned int status, result = 0; - port_addr = SYSFLG(port); - if (port_addr == SYSFLG1) { + if (port->line == 0) { status = clps_readl(SYSFLG1); if (status & SYSFLG1_DCD) result |= TIOCM_CAR; @@ -204,7 +201,8 @@ static unsigned int clps711xuart_get_mctrl(struct uart_port *port) result |= TIOCM_DSR; if (status & SYSFLG1_CTS) result |= TIOCM_CTS; - } + } else + result = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; return result; } -- cgit v1.2.3 From ec335526b4bce21f6777d3917d6d67c16009ec63 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 14 Oct 2012 11:05:29 +0400 Subject: serial: clps711x: Fix break control handling Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 7b0e539ee9c..73505c1edc7 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -218,12 +218,14 @@ static void clps711xuart_break_ctl(struct uart_port *port, int break_state) unsigned int ubrlcr; spin_lock_irqsave(&port->lock, flags); + ubrlcr = clps_readl(UBRLCR(port)); - if (break_state == -1) + if (break_state) ubrlcr |= UBRLCR_BREAK; else ubrlcr &= ~UBRLCR_BREAK; clps_writel(ubrlcr, UBRLCR(port)); + spin_unlock_irqrestore(&port->lock, flags); } -- cgit v1.2.3 From f27de95c2a2120526c8cb051d741b7eb09e78cc9 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 14 Oct 2012 11:05:30 +0400 Subject: serial: clps711x: Check for valid TTY in RX-interrupt Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 59 +++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 73505c1edc7..6039ebe349c 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -55,8 +55,6 @@ #define TX_IRQ(port) ((port)->line ? IRQ_UTXINT2 : IRQ_UTXINT1) #define RX_IRQ(port) ((port)->line ? IRQ_URXINT2 : IRQ_URXINT1) -#define UART_ANY_ERR (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR) - struct clps711x_port { struct uart_driver uart; struct clk *uart_clk; @@ -99,54 +97,55 @@ static void clps711xuart_enable_ms(struct uart_port *port) static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id) { struct uart_port *port = dev_id; - struct tty_struct *tty = port->state->port.tty; + struct tty_struct *tty = tty_port_tty_get(&port->state->port); unsigned int status, ch, flg; - status = clps_readl(SYSFLG(port)); - while (!(status & SYSFLG_URXFE)) { - ch = clps_readl(UARTDR(port)); + if (!tty) + return IRQ_HANDLED; - port->icount.rx++; + for (;;) { + status = clps_readl(SYSFLG(port)); + if (status & SYSFLG_URXFE) + break; + ch = clps_readw(UARTDR(port)); + status = ch & (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR); + ch &= 0xff; + + port->icount.rx++; flg = TTY_NORMAL; - /* - * Note that the error handling code is - * out of the main execution path - */ - if (unlikely(ch & UART_ANY_ERR)) { - if (ch & UARTDR_PARERR) + if (unlikely(status)) { + if (status & UARTDR_PARERR) port->icount.parity++; - else if (ch & UARTDR_FRMERR) + else if (status & UARTDR_FRMERR) port->icount.frame++; - if (ch & UARTDR_OVERR) + else if (status & UARTDR_OVERR) port->icount.overrun++; - ch &= port->read_status_mask; + status &= port->read_status_mask; - if (ch & UARTDR_PARERR) + if (status & UARTDR_PARERR) flg = TTY_PARITY; - else if (ch & UARTDR_FRMERR) + else if (status & UARTDR_FRMERR) flg = TTY_FRAME; - -#ifdef SUPPORT_SYSRQ - port->sysrq = 0; -#endif + else if (status & UARTDR_OVERR) + flg = TTY_OVERRUN; } if (uart_handle_sysrq_char(port, ch)) - goto ignore_char; + continue; - /* - * CHECK: does overrun affect the current character? - * ASSUMPTION: it does not. - */ - uart_insert_char(port, ch, UARTDR_OVERR, ch, flg); + if (status & port->ignore_status_mask) + continue; - ignore_char: - status = clps_readl(SYSFLG(port)); + uart_insert_char(port, status, UARTDR_OVERR, ch, flg); } + tty_flip_buffer_push(tty); + + tty_kref_put(tty); + return IRQ_HANDLED; } -- cgit v1.2.3 From 135cc7903593af78c45dc3f8e6a1f528f083e002 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 14 Oct 2012 11:05:31 +0400 Subject: serial: clps711x: Using resource-managed functions Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 6039ebe349c..7cf392829ff 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -94,7 +94,7 @@ static void clps711xuart_enable_ms(struct uart_port *port) { } -static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id) +static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) { struct uart_port *port = dev_id; struct tty_struct *tty = tty_port_tty_get(&port->state->port); @@ -149,7 +149,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) +static irqreturn_t uart_clps711x_int_tx(int irq, void *dev_id) { struct uart_port *port = dev_id; struct clps711x_port *s = dev_get_drvdata(port->dev); @@ -232,23 +232,20 @@ static int clps711xuart_startup(struct uart_port *port) { struct clps711x_port *s = dev_get_drvdata(port->dev); unsigned int syscon; - int retval; + int ret; s->tx_enabled[port->line] = 1; - - /* - * Allocate the IRQs - */ - retval = request_irq(TX_IRQ(port), clps711xuart_int_tx, 0, - "clps711xuart_tx", port); - if (retval) - return retval; - - retval = request_irq(RX_IRQ(port), clps711xuart_int_rx, 0, - "clps711xuart_rx", port); - if (retval) { - free_irq(TX_IRQ(port), port); - return retval; + /* Allocate the IRQs */ + ret = devm_request_irq(port->dev, TX_IRQ(port), uart_clps711x_int_tx, + 0, UART_CLPS711X_NAME " TX", port); + if (ret) + return ret; + + ret = devm_request_irq(port->dev, RX_IRQ(port), uart_clps711x_int_rx, + 0, UART_CLPS711X_NAME " RX", port); + if (ret) { + devm_free_irq(port->dev, TX_IRQ(port), port); + return ret; } /* @@ -265,11 +262,9 @@ static void clps711xuart_shutdown(struct uart_port *port) { unsigned int ubrlcr, syscon; - /* - * Free the interrupt - */ - free_irq(TX_IRQ(port), port); /* TX interrupt */ - free_irq(RX_IRQ(port), port); /* RX interrupt */ + /* Free the interrupts */ + devm_free_irq(port->dev, TX_IRQ(port), port); + devm_free_irq(port->dev, RX_IRQ(port), port); /* * disable the port -- cgit v1.2.3 From f52ede2ac1159f844994519ae0386def308a296b Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 14 Oct 2012 11:05:32 +0400 Subject: serial: clps711x: Disable "break"-state before port startup Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 7cf392829ff..e71508767e1 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -231,7 +231,6 @@ static void clps711xuart_break_ctl(struct uart_port *port, int break_state) static int clps711xuart_startup(struct uart_port *port) { struct clps711x_port *s = dev_get_drvdata(port->dev); - unsigned int syscon; int ret; s->tx_enabled[port->line] = 1; @@ -248,37 +247,23 @@ static int clps711xuart_startup(struct uart_port *port) return ret; } - /* - * enable the port - */ - syscon = clps_readl(SYSCON(port)); - syscon |= SYSCON_UARTEN; - clps_writel(syscon, SYSCON(port)); + /* Disable break */ + clps_writel(clps_readl(UBRLCR(port)) & ~UBRLCR_BREAK, UBRLCR(port)); + + /* Enable the port */ + clps_writel(clps_readl(SYSCON(port)) | SYSCON_UARTEN, SYSCON(port)); return 0; } static void clps711xuart_shutdown(struct uart_port *port) { - unsigned int ubrlcr, syscon; - /* Free the interrupts */ devm_free_irq(port->dev, TX_IRQ(port), port); devm_free_irq(port->dev, RX_IRQ(port), port); - /* - * disable the port - */ - syscon = clps_readl(SYSCON(port)); - syscon &= ~SYSCON_UARTEN; - clps_writel(syscon, SYSCON(port)); - - /* - * disable break condition and fifos - */ - ubrlcr = clps_readl(UBRLCR(port)); - ubrlcr &= ~(UBRLCR_FIFOEN | UBRLCR_BREAK); - clps_writel(ubrlcr, UBRLCR(port)); + /* Disable the port */ + clps_writel(clps_readl(SYSCON(port)) & ~SYSCON_UARTEN, SYSCON(port)); } static void -- cgit v1.2.3 From 7ae75e94ec1128598f91dc56ca2919c45701ec32 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 14 Oct 2012 11:05:33 +0400 Subject: serial: clps711x: Fix TERMIOS-flags handling Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index e71508767e1..90efe059571 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -273,10 +273,9 @@ clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios, unsigned int ubrlcr, baud, quot; unsigned long flags; - /* - * We don't implement CREAD. - */ - termios->c_cflag |= CREAD; + /* Mask termios capabilities we don't support */ + termios->c_cflag &= ~CMSPAR; + termios->c_iflag &= ~(BRKINT | IGNBRK); /* Ask the core to calculate the divisor for us */ baud = uart_get_baud_rate(port, termios, old, port->uartclk / 4096, @@ -297,8 +296,10 @@ clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios, ubrlcr = UBRLCR_WRDLEN8; break; } + if (termios->c_cflag & CSTOPB) ubrlcr |= UBRLCR_XSTOP; + if (termios->c_cflag & PARENB) { ubrlcr |= UBRLCR_PRTEN; if (!(termios->c_cflag & PARODD)) @@ -310,33 +311,20 @@ clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios, spin_lock_irqsave(&port->lock, flags); - /* - * Update the per-port timeout. - */ - uart_update_timeout(port, termios->c_cflag, baud); - + /* Set read status mask */ port->read_status_mask = UARTDR_OVERR; if (termios->c_iflag & INPCK) port->read_status_mask |= UARTDR_PARERR | UARTDR_FRMERR; - /* - * Characters to ignore - */ + /* Set status ignore mask */ port->ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= UARTDR_FRMERR | UARTDR_PARERR; - if (termios->c_iflag & IGNBRK) { - /* - * If we're ignoring parity and break indicators, - * ignore overruns to (for real raw support). - */ - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= UARTDR_OVERR; - } + if (!(termios->c_cflag & CREAD)) + port->ignore_status_mask |= UARTDR_OVERR | UARTDR_PARERR | + UARTDR_FRMERR; - quot -= 1; + uart_update_timeout(port, termios->c_cflag, baud); - clps_writel(ubrlcr | quot, UBRLCR(port)); + clps_writel(ubrlcr | (quot - 1), UBRLCR(port)); spin_unlock_irqrestore(&port->lock, flags); } -- cgit v1.2.3 From a1c25f2b98e10038f7d198704d033eb73bad0677 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 14 Oct 2012 11:05:34 +0400 Subject: serial: clps711x: Cleanup driver This patch performs cleanup on clps711x serial driver. This include: - Change functions naming style. - Removed unused includes. - Removed unneeded comments. Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 105 ++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 59 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 90efe059571..a0a6db5c32f 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -10,15 +10,6 @@ * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #if defined(CONFIG_SERIAL_CLPS711X_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) @@ -26,22 +17,18 @@ #endif #include -#include -#include -#include -#include -#include #include -#include -#include +#include #include #include #include #include +#include +#include +#include #include #include -#include #define UART_CLPS711X_NAME "uart-clps711x" #define UART_CLPS711X_NR 2 @@ -65,7 +52,7 @@ struct clps711x_port { #endif }; -static void clps711xuart_stop_tx(struct uart_port *port) +static void uart_clps711x_stop_tx(struct uart_port *port) { struct clps711x_port *s = dev_get_drvdata(port->dev); @@ -75,7 +62,7 @@ static void clps711xuart_stop_tx(struct uart_port *port) } } -static void clps711xuart_start_tx(struct uart_port *port) +static void uart_clps711x_start_tx(struct uart_port *port) { struct clps711x_port *s = dev_get_drvdata(port->dev); @@ -85,13 +72,14 @@ static void clps711xuart_start_tx(struct uart_port *port) } } -static void clps711xuart_stop_rx(struct uart_port *port) +static void uart_clps711x_stop_rx(struct uart_port *port) { disable_irq(RX_IRQ(port)); } -static void clps711xuart_enable_ms(struct uart_port *port) +static void uart_clps711x_enable_ms(struct uart_port *port) { + /* Do nothing */ } static irqreturn_t uart_clps711x_int_rx(int irq, void *dev_id) @@ -156,7 +144,7 @@ static irqreturn_t uart_clps711x_int_tx(int irq, void *dev_id) struct circ_buf *xmit = &port->state->xmit; if (port->x_char) { - clps_writel(port->x_char, UARTDR(port)); + clps_writew(port->x_char, UARTDR(port)); port->icount.tx++; port->x_char = 0; return IRQ_HANDLED; @@ -182,13 +170,12 @@ static irqreturn_t uart_clps711x_int_tx(int irq, void *dev_id) return IRQ_HANDLED; } -static unsigned int clps711xuart_tx_empty(struct uart_port *port) +static unsigned int uart_clps711x_tx_empty(struct uart_port *port) { - unsigned int status = clps_readl(SYSFLG(port)); - return status & SYSFLG_UBUSY ? 0 : TIOCSER_TEMT; + return (clps_readl(SYSFLG(port) & SYSFLG_UBUSY)) ? 0 : TIOCSER_TEMT; } -static unsigned int clps711xuart_get_mctrl(struct uart_port *port) +static unsigned int uart_clps711x_get_mctrl(struct uart_port *port) { unsigned int status, result = 0; @@ -206,12 +193,12 @@ static unsigned int clps711xuart_get_mctrl(struct uart_port *port) return result; } -static void -clps711xuart_set_mctrl_null(struct uart_port *port, unsigned int mctrl) +static void uart_clps711x_set_mctrl(struct uart_port *port, unsigned int mctrl) { + /* Do nothing */ } -static void clps711xuart_break_ctl(struct uart_port *port, int break_state) +static void uart_clps711x_break_ctl(struct uart_port *port, int break_state) { unsigned long flags; unsigned int ubrlcr; @@ -228,7 +215,7 @@ static void clps711xuart_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&port->lock, flags); } -static int clps711xuart_startup(struct uart_port *port) +static int uart_clps711x_startup(struct uart_port *port) { struct clps711x_port *s = dev_get_drvdata(port->dev); int ret; @@ -256,7 +243,7 @@ static int clps711xuart_startup(struct uart_port *port) return 0; } -static void clps711xuart_shutdown(struct uart_port *port) +static void uart_clps711x_shutdown(struct uart_port *port) { /* Free the interrupts */ devm_free_irq(port->dev, TX_IRQ(port), port); @@ -266,9 +253,9 @@ static void clps711xuart_shutdown(struct uart_port *port) clps_writel(clps_readl(SYSCON(port)) & ~SYSCON_UARTEN, SYSCON(port)); } -static void -clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) +static void uart_clps711x_set_termios(struct uart_port *port, + struct ktermios *termios, + struct ktermios *old) { unsigned int ubrlcr, baud, quot; unsigned long flags; @@ -292,7 +279,8 @@ clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios, case CS7: ubrlcr = UBRLCR_WRDLEN7; break; - default: // CS8 + case CS8: + default: ubrlcr = UBRLCR_WRDLEN8; break; } @@ -329,45 +317,44 @@ clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios, spin_unlock_irqrestore(&port->lock, flags); } -static const char *clps711xuart_type(struct uart_port *port) +static const char *uart_clps711x_type(struct uart_port *port) { - return port->type == PORT_CLPS711X ? "CLPS711x" : NULL; + return (port->type == PORT_CLPS711X) ? "CLPS711X" : NULL; } -/* - * Configure/autoconfigure the port. - */ -static void clps711xuart_config_port(struct uart_port *port, int flags) +static void uart_clps711x_config_port(struct uart_port *port, int flags) { if (flags & UART_CONFIG_TYPE) port->type = PORT_CLPS711X; } -static void clps711xuart_release_port(struct uart_port *port) +static void uart_clps711x_release_port(struct uart_port *port) { + /* Do nothing */ } -static int clps711xuart_request_port(struct uart_port *port) +static int uart_clps711x_request_port(struct uart_port *port) { + /* Do nothing */ return 0; } -static struct uart_ops uart_clps711x_ops = { - .tx_empty = clps711xuart_tx_empty, - .set_mctrl = clps711xuart_set_mctrl_null, - .get_mctrl = clps711xuart_get_mctrl, - .stop_tx = clps711xuart_stop_tx, - .start_tx = clps711xuart_start_tx, - .stop_rx = clps711xuart_stop_rx, - .enable_ms = clps711xuart_enable_ms, - .break_ctl = clps711xuart_break_ctl, - .startup = clps711xuart_startup, - .shutdown = clps711xuart_shutdown, - .set_termios = clps711xuart_set_termios, - .type = clps711xuart_type, - .config_port = clps711xuart_config_port, - .release_port = clps711xuart_release_port, - .request_port = clps711xuart_request_port, +static const struct uart_ops uart_clps711x_ops = { + .tx_empty = uart_clps711x_tx_empty, + .set_mctrl = uart_clps711x_set_mctrl, + .get_mctrl = uart_clps711x_get_mctrl, + .stop_tx = uart_clps711x_stop_tx, + .start_tx = uart_clps711x_start_tx, + .stop_rx = uart_clps711x_stop_rx, + .enable_ms = uart_clps711x_enable_ms, + .break_ctl = uart_clps711x_break_ctl, + .startup = uart_clps711x_startup, + .shutdown = uart_clps711x_shutdown, + .set_termios = uart_clps711x_set_termios, + .type = uart_clps711x_type, + .config_port = uart_clps711x_config_port, + .release_port = uart_clps711x_release_port, + .request_port = uart_clps711x_request_port, }; #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE -- cgit v1.2.3 From 752fde44fd1c4a411d709c7d4ad0f121f427f234 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 6 Oct 2012 18:43:19 -0300 Subject: perf trace: Support interrupted syscalls Using the same strategies as in the tmp.perf/trace2, i.e. the 'trace' tool implemented by tglx, just updated to the current codebase. Example: [root@sandy linux]# perf trace usleep 1 | tail 2.003: mmap(addr: 0, len: 4096, prot: 3, flags: 34, fd: 4294967295, off: 0 ) = -2128396288 2.017: mmap(addr: 0, len: 4096, prot: 3, flags: 34, fd: 4294967295, off: 0 ) = -2128400384 2.029: arch_prctl(option: 4098, arg2: 140146949441280, arg3: 140146949435392, arg4: 34, arg5: 4294967295) = 0 2.084: mprotect(start: 208741634048, len: 16384, prot: 1 ) = 0 2.098: mprotect(start: 208735956992, len: 4096, prot: 1 ) = 0 2.122: munmap(addr: 140146949447680, len: 91882 ) = 0 2.359: brk(brk: 0 ) = 28987392 2.371: brk(brk: 29122560 ) = 29122560 2.490: nanosleep(rqtp: 140735694241504, rmtp: 0 ) = 0 2.507: exit_group(error_code: 0 [root@sandy linux]# For now the timestamp and duration are always on, will be selectable. Also if multiple threads are being monitored, its tid will appear. The ret output continues to be interpreted a la strace. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ly9ulroru4my5isn0xe9gr0m@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 199 ++++++++++++++++++++++++++++++++++++++++----- tools/perf/util/util.h | 4 + 2 files changed, 181 insertions(+), 22 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 14b32296180..873f50b10cc 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1,5 +1,8 @@ #include "builtin.h" +#include "util/color.h" #include "util/evlist.h" +#include "util/machine.h" +#include "util/thread.h" #include "util/parse-options.h" #include "util/thread_map.h" #include "event-parse.h" @@ -43,6 +46,36 @@ struct syscall { struct syscall_fmt *fmt; }; +struct thread_trace { + u64 entry_time; + u64 exit_time; + bool entry_pending; + char *entry_str; +}; + +static struct thread_trace *thread_trace__new(void) +{ + return zalloc(sizeof(struct thread_trace)); +} + +static struct thread_trace *thread__trace(struct thread *thread) +{ + if (thread == NULL) + goto fail; + + if (thread->priv == NULL) + thread->priv = thread_trace__new(); + + if (thread->priv == NULL) + goto fail; + + return thread->priv; +fail: + color_fprintf(stdout, PERF_COLOR_RED, + "WARNING: not enough memory, dropping samples!\n"); + return NULL; +} + struct trace { int audit_machine; struct { @@ -50,8 +83,18 @@ struct trace { struct syscall *table; } syscalls; struct perf_record_opts opts; + struct machine host; + u64 base_time; + bool multiple_threads; }; +static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp) +{ + double ts = (double)(tstamp - trace->base_time) / NSEC_PER_MSEC; + + return fprintf(fp, "%10.3f: ", ts); +} + static bool done = false; static void sig_handler(int sig __maybe_unused) @@ -59,6 +102,67 @@ static void sig_handler(int sig __maybe_unused) done = true; } +static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thread, + u64 tstamp, FILE *fp) +{ + size_t printed = trace__fprintf_tstamp(trace, tstamp, fp); + + if (trace->multiple_threads) + printed += fprintf(fp, "%d ", thread->pid); + + return printed; +} + +static int trace__process_event(struct machine *machine, union perf_event *event) +{ + int ret = 0; + + switch (event->header.type) { + case PERF_RECORD_LOST: + color_fprintf(stdout, PERF_COLOR_RED, + "LOST %" PRIu64 " events!\n", event->lost.lost); + ret = machine__process_lost_event(machine, event); + default: + ret = machine__process_event(machine, event); + break; + } + + return ret; +} + +static int trace__tool_process(struct perf_tool *tool __maybe_unused, + union perf_event *event, + struct perf_sample *sample __maybe_unused, + struct machine *machine) +{ + return trace__process_event(machine, event); +} + +static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist) +{ + int err = symbol__init(); + + if (err) + return err; + + machine__init(&trace->host, "", HOST_KERNEL_ID); + machine__create_kernel_maps(&trace->host); + + if (perf_target__has_task(&trace->opts.target)) { + err = perf_event__synthesize_thread_map(NULL, evlist->threads, + trace__tool_process, + &trace->host); + } else { + err = perf_event__synthesize_threads(NULL, trace__tool_process, + &trace->host); + } + + if (err) + symbol__exit(); + + return err; +} + static int trace__read_syscall_info(struct trace *trace, int id) { char tp_name[128]; @@ -100,7 +204,8 @@ static int trace__read_syscall_info(struct trace *trace, int id) return sc->tp_format != NULL ? 0 : -1; } -static size_t syscall__fprintf_args(struct syscall *sc, unsigned long *args, FILE *fp) +static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, + unsigned long *args) { int i = 0; size_t printed = 0; @@ -109,12 +214,15 @@ static size_t syscall__fprintf_args(struct syscall *sc, unsigned long *args, FIL struct format_field *field; for (field = sc->tp_format->format.fields->next; field; field = field->next) { - printed += fprintf(fp, "%s%s: %ld", printed ? ", " : "", - field->name, args[i++]); + printed += scnprintf(bf + printed, size - printed, + "%s%s: %ld", printed ? ", " : "", + field->name, args[i++]); } } else { while (i < 6) { - printed += fprintf(fp, "%sarg%d: %ld", printed ? ", " : "", i, args[i]); + printed += scnprintf(bf + printed, size - printed, + "%sarg%d: %ld", + printed ? ", " : "", i, args[i]); ++i; } } @@ -153,10 +261,14 @@ out_cant_read: static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, struct perf_sample *sample) { + char *msg; void *args; + size_t printed = 0; + struct thread *thread = machine__findnew_thread(&trace->host, sample->tid); struct syscall *sc = trace__syscall_info(trace, evsel, sample); + struct thread_trace *ttrace = thread__trace(thread); - if (sc == NULL) + if (ttrace == NULL || sc == NULL) return -1; args = perf_evsel__rawptr(evsel, sample, "args"); @@ -165,8 +277,25 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, return -1; } - printf("%s(", sc->name); - syscall__fprintf_args(sc, args, stdout); + ttrace = thread->priv; + + if (ttrace->entry_str == NULL) { + ttrace->entry_str = malloc(1024); + if (!ttrace->entry_str) + return -1; + } + + ttrace->entry_time = sample->time; + msg = ttrace->entry_str; + printed += scnprintf(msg + printed, 1024 - printed, "%s(", sc->name); + + printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed, args); + + if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) { + trace__fprintf_entry_head(trace, thread, sample->time, stdout); + printf("%-70s\n", ttrace->entry_str); + } else + ttrace->entry_pending = true; return 0; } @@ -175,13 +304,29 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, struct perf_sample *sample) { int ret; + struct thread *thread = machine__findnew_thread(&trace->host, sample->tid); + struct thread_trace *ttrace = thread__trace(thread); struct syscall *sc = trace__syscall_info(trace, evsel, sample); - if (sc == NULL) + if (ttrace == NULL || sc == NULL) return -1; ret = perf_evsel__intval(evsel, sample, "ret"); + ttrace = thread->priv; + + ttrace->exit_time = sample->time; + + trace__fprintf_entry_head(trace, thread, sample->time, stdout); + + if (ttrace->entry_pending) { + printf("%-70s", ttrace->entry_str); + } else { + printf(" ... ["); + color_fprintf(stdout, PERF_COLOR_YELLOW, "continued"); + printf("]: %s()", sc->name); + } + if (ret < 0 && sc->fmt && sc->fmt->errmsg) { char bf[256]; const char *emsg = strerror_r(-ret, bf, sizeof(bf)), @@ -194,6 +339,9 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, printf(") = %d", ret); putchar('\n'); + + ttrace->entry_pending = false; + return 0; } @@ -221,6 +369,12 @@ static int trace__run(struct trace *trace, int argc, const char **argv) goto out_delete_evlist; } + err = trace__symbols_init(trace, evlist); + if (err < 0) { + printf("Problems initializing symbol libraries!\n"); + goto out_delete_evlist; + } + perf_evlist__config_attrs(evlist, &trace->opts); signal(SIGCHLD, sig_handler); @@ -251,6 +405,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (forks) perf_evlist__start_workload(evlist); + trace->multiple_threads = evlist->threads->map[0] == -1 || evlist->threads->nr > 1; again: before = nr_events; @@ -264,32 +419,32 @@ again: ++nr_events; - switch (type) { - case PERF_RECORD_SAMPLE: - break; - case PERF_RECORD_LOST: - printf("LOST %" PRIu64 " events!\n", event->lost.lost); - continue; - default: - printf("Unexpected %s event, skipping...\n", - perf_event__name(type)); - continue; - } - err = perf_evlist__parse_sample(evlist, event, &sample); if (err) { printf("Can't parse sample, err = %d, skipping...\n", err); continue; } + if (trace->base_time == 0) + trace->base_time = sample.time; + + if (type != PERF_RECORD_SAMPLE) { + trace__process_event(&trace->host, event); + continue; + } + evsel = perf_evlist__id2evsel(evlist, sample.id); if (evsel == NULL) { printf("Unknown tp ID %" PRIu64 ", skipping...\n", sample.id); continue; } - if (evlist->threads->map[0] == -1 || evlist->threads->nr > 1) - printf("%d ", sample.tid); + if (sample.raw_data == NULL) { + printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n", + perf_evsel__name(evsel), sample.tid, + sample.cpu, sample.raw_size); + continue; + } if (sample.raw_data == NULL) { printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n", diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index a6b83f8ebef..0d85209db8f 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -198,6 +198,10 @@ static inline int has_extension(const char *filename, const char *ext) #undef tolower #undef toupper +#ifndef NSEC_PER_MSEC +#define NSEC_PER_MSEC 1000000L +#endif + extern unsigned char sane_ctype[256]; #define GIT_SPACE 0x01 #define GIT_DIGIT 0x02 -- cgit v1.2.3 From 60c907abc635622964f7862c8f2977182124f89d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 24 Oct 2012 17:24:47 -0200 Subject: perf trace: Add an event duration column # perf trace usleep 1 | tail -10 0.453 ( 0.002 ms): mmap(addr: 0, len: 4096, prot: 3, flags: 34, fd: 4294967295, off: 0 ) = -763342848 0.456 ( 0.001 ms): mmap(addr: 0, len: 4096, prot: 3, flags: 34, fd: 4294967295, off: 0 ) = -763346944 0.459 ( 0.001 ms): arch_prctl(option: 4098, arg2: 140126839658240, arg3: 140126839652352, arg4: 34, arg5: 4294967295) = 0 0.473 ( 0.003 ms): mprotect(start: 208741634048, len: 16384, prot: 1 ) = 0 0.477 ( 0.003 ms): mprotect(start: 208735956992, len: 4096, prot: 1 ) = 0 0.483 ( 0.004 ms): munmap(addr: 140126839664640, len: 91882 ) = 0 0.540 ( 0.001 ms): brk(brk: 0 ) = 31928320 0.542 ( 0.002 ms): brk(brk: 32063488 ) = 32063488 1.456 ( 0.901 ms): nanosleep(rqtp: 140735472817168, rmtp: 0 ) = 0 1.462 ( 0.000 ms): exit_group(error_code: 0 # This also comes from the tmp.perf/trace2 branch. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Link: http://lkml.kernel.org/n/tip-g9akh5hjw2kvjerpo9xror6f@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 873f50b10cc..ddb6e3721b1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -46,6 +46,20 @@ struct syscall { struct syscall_fmt *fmt; }; +static size_t fprintf_duration(unsigned long t, FILE *fp) +{ + double duration = (double)t / NSEC_PER_MSEC; + size_t printed = fprintf(fp, "("); + + if (duration >= 1.0) + printed += color_fprintf(fp, PERF_COLOR_RED, "%6.3f ms", duration); + else if (duration >= 0.01) + printed += color_fprintf(fp, PERF_COLOR_YELLOW, "%6.3f ms", duration); + else + printed += color_fprintf(fp, PERF_COLOR_NORMAL, "%6.3f ms", duration); + return printed + fprintf(stdout, "): "); +} + struct thread_trace { u64 entry_time; u64 exit_time; @@ -92,7 +106,7 @@ static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp) { double ts = (double)(tstamp - trace->base_time) / NSEC_PER_MSEC; - return fprintf(fp, "%10.3f: ", ts); + return fprintf(fp, "%10.3f ", ts); } static bool done = false; @@ -103,9 +117,10 @@ static void sig_handler(int sig __maybe_unused) } static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thread, - u64 tstamp, FILE *fp) + u64 duration, u64 tstamp, FILE *fp) { size_t printed = trace__fprintf_tstamp(trace, tstamp, fp); + printed += fprintf_duration(duration, fp); if (trace->multiple_threads) printed += fprintf(fp, "%d ", thread->pid); @@ -292,7 +307,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed, args); if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) { - trace__fprintf_entry_head(trace, thread, sample->time, stdout); + trace__fprintf_entry_head(trace, thread, 1, sample->time, stdout); printf("%-70s\n", ttrace->entry_str); } else ttrace->entry_pending = true; @@ -304,6 +319,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, struct perf_sample *sample) { int ret; + u64 duration = 0; struct thread *thread = machine__findnew_thread(&trace->host, sample->tid); struct thread_trace *ttrace = thread__trace(thread); struct syscall *sc = trace__syscall_info(trace, evsel, sample); @@ -317,7 +333,10 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, ttrace->exit_time = sample->time; - trace__fprintf_entry_head(trace, thread, sample->time, stdout); + if (ttrace->entry_time) + duration = sample->time - ttrace->entry_time; + + trace__fprintf_entry_head(trace, thread, duration, sample->time, stdout); if (ttrace->entry_pending) { printf("%-70s", ttrace->entry_str); -- cgit v1.2.3 From ae9ed03579c9745e85a88e80522770df7ae5c9b7 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 8 Oct 2012 09:56:00 -0300 Subject: perf trace: Add duration filter Example: [acme@sandy linux]$ perf trace --duration 0.025 usleep 1 2.221 ( 0.958 ms): 6724 execve(arg0: 140733557168278, arg1: 140733557178768, arg2: 16134304, arg3: 140733557167840, arg4: 7955998171588342573, arg5: 6723) = -2 3.690 ( 1.443 ms): 6724 execve(arg0: 140733557168295, arg1: 140733557178768, arg2: 16134304, arg3: 140733557167840, arg4: 7955998171588342573, arg5: 6723) = 0 3.979 ( 0.048 ms): 6724 open(filename: 208733843841, flags: 0, mode: 1 ) = 3 4.071 ( 0.075 ms): 6724 open(filename: 139744419925673, flags: 0, mode: 0 ) = 3 4.318 ( 0.056 ms): 6724 nanosleep(rqtp: 140734030404608, rmtp: 0 ) = 0 [acme@sandy linux]$ perf trace --duration 0.100 usleep 1 1.143 ( 1.021 ms): 6726 execve(arg0: 140736323962279, arg1: 140736323972752, arg2: 34926752, arg3: 140736323961824, arg4: 7955998171588342573, arg5: 6725) = 0 [acme@sandy linux]$ Cherry picked from tmp.perf/trace2 branch. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Link: http://lkml.kernel.org/n/tip-oslw2j2958we9qf0ctra4whd@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-trace.txt | 3 +++ tools/perf/builtin-trace.c | 32 ++++++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index 3a2ae37310a..38d4b682af0 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -48,6 +48,9 @@ comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0- In per-thread mode with inheritance mode on (default), Events are captured only when the thread executes on the designated CPUs. Default is to monitor all CPUs. +--duration: + Show only events that had a duration greater than N.M ms. + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-script[1] diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index ddb6e3721b1..82ffa6c246d 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -100,8 +100,14 @@ struct trace { struct machine host; u64 base_time; bool multiple_threads; + double duration_filter; }; +static bool trace__filter_duration(struct trace *trace, double t) +{ + return t < (trace->duration_filter * NSEC_PER_MSEC); +} + static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp) { double ts = (double)(tstamp - trace->base_time) / NSEC_PER_MSEC; @@ -307,8 +313,10 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed, args); if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) { - trace__fprintf_entry_head(trace, thread, 1, sample->time, stdout); - printf("%-70s\n", ttrace->entry_str); + if (!trace->duration_filter) { + trace__fprintf_entry_head(trace, thread, 1, sample->time, stdout); + printf("%-70s\n", ttrace->entry_str); + } } else ttrace->entry_pending = true; @@ -333,8 +341,12 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, ttrace->exit_time = sample->time; - if (ttrace->entry_time) + if (ttrace->entry_time) { duration = sample->time - ttrace->entry_time; + if (trace__filter_duration(trace, duration)) + goto out; + } else if (trace->duration_filter) + goto out; trace__fprintf_entry_head(trace, thread, duration, sample->time, stdout); @@ -358,7 +370,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, printf(") = %d", ret); putchar('\n'); - +out: ttrace->entry_pending = false; return 0; @@ -495,6 +507,15 @@ out: return err; } +static int trace__set_duration(const struct option *opt, const char *str, + int unset __maybe_unused) +{ + struct trace *trace = opt->value; + + trace->duration_filter = atof(str); + return 0; +} + int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) { const char * const trace_usage[] = { @@ -533,6 +554,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) "number of mmap data pages"), OPT_STRING(0, "uid", &trace.opts.target.uid_str, "user", "user to profile"), + OPT_CALLBACK(0, "duration", &trace, "float", + "show only events with duration > N.M ms", + trace__set_duration), OPT_END() }; int err; -- cgit v1.2.3 From 8b745263d93470a6ab4528088a26e5cd3dfe7bf6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 18 Oct 2012 19:06:13 -0300 Subject: perf tools: Pretty print errno for some more functions This time: access, open and socket. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-e19dmpz8zxqo2uebxnp7ilkf@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 82ffa6c246d..fb83cfe472e 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -16,15 +16,18 @@ static struct syscall_fmt { bool errmsg; bool timeout; } syscall_fmts[] = { + { .name = "access", .errmsg = true, }, { .name = "arch_prctl", .errmsg = true, .alias = "prctl", }, { .name = "fstat", .errmsg = true, .alias = "newfstat", }, { .name = "fstatat", .errmsg = true, .alias = "newfstatat", }, { .name = "futex", .errmsg = true, }, + { .name = "open", .errmsg = true, }, { .name = "poll", .errmsg = true, .timeout = true, }, { .name = "ppoll", .errmsg = true, .timeout = true, }, { .name = "read", .errmsg = true, }, { .name = "recvfrom", .errmsg = true, }, { .name = "select", .errmsg = true, .timeout = true, }, + { .name = "socket", .errmsg = true, }, { .name = "stat", .errmsg = true, .alias = "newstat", }, }; -- cgit v1.2.3 From 814d7a4d2c33657489f7b45bc0b2dcaa0d88edc0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 24 Oct 2012 18:44:13 -0200 Subject: perf trace: Print the name of a syscall when failing to read its info When failing to read the tracepoint event format, like currently with sys_execve, that is not defined via SYSCALL_DEFINE macros and thus doesn't have an entry in: $ ls -d /sys/kernel/debug/tracing/events/syscalls/sys_enter_*exec* /sys/kernel/debug/tracing/events/syscalls/sys_enter_kexec_load $ Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt Cc: Thomas Gleixner echo Link: http://lkml.kernel.org/n/tip-`ranpwd -l 24`@git.kernel.org Link: http://lkml.kernel.org/n/tip-q3ak0j8b81yxylykq5wp2uwi@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index fb83cfe472e..ba055103b52 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -278,7 +278,10 @@ static struct syscall *trace__syscall_info(struct trace *trace, return &trace->syscalls.table[id]; out_cant_read: - printf("Problems reading syscall %d information\n", id); + printf("Problems reading syscall %d", id); + if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL) + printf("(%s)", trace->syscalls.table[id].name); + puts(" information"); return NULL; } -- cgit v1.2.3 From c30186e51e537d3ae8b1134983c1a5b4db3a8840 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 24 Oct 2012 14:19:16 -0700 Subject: USB: ezusb: unexport some functions that aren't being used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the ezusb code was split out, support was added for the fx2 chip type, but no one is using these functions, so comment it out. If someone needs it, it can be added back in the future. Also properly include into the ezusb.c file, to ensure we catch any function prototype mis-matches Reported-by: Fengguang Wu Cc: René Bürgel Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ezusb.c | 39 ++++++++++++++++++++++----------------- include/linux/usb/ezusb.h | 8 -------- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/drivers/usb/misc/ezusb.c b/drivers/usb/misc/ezusb.c index 4223d761223..0a48de91df3 100644 --- a/drivers/usb/misc/ezusb.c +++ b/drivers/usb/misc/ezusb.c @@ -15,6 +15,7 @@ #include #include #include +#include struct ezusb_fx_type { /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ @@ -22,21 +23,16 @@ struct ezusb_fx_type { unsigned short max_internal_adress; }; -struct ezusb_fx_type ezusb_fx1 = { +static struct ezusb_fx_type ezusb_fx1 = { .cpucs_reg = 0x7F92, .max_internal_adress = 0x1B3F, }; -struct ezusb_fx_type ezusb_fx2 = { - .cpucs_reg = 0xE600, - .max_internal_adress = 0x3FFF, -}; - /* Commands for writing to memory */ #define WRITE_INT_RAM 0xA0 #define WRITE_EXT_RAM 0xA3 -int ezusb_writememory(struct usb_device *dev, int address, +static int ezusb_writememory(struct usb_device *dev, int address, unsigned char *data, int length, __u8 request) { int result; @@ -58,10 +54,9 @@ int ezusb_writememory(struct usb_device *dev, int address, kfree(transfer_buffer); return result; } -EXPORT_SYMBOL_GPL(ezusb_writememory); -int ezusb_set_reset(struct usb_device *dev, unsigned short cpucs_reg, - unsigned char reset_bit) +static int ezusb_set_reset(struct usb_device *dev, unsigned short cpucs_reg, + unsigned char reset_bit) { int response = ezusb_writememory(dev, cpucs_reg, &reset_bit, 1, WRITE_INT_RAM); if (response < 0) @@ -76,12 +71,6 @@ int ezusb_fx1_set_reset(struct usb_device *dev, unsigned char reset_bit) } EXPORT_SYMBOL_GPL(ezusb_fx1_set_reset); -int ezusb_fx2_set_reset(struct usb_device *dev, unsigned char reset_bit) -{ - return ezusb_set_reset(dev, ezusb_fx2.cpucs_reg, reset_bit); -} -EXPORT_SYMBOL_GPL(ezusb_fx2_set_reset); - static int ezusb_ihex_firmware_download(struct usb_device *dev, struct ezusb_fx_type fx, const char *firmware_path) @@ -151,10 +140,26 @@ int ezusb_fx1_ihex_firmware_download(struct usb_device *dev, } EXPORT_SYMBOL_GPL(ezusb_fx1_ihex_firmware_download); +#if 0 +/* + * Once someone one needs these fx2 functions, uncomment them + * and add them to ezusb.h and all should be good. + */ +static struct ezusb_fx_type ezusb_fx2 = { + .cpucs_reg = 0xE600, + .max_internal_adress = 0x3FFF, +}; + +int ezusb_fx2_set_reset(struct usb_device *dev, unsigned char reset_bit) +{ + return ezusb_set_reset(dev, ezusb_fx2.cpucs_reg, reset_bit); +} +EXPORT_SYMBOL_GPL(ezusb_fx2_set_reset); + int ezusb_fx2_ihex_firmware_download(struct usb_device *dev, const char *firmware_path) { return ezusb_ihex_firmware_download(dev, ezusb_fx2, firmware_path); } EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download); - +#endif diff --git a/include/linux/usb/ezusb.h b/include/linux/usb/ezusb.h index fc618d8d1e9..639ee45779f 100644 --- a/include/linux/usb/ezusb.h +++ b/include/linux/usb/ezusb.h @@ -1,16 +1,8 @@ #ifndef __EZUSB_H #define __EZUSB_H - -extern int ezusb_writememory(struct usb_device *dev, int address, - unsigned char *data, int length, __u8 bRequest); - extern int ezusb_fx1_set_reset(struct usb_device *dev, unsigned char reset_bit); -extern int ezusb_fx2_set_reset(struct usb_device *dev, unsigned char reset_bit); - extern int ezusb_fx1_ihex_firmware_download(struct usb_device *dev, const char *firmware_path); -extern int ezusb_fx2_ihex_firmware_download(struct usb_device *dev, - const char *firmware_path); #endif /* __EZUSB_H */ -- cgit v1.2.3 From af3df2cf17f5df079189c3cc88870d28e219496b Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 28 Sep 2012 19:47:07 +0200 Subject: perf tools: Try to build Documentation when installing There's a portion in the "perf list" output refering to the exact specification of raw hardware events. Since this description is in the perf-list manpage, try to build and install the man pages, warning the user when that is not possible due to missing packages (xmlto and asciidoc). Signed-off-by: Borislav Petkov Tested-by: Arnaldo Carvalho de Melo Cc: Namhyung Kim Link: http://lkml.kernel.org/n/tip-ij71ysszkdvz3fy3wr331bke@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/Makefile | 31 +++++++++++++++++++++++++++++-- tools/perf/Makefile | 5 ++++- tools/perf/util/parse-events.c | 2 +- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index 9f2e44f2b17..ef6d22e879e 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -1,3 +1,5 @@ +include ../config/utilities.mak + OUTPUT := ./ ifeq ("$(origin O)", "command line") ifneq ($(O),) @@ -64,6 +66,7 @@ MAKEINFO=makeinfo INSTALL_INFO=install-info DOCBOOK2X_TEXI=docbook2x-texi DBLATEX=dblatex +XMLTO=xmlto ifndef PERL_PATH PERL_PATH = /usr/bin/perl endif @@ -71,6 +74,16 @@ endif -include ../config.mak.autogen -include ../config.mak +_tmp_tool_path := $(call get-executable,$(ASCIIDOC)) +ifeq ($(_tmp_tool_path),) + missing_tools = $(ASCIIDOC) +endif + +_tmp_tool_path := $(call get-executable,$(XMLTO)) +ifeq ($(_tmp_tool_path),) + missing_tools += $(XMLTO) +endif + # # For asciidoc ... # -7.1.2, no extra settings are needed. @@ -170,7 +183,12 @@ pdf: $(OUTPUT)user-manual.pdf install: install-man -install-man: man +check-man-tools: +ifdef missing_tools + $(error "You need to install $(missing_tools) for man pages") +endif + +do-install-man: man $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir) # $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir) # $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir) @@ -178,6 +196,15 @@ install-man: man # $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir) # $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir) +install-man: check-man-tools man + +try-install-man: +ifdef missing_tools + $(warning Please install $(missing_tools) to have the man pages installed) +else + $(MAKE) do-install-man +endif + install-info: info $(INSTALL) -d -m 755 $(DESTDIR)$(infodir) $(INSTALL) -m 644 $(OUTPUT)perf.info $(OUTPUT)perfman.info $(DESTDIR)$(infodir) @@ -246,7 +273,7 @@ $(MAN_HTML): $(OUTPUT)%.html : %.txt $(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml $(QUIET_XMLTO)$(RM) $@ && \ - xmlto -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< + $(XMLTO) -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< $(OUTPUT)%.xml : %.txt $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 78a81eda127..b14eeb86d8d 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -1041,7 +1041,7 @@ perfexec_instdir = $(prefix)/$(perfexecdir) endif perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir)) -install: all +install: all try-install-man $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' @@ -1067,6 +1067,9 @@ install-doc: install-man: $(MAKE) -C Documentation install-man +try-install-man: + $(MAKE) -C Documentation try-install-man + install-html: $(MAKE) -C Documentation install-html diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 2fe15874e46..3a3efcf3e4e 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1081,7 +1081,7 @@ void print_events(const char *event_glob, bool name_only) printf(" %-50s [%s]\n", "cpu/t1=v1[,t2=v2,t3 ...]/modifier", event_type_descriptors[PERF_TYPE_RAW]); - printf(" (see 'perf list --help' on how to encode it)\n"); + printf(" (see 'man perf-list' on how to encode it)\n"); printf("\n"); printf(" %-50s [%s]\n", -- cgit v1.2.3 From 54388b281c877b2797bb0fc97c099fb7ffd5336a Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 2 Oct 2012 16:49:25 -0600 Subject: usb: host: tegra remove include of Almost nothing from this file is used, and the file will hopefully be deleted soon. Copy the tiny portions that are used directly into ehci-tegra.c. I believe that Venu Byravarasu is working on cleaning up our USB driver, and those cleanups will remove the need for these constants. Signed-off-by: Stephen Warren Acked-by: Venu Byravarasu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-tegra.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 6223d175784..2de089001ae 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -28,7 +28,10 @@ #include #include -#include + +#define TEGRA_USB_BASE 0xC5000000 +#define TEGRA_USB2_BASE 0xC5004000 +#define TEGRA_USB3_BASE 0xC5008000 #define TEGRA_USB_DMA_ALIGN 32 -- cgit v1.2.3 From ffc7493df73cf0e3d2c6719f3794696dbc3929a9 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 2 Oct 2012 16:50:02 -0600 Subject: usb: phy: tegra remove include of Almost nothing from this file is used, and the file will hopefully be deleted soon. Copy the tiny portions that are used directly into tegra_usb_phy.c. I believe that Venu Byravarasu is working on cleaning up our USB driver, and those cleanups will remove the need for these constants. Signed-off-by: Stephen Warren Acked-by: Venu Byravarasu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/phy/tegra_usb_phy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/phy/tegra_usb_phy.c b/drivers/usb/phy/tegra_usb_phy.c index 987116f9efc..9d13c81754e 100644 --- a/drivers/usb/phy/tegra_usb_phy.c +++ b/drivers/usb/phy/tegra_usb_phy.c @@ -29,7 +29,9 @@ #include #include #include -#include + +#define TEGRA_USB_BASE 0xC5000000 +#define TEGRA_USB_SIZE SZ_16K #define ULPI_VIEWPORT 0x170 -- cgit v1.2.3 From e1deb56cb775ab953bc5245feaf1f43269409139 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Wed, 3 Oct 2012 08:40:42 +0900 Subject: usb: ehci-s5p: use clk_prepare_enable and clk_disable_unprepare Convert clk_enable/clk_disable to clk_prepare_enable/clk_disable_unprepare calls as required by common clock framework. Signed-off-by: Thomas Abraham Acked-by: Jingoo Han Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-s5p.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index 85b74be202e..abc178d21fe 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c @@ -136,7 +136,7 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev) goto fail_clk; } - err = clk_enable(s5p_ehci->clk); + err = clk_prepare_enable(s5p_ehci->clk); if (err) goto fail_clk; @@ -183,7 +183,7 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev) return 0; fail_io: - clk_disable(s5p_ehci->clk); + clk_disable_unprepare(s5p_ehci->clk); fail_clk: usb_put_hcd(hcd); return err; @@ -200,7 +200,7 @@ static int __devexit s5p_ehci_remove(struct platform_device *pdev) if (pdata && pdata->phy_exit) pdata->phy_exit(pdev, S5P_USB_PHY_HOST); - clk_disable(s5p_ehci->clk); + clk_disable_unprepare(s5p_ehci->clk); usb_put_hcd(hcd); @@ -231,7 +231,7 @@ static int s5p_ehci_suspend(struct device *dev) if (pdata && pdata->phy_exit) pdata->phy_exit(pdev, S5P_USB_PHY_HOST); - clk_disable(s5p_ehci->clk); + clk_disable_unprepare(s5p_ehci->clk); return rc; } @@ -243,7 +243,7 @@ static int s5p_ehci_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; - clk_enable(s5p_ehci->clk); + clk_prepare_enable(s5p_ehci->clk); if (pdata && pdata->phy_init) pdata->phy_init(pdev, S5P_USB_PHY_HOST); -- cgit v1.2.3 From c05c946c68e381074dde259d8ce243da1b1aae02 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Wed, 3 Oct 2012 08:41:37 +0900 Subject: usb: ohci-exynos: use clk_prepare_enable and clk_disable_unprepare Convert clk_enable/clk_disable to clk_prepare_enable/clk_disable_unprepare calls as required by common clock framework. Signed-off-by: Thomas Abraham Acked-by: Jingoo Han Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-exynos.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index 929a49437e2..9e3d2da7537 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -123,7 +123,7 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev) goto fail_clk; } - err = clk_enable(exynos_ohci->clk); + err = clk_prepare_enable(exynos_ohci->clk); if (err) goto fail_clken; @@ -167,7 +167,7 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev) return 0; fail_io: - clk_disable(exynos_ohci->clk); + clk_disable_unprepare(exynos_ohci->clk); fail_clken: clk_put(exynos_ohci->clk); fail_clk: @@ -186,7 +186,7 @@ static int __devexit exynos_ohci_remove(struct platform_device *pdev) if (pdata && pdata->phy_exit) pdata->phy_exit(pdev, S5P_USB_PHY_HOST); - clk_disable(exynos_ohci->clk); + clk_disable_unprepare(exynos_ohci->clk); clk_put(exynos_ohci->clk); usb_put_hcd(hcd); @@ -232,7 +232,7 @@ static int exynos_ohci_suspend(struct device *dev) if (pdata && pdata->phy_exit) pdata->phy_exit(pdev, S5P_USB_PHY_HOST); - clk_disable(exynos_ohci->clk); + clk_disable_unprepare(exynos_ohci->clk); fail: spin_unlock_irqrestore(&ohci->lock, flags); @@ -247,7 +247,7 @@ static int exynos_ohci_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; - clk_enable(exynos_ohci->clk); + clk_prepare_enable(exynos_ohci->clk); if (pdata && pdata->phy_init) pdata->phy_init(pdev, S5P_USB_PHY_HOST); -- cgit v1.2.3 From 60d80adbac9b7492439b1d0665353bc2117b4d78 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 4 Oct 2012 16:11:50 +0900 Subject: USB: ohci-exynos: use devm_clk_get() The devm_ functions allocate memory that is released when a driver detaches. This patch uses devm_clk_get() for these functions. Signed-off-by: Jingoo Han Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-exynos.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index 9e3d2da7537..2f303295b42 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -115,7 +115,7 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev) } exynos_ohci->hcd = hcd; - exynos_ohci->clk = clk_get(&pdev->dev, "usbhost"); + exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost"); if (IS_ERR(exynos_ohci->clk)) { dev_err(&pdev->dev, "Failed to get usbhost clock\n"); @@ -125,7 +125,7 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev) err = clk_prepare_enable(exynos_ohci->clk); if (err) - goto fail_clken; + goto fail_clk; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { @@ -168,8 +168,6 @@ static int __devinit exynos_ohci_probe(struct platform_device *pdev) fail_io: clk_disable_unprepare(exynos_ohci->clk); -fail_clken: - clk_put(exynos_ohci->clk); fail_clk: usb_put_hcd(hcd); return err; @@ -187,7 +185,6 @@ static int __devexit exynos_ohci_remove(struct platform_device *pdev) pdata->phy_exit(pdev, S5P_USB_PHY_HOST); clk_disable_unprepare(exynos_ohci->clk); - clk_put(exynos_ohci->clk); usb_put_hcd(hcd); -- cgit v1.2.3 From 30b1e495b81321f572020a2f5266ece3ed1a6ecd Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Sat, 6 Oct 2012 15:23:17 +0800 Subject: USB: use bus_to_hdc instead of container_of We defined bus_to_hdc for that, use it. Signed-off-by: Yuanhan Liu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index cd8fb44a3e1..7d3de09a82e 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -370,14 +370,14 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) { struct usb_device *dev; - struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self); + struct usb_hcd *usb_hcd = bus_to_hcd(bus); unsigned root_hub = 0; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; - if (!usb_get_hcd(bus_to_hcd(bus))) { + if (!usb_get_hcd(usb_hcd)) { kfree(dev); return NULL; } -- cgit v1.2.3 From 801f00633568ed6d5eebef5ef10d8b5661379f2c Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 8 Oct 2012 11:28:25 +0900 Subject: USB: ohci-s3c2410: use devm_ functions The devm_ functions allocate memory that is released when a driver detaches. This makes the code smaller and a bit simpler. Signed-off-by: Jingoo Han Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-s3c2410.c | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 281d5c658e3..e84190f25c6 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -323,8 +323,6 @@ usb_hcd_s3c2410_remove(struct usb_hcd *hcd, struct platform_device *dev) { usb_remove_hcd(hcd); s3c2410_stop_hc(dev); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); } @@ -353,35 +351,29 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver, hcd->rsrc_start = dev->resource[0].start; hcd->rsrc_len = resource_size(&dev->resource[0]); - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - dev_err(&dev->dev, "request_mem_region failed\n"); - retval = -EBUSY; + hcd->regs = devm_request_and_ioremap(&dev->dev, &dev->resource[0]); + if (!hcd->regs) { + dev_err(&dev->dev, "devm_request_and_ioremap failed\n"); + retval = -ENOMEM; goto err_put; } - clk = clk_get(&dev->dev, "usb-host"); + clk = devm_clk_get(&dev->dev, "usb-host"); if (IS_ERR(clk)) { dev_err(&dev->dev, "cannot get usb-host clock\n"); retval = PTR_ERR(clk); - goto err_mem; + goto err_put; } - usb_clk = clk_get(&dev->dev, "usb-bus-host"); + usb_clk = devm_clk_get(&dev->dev, "usb-bus-host"); if (IS_ERR(usb_clk)) { dev_err(&dev->dev, "cannot get usb-bus-host clock\n"); retval = PTR_ERR(usb_clk); - goto err_clk; + goto err_put; } s3c2410_start_hc(dev, hcd); - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - if (!hcd->regs) { - dev_err(&dev->dev, "ioremap failed\n"); - retval = -ENOMEM; - goto err_ioremap; - } - ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, dev->resource[1].start, 0); @@ -392,14 +384,6 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver, err_ioremap: s3c2410_stop_hc(dev); - iounmap(hcd->regs); - clk_put(usb_clk); - - err_clk: - clk_put(clk); - - err_mem: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err_put: usb_put_hcd(hcd); -- cgit v1.2.3 From e8cebb9cde3716800219ea8473306d431e83154b Mon Sep 17 00:00:00 2001 From: Constantine Shulyupin Date: Wed, 10 Oct 2012 16:14:00 +0200 Subject: USB: usb-skeleton.c: fix compilation error and restored kref_put on fail in skel_open Fixing compilaton error. Incrementing usage counter only on successful execution of skel_open. Removing redundant locking Some last changes in function skel_open and finally commit 52a7499 Revert "USB: usb-skeleton.c: fix open/disconnect race" introduced a bug in function skel_open, which this patch fixes. Changes since v2: - refactoring - Removing redundant mutex synchronization. Changes since v1: - Fixed accordingly feedback of Oliver Neukum oneukum@suse.de: also need to drop the lock. Signed-off-by: Constantine Shulyupin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usb-skeleton.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 0616f235bd6..ce310170829 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -105,20 +105,15 @@ static int skel_open(struct inode *inode, struct file *file) goto exit; } - /* increment our usage count for the device */ - kref_get(&dev->kref); - - /* lock the device to allow correctly handling errors - * in resumption */ - mutex_lock(&dev->io_mutex); - retval = usb_autopm_get_interface(interface); if (retval) - goto out_err; + goto exit; + + /* increment our usage count for the device */ + kref_get(&dev->kref); /* save our object in the file's private structure */ file->private_data = dev; - mutex_unlock(&dev->io_mutex); exit: return retval; -- cgit v1.2.3 From 6273f1810f95f4deeb2f0d6810f301726ad32308 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 18 Oct 2012 12:24:43 +0800 Subject: USB: EHCI: add condition for delay during the resume Without this condition, all controllers will do this delay, and increase the resume time. Only enabled and unsuspended port needs this delay, but Some buggy hardware(like Synopsys usb controller) will clear suspend bit once they receive/send resume signal, so it takes resume bit as consideration. Tested it at Freescale i.mx6q Sabrelite board. Signed-off-by: Peter Chen Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hub.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 914ce9370e7..a7ec827ca2c 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -384,11 +384,24 @@ static int ehci_bus_resume (struct usb_hcd *hcd) ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci->rh_state = EHCI_RH_RUNNING; - /* Some controller/firmware combinations need a delay during which - * they set up the port statuses. See Bugzilla #8190. */ - spin_unlock_irq(&ehci->lock); - msleep(8); - spin_lock_irq(&ehci->lock); + /* + * According to Bugzilla #8190, the port status for some controllers + * will be wrong without a delay. At their wrong status, the port + * is enabled, but not suspended neither resumed. + */ + i = HCS_N_PORTS(ehci->hcs_params); + while (i--) { + temp = ehci_readl(ehci, &ehci->regs->port_status[i]); + if ((temp & PORT_PE) && + !(temp & (PORT_SUSPEND | PORT_RESUME))) { + ehci_dbg(ehci, "Port status(0x%x) is wrong\n", temp); + spin_unlock_irq(&ehci->lock); + msleep(8); + spin_lock_irq(&ehci->lock); + break; + } + } + if (ehci->shutdown) goto shutdown; -- cgit v1.2.3 From d6064aca824b81fbb788fd230c88976d84b651b1 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 10 Oct 2012 15:07:30 -0400 Subject: USB: EHCI: move logging macros to ehci.h In preparation for splitting the ehci-hcd driver into a core library and separate platform-specific driver modules, this patch (as1616) moves the console logging macros from ehci-dbg.c to ehci.h, where they will be available to the platform drivers. Signed-off-by: Alan Stern Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-dbg.c | 15 --------------- drivers/usb/host/ehci.h | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 1599806e3d4..dfd3bf3aa4d 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -18,21 +18,6 @@ /* this file is part of ehci-hcd.c */ -#define ehci_dbg(ehci, fmt, args...) \ - dev_dbg (ehci_to_hcd(ehci)->self.controller , fmt , ## args ) -#define ehci_err(ehci, fmt, args...) \ - dev_err (ehci_to_hcd(ehci)->self.controller , fmt , ## args ) -#define ehci_info(ehci, fmt, args...) \ - dev_info (ehci_to_hcd(ehci)->self.controller , fmt , ## args ) -#define ehci_warn(ehci, fmt, args...) \ - dev_warn (ehci_to_hcd(ehci)->self.controller , fmt , ## args ) - -#ifdef VERBOSE_DEBUG -# define ehci_vdbg ehci_dbg -#else - static inline void ehci_vdbg(struct ehci_hcd *ehci, ...) {} -#endif - #ifdef DEBUG /* check the values in the HCSPARAMS register diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 4ddf7c51616..9b8cbb4b3e2 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -761,6 +761,21 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) /*-------------------------------------------------------------------------*/ +#define ehci_dbg(ehci, fmt, args...) \ + dev_dbg(ehci_to_hcd(ehci)->self.controller , fmt , ## args) +#define ehci_err(ehci, fmt, args...) \ + dev_err(ehci_to_hcd(ehci)->self.controller , fmt , ## args) +#define ehci_info(ehci, fmt, args...) \ + dev_info(ehci_to_hcd(ehci)->self.controller , fmt , ## args) +#define ehci_warn(ehci, fmt, args...) \ + dev_warn(ehci_to_hcd(ehci)->self.controller , fmt , ## args) + +#ifdef VERBOSE_DEBUG +# define ehci_vdbg ehci_dbg +#else + static inline void ehci_vdbg(struct ehci_hcd *ehci, ...) {} +#endif + #ifdef CONFIG_PCI /* For working around the MosChip frame-index-register bug */ -- cgit v1.2.3 From acc08503406f97ce6582c92fd8c8139f1e871a96 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 10 Oct 2012 15:07:39 -0400 Subject: USB: EHCI: make ehci_read_frame_index platform independent In preparation for splitting the ehci-hcd driver into a core library and separate platform-specific driver modules, this patch (as1617) changes the way ehci_read_frame_index() is handled. Since the same core library will have to work with both PCI and non-PCI platforms, the quirk handler routine will be compiled unconditionally. The decision about whether to call it or simply to read the frame index register is made at run time, based on whether the frame_index_bug quirk flag is set. Signed-off-by: Alan Stern Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 27 ++++++++++++++++++++++++++- drivers/usb/host/ehci-sched.c | 23 ----------------------- drivers/usb/host/ehci.h | 16 ---------------- 3 files changed, 26 insertions(+), 40 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 28fb5ddaf78..9c2afb516fe 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -118,9 +118,34 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us"); /*-------------------------------------------------------------------------*/ #include "ehci.h" -#include "ehci-dbg.c" #include "pci-quirks.h" +/* + * The MosChip MCS9990 controller updates its microframe counter + * a little before the frame counter, and occasionally we will read + * the invalid intermediate value. Avoid problems by checking the + * microframe number (the low-order 3 bits); if they are 0 then + * re-read the register to get the correct value. + */ +static unsigned ehci_moschip_read_frame_index(struct ehci_hcd *ehci) +{ + unsigned uf; + + uf = ehci_readl(ehci, &ehci->regs->frame_index); + if (unlikely((uf & 7) == 0)) + uf = ehci_readl(ehci, &ehci->regs->frame_index); + return uf; +} + +static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci) +{ + if (ehci->frame_index_bug) + return ehci_moschip_read_frame_index(ehci); + return ehci_readl(ehci, &ehci->regs->frame_index); +} + +#include "ehci-dbg.c" + /*-------------------------------------------------------------------------*/ /* diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index b538a4d62d5..2e14714b359 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -36,29 +36,6 @@ static int ehci_get_frame (struct usb_hcd *hcd); -#ifdef CONFIG_PCI - -static unsigned ehci_read_frame_index(struct ehci_hcd *ehci) -{ - unsigned uf; - - /* - * The MosChip MCS9990 controller updates its microframe counter - * a little before the frame counter, and occasionally we will read - * the invalid intermediate value. Avoid problems by checking the - * microframe number (the low-order 3 bits); if they are 0 then - * re-read the register to get the correct value. - */ - uf = ehci_readl(ehci, &ehci->regs->frame_index); - if (unlikely(ehci->frame_index_bug && ((uf & 7) == 0))) - uf = ehci_readl(ehci, &ehci->regs->frame_index); - return uf; -} - -#endif - -/*-------------------------------------------------------------------------*/ - /* * periodic_next_shadow - return "next" pointer on shadow list * @periodic: host pointer to qh/itd/sitd diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 9b8cbb4b3e2..ec948c3b1ce 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -776,22 +776,6 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) static inline void ehci_vdbg(struct ehci_hcd *ehci, ...) {} #endif -#ifdef CONFIG_PCI - -/* For working around the MosChip frame-index-register bug */ -static unsigned ehci_read_frame_index(struct ehci_hcd *ehci); - -#else - -static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci) -{ - return ehci_readl(ehci, &ehci->regs->frame_index); -} - -#endif - -/*-------------------------------------------------------------------------*/ - #ifndef DEBUG #define STUB_DEBUG_FILES #endif /* DEBUG */ -- cgit v1.2.3 From d39dbc8918be0e6bb850592e334203c9114c0e77 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 10 Oct 2012 15:07:46 -0400 Subject: USB: EHCI: move ehci_update_device() to ehci-lpm.c In preparation for splitting the ehci-hcd driver into a core library and separate platform-specific driver modules, this patch (as1618) moves ehci_update_device() from a couple of platform-specific source files into ehci-lpm.c. This is where it should have been all along, since all it does is call a couple of other functions that are already in ehci-lpm.c. Signed-off-by: Alan Stern Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-lpm.c | 23 ++++++++++++++++++++--- drivers/usb/host/ehci-pci.c | 16 ---------------- drivers/usb/host/ehci-vt8500.c | 16 ---------------- 3 files changed, 20 insertions(+), 35 deletions(-) diff --git a/drivers/usb/host/ehci-lpm.c b/drivers/usb/host/ehci-lpm.c index 2111627a19d..6b092c1dff6 100644 --- a/drivers/usb/host/ehci-lpm.c +++ b/drivers/usb/host/ehci-lpm.c @@ -17,8 +17,8 @@ */ /* this file is part of ehci-hcd.c */ -static int __maybe_unused ehci_lpm_set_da(struct ehci_hcd *ehci, - int dev_addr, int port_num) + +static int ehci_lpm_set_da(struct ehci_hcd *ehci, int dev_addr, int port_num) { u32 __iomem portsc; @@ -38,7 +38,7 @@ static int __maybe_unused ehci_lpm_set_da(struct ehci_hcd *ehci, * this function is used to check if the device support LPM * if yes, mark the PORTSC register with PORT_LPM bit */ -static int __maybe_unused ehci_lpm_check(struct ehci_hcd *ehci, int port) +static int ehci_lpm_check(struct ehci_hcd *ehci, int port) { u32 __iomem *portsc ; u32 val32; @@ -82,3 +82,20 @@ static int __maybe_unused ehci_lpm_check(struct ehci_hcd *ehci, int port) return retval; } + +static int __maybe_unused ehci_update_device(struct usb_hcd *hcd, + struct usb_device *udev) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int rc = 0; + + if (!udev->parent) /* udev is root hub itself, impossible */ + rc = -1; + /* we only support lpm device connected to root hub yet */ + if (ehci->has_lpm && !udev->parent->parent) { + rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum); + if (!rc) + rc = ehci_lpm_check(ehci, udev->portnum); + } + return rc; +} diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index d1407f8d42b..7880ba621f8 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -379,22 +379,6 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) } #endif -static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int rc = 0; - - if (!udev->parent) /* udev is root hub itself, impossible */ - rc = -1; - /* we only support lpm device connected to root hub yet */ - if (ehci->has_lpm && !udev->parent->parent) { - rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum); - if (!rc) - rc = ehci_lpm_check(ehci, udev->portnum); - } - return rc; -} - static const struct hc_driver ehci_pci_hc_driver = { .description = hcd_name, .product_desc = "EHCI Host Controller", diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c index d3c9a3e397b..c6fe0bb619c 100644 --- a/drivers/usb/host/ehci-vt8500.c +++ b/drivers/usb/host/ehci-vt8500.c @@ -19,22 +19,6 @@ #include #include -static int ehci_update_device(struct usb_hcd *hcd, struct usb_device *udev) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int rc = 0; - - if (!udev->parent) /* udev is root hub itself, impossible */ - rc = -1; - /* we only support lpm device connected to root hub yet */ - if (ehci->has_lpm && !udev->parent->parent) { - rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum); - if (!rc) - rc = ehci_lpm_check(ehci, udev->portnum); - } - return rc; -} - static const struct hc_driver vt8500_ehci_hc_driver = { .description = hcd_name, .product_desc = "VT8500 EHCI", -- cgit v1.2.3 From 969ddcfc95c9a1849114fb72466d2fdea70f1d48 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 19 Oct 2012 11:03:02 -0400 Subject: USB: hub_for_each_child should skip unconnected ports This patch (as1619) improves the interface to the "hub_for_each_child" macro. The name clearly suggests that the macro iterates over child devices; it does not suggest that the loop will also iterate over unnconnected ports. The patch changes the macro so that it will skip over unconnected ports and iterate only the actual child devices. The two existing call sites are updated to avoid testing for a NULL child pointer, which is now unnecessary. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devices.c | 18 ++++++++---------- drivers/usb/host/r8a66597-hcd.c | 6 ++---- include/linux/usb.h | 5 +++-- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index f460de31ace..cbacea933b1 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -591,16 +591,14 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, /* Now look at all of this device's children. */ usb_hub_for_each_child(usbdev, chix, childdev) { - if (childdev) { - usb_lock_device(childdev); - ret = usb_device_dump(buffer, nbytes, skip_bytes, - file_offset, childdev, bus, - level + 1, chix - 1, ++cnt); - usb_unlock_device(childdev); - if (ret == -EFAULT) - return total_written; - total_written += ret; - } + usb_lock_device(childdev); + ret = usb_device_dump(buffer, nbytes, skip_bytes, + file_offset, childdev, bus, + level + 1, chix - 1, ++cnt); + usb_unlock_device(childdev); + if (ret == -EFAULT) + return total_written; + total_written += ret; } return total_written; } diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index fcc09e5ec0a..b3eea0ba97a 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2036,10 +2036,8 @@ static void collect_usb_address_map(struct usb_device *udev, unsigned long *map) udev->parent->descriptor.bDeviceClass == USB_CLASS_HUB) map[udev->devnum/32] |= (1 << (udev->devnum % 32)); - usb_hub_for_each_child(udev, chix, childdev) { - if (childdev) - collect_usb_address_map(childdev, map); - } + usb_hub_for_each_child(udev, chix, childdev) + collect_usb_address_map(childdev, map); } /* this function must be called with interrupt disabled */ diff --git a/include/linux/usb.h b/include/linux/usb.h index f92cdf0c145..5df7c87b277 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -588,8 +588,9 @@ extern struct usb_device *usb_hub_find_child(struct usb_device *hdev, */ #define usb_hub_for_each_child(hdev, port1, child) \ for (port1 = 1, child = usb_hub_find_child(hdev, port1); \ - port1 <= hdev->maxchild; \ - child = usb_hub_find_child(hdev, ++port1)) + port1 <= hdev->maxchild; \ + child = usb_hub_find_child(hdev, ++port1)) \ + if (!child) continue; else /* USB device locking */ #define usb_lock_device(udev) device_lock(&(udev)->dev) -- cgit v1.2.3 From bfd1e910139be73fb0783a0b3171fc79e6afa031 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 19 Oct 2012 11:03:39 -0400 Subject: USB: speed up usb_bus_resume() This patch (as1620) speeds up USB root-hub resumes in the common case where every enabled port has its suspend feature set (which currently will be true for every runtime resume of the root hub). If all the enabled ports are suspended then resuming the root hub won't resume any of the downstream devices. In this case there's no need for a Resume Recovery delay, because that delay is meant to give devices a chance to get ready for active use. To keep track of the port suspend features, the patch adds a "port_is_suspended" flag to struct usb_device. This has to be tracked separately from the device's state; it's entirely possible for a USB-2 device to be suspended while the suspend feature on its parent port is clear. The reason is that devices will go into suspend whenever their parent hub does. Signed-off-by: Alan Stern Reviewed-by: Peter Chen Tested-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 19 +++++++++++++++++-- drivers/usb/core/hub.c | 2 ++ include/linux/usb.h | 2 ++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 1e741bca026..eaa14514e17 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2039,8 +2039,9 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) status = hcd->driver->bus_resume(hcd); clear_bit(HCD_FLAG_WAKEUP_PENDING, &hcd->flags); if (status == 0) { - /* TRSMRCY = 10 msec */ - msleep(10); + struct usb_device *udev; + int port1; + spin_lock_irq(&hcd_root_hub_lock); if (!HCD_DEAD(hcd)) { usb_set_device_state(rhdev, rhdev->actconfig @@ -2050,6 +2051,20 @@ int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg) hcd->state = HC_STATE_RUNNING; } spin_unlock_irq(&hcd_root_hub_lock); + + /* + * Check whether any of the enabled ports on the root hub are + * unsuspended. If they are then a TRSMRCY delay is needed + * (this is what the USB-2 spec calls a "global resume"). + * Otherwise we can skip the delay. + */ + usb_hub_for_each_child(rhdev, port1, udev) { + if (udev->state != USB_STATE_NOTATTACHED && + !udev->port_is_suspended) { + usleep_range(10000, 11000); /* TRSMRCY */ + break; + } + } } else { hcd->state = old_state; dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 64854d76f52..e729e94cb75 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2876,6 +2876,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) (PMSG_IS_AUTO(msg) ? "auto-" : ""), udev->do_remote_wakeup); usb_set_device_state(udev, USB_STATE_SUSPENDED); + udev->port_is_suspended = 1; msleep(10); } usb_mark_last_busy(hub->hdev); @@ -3040,6 +3041,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) SuspendCleared: if (status == 0) { + udev->port_is_suspended = 0; if (hub_is_superspeed(hub->hdev)) { if (portchange & USB_PORT_STAT_C_LINK_STATE) clear_port_feature(hub->hdev, port1, diff --git a/include/linux/usb.h b/include/linux/usb.h index 5df7c87b277..f51f9981de1 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -482,6 +482,7 @@ struct usb3_lpm_parameters { * @connect_time: time device was first connected * @do_remote_wakeup: remote wakeup should be enabled * @reset_resume: needs reset instead of resume + * @port_is_suspended: the upstream port is suspended (L2 or U3) * @wusb_dev: if this is a Wireless USB device, link to the WUSB * specific data for the device. * @slot_id: Slot ID assigned by xHCI @@ -560,6 +561,7 @@ struct usb_device { unsigned do_remote_wakeup:1; unsigned reset_resume:1; + unsigned port_is_suspended:1; #endif struct wusb_dev *wusb_dev; int slot_id; -- cgit v1.2.3 From bd066eef1aea5dd1f8e98934c4c6d21c5e0439c8 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Tue, 23 Oct 2012 07:45:01 -0700 Subject: usb: "ehci-w90x900" Fix a typo and add some whitespace. Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-w90x900.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index ec598082c14..fdd7c4873cf 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -13,7 +13,7 @@ #include -/*ebable phy0 and phy1 for w90p910*/ +/* enable phy0 and phy1 for w90p910 */ #define ENPHY (0x01<<8) #define PHY0_CTR (0xA4) #define PHY1_CTR (0xA8) -- cgit v1.2.3 From 7194d0e107fa70ca46b2a03b27b8b7ad2266d8bf Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 24 Oct 2012 14:21:51 +0900 Subject: staging/comedi: Use dev_ printks in drivers/vmk80xx.c fixed below checkpatch warning. - Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/vmk80xx.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index df277aa591b..366490776c5 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -1371,12 +1371,11 @@ static int vmk80xx_usb_probe(struct usb_interface *intf, if (dev->board.model == VMK8061_MODEL) { vmk80xx_read_eeprom(dev, IC3_VERSION); - printk(KERN_INFO "comedi#: vmk80xx: %s\n", dev->fw.ic3_vers); + dev_info(&intf->dev, "%s\n", dev->fw.ic3_vers); if (vmk80xx_check_data_link(dev)) { vmk80xx_read_eeprom(dev, IC6_VERSION); - printk(KERN_INFO "comedi#: vmk80xx: %s\n", - dev->fw.ic6_vers); + dev_info(&intf->dev, "%s\n", dev->fw.ic6_vers); } else { dbgcm("comedi#: vmk80xx: no conn. to CPU\n"); } @@ -1387,8 +1386,8 @@ static int vmk80xx_usb_probe(struct usb_interface *intf, dev->probed = 1; - printk(KERN_INFO "comedi#: vmk80xx: board #%d [%s] now attached\n", - dev->count, dev->board.name); + dev_info(&intf->dev, "board #%d [%s] now attached\n", + dev->count, dev->board.name); mutex_unlock(&glb_mutex); @@ -1422,8 +1421,8 @@ static void vmk80xx_usb_disconnect(struct usb_interface *intf) kfree(dev->usb_rx_buf); kfree(dev->usb_tx_buf); - printk(KERN_INFO "comedi#: vmk80xx: board #%d [%s] now detached\n", - dev->count, dev->board.name); + dev_info(&intf->dev, "board #%d [%s] now detached\n", + dev->count, dev->board.name); up(&dev->limit_sem); mutex_unlock(&glb_mutex); -- cgit v1.2.3 From 0a00ab999eb8cd0766277bac8f8209bda9bbbb87 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 24 Oct 2012 15:14:46 +0900 Subject: staging/comedi: Use pr_ or dev_ printks in drivers/usbduxfast.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... and added pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 152 +++++++++++++--------------- 1 file changed, 71 insertions(+), 81 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 1154a7e2895..060d853dc65 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -37,6 +37,8 @@ * udev coldplug problem */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -216,8 +218,9 @@ static int send_dux_commands(struct usbduxfastsub_s *udfs, int cmd_type) usb_sndbulkpipe(udfs->usbdev, CHANNELLISTEP), udfs->dux_commands, SIZEOFDUXBUFFER, &nsent, 10000); if (tmp < 0) - printk(KERN_ERR "comedi%d: could not transmit dux_commands to" - "the usb-device, err=%d\n", udfs->comedidev->minor, tmp); + dev_err(&udfs->interface->dev, + "could not transmit dux_commands to the usb-device, err=%d\n", + tmp); return tmp; } @@ -252,7 +255,7 @@ static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs, int do_unlink) int ret = 0; if (!udfs) { - printk(KERN_ERR "comedi?: usbduxfast_ai_stop: udfs=NULL!\n"); + pr_err("%s: udfs=NULL!\n", __func__); return -EFAULT; } #ifdef CONFIG_COMEDI_DEBUG @@ -284,7 +287,7 @@ static int usbduxfast_ai_cancel(struct comedi_device *dev, #endif udfs = dev->private; if (!udfs) { - printk(KERN_ERR "comedi: usbduxfast_ai_cancel: udfs=NULL\n"); + dev_err(dev->class_dev, "%s: udfs=NULL\n", __func__); return -EFAULT; } down(&udfs->sem); @@ -313,22 +316,19 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) /* sanity checks - is the urb there? */ if (!urb) { - printk(KERN_ERR "comedi_: usbduxfast_: ao int-handler called " - "with urb=NULL!\n"); + pr_err("ao int-handler called with urb=NULL!\n"); return; } /* the context variable points to the subdevice */ this_comedidev = urb->context; if (!this_comedidev) { - printk(KERN_ERR "comedi_: usbduxfast_: urb context is a NULL " - "pointer!\n"); + pr_err("urb context is a NULL pointer!\n"); return; } /* the private structure of the subdevice is usbduxfastsub_s */ udfs = this_comedidev->private; if (!udfs) { - printk(KERN_ERR "comedi_: usbduxfast_: private of comedi " - "subdev is a NULL pointer!\n"); + pr_err("private of comedi subdev is a NULL pointer!\n"); return; } /* are we running a command? */ @@ -427,8 +427,8 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) urb->status = 0; err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - printk(KERN_ERR "comedi%d: usbduxfast: urb resubm failed: %d", - udfs->comedidev->minor, err); + dev_err(&urb->dev->dev, + "urb resubm failed: %d", err); s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_ERROR; comedi_event(udfs->comedidev, s); @@ -477,8 +477,8 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs) local_transfer_buffer, 1, /* Length */ EZTIMEOUT); /* Timeout */ if (ret < 0) { - printk(KERN_ERR "comedi_: usbduxfast: control msg failed " - "(stop)\n"); + dev_err(&udfs->interface->dev, + "control msg failed (stop)\n"); return ret; } @@ -512,7 +512,7 @@ static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs, #endif if (ret < 0) { - printk(KERN_ERR "comedi_: usbduxfast: uppload failed\n"); + dev_err(&udfs->interface->dev, "uppload failed\n"); return ret; } @@ -538,8 +538,8 @@ static int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs) #endif ret = usb_submit_urb(udfs->urbIn, GFP_ATOMIC); if (ret) { - printk(KERN_ERR "comedi_: usbduxfast: ai: usb_submit_urb error" - " %d\n", ret); + dev_err(&udfs->interface->dev, + "ai: usb_submit_urb error %d\n", ret); return ret; } return 0; @@ -682,8 +682,7 @@ static int usbduxfast_ai_inttrig(struct comedi_device *dev, #endif if (trignum != 0) { - printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: invalid" - " trignum\n", dev->minor); + dev_err(dev->class_dev, "%s: invalid trignum\n", __func__); up(&udfs->sem); return -EINVAL; } @@ -691,16 +690,16 @@ static int usbduxfast_ai_inttrig(struct comedi_device *dev, udfs->ai_cmd_running = 1; ret = usbduxfastsub_submit_InURBs(udfs); if (ret < 0) { - printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: " - "urbSubmit: err=%d\n", dev->minor, ret); + dev_err(dev->class_dev, + "%s: urbSubmit: err=%d\n", __func__, ret); udfs->ai_cmd_running = 0; up(&udfs->sem); return ret; } s->async->inttrig = NULL; } else { - printk(KERN_ERR "comedi%d: ai_inttrig but acqu is already" - " running\n", dev->minor); + dev_err(dev->class_dev, + "ai_inttrig but acqu is already running\n"); } up(&udfs->sem); return 1; @@ -738,8 +737,8 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, return -ENODEV; } if (udfs->ai_cmd_running) { - printk(KERN_ERR "comedi%d: ai_cmd not possible. Another ai_cmd" - " is running.\n", dev->minor); + dev_err(dev->class_dev, + "ai_cmd not possible. Another ai_cmd is running.\n"); up(&udfs->sem); return -EBUSY; } @@ -757,31 +756,29 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, for (i = 0; i < cmd->chanlist_len; ++i) { chan = CR_CHAN(cmd->chanlist[i]); if (chan != i) { - printk(KERN_ERR "comedi%d: cmd is accepting " - "only consecutive channels.\n", - dev->minor); + dev_err(dev->class_dev, + "cmd is accepting only consecutive channels.\n"); up(&udfs->sem); return -EINVAL; } if ((gain != CR_RANGE(cmd->chanlist[i])) && (cmd->chanlist_len > 3)) { - printk(KERN_ERR "comedi%d: the gain must be" - " the same for all channels.\n", - dev->minor); + dev_err(dev->class_dev, + "the gain must be the same for all channels.\n"); up(&udfs->sem); return -EINVAL; } if (i >= NUMCHANNELS) { - printk(KERN_ERR "comedi%d: channel list too" - " long\n", dev->minor); + dev_err(dev->class_dev, + "channel list too long\n"); break; } } } steps = 0; if (cmd->scan_begin_src == TRIG_TIMER) { - printk(KERN_ERR "comedi%d: usbduxfast: " - "scan_begin_src==TRIG_TIMER not valid.\n", dev->minor); + dev_err(dev->class_dev, + "scan_begin_src==TRIG_TIMER not valid.\n"); up(&udfs->sem); return -EINVAL; } @@ -789,22 +786,21 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, steps = (cmd->convert_arg * 30) / 1000; if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) { - printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: steps=%ld, " - "scan_begin_arg=%d. Not properly tested by cmdtest?\n", - dev->minor, steps, cmd->scan_begin_arg); + dev_err(dev->class_dev, + "ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n", + steps, cmd->scan_begin_arg); up(&udfs->sem); return -EINVAL; } if (steps > MAX_SAMPLING_PERIOD) { - printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: sampling rate " - "too low.\n", dev->minor); + dev_err(dev->class_dev, "ai_cmd: sampling rate too low.\n"); up(&udfs->sem); return -EINVAL; } if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1) && (cmd->chanlist_len != 16)) { - printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: TRIG_EXT only" - " with 1 or 16 channels possible.\n", dev->minor); + dev_err(dev->class_dev, + "ai_cmd: TRIG_EXT only with 1 or 16 channels possible.\n"); up(&udfs->sem); return -EINVAL; } @@ -1121,8 +1117,7 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, break; default: - printk(KERN_ERR "comedi %d: unsupported combination of " - "channels\n", dev->minor); + dev_err(dev->class_dev, "unsupported combination of channels\n"); up(&udfs->sem); return -EFAULT; } @@ -1134,17 +1129,16 @@ static int usbduxfast_ai_cmd(struct comedi_device *dev, /* 0 means that the AD commands are sent */ result = send_dux_commands(udfs, SENDADCOMMANDS); if (result < 0) { - printk(KERN_ERR "comedi%d: adc command could not be submitted." - "Aborting...\n", dev->minor); + dev_err(dev->class_dev, + "adc command could not be submitted. Aborting...\n"); up(&udfs->sem); return result; } if (cmd->stop_src == TRIG_COUNT) { udfs->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg; if (udfs->ai_sample_count < 1) { - printk(KERN_ERR "comedi%d: " - "(cmd->stop_arg)*(cmd->scan_end_arg)<1, " - "aborting.\n", dev->minor); + dev_err(dev->class_dev, + "(cmd->stop_arg)*(cmd->scan_end_arg)<1, aborting.\n"); up(&udfs->sem); return -EFAULT; } @@ -1193,8 +1187,7 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev, udfs = dev->private; if (!udfs) { - printk(KERN_ERR "comedi%d: ai_insn_read: no usb dev.\n", - dev->minor); + dev_err(dev->class_dev, "%s: no usb dev.\n", __func__); return -ENODEV; } #ifdef CONFIG_COMEDI_DEBUG @@ -1207,8 +1200,8 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev, return -ENODEV; } if (udfs->ai_cmd_running) { - printk(KERN_ERR "comedi%d: ai_insn_read not possible. Async " - "Command is running.\n", dev->minor); + dev_err(dev->class_dev, + "ai_insn_read not possible. Async Command is running.\n"); up(&udfs->sem); return -EBUSY; } @@ -1268,8 +1261,8 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev, /* 0 means that the AD commands are sent */ err = send_dux_commands(udfs, SENDADCOMMANDS); if (err < 0) { - printk(KERN_ERR "comedi%d: adc command could not be submitted." - "Aborting...\n", dev->minor); + dev_err(dev->class_dev, + "adc command could not be submitted. Aborting...\n"); up(&udfs->sem); return err; } @@ -1284,8 +1277,7 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev, udfs->transfer_buffer, SIZEINBUF, &actual_length, 10000); if (err < 0) { - printk(KERN_ERR "comedi%d: insn timeout. No data.\n", - dev->minor); + dev_err(dev->class_dev, "insn timeout. No data.\n"); up(&udfs->sem); return err; } @@ -1297,15 +1289,13 @@ static int usbduxfast_ai_insn_read(struct comedi_device *dev, udfs->transfer_buffer, SIZEINBUF, &actual_length, 10000); if (err < 0) { - printk(KERN_ERR "comedi%d: insn data error: %d\n", - dev->minor, err); + dev_err(dev->class_dev, "insn data error: %d\n", err); up(&udfs->sem); return err; } n = actual_length / sizeof(uint16_t); if ((n % 16) != 0) { - printk(KERN_ERR "comedi%d: insn data packet " - "corrupted.\n", dev->minor); + dev_err(dev->class_dev, "insn data packet corrupted.\n"); up(&udfs->sem); return -EINVAL; } @@ -1535,8 +1525,8 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, int ret; if (udev->speed != USB_SPEED_HIGH) { - printk(KERN_ERR "comedi_: usbduxfast_: This driver needs" - "USB 2.0 to operate. Aborting...\n"); + dev_err(&uinterf->dev, + "This driver needs USB 2.0 to operate. Aborting...\n"); return -ENODEV; } #ifdef CONFIG_COMEDI_DEBUG @@ -1555,7 +1545,8 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, /* no more space */ if (index == -1) { - printk(KERN_ERR "Too many usbduxfast-devices connected.\n"); + dev_err(&uinterf->dev, + "Too many usbduxfast-devices connected.\n"); up(&start_stop_sem); return -EMFILE; } @@ -1586,8 +1577,8 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, usbduxfastsub[index].dux_commands = kmalloc(SIZEOFDUXBUFFER, GFP_KERNEL); if (!usbduxfastsub[index].dux_commands) { - printk(KERN_ERR "comedi_: usbduxfast: error alloc space for " - "dac commands\n"); + dev_err(&uinterf->dev, + "error alloc space for dac commands\n"); tidy_up(&(usbduxfastsub[index])); up(&start_stop_sem); return -ENOMEM; @@ -1595,8 +1586,8 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, /* create space of the instruction buffer */ usbduxfastsub[index].insnBuffer = kmalloc(SIZEINSNBUF, GFP_KERNEL); if (!usbduxfastsub[index].insnBuffer) { - printk(KERN_ERR "comedi_: usbduxfast: could not alloc space " - "for insnBuffer\n"); + dev_err(&uinterf->dev, + "could not alloc space for insnBuffer\n"); tidy_up(&(usbduxfastsub[index])); up(&start_stop_sem); return -ENOMEM; @@ -1605,24 +1596,25 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, i = usb_set_interface(usbduxfastsub[index].usbdev, usbduxfastsub[index].ifnum, 1); if (i < 0) { - printk(KERN_ERR "comedi_: usbduxfast%d: could not switch to " - "alternate setting 1.\n", index); + dev_err(&uinterf->dev, + "usbduxfast%d: could not switch to alternate setting 1.\n", + index); tidy_up(&(usbduxfastsub[index])); up(&start_stop_sem); return -ENODEV; } usbduxfastsub[index].urbIn = usb_alloc_urb(0, GFP_KERNEL); if (!usbduxfastsub[index].urbIn) { - printk(KERN_ERR "comedi_: usbduxfast%d: Could not alloc." - "urb\n", index); + dev_err(&uinterf->dev, + "usbduxfast%d: Could not alloc. urb\n", index); tidy_up(&(usbduxfastsub[index])); up(&start_stop_sem); return -ENOMEM; } usbduxfastsub[index].transfer_buffer = kmalloc(SIZEINBUF, GFP_KERNEL); if (!usbduxfastsub[index].transfer_buffer) { - printk(KERN_ERR "comedi_: usbduxfast%d: could not alloc. " - "transb.\n", index); + dev_err(&uinterf->dev, + "usbduxfast%d: could not alloc. transb.\n", index); tidy_up(&(usbduxfastsub[index])); up(&start_stop_sem); return -ENOMEM; @@ -1640,12 +1632,12 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, usbduxfast_firmware_request_complete_handler); if (ret) { - dev_err(&udev->dev, "could not load firmware (err=%d)\n", ret); + dev_err(&uinterf->dev, "could not load firmware (err=%d)\n", ret); return ret; } - printk(KERN_INFO "comedi_: usbduxfast%d has been successfully " - "initialized.\n", index); + dev_info(&uinterf->dev, + "usbduxfast%d has been successfully initialized.\n", index); /* success */ return 0; } @@ -1656,13 +1648,11 @@ static void usbduxfast_usb_disconnect(struct usb_interface *intf) struct usb_device *udev = interface_to_usbdev(intf); if (!udfs) { - printk(KERN_ERR "comedi_: usbduxfast: disconnect called with " - "null pointer.\n"); + dev_err(&intf->dev, "disconnect called with null pointer.\n"); return; } if (udfs->usbdev != udev) { - printk(KERN_ERR "comedi_: usbduxfast: BUG! called with wrong " - "ptr!!!\n"); + dev_err(&intf->dev, "BUG! called with wrong ptr!!!\n"); return; } -- cgit v1.2.3 From cf7d9b4231e5d505084e1438192b27ad6b82dd00 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 24 Oct 2012 21:06:17 +0900 Subject: staging/comedi: Use pr_ or dev_ printks in drivers/unioxx5.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... and added pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/unioxx5.c | 44 +++++++++++++++----------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c index 9f1fdec62dc..c9ded938314 100644 --- a/drivers/staging/comedi/drivers/unioxx5.c +++ b/drivers/staging/comedi/drivers/unioxx5.c @@ -42,6 +42,8 @@ Devices: [Fastwel] UNIOxx-5 (unioxx5), */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "../comedidev.h" #include #include @@ -144,8 +146,7 @@ static int __unioxx5_digital_read(struct unioxx5_subd_priv *usp, channel_offset = __unioxx5_define_chan_offset(channel); if (channel_offset < 0) { - printk(KERN_ERR - "comedi%d: undefined channel %d. channel range is 0 .. 23\n", + pr_err("comedi%d: undefined channel %d. channel range is 0 .. 23\n", minor, channel); return 0; } @@ -171,8 +172,7 @@ static int __unioxx5_analog_read(struct unioxx5_subd_priv *usp, /* defining if given module can work on input */ if (usp->usp_module_type[module_no] & MODULE_OUTPUT_MASK) { - printk(KERN_ERR - "comedi%d: module in position %d with id 0x%02x is for output only", + pr_err("comedi%d: module in position %d with id 0x%02x is for output only", minor, module_no, usp->usp_module_type[module_no]); return 0; } @@ -209,8 +209,7 @@ static int __unioxx5_digital_write(struct unioxx5_subd_priv *usp, channel_offset = __unioxx5_define_chan_offset(channel); if (channel_offset < 0) { - printk(KERN_ERR - "comedi%d: undefined channel %d. channel range is 0 .. 23\n", + pr_err("comedi%d: undefined channel %d. channel range is 0 .. 23\n", minor, channel); return 0; } @@ -240,8 +239,7 @@ static int __unioxx5_analog_write(struct unioxx5_subd_priv *usp, /* defining if given module can work on output */ if (!(usp->usp_module_type[module] & MODULE_OUTPUT_MASK)) { - printk(KERN_ERR - "comedi%d: module in position %d with id 0x%0x is for input only!\n", + pr_err("comedi%d: module in position %d with id 0x%0x is for input only!\n", minor, module, usp->usp_module_type[module]); return 0; } @@ -323,17 +321,17 @@ static int unioxx5_insn_config(struct comedi_device *dev, type = usp->usp_module_type[channel / 2]; if (type != MODULE_DIGITAL) { - printk(KERN_ERR - "comedi%d: channel configuration accessible only for digital modules\n", - dev->minor); + dev_err(dev->class_dev, + "comedi%d: channel configuration accessible only for digital modules\n", + dev->minor); return -1; } channel_offset = __unioxx5_define_chan_offset(channel); if (channel_offset < 0) { - printk(KERN_ERR - "comedi%d: undefined channel %d. channel range is 0 .. 23\n", - dev->minor, channel); + dev_err(dev->class_dev, + "comedi%d: undefined channel %d. channel range is 0 .. 23\n", + dev->minor, channel); return -1; } @@ -348,7 +346,8 @@ static int unioxx5_insn_config(struct comedi_device *dev, flags |= mask; break; default: - printk(KERN_ERR "comedi%d: unknown flag\n", dev->minor); + dev_err(dev->class_dev, + "comedi%d: unknown flag\n", dev->minor); return -1; } @@ -375,19 +374,21 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, int i, to, ndef_flag = 0; if (!request_region(subdev_iobase, UNIOXX5_SIZE, DRIVER_NAME)) { - printk(KERN_ERR "comedi%d: I/O port conflict\n", minor); + dev_err(subdev->class_dev, + "comedi%d: I/O port conflict\n", minor); return -EIO; } usp = kzalloc(sizeof(*usp), GFP_KERNEL); if (usp == NULL) { - printk(KERN_ERR "comedi%d: error! --> out of memory!\n", minor); + dev_err(subdev->class_dev, + "comedi%d: error! --> out of memory!\n", minor); return -1; } usp->usp_iobase = subdev_iobase; - printk(KERN_INFO "comedi%d: |", minor); + dev_info(subdev->class_dev, "comedi%d: |", minor); /* defining modules types */ for (i = 0; i < 12; i++) { @@ -433,8 +434,6 @@ static int __unioxx5_subdev_init(struct comedi_subdevice *subdev, /* for digital modules only!!! */ subdev->insn_config = unioxx5_insn_config; - printk(KERN_INFO "subdevice configured\n"); - return 0; } @@ -464,8 +463,8 @@ static int unioxx5_attach(struct comedi_device *dev, /* unioxx5 can has from two to four subdevices */ if (n_subd < 2) { - printk(KERN_ERR - "your card must has at least 2 'g01' subdevices\n"); + dev_err(dev->class_dev, + "your card must has at least 2 'g01' subdevices\n"); return -1; } @@ -480,7 +479,6 @@ static int unioxx5_attach(struct comedi_device *dev, return -1; } - printk(KERN_INFO "attached\n"); return 0; } -- cgit v1.2.3 From aad3d31fdf925277997641197c2f0eabf728e177 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 24 Oct 2012 02:33:57 -0400 Subject: staging: csr: remove the CsrTime typedef altogether remove CsrTime typedef and replace all the users with the u32 Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_log.h | 2 +- drivers/staging/csr/csr_sched.h | 12 ++++++------ drivers/staging/csr/csr_time.c | 8 ++++---- drivers/staging/csr/csr_time.h | 15 +-------------- drivers/staging/csr/csr_wifi_hip_dump.c | 4 ++-- drivers/staging/csr/csr_wifi_hip_unifi.h | 2 +- drivers/staging/csr/netdev.c | 8 ++++---- drivers/staging/csr/sme_sys.c | 10 +++++----- drivers/staging/csr/unifi_pdu_processing.c | 16 ++++++++-------- drivers/staging/csr/unifi_priv.h | 6 +++--- 10 files changed, 35 insertions(+), 48 deletions(-) diff --git a/drivers/staging/csr/csr_log.h b/drivers/staging/csr/csr_log.h index b2808569f8d..b619db69e14 100644 --- a/drivers/staging/csr/csr_log.h +++ b/drivers/staging/csr/csr_log.h @@ -201,7 +201,7 @@ void CsrLogTimedEventIn(u32 line, const char *file, CsrSchedQid task_id, CsrSchedTid tid, - CsrTime requested_delay, + u32 requested_delay, u16 fniarg, const void *fnvarg); diff --git a/drivers/staging/csr/csr_sched.h b/drivers/staging/csr/csr_sched.h index cc1b8bf6607..e5d6ad898e0 100644 --- a/drivers/staging/csr/csr_sched.h +++ b/drivers/staging/csr/csr_sched.h @@ -37,10 +37,10 @@ typedef CsrSchedIdentifier CsrSchedTid; typedef void (*schedEntryFunction_t)(void **inst); /* Time constants. */ -#define CSR_SCHED_TIME_MAX ((CsrTime) 0xFFFFFFFF) -#define CSR_SCHED_MILLISECOND ((CsrTime) (1000)) -#define CSR_SCHED_SECOND ((CsrTime) (1000 * CSR_SCHED_MILLISECOND)) -#define CSR_SCHED_MINUTE ((CsrTime) (60 * CSR_SCHED_SECOND)) +#define CSR_SCHED_TIME_MAX (0xFFFFFFFF) +#define CSR_SCHED_MILLISECOND (1000) +#define CSR_SCHED_SECOND (1000 * CSR_SCHED_MILLISECOND) +#define CSR_SCHED_MINUTE (60 * CSR_SCHED_SECOND) /* Queue and primitive that identifies the environment */ #define CSR_SCHED_TASK_ID 0xFFFF @@ -218,7 +218,7 @@ u8 CsrSchedMessageGet(u16 *pmi, void **pmv); * *----------------------------------------------------------------------------*/ #if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER) -CsrSchedTid CsrSchedTimerSetStringLog(CsrTime delay, +CsrSchedTid CsrSchedTimerSetStringLog(u32 delay, void (*fn)(u16 mi, void *mv), u16 fniarg, void *fnvarg, @@ -226,7 +226,7 @@ CsrSchedTid CsrSchedTimerSetStringLog(CsrTime delay, const char *file); #define CsrSchedTimerSet(d, fn, fni, fnv) CsrSchedTimerSetStringLog((d), (fn), (fni), (fnv), __LINE__, __FILE__) #else -CsrSchedTid CsrSchedTimerSet(CsrTime delay, +CsrSchedTid CsrSchedTimerSet(u32 delay, void (*fn)(u16 mi, void *mv), u16 fniarg, void *fnvarg); diff --git a/drivers/staging/csr/csr_time.c b/drivers/staging/csr/csr_time.c index f4ff98c71cc..f3f4a9c9c67 100644 --- a/drivers/staging/csr/csr_time.c +++ b/drivers/staging/csr/csr_time.c @@ -14,19 +14,19 @@ #include "csr_time.h" -CsrTime CsrTimeGet(CsrTime *high) +u32 CsrTimeGet(u32 *high) { struct timespec ts; u64 time; - CsrTime low; + u32 low; ts = current_kernel_time(); time = (u64) ts.tv_sec * 1000000 + ts.tv_nsec / 1000; if (high != NULL) - *high = (CsrTime) ((time >> 32) & 0xFFFFFFFF); + *high = (u32) ((time >> 32) & 0xFFFFFFFF); - low = (CsrTime) (time & 0xFFFFFFFF); + low = (u32) (time & 0xFFFFFFFF); return low; } diff --git a/drivers/staging/csr/csr_time.h b/drivers/staging/csr/csr_time.h index d8561541901..5a1d859866e 100644 --- a/drivers/staging/csr/csr_time.h +++ b/drivers/staging/csr/csr_time.h @@ -18,19 +18,6 @@ extern "C" { /******************************************************************************* -NAME - CsrTime - -DESCRIPTION - Type to hold a value describing the current system time, which is a - measure of time elapsed since some arbitrarily defined fixed time - reference, usually associated with system startup. - -*******************************************************************************/ -typedef u32 CsrTime; - -/******************************************************************************* - NAME CsrTimeGet @@ -55,7 +42,7 @@ RETURNS Low part of current system time in microseconds. *******************************************************************************/ -CsrTime CsrTimeGet(CsrTime *high); +u32 CsrTimeGet(u32 *high); /*------------------------------------------------------------------*/ diff --git a/drivers/staging/csr/csr_wifi_hip_dump.c b/drivers/staging/csr/csr_wifi_hip_dump.c index d67b460e7a8..f7523590291 100644 --- a/drivers/staging/csr/csr_wifi_hip_dump.c +++ b/drivers/staging/csr/csr_wifi_hip_dump.c @@ -40,7 +40,7 @@ typedef struct coredump_buf { u16 count; /* serial number of dump */ - CsrTime timestamp; /* host's system time at capture */ + u32 timestamp; /* host's system time at capture */ s16 requestor; /* request: 0=auto dump, 1=manual */ u16 chip_ver; u32 fw_ver; @@ -192,7 +192,7 @@ CsrResult unifi_coredump_capture(card_t *card, struct unifi_coredump_req *req) { CsrResult r = CSR_RESULT_SUCCESS; static u16 dump_seq_no = 1; - CsrTime time_of_capture; + u32 time_of_capture; func_enter(); diff --git a/drivers/staging/csr/csr_wifi_hip_unifi.h b/drivers/staging/csr/csr_wifi_hip_unifi.h index 2923e2ef12f..9042efac610 100644 --- a/drivers/staging/csr/csr_wifi_hip_unifi.h +++ b/drivers/staging/csr/csr_wifi_hip_unifi.h @@ -228,7 +228,7 @@ typedef struct unifi_coredump_req u32 chip_ver; /* Chip version */ u32 fw_ver; /* Firmware version */ s32 requestor; /* Requestor: 0=auto dump, 1=manual */ - CsrTime timestamp; /* time of capture by driver */ + u32 timestamp; /* time of capture by driver */ u32 serial; /* capture serial number */ s32 value; /* register value */ } unifi_coredump_req_t; /* mini-coredumped reg value request */ diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 8a5317159f8..113f2c189a6 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -3246,8 +3246,8 @@ static void check_ba_frame_age_timeout( unifi_priv_t *priv, netInterface_priv_t *interfacePriv, ba_session_rx_struct *ba_session) { - CsrTime now; - CsrTime age; + u32 now; + u32 age; u8 i, j; u16 sn_temp; @@ -3282,11 +3282,11 @@ static void check_ba_frame_age_timeout( unifi_priv_t *priv, if (ba_session->buffer[i].recv_time > now) { /* timer wrap */ - age = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, ba_session->buffer[i].recv_time), now); + age = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, ba_session->buffer[i].recv_time), now); } else { - age = (CsrTime)CsrTimeSub(now, ba_session->buffer[i].recv_time); + age = (u32)CsrTimeSub(now, ba_session->buffer[i].recv_time); } if (age >= CSR_WIFI_BA_MPDU_FRAME_AGE_TIMEOUT) diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c index 90a30dc1c00..9c5ca3a9261 100644 --- a/drivers/staging/csr/sme_sys.c +++ b/drivers/staging/csr/sme_sys.c @@ -2101,7 +2101,7 @@ static int peer_add_new_record(unifi_priv_t *priv,CsrWifiRouterCtrlPeerAddReq *r u8 freeSlotFound = FALSE; CsrWifiRouterCtrlStaInfo_t *newRecord = NULL; netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag]; - CsrTime currentTime, currentTimeHi; + u32 currentTime, currentTimeHi; unsigned long lock_flags; if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) { @@ -2295,8 +2295,8 @@ static void check_inactivity_timer_expire_func(unsigned long data) struct unifi_priv *priv; CsrWifiRouterCtrlStaInfo_t *sta_record = NULL; u8 i = 0; - CsrTime now; - CsrTime inactive_time; + u32 now; + u32 inactive_time; netInterface_priv_t *interfacePriv = (netInterface_priv_t *) data; if (!interfacePriv) @@ -2328,11 +2328,11 @@ static void check_inactivity_timer_expire_func(unsigned long data) if (sta_record->lastActivity > now) { /* simple timer wrap (for 1 wrap) */ - inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, sta_record->lastActivity), now); + inactive_time = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, sta_record->lastActivity), now); } else { - inactive_time = (CsrTime)CsrTimeSub(now, sta_record->lastActivity); + inactive_time = (u32)CsrTimeSub(now, sta_record->lastActivity); } if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL) diff --git a/drivers/staging/csr/unifi_pdu_processing.c b/drivers/staging/csr/unifi_pdu_processing.c index a762939a6ac..8f21d98dff2 100644 --- a/drivers/staging/csr/unifi_pdu_processing.c +++ b/drivers/staging/csr/unifi_pdu_processing.c @@ -1116,8 +1116,8 @@ void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,u16 interfaceTag, const CSR staRecord->nullDataHostTag = INVALID_HOST_TAG; if(pkt_cfm->TransmissionStatus == CSR_TX_RETRY_LIMIT){ - CsrTime now; - CsrTime inactive_time; + u32 now; + u32 inactive_time; unifi_trace(priv, UDBG1, "Nulldata to probe STA ALIVE Failed with retry limit\n"); /* Recheck if there is some activity after null data is sent. @@ -1133,12 +1133,12 @@ void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,u16 interfaceTag, const CSR if (staRecord->lastActivity > now) { /* simple timer wrap (for 1 wrap) */ - inactive_time = CsrTimeAdd((CsrTime)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity), + inactive_time = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity), now); } else { - inactive_time = (CsrTime)CsrTimeSub(now, staRecord->lastActivity); + inactive_time = (u32)CsrTimeSub(now, staRecord->lastActivity); } if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL) @@ -3491,11 +3491,11 @@ CsrWifiRouterCtrlStaInfo_t * CsrWifiRouterCtrlGetStationRecordFromHandle(unifi_p } /* Function to do inactivity */ -void uf_check_inactivity(unifi_priv_t *priv, u16 interfaceTag, CsrTime currentTime) +void uf_check_inactivity(unifi_priv_t *priv, u16 interfaceTag, u32 currentTime) { u32 i; CsrWifiRouterCtrlStaInfo_t *staInfo; - CsrTime elapsedTime; /* Time in microseconds */ + u32 elapsedTime; /* Time in microseconds */ netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; CsrWifiMacAddress peerMacAddress; unsigned long lock_flags; @@ -3542,8 +3542,8 @@ void uf_check_inactivity(unifi_priv_t *priv, u16 interfaceTag, CsrTime currentTi /* Function to update activity of a station */ void uf_update_sta_activity(unifi_priv_t *priv, u16 interfaceTag, const u8 *peerMacAddress) { - CsrTime elapsedTime, currentTime; /* Time in microseconds */ - CsrTime timeHi; /* Not used - Time in microseconds */ + u32 elapsedTime, currentTime; /* Time in microseconds */ + u32 timeHi; /* Not used - Time in microseconds */ CsrWifiRouterCtrlStaInfo_t *staInfo; netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; unsigned long lock_flags; diff --git a/drivers/staging/csr/unifi_priv.h b/drivers/staging/csr/unifi_priv.h index f25b92ab4e2..d20d74ce56c 100644 --- a/drivers/staging/csr/unifi_priv.h +++ b/drivers/staging/csr/unifi_priv.h @@ -312,7 +312,7 @@ typedef struct CsrWifiRouterCtrlStaInfo_t { CSR_CLIENT_TAG nullDataHostTag; /* Activity timestamps for the station */ - CsrTime lastActivity; + u32 lastActivity; /* during m/c transmission sp suspended */ u8 uspSuspend; @@ -652,7 +652,7 @@ typedef struct { bulk_data_param_t bulkdata; CSR_SIGNAL signal; u16 sn; - CsrTime recv_time; + u32 recv_time; } frame_desc_struct; typedef struct { @@ -735,7 +735,7 @@ typedef struct netInterface_priv u8 sta_activity_check_enabled; /* Timestamp when the last inactivity check was done */ - CsrTime last_inactivity_check; + u32 last_inactivity_check; /*number of multicast or borad cast packets queued*/ u16 noOfbroadcastPktQueued; -- cgit v1.2.3 From 5d380bebe76759a1cf591cff6e327e7c9cddc245 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Wed, 24 Oct 2012 02:34:28 -0400 Subject: staging: csr: remove unused function prototypes remove some of the function prototypes , they dont have a definition of the function Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_sched.h | 85 ----------------------------------------- 1 file changed, 85 deletions(-) diff --git a/drivers/staging/csr/csr_sched.h b/drivers/staging/csr/csr_sched.h index e5d6ad898e0..dc67a4a0855 100644 --- a/drivers/staging/csr/csr_sched.h +++ b/drivers/staging/csr/csr_sched.h @@ -55,58 +55,6 @@ typedef u16 CsrSchedBgint; typedef void (*CsrSchedBgintHandler)(void *); -/*----------------------------------------------------------------------------* - * NAME - * CsrSchedBgintReg - * - * DESCRIPTION - * Register a background interrupt handler function with the scheduler. - * When CsrSchedBgint() is called from the foreground (e.g. an interrupt - * routine) the registered function is called. - * - * If "cb" is null then the interrupt is effectively disabled. If a - * no bgints are available, CSR_SCHED_BGINT_INVALID is returned, otherwise - * a CsrSchedBgint value is returned to be used in subsequent calls to - * CsrSchedBgint(). id is a possibly NULL identifier used for logging - * purposes only. - * - * RETURNS - * CsrSchedBgint -- CSR_SCHED_BGINT_INVALID denotes failure to obtain a CsrSchedBgintSet. - * - *----------------------------------------------------------------------------*/ -CsrSchedBgint CsrSchedBgintReg(CsrSchedBgintHandler cb, - void *context, - const char *id); - -/*----------------------------------------------------------------------------* - * NAME - * CsrSchedBgintUnreg - * - * DESCRIPTION - * Unregister a background interrupt handler function. - * - * ``irq'' is a background interrupt handle previously obtained - * from a call to CsrSchedBgintReg(). - * - * RETURNS - * void. - * - *----------------------------------------------------------------------------*/ -void CsrSchedBgintUnreg(CsrSchedBgint bgint); - -/*----------------------------------------------------------------------------* - * NAME - * CsrSchedBgintSet - * - * DESCRIPTION - * Set background interrupt. - * - * RETURNS - * void. - * - *----------------------------------------------------------------------------*/ -void CsrSchedBgintSet(CsrSchedBgint bgint); - /*----------------------------------------------------------------------------* * NAME * CsrSchedMessagePut @@ -176,25 +124,6 @@ void CsrSchedMessageBroadcast(u16 mi, void *msg_build_ptr); #endif -/*----------------------------------------------------------------------------* - * NAME - * CsrSchedMessageGet - * - * DESCRIPTION - * Obtains a message from the message queue belonging to the calling task. - * The message consists of one or both of a u16 and a void *. - * - * RETURNS - * u8 - TRUE if a message has been obtained from the queue, else FALSE. - * If a message is taken from the queue, then "*pmi" and "*pmv" are set to - * the "mi" and "mv" passed to CsrSchedMessagePut() respectively. - * - * "pmi" and "pmv" can be null, in which case the corresponding value from - * them message is discarded. - * - *----------------------------------------------------------------------------*/ -u8 CsrSchedMessageGet(u16 *pmi, void **pmv); - /*----------------------------------------------------------------------------* * NAME * CsrSchedTimerSet @@ -271,20 +200,6 @@ u8 CsrSchedTimerCancel(CsrSchedTid eventid, CsrSchedQid CsrSchedTaskQueueGet(void); -/*----------------------------------------------------------------------------* - * NAME - * CsrSchedTaskQueueGet - * - * DESCRIPTION - * Return the queue identifier for the currently running queue - * - * RETURNS - * char - The current task queue identifier, or 0xFFFF if not available. - * - *----------------------------------------------------------------------------*/ -char* CsrSchedTaskNameGet(CsrSchedQid ); - - #ifdef __cplusplus } #endif -- cgit v1.2.3 From 41b25f871405a4abd6055ca47d3f3056c75200e7 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:45 +0100 Subject: staging: comedi: amplc_dio200: reformat driver comment Reformat the driver description comment to use the preferred block comment style so that future changes are acceptable to the checkpatch.pl script. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 358 +++++++++++++------------- 1 file changed, 179 insertions(+), 179 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 35cd3cbb3be..d08bab4d3f2 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -25,185 +25,185 @@ */ /* -Driver: amplc_dio200 -Description: Amplicon 200 Series Digital I/O -Author: Ian Abbott -Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e), - PCI215 (pci215 or amplc_dio200), PC218E (pc218e), PC272E (pc272e), - PCI272 (pci272 or amplc_dio200) -Updated: Wed, 22 Oct 2008 13:36:02 +0100 -Status: works - -Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E: - [0] - I/O port base address - [1] - IRQ (optional, but commands won't work without it) - -Configuration options - PCI215, PCI272: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first available PCI device will - be used. - -Passing a zero for an option is the same as leaving it unspecified. - -SUBDEVICES - - PC218E PC212E PC215E/PCI215 - ------------- ------------- ------------- - Subdevices 7 6 5 - 0 CTR-X1 PPI-X PPI-X - 1 CTR-X2 CTR-Y1 PPI-Y - 2 CTR-Y1 CTR-Y2 CTR-Z1 - 3 CTR-Y2 CTR-Z1 CTR-Z2 - 4 CTR-Z1 CTR-Z2 INTERRUPT - 5 CTR-Z2 INTERRUPT - 6 INTERRUPT - - PC214E PC272E/PCI272 - ------------- ------------- - Subdevices 4 4 - 0 PPI-X PPI-X - 1 PPI-Y PPI-Y - 2 CTR-Z1* PPI-Z - 3 INTERRUPT* INTERRUPT - -Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels -are configurable as inputs or outputs in four groups: - - Port A - channels 0 to 7 - Port B - channels 8 to 15 - Port CL - channels 16 to 19 - Port CH - channels 20 to 23 - -Only mode 0 of the 8255 chips is supported. - -Each CTR is a 8254 chip providing 3 16-bit counter channels. Each -channel is configured individually with INSN_CONFIG instructions. The -specific type of configuration instruction is specified in data[0]. -Some configuration instructions expect an additional parameter in -data[1]; others return a value in data[1]. The following configuration -instructions are supported: - - INSN_CONFIG_SET_COUNTER_MODE. Sets the counter channel's mode and - BCD/binary setting specified in data[1]. - - INSN_CONFIG_8254_READ_STATUS. Reads the status register value for the - counter channel into data[1]. - - INSN_CONFIG_SET_CLOCK_SRC. Sets the counter channel's clock source as - specified in data[1] (this is a hardware-specific value). Not - supported on PC214E. For the other boards, valid clock sources are - 0 to 7 as follows: - - 0. CLK n, the counter channel's dedicated CLK input from the SK1 - connector. (N.B. for other values, the counter channel's CLKn - pin on the SK1 connector is an output!) - 1. Internal 10 MHz clock. - 2. Internal 1 MHz clock. - 3. Internal 100 kHz clock. - 4. Internal 10 kHz clock. - 5. Internal 1 kHz clock. - 6. OUT n-1, the output of counter channel n-1 (see note 1 below). - 7. Ext Clock, the counter chip's dedicated Ext Clock input from - the SK1 connector. This pin is shared by all three counter - channels on the chip. - - INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current - clock source in data[1]. For internal clock sources, data[2] is set - to the period in ns. - - INSN_CONFIG_SET_GATE_SRC. Sets the counter channel's gate source as - specified in data[2] (this is a hardware-specific value). Not - supported on PC214E. For the other boards, valid gate sources are 0 - to 7 as follows: - - 0. VCC (internal +5V d.c.), i.e. gate permanently enabled. - 1. GND (internal 0V d.c.), i.e. gate permanently disabled. - 2. GAT n, the counter channel's dedicated GAT input from the SK1 - connector. (N.B. for other values, the counter channel's GATn - pin on the SK1 connector is an output!) - 3. /OUT n-2, the inverted output of counter channel n-2 (see note - 2 below). - 4. Reserved. - 5. Reserved. - 6. Reserved. - 7. Reserved. - - INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate - source in data[2]. - -Clock and gate interconnection notes: - - 1. Clock source OUT n-1 is the output of the preceding channel on the - same counter subdevice if n > 0, or the output of channel 2 on the - preceding counter subdevice (see note 3) if n = 0. - - 2. Gate source /OUT n-2 is the inverted output of channel 0 on the - same counter subdevice if n = 2, or the inverted output of channel n+1 - on the preceding counter subdevice (see note 3) if n < 2. - - 3. The counter subdevices are connected in a ring, so the highest - counter subdevice precedes the lowest. - -The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The -digital inputs come from the interrupt status register. The number of -channels matches the number of interrupt sources. The PC214E does not -have an interrupt status register; see notes on 'INTERRUPT SOURCES' -below. - -INTERRUPT SOURCES - - PC218E PC212E PC215E/PCI215 - ------------- ------------- ------------- - Sources 6 6 6 - 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0 - 1 CTR-X2-OUT PPI-X-C3 PPI-X-C3 - 2 CTR-Y1-OUT CTR-Y1-OUT PPI-Y-C0 - 3 CTR-Y2-OUT CTR-Y2-OUT PPI-Y-C3 - 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT - 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT - - PC214E PC272E/PCI272 - ------------- ------------- - Sources 1 6 - 0 JUMPER-J5 PPI-X-C0 - 1 PPI-X-C3 - 2 PPI-Y-C0 - 3 PPI-Y-C3 - 4 PPI-Z-C0 - 5 PPI-Z-C3 - -When an interrupt source is enabled in the interrupt source enable -register, a rising edge on the source signal latches the corresponding -bit to 1 in the interrupt status register. - -When the interrupt status register value as a whole (actually, just the -6 least significant bits) goes from zero to non-zero, the board will -generate an interrupt. For level-triggered hardware interrupts (PCI -card), the interrupt will remain asserted until the interrupt status -register is cleared to zero. For edge-triggered hardware interrupts -(ISA card), no further interrupts will occur until the interrupt status -register is cleared to zero. To clear a bit to zero in the interrupt -status register, the corresponding interrupt source must be disabled -in the interrupt source enable register (there is no separate interrupt -clear register). - -The PC214E does not have an interrupt source enable register or an -interrupt status register; its 'INTERRUPT' subdevice has a single -channel and its interrupt source is selected by the position of jumper -J5. - -COMMANDS - -The driver supports a read streaming acquisition command on the -'INTERRUPT' subdevice. The channel list selects the interrupt sources -to be enabled. All channels will be sampled together (convert_src == -TRIG_NOW). The scan begins a short time after the hardware interrupt -occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT, -scan_begin_arg == 0). The value read from the interrupt status register -is packed into a short value, one bit per requested channel, in the -order they appear in the channel list. -*/ + * Driver: amplc_dio200 + * Description: Amplicon 200 Series Digital I/O + * Author: Ian Abbott + * Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e), + * PCI215 (pci215 or amplc_dio200), PC218E (pc218e), PC272E (pc272e), + * PCI272 (pci272 or amplc_dio200) + * Updated: Wed, 22 Oct 2008 13:36:02 +0100 + * Status: works + * + * Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E: + * [0] - I/O port base address + * [1] - IRQ (optional, but commands won't work without it) + * + * Configuration options - PCI215, PCI272: + * [0] - PCI bus of device (optional) + * [1] - PCI slot of device (optional) + * If bus/slot is not specified, the first available PCI device will + * be used. + * + * Passing a zero for an option is the same as leaving it unspecified. + * + * SUBDEVICES + * + * PC218E PC212E PC215E/PCI215 + * ------------- ------------- ------------- + * Subdevices 7 6 5 + * 0 CTR-X1 PPI-X PPI-X + * 1 CTR-X2 CTR-Y1 PPI-Y + * 2 CTR-Y1 CTR-Y2 CTR-Z1 + * 3 CTR-Y2 CTR-Z1 CTR-Z2 + * 4 CTR-Z1 CTR-Z2 INTERRUPT + * 5 CTR-Z2 INTERRUPT + * 6 INTERRUPT + * + * PC214E PC272E/PCI272 + * ------------- ------------- + * Subdevices 4 4 + * 0 PPI-X PPI-X + * 1 PPI-Y PPI-Y + * 2 CTR-Z1* PPI-Z + * 3 INTERRUPT* INTERRUPT + * + * Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels + * are configurable as inputs or outputs in four groups: + * + * Port A - channels 0 to 7 + * Port B - channels 8 to 15 + * Port CL - channels 16 to 19 + * Port CH - channels 20 to 23 + * + * Only mode 0 of the 8255 chips is supported. + * + * Each CTR is a 8254 chip providing 3 16-bit counter channels. Each + * channel is configured individually with INSN_CONFIG instructions. The + * specific type of configuration instruction is specified in data[0]. + * Some configuration instructions expect an additional parameter in + * data[1]; others return a value in data[1]. The following configuration + * instructions are supported: + * + * INSN_CONFIG_SET_COUNTER_MODE. Sets the counter channel's mode and + * BCD/binary setting specified in data[1]. + * + * INSN_CONFIG_8254_READ_STATUS. Reads the status register value for the + * counter channel into data[1]. + * + * INSN_CONFIG_SET_CLOCK_SRC. Sets the counter channel's clock source as + * specified in data[1] (this is a hardware-specific value). Not + * supported on PC214E. For the other boards, valid clock sources are + * 0 to 7 as follows: + * + * 0. CLK n, the counter channel's dedicated CLK input from the SK1 + * connector. (N.B. for other values, the counter channel's CLKn + * pin on the SK1 connector is an output!) + * 1. Internal 10 MHz clock. + * 2. Internal 1 MHz clock. + * 3. Internal 100 kHz clock. + * 4. Internal 10 kHz clock. + * 5. Internal 1 kHz clock. + * 6. OUT n-1, the output of counter channel n-1 (see note 1 below). + * 7. Ext Clock, the counter chip's dedicated Ext Clock input from + * the SK1 connector. This pin is shared by all three counter + * channels on the chip. + * + * INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current + * clock source in data[1]. For internal clock sources, data[2] is set + * to the period in ns. + * + * INSN_CONFIG_SET_GATE_SRC. Sets the counter channel's gate source as + * specified in data[2] (this is a hardware-specific value). Not + * supported on PC214E. For the other boards, valid gate sources are 0 + * to 7 as follows: + * + * 0. VCC (internal +5V d.c.), i.e. gate permanently enabled. + * 1. GND (internal 0V d.c.), i.e. gate permanently disabled. + * 2. GAT n, the counter channel's dedicated GAT input from the SK1 + * connector. (N.B. for other values, the counter channel's GATn + * pin on the SK1 connector is an output!) + * 3. /OUT n-2, the inverted output of counter channel n-2 (see note + * 2 below). + * 4. Reserved. + * 5. Reserved. + * 6. Reserved. + * 7. Reserved. + * + * INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate + * source in data[2]. + * + * Clock and gate interconnection notes: + * + * 1. Clock source OUT n-1 is the output of the preceding channel on the + * same counter subdevice if n > 0, or the output of channel 2 on the + * preceding counter subdevice (see note 3) if n = 0. + * + * 2. Gate source /OUT n-2 is the inverted output of channel 0 on the + * same counter subdevice if n = 2, or the inverted output of channel n+1 + * on the preceding counter subdevice (see note 3) if n < 2. + * + * 3. The counter subdevices are connected in a ring, so the highest + * counter subdevice precedes the lowest. + * + * The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The + * digital inputs come from the interrupt status register. The number of + * channels matches the number of interrupt sources. The PC214E does not + * have an interrupt status register; see notes on 'INTERRUPT SOURCES' + * below. + * + * INTERRUPT SOURCES + * + * PC218E PC212E PC215E/PCI215 + * ------------- ------------- ------------- + * Sources 6 6 6 + * 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0 + * 1 CTR-X2-OUT PPI-X-C3 PPI-X-C3 + * 2 CTR-Y1-OUT CTR-Y1-OUT PPI-Y-C0 + * 3 CTR-Y2-OUT CTR-Y2-OUT PPI-Y-C3 + * 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT + * 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT + * + * PC214E PC272E/PCI272 + * ------------- ------------- + * Sources 1 6 + * 0 JUMPER-J5 PPI-X-C0 + * 1 PPI-X-C3 + * 2 PPI-Y-C0 + * 3 PPI-Y-C3 + * 4 PPI-Z-C0 + * 5 PPI-Z-C3 + * + * When an interrupt source is enabled in the interrupt source enable + * register, a rising edge on the source signal latches the corresponding + * bit to 1 in the interrupt status register. + * + * When the interrupt status register value as a whole (actually, just the + * 6 least significant bits) goes from zero to non-zero, the board will + * generate an interrupt. For level-triggered hardware interrupts (PCI + * card), the interrupt will remain asserted until the interrupt status + * register is cleared to zero. For edge-triggered hardware interrupts + * (ISA card), no further interrupts will occur until the interrupt status + * register is cleared to zero. To clear a bit to zero in the interrupt + * status register, the corresponding interrupt source must be disabled + * in the interrupt source enable register (there is no separate interrupt + * clear register). + * + * The PC214E does not have an interrupt source enable register or an + * interrupt status register; its 'INTERRUPT' subdevice has a single + * channel and its interrupt source is selected by the position of jumper + * J5. + * + * COMMANDS + * + * The driver supports a read streaming acquisition command on the + * 'INTERRUPT' subdevice. The channel list selects the interrupt sources + * to be enabled. All channels will be sampled together (convert_src == + * TRIG_NOW). The scan begins a short time after the hardware interrupt + * occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT, + * scan_begin_arg == 0). The value read from the interrupt status register + * is packed into a short value, one bit per requested channel, in the + * order they appear in the channel list. + */ #include #include -- cgit v1.2.3 From e45e423be45d7bbb404fd6db724960eea3702681 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:46 +0100 Subject: staging: comedi: amplc_dio200: remove manual configuration of PCI boards Remove the code that allows PCI boards to be manually attached by the `COMEDI_DEVCONFIG` ioctl (or the "comedi_config" application). Supported PCI boards will be attached automatically at probe time via `comedi_pci_auto_config()` and the `attach_pci` hook in the `struct comedi_driver`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 70 +++------------------------ 1 file changed, 7 insertions(+), 63 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index d08bab4d3f2..c07f86b7a4a 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -29,8 +29,7 @@ * Description: Amplicon 200 Series Digital I/O * Author: Ian Abbott * Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e), - * PCI215 (pci215 or amplc_dio200), PC218E (pc218e), PC272E (pc272e), - * PCI272 (pci272 or amplc_dio200) + * PCI215 (pci215), PC218E (pc218e), PC272E (pc272e), PCI272 (pci272) * Updated: Wed, 22 Oct 2008 13:36:02 +0100 * Status: works * @@ -38,11 +37,8 @@ * [0] - I/O port base address * [1] - IRQ (optional, but commands won't work without it) * - * Configuration options - PCI215, PCI272: - * [0] - PCI bus of device (optional) - * [1] - PCI slot of device (optional) - * If bus/slot is not specified, the first available PCI device will - * be used. + * Manual configuration of PCI cards is not supported; they are configured + * automatically. * * Passing a zero for an option is the same as leaving it unspecified. * @@ -272,7 +268,6 @@ enum dio200_model { pc215e_model, pci215_model, pc218e_model, pc272e_model, pci272_model, - anypci_model }; enum dio200_layout { @@ -343,12 +338,6 @@ static const struct dio200_board dio200_boards[] = { .model = pci272_model, .layout = pc272_layout, }, - { - .name = DIO200_DRIVER_NAME, - .devid = PCI_DEVICE_ID_INVALID, - .bustype = pci_bustype, - .model = anypci_model, /* wildcard */ - }, #endif }; @@ -478,49 +467,6 @@ dio200_find_pci_board(struct pci_dev *pci_dev) return NULL; } -/* - * This function looks for a PCI device matching the requested board name, - * bus and slot. - */ -static struct pci_dev *dio200_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - const struct dio200_board *thisboard = comedi_board(dev); - struct pci_dev *pci_dev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - - for_each_pci_dev(pci_dev) { - if (bus || slot) { - if (bus != pci_dev->bus->number || - slot != PCI_SLOT(pci_dev->devfn)) - continue; - } - if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON) - continue; - - if (thisboard->model == anypci_model) { - /* Wildcard board matches any supported PCI board. */ - const struct dio200_board *foundboard; - - foundboard = dio200_find_pci_board(pci_dev); - if (foundboard == NULL) - continue; - /* Replace wildcard board_ptr. */ - dev->board_ptr = foundboard; - } else { - /* Match specific model name. */ - if (pci_dev->device != thisboard->devid) - continue; - } - return pci_dev; - } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); - return NULL; -} - /* * This function checks and requests an I/O region, reporting an error * if there is a conflict. @@ -1356,12 +1302,10 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) return ret; return dio200_common_attach(dev, iobase, irq, 0); } else if (is_pci_board(thisboard)) { - struct pci_dev *pci_dev; - - pci_dev = dio200_find_pci_dev(dev, it); - if (!pci_dev) - return -EIO; - return dio200_pci_common_attach(dev, pci_dev); + dev_err(dev->class_dev, + "Manual configuration of PCI board '%s' is not supported\n", + thisboard->name); + return -EIO; } else { dev_err(dev->class_dev, DIO200_DRIVER_NAME ": BUG! cannot determine board type!\n"); -- cgit v1.2.3 From f34e08f54f078cb4911962b43c2bd16c2f8ccce3 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:47 +0100 Subject: staging: comedi: amplc_dio200: no need to manipulate PCI ref count Now that this driver no longer supports "manual" attachment of PCI devices in its `attach` hook (`dio200_attach()`), it no longer has code that searches for a suitable PCI device and increments its reference count. Since the driver no longer has any reason for incrementing and decrementing the PCI device's reference count, the calls to `pci_dev_get()` and `pci_dev_put()` can be removed. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index c07f86b7a4a..06550c999ba 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1339,13 +1339,6 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); return -EINVAL; } - /* - * Need to 'get' the PCI device to match the 'put' in dio200_detach(). - * TODO: Remove the pci_dev_get() and matching pci_dev_put() once - * support for manual attachment of PCI devices via dio200_attach() - * has been removed. - */ - pci_dev_get(pci_dev); return dio200_pci_common_attach(dev, pci_dev); } @@ -1384,7 +1377,6 @@ static void dio200_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } } -- cgit v1.2.3 From 8e17cfbaa0b6ffa839028661327a17020cc53d2d Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:48 +0100 Subject: staging: comedi: amplc_dio200: no need to set hw_dev The call to `comedi_set_hw_dev()` from `dio200_pci_common_attach()` is now unnecessary since `dio200_pci_common_attach()` is now only called from this driver's `attach_pci` hook `dio200_attach_pci()` and the comedi core now calls `comedi_set_hw_dev()` before calling that. Remove the unnecessary call. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 06550c999ba..2c39dc5f8d5 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1259,8 +1259,6 @@ static int dio200_pci_common_attach(struct comedi_device *dev, unsigned long iobase; int ret; - comedi_set_hw_dev(dev, &pci_dev->dev); - ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); if (ret < 0) { dev_err(dev->class_dev, -- cgit v1.2.3 From dba949a1a0839d324642d99bce90052964125b45 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:49 +0100 Subject: staging: comedi: amplc_dio200: absorb dio200_pci_common_attach() Absorb `dio200_pci_common_attach()` into `dio200_attach_pci()` since that's the only place it is called from. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 2c39dc5f8d5..0cc6e11d188 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1253,22 +1253,6 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, return 1; } -static int dio200_pci_common_attach(struct comedi_device *dev, - struct pci_dev *pci_dev) -{ - unsigned long iobase; - int ret; - - ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); - if (ret < 0) { - dev_err(dev->class_dev, - "error! cannot enable PCI device and request regions!\n"); - return ret; - } - iobase = pci_resource_start(pci_dev, 2); - return dio200_common_attach(dev, iobase, pci_dev->irq, IRQF_SHARED); -} - /* * Attach is called by the Comedi core to configure the driver * for a particular board. If you specified a board_name array @@ -1320,6 +1304,8 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { struct dio200_private *devpriv; + unsigned long iobase; + int ret; if (!DO_PCI) return -EINVAL; @@ -1337,7 +1323,14 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); return -EINVAL; } - return dio200_pci_common_attach(dev, pci_dev); + ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); + if (ret < 0) { + dev_err(dev->class_dev, + "error! cannot enable PCI device and request regions!\n"); + return ret; + } + iobase = pci_resource_start(pci_dev, 2); + return dio200_common_attach(dev, iobase, pci_dev->irq, IRQF_SHARED); } static void dio200_detach(struct comedi_device *dev) -- cgit v1.2.3 From 96a9319f71169a159a38113964f0745697d33929 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:50 +0100 Subject: staging: comedi: amplc_dio200: pass device to clock/gate config Rename the clock and gate configuration functions for the '8254' counter subdevices and pass in the pointers to the comedi device and comedi subdevice. This is just preparing the way for later changes. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 40 +++++++++++++++++---------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 0cc6e11d188..a7fdd66e029 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -953,9 +953,12 @@ dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s, * Set gate source for an '8254' counter subdevice channel. */ static int -dio200_set_gate_src(struct dio200_subdev_8254 *subpriv, - unsigned int counter_number, unsigned int gate_src) +dio200_subdev_8254_set_gate_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int counter_number, + unsigned int gate_src) { + struct dio200_subdev_8254 *subpriv = s->private; unsigned char byte; if (!subpriv->has_clk_gat_sce) @@ -976,9 +979,12 @@ dio200_set_gate_src(struct dio200_subdev_8254 *subpriv, * Get gate source for an '8254' counter subdevice channel. */ static int -dio200_get_gate_src(struct dio200_subdev_8254 *subpriv, - unsigned int counter_number) +dio200_subdev_8254_get_gate_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int counter_number) { + struct dio200_subdev_8254 *subpriv = s->private; + if (!subpriv->has_clk_gat_sce) return -1; if (counter_number > 2) @@ -991,9 +997,12 @@ dio200_get_gate_src(struct dio200_subdev_8254 *subpriv, * Set clock source for an '8254' counter subdevice channel. */ static int -dio200_set_clock_src(struct dio200_subdev_8254 *subpriv, - unsigned int counter_number, unsigned int clock_src) +dio200_subdev_8254_set_clock_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int counter_number, + unsigned int clock_src) { + struct dio200_subdev_8254 *subpriv = s->private; unsigned char byte; if (!subpriv->has_clk_gat_sce) @@ -1014,9 +1023,12 @@ dio200_set_clock_src(struct dio200_subdev_8254 *subpriv, * Get clock source for an '8254' counter subdevice channel. */ static int -dio200_get_clock_src(struct dio200_subdev_8254 *subpriv, - unsigned int counter_number, unsigned int *period_ns) +dio200_subdev_8254_get_clock_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int counter_number, + unsigned int *period_ns) { + struct dio200_subdev_8254 *subpriv = s->private; unsigned clock_src; if (!subpriv->has_clk_gat_sce) @@ -1052,12 +1064,12 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s, data[1] = i8254_status(subpriv->iobase, 0, chan); break; case INSN_CONFIG_SET_GATE_SRC: - ret = dio200_set_gate_src(subpriv, chan, data[2]); + ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]); if (ret < 0) ret = -EINVAL; break; case INSN_CONFIG_GET_GATE_SRC: - ret = dio200_get_gate_src(subpriv, chan); + ret = dio200_subdev_8254_get_gate_src(dev, s, chan); if (ret < 0) { ret = -EINVAL; break; @@ -1065,12 +1077,12 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s, data[2] = ret; break; case INSN_CONFIG_SET_CLOCK_SRC: - ret = dio200_set_clock_src(subpriv, chan, data[1]); + ret = dio200_subdev_8254_set_clock_src(dev, s, chan, data[1]); if (ret < 0) ret = -EINVAL; break; case INSN_CONFIG_GET_CLOCK_SRC: - ret = dio200_get_clock_src(subpriv, chan, &data[2]); + ret = dio200_subdev_8254_get_clock_src(dev, s, chan, &data[2]); if (ret < 0) { ret = -EINVAL; break; @@ -1133,9 +1145,9 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, I8254_MODE0 | I8254_BINARY); if (subpriv->has_clk_gat_sce) { /* Gate source 0 is VCC (logic 1). */ - dio200_set_gate_src(subpriv, chan, 0); + dio200_subdev_8254_set_gate_src(dev, s, chan, 0); /* Clock source 0 is the dedicated clock input. */ - dio200_set_clock_src(subpriv, chan, 0); + dio200_subdev_8254_set_clock_src(dev, s, chan, 0); } } -- cgit v1.2.3 From 853376e502283d740b7700524c822bb924b171b5 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:51 +0100 Subject: staging: comedi: amplc_dio200: rename enum dio200_layout Rename `enum dio200_layout` to `enum dio200_layout_idx`. It's only used once and frees up the `dio200_layout` tag for something else later. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index a7fdd66e029..a5876f87096 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -270,7 +270,7 @@ enum dio200_model { pc272e_model, pci272_model, }; -enum dio200_layout { +enum dio200_layout_idx { #if DO_ISA pc212_layout, pc214_layout, @@ -287,7 +287,7 @@ struct dio200_board { unsigned short devid; enum dio200_bustype bustype; enum dio200_model model; - enum dio200_layout layout; + enum dio200_layout_idx layout; }; static const struct dio200_board dio200_boards[] = { -- cgit v1.2.3 From 4821bdfc9c39349f97e9c604992aafd55f45255a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:52 +0100 Subject: staging: comedi: amplc_dio200: rename struct dio200_layout_struct Now that the tag name `dio200_layout` is available, rename `struct dio200_layout_struct` to `struct dio200_layout` as the `_struct` suffix is a bit redundant and I plan to use this type in other places in the module. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index a5876f87096..b03e7e32fb1 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -351,7 +351,7 @@ enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254 }; #define DIO200_MAX_SUBDEVS 7 #define DIO200_MAX_ISNS 6 -struct dio200_layout_struct { +struct dio200_layout { unsigned short n_subdevs; /* number of subdevices */ unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */ unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */ @@ -359,7 +359,7 @@ struct dio200_layout_struct { char has_clk_gat_sce; /* has clock/gate selection registers */ }; -static const struct dio200_layout_struct dio200_layouts[] = { +static const struct dio200_layout dio200_layouts[] = { #if DO_ISA [pc212_layout] = { .n_subdevs = 6, @@ -1195,8 +1195,7 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, { const struct dio200_board *thisboard = comedi_board(dev); struct dio200_private *devpriv = dev->private; - const struct dio200_layout_struct *layout = - &dio200_layouts[thisboard->layout]; + const struct dio200_layout *layout = &dio200_layouts[thisboard->layout]; struct comedi_subdevice *s; int sdx; unsigned int n; @@ -1348,7 +1347,7 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, static void dio200_detach(struct comedi_device *dev) { const struct dio200_board *thisboard = comedi_board(dev); - const struct dio200_layout_struct *layout; + const struct dio200_layout *layout; unsigned n; if (dev->irq) -- cgit v1.2.3 From a56a8a3c4979b0c968a53ab9cdbf6887e8e6ba1e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:53 +0100 Subject: staging: comedi: amplc_dio200: add helpers to get board layout Add inline helper function `dio200_board_layout(board)` to get a pointer to the board layout data for a board. Add inline helper function `dio200_dev_layout(dev)` to get a pointer to the board layout data for a comedi device (this function is currently unused but will be used by a later change). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index b03e7e32fb1..bf4f6e3365c 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -442,6 +442,18 @@ struct dio200_subdev_intr { int continuous; }; +static inline const struct dio200_layout * +dio200_board_layout(const struct dio200_board *board) +{ + return &dio200_layouts[board->layout]; +} + +static inline const struct dio200_layout * +dio200_dev_layout(struct comedi_device *dev) +{ + return dio200_board_layout(comedi_board(dev)); +} + static inline bool is_pci_board(const struct dio200_board *board) { return DO_PCI && board->bustype == pci_bustype; @@ -1195,7 +1207,7 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, { const struct dio200_board *thisboard = comedi_board(dev); struct dio200_private *devpriv = dev->private; - const struct dio200_layout *layout = &dio200_layouts[thisboard->layout]; + const struct dio200_layout *layout = dio200_board_layout(thisboard); struct comedi_subdevice *s; int sdx; unsigned int n; @@ -1353,7 +1365,7 @@ static void dio200_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); if (dev->subdevices) { - layout = &dio200_layouts[thisboard->layout]; + layout = dio200_board_layout(thisboard); for (n = 0; n < dev->n_subdevices; n++) { struct comedi_subdevice *s = &dev->subdevices[n]; switch (layout->sdtype[n]) { -- cgit v1.2.3 From 4bb4021762c33e65645244a965001454cbda6145 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:54 +0100 Subject: staging: comedi: amplc_dio200: remove 'has_clk_gat_sce' from subdevice The `has_clk_gat_sce` member of `struct dio200_subdev_8254` indicates whether the board has clock and gate source selection registers. The same information can be obtained from read-only board layout data so doesn't need to be set per '8254' counter subdevice. Eliminate the member and use the read-only data instead. The last parameter of `dio200_subdev_8254_init()` is used to initialize this member, so remove that parameter as well. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index bf4f6e3365c..bab2e6477fa 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -425,7 +425,6 @@ struct dio200_subdev_8254 { unsigned long clk_sce_iobase; /* CLK_SCE base address */ unsigned long gat_sce_iobase; /* GAT_SCE base address */ int which; /* Bit 5 of CLK_SCE or GAT_SCE */ - int has_clk_gat_sce; unsigned clock_src[3]; /* Current clock sources */ unsigned gate_src[3]; /* Current gate sources */ spinlock_t spinlock; @@ -970,10 +969,11 @@ dio200_subdev_8254_set_gate_src(struct comedi_device *dev, unsigned int counter_number, unsigned int gate_src) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_8254 *subpriv = s->private; unsigned char byte; - if (!subpriv->has_clk_gat_sce) + if (!layout->has_clk_gat_sce) return -1; if (counter_number > 2) return -1; @@ -995,9 +995,10 @@ dio200_subdev_8254_get_gate_src(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int counter_number) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_8254 *subpriv = s->private; - if (!subpriv->has_clk_gat_sce) + if (!layout->has_clk_gat_sce) return -1; if (counter_number > 2) return -1; @@ -1014,10 +1015,11 @@ dio200_subdev_8254_set_clock_src(struct comedi_device *dev, unsigned int counter_number, unsigned int clock_src) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_8254 *subpriv = s->private; unsigned char byte; - if (!subpriv->has_clk_gat_sce) + if (!layout->has_clk_gat_sce) return -1; if (counter_number > 2) return -1; @@ -1040,10 +1042,11 @@ dio200_subdev_8254_get_clock_src(struct comedi_device *dev, unsigned int counter_number, unsigned int *period_ns) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_8254 *subpriv = s->private; unsigned clock_src; - if (!subpriv->has_clk_gat_sce) + if (!layout->has_clk_gat_sce) return -1; if (counter_number > 2) return -1; @@ -1117,9 +1120,9 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s, */ static int dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned long iobase, unsigned offset, - int has_clk_gat_sce) + unsigned long iobase, unsigned offset) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_8254 *subpriv; unsigned int chan; @@ -1140,8 +1143,7 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, spin_lock_init(&subpriv->spinlock); subpriv->iobase = offset + iobase; - subpriv->has_clk_gat_sce = has_clk_gat_sce; - if (has_clk_gat_sce) { + if (layout->has_clk_gat_sce) { /* Derive CLK_SCE and GAT_SCE register offsets from * 8254 offset. */ subpriv->clk_sce_iobase = @@ -1155,7 +1157,7 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, for (chan = 0; chan < 3; chan++) { i8254_set_mode(subpriv->iobase, 0, chan, I8254_MODE0 | I8254_BINARY); - if (subpriv->has_clk_gat_sce) { + if (layout->has_clk_gat_sce) { /* Gate source 0 is VCC (logic 1). */ dio200_subdev_8254_set_gate_src(dev, s, chan, 0); /* Clock source 0 is the dedicated clock input. */ @@ -1227,8 +1229,7 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, case sd_8254: /* counter subdevice (8254) */ ret = dio200_subdev_8254_init(dev, s, iobase, - layout->sdinfo[n], - layout->has_clk_gat_sce); + layout->sdinfo[n]); if (ret < 0) return ret; break; -- cgit v1.2.3 From cda84375f337332421101e7a94f72d0512f8d742 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:55 +0100 Subject: staging: comedi: amplc_dio200: use register offsets in subdevices Replace the absolute, modified I/O base addresses in the private data structures for the '8254' counter and 'intr' DIO subdevices with offsets from the main I/O base address. `dio200_subdev_intr_init()` now needs the offset instead of the absolute address. `dio200_subdev_8254_init()` now only needs the offset instead of both the absolute address and the offset. The '8255' DIO subdevices are unaffected as they are handled by the external "8255" module. This change is not useful by itself but is an intermediate step for later changes. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 93 +++++++++++++-------------- 1 file changed, 45 insertions(+), 48 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index bab2e6477fa..16ae7a395d5 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -421,20 +421,19 @@ struct dio200_private { }; struct dio200_subdev_8254 { - unsigned long iobase; /* Counter base address */ - unsigned long clk_sce_iobase; /* CLK_SCE base address */ - unsigned long gat_sce_iobase; /* GAT_SCE base address */ - int which; /* Bit 5 of CLK_SCE or GAT_SCE */ - unsigned clock_src[3]; /* Current clock sources */ - unsigned gate_src[3]; /* Current gate sources */ + unsigned int ofs; /* Counter base offset */ + unsigned int clk_sce_ofs; /* CLK_SCE base address */ + unsigned int gat_sce_ofs; /* GAT_SCE base address */ + int which; /* Bit 5 of CLK_SCE or GAT_SCE */ + unsigned int clock_src[3]; /* Current clock sources */ + unsigned int gate_src[3]; /* Current gate sources */ spinlock_t spinlock; }; struct dio200_subdev_intr { - unsigned long iobase; + unsigned int ofs; spinlock_t spinlock; int active; - int has_int_sce; unsigned int valid_isns; unsigned int enabled_isns; unsigned int stopcount; @@ -502,11 +501,12 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_intr *subpriv = s->private; - if (subpriv->has_int_sce) { + if (layout->has_int_sce) { /* Just read the interrupt status register. */ - data[1] = inb(subpriv->iobase) & subpriv->valid_isns; + data[1] = inb(dev->iobase + subpriv->ofs) & subpriv->valid_isns; } else { /* No interrupt status register. */ data[0] = 0; @@ -521,12 +521,13 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev, static void dio200_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_intr *subpriv = s->private; subpriv->active = 0; subpriv->enabled_isns = 0; - if (subpriv->has_int_sce) - outb(0, subpriv->iobase); + if (layout->has_int_sce) + outb(0, dev->iobase + subpriv->ofs); } /* @@ -537,6 +538,7 @@ static int dio200_start_intr(struct comedi_device *dev, { unsigned int n; unsigned isn_bits; + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_intr *subpriv = s->private; struct comedi_cmd *cmd = &s->async->cmd; int retval = 0; @@ -556,8 +558,8 @@ static int dio200_start_intr(struct comedi_device *dev, isn_bits &= subpriv->valid_isns; /* Enable interrupt sources. */ subpriv->enabled_isns = isn_bits; - if (subpriv->has_int_sce) - outb(isn_bits, subpriv->iobase); + if (layout->has_int_sce) + outb(isn_bits, dev->iobase + subpriv->ofs); } return retval; @@ -599,6 +601,7 @@ dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_intr *subpriv = s->private; unsigned triggered; unsigned intstat; @@ -610,7 +613,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev, spin_lock_irqsave(&subpriv->spinlock, flags); oldevents = s->async->events; - if (subpriv->has_int_sce) { + if (layout->has_int_sce) { /* * Collect interrupt sources that have triggered and disable * them temporarily. Loop around until no extra interrupt @@ -622,11 +625,11 @@ static int dio200_handle_read_intr(struct comedi_device *dev, * loop in case of misconfiguration. */ cur_enabled = subpriv->enabled_isns; - while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns - & ~triggered)) != 0) { + while ((intstat = (inb(dev->iobase + subpriv->ofs) & + subpriv->valid_isns & ~triggered)) != 0) { triggered |= intstat; cur_enabled &= ~triggered; - outb(cur_enabled, subpriv->iobase); + outb(cur_enabled, dev->iobase + subpriv->ofs); } } else { /* @@ -644,8 +647,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev, * Reenable them NOW to minimize the time they are disabled. */ cur_enabled = subpriv->enabled_isns; - if (subpriv->has_int_sce) - outb(cur_enabled, subpriv->iobase); + if (layout->has_int_sce) + outb(cur_enabled, dev->iobase + subpriv->ofs); if (subpriv->active) { /* @@ -851,9 +854,9 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev, */ static int dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned long iobase, unsigned valid_isns, - int has_int_sce) + unsigned int offset, unsigned valid_isns) { + const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_intr *subpriv; subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL); @@ -861,18 +864,18 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, dev_err(dev->class_dev, "error! out of memory!\n"); return -ENOMEM; } - subpriv->iobase = iobase; - subpriv->has_int_sce = has_int_sce; + subpriv->ofs = offset; subpriv->valid_isns = valid_isns; spin_lock_init(&subpriv->spinlock); - if (has_int_sce) - outb(0, subpriv->iobase); /* Disable interrupt sources. */ + if (layout->has_int_sce) + /* Disable interrupt sources. */ + outb(0, dev->iobase + subpriv->ofs); s->private = subpriv; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_CMD_READ; - if (has_int_sce) { + if (layout->has_int_sce) { s->n_chan = DIO200_MAX_ISNS; s->len_chanlist = DIO200_MAX_ISNS; } else { @@ -936,7 +939,7 @@ dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long flags; spin_lock_irqsave(&subpriv->spinlock, flags); - data[0] = i8254_read(subpriv->iobase, 0, chan); + data[0] = i8254_read(dev->iobase + subpriv->ofs, 0, chan); spin_unlock_irqrestore(&subpriv->spinlock, flags); return 1; @@ -954,7 +957,7 @@ dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long flags; spin_lock_irqsave(&subpriv->spinlock, flags); - i8254_write(subpriv->iobase, 0, chan, data[0]); + i8254_write(dev->iobase + subpriv->ofs, 0, chan, data[0]); spin_unlock_irqrestore(&subpriv->spinlock, flags); return 1; @@ -982,7 +985,7 @@ dio200_subdev_8254_set_gate_src(struct comedi_device *dev, subpriv->gate_src[counter_number] = gate_src; byte = GAT_SCE(subpriv->which, counter_number, gate_src); - outb(byte, subpriv->gat_sce_iobase); + outb(byte, dev->iobase + subpriv->gat_sce_ofs); return 0; } @@ -1028,7 +1031,7 @@ dio200_subdev_8254_set_clock_src(struct comedi_device *dev, subpriv->clock_src[counter_number] = clock_src; byte = CLK_SCE(subpriv->which, counter_number, clock_src); - outb(byte, subpriv->clk_sce_iobase); + outb(byte, dev->iobase + subpriv->clk_sce_ofs); return 0; } @@ -1071,12 +1074,13 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s, spin_lock_irqsave(&subpriv->spinlock, flags); switch (data[0]) { case INSN_CONFIG_SET_COUNTER_MODE: - ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]); + ret = i8254_set_mode(dev->iobase + subpriv->ofs, 0, chan, + data[1]); if (ret < 0) ret = -EINVAL; break; case INSN_CONFIG_8254_READ_STATUS: - data[1] = i8254_status(subpriv->iobase, 0, chan); + data[1] = i8254_status(dev->iobase + subpriv->ofs, 0, chan); break; case INSN_CONFIG_SET_GATE_SRC: ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]); @@ -1114,13 +1118,10 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s, /* * This function initializes an '8254' counter subdevice. - * - * Note: iobase is the base address of the board, not the subdevice; - * offset is the offset to the 8254 chip. */ static int dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned long iobase, unsigned offset) + unsigned int offset) { const struct dio200_layout *layout = dio200_dev_layout(dev); struct dio200_subdev_8254 *subpriv; @@ -1142,20 +1143,18 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, s->insn_config = dio200_subdev_8254_config; spin_lock_init(&subpriv->spinlock); - subpriv->iobase = offset + iobase; + subpriv->ofs = offset; if (layout->has_clk_gat_sce) { /* Derive CLK_SCE and GAT_SCE register offsets from * 8254 offset. */ - subpriv->clk_sce_iobase = - DIO200_XCLK_SCE + (offset >> 3) + iobase; - subpriv->gat_sce_iobase = - DIO200_XGAT_SCE + (offset >> 3) + iobase; + subpriv->clk_sce_ofs = DIO200_XCLK_SCE + (offset >> 3); + subpriv->gat_sce_ofs = DIO200_XGAT_SCE + (offset >> 3); subpriv->which = (offset >> 2) & 1; } /* Initialize channels. */ for (chan = 0; chan < 3; chan++) { - i8254_set_mode(subpriv->iobase, 0, chan, + i8254_set_mode(dev->iobase + subpriv->ofs, 0, chan, I8254_MODE0 | I8254_BINARY); if (layout->has_clk_gat_sce) { /* Gate source 0 is VCC (logic 1). */ @@ -1228,7 +1227,7 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, switch (layout->sdtype[n]) { case sd_8254: /* counter subdevice (8254) */ - ret = dio200_subdev_8254_init(dev, s, iobase, + ret = dio200_subdev_8254_init(dev, s, layout->sdinfo[n]); if (ret < 0) return ret; @@ -1244,11 +1243,9 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, /* 'INTERRUPT' subdevice */ if (irq) { ret = dio200_subdev_intr_init(dev, s, - iobase + DIO200_INT_SCE, - layout->sdinfo[n], - layout-> - has_int_sce); + layout->sdinfo[n] + ); if (ret < 0) return ret; devpriv->intr_sd = n; -- cgit v1.2.3 From 155857cd5488d6287724ad560f063e568a077940 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:56 +0100 Subject: staging: comedi: amplc_dio200: add functions to access 8254 counters Add our own functions to manipulate the '8254' counter chip instead of the inline ones from "8253.h". This will make the code less messy when we add code to support new boards later. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 83 ++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 16ae7a395d5..d874bdfed6a 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -927,6 +927,73 @@ static irqreturn_t dio200_interrupt(int irq, void *d) return IRQ_RETVAL(handled); } +/* + * Read an '8254' counter subdevice channel. + */ +static unsigned int +dio200_subdev_8254_read_chan(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int chan) +{ + struct dio200_subdev_8254 *subpriv = s->private; + unsigned int val; + + /* latch counter */ + val = chan << 6; + outb(val, dev->iobase + subpriv->ofs + i8254_control_reg); + /* read lsb, msb */ + val = inb(dev->iobase + subpriv->ofs + chan); + val += inb(dev->iobase + subpriv->ofs + chan) << 8; + return val; +} + +/* + * Write an '8254' subdevice channel. + */ +static void +dio200_subdev_8254_write_chan(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int chan, + unsigned int count) +{ + struct dio200_subdev_8254 *subpriv = s->private; + + /* write lsb, msb */ + outb(count & 0xff, dev->iobase + subpriv->ofs + chan); + outb((count >> 8) & 0xff, dev->iobase + subpriv->ofs + chan); +} + +/* + * Set mode of an '8254' subdevice channel. + */ +static void +dio200_subdev_8254_set_mode(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int chan, + unsigned int mode) +{ + struct dio200_subdev_8254 *subpriv = s->private; + unsigned int byte; + + byte = chan << 6; + byte |= 0x30; /* access order: lsb, msb */ + byte |= (mode & 0xf); /* counter mode and BCD|binary */ + outb(byte, dev->iobase + subpriv->ofs + i8254_control_reg); +} + +/* + * Read status byte of an '8254' counter subdevice channel. + */ +static unsigned int +dio200_subdev_8254_status(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int chan) +{ + struct dio200_subdev_8254 *subpriv = s->private; + + /* latch status */ + outb(0xe0 | (2 << chan), + dev->iobase + subpriv->ofs + i8254_control_reg); + /* read status */ + return inb(dev->iobase + subpriv->ofs + chan); +} + /* * Handle 'insn_read' for an '8254' counter subdevice. */ @@ -939,7 +1006,7 @@ dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long flags; spin_lock_irqsave(&subpriv->spinlock, flags); - data[0] = i8254_read(dev->iobase + subpriv->ofs, 0, chan); + data[0] = dio200_subdev_8254_read_chan(dev, s, chan); spin_unlock_irqrestore(&subpriv->spinlock, flags); return 1; @@ -957,7 +1024,7 @@ dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long flags; spin_lock_irqsave(&subpriv->spinlock, flags); - i8254_write(dev->iobase + subpriv->ofs, 0, chan, data[0]); + dio200_subdev_8254_write_chan(dev, s, chan, data[0]); spin_unlock_irqrestore(&subpriv->spinlock, flags); return 1; @@ -1074,13 +1141,13 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s, spin_lock_irqsave(&subpriv->spinlock, flags); switch (data[0]) { case INSN_CONFIG_SET_COUNTER_MODE: - ret = i8254_set_mode(dev->iobase + subpriv->ofs, 0, chan, - data[1]); - if (ret < 0) + if (data[1] > (I8254_MODE5 | I8254_BINARY)) ret = -EINVAL; + else + dio200_subdev_8254_set_mode(dev, s, chan, data[1]); break; case INSN_CONFIG_8254_READ_STATUS: - data[1] = i8254_status(dev->iobase + subpriv->ofs, 0, chan); + data[1] = dio200_subdev_8254_status(dev, s, chan); break; case INSN_CONFIG_SET_GATE_SRC: ret = dio200_subdev_8254_set_gate_src(dev, s, chan, data[2]); @@ -1154,8 +1221,8 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, /* Initialize channels. */ for (chan = 0; chan < 3; chan++) { - i8254_set_mode(dev->iobase + subpriv->ofs, 0, chan, - I8254_MODE0 | I8254_BINARY); + dio200_subdev_8254_set_mode(dev, s, chan, + I8254_MODE0 | I8254_BINARY); if (layout->has_clk_gat_sce) { /* Gate source 0 is VCC (logic 1). */ dio200_subdev_8254_set_gate_src(dev, s, chan, 0); -- cgit v1.2.3 From 57054dcaec4848d5f6ce2fddaebfd0fc110e0c53 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:57 +0100 Subject: staging: comedi: amplc_dio200: internalize 8255 DIO implementation Implement the '8255' DIO subdevice internally to this module instead of using the external "8255" module. I plan to add support for additional cards to this driver that would require the I/O callback functionality of the 8255 module, but the existing callback functions do not have much context to handle this elegantly. The additional cards also have extra DIO features which cannot be handled by the existing "8255" module and that I'd like to support some time in the future. The bottom line is I _could_ continue using the "8255" module for a while with a callback function, but it would turn out to be a very ugly callback function and I'd have to ditch the use of the "8255" module as soon as I added an extra feature to the DIO subdevice. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 147 +++++++++++++++++++++++++- 1 file changed, 143 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index d874bdfed6a..0c824a99bed 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -207,7 +207,6 @@ #include "../comedidev.h" #include "comedi_fc.h" -#include "8255.h" #include "8253.h" #define DIO200_DRIVER_NAME "amplc_dio200" @@ -221,6 +220,15 @@ #define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b #define PCI_DEVICE_ID_INVALID 0xffff +/* 8255 control register bits */ +#define CR_C_LO_IO 0x01 +#define CR_B_IO 0x02 +#define CR_B_MODE 0x04 +#define CR_C_HI_IO 0x08 +#define CR_A_IO 0x10 +#define CR_A_MODE(a) ((a)<<5) +#define CR_CW 0x80 + /* 200 series registers */ #define DIO200_IO_SIZE 0x20 #define DIO200_XCLK_SCE 0x18 /* Group X clock selection register */ @@ -430,6 +438,10 @@ struct dio200_subdev_8254 { spinlock_t spinlock; }; +struct dio200_subdev_8255 { + unsigned int ofs; /* DIO base offset */ +}; + struct dio200_subdev_intr { unsigned int ofs; spinlock_t spinlock; @@ -1245,6 +1257,133 @@ dio200_subdev_8254_cleanup(struct comedi_device *dev, kfree(subpriv); } +/* + * This function sets I/O directions for an '8255' DIO subdevice. + */ +static void dio200_subdev_8255_set_dir(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct dio200_subdev_8255 *subpriv = s->private; + int config; + + config = CR_CW; + /* 1 in io_bits indicates output, 1 in config indicates input */ + if (!(s->io_bits & 0x0000ff)) + config |= CR_A_IO; + if (!(s->io_bits & 0x00ff00)) + config |= CR_B_IO; + if (!(s->io_bits & 0x0f0000)) + config |= CR_C_LO_IO; + if (!(s->io_bits & 0xf00000)) + config |= CR_C_HI_IO; + outb(config, dev->iobase + subpriv->ofs + 3); +} + +/* + * Handle 'insn_bits' for an '8255' DIO subdevice. + */ +static int dio200_subdev_8255_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct dio200_subdev_8255 *subpriv = s->private; + + if (data[0]) { + s->state &= ~data[0]; + s->state |= (data[0] & data[1]); + if (data[0] & 0xff) + outb(s->state & 0xff, dev->iobase + subpriv->ofs); + if (data[0] & 0xff00) + outb((s->state >> 8) & 0xff, + dev->iobase + subpriv->ofs + 1); + if (data[0] & 0xff0000) + outb((s->state >> 16) & 0xff, + dev->iobase + subpriv->ofs + 2); + } + data[1] = inb(dev->iobase + subpriv->ofs); + data[1] |= inb(dev->iobase + subpriv->ofs + 1) << 8; + data[1] |= inb(dev->iobase + subpriv->ofs + 2) << 16; + return 2; +} + +/* + * Handle 'insn_config' for an '8255' DIO subdevice. + */ +static int dio200_subdev_8255_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int mask; + unsigned int bits; + + mask = 1 << CR_CHAN(insn->chanspec); + if (mask & 0x0000ff) + bits = 0x0000ff; + else if (mask & 0x00ff00) + bits = 0x00ff00; + else if (mask & 0x0f0000) + bits = 0x0f0000; + else + bits = 0xf00000; + switch (data[0]) { + case INSN_CONFIG_DIO_INPUT: + s->io_bits &= ~bits; + break; + case INSN_CONFIG_DIO_OUTPUT: + s->io_bits |= bits; + break; + case INSN_CONFIG_DIO_QUERY: + data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT; + return insn->n; + break; + default: + return -EINVAL; + } + dio200_subdev_8255_set_dir(dev, s); + return 1; +} + +/* + * This function initializes an '8255' DIO subdevice. + * + * offset is the offset to the 8255 chip. + */ +static int dio200_subdev_8255_init(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int offset) +{ + struct dio200_subdev_8255 *subpriv; + + subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL); + if (!subpriv) + return -ENOMEM; + subpriv->ofs = offset; + s->private = subpriv; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 24; + s->range_table = &range_digital; + s->maxdata = 1; + s->insn_bits = dio200_subdev_8255_bits; + s->insn_config = dio200_subdev_8255_config; + s->state = 0; + s->io_bits = 0; + dio200_subdev_8255_set_dir(dev, s); + return 0; +} + +/* + * This function cleans up an '8255' DIO subdevice. + */ +static void dio200_subdev_8255_cleanup(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct dio200_subdev_8255 *subpriv = s->private; + + kfree(subpriv); +} + static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) { const struct dio200_board *thisboard = comedi_board(dev); @@ -1301,8 +1440,8 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, break; case sd_8255: /* digital i/o subdevice (8255) */ - ret = subdev_8255_init(dev, s, NULL, - iobase + layout->sdinfo[n]); + ret = dio200_subdev_8255_init(dev, s, + layout->sdinfo[n]); if (ret < 0) return ret; break; @@ -1438,7 +1577,7 @@ static void dio200_detach(struct comedi_device *dev) dio200_subdev_8254_cleanup(dev, s); break; case sd_8255: - subdev_8255_cleanup(dev, s); + dio200_subdev_8255_cleanup(dev, s); break; case sd_intr: dio200_subdev_intr_cleanup(dev, s); -- cgit v1.2.3 From 2662a9b62668ed541014fa078d88fbe99fce2b1e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:58 +0100 Subject: staging: comedi: amplc_dio200: don't select COMEDI_8255 The "amplc_dio200" module no longer depends on the "8255" module, so the 'COMEDI_AMPLC_DIO200' Kconfig setting no longer needs to select 'COMEDI_8255'. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 2093403af25..966730731c7 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1263,7 +1263,6 @@ config COMEDI_FC config COMEDI_AMPLC_DIO200 tristate - select COMEDI_8255 config COMEDI_AMPLC_PC236 tristate -- cgit v1.2.3 From c10aa035512f9c5092d7044676d3f3d14739f8d8 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:47:59 +0100 Subject: staging: comedi: amplc_dio200: use custom register access functions Add custom functions to access hardware registers and call them instead of calling `inb()` and `outb()` directly. When additional cards are supported by this driver requiring different register access methods, the new functions will localize the register access differences to just these functions. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 72 +++++++++++++++++---------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 0c824a99bed..4fe2b2b754c 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -474,6 +474,24 @@ static inline bool is_isa_board(const struct dio200_board *board) return DO_ISA && board->bustype == isa_bustype; } +/* + * Read 8-bit register. + */ +static unsigned char dio200_read8(struct comedi_device *dev, + unsigned int offset) +{ + return inb(dev->iobase + offset); +} + +/* + * Write 8-bit register. + */ +static void dio200_write8(struct comedi_device *dev, unsigned int offset, + unsigned char val) +{ + outb(val, dev->iobase + offset); +} + /* * This function looks for a board matching the supplied PCI device. */ @@ -518,7 +536,7 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev, if (layout->has_int_sce) { /* Just read the interrupt status register. */ - data[1] = inb(dev->iobase + subpriv->ofs) & subpriv->valid_isns; + data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns; } else { /* No interrupt status register. */ data[0] = 0; @@ -539,7 +557,7 @@ static void dio200_stop_intr(struct comedi_device *dev, subpriv->active = 0; subpriv->enabled_isns = 0; if (layout->has_int_sce) - outb(0, dev->iobase + subpriv->ofs); + dio200_write8(dev, subpriv->ofs, 0); } /* @@ -571,7 +589,7 @@ static int dio200_start_intr(struct comedi_device *dev, /* Enable interrupt sources. */ subpriv->enabled_isns = isn_bits; if (layout->has_int_sce) - outb(isn_bits, dev->iobase + subpriv->ofs); + dio200_write8(dev, subpriv->ofs, isn_bits); } return retval; @@ -637,11 +655,11 @@ static int dio200_handle_read_intr(struct comedi_device *dev, * loop in case of misconfiguration. */ cur_enabled = subpriv->enabled_isns; - while ((intstat = (inb(dev->iobase + subpriv->ofs) & + while ((intstat = (dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns & ~triggered)) != 0) { triggered |= intstat; cur_enabled &= ~triggered; - outb(cur_enabled, dev->iobase + subpriv->ofs); + dio200_write8(dev, subpriv->ofs, cur_enabled); } } else { /* @@ -660,7 +678,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev, */ cur_enabled = subpriv->enabled_isns; if (layout->has_int_sce) - outb(cur_enabled, dev->iobase + subpriv->ofs); + dio200_write8(dev, subpriv->ofs, cur_enabled); if (subpriv->active) { /* @@ -882,7 +900,7 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, if (layout->has_int_sce) /* Disable interrupt sources. */ - outb(0, dev->iobase + subpriv->ofs); + dio200_write8(dev, subpriv->ofs, 0); s->private = subpriv; s->type = COMEDI_SUBD_DI; @@ -951,10 +969,10 @@ dio200_subdev_8254_read_chan(struct comedi_device *dev, /* latch counter */ val = chan << 6; - outb(val, dev->iobase + subpriv->ofs + i8254_control_reg); + dio200_write8(dev, subpriv->ofs + i8254_control_reg, val); /* read lsb, msb */ - val = inb(dev->iobase + subpriv->ofs + chan); - val += inb(dev->iobase + subpriv->ofs + chan) << 8; + val = dio200_read8(dev, subpriv->ofs + chan); + val += dio200_read8(dev, subpriv->ofs + chan) << 8; return val; } @@ -969,8 +987,8 @@ dio200_subdev_8254_write_chan(struct comedi_device *dev, struct dio200_subdev_8254 *subpriv = s->private; /* write lsb, msb */ - outb(count & 0xff, dev->iobase + subpriv->ofs + chan); - outb((count >> 8) & 0xff, dev->iobase + subpriv->ofs + chan); + dio200_write8(dev, subpriv->ofs + chan, count & 0xff); + dio200_write8(dev, subpriv->ofs + chan, (count >> 8) & 0xff); } /* @@ -987,7 +1005,7 @@ dio200_subdev_8254_set_mode(struct comedi_device *dev, byte = chan << 6; byte |= 0x30; /* access order: lsb, msb */ byte |= (mode & 0xf); /* counter mode and BCD|binary */ - outb(byte, dev->iobase + subpriv->ofs + i8254_control_reg); + dio200_write8(dev, subpriv->ofs + i8254_control_reg, byte); } /* @@ -1000,10 +1018,10 @@ dio200_subdev_8254_status(struct comedi_device *dev, struct dio200_subdev_8254 *subpriv = s->private; /* latch status */ - outb(0xe0 | (2 << chan), - dev->iobase + subpriv->ofs + i8254_control_reg); + dio200_write8(dev, subpriv->ofs + i8254_control_reg, + 0xe0 | (2 << chan)); /* read status */ - return inb(dev->iobase + subpriv->ofs + chan); + return dio200_read8(dev, subpriv->ofs + chan); } /* @@ -1064,7 +1082,7 @@ dio200_subdev_8254_set_gate_src(struct comedi_device *dev, subpriv->gate_src[counter_number] = gate_src; byte = GAT_SCE(subpriv->which, counter_number, gate_src); - outb(byte, dev->iobase + subpriv->gat_sce_ofs); + dio200_write8(dev, subpriv->gat_sce_ofs, byte); return 0; } @@ -1110,7 +1128,7 @@ dio200_subdev_8254_set_clock_src(struct comedi_device *dev, subpriv->clock_src[counter_number] = clock_src; byte = CLK_SCE(subpriv->which, counter_number, clock_src); - outb(byte, dev->iobase + subpriv->clk_sce_ofs); + dio200_write8(dev, subpriv->clk_sce_ofs, byte); return 0; } @@ -1276,7 +1294,7 @@ static void dio200_subdev_8255_set_dir(struct comedi_device *dev, config |= CR_C_LO_IO; if (!(s->io_bits & 0xf00000)) config |= CR_C_HI_IO; - outb(config, dev->iobase + subpriv->ofs + 3); + dio200_write8(dev, subpriv->ofs + 3, config); } /* @@ -1292,17 +1310,17 @@ static int dio200_subdev_8255_bits(struct comedi_device *dev, s->state &= ~data[0]; s->state |= (data[0] & data[1]); if (data[0] & 0xff) - outb(s->state & 0xff, dev->iobase + subpriv->ofs); + dio200_write8(dev, subpriv->ofs, s->state & 0xff); if (data[0] & 0xff00) - outb((s->state >> 8) & 0xff, - dev->iobase + subpriv->ofs + 1); + dio200_write8(dev, subpriv->ofs + 1, + (s->state >> 8) & 0xff); if (data[0] & 0xff0000) - outb((s->state >> 16) & 0xff, - dev->iobase + subpriv->ofs + 2); + dio200_write8(dev, subpriv->ofs + 2, + (s->state >> 16) & 0xff); } - data[1] = inb(dev->iobase + subpriv->ofs); - data[1] |= inb(dev->iobase + subpriv->ofs + 1) << 8; - data[1] |= inb(dev->iobase + subpriv->ofs + 2) << 16; + data[1] = dio200_read8(dev, subpriv->ofs); + data[1] |= dio200_read8(dev, subpriv->ofs + 1) << 8; + data[1] |= dio200_read8(dev, subpriv->ofs + 2) << 16; return 2; } -- cgit v1.2.3 From 9bfa0d548c0ca427cba4a1c26658f870cfda64ca Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:00 +0100 Subject: staging: comedi: amplc_dio200: set dev->iobase before common attach Don't pass the I/O base address to `dio200_common_attach()`. The only thing it does with it is set `dev->iobase` to the passed in value. Do that before calling `dio200_common_attach()` in order to simplify upcoming support for different register access methods. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 4fe2b2b754c..1b734dc51b3 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1427,8 +1427,8 @@ static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) dev_info(dev->class_dev, "%s %sattached\n", dev->board_name, tmpbuf); } -static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, - unsigned int irq, unsigned long req_irq_flags) +static int dio200_common_attach(struct comedi_device *dev, unsigned int irq, + unsigned long req_irq_flags) { const struct dio200_board *thisboard = comedi_board(dev); struct dio200_private *devpriv = dev->private; @@ -1439,7 +1439,6 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned long iobase, int ret; devpriv->intr_sd = -1; - dev->iobase = iobase; dev->board_name = thisboard->name; ret = comedi_alloc_subdevices(dev, layout->n_subdevs); @@ -1527,7 +1526,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = dio200_request_region(dev, iobase, DIO200_IO_SIZE); if (ret < 0) return ret; - return dio200_common_attach(dev, iobase, irq, 0); + dev->iobase = iobase; + return dio200_common_attach(dev, irq, 0); } else if (is_pci_board(thisboard)) { dev_err(dev->class_dev, "Manual configuration of PCI board '%s' is not supported\n", @@ -1549,7 +1549,6 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { struct dio200_private *devpriv; - unsigned long iobase; int ret; if (!DO_PCI) @@ -1574,8 +1573,8 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, "error! cannot enable PCI device and request regions!\n"); return ret; } - iobase = pci_resource_start(pci_dev, 2); - return dio200_common_attach(dev, iobase, pci_dev->irq, IRQF_SHARED); + dev->iobase = pci_resource_start(pci_dev, 2); + return dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED); } static void dio200_detach(struct comedi_device *dev) -- cgit v1.2.3 From 71b3e9e8dc218133417d3c167632a61f9fed3651 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:01 +0100 Subject: staging: comedi: amplc_dio200: support memory-mapped I/O The boards currently supported by this module all use port I/O. Support memory-mapped I/O as well for future PCI/PCIe cards. Define `struct dio200_region` to hold the type of register access and either the port I/O base address or an ioremapped MMIO address. Add a member `io` to the comedi device private data (`struct dio200_private`) to hold this. Use this instead of `dev->iobase`. Memory-mapped registers are mapped in `dio200_pci_attach()` and unmapped in `dio200_detach()`. `dio200_detach()` now uses the private data pointer `devpriv` set to `dev->private` but can return early if it is `NULL` because no clean-up needs to be done in that case. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 61 +++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 1b734dc51b3..39fb82b4eca 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -264,6 +264,18 @@ static const unsigned clock_period[8] = { 0 /* group clock input pin */ }; +/* + * Register region. + */ +enum dio200_regtype { no_regtype = 0, io_regtype, mmio_regtype }; +struct dio200_region { + union { + unsigned long iobase; /* I/O base address */ + unsigned char __iomem *membase; /* mapped MMIO base address */ + } u; + enum dio200_regtype regtype; +}; + /* * Board descriptions. */ @@ -425,6 +437,7 @@ static const struct dio200_layout dio200_layouts[] = { feel free to suggest moving the variable to the struct comedi_device struct. */ struct dio200_private { + struct dio200_region io; /* Register region */ int intr_sd; }; @@ -480,7 +493,12 @@ static inline bool is_isa_board(const struct dio200_board *board) static unsigned char dio200_read8(struct comedi_device *dev, unsigned int offset) { - return inb(dev->iobase + offset); + struct dio200_private *devpriv = dev->private; + + if (devpriv->io.regtype == io_regtype) + return inb(devpriv->io.u.iobase + offset); + else + return readb(devpriv->io.u.membase + offset); } /* @@ -489,7 +507,12 @@ static unsigned char dio200_read8(struct comedi_device *dev, static void dio200_write8(struct comedi_device *dev, unsigned int offset, unsigned char val) { - outb(val, dev->iobase + offset); + struct dio200_private *devpriv = dev->private; + + if (devpriv->io.regtype == io_regtype) + outb(val, devpriv->io.u.iobase + offset); + else + writeb(val, devpriv->io.u.membase + offset); } /* @@ -1405,13 +1428,14 @@ static void dio200_subdev_8255_cleanup(struct comedi_device *dev, static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) { const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv = dev->private; struct pci_dev *pcidev = comedi_to_pci_dev(dev); char tmpbuf[60]; int tmplen; if (is_isa_board(thisboard)) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), - "(base %#lx) ", dev->iobase); + "(base %#lx) ", devpriv->io.u.iobase); else if (is_pci_board(thisboard)) tmplen = scnprintf(tmpbuf, sizeof(tmpbuf), "(pci %s) ", pci_name(pcidev)); @@ -1526,7 +1550,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = dio200_request_region(dev, iobase, DIO200_IO_SIZE); if (ret < 0) return ret; - dev->iobase = iobase; + devpriv->io.u.iobase = iobase; + devpriv->io.regtype = io_regtype; return dio200_common_attach(dev, irq, 0); } else if (is_pci_board(thisboard)) { dev_err(dev->class_dev, @@ -1549,6 +1574,7 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { struct dio200_private *devpriv; + resource_size_t base; int ret; if (!DO_PCI) @@ -1573,16 +1599,32 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, "error! cannot enable PCI device and request regions!\n"); return ret; } - dev->iobase = pci_resource_start(pci_dev, 2); + base = pci_resource_start(pci_dev, 2); + if ((pci_resource_flags(pci_dev, 2) & IORESOURCE_MEM) != 0) { + resource_size_t len = pci_resource_len(pci_dev, 2); + devpriv->io.u.membase = ioremap_nocache(base, len); + if (!devpriv->io.u.membase) { + dev_err(dev->class_dev, + "error! cannot remap registers\n"); + return -ENOMEM; + } + devpriv->io.regtype = mmio_regtype; + } else { + devpriv->io.u.iobase = (unsigned long)base; + devpriv->io.regtype = io_regtype; + } return dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED); } static void dio200_detach(struct comedi_device *dev) { const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv = dev->private; const struct dio200_layout *layout; unsigned n; + if (!thisboard || !devpriv) + return; if (dev->irq) free_irq(dev->irq, dev); if (dev->subdevices) { @@ -1605,13 +1647,16 @@ static void dio200_detach(struct comedi_device *dev) } } if (is_isa_board(thisboard)) { - if (dev->iobase) - release_region(dev->iobase, DIO200_IO_SIZE); + if (devpriv->io.regtype == io_regtype) + release_region(devpriv->io.u.iobase, DIO200_IO_SIZE); } else if (is_pci_board(thisboard)) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (pcidev) { - if (dev->iobase) + if (devpriv->io.regtype != no_regtype) { + if (devpriv->io.regtype == mmio_regtype) + iounmap(devpriv->io.u.membase); comedi_pci_disable(pcidev); + } } } } -- cgit v1.2.3 From ef0653ac20e739aba476ee63ca2a618a3a26857d Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:02 +0100 Subject: staging: comedi: amplc_dio200: add PCI BAR information to board Add `mainbar` member to `struct dio200_board` to hold the PCI BAR number for the main registers. This is `2` for the PCI boards currently supported (PCI215 and PCI272) but will be different for some new boards to be supported later. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 39fb82b4eca..2cbd2481aee 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -308,6 +308,7 @@ struct dio200_board { enum dio200_bustype bustype; enum dio200_model model; enum dio200_layout_idx layout; + unsigned char mainbar; }; static const struct dio200_board dio200_boards[] = { @@ -350,6 +351,7 @@ static const struct dio200_board dio200_boards[] = { .bustype = pci_bustype, .model = pci215_model, .layout = pc215_layout, + .mainbar = 2, }, { .name = "pci272", @@ -357,6 +359,7 @@ static const struct dio200_board dio200_boards[] = { .bustype = pci_bustype, .model = pci272_model, .layout = pc272_layout, + .mainbar = 2, }, #endif }; @@ -1573,8 +1576,10 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int __devinit dio200_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) { + const struct dio200_board *thisboard; struct dio200_private *devpriv; resource_size_t base; + unsigned int bar; int ret; if (!DO_PCI) @@ -1593,15 +1598,17 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); return -EINVAL; } + thisboard = comedi_board(dev); ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); if (ret < 0) { dev_err(dev->class_dev, "error! cannot enable PCI device and request regions!\n"); return ret; } - base = pci_resource_start(pci_dev, 2); - if ((pci_resource_flags(pci_dev, 2) & IORESOURCE_MEM) != 0) { - resource_size_t len = pci_resource_len(pci_dev, 2); + bar = thisboard->mainbar; + base = pci_resource_start(pci_dev, bar); + if ((pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) != 0) { + resource_size_t len = pci_resource_len(pci_dev, bar); devpriv->io.u.membase = ioremap_nocache(base, len); if (!devpriv->io.u.membase) { dev_err(dev->class_dev, -- cgit v1.2.3 From 805afd6bd62b2a6050cda8592fa2f9f72abe5a19 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:03 +0100 Subject: staging: comedi: amplc_dio200: add min register region size in board Store the length of the main register region in new member `mainsize` of `struct dio200_board` and initialize it in each element of `dio200_boards[]`. For all currently supported boards this is initialized to `DIO200_IO_SIZE` (0x20), but will be different for newer boards to be supported in the future. For ISA boards, this is the actual region length requested, but for PCI boards it's the minimum expected region length. Verify that the PCI BAR region length is sufficient in `dio200_attach_pci()`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 2cbd2481aee..ace218abae0 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -309,6 +309,7 @@ struct dio200_board { enum dio200_model model; enum dio200_layout_idx layout; unsigned char mainbar; + unsigned int mainsize; }; static const struct dio200_board dio200_boards[] = { @@ -318,30 +319,35 @@ static const struct dio200_board dio200_boards[] = { .bustype = isa_bustype, .model = pc212e_model, .layout = pc212_layout, + .mainsize = DIO200_IO_SIZE, }, { .name = "pc214e", .bustype = isa_bustype, .model = pc214e_model, .layout = pc214_layout, + .mainsize = DIO200_IO_SIZE, }, { .name = "pc215e", .bustype = isa_bustype, .model = pc215e_model, .layout = pc215_layout, + .mainsize = DIO200_IO_SIZE, }, { .name = "pc218e", .bustype = isa_bustype, .model = pc218e_model, .layout = pc218_layout, + .mainsize = DIO200_IO_SIZE, }, { .name = "pc272e", .bustype = isa_bustype, .model = pc272e_model, .layout = pc272_layout, + .mainsize = DIO200_IO_SIZE, }, #endif #if DO_PCI @@ -352,6 +358,7 @@ static const struct dio200_board dio200_boards[] = { .model = pci215_model, .layout = pc215_layout, .mainbar = 2, + .mainsize = DIO200_IO_SIZE, }, { .name = "pci272", @@ -360,6 +367,7 @@ static const struct dio200_board dio200_boards[] = { .model = pci272_model, .layout = pc272_layout, .mainbar = 2, + .mainsize = DIO200_IO_SIZE, }, #endif }; @@ -1550,7 +1558,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) iobase = it->options[0]; irq = it->options[1]; - ret = dio200_request_region(dev, iobase, DIO200_IO_SIZE); + ret = dio200_request_region(dev, iobase, thisboard->mainsize); if (ret < 0) return ret; devpriv->io.u.iobase = iobase; @@ -1578,7 +1586,7 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, { const struct dio200_board *thisboard; struct dio200_private *devpriv; - resource_size_t base; + resource_size_t base, len; unsigned int bar; int ret; @@ -1607,8 +1615,12 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, } bar = thisboard->mainbar; base = pci_resource_start(pci_dev, bar); + len = pci_resource_len(pci_dev, bar); + if (len < thisboard->mainsize) { + dev_err(dev->class_dev, "error! PCI region size too small!\n"); + return -EINVAL; + } if ((pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) != 0) { - resource_size_t len = pci_resource_len(pci_dev, bar); devpriv->io.u.membase = ioremap_nocache(base, len); if (!devpriv->io.u.membase) { dev_err(dev->class_dev, @@ -1655,7 +1667,8 @@ static void dio200_detach(struct comedi_device *dev) } if (is_isa_board(thisboard)) { if (devpriv->io.regtype == io_regtype) - release_region(devpriv->io.u.iobase, DIO200_IO_SIZE); + release_region(devpriv->io.u.iobase, + thisboard->mainsize); } else if (is_pci_board(thisboard)) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (pcidev) { -- cgit v1.2.3 From 34ed78e8f7f7895e21dc3215c05993aa16adddf3 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:04 +0100 Subject: staging: comedi: amplc_dio200: add register shift to board info Add `mainshift` member to `struct dio200_board` to hold the amount of left-shift required for main register offsets. This is 0 for all the boards currently supported so it doesn't need initializing explicitly in any current element of `dio200_boards[]`. It will be non-zero for some new boards to be supported by this driver. Modify the register access functions `dio200_read8()` and `dio200_write8()` to take the shift into account. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index ace218abae0..2e6ea759914 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -309,6 +309,7 @@ struct dio200_board { enum dio200_model model; enum dio200_layout_idx layout; unsigned char mainbar; + unsigned char mainshift; unsigned int mainsize; }; @@ -504,8 +505,10 @@ static inline bool is_isa_board(const struct dio200_board *board) static unsigned char dio200_read8(struct comedi_device *dev, unsigned int offset) { + const struct dio200_board *thisboard = comedi_board(dev); struct dio200_private *devpriv = dev->private; + offset <<= thisboard->mainshift; if (devpriv->io.regtype == io_regtype) return inb(devpriv->io.u.iobase + offset); else @@ -518,8 +521,10 @@ static unsigned char dio200_read8(struct comedi_device *dev, static void dio200_write8(struct comedi_device *dev, unsigned int offset, unsigned char val) { + const struct dio200_board *thisboard = comedi_board(dev); struct dio200_private *devpriv = dev->private; + offset <<= thisboard->mainshift; if (devpriv->io.regtype == io_regtype) outb(val, devpriv->io.u.iobase + offset); else -- cgit v1.2.3 From 2421a0242e17445ab35f7b450d0768518f0f63e6 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:05 +0100 Subject: staging: comedi: amplc_dio200: support PCIe215, PCIe236 and PCIe296 Add preliminary support for the above PCIe boards. The interrupt subdevice is not working yet as the boards need some additional initialization to enable interrupts. Reserve an unused subdevice that will eventually become a timer subdevice. Some unused subdevices have been added between the used subdevices on the PCIe215 and PCIe236. This is so the subdevice numbers will match a pattern-matching feature to be added at a later date, where the pattern-match specifications for a subdevice include pattern-match results from other subdevices, specified by index. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 178 ++++++++++++++++++++------ 1 file changed, 140 insertions(+), 38 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 2e6ea759914..a7a1be9ad72 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -29,39 +29,55 @@ * Description: Amplicon 200 Series Digital I/O * Author: Ian Abbott * Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e), - * PCI215 (pci215), PC218E (pc218e), PC272E (pc272e), PCI272 (pci272) - * Updated: Wed, 22 Oct 2008 13:36:02 +0100 + * PCI215 (pci215), PCIe215 (pcie215), PC218E (pc218e), PCIe236 (pcie236), + * PC272E (pc272e), PCI272 (pci272), PCIe296 (pcie296) + * Updated: Wed, 24 Oct 2012 16:22:34 +0100 * Status: works * * Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E: * [0] - I/O port base address * [1] - IRQ (optional, but commands won't work without it) * - * Manual configuration of PCI cards is not supported; they are configured + * Manual configuration of PCI(e) cards is not supported; they are configured * automatically. * * Passing a zero for an option is the same as leaving it unspecified. * * SUBDEVICES * - * PC218E PC212E PC215E/PCI215 + * PC212E PC214E PC215E/PCI215 * ------------- ------------- ------------- - * Subdevices 7 6 5 - * 0 CTR-X1 PPI-X PPI-X - * 1 CTR-X2 CTR-Y1 PPI-Y - * 2 CTR-Y1 CTR-Y2 CTR-Z1 - * 3 CTR-Y2 CTR-Z1 CTR-Z2 - * 4 CTR-Z1 CTR-Z2 INTERRUPT - * 5 CTR-Z2 INTERRUPT - * 6 INTERRUPT + * Subdevices 6 4 5 + * 0 PPI-X PPI-X PPI-X + * 1 CTR-Y1 PPI-Y PPI-Y + * 2 CTR-Y2 CTR-Z1* CTR-Z1 + * 3 CTR-Z1 INTERRUPT* CTR-Z2 + * 4 CTR-Z2 INTERRUPT + * 5 INTERRUPT * - * PC214E PC272E/PCI272 + * PCIe215 PC218E PCIe236 + * ------------- ------------- ------------- + * Subdevices 8 7 8 + * 0 PPI-X CTR-X1 PPI-X + * 1 UNUSED CTR-X2 UNUSED + * 2 PPI-Y CTR-Y1 UNUSED + * 3 UNUSED CTR-Y2 UNUSED + * 4 CTR-Z1 CTR-Z1 CTR-Z1 + * 5 CTR-Z2 CTR-Z2 CTR-Z2 + * 6 TIMER INTERRUPT TIMER + * 7 INTERRUPT INTERRUPT + * + * PC272E/PCI272 PCIe296 * ------------- ------------- - * Subdevices 4 4 - * 0 PPI-X PPI-X - * 1 PPI-Y PPI-Y - * 2 CTR-Z1* PPI-Z - * 3 INTERRUPT* INTERRUPT + * Subdevices 4 8 + * 0 PPI-X PPI-X1 + * 1 PPI-Y PPI-X2 + * 2 PPI-Z PPI-Y1 + * 3 INTERRUPT PPI-Y2 + * 4 CTR-Z1 + * 5 CTR-Z2 + * 6 TIMER + * 7 INTERRUPT * * Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels * are configurable as inputs or outputs in four groups: @@ -141,6 +157,8 @@ * 3. The counter subdevices are connected in a ring, so the highest * counter subdevice precedes the lowest. * + * The 'TIMER' subdevice is a free-running 32-bit timer subdevice. + * * The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The * digital inputs come from the interrupt status register. The number of * channels matches the number of interrupt sources. The PC214E does not @@ -149,25 +167,35 @@ * * INTERRUPT SOURCES * - * PC218E PC212E PC215E/PCI215 + * PC212E PC214E PC215E/PCI215 + * ------------- ------------- ------------- + * Sources 6 1 6 + * 0 PPI-X-C0 JUMPER-J5 PPI-X-C0 + * 1 PPI-X-C3 PPI-X-C3 + * 2 CTR-Y1-OUT1 PPI-Y-C0 + * 3 CTR-Y2-OUT1 PPI-Y-C3 + * 4 CTR-Z1-OUT1 CTR-Z1-OUT1 + * 5 CTR-Z2-OUT1 CTR-Z2-OUT1 + * + * PCIe215 PC218E PCIe236 * ------------- ------------- ------------- * Sources 6 6 6 - * 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0 - * 1 CTR-X2-OUT PPI-X-C3 PPI-X-C3 - * 2 CTR-Y1-OUT CTR-Y1-OUT PPI-Y-C0 - * 3 CTR-Y2-OUT CTR-Y2-OUT PPI-Y-C3 - * 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT - * 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT + * 0 PPI-X-C0 CTR-X1-OUT1 PPI-X-C0 + * 1 PPI-X-C3 CTR-X2-OUT1 PPI-X-C3 + * 2 PPI-Y-C0 CTR-Y1-OUT1 unused + * 3 PPI-Y-C3 CTR-Y2-OUT1 unused + * 4 CTR-Z1-OUT1 CTR-Z1-OUT1 CTR-Z1-OUT1 + * 5 CTR-Z2-OUT1 CTR-Z2-OUT1 CTR-Z2-OUT1 * - * PC214E PC272E/PCI272 + * PC272E/PCI272 PCIe296 * ------------- ------------- - * Sources 1 6 - * 0 JUMPER-J5 PPI-X-C0 - * 1 PPI-X-C3 - * 2 PPI-Y-C0 - * 3 PPI-Y-C3 - * 4 PPI-Z-C0 - * 5 PPI-Z-C3 + * Sources 6 6 + * 0 PPI-X-C0 PPI-X1-C0 + * 1 PPI-X-C3 PPI-X1-C3 + * 2 PPI-Y-C0 PPI-Y1-C0 + * 3 PPI-Y-C3 PPI-Y1-C3 + * 4 PPI-Z-C0 CTR-Z1-OUT1 + * 5 PPI-Z-C3 CTR-Z2-OUT1 * * When an interrupt source is enabled in the interrupt source enable * register, a rising edge on the source signal latches the corresponding @@ -218,7 +246,9 @@ #define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a #define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b -#define PCI_DEVICE_ID_INVALID 0xffff +#define PCI_DEVICE_ID_AMPLICON_PCIE236 0x0011 +#define PCI_DEVICE_ID_AMPLICON_PCIE215 0x0012 +#define PCI_DEVICE_ID_AMPLICON_PCIE296 0x0014 /* 8255 control register bits */ #define CR_C_LO_IO 0x01 @@ -231,6 +261,7 @@ /* 200 series registers */ #define DIO200_IO_SIZE 0x20 +#define DIO200_PCIE_IO_SIZE 0x4000 #define DIO200_XCLK_SCE 0x18 /* Group X clock selection register */ #define DIO200_YCLK_SCE 0x19 /* Group Y clock selection register */ #define DIO200_ZCLK_SCE 0x1a /* Group Z clock selection register */ @@ -285,9 +316,11 @@ enum dio200_bustype { isa_bustype, pci_bustype }; enum dio200_model { pc212e_model, pc214e_model, - pc215e_model, pci215_model, + pc215e_model, pci215_model, pcie215_model, pc218e_model, + pcie236_model, pc272e_model, pci272_model, + pcie296_model, }; enum dio200_layout_idx { @@ -299,7 +332,12 @@ enum dio200_layout_idx { #if DO_ISA pc218_layout, #endif - pc272_layout + pc272_layout, +#if DO_PCI + pcie215_layout, + pcie236_layout, + pcie296_layout, +#endif }; struct dio200_board { @@ -370,6 +408,36 @@ static const struct dio200_board dio200_boards[] = { .mainbar = 2, .mainsize = DIO200_IO_SIZE, }, + { + .name = "pcie215", + .devid = PCI_DEVICE_ID_AMPLICON_PCIE215, + .bustype = pci_bustype, + .model = pcie215_model, + .layout = pcie215_layout, + .mainbar = 1, + .mainshift = 3, + .mainsize = DIO200_PCIE_IO_SIZE, + }, + { + .name = "pcie236", + .devid = PCI_DEVICE_ID_AMPLICON_PCIE236, + .bustype = pci_bustype, + .model = pcie236_model, + .layout = pcie236_layout, + .mainbar = 1, + .mainshift = 3, + .mainsize = DIO200_PCIE_IO_SIZE, + }, + { + .name = "pcie296", + .devid = PCI_DEVICE_ID_AMPLICON_PCIE296, + .bustype = pci_bustype, + .model = pcie296_model, + .layout = pcie296_layout, + .mainbar = 1, + .mainshift = 3, + .mainsize = DIO200_PCIE_IO_SIZE, + }, #endif }; @@ -378,9 +446,9 @@ static const struct dio200_board dio200_boards[] = { * layout. */ -enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254 }; +enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer }; -#define DIO200_MAX_SUBDEVS 7 +#define DIO200_MAX_SUBDEVS 8 #define DIO200_MAX_ISNS 6 struct dio200_layout { @@ -442,6 +510,35 @@ static const struct dio200_layout dio200_layouts[] = { .has_int_sce = 1, .has_clk_gat_sce = 0, }, +#if DO_PCI + [pcie215_layout] = { + .n_subdevs = 8, + .sdtype = {sd_8255, sd_none, sd_8255, sd_none, + sd_8254, sd_8254, sd_timer, sd_intr}, + .sdinfo = {0x00, 0x00, 0x08, 0x00, + 0x10, 0x14, 0x00, 0x3F}, + .has_int_sce = 1, + .has_clk_gat_sce = 1, + }, + [pcie236_layout] = { + .n_subdevs = 8, + .sdtype = {sd_8255, sd_none, sd_none, sd_none, + sd_8254, sd_8254, sd_timer, sd_intr}, + .sdinfo = {0x00, 0x00, 0x00, 0x00, + 0x10, 0x14, 0x00, 0x3F}, + .has_int_sce = 1, + .has_clk_gat_sce = 1, + }, + [pcie296_layout] = { + .n_subdevs = 8, + .sdtype = {sd_8255, sd_8255, sd_8255, sd_8255, + sd_8254, sd_8254, sd_timer, sd_intr}, + .sdinfo = {0x00, 0x04, 0x08, 0x0C, + 0x10, 0x14, 0x00, 0x3F}, + .has_int_sce = 1, + .has_clk_gat_sce = 1, + }, +#endif }; /* this structure is for data unique to this hardware driver. If @@ -1516,6 +1613,8 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned int irq, s->type = COMEDI_SUBD_UNUSED; } break; + case sd_timer: + /* TODO. Fall-thru to default for now. */ default: s->type = COMEDI_SUBD_UNUSED; break; @@ -1707,6 +1806,9 @@ static struct comedi_driver amplc_dio200_driver = { static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) }, { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE236) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE215) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCIE296) }, {0} }; -- cgit v1.2.3 From c5f68d79259ee61b58197b0f751411e0196560f2 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:06 +0100 Subject: staging: comedi: amplc_dio200: allow generation of PCIe interrupts The new PCIe boards PCIe215, PCIe236 and PCIe296 need a special register setting to allow generation of interrupts on the PCIe bus. Add `dio200_pcie_board_setup()` to do this and call it from `dio200_attach_pci()` for those boards. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index a7a1be9ad72..cf53e84c3bc 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1538,6 +1538,42 @@ static void dio200_subdev_8255_cleanup(struct comedi_device *dev, kfree(subpriv); } +/* + * This function does some special set-up for the PCIe boards + * PCIe215, PCIe236, PCIe296. + */ +static int dio200_pcie_board_setup(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + void __iomem *brbase; + resource_size_t brlen; + + /* + * The board uses Altera Cyclone IV with PCI-Express hard IP. + * The FPGA configuration has the PCI-Express Avalon-MM Bridge + * Control registers in PCI BAR 0, offset 0, and the length of + * these registers is 0x4000. + * + * We need to write 0x80 to the "Avalon-MM to PCI-Express Interrupt + * Enable" register at offset 0x50 to allow generation of PCIe + * interrupts when RXmlrq_i is asserted in the SOPC Builder system. + */ + brlen = pci_resource_len(pcidev, 0); + if (brlen < 0x4000 || + !(pci_resource_flags(pcidev, 0) & IORESOURCE_MEM)) { + dev_err(dev->class_dev, "error! bad PCI region!\n"); + return -EINVAL; + } + brbase = ioremap_nocache(pci_resource_start(pcidev, 0), brlen); + if (!brbase) { + dev_err(dev->class_dev, "error! failed to map registers!\n"); + return -ENOMEM; + } + writel(0x80, brbase + 0x50); + iounmap(brbase); + return 0; +} + static void dio200_report_attach(struct comedi_device *dev, unsigned int irq) { const struct dio200_board *thisboard = comedi_board(dev); @@ -1736,6 +1772,18 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, devpriv->io.u.iobase = (unsigned long)base; devpriv->io.regtype = io_regtype; } + switch (thisboard->model) + { + case pcie215_model: + case pcie236_model: + case pcie296_model: + ret = dio200_pcie_board_setup(dev); + if (ret < 0) + return ret; + break; + default: + break; + } return dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED); } -- cgit v1.2.3 From 855d5fb469a7e9ac71358248e27d17422ad4c663 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:07 +0100 Subject: staging: comedi: amplc_dio200: enable enhanced features of PCIe boards The new PCIe boards PCIe215, PCIe236 and PCIe296 have some enhanced features (over the older boards), although none of these features are supported by this driver yet. Enable the enhanced features in hardware and use `dio200_layouts[]` to indicate which boards support the enhanced features. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index cf53e84c3bc..1fc6d63398e 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -269,6 +269,9 @@ #define DIO200_YGAT_SCE 0x1c /* Group Y gate selection register */ #define DIO200_ZGAT_SCE 0x1d /* Group Z gate selection register */ #define DIO200_INT_SCE 0x1e /* Interrupt enable/status register */ +/* Extra registers for new PCIe boards */ +#define DIO200_ENHANCE 0x20 /* 1 to enable enhanced features */ +#define DIO200_VERSION 0x24 /* Hardware version register */ /* * Macros for constructing value for DIO_200_?CLK_SCE and @@ -457,6 +460,7 @@ struct dio200_layout { unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */ char has_int_sce; /* has interrupt enable/status register */ char has_clk_gat_sce; /* has clock/gate selection registers */ + char has_enhancements; /* has enhanced features */ }; static const struct dio200_layout dio200_layouts[] = { @@ -519,6 +523,7 @@ static const struct dio200_layout dio200_layouts[] = { 0x10, 0x14, 0x00, 0x3F}, .has_int_sce = 1, .has_clk_gat_sce = 1, + .has_enhancements = 1, }, [pcie236_layout] = { .n_subdevs = 8, @@ -528,6 +533,7 @@ static const struct dio200_layout dio200_layouts[] = { 0x10, 0x14, 0x00, 0x3F}, .has_int_sce = 1, .has_clk_gat_sce = 1, + .has_enhancements = 1, }, [pcie296_layout] = { .n_subdevs = 8, @@ -537,6 +543,7 @@ static const struct dio200_layout dio200_layouts[] = { 0x10, 0x14, 0x00, 0x3F}, .has_int_sce = 1, .has_clk_gat_sce = 1, + .has_enhancements = 1, }, #endif }; @@ -1571,6 +1578,8 @@ static int dio200_pcie_board_setup(struct comedi_device *dev) } writel(0x80, brbase + 0x50); iounmap(brbase); + /* Enable "enhanced" features of board. */ + dio200_write8(dev, DIO200_ENHANCE, 1); return 0; } -- cgit v1.2.3 From b61ce8e2ff029e2b2cdf5ec2dc7118f3ab1e01cd Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:08 +0100 Subject: staging: comedi: amplc_dio200: allow extra clock and gate sources One of the enhancements of the new PCIe boards is the addition of extra clock and gate sources. Allow clock and gate sources up to 31 for these boards (compared to 7 for the old boards) although most of those are reserved for future use. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 78 +++++++++++++++++++++------ 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 1fc6d63398e..34bbf9bddcc 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -120,6 +120,14 @@ * the SK1 connector. This pin is shared by all three counter * channels on the chip. * + * For the PCIe boards, clock sources in the range 0 to 31 are allowed + * and the following additional clock sources are defined: + * + * 8. HIGH logic level. + * 9. LOW logic level. + * 10. "Pattern present" signal. + * 11. Internal 20 MHz clock. + * * INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current * clock source in data[1]. For internal clock sources, data[2] is set * to the period in ns. @@ -141,6 +149,27 @@ * 6. Reserved. * 7. Reserved. * + * For the PCIe boards, gate sources in the range 0 to 31 are allowed; + * the following additional clock sources and clock sources 6 and 7 are + * (re)defined: + * + * 6. /GAT n, negated version of the counter channel's dedicated + * GAT input (negated version of gate source 2). + * 7. OUT n-2, the non-inverted output of counter channel n-2 + * (negated version of gate source 3). + * 8. "Pattern present" signal, HIGH while pattern present. + * 9. "Pattern occurred" latched signal, latches HIGH when pattern + * occurs. + * 10. "Pattern gone away" latched signal, latches LOW when pattern + * goes away after it occurred. + * 11. Negated "pattern present" signal, LOW while pattern present + * (negated version of gate source 8). + * 12. Negated "pattern occurred" latched signal, latches LOW when + * pattern occurs (negated version of gate source 9). + * 13. Negated "pattern gone away" latched signal, latches LOW when + * pattern goes away after it occurred (negated version of gate + * source 10). + * * INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate * source in data[2]. * @@ -274,28 +303,43 @@ #define DIO200_VERSION 0x24 /* Hardware version register */ /* - * Macros for constructing value for DIO_200_?CLK_SCE and + * Functions for constructing value for DIO_200_?CLK_SCE and * DIO_200_?GAT_SCE registers: * * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2. * 'chan' is the channel: 0, 1 or 2. - * 'source' is the signal source: 0 to 7. + * 'source' is the signal source: 0 to 7, or 0 to 31 for "enhanced" boards. */ -#define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source)) -#define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source)) +static unsigned char clk_gat_sce(unsigned int which, unsigned int chan, + unsigned int source) +{ + return (which << 5) | (chan << 3) | + ((source & 030) << 3) | (source & 007); +} + +static unsigned char clk_sce(unsigned int which, unsigned int chan, + unsigned int source) +{ + return clk_gat_sce(which, chan, source); +} + +static unsigned char gat_sce(unsigned int which, unsigned int chan, + unsigned int source) +{ + return clk_gat_sce(which, chan, source); +} /* * Periods of the internal clock sources in nanoseconds. */ -static const unsigned clock_period[8] = { - 0, /* dedicated clock input/output pin */ - 100, /* 10 MHz */ - 1000, /* 1 MHz */ - 10000, /* 100 kHz */ - 100000, /* 10 kHz */ - 1000000, /* 1 kHz */ - 0, /* OUT N-1 */ - 0 /* group clock input pin */ +static const unsigned int clock_period[32] = { + [1] = 100, /* 10 MHz */ + [2] = 1000, /* 1 MHz */ + [3] = 10000, /* 100 kHz */ + [4] = 100000, /* 10 kHz */ + [5] = 1000000, /* 1 kHz */ + [11] = 50, /* 20 MHz (enhanced boards) */ + /* clock sources 12 and later reserved for enhanced boards */ }; /* @@ -1220,11 +1264,11 @@ dio200_subdev_8254_set_gate_src(struct comedi_device *dev, return -1; if (counter_number > 2) return -1; - if (gate_src > 7) + if (gate_src > (layout->has_enhancements ? 31 : 7)) return -1; subpriv->gate_src[counter_number] = gate_src; - byte = GAT_SCE(subpriv->which, counter_number, gate_src); + byte = gat_sce(subpriv->which, counter_number, gate_src); dio200_write8(dev, subpriv->gat_sce_ofs, byte); return 0; @@ -1266,11 +1310,11 @@ dio200_subdev_8254_set_clock_src(struct comedi_device *dev, return -1; if (counter_number > 2) return -1; - if (clock_src > 7) + if (clock_src > (layout->has_enhancements ? 31 : 7)) return -1; subpriv->clock_src[counter_number] = clock_src; - byte = CLK_SCE(subpriv->which, counter_number, clock_src); + byte = clk_sce(subpriv->which, counter_number, clock_src); dio200_write8(dev, subpriv->clk_sce_ofs, byte); return 0; -- cgit v1.2.3 From 025d1f675c401da7c1efa0e37d5eada1abebdc5a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:09 +0100 Subject: staging: comedi: comedi.h: extra clock and gate sources for amplc_dio200 Add constants to "comedi.h" for the extra clock and gate sources allowed by the new PCIe cards supported by the "amplc_dio200" driver. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 133f013e0f6..e0e822d56df 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -888,7 +888,12 @@ enum amplc_dio_clock_source { subdevice, preceding counter subdevice is the last counter subdevice) */ - AMPLC_DIO_CLK_EXT /* per chip external input pin */ + AMPLC_DIO_CLK_EXT, /* per chip external input pin */ + /* the following are "enhanced" clock sources for PCIe models */ + AMPLC_DIO_CLK_VCC, /* clock input HIGH */ + AMPLC_DIO_CLK_GND, /* clock input LOW */ + AMPLC_DIO_CLK_PAT_PRESENT, /* "pattern present" signal */ + AMPLC_DIO_CLK_20MHZ /* 20 MHz internal clock */ }; /* Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for @@ -907,7 +912,17 @@ enum amplc_dio_gate_source { AMPLC_DIO_GAT_RESERVED4, AMPLC_DIO_GAT_RESERVED5, AMPLC_DIO_GAT_RESERVED6, - AMPLC_DIO_GAT_RESERVED7 + AMPLC_DIO_GAT_RESERVED7, + /* the following are "enhanced" gate sources for PCIe models */ + AMPLC_DIO_GAT_NGATN = 6, /* negated per channel gate input */ + AMPLC_DIO_GAT_OUTNM2, /* non-negated output of counter + channel minus 2 */ + AMPLC_DIO_GAT_PAT_PRESENT, /* "pattern present" signal */ + AMPLC_DIO_GAT_PAT_OCCURRED, /* "pattern occurred" latched */ + AMPLC_DIO_GAT_PAT_GONE, /* "pattern gone away" latched */ + AMPLC_DIO_GAT_NPAT_PRESENT, /* negated "pattern present" */ + AMPLC_DIO_GAT_NPAT_OCCURRED, /* negated "pattern occurred" */ + AMPLC_DIO_GAT_NPAT_GONE /* negated "pattern gone away" */ }; #endif /* _COMEDI_H */ -- cgit v1.2.3 From 87276012ead9f96f249fedf715b1052106f2e0d0 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:10 +0100 Subject: staging: comedi: amplc_dio200: add 32-bit register access functions These are currently unused but will be used to support extra features of the PCIe boards. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 34bbf9bddcc..768a269d48f 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -679,6 +679,38 @@ static void dio200_write8(struct comedi_device *dev, unsigned int offset, writeb(val, devpriv->io.u.membase + offset); } +/* + * Read 32-bit register. + */ +static unsigned int dio200_read32(struct comedi_device *dev, + unsigned int offset) +{ + const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv = dev->private; + + offset <<= thisboard->mainshift; + if (devpriv->io.regtype == io_regtype) + return inl(devpriv->io.u.iobase + offset); + else + return readl(devpriv->io.u.membase + offset); +} + +/* + * Write 32-bit register. + */ +static void dio200_write32(struct comedi_device *dev, unsigned int offset, + unsigned int val) +{ + const struct dio200_board *thisboard = comedi_board(dev); + struct dio200_private *devpriv = dev->private; + + offset <<= thisboard->mainshift; + if (devpriv->io.regtype == io_regtype) + outl(val, devpriv->io.u.iobase + offset); + else + writel(val, devpriv->io.u.membase + offset); +} + /* * This function looks for a board matching the supplied PCI device. */ -- cgit v1.2.3 From 18cbf973a9a77e0b6128d4c187f337f4dc94df90 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:11 +0100 Subject: staging: comedi: amplc_dio200: implement timer subdevice Implement the timer subdevice for the new PCIe boards. The subdevice was previously marked as unused, but was reserved for this purpose. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 145 +++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 768a269d48f..d72a86b3e9f 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -301,6 +301,8 @@ /* Extra registers for new PCIe boards */ #define DIO200_ENHANCE 0x20 /* 1 to enable enhanced features */ #define DIO200_VERSION 0x24 /* Hardware version register */ +#define DIO200_TS_CONFIG 0x600 /* Timestamp timer config register */ +#define DIO200_TS_COUNT 0x602 /* Timestamp timer count register */ /* * Functions for constructing value for DIO_200_?CLK_SCE and @@ -342,6 +344,22 @@ static const unsigned int clock_period[32] = { /* clock sources 12 and later reserved for enhanced boards */ }; +/* + * Timestamp timer configuration register (for new PCIe boards). + */ +#define TS_CONFIG_RESET 0x100 /* Reset counter to zero. */ +#define TS_CONFIG_CLK_SRC_MASK 0x0FF /* Clock source. */ +#define TS_CONFIG_MAX_CLK_SRC 2 /* Maximum clock source value. */ + +/* + * Periods of the timestamp timer clock sources in nanoseconds. + */ +static const unsigned int ts_clock_period[TS_CONFIG_MAX_CLK_SRC + 1] = { + 1, /* 1 nanosecond (but with 20 ns granularity). */ + 1000, /* 1 microsecond. */ + 1000000, /* 1 millisecond. */ +}; + /* * Register region. */ @@ -1621,6 +1639,118 @@ static void dio200_subdev_8255_cleanup(struct comedi_device *dev, kfree(subpriv); } +/* + * Handle 'insn_read' for a timer subdevice. + */ +static int dio200_subdev_timer_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int n; + + for (n = 0; n < insn->n; n++) + data[n] = dio200_read32(dev, DIO200_TS_COUNT); + return n; +} + +/* + * Reset timer subdevice. + */ +static void dio200_subdev_timer_reset(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + unsigned int clock; + + clock = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK; + dio200_write32(dev, DIO200_TS_CONFIG, clock | TS_CONFIG_RESET); + dio200_write32(dev, DIO200_TS_CONFIG, clock); +} + +/* + * Get timer subdevice clock source and period. + */ +static void dio200_subdev_timer_get_clock_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int *src, + unsigned int *period) +{ + unsigned int clk; + + clk = dio200_read32(dev, DIO200_TS_CONFIG) & TS_CONFIG_CLK_SRC_MASK; + *src = clk; + *period = (clk < ARRAY_SIZE(ts_clock_period)) ? + ts_clock_period[clk] : 0; +} + +/* + * Set timer subdevice clock source. + */ +static int dio200_subdev_timer_set_clock_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int src) +{ + if (src > TS_CONFIG_MAX_CLK_SRC) + return -EINVAL; + dio200_write32(dev, DIO200_TS_CONFIG, src); + return 0; +} + +/* + * Handle 'insn_config' for a timer subdevice. + */ +static int dio200_subdev_timer_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + int ret = 0; + + switch (data[0]) { + case INSN_CONFIG_RESET: + dio200_subdev_timer_reset(dev, s); + break; + case INSN_CONFIG_SET_CLOCK_SRC: + ret = dio200_subdev_timer_set_clock_src(dev, s, data[1]); + if (ret < 0) + ret = -EINVAL; + break; + case INSN_CONFIG_GET_CLOCK_SRC: + dio200_subdev_timer_get_clock_src(dev, s, &data[1], &data[2]); + break; + default: + ret = -EINVAL; + break; + } + return ret < 0 ? ret : insn->n; +} + +/* + * This function initializes a timer subdevice. + * + * Uses the timestamp timer registers. There is only one timestamp timer. + */ +static int dio200_subdev_timer_init(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_READABLE | SDF_LSAMPL; + s->n_chan = 1; + s->maxdata = 0xFFFFFFFF; + s->insn_read = dio200_subdev_timer_read; + s->insn_config = dio200_subdev_timer_config; + return 0; +} + +/* + * This function cleans up a timer subdevice. + */ +static void dio200_subdev_timer_cleanup(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + /* Nothing to do. */ +} + /* * This function does some special set-up for the PCIe boards * PCIe215, PCIe236, PCIe296. @@ -1735,7 +1865,15 @@ static int dio200_common_attach(struct comedi_device *dev, unsigned int irq, } break; case sd_timer: - /* TODO. Fall-thru to default for now. */ + /* Only on PCIe boards. */ + if (DO_PCI) { + ret = dio200_subdev_timer_init(dev, s); + if (ret < 0) + return ret; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + break; default: s->type = COMEDI_SUBD_UNUSED; break; @@ -1897,6 +2035,11 @@ static void dio200_detach(struct comedi_device *dev) case sd_intr: dio200_subdev_intr_cleanup(dev, s); break; + case sd_timer: + /* Only on PCIe boards. */ + if (DO_PCI) + dio200_subdev_timer_cleanup(dev, s); + break; default: break; } -- cgit v1.2.3 From c59515a879d69fd8fc25c8d7eea6aa03ceb6983d Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:12 +0100 Subject: staging: comedi: comedi.h: add clock sources for amplc_dio200 timer Add clock source constants for the timer subdevice of the PCIe cards supported by the "amplc_dio200" driver. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index e0e822d56df..3cbd2cda1f7 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -896,6 +896,14 @@ enum amplc_dio_clock_source { AMPLC_DIO_CLK_20MHZ /* 20 MHz internal clock */ }; +/* Values for setting a clock source with INSN_CONFIG_SET_CLOCK_SRC for + * timer subdevice on some Amplicon DIO PCIe boards (amplc_dio200 driver). */ +enum amplc_dio_ts_clock_src { + AMPLC_DIO_TS_CLK_1GHZ, /* 1 ns period with 20 ns granularity */ + AMPLC_DIO_TS_CLK_1MHZ, /* 1 us period */ + AMPLC_DIO_TS_CLK_1KHZ /* 1 ms period */ +}; + /* Values for setting a gate source with INSN_CONFIG_SET_GATE_SRC for * 8254 counter subdevices on Amplicon DIO boards (amplc_dio200 driver). */ enum amplc_dio_gate_source { -- cgit v1.2.3 From fad18543cef4d6368b00fb318d0b31d1e2deabb6 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:13 +0100 Subject: staging: comedi: amplc_dio200: support multiple read/write of counter Change the `insn_read` and `insn_write` handlers of the '8254' counter subdevices to support reading and writing multiple data values. (Writing multiple values isn't very useful, but if that's what the user wants....) Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index d72a86b3e9f..95c3f7824d8 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1270,13 +1270,15 @@ dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s, { struct dio200_subdev_8254 *subpriv = s->private; int chan = CR_CHAN(insn->chanspec); + unsigned int n; unsigned long flags; - spin_lock_irqsave(&subpriv->spinlock, flags); - data[0] = dio200_subdev_8254_read_chan(dev, s, chan); - spin_unlock_irqrestore(&subpriv->spinlock, flags); - - return 1; + for (n = 0; n < insn->n; n++) { + spin_lock_irqsave(&subpriv->spinlock, flags); + data[n] = dio200_subdev_8254_read_chan(dev, s, chan); + spin_unlock_irqrestore(&subpriv->spinlock, flags); + } + return insn->n; } /* @@ -1288,13 +1290,15 @@ dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s, { struct dio200_subdev_8254 *subpriv = s->private; int chan = CR_CHAN(insn->chanspec); + unsigned int n; unsigned long flags; - spin_lock_irqsave(&subpriv->spinlock, flags); - dio200_subdev_8254_write_chan(dev, s, chan, data[0]); - spin_unlock_irqrestore(&subpriv->spinlock, flags); - - return 1; + for (n = 0; n < insn->n; n++) { + spin_lock_irqsave(&subpriv->spinlock, flags); + dio200_subdev_8254_write_chan(dev, s, chan, data[n]); + spin_unlock_irqrestore(&subpriv->spinlock, flags); + } + return insn->n; } /* -- cgit v1.2.3 From 23249ea2308a962517cc299955de415aad9db0ec Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 24 Oct 2012 16:48:14 +0100 Subject: staging: comedi: Kconfig: update COMEDI_AMPLC_DIO200_PCI option Update the prompt line and description for the COMEDI_AMPLC_DIO200_PCI config option to add the new PCIe boards supported by the "amplc_dio200" driver. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 966730731c7..21a6748d7ad 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -761,10 +761,11 @@ config COMEDI_ADV_PCI_DIO called adv_pci_dio. config COMEDI_AMPLC_DIO200_PCI - tristate "Amplicon PCI215 and PCI272 DIO board support" + tristate "Amplicon PCI215/PCI272/PCIe215/PCIe236/PCIe296 DIO support" select COMEDI_AMPLC_DIO200 ---help--- - Enable support for Amplicon PCI215 and PCI272 DIO boards. + Enable support for Amplicon PCI215, PCI272, PCIe215, PCIe236 + and PCIe296 DIO boards. To compile this driver as a module, choose M here: the module will be called amplc_dio200. -- cgit v1.2.3 From 7e6735c3578e76c270a2797225a4214176ba13ef Mon Sep 17 00:00:00 2001 From: Cyril Chemparathy Date: Wed, 12 Sep 2012 14:05:58 -0400 Subject: /dev/mem: use phys_addr_t for physical addresses This patch fixes the /dev/mem driver to use phys_addr_t for physical addresses. This is required on PAE systems, especially those that run entirely out of >4G physical memory space. Signed-off-by: Cyril Chemparathy Signed-off-by: Greg Kroah-Hartman --- arch/arm/include/asm/io.h | 2 +- arch/arm/mm/mmap.c | 2 +- arch/ia64/include/asm/io.h | 2 +- arch/ia64/kernel/efi.c | 2 +- arch/sh/include/asm/io.h | 2 +- arch/sh/mm/mmap.c | 2 +- drivers/char/mem.c | 10 +++++----- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 35c1ed89b93..f52a93d9866 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -374,7 +374,7 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); #ifdef CONFIG_MMU #define ARCH_HAS_VALID_PHYS_ADDR_RANGE -extern int valid_phys_addr_range(unsigned long addr, size_t size); +extern int valid_phys_addr_range(phys_addr_t addr, size_t size); extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); extern int devmem_is_allowed(unsigned long pfn); #endif diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index ce8cb1970d7..89f2b7f7b04 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c @@ -279,7 +279,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm) * You really shouldn't be using read() or write() on /dev/mem. This * might go away in the future. */ -int valid_phys_addr_range(unsigned long addr, size_t size) +int valid_phys_addr_range(phys_addr_t addr, size_t size) { if (addr < PHYS_OFFSET) return 0; diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h index 2c26321c28c..74a7cc3293b 100644 --- a/arch/ia64/include/asm/io.h +++ b/arch/ia64/include/asm/io.h @@ -90,7 +90,7 @@ phys_to_virt (unsigned long address) #define ARCH_HAS_VALID_PHYS_ADDR_RANGE extern u64 kern_mem_attribute (unsigned long phys_addr, unsigned long size); -extern int valid_phys_addr_range (unsigned long addr, size_t count); /* efi.c */ +extern int valid_phys_addr_range (phys_addr_t addr, size_t count); /* efi.c */ extern int valid_mmap_phys_addr_range (unsigned long pfn, size_t count); /* diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index d37bbd48637..f034563aeae 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -870,7 +870,7 @@ kern_mem_attribute (unsigned long phys_addr, unsigned long size) EXPORT_SYMBOL(kern_mem_attribute); int -valid_phys_addr_range (unsigned long phys_addr, unsigned long size) +valid_phys_addr_range (phys_addr_t phys_addr, unsigned long size) { u64 attr; diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h index 73a23f4617a..629db2ad791 100644 --- a/arch/sh/include/asm/io.h +++ b/arch/sh/include/asm/io.h @@ -382,7 +382,7 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; } #define xlate_dev_kmem_ptr(p) p #define ARCH_HAS_VALID_PHYS_ADDR_RANGE -int valid_phys_addr_range(unsigned long addr, size_t size); +int valid_phys_addr_range(phys_addr_t addr, size_t size); int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); #endif /* __KERNEL__ */ diff --git a/arch/sh/mm/mmap.c b/arch/sh/mm/mmap.c index afeb710ec5c..80bf494ddbc 100644 --- a/arch/sh/mm/mmap.c +++ b/arch/sh/mm/mmap.c @@ -238,7 +238,7 @@ bottomup: * You really shouldn't be using read() or write() on /dev/mem. This * might go away in the future. */ -int valid_phys_addr_range(unsigned long addr, size_t count) +int valid_phys_addr_range(phys_addr_t addr, size_t count) { if (addr < __MEMORY_START) return 0; diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 0537903c985..c6fa3bc2baa 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -48,7 +48,7 @@ static inline unsigned long size_inside_page(unsigned long start, } #ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE -static inline int valid_phys_addr_range(unsigned long addr, size_t count) +static inline int valid_phys_addr_range(phys_addr_t addr, size_t count) { return addr + count <= __pa(high_memory); } @@ -96,7 +96,7 @@ void __weak unxlate_dev_mem_ptr(unsigned long phys, void *addr) static ssize_t read_mem(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - unsigned long p = *ppos; + phys_addr_t p = *ppos; ssize_t read, sz; char *ptr; @@ -153,7 +153,7 @@ static ssize_t read_mem(struct file *file, char __user *buf, static ssize_t write_mem(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - unsigned long p = *ppos; + phys_addr_t p = *ppos; ssize_t written, sz; unsigned long copied; void *ptr; @@ -226,7 +226,7 @@ int __weak phys_mem_access_prot_allowed(struct file *file, * */ #ifdef pgprot_noncached -static int uncached_access(struct file *file, unsigned long addr) +static int uncached_access(struct file *file, phys_addr_t addr) { #if defined(CONFIG_IA64) /* @@ -258,7 +258,7 @@ static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size, pgprot_t vma_prot) { #ifdef pgprot_noncached - unsigned long offset = pfn << PAGE_SHIFT; + phys_addr_t offset = pfn << PAGE_SHIFT; if (uncached_access(file, offset)) return pgprot_noncached(vma_prot); -- cgit v1.2.3 From ebb108ef93605a68f6f38d5eb407e7d5138e8028 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 9 Oct 2012 16:50:16 +0200 Subject: mei: rename mei_cl_cb.information to mei_cl_cb.buf_idx rename 'information' member of the struct mei_cl_cb to more self-descriptive 'buf_idx' Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 43 +++++++++++++++++++++---------------------- drivers/misc/mei/iorw.c | 17 ++++++++--------- drivers/misc/mei/main.c | 33 +++++++++++++++------------------ drivers/misc/mei/mei_dev.h | 2 +- 4 files changed, 45 insertions(+), 50 deletions(-) diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 3533edde04a..320ebd2f06c 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -149,7 +149,7 @@ static int mei_irq_thread_read_amthi_message(struct mei_io_list *complete_list, return -ENODEV; dev->iamthif_stall_timer = 0; - cb->information = dev->iamthif_msg_buf_index; + cb->buf_idx = dev->iamthif_msg_buf_index; cb->read_time = jiffies; if (dev->iamthif_ioctl && cl == &dev->iamthif_cl) { /* found the iamthif cb */ @@ -205,10 +205,10 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, cl = (struct mei_cl *)cb_pos->file_private; if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) { cl->reading_state = MEI_READING; - buffer = cb_pos->response_buffer.data + cb_pos->information; + buffer = cb_pos->response_buffer.data + cb_pos->buf_idx; if (cb_pos->response_buffer.size < - mei_hdr->length + cb_pos->information) { + mei_hdr->length + cb_pos->buf_idx) { dev_dbg(&dev->pdev->dev, "message overflow.\n"); list_del(&cb_pos->cb_list); return -ENOMEM; @@ -216,7 +216,7 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, if (buffer) mei_read_slots(dev, buffer, mei_hdr->length); - cb_pos->information += mei_hdr->length; + cb_pos->buf_idx += mei_hdr->length; if (mei_hdr->msg_complete) { cl->status = 0; list_del(&cb_pos->cb_list); @@ -224,7 +224,8 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, "completed read H cl = %d, ME cl = %d, length = %lu\n", cl->host_client_id, cl->me_client_id, - cb_pos->information); + cb_pos->buf_idx); + list_add_tail(&cb_pos->cb_list, &complete_list->mei_cb.cb_list); } @@ -300,14 +301,14 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, if (mei_disconnect(dev, cl)) { cl->status = 0; - cb_pos->information = 0; + cb_pos->buf_idx = 0; list_move_tail(&cb_pos->cb_list, &cmpl_list->mei_cb.cb_list); return -EMSGSIZE; } else { cl->state = MEI_FILE_DISCONNECTING; cl->status = 0; - cb_pos->information = 0; + cb_pos->buf_idx = 0; list_move_tail(&cb_pos->cb_list, &dev->ctrl_rd_list.mei_cb.cb_list); cl->timer_count = MEI_CONNECT_TIMEOUT; @@ -834,7 +835,7 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, if (mei_send_flow_control(dev, cl)) { cl->status = -ENODEV; - cb_pos->information = 0; + cb_pos->buf_idx = 0; list_move_tail(&cb_pos->cb_list, &cmpl_list->mei_cb.cb_list); return -ENODEV; } @@ -871,7 +872,7 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); if (mei_connect(dev, cl)) { cl->status = -ENODEV; - cb_pos->information = 0; + cb_pos->buf_idx = 0; list_del(&cb_pos->cb_list); return -ENODEV; } else { @@ -901,28 +902,26 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, struct mei_msg_hdr *mei_hdr; if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - (cb_pos->request_buffer.size - - cb_pos->information))) { + (cb_pos->request_buffer.size - cb_pos->buf_idx))) { mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; mei_hdr->host_addr = cl->host_client_id; mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = cb_pos->request_buffer.size - - cb_pos->information; + mei_hdr->length = cb_pos->request_buffer.size - cb_pos->buf_idx; mei_hdr->msg_complete = 1; mei_hdr->reserved = 0; dev_dbg(&dev->pdev->dev, "cb_pos->request_buffer.size =%d" "mei_hdr->msg_complete = %d\n", cb_pos->request_buffer.size, mei_hdr->msg_complete); - dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n", - cb_pos->information); + dev_dbg(&dev->pdev->dev, "cb_pos->buf_idx =%lu\n", + cb_pos->buf_idx); dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length); *slots -= mei_data2slots(mei_hdr->length); if (mei_write_message(dev, mei_hdr, (unsigned char *) (cb_pos->request_buffer.data + - cb_pos->information), + cb_pos->buf_idx), mei_hdr->length)) { cl->status = -ENODEV; list_move_tail(&cb_pos->cb_list, @@ -932,7 +931,7 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, if (mei_flow_ctrl_reduce(dev, cl)) return -ENODEV; cl->status = 0; - cb_pos->information += mei_hdr->length; + cb_pos->buf_idx += mei_hdr->length; list_move_tail(&cb_pos->cb_list, &dev->write_waiting_list.mei_cb.cb_list); } @@ -949,21 +948,21 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, if (mei_write_message(dev, mei_hdr, (unsigned char *) (cb_pos->request_buffer.data + - cb_pos->information), + cb_pos->buf_idx), mei_hdr->length)) { cl->status = -ENODEV; list_move_tail(&cb_pos->cb_list, &cmpl_list->mei_cb.cb_list); return -ENODEV; } else { - cb_pos->information += mei_hdr->length; + cb_pos->buf_idx += mei_hdr->length; dev_dbg(&dev->pdev->dev, "cb_pos->request_buffer.size =%d" " mei_hdr->msg_complete = %d\n", cb_pos->request_buffer.size, mei_hdr->msg_complete); - dev_dbg(&dev->pdev->dev, "cb_pos->information =%lu\n", - cb_pos->information); + dev_dbg(&dev->pdev->dev, "cb_pos->buf_idx =%lu\n", + cb_pos->buf_idx); dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length); } @@ -1018,7 +1017,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, if (mei_flow_ctrl_reduce(dev, cl)) return -ENODEV; dev->iamthif_msg_buf_index += mei_hdr->length; - cb_pos->information = dev->iamthif_msg_buf_index; + cb_pos->buf_idx = dev->iamthif_msg_buf_index; cl->status = 0; dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; dev->iamthif_flow_control_pending = true; diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index fcba98eb892..20652e140c4 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -346,9 +346,9 @@ int amthi_read(struct mei_device *dev, struct file *file, } } /* if the whole message will fit remove it from the list */ - if (cb->information >= *offset && length >= (cb->information - *offset)) + if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset)) list_del(&cb->cb_list); - else if (cb->information > 0 && cb->information <= *offset) { + else if (cb->buf_idx > 0 && cb->buf_idx <= *offset) { /* end of the message has been reached */ list_del(&cb->cb_list); rets = 0; @@ -360,18 +360,17 @@ int amthi_read(struct mei_device *dev, struct file *file, dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n", cb->response_buffer.size); - dev_dbg(&dev->pdev->dev, "amthi cb->information - %lu\n", - cb->information); + dev_dbg(&dev->pdev->dev, "amthi cb->buf_idx - %lu\n", cb->buf_idx); /* length is being turncated to PAGE_SIZE, however, - * the information may be longer */ - length = min_t(size_t, length, (cb->information - *offset)); + * the buf_idx may point beyond */ + length = min_t(size_t, length, (cb->buf_idx - *offset)); if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) rets = -EFAULT; else { rets = length; - if ((*offset + length) < cb->information) { + if ((*offset + length) < cb->buf_idx) { *offset += length; goto out; } @@ -432,8 +431,8 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl) } dev_dbg(&dev->pdev->dev, "allocation call back data success.\n"); cb->major_file_operations = MEI_READ; - /* make sure information is zero before we start */ - cb->information = 0; + /* make sure buffer index is zero before we start */ + cb->buf_idx = 0; cb->file_private = (void *) cl; cl->read_cb = cb; if (dev->mei_host_buffer_is_empty) { diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index e8b0858132c..3d4f6d17d74 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -415,16 +415,15 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, goto out; } - if (cl->read_cb && cl->read_cb->information > *offset) { + if (cl->read_cb && cl->read_cb->buf_idx > *offset) { cb = cl->read_cb; goto copy_buffer; - } else if (cl->read_cb && cl->read_cb->information > 0 && - cl->read_cb->information <= *offset) { + } else if (cl->read_cb && cl->read_cb->buf_idx > 0 && + cl->read_cb->buf_idx <= *offset) { cb = cl->read_cb; rets = 0; goto free; - } else if ((!cl->read_cb || !cl->read_cb->information) && - *offset > 0) { + } else if ((!cl->read_cb || !cl->read_cb->buf_idx) && *offset > 0) { /*Offset needs to be cleaned for contiguous reads*/ *offset = 0; rets = 0; @@ -481,16 +480,15 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, copy_buffer: dev_dbg(&dev->pdev->dev, "cb->response_buffer size - %d\n", cb->response_buffer.size); - dev_dbg(&dev->pdev->dev, "cb->information - %lu\n", - cb->information); - if (length == 0 || ubuf == NULL || *offset > cb->information) { + dev_dbg(&dev->pdev->dev, "cb->buf_idx - %lu\n", cb->buf_idx); + if (length == 0 || ubuf == NULL || *offset > cb->buf_idx) { rets = -EMSGSIZE; goto free; } - /* length is being truncated to PAGE_SIZE, however, */ - /* information size may be longer */ - length = min_t(size_t, length, (cb->information - *offset)); + /* length is being truncated to PAGE_SIZE, + * however buf_idx may point beyond that */ + length = min_t(size_t, length, cb->buf_idx - *offset); if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) { rets = -EFAULT; @@ -499,7 +497,7 @@ copy_buffer: rets = length; *offset += length; - if ((unsigned long)*offset < cb->information) + if ((unsigned long)*offset < cb->buf_idx) goto out; free: @@ -637,7 +635,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, write_cb->response_buffer.size = dev->iamthif_mtu; write_cb->major_file_operations = MEI_IOCTL; - write_cb->information = 0; + write_cb->buf_idx = 0; write_cb->request_buffer.size = length; if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { rets = -ENODEV; @@ -668,9 +666,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, } write_cb->major_file_operations = MEI_WRITE; - /* make sure information is zero before we start */ - - write_cb->information = 0; + /* make sure buffer index is zero before we start */ + write_cb->buf_idx = 0; write_cb->request_buffer.size = length; dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", @@ -719,7 +716,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, goto unlock_dev; } cl->writing_state = MEI_WRITING; - write_cb->information = mei_hdr.length; + write_cb->buf_idx = mei_hdr.length; if (mei_hdr.msg_complete) { if (mei_flow_ctrl_reduce(dev, cl)) { rets = -ENODEV; @@ -734,7 +731,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, } else { - write_cb->information = 0; + write_cb->buf_idx = 0; cl->writing_state = MEI_WRITING; list_add_tail(&write_cb->cb_list, &dev->write_list.mei_cb.cb_list); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index adb35fb9281..c58b6fa06c0 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -149,7 +149,7 @@ struct mei_cl_cb { void *file_private; struct mei_message_data request_buffer; struct mei_message_data response_buffer; - unsigned long information; + unsigned long buf_idx; unsigned long read_time; struct file *file_object; }; -- cgit v1.2.3 From 33d28c9205257479be540a31b03339817cf2d62c Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 9 Oct 2012 16:50:17 +0200 Subject: mei: add allocation and initialization wrappers for io callback mei_io_cb_init - allocat and initializate mei_cl_cb mei_io_cb_alloc_req/resp_buf are separate function as buffers are not always needed Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 111 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 87 insertions(+), 24 deletions(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 3d4f6d17d74..15de4b19caa 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -515,6 +515,83 @@ out: return rets; } +/** + * mei_io_cb_init - allocate and initialize io callback + * + * @cl - mei client + * @file: pointer to file structure + * + * returns mei_cl_cb pointer or NULL; + */ +static struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp) +{ + struct mei_cl_cb *cb; + struct mei_device *dev; + + dev = cl->dev; + + cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); + if (!cb) + return NULL; + + INIT_LIST_HEAD(&cb->cb_list); + + cb->file_object = fp; + cb->file_private = cl; + cb->buf_idx = 0; + return cb; +} + + +/** + * mei_io_cb_alloc_req_buf - allocate request buffer + * + * @cb - io callback structure + * @size: size of the buffer + * + * returns 0 on success + * -EINVAL if cb is NULL + * -ENOMEM if allocation failed + */ +static int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length) +{ + if (!cb) + return -EINVAL; + + if (length == 0) + return 0; + + cb->request_buffer.data = kmalloc(length, GFP_KERNEL); + if (!cb->request_buffer.data) + return -ENOMEM; + cb->request_buffer.size = length; + return 0; +} +/** + * mei_io_cb_alloc_req_buf - allocate respose buffer + * + * @cb - io callback structure + * @size: size of the buffer + * + * returns 0 on success + * -EINVAL if cb is NULL + * -ENOMEM if allocation failed + */ +static int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length) +{ + if (!cb) + return -EINVAL; + + if (length == 0) + return 0; + + cb->response_buffer.data = kmalloc(length, GFP_KERNEL); + if (!cb->response_buffer.data) + return -ENOMEM; + cb->response_buffer.size = length; + return 0; +} + /** * mei_write - the write function. * @@ -581,20 +658,17 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, *offset = 0; - write_cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); + write_cb = mei_io_cb_init(cl, file); if (!write_cb) { - mutex_unlock(&dev->device_lock); - return -ENOMEM; + dev_err(&dev->pdev->dev, "write cb allocation failed\n"); + rets = -ENOMEM; + goto unlock_dev; } - - write_cb->file_object = file; - write_cb->file_private = cl; - write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL); - rets = -ENOMEM; - if (!write_cb->request_buffer.data) + rets = mei_io_cb_alloc_req_buf(write_cb, length); + if (rets) goto unlock_dev; - dev_dbg(&dev->pdev->dev, "length =%d\n", (int) length); + dev_dbg(&dev->pdev->dev, "cb request size = %zd\n", length); rets = -EFAULT; if (copy_from_user(write_cb->request_buffer.data, ubuf, length)) @@ -610,14 +684,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, write_cb->request_buffer.data, 4) == 0))) cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT; - INIT_LIST_HEAD(&write_cb->cb_list); if (cl == &dev->iamthif_cl) { - write_cb->response_buffer.data = - kmalloc(dev->iamthif_mtu, GFP_KERNEL); - if (!write_cb->response_buffer.data) { - rets = -ENOMEM; - goto unlock_dev; - } if (dev->dev_state != MEI_DEV_ENABLED) { rets = -ENODEV; goto unlock_dev; @@ -632,11 +699,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, rets = -EMSGSIZE; goto unlock_dev; } + rets = mei_io_cb_alloc_resp_buf(write_cb, dev->iamthif_mtu); + if (rets) + goto unlock_dev; - write_cb->response_buffer.size = dev->iamthif_mtu; write_cb->major_file_operations = MEI_IOCTL; - write_cb->buf_idx = 0; - write_cb->request_buffer.size = length; if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { rets = -ENODEV; goto unlock_dev; @@ -666,9 +733,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, } write_cb->major_file_operations = MEI_WRITE; - /* make sure buffer index is zero before we start */ - write_cb->buf_idx = 0; - write_cb->request_buffer.size = length; dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", cl->host_client_id, cl->me_client_id); @@ -688,7 +752,6 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, rets = -EINVAL; goto unlock_dev; } - write_cb->file_private = cl; rets = mei_flow_ctrl_creds(dev, cl); if (rets < 0) -- cgit v1.2.3 From 75f0ee1559c5d51948e029041a9b722b3e3f0b83 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 9 Oct 2012 16:50:18 +0200 Subject: mei: mei_write: revamp error path handling 1. unify common amt and regular error path and use it early in the function 2. fix indentation 3. propagate error code directly from copy_from_user 4. print out errors using dev_err instead of dev_dbg Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 75 ++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 48 deletions(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 15de4b19caa..8dcf59d43b0 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -621,10 +621,26 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, mutex_lock(&dev->device_lock); if (dev->dev_state != MEI_DEV_ENABLED) { - mutex_unlock(&dev->device_lock); - return -ENODEV; + rets = -ENODEV; + goto unlock_dev; } + i = mei_me_cl_by_id(dev, cl->me_client_id); + if (i < 0) { + rets = -ENODEV; + goto unlock_dev; + } + if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { + rets = -EMSGSIZE; + goto unlock_dev; + } + + if (cl->state != MEI_FILE_CONNECTED) { + rets = -ENODEV; + dev_err(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d", + cl->host_client_id, cl->me_client_id); + goto unlock_dev; + } if (cl == &dev->iamthif_cl) { write_cb = find_amthi_read_list_entry(dev, file); @@ -633,11 +649,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, msecs_to_jiffies(IAMTHIF_READ_TIMER); if (time_after(jiffies, timeout) || - cl->reading_state == MEI_READ_COMPLETE) { - *offset = 0; - list_del(&write_cb->cb_list); - mei_free_cb_private(write_cb); - write_cb = NULL; + cl->reading_state == MEI_READ_COMPLETE) { + *offset = 0; + list_del(&write_cb->cb_list); + mei_free_cb_private(write_cb); + write_cb = NULL; } } } @@ -670,8 +686,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, dev_dbg(&dev->pdev->dev, "cb request size = %zd\n", length); - rets = -EFAULT; - if (copy_from_user(write_cb->request_buffer.data, ubuf, length)) + rets = copy_from_user(write_cb->request_buffer.data, ubuf, length); + if (rets) goto unlock_dev; cl->sm_state = 0; @@ -685,29 +701,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT; if (cl == &dev->iamthif_cl) { - if (dev->dev_state != MEI_DEV_ENABLED) { - rets = -ENODEV; - goto unlock_dev; - } - i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id); - if (i < 0) { - rets = -ENODEV; - goto unlock_dev; - } - if (length > dev->me_clients[i].props.max_msg_length || - length <= 0) { - rets = -EMSGSIZE; - goto unlock_dev; - } rets = mei_io_cb_alloc_resp_buf(write_cb, dev->iamthif_mtu); if (rets) goto unlock_dev; write_cb->major_file_operations = MEI_IOCTL; - if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { - rets = -ENODEV; - goto unlock_dev; - } if (!list_empty(&dev->amthi_cmd_list.mei_cb.cb_list) || dev->iamthif_state != MEI_IAMTHIF_IDLE) { @@ -716,43 +714,24 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, dev_dbg(&dev->pdev->dev, "add amthi cb to amthi cmd waiting list\n"); list_add_tail(&write_cb->cb_list, &dev->amthi_cmd_list.mei_cb.cb_list); - rets = length; } else { dev_dbg(&dev->pdev->dev, "call amthi write\n"); rets = amthi_write(dev, write_cb); if (rets) { - dev_dbg(&dev->pdev->dev, "amthi write failed with status = %d\n", + dev_err(&dev->pdev->dev, "amthi write failed with status = %d\n", rets); goto unlock_dev; } - rets = length; } mutex_unlock(&dev->device_lock); - return rets; + return length; } write_cb->major_file_operations = MEI_WRITE; dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", cl->host_client_id, cl->me_client_id); - if (cl->state != MEI_FILE_CONNECTED) { - rets = -ENODEV; - dev_dbg(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d", - cl->host_client_id, - cl->me_client_id); - goto unlock_dev; - } - i = mei_me_cl_by_id(dev, cl->me_client_id); - if (i < 0) { - rets = -ENODEV; - goto unlock_dev; - } - if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { - rets = -EINVAL; - goto unlock_dev; - } - rets = mei_flow_ctrl_creds(dev, cl); if (rets < 0) goto unlock_dev; -- cgit v1.2.3 From fb601adb350f82738210c0a1dc6af928a15391db Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 15 Oct 2012 12:06:48 +0200 Subject: mei: kill usless struct mei_io_list kill useless mei_io_list list wrapper and use directly struct mei_cl_cb mei_cb which was its only member for managing io queues Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/init.c | 31 +++------- drivers/misc/mei/interrupt.c | 134 +++++++++++++++++++------------------------ drivers/misc/mei/iorw.c | 34 +++++------ drivers/misc/mei/main.c | 43 ++++++-------- drivers/misc/mei/mei_dev.h | 32 ++++++----- 5 files changed, 118 insertions(+), 156 deletions(-) diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 98f1430e3e1..2275cf03bad 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -47,35 +47,23 @@ const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c); -/** - * mei_io_list_init - Sets up a queue list. - * - * @list: An instance io list structure - * @dev: the device structure - */ -void mei_io_list_init(struct mei_io_list *list) -{ - /* initialize our queue list */ - INIT_LIST_HEAD(&list->mei_cb.cb_list); -} - /** * mei_io_list_flush - removes list entry belonging to cl. * * @list: An instance of our list structure * @cl: private data of the file object */ -void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl) +void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl) { struct mei_cl_cb *pos; struct mei_cl_cb *next; - list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) { + list_for_each_entry_safe(pos, next, &list->list, list) { if (pos->file_private) { struct mei_cl *cl_tmp; cl_tmp = (struct mei_cl *)pos->file_private; if (mei_cl_cmp_id(cl, cl_tmp)) - list_del(&pos->cb_list); + list_del(&pos->list); } } } @@ -351,9 +339,8 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) } } /* remove all waiting requests */ - list_for_each_entry_safe(cb_pos, cb_next, - &dev->write_list.mei_cb.cb_list, cb_list) { - list_del(&cb_pos->cb_list); + list_for_each_entry_safe(cb_pos, cb_next, &dev->write_list.list, list) { + list_del(&cb_pos->list); mei_free_cb_private(cb_pos); } } @@ -685,7 +672,7 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) if (!cb) return -ENOMEM; - INIT_LIST_HEAD(&cb->cb_list); + mei_io_list_init(cb); cb->file_private = cl; cb->major_file_operations = MEI_CLOSE; if (dev->mei_host_buffer_is_empty) { @@ -696,11 +683,11 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) goto free; } mdelay(10); /* Wait for hardware disconnection ready */ - list_add_tail(&cb->cb_list, &dev->ctrl_rd_list.mei_cb.cb_list); + list_add_tail(&cb->list, &dev->ctrl_rd_list.list); } else { dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n"); - list_add_tail(&cb->cb_list, - &dev->ctrl_wr_list.mei_cb.cb_list); + list_add_tail(&cb->list, &dev->ctrl_wr_list.list); + } mutex_unlock(&dev->device_lock); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 320ebd2f06c..54d6f1a1dbc 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -87,9 +87,8 @@ static void _mei_cmpl_iamthif(struct mei_device *dev, struct mei_cl_cb *cb_pos) memcpy(cb_pos->response_buffer.data, dev->iamthif_msg_buf, dev->iamthif_msg_buf_index); - list_add_tail(&cb_pos->cb_list, - &dev->amthi_read_complete_list.mei_cb.cb_list); - dev_dbg(&dev->pdev->dev, "amthi read completed.\n"); + list_add_tail(&cb_pos->list, &dev->amthi_read_complete_list.list); + dev_dbg(&dev->pdev->dev, "amthi read completed\n"); dev->iamthif_timer = jiffies; dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", dev->iamthif_timer); @@ -112,7 +111,7 @@ static void _mei_cmpl_iamthif(struct mei_device *dev, struct mei_cl_cb *cb_pos) * * returns 0 on success, <0 on failure. */ -static int mei_irq_thread_read_amthi_message(struct mei_io_list *complete_list, +static int mei_irq_thread_read_amthi_message(struct mei_cl_cb *complete_list, struct mei_device *dev, struct mei_msg_hdr *mei_hdr) { @@ -155,8 +154,7 @@ static int mei_irq_thread_read_amthi_message(struct mei_io_list *complete_list, /* found the iamthif cb */ dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n "); dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n "); - list_add_tail(&cb->cb_list, - &complete_list->mei_cb.cb_list); + list_add_tail(&cb->list, &complete_list->list); } return 0; } @@ -188,7 +186,7 @@ static int _mei_irq_thread_state_ok(struct mei_cl *cl, * * returns 0 on success, <0 on failure. */ -static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, +static int mei_irq_thread_read_client_message(struct mei_cl_cb *complete_list, struct mei_device *dev, struct mei_msg_hdr *mei_hdr) { @@ -197,11 +195,10 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, unsigned char *buffer = NULL; dev_dbg(&dev->pdev->dev, "start client msg\n"); - if (list_empty(&dev->read_list.mei_cb.cb_list)) + if (list_empty(&dev->read_list.list)) goto quit; - list_for_each_entry_safe(cb_pos, cb_next, - &dev->read_list.mei_cb.cb_list, cb_list) { + list_for_each_entry_safe(cb_pos, cb_next, &dev->read_list.list, list) { cl = (struct mei_cl *)cb_pos->file_private; if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) { cl->reading_state = MEI_READING; @@ -210,7 +207,7 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, if (cb_pos->response_buffer.size < mei_hdr->length + cb_pos->buf_idx) { dev_dbg(&dev->pdev->dev, "message overflow.\n"); - list_del(&cb_pos->cb_list); + list_del(&cb_pos->list); return -ENOMEM; } if (buffer) @@ -219,15 +216,15 @@ static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list, cb_pos->buf_idx += mei_hdr->length; if (mei_hdr->msg_complete) { cl->status = 0; - list_del(&cb_pos->cb_list); + list_del(&cb_pos->list); dev_dbg(&dev->pdev->dev, "completed read H cl = %d, ME cl = %d, length = %lu\n", cl->host_client_id, cl->me_client_id, cb_pos->buf_idx); - list_add_tail(&cb_pos->cb_list, - &complete_list->mei_cb.cb_list); + list_add_tail(&cb_pos->list, + &complete_list->list); } break; @@ -291,7 +288,7 @@ static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots) static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, struct mei_cl_cb *cb_pos, struct mei_cl *cl, - struct mei_io_list *cmpl_list) + struct mei_cl_cb *cmpl_list) { if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + sizeof(struct hbm_client_disconnect_request))) @@ -302,15 +299,13 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, if (mei_disconnect(dev, cl)) { cl->status = 0; cb_pos->buf_idx = 0; - list_move_tail(&cb_pos->cb_list, - &cmpl_list->mei_cb.cb_list); + list_move_tail(&cb_pos->list, &cmpl_list->list); return -EMSGSIZE; } else { cl->state = MEI_FILE_DISCONNECTING; cl->status = 0; cb_pos->buf_idx = 0; - list_move_tail(&cb_pos->cb_list, - &dev->ctrl_rd_list.mei_cb.cb_list); + list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list); cl->timer_count = MEI_CONNECT_TIMEOUT; } @@ -357,7 +352,7 @@ static void mei_client_connect_response(struct mei_device *dev, { struct mei_cl *cl; - struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; + struct mei_cl_cb *pos = NULL, *next = NULL; dev_dbg(&dev->pdev->dev, "connect_response:\n" @@ -383,17 +378,16 @@ static void mei_client_connect_response(struct mei_device *dev, dev->iamthif_state = MEI_IAMTHIF_IDLE; return; } - list_for_each_entry_safe(cb_pos, cb_next, - &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) { + list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) { - cl = (struct mei_cl *)cb_pos->file_private; + cl = (struct mei_cl *)pos->file_private; if (!cl) { - list_del(&cb_pos->cb_list); + list_del(&pos->list); return; } - if (MEI_IOCTL == cb_pos->major_file_operations) { + if (MEI_IOCTL == pos->major_file_operations) { if (is_treat_specially_client(cl, rs)) { - list_del(&cb_pos->cb_list); + list_del(&pos->list); cl->status = 0; cl->timer_count = 0; break; @@ -412,7 +406,7 @@ static void mei_client_disconnect_response(struct mei_device *dev, struct hbm_client_connect_response *rs) { struct mei_cl *cl; - struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; + struct mei_cl_cb *pos = NULL, *next = NULL; dev_dbg(&dev->pdev->dev, "disconnect_response:\n" @@ -423,12 +417,11 @@ static void mei_client_disconnect_response(struct mei_device *dev, rs->host_addr, rs->status); - list_for_each_entry_safe(cb_pos, cb_next, - &dev->ctrl_rd_list.mei_cb.cb_list, cb_list) { - cl = (struct mei_cl *)cb_pos->file_private; + list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) { + cl = (struct mei_cl *)pos->file_private; if (!cl) { - list_del(&cb_pos->cb_list); + list_del(&pos->list); return; } @@ -436,7 +429,7 @@ static void mei_client_disconnect_response(struct mei_device *dev, if (cl->host_client_id == rs->host_addr && cl->me_client_id == rs->me_addr) { - list_del(&cb_pos->cb_list); + list_del(&pos->list); if (!rs->status) cl->state = MEI_FILE_DISCONNECTED; @@ -822,12 +815,12 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, struct mei_cl_cb *cb_pos, struct mei_cl *cl, - struct mei_io_list *cmpl_list) + struct mei_cl_cb *cmpl_list) { if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + sizeof(struct hbm_flow_control))) { /* return the cancel routine */ - list_del(&cb_pos->cb_list); + list_del(&cb_pos->list); return -EBADMSG; } @@ -836,10 +829,10 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, if (mei_send_flow_control(dev, cl)) { cl->status = -ENODEV; cb_pos->buf_idx = 0; - list_move_tail(&cb_pos->cb_list, &cmpl_list->mei_cb.cb_list); + list_move_tail(&cb_pos->list, &cmpl_list->list); return -ENODEV; } - list_move_tail(&cb_pos->cb_list, &dev->read_list.mei_cb.cb_list); + list_move_tail(&cb_pos->list, &dev->read_list.list); return 0; } @@ -859,12 +852,12 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, struct mei_cl_cb *cb_pos, struct mei_cl *cl, - struct mei_io_list *cmpl_list) + struct mei_cl_cb *cmpl_list) { if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + sizeof(struct hbm_client_connect_request))) { /* return the cancel routine */ - list_del(&cb_pos->cb_list); + list_del(&cb_pos->list); return -EBADMSG; } @@ -873,11 +866,10 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, if (mei_connect(dev, cl)) { cl->status = -ENODEV; cb_pos->buf_idx = 0; - list_del(&cb_pos->cb_list); + list_del(&cb_pos->list); return -ENODEV; } else { - list_move_tail(&cb_pos->cb_list, - &dev->ctrl_rd_list.mei_cb.cb_list); + list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list); cl->timer_count = MEI_CONNECT_TIMEOUT; } return 0; @@ -897,7 +889,7 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, struct mei_cl_cb *cb_pos, struct mei_cl *cl, - struct mei_io_list *cmpl_list) + struct mei_cl_cb *cmpl_list) { struct mei_msg_hdr *mei_hdr; @@ -924,16 +916,14 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, cb_pos->buf_idx), mei_hdr->length)) { cl->status = -ENODEV; - list_move_tail(&cb_pos->cb_list, - &cmpl_list->mei_cb.cb_list); + list_move_tail(&cb_pos->list, &cmpl_list->list); return -ENODEV; } else { if (mei_flow_ctrl_reduce(dev, cl)) return -ENODEV; cl->status = 0; cb_pos->buf_idx += mei_hdr->length; - list_move_tail(&cb_pos->cb_list, - &dev->write_waiting_list.mei_cb.cb_list); + list_move_tail(&cb_pos->list, &dev->write_waiting_list.list); } } else if (*slots == dev->hbuf_depth) { /* buffer is still empty */ @@ -951,8 +941,7 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, cb_pos->buf_idx), mei_hdr->length)) { cl->status = -ENODEV; - list_move_tail(&cb_pos->cb_list, - &cmpl_list->mei_cb.cb_list); + list_move_tail(&cb_pos->list, &cmpl_list->list); return -ENODEV; } else { cb_pos->buf_idx += mei_hdr->length; @@ -988,7 +977,7 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, struct mei_cl_cb *cb_pos, struct mei_cl *cl, - struct mei_io_list *cmpl_list) + struct mei_cl_cb *cmpl_list) { struct mei_msg_hdr *mei_hdr; @@ -1011,7 +1000,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, mei_hdr->length)) { dev->iamthif_state = MEI_IAMTHIF_IDLE; cl->status = -ENODEV; - list_del(&cb_pos->cb_list); + list_del(&cb_pos->list); return -ENODEV; } else { if (mei_flow_ctrl_reduce(dev, cl)) @@ -1023,8 +1012,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, dev->iamthif_flow_control_pending = true; /* save iamthif cb sent to amthi client */ dev->iamthif_current_cb = cb_pos; - list_move_tail(&cb_pos->cb_list, - &dev->write_waiting_list.mei_cb.cb_list); + list_move_tail(&cb_pos->list, &dev->write_waiting_list.list); } } else if (*slots == dev->hbuf_depth) { @@ -1044,7 +1032,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, dev->iamthif_msg_buf_index), mei_hdr->length)) { cl->status = -ENODEV; - list_del(&cb_pos->cb_list); + list_del(&cb_pos->list); } else { dev->iamthif_msg_buf_index += mei_hdr->length; } @@ -1066,7 +1054,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, * * returns 0 on success, <0 on failure. */ -static int mei_irq_thread_read_handler(struct mei_io_list *cmpl_list, +static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list, struct mei_device *dev, s32 *slots) { @@ -1169,14 +1157,13 @@ end: * * returns 0 on success, <0 on failure. */ -static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, - struct mei_device *dev, - s32 *slots) +static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, + struct mei_device *dev, s32 *slots) { struct mei_cl *cl; struct mei_cl_cb *pos = NULL, *next = NULL; - struct mei_io_list *list; + struct mei_cl_cb *list; int ret; if (!mei_hbuf_is_empty(dev)) { @@ -1191,20 +1178,19 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n"); list = &dev->write_waiting_list; - list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) { + list_for_each_entry_safe(pos, next, &list->list, list) { cl = (struct mei_cl *)pos->file_private; if (cl == NULL) continue; cl->status = 0; - list_del(&pos->cb_list); + list_del(&pos->list); if (MEI_WRITING == cl->writing_state && (pos->major_file_operations == MEI_WRITE) && (cl != &dev->iamthif_cl)) { dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n"); cl->writing_state = MEI_WRITE_COMPLETE; - list_add_tail(&pos->cb_list, - &cmpl_list->mei_cb.cb_list); + list_add_tail(&pos->list, &cmpl_list->list); } if (cl == &dev->iamthif_cl) { dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n"); @@ -1250,11 +1236,10 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, /* complete control write list CB */ dev_dbg(&dev->pdev->dev, "complete control write list cb.\n"); - list_for_each_entry_safe(pos, next, - &dev->ctrl_wr_list.mei_cb.cb_list, cb_list) { + list_for_each_entry_safe(pos, next, &dev->ctrl_wr_list.list, list) { cl = (struct mei_cl *) pos->file_private; if (!cl) { - list_del(&pos->cb_list); + list_del(&pos->list); return -ENODEV; } switch (pos->major_file_operations) { @@ -1289,8 +1274,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, } /* complete write list CB */ dev_dbg(&dev->pdev->dev, "complete write list cb.\n"); - list_for_each_entry_safe(pos, next, - &dev->write_list.mei_cb.cb_list, cb_list) { + list_for_each_entry_safe(pos, next, &dev->write_list.list, list) { cl = (struct mei_cl *)pos->file_private; if (cl == NULL) continue; @@ -1410,16 +1394,15 @@ void mei_timer(struct work_struct *work) dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n"); - amthi_complete_list = &dev->amthi_read_complete_list. - mei_cb.cb_list; + amthi_complete_list = &dev->amthi_read_complete_list.list; - list_for_each_entry_safe(cb_pos, cb_next, amthi_complete_list, cb_list) { + list_for_each_entry_safe(cb_pos, cb_next, amthi_complete_list, list) { cl_pos = cb_pos->file_object->private_data; /* Finding the AMTHI entry. */ if (cl_pos == &dev->iamthif_cl) - list_del(&cb_pos->cb_list); + list_del(&cb_pos->list); } if (dev->iamthif_current_cb) mei_free_cb_private(dev->iamthif_current_cb); @@ -1450,7 +1433,7 @@ out: irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) { struct mei_device *dev = (struct mei_device *) dev_id; - struct mei_io_list complete_list; + struct mei_cl_cb complete_list; struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL; struct mei_cl *cl; s32 slots; @@ -1530,14 +1513,13 @@ end: wake_up_interruptible(&dev->wait_recvd_msg); bus_message_received = false; } - if (list_empty(&complete_list.mei_cb.cb_list)) + if (list_empty(&complete_list.list)) return IRQ_HANDLED; - list_for_each_entry_safe(cb_pos, cb_next, - &complete_list.mei_cb.cb_list, cb_list) { + list_for_each_entry_safe(cb_pos, cb_next, &complete_list.list, list) { cl = (struct mei_cl *)cb_pos->file_private; - list_del(&cb_pos->cb_list); + list_del(&cb_pos->list); if (cl) { if (cl != &dev->iamthif_cl) { dev_dbg(&dev->pdev->dev, "completing call back.\n"); diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index 20652e140c4..4ff9eaf2add 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -104,7 +104,7 @@ int mei_ioctl_connect_client(struct file *file, rets = -ENOMEM; goto end; } - INIT_LIST_HEAD(&cb->cb_list); + mei_io_list_init(cb); cb->major_file_operations = MEI_IOCTL; @@ -193,9 +193,7 @@ int mei_ioctl_connect_client(struct file *file, dev_dbg(&dev->pdev->dev, "Sending connect message - succeeded\n"); cl->timer_count = MEI_CONNECT_TIMEOUT; cb->file_private = cl; - list_add_tail(&cb->cb_list, - &dev->ctrl_rd_list.mei_cb. - cb_list); + list_add_tail(&cb->list, &dev->ctrl_rd_list.list); } @@ -203,8 +201,7 @@ int mei_ioctl_connect_client(struct file *file, dev_dbg(&dev->pdev->dev, "Queuing the connect request due to device busy\n"); cb->file_private = cl; dev_dbg(&dev->pdev->dev, "add connect cb to control write list.\n"); - list_add_tail(&cb->cb_list, - &dev->ctrl_wr_list.mei_cb.cb_list); + list_add_tail(&cb->list, &dev->ctrl_wr_list.list); } mutex_unlock(&dev->device_lock); err = wait_event_timeout(dev->wait_recvd_msg, @@ -255,7 +252,7 @@ struct mei_cl_cb *find_amthi_read_list_entry( struct mei_cl_cb *next = NULL; list_for_each_entry_safe(pos, next, - &dev->amthi_read_complete_list.mei_cb.cb_list, cb_list) { + &dev->amthi_read_complete_list.list, list) { cl_temp = (struct mei_cl *)pos->file_private; if (cl_temp && cl_temp == &dev->iamthif_cl && pos->file_object == file) @@ -340,17 +337,17 @@ int amthi_read(struct mei_device *dev, struct file *file, if (time_after(jiffies, timeout)) { dev_dbg(&dev->pdev->dev, "amthi Time out\n"); /* 15 sec for the message has expired */ - list_del(&cb->cb_list); + list_del(&cb->list); rets = -ETIMEDOUT; goto free; } } /* if the whole message will fit remove it from the list */ if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset)) - list_del(&cb->cb_list); + list_del(&cb->list); else if (cb->buf_idx > 0 && cb->buf_idx <= *offset) { /* end of the message has been reached */ - list_del(&cb->cb_list); + list_del(&cb->list); rets = 0; goto free; } @@ -441,9 +438,9 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl) rets = -ENODEV; goto unlock; } - list_add_tail(&cb->cb_list, &dev->read_list.mei_cb.cb_list); + list_add_tail(&cb->list, &dev->read_list.list); } else { - list_add_tail(&cb->cb_list, &dev->ctrl_wr_list.mei_cb.cb_list); + list_add_tail(&cb->list, &dev->ctrl_wr_list.list); } return rets; unlock: @@ -510,13 +507,11 @@ int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb) dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n"); dev->iamthif_current_cb = cb; dev->iamthif_file_object = cb->file_object; - list_add_tail(&cb->cb_list, - &dev->write_waiting_list.mei_cb.cb_list); + list_add_tail(&cb->list, &dev->write_waiting_list.list); } else { dev_dbg(&dev->pdev->dev, "message does not complete, " "so add amthi cb to write list.\n"); - list_add_tail(&cb->cb_list, - &dev->write_list.mei_cb.cb_list); + list_add_tail(&cb->list, &dev->write_list.list); } } else { if (!(dev->mei_host_buffer_is_empty)) @@ -524,7 +519,7 @@ int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb) dev_dbg(&dev->pdev->dev, "No flow control credentials, " "so add iamthif cb to write list.\n"); - list_add_tail(&cb->cb_list, &dev->write_list.mei_cb.cb_list); + list_add_tail(&cb->list, &dev->write_list.list); } return 0; } @@ -556,9 +551,8 @@ void mei_run_next_iamthif_cmd(struct mei_device *dev) dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n"); - list_for_each_entry_safe(pos, next, - &dev->amthi_cmd_list.mei_cb.cb_list, cb_list) { - list_del(&pos->cb_list); + list_for_each_entry_safe(pos, next, &dev->amthi_cmd_list.list, list) { + list_del(&pos->list); cl_tmp = (struct mei_cl *)pos->file_private; if (cl_tmp && cl_tmp == &dev->iamthif_cl) { diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 8dcf59d43b0..2e46291b8b7 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -111,12 +111,12 @@ static bool mei_clear_list(struct mei_device *dev, bool removed = false; /* list all list member */ - list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, cb_list) { + list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) { file_temp = (struct file *)cb_pos->file_object; /* check if list member associated with a file */ if (file_temp == file) { /* remove member from the list */ - list_del(&cb_pos->cb_list); + list_del(&cb_pos->list); /* check if cb equal to current iamthif cb */ if (dev->iamthif_current_cb == cb_pos) { dev->iamthif_current_cb = NULL; @@ -148,20 +148,20 @@ static bool mei_clear_lists(struct mei_device *dev, struct file *file) bool removed = false; /* remove callbacks associated with a file */ - mei_clear_list(dev, file, &dev->amthi_cmd_list.mei_cb.cb_list); + mei_clear_list(dev, file, &dev->amthi_cmd_list.list); if (mei_clear_list(dev, file, - &dev->amthi_read_complete_list.mei_cb.cb_list)) + &dev->amthi_read_complete_list.list)) removed = true; - mei_clear_list(dev, file, &dev->ctrl_rd_list.mei_cb.cb_list); + mei_clear_list(dev, file, &dev->ctrl_rd_list.list); - if (mei_clear_list(dev, file, &dev->ctrl_wr_list.mei_cb.cb_list)) + if (mei_clear_list(dev, file, &dev->ctrl_wr_list.list)) removed = true; - if (mei_clear_list(dev, file, &dev->write_waiting_list.mei_cb.cb_list)) + if (mei_clear_list(dev, file, &dev->write_waiting_list.list)) removed = true; - if (mei_clear_list(dev, file, &dev->write_list.mei_cb.cb_list)) + if (mei_clear_list(dev, file, &dev->write_list.list)) removed = true; /* check if iamthif_current_cb not NULL */ @@ -192,8 +192,7 @@ static struct mei_cl_cb *find_read_list_entry( struct mei_cl_cb *next = NULL; dev_dbg(&dev->pdev->dev, "remove read_list CB\n"); - list_for_each_entry_safe(pos, next, - &dev->read_list.mei_cb.cb_list, cb_list) { + list_for_each_entry_safe(pos, next, &dev->read_list.list, list) { struct mei_cl *cl_temp; cl_temp = (struct mei_cl *)pos->file_private; @@ -324,7 +323,7 @@ static int mei_release(struct inode *inode, struct file *file) cb = find_read_list_entry(dev, cl); /* Remove entry from read list */ if (cb) - list_del(&cb->cb_list); + list_del(&cb->list); cb = cl->read_cb; cl->read_cb = NULL; @@ -504,7 +503,7 @@ free: cb_pos = find_read_list_entry(dev, cl); /* Remove entry from read list */ if (cb_pos) - list_del(&cb_pos->cb_list); + list_del(&cb_pos->list); mei_free_cb_private(cb); cl->reading_state = MEI_IDLE; cl->read_cb = NULL; @@ -534,7 +533,7 @@ static struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp) if (!cb) return NULL; - INIT_LIST_HEAD(&cb->cb_list); + mei_io_list_init(cb); cb->file_object = fp; cb->file_private = cl; @@ -651,7 +650,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (time_after(jiffies, timeout) || cl->reading_state == MEI_READ_COMPLETE) { *offset = 0; - list_del(&write_cb->cb_list); + list_del(&write_cb->list); mei_free_cb_private(write_cb); write_cb = NULL; } @@ -663,7 +662,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, *offset = 0; write_cb = find_read_list_entry(dev, cl); if (write_cb) { - list_del(&write_cb->cb_list); + list_del(&write_cb->list); mei_free_cb_private(write_cb); write_cb = NULL; cl->reading_state = MEI_IDLE; @@ -707,13 +706,12 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, write_cb->major_file_operations = MEI_IOCTL; - if (!list_empty(&dev->amthi_cmd_list.mei_cb.cb_list) || + if (!list_empty(&dev->amthi_cmd_list.list) || dev->iamthif_state != MEI_IAMTHIF_IDLE) { dev_dbg(&dev->pdev->dev, "amthi_state = %d\n", (int) dev->iamthif_state); dev_dbg(&dev->pdev->dev, "add amthi cb to amthi cmd waiting list\n"); - list_add_tail(&write_cb->cb_list, - &dev->amthi_cmd_list.mei_cb.cb_list); + list_add_tail(&write_cb->list, &dev->amthi_cmd_list.list); } else { dev_dbg(&dev->pdev->dev, "call amthi write\n"); rets = amthi_write(dev, write_cb); @@ -764,19 +762,16 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, rets = -ENODEV; goto unlock_dev; } - list_add_tail(&write_cb->cb_list, - &dev->write_waiting_list.mei_cb.cb_list); + list_add_tail(&write_cb->list, &dev->write_waiting_list.list); } else { - list_add_tail(&write_cb->cb_list, - &dev->write_list.mei_cb.cb_list); + list_add_tail(&write_cb->list, &dev->write_list.list); } } else { write_cb->buf_idx = 0; cl->writing_state = MEI_WRITING; - list_add_tail(&write_cb->cb_list, - &dev->write_list.mei_cb.cb_list); + list_add_tail(&write_cb->list, &dev->write_list.list); } mutex_unlock(&dev->device_lock); return length; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index c58b6fa06c0..de5babc5c8e 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -144,7 +144,7 @@ struct mei_message_data { struct mei_cl_cb { - struct list_head cb_list; + struct list_head list; enum mei_cb_major_types major_file_operations; void *file_private; struct mei_message_data request_buffer; @@ -175,10 +175,6 @@ struct mei_cl { struct mei_cl_cb *read_cb; }; -struct mei_io_list { - struct mei_cl_cb mei_cb; -}; - /** * struct mei_deive - MEI private device struct * @hbuf_depth - depth of host(write) buffer @@ -189,15 +185,15 @@ struct mei_device { * lists of queues */ /* array of pointers to aio lists */ - struct mei_io_list read_list; /* driver read queue */ - struct mei_io_list write_list; /* driver write queue */ - struct mei_io_list write_waiting_list; /* write waiting queue */ - struct mei_io_list ctrl_wr_list; /* managed write IOCTL list */ - struct mei_io_list ctrl_rd_list; /* managed read IOCTL list */ - struct mei_io_list amthi_cmd_list; /* amthi list for cmd waiting */ + struct mei_cl_cb read_list; /* driver read queue */ + struct mei_cl_cb write_list; /* driver write queue */ + struct mei_cl_cb write_waiting_list; /* write waiting queue */ + struct mei_cl_cb ctrl_wr_list; /* managed write IOCTL list */ + struct mei_cl_cb ctrl_rd_list; /* managed read IOCTL list */ + struct mei_cl_cb amthi_cmd_list; /* amthi list for cmd waiting */ /* driver managed amthi list for reading completed amthi cmd data */ - struct mei_io_list amthi_read_complete_list; + struct mei_cl_cb amthi_read_complete_list; /* * list of files */ @@ -297,8 +293,16 @@ int mei_me_cl_by_id(struct mei_device *dev, u8 client_id); /* * MEI IO List Functions */ -void mei_io_list_init(struct mei_io_list *list); -void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl); +/** + * mei_io_list_init - Sets up a queue list. + * + * @list: An instance cl callback structure + */ +static inline void mei_io_list_init(struct mei_cl_cb *list) +{ + INIT_LIST_HEAD(&list->list); +} +void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl); /* * MEI ME Client Functions -- cgit v1.2.3 From 601a1efa630aab0ca72bf8d638c441a09654b250 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 9 Oct 2012 16:50:20 +0200 Subject: mei: rename mei_free_cb_private to mei_io_cb_free 1. cb_private was an old name that we depriacated in earlier cleanups 2. we also group the funcion declaration with other _io_ functions 3. Don't check cb for NULL as mei_io_cb_free is NULL safe Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/init.c | 4 ++-- drivers/misc/mei/interrupt.c | 12 +++++------- drivers/misc/mei/iorw.c | 35 ++++++++++++++++++----------------- drivers/misc/mei/main.c | 14 +++++++------- drivers/misc/mei/mei_dev.h | 5 +++-- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 2275cf03bad..4666f0ba350 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -341,7 +341,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) /* remove all waiting requests */ list_for_each_entry_safe(cb_pos, cb_next, &dev->write_list.list, list) { list_del(&cb_pos->list); - mei_free_cb_private(cb_pos); + mei_io_cb_free(cb_pos); } } @@ -715,7 +715,7 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) mei_io_list_flush(&dev->ctrl_rd_list, cl); mei_io_list_flush(&dev->ctrl_wr_list, cl); free: - mei_free_cb_private(cb); + mei_io_cb_free(cb); return rets; } diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 54d6f1a1dbc..5c65bac2fde 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -58,7 +58,7 @@ irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id) static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos) { if (cb_pos->major_file_operations == MEI_WRITE) { - mei_free_cb_private(cb_pos); + mei_io_cb_free(cb_pos); cb_pos = NULL; cl->writing_state = MEI_WRITE_COMPLETE; if (waitqueue_active(&cl->tx_wait)) @@ -1368,11 +1368,10 @@ void mei_timer(struct work_struct *work) dev->iamthif_state = MEI_IAMTHIF_IDLE; dev->iamthif_timer = 0; - if (dev->iamthif_current_cb) - mei_free_cb_private(dev->iamthif_current_cb); + mei_io_cb_free(dev->iamthif_current_cb); + dev->iamthif_current_cb = NULL; dev->iamthif_file_object = NULL; - dev->iamthif_current_cb = NULL; mei_run_next_iamthif_cmd(dev); } } @@ -1404,12 +1403,11 @@ void mei_timer(struct work_struct *work) if (cl_pos == &dev->iamthif_cl) list_del(&cb_pos->list); } - if (dev->iamthif_current_cb) - mei_free_cb_private(dev->iamthif_current_cb); + mei_io_cb_free(dev->iamthif_current_cb); + dev->iamthif_current_cb = NULL; dev->iamthif_file_object->private_data = NULL; dev->iamthif_file_object = NULL; - dev->iamthif_current_cb = NULL; dev->iamthif_timer = 0; mei_run_next_iamthif_cmd(dev); diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index 4ff9eaf2add..2891bc44f9d 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -38,6 +38,21 @@ #include #include "interface.h" +/** + * mei_io_cb_free - free mei_cb_private related memory + * + * @cb: mei callback struct + */ +void mei_io_cb_free(struct mei_cl_cb *cb) +{ + if (cb == NULL) + return; + + kfree(cb->request_buffer.data); + kfree(cb->response_buffer.data); + kfree(cb); +} + /** * mei_me_cl_by_id return index to me_clients for client_id * @@ -231,7 +246,7 @@ int mei_ioctl_connect_client(struct file *file, rets = 0; end: dev_dbg(&dev->pdev->dev, "free connect cb memory."); - kfree(cb); + mei_io_cb_free(cb); return rets; } @@ -375,7 +390,7 @@ int amthi_read(struct mei_device *dev, struct file *file, free: dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n"); *offset = 0; - mei_free_cb_private(cb); + mei_io_cb_free(cb); out: return rets; } @@ -444,7 +459,7 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl) } return rets; unlock: - mei_free_cb_private(cb); + mei_io_cb_free(cb); return rets; } @@ -568,17 +583,3 @@ void mei_run_next_iamthif_cmd(struct mei_device *dev) } } -/** - * mei_free_cb_private - free mei_cb_private related memory - * - * @cb: mei callback struct - */ -void mei_free_cb_private(struct mei_cl_cb *cb) -{ - if (cb == NULL) - return; - - kfree(cb->request_buffer.data); - kfree(cb->response_buffer.data); - kfree(cb); -} diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 2e46291b8b7..518e07eb107 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -124,7 +124,7 @@ static bool mei_clear_list(struct mei_device *dev, mei_send_flow_control(dev, &dev->iamthif_cl); } /* free all allocated buffers */ - mei_free_cb_private(cb_pos); + mei_io_cb_free(cb_pos); cb_pos = NULL; removed = true; } @@ -169,7 +169,7 @@ static bool mei_clear_lists(struct mei_device *dev, struct file *file) /* check file and iamthif current cb association */ if (dev->iamthif_current_cb->file_object == file) { /* remove cb */ - mei_free_cb_private(dev->iamthif_current_cb); + mei_io_cb_free(dev->iamthif_current_cb); dev->iamthif_current_cb = NULL; removed = true; } @@ -332,7 +332,7 @@ static int mei_release(struct inode *inode, struct file *file) file->private_data = NULL; if (cb) { - mei_free_cb_private(cb); + mei_io_cb_free(cb); cb = NULL; } @@ -504,7 +504,7 @@ free: /* Remove entry from read list */ if (cb_pos) list_del(&cb_pos->list); - mei_free_cb_private(cb); + mei_io_cb_free(cb); cl->reading_state = MEI_IDLE; cl->read_cb = NULL; cl->read_pending = 0; @@ -651,7 +651,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, cl->reading_state == MEI_READ_COMPLETE) { *offset = 0; list_del(&write_cb->list); - mei_free_cb_private(write_cb); + mei_io_cb_free(write_cb); write_cb = NULL; } } @@ -663,7 +663,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, write_cb = find_read_list_entry(dev, cl); if (write_cb) { list_del(&write_cb->list); - mei_free_cb_private(write_cb); + mei_io_cb_free(write_cb); write_cb = NULL; cl->reading_state = MEI_IDLE; cl->read_cb = NULL; @@ -778,7 +778,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, unlock_dev: mutex_unlock(&dev->device_lock); - mei_free_cb_private(write_cb); + mei_io_cb_free(write_cb); return rets; } diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index de5babc5c8e..4545a9ebd79 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -291,8 +291,10 @@ int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid); int mei_me_cl_by_id(struct mei_device *dev, u8 client_id); /* - * MEI IO List Functions + * MEI IO Functions */ +void mei_io_cb_free(struct mei_cl_cb *priv_cb); + /** * mei_io_list_init - Sets up a queue list. * @@ -361,7 +363,6 @@ struct mei_cl_cb *find_amthi_read_list_entry(struct mei_device *dev, void mei_run_next_iamthif_cmd(struct mei_device *dev); -void mei_free_cb_private(struct mei_cl_cb *priv_cb); /* -- cgit v1.2.3 From 664df38b3c74656261d4227b4dd380cfa453f78f Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 11 Oct 2012 16:35:08 +0200 Subject: mei: use mei_io_cb_ warppers also for control flows move the mei_io_cb_ wrappers to to iorw.c for global use and use them also for handling control flows Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/init.c | 4 +- drivers/misc/mei/iorw.c | 117 ++++++++++++++++++++++++++++++++++----------- drivers/misc/mei/main.c | 78 ------------------------------ drivers/misc/mei/mei_dev.h | 4 ++ 4 files changed, 94 insertions(+), 109 deletions(-) diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 4666f0ba350..1f13eb97a10 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -668,12 +668,10 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) if (cl->state != MEI_FILE_DISCONNECTING) return 0; - cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); + cb = mei_io_cb_init(cl, NULL); if (!cb) return -ENOMEM; - mei_io_list_init(cb); - cb->file_private = cl; cb->major_file_operations = MEI_CLOSE; if (dev->mei_host_buffer_is_empty) { dev->mei_host_buffer_is_empty = false; diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index 2891bc44f9d..541c157f325 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -52,6 +52,80 @@ void mei_io_cb_free(struct mei_cl_cb *cb) kfree(cb->response_buffer.data); kfree(cb); } +/** + * mei_io_cb_init - allocate and initialize io callback + * + * @cl - mei client + * @file: pointer to file structure + * + * returns mei_cl_cb pointer or NULL; + */ +struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp) +{ + struct mei_cl_cb *cb; + + cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); + if (!cb) + return NULL; + + mei_io_list_init(cb); + + cb->file_object = fp; + cb->file_private = cl; + cb->buf_idx = 0; + return cb; +} + + +/** + * mei_io_cb_alloc_req_buf - allocate request buffer + * + * @cb - io callback structure + * @size: size of the buffer + * + * returns 0 on success + * -EINVAL if cb is NULL + * -ENOMEM if allocation failed + */ +int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length) +{ + if (!cb) + return -EINVAL; + + if (length == 0) + return 0; + + cb->request_buffer.data = kmalloc(length, GFP_KERNEL); + if (!cb->request_buffer.data) + return -ENOMEM; + cb->request_buffer.size = length; + return 0; +} +/** + * mei_io_cb_alloc_req_buf - allocate respose buffer + * + * @cb - io callback structure + * @size: size of the buffer + * + * returns 0 on success + * -EINVAL if cb is NULL + * -ENOMEM if allocation failed + */ +int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length) +{ + if (!cb) + return -EINVAL; + + if (length == 0) + return 0; + + cb->response_buffer.data = kmalloc(length, GFP_KERNEL); + if (!cb->response_buffer.data) + return -ENOMEM; + cb->response_buffer.size = length; + return 0; +} + /** * mei_me_cl_by_id return index to me_clients for client_id @@ -112,14 +186,12 @@ int mei_ioctl_connect_client(struct file *file, dev_dbg(&dev->pdev->dev, "mei_ioctl_connect_client() Entry\n"); - /* buffered ioctl cb */ - cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); + cb = mei_io_cb_init(cl, file); if (!cb) { rets = -ENOMEM; goto end; } - mei_io_list_init(cb); cb->major_file_operations = MEI_IOCTL; @@ -207,14 +279,12 @@ int mei_ioctl_connect_client(struct file *file, } else { dev_dbg(&dev->pdev->dev, "Sending connect message - succeeded\n"); cl->timer_count = MEI_CONNECT_TIMEOUT; - cb->file_private = cl; list_add_tail(&cb->list, &dev->ctrl_rd_list.list); } } else { dev_dbg(&dev->pdev->dev, "Queuing the connect request due to device busy\n"); - cb->file_private = cl; dev_dbg(&dev->pdev->dev, "add connect cb to control write list.\n"); list_add_tail(&cb->list, &dev->ctrl_wr_list.list); } @@ -407,7 +477,7 @@ out: int mei_start_read(struct mei_device *dev, struct mei_cl *cl) { struct mei_cl_cb *cb; - int rets = 0; + int rets; int i; if (cl->state != MEI_FILE_CONNECTED) @@ -416,49 +486,40 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl) if (dev->dev_state != MEI_DEV_ENABLED) return -ENODEV; - dev_dbg(&dev->pdev->dev, "check if read is pending.\n"); if (cl->read_pending || cl->read_cb) { dev_dbg(&dev->pdev->dev, "read is pending.\n"); return -EBUSY; } + i = mei_me_cl_by_id(dev, cl->me_client_id); + if (i < 0) { + dev_err(&dev->pdev->dev, "no such me client %d\n", + cl->me_client_id); + return -ENODEV; + } - cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); + cb = mei_io_cb_init(cl, NULL); if (!cb) return -ENOMEM; - dev_dbg(&dev->pdev->dev, "allocation call back successful. host client = %d, ME client = %d\n", - cl->host_client_id, cl->me_client_id); - i = mei_me_cl_by_id(dev, cl->me_client_id); - if (i < 0) { - rets = -ENODEV; - goto unlock; - } + rets = mei_io_cb_alloc_resp_buf(cb, + dev->me_clients[i].props.max_msg_length); + if (rets) + goto err; - cb->response_buffer.size = dev->me_clients[i].props.max_msg_length; - cb->response_buffer.data = - kmalloc(cb->response_buffer.size, GFP_KERNEL); - if (!cb->response_buffer.data) { - rets = -ENOMEM; - goto unlock; - } - dev_dbg(&dev->pdev->dev, "allocation call back data success.\n"); cb->major_file_operations = MEI_READ; - /* make sure buffer index is zero before we start */ - cb->buf_idx = 0; - cb->file_private = (void *) cl; cl->read_cb = cb; if (dev->mei_host_buffer_is_empty) { dev->mei_host_buffer_is_empty = false; if (mei_send_flow_control(dev, cl)) { rets = -ENODEV; - goto unlock; + goto err; } list_add_tail(&cb->list, &dev->read_list.list); } else { list_add_tail(&cb->list, &dev->ctrl_wr_list.list); } return rets; -unlock: +err: mei_io_cb_free(cb); return rets; } diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 518e07eb107..ed4943f6b6c 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -513,84 +513,6 @@ out: mutex_unlock(&dev->device_lock); return rets; } - -/** - * mei_io_cb_init - allocate and initialize io callback - * - * @cl - mei client - * @file: pointer to file structure - * - * returns mei_cl_cb pointer or NULL; - */ -static struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp) -{ - struct mei_cl_cb *cb; - struct mei_device *dev; - - dev = cl->dev; - - cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL); - if (!cb) - return NULL; - - mei_io_list_init(cb); - - cb->file_object = fp; - cb->file_private = cl; - cb->buf_idx = 0; - return cb; -} - - -/** - * mei_io_cb_alloc_req_buf - allocate request buffer - * - * @cb - io callback structure - * @size: size of the buffer - * - * returns 0 on success - * -EINVAL if cb is NULL - * -ENOMEM if allocation failed - */ -static int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length) -{ - if (!cb) - return -EINVAL; - - if (length == 0) - return 0; - - cb->request_buffer.data = kmalloc(length, GFP_KERNEL); - if (!cb->request_buffer.data) - return -ENOMEM; - cb->request_buffer.size = length; - return 0; -} -/** - * mei_io_cb_alloc_req_buf - allocate respose buffer - * - * @cb - io callback structure - * @size: size of the buffer - * - * returns 0 on success - * -EINVAL if cb is NULL - * -ENOMEM if allocation failed - */ -static int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length) -{ - if (!cb) - return -EINVAL; - - if (length == 0) - return 0; - - cb->response_buffer.data = kmalloc(length, GFP_KERNEL); - if (!cb->response_buffer.data) - return -ENOMEM; - cb->response_buffer.size = length; - return 0; -} - /** * mei_write - the write function. * diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 4545a9ebd79..6adcb3f6621 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -293,7 +293,11 @@ int mei_me_cl_by_id(struct mei_device *dev, u8 client_id); /* * MEI IO Functions */ +struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp); void mei_io_cb_free(struct mei_cl_cb *priv_cb); +int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length); +int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length); + /** * mei_io_list_init - Sets up a queue list. -- cgit v1.2.3 From 0a0c3b5a24bd802b1ebbf99e0b01296647b8199b Mon Sep 17 00:00:00 2001 From: Damian Hobson-Garcia Date: Tue, 25 Sep 2012 15:09:11 +0900 Subject: Add new uio device for dynamic memory allocation This device extends the uio_pdrv_genirq driver to provide limited dynamic memory allocation for UIO devices. This allows UIO devices to use CMA and IOMMU allocated memory regions. This driver is based on the uio_pdrv_genirq driver and provides the same generic interrupt handling capabilities. Like uio_prdv_genirq, a fixed number of memory regions, defined in the platform device's .resources field are exported to userpace. This driver adds the ability to export additional regions whose number and size are known at boot time, but whose memory is not allocated until the uio device file is opened for the first time. When the device file is closed, the allocated memory block is freed. Physical (DMA) addresses for the dynamic regions are provided to the userspace via /sys/class/uio/uioX/maps/mapY/addr in the same way as static addresses are when the uio device file is open, when no processes are holding the device file open, the address returned to userspace is DMA_ERROR_CODE. Signed-off-by: Damian Hobson-Garcia Signed-off-by: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman --- drivers/uio/Kconfig | 16 ++ drivers/uio/Makefile | 1 + drivers/uio/uio_dmem_genirq.c | 354 ++++++++++++++++++++++++++ include/linux/platform_data/uio_dmem_genirq.h | 26 ++ 4 files changed, 397 insertions(+) create mode 100644 drivers/uio/uio_dmem_genirq.c create mode 100644 include/linux/platform_data/uio_dmem_genirq.h diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig index 6f3ea9bbc81..82e2b89d448 100644 --- a/drivers/uio/Kconfig +++ b/drivers/uio/Kconfig @@ -44,6 +44,22 @@ config UIO_PDRV_GENIRQ If you don't know what to do here, say N. +config UIO_DMEM_GENIRQ + tristate "Userspace platform driver with generic irq and dynamic memory" + help + Platform driver for Userspace I/O devices, including generic + interrupt handling code. Shared interrupts are not supported. + + Memory regions can be specified with the same platform device + resources as the UIO_PDRV drivers, but dynamic regions can also + be specified. + The number and size of these regions is static, + but the memory allocation is not performed until + the associated device file is opened. The + memory is freed once the uio device is closed. + + If you don't know what to do here, say N. + config UIO_AEC tristate "AEC video timestamp device" depends on PCI diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile index d4dd9a5552f..b354c539507 100644 --- a/drivers/uio/Makefile +++ b/drivers/uio/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_UIO) += uio.o obj-$(CONFIG_UIO_CIF) += uio_cif.o obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o +obj-$(CONFIG_UIO_DMEM_GENIRQ) += uio_dmem_genirq.o obj-$(CONFIG_UIO_AEC) += uio_aec.o obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o obj-$(CONFIG_UIO_PCI_GENERIC) += uio_pci_generic.o diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c new file mode 100644 index 00000000000..4d4dd008c8b --- /dev/null +++ b/drivers/uio/uio_dmem_genirq.c @@ -0,0 +1,354 @@ +/* + * drivers/uio/uio_dmem_genirq.c + * + * Userspace I/O platform driver with generic IRQ handling code. + * + * Copyright (C) 2012 Damian Hobson-Garcia + * + * Based on uio_pdrv_genirq.c by Magnus Damm + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define DRIVER_NAME "uio_dmem_genirq" + +struct uio_dmem_genirq_platdata { + struct uio_info *uioinfo; + spinlock_t lock; + unsigned long flags; + struct platform_device *pdev; + unsigned int dmem_region_start; + unsigned int num_dmem_regions; + struct mutex alloc_lock; + unsigned int refcnt; +}; + +static int uio_dmem_genirq_open(struct uio_info *info, struct inode *inode) +{ + struct uio_dmem_genirq_platdata *priv = info->priv; + struct uio_mem *uiomem; + int ret = 0; + + uiomem = &priv->uioinfo->mem[priv->dmem_region_start]; + + mutex_lock(&priv->alloc_lock); + while (!priv->refcnt && uiomem < &priv->uioinfo->mem[MAX_UIO_MAPS]) { + void *addr; + if (!uiomem->size) + break; + + addr = dma_alloc_coherent(&priv->pdev->dev, uiomem->size, + (dma_addr_t *)&uiomem->addr, GFP_KERNEL); + if (!addr) { + ret = -ENOMEM; + break; + } + + uiomem->internal_addr = addr; + ++uiomem; + } + priv->refcnt++; + + mutex_unlock(&priv->alloc_lock); + /* Wait until the Runtime PM code has woken up the device */ + pm_runtime_get_sync(&priv->pdev->dev); + return ret; +} + +static int uio_dmem_genirq_release(struct uio_info *info, struct inode *inode) +{ + struct uio_dmem_genirq_platdata *priv = info->priv; + struct uio_mem *uiomem; + + /* Tell the Runtime PM code that the device has become idle */ + pm_runtime_put_sync(&priv->pdev->dev); + + uiomem = &priv->uioinfo->mem[priv->dmem_region_start]; + + mutex_lock(&priv->alloc_lock); + + priv->refcnt--; + while (!priv->refcnt && uiomem < &priv->uioinfo->mem[MAX_UIO_MAPS]) { + if (!uiomem->size) + break; + + dma_free_coherent(&priv->pdev->dev, uiomem->size, + uiomem->internal_addr, uiomem->addr); + uiomem->addr = DMA_ERROR_CODE; + ++uiomem; + } + + mutex_unlock(&priv->alloc_lock); + return 0; +} + +static irqreturn_t uio_dmem_genirq_handler(int irq, struct uio_info *dev_info) +{ + struct uio_dmem_genirq_platdata *priv = dev_info->priv; + + /* Just disable the interrupt in the interrupt controller, and + * remember the state so we can allow user space to enable it later. + */ + + if (!test_and_set_bit(0, &priv->flags)) + disable_irq_nosync(irq); + + return IRQ_HANDLED; +} + +static int uio_dmem_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on) +{ + struct uio_dmem_genirq_platdata *priv = dev_info->priv; + unsigned long flags; + + /* Allow user space to enable and disable the interrupt + * in the interrupt controller, but keep track of the + * state to prevent per-irq depth damage. + * + * Serialize this operation to support multiple tasks. + */ + + spin_lock_irqsave(&priv->lock, flags); + if (irq_on) { + if (test_and_clear_bit(0, &priv->flags)) + enable_irq(dev_info->irq); + } else { + if (!test_and_set_bit(0, &priv->flags)) + disable_irq(dev_info->irq); + } + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static int uio_dmem_genirq_probe(struct platform_device *pdev) +{ + struct uio_dmem_genirq_pdata *pdata = pdev->dev.platform_data; + struct uio_info *uioinfo = &pdata->uioinfo; + struct uio_dmem_genirq_platdata *priv; + struct uio_mem *uiomem; + int ret = -EINVAL; + int i; + + if (!uioinfo) { + int irq; + + /* alloc uioinfo for one device */ + uioinfo = kzalloc(sizeof(*uioinfo), GFP_KERNEL); + if (!uioinfo) { + ret = -ENOMEM; + dev_err(&pdev->dev, "unable to kmalloc\n"); + goto bad2; + } + uioinfo->name = pdev->dev.of_node->name; + uioinfo->version = "devicetree"; + + /* Multiple IRQs are not supported */ + irq = platform_get_irq(pdev, 0); + if (irq == -ENXIO) + uioinfo->irq = UIO_IRQ_NONE; + else + uioinfo->irq = irq; + } + + if (!uioinfo || !uioinfo->name || !uioinfo->version) { + dev_err(&pdev->dev, "missing platform_data\n"); + goto bad0; + } + + if (uioinfo->handler || uioinfo->irqcontrol || + uioinfo->irq_flags & IRQF_SHARED) { + dev_err(&pdev->dev, "interrupt configuration error\n"); + goto bad0; + } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + dev_err(&pdev->dev, "unable to kmalloc\n"); + goto bad0; + } + + dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + + priv->uioinfo = uioinfo; + spin_lock_init(&priv->lock); + priv->flags = 0; /* interrupt is enabled to begin with */ + priv->pdev = pdev; + mutex_init(&priv->alloc_lock); + + if (!uioinfo->irq) { + ret = platform_get_irq(pdev, 0); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get IRQ\n"); + goto bad0; + } + uioinfo->irq = ret; + } + uiomem = &uioinfo->mem[0]; + + for (i = 0; i < pdev->num_resources; ++i) { + struct resource *r = &pdev->resource[i]; + + if (r->flags != IORESOURCE_MEM) + continue; + + if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) { + dev_warn(&pdev->dev, "device has more than " + __stringify(MAX_UIO_MAPS) + " I/O memory resources.\n"); + break; + } + + uiomem->memtype = UIO_MEM_PHYS; + uiomem->addr = r->start; + uiomem->size = resource_size(r); + ++uiomem; + } + + priv->dmem_region_start = i; + priv->num_dmem_regions = pdata->num_dynamic_regions; + + for (i = 0; i < pdata->num_dynamic_regions; ++i) { + if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) { + dev_warn(&pdev->dev, "device has more than " + __stringify(MAX_UIO_MAPS) + " dynamic and fixed memory regions.\n"); + break; + } + uiomem->memtype = UIO_MEM_PHYS; + uiomem->addr = DMA_ERROR_CODE; + uiomem->size = pdata->dynamic_region_sizes[i]; + ++uiomem; + } + + while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) { + uiomem->size = 0; + ++uiomem; + } + + /* This driver requires no hardware specific kernel code to handle + * interrupts. Instead, the interrupt handler simply disables the + * interrupt in the interrupt controller. User space is responsible + * for performing hardware specific acknowledge and re-enabling of + * the interrupt in the interrupt controller. + * + * Interrupt sharing is not supported. + */ + + uioinfo->handler = uio_dmem_genirq_handler; + uioinfo->irqcontrol = uio_dmem_genirq_irqcontrol; + uioinfo->open = uio_dmem_genirq_open; + uioinfo->release = uio_dmem_genirq_release; + uioinfo->priv = priv; + + /* Enable Runtime PM for this device: + * The device starts in suspended state to allow the hardware to be + * turned off by default. The Runtime PM bus code should power on the + * hardware and enable clocks at open(). + */ + pm_runtime_enable(&pdev->dev); + + ret = uio_register_device(&pdev->dev, priv->uioinfo); + if (ret) { + dev_err(&pdev->dev, "unable to register uio device\n"); + goto bad1; + } + + platform_set_drvdata(pdev, priv); + return 0; + bad1: + kfree(priv); + pm_runtime_disable(&pdev->dev); + bad0: + /* kfree uioinfo for OF */ + if (pdev->dev.of_node) + kfree(uioinfo); + bad2: + return ret; +} + +static int uio_dmem_genirq_remove(struct platform_device *pdev) +{ + struct uio_dmem_genirq_platdata *priv = platform_get_drvdata(pdev); + + uio_unregister_device(priv->uioinfo); + pm_runtime_disable(&pdev->dev); + + priv->uioinfo->handler = NULL; + priv->uioinfo->irqcontrol = NULL; + + /* kfree uioinfo for OF */ + if (pdev->dev.of_node) + kfree(priv->uioinfo); + + kfree(priv); + return 0; +} + +static int uio_dmem_genirq_runtime_nop(struct device *dev) +{ + /* Runtime PM callback shared between ->runtime_suspend() + * and ->runtime_resume(). Simply returns success. + * + * In this driver pm_runtime_get_sync() and pm_runtime_put_sync() + * are used at open() and release() time. This allows the + * Runtime PM code to turn off power to the device while the + * device is unused, ie before open() and after release(). + * + * This Runtime PM callback does not need to save or restore + * any registers since user space is responsbile for hardware + * register reinitialization after open(). + */ + return 0; +} + +static const struct dev_pm_ops uio_dmem_genirq_dev_pm_ops = { + .runtime_suspend = uio_dmem_genirq_runtime_nop, + .runtime_resume = uio_dmem_genirq_runtime_nop, +}; + +#ifdef CONFIG_OF +static const struct of_device_id uio_of_genirq_match[] = { + { /* empty for now */ }, +}; +MODULE_DEVICE_TABLE(of, uio_of_genirq_match); +#else +# define uio_of_genirq_match NULL +#endif + +static struct platform_driver uio_dmem_genirq = { + .probe = uio_dmem_genirq_probe, + .remove = uio_dmem_genirq_remove, + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .pm = &uio_dmem_genirq_dev_pm_ops, + .of_match_table = uio_of_genirq_match, + }, +}; + +module_platform_driver(uio_dmem_genirq); + +MODULE_AUTHOR("Damian Hobson-Garcia"); +MODULE_DESCRIPTION("Userspace I/O platform driver with dynamic memory."); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/include/linux/platform_data/uio_dmem_genirq.h b/include/linux/platform_data/uio_dmem_genirq.h new file mode 100644 index 00000000000..973c1bb3216 --- /dev/null +++ b/include/linux/platform_data/uio_dmem_genirq.h @@ -0,0 +1,26 @@ +/* + * include/linux/platform_data/uio_dmem_genirq.h + * + * Copyright (C) 2012 Damian Hobson-Garcia + * + * 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 version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _UIO_DMEM_GENIRQ_H +#define _UIO_DMEM_GENIRQ_H + +#include + +struct uio_dmem_genirq_pdata { + struct uio_info uioinfo; + unsigned int *dynamic_region_sizes; + unsigned int num_dynamic_regions; +}; +#endif /* _UIO_DMEM_GENIRQ_H */ -- cgit v1.2.3 From b533a83008c3fb4983c1213276790cacd39b518f Mon Sep 17 00:00:00 2001 From: Damian Hobson-Garcia Date: Tue, 25 Sep 2012 15:09:12 +0900 Subject: Add uio_dmem_genirq description to UIO documentation Signed-off-by: Damian Hobson-Garcia Signed-off-by: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman --- Documentation/DocBook/uio-howto.tmpl | 56 ++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl index ac3d0018140..fdbf86fcfcc 100644 --- a/Documentation/DocBook/uio-howto.tmpl +++ b/Documentation/DocBook/uio-howto.tmpl @@ -719,6 +719,62 @@ framework to set up sysfs files for this region. Simply leave it alone. + +Using uio_dmem_genirq for platform devices + + In addition to statically allocated memory ranges, they may also be + a desire to use dynamically allocated regions in a user space driver. + In particular, being able to access memory made available through the + dma-mapping API, may be particularly useful. The + uio_dmem_genirq driver provides a way to accomplish + this. + + + This driver is used in a similar manner to the + "uio_pdrv_genirq" driver with respect to interrupt + configuration and handling. + + + Set the .name element of + struct platform_device to + "uio_dmem_genirq" to use this driver. + + + When using this driver, fill in the .platform_data + element of struct platform_device, which is of type + struct uio_dmem_genirq_pdata and which contains the + following elements: + + + struct uio_info uioinfo: The same + structure used as the uio_pdrv_genirq platform + data + unsigned int *dynamic_region_sizes: + Pointer to list of sizes of dynamic memory regions to be mapped into + user space. + + unsigned int num_dynamic_regions: + Number of elements in dynamic_region_sizes array. + + + + The dynamic regions defined in the platform data will be appended to + the mem[] array after the platform device + resources, which implies that the total number of static and dynamic + memory regions cannot exceed MAX_UIO_MAPS. + + + The dynamic memory regions will be allocated when the UIO device file, + /dev/uioX is opened. + Simiar to static memory resources, the memory region information for + dynamic regions is then visible via sysfs at + /sys/class/uio/uioX/maps/mapY/*. + The dynmaic memory regions will be freed when the UIO device file is + closed. When no processes are holding the device file open, the address + returned to userspace is DMA_ERROR_CODE. + + + -- cgit v1.2.3 From 8b5c8b6396bc008fc23ade51a260594d59db4749 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 12 Oct 2012 13:22:41 -0700 Subject: Drivers: hv: Get rid of unnecessary forward declarations Get rid of unnecessary forward declarations. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Reported-by: Jason Wang Acked-by: Jason Wang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 406537420ff..1bb1a801a90 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -33,14 +33,6 @@ #define NUM_PAGES_SPANNED(addr, len) \ ((PAGE_ALIGN(addr + len) >> PAGE_SHIFT) - (addr >> PAGE_SHIFT)) -/* Internal routines */ -static int create_gpadl_header( - void *kbuffer, /* must be phys and virt contiguous */ - u32 size, /* page-size multiple */ - struct vmbus_channel_msginfo **msginfo, - u32 *messagecount); -static void vmbus_setevent(struct vmbus_channel *channel); - /* * vmbus_setevent- Trigger an event notification on the specified * channel. -- cgit v1.2.3 From b45635542ede4ffeecb8fc4a1033ac5511ec2439 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 22 Oct 2012 17:20:20 +0800 Subject: Drivers: hv: remove unused variable from channel_mgmt.c The variables guidtype, guidinstance and initiate are initialized but never used otherwise, so remove the unused variables. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 2b8b8d4558d..2f84c5cff8d 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -265,14 +265,9 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) { struct vmbus_channel_offer_channel *offer; struct vmbus_channel *newchannel; - uuid_le *guidtype; - uuid_le *guidinstance; offer = (struct vmbus_channel_offer_channel *)hdr; - guidtype = &offer->offer.if_type; - guidinstance = &offer->offer.if_instance; - /* Allocate the channel object and save this offer. */ newchannel = alloc_channel(); if (!newchannel) { @@ -470,7 +465,6 @@ static void vmbus_onversion_response( { struct vmbus_channel_msginfo *msginfo; struct vmbus_channel_message_header *requestheader; - struct vmbus_channel_initiate_contact *initiate; struct vmbus_channel_version_response *version_response; unsigned long flags; @@ -484,8 +478,6 @@ static void vmbus_onversion_response( if (requestheader->msgtype == CHANNELMSG_INITIATE_CONTACT) { - initiate = - (struct vmbus_channel_initiate_contact *)requestheader; memcpy(&msginfo->response.version_response, version_response, sizeof(struct vmbus_channel_version_response)); -- cgit v1.2.3 From 12b9f8a20d6596c8ea7786532a4a55dacf71020c Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 23 Oct 2012 13:03:27 -0700 Subject: drivers/w1/masters: remove CONFIG_EXPERIMENTAL This config item has not carried much meaning for a while now and is almost always enabled by default. As agreed during the Linux kernel summit, remove it. CC: Andrew Morton CC: Paul Walmsley CC: Felipe Balbi Signed-off-by: Kees Cook Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig index 7e984034a11..c433a746e3f 100644 --- a/drivers/w1/masters/Kconfig +++ b/drivers/w1/masters/Kconfig @@ -26,7 +26,7 @@ config W1_MASTER_DS2490 config W1_MASTER_DS2482 tristate "Maxim DS2482 I2C to 1-Wire bridge" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Maxim DS2482 I2C to 1-Wire bridge. -- cgit v1.2.3 From 1b3c16556a386fa019c48783f0f615fb416cb53b Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 23 Oct 2012 13:24:09 +0800 Subject: pc8736x_gpio: use platform_device_unregister in pc8736x_gpio_cleanup() platform_device_unregister() only calls platform_device_del() and platform_device_put(), thus use platform_device_unregister() to simplify the code. Also the documents in platform.c shows that platform_device_del and platform_device_put must _only_ be externally called in error cases. All other usage is a bug. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/char/pc8736x_gpio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index b304ec05250..3f79a9fb6b1 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c @@ -345,8 +345,7 @@ static void __exit pc8736x_gpio_cleanup(void) unregister_chrdev_region(MKDEV(major,0), PC8736X_GPIO_CT); release_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE); - platform_device_del(pdev); - platform_device_put(pdev); + platform_device_unregister(pdev); } module_init(pc8736x_gpio_init); -- cgit v1.2.3 From 35299f884aa301deefb0881096e6d88d0964c94b Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 8 Oct 2012 10:44:47 +0800 Subject: drivers:misc: ti-st: fix potential NULL pointer dereference in st_register() Remove the pointless NULL dereference above the NULL test. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index 46937b10726..b90a2241d79 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -511,7 +511,6 @@ long st_register(struct st_proto_s *new_proto) unsigned long flags = 0; st_kim_ref(&st_gdata, 0); - pr_info("%s(%d) ", __func__, new_proto->chnl_id); if (st_gdata == NULL || new_proto == NULL || new_proto->recv == NULL || new_proto->reg_complete_cb == NULL) { pr_err("gdata/new_proto/recv or reg_complete_cb not ready"); -- cgit v1.2.3 From dbfd5ccc057fbefb7247614741efbf96be0258c5 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 8 Oct 2012 22:06:07 +0800 Subject: w1/ds2482: use module_i2c_driver to simplify the code Use the module_i2c_driver() macro to make the code smaller and a bit simpler. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/ds2482.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c index e5f74416d4b..6429b9e9fb8 100644 --- a/drivers/w1/masters/ds2482.c +++ b/drivers/w1/masters/ds2482.c @@ -505,19 +505,8 @@ static int ds2482_remove(struct i2c_client *client) return 0; } -static int __init sensors_ds2482_init(void) -{ - return i2c_add_driver(&ds2482_driver); -} - -static void __exit sensors_ds2482_exit(void) -{ - i2c_del_driver(&ds2482_driver); -} +module_i2c_driver(ds2482_driver); MODULE_AUTHOR("Ben Gardner "); MODULE_DESCRIPTION("DS2482 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_ds2482_init); -module_exit(sensors_ds2482_exit); -- cgit v1.2.3 From ff331f7d9089a1917bf21d41110b0b182e74c766 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:28:36 -0700 Subject: staging: comedi: cb_pcidda: fix error test in cb_pcidda_attach_pci() As pointed out by Fengguang Wu, the error test after finding the boardinfo should be testing for (!thisboard). Signed-off-by: H Hartley Sweeten Reported-by: Fengguang Wu Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 798374fe8da..06e546f3fdb 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -657,7 +657,7 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, int ret; thisboard = cb_pcidda_find_boardinfo(dev, pcidev); - if (!pcidev) + if (!thisboard) return -ENODEV; dev->board_ptr = thisboard; dev->board_name = thisboard->name; -- cgit v1.2.3 From c1225b6f909fc91ec5352c3e87dce5b2bcbb7226 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:28:57 -0700 Subject: staging: comedi: cb_pcidda: remove code in #if 0/#endif blocks The functions cb_pcidda_ai_cmd(), cb_pcidda_ai_cmdtest(), and cb_pcidda_ns_to_timer() are all partially coded stubs for command support with the analog output subdevice. Just remove the code since it is #if 0'ed out. It can be added back later if command support is completed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 168 ----------------------------- 1 file changed, 168 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 06e546f3fdb..5f3242ce8c7 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -217,170 +217,6 @@ struct cb_pcidda_private { u16 eeprom_data[EEPROM_SIZE]; /* software copy of board's eeprom */ }; -/* - * I will program this later... ;-) - */ -#if 0 -static int cb_pcidda_ai_cmd(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - printk("cb_pcidda_ai_cmd\n"); - printk("subdev: %d\n", cmd->subdev); - printk("flags: %d\n", cmd->flags); - printk("start_src: %d\n", cmd->start_src); - printk("start_arg: %d\n", cmd->start_arg); - printk("scan_begin_src: %d\n", cmd->scan_begin_src); - printk("convert_src: %d\n", cmd->convert_src); - printk("convert_arg: %d\n", cmd->convert_arg); - printk("scan_end_src: %d\n", cmd->scan_end_src); - printk("scan_end_arg: %d\n", cmd->scan_end_arg); - printk("stop_src: %d\n", cmd->stop_src); - printk("stop_arg: %d\n", cmd->stop_arg); - printk("chanlist_len: %d\n", cmd->chanlist_len); -} -#endif - -#if 0 -static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_cmd *cmd) -{ - int err = 0; - int tmp; - - /* Step 1 : check if triggers are trivially valid */ - - err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); - err |= cfc_check_trigger_src(&cmd->scan_begin_src, - TRIG_TIMER | TRIG_EXT); - err |= cfc_check_trigger_src(&cmd->convert_src, - TRIG_TIMER | TRIG_EXT); - err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); - err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); - - if (err) - return 1; - - /* Step 2a : make sure trigger sources are unique */ - - err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); - err |= cfc_check_trigger_is_unique(cmd->convert_src); - err |= cfc_check_trigger_is_unique(cmd->stop_src); - - /* Step 2b : and mutually compatible */ - - if (err) - return 2; - - /* step 3: make sure arguments are trivially compatible */ - - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } -#define MAX_SPEED 10000 /* in nanoseconds */ -#define MIN_SPEED 1000000000 /* in nanoseconds */ - - if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } - if (cmd->scan_begin_arg > MIN_SPEED) { - cmd->scan_begin_arg = MIN_SPEED; - err++; - } - } else { - /* external trigger */ - /* should be level/edge, hi/lo specification here */ - /* should specify multiple external triggers */ - if (cmd->scan_begin_arg > 9) { - cmd->scan_begin_arg = 9; - err++; - } - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < MAX_SPEED) { - cmd->convert_arg = MAX_SPEED; - err++; - } - if (cmd->convert_arg > MIN_SPEED) { - cmd->convert_arg = MIN_SPEED; - err++; - } - } else { - /* external trigger */ - /* see above */ - if (cmd->convert_arg > 9) { - cmd->convert_arg = 9; - err++; - } - } - - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } - - if (err) - return 3; - - /* step 4: fix up any arguments */ - - if (cmd->scan_begin_src == TRIG_TIMER) { - tmp = cmd->scan_begin_arg; - cb_pcidda_ns_to_timer(&cmd->scan_begin_arg, - cmd->flags & TRIG_ROUND_MASK); - if (tmp != cmd->scan_begin_arg) - err++; - } - if (cmd->convert_src == TRIG_TIMER) { - tmp = cmd->convert_arg; - cb_pcidda_ns_to_timer(&cmd->convert_arg, - cmd->flags & TRIG_ROUND_MASK); - if (tmp != cmd->convert_arg) - err++; - if (cmd->scan_begin_src == TRIG_TIMER && - cmd->scan_begin_arg < - cmd->convert_arg * cmd->scan_end_arg) { - cmd->scan_begin_arg = - cmd->convert_arg * cmd->scan_end_arg; - err++; - } - } - - if (err) - return 4; - - return 0; -} -#endif - -/* This function doesn't require a particular form, this is just - * what happens to be used in some of the drivers. It should - * convert ns nanoseconds to a counter value suitable for programming - * the device. Also, it should adjust ns so that it cooresponds to - * the actual time that the device will use. */ -#if 0 -static int cb_pcidda_ns_to_timer(unsigned int *ns, int round) -{ - /* trivial timer */ - return *ns; -} -#endif - /* lowlevel read from eeprom */ static unsigned int cb_pcidda_serial_in(struct comedi_device *dev) { @@ -694,10 +530,6 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, s->range_table = thisboard->ranges; s->insn_write = cb_pcidda_ao_winsn; - /* s->subdev_flags |= SDF_CMD_READ; */ - /* s->do_cmd = cb_pcidda_ai_cmd; */ - /* s->do_cmdtest = cb_pcidda_ai_cmdtest; */ - /* two 8255 digital io subdevices */ s = &dev->subdevices[1]; subdev_8255_init(dev, s, NULL, devpriv->digitalio); -- cgit v1.2.3 From b9287a30122c24246a48342138788223e836d9d3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:29:16 -0700 Subject: staging: comedi: cb_pcidda: add defines for the PCI device ids The PCI device ids supported by this driver are used multiple places in the code. To improve maintainability, create #define's for them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 37 +++++++++++++++++++----------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 5f3242ce8c7..cc34afcea48 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -51,8 +51,17 @@ Please report success/failure with other different cards to #include "comedi_fc.h" #include "8255.h" -/* PCI vendor number of ComputerBoards */ -#define PCI_VENDOR_ID_CB 0x1307 +/* + * ComputerBoards PCI Device ID's supported by this driver + */ +#define PCI_VENDOR_ID_CB 0x1307 +#define PCI_DEVICE_ID_DDA02_12 0x0020 +#define PCI_DEVICE_ID_DDA04_12 0x0021 +#define PCI_DEVICE_ID_DDA08_12 0x0022 +#define PCI_DEVICE_ID_DDA02_16 0x0023 +#define PCI_DEVICE_ID_DDA04_16 0x0024 +#define PCI_DEVICE_ID_DDA08_16 0x0025 + #define EEPROM_SIZE 128 /* number of entries in eeprom */ /* maximum number of ao channels for supported boards */ #define MAX_AO_CHANNELS 8 @@ -148,7 +157,7 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { { .name = "pci-dda02/12", .status = 1, - .device_id = 0x20, + .device_id = PCI_DEVICE_ID_DDA02_12, .ao_chans = 2, .ao_bits = 12, .ranges = &cb_pcidda_ranges, @@ -156,7 +165,7 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { { .name = "pci-dda04/12", .status = 1, - .device_id = 0x21, + .device_id = PCI_DEVICE_ID_DDA04_12, .ao_chans = 4, .ao_bits = 12, .ranges = &cb_pcidda_ranges, @@ -164,7 +173,7 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { { .name = "pci-dda08/12", .status = 0, - .device_id = 0x22, + .device_id = PCI_DEVICE_ID_DDA08_12, .ao_chans = 8, .ao_bits = 12, .ranges = &cb_pcidda_ranges, @@ -172,7 +181,7 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { { .name = "pci-dda02/16", .status = 2, - .device_id = 0x23, + .device_id = PCI_DEVICE_ID_DDA02_16, .ao_chans = 2, .ao_bits = 16, .ranges = &cb_pcidda_ranges, @@ -180,7 +189,7 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { { .name = "pci-dda04/16", .status = 2, - .device_id = 0x24, + .device_id = PCI_DEVICE_ID_DDA04_16, .ao_chans = 4, .ao_bits = 16, .ranges = &cb_pcidda_ranges, @@ -188,7 +197,7 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { { .name = "pci-dda08/16", .status = 0, - .device_id = 0x25, + .device_id = PCI_DEVICE_ID_DDA08_16, .ao_chans = 8, .ao_bits = 16, .ranges = &cb_pcidda_ranges, @@ -585,12 +594,12 @@ static void __devexit cb_pcidda_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0020) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0021) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0022) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0023) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0024) }, - { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0025) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA02_12) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA04_12) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA08_12) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA02_16) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA04_16) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA08_16) }, { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table); -- cgit v1.2.3 From cb3e9d86945181a2d9154543f402dccf35d8dd58 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:29:32 -0700 Subject: staging: comedi: comedidev.h: add PCI_VENDOR_ID_CB Add a define for the ComputerBoards/Measurement Computing PCI vendor id. Remove the duplicates in the drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 6 +++- drivers/staging/comedi/drivers/8255_pci.c | 3 -- drivers/staging/comedi/drivers/cb_pcidas.c | 3 -- drivers/staging/comedi/drivers/cb_pcidas64.c | 42 +++++++++++++--------------- drivers/staging/comedi/drivers/cb_pcidda.c | 1 - drivers/staging/comedi/drivers/cb_pcimdas.c | 4 +-- drivers/staging/comedi/drivers/cb_pcimdda.c | 3 +- drivers/staging/comedi/drivers/das08.c | 3 +- 8 files changed, 28 insertions(+), 37 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 78a44fc46ef..78bc06299ea 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -54,9 +54,13 @@ COMEDI_MINORVERSION, COMEDI_MICROVERSION) #define COMEDI_RELEASE VERSION -#define PCI_VENDOR_ID_ADLINK 0x144a +/* + * PCI Vendor IDs not in + */ #define PCI_VENDOR_ID_ICP 0x104c #define PCI_VENDOR_ID_CONTEC 0x1221 +#define PCI_VENDOR_ID_CB 0x1307 /* Measurement Computing */ +#define PCI_VENDOR_ID_ADLINK 0x144a #define COMEDI_NUM_MINORS 0x100 #define COMEDI_NUM_BOARD_MINORS 0x30 diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 6191a82f89a..d9b46a10838 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -65,9 +65,6 @@ Configuration Options: not applicable, uses PCI auto config #define PCI_DEVICE_ID_ADLINK_PCI7248 0x7248 #define PCI_DEVICE_ID_ADLINK_PCI7296 0x7296 -/* ComputerBoards is now known as Measurement Computing */ -#define PCI_VENDOR_ID_CB 0x1307 - #define PCI_DEVICE_ID_CB_PCIDIO48H 0x000b #define PCI_DEVICE_ID_CB_PCIDIO24H 0x0014 #define PCI_DEVICE_ID_CB_PCIDIO96H 0x0017 diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 0e4d189d195..8e88573d270 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -76,9 +76,6 @@ analog triggering on 1602 series #include "amcc_s5933.h" #include "comedi_fc.h" -/* PCI vendor number of ComputerBoards/MeasurementComputing */ -#define PCI_VENDOR_ID_CB 0x1307 - #define TIMER_BASE 100 /* 10MHz master clock */ #define AI_BUFFER_SIZE 1024 /* max ai fifo size */ #define AO_BUFFER_SIZE 1024 /* max ao fifo size */ diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index a6f5e5e92c8..0ae7ef5856c 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -105,8 +105,6 @@ TODO: #define PRESCALED_TIMER_BASE 10000 /* 100kHz 'prescaled' clock for slow acquisition, maybe I'll support this someday */ #define DMA_BUFFER_SIZE 0x1000 -#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 - /* maximum value that can be loaded into board's 24-bit counters*/ static const int max_counter_value = 0xffffff; @@ -1661,7 +1659,7 @@ static struct pci_dev *cb_pcidas64_find_pci_dev(struct comedi_device *dev, slot != PCI_SLOT(pcidev->devfn)) continue; } - if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS) + if (pcidev->vendor != PCI_VENDOR_ID_CB) continue; for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++) { @@ -4258,25 +4256,25 @@ static void __devexit cb_pcidas64_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(cb_pcidas64_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x001d) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x001e) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0035) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0036) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0037) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0052) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005d) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005e) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x005f) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0061) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0062) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0063) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0064) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0066) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0067) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0068) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x006f) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0078) }, - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0079) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001d) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001e) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0035) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0036) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0037) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0052) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005d) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005e) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x005f) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0061) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0062) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0063) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0064) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0066) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0067) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0068) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x006f) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0078) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0079) }, { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcidas64_pci_table); diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index cc34afcea48..6692be4cd8c 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -54,7 +54,6 @@ Please report success/failure with other different cards to /* * ComputerBoards PCI Device ID's supported by this driver */ -#define PCI_VENDOR_ID_CB 0x1307 #define PCI_DEVICE_ID_DDA02_12 0x0020 #define PCI_DEVICE_ID_DDA04_12 0x0021 #define PCI_DEVICE_ID_DDA08_12 0x0022 diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 138cfb15814..b093c9d939d 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -51,8 +51,6 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. /* #define CBPCIMDAS_DEBUG */ #undef CBPCIMDAS_DEBUG -#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 - /* Registers for the PCIM-DAS1602/16 */ /* sizes of io regions (bytes) */ @@ -306,7 +304,7 @@ static void __devexit cb_pcimdas_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0056) }, { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table); diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 9c015004924..94aa2af57eb 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -84,7 +84,6 @@ Configuration Options: not applicable, uses PCI auto config #include "8255.h" /* device ids of the cards we support -- currently only 1 card supported */ -#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 #define PCI_ID_PCIM_DDA06_16 0x0053 /* @@ -228,7 +227,7 @@ static void __devexit cb_pcimdda_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(cb_pcimdda_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_ID_PCIM_DDA06_16) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_ID_PCIM_DDA06_16) }, { 0 } }; MODULE_DEVICE_TABLE(pci, cb_pcimdda_pci_table); diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index fe5cf77a6aa..03a82d2c57c 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -65,7 +65,6 @@ #define DO_PCI IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) #define DO_COMEDI_DRIVER_REGISTER (DO_ISA || DO_PCI) -#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307 #define PCI_DEVICE_ID_PCIDAS08 0x29 #define PCIDAS08_SIZE 0x54 @@ -876,7 +875,7 @@ static struct comedi_driver das08_driver = { #if DO_PCI static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08) }, + { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_PCIDAS08) }, {0} }; -- cgit v1.2.3 From a74531a54afe327589d267ecc3e5775981c9ed05 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:29:50 -0700 Subject: staging: comedi: cb_pcidda: remove private data variable 'dac' The private data variable 'dac' is used to hold the PCI base address for the board. Use the 'iobase' variable provided by the comedi_device instead. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 6692be4cd8c..ad67373679e 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -213,7 +213,6 @@ struct cb_pcidda_private { int data; unsigned long digitalio; - unsigned long dac; /* unsigned long control_status; */ /* unsigned long adc_fifo; */ @@ -228,14 +227,13 @@ struct cb_pcidda_private { /* lowlevel read from eeprom */ static unsigned int cb_pcidda_serial_in(struct comedi_device *dev) { - struct cb_pcidda_private *devpriv = dev->private; unsigned int value = 0; int i; const int value_width = 16; /* number of bits wide values are */ for (i = 1; i <= value_width; i++) { /* read bits most significant bit first */ - if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT) + if (inw_p(dev->iobase + DACALIBRATION1) & SERIAL_OUT_BIT) value |= 1 << (value_width - i); } @@ -255,7 +253,7 @@ static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value, devpriv->dac_cal1_bits |= SERIAL_IN_BIT; else devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT; - outw_p(devpriv->dac_cal1_bits, devpriv->dac + DACALIBRATION1); + outw_p(devpriv->dac_cal1_bits, dev->iobase + DACALIBRATION1); } } @@ -263,7 +261,6 @@ static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value, static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, unsigned int address) { - struct cb_pcidda_private *devpriv = dev->private; unsigned int i; unsigned int cal2_bits; unsigned int value; @@ -279,7 +276,7 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, /* deactivate caldacs (one caldac for every two channels) */ for (i = 0; i < max_num_caldacs; i++) cal2_bits |= DESELECT_CALDAC_BIT(i); - outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); + outw_p(cal2_bits, dev->iobase + DACALIBRATION2); /* tell eeprom we want to read */ cb_pcidda_serial_out(dev, read_instruction, instruction_length); @@ -290,7 +287,7 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, /* deactivate eeprom */ cal2_bits &= ~SELECT_EEPROM_BIT; - outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); + outw_p(cal2_bits, dev->iobase + DACALIBRATION2); return value; } @@ -300,7 +297,6 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev, unsigned int caldac, unsigned int channel, unsigned int value) { - struct cb_pcidda_private *devpriv = dev->private; unsigned int cal2_bits; unsigned int i; /* caldacs use 3 bit channel specification */ @@ -323,10 +319,10 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev, cal2_bits |= DESELECT_CALDAC_BIT(i); /* activate the caldac we want */ cal2_bits &= ~DESELECT_CALDAC_BIT(caldac); - outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); + outw_p(cal2_bits, dev->iobase + DACALIBRATION2); /* deactivate caldac */ cal2_bits |= DESELECT_CALDAC_BIT(caldac); - outw_p(cal2_bits, devpriv->dac + DACALIBRATION2); + outw_p(cal2_bits, dev->iobase + DACALIBRATION2); } /* returns caldac that calibrates given analog out channel */ @@ -468,10 +464,10 @@ static int cb_pcidda_ao_winsn(struct comedi_device *dev, /* output channel specification */ command |= channel << 2; - outw(command, devpriv->dac + DACONTROL); + outw(command, dev->iobase + DACONTROL); /* write data */ - outw(data[0], devpriv->dac + DADATA + channel * 2); + outw(data[0], dev->iobase + DADATA + channel * 2); /* return the number of samples read/written */ return 1; @@ -514,10 +510,9 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; + dev->iobase = pci_resource_start(pcidev, 3); devpriv->digitalio = pci_resource_start(pcidev, 2); - devpriv->dac = pci_resource_start(pcidev, 3); - dev->iobase = devpriv->dac; if (thisboard->status == 2) printk -- cgit v1.2.3 From dcf5e2b39aaec76e7771e57dc469f538386fe593 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:30:05 -0700 Subject: staging: comedi: cb_pcidda: cleanup the private data Remove the unused variables in the private data. Also remove the cut-and-paste comment from the skel driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index ad67373679e..6e504ddde86 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -203,20 +203,9 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { }, }; -/* - * this structure is for data unique to this hardware driver. If - * several hardware drivers keep similar information in this structure, - * feel free to suggest moving the variable to the struct comedi_device - * struct. - */ struct cb_pcidda_private { - int data; - unsigned long digitalio; - /* unsigned long control_status; */ - /* unsigned long adc_fifo; */ - /* bits last written to da calibration register 1 */ unsigned int dac_cal1_bits; /* current range settings for output channels */ -- cgit v1.2.3 From 08f082ed78eb2ece4438c7cd23cf18166e3cce4b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:30:21 -0700 Subject: staging: comedi: cb_pcidda: remove private data variable 'digitalio' The private data variable 'digitalio' is only used to hold the PCI base address for the 8255 devices on the board. This value is then passed to subdev_8255_init() and stored in it's own private data. There is no need to keep the value in the private data for the board. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 6e504ddde86..8feaa31b1be 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -204,8 +204,6 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { }; struct cb_pcidda_private { - unsigned long digitalio; - /* bits last written to da calibration register 1 */ unsigned int dac_cal1_bits; /* current range settings for output channels */ @@ -482,6 +480,7 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, const struct cb_pcidda_board *thisboard; struct cb_pcidda_private *devpriv; struct comedi_subdevice *s; + unsigned long iobase_8255; int index; int ret; @@ -500,8 +499,7 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, if (ret) return ret; dev->iobase = pci_resource_start(pcidev, 3); - - devpriv->digitalio = pci_resource_start(pcidev, 2); + iobase_8255 = pci_resource_start(pcidev, 2); if (thisboard->status == 2) printk @@ -524,9 +522,9 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, /* two 8255 digital io subdevices */ s = &dev->subdevices[1]; - subdev_8255_init(dev, s, NULL, devpriv->digitalio); + subdev_8255_init(dev, s, NULL, iobase_8255); s = &dev->subdevices[2]; - subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A); + subdev_8255_init(dev, s, NULL, iobase_8255 + PORT2A); dev_dbg(dev->class_dev, "eeprom:\n"); for (index = 0; index < EEPROM_SIZE; index++) { -- cgit v1.2.3 From 66483378b91287fed134efdf9fa04ec6e96a71ce Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:30:38 -0700 Subject: staging: comedi: cb_pcidda: remove the debug output of the eeprom data This is just noise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 8feaa31b1be..0e5b85d9bb9 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -526,12 +526,9 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, s = &dev->subdevices[2]; subdev_8255_init(dev, s, NULL, iobase_8255 + PORT2A); - dev_dbg(dev->class_dev, "eeprom:\n"); - for (index = 0; index < EEPROM_SIZE; index++) { + /* Read the caldac eeprom data */ + for (index = 0; index < EEPROM_SIZE; index++) devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index); - dev_dbg(dev->class_dev, "%i:0x%x\n", index, - devpriv->eeprom_data[index]); - } /* set calibrations dacs */ for (index = 0; index < thisboard->ao_chans; index++) -- cgit v1.2.3 From 2730c736d99c766c6e6c7674c4be53fb0f9d3315 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:30:57 -0700 Subject: staging: comedi: cb_pcidda: rename local variable 'index' For aesthetic reasons, rename the local variable 'index' used in the attach_pci function to simply 'i'. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 0e5b85d9bb9..511401fbdeb 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -481,7 +481,7 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, struct cb_pcidda_private *devpriv; struct comedi_subdevice *s; unsigned long iobase_8255; - int index; + int i; int ret; thisboard = cb_pcidda_find_boardinfo(dev, pcidev); @@ -527,12 +527,12 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, subdev_8255_init(dev, s, NULL, iobase_8255 + PORT2A); /* Read the caldac eeprom data */ - for (index = 0; index < EEPROM_SIZE; index++) - devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index); + for (i = 0; i < EEPROM_SIZE; i++) + devpriv->eeprom_data[i] = cb_pcidda_read_eeprom(dev, i); /* set calibrations dacs */ - for (index = 0; index < thisboard->ao_chans; index++) - cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]); + for (i = 0; i < thisboard->ao_chans; i++) + cb_pcidda_calibrate(dev, i, devpriv->ao_range[i]); dev_info(dev->class_dev, "%s attached\n", dev->board_name); -- cgit v1.2.3 From 618351aed1dc9b0340bc755ffc0dba6caf190299 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:31:14 -0700 Subject: staging: comedi: cb_pcidda: check for subdev_8255_init() failure The subdev_8255_init() can fail, make sure to check for it. This board has two 8255 subdevices, one at iobase PCI bar2 and one at iobase PCI bar2 + 4. Init the subdevices using a for() loop to make the code a bit more concise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 511401fbdeb..8371fa2a1b7 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -520,11 +520,13 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, s->range_table = thisboard->ranges; s->insn_write = cb_pcidda_ao_winsn; - /* two 8255 digital io subdevices */ - s = &dev->subdevices[1]; - subdev_8255_init(dev, s, NULL, iobase_8255); - s = &dev->subdevices[2]; - subdev_8255_init(dev, s, NULL, iobase_8255 + PORT2A); + /* two 8255 digital io subdevices */ + for (i = 0; i < 2; i++) { + s = &dev->subdevices[1 + i]; + ret = subdev_8255_init(dev, s, NULL, iobase_8255 + (i * 4)); + if (ret) + return ret; + } /* Read the caldac eeprom data */ for (i = 0; i < EEPROM_SIZE; i++) -- cgit v1.2.3 From f9c62f3fe83d5c273afcb41051ce9de3e45fdb6e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:31:31 -0700 Subject: staging: comedi: cb_pcidda: cleanup the analog output range All the boards supported by this driver have the same analog output ranges. Remove the 'range' from the boardinfo and just use the 'cb_pcidda_ranges' directly when initializing the subdevice. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 8371fa2a1b7..8918528e511 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -120,15 +120,14 @@ Please report success/failure with other different cards to #define DADATA 8 /* FIRST D/A DATA REGISTER (0) */ static const struct comedi_lrange cb_pcidda_ranges = { - 6, - { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - } + 6, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5) + } }; /* @@ -149,7 +148,6 @@ struct cb_pcidda_board { unsigned short device_id; int ao_chans; int ao_bits; - const struct comedi_lrange *ranges; }; static const struct cb_pcidda_board cb_pcidda_boards[] = { @@ -159,7 +157,6 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { .device_id = PCI_DEVICE_ID_DDA02_12, .ao_chans = 2, .ao_bits = 12, - .ranges = &cb_pcidda_ranges, }, { .name = "pci-dda04/12", @@ -167,7 +164,6 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { .device_id = PCI_DEVICE_ID_DDA04_12, .ao_chans = 4, .ao_bits = 12, - .ranges = &cb_pcidda_ranges, }, { .name = "pci-dda08/12", @@ -175,7 +171,6 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { .device_id = PCI_DEVICE_ID_DDA08_12, .ao_chans = 8, .ao_bits = 12, - .ranges = &cb_pcidda_ranges, }, { .name = "pci-dda02/16", @@ -183,7 +178,6 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { .device_id = PCI_DEVICE_ID_DDA02_16, .ao_chans = 2, .ao_bits = 16, - .ranges = &cb_pcidda_ranges, }, { .name = "pci-dda04/16", @@ -191,7 +185,6 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { .device_id = PCI_DEVICE_ID_DDA04_16, .ao_chans = 4, .ao_bits = 16, - .ranges = &cb_pcidda_ranges, }, { .name = "pci-dda08/16", @@ -199,7 +192,6 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { .device_id = PCI_DEVICE_ID_DDA08_16, .ao_chans = 8, .ao_bits = 16, - .ranges = &cb_pcidda_ranges, }, }; @@ -517,7 +509,7 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, s->subdev_flags = SDF_WRITABLE; s->n_chan = thisboard->ao_chans; s->maxdata = (1 << thisboard->ao_bits) - 1; - s->range_table = thisboard->ranges; + s->range_table = &cb_pcidda_ranges; s->insn_write = cb_pcidda_ao_winsn; /* two 8255 digital io subdevices */ -- cgit v1.2.3 From 3bb18724d6f6a26cbb6ec5a9ef45aed6f1200a43 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:31:47 -0700 Subject: staging: comedi: cb_pcidda: cleanup the copyright and comedi comments Reformat the copyright and driver description comments to follow the preferred block comment style. Reword the driver description to follow comedi style described in the skel driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 83 ++++++++++++++---------------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 8918528e511..69ca074d106 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -1,50 +1,45 @@ /* - comedi/drivers/cb_pcidda.c - This intends to be a driver for the ComputerBoards / MeasurementComputing - PCI-DDA series. - - Copyright (C) 2001 Ivan Martinez - Copyright (C) 2001 Frank Mori Hess - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1997-8 David A. Schleef - - 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. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * comedi/drivers/cb_pcidda.c + * Driver for the ComputerBoards / MeasurementComputing PCI-DDA series. + * + * Copyright (C) 2001 Ivan Martinez + * Copyright (C) 2001 Frank Mori Hess + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 1997-8 David A. Schleef + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ -*/ /* -Driver: cb_pcidda -Description: MeasurementComputing PCI-DDA series -Author: Ivan Martinez , Frank Mori Hess -Status: Supports 08/16, 04/16, 02/16, 08/12, 04/12, and 02/12 -Devices: [Measurement Computing] PCI-DDA08/12 (cb_pcidda), PCI-DDA04/12, - PCI-DDA02/12, PCI-DDA08/16, PCI-DDA04/16, PCI-DDA02/16 - -Configuration options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first available PCI - device will be used. - -Only simple analog output writing is supported. - -So far it has only been tested with: - - PCI-DDA08/12 -Please report success/failure with other different cards to -. -*/ + * Driver: cb_pcidda + * Description: MeasurementComputing PCI-DDA series + * Devices: (Measurement Computing) PCI-DDA08/12 [pci-dda08/12] + * (Measurement Computing) PCI-DDA04/12 [pci-dda04/12] + * (Measurement Computing) PCI-DDA02/12 [pci-dda02/12] + * (Measurement Computing) PCI-DDA08/16 [pci-dda08/16] + * (Measurement Computing) PCI-DDA04/16 [pci-dda04/16] + * (Measurement Computing) PCI-DDA02/16 [pci-dda02/16] + * Author: Ivan Martinez + * Frank Mori Hess + * Status: works + * + * Configuration options: not applicable, uses PCI auto config + * + * Only simple analog output writing is supported. + */ #include "../comedidev.h" -- cgit v1.2.3 From 8545d2a8117f9d8cff9e066310125f6e93503edb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:32:03 -0700 Subject: staging: comedi: cb_pcidda: remove the private data 'status' This variable in the private data is only used to output some kernel noise during the attach about certian board types not being fully tested. All of the boards supported by this driver share a common register map and should be compatible. Just remove the 'status' and the noise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 69ca074d106..2af32783e00 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -132,14 +132,6 @@ static const struct comedi_lrange cb_pcidda_ranges = { */ struct cb_pcidda_board { const char *name; - char status; /* Driver status: */ - - /* - * 0 - tested - * 1 - manual read, not tested - * 2 - manual not read - */ - unsigned short device_id; int ao_chans; int ao_bits; @@ -148,42 +140,36 @@ struct cb_pcidda_board { static const struct cb_pcidda_board cb_pcidda_boards[] = { { .name = "pci-dda02/12", - .status = 1, .device_id = PCI_DEVICE_ID_DDA02_12, .ao_chans = 2, .ao_bits = 12, }, { .name = "pci-dda04/12", - .status = 1, .device_id = PCI_DEVICE_ID_DDA04_12, .ao_chans = 4, .ao_bits = 12, }, { .name = "pci-dda08/12", - .status = 0, .device_id = PCI_DEVICE_ID_DDA08_12, .ao_chans = 8, .ao_bits = 12, }, { .name = "pci-dda02/16", - .status = 2, .device_id = PCI_DEVICE_ID_DDA02_16, .ao_chans = 2, .ao_bits = 16, }, { .name = "pci-dda04/16", - .status = 2, .device_id = PCI_DEVICE_ID_DDA04_16, .ao_chans = 4, .ao_bits = 16, }, { .name = "pci-dda08/16", - .status = 0, .device_id = PCI_DEVICE_ID_DDA08_16, .ao_chans = 8, .ao_bits = 16, @@ -488,12 +474,6 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, dev->iobase = pci_resource_start(pcidev, 3); iobase_8255 = pci_resource_start(pcidev, 2); - if (thisboard->status == 2) - printk - ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. " - "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. " - "PLEASE REPORT USAGE TO .\n"); - ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; -- cgit v1.2.3 From 0963fa1c83474557e6e868fbe56ddd53c99fb929 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:32:54 -0700 Subject: staging: comedi: cb_pcidda: cleanup the boardinfo For aesthetic reasons, add some whitespace to the boardinfo to improve readability. Also, remove the cut-and-paste comment from the skel driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 70 +++++++++++++----------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 2af32783e00..f1aa9c94315 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -125,11 +125,6 @@ static const struct comedi_lrange cb_pcidda_ranges = { } }; -/* - * Board descriptions for two imaginary boards. Describing the - * boards in this way is optional, and completely driver-dependent. - * Some drivers use arrays such as this, other do not. - */ struct cb_pcidda_board { const char *name; unsigned short device_id; @@ -139,41 +134,36 @@ struct cb_pcidda_board { static const struct cb_pcidda_board cb_pcidda_boards[] = { { - .name = "pci-dda02/12", - .device_id = PCI_DEVICE_ID_DDA02_12, - .ao_chans = 2, - .ao_bits = 12, - }, - { - .name = "pci-dda04/12", - .device_id = PCI_DEVICE_ID_DDA04_12, - .ao_chans = 4, - .ao_bits = 12, - }, - { - .name = "pci-dda08/12", - .device_id = PCI_DEVICE_ID_DDA08_12, - .ao_chans = 8, - .ao_bits = 12, - }, - { - .name = "pci-dda02/16", - .device_id = PCI_DEVICE_ID_DDA02_16, - .ao_chans = 2, - .ao_bits = 16, - }, - { - .name = "pci-dda04/16", - .device_id = PCI_DEVICE_ID_DDA04_16, - .ao_chans = 4, - .ao_bits = 16, - }, - { - .name = "pci-dda08/16", - .device_id = PCI_DEVICE_ID_DDA08_16, - .ao_chans = 8, - .ao_bits = 16, - }, + .name = "pci-dda02/12", + .device_id = PCI_DEVICE_ID_DDA02_12, + .ao_chans = 2, + .ao_bits = 12, + }, { + .name = "pci-dda04/12", + .device_id = PCI_DEVICE_ID_DDA04_12, + .ao_chans = 4, + .ao_bits = 12, + }, { + .name = "pci-dda08/12", + .device_id = PCI_DEVICE_ID_DDA08_12, + .ao_chans = 8, + .ao_bits = 12, + }, { + .name = "pci-dda02/16", + .device_id = PCI_DEVICE_ID_DDA02_16, + .ao_chans = 2, + .ao_bits = 16, + }, { + .name = "pci-dda04/16", + .device_id = PCI_DEVICE_ID_DDA04_16, + .ao_chans = 4, + .ao_bits = 16, + }, { + .name = "pci-dda08/16", + .device_id = PCI_DEVICE_ID_DDA08_16, + .ao_chans = 8, + .ao_bits = 16, + }, }; struct cb_pcidda_private { -- cgit v1.2.3 From c8ffd143fac826787eb948930982902b5f0a778d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:33:13 -0700 Subject: staging: comedi: cb_pcidda: cleanup the dio register defines Remove the unused defines for the dio registers. Add two new defines to document the iobase registers for the two 8255 devices. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index f1aa9c94315..2e2d00a60c9 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -61,21 +61,8 @@ #define MAX_AO_CHANNELS 8 /* Digital I/O registers */ -#define PORT1A 0 /* PORT 1A DATA */ - -#define PORT1B 1 /* PORT 1B DATA */ - -#define PORT1C 2 /* PORT 1C DATA */ - -#define CONTROL1 3 /* CONTROL REGISTER 1 */ - -#define PORT2A 4 /* PORT 2A DATA */ - -#define PORT2B 5 /* PORT 2B DATA */ - -#define PORT2C 6 /* PORT 2C DATA */ - -#define CONTROL2 7 /* CONTROL REGISTER 2 */ +#define CB_DDA_DIO0_8255_BASE 0x00 +#define CB_DDA_DIO1_8255_BASE 0x04 /* DAC registers */ #define DACONTROL 0 /* D/A CONTROL REGISTER */ -- cgit v1.2.3 From be2fcdbf91f77c7658f87a782a86a3cfc0775b2d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:33:30 -0700 Subject: staging: comedi: cb_pcidda: cleanup DACCONTROL defines Rename the defines used for the D/A Control register so that they have namespace with this driver. Cleanup the use of these defines. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 53 ++++++++++++------------------ 1 file changed, 21 insertions(+), 32 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 2e2d00a60c9..90930c801c8 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -65,16 +65,14 @@ #define CB_DDA_DIO1_8255_BASE 0x04 /* DAC registers */ -#define DACONTROL 0 /* D/A CONTROL REGISTER */ -#define SU 0000001 /* Simultaneous update enabled */ -#define NOSU 0000000 /* Simultaneous update disabled */ -#define ENABLEDAC 0000002 /* Enable specified DAC */ -#define DISABLEDAC 0000000 /* Disable specified DAC */ -#define RANGE2V5 0000000 /* 2.5V */ -#define RANGE5V 0000200 /* 5V */ -#define RANGE10V 0000300 /* 10V */ -#define UNIP 0000400 /* Unipolar outputs */ -#define BIP 0000000 /* Bipolar outputs */ +#define CB_DDA_DA_CTRL_REG 0x00 /* D/A Control Register */ +#define CB_DDA_DA_CTRL_SU (1 << 0) /* Simultaneous update */ +#define CB_DDA_DA_CTRL_EN (1 << 1) /* Enable specified DAC */ +#define CB_DDA_DA_CTRL_DAC(x) ((x) << 2) /* Specify DAC channel */ +#define CB_DDA_DA_CTRL_RANGE2V5 (0 << 6) /* 2.5V range */ +#define CB_DDA_DA_CTRL_RANGE5V (2 << 6) /* 5V range */ +#define CB_DDA_DA_CTRL_RANGE10V (3 << 6) /* 10V range */ +#define CB_DDA_DA_CTRL_UNIP (1 << 8) /* Unipolar range */ #define DACALIBRATION1 4 /* D/A CALIBRATION REGISTER 1 */ /* write bits */ @@ -364,44 +362,35 @@ static int cb_pcidda_ao_winsn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { struct cb_pcidda_private *devpriv = dev->private; - unsigned int command; - unsigned int channel, range; - - channel = CR_CHAN(insn->chanspec); - range = CR_RANGE(insn->chanspec); + unsigned int channel = CR_CHAN(insn->chanspec); + unsigned int range = CR_RANGE(insn->chanspec); + unsigned int ctrl; /* adjust calibration dacs if range has changed */ if (range != devpriv->ao_range[channel]) cb_pcidda_calibrate(dev, channel, range); - /* output channel configuration */ - command = NOSU | ENABLEDAC; + ctrl = CB_DDA_DA_CTRL_EN | CB_DDA_DA_CTRL_DAC(channel); - /* output channel range */ switch (range) { case 0: - command |= BIP | RANGE10V; - break; - case 1: - command |= BIP | RANGE5V; - break; - case 2: - command |= BIP | RANGE2V5; - break; case 3: - command |= UNIP | RANGE10V; + ctrl |= CB_DDA_DA_CTRL_RANGE10V; break; + case 1: case 4: - command |= UNIP | RANGE5V; + ctrl |= CB_DDA_DA_CTRL_RANGE5V; break; + case 2: case 5: - command |= UNIP | RANGE2V5; + ctrl |= CB_DDA_DA_CTRL_RANGE2V5; break; } - /* output channel specification */ - command |= channel << 2; - outw(command, dev->iobase + DACONTROL); + if (range > 2) + ctrl |= CB_DDA_DA_CTRL_UNIP; + + outw(ctrl, dev->iobase + CB_DDA_DA_CTRL_REG); /* write data */ outw(data[0], dev->iobase + DADATA + channel * 2); -- cgit v1.2.3 From 87c4e2c62e507625af7cab5f46a019ab17d95bb7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:33:45 -0700 Subject: staging: comedi: cb_pcidda: cleanup DADATA define Rename the define used for the D/A Data register so that is has namespace with this driver. Change the define so that it takes the channel as a parameter to calculate the correct register offset. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 90930c801c8..6b69e530ca7 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -97,7 +97,7 @@ /* manual says to set this bit with no explanation */ #define DUMMY_BIT 0x40 -#define DADATA 8 /* FIRST D/A DATA REGISTER (0) */ +#define CB_DDA_DA_DATA_REG(x) (0x08 + ((x) * 2)) static const struct comedi_lrange cb_pcidda_ranges = { 6, { @@ -393,7 +393,7 @@ static int cb_pcidda_ao_winsn(struct comedi_device *dev, outw(ctrl, dev->iobase + CB_DDA_DA_CTRL_REG); /* write data */ - outw(data[0], dev->iobase + DADATA + channel * 2); + outw(data[0], dev->iobase + CB_DDA_DA_DATA_REG(channel)); /* return the number of samples read/written */ return 1; -- cgit v1.2.3 From 2e54209e0f9bbe9fb38869ff582a04cc86915975 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:34:02 -0700 Subject: staging: comedi: cb_pcidda: cleanup cb_pcidda_ao_winsn() For aesthetic reasons, rename the function to help when searching for 'insn_write' functions. Remove the obvious comments and fix the return from the function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 6b69e530ca7..0ad576b8f95 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -357,16 +357,16 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, fine_gain_channel(channel), fine_gain); } -static int cb_pcidda_ao_winsn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int cb_pcidda_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct cb_pcidda_private *devpriv = dev->private; unsigned int channel = CR_CHAN(insn->chanspec); unsigned int range = CR_RANGE(insn->chanspec); unsigned int ctrl; - /* adjust calibration dacs if range has changed */ if (range != devpriv->ao_range[channel]) cb_pcidda_calibrate(dev, channel, range); @@ -392,11 +392,9 @@ static int cb_pcidda_ao_winsn(struct comedi_device *dev, outw(ctrl, dev->iobase + CB_DDA_DA_CTRL_REG); - /* write data */ outw(data[0], dev->iobase + CB_DDA_DA_DATA_REG(channel)); - /* return the number of samples read/written */ - return 1; + return insn->n; } static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev, @@ -451,7 +449,7 @@ static int cb_pcidda_attach_pci(struct comedi_device *dev, s->n_chan = thisboard->ao_chans; s->maxdata = (1 << thisboard->ao_bits) - 1; s->range_table = &cb_pcidda_ranges; - s->insn_write = cb_pcidda_ao_winsn; + s->insn_write = cb_pcidda_ao_insn_write; /* two 8255 digital io subdevices */ for (i = 0; i < 2; i++) { -- cgit v1.2.3 From 809ec5bcc16e42890ec33994baaa58418f4d6859 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 16:34:21 -0700 Subject: staging: comedi: cb_pcidda: cleanup cb_pcidda_calibrate() Refactor the function to make it a bit more concise and remove all the one-line helper functions. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 112 +++++++---------------------- 1 file changed, 25 insertions(+), 87 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 0ad576b8f95..eb03032ccfe 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -99,6 +99,12 @@ #define CB_DDA_DA_DATA_REG(x) (0x08 + ((x) * 2)) +/* Offsets for the caldac channels */ +#define CB_DDA_CALDAC_FINE_GAIN 0 +#define CB_DDA_CALDAC_COURSE_GAIN 1 +#define CB_DDA_CALDAC_COURSE_OFFSET 2 +#define CB_DDA_CALDAC_FINE_OFFSET 3 + static const struct comedi_lrange cb_pcidda_ranges = { 6, { BIP_RANGE(10), @@ -260,101 +266,33 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev, outw_p(cal2_bits, dev->iobase + DACALIBRATION2); } -/* returns caldac that calibrates given analog out channel */ -static unsigned int caldac_number(unsigned int channel) -{ - return channel / 2; -} - -/* returns caldac channel that provides fine gain for given ao channel */ -static unsigned int fine_gain_channel(unsigned int ao_channel) -{ - return 4 * (ao_channel % 2); -} - -/* returns caldac channel that provides coarse gain for given ao channel */ -static unsigned int coarse_gain_channel(unsigned int ao_channel) -{ - return 1 + 4 * (ao_channel % 2); -} - -/* returns caldac channel that provides coarse offset for given ao channel */ -static unsigned int coarse_offset_channel(unsigned int ao_channel) -{ - return 2 + 4 * (ao_channel % 2); -} - -/* returns caldac channel that provides fine offset for given ao channel */ -static unsigned int fine_offset_channel(unsigned int ao_channel) -{ - return 3 + 4 * (ao_channel % 2); -} - -/* returns eeprom address that provides offset for given ao channel and range */ -static unsigned int offset_eeprom_address(unsigned int ao_channel, - unsigned int range) -{ - return 0x7 + 2 * range + 12 * ao_channel; -} - -/* - * returns eeprom address that provides gain calibration for given ao - * channel and range - */ -static unsigned int gain_eeprom_address(unsigned int ao_channel, - unsigned int range) -{ - return 0x8 + 2 * range + 12 * ao_channel; -} - -/* - * returns upper byte of eeprom entry, which gives the coarse adjustment - * values - */ -static unsigned int eeprom_coarse_byte(unsigned int word) -{ - return (word >> 8) & 0xff; -} - -/* returns lower byte of eeprom entry, which gives the fine adjustment values */ -static unsigned int eeprom_fine_byte(unsigned int word) -{ - return word & 0xff; -} - /* set caldacs to eeprom values for given channel and range */ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel, unsigned int range) { struct cb_pcidda_private *devpriv = dev->private; - unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain; + unsigned int caldac = channel / 2; /* two caldacs per channel */ + unsigned int chan = 4 * (channel % 2); /* caldac channel base */ + unsigned int index = 2 * range + 12 * channel; + unsigned int offset; + unsigned int gain; - /* remember range so we can tell when we need to readjust calibration */ + /* save range so we can tell when we need to readjust calibration */ devpriv->ao_range[channel] = range; - /* get values from eeprom data */ - coarse_offset = - eeprom_coarse_byte(devpriv->eeprom_data - [offset_eeprom_address(channel, range)]); - fine_offset = - eeprom_fine_byte(devpriv->eeprom_data - [offset_eeprom_address(channel, range)]); - coarse_gain = - eeprom_coarse_byte(devpriv->eeprom_data - [gain_eeprom_address(channel, range)]); - fine_gain = - eeprom_fine_byte(devpriv->eeprom_data - [gain_eeprom_address(channel, range)]); - - /* set caldacs */ - cb_pcidda_write_caldac(dev, caldac_number(channel), - coarse_offset_channel(channel), coarse_offset); - cb_pcidda_write_caldac(dev, caldac_number(channel), - fine_offset_channel(channel), fine_offset); - cb_pcidda_write_caldac(dev, caldac_number(channel), - coarse_gain_channel(channel), coarse_gain); - cb_pcidda_write_caldac(dev, caldac_number(channel), - fine_gain_channel(channel), fine_gain); + /* get values from eeprom data */ + offset = devpriv->eeprom_data[0x7 + index]; + gain = devpriv->eeprom_data[0x8 + index]; + + /* set caldacs */ + cb_pcidda_write_caldac(dev, caldac, chan + CB_DDA_CALDAC_COURSE_OFFSET, + (offset >> 8) & 0xff); + cb_pcidda_write_caldac(dev, caldac, chan + CB_DDA_CALDAC_FINE_OFFSET, + offset & 0xff); + cb_pcidda_write_caldac(dev, caldac, chan + CB_DDA_CALDAC_COURSE_GAIN, + (gain >> 8) & 0xff); + cb_pcidda_write_caldac(dev, caldac, chan + CB_DDA_CALDAC_FINE_GAIN, + gain & 0xff); } static int cb_pcidda_ao_insn_write(struct comedi_device *dev, -- cgit v1.2.3 From 12f07ba56bad3defc37416e496c6e790029715b4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 18:11:01 -0700 Subject: staging: comedi: comedidev.h: add PCI_VENDOR_ID_ADVANTECH Add a define for the Advantech Co., Ltd. PCI vendor id. Remove the duplicates in the drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 + drivers/staging/comedi/drivers/adv_pci1710.c | 2 -- drivers/staging/comedi/drivers/adv_pci1723.c | 2 -- drivers/staging/comedi/drivers/adv_pci_dio.c | 2 -- 4 files changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 78bc06299ea..b925f6cb0c5 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -60,6 +60,7 @@ #define PCI_VENDOR_ID_ICP 0x104c #define PCI_VENDOR_ID_CONTEC 0x1221 #define PCI_VENDOR_ID_CB 0x1307 /* Measurement Computing */ +#define PCI_VENDOR_ID_ADVANTECH 0x13fe #define PCI_VENDOR_ID_ADLINK 0x144a #define COMEDI_NUM_MINORS 0x100 diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 6131a0a7aa9..dd83c749e6e 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -53,8 +53,6 @@ Configuration options: * correct channel number on every 12 bit * sample */ -#define PCI_VENDOR_ID_ADVANTECH 0x13fe - /* hardware types of the cards */ #define TYPE_PCI171X 0 #define TYPE_PCI1713 2 diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 2eaf56dcc95..7109e7d8b9f 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -50,8 +50,6 @@ TODO: #include "../comedidev.h" -#define PCI_VENDOR_ID_ADVANTECH 0x13fe /* Advantech PCI vendor ID */ - /* all the registers for the pci1723 board */ #define PCI1723_DA(N) ((N)<<1) /* W: D/A register N (0 to 7) */ diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 4b29f6d0505..131eb02324d 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -36,8 +36,6 @@ Configuration options: #include "8255.h" #include "8253.h" -#define PCI_VENDOR_ID_ADVANTECH 0x13fe - /* hardware types of the cards */ enum hw_cards_id { TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1735, TYPE_PCI1736, -- cgit v1.2.3 From b77d93a0306766456d7d6da21fb6f16c5e129fe6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 18:11:21 -0700 Subject: staging: comedi: comedidev.h: add PCI_VENDOR_ID_MEILHAUS Add a define for the Meilhaus Electronic GmbH Germany PCI vendor id. Remove the duplicates in the drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 + drivers/staging/comedi/drivers/me4000.c | 2 -- drivers/staging/comedi/drivers/me_daq.c | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index b925f6cb0c5..fa572073c0f 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -61,6 +61,7 @@ #define PCI_VENDOR_ID_CONTEC 0x1221 #define PCI_VENDOR_ID_CB 0x1307 /* Measurement Computing */ #define PCI_VENDOR_ID_ADVANTECH 0x13fe +#define PCI_VENDOR_ID_MEILHAUS 0x1402 #define PCI_VENDOR_ID_ADLINK 0x144a #define COMEDI_NUM_MINORS 0x100 diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index ba7fd9d53d1..322c8849b52 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -60,8 +60,6 @@ broken. #include "me4000_fw.h" #endif -#define PCI_VENDOR_ID_MEILHAUS 0x1402 - #define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650 #define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660 #define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661 diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 271db1cb607..ddb3dd79874 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -50,7 +50,6 @@ Configuration options: #define ME2600_FIRMWARE "me2600_firmware.bin" -#define PCI_VENDOR_ID_MEILHAUS 0x1402 #define ME2000_DEVICE_ID 0x2000 #define ME2600_DEVICE_ID 0x2600 -- cgit v1.2.3 From 9409e1dafe278233d01d0294f63999e2c30e4b90 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 18:11:40 -0700 Subject: staging: comedi: hwdrv_APCI1710: remove APCI1710_BOARD_VENDOR_ID This vendor id exists in pci_ids.h as PCI_VENDOR_ID_ADDIDATA_OLD. Use the kernels provided id instead. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 4 ++-- drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 10ae752f21c..5a93fda0463 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -183,7 +183,7 @@ static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { {PCI_DEVICE(APCI3200_BOARD_VENDOR_ID, 0x3007)}, #endif #ifdef CONFIG_APCI_1710 - {PCI_DEVICE(APCI1710_BOARD_VENDOR_ID, APCI1710_BOARD_DEVICE_ID)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, APCI1710_BOARD_DEVICE_ID)}, #endif #ifdef CONFIG_APCI_16XX {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1009)}, @@ -594,7 +594,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_1710 { .pc_DriverName = "apci1710", - .i_VendorId = APCI1710_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, .i_DeviceId = APCI1710_BOARD_DEVICE_ID, .i_IorangeBase0 = 128, .i_IorangeBase1 = 8, diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h index 89c99eb5228..dab528e68c2 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h @@ -24,7 +24,6 @@ #define COMEDI_SUBD_INCREMENTALCOUNTER 17 /* Incremental Counter */ #define APCI1710_BOARD_NAME "apci1710" -#define APCI1710_BOARD_VENDOR_ID 0x10E8 #define APCI1710_BOARD_DEVICE_ID 0x818F #define APCI1710_ADDRESS_RANGE 256 #define APCI1710_CONFIG_ADDRESS_RANGE 8 -- cgit v1.2.3 From b6365c0b779de527dd575ed61ad7a3623a911f05 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 18:11:59 -0700 Subject: staging: comedi: addi_common: use PCI_VENDOR_ID_ADDIDATA The kernel provides this id in pci_ids.h. Use it instead of creating duplicates of the id with different names. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 40 +++++++++++----------- .../comedi/drivers/addi-data/hwdrv_apci035.h | 1 - .../comedi/drivers/addi-data/hwdrv_apci1032.h | 1 - .../comedi/drivers/addi-data/hwdrv_apci1516.h | 1 - .../comedi/drivers/addi-data/hwdrv_apci1564.h | 1 - .../comedi/drivers/addi-data/hwdrv_apci2016.h | 1 - .../comedi/drivers/addi-data/hwdrv_apci2032.h | 1 - .../comedi/drivers/addi-data/hwdrv_apci2200.h | 1 - .../comedi/drivers/addi-data/hwdrv_apci3200.h | 1 - .../comedi/drivers/addi-data/hwdrv_apci3501.h | 1 - 10 files changed, 20 insertions(+), 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 5a93fda0463..aaec0ab635d 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -147,22 +147,22 @@ static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { {PCI_DEVICE(APCI3120_BOARD_VENDOR_ID, 0x818D)}, #endif #ifdef CONFIG_APCI_1032 - {PCI_DEVICE(APCI1032_BOARD_VENDOR_ID, 0x1003)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1003)}, #endif #ifdef CONFIG_APCI_1516 - {PCI_DEVICE(APCI1516_BOARD_VENDOR_ID, 0x1001)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1001)}, #endif #ifdef CONFIG_APCI_2016 - {PCI_DEVICE(APCI2016_BOARD_VENDOR_ID, 0x1002)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1002)}, #endif #ifdef CONFIG_APCI_2032 - {PCI_DEVICE(APCI2032_BOARD_VENDOR_ID, 0x1004)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004)}, #endif #ifdef CONFIG_APCI_2200 - {PCI_DEVICE(APCI2200_BOARD_VENDOR_ID, 0x1005)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1005)}, #endif #ifdef CONFIG_APCI_1564 - {PCI_DEVICE(APCI1564_BOARD_VENDOR_ID, 0x1006)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1006)}, #endif #ifdef CONFIG_APCI_1500 {PCI_DEVICE(APCI1500_BOARD_VENDOR_ID, 0x80fc)}, @@ -171,16 +171,16 @@ static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { {PCI_DEVICE(APCI3120_BOARD_VENDOR_ID, 0x828D)}, #endif #ifdef CONFIG_APCI_3501 - {PCI_DEVICE(APCI3501_BOARD_VENDOR_ID, 0x3001)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001)}, #endif #ifdef CONFIG_APCI_035 - {PCI_DEVICE(APCI035_BOARD_VENDOR_ID, 0x0300)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x0300)}, #endif #ifdef CONFIG_APCI_3200 - {PCI_DEVICE(APCI3200_BOARD_VENDOR_ID, 0x3000)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3000)}, #endif #ifdef CONFIG_APCI_3300 - {PCI_DEVICE(APCI3200_BOARD_VENDOR_ID, 0x3007)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3007)}, #endif #ifdef CONFIG_APCI_1710 {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, APCI1710_BOARD_DEVICE_ID)}, @@ -268,7 +268,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_1032 { .pc_DriverName = "apci1032", - .i_VendorId = APCI1032_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x1003, .i_IorangeBase0 = 4, .i_IorangeBase1 = APCI1032_ADDRESS_RANGE, @@ -285,7 +285,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_1516 { .pc_DriverName = "apci1516", - .i_VendorId = APCI1516_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x1001, .i_IorangeBase0 = 128, .i_IorangeBase1 = APCI1516_ADDRESS_RANGE, @@ -309,7 +309,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_2016 { .pc_DriverName = "apci2016", - .i_VendorId = APCI2016_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x1002, .i_IorangeBase0 = 128, .i_IorangeBase1 = APCI2016_ADDRESS_RANGE, @@ -330,7 +330,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_2032 { .pc_DriverName = "apci2032", - .i_VendorId = APCI2032_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x1004, .i_IorangeBase0 = 4, .i_IorangeBase1 = APCI2032_ADDRESS_RANGE, @@ -353,7 +353,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_2200 { .pc_DriverName = "apci2200", - .i_VendorId = APCI2200_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x1005, .i_IorangeBase0 = 4, .i_IorangeBase1 = APCI2200_ADDRESS_RANGE, @@ -376,7 +376,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_1564 { .pc_DriverName = "apci1564", - .i_VendorId = APCI1564_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x1006, .i_IorangeBase0 = 128, .i_IorangeBase1 = APCI1564_ADDRESS_RANGE, @@ -470,7 +470,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_3501 { .pc_DriverName = "apci3501", - .i_VendorId = APCI3501_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3001, .i_IorangeBase0 = 64, .i_IorangeBase1 = APCI3501_ADDRESS_RANGE, @@ -498,7 +498,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_035 { .pc_DriverName = "apci035", - .i_VendorId = APCI035_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x0300, .i_IorangeBase0 = 127, .i_IorangeBase1 = APCI035_ADDRESS_RANGE, @@ -524,7 +524,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_3200 { .pc_DriverName = "apci3200", - .i_VendorId = APCI3200_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3000, .i_IorangeBase0 = 128, .i_IorangeBase1 = 256, @@ -560,7 +560,7 @@ static const struct addi_board boardtypes[] = { /* Begin JK .20.10.2004 = APCI-3300 integration */ { .pc_DriverName = "apci3300", - .i_VendorId = APCI3200_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x3007, .i_IorangeBase0 = 128, .i_IorangeBase1 = 256, diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h index 3c700c7bf81..5f1f7f1f4e6 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h @@ -16,7 +16,6 @@ */ /* Card Specific information */ -#define APCI035_BOARD_VENDOR_ID 0x15B8 #define APCI035_ADDRESS_RANGE 255 /* ANALOG INPUT RANGE */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h index 7114acb4bd2..58d2de4720d 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h @@ -17,7 +17,6 @@ /********* Definitions for APCI-1032 card *****/ -#define APCI1032_BOARD_VENDOR_ID 0x15B8 #define APCI1032_ADDRESS_RANGE 20 /* DIGITAL INPUT DEFINE */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h index 44728293e49..88e86712e81 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h @@ -18,7 +18,6 @@ /********* Definitions for APCI-1516 card *****/ /* Card Specific information */ -#define APCI1516_BOARD_VENDOR_ID 0x15B8 #define APCI1516_ADDRESS_RANGE 8 /* DIGITAL INPUT-OUTPUT DEFINE */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h index c91594d56a4..aa249e91465 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h @@ -17,7 +17,6 @@ /********* Definitions for APCI-1564 card *****/ -#define APCI1564_BOARD_VENDOR_ID 0x15B8 #define APCI1564_ADDRESS_RANGE 128 /* DIGITAL INPUT-OUTPUT DEFINE */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h index c42612af0fa..8792da90291 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h @@ -16,7 +16,6 @@ */ /********* Definitions for APCI-2016 card *****/ -#define APCI2016_BOARD_VENDOR_ID 0x15B8 #define APCI2016_ADDRESS_RANGE 8 /* DIGITAL INPUT-OUTPUT DEFINE */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h index ab145e7c940..6300067969c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h @@ -18,7 +18,6 @@ /********* Definitions for APCI-2032 card *****/ /* Card Specific information */ -#define APCI2032_BOARD_VENDOR_ID 0x15B8 #define APCI2032_ADDRESS_RANGE 63 /* DIGITAL INPUT-OUTPUT DEFINE */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h index 83f42af84b8..c4aaa0b9405 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h @@ -18,7 +18,6 @@ /********* Definitions for APCI-2200 card *****/ /* Card Specific information */ -#define APCI2200_BOARD_VENDOR_ID 0x15b8 #define APCI2200_ADDRESS_RANGE 64 /* DIGITAL INPUT-OUTPUT DEFINE */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h index 812a9c46e11..afa7ba304b3 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h @@ -16,7 +16,6 @@ */ /* Card Specific information */ -#define APCI3200_BOARD_VENDOR_ID 0x15B8 /* #define APCI3200_ADDRESS_RANGE 264 */ int MODULE_NO; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h index 63df635a7b6..81ba7f0f16c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h @@ -16,7 +16,6 @@ */ /* Card Specific information */ -#define APCI3501_BOARD_VENDOR_ID 0x15B8 #define APCI3501_ADDRESS_RANGE 255 #define APCI3501_DIGITAL_IP 0x50 -- cgit v1.2.3 From 64f2f9335915b87373f73cfb47f0a2d9ed190f2b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 18:12:17 -0700 Subject: staging: comedi: addi_common: use PCI_VENDOR_ID_ADDIDATA_OLD The kernel provides this id in pci_ids.h. Use it instead of creating duplicates of the id with different names. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 12 ++++++------ drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h | 1 - drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index aaec0ab635d..b166698c846 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -144,7 +144,7 @@ void fpu_end(void) static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { #ifdef CONFIG_APCI_3120 - {PCI_DEVICE(APCI3120_BOARD_VENDOR_ID, 0x818D)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x818D)}, #endif #ifdef CONFIG_APCI_1032 {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1003)}, @@ -165,10 +165,10 @@ static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1006)}, #endif #ifdef CONFIG_APCI_1500 - {PCI_DEVICE(APCI1500_BOARD_VENDOR_ID, 0x80fc)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x80fc)}, #endif #ifdef CONFIG_APCI_3001 - {PCI_DEVICE(APCI3120_BOARD_VENDOR_ID, 0x828D)}, + {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x828D)}, #endif #ifdef CONFIG_APCI_3501 {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001)}, @@ -225,7 +225,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_3120 { .pc_DriverName = "apci3120", - .i_VendorId = APCI3120_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, .i_DeviceId = 0x818D, .i_IorangeBase0 = AMCC_OP_REG_SIZE, .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, @@ -403,7 +403,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_1500 { .pc_DriverName = "apci1500", - .i_VendorId = APCI1500_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, .i_DeviceId = 0x80fc, .i_IorangeBase0 = 128, .i_IorangeBase1 = APCI1500_ADDRESS_RANGE, @@ -431,7 +431,7 @@ static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_3001 { .pc_DriverName = "apci3001", - .i_VendorId = APCI3120_BOARD_VENDOR_ID, + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, .i_DeviceId = 0x828D, .i_IorangeBase0 = AMCC_OP_REG_SIZE, .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h index 647f9ebf552..1f2bd0ff6a9 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h @@ -18,7 +18,6 @@ /********* Definitions for APCI-1500 card *****/ /* Card Specific information */ -#define APCI1500_BOARD_VENDOR_ID 0x10e8 #define APCI1500_ADDRESS_RANGE 4 /* DIGITAL INPUT-OUTPUT DEFINE */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h index 50eb0a0a0a0..0cd1e3d867d 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h @@ -42,7 +42,6 @@ static const struct comedi_lrange range_apci3120_ao = { 2, { #define APCI3120_BIPOLAR_RANGES 4 /* used for test on mixture of BIP/UNI ranges */ -#define APCI3120_BOARD_VENDOR_ID 0x10E8 #define APCI3120_ADDRESS_RANGE 16 #define APCI3120_DISABLE 0 -- cgit v1.2.3 From f656ef5b6c15e518dde43a6d6ae6c47dccc6c920 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 18:12:34 -0700 Subject: staging: comedi: comedidev.h: add PCI_VENDOR_ID_DT Add a define for the Data Translation, Inc. PCI vendor id. Remove the duplicates in the drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 + drivers/staging/comedi/drivers/dt3000.c | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index fa572073c0f..23b13b090c7 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -58,6 +58,7 @@ * PCI Vendor IDs not in */ #define PCI_VENDOR_ID_ICP 0x104c +#define PCI_VENDOR_ID_DT 0x1116 #define PCI_VENDOR_ID_CONTEC 0x1221 #define PCI_VENDOR_ID_CB 0x1307 /* Measurement Computing */ #define PCI_VENDOR_ID_ADVANTECH 0x13fe diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 46645759781..29e6f8ea67e 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -65,8 +65,6 @@ AO commands are not supported. #include "comedi_fc.h" -#define PCI_VENDOR_ID_DT 0x1116 - static const struct comedi_lrange range_dt3000_ai = { 4, { RANGE(-10, 10), RANGE(-5, 5), -- cgit v1.2.3 From 0d374622a8a45dec37702a40c803fb9e9e9cb8e0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 18:12:50 -0700 Subject: staging: comedi: comedidev.h: add PCI_VENDOR_ID_KOLTER Add a define for the Kolter Electronic PCI vendor id. Remove the duplicates in the drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 + drivers/staging/comedi/drivers/ke_counter.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 23b13b090c7..be0dfe52076 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -57,6 +57,7 @@ /* * PCI Vendor IDs not in */ +#define PCI_VENDOR_ID_KOLTER 0x1001 #define PCI_VENDOR_ID_ICP 0x104c #define PCI_VENDOR_ID_DT 0x1116 #define PCI_VENDOR_ID_CONTEC 0x1221 diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 355af553ed5..8780a12ef59 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -36,7 +36,6 @@ Kolter Electronic PCI Counter Card. #include "../comedidev.h" -#define PCI_VENDOR_ID_KOLTER 0x1001 #define CNT_CARD_DEVICE_ID 0x0014 /*-- counter write ----------------------------------------------------------*/ -- cgit v1.2.3 From 34f8d2089d0f7820da9cc24964da9f33d59c03b2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 18:13:12 -0700 Subject: staging: comedi: comedidev.h: add PCI_VENDOR_ID_IOTECH Add a define for the Iotech Inc. PCI vendor id. Remove the duplicates in the drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 + drivers/staging/comedi/drivers/daqboard2000.c | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index be0dfe52076..41f0b576532 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -60,6 +60,7 @@ #define PCI_VENDOR_ID_KOLTER 0x1001 #define PCI_VENDOR_ID_ICP 0x104c #define PCI_VENDOR_ID_DT 0x1116 +#define PCI_VENDOR_ID_IOTECH 0x1616 #define PCI_VENDOR_ID_CONTEC 0x1221 #define PCI_VENDOR_ID_CB 0x1307 /* Measurement Computing */ #define PCI_VENDOR_ID_ADVANTECH 0x13fe diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 87b9cd572f8..8bc6189c578 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -117,8 +117,6 @@ Configuration options: not applicable, uses PCI auto config #define DAQBOARD2000_FIRMWARE "daqboard2000_firmware.bin" -#define PCI_VENDOR_ID_IOTECH 0x1616 - #define DAQBOARD2000_SUBSYSTEM_IDS2 0x0002 /* Daqboard/2000 - 2 Dacs */ #define DAQBOARD2000_SUBSYSTEM_IDS4 0x0004 /* Daqboard/2000 - 4 Dacs */ -- cgit v1.2.3 From 50d3c3f591958d68a3dd9410c3682c91bd3dda4a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 18:13:43 -0700 Subject: staging: comedi: comedidev.h: add PCI_VENDOR_ID_RTD Add a define for the RTD Embedded Technologies, Inc. PCI vendor id. Remove the duplicates in the drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 + drivers/staging/comedi/drivers/rtd520.c | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 41f0b576532..b02d43a3277 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -65,6 +65,7 @@ #define PCI_VENDOR_ID_CB 0x1307 /* Measurement Computing */ #define PCI_VENDOR_ID_ADVANTECH 0x13fe #define PCI_VENDOR_ID_MEILHAUS 0x1402 +#define PCI_VENDOR_ID_RTD 0x1435 #define PCI_VENDOR_ID_ADLINK 0x144a #define COMEDI_NUM_MINORS 0x100 diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 0a91738eae3..fc0b1337a47 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -147,8 +147,6 @@ Configuration options: Board specific stuff ======================================================================*/ -/* registers */ -#define PCI_VENDOR_ID_RTD 0x1435 /* The board has three memory windows: las0, las1, and lcfg (the PCI chip) Las1 has the data and can be burst DMAed 32bits at a time. -- cgit v1.2.3 From 268533124d621360710e08e0ce71a3f5313b6c78 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 18:14:00 -0700 Subject: staging: comedi: comedidev.h: add PCI_VENDOR_ID_AMCC Add a define for the Applied Micro Circuits Corp. PCI vendor id. Remove the duplicates in the drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 + drivers/staging/comedi/drivers/adl_pci9118.c | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index b02d43a3277..8c4847c8422 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -59,6 +59,7 @@ */ #define PCI_VENDOR_ID_KOLTER 0x1001 #define PCI_VENDOR_ID_ICP 0x104c +#define PCI_VENDOR_ID_AMCC 0x10e8 #define PCI_VENDOR_ID_DT 0x1116 #define PCI_VENDOR_ID_IOTECH 0x1616 #define PCI_VENDOR_ID_CONTEC 0x1221 diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 4bcc5b1171d..a5d0be21eff 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -73,8 +73,6 @@ Configuration options: #include "8253.h" #include "comedi_fc.h" -#define PCI_VENDOR_ID_AMCC 0x10e8 - /* paranoid checks are broken */ #undef PCI9118_PARANOIDCHECK /* * if defined, then is used code which control -- cgit v1.2.3 From 00f5c774a0f551e297c343222d17a3f919c603d3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 18:14:19 -0700 Subject: staging: comedi: dyna_pci10xx: remove PCI_VENDOR_ID_DYNALOG The PCI chip used on this board is from PLX Technologies Inc. As stated in the comments of this driver, Dynalog does not have a registered PCI vendor id so this board uses the PLX vendor id. The kernel provides an id for that vendor in pci_ids.h (PCI_VENDOR_ID_PLX). Use it instead of creating a duplicate with a different name. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dyna_pci10xx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index c345660d781..656d08b20db 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -40,8 +40,6 @@ #include "../comedidev.h" #include -#define PCI_VENDOR_ID_DYNALOG 0x10b5 - #define READ_TIMEOUT 50 static const struct comedi_lrange range_pci1050_ai = { 3, { @@ -283,7 +281,7 @@ static void __devexit dyna_pci10xx_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(dyna_pci10xx_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_DYNALOG, 0x1050) }, + { PCI_DEVICE(PCI_VENDOR_ID_PLX, 0x1050) }, { 0 } }; MODULE_DEVICE_TABLE(pci, dyna_pci10xx_pci_table); -- cgit v1.2.3 From 2847ff5d1b63496c2e3eedb8efad2752cc2e195d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 24 Oct 2012 18:14:40 -0700 Subject: staging: comedi: comedidev.h: add PCI_VENDOR_ID_AMPLICON Add a define for the Amplicon Liveline Limited PCI vendor id. Remove the duplicates in the drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 1 + drivers/staging/comedi/drivers/amplc_dio200.c | 1 - drivers/staging/comedi/drivers/amplc_pc236.c | 1 - drivers/staging/comedi/drivers/amplc_pc263.c | 1 - drivers/staging/comedi/drivers/amplc_pci224.c | 1 - drivers/staging/comedi/drivers/amplc_pci230.c | 1 - 6 files changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 8c4847c8422..d9f2b8bfe6f 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -68,6 +68,7 @@ #define PCI_VENDOR_ID_MEILHAUS 0x1402 #define PCI_VENDOR_ID_RTD 0x1435 #define PCI_VENDOR_ID_ADLINK 0x144a +#define PCI_VENDOR_ID_AMPLICON 0x14dc #define COMEDI_NUM_MINORS 0x100 #define COMEDI_NUM_BOARD_MINORS 0x30 diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 95c3f7824d8..ffe3f7385c7 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -272,7 +272,6 @@ #define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_DIO200_PCI) /* PCI IDs */ -#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a #define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b #define PCI_DEVICE_ID_AMPLICON_PCIE236 0x0011 diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 52541c95ba6..c4516355b34 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -66,7 +66,6 @@ unused. #define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_PC236_PCI) /* PCI236 PCI configuration register information */ -#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009 #define PCI_DEVICE_ID_INVALID 0xffff diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 60830ccfb90..0369996a383 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -52,7 +52,6 @@ The state of the outputs can be read. #define DO_PCI IS_ENABLED(CONFIG_COMEDI_AMPLC_PC263_PCI) /* PCI263 PCI configuration register information */ -#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c #define PCI_DEVICE_ID_INVALID 0xffff diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 6a9ec11c4f0..610f2ce8fa1 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -116,7 +116,6 @@ Caveats: /* * PCI IDs. */ -#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007 #define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008 #define PCI_DEVICE_ID_INVALID 0xffff diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 2675eefe8b5..d66d7d797f7 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -198,7 +198,6 @@ for (or detection of) various hardware problems added by Ian Abbott. #include "8255.h" /* PCI230 PCI configuration register information */ -#define PCI_VENDOR_ID_AMPLICON 0x14dc #define PCI_DEVICE_ID_PCI230 0x0000 #define PCI_DEVICE_ID_PCI260 0x0006 #define PCI_DEVICE_ID_INVALID 0xffff -- cgit v1.2.3 From 4f72b738b1c8a9502a297f998b83ffae0815024b Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Thu, 25 Oct 2012 09:16:49 +0900 Subject: staging/comedi: Use pr_ or dev_ printks in drivers/serial2002.c fixed below checkpatch warning. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... and added pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/serial2002.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c index 4b3b9b02947..e6177b48cca 100644 --- a/drivers/staging/comedi/drivers/serial2002.c +++ b/drivers/staging/comedi/drivers/serial2002.c @@ -31,6 +31,8 @@ Status: in development */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "../comedidev.h" #include @@ -272,7 +274,7 @@ static struct serial_data serial_read(struct file *f, int timeout) length++; if (data < 0) { - printk(KERN_ERR "serial2002 error\n"); + pr_err("Failed to read serial.\n"); break; } else if (data & 0x80) { result.value = (result.value << 7) | (data & 0x7f); @@ -346,7 +348,7 @@ static int serial_2002_open(struct comedi_device *dev) devpriv->tty = filp_open(port, O_RDWR, 0); if (IS_ERR(devpriv->tty)) { result = (int)PTR_ERR(devpriv->tty); - printk(KERN_ERR "serial_2002: file open error = %d\n", result); + dev_err(dev->class_dev, "file open error = %d\n", result); } else { struct config_t { -- cgit v1.2.3 From 479696840239e0cc43efb3c917bdcad2174d2215 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 15 Oct 2012 21:48:48 -0300 Subject: i82975x_edac: Fix dimm label initialization The driver has only 4 hardcoded labels, but allows much more memory. Fix it by removing the hardcoded logic, using snprintf() instead. [ 19.833972] general protection fault: 0000 [#1] SMP [ 19.837733] Modules linked in: i82975x_edac(+) edac_core firewire_ohci firewire_core crc_itu_t nouveau mxm_wmi wmi video i2c_algo_bit drm_kms_helper ttm drm i2c_core [ 19.837733] CPU 0 [ 19.837733] Pid: 390, comm: udevd Not tainted 3.6.1-1.fc17.x86_64.debug #1 Dell Inc. Precision WorkStation 390 /0MY510 [ 19.837733] RIP: 0010:[] [] strncpy+0x18/0x30 [ 19.837733] RSP: 0018:ffff880078535b68 EFLAGS: 00010202 [ 19.837733] RAX: ffff880069fa9708 RBX: ffff880078588000 RCX: ffff880069fa9708 [ 19.837733] RDX: 000000000000001f RSI: 5f706f5f63616465 RDI: ffff880069fa9708 [ 19.837733] RBP: ffff880078535b68 R08: ffff880069fa9727 R09: 000000000000fffe [ 19.837733] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000003 [ 19.837733] R13: 0000000000000000 R14: ffff880069fa9290 R15: ffff880079624a80 [ 19.837733] FS: 00007f3de01ee840(0000) GS:ffff88007c400000(0000) knlGS:0000000000000000 [ 19.837733] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 19.837733] CR2: 00007f3de00b9000 CR3: 0000000078dbc000 CR4: 00000000000007f0 [ 19.837733] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 19.837733] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 19.837733] Process udevd (pid: 390, threadinfo ffff880078534000, task ffff880079642450) [ 19.837733] Stack: [ 19.837733] ffff880078535c18 ffffffffa017c6b8 00040000816d627f ffff880079624a88 [ 19.837733] ffffc90004cd6000 ffff880079624520 ffff88007ac21148 0000000000000000 [ 19.837733] 0000000000000000 0004000000000000 feda000078535bc8 ffffffff810d696d [ 19.837733] Call Trace: [ 19.837733] [] i82975x_init_one+0x2e6/0x3e6 [i82975x_edac] ... Fix bug reported at: https://bugzilla.redhat.com/show_bug.cgi?id=848149 And, very likely: https://bbs.archlinux.org/viewtopic.php?id=148033 https://bugzilla.kernel.org/show_bug.cgi?id=47171 Cc: Alan Cox Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i82975x_edac.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/edac/i82975x_edac.c b/drivers/edac/i82975x_edac.c index 069e26c11c4..a98020409fa 100644 --- a/drivers/edac/i82975x_edac.c +++ b/drivers/edac/i82975x_edac.c @@ -370,10 +370,6 @@ static enum dev_type i82975x_dram_type(void __iomem *mch_window, int rank) static void i82975x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev, void __iomem *mch_window) { - static const char *labels[4] = { - "DIMM A1", "DIMM A2", - "DIMM B1", "DIMM B2" - }; struct csrow_info *csrow; unsigned long last_cumul_size; u8 value; @@ -423,9 +419,10 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci, dimm = mci->csrows[index]->channels[chan]->dimm; dimm->nr_pages = nr_pages / csrow->nr_channels; - strncpy(csrow->channels[chan]->dimm->label, - labels[(index >> 1) + (chan * 2)], - EDAC_MC_LABEL_LEN); + + snprintf(csrow->channels[chan]->dimm->label, EDAC_MC_LABEL_LEN, "DIMM %c%d", + (chan == 0) ? 'A' : 'B', + index); dimm->grain = 1 << 7; /* 128Byte cache-line resolution */ dimm->dtype = i82975x_dram_type(mch_window, index); dimm->mtype = MEM_DDR2; /* I82975x supports only DDR2 */ -- cgit v1.2.3 From 24bef66e74d647aebd34e0bef7693512b7912029 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 24 Oct 2012 10:30:01 -0200 Subject: edac: Fix the dimm filling for csrows-based layouts The driver is currently filling data in a wrong way, on drivers for csrows-based memory controller, when the first layer is a csrow. This is not easily to notice, as, in general, memories are filed in dual, interleaved, symetric mode, as very few memory controllers support asymetric modes. While digging into a bug for i82795_edac driver, the asymetric mode there is now working, allowing us to fill the machine with 4x1GB ranks at channel 0, and 2x512GB at channel 1: Channel 0 ranks: EDAC DEBUG: i82975x_init_csrows: DIMM A0: from page 0x00000000 to 0x0003ffff (size: 0x00040000 pages) EDAC DEBUG: i82975x_init_csrows: DIMM A1: from page 0x00040000 to 0x0007ffff (size: 0x00040000 pages) EDAC DEBUG: i82975x_init_csrows: DIMM A2: from page 0x00080000 to 0x000bffff (size: 0x00040000 pages) EDAC DEBUG: i82975x_init_csrows: DIMM A3: from page 0x000c0000 to 0x000fffff (size: 0x00040000 pages) Channel 1 ranks: EDAC DEBUG: i82975x_init_csrows: DIMM B0: from page 0x00100000 to 0x0011ffff (size: 0x00020000 pages) EDAC DEBUG: i82975x_init_csrows: DIMM B1: from page 0x00120000 to 0x0013ffff (size: 0x00020000 pages) Instead of properly showing the memories as such, before this patch, it shows the memory layout as: +-----------------------------------+ | mc0 | | csrow0 | csrow1 | csrow2 | ----------+-----------------------------------+ channel1: | 1024 MB | 1024 MB | 512 MB | channel0: | 1024 MB | 1024 MB | 512 MB | ----------+-----------------------------------+ as if both channels were symetric, grouping the DIMMs on a wrong layout. After this patch, the memory is correctly represented. So, for csrows at layers[0], it shows: +-----------------------------------------------+ | mc0 | | csrow0 | csrow1 | csrow2 | csrow3 | ----------+-----------------------------------------------+ channel1: | 512 MB | 512 MB | 0 MB | 0 MB | channel0: | 1024 MB | 1024 MB | 1024 MB | 1024 MB | ----------+-----------------------------------------------+ For csrows at layers[1], it shows: +-----------------------+ | mc0 | | channel0 | channel1 | --------+-----------------------+ csrow3: | 1024 MB | 0 MB | csrow2: | 1024 MB | 0 MB | --------+-----------------------+ csrow1: | 1024 MB | 512 MB | csrow0: | 1024 MB | 512 MB | --------+-----------------------+ So, no matter of what comes first, the information between channel and csrow will be properly represented. Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/edac_mc.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index d5dc9da7f99..81eb9fd3f71 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -416,10 +416,18 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num, dimm->cschannel = chn; /* Increment csrow location */ - row++; - if (row == tot_csrows) { - row = 0; + if (layers[0].is_virt_csrow) { chn++; + if (chn == tot_channels) { + chn = 0; + row++; + } + } else { + row++; + if (row == tot_csrows) { + row = 0; + chn++; + } } /* Increment dimm location */ -- cgit v1.2.3 From 7e06b7a3333f5c7a0cec12aff20d39c5c87c0795 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 18 Oct 2012 15:54:45 +0200 Subject: i7300_edac: Fix error flag testing * Right-shift the values in GET_FBD_FAT_IDX and GET_FBD_NF_IDX, so that the callers get the result they expect. * Fix definition of FERR_FAT_FBD_ERR_MASK. * Call GET_FBD_NF_IDX, not GET_FBD_FAT_IDX, when operating on register FERR_NF_FBD. We were lucky they have the same definition. This fixes kernel bug #44131: https://bugzilla.kernel.org/show_bug.cgi?id=44131 Signed-off-by: Jean Delvare Cc: Mauro Carvalho Chehab Cc: Doug Thompson Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/edac/i7300_edac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c index a09d0667f72..9d669cd4361 100644 --- a/drivers/edac/i7300_edac.c +++ b/drivers/edac/i7300_edac.c @@ -197,8 +197,8 @@ static const char *ferr_fat_fbd_name[] = { [0] = "Memory Write error on non-redundant retry or " "FBD configuration Write error on retry", }; -#define GET_FBD_FAT_IDX(fbderr) (fbderr & (3 << 28)) -#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) +#define GET_FBD_FAT_IDX(fbderr) (((fbderr) >> 28) & 3) +#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 22)) #define FERR_NF_FBD 0xa0 static const char *ferr_nf_fbd_name[] = { @@ -225,7 +225,7 @@ static const char *ferr_nf_fbd_name[] = { [1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC", [0] = "Uncorrectable Data ECC on Replay", }; -#define GET_FBD_NF_IDX(fbderr) (fbderr & (3 << 28)) +#define GET_FBD_NF_IDX(fbderr) (((fbderr) >> 28) & 3) #define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\ (1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\ (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\ @@ -464,7 +464,7 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) errnum = find_first_bit(&errors, ARRAY_SIZE(ferr_nf_fbd_name)); specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum); - branch = (GET_FBD_FAT_IDX(error_reg) == 2) ? 1 : 0; + branch = (GET_FBD_NF_IDX(error_reg) == 2) ? 1 : 0; pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, REDMEMA, &syndrome); -- cgit v1.2.3 From ba361c92e73c771fcbbbd24c2c03c322e2de2e31 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 17 Oct 2012 18:50:13 -0300 Subject: perf tools: Don't stop synthesizing threads when one vanishes The perf_event__synthesize_threads routine synthesizes all the existing threads in the system, because we don't have any kernel facilities to ask for PERF_RECORD_{FORK,MMAP,COMM} for existing threads. It was returning an error as soon as one thread couldn't be synthesized, which is a bit extreme when, for instance, a forkish workload is running, like a kernel compile. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-i7oas1eodpoer2bx38fwyasv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 0ae444ef142..ca9ca285406 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -405,16 +405,15 @@ int perf_event__synthesize_threads(struct perf_tool *tool, if (*end) /* only interested in proper numerical dirents */ continue; - - if (__event__synthesize_thread(comm_event, mmap_event, pid, 1, - process, tool, machine) != 0) { - err = -1; - goto out_closedir; - } + /* + * We may race with exiting thread, so don't stop just because + * one thread couldn't be synthesized. + */ + __event__synthesize_thread(comm_event, mmap_event, pid, 1, + process, tool, machine); } err = 0; -out_closedir: closedir(proc); out_free_mmap: free(mmap_event); -- cgit v1.2.3 From efd5745e43f3aabd95d521289e0caa0e30668cf4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 17 Oct 2012 17:09:46 -0300 Subject: perf trace: Count number of events for each thread and globally The nr_events in trace__run was local, but we will need it in other trace methods, move it to struct trace. We'll also need the number of events per thread, so introduce a nr_events method for that in struct thread_trace. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ksutaz0mtejnf7e6az3ca1td@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index ba055103b52..c95a3e9b033 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -67,6 +67,7 @@ struct thread_trace { u64 entry_time; u64 exit_time; bool entry_pending; + unsigned long nr_events; char *entry_str; }; @@ -77,16 +78,21 @@ static struct thread_trace *thread_trace__new(void) static struct thread_trace *thread__trace(struct thread *thread) { + struct thread_trace *ttrace; + if (thread == NULL) goto fail; if (thread->priv == NULL) thread->priv = thread_trace__new(); - + if (thread->priv == NULL) goto fail; - return thread->priv; + ttrace = thread->priv; + ++ttrace->nr_events; + + return ttrace; fail: color_fprintf(stdout, PERF_COLOR_RED, "WARNING: not enough memory, dropping samples!\n"); @@ -102,6 +108,7 @@ struct trace { struct perf_record_opts opts; struct machine host; u64 base_time; + unsigned long nr_events; bool multiple_threads; double duration_filter; }; @@ -386,7 +393,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv) { struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); struct perf_evsel *evsel; - int err = -1, i, nr_events = 0, before; + int err = -1, i; + unsigned long before; const bool forks = argc > 0; if (evlist == NULL) { @@ -444,7 +452,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) trace->multiple_threads = evlist->threads->map[0] == -1 || evlist->threads->nr > 1; again: - before = nr_events; + before = trace->nr_events; for (i = 0; i < evlist->nr_mmaps; i++) { union perf_event *event; @@ -454,7 +462,7 @@ again: tracepoint_handler handler; struct perf_sample sample; - ++nr_events; + ++trace->nr_events; err = perf_evlist__parse_sample(evlist, event, &sample); if (err) { @@ -495,7 +503,7 @@ again: } } - if (nr_events == before) { + if (trace->nr_events == before) { if (done) goto out_delete_evlist; -- cgit v1.2.3 From 1302d88e66f12a7b46a5598e641d93f0713007e0 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 17 Oct 2012 17:13:12 -0300 Subject: perf trace: Use sched:sched_stat_runtime to provide a thread summary [root@sandy ~]# perf trace --sched --duration 0.100 --pid `pidof firefox` 17079.847 ( 0.009 ms): 17643 poll(ufds: 140037623086496, nfds: 11, timeout_msecs: 0) = 0 Timeout 17079.892 ( 0.010 ms): 17643 read(fd: 4, buf: 140038178943092, count: 4096 ) = -1 EAGAIN Resource temporarily unavailable 17079.921 ( 0.013 ms): 17643 poll(ufds: 140037623086496, nfds: 11, timeout_msecs: 0) = 0 Timeout 17079.949 ( 0.009 ms): 17643 read(fd: 4, buf: 140038178943092, count: 4096 ) = -1 EAGAIN Resource temporarily unavailable ^C _____________________________________________________________________ __) Summary of events (__ [ task - pid ] [ events ] [ ratio ] [ runtime ] _____________________________________________________________________ firefox - 17643 : 18013 [ 72.2% ] 359.110 ms firefox - 17663 : 41 [ 0.2% ] 21.439 ms firefox - 17664 : 6840 [ 27.4% ] 133.642 ms firefox - 17667 : 46 [ 0.2% ] 0.682 ms [root@sandy ~]# This is equivalent to the 'perf trace summary' subcomand in the tmp.perf/trace2 branch. Another example, setting a huge duration filter to get just a system wide summary: [root@sandy ~]# perf trace --duration 10000.0 --sched ^C _____________________________________________________________________ __) Summary of events (__ [ task - pid ] [ events ] [ ratio ] [ runtime ] _____________________________________________________________________ scsi_eh_1 - 258 : 15 [ 0.0% ] 0.133 ms kworker/0:1H - 322 : 13 [ 0.0% ] 0.032 ms jbd2/dm-0-8 - 384 : 4 [ 0.0% ] 0.115 ms flush-253:0 - 470 : 1 [ 0.0% ] 0.027 ms firefox - 950 : 4783 [ 0.1% ] 24.863 ms firefox - 992 : 1883 [ 0.1% ] 6.808 ms firefox - 995 : 35 [ 0.0% ] 0.111 ms ksoftirqd/6 - 4362 : 2 [ 0.0% ] 0.005 ms ksoftirqd/7 - 4365 : 1 [ 0.0% ] 0.007 ms Xorg - 4671 : 148 [ 0.0% ] 0.912 ms gnome-settings- - 4846 : 14 [ 0.0% ] 0.086 ms seahorse-daemon - 4847 : 14 [ 0.0% ] 0.092 ms gnome-panel - 4875 : 46 [ 0.0% ] 0.159 ms gnome-power-man - 4918 : 16 [ 0.0% ] 0.065 ms gvfs-afc-volume - 4992 : 77 [ 0.0% ] 0.136 ms gnome-screensav - 5114 : 24 [ 0.0% ] 0.128 ms xchat - 8082 : 466 [ 0.0% ] 2.019 ms synergyc - 8369 : 941 [ 0.0% ] 3.291 ms synergyc - 8371 : 85 [ 0.0% ] 1.817 ms jbd2/dm-4-8 - 9352 : 4 [ 0.0% ] 0.109 ms rpcbind - 9786 : 3 [ 0.0% ] 0.017 ms rtkit-daemon - 12802 : 10 [ 0.0% ] 0.038 ms rtkit-daemon - 12803 : 8 [ 0.0% ] 0.000 ms udisks-daemon - 13020 : 27 [ 0.0% ] 0.240 ms kworker/7:0 - 14651 : 669 [ 0.0% ] 2.616 ms kworker/5:1 - 16220 : 2 [ 0.0% ] 0.069 ms kworker/4:0 - 19776 : 13 [ 0.0% ] 0.176 ms openvpn - 20131 : 133 [ 0.0% ] 0.762 ms plugin-containe - 20508 : 60658 [ 1.7% ] 131.153 ms npviewer.bin - 20520 : 72208 [ 2.0% ] 138.945 ms npviewer.bin - 20542 : 35 [ 0.0% ] 0.074 ms npviewer.bin - 20543 : 30 [ 0.0% ] 0.074 ms npviewer.bin - 20547 : 35 [ 0.0% ] 0.092 ms npviewer.bin - 20552 : 35 [ 0.0% ] 0.093 ms sshd - 20645 : 32 [ 0.0% ] 0.071 ms npviewer.bin - 21053 : 35 [ 0.0% ] 0.074 ms npviewer.bin - 21054 : 35 [ 0.0% ] 0.097 ms kworker/0:2 - 21169 : 149 [ 0.0% ] 1.143 ms kworker/3:0 - 22171 : 113 [ 0.0% ] 96.892 ms flush-253:4 - 22410 : 1 [ 0.0% ] 0.028 ms kworker/6:0 - 24581 : 25 [ 0.0% ] 0.275 ms kworker/1:0 - 25572 : 4 [ 0.0% ] 0.103 ms kworker/2:1 - 26299 : 138 [ 0.0% ] 1.440 ms kworker/0:0 - 26325 : 1 [ 0.0% ] 0.003 ms perf - 26330 : 3506967 [ 96.1% ] 6648.310 ms [root@sandy ~]# Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Thomas Gleixner Link: http://lkml.kernel.org/n/tip-mzuli0srnxyi1o029py6537x@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-trace.txt | 3 ++ tools/perf/builtin-trace.c | 88 ++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index 38d4b682af0..68718ccdd17 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -51,6 +51,9 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs. --duration: Show only events that had a duration greater than N.M ms. +--sched: + Accrue thread runtime and provide a summary at the end of the session. + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-script[1] diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c95a3e9b033..7932ffa2988 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -69,6 +69,7 @@ struct thread_trace { bool entry_pending; unsigned long nr_events; char *entry_str; + double runtime_ms; }; static struct thread_trace *thread_trace__new(void) @@ -109,8 +110,10 @@ struct trace { struct machine host; u64 base_time; unsigned long nr_events; + bool sched; bool multiple_threads; double duration_filter; + double runtime_ms; }; static bool trace__filter_duration(struct trace *trace, double t) @@ -389,6 +392,31 @@ out: return 0; } +static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evsel, + struct perf_sample *sample) +{ + u64 runtime = perf_evsel__intval(evsel, sample, "runtime"); + double runtime_ms = (double)runtime / NSEC_PER_MSEC; + struct thread *thread = machine__findnew_thread(&trace->host, sample->tid); + struct thread_trace *ttrace = thread__trace(thread); + + if (ttrace == NULL) + goto out_dump; + + ttrace->runtime_ms += runtime_ms; + trace->runtime_ms += runtime_ms; + return 0; + +out_dump: + printf("%s: comm=%s,pid=%u,runtime=%" PRIu64 ",vruntime=%" PRIu64 ")\n", + evsel->name, + perf_evsel__strval(evsel, sample, "comm"), + (pid_t)perf_evsel__intval(evsel, sample, "pid"), + runtime, + perf_evsel__intval(evsel, sample, "vruntime")); + return 0; +} + static int trace__run(struct trace *trace, int argc, const char **argv) { struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); @@ -408,6 +436,13 @@ static int trace__run(struct trace *trace, int argc, const char **argv) goto out_delete_evlist; } + if (trace->sched && + perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime", + trace__sched_stat_runtime)) { + printf("Couldn't read the sched_stat_runtime tracepoint information!\n"); + goto out_delete_evlist; + } + err = perf_evlist__create_maps(evlist, &trace->opts.target); if (err < 0) { printf("Problems parsing the target to trace, check your options!\n"); @@ -521,6 +556,51 @@ out: return err; } +static size_t trace__fprintf_threads_header(FILE *fp) +{ + size_t printed; + + printed = fprintf(fp, "\n _____________________________________________________________________\n"); + printed += fprintf(fp," __) Summary of events (__\n\n"); + printed += fprintf(fp," [ task - pid ] [ events ] [ ratio ] [ runtime ]\n"); + printed += fprintf(fp," _____________________________________________________________________\n\n"); + + return printed; +} + +static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp) +{ + size_t printed = trace__fprintf_threads_header(fp); + struct rb_node *nd; + + for (nd = rb_first(&trace->host.threads); nd; nd = rb_next(nd)) { + struct thread *thread = rb_entry(nd, struct thread, rb_node); + struct thread_trace *ttrace = thread->priv; + const char *color; + double ratio; + + if (ttrace == NULL) + continue; + + ratio = (double)ttrace->nr_events / trace->nr_events * 100.0; + + color = PERF_COLOR_NORMAL; + if (ratio > 50.0) + color = PERF_COLOR_RED; + else if (ratio > 25.0) + color = PERF_COLOR_GREEN; + else if (ratio > 5.0) + color = PERF_COLOR_YELLOW; + + printed += color_fprintf(fp, color, "%20s", thread->comm); + printed += fprintf(fp, " - %-5d :%11lu [", thread->pid, ttrace->nr_events); + printed += color_fprintf(fp, color, "%5.1f%%", ratio); + printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms); + } + + return printed; +} + static int trace__set_duration(const struct option *opt, const char *str, int unset __maybe_unused) { @@ -571,6 +651,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) OPT_CALLBACK(0, "duration", &trace, "float", "show only events with duration > N.M ms", trace__set_duration), + OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"), OPT_END() }; int err; @@ -595,5 +676,10 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) if (!argc && perf_target__none(&trace.opts.target)) trace.opts.target.system_wide = true; - return trace__run(&trace, argc, argv); + err = trace__run(&trace, argc, argv); + + if (trace.sched && !err) + trace__fprintf_thread_summary(&trace, stdout); + + return err; } -- cgit v1.2.3 From bad9955db1b73d7286f74a8136a0628a9b1ac017 Mon Sep 17 00:00:00 2001 From: Benjamin Poirier Date: Sun, 21 Oct 2012 05:27:53 -0400 Subject: menuconfig: Replace CIRCLEQ by list_head-style lists. sys/queue.h and CIRCLEQ in particular have proven to cause portability problems (reported on Debian Sarge, Cygwin and FreeBSD) Reported-by: Tetsuo Handa Tested-by: Tetsuo Handa Tested-by: Yaakov Selkowitz Signed-off-by: Benjamin Poirier Signed-off-by: "Yann E. MORIN" Signed-off-by: Michal Marek --- scripts/kconfig/expr.h | 5 +-- scripts/kconfig/list.h | 91 +++++++++++++++++++++++++++++++++++++++++++++ scripts/kconfig/lkc_proto.h | 4 +- scripts/kconfig/mconf.c | 6 +-- scripts/kconfig/menu.c | 14 ++++--- 5 files changed, 106 insertions(+), 14 deletions(-) create mode 100644 scripts/kconfig/list.h diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index bd2e0989555..cdd48600e02 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -12,7 +12,7 @@ extern "C" { #include #include -#include +#include "list.h" #ifndef __cplusplus #include #endif @@ -175,12 +175,11 @@ struct menu { #define MENU_ROOT 0x0002 struct jump_key { - CIRCLEQ_ENTRY(jump_key) entries; + struct list_head entries; size_t offset; struct menu *target; int index; }; -CIRCLEQ_HEAD(jk_head, jump_key); #define JUMP_NB 9 diff --git a/scripts/kconfig/list.h b/scripts/kconfig/list.h new file mode 100644 index 00000000000..0ae730be5f4 --- /dev/null +++ b/scripts/kconfig/list.h @@ -0,0 +1,91 @@ +#ifndef LIST_H +#define LIST_H + +/* + * Copied from include/linux/... + */ + +#undef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) + +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + + +struct list_head { + struct list_head *next, *prev; +}; + + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static inline int list_empty(const struct list_head *head) +{ + return head->next == head; +} + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static inline void __list_add(struct list_head *_new, + struct list_head *prev, + struct list_head *next) +{ + next->prev = _new; + _new->next = next; + _new->prev = prev; + prev->next = _new; +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static inline void list_add_tail(struct list_head *_new, struct list_head *head) +{ + __list_add(_new, head->prev, head); +} + +#endif diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h index 1d1c08537f1..ef1a7381f95 100644 --- a/scripts/kconfig/lkc_proto.h +++ b/scripts/kconfig/lkc_proto.h @@ -21,9 +21,9 @@ P(menu_get_root_menu,struct menu *,(struct menu *menu)); P(menu_get_parent_menu,struct menu *,(struct menu *menu)); P(menu_has_help,bool,(struct menu *menu)); P(menu_get_help,const char *,(struct menu *menu)); -P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct jk_head +P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head *head)); -P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct jk_head +P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head *head)); P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help)); diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 48f67448af7..53975cf8760 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -312,7 +312,7 @@ static void set_config_filename(const char *config_filename) struct search_data { - struct jk_head *head; + struct list_head *head; struct menu **targets; int *keys; }; @@ -323,7 +323,7 @@ static void update_text(char *buf, size_t start, size_t end, void *_data) struct jump_key *pos; int k = 0; - CIRCLEQ_FOREACH(pos, data->head, entries) { + list_for_each_entry(pos, data->head, entries) { if (pos->offset >= start && pos->offset < end) { char header[4]; @@ -375,7 +375,7 @@ again: sym_arr = sym_re_search(dialog_input); do { - struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head); + LIST_HEAD(head); struct menu *targets[JUMP_NB]; int keys[JUMP_NB + 1], i; struct search_data data = { diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index a3cade659f8..e98a05c8e50 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -508,7 +508,7 @@ const char *menu_get_help(struct menu *menu) } static void get_prompt_str(struct gstr *r, struct property *prop, - struct jk_head *head) + struct list_head *head) { int i, j; struct menu *submenu[8], *menu, *location = NULL; @@ -544,12 +544,13 @@ static void get_prompt_str(struct gstr *r, struct property *prop, } else jump->target = location; - if (CIRCLEQ_EMPTY(head)) + if (list_empty(head)) jump->index = 0; else - jump->index = CIRCLEQ_LAST(head)->index + 1; + jump->index = list_entry(head->prev, struct jump_key, + entries)->index + 1; - CIRCLEQ_INSERT_TAIL(head, jump, entries); + list_add_tail(&jump->entries, head); } if (i > 0) { @@ -573,7 +574,8 @@ static void get_prompt_str(struct gstr *r, struct property *prop, /* * head is optional and may be NULL */ -void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head) +void get_symbol_str(struct gstr *r, struct symbol *sym, + struct list_head *head) { bool hit; struct property *prop; @@ -612,7 +614,7 @@ void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head) str_append(r, "\n\n"); } -struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head) +struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head) { struct symbol *sym; struct gstr res = str_new(); -- cgit v1.2.3 From 0d13ac96b9c38e3e5434c93990e4bbf0939ab199 Mon Sep 17 00:00:00 2001 From: Jovi Zhang Date: Wed, 18 Jul 2012 17:51:26 +0800 Subject: uprobes: Fix misleading log entry There don't have any 'r' prefix in uprobe event naming, remove it. Signed-off-by: Jovi Zhang Acked-by: Srikar Dronamraju Signed-off-by: Oleg Nesterov --- kernel/trace/trace_uprobe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 03003cd7dd9..f3c3811f7e1 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -189,7 +189,7 @@ static int create_trace_uprobe(int argc, char **argv) if (argv[0][0] == '-') is_delete = true; else if (argv[0][0] != 'p') { - pr_info("Probe definition must be started with 'p', 'r' or" " '-'.\n"); + pr_info("Probe definition must be started with 'p' or '-'.\n"); return -EINVAL; } -- cgit v1.2.3 From ea29c4ea2b04462e92f409cd852dfe0d6d04f0fc Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 15 Oct 2012 12:48:11 +0300 Subject: OMAPDSS: DSI: fix dsi_get_dsidev_from_id() If dsi_get_dsidev_from_id() is called with a DSI module id that does not exist on the board, the function will crash as omap_dss_get_output() will return NULL. This happens on omap3 boards when dumping DSI clocks, as the dumping code will try to get the dsidev for DSI modules 0 and 1, but omap3 only has DSI module 0. Also clean up the id -> output mapping, so that if the function is called with invalid module ID it will return NULL. Signed-off-by: Tomi Valkeinen Cc: Archit Taneja --- drivers/video/omap2/dss/dsi.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index d64ac384288..bee92846cfa 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -365,11 +365,20 @@ struct platform_device *dsi_get_dsidev_from_id(int module) struct omap_dss_output *out; enum omap_dss_output_id id; - id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; + switch (module) { + case 0: + id = OMAP_DSS_OUTPUT_DSI1; + break; + case 1: + id = OMAP_DSS_OUTPUT_DSI2; + break; + default: + return NULL; + } out = omap_dss_get_output(id); - return out->pdev; + return out ? out->pdev : NULL; } static inline void dsi_write_reg(struct platform_device *dsidev, -- cgit v1.2.3 From 41fd087f5d452361d58cb618b1b8ecf749b68ad6 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Fri, 19 Oct 2012 08:24:18 -0300 Subject: [media] s5p-fimc: Don't ignore return value of vb2_queue_init() Add missing checks for return value of vb2_queue_init(), after this function has been modified recently to not throw BUG_ON(). This eliminates related compiler warnings, drivers/media/platform/s5p-fimc/fimc-lite.c: In function fimc_lite_subdev_registered: drivers/media/platform/s5p-fimc/fimc-lite.c:1256:16: warning: ignoring return value of vb2_queue_init, declared with attribute warn_unused_result [-Wunused-result] drivers/media/platform/s5p-fimc/fimc-capture.c: In function fimc_register_capture_device: drivers/media/platform/s5p-fimc/fimc-capture.c:1739:16: warning: ignoring return value of vb2_queue_init, declared with attribute warn_unused_result [-Wunused-result] Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-fimc/fimc-capture.c | 4 +++- drivers/media/platform/s5p-fimc/fimc-lite.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c b/drivers/media/platform/s5p-fimc/fimc-capture.c index 367efd164d0..3d39d97abaa 100644 --- a/drivers/media/platform/s5p-fimc/fimc-capture.c +++ b/drivers/media/platform/s5p-fimc/fimc-capture.c @@ -1736,7 +1736,9 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct fimc_vid_buffer); - vb2_queue_init(q); + ret = vb2_queue_init(q); + if (ret) + goto err_ent; vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0); diff --git a/drivers/media/platform/s5p-fimc/fimc-lite.c b/drivers/media/platform/s5p-fimc/fimc-lite.c index 70bcf39de87..9db246bed84 100644 --- a/drivers/media/platform/s5p-fimc/fimc-lite.c +++ b/drivers/media/platform/s5p-fimc/fimc-lite.c @@ -1253,7 +1253,9 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) q->buf_struct_size = sizeof(struct flite_buffer); q->drv_priv = fimc; - vb2_queue_init(q); + ret = vb2_queue_init(q); + if (ret < 0) + return ret; fimc->vd_pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0); -- cgit v1.2.3 From 02924ca45893adb9ad2383696006272fe8c2ef64 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 22 Oct 2012 06:12:05 -0300 Subject: [media] s5p-csis: Select S5P_SETUP_MIPIPHY After commit ccbfd1d49dc0d6a "[media] s5p-csis: Replace phy_enable platform.." s5p-csis depends now on the commmon MIPI CSIS/MIPI DSIM DPHY control code. Add select S5P_SETUP_MIPIPHY to make this dependency explicit, until the code from arch/arm/plat-samsung is moved to drivers/ directory and converted to a regular phy driver module. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-fimc/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/s5p-fimc/Kconfig b/drivers/media/platform/s5p-fimc/Kconfig index 8f090a8f270..c16b20d86ed 100644 --- a/drivers/media/platform/s5p-fimc/Kconfig +++ b/drivers/media/platform/s5p-fimc/Kconfig @@ -24,6 +24,7 @@ config VIDEO_S5P_FIMC config VIDEO_S5P_MIPI_CSIS tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver" depends on REGULATOR + select S5P_SETUP_MIPIPHY help This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2 receiver (MIPI-CSIS) devices. -- cgit v1.2.3 From afd7348c60b4f5d3d4d041aa0c29a6258a476b89 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 25 Oct 2012 10:48:44 -0300 Subject: [media] s5p-fimc: Fix platform entities registration Make sure the platform sub-devices are registered to the media device driver only when v4l2_device_register_subdev() succeeds. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-fimc/fimc-mdevice.c | 33 +++++++++++++------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index 80ada5882f6..a55370219a9 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -345,25 +345,23 @@ static int fimc_register_callback(struct device *dev, void *p) struct fimc_dev *fimc = dev_get_drvdata(dev); struct v4l2_subdev *sd = &fimc->vid_cap.subdev; struct fimc_md *fmd = p; - int ret = 0; - - if (!fimc || !fimc->pdev) - return 0; + int ret; - if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS) + if (fimc == NULL || fimc->id >= FIMC_MAX_DEVS) return 0; - fimc->pipeline_ops = &fimc_pipeline_ops; - fmd->fimc[fimc->pdev->id] = fimc; sd->grp_id = FIMC_GROUP_ID; ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); if (ret) { v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n", fimc->id, ret); + return ret; } - return ret; + fimc->pipeline_ops = &fimc_pipeline_ops; + fmd->fimc[fimc->id] = fimc; + return 0; } static int fimc_lite_register_callback(struct device *dev, void *p) @@ -373,14 +371,9 @@ static int fimc_lite_register_callback(struct device *dev, void *p) struct fimc_md *fmd = p; int ret; - if (fimc == NULL) + if (fimc == NULL || fimc->index >= FIMC_LITE_MAX_DEVS) return 0; - if (fimc->index >= FIMC_LITE_MAX_DEVS) - return 0; - - fimc->pipeline_ops = &fimc_pipeline_ops; - fmd->fimc_lite[fimc->index] = fimc; sd->grp_id = FLITE_GROUP_ID; ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); @@ -388,8 +381,12 @@ static int fimc_lite_register_callback(struct device *dev, void *p) v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC-LITE.%d (%d)\n", fimc->index, ret); + return ret; } - return ret; + + fimc->pipeline_ops = &fimc_pipeline_ops; + fmd->fimc_lite[fimc->index] = fimc; + return 0; } static int csis_register_callback(struct device *dev, void *p) @@ -407,10 +404,12 @@ static int csis_register_callback(struct device *dev, void *p) v4l2_info(sd, "csis%d sd: %s\n", pdev->id, sd->name); id = pdev->id < 0 ? 0 : pdev->id; - fmd->csis[id].sd = sd; sd->grp_id = CSIS_GROUP_ID; + ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); - if (ret) + if (!ret) + fmd->csis[id].sd = sd; + else v4l2_err(&fmd->v4l2_dev, "Failed to register CSIS subdevice: %d\n", ret); return ret; -- cgit v1.2.3 From 8163ec0b2648c2f7e84edb969dde537ec45f1666 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 25 Oct 2012 10:56:00 -0300 Subject: [media] s5p-fimc: Fix potential NULL pointer dereference 'fimc' was being dereferenced before the NULL check. Moved it to after the check. Signed-off-by: Sachin Kamat Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/s5p-fimc/fimc-mdevice.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/s5p-fimc/fimc-mdevice.c b/drivers/media/platform/s5p-fimc/fimc-mdevice.c index a55370219a9..38ea4d143a4 100644 --- a/drivers/media/platform/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/platform/s5p-fimc/fimc-mdevice.c @@ -343,13 +343,14 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) static int fimc_register_callback(struct device *dev, void *p) { struct fimc_dev *fimc = dev_get_drvdata(dev); - struct v4l2_subdev *sd = &fimc->vid_cap.subdev; + struct v4l2_subdev *sd; struct fimc_md *fmd = p; int ret; if (fimc == NULL || fimc->id >= FIMC_MAX_DEVS) return 0; + sd = &fimc->vid_cap.subdev; sd->grp_id = FIMC_GROUP_ID; ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); @@ -367,16 +368,15 @@ static int fimc_register_callback(struct device *dev, void *p) static int fimc_lite_register_callback(struct device *dev, void *p) { struct fimc_lite *fimc = dev_get_drvdata(dev); - struct v4l2_subdev *sd = &fimc->subdev; struct fimc_md *fmd = p; int ret; if (fimc == NULL || fimc->index >= FIMC_LITE_MAX_DEVS) return 0; - sd->grp_id = FLITE_GROUP_ID; + fimc->subdev.grp_id = FLITE_GROUP_ID; - ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd); + ret = v4l2_device_register_subdev(&fmd->v4l2_dev, &fimc->subdev); if (ret) { v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC-LITE.%d (%d)\n", -- cgit v1.2.3 From 6f602912c9d0c84c2edbd446dd9f72660b701605 Mon Sep 17 00:00:00 2001 From: Jarkko Huijts Date: Wed, 10 Oct 2012 15:05:06 +0200 Subject: usb: serial: ftdi_sio: Add missing chars_in_buffer function The driver does not wait until the hardware buffer (for data from the PC to the UART line) is drained when tcdrain or close is called in an application. Solution: Implement a chars_in_buffer function that checks both the software and hardware buffer. If the TEMT (TX empty) bit of the line status register indicates the hw buffer is not empty, let the function return at least 1. This has been verified to work correctly with an FT232RL. The check on the hw buffer can not be done for the original SIO device. Signed-off-by: Jarkko Huijts Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 60 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index be845873e23..38151557223 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -923,6 +923,7 @@ static int ftdi_get_icount(struct tty_struct *tty, static int ftdi_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static void ftdi_break_ctl(struct tty_struct *tty, int break_state); +static int ftdi_chars_in_buffer(struct tty_struct *tty); static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base); static unsigned short int ftdi_232am_baud_to_divisor(int baud); @@ -957,6 +958,7 @@ static struct usb_serial_driver ftdi_sio_device = { .ioctl = ftdi_ioctl, .set_termios = ftdi_set_termios, .break_ctl = ftdi_break_ctl, + .chars_in_buffer = ftdi_chars_in_buffer, }; static struct usb_serial_driver * const serial_drivers[] = { @@ -2089,6 +2091,64 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) } +static int ftdi_chars_in_buffer(struct tty_struct *tty) +{ + struct usb_serial_port *port = tty->driver_data; + struct ftdi_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + int chars; + unsigned char *buf; + int ret; + + /* Check software buffer (code from + * usb_serial_generic_chars_in_buffer()) */ + spin_lock_irqsave(&port->lock, flags); + chars = kfifo_len(&port->write_fifo) + port->tx_bytes; + spin_unlock_irqrestore(&port->lock, flags); + + /* Check hardware buffer */ + switch (priv->chip_type) { + case FT8U232AM: + case FT232BM: + case FT2232C: + case FT232RL: + case FT2232H: + case FT4232H: + case FT232H: + case FTX: + break; + case SIO: + default: + return chars; + } + + buf = kmalloc(2, GFP_KERNEL); + if (!buf) { + dev_err(&port->dev, "kmalloc failed"); + return chars; + } + + ret = usb_control_msg(port->serial->dev, + usb_rcvctrlpipe(port->serial->dev, 0), + FTDI_SIO_GET_MODEM_STATUS_REQUEST, + FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, + 0, priv->interface, + buf, 2, WDR_TIMEOUT); + + if (ret < 2) { + dev_err(&port->dev, "Unable to read modem and line status: " + "%i\n", ret); + goto chars_in_buffer_out; + } + + if (!(buf[1] & FTDI_RS_TEMT)) + chars++; + +chars_in_buffer_out: + kfree(buf); + return chars; +} + /* old_termios contains the original termios settings and tty->termios contains * the new setting to be used * WARNING: set_termios calls this with old_termios in kernel space -- cgit v1.2.3 From 43993e4af02ec99908d6d99176773fc2a3ee4c57 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 25 Oct 2012 10:30:34 -0700 Subject: ARM: OMAP2+: PM: add missing newline to VC warning message Add missing newline to warning message to avoid annoying wrapping problems during kernel boot like this one: omap_vc_i2c_init: I2C config for vdd_iva does not match other channels (0). omap_vc_i2c_init: I2C config for vdd_mpu does not match other channels (0).Power Management for TI OMAP4. Reported-by: Russell King Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/vc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 880249b1701..75878c37959 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c @@ -264,7 +264,7 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm) if (initialized) { if (voltdm->pmic->i2c_high_speed != i2c_high_speed) - pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).", + pr_warn("%s: I2C config for vdd_%s does not match other channels (%u).\n", __func__, voltdm->name, i2c_high_speed); return; } -- cgit v1.2.3 From b0f9bf369f34791cf8271be8c610a1e50ead6002 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 8 Oct 2012 08:35:56 -0300 Subject: [media] dvb-frontends: fix potential NULL pointer dereference in stv0900_set_mclk() The dereference should be moved below the NULL test. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-frontends/stv0900_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c index 262dfa503c2..b551ca350e0 100644 --- a/drivers/media/dvb-frontends/stv0900_core.c +++ b/drivers/media/dvb-frontends/stv0900_core.c @@ -300,15 +300,15 @@ static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 { u32 m_div, clk_sel; - dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, - intp->quartz); - if (intp == NULL) return STV0900_INVALID_HANDLE; if (intp->errs) return STV0900_I2C_ERROR; + dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk, + intp->quartz); + clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6); m_div = ((clk_sel * mclk) / intp->quartz) - 1; stv0900_write_bits(intp, F0900_M_DIV, m_div); -- cgit v1.2.3 From e3224111b3a527eb8f9b9b6deed83b727522941e Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Thu, 25 Oct 2012 12:46:21 -0400 Subject: staging: dgrp: remove use of real_raw and read_cnt in dgrp_input dgrp_input used real_raw and read_cnt from struct tty_struct. Those members have gone away. Rework the code to not use them. Reported-by: Fengguang Wu Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgrp/dgrp_net_ops.c | 67 +++++-------------------------------- 1 file changed, 8 insertions(+), 59 deletions(-) diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index ab839ea3b44..0788357fd3c 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c @@ -151,20 +151,15 @@ static void dgrp_read_data_block(struct ch_struct *ch, u8 *flipbuf, * Copys the rbuf to the flipbuf and sends to line discipline. * Sends input buffer data to the line discipline. * - * There are several modes to consider here: - * rawreadok, tty->real_raw, and IF_PARMRK */ static void dgrp_input(struct ch_struct *ch) { struct nd_struct *nd; struct tty_struct *tty; - int remain; int data_len; int len; - int flip_len; int tty_count; ulong lock_flags; - struct tty_ldisc *ld; u8 *myflipbuf; u8 *myflipflagbuf; @@ -212,37 +207,11 @@ static void dgrp_input(struct ch_struct *ch) spin_unlock_irqrestore(&nd->nd_lock, lock_flags); - /* Decide how much data we can send into the tty layer */ - if (dgrp_rawreadok && tty->real_raw) - flip_len = MYFLIPLEN; - else - flip_len = TTY_FLIPBUF_SIZE; - /* data_len should be the number of chars that we read in */ data_len = (ch->ch_rin - ch->ch_rout) & RBUF_MASK; - remain = data_len; /* len is the amount of data we are going to transfer here */ - len = min(data_len, flip_len); - - /* take into consideration length of ldisc */ - len = min(len, (N_TTY_BUF_SIZE - 1) - tty->read_cnt); - - ld = tty_ldisc_ref(tty); - - /* - * If we were unable to get a reference to the ld, - * don't flush our buffer, and act like the ld doesn't - * have any space to put the data right now. - */ - if (!ld) { - len = 0; - } else if (!ld->ops->receive_buf) { - spin_lock_irqsave(&nd->nd_lock, lock_flags); - ch->ch_rout = ch->ch_rin; - spin_unlock_irqrestore(&nd->nd_lock, lock_flags); - len = 0; - } + len = tty_buffer_request_room(tty, data_len); /* Check DPA flow control */ if ((nd->nd_dpa_debug) && @@ -254,42 +223,22 @@ static void dgrp_input(struct ch_struct *ch) dgrp_read_data_block(ch, myflipbuf, len); - /* - * In high performance mode, we don't have to update - * flag_buf or any of the counts or pointers into flip buf. - */ - if (!dgrp_rawreadok || !tty->real_raw) { - if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty)) - parity_scan(ch, myflipbuf, myflipflagbuf, &len); - else - memset(myflipflagbuf, TTY_NORMAL, len); - } + if (I_PARMRK(tty) || I_BRKINT(tty) || I_INPCK(tty)) + parity_scan(ch, myflipbuf, myflipflagbuf, &len); + else + memset(myflipflagbuf, TTY_NORMAL, len); if ((nd->nd_dpa_debug) && (nd->nd_dpa_port == PORT_NUM(MINOR(tty_devnum(tty))))) dgrp_dpa_data(nd, 1, myflipbuf, len); - /* - * If we're doing raw reads, jam it right into the - * line disc bypassing the flip buffers. - */ - if (dgrp_rawreadok && tty->real_raw) - ld->ops->receive_buf(tty, myflipbuf, NULL, len); - else { - len = tty_buffer_request_room(tty, len); - tty_insert_flip_string_flags(tty, myflipbuf, - myflipflagbuf, len); - - /* Tell the tty layer its okay to "eat" the data now */ - tty_flip_buffer_push(tty); - } + tty_insert_flip_string_flags(tty, myflipbuf, + myflipflagbuf, len); + tty_flip_buffer_push(tty); ch->ch_rxcount += len; } - if (ld) - tty_ldisc_deref(ld); - /* * Wake up any sleepers (maybe dgrp close) that might be waiting * for a channel flag state change. -- cgit v1.2.3 From 57cf50acbf5b153f331a966ecc08836324c1cd8d Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Thu, 25 Oct 2012 12:46:22 -0400 Subject: staging: dgrp: remove rawreadok module option The functionality behind this option has been removed in the driver so remove the config option to set/unset it. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgrp/dgrp_common.h | 1 - drivers/staging/dgrp/dgrp_driver.c | 4 ---- drivers/staging/dgrp/dgrp_specproc.c | 2 -- drivers/staging/dgrp/dgrp_sysfs.c | 18 ------------------ 4 files changed, 25 deletions(-) diff --git a/drivers/staging/dgrp/dgrp_common.h b/drivers/staging/dgrp/dgrp_common.h index 05ff338471a..0583fe9c7b0 100644 --- a/drivers/staging/dgrp/dgrp_common.h +++ b/drivers/staging/dgrp/dgrp_common.h @@ -31,7 +31,6 @@ * All global storage allocation. ************************************************************************/ -extern int dgrp_rawreadok; /* Allow raw writing of input */ extern int dgrp_register_cudevices; /* enable legacy cu devices */ extern int dgrp_register_prdevices; /* enable transparent print devices */ extern int dgrp_poll_tick; /* Poll interval - in ms */ diff --git a/drivers/staging/dgrp/dgrp_driver.c b/drivers/staging/dgrp/dgrp_driver.c index 6e4a0ebc074..aa262588e9b 100644 --- a/drivers/staging/dgrp/dgrp_driver.c +++ b/drivers/staging/dgrp/dgrp_driver.c @@ -39,14 +39,10 @@ MODULE_VERSION(DIGI_VERSION); struct list_head nd_struct_list; struct dgrp_poll_data dgrp_poll_data; -int dgrp_rawreadok = 1; /* Bypass flipbuf on input */ int dgrp_register_cudevices = 1;/* Turn on/off registering legacy cu devices */ int dgrp_register_prdevices = 1;/* Turn on/off registering transparent print */ int dgrp_poll_tick = 20; /* Poll interval - in ms */ -module_param_named(rawreadok, dgrp_rawreadok, int, 0644); -MODULE_PARM_DESC(rawreadok, "Bypass flip buffers on input"); - module_param_named(register_cudevices, dgrp_register_cudevices, int, 0644); MODULE_PARM_DESC(register_cudevices, "Turn on/off registering legacy cu devices"); diff --git a/drivers/staging/dgrp/dgrp_specproc.c b/drivers/staging/dgrp/dgrp_specproc.c index 24327c3bad8..db91f676508 100644 --- a/drivers/staging/dgrp/dgrp_specproc.c +++ b/drivers/staging/dgrp/dgrp_specproc.c @@ -629,8 +629,6 @@ static int info_proc_show(struct seq_file *m, void *v) { seq_printf(m, "version: %s\n", DIGI_VERSION); seq_puts(m, "register_with_sysfs: 1\n"); - seq_printf(m, "rawreadok: 0x%08x\t(%d)\n", - dgrp_rawreadok, dgrp_rawreadok); seq_printf(m, "pollrate: 0x%08x\t(%d)\n", dgrp_poll_tick, dgrp_poll_tick); diff --git a/drivers/staging/dgrp/dgrp_sysfs.c b/drivers/staging/dgrp/dgrp_sysfs.c index e5a3c88d016..8b513e9111c 100644 --- a/drivers/staging/dgrp/dgrp_sysfs.c +++ b/drivers/staging/dgrp/dgrp_sysfs.c @@ -55,23 +55,6 @@ static DEVICE_ATTR(register_with_sysfs, 0400, dgrp_class_register_with_sysfs_show, NULL); -static ssize_t dgrp_class_rawreadok_show(struct device *c, - struct device_attribute *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_rawreadok); -} -static ssize_t dgrp_class_rawreadok_store(struct device *c, - struct device_attribute *attr, - const char *buf, size_t count) -{ - sscanf(buf, "0x%x\n", &dgrp_rawreadok); - return count; -} -static DEVICE_ATTR(rawreadok, 0600, dgrp_class_rawreadok_show, - dgrp_class_rawreadok_store); - - static ssize_t dgrp_class_pollrate_show(struct device *c, struct device_attribute *attr, char *buf) @@ -91,7 +74,6 @@ static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show, static struct attribute *dgrp_sysfs_global_settings_entries[] = { &dev_attr_pollrate.attr, - &dev_attr_rawreadok.attr, &dev_attr_register_with_sysfs.attr, NULL }; -- cgit v1.2.3 From 39aee51d439d8ad7339ee49dc3ccaf91ca61d8f0 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Wed, 3 Oct 2012 17:24:36 +0530 Subject: serial: omap: Make context_loss_cnt signed get_context_loss_count returns an int however it is stored in unsigned integer context_loss_cnt . This patch tries to make context_loss_cnt int. So that in case of errors the value (which may be negative) is not interpreted wrongly. In serial_omap_runtime_resume in case of errors returned by get_context_loss_count print a warning and do a restore. Signed-off-by: Shubhrajyoti D Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 6ede6fd92b4..fd0fb8cf7cb 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -96,7 +96,7 @@ struct uart_omap_port { unsigned char msr_saved_flags; char name[20]; unsigned long port_activity; - u32 context_loss_cnt; + int context_loss_cnt; u32 errata; u8 wakeups_enabled; unsigned int irq_pending:1; @@ -1556,11 +1556,15 @@ static int serial_omap_runtime_resume(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); - u32 loss_cnt = serial_omap_get_context_loss_count(up); + int loss_cnt = serial_omap_get_context_loss_count(up); - if (up->context_loss_cnt != loss_cnt) + if (loss_cnt < 0) { + dev_err(dev, "serial_omap_get_context_loss_count failed : %d\n", + loss_cnt); serial_omap_restore_context(up); - + } else if (up->context_loss_cnt != loss_cnt) { + serial_omap_restore_context(up); + } up->latency = up->calc_latency; schedule_work(&up->qos_work); -- cgit v1.2.3 From 7ba897d77ce2df4538c2d3e5bcf3640bde3a54cd Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Wed, 3 Oct 2012 17:24:37 +0530 Subject: serial: omap: Remove the default setting of special character Special character detect enable if enabled by default.Received data comparison with XOFF2 data happens by default. tty provides only XOFF1 no X0FF2 is provided so no need to enable check for XOFF2. Keeping this enabled might give some slow transfers due to dummy xoff2 comparison with xoff2 reset value. Since not all want the XOFF2 support lets not enable it by default. Signed-off-by: Shubhrajyoti D Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index fd0fb8cf7cb..caf49a60916 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -702,11 +702,7 @@ serial_omap_configure_xonxoff serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); - /* Enable special char function UARTi.EFR_REG[5] and - * load the new software flow control mode IXON or IXOFF - * and restore the UARTi.EFR_REG[4] ENHANCED_EN value. - */ - serial_out(up, UART_EFR, up->efr | UART_EFR_SCD); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR); -- cgit v1.2.3 From 40477d0e04fd8d004ee9c70ad57e397a6b6ead63 Mon Sep 17 00:00:00 2001 From: Shubhrajyoti D Date: Wed, 3 Oct 2012 17:24:38 +0530 Subject: serial: omap: Remove the hardcode serial_omap_console_ports array. Currently the array serial_omap_console_ports is hard coded to 4. Make it depend on the maximum uart count. Post to [cfc55bc ARM: OMAP2+: serial: Change MAX_HSUART_PORTS to 6] the max ports is 6. Cc: AnilKumar Ch Signed-off-by: Shubhrajyoti D Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index caf49a60916..478383d3d9c 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1077,7 +1077,7 @@ out: #ifdef CONFIG_SERIAL_OMAP_CONSOLE -static struct uart_omap_port *serial_omap_console_ports[4]; +static struct uart_omap_port *serial_omap_console_ports[OMAP_MAX_HSUART_PORTS]; static struct uart_driver serial_omap_reg; -- cgit v1.2.3 From de609582072af195673e72d9e7647d5cba8eb7e4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 15 Oct 2012 13:36:01 +0200 Subject: serial/amba-pl011: use devm_* managed resources This switches a bunch of allocation and remapping to use the devm_* garbage collected methods and cleans up the error path and remove() paths consequently. devm_ioremap() is only in so fix up the erroneous include as well. Signed-off-by: Linus Walleij Tested-by: Domenico Andreoli Acked-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d7e1edec50b..7fca4022a8b 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -56,8 +56,7 @@ #include #include #include - -#include +#include #define UART_NR 14 @@ -1973,7 +1972,8 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) goto out; } - uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL); + uap = devm_kzalloc(&dev->dev, sizeof(struct uart_amba_port), + GFP_KERNEL); if (uap == NULL) { ret = -ENOMEM; goto out; @@ -1981,16 +1981,17 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) i = pl011_probe_dt_alias(i, &dev->dev); - base = ioremap(dev->res.start, resource_size(&dev->res)); + base = devm_ioremap(&dev->dev, dev->res.start, + resource_size(&dev->res)); if (!base) { ret = -ENOMEM; - goto free; + goto out; } uap->pinctrl = devm_pinctrl_get(&dev->dev); if (IS_ERR(uap->pinctrl)) { ret = PTR_ERR(uap->pinctrl); - goto unmap; + goto out; } uap->pins_default = pinctrl_lookup_state(uap->pinctrl, PINCTRL_STATE_DEFAULT); @@ -2002,10 +2003,10 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) if (IS_ERR(uap->pins_sleep)) dev_dbg(&dev->dev, "could not get sleep pinstate\n"); - uap->clk = clk_get(&dev->dev, NULL); + uap->clk = devm_clk_get(&dev->dev, NULL); if (IS_ERR(uap->clk)) { ret = PTR_ERR(uap->clk); - goto unmap; + goto out; } uap->vendor = vendor; @@ -2038,11 +2039,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) amba_set_drvdata(dev, NULL); amba_ports[i] = NULL; pl011_dma_remove(uap); - clk_put(uap->clk); - unmap: - iounmap(base); - free: - kfree(uap); } out: return ret; @@ -2062,9 +2058,6 @@ static int pl011_remove(struct amba_device *dev) amba_ports[i] = NULL; pl011_dma_remove(uap); - iounmap(uap->port.membase); - clk_put(uap->clk); - kfree(uap); return 0; } -- cgit v1.2.3 From 319fb0d21907f771d8ccdb6177fb2fcafabc6ab4 Mon Sep 17 00:00:00 2001 From: chao bi Date: Thu, 25 Oct 2012 09:02:32 +0800 Subject: serial: ifx6x60: different SPI word width configure requires different swap process SPI protocol driver only provide one function (swap_buf()) to swap SPI data into big endian format, which is only available when SPI controller's word width is 16 bits. But word width could be configured as 8/16/32 bits, different word width configure should be mapped to different swap methods.This patch is to make SPI protocol driver choose the right swap function corresponding to SPI word width configuration. cc: liu chuansheng cc: Chen Jun Signed-off-by: channing Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 70 +++++++++++++++++++++++++++++++++++++------- drivers/tty/serial/ifx6x60.h | 1 + 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 5b9bc19ed13..2d2bcbd8067 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -152,26 +152,67 @@ ifx_spi_power_state_clear(struct ifx_spi_device *ifx_dev, unsigned char val) } /** - * swap_buf + * swap_buf_8 * @buf: our buffer * @len : number of bytes (not words) in the buffer * @end: end of buffer * * Swap the contents of a buffer into big endian format */ -static inline void swap_buf(u16 *buf, int len, void *end) +static inline void swap_buf_8(unsigned char *buf, int len, void *end) +{ + /* don't swap buffer if SPI word width is 8 bits */ + return; +} + +/** + * swap_buf_16 + * @buf: our buffer + * @len : number of bytes (not words) in the buffer + * @end: end of buffer + * + * Swap the contents of a buffer into big endian format + */ +static inline void swap_buf_16(unsigned char *buf, int len, void *end) { int n; + u16 *buf_16 = (u16 *)buf; len = ((len + 1) >> 1); - if ((void *)&buf[len] > end) { - pr_err("swap_buf: swap exceeds boundary (%p > %p)!", - &buf[len], end); + if ((void *)&buf_16[len] > end) { + pr_err("swap_buf_16: swap exceeds boundary (%p > %p)!", + &buf_16[len], end); return; } for (n = 0; n < len; n++) { - *buf = cpu_to_be16(*buf); - buf++; + *buf_16 = cpu_to_be16(*buf_16); + buf_16++; + } +} + +/** + * swap_buf_32 + * @buf: our buffer + * @len : number of bytes (not words) in the buffer + * @end: end of buffer + * + * Swap the contents of a buffer into big endian format + */ +static inline void swap_buf_32(unsigned char *buf, int len, void *end) +{ + int n; + + u32 *buf_32 = (u32 *)buf; + len = (len + 3) >> 2; + + if ((void *)&buf_32[len] > end) { + pr_err("swap_buf_32: swap exceeds boundary (%p > %p)!\n", + &buf_32[len], end); + return; + } + for (n = 0; n < len; n++) { + *buf_32 = cpu_to_be32(*buf_32); + buf_32++; } } @@ -449,7 +490,7 @@ static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev) tx_count-IFX_SPI_HEADER_OVERHEAD, ifx_dev->spi_more); /* swap actual data in the buffer */ - swap_buf((u16 *)(ifx_dev->tx_buffer), tx_count, + ifx_dev->swap_buf((ifx_dev->tx_buffer), tx_count, &ifx_dev->tx_buffer[IFX_SPI_TRANSFER_SIZE]); return tx_count; } @@ -617,7 +658,7 @@ static void ifx_spi_complete(void *ctx) if (!ifx_dev->spi_msg.status) { /* check header validity, get comm flags */ - swap_buf((u16 *)ifx_dev->rx_buffer, IFX_SPI_HEADER_OVERHEAD, + ifx_dev->swap_buf(ifx_dev->rx_buffer, IFX_SPI_HEADER_OVERHEAD, &ifx_dev->rx_buffer[IFX_SPI_HEADER_OVERHEAD]); decode_result = ifx_spi_decode_spi_header(ifx_dev->rx_buffer, &length, &more, &cts); @@ -636,7 +677,8 @@ static void ifx_spi_complete(void *ctx) actual_length = min((unsigned int)length, ifx_dev->spi_msg.actual_length); - swap_buf((u16 *)(ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD), + ifx_dev->swap_buf( + (ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD), actual_length, &ifx_dev->rx_buffer[IFX_SPI_TRANSFER_SIZE]); ifx_spi_insert_flip_string( @@ -1001,6 +1043,14 @@ static int ifx_spi_spi_probe(struct spi_device *spi) return -ENODEV; } + /* init swap_buf function according to word width configuration */ + if (spi->bits_per_word == 32) + ifx_dev->swap_buf = swap_buf_32; + else if (spi->bits_per_word == 16) + ifx_dev->swap_buf = swap_buf_16; + else + ifx_dev->swap_buf = swap_buf_8; + /* ensure SPI protocol flags are initialized to enable transfer */ ifx_dev->spi_more = 0; ifx_dev->spi_slave_cts = 0; diff --git a/drivers/tty/serial/ifx6x60.h b/drivers/tty/serial/ifx6x60.h index e8464baf9e7..d8869f5a463 100644 --- a/drivers/tty/serial/ifx6x60.h +++ b/drivers/tty/serial/ifx6x60.h @@ -124,6 +124,7 @@ struct ifx_spi_device { #define MR_INPROGRESS 1 #define MR_COMPLETE 2 wait_queue_head_t mdm_reset_wait; + void (*swap_buf)(unsigned char *buf, int len, void *end); }; #endif /* _IFX6X60_H */ -- cgit v1.2.3 From c73ba2ae43fd4d69589caeecc5260a41be87b759 Mon Sep 17 00:00:00 2001 From: Jun Chen Date: Mon, 22 Oct 2012 10:23:07 -0400 Subject: serial: ifx6x60: add_timer is not safe in the mrdy_assert function This patch make use of mod_timer instead of add_timer in the mrdy_assert function. Because the srdy interrupter can go high when we are running function mrdy_assert and mrdy_assert can be called by multi-entry. In our medfield platform, spi stress test can encounter this error logs triggered by the BUG_ON of add_timer function.This patch had been tested on our medfield platform. the scenario: CPU0 CPU1 mrdy_assert set_bit(IFX_SPI_STATE_TIMER_PENDING) ifx_spi_handle_srdy ... clear_bit(IFX_SPI_STATE_TIMER_PENDING) ... mrdy_assert set_bit(IFX_SPI_STATE_TIMER_PENDING) ... add_timer ... add_timer Cc: liu chuansheng Cc: Bi Chao Signed-off-by: Chen Jun Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 2d2bcbd8067..4b001ea4b0b 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -231,9 +231,7 @@ static void mrdy_assert(struct ifx_spi_device *ifx_dev) if (!val) { if (!test_and_set_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags)) { - ifx_dev->spi_timer.expires = - jiffies + IFX_SPI_TIMEOUT_SEC*HZ; - add_timer(&ifx_dev->spi_timer); + mod_timer(&ifx_dev->spi_timer,jiffies + IFX_SPI_TIMEOUT_SEC*HZ); } } -- cgit v1.2.3 From 2e30802625f5754e9a0ce478a447ed0f2376d4d4 Mon Sep 17 00:00:00 2001 From: Jun Chen Date: Fri, 19 Oct 2012 09:51:30 -0400 Subject: serial: ifx6x60: del_timer_sync must not be called in interrupt context. This patch make use of del_timer instead of del_timer_sync in the interrupt context. The spi_timer function don't use any resources that may release after running del_timer, so using the del_timer is also safe and enough in this context. Signed-off-by: Chen Jun Acked-by: Alan Cox Tested-by: Chuansheng Liu Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 4b001ea4b0b..e595c832be2 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -866,7 +866,7 @@ error_ret: static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev) { if (test_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags)) { - del_timer_sync(&ifx_dev->spi_timer); + del_timer(&ifx_dev->spi_timer); clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); } -- cgit v1.2.3 From 1fa48cd5c4f1403db1f5a55ea3c346a33f39a33a Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 12 Oct 2012 11:28:40 -0300 Subject: [media] omap3isp: video: Fix warning caused by bad vidioc_s_crop prototype Commit 4f996594 ("v4l2: make vidioc_s_crop const") modified the vidioc_s_crop operation prototype but forgot to update the OMAP3 ISP driver. Add a const keyword to fix the function prototype. Signed-off-by: Laurent Pinchart Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/ispvideo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index a0b737fecf1..75cd309035f 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -792,7 +792,7 @@ isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop) } static int -isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop) +isp_video_set_crop(struct file *file, void *fh, const struct v4l2_crop *crop) { struct isp_video *video = video_drvdata(file); struct v4l2_subdev *subdev; -- cgit v1.2.3 From cadf74869013dc309bde50ed446f56d33a6a9806 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Thu, 25 Oct 2012 14:26:35 -0400 Subject: tty: add missing newlines to WARN_RATELIMIT WARN_RATELIMIT() expects the warning to end with a newline if one is needed. Not doing so results in odd looking warnings such as: [ 1339.454272] tty is NULLPid: 7147, comm: kworker/4:0 Tainted: G W 3.7.0-rc2-next-20121025-sasha-00001-g673f98e-dirty #75 Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 2 +- drivers/tty/tty_buffer.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 60b076cc4e2..19083efa231 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -151,7 +151,7 @@ static void n_tty_set_room(struct tty_struct *tty) /* Did this open up the receive buffer? We may need to flip */ if (left && !old_left) { WARN_RATELIMIT(tty->port->itty == NULL, - "scheduling with invalid itty"); + "scheduling with invalid itty\n"); schedule_work(&tty->port->buf.work); } } diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 6cf87d7afb7..45d916198f7 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -473,7 +473,7 @@ static void flush_to_ldisc(struct work_struct *work) struct tty_ldisc *disc; tty = port->itty; - if (WARN_RATELIMIT(tty == NULL, "tty is NULL")) + if (WARN_RATELIMIT(tty == NULL, "tty is NULL\n")) return; disc = tty_ldisc_ref(tty); -- cgit v1.2.3 From 55c8504672adfb8065da5196ce1cce7db97532d0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 12 Oct 2012 11:20:10 -0300 Subject: [media] omap3isp: Fix warning caused by bad subdev events operations prototypes Remove the const keyword from the V4L2 subdev events operations to match the V4L2 API. Signed-off-by: Laurent Pinchart Acked-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/omap3isp/ispccdc.c | 4 ++-- drivers/media/platform/omap3isp/ispstat.c | 4 ++-- drivers/media/platform/omap3isp/ispstat.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 60181ab9606..aa9df9d71a7 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -1706,7 +1706,7 @@ static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) } static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) + struct v4l2_event_subscription *sub) { if (sub->type != V4L2_EVENT_FRAME_SYNC) return -EINVAL; @@ -1719,7 +1719,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, } static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) + struct v4l2_event_subscription *sub) { return v4l2_event_unsubscribe(fh, sub); } diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c index d7ac76b5c2a..b8640be692f 100644 --- a/drivers/media/platform/omap3isp/ispstat.c +++ b/drivers/media/platform/omap3isp/ispstat.c @@ -1025,7 +1025,7 @@ void omap3isp_stat_dma_isr(struct ispstat *stat) int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) + struct v4l2_event_subscription *sub) { struct ispstat *stat = v4l2_get_subdevdata(subdev); @@ -1037,7 +1037,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev, struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) + struct v4l2_event_subscription *sub) { return v4l2_event_unsubscribe(fh, sub); } diff --git a/drivers/media/platform/omap3isp/ispstat.h b/drivers/media/platform/omap3isp/ispstat.h index a6fe653eb23..9b7c8654dc8 100644 --- a/drivers/media/platform/omap3isp/ispstat.h +++ b/drivers/media/platform/omap3isp/ispstat.h @@ -147,10 +147,10 @@ int omap3isp_stat_init(struct ispstat *stat, const char *name, void omap3isp_stat_cleanup(struct ispstat *stat); int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub); + struct v4l2_event_subscription *sub); int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev, struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub); + struct v4l2_event_subscription *sub); int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable); int omap3isp_stat_busy(struct ispstat *stat); -- cgit v1.2.3 From 0bbeb3c3e84bc963d1c66661e082d207023b0e5c Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Mon, 22 Oct 2012 11:58:01 -0400 Subject: of serial port driver - add clk_get_rate() support Currently this driver expects the clock-frequency attribute. This patch allows getting clock-frequency through clk driver API clk_get_rate() if clock-frequency attribute is not defined. So in the device bindings for serial device, one can add clocks phandle to refer to the clk device to get the rate. Signed-off-by: Murali Karicheri Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/of_serial.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index df443b908ca..533ccfe7709 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -21,8 +21,10 @@ #include #include #include +#include struct of_serial_info { + struct clk *clk; int type; int line; }; @@ -51,7 +53,8 @@ EXPORT_SYMBOL_GPL(tegra_serial_handle_break); * Fill a struct uart_port for a given device node */ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, - int type, struct uart_port *port) + int type, struct uart_port *port, + struct of_serial_info *info) { struct resource resource; struct device_node *np = ofdev->dev.of_node; @@ -60,8 +63,17 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, memset(port, 0, sizeof *port); if (of_property_read_u32(np, "clock-frequency", &clk)) { - dev_warn(&ofdev->dev, "no clock-frequency property set\n"); - return -ENODEV; + + /* Get clk rate through clk driver if present */ + info->clk = clk_get(&ofdev->dev, NULL); + if (info->clk == NULL) { + dev_warn(&ofdev->dev, + "clk or clock-frequency not defined\n"); + return -ENODEV; + } + + clk_prepare_enable(info->clk); + clk = clk_get_rate(info->clk); } /* If current-speed was set, then try not to change it. */ if (of_property_read_u32(np, "current-speed", &spd) == 0) @@ -70,7 +82,7 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, ret = of_address_to_resource(np, 0, &resource); if (ret) { dev_warn(&ofdev->dev, "invalid address\n"); - return ret; + goto out; } spin_lock_init(&port->lock); @@ -97,7 +109,8 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, default: dev_warn(&ofdev->dev, "unsupported reg-io-width (%d)\n", prop); - return -EINVAL; + ret = -EINVAL; + goto out; } } @@ -115,6 +128,10 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, port->handle_break = tegra_serial_handle_break; return 0; +out: + if (info->clk) + clk_disable_unprepare(info->clk); + return ret; } /* @@ -141,7 +158,7 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev) return -ENOMEM; port_type = (unsigned long)match->data; - ret = of_platform_serial_setup(ofdev, port_type, &port); + ret = of_platform_serial_setup(ofdev, port_type, &port, info); if (ret) goto out; @@ -204,6 +221,9 @@ static int of_platform_serial_remove(struct platform_device *ofdev) /* need to add code for these */ break; } + + if (info->clk) + clk_disable_unprepare(info->clk); kfree(info); return 0; } -- cgit v1.2.3 From ab72fa5523866cb93681abb9f9a401d43a93b7be Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Mon, 22 Oct 2012 11:58:02 -0400 Subject: Documentation: of-serial.txt - update for clocks phandle for clk Signed-off-by: Murali Karicheri Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/tty/serial/of-serial.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/tty/serial/of-serial.txt b/Documentation/devicetree/bindings/tty/serial/of-serial.txt index ba385f2e0dd..1e1145ca4f3 100644 --- a/Documentation/devicetree/bindings/tty/serial/of-serial.txt +++ b/Documentation/devicetree/bindings/tty/serial/of-serial.txt @@ -14,7 +14,10 @@ Required properties: - "serial" if the port type is unknown. - reg : offset and length of the register set for the device. - interrupts : should contain uart interrupt. -- clock-frequency : the input clock frequency for the UART. +- clock-frequency : the input clock frequency for the UART + or + clocks phandle to refer to the clk used as per Documentation/devicetree + /bindings/clock/clock-bindings.txt Optional properties: - current-speed : the current active speed of the UART. -- cgit v1.2.3 From b717727ef25d4b73f73e3666341c07a034f908a6 Mon Sep 17 00:00:00 2001 From: Claudio Scordino Date: Tue, 9 Oct 2012 12:21:17 +0200 Subject: umc-bus.c: fix usage of device_trylock Fix usage of device_trylock. It has the same semantics of mutex_trylock, so it returns 1 if the lock has been acquired successfully. Signed-off-by: Claudio Scordino Signed-off-by: Bruno Morelli Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/umc-bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/uwb/umc-bus.c b/drivers/uwb/umc-bus.c index 82a84d53120..5c5b3fc9088 100644 --- a/drivers/uwb/umc-bus.c +++ b/drivers/uwb/umc-bus.c @@ -63,7 +63,7 @@ int umc_controller_reset(struct umc_dev *umc) struct device *parent = umc->dev.parent; int ret = 0; - if (device_trylock(parent)) + if (!device_trylock(parent)) return -EAGAIN; ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper); if (ret >= 0) -- cgit v1.2.3 From e6f30deafe61179df048ac9040fe2bdf73a996c3 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Wed, 24 Oct 2012 11:59:24 +0800 Subject: USB: check port changes before hub runtime suspend for some bug device The hub status endpoint has a long 'bInterval', which is 255ms for FS/LS device and 256ms for HS device according to USB 2.0 spec, so the device connection change may be reported later more than 255ms via status pipe. The connection change in hub may have been happened already on the downstream ports, but no status URB completes when it is killed in hub_suspend(auto), so the connection change may be missed by some buggy hub devices, which won't generate remote wakeup signal after their remote wakeup is enabled and they are put into suspend state. The problem can be observed at least on the below Genesys Logic, Inc. hub devices: 0x05e3,0x0606 0x05e3,0x0608 In theory, there is no way to fix the problem completely, but we can make it less likely to occur by this patch. This patch introduces one quirk of HUB_QUIRK_CHECK_PORTS_AUTOSUSPEND to check ports' change during hub_suspend(auto) for the buggy devices. If ports' change is found, terminate the auto suspend and return to working state. So for the buggy hubs, if the connection change happend before the ports' check, it can be handled correctly. If it happens between the ports' check and enabling remote wakeup/entering suspend, it will be missed. Considered the interval is quite short, it is very less likely to happen during the window. Acked-by: Alan Stern Signed-off-by: Ming Lei Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index e729e94cb75..ff86355d0df 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -39,6 +39,9 @@ #endif #endif +#define USB_VENDOR_GENESYS_LOGIC 0x05e3 +#define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01 + struct usb_port { struct usb_device *child; struct device dev; @@ -86,6 +89,8 @@ struct usb_hub { unsigned quiescing:1; unsigned disconnected:1; + unsigned quirk_check_port_auto_suspend:1; + unsigned has_indicators:1; u8 indicator[USB_MAXCHILDREN]; struct delayed_work leds; @@ -1667,6 +1672,9 @@ descriptor_error: if (hdev->speed == USB_SPEED_HIGH) highspeed_hubs++; + if (id->driver_info & HUB_QUIRK_CHECK_PORT_AUTOSUSPEND) + hub->quirk_check_port_auto_suspend = 1; + if (hub_configure(hub, endpoint) >= 0) return 0; @@ -3125,6 +3133,21 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) #endif +static int check_ports_changed(struct usb_hub *hub) +{ + int port1; + + for (port1 = 1; port1 <= hub->hdev->maxchild; ++port1) { + u16 portstatus, portchange; + int status; + + status = hub_port_status(hub, port1, &portstatus, &portchange); + if (!status && portchange) + return 1; + } + return 0; +} + static int hub_suspend(struct usb_interface *intf, pm_message_t msg) { struct usb_hub *hub = usb_get_intfdata (intf); @@ -3143,6 +3166,16 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) return -EBUSY; } } + + if (hdev->do_remote_wakeup && hub->quirk_check_port_auto_suspend) { + /* check if there are changes pending on hub ports */ + if (check_ports_changed(hub)) { + if (PMSG_IS_AUTO(msg)) + return -EBUSY; + pm_wakeup_event(&hdev->dev, 2000); + } + } + if (hub_is_superspeed(hdev) && hdev->do_remote_wakeup) { /* Enable hub to send remote wakeup for all ports. */ for (port1 = 1; port1 <= hdev->maxchild; port1++) { @@ -4647,6 +4680,11 @@ static int hub_thread(void *__unused) } static const struct usb_device_id hub_id_table[] = { + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_INT_CLASS, + .idVendor = USB_VENDOR_GENESYS_LOGIC, + .bInterfaceClass = USB_CLASS_HUB, + .driver_info = HUB_QUIRK_CHECK_PORT_AUTOSUSPEND}, { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS, .bDeviceClass = USB_CLASS_HUB}, { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, -- cgit v1.2.3 From 596d789a211d134dc5f94d1e5957248c204ef850 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Wed, 24 Oct 2012 11:59:25 +0800 Subject: USB: set hub's default autosuspend delay as 0 This patch sets hub device's default autosuspend delay as 0 to speedup bus suspend, see comments in code for details. Acked-by: Alan Stern Signed-off-by: Ming Lei Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index ff86355d0df..43ce1467f8c 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1614,6 +1614,41 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) desc = intf->cur_altsetting; hdev = interface_to_usbdev(intf); + /* + * Set default autosuspend delay as 0 to speedup bus suspend, + * based on the below considerations: + * + * - Unlike other drivers, the hub driver does not rely on the + * autosuspend delay to provide enough time to handle a wakeup + * event, and the submitted status URB is just to check future + * change on hub downstream ports, so it is safe to do it. + * + * - The patch might cause one or more auto supend/resume for + * below very rare devices when they are plugged into hub + * first time: + * + * devices having trouble initializing, and disconnect + * themselves from the bus and then reconnect a second + * or so later + * + * devices just for downloading firmware, and disconnects + * themselves after completing it + * + * For these quite rare devices, their drivers may change the + * autosuspend delay of their parent hub in the probe() to one + * appropriate value to avoid the subtle problem if someone + * does care it. + * + * - The patch may cause one or more auto suspend/resume on + * hub during running 'lsusb', but it is probably too + * infrequent to worry about. + * + * - Change autosuspend delay of hub can avoid unnecessary auto + * suspend timer for hub, also may decrease power consumption + * of USB bus. + */ + pm_runtime_set_autosuspend_delay(&hdev->dev, 0); + /* Hubs have proper suspend/resume support. */ usb_enable_autosuspend(hdev); -- cgit v1.2.3 From d124a60dbbe7c12f3871e2c7fc71f98a821ee9a8 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Mon, 22 Oct 2012 12:02:16 +0900 Subject: USB: isp1760-if: Change to use irq_of_parse_and_map This uses irq_of_parse_and_map instead of of_irq_map_one and irq_create_of_mapping. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-if.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index fff114fd546..958379f9de7 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -43,7 +43,6 @@ static int of_isp1760_probe(struct platform_device *dev) struct device_node *dp = dev->dev.of_node; struct resource *res; struct resource memory; - struct of_irq oirq; int virq; resource_size_t res_len; int ret; @@ -69,14 +68,12 @@ static int of_isp1760_probe(struct platform_device *dev) goto free_data; } - if (of_irq_map_one(dp, 0, &oirq)) { + virq = irq_of_parse_and_map(dp, 0); + if (!virq) { ret = -ENODEV; goto release_reg; } - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); - if (of_device_is_compatible(dp, "nxp,usb-isp1761")) devflags |= ISP1760_FLAG_ISP1761; -- cgit v1.2.3 From 967857dfd990081f6702daebc6c9bc6f4ba7a39e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 23 Oct 2012 13:01:50 -0700 Subject: drivers/base: remove CONFIG_EXPERIMENTAL This config item has not carried much meaning for a while now and is almost always enabled by default. As agreed during the Linux kernel summit, remove it. CC: Greg Kroah-Hartman Signed-off-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- drivers/base/Kconfig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 08b4c520938..e439ebca837 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -57,7 +57,7 @@ config DEVTMPFS_MOUNT on the rootfs is completely empty. config STANDALONE - bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL + bool "Select only drivers that don't need compile-time external firmware" default y help Select this option if you don't have magic firmware for drivers that @@ -185,7 +185,6 @@ config DMA_SHARED_BUFFER bool default n select ANON_INODES - depends on EXPERIMENTAL help This option enables the framework for buffer-sharing between multiple drivers. A buffer is associated with a file using driver @@ -193,8 +192,8 @@ config DMA_SHARED_BUFFER driver. config CMA - bool "Contiguous Memory Allocator (EXPERIMENTAL)" - depends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK && EXPERIMENTAL + bool "Contiguous Memory Allocator" + depends on HAVE_DMA_CONTIGUOUS && HAVE_MEMBLOCK select MIGRATION select MEMORY_ISOLATION help -- cgit v1.2.3 From 5f1e7790963f03c5789070b3954f38d038ad528b Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 18 Oct 2012 23:15:05 +0800 Subject: vme: vme_vmivme7805.c: use module_pci_driver to simplify the code Use the module_pci_driver() macro to make the code simpler by eliminating module_init and module_exit calls. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/vme/boards/vme_vmivme7805.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/vme/boards/vme_vmivme7805.c b/drivers/vme/boards/vme_vmivme7805.c index 8e05bb4e135..dd22b5072e2 100644 --- a/drivers/vme/boards/vme_vmivme7805.c +++ b/drivers/vme/boards/vme_vmivme7805.c @@ -19,10 +19,8 @@ #include "vme_vmivme7805.h" -static int __init vmic_init(void); static int vmic_probe(struct pci_dev *, const struct pci_device_id *); static void vmic_remove(struct pci_dev *); -static void __exit vmic_exit(void); /** Base address to access FPGA register */ static void *vmic_base; @@ -41,11 +39,6 @@ static struct pci_driver vmic_driver = { .remove = vmic_remove, }; -static int __init vmic_init(void) -{ - return pci_register_driver(&vmic_driver); -} - static int vmic_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int retval; @@ -109,15 +102,9 @@ static void vmic_remove(struct pci_dev *pdev) } -static void __exit vmic_exit(void) -{ - pci_unregister_driver(&vmic_driver); -} +module_pci_driver(vmic_driver); MODULE_DESCRIPTION("VMIVME-7805 board support driver"); MODULE_AUTHOR("Arthur Benilov "); MODULE_LICENSE("GPL"); -module_init(vmic_init); -module_exit(vmic_exit); - -- cgit v1.2.3 From c7b50a2a29451f9a6ec6bc7fd4c8ad836297ffc4 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 18 Oct 2012 23:13:37 +0800 Subject: vme: vme_ca91cx42.c: use module_pci_driver to simplify the code Use the module_pci_driver() macro to make the code simpler by eliminating module_init and module_exit calls. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/vme/bridges/vme_ca91cx42.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/vme/bridges/vme_ca91cx42.c b/drivers/vme/bridges/vme_ca91cx42.c index 1425d22cf95..64bfea31442 100644 --- a/drivers/vme/bridges/vme_ca91cx42.c +++ b/drivers/vme/bridges/vme_ca91cx42.c @@ -34,10 +34,8 @@ #include "../vme_bridge.h" #include "vme_ca91cx42.h" -static int __init ca91cx42_init(void); static int ca91cx42_probe(struct pci_dev *, const struct pci_device_id *); static void ca91cx42_remove(struct pci_dev *); -static void __exit ca91cx42_exit(void); /* Module parameters */ static int geoid; @@ -1523,11 +1521,6 @@ static void ca91cx42_free_consistent(struct device *parent, size_t size, pci_free_consistent(pdev, size, vaddr, dma); } -static int __init ca91cx42_init(void) -{ - return pci_register_driver(&ca91cx42_driver); -} - /* * Configure CR/CSR space * @@ -1944,16 +1937,10 @@ static void ca91cx42_remove(struct pci_dev *pdev) kfree(ca91cx42_bridge); } -static void __exit ca91cx42_exit(void) -{ - pci_unregister_driver(&ca91cx42_driver); -} +module_pci_driver(ca91cx42_driver); MODULE_PARM_DESC(geoid, "Override geographical addressing"); module_param(geoid, int, 0); MODULE_DESCRIPTION("VME driver for the Tundra Universe II VME bridge"); MODULE_LICENSE("GPL"); - -module_init(ca91cx42_init); -module_exit(ca91cx42_exit); -- cgit v1.2.3 From 01c071439730013cc110dd321852b44432cf496c Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 18 Oct 2012 23:12:50 +0800 Subject: vme: vme_tsi148.c: use module_pci_driver to simplify the code Use the module_pci_driver() macro to make the code simpler by eliminating module_init and module_exit calls. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/vme/bridges/vme_tsi148.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c index 5fbd08ffb9c..9c1aa4dc39c 100644 --- a/drivers/vme/bridges/vme_tsi148.c +++ b/drivers/vme/bridges/vme_tsi148.c @@ -35,10 +35,8 @@ #include "../vme_bridge.h" #include "vme_tsi148.h" -static int __init tsi148_init(void); static int tsi148_probe(struct pci_dev *, const struct pci_device_id *); static void tsi148_remove(struct pci_dev *); -static void __exit tsi148_exit(void); /* Module parameter */ @@ -2244,11 +2242,6 @@ static void tsi148_free_consistent(struct device *parent, size_t size, pci_free_consistent(pdev, size, vaddr, dma); } -static int __init tsi148_init(void) -{ - return pci_register_driver(&tsi148_driver); -} - /* * Configure CR/CSR space * @@ -2754,10 +2747,7 @@ static void tsi148_remove(struct pci_dev *pdev) kfree(tsi148_bridge); } -static void __exit tsi148_exit(void) -{ - pci_unregister_driver(&tsi148_driver); -} +module_pci_driver(tsi148_driver); MODULE_PARM_DESC(err_chk, "Check for VME errors on reads and writes"); module_param(err_chk, bool, 0); @@ -2767,6 +2757,3 @@ module_param(geoid, int, 0); MODULE_DESCRIPTION("VME driver for the Tundra Tempe VME bridge"); MODULE_LICENSE("GPL"); - -module_init(tsi148_init); -module_exit(tsi148_exit); -- cgit v1.2.3 From 369130ab9233207d7036ee4578d92a867b150c9c Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 23 Oct 2012 13:02:06 -0700 Subject: drivers/iio/dac: remove CONFIG_EXPERIMENTAL This config item has not carried much meaning for a while now and is almost always enabled by default. As agreed during the Linux kernel summit, remove it. CC: Jonathan Cameron CC: Lars-Peter Clausen CC: Greg Kroah-Hartman CC: Michael Hennerich CC: Peter Meerwald Signed-off-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- drivers/iio/dac/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index f68756e6dd6..f4a6f083832 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -132,7 +132,7 @@ config AD5686 config MAX517 tristate "Maxim MAX517/518/519 DAC driver" - depends on I2C && EXPERIMENTAL + depends on I2C help If you say yes here you get support for the Maxim chips MAX517, MAX518 and MAX519 (I2C 8-Bit DACs with rail-to-rail outputs). -- cgit v1.2.3 From fd563dbb4f59acabdc9baa8b4e66a21ce82df8e3 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 24 Oct 2012 21:36:46 -0200 Subject: staging: ipu-v3: ipu-common: Make it less verbose IPU Interrupt numbers and the various IPU submodules base addresses are more interesting for debugging purposes rather than normal use, so use dev_dbg instead. Signed-off-by: Fabio Estevam Acked-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/ipu-v3/ipu-common.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c index f381960f42b..a4de4fa1b00 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c @@ -1006,7 +1006,7 @@ static int __devinit ipu_probe(struct platform_device *pdev) irq_err = platform_get_irq(pdev, 1); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - dev_info(&pdev->dev, "irq_sync: %d irq_err: %d\n", + dev_dbg(&pdev->dev, "irq_sync: %d irq_err: %d\n", irq_sync, irq_err); if (!res || irq_sync < 0 || irq_err < 0) @@ -1026,27 +1026,27 @@ static int __devinit ipu_probe(struct platform_device *pdev) spin_lock_init(&ipu->lock); mutex_init(&ipu->channel_lock); - dev_info(&pdev->dev, "cm_reg: 0x%08lx\n", + dev_dbg(&pdev->dev, "cm_reg: 0x%08lx\n", ipu_base + devtype->cm_ofs); - dev_info(&pdev->dev, "idmac: 0x%08lx\n", + dev_dbg(&pdev->dev, "idmac: 0x%08lx\n", ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS); - dev_info(&pdev->dev, "cpmem: 0x%08lx\n", + dev_dbg(&pdev->dev, "cpmem: 0x%08lx\n", ipu_base + devtype->cpmem_ofs); - dev_info(&pdev->dev, "disp0: 0x%08lx\n", + dev_dbg(&pdev->dev, "disp0: 0x%08lx\n", ipu_base + devtype->disp0_ofs); - dev_info(&pdev->dev, "disp1: 0x%08lx\n", + dev_dbg(&pdev->dev, "disp1: 0x%08lx\n", ipu_base + devtype->disp1_ofs); - dev_info(&pdev->dev, "srm: 0x%08lx\n", + dev_dbg(&pdev->dev, "srm: 0x%08lx\n", ipu_base + devtype->srm_ofs); - dev_info(&pdev->dev, "tpm: 0x%08lx\n", + dev_dbg(&pdev->dev, "tpm: 0x%08lx\n", ipu_base + devtype->tpm_ofs); - dev_info(&pdev->dev, "dc: 0x%08lx\n", + dev_dbg(&pdev->dev, "dc: 0x%08lx\n", ipu_base + devtype->cm_ofs + IPU_CM_DC_REG_OFS); - dev_info(&pdev->dev, "ic: 0x%08lx\n", + dev_dbg(&pdev->dev, "ic: 0x%08lx\n", ipu_base + devtype->cm_ofs + IPU_CM_IC_REG_OFS); - dev_info(&pdev->dev, "dmfc: 0x%08lx\n", + dev_dbg(&pdev->dev, "dmfc: 0x%08lx\n", ipu_base + devtype->cm_ofs + IPU_CM_DMFC_REG_OFS); - dev_info(&pdev->dev, "vdi: 0x%08lx\n", + dev_dbg(&pdev->dev, "vdi: 0x%08lx\n", ipu_base + devtype->vdi_ofs); ipu->cm_reg = devm_ioremap(&pdev->dev, -- cgit v1.2.3 From 9c2c438ceeee5d22aeaea4162a96c0f35f62a7ff Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 24 Oct 2012 21:36:47 -0200 Subject: staging: ipu-v3: ipu-common: Indicate succesful probe Indication of succesful probe is more useful than stating that the driver is about to be probed. Signed-off-by: Fabio Estevam Acked-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/ipu-v3/ipu-common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c index a4de4fa1b00..27e77c72c9c 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c @@ -1000,8 +1000,6 @@ static int __devinit ipu_probe(struct platform_device *pdev) devtype = of_id->data; - dev_info(&pdev->dev, "Initializing %s\n", devtype->name); - irq_sync = platform_get_irq(pdev, 0); irq_err = platform_get_irq(pdev, 1); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1098,6 +1096,8 @@ static int __devinit ipu_probe(struct platform_device *pdev) goto failed_add_clients; } + dev_info(&pdev->dev, "%s probed\n", devtype->name); + return 0; failed_add_clients: -- cgit v1.2.3 From 06026d911c31dfa602e14e635a3489b8d67cc786 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 24 Oct 2012 23:43:20 +0400 Subject: tty: pty - Move TIOCPKT handling into pty.c Since this ioctl is for pty devices only move it to pty.c. v2: - drop PTY_TYPE_MASTER test since it's master peer ioctl anyway (by jslaby@) Suggested-by: Alan Cox Signed-off-by: Cyrill Gorcunov CC: "H. Peter Anvin" CC: Pavel Emelyanov CC: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 26 ++++++++++++++++++++++++++ drivers/tty/tty_ioctl.c | 21 --------------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 4219f040adb..df3c64272d2 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -171,6 +171,28 @@ static int pty_set_lock(struct tty_struct *tty, int __user *arg) return 0; } +/* Set the packet mode on a pty */ +static int pty_set_pktmode(struct tty_struct *tty, int __user *arg) +{ + unsigned long flags; + int pktmode; + + if (get_user(pktmode, arg)) + return -EFAULT; + + spin_lock_irqsave(&tty->ctrl_lock, flags); + if (pktmode) { + if (!tty->packet) { + tty->packet = 1; + tty->link->ctrl_status = 0; + } + } else + tty->packet = 0; + spin_unlock_irqrestore(&tty->ctrl_lock, flags); + + return 0; +} + /* Send a signal to the slave */ static int pty_signal(struct tty_struct *tty, int sig) { @@ -398,6 +420,8 @@ static int pty_bsd_ioctl(struct tty_struct *tty, switch (cmd) { case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ return pty_set_lock(tty, (int __user *) arg); + case TIOCPKT: /* Set PT packet mode */ + return pty_set_pktmode(tty, (int __user *)arg); case TIOCSIG: /* Send signal to other side of pty */ return pty_signal(tty, (int) arg); } @@ -512,6 +536,8 @@ static int pty_unix98_ioctl(struct tty_struct *tty, switch (cmd) { case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ return pty_set_lock(tty, (int __user *)arg); + case TIOCPKT: /* Set PT packet mode */ + return pty_set_pktmode(tty, (int __user *)arg); case TIOCGPTN: /* Get PT Number */ return put_user(tty->index, (unsigned int __user *)arg); case TIOCSIG: /* Send signal to other side of pty */ diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 12b1fa0f4f8..8481b29d5b3 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -1118,7 +1118,6 @@ EXPORT_SYMBOL_GPL(tty_perform_flush); int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { - unsigned long flags; int retval; switch (cmd) { @@ -1153,26 +1152,6 @@ int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, return 0; case TCFLSH: return tty_perform_flush(tty, arg); - case TIOCPKT: - { - int pktmode; - - if (tty->driver->type != TTY_DRIVER_TYPE_PTY || - tty->driver->subtype != PTY_TYPE_MASTER) - return -ENOTTY; - if (get_user(pktmode, (int __user *) arg)) - return -EFAULT; - spin_lock_irqsave(&tty->ctrl_lock, flags); - if (pktmode) { - if (!tty->packet) { - tty->packet = 1; - tty->link->ctrl_status = 0; - } - } else - tty->packet = 0; - spin_unlock_irqrestore(&tty->ctrl_lock, flags); - return 0; - } default: /* Try the mode commands */ return tty_mode_ioctl(tty, file, cmd, arg); -- cgit v1.2.3 From c6298038bcfc20710430a4ad069bb1f3f069997c Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 24 Oct 2012 23:43:21 +0400 Subject: tty, ioctls -- Add new ioctl definitions for tty flags fetching This patch defines new ioctl codes TIOCGPKT, TIOCGPTLCK, TIOCGEXCL for fetching pty's packet mode and locking state, and exclusive mode of tty. [ No real handlers for the codes though, this will be addressed in another patch for easier review and bisectability ] Signed-off-by: Cyrill Gorcunov CC: Alan Cox CC: "H. Peter Anvin" CC: Pavel Emelyanov CC: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- arch/alpha/include/asm/ioctls.h | 3 +++ arch/mips/include/uapi/asm/ioctls.h | 3 +++ arch/parisc/include/uapi/asm/ioctls.h | 3 +++ arch/powerpc/include/uapi/asm/ioctls.h | 3 +++ arch/sh/include/uapi/asm/ioctls.h | 3 +++ arch/sparc/include/uapi/asm/ioctls.h | 3 +++ arch/xtensa/include/uapi/asm/ioctls.h | 3 +++ fs/compat_ioctl.c | 3 +++ include/uapi/asm-generic/ioctls.h | 3 +++ 9 files changed, 27 insertions(+) diff --git a/arch/alpha/include/asm/ioctls.h b/arch/alpha/include/asm/ioctls.h index 80e1cee90f1..92c557be49f 100644 --- a/arch/alpha/include/asm/ioctls.h +++ b/arch/alpha/include/asm/ioctls.h @@ -95,6 +95,9 @@ #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCVHANGUP 0x5437 +#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ +#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ +#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h index 92403c3d600..addd56b6069 100644 --- a/arch/mips/include/uapi/asm/ioctls.h +++ b/arch/mips/include/uapi/asm/ioctls.h @@ -86,6 +86,9 @@ #define TIOCGDEV _IOR('T', 0x32, unsigned int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T', 0x36, int) /* Generate signal on Pty slave */ #define TIOCVHANGUP 0x5437 +#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ +#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ +#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ /* I hope the range from 0x5480 on is free ... */ #define TIOCSCTTY 0x5480 /* become controlling tty */ diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h index 054ec06f9e2..66719c38a36 100644 --- a/arch/parisc/include/uapi/asm/ioctls.h +++ b/arch/parisc/include/uapi/asm/ioctls.h @@ -55,6 +55,9 @@ #define TIOCGDEV _IOR('T',0x32, int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCVHANGUP 0x5437 +#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ +#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ +#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ #define FIOCLEX 0x5451 diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h index e9b78870aaa..49a25796a61 100644 --- a/arch/powerpc/include/uapi/asm/ioctls.h +++ b/arch/powerpc/include/uapi/asm/ioctls.h @@ -97,6 +97,9 @@ #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCVHANGUP 0x5437 +#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ +#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ +#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define TIOCSERCONFIG 0x5453 #define TIOCSERGWILD 0x5454 diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h index a6769f352bf..34224107976 100644 --- a/arch/sh/include/uapi/asm/ioctls.h +++ b/arch/sh/include/uapi/asm/ioctls.h @@ -88,6 +88,9 @@ #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCVHANGUP _IO('T', 0x37) +#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ +#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ +#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */ #define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */ diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h index 9155f7041d4..897d1723fa1 100644 --- a/arch/sparc/include/uapi/asm/ioctls.h +++ b/arch/sparc/include/uapi/asm/ioctls.h @@ -21,6 +21,9 @@ #define TCSETSF2 _IOW('T', 15, struct termios2) #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ #define TIOCVHANGUP _IO('T', 0x37) +#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ +#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ +#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ /* Note that all the ioctls that are not available in Linux have a * double underscore on the front to: a) avoid some programs to diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h index 2aa4cd9f0ce..b4cb1100c0f 100644 --- a/arch/xtensa/include/uapi/asm/ioctls.h +++ b/arch/xtensa/include/uapi/asm/ioctls.h @@ -101,6 +101,9 @@ #define TIOCGDEV _IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */ #define TIOCSIG _IOW('T',0x36, int) /* Generate signal on Pty slave */ #define TIOCVHANGUP _IO('T', 0x37) +#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ +#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ +#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define TIOCSERCONFIG _IO('T', 83) #define TIOCSERGWILD _IOR('T', 84, int) diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index f5054025f9d..89cf6014a96 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -842,6 +842,9 @@ COMPATIBLE_IOCTL(TIOCGDEV) COMPATIBLE_IOCTL(TIOCCBRK) COMPATIBLE_IOCTL(TIOCGSID) COMPATIBLE_IOCTL(TIOCGICOUNT) +COMPATIBLE_IOCTL(TIOCGPKT) +COMPATIBLE_IOCTL(TIOCGPTLCK) +COMPATIBLE_IOCTL(TIOCGEXCL) /* Little t */ COMPATIBLE_IOCTL(TIOCGETD) COMPATIBLE_IOCTL(TIOCSETD) diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h index 199975fac39..143dacbb7d9 100644 --- a/include/uapi/asm-generic/ioctls.h +++ b/include/uapi/asm-generic/ioctls.h @@ -74,6 +74,9 @@ #define TCSETXW 0x5435 #define TIOCSIG _IOW('T', 0x36, int) /* pty: generate signal */ #define TIOCVHANGUP 0x5437 +#define TIOCGPKT _IOR('T', 0x38, int) /* Get packet mode state */ +#define TIOCGPTLCK _IOR('T', 0x39, int) /* Get Pty lock state */ +#define TIOCGEXCL _IOR('T', 0x40, int) /* Get exclusive mode state */ #define FIONCLEX 0x5450 #define FIOCLEX 0x5451 -- cgit v1.2.3 From 84fd7bdf1266ee6228319903af7e58702745024d Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 24 Oct 2012 23:43:22 +0400 Subject: tty: Add get- ioctls to fetch tty status v3 For checkpoint/restore we need to know if tty has exclusive or packet mode set, as well as if pty is currently locked. Just to be able to restore this characteristics. For this sake the following ioctl codes are introduced - TIOCGPKT to get packet mode state - TIOCGPTLCK to get Pty locked state - TIOCGEXCL to get Exclusive mode state Note this ioctls are a bit unsafe in terms of data obtained consistency. The tty characteristics might be changed right after ioctl complete. Keep it in mind and use this ioctl carefully. v2: - Use TIOC prefix for ioctl codes (by jslaby@) Signed-off-by: Cyrill Gorcunov CC: Alan Cox CC: "H. Peter Anvin" CC: Pavel Emelyanov CC: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 21 +++++++++++++++++++++ drivers/tty/tty_io.c | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index df3c64272d2..0ce0b3ec2bb 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -171,6 +171,12 @@ static int pty_set_lock(struct tty_struct *tty, int __user *arg) return 0; } +static int pty_get_lock(struct tty_struct *tty, int __user *arg) +{ + int locked = test_bit(TTY_PTY_LOCK, &tty->flags); + return put_user(locked, arg); +} + /* Set the packet mode on a pty */ static int pty_set_pktmode(struct tty_struct *tty, int __user *arg) { @@ -193,6 +199,13 @@ static int pty_set_pktmode(struct tty_struct *tty, int __user *arg) return 0; } +/* Get the packet mode of a pty */ +static int pty_get_pktmode(struct tty_struct *tty, int __user *arg) +{ + int pktmode = tty->packet; + return put_user(pktmode, arg); +} + /* Send a signal to the slave */ static int pty_signal(struct tty_struct *tty, int sig) { @@ -420,8 +433,12 @@ static int pty_bsd_ioctl(struct tty_struct *tty, switch (cmd) { case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ return pty_set_lock(tty, (int __user *) arg); + case TIOCGPTLCK: /* Get PT Lock status */ + return pty_get_lock(tty, (int __user *)arg); case TIOCPKT: /* Set PT packet mode */ return pty_set_pktmode(tty, (int __user *)arg); + case TIOCGPKT: /* Get PT packet mode */ + return pty_get_pktmode(tty, (int __user *)arg); case TIOCSIG: /* Send signal to other side of pty */ return pty_signal(tty, (int) arg); } @@ -536,8 +553,12 @@ static int pty_unix98_ioctl(struct tty_struct *tty, switch (cmd) { case TIOCSPTLCK: /* Set PT Lock (disallow slave open) */ return pty_set_lock(tty, (int __user *)arg); + case TIOCGPTLCK: /* Get PT Lock status */ + return pty_get_lock(tty, (int __user *)arg); case TIOCPKT: /* Set PT packet mode */ return pty_set_pktmode(tty, (int __user *)arg); + case TIOCGPKT: /* Get PT packet mode */ + return pty_get_pktmode(tty, (int __user *)arg); case TIOCGPTN: /* Get PT Number */ return put_user(tty->index, (unsigned int __user *)arg); case TIOCSIG: /* Send signal to other side of pty */ diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index a3eba7f359e..739ea86c1cf 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2687,6 +2687,11 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case TIOCNXCL: clear_bit(TTY_EXCLUSIVE, &tty->flags); return 0; + case TIOCGEXCL: + { + int excl = test_bit(TTY_EXCLUSIVE, &tty->flags); + return put_user(excl, (int __user *)p); + } case TIOCNOTTY: if (current->signal->tty != tty) return -ENOTTY; -- cgit v1.2.3 From 585628255a8c359d3db81818a23acfc6f22ff6d8 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 25 Oct 2012 01:50:58 -0400 Subject: staging: csr: remove panic at locking the mutex when down_interruptible fail, means a signal occur, or any other failure we are panicing, and it seems that we should not panic, instead we would have done a spinlock, but currently removing the panic call. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/csr/csr_framework_ext.c b/drivers/staging/csr/csr_framework_ext.c index e203f606de3..e62878ecbd2 100644 --- a/drivers/staging/csr/csr_framework_ext.c +++ b/drivers/staging/csr/csr_framework_ext.c @@ -82,7 +82,6 @@ CsrResult CsrMutexLock(CsrMutexHandle *mutexHandle) if (down_interruptible(mutexHandle)) { - CsrPanic(CSR_TECH_FW, CSR_PANIC_FW_UNEXPECTED_VALUE, "CsrMutexLock Failed"); return CSR_FE_RESULT_INVALID_POINTER; } -- cgit v1.2.3 From f28c407587846e5fc0ce1a9cf4876b74b21ab0ee Mon Sep 17 00:00:00 2001 From: Chihau Chau Date: Thu, 25 Oct 2012 03:37:38 -0300 Subject: Staging: csr: bh.c: fixing spaces coding style issues Fixed some coding style issues replacing spaces for tab at the beginning of some lines Signed-off-by: Chihau Chau Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/bh.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/staging/csr/bh.c b/drivers/staging/csr/bh.c index addee05a451..1a1f5c79822 100644 --- a/drivers/staging/csr/bh.c +++ b/drivers/staging/csr/bh.c @@ -228,20 +228,19 @@ handle_bh_error(unifi_priv_t *priv) * * --------------------------------------------------------------------------- */ -static int -bh_thread_function(void *arg) +static int bh_thread_function(void *arg) { - unifi_priv_t *priv = (unifi_priv_t*)arg; - CsrResult csrResult; - long ret; - u32 timeout, t; - struct uf_thread *this_thread; + unifi_priv_t *priv = (unifi_priv_t *)arg; + CsrResult csrResult; + long ret; + u32 timeout, t; + struct uf_thread *this_thread; - unifi_trace(priv, UDBG2, "bh_thread_function starting\n"); + unifi_trace(priv, UDBG2, "bh_thread_function starting\n"); - this_thread = &priv->bh_thread; + this_thread = &priv->bh_thread; - t = timeout = 0; + t = timeout = 0; while (!kthread_should_stop()) { /* wait until an error occurs, or we need to process something. */ unifi_trace(priv, UDBG3, "bh_thread goes to sleep.\n"); -- cgit v1.2.3 From 94b12302f2792199b1c6b0e6aa38d2915848091e Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Thu, 25 Oct 2012 15:54:53 +0900 Subject: staging: csr: csr_log.h: Fix coding style Fix coding style for csr_log.h Signed-off-by: SeongJae Park Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_log.h | 165 ++++++++++++++++++++---------------------- 1 file changed, 80 insertions(+), 85 deletions(-) diff --git a/drivers/staging/csr/csr_log.h b/drivers/staging/csr/csr_log.h index b619db69e14..304f065d5b4 100644 --- a/drivers/staging/csr/csr_log.h +++ b/drivers/staging/csr/csr_log.h @@ -2,11 +2,11 @@ #define CSR_LOG_H__ /***************************************************************************** - (c) Cambridge Silicon Radio Limited 2010 - All rights reserved and confidential information of CSR + (c) Cambridge Silicon Radio Limited 2010 + All rights reserved and confidential information of CSR - Refer to LICENSE.txt included with this source for details - on the license terms. + Refer to LICENSE.txt included with this source for details + on the license terms. *****************************************************************************/ @@ -77,34 +77,31 @@ u8 CsrLogTaskIsFiltered(CsrSchedQid taskId, CsrLogLevelTask level); /* * Logging stuff */ -#define CSR_LOG_STRINGIFY_REAL(a) #a +#define CSR_LOG_STRINGIFY_REAL(a) (#a) #define CSR_LOG_STRINGIFY(a) CSR_LOG_STRINGIFY_REAL(a) #ifdef CSR_LOG_ASSERT_ENABLE -#define CSR_LOG_ASSERT(cond) \ - do { \ - if (!(cond)) \ - { \ - char *panic_arg = "[" __FILE__ ":" CSR_LOG_STRINGIFY(__LINE__) "] - " CSR_LOG_STRINGIFY(cond); \ - CsrPanic(CSR_TECH_FW, CSR_PANIC_FW_ASSERTION_FAIL, panic_arg); \ - } \ - } while (0) +#define CSR_LOG_ASSERT(cond) \ + do { \ + if (!(cond)) { \ + char *panic_arg = "[" __FILE__ ":" CSR_LOG_STRINGIFY(__LINE__) "] - " CSR_LOG_STRINGIFY(cond); \ + CsrPanic(CSR_TECH_FW, CSR_PANIC_FW_ASSERTION_FAIL, panic_arg); \ + } \ + } while (0) #else #define CSR_LOG_ASSERT(cond) #endif -typedef struct -{ - u16 primitiveType; - const char *primitiveName; - CsrMsgConvMsgEntry *messageConv; /* Private - do not use */ +typedef struct { + u16 primitiveType; + const char *primitiveName; + CsrMsgConvMsgEntry *messageConv; /* Private - do not use */ } CsrLogPrimitiveInformation; -typedef struct -{ - const char *techVer; - u32 primitiveInfoCount; - CsrLogPrimitiveInformation *primitiveInfo; +typedef struct { + const char *techVer; + u32 primitiveInfoCount; + CsrLogPrimitiveInformation *primitiveInfo; } CsrLogTechInformation; /*---------------------------------*/ @@ -118,21 +115,19 @@ typedef u32 bitmask32_t; #ifdef CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER /* DEPRECATED - replaced by csr_log_text.h */ #define CSR_LOG_TEXT(text) \ - do { \ - if (!CsrLogTaskIsFiltered(CsrSchedTaskQueueGet(), CSR_LOG_LEVEL_TASK_TEXT)) \ - { \ - CsrLogTaskText(text, __LINE__, __FILE__); \ - } \ - } while (0) + do { \ + if (!CsrLogTaskIsFiltered(CsrSchedTaskQueueGet(), CSR_LOG_LEVEL_TASK_TEXT)) { \ + CsrLogTaskText(text, __LINE__, __FILE__); \ + } \ + } while (0) #else /* DEPRECATED - replaced by csr_log_text.h */ #define CSR_LOG_TEXT(text) \ - do { \ - if (!CsrLogTaskIsFiltered(CsrSchedTaskQueueGet(), CSR_LOG_LEVEL_TASK_TEXT)) \ - { \ - CsrLogTaskText(text, 0, NULL); \ - } \ - } while (0) + do { \ + if (!CsrLogTaskIsFiltered(CsrSchedTaskQueueGet(), CSR_LOG_LEVEL_TASK_TEXT)) { \ + CsrLogTaskText(text, 0, NULL); \ + } \ + } while (0) #endif #else #define CSR_LOG_TEXT(text) @@ -140,8 +135,8 @@ typedef u32 bitmask32_t; /* DEPRECATED - replaced by csr_log_text.h */ void CsrLogTaskText(const char *text, - u32 line, - const char *file); + u32 line, + const char *file); #define CSR_LOG_STATE_TRANSITION_MASK_FSM_NAME (0x001) #define CSR_LOG_STATE_TRANSITION_MASK_NEXT_STATE (0x002) @@ -153,16 +148,16 @@ void CsrLogTaskText(const char *text, /* DEPRECATED - replaced by csr_log_text.h */ void CsrLogStateTransition(bitmask16_t mask, - u32 identifier, - const char *fsm_name, - u32 prev_state, - const char *prev_state_str, - u32 in_event, - const char *in_event_str, - u32 next_state, - const char *next_state_str, - u32 line, - const char *file); + u32 identifier, + const char *fsm_name, + u32 prev_state, + const char *prev_state_str, + u32 in_event, + const char *in_event_str, + u32 next_state, + const char *next_state_str, + u32 line, + const char *file); /*---------------------------------*/ /* BSP logging */ @@ -183,64 +178,64 @@ void CsrLogDeactivate(CsrSchedQid tskid); #define SYNERGY_SERIALIZER_TYPE_SER (0x001) void CsrLogMessagePut(u32 line, - const char *file, - CsrSchedQid src_task_id, - CsrSchedQid dst_taskid, - CsrSchedMsgId msg_id, - u16 prim_type, - const void *msg); + const char *file, + CsrSchedQid src_task_id, + CsrSchedQid dst_taskid, + CsrSchedMsgId msg_id, + u16 prim_type, + const void *msg); void CsrLogMessageGet(CsrSchedQid src_task_id, - CsrSchedQid dst_taskid, - u8 get_res, - CsrSchedMsgId msg_id, - u16 prim_type, - const void *msg); + CsrSchedQid dst_taskid, + u8 get_res, + CsrSchedMsgId msg_id, + u16 prim_type, + const void *msg); void CsrLogTimedEventIn(u32 line, - const char *file, - CsrSchedQid task_id, - CsrSchedTid tid, - u32 requested_delay, - u16 fniarg, - const void *fnvarg); + const char *file, + CsrSchedQid task_id, + CsrSchedTid tid, + u32 requested_delay, + u16 fniarg, + const void *fnvarg); void CsrLogTimedEventFire(CsrSchedQid task_id, - CsrSchedTid tid); + CsrSchedTid tid); void CsrLogTimedEventDone(CsrSchedQid task_id, - CsrSchedTid tid); + CsrSchedTid tid); void CsrLogTimedEventCancel(u32 line, - const char *file, - CsrSchedQid task_id, - CsrSchedTid tid, - u8 cancel_res); + const char *file, + CsrSchedQid task_id, + CsrSchedTid tid, + u8 cancel_res); void CsrLogBgintRegister(u8 thread_id, - CsrSchedBgint irq, - const char *callback, - const void *ptr); + CsrSchedBgint irq, + const char *callback, + const void *ptr); void CsrLogBgintUnregister(CsrSchedBgint irq); void CsrLogBgintSet(CsrSchedBgint irq); void CsrLogBgintServiceStart(CsrSchedBgint irq); void CsrLogBgintServiceDone(CsrSchedBgint irq); void CsrLogExceptionStateEvent(u16 prim_type, - CsrPrim msg_type, - u16 state, - u32 line, - const char *file); + CsrPrim msg_type, + u16 state, + u32 line, + const char *file); void CsrLogExceptionGeneral(u16 prim_type, - u16 state, - const char *text, - u32 line, - const char *file); + u16 state, + const char *text, + u32 line, + const char *file); void CsrLogExceptionWarning(u16 prim_type, - u16 state, - const char *text, - u32 line, - const char *file); + u16 state, + const char *text, + u32 line, + const char *file); #ifdef __cplusplus } -- cgit v1.2.3 From f4221a7a63abd1b6e358d19fe4d05e4d2e44e11a Mon Sep 17 00:00:00 2001 From: Eric Millbrandt Date: Mon, 24 Sep 2012 12:16:47 +0000 Subject: powerpc/pcm030: add pcm030-audio-fabric to dts Add a node for the pcm030-audio-fabric ASoC driver Signed-off-by: Eric Millbrandt Signed-off-by: Anatolij Gustschin --- arch/powerpc/boot/dts/pcm030.dts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts index 9e354997eb7..96512c05803 100644 --- a/arch/powerpc/boot/dts/pcm030.dts +++ b/arch/powerpc/boot/dts/pcm030.dts @@ -59,7 +59,7 @@ #gpio-cells = <2>; }; - psc@2000 { /* PSC1 in ac97 mode */ + audioplatform: psc@2000 { /* PSC1 in ac97 mode */ compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97"; cell-index = <0>; }; @@ -134,4 +134,9 @@ localbus { status = "disabled"; }; + + sound { + compatible = "phytec,pcm030-audio-fabric"; + asoc-platform = <&audioplatform>; + }; }; -- cgit v1.2.3 From e34298c9a29a4b5bdcbb9a8994cc61f6ba506a94 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 10 Oct 2012 23:19:15 +0000 Subject: powerpc: 52xx: nop out unsupported critical IRQs Currently, when booting MPC52xx based platforms, we get: mpc52xx_irqhost_map: invalid irq: virq=16, l1=0, l2=3 irq: irq-16==>hwirq-0x3 mapping failed: -22 [WARNing skipped] The warning is wrong since the mapping itself is valid. However, there is no support for that type of IRQ currently. Print a proper warning and bind the irq to a no_irq chip. Signed-off-by: Wolfram Sang Cc: John Bonesio Cc: Anatolij Gustschin Cc: Grant Likely Signed-off-by: Anatolij Gustschin --- arch/powerpc/platforms/52xx/mpc52xx_pic.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 8520b58a5e9..b89ef65392d 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -372,10 +372,11 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq, case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break; case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break; case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break; - default: - pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n", - __func__, virq, l1irq, l2irq); - return -EINVAL; + case MPC52xx_IRQ_L1_CRIT: + pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n", + __func__, l2irq); + irq_set_chip(virq, &no_irq_chip); + return 0; } irq_set_chip_and_handler(virq, irqchip, handle_level_irq); -- cgit v1.2.3 From 7dfb736ec9917883fc9cfe6d0081987b8b110afe Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 5 Oct 2012 10:23:10 +0000 Subject: powerpc/mpc5200: move lpbfifo node and fix its interrupt property The LPB FIFO interrupt is a peripheral interrupt, thus its L1 cell has to be 2 instead of 3. Fix it and while at it, move the lpbfifo node to the common dtsi file. This patch fixes the irqdomain warning: ... WARNING: at kernel/irq/irqdomain.c:766 Modules linked in: NIP: c00587fc LR: c0058e0c CTR: c0014e54 REGS: c7837c10 TRAP: 0700 Tainted: G W (3.7.0-rc1-00003-g6e51414) MSR: 00029032 CR: 82cd8322 XER: 00000000 TASK = c7834000[1] 'swapper' THREAD: c7836000 GPR00: 00000001 c7837cc0 c7834000 c7806080 000000d7 c7837d20 00000003 c7837cec GPR08: c7837ce8 00000000 00000000 00000008 82cd3342 00000000 c0003f88 00000000 GPR16: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c7850ec0 GPR24: c782b010 00000000 00000001 c7852900 00000003 c7df5be0 c7806080 000000d7 NIP [c00587fc] irq_linear_revmap+0x2c/0x4c LR [c0058e0c] irq_create_mapping+0x28/0x124 Reported-by: Stefan Roese Signed-off-by: Anatolij Gustschin --- arch/powerpc/boot/dts/mpc5200b.dtsi | 6 ++++++ arch/powerpc/boot/dts/o2d.dtsi | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc5200b.dtsi b/arch/powerpc/boot/dts/mpc5200b.dtsi index 7ab286ab530..39ed65a44c5 100644 --- a/arch/powerpc/boot/dts/mpc5200b.dtsi +++ b/arch/powerpc/boot/dts/mpc5200b.dtsi @@ -231,6 +231,12 @@ interrupts = <2 7 0>; }; + sclpc@3c00 { + compatible = "fsl,mpc5200-lpbfifo"; + reg = <0x3c00 0x60>; + interrupts = <2 23 0>; + }; + i2c@3d00 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/powerpc/boot/dts/o2d.dtsi b/arch/powerpc/boot/dts/o2d.dtsi index 3444eb8f0ad..24f66803929 100644 --- a/arch/powerpc/boot/dts/o2d.dtsi +++ b/arch/powerpc/boot/dts/o2d.dtsi @@ -86,12 +86,6 @@ reg = <0>; }; }; - - sclpc@3c00 { - compatible = "fsl,mpc5200-lpbfifo"; - reg = <0x3c00 0x60>; - interrupts = <3 23 0>; - }; }; localbus { -- cgit v1.2.3 From 2066306099d35430d01ed1b3d81c0536d77bf390 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Tue, 23 Oct 2012 19:53:06 -0500 Subject: arm: l2cc: doc: fix device tree example typo The list of attributes above details the use of the 'filter-ranges' property, but the example improperly used 'filter-latency'. Make these consistent by fixing up the example. Signed-off-by: Josh Cartwright Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/arm/l2cc.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/l2cc.txt b/Documentation/devicetree/bindings/arm/l2cc.txt index 7ca52161e7a..7c3ee3aeb7b 100644 --- a/Documentation/devicetree/bindings/arm/l2cc.txt +++ b/Documentation/devicetree/bindings/arm/l2cc.txt @@ -37,7 +37,7 @@ L2: cache-controller { reg = <0xfff12000 0x1000>; arm,data-latency = <1 1 1>; arm,tag-latency = <2 2 2>; - arm,filter-latency = <0x80000000 0x8000000>; + arm,filter-ranges = <0x80000000 0x8000000>; cache-unified; cache-level = <2>; interrupts = <45>; -- cgit v1.2.3 From f65e384bec59ef35dfa77455181af2ecf7a7ef44 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 25 Oct 2012 20:42:10 +0200 Subject: omapdss: dss: Fix clocks on OMAP363x Commit 185bae1095188aa199c9be64d6030d8dbfc65e0a ("OMAPDSS: DSS: Cleanup cpu_is_xxxx checks") broke the DSS clocks configuration by erroneously using the clock parameters applicable to all other OMAP34xx SoCs for the OMAP363x. This went unnoticed probably because the cpu_is_omap34xx() class check wasn't seen as matching the OMAP363x subclass. Fix it by checking for the OMAP363x subclass before checking for the OMAP34xx class. Signed-off-by: Laurent Pinchart Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 2ab1c3e9655..0bb7406bdbb 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -805,10 +805,10 @@ static int __init dss_init_features(struct device *dev) if (cpu_is_omap24xx()) src = &omap24xx_dss_feats; - else if (cpu_is_omap34xx()) - src = &omap34xx_dss_feats; else if (cpu_is_omap3630()) src = &omap3630_dss_feats; + else if (cpu_is_omap34xx()) + src = &omap34xx_dss_feats; else if (cpu_is_omap44xx()) src = &omap44xx_dss_feats; else if (soc_is_omap54xx()) -- cgit v1.2.3 From dffc70ade1d13edd186f542718c4d78a31d92fb8 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 21 Oct 2012 20:54:26 +0800 Subject: OMAPDSS: HDMI: fix missing unlock on error in hdmi_dump_regs() Add the missing unlock on the error handling path in function hdmi_dump_regs(). Signed-off-by: Wei Yongjun Reviewed-by: Sumit Semwal Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/hdmi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index a48a7dd75b3..8c9b8b3b7f7 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -644,8 +644,10 @@ static void hdmi_dump_regs(struct seq_file *s) { mutex_lock(&hdmi.lock); - if (hdmi_runtime_get()) + if (hdmi_runtime_get()) { + mutex_unlock(&hdmi.lock); return; + } hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); -- cgit v1.2.3 From 00a89180e5419f6567135d86e66a989a1b610b45 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 26 Oct 2012 09:55:31 +0300 Subject: Revert "usb: musb: use DMA mode 1 whenever possible" This reverts commit 4f3e8d263d34e52e75b5adfa14811467d3033d8e. it turns out that current implementation of Mode 1 DMA added a few regressions to some users, so we need to revert this patch and let author work on a better version of Mode 1 DMA support. Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d0b87e7b4ab..b6b84dacc79 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -707,11 +707,12 @@ static void rxstate(struct musb *musb, struct musb_request *req) fifo_count = musb_readw(epio, MUSB_RXCOUNT); /* - * use mode 1 only if we expect data of at least ep packet_sz - * and have not yet received a short packet + * Enable Mode 1 on RX transfers only when short_not_ok flag + * is set. Currently short_not_ok flag is set only from + * file_storage and f_mass_storage drivers */ - if ((request->length - request->actual >= musb_ep->packet_sz) && - (fifo_count >= musb_ep->packet_sz)) + + if (request->short_not_ok && fifo_count == musb_ep->packet_sz) use_mode_1 = 1; else use_mode_1 = 0; @@ -727,6 +728,27 @@ static void rxstate(struct musb *musb, struct musb_request *req) c = musb->dma_controller; channel = musb_ep->dma; + /* We use DMA Req mode 0 in rx_csr, and DMA controller operates in + * mode 0 only. So we do not get endpoint interrupts due to DMA + * completion. We only get interrupts from DMA controller. + * + * We could operate in DMA mode 1 if we knew the size of the tranfer + * in advance. For mass storage class, request->length = what the host + * sends, so that'd work. But for pretty much everything else, + * request->length is routinely more than what the host sends. For + * most these gadgets, end of is signified either by a short packet, + * or filling the last byte of the buffer. (Sending extra data in + * that last pckate should trigger an overflow fault.) But in mode 1, + * we don't get DMA completion interrupt for short packets. + * + * Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1), + * to get endpoint interrupt on every DMA req, but that didn't seem + * to work reliably. + * + * REVISIT an updated g_file_storage can set req->short_not_ok, which + * then becomes usable as a runtime "use mode 1" hint... + */ + /* Experimental: Mode1 works with mass storage use cases */ if (use_mode_1) { csr |= MUSB_RXCSR_AUTOCLEAR; -- cgit v1.2.3 From d6a2fa0424aefe97289aa561444ec3ae09bdbba0 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Wed, 24 Oct 2012 12:34:46 +0400 Subject: GPIO: clps711x: Fix direction logic for PORTD PORTD have different direction logic, i.e. "0" is output and "1" is input. This patch fix this issue. Signed-off-by: Alexander Shiyan Signed-off-by: Linus Walleij --- drivers/gpio/gpio-clps711x.c | 65 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c index 0753b3a9a34..ad181db7950 100644 --- a/drivers/gpio/gpio-clps711x.c +++ b/drivers/gpio/gpio-clps711x.c @@ -65,7 +65,7 @@ static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset, spin_unlock_irqrestore(&gpio->lock, flags); } -static int gpio_clps711x_direction_in(struct gpio_chip *chip, unsigned offset) +static int gpio_clps711x_dir_in(struct gpio_chip *chip, unsigned offset) { int tmp; unsigned long flags; @@ -79,8 +79,8 @@ static int gpio_clps711x_direction_in(struct gpio_chip *chip, unsigned offset) return 0; } -static int gpio_clps711x_direction_out(struct gpio_chip *chip, unsigned offset, - int value) +static int gpio_clps711x_dir_out(struct gpio_chip *chip, unsigned offset, + int value) { int tmp; unsigned long flags; @@ -98,17 +98,49 @@ static int gpio_clps711x_direction_out(struct gpio_chip *chip, unsigned offset, return 0; } -struct clps711x_gpio_port { +static int gpio_clps711x_dir_in_inv(struct gpio_chip *chip, unsigned offset) +{ + int tmp; + unsigned long flags; + struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); + + spin_lock_irqsave(&gpio->lock, flags); + tmp = readb(clps711x_pdir(chip)) | (1 << offset); + writeb(tmp, clps711x_pdir(chip)); + spin_unlock_irqrestore(&gpio->lock, flags); + + return 0; +} + +static int gpio_clps711x_dir_out_inv(struct gpio_chip *chip, unsigned offset, + int value) +{ + int tmp; + unsigned long flags; + struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); + + spin_lock_irqsave(&gpio->lock, flags); + tmp = readb(clps711x_pdir(chip)) & ~(1 << offset); + writeb(tmp, clps711x_pdir(chip)); + tmp = readb(clps711x_port(chip)) & ~(1 << offset); + if (value) + tmp |= 1 << offset; + writeb(tmp, clps711x_port(chip)); + spin_unlock_irqrestore(&gpio->lock, flags); + + return 0; +} + +static struct { char *name; int nr; -}; - -static const struct clps711x_gpio_port clps711x_gpio_ports[] __initconst = { - { "PORTA", 8, }, - { "PORTB", 8, }, - { "PORTC", 8, }, - { "PORTD", 8, }, - { "PORTE", 3, }, + int inv_dir; +} clps711x_gpio_ports[] __initconst = { + { "PORTA", 8, 0, }, + { "PORTB", 8, 0, }, + { "PORTC", 8, 0, }, + { "PORTD", 8, 1, }, + { "PORTE", 3, 0, }, }; static int __init gpio_clps711x_init(void) @@ -145,10 +177,15 @@ static int __init gpio_clps711x_init(void) gpio->chip[i].label = clps711x_gpio_ports[i].name; gpio->chip[i].base = i * 8; gpio->chip[i].ngpio = clps711x_gpio_ports[i].nr; - gpio->chip[i].direction_input = gpio_clps711x_direction_in; gpio->chip[i].get = gpio_clps711x_get; - gpio->chip[i].direction_output = gpio_clps711x_direction_out; gpio->chip[i].set = gpio_clps711x_set; + if (!clps711x_gpio_ports[i].inv_dir) { + gpio->chip[i].direction_input = gpio_clps711x_dir_in; + gpio->chip[i].direction_output = gpio_clps711x_dir_out; + } else { + gpio->chip[i].direction_input = gpio_clps711x_dir_in_inv; + gpio->chip[i].direction_output = gpio_clps711x_dir_out_inv; + } WARN_ON(gpiochip_add(&gpio->chip[i])); } -- cgit v1.2.3 From 80b0a6029272247f19146bf8f88e5d4bba94cba5 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Wed, 24 Oct 2012 17:25:27 +0300 Subject: gpiolib: add gpio get direction callback support Add .get_direction callback to gpio_chip. This allows gpiolib to check the current direction of a gpio. Used to show the correct gpio direction in sysfs and debug entries. If callback is not set then gpiolib will work as previously; e.g. guessing everything is input until a direction is set. Signed-off-by: Mathias Nyman Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 38 +++++++++++++++++++++++++++++++++++++- include/asm-generic/gpio.h | 5 ++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index d5f9742d9ac..e468eed261c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -191,6 +191,32 @@ err: return ret; } +/* caller ensures gpio is valid and requested, chip->get_direction may sleep */ +static int gpio_get_direction(unsigned gpio) +{ + struct gpio_chip *chip; + struct gpio_desc *desc = &gpio_desc[gpio]; + int status = -EINVAL; + + chip = gpio_to_chip(gpio); + gpio -= chip->base; + + if (!chip->get_direction) + return status; + + status = chip->get_direction(chip, gpio); + if (status > 0) { + /* GPIOF_DIR_IN, or other positive */ + status = 1; + clear_bit(FLAG_IS_OUT, &desc->flags); + } + if (status == 0) { + /* GPIOF_DIR_OUT */ + set_bit(FLAG_IS_OUT, &desc->flags); + } + return status; +} + #ifdef CONFIG_GPIO_SYSFS /* lock protects against unexport_gpio() being called while @@ -223,6 +249,7 @@ static ssize_t gpio_direction_show(struct device *dev, struct device_attribute *attr, char *buf) { const struct gpio_desc *desc = dev_get_drvdata(dev); + unsigned gpio = desc - gpio_desc; ssize_t status; mutex_lock(&sysfs_lock); @@ -230,6 +257,7 @@ static ssize_t gpio_direction_show(struct device *dev, if (!test_bit(FLAG_EXPORT, &desc->flags)) status = -EIO; else + gpio_get_direction(gpio); status = sprintf(buf, "%s\n", test_bit(FLAG_IS_OUT, &desc->flags) ? "out" : "in"); @@ -1080,6 +1108,7 @@ int gpiochip_add(struct gpio_chip *chip) * inputs (often with pullups enabled) so power * usage is minimized. Linux code should set the * gpio direction first thing; but until it does, + * and in case chip->get_direction is not set, * we may expose the wrong direction in sysfs. */ gpio_desc[id].flags = !chip->direction_input @@ -1231,9 +1260,15 @@ int gpio_request(unsigned gpio, const char *label) desc_set_label(desc, NULL); module_put(chip->owner); clear_bit(FLAG_REQUESTED, &desc->flags); + goto done; } } - + if (chip->get_direction) { + /* chip->get_direction may sleep */ + spin_unlock_irqrestore(&gpio_lock, flags); + gpio_get_direction(gpio); + spin_lock_irqsave(&gpio_lock, flags); + } done: if (status) pr_debug("gpio_request: gpio-%d (%s) status %d\n", @@ -1769,6 +1804,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) continue; + gpio_get_direction(gpio); is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); seq_printf(s, " gpio-%-3d (%-20.20s) %s %s", gpio, gdesc->label, diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index a9432fc6b8b..eb70ca29597 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -56,6 +56,8 @@ struct device_node; * enabling module power and clock; may sleep * @free: optional hook for chip-specific deactivation, such as * disabling module power and clock; may sleep + * @get_direction: returns direction for signal "offset", 0=out, 1=in, + * (same as GPIOF_DIR_XXX), or negative error * @direction_input: configures signal "offset" as input, or returns error * @get: returns value for signal "offset"; for output signals this * returns either the value actually sensed, or zero @@ -100,7 +102,8 @@ struct gpio_chip { unsigned offset); void (*free)(struct gpio_chip *chip, unsigned offset); - + int (*get_direction)(struct gpio_chip *chip, + unsigned offset); int (*direction_input)(struct gpio_chip *chip, unsigned offset); int (*get)(struct gpio_chip *chip, -- cgit v1.2.3 From 529f2ad5e374f61987a8312603963c61d75a890a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 26 Oct 2012 09:59:43 +0300 Subject: gpiolib: unlock on error in gpio_export() We need to unlock here before returning. Signed-off-by: Dan Carpenter Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e468eed261c..fd2b71c7099 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -756,7 +756,8 @@ int gpio_export(unsigned gpio, bool direction_may_change) __func__, gpio, test_bit(FLAG_REQUESTED, &desc->flags), test_bit(FLAG_EXPORT, &desc->flags)); - return -EPERM; + status = -EPERM; + goto fail_unlock; } if (!desc->chip->direction_input || !desc->chip->direction_output) -- cgit v1.2.3 From d0235677311cbd404a3dcd3c0f24bf15dd24dd36 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 16 Oct 2012 21:00:09 +0200 Subject: gpio/tegra: convert to use linear irqdomain The Tegra driver tries to do the work of irq_domain_add_linear() by reserving a bunch of descriptors somewhere and keeping track of the base offset, then calling irq_domain_add_legacy(). Let's stop doing that and simply use the linear IRQ domain. For this to work: use irq_create_mapping() in the IRQ iterator so that the descriptors get allocated here. Cc: Rob Herring Cc: Grant Likely Tested-by: Stephen Warren Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index d982593d756..c7c175a4aff 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -380,7 +380,6 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) { const struct of_device_id *match; struct tegra_gpio_soc_config *config; - int irq_base; struct resource *res; struct tegra_gpio_bank *bank; int gpio; @@ -417,14 +416,11 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) return -ENODEV; } - irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0); - if (irq_base < 0) { - dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n"); - return -ENODEV; - } - irq_domain = irq_domain_add_legacy(pdev->dev.of_node, - tegra_gpio_chip.ngpio, irq_base, 0, + irq_domain = irq_domain_add_linear(pdev->dev.of_node, + tegra_gpio_chip.ngpio, &irq_domain_simple_ops, NULL); + if (!irq_domain) + return -ENODEV; for (i = 0; i < tegra_gpio_bank_count; i++) { res = platform_get_resource(pdev, IORESOURCE_IRQ, i); @@ -464,7 +460,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) gpiochip_add(&tegra_gpio_chip); for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) { - int irq = irq_find_mapping(irq_domain, gpio); + int irq = irq_create_mapping(irq_domain, gpio); /* No validity check; all Tegra GPIOs are valid IRQs */ bank = &tegra_gpio_banks[GPIO_BANK(gpio)]; -- cgit v1.2.3 From ce931f571b6dcf8534e8740e8cd16565cf362536 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 16 Oct 2012 20:21:04 +0200 Subject: gpio/mvebu: convert to use irq_domain_add_simple() The MVEBU driver probably just wants a few IRQs. Using the simple domain has the upside of allocating IRQ descriptors if need be, especially in a SPARSE_IRQ environment. Cc: Rob Herring Cc: Grant Likely Cc: Thomas Petazzoni Cc: Sebastian Hesselbarth Cc: Andrew Lunn Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mvebu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 902af437eaf..e0bde063221 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -645,8 +645,8 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); /* Setup irq domain on top of the generic chip. */ - mvchip->domain = irq_domain_add_legacy(np, mvchip->chip.ngpio, - mvchip->irqbase, 0, + mvchip->domain = irq_domain_add_simple(np, mvchip->chip.ngpio, + mvchip->irqbase, &irq_domain_simple_ops, mvchip); if (!mvchip->domain) { -- cgit v1.2.3 From 7385500a49b769c95438c111aff92110b06ff751 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 16 Oct 2012 20:15:02 +0200 Subject: gpio/em: convert to linear IRQ domain The code in the em driver seems to want to try to do the job of the linear IRQ domain (allocate descriptors and grab a virtual range). So why not just use the linear IRQ domain? The code is now cut down so we don't need isolated functions for this. Also note that we use irq_create_mapping() to make sure descriptors are allocated for these IRQs. Also fixed the FIXME to remove the domain after use. Cc: Grant Likely Cc: Magnus Damm Signed-off-by: Linus Walleij --- drivers/gpio/gpio-em.c | 46 +++++++--------------------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index efb4c2d0d13..88bdfe37816 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -35,7 +35,6 @@ struct em_gio_priv { void __iomem *base0; void __iomem *base1; - unsigned int irq_base; spinlock_t sense_lock; struct platform_device *pdev; struct gpio_chip gpio_chip; @@ -214,7 +213,7 @@ static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset, static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset) { - return irq_find_mapping(gpio_to_priv(chip)->irq_domain, offset); + return irq_create_mapping(gpio_to_priv(chip)->irq_domain, offset); } static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq, @@ -234,40 +233,6 @@ static struct irq_domain_ops em_gio_irq_domain_ops = { .map = em_gio_irq_domain_map, }; -static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p) -{ - struct platform_device *pdev = p->pdev; - struct gpio_em_config *pdata = pdev->dev.platform_data; - - p->irq_base = irq_alloc_descs(pdata->irq_base, 0, - pdata->number_of_pins, numa_node_id()); - if (p->irq_base < 0) { - dev_err(&pdev->dev, "cannot get irq_desc\n"); - return p->irq_base; - } - pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n", - pdata->gpio_base, pdata->number_of_pins, p->irq_base); - - p->irq_domain = irq_domain_add_legacy(pdev->dev.of_node, - pdata->number_of_pins, - p->irq_base, 0, - &em_gio_irq_domain_ops, p); - if (!p->irq_domain) { - irq_free_descs(p->irq_base, pdata->number_of_pins); - return -ENXIO; - } - - return 0; -} - -static void em_gio_irq_domain_cleanup(struct em_gio_priv *p) -{ - struct gpio_em_config *pdata = p->pdev->dev.platform_data; - - irq_free_descs(p->irq_base, pdata->number_of_pins); - /* FIXME: irq domain wants to be freed! */ -} - static int __devinit em_gio_probe(struct platform_device *pdev) { struct gpio_em_config *pdata = pdev->dev.platform_data; @@ -334,8 +299,11 @@ static int __devinit em_gio_probe(struct platform_device *pdev) irq_chip->irq_set_type = em_gio_irq_set_type; irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; - ret = em_gio_irq_domain_init(p); - if (ret) { + p->irq_domain = irq_domain_add_linear(pdev->dev.of_node, + pdata->number_of_pins, + &em_gio_irq_domain_ops, p); + if (!p->irq_domain) + err = -ENXIO; dev_err(&pdev->dev, "cannot initialize irq domain\n"); goto err3; } @@ -364,7 +332,7 @@ err6: err5: free_irq(irq[0]->start, pdev); err4: - em_gio_irq_domain_cleanup(p); + irq_domain_remove(p->irq_domain); err3: iounmap(p->base1); err2: -- cgit v1.2.3 From a362605b341d95e7209ead8052363cb28dda1c44 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 16 Oct 2012 19:43:53 +0200 Subject: gpio/tc3589x: convert to use the simple irqdomain The special checks for whether we have a base IRQ offset or not is surplus if we use the simple IRQ domain. The IRQ offset zero will be interpreted as a linear domain case. Plus this makes sure we allocate descriptors where need be, or warn if they are preallocated with SPARSE_IRQ. Cc: Grant Likely Cc: Rob Herring Cc: Lee Jones Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tc3589x.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 1e48317e70f..8c8447c7d2a 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -292,17 +292,15 @@ static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio, { int base = tc3589x_gpio->irq_base; - if (base) { - tc3589x_gpio->domain = irq_domain_add_legacy( - NULL, tc3589x_gpio->chip.ngpio, base, - 0, &tc3589x_irq_ops, tc3589x_gpio); - } - else { - tc3589x_gpio->domain = irq_domain_add_linear( - np, tc3589x_gpio->chip.ngpio, - &tc3589x_irq_ops, tc3589x_gpio); - } - + /* + * If this results in a linear domain, irq_create_mapping() will + * take care of allocating IRQ descriptors at runtime. When a base + * is provided, the IRQ descriptors will be allocated when the + * domain is instantiated. + */ + tc3589x_gpio->domain = irq_domain_add_simple(np, + tc3589x_gpio->chip.ngpio, base, &tc3589x_irq_ops, + tc3589x_gpio); if (!tc3589x_gpio->domain) { dev_err(tc3589x_gpio->dev, "Failed to create irqdomain\n"); return -ENOSYS; -- cgit v1.2.3 From 562915153140292b8c59bcab12f039b3aef78cb5 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 23 Oct 2012 13:24:51 +0800 Subject: usb: musb: am35x: use platform_device_unregister in am35x_remove() platform_device_unregister() only calls platform_device_del() and platform_device_put(), thus use platform_device_unregister() to simplify the code. Also the documents in platform.c shows that platform_device_del and platform_device_put must _only_ be externally called in error cases. All other usage is a bug. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/musb/am35x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 89b128bdbca..fdfd779c35b 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -572,8 +572,7 @@ static int __devexit am35x_remove(struct platform_device *pdev) struct am35x_glue *glue = platform_get_drvdata(pdev); musb_put_id(&pdev->dev, glue->musb->id); - platform_device_del(glue->musb); - platform_device_put(glue->musb); + platform_device_unregister(glue->musb); clk_disable(glue->clk); clk_disable(glue->phy_clk); clk_put(glue->clk); -- cgit v1.2.3 From 01e40da08ca1fd6febcfbac819dbf07ad80bf2af Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 23 Oct 2012 13:26:00 +0800 Subject: usb: musb: blackfin: use platform_device_unregister in bfin_remove() platform_device_unregister() only calls platform_device_del() and platform_device_put(), thus use platform_device_unregister() to simplify the code. Also the documents in platform.c shows that platform_device_del and platform_device_put must _only_ be externally called in error cases. All other usage is a bug. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/musb/blackfin.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 8c16a22e171..307e726a2bd 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -528,8 +528,7 @@ static int __devexit bfin_remove(struct platform_device *pdev) struct bfin_glue *glue = platform_get_drvdata(pdev); musb_put_id(&pdev->dev, glue->musb->id); - platform_device_del(glue->musb); - platform_device_put(glue->musb); + platform_device_unregister(glue->musb); kfree(glue); return 0; -- cgit v1.2.3 From b59e906c57403d5c55abb43c3602ffbb72b3ae60 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 23 Oct 2012 13:26:15 +0800 Subject: usb: musb: da8xx: use platform_device_unregister in da8xx_remove() platform_device_unregister() only calls platform_device_del() and platform_device_put(), thus use platform_device_unregister() to simplify the code. Also the documents in platform.c shows that platform_device_del and platform_device_put must _only_ be externally called in error cases. All other usage is a bug. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/musb/da8xx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 2366b818443..e94f556c6ae 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -573,8 +573,7 @@ static int __devexit da8xx_remove(struct platform_device *pdev) struct da8xx_glue *glue = platform_get_drvdata(pdev); musb_put_id(&pdev->dev, glue->musb->id); - platform_device_del(glue->musb); - platform_device_put(glue->musb); + platform_device_unregister(glue->musb); clk_disable(glue->clk); clk_put(glue->clk); kfree(glue); -- cgit v1.2.3 From 12a71f5b1ce510335c720443b6eec691ed3cf906 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 23 Oct 2012 13:35:46 +0800 Subject: usb: musb: davinci: use platform_device_unregister in davinci_remove() platform_device_unregister() only calls platform_device_del() and platform_device_put(), thus use platform_device_unregister() to simplify the code. Also the documents in platform.c shows that platform_device_del and platform_device_put must _only_ be externally called in error cases. All other usage is a bug. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/musb/davinci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 62785bf0f95..959a6d71e1d 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -605,8 +605,7 @@ static int __devexit davinci_remove(struct platform_device *pdev) struct davinci_glue *glue = platform_get_drvdata(pdev); musb_put_id(&pdev->dev, glue->musb->id); - platform_device_del(glue->musb); - platform_device_put(glue->musb); + platform_device_unregister(glue->musb); clk_disable(glue->clk); clk_put(glue->clk); kfree(glue); -- cgit v1.2.3 From b415c8fa9ee46f07a5a8c0dbf34c75519290a912 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 23 Oct 2012 13:36:06 +0800 Subject: usb: musb: dsps: use platform_device_unregister in dsps_delete_musb_pdev() platform_device_unregister() only calls platform_device_del() and platform_device_put(), thus use platform_device_unregister() to simplify the code. Also the documents in platform.c shows that platform_device_del and platform_device_put must _only_ be externally called in error cases. All other usage is a bug. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 444346e1e10..828d2a216d9 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -565,8 +565,7 @@ err0: static void dsps_delete_musb_pdev(struct dsps_glue *glue, u8 id) { musb_put_id(glue->dev, glue->musb[id]->id); - platform_device_del(glue->musb[id]); - platform_device_put(glue->musb[id]); + platform_device_unregister(glue->musb[id]); } static int __devinit dsps_probe(struct platform_device *pdev) -- cgit v1.2.3 From a81a01f9feab302504c3e43fbece99fd7f578df8 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 23 Oct 2012 13:36:20 +0800 Subject: usb: musb: tusb6010: use platform_device_unregister in tusb_remove() platform_device_unregister() only calls platform_device_del() and platform_device_put(), thus use platform_device_unregister() to simplify the code. Also the documents in platform.c shows that platform_device_del and platform_device_put must _only_ be externally called in error cases. All other usage is a bug. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/musb/tusb6010.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 39ece28019f..4454561c6f5 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1233,8 +1233,7 @@ static int __devexit tusb_remove(struct platform_device *pdev) struct tusb6010_glue *glue = platform_get_drvdata(pdev); musb_put_id(&pdev->dev, glue->musb->id); - platform_device_del(glue->musb); - platform_device_put(glue->musb); + platform_device_unregister(glue->musb); kfree(glue); return 0; -- cgit v1.2.3 From 4b0de6f38362960460d3693f122c6abe6bb0704b Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 23 Oct 2012 13:36:43 +0800 Subject: usb: musb: ux500: use platform_device_unregister in ux500_remove() platform_device_unregister() only calls platform_device_del() and platform_device_put(), thus use platform_device_unregister() to simplify the code. Also the documents in platform.c shows that platform_device_del and platform_device_put must _only_ be externally called in error cases. All other usage is a bug. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index be1430ad60e..4197f307ae0 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -159,8 +159,7 @@ static int __devexit ux500_remove(struct platform_device *pdev) struct ux500_glue *glue = platform_get_drvdata(pdev); musb_put_id(&pdev->dev, glue->musb->id); - platform_device_del(glue->musb); - platform_device_put(glue->musb); + platform_device_unregister(glue->musb); clk_disable(glue->clk); clk_put(glue->clk); kfree(glue); -- cgit v1.2.3 From 9a65d162e449145706aa7309a1be00e3c3d5c80e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 23 Oct 2012 14:12:37 +0800 Subject: usb: musb: ux500: fix 'musbid' undeclared error in ux500_remove() commit 65b3d52d02a558fbfe08e43688e15390c5ab3067 (usb: musb: add musb_ida for multi instance support) used musbid in ux500_remove() but nerver declared it. I found this in x86_64 platform, but not sure whether this is a error on the correct ARCH. $ make drivers/usb/musb/ux500.o make[1]: Nothing to be done for `all'. make[1]: Nothing to be done for `relocs'. CHK include/generated/uapi/linux/version.h CHK include/generated/utsrelease.h UPD include/generated/utsrelease.h CALL scripts/checksyscalls.sh CC drivers/usb/musb/ux500.o drivers/usb/musb/ux500.c: In function 'ux500_probe': drivers/usb/musb/ux500.c:78:2: error: 'musbid' undeclared (first use in this function) drivers/usb/musb/ux500.c:78:2: note: each undeclared identifier is reported only once for each function it appears in make[1]: *** [drivers/usb/musb/ux500.o] Error 1 make: *** [drivers/usb/musb/ux500.o] Error 2 Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index d62a91fedc2..0e62f504410 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -65,7 +65,7 @@ static int __devinit ux500_probe(struct platform_device *pdev) struct platform_device *musb; struct ux500_glue *glue; struct clk *clk; - + int musbid; int ret = -ENOMEM; glue = kzalloc(sizeof(*glue), GFP_KERNEL); -- cgit v1.2.3 From c6039f4a00901259517b7c027007697105209968 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Thu, 25 Oct 2012 20:17:02 -0700 Subject: x86/boot/doc: Fix grammar and typo in boot.txt Fixes some minor issues in the x86 boot documentation. Signed-off-by: Kees Cook Cc: Rob Landley Link: http://lkml.kernel.org/r/20121026031702.GA23828@www.outflux.net Signed-off-by: Ingo Molnar --- Documentation/x86/boot.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt index 9efceff51bf..f15cb74c4f7 100644 --- a/Documentation/x86/boot.txt +++ b/Documentation/x86/boot.txt @@ -1013,7 +1013,7 @@ boot_params as that of 16-bit boot protocol, the boot loader should also fill the additional fields of the struct boot_params as that described in zero-page.txt. -After setupping the struct boot_params, the boot loader can load the +After setting up the struct boot_params, the boot loader can load the 32/64-bit kernel in the same way as that of 16-bit boot protocol. In 32-bit boot protocol, the kernel is started by jumping to the @@ -1023,7 +1023,7 @@ In 32-bit boot protocol, the kernel is started by jumping to the At entry, the CPU must be in 32-bit protected mode with paging disabled; a GDT must be loaded with the descriptors for selectors __BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G flat -segment; __BOOS_CS must have execute/read permission, and __BOOT_DS +segment; __BOOT_CS must have execute/read permission, and __BOOT_DS must have read/write permission; CS must be __BOOT_CS and DS, ES, SS must be __BOOT_DS; interrupt must be disabled; %esi must hold the base address of the struct boot_params; %ebp, %edi and %ebx must be zero. -- cgit v1.2.3 From 6e87f9b7e48e165cb8e6092b9abe682e7065614a Mon Sep 17 00:00:00 2001 From: Bin Gao Date: Thu, 25 Oct 2012 09:35:44 -0700 Subject: arch/x86/Kconfig: Allow turning off CONFIG_X86_MPPARSE when either ACPI or SFI is present MPS tables are not needed for systems that have proper ACPI support. This is also true for systems that have SFI in place. So this patch allows the configuration (turning off) of CONFIG_X86_MPPARSE when either ACPI or SFI is present. Signed-off-by: Bin Gao Cc: Len Brown Cc: Bin Gao Link: http://lkml.kernel.org/r/20121025163544.GB38477@bingao-desk1.fm.intel.com Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 46c3bff3ced..b1494bd92b6 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -310,7 +310,7 @@ config X86_X2APIC If you don't know what to do here, say N. config X86_MPPARSE - bool "Enable MPS table" if ACPI + bool "Enable MPS table" if ACPI || SFI default y depends on X86_LOCAL_APIC ---help--- -- cgit v1.2.3 From 4d0e42cc66f4e7e0bf08b29da1ae6ebd60549c4e Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Thu, 25 Oct 2012 18:13:11 +0200 Subject: x86: Remove dead hlt_use_halt code The hlt_use_halt function returns always true and there is only one definition of it. The default_idle function can then get ride of the if ... statement and we can remove the else branch. Signed-off-by: Daniel Lezcano Cc: linaro-dev@lists.linaro.org Cc: patches@linaro.org Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1351181591-8710-1-git-send-email-daniel.lezcano@linaro.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/process.c | 39 ++++++++++++++------------------------- 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index b644e1c765d..2f99e312187 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -306,11 +306,6 @@ void (*pm_idle)(void); EXPORT_SYMBOL(pm_idle); #endif -static inline int hlt_use_halt(void) -{ - return 1; -} - #ifndef CONFIG_SMP static inline void play_dead(void) { @@ -410,28 +405,22 @@ void cpu_idle(void) */ void default_idle(void) { - if (hlt_use_halt()) { - trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id()); - trace_cpu_idle_rcuidle(1, smp_processor_id()); - current_thread_info()->status &= ~TS_POLLING; - /* - * TS_POLLING-cleared state must be visible before we - * test NEED_RESCHED: - */ - smp_mb(); + trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id()); + trace_cpu_idle_rcuidle(1, smp_processor_id()); + current_thread_info()->status &= ~TS_POLLING; + /* + * TS_POLLING-cleared state must be visible before we + * test NEED_RESCHED: + */ + smp_mb(); - if (!need_resched()) - safe_halt(); /* enables interrupts racelessly */ - else - local_irq_enable(); - current_thread_info()->status |= TS_POLLING; - trace_power_end_rcuidle(smp_processor_id()); - trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); - } else { + if (!need_resched()) + safe_halt(); /* enables interrupts racelessly */ + else local_irq_enable(); - /* loop is done by the caller */ - cpu_relax(); - } + current_thread_info()->status |= TS_POLLING; + trace_power_end_rcuidle(smp_processor_id()); + trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); } #ifdef CONFIG_APM_MODULE EXPORT_SYMBOL(default_idle); -- cgit v1.2.3 From 98a1eebda3cb2a84ecf1f219bb3a95769033d1bf Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Wed, 10 Oct 2012 10:55:28 +0300 Subject: UBIFS: introduce categorized lprops counter This commit is a preparation for a subsequent bugfix. We introduce a counter for categorized lprops. Signed-off-by: Artem Bityutskiy Cc: stable@vger.kernel.org --- fs/ubifs/lprops.c | 6 ++++++ fs/ubifs/ubifs.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c index e5a2a35a46d..46190a7c42a 100644 --- a/fs/ubifs/lprops.c +++ b/fs/ubifs/lprops.c @@ -300,8 +300,11 @@ void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops, default: ubifs_assert(0); } + lprops->flags &= ~LPROPS_CAT_MASK; lprops->flags |= cat; + c->in_a_category_cnt += 1; + ubifs_assert(c->in_a_category_cnt <= c->main_lebs); } /** @@ -334,6 +337,9 @@ static void ubifs_remove_from_cat(struct ubifs_info *c, default: ubifs_assert(0); } + + c->in_a_category_cnt -= 1; + ubifs_assert(c->in_a_category_cnt >= 0); } /** diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 5486346d0a3..d133c276fe0 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -1183,6 +1183,8 @@ struct ubifs_debug_info; * @freeable_list: list of freeable non-index LEBs (free + dirty == @leb_size) * @frdi_idx_list: list of freeable index LEBs (free + dirty == @leb_size) * @freeable_cnt: number of freeable LEBs in @freeable_list + * @in_a_category_cnt: count of lprops which are in a certain category, which + * basically meants that they were loaded from the flash * * @ltab_lnum: LEB number of LPT's own lprops table * @ltab_offs: offset of LPT's own lprops table @@ -1412,6 +1414,7 @@ struct ubifs_info { struct list_head freeable_list; struct list_head frdi_idx_list; int freeable_cnt; + int in_a_category_cnt; int ltab_lnum; int ltab_offs; -- cgit v1.2.3 From b6f4f804108bd563070ab95199cbddcf7650cbf4 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 26 Oct 2012 17:55:48 +0900 Subject: tools lib traceevent: Do not generate dependency for system header files Ingo reported (again!) that 'make clean' on perf/traceevent does not work due to some reason with system header file. Quotes Ingo: "Note that the old dependency related build failure thought to be fixed in commit 860df5833e46 is back: make[1]: *** No rule to make target `/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stddef.h', needed by `.trace-seq.d'. Stop. 'make clean' itself does not work in libtraceevent: comet:~/tip/tools/lib/traceevent> make clean make: *** No rule to make target `/usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stddef.h', needed by `.trace-seq.d'. Stop. So I had to clean it out manually: comet:~/tip/tools/lib/traceevent> git ls-files --others | xargs rm comet:~/tip/tools/lib/traceevent> and then things build fine." Try to fix it by excluding system headers from dependency generation. Signed-off-by: Namhyung Kim Reported-by: Ingo Molnar Cc: Borislav Petkov Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1351241752-2919-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index 04d959fa022..a20e3203343 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -253,7 +253,7 @@ all_deps := $(all_objs:%.o=.%.d) # let .d file also depends on the source and header files define check_deps @set -e; $(RM) $@; \ - $(CC) -M $(CFLAGS) $< > $@.$$$$; \ + $(CC) -MM $(CFLAGS) $< > $@.$$$$; \ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ $(RM) $@.$$$$ endef -- cgit v1.2.3 From 536e2b0fc2af42a464ea6eb6b67a2c754e14f2e2 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 26 Oct 2012 17:55:49 +0900 Subject: perf tools: Cleanup doc related targets Documentation targets handling rules are duplicate. Consolidate them with DOC_TARGETS and INSTALL_DOC_TARGETS. Signed-off-by: Namhyung Kim Cc: Borislav Petkov Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351241752-2919-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 46 +++++++++------------------------------------- 1 file changed, 9 insertions(+), 37 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index b14eeb86d8d..5cf40cbdaaf 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -977,20 +977,15 @@ help: @echo 'Perf maintainer targets:' @echo ' clean - clean all binary objects and build output' -doc: - $(MAKE) -C Documentation all -man: - $(MAKE) -C Documentation man +DOC_TARGETS := doc man html info pdf -html: - $(MAKE) -C Documentation html +INSTALL_DOC_TARGETS := $(patsubst %,install-%,$(DOC_TARGETS)) try-install-man +INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html -info: - $(MAKE) -C Documentation info - -pdf: - $(MAKE) -C Documentation pdf +# 'make doc' should call 'make -C Documentation all' +$(DOC_TARGETS): + $(MAKE) -C Documentation $(@:doc=all) TAGS: $(RM) TAGS @@ -1061,32 +1056,9 @@ install: all try-install-man install-python_ext: $(PYTHON_WORD) util/setup.py --quiet install --root='/$(DESTDIR_SQ)' -install-doc: - $(MAKE) -C Documentation install - -install-man: - $(MAKE) -C Documentation install-man - -try-install-man: - $(MAKE) -C Documentation try-install-man - -install-html: - $(MAKE) -C Documentation install-html - -install-info: - $(MAKE) -C Documentation install-info - -install-pdf: - $(MAKE) -C Documentation install-pdf - -quick-install-doc: - $(MAKE) -C Documentation quick-install - -quick-install-man: - $(MAKE) -C Documentation quick-install-man - -quick-install-html: - $(MAKE) -C Documentation quick-install-html +# 'make install-doc' should call 'make -C Documentation install' +$(INSTALL_DOC_TARGETS): + $(MAKE) -C Documentation $(@:-doc=) ### Cleaning rules -- cgit v1.2.3 From 615d774d69031357a1bfed57fd383c6fe6f90a69 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 26 Oct 2012 17:55:50 +0900 Subject: perf tools: Convert invocation of MAKE into SUBDIR This will show directory change info in a consistent form. Also it can be converted again into David Howell's descend command. Signed-off-by: Namhyung Kim Cc: Borislav Petkov Cc: David Howells Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351241752-2919-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 5cf40cbdaaf..2d0c09ab58b 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -985,7 +985,7 @@ INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html # 'make doc' should call 'make -C Documentation all' $(DOC_TARGETS): - $(MAKE) -C Documentation $(@:doc=all) + $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:doc=all) TAGS: $(RM) TAGS @@ -1058,7 +1058,7 @@ install-python_ext: # 'make install-doc' should call 'make -C Documentation install' $(INSTALL_DOC_TARGETS): - $(MAKE) -C Documentation $(@:-doc=) + $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:-doc=) ### Cleaning rules @@ -1066,7 +1066,7 @@ clean: $(LIBTRACEEVENT)-clean $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) $(RM) $(ALL_PROGRAMS) perf $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* - $(MAKE) -C Documentation/ clean + $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(RM) $(OUTPUT)util/*-bison* $(RM) $(OUTPUT)util/*-flex* -- cgit v1.2.3 From cf3aa103555136c04894058152b129c133ebf350 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 26 Oct 2012 17:55:51 +0900 Subject: perf tools: Always show CHK message when doing try-cc It might be useful to see what's happening behind us rather than just waiting few seconds during the config checking. Also align the CHK message with other ones. Signed-off-by: Namhyung Kim Cc: Borislav Petkov Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351241752-2919-4-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/config/utilities.mak | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak index ea853c279b3..e5413125e6b 100644 --- a/tools/perf/config/utilities.mak +++ b/tools/perf/config/utilities.mak @@ -183,9 +183,8 @@ _gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) # Usage: option = $(call try-cc, source-to-build, cc-options, msg) ifndef V TRY_CC_OUTPUT= > /dev/null 2>&1 -else -TRY_CC_MSG=echo "CHK $(3)" 1>&2; endif +TRY_CC_MSG=echo " CHK $(3)" 1>&2; try-cc = $(shell sh -c \ 'TMP="$(OUTPUT)$(TMPOUT).$$$$"; \ -- cgit v1.2.3 From fcc328032e7382bf413517ee4dddf1eca7970fe4 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 26 Oct 2012 17:55:52 +0900 Subject: perf tools: Fix LIBELF_MMAP checking Currently checking mmap support in libelf failed due to wrong flags. CHK libelf CHK libdw CHK libunwind CHK -DLIBELF_MMAP /tmp/ccYJwdR0.o: In function `main': :(.text+0x18): undefined reference to `elf_begin' collect2: error: ld returned 1 exit status This cannot happen since we checked the elf_begin() when checking libelf and it succeeded. Fix it by using a same flag with libelf checking. Signed-off-by: Namhyung Kim Cc: Borislav Petkov Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351241752-2919-5-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 2d0c09ab58b..629fc6a4b0d 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -541,7 +541,8 @@ LIB_OBJS += $(OUTPUT)util/symbol-minimal.o else # NO_LIBELF BASIC_CFLAGS += -DLIBELF_SUPPORT -ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON),-DLIBELF_MMAP),y) +FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) +ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y) BASIC_CFLAGS += -DLIBELF_MMAP endif -- cgit v1.2.3 From e558a5bd8b74aff4690a8c55b08a1dc91ef50d7c Mon Sep 17 00:00:00 2001 From: Andrew Vagin Date: Tue, 7 Aug 2012 16:56:02 +0400 Subject: perf inject: Work with files Before this patch "perf inject" can only handle data from pipe. I want to use "perf inject" for reworking events. Look at my following patch. v2: add information about new options in tools/perf/Documentation/ Signed-off-by: Andrew Vagin Acked-by: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1344344165-369636-2-git-send-email-avagin@openvz.org [ committer note: fixed it up to cope with 5852a44, 5ded57a, 002439e & f62d3f0 ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-inject.txt | 6 +++++ tools/perf/builtin-inject.c | 38 +++++++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/tools/perf/Documentation/perf-inject.txt b/tools/perf/Documentation/perf-inject.txt index 025630d43cd..673ef97877f 100644 --- a/tools/perf/Documentation/perf-inject.txt +++ b/tools/perf/Documentation/perf-inject.txt @@ -29,6 +29,12 @@ OPTIONS -v:: --verbose:: Be more verbose. +-i:: +--input=:: + Input file name. (default: stdin) +-o:: +--output=:: + Output file name. (default: stdout) SEE ALSO -------- diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 386a5c0013f..a706ed57f94 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -17,24 +17,30 @@ struct perf_inject { struct perf_tool tool; bool build_ids; + const char *input_name; + int pipe_output, + output; + u64 bytes_written; }; -static int perf_event__repipe_synth(struct perf_tool *tool __maybe_unused, +static int perf_event__repipe_synth(struct perf_tool *tool, union perf_event *event, struct machine *machine __maybe_unused) { + struct perf_inject *inject = container_of(tool, struct perf_inject, tool); uint32_t size; void *buf = event; size = event->header.size; while (size) { - int ret = write(STDOUT_FILENO, buf, size); + int ret = write(inject->output, buf, size); if (ret < 0) return -errno; size -= ret; buf += ret; + inject->bytes_written += ret; } return 0; @@ -231,12 +237,20 @@ static int __cmd_inject(struct perf_inject *inject) inject->tool.tracing_data = perf_event__repipe_tracing_data; } - session = perf_session__new("-", O_RDONLY, false, true, &inject->tool); + session = perf_session__new(inject->input_name, O_RDONLY, false, true, &inject->tool); if (session == NULL) return -ENOMEM; + if (!inject->pipe_output) + lseek(inject->output, session->header.data_offset, SEEK_SET); + ret = perf_session__process_events(session, &inject->tool); + if (!inject->pipe_output) { + session->header.data_size = inject->bytes_written; + perf_session__write_header(session, session->evlist, inject->output, true); + } + perf_session__delete(session); return ret; @@ -260,10 +274,16 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) .tracing_data = perf_event__repipe_tracing_data_synth, .build_id = perf_event__repipe_op2_synth, }, + .input_name = "-", }; + const char *output_name = "-"; const struct option options[] = { OPT_BOOLEAN('b', "build-ids", &inject.build_ids, "Inject build-ids into the output stream"), + OPT_STRING('i', "input", &inject.input_name, "file", + "input file name"), + OPT_STRING('o', "output", &output_name, "file", + "output file name"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show build ids, etc)"), OPT_END() @@ -281,6 +301,18 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) if (argc) usage_with_options(inject_usage, options); + if (!strcmp(output_name, "-")) { + inject.pipe_output = 1; + inject.output = STDOUT_FILENO; + } else { + inject.output = open(output_name, O_CREAT | O_WRONLY | O_TRUNC, + S_IRUSR | S_IWUSR); + if (inject.output < 0) { + perror("failed to create output file"); + return -1; + } + } + if (symbol__init() < 0) return -1; -- cgit v1.2.3 From 26a031e136f4f8dc82c64df48cca0eb3b5d3eb4f Mon Sep 17 00:00:00 2001 From: Andrew Vagin Date: Tue, 7 Aug 2012 16:56:04 +0400 Subject: perf inject: Merge sched_stat_* and sched_switch events You may want to know where and how long a task is sleeping. A callchain may be found in sched_switch and a time slice in stat_iowait, so I add handler in perf inject for merging this events. My code saves sched_switch event for each process and when it meets stat_iowait, it reports the sched_switch event, because this event contains a correct callchain. By another words it replaces all stat_iowait events on proper sched_switch events. I use the next sequence of commands for testing: perf record -e sched:sched_stat_sleep -e sched:sched_switch \ -e sched:sched_process_exit -g -o ~/perf.data.raw \ ~/test-program perf inject -v -s -i ~/perf.data.raw -o ~/perf.data perf report --stdio -i ~/perf.data 100.00% foo [kernel.kallsyms] [k] __schedule | --- __schedule schedule | |--79.75%-- schedule_hrtimeout_range_clock | schedule_hrtimeout_range | poll_schedule_timeout | do_select | core_sys_select | sys_select | system_call_fastpath | __select | __libc_start_main | --20.25%-- do_nanosleep hrtimer_nanosleep sys_nanosleep system_call_fastpath __GI___libc_nanosleep __libc_start_main And here is test-program.c: #include #include #include int main() { struct timespec ts1; struct timeval tv1; int i; long s; for (i = 0; i < 10; i++) { ts1.tv_sec = 0; ts1.tv_nsec = 10000000; nanosleep(&ts1, NULL); tv1.tv_sec = 0; tv1.tv_usec = 40000; select(0, NULL, NULL, NULL,&tv1); } return 1; } Signed-off-by: Andrew Vagin Acked-by: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1344344165-369636-4-git-send-email-avagin@openvz.org [ committer note: Made it use evsel->handler ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-inject.txt | 5 ++ tools/perf/builtin-inject.c | 142 ++++++++++++++++++++++++++++++- 2 files changed, 144 insertions(+), 3 deletions(-) diff --git a/tools/perf/Documentation/perf-inject.txt b/tools/perf/Documentation/perf-inject.txt index 673ef97877f..a00a34276c5 100644 --- a/tools/perf/Documentation/perf-inject.txt +++ b/tools/perf/Documentation/perf-inject.txt @@ -35,6 +35,11 @@ OPTIONS -o:: --output=:: Output file name. (default: stdout) +-s:: +--sched-stat:: + Merge sched_stat and sched_switch for getting events where and how long + tasks slept. sched_switch contains a callchain where a task slept and + sched_stat contains a timeslice how long a task slept. SEE ALSO -------- diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index a706ed57f94..a4a307258fa 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -8,19 +8,32 @@ #include "builtin.h" #include "perf.h" +#include "util/color.h" +#include "util/evlist.h" +#include "util/evsel.h" #include "util/session.h" #include "util/tool.h" #include "util/debug.h" #include "util/parse-options.h" +#include + struct perf_inject { struct perf_tool tool; bool build_ids; + bool sched_stat; const char *input_name; int pipe_output, output; u64 bytes_written; + struct list_head samples; +}; + +struct event_entry { + struct list_head node; + u32 tid; + union perf_event event[0]; }; static int perf_event__repipe_synth(struct perf_tool *tool, @@ -86,12 +99,23 @@ static int perf_event__repipe(struct perf_tool *tool, return perf_event__repipe_synth(tool, event, machine); } +typedef int (*inject_handler)(struct perf_tool *tool, + union perf_event *event, + struct perf_sample *sample, + struct perf_evsel *evsel, + struct machine *machine); + static int perf_event__repipe_sample(struct perf_tool *tool, union perf_event *event, - struct perf_sample *sample __maybe_unused, - struct perf_evsel *evsel __maybe_unused, - struct machine *machine) + struct perf_sample *sample, + struct perf_evsel *evsel, + struct machine *machine) { + if (evsel->handler.func) { + inject_handler f = evsel->handler.func; + return f(tool, event, sample, evsel, machine); + } + return perf_event__repipe_synth(tool, event, machine); } @@ -216,6 +240,79 @@ repipe: return 0; } +static int perf_inject__sched_process_exit(struct perf_tool *tool, + union perf_event *event __maybe_unused, + struct perf_sample *sample, + struct perf_evsel *evsel __maybe_unused, + struct machine *machine __maybe_unused) +{ + struct perf_inject *inject = container_of(tool, struct perf_inject, tool); + struct event_entry *ent; + + list_for_each_entry(ent, &inject->samples, node) { + if (sample->tid == ent->tid) { + list_del_init(&ent->node); + free(ent); + break; + } + } + + return 0; +} + +static int perf_inject__sched_switch(struct perf_tool *tool, + union perf_event *event, + struct perf_sample *sample, + struct perf_evsel *evsel, + struct machine *machine) +{ + struct perf_inject *inject = container_of(tool, struct perf_inject, tool); + struct event_entry *ent; + + perf_inject__sched_process_exit(tool, event, sample, evsel, machine); + + ent = malloc(event->header.size + sizeof(struct event_entry)); + if (ent == NULL) { + color_fprintf(stderr, PERF_COLOR_RED, + "Not enough memory to process sched switch event!"); + return -1; + } + + ent->tid = sample->tid; + memcpy(&ent->event, event, event->header.size); + list_add(&ent->node, &inject->samples); + return 0; +} + +static int perf_inject__sched_stat(struct perf_tool *tool, + union perf_event *event __maybe_unused, + struct perf_sample *sample, + struct perf_evsel *evsel, + struct machine *machine) +{ + struct event_entry *ent; + union perf_event *event_sw; + struct perf_sample sample_sw; + struct perf_inject *inject = container_of(tool, struct perf_inject, tool); + u32 pid = perf_evsel__intval(evsel, sample, "pid"); + + list_for_each_entry(ent, &inject->samples, node) { + if (pid == ent->tid) + goto found; + } + + return 0; +found: + event_sw = &ent->event[0]; + perf_evsel__parse_sample(evsel, event_sw, &sample_sw); + + sample_sw.period = sample->period; + sample_sw.time = sample->time; + perf_event__synthesize_sample(event_sw, evsel->attr.sample_type, + &sample_sw, false); + return perf_event__repipe(tool, event_sw, &sample_sw, machine); +} + extern volatile int session_done; static void sig_handler(int sig __maybe_unused) @@ -223,6 +320,21 @@ static void sig_handler(int sig __maybe_unused) session_done = 1; } +static int perf_evsel__check_stype(struct perf_evsel *evsel, + u64 sample_type, const char *sample_msg) +{ + struct perf_event_attr *attr = &evsel->attr; + const char *name = perf_evsel__name(evsel); + + if (!(attr->sample_type & sample_type)) { + pr_err("Samples for %s event do not have %s attribute set.", + name, sample_msg); + return -EINVAL; + } + + return 0; +} + static int __cmd_inject(struct perf_inject *inject) { struct perf_session *session; @@ -241,6 +353,26 @@ static int __cmd_inject(struct perf_inject *inject) if (session == NULL) return -ENOMEM; + if (inject->sched_stat) { + struct perf_evsel *evsel; + + inject->tool.ordered_samples = true; + + list_for_each_entry(evsel, &session->evlist->entries, node) { + const char *name = perf_evsel__name(evsel); + + if (!strcmp(name, "sched:sched_switch")) { + if (perf_evsel__check_stype(evsel, PERF_SAMPLE_TID, "TID")) + return -EINVAL; + + evsel->handler.func = perf_inject__sched_switch; + } else if (!strcmp(name, "sched:sched_process_exit")) + evsel->handler.func = perf_inject__sched_process_exit; + else if (!strncmp(name, "sched:sched_stat_", 17)) + evsel->handler.func = perf_inject__sched_stat; + } + } + if (!inject->pipe_output) lseek(inject->output, session->header.data_offset, SEEK_SET); @@ -275,6 +407,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) .build_id = perf_event__repipe_op2_synth, }, .input_name = "-", + .samples = LIST_HEAD_INIT(inject.samples), }; const char *output_name = "-"; const struct option options[] = { @@ -284,6 +417,9 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) "input file name"), OPT_STRING('o', "output", &output_name, "file", "output file name"), + OPT_BOOLEAN('s', "sched-stat", &inject.sched_stat, + "Merge sched-stat and sched-switch for getting events " + "where and how long tasks slept"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show build ids, etc)"), OPT_END() -- cgit v1.2.3 From 54a3cf59b53b3f01989a28344ecf4cb68217a6f6 Mon Sep 17 00:00:00 2001 From: Andrew Vagin Date: Tue, 7 Aug 2012 16:56:05 +0400 Subject: perf inject: Mark a dso if it's used Otherwise they will be not written in an output file. Signed-off-by: Andrew Vagin Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1344344165-369636-5-git-send-email-avagin@openvz.org [ committer note: Fixed up wrt changes made in the immediate previous patches ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 11 ++++++++--- tools/perf/util/build-id.c | 10 +++++----- tools/perf/util/build-id.h | 4 ++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index a4a307258fa..84ad6abe425 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -14,6 +14,7 @@ #include "util/session.h" #include "util/tool.h" #include "util/debug.h" +#include "util/build-id.h" #include "util/parse-options.h" @@ -116,6 +117,8 @@ static int perf_event__repipe_sample(struct perf_tool *tool, return f(tool, event, sample, evsel, machine); } + build_id__mark_dso_hit(tool, event, sample, evsel, machine); + return perf_event__repipe_synth(tool, event, machine); } @@ -310,6 +313,7 @@ found: sample_sw.time = sample->time; perf_event__synthesize_sample(event_sw, evsel->attr.sample_type, &sample_sw, false); + build_id__mark_dso_hit(tool, event_sw, &sample_sw, evsel, machine); return perf_event__repipe(tool, event_sw, &sample_sw, machine); } @@ -342,8 +346,7 @@ static int __cmd_inject(struct perf_inject *inject) signal(SIGINT, sig_handler); - if (inject->build_ids) { - inject->tool.sample = perf_event__inject_buildid; + if (inject->build_ids || inject->sched_stat) { inject->tool.mmap = perf_event__repipe_mmap; inject->tool.fork = perf_event__repipe_fork; inject->tool.tracing_data = perf_event__repipe_tracing_data; @@ -353,7 +356,9 @@ static int __cmd_inject(struct perf_inject *inject) if (session == NULL) return -ENOMEM; - if (inject->sched_stat) { + if (inject->build_ids) { + inject->tool.sample = perf_event__inject_buildid; + } else if (inject->sched_stat) { struct perf_evsel *evsel; inject->tool.ordered_samples = true; diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 6a6399955ef..94ca117b8d6 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -16,11 +16,11 @@ #include "session.h" #include "tool.h" -static int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, - union perf_event *event, - struct perf_sample *sample __maybe_unused, - struct perf_evsel *evsel __maybe_unused, - struct machine *machine) +int build_id__mark_dso_hit(struct perf_tool *tool __maybe_unused, + union perf_event *event, + struct perf_sample *sample __maybe_unused, + struct perf_evsel *evsel __maybe_unused, + struct machine *machine) { struct addr_location al; u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index a993ba87d99..45c500bd5b9 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -7,4 +7,8 @@ extern struct perf_tool build_id__mark_dso_hit_ops; char *dso__build_id_filename(struct dso *self, char *bf, size_t size); +int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, + struct perf_sample *sample, struct perf_evsel *evsel, + struct machine *machine); + #endif -- cgit v1.2.3 From 1f16c5754d3a4008c29f3bf67b4f1271313ba385 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 23 Oct 2012 13:40:14 +0200 Subject: perf stat: Add --pre and --post command In order to measure kernel builds, one has to do some pre/post cleanup work in order to do the repeat build. So provide --pre and --post command hooks to allow doing just that. perf stat --repeat 10 --null --sync --pre 'make -s O=defconfig-build/clean' \ -- make -s -j64 O=defconfig-build/ bzImage Signed-off-by: Peter Zijlstra Acked-by: Ingo Molnar Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1350992414.13456.5.camel@twins [ committer note: Added respective entries in Documentation/perf-stat.txt ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-stat.txt | 5 ++++ tools/perf/builtin-stat.c | 42 +++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index 2fa173b5197..cf0c3107e06 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -108,6 +108,11 @@ with it. --append may be used here. Examples: 3>results perf stat --log-fd 3 -- $cmd 3>>results perf stat --log-fd 3 --append -- $cmd +--pre:: +--post:: + Pre and post measurement hooks, e.g.: + +perf stat --repeat 10 --null --sync --pre 'make -s O=defconfig-build/clean' -- make -s -j64 O=defconfig-build/ bzImage EXAMPLES diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 93b9011fa3e..6888960ef8b 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -57,6 +57,7 @@ #include "util/thread.h" #include "util/thread_map.h" +#include #include #include @@ -83,6 +84,9 @@ static const char *csv_sep = NULL; static bool csv_output = false; static bool group = false; static FILE *output = NULL; +static const char *pre_cmd = NULL; +static const char *post_cmd = NULL; +static bool sync_run = false; static volatile int done = 0; @@ -265,7 +269,7 @@ static int read_counter(struct perf_evsel *counter) return 0; } -static int run_perf_stat(int argc __maybe_unused, const char **argv) +static int __run_perf_stat(int argc __maybe_unused, const char **argv) { unsigned long long t0, t1; struct perf_evsel *counter, *first; @@ -405,6 +409,32 @@ static int run_perf_stat(int argc __maybe_unused, const char **argv) return WEXITSTATUS(status); } +static int run_perf_stat(int argc __maybe_unused, const char **argv) +{ + int ret; + + if (pre_cmd) { + ret = system(pre_cmd); + if (ret) + return ret; + } + + if (sync_run) + sync(); + + ret = __run_perf_stat(argc, argv); + if (ret) + return ret; + + if (post_cmd) { + ret = system(post_cmd); + if (ret) + return ret; + } + + return ret; +} + static void print_noise_pct(double total, double avg) { double pct = rel_stddev_stats(total, avg); @@ -1069,8 +1099,7 @@ static int add_default_attributes(void) int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) { - bool append_file = false, - sync_run = false; + bool append_file = false; int output_fd = 0; const char *output_name = NULL; const struct option options[] = { @@ -1114,6 +1143,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) OPT_BOOLEAN(0, "append", &append_file, "append to the output file"), OPT_INTEGER(0, "log-fd", &output_fd, "log output to fd, instead of stderr"), + OPT_STRING(0, "pre", &pre_cmd, "command", + "command to run prior to the measured command"), + OPT_STRING(0, "post", &post_cmd, "command", + "command to run after to the measured command"), OPT_END() }; const char * const stat_usage[] = { @@ -1238,9 +1271,6 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) fprintf(output, "[ perf stat: executing run #%d ... ]\n", run_idx + 1); - if (sync_run) - sync(); - status = run_perf_stat(argc, argv); } -- cgit v1.2.3 From a28ad42a4a0c6f302f488f26488b8b37c9b30024 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Tue, 9 Oct 2012 16:20:15 +0300 Subject: UBIFS: fix mounting problems after power cuts This is a bugfix for a problem with the following symptoms: 1. A power cut happens 2. After reboot, we try to mount UBIFS 3. Mount fails with "No space left on device" error message UBIFS complains like this: UBIFS error (pid 28225): grab_empty_leb: could not find an empty LEB The root cause of this problem is that when we mount, not all LEBs are categorized. Only those which were read are. However, the 'ubifs_find_free_leb_for_idx()' function assumes that all LEBs were categorized and 'c->freeable_cnt' is valid, which is a false assumption. This patch fixes the problem by teaching 'ubifs_find_free_leb_for_idx()' to always fall back to LPT scanning if no freeable LEBs were found. This problem was reported by few people in the past, but Brent Taylor was able to reproduce it and send me a flash image which cannot be mounted, which made it easy to hunt the bug. Kudos to Brent. Reported-by: Brent Taylor Signed-off-by: Artem Bityutskiy Cc: stable@vger.kernel.org --- fs/ubifs/find.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c index 28ec13af28d..2dcf3d473fe 100644 --- a/fs/ubifs/find.c +++ b/fs/ubifs/find.c @@ -681,8 +681,16 @@ int ubifs_find_free_leb_for_idx(struct ubifs_info *c) if (!lprops) { lprops = ubifs_fast_find_freeable(c); if (!lprops) { - ubifs_assert(c->freeable_cnt == 0); - if (c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { + /* + * The first condition means the following: go scan the + * LPT if there are uncategorized lprops, which means + * there may be freeable LEBs there (UBIFS does not + * store the information about freeable LEBs in the + * master node). + */ + if (c->in_a_category_cnt != c->main_lebs || + c->lst.empty_lebs - c->lst.taken_empty_lebs > 0) { + ubifs_assert(c->freeable_cnt == 0); lprops = scan_for_leb_for_idx(c); if (IS_ERR(lprops)) { err = PTR_ERR(lprops); -- cgit v1.2.3 From cd2112220b6b0a35fa12ba988a0dd837515dfaf8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 26 Oct 2012 09:03:21 -0700 Subject: Staging: remove rts_pstor driver Support for this hardware is now included in a "real" driver in the kernel, so it is safe to remove the staging driver now. Cc: wwang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/rts_pstor/Kconfig | 16 - drivers/staging/rts_pstor/Makefile | 16 - drivers/staging/rts_pstor/TODO | 9 - drivers/staging/rts_pstor/debug.h | 43 - drivers/staging/rts_pstor/general.c | 35 - drivers/staging/rts_pstor/general.h | 31 - drivers/staging/rts_pstor/ms.c | 4051 ------------------------ drivers/staging/rts_pstor/ms.h | 225 -- drivers/staging/rts_pstor/rtsx.c | 1105 ------- drivers/staging/rts_pstor/rtsx.h | 186 -- drivers/staging/rts_pstor/rtsx_card.c | 1233 -------- drivers/staging/rts_pstor/rtsx_card.h | 1093 ------- drivers/staging/rts_pstor/rtsx_chip.c | 2264 -------------- drivers/staging/rts_pstor/rtsx_chip.h | 989 ------ drivers/staging/rts_pstor/rtsx_scsi.c | 3137 ------------------- drivers/staging/rts_pstor/rtsx_scsi.h | 142 - drivers/staging/rts_pstor/rtsx_sys.h | 50 - drivers/staging/rts_pstor/rtsx_transport.c | 769 ----- drivers/staging/rts_pstor/rtsx_transport.h | 66 - drivers/staging/rts_pstor/sd.c | 4570 ---------------------------- drivers/staging/rts_pstor/sd.h | 300 -- drivers/staging/rts_pstor/spi.c | 812 ----- drivers/staging/rts_pstor/spi.h | 65 - drivers/staging/rts_pstor/trace.h | 93 - drivers/staging/rts_pstor/xd.c | 2052 ------------- drivers/staging/rts_pstor/xd.h | 188 -- 28 files changed, 23543 deletions(-) delete mode 100644 drivers/staging/rts_pstor/Kconfig delete mode 100644 drivers/staging/rts_pstor/Makefile delete mode 100644 drivers/staging/rts_pstor/TODO delete mode 100644 drivers/staging/rts_pstor/debug.h delete mode 100644 drivers/staging/rts_pstor/general.c delete mode 100644 drivers/staging/rts_pstor/general.h delete mode 100644 drivers/staging/rts_pstor/ms.c delete mode 100644 drivers/staging/rts_pstor/ms.h delete mode 100644 drivers/staging/rts_pstor/rtsx.c delete mode 100644 drivers/staging/rts_pstor/rtsx.h delete mode 100644 drivers/staging/rts_pstor/rtsx_card.c delete mode 100644 drivers/staging/rts_pstor/rtsx_card.h delete mode 100644 drivers/staging/rts_pstor/rtsx_chip.c delete mode 100644 drivers/staging/rts_pstor/rtsx_chip.h delete mode 100644 drivers/staging/rts_pstor/rtsx_scsi.c delete mode 100644 drivers/staging/rts_pstor/rtsx_scsi.h delete mode 100644 drivers/staging/rts_pstor/rtsx_sys.h delete mode 100644 drivers/staging/rts_pstor/rtsx_transport.c delete mode 100644 drivers/staging/rts_pstor/rtsx_transport.h delete mode 100644 drivers/staging/rts_pstor/sd.c delete mode 100644 drivers/staging/rts_pstor/sd.h delete mode 100644 drivers/staging/rts_pstor/spi.c delete mode 100644 drivers/staging/rts_pstor/spi.h delete mode 100644 drivers/staging/rts_pstor/trace.h delete mode 100644 drivers/staging/rts_pstor/xd.c delete mode 100644 drivers/staging/rts_pstor/xd.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index d805eef1191..8b4566e776e 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -52,8 +52,6 @@ source "drivers/staging/rtl8192e/Kconfig" source "drivers/staging/rtl8712/Kconfig" -source "drivers/staging/rts_pstor/Kconfig" - source "drivers/staging/rts5139/Kconfig" source "drivers/staging/frontier/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 76e2ebd596f..72e8014c6d1 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_R8187SE) += rtl8187se/ obj-$(CONFIG_RTL8192U) += rtl8192u/ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_R8712U) += rtl8712/ -obj-$(CONFIG_RTS_PSTOR) += rts_pstor/ obj-$(CONFIG_RTS5139) += rts5139/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_IDE_PHISON) += phison/ diff --git a/drivers/staging/rts_pstor/Kconfig b/drivers/staging/rts_pstor/Kconfig deleted file mode 100644 index 4d66a99fba8..00000000000 --- a/drivers/staging/rts_pstor/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -config RTS_PSTOR - tristate "RealTek PCI-E Card Reader support" - depends on PCI && SCSI - help - Say Y here to include driver code to support the Realtek - PCI-E card readers. - - If this driver is compiled as a module, it will be named rts_pstor. - -config RTS_PSTOR_DEBUG - bool "Realtek PCI-E Card Reader verbose debug" - depends on RTS_PSTOR - help - Say Y here in order to have the rts_pstor code generate - verbose debugging messages. - diff --git a/drivers/staging/rts_pstor/Makefile b/drivers/staging/rts_pstor/Makefile deleted file mode 100644 index 42533d39c07..00000000000 --- a/drivers/staging/rts_pstor/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -ccflags := -Idrivers/scsi - -obj-$(CONFIG_RTS_PSTOR) := rts_pstor.o - -rts_pstor-y := \ - rtsx.o \ - rtsx_chip.o \ - rtsx_transport.o \ - rtsx_scsi.o \ - rtsx_card.o \ - general.o \ - sd.o \ - xd.o \ - ms.o \ - spi.o - diff --git a/drivers/staging/rts_pstor/TODO b/drivers/staging/rts_pstor/TODO deleted file mode 100644 index becb95e4f2c..00000000000 --- a/drivers/staging/rts_pstor/TODO +++ /dev/null @@ -1,9 +0,0 @@ -TODO: -- support more pcie card reader of Realtek family -- use kernel coding style -- checkpatch.pl fixes -- stop having thousands of lines of code duplicated with staging/rts5139 -- This driver contains an entire SD/MMC stack -- it should use the stack in - drivers/mmc instead, as a host driver e.g. drivers/mmc/host/realtek-pci.c; - see drivers/mmc/host/via-sdmmc.c as an example. -- This driver presents cards as SCSI devices, but they should be MMC devices. diff --git a/drivers/staging/rts_pstor/debug.h b/drivers/staging/rts_pstor/debug.h deleted file mode 100644 index ab305be96fb..00000000000 --- a/drivers/staging/rts_pstor/debug.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __REALTEK_RTSX_DEBUG_H -#define __REALTEK_RTSX_DEBUG_H - -#include - -#define RTSX_STOR "rts_pstor: " - -#ifdef CONFIG_RTS_PSTOR_DEBUG -#define RTSX_DEBUGP(x...) printk(KERN_DEBUG RTSX_STOR x) -#define RTSX_DEBUGPN(x...) printk(KERN_DEBUG x) -#define RTSX_DEBUGPX(x...) printk(x) -#define RTSX_DEBUG(x) x -#else -#define RTSX_DEBUGP(x...) -#define RTSX_DEBUGPN(x...) -#define RTSX_DEBUGPX(x...) -#define RTSX_DEBUG(x) -#endif - -#endif /* __REALTEK_RTSX_DEBUG_H */ diff --git a/drivers/staging/rts_pstor/general.c b/drivers/staging/rts_pstor/general.c deleted file mode 100644 index 056e98d2475..00000000000 --- a/drivers/staging/rts_pstor/general.c +++ /dev/null @@ -1,35 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include "general.h" - -int bit1cnt_long(u32 data) -{ - int i, cnt = 0; - for (i = 0; i < 32; i++) { - if (data & 0x01) - cnt++; - data >>= 1; - } - return cnt; -} - diff --git a/drivers/staging/rts_pstor/general.h b/drivers/staging/rts_pstor/general.h deleted file mode 100644 index f17930d2e0c..00000000000 --- a/drivers/staging/rts_pstor/general.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTSX_GENERAL_H -#define __RTSX_GENERAL_H - -#include "rtsx.h" - -int bit1cnt_long(u32 data); - -#endif /* __RTSX_GENERAL_H */ diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c deleted file mode 100644 index 16a5c16fb6a..00000000000 --- a/drivers/staging/rts_pstor/ms.c +++ /dev/null @@ -1,4051 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include - -#include "rtsx.h" -#include "rtsx_transport.h" -#include "rtsx_scsi.h" -#include "rtsx_card.h" -#include "ms.h" - -static inline void ms_set_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct ms_info *ms_card = &(chip->ms_card); - - ms_card->err_code = err_code; -} - -static inline int ms_check_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct ms_info *ms_card = &(chip->ms_card); - - return (ms_card->err_code == err_code); -} - -static int ms_parse_err_code(struct rtsx_chip *chip) -{ - TRACE_RET(chip, STATUS_FAIL); -} - -static int ms_transfer_tpc(struct rtsx_chip *chip, u8 trans_mode, u8 tpc, u8 cnt, u8 cfg) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u8 *ptr; - - RTSX_DEBUGP("ms_transfer_tpc: tpc = 0x%x\n", tpc); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | trans_mode); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_add_cmd(chip, READ_REG_CMD, MS_TRANS_CFG, 0, 0); - - retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval < 0) { - rtsx_clear_ms_error(chip); - ms_set_err_code(chip, MS_TO_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - - ptr = rtsx_get_cmd_data(chip) + 1; - - if (!(tpc & 0x08)) { /* Read Packet */ - if (*ptr & MS_CRC16_ERR) { - ms_set_err_code(chip, MS_CRC16_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - } else { /* Write Packet */ - if (CHK_MSPRO(ms_card) && !(*ptr & 0x80)) { - if (*ptr & (MS_INT_ERR | MS_INT_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - } - } - - if (*ptr & MS_RDY_TIMEOUT) { - rtsx_clear_ms_error(chip); - ms_set_err_code(chip, MS_TO_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - - return STATUS_SUCCESS; -} - -static int ms_transfer_data(struct rtsx_chip *chip, u8 trans_mode, u8 tpc, u16 sec_cnt, - u8 cfg, int mode_2k, int use_sg, void *buf, int buf_len) -{ - int retval; - u8 val, err_code = 0; - enum dma_data_direction dir; - - if (!buf || !buf_len) - TRACE_RET(chip, STATUS_FAIL); - - if (trans_mode == MS_TM_AUTO_READ) { - dir = DMA_FROM_DEVICE; - err_code = MS_FLASH_READ_ERROR; - } else if (trans_mode == MS_TM_AUTO_WRITE) { - dir = DMA_TO_DEVICE; - err_code = MS_FLASH_WRITE_ERROR; - } else { - TRACE_RET(chip, STATUS_FAIL); - } - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_add_cmd(chip, WRITE_REG_CMD, - MS_SECTOR_CNT_H, 0xFF, (u8)(sec_cnt >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, (u8)sec_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - - if (mode_2k) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - MS_CFG, MS_2K_SECTOR_MODE, MS_2K_SECTOR_MODE); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE, 0); - } - - trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, - MS_TRANSFER, 0xFF, MS_TRANSFER_START | trans_mode); - rtsx_add_cmd(chip, CHECK_REG_CMD, - MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, MS_CARD, buf, buf_len, - use_sg, dir, chip->mspro_timeout); - if (retval < 0) { - ms_set_err_code(chip, err_code); - if (retval == -ETIMEDOUT) - retval = STATUS_TIMEDOUT; - else - retval = STATUS_FAIL; - - TRACE_RET(chip, retval); - } - - RTSX_READ_REG(chip, MS_TRANS_CFG, &val); - if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int ms_write_bytes(struct rtsx_chip *chip, - u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - - if (!data || (data_len < cnt)) - TRACE_RET(chip, STATUS_ERROR); - - rtsx_init_cmd(chip); - - for (i = 0; i < cnt; i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - PPBUF_BASE2 + i, 0xFF, data[i]); - } - if (cnt % 2) - rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, 0xFF); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, - MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES); - rtsx_add_cmd(chip, CHECK_REG_CMD, - MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); - - retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval < 0) { - u8 val = 0; - - rtsx_read_register(chip, MS_TRANS_CFG, &val); - RTSX_DEBUGP("MS_TRANS_CFG: 0x%02x\n", val); - - rtsx_clear_ms_error(chip); - - if (!(tpc & 0x08)) { - if (val & MS_CRC16_ERR) { - ms_set_err_code(chip, MS_CRC16_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - } else { - if (CHK_MSPRO(ms_card) && !(val & 0x80)) { - if (val & (MS_INT_ERR | MS_INT_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - } - } - - if (val & MS_RDY_TIMEOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - - ms_set_err_code(chip, MS_TO_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - - return STATUS_SUCCESS; -} - -static int ms_read_bytes(struct rtsx_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *data, int data_len) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - u8 *ptr; - - if (!data) - TRACE_RET(chip, STATUS_ERROR); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, MS_TRANSFER_START | MS_TM_READ_BYTES); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); - - for (i = 0; i < data_len - 1; i++) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0); - - if (data_len % 2) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len, 0, 0); - else - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len - 1, 0, 0); - - retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval < 0) { - u8 val = 0; - - rtsx_read_register(chip, MS_TRANS_CFG, &val); - rtsx_clear_ms_error(chip); - - if (!(tpc & 0x08)) { - if (val & MS_CRC16_ERR) { - ms_set_err_code(chip, MS_CRC16_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - } else { - if (CHK_MSPRO(ms_card) && !(val & 0x80)) { - if (val & (MS_INT_ERR | MS_INT_CMDNK)) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - } - } - - if (val & MS_RDY_TIMEOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - - ms_set_err_code(chip, MS_TO_ERROR); - TRACE_RET(chip, ms_parse_err_code(chip)); - } - - ptr = rtsx_get_cmd_data(chip) + 1; - - for (i = 0; i < data_len; i++) - data[i] = ptr[i]; - - if ((tpc == PRO_READ_SHORT_DATA) && (data_len == 8)) { - RTSX_DEBUGP("Read format progress:\n"); - RTSX_DUMP(ptr, cnt); - } - - return STATUS_SUCCESS; -} - -static int ms_set_rw_reg_addr(struct rtsx_chip *chip, - u8 read_start, u8 read_cnt, u8 write_start, u8 write_cnt) -{ - int retval, i; - u8 data[4]; - - data[0] = read_start; - data[1] = read_cnt; - data[2] = write_start; - data[3] = write_cnt; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, SET_RW_REG_ADRS, 4, - NO_WAIT_INT, data, 4); - if (retval == STATUS_SUCCESS) - return STATUS_SUCCESS; - rtsx_clear_ms_error(chip); - } - - TRACE_RET(chip, STATUS_FAIL); -} - -static int ms_send_cmd(struct rtsx_chip *chip, u8 cmd, u8 cfg) -{ - u8 data[2]; - - data[0] = cmd; - data[1] = 0; - - return ms_write_bytes(chip, PRO_SET_CMD, 1, cfg, data, 1); -} - -static int ms_set_init_para(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - - if (CHK_HG8BIT(ms_card)) { - if (chip->asic_code) - ms_card->ms_clock = chip->asic_ms_hg_clk; - else - ms_card->ms_clock = chip->fpga_ms_hg_clk; - - } else if (CHK_MSPRO(ms_card) || CHK_MS4BIT(ms_card)) { - if (chip->asic_code) - ms_card->ms_clock = chip->asic_ms_4bit_clk; - else - ms_card->ms_clock = chip->fpga_ms_4bit_clk; - - } else { - if (chip->asic_code) - ms_card->ms_clock = chip->asic_ms_1bit_clk; - else - ms_card->ms_clock = chip->fpga_ms_1bit_clk; - } - - retval = switch_clock(chip, ms_card->ms_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int ms_switch_clock(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - - retval = select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = switch_clock(chip, ms_card->ms_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int ms_pull_ctl_disable(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5209)) { - RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, 0x15); - } else if (CHECK_PID(chip, 0x5208)) { - RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, - MS_D1_PD | MS_D2_PD | MS_CLK_PD | MS_D6_PD); - RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, - MS_D3_PD | MS_D0_PD | MS_BS_PD | XD_D4_PD); - RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, - MS_D7_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); - RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD); - RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); - RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B); - RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69); - } - } - - return STATUS_SUCCESS; -} - -static int ms_pull_ctl_enable(struct rtsx_chip *chip) -{ - int retval; - - rtsx_init_cmd(chip); - - if (CHECK_PID(chip, 0x5209)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x15); - } else if (CHECK_PID(chip, 0x5208)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - MS_D1_PD | MS_D2_PD | MS_CLK_NP | MS_D6_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - MS_D3_PD | MS_D0_PD | MS_BS_NP | XD_D4_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - MS_D7_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, - MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_PULL_CTL1, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_PULL_CTL2, 0xFF, 0x45); - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_PULL_CTL3, 0xFF, 0x4B); - rtsx_add_cmd(chip, WRITE_REG_CMD, - CARD_PULL_CTL4, 0xFF, 0x29); - } - } - - retval = rtsx_send_cmd(chip, MS_CARD, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int ms_prepare_reset(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u8 oc_mask = 0; - - ms_card->ms_type = 0; - ms_card->check_ms_flow = 0; - ms_card->switch_8bit_fail = 0; - ms_card->delay_write.delay_write_flag = 0; - - ms_card->pro_under_formatting = 0; - - retval = ms_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (!chip->ft2_fast_mode) - wait_timeout(250); - - retval = enable_card_clock(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (chip->asic_code) { - retval = ms_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_MS_PULL_CTL_BIT | 0x20, 0); - } - - if (!chip->ft2_fast_mode) { - retval = card_power_on(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - wait_timeout(150); - -#ifdef SUPPORT_OCP - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - oc_mask = MS_OC_NOW | MS_OC_EVER; - else - oc_mask = SD_OC_NOW | SD_OC_EVER; - - if (chip->ocp_stat & oc_mask) { - RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", - chip->ocp_stat); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - } - - RTSX_WRITE_REG(chip, CARD_OE, MS_OUTPUT_EN, MS_OUTPUT_EN); - - if (chip->asic_code) { - RTSX_WRITE_REG(chip, MS_CFG, 0xFF, - SAMPLE_TIME_RISING | PUSH_TIME_DEFAULT | - NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1); - } else { - RTSX_WRITE_REG(chip, MS_CFG, 0xFF, - SAMPLE_TIME_FALLING | PUSH_TIME_DEFAULT | - NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1); - } - RTSX_WRITE_REG(chip, MS_TRANS_CFG, 0xFF, NO_WAIT_INT | NO_AUTO_READ_INT_REG); - RTSX_WRITE_REG(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR); - - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int ms_identify_media_type(struct rtsx_chip *chip, int switch_8bit_bus) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - u8 val; - - retval = ms_set_rw_reg_addr(chip, Pro_StatusReg, 6, SystemParm, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, READ_REG, 6, NO_WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_READ_REG(chip, PPBUF_BASE2 + 2, &val); - RTSX_DEBUGP("Type register: 0x%x\n", val); - if (val != 0x01) { - if (val != 0x02) - ms_card->check_ms_flow = 1; - - TRACE_RET(chip, STATUS_FAIL); - } - - RTSX_READ_REG(chip, PPBUF_BASE2 + 4, &val); - RTSX_DEBUGP("Category register: 0x%x\n", val); - if (val != 0) { - ms_card->check_ms_flow = 1; - TRACE_RET(chip, STATUS_FAIL); - } - - RTSX_READ_REG(chip, PPBUF_BASE2 + 5, &val); - RTSX_DEBUGP("Class register: 0x%x\n", val); - if (val == 0) { - RTSX_READ_REG(chip, PPBUF_BASE2, &val); - if (val & WRT_PRTCT) - chip->card_wp |= MS_CARD; - else - chip->card_wp &= ~MS_CARD; - - } else if ((val == 0x01) || (val == 0x02) || (val == 0x03)) { - chip->card_wp |= MS_CARD; - } else { - ms_card->check_ms_flow = 1; - TRACE_RET(chip, STATUS_FAIL); - } - - ms_card->ms_type |= TYPE_MSPRO; - - RTSX_READ_REG(chip, PPBUF_BASE2 + 3, &val); - RTSX_DEBUGP("IF Mode register: 0x%x\n", val); - if (val == 0) { - ms_card->ms_type &= 0x0F; - } else if (val == 7) { - if (switch_8bit_bus) - ms_card->ms_type |= MS_HG; - else - ms_card->ms_type &= 0x0F; - - } else { - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int ms_confirm_cpu_startup(struct rtsx_chip *chip) -{ - int retval, i, k; - u8 val; - - /* Confirm CPU StartUp */ - k = 0; - do { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - - if (k > 100) - TRACE_RET(chip, STATUS_FAIL); - - k++; - wait_timeout(100); - } while (!(val & INT_REG_CED)); - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - - if (val & INT_REG_ERR) { - if (val & INT_REG_CMDNK) - chip->card_wp |= (MS_CARD); - else - TRACE_RET(chip, STATUS_FAIL); - } - /* -- end confirm CPU startup */ - - return STATUS_SUCCESS; -} - -static int ms_switch_parallel_bus(struct rtsx_chip *chip) -{ - int retval, i; - u8 data[2]; - - data[0] = PARALLEL_4BIT_IF; - data[1] = 0; - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT, data, 2); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int ms_switch_8bit_bus(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - u8 data[2]; - - data[0] = PARALLEL_8BIT_IF; - data[1] = 0; - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT, data, 2); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, MS_CFG, 0x98, MS_BUS_WIDTH_8 | SAMPLE_TIME_FALLING); - ms_card->ms_type |= MS_8BIT; - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int ms_pro_reset_flow(struct rtsx_chip *chip, int switch_8bit_bus) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - - for (i = 0; i < 3; i++) { - retval = ms_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_identify_media_type(chip, switch_8bit_bus); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_confirm_cpu_startup(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_switch_parallel_bus(chip); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - continue; - } else { - break; - } - } - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - /* Switch MS-PRO into Parallel mode */ - RTSX_WRITE_REG(chip, MS_CFG, 0x18, MS_BUS_WIDTH_4); - RTSX_WRITE_REG(chip, MS_CFG, PUSH_TIME_ODD, PUSH_TIME_ODD); - - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - /* If MSPro HG Card, We shall try to switch to 8-bit bus */ - if (CHK_MSHG(ms_card) && chip->support_ms_8bit && switch_8bit_bus) { - retval = ms_switch_8bit_bus(chip); - if (retval != STATUS_SUCCESS) { - ms_card->switch_8bit_fail = 1; - TRACE_RET(chip, STATUS_FAIL); - } - } - - return STATUS_SUCCESS; -} - -#ifdef XC_POWERCLASS -static int msxc_change_power(struct rtsx_chip *chip, u8 mode) -{ - int retval; - u8 buf[6]; - - ms_cleanup_work(chip); - - retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - buf[0] = 0; - buf[1] = mode; - buf[2] = 0; - buf[3] = 0; - buf[4] = 0; - buf[5] = 0; - - retval = ms_write_bytes(chip, PRO_WRITE_REG , 6, NO_WAIT_INT, buf, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_send_cmd(chip, XC_CHG_POWER, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_READ_REG(chip, MS_TRANS_CFG, buf); - if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR)) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} -#endif - -static int ms_read_attribute_info(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - u8 val, *buf, class_code, device_type, sub_class, data[16]; - u16 total_blk = 0, blk_size = 0; -#ifdef SUPPORT_MSXC - u32 xc_total_blk = 0, xc_blk_size = 0; -#endif - u32 sys_info_addr = 0, sys_info_size; -#ifdef SUPPORT_PCGL_1P18 - u32 model_name_addr = 0, model_name_size; - int found_sys_info = 0, found_model_name = 0; -#endif - - retval = ms_set_rw_reg_addr(chip, Pro_IntReg, 2, Pro_SystemParm, 7); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHK_MS8BIT(ms_card)) - data[0] = PARALLEL_8BIT_IF; - else - data[0] = PARALLEL_4BIT_IF; - - data[1] = 0; - - data[2] = 0x40; - data[3] = 0; - data[4] = 0; - data[5] = 0; - data[6] = 0; - data[7] = 0; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, PRO_WRITE_REG, 7, NO_WAIT_INT, data, 8); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - buf = kmalloc(64 * 512, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, STATUS_ERROR); - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_send_cmd(chip, PRO_READ_ATRB, WAIT_INT); - if (retval != STATUS_SUCCESS) - continue; - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - if (!(val & MS_INT_BREQ)) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, - 0x40, WAIT_INT, 0, 0, buf, 64 * 512); - if (retval == STATUS_SUCCESS) - break; - else - rtsx_clear_ms_error(chip); - } - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - i = 0; - do { - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - if ((val & MS_INT_CED) || !(val & MS_INT_BREQ)) - break; - - retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, PRO_READ_LONG_DATA, 0, WAIT_INT); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - i++; - } while (i < 1024); - - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - if ((buf[0] != 0xa5) && (buf[1] != 0xc3)) { - /* Signature code is wrong */ - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - if ((buf[4] < 1) || (buf[4] > 12)) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - for (i = 0; i < buf[4]; i++) { - int cur_addr_off = 16 + i * 12; - -#ifdef SUPPORT_MSXC - if ((buf[cur_addr_off + 8] == 0x10) || (buf[cur_addr_off + 8] == 0x13)) -#else - if (buf[cur_addr_off + 8] == 0x10) -#endif - { - sys_info_addr = ((u32)buf[cur_addr_off + 0] << 24) | - ((u32)buf[cur_addr_off + 1] << 16) | - ((u32)buf[cur_addr_off + 2] << 8) | buf[cur_addr_off + 3]; - sys_info_size = ((u32)buf[cur_addr_off + 4] << 24) | - ((u32)buf[cur_addr_off + 5] << 16) | - ((u32)buf[cur_addr_off + 6] << 8) | buf[cur_addr_off + 7]; - RTSX_DEBUGP("sys_info_addr = 0x%x, sys_info_size = 0x%x\n", - sys_info_addr, sys_info_size); - if (sys_info_size != 96) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - if (sys_info_addr < 0x1A0) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - if ((sys_info_size + sys_info_addr) > 0x8000) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - -#ifdef SUPPORT_MSXC - if (buf[cur_addr_off + 8] == 0x13) - ms_card->ms_type |= MS_XC; -#endif -#ifdef SUPPORT_PCGL_1P18 - found_sys_info = 1; -#else - break; -#endif - } -#ifdef SUPPORT_PCGL_1P18 - if (buf[cur_addr_off + 8] == 0x15) { - model_name_addr = ((u32)buf[cur_addr_off + 0] << 24) | - ((u32)buf[cur_addr_off + 1] << 16) | - ((u32)buf[cur_addr_off + 2] << 8) | buf[cur_addr_off + 3]; - model_name_size = ((u32)buf[cur_addr_off + 4] << 24) | - ((u32)buf[cur_addr_off + 5] << 16) | - ((u32)buf[cur_addr_off + 6] << 8) | buf[cur_addr_off + 7]; - RTSX_DEBUGP("model_name_addr = 0x%x, model_name_size = 0x%x\n", - model_name_addr, model_name_size); - if (model_name_size != 48) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - if (model_name_addr < 0x1A0) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - if ((model_name_size + model_name_addr) > 0x8000) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - found_model_name = 1; - } - - if (found_sys_info && found_model_name) - break; -#endif - } - - if (i == buf[4]) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - class_code = buf[sys_info_addr + 0]; - device_type = buf[sys_info_addr + 56]; - sub_class = buf[sys_info_addr + 46]; -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) { - xc_total_blk = ((u32)buf[sys_info_addr + 6] << 24) | - ((u32)buf[sys_info_addr + 7] << 16) | - ((u32)buf[sys_info_addr + 8] << 8) | - buf[sys_info_addr + 9]; - xc_blk_size = ((u32)buf[sys_info_addr + 32] << 24) | - ((u32)buf[sys_info_addr + 33] << 16) | - ((u32)buf[sys_info_addr + 34] << 8) | - buf[sys_info_addr + 35]; - RTSX_DEBUGP("xc_total_blk = 0x%x, xc_blk_size = 0x%x\n", xc_total_blk, xc_blk_size); - } else { - total_blk = ((u16)buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + 7]; - blk_size = ((u16)buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + 3]; - RTSX_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", total_blk, blk_size); - } -#else - total_blk = ((u16)buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + 7]; - blk_size = ((u16)buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + 3]; - RTSX_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", total_blk, blk_size); -#endif - - RTSX_DEBUGP("class_code = 0x%x, device_type = 0x%x, sub_class = 0x%x\n", - class_code, device_type, sub_class); - - memcpy(ms_card->raw_sys_info, buf + sys_info_addr, 96); -#ifdef SUPPORT_PCGL_1P18 - memcpy(ms_card->raw_model_name, buf + model_name_addr, 48); -#endif - - kfree(buf); - -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) { - if (class_code != 0x03) - TRACE_RET(chip, STATUS_FAIL); - } else { - if (class_code != 0x02) - TRACE_RET(chip, STATUS_FAIL); - } -#else - if (class_code != 0x02) - TRACE_RET(chip, STATUS_FAIL); -#endif - - if (device_type != 0x00) { - if ((device_type == 0x01) || (device_type == 0x02) || - (device_type == 0x03)) { - chip->card_wp |= MS_CARD; - } else { - TRACE_RET(chip, STATUS_FAIL); - } - } - - if (sub_class & 0xC0) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_DEBUGP("class_code: 0x%x, device_type: 0x%x, sub_class: 0x%x\n", - class_code, device_type, sub_class); - -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) { - chip->capacity[chip->card2lun[MS_CARD]] = - ms_card->capacity = xc_total_blk * xc_blk_size; - } else { - chip->capacity[chip->card2lun[MS_CARD]] = - ms_card->capacity = total_blk * blk_size; - } -#else - chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity = total_blk * blk_size; -#endif - - return STATUS_SUCCESS; -} - -#ifdef SUPPORT_MAGIC_GATE -static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type, u8 mg_entry_num); -#endif - -static int reset_ms_pro(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; -#ifdef XC_POWERCLASS - u8 change_power_class; - - if (chip->ms_power_class_en & 0x02) - change_power_class = 2; - else if (chip->ms_power_class_en & 0x01) - change_power_class = 1; - else - change_power_class = 0; -#endif - -#ifdef XC_POWERCLASS -Retry: -#endif - retval = ms_pro_reset_flow(chip, 1); - if (retval != STATUS_SUCCESS) { - if (ms_card->switch_8bit_fail) { - retval = ms_pro_reset_flow(chip, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - TRACE_RET(chip, STATUS_FAIL); - } - } - - retval = ms_read_attribute_info(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - -#ifdef XC_POWERCLASS - if (CHK_HG8BIT(ms_card)) - change_power_class = 0; - - if (change_power_class && CHK_MSXC(ms_card)) { - u8 power_class_en = chip->ms_power_class_en; - - RTSX_DEBUGP("power_class_en = 0x%x\n", power_class_en); - RTSX_DEBUGP("change_power_class = %d\n", change_power_class); - - if (change_power_class) - power_class_en &= (1 << (change_power_class - 1)); - else - power_class_en = 0; - - if (power_class_en) { - u8 power_class_mode = (ms_card->raw_sys_info[46] & 0x18) >> 3; - RTSX_DEBUGP("power_class_mode = 0x%x", power_class_mode); - if (change_power_class > power_class_mode) - change_power_class = power_class_mode; - if (change_power_class) { - retval = msxc_change_power(chip, change_power_class); - if (retval != STATUS_SUCCESS) { - change_power_class--; - goto Retry; - } - } - } - } -#endif - -#ifdef SUPPORT_MAGIC_GATE - retval = mg_set_tpc_para_sub(chip, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); -#endif - - if (CHK_HG8BIT(ms_card)) - chip->card_bus_width[chip->card2lun[MS_CARD]] = 8; - else - chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; - - return STATUS_SUCCESS; -} - -static int ms_read_status_reg(struct rtsx_chip *chip) -{ - int retval; - u8 val[2]; - - retval = ms_set_rw_reg_addr(chip, StatusReg0, 2, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_read_bytes(chip, READ_REG, 2, NO_WAIT_INT, val, 2); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (val[1] & (STS_UCDT | STS_UCEX | STS_UCFG)) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - - -static int ms_read_extra_data(struct rtsx_chip *chip, - u16 block_addr, u8 page_num, u8 *buf, int buf_len) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - u8 val, data[10]; - - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHK_MS4BIT(ms_card)) { - /* Parallel interface */ - data[0] = 0x88; - } else { - /* Serial interface */ - data[0] = 0x80; - } - data[1] = 0; - data[2] = (u8)(block_addr >> 8); - data[3] = (u8)block_addr; - data[4] = 0x40; - data[5] = page_num; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - } - - retval = ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT, data, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (buf && buf_len) { - if (buf_len > MS_EXTRA_SIZE) - buf_len = MS_EXTRA_SIZE; - memcpy(buf, data, buf_len); - } - - return STATUS_SUCCESS; -} - -static int ms_write_extra_data(struct rtsx_chip *chip, - u16 block_addr, u8 page_num, u8 *buf, int buf_len) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - u8 val, data[16]; - - if (!buf || (buf_len < MS_EXTRA_SIZE)) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6 + MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(block_addr >> 8); - data[3] = (u8)block_addr; - data[4] = 0x40; - data[5] = page_num; - - for (i = 6; i < MS_EXTRA_SIZE + 6; i++) - data[i] = buf[i - 6]; - - retval = ms_write_bytes(chip, WRITE_REG , (6+MS_EXTRA_SIZE), NO_WAIT_INT, data, 16); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - return STATUS_SUCCESS; -} - - -static int ms_read_page(struct rtsx_chip *chip, u16 block_addr, u8 page_num) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u8 val, data[6]; - - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(block_addr >> 8); - data[3] = (u8)block_addr; - data[4] = 0x20; - data[5] = page_num; - - retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, data, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - - } else { - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, 0, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - - -static int ms_set_bad_block(struct rtsx_chip *chip, u16 phy_blk) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u8 val, data[8], extra[MS_EXTRA_SIZE]; - - retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(phy_blk >> 8); - data[3] = (u8)phy_blk; - data[4] = 0x80; - data[5] = 0; - data[6] = extra[0] & 0x7F; - data[7] = 0xFF; - - retval = ms_write_bytes(chip, WRITE_REG , 7, NO_WAIT_INT, data, 7); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - return STATUS_SUCCESS; -} - - -static int ms_erase_block(struct rtsx_chip *chip, u16 phy_blk) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i = 0; - u8 val, data[6]; - - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(phy_blk >> 8); - data[3] = (u8)phy_blk; - data[4] = 0; - data[5] = 0; - - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - -ERASE_RTY: - retval = ms_send_cmd(chip, BLOCK_ERASE, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (val & INT_REG_CMDNK) { - if (i < 3) { - i++; - goto ERASE_RTY; - } - - ms_set_err_code(chip, MS_CMD_NK); - ms_set_bad_block(chip, phy_blk); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - return STATUS_SUCCESS; -} - - -static void ms_set_page_status(u16 log_blk, u8 type, u8 *extra, int extra_len) -{ - if (!extra || (extra_len < MS_EXTRA_SIZE)) - return; - - memset(extra, 0xFF, MS_EXTRA_SIZE); - - if (type == setPS_NG) { - /* set page status as 1:NG,and block status keep 1:OK */ - extra[0] = 0xB8; - } else { - /* set page status as 0:Data Error,and block status keep 1:OK */ - extra[0] = 0x98; - } - - extra[2] = (u8)(log_blk >> 8); - extra[3] = (u8)log_blk; -} - -static int ms_init_page(struct rtsx_chip *chip, u16 phy_blk, u16 log_blk, u8 start_page, u8 end_page) -{ - int retval; - u8 extra[MS_EXTRA_SIZE], i; - - memset(extra, 0xff, MS_EXTRA_SIZE); - - extra[0] = 0xf8; /* Block, page OK, data erased */ - extra[1] = 0xff; - extra[2] = (u8)(log_blk >> 8); - extra[3] = (u8)log_blk; - - for (i = start_page; i < end_page; i++) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = ms_write_extra_data(chip, phy_blk, i, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int ms_copy_page(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, - u16 log_blk, u8 start_page, u8 end_page) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, rty_cnt, uncorrect_flag = 0; - u8 extra[MS_EXTRA_SIZE], val, i, j, data[16]; - - RTSX_DEBUGP("Copy page from 0x%x to 0x%x, logical block is 0x%x\n", - old_blk, new_blk, log_blk); - RTSX_DEBUGP("start_page = %d, end_page = %d\n", start_page, end_page); - - retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_READ_REG(chip, PPBUF_BASE2, &val); - - if (val & BUF_FULL) { - retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - for (i = start_page; i < end_page; i++) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - ms_read_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE); - - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(old_blk >> 8); - data[3] = (u8)old_blk; - data[4] = 0x20; - data[5] = i; - - retval = ms_write_bytes(chip, WRITE_REG , 6, NO_WAIT_INT, data, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) { - uncorrect_flag = 1; - RTSX_DEBUGP("Uncorrectable error\n"); - } else { - uncorrect_flag = 0; - } - - retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, 0, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (uncorrect_flag) { - ms_set_page_status(log_blk, setPS_NG, extra, MS_EXTRA_SIZE); - if (i == 0) - extra[0] &= 0xEF; - - ms_write_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE); - RTSX_DEBUGP("page %d : extra[0] = 0x%x\n", i, extra[0]); - MS_SET_BAD_BLOCK_FLG(ms_card); - - ms_set_page_status(log_blk, setPS_Error, extra, MS_EXTRA_SIZE); - ms_write_extra_data(chip, new_blk, i, extra, MS_EXTRA_SIZE); - continue; - } - - for (rty_cnt = 0; rty_cnt < MS_MAX_RETRY_COUNT; rty_cnt++) { - retval = ms_transfer_tpc(chip, MS_TM_NORMAL_WRITE, - WRITE_PAGE_DATA, 0, NO_WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (rty_cnt == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - } - - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, - MS_EXTRA_SIZE, SystemParm, (6+MS_EXTRA_SIZE)); - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(new_blk >> 8); - data[3] = (u8)new_blk; - data[4] = 0x20; - data[5] = i; - - if ((extra[0] & 0x60) != 0x60) - data[6] = extra[0]; - else - data[6] = 0xF8; - - data[6 + 1] = 0xFF; - data[6 + 2] = (u8)(log_blk >> 8); - data[6 + 3] = (u8)log_blk; - - for (j = 4; j <= MS_EXTRA_SIZE; j++) - data[6 + j] = 0xFF; - - retval = ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE), NO_WAIT_INT, data, 16); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - if (i == 0) { - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(old_blk >> 8); - data[3] = (u8)old_blk; - data[4] = 0x80; - data[5] = 0; - data[6] = 0xEF; - data[7] = 0xFF; - - retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 8); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CED) { - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - } - - return STATUS_SUCCESS; -} - - -static int reset_ms(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u16 i, reg_addr, block_size; - u8 val, extra[MS_EXTRA_SIZE], j, *ptr; -#ifndef SUPPORT_MAGIC_GATE - u16 eblock_cnt; -#endif - - retval = ms_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_card->ms_type |= TYPE_MS; - - retval = ms_send_cmd(chip, MS_RESET, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_READ_REG(chip, PPBUF_BASE2, &val); - if (val & WRT_PRTCT) - chip->card_wp |= MS_CARD; - else - chip->card_wp &= ~MS_CARD; - - i = 0; - -RE_SEARCH: - /* Search Boot Block */ - while (i < (MAX_DEFECTIVE_BLOCK + 2)) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = ms_read_extra_data(chip, i, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) { - i++; - continue; - } - - if (extra[0] & BLOCK_OK) { - if (!(extra[1] & NOT_BOOT_BLOCK)) { - ms_card->boot_block = i; - break; - } - } - i++; - } - - if (i == (MAX_DEFECTIVE_BLOCK + 2)) { - RTSX_DEBUGP("No boot block found!"); - TRACE_RET(chip, STATUS_FAIL); - } - - for (j = 0; j < 3; j++) { - retval = ms_read_page(chip, ms_card->boot_block, j); - if (retval != STATUS_SUCCESS) { - if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) { - i = ms_card->boot_block + 1; - ms_set_err_code(chip, MS_NO_ERROR); - goto RE_SEARCH; - } - } - } - - retval = ms_read_page(chip, ms_card->boot_block, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - /* Read MS system information as sys_info */ - rtsx_init_cmd(chip); - - for (i = 0; i < 96; i++) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 0x1A0 + i, 0, 0); - - retval = rtsx_send_cmd(chip, MS_CARD, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - ptr = rtsx_get_cmd_data(chip); - memcpy(ms_card->raw_sys_info, ptr, 96); - - /* Read useful block contents */ - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID0, 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, HEADER_ID1, 0, 0); - - for (reg_addr = DISABLED_BLOCK0; reg_addr <= DISABLED_BLOCK3; reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - for (reg_addr = BLOCK_SIZE_0; reg_addr <= PAGE_SIZE_1; reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - rtsx_add_cmd(chip, READ_REG_CMD, MS_Device_Type, 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, MS_4bit_Support, 0, 0); - - retval = rtsx_send_cmd(chip, MS_CARD, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - ptr = rtsx_get_cmd_data(chip); - - RTSX_DEBUGP("Boot block data:\n"); - RTSX_DUMP(ptr, 16); - - /* Block ID error - * HEADER_ID0, HEADER_ID1 - */ - if (ptr[0] != 0x00 || ptr[1] != 0x01) { - i = ms_card->boot_block + 1; - goto RE_SEARCH; - } - - /* Page size error - * PAGE_SIZE_0, PAGE_SIZE_1 - */ - if (ptr[12] != 0x02 || ptr[13] != 0x00) { - i = ms_card->boot_block + 1; - goto RE_SEARCH; - } - - if ((ptr[14] == 1) || (ptr[14] == 3)) - chip->card_wp |= MS_CARD; - - /* BLOCK_SIZE_0, BLOCK_SIZE_1 */ - block_size = ((u16)ptr[6] << 8) | ptr[7]; - if (block_size == 0x0010) { - /* Block size 16KB */ - ms_card->block_shift = 5; - ms_card->page_off = 0x1F; - } else if (block_size == 0x0008) { - /* Block size 8KB */ - ms_card->block_shift = 4; - ms_card->page_off = 0x0F; - } - - /* BLOCK_COUNT_0, BLOCK_COUNT_1 */ - ms_card->total_block = ((u16)ptr[8] << 8) | ptr[9]; - -#ifdef SUPPORT_MAGIC_GATE - j = ptr[10]; - - if (ms_card->block_shift == 4) { /* 4MB or 8MB */ - if (j < 2) { /* Effective block for 4MB: 0x1F0 */ - ms_card->capacity = 0x1EE0; - } else { /* Effective block for 8MB: 0x3E0 */ - ms_card->capacity = 0x3DE0; - } - } else { /* 16MB, 32MB, 64MB or 128MB */ - if (j < 5) { /* Effective block for 16MB: 0x3E0 */ - ms_card->capacity = 0x7BC0; - } else if (j < 0xA) { /* Effective block for 32MB: 0x7C0 */ - ms_card->capacity = 0xF7C0; - } else if (j < 0x11) { /* Effective block for 64MB: 0xF80 */ - ms_card->capacity = 0x1EF80; - } else { /* Effective block for 128MB: 0x1F00 */ - ms_card->capacity = 0x3DF00; - } - } -#else - /* EBLOCK_COUNT_0, EBLOCK_COUNT_1 */ - eblock_cnt = ((u16)ptr[10] << 8) | ptr[11]; - - ms_card->capacity = ((u32)eblock_cnt - 2) << ms_card->block_shift; -#endif - - chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity; - - /* Switch I/F Mode */ - if (ptr[15]) { - retval = ms_set_rw_reg_addr(chip, 0, 0, SystemParm, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, PPBUF_BASE2, 0xFF, 0x88); - RTSX_WRITE_REG(chip, PPBUF_BASE2 + 1, 0xFF, 0); - - retval = ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG , 1, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, MS_CFG, 0x58 | MS_NO_CHECK_INT, - MS_BUS_WIDTH_4 | PUSH_TIME_ODD | MS_NO_CHECK_INT); - - ms_card->ms_type |= MS_4BIT; - } - - if (CHK_MS4BIT(ms_card)) - chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; - else - chip->card_bus_width[chip->card2lun[MS_CARD]] = 1; - - return STATUS_SUCCESS; -} - -static int ms_init_l2p_tbl(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int size, i, seg_no, retval; - u16 defect_block, reg_addr; - u8 val1, val2; - - ms_card->segment_cnt = ms_card->total_block >> 9; - RTSX_DEBUGP("ms_card->segment_cnt = %d\n", ms_card->segment_cnt); - - size = ms_card->segment_cnt * sizeof(struct zone_entry); - ms_card->segment = vzalloc(size); - if (ms_card->segment == NULL) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_read_page(chip, ms_card->boot_block, 1); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, INIT_FAIL); - - reg_addr = PPBUF_BASE2; - for (i = 0; i < (((ms_card->total_block >> 9) * 10) + 1); i++) { - retval = rtsx_read_register(chip, reg_addr++, &val1); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, INIT_FAIL); - - retval = rtsx_read_register(chip, reg_addr++, &val2); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, INIT_FAIL); - - defect_block = ((u16)val1 << 8) | val2; - if (defect_block == 0xFFFF) - break; - - seg_no = defect_block / 512; - ms_card->segment[seg_no].defect_list[ms_card->segment[seg_no].disable_count++] = defect_block; - } - - for (i = 0; i < ms_card->segment_cnt; i++) { - ms_card->segment[i].build_flag = 0; - ms_card->segment[i].l2p_table = NULL; - ms_card->segment[i].free_table = NULL; - ms_card->segment[i].get_index = 0; - ms_card->segment[i].set_index = 0; - ms_card->segment[i].unused_blk_cnt = 0; - - RTSX_DEBUGP("defective block count of segment %d is %d\n", - i, ms_card->segment[i].disable_count); - } - - return STATUS_SUCCESS; - -INIT_FAIL: - if (ms_card->segment) { - vfree(ms_card->segment); - ms_card->segment = NULL; - } - - return STATUS_FAIL; -} - -static u16 ms_get_l2p_tbl(struct rtsx_chip *chip, int seg_no, u16 log_off) -{ - struct ms_info *ms_card = &(chip->ms_card); - struct zone_entry *segment; - - if (ms_card->segment == NULL) - return 0xFFFF; - - segment = &(ms_card->segment[seg_no]); - - if (segment->l2p_table) - return segment->l2p_table[log_off]; - - return 0xFFFF; -} - -static void ms_set_l2p_tbl(struct rtsx_chip *chip, int seg_no, u16 log_off, u16 phy_blk) -{ - struct ms_info *ms_card = &(chip->ms_card); - struct zone_entry *segment; - - if (ms_card->segment == NULL) - return; - - segment = &(ms_card->segment[seg_no]); - if (segment->l2p_table) - segment->l2p_table[log_off] = phy_blk; -} - -static void ms_set_unused_block(struct rtsx_chip *chip, u16 phy_blk) -{ - struct ms_info *ms_card = &(chip->ms_card); - struct zone_entry *segment; - int seg_no; - - seg_no = (int)phy_blk >> 9; - segment = &(ms_card->segment[seg_no]); - - segment->free_table[segment->set_index++] = phy_blk; - if (segment->set_index >= MS_FREE_TABLE_CNT) - segment->set_index = 0; - - segment->unused_blk_cnt++; -} - -static u16 ms_get_unused_block(struct rtsx_chip *chip, int seg_no) -{ - struct ms_info *ms_card = &(chip->ms_card); - struct zone_entry *segment; - u16 phy_blk; - - segment = &(ms_card->segment[seg_no]); - - if (segment->unused_blk_cnt <= 0) - return 0xFFFF; - - phy_blk = segment->free_table[segment->get_index]; - segment->free_table[segment->get_index++] = 0xFFFF; - if (segment->get_index >= MS_FREE_TABLE_CNT) - segment->get_index = 0; - - segment->unused_blk_cnt--; - - return phy_blk; -} - -static const unsigned short ms_start_idx[] = {0, 494, 990, 1486, 1982, 2478, 2974, 3470, - 3966, 4462, 4958, 5454, 5950, 6446, 6942, 7438, 7934}; - -static int ms_arbitrate_l2p(struct rtsx_chip *chip, u16 phy_blk, u16 log_off, u8 us1, u8 us2) -{ - struct ms_info *ms_card = &(chip->ms_card); - struct zone_entry *segment; - int seg_no; - u16 tmp_blk; - - seg_no = (int)phy_blk >> 9; - segment = &(ms_card->segment[seg_no]); - tmp_blk = segment->l2p_table[log_off]; - - if (us1 != us2) { - if (us1 == 0) { - if (!(chip->card_wp & MS_CARD)) - ms_erase_block(chip, tmp_blk); - - ms_set_unused_block(chip, tmp_blk); - segment->l2p_table[log_off] = phy_blk; - } else { - if (!(chip->card_wp & MS_CARD)) - ms_erase_block(chip, phy_blk); - - ms_set_unused_block(chip, phy_blk); - } - } else { - if (phy_blk < tmp_blk) { - if (!(chip->card_wp & MS_CARD)) - ms_erase_block(chip, phy_blk); - - ms_set_unused_block(chip, phy_blk); - } else { - if (!(chip->card_wp & MS_CARD)) - ms_erase_block(chip, tmp_blk); - - ms_set_unused_block(chip, tmp_blk); - segment->l2p_table[log_off] = phy_blk; - } - } - - return STATUS_SUCCESS; -} - -static int ms_build_l2p_tbl(struct rtsx_chip *chip, int seg_no) -{ - struct ms_info *ms_card = &(chip->ms_card); - struct zone_entry *segment; - int retval, table_size, disable_cnt, defect_flag, i; - u16 start, end, phy_blk, log_blk, tmp_blk; - u8 extra[MS_EXTRA_SIZE], us1, us2; - - RTSX_DEBUGP("ms_build_l2p_tbl: %d\n", seg_no); - - if (ms_card->segment == NULL) { - retval = ms_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } - - if (ms_card->segment[seg_no].build_flag) { - RTSX_DEBUGP("l2p table of segment %d has been built\n", seg_no); - return STATUS_SUCCESS; - } - - if (seg_no == 0) - table_size = 494; - else - table_size = 496; - - segment = &(ms_card->segment[seg_no]); - - if (segment->l2p_table == NULL) { - segment->l2p_table = (u16 *)vmalloc(table_size * 2); - if (segment->l2p_table == NULL) - TRACE_GOTO(chip, BUILD_FAIL); - } - memset((u8 *)(segment->l2p_table), 0xff, table_size * 2); - - if (segment->free_table == NULL) { - segment->free_table = (u16 *)vmalloc(MS_FREE_TABLE_CNT * 2); - if (segment->free_table == NULL) - TRACE_GOTO(chip, BUILD_FAIL); - } - memset((u8 *)(segment->free_table), 0xff, MS_FREE_TABLE_CNT * 2); - - start = (u16)seg_no << 9; - end = (u16)(seg_no + 1) << 9; - - disable_cnt = segment->disable_count; - - segment->get_index = segment->set_index = 0; - segment->unused_blk_cnt = 0; - - for (phy_blk = start; phy_blk < end; phy_blk++) { - if (disable_cnt) { - defect_flag = 0; - for (i = 0; i < segment->disable_count; i++) { - if (phy_blk == segment->defect_list[i]) { - defect_flag = 1; - break; - } - } - if (defect_flag) { - disable_cnt--; - continue; - } - } - - retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) { - RTSX_DEBUGP("read extra data fail\n"); - ms_set_bad_block(chip, phy_blk); - continue; - } - - if (seg_no == ms_card->segment_cnt - 1) { - if (!(extra[1] & NOT_TRANSLATION_TABLE)) { - if (!(chip->card_wp & MS_CARD)) { - retval = ms_erase_block(chip, phy_blk); - if (retval != STATUS_SUCCESS) - continue; - extra[2] = 0xff; - extra[3] = 0xff; - } - } - } - - if (!(extra[0] & BLOCK_OK)) - continue; - if (!(extra[1] & NOT_BOOT_BLOCK)) - continue; - if ((extra[0] & PAGE_OK) != PAGE_OK) - continue; - - log_blk = ((u16)extra[2] << 8) | extra[3]; - - if (log_blk == 0xFFFF) { - if (!(chip->card_wp & MS_CARD)) { - retval = ms_erase_block(chip, phy_blk); - if (retval != STATUS_SUCCESS) - continue; - } - ms_set_unused_block(chip, phy_blk); - continue; - } - - if ((log_blk < ms_start_idx[seg_no]) || - (log_blk >= ms_start_idx[seg_no+1])) { - if (!(chip->card_wp & MS_CARD)) { - retval = ms_erase_block(chip, phy_blk); - if (retval != STATUS_SUCCESS) - continue; - } - ms_set_unused_block(chip, phy_blk); - continue; - } - - if (segment->l2p_table[log_blk - ms_start_idx[seg_no]] == 0xFFFF) { - segment->l2p_table[log_blk - ms_start_idx[seg_no]] = phy_blk; - continue; - } - - us1 = extra[0] & 0x10; - tmp_blk = segment->l2p_table[log_blk - ms_start_idx[seg_no]]; - retval = ms_read_extra_data(chip, tmp_blk, 0, extra, MS_EXTRA_SIZE); - if (retval != STATUS_SUCCESS) - continue; - us2 = extra[0] & 0x10; - - (void)ms_arbitrate_l2p(chip, phy_blk, log_blk-ms_start_idx[seg_no], us1, us2); - continue; - } - - segment->build_flag = 1; - - RTSX_DEBUGP("unused block count: %d\n", segment->unused_blk_cnt); - - /* Logical Address Confirmation Process */ - if (seg_no == ms_card->segment_cnt - 1) { - if (segment->unused_blk_cnt < 2) - chip->card_wp |= MS_CARD; - } else { - if (segment->unused_blk_cnt < 1) - chip->card_wp |= MS_CARD; - } - - if (chip->card_wp & MS_CARD) - return STATUS_SUCCESS; - - for (log_blk = ms_start_idx[seg_no]; log_blk < ms_start_idx[seg_no + 1]; log_blk++) { - if (segment->l2p_table[log_blk-ms_start_idx[seg_no]] == 0xFFFF) { - phy_blk = ms_get_unused_block(chip, seg_no); - if (phy_blk == 0xFFFF) { - chip->card_wp |= MS_CARD; - return STATUS_SUCCESS; - } - retval = ms_init_page(chip, phy_blk, log_blk, 0, 1); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, BUILD_FAIL); - - segment->l2p_table[log_blk-ms_start_idx[seg_no]] = phy_blk; - if (seg_no == ms_card->segment_cnt - 1) { - if (segment->unused_blk_cnt < 2) { - chip->card_wp |= MS_CARD; - return STATUS_SUCCESS; - } - } else { - if (segment->unused_blk_cnt < 1) { - chip->card_wp |= MS_CARD; - return STATUS_SUCCESS; - } - } - } - } - - /* Make boot block be the first normal block */ - if (seg_no == 0) { - for (log_blk = 0; log_blk < 494; log_blk++) { - tmp_blk = segment->l2p_table[log_blk]; - if (tmp_blk < ms_card->boot_block) { - RTSX_DEBUGP("Boot block is not the first normal block.\n"); - - if (chip->card_wp & MS_CARD) - break; - - phy_blk = ms_get_unused_block(chip, 0); - retval = ms_copy_page(chip, tmp_blk, phy_blk, - log_blk, 0, ms_card->page_off + 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - segment->l2p_table[log_blk] = phy_blk; - - retval = ms_set_bad_block(chip, tmp_blk); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - return STATUS_SUCCESS; - -BUILD_FAIL: - segment->build_flag = 0; - if (segment->l2p_table) { - vfree(segment->l2p_table); - segment->l2p_table = NULL; - } - if (segment->free_table) { - vfree(segment->free_table); - segment->free_table = NULL; - } - - return STATUS_FAIL; -} - - -int reset_ms_card(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - - memset(ms_card, 0, sizeof(struct ms_info)); - - retval = enable_card_clock(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = select_card(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_card->ms_type = 0; - - retval = reset_ms_pro(chip); - if (retval != STATUS_SUCCESS) { - if (ms_card->check_ms_flow) { - retval = reset_ms(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - TRACE_RET(chip, STATUS_FAIL); - } - } - - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (!CHK_MSPRO(ms_card)) { - /* Build table for the last segment, - * to check if L2P table block exists, erasing it - */ - retval = ms_build_l2p_tbl(chip, ms_card->total_block / 512 - 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - RTSX_DEBUGP("ms_card->ms_type = 0x%x\n", ms_card->ms_type); - - return STATUS_SUCCESS; -} - -static int mspro_set_rw_cmd(struct rtsx_chip *chip, u32 start_sec, u16 sec_cnt, u8 cmd) -{ - int retval, i; - u8 data[8]; - - data[0] = cmd; - data[1] = (u8)(sec_cnt >> 8); - data[2] = (u8)sec_cnt; - data[3] = (u8)(start_sec >> 24); - data[4] = (u8)(start_sec >> 16); - data[5] = (u8)(start_sec >> 8); - data[6] = (u8)start_sec; - data[7] = 0; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, WAIT_INT, data, 8); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - - -void mspro_stop_seq_mode(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - - RTSX_DEBUGP("--%s--\n", __func__); - - if (ms_card->seq_mode) { - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return; - - ms_card->seq_mode = 0; - ms_card->total_sec_cnt = 0; - ms_send_cmd(chip, PRO_STOP, WAIT_INT); - - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - } -} - -static inline int ms_auto_tune_clock(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - - RTSX_DEBUGP("--%s--\n", __func__); - - if (chip->asic_code) { - if (ms_card->ms_clock > 30) - ms_card->ms_clock -= 20; - } else { - if (ms_card->ms_clock == CLK_80) - ms_card->ms_clock = CLK_60; - else if (ms_card->ms_clock == CLK_60) - ms_card->ms_clock = CLK_40; - } - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int mspro_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, mode_2k = 0; - u16 count; - u8 val, trans_mode, rw_tpc, rw_cmd; - - ms_set_err_code(chip, MS_NO_ERROR); - - ms_card->cleanup_counter = 0; - - if (CHK_MSHG(ms_card)) { - if ((start_sector % 4) || (sector_cnt % 4)) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rw_tpc = PRO_READ_LONG_DATA; - rw_cmd = PRO_READ_DATA; - } else { - rw_tpc = PRO_WRITE_LONG_DATA; - rw_cmd = PRO_WRITE_DATA; - } - } else { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rw_tpc = PRO_READ_QUAD_DATA; - rw_cmd = PRO_READ_2K_DATA; - } else { - rw_tpc = PRO_WRITE_QUAD_DATA; - rw_cmd = PRO_WRITE_2K_DATA; - } - mode_2k = 1; - } - } else { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rw_tpc = PRO_READ_LONG_DATA; - rw_cmd = PRO_READ_DATA; - } else { - rw_tpc = PRO_WRITE_LONG_DATA; - rw_cmd = PRO_WRITE_DATA; - } - } - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (srb->sc_data_direction == DMA_FROM_DEVICE) - trans_mode = MS_TM_AUTO_READ; - else - trans_mode = MS_TM_AUTO_WRITE; - - RTSX_READ_REG(chip, MS_TRANS_CFG, &val); - - if (ms_card->seq_mode) { - if ((ms_card->pre_dir != srb->sc_data_direction) - || ((ms_card->pre_sec_addr + ms_card->pre_sec_cnt) != start_sector) - || (mode_2k && (ms_card->seq_mode & MODE_512_SEQ)) - || (!mode_2k && (ms_card->seq_mode & MODE_2K_SEQ)) - || !(val & MS_INT_BREQ) - || ((ms_card->total_sec_cnt + sector_cnt) > 0xFE00)) { - ms_card->seq_mode = 0; - ms_card->total_sec_cnt = 0; - if (val & MS_INT_BREQ) { - retval = ms_send_cmd(chip, PRO_STOP, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - } - } - } - - if (!ms_card->seq_mode) { - ms_card->total_sec_cnt = 0; - if (sector_cnt >= SEQ_START_CRITERIA) { - if ((ms_card->capacity - start_sector) > 0xFE00) - count = 0xFE00; - else - count = (u16)(ms_card->capacity - start_sector); - - if (count > sector_cnt) { - if (mode_2k) - ms_card->seq_mode |= MODE_2K_SEQ; - else - ms_card->seq_mode |= MODE_512_SEQ; - } - } else { - count = sector_cnt; - } - retval = mspro_set_rw_cmd(chip, start_sector, count, rw_cmd); - if (retval != STATUS_SUCCESS) { - ms_card->seq_mode = 0; - TRACE_RET(chip, STATUS_FAIL); - } - } - - retval = ms_transfer_data(chip, trans_mode, rw_tpc, sector_cnt, WAIT_INT, mode_2k, - scsi_sg_count(srb), scsi_sglist(srb), scsi_bufflen(srb)); - if (retval != STATUS_SUCCESS) { - ms_card->seq_mode = 0; - rtsx_read_register(chip, MS_TRANS_CFG, &val); - rtsx_clear_ms_error(chip); - - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - chip->rw_need_retry = 0; - RTSX_DEBUGP("No card exist, exit mspro_rw_multi_sector\n"); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & MS_INT_BREQ) - ms_send_cmd(chip, PRO_STOP, WAIT_INT); - - if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { - RTSX_DEBUGP("MSPro CRC error, tune clock!\n"); - chip->rw_need_retry = 1; - ms_auto_tune_clock(chip); - } - - TRACE_RET(chip, retval); - } - - if (ms_card->seq_mode) { - ms_card->pre_sec_addr = start_sector; - ms_card->pre_sec_cnt = sector_cnt; - ms_card->pre_dir = srb->sc_data_direction; - ms_card->total_sec_cnt += sector_cnt; - } - - return STATUS_SUCCESS; -} - -static int mspro_read_format_progress(struct rtsx_chip *chip, const int short_data_len) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - u32 total_progress, cur_progress; - u8 cnt, tmp; - u8 data[8]; - - RTSX_DEBUGP("mspro_read_format_progress, short_data_len = %d\n", short_data_len); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - TRACE_RET(chip, STATUS_FAIL); - } - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - TRACE_RET(chip, STATUS_FAIL); - } - - if (!(tmp & MS_INT_BREQ)) { - if ((tmp & (MS_INT_CED | MS_INT_BREQ | MS_INT_CMDNK | MS_INT_ERR)) == MS_INT_CED) { - ms_card->format_status = FORMAT_SUCCESS; - return STATUS_SUCCESS; - } - ms_card->format_status = FORMAT_FAIL; - TRACE_RET(chip, STATUS_FAIL); - } - - if (short_data_len >= 256) - cnt = 0; - else - cnt = (u8)short_data_len; - - retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, MS_NO_CHECK_INT); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - TRACE_RET(chip, STATUS_FAIL); - } - - retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, cnt, WAIT_INT, data, 8); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - TRACE_RET(chip, STATUS_FAIL); - } - - total_progress = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; - cur_progress = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]; - - RTSX_DEBUGP("total_progress = %d, cur_progress = %d\n", - total_progress, cur_progress); - - if (total_progress == 0) { - ms_card->progress = 0; - } else { - u64 ulltmp = (u64)cur_progress * (u64)65535; - do_div(ulltmp, total_progress); - ms_card->progress = (u16)ulltmp; - } - RTSX_DEBUGP("progress = %d\n", ms_card->progress); - - for (i = 0; i < 5000; i++) { - retval = rtsx_read_register(chip, MS_TRANS_CFG, &tmp); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - TRACE_RET(chip, STATUS_FAIL); - } - if (tmp & (MS_INT_CED | MS_INT_CMDNK | MS_INT_BREQ | MS_INT_ERR)) - break; - - wait_timeout(1); - } - - retval = rtsx_write_register(chip, MS_CFG, MS_NO_CHECK_INT, 0); - if (retval != STATUS_SUCCESS) { - ms_card->format_status = FORMAT_FAIL; - TRACE_RET(chip, STATUS_FAIL); - } - - if (i == 5000) { - ms_card->format_status = FORMAT_FAIL; - TRACE_RET(chip, STATUS_FAIL); - } - - if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) { - ms_card->format_status = FORMAT_FAIL; - TRACE_RET(chip, STATUS_FAIL); - } - - if (tmp & MS_INT_CED) { - ms_card->format_status = FORMAT_SUCCESS; - ms_card->pro_under_formatting = 0; - } else if (tmp & MS_INT_BREQ) { - ms_card->format_status = FORMAT_IN_PROGRESS; - } else { - ms_card->format_status = FORMAT_FAIL; - ms_card->pro_under_formatting = 0; - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -void mspro_polling_format_status(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int i; - - if (ms_card->pro_under_formatting && (rtsx_get_stat(chip) != RTSX_STAT_SS)) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - - for (i = 0; i < 65535; i++) { - mspro_read_format_progress(chip, MS_SHORT_DATA_LEN); - if (ms_card->format_status != FORMAT_IN_PROGRESS) - break; - } - } - - return; -} - -int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, int short_data_len, int quick_format) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - u8 buf[8], tmp; - u16 para; - - RTSX_DEBUGP("--%s--\n", __func__); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_set_rw_reg_addr(chip, 0x00, 0x00, Pro_TPCParm, 0x01); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - memset(buf, 0, 2); - switch (short_data_len) { - case 32: - buf[0] = 0; - break; - case 64: - buf[0] = 1; - break; - case 128: - buf[0] = 2; - break; - case 256: - default: - buf[0] = 3; - break; - } - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, PRO_WRITE_REG, 1, NO_WAIT_INT, buf, 2); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - - if (quick_format) - para = 0x0000; - else - para = 0x0001; - - retval = mspro_set_rw_cmd(chip, 0, para, PRO_FORMAT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_READ_REG(chip, MS_TRANS_CFG, &tmp); - - if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) - TRACE_RET(chip, STATUS_FAIL); - - if ((tmp & (MS_INT_BREQ | MS_INT_CED)) == MS_INT_BREQ) { - ms_card->pro_under_formatting = 1; - ms_card->progress = 0; - ms_card->format_status = FORMAT_IN_PROGRESS; - return STATUS_SUCCESS; - } - - if (tmp & MS_INT_CED) { - ms_card->pro_under_formatting = 0; - ms_card->progress = 0; - ms_card->format_status = FORMAT_SUCCESS; - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE); - return STATUS_SUCCESS; - } - - TRACE_RET(chip, STATUS_FAIL); -} - - -static int ms_read_multiple_pages(struct rtsx_chip *chip, u16 phy_blk, u16 log_blk, - u8 start_page, u8 end_page, u8 *buf, unsigned int *index, unsigned int *offset) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - u8 extra[MS_EXTRA_SIZE], page_addr, val, trans_cfg, data[6]; - u8 *ptr; - - retval = ms_read_extra_data(chip, phy_blk, start_page, extra, MS_EXTRA_SIZE); - if (retval == STATUS_SUCCESS) { - if ((extra[1] & 0x30) != 0x30) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(phy_blk >> 8); - data[3] = (u8)phy_blk; - data[4] = 0; - data[5] = start_page; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - - retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ptr = buf; - - for (page_addr = start_page; page_addr < end_page; page_addr++) { - ms_set_err_code(chip, MS_NO_ERROR); - - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - if (val & INT_REG_ERR) { - if (val & INT_REG_BREQ) { - retval = ms_read_status_reg(chip); - if (retval != STATUS_SUCCESS) { - if (!(chip->card_wp & MS_CARD)) { - reset_ms(chip); - ms_set_page_status(log_blk, setPS_NG, extra, MS_EXTRA_SIZE); - ms_write_extra_data(chip, phy_blk, - page_addr, extra, MS_EXTRA_SIZE); - } - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } else { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } else { - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - if (page_addr == (end_page - 1)) { - if (!(val & INT_REG_CED)) { - retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_READ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - - trans_cfg = NO_WAIT_INT; - } else { - trans_cfg = WAIT_INT; - } - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, READ_PAGE_DATA); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, trans_cfg); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - - trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_NORMAL_READ); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr, 512, scsi_sg_count(chip->srb), - index, offset, DMA_FROM_DEVICE, chip->ms_timeout); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - ms_set_err_code(chip, MS_TO_ERROR); - rtsx_clear_ms_error(chip); - TRACE_RET(chip, STATUS_TIMEDOUT); - } - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_TO_ERROR); - rtsx_clear_ms_error(chip); - TRACE_RET(chip, STATUS_TIMEDOUT); - } - if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { - ms_set_err_code(chip, MS_CRC16_ERROR); - rtsx_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - } - - if (scsi_sg_count(chip->srb) == 0) - ptr += 512; - } - - return STATUS_SUCCESS; -} - -static int ms_write_multiple_pages(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, - u16 log_blk, u8 start_page, u8 end_page, u8 *buf, - unsigned int *index, unsigned int *offset) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, i; - u8 page_addr, val, data[16]; - u8 *ptr; - - if (!start_page) { - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(old_blk >> 8); - data[3] = (u8)old_blk; - data[4] = 0x80; - data[5] = 0; - data[6] = 0xEF; - data[7] = 0xFF; - - retval = ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 8); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - retval = ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, NO_WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - retval = ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, (6 + MS_EXTRA_SIZE)); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ms_set_err_code(chip, MS_NO_ERROR); - - if (CHK_MS4BIT(ms_card)) - data[0] = 0x88; - else - data[0] = 0x80; - - data[1] = 0; - data[2] = (u8)(new_blk >> 8); - data[3] = (u8)new_blk; - if ((end_page - start_page) == 1) - data[4] = 0x20; - else - data[4] = 0; - - data[5] = start_page; - data[6] = 0xF8; - data[7] = 0xFF; - data[8] = (u8)(log_blk >> 8); - data[9] = (u8)log_blk; - - for (i = 0x0A; i < 0x10; i++) - data[i] = 0xFF; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, WRITE_REG, 6 + MS_EXTRA_SIZE, NO_WAIT_INT, data, 16); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - ptr = buf; - for (page_addr = start_page; page_addr < end_page; page_addr++) { - ms_set_err_code(chip, MS_NO_ERROR); - - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - ms_set_err_code(chip, MS_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - if (val & INT_REG_CMDNK) { - ms_set_err_code(chip, MS_CMD_NK); - TRACE_RET(chip, STATUS_FAIL); - } - if (val & INT_REG_ERR) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - if (!(val & INT_REG_BREQ)) { - ms_set_err_code(chip, MS_BREQ_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - - udelay(30); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, WRITE_PAGE_DATA); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, WAIT_INT); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - - trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_NORMAL_WRITE); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data_partial(chip, MS_CARD, ptr, 512, scsi_sg_count(chip->srb), - index, offset, DMA_TO_DEVICE, chip->ms_timeout); - if (retval < 0) { - ms_set_err_code(chip, MS_TO_ERROR); - rtsx_clear_ms_error(chip); - - if (retval == -ETIMEDOUT) - TRACE_RET(chip, STATUS_TIMEDOUT); - else - TRACE_RET(chip, STATUS_FAIL); - } - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if ((end_page - start_page) == 1) { - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } else { - if (page_addr == (end_page - 1)) { - if (!(val & INT_REG_CED)) { - retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - if ((page_addr == (end_page - 1)) || (page_addr == ms_card->page_off)) { - if (!(val & INT_REG_CED)) { - ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - if (scsi_sg_count(chip->srb) == 0) - ptr += 512; - } - - return STATUS_SUCCESS; -} - - -static int ms_finish_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, - u16 log_blk, u8 page_off) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval, seg_no; - - retval = ms_copy_page(chip, old_blk, new_blk, log_blk, - page_off, ms_card->page_off + 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - seg_no = old_blk >> 9; - - if (MS_TST_BAD_BLOCK_FLG(ms_card)) { - MS_CLR_BAD_BLOCK_FLG(ms_card); - ms_set_bad_block(chip, old_blk); - } else { - retval = ms_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) - ms_set_unused_block(chip, old_blk); - } - - ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk); - - return STATUS_SUCCESS; -} - -static int ms_prepare_write(struct rtsx_chip *chip, u16 old_blk, u16 new_blk, - u16 log_blk, u8 start_page) -{ - int retval; - - if (start_page) { - retval = ms_copy_page(chip, old_blk, new_blk, log_blk, 0, start_page); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -#ifdef MS_DELAY_WRITE -int ms_delay_write(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - struct ms_delay_write_tag *delay_write = &(ms_card->delay_write); - int retval; - - if (delay_write->delay_write_flag) { - retval = ms_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - delay_write->delay_write_flag = 0; - retval = ms_finish_write(chip, - delay_write->old_phyblock, delay_write->new_phyblock, - delay_write->logblock, delay_write->pageoff); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} -#endif - -static inline void ms_rw_fail(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); -} - -static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt) -{ - struct ms_info *ms_card = &(chip->ms_card); - unsigned int lun = SCSI_LUN(srb); - int retval, seg_no; - unsigned int index = 0, offset = 0; - u16 old_blk = 0, new_blk = 0, log_blk, total_sec_cnt = sector_cnt; - u8 start_page, end_page = 0, page_cnt; - u8 *ptr; -#ifdef MS_DELAY_WRITE - struct ms_delay_write_tag *delay_write = &(ms_card->delay_write); -#endif - - ms_set_err_code(chip, MS_NO_ERROR); - - ms_card->cleanup_counter = 0; - - ptr = (u8 *)scsi_sglist(srb); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) { - ms_rw_fail(srb, chip); - TRACE_RET(chip, STATUS_FAIL); - } - - log_blk = (u16)(start_sector >> ms_card->block_shift); - start_page = (u8)(start_sector & ms_card->page_off); - - for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; seg_no++) { - if (log_blk < ms_start_idx[seg_no+1]) - break; - } - - if (ms_card->segment[seg_no].build_flag == 0) { - retval = ms_build_l2p_tbl(chip, seg_no); - if (retval != STATUS_SUCCESS) { - chip->card_fail |= MS_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { -#ifdef MS_DELAY_WRITE - if (delay_write->delay_write_flag && - (delay_write->logblock == log_blk) && - (start_page > delay_write->pageoff)) { - delay_write->delay_write_flag = 0; - retval = ms_copy_page(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, log_blk, - delay_write->pageoff, start_page); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - old_blk = delay_write->old_phyblock; - new_blk = delay_write->new_phyblock; - } else if (delay_write->delay_write_flag && - (delay_write->logblock == log_blk) && - (start_page == delay_write->pageoff)) { - delay_write->delay_write_flag = 0; - old_blk = delay_write->old_phyblock; - new_blk = delay_write->new_phyblock; - } else { - retval = ms_delay_write(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - old_blk = ms_get_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no]); - new_blk = ms_get_unused_block(chip, seg_no); - if ((old_blk == 0xFFFF) || (new_blk == 0xFFFF)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = ms_prepare_write(chip, old_blk, new_blk, log_blk, start_page); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } -#ifdef MS_DELAY_WRITE - } -#endif - } else { -#ifdef MS_DELAY_WRITE - retval = ms_delay_write(chip); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - old_blk = ms_get_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no]); - if (old_blk == 0xFFFF) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", seg_no, old_blk, new_blk); - - while (total_sec_cnt) { - if ((start_page + total_sec_cnt) > (ms_card->page_off + 1)) - end_page = ms_card->page_off + 1; - else - end_page = start_page + (u8)total_sec_cnt; - - page_cnt = end_page - start_page; - - RTSX_DEBUGP("start_page = %d, end_page = %d, page_cnt = %d\n", - start_page, end_page, page_cnt); - - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - retval = ms_read_multiple_pages(chip, - old_blk, log_blk, start_page, end_page, - ptr, &index, &offset); - } else { - retval = ms_write_multiple_pages(chip, old_blk, - new_blk, log_blk, start_page, end_page, - ptr, &index, &offset); - } - - if (retval != STATUS_SUCCESS) { - toggle_gpio(chip, 1); - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - ms_rw_fail(srb, chip); - TRACE_RET(chip, STATUS_FAIL); - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - if (end_page == (ms_card->page_off + 1)) { - retval = ms_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) - ms_set_unused_block(chip, old_blk); - - ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk); - } - } - - total_sec_cnt -= page_cnt; - if (scsi_sg_count(srb) == 0) - ptr += page_cnt * 512; - - if (total_sec_cnt == 0) - break; - - log_blk++; - - for (seg_no = 0; seg_no < ARRAY_SIZE(ms_start_idx) - 1; - seg_no++) { - if (log_blk < ms_start_idx[seg_no+1]) - break; - } - - if (ms_card->segment[seg_no].build_flag == 0) { - retval = ms_build_l2p_tbl(chip, seg_no); - if (retval != STATUS_SUCCESS) { - chip->card_fail |= MS_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - } - - old_blk = ms_get_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no]); - if (old_blk == 0xFFFF) { - ms_rw_fail(srb, chip); - TRACE_RET(chip, STATUS_FAIL); - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - new_blk = ms_get_unused_block(chip, seg_no); - if (new_blk == 0xFFFF) { - ms_rw_fail(srb, chip); - TRACE_RET(chip, STATUS_FAIL); - } - } - - RTSX_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", seg_no, old_blk, new_blk); - - start_page = 0; - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - if (end_page < (ms_card->page_off + 1)) { -#ifdef MS_DELAY_WRITE - delay_write->delay_write_flag = 1; - delay_write->old_phyblock = old_blk; - delay_write->new_phyblock = new_blk; - delay_write->logblock = log_blk; - delay_write->pageoff = end_page; -#else - retval = ms_finish_write(chip, old_blk, new_blk, log_blk, end_page); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, MS_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - - ms_rw_fail(srb, chip); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - } - } - - scsi_set_resid(srb, 0); - - return STATUS_SUCCESS; -} - -int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - - if (CHK_MSPRO(ms_card)) - retval = mspro_rw_multi_sector(srb, chip, start_sector, sector_cnt); - else - retval = ms_rw_multi_sector(srb, chip, start_sector, sector_cnt); - - return retval; -} - - -void ms_free_l2p_tbl(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int i = 0; - - if (ms_card->segment != NULL) { - for (i = 0; i < ms_card->segment_cnt; i++) { - if (ms_card->segment[i].l2p_table != NULL) { - vfree(ms_card->segment[i].l2p_table); - ms_card->segment[i].l2p_table = NULL; - } - if (ms_card->segment[i].free_table != NULL) { - vfree(ms_card->segment[i].free_table); - ms_card->segment[i].free_table = NULL; - } - } - vfree(ms_card->segment); - ms_card->segment = NULL; - } -} - -#ifdef SUPPORT_MAGIC_GATE - -#ifdef READ_BYTES_WAIT_INT -static int ms_poll_int(struct rtsx_chip *chip) -{ - int retval; - u8 val; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANS_CFG, MS_INT_CED, MS_INT_CED); - - retval = rtsx_send_cmd(chip, MS_CARD, 5000); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - val = *rtsx_get_cmd_data(chip); - if (val & MS_INT_ERR) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} -#endif - -#ifdef MS_SAMPLE_INT_ERR -static int check_ms_err(struct rtsx_chip *chip) -{ - int retval; - u8 val; - - retval = rtsx_read_register(chip, MS_TRANSFER, &val); - if (retval != STATUS_SUCCESS) - return 1; - if (val & MS_TRANSFER_ERR) - return 1; - - retval = rtsx_read_register(chip, MS_TRANS_CFG, &val); - if (retval != STATUS_SUCCESS) - return 1; - - if (val & (MS_INT_ERR | MS_INT_CMDNK)) - return 1; - - return 0; -} -#else -static int check_ms_err(struct rtsx_chip *chip) -{ - int retval; - u8 val; - - retval = rtsx_read_register(chip, MS_TRANSFER, &val); - if (retval != STATUS_SUCCESS) - return 1; - if (val & MS_TRANSFER_ERR) - return 1; - - return 0; -} -#endif - -static int mg_send_ex_cmd(struct rtsx_chip *chip, u8 cmd, u8 entry_num) -{ - int retval, i; - u8 data[8]; - - data[0] = cmd; - data[1] = 0; - data[2] = 0; - data[3] = 0; - data[4] = 0; - data[5] = 0; - data[6] = entry_num; - data[7] = 0; - - for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { - retval = ms_write_bytes(chip, PRO_EX_SET_CMD, 7, WAIT_INT, data, 8); - if (retval == STATUS_SUCCESS) - break; - } - if (i == MS_MAX_RETRY_COUNT) - TRACE_RET(chip, STATUS_FAIL); - - if (check_ms_err(chip)) { - rtsx_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int mg_set_tpc_para_sub(struct rtsx_chip *chip, int type, u8 mg_entry_num) -{ - int retval; - u8 buf[6]; - - RTSX_DEBUGP("--%s--\n", __func__); - - if (type == 0) - retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_TPCParm, 1); - else - retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - buf[0] = 0; - buf[1] = 0; - if (type == 1) { - buf[2] = 0; - buf[3] = 0; - buf[4] = 0; - buf[5] = mg_entry_num; - } - retval = ms_write_bytes(chip, PRO_WRITE_REG, (type == 0) ? 1 : 6, NO_WAIT_INT, buf, 6); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - int i; - unsigned int lun = SCSI_LUN(srb); - u8 buf1[32], buf2[12]; - - RTSX_DEBUGP("--%s--\n", __func__); - - if (scsi_bufflen(srb) < 12) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, STATUS_FAIL); - } - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = mg_send_ex_cmd(chip, MG_SET_LID, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - TRACE_RET(chip, STATUS_FAIL); - } - - memset(buf1, 0, 32); - rtsx_stor_get_xfer_buf(buf2, min(12, (int)scsi_bufflen(srb)), srb); - for (i = 0; i < 8; i++) - buf1[8+i] = buf2[4+i]; - - retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf1, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - TRACE_RET(chip, STATUS_FAIL); - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - rtsx_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval = STATUS_FAIL; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 *buf = NULL; - - RTSX_DEBUGP("--%s--\n", __func__); - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - buf = kmalloc(1540, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, STATUS_ERROR); - - buf[0] = 0x04; - buf[1] = 0x1A; - buf[2] = 0x00; - buf[3] = 0x00; - - retval = mg_send_ex_cmd(chip, MG_GET_LEKB, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_GOTO(chip, GetEKBFinish); - } - - retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, - 3, WAIT_INT, 0, 0, buf + 4, 1536); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rtsx_clear_ms_error(chip); - TRACE_GOTO(chip, GetEKBFinish); - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rtsx_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - bufflen = min(1052, (int)scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf, bufflen, srb); - -GetEKBFinish: - kfree(buf); - return retval; -} - -int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - int bufflen; - int i; - unsigned int lun = SCSI_LUN(srb); - u8 buf[32]; - - RTSX_DEBUGP("--%s--\n", __func__); - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = mg_send_ex_cmd(chip, MG_GET_ID, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, STATUS_FAIL); - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - rtsx_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - memcpy(ms_card->magic_gate_id, buf, 16); - -#ifdef READ_BYTES_WAIT_INT - retval = ms_poll_int(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - - retval = mg_send_ex_cmd(chip, MG_SET_RD, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, STATUS_FAIL); - } - - bufflen = min(12, (int)scsi_bufflen(srb)); - rtsx_stor_get_xfer_buf(buf, bufflen, srb); - - for (i = 0; i < 8; i++) - buf[i] = buf[4+i]; - - for (i = 0; i < 24; i++) - buf[8+i] = 0; - - retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, - 32, WAIT_INT, buf, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, STATUS_FAIL); - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - rtsx_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - ms_card->mg_auth = 0; - - return STATUS_SUCCESS; -} - -int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 buf1[32], buf2[36]; - - RTSX_DEBUGP("--%s--\n", __func__); - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf1, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_RET(chip, STATUS_FAIL); - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rtsx_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - buf2[0] = 0x00; - buf2[1] = 0x22; - buf2[2] = 0x00; - buf2[3] = 0x00; - - memcpy(buf2 + 4, ms_card->magic_gate_id, 16); - memcpy(buf2 + 20, buf1, 16); - - bufflen = min(36, (int)scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf2, bufflen, srb); - -#ifdef READ_BYTES_WAIT_INT - retval = ms_poll_int(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - - return STATUS_SUCCESS; -} - -int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - int i; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 buf[32]; - - RTSX_DEBUGP("--%s--\n", __func__); - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_RET(chip, STATUS_FAIL); - } - - bufflen = min(12, (int)scsi_bufflen(srb)); - rtsx_stor_get_xfer_buf(buf, bufflen, srb); - - for (i = 0; i < 8; i++) - buf[i] = buf[4+i]; - - for (i = 0; i < 24; i++) - buf[8+i] = 0; - - retval = ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - TRACE_RET(chip, STATUS_FAIL); - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); - rtsx_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - ms_card->mg_auth = 1; - - return STATUS_SUCCESS; -} - -int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - int bufflen; - unsigned int lun = SCSI_LUN(srb); - u8 *buf = NULL; - - RTSX_DEBUGP("--%s--\n", __func__); - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - buf = kmalloc(1028, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, STATUS_ERROR); - - buf[0] = 0x04; - buf[1] = 0x02; - buf[2] = 0x00; - buf[3] = 0x00; - - retval = mg_send_ex_cmd(chip, MG_GET_IBD, ms_card->mg_entry_num); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_GOTO(chip, GetICVFinish); - } - - retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, - 2, WAIT_INT, 0, 0, buf + 4, 1024); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - rtsx_clear_ms_error(chip); - TRACE_GOTO(chip, GetICVFinish); - } - if (check_ms_err(chip)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - rtsx_clear_ms_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - bufflen = min(1028, (int)scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf, bufflen, srb); - -GetICVFinish: - kfree(buf); - return retval; -} - -int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - int bufflen; -#ifdef MG_SET_ICV_SLOW - int i; -#endif - unsigned int lun = SCSI_LUN(srb); - u8 *buf = NULL; - - RTSX_DEBUGP("--%s--\n", __func__); - - ms_cleanup_work(chip); - - retval = ms_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - buf = kmalloc(1028, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, STATUS_ERROR); - - bufflen = min(1028, (int)scsi_bufflen(srb)); - rtsx_stor_get_xfer_buf(buf, bufflen, srb); - - retval = mg_send_ex_cmd(chip, MG_SET_IBD, ms_card->mg_entry_num); - if (retval != STATUS_SUCCESS) { - if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } else { - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } - TRACE_GOTO(chip, SetICVFinish); - } - -#ifdef MG_SET_ICV_SLOW - for (i = 0; i < 2; i++) { - udelay(50); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, PRO_WRITE_LONG_DATA); - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, WAIT_INT); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - - trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, - MS_TRANSFER_START | MS_TM_NORMAL_WRITE); - rtsx_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, MS_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, MS_CARD, buf + 4 + i*512, 512, 0, DMA_TO_DEVICE, 3000); - if ((retval < 0) || check_ms_err(chip)) { - rtsx_clear_ms_error(chip); - if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } else { - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } - retval = STATUS_FAIL; - TRACE_GOTO(chip, SetICVFinish); - } - } -#else - retval = ms_transfer_data(chip, MS_TM_AUTO_WRITE, PRO_WRITE_LONG_DATA, - 2, WAIT_INT, 0, 0, buf + 4, 1024); - if ((retval != STATUS_SUCCESS) || check_ms_err(chip)) { - rtsx_clear_ms_error(chip); - if (ms_card->mg_auth == 0) { - if ((buf[5] & 0xC0) != 0) - set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); - else - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } else { - set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); - } - TRACE_GOTO(chip, SetICVFinish); - } -#endif - -SetICVFinish: - kfree(buf); - return retval; -} - -#endif /* SUPPORT_MAGIC_GATE */ - -void ms_cleanup_work(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - - if (CHK_MSPRO(ms_card)) { - if (ms_card->seq_mode) { - RTSX_DEBUGP("MS Pro: stop transmission\n"); - mspro_stop_seq_mode(chip); - ms_card->cleanup_counter = 0; - } - if (CHK_MSHG(ms_card)) { - rtsx_write_register(chip, MS_CFG, - MS_2K_SECTOR_MODE, 0x00); - } - } -#ifdef MS_DELAY_WRITE - else if ((!CHK_MSPRO(ms_card)) && ms_card->delay_write.delay_write_flag) { - RTSX_DEBUGP("MS: delay write\n"); - ms_delay_write(chip); - ms_card->cleanup_counter = 0; - } -#endif -} - -int ms_power_off_card3v3(struct rtsx_chip *chip) -{ - int retval; - - retval = disable_card_clock(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (chip->asic_code) { - retval = ms_pull_ctl_disable(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - RTSX_WRITE_REG(chip, FPGA_PULL_CTL, - FPGA_MS_PULL_CTL_BIT | 0x20, FPGA_MS_PULL_CTL_BIT); - } - RTSX_WRITE_REG(chip, CARD_OE, MS_OUTPUT_EN, 0); - if (!chip->ft2_fast_mode) { - retval = card_power_off(chip, MS_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -int release_ms_card(struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - int retval; - - RTSX_DEBUGP("release_ms_card\n"); - -#ifdef MS_DELAY_WRITE - ms_card->delay_write.delay_write_flag = 0; -#endif - ms_card->pro_under_formatting = 0; - - chip->card_ready &= ~MS_CARD; - chip->card_fail &= ~MS_CARD; - chip->card_wp &= ~MS_CARD; - - ms_free_l2p_tbl(chip); - - memset(ms_card->raw_sys_info, 0, 96); -#ifdef SUPPORT_PCGL_1P18 - memset(ms_card->raw_model_name, 0, 48); -#endif - - retval = ms_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - diff --git a/drivers/staging/rts_pstor/ms.h b/drivers/staging/rts_pstor/ms.h deleted file mode 100644 index 53701987613..00000000000 --- a/drivers/staging/rts_pstor/ms.h +++ /dev/null @@ -1,225 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __REALTEK_RTSX_MS_H -#define __REALTEK_RTSX_MS_H - -#define MS_DELAY_WRITE - -#define MS_MAX_RETRY_COUNT 3 - -#define MS_EXTRA_SIZE 0x9 - -#define WRT_PRTCT 0x01 - -/* Error Code */ -#define MS_NO_ERROR 0x00 -#define MS_CRC16_ERROR 0x80 -#define MS_TO_ERROR 0x40 -#define MS_NO_CARD 0x20 -#define MS_NO_MEMORY 0x10 -#define MS_CMD_NK 0x08 -#define MS_FLASH_READ_ERROR 0x04 -#define MS_FLASH_WRITE_ERROR 0x02 -#define MS_BREQ_ERROR 0x01 -#define MS_NOT_FOUND 0x03 - -/* Transfer Protocol Command */ -#define READ_PAGE_DATA 0x02 -#define READ_REG 0x04 -#define GET_INT 0x07 -#define WRITE_PAGE_DATA 0x0D -#define WRITE_REG 0x0B -#define SET_RW_REG_ADRS 0x08 -#define SET_CMD 0x0E - -#define PRO_READ_LONG_DATA 0x02 -#define PRO_READ_SHORT_DATA 0x03 -#define PRO_READ_REG 0x04 -#define PRO_READ_QUAD_DATA 0x05 -#define PRO_GET_INT 0x07 -#define PRO_WRITE_LONG_DATA 0x0D -#define PRO_WRITE_SHORT_DATA 0x0C -#define PRO_WRITE_QUAD_DATA 0x0A -#define PRO_WRITE_REG 0x0B -#define PRO_SET_RW_REG_ADRS 0x08 -#define PRO_SET_CMD 0x0E -#define PRO_EX_SET_CMD 0x09 - -#ifdef SUPPORT_MAGIC_GATE - -#define MG_GET_ID 0x40 -#define MG_SET_LID 0x41 -#define MG_GET_LEKB 0x42 -#define MG_SET_RD 0x43 -#define MG_MAKE_RMS 0x44 -#define MG_MAKE_KSE 0x45 -#define MG_SET_IBD 0x46 -#define MG_GET_IBD 0x47 - -#endif - -#ifdef XC_POWERCLASS -#define XC_CHG_POWER 0x16 -#endif - -#define BLOCK_READ 0xAA -#define BLOCK_WRITE 0x55 -#define BLOCK_END 0x33 -#define BLOCK_ERASE 0x99 -#define FLASH_STOP 0xCC - -#define SLEEP 0x5A -#define CLEAR_BUF 0xC3 -#define MS_RESET 0x3C - -#define PRO_READ_DATA 0x20 -#define PRO_WRITE_DATA 0x21 -#define PRO_READ_ATRB 0x24 -#define PRO_STOP 0x25 -#define PRO_ERASE 0x26 -#define PRO_READ_2K_DATA 0x27 -#define PRO_WRITE_2K_DATA 0x28 - -#define PRO_FORMAT 0x10 -#define PRO_SLEEP 0x11 - -#define IntReg 0x01 -#define StatusReg0 0x02 -#define StatusReg1 0x03 - -#define SystemParm 0x10 -#define BlockAdrs 0x11 -#define CMDParm 0x14 -#define PageAdrs 0x15 - -#define OverwriteFlag 0x16 -#define ManagemenFlag 0x17 -#define LogicalAdrs 0x18 -#define ReserveArea 0x1A - -#define Pro_IntReg 0x01 -#define Pro_StatusReg 0x02 -#define Pro_TypeReg 0x04 -#define Pro_IFModeReg 0x05 -#define Pro_CatagoryReg 0x06 -#define Pro_ClassReg 0x07 - - -#define Pro_SystemParm 0x10 -#define Pro_DataCount1 0x11 -#define Pro_DataCount0 0x12 -#define Pro_DataAddr3 0x13 -#define Pro_DataAddr2 0x14 -#define Pro_DataAddr1 0x15 -#define Pro_DataAddr0 0x16 - -#define Pro_TPCParm 0x17 -#define Pro_CMDParm 0x18 - -#define INT_REG_CED 0x80 -#define INT_REG_ERR 0x40 -#define INT_REG_BREQ 0x20 -#define INT_REG_CMDNK 0x01 - -#define BLOCK_BOOT 0xC0 -#define BLOCK_OK 0x80 -#define PAGE_OK 0x60 -#define DATA_COMPL 0x10 - -#define NOT_BOOT_BLOCK 0x4 -#define NOT_TRANSLATION_TABLE 0x8 - -#define HEADER_ID0 PPBUF_BASE2 -#define HEADER_ID1 (PPBUF_BASE2 + 1) -#define DISABLED_BLOCK0 (PPBUF_BASE2 + 0x170 + 4) -#define DISABLED_BLOCK1 (PPBUF_BASE2 + 0x170 + 5) -#define DISABLED_BLOCK2 (PPBUF_BASE2 + 0x170 + 6) -#define DISABLED_BLOCK3 (PPBUF_BASE2 + 0x170 + 7) -#define BLOCK_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 2) -#define BLOCK_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 3) -#define BLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 4) -#define BLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 5) -#define EBLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 6) -#define EBLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 7) -#define PAGE_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 8) -#define PAGE_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 9) - -#define MS_Device_Type (PPBUF_BASE2 + 0x1D8) - -#define MS_4bit_Support (PPBUF_BASE2 + 0x1D3) - -#define setPS_NG 1 -#define setPS_Error 0 - -#define PARALLEL_8BIT_IF 0x40 -#define PARALLEL_4BIT_IF 0x00 -#define SERIAL_IF 0x80 - -#define BUF_FULL 0x10 -#define BUF_EMPTY 0x20 - -#define MEDIA_BUSY 0x80 -#define FLASH_BUSY 0x40 -#define DATA_ERROR 0x20 -#define STS_UCDT 0x10 -#define EXTRA_ERROR 0x08 -#define STS_UCEX 0x04 -#define FLAG_ERROR 0x02 -#define STS_UCFG 0x01 - -#define MS_SHORT_DATA_LEN 32 - -#define FORMAT_SUCCESS 0 -#define FORMAT_FAIL 1 -#define FORMAT_IN_PROGRESS 2 - -#define MS_SET_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag |= 0x80) -#define MS_CLR_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag &= 0x7F) -#define MS_TST_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag & 0x80) - -void mspro_polling_format_status(struct rtsx_chip *chip); - -void mspro_stop_seq_mode(struct rtsx_chip *chip); -int reset_ms_card(struct rtsx_chip *chip); -int ms_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt); -int mspro_format(struct scsi_cmnd *srb, struct rtsx_chip *chip, int short_data_len, int quick_format); -void ms_free_l2p_tbl(struct rtsx_chip *chip); -void ms_cleanup_work(struct rtsx_chip *chip); -int ms_power_off_card3v3(struct rtsx_chip *chip); -int release_ms_card(struct rtsx_chip *chip); -#ifdef MS_DELAY_WRITE -int ms_delay_write(struct rtsx_chip *chip); -#endif - -#ifdef SUPPORT_MAGIC_GATE -int mg_set_leaf_id(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_get_local_EKB(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_get_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int mg_set_ICV(struct scsi_cmnd *srb, struct rtsx_chip *chip); -#endif - -#endif /* __REALTEK_RTSX_MS_H */ diff --git a/drivers/staging/rts_pstor/rtsx.c b/drivers/staging/rts_pstor/rtsx.c deleted file mode 100644 index afe9c2e763d..00000000000 --- a/drivers/staging/rts_pstor/rtsx.c +++ /dev/null @@ -1,1105 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include - -#include "rtsx.h" -#include "rtsx_chip.h" -#include "rtsx_transport.h" -#include "rtsx_scsi.h" -#include "rtsx_card.h" -#include "general.h" - -#include "ms.h" -#include "sd.h" -#include "xd.h" - -#define DRIVER_VERSION "v1.10" - -MODULE_DESCRIPTION("Realtek PCI-Express card reader driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); - -static unsigned int delay_use = 1; -module_param(delay_use, uint, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); - -static int ss_en; -module_param(ss_en, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(ss_en, "enable selective suspend"); - -static int ss_interval = 50; -module_param(ss_interval, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(ss_interval, "Interval to enter ss state in seconds"); - -static int auto_delink_en; -module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); - -static unsigned char aspm_l0s_l1_en; -module_param(aspm_l0s_l1_en, byte, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(aspm_l0s_l1_en, "enable device aspm"); - -static int msi_en; -module_param(msi_en, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(msi_en, "enable msi"); - -static irqreturn_t rtsx_interrupt(int irq, void *dev_id); - -/*********************************************************************** - * Host functions - ***********************************************************************/ - -static const char *host_info(struct Scsi_Host *host) -{ - return "SCSI emulation for PCI-Express Mass Storage devices"; -} - -static int slave_alloc(struct scsi_device *sdev) -{ - /* - * Set the INQUIRY transfer length to 36. We don't use any of - * the extra data and many devices choke if asked for more or - * less than 36 bytes. - */ - sdev->inquiry_len = 36; - return 0; -} - -static int slave_configure(struct scsi_device *sdev) -{ - /* Scatter-gather buffers (all but the last) must have a length - * divisible by the bulk maxpacket size. Otherwise a data packet - * would end up being short, causing a premature end to the data - * transfer. Since high-speed bulk pipes have a maxpacket size - * of 512, we'll use that as the scsi device queue's DMA alignment - * mask. Guaranteeing proper alignment of the first buffer will - * have the desired effect because, except at the beginning and - * the end, scatter-gather buffers follow page boundaries. */ - blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); - - /* Set the SCSI level to at least 2. We'll leave it at 3 if that's - * what is originally reported. We need this to avoid confusing - * the SCSI layer with devices that report 0 or 1, but need 10-byte - * commands (ala ATAPI devices behind certain bridges, or devices - * which simply have broken INQUIRY data). - * - * NOTE: This means /dev/sg programs (ala cdrecord) will get the - * actual information. This seems to be the preference for - * programs like that. - * - * NOTE: This also means that /proc/scsi/scsi and sysfs may report - * the actual value or the modified one, depending on where the - * data comes from. - */ - if (sdev->scsi_level < SCSI_2) - sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2; - - return 0; -} - - -/*********************************************************************** - * /proc/scsi/ functions - ***********************************************************************/ - -/* we use this macro to help us write into the buffer */ -#undef SPRINTF -#define SPRINTF(args...) \ - do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0) - -static int proc_info(struct Scsi_Host *host, char *buffer, - char **start, off_t offset, int length, int inout) -{ - char *pos = buffer; - - /* if someone is sending us data, just throw it away */ - if (inout) - return length; - - /* print the controller name */ - SPRINTF(" Host scsi%d: %s\n", host->host_no, CR_DRIVER_NAME); - - /* print product, vendor, and driver version strings */ - SPRINTF(" Vendor: Realtek Corp.\n"); - SPRINTF(" Product: PCIE Card Reader\n"); - SPRINTF(" Version: %s\n", DRIVER_VERSION); - - /* - * Calculate start of next buffer, and return value. - */ - *start = buffer + offset; - - if ((pos - buffer) < offset) - return 0; - else if ((pos - buffer - offset) < length) - return pos - buffer - offset; - else - return length; -} - -/* queue a command */ -/* This is always called with scsi_lock(host) held */ -static int queuecommand_lck(struct scsi_cmnd *srb, - void (*done)(struct scsi_cmnd *)) -{ - struct rtsx_dev *dev = host_to_rtsx(srb->device->host); - struct rtsx_chip *chip = dev->chip; - - /* check for state-transition errors */ - if (chip->srb != NULL) { - dev_err(&dev->pci->dev, "Error in %s: chip->srb = %p\n", - __func__, chip->srb); - return SCSI_MLQUEUE_HOST_BUSY; - } - - /* fail the command if we are disconnecting */ - if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - dev_info(&dev->pci->dev, "Fail command during disconnect\n"); - srb->result = DID_NO_CONNECT << 16; - done(srb); - return 0; - } - - /* enqueue the command and wake up the control thread */ - srb->scsi_done = done; - chip->srb = srb; - complete(&dev->cmnd_ready); - - return 0; -} - -static DEF_SCSI_QCMD(queuecommand) - -/*********************************************************************** - * Error handling functions - ***********************************************************************/ - -/* Command timeout and abort */ -static int command_abort(struct scsi_cmnd *srb) -{ - struct Scsi_Host *host = srb->device->host; - struct rtsx_dev *dev = host_to_rtsx(host); - struct rtsx_chip *chip = dev->chip; - - dev_info(&dev->pci->dev, "%s called\n", __func__); - - scsi_lock(host); - - /* Is this command still active? */ - if (chip->srb != srb) { - scsi_unlock(host); - dev_info(&dev->pci->dev, "-- nothing to abort\n"); - return FAILED; - } - - rtsx_set_stat(chip, RTSX_STAT_ABORT); - - scsi_unlock(host); - - /* Wait for the aborted command to finish */ - wait_for_completion(&dev->notify); - - return SUCCESS; -} - -/* This invokes the transport reset mechanism to reset the state of the - * device */ -static int device_reset(struct scsi_cmnd *srb) -{ - int result = 0; - struct rtsx_dev *dev = host_to_rtsx(srb->device->host); - - dev_info(&dev->pci->dev, "%s called\n", __func__); - - return result < 0 ? FAILED : SUCCESS; -} - -/* Simulate a SCSI bus reset by resetting the device's USB port. */ -static int bus_reset(struct scsi_cmnd *srb) -{ - int result = 0; - struct rtsx_dev *dev = host_to_rtsx(srb->device->host); - - dev_info(&dev->pci->dev, "%s called\n", __func__); - - return result < 0 ? FAILED : SUCCESS; -} - - -/* - * this defines our host template, with which we'll allocate hosts - */ - -static struct scsi_host_template rtsx_host_template = { - /* basic userland interface stuff */ - .name = CR_DRIVER_NAME, - .proc_name = CR_DRIVER_NAME, - .proc_info = proc_info, - .info = host_info, - - /* command interface -- queued only */ - .queuecommand = queuecommand, - - /* error and abort handlers */ - .eh_abort_handler = command_abort, - .eh_device_reset_handler = device_reset, - .eh_bus_reset_handler = bus_reset, - - /* queue commands only, only one command per LUN */ - .can_queue = 1, - .cmd_per_lun = 1, - - /* unknown initiator id */ - .this_id = -1, - - .slave_alloc = slave_alloc, - .slave_configure = slave_configure, - - /* lots of sg segments can be handled */ - .sg_tablesize = SG_ALL, - - /* limit the total size of a transfer to 120 KB */ - .max_sectors = 240, - - /* merge commands... this seems to help performance, but - * periodically someone should test to see which setting is more - * optimal. - */ - .use_clustering = 1, - - /* emulated HBA */ - .emulated = 1, - - /* we do our own delay after a device or bus reset */ - .skip_settle_delay = 1, - - /* module management */ - .module = THIS_MODULE -}; - - -static int rtsx_acquire_irq(struct rtsx_dev *dev) -{ - struct rtsx_chip *chip = dev->chip; - - dev_info(&dev->pci->dev, "%s: chip->msi_en = %d, pci->irq = %d\n", - __func__, chip->msi_en, dev->pci->irq); - - if (request_irq(dev->pci->irq, rtsx_interrupt, - chip->msi_en ? 0 : IRQF_SHARED, - CR_DRIVER_NAME, dev)) { - dev_err(&dev->pci->dev, - "rtsx: unable to grab IRQ %d, disabling device\n", - dev->pci->irq); - return -1; - } - - dev->irq = dev->pci->irq; - pci_intx(dev->pci, !chip->msi_en); - - return 0; -} - - -int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val) -{ - struct pci_dev *pdev; - u8 data; - u8 devfn = (dev << 3) | func; - - pdev = pci_get_bus_and_slot(bus, devfn); - if (!pdev) - return -1; - - pci_read_config_byte(pdev, offset, &data); - if (val) - *val = data; - - return 0; -} - -#ifdef CONFIG_PM -/* - * power management - */ -static int rtsx_suspend(struct pci_dev *pci, pm_message_t state) -{ - struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); - struct rtsx_chip *chip; - - if (!dev) - return 0; - - /* lock the device pointers */ - mutex_lock(&(dev->dev_mutex)); - - chip = dev->chip; - - rtsx_do_before_power_down(chip, PM_S3); - - if (dev->irq >= 0) { - synchronize_irq(dev->irq); - free_irq(dev->irq, (void *)dev); - dev->irq = -1; - } - - if (chip->msi_en) - pci_disable_msi(pci); - - pci_save_state(pci); - pci_enable_wake(pci, pci_choose_state(pci, state), 1); - pci_disable_device(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); - - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - - return 0; -} - -static int rtsx_resume(struct pci_dev *pci) -{ - struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); - struct rtsx_chip *chip; - - if (!dev) - return 0; - - chip = dev->chip; - - /* lock the device pointers */ - mutex_lock(&(dev->dev_mutex)); - - pci_set_power_state(pci, PCI_D0); - pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - dev_err(&dev->pci->dev, - "%s: pci_enable_device failed, disabling device\n", - CR_DRIVER_NAME); - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - return -EIO; - } - pci_set_master(pci); - - if (chip->msi_en) { - if (pci_enable_msi(pci) < 0) - chip->msi_en = 0; - } - - if (rtsx_acquire_irq(dev) < 0) { - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - return -EIO; - } - - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 0x00); - rtsx_init_chip(chip); - - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - - return 0; -} -#endif /* CONFIG_PM */ - -static void rtsx_shutdown(struct pci_dev *pci) -{ - struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); - struct rtsx_chip *chip; - - if (!dev) - return; - - chip = dev->chip; - - rtsx_do_before_power_down(chip, PM_S1); - - if (dev->irq >= 0) { - synchronize_irq(dev->irq); - free_irq(dev->irq, (void *)dev); - dev->irq = -1; - } - - if (chip->msi_en) - pci_disable_msi(pci); - - pci_disable_device(pci); - - return; -} - -static int rtsx_control_thread(void *__dev) -{ - struct rtsx_dev *dev = (struct rtsx_dev *)__dev; - struct rtsx_chip *chip = dev->chip; - struct Scsi_Host *host = rtsx_to_host(dev); - - for (;;) { - if (wait_for_completion_interruptible(&dev->cmnd_ready)) - break; - - /* lock the device pointers */ - mutex_lock(&(dev->dev_mutex)); - - /* if the device has disconnected, we are free to exit */ - if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - dev_info(&dev->pci->dev, "-- rtsx-control exiting\n"); - mutex_unlock(&dev->dev_mutex); - break; - } - - /* lock access to the state */ - scsi_lock(host); - - /* has the command aborted ? */ - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { - chip->srb->result = DID_ABORT << 16; - goto SkipForAbort; - } - - scsi_unlock(host); - - /* reject the command if the direction indicator - * is UNKNOWN - */ - if (chip->srb->sc_data_direction == DMA_BIDIRECTIONAL) { - dev_err(&dev->pci->dev, "UNKNOWN data direction\n"); - chip->srb->result = DID_ERROR << 16; - } - - /* reject if target != 0 or if LUN is higher than - * the maximum known LUN - */ - else if (chip->srb->device->id) { - dev_err(&dev->pci->dev, "Bad target number (%d:%d)\n", - chip->srb->device->id, - chip->srb->device->lun); - chip->srb->result = DID_BAD_TARGET << 16; - } - - else if (chip->srb->device->lun > chip->max_lun) { - dev_err(&dev->pci->dev, "Bad LUN (%d:%d)\n", - chip->srb->device->id, - chip->srb->device->lun); - chip->srb->result = DID_BAD_TARGET << 16; - } - - /* we've got a command, let's do it! */ - else { - RTSX_DEBUG(scsi_show_command(chip->srb)); - rtsx_invoke_transport(chip->srb, chip); - } - - /* lock access to the state */ - scsi_lock(host); - - /* did the command already complete because of a disconnect? */ - if (!chip->srb) - ; /* nothing to do */ - - /* indicate that the command is done */ - else if (chip->srb->result != DID_ABORT << 16) { - chip->srb->scsi_done(chip->srb); - } else { -SkipForAbort: - dev_err(&dev->pci->dev, "scsi command aborted\n"); - } - - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { - complete(&(dev->notify)); - - rtsx_set_stat(chip, RTSX_STAT_IDLE); - } - - /* finished working on this command */ - chip->srb = NULL; - scsi_unlock(host); - - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - } /* for (;;) */ - - /* notify the exit routine that we're actually exiting now - * - * complete()/wait_for_completion() is similar to up()/down(), - * except that complete() is safe in the case where the structure - * is getting deleted in a parallel mode of execution (i.e. just - * after the down() -- that's necessary for the thread-shutdown - * case. - * - * complete_and_exit() goes even further than this -- it is safe in - * the case that the thread of the caller is going away (not just - * the structure) -- this is necessary for the module-remove case. - * This is important in preemption kernels, which transfer the flow - * of execution immediately upon a complete(). - */ - complete_and_exit(&dev->control_exit, 0); -} - - -static int rtsx_polling_thread(void *__dev) -{ - struct rtsx_dev *dev = (struct rtsx_dev *)__dev; - struct rtsx_chip *chip = dev->chip; - struct sd_info *sd_card = &(chip->sd_card); - struct xd_info *xd_card = &(chip->xd_card); - struct ms_info *ms_card = &(chip->ms_card); - - sd_card->cleanup_counter = 0; - xd_card->cleanup_counter = 0; - ms_card->cleanup_counter = 0; - - /* Wait until SCSI scan finished */ - wait_timeout((delay_use + 5) * 1000); - - for (;;) { - - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(POLLING_INTERVAL); - - /* lock the device pointers */ - mutex_lock(&(dev->dev_mutex)); - - /* if the device has disconnected, we are free to exit */ - if (rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - dev_info(&dev->pci->dev, "-- rtsx-polling exiting\n"); - mutex_unlock(&dev->dev_mutex); - break; - } - - mutex_unlock(&dev->dev_mutex); - - mspro_polling_format_status(chip); - - /* lock the device pointers */ - mutex_lock(&(dev->dev_mutex)); - - rtsx_polling_func(chip); - - /* unlock the device pointers */ - mutex_unlock(&dev->dev_mutex); - } - - complete_and_exit(&dev->polling_exit, 0); -} - -/* - * interrupt handler - */ -static irqreturn_t rtsx_interrupt(int irq, void *dev_id) -{ - struct rtsx_dev *dev = dev_id; - struct rtsx_chip *chip; - int retval; - u32 status; - - if (dev) - chip = dev->chip; - else - return IRQ_NONE; - - if (!chip) - return IRQ_NONE; - - spin_lock(&dev->reg_lock); - - retval = rtsx_pre_handle_interrupt(chip); - if (retval == STATUS_FAIL) { - spin_unlock(&dev->reg_lock); - if (chip->int_reg == 0xFFFFFFFF) - return IRQ_HANDLED; - else - return IRQ_NONE; - } - - status = chip->int_reg; - - if (dev->check_card_cd) { - if (!(dev->check_card_cd & status)) { - /* card not exist, return TRANS_RESULT_FAIL */ - dev->trans_result = TRANS_RESULT_FAIL; - if (dev->done) - complete(dev->done); - goto Exit; - } - } - - if (status & (NEED_COMPLETE_INT | DELINK_INT)) { - if (status & (TRANS_FAIL_INT | DELINK_INT)) { - if (status & DELINK_INT) - RTSX_SET_DELINK(chip); - dev->trans_result = TRANS_RESULT_FAIL; - if (dev->done) - complete(dev->done); - } else if (status & TRANS_OK_INT) { - dev->trans_result = TRANS_RESULT_OK; - if (dev->done) - complete(dev->done); - } else if (status & DATA_DONE_INT) { - dev->trans_result = TRANS_NOT_READY; - if (dev->done && (dev->trans_state == STATE_TRANS_SG)) - complete(dev->done); - } - } - -Exit: - spin_unlock(&dev->reg_lock); - return IRQ_HANDLED; -} - - -/* Release all our dynamic resources */ -static void rtsx_release_resources(struct rtsx_dev *dev) -{ - dev_info(&dev->pci->dev, "-- %s\n", __func__); - - /* Tell the control thread to exit. The SCSI host must - * already have been removed so it won't try to queue - * any more commands. - */ - dev_info(&dev->pci->dev, "-- sending exit command to thread\n"); - complete(&dev->cmnd_ready); - if (dev->ctl_thread) - wait_for_completion(&dev->control_exit); - if (dev->polling_thread) - wait_for_completion(&dev->polling_exit); - - wait_timeout(200); - - if (dev->rtsx_resv_buf) { - dma_free_coherent(&(dev->pci->dev), RTSX_RESV_BUF_LEN, - dev->rtsx_resv_buf, dev->rtsx_resv_buf_addr); - dev->chip->host_cmds_ptr = NULL; - dev->chip->host_sg_tbl_ptr = NULL; - } - - if (dev->irq > 0) - free_irq(dev->irq, (void *)dev); - if (dev->chip->msi_en) - pci_disable_msi(dev->pci); - if (dev->remap_addr) - iounmap(dev->remap_addr); - - pci_disable_device(dev->pci); - pci_release_regions(dev->pci); - - rtsx_release_chip(dev->chip); - kfree(dev->chip); -} - -/* First stage of disconnect processing: stop all commands and remove - * the host */ -static void quiesce_and_remove_host(struct rtsx_dev *dev) -{ - struct Scsi_Host *host = rtsx_to_host(dev); - struct rtsx_chip *chip = dev->chip; - - /* Prevent new transfers, stop the current command, and - * interrupt a SCSI-scan or device-reset delay */ - mutex_lock(&dev->dev_mutex); - scsi_lock(host); - rtsx_set_stat(chip, RTSX_STAT_DISCONNECT); - scsi_unlock(host); - mutex_unlock(&dev->dev_mutex); - wake_up(&dev->delay_wait); - wait_for_completion(&dev->scanning_done); - - /* Wait some time to let other threads exist */ - wait_timeout(100); - - /* queuecommand won't accept any new commands and the control - * thread won't execute a previously-queued command. If there - * is such a command pending, complete it with an error. */ - mutex_lock(&dev->dev_mutex); - if (chip->srb) { - chip->srb->result = DID_NO_CONNECT << 16; - scsi_lock(host); - chip->srb->scsi_done(dev->chip->srb); - chip->srb = NULL; - scsi_unlock(host); - } - mutex_unlock(&dev->dev_mutex); - - /* Now we own no commands so it's safe to remove the SCSI host */ - scsi_remove_host(host); -} - -/* Second stage of disconnect processing: deallocate all resources */ -static void release_everything(struct rtsx_dev *dev) -{ - rtsx_release_resources(dev); - - /* Drop our reference to the host; the SCSI core will free it - * when the refcount becomes 0. */ - scsi_host_put(rtsx_to_host(dev)); -} - -/* Thread to carry out delayed SCSI-device scanning */ -static int rtsx_scan_thread(void *__dev) -{ - struct rtsx_dev *dev = (struct rtsx_dev *)__dev; - struct rtsx_chip *chip = dev->chip; - - /* Wait for the timeout to expire or for a disconnect */ - if (delay_use > 0) { - dev_info(&dev->pci->dev, - "%s: waiting for device to settle before scanning\n", - CR_DRIVER_NAME); - wait_event_interruptible_timeout(dev->delay_wait, - rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT), - delay_use * HZ); - } - - /* If the device is still connected, perform the scanning */ - if (!rtsx_chk_stat(chip, RTSX_STAT_DISCONNECT)) { - scsi_scan_host(rtsx_to_host(dev)); - dev_info(&dev->pci->dev, "%s: device scan complete\n", - CR_DRIVER_NAME); - - /* Should we unbind if no devices were detected? */ - } - - complete_and_exit(&dev->scanning_done, 0); -} - -static void rtsx_init_options(struct rtsx_chip *chip) -{ - chip->vendor_id = chip->rtsx->pci->vendor; - chip->product_id = chip->rtsx->pci->device; - chip->adma_mode = 1; - chip->lun_mc = 0; - chip->driver_first_load = 1; -#ifdef HW_AUTO_SWITCH_SD_BUS - chip->sdio_in_charge = 0; -#endif - - chip->mspro_formatter_enable = 1; - chip->ignore_sd = 0; - chip->use_hw_setting = 0; - chip->lun_mode = DEFAULT_SINGLE; - chip->auto_delink_en = auto_delink_en; - chip->ss_en = ss_en; - chip->ss_idle_period = ss_interval * 1000; - chip->remote_wakeup_en = 0; - chip->aspm_l0s_l1_en = aspm_l0s_l1_en; - chip->dynamic_aspm = 1; - chip->fpga_sd_sdr104_clk = CLK_200; - chip->fpga_sd_ddr50_clk = CLK_100; - chip->fpga_sd_sdr50_clk = CLK_100; - chip->fpga_sd_hs_clk = CLK_100; - chip->fpga_mmc_52m_clk = CLK_80; - chip->fpga_ms_hg_clk = CLK_80; - chip->fpga_ms_4bit_clk = CLK_80; - chip->fpga_ms_1bit_clk = CLK_40; - chip->asic_sd_sdr104_clk = 203; - chip->asic_sd_sdr50_clk = 98; - chip->asic_sd_ddr50_clk = 98; - chip->asic_sd_hs_clk = 98; - chip->asic_mmc_52m_clk = 98; - chip->asic_ms_hg_clk = 117; - chip->asic_ms_4bit_clk = 78; - chip->asic_ms_1bit_clk = 39; - chip->ssc_depth_sd_sdr104 = SSC_DEPTH_2M; - chip->ssc_depth_sd_sdr50 = SSC_DEPTH_2M; - chip->ssc_depth_sd_ddr50 = SSC_DEPTH_1M; - chip->ssc_depth_sd_hs = SSC_DEPTH_1M; - chip->ssc_depth_mmc_52m = SSC_DEPTH_1M; - chip->ssc_depth_ms_hg = SSC_DEPTH_1M; - chip->ssc_depth_ms_4bit = SSC_DEPTH_512K; - chip->ssc_depth_low_speed = SSC_DEPTH_512K; - chip->ssc_en = 1; - chip->sd_speed_prior = 0x01040203; - chip->sd_current_prior = 0x00010203; - chip->sd_ctl = SD_PUSH_POINT_AUTO | - SD_SAMPLE_POINT_AUTO | - SUPPORT_MMC_DDR_MODE; - chip->sd_ddr_tx_phase = 0; - chip->mmc_ddr_tx_phase = 1; - chip->sd_default_tx_phase = 15; - chip->sd_default_rx_phase = 15; - chip->pmos_pwr_on_interval = 200; - chip->sd_voltage_switch_delay = 1000; - chip->ms_power_class_en = 3; - - chip->sd_400mA_ocp_thd = 1; - chip->sd_800mA_ocp_thd = 5; - chip->ms_ocp_thd = 2; - - chip->card_drive_sel = 0x55; - chip->sd30_drive_sel_1v8 = 0x03; - chip->sd30_drive_sel_3v3 = 0x01; - - chip->do_delink_before_power_down = 1; - chip->auto_power_down = 1; - chip->polling_config = 0; - - chip->force_clkreq_0 = 1; - chip->ft2_fast_mode = 0; - - chip->sdio_retry_cnt = 1; - - chip->xd_timeout = 2000; - chip->sd_timeout = 10000; - chip->ms_timeout = 2000; - chip->mspro_timeout = 15000; - - chip->power_down_in_ss = 1; - - chip->sdr104_en = 1; - chip->sdr50_en = 1; - chip->ddr50_en = 1; - - chip->delink_stage1_step = 100; - chip->delink_stage2_step = 40; - chip->delink_stage3_step = 20; - - chip->auto_delink_in_L1 = 1; - chip->blink_led = 1; - chip->msi_en = msi_en; - chip->hp_watch_bios_hotplug = 0; - chip->max_payload = 0; - chip->phy_voltage = 0; - - chip->support_ms_8bit = 1; - chip->s3_pwr_off_delay = 1000; -} - -static int __devinit rtsx_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - struct Scsi_Host *host; - struct rtsx_dev *dev; - int err = 0; - struct task_struct *th; - - RTSX_DEBUGP("Realtek PCI-E card reader detected\n"); - - err = pci_enable_device(pci); - if (err < 0) { - dev_err(&pci->dev, "PCI enable device failed!\n"); - return err; - } - - err = pci_request_regions(pci, CR_DRIVER_NAME); - if (err < 0) { - dev_err(&pci->dev, "PCI request regions for %s failed!\n", - CR_DRIVER_NAME); - pci_disable_device(pci); - return err; - } - - /* - * Ask the SCSI layer to allocate a host structure, with extra - * space at the end for our private rtsx_dev structure. - */ - host = scsi_host_alloc(&rtsx_host_template, sizeof(*dev)); - if (!host) { - dev_err(&pci->dev, "Unable to allocate the scsi host\n"); - pci_release_regions(pci); - pci_disable_device(pci); - return -ENOMEM; - } - - dev = host_to_rtsx(host); - memset(dev, 0, sizeof(struct rtsx_dev)); - - dev->chip = kzalloc(sizeof(struct rtsx_chip), GFP_KERNEL); - if (dev->chip == NULL) - goto errout; - - spin_lock_init(&dev->reg_lock); - mutex_init(&(dev->dev_mutex)); - init_completion(&dev->cmnd_ready); - init_completion(&dev->control_exit); - init_completion(&dev->polling_exit); - init_completion(&(dev->notify)); - init_completion(&dev->scanning_done); - init_waitqueue_head(&dev->delay_wait); - - dev->pci = pci; - dev->irq = -1; - - dev_info(&pci->dev, "Resource length: 0x%x\n", - (unsigned int)pci_resource_len(pci, 0)); - dev->addr = pci_resource_start(pci, 0); - dev->remap_addr = ioremap_nocache(dev->addr, pci_resource_len(pci, 0)); - if (dev->remap_addr == NULL) { - dev_err(&pci->dev, "ioremap error\n"); - err = -ENXIO; - goto errout; - } - - /* - * Using "unsigned long" cast here to eliminate gcc warning in - * 64-bit system - */ - dev_info(&pci->dev, "Original address: 0x%lx, remapped address: 0x%lx\n", - (unsigned long)(dev->addr), (unsigned long)(dev->remap_addr)); - - dev->rtsx_resv_buf = dma_alloc_coherent(&(pci->dev), RTSX_RESV_BUF_LEN, - &(dev->rtsx_resv_buf_addr), GFP_KERNEL); - if (dev->rtsx_resv_buf == NULL) { - dev_err(&pci->dev, "alloc dma buffer fail\n"); - err = -ENXIO; - goto errout; - } - dev->chip->host_cmds_ptr = dev->rtsx_resv_buf; - dev->chip->host_cmds_addr = dev->rtsx_resv_buf_addr; - dev->chip->host_sg_tbl_ptr = dev->rtsx_resv_buf + HOST_CMDS_BUF_LEN; - dev->chip->host_sg_tbl_addr = dev->rtsx_resv_buf_addr + - HOST_CMDS_BUF_LEN; - - dev->chip->rtsx = dev; - - rtsx_init_options(dev->chip); - - dev_info(&pci->dev, "pci->irq = %d\n", pci->irq); - - if (dev->chip->msi_en) { - if (pci_enable_msi(pci) < 0) - dev->chip->msi_en = 0; - } - - if (rtsx_acquire_irq(dev) < 0) { - err = -EBUSY; - goto errout; - } - - pci_set_master(pci); - synchronize_irq(dev->irq); - - rtsx_init_chip(dev->chip); - - /* set the supported max_lun and max_id for the scsi host - * NOTE: the minimal value of max_id is 1 */ - host->max_id = 1; - host->max_lun = dev->chip->max_lun; - - /* Start up our control thread */ - th = kthread_run(rtsx_control_thread, dev, CR_DRIVER_NAME); - if (IS_ERR(th)) { - dev_err(&pci->dev, "Unable to start control thread\n"); - err = PTR_ERR(th); - goto errout; - } - dev->ctl_thread = th; - - err = scsi_add_host(host, &pci->dev); - if (err) { - dev_err(&pci->dev, "Unable to add the scsi host\n"); - goto errout; - } - - /* Start up the thread for delayed SCSI-device scanning */ - th = kthread_run(rtsx_scan_thread, dev, "rtsx-scan"); - if (IS_ERR(th)) { - dev_err(&pci->dev, "Unable to start the device-scanning thread\n"); - complete(&dev->scanning_done); - quiesce_and_remove_host(dev); - err = PTR_ERR(th); - goto errout; - } - - /* Start up the thread for polling thread */ - th = kthread_run(rtsx_polling_thread, dev, "rtsx-polling"); - if (IS_ERR(th)) { - dev_err(&pci->dev, "Unable to start the device-polling thread\n"); - quiesce_and_remove_host(dev); - err = PTR_ERR(th); - goto errout; - } - dev->polling_thread = th; - - pci_set_drvdata(pci, dev); - - return 0; - - /* We come here if there are any problems */ -errout: - dev_err(&pci->dev, "rtsx_probe() failed\n"); - release_everything(dev); - - return err; -} - - -static void __devexit rtsx_remove(struct pci_dev *pci) -{ - struct rtsx_dev *dev = (struct rtsx_dev *)pci_get_drvdata(pci); - - dev_info(&pci->dev, "rtsx_remove() called\n"); - - quiesce_and_remove_host(dev); - release_everything(dev); - - pci_set_drvdata(pci, NULL); -} - -/* PCI IDs */ -static DEFINE_PCI_DEVICE_TABLE(rtsx_ids) = { - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5208), PCI_CLASS_OTHERS << 16, 0xFF0000 }, - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5209), PCI_CLASS_OTHERS << 16, 0xFF0000 }, - { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x5288), PCI_CLASS_OTHERS << 16, 0xFF0000 }, - { 0, }, -}; - -MODULE_DEVICE_TABLE(pci, rtsx_ids); - -/* pci_driver definition */ -static struct pci_driver driver = { - .name = CR_DRIVER_NAME, - .id_table = rtsx_ids, - .probe = rtsx_probe, - .remove = __devexit_p(rtsx_remove), -#ifdef CONFIG_PM - .suspend = rtsx_suspend, - .resume = rtsx_resume, -#endif - .shutdown = rtsx_shutdown, -}; - -static int __init rtsx_init(void) -{ - pr_info("Initializing Realtek PCIE storage driver...\n"); - - return pci_register_driver(&driver); -} - -static void __exit rtsx_exit(void) -{ - pr_info("rtsx_exit() called\n"); - - pci_unregister_driver(&driver); - - pr_info("%s module exit\n", CR_DRIVER_NAME); -} - -module_init(rtsx_init) -module_exit(rtsx_exit) - diff --git a/drivers/staging/rts_pstor/rtsx.h b/drivers/staging/rts_pstor/rtsx.h deleted file mode 100644 index 1ab42fcc47d..00000000000 --- a/drivers/staging/rts_pstor/rtsx.h +++ /dev/null @@ -1,186 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __REALTEK_RTSX_H -#define __REALTEK_RTSX_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "debug.h" -#include "trace.h" -#include "general.h" - -#define CR_DRIVER_NAME "rts_pstor" - -#define pci_get_bus_and_slot(bus, devfn) \ - pci_get_domain_bus_and_slot(0, (bus), (devfn)) - -/* - * macros for easy use - */ -#define rtsx_writel(chip, reg, value) \ - iowrite32(value, (chip)->rtsx->remap_addr + reg) -#define rtsx_readl(chip, reg) \ - ioread32((chip)->rtsx->remap_addr + reg) -#define rtsx_writew(chip, reg, value) \ - iowrite16(value, (chip)->rtsx->remap_addr + reg) -#define rtsx_readw(chip, reg) \ - ioread16((chip)->rtsx->remap_addr + reg) -#define rtsx_writeb(chip, reg, value) \ - iowrite8(value, (chip)->rtsx->remap_addr + reg) -#define rtsx_readb(chip, reg) \ - ioread8((chip)->rtsx->remap_addr + reg) - -#define rtsx_read_config_byte(chip, where, val) \ - pci_read_config_byte((chip)->rtsx->pci, where, val) - -#define rtsx_write_config_byte(chip, where, val) \ - pci_write_config_byte((chip)->rtsx->pci, where, val) - -#define wait_timeout_x(task_state, msecs) \ -do { \ - set_current_state((task_state)); \ - schedule_timeout((msecs) * HZ / 1000); \ -} while (0) -#define wait_timeout(msecs) wait_timeout_x(TASK_INTERRUPTIBLE, (msecs)) - - -#define STATE_TRANS_NONE 0 -#define STATE_TRANS_CMD 1 -#define STATE_TRANS_BUF 2 -#define STATE_TRANS_SG 3 - -#define TRANS_NOT_READY 0 -#define TRANS_RESULT_OK 1 -#define TRANS_RESULT_FAIL 2 - -#define SCSI_LUN(srb) ((srb)->device->lun) - -typedef unsigned long DELAY_PARA_T; - -struct rtsx_chip; - -struct rtsx_dev { - struct pci_dev *pci; - - /* pci resources */ - unsigned long addr; - void __iomem *remap_addr; - int irq; - - /* locks */ - spinlock_t reg_lock; - - struct task_struct *ctl_thread; /* the control thread */ - struct task_struct *polling_thread; /* the polling thread */ - - /* mutual exclusion and synchronization structures */ - struct completion cmnd_ready; /* to sleep thread on */ - struct completion control_exit; /* control thread exit */ - struct completion polling_exit; /* polling thread exit */ - struct completion notify; /* thread begin/end */ - struct completion scanning_done; /* wait for scan thread */ - - wait_queue_head_t delay_wait; /* wait during scan, reset */ - struct mutex dev_mutex; - - /* host reserved buffer */ - void *rtsx_resv_buf; - dma_addr_t rtsx_resv_buf_addr; - - char trans_result; - char trans_state; - - struct completion *done; - /* Whether interrupt handler should care card cd info */ - u32 check_card_cd; - - struct rtsx_chip *chip; -}; - -typedef struct rtsx_dev rtsx_dev_t; - -/* Convert between rtsx_dev and the corresponding Scsi_Host */ -static inline struct Scsi_Host *rtsx_to_host(struct rtsx_dev *dev) -{ - return container_of((void *) dev, struct Scsi_Host, hostdata); -} -static inline struct rtsx_dev *host_to_rtsx(struct Scsi_Host *host) -{ - return (struct rtsx_dev *) host->hostdata; -} - -static inline void get_current_time(u8 *timeval_buf, int buf_len) -{ - struct timeval tv; - - if (!timeval_buf || (buf_len < 8)) - return; - - do_gettimeofday(&tv); - - timeval_buf[0] = (u8)(tv.tv_sec >> 24); - timeval_buf[1] = (u8)(tv.tv_sec >> 16); - timeval_buf[2] = (u8)(tv.tv_sec >> 8); - timeval_buf[3] = (u8)(tv.tv_sec); - timeval_buf[4] = (u8)(tv.tv_usec >> 24); - timeval_buf[5] = (u8)(tv.tv_usec >> 16); - timeval_buf[6] = (u8)(tv.tv_usec >> 8); - timeval_buf[7] = (u8)(tv.tv_usec); -} - -/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the - * single queue element srb for write access */ -#define scsi_unlock(host) spin_unlock_irq(host->host_lock) -#define scsi_lock(host) spin_lock_irq(host->host_lock) - -#define lock_state(chip) spin_lock_irq(&((chip)->rtsx->reg_lock)) -#define unlock_state(chip) spin_unlock_irq(&((chip)->rtsx->reg_lock)) - -/* struct scsi_cmnd transfer buffer access utilities */ -enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF}; - -int rtsx_read_pci_cfg_byte(u8 bus, u8 dev, u8 func, u8 offset, u8 *val); - -#endif /* __REALTEK_RTSX_H */ diff --git a/drivers/staging/rts_pstor/rtsx_card.c b/drivers/staging/rts_pstor/rtsx_card.c deleted file mode 100644 index 539aa6a2778..00000000000 --- a/drivers/staging/rts_pstor/rtsx_card.c +++ /dev/null @@ -1,1233 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include -#include - -#include "rtsx.h" -#include "rtsx_transport.h" -#include "rtsx_scsi.h" -#include "rtsx_card.h" - -#include "rtsx_sys.h" -#include "general.h" - -#include "sd.h" -#include "xd.h" -#include "ms.h" - -void do_remaining_work(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); -#ifdef XD_DELAY_WRITE - struct xd_info *xd_card = &(chip->xd_card); -#endif - struct ms_info *ms_card = &(chip->ms_card); - - if (chip->card_ready & SD_CARD) { - if (sd_card->seq_mode) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - sd_card->cleanup_counter++; - } else { - sd_card->cleanup_counter = 0; - } - } - -#ifdef XD_DELAY_WRITE - if (chip->card_ready & XD_CARD) { - if (xd_card->delay_write.delay_write_flag) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - xd_card->cleanup_counter++; - } else { - xd_card->cleanup_counter = 0; - } - } -#endif - - if (chip->card_ready & MS_CARD) { - if (CHK_MSPRO(ms_card)) { - if (ms_card->seq_mode) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - ms_card->cleanup_counter++; - } else { - ms_card->cleanup_counter = 0; - } - } else { -#ifdef MS_DELAY_WRITE - if (ms_card->delay_write.delay_write_flag) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - ms_card->cleanup_counter++; - } else { - ms_card->cleanup_counter = 0; - } -#endif - } - } - - if (sd_card->cleanup_counter > POLLING_WAIT_CNT) - sd_cleanup_work(chip); - - if (xd_card->cleanup_counter > POLLING_WAIT_CNT) - xd_cleanup_work(chip); - - if (ms_card->cleanup_counter > POLLING_WAIT_CNT) - ms_cleanup_work(chip); -} - -void try_to_switch_sdio_ctrl(struct rtsx_chip *chip) -{ - u8 reg1 = 0, reg2 = 0; - - rtsx_read_register(chip, 0xFF34, ®1); - rtsx_read_register(chip, 0xFF38, ®2); - RTSX_DEBUGP("reg 0xFF34: 0x%x, reg 0xFF38: 0x%x\n", reg1, reg2); - if ((reg1 & 0xC0) && (reg2 & 0xC0)) { - chip->sd_int = 1; - rtsx_write_register(chip, SDIO_CTRL, 0xFF, SDIO_BUS_CTRL | SDIO_CD_CTRL); - rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); - } -} - -#ifdef SUPPORT_SDIO_ASPM -void dynamic_configure_sdio_aspm(struct rtsx_chip *chip) -{ - u8 buf[12], reg; - int i; - - for (i = 0; i < 12; i++) - rtsx_read_register(chip, 0xFF08 + i, &buf[i]); - rtsx_read_register(chip, 0xFF25, ®); - if ((memcmp(buf, chip->sdio_raw_data, 12) != 0) || (reg & 0x03)) { - chip->sdio_counter = 0; - chip->sdio_idle = 0; - } else { - if (!chip->sdio_idle) { - chip->sdio_counter++; - if (chip->sdio_counter >= SDIO_IDLE_COUNT) { - chip->sdio_counter = 0; - chip->sdio_idle = 1; - } - } - } - memcpy(chip->sdio_raw_data, buf, 12); - - if (chip->sdio_idle) { - if (!chip->sdio_aspm) { - RTSX_DEBUGP("SDIO enter ASPM!\n"); - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, - 0x30 | (chip->aspm_level[1] << 2)); - chip->sdio_aspm = 1; - } - } else { - if (chip->sdio_aspm) { - RTSX_DEBUGP("SDIO exit ASPM!\n"); - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFC, 0x30); - chip->sdio_aspm = 0; - } - } -} -#endif - -void do_reset_sd_card(struct rtsx_chip *chip) -{ - int retval; - - RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__, - chip->sd_reset_counter, chip->card2lun[SD_CARD]); - - if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) { - clear_bit(SD_NR, &(chip->need_reset)); - chip->sd_reset_counter = 0; - chip->sd_show_cnt = 0; - return; - } - - chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; - - rtsx_set_stat(chip, RTSX_STAT_RUN); - rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); - - retval = reset_sd_card(chip); - if (chip->need_release & SD_CARD) - return; - if (retval == STATUS_SUCCESS) { - clear_bit(SD_NR, &(chip->need_reset)); - chip->sd_reset_counter = 0; - chip->sd_show_cnt = 0; - chip->card_ready |= SD_CARD; - chip->card_fail &= ~SD_CARD; - chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw; - } else { - if (chip->sd_io || (chip->sd_reset_counter >= MAX_RESET_CNT)) { - clear_bit(SD_NR, &(chip->need_reset)); - chip->sd_reset_counter = 0; - chip->sd_show_cnt = 0; - } else { - chip->sd_reset_counter++; - } - chip->card_ready &= ~SD_CARD; - chip->card_fail |= SD_CARD; - chip->capacity[chip->card2lun[SD_CARD]] = 0; - chip->rw_card[chip->card2lun[SD_CARD]] = NULL; - - rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); - if (!chip->ft2_fast_mode) - card_power_off(chip, SD_CARD); - if (chip->sd_io) { - chip->sd_int = 0; - try_to_switch_sdio_ctrl(chip); - } else { - disable_card_clock(chip, SD_CARD); - } - } -} - -void do_reset_xd_card(struct rtsx_chip *chip) -{ - int retval; - - RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__, - chip->xd_reset_counter, chip->card2lun[XD_CARD]); - - if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT) { - clear_bit(XD_NR, &(chip->need_reset)); - chip->xd_reset_counter = 0; - chip->xd_show_cnt = 0; - return; - } - - chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; - - rtsx_set_stat(chip, RTSX_STAT_RUN); - rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); - - retval = reset_xd_card(chip); - if (chip->need_release & XD_CARD) - return; - if (retval == STATUS_SUCCESS) { - clear_bit(XD_NR, &(chip->need_reset)); - chip->xd_reset_counter = 0; - chip->card_ready |= XD_CARD; - chip->card_fail &= ~XD_CARD; - chip->rw_card[chip->card2lun[XD_CARD]] = xd_rw; - } else { - if (chip->xd_reset_counter >= MAX_RESET_CNT) { - clear_bit(XD_NR, &(chip->need_reset)); - chip->xd_reset_counter = 0; - chip->xd_show_cnt = 0; - } else { - chip->xd_reset_counter++; - } - chip->card_ready &= ~XD_CARD; - chip->card_fail |= XD_CARD; - chip->capacity[chip->card2lun[XD_CARD]] = 0; - chip->rw_card[chip->card2lun[XD_CARD]] = NULL; - - rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); - if (!chip->ft2_fast_mode) - card_power_off(chip, XD_CARD); - disable_card_clock(chip, XD_CARD); - } -} - -void do_reset_ms_card(struct rtsx_chip *chip) -{ - int retval; - - RTSX_DEBUGP("%s: %d, card2lun = 0x%x\n", __func__, - chip->ms_reset_counter, chip->card2lun[MS_CARD]); - - if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) { - clear_bit(MS_NR, &(chip->need_reset)); - chip->ms_reset_counter = 0; - chip->ms_show_cnt = 0; - return; - } - - chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; - - rtsx_set_stat(chip, RTSX_STAT_RUN); - rtsx_write_register(chip, SDIO_CTRL, 0xFF, 0); - - retval = reset_ms_card(chip); - if (chip->need_release & MS_CARD) - return; - if (retval == STATUS_SUCCESS) { - clear_bit(MS_NR, &(chip->need_reset)); - chip->ms_reset_counter = 0; - chip->card_ready |= MS_CARD; - chip->card_fail &= ~MS_CARD; - chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw; - } else { - if (chip->ms_reset_counter >= MAX_RESET_CNT) { - clear_bit(MS_NR, &(chip->need_reset)); - chip->ms_reset_counter = 0; - chip->ms_show_cnt = 0; - } else { - chip->ms_reset_counter++; - } - chip->card_ready &= ~MS_CARD; - chip->card_fail |= MS_CARD; - chip->capacity[chip->card2lun[MS_CARD]] = 0; - chip->rw_card[chip->card2lun[MS_CARD]] = NULL; - - rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); - if (!chip->ft2_fast_mode) - card_power_off(chip, MS_CARD); - disable_card_clock(chip, MS_CARD); - } -} - -static void release_sdio(struct rtsx_chip *chip) -{ - if (chip->sd_io) { - rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, - SD_STOP | SD_CLR_ERR); - - if (chip->chip_insert_with_sdio) { - chip->chip_insert_with_sdio = 0; - - if (CHECK_PID(chip, 0x5288)) - rtsx_write_register(chip, 0xFE5A, 0x08, 0x00); - else - rtsx_write_register(chip, 0xFE70, 0x80, 0x00); - } - - rtsx_write_register(chip, SDIO_CTRL, SDIO_CD_CTRL, 0); - chip->sd_io = 0; - } -} - -void rtsx_power_off_card(struct rtsx_chip *chip) -{ - if ((chip->card_ready & SD_CARD) || chip->sd_io) { - sd_cleanup_work(chip); - sd_power_off_card3v3(chip); - } - - if (chip->card_ready & XD_CARD) { - xd_cleanup_work(chip); - xd_power_off_card3v3(chip); - } - - if (chip->card_ready & MS_CARD) { - ms_cleanup_work(chip); - ms_power_off_card3v3(chip); - } -} - -void rtsx_release_cards(struct rtsx_chip *chip) -{ - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if ((chip->card_ready & SD_CARD) || chip->sd_io) { - if (chip->int_reg & SD_EXIST) - sd_cleanup_work(chip); - release_sd_card(chip); - } - - if (chip->card_ready & XD_CARD) { - if (chip->int_reg & XD_EXIST) - xd_cleanup_work(chip); - release_xd_card(chip); - } - - if (chip->card_ready & MS_CARD) { - if (chip->int_reg & MS_EXIST) - ms_cleanup_work(chip); - release_ms_card(chip); - } -} - -void rtsx_reset_cards(struct rtsx_chip *chip) -{ - if (!chip->need_reset) - return; - - rtsx_set_stat(chip, RTSX_STAT_RUN); - - rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); - - rtsx_disable_aspm(chip); - - if ((chip->need_reset & SD_CARD) && chip->chip_insert_with_sdio) - clear_bit(SD_NR, &(chip->need_reset)); - - if (chip->need_reset & XD_CARD) { - chip->card_exist |= XD_CARD; - - if (chip->xd_show_cnt >= MAX_SHOW_CNT) - do_reset_xd_card(chip); - else - chip->xd_show_cnt++; - } - if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { - if (chip->card_exist & XD_CARD) { - clear_bit(SD_NR, &(chip->need_reset)); - clear_bit(MS_NR, &(chip->need_reset)); - } - } - if (chip->need_reset & SD_CARD) { - chip->card_exist |= SD_CARD; - - if (chip->sd_show_cnt >= MAX_SHOW_CNT) { - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - do_reset_sd_card(chip); - } else { - chip->sd_show_cnt++; - } - } - if (chip->need_reset & MS_CARD) { - chip->card_exist |= MS_CARD; - - if (chip->ms_show_cnt >= MAX_SHOW_CNT) - do_reset_ms_card(chip); - else - chip->ms_show_cnt++; - } -} - -void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip) -{ - rtsx_set_stat(chip, RTSX_STAT_RUN); - - rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); - - if (reset_chip) - rtsx_reset_chip(chip); - - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if ((chip->int_reg & SD_EXIST) && (chip->need_reinit & SD_CARD)) { - release_sdio(chip); - release_sd_card(chip); - - wait_timeout(100); - - chip->card_exist |= SD_CARD; - do_reset_sd_card(chip); - } - - if ((chip->int_reg & XD_EXIST) && (chip->need_reinit & XD_CARD)) { - release_xd_card(chip); - - wait_timeout(100); - - chip->card_exist |= XD_CARD; - do_reset_xd_card(chip); - } - - if ((chip->int_reg & MS_EXIST) && (chip->need_reinit & MS_CARD)) { - release_ms_card(chip); - - wait_timeout(100); - - chip->card_exist |= MS_CARD; - do_reset_ms_card(chip); - } - - chip->need_reinit = 0; -} - -#ifdef DISABLE_CARD_INT -void card_cd_debounce(struct rtsx_chip *chip, unsigned long *need_reset, unsigned long *need_release) -{ - u8 release_map = 0, reset_map = 0; - - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if (chip->card_exist) { - if (chip->card_exist & XD_CARD) { - if (!(chip->int_reg & XD_EXIST)) - release_map |= XD_CARD; - } else if (chip->card_exist & SD_CARD) { - if (!(chip->int_reg & SD_EXIST)) - release_map |= SD_CARD; - } else if (chip->card_exist & MS_CARD) { - if (!(chip->int_reg & MS_EXIST)) - release_map |= MS_CARD; - } - } else { - if (chip->int_reg & XD_EXIST) - reset_map |= XD_CARD; - else if (chip->int_reg & SD_EXIST) - reset_map |= SD_CARD; - else if (chip->int_reg & MS_EXIST) - reset_map |= MS_CARD; - } - - if (reset_map) { - int xd_cnt = 0, sd_cnt = 0, ms_cnt = 0; - int i; - - for (i = 0; i < (DEBOUNCE_CNT); i++) { - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - - if (chip->int_reg & XD_EXIST) - xd_cnt++; - else - xd_cnt = 0; - - if (chip->int_reg & SD_EXIST) - sd_cnt++; - else - sd_cnt = 0; - - if (chip->int_reg & MS_EXIST) - ms_cnt++; - else - ms_cnt = 0; - - wait_timeout(30); - } - - reset_map = 0; - if (!(chip->card_exist & XD_CARD) && (xd_cnt > (DEBOUNCE_CNT-1))) - reset_map |= XD_CARD; - if (!(chip->card_exist & SD_CARD) && (sd_cnt > (DEBOUNCE_CNT-1))) - reset_map |= SD_CARD; - if (!(chip->card_exist & MS_CARD) && (ms_cnt > (DEBOUNCE_CNT-1))) - reset_map |= MS_CARD; - } - - if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) - rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0x00); - - if (need_reset) - *need_reset = reset_map; - if (need_release) - *need_release = release_map; -} -#endif - -void rtsx_init_cards(struct rtsx_chip *chip) -{ - if (RTSX_TST_DELINK(chip) && (rtsx_get_stat(chip) != RTSX_STAT_SS)) { - RTSX_DEBUGP("Reset chip in polling thread!\n"); - rtsx_reset_chip(chip); - RTSX_CLR_DELINK(chip); - } - -#ifdef DISABLE_CARD_INT - card_cd_debounce(chip, &(chip->need_reset), &(chip->need_release)); -#endif - - if (chip->need_release) { - if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) { - if (chip->int_reg & XD_EXIST) { - clear_bit(SD_NR, &(chip->need_release)); - clear_bit(MS_NR, &(chip->need_release)); - } - } - - if (!(chip->card_exist & SD_CARD) && !chip->sd_io) - clear_bit(SD_NR, &(chip->need_release)); - if (!(chip->card_exist & XD_CARD)) - clear_bit(XD_NR, &(chip->need_release)); - if (!(chip->card_exist & MS_CARD)) - clear_bit(MS_NR, &(chip->need_release)); - - RTSX_DEBUGP("chip->need_release = 0x%x\n", (unsigned int)(chip->need_release)); - -#ifdef SUPPORT_OCP - if (chip->need_release) { - if (CHECK_PID(chip, 0x5209)) { - u8 mask = 0, val = 0; - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER)) { - mask |= MS_OCP_INT_CLR | MS_OC_CLR; - val |= MS_OCP_INT_CLR | MS_OC_CLR; - } - } - if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { - mask |= SD_OCP_INT_CLR | SD_OC_CLR; - val |= SD_OCP_INT_CLR | SD_OC_CLR; - } - if (mask) - rtsx_write_register(chip, OCPCTL, mask, val); - } else { - if (chip->ocp_stat & (CARD_OC_NOW | CARD_OC_EVER)) - rtsx_write_register(chip, OCPCLR, - CARD_OC_INT_CLR | CARD_OC_CLR, - CARD_OC_INT_CLR | CARD_OC_CLR); - } - chip->ocp_stat = 0; - } -#endif - if (chip->need_release) { - rtsx_set_stat(chip, RTSX_STAT_RUN); - rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); - } - - if (chip->need_release & SD_CARD) { - clear_bit(SD_NR, &(chip->need_release)); - chip->card_exist &= ~SD_CARD; - chip->card_ejected &= ~SD_CARD; - chip->card_fail &= ~SD_CARD; - CLR_BIT(chip->lun_mc, chip->card2lun[SD_CARD]); - chip->rw_fail_cnt[chip->card2lun[SD_CARD]] = 0; - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - - release_sdio(chip); - release_sd_card(chip); - } - - if (chip->need_release & XD_CARD) { - clear_bit(XD_NR, &(chip->need_release)); - chip->card_exist &= ~XD_CARD; - chip->card_ejected &= ~XD_CARD; - chip->card_fail &= ~XD_CARD; - CLR_BIT(chip->lun_mc, chip->card2lun[XD_CARD]); - chip->rw_fail_cnt[chip->card2lun[XD_CARD]] = 0; - - release_xd_card(chip); - - if (CHECK_PID(chip, 0x5288) && CHECK_BARO_PKG(chip, QFN)) - rtsx_write_register(chip, HOST_SLEEP_STATE, 0xC0, 0xC0); - } - - if (chip->need_release & MS_CARD) { - clear_bit(MS_NR, &(chip->need_release)); - chip->card_exist &= ~MS_CARD; - chip->card_ejected &= ~MS_CARD; - chip->card_fail &= ~MS_CARD; - CLR_BIT(chip->lun_mc, chip->card2lun[MS_CARD]); - chip->rw_fail_cnt[chip->card2lun[MS_CARD]] = 0; - - release_ms_card(chip); - } - - RTSX_DEBUGP("chip->card_exist = 0x%x\n", chip->card_exist); - - if (!chip->card_exist) - turn_off_led(chip, LED_GPIO); - } - - if (chip->need_reset) { - RTSX_DEBUGP("chip->need_reset = 0x%x\n", (unsigned int)(chip->need_reset)); - - rtsx_reset_cards(chip); - } - - if (chip->need_reinit) { - RTSX_DEBUGP("chip->need_reinit = 0x%x\n", (unsigned int)(chip->need_reinit)); - - rtsx_reinit_cards(chip, 0); - } -} - -static inline u8 double_depth(u8 depth) -{ - return ((depth > 1) ? (depth - 1) : depth); -} - -int switch_ssc_clock(struct rtsx_chip *chip, int clk) -{ - struct sd_info *sd_card = &(chip->sd_card); - struct ms_info *ms_card = &(chip->ms_card); - int retval; - u8 N = (u8)(clk - 2), min_N, max_N; - u8 mcu_cnt, div, max_div, ssc_depth, ssc_depth_mask; - int sd_vpclk_phase_reset = 0; - - if (chip->cur_clk == clk) - return STATUS_SUCCESS; - - if (CHECK_PID(chip, 0x5209)) { - min_N = 80; - max_N = 208; - max_div = CLK_DIV_8; - } else { - min_N = 60; - max_N = 120; - max_div = CLK_DIV_4; - } - - if (CHECK_PID(chip, 0x5209) && (chip->cur_card == SD_CARD)) { - struct sd_info *sd_card = &(chip->sd_card); - if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card)) - sd_vpclk_phase_reset = 1; - } - - RTSX_DEBUGP("Switch SSC clock to %dMHz (cur_clk = %d)\n", clk, chip->cur_clk); - - if ((clk <= 2) || (N > max_N)) - TRACE_RET(chip, STATUS_FAIL); - - mcu_cnt = (u8)(125/clk + 3); - if (CHECK_PID(chip, 0x5209)) { - if (mcu_cnt > 15) - mcu_cnt = 15; - } else { - if (mcu_cnt > 7) - mcu_cnt = 7; - } - - div = CLK_DIV_1; - while ((N < min_N) && (div < max_div)) { - N = (N + 2) * 2 - 2; - div++; - } - RTSX_DEBUGP("N = %d, div = %d\n", N, div); - - if (chip->ssc_en) { - if (CHECK_PID(chip, 0x5209)) { - if (chip->cur_card == SD_CARD) { - if (CHK_SD_SDR104(sd_card)) - ssc_depth = chip->ssc_depth_sd_sdr104; - else if (CHK_SD_SDR50(sd_card)) - ssc_depth = chip->ssc_depth_sd_sdr50; - else if (CHK_SD_DDR50(sd_card)) - ssc_depth = double_depth(chip->ssc_depth_sd_ddr50); - else if (CHK_SD_HS(sd_card)) - ssc_depth = double_depth(chip->ssc_depth_sd_hs); - else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) - ssc_depth = double_depth(chip->ssc_depth_mmc_52m); - else - ssc_depth = double_depth(chip->ssc_depth_low_speed); - } else if (chip->cur_card == MS_CARD) { - if (CHK_MSPRO(ms_card)) { - if (CHK_HG8BIT(ms_card)) - ssc_depth = double_depth(chip->ssc_depth_ms_hg); - else - ssc_depth = double_depth(chip->ssc_depth_ms_4bit); - } else { - if (CHK_MS4BIT(ms_card)) - ssc_depth = double_depth(chip->ssc_depth_ms_4bit); - else - ssc_depth = double_depth(chip->ssc_depth_low_speed); - } - } else { - ssc_depth = double_depth(chip->ssc_depth_low_speed); - } - - if (ssc_depth) { - if (div == CLK_DIV_2) { - if (ssc_depth > 1) - ssc_depth -= 1; - else - ssc_depth = SSC_DEPTH_4M; - - } else if (div == CLK_DIV_4) { - if (ssc_depth > 2) - ssc_depth -= 2; - else - ssc_depth = SSC_DEPTH_4M; - - } else if (div == CLK_DIV_8) { - if (ssc_depth > 3) - ssc_depth -= 3; - else - ssc_depth = SSC_DEPTH_4M; - - } - } - } else { - ssc_depth = 0x01; - N -= 2; - } - } else { - ssc_depth = 0; - } - - if (CHECK_PID(chip, 0x5209)) - ssc_depth_mask = SSC_DEPTH_MASK; - else - ssc_depth_mask = 0x03; - - RTSX_DEBUGP("ssc_depth = %d\n", ssc_depth); - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); - rtsx_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0xFF, (div << 4) | mcu_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, ssc_depth_mask, ssc_depth); - rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N); - rtsx_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); - if (sd_vpclk_phase_reset) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); - } - - retval = rtsx_send_cmd(chip, 0, WAIT_TIME); - if (retval < 0) - TRACE_RET(chip, STATUS_ERROR); - - udelay(10); - RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); - - chip->cur_clk = clk; - - return STATUS_SUCCESS; -} - -int switch_normal_clock(struct rtsx_chip *chip, int clk) -{ - u8 sel, div, mcu_cnt; - int sd_vpclk_phase_reset = 0; - - if (chip->cur_clk == clk) - return STATUS_SUCCESS; - - if (CHECK_PID(chip, 0x5209) && (chip->cur_card == SD_CARD)) { - struct sd_info *sd_card = &(chip->sd_card); - if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card)) - sd_vpclk_phase_reset = 1; - } - - switch (clk) { - case CLK_20: - RTSX_DEBUGP("Switch clock to 20MHz\n"); - sel = SSC_80; - div = CLK_DIV_4; - mcu_cnt = 7; - break; - - case CLK_30: - RTSX_DEBUGP("Switch clock to 30MHz\n"); - sel = SSC_120; - div = CLK_DIV_4; - mcu_cnt = 7; - break; - - case CLK_40: - RTSX_DEBUGP("Switch clock to 40MHz\n"); - sel = SSC_80; - div = CLK_DIV_2; - mcu_cnt = 7; - break; - - case CLK_50: - RTSX_DEBUGP("Switch clock to 50MHz\n"); - sel = SSC_100; - div = CLK_DIV_2; - mcu_cnt = 6; - break; - - case CLK_60: - RTSX_DEBUGP("Switch clock to 60MHz\n"); - sel = SSC_120; - div = CLK_DIV_2; - mcu_cnt = 6; - break; - - case CLK_80: - RTSX_DEBUGP("Switch clock to 80MHz\n"); - sel = SSC_80; - div = CLK_DIV_1; - mcu_cnt = 5; - break; - - case CLK_100: - RTSX_DEBUGP("Switch clock to 100MHz\n"); - sel = SSC_100; - div = CLK_DIV_1; - mcu_cnt = 5; - break; - - case CLK_120: - RTSX_DEBUGP("Switch clock to 120MHz\n"); - sel = SSC_120; - div = CLK_DIV_1; - mcu_cnt = 5; - break; - - case CLK_150: - RTSX_DEBUGP("Switch clock to 150MHz\n"); - sel = SSC_150; - div = CLK_DIV_1; - mcu_cnt = 4; - break; - - case CLK_200: - RTSX_DEBUGP("Switch clock to 200MHz\n"); - sel = SSC_200; - div = CLK_DIV_1; - mcu_cnt = 4; - break; - - default: - RTSX_DEBUGP("Try to switch to an illegal clock (%d)\n", clk); - TRACE_RET(chip, STATUS_FAIL); - } - - RTSX_WRITE_REG(chip, CLK_CTL, 0xFF, CLK_LOW_FREQ); - if (sd_vpclk_phase_reset) { - RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); - RTSX_WRITE_REG(chip, SD_VPCLK1_CTL, PHASE_NOT_RESET, 0); - } - RTSX_WRITE_REG(chip, CLK_DIV, 0xFF, (div << 4) | mcu_cnt); - RTSX_WRITE_REG(chip, CLK_SEL, 0xFF, sel); - - if (sd_vpclk_phase_reset) { - udelay(200); - RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); - RTSX_WRITE_REG(chip, SD_VPCLK1_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); - udelay(200); - } - RTSX_WRITE_REG(chip, CLK_CTL, 0xFF, 0); - - chip->cur_clk = clk; - - return STATUS_SUCCESS; -} - -void trans_dma_enable(enum dma_data_direction dir, struct rtsx_chip *chip, u32 byte_cnt, u8 pack_size) -{ - if (pack_size > DMA_1024) - pack_size = DMA_512; - - rtsx_add_cmd(chip, WRITE_REG_CMD, IRQSTAT0, DMA_DONE_INT, DMA_DONE_INT); - - rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(byte_cnt >> 24)); - rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(byte_cnt >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(byte_cnt >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, DMATC0, 0xFF, (u8)byte_cnt); - - if (dir == DMA_FROM_DEVICE) { - rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, 0x03 | DMA_PACK_SIZE_MASK, - DMA_DIR_FROM_CARD | DMA_EN | pack_size); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, DMACTL, 0x03 | DMA_PACK_SIZE_MASK, - DMA_DIR_TO_CARD | DMA_EN | pack_size); - } - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); -} - -int enable_card_clock(struct rtsx_chip *chip, u8 card) -{ - u8 clk_en = 0; - - if (card & XD_CARD) - clk_en |= XD_CLK_EN; - if (card & SD_CARD) - clk_en |= SD_CLK_EN; - if (card & MS_CARD) - clk_en |= MS_CLK_EN; - - RTSX_WRITE_REG(chip, CARD_CLK_EN, clk_en, clk_en); - - return STATUS_SUCCESS; -} - -int disable_card_clock(struct rtsx_chip *chip, u8 card) -{ - u8 clk_en = 0; - - if (card & XD_CARD) - clk_en |= XD_CLK_EN; - if (card & SD_CARD) - clk_en |= SD_CLK_EN; - if (card & MS_CARD) - clk_en |= MS_CLK_EN; - - RTSX_WRITE_REG(chip, CARD_CLK_EN, clk_en, 0); - - return STATUS_SUCCESS; -} - -int card_power_on(struct rtsx_chip *chip, u8 card) -{ - int retval; - u8 mask, val1, val2; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) { - mask = MS_POWER_MASK; - val1 = MS_PARTIAL_POWER_ON; - val2 = MS_POWER_ON; - } else { - mask = SD_POWER_MASK; - val1 = SD_PARTIAL_POWER_ON; - val2 = SD_POWER_ON; - } - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val1); - if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) - rtsx_add_cmd(chip, WRITE_REG_CMD, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_SUSPEND); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - udelay(chip->pmos_pwr_on_interval); - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, mask, val2); - if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) - rtsx_add_cmd(chip, WRITE_REG_CMD, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int card_power_off(struct rtsx_chip *chip, u8 card) -{ - u8 mask, val; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (card == MS_CARD)) { - mask = MS_POWER_MASK; - val = MS_POWER_OFF; - } else { - mask = SD_POWER_MASK; - val = SD_POWER_OFF; - } - if (CHECK_PID(chip, 0x5209)) { - mask |= PMOS_STRG_MASK; - val |= PMOS_STRG_400mA; - } - - RTSX_WRITE_REG(chip, CARD_PWR_CTL, mask, val); - if (CHECK_PID(chip, 0x5209) && (card == SD_CARD)) - RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); - - return STATUS_SUCCESS; -} - -int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt) -{ - int retval; - unsigned int lun = SCSI_LUN(srb); - int i; - - if (chip->rw_card[lun] == NULL) - TRACE_RET(chip, STATUS_FAIL); - - for (i = 0; i < 3; i++) { - chip->rw_need_retry = 0; - - retval = chip->rw_card[lun](srb, chip, sec_addr, sec_cnt); - if (retval != STATUS_SUCCESS) { - if (rtsx_check_chip_exist(chip) != STATUS_SUCCESS) { - rtsx_release_chip(chip); - TRACE_RET(chip, STATUS_FAIL); - } - if (detect_card_cd(chip, chip->cur_card) != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (!chip->rw_need_retry) { - RTSX_DEBUGP("RW fail, but no need to retry\n"); - break; - } - } else { - chip->rw_need_retry = 0; - break; - } - - RTSX_DEBUGP("Retry RW, (i = %d)\n", i); - } - - return retval; -} - -int card_share_mode(struct rtsx_chip *chip, int card) -{ - u8 mask, value; - - if (CHECK_PID(chip, 0x5209) || CHECK_PID(chip, 0x5208)) { - mask = CARD_SHARE_MASK; - if (card == SD_CARD) - value = CARD_SHARE_48_SD; - else if (card == MS_CARD) - value = CARD_SHARE_48_MS; - else if (card == XD_CARD) - value = CARD_SHARE_48_XD; - else - TRACE_RET(chip, STATUS_FAIL); - - } else if (CHECK_PID(chip, 0x5288)) { - mask = 0x03; - if (card == SD_CARD) - value = CARD_SHARE_BAROSSA_SD; - else if (card == MS_CARD) - value = CARD_SHARE_BAROSSA_MS; - else if (card == XD_CARD) - value = CARD_SHARE_BAROSSA_XD; - else - TRACE_RET(chip, STATUS_FAIL); - - } else { - TRACE_RET(chip, STATUS_FAIL); - } - - RTSX_WRITE_REG(chip, CARD_SHARE_MODE, mask, value); - - return STATUS_SUCCESS; -} - - -int select_card(struct rtsx_chip *chip, int card) -{ - int retval; - - if (chip->cur_card != card) { - u8 mod; - - if (card == SD_CARD) - mod = SD_MOD_SEL; - else if (card == MS_CARD) - mod = MS_MOD_SEL; - else if (card == XD_CARD) - mod = XD_MOD_SEL; - else if (card == SPI_CARD) - mod = SPI_MOD_SEL; - else - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, CARD_SELECT, 0x07, mod); - chip->cur_card = card; - - retval = card_share_mode(chip, card); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -void toggle_gpio(struct rtsx_chip *chip, u8 gpio) -{ - u8 temp_reg; - - rtsx_read_register(chip, CARD_GPIO, &temp_reg); - temp_reg ^= (0x01 << gpio); - rtsx_write_register(chip, CARD_GPIO, 0xFF, temp_reg); -} - -void turn_on_led(struct rtsx_chip *chip, u8 gpio) -{ - if (CHECK_PID(chip, 0x5288)) - rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio)); - else - rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); -} - -void turn_off_led(struct rtsx_chip *chip, u8 gpio) -{ - if (CHECK_PID(chip, 0x5288)) - rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), 0); - else - rtsx_write_register(chip, CARD_GPIO, (u8)(1 << gpio), (u8)(1 << gpio)); -} - -int detect_card_cd(struct rtsx_chip *chip, int card) -{ - u32 card_cd, status; - - if (card == SD_CARD) { - card_cd = SD_EXIST; - } else if (card == MS_CARD) { - card_cd = MS_EXIST; - } else if (card == XD_CARD) { - card_cd = XD_EXIST; - } else { - RTSX_DEBUGP("Wrong card type: 0x%x\n", card); - TRACE_RET(chip, STATUS_FAIL); - } - - status = rtsx_readl(chip, RTSX_BIPR); - if (!(status & card_cd)) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int check_card_exist(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_exist & chip->lun2card[lun]) - return 1; - - return 0; -} - -int check_card_ready(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_ready & chip->lun2card[lun]) - return 1; - - return 0; -} - -int check_card_wp(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_wp & chip->lun2card[lun]) - return 1; - - return 0; -} - -int check_card_fail(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_fail & chip->lun2card[lun]) - return 1; - - return 0; -} - -int check_card_ejected(struct rtsx_chip *chip, unsigned int lun) -{ - if (chip->card_ejected & chip->lun2card[lun]) - return 1; - - return 0; -} - -u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun) -{ - if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) - return (u8)XD_CARD; - else if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) - return (u8)SD_CARD; - else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) - return (u8)MS_CARD; - - return 0; -} - -void eject_card(struct rtsx_chip *chip, unsigned int lun) -{ - do_remaining_work(chip); - - if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) { - release_sd_card(chip); - chip->card_ejected |= SD_CARD; - chip->card_ready &= ~SD_CARD; - chip->capacity[lun] = 0; - } else if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) { - release_xd_card(chip); - chip->card_ejected |= XD_CARD; - chip->card_ready &= ~XD_CARD; - chip->capacity[lun] = 0; - } else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) { - release_ms_card(chip); - chip->card_ejected |= MS_CARD; - chip->card_ready &= ~MS_CARD; - chip->capacity[lun] = 0; - } -} diff --git a/drivers/staging/rts_pstor/rtsx_card.h b/drivers/staging/rts_pstor/rtsx_card.h deleted file mode 100644 index 3f727767620..00000000000 --- a/drivers/staging/rts_pstor/rtsx_card.h +++ /dev/null @@ -1,1093 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __REALTEK_RTSX_CARD_H -#define __REALTEK_RTSX_CARD_H - -#include "debug.h" -#include "rtsx.h" -#include "rtsx_chip.h" -#include "rtsx_transport.h" -#include "sd.h" - -#define SSC_POWER_DOWN 0x01 -#define SD_OC_POWER_DOWN 0x02 -#define MS_OC_POWER_DOWN 0x04 -#define ALL_POWER_DOWN 0x07 -#define OC_POWER_DOWN 0x06 - -#define PMOS_STRG_MASK 0x10 -#define PMOS_STRG_800mA 0x10 -#define PMOS_STRG_400mA 0x00 - -#define POWER_OFF 0x03 -#define PARTIAL_POWER_ON 0x01 -#define POWER_ON 0x00 - -#define MS_POWER_OFF 0x0C -#define MS_PARTIAL_POWER_ON 0x04 -#define MS_POWER_ON 0x00 -#define MS_POWER_MASK 0x0C - -#define SD_POWER_OFF 0x03 -#define SD_PARTIAL_POWER_ON 0x01 -#define SD_POWER_ON 0x00 -#define SD_POWER_MASK 0x03 - -#define XD_OUTPUT_EN 0x02 -#define SD_OUTPUT_EN 0x04 -#define MS_OUTPUT_EN 0x08 -#define SPI_OUTPUT_EN 0x10 - -#define CLK_LOW_FREQ 0x01 - -#define CLK_DIV_1 0x01 -#define CLK_DIV_2 0x02 -#define CLK_DIV_4 0x03 -#define CLK_DIV_8 0x04 - -#define SSC_80 0 -#define SSC_100 1 -#define SSC_120 2 -#define SSC_150 3 -#define SSC_200 4 - -#define XD_CLK_EN 0x02 -#define SD_CLK_EN 0x04 -#define MS_CLK_EN 0x08 -#define SPI_CLK_EN 0x10 - -#define XD_MOD_SEL 1 -#define SD_MOD_SEL 2 -#define MS_MOD_SEL 3 -#define SPI_MOD_SEL 4 - -#define CHANGE_CLK 0x01 - -#define SD_CRC7_ERR 0x80 -#define SD_CRC16_ERR 0x40 -#define SD_CRC_WRITE_ERR 0x20 -#define SD_CRC_WRITE_ERR_MASK 0x1C -#define GET_CRC_TIME_OUT 0x02 -#define SD_TUNING_COMPARE_ERR 0x01 - -#define SD_RSP_80CLK_TIMEOUT 0x01 - -#define SD_CLK_TOGGLE_EN 0x80 -#define SD_CLK_FORCE_STOP 0x40 -#define SD_DAT3_STATUS 0x10 -#define SD_DAT2_STATUS 0x08 -#define SD_DAT1_STATUS 0x04 -#define SD_DAT0_STATUS 0x02 -#define SD_CMD_STATUS 0x01 - -#define SD_IO_USING_1V8 0x80 -#define SD_IO_USING_3V3 0x7F -#define TYPE_A_DRIVING 0x00 -#define TYPE_B_DRIVING 0x01 -#define TYPE_C_DRIVING 0x02 -#define TYPE_D_DRIVING 0x03 - -#define DDR_FIX_RX_DAT 0x00 -#define DDR_VAR_RX_DAT 0x80 -#define DDR_FIX_RX_DAT_EDGE 0x00 -#define DDR_FIX_RX_DAT_14_DELAY 0x40 -#define DDR_FIX_RX_CMD 0x00 -#define DDR_VAR_RX_CMD 0x20 -#define DDR_FIX_RX_CMD_POS_EDGE 0x00 -#define DDR_FIX_RX_CMD_14_DELAY 0x10 -#define SD20_RX_POS_EDGE 0x00 -#define SD20_RX_14_DELAY 0x08 -#define SD20_RX_SEL_MASK 0x08 - -#define DDR_FIX_TX_CMD_DAT 0x00 -#define DDR_VAR_TX_CMD_DAT 0x80 -#define DDR_FIX_TX_DAT_14_TSU 0x00 -#define DDR_FIX_TX_DAT_12_TSU 0x40 -#define DDR_FIX_TX_CMD_NEG_EDGE 0x00 -#define DDR_FIX_TX_CMD_14_AHEAD 0x20 -#define SD20_TX_NEG_EDGE 0x00 -#define SD20_TX_14_AHEAD 0x10 -#define SD20_TX_SEL_MASK 0x10 -#define DDR_VAR_SDCLK_POL_SWAP 0x01 - -#define SD_TRANSFER_START 0x80 -#define SD_TRANSFER_END 0x40 -#define SD_STAT_IDLE 0x20 -#define SD_TRANSFER_ERR 0x10 -#define SD_TM_NORMAL_WRITE 0x00 -#define SD_TM_AUTO_WRITE_3 0x01 -#define SD_TM_AUTO_WRITE_4 0x02 -#define SD_TM_AUTO_READ_3 0x05 -#define SD_TM_AUTO_READ_4 0x06 -#define SD_TM_CMD_RSP 0x08 -#define SD_TM_AUTO_WRITE_1 0x09 -#define SD_TM_AUTO_WRITE_2 0x0A -#define SD_TM_NORMAL_READ 0x0C -#define SD_TM_AUTO_READ_1 0x0D -#define SD_TM_AUTO_READ_2 0x0E -#define SD_TM_AUTO_TUNING 0x0F - -#define PHASE_CHANGE 0x80 -#define PHASE_NOT_RESET 0x40 - -#define DCMPS_CHANGE 0x80 -#define DCMPS_CHANGE_DONE 0x40 -#define DCMPS_ERROR 0x20 -#define DCMPS_CURRENT_PHASE 0x1F - -#define SD_CLK_DIVIDE_0 0x00 -#define SD_CLK_DIVIDE_256 0xC0 -#define SD_CLK_DIVIDE_128 0x80 -#define SD_BUS_WIDTH_1 0x00 -#define SD_BUS_WIDTH_4 0x01 -#define SD_BUS_WIDTH_8 0x02 -#define SD_ASYNC_FIFO_NOT_RST 0x10 -#define SD_20_MODE 0x00 -#define SD_DDR_MODE 0x04 -#define SD_30_MODE 0x08 - -#define SD_CLK_DIVIDE_MASK 0xC0 - -#define SD_CMD_IDLE 0x80 - -#define SD_DATA_IDLE 0x80 - -#define DCM_RESET 0x08 -#define DCM_LOCKED 0x04 -#define DCM_208M 0x00 -#define DCM_TX 0x01 -#define DCM_RX 0x02 - -#define DRP_START 0x80 -#define DRP_DONE 0x40 - -#define DRP_WRITE 0x80 -#define DRP_READ 0x00 -#define DCM_WRITE_ADDRESS_50 0x50 -#define DCM_WRITE_ADDRESS_51 0x51 -#define DCM_READ_ADDRESS_00 0x00 -#define DCM_READ_ADDRESS_51 0x51 - -#define SD_CALCULATE_CRC7 0x00 -#define SD_NO_CALCULATE_CRC7 0x80 -#define SD_CHECK_CRC16 0x00 -#define SD_NO_CHECK_CRC16 0x40 -#define SD_NO_CHECK_WAIT_CRC_TO 0x20 -#define SD_WAIT_BUSY_END 0x08 -#define SD_NO_WAIT_BUSY_END 0x00 -#define SD_CHECK_CRC7 0x00 -#define SD_NO_CHECK_CRC7 0x04 -#define SD_RSP_LEN_0 0x00 -#define SD_RSP_LEN_6 0x01 -#define SD_RSP_LEN_17 0x02 -#define SD_RSP_TYPE_R0 0x04 -#define SD_RSP_TYPE_R1 0x01 -#define SD_RSP_TYPE_R1b 0x09 -#define SD_RSP_TYPE_R2 0x02 -#define SD_RSP_TYPE_R3 0x05 -#define SD_RSP_TYPE_R4 0x05 -#define SD_RSP_TYPE_R5 0x01 -#define SD_RSP_TYPE_R6 0x01 -#define SD_RSP_TYPE_R7 0x01 - -#define SD_RSP_80CLK_TIMEOUT_EN 0x01 - -#define SAMPLE_TIME_RISING 0x00 -#define SAMPLE_TIME_FALLING 0x80 -#define PUSH_TIME_DEFAULT 0x00 -#define PUSH_TIME_ODD 0x40 -#define NO_EXTEND_TOGGLE 0x00 -#define EXTEND_TOGGLE_CHK 0x20 -#define MS_BUS_WIDTH_1 0x00 -#define MS_BUS_WIDTH_4 0x10 -#define MS_BUS_WIDTH_8 0x18 -#define MS_2K_SECTOR_MODE 0x04 -#define MS_512_SECTOR_MODE 0x00 -#define MS_TOGGLE_TIMEOUT_EN 0x00 -#define MS_TOGGLE_TIMEOUT_DISEN 0x01 -#define MS_NO_CHECK_INT 0x02 - -#define WAIT_INT 0x80 -#define NO_WAIT_INT 0x00 -#define NO_AUTO_READ_INT_REG 0x00 -#define AUTO_READ_INT_REG 0x40 -#define MS_CRC16_ERR 0x20 -#define MS_RDY_TIMEOUT 0x10 -#define MS_INT_CMDNK 0x08 -#define MS_INT_BREQ 0x04 -#define MS_INT_ERR 0x02 -#define MS_INT_CED 0x01 - -#define MS_TRANSFER_START 0x80 -#define MS_TRANSFER_END 0x40 -#define MS_TRANSFER_ERR 0x20 -#define MS_BS_STATE 0x10 -#define MS_TM_READ_BYTES 0x00 -#define MS_TM_NORMAL_READ 0x01 -#define MS_TM_WRITE_BYTES 0x04 -#define MS_TM_NORMAL_WRITE 0x05 -#define MS_TM_AUTO_READ 0x08 -#define MS_TM_AUTO_WRITE 0x0C - -#define CARD_SHARE_MASK 0x0F -#define CARD_SHARE_MULTI_LUN 0x00 -#define CARD_SHARE_NORMAL 0x00 -#define CARD_SHARE_48_XD 0x02 -#define CARD_SHARE_48_SD 0x04 -#define CARD_SHARE_48_MS 0x08 -#define CARD_SHARE_BAROSSA_XD 0x00 -#define CARD_SHARE_BAROSSA_SD 0x01 -#define CARD_SHARE_BAROSSA_MS 0x02 - -#define MS_DRIVE_8 0x00 -#define MS_DRIVE_4 0x40 -#define MS_DRIVE_12 0x80 -#define SD_DRIVE_8 0x00 -#define SD_DRIVE_4 0x10 -#define SD_DRIVE_12 0x20 -#define XD_DRIVE_8 0x00 -#define XD_DRIVE_4 0x04 -#define XD_DRIVE_12 0x08 - -#define SPI_STOP 0x01 -#define XD_STOP 0x02 -#define SD_STOP 0x04 -#define MS_STOP 0x08 -#define SPI_CLR_ERR 0x10 -#define XD_CLR_ERR 0x20 -#define SD_CLR_ERR 0x40 -#define MS_CLR_ERR 0x80 - -#define CRC_FIX_CLK (0x00 << 0) -#define CRC_VAR_CLK0 (0x01 << 0) -#define CRC_VAR_CLK1 (0x02 << 0) -#define SD30_FIX_CLK (0x00 << 2) -#define SD30_VAR_CLK0 (0x01 << 2) -#define SD30_VAR_CLK1 (0x02 << 2) -#define SAMPLE_FIX_CLK (0x00 << 4) -#define SAMPLE_VAR_CLK0 (0x01 << 4) -#define SAMPLE_VAR_CLK1 (0x02 << 4) - -#define SDIO_VER_20 0x80 -#define SDIO_VER_10 0x00 -#define SDIO_VER_CHG 0x40 -#define SDIO_BUS_AUTO_SWITCH 0x10 - -#define PINGPONG_BUFFER 0x01 -#define RING_BUFFER 0x00 - -#define RB_FLUSH 0x80 - -#define DMA_DONE_INT_EN 0x80 -#define SUSPEND_INT_EN 0x40 -#define LINK_RDY_INT_EN 0x20 -#define LINK_DOWN_INT_EN 0x10 - -#define DMA_DONE_INT 0x80 -#define SUSPEND_INT 0x40 -#define LINK_RDY_INT 0x20 -#define LINK_DOWN_INT 0x10 - -#define MRD_ERR_INT_EN 0x40 -#define MWR_ERR_INT_EN 0x20 -#define SCSI_CMD_INT_EN 0x10 -#define TLP_RCV_INT_EN 0x08 -#define TLP_TRSMT_INT_EN 0x04 -#define MRD_COMPLETE_INT_EN 0x02 -#define MWR_COMPLETE_INT_EN 0x01 - -#define MRD_ERR_INT 0x40 -#define MWR_ERR_INT 0x20 -#define SCSI_CMD_INT 0x10 -#define TLP_RX_INT 0x08 -#define TLP_TX_INT 0x04 -#define MRD_COMPLETE_INT 0x02 -#define MWR_COMPLETE_INT 0x01 - -#define MSG_RX_INT_EN 0x08 -#define MRD_RX_INT_EN 0x04 -#define MWR_RX_INT_EN 0x02 -#define CPLD_RX_INT_EN 0x01 - -#define MSG_RX_INT 0x08 -#define MRD_RX_INT 0x04 -#define MWR_RX_INT 0x02 -#define CPLD_RX_INT 0x01 - -#define MSG_TX_INT_EN 0x08 -#define MRD_TX_INT_EN 0x04 -#define MWR_TX_INT_EN 0x02 -#define CPLD_TX_INT_EN 0x01 - -#define MSG_TX_INT 0x08 -#define MRD_TX_INT 0x04 -#define MWR_TX_INT 0x02 -#define CPLD_TX_INT 0x01 - -#define DMA_RST 0x80 -#define DMA_BUSY 0x04 -#define DMA_DIR_TO_CARD 0x00 -#define DMA_DIR_FROM_CARD 0x02 -#define DMA_EN 0x01 -#define DMA_128 (0 << 4) -#define DMA_256 (1 << 4) -#define DMA_512 (2 << 4) -#define DMA_1024 (3 << 4) -#define DMA_PACK_SIZE_MASK 0x30 - -#define XD_PWR_OFF_DELAY0 0x00 -#define XD_PWR_OFF_DELAY1 0x02 -#define XD_PWR_OFF_DELAY2 0x04 -#define XD_PWR_OFF_DELAY3 0x06 -#define XD_AUTO_PWR_OFF_EN 0xF7 -#define XD_NO_AUTO_PWR_OFF 0x08 - -#define XD_TIME_RWN_1 0x00 -#define XD_TIME_RWN_STEP 0x20 -#define XD_TIME_RW_1 0x00 -#define XD_TIME_RW_STEP 0x04 -#define XD_TIME_SETUP_1 0x00 -#define XD_TIME_SETUP_STEP 0x01 - -#define XD_ECC2_UNCORRECTABLE 0x80 -#define XD_ECC2_ERROR 0x40 -#define XD_ECC1_UNCORRECTABLE 0x20 -#define XD_ECC1_ERROR 0x10 -#define XD_RDY 0x04 -#define XD_CE_EN 0xFD -#define XD_CE_DISEN 0x02 -#define XD_WP_EN 0xFE -#define XD_WP_DISEN 0x01 - -#define XD_TRANSFER_START 0x80 -#define XD_TRANSFER_END 0x40 -#define XD_PPB_EMPTY 0x20 -#define XD_RESET 0x00 -#define XD_ERASE 0x01 -#define XD_READ_STATUS 0x02 -#define XD_READ_ID 0x03 -#define XD_READ_REDUNDANT 0x04 -#define XD_READ_PAGES 0x05 -#define XD_SET_CMD 0x06 -#define XD_NORMAL_READ 0x07 -#define XD_WRITE_PAGES 0x08 -#define XD_NORMAL_WRITE 0x09 -#define XD_WRITE_REDUNDANT 0x0A -#define XD_SET_ADDR 0x0B - -#define XD_PPB_TO_SIE 0x80 -#define XD_TO_PPB_ONLY 0x00 -#define XD_BA_TRANSFORM 0x40 -#define XD_BA_NO_TRANSFORM 0x00 -#define XD_NO_CALC_ECC 0x20 -#define XD_CALC_ECC 0x00 -#define XD_IGNORE_ECC 0x10 -#define XD_CHECK_ECC 0x00 -#define XD_DIRECT_TO_RB 0x08 -#define XD_ADDR_LENGTH_0 0x00 -#define XD_ADDR_LENGTH_1 0x01 -#define XD_ADDR_LENGTH_2 0x02 -#define XD_ADDR_LENGTH_3 0x03 -#define XD_ADDR_LENGTH_4 0x04 - -#define XD_GPG 0xFF -#define XD_BPG 0x00 - -#define XD_GBLK 0xFF -#define XD_LATER_BBLK 0xF0 - -#define XD_ECC2_ALL1 0x80 -#define XD_ECC1_ALL1 0x40 -#define XD_BA2_ALL0 0x20 -#define XD_BA1_ALL0 0x10 -#define XD_BA1_BA2_EQL 0x04 -#define XD_BA2_VALID 0x02 -#define XD_BA1_VALID 0x01 - -#define XD_PGSTS_ZEROBIT_OVER4 0x00 -#define XD_PGSTS_NOT_FF 0x02 -#define XD_AUTO_CHK_DATA_STATUS 0x01 - -#define RSTB_MODE_DETECT 0x80 -#define MODE_OUT_VLD 0x40 -#define MODE_OUT_0_NONE 0x00 -#define MODE_OUT_10_NONE 0x04 -#define MODE_OUT_10_47 0x05 -#define MODE_OUT_10_180 0x06 -#define MODE_OUT_10_680 0x07 -#define MODE_OUT_16_NONE 0x08 -#define MODE_OUT_16_47 0x09 -#define MODE_OUT_16_180 0x0A -#define MODE_OUT_16_680 0x0B -#define MODE_OUT_NONE_NONE 0x0C -#define MODE_OUT_NONE_47 0x0D -#define MODE_OUT_NONE_180 0x0E -#define MODE_OUT_NONE_680 0x0F - -#define CARD_OC_INT_EN 0x20 -#define CARD_DETECT_EN 0x08 - -#define MS_DETECT_EN 0x80 -#define MS_OCP_INT_EN 0x40 -#define MS_OCP_INT_CLR 0x20 -#define MS_OC_CLR 0x10 -#define SD_DETECT_EN 0x08 -#define SD_OCP_INT_EN 0x04 -#define SD_OCP_INT_CLR 0x02 -#define SD_OC_CLR 0x01 - -#define CARD_OCP_DETECT 0x80 -#define CARD_OC_NOW 0x08 -#define CARD_OC_EVER 0x04 - -#define MS_OCP_DETECT 0x80 -#define MS_OC_NOW 0x40 -#define MS_OC_EVER 0x20 -#define SD_OCP_DETECT 0x08 -#define SD_OC_NOW 0x04 -#define SD_OC_EVER 0x02 - -#define CARD_OC_INT_CLR 0x08 -#define CARD_OC_CLR 0x02 - -#define SD_OCP_GLITCH_MASK 0x07 -#define SD_OCP_GLITCH_6_4 0x00 -#define SD_OCP_GLITCH_64 0x01 -#define SD_OCP_GLITCH_640 0x02 -#define SD_OCP_GLITCH_1000 0x03 -#define SD_OCP_GLITCH_2000 0x04 -#define SD_OCP_GLITCH_4000 0x05 -#define SD_OCP_GLITCH_8000 0x06 -#define SD_OCP_GLITCH_10000 0x07 - -#define MS_OCP_GLITCH_MASK 0x70 -#define MS_OCP_GLITCH_6_4 (0x00 << 4) -#define MS_OCP_GLITCH_64 (0x01 << 4) -#define MS_OCP_GLITCH_640 (0x02 << 4) -#define MS_OCP_GLITCH_1000 (0x03 << 4) -#define MS_OCP_GLITCH_2000 (0x04 << 4) -#define MS_OCP_GLITCH_4000 (0x05 << 4) -#define MS_OCP_GLITCH_8000 (0x06 << 4) -#define MS_OCP_GLITCH_10000 (0x07 << 4) - -#define OCP_TIME_60 0x00 -#define OCP_TIME_100 (0x01 << 3) -#define OCP_TIME_200 (0x02 << 3) -#define OCP_TIME_400 (0x03 << 3) -#define OCP_TIME_600 (0x04 << 3) -#define OCP_TIME_800 (0x05 << 3) -#define OCP_TIME_1100 (0x06 << 3) -#define OCP_TIME_MASK 0x38 - -#define MS_OCP_TIME_60 0x00 -#define MS_OCP_TIME_100 (0x01 << 4) -#define MS_OCP_TIME_200 (0x02 << 4) -#define MS_OCP_TIME_400 (0x03 << 4) -#define MS_OCP_TIME_600 (0x04 << 4) -#define MS_OCP_TIME_800 (0x05 << 4) -#define MS_OCP_TIME_1100 (0x06 << 4) -#define MS_OCP_TIME_MASK 0x70 - -#define SD_OCP_TIME_60 0x00 -#define SD_OCP_TIME_100 0x01 -#define SD_OCP_TIME_200 0x02 -#define SD_OCP_TIME_400 0x03 -#define SD_OCP_TIME_600 0x04 -#define SD_OCP_TIME_800 0x05 -#define SD_OCP_TIME_1100 0x06 -#define SD_OCP_TIME_MASK 0x07 - -#define OCP_THD_315_417 0x00 -#define OCP_THD_283_783 (0x01 << 6) -#define OCP_THD_244_946 (0x02 << 6) -#define OCP_THD_191_1080 (0x03 << 6) -#define OCP_THD_MASK 0xC0 - -#define MS_OCP_THD_450 0x00 -#define MS_OCP_THD_550 (0x01 << 4) -#define MS_OCP_THD_650 (0x02 << 4) -#define MS_OCP_THD_750 (0x03 << 4) -#define MS_OCP_THD_850 (0x04 << 4) -#define MS_OCP_THD_950 (0x05 << 4) -#define MS_OCP_THD_1050 (0x06 << 4) -#define MS_OCP_THD_1150 (0x07 << 4) -#define MS_OCP_THD_MASK 0x70 - -#define SD_OCP_THD_450 0x00 -#define SD_OCP_THD_550 0x01 -#define SD_OCP_THD_650 0x02 -#define SD_OCP_THD_750 0x03 -#define SD_OCP_THD_850 0x04 -#define SD_OCP_THD_950 0x05 -#define SD_OCP_THD_1050 0x06 -#define SD_OCP_THD_1150 0x07 -#define SD_OCP_THD_MASK 0x07 - -#define FPGA_MS_PULL_CTL_EN 0xEF -#define FPGA_SD_PULL_CTL_EN 0xF7 -#define FPGA_XD_PULL_CTL_EN1 0xFE -#define FPGA_XD_PULL_CTL_EN2 0xFD -#define FPGA_XD_PULL_CTL_EN3 0xFB - -#define FPGA_MS_PULL_CTL_BIT 0x10 -#define FPGA_SD_PULL_CTL_BIT 0x08 - -#define BLINK_EN 0x08 -#define LED_GPIO0 (0 << 4) -#define LED_GPIO1 (1 << 4) -#define LED_GPIO2 (2 << 4) - -#define SDIO_BUS_CTRL 0x01 -#define SDIO_CD_CTRL 0x02 - -#define SSC_RSTB 0x80 -#define SSC_8X_EN 0x40 -#define SSC_FIX_FRAC 0x20 -#define SSC_SEL_1M 0x00 -#define SSC_SEL_2M 0x08 -#define SSC_SEL_4M 0x10 -#define SSC_SEL_8M 0x18 - -#define SSC_DEPTH_MASK 0x07 -#define SSC_DEPTH_DISALBE 0x00 -#define SSC_DEPTH_4M 0x01 -#define SSC_DEPTH_2M 0x02 -#define SSC_DEPTH_1M 0x03 -#define SSC_DEPTH_512K 0x04 -#define SSC_DEPTH_256K 0x05 -#define SSC_DEPTH_128K 0x06 -#define SSC_DEPTH_64K 0x07 - -#define XD_D3_NP 0x00 -#define XD_D3_PD (0x01 << 6) -#define XD_D3_PU (0x02 << 6) -#define XD_D2_NP 0x00 -#define XD_D2_PD (0x01 << 4) -#define XD_D2_PU (0x02 << 4) -#define XD_D1_NP 0x00 -#define XD_D1_PD (0x01 << 2) -#define XD_D1_PU (0x02 << 2) -#define XD_D0_NP 0x00 -#define XD_D0_PD 0x01 -#define XD_D0_PU 0x02 - -#define SD_D7_NP 0x00 -#define SD_D7_PD (0x01 << 4) -#define SD_DAT7_PU (0x02 << 4) -#define SD_CLK_NP 0x00 -#define SD_CLK_PD (0x01 << 2) -#define SD_CLK_PU (0x02 << 2) -#define SD_D5_NP 0x00 -#define SD_D5_PD 0x01 -#define SD_D5_PU 0x02 - -#define MS_D1_NP 0x00 -#define MS_D1_PD (0x01 << 6) -#define MS_D1_PU (0x02 << 6) -#define MS_D2_NP 0x00 -#define MS_D2_PD (0x01 << 4) -#define MS_D2_PU (0x02 << 4) -#define MS_CLK_NP 0x00 -#define MS_CLK_PD (0x01 << 2) -#define MS_CLK_PU (0x02 << 2) -#define MS_D6_NP 0x00 -#define MS_D6_PD 0x01 -#define MS_D6_PU 0x02 - -#define XD_D7_NP 0x00 -#define XD_D7_PD (0x01 << 6) -#define XD_D7_PU (0x02 << 6) -#define XD_D6_NP 0x00 -#define XD_D6_PD (0x01 << 4) -#define XD_D6_PU (0x02 << 4) -#define XD_D5_NP 0x00 -#define XD_D5_PD (0x01 << 2) -#define XD_D5_PU (0x02 << 2) -#define XD_D4_NP 0x00 -#define XD_D4_PD 0x01 -#define XD_D4_PU 0x02 - -#define SD_D6_NP 0x00 -#define SD_D6_PD (0x01 << 6) -#define SD_D6_PU (0x02 << 6) -#define SD_D0_NP 0x00 -#define SD_D0_PD (0x01 << 4) -#define SD_D0_PU (0x02 << 4) -#define SD_D1_NP 0x00 -#define SD_D1_PD 0x01 -#define SD_D1_PU 0x02 - -#define MS_D3_NP 0x00 -#define MS_D3_PD (0x01 << 6) -#define MS_D3_PU (0x02 << 6) -#define MS_D0_NP 0x00 -#define MS_D0_PD (0x01 << 4) -#define MS_D0_PU (0x02 << 4) -#define MS_BS_NP 0x00 -#define MS_BS_PD (0x01 << 2) -#define MS_BS_PU (0x02 << 2) - -#define XD_WP_NP 0x00 -#define XD_WP_PD (0x01 << 6) -#define XD_WP_PU (0x02 << 6) -#define XD_CE_NP 0x00 -#define XD_CE_PD (0x01 << 3) -#define XD_CE_PU (0x02 << 3) -#define XD_CLE_NP 0x00 -#define XD_CLE_PD (0x01 << 1) -#define XD_CLE_PU (0x02 << 1) -#define XD_CD_PD 0x00 -#define XD_CD_PU 0x01 - -#define SD_D4_NP 0x00 -#define SD_D4_PD (0x01 << 6) -#define SD_D4_PU (0x02 << 6) - -#define MS_D7_NP 0x00 -#define MS_D7_PD (0x01 << 6) -#define MS_D7_PU (0x02 << 6) - -#define XD_RDY_NP 0x00 -#define XD_RDY_PD (0x01 << 6) -#define XD_RDY_PU (0x02 << 6) -#define XD_WE_NP 0x00 -#define XD_WE_PD (0x01 << 4) -#define XD_WE_PU (0x02 << 4) -#define XD_RE_NP 0x00 -#define XD_RE_PD (0x01 << 2) -#define XD_RE_PU (0x02 << 2) -#define XD_ALE_NP 0x00 -#define XD_ALE_PD 0x01 -#define XD_ALE_PU 0x02 - -#define SD_D3_NP 0x00 -#define SD_D3_PD (0x01 << 4) -#define SD_D3_PU (0x02 << 4) -#define SD_D2_NP 0x00 -#define SD_D2_PD (0x01 << 2) -#define SD_D2_PU (0x02 << 2) - -#define MS_INS_PD 0x00 -#define MS_INS_PU (0x01 << 7) -#define SD_WP_NP 0x00 -#define SD_WP_PD (0x01 << 5) -#define SD_WP_PU (0x02 << 5) -#define SD_CD_PD 0x00 -#define SD_CD_PU (0x01 << 4) -#define SD_CMD_NP 0x00 -#define SD_CMD_PD (0x01 << 2) -#define SD_CMD_PU (0x02 << 2) - -#define MS_D5_NP 0x00 -#define MS_D5_PD (0x01 << 2) -#define MS_D5_PU (0x02 << 2) -#define MS_D4_NP 0x00 -#define MS_D4_PD 0x01 -#define MS_D4_PU 0x02 - -#define FORCE_PM_CLOCK 0x10 -#define EN_CLOCK_PM 0x01 - -#define HOST_ENTER_S3 0x02 -#define HOST_ENTER_S1 0x01 - -#define AUX_PWR_DETECTED 0x01 - -#define PHY_DEBUG_MODE 0x01 - -#define SPI_COMMAND_BIT_8 0xE0 -#define SPI_ADDRESS_BIT_24 0x17 -#define SPI_ADDRESS_BIT_32 0x1F - -#define SPI_TRANSFER0_START 0x80 -#define SPI_TRANSFER0_END 0x40 -#define SPI_C_MODE0 0x00 -#define SPI_CA_MODE0 0x01 -#define SPI_CDO_MODE0 0x02 -#define SPI_CDI_MODE0 0x03 -#define SPI_CADO_MODE0 0x04 -#define SPI_CADI_MODE0 0x05 -#define SPI_POLLING_MODE0 0x06 - -#define SPI_TRANSFER1_START 0x80 -#define SPI_TRANSFER1_END 0x40 -#define SPI_DO_MODE1 0x00 -#define SPI_DI_MODE1 0x01 - -#define CS_POLARITY_HIGH 0x40 -#define CS_POLARITY_LOW 0x00 -#define DTO_MSB_FIRST 0x00 -#define DTO_LSB_FIRST 0x20 -#define SPI_MASTER 0x00 -#define SPI_SLAVE 0x10 -#define SPI_MODE0 0x00 -#define SPI_MODE1 0x04 -#define SPI_MODE2 0x08 -#define SPI_MODE3 0x0C -#define SPI_MANUAL 0x00 -#define SPI_HALF_AUTO 0x01 -#define SPI_AUTO 0x02 -#define SPI_EEPROM_AUTO 0x03 - -#define EDO_TIMING_MASK 0x03 -#define SAMPLE_RISING 0x00 -#define SAMPLE_DELAY_HALF 0x01 -#define SAMPLE_DELAY_ONE 0x02 -#define SAPMLE_DELAY_ONE_HALF 0x03 -#define TCS_MASK 0x0C - -#define NOT_BYPASS_SD 0x02 -#define DISABLE_SDIO_FUNC 0x04 -#define SELECT_1LUN 0x08 - -#define PWR_GATE_EN 0x01 -#define LDO3318_PWR_MASK 0x06 -#define LDO_ON 0x00 -#define LDO_SUSPEND 0x04 -#define LDO_OFF 0x06 - -#define SD_CFG1 0xFDA0 -#define SD_CFG2 0xFDA1 -#define SD_CFG3 0xFDA2 -#define SD_STAT1 0xFDA3 -#define SD_STAT2 0xFDA4 -#define SD_BUS_STAT 0xFDA5 -#define SD_PAD_CTL 0xFDA6 -#define SD_SAMPLE_POINT_CTL 0xFDA7 -#define SD_PUSH_POINT_CTL 0xFDA8 -#define SD_CMD0 0xFDA9 -#define SD_CMD1 0xFDAA -#define SD_CMD2 0xFDAB -#define SD_CMD3 0xFDAC -#define SD_CMD4 0xFDAD -#define SD_CMD5 0xFDAE -#define SD_BYTE_CNT_L 0xFDAF -#define SD_BYTE_CNT_H 0xFDB0 -#define SD_BLOCK_CNT_L 0xFDB1 -#define SD_BLOCK_CNT_H 0xFDB2 -#define SD_TRANSFER 0xFDB3 -#define SD_CMD_STATE 0xFDB5 -#define SD_DATA_STATE 0xFDB6 - -#define DCM_DRP_CTL 0xFC23 -#define DCM_DRP_TRIG 0xFC24 -#define DCM_DRP_CFG 0xFC25 -#define DCM_DRP_WR_DATA_L 0xFC26 -#define DCM_DRP_WR_DATA_H 0xFC27 -#define DCM_DRP_RD_DATA_L 0xFC28 -#define DCM_DRP_RD_DATA_H 0xFC29 -#define SD_VPCLK0_CTL 0xFC2A -#define SD_VPCLK1_CTL 0xFC2B -#define SD_DCMPS0_CTL 0xFC2C -#define SD_DCMPS1_CTL 0xFC2D -#define SD_VPTX_CTL SD_VPCLK0_CTL -#define SD_VPRX_CTL SD_VPCLK1_CTL -#define SD_DCMPS_TX_CTL SD_DCMPS0_CTL -#define SD_DCMPS_RX_CTL SD_DCMPS1_CTL - -#define CARD_CLK_SOURCE 0xFC2E - -#define CARD_PWR_CTL 0xFD50 -#define CARD_CLK_SWITCH 0xFD51 -#define CARD_SHARE_MODE 0xFD52 -#define CARD_DRIVE_SEL 0xFD53 -#define CARD_STOP 0xFD54 -#define CARD_OE 0xFD55 -#define CARD_AUTO_BLINK 0xFD56 -#define CARD_GPIO_DIR 0xFD57 -#define CARD_GPIO 0xFD58 - -#define CARD_DATA_SOURCE 0xFD5B -#define CARD_SELECT 0xFD5C -#define SD30_DRIVE_SEL 0xFD5E - -#define CARD_CLK_EN 0xFD69 - -#define SDIO_CTRL 0xFD6B - -#define FPDCTL 0xFC00 -#define PDINFO 0xFC01 - -#define CLK_CTL 0xFC02 -#define CLK_DIV 0xFC03 -#define CLK_SEL 0xFC04 - -#define SSC_DIV_N_0 0xFC0F -#define SSC_DIV_N_1 0xFC10 - -#define RCCTL 0xFC14 - -#define FPGA_PULL_CTL 0xFC1D - -#define CARD_PULL_CTL1 0xFD60 -#define CARD_PULL_CTL2 0xFD61 -#define CARD_PULL_CTL3 0xFD62 -#define CARD_PULL_CTL4 0xFD63 -#define CARD_PULL_CTL5 0xFD64 -#define CARD_PULL_CTL6 0xFD65 - -#define IRQEN0 0xFE20 -#define IRQSTAT0 0xFE21 -#define IRQEN1 0xFE22 -#define IRQSTAT1 0xFE23 -#define TLPRIEN 0xFE24 -#define TLPRISTAT 0xFE25 -#define TLPTIEN 0xFE26 -#define TLPTISTAT 0xFE27 -#define DMATC0 0xFE28 -#define DMATC1 0xFE29 -#define DMATC2 0xFE2A -#define DMATC3 0xFE2B -#define DMACTL 0xFE2C -#define BCTL 0xFE2D -#define RBBC0 0xFE2E -#define RBBC1 0xFE2F -#define RBDAT 0xFE30 -#define RBCTL 0xFE34 -#define CFGADDR0 0xFE35 -#define CFGADDR1 0xFE36 -#define CFGDATA0 0xFE37 -#define CFGDATA1 0xFE38 -#define CFGDATA2 0xFE39 -#define CFGDATA3 0xFE3A -#define CFGRWCTL 0xFE3B -#define PHYRWCTL 0xFE3C -#define PHYDATA0 0xFE3D -#define PHYDATA1 0xFE3E -#define PHYADDR 0xFE3F -#define MSGRXDATA0 0xFE40 -#define MSGRXDATA1 0xFE41 -#define MSGRXDATA2 0xFE42 -#define MSGRXDATA3 0xFE43 -#define MSGTXDATA0 0xFE44 -#define MSGTXDATA1 0xFE45 -#define MSGTXDATA2 0xFE46 -#define MSGTXDATA3 0xFE47 -#define MSGTXCTL 0xFE48 -#define PETXCFG 0xFE49 - -#define CDRESUMECTL 0xFE52 -#define WAKE_SEL_CTL 0xFE54 -#define PME_FORCE_CTL 0xFE56 -#define ASPM_FORCE_CTL 0xFE57 -#define PM_CLK_FORCE_CTL 0xFE58 -#define PERST_GLITCH_WIDTH 0xFE5C -#define CHANGE_LINK_STATE 0xFE5B -#define RESET_LOAD_REG 0xFE5E -#define HOST_SLEEP_STATE 0xFE60 -#define MAIN_PWR_OFF_CTL 0xFE70 /* RTS5208 */ -#define SDIO_CFG 0xFE70 /* RTS5209 */ - -#define NFTS_TX_CTRL 0xFE72 - -#define PWR_GATE_CTRL 0xFE75 -#define PWD_SUSPEND_EN 0xFE76 - -#define EFUSE_CONTENT 0xFE5F - -#define XD_INIT 0xFD10 -#define XD_DTCTL 0xFD11 -#define XD_CTL 0xFD12 -#define XD_TRANSFER 0xFD13 -#define XD_CFG 0xFD14 -#define XD_ADDRESS0 0xFD15 -#define XD_ADDRESS1 0xFD16 -#define XD_ADDRESS2 0xFD17 -#define XD_ADDRESS3 0xFD18 -#define XD_ADDRESS4 0xFD19 -#define XD_DAT 0xFD1A -#define XD_PAGE_CNT 0xFD1B -#define XD_PAGE_STATUS 0xFD1C -#define XD_BLOCK_STATUS 0xFD1D -#define XD_BLOCK_ADDR1_L 0xFD1E -#define XD_BLOCK_ADDR1_H 0xFD1F -#define XD_BLOCK_ADDR2_L 0xFD20 -#define XD_BLOCK_ADDR2_H 0xFD21 -#define XD_BYTE_CNT_L 0xFD22 -#define XD_BYTE_CNT_H 0xFD23 -#define XD_PARITY 0xFD24 -#define XD_ECC_BIT1 0xFD25 -#define XD_ECC_BYTE1 0xFD26 -#define XD_ECC_BIT2 0xFD27 -#define XD_ECC_BYTE2 0xFD28 -#define XD_RESERVED0 0xFD29 -#define XD_RESERVED1 0xFD2A -#define XD_RESERVED2 0xFD2B -#define XD_RESERVED3 0xFD2C -#define XD_CHK_DATA_STATUS 0xFD2D -#define XD_CATCTL 0xFD2E - -#define MS_CFG 0xFD40 -#define MS_TPC 0xFD41 -#define MS_TRANS_CFG 0xFD42 -#define MS_TRANSFER 0xFD43 -#define MS_INT_REG 0xFD44 -#define MS_BYTE_CNT 0xFD45 -#define MS_SECTOR_CNT_L 0xFD46 -#define MS_SECTOR_CNT_H 0xFD47 -#define MS_DBUS_H 0xFD48 - -#define SSC_CTL1 0xFC11 -#define SSC_CTL2 0xFC12 - -#define OCPCTL 0xFC15 -#define OCPSTAT 0xFC16 -#define OCPCLR 0xFC17 /* 5208 */ -#define OCPGLITCH 0xFC17 /* 5209 */ -#define OCPPARA1 0xFC18 -#define OCPPARA2 0xFC19 - -#define EFUSE_OP 0xFC20 -#define EFUSE_CTRL 0xFC21 -#define EFUSE_DATA 0xFC22 - -#define SPI_COMMAND 0xFD80 -#define SPI_ADDR0 0xFD81 -#define SPI_ADDR1 0xFD82 -#define SPI_ADDR2 0xFD83 -#define SPI_ADDR3 0xFD84 -#define SPI_CA_NUMBER 0xFD85 -#define SPI_LENGTH0 0xFD86 -#define SPI_LENGTH1 0xFD87 -#define SPI_DATA 0xFD88 -#define SPI_DATA_NUMBER 0xFD89 -#define SPI_TRANSFER0 0xFD90 -#define SPI_TRANSFER1 0xFD91 -#define SPI_CONTROL 0xFD92 -#define SPI_SIG 0xFD93 -#define SPI_TCTL 0xFD94 -#define SPI_SLAVE_NUM 0xFD95 -#define SPI_CLK_DIVIDER0 0xFD96 -#define SPI_CLK_DIVIDER1 0xFD97 - -#define SRAM_BASE 0xE600 -#define RBUF_BASE 0xF400 -#define PPBUF_BASE1 0xF800 -#define PPBUF_BASE2 0xFA00 -#define IMAGE_FLAG_ADDR0 0xCE80 -#define IMAGE_FLAG_ADDR1 0xCE81 - -#define READ_OP 1 -#define WRITE_OP 2 - -#define LCTLR 0x80 - -#define POLLING_WAIT_CNT 1 -#define IDLE_MAX_COUNT 10 -#define SDIO_IDLE_COUNT 10 - -#define DEBOUNCE_CNT 5 - -void do_remaining_work(struct rtsx_chip *chip); -void try_to_switch_sdio_ctrl(struct rtsx_chip *chip); -void do_reset_sd_card(struct rtsx_chip *chip); -void do_reset_xd_card(struct rtsx_chip *chip); -void do_reset_ms_card(struct rtsx_chip *chip); -void rtsx_power_off_card(struct rtsx_chip *chip); -void rtsx_release_cards(struct rtsx_chip *chip); -void rtsx_reset_cards(struct rtsx_chip *chip); -void rtsx_reinit_cards(struct rtsx_chip *chip, int reset_chip); -void rtsx_init_cards(struct rtsx_chip *chip); -int switch_ssc_clock(struct rtsx_chip *chip, int clk); -int switch_normal_clock(struct rtsx_chip *chip, int clk); -int enable_card_clock(struct rtsx_chip *chip, u8 card); -int disable_card_clock(struct rtsx_chip *chip, u8 card); -int card_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt); -void trans_dma_enable(enum dma_data_direction dir, struct rtsx_chip *chip, u32 byte_cnt, u8 pack_size); -void toggle_gpio(struct rtsx_chip *chip, u8 gpio); -void turn_on_led(struct rtsx_chip *chip, u8 gpio); -void turn_off_led(struct rtsx_chip *chip, u8 gpio); - -int card_share_mode(struct rtsx_chip *chip, int card); -int select_card(struct rtsx_chip *chip, int card); -int detect_card_cd(struct rtsx_chip *chip, int card); -int check_card_exist(struct rtsx_chip *chip, unsigned int lun); -int check_card_ready(struct rtsx_chip *chip, unsigned int lun); -int check_card_wp(struct rtsx_chip *chip, unsigned int lun); -int check_card_fail(struct rtsx_chip *chip, unsigned int lun); -int check_card_ejected(struct rtsx_chip *chip, unsigned int lun); -void eject_card(struct rtsx_chip *chip, unsigned int lun); -u8 get_lun_card(struct rtsx_chip *chip, unsigned int lun); - -static inline u32 get_card_size(struct rtsx_chip *chip, unsigned int lun) -{ -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &(chip->sd_card); - - if ((get_lun_card(chip, lun) == SD_CARD) && (sd_card->sd_lock_status & SD_LOCKED)) - return 0; - else - return chip->capacity[lun]; -#else - return chip->capacity[lun]; -#endif -} - -static inline int switch_clock(struct rtsx_chip *chip, int clk) -{ - int retval = 0; - - if (chip->asic_code) - retval = switch_ssc_clock(chip, clk); - else - retval = switch_normal_clock(chip, clk); - - return retval; -} - -int card_power_on(struct rtsx_chip *chip, u8 card); -int card_power_off(struct rtsx_chip *chip, u8 card); - -static inline int card_power_off_all(struct rtsx_chip *chip) -{ - RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0x0F, 0x0F); - - return STATUS_SUCCESS; -} - -static inline void rtsx_clear_xd_error(struct rtsx_chip *chip) -{ - rtsx_write_register(chip, CARD_STOP, XD_STOP | XD_CLR_ERR, XD_STOP | XD_CLR_ERR); -} - -static inline void rtsx_clear_sd_error(struct rtsx_chip *chip) -{ - rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR); -} - -static inline void rtsx_clear_ms_error(struct rtsx_chip *chip) -{ - rtsx_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR); -} - -static inline void rtsx_clear_spi_error(struct rtsx_chip *chip) -{ - rtsx_write_register(chip, CARD_STOP, SPI_STOP | SPI_CLR_ERR, SPI_STOP | SPI_CLR_ERR); -} - -#ifdef SUPPORT_SDIO_ASPM -void dynamic_configure_sdio_aspm(struct rtsx_chip *chip); -#endif - -#endif /* __REALTEK_RTSX_CARD_H */ diff --git a/drivers/staging/rts_pstor/rtsx_chip.c b/drivers/staging/rts_pstor/rtsx_chip.c deleted file mode 100644 index d8e691b9902..00000000000 --- a/drivers/staging/rts_pstor/rtsx_chip.c +++ /dev/null @@ -1,2264 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include -#include - -#include "rtsx.h" -#include "rtsx_transport.h" -#include "rtsx_scsi.h" -#include "rtsx_card.h" -#include "rtsx_chip.h" -#include "rtsx_sys.h" -#include "general.h" - -#include "sd.h" -#include "xd.h" -#include "ms.h" - -static void rtsx_calibration(struct rtsx_chip *chip) -{ - rtsx_write_phy_register(chip, 0x1B, 0x135E); - wait_timeout(10); - rtsx_write_phy_register(chip, 0x00, 0x0280); - rtsx_write_phy_register(chip, 0x01, 0x7112); - rtsx_write_phy_register(chip, 0x01, 0x7110); - rtsx_write_phy_register(chip, 0x01, 0x7112); - rtsx_write_phy_register(chip, 0x01, 0x7113); - rtsx_write_phy_register(chip, 0x00, 0x0288); -} - -void rtsx_disable_card_int(struct rtsx_chip *chip) -{ - u32 reg = rtsx_readl(chip, RTSX_BIER); - - reg &= ~(XD_INT_EN | SD_INT_EN | MS_INT_EN); - rtsx_writel(chip, RTSX_BIER, reg); -} - -void rtsx_enable_card_int(struct rtsx_chip *chip) -{ - u32 reg = rtsx_readl(chip, RTSX_BIER); - int i; - - for (i = 0; i <= chip->max_lun; i++) { - if (chip->lun2card[i] & XD_CARD) - reg |= XD_INT_EN; - if (chip->lun2card[i] & SD_CARD) - reg |= SD_INT_EN; - if (chip->lun2card[i] & MS_CARD) - reg |= MS_INT_EN; - } - if (chip->hw_bypass_sd) - reg &= ~((u32)SD_INT_EN); - - rtsx_writel(chip, RTSX_BIER, reg); -} - -void rtsx_enable_bus_int(struct rtsx_chip *chip) -{ - u32 reg = 0; -#ifndef DISABLE_CARD_INT - int i; -#endif - - reg = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN; - -#ifndef DISABLE_CARD_INT - for (i = 0; i <= chip->max_lun; i++) { - RTSX_DEBUGP("lun2card[%d] = 0x%02x\n", i, chip->lun2card[i]); - - if (chip->lun2card[i] & XD_CARD) - reg |= XD_INT_EN; - if (chip->lun2card[i] & SD_CARD) - reg |= SD_INT_EN; - if (chip->lun2card[i] & MS_CARD) - reg |= MS_INT_EN; - } - if (chip->hw_bypass_sd) - reg &= ~((u32)SD_INT_EN); -#endif - - if (chip->ic_version >= IC_VER_C) - reg |= DELINK_INT_EN; -#ifdef SUPPORT_OCP - if (CHECK_PID(chip, 0x5209)) { - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - reg |= MS_OC_INT_EN | SD_OC_INT_EN; - else - reg |= SD_OC_INT_EN; - } else { - reg |= OC_INT_EN; - } -#endif - if (!chip->adma_mode) - reg |= DATA_DONE_INT_EN; - - /* Enable Bus Interrupt */ - rtsx_writel(chip, RTSX_BIER, reg); - - RTSX_DEBUGP("RTSX_BIER: 0x%08x\n", reg); -} - -void rtsx_disable_bus_int(struct rtsx_chip *chip) -{ - rtsx_writel(chip, RTSX_BIER, 0); -} - -static int rtsx_pre_handle_sdio_old(struct rtsx_chip *chip) -{ - if (chip->ignore_sd && CHK_SDIO_EXIST(chip)) { - if (chip->asic_code) { - RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU); - } else { - RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF, FPGA_SD_PULL_CTL_EN); - } - RTSX_WRITE_REG(chip, CARD_SHARE_MODE, 0xFF, CARD_SHARE_48_SD); - - /* Enable SDIO internal clock */ - RTSX_WRITE_REG(chip, 0xFF2C, 0x01, 0x01); - - RTSX_WRITE_REG(chip, SDIO_CTRL, 0xFF, SDIO_BUS_CTRL | SDIO_CD_CTRL); - - chip->sd_int = 1; - chip->sd_io = 1; - } else { - chip->need_reset |= SD_CARD; - } - - return STATUS_SUCCESS; -} - -#ifdef HW_AUTO_SWITCH_SD_BUS -static int rtsx_pre_handle_sdio_new(struct rtsx_chip *chip) -{ - u8 tmp; - int sw_bypass_sd = 0; - int retval; - - if (chip->driver_first_load) { - if (CHECK_PID(chip, 0x5288)) { - RTSX_READ_REG(chip, 0xFE5A, &tmp); - if (tmp & 0x08) - sw_bypass_sd = 1; - } else if (CHECK_PID(chip, 0x5208)) { - RTSX_READ_REG(chip, 0xFE70, &tmp); - if (tmp & 0x80) - sw_bypass_sd = 1; - } else if (CHECK_PID(chip, 0x5209)) { - RTSX_READ_REG(chip, SDIO_CFG, &tmp); - if (tmp & SDIO_BUS_AUTO_SWITCH) - sw_bypass_sd = 1; - } - } else { - if (chip->sdio_in_charge) - sw_bypass_sd = 1; - } - RTSX_DEBUGP("chip->sdio_in_charge = %d\n", chip->sdio_in_charge); - RTSX_DEBUGP("chip->driver_first_load = %d\n", chip->driver_first_load); - RTSX_DEBUGP("sw_bypass_sd = %d\n", sw_bypass_sd); - - if (sw_bypass_sd) { - u8 cd_toggle_mask = 0; - - RTSX_READ_REG(chip, TLPTISTAT, &tmp); - if (CHECK_PID(chip, 0x5209)) - cd_toggle_mask = 0x10; - else - cd_toggle_mask = 0x08; - - if (tmp & cd_toggle_mask) { - /* Disable sdio_bus_auto_switch */ - if (CHECK_PID(chip, 0x5288)) - RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x00); - else if (CHECK_PID(chip, 0x5208)) - RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x00); - else - RTSX_WRITE_REG(chip, SDIO_CFG, SDIO_BUS_AUTO_SWITCH, 0); - - RTSX_WRITE_REG(chip, TLPTISTAT, 0xFF, tmp); - - chip->need_reset |= SD_CARD; - } else { - RTSX_DEBUGP("Chip inserted with SDIO!\n"); - - if (chip->asic_code) { - retval = sd_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20, 0); - } - retval = card_share_mode(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - /* Enable sdio_bus_auto_switch */ - if (CHECK_PID(chip, 0x5288)) { - RTSX_WRITE_REG(chip, 0xFE5A, 0x08, 0x08); - } else if (CHECK_PID(chip, 0x5208)) { - RTSX_WRITE_REG(chip, 0xFE70, 0x80, 0x80); - } else { - RTSX_WRITE_REG(chip, SDIO_CFG, - SDIO_BUS_AUTO_SWITCH, SDIO_BUS_AUTO_SWITCH); - } - chip->chip_insert_with_sdio = 1; - chip->sd_io = 1; - } - } else { - if (CHECK_PID(chip, 0x5209)) - RTSX_WRITE_REG(chip, TLPTISTAT, 0x10, 0x10); - else - RTSX_WRITE_REG(chip, TLPTISTAT, 0x08, 0x08); - - chip->need_reset |= SD_CARD; - } - - return STATUS_SUCCESS; -} -#endif - -int rtsx_reset_chip(struct rtsx_chip *chip) -{ - int retval; - - rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); - - rtsx_disable_aspm(chip); - - if (CHECK_PID(chip, 0x5209) && chip->asic_code) { - u16 val; - - /* optimize PHY */ - retval = rtsx_write_phy_register(chip, 0x00, 0xB966); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_write_phy_register(chip, 0x01, 0x713F); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_write_phy_register(chip, 0x03, 0xA549); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_write_phy_register(chip, 0x06, 0xB235); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_write_phy_register(chip, 0x07, 0xEF40); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_write_phy_register(chip, 0x1E, 0xF8EB); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_write_phy_register(chip, 0x19, 0xFE6C); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - wait_timeout(1); - retval = rtsx_write_phy_register(chip, 0x0A, 0x05C0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - - retval = rtsx_write_cfg_dw(chip, 1, 0x110, 0xFFFF, 0xFFFF); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_read_phy_register(chip, 0x08, &val); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_DEBUGP("Read from phy 0x08: 0x%04x\n", val); - - if (chip->phy_voltage) { - chip->phy_voltage &= 0x3F; - RTSX_DEBUGP("chip->phy_voltage = 0x%x\n", chip->phy_voltage); - val &= ~0x3F; - val |= chip->phy_voltage; - RTSX_DEBUGP("Write to phy 0x08: 0x%04x\n", val); - retval = rtsx_write_phy_register(chip, 0x08, val); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - } else { - chip->phy_voltage = (u8)(val & 0x3F); - RTSX_DEBUGP("Default, chip->phy_voltage = 0x%x\n", chip->phy_voltage); - } - } - - RTSX_WRITE_REG(chip, HOST_SLEEP_STATE, 0x03, 0x00); - - /* Disable card clock */ - RTSX_WRITE_REG(chip, CARD_CLK_EN, 0x1E, 0); - -#ifdef SUPPORT_OCP - /* SSC power on, OCD power on */ - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, 0); - else - RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, MS_OC_POWER_DOWN); - - if (CHECK_PID(chip, 0x5209)) { - RTSX_WRITE_REG(chip, OCPPARA1, SD_OCP_TIME_MASK | MS_OCP_TIME_MASK, - SD_OCP_TIME_800 | MS_OCP_TIME_800); - RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK | MS_OCP_THD_MASK, - chip->sd_400mA_ocp_thd | (chip->ms_ocp_thd << 4)); - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - RTSX_WRITE_REG(chip, OCPGLITCH, SD_OCP_GLITCH_MASK | MS_OCP_GLITCH_MASK, - SD_OCP_GLITCH_10000 | MS_OCP_GLITCH_10000); - } else { - RTSX_WRITE_REG(chip, OCPGLITCH, SD_OCP_GLITCH_MASK, SD_OCP_GLITCH_10000); - } - RTSX_WRITE_REG(chip, OCPCTL, 0xFF, - SD_OCP_INT_EN | SD_DETECT_EN | MS_OCP_INT_EN | MS_DETECT_EN); - } else { - RTSX_WRITE_REG(chip, OCPPARA1, OCP_TIME_MASK, OCP_TIME_800); - RTSX_WRITE_REG(chip, OCPPARA2, OCP_THD_MASK, OCP_THD_244_946); - RTSX_WRITE_REG(chip, OCPCTL, 0xFF, CARD_OC_INT_EN | CARD_DETECT_EN); - } -#else - /* OC power down */ - RTSX_WRITE_REG(chip, FPDCTL, OC_POWER_DOWN, OC_POWER_DOWN); -#endif - - if (!CHECK_PID(chip, 0x5288)) - RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0xFF, 0x03); - - /* Turn off LED */ - RTSX_WRITE_REG(chip, CARD_GPIO, 0xFF, 0x03); - - /* Reset delink mode */ - RTSX_WRITE_REG(chip, CHANGE_LINK_STATE, 0x0A, 0); - - /* Card driving select */ - RTSX_WRITE_REG(chip, CARD_DRIVE_SEL, 0xFF, chip->card_drive_sel); - if (CHECK_PID(chip, 0x5209)) - RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_3v3); - -#ifdef LED_AUTO_BLINK - RTSX_WRITE_REG(chip, CARD_AUTO_BLINK, 0xFF, - LED_BLINK_SPEED | BLINK_EN | LED_GPIO0); -#endif - - if (chip->asic_code) { - /* Enable SSC Clock */ - RTSX_WRITE_REG(chip, SSC_CTL1, 0xFF, SSC_8X_EN | SSC_SEL_4M); - RTSX_WRITE_REG(chip, SSC_CTL2, 0xFF, 0x12); - } - - /* Disable cd_pwr_save (u_force_rst_core_en=0, u_cd_rst_core_en=0) - 0xFE5B - bit[1] u_cd_rst_core_en rst_value = 0 - bit[2] u_force_rst_core_en rst_value = 0 - bit[5] u_mac_phy_rst_n_dbg rst_value = 1 - bit[4] u_non_sticky_rst_n_dbg rst_value = 0 - */ - RTSX_WRITE_REG(chip, CHANGE_LINK_STATE, 0x16, 0x10); - - /* Enable ASPM */ - if (chip->aspm_l0s_l1_en) { - if (chip->dynamic_aspm) { - if (CHK_SDIO_EXIST(chip)) { - if (CHECK_PID(chip, 0x5209)) { - retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - } else if (CHECK_PID(chip, 0x5288)) { - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - } - } else { - if (CHECK_PID(chip, 0x5208)) - RTSX_WRITE_REG(chip, ASPM_FORCE_CTL, 0xFF, 0x3F); - - retval = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - chip->aspm_level[0] = chip->aspm_l0s_l1_en; - if (CHK_SDIO_EXIST(chip)) { - chip->aspm_level[1] = chip->aspm_l0s_l1_en; - if (CHECK_PID(chip, 0x5288)) - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF, chip->aspm_l0s_l1_en); - else - retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF, chip->aspm_l0s_l1_en); - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - } - - chip->aspm_enabled = 1; - } - } else { - if (chip->asic_code && CHECK_PID(chip, 0x5208)) { - retval = rtsx_write_phy_register(chip, 0x07, 0x0129); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - retval = rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - retval = rtsx_write_config_byte(chip, 0x81, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHK_SDIO_EXIST(chip)) { - if (CHECK_PID(chip, 0x5288)) - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100); - else - retval = rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100); - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - } - - if (CHECK_PID(chip, 0x5209)) { - retval = rtsx_write_cfg_dw(chip, 0, 0x70C, 0xFF000000, 0x5B); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - if (CHECK_PID(chip, 0x5288)) { - if (!CHK_SDIO_EXIST(chip)) { - retval = rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, 0x0103); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_write_cfg_dw(chip, 2, 0x84, 0xFF, 0x03); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - } - } - - RTSX_WRITE_REG(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); - - RTSX_WRITE_REG(chip, PERST_GLITCH_WIDTH, 0xFF, 0x80); - - if (CHECK_PID(chip, 0x5209)) { - RTSX_WRITE_REG(chip, PWD_SUSPEND_EN, 0xFF, 0xFF); - RTSX_WRITE_REG(chip, PWR_GATE_CTRL, PWR_GATE_EN, PWR_GATE_EN); - } - - /* Enable PCIE interrupt */ - if (chip->asic_code) { - if (CHECK_PID(chip, 0x5208)) { - if (chip->phy_debug_mode) { - RTSX_WRITE_REG(chip, CDRESUMECTL, 0x77, 0); - rtsx_disable_bus_int(chip); - } else { - rtsx_enable_bus_int(chip); - } - - if (chip->ic_version >= IC_VER_D) { - u16 reg; - retval = rtsx_read_phy_register(chip, 0x00, ®); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - reg &= 0xFE7F; - reg |= 0x80; - retval = rtsx_write_phy_register(chip, 0x00, reg); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - reg &= 0xFFF7; - retval = rtsx_write_phy_register(chip, 0x1C, reg); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - } - - if (chip->driver_first_load && (chip->ic_version < IC_VER_C)) - rtsx_calibration(chip); - - } else { - rtsx_enable_bus_int(chip); - } - } else { - rtsx_enable_bus_int(chip); - } - -#ifdef HW_INT_WRITE_CLR - if (CHECK_PID(chip, 0x5209)) { - /* Set interrupt write clear */ - RTSX_WRITE_REG(chip, NFTS_TX_CTRL, 0x02, 0); - } -#endif - - chip->need_reset = 0; - - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); -#ifdef HW_INT_WRITE_CLR - if (CHECK_PID(chip, 0x5209)) { - /* Clear interrupt flag */ - rtsx_writel(chip, RTSX_BIPR, chip->int_reg); - } -#endif - if (chip->hw_bypass_sd) - goto NextCard; - RTSX_DEBUGP("In rtsx_reset_chip, chip->int_reg = 0x%x\n", chip->int_reg); - if (chip->int_reg & SD_EXIST) { -#ifdef HW_AUTO_SWITCH_SD_BUS - if (CHECK_PID(chip, 0x5208) && (chip->ic_version < IC_VER_C)) - retval = rtsx_pre_handle_sdio_old(chip); - else - retval = rtsx_pre_handle_sdio_new(chip); - - RTSX_DEBUGP("chip->need_reset = 0x%x (rtsx_reset_chip)\n", (unsigned int)(chip->need_reset)); -#else /* HW_AUTO_SWITCH_SD_BUS */ - retval = rtsx_pre_handle_sdio_old(chip); -#endif /* HW_AUTO_SWITCH_SD_BUS */ - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - } else { - chip->sd_io = 0; - RTSX_WRITE_REG(chip, SDIO_CTRL, SDIO_BUS_CTRL | SDIO_CD_CTRL, 0); - } - -NextCard: - if (chip->int_reg & XD_EXIST) - chip->need_reset |= XD_CARD; - if (chip->int_reg & MS_EXIST) - chip->need_reset |= MS_CARD; - if (chip->int_reg & CARD_EXIST) - RTSX_WRITE_REG(chip, SSC_CTL1, SSC_RSTB, SSC_RSTB); - - RTSX_DEBUGP("In rtsx_init_chip, chip->need_reset = 0x%x\n", (unsigned int)(chip->need_reset)); - - RTSX_WRITE_REG(chip, RCCTL, 0x01, 0x00); - - if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) { - /* Turn off main power when entering S3/S4 state */ - RTSX_WRITE_REG(chip, MAIN_PWR_OFF_CTL, 0x03, 0x03); - } - - if (chip->remote_wakeup_en && !chip->auto_delink_en) { - RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x07); - if (chip->aux_pwr_exist) - RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x33); - } else { - RTSX_WRITE_REG(chip, WAKE_SEL_CTL, 0x07, 0x04); - RTSX_WRITE_REG(chip, PME_FORCE_CTL, 0xFF, 0x30); - } - - if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D)) { - RTSX_WRITE_REG(chip, PETXCFG, 0x1C, 0x14); - } else if (CHECK_PID(chip, 0x5209)) { - if (chip->force_clkreq_0) - RTSX_WRITE_REG(chip, PETXCFG, 0x08, 0x08); - else - RTSX_WRITE_REG(chip, PETXCFG, 0x08, 0x00); - } - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) { - retval = rtsx_clr_phy_reg_bit(chip, 0x1C, 2); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - if (chip->ft2_fast_mode) { - RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, MS_PARTIAL_POWER_ON | SD_PARTIAL_POWER_ON); - udelay(chip->pmos_pwr_on_interval); - RTSX_WRITE_REG(chip, CARD_PWR_CTL, 0xFF, MS_POWER_ON | SD_POWER_ON); - - wait_timeout(200); - } - - /* Reset card */ - rtsx_reset_detected_cards(chip, 0); - - chip->driver_first_load = 0; - - return STATUS_SUCCESS; -} - -static inline int check_sd_speed_prior(u32 sd_speed_prior) -{ - int i, fake_para = 0; - - for (i = 0; i < 4; i++) { - u8 tmp = (u8)(sd_speed_prior >> (i*8)); - if ((tmp < 0x01) || (tmp > 0x04)) { - fake_para = 1; - break; - } - } - - return !fake_para; -} - -static inline int check_sd_current_prior(u32 sd_current_prior) -{ - int i, fake_para = 0; - - for (i = 0; i < 4; i++) { - u8 tmp = (u8)(sd_current_prior >> (i*8)); - if (tmp > 0x03) { - fake_para = 1; - break; - } - } - - return !fake_para; -} - -static int rts5209_init(struct rtsx_chip *chip) -{ - int retval; - u32 lval = 0; - u8 val = 0; - - val = rtsx_readb(chip, 0x1C); - if ((val & 0x10) == 0) - chip->asic_code = 1; - else - chip->asic_code = 0; - - chip->ic_version = val & 0x0F; - chip->phy_debug_mode = 0; - - chip->aux_pwr_exist = 0; - - chip->ms_power_class_en = 0x03; - - retval = rtsx_read_cfg_dw(chip, 0, 0x724, &lval); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_DEBUGP("dw in 0x724: 0x%x\n", lval); - val = (u8)lval; - if (!(val & 0x80)) { - if (val & 0x08) - chip->lun_mode = DEFAULT_SINGLE; - else - chip->lun_mode = SD_MS_2LUN; - - if (val & 0x04) - SET_SDIO_EXIST(chip); - else - CLR_SDIO_EXIST(chip); - - if (val & 0x02) - chip->hw_bypass_sd = 0; - else - chip->hw_bypass_sd = 1; - - } else { - SET_SDIO_EXIST(chip); - chip->hw_bypass_sd = 0; - } - - if (chip->use_hw_setting) { - u8 clk; - - chip->aspm_l0s_l1_en = (val >> 5) & 0x03; - - val = (u8)(lval >> 8); - - clk = (val >> 5) & 0x07; - if (clk != 0x07) - chip->asic_sd_sdr50_clk = 98 - clk * 2; - - if (val & 0x10) - chip->auto_delink_en = 1; - else - chip->auto_delink_en = 0; - - if (chip->ss_en == 2) { - chip->ss_en = 0; - } else { - if (val & 0x08) - chip->ss_en = 1; - else - chip->ss_en = 0; - } - - clk = val & 0x07; - if (clk != 0x07) - chip->asic_ms_hg_clk = (59 - clk) * 2; - - val = (u8)(lval >> 16); - - clk = (val >> 6) & 0x03; - if (clk != 0x03) { - chip->asic_sd_hs_clk = (49 - clk * 2) * 2; - chip->asic_mmc_52m_clk = (49 - clk * 2) * 2; - } - - clk = (val >> 4) & 0x03; - if (clk != 0x03) - chip->asic_sd_ddr50_clk = (48 - clk * 2) * 2; - - if (val & 0x01) - chip->sdr104_en = 1; - else - chip->sdr104_en = 0; - - if (val & 0x02) - chip->ddr50_en = 1; - else - chip->ddr50_en = 0; - - if (val & 0x04) - chip->sdr50_en = 1; - else - chip->sdr50_en = 0; - - - val = (u8)(lval >> 24); - - clk = (val >> 5) & 0x07; - if (clk != 0x07) - chip->asic_sd_sdr104_clk = 206 - clk * 3; - - if (val & 0x10) - chip->power_down_in_ss = 1; - else - chip->power_down_in_ss = 0; - - chip->ms_power_class_en = val & 0x03; - } - - if (chip->hp_watch_bios_hotplug && chip->auto_delink_en) { - u8 reg58, reg5b; - - retval = rtsx_read_pci_cfg_byte(0x00, - 0x1C, 0x02, 0x58, ®58); - if (retval < 0) - return STATUS_SUCCESS; - - retval = rtsx_read_pci_cfg_byte(0x00, - 0x1C, 0x02, 0x5B, ®5b); - if (retval < 0) - return STATUS_SUCCESS; - - RTSX_DEBUGP("reg58 = 0x%x, reg5b = 0x%x\n", reg58, reg5b); - - if ((reg58 == 0x00) && (reg5b == 0x01)) - chip->auto_delink_en = 0; - - } - - return STATUS_SUCCESS; -} - -static int rts5208_init(struct rtsx_chip *chip) -{ - int retval; - u16 reg = 0; - u8 val = 0; - - RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); - RTSX_READ_REG(chip, CLK_SEL, &val); - if (val == 0) - chip->asic_code = 1; - else - chip->asic_code = 0; - - if (chip->asic_code) { - retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_DEBUGP("Value of phy register 0x1C is 0x%x\n", reg); - chip->ic_version = (reg >> 4) & 0x07; - if (reg & PHY_DEBUG_MODE) - chip->phy_debug_mode = 1; - else - chip->phy_debug_mode = 0; - - } else { - RTSX_READ_REG(chip, 0xFE80, &val); - chip->ic_version = val; - chip->phy_debug_mode = 0; - } - - RTSX_READ_REG(chip, PDINFO, &val); - RTSX_DEBUGP("PDINFO: 0x%x\n", val); - if (val & AUX_PWR_DETECTED) - chip->aux_pwr_exist = 1; - else - chip->aux_pwr_exist = 0; - - RTSX_READ_REG(chip, 0xFE50, &val); - if (val & 0x01) - chip->hw_bypass_sd = 1; - else - chip->hw_bypass_sd = 0; - - rtsx_read_config_byte(chip, 0x0E, &val); - if (val & 0x80) - SET_SDIO_EXIST(chip); - else - CLR_SDIO_EXIST(chip); - - if (chip->use_hw_setting) { - RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val); - if (val & 0x80) - chip->auto_delink_en = 1; - else - chip->auto_delink_en = 0; - } - - return STATUS_SUCCESS; -} - -static int rts5288_init(struct rtsx_chip *chip) -{ - int retval; - u8 val = 0, max_func; - u32 lval = 0; - - RTSX_WRITE_REG(chip, CLK_SEL, 0x03, 0x03); - RTSX_READ_REG(chip, CLK_SEL, &val); - if (val == 0) - chip->asic_code = 1; - else - chip->asic_code = 0; - - chip->ic_version = 0; - chip->phy_debug_mode = 0; - - RTSX_READ_REG(chip, PDINFO, &val); - RTSX_DEBUGP("PDINFO: 0x%x\n", val); - if (val & AUX_PWR_DETECTED) - chip->aux_pwr_exist = 1; - else - chip->aux_pwr_exist = 0; - - RTSX_READ_REG(chip, CARD_SHARE_MODE, &val); - RTSX_DEBUGP("CARD_SHARE_MODE: 0x%x\n", val); - if (val & 0x04) - chip->baro_pkg = QFN; - else - chip->baro_pkg = LQFP; - - RTSX_READ_REG(chip, 0xFE5A, &val); - if (val & 0x10) - chip->hw_bypass_sd = 1; - else - chip->hw_bypass_sd = 0; - - retval = rtsx_read_cfg_dw(chip, 0, 0x718, &lval); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - max_func = (u8)((lval >> 29) & 0x07); - RTSX_DEBUGP("Max function number: %d\n", max_func); - if (max_func == 0x02) - SET_SDIO_EXIST(chip); - else - CLR_SDIO_EXIST(chip); - - if (chip->use_hw_setting) { - RTSX_READ_REG(chip, CHANGE_LINK_STATE, &val); - if (val & 0x80) - chip->auto_delink_en = 1; - else - chip->auto_delink_en = 0; - - if (CHECK_BARO_PKG(chip, LQFP)) - chip->lun_mode = SD_MS_1LUN; - else - chip->lun_mode = DEFAULT_SINGLE; - - } - - return STATUS_SUCCESS; -} - -int rtsx_init_chip(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - struct xd_info *xd_card = &(chip->xd_card); - struct ms_info *ms_card = &(chip->ms_card); - int retval; - unsigned int i; - - RTSX_DEBUGP("Vendor ID: 0x%04x, Product ID: 0x%04x\n", - chip->vendor_id, chip->product_id); - - chip->ic_version = 0; - -#ifdef _MSG_TRACE - chip->msg_idx = 0; -#endif - - memset(xd_card, 0, sizeof(struct xd_info)); - memset(sd_card, 0, sizeof(struct sd_info)); - memset(ms_card, 0, sizeof(struct ms_info)); - - chip->xd_reset_counter = 0; - chip->sd_reset_counter = 0; - chip->ms_reset_counter = 0; - - chip->xd_show_cnt = MAX_SHOW_CNT; - chip->sd_show_cnt = MAX_SHOW_CNT; - chip->ms_show_cnt = MAX_SHOW_CNT; - - chip->sd_io = 0; - chip->auto_delink_cnt = 0; - chip->auto_delink_allowed = 1; - rtsx_set_stat(chip, RTSX_STAT_INIT); - - chip->aspm_enabled = 0; - chip->chip_insert_with_sdio = 0; - chip->sdio_aspm = 0; - chip->sdio_idle = 0; - chip->sdio_counter = 0; - chip->cur_card = 0; - chip->phy_debug_mode = 0; - chip->sdio_func_exist = 0; - memset(chip->sdio_raw_data, 0, 12); - - for (i = 0; i < MAX_ALLOWED_LUN_CNT; i++) { - set_sense_type(chip, i, SENSE_TYPE_NO_SENSE); - chip->rw_fail_cnt[i] = 0; - } - - if (!check_sd_speed_prior(chip->sd_speed_prior)) - chip->sd_speed_prior = 0x01040203; - - RTSX_DEBUGP("sd_speed_prior = 0x%08x\n", chip->sd_speed_prior); - - if (!check_sd_current_prior(chip->sd_current_prior)) - chip->sd_current_prior = 0x00010203; - - RTSX_DEBUGP("sd_current_prior = 0x%08x\n", chip->sd_current_prior); - - if ((chip->sd_ddr_tx_phase > 31) || (chip->sd_ddr_tx_phase < 0)) - chip->sd_ddr_tx_phase = 0; - - if ((chip->mmc_ddr_tx_phase > 31) || (chip->mmc_ddr_tx_phase < 0)) - chip->mmc_ddr_tx_phase = 0; - - RTSX_WRITE_REG(chip, FPDCTL, SSC_POWER_DOWN, 0); - wait_timeout(200); - RTSX_WRITE_REG(chip, CLK_DIV, 0x07, 0x07); - RTSX_DEBUGP("chip->use_hw_setting = %d\n", chip->use_hw_setting); - - if (CHECK_PID(chip, 0x5209)) { - retval = rts5209_init(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - } else if (CHECK_PID(chip, 0x5208)) { - retval = rts5208_init(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - } else if (CHECK_PID(chip, 0x5288)) { - retval = rts5288_init(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - } - - if (chip->ss_en == 2) - chip->ss_en = 0; - - RTSX_DEBUGP("chip->asic_code = %d\n", chip->asic_code); - RTSX_DEBUGP("chip->ic_version = 0x%x\n", chip->ic_version); - RTSX_DEBUGP("chip->phy_debug_mode = %d\n", chip->phy_debug_mode); - RTSX_DEBUGP("chip->aux_pwr_exist = %d\n", chip->aux_pwr_exist); - RTSX_DEBUGP("chip->sdio_func_exist = %d\n", chip->sdio_func_exist); - RTSX_DEBUGP("chip->hw_bypass_sd = %d\n", chip->hw_bypass_sd); - RTSX_DEBUGP("chip->aspm_l0s_l1_en = %d\n", chip->aspm_l0s_l1_en); - RTSX_DEBUGP("chip->lun_mode = %d\n", chip->lun_mode); - RTSX_DEBUGP("chip->auto_delink_en = %d\n", chip->auto_delink_en); - RTSX_DEBUGP("chip->ss_en = %d\n", chip->ss_en); - RTSX_DEBUGP("chip->baro_pkg = %d\n", chip->baro_pkg); - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - chip->card2lun[SD_CARD] = 0; - chip->card2lun[MS_CARD] = 1; - chip->card2lun[XD_CARD] = 0xFF; - chip->lun2card[0] = SD_CARD; - chip->lun2card[1] = MS_CARD; - chip->max_lun = 1; - SET_SDIO_IGNORED(chip); - } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) { - chip->card2lun[SD_CARD] = 0; - chip->card2lun[MS_CARD] = 0; - chip->card2lun[XD_CARD] = 0xFF; - chip->lun2card[0] = SD_CARD | MS_CARD; - chip->max_lun = 0; - } else { - chip->card2lun[XD_CARD] = 0; - chip->card2lun[SD_CARD] = 0; - chip->card2lun[MS_CARD] = 0; - chip->lun2card[0] = XD_CARD | SD_CARD | MS_CARD; - chip->max_lun = 0; - } - - retval = rtsx_reset_chip(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -void rtsx_release_chip(struct rtsx_chip *chip) -{ - xd_free_l2p_tbl(chip); - ms_free_l2p_tbl(chip); - chip->card_exist = 0; - chip->card_ready = 0; -} - -#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) -static inline void rtsx_blink_led(struct rtsx_chip *chip) -{ - if (chip->card_exist && chip->blink_led) { - if (chip->led_toggle_counter < LED_TOGGLE_INTERVAL) { - chip->led_toggle_counter++; - } else { - chip->led_toggle_counter = 0; - toggle_gpio(chip, LED_GPIO); - } - } -} -#endif - -static void rtsx_monitor_aspm_config(struct rtsx_chip *chip) -{ - int maybe_support_aspm, reg_changed; - u32 tmp = 0; - u8 reg0 = 0, reg1 = 0; - - maybe_support_aspm = 0; - reg_changed = 0; - rtsx_read_config_byte(chip, LCTLR, ®0); - if (chip->aspm_level[0] != reg0) { - reg_changed = 1; - chip->aspm_level[0] = reg0; - } - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { - rtsx_read_cfg_dw(chip, 1, 0xC0, &tmp); - reg1 = (u8)tmp; - if (chip->aspm_level[1] != reg1) { - reg_changed = 1; - chip->aspm_level[1] = reg1; - } - - if ((reg0 & 0x03) && (reg1 & 0x03)) - maybe_support_aspm = 1; - - } else { - if (reg0 & 0x03) - maybe_support_aspm = 1; - - } - - if (reg_changed) { - if (maybe_support_aspm) - chip->aspm_l0s_l1_en = 0x03; - - RTSX_DEBUGP("aspm_level[0] = 0x%02x, aspm_level[1] = 0x%02x\n", - chip->aspm_level[0], chip->aspm_level[1]); - - if (chip->aspm_l0s_l1_en) { - chip->aspm_enabled = 1; - } else { - chip->aspm_enabled = 0; - chip->sdio_aspm = 0; - } - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xFF, - 0x30 | chip->aspm_level[0] | (chip->aspm_level[1] << 2)); - } -} - -void rtsx_polling_func(struct rtsx_chip *chip) -{ -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &(chip->sd_card); -#endif - int ss_allowed; - - if (rtsx_chk_stat(chip, RTSX_STAT_SUSPEND)) - return; - - if (rtsx_chk_stat(chip, RTSX_STAT_DELINK)) - goto Delink_Stage; - - if (chip->polling_config) { - u8 val; - rtsx_read_config_byte(chip, 0, &val); - } - - if (rtsx_chk_stat(chip, RTSX_STAT_SS)) - return; - -#ifdef SUPPORT_OCP - if (chip->ocp_int) { - rtsx_read_register(chip, OCPSTAT, &(chip->ocp_stat)); - - if (CHECK_PID(chip, 0x5209) && - CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->ocp_int & SD_OC_INT) - sd_power_off_card3v3(chip); - if (chip->ocp_int & MS_OC_INT) - ms_power_off_card3v3(chip); - } else { - if (chip->card_exist & SD_CARD) - sd_power_off_card3v3(chip); - else if (chip->card_exist & MS_CARD) - ms_power_off_card3v3(chip); - else if (chip->card_exist & XD_CARD) - xd_power_off_card3v3(chip); - - } - - chip->ocp_int = 0; - } -#endif - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_erase_status) { - if (chip->card_exist & SD_CARD) { - u8 val; - if (CHECK_PID(chip, 0x5209)) { - rtsx_read_register(chip, SD_BUS_STAT, &val); - if (val & SD_DAT0_STATUS) { - sd_card->sd_erase_status = SD_NOT_ERASE; - sd_card->sd_lock_notify = 1; - chip->need_reinit |= SD_CARD; - } - } else { - rtsx_read_register(chip, 0xFD30, &val); - if (val & 0x02) { - sd_card->sd_erase_status = SD_NOT_ERASE; - sd_card->sd_lock_notify = 1; - chip->need_reinit |= SD_CARD; - } - } - } else { - sd_card->sd_erase_status = SD_NOT_ERASE; - } - } -#endif - - rtsx_init_cards(chip); - - if (chip->ss_en) { - ss_allowed = 1; - - if (CHECK_PID(chip, 0x5288)) { - ss_allowed = 0; - } else { - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { - u32 val; - rtsx_read_cfg_dw(chip, 1, 0x04, &val); - if (val & 0x07) - ss_allowed = 0; - - } - } - } else { - ss_allowed = 0; - } - - if (ss_allowed && !chip->sd_io) { - if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) { - chip->ss_counter = 0; - } else { - if (chip->ss_counter < - (chip->ss_idle_period / POLLING_INTERVAL)) { - chip->ss_counter++; - } else { - rtsx_exclusive_enter_ss(chip); - return; - } - } - } - - if (CHECK_PID(chip, 0x5208)) { - rtsx_monitor_aspm_config(chip); - -#ifdef SUPPORT_SDIO_ASPM - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && - chip->aspm_l0s_l1_en && chip->dynamic_aspm) { - if (chip->sd_io) { - dynamic_configure_sdio_aspm(chip); - } else { - if (!chip->sdio_aspm) { - RTSX_DEBUGP("SDIO enter ASPM!\n"); - rtsx_write_register(chip, - ASPM_FORCE_CTL, 0xFC, - 0x30 | (chip->aspm_level[1] << 2)); - chip->sdio_aspm = 1; - } - } - } -#endif - } - - if (chip->idle_counter < IDLE_MAX_COUNT) { - chip->idle_counter++; - } else { - if (rtsx_get_stat(chip) != RTSX_STAT_IDLE) { - RTSX_DEBUGP("Idle state!\n"); - rtsx_set_stat(chip, RTSX_STAT_IDLE); - -#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) - chip->led_toggle_counter = 0; -#endif - rtsx_force_power_on(chip, SSC_PDCTL); - - turn_off_led(chip, LED_GPIO); - - if (chip->auto_power_down && !chip->card_ready && !chip->sd_io) - rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); - - } - } - - switch (rtsx_get_stat(chip)) { - case RTSX_STAT_RUN: -#if !defined(LED_AUTO_BLINK) && defined(REGULAR_BLINK) - rtsx_blink_led(chip); -#endif - do_remaining_work(chip); - break; - - case RTSX_STAT_IDLE: - if (chip->sd_io && !chip->sd_int) - try_to_switch_sdio_ctrl(chip); - - rtsx_enable_aspm(chip); - break; - - default: - break; - } - - -#ifdef SUPPORT_OCP - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { -#ifdef CONFIG_RTS_PSTOR_DEBUG - if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER | MS_OC_NOW | MS_OC_EVER)) - RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); -#endif - - if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { - if (chip->card_exist & SD_CARD) { - rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); - card_power_off(chip, SD_CARD); - chip->card_fail |= SD_CARD; - } - } - if (chip->ocp_stat & (MS_OC_NOW | MS_OC_EVER)) { - if (chip->card_exist & MS_CARD) { - rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); - card_power_off(chip, MS_CARD); - chip->card_fail |= MS_CARD; - } - } - } else { - if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { - RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); - if (chip->card_exist & SD_CARD) { - rtsx_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); - chip->card_fail |= SD_CARD; - } else if (chip->card_exist & MS_CARD) { - rtsx_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); - chip->card_fail |= MS_CARD; - } else if (chip->card_exist & XD_CARD) { - rtsx_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); - chip->card_fail |= XD_CARD; - } - card_power_off(chip, SD_CARD); - } - } -#endif - -Delink_Stage: - if (chip->auto_delink_en && chip->auto_delink_allowed && - !chip->card_ready && !chip->card_ejected && !chip->sd_io) { - int enter_L1 = chip->auto_delink_in_L1 && (chip->aspm_l0s_l1_en || chip->ss_en); - int delink_stage1_cnt = chip->delink_stage1_step; - int delink_stage2_cnt = delink_stage1_cnt + chip->delink_stage2_step; - int delink_stage3_cnt = delink_stage2_cnt + chip->delink_stage3_step; - - if (chip->auto_delink_cnt <= delink_stage3_cnt) { - if (chip->auto_delink_cnt == delink_stage1_cnt) { - rtsx_set_stat(chip, RTSX_STAT_DELINK); - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_set_phy_reg_bit(chip, 0x1C, 2); - - if (chip->card_exist) { - RTSX_DEBUGP("False card inserted, do force delink\n"); - - if (enter_L1) - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); - - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x0A); - - if (enter_L1) - rtsx_enter_L1(chip); - - chip->auto_delink_cnt = delink_stage3_cnt + 1; - } else { - RTSX_DEBUGP("No card inserted, do delink\n"); - - if (enter_L1) - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, 1); - -#ifdef HW_INT_WRITE_CLR - if (CHECK_PID(chip, 0x5209)) { - rtsx_writel(chip, RTSX_BIPR, 0xFFFFFFFF); - RTSX_DEBUGP("RTSX_BIPR: 0x%x\n", rtsx_readl(chip, RTSX_BIPR)); - } -#endif - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0x02); - - if (enter_L1) - rtsx_enter_L1(chip); - - } - } - - if (chip->auto_delink_cnt == delink_stage2_cnt) { - RTSX_DEBUGP("Try to do force delink\n"); - - if (enter_L1) - rtsx_exit_L1(chip); - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_set_phy_reg_bit(chip, 0x1C, 2); - - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x0A); - } - - chip->auto_delink_cnt++; - } - } else { - chip->auto_delink_cnt = 0; - } -} - -void rtsx_undo_delink(struct rtsx_chip *chip) -{ - chip->auto_delink_allowed = 0; - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x0A, 0x00); -} - -/** - * rtsx_stop_cmd - stop command transfer and DMA transfer - * @chip: Realtek's card reader chip - * @card: flash card type - * - * Stop command transfer and DMA transfer. - * This function is called in error handler. - */ -void rtsx_stop_cmd(struct rtsx_chip *chip, int card) -{ - int i; - - for (i = 0; i <= 8; i++) { - int addr = RTSX_HCBAR + i * 4; - u32 reg; - reg = rtsx_readl(chip, addr); - RTSX_DEBUGP("BAR (0x%02x): 0x%08x\n", addr, reg); - } - rtsx_writel(chip, RTSX_HCBCTLR, STOP_CMD); - rtsx_writel(chip, RTSX_HDBCTLR, STOP_DMA); - - for (i = 0; i < 16; i++) { - u16 addr = 0xFE20 + (u16)i; - u8 val; - rtsx_read_register(chip, addr, &val); - RTSX_DEBUGP("0x%04X: 0x%02x\n", addr, val); - } - - rtsx_write_register(chip, DMACTL, 0x80, 0x80); - rtsx_write_register(chip, RBCTL, 0x80, 0x80); -} - -#define MAX_RW_REG_CNT 1024 - -int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data) -{ - int i; - u32 val = 3 << 30; - - val |= (u32)(addr & 0x3FFF) << 16; - val |= (u32)mask << 8; - val |= (u32)data; - - rtsx_writel(chip, RTSX_HAIMR, val); - - for (i = 0; i < MAX_RW_REG_CNT; i++) { - val = rtsx_readl(chip, RTSX_HAIMR); - if ((val & (1 << 31)) == 0) { - if (data != (u8)val) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; - } - } - - TRACE_RET(chip, STATUS_TIMEDOUT); -} - -int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data) -{ - u32 val = 2 << 30; - int i; - - if (data) - *data = 0; - - val |= (u32)(addr & 0x3FFF) << 16; - - rtsx_writel(chip, RTSX_HAIMR, val); - - for (i = 0; i < MAX_RW_REG_CNT; i++) { - val = rtsx_readl(chip, RTSX_HAIMR); - if ((val & (1 << 31)) == 0) - break; - } - - if (i >= MAX_RW_REG_CNT) - TRACE_RET(chip, STATUS_TIMEDOUT); - - if (data) - *data = (u8)(val & 0xFF); - - return STATUS_SUCCESS; -} - -int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, u32 val) -{ - u8 mode = 0, tmp; - int i; - - for (i = 0; i < 4; i++) { - if (mask & 0xFF) { - RTSX_WRITE_REG(chip, CFGDATA0 + i, - 0xFF, (u8)(val & mask & 0xFF)); - mode |= (1 << i); - } - mask >>= 8; - val >>= 8; - } - - if (mode) { - RTSX_WRITE_REG(chip, CFGADDR0, 0xFF, (u8)addr); - RTSX_WRITE_REG(chip, CFGADDR1, 0xFF, (u8)(addr >> 8)); - - RTSX_WRITE_REG(chip, CFGRWCTL, 0xFF, - 0x80 | mode | ((func_no & 0x03) << 4)); - - for (i = 0; i < MAX_RW_REG_CNT; i++) { - RTSX_READ_REG(chip, CFGRWCTL, &tmp); - if ((tmp & 0x80) == 0) - break; - } - } - - return STATUS_SUCCESS; -} - -int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val) -{ - int i; - u8 tmp; - u32 data = 0; - - RTSX_WRITE_REG(chip, CFGADDR0, 0xFF, (u8)addr); - RTSX_WRITE_REG(chip, CFGADDR1, 0xFF, (u8)(addr >> 8)); - RTSX_WRITE_REG(chip, CFGRWCTL, 0xFF, 0x80 | ((func_no & 0x03) << 4)); - - for (i = 0; i < MAX_RW_REG_CNT; i++) { - RTSX_READ_REG(chip, CFGRWCTL, &tmp); - if ((tmp & 0x80) == 0) - break; - } - - for (i = 0; i < 4; i++) { - RTSX_READ_REG(chip, CFGDATA0 + i, &tmp); - data |= (u32)tmp << (i * 8); - } - - if (val) - *val = data; - - return STATUS_SUCCESS; -} - -int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len) -{ - u32 *data, *mask; - u16 offset = addr % 4; - u16 aligned_addr = addr - offset; - int dw_len, i, j; - int retval; - - RTSX_DEBUGP("%s\n", __func__); - - if (!buf) - TRACE_RET(chip, STATUS_NOMEM); - - if ((len + offset) % 4) - dw_len = (len + offset) / 4 + 1; - else - dw_len = (len + offset) / 4; - - RTSX_DEBUGP("dw_len = %d\n", dw_len); - - data = vzalloc(dw_len * 4); - if (!data) - TRACE_RET(chip, STATUS_NOMEM); - - mask = vzalloc(dw_len * 4); - if (!mask) { - vfree(data); - TRACE_RET(chip, STATUS_NOMEM); - } - - j = 0; - for (i = 0; i < len; i++) { - mask[j] |= 0xFF << (offset * 8); - data[j] |= buf[i] << (offset * 8); - if (++offset == 4) { - j++; - offset = 0; - } - } - - RTSX_DUMP(mask, dw_len * 4); - RTSX_DUMP(data, dw_len * 4); - - for (i = 0; i < dw_len; i++) { - retval = rtsx_write_cfg_dw(chip, func, aligned_addr + i * 4, mask[i], data[i]); - if (retval != STATUS_SUCCESS) { - vfree(data); - vfree(mask); - TRACE_RET(chip, STATUS_FAIL); - } - } - - vfree(data); - vfree(mask); - - return STATUS_SUCCESS; -} - -int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len) -{ - u32 *data; - u16 offset = addr % 4; - u16 aligned_addr = addr - offset; - int dw_len, i, j; - int retval; - - RTSX_DEBUGP("%s\n", __func__); - - if ((len + offset) % 4) - dw_len = (len + offset) / 4 + 1; - else - dw_len = (len + offset) / 4; - - RTSX_DEBUGP("dw_len = %d\n", dw_len); - - data = (u32 *)vmalloc(dw_len * 4); - if (!data) - TRACE_RET(chip, STATUS_NOMEM); - - for (i = 0; i < dw_len; i++) { - retval = rtsx_read_cfg_dw(chip, func, aligned_addr + i * 4, data + i); - if (retval != STATUS_SUCCESS) { - vfree(data); - TRACE_RET(chip, STATUS_FAIL); - } - } - - if (buf) { - j = 0; - - for (i = 0; i < len; i++) { - buf[i] = (u8)(data[j] >> (offset * 8)); - if (++offset == 4) { - j++; - offset = 0; - } - } - } - - vfree(data); - - return STATUS_SUCCESS; -} - -int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val) -{ - int i, finished = 0; - u8 tmp; - - RTSX_WRITE_REG(chip, PHYDATA0, 0xFF, (u8)val); - RTSX_WRITE_REG(chip, PHYDATA1, 0xFF, (u8)(val >> 8)); - RTSX_WRITE_REG(chip, PHYADDR, 0xFF, addr); - RTSX_WRITE_REG(chip, PHYRWCTL, 0xFF, 0x81); - - for (i = 0; i < 100000; i++) { - RTSX_READ_REG(chip, PHYRWCTL, &tmp); - if (!(tmp & 0x80)) { - finished = 1; - break; - } - } - - if (!finished) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val) -{ - int i, finished = 0; - u16 data = 0; - u8 tmp; - - RTSX_WRITE_REG(chip, PHYADDR, 0xFF, addr); - RTSX_WRITE_REG(chip, PHYRWCTL, 0xFF, 0x80); - - for (i = 0; i < 100000; i++) { - RTSX_READ_REG(chip, PHYRWCTL, &tmp); - if (!(tmp & 0x80)) { - finished = 1; - break; - } - } - - if (!finished) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_READ_REG(chip, PHYDATA0, &tmp); - data = tmp; - RTSX_READ_REG(chip, PHYDATA1, &tmp); - data |= (u16)tmp << 8; - - if (val) - *val = data; - - return STATUS_SUCCESS; -} - -int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val) -{ - int i; - u8 data = 0; - - RTSX_WRITE_REG(chip, EFUSE_CTRL, 0xFF, 0x80|addr); - - for (i = 0; i < 100; i++) { - RTSX_READ_REG(chip, EFUSE_CTRL, &data); - if (!(data & 0x80)) - break; - udelay(1); - } - - if (data & 0x80) - TRACE_RET(chip, STATUS_TIMEDOUT); - - RTSX_READ_REG(chip, EFUSE_DATA, &data); - if (val) - *val = data; - - return STATUS_SUCCESS; -} - -int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val) -{ - int i, j; - u8 data = 0, tmp = 0xFF; - - for (i = 0; i < 8; i++) { - if (val & (u8)(1 << i)) - continue; - - tmp &= (~(u8)(1 << i)); - RTSX_DEBUGP("Write 0x%x to 0x%x\n", tmp, addr); - - RTSX_WRITE_REG(chip, EFUSE_DATA, 0xFF, tmp); - RTSX_WRITE_REG(chip, EFUSE_CTRL, 0xFF, 0xA0|addr); - - for (j = 0; j < 100; j++) { - RTSX_READ_REG(chip, EFUSE_CTRL, &data); - if (!(data & 0x80)) - break; - wait_timeout(3); - } - - if (data & 0x80) - TRACE_RET(chip, STATUS_TIMEDOUT); - - wait_timeout(5); - } - - return STATUS_SUCCESS; -} - -int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) -{ - int retval; - u16 value; - - retval = rtsx_read_phy_register(chip, reg, &value); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (value & (1 << bit)) { - value &= ~(1 << bit); - retval = rtsx_write_phy_register(chip, reg, value); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit) -{ - int retval; - u16 value; - - retval = rtsx_read_phy_register(chip, reg, &value); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (0 == (value & (1 << bit))) { - value |= (1 << bit); - retval = rtsx_write_phy_register(chip, reg, value); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -int rtsx_check_link_ready(struct rtsx_chip *chip) -{ - u8 val; - - RTSX_READ_REG(chip, IRQSTAT0, &val); - - RTSX_DEBUGP("IRQSTAT0: 0x%x\n", val); - if (val & LINK_RDY_INT) { - RTSX_DEBUGP("Delinked!\n"); - rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -static void rtsx_handle_pm_dstate(struct rtsx_chip *chip, u8 dstate) -{ - u32 ultmp; - - RTSX_DEBUGP("%04x set pm_dstate to %d\n", chip->product_id, dstate); - - if (CHK_SDIO_EXIST(chip)) { - u8 func_no; - - if (CHECK_PID(chip, 0x5288)) - func_no = 2; - else - func_no = 1; - - rtsx_read_cfg_dw(chip, func_no, 0x84, &ultmp); - RTSX_DEBUGP("pm_dstate of function %d: 0x%x\n", (int)func_no, ultmp); - rtsx_write_cfg_dw(chip, func_no, 0x84, 0xFF, dstate); - } - - rtsx_write_config_byte(chip, 0x44, dstate); - rtsx_write_config_byte(chip, 0x45, 0); -} - -void rtsx_enter_L1(struct rtsx_chip *chip) -{ - rtsx_handle_pm_dstate(chip, 2); -} - -void rtsx_exit_L1(struct rtsx_chip *chip) -{ - rtsx_write_config_byte(chip, 0x44, 0); - rtsx_write_config_byte(chip, 0x45, 0); -} - -void rtsx_enter_ss(struct rtsx_chip *chip) -{ - RTSX_DEBUGP("Enter Selective Suspend State!\n"); - - rtsx_write_register(chip, IRQSTAT0, LINK_RDY_INT, LINK_RDY_INT); - - if (chip->power_down_in_ss) { - rtsx_power_off_card(chip); - rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); - } - - if (CHK_SDIO_EXIST(chip)) { - if (CHECK_PID(chip, 0x5288)) - rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFF00, 0x0100); - else - rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFF00, 0x0100); - } - - if (chip->auto_delink_en) { - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x01, 0x01); - } else { - if (!chip->phy_debug_mode) { - u32 tmp; - tmp = rtsx_readl(chip, RTSX_BIER); - tmp |= CARD_INT; - rtsx_writel(chip, RTSX_BIER, tmp); - } - - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 0); - } - - rtsx_enter_L1(chip); - - RTSX_CLR_DELINK(chip); - rtsx_set_stat(chip, RTSX_STAT_SS); -} - -void rtsx_exit_ss(struct rtsx_chip *chip) -{ - RTSX_DEBUGP("Exit Selective Suspend State!\n"); - - rtsx_exit_L1(chip); - - if (chip->power_down_in_ss) { - rtsx_force_power_on(chip, SSC_PDCTL | OC_PDCTL); - udelay(1000); - } - - if (RTSX_TST_DELINK(chip)) { - chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; - rtsx_reinit_cards(chip, 1); - RTSX_CLR_DELINK(chip); - } else if (chip->power_down_in_ss) { - chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; - rtsx_reinit_cards(chip, 0); - } -} - -int rtsx_pre_handle_interrupt(struct rtsx_chip *chip) -{ - u32 status, int_enable; - int exit_ss = 0; -#ifdef SUPPORT_OCP - u32 ocp_int = 0; - - if (CHECK_PID(chip, 0x5209)) { - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - ocp_int = MS_OC_INT | SD_OC_INT; - else - ocp_int = SD_OC_INT; - - } else { - ocp_int = OC_INT; - } -#endif - - if (chip->ss_en) { - chip->ss_counter = 0; - if (rtsx_get_stat(chip) == RTSX_STAT_SS) { - exit_ss = 1; - rtsx_exit_L1(chip); - rtsx_set_stat(chip, RTSX_STAT_RUN); - } - } - - int_enable = rtsx_readl(chip, RTSX_BIER); - chip->int_reg = rtsx_readl(chip, RTSX_BIPR); - -#ifdef HW_INT_WRITE_CLR - if (CHECK_PID(chip, 0x5209)) - rtsx_writel(chip, RTSX_BIPR, chip->int_reg); -#endif - - if (((chip->int_reg & int_enable) == 0) || (chip->int_reg == 0xFFFFFFFF)) - return STATUS_FAIL; - - if (!chip->msi_en) { - if (CHECK_PID(chip, 0x5209)) { - u8 val; - rtsx_read_config_byte(chip, 0x05, &val); - if (val & 0x04) - return STATUS_FAIL; - } - } - - status = chip->int_reg &= (int_enable | 0x7FFFFF); - - if (status & CARD_INT) { - chip->auto_delink_cnt = 0; - - if (status & SD_INT) { - if (status & SD_EXIST) { - set_bit(SD_NR, &(chip->need_reset)); - } else { - set_bit(SD_NR, &(chip->need_release)); - chip->sd_reset_counter = 0; - chip->sd_show_cnt = 0; - clear_bit(SD_NR, &(chip->need_reset)); - } - } else { - /* If multi-luns, it's possible that - when plugging/unplugging one card - there is another card which still - exists in the slot. In this case, - all existed cards should be reset. - */ - if (exit_ss && (status & SD_EXIST)) - set_bit(SD_NR, &(chip->need_reinit)); - } - if (!CHECK_PID(chip, 0x5288) || CHECK_BARO_PKG(chip, QFN)) { - if (status & XD_INT) { - if (status & XD_EXIST) { - set_bit(XD_NR, &(chip->need_reset)); - } else { - set_bit(XD_NR, &(chip->need_release)); - chip->xd_reset_counter = 0; - chip->xd_show_cnt = 0; - clear_bit(XD_NR, &(chip->need_reset)); - } - } else { - if (exit_ss && (status & XD_EXIST)) - set_bit(XD_NR, &(chip->need_reinit)); - } - } - if (status & MS_INT) { - if (status & MS_EXIST) { - set_bit(MS_NR, &(chip->need_reset)); - } else { - set_bit(MS_NR, &(chip->need_release)); - chip->ms_reset_counter = 0; - chip->ms_show_cnt = 0; - clear_bit(MS_NR, &(chip->need_reset)); - } - } else { - if (exit_ss && (status & MS_EXIST)) - set_bit(MS_NR, &(chip->need_reinit)); - } - } - -#ifdef SUPPORT_OCP - chip->ocp_int = ocp_int & status; -#endif - - if (chip->sd_io) { - if (chip->int_reg & DATA_DONE_INT) - chip->int_reg &= ~(u32)DATA_DONE_INT; - } - - return STATUS_SUCCESS; -} - -void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat) -{ - int retval; - - RTSX_DEBUGP("rtsx_do_before_power_down, pm_stat = %d\n", pm_stat); - - rtsx_set_stat(chip, RTSX_STAT_SUSPEND); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) - return; - - rtsx_release_cards(chip); - rtsx_disable_bus_int(chip); - turn_off_led(chip, LED_GPIO); - -#ifdef HW_AUTO_SWITCH_SD_BUS - if (chip->sd_io) { - chip->sdio_in_charge = 1; - if (CHECK_PID(chip, 0x5208)) { - rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08); - /* Enable sdio_bus_auto_switch */ - rtsx_write_register(chip, 0xFE70, 0x80, 0x80); - } else if (CHECK_PID(chip, 0x5288)) { - rtsx_write_register(chip, TLPTISTAT, 0x08, 0x08); - /* Enable sdio_bus_auto_switch */ - rtsx_write_register(chip, 0xFE5A, 0x08, 0x08); - } else if (CHECK_PID(chip, 0x5209)) { - rtsx_write_register(chip, TLPTISTAT, 0x10, 0x10); - /* Enable sdio_bus_auto_switch */ - rtsx_write_register(chip, SDIO_CFG, SDIO_BUS_AUTO_SWITCH, SDIO_BUS_AUTO_SWITCH); - } - } -#endif - - if (CHECK_PID(chip, 0x5208) && (chip->ic_version >= IC_VER_D)) { - /* u_force_clkreq_0 */ - rtsx_write_register(chip, PETXCFG, 0x08, 0x08); - } else if (CHECK_PID(chip, 0x5209)) { - /* u_force_clkreq_0 */ - rtsx_write_register(chip, PETXCFG, 0x08, 0x08); - } - - if (pm_stat == PM_S1) { - RTSX_DEBUGP("Host enter S1\n"); - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, HOST_ENTER_S1); - } else if (pm_stat == PM_S3) { - if (chip->s3_pwr_off_delay > 0) - wait_timeout(chip->s3_pwr_off_delay); - - RTSX_DEBUGP("Host enter S3\n"); - rtsx_write_register(chip, HOST_SLEEP_STATE, 0x03, HOST_ENTER_S3); - } - - if (chip->do_delink_before_power_down && chip->auto_delink_en) - rtsx_write_register(chip, CHANGE_LINK_STATE, 0x02, 2); - - rtsx_force_power_down(chip, SSC_PDCTL | OC_PDCTL); - - chip->cur_clk = 0; - chip->cur_card = 0; - chip->card_exist = 0; -} - -void rtsx_enable_aspm(struct rtsx_chip *chip) -{ - if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) { - if (!chip->aspm_enabled) { - RTSX_DEBUGP("Try to enable ASPM\n"); - chip->aspm_enabled = 1; - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_write_phy_register(chip, 0x07, 0); - if (CHECK_PID(chip, 0x5208)) { - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, - 0x30 | chip->aspm_level[0]); - } else { - rtsx_write_config_byte(chip, LCTLR, chip->aspm_l0s_l1_en); - } - - if (CHK_SDIO_EXIST(chip)) { - u16 val = chip->aspm_l0s_l1_en | 0x0100; - if (CHECK_PID(chip, 0x5288)) - rtsx_write_cfg_dw(chip, 2, 0xC0, 0xFFFF, val); - else - rtsx_write_cfg_dw(chip, 1, 0xC0, 0xFFFF, val); - } - } - } - - return; -} - -void rtsx_disable_aspm(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5208)) - rtsx_monitor_aspm_config(chip); - - if (chip->aspm_l0s_l1_en && chip->dynamic_aspm) { - if (chip->aspm_enabled) { - RTSX_DEBUGP("Try to disable ASPM\n"); - chip->aspm_enabled = 0; - - if (chip->asic_code && CHECK_PID(chip, 0x5208)) - rtsx_write_phy_register(chip, 0x07, 0x0129); - if (CHECK_PID(chip, 0x5208)) - rtsx_write_register(chip, ASPM_FORCE_CTL, 0xF3, 0x30); - else - rtsx_write_config_byte(chip, LCTLR, 0x00); - - wait_timeout(1); - } - } - - return; -} - -int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) -{ - int retval; - int i, j; - u16 reg_addr; - u8 *ptr; - - if (!buf) - TRACE_RET(chip, STATUS_ERROR); - - ptr = buf; - reg_addr = PPBUF_BASE2; - for (i = 0; i < buf_len/256; i++) { - rtsx_init_cmd(chip); - - for (j = 0; j < 256; j++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0); - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - memcpy(ptr, rtsx_get_cmd_data(chip), 256); - ptr += 256; - } - - if (buf_len%256) { - rtsx_init_cmd(chip); - - for (j = 0; j < buf_len%256; j++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr++, 0, 0); - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - } - - memcpy(ptr, rtsx_get_cmd_data(chip), buf_len%256); - - return STATUS_SUCCESS; -} - -int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len) -{ - int retval; - int i, j; - u16 reg_addr; - u8 *ptr; - - if (!buf) - TRACE_RET(chip, STATUS_ERROR); - - ptr = buf; - reg_addr = PPBUF_BASE2; - for (i = 0; i < buf_len/256; i++) { - rtsx_init_cmd(chip); - - for (j = 0; j < 256; j++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, *ptr); - ptr++; - } - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - } - - if (buf_len%256) { - rtsx_init_cmd(chip); - - for (j = 0; j < buf_len%256; j++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, reg_addr++, 0xFF, *ptr); - ptr++; - } - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -int rtsx_check_chip_exist(struct rtsx_chip *chip) -{ - if (rtsx_readl(chip, 0) == 0xFFFFFFFF) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl) -{ - int retval; - u8 mask = 0; - - if (ctl & SSC_PDCTL) - mask |= SSC_POWER_DOWN; - -#ifdef SUPPORT_OCP - if (ctl & OC_PDCTL) { - mask |= SD_OC_POWER_DOWN; - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - mask |= MS_OC_POWER_DOWN; - } -#endif - - if (mask) { - retval = rtsx_write_register(chip, FPDCTL, mask, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHECK_PID(chip, 0x5288)) - wait_timeout(200); - } - - return STATUS_SUCCESS; -} - -int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl) -{ - int retval; - u8 mask = 0, val = 0; - - if (ctl & SSC_PDCTL) - mask |= SSC_POWER_DOWN; - -#ifdef SUPPORT_OCP - if (ctl & OC_PDCTL) { - mask |= SD_OC_POWER_DOWN; - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - mask |= MS_OC_POWER_DOWN; - } -#endif - - if (mask) { - val = mask; - retval = rtsx_write_register(chip, FPDCTL, mask, val); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts_pstor/rtsx_chip.h b/drivers/staging/rts_pstor/rtsx_chip.h deleted file mode 100644 index 9f7cd82a154..00000000000 --- a/drivers/staging/rts_pstor/rtsx_chip.h +++ /dev/null @@ -1,989 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __REALTEK_RTSX_CHIP_H -#define __REALTEK_RTSX_CHIP_H - -#include "rtsx.h" - -#define SUPPORT_CPRM -#define SUPPORT_OCP -#define SUPPORT_SDIO_ASPM -#define SUPPORT_MAGIC_GATE -#define SUPPORT_MSXC -#define SUPPORT_SD_LOCK -/* Hardware switch bus_ctl and cd_ctl automatically */ -#define HW_AUTO_SWITCH_SD_BUS -/* Enable hardware interrupt write clear */ -#define HW_INT_WRITE_CLR -/* #define LED_AUTO_BLINK */ -/* #define DISABLE_CARD_INT */ - -#ifdef SUPPORT_MAGIC_GATE - /* Using NORMAL_WRITE instead of AUTO_WRITE to set ICV */ - #define MG_SET_ICV_SLOW - /* HW may miss ERR/CMDNK signal when sampling INT status. */ - #define MS_SAMPLE_INT_ERR - /* HW DO NOT support Wait_INT function during READ_BYTES transfer mode */ - #define READ_BYTES_WAIT_INT -#endif - -#ifdef SUPPORT_MSXC -#define XC_POWERCLASS -#define SUPPORT_PCGL_1P18 -#endif - -#ifndef LED_AUTO_BLINK -#define REGULAR_BLINK -#endif - -#define LED_BLINK_SPEED 5 -#define LED_TOGGLE_INTERVAL 6 -#define GPIO_TOGGLE_THRESHOLD 1024 -#define LED_GPIO 0 - -#define POLLING_INTERVAL 30 - -#define TRACE_ITEM_CNT 64 - -#ifndef STATUS_SUCCESS -#define STATUS_SUCCESS 0 -#endif -#ifndef STATUS_FAIL -#define STATUS_FAIL 1 -#endif -#ifndef STATUS_TIMEDOUT -#define STATUS_TIMEDOUT 2 -#endif -#ifndef STATUS_NOMEM -#define STATUS_NOMEM 3 -#endif -#ifndef STATUS_READ_FAIL -#define STATUS_READ_FAIL 4 -#endif -#ifndef STATUS_WRITE_FAIL -#define STATUS_WRITE_FAIL 5 -#endif -#ifndef STATUS_ERROR -#define STATUS_ERROR 10 -#endif - -#define PM_S1 1 -#define PM_S3 3 - -/* - * Transport return codes - */ - -#define TRANSPORT_GOOD 0 /* Transport good, command good */ -#define TRANSPORT_FAILED 1 /* Transport good, command failed */ -#define TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */ -#define TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */ - - -/*----------------------------------- - Start-Stop-Unit ------------------------------------*/ -#define STOP_MEDIUM 0x00 /* access disable */ -#define MAKE_MEDIUM_READY 0x01 /* access enable */ -#define UNLOAD_MEDIUM 0x02 /* unload */ -#define LOAD_MEDIUM 0x03 /* load */ - -/*----------------------------------- - STANDARD_INQUIRY ------------------------------------*/ -#define QULIFIRE 0x00 -#define AENC_FNC 0x00 -#define TRML_IOP 0x00 -#define REL_ADR 0x00 -#define WBUS_32 0x00 -#define WBUS_16 0x00 -#define SYNC 0x00 -#define LINKED 0x00 -#define CMD_QUE 0x00 -#define SFT_RE 0x00 - -#define VEN_ID_LEN 8 /* Vendor ID Length */ -#define PRDCT_ID_LEN 16 /* Product ID Length */ -#define PRDCT_REV_LEN 4 /* Product LOT Length */ - -/* Dynamic flag definitions: used in set_bit() etc. */ -#define RTSX_FLIDX_TRANS_ACTIVE 18 /* 0x00040000 transfer is active */ -#define RTSX_FLIDX_ABORTING 20 /* 0x00100000 abort is in progress */ -#define RTSX_FLIDX_DISCONNECTING 21 /* 0x00200000 disconnect in progress */ -#define ABORTING_OR_DISCONNECTING ((1UL << US_FLIDX_ABORTING) | \ - (1UL << US_FLIDX_DISCONNECTING)) -#define RTSX_FLIDX_RESETTING 22 /* 0x00400000 device reset in progress */ -#define RTSX_FLIDX_TIMED_OUT 23 /* 0x00800000 SCSI midlayer timed out */ - -#define DRCT_ACCESS_DEV 0x00 /* Direct Access Device */ -#define RMB_DISC 0x80 /* The Device is Removable */ -#define ANSI_SCSI2 0x02 /* Based on ANSI-SCSI2 */ - -#define SCSI 0x00 /* Interface ID */ - -#define WRITE_PROTECTED_MEDIA 0x07 - -/*---- sense key ----*/ -#define ILI 0x20 /* ILI bit is on */ - -#define NO_SENSE 0x00 /* not exist sense key */ -#define RECOVER_ERR 0x01 /* Target/Logical unit is recoverd */ -#define NOT_READY 0x02 /* Logical unit is not ready */ -#define MEDIA_ERR 0x03 /* medium/data error */ -#define HARDWARE_ERR 0x04 /* hardware error */ -#define ILGAL_REQ 0x05 /* CDB/parameter/identify msg error */ -#define UNIT_ATTENTION 0x06 /* unit attention condition occur */ -#define DAT_PRTCT 0x07 /* read/write is desable */ -#define BLNC_CHK 0x08 /* find blank/DOF in read */ - /* write to unblank area */ -#define CPY_ABRT 0x0a /* Copy/Compare/Copy&Verify illgal */ -#define ABRT_CMD 0x0b /* Target make the command in error */ -#define EQUAL 0x0c /* Search Data end with Equal */ -#define VLM_OVRFLW 0x0d /* Some data are left in buffer */ -#define MISCMP 0x0e /* find inequality */ - -#define READ_ERR -1 -#define WRITE_ERR -2 - -#define FIRST_RESET 0x01 -#define USED_EXIST 0x02 - -/*----------------------------------- - SENSE_DATA ------------------------------------*/ -/*---- valid ----*/ -#define SENSE_VALID 0x80 /* Sense data is valid as SCSI2 */ -#define SENSE_INVALID 0x00 /* Sense data is invalid as SCSI2 */ - -/*---- error code ----*/ -#define CUR_ERR 0x70 /* current error */ -#define DEF_ERR 0x71 /* specific command error */ - -/*---- sense key Information ----*/ -#define SNSKEYINFO_LEN 3 /* length of sense key information */ - -#define SKSV 0x80 -#define CDB_ILLEGAL 0x40 -#define DAT_ILLEGAL 0x00 -#define BPV 0x08 -#define BIT_ILLEGAL0 0 /* bit0 is illegal */ -#define BIT_ILLEGAL1 1 /* bit1 is illegal */ -#define BIT_ILLEGAL2 2 /* bit2 is illegal */ -#define BIT_ILLEGAL3 3 /* bit3 is illegal */ -#define BIT_ILLEGAL4 4 /* bit4 is illegal */ -#define BIT_ILLEGAL5 5 /* bit5 is illegal */ -#define BIT_ILLEGAL6 6 /* bit6 is illegal */ -#define BIT_ILLEGAL7 7 /* bit7 is illegal */ - -/*---- ASC ----*/ -#define ASC_NO_INFO 0x00 -#define ASC_MISCMP 0x1d -#define ASC_INVLD_CDB 0x24 -#define ASC_INVLD_PARA 0x26 -#define ASC_LU_NOT_READY 0x04 -#define ASC_WRITE_ERR 0x0c -#define ASC_READ_ERR 0x11 -#define ASC_LOAD_EJCT_ERR 0x53 -#define ASC_MEDIA_NOT_PRESENT 0x3A -#define ASC_MEDIA_CHANGED 0x28 -#define ASC_MEDIA_IN_PROCESS 0x04 -#define ASC_WRITE_PROTECT 0x27 -#define ASC_LUN_NOT_SUPPORTED 0x25 - -/*---- ASQC ----*/ -#define ASCQ_NO_INFO 0x00 -#define ASCQ_MEDIA_IN_PROCESS 0x01 -#define ASCQ_MISCMP 0x00 -#define ASCQ_INVLD_CDB 0x00 -#define ASCQ_INVLD_PARA 0x02 -#define ASCQ_LU_NOT_READY 0x02 -#define ASCQ_WRITE_ERR 0x02 -#define ASCQ_READ_ERR 0x00 -#define ASCQ_LOAD_EJCT_ERR 0x00 -#define ASCQ_WRITE_PROTECT 0x00 - - -struct sense_data_t { - unsigned char err_code; /* error code */ - /* bit7 : valid */ - /* (1 : SCSI2) */ - /* (0 : Vendor specific) */ - /* bit6-0 : error code */ - /* (0x70 : current error) */ - /* (0x71 : specific command error) */ - unsigned char seg_no; /* segment No. */ - unsigned char sense_key; /* byte5 : ILI */ - /* bit3-0 : sense key */ - unsigned char info[4]; /* information */ - unsigned char ad_sense_len; /* additional sense data length */ - unsigned char cmd_info[4]; /* command specific information */ - unsigned char asc; /* ASC */ - unsigned char ascq; /* ASCQ */ - unsigned char rfu; /* FRU */ - unsigned char sns_key_info[3]; /* sense key specific information */ -}; - -/* PCI Operation Register Address */ -#define RTSX_HCBAR 0x00 -#define RTSX_HCBCTLR 0x04 -#define RTSX_HDBAR 0x08 -#define RTSX_HDBCTLR 0x0C -#define RTSX_HAIMR 0x10 -#define RTSX_BIPR 0x14 -#define RTSX_BIER 0x18 - -/* Host command buffer control register */ -#define STOP_CMD (0x01 << 28) - -/* Host data buffer control register */ -#define SDMA_MODE 0x00 -#define ADMA_MODE (0x02 << 26) -#define STOP_DMA (0x01 << 28) -#define TRIG_DMA (0x01 << 31) - -/* Bus interrupt pending register */ -#define CMD_DONE_INT (1 << 31) -#define DATA_DONE_INT (1 << 30) -#define TRANS_OK_INT (1 << 29) -#define TRANS_FAIL_INT (1 << 28) -#define XD_INT (1 << 27) -#define MS_INT (1 << 26) -#define SD_INT (1 << 25) -#define GPIO0_INT (1 << 24) -#define OC_INT (1 << 23) -#define SD_WRITE_PROTECT (1 << 19) -#define XD_EXIST (1 << 18) -#define MS_EXIST (1 << 17) -#define SD_EXIST (1 << 16) -#define DELINK_INT GPIO0_INT -#define MS_OC_INT (1 << 23) -#define SD_OC_INT (1 << 22) - -#define CARD_INT (XD_INT | MS_INT | SD_INT) -#define NEED_COMPLETE_INT (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT) -#define RTSX_INT (CMD_DONE_INT | NEED_COMPLETE_INT | CARD_INT | GPIO0_INT | OC_INT) - -#define CARD_EXIST (XD_EXIST | MS_EXIST | SD_EXIST) - -/* Bus interrupt enable register */ -#define CMD_DONE_INT_EN (1 << 31) -#define DATA_DONE_INT_EN (1 << 30) -#define TRANS_OK_INT_EN (1 << 29) -#define TRANS_FAIL_INT_EN (1 << 28) -#define XD_INT_EN (1 << 27) -#define MS_INT_EN (1 << 26) -#define SD_INT_EN (1 << 25) -#define GPIO0_INT_EN (1 << 24) -#define OC_INT_EN (1 << 23) -#define DELINK_INT_EN GPIO0_INT_EN -#define MS_OC_INT_EN (1 << 23) -#define SD_OC_INT_EN (1 << 22) - - -#define READ_REG_CMD 0 -#define WRITE_REG_CMD 1 -#define CHECK_REG_CMD 2 - -#define HOST_TO_DEVICE 0 -#define DEVICE_TO_HOST 1 - - -#define RTSX_RESV_BUF_LEN 4096 -#define HOST_CMDS_BUF_LEN 1024 -#define HOST_SG_TBL_BUF_LEN (RTSX_RESV_BUF_LEN - HOST_CMDS_BUF_LEN) - -#define SD_NR 2 -#define MS_NR 3 -#define XD_NR 4 -#define SPI_NR 7 -#define SD_CARD (1 << SD_NR) -#define MS_CARD (1 << MS_NR) -#define XD_CARD (1 << XD_NR) -#define SPI_CARD (1 << SPI_NR) - -#define MAX_ALLOWED_LUN_CNT 8 - -#define XD_FREE_TABLE_CNT 1200 -#define MS_FREE_TABLE_CNT 512 - - -/* Bit Operation */ -#define SET_BIT(data, idx) ((data) |= 1 << (idx)) -#define CLR_BIT(data, idx) ((data) &= ~(1 << (idx))) -#define CHK_BIT(data, idx) ((data) & (1 << (idx))) - -/* SG descriptor */ -#define SG_INT 0x04 -#define SG_END 0x02 -#define SG_VALID 0x01 - -#define SG_NO_OP 0x00 -#define SG_TRANS_DATA (0x02 << 4) -#define SG_LINK_DESC (0x03 << 4) - -struct rtsx_chip; - -typedef int (*card_rw_func)(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 sec_addr, u16 sec_cnt); - -/* Supported Clock */ -enum card_clock {CLK_20 = 1, CLK_30, CLK_40, CLK_50, CLK_60, CLK_80, CLK_100, CLK_120, CLK_150, CLK_200}; - -enum RTSX_STAT {RTSX_STAT_INIT, RTSX_STAT_IDLE, RTSX_STAT_RUN, RTSX_STAT_SS, - RTSX_STAT_DELINK, RTSX_STAT_SUSPEND, RTSX_STAT_ABORT, RTSX_STAT_DISCONNECT}; -enum IC_VER {IC_VER_AB, IC_VER_C = 2, IC_VER_D = 3}; - -#define MAX_RESET_CNT 3 - -/* For MS Card */ -#define MAX_DEFECTIVE_BLOCK 10 - -struct zone_entry { - u16 *l2p_table; - u16 *free_table; - u16 defect_list[MAX_DEFECTIVE_BLOCK]; /* For MS card only */ - int set_index; - int get_index; - int unused_blk_cnt; - int disable_count; - /* To indicate whether the L2P table of this zone has been built. */ - int build_flag; -}; - -#define TYPE_SD 0x0000 -#define TYPE_MMC 0x0001 - -/* TYPE_SD */ -#define SD_HS 0x0100 -#define SD_SDR50 0x0200 -#define SD_DDR50 0x0400 -#define SD_SDR104 0x0800 -#define SD_HCXC 0x1000 - -/* TYPE_MMC */ -#define MMC_26M 0x0100 -#define MMC_52M 0x0200 -#define MMC_4BIT 0x0400 -#define MMC_8BIT 0x0800 -#define MMC_SECTOR_MODE 0x1000 -#define MMC_DDR52 0x2000 - -/* SD card */ -#define CHK_SD(sd_card) (((sd_card)->sd_type & 0xFF) == TYPE_SD) -#define CHK_SD_HS(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_HS)) -#define CHK_SD_SDR50(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_SDR50)) -#define CHK_SD_DDR50(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_DDR50)) -#define CHK_SD_SDR104(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_SDR104)) -#define CHK_SD_HCXC(sd_card) (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_HCXC)) -#define CHK_SD_HC(sd_card) (CHK_SD_HCXC(sd_card) && ((sd_card)->capacity <= 0x4000000)) -#define CHK_SD_XC(sd_card) (CHK_SD_HCXC(sd_card) && ((sd_card)->capacity > 0x4000000)) -#define CHK_SD30_SPEED(sd_card) (CHK_SD_SDR50(sd_card) || CHK_SD_DDR50(sd_card) || CHK_SD_SDR104(sd_card)) - -#define SET_SD(sd_card) ((sd_card)->sd_type = TYPE_SD) -#define SET_SD_HS(sd_card) ((sd_card)->sd_type |= SD_HS) -#define SET_SD_SDR50(sd_card) ((sd_card)->sd_type |= SD_SDR50) -#define SET_SD_DDR50(sd_card) ((sd_card)->sd_type |= SD_DDR50) -#define SET_SD_SDR104(sd_card) ((sd_card)->sd_type |= SD_SDR104) -#define SET_SD_HCXC(sd_card) ((sd_card)->sd_type |= SD_HCXC) - -#define CLR_SD_HS(sd_card) ((sd_card)->sd_type &= ~SD_HS) -#define CLR_SD_SDR50(sd_card) ((sd_card)->sd_type &= ~SD_SDR50) -#define CLR_SD_DDR50(sd_card) ((sd_card)->sd_type &= ~SD_DDR50) -#define CLR_SD_SDR104(sd_card) ((sd_card)->sd_type &= ~SD_SDR104) -#define CLR_SD_HCXC(sd_card) ((sd_card)->sd_type &= ~SD_HCXC) - -/* MMC card */ -#define CHK_MMC(sd_card) (((sd_card)->sd_type & 0xFF) == TYPE_MMC) -#define CHK_MMC_26M(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_26M)) -#define CHK_MMC_52M(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_52M)) -#define CHK_MMC_4BIT(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_4BIT)) -#define CHK_MMC_8BIT(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_8BIT)) -#define CHK_MMC_SECTOR_MODE(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_SECTOR_MODE)) -#define CHK_MMC_DDR52(sd_card) (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_DDR52)) - -#define SET_MMC(sd_card) ((sd_card)->sd_type = TYPE_MMC) -#define SET_MMC_26M(sd_card) ((sd_card)->sd_type |= MMC_26M) -#define SET_MMC_52M(sd_card) ((sd_card)->sd_type |= MMC_52M) -#define SET_MMC_4BIT(sd_card) ((sd_card)->sd_type |= MMC_4BIT) -#define SET_MMC_8BIT(sd_card) ((sd_card)->sd_type |= MMC_8BIT) -#define SET_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type |= MMC_SECTOR_MODE) -#define SET_MMC_DDR52(sd_card) ((sd_card)->sd_type |= MMC_DDR52) - -#define CLR_MMC_26M(sd_card) ((sd_card)->sd_type &= ~MMC_26M) -#define CLR_MMC_52M(sd_card) ((sd_card)->sd_type &= ~MMC_52M) -#define CLR_MMC_4BIT(sd_card) ((sd_card)->sd_type &= ~MMC_4BIT) -#define CLR_MMC_8BIT(sd_card) ((sd_card)->sd_type &= ~MMC_8BIT) -#define CLR_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type &= ~MMC_SECTOR_MODE) -#define CLR_MMC_DDR52(sd_card) ((sd_card)->sd_type &= ~MMC_DDR52) - -#define CHK_MMC_HS(sd_card) (CHK_MMC_52M(sd_card) && CHK_MMC_26M(sd_card)) -#define CLR_MMC_HS(sd_card) \ -do { \ - CLR_MMC_DDR52(sd_card); \ - CLR_MMC_52M(sd_card); \ - CLR_MMC_26M(sd_card); \ -} while (0) - -#define SD_SUPPORT_CLASS_TEN 0x01 -#define SD_SUPPORT_1V8 0x02 - -#define SD_SET_CLASS_TEN(sd_card) ((sd_card)->sd_setting |= SD_SUPPORT_CLASS_TEN) -#define SD_CHK_CLASS_TEN(sd_card) ((sd_card)->sd_setting & SD_SUPPORT_CLASS_TEN) -#define SD_CLR_CLASS_TEN(sd_card) ((sd_card)->sd_setting &= ~SD_SUPPORT_CLASS_TEN) -#define SD_SET_1V8(sd_card) ((sd_card)->sd_setting |= SD_SUPPORT_1V8) -#define SD_CHK_1V8(sd_card) ((sd_card)->sd_setting & SD_SUPPORT_1V8) -#define SD_CLR_1V8(sd_card) ((sd_card)->sd_setting &= ~SD_SUPPORT_1V8) - -struct sd_info { - u16 sd_type; - u8 err_code; - u8 sd_data_buf_ready; - u32 sd_addr; - u32 capacity; - - u8 raw_csd[16]; - u8 raw_scr[8]; - - /* Sequential RW */ - int seq_mode; - enum dma_data_direction pre_dir; - u32 pre_sec_addr; - u16 pre_sec_cnt; - - int cleanup_counter; - - int sd_clock; - - int mmc_dont_switch_bus; - -#ifdef SUPPORT_CPRM - int sd_pass_thru_en; - int pre_cmd_err; - u8 last_rsp_type; - u8 rsp[17]; -#endif - - u8 func_group1_mask; - u8 func_group2_mask; - u8 func_group3_mask; - u8 func_group4_mask; - - u8 sd_switch_fail; - u8 sd_read_phase; - -#ifdef SUPPORT_SD_LOCK - u8 sd_lock_status; - u8 sd_erase_status; - u8 sd_lock_notify; -#endif - int need_retune; -}; - -struct xd_delay_write_tag { - u32 old_phyblock; - u32 new_phyblock; - u32 logblock; - u8 pageoff; - u8 delay_write_flag; -}; - -struct xd_info { - u8 maker_code; - u8 device_code; - u8 block_shift; - u8 page_off; - u8 addr_cycle; - u16 cis_block; - u8 multi_flag; - u8 err_code; - u32 capacity; - - struct zone_entry *zone; - int zone_cnt; - - struct xd_delay_write_tag delay_write; - int cleanup_counter; - - int xd_clock; -}; - -#define MODE_512_SEQ 0x01 -#define MODE_2K_SEQ 0x02 - -#define TYPE_MS 0x0000 -#define TYPE_MSPRO 0x0001 - -#define MS_4BIT 0x0100 -#define MS_8BIT 0x0200 -#define MS_HG 0x0400 -#define MS_XC 0x0800 - -#define HG8BIT (MS_HG | MS_8BIT) - -#define CHK_MSPRO(ms_card) (((ms_card)->ms_type & 0xFF) == TYPE_MSPRO) -#define CHK_HG8BIT(ms_card) (CHK_MSPRO(ms_card) && (((ms_card)->ms_type & HG8BIT) == HG8BIT)) -#define CHK_MSXC(ms_card) (CHK_MSPRO(ms_card) && ((ms_card)->ms_type & MS_XC)) -#define CHK_MSHG(ms_card) (CHK_MSPRO(ms_card) && ((ms_card)->ms_type & MS_HG)) - -#define CHK_MS8BIT(ms_card) (((ms_card)->ms_type & MS_8BIT)) -#define CHK_MS4BIT(ms_card) (((ms_card)->ms_type & MS_4BIT)) - -struct ms_delay_write_tag { - u16 old_phyblock; - u16 new_phyblock; - u16 logblock; - u8 pageoff; - u8 delay_write_flag; -}; - -struct ms_info { - u16 ms_type; - u8 block_shift; - u8 page_off; - u16 total_block; - u16 boot_block; - u32 capacity; - - u8 check_ms_flow; - u8 switch_8bit_fail; - u8 err_code; - - struct zone_entry *segment; - int segment_cnt; - - int pro_under_formatting; - int format_status; - u16 progress; - u8 raw_sys_info[96]; -#ifdef SUPPORT_PCGL_1P18 - u8 raw_model_name[48]; -#endif - - u8 multi_flag; - - /* Sequential RW */ - u8 seq_mode; - enum dma_data_direction pre_dir; - u32 pre_sec_addr; - u16 pre_sec_cnt; - u32 total_sec_cnt; - - struct ms_delay_write_tag delay_write; - - int cleanup_counter; - - int ms_clock; - -#ifdef SUPPORT_MAGIC_GATE - u8 magic_gate_id[16]; - u8 mg_entry_num; - int mg_auth; /* flag to indicate authentication process */ -#endif -}; - -struct spi_info { - u8 use_clk; - u8 write_en; - u16 clk_div; - u8 err_code; - - int spi_clock; -}; - - -#ifdef _MSG_TRACE -struct trace_msg_t { - u16 line; -#define MSG_FUNC_LEN 64 - char func[MSG_FUNC_LEN]; -#define MSG_FILE_LEN 32 - char file[MSG_FILE_LEN]; -#define TIME_VAL_LEN 16 - u8 timeval_buf[TIME_VAL_LEN]; - u8 valid; -}; -#endif - -/************/ -/* LUN mode */ -/************/ -/* Single LUN, support xD/SD/MS */ -#define DEFAULT_SINGLE 0 -/* 2 LUN mode, support SD/MS */ -#define SD_MS_2LUN 1 -/* Single LUN, but only support SD/MS, for Barossa LQFP */ -#define SD_MS_1LUN 2 - -#define LAST_LUN_MODE 2 - -/* Barossa package */ -#define QFN 0 -#define LQFP 1 - -/******************/ -/* sd_ctl bit map */ -/******************/ -/* SD push point control, bit 0, 1 */ -#define SD_PUSH_POINT_CTL_MASK 0x03 -#define SD_PUSH_POINT_DELAY 0x01 -#define SD_PUSH_POINT_AUTO 0x02 -/* SD sample point control, bit 2, 3 */ -#define SD_SAMPLE_POINT_CTL_MASK 0x0C -#define SD_SAMPLE_POINT_DELAY 0x04 -#define SD_SAMPLE_POINT_AUTO 0x08 -/* SD DDR Tx phase set by user, bit 4 */ -#define SD_DDR_TX_PHASE_SET_BY_USER 0x10 -/* MMC DDR Tx phase set by user, bit 5 */ -#define MMC_DDR_TX_PHASE_SET_BY_USER 0x20 -/* Support MMC DDR mode, bit 6 */ -#define SUPPORT_MMC_DDR_MODE 0x40 -/* Reset MMC at first */ -#define RESET_MMC_FIRST 0x80 - -#define SEQ_START_CRITERIA 0x20 - -/* MS Power Class En */ -#define POWER_CLASS_2_EN 0x02 -#define POWER_CLASS_1_EN 0x01 - -#define MAX_SHOW_CNT 10 -#define MAX_RESET_CNT 3 - -#define SDIO_EXIST 0x01 -#define SDIO_IGNORED 0x02 - -#define CHK_SDIO_EXIST(chip) ((chip)->sdio_func_exist & SDIO_EXIST) -#define SET_SDIO_EXIST(chip) ((chip)->sdio_func_exist |= SDIO_EXIST) -#define CLR_SDIO_EXIST(chip) ((chip)->sdio_func_exist &= ~SDIO_EXIST) - -#define CHK_SDIO_IGNORED(chip) ((chip)->sdio_func_exist & SDIO_IGNORED) -#define SET_SDIO_IGNORED(chip) ((chip)->sdio_func_exist |= SDIO_IGNORED) -#define CLR_SDIO_IGNORED(chip) ((chip)->sdio_func_exist &= ~SDIO_IGNORED) - -struct rtsx_chip { - rtsx_dev_t *rtsx; - - u32 int_reg; /* Bus interrupt pending register */ - char max_lun; - void *context; - - void *host_cmds_ptr; /* host commands buffer pointer */ - dma_addr_t host_cmds_addr; - int ci; /* Command Index */ - - void *host_sg_tbl_ptr; /* SG descriptor table */ - dma_addr_t host_sg_tbl_addr; - int sgi; /* SG entry index */ - - struct scsi_cmnd *srb; /* current srb */ - struct sense_data_t sense_buffer[MAX_ALLOWED_LUN_CNT]; - - int cur_clk; /* current card clock */ - - /* Current accessed card */ - int cur_card; - - unsigned long need_release; /* need release bit map */ - unsigned long need_reset; /* need reset bit map */ - /* Flag to indicate that this card is just resumed from SS state, - * and need released before being resetted - */ - unsigned long need_reinit; - - int rw_need_retry; - -#ifdef SUPPORT_OCP - u32 ocp_int; - u8 ocp_stat; -#endif - - u8 card_exist; /* card exist bit map (physical exist) */ - u8 card_ready; /* card ready bit map (reset successfully) */ - u8 card_fail; /* card reset fail bit map */ - u8 card_ejected; /* card ejected bit map */ - u8 card_wp; /* card write protected bit map */ - - u8 lun_mc; /* flag to indicate whether to answer MediaChange */ - -#ifndef LED_AUTO_BLINK - int led_toggle_counter; -#endif - - int sd_reset_counter; - int xd_reset_counter; - int ms_reset_counter; - - /* card bus width */ - u8 card_bus_width[MAX_ALLOWED_LUN_CNT]; - /* card capacity */ - u32 capacity[MAX_ALLOWED_LUN_CNT]; - /* read/write card function pointer */ - card_rw_func rw_card[MAX_ALLOWED_LUN_CNT]; - /* read/write capacity, used for GPIO Toggle */ - u32 rw_cap[MAX_ALLOWED_LUN_CNT]; - /* card to lun mapping table */ - u8 card2lun[32]; - /* lun to card mapping table */ - u8 lun2card[MAX_ALLOWED_LUN_CNT]; - - int rw_fail_cnt[MAX_ALLOWED_LUN_CNT]; - - int sd_show_cnt; - int xd_show_cnt; - int ms_show_cnt; - - /* card information */ - struct sd_info sd_card; - struct xd_info xd_card; - struct ms_info ms_card; - - struct spi_info spi; - -#ifdef _MSG_TRACE - struct trace_msg_t trace_msg[TRACE_ITEM_CNT]; - int msg_idx; -#endif - - int auto_delink_cnt; - int auto_delink_allowed; - - int aspm_enabled; - - int sdio_aspm; - int sdio_idle; - int sdio_counter; - u8 sdio_raw_data[12]; - - u8 sd_io; - u8 sd_int; - - u8 rtsx_flag; - - int ss_counter; - int idle_counter; - enum RTSX_STAT rtsx_stat; - - u16 vendor_id; - u16 product_id; - u8 ic_version; - - int driver_first_load; - -#ifdef HW_AUTO_SWITCH_SD_BUS - int sdio_in_charge; -#endif - - u8 aspm_level[2]; - - int chip_insert_with_sdio; - - /* Options */ - - int adma_mode; - - int auto_delink_en; - int ss_en; - u8 lun_mode; - u8 aspm_l0s_l1_en; - - int power_down_in_ss; - - int sdr104_en; - int ddr50_en; - int sdr50_en; - - int baro_pkg; - - int asic_code; - int phy_debug_mode; - int hw_bypass_sd; - int sdio_func_exist; - int aux_pwr_exist; - u8 ms_power_class_en; - - int mspro_formatter_enable; - - int remote_wakeup_en; - - int ignore_sd; - int use_hw_setting; - - int ss_idle_period; - - int dynamic_aspm; - - int fpga_sd_sdr104_clk; - int fpga_sd_ddr50_clk; - int fpga_sd_sdr50_clk; - int fpga_sd_hs_clk; - int fpga_mmc_52m_clk; - int fpga_ms_hg_clk; - int fpga_ms_4bit_clk; - int fpga_ms_1bit_clk; - - int asic_sd_sdr104_clk; - int asic_sd_ddr50_clk; - int asic_sd_sdr50_clk; - int asic_sd_hs_clk; - int asic_mmc_52m_clk; - int asic_ms_hg_clk; - int asic_ms_4bit_clk; - int asic_ms_1bit_clk; - - u8 ssc_depth_sd_sdr104; - u8 ssc_depth_sd_ddr50; - u8 ssc_depth_sd_sdr50; - u8 ssc_depth_sd_hs; - u8 ssc_depth_mmc_52m; - u8 ssc_depth_ms_hg; - u8 ssc_depth_ms_4bit; - u8 ssc_depth_low_speed; - - u8 card_drive_sel; - u8 sd30_drive_sel_1v8; - u8 sd30_drive_sel_3v3; - - u8 sd_400mA_ocp_thd; - u8 sd_800mA_ocp_thd; - u8 ms_ocp_thd; - - int ssc_en; - int msi_en; - - int xd_timeout; - int sd_timeout; - int ms_timeout; - int mspro_timeout; - - int auto_power_down; - - int sd_ddr_tx_phase; - int mmc_ddr_tx_phase; - int sd_default_tx_phase; - int sd_default_rx_phase; - - int pmos_pwr_on_interval; - int sd_voltage_switch_delay; - int s3_pwr_off_delay; - - int force_clkreq_0; - int ft2_fast_mode; - - int do_delink_before_power_down; - int polling_config; - int sdio_retry_cnt; - - int delink_stage1_step; - int delink_stage2_step; - int delink_stage3_step; - - int auto_delink_in_L1; - int hp_watch_bios_hotplug; - int support_ms_8bit; - - u8 blink_led; - u8 phy_voltage; - u8 max_payload; - - u32 sd_speed_prior; - u32 sd_current_prior; - u32 sd_ctl; -}; - -#define rtsx_set_stat(chip, stat) \ -do { \ - if ((stat) != RTSX_STAT_IDLE) { \ - (chip)->idle_counter = 0; \ - } \ - (chip)->rtsx_stat = (enum RTSX_STAT)(stat); \ -} while (0) -#define rtsx_get_stat(chip) ((chip)->rtsx_stat) -#define rtsx_chk_stat(chip, stat) ((chip)->rtsx_stat == (stat)) - -#define RTSX_SET_DELINK(chip) ((chip)->rtsx_flag |= 0x01) -#define RTSX_CLR_DELINK(chip) ((chip)->rtsx_flag &= 0xFE) -#define RTSX_TST_DELINK(chip) ((chip)->rtsx_flag & 0x01) - -#define CHECK_PID(chip, pid) ((chip)->product_id == (pid)) -#define CHECK_BARO_PKG(chip, pkg) ((chip)->baro_pkg == (pkg)) -#define CHECK_LUN_MODE(chip, mode) ((chip)->lun_mode == (mode)) - -/* Power down control */ -#define SSC_PDCTL 0x01 -#define OC_PDCTL 0x02 - -int rtsx_force_power_on(struct rtsx_chip *chip, u8 ctl); -int rtsx_force_power_down(struct rtsx_chip *chip, u8 ctl); - -void rtsx_disable_card_int(struct rtsx_chip *chip); -void rtsx_enable_card_int(struct rtsx_chip *chip); -void rtsx_enable_bus_int(struct rtsx_chip *chip); -void rtsx_disable_bus_int(struct rtsx_chip *chip); -int rtsx_reset_chip(struct rtsx_chip *chip); -int rtsx_init_chip(struct rtsx_chip *chip); -void rtsx_release_chip(struct rtsx_chip *chip); -void rtsx_polling_func(struct rtsx_chip *chip); -void rtsx_undo_delink(struct rtsx_chip *chip); -void rtsx_stop_cmd(struct rtsx_chip *chip, int card); -int rtsx_write_register(struct rtsx_chip *chip, u16 addr, u8 mask, u8 data); -int rtsx_read_register(struct rtsx_chip *chip, u16 addr, u8 *data); -int rtsx_write_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 mask, u32 val); -int rtsx_read_cfg_dw(struct rtsx_chip *chip, u8 func_no, u16 addr, u32 *val); -int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len); -int rtsx_read_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, int len); -int rtsx_write_phy_register(struct rtsx_chip *chip, u8 addr, u16 val); -int rtsx_read_phy_register(struct rtsx_chip *chip, u8 addr, u16 *val); -int rtsx_read_efuse(struct rtsx_chip *chip, u8 addr, u8 *val); -int rtsx_write_efuse(struct rtsx_chip *chip, u8 addr, u8 val); -int rtsx_clr_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit); -int rtsx_set_phy_reg_bit(struct rtsx_chip *chip, u8 reg, u8 bit); -int rtsx_check_link_ready(struct rtsx_chip *chip); -void rtsx_enter_ss(struct rtsx_chip *chip); -void rtsx_exit_ss(struct rtsx_chip *chip); -int rtsx_pre_handle_interrupt(struct rtsx_chip *chip); -void rtsx_enter_L1(struct rtsx_chip *chip); -void rtsx_exit_L1(struct rtsx_chip *chip); -void rtsx_do_before_power_down(struct rtsx_chip *chip, int pm_stat); -void rtsx_enable_aspm(struct rtsx_chip *chip); -void rtsx_disable_aspm(struct rtsx_chip *chip); -int rtsx_read_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len); -int rtsx_write_ppbuf(struct rtsx_chip *chip, u8 *buf, int buf_len); -int rtsx_check_chip_exist(struct rtsx_chip *chip); - -#define RTSX_WRITE_REG(chip, addr, mask, data) \ -do { \ - int retval = rtsx_write_register((chip), (addr), (mask), (data)); \ - if (retval != STATUS_SUCCESS) { \ - TRACE_RET((chip), retval); \ - } \ -} while (0) - -#define RTSX_READ_REG(chip, addr, data) \ -do { \ - int retval = rtsx_read_register((chip), (addr), (data)); \ - if (retval != STATUS_SUCCESS) { \ - TRACE_RET((chip), retval); \ - } \ -} while (0) - -#endif /* __REALTEK_RTSX_CHIP_H */ diff --git a/drivers/staging/rts_pstor/rtsx_scsi.c b/drivers/staging/rts_pstor/rtsx_scsi.c deleted file mode 100644 index 86c41b3a42a..00000000000 --- a/drivers/staging/rts_pstor/rtsx_scsi.c +++ /dev/null @@ -1,3137 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include - -#include "rtsx.h" -#include "rtsx_transport.h" -#include "rtsx_sys.h" -#include "rtsx_card.h" -#include "rtsx_chip.h" -#include "rtsx_scsi.h" -#include "sd.h" -#include "ms.h" -#include "spi.h" - -void scsi_show_command(struct scsi_cmnd *srb) -{ - char *what = NULL; - int i, unknown_cmd = 0; - - switch (srb->cmnd[0]) { - case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break; - case REZERO_UNIT: what = "REZERO_UNIT"; break; - case REQUEST_SENSE: what = "REQUEST_SENSE"; break; - case FORMAT_UNIT: what = "FORMAT_UNIT"; break; - case READ_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break; - case REASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break; - case READ_6: what = "READ_6"; break; - case WRITE_6: what = "WRITE_6"; break; - case SEEK_6: what = "SEEK_6"; break; - case READ_REVERSE: what = "READ_REVERSE"; break; - case WRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break; - case SPACE: what = "SPACE"; break; - case INQUIRY: what = "INQUIRY"; break; - case RECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break; - case MODE_SELECT: what = "MODE_SELECT"; break; - case RESERVE: what = "RESERVE"; break; - case RELEASE: what = "RELEASE"; break; - case COPY: what = "COPY"; break; - case ERASE: what = "ERASE"; break; - case MODE_SENSE: what = "MODE_SENSE"; break; - case START_STOP: what = "START_STOP"; break; - case RECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break; - case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break; - case ALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break; - case SET_WINDOW: what = "SET_WINDOW"; break; - case READ_CAPACITY: what = "READ_CAPACITY"; break; - case READ_10: what = "READ_10"; break; - case WRITE_10: what = "WRITE_10"; break; - case SEEK_10: what = "SEEK_10"; break; - case WRITE_VERIFY: what = "WRITE_VERIFY"; break; - case VERIFY: what = "VERIFY"; break; - case SEARCH_HIGH: what = "SEARCH_HIGH"; break; - case SEARCH_EQUAL: what = "SEARCH_EQUAL"; break; - case SEARCH_LOW: what = "SEARCH_LOW"; break; - case SET_LIMITS: what = "SET_LIMITS"; break; - case READ_POSITION: what = "READ_POSITION"; break; - case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break; - case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break; - case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break; - case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break; - case COMPARE: what = "COMPARE"; break; - case COPY_VERIFY: what = "COPY_VERIFY"; break; - case WRITE_BUFFER: what = "WRITE_BUFFER"; break; - case READ_BUFFER: what = "READ_BUFFER"; break; - case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break; - case READ_LONG: what = "READ_LONG"; break; - case WRITE_LONG: what = "WRITE_LONG"; break; - case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break; - case WRITE_SAME: what = "WRITE_SAME"; break; - case GPCMD_READ_SUBCHANNEL: what = "READ SUBCHANNEL"; break; - case READ_TOC: what = "READ_TOC"; break; - case GPCMD_READ_HEADER: what = "READ HEADER"; break; - case GPCMD_PLAY_AUDIO_10: what = "PLAY AUDIO (10)"; break; - case GPCMD_PLAY_AUDIO_MSF: what = "PLAY AUDIO MSF"; break; - case GPCMD_GET_EVENT_STATUS_NOTIFICATION: - what = "GET EVENT/STATUS NOTIFICATION"; break; - case GPCMD_PAUSE_RESUME: what = "PAUSE/RESUME"; break; - case LOG_SELECT: what = "LOG_SELECT"; break; - case LOG_SENSE: what = "LOG_SENSE"; break; - case GPCMD_STOP_PLAY_SCAN: what = "STOP PLAY/SCAN"; break; - case GPCMD_READ_DISC_INFO: what = "READ DISC INFORMATION"; break; - case GPCMD_READ_TRACK_RZONE_INFO: - what = "READ TRACK INFORMATION"; break; - case GPCMD_RESERVE_RZONE_TRACK: what = "RESERVE TRACK"; break; - case GPCMD_SEND_OPC: what = "SEND OPC"; break; - case MODE_SELECT_10: what = "MODE_SELECT_10"; break; - case GPCMD_REPAIR_RZONE_TRACK: what = "REPAIR TRACK"; break; - case 0x59: what = "READ MASTER CUE"; break; - case MODE_SENSE_10: what = "MODE_SENSE_10"; break; - case GPCMD_CLOSE_TRACK: what = "CLOSE TRACK/SESSION"; break; - case 0x5C: what = "READ BUFFER CAPACITY"; break; - case 0x5D: what = "SEND CUE SHEET"; break; - case GPCMD_BLANK: what = "BLANK"; break; - case REPORT_LUNS: what = "REPORT LUNS"; break; - case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break; - case READ_12: what = "READ_12"; break; - case WRITE_12: what = "WRITE_12"; break; - case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break; - case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break; - case SEARCH_EQUAL_12: what = "SEARCH_EQUAL_12"; break; - case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break; - case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break; - case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break; - case GPCMD_READ_CD_MSF: what = "READ CD MSF"; break; - case GPCMD_SCAN: what = "SCAN"; break; - case GPCMD_SET_SPEED: what = "SET CD SPEED"; break; - case GPCMD_MECHANISM_STATUS: what = "MECHANISM STATUS"; break; - case GPCMD_READ_CD: what = "READ CD"; break; - case 0xE1: what = "WRITE CONTINUE"; break; - case WRITE_LONG_2: what = "WRITE_LONG_2"; break; - case VENDOR_CMND: what = "Realtek's vendor command"; break; - default: what = "(unknown command)"; unknown_cmd = 1; break; - } - - if (srb->cmnd[0] != TEST_UNIT_READY) - RTSX_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len); - - if (unknown_cmd) { - RTSX_DEBUGP(""); - for (i = 0; i < srb->cmd_len && i < 16; i++) - RTSX_DEBUGPN(" %02x", srb->cmnd[i]); - RTSX_DEBUGPN("\n"); - } -} - -void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type) -{ - switch (sense_type) { - case SENSE_TYPE_MEDIA_CHANGE: - set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_NOT_PRESENT: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_LBA_OVER_RANGE: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_WRITE_PROTECT: - set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0); - break; - - case SENSE_TYPE_MEDIA_WRITE_ERR: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0); - break; - - case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD: - set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0, - ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1); - break; - - case SENSE_TYPE_FORMAT_IN_PROGRESS: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, 0); - break; - - case SENSE_TYPE_FORMAT_CMD_FAILED: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0); - break; - -#ifdef SUPPORT_MAGIC_GATE - case SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0); - break; - - case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN: - set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0); - break; - - case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM: - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0); - break; - - case SENSE_TYPE_MG_WRITE_ERR: - set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0); - break; -#endif - -#ifdef SUPPORT_SD_LOCK - case SENSE_TYPE_MEDIA_READ_FORBIDDEN: - set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x11, 0x13, 0, 0); - break; -#endif - - case SENSE_TYPE_NO_SENSE: - default: - set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0); - break; - } -} - -void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, u8 sense_key, - u32 info, u8 asc, u8 ascq, u8 sns_key_info0, u16 sns_key_info1) -{ - struct sense_data_t *sense = &(chip->sense_buffer[lun]); - - sense->err_code = err_code; - sense->sense_key = sense_key; - sense->info[0] = (u8)(info >> 24); - sense->info[1] = (u8)(info >> 16); - sense->info[2] = (u8)(info >> 8); - sense->info[3] = (u8)info; - - sense->ad_sense_len = sizeof(struct sense_data_t) - 8; - sense->asc = asc; - sense->ascq = ascq; - if (sns_key_info0 != 0) { - sense->sns_key_info[0] = SKSV | sns_key_info0; - sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 8; - sense->sns_key_info[2] = sns_key_info1 & 0x0f; - } -} - -static int test_unit_ready(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - return TRANSPORT_FAILED; - } - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - -#ifdef SUPPORT_SD_LOCK - if (get_lun_card(chip, SCSI_LUN(srb)) == SD_CARD) { - struct sd_info *sd_card = &(chip->sd_card); - if (sd_card->sd_lock_notify) { - sd_card->sd_lock_notify = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } else if (sd_card->sd_lock_status & SD_LOCKED) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); - return TRANSPORT_FAILED; - } - } -#endif - - return TRANSPORT_GOOD; -} - -static unsigned char formatter_inquiry_str[20] = { - 'M', 'E', 'M', 'O', 'R', 'Y', 'S', 'T', 'I', 'C', 'K', -#ifdef SUPPORT_MAGIC_GATE - '-', 'M', 'G', /* Byte[47:49] */ -#else - 0x20, 0x20, 0x20, /* Byte[47:49] */ -#endif - -#ifdef SUPPORT_MAGIC_GATE - 0x0B, /* Byte[50]: MG, MS, MSPro, MSXC */ -#else - 0x09, /* Byte[50]: MS, MSPro, MSXC */ -#endif - 0x00, /* Byte[51]: Category Specific Commands */ - 0x00, /* Byte[52]: Access Control and feature */ - 0x20, 0x20, 0x20, /* Byte[53:55] */ -}; - -static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - char *inquiry_default = (char *)"Generic-xD/SD/M.S. 1.00 "; - char *inquiry_sdms = (char *)"Generic-SD/MemoryStick 1.00 "; - char *inquiry_sd = (char *)"Generic-SD/MMC 1.00 "; - char *inquiry_ms = (char *)"Generic-MemoryStick 1.00 "; - char *inquiry_string; - unsigned char sendbytes; - unsigned char *buf; - u8 card = get_lun_card(chip, lun); - int pro_formatter_flag = 0; - unsigned char inquiry_buf[] = { - QULIFIRE|DRCT_ACCESS_DEV, - RMB_DISC|0x0D, - 0x00, - 0x01, - 0x1f, - 0x02, - 0, - REL_ADR|WBUS_32|WBUS_16|SYNC|LINKED|CMD_QUE|SFT_RE, - }; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->lun2card[lun] == SD_CARD) - inquiry_string = inquiry_sd; - else - inquiry_string = inquiry_ms; - - } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) { - inquiry_string = inquiry_sdms; - } else { - inquiry_string = inquiry_default; - } - - buf = vmalloc(scsi_bufflen(srb)); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - -#ifdef SUPPORT_MAGIC_GATE - if ((chip->mspro_formatter_enable) && - (chip->lun2card[lun] & MS_CARD)) -#else - if (chip->mspro_formatter_enable) -#endif - { - if (!card || (card == MS_CARD)) - pro_formatter_flag = 1; - } - - if (pro_formatter_flag) { - if (scsi_bufflen(srb) < 56) - sendbytes = (unsigned char)(scsi_bufflen(srb)); - else - sendbytes = 56; - - } else { - if (scsi_bufflen(srb) < 36) - sendbytes = (unsigned char)(scsi_bufflen(srb)); - else - sendbytes = 36; - } - - if (sendbytes > 8) { - memcpy(buf, inquiry_buf, 8); - memcpy(buf + 8, inquiry_string, sendbytes - 8); - if (pro_formatter_flag) { - /* Additional Length */ - buf[4] = 0x33; - } - } else { - memcpy(buf, inquiry_buf, sendbytes); - } - - if (pro_formatter_flag) { - if (sendbytes > 36) - memcpy(buf + 36, formatter_inquiry_str, sendbytes - 36); - } - - scsi_set_resid(srb, 0); - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - vfree(buf); - - return TRANSPORT_GOOD; -} - - -static int start_stop_unit(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - - scsi_set_resid(srb, scsi_bufflen(srb)); - - if (srb->cmnd[1] == 1) - return TRANSPORT_GOOD; - - switch (srb->cmnd[0x4]) { - case STOP_MEDIUM: - /* Media disabled */ - return TRANSPORT_GOOD; - - case UNLOAD_MEDIUM: - /* Media shall be unload */ - if (check_card_ready(chip, lun)) - eject_card(chip, lun); - return TRANSPORT_GOOD; - - case MAKE_MEDIUM_READY: - case LOAD_MEDIUM: - if (check_card_ready(chip, lun)) { - return TRANSPORT_GOOD; - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - break; - } - - TRACE_RET(chip, TRANSPORT_ERROR); -} - - -static int allow_medium_removal(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int prevent; - - prevent = srb->cmnd[4] & 0x1; - - scsi_set_resid(srb, 0); - - if (prevent) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return TRANSPORT_GOOD; -} - - -static int request_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sense_data_t *sense; - unsigned int lun = SCSI_LUN(srb); - struct ms_info *ms_card = &(chip->ms_card); - unsigned char *tmp, *buf; - - sense = &(chip->sense_buffer[lun]); - - if ((get_lun_card(chip, lun) == MS_CARD) && ms_card->pro_under_formatting) { - if (ms_card->format_status == FORMAT_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - ms_card->pro_under_formatting = 0; - ms_card->progress = 0; - } else if (ms_card->format_status == FORMAT_IN_PROGRESS) { - /* Logical Unit Not Ready Format in Progress */ - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, - 0, (u16)(ms_card->progress)); - } else { - /* Format Command Failed */ - set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); - ms_card->pro_under_formatting = 0; - ms_card->progress = 0; - } - - rtsx_set_stat(chip, RTSX_STAT_RUN); - } - - buf = vmalloc(scsi_bufflen(srb)); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - tmp = (unsigned char *)sense; - memcpy(buf, tmp, scsi_bufflen(srb)); - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - vfree(buf); - - scsi_set_resid(srb, 0); - /* Reset Sense Data */ - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - return TRANSPORT_GOOD; -} - -static void ms_mode_sense(struct rtsx_chip *chip, u8 cmd, - int lun, u8 *buf, int buf_len) -{ - struct ms_info *ms_card = &(chip->ms_card); - int sys_info_offset; - int data_size = buf_len; - int support_format = 0; - int i = 0; - - if (cmd == MODE_SENSE) { - sys_info_offset = 8; - if (data_size > 0x68) - data_size = 0x68; - - buf[i++] = 0x67; /* Mode Data Length */ - } else { - sys_info_offset = 12; - if (data_size > 0x6C) - data_size = 0x6C; - - buf[i++] = 0x00; /* Mode Data Length (MSB) */ - buf[i++] = 0x6A; /* Mode Data Length (LSB) */ - } - - /* Medium Type Code */ - if (check_card_ready(chip, lun)) { - if (CHK_MSXC(ms_card)) { - support_format = 1; - buf[i++] = 0x40; - } else if (CHK_MSPRO(ms_card)) { - support_format = 1; - buf[i++] = 0x20; - } else { - buf[i++] = 0x10; - } - - /* WP */ - if (check_card_wp(chip, lun)) - buf[i++] = 0x80; - else - buf[i++] = 0x00; - - } else { - buf[i++] = 0x00; /* MediaType */ - buf[i++] = 0x00; /* WP */ - } - - buf[i++] = 0x00; /* Reserved */ - - if (cmd == MODE_SENSE_10) { - buf[i++] = 0x00; /* Reserved */ - buf[i++] = 0x00; /* Block descriptor length(MSB) */ - buf[i++] = 0x00; /* Block descriptor length(LSB) */ - - /* The Following Data is the content of "Page 0x20" */ - if (data_size >= 9) - buf[i++] = 0x20; /* Page Code */ - if (data_size >= 10) - buf[i++] = 0x62; /* Page Length */ - if (data_size >= 11) - buf[i++] = 0x00; /* No Access Control */ - if (data_size >= 12) { - if (support_format) - buf[i++] = 0xC0; /* SF, SGM */ - else - buf[i++] = 0x00; - } - } else { - /* The Following Data is the content of "Page 0x20" */ - if (data_size >= 5) - buf[i++] = 0x20; /* Page Code */ - if (data_size >= 6) - buf[i++] = 0x62; /* Page Length */ - if (data_size >= 7) - buf[i++] = 0x00; /* No Access Control */ - if (data_size >= 8) { - if (support_format) - buf[i++] = 0xC0; /* SF, SGM */ - else - buf[i++] = 0x00; - } - } - - if (data_size > sys_info_offset) { - /* 96 Bytes Attribute Data */ - int len = data_size - sys_info_offset; - len = (len < 96) ? len : 96; - - memcpy(buf + sys_info_offset, ms_card->raw_sys_info, len); - } -} - -static int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - unsigned int dataSize; - int status; - int pro_formatter_flag; - unsigned char pageCode, *buf; - u8 card = get_lun_card(chip, lun); - -#ifndef SUPPORT_MAGIC_GATE - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - scsi_set_resid(srb, scsi_bufflen(srb)); - TRACE_RET(chip, TRANSPORT_FAILED); - } -#endif - - pro_formatter_flag = 0; - dataSize = 8; -#ifdef SUPPORT_MAGIC_GATE - if ((chip->lun2card[lun] & MS_CARD)) { - if (!card || (card == MS_CARD)) { - dataSize = 108; - if (chip->mspro_formatter_enable) - pro_formatter_flag = 1; - } - } -#else - if (card == MS_CARD) { - if (chip->mspro_formatter_enable) { - pro_formatter_flag = 1; - dataSize = 108; - } - } -#endif - - buf = kmalloc(dataSize, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - pageCode = srb->cmnd[2] & 0x3f; - - if ((pageCode == 0x3F) || (pageCode == 0x1C) || - (pageCode == 0x00) || - (pro_formatter_flag && (pageCode == 0x20))) { - if (srb->cmnd[0] == MODE_SENSE) { - if ((pageCode == 0x3F) || (pageCode == 0x20)) { - ms_mode_sense(chip, srb->cmnd[0], - lun, buf, dataSize); - } else { - dataSize = 4; - buf[0] = 0x03; - buf[1] = 0x00; - if (check_card_wp(chip, lun)) - buf[2] = 0x80; - else - buf[2] = 0x00; - - buf[3] = 0x00; - } - } else { - if ((pageCode == 0x3F) || (pageCode == 0x20)) { - ms_mode_sense(chip, srb->cmnd[0], - lun, buf, dataSize); - } else { - dataSize = 8; - buf[0] = 0x00; - buf[1] = 0x06; - buf[2] = 0x00; - if (check_card_wp(chip, lun)) - buf[3] = 0x80; - else - buf[3] = 0x00; - buf[4] = 0x00; - buf[5] = 0x00; - buf[6] = 0x00; - buf[7] = 0x00; - } - } - status = TRANSPORT_GOOD; - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - scsi_set_resid(srb, scsi_bufflen(srb)); - status = TRANSPORT_FAILED; - } - - if (status == TRANSPORT_GOOD) { - unsigned int len = min(scsi_bufflen(srb), dataSize); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - } - kfree(buf); - - return status; -} - -static int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &(chip->sd_card); -#endif - unsigned int lun = SCSI_LUN(srb); - int retval; - u32 start_sec; - u16 sec_cnt; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - if (!check_card_ready(chip, lun) || (get_card_size(chip, lun) == 0)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_erase_status) { - /* Accessing to any card is forbidden - * until the erase procedure of SD is completed - */ - RTSX_DEBUGP("SD card being erased!\n"); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (get_lun_card(chip, lun) == SD_CARD) { - if (sd_card->sd_lock_status & SD_LOCKED) { - RTSX_DEBUGP("SD card locked!\n"); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } -#endif - - if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) { - start_sec = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | - ((u32)srb->cmnd[4] << 8) | ((u32)srb->cmnd[5]); - sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { - start_sec = ((u32)(srb->cmnd[1] & 0x1F) << 16) | - ((u32)srb->cmnd[2] << 8) | ((u32)srb->cmnd[3]); - sec_cnt = srb->cmnd[4]; - } else if ((srb->cmnd[0] == VENDOR_CMND) && (srb->cmnd[1] == SCSI_APP_CMD) && - ((srb->cmnd[2] == PP_READ10) || (srb->cmnd[2] == PP_WRITE10))) { - start_sec = ((u32)srb->cmnd[4] << 24) | ((u32)srb->cmnd[5] << 16) | - ((u32)srb->cmnd[6] << 8) | ((u32)srb->cmnd[7]); - sec_cnt = ((u16)(srb->cmnd[9]) << 8) | srb->cmnd[10]; - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - /* In some test, we will receive a start_sec like 0xFFFFFFFF. - * In this situation, start_sec + sec_cnt will overflow, so we - * need to judge start_sec at first - */ - if ((start_sec > get_card_size(chip, lun)) || - ((start_sec + sec_cnt) > get_card_size(chip, lun))) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (sec_cnt == 0) { - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - } - - if (chip->rw_fail_cnt[lun] == 3) { - RTSX_DEBUGP("read/write fail three times in succession\n"); - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - if (check_card_wp(chip, lun)) { - RTSX_DEBUGP("Write protected card!\n"); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - if (CHECK_PID(chip, 0x5209) && chip->max_payload) { - u8 val = 0x10 | (chip->max_payload << 5); - retval = rtsx_write_cfg_dw(chip, 0, 0x78, 0xFF, val); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_ERROR); - } - } - - retval = card_rw(srb, chip, start_sec, sec_cnt); - if (retval != STATUS_SUCCESS) { - if (chip->need_release & chip->lun2card[lun]) { - chip->rw_fail_cnt[lun] = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - } else { - chip->rw_fail_cnt[lun]++; - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - } - retval = TRANSPORT_FAILED; - TRACE_GOTO(chip, Exit); - } else { - chip->rw_fail_cnt[lun] = 0; - retval = TRANSPORT_GOOD; - } - - scsi_set_resid(srb, 0); - -Exit: - if (srb->sc_data_direction == DMA_TO_DEVICE) { - if (CHECK_PID(chip, 0x5209) && chip->max_payload) { - retval = rtsx_write_cfg_dw(chip, 0, 0x78, 0xFF, 0x10); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_ERROR); - } - } - - return retval; -} - -static int read_format_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned char *buf; - unsigned int lun = SCSI_LUN(srb); - unsigned int buf_len; - u8 card = get_lun_card(chip, lun); - u32 card_size; - int desc_cnt; - int i = 0; - - if (!check_card_ready(chip, lun)) { - if (!chip->mspro_formatter_enable) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - buf_len = (scsi_bufflen(srb) > 12) ? 0x14 : 12; - - buf = kmalloc(buf_len, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - buf[i++] = 0; - buf[i++] = 0; - buf[i++] = 0; - - /* Capacity List Length */ - if ((buf_len > 12) && chip->mspro_formatter_enable && - (chip->lun2card[lun] & MS_CARD) && - (!card || (card == MS_CARD))) { - buf[i++] = 0x10; - desc_cnt = 2; - } else { - buf[i++] = 0x08; - desc_cnt = 1; - } - - while (desc_cnt) { - if (check_card_ready(chip, lun)) { - card_size = get_card_size(chip, lun); - buf[i++] = (unsigned char)(card_size >> 24); - buf[i++] = (unsigned char)(card_size >> 16); - buf[i++] = (unsigned char)(card_size >> 8); - buf[i++] = (unsigned char)card_size; - - if (desc_cnt == 2) - buf[i++] = 2; - else - buf[i++] = 0; - } else { - buf[i++] = 0xFF; - buf[i++] = 0xFF; - buf[i++] = 0xFF; - buf[i++] = 0xFF; - - if (desc_cnt == 2) - buf[i++] = 3; - else - buf[i++] = 0; - } - - buf[i++] = 0x00; - buf[i++] = 0x02; - buf[i++] = 0x00; - - desc_cnt--; - } - - buf_len = min(scsi_bufflen(srb), buf_len); - rtsx_stor_set_xfer_buf(buf, buf_len, srb); - kfree(buf); - - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - return TRANSPORT_GOOD; -} - -static int read_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned char *buf; - unsigned int lun = SCSI_LUN(srb); - u32 card_size; - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - return TRANSPORT_FAILED; - } - - buf = kmalloc(8, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - card_size = get_card_size(chip, lun); - buf[0] = (unsigned char)((card_size - 1) >> 24); - buf[1] = (unsigned char)((card_size - 1) >> 16); - buf[2] = (unsigned char)((card_size - 1) >> 8); - buf[3] = (unsigned char)(card_size - 1); - - buf[4] = 0x00; - buf[5] = 0x00; - buf[6] = 0x02; - buf[7] = 0x00; - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - kfree(buf); - - scsi_set_resid(srb, 0); - - return TRANSPORT_GOOD; -} - -static int read_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - buf = (u8 *)vmalloc(len); - if (!buf) - TRACE_RET(chip, TRANSPORT_ERROR); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - for (i = 0; i < len; i++) { - retval = spi_read_eeprom(chip, i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (len == 511) { - retval = spi_erase_eeprom_chip(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } else { - len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); - buf = (u8 *)vmalloc(len); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - for (i = 0; i < len; i++) { - retval = spi_write_eeprom(chip, i, buf[i]); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - vfree(buf); - } - - return TRANSPORT_GOOD; -} - -static int read_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3]; - len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - if (addr < 0xFC00) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - buf = (u8 *)vmalloc(len); - if (!buf) - TRACE_RET(chip, TRANSPORT_ERROR); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - for (i = 0; i < len; i++) { - retval = rtsx_read_register(chip, addr + i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3]; - len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - if (addr < 0xFC00) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); - buf = (u8 *)vmalloc(len); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - for (i = 0; i < len; i++) { - retval = rtsx_write_register(chip, addr + i, 0xFF, buf[i]); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int get_sd_csd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - unsigned int lun = SCSI_LUN(srb); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (get_lun_card(chip, lun) != SD_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - rtsx_stor_set_xfer_buf(sd_card->raw_csd, scsi_bufflen(srb), srb); - - return TRANSPORT_GOOD; -} - -static int toggle_gpio_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - u8 gpio = srb->cmnd[2]; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - if (gpio > 3) - gpio = 1; - toggle_gpio(chip, gpio); - - return TRANSPORT_GOOD; -} - -#ifdef _MSG_TRACE -static int trace_msg_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned char *ptr, *buf = NULL; - int i, msg_cnt; - u8 clear; - unsigned int buf_len; - - buf_len = 4 + ((2 + MSG_FUNC_LEN + MSG_FILE_LEN + TIME_VAL_LEN) * TRACE_ITEM_CNT); - - if ((scsi_bufflen(srb) < buf_len) || (scsi_sglist(srb) == NULL)) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - clear = srb->cmnd[2]; - - buf = (unsigned char *)vmalloc(scsi_bufflen(srb)); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - ptr = buf; - - if (chip->trace_msg[chip->msg_idx].valid) - msg_cnt = TRACE_ITEM_CNT; - else - msg_cnt = chip->msg_idx; - - *(ptr++) = (u8)(msg_cnt >> 24); - *(ptr++) = (u8)(msg_cnt >> 16); - *(ptr++) = (u8)(msg_cnt >> 8); - *(ptr++) = (u8)msg_cnt; - RTSX_DEBUGP("Trace message count is %d\n", msg_cnt); - - for (i = 1; i <= msg_cnt; i++) { - int j, idx; - - idx = chip->msg_idx - i; - if (idx < 0) - idx += TRACE_ITEM_CNT; - - *(ptr++) = (u8)(chip->trace_msg[idx].line >> 8); - *(ptr++) = (u8)(chip->trace_msg[idx].line); - for (j = 0; j < MSG_FUNC_LEN; j++) - *(ptr++) = chip->trace_msg[idx].func[j]; - - for (j = 0; j < MSG_FILE_LEN; j++) - *(ptr++) = chip->trace_msg[idx].file[j]; - - for (j = 0; j < TIME_VAL_LEN; j++) - *(ptr++) = chip->trace_msg[idx].timeval_buf[j]; - } - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - vfree(buf); - - if (clear) { - chip->msg_idx = 0; - for (i = 0; i < TRACE_ITEM_CNT; i++) - chip->trace_msg[i].valid = 0; - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} -#endif - -static int read_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - u8 addr, buf[4]; - u32 val; - unsigned int len; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = srb->cmnd[4]; - - val = rtsx_readl(chip, addr); - RTSX_DEBUGP("Host register (0x%x): 0x%x\n", addr, val); - - buf[0] = (u8)(val >> 24); - buf[1] = (u8)(val >> 16); - buf[2] = (u8)(val >> 8); - buf[3] = (u8)val; - - len = min(scsi_bufflen(srb), (unsigned int)4); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - return TRANSPORT_GOOD; -} - -static int write_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - u8 addr, buf[4]; - u32 val; - unsigned int len; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = srb->cmnd[4]; - - len = min(scsi_bufflen(srb), (unsigned int)4); - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - val = ((u32)buf[0] << 24) | ((u32)buf[1] << 16) | ((u32)buf[2] << 8) | buf[3]; - - rtsx_writel(chip, addr, val); - - return TRANSPORT_GOOD; -} - -static int set_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned lun = SCSI_LUN(srb); - - if (srb->cmnd[3] == 1) { - /* Variable Clock */ - struct xd_info *xd_card = &(chip->xd_card); - struct sd_info *sd_card = &(chip->sd_card); - struct ms_info *ms_card = &(chip->ms_card); - - switch (srb->cmnd[4]) { - case XD_CARD: - xd_card->xd_clock = srb->cmnd[5]; - break; - - case SD_CARD: - sd_card->sd_clock = srb->cmnd[5]; - break; - - case MS_CARD: - ms_card->ms_clock = srb->cmnd[5]; - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } else if (srb->cmnd[3] == 2) { - if (srb->cmnd[4]) { - chip->blink_led = 1; - } else { - int retval; - - chip->blink_led = 0; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - turn_off_led(chip, LED_GPIO); - } - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return TRANSPORT_GOOD; -} - -static int get_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - - if (srb->cmnd[3] == 1) { - struct xd_info *xd_card = &(chip->xd_card); - struct sd_info *sd_card = &(chip->sd_card); - struct ms_info *ms_card = &(chip->ms_card); - u8 tmp; - - switch (srb->cmnd[4]) { - case XD_CARD: - tmp = (u8)(xd_card->xd_clock); - break; - - case SD_CARD: - tmp = (u8)(sd_card->sd_clock); - break; - - case MS_CARD: - tmp = (u8)(ms_card->ms_clock); - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - rtsx_stor_set_xfer_buf(&tmp, 1, srb); - } else if (srb->cmnd[3] == 2) { - u8 tmp = chip->blink_led; - rtsx_stor_set_xfer_buf(&tmp, 1, srb); - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return TRANSPORT_GOOD; -} - -static int dma_access_ring_buffer(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - unsigned int lun = SCSI_LUN(srb); - u16 len; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - len = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; - len = min(len, (u16)scsi_bufflen(srb)); - - if (srb->sc_data_direction == DMA_FROM_DEVICE) - RTSX_DEBUGP("Read from device\n"); - else - RTSX_DEBUGP("Write to device\n"); - - retval = rtsx_transfer_data(chip, 0, scsi_sglist(srb), len, - scsi_sg_count(srb), srb->sc_data_direction, 1000); - if (retval < 0) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - - TRACE_RET(chip, TRANSPORT_FAILED); - } - scsi_set_resid(srb, 0); - - return TRANSPORT_GOOD; -} - -static int get_dev_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - struct ms_info *ms_card = &(chip->ms_card); - int buf_len; - unsigned int lun = SCSI_LUN(srb); - u8 card = get_lun_card(chip, lun); - u8 status[32]; -#ifdef SUPPORT_OCP - u8 oc_now_mask = 0, oc_ever_mask = 0; -#endif - - memset(status, 0, 32); - - status[0] = (u8)(chip->product_id); - status[1] = chip->ic_version; - - if (chip->auto_delink_en) - status[2] = 0x10; - else - status[2] = 0x00; - - status[3] = 20; - status[4] = 10; - status[5] = 05; - status[6] = 21; - - if (chip->card_wp) - status[7] = 0x20; - else - status[7] = 0x00; - -#ifdef SUPPORT_OCP - status[8] = 0; - if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (chip->lun2card[lun] == MS_CARD)) { - oc_now_mask = MS_OC_NOW; - oc_ever_mask = MS_OC_EVER; - } else { - oc_now_mask = SD_OC_NOW; - oc_ever_mask = SD_OC_EVER; - } - - if (chip->ocp_stat & oc_now_mask) - status[8] |= 0x02; - - if (chip->ocp_stat & oc_ever_mask) - status[8] |= 0x01; -#endif - - if (card == SD_CARD) { - if (CHK_SD(sd_card)) { - if (CHK_SD_HCXC(sd_card)) { - if (sd_card->capacity > 0x4000000) - status[0x0E] = 0x02; - else - status[0x0E] = 0x01; - } else { - status[0x0E] = 0x00; - } - - if (CHK_SD_SDR104(sd_card)) - status[0x0F] = 0x03; - else if (CHK_SD_DDR50(sd_card)) - status[0x0F] = 0x04; - else if (CHK_SD_SDR50(sd_card)) - status[0x0F] = 0x02; - else if (CHK_SD_HS(sd_card)) - status[0x0F] = 0x01; - else - status[0x0F] = 0x00; - } else { - if (CHK_MMC_SECTOR_MODE(sd_card)) - status[0x0E] = 0x01; - else - status[0x0E] = 0x00; - - if (CHK_MMC_DDR52(sd_card)) - status[0x0F] = 0x03; - else if (CHK_MMC_52M(sd_card)) - status[0x0F] = 0x02; - else if (CHK_MMC_26M(sd_card)) - status[0x0F] = 0x01; - else - status[0x0F] = 0x00; - } - } else if (card == MS_CARD) { - if (CHK_MSPRO(ms_card)) { - if (CHK_MSXC(ms_card)) - status[0x0E] = 0x01; - else - status[0x0E] = 0x00; - - if (CHK_HG8BIT(ms_card)) - status[0x0F] = 0x01; - else - status[0x0F] = 0x00; - } - } - -#ifdef SUPPORT_SD_LOCK - if (card == SD_CARD) { - status[0x17] = 0x80; - if (sd_card->sd_erase_status) - status[0x17] |= 0x01; - if (sd_card->sd_lock_status & SD_LOCKED) { - status[0x17] |= 0x02; - status[0x07] |= 0x40; - } - if (sd_card->sd_lock_status & SD_PWD_EXIST) - status[0x17] |= 0x04; - } else { - status[0x17] = 0x00; - } - - RTSX_DEBUGP("status[0x17] = 0x%x\n", status[0x17]); -#endif - - status[0x18] = 0x8A; - status[0x1A] = 0x28; -#ifdef SUPPORT_SD_LOCK - status[0x1F] = 0x01; -#endif - - buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(status)); - rtsx_stor_set_xfer_buf(status, buf_len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - return TRANSPORT_GOOD; -} - -static int set_chip_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int phy_debug_mode; - int retval; - u16 reg; - - if (!CHECK_PID(chip, 0x5208)) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - phy_debug_mode = (int)(srb->cmnd[3]); - - if (phy_debug_mode) { - chip->phy_debug_mode = 1; - retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - rtsx_disable_bus_int(chip); - - retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - reg |= 0x0001; - retval = rtsx_write_phy_register(chip, 0x1C, reg); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } else { - chip->phy_debug_mode = 0; - retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0x77); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - rtsx_enable_bus_int(chip); - - retval = rtsx_read_phy_register(chip, 0x1C, ®); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - reg &= 0xFFFE; - retval = rtsx_write_phy_register(chip, 0x1C, reg); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return TRANSPORT_GOOD; -} - -static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval = STATUS_SUCCESS; - unsigned int lun = SCSI_LUN(srb); - u8 cmd_type, mask, value, idx; - u16 addr; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - switch (srb->cmnd[3]) { - case INIT_BATCHCMD: - rtsx_init_cmd(chip); - break; - - case ADD_BATCHCMD: - cmd_type = srb->cmnd[4]; - if (cmd_type > 2) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - addr = (srb->cmnd[5] << 8) | srb->cmnd[6]; - mask = srb->cmnd[7]; - value = srb->cmnd[8]; - rtsx_add_cmd(chip, cmd_type, addr, mask, value); - break; - - case SEND_BATCHCMD: - retval = rtsx_send_cmd(chip, 0, 1000); - break; - - case GET_BATCHRSP: - idx = srb->cmnd[4]; - value = *(rtsx_get_cmd_data(chip) + idx); - if (scsi_bufflen(srb) < 1) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - rtsx_stor_set_xfer_buf(&value, 1, srb); - scsi_set_resid(srb, 0); - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return TRANSPORT_GOOD; -} - -static int suit_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - - switch (srb->cmnd[3]) { - case INIT_BATCHCMD: - case ADD_BATCHCMD: - case SEND_BATCHCMD: - case GET_BATCHRSP: - result = rw_mem_cmd_buf(srb, chip); - break; - default: - result = TRANSPORT_ERROR; - } - - return result; -} - -static int read_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - u16 val; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; - - if (len % 2) - len -= len % 2; - - if (len) { - buf = (u8 *)vmalloc(len); - if (!buf) - TRACE_RET(chip, TRANSPORT_ERROR); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - for (i = 0; i < len / 2; i++) { - retval = rtsx_read_phy_register(chip, addr + i, &val); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - buf[2*i] = (u8)(val >> 8); - buf[2*i+1] = (u8)val; - } - - len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - } - - return TRANSPORT_GOOD; -} - -static int write_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - u16 val; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; - - if (len % 2) - len -= len % 2; - - if (len) { - len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); - - buf = (u8 *)vmalloc(len); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - for (i = 0; i < len / 2; i++) { - val = ((u16)buf[2*i] << 8) | buf[2*i+1]; - retval = rtsx_write_phy_register(chip, addr + i, val); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - vfree(buf); - } - - return TRANSPORT_GOOD; -} - -static int erase_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr; - int retval; - u8 mode; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - mode = srb->cmnd[3]; - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - - if (mode == 0) { - retval = spi_erase_eeprom_chip(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } else if (mode == 1) { - retval = spi_erase_eeprom_byte(chip, addr); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } else { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return TRANSPORT_GOOD; -} - -static int read_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; - - buf = (u8 *)vmalloc(len); - if (!buf) - TRACE_RET(chip, TRANSPORT_ERROR); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - for (i = 0; i < len; i++) { - retval = spi_read_eeprom(chip, addr + i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned short addr, len, i; - int retval; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; - len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; - - len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); - buf = (u8 *)vmalloc(len); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - for (i = 0; i < len; i++) { - retval = spi_write_eeprom(chip, addr + i, buf[i]); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int read_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 addr, len, i; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = srb->cmnd[4]; - len = srb->cmnd[5]; - - buf = (u8 *)vmalloc(len); - if (!buf) - TRACE_RET(chip, TRANSPORT_ERROR); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - for (i = 0; i < len; i++) { - retval = rtsx_read_efuse(chip, addr + i, buf + i); - if (retval != STATUS_SUCCESS) { - vfree(buf); - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - len = (u8)min(scsi_bufflen(srb), (unsigned int)len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval, result = TRANSPORT_GOOD; - u16 val; - u8 addr, len, i; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - addr = srb->cmnd[4]; - len = srb->cmnd[5]; - - len = (u8)min(scsi_bufflen(srb), (unsigned int)len); - buf = (u8 *)vmalloc(len); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_force_power_on(chip, SSC_PDCTL); - if (retval != STATUS_SUCCESS) { - vfree(buf); - TRACE_RET(chip, TRANSPORT_ERROR); - } - - if (chip->asic_code) { - retval = rtsx_read_phy_register(chip, 0x08, &val); - if (retval != STATUS_SUCCESS) { - vfree(buf); - TRACE_RET(chip, TRANSPORT_ERROR); - } - - retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); - if (retval != STATUS_SUCCESS) { - vfree(buf); - TRACE_RET(chip, TRANSPORT_ERROR); - } - - wait_timeout(600); - - retval = rtsx_write_phy_register(chip, 0x08, 0x4C00 | chip->phy_voltage); - if (retval != STATUS_SUCCESS) { - vfree(buf); - TRACE_RET(chip, TRANSPORT_ERROR); - } - - retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); - if (retval != STATUS_SUCCESS) { - vfree(buf); - TRACE_RET(chip, TRANSPORT_ERROR); - } - - wait_timeout(600); - } - - retval = card_power_on(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) { - vfree(buf); - TRACE_RET(chip, TRANSPORT_ERROR); - } - - wait_timeout(50); - - for (i = 0; i < len; i++) { - retval = rtsx_write_efuse(chip, addr + i, buf[i]); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - result = TRANSPORT_FAILED; - TRACE_GOTO(chip, Exit); - } - } - -Exit: - vfree(buf); - - retval = card_power_off(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_ERROR); - - if (chip->asic_code) { - retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_ERROR); - - wait_timeout(600); - - retval = rtsx_write_phy_register(chip, 0x08, val); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_ERROR); - - retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_ERROR); - } - - return result; -} - -static int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 func, func_max; - u16 addr, len; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - func = srb->cmnd[3]; - addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; - len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7]; - - RTSX_DEBUGP("%s: func = %d, addr = 0x%x, len = %d\n", __func__, func, addr, len); - - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) - func_max = 1; - else - func_max = 0; - - if (func > func_max) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - buf = (u8 *)vmalloc(len); - if (!buf) - TRACE_RET(chip, TRANSPORT_ERROR); - - retval = rtsx_read_cfg_seq(chip, func, addr, buf, len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - vfree(buf); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - len = (u16)min(scsi_bufflen(srb), (unsigned int)len); - rtsx_stor_set_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 func, func_max; - u16 addr, len; - u8 *buf; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - func = srb->cmnd[3]; - addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; - len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7]; - - RTSX_DEBUGP("%s: func = %d, addr = 0x%x\n", __func__, func, addr); - - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) - func_max = 1; - else - func_max = 0; - - if (func > func_max) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); - buf = (u8 *)vmalloc(len); - if (!buf) - TRACE_RET(chip, TRANSPORT_ERROR); - - rtsx_stor_get_xfer_buf(buf, len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - len); - - retval = rtsx_write_cfg_seq(chip, func, addr, buf, len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); - vfree(buf); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - vfree(buf); - - return TRANSPORT_GOOD; -} - -static int app_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - - switch (srb->cmnd[2]) { - case PP_READ10: - case PP_WRITE10: - result = read_write(srb, chip); - break; - - case READ_HOST_REG: - result = read_host_reg(srb, chip); - break; - - case WRITE_HOST_REG: - result = write_host_reg(srb, chip); - break; - - case GET_VAR: - result = get_variable(srb, chip); - break; - - case SET_VAR: - result = set_variable(srb, chip); - break; - - case DMA_READ: - case DMA_WRITE: - result = dma_access_ring_buffer(srb, chip); - break; - - case READ_PHY: - result = read_phy_register(srb, chip); - break; - - case WRITE_PHY: - result = write_phy_register(srb, chip); - break; - - case ERASE_EEPROM2: - result = erase_eeprom2(srb, chip); - break; - - case READ_EEPROM2: - result = read_eeprom2(srb, chip); - break; - - case WRITE_EEPROM2: - result = write_eeprom2(srb, chip); - break; - - case READ_EFUSE: - result = read_efuse(srb, chip); - break; - - case WRITE_EFUSE: - result = write_efuse(srb, chip); - break; - - case READ_CFG: - result = read_cfg_byte(srb, chip); - break; - - case WRITE_CFG: - result = write_cfg_byte(srb, chip); - break; - - case SET_CHIP_MODE: - result = set_chip_mode(srb, chip); - break; - - case SUIT_CMD: - result = suit_cmd(srb, chip); - break; - - case GET_DEV_STATUS: - result = get_dev_status(srb, chip); - break; - - default: - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return result; -} - - -static int read_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - u8 rtsx_status[16]; - int buf_len; - unsigned int lun = SCSI_LUN(srb); - - rtsx_status[0] = (u8)(chip->vendor_id >> 8); - rtsx_status[1] = (u8)(chip->vendor_id); - - rtsx_status[2] = (u8)(chip->product_id >> 8); - rtsx_status[3] = (u8)(chip->product_id); - - rtsx_status[4] = (u8)lun; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->lun2card[lun] == SD_CARD) - rtsx_status[5] = 2; - else - rtsx_status[5] = 3; - } else { - if (chip->card_exist) { - if (chip->card_exist & XD_CARD) - rtsx_status[5] = 4; - else if (chip->card_exist & SD_CARD) - rtsx_status[5] = 2; - else if (chip->card_exist & MS_CARD) - rtsx_status[5] = 3; - else - rtsx_status[5] = 7; - } else { - rtsx_status[5] = 7; - } - } - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - rtsx_status[6] = 2; - else - rtsx_status[6] = 1; - - rtsx_status[7] = (u8)(chip->product_id); - rtsx_status[8] = chip->ic_version; - - if (check_card_exist(chip, lun)) - rtsx_status[9] = 1; - else - rtsx_status[9] = 0; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) - rtsx_status[10] = 0; - else - rtsx_status[10] = 1; - - if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { - if (chip->lun2card[lun] == SD_CARD) - rtsx_status[11] = SD_CARD; - else - rtsx_status[11] = MS_CARD; - } else { - rtsx_status[11] = XD_CARD | SD_CARD | MS_CARD; - } - - if (check_card_ready(chip, lun)) - rtsx_status[12] = 1; - else - rtsx_status[12] = 0; - - if (get_lun_card(chip, lun) == XD_CARD) { - rtsx_status[13] = 0x40; - } else if (get_lun_card(chip, lun) == SD_CARD) { - struct sd_info *sd_card = &(chip->sd_card); - - rtsx_status[13] = 0x20; - if (CHK_SD(sd_card)) { - if (CHK_SD_HCXC(sd_card)) - rtsx_status[13] |= 0x04; - if (CHK_SD_HS(sd_card)) - rtsx_status[13] |= 0x02; - } else { - rtsx_status[13] |= 0x08; - if (CHK_MMC_52M(sd_card)) - rtsx_status[13] |= 0x02; - if (CHK_MMC_SECTOR_MODE(sd_card)) - rtsx_status[13] |= 0x04; - } - } else if (get_lun_card(chip, lun) == MS_CARD) { - struct ms_info *ms_card = &(chip->ms_card); - - if (CHK_MSPRO(ms_card)) { - rtsx_status[13] = 0x38; - if (CHK_HG8BIT(ms_card)) - rtsx_status[13] |= 0x04; -#ifdef SUPPORT_MSXC - if (CHK_MSXC(ms_card)) - rtsx_status[13] |= 0x01; -#endif - } else { - rtsx_status[13] = 0x30; - } - } else { - if (CHECK_LUN_MODE(chip, DEFAULT_SINGLE)) { -#ifdef SUPPORT_SDIO - if (chip->sd_io && chip->sd_int) - rtsx_status[13] = 0x60; - else - rtsx_status[13] = 0x70; -#else - rtsx_status[13] = 0x70; -#endif - } else { - if (chip->lun2card[lun] == SD_CARD) - rtsx_status[13] = 0x20; - else - rtsx_status[13] = 0x30; - } - } - - rtsx_status[14] = 0x78; - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) - rtsx_status[15] = 0x83; - else - rtsx_status[15] = 0x82; - - buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(rtsx_status)); - rtsx_stor_set_xfer_buf(rtsx_status, buf_len, srb); - scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); - - return TRANSPORT_GOOD; -} - -static int get_card_bus_width(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - u8 card, bus_width; - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - card = get_lun_card(chip, lun); - if ((card == SD_CARD) || (card == MS_CARD)) { - bus_width = chip->card_bus_width[lun]; - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - rtsx_stor_set_xfer_buf(&bus_width, scsi_bufflen(srb), srb); - - return TRANSPORT_GOOD; -} - -static int spi_vendor_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - unsigned int lun = SCSI_LUN(srb); - u8 gpio_dir; - - if (CHECK_PID(chip, 0x5208) || CHECK_PID(chip, 0x5288)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - rtsx_force_power_on(chip, SSC_PDCTL); - - rtsx_read_register(chip, CARD_GPIO_DIR, &gpio_dir); - rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir & 0x06); - - switch (srb->cmnd[2]) { - case SCSI_SPI_GETSTATUS: - result = spi_get_status(srb, chip); - break; - - case SCSI_SPI_SETPARAMETER: - result = spi_set_parameter(srb, chip); - break; - - case SCSI_SPI_READFALSHID: - result = spi_read_flash_id(srb, chip); - break; - - case SCSI_SPI_READFLASH: - result = spi_read_flash(srb, chip); - break; - - case SCSI_SPI_WRITEFLASH: - result = spi_write_flash(srb, chip); - break; - - case SCSI_SPI_WRITEFLASHSTATUS: - result = spi_write_flash_status(srb, chip); - break; - - case SCSI_SPI_ERASEFLASH: - result = spi_erase_flash(srb, chip); - break; - - default: - rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); - - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); - - if (result != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - return TRANSPORT_GOOD; -} - -static int vendor_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - - switch (srb->cmnd[1]) { - case READ_STATUS: - result = read_status(srb, chip); - break; - - case READ_MEM: - result = read_mem(srb, chip); - break; - - case WRITE_MEM: - result = write_mem(srb, chip); - break; - - case READ_EEPROM: - result = read_eeprom(srb, chip); - break; - - case WRITE_EEPROM: - result = write_eeprom(srb, chip); - break; - - case TOGGLE_GPIO: - result = toggle_gpio_cmd(srb, chip); - break; - - case GET_SD_CSD: - result = get_sd_csd(srb, chip); - break; - - case GET_BUS_WIDTH: - result = get_card_bus_width(srb, chip); - break; - -#ifdef _MSG_TRACE - case TRACE_MSG: - result = trace_msg_cmd(srb, chip); - break; -#endif - - case SCSI_APP_CMD: - result = app_cmd(srb, chip); - break; - - case SPI_VENDOR_COMMAND: - result = spi_vendor_cmd(srb, chip); - break; - - default: - set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return result; -} - -#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK) -void led_shine(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - u16 sec_cnt; - - if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) - sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) - sec_cnt = srb->cmnd[4]; - else - return; - - if (chip->rw_cap[lun] >= GPIO_TOGGLE_THRESHOLD) { - toggle_gpio(chip, LED_GPIO); - chip->rw_cap[lun] = 0; - } else { - chip->rw_cap[lun] += sec_cnt; - } -} -#endif - -static int ms_format_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - unsigned int lun = SCSI_LUN(srb); - int retval, quick_format; - - if (get_lun_card(chip, lun) != MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if ((srb->cmnd[3] != 0x4D) || (srb->cmnd[4] != 0x47) || - (srb->cmnd[5] != 0x66) || (srb->cmnd[6] != 0x6D) || - (srb->cmnd[7] != 0x74)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - - if (!check_card_ready(chip, lun) || - (get_card_size(chip, lun) == 0)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - if (srb->cmnd[8] & 0x01) - quick_format = 0; - else - quick_format = 1; - - if (!(chip->card_ready & MS_CARD)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (chip->card_wp & MS_CARD) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (!CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - retval = mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} - -#ifdef SUPPORT_PCGL_1P18 -static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - unsigned int lun = SCSI_LUN(srb); - u8 dev_info_id, data_len; - u8 *buf; - unsigned int buf_len; - int i; - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - if ((get_lun_card(chip, lun) != MS_CARD)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if ((srb->cmnd[2] != 0xB0) || (srb->cmnd[4] != 0x4D) || - (srb->cmnd[5] != 0x53) || (srb->cmnd[6] != 0x49) || - (srb->cmnd[7] != 0x44)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - dev_info_id = srb->cmnd[3]; - if ((CHK_MSXC(ms_card) && (dev_info_id == 0x10)) || - (!CHK_MSXC(ms_card) && (dev_info_id == 0x13)) || - !CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (dev_info_id == 0x15) - buf_len = data_len = 0x3A; - else - buf_len = data_len = 0x6A; - - buf = kmalloc(buf_len, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, TRANSPORT_ERROR); - - i = 0; - /* GET Memory Stick Media Information Response Header */ - buf[i++] = 0x00; /* Data length MSB */ - buf[i++] = data_len; /* Data length LSB */ - /* Device Information Type Code */ - if (CHK_MSXC(ms_card)) - buf[i++] = 0x03; - else - buf[i++] = 0x02; - - /* SGM bit */ - buf[i++] = 0x01; - /* Reserved */ - buf[i++] = 0x00; - buf[i++] = 0x00; - buf[i++] = 0x00; - /* Number of Device Information */ - buf[i++] = 0x01; - - /* Device Information Body */ - - /* Device Information ID Number */ - buf[i++] = dev_info_id; - /* Device Information Length */ - if (dev_info_id == 0x15) - data_len = 0x31; - else - data_len = 0x61; - - buf[i++] = 0x00; /* Data length MSB */ - buf[i++] = data_len; /* Data length LSB */ - /* Valid Bit */ - buf[i++] = 0x80; - if ((dev_info_id == 0x10) || (dev_info_id == 0x13)) { - /* System Information */ - memcpy(buf+i, ms_card->raw_sys_info, 96); - } else { - /* Model Name */ - memcpy(buf+i, ms_card->raw_model_name, 48); - } - - rtsx_stor_set_xfer_buf(buf, buf_len, srb); - - if (dev_info_id == 0x15) - scsi_set_resid(srb, scsi_bufflen(srb)-0x3C); - else - scsi_set_resid(srb, scsi_bufflen(srb)-0x6C); - - kfree(buf); - return STATUS_SUCCESS; -} -#endif - -static int ms_sp_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval = TRANSPORT_ERROR; - - if (srb->cmnd[2] == MS_FORMAT) - retval = ms_format_cmnd(srb, chip); -#ifdef SUPPORT_PCGL_1P18 - else if (srb->cmnd[2] == GET_MS_INFORMATION) - retval = get_ms_information(srb, chip); -#endif - - return retval; -} - -#ifdef SUPPORT_CPRM -static int sd_extention_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - unsigned int lun = SCSI_LUN(srb); - int result; - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - sd_cleanup_work(chip); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - if ((get_lun_card(chip, lun) != SD_CARD)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - switch (srb->cmnd[0]) { - case SD_PASS_THRU_MODE: - result = sd_pass_thru_mode(srb, chip); - break; - - case SD_EXECUTE_NO_DATA: - result = sd_execute_no_data(srb, chip); - break; - - case SD_EXECUTE_READ: - result = sd_execute_read_data(srb, chip); - break; - - case SD_EXECUTE_WRITE: - result = sd_execute_write_data(srb, chip); - break; - - case SD_GET_RSP: - result = sd_get_cmd_rsp(srb, chip); - break; - - case SD_HW_RST: - result = sd_hw_rst(srb, chip); - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - return result; -} -#endif - -#ifdef SUPPORT_MAGIC_GATE -static int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - unsigned int lun = SCSI_LUN(srb); - int retval; - u8 key_format; - - RTSX_DEBUGP("--%s--\n", __func__); - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - ms_cleanup_work(chip); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - if ((get_lun_card(chip, lun) != MS_CARD)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (srb->cmnd[7] != KC_MG_R_PRO) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (!CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - key_format = srb->cmnd[10] & 0x3F; - RTSX_DEBUGP("key_format = 0x%x\n", key_format); - - switch (key_format) { - case KF_GET_LOC_EKB: - if ((scsi_bufflen(srb) == 0x41C) && - (srb->cmnd[8] == 0x04) && - (srb->cmnd[9] == 0x1C)) { - retval = mg_get_local_EKB(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - case KF_RSP_CHG: - if ((scsi_bufflen(srb) == 0x24) && - (srb->cmnd[8] == 0x00) && - (srb->cmnd[9] == 0x24)) { - retval = mg_get_rsp_chg(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - case KF_GET_ICV: - ms_card->mg_entry_num = srb->cmnd[5]; - if ((scsi_bufflen(srb) == 0x404) && - (srb->cmnd[8] == 0x04) && - (srb->cmnd[9] == 0x04) && - (srb->cmnd[2] == 0x00) && - (srb->cmnd[3] == 0x00) && - (srb->cmnd[4] == 0x00) && - (srb->cmnd[5] < 32)) { - retval = mg_get_ICV(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} - -static int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct ms_info *ms_card = &(chip->ms_card); - unsigned int lun = SCSI_LUN(srb); - int retval; - u8 key_format; - - RTSX_DEBUGP("--%s--\n", __func__); - - rtsx_disable_aspm(chip); - - if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { - rtsx_exit_ss(chip); - wait_timeout(100); - } - rtsx_set_stat(chip, RTSX_STAT_RUN); - - ms_cleanup_work(chip); - - if (!check_card_ready(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - if (check_card_wp(chip, lun)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - if ((get_lun_card(chip, lun) != MS_CARD)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (srb->cmnd[7] != KC_MG_R_PRO) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (!CHK_MSPRO(ms_card)) { - set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - key_format = srb->cmnd[10] & 0x3F; - RTSX_DEBUGP("key_format = 0x%x\n", key_format); - - switch (key_format) { - case KF_SET_LEAF_ID: - if ((scsi_bufflen(srb) == 0x0C) && - (srb->cmnd[8] == 0x00) && - (srb->cmnd[9] == 0x0C)) { - retval = mg_set_leaf_id(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - case KF_CHG_HOST: - if ((scsi_bufflen(srb) == 0x0C) && - (srb->cmnd[8] == 0x00) && - (srb->cmnd[9] == 0x0C)) { - retval = mg_chg(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - case KF_RSP_HOST: - if ((scsi_bufflen(srb) == 0x0C) && - (srb->cmnd[8] == 0x00) && - (srb->cmnd[9] == 0x0C)) { - retval = mg_rsp(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - case KF_SET_ICV: - ms_card->mg_entry_num = srb->cmnd[5]; - if ((scsi_bufflen(srb) == 0x404) && - (srb->cmnd[8] == 0x04) && - (srb->cmnd[9] == 0x04) && - (srb->cmnd[2] == 0x00) && - (srb->cmnd[3] == 0x00) && - (srb->cmnd[4] == 0x00) && - (srb->cmnd[5] < 32)) { - retval = mg_set_ICV(srb, chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - } else { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} -#endif - -int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ -#ifdef SUPPORT_SD_LOCK - struct sd_info *sd_card = &(chip->sd_card); -#endif - struct ms_info *ms_card = &(chip->ms_card); - unsigned int lun = SCSI_LUN(srb); - int result; - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_erase_status) { - /* Block all SCSI command except for - * REQUEST_SENSE and rs_ppstatus - */ - if (!((srb->cmnd[0] == VENDOR_CMND) && - (srb->cmnd[1] == SCSI_APP_CMD) && - (srb->cmnd[2] == GET_DEV_STATUS)) && - (srb->cmnd[0] != REQUEST_SENSE)) { - /* Logical Unit Not Ready Format in Progress */ - set_sense_data(chip, lun, CUR_ERR, - 0x02, 0, 0x04, 0x04, 0, 0); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } -#endif - - if ((get_lun_card(chip, lun) == MS_CARD) && - (ms_card->format_status == FORMAT_IN_PROGRESS)) { - if ((srb->cmnd[0] != REQUEST_SENSE) && (srb->cmnd[0] != INQUIRY)) { - /* Logical Unit Not Ready Format in Progress */ - set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, - 0, (u16)(ms_card->progress)); - TRACE_RET(chip, TRANSPORT_FAILED); - } - } - - switch (srb->cmnd[0]) { - case READ_10: - case WRITE_10: - case READ_6: - case WRITE_6: - result = read_write(srb, chip); -#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK) - led_shine(srb, chip); -#endif - break; - - case TEST_UNIT_READY: - result = test_unit_ready(srb, chip); - break; - - case INQUIRY: - result = inquiry(srb, chip); - break; - - case READ_CAPACITY: - result = read_capacity(srb, chip); - break; - - case START_STOP: - result = start_stop_unit(srb, chip); - break; - - case ALLOW_MEDIUM_REMOVAL: - result = allow_medium_removal(srb, chip); - break; - - case REQUEST_SENSE: - result = request_sense(srb, chip); - break; - - case MODE_SENSE: - case MODE_SENSE_10: - result = mode_sense(srb, chip); - break; - - case 0x23: - result = read_format_capacity(srb, chip); - break; - - case VENDOR_CMND: - result = vendor_cmnd(srb, chip); - break; - - case MS_SP_CMND: - result = ms_sp_cmnd(srb, chip); - break; - -#ifdef SUPPORT_CPRM - case SD_PASS_THRU_MODE: - case SD_EXECUTE_NO_DATA: - case SD_EXECUTE_READ: - case SD_EXECUTE_WRITE: - case SD_GET_RSP: - case SD_HW_RST: - result = sd_extention_cmnd(srb, chip); - break; -#endif - -#ifdef SUPPORT_MAGIC_GATE - case CMD_MSPRO_MG_RKEY: - result = mg_report_key(srb, chip); - break; - - case CMD_MSPRO_MG_SKEY: - result = mg_send_key(srb, chip); - break; -#endif - - case FORMAT_UNIT: - case MODE_SELECT: - case VERIFY: - result = TRANSPORT_GOOD; - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - result = TRANSPORT_FAILED; - } - - return result; -} diff --git a/drivers/staging/rts_pstor/rtsx_scsi.h b/drivers/staging/rts_pstor/rtsx_scsi.h deleted file mode 100644 index 64b84992fdb..00000000000 --- a/drivers/staging/rts_pstor/rtsx_scsi.h +++ /dev/null @@ -1,142 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __REALTEK_RTSX_SCSI_H -#define __REALTEK_RTSX_SCSI_H - -#include "rtsx.h" -#include "rtsx_chip.h" - -#define MS_SP_CMND 0xFA -#define MS_FORMAT 0xA0 -#define GET_MS_INFORMATION 0xB0 - -#define VENDOR_CMND 0xF0 - -#define READ_STATUS 0x09 - -#define READ_EEPROM 0x04 -#define WRITE_EEPROM 0x05 -#define READ_MEM 0x0D -#define WRITE_MEM 0x0E -#define GET_BUS_WIDTH 0x13 -#define GET_SD_CSD 0x14 -#define TOGGLE_GPIO 0x15 -#define TRACE_MSG 0x18 - -#define SCSI_APP_CMD 0x10 - -#define PP_READ10 0x1A -#define PP_WRITE10 0x0A -#define READ_HOST_REG 0x1D -#define WRITE_HOST_REG 0x0D -#define SET_VAR 0x05 -#define GET_VAR 0x15 -#define DMA_READ 0x16 -#define DMA_WRITE 0x06 -#define GET_DEV_STATUS 0x10 -#define SET_CHIP_MODE 0x27 -#define SUIT_CMD 0xE0 -#define WRITE_PHY 0x07 -#define READ_PHY 0x17 -#define WRITE_EEPROM2 0x03 -#define READ_EEPROM2 0x13 -#define ERASE_EEPROM2 0x23 -#define WRITE_EFUSE 0x04 -#define READ_EFUSE 0x14 -#define WRITE_CFG 0x0E -#define READ_CFG 0x1E - -#define SPI_VENDOR_COMMAND 0x1C - -#define SCSI_SPI_GETSTATUS 0x00 -#define SCSI_SPI_SETPARAMETER 0x01 -#define SCSI_SPI_READFALSHID 0x02 -#define SCSI_SPI_READFLASH 0x03 -#define SCSI_SPI_WRITEFLASH 0x04 -#define SCSI_SPI_WRITEFLASHSTATUS 0x05 -#define SCSI_SPI_ERASEFLASH 0x06 - -#define INIT_BATCHCMD 0x41 -#define ADD_BATCHCMD 0x42 -#define SEND_BATCHCMD 0x43 -#define GET_BATCHRSP 0x44 - -#define CHIP_NORMALMODE 0x00 -#define CHIP_DEBUGMODE 0x01 - -/* SD Pass Through Command Extension */ -#define SD_PASS_THRU_MODE 0xD0 -#define SD_EXECUTE_NO_DATA 0xD1 -#define SD_EXECUTE_READ 0xD2 -#define SD_EXECUTE_WRITE 0xD3 -#define SD_GET_RSP 0xD4 -#define SD_HW_RST 0xD6 - -#ifdef SUPPORT_MAGIC_GATE -#define CMD_MSPRO_MG_RKEY 0xA4 /* Report Key Command */ -#define CMD_MSPRO_MG_SKEY 0xA3 /* Send Key Command */ - -/* CBWCB field: key class */ -#define KC_MG_R_PRO 0xBE /* MG-R PRO*/ - -/* CBWCB field: key format */ -#define KF_SET_LEAF_ID 0x31 /* Set Leaf ID */ -#define KF_GET_LOC_EKB 0x32 /* Get Local EKB */ -#define KF_CHG_HOST 0x33 /* Challenge (host) */ -#define KF_RSP_CHG 0x34 /* Response and Challenge (device) */ -#define KF_RSP_HOST 0x35 /* Response (host) */ -#define KF_GET_ICV 0x36 /* Get ICV */ -#define KF_SET_ICV 0x37 /* SSet ICV */ -#endif - -/* Sense type */ -#define SENSE_TYPE_NO_SENSE 0 -#define SENSE_TYPE_MEDIA_CHANGE 1 -#define SENSE_TYPE_MEDIA_NOT_PRESENT 2 -#define SENSE_TYPE_MEDIA_LBA_OVER_RANGE 3 -#define SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT 4 -#define SENSE_TYPE_MEDIA_WRITE_PROTECT 5 -#define SENSE_TYPE_MEDIA_INVALID_CMD_FIELD 6 -#define SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR 7 -#define SENSE_TYPE_MEDIA_WRITE_ERR 8 -#define SENSE_TYPE_FORMAT_IN_PROGRESS 9 -#define SENSE_TYPE_FORMAT_CMD_FAILED 10 -#ifdef SUPPORT_MAGIC_GATE -#define SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB 0x0b -#define SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN 0x0c -#define SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM 0x0d -#define SENSE_TYPE_MG_WRITE_ERR 0x0e -#endif -#ifdef SUPPORT_SD_LOCK -#define SENSE_TYPE_MEDIA_READ_FORBIDDEN 0x10 /* FOR Locked SD card*/ -#endif - -void scsi_show_command(struct scsi_cmnd *srb); -void set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type); -void set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, u8 sense_key, - u32 info, u8 asc, u8 ascq, u8 sns_key_info0, u16 sns_key_info1); -int rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip); - -#endif /* __REALTEK_RTSX_SCSI_H */ - diff --git a/drivers/staging/rts_pstor/rtsx_sys.h b/drivers/staging/rts_pstor/rtsx_sys.h deleted file mode 100644 index 8e55a3a8b00..00000000000 --- a/drivers/staging/rts_pstor/rtsx_sys.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __RTSX_SYS_H -#define __RTSX_SYS_H - -#include "rtsx.h" -#include "rtsx_chip.h" -#include "rtsx_card.h" - -typedef dma_addr_t ULONG_PTR; - -static inline void rtsx_exclusive_enter_ss(struct rtsx_chip *chip) -{ - struct rtsx_dev *dev = chip->rtsx; - - spin_lock(&(dev->reg_lock)); - rtsx_enter_ss(chip); - spin_unlock(&(dev->reg_lock)); -} - -static inline void rtsx_reset_detected_cards(struct rtsx_chip *chip, int flag) -{ - rtsx_reset_cards(chip); -} - -#define RTSX_MSG_IN_INT(x) - -#endif /* __RTSX_SYS_H */ - diff --git a/drivers/staging/rts_pstor/rtsx_transport.c b/drivers/staging/rts_pstor/rtsx_transport.c deleted file mode 100644 index 1f9a4248044..00000000000 --- a/drivers/staging/rts_pstor/rtsx_transport.c +++ /dev/null @@ -1,769 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include - -#include "rtsx.h" -#include "rtsx_scsi.h" -#include "rtsx_transport.h" -#include "rtsx_chip.h" -#include "rtsx_card.h" -#include "debug.h" - -/*********************************************************************** - * Scatter-gather transfer buffer access routines - ***********************************************************************/ - -/* Copy a buffer of length buflen to/from the srb's transfer buffer. - * (Note: for scatter-gather transfers (srb->use_sg > 0), srb->request_buffer - * points to a list of s-g entries and we ignore srb->request_bufflen. - * For non-scatter-gather transfers, srb->request_buffer points to the - * transfer buffer itself and srb->request_bufflen is the buffer's length.) - * Update the *index and *offset variables so that the next copy will - * pick up from where this one left off. */ - -unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, - unsigned int *offset, enum xfer_buf_dir dir) -{ - unsigned int cnt; - - /* If not using scatter-gather, just transfer the data directly. - * Make certain it will fit in the available buffer space. */ - if (scsi_sg_count(srb) == 0) { - if (*offset >= scsi_bufflen(srb)) - return 0; - cnt = min(buflen, scsi_bufflen(srb) - *offset); - if (dir == TO_XFER_BUF) - memcpy((unsigned char *) scsi_sglist(srb) + *offset, - buffer, cnt); - else - memcpy(buffer, (unsigned char *) scsi_sglist(srb) + - *offset, cnt); - *offset += cnt; - - /* Using scatter-gather. We have to go through the list one entry - * at a time. Each s-g entry contains some number of pages, and - * each page has to be kmap()'ed separately. If the page is already - * in kernel-addressable memory then kmap() will return its address. - * If the page is not directly accessible -- such as a user buffer - * located in high memory -- then kmap() will map it to a temporary - * position in the kernel's virtual address space. */ - } else { - struct scatterlist *sg = - (struct scatterlist *) scsi_sglist(srb) - + *index; - - /* This loop handles a single s-g list entry, which may - * include multiple pages. Find the initial page structure - * and the starting offset within the page, and update - * the *offset and *index values for the next loop. */ - cnt = 0; - while (cnt < buflen && *index < scsi_sg_count(srb)) { - struct page *page = sg_page(sg) + - ((sg->offset + *offset) >> PAGE_SHIFT); - unsigned int poff = - (sg->offset + *offset) & (PAGE_SIZE-1); - unsigned int sglen = sg->length - *offset; - - if (sglen > buflen - cnt) { - - /* Transfer ends within this s-g entry */ - sglen = buflen - cnt; - *offset += sglen; - } else { - - /* Transfer continues to next s-g entry */ - *offset = 0; - ++*index; - ++sg; - } - - /* Transfer the data for all the pages in this - * s-g entry. For each page: call kmap(), do the - * transfer, and call kunmap() immediately after. */ - while (sglen > 0) { - unsigned int plen = min(sglen, (unsigned int) - PAGE_SIZE - poff); - unsigned char *ptr = kmap(page); - - if (dir == TO_XFER_BUF) - memcpy(ptr + poff, buffer + cnt, plen); - else - memcpy(buffer + cnt, ptr + poff, plen); - kunmap(page); - - /* Start at the beginning of the next page */ - poff = 0; - ++page; - cnt += plen; - sglen -= plen; - } - } - } - - /* Return the amount actually transferred */ - return cnt; -} - -/* Store the contents of buffer into srb's transfer buffer and set the -* SCSI residue. */ -void rtsx_stor_set_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) -{ - unsigned int index = 0, offset = 0; - - rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset, - TO_XFER_BUF); - if (buflen < scsi_bufflen(srb)) - scsi_set_resid(srb, scsi_bufflen(srb) - buflen); -} - -void rtsx_stor_get_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb) -{ - unsigned int index = 0, offset = 0; - - rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset, - FROM_XFER_BUF); - if (buflen < scsi_bufflen(srb)) - scsi_set_resid(srb, scsi_bufflen(srb) - buflen); -} - - -/*********************************************************************** - * Transport routines - ***********************************************************************/ - -/* Invoke the transport and basic error-handling/recovery methods - * - * This is used to send the message to the device and receive the response. - */ -void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int result; - - result = rtsx_scsi_handler(srb, chip); - - /* if the command gets aborted by the higher layers, we need to - * short-circuit all other processing - */ - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) { - RTSX_DEBUGP("-- command was aborted\n"); - srb->result = DID_ABORT << 16; - goto Handle_Errors; - } - - /* if there is a transport error, reset and don't auto-sense */ - if (result == TRANSPORT_ERROR) { - RTSX_DEBUGP("-- transport indicates error, resetting\n"); - srb->result = DID_ERROR << 16; - goto Handle_Errors; - } - - srb->result = SAM_STAT_GOOD; - - /* - * If we have a failure, we're going to do a REQUEST_SENSE - * automatically. Note that we differentiate between a command - * "failure" and an "error" in the transport mechanism. - */ - if (result == TRANSPORT_FAILED) { - /* set the result so the higher layers expect this data */ - srb->result = SAM_STAT_CHECK_CONDITION; - memcpy(srb->sense_buffer, - (unsigned char *)&(chip->sense_buffer[SCSI_LUN(srb)]), - sizeof(struct sense_data_t)); - } - - return; - - /* Error and abort processing: try to resynchronize with the device - * by issuing a port reset. If that fails, try a class-specific - * device reset. */ -Handle_Errors: - return; -} - -void rtsx_add_cmd(struct rtsx_chip *chip, - u8 cmd_type, u16 reg_addr, u8 mask, u8 data) -{ - u32 *cb = (u32 *)(chip->host_cmds_ptr); - u32 val = 0; - - val |= (u32)(cmd_type & 0x03) << 30; - val |= (u32)(reg_addr & 0x3FFF) << 16; - val |= (u32)mask << 8; - val |= (u32)data; - - spin_lock_irq(&chip->rtsx->reg_lock); - if (chip->ci < (HOST_CMDS_BUF_LEN / 4)) - cb[(chip->ci)++] = cpu_to_le32(val); - - spin_unlock_irq(&chip->rtsx->reg_lock); -} - -void rtsx_send_cmd_no_wait(struct rtsx_chip *chip) -{ - u32 val = 1 << 31; - - rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); - - val |= (u32)(chip->ci * 4) & 0x00FFFFFF; - /* Hardware Auto Response */ - val |= 0x40000000; - rtsx_writel(chip, RTSX_HCBCTLR, val); -} - -int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - u32 val = 1 << 31; - long timeleft; - int err = 0; - - if (card == SD_CARD) - rtsx->check_card_cd = SD_EXIST; - else if (card == MS_CARD) - rtsx->check_card_cd = MS_EXIST; - else if (card == XD_CARD) - rtsx->check_card_cd = XD_EXIST; - else - rtsx->check_card_cd = 0; - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - rtsx->trans_result = TRANS_NOT_READY; - init_completion(&trans_done); - rtsx->trans_state = STATE_TRANS_CMD; - - rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr); - - val |= (u32)(chip->ci * 4) & 0x00FFFFFF; - /* Hardware Auto Response */ - val |= 0x40000000; - rtsx_writel(chip, RTSX_HCBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - /* Wait for TRANS_OK_INT */ - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, timeout * HZ / 1000); - if (timeleft <= 0) { - RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); - err = -ETIMEDOUT; - TRACE_GOTO(chip, finish_send_cmd); - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) - err = -EIO; - else if (rtsx->trans_result == TRANS_RESULT_OK) - err = 0; - - spin_unlock_irq(&rtsx->reg_lock); - -finish_send_cmd: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - -static inline void rtsx_add_sg_tbl( - struct rtsx_chip *chip, u32 addr, u32 len, u8 option) -{ - u64 *sgb = (u64 *)(chip->host_sg_tbl_ptr); - u64 val = 0; - u32 temp_len = 0; - u8 temp_opt = 0; - - do { - if (len > 0x80000) { - temp_len = 0x80000; - temp_opt = option & (~SG_END); - } else { - temp_len = len; - temp_opt = option; - } - val = ((u64)addr << 32) | ((u64)temp_len << 12) | temp_opt; - - if (chip->sgi < (HOST_SG_TBL_BUF_LEN / 8)) - sgb[(chip->sgi)++] = cpu_to_le64(val); - - len -= temp_len; - addr += temp_len; - } while (len); -} - -static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card, - struct scatterlist *sg, int num_sg, unsigned int *index, - unsigned int *offset, int size, - enum dma_data_direction dma_dir, int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - u8 dir; - int sg_cnt, i, resid; - int err = 0; - long timeleft; - struct scatterlist *sg_ptr; - u32 val = TRIG_DMA; - - if ((sg == NULL) || (num_sg <= 0) || !offset || !index) - return -EIO; - - if (dma_dir == DMA_TO_DEVICE) - dir = HOST_TO_DEVICE; - else if (dma_dir == DMA_FROM_DEVICE) - dir = DEVICE_TO_HOST; - else - return -ENXIO; - - if (card == SD_CARD) - rtsx->check_card_cd = SD_EXIST; - else if (card == MS_CARD) - rtsx->check_card_cd = MS_EXIST; - else if (card == XD_CARD) - rtsx->check_card_cd = XD_EXIST; - else - rtsx->check_card_cd = 0; - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - - rtsx->trans_state = STATE_TRANS_SG; - rtsx->trans_result = TRANS_NOT_READY; - - spin_unlock_irq(&rtsx->reg_lock); - - sg_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); - - resid = size; - sg_ptr = sg; - chip->sgi = 0; - /* Usually the next entry will be @sg@ + 1, but if this sg element - * is part of a chained scatterlist, it could jump to the start of - * a new scatterlist array. So here we use sg_next to move to - * the proper sg - */ - for (i = 0; i < *index; i++) - sg_ptr = sg_next(sg_ptr); - for (i = *index; i < sg_cnt; i++) { - dma_addr_t addr; - unsigned int len; - u8 option; - - addr = sg_dma_address(sg_ptr); - len = sg_dma_len(sg_ptr); - - RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n", - (unsigned int)addr, len); - RTSX_DEBUGP("*index = %d, *offset = %d\n", *index, *offset); - - addr += *offset; - - if ((len - *offset) > resid) { - *offset += resid; - len = resid; - resid = 0; - } else { - resid -= (len - *offset); - len -= *offset; - *offset = 0; - *index = *index + 1; - } - if ((i == (sg_cnt - 1)) || !resid) - option = SG_VALID | SG_END | SG_TRANS_DATA; - else - option = SG_VALID | SG_TRANS_DATA; - - rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); - - if (!resid) - break; - - sg_ptr = sg_next(sg_ptr); - } - - RTSX_DEBUGP("SG table count = %d\n", chip->sgi); - - val |= (u32)(dir & 0x01) << 29; - val |= ADMA_MODE; - - spin_lock_irq(&rtsx->reg_lock); - - init_completion(&trans_done); - - rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr); - rtsx_writel(chip, RTSX_HDBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, timeout * HZ / 1000); - if (timeleft <= 0) { - RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); - RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) { - err = -EIO; - spin_unlock_irq(&rtsx->reg_lock); - goto out; - } - spin_unlock_irq(&rtsx->reg_lock); - - /* Wait for TRANS_OK_INT */ - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_NOT_READY) { - init_completion(&trans_done); - spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, timeout * HZ / 1000); - if (timeleft <= 0) { - RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); - RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - } else { - spin_unlock_irq(&rtsx->reg_lock); - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) - err = -EIO; - else if (rtsx->trans_result == TRANS_RESULT_OK) - err = 0; - - spin_unlock_irq(&rtsx->reg_lock); - -out: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - -static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card, - struct scatterlist *sg, int num_sg, - enum dma_data_direction dma_dir, int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - u8 dir; - int buf_cnt, i; - int err = 0; - long timeleft; - struct scatterlist *sg_ptr; - - if ((sg == NULL) || (num_sg <= 0)) - return -EIO; - - if (dma_dir == DMA_TO_DEVICE) - dir = HOST_TO_DEVICE; - else if (dma_dir == DMA_FROM_DEVICE) - dir = DEVICE_TO_HOST; - else - return -ENXIO; - - if (card == SD_CARD) - rtsx->check_card_cd = SD_EXIST; - else if (card == MS_CARD) - rtsx->check_card_cd = MS_EXIST; - else if (card == XD_CARD) - rtsx->check_card_cd = XD_EXIST; - else - rtsx->check_card_cd = 0; - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - - rtsx->trans_state = STATE_TRANS_SG; - rtsx->trans_result = TRANS_NOT_READY; - - spin_unlock_irq(&rtsx->reg_lock); - - buf_cnt = dma_map_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); - - sg_ptr = sg; - - for (i = 0; i <= buf_cnt / (HOST_SG_TBL_BUF_LEN / 8); i++) { - u32 val = TRIG_DMA; - int sg_cnt, j; - - if (i == buf_cnt / (HOST_SG_TBL_BUF_LEN / 8)) - sg_cnt = buf_cnt % (HOST_SG_TBL_BUF_LEN / 8); - else - sg_cnt = (HOST_SG_TBL_BUF_LEN / 8); - - chip->sgi = 0; - for (j = 0; j < sg_cnt; j++) { - dma_addr_t addr = sg_dma_address(sg_ptr); - unsigned int len = sg_dma_len(sg_ptr); - u8 option; - - RTSX_DEBUGP("DMA addr: 0x%x, Len: 0x%x\n", - (unsigned int)addr, len); - - if (j == (sg_cnt - 1)) - option = SG_VALID | SG_END | SG_TRANS_DATA; - else - option = SG_VALID | SG_TRANS_DATA; - - rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option); - - sg_ptr = sg_next(sg_ptr); - } - - RTSX_DEBUGP("SG table count = %d\n", chip->sgi); - - val |= (u32)(dir & 0x01) << 29; - val |= ADMA_MODE; - - spin_lock_irq(&rtsx->reg_lock); - - init_completion(&trans_done); - - rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr); - rtsx_writel(chip, RTSX_HDBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, timeout * HZ / 1000); - if (timeleft <= 0) { - RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); - RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) { - err = -EIO; - spin_unlock_irq(&rtsx->reg_lock); - goto out; - } - spin_unlock_irq(&rtsx->reg_lock); - - sg_ptr += sg_cnt; - } - - /* Wait for TRANS_OK_INT */ - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_NOT_READY) { - init_completion(&trans_done); - spin_unlock_irq(&rtsx->reg_lock); - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, timeout * HZ / 1000); - if (timeleft <= 0) { - RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); - RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - } else { - spin_unlock_irq(&rtsx->reg_lock); - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) - err = -EIO; - else if (rtsx->trans_result == TRANS_RESULT_OK) - err = 0; - - spin_unlock_irq(&rtsx->reg_lock); - -out: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_sg(&(rtsx->pci->dev), sg, num_sg, dma_dir); - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - -static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf, size_t len, - enum dma_data_direction dma_dir, int timeout) -{ - struct rtsx_dev *rtsx = chip->rtsx; - struct completion trans_done; - dma_addr_t addr; - u8 dir; - int err = 0; - u32 val = (1 << 31); - long timeleft; - - if ((buf == NULL) || (len <= 0)) - return -EIO; - - if (dma_dir == DMA_TO_DEVICE) - dir = HOST_TO_DEVICE; - else if (dma_dir == DMA_FROM_DEVICE) - dir = DEVICE_TO_HOST; - else - return -ENXIO; - - addr = dma_map_single(&(rtsx->pci->dev), buf, len, dma_dir); - if (!addr) - return -ENOMEM; - - if (card == SD_CARD) - rtsx->check_card_cd = SD_EXIST; - else if (card == MS_CARD) - rtsx->check_card_cd = MS_EXIST; - else if (card == XD_CARD) - rtsx->check_card_cd = XD_EXIST; - else - rtsx->check_card_cd = 0; - - val |= (u32)(dir & 0x01) << 29; - val |= (u32)(len & 0x00FFFFFF); - - spin_lock_irq(&rtsx->reg_lock); - - /* set up data structures for the wakeup system */ - rtsx->done = &trans_done; - - init_completion(&trans_done); - - rtsx->trans_state = STATE_TRANS_BUF; - rtsx->trans_result = TRANS_NOT_READY; - - rtsx_writel(chip, RTSX_HDBAR, addr); - rtsx_writel(chip, RTSX_HDBCTLR, val); - - spin_unlock_irq(&rtsx->reg_lock); - - /* Wait for TRANS_OK_INT */ - timeleft = wait_for_completion_interruptible_timeout( - &trans_done, timeout * HZ / 1000); - if (timeleft <= 0) { - RTSX_DEBUGP("Timeout (%s %d)\n", __func__, __LINE__); - RTSX_DEBUGP("chip->int_reg = 0x%x\n", chip->int_reg); - err = -ETIMEDOUT; - goto out; - } - - spin_lock_irq(&rtsx->reg_lock); - if (rtsx->trans_result == TRANS_RESULT_FAIL) - err = -EIO; - else if (rtsx->trans_result == TRANS_RESULT_OK) - err = 0; - - spin_unlock_irq(&rtsx->reg_lock); - -out: - rtsx->done = NULL; - rtsx->trans_state = STATE_TRANS_NONE; - dma_unmap_single(&(rtsx->pci->dev), addr, len, dma_dir); - - if (err < 0) - rtsx_stop_cmd(chip, card); - - return err; -} - -int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, - void *buf, size_t len, int use_sg, unsigned int *index, - unsigned int *offset, enum dma_data_direction dma_dir, - int timeout) -{ - int err = 0; - - /* don't transfer data during abort processing */ - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) - return -EIO; - - if (use_sg) { - err = rtsx_transfer_sglist_adma_partial(chip, card, - (struct scatterlist *)buf, use_sg, - index, offset, (int)len, dma_dir, timeout); - } else { - err = rtsx_transfer_buf(chip, card, - buf, len, dma_dir, timeout); - } - - if (err < 0) { - if (RTSX_TST_DELINK(chip)) { - RTSX_CLR_DELINK(chip); - chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; - rtsx_reinit_cards(chip, 1); - } - } - - return err; -} - -int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len, - int use_sg, enum dma_data_direction dma_dir, int timeout) -{ - int err = 0; - - RTSX_DEBUGP("use_sg = %d\n", use_sg); - - /* don't transfer data during abort processing */ - if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) - return -EIO; - - if (use_sg) { - err = rtsx_transfer_sglist_adma(chip, card, - (struct scatterlist *)buf, - use_sg, dma_dir, timeout); - } else { - err = rtsx_transfer_buf(chip, card, buf, len, dma_dir, timeout); - } - - if (err < 0) { - if (RTSX_TST_DELINK(chip)) { - RTSX_CLR_DELINK(chip); - chip->need_reinit = SD_CARD | MS_CARD | XD_CARD; - rtsx_reinit_cards(chip, 1); - } - } - - return err; -} - diff --git a/drivers/staging/rts_pstor/rtsx_transport.h b/drivers/staging/rts_pstor/rtsx_transport.h deleted file mode 100644 index 41f1ea05a8d..00000000000 --- a/drivers/staging/rts_pstor/rtsx_transport.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __REALTEK_RTSX_TRANSPORT_H -#define __REALTEK_RTSX_TRANSPORT_H - -#include "rtsx.h" -#include "rtsx_chip.h" - -#define WAIT_TIME 2000 - -unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, - unsigned int *offset, enum xfer_buf_dir dir); -void rtsx_stor_set_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb); -void rtsx_stor_get_xfer_buf(unsigned char *buffer, - unsigned int buflen, struct scsi_cmnd *srb); -void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip); - - -#define rtsx_init_cmd(chip) ((chip)->ci = 0) - -void rtsx_add_cmd(struct rtsx_chip *chip, - u8 cmd_type, u16 reg_addr, u8 mask, u8 data); -void rtsx_send_cmd_no_wait(struct rtsx_chip *chip); -int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout); - -extern inline u8 *rtsx_get_cmd_data(struct rtsx_chip *chip) -{ -#ifdef CMD_USING_SG - return (u8 *)(chip->host_sg_tbl_ptr); -#else - return (u8 *)(chip->host_cmds_ptr); -#endif -} - -int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len, - int use_sg, enum dma_data_direction dma_dir, int timeout); - -int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card, void *buf, size_t len, - int use_sg, unsigned int *index, unsigned int *offset, - enum dma_data_direction dma_dir, int timeout); - -#endif /* __REALTEK_RTSX_TRANSPORT_H */ - diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c deleted file mode 100644 index c6a581c47cb..00000000000 --- a/drivers/staging/rts_pstor/sd.c +++ /dev/null @@ -1,4570 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include - -#include "rtsx.h" -#include "rtsx_transport.h" -#include "rtsx_scsi.h" -#include "rtsx_card.h" -#include "sd.h" - -#define SD_MAX_RETRY_COUNT 3 - -static u16 REG_SD_CFG1; -static u16 REG_SD_CFG2; -static u16 REG_SD_CFG3; -static u16 REG_SD_STAT1; -static u16 REG_SD_STAT2; -static u16 REG_SD_BUS_STAT; -static u16 REG_SD_PAD_CTL; -static u16 REG_SD_SAMPLE_POINT_CTL; -static u16 REG_SD_PUSH_POINT_CTL; -static u16 REG_SD_CMD0; -static u16 REG_SD_CMD1; -static u16 REG_SD_CMD2; -static u16 REG_SD_CMD3; -static u16 REG_SD_CMD4; -static u16 REG_SD_CMD5; -static u16 REG_SD_BYTE_CNT_L; -static u16 REG_SD_BYTE_CNT_H; -static u16 REG_SD_BLOCK_CNT_L; -static u16 REG_SD_BLOCK_CNT_H; -static u16 REG_SD_TRANSFER; -static u16 REG_SD_VPCLK0_CTL; -static u16 REG_SD_VPCLK1_CTL; -static u16 REG_SD_DCMPS0_CTL; -static u16 REG_SD_DCMPS1_CTL; - -static inline void sd_set_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct sd_info *sd_card = &(chip->sd_card); - - sd_card->err_code |= err_code; -} - -static inline void sd_clr_err_code(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - - sd_card->err_code = 0; -} - -static inline int sd_check_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct sd_info *sd_card = &(chip->sd_card); - - return sd_card->err_code & err_code; -} - -static void sd_init_reg_addr(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5209)) { - REG_SD_CFG1 = SD_CFG1; - REG_SD_CFG2 = SD_CFG2; - REG_SD_CFG3 = SD_CFG3; - REG_SD_STAT1 = SD_STAT1; - REG_SD_STAT2 = SD_STAT2; - REG_SD_BUS_STAT = SD_BUS_STAT; - REG_SD_PAD_CTL = SD_PAD_CTL; - REG_SD_SAMPLE_POINT_CTL = SD_SAMPLE_POINT_CTL; - REG_SD_PUSH_POINT_CTL = SD_PUSH_POINT_CTL; - REG_SD_CMD0 = SD_CMD0; - REG_SD_CMD1 = SD_CMD1; - REG_SD_CMD2 = SD_CMD2; - REG_SD_CMD3 = SD_CMD3; - REG_SD_CMD4 = SD_CMD4; - REG_SD_CMD5 = SD_CMD5; - REG_SD_BYTE_CNT_L = SD_BYTE_CNT_L; - REG_SD_BYTE_CNT_H = SD_BYTE_CNT_H; - REG_SD_BLOCK_CNT_L = SD_BLOCK_CNT_L; - REG_SD_BLOCK_CNT_H = SD_BLOCK_CNT_H; - REG_SD_TRANSFER = SD_TRANSFER; - REG_SD_VPCLK0_CTL = SD_VPCLK0_CTL; - REG_SD_VPCLK1_CTL = SD_VPCLK1_CTL; - REG_SD_DCMPS0_CTL = SD_DCMPS0_CTL; - REG_SD_DCMPS1_CTL = SD_DCMPS1_CTL; - } else { - REG_SD_CFG1 = 0xFD31; - REG_SD_CFG2 = 0xFD33; - REG_SD_CFG3 = 0xFD3E; - REG_SD_STAT1 = 0xFD30; - REG_SD_STAT2 = 0; - REG_SD_BUS_STAT = 0; - REG_SD_PAD_CTL = 0; - REG_SD_SAMPLE_POINT_CTL = 0; - REG_SD_PUSH_POINT_CTL = 0; - REG_SD_CMD0 = 0xFD34; - REG_SD_CMD1 = 0xFD35; - REG_SD_CMD2 = 0xFD36; - REG_SD_CMD3 = 0xFD37; - REG_SD_CMD4 = 0xFD38; - REG_SD_CMD5 = 0xFD5A; - REG_SD_BYTE_CNT_L = 0xFD39; - REG_SD_BYTE_CNT_H = 0xFD3A; - REG_SD_BLOCK_CNT_L = 0xFD3B; - REG_SD_BLOCK_CNT_H = 0xFD3C; - REG_SD_TRANSFER = 0xFD32; - REG_SD_VPCLK0_CTL = 0; - REG_SD_VPCLK1_CTL = 0; - REG_SD_DCMPS0_CTL = 0; - REG_SD_DCMPS1_CTL = 0; - } -} - -static int sd_check_data0_status(struct rtsx_chip *chip) -{ - u8 stat; - - if (CHECK_PID(chip, 0x5209)) - RTSX_READ_REG(chip, REG_SD_BUS_STAT, &stat); - else - RTSX_READ_REG(chip, REG_SD_STAT1, &stat); - - if (!(stat & SD_DAT0_STATUS)) { - sd_set_err_code(chip, SD_BUSY); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, - u32 arg, u8 rsp_type, u8 *rsp, int rsp_len) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - int timeout = 100; - u16 reg_addr; - u8 *ptr; - int stat_idx = 0; - int rty_cnt = 0; - - sd_clr_err_code(chip); - - RTSX_DEBUGP("SD/MMC CMD %d, arg = 0x%08x\n", cmd_idx, arg); - - if (rsp_type == SD_RSP_TYPE_R1b) - timeout = 3000; - -RTY_SEND_CMD: - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, - 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END | SD_STAT_IDLE, SD_TRANSFER_END | SD_STAT_IDLE); - - if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - stat_idx = 16; - } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - stat_idx = 5; - } - - rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, timeout); - if (retval < 0) { - u8 val; - - rtsx_read_register(chip, REG_SD_STAT1, &val); - RTSX_DEBUGP("SD_STAT1: 0x%x\n", val); - - if (CHECK_PID(chip, 0x5209)) { - rtsx_read_register(chip, REG_SD_STAT2, &val); - RTSX_DEBUGP("SD_STAT2: 0x%x\n", val); - - if (val & SD_RSP_80CLK_TIMEOUT) { - rtsx_clear_sd_error(chip); - sd_set_err_code(chip, SD_RSP_TIMEOUT); - TRACE_RET(chip, STATUS_FAIL); - } - - rtsx_read_register(chip, REG_SD_BUS_STAT, &val); - RTSX_DEBUGP("SD_BUS_STAT: 0x%x\n", val); - } else { - rtsx_read_register(chip, REG_SD_CFG3, &val); - RTSX_DEBUGP("SD_CFG3: 0x%x\n", val); - } - - if (retval == -ETIMEDOUT) { - if (rsp_type & SD_WAIT_BUSY_END) { - retval = sd_check_data0_status(chip); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - TRACE_RET(chip, retval); - } - } else { - sd_set_err_code(chip, SD_TO_ERR); - } - retval = STATUS_TIMEDOUT; - } else { - retval = STATUS_FAIL; - } - rtsx_clear_sd_error(chip); - - TRACE_RET(chip, retval); - } - - if (rsp_type == SD_RSP_TYPE_R0) - return STATUS_SUCCESS; - - ptr = rtsx_get_cmd_data(chip) + 1; - - if ((ptr[0] & 0xC0) != 0) { - sd_set_err_code(chip, SD_STS_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - if (!(rsp_type & SD_NO_CHECK_CRC7)) { - if (ptr[stat_idx] & SD_CRC7_ERR) { - if (cmd_idx == WRITE_MULTIPLE_BLOCK) { - sd_set_err_code(chip, SD_CRC_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - if (rty_cnt < SD_MAX_RETRY_COUNT) { - wait_timeout(20); - rty_cnt++; - goto RTY_SEND_CMD; - } else { - sd_set_err_code(chip, SD_CRC_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - if ((rsp_type == SD_RSP_TYPE_R1) || (rsp_type == SD_RSP_TYPE_R1b)) { - if ((cmd_idx != SEND_RELATIVE_ADDR) && (cmd_idx != SEND_IF_COND)) { - if (cmd_idx != STOP_TRANSMISSION) { - if (ptr[1] & 0x80) - TRACE_RET(chip, STATUS_FAIL); - } -#ifdef SUPPORT_SD_LOCK - if (ptr[1] & 0x7D) -#else - if (ptr[1] & 0x7F) -#endif - { - RTSX_DEBUGP("ptr[1]: 0x%02x\n", ptr[1]); - TRACE_RET(chip, STATUS_FAIL); - } - if (ptr[2] & 0xFF) { - RTSX_DEBUGP("ptr[2]: 0x%02x\n", ptr[2]); - TRACE_RET(chip, STATUS_FAIL); - } - if (ptr[3] & 0x80) { - RTSX_DEBUGP("ptr[3]: 0x%02x\n", ptr[3]); - TRACE_RET(chip, STATUS_FAIL); - } - if (ptr[3] & 0x01) - sd_card->sd_data_buf_ready = 1; - else - sd_card->sd_data_buf_ready = 0; - } - } - - if (rsp && rsp_len) - memcpy(rsp, ptr, rsp_len); - - return STATUS_SUCCESS; -} - -static int sd_read_data(struct rtsx_chip *chip, - u8 trans_mode, u8 *cmd, int cmd_len, u16 byte_cnt, - u16 blk_cnt, u8 bus_width, u8 *buf, int buf_len, - int timeout) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - int i; - - sd_clr_err_code(chip); - - if (!buf) - buf_len = 0; - - if (buf_len > 512) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_init_cmd(chip); - - if (cmd_len) { - RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40); - for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0 + i, 0xFF, cmd[i]); - } - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, (u8)(byte_cnt >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, (u8)blk_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, (u8)(blk_cnt >> 8)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6); - if (trans_mode != SD_TM_AUTO_TUNING) - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, trans_mode | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, SD_CARD, timeout); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - - TRACE_RET(chip, STATUS_FAIL); - } - - if (buf && buf_len) { - retval = rtsx_read_ppbuf(chip, buf, buf_len); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_write_data(struct rtsx_chip *chip, u8 trans_mode, - u8 *cmd, int cmd_len, u16 byte_cnt, u16 blk_cnt, u8 bus_width, - u8 *buf, int buf_len, int timeout) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - int i; - - sd_clr_err_code(chip); - - if (!buf) - buf_len = 0; - - if (buf_len > 512) { - /* This function can't write data more than one page */ - TRACE_RET(chip, STATUS_FAIL); - } - - if (buf && buf_len) { - retval = rtsx_write_ppbuf(chip, buf, buf_len); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - rtsx_init_cmd(chip); - - if (cmd_len) { - RTSX_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40); - for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - REG_SD_CMD0 + i, 0xFF, cmd[i]); - } - } - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, (u8)(byte_cnt >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, (u8)blk_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, (u8)(blk_cnt >> 8)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, trans_mode | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, SD_CARD, timeout); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - } - - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_check_csd(struct rtsx_chip *chip, char check_wp) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - int i; - u8 csd_ver, trans_speed; - u8 rsp[16]; - - for (i = 0; i < 6; i++) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sd_send_cmd_get_rsp(chip, SEND_CSD, sd_card->sd_addr, SD_RSP_TYPE_R2, rsp, 16); - if (retval == STATUS_SUCCESS) - break; - } - - if (i == 6) - TRACE_RET(chip, STATUS_FAIL); - - memcpy(sd_card->raw_csd, rsp + 1, 15); - - if (CHECK_PID(chip, 0x5209)) - RTSX_READ_REG(chip, REG_SD_CMD5, sd_card->raw_csd + 15); - - RTSX_DEBUGP("CSD Response:\n"); - RTSX_DUMP(sd_card->raw_csd, 16); - - csd_ver = (rsp[1] & 0xc0) >> 6; - RTSX_DEBUGP("csd_ver = %d\n", csd_ver); - - trans_speed = rsp[4]; - if ((trans_speed & 0x07) == 0x02) { - if ((trans_speed & 0xf8) >= 0x30) { - if (chip->asic_code) - sd_card->sd_clock = 47; - else - sd_card->sd_clock = CLK_50; - - } else if ((trans_speed & 0xf8) == 0x28) { - if (chip->asic_code) - sd_card->sd_clock = 39; - else - sd_card->sd_clock = CLK_40; - - } else if ((trans_speed & 0xf8) == 0x20) { - if (chip->asic_code) - sd_card->sd_clock = 29; - else - sd_card->sd_clock = CLK_30; - - } else if ((trans_speed & 0xf8) >= 0x10) { - if (chip->asic_code) - sd_card->sd_clock = 23; - else - sd_card->sd_clock = CLK_20; - - } else if ((trans_speed & 0x08) >= 0x08) { - if (chip->asic_code) - sd_card->sd_clock = 19; - else - sd_card->sd_clock = CLK_20; - } else { - TRACE_RET(chip, STATUS_FAIL); - } - } else { - TRACE_RET(chip, STATUS_FAIL); - } - - if (CHK_MMC_SECTOR_MODE(sd_card)) { - sd_card->capacity = 0; - } else { - if ((!CHK_SD_HCXC(sd_card)) || (csd_ver == 0)) { - u8 blk_size, c_size_mult; - u16 c_size; - blk_size = rsp[6] & 0x0F; - c_size = ((u16)(rsp[7] & 0x03) << 10) - + ((u16)rsp[8] << 2) - + ((u16)(rsp[9] & 0xC0) >> 6); - c_size_mult = (u8)((rsp[10] & 0x03) << 1); - c_size_mult += (rsp[11] & 0x80) >> 7; - sd_card->capacity = (((u32)(c_size + 1)) * (1 << (c_size_mult + 2))) << (blk_size - 9); - } else { - u32 total_sector = 0; - total_sector = (((u32)rsp[8] & 0x3f) << 16) | - ((u32)rsp[9] << 8) | (u32)rsp[10]; - sd_card->capacity = (total_sector + 1) << 10; - } - } - - if (check_wp) { - if (rsp[15] & 0x30) - chip->card_wp |= SD_CARD; - - RTSX_DEBUGP("CSD WP Status: 0x%x\n", rsp[15]); - } - - return STATUS_SUCCESS; -} - -static int sd_set_sample_push_timing(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - - if (CHECK_PID(chip, 0x5209)) { - if (CHK_SD_SDR104(sd_card) || CHK_SD_SDR50(sd_card)) { - RTSX_WRITE_REG(chip, SD_CFG1, 0x0C | SD_ASYNC_FIFO_NOT_RST, - SD_30_MODE | SD_ASYNC_FIFO_NOT_RST); - RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); - RTSX_WRITE_REG(chip, CARD_CLK_SOURCE, 0xFF, - CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); - RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); - } else if (CHK_SD_DDR50(sd_card) || CHK_MMC_DDR52(sd_card)) { - RTSX_WRITE_REG(chip, SD_CFG1, 0x0C | SD_ASYNC_FIFO_NOT_RST, - SD_DDR_MODE | SD_ASYNC_FIFO_NOT_RST); - RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); - RTSX_WRITE_REG(chip, CARD_CLK_SOURCE, 0xFF, - CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); - RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); - RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, DDR_VAR_TX_CMD_DAT, - DDR_VAR_TX_CMD_DAT); - RTSX_WRITE_REG(chip, SD_SAMPLE_POINT_CTL, DDR_VAR_RX_DAT | DDR_VAR_RX_CMD, - DDR_VAR_RX_DAT | DDR_VAR_RX_CMD); - } else { - u8 val = 0; - - RTSX_WRITE_REG(chip, SD_CFG1, 0x0C, SD_20_MODE); - RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ); - RTSX_WRITE_REG(chip, CARD_CLK_SOURCE, 0xFF, - CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1); - RTSX_WRITE_REG(chip, CLK_CTL, CLK_LOW_FREQ, 0); - - if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_AUTO) - val = SD20_TX_NEG_EDGE; - else if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY) - val = SD20_TX_14_AHEAD; - else - val = SD20_TX_NEG_EDGE; - - RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, SD20_TX_SEL_MASK, val); - - if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_AUTO) { - if (chip->asic_code) { - if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) - val = SD20_RX_14_DELAY; - else - val = SD20_RX_POS_EDGE; - } else { - val = SD20_RX_14_DELAY; - } - } else if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_DELAY) { - val = SD20_RX_14_DELAY; - } else { - val = SD20_RX_POS_EDGE; - } - RTSX_WRITE_REG(chip, SD_SAMPLE_POINT_CTL, SD20_RX_SEL_MASK, val); - } - } else { - u8 val = 0; - - if ((chip->sd_ctl & SD_PUSH_POINT_CTL_MASK) == SD_PUSH_POINT_DELAY) - val |= 0x10; - - if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_AUTO) { - if (chip->asic_code) { - if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) { - if (val & 0x10) - val |= 0x04; - else - val |= 0x08; - } - } else { - if (val & 0x10) - val |= 0x04; - else - val |= 0x08; - } - } else if ((chip->sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == SD_SAMPLE_POINT_DELAY) { - if (val & 0x10) - val |= 0x04; - else - val |= 0x08; - } - - RTSX_WRITE_REG(chip, REG_SD_CFG1, 0x1C, val); - } - - return STATUS_SUCCESS; -} - -static void sd_choose_proper_clock(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - - if (CHK_SD_SDR104(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_sd_sdr104_clk; - else - sd_card->sd_clock = chip->fpga_sd_sdr104_clk; - - } else if (CHK_SD_DDR50(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_sd_ddr50_clk; - else - sd_card->sd_clock = chip->fpga_sd_ddr50_clk; - - } else if (CHK_SD_SDR50(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_sd_sdr50_clk; - else - sd_card->sd_clock = chip->fpga_sd_sdr50_clk; - - } else if (CHK_SD_HS(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_sd_hs_clk; - else - sd_card->sd_clock = chip->fpga_sd_hs_clk; - - } else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = chip->asic_mmc_52m_clk; - else - sd_card->sd_clock = chip->fpga_mmc_52m_clk; - - } else if (CHK_MMC_26M(sd_card)) { - if (chip->asic_code) - sd_card->sd_clock = 48; - else - sd_card->sd_clock = CLK_50; - } -} - -static int sd_set_clock_divider(struct rtsx_chip *chip, u8 clk_div) -{ - u8 mask = 0, val = 0; - - if (CHECK_PID(chip, 0x5209)) { - mask = SD_CLK_DIVIDE_MASK; - val = clk_div; - } else { - mask = 0x60; - if (clk_div == SD_CLK_DIVIDE_0) - val = 0x00; - else if (clk_div == SD_CLK_DIVIDE_128) - val = 0x40; - else if (clk_div == SD_CLK_DIVIDE_256) - val = 0x20; - } - - RTSX_WRITE_REG(chip, REG_SD_CFG1, mask, val); - - return STATUS_SUCCESS; -} - -static int sd_set_init_para(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - - retval = sd_set_sample_push_timing(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - sd_choose_proper_clock(chip); - - retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int sd_select_card(struct rtsx_chip *chip, int select) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 cmd_idx, cmd_type; - u32 addr; - - if (select) { - cmd_idx = SELECT_CARD; - cmd_type = SD_RSP_TYPE_R1; - addr = sd_card->sd_addr; - } else { - cmd_idx = DESELECT_CARD; - cmd_type = SD_RSP_TYPE_R0; - addr = 0; - } - - retval = sd_send_cmd_get_rsp(chip, cmd_idx, addr, cmd_type, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -#ifdef SUPPORT_SD_LOCK -static int sd_update_lock_status(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 rsp[5]; - - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, rsp, 5); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (rsp[1] & 0x02) - sd_card->sd_lock_status |= SD_LOCKED; - else - sd_card->sd_lock_status &= ~SD_LOCKED; - - RTSX_DEBUGP("sd_card->sd_lock_status = 0x%x\n", sd_card->sd_lock_status); - - if (rsp[1] & 0x01) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} -#endif - -static int sd_wait_state_data_ready(struct rtsx_chip *chip, u8 state, u8 data_ready, int polling_cnt) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval, i; - u8 rsp[5]; - - for (i = 0; i < polling_cnt; i++) { - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, rsp, 5); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (((rsp[3] & 0x1E) == state) && ((rsp[3] & 0x01) == data_ready)) - return STATUS_SUCCESS; - } - - TRACE_RET(chip, STATUS_FAIL); -} - -static int sd_change_bank_voltage(struct rtsx_chip *chip, u8 voltage) -{ - int retval; - - if (voltage == SD_IO_3V3) { - if (chip->asic_code) { - retval = rtsx_write_phy_register(chip, 0x08, 0x4FC0 | chip->phy_voltage); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - RTSX_WRITE_REG(chip, SD_PAD_CTL, SD_IO_USING_1V8, 0); - } - } else if (voltage == SD_IO_1V8) { - if (chip->asic_code) { - retval = rtsx_write_phy_register(chip, 0x08, 0x4C40 | chip->phy_voltage); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - RTSX_WRITE_REG(chip, SD_PAD_CTL, SD_IO_USING_1V8, SD_IO_USING_1V8); - } - } else { - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_voltage_switch(struct rtsx_chip *chip) -{ - int retval; - u8 stat; - - RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, SD_CLK_TOGGLE_EN); - - retval = sd_send_cmd_get_rsp(chip, VOLTAGE_SWITCH, 0, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - udelay(chip->sd_voltage_switch_delay); - - RTSX_READ_REG(chip, SD_BUS_STAT, &stat); - if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS)) { - TRACE_RET(chip, STATUS_FAIL); - } - - RTSX_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_FORCE_STOP); - retval = sd_change_bank_voltage(chip, SD_IO_1V8); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - wait_timeout(50); - - RTSX_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_TOGGLE_EN); - wait_timeout(10); - - RTSX_READ_REG(chip, SD_BUS_STAT, &stat); - if ((stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS)) != - (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | - SD_DAT1_STATUS | SD_DAT0_STATUS)) { - RTSX_DEBUGP("SD_BUS_STAT: 0x%x\n", stat); - rtsx_write_register(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); - rtsx_write_register(chip, CARD_CLK_EN, 0xFF, 0); - TRACE_RET(chip, STATUS_FAIL); - } - - RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); - - return STATUS_SUCCESS; -} - -static int sd_reset_dcm(struct rtsx_chip *chip, u8 tune_dir) -{ - if (tune_dir == TUNE_RX) { - RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RESET | DCM_RX); - RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RX); - } else { - RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_RESET | DCM_TX); - RTSX_WRITE_REG(chip, DCM_DRP_CTL, 0xFF, DCM_TX); - } - - return STATUS_SUCCESS; -} - -static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) -{ - struct sd_info *sd_card = &(chip->sd_card); - u16 SD_VP_CTL, SD_DCMPS_CTL; - u8 val; - int retval; - int ddr_rx = 0; - - RTSX_DEBUGP("sd_change_phase (sample_point = %d, tune_dir = %d)\n", - sample_point, tune_dir); - - if (tune_dir == TUNE_RX) { - SD_VP_CTL = SD_VPRX_CTL; - SD_DCMPS_CTL = SD_DCMPS_RX_CTL; - if (CHK_SD_DDR50(sd_card)) - ddr_rx = 1; - } else { - SD_VP_CTL = SD_VPTX_CTL; - SD_DCMPS_CTL = SD_DCMPS_TX_CTL; - } - - if (chip->asic_code) { - RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, CHANGE_CLK); - RTSX_WRITE_REG(chip, SD_VP_CTL, 0x1F, sample_point); - RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); - RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); - RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0); - } else { -#ifdef CONFIG_RTS_PSTOR_DEBUG - rtsx_read_register(chip, SD_VP_CTL, &val); - RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val); - rtsx_read_register(chip, SD_DCMPS_CTL, &val); - RTSX_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val); -#endif - - if (ddr_rx) { - RTSX_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, PHASE_CHANGE); - udelay(50); - RTSX_WRITE_REG(chip, SD_VP_CTL, 0xFF, - PHASE_CHANGE | PHASE_NOT_RESET | sample_point); - } else { - RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, CHANGE_CLK); - udelay(50); - RTSX_WRITE_REG(chip, SD_VP_CTL, 0xFF, - PHASE_NOT_RESET | sample_point); - } - udelay(100); - - rtsx_init_cmd(chip); - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE, DCMPS_CHANGE); - rtsx_add_cmd(chip, CHECK_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE_DONE, DCMPS_CHANGE_DONE); - retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, Fail); - - val = *rtsx_get_cmd_data(chip); - if (val & DCMPS_ERROR) - TRACE_GOTO(chip, Fail); - - if ((val & DCMPS_CURRENT_PHASE) != sample_point) - TRACE_GOTO(chip, Fail); - - RTSX_WRITE_REG(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); - if (ddr_rx) - RTSX_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, 0); - else - RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0); - - udelay(50); - } - - RTSX_WRITE_REG(chip, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); - - return STATUS_SUCCESS; - -Fail: -#ifdef CONFIG_RTS_PSTOR_DEBUG - rtsx_read_register(chip, SD_VP_CTL, &val); - RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val); - rtsx_read_register(chip, SD_DCMPS_CTL, &val); - RTSX_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val); -#endif - - rtsx_write_register(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); - rtsx_write_register(chip, SD_VP_CTL, PHASE_CHANGE, 0); - wait_timeout(10); - sd_reset_dcm(chip, tune_dir); - return STATUS_FAIL; -} - -static int sd_check_spec(struct rtsx_chip *chip, u8 bus_width) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 cmd[5], buf[8]; - - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - cmd[0] = 0x40 | SEND_SCR; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 8, 1, bus_width, buf, 8, 250); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - memcpy(sd_card->raw_scr, buf, 8); - - if ((buf[0] & 0x0F) == 0) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int sd_query_switch_result(struct rtsx_chip *chip, u8 func_group, u8 func_to_switch, - u8 *buf, int buf_len) -{ - u8 support_mask = 0, query_switch = 0, switch_busy = 0; - int support_offset = 0, query_switch_offset = 0, check_busy_offset = 0; - - if (func_group == SD_FUNC_GROUP_1) { - support_offset = FUNCTION_GROUP1_SUPPORT_OFFSET; - query_switch_offset = FUNCTION_GROUP1_QUERY_SWITCH_OFFSET; - check_busy_offset = FUNCTION_GROUP1_CHECK_BUSY_OFFSET; - - switch (func_to_switch) { - case HS_SUPPORT: - support_mask = HS_SUPPORT_MASK; - query_switch = HS_QUERY_SWITCH_OK; - switch_busy = HS_SWITCH_BUSY; - break; - - case SDR50_SUPPORT: - support_mask = SDR50_SUPPORT_MASK; - query_switch = SDR50_QUERY_SWITCH_OK; - switch_busy = SDR50_SWITCH_BUSY; - break; - - case SDR104_SUPPORT: - support_mask = SDR104_SUPPORT_MASK; - query_switch = SDR104_QUERY_SWITCH_OK; - switch_busy = SDR104_SWITCH_BUSY; - break; - - case DDR50_SUPPORT: - support_mask = DDR50_SUPPORT_MASK; - query_switch = DDR50_QUERY_SWITCH_OK; - switch_busy = DDR50_SWITCH_BUSY; - break; - - default: - TRACE_RET(chip, STATUS_FAIL); - } - } else if (func_group == SD_FUNC_GROUP_3) { - support_offset = FUNCTION_GROUP3_SUPPORT_OFFSET; - query_switch_offset = FUNCTION_GROUP3_QUERY_SWITCH_OFFSET; - check_busy_offset = FUNCTION_GROUP3_CHECK_BUSY_OFFSET; - - switch (func_to_switch) { - case DRIVING_TYPE_A: - support_mask = DRIVING_TYPE_A_MASK; - query_switch = TYPE_A_QUERY_SWITCH_OK; - switch_busy = TYPE_A_SWITCH_BUSY; - break; - - case DRIVING_TYPE_C: - support_mask = DRIVING_TYPE_C_MASK; - query_switch = TYPE_C_QUERY_SWITCH_OK; - switch_busy = TYPE_C_SWITCH_BUSY; - break; - - case DRIVING_TYPE_D: - support_mask = DRIVING_TYPE_D_MASK; - query_switch = TYPE_D_QUERY_SWITCH_OK; - switch_busy = TYPE_D_SWITCH_BUSY; - break; - - default: - TRACE_RET(chip, STATUS_FAIL); - } - } else if (func_group == SD_FUNC_GROUP_4) { - support_offset = FUNCTION_GROUP4_SUPPORT_OFFSET; - query_switch_offset = FUNCTION_GROUP4_QUERY_SWITCH_OFFSET; - check_busy_offset = FUNCTION_GROUP4_CHECK_BUSY_OFFSET; - - switch (func_to_switch) { - case CURRENT_LIMIT_400: - support_mask = CURRENT_LIMIT_400_MASK; - query_switch = CURRENT_LIMIT_400_QUERY_SWITCH_OK; - switch_busy = CURRENT_LIMIT_400_SWITCH_BUSY; - break; - - case CURRENT_LIMIT_600: - support_mask = CURRENT_LIMIT_600_MASK; - query_switch = CURRENT_LIMIT_600_QUERY_SWITCH_OK; - switch_busy = CURRENT_LIMIT_600_SWITCH_BUSY; - break; - - case CURRENT_LIMIT_800: - support_mask = CURRENT_LIMIT_800_MASK; - query_switch = CURRENT_LIMIT_800_QUERY_SWITCH_OK; - switch_busy = CURRENT_LIMIT_800_SWITCH_BUSY; - break; - - default: - TRACE_RET(chip, STATUS_FAIL); - } - } else { - TRACE_RET(chip, STATUS_FAIL); - } - - if (func_group == SD_FUNC_GROUP_1) { - if (!(buf[support_offset] & support_mask) || - ((buf[query_switch_offset] & 0x0F) != query_switch)) { - TRACE_RET(chip, STATUS_FAIL); - } - } - - /* Check 'Busy Status' */ - if ((buf[DATA_STRUCTURE_VER_OFFSET] == 0x01) && - ((buf[check_busy_offset] & switch_busy) == switch_busy)) { - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, - u8 func_group, u8 func_to_switch, u8 bus_width) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 cmd[5], buf[64]; - - RTSX_DEBUGP("sd_check_switch_mode (mode = %d, func_group = %d, func_to_switch = %d)\n", - mode, func_group, func_to_switch); - - cmd[0] = 0x40 | SWITCH; - cmd[1] = mode; - - if (func_group == SD_FUNC_GROUP_1) { - cmd[2] = 0xFF; - cmd[3] = 0xFF; - cmd[4] = 0xF0 + func_to_switch; - } else if (func_group == SD_FUNC_GROUP_3) { - cmd[2] = 0xFF; - cmd[3] = 0xF0 + func_to_switch; - cmd[4] = 0xFF; - } else if (func_group == SD_FUNC_GROUP_4) { - cmd[2] = 0xFF; - cmd[3] = 0x0F + (func_to_switch << 4); - cmd[4] = 0xFF; - } else { - cmd[1] = SD_CHECK_MODE; - cmd[2] = 0xFF; - cmd[3] = 0xFF; - cmd[4] = 0xFF; - } - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, bus_width, buf, 64, 250); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - RTSX_DUMP(buf, 64); - - if (func_group == NO_ARGUMENT) { - sd_card->func_group1_mask = buf[0x0D]; - sd_card->func_group2_mask = buf[0x0B]; - sd_card->func_group3_mask = buf[0x09]; - sd_card->func_group4_mask = buf[0x07]; - - RTSX_DEBUGP("func_group1_mask = 0x%02x\n", buf[0x0D]); - RTSX_DEBUGP("func_group2_mask = 0x%02x\n", buf[0x0B]); - RTSX_DEBUGP("func_group3_mask = 0x%02x\n", buf[0x09]); - RTSX_DEBUGP("func_group4_mask = 0x%02x\n", buf[0x07]); - } else { - /* Maximum current consumption, check whether current is acceptable; - * bit[511:496] = 0x0000 means some error happened. - */ - u16 cc = ((u16)buf[0] << 8) | buf[1]; - RTSX_DEBUGP("Maximum current consumption: %dmA\n", cc); - if ((cc == 0) || (cc > 800)) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_query_switch_result(chip, func_group, func_to_switch, buf, 64); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if ((cc > 400) || (func_to_switch > CURRENT_LIMIT_400)) { - RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK, chip->sd_800mA_ocp_thd); - RTSX_WRITE_REG(chip, CARD_PWR_CTL, PMOS_STRG_MASK, PMOS_STRG_800mA); - } - } - - return STATUS_SUCCESS; -} - -static u8 downgrade_switch_mode(u8 func_group, u8 func_to_switch) -{ - if (func_group == SD_FUNC_GROUP_1) { - if (func_to_switch > HS_SUPPORT) - func_to_switch--; - - } else if (func_group == SD_FUNC_GROUP_4) { - if (func_to_switch > CURRENT_LIMIT_200) - func_to_switch--; - } - - return func_to_switch; -} - -static int sd_check_switch(struct rtsx_chip *chip, - u8 func_group, u8 func_to_switch, u8 bus_width) -{ - int retval; - int i; - int switch_good = 0; - - for (i = 0; i < 3; i++) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sd_check_switch_mode(chip, SD_CHECK_MODE, func_group, - func_to_switch, bus_width); - if (retval == STATUS_SUCCESS) { - u8 stat; - - retval = sd_check_switch_mode(chip, SD_SWITCH_MODE, - func_group, func_to_switch, bus_width); - if (retval == STATUS_SUCCESS) { - switch_good = 1; - break; - } - - RTSX_READ_REG(chip, SD_STAT1, &stat); - if (stat & SD_CRC16_ERR) { - RTSX_DEBUGP("SD CRC16 error when switching mode\n"); - TRACE_RET(chip, STATUS_FAIL); - } - } - - func_to_switch = downgrade_switch_mode(func_group, func_to_switch); - - wait_timeout(20); - } - - if (!switch_good) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int sd_switch_function(struct rtsx_chip *chip, u8 bus_width) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - int i; - u8 func_to_switch = 0; - - /* Get supported functions */ - retval = sd_check_switch_mode(chip, SD_CHECK_MODE, - NO_ARGUMENT, NO_ARGUMENT, bus_width); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - sd_card->func_group1_mask &= ~(sd_card->sd_switch_fail); - - /* Function Group 1: Access Mode */ - for (i = 0; i < 4; i++) { - switch ((u8)(chip->sd_speed_prior >> (i*8))) { - case SDR104_SUPPORT: - if ((sd_card->func_group1_mask & SDR104_SUPPORT_MASK) - && chip->sdr104_en) { - func_to_switch = SDR104_SUPPORT; - } - break; - - case DDR50_SUPPORT: - if ((sd_card->func_group1_mask & DDR50_SUPPORT_MASK) - && chip->ddr50_en) { - func_to_switch = DDR50_SUPPORT; - } - break; - - case SDR50_SUPPORT: - if ((sd_card->func_group1_mask & SDR50_SUPPORT_MASK) - && chip->sdr50_en) { - func_to_switch = SDR50_SUPPORT; - } - break; - - case HS_SUPPORT: - if (sd_card->func_group1_mask & HS_SUPPORT_MASK) - func_to_switch = HS_SUPPORT; - - break; - - default: - continue; - } - - - if (func_to_switch) - break; - - } - RTSX_DEBUGP("SD_FUNC_GROUP_1: func_to_switch = 0x%02x", func_to_switch); - -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_SDR_RST) - && (DDR50_SUPPORT == func_to_switch) - && (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) { - func_to_switch = SDR50_SUPPORT; - RTSX_DEBUGP("Using SDR50 instead of DDR50 for SD Lock\n"); - } -#endif - - if (func_to_switch) { - retval = sd_check_switch(chip, SD_FUNC_GROUP_1, func_to_switch, bus_width); - if (retval != STATUS_SUCCESS) { - if (func_to_switch == SDR104_SUPPORT) { - sd_card->sd_switch_fail = SDR104_SUPPORT_MASK; - } else if (func_to_switch == DDR50_SUPPORT) { - sd_card->sd_switch_fail = - SDR104_SUPPORT_MASK | DDR50_SUPPORT_MASK; - } else if (func_to_switch == SDR50_SUPPORT) { - sd_card->sd_switch_fail = - SDR104_SUPPORT_MASK | DDR50_SUPPORT_MASK | - SDR50_SUPPORT_MASK; - } - TRACE_RET(chip, STATUS_FAIL); - } - - if (func_to_switch == SDR104_SUPPORT) - SET_SD_SDR104(sd_card); - else if (func_to_switch == DDR50_SUPPORT) - SET_SD_DDR50(sd_card); - else if (func_to_switch == SDR50_SUPPORT) - SET_SD_SDR50(sd_card); - else - SET_SD_HS(sd_card); - } - - if (CHK_SD_DDR50(sd_card)) { - RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0x06, 0x04); - retval = sd_set_sample_push_timing(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - if (!func_to_switch || (func_to_switch == HS_SUPPORT)) { - /* Do not try to switch current limit if the card doesn't - * support UHS mode or we don't want it to support UHS mode - */ - return STATUS_SUCCESS; - } - - /* Function Group 4: Current Limit */ - func_to_switch = 0xFF; - - for (i = 0; i < 4; i++) { - switch ((u8)(chip->sd_current_prior >> (i*8))) { - case CURRENT_LIMIT_800: - if (sd_card->func_group4_mask & CURRENT_LIMIT_800_MASK) - func_to_switch = CURRENT_LIMIT_800; - - break; - - case CURRENT_LIMIT_600: - if (sd_card->func_group4_mask & CURRENT_LIMIT_600_MASK) - func_to_switch = CURRENT_LIMIT_600; - - break; - - case CURRENT_LIMIT_400: - if (sd_card->func_group4_mask & CURRENT_LIMIT_400_MASK) - func_to_switch = CURRENT_LIMIT_400; - - break; - - case CURRENT_LIMIT_200: - if (sd_card->func_group4_mask & CURRENT_LIMIT_200_MASK) - func_to_switch = CURRENT_LIMIT_200; - - break; - - default: - continue; - } - - if (func_to_switch != 0xFF) - break; - } - - RTSX_DEBUGP("SD_FUNC_GROUP_4: func_to_switch = 0x%02x", func_to_switch); - - if (func_to_switch <= CURRENT_LIMIT_800) { - retval = sd_check_switch(chip, SD_FUNC_GROUP_4, func_to_switch, bus_width); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_NO_CARD)) - TRACE_RET(chip, STATUS_FAIL); - } - RTSX_DEBUGP("Switch current limit finished! (%d)\n", retval); - } - - if (CHK_SD_DDR50(sd_card)) - RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0x06, 0); - - return STATUS_SUCCESS; -} - -static int sd_wait_data_idle(struct rtsx_chip *chip) -{ - int retval = STATUS_TIMEDOUT; - int i; - u8 val = 0; - - for (i = 0; i < 100; i++) { - RTSX_READ_REG(chip, SD_DATA_STATE, &val); - if (val & SD_DATA_IDLE) { - retval = STATUS_SUCCESS; - break; - } - udelay(100); - } - RTSX_DEBUGP("SD_DATA_STATE: 0x%02x\n", val); - - return retval; -} - -static int sd_sdr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - int retval; - u8 cmd[5]; - - retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - cmd[0] = 0x40 | SEND_TUNING_PATTERN; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_AUTO_TUNING, - cmd, 5, 0x40, 1, SD_BUS_WIDTH_4, NULL, 0, 100); - if (retval != STATUS_SUCCESS) { - (void)sd_wait_data_idle(chip); - - rtsx_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_ddr_tuning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 cmd[5]; - - retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_DEBUGP("sd ddr tuning rx\n"); - - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - cmd[0] = 0x40 | SD_STATUS; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, - cmd, 5, 64, 1, SD_BUS_WIDTH_4, NULL, 0, 100); - if (retval != STATUS_SUCCESS) { - (void)sd_wait_data_idle(chip); - - rtsx_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int mmc_ddr_tunning_rx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 cmd[5], bus_width; - - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - - retval = sd_change_phase(chip, sample_point, TUNE_RX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_DEBUGP("mmc ddr tuning rx\n"); - - cmd[0] = 0x40 | SEND_EXT_CSD; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, - cmd, 5, 0x200, 1, bus_width, NULL, 0, 100); - if (retval != STATUS_SUCCESS) { - (void)sd_wait_data_idle(chip); - - rtsx_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_sdr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - - retval = sd_change_phase(chip, sample_point, TUNE_TX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, SD_RSP_80CLK_TIMEOUT_EN); - - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_RSP_TIMEOUT)) { - rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); - TRACE_RET(chip, STATUS_FAIL); - } - } - - RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); - - return STATUS_SUCCESS; -} - -static int sd_ddr_tuning_tx_cmd(struct rtsx_chip *chip, u8 sample_point) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 cmd[5], bus_width; - - retval = sd_change_phase(chip, sample_point, TUNE_TX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHK_SD(sd_card)) { - bus_width = SD_BUS_WIDTH_4; - } else { - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - } - - retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, SD_RSP_80CLK_TIMEOUT_EN); - - cmd[0] = 0x40 | PROGRAM_CSD; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_write_data(chip, SD_TM_AUTO_WRITE_2, - cmd, 5, 16, 1, bus_width, sd_card->raw_csd, 16, 100); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - rtsx_write_register(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); - TRACE_RET(chip, STATUS_FAIL); - } - - RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); - - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - - return STATUS_SUCCESS; -} - -static u8 sd_search_final_phase(struct rtsx_chip *chip, u32 phase_map, u8 tune_dir) -{ - struct sd_info *sd_card = &(chip->sd_card); - struct timing_phase_path path[MAX_PHASE + 1]; - int i, j, cont_path_cnt; - int new_block, max_len, final_path_idx; - u8 final_phase = 0xFF; - - if (phase_map == 0xFFFFFFFF) { - if (tune_dir == TUNE_RX) - final_phase = (u8)chip->sd_default_rx_phase; - else - final_phase = (u8)chip->sd_default_tx_phase; - - goto Search_Finish; - } - - cont_path_cnt = 0; - new_block = 1; - j = 0; - for (i = 0; i < MAX_PHASE + 1; i++) { - if (phase_map & (1 << i)) { - if (new_block) { - new_block = 0; - j = cont_path_cnt++; - path[j].start = i; - path[j].end = i; - } else { - path[j].end = i; - } - } else { - new_block = 1; - if (cont_path_cnt) { - int idx = cont_path_cnt - 1; - path[idx].len = path[idx].end - path[idx].start + 1; - path[idx].mid = path[idx].start + path[idx].len / 2; - } - } - } - - if (cont_path_cnt == 0) { - RTSX_DEBUGP("No continuous phase path\n"); - goto Search_Finish; - } else { - int idx = cont_path_cnt - 1; - path[idx].len = path[idx].end - path[idx].start + 1; - path[idx].mid = path[idx].start + path[idx].len / 2; - } - - if ((path[0].start == 0) && (path[cont_path_cnt - 1].end == MAX_PHASE)) { - path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1; - path[0].len += path[cont_path_cnt - 1].len; - path[0].mid = path[0].start + path[0].len / 2; - if (path[0].mid < 0) - path[0].mid += MAX_PHASE + 1; - - cont_path_cnt--; - } - - max_len = 0; - final_phase = 0; - final_path_idx = 0; - for (i = 0; i < cont_path_cnt; i++) { - if (path[i].len > max_len) { - max_len = path[i].len; - final_phase = (u8)path[i].mid; - final_path_idx = i; - } - - RTSX_DEBUGP("path[%d].start = %d\n", i, path[i].start); - RTSX_DEBUGP("path[%d].end = %d\n", i, path[i].end); - RTSX_DEBUGP("path[%d].len = %d\n", i, path[i].len); - RTSX_DEBUGP("path[%d].mid = %d\n", i, path[i].mid); - RTSX_DEBUGP("\n"); - } - - if (tune_dir == TUNE_TX) { - if (CHK_SD_SDR104(sd_card)) { - if (max_len > 15) { - int temp_mid = (max_len - 16) / 2; - int temp_final_phase = - path[final_path_idx].end - (max_len - (6 + temp_mid)); - - if (temp_final_phase < 0) - final_phase = (u8)(temp_final_phase + MAX_PHASE + 1); - else - final_phase = (u8)temp_final_phase; - } - } else if (CHK_SD_SDR50(sd_card)) { - if (max_len > 12) { - int temp_mid = (max_len - 13) / 2; - int temp_final_phase = - path[final_path_idx].end - (max_len - (3 + temp_mid)); - - if (temp_final_phase < 0) - final_phase = (u8)(temp_final_phase + MAX_PHASE + 1); - else - final_phase = (u8)temp_final_phase; - } - } - } - -Search_Finish: - RTSX_DEBUGP("Final chosen phase: %d\n", final_phase); - return final_phase; -} - -static int sd_tuning_rx(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - int i, j; - u32 raw_phase_map[3], phase_map; - u8 final_phase; - int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point); - - if (CHK_SD(sd_card)) { - if (CHK_SD_DDR50(sd_card)) - tuning_cmd = sd_ddr_tuning_rx_cmd; - else - tuning_cmd = sd_sdr_tuning_rx_cmd; - - } else { - if (CHK_MMC_DDR52(sd_card)) - tuning_cmd = mmc_ddr_tunning_rx_cmd; - else - TRACE_RET(chip, STATUS_FAIL); - } - - for (i = 0; i < 3; i++) { - raw_phase_map[i] = 0; - for (j = MAX_PHASE; j >= 0; j--) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = tuning_cmd(chip, (u8)j); - if (retval == STATUS_SUCCESS) - raw_phase_map[i] |= 1 << j; - } - } - - phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; - for (i = 0; i < 3; i++) - RTSX_DEBUGP("RX raw_phase_map[%d] = 0x%08x\n", i, raw_phase_map[i]); - - RTSX_DEBUGP("RX phase_map = 0x%08x\n", phase_map); - - final_phase = sd_search_final_phase(chip, phase_map, TUNE_RX); - if (final_phase == 0xFF) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_change_phase(chip, final_phase, TUNE_RX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int sd_ddr_pre_tuning_tx(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - int i; - u32 phase_map; - u8 final_phase; - - RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, SD_RSP_80CLK_TIMEOUT_EN); - - phase_map = 0; - for (i = MAX_PHASE; i >= 0; i--) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - rtsx_write_register(chip, SD_CFG3, - SD_RSP_80CLK_TIMEOUT_EN, 0); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sd_change_phase(chip, (u8)i, TUNE_TX); - if (retval != STATUS_SUCCESS) - continue; - - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - if ((retval == STATUS_SUCCESS) || !sd_check_err_code(chip, SD_RSP_TIMEOUT)) - phase_map |= 1 << i; - } - - RTSX_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); - - RTSX_DEBUGP("DDR TX pre tune phase_map = 0x%08x\n", phase_map); - - final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); - if (final_phase == 0xFF) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_change_phase(chip, final_phase, TUNE_TX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_DEBUGP("DDR TX pre tune phase: %d\n", (int)final_phase); - - return STATUS_SUCCESS; -} - -static int sd_tuning_tx(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - int i, j; - u32 raw_phase_map[3], phase_map; - u8 final_phase; - int (*tuning_cmd)(struct rtsx_chip *chip, u8 sample_point); - - if (CHK_SD(sd_card)) { - if (CHK_SD_DDR50(sd_card)) - tuning_cmd = sd_ddr_tuning_tx_cmd; - else - tuning_cmd = sd_sdr_tuning_tx_cmd; - - } else { - if (CHK_MMC_DDR52(sd_card)) - tuning_cmd = sd_ddr_tuning_tx_cmd; - else - TRACE_RET(chip, STATUS_FAIL); - } - - for (i = 0; i < 3; i++) { - raw_phase_map[i] = 0; - for (j = MAX_PHASE; j >= 0; j--) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - rtsx_write_register(chip, SD_CFG3, - SD_RSP_80CLK_TIMEOUT_EN, 0); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = tuning_cmd(chip, (u8)j); - if (retval == STATUS_SUCCESS) - raw_phase_map[i] |= 1 << j; - } - } - - phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; - for (i = 0; i < 3; i++) - RTSX_DEBUGP("TX raw_phase_map[%d] = 0x%08x\n", i, raw_phase_map[i]); - - RTSX_DEBUGP("TX phase_map = 0x%08x\n", phase_map); - - final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); - if (final_phase == 0xFF) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_change_phase(chip, final_phase, TUNE_TX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int sd_sdr_tuning(struct rtsx_chip *chip) -{ - int retval; - - retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int sd_ddr_tuning(struct rtsx_chip *chip) -{ - int retval; - - if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_ddr_pre_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - retval = sd_change_phase(chip, (u8)chip->sd_ddr_tx_phase, TUNE_TX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (!(chip->sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int mmc_ddr_tuning(struct rtsx_chip *chip) -{ - int retval; - - if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_ddr_pre_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - retval = sd_change_phase(chip, (u8)chip->mmc_ddr_tx_phase, TUNE_TX); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sd_tuning_rx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (!(chip->sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { - retval = sd_tuning_tx(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -int sd_switch_clock(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - int re_tuning = 0; - - retval = select_card(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHECK_PID(chip, 0x5209) && - (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card))) { - if (sd_card->need_retune && (sd_card->sd_clock != chip->cur_clk)) { - re_tuning = 1; - sd_card->need_retune = 0; - } - } - - retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (re_tuning) { - if (CHK_SD(sd_card)) { - if (CHK_SD_DDR50(sd_card)) - retval = sd_ddr_tuning(chip); - else - retval = sd_sdr_tuning(chip); - } else { - if (CHK_MMC_DDR52(sd_card)) - retval = mmc_ddr_tuning(chip); - } - - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_prepare_reset(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - - if (chip->asic_code) - sd_card->sd_clock = 29; - else - sd_card->sd_clock = CLK_30; - - sd_card->sd_type = 0; - sd_card->seq_mode = 0; - sd_card->sd_data_buf_ready = 0; - sd_card->capacity = 0; - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - - chip->capacity[chip->card2lun[SD_CARD]] = 0; - chip->sd_io = 0; - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - if (CHECK_PID(chip, 0x5209)) { - RTSX_WRITE_REG(chip, REG_SD_CFG1, 0xFF, - SD_CLK_DIVIDE_128 | SD_20_MODE | SD_BUS_WIDTH_1); - RTSX_WRITE_REG(chip, SD_SAMPLE_POINT_CTL, 0xFF, SD20_RX_POS_EDGE); - RTSX_WRITE_REG(chip, SD_PUSH_POINT_CTL, 0xFF, 0); - } else { - RTSX_WRITE_REG(chip, REG_SD_CFG1, 0xFF, 0x40); - } - - RTSX_WRITE_REG(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR); - - retval = select_card(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int sd_pull_ctl_disable(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5209)) { - RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0xD5); - } else if (CHECK_PID(chip, 0x5208)) { - RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | SD_D7_PD | SD_CLK_PD | SD_D5_PD); - RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, - SD_D6_PD | SD_D0_PD | SD_D1_PD | XD_D5_PD); - RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, - SD_D4_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); - RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | SD_D3_PD | SD_D2_PD | XD_ALE_PD); - RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); - RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B); - RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69); - } - } - - return STATUS_SUCCESS; -} - -int sd_pull_ctl_enable(struct rtsx_chip *chip) -{ - int retval; - - rtsx_init_cmd(chip); - - if (CHECK_PID(chip, 0x5209)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xAA); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0xAA); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xE9); - } else if (CHECK_PID(chip, 0x5208)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | SD_DAT7_PU | SD_CLK_NP | SD_D5_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - SD_D6_PU | SD_D0_PU | SD_D1_PU | XD_D5_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - SD_D4_PU | XD_CE_PD | XD_CLE_PD | XD_CD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | SD_D3_PU | SD_D2_PU | XD_ALE_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PU | SD_CD_PU | SD_CMD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xA8); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x5A); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0xAA); - } - } - - retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int sd_init_power(struct rtsx_chip *chip) -{ - int retval; - - if (CHECK_PID(chip, 0x5209)) - RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); - - retval = sd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (!chip->ft2_fast_mode) - wait_timeout(250); - - retval = enable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (chip->asic_code) { - retval = sd_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - RTSX_WRITE_REG(chip, FPGA_PULL_CTL, FPGA_SD_PULL_CTL_BIT | 0x20, 0); - } - - if (chip->ft2_fast_mode) { - if (CHECK_PID(chip, 0x5209)) - RTSX_WRITE_REG(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); - - } else { - retval = card_power_on(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - wait_timeout(260); - -#ifdef SUPPORT_OCP - if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { - RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - } - - RTSX_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN); - - return STATUS_SUCCESS; -} - -static int sd_dummy_clock(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5209)) { - RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN, SD_CLK_TOGGLE_EN); - wait_timeout(5); - RTSX_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00); - } else { - RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x01, 0x01); - wait_timeout(5); - RTSX_WRITE_REG(chip, REG_SD_CFG3, 0x01, 0); - } - - return STATUS_SUCCESS; -} - -static int sd_read_lba0(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 cmd[5], bus_width; - - cmd[0] = 0x40 | READ_SINGLE_BLOCK; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - if (CHK_SD(sd_card)) { - bus_width = SD_BUS_WIDTH_4; - } else { - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - } - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, - 5, 512, 1, bus_width, NULL, 0, 100); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sd_check_wp_state(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u32 val; - u16 sd_card_type; - u8 cmd[5], buf[64]; - - retval = sd_send_cmd_get_rsp(chip, APP_CMD, - sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - cmd[0] = 0x40 | SD_STATUS; - cmd[1] = 0; - cmd[2] = 0; - cmd[3] = 0; - cmd[4] = 0; - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, SD_BUS_WIDTH_4, buf, 64, 250); - if (retval != STATUS_SUCCESS) { - rtsx_clear_sd_error(chip); - - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - TRACE_RET(chip, STATUS_FAIL); - } - - RTSX_DEBUGP("ACMD13:\n"); - RTSX_DUMP(buf, 64); - - sd_card_type = ((u16)buf[2] << 8) | buf[3]; - RTSX_DEBUGP("sd_card_type = 0x%04x\n", sd_card_type); - if ((sd_card_type == 0x0001) || (sd_card_type == 0x0002)) { - /* ROM card or OTP */ - chip->card_wp |= SD_CARD; - } - - /* Check SD Machanical Write-Protect Switch */ - val = rtsx_readl(chip, RTSX_BIPR); - if (val & SD_WRITE_PROTECT) - chip->card_wp |= SD_CARD; - - return STATUS_SUCCESS; -} - -static int reset_sd(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval, i = 0, j = 0, k = 0, hi_cap_flow = 0; - int sd_dont_switch = 0; - int support_1v8 = 0; - int try_sdio = 1; - u8 rsp[16]; - u8 switch_bus_width; - u32 voltage = 0; - int sd20_mode = 0; - - SET_SD(sd_card); - -Switch_Fail: - - i = 0; - j = 0; - k = 0; - hi_cap_flow = 0; - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) - goto SD_UNLOCK_ENTRY; -#endif - - retval = sd_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_dummy_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip) && try_sdio) { - int rty_cnt = 0; - - for (; rty_cnt < chip->sdio_retry_cnt; rty_cnt++) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sd_send_cmd_get_rsp(chip, IO_SEND_OP_COND, 0, SD_RSP_TYPE_R4, rsp, 5); - if (retval == STATUS_SUCCESS) { - int func_num = (rsp[1] >> 4) & 0x07; - if (func_num) { - RTSX_DEBUGP("SD_IO card (Function number: %d)!\n", func_num); - chip->sd_io = 1; - TRACE_RET(chip, STATUS_FAIL); - } - - break; - } - - sd_init_power(chip); - - sd_dummy_clock(chip); - } - - RTSX_DEBUGP("Normal card!\n"); - } - - /* Start Initialization Process of SD Card */ -RTY_SD_RST: - retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - wait_timeout(20); - - retval = sd_send_cmd_get_rsp(chip, SEND_IF_COND, 0x000001AA, SD_RSP_TYPE_R7, rsp, 5); - if (retval == STATUS_SUCCESS) { - if ((rsp[4] == 0xAA) && ((rsp[3] & 0x0f) == 0x01)) { - hi_cap_flow = 1; - if (CHECK_PID(chip, 0x5209)) { - if (sd20_mode) { - voltage = SUPPORT_VOLTAGE | - SUPPORT_HIGH_AND_EXTENDED_CAPACITY; - } else { - voltage = SUPPORT_VOLTAGE | - SUPPORT_HIGH_AND_EXTENDED_CAPACITY | - SUPPORT_MAX_POWER_PERMANCE | SUPPORT_1V8; - } - } else { - voltage = SUPPORT_VOLTAGE | 0x40000000; - } - } - } - - if (!hi_cap_flow) { - voltage = SUPPORT_VOLTAGE; - - retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - wait_timeout(20); - } - - do { - retval = sd_send_cmd_get_rsp(chip, APP_CMD, 0, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - j++; - if (j < 3) - goto RTY_SD_RST; - else - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sd_send_cmd_get_rsp(chip, SD_APP_OP_COND, voltage, SD_RSP_TYPE_R3, rsp, 5); - if (retval != STATUS_SUCCESS) { - k++; - if (k < 3) - goto RTY_SD_RST; - else - TRACE_RET(chip, STATUS_FAIL); - } - - i++; - wait_timeout(20); - } while (!(rsp[1] & 0x80) && (i < 255)); - - if (i == 255) - TRACE_RET(chip, STATUS_FAIL); - - if (hi_cap_flow) { - if (rsp[1] & 0x40) - SET_SD_HCXC(sd_card); - else - CLR_SD_HCXC(sd_card); - - if (CHECK_PID(chip, 0x5209) && CHK_SD_HCXC(sd_card) && !sd20_mode) - support_1v8 = (rsp[1] & 0x01) ? 1 : 0; - else - support_1v8 = 0; - } else { - CLR_SD_HCXC(sd_card); - support_1v8 = 0; - } - RTSX_DEBUGP("support_1v8 = %d\n", support_1v8); - - if (support_1v8) { - retval = sd_voltage_switch(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - for (i = 0; i < 3; i++) { - retval = sd_send_cmd_get_rsp(chip, SEND_RELATIVE_ADDR, 0, SD_RSP_TYPE_R6, rsp, 5); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - sd_card->sd_addr = (u32)rsp[1] << 24; - sd_card->sd_addr += (u32)rsp[2] << 16; - - if (sd_card->sd_addr) - break; - } - - retval = sd_check_csd(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - -#ifdef SUPPORT_SD_LOCK -SD_UNLOCK_ENTRY: - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (sd_card->sd_lock_status & SD_LOCKED) { - sd_card->sd_lock_status |= (SD_LOCK_1BIT_MODE | SD_PWD_EXIST); - return STATUS_SUCCESS; - } else if (!(sd_card->sd_lock_status & SD_UNLOCK_POW_ON)) { - sd_card->sd_lock_status &= ~SD_PWD_EXIST; - } -#endif - - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_send_cmd_get_rsp(chip, SET_CLR_CARD_DETECT, 0, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (support_1v8) { - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - switch_bus_width = SD_BUS_WIDTH_4; - } else { - switch_bus_width = SD_BUS_WIDTH_1; - } - - retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (!(sd_card->raw_csd[4] & 0x40)) - sd_dont_switch = 1; - - if (!sd_dont_switch) { - if (sd20_mode) { - /* Set sd_switch_fail here, because we needn't - * switch to UHS mode - */ - sd_card->sd_switch_fail = SDR104_SUPPORT_MASK | - DDR50_SUPPORT_MASK | SDR50_SUPPORT_MASK; - } - - /* Check the card whether follow SD1.1 spec or higher */ - retval = sd_check_spec(chip, switch_bus_width); - if (retval == STATUS_SUCCESS) { - retval = sd_switch_function(chip, switch_bus_width); - if (retval != STATUS_SUCCESS) { - if (CHECK_PID(chip, 0x5209)) - sd_change_bank_voltage(chip, SD_IO_3V3); - - sd_init_power(chip); - sd_dont_switch = 1; - try_sdio = 0; - - goto Switch_Fail; - } - } else { - if (support_1v8) { - if (CHECK_PID(chip, 0x5209)) - sd_change_bank_voltage(chip, SD_IO_3V3); - - sd_init_power(chip); - sd_dont_switch = 1; - try_sdio = 0; - - goto Switch_Fail; - } - } - } - - if (!support_1v8) { - retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif - - if (!sd20_mode && CHK_SD30_SPEED(sd_card)) { - int read_lba0 = 1; - - RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_1v8); - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHK_SD_DDR50(sd_card)) - retval = sd_ddr_tuning(chip); - else - retval = sd_sdr_tuning(chip); - - if (retval != STATUS_SUCCESS) { - if (sd20_mode) { - TRACE_RET(chip, STATUS_FAIL); - } else { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - try_sdio = 0; - sd20_mode = 1; - goto Switch_Fail; - } - } - - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - - if (CHK_SD_DDR50(sd_card)) { - retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval != STATUS_SUCCESS) - read_lba0 = 0; - } - - if (read_lba0) { - retval = sd_read_lba0(chip); - if (retval != STATUS_SUCCESS) { - if (sd20_mode) { - TRACE_RET(chip, STATUS_FAIL); - } else { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - try_sdio = 0; - sd20_mode = 1; - goto Switch_Fail; - } - } - } - } - - retval = sd_check_wp_state(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { - RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_H, 0xFF, 0x02); - RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_L, 0xFF, 0x00); - } -#endif - - return STATUS_SUCCESS; -} - - -static int mmc_test_switch_bus(struct rtsx_chip *chip, u8 width) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 buf[8] = {0}, bus_width, *ptr; - u16 byte_cnt; - int len; - - retval = sd_send_cmd_get_rsp(chip, BUSTEST_W, 0, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, SWITCH_FAIL); - - if (width == MMC_8BIT_BUS) { - buf[0] = 0x55; - buf[1] = 0xAA; - len = 8; - byte_cnt = 8; - bus_width = SD_BUS_WIDTH_8; - } else { - buf[0] = 0x5A; - len = 4; - byte_cnt = 4; - bus_width = SD_BUS_WIDTH_4; - } - - if (!CHECK_PID(chip, 0x5209)) { - retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0x02); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, SWITCH_ERR); - } - - retval = sd_write_data(chip, SD_TM_AUTO_WRITE_3, - NULL, 0, byte_cnt, 1, bus_width, buf, len, 100); - if (retval != STATUS_SUCCESS) { - if (CHECK_PID(chip, 0x5209)) { - u8 val1 = 0, val2 = 0; - rtsx_read_register(chip, REG_SD_STAT1, &val1); - rtsx_read_register(chip, REG_SD_STAT2, &val2); - rtsx_clear_sd_error(chip); - if ((val1 & 0xE0) || val2) - TRACE_RET(chip, SWITCH_ERR); - } else { - rtsx_clear_sd_error(chip); - rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0); - TRACE_RET(chip, SWITCH_ERR); - } - } - - if (!CHECK_PID(chip, 0x5209)) { - retval = rtsx_write_register(chip, REG_SD_CFG3, 0x02, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, SWITCH_ERR); - } - - RTSX_DEBUGP("SD/MMC CMD %d\n", BUSTEST_R); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | BUSTEST_R); - - if (width == MMC_8BIT_BUS) - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x08); - else - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x04); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_NO_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, SD_TM_NORMAL_READ | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2, 0, 0); - if (width == MMC_8BIT_BUS) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 1, 0, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval < 0) { - rtsx_clear_sd_error(chip); - TRACE_RET(chip, SWITCH_ERR); - } - - ptr = rtsx_get_cmd_data(chip) + 1; - - if (width == MMC_8BIT_BUS) { - RTSX_DEBUGP("BUSTEST_R [8bits]: 0x%02x 0x%02x\n", ptr[0], ptr[1]); - if ((ptr[0] == 0xAA) && (ptr[1] == 0x55)) { - u8 rsp[5]; - u32 arg; - - if (CHK_MMC_DDR52(sd_card)) - arg = 0x03B70600; - else - arg = 0x03B70200; - - retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, SD_RSP_TYPE_R1b, rsp, 5); - if ((retval == STATUS_SUCCESS) && !(rsp[4] & MMC_SWITCH_ERR)) - return SWITCH_SUCCESS; - } - } else { - RTSX_DEBUGP("BUSTEST_R [4bits]: 0x%02x\n", ptr[0]); - if (ptr[0] == 0xA5) { - u8 rsp[5]; - u32 arg; - - if (CHK_MMC_DDR52(sd_card)) - arg = 0x03B70500; - else - arg = 0x03B70100; - - retval = sd_send_cmd_get_rsp(chip, SWITCH, arg, SD_RSP_TYPE_R1b, rsp, 5); - if ((retval == STATUS_SUCCESS) && !(rsp[4] & MMC_SWITCH_ERR)) - return SWITCH_SUCCESS; - } - } - - TRACE_RET(chip, SWITCH_FAIL); -} - - -static int mmc_switch_timing_bus(struct rtsx_chip *chip, int switch_ddr) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - u8 *ptr, card_type, card_type_mask = 0; - - CLR_MMC_HS(sd_card); - - RTSX_DEBUGP("SD/MMC CMD %d\n", SEND_EXT_CSD); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | SEND_EXT_CSD); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, 0); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 2); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, - SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, SD_TM_NORMAL_READ | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 196, 0xFF, 0); - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 212, 0xFF, 0); - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 213, 0xFF, 0); - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 214, 0xFF, 0); - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 215, 0xFF, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, 1000); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - rtsx_clear_sd_error(chip); - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0); - } - TRACE_RET(chip, STATUS_FAIL); - } - - ptr = rtsx_get_cmd_data(chip); - if (ptr[0] & SD_TRANSFER_ERR) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - TRACE_RET(chip, STATUS_FAIL); - } - - if (CHK_MMC_SECTOR_MODE(sd_card)) { - sd_card->capacity = ((u32)ptr[5] << 24) | ((u32)ptr[4] << 16) | - ((u32)ptr[3] << 8) | ((u32)ptr[2]); - } - - if (CHECK_PID(chip, 0x5209)) { -#ifdef SUPPORT_SD_LOCK - if (!(sd_card->sd_lock_status & SD_SDR_RST) && - (chip->sd_ctl & SUPPORT_MMC_DDR_MODE)) { - card_type_mask = 0x07; - } else { - card_type_mask = 0x03; - } -#else - if (chip->sd_ctl & SUPPORT_MMC_DDR_MODE) - card_type_mask = 0x07; - else - card_type_mask = 0x03; -#endif - } else { - card_type_mask = 0x03; - } - card_type = ptr[1] & card_type_mask; - if (card_type) { - u8 rsp[5]; - - if (card_type & 0x04) { - if (switch_ddr) - SET_MMC_DDR52(sd_card); - else - SET_MMC_52M(sd_card); - } else if (card_type & 0x02) { - SET_MMC_52M(sd_card); - } else { - SET_MMC_26M(sd_card); - } - - retval = sd_send_cmd_get_rsp(chip, SWITCH, - 0x03B90100, SD_RSP_TYPE_R1b, rsp, 5); - if ((retval != STATUS_SUCCESS) || (rsp[4] & MMC_SWITCH_ERR)) - CLR_MMC_HS(sd_card); - } - - sd_choose_proper_clock(chip); - retval = switch_clock(chip, sd_card->sd_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - /* Test Bus Procedure */ - retval = mmc_test_switch_bus(chip, MMC_8BIT_BUS); - if (retval == SWITCH_SUCCESS) { - SET_MMC_8BIT(sd_card); - chip->card_bus_width[chip->card2lun[SD_CARD]] = 8; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif - } else if (retval == SWITCH_FAIL) { - retval = mmc_test_switch_bus(chip, MMC_4BIT_BUS); - if (retval == SWITCH_SUCCESS) { - SET_MMC_4BIT(sd_card); - chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; -#endif - } else if (retval == SWITCH_FAIL) { - CLR_MMC_8BIT(sd_card); - CLR_MMC_4BIT(sd_card); - } else { - TRACE_RET(chip, STATUS_FAIL); - } - } else { - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - - -static int reset_mmc(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval, i = 0, j = 0, k = 0; - int switch_ddr = 1; - u8 rsp[16]; - u8 spec_ver = 0; - u32 temp; - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) - goto MMC_UNLOCK_ENTRY; -#endif - -Switch_Fail: - retval = sd_prepare_reset(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - - SET_MMC(sd_card); - -RTY_MMC_RST: - retval = sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - do { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sd_send_cmd_get_rsp(chip, SEND_OP_COND, - (SUPPORT_VOLTAGE|0x40000000), SD_RSP_TYPE_R3, rsp, 5); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_BUSY) || sd_check_err_code(chip, SD_TO_ERR)) { - k++; - if (k < 20) { - sd_clr_err_code(chip); - goto RTY_MMC_RST; - } else { - TRACE_RET(chip, STATUS_FAIL); - } - } else { - j++; - if (j < 100) { - sd_clr_err_code(chip); - goto RTY_MMC_RST; - } else { - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - wait_timeout(20); - i++; - } while (!(rsp[1] & 0x80) && (i < 255)); - - if (i == 255) - TRACE_RET(chip, STATUS_FAIL); - - if ((rsp[1] & 0x60) == 0x40) - SET_MMC_SECTOR_MODE(sd_card); - else - CLR_MMC_SECTOR_MODE(sd_card); - - retval = sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - sd_card->sd_addr = 0x00100000; - retval = sd_send_cmd_get_rsp(chip, SET_RELATIVE_ADDR, sd_card->sd_addr, SD_RSP_TYPE_R6, rsp, 5); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_check_csd(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2; - - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - -#ifdef SUPPORT_SD_LOCK -MMC_UNLOCK_ENTRY: - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); -#endif - - retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - chip->card_bus_width[chip->card2lun[SD_CARD]] = 1; - - if (!sd_card->mmc_dont_switch_bus) { - if (spec_ver == 4) { - /* MMC 4.x Cards */ - retval = mmc_switch_timing_bus(chip, switch_ddr); - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - sd_card->mmc_dont_switch_bus = 1; - TRACE_GOTO(chip, Switch_Fail); - } - } - - if (CHK_MMC_SECTOR_MODE(sd_card) && (sd_card->capacity == 0)) - TRACE_RET(chip, STATUS_FAIL); - - if (switch_ddr && CHK_MMC_DDR52(sd_card)) { - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = mmc_ddr_tuning(chip); - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - switch_ddr = 0; - TRACE_GOTO(chip, Switch_Fail); - } - - retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval == STATUS_SUCCESS) { - retval = sd_read_lba0(chip); - if (retval != STATUS_SUCCESS) { - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - switch_ddr = 0; - TRACE_GOTO(chip, Switch_Fail); - } - } - } - } - -#ifdef SUPPORT_SD_LOCK - if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { - RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_H, 0xFF, 0x02); - RTSX_WRITE_REG(chip, REG_SD_BLOCK_CNT_L, 0xFF, 0x00); - } -#endif - - temp = rtsx_readl(chip, RTSX_BIPR); - if (temp & SD_WRITE_PROTECT) - chip->card_wp |= SD_CARD; - - return STATUS_SUCCESS; -} - -int reset_sd_card(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - - sd_init_reg_addr(chip); - - memset(sd_card, 0, sizeof(struct sd_info)); - chip->capacity[chip->card2lun[SD_CARD]] = 0; - - retval = enable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (chip->ignore_sd && CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { - if (chip->asic_code) { - retval = sd_pull_ctl_enable(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - retval = rtsx_write_register(chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - retval = card_share_mode(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - chip->sd_io = 1; - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (chip->sd_ctl & RESET_MMC_FIRST) { - retval = reset_mmc(chip); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_NO_CARD)) - TRACE_RET(chip, STATUS_FAIL); - - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - if (CHECK_PID(chip, 0x5209)) - sd_change_bank_voltage(chip, SD_IO_3V3); - - TRACE_RET(chip, STATUS_FAIL); - } - } - } else { - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - if (sd_check_err_code(chip, SD_NO_CARD)) - TRACE_RET(chip, STATUS_FAIL); - - if (CHECK_PID(chip, 0x5209)) { - retval = sd_change_bank_voltage(chip, SD_IO_3V3); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - if (chip->sd_io) { - TRACE_RET(chip, STATUS_FAIL); - } else { - retval = reset_mmc(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_L, 0xFF, 0); - RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_H, 0xFF, 2); - - chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_DEBUGP("sd_card->sd_type = 0x%x\n", sd_card->sd_type); - - return STATUS_SUCCESS; -} - -static int reset_mmc_only(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - - sd_card->sd_type = 0; - sd_card->seq_mode = 0; - sd_card->sd_data_buf_ready = 0; - sd_card->capacity = 0; - sd_card->sd_switch_fail = 0; - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - - chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0; - - retval = enable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_init_power(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = reset_mmc(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sd_set_clock_divider(chip, SD_CLK_DIVIDE_0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_L, 0xFF, 0); - RTSX_WRITE_REG(chip, REG_SD_BYTE_CNT_H, 0xFF, 2); - - chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; - - retval = sd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_DEBUGP("In reset_mmc_only, sd_card->sd_type = 0x%x\n", sd_card->sd_type); - - return STATUS_SUCCESS; -} - -#define WAIT_DATA_READY_RTY_CNT 255 - -static int wait_data_buf_ready(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int i, retval; - - for (i = 0; i < WAIT_DATA_READY_RTY_CNT; i++) { - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - sd_card->sd_data_buf_ready = 0; - - retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (sd_card->sd_data_buf_ready) { - return sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - } - } - - sd_set_err_code(chip, SD_TO_ERR); - - TRACE_RET(chip, STATUS_FAIL); -} - -void sd_stop_seq_mode(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - - if (sd_card->seq_mode) { - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - return; - - retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, - SD_RSP_TYPE_R1b, NULL, 0); - if (retval != STATUS_SUCCESS) - sd_set_err_code(chip, SD_STS_ERR); - - retval = sd_wait_state_data_ready(chip, 0x08, 1, 1000); - if (retval != STATUS_SUCCESS) - sd_set_err_code(chip, SD_STS_ERR); - - sd_card->seq_mode = 0; - - rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - } -} - -static inline int sd_auto_tune_clock(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - - if (chip->asic_code) { - if (sd_card->sd_clock > 30) - sd_card->sd_clock -= 20; - } else { - switch (sd_card->sd_clock) { - case CLK_200: - sd_card->sd_clock = CLK_150; - break; - - case CLK_150: - sd_card->sd_clock = CLK_120; - break; - - case CLK_120: - sd_card->sd_clock = CLK_100; - break; - - case CLK_100: - sd_card->sd_clock = CLK_80; - break; - - case CLK_80: - sd_card->sd_clock = CLK_60; - break; - - case CLK_60: - sd_card->sd_clock = CLK_50; - break; - - default: - break; - } - } - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt) -{ - struct sd_info *sd_card = &(chip->sd_card); - u32 data_addr; - u8 cfg2; - int retval; - - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - RTSX_DEBUGP("sd_rw: Read %d %s from 0x%x\n", sector_cnt, - (sector_cnt > 1) ? "sectors" : "sector", start_sector); - } else { - RTSX_DEBUGP("sd_rw: Write %d %s to 0x%x\n", sector_cnt, - (sector_cnt > 1) ? "sectors" : "sector", start_sector); - } - - sd_card->cleanup_counter = 0; - - if (!(chip->card_ready & SD_CARD)) { - sd_card->seq_mode = 0; - - retval = reset_sd_card(chip); - if (retval == STATUS_SUCCESS) { - chip->card_ready |= SD_CARD; - chip->card_fail &= ~SD_CARD; - } else { - chip->card_ready &= ~SD_CARD; - chip->card_fail |= SD_CARD; - chip->capacity[chip->card2lun[SD_CARD]] = 0; - chip->rw_need_retry = 1; - TRACE_RET(chip, STATUS_FAIL); - } - } - - if (!CHK_SD_HCXC(sd_card) && !CHK_MMC_SECTOR_MODE(sd_card)) - data_addr = start_sector << 9; - else - data_addr = start_sector; - - sd_clr_err_code(chip); - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_IO_ERR); - TRACE_GOTO(chip, RW_FAIL); - } - - if (sd_card->seq_mode && ((sd_card->pre_dir != srb->sc_data_direction) - || ((sd_card->pre_sec_addr + sd_card->pre_sec_cnt) != start_sector))) { - if ((sd_card->pre_sec_cnt < 0x80) - && (sd_card->pre_dir == DMA_FROM_DEVICE) - && !CHK_SD30_SPEED(sd_card) - && !CHK_SD_HS(sd_card) - && !CHK_MMC_HS(sd_card)) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - } - - retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, - 0, SD_RSP_TYPE_R1b, NULL, 0); - if (retval != STATUS_SUCCESS) { - chip->rw_need_retry = 1; - sd_set_err_code(chip, SD_STS_ERR); - TRACE_GOTO(chip, RW_FAIL); - } - - sd_card->seq_mode = 0; - - retval = rtsx_write_register(chip, RBCTL, RB_FLUSH, RB_FLUSH); - if (retval != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_IO_ERR); - TRACE_GOTO(chip, RW_FAIL); - } - - if ((sd_card->pre_sec_cnt < 0x80) - && !CHK_SD30_SPEED(sd_card) - && !CHK_SD_HS(sd_card) - && !CHK_MMC_HS(sd_card)) { - sd_send_cmd_get_rsp(chip, SEND_STATUS, - sd_card->sd_addr, SD_RSP_TYPE_R1, NULL, 0); - } - } - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, (u8)sector_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, (u8)(sector_cnt >> 8)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - - if (CHK_MMC_8BIT(sd_card)) - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_8); - else if (CHK_MMC_4BIT(sd_card) || CHK_SD(sd_card)) - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - else - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_1); - - if (sd_card->seq_mode) { - cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; - if (CHECK_PID(chip, 0x5209)) { - if (!CHK_SD30_SPEED(sd_card)) - cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; - } - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2); - - trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, DMA_512); - - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_READ_3 | SD_TRANSFER_START); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - } - - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - } else { - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - RTSX_DEBUGP("SD/MMC CMD %d\n", READ_MULTIPLE_BLOCK); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, - 0x40 | READ_MULTIPLE_BLOCK); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(data_addr >> 24)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(data_addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(data_addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)data_addr); - - cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_CHECK_CRC7 | SD_RSP_LEN_6; - if (CHECK_PID(chip, 0x5209)) { - if (!CHK_SD30_SPEED(sd_card)) - cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; - } - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2); - - trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_READ_2 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - } else { - retval = rtsx_send_cmd(chip, SD_CARD, 50); - if (retval < 0) { - rtsx_clear_sd_error(chip); - - chip->rw_need_retry = 1; - sd_set_err_code(chip, SD_TO_ERR); - TRACE_GOTO(chip, RW_FAIL); - } - - retval = wait_data_buf_ready(chip); - if (retval != STATUS_SUCCESS) { - chip->rw_need_retry = 1; - sd_set_err_code(chip, SD_TO_ERR); - TRACE_GOTO(chip, RW_FAIL); - } - - retval = sd_send_cmd_get_rsp(chip, WRITE_MULTIPLE_BLOCK, - data_addr, SD_RSP_TYPE_R1, NULL, 0); - if (retval != STATUS_SUCCESS) { - chip->rw_need_retry = 1; - TRACE_GOTO(chip, RW_FAIL); - } - - rtsx_init_cmd(chip); - - cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END | - SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; - if (CHECK_PID(chip, 0x5209)) { - if (!CHK_SD30_SPEED(sd_card)) - cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; - } - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, cfg2); - - trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, - SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - } - - sd_card->seq_mode = 1; - } - - retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), scsi_bufflen(srb), - scsi_sg_count(srb), srb->sc_data_direction, chip->sd_timeout); - if (retval < 0) { - u8 stat = 0; - int err; - - sd_card->seq_mode = 0; - - if (retval == -ETIMEDOUT) - err = STATUS_TIMEDOUT; - else - err = STATUS_FAIL; - - rtsx_read_register(chip, REG_SD_STAT1, &stat); - rtsx_clear_sd_error(chip); - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - chip->rw_need_retry = 0; - RTSX_DEBUGP("No card exist, exit sd_rw\n"); - TRACE_RET(chip, STATUS_FAIL); - } - - chip->rw_need_retry = 1; - - retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, SD_RSP_TYPE_R1b, NULL, 0); - if (retval != STATUS_SUCCESS) { - sd_set_err_code(chip, SD_STS_ERR); - TRACE_GOTO(chip, RW_FAIL); - } - - if (stat & (SD_CRC7_ERR | SD_CRC16_ERR | SD_CRC_WRITE_ERR)) { - RTSX_DEBUGP("SD CRC error, tune clock!\n"); - sd_set_err_code(chip, SD_CRC_ERR); - TRACE_GOTO(chip, RW_FAIL); - } - - if (err == STATUS_TIMEDOUT) { - sd_set_err_code(chip, SD_TO_ERR); - TRACE_GOTO(chip, RW_FAIL); - } - - TRACE_RET(chip, err); - } - - sd_card->pre_sec_addr = start_sector; - sd_card->pre_sec_cnt = sector_cnt; - sd_card->pre_dir = srb->sc_data_direction; - - return STATUS_SUCCESS; - -RW_FAIL: - sd_card->seq_mode = 0; - - if (detect_card_cd(chip, SD_CARD) != STATUS_SUCCESS) { - chip->rw_need_retry = 0; - RTSX_DEBUGP("No card exist, exit sd_rw\n"); - TRACE_RET(chip, STATUS_FAIL); - } - - if (sd_check_err_code(chip, SD_CRC_ERR)) { - if (CHK_MMC_4BIT(sd_card) || CHK_MMC_8BIT(sd_card)) { - sd_card->mmc_dont_switch_bus = 1; - reset_mmc_only(chip); - sd_card->mmc_dont_switch_bus = 0; - } else { - sd_card->need_retune = 1; - sd_auto_tune_clock(chip); - } - } else if (sd_check_err_code(chip, SD_TO_ERR | SD_STS_ERR)) { - retval = reset_sd_card(chip); - if (retval != STATUS_SUCCESS) { - chip->card_ready &= ~SD_CARD; - chip->card_fail |= SD_CARD; - chip->capacity[chip->card2lun[SD_CARD]] = 0; - } - } - - TRACE_RET(chip, STATUS_FAIL); -} - -#ifdef SUPPORT_CPRM -int soft_reset_sd_card(struct rtsx_chip *chip) -{ - return reset_sd(chip); -} - -int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, - u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check) -{ - int retval; - int timeout = 100; - u16 reg_addr; - u8 *ptr; - int stat_idx = 0; - int rty_cnt = 0; - - RTSX_DEBUGP("EXT SD/MMC CMD %d\n", cmd_idx); - - if (rsp_type == SD_RSP_TYPE_R1b) - timeout = 3000; - -RTY_SEND_CMD: - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, (u8)(arg >> 24)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, (u8)(arg >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, (u8)(arg >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, (u8)arg); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, - 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, - 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); - - if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - stat_idx = 17; - } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); - - stat_idx = 6; - } - rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0, 0); - - rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_STAT1, 0, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, timeout); - if (retval < 0) { - if (retval == -ETIMEDOUT) { - rtsx_clear_sd_error(chip); - - if (rsp_type & SD_WAIT_BUSY_END) { - retval = sd_check_data0_status(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, retval); - } else { - sd_set_err_code(chip, SD_TO_ERR); - } - } - TRACE_RET(chip, STATUS_FAIL); - } - - if (rsp_type == SD_RSP_TYPE_R0) - return STATUS_SUCCESS; - - ptr = rtsx_get_cmd_data(chip) + 1; - - if ((ptr[0] & 0xC0) != 0) { - sd_set_err_code(chip, SD_STS_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - if (!(rsp_type & SD_NO_CHECK_CRC7)) { - if (ptr[stat_idx] & SD_CRC7_ERR) { - if (cmd_idx == WRITE_MULTIPLE_BLOCK) { - sd_set_err_code(chip, SD_CRC_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - if (rty_cnt < SD_MAX_RETRY_COUNT) { - wait_timeout(20); - rty_cnt++; - goto RTY_SEND_CMD; - } else { - sd_set_err_code(chip, SD_CRC_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - if ((cmd_idx == SELECT_CARD) || (cmd_idx == APP_CMD) || - (cmd_idx == SEND_STATUS) || (cmd_idx == STOP_TRANSMISSION)) { - if ((cmd_idx != STOP_TRANSMISSION) && (special_check == 0)) { - if (ptr[1] & 0x80) - TRACE_RET(chip, STATUS_FAIL); - } -#ifdef SUPPORT_SD_LOCK - if (ptr[1] & 0x7D) -#else - if (ptr[1] & 0x7F) -#endif - { - TRACE_RET(chip, STATUS_FAIL); - } - if (ptr[2] & 0xF8) - TRACE_RET(chip, STATUS_FAIL); - - if (cmd_idx == SELECT_CARD) { - if (rsp_type == SD_RSP_TYPE_R2) { - if ((ptr[3] & 0x1E) != 0x04) - TRACE_RET(chip, STATUS_FAIL); - - } else if (rsp_type == SD_RSP_TYPE_R0) { - if ((ptr[3] & 0x1E) != 0x03) - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - if (rsp && rsp_len) - memcpy(rsp, ptr, rsp_len); - - return STATUS_SUCCESS; -} - -int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type) -{ - int retval, rsp_len; - u16 reg_addr; - - if (rsp_type == SD_RSP_TYPE_R0) - return STATUS_SUCCESS; - - rtsx_init_cmd(chip); - - if (rsp_type == SD_RSP_TYPE_R2) { - for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); - - rsp_len = 17; - } else if (rsp_type != SD_RSP_TYPE_R0) { - for (reg_addr = REG_SD_CMD0; reg_addr <= REG_SD_CMD4; reg_addr++) - rtsx_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); - - rsp_len = 6; - } - rtsx_add_cmd(chip, READ_REG_CMD, REG_SD_CMD5, 0xFF, 0); - - retval = rtsx_send_cmd(chip, SD_CARD, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (rsp) { - int min_len = (rsp_len < len) ? rsp_len : len; - - memcpy(rsp, rtsx_get_cmd_data(chip), min_len); - - RTSX_DEBUGP("min_len = %d\n", min_len); - RTSX_DEBUGP("Response in cmd buf: 0x%x 0x%x 0x%x 0x%x\n", - rsp[0], rsp[1], rsp[2], rsp[3]); - } - - return STATUS_SUCCESS; -} - -int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - unsigned int lun = SCSI_LUN(srb); - int len; - u8 buf[18] = { - 0x00, - 0x00, - 0x00, - 0x0E, - 0x00, - 0x00, - 0x00, - 0x00, - 0x53, - 0x44, - 0x20, - 0x43, - 0x61, - 0x72, - 0x64, - 0x00, - 0x00, - 0x00, - }; - - sd_card->pre_cmd_err = 0; - - if (!(CHK_BIT(chip->lun_mc, lun))) { - SET_BIT(chip->lun_mc, lun); - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) || (0x20 != srb->cmnd[4]) || - (0x43 != srb->cmnd[5]) || (0x61 != srb->cmnd[6]) || - (0x72 != srb->cmnd[7]) || (0x64 != srb->cmnd[8])) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - switch (srb->cmnd[1] & 0x0F) { - case 0: - sd_card->sd_pass_thru_en = 0; - break; - - case 1: - sd_card->sd_pass_thru_en = 1; - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - buf[5] = (1 == CHK_SD(sd_card)) ? 0x01 : 0x02; - if (chip->card_wp & SD_CARD) - buf[5] |= 0x80; - - buf[6] = (u8)(sd_card->sd_addr >> 16); - buf[7] = (u8)(sd_card->sd_addr >> 24); - - buf[15] = chip->max_lun; - - len = min(18, (int)scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf, len, srb); - - return TRANSPORT_GOOD; -} - -static inline int get_rsp_type(struct scsi_cmnd *srb, u8 *rsp_type, int *rsp_len) -{ - if (!rsp_type || !rsp_len) - return STATUS_FAIL; - - switch (srb->cmnd[10]) { - case 0x03: - *rsp_type = SD_RSP_TYPE_R0; - *rsp_len = 0; - break; - - case 0x04: - *rsp_type = SD_RSP_TYPE_R1; - *rsp_len = 6; - break; - - case 0x05: - *rsp_type = SD_RSP_TYPE_R1b; - *rsp_len = 6; - break; - - case 0x06: - *rsp_type = SD_RSP_TYPE_R2; - *rsp_len = 17; - break; - - case 0x07: - *rsp_type = SD_RSP_TYPE_R3; - *rsp_len = 6; - break; - - default: - return STATUS_FAIL; - } - - return STATUS_SUCCESS; -} - -int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - unsigned int lun = SCSI_LUN(srb); - int retval, rsp_len; - u8 cmd_idx, rsp_type; - u8 standby = 0, acmd = 0; - u32 arg; - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x02) - standby = 1; - - if (srb->cmnd[1] & 0x01) - acmd = 1; - - arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | - ((u32)srb->cmnd[5] << 8) | srb->cmnd[6]; - - retval = get_rsp_type(srb, &rsp_type, &rsp_len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - sd_card->last_rsp_type = rsp_type; - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) { - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_8); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } - } -#else - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); -#endif - - if (standby) { - retval = sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Cmd_Failed); - } - - if (acmd) { - retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Cmd_Failed); - } - - retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, - sd_card->rsp, rsp_len, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Cmd_Failed); - - if (standby) { - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Cmd_Failed); - } - -#ifdef SUPPORT_SD_LOCK - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Cmd_Failed); -#endif - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - -SD_Execute_Cmd_Failed: - sd_card->pre_cmd_err = 1; - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - release_sd_card(chip); - do_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - - TRACE_RET(chip, TRANSPORT_FAILED); -} - -int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - unsigned int lun = SCSI_LUN(srb); - int retval, rsp_len, i; - int cmd13_checkbit = 0, read_err = 0; - u8 cmd_idx, rsp_type, bus_width; - u8 send_cmd12 = 0, standby = 0, acmd = 0; - u32 data_len; - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x04) - send_cmd12 = 1; - - if (srb->cmnd[1] & 0x02) - standby = 1; - - if (srb->cmnd[1] & 0x01) - acmd = 1; - - data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] << 8) | srb->cmnd[9]; - - retval = get_rsp_type(srb, &rsp_type, &rsp_len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - sd_card->last_rsp_type = rsp_type; - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) - bus_width = SD_BUS_WIDTH_8; - else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) - bus_width = SD_BUS_WIDTH_4; - else - bus_width = SD_BUS_WIDTH_1; - } else { - bus_width = SD_BUS_WIDTH_4; - } - RTSX_DEBUGP("bus_width = %d\n", bus_width); -#else - bus_width = SD_BUS_WIDTH_4; -#endif - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, - SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - if (standby) { - retval = sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - if (acmd) { - retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - if (data_len <= 512) { - int min_len; - u8 *buf; - u16 byte_cnt, blk_cnt; - u8 cmd[5]; - - byte_cnt = ((u16)(srb->cmnd[8] & 0x03) << 8) | srb->cmnd[9]; - blk_cnt = 1; - - cmd[0] = 0x40 | cmd_idx; - cmd[1] = srb->cmnd[3]; - cmd[2] = srb->cmnd[4]; - cmd[3] = srb->cmnd[5]; - cmd[4] = srb->cmnd[6]; - - buf = kmalloc(data_len, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, byte_cnt, - blk_cnt, bus_width, buf, data_len, 2000); - if (retval != STATUS_SUCCESS) { - read_err = 1; - kfree(buf); - rtsx_clear_sd_error(chip); - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - min_len = min(data_len, scsi_bufflen(srb)); - rtsx_stor_set_xfer_buf(buf, min_len, srb); - - kfree(buf); - } else if (!(data_len & 0x1FF)) { - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, - 0xFF, (srb->cmnd[7] & 0xFE) >> 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, - 0xFF, (u8)((data_len & 0x0001FE00) >> 9)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD0, 0xFF, 0x40 | cmd_idx); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD1, 0xFF, srb->cmnd[3]); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD2, 0xFF, srb->cmnd[4]); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD3, 0xFF, srb->cmnd[5]); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CMD4, 0xFF, srb->cmnd[6]); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG1, 0x03, bus_width); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_CFG2, 0xFF, rsp_type); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, - 0xFF, SD_TM_AUTO_READ_2 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), scsi_bufflen(srb), - scsi_sg_count(srb), DMA_FROM_DEVICE, 10000); - if (retval < 0) { - read_err = 1; - rtsx_clear_sd_error(chip); - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - } else { - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - retval = ext_sd_get_rsp(chip, rsp_len, sd_card->rsp, rsp_type); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - - if (standby) { - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - if (send_cmd12) { - retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, - 0, SD_RSP_TYPE_R1b, NULL, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, - SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - - retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - - retval = rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - } - - if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) - cmd13_checkbit = 1; - - for (i = 0; i < 3; i++) { - retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, cmd13_checkbit); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - -SD_Execute_Read_Cmd_Failed: - sd_card->pre_cmd_err = 1; - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - if (read_err) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - - release_sd_card(chip); - do_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - - TRACE_RET(chip, TRANSPORT_FAILED); -} - -int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - unsigned int lun = SCSI_LUN(srb); - int retval, rsp_len, i; - int cmd13_checkbit = 0, write_err = 0; - u8 cmd_idx, rsp_type; - u8 send_cmd12 = 0, standby = 0, acmd = 0; - u32 data_len, arg; -#ifdef SUPPORT_SD_LOCK - int lock_cmd_fail = 0; - u8 sd_lock_state = 0; - u8 lock_cmd_type = 0; -#endif - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - cmd_idx = srb->cmnd[2] & 0x3F; - if (srb->cmnd[1] & 0x04) - send_cmd12 = 1; - - if (srb->cmnd[1] & 0x02) - standby = 1; - - if (srb->cmnd[1] & 0x01) - acmd = 1; - - data_len = ((u32)srb->cmnd[7] << 16) | ((u32)srb->cmnd[8] << 8) | srb->cmnd[9]; - arg = ((u32)srb->cmnd[3] << 24) | ((u32)srb->cmnd[4] << 16) | - ((u32)srb->cmnd[5] << 8) | srb->cmnd[6]; - -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - sd_lock_state = sd_card->sd_lock_status; - sd_lock_state &= SD_LOCKED; - } -#endif - - retval = get_rsp_type(srb, &rsp_type, &rsp_len); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - sd_card->last_rsp_type = rsp_type; - - retval = sd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - -#ifdef SUPPORT_SD_LOCK - if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { - if (CHK_MMC_8BIT(sd_card)) { - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_8); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - - } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); - } - } -#else - retval = rtsx_write_register(chip, REG_SD_CFG1, 0x03, SD_BUS_WIDTH_4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, TRANSPORT_FAILED); -#endif - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, - SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - if (standby) { - retval = sd_select_card(chip, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - if (acmd) { - retval = ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, - sd_card->rsp, rsp_len, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - - if (data_len <= 512) { - u16 i; - u8 *buf; - - buf = kmalloc(data_len, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, TRANSPORT_ERROR); - - rtsx_stor_get_xfer_buf(buf, data_len, srb); - -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) - lock_cmd_type = buf[0] & 0x0F; -#endif - - if (data_len > 256) { - rtsx_init_cmd(chip); - for (i = 0; i < 256; i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - PPBUF_BASE2 + i, 0xFF, buf[i]); - } - retval = rtsx_send_cmd(chip, 0, 250); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - rtsx_init_cmd(chip); - for (i = 256; i < data_len; i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - PPBUF_BASE2 + i, 0xFF, buf[i]); - } - retval = rtsx_send_cmd(chip, 0, 250); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - } else { - rtsx_init_cmd(chip); - for (i = 0; i < data_len; i++) { - rtsx_add_cmd(chip, WRITE_REG_CMD, - PPBUF_BASE2 + i, 0xFF, buf[i]); - } - retval = rtsx_send_cmd(chip, 0, 250); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - } - - kfree(buf); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, srb->cmnd[8] & 0x03); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, srb->cmnd[9]); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, 0xFF, 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, 0xFF, 0x01); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, SD_CARD, 250); - } else if (!(data_len & 0x1FF)) { - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_H, 0xFF, 0x02); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BYTE_CNT_L, 0xFF, 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_H, - 0xFF, (srb->cmnd[7] & 0xFE) >> 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_BLOCK_CNT_L, - 0xFF, (u8)((data_len & 0x0001FE00) >> 9)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, REG_SD_TRANSFER, 0xFF, SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, REG_SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, SD_CARD, scsi_sglist(srb), scsi_bufflen(srb), - scsi_sg_count(srb), DMA_TO_DEVICE, 10000); - - } else { - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - if (retval < 0) { - write_err = 1; - rtsx_clear_sd_error(chip); - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - if (lock_cmd_type == SD_ERASE) { - sd_card->sd_erase_status = SD_UNDER_ERASING; - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - } - - rtsx_init_cmd(chip); - if (CHECK_PID(chip, 0x5209)) - rtsx_add_cmd(chip, CHECK_REG_CMD, SD_BUS_STAT, SD_DAT0_STATUS, SD_DAT0_STATUS); - else - rtsx_add_cmd(chip, CHECK_REG_CMD, 0xFD30, 0x02, 0x02); - - rtsx_send_cmd(chip, SD_CARD, 250); - - retval = sd_update_lock_status(chip); - if (retval != STATUS_SUCCESS) { - RTSX_DEBUGP("Lock command fail!\n"); - lock_cmd_fail = 1; - } - } -#endif /* SUPPORT_SD_LOCK */ - - if (standby) { - retval = sd_select_card(chip, 1); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - if (send_cmd12) { - retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, - 0, SD_RSP_TYPE_R1b, NULL, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - if (data_len < 512) { - retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, - SD_RSP_TYPE_R1, NULL, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - - retval = rtsx_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - - rtsx_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - - if ((srb->cmnd[1] & 0x02) || (srb->cmnd[1] & 0x04)) - cmd13_checkbit = 1; - - for (i = 0; i < 3; i++) { - retval = ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, - SD_RSP_TYPE_R1, NULL, 0, cmd13_checkbit); - if (retval == STATUS_SUCCESS) - break; - } - if (retval != STATUS_SUCCESS) - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - -#ifdef SUPPORT_SD_LOCK - if (cmd_idx == LOCK_UNLOCK) { - if (!lock_cmd_fail) { - RTSX_DEBUGP("lock_cmd_type = 0x%x\n", lock_cmd_type); - if (lock_cmd_type & SD_CLR_PWD) - sd_card->sd_lock_status &= ~SD_PWD_EXIST; - - if (lock_cmd_type & SD_SET_PWD) - sd_card->sd_lock_status |= SD_PWD_EXIST; - } - - RTSX_DEBUGP("sd_lock_state = 0x%x, sd_card->sd_lock_status = 0x%x\n", - sd_lock_state, sd_card->sd_lock_status); - if (sd_lock_state ^ (sd_card->sd_lock_status & SD_LOCKED)) { - sd_card->sd_lock_notify = 1; - if (sd_lock_state) { - if (sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) { - sd_card->sd_lock_status |= (SD_UNLOCK_POW_ON | SD_SDR_RST); - if (CHK_SD(sd_card)) { - retval = reset_sd(chip); - if (retval != STATUS_SUCCESS) { - sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST); - TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); - } - } - - sd_card->sd_lock_status &= ~(SD_UNLOCK_POW_ON | SD_SDR_RST); - } - } - } - } - - if (lock_cmd_fail) { - scsi_set_resid(srb, 0); - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - TRACE_RET(chip, TRANSPORT_FAILED); - } -#endif /* SUPPORT_SD_LOCK */ - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; - -SD_Execute_Write_Cmd_Failed: - sd_card->pre_cmd_err = 1; - set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); - if (write_err) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - - release_sd_card(chip); - do_reset_sd_card(chip); - if (!(chip->card_ready & SD_CARD)) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - - TRACE_RET(chip, TRANSPORT_FAILED); -} - -int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - unsigned int lun = SCSI_LUN(srb); - int count; - u16 data_len; - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - data_len = ((u16)srb->cmnd[7] << 8) | srb->cmnd[8]; - - if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) { - count = (data_len < 17) ? data_len : 17; - } else { - count = (data_len < 6) ? data_len : 6; - } - rtsx_stor_set_xfer_buf(sd_card->rsp, count, srb); - - RTSX_DEBUGP("Response length: %d\n", data_len); - RTSX_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n", - sd_card->rsp[0], sd_card->rsp[1], sd_card->rsp[2], sd_card->rsp[3]); - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} - -int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - unsigned int lun = SCSI_LUN(srb); - int retval; - - if (!sd_card->sd_pass_thru_en) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if (sd_card->pre_cmd_err) { - sd_card->pre_cmd_err = 0; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) || (0x20 != srb->cmnd[4]) || - (0x43 != srb->cmnd[5]) || (0x61 != srb->cmnd[6]) || - (0x72 != srb->cmnd[7]) || (0x64 != srb->cmnd[8])) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - switch (srb->cmnd[1] & 0x0F) { - case 0: -#ifdef SUPPORT_SD_LOCK - if (0x64 == srb->cmnd[9]) - sd_card->sd_lock_status |= SD_SDR_RST; -#endif - retval = reset_sd_card(chip); - if (retval != STATUS_SUCCESS) { -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_SDR_RST; -#endif - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - sd_card->pre_cmd_err = 1; - TRACE_RET(chip, TRANSPORT_FAILED); - } -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status &= ~SD_SDR_RST; -#endif - break; - - case 1: - retval = soft_reset_sd_card(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - sd_card->pre_cmd_err = 1; - TRACE_RET(chip, TRANSPORT_FAILED); - } - break; - - default: - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); - TRACE_RET(chip, TRANSPORT_FAILED); - } - - scsi_set_resid(srb, 0); - return TRANSPORT_GOOD; -} -#endif - -void sd_cleanup_work(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - - if (sd_card->seq_mode) { - RTSX_DEBUGP("SD: stop transmission\n"); - sd_stop_seq_mode(chip); - sd_card->cleanup_counter = 0; - } -} - -int sd_power_off_card3v3(struct rtsx_chip *chip) -{ - int retval; - - retval = disable_card_clock(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, 0); - - if (!chip->ft2_fast_mode) { - retval = card_power_off(chip, SD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - wait_timeout(50); - } - - if (chip->asic_code) { - retval = sd_pull_ctl_disable(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - RTSX_WRITE_REG(chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT | 0x20, FPGA_SD_PULL_CTL_BIT); - } - - return STATUS_SUCCESS; -} - -int release_sd_card(struct rtsx_chip *chip) -{ - struct sd_info *sd_card = &(chip->sd_card); - int retval; - - RTSX_DEBUGP("release_sd_card\n"); - - chip->card_ready &= ~SD_CARD; - chip->card_fail &= ~SD_CARD; - chip->card_wp &= ~SD_CARD; - - chip->sd_io = 0; - chip->sd_int = 0; - -#ifdef SUPPORT_SD_LOCK - sd_card->sd_lock_status = 0; - sd_card->sd_erase_status = 0; -#endif - - memset(sd_card->raw_csd, 0, 16); - memset(sd_card->raw_scr, 0, 8); - - retval = sd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHECK_PID(chip, 0x5209)) { - retval = sd_change_bank_voltage(chip, SD_IO_3V3); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (CHK_SD30_SPEED(sd_card)) - RTSX_WRITE_REG(chip, SD30_DRIVE_SEL, 0x07, chip->sd30_drive_sel_3v3); - - RTSX_WRITE_REG(chip, OCPPARA2, SD_OCP_THD_MASK, chip->sd_400mA_ocp_thd); - } - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts_pstor/sd.h b/drivers/staging/rts_pstor/sd.h deleted file mode 100644 index 1df1aa75e93..00000000000 --- a/drivers/staging/rts_pstor/sd.h +++ /dev/null @@ -1,300 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __REALTEK_RTSX_SD_H -#define __REALTEK_RTSX_SD_H - -#include "rtsx_chip.h" - -#define SUPPORT_VOLTAGE 0x003C0000 - -/* Error Code */ -#define SD_NO_ERROR 0x0 -#define SD_CRC_ERR 0x80 -#define SD_TO_ERR 0x40 -#define SD_NO_CARD 0x20 -#define SD_BUSY 0x10 -#define SD_STS_ERR 0x08 -#define SD_RSP_TIMEOUT 0x04 -#define SD_IO_ERR 0x02 - -/* Return code for MMC switch bus */ -#define SWITCH_SUCCESS 0 -#define SWITCH_ERR 1 -#define SWITCH_FAIL 2 - -/* MMC/SD Command Index */ -/* Basic command (class 0) */ -#define GO_IDLE_STATE 0 -#define SEND_OP_COND 1 -#define ALL_SEND_CID 2 -#define SET_RELATIVE_ADDR 3 -#define SEND_RELATIVE_ADDR 3 -#define SET_DSR 4 -#define IO_SEND_OP_COND 5 -#define SWITCH 6 -#define SELECT_CARD 7 -#define DESELECT_CARD 7 -/* CMD8 is "SEND_EXT_CSD" for MMC4.x Spec - * while is "SEND_IF_COND" for SD 2.0 - */ -#define SEND_EXT_CSD 8 -#define SEND_IF_COND 8 - -#define SEND_CSD 9 -#define SEND_CID 10 -#define VOLTAGE_SWITCH 11 -#define READ_DAT_UTIL_STOP 11 -#define STOP_TRANSMISSION 12 -#define SEND_STATUS 13 -#define GO_INACTIVE_STATE 15 - -#define SET_BLOCKLEN 16 -#define READ_SINGLE_BLOCK 17 -#define READ_MULTIPLE_BLOCK 18 -#define SEND_TUNING_PATTERN 19 - -#define BUSTEST_R 14 -#define BUSTEST_W 19 - -#define WRITE_BLOCK 24 -#define WRITE_MULTIPLE_BLOCK 25 -#define PROGRAM_CSD 27 - -#define ERASE_WR_BLK_START 32 -#define ERASE_WR_BLK_END 33 -#define ERASE_CMD 38 - -#define LOCK_UNLOCK 42 -#define IO_RW_DIRECT 52 - -#define APP_CMD 55 -#define GEN_CMD 56 - -#define SET_BUS_WIDTH 6 -#define SD_STATUS 13 -#define SEND_NUM_WR_BLOCKS 22 -#define SET_WR_BLK_ERASE_COUNT 23 -#define SD_APP_OP_COND 41 -#define SET_CLR_CARD_DETECT 42 -#define SEND_SCR 51 - -#define SD_READ_COMPLETE 0x00 -#define SD_READ_TO 0x01 -#define SD_READ_ADVENCE 0x02 - -#define SD_CHECK_MODE 0x00 -#define SD_SWITCH_MODE 0x80 -#define SD_FUNC_GROUP_1 0x01 -#define SD_FUNC_GROUP_2 0x02 -#define SD_FUNC_GROUP_3 0x03 -#define SD_FUNC_GROUP_4 0x04 -#define SD_CHECK_SPEC_V1_1 0xFF - -#define NO_ARGUMENT 0x00 -#define CHECK_PATTERN 0x000000AA -#define VOLTAGE_SUPPLY_RANGE 0x00000100 -#define SUPPORT_HIGH_AND_EXTENDED_CAPACITY 0x40000000 -#define SUPPORT_MAX_POWER_PERMANCE 0x10000000 -#define SUPPORT_1V8 0x01000000 - -#define SWTICH_NO_ERR 0x00 -#define CARD_NOT_EXIST 0x01 -#define SPEC_NOT_SUPPORT 0x02 -#define CHECK_MODE_ERR 0x03 -#define CHECK_NOT_READY 0x04 -#define SWITCH_CRC_ERR 0x05 -#define SWITCH_MODE_ERR 0x06 -#define SWITCH_PASS 0x07 - -#ifdef SUPPORT_SD_LOCK -#define SD_ERASE 0x08 -#define SD_LOCK 0x04 -#define SD_UNLOCK 0x00 -#define SD_CLR_PWD 0x02 -#define SD_SET_PWD 0x01 - -#define SD_PWD_LEN 0x10 - -#define SD_LOCKED 0x80 -#define SD_LOCK_1BIT_MODE 0x40 -#define SD_PWD_EXIST 0x20 -#define SD_UNLOCK_POW_ON 0x01 -#define SD_SDR_RST 0x02 - -#define SD_NOT_ERASE 0x00 -#define SD_UNDER_ERASING 0x01 -#define SD_COMPLETE_ERASE 0x02 - -#define SD_RW_FORBIDDEN 0x0F - -#endif - -#define HS_SUPPORT 0x01 -#define SDR50_SUPPORT 0x02 -#define SDR104_SUPPORT 0x03 -#define DDR50_SUPPORT 0x04 - -#define HS_SUPPORT_MASK 0x02 -#define SDR50_SUPPORT_MASK 0x04 -#define SDR104_SUPPORT_MASK 0x08 -#define DDR50_SUPPORT_MASK 0x10 - -#define HS_QUERY_SWITCH_OK 0x01 -#define SDR50_QUERY_SWITCH_OK 0x02 -#define SDR104_QUERY_SWITCH_OK 0x03 -#define DDR50_QUERY_SWITCH_OK 0x04 - -#define HS_SWITCH_BUSY 0x02 -#define SDR50_SWITCH_BUSY 0x04 -#define SDR104_SWITCH_BUSY 0x08 -#define DDR50_SWITCH_BUSY 0x10 - -#define FUNCTION_GROUP1_SUPPORT_OFFSET 0x0D -#define FUNCTION_GROUP1_QUERY_SWITCH_OFFSET 0x10 -#define FUNCTION_GROUP1_CHECK_BUSY_OFFSET 0x1D - -#define DRIVING_TYPE_A 0x01 -#define DRIVING_TYPE_B 0x00 -#define DRIVING_TYPE_C 0x02 -#define DRIVING_TYPE_D 0x03 - -#define DRIVING_TYPE_A_MASK 0x02 -#define DRIVING_TYPE_B_MASK 0x01 -#define DRIVING_TYPE_C_MASK 0x04 -#define DRIVING_TYPE_D_MASK 0x08 - -#define TYPE_A_QUERY_SWITCH_OK 0x01 -#define TYPE_B_QUERY_SWITCH_OK 0x00 -#define TYPE_C_QUERY_SWITCH_OK 0x02 -#define TYPE_D_QUERY_SWITCH_OK 0x03 - -#define TYPE_A_SWITCH_BUSY 0x02 -#define TYPE_B_SWITCH_BUSY 0x01 -#define TYPE_C_SWITCH_BUSY 0x04 -#define TYPE_D_SWITCH_BUSY 0x08 - -#define FUNCTION_GROUP3_SUPPORT_OFFSET 0x09 -#define FUNCTION_GROUP3_QUERY_SWITCH_OFFSET 0x0F -#define FUNCTION_GROUP3_CHECK_BUSY_OFFSET 0x19 - -#define CURRENT_LIMIT_200 0x00 -#define CURRENT_LIMIT_400 0x01 -#define CURRENT_LIMIT_600 0x02 -#define CURRENT_LIMIT_800 0x03 - -#define CURRENT_LIMIT_200_MASK 0x01 -#define CURRENT_LIMIT_400_MASK 0x02 -#define CURRENT_LIMIT_600_MASK 0x04 -#define CURRENT_LIMIT_800_MASK 0x08 - -#define CURRENT_LIMIT_200_QUERY_SWITCH_OK 0x00 -#define CURRENT_LIMIT_400_QUERY_SWITCH_OK 0x01 -#define CURRENT_LIMIT_600_QUERY_SWITCH_OK 0x02 -#define CURRENT_LIMIT_800_QUERY_SWITCH_OK 0x03 - -#define CURRENT_LIMIT_200_SWITCH_BUSY 0x01 -#define CURRENT_LIMIT_400_SWITCH_BUSY 0x02 -#define CURRENT_LIMIT_600_SWITCH_BUSY 0x04 -#define CURRENT_LIMIT_800_SWITCH_BUSY 0x08 - -#define FUNCTION_GROUP4_SUPPORT_OFFSET 0x07 -#define FUNCTION_GROUP4_QUERY_SWITCH_OFFSET 0x0F -#define FUNCTION_GROUP4_CHECK_BUSY_OFFSET 0x17 - -#define DATA_STRUCTURE_VER_OFFSET 0x11 - -#define MAX_PHASE 31 - -#define MMC_8BIT_BUS 0x0010 -#define MMC_4BIT_BUS 0x0020 - -#define MMC_SWITCH_ERR 0x80 - -#define SD_IO_3V3 0 -#define SD_IO_1V8 1 - -#define TUNE_TX 0x00 -#define TUNE_RX 0x01 - -#define CHANGE_TX 0x00 -#define CHANGE_RX 0x01 - -#define DCM_HIGH_FREQUENCY_MODE 0x00 -#define DCM_LOW_FREQUENCY_MODE 0x01 - -#define DCM_HIGH_FREQUENCY_MODE_SET 0x0C -#define DCM_Low_FREQUENCY_MODE_SET 0x00 - -#define MULTIPLY_BY_1 0x00 -#define MULTIPLY_BY_2 0x01 -#define MULTIPLY_BY_3 0x02 -#define MULTIPLY_BY_4 0x03 -#define MULTIPLY_BY_5 0x04 -#define MULTIPLY_BY_6 0x05 -#define MULTIPLY_BY_7 0x06 -#define MULTIPLY_BY_8 0x07 -#define MULTIPLY_BY_9 0x08 -#define MULTIPLY_BY_10 0x09 - -#define DIVIDE_BY_2 0x01 -#define DIVIDE_BY_3 0x02 -#define DIVIDE_BY_4 0x03 -#define DIVIDE_BY_5 0x04 -#define DIVIDE_BY_6 0x05 -#define DIVIDE_BY_7 0x06 -#define DIVIDE_BY_8 0x07 -#define DIVIDE_BY_9 0x08 -#define DIVIDE_BY_10 0x09 - -struct timing_phase_path { - int start; - int end; - int mid; - int len; -}; - -int sd_select_card(struct rtsx_chip *chip, int select); -int sd_pull_ctl_enable(struct rtsx_chip *chip); -int reset_sd_card(struct rtsx_chip *chip); -int sd_switch_clock(struct rtsx_chip *chip); -void sd_stop_seq_mode(struct rtsx_chip *chip); -int sd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt); -void sd_cleanup_work(struct rtsx_chip *chip); -int sd_power_off_card3v3(struct rtsx_chip *chip); -int release_sd_card(struct rtsx_chip *chip); -#ifdef SUPPORT_CPRM -int soft_reset_sd_card(struct rtsx_chip *chip); -int ext_sd_send_cmd_get_rsp(struct rtsx_chip *chip, u8 cmd_idx, - u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, int special_check); -int ext_sd_get_rsp(struct rtsx_chip *chip, int len, u8 *rsp, u8 rsp_type); - -int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_execute_no_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int sd_hw_rst(struct scsi_cmnd *srb, struct rtsx_chip *chip); -#endif - -#endif /* __REALTEK_RTSX_SD_H */ diff --git a/drivers/staging/rts_pstor/spi.c b/drivers/staging/rts_pstor/spi.c deleted file mode 100644 index 6b36cc532a8..00000000000 --- a/drivers/staging/rts_pstor/spi.c +++ /dev/null @@ -1,812 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include - -#include "rtsx.h" -#include "rtsx_transport.h" -#include "rtsx_scsi.h" -#include "rtsx_card.h" -#include "spi.h" - -static inline void spi_set_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct spi_info *spi = &(chip->spi); - - spi->err_code = err_code; -} - -static int spi_init(struct rtsx_chip *chip) -{ - RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF, - CS_POLARITY_LOW | DTO_MSB_FIRST | SPI_MASTER | SPI_MODE0 | SPI_AUTO); - RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF); - - return STATUS_SUCCESS; -} - -static int spi_set_init_para(struct rtsx_chip *chip) -{ - struct spi_info *spi = &(chip->spi); - int retval; - - RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, (u8)(spi->clk_div >> 8)); - RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, (u8)(spi->clk_div)); - - retval = switch_clock(chip, spi->spi_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = select_card(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN); - RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN); - - wait_timeout(10); - - retval = spi_init(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int sf_polling_status(struct rtsx_chip *chip, int msec) -{ - int retval; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, SPI_RDSR); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_POLLING_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, msec); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_BUSY_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sf_enable_write(struct rtsx_chip *chip, u8 ins) -{ - struct spi_info *spi = &(chip->spi); - int retval; - - if (!spi->write_en) - return STATUS_SUCCESS; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int sf_disable_write(struct rtsx_chip *chip, u8 ins) -{ - struct spi_info *spi = &(chip->spi); - int retval; - - if (!spi->write_en) - return STATUS_SUCCESS; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static void sf_program(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr, u16 len) -{ - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)len); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(len >> 8)); - if (addr_mode) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CADO_MODE0); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CDO_MODE0); - } - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); -} - -static int sf_erase(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr) -{ - int retval; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - if (addr_mode) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0); - } - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int spi_init_eeprom(struct rtsx_chip *chip) -{ - int retval; - int clk; - - if (chip->asic_code) - clk = 30; - else - clk = CLK_30; - - RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, 0x00); - RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, 0x27); - - retval = switch_clock(chip, clk); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = select_card(chip, SPI_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN); - RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN); - - wait_timeout(10); - - RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF, CS_POLARITY_HIGH | SPI_EEPROM_AUTO); - RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF); - - return STATUS_SUCCESS; -} - -static int spi_eeprom_program_enable(struct rtsx_chip *chip) -{ - int retval; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x86); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x13); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -int spi_erase_eeprom_chip(struct rtsx_chip *chip) -{ - int retval; - - retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = spi_eeprom_program_enable(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x12); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x84); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); - - return STATUS_SUCCESS; -} - -int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr) -{ - int retval; - - retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = spi_eeprom_program_enable(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x07); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); - - return STATUS_SUCCESS; -} - - -int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val) -{ - int retval; - u8 data; - - retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x06); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CADI_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - wait_timeout(5); - RTSX_READ_REG(chip, SPI_DATA, &data); - - if (val) - *val = data; - - RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); - - return STATUS_SUCCESS; -} - -int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val) -{ - int retval; - - retval = spi_init_eeprom(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = spi_eeprom_program_enable(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x05); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, val); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x4E); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01); - - return STATUS_SUCCESS; -} - - -int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct spi_info *spi = &(chip->spi); - - RTSX_DEBUGP("spi_get_status: err_code = 0x%x\n", spi->err_code); - rtsx_stor_set_xfer_buf(&(spi->err_code), min((int)scsi_bufflen(srb), 1), srb); - scsi_set_resid(srb, scsi_bufflen(srb) - 1); - - return STATUS_SUCCESS; -} - -int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - struct spi_info *spi = &(chip->spi); - - spi_set_err_code(chip, SPI_NO_ERR); - - if (chip->asic_code) - spi->spi_clock = ((u16)(srb->cmnd[8]) << 8) | srb->cmnd[9]; - else - spi->spi_clock = srb->cmnd[3]; - - spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; - spi->write_en = srb->cmnd[6]; - - RTSX_DEBUGP("spi_set_parameter: spi_clock = %d, clk_div = %d, write_en = %d\n", - spi->spi_clock, spi->clk_div, spi->write_en); - - return STATUS_SUCCESS; -} - -int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u16 len; - u8 *buf; - - spi_set_err_code(chip, SPI_NO_ERR); - - len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - if (len > 512) { - spi_set_err_code(chip, SPI_INVALID_COMMAND); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, srb->cmnd[3]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, srb->cmnd[4]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, srb->cmnd[5]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, srb->cmnd[6]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, srb->cmnd[7]); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, srb->cmnd[8]); - - if (len == 0) { - if (srb->cmnd[9]) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, - 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, - 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0); - } - } else { - if (srb->cmnd[9]) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, - 0xFF, SPI_TRANSFER0_START | SPI_CADI_MODE0); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, - 0xFF, SPI_TRANSFER0_START | SPI_CDI_MODE0); - } - } - - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - if (len) { - buf = kmalloc(len, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, STATUS_ERROR); - - retval = rtsx_read_ppbuf(chip, buf, len); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_READ_ERR); - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); - scsi_set_resid(srb, 0); - - kfree(buf); - } - - return STATUS_SUCCESS; -} - -int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - unsigned int index = 0, offset = 0; - u8 ins, slow_read; - u32 addr; - u16 len; - u8 *buf; - - spi_set_err_code(chip, SPI_NO_ERR); - - ins = srb->cmnd[3]; - addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6]; - len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - slow_read = srb->cmnd[9]; - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL); - if (buf == NULL) - TRACE_RET(chip, STATUS_ERROR); - - while (len) { - u16 pagelen = SF_PAGE_LEN - (u8)addr; - - if (pagelen > len) - pagelen = len; - - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_FROM_DEVICE, chip, 256, DMA_256); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - - if (slow_read) { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR3, 0xFF, (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_32); - } - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(pagelen >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)pagelen); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CADI_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, DMA_FROM_DEVICE, 10000); - if (retval < 0) { - kfree(buf); - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, TO_XFER_BUF); - - addr += pagelen; - len -= pagelen; - } - - scsi_set_resid(srb, 0); - kfree(buf); - - return STATUS_SUCCESS; -} - -int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 ins, program_mode; - u32 addr; - u16 len; - u8 *buf; - unsigned int index = 0, offset = 0; - - spi_set_err_code(chip, SPI_NO_ERR); - - ins = srb->cmnd[3]; - addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6]; - len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; - program_mode = srb->cmnd[9]; - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - if (program_mode == BYTE_PROGRAM) { - buf = kmalloc(4, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, STATUS_ERROR); - - while (len) { - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, FROM_XFER_BUF); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, buf[0]); - sf_program(chip, ins, 1, addr, 1); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - kfree(buf); - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - addr++; - len--; - } - - kfree(buf); - - } else if (program_mode == AAI_PROGRAM) { - int first_byte = 1; - - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - buf = kmalloc(4, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, STATUS_ERROR); - - while (len) { - rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, FROM_XFER_BUF); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, buf[0]); - if (first_byte) { - sf_program(chip, ins, 1, addr, 1); - first_byte = 0; - } else { - sf_program(chip, ins, 0, 0, 1); - } - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval < 0) { - kfree(buf); - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - len--; - } - - kfree(buf); - - retval = sf_disable_write(chip, SPI_WRDI); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else if (program_mode == PAGE_PROGRAM) { - buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL); - if (!buf) - TRACE_RET(chip, STATUS_NOMEM); - - while (len) { - u16 pagelen = SF_PAGE_LEN - (u8)addr; - - if (pagelen > len) - pagelen = len; - - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_TO_DEVICE, chip, 256, DMA_256); - sf_program(chip, ins, 1, addr, pagelen); - - rtsx_send_cmd_no_wait(chip); - - rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, FROM_XFER_BUF); - - retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, DMA_TO_DEVICE, 100); - if (retval < 0) { - kfree(buf); - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sf_polling_status(chip, 100); - if (retval != STATUS_SUCCESS) { - kfree(buf); - TRACE_RET(chip, STATUS_FAIL); - } - - addr += pagelen; - len -= pagelen; - } - - kfree(buf); - } else { - spi_set_err_code(chip, SPI_INVALID_COMMAND); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 ins, erase_mode; - u32 addr; - - spi_set_err_code(chip, SPI_NO_ERR); - - ins = srb->cmnd[3]; - addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6]; - erase_mode = srb->cmnd[9]; - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - if (erase_mode == PAGE_ERASE) { - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sf_erase(chip, ins, 1, addr); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else if (erase_mode == CHIP_ERASE) { - retval = sf_enable_write(chip, SPI_WREN); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = sf_erase(chip, ins, 0, 0); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - spi_set_err_code(chip, SPI_INVALID_COMMAND); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) -{ - int retval; - u8 ins, status, ewsr; - - ins = srb->cmnd[3]; - status = srb->cmnd[4]; - ewsr = srb->cmnd[5]; - - retval = spi_set_init_para(chip); - if (retval != STATUS_SUCCESS) { - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = sf_enable_write(chip, ewsr); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, status); - rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CDO_MODE0); - rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END); - - retval = rtsx_send_cmd(chip, 0, 100); - if (retval != STATUS_SUCCESS) { - rtsx_clear_spi_error(chip); - spi_set_err_code(chip, SPI_HW_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - diff --git a/drivers/staging/rts_pstor/spi.h b/drivers/staging/rts_pstor/spi.h deleted file mode 100644 index b59291f8b20..00000000000 --- a/drivers/staging/rts_pstor/spi.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __REALTEK_RTSX_SPI_H -#define __REALTEK_RTSX_SPI_H - -/* SPI operation error */ -#define SPI_NO_ERR 0x00 -#define SPI_HW_ERR 0x01 -#define SPI_INVALID_COMMAND 0x02 -#define SPI_READ_ERR 0x03 -#define SPI_WRITE_ERR 0x04 -#define SPI_ERASE_ERR 0x05 -#define SPI_BUSY_ERR 0x06 - -/* Serial flash instruction */ -#define SPI_READ 0x03 -#define SPI_FAST_READ 0x0B -#define SPI_WREN 0x06 -#define SPI_WRDI 0x04 -#define SPI_RDSR 0x05 - -#define SF_PAGE_LEN 256 - -#define BYTE_PROGRAM 0 -#define AAI_PROGRAM 1 -#define PAGE_PROGRAM 2 - -#define PAGE_ERASE 0 -#define CHIP_ERASE 1 - -int spi_erase_eeprom_chip(struct rtsx_chip *chip); -int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr); -int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val); -int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val); -int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip); -int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip); - - -#endif /* __REALTEK_RTSX_SPI_H */ diff --git a/drivers/staging/rts_pstor/trace.h b/drivers/staging/rts_pstor/trace.h deleted file mode 100644 index cf60a1b872b..00000000000 --- a/drivers/staging/rts_pstor/trace.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __REALTEK_RTSX_TRACE_H -#define __REALTEK_RTSX_TRACE_H - -#define _MSG_TRACE - -#ifdef _MSG_TRACE -static inline char *filename(char *path) -{ - char *ptr; - - if (path == NULL) - return NULL; - - ptr = path; - - while (*ptr != '\0') { - if ((*ptr == '\\') || (*ptr == '/')) - path = ptr + 1; - - ptr++; - } - - return path; -} - -#define TRACE_RET(chip, ret) \ -do { \ - char *_file = filename(__FILE__); \ - RTSX_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \ - (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \ - strncpy((chip)->trace_msg[(chip)->msg_idx].func, __func__, MSG_FUNC_LEN-1); \ - strncpy((chip)->trace_msg[(chip)->msg_idx].file, _file, MSG_FILE_LEN-1); \ - get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf, TIME_VAL_LEN); \ - (chip)->trace_msg[(chip)->msg_idx].valid = 1; \ - (chip)->msg_idx++; \ - if ((chip)->msg_idx >= TRACE_ITEM_CNT) { \ - (chip)->msg_idx = 0; \ - } \ - return ret; \ -} while (0) - -#define TRACE_GOTO(chip, label) \ -do { \ - char *_file = filename(__FILE__); \ - RTSX_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \ - (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \ - strncpy((chip)->trace_msg[(chip)->msg_idx].func, __func__, MSG_FUNC_LEN-1); \ - strncpy((chip)->trace_msg[(chip)->msg_idx].file, _file, MSG_FILE_LEN-1); \ - get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf, TIME_VAL_LEN); \ - (chip)->trace_msg[(chip)->msg_idx].valid = 1; \ - (chip)->msg_idx++; \ - if ((chip)->msg_idx >= TRACE_ITEM_CNT) { \ - (chip)->msg_idx = 0; \ - } \ - goto label; \ -} while (0) -#else -#define TRACE_RET(chip, ret) return ret -#define TRACE_GOTO(chip, label) goto label -#endif - -#ifdef CONFIG_RTS_PSTOR_DEBUG -#define RTSX_DUMP(buf, buf_len) \ - print_hex_dump(KERN_DEBUG, RTSX_STOR, DUMP_PREFIX_NONE, \ - 16, 1, (buf), (buf_len), false) -#else -#define RTSX_DUMP(buf, buf_len) -#endif - -#endif /* __REALTEK_RTSX_TRACE_H */ diff --git a/drivers/staging/rts_pstor/xd.c b/drivers/staging/rts_pstor/xd.c deleted file mode 100644 index 9bba5b11a82..00000000000 --- a/drivers/staging/rts_pstor/xd.c +++ /dev/null @@ -1,2052 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#include -#include -#include -#include - -#include "rtsx.h" -#include "rtsx_transport.h" -#include "rtsx_scsi.h" -#include "rtsx_card.h" -#include "xd.h" - -static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no); -static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, u16 logoff, u8 start_page, u8 end_page); - -static inline void xd_set_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct xd_info *xd_card = &(chip->xd_card); - - xd_card->err_code = err_code; -} - -static inline int xd_check_err_code(struct rtsx_chip *chip, u8 err_code) -{ - struct xd_info *xd_card = &(chip->xd_card); - - return (xd_card->err_code == err_code); -} - -static int xd_set_init_para(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - int retval; - - if (chip->asic_code) - xd_card->xd_clock = 47; - else - xd_card->xd_clock = CLK_50; - - retval = switch_clock(chip, xd_card->xd_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int xd_switch_clock(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - int retval; - - retval = select_card(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = switch_clock(chip, xd_card->xd_clock); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int xd_read_id(struct rtsx_chip *chip, u8 id_cmd, u8 *id_buf, u8 buf_len) -{ - int retval, i; - u8 *ptr; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, id_cmd); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_ID); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - - for (i = 0; i < 4; i++) - rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_ADDRESS1 + i), 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 20); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - ptr = rtsx_get_cmd_data(chip) + 1; - if (id_buf && buf_len) { - if (buf_len > 4) - buf_len = 4; - memcpy(id_buf, ptr, buf_len); - } - - return STATUS_SUCCESS; -} - -static void xd_assign_phy_addr(struct rtsx_chip *chip, u32 addr, u8 mode) -{ - struct xd_info *xd_card = &(chip->xd_card); - - switch (mode) { - case XD_RW_ADDR: - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS3, 0xFF, (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF, - xd_card->addr_cycle | XD_CALC_ECC | XD_BA_NO_TRANSFORM); - break; - - case XD_ERASE_ADDR: - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, (u8)addr); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, (u8)(addr >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, 0xFF, (u8)(addr >> 16)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF, - (xd_card->addr_cycle - 1) | XD_CALC_ECC | XD_BA_NO_TRANSFORM); - break; - - default: - break; - } -} - -static int xd_read_redundant(struct rtsx_chip *chip, u32 page_addr, u8 *buf, int buf_len) -{ - int retval, i; - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_REDUNDANT); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - - for (i = 0; i < 6; i++) - rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_PAGE_STATUS + i), 0, 0); - for (i = 0; i < 4; i++) - rtsx_add_cmd(chip, READ_REG_CMD, (u16)(XD_RESERVED0 + i), 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, XD_PARITY, 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - if (buf && buf_len) { - u8 *ptr = rtsx_get_cmd_data(chip) + 1; - - if (buf_len > 11) - buf_len = 11; - memcpy(buf, ptr, buf_len); - } - - return STATUS_SUCCESS; -} - -static int xd_read_data_from_ppb(struct rtsx_chip *chip, int offset, u8 *buf, int buf_len) -{ - int retval, i; - - if (!buf || (buf_len < 0)) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_init_cmd(chip); - - for (i = 0; i < buf_len; i++) - rtsx_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + offset + i, 0, 0); - - retval = rtsx_send_cmd(chip, 0, 250); - if (retval < 0) { - rtsx_clear_xd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - memcpy(buf, rtsx_get_cmd_data(chip), buf_len); - - return STATUS_SUCCESS; -} - -static int xd_read_cis(struct rtsx_chip *chip, u32 page_addr, u8 *buf, int buf_len) -{ - int retval; - u8 reg; - - if (!buf || (buf_len < 10)) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 250); - if (retval == -ETIMEDOUT) { - rtsx_clear_xd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - RTSX_READ_REG(chip, XD_PAGE_STATUS, ®); - if (reg != XD_GPG) { - rtsx_clear_xd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - RTSX_READ_REG(chip, XD_CTL, ®); - if (!(reg & XD_ECC1_ERROR) || !(reg & XD_ECC1_UNCORRECTABLE)) { - retval = xd_read_data_from_ppb(chip, 0, buf, buf_len); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - if (reg & XD_ECC1_ERROR) { - u8 ecc_bit, ecc_byte; - - RTSX_READ_REG(chip, XD_ECC_BIT1, &ecc_bit); - RTSX_READ_REG(chip, XD_ECC_BYTE1, &ecc_byte); - - RTSX_DEBUGP("ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n", ecc_bit, ecc_byte); - if (ecc_byte < buf_len) { - RTSX_DEBUGP("Before correct: 0x%x\n", buf[ecc_byte]); - buf[ecc_byte] ^= (1 << ecc_bit); - RTSX_DEBUGP("After correct: 0x%x\n", buf[ecc_byte]); - } - } - } else if (!(reg & XD_ECC2_ERROR) || !(reg & XD_ECC2_UNCORRECTABLE)) { - rtsx_clear_xd_error(chip); - - retval = xd_read_data_from_ppb(chip, 256, buf, buf_len); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - if (reg & XD_ECC2_ERROR) { - u8 ecc_bit, ecc_byte; - - RTSX_READ_REG(chip, XD_ECC_BIT2, &ecc_bit); - RTSX_READ_REG(chip, XD_ECC_BYTE2, &ecc_byte); - - RTSX_DEBUGP("ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n", ecc_bit, ecc_byte); - if (ecc_byte < buf_len) { - RTSX_DEBUGP("Before correct: 0x%x\n", buf[ecc_byte]); - buf[ecc_byte] ^= (1 << ecc_bit); - RTSX_DEBUGP("After correct: 0x%x\n", buf[ecc_byte]); - } - } - } else { - rtsx_clear_xd_error(chip); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static void xd_fill_pull_ctl_disable(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5209)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xD5); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x15); - } else if (CHECK_PID(chip, 0x5208)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x4B); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x69); - } - } -} - -static void xd_fill_pull_ctl_stage1_barossa(struct rtsx_chip *chip) -{ - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x4B); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - } -} - -static void xd_fill_pull_ctl_enable(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5209)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xAA); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xD5); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x15); - } else if (CHECK_PID(chip, 0x5208)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, - XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, - XD_WP_PD | XD_CE_PU | XD_CLE_PD | XD_CD_PU); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, - XD_RDY_PU | XD_WE_PU | XD_RE_PU | XD_ALE_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x53); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0xA9); - } - } -} - -static int xd_pull_ctl_disable(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5209)) { - RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0xD5); - RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, 0x15); - } else if (CHECK_PID(chip, 0x5208)) { - RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, - XD_D3_PD | XD_D2_PD | XD_D1_PD | XD_D0_PD); - RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, - XD_D7_PD | XD_D6_PD | XD_D5_PD | XD_D4_PD); - RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, - XD_WP_PD | XD_CE_PD | XD_CLE_PD | XD_CD_PU); - RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, - XD_RDY_PD | XD_WE_PD | XD_RE_PD | XD_ALE_PD); - RTSX_WRITE_REG(chip, CARD_PULL_CTL5, 0xFF, - MS_INS_PU | SD_WP_PD | SD_CD_PU | SD_CMD_PD); - RTSX_WRITE_REG(chip, CARD_PULL_CTL6, 0xFF, MS_D5_PD | MS_D4_PD); - } else if (CHECK_PID(chip, 0x5288)) { - if (CHECK_BARO_PKG(chip, QFN)) { - RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL2, 0xFF, 0x55); - RTSX_WRITE_REG(chip, CARD_PULL_CTL3, 0xFF, 0x4B); - RTSX_WRITE_REG(chip, CARD_PULL_CTL4, 0xFF, 0x69); - } - } - - return STATUS_SUCCESS; -} - -static void xd_clear_dma_buffer(struct rtsx_chip *chip) -{ - if (CHECK_PID(chip, 0x5209)) { - int retval; - u8 *buf; - - RTSX_DEBUGP("xD ECC error, dummy write!\n"); - - buf = kmalloc(512, GFP_KERNEL); - if (!buf) - return; - - rtsx_init_cmd(chip); - - trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_SELECT, 0x07, SD_MOD_SEL); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, SD_CLK_EN); - if (chip->asic_code) { - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0xAA); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT, 0); - } - - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, SD_BUS_WIDTH_4); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - - rtsx_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, - SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); - rtsx_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, SD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data(chip, SD_CARD, buf, 512, 0, DMA_TO_DEVICE, 100); - if (retval < 0) { - u8 val; - - rtsx_read_register(chip, SD_STAT1, &val); - RTSX_DEBUGP("SD_STAT1: 0x%x\n", val); - - rtsx_read_register(chip, SD_STAT2, &val); - RTSX_DEBUGP("SD_STAT2: 0x%x\n", val); - - rtsx_read_register(chip, SD_BUS_STAT, &val); - RTSX_DEBUGP("SD_BUS_STAT: 0x%x\n", val); - - rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR); - } - - kfree(buf); - - if (chip->asic_code) { - rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF, 0x55); - } else { - rtsx_write_register(chip, FPGA_PULL_CTL, - FPGA_SD_PULL_CTL_BIT, FPGA_SD_PULL_CTL_BIT); - } - rtsx_write_register(chip, CARD_SELECT, 0x07, XD_MOD_SEL); - rtsx_write_register(chip, CARD_CLK_EN, SD_CLK_EN, 0); - } -} - -static int reset_xd(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - int retval, i, j; - u8 *ptr, id_buf[4], redunt[11]; - - retval = select_card(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, 0xFF, XD_PGSTS_NOT_FF); - if (chip->asic_code) { - if (!CHECK_PID(chip, 0x5288)) - xd_fill_pull_ctl_disable(chip); - else - xd_fill_pull_ctl_stage1_barossa(chip); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, - (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN3) | 0x20); - } - - if (!chip->ft2_fast_mode) - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_INIT, XD_NO_AUTO_PWR_OFF, 0); - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - if (!chip->ft2_fast_mode) { - retval = card_power_off(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - wait_timeout(250); - - if (CHECK_PID(chip, 0x5209)) - RTSX_WRITE_REG(chip, CARD_PULL_CTL1, 0xFF, 0xAA); - - rtsx_init_cmd(chip); - - if (chip->asic_code) { - xd_fill_pull_ctl_enable(chip); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, - (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN2) | 0x20); - } - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - retval = card_power_on(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - -#ifdef SUPPORT_OCP - wait_timeout(50); - if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { - RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - } - - rtsx_init_cmd(chip); - - if (chip->ft2_fast_mode) { - if (chip->asic_code) { - xd_fill_pull_ctl_enable(chip); - } else { - rtsx_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, - (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN2) | 0x20); - } - } - - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, XD_OUTPUT_EN); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CTL, XD_CE_DISEN, XD_CE_DISEN); - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - if (!chip->ft2_fast_mode) - wait_timeout(200); - - retval = xd_set_init_para(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - /* Read ID to check if the timing setting is right */ - for (i = 0; i < 4; i++) { - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DTCTL, 0xFF, - XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * (2 + i) + XD_TIME_RWN_STEP * i); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CATCTL, 0xFF, - XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * (4 + i) + XD_TIME_RWN_STEP * (3 + i)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_RESET); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - - rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - ptr = rtsx_get_cmd_data(chip) + 1; - - RTSX_DEBUGP("XD_DAT: 0x%x, XD_CTL: 0x%x\n", ptr[0], ptr[1]); - - if (((ptr[0] & READY_FLAG) != READY_STATE) || !(ptr[1] & XD_RDY)) - continue; - - retval = xd_read_id(chip, READ_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_DEBUGP("READ_ID: 0x%x 0x%x 0x%x 0x%x\n", - id_buf[0], id_buf[1], id_buf[2], id_buf[3]); - - xd_card->device_code = id_buf[1]; - - /* Check if the xD card is supported */ - switch (xd_card->device_code) { - case XD_4M_X8_512_1: - case XD_4M_X8_512_2: - xd_card->block_shift = 4; - xd_card->page_off = 0x0F; - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 1; - xd_card->capacity = 8000; - XD_SET_4MB(xd_card); - break; - case XD_8M_X8_512: - xd_card->block_shift = 4; - xd_card->page_off = 0x0F; - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 1; - xd_card->capacity = 16000; - break; - case XD_16M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 1; - xd_card->capacity = 32000; - break; - case XD_32M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 3; - xd_card->zone_cnt = 2; - xd_card->capacity = 64000; - break; - case XD_64M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 4; - xd_card->capacity = 128000; - break; - case XD_128M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 8; - xd_card->capacity = 256000; - break; - case XD_256M_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 16; - xd_card->capacity = 512000; - break; - case XD_512M_X8: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 32; - xd_card->capacity = 1024000; - break; - case xD_1G_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 64; - xd_card->capacity = 2048000; - break; - case xD_2G_X8_512: - XD_PAGE_512(xd_card); - xd_card->addr_cycle = 4; - xd_card->zone_cnt = 128; - xd_card->capacity = 4096000; - break; - default: - continue; - } - - /* Confirm timing setting */ - for (j = 0; j < 10; j++) { - retval = xd_read_id(chip, READ_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if (id_buf[1] != xd_card->device_code) - break; - } - - if (j == 10) - break; - } - - if (i == 4) { - xd_card->block_shift = 0; - xd_card->page_off = 0; - xd_card->addr_cycle = 0; - xd_card->capacity = 0; - - TRACE_RET(chip, STATUS_FAIL); - } - - retval = xd_read_id(chip, READ_xD_ID, id_buf, 4); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - RTSX_DEBUGP("READ_xD_ID: 0x%x 0x%x 0x%x 0x%x\n", - id_buf[0], id_buf[1], id_buf[2], id_buf[3]); - if (id_buf[2] != XD_ID_CODE) - TRACE_RET(chip, STATUS_FAIL); - - /* Search CIS block */ - for (i = 0; i < 24; i++) { - u32 page_addr; - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - page_addr = (u32)i << xd_card->block_shift; - - for (j = 0; j < 3; j++) { - retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval == STATUS_SUCCESS) - break; - } - if (j == 3) - continue; - - if (redunt[BLOCK_STATUS] != XD_GBLK) - continue; - - j = 0; - if (redunt[PAGE_STATUS] != XD_GPG) { - for (j = 1; j <= 8; j++) { - retval = xd_read_redundant(chip, page_addr + j, redunt, 11); - if (retval == STATUS_SUCCESS) { - if (redunt[PAGE_STATUS] == XD_GPG) - break; - } - } - - if (j == 9) - break; - } - - /* Check CIS data */ - if ((redunt[BLOCK_STATUS] == XD_GBLK) && (redunt[PARITY] & XD_BA1_ALL0)) { - u8 buf[10]; - - page_addr += j; - - retval = xd_read_cis(chip, page_addr, buf, 10); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - if ((buf[0] == 0x01) && (buf[1] == 0x03) && (buf[2] == 0xD9) - && (buf[3] == 0x01) && (buf[4] == 0xFF) - && (buf[5] == 0x18) && (buf[6] == 0x02) - && (buf[7] == 0xDF) && (buf[8] == 0x01) - && (buf[9] == 0x20)) { - xd_card->cis_block = (u16)i; - } - } - - break; - } - - RTSX_DEBUGP("CIS block: 0x%x\n", xd_card->cis_block); - if (xd_card->cis_block == 0xFFFF) - TRACE_RET(chip, STATUS_FAIL); - - chip->capacity[chip->card2lun[XD_CARD]] = xd_card->capacity; - - return STATUS_SUCCESS; -} - -static int xd_check_data_blank(u8 *redunt) -{ - int i; - - for (i = 0; i < 6; i++) { - if (redunt[PAGE_STATUS + i] != 0xFF) - return 0; - } - - if ((redunt[PARITY] & (XD_ECC1_ALL1 | XD_ECC2_ALL1)) != (XD_ECC1_ALL1 | XD_ECC2_ALL1)) - return 0; - - - for (i = 0; i < 4; i++) { - if (redunt[RESERVED0 + i] != 0xFF) - return 0; - } - - return 1; -} - -static u16 xd_load_log_block_addr(u8 *redunt) -{ - u16 addr = 0xFFFF; - - if (redunt[PARITY] & XD_BA1_BA2_EQL) - addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | redunt[BLOCK_ADDR1_L]; - else if (redunt[PARITY] & XD_BA1_VALID) - addr = ((u16)redunt[BLOCK_ADDR1_H] << 8) | redunt[BLOCK_ADDR1_L]; - else if (redunt[PARITY] & XD_BA2_VALID) - addr = ((u16)redunt[BLOCK_ADDR2_H] << 8) | redunt[BLOCK_ADDR2_L]; - - return addr; -} - -static int xd_init_l2p_tbl(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - int size, i; - - RTSX_DEBUGP("xd_init_l2p_tbl: zone_cnt = %d\n", xd_card->zone_cnt); - - if (xd_card->zone_cnt < 1) - TRACE_RET(chip, STATUS_FAIL); - - size = xd_card->zone_cnt * sizeof(struct zone_entry); - RTSX_DEBUGP("Buffer size for l2p table is %d\n", size); - - xd_card->zone = (struct zone_entry *)vmalloc(size); - if (!xd_card->zone) - TRACE_RET(chip, STATUS_ERROR); - - for (i = 0; i < xd_card->zone_cnt; i++) { - xd_card->zone[i].build_flag = 0; - xd_card->zone[i].l2p_table = NULL; - xd_card->zone[i].free_table = NULL; - xd_card->zone[i].get_index = 0; - xd_card->zone[i].set_index = 0; - xd_card->zone[i].unused_blk_cnt = 0; - } - - return STATUS_SUCCESS; -} - -static inline void free_zone(struct zone_entry *zone) -{ - RTSX_DEBUGP("free_zone\n"); - - if (!zone) - return; - - zone->build_flag = 0; - zone->set_index = 0; - zone->get_index = 0; - zone->unused_blk_cnt = 0; - if (zone->l2p_table) { - vfree(zone->l2p_table); - zone->l2p_table = NULL; - } - if (zone->free_table) { - vfree(zone->free_table); - zone->free_table = NULL; - } -} - -static void xd_set_unused_block(struct rtsx_chip *chip, u32 phy_blk) -{ - struct xd_info *xd_card = &(chip->xd_card); - struct zone_entry *zone; - int zone_no; - - zone_no = (int)phy_blk >> 10; - if (zone_no >= xd_card->zone_cnt) { - RTSX_DEBUGP("Set unused block to invalid zone (zone_no = %d, zone_cnt = %d)\n", - zone_no, xd_card->zone_cnt); - return; - } - zone = &(xd_card->zone[zone_no]); - - if (zone->free_table == NULL) { - if (xd_build_l2p_tbl(chip, zone_no) != STATUS_SUCCESS) - return; - } - - if ((zone->set_index >= XD_FREE_TABLE_CNT) - || (zone->set_index < 0)) { - free_zone(zone); - RTSX_DEBUGP("Set unused block fail, invalid set_index\n"); - return; - } - - RTSX_DEBUGP("Set unused block to index %d\n", zone->set_index); - - zone->free_table[zone->set_index++] = (u16) (phy_blk & 0x3ff); - if (zone->set_index >= XD_FREE_TABLE_CNT) - zone->set_index = 0; - zone->unused_blk_cnt++; -} - -static u32 xd_get_unused_block(struct rtsx_chip *chip, int zone_no) -{ - struct xd_info *xd_card = &(chip->xd_card); - struct zone_entry *zone; - u32 phy_blk; - - if (zone_no >= xd_card->zone_cnt) { - RTSX_DEBUGP("Get unused block from invalid zone (zone_no = %d, zone_cnt = %d)\n", - zone_no, xd_card->zone_cnt); - return BLK_NOT_FOUND; - } - zone = &(xd_card->zone[zone_no]); - - if ((zone->unused_blk_cnt == 0) || (zone->set_index == zone->get_index)) { - free_zone(zone); - RTSX_DEBUGP("Get unused block fail, no unused block available\n"); - return BLK_NOT_FOUND; - } - if ((zone->get_index >= XD_FREE_TABLE_CNT) || (zone->get_index < 0)) { - free_zone(zone); - RTSX_DEBUGP("Get unused block fail, invalid get_index\n"); - return BLK_NOT_FOUND; - } - - RTSX_DEBUGP("Get unused block from index %d\n", zone->get_index); - - phy_blk = zone->free_table[zone->get_index]; - zone->free_table[zone->get_index++] = 0xFFFF; - if (zone->get_index >= XD_FREE_TABLE_CNT) - zone->get_index = 0; - zone->unused_blk_cnt--; - - phy_blk += ((u32)(zone_no) << 10); - return phy_blk; -} - -static void xd_set_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off, u16 phy_off) -{ - struct xd_info *xd_card = &(chip->xd_card); - struct zone_entry *zone; - - zone = &(xd_card->zone[zone_no]); - zone->l2p_table[log_off] = phy_off; -} - -static u32 xd_get_l2p_tbl(struct rtsx_chip *chip, int zone_no, u16 log_off) -{ - struct xd_info *xd_card = &(chip->xd_card); - struct zone_entry *zone; - int retval; - - zone = &(xd_card->zone[zone_no]); - if (zone->l2p_table[log_off] == 0xFFFF) { - u32 phy_blk = 0; - int i; - -#ifdef XD_DELAY_WRITE - retval = xd_delay_write(chip); - if (retval != STATUS_SUCCESS) { - RTSX_DEBUGP("In xd_get_l2p_tbl, delay write fail!\n"); - return BLK_NOT_FOUND; - } -#endif - - if (zone->unused_blk_cnt <= 0) { - RTSX_DEBUGP("No unused block!\n"); - return BLK_NOT_FOUND; - } - - for (i = 0; i < zone->unused_blk_cnt; i++) { - phy_blk = xd_get_unused_block(chip, zone_no); - if (phy_blk == BLK_NOT_FOUND) { - RTSX_DEBUGP("No unused block available!\n"); - return BLK_NOT_FOUND; - } - - retval = xd_init_page(chip, phy_blk, log_off, 0, xd_card->page_off + 1); - if (retval == STATUS_SUCCESS) - break; - } - if (i >= zone->unused_blk_cnt) { - RTSX_DEBUGP("No good unused block available!\n"); - return BLK_NOT_FOUND; - } - - xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(phy_blk & 0x3FF)); - return phy_blk; - } - - return (u32)zone->l2p_table[log_off] + ((u32)(zone_no) << 10); -} - -int reset_xd_card(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - int retval; - - memset(xd_card, 0, sizeof(struct xd_info)); - - xd_card->block_shift = 0; - xd_card->page_off = 0; - xd_card->addr_cycle = 0; - xd_card->capacity = 0; - xd_card->zone_cnt = 0; - xd_card->cis_block = 0xFFFF; - xd_card->delay_write.delay_write_flag = 0; - - retval = enable_card_clock(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = reset_xd(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - retval = xd_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int xd_mark_bad_block(struct rtsx_chip *chip, u32 phy_blk) -{ - struct xd_info *xd_card = &(chip->xd_card); - int retval; - u32 page_addr; - u8 reg = 0; - - RTSX_DEBUGP("mark block 0x%x as bad block\n", phy_blk); - - if (phy_blk == BLK_NOT_FOUND) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_LATER_BBLK); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_H, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_L, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED0, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED1, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED2, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED3, 0xFF, 0xFF); - - page_addr = phy_blk << xd_card->block_shift; - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, xd_card->page_off + 1); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_WRITE_REDUNDANT); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) { - rtsx_clear_xd_error(chip); - rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) - xd_set_err_code(chip, XD_PRG_ERROR); - else - xd_set_err_code(chip, XD_TO_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int xd_init_page(struct rtsx_chip *chip, u32 phy_blk, u16 logoff, u8 start_page, u8 end_page) -{ - struct xd_info *xd_card = &(chip->xd_card); - int retval; - u32 page_addr; - u8 reg = 0; - - RTSX_DEBUGP("Init block 0x%x\n", phy_blk); - - if (start_page > end_page) - TRACE_RET(chip, STATUS_FAIL); - if (phy_blk == BLK_NOT_FOUND) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, 0xFF); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, (u8)(logoff >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)logoff); - - page_addr = (phy_blk << xd_card->block_shift) + start_page; - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, XD_BA_TRANSFORM); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, (end_page - start_page)); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_WRITE_REDUNDANT); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) { - rtsx_clear_xd_error(chip); - rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) { - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - } else { - xd_set_err_code(chip, XD_TO_ERROR); - } - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - -static int xd_copy_page(struct rtsx_chip *chip, u32 old_blk, u32 new_blk, u8 start_page, u8 end_page) -{ - struct xd_info *xd_card = &(chip->xd_card); - u32 old_page, new_page; - u8 i, reg = 0; - int retval; - - RTSX_DEBUGP("Copy page from block 0x%x to block 0x%x\n", old_blk, new_blk); - - if (start_page > end_page) - TRACE_RET(chip, STATUS_FAIL); - - if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) - TRACE_RET(chip, STATUS_FAIL); - - old_page = (old_blk << xd_card->block_shift) + start_page; - new_page = (new_blk << xd_card->block_shift) + start_page; - - XD_CLR_BAD_NEWBLK(xd_card); - - RTSX_WRITE_REG(chip, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); - - for (i = start_page; i < end_page; i++) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - rtsx_clear_xd_error(chip); - xd_set_err_code(chip, XD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, old_page, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS, 0); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 500); - if (retval < 0) { - rtsx_clear_xd_error(chip); - reg = 0; - rtsx_read_register(chip, XD_CTL, ®); - if (reg & (XD_ECC1_ERROR | XD_ECC2_ERROR)) { - wait_timeout(100); - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - xd_set_err_code(chip, XD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - if (((reg & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) == - (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) - || ((reg & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) == - (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) { - rtsx_write_register(chip, XD_PAGE_STATUS, 0xFF, XD_BPG); - rtsx_write_register(chip, XD_BLOCK_STATUS, 0xFF, XD_GBLK); - XD_SET_BAD_OLDBLK(xd_card); - RTSX_DEBUGP("old block 0x%x ecc error\n", old_blk); - } - } else { - xd_set_err_code(chip, XD_TO_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - if (XD_CHK_BAD_OLDBLK(xd_card)) - rtsx_clear_xd_error(chip); - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, new_page, XD_RW_ADDR); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, - XD_TRANSFER_START | XD_WRITE_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 300); - if (retval < 0) { - rtsx_clear_xd_error(chip); - reg = 0; - rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) { - xd_mark_bad_block(chip, new_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - XD_SET_BAD_NEWBLK(xd_card); - } else { - xd_set_err_code(chip, XD_TO_ERROR); - } - TRACE_RET(chip, STATUS_FAIL); - } - - old_page++; - new_page++; - } - - return STATUS_SUCCESS; -} - -static int xd_reset_cmd(struct rtsx_chip *chip) -{ - int retval; - u8 *ptr; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_RESET); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); - rtsx_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 100); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - ptr = rtsx_get_cmd_data(chip) + 1; - if (((ptr[0] & READY_FLAG) == READY_STATE) && (ptr[1] & XD_RDY)) - return STATUS_SUCCESS; - - TRACE_RET(chip, STATUS_FAIL); -} - -static int xd_erase_block(struct rtsx_chip *chip, u32 phy_blk) -{ - struct xd_info *xd_card = &(chip->xd_card); - u32 page_addr; - u8 reg = 0, *ptr; - int i, retval; - - if (phy_blk == BLK_NOT_FOUND) - TRACE_RET(chip, STATUS_FAIL); - - page_addr = phy_blk << xd_card->block_shift; - - for (i = 0; i < 3; i++) { - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_ERASE_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_ERASE); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - rtsx_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); - - retval = rtsx_send_cmd(chip, XD_CARD, 250); - if (retval < 0) { - rtsx_clear_xd_error(chip); - rtsx_read_register(chip, XD_DAT, ®); - if (reg & PROGRAM_ERROR) { - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } else { - xd_set_err_code(chip, XD_ERASE_FAIL); - } - retval = xd_reset_cmd(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - continue; - } - - ptr = rtsx_get_cmd_data(chip) + 1; - if (*ptr & PROGRAM_ERROR) { - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_PRG_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; - } - - xd_mark_bad_block(chip, phy_blk); - xd_set_err_code(chip, XD_ERASE_FAIL); - TRACE_RET(chip, STATUS_FAIL); -} - - -static int xd_build_l2p_tbl(struct rtsx_chip *chip, int zone_no) -{ - struct xd_info *xd_card = &(chip->xd_card); - struct zone_entry *zone; - int retval; - u32 start, end, i; - u16 max_logoff, cur_fst_page_logoff, cur_lst_page_logoff, ent_lst_page_logoff; - u8 redunt[11]; - - RTSX_DEBUGP("xd_build_l2p_tbl: %d\n", zone_no); - - if (xd_card->zone == NULL) { - retval = xd_init_l2p_tbl(chip); - if (retval != STATUS_SUCCESS) - return retval; - } - - if (xd_card->zone[zone_no].build_flag) { - RTSX_DEBUGP("l2p table of zone %d has been built\n", zone_no); - return STATUS_SUCCESS; - } - - zone = &(xd_card->zone[zone_no]); - - if (zone->l2p_table == NULL) { - zone->l2p_table = (u16 *)vmalloc(2000); - if (zone->l2p_table == NULL) - TRACE_GOTO(chip, Build_Fail); - } - memset((u8 *)(zone->l2p_table), 0xff, 2000); - - if (zone->free_table == NULL) { - zone->free_table = (u16 *)vmalloc(XD_FREE_TABLE_CNT * 2); - if (zone->free_table == NULL) - TRACE_GOTO(chip, Build_Fail); - } - memset((u8 *)(zone->free_table), 0xff, XD_FREE_TABLE_CNT * 2); - - if (zone_no == 0) { - if (xd_card->cis_block == 0xFFFF) - start = 0; - else - start = xd_card->cis_block + 1; - if (XD_CHK_4MB(xd_card)) { - end = 0x200; - max_logoff = 499; - } else { - end = 0x400; - max_logoff = 999; - } - } else { - start = (u32)(zone_no) << 10; - end = (u32)(zone_no + 1) << 10; - max_logoff = 999; - } - - RTSX_DEBUGP("start block 0x%x, end block 0x%x\n", start, end); - - zone->set_index = zone->get_index = 0; - zone->unused_blk_cnt = 0; - - for (i = start; i < end; i++) { - u32 page_addr = i << xd_card->block_shift; - u32 phy_block; - - retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval != STATUS_SUCCESS) - continue; - - if (redunt[BLOCK_STATUS] != 0xFF) { - RTSX_DEBUGP("bad block\n"); - continue; - } - - if (xd_check_data_blank(redunt)) { - RTSX_DEBUGP("blank block\n"); - xd_set_unused_block(chip, i); - continue; - } - - cur_fst_page_logoff = xd_load_log_block_addr(redunt); - if ((cur_fst_page_logoff == 0xFFFF) || (cur_fst_page_logoff > max_logoff)) { - retval = xd_erase_block(chip, i); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, i); - continue; - } - - if ((zone_no == 0) && (cur_fst_page_logoff == 0) && (redunt[PAGE_STATUS] != XD_GPG)) - XD_SET_MBR_FAIL(xd_card); - - if (zone->l2p_table[cur_fst_page_logoff] == 0xFFFF) { - zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF); - continue; - } - - phy_block = zone->l2p_table[cur_fst_page_logoff] + ((u32)((zone_no) << 10)); - - page_addr = ((i + 1) << xd_card->block_shift) - 1; - - retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval != STATUS_SUCCESS) - continue; - - cur_lst_page_logoff = xd_load_log_block_addr(redunt); - if (cur_lst_page_logoff == cur_fst_page_logoff) { - int m; - - page_addr = ((phy_block + 1) << xd_card->block_shift) - 1; - - for (m = 0; m < 3; m++) { - retval = xd_read_redundant(chip, page_addr, redunt, 11); - if (retval == STATUS_SUCCESS) - break; - } - - if (m == 3) { - zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF); - retval = xd_erase_block(chip, phy_block); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, phy_block); - continue; - } - - ent_lst_page_logoff = xd_load_log_block_addr(redunt); - if (ent_lst_page_logoff != cur_fst_page_logoff) { - zone->l2p_table[cur_fst_page_logoff] = (u16)(i & 0x3FF); - retval = xd_erase_block(chip, phy_block); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, phy_block); - continue; - } else { - retval = xd_erase_block(chip, i); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, i); - } - } else { - retval = xd_erase_block(chip, i); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, i); - } - } - - if (XD_CHK_4MB(xd_card)) - end = 500; - else - end = 1000; - - i = 0; - for (start = 0; start < end; start++) { - if (zone->l2p_table[start] == 0xFFFF) - i++; - } - - RTSX_DEBUGP("Block count %d, invalid L2P entry %d\n", end, i); - RTSX_DEBUGP("Total unused block: %d\n", zone->unused_blk_cnt); - - if ((zone->unused_blk_cnt - i) < 1) - chip->card_wp |= XD_CARD; - - zone->build_flag = 1; - - return STATUS_SUCCESS; - -Build_Fail: - if (zone->l2p_table) { - vfree(zone->l2p_table); - zone->l2p_table = NULL; - } - if (zone->free_table) { - vfree(zone->free_table); - zone->free_table = NULL; - } - - return STATUS_FAIL; -} - -static int xd_send_cmd(struct rtsx_chip *chip, u8 cmd) -{ - int retval; - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, cmd); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_SET_CMD); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - - retval = rtsx_send_cmd(chip, XD_CARD, 200); - if (retval < 0) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} - -static int xd_read_multiple_pages(struct rtsx_chip *chip, u32 phy_blk, u32 log_blk, - u8 start_page, u8 end_page, u8 *buf, unsigned int *index, unsigned int *offset) -{ - struct xd_info *xd_card = &(chip->xd_card); - u32 page_addr, new_blk; - u16 log_off; - u8 reg_val, page_cnt; - int zone_no, retval, i; - - if (start_page > end_page) - TRACE_RET(chip, STATUS_FAIL); - - page_cnt = end_page - start_page; - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - if ((phy_blk & 0x3FF) == 0x3FF) { - for (i = 0; i < 256; i++) { - page_addr = ((u32)i) << xd_card->block_shift; - - retval = xd_read_redundant(chip, page_addr, NULL, 0); - if (retval == STATUS_SUCCESS) - break; - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - xd_set_err_code(chip, XD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - } - } - - page_addr = (phy_blk << xd_card->block_shift) + start_page; - - rtsx_init_cmd(chip); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_PPB_TO_SIE, XD_PPB_TO_SIE); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, - XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); - - trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_READ_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, - XD_TRANSFER_END | XD_PPB_EMPTY, XD_TRANSFER_END | XD_PPB_EMPTY); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512, scsi_sg_count(chip->srb), - index, offset, DMA_FROM_DEVICE, chip->xd_timeout); - if (retval < 0) { - rtsx_clear_xd_error(chip); - xd_clear_dma_buffer(chip); - - if (retval == -ETIMEDOUT) { - xd_set_err_code(chip, XD_TO_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } else { - TRACE_GOTO(chip, Fail); - } - } - - return STATUS_SUCCESS; - -Fail: - RTSX_READ_REG(chip, XD_PAGE_STATUS, ®_val); - - if (reg_val != XD_GPG) - xd_set_err_code(chip, XD_PRG_ERROR); - - RTSX_READ_REG(chip, XD_CTL, ®_val); - - if (((reg_val & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) - == (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) - || ((reg_val & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) - == (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) { - wait_timeout(100); - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - xd_set_err_code(chip, XD_NO_CARD); - TRACE_RET(chip, STATUS_FAIL); - } - - xd_set_err_code(chip, XD_ECC_ERROR); - - new_blk = xd_get_unused_block(chip, zone_no); - if (new_blk == NO_NEW_BLK) { - XD_CLR_BAD_OLDBLK(xd_card); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = xd_copy_page(chip, phy_blk, new_blk, 0, xd_card->page_off + 1); - if (retval != STATUS_SUCCESS) { - if (!XD_CHK_BAD_NEWBLK(xd_card)) { - retval = xd_erase_block(chip, new_blk); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, new_blk); - } else { - XD_CLR_BAD_NEWBLK(xd_card); - } - XD_CLR_BAD_OLDBLK(xd_card); - TRACE_RET(chip, STATUS_FAIL); - } - xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); - xd_erase_block(chip, phy_blk); - xd_mark_bad_block(chip, phy_blk); - XD_CLR_BAD_OLDBLK(xd_card); - } - - TRACE_RET(chip, STATUS_FAIL); -} - -static int xd_finish_write(struct rtsx_chip *chip, - u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) -{ - struct xd_info *xd_card = &(chip->xd_card); - int retval, zone_no; - u16 log_off; - - RTSX_DEBUGP("xd_finish_write, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n", - old_blk, new_blk, log_blk); - - if (page_off > xd_card->page_off) - TRACE_RET(chip, STATUS_FAIL); - - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - if (old_blk == BLK_NOT_FOUND) { - retval = xd_init_page(chip, new_blk, log_off, - page_off, xd_card->page_off + 1); - if (retval != STATUS_SUCCESS) { - retval = xd_erase_block(chip, new_blk); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, new_blk); - TRACE_RET(chip, STATUS_FAIL); - } - } else { - retval = xd_copy_page(chip, old_blk, new_blk, - page_off, xd_card->page_off + 1); - if (retval != STATUS_SUCCESS) { - if (!XD_CHK_BAD_NEWBLK(xd_card)) { - retval = xd_erase_block(chip, new_blk); - if (retval == STATUS_SUCCESS) - xd_set_unused_block(chip, new_blk); - } - XD_CLR_BAD_NEWBLK(xd_card); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = xd_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) { - if (XD_CHK_BAD_OLDBLK(xd_card)) { - xd_mark_bad_block(chip, old_blk); - XD_CLR_BAD_OLDBLK(xd_card); - } else { - xd_set_unused_block(chip, old_blk); - } - } else { - xd_set_err_code(chip, XD_NO_ERROR); - XD_CLR_BAD_OLDBLK(xd_card); - } - } - - xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); - - return STATUS_SUCCESS; -} - -static int xd_prepare_write(struct rtsx_chip *chip, - u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) -{ - int retval; - - RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x, page_off = %d\n", - __func__, old_blk, new_blk, log_blk, (int)page_off); - - if (page_off) { - retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} - - -static int xd_write_multiple_pages(struct rtsx_chip *chip, u32 old_blk, u32 new_blk, u32 log_blk, - u8 start_page, u8 end_page, u8 *buf, unsigned int *index, unsigned int *offset) -{ - struct xd_info *xd_card = &(chip->xd_card); - u32 page_addr; - int zone_no, retval; - u16 log_off; - u8 page_cnt, reg_val; - - RTSX_DEBUGP("%s, old_blk = 0x%x, new_blk = 0x%x, log_blk = 0x%x\n", - __func__, old_blk, new_blk, log_blk); - - if (start_page > end_page) - TRACE_RET(chip, STATUS_FAIL); - - page_cnt = end_page - start_page; - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - page_addr = (new_blk << xd_card->block_shift) + start_page; - - retval = xd_send_cmd(chip, READ1_1); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - rtsx_init_cmd(chip); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, (u8)(log_off >> 8)); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, (u8)log_off); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_GBLK); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); - - xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, XD_BA_TRANSFORM); - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); - rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER); - - trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512, DMA_512); - - rtsx_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, XD_TRANSFER_START | XD_WRITE_PAGES); - rtsx_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, XD_TRANSFER_END); - - rtsx_send_cmd_no_wait(chip); - - retval = rtsx_transfer_data_partial(chip, XD_CARD, buf, page_cnt * 512, scsi_sg_count(chip->srb), - index, offset, DMA_TO_DEVICE, chip->xd_timeout); - if (retval < 0) { - rtsx_clear_xd_error(chip); - - if (retval == -ETIMEDOUT) { - xd_set_err_code(chip, XD_TO_ERROR); - TRACE_RET(chip, STATUS_FAIL); - } else { - TRACE_GOTO(chip, Fail); - } - } - - if (end_page == (xd_card->page_off + 1)) { - xd_card->delay_write.delay_write_flag = 0; - - if (old_blk != BLK_NOT_FOUND) { - retval = xd_erase_block(chip, old_blk); - if (retval == STATUS_SUCCESS) { - if (XD_CHK_BAD_OLDBLK(xd_card)) { - xd_mark_bad_block(chip, old_blk); - XD_CLR_BAD_OLDBLK(xd_card); - } else { - xd_set_unused_block(chip, old_blk); - } - } else { - xd_set_err_code(chip, XD_NO_ERROR); - XD_CLR_BAD_OLDBLK(xd_card); - } - } - xd_set_l2p_tbl(chip, zone_no, log_off, (u16)(new_blk & 0x3FF)); - } - - return STATUS_SUCCESS; - -Fail: - RTSX_READ_REG(chip, XD_DAT, ®_val); - if (reg_val & PROGRAM_ERROR) { - xd_set_err_code(chip, XD_PRG_ERROR); - xd_mark_bad_block(chip, new_blk); - } - - TRACE_RET(chip, STATUS_FAIL); -} - -#ifdef XD_DELAY_WRITE -int xd_delay_write(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - struct xd_delay_write_tag *delay_write = &(xd_card->delay_write); - int retval; - - if (delay_write->delay_write_flag) { - RTSX_DEBUGP("xd_delay_write\n"); - retval = xd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - delay_write->delay_write_flag = 0; - retval = xd_finish_write(chip, - delay_write->old_phyblock, delay_write->new_phyblock, - delay_write->logblock, delay_write->pageoff); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } - - return STATUS_SUCCESS; -} -#endif - -int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt) -{ - struct xd_info *xd_card = &(chip->xd_card); - unsigned int lun = SCSI_LUN(srb); -#ifdef XD_DELAY_WRITE - struct xd_delay_write_tag *delay_write = &(xd_card->delay_write); -#endif - int retval, zone_no; - unsigned int index = 0, offset = 0; - u32 log_blk, old_blk = 0, new_blk = 0; - u16 log_off, total_sec_cnt = sector_cnt; - u8 start_page, end_page = 0, page_cnt; - u8 *ptr; - - xd_set_err_code(chip, XD_NO_ERROR); - - xd_card->cleanup_counter = 0; - - RTSX_DEBUGP("xd_rw: scsi_sg_count = %d\n", scsi_sg_count(srb)); - - ptr = (u8 *)scsi_sglist(srb); - - retval = xd_switch_clock(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - - log_blk = start_sector >> xd_card->block_shift; - start_page = (u8)start_sector & xd_card->page_off; - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - if (xd_card->zone[zone_no].build_flag == 0) { - retval = xd_build_l2p_tbl(chip, zone_no); - if (retval != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { -#ifdef XD_DELAY_WRITE - if (delay_write->delay_write_flag && - (delay_write->logblock == log_blk) && - (start_page > delay_write->pageoff)) { - delay_write->delay_write_flag = 0; - if (delay_write->old_phyblock != BLK_NOT_FOUND) { - retval = xd_copy_page(chip, - delay_write->old_phyblock, - delay_write->new_phyblock, - delay_write->pageoff, start_page); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } - old_blk = delay_write->old_phyblock; - new_blk = delay_write->new_phyblock; - } else if (delay_write->delay_write_flag && - (delay_write->logblock == log_blk) && - (start_page == delay_write->pageoff)) { - delay_write->delay_write_flag = 0; - old_blk = delay_write->old_phyblock; - new_blk = delay_write->new_phyblock; - } else { - retval = xd_delay_write(chip); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); - new_blk = xd_get_unused_block(chip, zone_no); - if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = xd_prepare_write(chip, old_blk, new_blk, log_blk, start_page); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } -#ifdef XD_DELAY_WRITE - } -#endif - } else { -#ifdef XD_DELAY_WRITE - retval = xd_delay_write(chip); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - - old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); - if (old_blk == BLK_NOT_FOUND) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - RTSX_DEBUGP("old_blk = 0x%x\n", old_blk); - - while (total_sec_cnt) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - - if ((start_page + total_sec_cnt) > (xd_card->page_off + 1)) - end_page = xd_card->page_off + 1; - else - end_page = start_page + (u8)total_sec_cnt; - - page_cnt = end_page - start_page; - if (srb->sc_data_direction == DMA_FROM_DEVICE) { - retval = xd_read_multiple_pages(chip, old_blk, log_blk, - start_page, end_page, ptr, &index, &offset); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } else { - retval = xd_write_multiple_pages(chip, old_blk, new_blk, log_blk, - start_page, end_page, ptr, &index, &offset); - if (retval != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - total_sec_cnt -= page_cnt; - if (scsi_sg_count(srb) == 0) - ptr += page_cnt * 512; - - if (total_sec_cnt == 0) - break; - - log_blk++; - zone_no = (int)(log_blk / 1000); - log_off = (u16)(log_blk % 1000); - - if (xd_card->zone[zone_no].build_flag == 0) { - retval = xd_build_l2p_tbl(chip, zone_no); - if (retval != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - } - - old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); - if (old_blk == BLK_NOT_FOUND) { - if (srb->sc_data_direction == DMA_FROM_DEVICE) - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); - else - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - - TRACE_RET(chip, STATUS_FAIL); - } - - if (srb->sc_data_direction == DMA_TO_DEVICE) { - new_blk = xd_get_unused_block(chip, zone_no); - if (new_blk == BLK_NOT_FOUND) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } - } - - start_page = 0; - } - - if ((srb->sc_data_direction == DMA_TO_DEVICE) && - (end_page != (xd_card->page_off + 1))) { -#ifdef XD_DELAY_WRITE - delay_write->delay_write_flag = 1; - delay_write->old_phyblock = old_blk; - delay_write->new_phyblock = new_blk; - delay_write->logblock = log_blk; - delay_write->pageoff = end_page; -#else - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - chip->card_fail |= XD_CARD; - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - - retval = xd_finish_write(chip, old_blk, new_blk, log_blk, end_page); - if (retval != STATUS_SUCCESS) { - if (detect_card_cd(chip, XD_CARD) != STATUS_SUCCESS) { - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); - TRACE_RET(chip, STATUS_FAIL); - } - set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); - TRACE_RET(chip, STATUS_FAIL); - } -#endif - } - - scsi_set_resid(srb, 0); - - return STATUS_SUCCESS; -} - -void xd_free_l2p_tbl(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - int i = 0; - - if (xd_card->zone != NULL) { - for (i = 0; i < xd_card->zone_cnt; i++) { - if (xd_card->zone[i].l2p_table != NULL) { - vfree(xd_card->zone[i].l2p_table); - xd_card->zone[i].l2p_table = NULL; - } - if (xd_card->zone[i].free_table != NULL) { - vfree(xd_card->zone[i].free_table); - xd_card->zone[i].free_table = NULL; - } - } - vfree(xd_card->zone); - xd_card->zone = NULL; - } -} - -void xd_cleanup_work(struct rtsx_chip *chip) -{ -#ifdef XD_DELAY_WRITE - struct xd_info *xd_card = &(chip->xd_card); - - if (xd_card->delay_write.delay_write_flag) { - RTSX_DEBUGP("xD: delay write\n"); - xd_delay_write(chip); - xd_card->cleanup_counter = 0; - } -#endif -} - -int xd_power_off_card3v3(struct rtsx_chip *chip) -{ - int retval; - - retval = disable_card_clock(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - RTSX_WRITE_REG(chip, CARD_OE, XD_OUTPUT_EN, 0); - - if (!chip->ft2_fast_mode) { - retval = card_power_off(chip, XD_CARD); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - wait_timeout(50); - } - - if (chip->asic_code) { - retval = xd_pull_ctl_disable(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - } else { - RTSX_WRITE_REG(chip, FPGA_PULL_CTL, 0xFF, 0xDF); - } - - return STATUS_SUCCESS; -} - -int release_xd_card(struct rtsx_chip *chip) -{ - struct xd_info *xd_card = &(chip->xd_card); - int retval; - - RTSX_DEBUGP("release_xd_card\n"); - - chip->card_ready &= ~XD_CARD; - chip->card_fail &= ~XD_CARD; - chip->card_wp &= ~XD_CARD; - - xd_card->delay_write.delay_write_flag = 0; - - xd_free_l2p_tbl(chip); - - retval = xd_power_off_card3v3(chip); - if (retval != STATUS_SUCCESS) - TRACE_RET(chip, STATUS_FAIL); - - return STATUS_SUCCESS; -} diff --git a/drivers/staging/rts_pstor/xd.h b/drivers/staging/rts_pstor/xd.h deleted file mode 100644 index cd9fbc1f96d..00000000000 --- a/drivers/staging/rts_pstor/xd.h +++ /dev/null @@ -1,188 +0,0 @@ -/* Driver for Realtek PCI-Express card reader - * Header file - * - * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. - * - * 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, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see . - * - * Author: - * wwang (wei_wang@realsil.com.cn) - * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China - */ - -#ifndef __REALTEK_RTSX_XD_H -#define __REALTEK_RTSX_XD_H - -#define XD_DELAY_WRITE - -/* Error Codes */ -#define XD_NO_ERROR 0x00 -#define XD_NO_MEMORY 0x80 -#define XD_PRG_ERROR 0x40 -#define XD_NO_CARD 0x20 -#define XD_READ_FAIL 0x10 -#define XD_ERASE_FAIL 0x08 -#define XD_WRITE_FAIL 0x04 -#define XD_ECC_ERROR 0x02 -#define XD_TO_ERROR 0x01 - -/* XD Commands */ -#define READ1_1 0x00 -#define READ1_2 0x01 -#define READ2 0x50 -#define READ_ID 0x90 -#define RESET 0xff -#define PAGE_PRG_1 0x80 -#define PAGE_PRG_2 0x10 -#define BLK_ERASE_1 0x60 -#define BLK_ERASE_2 0xD0 -#define READ_STS 0x70 -#define READ_xD_ID 0x9A -#define COPY_BACK_512 0x8A -#define COPY_BACK_2K 0x85 -#define READ1_1_2 0x30 -#define READ1_1_3 0x35 -#define CHG_DAT_OUT_1 0x05 -#define RDM_DAT_OUT_1 0x05 -#define CHG_DAT_OUT_2 0xE0 -#define RDM_DAT_OUT_2 0xE0 -#define CHG_DAT_OUT_2 0xE0 -#define CHG_DAT_IN_1 0x85 -#define CACHE_PRG 0x15 - -/* Redundant Area Related */ -#define XD_EXTRA_SIZE 0x10 -#define XD_2K_EXTRA_SIZE 0x40 - -#define NOT_WRITE_PROTECTED 0x80 -#define READY_STATE 0x40 -#define PROGRAM_ERROR 0x01 -#define PROGRAM_ERROR_N_1 0x02 -#define INTERNAL_READY 0x20 -#define READY_FLAG 0x5F - -#define XD_8M_X8_512 0xE6 -#define XD_16M_X8_512 0x73 -#define XD_32M_X8_512 0x75 -#define XD_64M_X8_512 0x76 -#define XD_128M_X8_512 0x79 -#define XD_256M_X8_512 0x71 -#define XD_128M_X8_2048 0xF1 -#define XD_256M_X8_2048 0xDA -#define XD_512M_X8 0xDC -#define XD_128M_X16_2048 0xC1 -#define XD_4M_X8_512_1 0xE3 -#define XD_4M_X8_512_2 0xE5 -#define xD_1G_X8_512 0xD3 -#define xD_2G_X8_512 0xD5 - -#define XD_ID_CODE 0xB5 - -#define VENDOR_BLOCK 0xEFFF -#define CIS_BLOCK 0xDFFF - -#define BLK_NOT_FOUND 0xFFFFFFFF - -#define NO_NEW_BLK 0xFFFFFFFF - -#define PAGE_CORRECTABLE 0x0 -#define PAGE_NOTCORRECTABLE 0x1 - -#define NO_OFFSET 0x0 -#define WITH_OFFSET 0x1 - -#define Sect_Per_Page 4 -#define XD_ADDR_MODE_2C XD_ADDR_MODE_2A - -#define ZONE0_BAD_BLOCK 23 -#define NOT_ZONE0_BAD_BLOCK 24 - -#define XD_RW_ADDR 0x01 -#define XD_ERASE_ADDR 0x02 - -#define XD_PAGE_512(xd_card) \ -do { \ - (xd_card)->block_shift = 5; \ - (xd_card)->page_off = 0x1F; \ -} while (0) - -#define XD_SET_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag |= 0x01) -#define XD_CLR_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag &= ~0x01) -#define XD_CHK_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag & 0x01) - -#define XD_SET_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag |= 0x02) -#define XD_CLR_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag &= ~0x02) -#define XD_CHK_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag & 0x02) - -#define XD_SET_MBR_FAIL(xd_card) ((xd_card)->multi_flag |= 0x04) -#define XD_CLR_MBR_FAIL(xd_card) ((xd_card)->multi_flag &= ~0x04) -#define XD_CHK_MBR_FAIL(xd_card) ((xd_card)->multi_flag & 0x04) - -#define XD_SET_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag |= 0x08) -#define XD_CLR_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag &= ~0x08) -#define XD_CHK_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag & 0x08) - -#define XD_SET_4MB(xd_card) ((xd_card)->multi_flag |= 0x10) -#define XD_CLR_4MB(xd_card) ((xd_card)->multi_flag &= ~0x10) -#define XD_CHK_4MB(xd_card) ((xd_card)->multi_flag & 0x10) - -#define XD_SET_ECC_ERR(xd_card) ((xd_card)->multi_flag |= 0x40) -#define XD_CLR_ECC_ERR(xd_card) ((xd_card)->multi_flag &= ~0x40) -#define XD_CHK_ECC_ERR(xd_card) ((xd_card)->multi_flag & 0x40) - -#define PAGE_STATUS 0 -#define BLOCK_STATUS 1 -#define BLOCK_ADDR1_L 2 -#define BLOCK_ADDR1_H 3 -#define BLOCK_ADDR2_L 4 -#define BLOCK_ADDR2_H 5 -#define RESERVED0 6 -#define RESERVED1 7 -#define RESERVED2 8 -#define RESERVED3 9 -#define PARITY 10 - -#define CIS0_0 0 -#define CIS0_1 1 -#define CIS0_2 2 -#define CIS0_3 3 -#define CIS0_4 4 -#define CIS0_5 5 -#define CIS0_6 6 -#define CIS0_7 7 -#define CIS0_8 8 -#define CIS0_9 9 -#define CIS1_0 256 -#define CIS1_1 (256 + 1) -#define CIS1_2 (256 + 2) -#define CIS1_3 (256 + 3) -#define CIS1_4 (256 + 4) -#define CIS1_5 (256 + 5) -#define CIS1_6 (256 + 6) -#define CIS1_7 (256 + 7) -#define CIS1_8 (256 + 8) -#define CIS1_9 (256 + 9) - -int reset_xd_card(struct rtsx_chip *chip); -#ifdef XD_DELAY_WRITE -int xd_delay_write(struct rtsx_chip *chip); -#endif -int xd_rw(struct scsi_cmnd *srb, struct rtsx_chip *chip, u32 start_sector, u16 sector_cnt); -void xd_free_l2p_tbl(struct rtsx_chip *chip); -void xd_cleanup_work(struct rtsx_chip *chip); -int xd_power_off_card3v3(struct rtsx_chip *chip); -int release_xd_card(struct rtsx_chip *chip); - -#endif /* __REALTEK_RTSX_XD_H */ - -- cgit v1.2.3 From 1d08782c0ed0b5c52488dac3ae12944cc8ff39e8 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 25 Oct 2012 16:54:48 -0400 Subject: staging: csr: remove CsrMutexLock function nobody inside the csr directory is calling this function, so remove this Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext.c | 28 ---------------------------- drivers/staging/csr/csr_framework_ext.h | 15 --------------- 2 files changed, 43 deletions(-) diff --git a/drivers/staging/csr/csr_framework_ext.c b/drivers/staging/csr/csr_framework_ext.c index e62878ecbd2..2033e9755e4 100644 --- a/drivers/staging/csr/csr_framework_ext.c +++ b/drivers/staging/csr/csr_framework_ext.c @@ -60,34 +60,6 @@ void CsrMutexDestroy(CsrMutexHandle *mutexHandle) { } -/*----------------------------------------------------------------------------* - * NAME - * CsrMutexLock - * - * DESCRIPTION - * Lock the mutex refered to by the provided handle. - * - * RETURNS - * Possible values: - * CSR_RESULT_SUCCESS in case of success - * CSR_FE_RESULT_INVALID_HANDLE in case the mutexHandle is invalid - * - *----------------------------------------------------------------------------*/ -CsrResult CsrMutexLock(CsrMutexHandle *mutexHandle) -{ - if (mutexHandle == NULL) - { - return CSR_FE_RESULT_INVALID_POINTER; - } - - if (down_interruptible(mutexHandle)) - { - return CSR_FE_RESULT_INVALID_POINTER; - } - - return CSR_RESULT_SUCCESS; -} - /*----------------------------------------------------------------------------* * NAME * CsrMutexUnlock diff --git a/drivers/staging/csr/csr_framework_ext.h b/drivers/staging/csr/csr_framework_ext.h index 16635a9717b..a49e459385b 100644 --- a/drivers/staging/csr/csr_framework_ext.h +++ b/drivers/staging/csr/csr_framework_ext.h @@ -111,21 +111,6 @@ void CsrEventDestroy(CsrEventHandle *eventHandle); *----------------------------------------------------------------------------*/ CsrResult CsrMutexCreate(CsrMutexHandle *mutexHandle); -/*----------------------------------------------------------------------------* - * NAME - * CsrMutexLock - * - * DESCRIPTION - * Lock the mutex refered to by the provided handle. - * - * RETURNS - * Possible values: - * CSR_RESULT_SUCCESS in case of success - * CSR_FE_RESULT_INVALID_HANDLE in case the mutexHandle is invalid - * - *----------------------------------------------------------------------------*/ -CsrResult CsrMutexLock(CsrMutexHandle *mutexHandle); - /*----------------------------------------------------------------------------* * NAME * CsrMutexUnlock -- cgit v1.2.3 From ce1f5b80a1954c07b80fa8b778690f778da663d6 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 25 Oct 2012 16:55:27 -0400 Subject: staging: csr: remove CsrMutexUnlock function Nobody is using this function inside the csr directory, so remove this function also Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext.c | 25 ------------------------- drivers/staging/csr/csr_framework_ext.h | 30 ------------------------------ 2 files changed, 55 deletions(-) diff --git a/drivers/staging/csr/csr_framework_ext.c b/drivers/staging/csr/csr_framework_ext.c index 2033e9755e4..086438feb81 100644 --- a/drivers/staging/csr/csr_framework_ext.c +++ b/drivers/staging/csr/csr_framework_ext.c @@ -60,31 +60,6 @@ void CsrMutexDestroy(CsrMutexHandle *mutexHandle) { } -/*----------------------------------------------------------------------------* - * NAME - * CsrMutexUnlock - * - * DESCRIPTION - * Unlock the mutex refered to by the provided handle. - * - * RETURNS - * Possible values: - * CSR_RESULT_SUCCESS in case of success - * CSR_FE_RESULT_INVALID_HANDLE in case the mutexHandle is invalid - * - *----------------------------------------------------------------------------*/ -CsrResult CsrMutexUnlock(CsrMutexHandle *mutexHandle) -{ - if (mutexHandle == NULL) - { - return CSR_FE_RESULT_INVALID_POINTER; - } - - up(mutexHandle); - - return CSR_RESULT_SUCCESS; -} - /*----------------------------------------------------------------------------* * NAME * CsrThreadSleep diff --git a/drivers/staging/csr/csr_framework_ext.h b/drivers/staging/csr/csr_framework_ext.h index a49e459385b..cad0cec0be9 100644 --- a/drivers/staging/csr/csr_framework_ext.h +++ b/drivers/staging/csr/csr_framework_ext.h @@ -111,21 +111,6 @@ void CsrEventDestroy(CsrEventHandle *eventHandle); *----------------------------------------------------------------------------*/ CsrResult CsrMutexCreate(CsrMutexHandle *mutexHandle); -/*----------------------------------------------------------------------------* - * NAME - * CsrMutexUnlock - * - * DESCRIPTION - * Unlock the mutex refered to by the provided handle. - * - * RETURNS - * Possible values: - * CSR_RESULT_SUCCESS in case of success - * CSR_FE_RESULT_INVALID_HANDLE in case the mutexHandle is invalid - * - *----------------------------------------------------------------------------*/ -CsrResult CsrMutexUnlock(CsrMutexHandle *mutexHandle); - /*----------------------------------------------------------------------------* * NAME * CsrMutexDestroy @@ -139,21 +124,6 @@ CsrResult CsrMutexUnlock(CsrMutexHandle *mutexHandle); *----------------------------------------------------------------------------*/ void CsrMutexDestroy(CsrMutexHandle *mutexHandle); -/*----------------------------------------------------------------------------* - * NAME - * CsrGlobalMutexLock - * - * DESCRIPTION - * Lock the global mutex. The global mutex is a single pre-initialised - * shared mutex, spinlock or similar that does not need to be created prior - * to use. The limitation is that there is only one single lock shared - * between all code. Consequently, it must only be used very briefly to - * either protect simple one-time initialisation or to protect the creation - * of a dedicated mutex by calling CsrMutexCreate. - * - *----------------------------------------------------------------------------*/ -void CsrGlobalMutexLock(void); - /*----------------------------------------------------------------------------* * NAME * CsrGlobalMutexUnlock -- cgit v1.2.3 From 0edf65f9b47fcffc003d6416167d60e47ab17e2f Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 25 Oct 2012 16:55:59 -0400 Subject: staging: csr: remove CsrMutexDestroy function this function never gets called from anywhere, so remove this too. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext.c | 15 --------------- drivers/staging/csr/csr_framework_ext.h | 13 ------------- 2 files changed, 28 deletions(-) diff --git a/drivers/staging/csr/csr_framework_ext.c b/drivers/staging/csr/csr_framework_ext.c index 086438feb81..48573f64edd 100644 --- a/drivers/staging/csr/csr_framework_ext.c +++ b/drivers/staging/csr/csr_framework_ext.c @@ -45,21 +45,6 @@ CsrResult CsrMutexCreate(CsrMutexHandle *mutexHandle) return CSR_RESULT_SUCCESS; } -/*----------------------------------------------------------------------------* - * NAME - * CsrMutexDestroy - * - * DESCRIPTION - * Destroy the previously created mutex. - * - * RETURNS - * void - * - *----------------------------------------------------------------------------*/ -void CsrMutexDestroy(CsrMutexHandle *mutexHandle) -{ -} - /*----------------------------------------------------------------------------* * NAME * CsrThreadSleep diff --git a/drivers/staging/csr/csr_framework_ext.h b/drivers/staging/csr/csr_framework_ext.h index cad0cec0be9..83781ea6ef0 100644 --- a/drivers/staging/csr/csr_framework_ext.h +++ b/drivers/staging/csr/csr_framework_ext.h @@ -111,19 +111,6 @@ void CsrEventDestroy(CsrEventHandle *eventHandle); *----------------------------------------------------------------------------*/ CsrResult CsrMutexCreate(CsrMutexHandle *mutexHandle); -/*----------------------------------------------------------------------------* - * NAME - * CsrMutexDestroy - * - * DESCRIPTION - * Destroy the previously created mutex. - * - * RETURNS - * void - * - *----------------------------------------------------------------------------*/ -void CsrMutexDestroy(CsrMutexHandle *mutexHandle); - /*----------------------------------------------------------------------------* * NAME * CsrGlobalMutexUnlock -- cgit v1.2.3 From 4c956106d483a2186c6ea97ae93cd88b2cdbea53 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 25 Oct 2012 16:56:38 -0400 Subject: staging: csr: remove CsrMutexCreate function nobody are calling this function in here, so remove this Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext.c | 26 -------------------------- drivers/staging/csr/csr_framework_ext.h | 16 ---------------- 2 files changed, 42 deletions(-) diff --git a/drivers/staging/csr/csr_framework_ext.c b/drivers/staging/csr/csr_framework_ext.c index 48573f64edd..5b2bc4bdeff 100644 --- a/drivers/staging/csr/csr_framework_ext.c +++ b/drivers/staging/csr/csr_framework_ext.c @@ -19,32 +19,6 @@ #include "csr_framework_ext.h" #include "csr_panic.h" -/*----------------------------------------------------------------------------* - * NAME - * CsrMutexCreate - * - * DESCRIPTION - * Create a mutex and return a handle to the created mutex. - * - * RETURNS - * Possible values: - * CSR_RESULT_SUCCESS in case of success - * CSR_FE_RESULT_NO_MORE_MUTEXES in case of out of mutex resources - * CSR_FE_RESULT_INVALID_POINTER in case the mutexHandle pointer is invalid - * - *----------------------------------------------------------------------------*/ -CsrResult CsrMutexCreate(CsrMutexHandle *mutexHandle) -{ - if (mutexHandle == NULL) - { - return CSR_FE_RESULT_INVALID_POINTER; - } - - sema_init(mutexHandle, 1); - - return CSR_RESULT_SUCCESS; -} - /*----------------------------------------------------------------------------* * NAME * CsrThreadSleep diff --git a/drivers/staging/csr/csr_framework_ext.h b/drivers/staging/csr/csr_framework_ext.h index 83781ea6ef0..3991274d812 100644 --- a/drivers/staging/csr/csr_framework_ext.h +++ b/drivers/staging/csr/csr_framework_ext.h @@ -95,22 +95,6 @@ CsrResult CsrEventSet(CsrEventHandle *eventHandle, u32 eventBits); *----------------------------------------------------------------------------*/ void CsrEventDestroy(CsrEventHandle *eventHandle); -/*----------------------------------------------------------------------------* - * NAME - * CsrMutexCreate - * - * DESCRIPTION - * Create a mutex and return a handle to the created mutex. - * - * RETURNS - * Possible values: - * CSR_RESULT_SUCCESS in case of success - * CSR_FE_RESULT_NO_MORE_MUTEXES in case of out of mutex resources - * CSR_FE_RESULT_INVALID_POINTER in case the mutexHandle pointer is invalid - * - *----------------------------------------------------------------------------*/ -CsrResult CsrMutexCreate(CsrMutexHandle *mutexHandle); - /*----------------------------------------------------------------------------* * NAME * CsrGlobalMutexUnlock -- cgit v1.2.3 From 7f7a252cd0dc65565f0fd62a8364670dac77e21b Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 25 Oct 2012 16:57:16 -0400 Subject: staging: csr: remove all prototypes of not defined functions these prototypes doesn't have function definitions in any of the c files Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext.h | 82 --------------------------------- 1 file changed, 82 deletions(-) diff --git a/drivers/staging/csr/csr_framework_ext.h b/drivers/staging/csr/csr_framework_ext.h index 3991274d812..50e5f45e52b 100644 --- a/drivers/staging/csr/csr_framework_ext.h +++ b/drivers/staging/csr/csr_framework_ext.h @@ -34,88 +34,6 @@ extern "C" { #define CSR_EVENT_WAIT_INFINITE ((u16) 0xFFFF) -/*----------------------------------------------------------------------------* - * NAME - * CsrEventCreate - * - * DESCRIPTION - * Creates an event and returns a handle to the created event. - * - * RETURNS - * Possible values: - * CSR_RESULT_SUCCESS in case of success - * CSR_FE_RESULT_NO_MORE_EVENTS in case of out of event resources - * CSR_FE_RESULT_INVALID_POINTER in case the eventHandle pointer is invalid - * - *----------------------------------------------------------------------------*/ -CsrResult CsrEventCreate(CsrEventHandle *eventHandle); - -/*----------------------------------------------------------------------------* - * NAME - * CsrEventWait - * - * DESCRIPTION - * Wait fore one or more of the event bits to be set. - * - * RETURNS - * Possible values: - * CSR_RESULT_SUCCESS in case of success - * CSR_FE_RESULT_TIMEOUT in case of timeout - * CSR_FE_RESULT_INVALID_HANDLE in case the eventHandle is invalid - * CSR_FE_RESULT_INVALID_POINTER in case the eventBits pointer is invalid - * - *----------------------------------------------------------------------------*/ -CsrResult CsrEventWait(CsrEventHandle *eventHandle, u16 timeoutInMs, u32 *eventBits); - -/*----------------------------------------------------------------------------* - * NAME - * CsrEventSet - * - * DESCRIPTION - * Set an event. - * - * RETURNS - * Possible values: - * CSR_RESULT_SUCCESS in case of success - * CSR_FE_RESULT_INVALID_HANDLE in case the eventHandle is invalid - * - *----------------------------------------------------------------------------*/ -CsrResult CsrEventSet(CsrEventHandle *eventHandle, u32 eventBits); - -/*----------------------------------------------------------------------------* - * NAME - * CsrEventDestroy - * - * DESCRIPTION - * Destroy the event associated. - * - * RETURNS - * void - * - *----------------------------------------------------------------------------*/ -void CsrEventDestroy(CsrEventHandle *eventHandle); - -/*----------------------------------------------------------------------------* - * NAME - * CsrGlobalMutexUnlock - * - * DESCRIPTION - * Unlock the global mutex. - * - *----------------------------------------------------------------------------*/ -void CsrGlobalMutexUnlock(void); - -/*----------------------------------------------------------------------------* - * NAME - * CsrThreadSleep - * - * DESCRIPTION - * Sleep for a given period. - * - * RETURNS - * void - * - *----------------------------------------------------------------------------*/ void CsrThreadSleep(u16 sleepTimeInMs); #ifdef __cplusplus -- cgit v1.2.3 From ea50aab519738a2cbb890053e255419c0b39e962 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Fri, 26 Oct 2012 07:01:57 -0400 Subject: staging: csr: remove csrPanic and CSR_LOG_ASSERT and CSR_LOG_ASSERT_ENABLE these are not called at anypoint or enabled at anyplace in the code, remove them Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/Makefile | 3 +- drivers/staging/csr/csr_framework_ext.c | 1 - drivers/staging/csr/csr_log.h | 13 -------- drivers/staging/csr/csr_msgconv.c | 1 - drivers/staging/csr/csr_panic.c | 20 ------------ drivers/staging/csr/csr_panic.h | 53 -------------------------------- drivers/staging/csr/csr_wifi_fsm_types.h | 1 - 7 files changed, 1 insertion(+), 91 deletions(-) delete mode 100644 drivers/staging/csr/csr_panic.c delete mode 100644 drivers/staging/csr/csr_panic.h diff --git a/drivers/staging/csr/Makefile b/drivers/staging/csr/Makefile index ab626edc5ba..dbd135a8b17 100644 --- a/drivers/staging/csr/Makefile +++ b/drivers/staging/csr/Makefile @@ -70,5 +70,4 @@ csr_helper-y := csr_time.o \ csr_framework_ext.o \ csr_wifi_serialize_primitive_types.o \ csr_serialize_primitive_types.o \ - csr_msgconv.o \ - csr_panic.o + csr_msgconv.o diff --git a/drivers/staging/csr/csr_framework_ext.c b/drivers/staging/csr/csr_framework_ext.c index 5b2bc4bdeff..2aabb6c6b0a 100644 --- a/drivers/staging/csr/csr_framework_ext.c +++ b/drivers/staging/csr/csr_framework_ext.c @@ -17,7 +17,6 @@ #include #include "csr_framework_ext.h" -#include "csr_panic.h" /*----------------------------------------------------------------------------* * NAME diff --git a/drivers/staging/csr/csr_log.h b/drivers/staging/csr/csr_log.h index 304f065d5b4..9eb8c098845 100644 --- a/drivers/staging/csr/csr_log.h +++ b/drivers/staging/csr/csr_log.h @@ -11,7 +11,6 @@ *****************************************************************************/ #include "csr_sched.h" -#include "csr_panic.h" #include "csr_prim_defs.h" #include "csr_msgconv.h" @@ -80,18 +79,6 @@ u8 CsrLogTaskIsFiltered(CsrSchedQid taskId, CsrLogLevelTask level); #define CSR_LOG_STRINGIFY_REAL(a) (#a) #define CSR_LOG_STRINGIFY(a) CSR_LOG_STRINGIFY_REAL(a) -#ifdef CSR_LOG_ASSERT_ENABLE -#define CSR_LOG_ASSERT(cond) \ - do { \ - if (!(cond)) { \ - char *panic_arg = "[" __FILE__ ":" CSR_LOG_STRINGIFY(__LINE__) "] - " CSR_LOG_STRINGIFY(cond); \ - CsrPanic(CSR_TECH_FW, CSR_PANIC_FW_ASSERTION_FAIL, panic_arg); \ - } \ - } while (0) -#else -#define CSR_LOG_ASSERT(cond) -#endif - typedef struct { u16 primitiveType; const char *primitiveName; diff --git a/drivers/staging/csr/csr_msgconv.c b/drivers/staging/csr/csr_msgconv.c index 0081a255e91..db5e845e60f 100644 --- a/drivers/staging/csr/csr_msgconv.c +++ b/drivers/staging/csr/csr_msgconv.c @@ -11,7 +11,6 @@ #include #include #include -#include "csr_panic.h" #include "csr_sched.h" #include "csr_msgconv.h" #include "csr_macro.h" diff --git a/drivers/staging/csr/csr_panic.c b/drivers/staging/csr/csr_panic.c deleted file mode 100644 index 095f7fa3ae2..00000000000 --- a/drivers/staging/csr/csr_panic.c +++ /dev/null @@ -1,20 +0,0 @@ -/***************************************************************************** - - (c) Cambridge Silicon Radio Limited 2010 - All rights reserved and confidential information of CSR - - Refer to LICENSE.txt included with this source for details - on the license terms. - -*****************************************************************************/ - -#include -#include - -#include "csr_panic.h" - -void CsrPanic(u8 tech, u16 reason, const char *p) -{ - BUG_ON(1); -} -EXPORT_SYMBOL_GPL(CsrPanic); diff --git a/drivers/staging/csr/csr_panic.h b/drivers/staging/csr/csr_panic.h deleted file mode 100644 index 37989fc15bb..00000000000 --- a/drivers/staging/csr/csr_panic.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef CSR_PANIC_H__ -#define CSR_PANIC_H__ -/***************************************************************************** - - (c) Cambridge Silicon Radio Limited 2010 - All rights reserved and confidential information of CSR - - Refer to LICENSE.txt included with this source for details - on the license terms. - -*****************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -/* Synergy techonology ID definitions */ -#define CSR_TECH_FW 0 -#define CSR_TECH_BT 1 -#define CSR_TECH_WIFI 2 -#define CSR_TECH_GPS 3 -#define CSR_TECH_NFC 4 - -/* Panic type ID definitions for technology type CSR_TECH_FW */ -#define CSR_PANIC_FW_UNEXPECTED_VALUE 0 -#define CSR_PANIC_FW_HEAP_EXHAUSTION 1 -#define CSR_PANIC_FW_INVALID_PFREE_POINTER 2 -#define CSR_PANIC_FW_EXCEPTION 3 -#define CSR_PANIC_FW_ASSERTION_FAIL 4 -#define CSR_PANIC_FW_NULL_TASK_HANDLER 5 -#define CSR_PANIC_FW_UNKNOWN_TASK 6 -#define CSR_PANIC_FW_QUEUE_ACCESS_VIOLATION 7 -#define CSR_PANIC_FW_TOO_MANY_MESSAGES 8 -#define CSR_PANIC_FW_TOO_MANY_TIMED_EVENTS 9 -#define CSR_PANIC_FW_ABCSP_SYNC_LOST 10 -#define CSR_PANIC_FW_OVERSIZE_ABCSP_PRIM 11 -#define CSR_PANIC_FW_H4_CORRUPTION 12 -#define CSR_PANIC_FW_H4_SYNC_LOST 13 -#define CSR_PANIC_FW_H4_RX_OVERRUN 14 -#define CSR_PANIC_FW_H4_TX_OVERRUN 15 -#define CSR_PANIC_FW_TM_BC_RESTART_FAIL 16 -#define CSR_PANIC_FW_TM_BC_START_FAIL 17 -#define CSR_PANIC_FW_TM_BC_BAD_STATE 18 -#define CSR_PANIC_FW_TM_BC_TRANSPORT_LOST 19 - -/* Panic interface used by technologies */ -/* DEPRECATED - replaced by csr_log_text.h */ -void CsrPanic(u8 tech, u16 reason, const char *p); - -#ifdef __cplusplus -} -#endif - -#endif /* CSR_PANIC_H__ */ diff --git a/drivers/staging/csr/csr_wifi_fsm_types.h b/drivers/staging/csr/csr_wifi_fsm_types.h index 26752bf316e..90ef77e0783 100644 --- a/drivers/staging/csr/csr_wifi_fsm_types.h +++ b/drivers/staging/csr/csr_wifi_fsm_types.h @@ -17,7 +17,6 @@ extern "C" { #include #include "csr_macro.h" -#include "csr_panic.h" #include "csr_sched.h" #ifdef CSR_WIFI_FSM_MUTEX_ENABLE -- cgit v1.2.3 From 37a836b1fd03c2bae6779b226ec5aef8bc37c146 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Fri, 26 Oct 2012 09:21:45 +0900 Subject: staging/comedi: Use pr_ or dev_ printks in drivers/gsc_hpdi.c fixed below checkpatch warning. - WARNING: Prefer netdev_warn(netdev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ... some of them have been replaced by dev_dbg. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 17aec51343b..48092958d73 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -479,7 +479,7 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) int i; int retval; - printk(KERN_WARNING "comedi%d: gsc_hpdi\n", dev->minor); + dev_dbg(dev->class_dev, "gsc_hpdi\n"); devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) @@ -510,17 +510,17 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) } while (pcidev != NULL); } if (dev->board_ptr == NULL) { - printk(KERN_WARNING "gsc_hpdi: no hpdi card found\n"); + dev_warn(dev->class_dev, "no hpdi card found\n"); return -EIO; } - printk(KERN_WARNING - "gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name, - pcidev->bus->number, PCI_SLOT(pcidev->devfn)); + dev_warn(dev->class_dev, + "found %s on bus %i, slot %i\n", board(dev)->name, + pcidev->bus->number, PCI_SLOT(pcidev->devfn)); if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { - printk(KERN_WARNING - " failed enable PCI device and request regions\n"); + dev_warn(dev->class_dev, + "failed enable PCI device and request regions\n"); return -EIO; } pci_set_master(pcidev); @@ -541,7 +541,7 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) ioremap(devpriv->hpdi_phys_iobase, pci_resource_len(pcidev, HPDI_BADDRINDEX)); if (!devpriv->plx9080_iobase || !devpriv->hpdi_iobase) { - printk(KERN_WARNING " failed to remap io memory\n"); + dev_warn(dev->class_dev, "failed to remap io memory\n"); return -ENOMEM; } @@ -553,13 +553,13 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* get irq */ if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, dev->driver->driver_name, dev)) { - printk(KERN_WARNING - " unable to allocate irq %u\n", pcidev->irq); + dev_warn(dev->class_dev, + "unable to allocate irq %u\n", pcidev->irq); return -EINVAL; } dev->irq = pcidev->irq; - printk(KERN_WARNING " irq %u\n", dev->irq); + dev_dbg(dev->class_dev, " irq %u\n", dev->irq); /* allocate pci dma buffers */ for (i = 0; i < NUM_DMA_BUFFERS; i++) { @@ -577,8 +577,8 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) &devpriv-> dma_desc_phys_addr); if (devpriv->dma_desc_phys_addr & 0xf) { - printk(KERN_WARNING - " dma descriptors not quad-word aligned (bug)\n"); + dev_warn(dev->class_dev, + " dma descriptors not quad-word aligned (bug)\n"); return -EIO; } -- cgit v1.2.3 From c665814d750a5f5a378e0adfd5bedcf08cb177c3 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 26 Oct 2012 22:36:45 +0800 Subject: staging: ced1401: usb1401: remove unused including Remove including that don't need it. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ced1401/usb1401.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/ced1401/usb1401.c b/drivers/staging/ced1401/usb1401.c index 88e2cc0e2a2..53c9867ea79 100644 --- a/drivers/staging/ced1401/usb1401.c +++ b/drivers/staging/ced1401/usb1401.c @@ -89,7 +89,6 @@ synchronous non-Urb based transfers. #include #include #include -#include #include #include #include -- cgit v1.2.3 From 3d568028ba910ab03b3186d0b8331acd8f0ec15e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 26 Oct 2012 23:23:00 +0800 Subject: staging: comedi: use module_comedi_driver to simplify the code Use the module_comedi_driver() macro to make the code simpler by eliminating module_init and module_exit calls. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das800.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 1ba26b46fd9..85ab24c4556 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -342,22 +342,7 @@ static int das800_probe(struct comedi_device *dev) return -1; } -/* - * A convenient macro that defines init_module() and cleanup_module(), - * as necessary. - */ -static int __init driver_das800_init_module(void) -{ - return comedi_driver_register(&driver_das800); -} - -static void __exit driver_das800_cleanup_module(void) -{ - comedi_driver_unregister(&driver_das800); -} - -module_init(driver_das800_init_module); -module_exit(driver_das800_cleanup_module); +module_comedi_driver(driver_das800); /* interrupt service routine */ static irqreturn_t das800_interrupt(int irq, void *d) -- cgit v1.2.3 From ea8690997095a8ba8d9dc22ae7fe75e64f047e38 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 26 Oct 2012 23:24:46 +0800 Subject: staging: comedi: skel: use module_comedi_driver to simplify the code Use the module_comedi_driver() macro to make the code simpler by eliminating module_init and module_exit calls. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index f292d798f31..e1b78a11196 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -628,18 +628,7 @@ static void __exit driver_skel_cleanup_module(void) module_init(driver_skel_init_module); module_exit(driver_skel_cleanup_module); #else -static int __init driver_skel_init_module(void) -{ - return comedi_driver_register(&driver_skel); -} - -static void __exit driver_skel_cleanup_module(void) -{ - comedi_driver_unregister(&driver_skel); -} - -module_init(driver_skel_init_module); -module_exit(driver_skel_cleanup_module); +module_comedi_driver(driver_skel); #endif MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v1.2.3 From 0473c02a8b560e7a59af4a2d5132ef0ade0f6a33 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 17:24:23 -0700 Subject: staging: comedi: dt3000: remove this_board macro This macro relies on a local variable having a specific name. Remove it and use the comedi_board() helper to get the pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 29e6f8ea67e..7eda7ddc948 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -159,8 +159,6 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = { }, }; -#define this_board ((const struct dt3k_boardtype *)dev->board_ptr) - #define DT3000_SIZE (4*0x1000) /* dual-ported RAM location definitions */ @@ -410,6 +408,7 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev, static int dt3k_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct dt3k_boardtype *this_board = comedi_board(dev); int err = 0; int tmp; @@ -796,6 +795,7 @@ static struct pci_dev *dt3000_find_pci_dev(struct comedi_device *dev, static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct dt3k_boardtype *this_board; struct dt3k_private *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; @@ -813,6 +813,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!pcidev) return -EIO; comedi_set_hw_dev(dev, &pcidev->dev); + this_board = comedi_board(dev); ret = comedi_pci_enable(pcidev, "dt3000"); if (ret < 0) -- cgit v1.2.3 From fbbeddfa91df61df53aa6fd33f4f290e6d199a87 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 17:24:39 -0700 Subject: staging: comedi: dt3000: convert driver to attach_pci Convert this driver to use the comedi PCI auto config mechanism by adding an attach_pci callback. Since this driver requires no extra configuration options, and the attach callback is now optional, remove it. Remove the kernel noise that is output when the attach fails for various reasons. Use the found 'dev->board_name' for the resource name passed to comedi_pci_enable() and request_irq(). Pass on the error returned from request_irq() instead of returning -EINVAL on error. Since this driver no longer walks the pci bus to find the pci_dev, remove the pci_dev_put() in the detach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 68 ++++++++++----------------------- 1 file changed, 21 insertions(+), 47 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 7eda7ddc948..0e84bf4dafe 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -29,11 +29,7 @@ Devices: [Data Translation] DT3001 (dt3000), DT3001-PGL, DT3002, DT3003, Updated: Mon, 14 Apr 2008 15:41:24 +0100 Status: works -Configuration Options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - If bus/slot is not specified, the first supported - PCI device found will be used. +Configuration Options: not applicable, uses PCI auto config There is code to support AI commands, but it may not work. @@ -764,58 +760,41 @@ static int dt3k_mem_insn_read(struct comedi_device *dev, return i; } -static struct pci_dev *dt3000_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *dt3000_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; + const struct dt3k_boardtype *this_board; int i; - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_DT) - continue; - for (i = 0; i < ARRAY_SIZE(dt3k_boardtypes); i++) { - if (dt3k_boardtypes[i].device_id != pcidev->device) - continue; - dev->board_ptr = dt3k_boardtypes + i; - return pcidev; - } + for (i = 0; i < ARRAY_SIZE(dt3k_boardtypes); i++) { + this_board = &dt3k_boardtypes[i]; + if (this_board->device_id == pcidev->device) + return this_board; } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); return NULL; } -static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int dt3000_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct dt3k_boardtype *this_board; struct dt3k_private *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; resource_size_t pci_base; int ret = 0; - dev_dbg(dev->class_dev, "dt3000:\n"); + this_board = dt3000_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->name; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; dev->private = devpriv; - pcidev = dt3000_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - this_board = comedi_board(dev); - - ret = comedi_pci_enable(pcidev, "dt3000"); + ret = comedi_pci_enable(pcidev, dev->board_name); if (ret < 0) return ret; dev->iobase = 1; /* the "detach" needs this */ @@ -825,14 +804,10 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!devpriv->io_addr) return -ENOMEM; - dev->board_name = this_board->name; - - if (request_irq(pcidev->irq, dt3k_interrupt, IRQF_SHARED, - "dt3000", dev)) { - dev_err(dev->class_dev, "unable to allocate IRQ %u\n", - pcidev->irq); - return -EINVAL; - } + ret = request_irq(pcidev->irq, dt3k_interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret) + return ret; dev->irq = pcidev->irq; ret = comedi_alloc_subdevices(dev, 4); @@ -909,14 +884,13 @@ static void dt3000_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver dt3000_driver = { .driver_name = "dt3000", .module = THIS_MODULE, - .attach = dt3000_attach, + .attach_pci = dt3000_attach_pci, .detach = dt3000_detach, }; -- cgit v1.2.3 From 834df4b520353d09203825c28ebdfd72fa929993 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 17:24:53 -0700 Subject: staging: comedi: dt3000: cleanup the range tables Use the BIP_RANGE() macro instead of the more generic RANGE() macro. Cleanup the whitespace. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 0e84bf4dafe..5fcfd06e6ae 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -61,20 +61,22 @@ AO commands are not supported. #include "comedi_fc.h" -static const struct comedi_lrange range_dt3000_ai = { 4, { - RANGE(-10, 10), - RANGE(-5, 5), - RANGE(-2.5, 2.5), - RANGE(-1.25, 1.25) - } +static const struct comedi_lrange range_dt3000_ai = { + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25) + } }; -static const struct comedi_lrange range_dt3000_ai_pgl = { 4, { - RANGE(-10, 10), - RANGE(-1, 1), - RANGE(-0.1, 0.1), - RANGE(-0.02, 0.02) - } +static const struct comedi_lrange range_dt3000_ai_pgl = { + 4, { + BIP_RANGE(10), + BIP_RANGE(1), + BIP_RANGE(0.1), + BIP_RANGE(0.02) + } }; struct dt3k_boardtype { -- cgit v1.2.3 From af4c0fa01e5021563663bde3e9636795d0f9c7c1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 17:25:09 -0700 Subject: staging: comedi: dt3000: add defines for the PCI device ids The PCI device ids supported by this driver are used multiple places in the code. To improve maintainability, create #define's for them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 39 +++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 5fcfd06e6ae..407c8ee0a75 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -61,6 +61,17 @@ AO commands are not supported. #include "comedi_fc.h" +/* + * PCI device id's supported by this driver + */ +#define PCI_DEVICE_ID_DT3001 0x0022 +#define PCI_DEVICE_ID_DT3002 0x0023 +#define PCI_DEVICE_ID_DT3003 0x0024 +#define PCI_DEVICE_ID_DT3004 0x0025 +#define PCI_DEVICE_ID_DT3005 0x0026 +#define PCI_DEVICE_ID_DT3001_PGL 0x0027 +#define PCI_DEVICE_ID_DT3003_PGL 0x0028 + static const struct comedi_lrange range_dt3000_ai = { 4, { BIP_RANGE(10), @@ -93,7 +104,7 @@ struct dt3k_boardtype { static const struct dt3k_boardtype dt3k_boardtypes[] = { {.name = "dt3001", - .device_id = 0x22, + .device_id = PCI_DEVICE_ID_DT3001, .adchan = 16, .adbits = 12, .adrange = &range_dt3000_ai, @@ -102,7 +113,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = { .dabits = 12, }, {.name = "dt3001-pgl", - .device_id = 0x27, + .device_id = PCI_DEVICE_ID_DT3001_PGL, .adchan = 16, .adbits = 12, .adrange = &range_dt3000_ai_pgl, @@ -111,7 +122,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = { .dabits = 12, }, {.name = "dt3002", - .device_id = 0x23, + .device_id = PCI_DEVICE_ID_DT3002, .adchan = 32, .adbits = 12, .adrange = &range_dt3000_ai, @@ -120,7 +131,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = { .dabits = 0, }, {.name = "dt3003", - .device_id = 0x24, + .device_id = PCI_DEVICE_ID_DT3003, .adchan = 64, .adbits = 12, .adrange = &range_dt3000_ai, @@ -129,7 +140,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = { .dabits = 12, }, {.name = "dt3003-pgl", - .device_id = 0x28, + .device_id = PCI_DEVICE_ID_DT3003_PGL, .adchan = 64, .adbits = 12, .adrange = &range_dt3000_ai_pgl, @@ -138,7 +149,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = { .dabits = 12, }, {.name = "dt3004", - .device_id = 0x25, + .device_id = PCI_DEVICE_ID_DT3004, .adchan = 16, .adbits = 16, .adrange = &range_dt3000_ai, @@ -147,7 +158,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = { .dabits = 12, }, {.name = "dt3005", /* a.k.a. 3004-200 */ - .device_id = 0x26, + .device_id = PCI_DEVICE_ID_DT3005, .adchan = 16, .adbits = 16, .adrange = &range_dt3000_ai, @@ -908,13 +919,13 @@ static void __devexit dt3000_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(dt3000_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0022) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0027) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0023) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0024) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0028) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0025) }, - { PCI_DEVICE(PCI_VENDOR_ID_DT, 0x0026) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3001) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3001_PGL) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3002) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3003) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3003_PGL) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3004) }, + { PCI_DEVICE(PCI_VENDOR_ID_DT, PCI_DEVICE_ID_DT3005) }, { 0 } }; MODULE_DEVICE_TABLE(pci, dt3000_pci_table); -- cgit v1.2.3 From da0c1012b3aba653338518a9c6ff2eedb614c446 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 17:25:23 -0700 Subject: staging: comedi: dt3000: remove forward declarations Move some of the functions to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 184 +++++++++++++++----------------- 1 file changed, 87 insertions(+), 97 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 407c8ee0a75..2883239e9c8 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -262,14 +262,22 @@ struct dt3k_private { unsigned int ai_rear; }; -static void dt3k_ai_empty_fifo(struct comedi_device *dev, - struct comedi_subdevice *s); -static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *arg, - unsigned int round_mode); -static int dt3k_ai_cancel(struct comedi_device *dev, - struct comedi_subdevice *s); #ifdef DEBUG -static void debug_intr_flags(unsigned int flags); +static char *intr_flags[] = { + "AdFull", "AdSwError", "AdHwError", "DaEmpty", + "DaSwError", "DaHwError", "CtDone", "CmDone", +}; + +static void debug_intr_flags(unsigned int flags) +{ + int i; + printk(KERN_DEBUG "dt3k: intr_flags:"); + for (i = 0; i < 8; i++) { + if (flags & (1 << i)) + printk(KERN_CONT " %s", intr_flags[i]); + } + printk(KERN_CONT "\n"); +} #endif #define TIMEOUT 100 @@ -327,6 +335,50 @@ static void dt3k_writesingle(struct comedi_device *dev, unsigned int subsys, dt3k_send_cmd(dev, CMD_WRITESINGLE); } +static void dt3k_ai_empty_fifo(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct dt3k_private *devpriv = dev->private; + int front; + int rear; + int count; + int i; + short data; + + front = readw(devpriv->io_addr + DPR_AD_Buf_Front); + count = front - devpriv->ai_front; + if (count < 0) + count += AI_FIFO_DEPTH; + + dev_dbg(dev->class_dev, "reading %d samples\n", count); + + rear = devpriv->ai_rear; + + for (i = 0; i < count; i++) { + data = readw(devpriv->io_addr + DPR_ADC_buffer + rear); + comedi_buf_put(s->async, data); + rear++; + if (rear >= AI_FIFO_DEPTH) + rear = 0; + } + + devpriv->ai_rear = rear; + writew(rear, devpriv->io_addr + DPR_AD_Buf_Rear); +} + +static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) +{ + struct dt3k_private *devpriv = dev->private; + int ret; + + writew(SUBS_AI, devpriv->io_addr + DPR_SubSys); + ret = dt3k_send_cmd(dev, CMD_STOP); + + writew(0, devpriv->io_addr + DPR_Int_Mask); + + return 0; +} + static int debug_n_ints; /* FIXME! Assumes shared interrupt is for this card. */ @@ -365,53 +417,39 @@ static irqreturn_t dt3k_interrupt(int irq, void *d) return IRQ_HANDLED; } -#ifdef DEBUG -static char *intr_flags[] = { - "AdFull", "AdSwError", "AdHwError", "DaEmpty", - "DaSwError", "DaHwError", "CtDone", "CmDone", -}; - -static void debug_intr_flags(unsigned int flags) -{ - int i; - printk(KERN_DEBUG "dt3k: intr_flags:"); - for (i = 0; i < 8; i++) { - if (flags & (1 << i)) - printk(KERN_CONT " %s", intr_flags[i]); - } - printk(KERN_CONT "\n"); -} -#endif - -static void dt3k_ai_empty_fifo(struct comedi_device *dev, - struct comedi_subdevice *s) +static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec, + unsigned int round_mode) { - struct dt3k_private *devpriv = dev->private; - int front; - int rear; - int count; - int i; - short data; - - front = readw(devpriv->io_addr + DPR_AD_Buf_Front); - count = front - devpriv->ai_front; - if (count < 0) - count += AI_FIFO_DEPTH; - - dev_dbg(dev->class_dev, "reading %d samples\n", count); + int divider, base, prescale; - rear = devpriv->ai_rear; + /* This function needs improvment */ + /* Don't know if divider==0 works. */ - for (i = 0; i < count; i++) { - data = readw(devpriv->io_addr + DPR_ADC_buffer + rear); - comedi_buf_put(s->async, data); - rear++; - if (rear >= AI_FIFO_DEPTH) - rear = 0; + for (prescale = 0; prescale < 16; prescale++) { + base = timer_base * (prescale + 1); + switch (round_mode) { + case TRIG_ROUND_NEAREST: + default: + divider = (*nanosec + base / 2) / base; + break; + case TRIG_ROUND_DOWN: + divider = (*nanosec) / base; + break; + case TRIG_ROUND_UP: + divider = (*nanosec) / base; + break; + } + if (divider < 65536) { + *nanosec = divider * base; + return (prescale << 16) | (divider); + } } - devpriv->ai_rear = rear; - writew(rear, devpriv->io_addr + DPR_AD_Buf_Rear); + prescale = 15; + base = timer_base * (1 << prescale); + divider = 65535; + *nanosec = divider * base; + return (prescale << 16) | (divider); } static int dt3k_ai_cmdtest(struct comedi_device *dev, @@ -524,41 +562,6 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, return 0; } -static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec, - unsigned int round_mode) -{ - int divider, base, prescale; - - /* This function needs improvment */ - /* Don't know if divider==0 works. */ - - for (prescale = 0; prescale < 16; prescale++) { - base = timer_base * (prescale + 1); - switch (round_mode) { - case TRIG_ROUND_NEAREST: - default: - divider = (*nanosec + base / 2) / base; - break; - case TRIG_ROUND_DOWN: - divider = (*nanosec) / base; - break; - case TRIG_ROUND_UP: - divider = (*nanosec) / base; - break; - } - if (divider < 65536) { - *nanosec = divider * base; - return (prescale << 16) | (divider); - } - } - - prescale = 15; - base = timer_base * (1 << prescale); - divider = 65535; - *nanosec = divider * base; - return (prescale << 16) | (divider); -} - static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { struct dt3k_private *devpriv = dev->private; @@ -628,19 +631,6 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) -{ - struct dt3k_private *devpriv = dev->private; - int ret; - - writew(SUBS_AI, devpriv->io_addr + DPR_SubSys); - ret = dt3k_send_cmd(dev, CMD_STOP); - - writew(0, devpriv->io_addr + DPR_Int_Mask); - - return 0; -} - static int dt3k_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { -- cgit v1.2.3 From ad25f545e451f20fc798d69bba60c8fb5558810e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 17:25:38 -0700 Subject: staging: comedi: dt3000: remove '0' entries in boardinfo These entries will default to '0'. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 2883239e9c8..48d303298a2 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -127,8 +127,6 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = { .adbits = 12, .adrange = &range_dt3000_ai, .ai_speed = 3000, - .dachan = 0, - .dabits = 0, }, {.name = "dt3003", .device_id = PCI_DEVICE_ID_DT3003, -- cgit v1.2.3 From ecab2effbf4b692e2b4e21a3ec46bac6bbaf5734 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 17:25:53 -0700 Subject: staging: comedi: dt3000: cleanup the boardinfo Add some whitespace to make the code more readable. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 124 ++++++++++++++++---------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 48d303298a2..be65a1ccfc9 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -91,7 +91,6 @@ static const struct comedi_lrange range_dt3000_ai_pgl = { }; struct dt3k_boardtype { - const char *name; unsigned int device_id; int adchan; @@ -103,67 +102,68 @@ struct dt3k_boardtype { }; static const struct dt3k_boardtype dt3k_boardtypes[] = { - {.name = "dt3001", - .device_id = PCI_DEVICE_ID_DT3001, - .adchan = 16, - .adbits = 12, - .adrange = &range_dt3000_ai, - .ai_speed = 3000, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt3001-pgl", - .device_id = PCI_DEVICE_ID_DT3001_PGL, - .adchan = 16, - .adbits = 12, - .adrange = &range_dt3000_ai_pgl, - .ai_speed = 3000, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt3002", - .device_id = PCI_DEVICE_ID_DT3002, - .adchan = 32, - .adbits = 12, - .adrange = &range_dt3000_ai, - .ai_speed = 3000, - }, - {.name = "dt3003", - .device_id = PCI_DEVICE_ID_DT3003, - .adchan = 64, - .adbits = 12, - .adrange = &range_dt3000_ai, - .ai_speed = 3000, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt3003-pgl", - .device_id = PCI_DEVICE_ID_DT3003_PGL, - .adchan = 64, - .adbits = 12, - .adrange = &range_dt3000_ai_pgl, - .ai_speed = 3000, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt3004", - .device_id = PCI_DEVICE_ID_DT3004, - .adchan = 16, - .adbits = 16, - .adrange = &range_dt3000_ai, - .ai_speed = 10000, - .dachan = 2, - .dabits = 12, - }, - {.name = "dt3005", /* a.k.a. 3004-200 */ - .device_id = PCI_DEVICE_ID_DT3005, - .adchan = 16, - .adbits = 16, - .adrange = &range_dt3000_ai, - .ai_speed = 5000, - .dachan = 2, - .dabits = 12, - }, + { + .name = "dt3001", + .device_id = PCI_DEVICE_ID_DT3001, + .adchan = 16, + .adbits = 12, + .adrange = &range_dt3000_ai, + .ai_speed = 3000, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt3001-pgl", + .device_id = PCI_DEVICE_ID_DT3001_PGL, + .adchan = 16, + .adbits = 12, + .adrange = &range_dt3000_ai_pgl, + .ai_speed = 3000, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt3002", + .device_id = PCI_DEVICE_ID_DT3002, + .adchan = 32, + .adbits = 12, + .adrange = &range_dt3000_ai, + .ai_speed = 3000, + }, { + .name = "dt3003", + .device_id = PCI_DEVICE_ID_DT3003, + .adchan = 64, + .adbits = 12, + .adrange = &range_dt3000_ai, + .ai_speed = 3000, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt3003-pgl", + .device_id = PCI_DEVICE_ID_DT3003_PGL, + .adchan = 64, + .adbits = 12, + .adrange = &range_dt3000_ai_pgl, + .ai_speed = 3000, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt3004", + .device_id = PCI_DEVICE_ID_DT3004, + .adchan = 16, + .adbits = 16, + .adrange = &range_dt3000_ai, + .ai_speed = 10000, + .dachan = 2, + .dabits = 12, + }, { + .name = "dt3005", /* a.k.a. 3004-200 */ + .device_id = PCI_DEVICE_ID_DT3005, + .adchan = 16, + .adbits = 16, + .adrange = &range_dt3000_ai, + .ai_speed = 5000, + .dachan = 2, + .dabits = 12, + }, }; #define DT3000_SIZE (4*0x1000) -- cgit v1.2.3 From c3ebe8f634829e394b527b2b6eea67af01379a2a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 17:26:10 -0700 Subject: staging: comedi: dt3000: add a simple dev_info() when attached When the board is finished with the attach output a simple dev_info() message. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index be65a1ccfc9..e29049e45b5 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -868,6 +868,8 @@ static int dt3000_attach_pci(struct comedi_device *dev, s->type = COMEDI_SUBD_PROC; #endif + dev_info(dev->class_dev, "%s attached\n", dev->board_name); + return 0; } -- cgit v1.2.3 From 4fbb1c4c4b4a40d2c0bbde7824ec6a4a55300229 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 17:26:25 -0700 Subject: staging: comedi: dt3000: add some whitespace to the subdevice init To improve the readability, add some whitespace to the subdevice init. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 67 ++++++++++++++++----------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index e29049e45b5..347527f6759 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -817,50 +817,49 @@ static int dt3000_attach_pci(struct comedi_device *dev, s = &dev->subdevices[0]; dev->read_subdev = s; - /* ai subdevice */ - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; - s->n_chan = this_board->adchan; - s->insn_read = dt3k_ai_insn; - s->maxdata = (1 << this_board->adbits) - 1; - s->len_chanlist = 512; - s->range_table = &range_dt3000_ai; /* XXX */ - s->do_cmd = dt3k_ai_cmd; - s->do_cmdtest = dt3k_ai_cmdtest; - s->cancel = dt3k_ai_cancel; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; + s->n_chan = this_board->adchan; + s->insn_read = dt3k_ai_insn; + s->maxdata = (1 << this_board->adbits) - 1; + s->len_chanlist = 512; + s->range_table = &range_dt3000_ai; /* XXX */ + s->do_cmd = dt3k_ai_cmd; + s->do_cmdtest = dt3k_ai_cmdtest; + s->cancel = dt3k_ai_cancel; s = &dev->subdevices[1]; /* ao subsystem */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 2; - s->insn_read = dt3k_ao_insn_read; - s->insn_write = dt3k_ao_insn; - s->maxdata = (1 << this_board->dabits) - 1; - s->len_chanlist = 1; - s->range_table = &range_bipolar10; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 2; + s->insn_read = dt3k_ao_insn_read; + s->insn_write = dt3k_ao_insn; + s->maxdata = (1 << this_board->dabits) - 1; + s->len_chanlist = 1; + s->range_table = &range_bipolar10; s = &dev->subdevices[2]; /* dio subsystem */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 8; - s->insn_config = dt3k_dio_insn_config; - s->insn_bits = dt3k_dio_insn_bits; - s->maxdata = 1; - s->len_chanlist = 8; - s->range_table = &range_digital; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 8; + s->insn_config = dt3k_dio_insn_config; + s->insn_bits = dt3k_dio_insn_bits; + s->maxdata = 1; + s->len_chanlist = 8; + s->range_table = &range_digital; s = &dev->subdevices[3]; /* mem subsystem */ - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE; - s->n_chan = 0x1000; - s->insn_read = dt3k_mem_insn_read; - s->maxdata = 0xff; - s->len_chanlist = 1; - s->range_table = &range_unknown; + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE; + s->n_chan = 0x1000; + s->insn_read = dt3k_mem_insn_read; + s->maxdata = 0xff; + s->len_chanlist = 1; + s->range_table = &range_unknown; #if 0 s = &dev->subdevices[4]; -- cgit v1.2.3 From f26d8b70b4ac22646388b7c58ec3d9f97d4e0f9f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 17:26:40 -0700 Subject: staging: comedi: dt3000: remove dev_dbg() noise Remove most of the dev_dbg() output from this driver. Most of it is just noise. For now I have left the dev_dbg() in the dt3k_send_cmd() function. I still have not quite figured out how the low-level i/o works in this driver... Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 347527f6759..dba54844372 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -348,8 +348,6 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev, if (count < 0) count += AI_FIFO_DEPTH; - dev_dbg(dev->class_dev, "reading %d samples\n", count); - rear = devpriv->ai_rear; for (i = 0; i < count; i++) { @@ -571,7 +569,6 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) int ret; unsigned int mode; - dev_dbg(dev->class_dev, "dt3k_ai_cmd:\n"); for (i = 0; i < cmd->chanlist_len; i++) { chan = CR_CHAN(cmd->chanlist[i]); range = CR_RANGE(cmd->chanlist[i]); @@ -582,15 +579,12 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) aref = CR_AREF(cmd->chanlist[0]); writew(cmd->scan_end_arg, devpriv->io_addr + DPR_Params(0)); - dev_dbg(dev->class_dev, "param[0]=0x%04x\n", cmd->scan_end_arg); if (cmd->convert_src == TRIG_TIMER) { divider = dt3k_ns_to_timer(50, &cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK); writew((divider >> 16), devpriv->io_addr + DPR_Params(1)); - dev_dbg(dev->class_dev, "param[1]=0x%04x\n", divider >> 16); writew((divider & 0xffff), devpriv->io_addr + DPR_Params(2)); - dev_dbg(dev->class_dev, "param[2]=0x%04x\n", divider & 0xffff); } else { /* not supported */ } @@ -599,21 +593,16 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK); writew((tscandiv >> 16), devpriv->io_addr + DPR_Params(3)); - dev_dbg(dev->class_dev, "param[3]=0x%04x\n", tscandiv >> 16); writew((tscandiv & 0xffff), devpriv->io_addr + DPR_Params(4)); - dev_dbg(dev->class_dev, "param[4]=0x%04x\n", tscandiv & 0xffff); } else { /* not supported */ } mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0; writew(mode, devpriv->io_addr + DPR_Params(5)); - dev_dbg(dev->class_dev, "param[5]=0x%04x\n", mode); writew(aref == AREF_DIFF, devpriv->io_addr + DPR_Params(6)); - dev_dbg(dev->class_dev, "param[6]=0x%04x\n", aref == AREF_DIFF); writew(AI_FIFO_DEPTH / 2, devpriv->io_addr + DPR_Params(7)); - dev_dbg(dev->class_dev, "param[7]=0x%04x\n", AI_FIFO_DEPTH / 2); writew(SUBS_AI, devpriv->io_addr + DPR_SubSys); ret = dt3k_send_cmd(dev, CMD_CONFIG); -- cgit v1.2.3 From d3bf2177c85f15a10c715cb0225311992503e8eb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 17:26:54 -0700 Subject: staging: comedi: dt3000: remove empty 'else' code There are a number of: } else { /* not supported */ } cases in this driver. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index dba54844372..d54b91cba9b 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -488,9 +488,8 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, cmd->scan_begin_arg = 100 * 16 * 65535; err++; } - } else { - /* not supported */ } + if (cmd->convert_src == TRIG_TIMER) { if (cmd->convert_arg < this_board->ai_speed) { cmd->convert_arg = this_board->ai_speed; @@ -500,8 +499,6 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, cmd->convert_arg = 50 * 16 * 65535; err++; } - } else { - /* not supported */ } if (cmd->scan_end_arg != cmd->chanlist_len) { @@ -532,9 +529,8 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, cmd->flags & TRIG_ROUND_MASK); if (tmp != cmd->scan_begin_arg) err++; - } else { - /* not supported */ } + if (cmd->convert_src == TRIG_TIMER) { tmp = cmd->convert_arg; dt3k_ns_to_timer(50, &cmd->convert_arg, @@ -548,8 +544,6 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, cmd->convert_arg * cmd->scan_end_arg; err++; } - } else { - /* not supported */ } if (err) @@ -585,8 +579,6 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) cmd->flags & TRIG_ROUND_MASK); writew((divider >> 16), devpriv->io_addr + DPR_Params(1)); writew((divider & 0xffff), devpriv->io_addr + DPR_Params(2)); - } else { - /* not supported */ } if (cmd->scan_begin_src == TRIG_TIMER) { @@ -594,8 +586,6 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) cmd->flags & TRIG_ROUND_MASK); writew((tscandiv >> 16), devpriv->io_addr + DPR_Params(3)); writew((tscandiv & 0xffff), devpriv->io_addr + DPR_Params(4)); - } else { - /* not supported */ } mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0; -- cgit v1.2.3 From 0014048e091da8bfdbe6f5a15d4045d3747d1335 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 17:27:12 -0700 Subject: staging: comedi: dt3000: change return type of dt3k_send_cmd to void None of the callers check the return value. Just make it a void. Flip the status check at the end of the function to check for an error before outputing the dev_dbg(). Use __func__ for the function name in the message. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index d54b91cba9b..3897960108a 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -280,7 +280,7 @@ static void debug_intr_flags(unsigned int flags) #define TIMEOUT 100 -static int dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd) +static void dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd) { struct dt3k_private *devpriv = dev->private; int i; @@ -294,13 +294,10 @@ static int dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd) break; udelay(1); } - if ((status & DT3000_COMPLETION_MASK) == DT3000_NOERROR) - return 0; - dev_dbg(dev->class_dev, "dt3k_send_cmd() timeout/error status=0x%04x\n", - status); - - return -ETIME; + if ((status & DT3000_COMPLETION_MASK) != DT3000_NOERROR) + dev_dbg(dev->class_dev, "%s: timeout/error status=0x%04x\n", + __func__, status); } static unsigned int dt3k_readsingle(struct comedi_device *dev, @@ -365,10 +362,9 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev, static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { struct dt3k_private *devpriv = dev->private; - int ret; writew(SUBS_AI, devpriv->io_addr + DPR_SubSys); - ret = dt3k_send_cmd(dev, CMD_STOP); + dt3k_send_cmd(dev, CMD_STOP); writew(0, devpriv->io_addr + DPR_Int_Mask); @@ -560,7 +556,6 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) unsigned int chan, range, aref; unsigned int divider; unsigned int tscandiv; - int ret; unsigned int mode; for (i = 0; i < cmd->chanlist_len; i++) { @@ -595,7 +590,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writew(AI_FIFO_DEPTH / 2, devpriv->io_addr + DPR_Params(7)); writew(SUBS_AI, devpriv->io_addr + DPR_SubSys); - ret = dt3k_send_cmd(dev, CMD_CONFIG); + dt3k_send_cmd(dev, CMD_CONFIG); writew(DT3000_ADFULL | DT3000_ADSWERR | DT3000_ADHWERR, devpriv->io_addr + DPR_Int_Mask); @@ -603,7 +598,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) debug_n_ints = 0; writew(SUBS_AI, devpriv->io_addr + DPR_SubSys); - ret = dt3k_send_cmd(dev, CMD_START); + dt3k_send_cmd(dev, CMD_START); return 0; } -- cgit v1.2.3 From 736b605c897204b8c05f15160f12e70c61b2e6e6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:05:46 -0700 Subject: staging: comedi: me_daq: fix pointer dereference in me_detach() As pointed out by Dan Carpenter, dev_private could be NULL when it is checked before calling comedi_pci_disable(). The private data variable 'plx_regbase_size' is only used to see if the pci device has been enabled. Remove that variable from the private data and just use the unused dev->iobase variable to let the detach know that the pci device is enabled. Signed-off-by: H Hartley Sweeten Reported-by: Dan Carpenter Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index ddb3dd79874..cdb97955bbc 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -224,7 +224,6 @@ static const struct me_board me_boards[] = { struct me_private_data { void __iomem *plx_regbase; /* PLX configuration base address */ void __iomem *me_regbase; /* Base address of the Meilhaus card */ - unsigned long plx_regbase_size; /* Size of PLX configuration space */ unsigned long me_regbase_size; /* Size of Meilhaus space */ unsigned short control_1; /* Mirror of CONTROL_1 register */ @@ -639,7 +638,6 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) struct me_private_data *dev_private; struct comedi_subdevice *s; resource_size_t plx_regbase_tmp; - unsigned long plx_regbase_size_tmp; resource_size_t me_regbase_tmp; unsigned long me_regbase_size_tmp; resource_size_t swap_regbase_tmp; @@ -664,13 +662,12 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) "Failed to enable PCI device and request regions\n"); return -EIO; } + dev->iobase = 1; /* detach needs this */ /* Read PLX register base address [PCI_BASE_ADDRESS #0]. */ plx_regbase_tmp = pci_resource_start(pcidev, 0); - plx_regbase_size_tmp = pci_resource_len(pcidev, 0); - dev_private->plx_regbase = - ioremap(plx_regbase_tmp, plx_regbase_size_tmp); - dev_private->plx_regbase_size = plx_regbase_size_tmp; + dev_private->plx_regbase = ioremap(plx_regbase_tmp, + pci_resource_len(pcidev, 0)); if (!dev_private->plx_regbase) { dev_err(dev->class_dev, "Failed to remap I/O memory\n"); return -ENOMEM; @@ -791,7 +788,7 @@ static void me_detach(struct comedi_device *dev) iounmap(dev_private->plx_regbase); } if (pcidev) { - if (dev_private->plx_regbase_size) + if (dev->iobase) comedi_pci_disable(pcidev); pci_dev_put(pcidev); } -- cgit v1.2.3 From 52c4cbe94c3ce0a643ad57f68cafae88249c03a1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:06:02 -0700 Subject: staging: comedi: me_daq: cleanup ioremap of PCI bar 2 PCI bar 2 is the main i/o address for this driver. Currently the pci_resource_len of the bar is stored in the private data but it is never used. Remove 'me_regbase_size' from the private data. Also, remove the local variables used for the pci_resource_start and _len. Just pass the values directly to the ioremap(). Remove the kernel noise when the ioremap fails. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index cdb97955bbc..0bfef54b351 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -224,7 +224,6 @@ static const struct me_board me_boards[] = { struct me_private_data { void __iomem *plx_regbase; /* PLX configuration base address */ void __iomem *me_regbase; /* Base address of the Meilhaus card */ - unsigned long me_regbase_size; /* Size of Meilhaus space */ unsigned short control_1; /* Mirror of CONTROL_1 register */ unsigned short control_2; /* Mirror of CONTROL_2 register */ @@ -638,8 +637,6 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) struct me_private_data *dev_private; struct comedi_subdevice *s; resource_size_t plx_regbase_tmp; - resource_size_t me_regbase_tmp; - unsigned long me_regbase_size_tmp; resource_size_t swap_regbase_tmp; unsigned long swap_regbase_size_tmp; resource_size_t regbase_tmp; @@ -712,16 +709,10 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) } /*--------------------------------------------- Workaround end -----*/ - /* Read Meilhaus register base address [PCI_BASE_ADDRESS #2]. */ - - me_regbase_tmp = pci_resource_start(pcidev, 2); - me_regbase_size_tmp = pci_resource_len(pcidev, 2); - dev_private->me_regbase_size = me_regbase_size_tmp; - dev_private->me_regbase = ioremap(me_regbase_tmp, me_regbase_size_tmp); - if (!dev_private->me_regbase) { - dev_err(dev->class_dev, "Failed to remap I/O memory\n"); + dev_private->me_regbase = ioremap(pci_resource_start(pcidev, 2), + pci_resource_len(pcidev, 2)); + if (!dev_private->me_regbase) return -ENOMEM; - } /* Download firmware and reset card */ if (board->device_id == ME2600_DEVICE_ID) { -- cgit v1.2.3 From 4bb153b4e4f9e11ac7e9b58d3957dba9a3c3fd2e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:06:20 -0700 Subject: staging: comedi: me_daq: replace 'result' and 'error' with 'ret' Two local variables are used in me_attach_pci() to check for errors when calling other functions, 'result' and 'error'. Remove both of them and just use a common 'ret' variable. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 0bfef54b351..aedc5092808 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -640,7 +640,7 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) resource_size_t swap_regbase_tmp; unsigned long swap_regbase_size_tmp; resource_size_t regbase_tmp; - int result, error; + int ret; board = me_find_boardinfo(dev, pcidev); if (!board) @@ -687,23 +687,23 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) plx_regbase_tmp = swap_regbase_tmp; swap_regbase_tmp = regbase_tmp; - result = pci_write_config_dword(pcidev, + ret = pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_0, plx_regbase_tmp); - if (result != PCIBIOS_SUCCESSFUL) + if (ret != PCIBIOS_SUCCESSFUL) return -EIO; - result = pci_write_config_dword(pcidev, + ret = pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_5, swap_regbase_tmp); - if (result != PCIBIOS_SUCCESSFUL) + if (ret != PCIBIOS_SUCCESSFUL) return -EIO; } else { plx_regbase_tmp -= 0x80; - result = pci_write_config_dword(pcidev, + ret = pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_0, plx_regbase_tmp); - if (result != PCIBIOS_SUCCESSFUL) + if (ret != PCIBIOS_SUCCESSFUL) return -EIO; } } @@ -716,15 +716,15 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) /* Download firmware and reset card */ if (board->device_id == ME2600_DEVICE_ID) { - result = me2600_upload_firmware(dev); - if (result < 0) - return result; + ret = me2600_upload_firmware(dev); + if (ret < 0) + return ret; } me_reset(dev); - error = comedi_alloc_subdevices(dev, 3); - if (error) - return error; + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; -- cgit v1.2.3 From 4ae76422338f25ee4907e92ae3cdc968fdd9b578 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:06:37 -0700 Subject: staging: comedi: me_daq: pass on the error from comedi_pci_enable() Instead of returning -EIO when comedi_pci_enable() fails, pass on the actual error code. Also, remove the kernel noise when the function fails. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index aedc5092808..95fbecc4929 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -653,12 +653,9 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) return -ENOMEM; dev->private = dev_private; - /* Enable PCI device and request PCI regions */ - if (comedi_pci_enable(pcidev, dev->board_name) < 0) { - dev_err(dev->class_dev, - "Failed to enable PCI device and request regions\n"); - return -EIO; - } + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; dev->iobase = 1; /* detach needs this */ /* Read PLX register base address [PCI_BASE_ADDRESS #0]. */ -- cgit v1.2.3 From 10cba302edf32753a653659740e1688094f92c86 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:06:58 -0700 Subject: staging: comedi: me_daq: factor out the PLX bug workaround Factor out the code in me_attach_pci() that handles the PLX-Bug workaround to a separate function. This looks odd. It appears that the bug workaround either swaps PCI bars 0 and 5 or it modifies PCI bar 0. Shouldn't this happen before PCI bar 0 is ioremap'ed? Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 95 ++++++++++++++++----------------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 95fbecc4929..182a184604e 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -617,6 +617,48 @@ static int me_reset(struct comedi_device *dev) return 0; } +static int me_plx_bug_check(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + resource_size_t plx_regbase_tmp = pci_resource_start(pcidev, 0); + resource_size_t swap_regbase_tmp = pci_resource_start(pcidev, 5); + resource_size_t regbase_tmp; + int ret; + + if (!swap_regbase_tmp) + dev_err(dev->class_dev, "Swap not present\n"); + + if (plx_regbase_tmp & 0x0080) { + dev_err(dev->class_dev, "PLX-Bug detected\n"); + + if (swap_regbase_tmp) { + regbase_tmp = plx_regbase_tmp; + plx_regbase_tmp = swap_regbase_tmp; + swap_regbase_tmp = regbase_tmp; + + ret = pci_write_config_dword(pcidev, + PCI_BASE_ADDRESS_0, + plx_regbase_tmp); + if (ret != PCIBIOS_SUCCESSFUL) + return -EIO; + + ret = pci_write_config_dword(pcidev, + PCI_BASE_ADDRESS_5, + swap_regbase_tmp); + if (ret != PCIBIOS_SUCCESSFUL) + return -EIO; + } else { + plx_regbase_tmp -= 0x80; + ret = pci_write_config_dword(pcidev, + PCI_BASE_ADDRESS_0, + plx_regbase_tmp); + if (ret != PCIBIOS_SUCCESSFUL) + return -EIO; + } + } + return 0; +} + static const void *me_find_boardinfo(struct comedi_device *dev, struct pci_dev *pcidev) { @@ -636,10 +678,6 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) const struct me_board *board; struct me_private_data *dev_private; struct comedi_subdevice *s; - resource_size_t plx_regbase_tmp; - resource_size_t swap_regbase_tmp; - unsigned long swap_regbase_size_tmp; - resource_size_t regbase_tmp; int ret; board = me_find_boardinfo(dev, pcidev); @@ -658,53 +696,14 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) return ret; dev->iobase = 1; /* detach needs this */ - /* Read PLX register base address [PCI_BASE_ADDRESS #0]. */ - plx_regbase_tmp = pci_resource_start(pcidev, 0); - dev_private->plx_regbase = ioremap(plx_regbase_tmp, + dev_private->plx_regbase = ioremap(pci_resource_start(pcidev, 0), pci_resource_len(pcidev, 0)); - if (!dev_private->plx_regbase) { - dev_err(dev->class_dev, "Failed to remap I/O memory\n"); + if (!dev_private->plx_regbase) return -ENOMEM; - } - - /* Read Swap base address [PCI_BASE_ADDRESS #5]. */ - - swap_regbase_tmp = pci_resource_start(pcidev, 5); - swap_regbase_size_tmp = pci_resource_len(pcidev, 5); - - if (!swap_regbase_tmp) - dev_err(dev->class_dev, "Swap not present\n"); - - /*---------------------------------------------- Workaround start ---*/ - if (plx_regbase_tmp & 0x0080) { - dev_err(dev->class_dev, "PLX-Bug detected\n"); - - if (swap_regbase_tmp) { - regbase_tmp = plx_regbase_tmp; - plx_regbase_tmp = swap_regbase_tmp; - swap_regbase_tmp = regbase_tmp; - ret = pci_write_config_dword(pcidev, - PCI_BASE_ADDRESS_0, - plx_regbase_tmp); - if (ret != PCIBIOS_SUCCESSFUL) - return -EIO; - - ret = pci_write_config_dword(pcidev, - PCI_BASE_ADDRESS_5, - swap_regbase_tmp); - if (ret != PCIBIOS_SUCCESSFUL) - return -EIO; - } else { - plx_regbase_tmp -= 0x80; - ret = pci_write_config_dword(pcidev, - PCI_BASE_ADDRESS_0, - plx_regbase_tmp); - if (ret != PCIBIOS_SUCCESSFUL) - return -EIO; - } - } - /*--------------------------------------------- Workaround end -----*/ + ret = me_plx_bug_check(dev, pcidev); + if (ret) + return ret; dev_private->me_regbase = ioremap(pci_resource_start(pcidev, 2), pci_resource_len(pcidev, 2)); -- cgit v1.2.3 From 43d51f885a1e0901229ad479b61ed97aa2c103f6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:07:17 -0700 Subject: staging: comedi: me_daq: analog output subdevice could be unused One of the boards supported by this driver does not have analog outputs. Fix the attach code to account for this. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 182a184604e..f5ede1ae113 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -735,14 +735,18 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s->do_cmd = me_ai_do_cmd; s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; - s->n_chan = board->ao_channel_nbr; - s->maxdata = board->ao_resolution_mask; - s->len_chanlist = board->ao_channel_nbr; - s->range_table = board->ao_range_list; - s->insn_read = me_ao_insn_read; - s->insn_write = me_ao_insn_write; + if (board->ao_channel_nbr) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; + s->n_chan = board->ao_channel_nbr; + s->maxdata = board->ao_resolution_mask; + s->len_chanlist = board->ao_channel_nbr; + s->range_table = board->ao_range_list; + s->insn_read = me_ao_insn_read; + s->insn_write = me_ao_insn_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DIO; -- cgit v1.2.3 From f15c0a65dfd400a100ed5b6ae6dbcc6ac0863e02 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:07:36 -0700 Subject: staging: comedi: me_daq: remove '0' and 'NULL' entries in boardinfo These entries will default to '0' or 'NULL' as appropriate. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index f5ede1ae113..7fd94000af9 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -206,11 +206,6 @@ static const struct me_board me_boards[] = { { .name = "me-2000i", .device_id = ME2000_DEVICE_ID, - /* Analog Output */ - .ao_channel_nbr = 0, - .ao_resolution = 0, - .ao_resolution_mask = 0, - .ao_range_list = NULL, .ai_channel_nbr = 16, /* Analog Input */ .ai_resolution = 12, -- cgit v1.2.3 From 78830a75b40aba0163203f80ec88e8f8b1596777 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:07:52 -0700 Subject: staging: comedi: me_daq: remove {ao,ai}_resoultion_mask These values can be determined from the {ao,ai}_resolution. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 7fd94000af9..f14907e4940 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -178,11 +178,9 @@ struct me_board { int device_id; int ao_channel_nbr; /* DA config */ int ao_resolution; - int ao_resolution_mask; const struct comedi_lrange *ao_range_list; int ai_channel_nbr; /* AD config */ int ai_resolution; - int ai_resolution_mask; const struct comedi_lrange *ai_range_list; int dio_channel_nbr; /* DIO config */ }; @@ -194,12 +192,10 @@ static const struct me_board me_boards[] = { /* Analog Output */ .ao_channel_nbr = 4, .ao_resolution = 12, - .ao_resolution_mask = 0x0fff, .ao_range_list = &me2600_ao_range, .ai_channel_nbr = 16, /* Analog Input */ .ai_resolution = 12, - .ai_resolution_mask = 0x0fff, .ai_range_list = &me2600_ai_range, .dio_channel_nbr = 32, }, @@ -209,7 +205,6 @@ static const struct me_board me_boards[] = { .ai_channel_nbr = 16, /* Analog Input */ .ai_resolution = 12, - .ai_resolution_mask = 0x0fff, .ai_range_list = &me2000_ai_range, .dio_channel_nbr = 32, } @@ -721,7 +716,7 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; s->n_chan = board->ai_channel_nbr; - s->maxdata = board->ai_resolution_mask; + s->maxdata = (1 << board->ai_resolution) - 1; s->len_chanlist = board->ai_channel_nbr; s->range_table = board->ai_range_list; s->cancel = me_ai_cancel; @@ -734,7 +729,7 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; s->n_chan = board->ao_channel_nbr; - s->maxdata = board->ao_resolution_mask; + s->maxdata = (1 << board->ao_resolution) - 1; s->len_chanlist = board->ao_channel_nbr; s->range_table = board->ao_range_list; s->insn_read = me_ao_insn_read; -- cgit v1.2.3 From 20482c786a04df130b1e7847589d09b8fd807dcf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:08:09 -0700 Subject: staging: comedi: me_daq: remove dio_channel_nbr from boardinfo All the boards supported by this driver have 32 dio channels. Remove the boardinfo and just open code the value in the attach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index f14907e4940..6a8b2c966c4 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -182,7 +182,6 @@ struct me_board { int ai_channel_nbr; /* AD config */ int ai_resolution; const struct comedi_lrange *ai_range_list; - int dio_channel_nbr; /* DIO config */ }; static const struct me_board me_boards[] = { @@ -197,7 +196,6 @@ static const struct me_board me_boards[] = { /* Analog Input */ .ai_resolution = 12, .ai_range_list = &me2600_ai_range, - .dio_channel_nbr = 32, }, { .name = "me-2000i", @@ -206,7 +204,6 @@ static const struct me_board me_boards[] = { /* Analog Input */ .ai_resolution = 12, .ai_range_list = &me2000_ai_range, - .dio_channel_nbr = 32, } }; @@ -741,9 +738,9 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s = &dev->subdevices[2]; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; - s->n_chan = board->dio_channel_nbr; + s->n_chan = 32; s->maxdata = 1; - s->len_chanlist = board->dio_channel_nbr; + s->len_chanlist = 32; s->range_table = &range_digital; s->insn_bits = me_dio_insn_bits; s->insn_config = me_dio_insn_config; -- cgit v1.2.3 From 32d39862be8ff3b098e56cbb0d667f76df015948 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:08:25 -0700 Subject: staging: comedi: me_daq: cleanup the boardinfo Rename the boardinfo variables so they are a bit more concise. Remove the unnecessary comments in the boardinfo. Add some whitespace to make the code more readable. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 67 +++++++++++++++------------------ 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 6a8b2c966c4..7e8f4d6cf11 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -172,39 +172,34 @@ static const struct comedi_lrange me2600_ao_range = { } }; -/* Board specification structure */ struct me_board { - const char *name; /* driver name */ + const char *name; int device_id; - int ao_channel_nbr; /* DA config */ - int ao_resolution; - const struct comedi_lrange *ao_range_list; - int ai_channel_nbr; /* AD config */ - int ai_resolution; - const struct comedi_lrange *ai_range_list; + int ao_chans; + int ao_bits; + const struct comedi_lrange *ao_range; + int ai_chans; + int ai_bits; + const struct comedi_lrange *ai_range; }; static const struct me_board me_boards[] = { { - .name = "me-2600i", - .device_id = ME2600_DEVICE_ID, - /* Analog Output */ - .ao_channel_nbr = 4, - .ao_resolution = 12, - .ao_range_list = &me2600_ao_range, - .ai_channel_nbr = 16, - /* Analog Input */ - .ai_resolution = 12, - .ai_range_list = &me2600_ai_range, - }, - { - .name = "me-2000i", - .device_id = ME2000_DEVICE_ID, - .ai_channel_nbr = 16, - /* Analog Input */ - .ai_resolution = 12, - .ai_range_list = &me2000_ai_range, - } + .name = "me-2600i", + .device_id = ME2600_DEVICE_ID, + .ao_chans = 4, + .ao_bits = 12, + .ao_range = &me2600_ao_range, + .ai_chans = 16, + .ai_bits = 12, + .ai_range = &me2600_ai_range, + }, { + .name = "me-2000i", + .device_id = ME2000_DEVICE_ID, + .ai_chans = 16, + .ai_bits = 12, + .ai_range = &me2000_ai_range, + } }; /* Private data structure */ @@ -712,23 +707,23 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; - s->n_chan = board->ai_channel_nbr; - s->maxdata = (1 << board->ai_resolution) - 1; - s->len_chanlist = board->ai_channel_nbr; - s->range_table = board->ai_range_list; + s->n_chan = board->ai_chans; + s->maxdata = (1 << board->ai_bits) - 1; + s->len_chanlist = board->ai_chans; + s->range_table = board->ai_range; s->cancel = me_ai_cancel; s->insn_read = me_ai_insn_read; s->do_cmdtest = me_ai_do_cmd_test; s->do_cmd = me_ai_do_cmd; s = &dev->subdevices[1]; - if (board->ao_channel_nbr) { + if (board->ao_chans) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; - s->n_chan = board->ao_channel_nbr; - s->maxdata = (1 << board->ao_resolution) - 1; - s->len_chanlist = board->ao_channel_nbr; - s->range_table = board->ao_range_list; + s->n_chan = board->ao_chans; + s->maxdata = (1 << board->ao_bits) - 1; + s->len_chanlist = board->ao_chans; + s->range_table = board->ao_range; s->insn_read = me_ao_insn_read; s->insn_write = me_ao_insn_write; } else { -- cgit v1.2.3 From cd0fa970b5e49c8249b1f5520c7764dec2ac9310 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:08:42 -0700 Subject: staging: comedi: me_daq: cleanup the range tables Fix the whitespace. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 53 ++++++++++++++++----------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 7e8f4d6cf11..6231a0c3aaa 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -136,40 +136,37 @@ Configuration options: #define ME_COUNTER_VALUE_B 0x0022 /* R | - */ static const struct comedi_lrange me2000_ai_range = { - 8, - { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25) - } + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; static const struct comedi_lrange me2600_ai_range = { - 8, - { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25) - } + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2.5), + BIP_RANGE(1.25), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2.5), + UNI_RANGE(1.25) + } }; static const struct comedi_lrange me2600_ao_range = { - 3, - { - BIP_RANGE(10), - BIP_RANGE(5), - UNI_RANGE(10) - } + 3, { + BIP_RANGE(10), + BIP_RANGE(5), + UNI_RANGE(10) + } }; struct me_board { -- cgit v1.2.3 From ab69b334c569ff3aacb53f492cb71b11dc9b4a36 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:09:02 -0700 Subject: staging: comedi: me_daq: add some whitespace to the subdevice init To improve the readability, add some whitespace to the subdevice init. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 54 ++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 6231a0c3aaa..952c68259c4 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -702,41 +702,41 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) return ret; s = &dev->subdevices[0]; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; - s->n_chan = board->ai_chans; - s->maxdata = (1 << board->ai_bits) - 1; - s->len_chanlist = board->ai_chans; - s->range_table = board->ai_range; - s->cancel = me_ai_cancel; - s->insn_read = me_ai_insn_read; - s->do_cmdtest = me_ai_do_cmd_test; - s->do_cmd = me_ai_do_cmd; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; + s->n_chan = board->ai_chans; + s->maxdata = (1 << board->ai_bits) - 1; + s->len_chanlist = board->ai_chans; + s->range_table = board->ai_range; + s->cancel = me_ai_cancel; + s->insn_read = me_ai_insn_read; + s->do_cmdtest = me_ai_do_cmd_test; + s->do_cmd = me_ai_do_cmd; s = &dev->subdevices[1]; if (board->ao_chans) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; - s->n_chan = board->ao_chans; - s->maxdata = (1 << board->ao_bits) - 1; - s->len_chanlist = board->ao_chans; - s->range_table = board->ao_range; - s->insn_read = me_ao_insn_read; - s->insn_write = me_ao_insn_write; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; + s->n_chan = board->ao_chans; + s->maxdata = (1 << board->ao_bits) - 1; + s->len_chanlist = board->ao_chans; + s->range_table = board->ao_range; + s->insn_read = me_ao_insn_read; + s->insn_write = me_ao_insn_write; } else { s->type = COMEDI_SUBD_UNUSED; } s = &dev->subdevices[2]; - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; - s->n_chan = 32; - s->maxdata = 1; - s->len_chanlist = 32; - s->range_table = &range_digital; - s->insn_bits = me_dio_insn_bits; - s->insn_config = me_dio_insn_config; - s->io_bits = 0; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITEABLE; + s->n_chan = 32; + s->maxdata = 1; + s->len_chanlist = 32; + s->range_table = &range_digital; + s->insn_bits = me_dio_insn_bits; + s->insn_config = me_dio_insn_config; + s->io_bits = 0; dev_info(dev->class_dev, "%s: %s attached\n", dev->driver->driver_name, dev->board_name); -- cgit v1.2.3 From e43937926265ad417942c8ffb7be8bd185788335 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:09:18 -0700 Subject: staging: comedi: me_daq: remove pci_dev_put() in detach This driver uses the comedi auto config mechanism and does not walk the pci bus to find the pci_dev. It should not be calling pci_dev_put() to decrement the ref count. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 952c68259c4..1e4a980a63b 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -760,7 +760,6 @@ static void me_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } -- cgit v1.2.3 From 91b0da570722faf2e6a06f999e789405161943b5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:09:33 -0700 Subject: staging: comedi: me_daq: fix me_ao_insn_read() This function is supposed to return the analog output value for a specified channel. The channel number is packed in insn->chanspec, which is an unsigned int, and unpacked using the CR_CHAN() macro. Currently this function is trying to use the chanspec as an array. This works only if a single data value is read. Fix the function so that the desired channel is determined and all the data returned is from that channel. Also, fix the return. The comedi core expects insn_read functions to return the number of data values (insn->n). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 1e4a980a63b..1efad5967d9 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -469,20 +469,19 @@ static int me_ao_insn_write(struct comedi_device *dev, return i; } -/* Analog output readback */ static int me_ao_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) { struct me_private_data *dev_private = dev->private; + unsigned int chan = CR_CHAN(insn->chanspec); int i; - for (i = 0; i < insn->n; i++) { - data[i] = - dev_private->ao_readback[CR_CHAN((&insn->chanspec)[i])]; - } + for (i = 0; i < insn->n; i++) + data[i] = dev_private->ao_readback[chan]; - return 1; + return insn->n; } /* -- cgit v1.2.3 From 14d09f79d7b792d20131bc2f25a3d8a8e7cd593f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:09:47 -0700 Subject: staging: comedi: me_daq: fix me_ao_insn_write() This function is supposed to write to a single analog output channel. The channel number is packed in insn->chanspec, which is an unsigned int, and unpacked using the CR_CHAN() macro. Currently this function is trying to use the chanspec as an array. This works only if a single value is written. Fix the function so that the desired channel is determined and all the data is written to that channel. Also, fix the return. The comedi core expects insn_read functions to return the number of data values (insn->n). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 1efad5967d9..9f65a8ee78a 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -409,22 +409,14 @@ static int me_ai_do_cmd(struct comedi_device *dev, return 0; } -/* - * ------------------------------------------------------------------ - * - * ANALOG OUTPUT SECTION - * - * ------------------------------------------------------------------ - */ - -/* Analog instant output */ static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { struct me_private_data *dev_private = dev->private; - int chan; - int rang; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int rang = CR_RANGE(insn->chanspec); int i; /* Enable all DAC */ @@ -437,9 +429,6 @@ static int me_ao_insn_write(struct comedi_device *dev, /* Set dac-control register */ for (i = 0; i < insn->n; i++) { - chan = CR_CHAN((&insn->chanspec)[i]); - rang = CR_RANGE((&insn->chanspec)[i]); - /* clear bits for this channel */ dev_private->dac_control &= ~(0x0880 >> chan); if (rang == 0) @@ -457,7 +446,6 @@ static int me_ao_insn_write(struct comedi_device *dev, /* Set data register */ for (i = 0; i < insn->n; i++) { - chan = CR_CHAN((&insn->chanspec)[i]); writew((data[0] & s->maxdata), dev_private->me_regbase + ME_DAC_DATA_A + (chan << 1)); dev_private->ao_readback[chan] = (data[0] & s->maxdata); @@ -466,7 +454,7 @@ static int me_ao_insn_write(struct comedi_device *dev, /* Update dac with data registers */ readw(dev_private->me_regbase + ME_DAC_UPDATE); - return i; + return insn->n; } static int me_ao_insn_read(struct comedi_device *dev, -- cgit v1.2.3 From aa0ed8280a552a4ee56a040a5d696c296510985e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:10:03 -0700 Subject: staging: comedi: me_daq: remove incomplete analog input command support The analog input subdevice functions me_ai_do_cmd_test() and me_ai_do_cmd() are only stubbed in. They both just return 0. The me_ai_cancel() function does have code to stop any running conversions but the me_ai_insn_read() function does that also. Just remove the incomplete functions and remove SDF_CMD_READ from the subdevice_flags. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 41 +-------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 9f65a8ee78a..ba7ff60b9d5 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -373,42 +373,6 @@ static int me_ai_insn_read(struct comedi_device *dev, return 1; } -/* - * ------------------------------------------------------------------ - * - * HARDWARE TRIGGERED ANALOG INPUT SECTION - * - * ------------------------------------------------------------------ - */ - -/* Cancel analog input autoscan */ -static int me_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) -{ - struct me_private_data *dev_private = dev->private; - - /* disable interrupts */ - - /* stop any running conversion */ - dev_private->control_1 &= 0xFFFC; - writew(dev_private->control_1, dev_private->me_regbase + ME_CONTROL_1); - - return 0; -} - -/* Test analog input command */ -static int me_ai_do_cmd_test(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd) -{ - return 0; -} - -/* Analog input command */ -static int me_ai_do_cmd(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - return 0; -} - static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -690,15 +654,12 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_COMMON; s->n_chan = board->ai_chans; s->maxdata = (1 << board->ai_bits) - 1; s->len_chanlist = board->ai_chans; s->range_table = board->ai_range; - s->cancel = me_ai_cancel; s->insn_read = me_ai_insn_read; - s->do_cmdtest = me_ai_do_cmd_test; - s->do_cmd = me_ai_do_cmd; s = &dev->subdevices[1]; if (board->ao_chans) { -- cgit v1.2.3 From 544c05505cdf31cabe95cef1d7d2bd0b4927d7b6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:10:19 -0700 Subject: staging: comedi: me_daq: cleanup the copyright and comedi comments Reformat the copyright and driver description comments to follow the preferred block comment style. Reword the driver description to follow comedi style described in the skel driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 73 +++++++++++++++------------------ 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index ba7ff60b9d5..bad34310adc 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -1,47 +1,38 @@ /* - - comedi/drivers/me_daq.c - - Hardware driver for Meilhaus data acquisition cards: - - ME-2000i, ME-2600i, ME-3000vm1 - - Copyright (C) 2002 Michael Hillmann - - 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. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ + * comedi/drivers/me_daq.c + * Hardware driver for Meilhaus data acquisition cards: + * ME-2000i, ME-2600i, ME-3000vm1 + * + * Copyright (C) 2002 Michael Hillmann + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ /* -Driver: me_daq -Description: Meilhaus PCI data acquisition cards -Author: Michael Hillmann -Devices: [Meilhaus] ME-2600i (me_daq), ME-2000i -Status: experimental - -Supports: - - Analog Output - -Configuration options: - - [0] - PCI bus number (optional) - [1] - PCI slot number (optional) - - If bus/slot is not specified, the first available PCI - device will be used. -*/ + * Driver: me_daq + * Description: Meilhaus PCI data acquisition cards + * Devices: (Meilhaus) ME-2600i [me-2600i] + * (Meilhaus) ME-2000i [me-2000i] + * Author: Michael Hillmann + * Status: experimental + * + * Configuration options: not applicable, uses PCI auto config + * + * Supports: + * Analog Input, Analog Output, Digital I/O + */ #include #include -- cgit v1.2.3 From fa8eec60259e10a1307f8ff8cdfc6f6db898d4aa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:10:35 -0700 Subject: staging: comedi: me_daq: all boards have the same analog input specs All the boards supported by this driver have the same analog input specifications. Remove the unnecessary boardinfo and just open-code the values in the subdevice initialization. The boards also share the same analog input range capabilities. Remove one of the duplicate tables and rename the other to make it common for all board types. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index bad34310adc..686a1c4f543 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -126,20 +126,7 @@ #define ME_COUNTER_STARTDATA_B 0x0022 /* - | W */ #define ME_COUNTER_VALUE_B 0x0022 /* R | - */ -static const struct comedi_lrange me2000_ai_range = { - 8, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2.5), - BIP_RANGE(1.25), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2.5), - UNI_RANGE(1.25) - } -}; - -static const struct comedi_lrange me2600_ai_range = { +static const struct comedi_lrange me_ai_range = { 8, { BIP_RANGE(10), BIP_RANGE(5), @@ -166,9 +153,6 @@ struct me_board { int ao_chans; int ao_bits; const struct comedi_lrange *ao_range; - int ai_chans; - int ai_bits; - const struct comedi_lrange *ai_range; }; static const struct me_board me_boards[] = { @@ -178,15 +162,9 @@ static const struct me_board me_boards[] = { .ao_chans = 4, .ao_bits = 12, .ao_range = &me2600_ao_range, - .ai_chans = 16, - .ai_bits = 12, - .ai_range = &me2600_ai_range, }, { .name = "me-2000i", .device_id = ME2000_DEVICE_ID, - .ai_chans = 16, - .ai_bits = 12, - .ai_range = &me2000_ai_range, } }; @@ -646,10 +624,10 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON; - s->n_chan = board->ai_chans; - s->maxdata = (1 << board->ai_bits) - 1; - s->len_chanlist = board->ai_chans; - s->range_table = board->ai_range; + s->n_chan = 16; + s->maxdata = 0x0fff; + s->len_chanlist = 16; + s->range_table = &me_ai_range; s->insn_read = me_ai_insn_read; s = &dev->subdevices[1]; -- cgit v1.2.3 From 310239e70aab8d958088948449b7e05d6de64b9c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:10:52 -0700 Subject: staging: comedi: me_daq: simplify analog output boardinfo The boards supported by this driver either have analog outputs or don't have them. Add a new boardinfo value, 'has_ao', to indicate this. The boards that have analog outputs always have 4, 12-bit channels. Remove the unnecessary boardinfo and just open-code the values in the subdevice initialization. The boards with analog outputs also share the same output range capabilities. Rename the comedi_lrange to make it common for all board types. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 686a1c4f543..ceb5b82762e 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -139,7 +139,7 @@ static const struct comedi_lrange me_ai_range = { } }; -static const struct comedi_lrange me2600_ao_range = { +static const struct comedi_lrange me_ao_range = { 3, { BIP_RANGE(10), BIP_RANGE(5), @@ -150,18 +150,14 @@ static const struct comedi_lrange me2600_ao_range = { struct me_board { const char *name; int device_id; - int ao_chans; - int ao_bits; - const struct comedi_lrange *ao_range; + int has_ao; }; static const struct me_board me_boards[] = { { .name = "me-2600i", .device_id = ME2600_DEVICE_ID, - .ao_chans = 4, - .ao_bits = 12, - .ao_range = &me2600_ao_range, + .has_ao = 1, }, { .name = "me-2000i", .device_id = ME2000_DEVICE_ID, @@ -631,13 +627,13 @@ static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s->insn_read = me_ai_insn_read; s = &dev->subdevices[1]; - if (board->ao_chans) { + if (board->has_ao) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_COMMON; - s->n_chan = board->ao_chans; - s->maxdata = (1 << board->ao_bits) - 1; - s->len_chanlist = board->ao_chans; - s->range_table = board->ao_range; + s->n_chan = 4; + s->maxdata = 0x0fff; + s->len_chanlist = 4; + s->range_table = &me_ao_range; s->insn_read = me_ao_insn_read; s->insn_write = me_ao_insn_write; } else { -- cgit v1.2.3 From 5e177c453f3dd9e43c7a407f46f8649c47a3614d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:11:07 -0700 Subject: staging: comedi: me_daq: fix me_dio_insn_config() Currently this function does not work like the comedi code expects. Fix the function so that it checks the instruction, data[0], and does the correct action based on it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 57 ++++++++++++++++----------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index ceb5b82762e..450bee0b3a3 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -188,48 +188,45 @@ static inline void sleep(unsigned sec) schedule_timeout(sec * HZ); } -/* - * ------------------------------------------------------------------ - * - * DIGITAL INPUT/OUTPUT SECTION - * - * ------------------------------------------------------------------ - */ static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { struct me_private_data *dev_private = dev->private; - int bits; - int mask = 1 << CR_CHAN(insn->chanspec); + unsigned int mask = 1 << CR_CHAN(insn->chanspec); + unsigned int bits; + unsigned int port; - /* calculate port */ - if (mask & 0x0000ffff) { /* Port A in use */ + if (mask & 0x0000ffff) { bits = 0x0000ffff; - - /* Enable Port A */ - dev_private->control_2 |= ENABLE_PORT_A; - writew(dev_private->control_2, - dev_private->me_regbase + ME_CONTROL_2); - } else { /* Port B in use */ - + port = ENABLE_PORT_A; + } else { bits = 0xffff0000; - - /* Enable Port B */ - dev_private->control_2 |= ENABLE_PORT_B; - writew(dev_private->control_2, - dev_private->me_regbase + ME_CONTROL_2); + port = ENABLE_PORT_B; } - if (data[0]) { - /* Config port as output */ - s->io_bits |= bits; - } else { - /* Config port as input */ + switch (data[0]) { + case INSN_CONFIG_DIO_INPUT: s->io_bits &= ~bits; + dev_private->control_2 &= ~port; + break; + case INSN_CONFIG_DIO_OUTPUT: + s->io_bits |= bits; + dev_private->control_2 |= port; + break; + case INSN_CONFIG_DIO_QUERY: + data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT; + return insn->n; + break; + default: + return -EINVAL; } - return 1; + /* Update the port configuration */ + writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2); + + return insn->n; } /* Digital instant input/outputs */ -- cgit v1.2.3 From ec6521a20431723ff4fa15fdefb386184075baa2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:11:23 -0700 Subject: staging: comedi: me_daq: cleanup me_dio_insn_bits() This function only needs to update the output channel state when the 'mask' (data[0]) indicates that the state is changing. It's also supposed to return the state for all the input and output channels in data[1]. This function appears to work correctly but it's coded quite differently form the other comedi drivers. Rework the function so it follows the normal form. Also, use a couple local variables for the mmio addresses used to read/write the dio ports. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 45 +++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 450bee0b3a3..823fbf90811 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -229,33 +229,40 @@ static int me_dio_insn_config(struct comedi_device *dev, return insn->n; } -/* Digital instant input/outputs */ static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { struct me_private_data *dev_private = dev->private; + void __iomem *mmio_porta = dev_private->me_regbase + ME_DIO_PORT_A; + void __iomem *mmio_portb = dev_private->me_regbase + ME_DIO_PORT_B; unsigned int mask = data[0]; + unsigned int bits = data[1]; + unsigned int val; + + mask &= s->io_bits; /* only update the COMEDI_OUTPUT channels */ + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); + + if (mask & 0x0000ffff) + writew((s->state & 0xffff), mmio_porta); + if (mask & 0xffff0000) + writew(((s->state >> 16) & 0xffff), mmio_portb); + } - s->state &= ~mask; - s->state |= (mask & data[1]); + if (s->io_bits & 0x0000ffff) + val = s->state & 0xffff; + else + val = readw(mmio_porta); - mask &= s->io_bits; - if (mask & 0x0000ffff) { /* Port A */ - writew((s->state & 0xffff), - dev_private->me_regbase + ME_DIO_PORT_A); - } else { - data[1] &= ~0x0000ffff; - data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_A); - } + if (s->io_bits & 0xffff0000) + val |= (s->state & 0xffff0000); + else + val |= (readw(mmio_portb) << 16); - if (mask & 0xffff0000) { /* Port B */ - writew(((s->state >> 16) & 0xffff), - dev_private->me_regbase + ME_DIO_PORT_B); - } else { - data[1] &= ~0xffff0000; - data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_B) << 16; - } + data[1] = val; return insn->n; } -- cgit v1.2.3 From 61532e9d6e8536a6cd05eb2d38eb84ebf08784af Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:11:38 -0700 Subject: staging: comedi: me_daq: cleanup me_ai_insn_read() Fix the use of insn->chanspec with the CR_CHAN, CR_RANGE, and CR_AREF macros. insn->chanspec is an unsigned int not an array. Cleanup the comments when creating the 'val' to write to the channel list fifo so that the code is a bit more readable. Use the 'val' variable when getting the value from the ADC fifo and then munging the data. This cleans up the goofy line breaks. This function still does not follow the expectations of the comedi core. It is supposed to read insn->n values from the channel and return those values. Currently it only reads a single value. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 40 ++++++++++++--------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 823fbf90811..7aa339908e5 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -267,24 +267,16 @@ static int me_dio_insn_bits(struct comedi_device *dev, return insn->n; } -/* - * ------------------------------------------------------------------ - * - * ANALOG INPUT SECTION - * - * ------------------------------------------------------------------ - */ - -/* Analog instant input */ static int me_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { struct me_private_data *dev_private = dev->private; - unsigned short value; - int chan = CR_CHAN((&insn->chanspec)[0]); - int rang = CR_RANGE((&insn->chanspec)[0]); - int aref = CR_AREF((&insn->chanspec)[0]); + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int rang = CR_RANGE(insn->chanspec); + unsigned int aref = CR_AREF(insn->chanspec); + unsigned short val; int i; /* stop any running conversion */ @@ -303,15 +295,11 @@ static int me_ai_insn_read(struct comedi_device *dev, writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2); /* write to channel list fifo */ - /* b3:b0 are the channel number */ - value = chan & 0x0f; - /* b5:b4 are the channel gain */ - value |= (rang & 0x03) << 4; - /* b6 channel polarity */ - value |= (rang & 0x04) << 4; - /* b7 single or differential */ - value |= ((aref & AREF_DIFF) ? 0x80 : 0); - writew(value & 0xff, dev_private->me_regbase + ME_CHANNEL_LIST); + val = chan & 0x0f; /* b3:b0 channel */ + val |= (rang & 0x03) << 4; /* b5:b4 gain */ + val |= (rang & 0x04) << 4; /* b6 polarity */ + val |= ((aref & AREF_DIFF) ? 0x80 : 0); /* b7 differential */ + writew(val & 0xff, dev_private->me_regbase + ME_CHANNEL_LIST); /* set ADC mode to software trigger */ dev_private->control_1 |= SOFTWARE_TRIGGERED_ADC; @@ -327,9 +315,9 @@ static int me_ai_insn_read(struct comedi_device *dev, /* get value from ADC fifo */ if (i) { - data[0] = - (readw(dev_private->me_regbase + - ME_READ_AD_FIFO) ^ 0x800) & 0x0FFF; + val = readw(dev_private->me_regbase + ME_READ_AD_FIFO); + val = (val ^ 0x800) & 0x0fff; + data[0] = val; } else { dev_err(dev->class_dev, "Cannot get single value\n"); return -EIO; -- cgit v1.2.3 From e33909c6d43b3f3913a5d5a370d9ff1335e4bd58 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 25 Oct 2012 15:11:52 -0700 Subject: staging: comedi: me_daq: remove some obvious comments These comments are just extra cruft. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 7aa339908e5..6a2dbdf9f0d 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -164,7 +164,6 @@ static const struct me_board me_boards[] = { } }; -/* Private data structure */ struct me_private_data { void __iomem *plx_regbase; /* PLX configuration base address */ void __iomem *me_regbase; /* Base address of the Meilhaus card */ @@ -175,13 +174,6 @@ struct me_private_data { int ao_readback[4]; /* Mirror of analog output data */ }; -/* - * ------------------------------------------------------------------ - * - * Helpful functions - * - * ------------------------------------------------------------------ - */ static inline void sleep(unsigned sec) { current->state = TASK_INTERRUPTIBLE; @@ -393,15 +385,6 @@ static int me_ao_insn_read(struct comedi_device *dev, return insn->n; } -/* - * ------------------------------------------------------------------ - * - * INITIALISATION SECTION - * - * ------------------------------------------------------------------ - */ - -/* Xilinx firmware download for card: ME-2600i */ static int me2600_xilinx_download(struct comedi_device *dev, const u8 *data, size_t size) { @@ -485,7 +468,6 @@ static int me2600_upload_firmware(struct comedi_device *dev) return ret; } -/* Reset device */ static int me_reset(struct comedi_device *dev) { struct me_private_data *dev_private = dev->private; -- cgit v1.2.3 From db9d1f6dd2601aee860304ffc1023a7d5709f314 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 25 Oct 2012 15:30:06 +0300 Subject: staging: r8712u: cleanup pointer type in r8712_setassocsta_cmd() This seems like a cut and paste bug. Smatch complains that we don't allocate enough memory for a set_stakey_rsp struct. In fact this is used as a set_assocsta_rsp struct throughout and that also matches the name of the function. Signed-off-by: Dan Carpenter Acked-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8712/rtl871x_cmd.c b/drivers/staging/rtl8712/rtl871x_cmd.c index 659683e022b..31f31dbf7f3 100644 --- a/drivers/staging/rtl8712/rtl871x_cmd.c +++ b/drivers/staging/rtl8712/rtl871x_cmd.c @@ -814,7 +814,7 @@ u8 r8712_setassocsta_cmd(struct _adapter *padapter, u8 *mac_addr) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; struct cmd_obj *ph2c; struct set_assocsta_parm *psetassocsta_para; - struct set_stakey_rsp *psetassocsta_rsp = NULL; + struct set_assocsta_rsp *psetassocsta_rsp = NULL; ph2c = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj)); if (ph2c == NULL) @@ -825,7 +825,7 @@ u8 r8712_setassocsta_cmd(struct _adapter *padapter, u8 *mac_addr) kfree((u8 *) ph2c); return _FAIL; } - psetassocsta_rsp = (struct set_stakey_rsp *)_malloc( + psetassocsta_rsp = (struct set_assocsta_rsp *)_malloc( sizeof(struct set_assocsta_rsp)); if (psetassocsta_rsp == NULL) { kfree((u8 *)ph2c); -- cgit v1.2.3 From 34ec83f4c1dc0d6bf4b056f89841706907a06255 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 25 Oct 2012 02:11:51 -0400 Subject: staging: slicoss: fix a leak when kzalloc fail slic_card_locate does a kzalloc of physcard, and if it fails, in my previous patch i returned -ENOMEM, but left the driver leak the memory if card_hostid == SLIC_HOSTID_DEFAULT, fix this memory leak if the above condition is true Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index f08f4593b18..ee0f0e4e41a 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -3657,8 +3657,11 @@ static u32 slic_card_locate(struct adapter *adapter) if (!physcard) { /* no structure allocated for this physical card yet */ physcard = kzalloc(sizeof(struct physcard), GFP_ATOMIC); - if (!physcard) + if (!physcard) { + if (card_hostid == SLIC_HOSTID_DEFAULT) + kfree(card); return -ENOMEM; + } physcard->next = slic_global.phys_card; slic_global.phys_card = physcard; -- cgit v1.2.3 From 7326446c728f633a0d6b3318cf491f71f044dce0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 26 Oct 2012 13:06:04 -0700 Subject: Staging: remove telephony drivers We said we would wait until the 3.6 kernel release to remove these drivers. So we waited 6 months longer, that should be fine. If anyone wants them back, it is trivial to revert these, but given that I don't think they even build anymore, I doubt anyone will want them. Cc: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/telephony/Kconfig | 47 - drivers/staging/telephony/Makefile | 7 - drivers/staging/telephony/TODO | 10 - drivers/staging/telephony/ixj-ver.h | 4 - drivers/staging/telephony/ixj.c | 10571 ------------------------------- drivers/staging/telephony/ixj.h | 1322 ---- drivers/staging/telephony/ixj_pcmcia.c | 187 - drivers/staging/telephony/phonedev.c | 166 - 10 files changed, 12317 deletions(-) delete mode 100644 drivers/staging/telephony/Kconfig delete mode 100644 drivers/staging/telephony/Makefile delete mode 100644 drivers/staging/telephony/TODO delete mode 100644 drivers/staging/telephony/ixj-ver.h delete mode 100644 drivers/staging/telephony/ixj.c delete mode 100644 drivers/staging/telephony/ixj.h delete mode 100644 drivers/staging/telephony/ixj_pcmcia.c delete mode 100644 drivers/staging/telephony/phonedev.c diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 8b4566e776e..231a2729d34 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -118,8 +118,6 @@ source "drivers/staging/omapdrm/Kconfig" source "drivers/staging/android/Kconfig" -source "drivers/staging/telephony/Kconfig" - source "drivers/staging/ozwpan/Kconfig" source "drivers/staging/ccg/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 72e8014c6d1..2b291c01c51 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -52,7 +52,6 @@ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ obj-$(CONFIG_MFD_NVEC) += nvec/ obj-$(CONFIG_DRM_OMAP) += omapdrm/ obj-$(CONFIG_ANDROID) += android/ -obj-$(CONFIG_PHONE) += telephony/ obj-$(CONFIG_USB_WPAN_HCD) += ozwpan/ obj-$(CONFIG_USB_G_CCG) += ccg/ obj-$(CONFIG_WIMAX_GDM72XX) += gdm72xx/ diff --git a/drivers/staging/telephony/Kconfig b/drivers/staging/telephony/Kconfig deleted file mode 100644 index b5f78b6ed2b..00000000000 --- a/drivers/staging/telephony/Kconfig +++ /dev/null @@ -1,47 +0,0 @@ -# -# Telephony device configuration -# - -menuconfig PHONE - tristate "Telephony support" - depends on HAS_IOMEM - ---help--- - Say Y here if you have a telephony card, which for example allows - you to use a regular phone for voice-over-IP applications. - - Note: this has nothing to do with modems. You do not need to say Y - here in order to be able to use a modem under Linux. - - To compile this driver as a module, choose M here: the - module will be called phonedev. - -if PHONE - -config PHONE_IXJ - tristate "QuickNet Internet LineJack/PhoneJack support" - depends on ISA || PCI - ---help--- - Say M if you have a telephony card manufactured by Quicknet - Technologies, Inc. These include the Internet PhoneJACK and - Internet LineJACK Telephony Cards. You will get a module called - ixj. - - For the ISA versions of these products, you can configure the - cards using the isapnp tools (pnpdump/isapnp) or you can use the - isapnp support. Please read . - - For more information on these cards, see Quicknet's web site at: - . - - If you do not have any Quicknet telephony cards, you can safely - say N here. - -config PHONE_IXJ_PCMCIA - tristate "QuickNet Internet LineJack/PhoneJack PCMCIA support" - depends on PHONE_IXJ && PCMCIA - help - Say Y here to configure in PCMCIA service support for the Quicknet - cards manufactured by Quicknet Technologies, Inc. This changes the - card initialization code to work with the card manager daemon. - -endif # PHONE diff --git a/drivers/staging/telephony/Makefile b/drivers/staging/telephony/Makefile deleted file mode 100644 index 1206615d69e..00000000000 --- a/drivers/staging/telephony/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for drivers/telephony -# - -obj-$(CONFIG_PHONE) += phonedev.o -obj-$(CONFIG_PHONE_IXJ) += ixj.o -obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o diff --git a/drivers/staging/telephony/TODO b/drivers/staging/telephony/TODO deleted file mode 100644 index d47dec3508d..00000000000 --- a/drivers/staging/telephony/TODO +++ /dev/null @@ -1,10 +0,0 @@ -TODO -. Determine if the boards are still in use - and move this module back to drivers/telephony if necessary -. Coding style cleanups - -Please send patches to Greg Kroah-Hartman and -cc Joe Perches if the module should be reactivated. - -If no module activity occurs before version 3.6 is released, this -module should be removed. diff --git a/drivers/staging/telephony/ixj-ver.h b/drivers/staging/telephony/ixj-ver.h deleted file mode 100644 index 2031ac6c888..00000000000 --- a/drivers/staging/telephony/ixj-ver.h +++ /dev/null @@ -1,4 +0,0 @@ -/* configuration management identifiers */ -#define IXJ_VER_MAJOR 1 -#define IXJ_VER_MINOR 0 -#define IXJ_BLD_VER 1 diff --git a/drivers/staging/telephony/ixj.c b/drivers/staging/telephony/ixj.c deleted file mode 100644 index 1cfa0b07d72..00000000000 --- a/drivers/staging/telephony/ixj.c +++ /dev/null @@ -1,10571 +0,0 @@ -/**************************************************************************** - * ixj.c - * - * Device Driver for Quicknet Technologies, Inc.'s Telephony cards - * including the Internet PhoneJACK, Internet PhoneJACK Lite, - * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and - * SmartCABLE - * - * (c) Copyright 1999-2001 Quicknet Technologies, Inc. - * - * 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. - * - * Author: Ed Okerson, - * - * Contributors: Greg Herlein, - * David W. Erhart, - * John Sellers, - * Mike Preston, - * - * Fixes: David Huggins-Daines, - * Fabio Ferrari, - * Artis Kugevics, - * Daniele Bellucci, - * - * More information about the hardware related to this driver can be found - * at our website: http://www.quicknet.net - * - * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET - * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION - * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - ***************************************************************************/ - -/* - * Revision 4.8 2003/07/09 19:39:00 Daniele Bellucci - * Audit some copy_*_user and minor cleanup. - * - * Revision 4.7 2001/08/13 06:19:33 craigs - * Added additional changes from Alan Cox and John Anderson for - * 2.2 to 2.4 cleanup and bounds checking - * - * Revision 4.6 2001/08/13 01:05:05 craigs - * Really fixed PHONE_QUERY_CODEC problem this time - * - * Revision 4.5 2001/08/13 00:11:03 craigs - * Fixed problem in handling of PHONE_QUERY_CODEC, thanks to Shane Anderson - * - * Revision 4.4 2001/08/07 07:58:12 craigs - * Changed back to three digit version numbers - * Added tagbuild target to allow automatic and easy tagging of versions - * - * Revision 4.3 2001/08/07 07:24:47 craigs - * Added ixj-ver.h to allow easy configuration management of driver - * Added display of version number in /prox/ixj - * - * Revision 4.2 2001/08/06 07:07:19 craigs - * Reverted IXJCTL_DSP_TYPE and IXJCTL_DSP_VERSION files to original - * behaviour of returning int rather than short * - * - * Revision 4.1 2001/08/05 00:17:37 craigs - * More changes for correct PCMCIA installation - * Start of changes for backward Linux compatibility - * - * Revision 4.0 2001/08/04 12:33:12 craigs - * New version using GNU autoconf - * - * Revision 3.105 2001/07/20 23:14:32 eokerson - * More work on CallerID generation when using ring cadences. - * - * Revision 3.104 2001/07/06 01:33:55 eokerson - * Some bugfixes from Robert Vojta and a few mods to the Makefile. - * - * Revision 3.103 2001/07/05 19:20:16 eokerson - * Updated HOWTO - * Changed mic gain to 30dB on Internet LineJACK mic/speaker port. - * - * Revision 3.102 2001/07/03 23:51:21 eokerson - * Un-mute mic on Internet LineJACK when in speakerphone mode. - * - * Revision 3.101 2001/07/02 19:26:56 eokerson - * Removed initialiazation of ixjdebug and ixj_convert_loaded so they will go in the .bss instead of the .data - * - * Revision 3.100 2001/07/02 19:18:27 eokerson - * Changed driver to make dynamic allocation possible. We now pass IXJ * between functions instead of array indexes. - * Fixed the way the POTS and PSTN ports interact during a PSTN call to allow local answering. - * Fixed speaker mode on Internet LineJACK. - * - * Revision 3.99 2001/05/09 14:11:16 eokerson - * Fixed kmalloc error in ixj_build_filter_cadence. Thanks David Chan . - * - * Revision 3.98 2001/05/08 19:55:33 eokerson - * Fixed POTS hookstate detection while it is connected to PSTN port. - * - * Revision 3.97 2001/05/08 00:01:04 eokerson - * Fixed kernel oops when sending caller ID data. - * - * Revision 3.96 2001/05/04 23:09:30 eokerson - * Now uses one kernel timer for each card, instead of one for the entire driver. - * - * Revision 3.95 2001/04/25 22:06:47 eokerson - * Fixed squawking at beginning of some G.723.1 calls. - * - * Revision 3.94 2001/04/03 23:42:00 eokerson - * Added linear volume ioctls - * Added raw filter load ioctl - * - * Revision 3.93 2001/02/27 01:00:06 eokerson - * Fixed blocking in CallerID. - * Reduced size of ixj structure for smaller driver footprint. - * - * Revision 3.92 2001/02/20 22:02:59 eokerson - * Fixed isapnp and pcmcia module compatibility for 2.4.x kernels. - * Improved PSTN ring detection. - * Fixed wink generation on POTS ports. - * - * Revision 3.91 2001/02/13 00:55:44 eokerson - * Turn AEC back on after changing frame sizes. - * - * Revision 3.90 2001/02/12 16:42:00 eokerson - * Added ALAW codec, thanks to Fabio Ferrari for the table based converters to make ALAW from ULAW. - * - * Revision 3.89 2001/02/12 15:41:16 eokerson - * Fix from Artis Kugevics - Tone gains were not being set correctly. - * - * Revision 3.88 2001/02/05 23:25:42 eokerson - * Fixed lockup bugs with deregister. - * - * Revision 3.87 2001/01/29 21:00:39 eokerson - * Fix from Fabio Ferrari to properly handle EAGAIN and EINTR during non-blocking write. - * Updated copyright date. - * - * Revision 3.86 2001/01/23 23:53:46 eokerson - * Fixes to G.729 compatibility. - * - * Revision 3.85 2001/01/23 21:30:36 eokerson - * Added verbage about cards supported. - * Removed commands that put the card in low power mode at some times that it should not be in low power mode. - * - * Revision 3.84 2001/01/22 23:32:10 eokerson - * Some bugfixes from David Huggins-Daines, and other cleanups. - * - * Revision 3.83 2001/01/19 14:51:41 eokerson - * Fixed ixj_WriteDSPCommand to decrement usage counter when command fails. - * - * Revision 3.82 2001/01/19 00:34:49 eokerson - * Added verbosity to write overlap errors. - * - * Revision 3.81 2001/01/18 23:56:54 eokerson - * Fixed PSTN line test functions. - * - * Revision 3.80 2001/01/18 22:29:27 eokerson - * Updated AEC/AGC values for different cards. - * - * Revision 3.79 2001/01/17 02:58:54 eokerson - * Fixed AEC reset after Caller ID. - * Fixed Codec lockup after Caller ID on Call Waiting when not using 30ms frames. - * - * Revision 3.78 2001/01/16 19:43:09 eokerson - * Added support for Linux 2.4.x kernels. - * - * Revision 3.77 2001/01/09 04:00:52 eokerson - * Linetest will now test the line, even if it has previously succeeded. - * - * Revision 3.76 2001/01/08 19:27:00 eokerson - * Fixed problem with standard cable on Internet PhoneCARD. - * - * Revision 3.75 2000/12/22 16:52:14 eokerson - * Modified to allow hookstate detection on the POTS port when the PSTN port is selected. - * - * Revision 3.74 2000/12/08 22:41:50 eokerson - * Added capability for G729B. - * - * Revision 3.73 2000/12/07 23:35:16 eokerson - * Added capability to have different ring pattern before CallerID data. - * Added hookstate checks in CallerID routines to stop FSK. - * - * Revision 3.72 2000/12/06 19:31:31 eokerson - * Modified signal behavior to only send one signal per event. - * - * Revision 3.71 2000/12/06 03:23:08 eokerson - * Fixed CallerID on Call Waiting. - * - * Revision 3.70 2000/12/04 21:29:37 eokerson - * Added checking to Smart Cable gain functions. - * - * Revision 3.69 2000/12/04 21:05:20 eokerson - * Changed ixjdebug levels. - * Added ioctls to change gains in Internet Phone CARD Smart Cable. - * - * Revision 3.68 2000/12/04 00:17:21 craigs - * Changed mixer voice gain to +6dB rather than 0dB - * - * Revision 3.67 2000/11/30 21:25:51 eokerson - * Fixed write signal errors. - * - * Revision 3.66 2000/11/29 22:42:44 eokerson - * Fixed PSTN ring detect problems. - * - * Revision 3.65 2000/11/29 07:31:55 craigs - * Added new 425Hz filter co-efficients - * Added card-specific DTMF prescaler initialisation - * - * Revision 3.64 2000/11/28 14:03:32 craigs - * Changed certain mixer initialisations to be 0dB rather than 12dB - * Added additional information to /proc/ixj - * - * Revision 3.63 2000/11/28 11:38:41 craigs - * Added display of AEC modes in AUTO and AGC mode - * - * Revision 3.62 2000/11/28 04:05:44 eokerson - * Improved PSTN ring detection routine. - * - * Revision 3.61 2000/11/27 21:53:12 eokerson - * Fixed flash detection. - * - * Revision 3.60 2000/11/27 15:57:29 eokerson - * More work on G.729 load routines. - * - * Revision 3.59 2000/11/25 21:55:12 eokerson - * Fixed errors in G.729 load routine. - * - * Revision 3.58 2000/11/25 04:08:29 eokerson - * Added board locks around G.729 and TS85 load routines. - * - * Revision 3.57 2000/11/24 05:35:17 craigs - * Added ability to retrieve mixer values on LineJACK - * Added complete initialisation of all mixer values at startup - * Fixed spelling mistake - * - * Revision 3.56 2000/11/23 02:52:11 robertj - * Added cvs change log keyword. - * Fixed bug in capabilities list when using G.729 module. - * - */ - -#include "ixj-ver.h" - -#define PERFMON_STATS -#define IXJDEBUG 0 -#define MAXRINGS 5 - -#include - -#include -#include -#include /* printk() */ -#include /* everything... */ -#include /* error codes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "ixj.h" - -#define TYPE(inode) (iminor(inode) >> 4) -#define NUM(inode) (iminor(inode) & 0xf) - -static DEFINE_MUTEX(ixj_mutex); -static int ixjdebug; -static int hertz = HZ; -static int samplerate = 100; - -module_param(ixjdebug, int, 0); - -static DEFINE_PCI_DEVICE_TABLE(ixj_pci_tbl) = { - { PCI_VENDOR_ID_QUICKNET, PCI_DEVICE_ID_QUICKNET_XJ, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { } -}; -MODULE_DEVICE_TABLE(pci, ixj_pci_tbl); - -/************************************************************************ -* -* ixjdebug meanings are now bit mapped instead of level based -* Values can be or'ed together to turn on multiple messages -* -* bit 0 (0x0001) = any failure -* bit 1 (0x0002) = general messages -* bit 2 (0x0004) = POTS ringing related -* bit 3 (0x0008) = PSTN events -* bit 4 (0x0010) = PSTN Cadence state details -* bit 5 (0x0020) = Tone detection triggers -* bit 6 (0x0040) = Tone detection cadence details -* bit 7 (0x0080) = ioctl tracking -* bit 8 (0x0100) = signal tracking -* bit 9 (0x0200) = CallerID generation details -* -************************************************************************/ - -#ifdef IXJ_DYN_ALLOC - -static IXJ *ixj[IXJMAX]; -#define get_ixj(b) ixj[(b)] - -/* - * Allocate a free IXJ device - */ - -static IXJ *ixj_alloc() -{ - for(cnt=0; cntDSPbase) - { - j = kmalloc(sizeof(IXJ), GFP_KERNEL); - if (j == NULL) - return NULL; - ixj[cnt] = j; - return j; - } - } - return NULL; -} - -static void ixj_fsk_free(IXJ *j) -{ - kfree(j->fskdata); - j->fskdata = NULL; -} - -static void ixj_fsk_alloc(IXJ *j) -{ - if(!j->fskdata) { - j->fskdata = kmalloc(8000, GFP_KERNEL); - if (!j->fskdata) { - if(ixjdebug & 0x0200) { - printk("IXJ phone%d - allocate failed\n", j->board); - } - return; - } else { - j->fsksize = 8000; - if(ixjdebug & 0x0200) { - printk("IXJ phone%d - allocate succeeded\n", j->board); - } - } - } -} - -#else - -static IXJ ixj[IXJMAX]; -#define get_ixj(b) (&ixj[(b)]) - -/* - * Allocate a free IXJ device - */ - -static IXJ *ixj_alloc(void) -{ - int cnt; - for(cnt=0; cntfsksize = 8000; -} - -#endif - -#ifdef PERFMON_STATS -#define ixj_perfmon(x) ((x)++) -#else -#define ixj_perfmon(x) do { } while(0) -#endif - -static int ixj_convert_loaded; - -static int ixj_WriteDSPCommand(unsigned short, IXJ *j); - -/************************************************************************ -* -* These are function definitions to allow external modules to register -* enhanced functionality call backs. -* -************************************************************************/ - -static int Stub(IXJ * J, unsigned long arg) -{ - return 0; -} - -static IXJ_REGFUNC ixj_PreRead = &Stub; -static IXJ_REGFUNC ixj_PostRead = &Stub; -static IXJ_REGFUNC ixj_PreWrite = &Stub; -static IXJ_REGFUNC ixj_PostWrite = &Stub; - -static void ixj_read_frame(IXJ *j); -static void ixj_write_frame(IXJ *j); -static void ixj_init_timer(IXJ *j); -static void ixj_add_timer(IXJ * j); -static void ixj_timeout(unsigned long ptr); -static int read_filters(IXJ *j); -static int LineMonitor(IXJ *j); -static int ixj_fasync(int fd, struct file *, int mode); -static int ixj_set_port(IXJ *j, int arg); -static int ixj_set_pots(IXJ *j, int arg); -static int ixj_hookstate(IXJ *j); -static int ixj_record_start(IXJ *j); -static void ixj_record_stop(IXJ *j); -static void set_rec_volume(IXJ *j, int volume); -static int get_rec_volume(IXJ *j); -static int set_rec_codec(IXJ *j, int rate); -static void ixj_vad(IXJ *j, int arg); -static int ixj_play_start(IXJ *j); -static void ixj_play_stop(IXJ *j); -static int ixj_set_tone_on(unsigned short arg, IXJ *j); -static int ixj_set_tone_off(unsigned short, IXJ *j); -static int ixj_play_tone(IXJ *j, char tone); -static void ixj_aec_start(IXJ *j, int level); -static int idle(IXJ *j); -static void ixj_ring_on(IXJ *j); -static void ixj_ring_off(IXJ *j); -static void aec_stop(IXJ *j); -static void ixj_ringback(IXJ *j); -static void ixj_busytone(IXJ *j); -static void ixj_dialtone(IXJ *j); -static void ixj_cpt_stop(IXJ *j); -static char daa_int_read(IXJ *j); -static char daa_CR_read(IXJ *j, int cr); -static int daa_set_mode(IXJ *j, int mode); -static int ixj_linetest(IXJ *j); -static int ixj_daa_write(IXJ *j); -static int ixj_daa_cid_read(IXJ *j); -static void DAA_Coeff_US(IXJ *j); -static void DAA_Coeff_UK(IXJ *j); -static void DAA_Coeff_France(IXJ *j); -static void DAA_Coeff_Germany(IXJ *j); -static void DAA_Coeff_Australia(IXJ *j); -static void DAA_Coeff_Japan(IXJ *j); -static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf); -static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr); -static int ixj_init_tone(IXJ *j, IXJ_TONE * ti); -static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp); -static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp); -/* Serial Control Interface funtions */ -static int SCI_Control(IXJ *j, int control); -static int SCI_Prepare(IXJ *j); -static int SCI_WaitHighSCI(IXJ *j); -static int SCI_WaitLowSCI(IXJ *j); -static DWORD PCIEE_GetSerialNumber(WORD wAddress); -static int ixj_PCcontrol_wait(IXJ *j); -static void ixj_pre_cid(IXJ *j); -static void ixj_write_cid(IXJ *j); -static void ixj_write_cid_bit(IXJ *j, int bit); -static int set_base_frame(IXJ *j, int size); -static int set_play_codec(IXJ *j, int rate); -static void set_rec_depth(IXJ *j, int depth); -static int ixj_mixer(long val, IXJ *j); - -/************************************************************************ -CT8020/CT8021 Host Programmers Model -Host address Function Access -DSPbase + -0-1 Aux Software Status Register (reserved) Read Only -2-3 Software Status Register Read Only -4-5 Aux Software Control Register (reserved) Read Write -6-7 Software Control Register Read Write -8-9 Hardware Status Register Read Only -A-B Hardware Control Register Read Write -C-D Host Transmit (Write) Data Buffer Access Port (buffer input)Write Only -E-F Host Receive (Read) Data Buffer Access Port (buffer input) Read Only -************************************************************************/ - -static inline void ixj_read_HSR(IXJ *j) -{ - j->hsr.bytes.low = inb_p(j->DSPbase + 8); - j->hsr.bytes.high = inb_p(j->DSPbase + 9); -} - -static inline int IsControlReady(IXJ *j) -{ - ixj_read_HSR(j); - return j->hsr.bits.controlrdy ? 1 : 0; -} - -static inline int IsPCControlReady(IXJ *j) -{ - j->pccr1.byte = inb_p(j->XILINXbase + 3); - return j->pccr1.bits.crr ? 1 : 0; -} - -static inline int IsStatusReady(IXJ *j) -{ - ixj_read_HSR(j); - return j->hsr.bits.statusrdy ? 1 : 0; -} - -static inline int IsRxReady(IXJ *j) -{ - ixj_read_HSR(j); - ixj_perfmon(j->rxreadycheck); - return j->hsr.bits.rxrdy ? 1 : 0; -} - -static inline int IsTxReady(IXJ *j) -{ - ixj_read_HSR(j); - ixj_perfmon(j->txreadycheck); - return j->hsr.bits.txrdy ? 1 : 0; -} - -static inline void set_play_volume(IXJ *j, int volume) -{ - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: /dev/phone%d Setting Play Volume to 0x%4.4x\n", j->board, volume); - ixj_WriteDSPCommand(0xCF02, j); - ixj_WriteDSPCommand(volume, j); -} - -static int set_play_volume_linear(IXJ *j, int volume) -{ - int newvolume, dspplaymax; - - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Play Volume to 0x%4.4x\n", j->board, volume); - if(volume > 100 || volume < 0) { - return -1; - } - - /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */ - switch (j->cardtype) { - case QTI_PHONEJACK: - dspplaymax = 0x380; - break; - case QTI_LINEJACK: - if(j->port == PORT_PSTN) { - dspplaymax = 0x48; - } else { - dspplaymax = 0x100; - } - break; - case QTI_PHONEJACK_LITE: - dspplaymax = 0x380; - break; - case QTI_PHONEJACK_PCI: - dspplaymax = 0x6C; - break; - case QTI_PHONECARD: - dspplaymax = 0x50; - break; - default: - return -1; - } - newvolume = (dspplaymax * volume) / 100; - set_play_volume(j, newvolume); - return 0; -} - -static inline void set_play_depth(IXJ *j, int depth) -{ - if (depth > 60) - depth = 60; - if (depth < 0) - depth = 0; - ixj_WriteDSPCommand(0x5280 + depth, j); -} - -static inline int get_play_volume(IXJ *j) -{ - ixj_WriteDSPCommand(0xCF00, j); - return j->ssr.high << 8 | j->ssr.low; -} - -static int get_play_volume_linear(IXJ *j) -{ - int volume, newvolume, dspplaymax; - - /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */ - switch (j->cardtype) { - case QTI_PHONEJACK: - dspplaymax = 0x380; - break; - case QTI_LINEJACK: - if(j->port == PORT_PSTN) { - dspplaymax = 0x48; - } else { - dspplaymax = 0x100; - } - break; - case QTI_PHONEJACK_LITE: - dspplaymax = 0x380; - break; - case QTI_PHONEJACK_PCI: - dspplaymax = 0x6C; - break; - case QTI_PHONECARD: - dspplaymax = 100; - break; - default: - return -1; - } - volume = get_play_volume(j); - newvolume = (volume * 100) / dspplaymax; - if(newvolume > 100) - newvolume = 100; - return newvolume; -} - -static inline BYTE SLIC_GetState(IXJ *j) -{ - if (j->cardtype == QTI_PHONECARD) { - j->pccr1.byte = 0; - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 1; - outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00); - ixj_PCcontrol_wait(j); - j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF; - ixj_PCcontrol_wait(j); - if (j->pslic.bits.powerdown) - return PLD_SLIC_STATE_OC; - else if (!j->pslic.bits.ring0 && !j->pslic.bits.ring1) - return PLD_SLIC_STATE_ACTIVE; - else - return PLD_SLIC_STATE_RINGING; - } else { - j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01); - } - return j->pld_slicr.bits.state; -} - -static bool SLIC_SetState(BYTE byState, IXJ *j) -{ - bool fRetVal = false; - - if (j->cardtype == QTI_PHONECARD) { - if (j->flags.pcmciasct) { - switch (byState) { - case PLD_SLIC_STATE_TIPOPEN: - case PLD_SLIC_STATE_OC: - j->pslic.bits.powerdown = 1; - j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0; - fRetVal = true; - break; - case PLD_SLIC_STATE_RINGING: - if (j->readers || j->writers) { - j->pslic.bits.powerdown = 0; - j->pslic.bits.ring0 = 1; - j->pslic.bits.ring1 = 0; - fRetVal = true; - } - break; - case PLD_SLIC_STATE_OHT: /* On-hook transmit */ - - case PLD_SLIC_STATE_STANDBY: - case PLD_SLIC_STATE_ACTIVE: - if (j->readers || j->writers) { - j->pslic.bits.powerdown = 0; - } else { - j->pslic.bits.powerdown = 1; - } - j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0; - fRetVal = true; - break; - case PLD_SLIC_STATE_APR: /* Active polarity reversal */ - - case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */ - - default: - fRetVal = false; - break; - } - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 0; - outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00); - ixj_PCcontrol_wait(j); - } - } else { - /* Set the C1, C2, C3 & B2EN signals. */ - switch (byState) { - case PLD_SLIC_STATE_OC: - j->pld_slicw.bits.c1 = 0; - j->pld_slicw.bits.c2 = 0; - j->pld_slicw.bits.c3 = 0; - j->pld_slicw.bits.b2en = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_RINGING: - j->pld_slicw.bits.c1 = 1; - j->pld_slicw.bits.c2 = 0; - j->pld_slicw.bits.c3 = 0; - j->pld_slicw.bits.b2en = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_ACTIVE: - j->pld_slicw.bits.c1 = 0; - j->pld_slicw.bits.c2 = 1; - j->pld_slicw.bits.c3 = 0; - j->pld_slicw.bits.b2en = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_OHT: /* On-hook transmit */ - - j->pld_slicw.bits.c1 = 1; - j->pld_slicw.bits.c2 = 1; - j->pld_slicw.bits.c3 = 0; - j->pld_slicw.bits.b2en = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_TIPOPEN: - j->pld_slicw.bits.c1 = 0; - j->pld_slicw.bits.c2 = 0; - j->pld_slicw.bits.c3 = 1; - j->pld_slicw.bits.b2en = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_STANDBY: - j->pld_slicw.bits.c1 = 1; - j->pld_slicw.bits.c2 = 0; - j->pld_slicw.bits.c3 = 1; - j->pld_slicw.bits.b2en = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_APR: /* Active polarity reversal */ - - j->pld_slicw.bits.c1 = 0; - j->pld_slicw.bits.c2 = 1; - j->pld_slicw.bits.c3 = 1; - j->pld_slicw.bits.b2en = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */ - - j->pld_slicw.bits.c1 = 1; - j->pld_slicw.bits.c2 = 1; - j->pld_slicw.bits.c3 = 1; - j->pld_slicw.bits.b2en = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - fRetVal = true; - break; - default: - fRetVal = false; - break; - } - } - - return fRetVal; -} - -static int ixj_wink(IXJ *j) -{ - BYTE slicnow; - - slicnow = SLIC_GetState(j); - - j->pots_winkstart = jiffies; - SLIC_SetState(PLD_SLIC_STATE_OC, j); - - msleep(jiffies_to_msecs(j->winktime)); - - SLIC_SetState(slicnow, j); - return 0; -} - -static void ixj_init_timer(IXJ *j) -{ - init_timer(&j->timer); - j->timer.function = ixj_timeout; - j->timer.data = (unsigned long)j; -} - -static void ixj_add_timer(IXJ *j) -{ - j->timer.expires = jiffies + (hertz / samplerate); - add_timer(&j->timer); -} - -static void ixj_tone_timeout(IXJ *j) -{ - IXJ_TONE ti; - - j->tone_state++; - if (j->tone_state == 3) { - j->tone_state = 0; - if (j->cadence_t) { - j->tone_cadence_state++; - if (j->tone_cadence_state >= j->cadence_t->elements_used) { - switch (j->cadence_t->termination) { - case PLAY_ONCE: - ixj_cpt_stop(j); - break; - case REPEAT_LAST_ELEMENT: - j->tone_cadence_state--; - ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index); - break; - case REPEAT_ALL: - j->tone_cadence_state = 0; - if (j->cadence_t->ce[j->tone_cadence_state].freq0) { - ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index; - ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0; - ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0; - ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1; - ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1; - ixj_init_tone(j, &ti); - } - ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, j); - ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, j); - ixj_play_tone(j, j->cadence_t->ce[0].index); - break; - } - } else { - if (j->cadence_t->ce[j->tone_cadence_state].gain0) { - ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index; - ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0; - ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0; - ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1; - ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1; - ixj_init_tone(j, &ti); - } - ixj_set_tone_on(j->cadence_t->ce[j->tone_cadence_state].tone_on_time, j); - ixj_set_tone_off(j->cadence_t->ce[j->tone_cadence_state].tone_off_time, j); - ixj_play_tone(j, j->cadence_t->ce[j->tone_cadence_state].index); - } - } - } -} - -static inline void ixj_kill_fasync(IXJ *j, IXJ_SIGEVENT event, int dir) -{ - if(j->ixj_signals[event]) { - if(ixjdebug & 0x0100) - printk("Sending signal for event %d\n", event); - /* Send apps notice of change */ - /* see config.h for macro definition */ - kill_fasync(&(j->async_queue), j->ixj_signals[event], dir); - } -} - -static void ixj_pstn_state(IXJ *j) -{ - int var; - union XOPXR0 XR0, daaint; - - var = 10; - - XR0.reg = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg; - daaint.reg = 0; - XR0.bitreg.RMR = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR; - - j->pld_scrr.byte = inb_p(j->XILINXbase); - if (j->pld_scrr.bits.daaflag) { - daa_int_read(j); - if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) { - if(time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) { - daaint.bitreg.RING = 1; - if(ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ DAA Ring Interrupt /dev/phone%d at %ld\n", j->board, jiffies); - } - } else { - daa_set_mode(j, SOP_PU_RESET); - } - } - if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) { - daaint.bitreg.Caller_ID = 1; - j->pstn_cid_intr = 1; - j->pstn_cid_received = jiffies; - if(ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ DAA Caller_ID Interrupt /dev/phone%d at %ld\n", j->board, jiffies); - } - } - if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) { - daaint.bitreg.Cadence = 1; - if(ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ DAA Cadence Interrupt /dev/phone%d at %ld\n", j->board, jiffies); - } - } - if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK != XR0.bitreg.VDD_OK) { - daaint.bitreg.VDD_OK = 1; - daaint.bitreg.SI_0 = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK; - } - } - daa_CR_read(j, 1); - if(j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR != XR0.bitreg.RMR && time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) { - daaint.bitreg.RMR = 1; - daaint.bitreg.SI_1 = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR; - if(ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ DAA RMR /dev/phone%d was %s for %ld\n", j->board, XR0.bitreg.RMR?"on":"off", jiffies - j->pstn_last_rmr); - } - j->pstn_prev_rmr = j->pstn_last_rmr; - j->pstn_last_rmr = jiffies; - } - switch(j->daa_mode) { - case SOP_PU_SLEEP: - if (daaint.bitreg.RING) { - if (!j->flags.pstn_ringing) { - if (j->daa_mode != SOP_PU_RINGING) { - j->pstn_ring_int = jiffies; - daa_set_mode(j, SOP_PU_RINGING); - } - } - } - break; - case SOP_PU_RINGING: - if (daaint.bitreg.RMR) { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence a state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies); - } - if (daaint.bitreg.SI_1) { /* Rising edge of RMR */ - j->flags.pstn_rmr = 1; - j->pstn_ring_start = jiffies; - j->pstn_ring_stop = 0; - j->ex.bits.pstn_ring = 0; - if (j->cadence_f[4].state == 0) { - j->cadence_f[4].state = 1; - j->cadence_f[4].on1min = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 - var)) / 10000); - j->cadence_f[4].on1dot = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100)) / 10000); - j->cadence_f[4].on1max = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 + var)) / 10000); - } else if (j->cadence_f[4].state == 2) { - if((time_after(jiffies, j->cadence_f[4].off1min) && - time_before(jiffies, j->cadence_f[4].off1max))) { - if (j->cadence_f[4].on2) { - j->cadence_f[4].state = 3; - j->cadence_f[4].on2min = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 - var)) / 10000)); - j->cadence_f[4].on2dot = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100)) / 10000)); - j->cadence_f[4].on2max = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[4].state = 7; - } - } else { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", - j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, - j->cadence_f[4].off1); - } - j->cadence_f[4].state = 0; - } - } else if (j->cadence_f[4].state == 4) { - if((time_after(jiffies, j->cadence_f[4].off2min) && - time_before(jiffies, j->cadence_f[4].off2max))) { - if (j->cadence_f[4].on3) { - j->cadence_f[4].state = 5; - j->cadence_f[4].on3min = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 - var)) / 10000)); - j->cadence_f[4].on3dot = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100)) / 10000)); - j->cadence_f[4].on3max = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[4].state = 7; - } - } else { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", - j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, - j->cadence_f[4].off2); - } - j->cadence_f[4].state = 0; - } - } else if (j->cadence_f[4].state == 6) { - if((time_after(jiffies, j->cadence_f[4].off3min) && - time_before(jiffies, j->cadence_f[4].off3max))) { - j->cadence_f[4].state = 7; - } else { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", - j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, - j->cadence_f[4].off3); - } - j->cadence_f[4].state = 0; - } - } else { - j->cadence_f[4].state = 0; - } - } else { /* Falling edge of RMR */ - j->pstn_ring_start = 0; - j->pstn_ring_stop = jiffies; - if (j->cadence_f[4].state == 1) { - if(!j->cadence_f[4].on1) { - j->cadence_f[4].state = 7; - } else if((time_after(jiffies, j->cadence_f[4].on1min) && - time_before(jiffies, j->cadence_f[4].on1max))) { - if (j->cadence_f[4].off1) { - j->cadence_f[4].state = 2; - j->cadence_f[4].off1min = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 - var)) / 10000)); - j->cadence_f[4].off1dot = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100)) / 10000)); - j->cadence_f[4].off1max = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[4].state = 7; - } - } else { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", - j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, - j->cadence_f[4].on1); - } - j->cadence_f[4].state = 0; - } - } else if (j->cadence_f[4].state == 3) { - if((time_after(jiffies, j->cadence_f[4].on2min) && - time_before(jiffies, j->cadence_f[4].on2max))) { - if (j->cadence_f[4].off2) { - j->cadence_f[4].state = 4; - j->cadence_f[4].off2min = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 - var)) / 10000)); - j->cadence_f[4].off2dot = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100)) / 10000)); - j->cadence_f[4].off2max = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[4].state = 7; - } - } else { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", - j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, - j->cadence_f[4].on2); - } - j->cadence_f[4].state = 0; - } - } else if (j->cadence_f[4].state == 5) { - if((time_after(jiffies, j->cadence_f[4].on3min) && - time_before(jiffies, j->cadence_f[4].on3max))) { - if (j->cadence_f[4].off3) { - j->cadence_f[4].state = 6; - j->cadence_f[4].off3min = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 - var)) / 10000)); - j->cadence_f[4].off3dot = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100)) / 10000)); - j->cadence_f[4].off3max = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[4].state = 7; - } - } else { - j->cadence_f[4].state = 0; - } - } else { - if (ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n", - j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr, - j->cadence_f[4].on3); - } - j->cadence_f[4].state = 0; - } - } - if (ixjdebug & 0x0010) { - printk(KERN_INFO "IXJ Ring Cadence b state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies); - } - if (ixjdebug & 0x0010) { - switch(j->cadence_f[4].state) { - case 1: - printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, - j->cadence_f[4].on1, j->cadence_f[4].on1min, j->cadence_f[4].on1dot, j->cadence_f[4].on1max); - break; - case 2: - printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, - j->cadence_f[4].off1, j->cadence_f[4].off1min, j->cadence_f[4].off1dot, j->cadence_f[4].off1max); - break; - case 3: - printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, - j->cadence_f[4].on2, j->cadence_f[4].on2min, j->cadence_f[4].on2dot, j->cadence_f[4].on2max); - break; - case 4: - printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, - j->cadence_f[4].off2, j->cadence_f[4].off2min, j->cadence_f[4].off2dot, j->cadence_f[4].off2max); - break; - case 5: - printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, - j->cadence_f[4].on3, j->cadence_f[4].on3min, j->cadence_f[4].on3dot, j->cadence_f[4].on3max); - break; - case 6: - printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board, - j->cadence_f[4].off3, j->cadence_f[4].off3min, j->cadence_f[4].off3dot, j->cadence_f[4].off3max); - break; - } - } - } - if (j->cadence_f[4].state == 7) { - j->cadence_f[4].state = 0; - j->pstn_ring_stop = jiffies; - j->ex.bits.pstn_ring = 1; - ixj_kill_fasync(j, SIG_PSTN_RING, POLL_IN); - if(ixjdebug & 0x0008) { - printk(KERN_INFO "IXJ Ring int set /dev/phone%d at %ld\n", j->board, jiffies); - } - } - if((j->pstn_ring_int != 0 && time_after(jiffies, j->pstn_ring_int + (hertz * 5)) && !j->flags.pstn_rmr) || - (j->pstn_ring_stop != 0 && time_after(jiffies, j->pstn_ring_stop + (hertz * 5)))) { - if(ixjdebug & 0x0008) { - printk("IXJ DAA no ring in 5 seconds /dev/phone%d at %ld\n", j->board, jiffies); - printk("IXJ DAA pstn ring int /dev/phone%d at %ld\n", j->board, j->pstn_ring_int); - printk("IXJ DAA pstn ring stop /dev/phone%d at %ld\n", j->board, j->pstn_ring_stop); - } - j->pstn_ring_stop = j->pstn_ring_int = 0; - daa_set_mode(j, SOP_PU_SLEEP); - } - outb_p(j->pld_scrw.byte, j->XILINXbase); - if (j->pstn_cid_intr && time_after(jiffies, j->pstn_cid_received + hertz)) { - ixj_daa_cid_read(j); - j->ex.bits.caller_id = 1; - ixj_kill_fasync(j, SIG_CALLER_ID, POLL_IN); - j->pstn_cid_intr = 0; - } - if (daaint.bitreg.Cadence) { - if(ixjdebug & 0x0008) { - printk("IXJ DAA Cadence interrupt going to sleep /dev/phone%d\n", j->board); - } - daa_set_mode(j, SOP_PU_SLEEP); - j->ex.bits.pstn_ring = 0; - } - break; - case SOP_PU_CONVERSATION: - if (daaint.bitreg.VDD_OK) { - if(!daaint.bitreg.SI_0) { - if (!j->pstn_winkstart) { - if(ixjdebug & 0x0008) { - printk("IXJ DAA possible wink /dev/phone%d %ld\n", j->board, jiffies); - } - j->pstn_winkstart = jiffies; - } - } else { - if (j->pstn_winkstart) { - if(ixjdebug & 0x0008) { - printk("IXJ DAA possible wink end /dev/phone%d %ld\n", j->board, jiffies); - } - j->pstn_winkstart = 0; - } - } - } - if (j->pstn_winkstart && time_after(jiffies, j->pstn_winkstart + ((hertz * j->winktime) / 1000))) { - if(ixjdebug & 0x0008) { - printk("IXJ DAA wink detected going to sleep /dev/phone%d %ld\n", j->board, jiffies); - } - daa_set_mode(j, SOP_PU_SLEEP); - j->pstn_winkstart = 0; - j->ex.bits.pstn_wink = 1; - ixj_kill_fasync(j, SIG_PSTN_WINK, POLL_IN); - } - break; - } -} - -static void ixj_timeout(unsigned long ptr) -{ - int board; - unsigned long jifon; - IXJ *j = (IXJ *)ptr; - board = j->board; - - if (j->DSPbase && atomic_read(&j->DSPWrite) == 0 && test_and_set_bit(board, (void *)&j->busyflags) == 0) { - ixj_perfmon(j->timerchecks); - j->hookstate = ixj_hookstate(j); - if (j->tone_state) { - if (!(j->hookstate)) { - ixj_cpt_stop(j); - if (j->m_hook) { - j->m_hook = 0; - j->ex.bits.hookstate = 1; - ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN); - } - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } - if (j->tone_state == 1) - jifon = ((hertz * j->tone_on_time) * 25 / 100000); - else - jifon = ((hertz * j->tone_on_time) * 25 / 100000) + ((hertz * j->tone_off_time) * 25 / 100000); - if (time_before(jiffies, j->tone_start_jif + jifon)) { - if (j->tone_state == 1) { - ixj_play_tone(j, j->tone_index); - if (j->dsp.low == 0x20) { - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } - } else { - ixj_play_tone(j, 0); - if (j->dsp.low == 0x20) { - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } - } - } else { - ixj_tone_timeout(j); - if (j->flags.dialtone) { - ixj_dialtone(j); - } - if (j->flags.busytone) { - ixj_busytone(j); - if (j->dsp.low == 0x20) { - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } - } - if (j->flags.ringback) { - ixj_ringback(j); - if (j->dsp.low == 0x20) { - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } - } - if (!j->tone_state) { - ixj_cpt_stop(j); - } - } - } - if (!(j->tone_state && j->dsp.low == 0x20)) { - if (IsRxReady(j)) { - ixj_read_frame(j); - } - if (IsTxReady(j)) { - ixj_write_frame(j); - } - } - if (j->flags.cringing) { - if (j->hookstate & 1) { - j->flags.cringing = 0; - ixj_ring_off(j); - } else if(j->cadence_f[5].enable && ((!j->cadence_f[5].en_filter) || (j->cadence_f[5].en_filter && j->flags.firstring))) { - switch(j->cadence_f[5].state) { - case 0: - j->cadence_f[5].on1dot = jiffies + (long)((j->cadence_f[5].on1 * (hertz * 100) / 10000)); - if (time_before(jiffies, j->cadence_f[5].on1dot)) { - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - ixj_ring_on(j); - } - j->cadence_f[5].state = 1; - break; - case 1: - if (time_after(jiffies, j->cadence_f[5].on1dot)) { - j->cadence_f[5].off1dot = jiffies + (long)((j->cadence_f[5].off1 * (hertz * 100) / 10000)); - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - ixj_ring_off(j); - j->cadence_f[5].state = 2; - } - break; - case 2: - if (time_after(jiffies, j->cadence_f[5].off1dot)) { - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - ixj_ring_on(j); - if (j->cadence_f[5].on2) { - j->cadence_f[5].on2dot = jiffies + (long)((j->cadence_f[5].on2 * (hertz * 100) / 10000)); - j->cadence_f[5].state = 3; - } else { - j->cadence_f[5].state = 7; - } - } - break; - case 3: - if (time_after(jiffies, j->cadence_f[5].on2dot)) { - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - ixj_ring_off(j); - if (j->cadence_f[5].off2) { - j->cadence_f[5].off2dot = jiffies + (long)((j->cadence_f[5].off2 * (hertz * 100) / 10000)); - j->cadence_f[5].state = 4; - } else { - j->cadence_f[5].state = 7; - } - } - break; - case 4: - if (time_after(jiffies, j->cadence_f[5].off2dot)) { - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - ixj_ring_on(j); - if (j->cadence_f[5].on3) { - j->cadence_f[5].on3dot = jiffies + (long)((j->cadence_f[5].on3 * (hertz * 100) / 10000)); - j->cadence_f[5].state = 5; - } else { - j->cadence_f[5].state = 7; - } - } - break; - case 5: - if (time_after(jiffies, j->cadence_f[5].on3dot)) { - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - ixj_ring_off(j); - if (j->cadence_f[5].off3) { - j->cadence_f[5].off3dot = jiffies + (long)((j->cadence_f[5].off3 * (hertz * 100) / 10000)); - j->cadence_f[5].state = 6; - } else { - j->cadence_f[5].state = 7; - } - } - break; - case 6: - if (time_after(jiffies, j->cadence_f[5].off3dot)) { - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - j->cadence_f[5].state = 7; - } - break; - case 7: - if(ixjdebug & 0x0004) { - printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies); - } - j->flags.cidring = 1; - j->cadence_f[5].state = 0; - break; - } - if (j->flags.cidring && !j->flags.cidsent) { - j->flags.cidsent = 1; - if(j->fskdcnt) { - SLIC_SetState(PLD_SLIC_STATE_OHT, j); - ixj_pre_cid(j); - } - j->flags.cidring = 0; - } - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } else { - if (time_after(jiffies, j->ring_cadence_jif + (hertz / 2))) { - if (j->flags.cidring && !j->flags.cidsent) { - j->flags.cidsent = 1; - if(j->fskdcnt) { - SLIC_SetState(PLD_SLIC_STATE_OHT, j); - ixj_pre_cid(j); - } - j->flags.cidring = 0; - } - j->ring_cadence_t--; - if (j->ring_cadence_t == -1) - j->ring_cadence_t = 15; - j->ring_cadence_jif = jiffies; - - if (j->ring_cadence & 1 << j->ring_cadence_t) { - if(j->flags.cidsent && j->cadence_f[5].en_filter) - j->flags.firstring = 1; - else - ixj_ring_on(j); - } else { - ixj_ring_off(j); - if(!j->flags.cidsent) - j->flags.cidring = 1; - } - } - clear_bit(board, &j->busyflags); - ixj_add_timer(j); - return; - } - } - if (!j->flags.ringing) { - if (j->hookstate) { /* & 1) { */ - if (j->dsp.low != 0x20 && - SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) { - SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); - } - LineMonitor(j); - read_filters(j); - ixj_WriteDSPCommand(0x511B, j); - j->proc_load = j->ssr.high << 8 | j->ssr.low; - if (!j->m_hook && (j->hookstate & 1)) { - j->m_hook = j->ex.bits.hookstate = 1; - ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN); - } - } else { - if (j->ex.bits.dtmf_ready) { - j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0; - } - if (j->m_hook) { - j->m_hook = 0; - j->ex.bits.hookstate = 1; - ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN); - } - } - } - if (j->cardtype == QTI_LINEJACK && !j->flags.pstncheck && j->flags.pstn_present) { - ixj_pstn_state(j); - } - if (j->ex.bytes) { - wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ - } - clear_bit(board, &j->busyflags); - } - ixj_add_timer(j); -} - -static int ixj_status_wait(IXJ *j) -{ - unsigned long jif; - - jif = jiffies + ((60 * hertz) / 100); - while (!IsStatusReady(j)) { - ixj_perfmon(j->statuswait); - if (time_after(jiffies, jif)) { - ixj_perfmon(j->statuswaitfail); - return -1; - } - } - return 0; -} - -static int ixj_PCcontrol_wait(IXJ *j) -{ - unsigned long jif; - - jif = jiffies + ((60 * hertz) / 100); - while (!IsPCControlReady(j)) { - ixj_perfmon(j->pcontrolwait); - if (time_after(jiffies, jif)) { - ixj_perfmon(j->pcontrolwaitfail); - return -1; - } - } - return 0; -} - -static int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j) -{ - BYTES bytes; - unsigned long jif; - - atomic_inc(&j->DSPWrite); - if(atomic_read(&j->DSPWrite) > 1) { - printk("IXJ %d DSP write overlap attempting command 0x%4.4x\n", j->board, cmd); - return -1; - } - bytes.high = (cmd & 0xFF00) >> 8; - bytes.low = cmd & 0x00FF; - jif = jiffies + ((60 * hertz) / 100); - while (!IsControlReady(j)) { - ixj_perfmon(j->iscontrolready); - if (time_after(jiffies, jif)) { - ixj_perfmon(j->iscontrolreadyfail); - atomic_dec(&j->DSPWrite); - if(atomic_read(&j->DSPWrite) > 0) { - printk("IXJ %d DSP overlaped command 0x%4.4x during control ready failure.\n", j->board, cmd); - while(atomic_read(&j->DSPWrite) > 0) { - atomic_dec(&j->DSPWrite); - } - } - return -1; - } - } - outb(bytes.low, j->DSPbase + 6); - outb(bytes.high, j->DSPbase + 7); - - if (ixj_status_wait(j)) { - j->ssr.low = 0xFF; - j->ssr.high = 0xFF; - atomic_dec(&j->DSPWrite); - if(atomic_read(&j->DSPWrite) > 0) { - printk("IXJ %d DSP overlaped command 0x%4.4x during status wait failure.\n", j->board, cmd); - while(atomic_read(&j->DSPWrite) > 0) { - atomic_dec(&j->DSPWrite); - } - } - return -1; - } -/* Read Software Status Register */ - j->ssr.low = inb_p(j->DSPbase + 2); - j->ssr.high = inb_p(j->DSPbase + 3); - atomic_dec(&j->DSPWrite); - if(atomic_read(&j->DSPWrite) > 0) { - printk("IXJ %d DSP overlaped command 0x%4.4x\n", j->board, cmd); - while(atomic_read(&j->DSPWrite) > 0) { - atomic_dec(&j->DSPWrite); - } - } - return 0; -} - -/*************************************************************************** -* -* General Purpose IO Register read routine -* -***************************************************************************/ -static inline int ixj_gpio_read(IXJ *j) -{ - if (ixj_WriteDSPCommand(0x5143, j)) - return -1; - - j->gpio.bytes.low = j->ssr.low; - j->gpio.bytes.high = j->ssr.high; - - return 0; -} - -static inline void LED_SetState(int state, IXJ *j) -{ - if (j->cardtype == QTI_LINEJACK) { - j->pld_scrw.bits.led1 = state & 0x1 ? 1 : 0; - j->pld_scrw.bits.led2 = state & 0x2 ? 1 : 0; - j->pld_scrw.bits.led3 = state & 0x4 ? 1 : 0; - j->pld_scrw.bits.led4 = state & 0x8 ? 1 : 0; - - outb(j->pld_scrw.byte, j->XILINXbase); - } -} - -/********************************************************************* -* GPIO Pins are configured as follows on the Quicknet Internet -* PhoneJACK Telephony Cards -* -* POTS Select GPIO_6=0 GPIO_7=0 -* Mic/Speaker Select GPIO_6=0 GPIO_7=1 -* Handset Select GPIO_6=1 GPIO_7=0 -* -* SLIC Active GPIO_1=0 GPIO_2=1 GPIO_5=0 -* SLIC Ringing GPIO_1=1 GPIO_2=1 GPIO_5=0 -* SLIC Open Circuit GPIO_1=0 GPIO_2=0 GPIO_5=0 -* -* Hook Switch changes reported on GPIO_3 -*********************************************************************/ -static int ixj_set_port(IXJ *j, int arg) -{ - if (j->cardtype == QTI_PHONEJACK_LITE) { - if (arg != PORT_POTS) - return 10; - else - return 0; - } - switch (arg) { - case PORT_POTS: - j->port = PORT_POTS; - switch (j->cardtype) { - case QTI_PHONECARD: - if (j->flags.pcmciasct == 1) - SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); - else - return 11; - break; - case QTI_PHONEJACK_PCI: - j->pld_slicw.pcib.mic = 0; - j->pld_slicw.pcib.spk = 0; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - break; - case QTI_LINEJACK: - ixj_set_pots(j, 0); /* Disconnect POTS/PSTN relay */ - if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to - Software Control Register */ - return 2; - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb(j->pld_scrw.byte, j->XILINXbase); - j->pld_clock.byte = 0; - outb(j->pld_clock.byte, j->XILINXbase + 0x04); - j->pld_slicw.bits.rly1 = 1; - j->pld_slicw.bits.spken = 0; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - ixj_mixer(0x1200, j); /* Turn Off MIC switch on mixer left */ - ixj_mixer(0x1401, j); /* Turn On Mono1 switch on mixer left */ - ixj_mixer(0x1300, j); /* Turn Off MIC switch on mixer right */ - ixj_mixer(0x1501, j); /* Turn On Mono1 switch on mixer right */ - ixj_mixer(0x0E80, j); /*Mic mute */ - ixj_mixer(0x0F00, j); /* Set mono out (SLIC) to 0dB */ - ixj_mixer(0x0080, j); /* Mute Master Left volume */ - ixj_mixer(0x0180, j); /* Mute Master Right volume */ - SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); -/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */ - break; - case QTI_PHONEJACK: - j->gpio.bytes.high = 0x0B; - j->gpio.bits.gpio6 = 0; - j->gpio.bits.gpio7 = 0; - ixj_WriteDSPCommand(j->gpio.word, j); - break; - } - break; - case PORT_PSTN: - if (j->cardtype == QTI_LINEJACK) { - ixj_WriteDSPCommand(0xC534, j); /* Write CODEC config to Software Control Register */ - - j->pld_slicw.bits.rly3 = 0; - j->pld_slicw.bits.rly1 = 1; - j->pld_slicw.bits.spken = 0; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - j->port = PORT_PSTN; - } else { - return 4; - } - break; - case PORT_SPEAKER: - j->port = PORT_SPEAKER; - switch (j->cardtype) { - case QTI_PHONECARD: - if (j->flags.pcmciasct) { - SLIC_SetState(PLD_SLIC_STATE_OC, j); - } - break; - case QTI_PHONEJACK_PCI: - j->pld_slicw.pcib.mic = 1; - j->pld_slicw.pcib.spk = 1; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - break; - case QTI_LINEJACK: - ixj_set_pots(j, 0); /* Disconnect POTS/PSTN relay */ - if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to - Software Control Register */ - return 2; - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb(j->pld_scrw.byte, j->XILINXbase); - j->pld_clock.byte = 0; - outb(j->pld_clock.byte, j->XILINXbase + 0x04); - j->pld_slicw.bits.rly1 = 1; - j->pld_slicw.bits.spken = 1; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - ixj_mixer(0x1201, j); /* Turn On MIC switch on mixer left */ - ixj_mixer(0x1400, j); /* Turn Off Mono1 switch on mixer left */ - ixj_mixer(0x1301, j); /* Turn On MIC switch on mixer right */ - ixj_mixer(0x1500, j); /* Turn Off Mono1 switch on mixer right */ - ixj_mixer(0x0E06, j); /*Mic un-mute 0dB */ - ixj_mixer(0x0F80, j); /* Mute mono out (SLIC) */ - ixj_mixer(0x0000, j); /* Set Master Left volume to 0dB */ - ixj_mixer(0x0100, j); /* Set Master Right volume to 0dB */ - break; - case QTI_PHONEJACK: - j->gpio.bytes.high = 0x0B; - j->gpio.bits.gpio6 = 0; - j->gpio.bits.gpio7 = 1; - ixj_WriteDSPCommand(j->gpio.word, j); - break; - } - break; - case PORT_HANDSET: - if (j->cardtype != QTI_PHONEJACK) { - return 5; - } else { - j->gpio.bytes.high = 0x0B; - j->gpio.bits.gpio6 = 1; - j->gpio.bits.gpio7 = 0; - ixj_WriteDSPCommand(j->gpio.word, j); - j->port = PORT_HANDSET; - } - break; - default: - return 6; - break; - } - return 0; -} - -static int ixj_set_pots(IXJ *j, int arg) -{ - if (j->cardtype == QTI_LINEJACK) { - if (arg) { - if (j->port == PORT_PSTN) { - j->pld_slicw.bits.rly1 = 0; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - j->flags.pots_pstn = 1; - return 1; - } else { - j->flags.pots_pstn = 0; - return 0; - } - } else { - j->pld_slicw.bits.rly1 = 1; - outb(j->pld_slicw.byte, j->XILINXbase + 0x01); - j->flags.pots_pstn = 0; - return 1; - } - } else { - return 0; - } -} - -static void ixj_ring_on(IXJ *j) -{ - if (j->dsp.low == 0x20) /* Internet PhoneJACK */ - { - if (ixjdebug & 0x0004) - printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board); - - j->gpio.bytes.high = 0x0B; - j->gpio.bytes.low = 0x00; - j->gpio.bits.gpio1 = 1; - j->gpio.bits.gpio2 = 1; - j->gpio.bits.gpio5 = 0; - ixj_WriteDSPCommand(j->gpio.word, j); /* send the ring signal */ - } else /* Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI */ - { - if (ixjdebug & 0x0004) - printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board); - - SLIC_SetState(PLD_SLIC_STATE_RINGING, j); - } -} - -static int ixj_siadc(IXJ *j, int val) -{ - if(j->cardtype == QTI_PHONECARD){ - if(j->flags.pcmciascp){ - if(val == -1) - return j->siadc.bits.rxg; - - if(val < 0 || val > 0x1F) - return -1; - - j->siadc.bits.hom = 0; /* Handset Out Mute */ - j->siadc.bits.lom = 0; /* Line Out Mute */ - j->siadc.bits.rxg = val; /*(0xC000 - 0x41C8) / 0x4EF; RX PGA Gain */ - j->psccr.bits.addr = 6; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(j->siadc.byte, j->XILINXbase + 0x00); - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - return j->siadc.bits.rxg; - } - } - return -1; -} - -static int ixj_sidac(IXJ *j, int val) -{ - if(j->cardtype == QTI_PHONECARD){ - if(j->flags.pcmciascp){ - if(val == -1) - return j->sidac.bits.txg; - - if(val < 0 || val > 0x1F) - return -1; - - j->sidac.bits.srm = 1; /* Speaker Right Mute */ - j->sidac.bits.slm = 1; /* Speaker Left Mute */ - j->sidac.bits.txg = val; /* (0xC000 - 0x45E4) / 0x5D3; TX PGA Gain */ - j->psccr.bits.addr = 7; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(j->sidac.byte, j->XILINXbase + 0x00); - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - return j->sidac.bits.txg; - } - } - return -1; -} - -static int ixj_pcmcia_cable_check(IXJ *j) -{ - j->pccr1.byte = inb_p(j->XILINXbase + 0x03); - if (!j->flags.pcmciastate) { - j->pccr2.byte = inb_p(j->XILINXbase + 0x02); - if (j->pccr1.bits.drf || j->pccr2.bits.rstc) { - j->flags.pcmciastate = 4; - return 0; - } - if (j->pccr1.bits.ed) { - j->pccr1.bits.ed = 0; - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 1; - outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00); - ixj_PCcontrol_wait(j); - j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF; - j->pslic.bits.led2 = j->pslic.bits.det ? 1 : 0; - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 0; - outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00); - ixj_PCcontrol_wait(j); - return j->pslic.bits.led2 ? 1 : 0; - } else if (j->flags.pcmciasct) { - return j->r_hook; - } else { - return 1; - } - } else if (j->flags.pcmciastate == 4) { - if (!j->pccr1.bits.drf) { - j->flags.pcmciastate = 3; - } - return 0; - } else if (j->flags.pcmciastate == 3) { - j->pccr2.bits.pwr = 0; - j->pccr2.bits.rstc = 1; - outb(j->pccr2.byte, j->XILINXbase + 0x02); - j->checkwait = jiffies + (hertz * 2); - j->flags.incheck = 1; - j->flags.pcmciastate = 2; - return 0; - } else if (j->flags.pcmciastate == 2) { - if (j->flags.incheck) { - if (time_before(jiffies, j->checkwait)) { - return 0; - } else { - j->flags.incheck = 0; - } - } - j->pccr2.bits.pwr = 0; - j->pccr2.bits.rstc = 0; - outb_p(j->pccr2.byte, j->XILINXbase + 0x02); - j->flags.pcmciastate = 1; - return 0; - } else if (j->flags.pcmciastate == 1) { - j->flags.pcmciastate = 0; - if (!j->pccr1.bits.drf) { - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 1; - outb_p(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - j->flags.pcmciascp = 1; /* Set Cable Present Flag */ - - j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03; /* Get Cable Type */ - - if (j->flags.pcmciasct == 3) { - j->flags.pcmciastate = 4; - return 0; - } else if (j->flags.pcmciasct == 0) { - j->pccr2.bits.pwr = 1; - j->pccr2.bits.rstc = 0; - outb_p(j->pccr2.byte, j->XILINXbase + 0x02); - j->port = PORT_SPEAKER; - } else { - j->port = PORT_POTS; - } - j->sic1.bits.cpd = 0; /* Chip Power Down */ - j->sic1.bits.mpd = 0; /* MIC Bias Power Down */ - j->sic1.bits.hpd = 0; /* Handset Bias Power Down */ - j->sic1.bits.lpd = 0; /* Line Bias Power Down */ - j->sic1.bits.spd = 1; /* Speaker Drive Power Down */ - j->psccr.bits.addr = 1; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(j->sic1.byte, j->XILINXbase + 0x00); - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - - j->sic2.bits.al = 0; /* Analog Loopback DAC analog -> ADC analog */ - j->sic2.bits.dl2 = 0; /* Digital Loopback DAC -> ADC one bit */ - j->sic2.bits.dl1 = 0; /* Digital Loopback ADC -> DAC one bit */ - j->sic2.bits.pll = 0; /* 1 = div 10, 0 = div 5 */ - j->sic2.bits.hpd = 0; /* HPF disable */ - j->psccr.bits.addr = 2; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(j->sic2.byte, j->XILINXbase + 0x00); - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - - j->psccr.bits.addr = 3; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(0x00, j->XILINXbase + 0x00); /* PLL Divide N1 */ - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - - j->psccr.bits.addr = 4; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(0x09, j->XILINXbase + 0x00); /* PLL Multiply M1 */ - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - - j->sirxg.bits.lig = 1; /* Line In Gain */ - j->sirxg.bits.lim = 1; /* Line In Mute */ - j->sirxg.bits.mcg = 0; /* MIC In Gain was 3 */ - j->sirxg.bits.mcm = 0; /* MIC In Mute */ - j->sirxg.bits.him = 0; /* Handset In Mute */ - j->sirxg.bits.iir = 1; /* IIR */ - j->psccr.bits.addr = 5; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(j->sirxg.byte, j->XILINXbase + 0x00); - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - - ixj_siadc(j, 0x17); - ixj_sidac(j, 0x1D); - - j->siaatt.bits.sot = 0; - j->psccr.bits.addr = 9; /* R/W Smart Cable Register Address */ - j->psccr.bits.rw = 0; /* Read / Write flag */ - j->psccr.bits.dev = 0; - outb(j->siaatt.byte, j->XILINXbase + 0x00); - outb(j->psccr.byte, j->XILINXbase + 0x01); - ixj_PCcontrol_wait(j); - - if (j->flags.pcmciasct == 1 && !j->readers && !j->writers) { - j->psccr.byte = j->pslic.byte = 0; - j->pslic.bits.powerdown = 1; - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 0; - outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00); - ixj_PCcontrol_wait(j); - } - } - return 0; - } else { - j->flags.pcmciascp = 0; - return 0; - } - return 0; -} - -static int ixj_hookstate(IXJ *j) -{ - int fOffHook = 0; - - switch (j->cardtype) { - case QTI_PHONEJACK: - ixj_gpio_read(j); - fOffHook = j->gpio.bits.gpio3read ? 1 : 0; - break; - case QTI_LINEJACK: - case QTI_PHONEJACK_LITE: - case QTI_PHONEJACK_PCI: - SLIC_GetState(j); - if(j->cardtype == QTI_LINEJACK && j->flags.pots_pstn == 1 && (j->readers || j->writers)) { - fOffHook = j->pld_slicr.bits.potspstn ? 1 : 0; - if(fOffHook != j->p_hook) { - if(!j->checkwait) { - j->checkwait = jiffies; - } - if(time_before(jiffies, j->checkwait + 2)) { - fOffHook ^= 1; - } else { - j->checkwait = 0; - } - j->p_hook = fOffHook; - printk("IXJ : /dev/phone%d pots-pstn hookstate check %d at %ld\n", j->board, fOffHook, jiffies); - } - } else { - if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE || - j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) { - if (j->flags.ringing || j->flags.cringing) { - if (!in_interrupt()) { - msleep(20); - } - SLIC_GetState(j); - if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) { - ixj_ring_on(j); - } - } - if (j->cardtype == QTI_PHONEJACK_PCI) { - j->pld_scrr.byte = inb_p(j->XILINXbase); - fOffHook = j->pld_scrr.pcib.det ? 1 : 0; - } else - fOffHook = j->pld_slicr.bits.det ? 1 : 0; - } - } - break; - case QTI_PHONECARD: - fOffHook = ixj_pcmcia_cable_check(j); - break; - } - if (j->r_hook != fOffHook) { - j->r_hook = fOffHook; - if (j->port == PORT_SPEAKER || j->port == PORT_HANDSET) { // || (j->port == PORT_PSTN && j->flags.pots_pstn == 0)) { - j->ex.bits.hookstate = 1; - ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN); - } else if (!fOffHook) { - j->flash_end = jiffies + ((60 * hertz) / 100); - } - } - if (fOffHook) { - if(time_before(jiffies, j->flash_end)) { - j->ex.bits.flash = 1; - j->flash_end = 0; - ixj_kill_fasync(j, SIG_FLASH, POLL_IN); - } - } else { - if(time_before(jiffies, j->flash_end)) { - fOffHook = 1; - } - } - - if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION) - fOffHook |= 2; - - if (j->port == PORT_SPEAKER) { - if(j->cardtype == QTI_PHONECARD) { - if(j->flags.pcmciascp && j->flags.pcmciasct) { - fOffHook |= 2; - } - } else { - fOffHook |= 2; - } - } - - if (j->port == PORT_HANDSET) - fOffHook |= 2; - - return fOffHook; -} - -static void ixj_ring_off(IXJ *j) -{ - if (j->dsp.low == 0x20) /* Internet PhoneJACK */ - { - if (ixjdebug & 0x0004) - printk(KERN_INFO "IXJ Ring Off\n"); - j->gpio.bytes.high = 0x0B; - j->gpio.bytes.low = 0x00; - j->gpio.bits.gpio1 = 0; - j->gpio.bits.gpio2 = 1; - j->gpio.bits.gpio5 = 0; - ixj_WriteDSPCommand(j->gpio.word, j); - } else /* Internet LineJACK */ - { - if (ixjdebug & 0x0004) - printk(KERN_INFO "IXJ Ring Off\n"); - - if(!j->flags.cidplay) - SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); - - SLIC_GetState(j); - } -} - -static void ixj_ring_start(IXJ *j) -{ - j->flags.cringing = 1; - if (ixjdebug & 0x0004) - printk(KERN_INFO "IXJ Cadence Ringing Start /dev/phone%d\n", j->board); - if (ixj_hookstate(j) & 1) { - if (j->port == PORT_POTS) - ixj_ring_off(j); - j->flags.cringing = 0; - if (ixjdebug & 0x0004) - printk(KERN_INFO "IXJ Cadence Ringing Stopped /dev/phone%d off hook\n", j->board); - } else if(j->cadence_f[5].enable && (!j->cadence_f[5].en_filter)) { - j->ring_cadence_jif = jiffies; - j->flags.cidsent = j->flags.cidring = 0; - j->cadence_f[5].state = 0; - if(j->cadence_f[5].on1) - ixj_ring_on(j); - } else { - j->ring_cadence_jif = jiffies; - j->ring_cadence_t = 15; - if (j->ring_cadence & 1 << j->ring_cadence_t) { - ixj_ring_on(j); - } else { - ixj_ring_off(j); - } - j->flags.cidsent = j->flags.cidring = j->flags.firstring = 0; - } -} - -static int ixj_ring(IXJ *j) -{ - char cntr; - unsigned long jif; - - j->flags.ringing = 1; - if (ixj_hookstate(j) & 1) { - ixj_ring_off(j); - j->flags.ringing = 0; - return 1; - } - for (cntr = 0; cntr < j->maxrings; cntr++) { - jif = jiffies + (1 * hertz); - ixj_ring_on(j); - while (time_before(jiffies, jif)) { - if (ixj_hookstate(j) & 1) { - ixj_ring_off(j); - j->flags.ringing = 0; - return 1; - } - schedule_timeout_interruptible(1); - if (signal_pending(current)) - break; - } - jif = jiffies + (3 * hertz); - ixj_ring_off(j); - while (time_before(jiffies, jif)) { - if (ixj_hookstate(j) & 1) { - msleep(10); - if (ixj_hookstate(j) & 1) { - j->flags.ringing = 0; - return 1; - } - } - schedule_timeout_interruptible(1); - if (signal_pending(current)) - break; - } - } - ixj_ring_off(j); - j->flags.ringing = 0; - return 0; -} - -static int ixj_open(struct phone_device *p, struct file *file_p) -{ - IXJ *j = get_ixj(p->board); - file_p->private_data = j; - - if (!j->DSPbase) - return -ENODEV; - - if (file_p->f_mode & FMODE_READ) { - if(!j->readers) { - j->readers++; - } else { - return -EBUSY; - } - } - - if (file_p->f_mode & FMODE_WRITE) { - if(!j->writers) { - j->writers++; - } else { - if (file_p->f_mode & FMODE_READ){ - j->readers--; - } - return -EBUSY; - } - } - - if (j->cardtype == QTI_PHONECARD) { - j->pslic.bits.powerdown = 0; - j->psccr.bits.dev = 3; - j->psccr.bits.rw = 0; - outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00); - ixj_PCcontrol_wait(j); - } - - j->flags.cidplay = 0; - j->flags.cidcw_ack = 0; - - if (ixjdebug & 0x0002) - printk(KERN_INFO "Opening board %d\n", p->board); - - j->framesread = j->frameswritten = 0; - return 0; -} - -static int ixj_release(struct inode *inode, struct file *file_p) -{ - IXJ_TONE ti; - int cnt; - IXJ *j = file_p->private_data; - int board = j->p.board; - - /* - * Set up locks to ensure that only one process is talking to the DSP at a time. - * This is necessary to keep the DSP from locking up. - */ - while(test_and_set_bit(board, (void *)&j->busyflags) != 0) - schedule_timeout_interruptible(1); - if (ixjdebug & 0x0002) - printk(KERN_INFO "Closing board %d\n", NUM(inode)); - - if (j->cardtype == QTI_PHONECARD) - ixj_set_port(j, PORT_SPEAKER); - else - ixj_set_port(j, PORT_POTS); - - aec_stop(j); - ixj_play_stop(j); - ixj_record_stop(j); - set_play_volume(j, 0x100); - set_rec_volume(j, 0x100); - ixj_ring_off(j); - - /* Restore the tone table to default settings. */ - ti.tone_index = 10; - ti.gain0 = 1; - ti.freq0 = hz941; - ti.gain1 = 0; - ti.freq1 = hz1209; - ixj_init_tone(j, &ti); - ti.tone_index = 11; - ti.gain0 = 1; - ti.freq0 = hz941; - ti.gain1 = 0; - ti.freq1 = hz1336; - ixj_init_tone(j, &ti); - ti.tone_index = 12; - ti.gain0 = 1; - ti.freq0 = hz941; - ti.gain1 = 0; - ti.freq1 = hz1477; - ixj_init_tone(j, &ti); - ti.tone_index = 13; - ti.gain0 = 1; - ti.freq0 = hz800; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 14; - ti.gain0 = 1; - ti.freq0 = hz1000; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 15; - ti.gain0 = 1; - ti.freq0 = hz1250; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 16; - ti.gain0 = 1; - ti.freq0 = hz950; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 17; - ti.gain0 = 1; - ti.freq0 = hz1100; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 18; - ti.gain0 = 1; - ti.freq0 = hz1400; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 19; - ti.gain0 = 1; - ti.freq0 = hz1500; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 20; - ti.gain0 = 1; - ti.freq0 = hz1600; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 21; - ti.gain0 = 1; - ti.freq0 = hz1800; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 22; - ti.gain0 = 1; - ti.freq0 = hz2100; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 23; - ti.gain0 = 1; - ti.freq0 = hz1300; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 24; - ti.gain0 = 1; - ti.freq0 = hz2450; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - ti.tone_index = 25; - ti.gain0 = 1; - ti.freq0 = hz350; - ti.gain1 = 0; - ti.freq1 = hz440; - ixj_init_tone(j, &ti); - ti.tone_index = 26; - ti.gain0 = 1; - ti.freq0 = hz440; - ti.gain1 = 0; - ti.freq1 = hz480; - ixj_init_tone(j, &ti); - ti.tone_index = 27; - ti.gain0 = 1; - ti.freq0 = hz480; - ti.gain1 = 0; - ti.freq1 = hz620; - ixj_init_tone(j, &ti); - - set_rec_depth(j, 2); /* Set Record Channel Limit to 2 frames */ - - set_play_depth(j, 2); /* Set Playback Channel Limit to 2 frames */ - - j->ex.bits.dtmf_ready = 0; - j->dtmf_state = 0; - j->dtmf_wp = j->dtmf_rp = 0; - j->rec_mode = j->play_mode = -1; - j->flags.ringing = 0; - j->maxrings = MAXRINGS; - j->ring_cadence = USA_RING_CADENCE; - if(j->cadence_f[5].enable) { - j->cadence_f[5].enable = j->cadence_f[5].en_filter = j->cadence_f[5].state = 0; - } - j->drybuffer = 0; - j->winktime = 320; - j->flags.dtmf_oob = 0; - for (cnt = 0; cnt < 4; cnt++) - j->cadence_f[cnt].enable = 0; - - idle(j); - - if(j->cardtype == QTI_PHONECARD) { - SLIC_SetState(PLD_SLIC_STATE_OC, j); - } - - if (file_p->f_mode & FMODE_READ) - j->readers--; - if (file_p->f_mode & FMODE_WRITE) - j->writers--; - - if (j->read_buffer && !j->readers) { - kfree(j->read_buffer); - j->read_buffer = NULL; - j->read_buffer_size = 0; - } - if (j->write_buffer && !j->writers) { - kfree(j->write_buffer); - j->write_buffer = NULL; - j->write_buffer_size = 0; - } - j->rec_codec = j->play_codec = 0; - j->rec_frame_size = j->play_frame_size = 0; - j->flags.cidsent = j->flags.cidring = 0; - - if(j->cardtype == QTI_LINEJACK && !j->readers && !j->writers) { - ixj_set_port(j, PORT_PSTN); - daa_set_mode(j, SOP_PU_SLEEP); - ixj_set_pots(j, 1); - } - ixj_WriteDSPCommand(0x0FE3, j); /* Put the DSP in 1/5 power mode. */ - - /* Set up the default signals for events */ - for (cnt = 0; cnt < 35; cnt++) - j->ixj_signals[cnt] = SIGIO; - - /* Set the excetion signal enable flags */ - j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = - j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = - j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1; - - file_p->private_data = NULL; - clear_bit(board, &j->busyflags); - return 0; -} - -static int read_filters(IXJ *j) -{ - unsigned short fc, cnt, trg; - int var; - - trg = 0; - if (ixj_WriteDSPCommand(0x5144, j)) { - if(ixjdebug & 0x0001) { - printk(KERN_INFO "Read Frame Counter failed!\n"); - } - return -1; - } - fc = j->ssr.high << 8 | j->ssr.low; - if (fc == j->frame_count) - return 1; - - j->frame_count = fc; - - if (j->dtmf_proc) - return 1; - - var = 10; - - for (cnt = 0; cnt < 4; cnt++) { - if (ixj_WriteDSPCommand(0x5154 + cnt, j)) { - if(ixjdebug & 0x0001) { - printk(KERN_INFO "Select Filter %d failed!\n", cnt); - } - return -1; - } - if (ixj_WriteDSPCommand(0x515C, j)) { - if(ixjdebug & 0x0001) { - printk(KERN_INFO "Read Filter History %d failed!\n", cnt); - } - return -1; - } - j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low; - - if (j->cadence_f[cnt].enable) { - if (j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) { - if (j->cadence_f[cnt].state == 0) { - j->cadence_f[cnt].state = 1; - j->cadence_f[cnt].on1min = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 - var)) / 10000)); - j->cadence_f[cnt].on1dot = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100)) / 10000)); - j->cadence_f[cnt].on1max = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 + var)) / 10000)); - } else if (j->cadence_f[cnt].state == 2 && - (time_after(jiffies, j->cadence_f[cnt].off1min) && - time_before(jiffies, j->cadence_f[cnt].off1max))) { - if (j->cadence_f[cnt].on2) { - j->cadence_f[cnt].state = 3; - j->cadence_f[cnt].on2min = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 - var)) / 10000)); - j->cadence_f[cnt].on2dot = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100)) / 10000)); - j->cadence_f[cnt].on2max = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[cnt].state = 7; - } - } else if (j->cadence_f[cnt].state == 4 && - (time_after(jiffies, j->cadence_f[cnt].off2min) && - time_before(jiffies, j->cadence_f[cnt].off2max))) { - if (j->cadence_f[cnt].on3) { - j->cadence_f[cnt].state = 5; - j->cadence_f[cnt].on3min = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 - var)) / 10000)); - j->cadence_f[cnt].on3dot = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100)) / 10000)); - j->cadence_f[cnt].on3max = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[cnt].state = 7; - } - } else { - j->cadence_f[cnt].state = 0; - } - } else if (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)) { - if (j->cadence_f[cnt].state == 1) { - if(!j->cadence_f[cnt].on1) { - j->cadence_f[cnt].state = 7; - } else if((time_after(jiffies, j->cadence_f[cnt].on1min) && - time_before(jiffies, j->cadence_f[cnt].on1max))) { - if(j->cadence_f[cnt].off1) { - j->cadence_f[cnt].state = 2; - j->cadence_f[cnt].off1min = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 - var)) / 10000)); - j->cadence_f[cnt].off1dot = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100)) / 10000)); - j->cadence_f[cnt].off1max = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[cnt].state = 7; - } - } else { - j->cadence_f[cnt].state = 0; - } - } else if (j->cadence_f[cnt].state == 3) { - if((time_after(jiffies, j->cadence_f[cnt].on2min) && - time_before(jiffies, j->cadence_f[cnt].on2max))) { - if(j->cadence_f[cnt].off2) { - j->cadence_f[cnt].state = 4; - j->cadence_f[cnt].off2min = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 - var)) / 10000)); - j->cadence_f[cnt].off2dot = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100)) / 10000)); - j->cadence_f[cnt].off2max = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[cnt].state = 7; - } - } else { - j->cadence_f[cnt].state = 0; - } - } else if (j->cadence_f[cnt].state == 5) { - if ((time_after(jiffies, j->cadence_f[cnt].on3min) && - time_before(jiffies, j->cadence_f[cnt].on3max))) { - if(j->cadence_f[cnt].off3) { - j->cadence_f[cnt].state = 6; - j->cadence_f[cnt].off3min = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 - var)) / 10000)); - j->cadence_f[cnt].off3dot = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100)) / 10000)); - j->cadence_f[cnt].off3max = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 + var)) / 10000)); - } else { - j->cadence_f[cnt].state = 7; - } - } else { - j->cadence_f[cnt].state = 0; - } - } else { - j->cadence_f[cnt].state = 0; - } - } else { - switch(j->cadence_f[cnt].state) { - case 1: - if(time_after(jiffies, j->cadence_f[cnt].on1dot) && - !j->cadence_f[cnt].off1 && - !j->cadence_f[cnt].on2 && !j->cadence_f[cnt].off2 && - !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) { - j->cadence_f[cnt].state = 7; - } - break; - case 3: - if(time_after(jiffies, j->cadence_f[cnt].on2dot) && - !j->cadence_f[cnt].off2 && - !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) { - j->cadence_f[cnt].state = 7; - } - break; - case 5: - if(time_after(jiffies, j->cadence_f[cnt].on3dot) && - !j->cadence_f[cnt].off3) { - j->cadence_f[cnt].state = 7; - } - break; - } - } - - if (ixjdebug & 0x0040) { - printk(KERN_INFO "IXJ Tone Cadence state = %d /dev/phone%d at %ld\n", j->cadence_f[cnt].state, j->board, jiffies); - switch(j->cadence_f[cnt].state) { - case 0: - printk(KERN_INFO "IXJ /dev/phone%d No Tone detected\n", j->board); - break; - case 1: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %u %ld - %ld - %ld\n", j->board, - j->cadence_f[cnt].on1, j->cadence_f[cnt].on1min, j->cadence_f[cnt].on1dot, j->cadence_f[cnt].on1max); - break; - case 2: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min, - j->cadence_f[cnt].off1max); - break; - case 3: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on2min, - j->cadence_f[cnt].on2max); - break; - case 4: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off2min, - j->cadence_f[cnt].off2max); - break; - case 5: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on3min, - j->cadence_f[cnt].on3max); - break; - case 6: - printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off3min, - j->cadence_f[cnt].off3max); - break; - } - } - } - if (j->cadence_f[cnt].state == 7) { - j->cadence_f[cnt].state = 0; - if (j->cadence_f[cnt].enable == 1) - j->cadence_f[cnt].enable = 0; - switch (cnt) { - case 0: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter Cadence 0 triggered %ld\n", jiffies); - } - j->ex.bits.fc0 = 1; - ixj_kill_fasync(j, SIG_FC0, POLL_IN); - break; - case 1: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter Cadence 1 triggered %ld\n", jiffies); - } - j->ex.bits.fc1 = 1; - ixj_kill_fasync(j, SIG_FC1, POLL_IN); - break; - case 2: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter Cadence 2 triggered %ld\n", jiffies); - } - j->ex.bits.fc2 = 1; - ixj_kill_fasync(j, SIG_FC2, POLL_IN); - break; - case 3: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter Cadence 3 triggered %ld\n", jiffies); - } - j->ex.bits.fc3 = 1; - ixj_kill_fasync(j, SIG_FC3, POLL_IN); - break; - } - } - if (j->filter_en[cnt] && ((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) || - (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)))) { - if((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12))) { - trg = 1; - } else if((j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3))) { - trg = 0; - } - switch (cnt) { - case 0: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter 0 triggered %d at %ld\n", trg, jiffies); - } - j->ex.bits.f0 = 1; - ixj_kill_fasync(j, SIG_F0, POLL_IN); - break; - case 1: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter 1 triggered %d at %ld\n", trg, jiffies); - } - j->ex.bits.f1 = 1; - ixj_kill_fasync(j, SIG_F1, POLL_IN); - break; - case 2: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter 2 triggered %d at %ld\n", trg, jiffies); - } - j->ex.bits.f2 = 1; - ixj_kill_fasync(j, SIG_F2, POLL_IN); - break; - case 3: - if(ixjdebug & 0x0020) { - printk(KERN_INFO "Filter 3 triggered %d at %ld\n", trg, jiffies); - } - j->ex.bits.f3 = 1; - ixj_kill_fasync(j, SIG_F3, POLL_IN); - break; - } - } - } - return 0; -} - -static int LineMonitor(IXJ *j) -{ - if (j->dtmf_proc) { - return -1; - } - j->dtmf_proc = 1; - - if (ixj_WriteDSPCommand(0x7000, j)) /* Line Monitor */ - return -1; - - j->dtmf.bytes.high = j->ssr.high; - j->dtmf.bytes.low = j->ssr.low; - if (!j->dtmf_state && j->dtmf.bits.dtmf_valid) { - j->dtmf_state = 1; - j->dtmf_current = j->dtmf.bits.digit; - } - if (j->dtmf_state && !j->dtmf.bits.dtmf_valid) /* && j->dtmf_wp != j->dtmf_rp) */ - { - if(!j->cidcw_wait) { - j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current; - j->dtmf_wp++; - if (j->dtmf_wp == 79) - j->dtmf_wp = 0; - j->ex.bits.dtmf_ready = 1; - if(j->ex_sig.bits.dtmf_ready) { - ixj_kill_fasync(j, SIG_DTMF_READY, POLL_IN); - } - } - else if(j->dtmf_current == 0x00 || j->dtmf_current == 0x0D) { - if(ixjdebug & 0x0020) { - printk("IXJ phone%d saw CIDCW Ack DTMF %d from display at %ld\n", j->board, j->dtmf_current, jiffies); - } - j->flags.cidcw_ack = 1; - } - j->dtmf_state = 0; - } - j->dtmf_proc = 0; - - return 0; -} - -/************************************************************************ -* -* Functions to allow alaw <-> ulaw conversions. -* -************************************************************************/ - -static void ulaw2alaw(unsigned char *buff, unsigned long len) -{ - static unsigned char table_ulaw2alaw[] = - { - 0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D, - 0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, - 0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, - 0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35, - 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02, - 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A, - 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12, - 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B, - 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63, - 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79, - 0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71, - 0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D, - 0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45, - 0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D, - 0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, - 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5, - 0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD, - 0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5, - 0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD, - 0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5, - 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82, - 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A, - 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92, - 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB, - 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3, - 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9, - 0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1, - 0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD, - 0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5, - 0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD, - 0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1, - 0xD6, 0xD6, 0xD7, 0xD7, 0xD4, 0xD4, 0xD5, 0xD5 - }; - - while (len--) - { - *buff = table_ulaw2alaw[*(unsigned char *)buff]; - buff++; - } -} - -static void alaw2ulaw(unsigned char *buff, unsigned long len) -{ - static unsigned char table_alaw2ulaw[] = - { - 0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C, - 0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24, - 0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C, - 0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34, - 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, - 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, - 0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, - 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, - 0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, - 0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E, - 0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A, - 0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, - 0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B, - 0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43, - 0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59, - 0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51, - 0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC, - 0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4, - 0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC, - 0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4, - 0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, - 0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, - 0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, - 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, - 0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, - 0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE, - 0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA, - 0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, - 0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB, - 0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3, - 0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9, - 0xCF, 0xCF, 0xCE, 0xCE, 0xD2, 0xD3, 0xD0, 0xD1 - }; - - while (len--) - { - *buff = table_alaw2ulaw[*(unsigned char *)buff]; - buff++; - } -} - -static ssize_t ixj_read(struct file * file_p, char __user *buf, size_t length, loff_t * ppos) -{ - unsigned long i = *ppos; - IXJ * j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); - - DECLARE_WAITQUEUE(wait, current); - - if (j->flags.inread) - return -EALREADY; - - j->flags.inread = 1; - - add_wait_queue(&j->read_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - mb(); - - while (!j->read_buffer_ready || (j->dtmf_state && j->flags.dtmf_oob)) { - ++j->read_wait; - if (file_p->f_flags & O_NONBLOCK) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->read_q, &wait); - j->flags.inread = 0; - return -EAGAIN; - } - if (!ixj_hookstate(j)) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->read_q, &wait); - j->flags.inread = 0; - return 0; - } - interruptible_sleep_on(&j->read_q); - if (signal_pending(current)) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->read_q, &wait); - j->flags.inread = 0; - return -EINTR; - } - } - - remove_wait_queue(&j->read_q, &wait); - set_current_state(TASK_RUNNING); - /* Don't ever copy more than the user asks */ - if(j->rec_codec == ALAW) - ulaw2alaw(j->read_buffer, min(length, j->read_buffer_size)); - i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size)); - j->read_buffer_ready = 0; - if (i) { - j->flags.inread = 0; - return -EFAULT; - } else { - j->flags.inread = 0; - return min(length, j->read_buffer_size); - } -} - -static ssize_t ixj_enhanced_read(struct file * file_p, char __user *buf, size_t length, - loff_t * ppos) -{ - int pre_retval; - ssize_t read_retval = 0; - IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); - - pre_retval = ixj_PreRead(j, 0L); - switch (pre_retval) { - case NORMAL: - read_retval = ixj_read(file_p, buf, length, ppos); - ixj_PostRead(j, 0L); - break; - case NOPOST: - read_retval = ixj_read(file_p, buf, length, ppos); - break; - case POSTONLY: - ixj_PostRead(j, 0L); - break; - default: - read_retval = pre_retval; - } - return read_retval; -} - -static ssize_t ixj_write(struct file *file_p, const char __user *buf, size_t count, loff_t * ppos) -{ - unsigned long i = *ppos; - IXJ *j = file_p->private_data; - - DECLARE_WAITQUEUE(wait, current); - - if (j->flags.inwrite) - return -EALREADY; - - j->flags.inwrite = 1; - - add_wait_queue(&j->write_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - mb(); - - - while (!j->write_buffers_empty) { - ++j->write_wait; - if (file_p->f_flags & O_NONBLOCK) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->write_q, &wait); - j->flags.inwrite = 0; - return -EAGAIN; - } - if (!ixj_hookstate(j)) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->write_q, &wait); - j->flags.inwrite = 0; - return 0; - } - interruptible_sleep_on(&j->write_q); - if (signal_pending(current)) { - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->write_q, &wait); - j->flags.inwrite = 0; - return -EINTR; - } - } - set_current_state(TASK_RUNNING); - remove_wait_queue(&j->write_q, &wait); - if (j->write_buffer_wp + count >= j->write_buffer_end) - j->write_buffer_wp = j->write_buffer; - i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size)); - if (i) { - j->flags.inwrite = 0; - return -EFAULT; - } - if(j->play_codec == ALAW) - alaw2ulaw(j->write_buffer_wp, min(count, j->write_buffer_size)); - j->flags.inwrite = 0; - return min(count, j->write_buffer_size); -} - -static ssize_t ixj_enhanced_write(struct file * file_p, const char __user *buf, size_t count, loff_t * ppos) -{ - int pre_retval; - ssize_t write_retval = 0; - - IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); - - pre_retval = ixj_PreWrite(j, 0L); - switch (pre_retval) { - case NORMAL: - write_retval = ixj_write(file_p, buf, count, ppos); - if (write_retval > 0) { - ixj_PostWrite(j, 0L); - j->write_buffer_wp += write_retval; - j->write_buffers_empty--; - } - break; - case NOPOST: - write_retval = ixj_write(file_p, buf, count, ppos); - if (write_retval > 0) { - j->write_buffer_wp += write_retval; - j->write_buffers_empty--; - } - break; - case POSTONLY: - ixj_PostWrite(j, 0L); - break; - default: - write_retval = pre_retval; - } - return write_retval; -} - -static void ixj_read_frame(IXJ *j) -{ - int cnt, dly; - - if (j->read_buffer) { - for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) { - if (!(cnt % 16) && !IsRxReady(j)) { - dly = 0; - while (!IsRxReady(j)) { - if (dly++ > 5) { - dly = 0; - break; - } - udelay(10); - } - } - /* Throw away word 0 of the 8021 compressed format to get standard G.729. */ - if (j->rec_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) { - inb_p(j->DSPbase + 0x0E); - inb_p(j->DSPbase + 0x0F); - } - *(j->read_buffer + cnt) = inb_p(j->DSPbase + 0x0E); - *(j->read_buffer + cnt + 1) = inb_p(j->DSPbase + 0x0F); - } - ++j->framesread; - if (j->intercom != -1) { - if (IsTxReady(get_ixj(j->intercom))) { - for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) { - if (!(cnt % 16) && !IsTxReady(j)) { - dly = 0; - while (!IsTxReady(j)) { - if (dly++ > 5) { - dly = 0; - break; - } - udelay(10); - } - } - outb_p(*(j->read_buffer + cnt), get_ixj(j->intercom)->DSPbase + 0x0C); - outb_p(*(j->read_buffer + cnt + 1), get_ixj(j->intercom)->DSPbase + 0x0D); - } - get_ixj(j->intercom)->frameswritten++; - } - } else { - j->read_buffer_ready = 1; - wake_up_interruptible(&j->read_q); /* Wake any blocked readers */ - - wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ - - if(j->ixj_signals[SIG_READ_READY]) - ixj_kill_fasync(j, SIG_READ_READY, POLL_OUT); - } - } -} - -static short fsk[][6][20] = -{ - { - { - 0, 17846, 29934, 32364, 24351, 8481, -10126, -25465, -32587, -29196, - -16384, 1715, 19260, 30591, 32051, 23170, 6813, -11743, -26509, -32722 - }, - { - -28377, -14876, 3425, 20621, 31163, 31650, 21925, 5126, -13328, -27481, - -32767, -27481, -13328, 5126, 21925, 31650, 31163, 20621, 3425, -14876 - }, - { - -28377, -32722, -26509, -11743, 6813, 23170, 32051, 30591, 19260, 1715, - -16384, -29196, -32587, -25465, -10126, 8481, 24351, 32364, 29934, 17846 - }, - { - 0, -17846, -29934, -32364, -24351, -8481, 10126, 25465, 32587, 29196, - 16384, -1715, -19260, -30591, -32051, -23170, -6813, 11743, 26509, 32722 - }, - { - 28377, 14876, -3425, -20621, -31163, -31650, -21925, -5126, 13328, 27481, - 32767, 27481, 13328, -5126, -21925, -31650, -31163, -20621, -3425, 14876 - }, - { - 28377, 32722, 26509, 11743, -6813, -23170, -32051, -30591, -19260, -1715, - 16384, 29196, 32587, 25465, 10126, -8481, -24351, -32364, -29934, -17846 - } - }, - { - { - 0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126, - 0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126 - }, - { - -28377, -21925, -13328, -3425, 6813, 16384, 24351, 29934, 32587, 32051, - 28377, 21925, 13328, 3425, -6813, -16384, -24351, -29934, -32587, -32051 - }, - { - -28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925, - 28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925 - }, - { - 0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126, - 0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126 - }, - { - 28377, 21925, 13328, 3425, -6813, -16383, -24351, -29934, -32587, -32051, - -28377, -21925, -13328, -3425, 6813, 16383, 24351, 29934, 32587, 32051 - }, - { - 28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925, - -28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925 - } - } -}; - - -static void ixj_write_cid_bit(IXJ *j, int bit) -{ - while (j->fskcnt < 20) { - if(j->fskdcnt < (j->fsksize - 1)) - j->fskdata[j->fskdcnt++] = fsk[bit][j->fskz][j->fskcnt]; - - j->fskcnt += 3; - } - j->fskcnt %= 20; - - if (!bit) - j->fskz++; - if (j->fskz >= 6) - j->fskz = 0; - -} - -static void ixj_write_cid_byte(IXJ *j, char byte) -{ - IXJ_CBYTE cb; - - cb.cbyte = byte; - ixj_write_cid_bit(j, 0); - ixj_write_cid_bit(j, cb.cbits.b0 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b1 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b2 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b3 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b4 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b5 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b6 ? 1 : 0); - ixj_write_cid_bit(j, cb.cbits.b7 ? 1 : 0); - ixj_write_cid_bit(j, 1); -} - -static void ixj_write_cid_seize(IXJ *j) -{ - int cnt; - - for (cnt = 0; cnt < 150; cnt++) { - ixj_write_cid_bit(j, 0); - ixj_write_cid_bit(j, 1); - } - for (cnt = 0; cnt < 180; cnt++) { - ixj_write_cid_bit(j, 1); - } -} - -static void ixj_write_cidcw_seize(IXJ *j) -{ - int cnt; - - for (cnt = 0; cnt < 80; cnt++) { - ixj_write_cid_bit(j, 1); - } -} - -static int ixj_write_cid_string(IXJ *j, char *s, int checksum) -{ - int cnt; - - for (cnt = 0; cnt < strlen(s); cnt++) { - ixj_write_cid_byte(j, s[cnt]); - checksum = (checksum + s[cnt]); - } - return checksum; -} - -static void ixj_pad_fsk(IXJ *j, int pad) -{ - int cnt; - - for (cnt = 0; cnt < pad; cnt++) { - if(j->fskdcnt < (j->fsksize - 1)) - j->fskdata[j->fskdcnt++] = 0x0000; - } - for (cnt = 0; cnt < 720; cnt++) { - if(j->fskdcnt < (j->fsksize - 1)) - j->fskdata[j->fskdcnt++] = 0x0000; - } -} - -static void ixj_pre_cid(IXJ *j) -{ - j->cid_play_codec = j->play_codec; - j->cid_play_frame_size = j->play_frame_size; - j->cid_play_volume = get_play_volume(j); - j->cid_play_flag = j->flags.playing; - - j->cid_rec_codec = j->rec_codec; - j->cid_rec_volume = get_rec_volume(j); - j->cid_rec_flag = j->flags.recording; - - j->cid_play_aec_level = j->aec_level; - - switch(j->baseframe.low) { - case 0xA0: - j->cid_base_frame_size = 20; - break; - case 0x50: - j->cid_base_frame_size = 10; - break; - case 0xF0: - j->cid_base_frame_size = 30; - break; - } - - ixj_play_stop(j); - ixj_cpt_stop(j); - - j->flags.cidplay = 1; - - set_base_frame(j, 30); - set_play_codec(j, LINEAR16); - set_play_volume(j, 0x1B); - ixj_play_start(j); -} - -static void ixj_post_cid(IXJ *j) -{ - ixj_play_stop(j); - - if(j->cidsize > 5000) { - SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); - } - j->flags.cidplay = 0; - if(ixjdebug & 0x0200) { - printk("IXJ phone%d Finished Playing CallerID data %ld\n", j->board, jiffies); - } - - ixj_fsk_free(j); - - j->fskdcnt = 0; - set_base_frame(j, j->cid_base_frame_size); - set_play_codec(j, j->cid_play_codec); - ixj_aec_start(j, j->cid_play_aec_level); - set_play_volume(j, j->cid_play_volume); - - set_rec_codec(j, j->cid_rec_codec); - set_rec_volume(j, j->cid_rec_volume); - - if(j->cid_rec_flag) - ixj_record_start(j); - - if(j->cid_play_flag) - ixj_play_start(j); - - if(j->cid_play_flag) { - wake_up_interruptible(&j->write_q); /* Wake any blocked writers */ - } -} - -static void ixj_write_cid(IXJ *j) -{ - char sdmf1[50]; - char sdmf2[50]; - char sdmf3[80]; - char mdmflen, len1, len2, len3; - int pad; - - int checksum = 0; - - if (j->dsp.low == 0x20 || j->flags.cidplay) - return; - - j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0; - j->cidsize = j->cidcnt = 0; - - ixj_fsk_alloc(j); - - strcpy(sdmf1, j->cid_send.month); - strcat(sdmf1, j->cid_send.day); - strcat(sdmf1, j->cid_send.hour); - strcat(sdmf1, j->cid_send.min); - strcpy(sdmf2, j->cid_send.number); - strcpy(sdmf3, j->cid_send.name); - - len1 = strlen(sdmf1); - len2 = strlen(sdmf2); - len3 = strlen(sdmf3); - mdmflen = len1 + len2 + len3 + 6; - - while(1){ - ixj_write_cid_seize(j); - - ixj_write_cid_byte(j, 0x80); - checksum = 0x80; - ixj_write_cid_byte(j, mdmflen); - checksum = checksum + mdmflen; - - ixj_write_cid_byte(j, 0x01); - checksum = checksum + 0x01; - ixj_write_cid_byte(j, len1); - checksum = checksum + len1; - checksum = ixj_write_cid_string(j, sdmf1, checksum); - if(ixj_hookstate(j) & 1) - break; - - ixj_write_cid_byte(j, 0x02); - checksum = checksum + 0x02; - ixj_write_cid_byte(j, len2); - checksum = checksum + len2; - checksum = ixj_write_cid_string(j, sdmf2, checksum); - if(ixj_hookstate(j) & 1) - break; - - ixj_write_cid_byte(j, 0x07); - checksum = checksum + 0x07; - ixj_write_cid_byte(j, len3); - checksum = checksum + len3; - checksum = ixj_write_cid_string(j, sdmf3, checksum); - if(ixj_hookstate(j) & 1) - break; - - checksum %= 256; - checksum ^= 0xFF; - checksum += 1; - - ixj_write_cid_byte(j, (char) checksum); - - pad = j->fskdcnt % 240; - if (pad) { - pad = 240 - pad; - } - ixj_pad_fsk(j, pad); - break; - } - - ixj_write_frame(j); -} - -static void ixj_write_cidcw(IXJ *j) -{ - IXJ_TONE ti; - - char sdmf1[50]; - char sdmf2[50]; - char sdmf3[80]; - char mdmflen, len1, len2, len3; - int pad; - - int checksum = 0; - - if (j->dsp.low == 0x20 || j->flags.cidplay) - return; - - j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0; - j->cidsize = j->cidcnt = 0; - - ixj_fsk_alloc(j); - - j->flags.cidcw_ack = 0; - - ti.tone_index = 23; - ti.gain0 = 1; - ti.freq0 = hz440; - ti.gain1 = 0; - ti.freq1 = 0; - ixj_init_tone(j, &ti); - - ixj_set_tone_on(1500, j); - ixj_set_tone_off(32, j); - if(ixjdebug & 0x0200) { - printk("IXJ cidcw phone%d first tone start at %ld\n", j->board, jiffies); - } - ixj_play_tone(j, 23); - - clear_bit(j->board, &j->busyflags); - while(j->tone_state) - schedule_timeout_interruptible(1); - while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) - schedule_timeout_interruptible(1); - if(ixjdebug & 0x0200) { - printk("IXJ cidcw phone%d first tone end at %ld\n", j->board, jiffies); - } - - ti.tone_index = 24; - ti.gain0 = 1; - ti.freq0 = hz2130; - ti.gain1 = 0; - ti.freq1 = hz2750; - ixj_init_tone(j, &ti); - - ixj_set_tone_off(10, j); - ixj_set_tone_on(600, j); - if(ixjdebug & 0x0200) { - printk("IXJ cidcw phone%d second tone start at %ld\n", j->board, jiffies); - } - ixj_play_tone(j, 24); - - clear_bit(j->board, &j->busyflags); - while(j->tone_state) - schedule_timeout_interruptible(1); - while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) - schedule_timeout_interruptible(1); - if(ixjdebug & 0x0200) { - printk("IXJ cidcw phone%d sent second tone at %ld\n", j->board, jiffies); - } - - j->cidcw_wait = jiffies + ((50 * hertz) / 100); - - clear_bit(j->board, &j->busyflags); - while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait)) - schedule_timeout_interruptible(1); - while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) - schedule_timeout_interruptible(1); - j->cidcw_wait = 0; - if(!j->flags.cidcw_ack) { - if(ixjdebug & 0x0200) { - printk("IXJ cidcw phone%d did not receive ACK from display %ld\n", j->board, jiffies); - } - ixj_post_cid(j); - if(j->cid_play_flag) { - wake_up_interruptible(&j->write_q); /* Wake any blocked readers */ - } - return; - } else { - ixj_pre_cid(j); - } - j->flags.cidcw_ack = 0; - strcpy(sdmf1, j->cid_send.month); - strcat(sdmf1, j->cid_send.day); - strcat(sdmf1, j->cid_send.hour); - strcat(sdmf1, j->cid_send.min); - strcpy(sdmf2, j->cid_send.number); - strcpy(sdmf3, j->cid_send.name); - - len1 = strlen(sdmf1); - len2 = strlen(sdmf2); - len3 = strlen(sdmf3); - mdmflen = len1 + len2 + len3 + 6; - - ixj_write_cidcw_seize(j); - - ixj_write_cid_byte(j, 0x80); - checksum = 0x80; - ixj_write_cid_byte(j, mdmflen); - checksum = checksum + mdmflen; - - ixj_write_cid_byte(j, 0x01); - checksum = checksum + 0x01; - ixj_write_cid_byte(j, len1); - checksum = checksum + len1; - checksum = ixj_write_cid_string(j, sdmf1, checksum); - - ixj_write_cid_byte(j, 0x02); - checksum = checksum + 0x02; - ixj_write_cid_byte(j, len2); - checksum = checksum + len2; - checksum = ixj_write_cid_string(j, sdmf2, checksum); - - ixj_write_cid_byte(j, 0x07); - checksum = checksum + 0x07; - ixj_write_cid_byte(j, len3); - checksum = checksum + len3; - checksum = ixj_write_cid_string(j, sdmf3, checksum); - - checksum %= 256; - checksum ^= 0xFF; - checksum += 1; - - ixj_write_cid_byte(j, (char) checksum); - - pad = j->fskdcnt % 240; - if (pad) { - pad = 240 - pad; - } - ixj_pad_fsk(j, pad); - if(ixjdebug & 0x0200) { - printk("IXJ cidcw phone%d sent FSK data at %ld\n", j->board, jiffies); - } -} - -static void ixj_write_vmwi(IXJ *j, int msg) -{ - char mdmflen; - int pad; - - int checksum = 0; - - if (j->dsp.low == 0x20 || j->flags.cidplay) - return; - - j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0; - j->cidsize = j->cidcnt = 0; - - ixj_fsk_alloc(j); - - mdmflen = 3; - - if (j->port == PORT_POTS) - SLIC_SetState(PLD_SLIC_STATE_OHT, j); - - ixj_write_cid_seize(j); - - ixj_write_cid_byte(j, 0x82); - checksum = 0x82; - ixj_write_cid_byte(j, mdmflen); - checksum = checksum + mdmflen; - - ixj_write_cid_byte(j, 0x0B); - checksum = checksum + 0x0B; - ixj_write_cid_byte(j, 1); - checksum = checksum + 1; - - if(msg) { - ixj_write_cid_byte(j, 0xFF); - checksum = checksum + 0xFF; - } - else { - ixj_write_cid_byte(j, 0x00); - checksum = checksum + 0x00; - } - - checksum %= 256; - checksum ^= 0xFF; - checksum += 1; - - ixj_write_cid_byte(j, (char) checksum); - - pad = j->fskdcnt % 240; - if (pad) { - pad = 240 - pad; - } - ixj_pad_fsk(j, pad); -} - -static void ixj_write_frame(IXJ *j) -{ - int cnt, frame_count, dly; - IXJ_WORD dat; - - frame_count = 0; - if(j->flags.cidplay) { - for(cnt = 0; cnt < 480; cnt++) { - if (!(cnt % 16) && !IsTxReady(j)) { - dly = 0; - while (!IsTxReady(j)) { - if (dly++ > 5) { - dly = 0; - break; - } - udelay(10); - } - } - dat.word = j->fskdata[j->cidcnt++]; - outb_p(dat.bytes.low, j->DSPbase + 0x0C); - outb_p(dat.bytes.high, j->DSPbase + 0x0D); - cnt++; - } - if(j->cidcnt >= j->fskdcnt) { - ixj_post_cid(j); - } - /* This may seem rude, but if we just played one frame of FSK data for CallerID - and there is real audio data in the buffer, we need to throw it away because - we just used it's time slot */ - if (j->write_buffer_rp > j->write_buffer_wp) { - j->write_buffer_rp += j->cid_play_frame_size * 2; - if (j->write_buffer_rp >= j->write_buffer_end) { - j->write_buffer_rp = j->write_buffer; - } - j->write_buffers_empty++; - wake_up_interruptible(&j->write_q); /* Wake any blocked writers */ - - wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ - } - } else if (j->write_buffer && j->write_buffers_empty < 1) { - if (j->write_buffer_wp > j->write_buffer_rp) { - frame_count = - (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2); - } - if (j->write_buffer_rp > j->write_buffer_wp) { - frame_count = - (j->write_buffer_wp - j->write_buffer) / (j->play_frame_size * 2) + - (j->write_buffer_end - j->write_buffer_rp) / (j->play_frame_size * 2); - } - if (frame_count >= 1) { - if (j->ver.low == 0x12 && j->play_mode && j->flags.play_first_frame) { - BYTES blankword; - - switch (j->play_mode) { - case PLAYBACK_MODE_ULAW: - case PLAYBACK_MODE_ALAW: - blankword.low = blankword.high = 0xFF; - break; - case PLAYBACK_MODE_8LINEAR: - case PLAYBACK_MODE_16LINEAR: - default: - blankword.low = blankword.high = 0x00; - break; - case PLAYBACK_MODE_8LINEAR_WSS: - blankword.low = blankword.high = 0x80; - break; - } - for (cnt = 0; cnt < 16; cnt++) { - if (!(cnt % 16) && !IsTxReady(j)) { - dly = 0; - while (!IsTxReady(j)) { - if (dly++ > 5) { - dly = 0; - break; - } - udelay(10); - } - } - outb_p((blankword.low), j->DSPbase + 0x0C); - outb_p((blankword.high), j->DSPbase + 0x0D); - } - j->flags.play_first_frame = 0; - } else if (j->play_codec == G723_63 && j->flags.play_first_frame) { - for (cnt = 0; cnt < 24; cnt++) { - BYTES blankword; - - if(cnt == 12) { - blankword.low = 0x02; - blankword.high = 0x00; - } - else { - blankword.low = blankword.high = 0x00; - } - if (!(cnt % 16) && !IsTxReady(j)) { - dly = 0; - while (!IsTxReady(j)) { - if (dly++ > 5) { - dly = 0; - break; - } - udelay(10); - } - } - outb_p((blankword.low), j->DSPbase + 0x0C); - outb_p((blankword.high), j->DSPbase + 0x0D); - } - j->flags.play_first_frame = 0; - } - for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) { - if (!(cnt % 16) && !IsTxReady(j)) { - dly = 0; - while (!IsTxReady(j)) { - if (dly++ > 5) { - dly = 0; - break; - } - udelay(10); - } - } - /* Add word 0 to G.729 frames for the 8021. Right now we don't do VAD/CNG */ - if (j->play_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) { - if (j->write_buffer_rp[cnt] == 0 && - j->write_buffer_rp[cnt + 1] == 0 && - j->write_buffer_rp[cnt + 2] == 0 && - j->write_buffer_rp[cnt + 3] == 0 && - j->write_buffer_rp[cnt + 4] == 0 && - j->write_buffer_rp[cnt + 5] == 0 && - j->write_buffer_rp[cnt + 6] == 0 && - j->write_buffer_rp[cnt + 7] == 0 && - j->write_buffer_rp[cnt + 8] == 0 && - j->write_buffer_rp[cnt + 9] == 0) { - /* someone is trying to write silence lets make this a type 0 frame. */ - outb_p(0x00, j->DSPbase + 0x0C); - outb_p(0x00, j->DSPbase + 0x0D); - } else { - /* so all other frames are type 1. */ - outb_p(0x01, j->DSPbase + 0x0C); - outb_p(0x00, j->DSPbase + 0x0D); - } - } - outb_p(*(j->write_buffer_rp + cnt), j->DSPbase + 0x0C); - outb_p(*(j->write_buffer_rp + cnt + 1), j->DSPbase + 0x0D); - *(j->write_buffer_rp + cnt) = 0; - *(j->write_buffer_rp + cnt + 1) = 0; - } - j->write_buffer_rp += j->play_frame_size * 2; - if (j->write_buffer_rp >= j->write_buffer_end) { - j->write_buffer_rp = j->write_buffer; - } - j->write_buffers_empty++; - wake_up_interruptible(&j->write_q); /* Wake any blocked writers */ - - wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ - - ++j->frameswritten; - } - } else { - j->drybuffer++; - } - if(j->ixj_signals[SIG_WRITE_READY]) { - ixj_kill_fasync(j, SIG_WRITE_READY, POLL_OUT); - } -} - -static int idle(IXJ *j) -{ - if (ixj_WriteDSPCommand(0x0000, j)) /* DSP Idle */ - - return 0; - - if (j->ssr.high || j->ssr.low) { - return 0; - } else { - j->play_mode = -1; - j->flags.playing = 0; - j->rec_mode = -1; - j->flags.recording = 0; - return 1; - } -} - -static int set_base_frame(IXJ *j, int size) -{ - unsigned short cmd; - int cnt; - - idle(j); - j->cid_play_aec_level = j->aec_level; - aec_stop(j); - for (cnt = 0; cnt < 10; cnt++) { - if (idle(j)) - break; - } - if (j->ssr.high || j->ssr.low) - return -1; - if (j->dsp.low != 0x20) { - switch (size) { - case 30: - cmd = 0x07F0; - /* Set Base Frame Size to 240 pg9-10 8021 */ - break; - case 20: - cmd = 0x07A0; - /* Set Base Frame Size to 160 pg9-10 8021 */ - break; - case 10: - cmd = 0x0750; - /* Set Base Frame Size to 80 pg9-10 8021 */ - break; - default: - return -1; - } - } else { - if (size == 30) - return size; - else - return -1; - } - if (ixj_WriteDSPCommand(cmd, j)) { - j->baseframe.high = j->baseframe.low = 0xFF; - return -1; - } else { - j->baseframe.high = j->ssr.high; - j->baseframe.low = j->ssr.low; - /* If the status returned is 0x0000 (pg9-9 8021) the call failed */ - if(j->baseframe.high == 0x00 && j->baseframe.low == 0x00) { - return -1; - } - } - ixj_aec_start(j, j->cid_play_aec_level); - return size; -} - -static int set_rec_codec(IXJ *j, int rate) -{ - int retval = 0; - - j->rec_codec = rate; - - switch (rate) { - case G723_63: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->rec_frame_size = 12; - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case G723_53: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->rec_frame_size = 10; - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case TS85: - if (j->dsp.low == 0x20 || j->flags.ts85_loaded) { - j->rec_frame_size = 16; - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case TS48: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->rec_frame_size = 9; - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case TS41: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->rec_frame_size = 8; - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case G728: - if (j->dsp.low != 0x20) { - j->rec_frame_size = 48; - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case G729: - if (j->dsp.low != 0x20) { - if (!j->flags.g729_loaded) { - retval = 1; - break; - } - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 10; - break; - case 0x50: - j->rec_frame_size = 5; - break; - default: - j->rec_frame_size = 15; - break; - } - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case G729B: - if (j->dsp.low != 0x20) { - if (!j->flags.g729_loaded) { - retval = 1; - break; - } - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 12; - break; - case 0x50: - j->rec_frame_size = 6; - break; - default: - j->rec_frame_size = 18; - break; - } - j->rec_mode = 0; - } else { - retval = 1; - } - break; - case ULAW: - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 80; - break; - case 0x50: - j->rec_frame_size = 40; - break; - default: - j->rec_frame_size = 120; - break; - } - j->rec_mode = 4; - break; - case ALAW: - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 80; - break; - case 0x50: - j->rec_frame_size = 40; - break; - default: - j->rec_frame_size = 120; - break; - } - j->rec_mode = 4; - break; - case LINEAR16: - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 160; - break; - case 0x50: - j->rec_frame_size = 80; - break; - default: - j->rec_frame_size = 240; - break; - } - j->rec_mode = 5; - break; - case LINEAR8: - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 80; - break; - case 0x50: - j->rec_frame_size = 40; - break; - default: - j->rec_frame_size = 120; - break; - } - j->rec_mode = 6; - break; - case WSS: - switch (j->baseframe.low) { - case 0xA0: - j->rec_frame_size = 80; - break; - case 0x50: - j->rec_frame_size = 40; - break; - default: - j->rec_frame_size = 120; - break; - } - j->rec_mode = 7; - break; - default: - kfree(j->read_buffer); - j->rec_frame_size = 0; - j->rec_mode = -1; - j->read_buffer = NULL; - j->read_buffer_size = 0; - retval = 1; - break; - } - return retval; -} - -static int ixj_record_start(IXJ *j) -{ - unsigned short cmd = 0x0000; - - if (j->read_buffer) { - ixj_record_stop(j); - } - j->flags.recording = 1; - ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */ - - if(ixjdebug & 0x0002) - printk("IXJ %d Starting Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies); - - if (!j->rec_mode) { - switch (j->rec_codec) { - case G723_63: - cmd = 0x5131; - break; - case G723_53: - cmd = 0x5132; - break; - case TS85: - cmd = 0x5130; /* TrueSpeech 8.5 */ - - break; - case TS48: - cmd = 0x5133; /* TrueSpeech 4.8 */ - - break; - case TS41: - cmd = 0x5134; /* TrueSpeech 4.1 */ - - break; - case G728: - cmd = 0x5135; - break; - case G729: - case G729B: - cmd = 0x5136; - break; - default: - return 1; - } - if (ixj_WriteDSPCommand(cmd, j)) - return -1; - } - if (!j->read_buffer) { - if (!j->read_buffer) - j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_ATOMIC); - if (!j->read_buffer) { - printk("Read buffer allocation for ixj board %d failed!\n", j->board); - return -ENOMEM; - } - } - j->read_buffer_size = j->rec_frame_size * 2; - - if (ixj_WriteDSPCommand(0x5102, j)) /* Set Poll sync mode */ - - return -1; - - switch (j->rec_mode) { - case 0: - cmd = 0x1C03; /* Record C1 */ - - break; - case 4: - if (j->ver.low == 0x12) { - cmd = 0x1E03; /* Record C1 */ - - } else { - cmd = 0x1E01; /* Record C1 */ - - } - break; - case 5: - if (j->ver.low == 0x12) { - cmd = 0x1E83; /* Record C1 */ - - } else { - cmd = 0x1E81; /* Record C1 */ - - } - break; - case 6: - if (j->ver.low == 0x12) { - cmd = 0x1F03; /* Record C1 */ - - } else { - cmd = 0x1F01; /* Record C1 */ - - } - break; - case 7: - if (j->ver.low == 0x12) { - cmd = 0x1F83; /* Record C1 */ - } else { - cmd = 0x1F81; /* Record C1 */ - } - break; - } - if (ixj_WriteDSPCommand(cmd, j)) - return -1; - - if (j->flags.playing) { - ixj_aec_start(j, j->aec_level); - } - return 0; -} - -static void ixj_record_stop(IXJ *j) -{ - if (ixjdebug & 0x0002) - printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies); - - kfree(j->read_buffer); - j->read_buffer = NULL; - j->read_buffer_size = 0; - if (j->rec_mode > -1) { - ixj_WriteDSPCommand(0x5120, j); - j->rec_mode = -1; - } - j->flags.recording = 0; -} -static void ixj_vad(IXJ *j, int arg) -{ - if (arg) - ixj_WriteDSPCommand(0x513F, j); - else - ixj_WriteDSPCommand(0x513E, j); -} - -static void set_rec_depth(IXJ *j, int depth) -{ - if (depth > 60) - depth = 60; - if (depth < 0) - depth = 0; - ixj_WriteDSPCommand(0x5180 + depth, j); -} - -static void set_dtmf_prescale(IXJ *j, int volume) -{ - ixj_WriteDSPCommand(0xCF07, j); - ixj_WriteDSPCommand(volume, j); -} - -static int get_dtmf_prescale(IXJ *j) -{ - ixj_WriteDSPCommand(0xCF05, j); - return j->ssr.high << 8 | j->ssr.low; -} - -static void set_rec_volume(IXJ *j, int volume) -{ - if(j->aec_level == AEC_AGC) { - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: /dev/phone%d Setting AGC Threshold to 0x%4.4x\n", j->board, volume); - ixj_WriteDSPCommand(0xCF96, j); - ixj_WriteDSPCommand(volume, j); - } else { - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: /dev/phone %d Setting Record Volume to 0x%4.4x\n", j->board, volume); - ixj_WriteDSPCommand(0xCF03, j); - ixj_WriteDSPCommand(volume, j); - } -} - -static int set_rec_volume_linear(IXJ *j, int volume) -{ - int newvolume, dsprecmax; - - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Record Volume to 0x%4.4x\n", j->board, volume); - if(volume > 100 || volume < 0) { - return -1; - } - - /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */ - switch (j->cardtype) { - case QTI_PHONEJACK: - dsprecmax = 0x440; - break; - case QTI_LINEJACK: - dsprecmax = 0x180; - ixj_mixer(0x0203, j); /*Voice Left Volume unmute 6db */ - ixj_mixer(0x0303, j); /*Voice Right Volume unmute 6db */ - ixj_mixer(0x0C00, j); /*Mono1 unmute 12db */ - break; - case QTI_PHONEJACK_LITE: - dsprecmax = 0x4C0; - break; - case QTI_PHONEJACK_PCI: - dsprecmax = 0x100; - break; - case QTI_PHONECARD: - dsprecmax = 0x400; - break; - default: - return -1; - } - newvolume = (dsprecmax * volume) / 100; - set_rec_volume(j, newvolume); - return 0; -} - -static int get_rec_volume(IXJ *j) -{ - if(j->aec_level == AEC_AGC) { - if (ixjdebug & 0x0002) - printk(KERN_INFO "Getting AGC Threshold\n"); - ixj_WriteDSPCommand(0xCF86, j); - if (ixjdebug & 0x0002) - printk(KERN_INFO "AGC Threshold is 0x%2.2x%2.2x\n", j->ssr.high, j->ssr.low); - return j->ssr.high << 8 | j->ssr.low; - } else { - if (ixjdebug & 0x0002) - printk(KERN_INFO "Getting Record Volume\n"); - ixj_WriteDSPCommand(0xCF01, j); - return j->ssr.high << 8 | j->ssr.low; - } -} - -static int get_rec_volume_linear(IXJ *j) -{ - int volume, newvolume, dsprecmax; - - switch (j->cardtype) { - case QTI_PHONEJACK: - dsprecmax = 0x440; - break; - case QTI_LINEJACK: - dsprecmax = 0x180; - break; - case QTI_PHONEJACK_LITE: - dsprecmax = 0x4C0; - break; - case QTI_PHONEJACK_PCI: - dsprecmax = 0x100; - break; - case QTI_PHONECARD: - dsprecmax = 0x400; - break; - default: - return -1; - } - volume = get_rec_volume(j); - newvolume = (volume * 100) / dsprecmax; - if(newvolume > 100) - newvolume = 100; - return newvolume; -} - -static int get_rec_level(IXJ *j) -{ - int retval; - - ixj_WriteDSPCommand(0xCF88, j); - - retval = j->ssr.high << 8 | j->ssr.low; - retval = (retval * 256) / 240; - return retval; -} - -static void ixj_aec_start(IXJ *j, int level) -{ - j->aec_level = level; - if (ixjdebug & 0x0002) - printk(KERN_INFO "AGC set = 0x%2.2x\n", j->aec_level); - if (!level) { - aec_stop(j); - } else { - if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) { - ixj_WriteDSPCommand(0xE022, j); /* Move AEC filter buffer */ - - ixj_WriteDSPCommand(0x0300, j); - } - ixj_WriteDSPCommand(0xB001, j); /* AEC On */ - - ixj_WriteDSPCommand(0xE013, j); /* Advanced AEC C1 */ - - switch (level) { - case AEC_LOW: - ixj_WriteDSPCommand(0x0000, j); /* Advanced AEC C2 = off */ - - ixj_WriteDSPCommand(0xE011, j); - ixj_WriteDSPCommand(0xFFFF, j); - - ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ - ixj_WriteDSPCommand(0x0000, j); /* to off */ - - break; - - case AEC_MED: - ixj_WriteDSPCommand(0x0600, j); /* Advanced AEC C2 = on medium */ - - ixj_WriteDSPCommand(0xE011, j); - ixj_WriteDSPCommand(0x0080, j); - - ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ - ixj_WriteDSPCommand(0x0000, j); /* to off */ - - break; - - case AEC_HIGH: - ixj_WriteDSPCommand(0x0C00, j); /* Advanced AEC C2 = on high */ - - ixj_WriteDSPCommand(0xE011, j); - ixj_WriteDSPCommand(0x0080, j); - - ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ - ixj_WriteDSPCommand(0x0000, j); /* to off */ - - break; - - case AEC_AGC: - /* First we have to put the AEC into advance auto mode so that AGC will not conflict with it */ - ixj_WriteDSPCommand(0x0002, j); /* Attenuation scaling factor of 2 */ - - ixj_WriteDSPCommand(0xE011, j); - ixj_WriteDSPCommand(0x0100, j); /* Higher Threshold Floor */ - - ixj_WriteDSPCommand(0xE012, j); /* Set Train and Lock */ - - if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD) - ixj_WriteDSPCommand(0x0224, j); - else - ixj_WriteDSPCommand(0x1224, j); - - ixj_WriteDSPCommand(0xE014, j); - ixj_WriteDSPCommand(0x0003, j); /* Lock threshold at 3dB */ - - ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */ - - /* Now we can set the AGC initial parameters and turn it on */ - ixj_WriteDSPCommand(0xCF90, j); /* Set AGC Minimum gain */ - ixj_WriteDSPCommand(0x0020, j); /* to 0.125 (-18dB) */ - - ixj_WriteDSPCommand(0xCF91, j); /* Set AGC Maximum gain */ - ixj_WriteDSPCommand(0x1000, j); /* to 16 (24dB) */ - - ixj_WriteDSPCommand(0xCF92, j); /* Set AGC start gain */ - ixj_WriteDSPCommand(0x0800, j); /* to 8 (+18dB) */ - - ixj_WriteDSPCommand(0xCF93, j); /* Set AGC hold time */ - ixj_WriteDSPCommand(0x1F40, j); /* to 2 seconds (units are 250us) */ - - ixj_WriteDSPCommand(0xCF94, j); /* Set AGC Attack Time Constant */ - ixj_WriteDSPCommand(0x0005, j); /* to 8ms */ - - ixj_WriteDSPCommand(0xCF95, j); /* Set AGC Decay Time Constant */ - ixj_WriteDSPCommand(0x000D, j); /* to 4096ms */ - - ixj_WriteDSPCommand(0xCF96, j); /* Set AGC Attack Threshold */ - ixj_WriteDSPCommand(0x1200, j); /* to 25% */ - - ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */ - ixj_WriteDSPCommand(0x0001, j); /* to on */ - - break; - - case AEC_AUTO: - ixj_WriteDSPCommand(0x0002, j); /* Attenuation scaling factor of 2 */ - - ixj_WriteDSPCommand(0xE011, j); - ixj_WriteDSPCommand(0x0100, j); /* Higher Threshold Floor */ - - ixj_WriteDSPCommand(0xE012, j); /* Set Train and Lock */ - - if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD) - ixj_WriteDSPCommand(0x0224, j); - else - ixj_WriteDSPCommand(0x1224, j); - - ixj_WriteDSPCommand(0xE014, j); - ixj_WriteDSPCommand(0x0003, j); /* Lock threshold at 3dB */ - - ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */ - - break; - } - } -} - -static void aec_stop(IXJ *j) -{ - j->aec_level = AEC_OFF; - if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) { - ixj_WriteDSPCommand(0xE022, j); /* Move AEC filter buffer back */ - - ixj_WriteDSPCommand(0x0700, j); - } - if (j->play_mode != -1 && j->rec_mode != -1) - { - ixj_WriteDSPCommand(0xB002, j); /* AEC Stop */ - } -} - -static int set_play_codec(IXJ *j, int rate) -{ - int retval = 0; - - j->play_codec = rate; - - switch (rate) { - case G723_63: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->play_frame_size = 12; - j->play_mode = 0; - } else { - retval = 1; - } - break; - case G723_53: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->play_frame_size = 10; - j->play_mode = 0; - } else { - retval = 1; - } - break; - case TS85: - if (j->dsp.low == 0x20 || j->flags.ts85_loaded) { - j->play_frame_size = 16; - j->play_mode = 0; - } else { - retval = 1; - } - break; - case TS48: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->play_frame_size = 9; - j->play_mode = 0; - } else { - retval = 1; - } - break; - case TS41: - if (j->ver.low != 0x12 || ixj_convert_loaded) { - j->play_frame_size = 8; - j->play_mode = 0; - } else { - retval = 1; - } - break; - case G728: - if (j->dsp.low != 0x20) { - j->play_frame_size = 48; - j->play_mode = 0; - } else { - retval = 1; - } - break; - case G729: - if (j->dsp.low != 0x20) { - if (!j->flags.g729_loaded) { - retval = 1; - break; - } - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 10; - break; - case 0x50: - j->play_frame_size = 5; - break; - default: - j->play_frame_size = 15; - break; - } - j->play_mode = 0; - } else { - retval = 1; - } - break; - case G729B: - if (j->dsp.low != 0x20) { - if (!j->flags.g729_loaded) { - retval = 1; - break; - } - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 12; - break; - case 0x50: - j->play_frame_size = 6; - break; - default: - j->play_frame_size = 18; - break; - } - j->play_mode = 0; - } else { - retval = 1; - } - break; - case ULAW: - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 80; - break; - case 0x50: - j->play_frame_size = 40; - break; - default: - j->play_frame_size = 120; - break; - } - j->play_mode = 2; - break; - case ALAW: - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 80; - break; - case 0x50: - j->play_frame_size = 40; - break; - default: - j->play_frame_size = 120; - break; - } - j->play_mode = 2; - break; - case LINEAR16: - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 160; - break; - case 0x50: - j->play_frame_size = 80; - break; - default: - j->play_frame_size = 240; - break; - } - j->play_mode = 6; - break; - case LINEAR8: - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 80; - break; - case 0x50: - j->play_frame_size = 40; - break; - default: - j->play_frame_size = 120; - break; - } - j->play_mode = 4; - break; - case WSS: - switch (j->baseframe.low) { - case 0xA0: - j->play_frame_size = 80; - break; - case 0x50: - j->play_frame_size = 40; - break; - default: - j->play_frame_size = 120; - break; - } - j->play_mode = 5; - break; - default: - kfree(j->write_buffer); - j->play_frame_size = 0; - j->play_mode = -1; - j->write_buffer = NULL; - j->write_buffer_size = 0; - retval = 1; - break; - } - return retval; -} - -static int ixj_play_start(IXJ *j) -{ - unsigned short cmd = 0x0000; - - if (j->write_buffer) { - ixj_play_stop(j); - } - - if(ixjdebug & 0x0002) - printk("IXJ %d Starting Play Codec %d at %ld\n", j->board, j->play_codec, jiffies); - - j->flags.playing = 1; - ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */ - - j->flags.play_first_frame = 1; - j->drybuffer = 0; - - if (!j->play_mode) { - switch (j->play_codec) { - case G723_63: - cmd = 0x5231; - break; - case G723_53: - cmd = 0x5232; - break; - case TS85: - cmd = 0x5230; /* TrueSpeech 8.5 */ - - break; - case TS48: - cmd = 0x5233; /* TrueSpeech 4.8 */ - - break; - case TS41: - cmd = 0x5234; /* TrueSpeech 4.1 */ - - break; - case G728: - cmd = 0x5235; - break; - case G729: - case G729B: - cmd = 0x5236; - break; - default: - return 1; - } - if (ixj_WriteDSPCommand(cmd, j)) - return -1; - } - j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC); - if (!j->write_buffer) { - printk("Write buffer allocation for ixj board %d failed!\n", j->board); - return -ENOMEM; - } -/* j->write_buffers_empty = 2; */ - j->write_buffers_empty = 1; - j->write_buffer_size = j->play_frame_size * 2; - j->write_buffer_end = j->write_buffer + j->play_frame_size * 2; - j->write_buffer_rp = j->write_buffer_wp = j->write_buffer; - - if (ixj_WriteDSPCommand(0x5202, j)) /* Set Poll sync mode */ - - return -1; - - switch (j->play_mode) { - case 0: - cmd = 0x2C03; - break; - case 2: - if (j->ver.low == 0x12) { - cmd = 0x2C23; - } else { - cmd = 0x2C21; - } - break; - case 4: - if (j->ver.low == 0x12) { - cmd = 0x2C43; - } else { - cmd = 0x2C41; - } - break; - case 5: - if (j->ver.low == 0x12) { - cmd = 0x2C53; - } else { - cmd = 0x2C51; - } - break; - case 6: - if (j->ver.low == 0x12) { - cmd = 0x2C63; - } else { - cmd = 0x2C61; - } - break; - } - if (ixj_WriteDSPCommand(cmd, j)) - return -1; - - if (ixj_WriteDSPCommand(0x2000, j)) /* Playback C2 */ - return -1; - - if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j)) /* Playback C3 */ - return -1; - - if (j->flags.recording) { - ixj_aec_start(j, j->aec_level); - } - - return 0; -} - -static void ixj_play_stop(IXJ *j) -{ - if (ixjdebug & 0x0002) - printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies); - - kfree(j->write_buffer); - j->write_buffer = NULL; - j->write_buffer_size = 0; - if (j->play_mode > -1) { - ixj_WriteDSPCommand(0x5221, j); /* Stop playback and flush buffers. 8022 reference page 9-40 */ - - j->play_mode = -1; - } - j->flags.playing = 0; -} - -static inline int get_play_level(IXJ *j) -{ - int retval; - - ixj_WriteDSPCommand(0xCF8F, j); /* 8022 Reference page 9-38 */ - return j->ssr.high << 8 | j->ssr.low; - retval = j->ssr.high << 8 | j->ssr.low; - retval = (retval * 256) / 240; - return retval; -} - -static unsigned int ixj_poll(struct file *file_p, poll_table * wait) -{ - unsigned int mask = 0; - - IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); - - poll_wait(file_p, &(j->poll_q), wait); - if (j->read_buffer_ready > 0) - mask |= POLLIN | POLLRDNORM; /* readable */ - if (j->write_buffers_empty > 0) - mask |= POLLOUT | POLLWRNORM; /* writable */ - if (j->ex.bytes) - mask |= POLLPRI; - return mask; -} - -static int ixj_play_tone(IXJ *j, char tone) -{ - if (!j->tone_state) { - if(ixjdebug & 0x0002) { - printk("IXJ %d starting tone %d at %ld\n", j->board, tone, jiffies); - } - if (j->dsp.low == 0x20) { - idle(j); - } - j->tone_start_jif = jiffies; - - j->tone_state = 1; - } - - j->tone_index = tone; - if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j)) - return -1; - - return 0; -} - -static int ixj_set_tone_on(unsigned short arg, IXJ *j) -{ - j->tone_on_time = arg; - - if (ixj_WriteDSPCommand(0x6E04, j)) /* Set Tone On Period */ - - return -1; - - if (ixj_WriteDSPCommand(arg, j)) - return -1; - - return 0; -} - -static int SCI_WaitHighSCI(IXJ *j) -{ - int cnt; - - j->pld_scrr.byte = inb_p(j->XILINXbase); - if (!j->pld_scrr.bits.sci) { - for (cnt = 0; cnt < 10; cnt++) { - udelay(32); - j->pld_scrr.byte = inb_p(j->XILINXbase); - - if ((j->pld_scrr.bits.sci)) - return 1; - } - if (ixjdebug & 0x0001) - printk(KERN_INFO "SCI Wait High failed %x\n", j->pld_scrr.byte); - return 0; - } else - return 1; -} - -static int SCI_WaitLowSCI(IXJ *j) -{ - int cnt; - - j->pld_scrr.byte = inb_p(j->XILINXbase); - if (j->pld_scrr.bits.sci) { - for (cnt = 0; cnt < 10; cnt++) { - udelay(32); - j->pld_scrr.byte = inb_p(j->XILINXbase); - - if (!(j->pld_scrr.bits.sci)) - return 1; - } - if (ixjdebug & 0x0001) - printk(KERN_INFO "SCI Wait Low failed %x\n", j->pld_scrr.byte); - return 0; - } else - return 1; -} - -static int SCI_Control(IXJ *j, int control) -{ - switch (control) { - case SCI_End: - j->pld_scrw.bits.c0 = 0; /* Set PLD Serial control interface */ - - j->pld_scrw.bits.c1 = 0; /* to no selection */ - - break; - case SCI_Enable_DAA: - j->pld_scrw.bits.c0 = 1; /* Set PLD Serial control interface */ - - j->pld_scrw.bits.c1 = 0; /* to write to DAA */ - - break; - case SCI_Enable_Mixer: - j->pld_scrw.bits.c0 = 0; /* Set PLD Serial control interface */ - - j->pld_scrw.bits.c1 = 1; /* to write to mixer */ - - break; - case SCI_Enable_EEPROM: - j->pld_scrw.bits.c0 = 1; /* Set PLD Serial control interface */ - - j->pld_scrw.bits.c1 = 1; /* to write to EEPROM */ - - break; - default: - return 0; - break; - } - outb_p(j->pld_scrw.byte, j->XILINXbase); - - switch (control) { - case SCI_End: - return 1; - break; - case SCI_Enable_DAA: - case SCI_Enable_Mixer: - case SCI_Enable_EEPROM: - if (!SCI_WaitHighSCI(j)) - return 0; - break; - default: - return 0; - break; - } - return 1; -} - -static int SCI_Prepare(IXJ *j) -{ - if (!SCI_Control(j, SCI_End)) - return 0; - - if (!SCI_WaitLowSCI(j)) - return 0; - - return 1; -} - -static int ixj_get_mixer(long val, IXJ *j) -{ - int reg = (val & 0x1F00) >> 8; - return j->mix.vol[reg]; -} - -static int ixj_mixer(long val, IXJ *j) -{ - BYTES bytes; - - bytes.high = (val & 0x1F00) >> 8; - bytes.low = val & 0x00FF; - - /* save mixer value so we can get back later on */ - j->mix.vol[bytes.high] = bytes.low; - - outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03); /* Load Mixer Address */ - - outb_p(bytes.low, j->XILINXbase + 0x02); /* Load Mixer Data */ - - SCI_Control(j, SCI_Enable_Mixer); - - SCI_Control(j, SCI_End); - - return 0; -} - -static int daa_load(BYTES * p_bytes, IXJ *j) -{ - outb_p(p_bytes->high, j->XILINXbase + 0x03); - outb_p(p_bytes->low, j->XILINXbase + 0x02); - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - else - return 1; -} - -static int ixj_daa_cr4(IXJ *j, char reg) -{ - BYTES bytes; - - switch (j->daa_mode) { - case SOP_PU_SLEEP: - bytes.high = 0x14; - break; - case SOP_PU_RINGING: - bytes.high = 0x54; - break; - case SOP_PU_CONVERSATION: - bytes.high = 0x94; - break; - case SOP_PU_PULSEDIALING: - bytes.high = 0xD4; - break; - } - - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = reg; - - switch (j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGX) { - case 0: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 0; - break; - case 1: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 2; - break; - case 2: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 1; - break; - case 3: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 3; - break; - } - - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg; - - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Prepare(j)) - return 0; - - return 1; -} - -static char daa_int_read(IXJ *j) -{ - BYTES bytes; - - if (!SCI_Prepare(j)) - return 0; - - bytes.high = 0x38; - bytes.low = 0x00; - outb_p(bytes.high, j->XILINXbase + 0x03); - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - bytes.high = inb_p(j->XILINXbase + 0x03); - bytes.low = inb_p(j->XILINXbase + 0x02); - if (bytes.low != ALISDAA_ID_BYTE) { - if (ixjdebug & 0x0001) - printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low); - return 0; - } - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - if (!SCI_Control(j, SCI_End)) - return 0; - - bytes.high = inb_p(j->XILINXbase + 0x03); - bytes.low = inb_p(j->XILINXbase + 0x02); - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg = bytes.high; - - return 1; -} - -static char daa_CR_read(IXJ *j, int cr) -{ - IXJ_WORD wdata; - BYTES bytes; - - if (!SCI_Prepare(j)) - return 0; - - switch (j->daa_mode) { - case SOP_PU_SLEEP: - bytes.high = 0x30 + cr; - break; - case SOP_PU_RINGING: - bytes.high = 0x70 + cr; - break; - case SOP_PU_CONVERSATION: - bytes.high = 0xB0 + cr; - break; - case SOP_PU_PULSEDIALING: - default: - bytes.high = 0xF0 + cr; - break; - } - - bytes.low = 0x00; - - outb_p(bytes.high, j->XILINXbase + 0x03); - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - bytes.high = inb_p(j->XILINXbase + 0x03); - bytes.low = inb_p(j->XILINXbase + 0x02); - if (bytes.low != ALISDAA_ID_BYTE) { - if (ixjdebug & 0x0001) - printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low); - return 0; - } - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - if (!SCI_Control(j, SCI_End)) - return 0; - - wdata.word = inw_p(j->XILINXbase + 0x02); - - switch(cr){ - case 5: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = wdata.bytes.high; - break; - case 4: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = wdata.bytes.high; - break; - case 3: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = wdata.bytes.high; - break; - case 2: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = wdata.bytes.high; - break; - case 1: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = wdata.bytes.high; - break; - case 0: - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = wdata.bytes.high; - break; - default: - return 0; - } - return 1; -} - -static int ixj_daa_cid_reset(IXJ *j) -{ - int i; - BYTES bytes; - - if (ixjdebug & 0x0002) - printk("DAA Clearing CID ram\n"); - - if (!SCI_Prepare(j)) - return 0; - - bytes.high = 0x58; - bytes.low = 0x00; - outb_p(bytes.high, j->XILINXbase + 0x03); - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - if (!SCI_WaitHighSCI(j)) - return 0; - - for (i = 0; i < ALISDAA_CALLERID_SIZE - 1; i += 2) { - bytes.high = bytes.low = 0x00; - outb_p(bytes.high, j->XILINXbase + 0x03); - - if (i < ALISDAA_CALLERID_SIZE - 1) - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - if (!SCI_WaitHighSCI(j)) - return 0; - - } - - if (!SCI_Control(j, SCI_End)) - return 0; - - if (ixjdebug & 0x0002) - printk("DAA CID ram cleared\n"); - - return 1; -} - -static int ixj_daa_cid_read(IXJ *j) -{ - int i; - BYTES bytes; - char CID[ALISDAA_CALLERID_SIZE]; - bool mContinue; - char *pIn, *pOut; - - if (!SCI_Prepare(j)) - return 0; - - bytes.high = 0x78; - bytes.low = 0x00; - outb_p(bytes.high, j->XILINXbase + 0x03); - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - if (!SCI_WaitHighSCI(j)) - return 0; - - bytes.high = inb_p(j->XILINXbase + 0x03); - bytes.low = inb_p(j->XILINXbase + 0x02); - if (bytes.low != ALISDAA_ID_BYTE) { - if (ixjdebug & 0x0001) - printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low); - return 0; - } - for (i = 0; i < ALISDAA_CALLERID_SIZE; i += 2) { - bytes.high = bytes.low = 0x00; - outb_p(bytes.high, j->XILINXbase + 0x03); - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - if (!SCI_WaitHighSCI(j)) - return 0; - - CID[i + 0] = inb_p(j->XILINXbase + 0x03); - CID[i + 1] = inb_p(j->XILINXbase + 0x02); - } - - if (!SCI_Control(j, SCI_End)) - return 0; - - pIn = CID; - pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID; - mContinue = true; - while (mContinue) { - if ((pIn[1] & 0x03) == 0x01) { - pOut[0] = pIn[0]; - } - if ((pIn[2] & 0x0c) == 0x04) { - pOut[1] = ((pIn[2] & 0x03) << 6) | ((pIn[1] & 0xfc) >> 2); - } - if ((pIn[3] & 0x30) == 0x10) { - pOut[2] = ((pIn[3] & 0x0f) << 4) | ((pIn[2] & 0xf0) >> 4); - } - if ((pIn[4] & 0xc0) == 0x40) { - pOut[3] = ((pIn[4] & 0x3f) << 2) | ((pIn[3] & 0xc0) >> 6); - } else { - mContinue = false; - } - pIn += 5, pOut += 4; - } - memset(&j->cid, 0, sizeof(PHONE_CID)); - pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID; - pOut += 4; - strncpy(j->cid.month, pOut, 2); - pOut += 2; - strncpy(j->cid.day, pOut, 2); - pOut += 2; - strncpy(j->cid.hour, pOut, 2); - pOut += 2; - strncpy(j->cid.min, pOut, 2); - pOut += 3; - j->cid.numlen = *pOut; - pOut += 1; - strncpy(j->cid.number, pOut, j->cid.numlen); - pOut += j->cid.numlen + 1; - j->cid.namelen = *pOut; - pOut += 1; - strncpy(j->cid.name, pOut, j->cid.namelen); - - ixj_daa_cid_reset(j); - return 1; -} - -static char daa_get_version(IXJ *j) -{ - BYTES bytes; - - if (!SCI_Prepare(j)) - return 0; - - bytes.high = 0x35; - bytes.low = 0x00; - outb_p(bytes.high, j->XILINXbase + 0x03); - outb_p(bytes.low, j->XILINXbase + 0x02); - - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - bytes.high = inb_p(j->XILINXbase + 0x03); - bytes.low = inb_p(j->XILINXbase + 0x02); - if (bytes.low != ALISDAA_ID_BYTE) { - if (ixjdebug & 0x0001) - printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low); - return 0; - } - if (!SCI_Control(j, SCI_Enable_DAA)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - - bytes.high = inb_p(j->XILINXbase + 0x03); - bytes.low = inb_p(j->XILINXbase + 0x02); - if (ixjdebug & 0x0002) - printk("DAA CR5 Byte high = 0x%x low = 0x%x\n", bytes.high, bytes.low); - j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = bytes.high; - return bytes.high; -} - -static int daa_set_mode(IXJ *j, int mode) -{ - /* NOTE: - The DAA *MUST* be in the conversation mode if the - PSTN line is to be seized (PSTN line off-hook). - Taking the PSTN line off-hook while the DAA is in - a mode other than conversation mode will cause a - hardware failure of the ALIS-A part. - - NOTE: - The DAA can only go to SLEEP, RINGING or PULSEDIALING modes - if the PSTN line is on-hook. Failure to have the PSTN line - in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE - ALIS-A part. - */ - - BYTES bytes; - - j->flags.pstn_rmr = 0; - - if (!SCI_Prepare(j)) - return 0; - - switch (mode) { - case SOP_PU_RESET: - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly2 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - bytes.high = 0x10; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - daa_load(&bytes, j); - if (!SCI_Prepare(j)) - return 0; - - j->daa_mode = SOP_PU_SLEEP; - break; - case SOP_PU_SLEEP: - if(j->daa_mode == SOP_PU_SLEEP) - { - break; - } - if (ixjdebug & 0x0008) - printk(KERN_INFO "phone DAA: SOP_PU_SLEEP at %ld\n", jiffies); -/* if(j->daa_mode == SOP_PU_CONVERSATION) */ - { - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly2 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - bytes.high = 0x10; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - daa_load(&bytes, j); - if (!SCI_Prepare(j)) - return 0; - } - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly2 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - bytes.high = 0x10; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - daa_load(&bytes, j); - if (!SCI_Prepare(j)) - return 0; - - j->daa_mode = SOP_PU_SLEEP; - j->flags.pstn_ringing = 0; - j->ex.bits.pstn_ring = 0; - j->pstn_sleeptil = jiffies + (hertz / 4); - wake_up_interruptible(&j->read_q); /* Wake any blocked readers */ - wake_up_interruptible(&j->write_q); /* Wake any blocked writers */ - wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */ - break; - case SOP_PU_RINGING: - if (ixjdebug & 0x0008) - printk(KERN_INFO "phone DAA: SOP_PU_RINGING at %ld\n", jiffies); - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly2 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - bytes.high = 0x50; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - daa_load(&bytes, j); - if (!SCI_Prepare(j)) - return 0; - j->daa_mode = SOP_PU_RINGING; - break; - case SOP_PU_CONVERSATION: - if (ixjdebug & 0x0008) - printk(KERN_INFO "phone DAA: SOP_PU_CONVERSATION at %ld\n", jiffies); - bytes.high = 0x90; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - daa_load(&bytes, j); - if (!SCI_Prepare(j)) - return 0; - j->pld_slicw.bits.rly2 = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - j->pld_scrw.bits.daafsyncen = 1; /* Turn on DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->daa_mode = SOP_PU_CONVERSATION; - j->flags.pstn_ringing = 0; - j->ex.bits.pstn_ring = 0; - j->pstn_sleeptil = jiffies; - j->pstn_ring_start = j->pstn_ring_stop = j->pstn_ring_int = 0; - break; - case SOP_PU_PULSEDIALING: - if (ixjdebug & 0x0008) - printk(KERN_INFO "phone DAA: SOP_PU_PULSEDIALING at %ld\n", jiffies); - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly2 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - bytes.high = 0xD0; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - daa_load(&bytes, j); - if (!SCI_Prepare(j)) - return 0; - j->daa_mode = SOP_PU_PULSEDIALING; - break; - default: - break; - } - return 1; -} - -static int ixj_daa_write(IXJ *j) -{ - BYTES bytes; - - j->flags.pstncheck = 1; - - daa_set_mode(j, SOP_PU_SLEEP); - - if (!SCI_Prepare(j)) - return 0; - - outb_p(j->pld_scrw.byte, j->XILINXbase); - - bytes.high = 0x14; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg; - bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Prepare(j)) - return 0; - - bytes.high = 0x1F; - bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.XOP_xr6_W.reg; - bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg; - bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg; - bytes.low = j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.XOP_xr0_W.reg; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Prepare(j)) - return 0; - - bytes.high = 0x00; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x01; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x02; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x03; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x04; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x05; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x06; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x07; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x08; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x09; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x0A; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x0B; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x0C; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x0D; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x0E; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - if (!SCI_Control(j, SCI_End)) - return 0; - if (!SCI_WaitLowSCI(j)) - return 0; - - bytes.high = 0x0F; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2]; - bytes.low = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1]; - if (!daa_load(&bytes, j)) - return 0; - - bytes.high = j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0]; - bytes.low = 0x00; - if (!daa_load(&bytes, j)) - return 0; - - udelay(32); - j->pld_scrr.byte = inb_p(j->XILINXbase); - if (!SCI_Control(j, SCI_End)) - return 0; - - outb_p(j->pld_scrw.byte, j->XILINXbase); - - if (ixjdebug & 0x0002) - printk("DAA Coefficients Loaded\n"); - - j->flags.pstncheck = 0; - return 1; -} - -static int ixj_set_tone_off(unsigned short arg, IXJ *j) -{ - j->tone_off_time = arg; - if (ixj_WriteDSPCommand(0x6E05, j)) /* Set Tone Off Period */ - - return -1; - if (ixj_WriteDSPCommand(arg, j)) - return -1; - return 0; -} - -static int ixj_get_tone_on(IXJ *j) -{ - if (ixj_WriteDSPCommand(0x6E06, j)) /* Get Tone On Period */ - - return -1; - return 0; -} - -static int ixj_get_tone_off(IXJ *j) -{ - if (ixj_WriteDSPCommand(0x6E07, j)) /* Get Tone Off Period */ - - return -1; - return 0; -} - -static void ixj_busytone(IXJ *j) -{ - j->flags.ringback = 0; - j->flags.dialtone = 0; - j->flags.busytone = 1; - ixj_set_tone_on(0x07D0, j); - ixj_set_tone_off(0x07D0, j); - ixj_play_tone(j, 27); -} - -static void ixj_dialtone(IXJ *j) -{ - j->flags.ringback = 0; - j->flags.dialtone = 1; - j->flags.busytone = 0; - if (j->dsp.low == 0x20) { - return; - } else { - ixj_set_tone_on(0xFFFF, j); - ixj_set_tone_off(0x0000, j); - ixj_play_tone(j, 25); - } -} - -static void ixj_cpt_stop(IXJ *j) -{ - if(j->tone_state || j->tone_cadence_state) - { - j->flags.dialtone = 0; - j->flags.busytone = 0; - j->flags.ringback = 0; - ixj_set_tone_on(0x0001, j); - ixj_set_tone_off(0x0000, j); - ixj_play_tone(j, 0); - j->tone_state = j->tone_cadence_state = 0; - if (j->cadence_t) { - kfree(j->cadence_t->ce); - kfree(j->cadence_t); - j->cadence_t = NULL; - } - } - if (j->play_mode == -1 && j->rec_mode == -1) - idle(j); - if (j->play_mode != -1 && j->dsp.low == 0x20) - ixj_play_start(j); - if (j->rec_mode != -1 && j->dsp.low == 0x20) - ixj_record_start(j); -} - -static void ixj_ringback(IXJ *j) -{ - j->flags.busytone = 0; - j->flags.dialtone = 0; - j->flags.ringback = 1; - ixj_set_tone_on(0x0FA0, j); - ixj_set_tone_off(0x2EE0, j); - ixj_play_tone(j, 26); -} - -static void ixj_testram(IXJ *j) -{ - ixj_WriteDSPCommand(0x3001, j); /* Test External SRAM */ -} - -static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp) -{ - ixj_cadence *lcp; - IXJ_CADENCE_ELEMENT __user *cep; - IXJ_CADENCE_ELEMENT *lcep; - IXJ_TONE ti; - int err; - - lcp = kmalloc(sizeof(ixj_cadence), GFP_KERNEL); - if (lcp == NULL) - return -ENOMEM; - - err = -EFAULT; - if (copy_from_user(&lcp->elements_used, - &cp->elements_used, sizeof(int))) - goto out; - if (copy_from_user(&lcp->termination, - &cp->termination, sizeof(IXJ_CADENCE_TERM))) - goto out; - if (get_user(cep, &cp->ce)) - goto out; - - err = -EINVAL; - if ((unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT)) - goto out; - - err = -ENOMEM; - lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL); - if (!lcep) - goto out; - - err = -EFAULT; - if (copy_from_user(lcep, cep, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used)) - goto out1; - - if (j->cadence_t) { - kfree(j->cadence_t->ce); - kfree(j->cadence_t); - } - lcp->ce = (void *) lcep; - j->cadence_t = lcp; - j->tone_cadence_state = 0; - ixj_set_tone_on(lcp->ce[0].tone_on_time, j); - ixj_set_tone_off(lcp->ce[0].tone_off_time, j); - if (j->cadence_t->ce[j->tone_cadence_state].freq0) { - ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index; - ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0; - ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0; - ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1; - ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1; - ixj_init_tone(j, &ti); - } - ixj_play_tone(j, lcp->ce[0].index); - return 1; -out1: - kfree(lcep); -out: - kfree(lcp); - return err; -} - -static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp) -{ - IXJ_FILTER_CADENCE *lcp; - lcp = memdup_user(cp, sizeof(IXJ_FILTER_CADENCE)); - if (IS_ERR(lcp)) { - if(ixjdebug & 0x0001) { - printk(KERN_INFO "Could not allocate memory for cadence or could not copy cadence to kernel\n"); - } - return PTR_ERR(lcp); - } - if (lcp->filter > 5) { - if(ixjdebug & 0x0001) { - printk(KERN_INFO "Cadence out of range\n"); - } - kfree(lcp); - return -1; - } - j->cadence_f[lcp->filter].state = 0; - j->cadence_f[lcp->filter].enable = lcp->enable; - j->filter_en[lcp->filter] = j->cadence_f[lcp->filter].en_filter = lcp->en_filter; - j->cadence_f[lcp->filter].on1 = lcp->on1; - j->cadence_f[lcp->filter].on1min = 0; - j->cadence_f[lcp->filter].on1max = 0; - j->cadence_f[lcp->filter].off1 = lcp->off1; - j->cadence_f[lcp->filter].off1min = 0; - j->cadence_f[lcp->filter].off1max = 0; - j->cadence_f[lcp->filter].on2 = lcp->on2; - j->cadence_f[lcp->filter].on2min = 0; - j->cadence_f[lcp->filter].on2max = 0; - j->cadence_f[lcp->filter].off2 = lcp->off2; - j->cadence_f[lcp->filter].off2min = 0; - j->cadence_f[lcp->filter].off2max = 0; - j->cadence_f[lcp->filter].on3 = lcp->on3; - j->cadence_f[lcp->filter].on3min = 0; - j->cadence_f[lcp->filter].on3max = 0; - j->cadence_f[lcp->filter].off3 = lcp->off3; - j->cadence_f[lcp->filter].off3min = 0; - j->cadence_f[lcp->filter].off3max = 0; - if(ixjdebug & 0x0002) { - printk(KERN_INFO "Cadence %d loaded\n", lcp->filter); - } - kfree(lcp); - return 0; -} - -static void add_caps(IXJ *j) -{ - j->caps = 0; - j->caplist[j->caps].cap = PHONE_VENDOR_QUICKNET; - strcpy(j->caplist[j->caps].desc, "Quicknet Technologies, Inc. (www.quicknet.net)"); - j->caplist[j->caps].captype = vendor; - j->caplist[j->caps].handle = j->caps; - j->caps++; - j->caplist[j->caps].captype = device; - switch (j->cardtype) { - case QTI_PHONEJACK: - strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK"); - break; - case QTI_LINEJACK: - strcpy(j->caplist[j->caps].desc, "Quicknet Internet LineJACK"); - break; - case QTI_PHONEJACK_LITE: - strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK Lite"); - break; - case QTI_PHONEJACK_PCI: - strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneJACK PCI"); - break; - case QTI_PHONECARD: - strcpy(j->caplist[j->caps].desc, "Quicknet Internet PhoneCARD"); - break; - } - j->caplist[j->caps].cap = j->cardtype; - j->caplist[j->caps].handle = j->caps; - j->caps++; - strcpy(j->caplist[j->caps].desc, "POTS"); - j->caplist[j->caps].captype = port; - j->caplist[j->caps].cap = pots; - j->caplist[j->caps].handle = j->caps; - j->caps++; - - /* add devices that can do speaker/mic */ - switch (j->cardtype) { - case QTI_PHONEJACK: - case QTI_LINEJACK: - case QTI_PHONEJACK_PCI: - case QTI_PHONECARD: - strcpy(j->caplist[j->caps].desc, "SPEAKER"); - j->caplist[j->caps].captype = port; - j->caplist[j->caps].cap = speaker; - j->caplist[j->caps].handle = j->caps; - j->caps++; - default: - break; - } - - /* add devices that can do handset */ - switch (j->cardtype) { - case QTI_PHONEJACK: - strcpy(j->caplist[j->caps].desc, "HANDSET"); - j->caplist[j->caps].captype = port; - j->caplist[j->caps].cap = handset; - j->caplist[j->caps].handle = j->caps; - j->caps++; - break; - default: - break; - } - - /* add devices that can do PSTN */ - switch (j->cardtype) { - case QTI_LINEJACK: - strcpy(j->caplist[j->caps].desc, "PSTN"); - j->caplist[j->caps].captype = port; - j->caplist[j->caps].cap = pstn; - j->caplist[j->caps].handle = j->caps; - j->caps++; - break; - default: - break; - } - - /* add codecs - all cards can do uLaw, linear 8/16, and Windows sound system */ - strcpy(j->caplist[j->caps].desc, "ULAW"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = ULAW; - j->caplist[j->caps].handle = j->caps; - j->caps++; - - strcpy(j->caplist[j->caps].desc, "LINEAR 16 bit"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = LINEAR16; - j->caplist[j->caps].handle = j->caps; - j->caps++; - - strcpy(j->caplist[j->caps].desc, "LINEAR 8 bit"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = LINEAR8; - j->caplist[j->caps].handle = j->caps; - j->caps++; - - strcpy(j->caplist[j->caps].desc, "Windows Sound System"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = WSS; - j->caplist[j->caps].handle = j->caps; - j->caps++; - - /* software ALAW codec, made from ULAW */ - strcpy(j->caplist[j->caps].desc, "ALAW"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = ALAW; - j->caplist[j->caps].handle = j->caps; - j->caps++; - - /* version 12 of the 8020 does the following codecs in a broken way */ - if (j->dsp.low != 0x20 || j->ver.low != 0x12) { - strcpy(j->caplist[j->caps].desc, "G.723.1 6.3kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = G723_63; - j->caplist[j->caps].handle = j->caps; - j->caps++; - - strcpy(j->caplist[j->caps].desc, "G.723.1 5.3kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = G723_53; - j->caplist[j->caps].handle = j->caps; - j->caps++; - - strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = TS48; - j->caplist[j->caps].handle = j->caps; - j->caps++; - - strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = TS41; - j->caplist[j->caps].handle = j->caps; - j->caps++; - } - - /* 8020 chips can do TS8.5 native, and 8021/8022 can load it */ - if (j->dsp.low == 0x20 || j->flags.ts85_loaded) { - strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = TS85; - j->caplist[j->caps].handle = j->caps; - j->caps++; - } - - /* 8021 chips can do G728 */ - if (j->dsp.low == 0x21) { - strcpy(j->caplist[j->caps].desc, "G.728 16kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = G728; - j->caplist[j->caps].handle = j->caps; - j->caps++; - } - - /* 8021/8022 chips can do G729 if loaded */ - if (j->dsp.low != 0x20 && j->flags.g729_loaded) { - strcpy(j->caplist[j->caps].desc, "G.729A 8kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = G729; - j->caplist[j->caps].handle = j->caps; - j->caps++; - } - if (j->dsp.low != 0x20 && j->flags.g729_loaded) { - strcpy(j->caplist[j->caps].desc, "G.729B 8kbps"); - j->caplist[j->caps].captype = codec; - j->caplist[j->caps].cap = G729B; - j->caplist[j->caps].handle = j->caps; - j->caps++; - } -} - -static int capabilities_check(IXJ *j, struct phone_capability *pcreq) -{ - int cnt; - int retval = 0; - for (cnt = 0; cnt < j->caps; cnt++) { - if (pcreq->captype == j->caplist[cnt].captype - && pcreq->cap == j->caplist[cnt].cap) { - retval = 1; - break; - } - } - return retval; -} - -static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg) -{ - IXJ_TONE ti; - IXJ_FILTER jf; - IXJ_FILTER_RAW jfr; - void __user *argp = (void __user *)arg; - struct inode *inode = file_p->f_path.dentry->d_inode; - unsigned int minor = iminor(inode); - unsigned int raise, mant; - int board = NUM(inode); - - IXJ *j = get_ixj(NUM(inode)); - - int retval = 0; - - /* - * Set up locks to ensure that only one process is talking to the DSP at a time. - * This is necessary to keep the DSP from locking up. - */ - while(test_and_set_bit(board, (void *)&j->busyflags) != 0) - schedule_timeout_interruptible(1); - if (ixjdebug & 0x0040) - printk("phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg); - if (minor >= IXJMAX) { - clear_bit(board, &j->busyflags); - return -ENODEV; - } - /* - * Check ioctls only root can use. - */ - if (!capable(CAP_SYS_ADMIN)) { - switch (cmd) { - case IXJCTL_TESTRAM: - case IXJCTL_HZ: - retval = -EPERM; - } - } - switch (cmd) { - case IXJCTL_TESTRAM: - ixj_testram(j); - retval = (j->ssr.high << 8) + j->ssr.low; - break; - case IXJCTL_CARDTYPE: - retval = j->cardtype; - break; - case IXJCTL_SERIAL: - retval = j->serial; - break; - case IXJCTL_VERSION: - { - char arg_str[100]; - snprintf(arg_str, sizeof(arg_str), - "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, - IXJ_VER_MINOR, IXJ_BLD_VER); - if (copy_to_user(argp, arg_str, strlen(arg_str))) - retval = -EFAULT; - } - break; - case PHONE_RING_CADENCE: - j->ring_cadence = arg; - break; - case IXJCTL_CIDCW: - if(arg) { - if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) { - retval = -EFAULT; - break; - } - } else { - memset(&j->cid_send, 0, sizeof(PHONE_CID)); - } - ixj_write_cidcw(j); - break; - /* Binary compatbility */ - case OLD_PHONE_RING_START: - arg = 0; - /* Fall through */ - case PHONE_RING_START: - if(arg) { - if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) { - retval = -EFAULT; - break; - } - ixj_write_cid(j); - } else { - memset(&j->cid_send, 0, sizeof(PHONE_CID)); - } - ixj_ring_start(j); - break; - case PHONE_RING_STOP: - j->flags.cringing = 0; - if(j->cadence_f[5].enable) { - j->cadence_f[5].state = 0; - } - ixj_ring_off(j); - break; - case PHONE_RING: - retval = ixj_ring(j); - break; - case PHONE_EXCEPTION: - retval = j->ex.bytes; - if(j->ex.bits.flash) { - j->flash_end = 0; - j->ex.bits.flash = 0; - } - j->ex.bits.pstn_ring = 0; - j->ex.bits.caller_id = 0; - j->ex.bits.pstn_wink = 0; - j->ex.bits.f0 = 0; - j->ex.bits.f1 = 0; - j->ex.bits.f2 = 0; - j->ex.bits.f3 = 0; - j->ex.bits.fc0 = 0; - j->ex.bits.fc1 = 0; - j->ex.bits.fc2 = 0; - j->ex.bits.fc3 = 0; - j->ex.bits.reserved = 0; - break; - case PHONE_HOOKSTATE: - j->ex.bits.hookstate = 0; - retval = j->hookstate; //j->r_hook; - break; - case IXJCTL_SET_LED: - LED_SetState(arg, j); - break; - case PHONE_FRAME: - retval = set_base_frame(j, arg); - break; - case PHONE_REC_CODEC: - retval = set_rec_codec(j, arg); - break; - case PHONE_VAD: - ixj_vad(j, arg); - break; - case PHONE_REC_START: - ixj_record_start(j); - break; - case PHONE_REC_STOP: - ixj_record_stop(j); - break; - case PHONE_REC_DEPTH: - set_rec_depth(j, arg); - break; - case PHONE_REC_VOLUME: - if(arg == -1) { - retval = get_rec_volume(j); - } - else { - set_rec_volume(j, arg); - retval = arg; - } - break; - case PHONE_REC_VOLUME_LINEAR: - if(arg == -1) { - retval = get_rec_volume_linear(j); - } - else { - set_rec_volume_linear(j, arg); - retval = arg; - } - break; - case IXJCTL_DTMF_PRESCALE: - if(arg == -1) { - retval = get_dtmf_prescale(j); - } - else { - set_dtmf_prescale(j, arg); - retval = arg; - } - break; - case PHONE_REC_LEVEL: - retval = get_rec_level(j); - break; - case IXJCTL_SC_RXG: - retval = ixj_siadc(j, arg); - break; - case IXJCTL_SC_TXG: - retval = ixj_sidac(j, arg); - break; - case IXJCTL_AEC_START: - ixj_aec_start(j, arg); - break; - case IXJCTL_AEC_STOP: - aec_stop(j); - break; - case IXJCTL_AEC_GET_LEVEL: - retval = j->aec_level; - break; - case PHONE_PLAY_CODEC: - retval = set_play_codec(j, arg); - break; - case PHONE_PLAY_START: - retval = ixj_play_start(j); - break; - case PHONE_PLAY_STOP: - ixj_play_stop(j); - break; - case PHONE_PLAY_DEPTH: - set_play_depth(j, arg); - break; - case PHONE_PLAY_VOLUME: - if(arg == -1) { - retval = get_play_volume(j); - } - else { - set_play_volume(j, arg); - retval = arg; - } - break; - case PHONE_PLAY_VOLUME_LINEAR: - if(arg == -1) { - retval = get_play_volume_linear(j); - } - else { - set_play_volume_linear(j, arg); - retval = arg; - } - break; - case PHONE_PLAY_LEVEL: - retval = get_play_level(j); - break; - case IXJCTL_DSP_TYPE: - retval = (j->dsp.high << 8) + j->dsp.low; - break; - case IXJCTL_DSP_VERSION: - retval = (j->ver.high << 8) + j->ver.low; - break; - case IXJCTL_HZ: - hertz = arg; - break; - case IXJCTL_RATE: - if (arg > hertz) - retval = -1; - else - samplerate = arg; - break; - case IXJCTL_DRYBUFFER_READ: - put_user(j->drybuffer, (unsigned long __user *) argp); - break; - case IXJCTL_DRYBUFFER_CLEAR: - j->drybuffer = 0; - break; - case IXJCTL_FRAMES_READ: - put_user(j->framesread, (unsigned long __user *) argp); - break; - case IXJCTL_FRAMES_WRITTEN: - put_user(j->frameswritten, (unsigned long __user *) argp); - break; - case IXJCTL_READ_WAIT: - put_user(j->read_wait, (unsigned long __user *) argp); - break; - case IXJCTL_WRITE_WAIT: - put_user(j->write_wait, (unsigned long __user *) argp); - break; - case PHONE_MAXRINGS: - j->maxrings = arg; - break; - case PHONE_SET_TONE_ON_TIME: - ixj_set_tone_on(arg, j); - break; - case PHONE_SET_TONE_OFF_TIME: - ixj_set_tone_off(arg, j); - break; - case PHONE_GET_TONE_ON_TIME: - if (ixj_get_tone_on(j)) { - retval = -1; - } else { - retval = (j->ssr.high << 8) + j->ssr.low; - } - break; - case PHONE_GET_TONE_OFF_TIME: - if (ixj_get_tone_off(j)) { - retval = -1; - } else { - retval = (j->ssr.high << 8) + j->ssr.low; - } - break; - case PHONE_PLAY_TONE: - if (!j->tone_state) - retval = ixj_play_tone(j, arg); - else - retval = -1; - break; - case PHONE_GET_TONE_STATE: - retval = j->tone_state; - break; - case PHONE_DTMF_READY: - retval = j->ex.bits.dtmf_ready; - break; - case PHONE_GET_DTMF: - if (ixj_hookstate(j)) { - if (j->dtmf_rp != j->dtmf_wp) { - retval = j->dtmfbuffer[j->dtmf_rp]; - j->dtmf_rp++; - if (j->dtmf_rp == 79) - j->dtmf_rp = 0; - if (j->dtmf_rp == j->dtmf_wp) { - j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0; - } - } - } - break; - case PHONE_GET_DTMF_ASCII: - if (ixj_hookstate(j)) { - if (j->dtmf_rp != j->dtmf_wp) { - switch (j->dtmfbuffer[j->dtmf_rp]) { - case 10: - retval = 42; /* '*'; */ - - break; - case 11: - retval = 48; /*'0'; */ - - break; - case 12: - retval = 35; /*'#'; */ - - break; - case 28: - retval = 65; /*'A'; */ - - break; - case 29: - retval = 66; /*'B'; */ - - break; - case 30: - retval = 67; /*'C'; */ - - break; - case 31: - retval = 68; /*'D'; */ - - break; - default: - retval = 48 + j->dtmfbuffer[j->dtmf_rp]; - break; - } - j->dtmf_rp++; - if (j->dtmf_rp == 79) - j->dtmf_rp = 0; - if(j->dtmf_rp == j->dtmf_wp) - { - j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0; - } - } - } - break; - case PHONE_DTMF_OOB: - j->flags.dtmf_oob = arg; - break; - case PHONE_DIALTONE: - ixj_dialtone(j); - break; - case PHONE_BUSY: - ixj_busytone(j); - break; - case PHONE_RINGBACK: - ixj_ringback(j); - break; - case PHONE_WINK: - if(j->cardtype == QTI_PHONEJACK) - retval = -1; - else - retval = ixj_wink(j); - break; - case PHONE_CPT_STOP: - ixj_cpt_stop(j); - break; - case PHONE_QUERY_CODEC: - { - struct phone_codec_data pd; - int val; - int proto_size[] = { - -1, - 12, 10, 16, 9, 8, 48, 5, - 40, 40, 80, 40, 40, 6 - }; - if(copy_from_user(&pd, argp, sizeof(pd))) { - retval = -EFAULT; - break; - } - if(pd.type<1 || pd.type>13) { - retval = -EPROTONOSUPPORT; - break; - } - if(pd.typebaseframe.low) - { - case 0xA0:val=2*proto_size[pd.type];break; - case 0x50:val=proto_size[pd.type];break; - default:val=proto_size[pd.type]*3;break; - } - pd.buf_min=pd.buf_max=pd.buf_opt=val; - if(copy_to_user(argp, &pd, sizeof(pd))) - retval = -EFAULT; - break; - } - case IXJCTL_DSP_IDLE: - idle(j); - break; - case IXJCTL_MIXER: - if ((arg & 0xff) == 0xff) - retval = ixj_get_mixer(arg, j); - else - ixj_mixer(arg, j); - break; - case IXJCTL_DAA_COEFF_SET: - switch (arg) { - case DAA_US: - DAA_Coeff_US(j); - retval = ixj_daa_write(j); - break; - case DAA_UK: - DAA_Coeff_UK(j); - retval = ixj_daa_write(j); - break; - case DAA_FRANCE: - DAA_Coeff_France(j); - retval = ixj_daa_write(j); - break; - case DAA_GERMANY: - DAA_Coeff_Germany(j); - retval = ixj_daa_write(j); - break; - case DAA_AUSTRALIA: - DAA_Coeff_Australia(j); - retval = ixj_daa_write(j); - break; - case DAA_JAPAN: - DAA_Coeff_Japan(j); - retval = ixj_daa_write(j); - break; - default: - retval = 1; - break; - } - break; - case IXJCTL_DAA_AGAIN: - ixj_daa_cr4(j, arg | 0x02); - break; - case IXJCTL_PSTN_LINETEST: - retval = ixj_linetest(j); - break; - case IXJCTL_VMWI: - ixj_write_vmwi(j, arg); - break; - case IXJCTL_CID: - if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID))) - retval = -EFAULT; - j->ex.bits.caller_id = 0; - break; - case IXJCTL_WINK_DURATION: - j->winktime = arg; - break; - case IXJCTL_PORT: - if (arg) - retval = ixj_set_port(j, arg); - else - retval = j->port; - break; - case IXJCTL_POTS_PSTN: - retval = ixj_set_pots(j, arg); - break; - case PHONE_CAPABILITIES: - add_caps(j); - retval = j->caps; - break; - case PHONE_CAPABILITIES_LIST: - add_caps(j); - if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps)) - retval = -EFAULT; - break; - case PHONE_CAPABILITIES_CHECK: - { - struct phone_capability cap; - if (copy_from_user(&cap, argp, sizeof(cap))) - retval = -EFAULT; - else { - add_caps(j); - retval = capabilities_check(j, &cap); - } - } - break; - case PHONE_PSTN_SET_STATE: - daa_set_mode(j, arg); - break; - case PHONE_PSTN_GET_STATE: - retval = j->daa_mode; - j->ex.bits.pstn_ring = 0; - break; - case IXJCTL_SET_FILTER: - if (copy_from_user(&jf, argp, sizeof(jf))) - retval = -EFAULT; - else - retval = ixj_init_filter(j, &jf); - break; - case IXJCTL_SET_FILTER_RAW: - if (copy_from_user(&jfr, argp, sizeof(jfr))) - retval = -EFAULT; - else - retval = ixj_init_filter_raw(j, &jfr); - break; - case IXJCTL_GET_FILTER_HIST: - if(arg<0||arg>3) - retval = -EINVAL; - else - retval = j->filter_hist[arg]; - break; - case IXJCTL_INIT_TONE: - if (copy_from_user(&ti, argp, sizeof(ti))) - retval = -EFAULT; - else - retval = ixj_init_tone(j, &ti); - break; - case IXJCTL_TONE_CADENCE: - retval = ixj_build_cadence(j, argp); - break; - case IXJCTL_FILTER_CADENCE: - retval = ixj_build_filter_cadence(j, argp); - break; - case IXJCTL_SIGCTL: - if (copy_from_user(&j->sigdef, argp, sizeof(IXJ_SIGDEF))) { - retval = -EFAULT; - break; - } - j->ixj_signals[j->sigdef.event] = j->sigdef.signal; - if(j->sigdef.event < 33) { - raise = 1; - for(mant = 0; mant < j->sigdef.event; mant++){ - raise *= 2; - } - if(j->sigdef.signal) - j->ex_sig.bytes |= raise; - else - j->ex_sig.bytes &= (raise^0xffff); - } - break; - case IXJCTL_INTERCOM_STOP: - if(arg < 0 || arg >= IXJMAX) - return -EINVAL; - j->intercom = -1; - ixj_record_stop(j); - ixj_play_stop(j); - idle(j); - get_ixj(arg)->intercom = -1; - ixj_record_stop(get_ixj(arg)); - ixj_play_stop(get_ixj(arg)); - idle(get_ixj(arg)); - break; - case IXJCTL_INTERCOM_START: - if(arg < 0 || arg >= IXJMAX) - return -EINVAL; - j->intercom = arg; - ixj_record_start(j); - ixj_play_start(j); - get_ixj(arg)->intercom = board; - ixj_play_start(get_ixj(arg)); - ixj_record_start(get_ixj(arg)); - break; - } - if (ixjdebug & 0x0040) - printk("phone%d ioctl end, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg); - clear_bit(board, &j->busyflags); - return retval; -} - -static long ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg) -{ - long ret; - mutex_lock(&ixj_mutex); - ret = do_ixj_ioctl(file_p, cmd, arg); - mutex_unlock(&ixj_mutex); - return ret; -} - -static int ixj_fasync(int fd, struct file *file_p, int mode) -{ - IXJ *j = get_ixj(NUM(file_p->f_path.dentry->d_inode)); - - return fasync_helper(fd, file_p, mode, &j->async_queue); -} - -static const struct file_operations ixj_fops = -{ - .owner = THIS_MODULE, - .read = ixj_enhanced_read, - .write = ixj_enhanced_write, - .poll = ixj_poll, - .unlocked_ioctl = ixj_ioctl, - .release = ixj_release, - .fasync = ixj_fasync, - .llseek = default_llseek, -}; - -static int ixj_linetest(IXJ *j) -{ - j->flags.pstncheck = 1; /* Testing */ - j->flags.pstn_present = 0; /* Assume the line is not there */ - - daa_int_read(j); /*Clear DAA Interrupt flags */ - /* */ - /* Hold all relays in the normally de-energized position. */ - /* */ - - j->pld_slicw.bits.rly1 = 0; - j->pld_slicw.bits.rly2 = 0; - j->pld_slicw.bits.rly3 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01); - if (j->pld_slicr.bits.potspstn) { - j->flags.pots_pstn = 1; - j->flags.pots_correct = 0; - LED_SetState(0x4, j); - } else { - j->flags.pots_pstn = 0; - j->pld_slicw.bits.rly1 = 0; - j->pld_slicw.bits.rly2 = 0; - j->pld_slicw.bits.rly3 = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - daa_set_mode(j, SOP_PU_CONVERSATION); - msleep(1000); - daa_int_read(j); - daa_set_mode(j, SOP_PU_RESET); - if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) { - j->flags.pots_correct = 0; /* Should not be line voltage on POTS port. */ - LED_SetState(0x4, j); - j->pld_slicw.bits.rly3 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - } else { - j->flags.pots_correct = 1; - LED_SetState(0x8, j); - j->pld_slicw.bits.rly1 = 1; - j->pld_slicw.bits.rly2 = 0; - j->pld_slicw.bits.rly3 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - } - } - j->pld_slicw.bits.rly3 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - daa_set_mode(j, SOP_PU_CONVERSATION); - msleep(1000); - daa_int_read(j); - daa_set_mode(j, SOP_PU_RESET); - if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) { - j->pstn_sleeptil = jiffies + (hertz / 4); - j->flags.pstn_present = 1; - } else { - j->flags.pstn_present = 0; - } - if (j->flags.pstn_present) { - if (j->flags.pots_correct) { - LED_SetState(0xA, j); - } else { - LED_SetState(0x6, j); - } - } else { - if (j->flags.pots_correct) { - LED_SetState(0x9, j); - } else { - LED_SetState(0x5, j); - } - } - j->flags.pstncheck = 0; /* Testing */ - return j->flags.pstn_present; -} - -static int ixj_selfprobe(IXJ *j) -{ - unsigned short cmd; - int cnt; - BYTES bytes; - - init_waitqueue_head(&j->poll_q); - init_waitqueue_head(&j->read_q); - init_waitqueue_head(&j->write_q); - - while(atomic_read(&j->DSPWrite) > 0) - atomic_dec(&j->DSPWrite); - if (ixjdebug & 0x0002) - printk(KERN_INFO "Write IDLE to Software Control Register\n"); - ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */ - - if (ixj_WriteDSPCommand(0x0000, j)) /* Write IDLE to Software Control Register */ - return -1; -/* The read values of the SSR should be 0x00 for the IDLE command */ - if (j->ssr.low || j->ssr.high) - return -1; - if (ixjdebug & 0x0002) - printk(KERN_INFO "Get Device ID Code\n"); - if (ixj_WriteDSPCommand(0x3400, j)) /* Get Device ID Code */ - return -1; - j->dsp.low = j->ssr.low; - j->dsp.high = j->ssr.high; - if (ixjdebug & 0x0002) - printk(KERN_INFO "Get Device Version Code\n"); - if (ixj_WriteDSPCommand(0x3800, j)) /* Get Device Version Code */ - return -1; - j->ver.low = j->ssr.low; - j->ver.high = j->ssr.high; - if (!j->cardtype) { - if (j->dsp.low == 0x21) { - bytes.high = bytes.low = inb_p(j->XILINXbase + 0x02); - outb_p(bytes.low ^ 0xFF, j->XILINXbase + 0x02); -/* Test for Internet LineJACK or Internet PhoneJACK Lite */ - bytes.low = inb_p(j->XILINXbase + 0x02); - if (bytes.low == bytes.high) /* Register is read only on */ - /* Internet PhoneJack Lite */ - { - j->cardtype = QTI_PHONEJACK_LITE; - if (!request_region(j->XILINXbase, 4, "ixj control")) { - printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); - return -1; - } - j->pld_slicw.pcib.e1 = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase); - } else { - j->cardtype = QTI_LINEJACK; - - if (!request_region(j->XILINXbase, 8, "ixj control")) { - printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); - return -1; - } - } - } else if (j->dsp.low == 0x22) { - j->cardtype = QTI_PHONEJACK_PCI; - request_region(j->XILINXbase, 4, "ixj control"); - j->pld_slicw.pcib.e1 = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase); - } else - j->cardtype = QTI_PHONEJACK; - } else { - switch (j->cardtype) { - case QTI_PHONEJACK: - if (!j->dsp.low != 0x20) { - j->dsp.high = 0x80; - j->dsp.low = 0x20; - ixj_WriteDSPCommand(0x3800, j); - j->ver.low = j->ssr.low; - j->ver.high = j->ssr.high; - } - break; - case QTI_LINEJACK: - if (!request_region(j->XILINXbase, 8, "ixj control")) { - printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); - return -1; - } - break; - case QTI_PHONEJACK_LITE: - case QTI_PHONEJACK_PCI: - if (!request_region(j->XILINXbase, 4, "ixj control")) { - printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase); - return -1; - } - j->pld_slicw.pcib.e1 = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase); - break; - case QTI_PHONECARD: - break; - } - } - if (j->dsp.low == 0x20 || j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) { - if (ixjdebug & 0x0002) - printk(KERN_INFO "Write CODEC config to Software Control Register\n"); - if (ixj_WriteDSPCommand(0xC462, j)) /* Write CODEC config to Software Control Register */ - return -1; - if (ixjdebug & 0x0002) - printk(KERN_INFO "Write CODEC timing to Software Control Register\n"); - if (j->cardtype == QTI_PHONEJACK) { - cmd = 0x9FF2; - } else { - cmd = 0x9FF5; - } - if (ixj_WriteDSPCommand(cmd, j)) /* Write CODEC timing to Software Control Register */ - return -1; - } else { - if (set_base_frame(j, 30) != 30) - return -1; - if (ixjdebug & 0x0002) - printk(KERN_INFO "Write CODEC config to Software Control Register\n"); - if (j->cardtype == QTI_PHONECARD) { - if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to Software Control Register */ - return -1; - } - if (j->cardtype == QTI_LINEJACK) { - if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to Software Control Register */ - return -1; - if (ixjdebug & 0x0002) - printk(KERN_INFO "Turn on the PLD Clock at 8Khz\n"); - j->pld_clock.byte = 0; - outb_p(j->pld_clock.byte, j->XILINXbase + 0x04); - } - } - - if (j->dsp.low == 0x20) { - if (ixjdebug & 0x0002) - printk(KERN_INFO "Configure GPIO pins\n"); - j->gpio.bytes.high = 0x09; -/* bytes.low = 0xEF; 0xF7 */ - j->gpio.bits.gpio1 = 1; - j->gpio.bits.gpio2 = 1; - j->gpio.bits.gpio3 = 0; - j->gpio.bits.gpio4 = 1; - j->gpio.bits.gpio5 = 1; - j->gpio.bits.gpio6 = 1; - j->gpio.bits.gpio7 = 1; - ixj_WriteDSPCommand(j->gpio.word, j); /* Set GPIO pin directions */ - if (ixjdebug & 0x0002) - printk(KERN_INFO "Enable SLIC\n"); - j->gpio.bytes.high = 0x0B; - j->gpio.bytes.low = 0x00; - j->gpio.bits.gpio1 = 0; - j->gpio.bits.gpio2 = 1; - j->gpio.bits.gpio5 = 0; - ixj_WriteDSPCommand(j->gpio.word, j); /* send the ring stop signal */ - j->port = PORT_POTS; - } else { - if (j->cardtype == QTI_LINEJACK) { - LED_SetState(0x1, j); - msleep(100); - LED_SetState(0x2, j); - msleep(100); - LED_SetState(0x4, j); - msleep(100); - LED_SetState(0x8, j); - msleep(100); - LED_SetState(0x0, j); - daa_get_version(j); - if (ixjdebug & 0x0002) - printk("Loading DAA Coefficients\n"); - DAA_Coeff_US(j); - if (!ixj_daa_write(j)) { - printk("DAA write failed on board %d\n", j->board); - return -1; - } - if(!ixj_daa_cid_reset(j)) { - printk("DAA CID reset failed on board %d\n", j->board); - return -1; - } - j->flags.pots_correct = 0; - j->flags.pstn_present = 0; - ixj_linetest(j); - if (j->flags.pots_correct) { - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly1 = 1; - j->pld_slicw.bits.spken = 1; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); -/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */ - j->port = PORT_POTS; - } - ixj_set_port(j, PORT_PSTN); - ixj_set_pots(j, 1); - if (ixjdebug & 0x0002) - printk(KERN_INFO "Enable Mixer\n"); - ixj_mixer(0x0000, j); /*Master Volume Left unmute 0db */ - ixj_mixer(0x0100, j); /*Master Volume Right unmute 0db */ - - ixj_mixer(0x0203, j); /*Voice Left Volume unmute 6db */ - ixj_mixer(0x0303, j); /*Voice Right Volume unmute 6db */ - - ixj_mixer(0x0480, j); /*FM Left mute */ - ixj_mixer(0x0580, j); /*FM Right mute */ - - ixj_mixer(0x0680, j); /*CD Left mute */ - ixj_mixer(0x0780, j); /*CD Right mute */ - - ixj_mixer(0x0880, j); /*Line Left mute */ - ixj_mixer(0x0980, j); /*Line Right mute */ - - ixj_mixer(0x0A80, j); /*Aux left mute */ - ixj_mixer(0x0B80, j); /*Aux right mute */ - - ixj_mixer(0x0C00, j); /*Mono1 unmute 12db */ - ixj_mixer(0x0D80, j); /*Mono2 mute */ - - ixj_mixer(0x0E80, j); /*Mic mute */ - - ixj_mixer(0x0F00, j); /*Mono Out Volume unmute 0db */ - - ixj_mixer(0x1000, j); /*Voice Left and Right out only */ - ixj_mixer(0x110C, j); - - - ixj_mixer(0x1200, j); /*Mono1 switch on mixer left */ - ixj_mixer(0x1401, j); - - ixj_mixer(0x1300, j); /*Mono1 switch on mixer right */ - ixj_mixer(0x1501, j); - - ixj_mixer(0x1700, j); /*Clock select */ - - ixj_mixer(0x1800, j); /*ADC input from mixer */ - - ixj_mixer(0x1901, j); /*Mic gain 30db */ - - if (ixjdebug & 0x0002) - printk(KERN_INFO "Setting Default US Ring Cadence Detection\n"); - j->cadence_f[4].state = 0; - j->cadence_f[4].on1 = 0; /*Cadence Filter 4 is used for PSTN ring cadence */ - j->cadence_f[4].off1 = 0; - j->cadence_f[4].on2 = 0; - j->cadence_f[4].off2 = 0; - j->cadence_f[4].on3 = 0; - j->cadence_f[4].off3 = 0; /* These should represent standard US ring pulse. */ - j->pstn_last_rmr = jiffies; - - } else { - if (j->cardtype == QTI_PHONECARD) { - ixj_WriteDSPCommand(0xCF07, j); - ixj_WriteDSPCommand(0x00B0, j); - ixj_set_port(j, PORT_SPEAKER); - } else { - ixj_set_port(j, PORT_POTS); - SLIC_SetState(PLD_SLIC_STATE_STANDBY, j); -/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */ - } - } - } - - j->intercom = -1; - j->framesread = j->frameswritten = 0; - j->read_wait = j->write_wait = 0; - j->rxreadycheck = j->txreadycheck = 0; - - /* initialise the DTMF prescale to a sensible value */ - if (j->cardtype == QTI_LINEJACK) { - set_dtmf_prescale(j, 0x10); - } else { - set_dtmf_prescale(j, 0x40); - } - set_play_volume(j, 0x100); - set_rec_volume(j, 0x100); - - if (ixj_WriteDSPCommand(0x0000, j)) /* Write IDLE to Software Control Register */ - return -1; -/* The read values of the SSR should be 0x00 for the IDLE command */ - if (j->ssr.low || j->ssr.high) - return -1; - - if (ixjdebug & 0x0002) - printk(KERN_INFO "Enable Line Monitor\n"); - - if (ixjdebug & 0x0002) - printk(KERN_INFO "Set Line Monitor to Asynchronous Mode\n"); - - if (ixj_WriteDSPCommand(0x7E01, j)) /* Asynchronous Line Monitor */ - return -1; - - if (ixjdebug & 0x002) - printk(KERN_INFO "Enable DTMF Detectors\n"); - - if (ixj_WriteDSPCommand(0x5151, j)) /* Enable DTMF detection */ - return -1; - - if (ixj_WriteDSPCommand(0x6E01, j)) /* Set Asynchronous Tone Generation */ - return -1; - - set_rec_depth(j, 2); /* Set Record Channel Limit to 2 frames */ - - set_play_depth(j, 2); /* Set Playback Channel Limit to 2 frames */ - - j->ex.bits.dtmf_ready = 0; - j->dtmf_state = 0; - j->dtmf_wp = j->dtmf_rp = 0; - j->rec_mode = j->play_mode = -1; - j->flags.ringing = 0; - j->maxrings = MAXRINGS; - j->ring_cadence = USA_RING_CADENCE; - j->drybuffer = 0; - j->winktime = 320; - j->flags.dtmf_oob = 0; - for (cnt = 0; cnt < 4; cnt++) - j->cadence_f[cnt].enable = 0; - /* must be a device on the specified address */ - ixj_WriteDSPCommand(0x0FE3, j); /* Put the DSP in 1/5 power mode. */ - - /* Set up the default signals for events */ - for (cnt = 0; cnt < 35; cnt++) - j->ixj_signals[cnt] = SIGIO; - - /* Set the exception signal enable flags */ - j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = - j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = - j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1; -#ifdef IXJ_DYN_ALLOC - j->fskdata = NULL; -#endif - j->fskdcnt = 0; - j->cidcw_wait = 0; - - /* Register with the Telephony for Linux subsystem */ - j->p.f_op = &ixj_fops; - j->p.open = ixj_open; - j->p.board = j->board; - phone_register_device(&j->p, PHONE_UNIT_ANY); - - ixj_init_timer(j); - ixj_add_timer(j); - return 0; -} - -/* - * Exported service for pcmcia card handling - */ - -IXJ *ixj_pcmcia_probe(unsigned long dsp, unsigned long xilinx) -{ - IXJ *j = ixj_alloc(); - - j->board = 0; - - j->DSPbase = dsp; - j->XILINXbase = xilinx; - j->cardtype = QTI_PHONECARD; - ixj_selfprobe(j); - return j; -} - -EXPORT_SYMBOL(ixj_pcmcia_probe); /* For PCMCIA */ - -static int ixj_get_status_proc(char *buf) -{ - int len; - int cnt; - IXJ *j; - len = 0; - len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER); - len += sprintf(buf + len, "\nsizeof IXJ struct %Zd bytes", sizeof(IXJ)); - len += sprintf(buf + len, "\nsizeof DAA struct %Zd bytes", sizeof(DAA_REGS)); - len += sprintf(buf + len, "\nUsing old telephony API"); - len += sprintf(buf + len, "\nDebug Level %d\n", ixjdebug); - - for (cnt = 0; cnt < IXJMAX; cnt++) { - j = get_ixj(cnt); - if(j==NULL) - continue; - if (j->DSPbase) { - len += sprintf(buf + len, "\nCard Num %d", cnt); - len += sprintf(buf + len, "\nDSP Base Address 0x%4.4x", j->DSPbase); - if (j->cardtype != QTI_PHONEJACK) - len += sprintf(buf + len, "\nXILINX Base Address 0x%4.4x", j->XILINXbase); - len += sprintf(buf + len, "\nDSP Type %2.2x%2.2x", j->dsp.high, j->dsp.low); - len += sprintf(buf + len, "\nDSP Version %2.2x.%2.2x", j->ver.high, j->ver.low); - len += sprintf(buf + len, "\nSerial Number %8.8x", j->serial); - switch (j->cardtype) { - case (QTI_PHONEJACK): - len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK"); - break; - case (QTI_LINEJACK): - len += sprintf(buf + len, "\nCard Type = Internet LineJACK"); - if (j->flags.g729_loaded) - len += sprintf(buf + len, " w/G.729 A/B"); - len += sprintf(buf + len, " Country = %d", j->daa_country); - break; - case (QTI_PHONEJACK_LITE): - len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK Lite"); - if (j->flags.g729_loaded) - len += sprintf(buf + len, " w/G.729 A/B"); - break; - case (QTI_PHONEJACK_PCI): - len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK PCI"); - if (j->flags.g729_loaded) - len += sprintf(buf + len, " w/G.729 A/B"); - break; - case (QTI_PHONECARD): - len += sprintf(buf + len, "\nCard Type = Internet PhoneCARD"); - if (j->flags.g729_loaded) - len += sprintf(buf + len, " w/G.729 A/B"); - len += sprintf(buf + len, "\nSmart Cable %spresent", j->pccr1.bits.drf ? "not " : ""); - if (!j->pccr1.bits.drf) - len += sprintf(buf + len, "\nSmart Cable type %d", j->flags.pcmciasct); - len += sprintf(buf + len, "\nSmart Cable state %d", j->flags.pcmciastate); - break; - default: - len += sprintf(buf + len, "\nCard Type = %d", j->cardtype); - break; - } - len += sprintf(buf + len, "\nReaders %d", j->readers); - len += sprintf(buf + len, "\nWriters %d", j->writers); - add_caps(j); - len += sprintf(buf + len, "\nCapabilities %d", j->caps); - if (j->dsp.low != 0x20) - len += sprintf(buf + len, "\nDSP Processor load %d", j->proc_load); - if (j->flags.cidsent) - len += sprintf(buf + len, "\nCaller ID data sent"); - else - len += sprintf(buf + len, "\nCaller ID data not sent"); - - len += sprintf(buf + len, "\nPlay CODEC "); - switch (j->play_codec) { - case G723_63: - len += sprintf(buf + len, "G.723.1 6.3"); - break; - case G723_53: - len += sprintf(buf + len, "G.723.1 5.3"); - break; - case TS85: - len += sprintf(buf + len, "TrueSpeech 8.5"); - break; - case TS48: - len += sprintf(buf + len, "TrueSpeech 4.8"); - break; - case TS41: - len += sprintf(buf + len, "TrueSpeech 4.1"); - break; - case G728: - len += sprintf(buf + len, "G.728"); - break; - case G729: - len += sprintf(buf + len, "G.729"); - break; - case G729B: - len += sprintf(buf + len, "G.729B"); - break; - case ULAW: - len += sprintf(buf + len, "uLaw"); - break; - case ALAW: - len += sprintf(buf + len, "aLaw"); - break; - case LINEAR16: - len += sprintf(buf + len, "16 bit Linear"); - break; - case LINEAR8: - len += sprintf(buf + len, "8 bit Linear"); - break; - case WSS: - len += sprintf(buf + len, "Windows Sound System"); - break; - default: - len += sprintf(buf + len, "NO CODEC CHOSEN"); - break; - } - len += sprintf(buf + len, "\nRecord CODEC "); - switch (j->rec_codec) { - case G723_63: - len += sprintf(buf + len, "G.723.1 6.3"); - break; - case G723_53: - len += sprintf(buf + len, "G.723.1 5.3"); - break; - case TS85: - len += sprintf(buf + len, "TrueSpeech 8.5"); - break; - case TS48: - len += sprintf(buf + len, "TrueSpeech 4.8"); - break; - case TS41: - len += sprintf(buf + len, "TrueSpeech 4.1"); - break; - case G728: - len += sprintf(buf + len, "G.728"); - break; - case G729: - len += sprintf(buf + len, "G.729"); - break; - case G729B: - len += sprintf(buf + len, "G.729B"); - break; - case ULAW: - len += sprintf(buf + len, "uLaw"); - break; - case ALAW: - len += sprintf(buf + len, "aLaw"); - break; - case LINEAR16: - len += sprintf(buf + len, "16 bit Linear"); - break; - case LINEAR8: - len += sprintf(buf + len, "8 bit Linear"); - break; - case WSS: - len += sprintf(buf + len, "Windows Sound System"); - break; - default: - len += sprintf(buf + len, "NO CODEC CHOSEN"); - break; - } - len += sprintf(buf + len, "\nAEC "); - switch (j->aec_level) { - case AEC_OFF: - len += sprintf(buf + len, "Off"); - break; - case AEC_LOW: - len += sprintf(buf + len, "Low"); - break; - case AEC_MED: - len += sprintf(buf + len, "Med"); - break; - case AEC_HIGH: - len += sprintf(buf + len, "High"); - break; - case AEC_AUTO: - len += sprintf(buf + len, "Auto"); - break; - case AEC_AGC: - len += sprintf(buf + len, "AEC/AGC"); - break; - default: - len += sprintf(buf + len, "unknown(%i)", j->aec_level); - break; - } - - len += sprintf(buf + len, "\nRec volume 0x%x", get_rec_volume(j)); - len += sprintf(buf + len, "\nPlay volume 0x%x", get_play_volume(j)); - len += sprintf(buf + len, "\nDTMF prescale 0x%x", get_dtmf_prescale(j)); - - len += sprintf(buf + len, "\nHook state %d", j->hookstate); /* j->r_hook); */ - - if (j->cardtype == QTI_LINEJACK) { - len += sprintf(buf + len, "\nPOTS Correct %d", j->flags.pots_correct); - len += sprintf(buf + len, "\nPSTN Present %d", j->flags.pstn_present); - len += sprintf(buf + len, "\nPSTN Check %d", j->flags.pstncheck); - len += sprintf(buf + len, "\nPOTS to PSTN %d", j->flags.pots_pstn); - switch (j->daa_mode) { - case SOP_PU_SLEEP: - len += sprintf(buf + len, "\nDAA PSTN On Hook"); - break; - case SOP_PU_RINGING: - len += sprintf(buf + len, "\nDAA PSTN Ringing"); - len += sprintf(buf + len, "\nRinging state = %d", j->cadence_f[4].state); - break; - case SOP_PU_CONVERSATION: - len += sprintf(buf + len, "\nDAA PSTN Off Hook"); - break; - case SOP_PU_PULSEDIALING: - len += sprintf(buf + len, "\nDAA PSTN Pulse Dialing"); - break; - } - len += sprintf(buf + len, "\nDAA RMR = %d", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR); - len += sprintf(buf + len, "\nDAA VDD OK = %d", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK); - len += sprintf(buf + len, "\nDAA CR0 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg); - len += sprintf(buf + len, "\nDAA CR1 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg); - len += sprintf(buf + len, "\nDAA CR2 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg); - len += sprintf(buf + len, "\nDAA CR3 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg); - len += sprintf(buf + len, "\nDAA CR4 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg); - len += sprintf(buf + len, "\nDAA CR5 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg); - len += sprintf(buf + len, "\nDAA XR0 = 0x%02x", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg); - len += sprintf(buf + len, "\nDAA ringstop %ld - jiffies %ld", j->pstn_ring_stop, jiffies); - } - switch (j->port) { - case PORT_POTS: - len += sprintf(buf + len, "\nPort POTS"); - break; - case PORT_PSTN: - len += sprintf(buf + len, "\nPort PSTN"); - break; - case PORT_SPEAKER: - len += sprintf(buf + len, "\nPort SPEAKER/MIC"); - break; - case PORT_HANDSET: - len += sprintf(buf + len, "\nPort HANDSET"); - break; - } - if (j->dsp.low == 0x21 || j->dsp.low == 0x22) { - len += sprintf(buf + len, "\nSLIC state "); - switch (SLIC_GetState(j)) { - case PLD_SLIC_STATE_OC: - len += sprintf(buf + len, "OC"); - break; - case PLD_SLIC_STATE_RINGING: - len += sprintf(buf + len, "RINGING"); - break; - case PLD_SLIC_STATE_ACTIVE: - len += sprintf(buf + len, "ACTIVE"); - break; - case PLD_SLIC_STATE_OHT: /* On-hook transmit */ - len += sprintf(buf + len, "OHT"); - break; - case PLD_SLIC_STATE_TIPOPEN: - len += sprintf(buf + len, "TIPOPEN"); - break; - case PLD_SLIC_STATE_STANDBY: - len += sprintf(buf + len, "STANDBY"); - break; - case PLD_SLIC_STATE_APR: /* Active polarity reversal */ - len += sprintf(buf + len, "APR"); - break; - case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */ - len += sprintf(buf + len, "OHTPR"); - break; - default: - len += sprintf(buf + len, "%d", SLIC_GetState(j)); - break; - } - } - len += sprintf(buf + len, "\nBase Frame %2.2x.%2.2x", j->baseframe.high, j->baseframe.low); - len += sprintf(buf + len, "\nCID Base Frame %2d", j->cid_base_frame_size); -#ifdef PERFMON_STATS - len += sprintf(buf + len, "\nTimer Checks %ld", j->timerchecks); - len += sprintf(buf + len, "\nRX Ready Checks %ld", j->rxreadycheck); - len += sprintf(buf + len, "\nTX Ready Checks %ld", j->txreadycheck); - len += sprintf(buf + len, "\nFrames Read %ld", j->framesread); - len += sprintf(buf + len, "\nFrames Written %ld", j->frameswritten); - len += sprintf(buf + len, "\nDry Buffer %ld", j->drybuffer); - len += sprintf(buf + len, "\nRead Waits %ld", j->read_wait); - len += sprintf(buf + len, "\nWrite Waits %ld", j->write_wait); - len += sprintf(buf + len, "\nStatus Waits %ld", j->statuswait); - len += sprintf(buf + len, "\nStatus Wait Fails %ld", j->statuswaitfail); - len += sprintf(buf + len, "\nPControl Waits %ld", j->pcontrolwait); - len += sprintf(buf + len, "\nPControl Wait Fails %ld", j->pcontrolwaitfail); - len += sprintf(buf + len, "\nIs Control Ready Checks %ld", j->iscontrolready); - len += sprintf(buf + len, "\nIs Control Ready Check failures %ld", j->iscontrolreadyfail); - -#endif - len += sprintf(buf + len, "\n"); - } - } - return len; -} - -static int ixj_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = ixj_get_status_proc(page); - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; -} - - -static void cleanup(void) -{ - int cnt; - IXJ *j; - - for (cnt = 0; cnt < IXJMAX; cnt++) { - j = get_ixj(cnt); - if(j != NULL && j->DSPbase) { - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Deleting timer for /dev/phone%d\n", cnt); - del_timer(&j->timer); - if (j->cardtype == QTI_LINEJACK) { - j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */ - - outb_p(j->pld_scrw.byte, j->XILINXbase); - j->pld_slicw.bits.rly1 = 0; - j->pld_slicw.bits.rly2 = 0; - j->pld_slicw.bits.rly3 = 0; - outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01); - LED_SetState(0x0, j); - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt); - release_region(j->XILINXbase, 8); - } else if (j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) { - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt); - release_region(j->XILINXbase, 4); - } - kfree(j->read_buffer); - kfree(j->write_buffer); - if (j->dev) - pnp_device_detach(j->dev); - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Unregistering /dev/phone%d from LTAPI\n", cnt); - phone_unregister_device(&j->p); - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Releasing DSP address for /dev/phone%d\n", cnt); - release_region(j->DSPbase, 16); -#ifdef IXJ_DYN_ALLOC - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Freeing memory for /dev/phone%d\n", cnt); - kfree(j); - ixj[cnt] = NULL; -#endif - } - } - if (ixjdebug & 0x0002) - printk(KERN_INFO "IXJ: Removing /proc/ixj\n"); - remove_proc_entry ("ixj", NULL); -} - -/* Typedefs */ -typedef struct { - BYTE length; - DWORD bits; -} DATABLOCK; - -static void PCIEE_WriteBit(WORD wEEPROMAddress, BYTE lastLCC, BYTE byData) -{ - lastLCC = lastLCC & 0xfb; - lastLCC = lastLCC | (byData ? 4 : 0); - outb(lastLCC, wEEPROMAddress); /*set data out bit as appropriate */ - - mdelay(1); - lastLCC = lastLCC | 0x01; - outb(lastLCC, wEEPROMAddress); /*SK rising edge */ - - byData = byData << 1; - lastLCC = lastLCC & 0xfe; - mdelay(1); - outb(lastLCC, wEEPROMAddress); /*after delay, SK falling edge */ - -} - -static BYTE PCIEE_ReadBit(WORD wEEPROMAddress, BYTE lastLCC) -{ - mdelay(1); - lastLCC = lastLCC | 0x01; - outb(lastLCC, wEEPROMAddress); /*SK rising edge */ - - lastLCC = lastLCC & 0xfe; - mdelay(1); - outb(lastLCC, wEEPROMAddress); /*after delay, SK falling edge */ - - return ((inb(wEEPROMAddress) >> 3) & 1); -} - -static bool PCIEE_ReadWord(WORD wAddress, WORD wLoc, WORD * pwResult) -{ - BYTE lastLCC; - WORD wEEPROMAddress = wAddress + 3; - DWORD i; - BYTE byResult; - *pwResult = 0; - lastLCC = inb(wEEPROMAddress); - lastLCC = lastLCC | 0x02; - lastLCC = lastLCC & 0xfe; - outb(lastLCC, wEEPROMAddress); /* CS hi, SK lo */ - - mdelay(1); /* delay */ - - PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1); - PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1); - PCIEE_WriteBit(wEEPROMAddress, lastLCC, 0); - for (i = 0; i < 8; i++) { - PCIEE_WriteBit(wEEPROMAddress, lastLCC, wLoc & 0x80 ? 1 : 0); - wLoc <<= 1; - } - - for (i = 0; i < 16; i++) { - byResult = PCIEE_ReadBit(wEEPROMAddress, lastLCC); - *pwResult = (*pwResult << 1) | byResult; - } - - mdelay(1); /* another delay */ - - lastLCC = lastLCC & 0xfd; - outb(lastLCC, wEEPROMAddress); /* negate CS */ - - return 0; -} - -static DWORD PCIEE_GetSerialNumber(WORD wAddress) -{ - WORD wLo, wHi; - if (PCIEE_ReadWord(wAddress, 62, &wLo)) - return 0; - if (PCIEE_ReadWord(wAddress, 63, &wHi)) - return 0; - return (((DWORD) wHi << 16) | wLo); -} - -static int dspio[IXJMAX + 1] = -{ - 0, -}; -static int xio[IXJMAX + 1] = -{ - 0, -}; - -module_param_array(dspio, int, NULL, 0); -module_param_array(xio, int, NULL, 0); -MODULE_DESCRIPTION("Quicknet VoIP Telephony card module - www.quicknet.net"); -MODULE_AUTHOR("Ed Okerson "); -MODULE_LICENSE("GPL"); - -static void __exit ixj_exit(void) -{ - cleanup(); -} - -static IXJ *new_ixj(unsigned long port) -{ - IXJ *res; - if (!request_region(port, 16, "ixj DSP")) { - printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n", port); - return NULL; - } - res = ixj_alloc(); - if (!res) { - release_region(port, 16); - printk(KERN_INFO "ixj: out of memory\n"); - return NULL; - } - res->DSPbase = port; - return res; -} - -static int __init ixj_probe_isapnp(int *cnt) -{ - int probe = 0; - int func = 0x110; - struct pnp_dev *dev = NULL, *old_dev = NULL; - - while (1) { - do { - IXJ *j; - int result; - - old_dev = dev; - dev = pnp_find_dev(NULL, ISAPNP_VENDOR('Q', 'T', 'I'), - ISAPNP_FUNCTION(func), old_dev); - if (!dev || !dev->card) - break; - result = pnp_device_attach(dev); - if (result < 0) { - printk("pnp attach failed %d \n", result); - break; - } - if (pnp_activate_dev(dev) < 0) { - printk("pnp activate failed (out of resources?)\n"); - pnp_device_detach(dev); - return -ENOMEM; - } - - if (!pnp_port_valid(dev, 0)) { - pnp_device_detach(dev); - return -ENODEV; - } - - j = new_ixj(pnp_port_start(dev, 0)); - if (!j) - break; - - if (func != 0x110) - j->XILINXbase = pnp_port_start(dev, 1); /* get real port */ - - switch (func) { - case (0x110): - j->cardtype = QTI_PHONEJACK; - break; - case (0x310): - j->cardtype = QTI_LINEJACK; - break; - case (0x410): - j->cardtype = QTI_PHONEJACK_LITE; - break; - } - j->board = *cnt; - probe = ixj_selfprobe(j); - if(!probe) { - j->serial = dev->card->serial; - j->dev = dev; - switch (func) { - case 0x110: - printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n", j->DSPbase); - break; - case 0x310: - printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n", j->DSPbase); - break; - case 0x410: - printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n", j->DSPbase); - break; - } - } - ++*cnt; - } while (dev); - if (func == 0x410) - break; - if (func == 0x310) - func = 0x410; - if (func == 0x110) - func = 0x310; - dev = NULL; - } - return probe; -} - -static int __init ixj_probe_isa(int *cnt) -{ - int i, probe; - - /* Use passed parameters for older kernels without PnP */ - for (i = 0; i < IXJMAX; i++) { - if (dspio[i]) { - IXJ *j = new_ixj(dspio[i]); - - if (!j) - break; - - j->XILINXbase = xio[i]; - j->cardtype = 0; - - j->board = *cnt; - probe = ixj_selfprobe(j); - j->dev = NULL; - ++*cnt; - } - } - return 0; -} - -static int __init ixj_probe_pci(int *cnt) -{ - struct pci_dev *pci = NULL; - int i, probe = 0; - IXJ *j = NULL; - - for (i = 0; i < IXJMAX - *cnt; i++) { - pci = pci_get_device(PCI_VENDOR_ID_QUICKNET, - PCI_DEVICE_ID_QUICKNET_XJ, pci); - if (!pci) - break; - - if (pci_enable_device(pci)) - break; - j = new_ixj(pci_resource_start(pci, 0)); - if (!j) - break; - - j->serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2); - j->XILINXbase = j->DSPbase + 0x10; - j->cardtype = QTI_PHONEJACK_PCI; - j->board = *cnt; - probe = ixj_selfprobe(j); - if (!probe) - printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase); - ++*cnt; - } - pci_dev_put(pci); - return probe; -} - -static int __init ixj_init(void) -{ - int cnt = 0; - int probe = 0; - - cnt = 0; - - /* These might be no-ops, see above. */ - if ((probe = ixj_probe_isapnp(&cnt)) < 0) { - return probe; - } - if ((probe = ixj_probe_isa(&cnt)) < 0) { - return probe; - } - if ((probe = ixj_probe_pci(&cnt)) < 0) { - return probe; - } - printk(KERN_INFO "ixj driver initialized.\n"); - create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL); - return probe; -} - -module_init(ixj_init); -module_exit(ixj_exit); - -static void DAA_Coeff_US(IXJ *j) -{ - int i; - - j->daa_country = DAA_US; - /*----------------------------------------------- */ - /* CAO */ - for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { - j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; - } - -/* Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x03; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0x4B; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x5D; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xCD; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x24; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xC5; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; -/* Bytes for IM-filter part 2 (05): 72,85,00,0E,2B,3A,D0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x71; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x1A; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; -/* Bytes for FRX-filter (08): 03,8F,48,F2,8F,48,70,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x05; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x72; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x3F; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x3B; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; -/* Bytes for FRR-filter (07): 04,8F,38,7F,9B,EA,B0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x05; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x3E; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; -/* Bytes for AX-filter (0A): 16,55,DD,CA */ - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x41; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; -/* Bytes for AR-filter (09): 52,D3,11,42 */ - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; -/* Bytes for TH-filter part 1 (00): 00,42,48,81,B3,80,00,98 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA5; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; -/* Bytes for TH-filter part 2 (01): 02,F2,33,A0,68,AB,8A,AD */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAB; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xCC; -/* Bytes for TH-filter part 3 (02): 00,88,DA,54,A4,BA,2D,BB */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xD2; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x24; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xA9; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x3B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xA6; -/* ; (10K, 0.68uF) */ - /* */ - /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; - /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; - - /* Levelmetering Ringing (0D):B2,45,0F,8E */ - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; - - /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1C; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0xB3; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0xAB; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xAB; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x54; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x2D; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0x62; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x2D; */ - /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x2D; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x62; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBB; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x2A; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7D; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD4; */ -/* */ - /* Levelmetering Ringing (0D):B2,45,0F,8E */ -/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x05; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; */ -/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; */ - - /* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; -/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; -/* */ - /* ;CR Registers */ - /* Config. Reg. 0 (filters) (cr0):FE ; CLK gen. by crystal */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; -/* Config. Reg. 1 (dialing) (cr1):05 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; -/* Config. Reg. 2 (caller ID) (cr2):04 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; -/* Config. Reg. 3 (testloops) (cr3):03 ; SEL Bit==0, HP-disabled */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; -/* Config. Reg. 4 (analog gain) (cr4):02 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; - /* Config. Reg. 5 (Version) (cr5):02 */ - /* Config. Reg. 6 (Reserved) (cr6):00 */ - /* Config. Reg. 7 (Reserved) (cr7):00 */ - /* */ - /* ;xr Registers */ - /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ - - j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ - /* Ext. Reg. 1 (Interrupt enable) (xr1):3C Cadence, RING, Caller ID, VDD_OK */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x3C; -/* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; -/* Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off == 1 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x3B; /*0x32; */ - /* Ext. Reg. 4 (Cadence) (xr4):00 */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; -/* Ext. Reg. 5 (Ring timer) (xr5):22 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; -/* Ext. Reg. 6 (Power State) (xr6):00 */ - j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; -/* Ext. Reg. 7 (Vdd) (xr7):40 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */ - /* */ - /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ - /* 12,33,5A,C3 ; 770 Hz */ - /* 13,3C,5B,32 ; 852 Hz */ - /* 1D,1B,5C,CC ; 941 Hz */ - - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; -/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ - /* EC,1D,52,22 ; 1336 Hz */ - /* AA,AC,51,D2 ; 1477 Hz */ - /* 9B,3B,51,25 ; 1633 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; -} - -static void DAA_Coeff_UK(IXJ *j) -{ - int i; - - j->daa_country = DAA_UK; - /*----------------------------------------------- */ - /* CAO */ - for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { - j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; - } - -/* Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xC2; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xA8; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xCB; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; -/* Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x40; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xA4; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; -/* Bytes for FRX-filter (08): 07,9B,ED,24,B2,A2,A0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9B; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xED; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x24; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0xB2; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xA0; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; -/* Bytes for FRR-filter (07): 0F,92,F2,B2,87,D2,30,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x92; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF2; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0xB2; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x87; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xD2; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x30; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; -/* Bytes for AX-filter (0A): 1B,A5,DD,CA */ - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xA5; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; -/* Bytes for AR-filter (09): E2,27,10,D6 */ - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x27; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; -/* Bytes for TH-filter part 1 (00): 80,2D,38,8B,D0,00,00,98 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x2D; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x38; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x8B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xD0; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; -/* Bytes for TH-filter part 2 (01): 02,5A,53,F0,0B,5F,84,D4 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x53; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xF0; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x0B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5F; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x84; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xD4; -/* Bytes for TH-filter part 3 (02): 00,88,6A,A4,8F,52,F5,32 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x6A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0xA4; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x8F; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xF5; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x32; -/* ; idle */ - /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; -/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; -/* Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V less possible? */ - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; -/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; -/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; -/* ;CR Registers */ - /* Config. Reg. 0 (filters) (cr0):FF */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; -/* Config. Reg. 1 (dialing) (cr1):05 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; -/* Config. Reg. 2 (caller ID) (cr2):04 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; -/* Config. Reg. 3 (testloops) (cr3):00 ; */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; -/* Config. Reg. 4 (analog gain) (cr4):02 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; - /* Config. Reg. 5 (Version) (cr5):02 */ - /* Config. Reg. 6 (Reserved) (cr6):00 */ - /* Config. Reg. 7 (Reserved) (cr7):00 */ - /* ;xr Registers */ - /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ - - j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ - /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ - /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; -/* Ext. Reg. 3 (DC Char) (xr3):36 ; */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36; -/* Ext. Reg. 4 (Cadence) (xr4):00 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; -/* Ext. Reg. 5 (Ring timer) (xr5):22 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; -/* Ext. Reg. 6 (Power State) (xr6):00 */ - j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; -/* Ext. Reg. 7 (Vdd) (xr7):46 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; /* 0x46 ??? Should it be 0x00? */ - /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ - /* 12,33,5A,C3 ; 770 Hz */ - /* 13,3C,5B,32 ; 852 Hz */ - /* 1D,1B,5C,CC ; 941 Hz */ - - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; -/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ - /* EC,1D,52,22 ; 1336 Hz */ - /* AA,AC,51,D2 ; 1477 Hz */ - /* 9B,3B,51,25 ; 1633 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; -} - - -static void DAA_Coeff_France(IXJ *j) -{ - int i; - - j->daa_country = DAA_FRANCE; - /*----------------------------------------------- */ - /* CAO */ - for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { - j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; - } - -/* Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x43; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2C; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xAF; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; -/* Bytes for IM-filter part 2 (05): 67,CE,00,0C,22,33,E0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x67; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xCE; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x2C; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; -/* Bytes for FRX-filter (08): 07,9A,28,F6,23,4A,B0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9A; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x28; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0xF6; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x23; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x4A; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xB0; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; -/* Bytes for FRR-filter (07): 03,8F,F9,2F,9E,FA,20,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x2F; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9E; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xFA; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; -/* Bytes for AX-filter (0A): 16,B5,DD,CA */ - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; -/* Bytes for AR-filter (09): 52,C7,10,D6 */ - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; -/* Bytes for TH-filter part 1 (00): 00,42,48,81,A6,80,00,98 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; -/* Bytes for TH-filter part 2 (01): 02,AC,2A,30,78,AC,8A,2C */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAC; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x30; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x78; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAC; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x2C; -/* Bytes for TH-filter part 3 (02): 00,88,DA,A5,22,BA,2C,45 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0xA5; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2C; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x45; -/* ; idle */ - /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; -/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; -/* Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V */ - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84; -/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; -/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; -/* ;CR Registers */ - /* Config. Reg. 0 (filters) (cr0):FF */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; -/* Config. Reg. 1 (dialing) (cr1):05 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; -/* Config. Reg. 2 (caller ID) (cr2):04 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; -/* Config. Reg. 3 (testloops) (cr3):00 ; */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; -/* Config. Reg. 4 (analog gain) (cr4):02 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; - /* Config. Reg. 5 (Version) (cr5):02 */ - /* Config. Reg. 6 (Reserved) (cr6):00 */ - /* Config. Reg. 7 (Reserved) (cr7):00 */ - /* ;xr Registers */ - /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ - - j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ - /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ - /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; -/* Ext. Reg. 3 (DC Char) (xr3):36 ; */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36; -/* Ext. Reg. 4 (Cadence) (xr4):00 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; -/* Ext. Reg. 5 (Ring timer) (xr5):22 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; -/* Ext. Reg. 6 (Power State) (xr6):00 */ - j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; -/* Ext. Reg. 7 (Vdd) (xr7):46 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; /* 0x46 ??? Should it be 0x00? */ - /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ - /* 12,33,5A,C3 ; 770 Hz */ - /* 13,3C,5B,32 ; 852 Hz */ - /* 1D,1B,5C,CC ; 941 Hz */ - - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; -/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ - /* EC,1D,52,22 ; 1336 Hz */ - /* AA,AC,51,D2 ; 1477 Hz */ - /* 9B,3B,51,25 ; 1633 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; -} - - -static void DAA_Coeff_Germany(IXJ *j) -{ - int i; - - j->daa_country = DAA_GERMANY; - /*----------------------------------------------- */ - /* CAO */ - for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { - j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; - } - -/* Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xCE; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xB8; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xD2; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xB0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; -/* Bytes for IM-filter part 2 (05): 45,8F,00,0C,D2,3A,D0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x45; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x8F; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0C; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xD2; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; -/* Bytes for FRX-filter (08): 07,AA,E2,34,24,89,20,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xAA; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x24; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x89; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x20; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; -/* Bytes for FRR-filter (07): 02,87,FA,37,9A,CA,B0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xFA; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x37; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9A; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; -/* Bytes for AX-filter (0A): 72,D5,DD,CA */ - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x72; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xD5; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; -/* Bytes for AR-filter (09): 72,42,13,4B */ - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x72; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x42; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x13; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x4B; -/* Bytes for TH-filter part 1 (00): 80,52,48,81,AD,80,00,98 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAD; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; -/* Bytes for TH-filter part 2 (01): 02,42,5A,20,E8,1A,81,27 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x42; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x20; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x1A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x27; -/* Bytes for TH-filter part 3 (02): 00,88,63,26,BD,4B,A3,C2 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x63; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x26; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBD; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x4B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xC2; -/* ; (10K, 0.68uF) */ - /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x9B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0xD4; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; -/* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0xD4; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; -/* Levelmetering Ringing (0D):B2,45,0F,8E */ - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; -/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; -/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; -/* ;CR Registers */ - /* Config. Reg. 0 (filters) (cr0):FF ; all Filters enabled, CLK from ext. source */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; -/* Config. Reg. 1 (dialing) (cr1):05 ; Manual Ring, Ring metering enabled */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; -/* Config. Reg. 2 (caller ID) (cr2):04 ; Analog Gain 0dB, FSC internal */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; -/* Config. Reg. 3 (testloops) (cr3):00 ; SEL Bit==0, HP-enabled */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; -/* Config. Reg. 4 (analog gain) (cr4):02 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; - /* Config. Reg. 5 (Version) (cr5):02 */ - /* Config. Reg. 6 (Reserved) (cr6):00 */ - /* Config. Reg. 7 (Reserved) (cr7):00 */ - /* ;xr Registers */ - /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ - - j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ - /* Ext. Reg. 1 (Interrupt enable) (xr1):1C ; Ring, CID, VDDOK Interrupts enabled */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ - /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; -/* Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off==1, U0=3.5V, R=200Ohm */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x32; -/* Ext. Reg. 4 (Cadence) (xr4):00 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; -/* Ext. Reg. 5 (Ring timer) (xr5):22 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; -/* Ext. Reg. 6 (Power State) (xr6):00 */ - j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; -/* Ext. Reg. 7 (Vdd) (xr7):40 ; VDD=4.25 V */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */ - /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ - /* 12,33,5A,C3 ; 770 Hz */ - /* 13,3C,5B,32 ; 852 Hz */ - /* 1D,1B,5C,CC ; 941 Hz */ - - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; -/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ - /* EC,1D,52,22 ; 1336 Hz */ - /* AA,AC,51,D2 ; 1477 Hz */ - /* 9B,3B,51,25 ; 1633 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; -} - - -static void DAA_Coeff_Australia(IXJ *j) -{ - int i; - - j->daa_country = DAA_AUSTRALIA; - /*----------------------------------------------- */ - /* CAO */ - for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { - j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; - } - -/* Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xAA; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x28; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x82; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xD0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; -/* Bytes for IM-filter part 2 (05): 70,96,00,09,32,6B,C0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x70; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x96; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x6B; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xC0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; -/* Bytes for FRX-filter (08): 07,96,E2,34,32,9B,30,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x96; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x9B; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; -/* Bytes for FRR-filter (07): 0F,9A,E9,2F,22,CC,A0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x9A; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xE9; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x2F; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCC; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xA0; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; -/* Bytes for AX-filter (0A): CB,45,DD,CA */ - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0xCB; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x45; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; -/* Bytes for AR-filter (09): 1B,67,10,D6 */ - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x67; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; -/* Bytes for TH-filter part 1 (00): 80,52,48,81,AF,80,00,98 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAF; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; -/* Bytes for TH-filter part 2 (01): 02,DB,52,B0,38,01,82,AC */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xDB; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x38; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x01; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x82; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAC; -/* Bytes for TH-filter part 3 (02): 00,88,4A,3E,2C,3B,24,46 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x4A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x3E; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x2C; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x3B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x24; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x46; -/* ; idle */ - /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; -/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; -/* Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V */ - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84; -/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; -/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; -/* ;CR Registers */ - /* Config. Reg. 0 (filters) (cr0):FF */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; -/* Config. Reg. 1 (dialing) (cr1):05 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; -/* Config. Reg. 2 (caller ID) (cr2):04 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; -/* Config. Reg. 3 (testloops) (cr3):00 ; */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; -/* Config. Reg. 4 (analog gain) (cr4):02 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; - /* Config. Reg. 5 (Version) (cr5):02 */ - /* Config. Reg. 6 (Reserved) (cr6):00 */ - /* Config. Reg. 7 (Reserved) (cr7):00 */ - /* ;xr Registers */ - /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ - - j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ - /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ - /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; -/* Ext. Reg. 3 (DC Char) (xr3):2B ; */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x2B; -/* Ext. Reg. 4 (Cadence) (xr4):00 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; -/* Ext. Reg. 5 (Ring timer) (xr5):22 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; -/* Ext. Reg. 6 (Power State) (xr6):00 */ - j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; -/* Ext. Reg. 7 (Vdd) (xr7):40 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */ - - /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ - /* 12,33,5A,C3 ; 770 Hz */ - /* 13,3C,5B,32 ; 852 Hz */ - /* 1D,1B,5C,CC ; 941 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; - - /* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ - /* EC,1D,52,22 ; 1336 Hz */ - /* AA,AC,51,D2 ; 1477 Hz */ - /* 9B,3B,51,25 ; 1633 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; -} - -static void DAA_Coeff_Japan(IXJ *j) -{ - int i; - - j->daa_country = DAA_JAPAN; - /*----------------------------------------------- */ - /* CAO */ - for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) { - j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0; - } - -/* Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x06; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xBD; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2D; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xF9; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00; -/* Bytes for IM-filter part 2 (05): 6F,F7,00,0E,34,33,E0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x6F; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xF7; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x34; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0; - j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08; -/* Bytes for FRX-filter (08): 02,8F,68,77,9C,58,F0,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x68; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x77; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x9C; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x58; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xF0; - j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08; -/* Bytes for FRR-filter (07): 03,8F,38,73,87,EA,20,08 */ - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0x38; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x73; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x87; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20; - j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08; -/* Bytes for AX-filter (0A): 51,C5,DD,CA */ - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x51; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xC5; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD; - j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA; -/* Bytes for AR-filter (09): 25,A7,10,D6 */ - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xA7; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10; - j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6; -/* Bytes for TH-filter part 1 (00): 00,42,48,81,AE,80,00,98 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xAE; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98; -/* Bytes for TH-filter part 2 (01): 02,AB,2A,20,99,5B,89,28 */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAB; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0x20; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5B; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x89; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x28; -/* Bytes for TH-filter part 3 (02): 00,88,DA,25,34,C5,4C,BA */ - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x25; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0x34; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xC5; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x4C; - j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBA; -/* ; idle */ - /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23; -/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */ - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; - j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5; -/* Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V ????????? */ - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; - j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; -/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[4] = 0x09; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[3] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99; -/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */ - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[4] = 0x07; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[3] = 0xDA; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00; - j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00; -/* ;CR Registers */ - /* Config. Reg. 0 (filters) (cr0):FF */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF; -/* Config. Reg. 1 (dialing) (cr1):05 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05; -/* Config. Reg. 2 (caller ID) (cr2):04 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04; -/* Config. Reg. 3 (testloops) (cr3):00 ; */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00; -/* Config. Reg. 4 (analog gain) (cr4):02 */ - j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; - /* Config. Reg. 5 (Version) (cr5):02 */ - /* Config. Reg. 6 (Reserved) (cr6):00 */ - /* Config. Reg. 7 (Reserved) (cr7):00 */ - /* ;xr Registers */ - /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */ - - j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */ - /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */ - /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */ - - j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D; -/* Ext. Reg. 3 (DC Char) (xr3):22 ; */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x22; -/* Ext. Reg. 4 (Cadence) (xr4):00 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00; -/* Ext. Reg. 5 (Ring timer) (xr5):22 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22; -/* Ext. Reg. 6 (Power State) (xr6):00 */ - j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00; -/* Ext. Reg. 7 (Vdd) (xr7):40 */ - j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */ - /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */ - /* 12,33,5A,C3 ; 770 Hz */ - /* 13,3C,5B,32 ; 852 Hz */ - /* 1D,1B,5C,CC ; 941 Hz */ - - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A; - j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C; -/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */ - /* EC,1D,52,22 ; 1336 Hz */ - /* AA,AC,51,D2 ; 1477 Hz */ - /* 9B,3B,51,25 ; 1633 Hz */ - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52; - j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3; -} - -static s16 tone_table[][19] = -{ - { /* f20_50[] 11 */ - 32538, /* A1 = 1.985962 */ - -32325, /* A2 = -0.986511 */ - -343, /* B2 = -0.010493 */ - 0, /* B1 = 0 */ - 343, /* B0 = 0.010493 */ - 32619, /* A1 = 1.990906 */ - -32520, /* A2 = -0.992462 */ - 19179, /* B2 = 0.585327 */ - -19178, /* B1 = -1.170593 */ - 19179, /* B0 = 0.585327 */ - 32723, /* A1 = 1.997314 */ - -32686, /* A2 = -0.997528 */ - 9973, /* B2 = 0.304352 */ - -9955, /* B1 = -0.607605 */ - 9973, /* B0 = 0.304352 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f133_200[] 12 */ - 32072, /* A1 = 1.95752 */ - -31896, /* A2 = -0.973419 */ - -435, /* B2 = -0.013294 */ - 0, /* B1 = 0 */ - 435, /* B0 = 0.013294 */ - 32188, /* A1 = 1.9646 */ - -32400, /* A2 = -0.98877 */ - 15139, /* B2 = 0.462036 */ - -14882, /* B1 = -0.908356 */ - 15139, /* B0 = 0.462036 */ - 32473, /* A1 = 1.981995 */ - -32524, /* A2 = -0.992584 */ - 23200, /* B2 = 0.708008 */ - -23113, /* B1 = -1.410706 */ - 23200, /* B0 = 0.708008 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f300 13 */ - 31769, /* A1 = -1.939026 */ - -32584, /* A2 = 0.994385 */ - -475, /* B2 = -0.014522 */ - 0, /* B1 = 0.000000 */ - 475, /* B0 = 0.014522 */ - 31789, /* A1 = -1.940247 */ - -32679, /* A2 = 0.997284 */ - 17280, /* B2 = 0.527344 */ - -16865, /* B1 = -1.029358 */ - 17280, /* B0 = 0.527344 */ - 31841, /* A1 = -1.943481 */ - -32681, /* A2 = 0.997345 */ - 543, /* B2 = 0.016579 */ - -525, /* B1 = -0.032097 */ - 543, /* B0 = 0.016579 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f300_420[] 14 */ - 30750, /* A1 = 1.876892 */ - -31212, /* A2 = -0.952515 */ - -804, /* B2 = -0.024541 */ - 0, /* B1 = 0 */ - 804, /* B0 = 0.024541 */ - 30686, /* A1 = 1.872925 */ - -32145, /* A2 = -0.980988 */ - 14747, /* B2 = 0.450043 */ - -13703, /* B1 = -0.836395 */ - 14747, /* B0 = 0.450043 */ - 31651, /* A1 = 1.931824 */ - -32321, /* A2 = -0.986389 */ - 24425, /* B2 = 0.745422 */ - -23914, /* B1 = -1.459595 */ - 24427, /* B0 = 0.745483 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f330 15 */ - 31613, /* A1 = -1.929565 */ - -32646, /* A2 = 0.996277 */ - -185, /* B2 = -0.005657 */ - 0, /* B1 = 0.000000 */ - 185, /* B0 = 0.005657 */ - 31620, /* A1 = -1.929932 */ - -32713, /* A2 = 0.998352 */ - 19253, /* B2 = 0.587585 */ - -18566, /* B1 = -1.133179 */ - 19253, /* B0 = 0.587585 */ - 31674, /* A1 = -1.933228 */ - -32715, /* A2 = 0.998413 */ - 2575, /* B2 = 0.078590 */ - -2495, /* B1 = -0.152283 */ - 2575, /* B0 = 0.078590 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f300_425[] 16 */ - 30741, /* A1 = 1.876282 */ - -31475, /* A2 = -0.960541 */ - -703, /* B2 = -0.021484 */ - 0, /* B1 = 0 */ - 703, /* B0 = 0.021484 */ - 30688, /* A1 = 1.873047 */ - -32248, /* A2 = -0.984161 */ - 14542, /* B2 = 0.443787 */ - -13523, /* B1 = -0.825439 */ - 14542, /* B0 = 0.443817 */ - 31494, /* A1 = 1.922302 */ - -32366, /* A2 = -0.987762 */ - 21577, /* B2 = 0.658508 */ - -21013, /* B1 = -1.282532 */ - 21577, /* B0 = 0.658508 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f330_440[] 17 */ - 30627, /* A1 = 1.869324 */ - -31338, /* A2 = -0.95636 */ - -843, /* B2 = -0.025749 */ - 0, /* B1 = 0 */ - 843, /* B0 = 0.025749 */ - 30550, /* A1 = 1.864685 */ - -32221, /* A2 = -0.983337 */ - 13594, /* B2 = 0.414886 */ - -12589, /* B1 = -0.768402 */ - 13594, /* B0 = 0.414886 */ - 31488, /* A1 = 1.921936 */ - -32358, /* A2 = -0.987518 */ - 24684, /* B2 = 0.753296 */ - -24029, /* B1 = -1.466614 */ - 24684, /* B0 = 0.753296 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f340 18 */ - 31546, /* A1 = -1.925476 */ - -32646, /* A2 = 0.996277 */ - -445, /* B2 = -0.013588 */ - 0, /* B1 = 0.000000 */ - 445, /* B0 = 0.013588 */ - 31551, /* A1 = -1.925781 */ - -32713, /* A2 = 0.998352 */ - 23884, /* B2 = 0.728882 */ - -22979, /* B1 = -1.402527 */ - 23884, /* B0 = 0.728882 */ - 31606, /* A1 = -1.929138 */ - -32715, /* A2 = 0.998413 */ - 863, /* B2 = 0.026367 */ - -835, /* B1 = -0.050985 */ - 863, /* B0 = 0.026367 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f350_400[] 19 */ - 31006, /* A1 = 1.892517 */ - -32029, /* A2 = -0.977448 */ - -461, /* B2 = -0.014096 */ - 0, /* B1 = 0 */ - 461, /* B0 = 0.014096 */ - 30999, /* A1 = 1.892029 */ - -32487, /* A2 = -0.991455 */ - 11325, /* B2 = 0.345612 */ - -10682, /* B1 = -0.651978 */ - 11325, /* B0 = 0.345612 */ - 31441, /* A1 = 1.919067 */ - -32526, /* A2 = -0.992615 */ - 24324, /* B2 = 0.74231 */ - -23535, /* B1 = -1.436523 */ - 24324, /* B0 = 0.74231 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f350_440[] */ - 30634, /* A1 = 1.869751 */ - -31533, /* A2 = -0.962341 */ - -680, /* B2 = -0.020782 */ - 0, /* B1 = 0 */ - 680, /* B0 = 0.020782 */ - 30571, /* A1 = 1.865906 */ - -32277, /* A2 = -0.985016 */ - 12894, /* B2 = 0.393524 */ - -11945, /* B1 = -0.729065 */ - 12894, /* B0 = 0.393524 */ - 31367, /* A1 = 1.91449 */ - -32379, /* A2 = -0.988129 */ - 23820, /* B2 = 0.726929 */ - -23104, /* B1 = -1.410217 */ - 23820, /* B0 = 0.726929 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f350_450[] */ - 30552, /* A1 = 1.864807 */ - -31434, /* A2 = -0.95929 */ - -690, /* B2 = -0.021066 */ - 0, /* B1 = 0 */ - 690, /* B0 = 0.021066 */ - 30472, /* A1 = 1.859924 */ - -32248, /* A2 = -0.984161 */ - 13385, /* B2 = 0.408478 */ - -12357, /* B1 = -0.754242 */ - 13385, /* B0 = 0.408478 */ - 31358, /* A1 = 1.914001 */ - -32366, /* A2 = -0.987732 */ - 26488, /* B2 = 0.80835 */ - -25692, /* B1 = -1.568176 */ - 26490, /* B0 = 0.808411 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f360 */ - 31397, /* A1 = -1.916321 */ - -32623, /* A2 = 0.995605 */ - -117, /* B2 = -0.003598 */ - 0, /* B1 = 0.000000 */ - 117, /* B0 = 0.003598 */ - 31403, /* A1 = -1.916687 */ - -32700, /* A2 = 0.997925 */ - 3388, /* B2 = 0.103401 */ - -3240, /* B1 = -0.197784 */ - 3388, /* B0 = 0.103401 */ - 31463, /* A1 = -1.920410 */ - -32702, /* A2 = 0.997986 */ - 13346, /* B2 = 0.407288 */ - -12863, /* B1 = -0.785126 */ - 13346, /* B0 = 0.407288 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f380_420[] */ - 30831, /* A1 = 1.881775 */ - -32064, /* A2 = -0.978546 */ - -367, /* B2 = -0.01122 */ - 0, /* B1 = 0 */ - 367, /* B0 = 0.01122 */ - 30813, /* A1 = 1.880737 */ - -32456, /* A2 = -0.990509 */ - 11068, /* B2 = 0.337769 */ - -10338, /* B1 = -0.631042 */ - 11068, /* B0 = 0.337769 */ - 31214, /* A1 = 1.905212 */ - -32491, /* A2 = -0.991577 */ - 16374, /* B2 = 0.499695 */ - -15781, /* B1 = -0.963196 */ - 16374, /* B0 = 0.499695 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f392 */ - 31152, /* A1 = -1.901428 */ - -32613, /* A2 = 0.995300 */ - -314, /* B2 = -0.009605 */ - 0, /* B1 = 0.000000 */ - 314, /* B0 = 0.009605 */ - 31156, /* A1 = -1.901672 */ - -32694, /* A2 = 0.997742 */ - 28847, /* B2 = 0.880371 */ - -2734, /* B1 = -0.166901 */ - 28847, /* B0 = 0.880371 */ - 31225, /* A1 = -1.905823 */ - -32696, /* A2 = 0.997803 */ - 462, /* B2 = 0.014108 */ - -442, /* B1 = -0.027019 */ - 462, /* B0 = 0.014108 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f400_425[] */ - 30836, /* A1 = 1.882141 */ - -32296, /* A2 = -0.985596 */ - -324, /* B2 = -0.009903 */ - 0, /* B1 = 0 */ - 324, /* B0 = 0.009903 */ - 30825, /* A1 = 1.881409 */ - -32570, /* A2 = -0.993958 */ - 16847, /* B2 = 0.51416 */ - -15792, /* B1 = -0.963898 */ - 16847, /* B0 = 0.51416 */ - 31106, /* A1 = 1.89856 */ - -32584, /* A2 = -0.994415 */ - 9579, /* B2 = 0.292328 */ - -9164, /* B1 = -0.559357 */ - 9579, /* B0 = 0.292328 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f400_440[] */ - 30702, /* A1 = 1.873962 */ - -32134, /* A2 = -0.980682 */ - -517, /* B2 = -0.015793 */ - 0, /* B1 = 0 */ - 517, /* B0 = 0.015793 */ - 30676, /* A1 = 1.872375 */ - -32520, /* A2 = -0.992462 */ - 8144, /* B2 = 0.24855 */ - -7596, /* B1 = -0.463684 */ - 8144, /* B0 = 0.24855 */ - 31084, /* A1 = 1.897217 */ - -32547, /* A2 = -0.993256 */ - 22713, /* B2 = 0.693176 */ - -21734, /* B1 = -1.326599 */ - 22713, /* B0 = 0.693176 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f400_450[] */ - 30613, /* A1 = 1.86853 */ - -32031, /* A2 = -0.977509 */ - -618, /* B2 = -0.018866 */ - 0, /* B1 = 0 */ - 618, /* B0 = 0.018866 */ - 30577, /* A1 = 1.866272 */ - -32491, /* A2 = -0.991577 */ - 9612, /* B2 = 0.293335 */ - -8935, /* B1 = -0.54541 */ - 9612, /* B0 = 0.293335 */ - 31071, /* A1 = 1.896484 */ - -32524, /* A2 = -0.992584 */ - 21596, /* B2 = 0.659058 */ - -20667, /* B1 = -1.261414 */ - 21596, /* B0 = 0.659058 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f420 */ - 30914, /* A1 = -1.886841 */ - -32584, /* A2 = 0.994385 */ - -426, /* B2 = -0.013020 */ - 0, /* B1 = 0.000000 */ - 426, /* B0 = 0.013020 */ - 30914, /* A1 = -1.886841 */ - -32679, /* A2 = 0.997314 */ - 17520, /* B2 = 0.534668 */ - -16471, /* B1 = -1.005310 */ - 17520, /* B0 = 0.534668 */ - 31004, /* A1 = -1.892334 */ - -32683, /* A2 = 0.997406 */ - 819, /* B2 = 0.025023 */ - -780, /* B1 = -0.047619 */ - 819, /* B0 = 0.025023 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, -#if 0 - { /* f425 */ - 30881, /* A1 = -1.884827 */ - -32603, /* A2 = 0.994965 */ - -496, /* B2 = -0.015144 */ - 0, /* B1 = 0.000000 */ - 496, /* B0 = 0.015144 */ - 30880, /* A1 = -1.884766 */ - -32692, /* A2 = 0.997711 */ - 24767, /* B2 = 0.755859 */ - -23290, /* B1 = -1.421509 */ - 24767, /* B0 = 0.755859 */ - 30967, /* A1 = -1.890076 */ - -32694, /* A2 = 0.997772 */ - 728, /* B2 = 0.022232 */ - -691, /* B1 = -0.042194 */ - 728, /* B0 = 0.022232 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, -#else - { - 30850, - -32534, - -504, - 0, - 504, - 30831, - -32669, - 24303, - -22080, - 24303, - 30994, - -32673, - 1905, - -1811, - 1905, - 5, - 129, - 17, - 0xff5 - }, -#endif - { /* f425_450[] */ - 30646, /* A1 = 1.870544 */ - -32327, /* A2 = -0.986572 */ - -287, /* B2 = -0.008769 */ - 0, /* B1 = 0 */ - 287, /* B0 = 0.008769 */ - 30627, /* A1 = 1.869324 */ - -32607, /* A2 = -0.995087 */ - 13269, /* B2 = 0.404968 */ - -12376, /* B1 = -0.755432 */ - 13269, /* B0 = 0.404968 */ - 30924, /* A1 = 1.887512 */ - -32619, /* A2 = -0.995453 */ - 19950, /* B2 = 0.608826 */ - -18940, /* B1 = -1.156006 */ - 19950, /* B0 = 0.608826 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f425_475[] */ - 30396, /* A1 = 1.855225 */ - -32014, /* A2 = -0.97699 */ - -395, /* B2 = -0.012055 */ - 0, /* B1 = 0 */ - 395, /* B0 = 0.012055 */ - 30343, /* A1 = 1.85199 */ - -32482, /* A2 = -0.991302 */ - 17823, /* B2 = 0.543945 */ - -16431, /* B1 = -1.002869 */ - 17823, /* B0 = 0.543945 */ - 30872, /* A1 = 1.884338 */ - -32516, /* A2 = -0.99231 */ - 18124, /* B2 = 0.553101 */ - -17246, /* B1 = -1.052673 */ - 18124, /* B0 = 0.553101 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f435 */ - 30796, /* A1 = -1.879639 */ - -32603, /* A2 = 0.994965 */ - -254, /* B2 = -0.007762 */ - 0, /* B1 = 0.000000 */ - 254, /* B0 = 0.007762 */ - 30793, /* A1 = -1.879456 */ - -32692, /* A2 = 0.997711 */ - 18934, /* B2 = 0.577820 */ - -17751, /* B1 = -1.083496 */ - 18934, /* B0 = 0.577820 */ - 30882, /* A1 = -1.884888 */ - -32694, /* A2 = 0.997772 */ - 1858, /* B2 = 0.056713 */ - -1758, /* B1 = -0.107357 */ - 1858, /* B0 = 0.056713 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f440_450[] */ - 30641, /* A1 = 1.870239 */ - -32458, /* A2 = -0.99057 */ - -155, /* B2 = -0.004735 */ - 0, /* B1 = 0 */ - 155, /* B0 = 0.004735 */ - 30631, /* A1 = 1.869568 */ - -32630, /* A2 = -0.995789 */ - 11453, /* B2 = 0.349548 */ - -10666, /* B1 = -0.651001 */ - 11453, /* B0 = 0.349548 */ - 30810, /* A1 = 1.880554 */ - -32634, /* A2 = -0.995941 */ - 12237, /* B2 = 0.373474 */ - -11588, /* B1 = -0.707336 */ - 12237, /* B0 = 0.373474 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f440_480[] */ - 30367, /* A1 = 1.853455 */ - -32147, /* A2 = -0.981079 */ - -495, /* B2 = -0.015113 */ - 0, /* B1 = 0 */ - 495, /* B0 = 0.015113 */ - 30322, /* A1 = 1.850769 */ - -32543, /* A2 = -0.993134 */ - 10031, /* B2 = 0.306152 */ - -9252, /* B1 = -0.564728 */ - 10031, /* B0 = 0.306152 */ - 30770, /* A1 = 1.878052 */ - -32563, /* A2 = -0.993774 */ - 22674, /* B2 = 0.691956 */ - -21465, /* B1 = -1.31012 */ - 22674, /* B0 = 0.691956 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f445 */ - 30709, /* A1 = -1.874329 */ - -32603, /* A2 = 0.994965 */ - -83, /* B2 = -0.002545 */ - 0, /* B1 = 0.000000 */ - 83, /* B0 = 0.002545 */ - 30704, /* A1 = -1.874084 */ - -32692, /* A2 = 0.997711 */ - 10641, /* B2 = 0.324738 */ - -9947, /* B1 = -0.607147 */ - 10641, /* B0 = 0.324738 */ - 30796, /* A1 = -1.879639 */ - -32694, /* A2 = 0.997772 */ - 10079, /* B2 = 0.307587 */ - 9513, /* B1 = 0.580688 */ - 10079, /* B0 = 0.307587 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f450 */ - 30664, /* A1 = -1.871643 */ - -32603, /* A2 = 0.994965 */ - -164, /* B2 = -0.005029 */ - 0, /* B1 = 0.000000 */ - 164, /* B0 = 0.005029 */ - 30661, /* A1 = -1.871399 */ - -32692, /* A2 = 0.997711 */ - 15294, /* B2 = 0.466736 */ - -14275, /* B1 = -0.871307 */ - 15294, /* B0 = 0.466736 */ - 30751, /* A1 = -1.876953 */ - -32694, /* A2 = 0.997772 */ - 3548, /* B2 = 0.108284 */ - -3344, /* B1 = -0.204155 */ - 3548, /* B0 = 0.108284 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f452 */ - 30653, /* A1 = -1.870911 */ - -32615, /* A2 = 0.995361 */ - -209, /* B2 = -0.006382 */ - 0, /* B1 = 0.000000 */ - 209, /* B0 = 0.006382 */ - 30647, /* A1 = -1.870605 */ - -32702, /* A2 = 0.997986 */ - 18971, /* B2 = 0.578979 */ - -17716, /* B1 = -1.081299 */ - 18971, /* B0 = 0.578979 */ - 30738, /* A1 = -1.876099 */ - -32702, /* A2 = 0.998016 */ - 2967, /* B2 = 0.090561 */ - -2793, /* B1 = -0.170502 */ - 2967, /* B0 = 0.090561 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f475 */ - 30437, /* A1 = -1.857727 */ - -32603, /* A2 = 0.994965 */ - -264, /* B2 = -0.008062 */ - 0, /* B1 = 0.000000 */ - 264, /* B0 = 0.008062 */ - 30430, /* A1 = -1.857300 */ - -32692, /* A2 = 0.997711 */ - 21681, /* B2 = 0.661682 */ - -20082, /* B1 = -1.225708 */ - 21681, /* B0 = 0.661682 */ - 30526, /* A1 = -1.863220 */ - -32694, /* A2 = 0.997742 */ - 1559, /* B2 = 0.047600 */ - -1459, /* B1 = -0.089096 */ - 1559, /* B0 = 0.047600 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f480_620[] */ - 28975, /* A1 = 1.768494 */ - -30955, /* A2 = -0.944672 */ - -1026, /* B2 = -0.03133 */ - 0, /* B1 = 0 */ - 1026, /* B0 = 0.03133 */ - 28613, /* A1 = 1.746399 */ - -32089, /* A2 = -0.979309 */ - 14214, /* B2 = 0.433807 */ - -12202, /* B1 = -0.744812 */ - 14214, /* B0 = 0.433807 */ - 30243, /* A1 = 1.845947 */ - -32238, /* A2 = -0.983856 */ - 24825, /* B2 = 0.757629 */ - -23402, /* B1 = -1.428345 */ - 24825, /* B0 = 0.757629 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f494 */ - 30257, /* A1 = -1.846741 */ - -32605, /* A2 = 0.995056 */ - -249, /* B2 = -0.007625 */ - 0, /* B1 = 0.000000 */ - 249, /* B0 = 0.007625 */ - 30247, /* A1 = -1.846191 */ - -32694, /* A2 = 0.997772 */ - 18088, /* B2 = 0.552002 */ - -16652, /* B1 = -1.016418 */ - 18088, /* B0 = 0.552002 */ - 30348, /* A1 = -1.852295 */ - -32696, /* A2 = 0.997803 */ - 2099, /* B2 = 0.064064 */ - -1953, /* B1 = -0.119202 */ - 2099, /* B0 = 0.064064 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f500 */ - 30202, /* A1 = -1.843431 */ - -32624, /* A2 = 0.995622 */ - -413, /* B2 = -0.012622 */ - 0, /* B1 = 0.000000 */ - 413, /* B0 = 0.012622 */ - 30191, /* A1 = -1.842721 */ - -32714, /* A2 = 0.998364 */ - 25954, /* B2 = 0.792057 */ - -23890, /* B1 = -1.458131 */ - 25954, /* B0 = 0.792057 */ - 30296, /* A1 = -1.849172 */ - -32715, /* A2 = 0.998397 */ - 2007, /* B2 = 0.061264 */ - -1860, /* B1 = -0.113568 */ - 2007, /* B0 = 0.061264 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f520 */ - 30001, /* A1 = -1.831116 */ - -32613, /* A2 = 0.995270 */ - -155, /* B2 = -0.004750 */ - 0, /* B1 = 0.000000 */ - 155, /* B0 = 0.004750 */ - 29985, /* A1 = -1.830200 */ - -32710, /* A2 = 0.998260 */ - 6584, /* B2 = 0.200928 */ - -6018, /* B1 = -0.367355 */ - 6584, /* B0 = 0.200928 */ - 30105, /* A1 = -1.837524 */ - -32712, /* A2 = 0.998291 */ - 23812, /* B2 = 0.726685 */ - -21936, /* B1 = -1.338928 */ - 23812, /* B0 = 0.726685 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f523 */ - 29964, /* A1 = -1.828918 */ - -32601, /* A2 = 0.994904 */ - -101, /* B2 = -0.003110 */ - 0, /* B1 = 0.000000 */ - 101, /* B0 = 0.003110 */ - 29949, /* A1 = -1.827942 */ - -32700, /* A2 = 0.997925 */ - 11041, /* B2 = 0.336975 */ - -10075, /* B1 = -0.614960 */ - 11041, /* B0 = 0.336975 */ - 30070, /* A1 = -1.835388 */ - -32702, /* A2 = 0.997986 */ - 16762, /* B2 = 0.511536 */ - -15437, /* B1 = -0.942230 */ - 16762, /* B0 = 0.511536 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f525 */ - 29936, /* A1 = -1.827209 */ - -32584, /* A2 = 0.994415 */ - -91, /* B2 = -0.002806 */ - 0, /* B1 = 0.000000 */ - 91, /* B0 = 0.002806 */ - 29921, /* A1 = -1.826233 */ - -32688, /* A2 = 0.997559 */ - 11449, /* B2 = 0.349396 */ - -10426, /* B1 = -0.636383 */ - 11449, /* B0 = 0.349396 */ - 30045, /* A1 = -1.833862 */ - -32688, /* A2 = 0.997589 */ - 13055, /* B2 = 0.398407 */ - -12028, /* B1 = -0.734161 */ - 13055, /* B0 = 0.398407 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f540_660[] */ - 28499, /* A1 = 1.739441 */ - -31129, /* A2 = -0.949982 */ - -849, /* B2 = -0.025922 */ - 0, /* B1 = 0 */ - 849, /* B0 = 0.025922 */ - 28128, /* A1 = 1.716797 */ - -32130, /* A2 = -0.98056 */ - 14556, /* B2 = 0.444214 */ - -12251, /* B1 = -0.747772 */ - 14556, /* B0 = 0.444244 */ - 29667, /* A1 = 1.81073 */ - -32244, /* A2 = -0.984039 */ - 23038, /* B2 = 0.703064 */ - -21358, /* B1 = -1.303589 */ - 23040, /* B0 = 0.703125 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f587 */ - 29271, /* A1 = -1.786560 */ - -32599, /* A2 = 0.994873 */ - -490, /* B2 = -0.014957 */ - 0, /* B1 = 0.000000 */ - 490, /* B0 = 0.014957 */ - 29246, /* A1 = -1.785095 */ - -32700, /* A2 = 0.997925 */ - 28961, /* B2 = 0.883850 */ - -25796, /* B1 = -1.574463 */ - 28961, /* B0 = 0.883850 */ - 29383, /* A1 = -1.793396 */ - -32700, /* A2 = 0.997955 */ - 1299, /* B2 = 0.039650 */ - -1169, /* B1 = -0.071396 */ - 1299, /* B0 = 0.039650 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f590 */ - 29230, /* A1 = -1.784058 */ - -32584, /* A2 = 0.994415 */ - -418, /* B2 = -0.012757 */ - 0, /* B1 = 0.000000 */ - 418, /* B0 = 0.012757 */ - 29206, /* A1 = -1.782593 */ - -32688, /* A2 = 0.997559 */ - 36556, /* B2 = 1.115601 */ - -32478, /* B1 = -1.982300 */ - 36556, /* B0 = 1.115601 */ - 29345, /* A1 = -1.791077 */ - -32688, /* A2 = 0.997589 */ - 897, /* B2 = 0.027397 */ - -808, /* B1 = -0.049334 */ - 897, /* B0 = 0.027397 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f600 */ - 29116, /* A1 = -1.777100 */ - -32603, /* A2 = 0.994965 */ - -165, /* B2 = -0.005039 */ - 0, /* B1 = 0.000000 */ - 165, /* B0 = 0.005039 */ - 29089, /* A1 = -1.775452 */ - -32708, /* A2 = 0.998199 */ - 6963, /* B2 = 0.212494 */ - -6172, /* B1 = -0.376770 */ - 6963, /* B0 = 0.212494 */ - 29237, /* A1 = -1.784485 */ - -32710, /* A2 = 0.998230 */ - 24197, /* B2 = 0.738464 */ - -21657, /* B1 = -1.321899 */ - 24197, /* B0 = 0.738464 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f660 */ - 28376, /* A1 = -1.731934 */ - -32567, /* A2 = 0.993896 */ - -363, /* B2 = -0.011102 */ - 0, /* B1 = 0.000000 */ - 363, /* B0 = 0.011102 */ - 28337, /* A1 = -1.729614 */ - -32683, /* A2 = 0.997434 */ - 21766, /* B2 = 0.664246 */ - -18761, /* B1 = -1.145081 */ - 21766, /* B0 = 0.664246 */ - 28513, /* A1 = -1.740356 */ - -32686, /* A2 = 0.997498 */ - 2509, /* B2 = 0.076584 */ - -2196, /* B1 = -0.134041 */ - 2509, /* B0 = 0.076584 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f700 */ - 27844, /* A1 = -1.699463 */ - -32563, /* A2 = 0.993744 */ - -366, /* B2 = -0.011187 */ - 0, /* B1 = 0.000000 */ - 366, /* B0 = 0.011187 */ - 27797, /* A1 = -1.696655 */ - -32686, /* A2 = 0.997498 */ - 22748, /* B2 = 0.694214 */ - -19235, /* B1 = -1.174072 */ - 22748, /* B0 = 0.694214 */ - 27995, /* A1 = -1.708740 */ - -32688, /* A2 = 0.997559 */ - 2964, /* B2 = 0.090477 */ - -2546, /* B1 = -0.155449 */ - 2964, /* B0 = 0.090477 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f740 */ - 27297, /* A1 = -1.666077 */ - -32551, /* A2 = 0.993408 */ - -345, /* B2 = -0.010540 */ - 0, /* B1 = 0.000000 */ - 345, /* B0 = 0.010540 */ - 27240, /* A1 = -1.662598 */ - -32683, /* A2 = 0.997406 */ - 22560, /* B2 = 0.688477 */ - -18688, /* B1 = -1.140625 */ - 22560, /* B0 = 0.688477 */ - 27461, /* A1 = -1.676147 */ - -32684, /* A2 = 0.997467 */ - 3541, /* B2 = 0.108086 */ - -2985, /* B1 = -0.182220 */ - 3541, /* B0 = 0.108086 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f750 */ - 27155, /* A1 = -1.657410 */ - -32551, /* A2 = 0.993408 */ - -462, /* B2 = -0.014117 */ - 0, /* B1 = 0.000000 */ - 462, /* B0 = 0.014117 */ - 27097, /* A1 = -1.653870 */ - -32683, /* A2 = 0.997406 */ - 32495, /* B2 = 0.991699 */ - -26776, /* B1 = -1.634338 */ - 32495, /* B0 = 0.991699 */ - 27321, /* A1 = -1.667542 */ - -32684, /* A2 = 0.997467 */ - 1835, /* B2 = 0.056007 */ - -1539, /* B1 = -0.093948 */ - 1835, /* B0 = 0.056007 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f750_1450[] */ - 19298, /* A1 = 1.177917 */ - -24471, /* A2 = -0.746796 */ - -4152, /* B2 = -0.126709 */ - 0, /* B1 = 0 */ - 4152, /* B0 = 0.126709 */ - 12902, /* A1 = 0.787476 */ - -29091, /* A2 = -0.887817 */ - 12491, /* B2 = 0.38121 */ - -1794, /* B1 = -0.109528 */ - 12494, /* B0 = 0.381317 */ - 26291, /* A1 = 1.604736 */ - -30470, /* A2 = -0.929901 */ - 28859, /* B2 = 0.880737 */ - -26084, /* B1 = -1.592102 */ - 28861, /* B0 = 0.880798 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f770 */ - 26867, /* A1 = -1.639832 */ - -32551, /* A2 = 0.993408 */ - -123, /* B2 = -0.003755 */ - 0, /* B1 = 0.000000 */ - 123, /* B0 = 0.003755 */ - 26805, /* A1 = -1.636108 */ - -32683, /* A2 = 0.997406 */ - 17297, /* B2 = 0.527863 */ - -14096, /* B1 = -0.860382 */ - 17297, /* B0 = 0.527863 */ - 27034, /* A1 = -1.650085 */ - -32684, /* A2 = 0.997467 */ - 12958, /* B2 = 0.395477 */ - -10756, /* B1 = -0.656525 */ - 12958, /* B0 = 0.395477 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f800 */ - 26413, /* A1 = -1.612122 */ - -32547, /* A2 = 0.993286 */ - -223, /* B2 = -0.006825 */ - 0, /* B1 = 0.000000 */ - 223, /* B0 = 0.006825 */ - 26342, /* A1 = -1.607849 */ - -32686, /* A2 = 0.997498 */ - 6391, /* B2 = 0.195053 */ - -5120, /* B1 = -0.312531 */ - 6391, /* B0 = 0.195053 */ - 26593, /* A1 = -1.623108 */ - -32688, /* A2 = 0.997559 */ - 23681, /* B2 = 0.722717 */ - -19328, /* B1 = -1.179688 */ - 23681, /* B0 = 0.722717 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f816 */ - 26168, /* A1 = -1.597209 */ - -32528, /* A2 = 0.992706 */ - -235, /* B2 = -0.007182 */ - 0, /* B1 = 0.000000 */ - 235, /* B0 = 0.007182 */ - 26092, /* A1 = -1.592590 */ - -32675, /* A2 = 0.997192 */ - 20823, /* B2 = 0.635498 */ - -16510, /* B1 = -1.007751 */ - 20823, /* B0 = 0.635498 */ - 26363, /* A1 = -1.609070 */ - -32677, /* A2 = 0.997253 */ - 6739, /* B2 = 0.205688 */ - -5459, /* B1 = -0.333206 */ - 6739, /* B0 = 0.205688 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f850 */ - 25641, /* A1 = -1.565063 */ - -32536, /* A2 = 0.992950 */ - -121, /* B2 = -0.003707 */ - 0, /* B1 = 0.000000 */ - 121, /* B0 = 0.003707 */ - 25560, /* A1 = -1.560059 */ - -32684, /* A2 = 0.997437 */ - 18341, /* B2 = 0.559753 */ - -14252, /* B1 = -0.869904 */ - 18341, /* B0 = 0.559753 */ - 25837, /* A1 = -1.577026 */ - -32684, /* A2 = 0.997467 */ - 16679, /* B2 = 0.509003 */ - -13232, /* B1 = -0.807648 */ - 16679, /* B0 = 0.509003 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f857_1645[] */ - 16415, /* A1 = 1.001953 */ - -23669, /* A2 = -0.722321 */ - -4549, /* B2 = -0.138847 */ - 0, /* B1 = 0 */ - 4549, /* B0 = 0.138847 */ - 8456, /* A1 = 0.516174 */ - -28996, /* A2 = -0.884918 */ - 13753, /* B2 = 0.419724 */ - -12, /* B1 = -0.000763 */ - 13757, /* B0 = 0.419846 */ - 24632, /* A1 = 1.503418 */ - -30271, /* A2 = -0.923828 */ - 29070, /* B2 = 0.887146 */ - -25265, /* B1 = -1.542114 */ - 29073, /* B0 = 0.887268 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f900 */ - 24806, /* A1 = -1.514099 */ - -32501, /* A2 = 0.991852 */ - -326, /* B2 = -0.009969 */ - 0, /* B1 = 0.000000 */ - 326, /* B0 = 0.009969 */ - 24709, /* A1 = -1.508118 */ - -32659, /* A2 = 0.996674 */ - 20277, /* B2 = 0.618835 */ - -15182, /* B1 = -0.926636 */ - 20277, /* B0 = 0.618835 */ - 25022, /* A1 = -1.527222 */ - -32661, /* A2 = 0.996735 */ - 4320, /* B2 = 0.131836 */ - -3331, /* B1 = -0.203339 */ - 4320, /* B0 = 0.131836 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f900_1300[] */ - 19776, /* A1 = 1.207092 */ - -27437, /* A2 = -0.837341 */ - -2666, /* B2 = -0.081371 */ - 0, /* B1 = 0 */ - 2666, /* B0 = 0.081371 */ - 16302, /* A1 = 0.995026 */ - -30354, /* A2 = -0.926361 */ - 10389, /* B2 = 0.317062 */ - -3327, /* B1 = -0.203064 */ - 10389, /* B0 = 0.317062 */ - 24299, /* A1 = 1.483154 */ - -30930, /* A2 = -0.943909 */ - 25016, /* B2 = 0.763428 */ - -21171, /* B1 = -1.292236 */ - 25016, /* B0 = 0.763428 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f935_1215[] */ - 20554, /* A1 = 1.254517 */ - -28764, /* A2 = -0.877838 */ - -2048, /* B2 = -0.062515 */ - 0, /* B1 = 0 */ - 2048, /* B0 = 0.062515 */ - 18209, /* A1 = 1.11145 */ - -30951, /* A2 = -0.94458 */ - 9390, /* B2 = 0.286575 */ - -3955, /* B1 = -0.241455 */ - 9390, /* B0 = 0.286575 */ - 23902, /* A1 = 1.458923 */ - -31286, /* A2 = -0.954803 */ - 23252, /* B2 = 0.709595 */ - -19132, /* B1 = -1.167725 */ - 23252, /* B0 = 0.709595 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f941_1477[] */ - 17543, /* A1 = 1.07074 */ - -26220, /* A2 = -0.800201 */ - -3298, /* B2 = -0.100647 */ - 0, /* B1 = 0 */ - 3298, /* B0 = 0.100647 */ - 12423, /* A1 = 0.75827 */ - -30036, /* A2 = -0.916626 */ - 12651, /* B2 = 0.386078 */ - -2444, /* B1 = -0.14917 */ - 12653, /* B0 = 0.386154 */ - 23518, /* A1 = 1.435425 */ - -30745, /* A2 = -0.938293 */ - 27282, /* B2 = 0.832581 */ - -22529, /* B1 = -1.375122 */ - 27286, /* B0 = 0.832703 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f942 */ - 24104, /* A1 = -1.471252 */ - -32507, /* A2 = 0.992065 */ - -351, /* B2 = -0.010722 */ - 0, /* B1 = 0.000000 */ - 351, /* B0 = 0.010722 */ - 23996, /* A1 = -1.464600 */ - -32671, /* A2 = 0.997040 */ - 22848, /* B2 = 0.697266 */ - -16639, /* B1 = -1.015564 */ - 22848, /* B0 = 0.697266 */ - 24332, /* A1 = -1.485168 */ - -32673, /* A2 = 0.997101 */ - 4906, /* B2 = 0.149727 */ - -3672, /* B1 = -0.224174 */ - 4906, /* B0 = 0.149727 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f950 */ - 23967, /* A1 = -1.462830 */ - -32507, /* A2 = 0.992065 */ - -518, /* B2 = -0.015821 */ - 0, /* B1 = 0.000000 */ - 518, /* B0 = 0.015821 */ - 23856, /* A1 = -1.456055 */ - -32671, /* A2 = 0.997040 */ - 26287, /* B2 = 0.802246 */ - -19031, /* B1 = -1.161560 */ - 26287, /* B0 = 0.802246 */ - 24195, /* A1 = -1.476746 */ - -32673, /* A2 = 0.997101 */ - 2890, /* B2 = 0.088196 */ - -2151, /* B1 = -0.131317 */ - 2890, /* B0 = 0.088196 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f950_1400[] */ - 18294, /* A1 = 1.116638 */ - -26962, /* A2 = -0.822845 */ - -2914, /* B2 = -0.088936 */ - 0, /* B1 = 0 */ - 2914, /* B0 = 0.088936 */ - 14119, /* A1 = 0.861786 */ - -30227, /* A2 = -0.922455 */ - 11466, /* B2 = 0.349945 */ - -2833, /* B1 = -0.172943 */ - 11466, /* B0 = 0.349945 */ - 23431, /* A1 = 1.430115 */ - -30828, /* A2 = -0.940796 */ - 25331, /* B2 = 0.773071 */ - -20911, /* B1 = -1.276367 */ - 25331, /* B0 = 0.773071 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f975 */ - 23521, /* A1 = -1.435608 */ - -32489, /* A2 = 0.991516 */ - -193, /* B2 = -0.005915 */ - 0, /* B1 = 0.000000 */ - 193, /* B0 = 0.005915 */ - 23404, /* A1 = -1.428467 */ - -32655, /* A2 = 0.996582 */ - 17740, /* B2 = 0.541412 */ - -12567, /* B1 = -0.767029 */ - 17740, /* B0 = 0.541412 */ - 23753, /* A1 = -1.449829 */ - -32657, /* A2 = 0.996613 */ - 9090, /* B2 = 0.277405 */ - -6662, /* B1 = -0.406647 */ - 9090, /* B0 = 0.277405 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1000 */ - 23071, /* A1 = -1.408203 */ - -32489, /* A2 = 0.991516 */ - -293, /* B2 = -0.008965 */ - 0, /* B1 = 0.000000 */ - 293, /* B0 = 0.008965 */ - 22951, /* A1 = -1.400818 */ - -32655, /* A2 = 0.996582 */ - 5689, /* B2 = 0.173645 */ - -3951, /* B1 = -0.241150 */ - 5689, /* B0 = 0.173645 */ - 23307, /* A1 = -1.422607 */ - -32657, /* A2 = 0.996613 */ - 18692, /* B2 = 0.570435 */ - -13447, /* B1 = -0.820770 */ - 18692, /* B0 = 0.570435 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1020 */ - 22701, /* A1 = -1.385620 */ - -32474, /* A2 = 0.991058 */ - -292, /* B2 = -0.008933 */ - 0, /*163840 , B1 = 10.000000 */ - 292, /* B0 = 0.008933 */ - 22564, /* A1 = -1.377258 */ - -32655, /* A2 = 0.996552 */ - 20756, /* B2 = 0.633423 */ - -14176, /* B1 = -0.865295 */ - 20756, /* B0 = 0.633423 */ - 22960, /* A1 = -1.401428 */ - -32657, /* A2 = 0.996613 */ - 6520, /* B2 = 0.198990 */ - -4619, /* B1 = -0.281937 */ - 6520, /* B0 = 0.198990 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1050 */ - 22142, /* A1 = -1.351501 */ - -32474, /* A2 = 0.991058 */ - -147, /* B2 = -0.004493 */ - 0, /* B1 = 0.000000 */ - 147, /* B0 = 0.004493 */ - 22000, /* A1 = -1.342834 */ - -32655, /* A2 = 0.996552 */ - 15379, /* B2 = 0.469360 */ - -10237, /* B1 = -0.624847 */ - 15379, /* B0 = 0.469360 */ - 22406, /* A1 = -1.367554 */ - -32657, /* A2 = 0.996613 */ - 17491, /* B2 = 0.533783 */ - -12096, /* B1 = -0.738312 */ - 17491, /* B0 = 0.533783 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1100_1750[] */ - 12973, /* A1 = 0.79184 */ - -24916, /* A2 = -0.760376 */ - 6655, /* B2 = 0.203102 */ - 367, /* B1 = 0.0224 */ - 6657, /* B0 = 0.203171 */ - 5915, /* A1 = 0.361053 */ - -29560, /* A2 = -0.90213 */ - -7777, /* B2 = -0.23735 */ - 0, /* B1 = 0 */ - 7777, /* B0 = 0.23735 */ - 20510, /* A1 = 1.251892 */ - -30260, /* A2 = -0.923462 */ - 26662, /* B2 = 0.81366 */ - -20573, /* B1 = -1.255737 */ - 26668, /* B0 = 0.813843 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1140 */ - 20392, /* A1 = -1.244629 */ - -32460, /* A2 = 0.990601 */ - -270, /* B2 = -0.008240 */ - 0, /* B1 = 0.000000 */ - 270, /* B0 = 0.008240 */ - 20218, /* A1 = -1.234009 */ - -32655, /* A2 = 0.996582 */ - 21337, /* B2 = 0.651154 */ - -13044, /* B1 = -0.796143 */ - 21337, /* B0 = 0.651154 */ - 20684, /* A1 = -1.262512 */ - -32657, /* A2 = 0.996643 */ - 8572, /* B2 = 0.261612 */ - -5476, /* B1 = -0.334244 */ - 8572, /* B0 = 0.261612 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1200 */ - 19159, /* A1 = -1.169373 */ - -32456, /* A2 = 0.990509 */ - -335, /* B2 = -0.010252 */ - 0, /* B1 = 0.000000 */ - 335, /* B0 = 0.010252 */ - 18966, /* A1 = -1.157593 */ - -32661, /* A2 = 0.996735 */ - 6802, /* B2 = 0.207588 */ - -3900, /* B1 = -0.238098 */ - 6802, /* B0 = 0.207588 */ - 19467, /* A1 = -1.188232 */ - -32661, /* A2 = 0.996765 */ - 25035, /* B2 = 0.764008 */ - -15049, /* B1 = -0.918579 */ - 25035, /* B0 = 0.764008 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1209 */ - 18976, /* A1 = -1.158264 */ - -32439, /* A2 = 0.989990 */ - -183, /* B2 = -0.005588 */ - 0, /* B1 = 0.000000 */ - 183, /* B0 = 0.005588 */ - 18774, /* A1 = -1.145874 */ - -32650, /* A2 = 0.996429 */ - 15468, /* B2 = 0.472076 */ - -8768, /* B1 = -0.535217 */ - 15468, /* B0 = 0.472076 */ - 19300, /* A1 = -1.177979 */ - -32652, /* A2 = 0.996490 */ - 19840, /* B2 = 0.605499 */ - -11842, /* B1 = -0.722809 */ - 19840, /* B0 = 0.605499 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1330 */ - 16357, /* A1 = -0.998413 */ - -32368, /* A2 = 0.987793 */ - -217, /* B2 = -0.006652 */ - 0, /* B1 = 0.000000 */ - 217, /* B0 = 0.006652 */ - 16107, /* A1 = -0.983126 */ - -32601, /* A2 = 0.994904 */ - 11602, /* B2 = 0.354065 */ - -5555, /* B1 = -0.339111 */ - 11602, /* B0 = 0.354065 */ - 16722, /* A1 = -1.020630 */ - -32603, /* A2 = 0.994965 */ - 15574, /* B2 = 0.475311 */ - -8176, /* B1 = -0.499069 */ - 15574, /* B0 = 0.475311 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1336 */ - 16234, /* A1 = -0.990875 */ - 32404, /* A2 = -0.988922 */ - -193, /* B2 = -0.005908 */ - 0, /* B1 = 0.000000 */ - 193, /* B0 = 0.005908 */ - 15986, /* A1 = -0.975769 */ - -32632, /* A2 = 0.995880 */ - 18051, /* B2 = 0.550903 */ - -8658, /* B1 = -0.528473 */ - 18051, /* B0 = 0.550903 */ - 16591, /* A1 = -1.012695 */ - -32634, /* A2 = 0.995941 */ - 15736, /* B2 = 0.480240 */ - -8125, /* B1 = -0.495926 */ - 15736, /* B0 = 0.480240 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1366 */ - 15564, /* A1 = -0.949982 */ - -32404, /* A2 = 0.988922 */ - -269, /* B2 = -0.008216 */ - 0, /* B1 = 0.000000 */ - 269, /* B0 = 0.008216 */ - 15310, /* A1 = -0.934479 */ - -32632, /* A2 = 0.995880 */ - 10815, /* B2 = 0.330063 */ - -4962, /* B1 = -0.302887 */ - 10815, /* B0 = 0.330063 */ - 15924, /* A1 = -0.971924 */ - -32634, /* A2 = 0.995941 */ - 18880, /* B2 = 0.576172 */ - -9364, /* B1 = -0.571594 */ - 18880, /* B0 = 0.576172 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1380 */ - 15247, /* A1 = -0.930603 */ - -32397, /* A2 = 0.988708 */ - -244, /* B2 = -0.007451 */ - 0, /* B1 = 0.000000 */ - 244, /* B0 = 0.007451 */ - 14989, /* A1 = -0.914886 */ - -32627, /* A2 = 0.995697 */ - 18961, /* B2 = 0.578644 */ - -8498, /* B1 = -0.518707 */ - 18961, /* B0 = 0.578644 */ - 15608, /* A1 = -0.952667 */ - -32628, /* A2 = 0.995758 */ - 11145, /* B2 = 0.340134 */ - -5430, /* B1 = -0.331467 */ - 11145, /* B0 = 0.340134 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1400 */ - 14780, /* A1 = -0.902130 */ - -32393, /* A2 = 0.988586 */ - -396, /* B2 = -0.012086 */ - 0, /* B1 = 0.000000 */ - 396, /* B0 = 0.012086 */ - 14510, /* A1 = -0.885651 */ - -32630, /* A2 = 0.995819 */ - 6326, /* B2 = 0.193069 */ - -2747, /* B1 = -0.167671 */ - 6326, /* B0 = 0.193069 */ - 15154, /* A1 = -0.924957 */ - -32632, /* A2 = 0.995850 */ - 23235, /* B2 = 0.709076 */ - -10983, /* B1 = -0.670380 */ - 23235, /* B0 = 0.709076 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1477 */ - 13005, /* A1 = -0.793793 */ - -32368, /* A2 = 0.987823 */ - -500, /* B2 = -0.015265 */ - 0, /* B1 = 0.000000 */ - 500, /* B0 = 0.015265 */ - 12708, /* A1 = -0.775665 */ - -32615, /* A2 = 0.995331 */ - 11420, /* B2 = 0.348526 */ - -4306, /* B1 = -0.262833 */ - 11420, /* B0 = 0.348526 */ - 13397, /* A1 = -0.817688 */ - -32615, /* A2 = 0.995361 */ - 9454, /* B2 = 0.288528 */ - -3981, /* B1 = -0.243027 */ - 9454, /* B0 = 0.288528 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1600 */ - 10046, /* A1 = -0.613190 */ - -32331, /* A2 = 0.986694 */ - -455, /* B2 = -0.013915 */ - 0, /* B1 = 0.000000 */ - 455, /* B0 = 0.013915 */ - 9694, /* A1 = -0.591705 */ - -32601, /* A2 = 0.994934 */ - 6023, /* B2 = 0.183815 */ - -1708, /* B1 = -0.104279 */ - 6023, /* B0 = 0.183815 */ - 10478, /* A1 = -0.639587 */ - -32603, /* A2 = 0.994965 */ - 22031, /* B2 = 0.672333 */ - -7342, /* B1 = -0.448151 */ - 22031, /* B0 = 0.672333 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1633_1638[] */ - 9181, /* A1 = 0.560394 */ - -32256, /* A2 = -0.984375 */ - -556, /* B2 = -0.016975 */ - 0, /* B1 = 0 */ - 556, /* B0 = 0.016975 */ - 8757, /* A1 = 0.534515 */ - -32574, /* A2 = -0.99408 */ - 8443, /* B2 = 0.25769 */ - -2135, /* B1 = -0.130341 */ - 8443, /* B0 = 0.25769 */ - 9691, /* A1 = 0.591522 */ - -32574, /* A2 = -0.99411 */ - 15446, /* B2 = 0.471375 */ - -4809, /* B1 = -0.293579 */ - 15446, /* B0 = 0.471375 */ - 7, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1800 */ - 5076, /* A1 = -0.309875 */ - -32304, /* A2 = 0.985840 */ - -508, /* B2 = -0.015503 */ - 0, /* B1 = 0.000000 */ - 508, /* B0 = 0.015503 */ - 4646, /* A1 = -0.283600 */ - -32605, /* A2 = 0.995026 */ - 6742, /* B2 = 0.205780 */ - -878, /* B1 = -0.053635 */ - 6742, /* B0 = 0.205780 */ - 5552, /* A1 = -0.338928 */ - -32605, /* A2 = 0.995056 */ - 23667, /* B2 = 0.722260 */ - -4297, /* B1 = -0.262329 */ - 23667, /* B0 = 0.722260 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, - { /* f1860 */ - 3569, /* A1 = -0.217865 */ - -32292, /* A2 = 0.985504 */ - -239, /* B2 = -0.007322 */ - 0, /* B1 = 0.000000 */ - 239, /* B0 = 0.007322 */ - 3117, /* A1 = -0.190277 */ - -32603, /* A2 = 0.994965 */ - 18658, /* B2 = 0.569427 */ - -1557, /* B1 = -0.095032 */ - 18658, /* B0 = 0.569427 */ - 4054, /* A1 = -0.247437 */ - -32603, /* A2 = 0.994965 */ - 18886, /* B2 = 0.576385 */ - -2566, /* B1 = -0.156647 */ - 18886, /* B0 = 0.576385 */ - 5, /* Internal filter scaling */ - 159, /* Minimum in-band energy threshold */ - 21, /* 21/32 in-band to broad-band ratio */ - 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */ - }, -}; -static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf) -{ - unsigned short cmd; - int cnt, max; - - if (jf->filter > 3) { - return -1; - } - if (ixj_WriteDSPCommand(0x5154 + jf->filter, j)) /* Select Filter */ - - return -1; - if (!jf->enable) { - if (ixj_WriteDSPCommand(0x5152, j)) /* Disable Filter */ - - return -1; - else - return 0; - } else { - if (ixj_WriteDSPCommand(0x5153, j)) /* Enable Filter */ - - return -1; - /* Select the filter (f0 - f3) to use. */ - if (ixj_WriteDSPCommand(0x5154 + jf->filter, j)) - return -1; - } - if (jf->freq < 12 && jf->freq > 3) { - /* Select the frequency for the selected filter. */ - if (ixj_WriteDSPCommand(0x5170 + jf->freq, j)) - return -1; - } else if (jf->freq > 11) { - /* We need to load a programmable filter set for undefined */ - /* frequencies. So we will point the filter to a programmable set. */ - /* Since there are only 4 filters and 4 programmable sets, we will */ - /* just point the filter to the same number set and program it for the */ - /* frequency we want. */ - if (ixj_WriteDSPCommand(0x5170 + jf->filter, j)) - return -1; - if (j->ver.low != 0x12) { - cmd = 0x515B; - max = 19; - } else { - cmd = 0x515E; - max = 15; - } - if (ixj_WriteDSPCommand(cmd, j)) - return -1; - for (cnt = 0; cnt < max; cnt++) { - if (ixj_WriteDSPCommand(tone_table[jf->freq - 12][cnt], j)) - return -1; - } - } - j->filter_en[jf->filter] = jf->enable; - return 0; -} - -static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr) -{ - unsigned short cmd; - int cnt, max; - if (jfr->filter > 3) { - return -1; - } - if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j)) /* Select Filter */ - return -1; - - if (!jfr->enable) { - if (ixj_WriteDSPCommand(0x5152, j)) /* Disable Filter */ - return -1; - else - return 0; - } else { - if (ixj_WriteDSPCommand(0x5153, j)) /* Enable Filter */ - return -1; - /* Select the filter (f0 - f3) to use. */ - if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j)) - return -1; - } - /* We need to load a programmable filter set for undefined */ - /* frequencies. So we will point the filter to a programmable set. */ - /* Since there are only 4 filters and 4 programmable sets, we will */ - /* just point the filter to the same number set and program it for the */ - /* frequency we want. */ - if (ixj_WriteDSPCommand(0x5170 + jfr->filter, j)) - return -1; - if (j->ver.low != 0x12) { - cmd = 0x515B; - max = 19; - } else { - cmd = 0x515E; - max = 15; - } - if (ixj_WriteDSPCommand(cmd, j)) - return -1; - for (cnt = 0; cnt < max; cnt++) { - if (ixj_WriteDSPCommand(jfr->coeff[cnt], j)) - return -1; - } - j->filter_en[jfr->filter] = jfr->enable; - return 0; -} - -static int ixj_init_tone(IXJ *j, IXJ_TONE * ti) -{ - int freq0, freq1; - unsigned short data; - if (ti->freq0) { - freq0 = ti->freq0; - } else { - freq0 = 0x7FFF; - } - - if (ti->freq1) { - freq1 = ti->freq1; - } else { - freq1 = 0x7FFF; - } - - if(ti->tone_index > 12 && ti->tone_index < 28) - { - if (ixj_WriteDSPCommand(0x6800 + ti->tone_index, j)) - return -1; - if (ixj_WriteDSPCommand(0x6000 + (ti->gain1 << 4) + ti->gain0, j)) - return -1; - data = freq0; - if (ixj_WriteDSPCommand(data, j)) - return -1; - data = freq1; - if (ixj_WriteDSPCommand(data, j)) - return -1; - } - return freq0; -} - diff --git a/drivers/staging/telephony/ixj.h b/drivers/staging/telephony/ixj.h deleted file mode 100644 index 2c841134f61..00000000000 --- a/drivers/staging/telephony/ixj.h +++ /dev/null @@ -1,1322 +0,0 @@ -/****************************************************************************** - * ixj.h - * - * - * Device Driver for Quicknet Technologies, Inc.'s Telephony cards - * including the Internet PhoneJACK, Internet PhoneJACK Lite, - * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and - * SmartCABLE - * - * (c) Copyright 1999-2001 Quicknet Technologies, Inc. - * - * 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. - * - * Author: Ed Okerson, - * - * Contributors: Greg Herlein, - * David W. Erhart, - * John Sellers, - * Mike Preston, - * - * More information about the hardware related to this driver can be found - * at our website: http://www.quicknet.net - * - * Fixes: - * - * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET - * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION - * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - *****************************************************************************/ -#define IXJ_VERSION 3031 - -#include - -#include -#include - -typedef __u16 WORD; -typedef __u32 DWORD; -typedef __u8 BYTE; - -#ifndef IXJMAX -#define IXJMAX 16 -#endif - -/****************************************************************************** -* -* This structure when unioned with the structures below makes simple byte -* access to the registers easier. -* -******************************************************************************/ -typedef struct { - unsigned char low; - unsigned char high; -} BYTES; - -typedef union { - BYTES bytes; - short word; -} IXJ_WORD; - -typedef struct{ - unsigned int b0:1; - unsigned int b1:1; - unsigned int b2:1; - unsigned int b3:1; - unsigned int b4:1; - unsigned int b5:1; - unsigned int b6:1; - unsigned int b7:1; -} IXJ_CBITS; - -typedef union{ - IXJ_CBITS cbits; - char cbyte; -} IXJ_CBYTE; - -/****************************************************************************** -* -* This structure represents the Hardware Control Register of the CT8020/8021 -* The CT8020 is used in the Internet PhoneJACK, and the 8021 in the -* Internet LineJACK -* -******************************************************************************/ -typedef struct { - unsigned int rxrdy:1; - unsigned int txrdy:1; - unsigned int status:1; - unsigned int auxstatus:1; - unsigned int rxdma:1; - unsigned int txdma:1; - unsigned int rxburst:1; - unsigned int txburst:1; - unsigned int dmadir:1; - unsigned int cont:1; - unsigned int irqn:1; - unsigned int t:5; -} HCRBIT; - -typedef union { - HCRBIT bits; - BYTES bytes; -} HCR; - -/****************************************************************************** -* -* This structure represents the Hardware Status Register of the CT8020/8021 -* The CT8020 is used in the Internet PhoneJACK, and the 8021 in the -* Internet LineJACK -* -******************************************************************************/ -typedef struct { - unsigned int controlrdy:1; - unsigned int auxctlrdy:1; - unsigned int statusrdy:1; - unsigned int auxstatusrdy:1; - unsigned int rxrdy:1; - unsigned int txrdy:1; - unsigned int restart:1; - unsigned int irqn:1; - unsigned int rxdma:1; - unsigned int txdma:1; - unsigned int cohostshutdown:1; - unsigned int t:5; -} HSRBIT; - -typedef union { - HSRBIT bits; - BYTES bytes; -} HSR; - -/****************************************************************************** -* -* This structure represents the General Purpose IO Register of the CT8020/8021 -* The CT8020 is used in the Internet PhoneJACK, and the 8021 in the -* Internet LineJACK -* -******************************************************************************/ -typedef struct { - unsigned int x:1; - unsigned int gpio1:1; - unsigned int gpio2:1; - unsigned int gpio3:1; - unsigned int gpio4:1; - unsigned int gpio5:1; - unsigned int gpio6:1; - unsigned int gpio7:1; - unsigned int xread:1; - unsigned int gpio1read:1; - unsigned int gpio2read:1; - unsigned int gpio3read:1; - unsigned int gpio4read:1; - unsigned int gpio5read:1; - unsigned int gpio6read:1; - unsigned int gpio7read:1; -} GPIOBIT; - -typedef union { - GPIOBIT bits; - BYTES bytes; - unsigned short word; -} GPIO; - -/****************************************************************************** -* -* This structure represents the Line Monitor status response -* -******************************************************************************/ -typedef struct { - unsigned int digit:4; - unsigned int cpf_valid:1; - unsigned int dtmf_valid:1; - unsigned int peak:1; - unsigned int z:1; - unsigned int f0:1; - unsigned int f1:1; - unsigned int f2:1; - unsigned int f3:1; - unsigned int frame:4; -} LMON; - -typedef union { - LMON bits; - BYTES bytes; -} DTMF; - -typedef struct { - unsigned int z:7; - unsigned int dtmf_en:1; - unsigned int y:4; - unsigned int F3:1; - unsigned int F2:1; - unsigned int F1:1; - unsigned int F0:1; -} CP; - -typedef union { - CP bits; - BYTES bytes; -} CPTF; - -/****************************************************************************** -* -* This structure represents the Status Control Register on the Internet -* LineJACK -* -******************************************************************************/ -typedef struct { - unsigned int c0:1; - unsigned int c1:1; - unsigned int stereo:1; - unsigned int daafsyncen:1; - unsigned int led1:1; - unsigned int led2:1; - unsigned int led3:1; - unsigned int led4:1; -} PSCRWI; /* Internet LineJACK and Internet PhoneJACK Lite */ - -typedef struct { - unsigned int eidp:1; - unsigned int eisd:1; - unsigned int x:6; -} PSCRWP; /* Internet PhoneJACK PCI */ - -typedef union { - PSCRWI bits; - PSCRWP pcib; - char byte; -} PLD_SCRW; - -typedef struct { - unsigned int c0:1; - unsigned int c1:1; - unsigned int x:1; - unsigned int d0ee:1; - unsigned int mixerbusy:1; - unsigned int sci:1; - unsigned int dspflag:1; - unsigned int daaflag:1; -} PSCRRI; - -typedef struct { - unsigned int eidp:1; - unsigned int eisd:1; - unsigned int x:4; - unsigned int dspflag:1; - unsigned int det:1; -} PSCRRP; - -typedef union { - PSCRRI bits; - PSCRRP pcib; - char byte; -} PLD_SCRR; - -/****************************************************************************** -* -* These structures represents the SLIC Control Register on the -* Internet LineJACK -* -******************************************************************************/ -typedef struct { - unsigned int c1:1; - unsigned int c2:1; - unsigned int c3:1; - unsigned int b2en:1; - unsigned int spken:1; - unsigned int rly1:1; - unsigned int rly2:1; - unsigned int rly3:1; -} PSLICWRITE; - -typedef struct { - unsigned int state:3; - unsigned int b2en:1; - unsigned int spken:1; - unsigned int c3:1; - unsigned int potspstn:1; - unsigned int det:1; -} PSLICREAD; - -typedef struct { - unsigned int c1:1; - unsigned int c2:1; - unsigned int c3:1; - unsigned int b2en:1; - unsigned int e1:1; - unsigned int mic:1; - unsigned int spk:1; - unsigned int x:1; -} PSLICPCI; - -typedef union { - PSLICPCI pcib; - PSLICWRITE bits; - PSLICREAD slic; - char byte; -} PLD_SLICW; - -typedef union { - PSLICPCI pcib; - PSLICREAD bits; - char byte; -} PLD_SLICR; - -/****************************************************************************** -* -* These structures represents the Clock Control Register on the -* Internet LineJACK -* -******************************************************************************/ -typedef struct { - unsigned int clk0:1; - unsigned int clk1:1; - unsigned int clk2:1; - unsigned int x0:1; - unsigned int slic_e1:1; - unsigned int x1:1; - unsigned int x2:1; - unsigned int x3:1; -} PCLOCK; - -typedef union { - PCLOCK bits; - char byte; -} PLD_CLOCK; - -/****************************************************************************** -* -* These structures deal with the mixer on the Internet LineJACK -* -******************************************************************************/ - -typedef struct { - unsigned short vol[10]; - unsigned int recsrc; - unsigned int modcnt; - unsigned short micpreamp; -} MIX; - -/****************************************************************************** -* -* These structures deal with the control logic on the Internet PhoneCARD -* -******************************************************************************/ -typedef struct { - unsigned int x0:4; /* unused bits */ - - unsigned int ed:1; /* Event Detect */ - - unsigned int drf:1; /* SmartCABLE Removal Flag 1=no cable */ - - unsigned int dspf:1; /* DSP Flag 1=DSP Ready */ - - unsigned int crr:1; /* Control Register Ready */ - -} COMMAND_REG1; - -typedef union { - COMMAND_REG1 bits; - unsigned char byte; -} PCMCIA_CR1; - -typedef struct { - unsigned int x0:4; /* unused bits */ - - unsigned int rstc:1; /* SmartCABLE Reset */ - - unsigned int pwr:1; /* SmartCABLE Power */ - - unsigned int x1:2; /* unused bits */ - -} COMMAND_REG2; - -typedef union { - COMMAND_REG2 bits; - unsigned char byte; -} PCMCIA_CR2; - -typedef struct { - unsigned int addr:5; /* R/W SmartCABLE Register Address */ - - unsigned int rw:1; /* Read / Write flag */ - - unsigned int dev:2; /* 2 bit SmartCABLE Device Address */ - -} CONTROL_REG; - -typedef union { - CONTROL_REG bits; - unsigned char byte; -} PCMCIA_SCCR; - -typedef struct { - unsigned int hsw:1; - unsigned int det:1; - unsigned int led2:1; - unsigned int led1:1; - unsigned int ring1:1; - unsigned int ring0:1; - unsigned int x:1; - unsigned int powerdown:1; -} PCMCIA_SLIC_REG; - -typedef union { - PCMCIA_SLIC_REG bits; - unsigned char byte; -} PCMCIA_SLIC; - -typedef struct { - unsigned int cpd:1; /* Chip Power Down */ - - unsigned int mpd:1; /* MIC Bias Power Down */ - - unsigned int hpd:1; /* Handset Drive Power Down */ - - unsigned int lpd:1; /* Line Drive Power Down */ - - unsigned int spd:1; /* Speaker Drive Power Down */ - - unsigned int x:2; /* unused bits */ - - unsigned int sr:1; /* Software Reset */ - -} Si3CONTROL1; - -typedef union { - Si3CONTROL1 bits; - unsigned char byte; -} Si3C1; - -typedef struct { - unsigned int al:1; /* Analog Loopback DAC analog -> ADC analog */ - - unsigned int dl2:1; /* Digital Loopback DAC -> ADC one bit */ - - unsigned int dl1:1; /* Digital Loopback ADC -> DAC one bit */ - - unsigned int pll:1; /* 1 = div 10, 0 = div 5 */ - - unsigned int hpd:1; /* HPF disable */ - - unsigned int x:3; /* unused bits */ - -} Si3CONTROL2; - -typedef union { - Si3CONTROL2 bits; - unsigned char byte; -} Si3C2; - -typedef struct { - unsigned int iir:1; /* 1 enables IIR, 0 enables FIR */ - - unsigned int him:1; /* Handset Input Mute */ - - unsigned int mcm:1; /* MIC In Mute */ - - unsigned int mcg:2; /* MIC In Gain */ - - unsigned int lim:1; /* Line In Mute */ - - unsigned int lig:2; /* Line In Gain */ - -} Si3RXGAIN; - -typedef union { - Si3RXGAIN bits; - unsigned char byte; -} Si3RXG; - -typedef struct { - unsigned int hom:1; /* Handset Out Mute */ - - unsigned int lom:1; /* Line Out Mute */ - - unsigned int rxg:5; /* RX PGA Gain */ - - unsigned int x:1; /* unused bit */ - -} Si3ADCVOLUME; - -typedef union { - Si3ADCVOLUME bits; - unsigned char byte; -} Si3ADC; - -typedef struct { - unsigned int srm:1; /* Speaker Right Mute */ - - unsigned int slm:1; /* Speaker Left Mute */ - - unsigned int txg:5; /* TX PGA Gain */ - - unsigned int x:1; /* unused bit */ - -} Si3DACVOLUME; - -typedef union { - Si3DACVOLUME bits; - unsigned char byte; -} Si3DAC; - -typedef struct { - unsigned int x:5; /* unused bit */ - - unsigned int losc:1; /* Line Out Short Circuit */ - - unsigned int srsc:1; /* Speaker Right Short Circuit */ - - unsigned int slsc:1; /* Speaker Left Short Circuit */ - -} Si3STATUSREPORT; - -typedef union { - Si3STATUSREPORT bits; - unsigned char byte; -} Si3STAT; - -typedef struct { - unsigned int sot:2; /* Speaker Out Attenuation */ - - unsigned int lot:2; /* Line Out Attenuation */ - - unsigned int x:4; /* unused bits */ - -} Si3ANALOGATTN; - -typedef union { - Si3ANALOGATTN bits; - unsigned char byte; -} Si3AATT; - -/****************************************************************************** -* -* These structures deal with the DAA on the Internet LineJACK -* -******************************************************************************/ - -typedef struct _DAA_REGS { - /*----------------------------------------------- */ - /* SOP Registers */ - /* */ - BYTE bySOP; - - union _SOP_REGS { - struct _SOP { - union /* SOP - CR0 Register */ - { - BYTE reg; - struct _CR0_BITREGS { - BYTE CLK_EXT:1; /* cr0[0:0] */ - - BYTE RIP:1; /* cr0[1:1] */ - - BYTE AR:1; /* cr0[2:2] */ - - BYTE AX:1; /* cr0[3:3] */ - - BYTE FRR:1; /* cr0[4:4] */ - - BYTE FRX:1; /* cr0[5:5] */ - - BYTE IM:1; /* cr0[6:6] */ - - BYTE TH:1; /* cr0[7:7] */ - - } bitreg; - } cr0; - - union /* SOP - CR1 Register */ - { - BYTE reg; - struct _CR1_REGS { - BYTE RM:1; /* cr1[0:0] */ - - BYTE RMR:1; /* cr1[1:1] */ - - BYTE No_auto:1; /* cr1[2:2] */ - - BYTE Pulse:1; /* cr1[3:3] */ - - BYTE P_Tone1:1; /* cr1[4:4] */ - - BYTE P_Tone2:1; /* cr1[5:5] */ - - BYTE E_Tone1:1; /* cr1[6:6] */ - - BYTE E_Tone2:1; /* cr1[7:7] */ - - } bitreg; - } cr1; - - union /* SOP - CR2 Register */ - { - BYTE reg; - struct _CR2_REGS { - BYTE Call_II:1; /* CR2[0:0] */ - - BYTE Call_I:1; /* CR2[1:1] */ - - BYTE Call_en:1; /* CR2[2:2] */ - - BYTE Call_pon:1; /* CR2[3:3] */ - - BYTE IDR:1; /* CR2[4:4] */ - - BYTE COT_R:3; /* CR2[5:7] */ - - } bitreg; - } cr2; - - union /* SOP - CR3 Register */ - { - BYTE reg; - struct _CR3_REGS { - BYTE DHP_X:1; /* CR3[0:0] */ - - BYTE DHP_R:1; /* CR3[1:1] */ - - BYTE Cal_pctl:1; /* CR3[2:2] */ - - BYTE SEL:1; /* CR3[3:3] */ - - BYTE TestLoops:4; /* CR3[4:7] */ - - } bitreg; - } cr3; - - union /* SOP - CR4 Register */ - { - BYTE reg; - struct _CR4_REGS { - BYTE Fsc_en:1; /* CR4[0:0] */ - - BYTE Int_en:1; /* CR4[1:1] */ - - BYTE AGX:2; /* CR4[2:3] */ - - BYTE AGR_R:2; /* CR4[4:5] */ - - BYTE AGR_Z:2; /* CR4[6:7] */ - - } bitreg; - } cr4; - - union /* SOP - CR5 Register */ - { - BYTE reg; - struct _CR5_REGS { - BYTE V_0:1; /* CR5[0:0] */ - - BYTE V_1:1; /* CR5[1:1] */ - - BYTE V_2:1; /* CR5[2:2] */ - - BYTE V_3:1; /* CR5[3:3] */ - - BYTE V_4:1; /* CR5[4:4] */ - - BYTE V_5:1; /* CR5[5:5] */ - - BYTE V_6:1; /* CR5[6:6] */ - - BYTE V_7:1; /* CR5[7:7] */ - - } bitreg; - } cr5; - - union /* SOP - CR6 Register */ - { - BYTE reg; - struct _CR6_REGS { - BYTE reserved:8; /* CR6[0:7] */ - - } bitreg; - } cr6; - - union /* SOP - CR7 Register */ - { - BYTE reg; - struct _CR7_REGS { - BYTE reserved:8; /* CR7[0:7] */ - - } bitreg; - } cr7; - } SOP; - - BYTE ByteRegs[sizeof(struct _SOP)]; - - } SOP_REGS; - - /* DAA_REGS.SOP_REGS.SOP.CR5.reg */ - /* DAA_REGS.SOP_REGS.SOP.CR5.bitreg */ - /* DAA_REGS.SOP_REGS.SOP.CR5.bitreg.V_2 */ - /* DAA_REGS.SOP_REGS.ByteRegs[5] */ - - /*----------------------------------------------- */ - /* XOP Registers */ - /* */ - BYTE byXOP; - - union _XOP_REGS { - struct _XOP { - union XOPXR0/* XOP - XR0 Register - Read values */ - { - BYTE reg; - struct _XR0_BITREGS { - BYTE SI_0:1; /* XR0[0:0] - Read */ - - BYTE SI_1:1; /* XR0[1:1] - Read */ - - BYTE VDD_OK:1; /* XR0[2:2] - Read */ - - BYTE Caller_ID:1; /* XR0[3:3] - Read */ - - BYTE RING:1; /* XR0[4:4] - Read */ - - BYTE Cadence:1; /* XR0[5:5] - Read */ - - BYTE Wake_up:1; /* XR0[6:6] - Read */ - - BYTE RMR:1; /* XR0[7:7] - Read */ - - } bitreg; - } xr0; - - union /* XOP - XR1 Register */ - { - BYTE reg; - struct _XR1_BITREGS { - BYTE M_SI_0:1; /* XR1[0:0] */ - - BYTE M_SI_1:1; /* XR1[1:1] */ - - BYTE M_VDD_OK:1; /* XR1[2:2] */ - - BYTE M_Caller_ID:1; /* XR1[3:3] */ - - BYTE M_RING:1; /* XR1[4:4] */ - - BYTE M_Cadence:1; /* XR1[5:5] */ - - BYTE M_Wake_up:1; /* XR1[6:6] */ - - BYTE unused:1; /* XR1[7:7] */ - - } bitreg; - } xr1; - - union /* XOP - XR2 Register */ - { - BYTE reg; - struct _XR2_BITREGS { - BYTE CTO0:1; /* XR2[0:0] */ - - BYTE CTO1:1; /* XR2[1:1] */ - - BYTE CTO2:1; /* XR2[2:2] */ - - BYTE CTO3:1; /* XR2[3:3] */ - - BYTE CTO4:1; /* XR2[4:4] */ - - BYTE CTO5:1; /* XR2[5:5] */ - - BYTE CTO6:1; /* XR2[6:6] */ - - BYTE CTO7:1; /* XR2[7:7] */ - - } bitreg; - } xr2; - - union /* XOP - XR3 Register */ - { - BYTE reg; - struct _XR3_BITREGS { - BYTE DCR0:1; /* XR3[0:0] */ - - BYTE DCR1:1; /* XR3[1:1] */ - - BYTE DCI:1; /* XR3[2:2] */ - - BYTE DCU0:1; /* XR3[3:3] */ - - BYTE DCU1:1; /* XR3[4:4] */ - - BYTE B_off:1; /* XR3[5:5] */ - - BYTE AGB0:1; /* XR3[6:6] */ - - BYTE AGB1:1; /* XR3[7:7] */ - - } bitreg; - } xr3; - - union /* XOP - XR4 Register */ - { - BYTE reg; - struct _XR4_BITREGS { - BYTE C_0:1; /* XR4[0:0] */ - - BYTE C_1:1; /* XR4[1:1] */ - - BYTE C_2:1; /* XR4[2:2] */ - - BYTE C_3:1; /* XR4[3:3] */ - - BYTE C_4:1; /* XR4[4:4] */ - - BYTE C_5:1; /* XR4[5:5] */ - - BYTE C_6:1; /* XR4[6:6] */ - - BYTE C_7:1; /* XR4[7:7] */ - - } bitreg; - } xr4; - - union /* XOP - XR5 Register */ - { - BYTE reg; - struct _XR5_BITREGS { - BYTE T_0:1; /* XR5[0:0] */ - - BYTE T_1:1; /* XR5[1:1] */ - - BYTE T_2:1; /* XR5[2:2] */ - - BYTE T_3:1; /* XR5[3:3] */ - - BYTE T_4:1; /* XR5[4:4] */ - - BYTE T_5:1; /* XR5[5:5] */ - - BYTE T_6:1; /* XR5[6:6] */ - - BYTE T_7:1; /* XR5[7:7] */ - - } bitreg; - } xr5; - - union /* XOP - XR6 Register - Read Values */ - { - BYTE reg; - struct _XR6_BITREGS { - BYTE CPS0:1; /* XR6[0:0] */ - - BYTE CPS1:1; /* XR6[1:1] */ - - BYTE unused1:2; /* XR6[2:3] */ - - BYTE CLK_OFF:1; /* XR6[4:4] */ - - BYTE unused2:3; /* XR6[5:7] */ - - } bitreg; - } xr6; - - union /* XOP - XR7 Register */ - { - BYTE reg; - struct _XR7_BITREGS { - BYTE unused1:1; /* XR7[0:0] */ - - BYTE Vdd0:1; /* XR7[1:1] */ - - BYTE Vdd1:1; /* XR7[2:2] */ - - BYTE unused2:5; /* XR7[3:7] */ - - } bitreg; - } xr7; - } XOP; - - BYTE ByteRegs[sizeof(struct _XOP)]; - - } XOP_REGS; - - /* DAA_REGS.XOP_REGS.XOP.XR7.reg */ - /* DAA_REGS.XOP_REGS.XOP.XR7.bitreg */ - /* DAA_REGS.XOP_REGS.XOP.XR7.bitreg.Vdd0 */ - /* DAA_REGS.XOP_REGS.ByteRegs[7] */ - - /*----------------------------------------------- */ - /* COP Registers */ - /* */ - BYTE byCOP; - - union _COP_REGS { - struct _COP { - BYTE THFilterCoeff_1[8]; /* COP - TH Filter Coefficients, CODE=0, Part 1 */ - - BYTE THFilterCoeff_2[8]; /* COP - TH Filter Coefficients, CODE=1, Part 2 */ - - BYTE THFilterCoeff_3[8]; /* COP - TH Filter Coefficients, CODE=2, Part 3 */ - - BYTE RingerImpendance_1[8]; /* COP - Ringer Impendance Coefficients, CODE=3, Part 1 */ - - BYTE IMFilterCoeff_1[8]; /* COP - IM Filter Coefficients, CODE=4, Part 1 */ - - BYTE IMFilterCoeff_2[8]; /* COP - IM Filter Coefficients, CODE=5, Part 2 */ - - BYTE RingerImpendance_2[8]; /* COP - Ringer Impendance Coefficients, CODE=6, Part 2 */ - - BYTE FRRFilterCoeff[8]; /* COP - FRR Filter Coefficients, CODE=7 */ - - BYTE FRXFilterCoeff[8]; /* COP - FRX Filter Coefficients, CODE=8 */ - - BYTE ARFilterCoeff[4]; /* COP - AR Filter Coefficients, CODE=9 */ - - BYTE AXFilterCoeff[4]; /* COP - AX Filter Coefficients, CODE=10 */ - - BYTE Tone1Coeff[4]; /* COP - Tone1 Coefficients, CODE=11 */ - - BYTE Tone2Coeff[4]; /* COP - Tone2 Coefficients, CODE=12 */ - - BYTE LevelmeteringRinging[4]; /* COP - Levelmetering Ringing, CODE=13 */ - - BYTE CallerID1stTone[8]; /* COP - Caller ID 1st Tone, CODE=14 */ - - BYTE CallerID2ndTone[8]; /* COP - Caller ID 2nd Tone, CODE=15 */ - - } COP; - - BYTE ByteRegs[sizeof(struct _COP)]; - - } COP_REGS; - - /* DAA_REGS.COP_REGS.COP.XR7.Tone1Coeff[3] */ - /* DAA_REGS.COP_REGS.COP.XR7.bitreg */ - /* DAA_REGS.COP_REGS.COP.XR7.bitreg.Vdd0 */ - /* DAA_REGS.COP_REGS.ByteRegs[57] */ - - /*----------------------------------------------- */ - /* CAO Registers */ - /* */ - BYTE byCAO; - - union _CAO_REGS { - struct _CAO { - BYTE CallerID[512]; /* CAO - Caller ID Bytes */ - - } CAO; - - BYTE ByteRegs[sizeof(struct _CAO)]; - } CAO_REGS; - - union /* XOP - XR0 Register - Write values */ - { - BYTE reg; - struct _XR0_BITREGSW { - BYTE SO_0:1; /* XR1[0:0] - Write */ - - BYTE SO_1:1; /* XR1[1:1] - Write */ - - BYTE SO_2:1; /* XR1[2:2] - Write */ - - BYTE unused:5; /* XR1[3:7] - Write */ - - } bitreg; - } XOP_xr0_W; - - union /* XOP - XR6 Register - Write values */ - { - BYTE reg; - struct _XR6_BITREGSW { - BYTE unused1:4; /* XR6[0:3] */ - - BYTE CLK_OFF:1; /* XR6[4:4] */ - - BYTE unused2:3; /* XR6[5:7] */ - - } bitreg; - } XOP_xr6_W; - -} DAA_REGS; - -#define ALISDAA_ID_BYTE 0x81 -#define ALISDAA_CALLERID_SIZE 512 - -/*------------------------------ */ -/* */ -/* Misc definitions */ -/* */ - -/* Power Up Operation */ -#define SOP_PU_SLEEP 0 -#define SOP_PU_RINGING 1 -#define SOP_PU_CONVERSATION 2 -#define SOP_PU_PULSEDIALING 3 -#define SOP_PU_RESET 4 - -#define ALISDAA_CALLERID_SIZE 512 - -#define PLAYBACK_MODE_COMPRESSED 0 /* Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */ -#define PLAYBACK_MODE_TRUESPEECH_V40 0 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */ -#define PLAYBACK_MODE_TRUESPEECH 8 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps Version 5.1 */ -#define PLAYBACK_MODE_ULAW 2 /* Selects: 64 Kbit/sec MuA-law PCM */ -#define PLAYBACK_MODE_ALAW 10 /* Selects: 64 Kbit/sec A-law PCM */ -#define PLAYBACK_MODE_16LINEAR 6 /* Selects: 128 Kbit/sec 16-bit linear */ -#define PLAYBACK_MODE_8LINEAR 4 /* Selects: 64 Kbit/sec 8-bit signed linear */ -#define PLAYBACK_MODE_8LINEAR_WSS 5 /* Selects: 64 Kbit/sec WSS 8-bit unsigned linear */ - -#define RECORD_MODE_COMPRESSED 0 /* Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */ -#define RECORD_MODE_TRUESPEECH 0 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */ -#define RECORD_MODE_ULAW 4 /* Selects: 64 Kbit/sec Mu-law PCM */ -#define RECORD_MODE_ALAW 12 /* Selects: 64 Kbit/sec A-law PCM */ -#define RECORD_MODE_16LINEAR 5 /* Selects: 128 Kbit/sec 16-bit linear */ -#define RECORD_MODE_8LINEAR 6 /* Selects: 64 Kbit/sec 8-bit signed linear */ -#define RECORD_MODE_8LINEAR_WSS 7 /* Selects: 64 Kbit/sec WSS 8-bit unsigned linear */ - -enum SLIC_STATES { - PLD_SLIC_STATE_OC = 0, - PLD_SLIC_STATE_RINGING, - PLD_SLIC_STATE_ACTIVE, - PLD_SLIC_STATE_OHT, - PLD_SLIC_STATE_TIPOPEN, - PLD_SLIC_STATE_STANDBY, - PLD_SLIC_STATE_APR, - PLD_SLIC_STATE_OHTPR -}; - -enum SCI_CONTROL { - SCI_End = 0, - SCI_Enable_DAA, - SCI_Enable_Mixer, - SCI_Enable_EEPROM -}; - -enum Mode { - T63, T53, T48, T40 -}; -enum Dir { - V3_TO_V4, V4_TO_V3, V4_TO_V5, V5_TO_V4 -}; - -typedef struct Proc_Info_Tag { - enum Mode convert_mode; - enum Dir convert_dir; - int Prev_Frame_Type; - int Current_Frame_Type; -} Proc_Info_Type; - -enum PREVAL { - NORMAL = 0, - NOPOST, - POSTONLY, - PREERROR -}; - -enum IXJ_EXTENSIONS { - G729LOADER = 0, - TS85LOADER, - PRE_READ, - POST_READ, - PRE_WRITE, - POST_WRITE, - PRE_IOCTL, - POST_IOCTL -}; - -typedef struct { - char enable; - char en_filter; - unsigned int filter; - unsigned int state; /* State 0 when cadence has not started. */ - - unsigned int on1; /* State 1 */ - - unsigned long on1min; /* State 1 - 10% + jiffies */ - unsigned long on1dot; /* State 1 + jiffies */ - - unsigned long on1max; /* State 1 + 10% + jiffies */ - - unsigned int off1; /* State 2 */ - - unsigned long off1min; - unsigned long off1dot; /* State 2 + jiffies */ - unsigned long off1max; - unsigned int on2; /* State 3 */ - - unsigned long on2min; - unsigned long on2dot; - unsigned long on2max; - unsigned int off2; /* State 4 */ - - unsigned long off2min; - unsigned long off2dot; /* State 4 + jiffies */ - unsigned long off2max; - unsigned int on3; /* State 5 */ - - unsigned long on3min; - unsigned long on3dot; - unsigned long on3max; - unsigned int off3; /* State 6 */ - - unsigned long off3min; - unsigned long off3dot; /* State 6 + jiffies */ - unsigned long off3max; -} IXJ_CADENCE_F; - -typedef struct { - unsigned int busytone:1; - unsigned int dialtone:1; - unsigned int ringback:1; - unsigned int ringing:1; - unsigned int playing:1; - unsigned int recording:1; - unsigned int cringing:1; - unsigned int play_first_frame:1; - unsigned int pstn_present:1; - unsigned int pstn_ringing:1; - unsigned int pots_correct:1; - unsigned int pots_pstn:1; - unsigned int g729_loaded:1; - unsigned int ts85_loaded:1; - unsigned int dtmf_oob:1; /* DTMF Out-Of-Band */ - - unsigned int pcmciascp:1; /* SmartCABLE Present */ - - unsigned int pcmciasct:2; /* SmartCABLE Type */ - - unsigned int pcmciastate:3; /* SmartCABLE Init State */ - - unsigned int inwrite:1; /* Currently writing */ - - unsigned int inread:1; /* Currently reading */ - - unsigned int incheck:1; /* Currently checking the SmartCABLE */ - - unsigned int cidplay:1; /* Currently playing Caller ID */ - - unsigned int cidring:1; /* This is the ring for Caller ID */ - - unsigned int cidsent:1; /* Caller ID has been sent */ - - unsigned int cidcw_ack:1; /* Caller ID CW ACK (from CPE) */ - unsigned int firstring:1; /* First ring cadence is complete */ - unsigned int pstncheck:1; /* Currently checking the PSTN Line */ - unsigned int pstn_rmr:1; - unsigned int x:3; /* unused bits */ - -} IXJ_FLAGS; - -/****************************************************************************** -* -* This structure holds the state of all of the Quicknet cards -* -******************************************************************************/ - -typedef struct { - int elements_used; - IXJ_CADENCE_TERM termination; - IXJ_CADENCE_ELEMENT *ce; -} ixj_cadence; - -typedef struct { - struct phone_device p; - struct timer_list timer; - unsigned int board; - unsigned int DSPbase; - unsigned int XILINXbase; - unsigned int serial; - atomic_t DSPWrite; - struct phone_capability caplist[30]; - unsigned int caps; - struct pnp_dev *dev; - unsigned int cardtype; - unsigned int rec_codec; - unsigned int cid_rec_codec; - unsigned int cid_rec_volume; - unsigned char cid_rec_flag; - signed char rec_mode; - unsigned int play_codec; - unsigned int cid_play_codec; - unsigned int cid_play_volume; - unsigned char cid_play_flag; - signed char play_mode; - IXJ_FLAGS flags; - unsigned long busyflags; - unsigned int rec_frame_size; - unsigned int play_frame_size; - unsigned int cid_play_frame_size; - unsigned int cid_base_frame_size; - unsigned long cidcw_wait; - int aec_level; - int cid_play_aec_level; - int readers, writers; - wait_queue_head_t poll_q; - wait_queue_head_t read_q; - char *read_buffer, *read_buffer_end; - char *read_convert_buffer; - size_t read_buffer_size; - unsigned int read_buffer_ready; - wait_queue_head_t write_q; - char *write_buffer, *write_buffer_end; - char *write_convert_buffer; - size_t write_buffer_size; - unsigned int write_buffers_empty; - unsigned long drybuffer; - char *write_buffer_rp, *write_buffer_wp; - char dtmfbuffer[80]; - char dtmf_current; - int dtmf_wp, dtmf_rp, dtmf_state, dtmf_proc; - int tone_off_time, tone_on_time; - struct fasync_struct *async_queue; - unsigned long tone_start_jif; - char tone_index; - char tone_state; - char maxrings; - ixj_cadence *cadence_t; - ixj_cadence *cadence_r; - int tone_cadence_state; - IXJ_CADENCE_F cadence_f[6]; - DTMF dtmf; - CPTF cptf; - BYTES dsp; - BYTES ver; - BYTES scr; - BYTES ssr; - BYTES baseframe; - HSR hsr; - GPIO gpio; - PLD_SCRR pld_scrr; - PLD_SCRW pld_scrw; - PLD_SLICW pld_slicw; - PLD_SLICR pld_slicr; - PLD_CLOCK pld_clock; - PCMCIA_CR1 pccr1; - PCMCIA_CR2 pccr2; - PCMCIA_SCCR psccr; - PCMCIA_SLIC pslic; - char pscdd; - Si3C1 sic1; - Si3C2 sic2; - Si3RXG sirxg; - Si3ADC siadc; - Si3DAC sidac; - Si3STAT sistat; - Si3AATT siaatt; - MIX mix; - unsigned short ring_cadence; - int ring_cadence_t; - unsigned long ring_cadence_jif; - unsigned long checkwait; - int intercom; - int m_hook; - int r_hook; - int p_hook; - char pstn_envelope; - char pstn_cid_intr; - unsigned char fskz; - unsigned char fskphase; - unsigned char fskcnt; - unsigned int cidsize; - unsigned int cidcnt; - unsigned long pstn_cid_received; - PHONE_CID cid; - PHONE_CID cid_send; - unsigned long pstn_ring_int; - unsigned long pstn_ring_start; - unsigned long pstn_ring_stop; - unsigned long pstn_winkstart; - unsigned long pstn_last_rmr; - unsigned long pstn_prev_rmr; - unsigned long pots_winkstart; - unsigned int winktime; - unsigned long flash_end; - char port; - char hookstate; - union telephony_exception ex; - union telephony_exception ex_sig; - int ixj_signals[35]; - IXJ_SIGDEF sigdef; - char daa_mode; - char daa_country; - unsigned long pstn_sleeptil; - DAA_REGS m_DAAShadowRegs; - Proc_Info_Type Info_read; - Proc_Info_Type Info_write; - unsigned short frame_count; - unsigned int filter_hist[4]; - unsigned char filter_en[6]; - unsigned short proc_load; - unsigned long framesread; - unsigned long frameswritten; - unsigned long read_wait; - unsigned long write_wait; - unsigned long timerchecks; - unsigned long txreadycheck; - unsigned long rxreadycheck; - unsigned long statuswait; - unsigned long statuswaitfail; - unsigned long pcontrolwait; - unsigned long pcontrolwaitfail; - unsigned long iscontrolready; - unsigned long iscontrolreadyfail; - unsigned long pstnstatecheck; -#ifdef IXJ_DYN_ALLOC - short *fskdata; -#else - short fskdata[8000]; -#endif - int fsksize; - int fskdcnt; -} IXJ; - -typedef int (*IXJ_REGFUNC) (IXJ * j, unsigned long arg); - -extern IXJ *ixj_pcmcia_probe(unsigned long, unsigned long); - diff --git a/drivers/staging/telephony/ixj_pcmcia.c b/drivers/staging/telephony/ixj_pcmcia.c deleted file mode 100644 index 05032e2cc95..00000000000 --- a/drivers/staging/telephony/ixj_pcmcia.c +++ /dev/null @@ -1,187 +0,0 @@ -#include "ixj-ver.h" - -#include - -#include -#include /* printk() */ -#include /* everything... */ -#include /* error codes */ -#include - -#include -#include - -#include "ixj.h" - -/* - * PCMCIA service support for Quicknet cards - */ - - -typedef struct ixj_info_t { - int ndev; - struct ixj *port; -} ixj_info_t; - -static void ixj_detach(struct pcmcia_device *p_dev); -static int ixj_config(struct pcmcia_device * link); -static void ixj_cs_release(struct pcmcia_device * link); - -static int ixj_probe(struct pcmcia_device *p_dev) -{ - dev_dbg(&p_dev->dev, "ixj_attach()\n"); - /* Create new ixj device */ - p_dev->priv = kzalloc(sizeof(struct ixj_info_t), GFP_KERNEL); - if (!p_dev->priv) { - return -ENOMEM; - } - - return ixj_config(p_dev); -} - -static void ixj_detach(struct pcmcia_device *link) -{ - dev_dbg(&link->dev, "ixj_detach\n"); - - ixj_cs_release(link); - - kfree(link->priv); -} - -static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) -{ - char *str; - int i, place; - dev_dbg(&link->dev, "ixj_get_serial\n"); - - str = link->prod_id[0]; - if (!str) - goto failed; - printk("%s", str); - str = link->prod_id[1]; - if (!str) - goto failed; - printk(" %s", str); - str = link->prod_id[2]; - if (!str) - goto failed; - place = 1; - for (i = strlen(str) - 1; i >= 0; i--) { - switch (str[i]) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - j->serial += (str[i] - 48) * place; - break; - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - j->serial += (str[i] - 55) * place; - break; - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - j->serial += (str[i] - 87) * place; - break; - } - place = place * 0x10; - } - str = link->prod_id[3]; - if (!str) - goto failed; - printk(" version %s\n", str); -failed: - return; -} - -static int ixj_config_check(struct pcmcia_device *p_dev, void *priv_data) -{ - p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; - p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; - p_dev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH; - p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; - p_dev->io_lines = 3; - - return pcmcia_request_io(p_dev); -} - -static int ixj_config(struct pcmcia_device * link) -{ - IXJ *j; - ixj_info_t *info; - - info = link->priv; - dev_dbg(&link->dev, "ixj_config\n"); - - link->config_flags = CONF_AUTO_SET_IO; - - if (pcmcia_loop_config(link, ixj_config_check, NULL)) - goto failed; - - if (pcmcia_enable_device(link)) - goto failed; - - /* - * Register the card with the core. - */ - j = ixj_pcmcia_probe(link->resource[0]->start, - link->resource[0]->start + 0x10); - - info->ndev = 1; - ixj_get_serial(link, j); - return 0; - -failed: - ixj_cs_release(link); - return -ENODEV; -} - -static void ixj_cs_release(struct pcmcia_device *link) -{ - ixj_info_t *info = link->priv; - dev_dbg(&link->dev, "ixj_cs_release\n"); - info->ndev = 0; - pcmcia_disable_device(link); -} - -static const struct pcmcia_device_id ixj_ids[] = { - PCMCIA_DEVICE_MANF_CARD(0x0257, 0x0600), - PCMCIA_DEVICE_NULL -}; -MODULE_DEVICE_TABLE(pcmcia, ixj_ids); - -static struct pcmcia_driver ixj_driver = { - .owner = THIS_MODULE, - .name = "ixj_cs", - .probe = ixj_probe, - .remove = ixj_detach, - .id_table = ixj_ids, -}; - -static int __init ixj_pcmcia_init(void) -{ - return pcmcia_register_driver(&ixj_driver); -} - -static void ixj_pcmcia_exit(void) -{ - pcmcia_unregister_driver(&ixj_driver); -} - -module_init(ixj_pcmcia_init); -module_exit(ixj_pcmcia_exit); - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/telephony/phonedev.c b/drivers/staging/telephony/phonedev.c deleted file mode 100644 index 1dd0b6717cc..00000000000 --- a/drivers/staging/telephony/phonedev.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Telephony registration for Linux - * - * (c) Copyright 1999 Red Hat Software Inc. - * - * 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. - * - * Author: Alan Cox, - * - * Fixes: Mar 01 2000 Thomas Sparr, - * phone_register_device now works with unit!=PHONE_UNIT_ANY - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define PHONE_NUM_DEVICES 256 - -/* - * Active devices - */ - -static struct phone_device *phone_device[PHONE_NUM_DEVICES]; -static DEFINE_MUTEX(phone_lock); - -/* - * Open a phone device. - */ - -static int phone_open(struct inode *inode, struct file *file) -{ - unsigned int minor = iminor(inode); - int err = 0; - struct phone_device *p; - const struct file_operations *old_fops, *new_fops = NULL; - - if (minor >= PHONE_NUM_DEVICES) - return -ENODEV; - - mutex_lock(&phone_lock); - p = phone_device[minor]; - if (p) - new_fops = fops_get(p->f_op); - if (!new_fops) { - mutex_unlock(&phone_lock); - request_module("char-major-%d-%d", PHONE_MAJOR, minor); - mutex_lock(&phone_lock); - p = phone_device[minor]; - if (p == NULL || (new_fops = fops_get(p->f_op)) == NULL) - { - err=-ENODEV; - goto end; - } - } - old_fops = file->f_op; - file->f_op = new_fops; - if (p->open) - err = p->open(p, file); /* Tell the device it is open */ - if (err) { - fops_put(file->f_op); - file->f_op = fops_get(old_fops); - } - fops_put(old_fops); -end: - mutex_unlock(&phone_lock); - return err; -} - -/* - * Telephony For Linux device drivers request registration here. - */ - -int phone_register_device(struct phone_device *p, int unit) -{ - int base; - int end; - int i; - - base = 0; - end = PHONE_NUM_DEVICES - 1; - - if (unit != PHONE_UNIT_ANY) { - base = unit; - end = unit + 1; /* enter the loop at least one time */ - } - - mutex_lock(&phone_lock); - for (i = base; i < end; i++) { - if (phone_device[i] == NULL) { - phone_device[i] = p; - p->minor = i; - mutex_unlock(&phone_lock); - return 0; - } - } - mutex_unlock(&phone_lock); - return -ENFILE; -} - -/* - * Unregister an unused Telephony for linux device - */ - -void phone_unregister_device(struct phone_device *pfd) -{ - mutex_lock(&phone_lock); - if (likely(phone_device[pfd->minor] == pfd)) - phone_device[pfd->minor] = NULL; - mutex_unlock(&phone_lock); -} - - -static const struct file_operations phone_fops = -{ - .owner = THIS_MODULE, - .open = phone_open, - .llseek = noop_llseek, -}; - -/* - * Board init functions - */ - - -/* - * Initialise Telephony for linux - */ - -static int __init telephony_init(void) -{ - printk(KERN_INFO "Linux telephony interface: v1.00\n"); - if (register_chrdev(PHONE_MAJOR, "telephony", &phone_fops)) { - printk("phonedev: unable to get major %d\n", PHONE_MAJOR); - return -EIO; - } - - return 0; -} - -static void __exit telephony_exit(void) -{ - unregister_chrdev(PHONE_MAJOR, "telephony"); -} - -module_init(telephony_init); -module_exit(telephony_exit); - -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(phone_register_device); -EXPORT_SYMBOL(phone_unregister_device); -- cgit v1.2.3 From 7a4cae7aabe55e4d5abb8ba1ee2b78a9857c4507 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Fri, 26 Oct 2012 18:00:22 -0400 Subject: staging: csr: remove unused macros/ prototypes in csr_sched.h there are macros and functions that are not used, or their function is missing, so remove them. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_sched.h | 114 ---------------------------------------- 1 file changed, 114 deletions(-) diff --git a/drivers/staging/csr/csr_sched.h b/drivers/staging/csr/csr_sched.h index dc67a4a0855..1e2da0f26ea 100644 --- a/drivers/staging/csr/csr_sched.h +++ b/drivers/staging/csr/csr_sched.h @@ -24,7 +24,6 @@ typedef u16 CsrSchedTaskId; /* A queue identifier */ typedef u16 CsrSchedQid; -#define CSR_SCHED_QID_INVALID ((CsrSchedQid) 0xFFFF) /* A message identifier */ typedef CsrSchedIdentifier CsrSchedMsgId; @@ -33,9 +32,6 @@ typedef CsrSchedIdentifier CsrSchedMsgId; typedef CsrSchedIdentifier CsrSchedTid; #define CSR_SCHED_TID_INVALID ((CsrSchedTid) 0) -/* Scheduler entry functions share this structure */ -typedef void (*schedEntryFunction_t)(void **inst); - /* Time constants. */ #define CSR_SCHED_TIME_MAX (0xFFFFFFFF) #define CSR_SCHED_MILLISECOND (1000) @@ -53,8 +49,6 @@ typedef void (*schedEntryFunction_t)(void **inst); typedef u16 CsrSchedBgint; #define CSR_SCHED_BGINT_INVALID ((CsrSchedBgint) 0xFFFF) -typedef void (*CsrSchedBgintHandler)(void *); - /*----------------------------------------------------------------------------* * NAME * CsrSchedMessagePut @@ -92,114 +86,6 @@ void CsrSchedMessagePut(CsrSchedQid q, void *mv); #endif -/*----------------------------------------------------------------------------* - * NAME - * CsrSchedMessageBroadcast - * - * DESCRIPTION - * Sends a message to all tasks. - * - * The user must supply a "factory function" that is called once - * for every task that exists. The "factory function", msg_build_func, - * must allocate and initialise the message and set the msg_build_ptr - * to point to the message when done. - * - * NOTE - * N/A - * - * RETURNS - * void - * - *----------------------------------------------------------------------------*/ -#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER) -void CsrSchedMessageBroadcastStringLog(u16 mi, - void *(*msg_build_func)(void *), - void *msg_build_ptr, - u32 line, - const char *file); -#define CsrSchedMessageBroadcast(mi, fn, ptr) CsrSchedMessageBroadcastStringLog((mi), (fn), (ptr), __LINE__, __FILE__) -#else -void CsrSchedMessageBroadcast(u16 mi, - void *(*msg_build_func)(void *), - void *msg_build_ptr); -#endif - -/*----------------------------------------------------------------------------* - * NAME - * CsrSchedTimerSet - * - * DESCRIPTION - * Causes the void function "fn" to be called with the arguments - * "fniarg" and "fnvarg" after "delay" has elapsed. - * - * "delay" must be less than half the range of a CsrTime. - * - * CsrSchedTimerSet() does nothing with "fniarg" and "fnvarg" except - * deliver them via a call to "fn()". (Unless CsrSchedTimerCancel() - * is used to prevent delivery.) - * - * NOTE - * The function will be called at or after "delay"; the actual delay will - * depend on the timing behaviour of the scheduler's tasks. - * - * RETURNS - * CsrSchedTid - A timed event identifier, can be used in CsrSchedTimerCancel(). - * - *----------------------------------------------------------------------------*/ -#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER) -CsrSchedTid CsrSchedTimerSetStringLog(u32 delay, - void (*fn)(u16 mi, void *mv), - u16 fniarg, - void *fnvarg, - u32 line, - const char *file); -#define CsrSchedTimerSet(d, fn, fni, fnv) CsrSchedTimerSetStringLog((d), (fn), (fni), (fnv), __LINE__, __FILE__) -#else -CsrSchedTid CsrSchedTimerSet(u32 delay, - void (*fn)(u16 mi, void *mv), - u16 fniarg, - void *fnvarg); -#endif - -/*----------------------------------------------------------------------------* - * NAME - * CsrSchedTimerCancel - * - * DESCRIPTION - * Attempts to prevent the timed event with identifier "eventid" from - * occurring. - * - * RETURNS - * u8 - TRUE if cancelled, FALSE if the event has already occurred. - * - *----------------------------------------------------------------------------*/ -#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER) -u8 CsrSchedTimerCancelStringLog(CsrSchedTid eventid, - u16 *pmi, - void **pmv, - u32 line, - const char *file); -#define CsrSchedTimerCancel(e, pmi, pmv) CsrSchedTimerCancelStringLog((e), (pmi), (pmv), __LINE__, __FILE__) -#else -u8 CsrSchedTimerCancel(CsrSchedTid eventid, - u16 *pmi, - void **pmv); -#endif - -/*----------------------------------------------------------------------------* - * NAME - * CsrSchedTaskQueueGet - * - * DESCRIPTION - * Return the queue identifier for the currently running queue - * - * RETURNS - * CsrSchedQid - The current task queue identifier, or 0xFFFF if not available. - * - *----------------------------------------------------------------------------*/ -CsrSchedQid CsrSchedTaskQueueGet(void); - - #ifdef __cplusplus } #endif -- cgit v1.2.3 From 1481c5f1083ac11f83beb75bfa8eb3ae44b4dbc3 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Fri, 26 Oct 2012 18:01:11 -0400 Subject: staging: csr: remove unused macros and prototypes this file includes prototypes that doesnt have a function for them, and some macros which are never used, remove them instead Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_vif_utils.h | 73 -------------------------------- 1 file changed, 73 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_vif_utils.h b/drivers/staging/csr/csr_wifi_vif_utils.h index 523172d1ac9..042f93ee162 100644 --- a/drivers/staging/csr/csr_wifi_vif_utils.h +++ b/drivers/staging/csr/csr_wifi_vif_utils.h @@ -27,79 +27,6 @@ extern "C" { #define CSR_WIFI_NUM_INTERFACES (u8)0x1 #define CSR_WIFI_INTERFACE_IN_USE (u16)0x0 -/* This is used at places where interface Id isn't available*/ -#define CSR_WIFI_INTERFACE_ZERO 0 -#define CSR_WIFI_INTERFACE_STA 0 -#define CSR_WIFI_INTERFACE_AMP 0 - - -#define CSR_WIFI_VIF_UTILS_UNDEFINED_TAG 0xFFFF - -/* Extract the Interface Id from the event */ -#define CsrWifiVifUtilsGetVifTagFromEvent(msg) \ - ((u16) * ((u16 *) ((u8 *) (msg) + sizeof(CsrWifiFsmEvent)))) - -/* The HPI Vif combines the type and the interface id */ -#define CsrWifiVifUtilsGetVifTagFromHipEvent(msg) \ - ((msg)->virtualInterfaceIdentifier & 0x00FF) - -#define CsrWifiVifUtilsPackHipEventVif(type, interfaceId) \ - ((u16)((interfaceId) | ((type) << 8))) - - -/* TYPES DEFINITIONS ********************************************************/ - -/* GLOBAL VARIABLE DECLARATIONS *********************************************/ - -/* PUBLIC FUNCTION PROTOTYPES ***********************************************/ - -/** - * @brief - * First checks if the mode is supported capability bitmap of the interface. - * If this succeeds, then checks if running this mode on this interface is allowed. - * - * @param[in] u8 : interface capability bitmap - * @param[in] u8* : pointer to the array of current interface modes - * @param[in] u16 : interfaceTag - * @param[in] CsrWifiInterfaceMode : mode - * - * @return - * u8 : returns true if the interface is allowed to operate in the mode otherwise false. - */ -extern u8 CsrWifiVifUtilsCheckCompatibility(u8 interfaceCapability, - u8 *currentInterfaceModes, - u16 interfaceTag, - CsrWifiInterfaceMode mode); - -/** - * @brief - * Checks if the specified interface is supported. - * NOTE: Only checks that the interface is supported, no checks are made to - * determine whether a supported interface may be made active. - * - * @param[in] u16 : interfaceTag - * - * @return - * u8 : returns true if the interface is supported, otherwise false. - */ -extern u8 CsrWifiVifUtilsIsSupported(u16 interfaceTag); - -#ifdef CSR_LOG_ENABLE -/** - * @brief - * Registers the virtual interface utils logging details. - * Should only be called once at initialisation. - * - * @param[in/out] None - * - * @return - * None - */ -void CsrWifiVifUtilsLogTextRegister(void); -#else -#define CsrWifiVifUtilsLogTextRegister() -#endif - #ifdef __cplusplus } #endif -- cgit v1.2.3 From 1bbffe726e00f1f79ba1b8cf0cbd78223c995c0f Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sat, 27 Oct 2012 07:25:53 +0900 Subject: staging:comedi: Use pr_ or dev_ printks in drivers/usbduxfaxt.c fixed below checkpatch warnings. -WARNING: printk() should include KERN_ facility level Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 060d853dc65..b4e987b892a 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -370,9 +370,8 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) return; default: - printk("comedi%d: usbduxfast: non-zero urb status received in " - "ai intr context: %d\n", - udfs->comedidev->minor, urb->status); + pr_err("non-zero urb status received in ai intr context: %d\n", + urb->status); s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_ERROR; comedi_event(udfs->comedidev, s); @@ -454,7 +453,8 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs) 1, /* Length */ EZTIMEOUT); /* Timeout */ if (ret < 0) { - printk("comedi_: usbduxfast_: control msg failed (start)\n"); + dev_err(&udfs->interface->dev, + "control msg failed (start)\n"); return ret; } -- cgit v1.2.3 From 31370f7e57b5a9f95457fb583354474f7e39fa3e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 26 Oct 2012 16:29:09 -0700 Subject: Staging: csr: remove __cplusplus nonsense from the .h files In the kernel, we use C. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext.h | 8 --- drivers/staging/csr/csr_framework_ext_types.h | 9 --- drivers/staging/csr/csr_lib.h | 8 --- drivers/staging/csr/csr_log.h | 8 --- drivers/staging/csr/csr_log_configure.h | 8 --- drivers/staging/csr/csr_log_text.h | 8 --- drivers/staging/csr/csr_macro.h | 8 --- drivers/staging/csr/csr_msg_transport.h | 8 --- drivers/staging/csr/csr_msgconv.h | 9 --- drivers/staging/csr/csr_prim_defs.h | 7 --- drivers/staging/csr/csr_result.h | 8 --- drivers/staging/csr/csr_sched.h | 8 --- drivers/staging/csr/csr_sdio.h | 8 --- drivers/staging/csr/csr_time.h | 8 --- drivers/staging/csr/csr_wifi_common.h | 8 --- drivers/staging/csr/csr_wifi_fsm.h | 8 --- drivers/staging/csr/csr_wifi_fsm_event.h | 8 --- drivers/staging/csr/csr_wifi_fsm_types.h | 9 --- drivers/staging/csr/csr_wifi_hip_card.h | 9 --- drivers/staging/csr/csr_wifi_hip_card_sdio.h | 8 --- drivers/staging/csr/csr_wifi_hip_chiphelper.h | 64 ---------------------- .../staging/csr/csr_wifi_hip_chiphelper_private.h | 8 --- drivers/staging/csr/csr_wifi_hip_conversions.h | 8 --- drivers/staging/csr/csr_wifi_hip_signals.h | 9 --- drivers/staging/csr/csr_wifi_hip_sigs.h | 8 --- drivers/staging/csr/csr_wifi_hip_ta_sampling.h | 9 --- drivers/staging/csr/csr_wifi_hip_unifi.h | 8 --- drivers/staging/csr/csr_wifi_hip_unifi_udi.h | 9 --- drivers/staging/csr/csr_wifi_hip_unifihw.h | 8 --- drivers/staging/csr/csr_wifi_hip_unifiversion.h | 8 --- drivers/staging/csr/csr_wifi_hip_xbv.h | 8 --- drivers/staging/csr/csr_wifi_hostio_prim.h | 9 --- drivers/staging/csr/csr_wifi_lib.h | 9 --- drivers/staging/csr/csr_wifi_msgconv.h | 9 --- .../staging/csr/csr_wifi_nme_ap_converter_init.h | 8 --- drivers/staging/csr/csr_wifi_nme_ap_lib.h | 10 ---- drivers/staging/csr/csr_wifi_nme_ap_prim.h | 9 --- drivers/staging/csr/csr_wifi_nme_ap_sef.h | 10 ---- drivers/staging/csr/csr_wifi_nme_ap_serialize.h | 9 --- drivers/staging/csr/csr_wifi_nme_converter_init.h | 8 --- drivers/staging/csr/csr_wifi_nme_lib.h | 9 --- drivers/staging/csr/csr_wifi_nme_prim.h | 9 --- drivers/staging/csr/csr_wifi_nme_serialize.h | 8 --- drivers/staging/csr/csr_wifi_nme_task.h | 8 --- drivers/staging/csr/csr_wifi_private_common.h | 8 --- drivers/staging/csr/csr_wifi_result.h | 8 --- .../staging/csr/csr_wifi_router_converter_init.h | 8 --- .../csr/csr_wifi_router_ctrl_converter_init.h | 8 --- drivers/staging/csr/csr_wifi_router_ctrl_lib.h | 10 ---- drivers/staging/csr/csr_wifi_router_ctrl_prim.h | 9 --- drivers/staging/csr/csr_wifi_router_ctrl_sef.h | 7 --- .../staging/csr/csr_wifi_router_ctrl_serialize.h | 8 --- drivers/staging/csr/csr_wifi_router_lib.h | 10 ---- drivers/staging/csr/csr_wifi_router_prim.h | 9 --- drivers/staging/csr/csr_wifi_router_sef.h | 8 --- drivers/staging/csr/csr_wifi_router_serialize.h | 8 --- drivers/staging/csr/csr_wifi_router_task.h | 8 --- drivers/staging/csr/csr_wifi_sme_ap_lib.h | 9 --- drivers/staging/csr/csr_wifi_sme_ap_prim.h | 8 --- drivers/staging/csr/csr_wifi_sme_converter_init.h | 8 --- drivers/staging/csr/csr_wifi_sme_lib.h | 10 ---- drivers/staging/csr/csr_wifi_sme_prim.h | 9 --- drivers/staging/csr/csr_wifi_sme_sef.h | 9 --- drivers/staging/csr/csr_wifi_sme_serialize.h | 8 --- drivers/staging/csr/csr_wifi_sme_task.h | 8 --- drivers/staging/csr/csr_wifi_vif_utils.h | 8 --- 66 files changed, 611 deletions(-) diff --git a/drivers/staging/csr/csr_framework_ext.h b/drivers/staging/csr/csr_framework_ext.h index 50e5f45e52b..e8ae490c09d 100644 --- a/drivers/staging/csr/csr_framework_ext.h +++ b/drivers/staging/csr/csr_framework_ext.h @@ -13,10 +13,6 @@ #include "csr_result.h" #include "csr_framework_ext_types.h" -#ifdef __cplusplus -extern "C" { -#endif - /* Result codes */ #define CSR_FE_RESULT_NO_MORE_EVENTS ((CsrResult) 0x0001) #define CSR_FE_RESULT_INVALID_POINTER ((CsrResult) 0x0002) @@ -36,8 +32,4 @@ extern "C" { void CsrThreadSleep(u16 sleepTimeInMs); -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_framework_ext_types.h b/drivers/staging/csr/csr_framework_ext_types.h index cd1f8771922..627556a04ea 100644 --- a/drivers/staging/csr/csr_framework_ext_types.h +++ b/drivers/staging/csr/csr_framework_ext_types.h @@ -17,11 +17,6 @@ #include #endif -#ifdef __cplusplus -extern "C" { -#endif - - #ifdef __KERNEL__ struct CsrEvent { @@ -46,8 +41,4 @@ typedef pthread_mutex_t CsrMutexHandle; #endif /* __KERNEL__ */ -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_lib.h b/drivers/staging/csr/csr_lib.h index b1a57d5d06f..d661fc4baff 100644 --- a/drivers/staging/csr/csr_lib.h +++ b/drivers/staging/csr/csr_lib.h @@ -12,10 +12,6 @@ #include "csr_prim_defs.h" -#ifdef __cplusplus -extern "C" { -#endif - typedef struct { CsrPrim type; @@ -181,8 +177,4 @@ typedef struct *----------------------------------------------------------------------------*/ CsrEventCsrUint32CsrCharString *CsrEventCsrUint32CsrCharString_struct(u16 primtype, u16 msgtype, u32 value1, char *value2); -#ifdef __cplusplus -} -#endif - #endif /* CSR_LIB_H__ */ diff --git a/drivers/staging/csr/csr_log.h b/drivers/staging/csr/csr_log.h index 9eb8c098845..5de5650767d 100644 --- a/drivers/staging/csr/csr_log.h +++ b/drivers/staging/csr/csr_log.h @@ -14,10 +14,6 @@ #include "csr_prim_defs.h" #include "csr_msgconv.h" -#ifdef __cplusplus -extern "C" { -#endif - /* * Log filtering */ @@ -224,8 +220,4 @@ void CsrLogExceptionWarning(u16 prim_type, u32 line, const char *file); -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_log_configure.h b/drivers/staging/csr/csr_log_configure.h index 08fc0807cb7..31c3361fc67 100644 --- a/drivers/staging/csr/csr_log_configure.h +++ b/drivers/staging/csr/csr_log_configure.h @@ -12,10 +12,6 @@ #include "csr_log.h" -#ifdef __cplusplus -extern "C" { -#endif - /*---------------------------------*/ /* Log init/deinit */ /*---------------------------------*/ @@ -127,8 +123,4 @@ void CsrLogLevelTextSet(const char *originName, const char *subOriginName, CsrLogLevelText warningLevelMask); -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_log_text.h b/drivers/staging/csr/csr_log_text.h index 9fe6c90244c..cfcf64aa622 100644 --- a/drivers/staging/csr/csr_log_text.h +++ b/drivers/staging/csr/csr_log_text.h @@ -12,10 +12,6 @@ #include "csr_log_configure.h" -#ifdef __cplusplus -extern "C" { -#endif - typedef struct CsrLogSubOrigin { u16 subOriginNumber; /* Id of the given SubOrigin */ @@ -125,8 +121,4 @@ void CsrLogTextBufferDebug(CsrLogTextTaskId taskId, u16 subOrigin, size_t buffer #define CSR_LOG_TEXT_UNHANDLED_PRIMITIVE(origin, suborigin, primClass, primType) #endif -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_macro.h b/drivers/staging/csr/csr_macro.h index 57cbfcb0619..3dcb2bd9275 100644 --- a/drivers/staging/csr/csr_macro.h +++ b/drivers/staging/csr/csr_macro.h @@ -12,10 +12,6 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - #define FALSE (0) #define TRUE (1) @@ -107,8 +103,4 @@ extern "C" { #define CSR_TOLOWER(character) (((character) >= 'A') && ((character) <= 'Z') ? ((character) + 0x20) : (character)) #define CSR_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_msg_transport.h b/drivers/staging/csr/csr_msg_transport.h index b0095b02381..8d88e783656 100644 --- a/drivers/staging/csr/csr_msg_transport.h +++ b/drivers/staging/csr/csr_msg_transport.h @@ -10,16 +10,8 @@ *****************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CsrMsgTransport #define CsrMsgTransport CsrSchedMessagePut #endif -#ifdef __cplusplus -} -#endif - #endif /* CSR_MSG_TRANSPORT */ diff --git a/drivers/staging/csr/csr_msgconv.h b/drivers/staging/csr/csr_msgconv.h index 09489f38e52..7e4dd388ae3 100644 --- a/drivers/staging/csr/csr_msgconv.h +++ b/drivers/staging/csr/csr_msgconv.h @@ -15,10 +15,6 @@ #include "csr_prim_defs.h" #include "csr_sched.h" -#ifdef __cplusplus -extern "C" { -#endif - typedef size_t (CsrMsgSizeofFunc)(void *msg); typedef u8 *(CsrMsgSerializeFunc)(u8 *buffer, size_t *length, void *msg); typedef void (CsrMsgFreeFunc)(void *msg); @@ -79,9 +75,4 @@ void CsrUint32Des(u32 *value, u8 *buffer, size_t *offset); void CsrMemCpyDes(void *value, u8 *buffer, size_t *offset, size_t length); void CsrCharStringDes(char **value, u8 *buffer, size_t *offset); - -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_prim_defs.h b/drivers/staging/csr/csr_prim_defs.h index 6a7f73dbb70..81a1eaac30d 100644 --- a/drivers/staging/csr/csr_prim_defs.h +++ b/drivers/staging/csr/csr_prim_defs.h @@ -9,9 +9,6 @@ on the license terms. *****************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif /************************************************************************************ * Segmentation of primitives in upstream and downstream segment @@ -55,8 +52,4 @@ typedef u16 CsrPrim; #define CSR_ENV_PRIM ((u16) (0x00FF | CSR_SYNERGY_EVENT_CLASS_MISC_BASE)) -#ifdef __cplusplus -} -#endif - #endif /* CSR_PRIM_DEFS_H__ */ diff --git a/drivers/staging/csr/csr_result.h b/drivers/staging/csr/csr_result.h index c7c36d6b59e..cbb607d943c 100644 --- a/drivers/staging/csr/csr_result.h +++ b/drivers/staging/csr/csr_result.h @@ -10,16 +10,8 @@ *****************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - typedef u16 CsrResult; #define CSR_RESULT_SUCCESS ((CsrResult) 0x0000) #define CSR_RESULT_FAILURE ((CsrResult) 0xFFFF) -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_sched.h b/drivers/staging/csr/csr_sched.h index 1e2da0f26ea..c7d672c59f5 100644 --- a/drivers/staging/csr/csr_sched.h +++ b/drivers/staging/csr/csr_sched.h @@ -12,10 +12,6 @@ #include #include "csr_time.h" -#ifdef __cplusplus -extern "C" { -#endif - /* An identifier issued by the scheduler. */ typedef u32 CsrSchedIdentifier; @@ -86,8 +82,4 @@ void CsrSchedMessagePut(CsrSchedQid q, void *mv); #endif -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_sdio.h b/drivers/staging/csr/csr_sdio.h index f0cda84f6a0..624a53fa1d7 100644 --- a/drivers/staging/csr/csr_sdio.h +++ b/drivers/staging/csr/csr_sdio.h @@ -12,10 +12,6 @@ #include "csr_result.h" -#ifdef __cplusplus -extern "C" { -#endif - /* Result Codes */ #define CSR_SDIO_RESULT_INVALID_VALUE ((CsrResult) 1) /* Invalid argument value */ #define CSR_SDIO_RESULT_NO_DEVICE ((CsrResult) 2) /* The specified device is no longer present */ @@ -724,8 +720,4 @@ CsrResult CsrSdioHardReset(CsrSdioFunction *function); void CsrSdioFunctionActive(CsrSdioFunction *function); void CsrSdioFunctionIdle(CsrSdioFunction *function); -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_time.h b/drivers/staging/csr/csr_time.h index 5a1d859866e..fc29e8e5e47 100644 --- a/drivers/staging/csr/csr_time.h +++ b/drivers/staging/csr/csr_time.h @@ -12,10 +12,6 @@ on the license terms. #include -#ifdef __cplusplus -extern "C" { -#endif - /******************************************************************************* NAME @@ -77,8 +73,4 @@ u32 CsrTimeGet(u32 *high); *----------------------------------------------------------------------------*/ #define CsrTimeSub(t1, t2) ((s32) (t1) - (s32) (t2)) -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_wifi_common.h b/drivers/staging/csr/csr_wifi_common.h index cc41a94b8f2..efc43a525a3 100644 --- a/drivers/staging/csr/csr_wifi_common.h +++ b/drivers/staging/csr/csr_wifi_common.h @@ -14,10 +14,6 @@ #include #include "csr_result.h" -#ifdef __cplusplus -extern "C" { -#endif - /* MAC address */ typedef struct { @@ -101,9 +97,5 @@ typedef struct #define CSR_WIFI_VERSION "5.1.0.0" -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_wifi_fsm.h b/drivers/staging/csr/csr_wifi_fsm.h index 073e2f8b553..fde1508c1ea 100644 --- a/drivers/staging/csr/csr_wifi_fsm.h +++ b/drivers/staging/csr/csr_wifi_fsm.h @@ -11,10 +11,6 @@ #ifndef CSR_WIFI_FSM_H #define CSR_WIFI_FSM_H -#ifdef __cplusplus -extern "C" { -#endif - #include "csr_prim_defs.h" #include "csr_log_text.h" #include "csr_wifi_fsm_event.h" @@ -240,9 +236,5 @@ extern u8 CsrWifiFsmHasEvents(CsrWifiFsmContext *context); */ extern void CsrWifiFsmInstallWakeupCallback(CsrWifiFsmContext *context, CsrWifiFsmExternalWakupCallbackPtr callback); -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_FSM_H */ diff --git a/drivers/staging/csr/csr_wifi_fsm_event.h b/drivers/staging/csr/csr_wifi_fsm_event.h index 57a5cafd40b..0690ca955ef 100644 --- a/drivers/staging/csr/csr_wifi_fsm_event.h +++ b/drivers/staging/csr/csr_wifi_fsm_event.h @@ -11,10 +11,6 @@ #ifndef CSR_WIFI_FSM_EVENT_H #define CSR_WIFI_FSM_EVENT_H -#ifdef __cplusplus -extern "C" { -#endif - #include "csr_prim_defs.h" #include "csr_sched.h" @@ -42,9 +38,5 @@ typedef struct CsrWifiFsmEvent struct CsrWifiFsmEvent *next; } CsrWifiFsmEvent; -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_FSM_EVENT_H */ diff --git a/drivers/staging/csr/csr_wifi_fsm_types.h b/drivers/staging/csr/csr_wifi_fsm_types.h index 90ef77e0783..d21c60a81fc 100644 --- a/drivers/staging/csr/csr_wifi_fsm_types.h +++ b/drivers/staging/csr/csr_wifi_fsm_types.h @@ -11,10 +11,6 @@ #ifndef CSR_WIFI_FSM_TYPES_H #define CSR_WIFI_FSM_TYPES_H -#ifdef __cplusplus -extern "C" { -#endif - #include #include "csr_macro.h" #include "csr_sched.h" @@ -431,9 +427,4 @@ struct CsrWifiFsmContext #endif }; - -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_FSM_TYPES_H */ diff --git a/drivers/staging/csr/csr_wifi_hip_card.h b/drivers/staging/csr/csr_wifi_hip_card.h index 9caf88c7887..bd47f606e0d 100644 --- a/drivers/staging/csr/csr_wifi_hip_card.h +++ b/drivers/staging/csr/csr_wifi_hip_card.h @@ -21,10 +21,6 @@ #ifndef __CARD_H__ #define __CARD_H__ -#ifdef __cplusplus -extern "C" { -#endif - #include "csr_wifi_hip_card_sdio.h" #include "csr_wifi_hip_signals.h" #include "csr_wifi_hip_unifi_udi.h" @@ -115,9 +111,4 @@ void unifi_debug_string_to_buf(const char *str); void unifi_debug_hex_to_buf(const char *buff, u16 length); #endif - -#ifdef __cplusplus -} -#endif - #endif /* __CARD_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio.h b/drivers/staging/csr/csr_wifi_hip_card_sdio.h index dc2ed70f7ed..a9b9ec42732 100644 --- a/drivers/staging/csr/csr_wifi_hip_card_sdio.h +++ b/drivers/staging/csr/csr_wifi_hip_card_sdio.h @@ -20,10 +20,6 @@ #ifndef __CARD_SDIO_H__ #define __CARD_SDIO_H__ -#ifdef __cplusplus -extern "C" { -#endif - #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_unifi_udi.h" #include "csr_wifi_hip_unifihw.h" @@ -695,8 +691,4 @@ CsrResult prealloc_netdata_alloc(card_t *card); void dump(void *mem, u16 len); void dump16(void *mem, u16 len); -#ifdef __cplusplus -} -#endif - #endif /* __CARD_SDIO_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_chiphelper.h b/drivers/staging/csr/csr_wifi_hip_chiphelper.h index 24737ae8a2d..b6b67ee11db 100644 --- a/drivers/staging/csr/csr_wifi_hip_chiphelper.h +++ b/drivers/staging/csr/csr_wifi_hip_chiphelper.h @@ -14,10 +14,6 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - /* The age of the BlueCore chip. This is probably not useful, if you know the age then you can probably work out the version directly. */ enum chip_helper_bluecore_age @@ -408,64 +404,4 @@ s32 ChipHelper_DecodeWindow(ChipDescript *chip_help, u32 offset, u16 *page, u16 *addr, u32 *len); -#ifdef __cplusplus -/* Close the extern "C" */ -} - -/* - * This is the C++ API. - */ - -class ChipHelper -{ -public: - /* If this constructor is used then a GetVersionXXX function - should be called next. */ - ChipHelper(); - - /* copy constructor */ - ChipHelper(ChipDescript * desc); - - /* The default constructor assume a BC7 / UF105x series chip - and that the number given is the value of UNIFI_GBL_CHIP_VERSION - (0xFE81) */ - ChipHelper(u16 version); - - /* This returns the C interface magic token from a C++ instance. */ - ChipDescript* GetDescript() const - { - return m_desc; - } - - - /* Clear out theis class (set it to the null token). */ - void ClearVersion(); - - /* Load this class with data for a specific chip. */ - void GetVersionAny(u16 from_FF9A, u16 from_FE81); - void GetVersionUniFi(u16 version); - void GetVersionBlueCore(chip_helper_bluecore_age age, u16 version); - void GetVersionSdio(u8 sdio_version); - - /* Helpers to build the definitions of the member functions. */ -#define CHIP_HELPER_DEF0_CPP_DEC(ret_type, name, info) \ - ret_type name() const; -#define CHIP_HELPER_DEF1_CPP_DEC(ret_type, name, type1, name1) \ - ret_type name(type1 name1) const; - - CHIP_HELPER_LIST(CPP_DEC) - - - /* The DecodeWindow function, see the description of the C version. */ - s32 DecodeWindow(chip_helper_window_index window, - chip_helper_window_type type, - u32 offset, - u16 &page, u16 &addr, u32 &len) const; - -private: - ChipDescript *m_desc; -}; - -#endif /* __cplusplus */ - #endif diff --git a/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h b/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h index cb0ea4b63e6..e5e57991255 100644 --- a/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h +++ b/drivers/staging/csr/csr_wifi_hip_chiphelper_private.h @@ -14,10 +14,6 @@ #include "csr_wifi_hip_chiphelper.h" -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - /* This GP stuff should be somewhere else? */ /* Memory spaces encoded in top byte of Generic Pointer type */ @@ -201,8 +197,4 @@ struct chip_device_desc_t const struct window_info_t *windows[CHIP_HELPER_WINDOW_COUNT]; }; -#ifdef __cplusplus -} -#endif /* __cplusplus */ - #endif /* CSR_WIFI_HIP_CHIPHELPER_PRIVATE_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_conversions.h b/drivers/staging/csr/csr_wifi_hip_conversions.h index 7d045c06936..bf7a52e8299 100644 --- a/drivers/staging/csr/csr_wifi_hip_conversions.h +++ b/drivers/staging/csr/csr_wifi_hip_conversions.h @@ -23,10 +23,6 @@ #ifndef __CSR_WIFI_HIP_CONVERSIONS_H__ #define __CSR_WIFI_HIP_CONVERSIONS_H__ -#ifdef __cplusplus -extern "C" { -#endif - #define SIZEOF_UINT16 2 #define SIZEOF_UINT32 4 #define SIZEOF_UINT64 8 @@ -73,9 +69,5 @@ s32 get_packed_struct_size(const u8 *buf); CsrResult read_unpack_signal(const u8 *ptr, CSR_SIGNAL *sig); CsrResult write_pack(const CSR_SIGNAL *sig, u8 *ptr, u16 *sig_len); -#ifdef __cplusplus -} -#endif - #endif /* __CSR_WIFI_HIP_CONVERSIONS_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_signals.h b/drivers/staging/csr/csr_wifi_hip_signals.h index ebe2f6d9ea8..ca4d0774195 100644 --- a/drivers/staging/csr/csr_wifi_hip_signals.h +++ b/drivers/staging/csr/csr_wifi_hip_signals.h @@ -101,10 +101,6 @@ /* FUNCTION DECLARATIONS */ /******************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - /****************************************************************************** * SigGetNumDataRefs - Retrieve pointers to data-refs from a signal. * @@ -129,9 +125,4 @@ s32 SigGetDataRefs(CSR_SIGNAL *aSignal, CSR_DATAREF **aDataRef); */ s32 SigGetSize(const CSR_SIGNAL *aSignal); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - #endif /* __CSR_WIFI_HIP_SIGNALS_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_sigs.h b/drivers/staging/csr/csr_wifi_hip_sigs.h index 2b9f51d7f29..6112cc3e87f 100644 --- a/drivers/staging/csr/csr_wifi_hip_sigs.h +++ b/drivers/staging/csr/csr_wifi_hip_sigs.h @@ -16,10 +16,6 @@ #ifndef CSR_WIFI_HIP_SIGS_H #define CSR_WIFI_HIP_SIGS_H -#ifdef __cplusplus -extern "C" { -#endif - typedef s16 csr_place_holding_type; typedef u16 CSR_ASSOCIATION_ID; @@ -1418,8 +1414,4 @@ typedef struct CSR_SIGNAL_PRIMITIVE u32 SigGetFilterPos(u16 aSigID); -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_wifi_hip_ta_sampling.h b/drivers/staging/csr/csr_wifi_hip_ta_sampling.h index 46c630b4bee..aa684c654d0 100644 --- a/drivers/staging/csr/csr_wifi_hip_ta_sampling.h +++ b/drivers/staging/csr/csr_wifi_hip_ta_sampling.h @@ -21,10 +21,6 @@ #ifndef __TA_SAMPLING_H__ #define __TA_SAMPLING_H__ -#ifdef __cplusplus -extern "C" { -#endif - #include "csr_wifi_hip_unifi.h" typedef struct ta_l4stats @@ -67,9 +63,4 @@ typedef struct ta_data void unifi_ta_sampling_init(card_t *card); - -#ifdef __cplusplus -} -#endif - #endif /* __TA_SAMPLING_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_unifi.h b/drivers/staging/csr/csr_wifi_hip_unifi.h index 9042efac610..c2a2231680f 100644 --- a/drivers/staging/csr/csr_wifi_hip_unifi.h +++ b/drivers/staging/csr/csr_wifi_hip_unifi.h @@ -20,10 +20,6 @@ #ifndef __CSR_WIFI_HIP_UNIFI_H__ #define __CSR_WIFI_HIP_UNIFI_H__ 1 -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_HIP_TA_DISABLE #include "csr_wifi_router_ctrl_prim.h" #include "csr_wifi_router_prim.h" @@ -872,8 +868,4 @@ CsrResult unifi_coredump_request_at_next_reset(card_t *card, s8 enable); CsrResult unifi_coredump_init(card_t *card, u16 num_dump_buffers); void unifi_coredump_free(card_t *card); -#ifdef __cplusplus -} -#endif - #endif /* __CSR_WIFI_HIP_UNIFI_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_unifi_udi.h b/drivers/staging/csr/csr_wifi_hip_unifi_udi.h index 83032d0b4ec..9d85cfd5761 100644 --- a/drivers/staging/csr/csr_wifi_hip_unifi_udi.h +++ b/drivers/staging/csr/csr_wifi_hip_unifi_udi.h @@ -20,10 +20,6 @@ #ifndef __CSR_WIFI_HIP_UNIFI_UDI_H__ #define __CSR_WIFI_HIP_UNIFI_UDI_H__ -#ifdef __cplusplus -extern "C" { -#endif - #include "csr_wifi_hip_unifi.h" #include "csr_wifi_hip_signals.h" @@ -68,9 +64,4 @@ s32 unifi_print_status(card_t *card, char *str, s32 *remain); } \ } while (0) - -#ifdef __cplusplus -} -#endif - #endif /* __CSR_WIFI_HIP_UNIFI_UDI_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_unifihw.h b/drivers/staging/csr/csr_wifi_hip_unifihw.h index 5ffd6ba38d3..3f9fcbd55b5 100644 --- a/drivers/staging/csr/csr_wifi_hip_unifihw.h +++ b/drivers/staging/csr/csr_wifi_hip_unifihw.h @@ -20,10 +20,6 @@ #ifndef __UNIFIHW_H__ #define __UNIFIHW_H__ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* Symbol Look Up Table fingerprint. IDs are in sigs.h */ #define SLUT_FINGERPRINT 0xD397 @@ -60,8 +56,4 @@ extern "C" { #define UNIFI_GP_OFFSET(GP) ((GP) & 0xFFFFFF) #define UNIFI_GP_SPACE(GP) (((GP) >> 24) & 0xFF) -#ifdef __cplusplus -} -#endif - #endif /* __UNIFIHW_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_unifiversion.h b/drivers/staging/csr/csr_wifi_hip_unifiversion.h index e1fdbb27a46..d1c66783f32 100644 --- a/drivers/staging/csr/csr_wifi_hip_unifiversion.h +++ b/drivers/staging/csr/csr_wifi_hip_unifiversion.h @@ -21,18 +21,10 @@ #ifndef __UNIFIVERSION_H__ #define __UNIFIVERSION_H__ -#ifdef __cplusplus -extern "C" { -#endif - /* * The minimum version of Host Interface Protocol required by the driver. */ #define UNIFI_HIP_MAJOR_VERSION 9 #define UNIFI_HIP_MINOR_VERSION 1 -#ifdef __cplusplus -} -#endif - #endif /* __UNIFIVERSION_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hip_xbv.h b/drivers/staging/csr/csr_wifi_hip_xbv.h index 9b60a7e2dc7..3c507235323 100644 --- a/drivers/staging/csr/csr_wifi_hip_xbv.h +++ b/drivers/staging/csr/csr_wifi_hip_xbv.h @@ -21,10 +21,6 @@ #ifndef __XBV_H__ #define __XBV_H__ -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_XBV_TEST /* Driver includes */ #include "csr_wifi_hip_unifi.h" @@ -120,8 +116,4 @@ s32 xbv1_read_slut(card_t *card, fwreadfn_t readfn, void *dlpriv, xbv1_t *fwinfo void* xbv_to_patch(card_t *card, fwreadfn_t readfn, const void *fw_buf, const xbv1_t *fwinfo, u32 *size); -#ifdef __cplusplus -} -#endif - #endif /* __XBV_H__ */ diff --git a/drivers/staging/csr/csr_wifi_hostio_prim.h b/drivers/staging/csr/csr_wifi_hostio_prim.h index bf7c55c6e84..cfb3e272e35 100644 --- a/drivers/staging/csr/csr_wifi_hostio_prim.h +++ b/drivers/staging/csr/csr_wifi_hostio_prim.h @@ -12,16 +12,7 @@ #ifndef CSR_WIFI_HOSTIO_H #define CSR_WIFI_HOSTIO_H -#ifdef __cplusplus -extern "C" { -#endif - - #define CSR_WIFI_HOSTIO_PRIM 0x0453 -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_HOSTIO_H */ diff --git a/drivers/staging/csr/csr_wifi_lib.h b/drivers/staging/csr/csr_wifi_lib.h index eb56f620887..5fde0efb5dc 100644 --- a/drivers/staging/csr/csr_wifi_lib.h +++ b/drivers/staging/csr/csr_wifi_lib.h @@ -12,11 +12,6 @@ #include "csr_wifi_fsm_event.h" - -#ifdef __cplusplus -extern "C" { -#endif - /*----------------------------------------------------------------------------* * CsrWifiFsmEventInit * @@ -105,8 +100,4 @@ typedef struct *----------------------------------------------------------------------------*/ CsrWifiEventCsrUint16CsrUint8* CsrWifiEventCsrUint16CsrUint8_struct(u16 primtype, u16 msgtype, CsrSchedQid dst, CsrSchedQid src, u16 value16, u8 value8); -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_msgconv.h b/drivers/staging/csr/csr_wifi_msgconv.h index 7ec35d70e14..f8b402947a0 100644 --- a/drivers/staging/csr/csr_wifi_msgconv.h +++ b/drivers/staging/csr/csr_wifi_msgconv.h @@ -14,11 +14,6 @@ #include "csr_prim_defs.h" #include "csr_sched.h" -#ifdef __cplusplus -extern "C" { -#endif - - void CsrUint16SerBigEndian(u8 *ptr, size_t *len, u16 v); void CsrUint24SerBigEndian(u8 *ptr, size_t *len, u32 v); void CsrUint32SerBigEndian(u8 *ptr, size_t *len, u32 v); @@ -51,8 +46,4 @@ size_t CsrWifiEventCsrUint16CsrUint8Sizeof(void *msg); u8* CsrWifiEventCsrUint16CsrUint8Ser(u8 *ptr, size_t *len, void *msg); void* CsrWifiEventCsrUint16CsrUint8Des(u8 *buffer, size_t length); -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_MSGCONV_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h b/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h index 4072c06a152..b89d7c7f8e2 100644 --- a/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h +++ b/drivers/staging/csr/csr_wifi_nme_ap_converter_init.h @@ -13,10 +13,6 @@ #ifndef CSR_WIFI_NME_AP_CONVERTER_INIT_H__ #define CSR_WIFI_NME_AP_CONVERTER_INIT_H__ -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_NME_ENABLE #error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_converter_init.h #endif @@ -42,8 +38,4 @@ extern void CsrWifiNmeApConverterInit(void); #endif /* EXCLUDE_CSR_WIFI_NME_AP_MODULE */ -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_NME_AP_CONVERTER_INIT_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_ap_lib.h b/drivers/staging/csr/csr_wifi_nme_ap_lib.h index d4014709112..7d2fccde9fb 100644 --- a/drivers/staging/csr/csr_wifi_nme_ap_lib.h +++ b/drivers/staging/csr/csr_wifi_nme_ap_lib.h @@ -22,11 +22,6 @@ #include "csr_wifi_nme_ap_prim.h" #include "csr_wifi_nme_task.h" - -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_NME_ENABLE #error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_lib.h #endif @@ -515,9 +510,4 @@ extern const char *CsrWifiNmeApDownstreamPrimNames[CSR_WIFI_NME_AP_PRIM_DOWNSTRE #define CsrWifiNmeApWpsRegisterCfmSend(dst__, interfaceTag__, status__) \ CsrWifiNmeApWpsRegisterCfmSendTo(dst__, CSR_WIFI_NME_IFACEQUEUE, interfaceTag__, status__) - -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_NME_AP_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_ap_prim.h b/drivers/staging/csr/csr_wifi_nme_ap_prim.h index fc44560b28b..b32bdbc7e22 100644 --- a/drivers/staging/csr/csr_wifi_nme_ap_prim.h +++ b/drivers/staging/csr/csr_wifi_nme_ap_prim.h @@ -22,10 +22,6 @@ #include "csr_wifi_sme_ap_prim.h" #include "csr_wifi_nme_prim.h" -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_NME_ENABLE #error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_prim.h #endif @@ -494,10 +490,5 @@ typedef struct CsrWifiMacAddress peerDeviceAddress; } CsrWifiNmeApStationInd; - -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_NME_AP_PRIM_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_ap_sef.h b/drivers/staging/csr/csr_wifi_nme_ap_sef.h index 3f353633fa5..3daaa0944db 100644 --- a/drivers/staging/csr/csr_wifi_nme_ap_sef.h +++ b/drivers/staging/csr/csr_wifi_nme_ap_sef.h @@ -11,11 +11,6 @@ #include "csr_wifi_nme_prim.h" - -#ifdef __cplusplus -extern "C" { -#endif - void CsrWifiNmeApUpstreamStateHandlers(void* drvpriv, CsrWifiFsmEvent* msg); @@ -23,9 +18,4 @@ extern void CsrWifiNmeApConfigSetCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg) extern void CsrWifiNmeApStartCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); extern void CsrWifiNmeApStopCfmHandler(void* drvpriv, CsrWifiFsmEvent* msg); - -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_NME_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_ap_serialize.h b/drivers/staging/csr/csr_wifi_nme_ap_serialize.h index 0f578294722..c04585e7246 100644 --- a/drivers/staging/csr/csr_wifi_nme_ap_serialize.h +++ b/drivers/staging/csr/csr_wifi_nme_ap_serialize.h @@ -17,10 +17,6 @@ #include "csr_wifi_nme_ap_prim.h" -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_NME_ENABLE #error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_ap_serialize.h #endif @@ -95,9 +91,4 @@ extern void* CsrWifiNmeApStationIndDes(u8 *buffer, size_t len); extern size_t CsrWifiNmeApStationIndSizeof(void *msg); #define CsrWifiNmeApStationIndSerFree CsrWifiNmeApPfree - -#ifdef __cplusplus -} -#endif #endif /* CSR_WIFI_NME_AP_SERIALIZE_H__ */ - diff --git a/drivers/staging/csr/csr_wifi_nme_converter_init.h b/drivers/staging/csr/csr_wifi_nme_converter_init.h index 6661914fb40..85e6f5f5713 100644 --- a/drivers/staging/csr/csr_wifi_nme_converter_init.h +++ b/drivers/staging/csr/csr_wifi_nme_converter_init.h @@ -13,10 +13,6 @@ #ifndef CSR_WIFI_NME_CONVERTER_INIT_H__ #define CSR_WIFI_NME_CONVERTER_INIT_H__ -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_NME_ENABLE #error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_converter_init.h #endif @@ -39,8 +35,4 @@ extern void CsrWifiNmeConverterInit(void); #endif /* EXCLUDE_CSR_WIFI_NME_MODULE */ -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_NME_CONVERTER_INIT_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_lib.h b/drivers/staging/csr/csr_wifi_nme_lib.h index 709ece46497..1b1e0376a86 100644 --- a/drivers/staging/csr/csr_wifi_nme_lib.h +++ b/drivers/staging/csr/csr_wifi_nme_lib.h @@ -23,10 +23,6 @@ #include "csr_wifi_nme_task.h" -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_NME_ENABLE #error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_lib.h #endif @@ -1046,9 +1042,4 @@ extern const char *CsrWifiNmeDownstreamPrimNames[CSR_WIFI_NME_PRIM_DOWNSTREAM_CO #define CsrWifiNmeWpsReqSend(src__, interfaceTag__, pin__, ssid__, bssid__) \ CsrWifiNmeWpsReqSendTo(CSR_WIFI_NME_IFACEQUEUE, src__, interfaceTag__, pin__, ssid__, bssid__) - -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_NME_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_prim.h b/drivers/staging/csr/csr_wifi_nme_prim.h index 20dc77971f9..9a7927a117e 100644 --- a/drivers/staging/csr/csr_wifi_nme_prim.h +++ b/drivers/staging/csr/csr_wifi_nme_prim.h @@ -21,10 +21,6 @@ #include "csr_wifi_fsm_event.h" #include "csr_wifi_sme_prim.h" -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_NME_ENABLE #error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_prim.h #endif @@ -1657,10 +1653,5 @@ typedef struct CsrResult status; } CsrWifiNmeEventMaskSetCfm; - -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_NME_PRIM_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_serialize.h b/drivers/staging/csr/csr_wifi_nme_serialize.h index c6b163660a3..ebac484419c 100644 --- a/drivers/staging/csr/csr_wifi_nme_serialize.h +++ b/drivers/staging/csr/csr_wifi_nme_serialize.h @@ -16,10 +16,6 @@ #include "csr_wifi_msgconv.h" #include "csr_wifi_nme_prim.h" -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_NME_ENABLE #error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_serialize.h #endif @@ -166,9 +162,5 @@ extern size_t CsrWifiNmeSimUmtsAuthIndSizeof(void *msg); #define CsrWifiNmeEventMaskSetCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiNmeEventMaskSetCfmSerFree CsrWifiNmePfree - -#ifdef __cplusplus -} -#endif #endif /* CSR_WIFI_NME_SERIALIZE_H__ */ diff --git a/drivers/staging/csr/csr_wifi_nme_task.h b/drivers/staging/csr/csr_wifi_nme_task.h index 76f44dbe26a..8a1aae66140 100644 --- a/drivers/staging/csr/csr_wifi_nme_task.h +++ b/drivers/staging/csr/csr_wifi_nme_task.h @@ -16,10 +16,6 @@ #include #include "csr_sched.h" -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_NME_ENABLE #error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_task.h #endif @@ -30,9 +26,5 @@ void CsrWifiNmeInit(void **gash); void CsrWifiNmeDeinit(void **gash); void CsrWifiNmeHandler(void **gash); -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_NME_TASK_H__ */ diff --git a/drivers/staging/csr/csr_wifi_private_common.h b/drivers/staging/csr/csr_wifi_private_common.h index 47309984e2a..ee3bd51b934 100644 --- a/drivers/staging/csr/csr_wifi_private_common.h +++ b/drivers/staging/csr/csr_wifi_private_common.h @@ -11,10 +11,6 @@ #ifndef CSR_WIFI_PRIVATE_COMMON_H__ #define CSR_WIFI_PRIVATE_COMMON_H__ -#ifdef __cplusplus -extern "C" { -#endif - /** * @brief maximum number of STAs allowed to be connected * @@ -81,9 +77,5 @@ typedef u8 CsrWifiInterfaceMode; #define CSR_WIFI_MODE_WPS_ENROLLEE ((CsrWifiInterfaceMode) 0x06) #define CSR_WIFI_MODE_IBSS ((CsrWifiInterfaceMode) 0x07) -#ifdef __cplusplus -} -#endif - #endif diff --git a/drivers/staging/csr/csr_wifi_result.h b/drivers/staging/csr/csr_wifi_result.h index 2f87cda9003..3c394c7e5fa 100644 --- a/drivers/staging/csr/csr_wifi_result.h +++ b/drivers/staging/csr/csr_wifi_result.h @@ -13,10 +13,6 @@ #include "csr_result.h" -#ifdef __cplusplus -extern "C" { -#endif - /* THIS FILE SHOULD CONTAIN ONLY RESULT CODES */ /* Result Codes */ @@ -27,9 +23,5 @@ extern "C" { #define CSR_WIFI_HIP_RESULT_RANGE ((CsrResult) 5) /* Request exceeds the range of a file or a buffer */ #define CSR_WIFI_HIP_RESULT_NOT_FOUND ((CsrResult) 6) /* A file (typically a f/w patch) is not found */ -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_RESULT_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_converter_init.h b/drivers/staging/csr/csr_wifi_router_converter_init.h index 2a293e457ff..478327b75c1 100644 --- a/drivers/staging/csr/csr_wifi_router_converter_init.h +++ b/drivers/staging/csr/csr_wifi_router_converter_init.h @@ -13,10 +13,6 @@ #ifndef CSR_WIFI_ROUTER_CONVERTER_INIT_H__ #define CSR_WIFI_ROUTER_CONVERTER_INIT_H__ -#ifdef __cplusplus -extern "C" { -#endif - #ifndef EXCLUDE_CSR_WIFI_ROUTER_MODULE #include "csr_msgconv.h" @@ -35,8 +31,4 @@ extern void CsrWifiRouterConverterInit(void); #endif /* EXCLUDE_CSR_WIFI_ROUTER_MODULE */ -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_ROUTER_CONVERTER_INIT_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h b/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h index 0c9d26b7a0b..c9845891282 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h +++ b/drivers/staging/csr/csr_wifi_router_ctrl_converter_init.h @@ -13,10 +13,6 @@ #ifndef CSR_WIFI_ROUTER_CTRL_CONVERTER_INIT_H__ #define CSR_WIFI_ROUTER_CTRL_CONVERTER_INIT_H__ -#ifdef __cplusplus -extern "C" { -#endif - #ifndef EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE #include "csr_msgconv.h" @@ -35,8 +31,4 @@ extern void CsrWifiRouterCtrlConverterInit(void); #endif /* EXCLUDE_CSR_WIFI_ROUTER_CTRL_MODULE */ -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_ROUTER_CTRL_CONVERTER_INIT_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_lib.h b/drivers/staging/csr/csr_wifi_router_ctrl_lib.h index 93d0fadf5e6..f235153c42a 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_lib.h +++ b/drivers/staging/csr/csr_wifi_router_ctrl_lib.h @@ -22,11 +22,6 @@ #include "csr_wifi_router_ctrl_prim.h" #include "csr_wifi_router_task.h" - -#ifdef __cplusplus -extern "C" { -#endif - /*----------------------------------------------------------------------------* * CsrWifiRouterCtrlFreeUpstreamMessageContents * @@ -2084,9 +2079,4 @@ extern const char *CsrWifiRouterCtrlDownstreamPrimNames[CSR_WIFI_ROUTER_CTRL_PRI #define CsrWifiRouterCtrlWifiOnCfmSend(dst__, clientData__, status__) \ CsrWifiRouterCtrlWifiOnCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, clientData__, status__) - -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_ROUTER_CTRL_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_prim.h b/drivers/staging/csr/csr_wifi_router_ctrl_prim.h index ec972ac0b5a..1312a335dd7 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_prim.h +++ b/drivers/staging/csr/csr_wifi_router_ctrl_prim.h @@ -20,10 +20,6 @@ #include "csr_result.h" #include "csr_wifi_fsm_event.h" -#ifdef __cplusplus -extern "C" { -#endif - #define CSR_WIFI_ROUTER_CTRL_PRIM (0x0401) typedef CsrPrim CsrWifiRouterCtrlPrim; @@ -2113,10 +2109,5 @@ typedef struct u8 *data; } CsrWifiRouterCtrlWapiUnicastTxEncryptInd; - -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_ROUTER_CTRL_PRIM_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_sef.h b/drivers/staging/csr/csr_wifi_router_ctrl_sef.h index e0ee5cf45f9..2fb4937bc90 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_sef.h +++ b/drivers/staging/csr/csr_wifi_router_ctrl_sef.h @@ -12,10 +12,6 @@ #include "csr_wifi_router_ctrl_prim.h" -#ifdef __cplusplus -extern "C" { -#endif - typedef void (*CsrWifiRouterCtrlStateHandlerType)(void* drvpriv, CsrWifiFsmEvent* msg); extern const CsrWifiRouterCtrlStateHandlerType CsrWifiRouterCtrlDownstreamStateHandlers[CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_COUNT]; @@ -51,8 +47,5 @@ extern "C" { extern void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); extern void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); extern void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); -#ifdef __cplusplus -} -#endif #endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_CTRL_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h index 2c2a229f4bf..c9048386cfc 100644 --- a/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h +++ b/drivers/staging/csr/csr_wifi_router_ctrl_serialize.h @@ -17,10 +17,6 @@ #include "csr_wifi_router_ctrl_prim.h" -#ifdef __cplusplus -extern "C" { -#endif - extern void CsrWifiRouterCtrlPfree(void *ptr); extern u8* CsrWifiRouterCtrlConfigurePowerModeReqSer(u8 *ptr, size_t *len, void *msg); @@ -333,9 +329,5 @@ extern void* CsrWifiRouterCtrlWapiUnicastTxEncryptIndDes(u8 *buffer, size_t len) extern size_t CsrWifiRouterCtrlWapiUnicastTxEncryptIndSizeof(void *msg); extern void CsrWifiRouterCtrlWapiUnicastTxEncryptIndSerFree(void *msg); - -#ifdef __cplusplus -} -#endif #endif /* CSR_WIFI_ROUTER_CTRL_SERIALIZE_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_lib.h b/drivers/staging/csr/csr_wifi_router_lib.h index 06a2214714b..b0477c413aa 100644 --- a/drivers/staging/csr/csr_wifi_router_lib.h +++ b/drivers/staging/csr/csr_wifi_router_lib.h @@ -22,11 +22,6 @@ #include "csr_wifi_router_prim.h" #include "csr_wifi_router_task.h" - -#ifdef __cplusplus -extern "C" { -#endif - /*----------------------------------------------------------------------------* * CsrWifiRouterFreeUpstreamMessageContents * @@ -419,9 +414,4 @@ extern const char *CsrWifiRouterDownstreamPrimNames[CSR_WIFI_ROUTER_PRIM_DOWNSTR #define CsrWifiRouterMaPacketUnsubscribeCfmSend(dst__, interfaceTag__, status__) \ CsrWifiRouterMaPacketUnsubscribeCfmSendTo(dst__, CSR_WIFI_ROUTER_IFACEQUEUE, interfaceTag__, status__) - -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_ROUTER_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_prim.h b/drivers/staging/csr/csr_wifi_router_prim.h index c61486fbb6d..c52344b51f2 100644 --- a/drivers/staging/csr/csr_wifi_router_prim.h +++ b/drivers/staging/csr/csr_wifi_router_prim.h @@ -20,10 +20,6 @@ #include "csr_result.h" #include "csr_wifi_fsm_event.h" -#ifdef __cplusplus -extern "C" { -#endif - #define CSR_WIFI_ROUTER_PRIM (0x0400) typedef CsrPrim CsrWifiRouterPrim; @@ -421,10 +417,5 @@ typedef struct u16 rate; } CsrWifiRouterMaPacketInd; - -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_ROUTER_PRIM_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_sef.h b/drivers/staging/csr/csr_wifi_router_sef.h index 49dd158fa98..86692c7780c 100644 --- a/drivers/staging/csr/csr_wifi_router_sef.h +++ b/drivers/staging/csr/csr_wifi_router_sef.h @@ -12,10 +12,6 @@ #include "csr_wifi_router_prim.h" -#ifdef __cplusplus -extern "C" { -#endif - typedef void (*CsrWifiRouterStateHandlerType)(void* drvpriv, CsrWifiFsmEvent* msg); extern const CsrWifiRouterStateHandlerType CsrWifiRouterDownstreamStateHandlers[CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_COUNT]; @@ -26,8 +22,4 @@ extern "C" { extern void CsrWifiRouterMaPacketResHandler(void* drvpriv, CsrWifiFsmEvent* msg); extern void CsrWifiRouterMaPacketCancelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg); -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_ROUTER_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_serialize.h b/drivers/staging/csr/csr_wifi_router_serialize.h index 07e21b2b436..94ccdac5606 100644 --- a/drivers/staging/csr/csr_wifi_router_serialize.h +++ b/drivers/staging/csr/csr_wifi_router_serialize.h @@ -16,10 +16,6 @@ #include "csr_wifi_msgconv.h" #include "csr_wifi_router_prim.h" -#ifdef __cplusplus -extern "C" { -#endif - extern void CsrWifiRouterPfree(void *ptr); extern u8* CsrWifiRouterMaPacketSubscribeReqSer(u8 *ptr, size_t *len, void *msg); @@ -67,9 +63,5 @@ extern void* CsrWifiRouterMaPacketIndDes(u8 *buffer, size_t len); extern size_t CsrWifiRouterMaPacketIndSizeof(void *msg); extern void CsrWifiRouterMaPacketIndSerFree(void *msg); - -#ifdef __cplusplus -} -#endif #endif /* CSR_WIFI_ROUTER_SERIALIZE_H__ */ diff --git a/drivers/staging/csr/csr_wifi_router_task.h b/drivers/staging/csr/csr_wifi_router_task.h index 4e51fae4cda..9ba892f34e6 100644 --- a/drivers/staging/csr/csr_wifi_router_task.h +++ b/drivers/staging/csr/csr_wifi_router_task.h @@ -15,19 +15,11 @@ #include "csr_sched.h" -#ifdef __cplusplus -extern "C" { -#endif - #define CSR_WIFI_ROUTER_LOG_ID 0x1201FFFF extern CsrSchedQid CSR_WIFI_ROUTER_IFACEQUEUE; void CsrWifiRouterInit(void **gash); void CsrWifiRouterDeinit(void **gash); void CsrWifiRouterHandler(void **gash); -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_ROUTER_TASK_H__ */ diff --git a/drivers/staging/csr/csr_wifi_sme_ap_lib.h b/drivers/staging/csr/csr_wifi_sme_ap_lib.h index 350cb9ec301..48ea9143f59 100644 --- a/drivers/staging/csr/csr_wifi_sme_ap_lib.h +++ b/drivers/staging/csr/csr_wifi_sme_ap_lib.h @@ -22,11 +22,6 @@ #include "csr_wifi_sme_ap_prim.h" #include "csr_wifi_sme_task.h" - -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_AP_ENABLE #error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_sme_ap_lib.h #endif @@ -776,8 +771,4 @@ extern const char *CsrWifiSmeApDownstreamPrimNames[CSR_WIFI_SME_AP_PRIM_DOWNSTRE CsrWifiSmeApWpsRegistrationStartedCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, interfaceTag__, status__) -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_SME_AP_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_sme_ap_prim.h b/drivers/staging/csr/csr_wifi_sme_ap_prim.h index 93b64e9154c..3c4bcbc1612 100644 --- a/drivers/staging/csr/csr_wifi_sme_ap_prim.h +++ b/drivers/staging/csr/csr_wifi_sme_ap_prim.h @@ -20,10 +20,6 @@ #include "csr_wifi_fsm_event.h" #include "csr_wifi_sme_prim.h" -#ifdef __cplusplus -extern "C" { -#endif - #ifndef CSR_WIFI_AP_ENABLE #error CSR_WIFI_AP_ENABLE MUST be defined inorder to use csr_wifi_sme_ap_prim.h #endif @@ -1030,9 +1026,5 @@ typedef struct } CsrWifiSmeApBaDeleteCfm; -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_SME_AP_PRIM_H__ */ diff --git a/drivers/staging/csr/csr_wifi_sme_converter_init.h b/drivers/staging/csr/csr_wifi_sme_converter_init.h index fb895dec768..ba5e4b44bb6 100644 --- a/drivers/staging/csr/csr_wifi_sme_converter_init.h +++ b/drivers/staging/csr/csr_wifi_sme_converter_init.h @@ -13,10 +13,6 @@ #ifndef CSR_WIFI_SME_CONVERTER_INIT_H__ #define CSR_WIFI_SME_CONVERTER_INIT_H__ -#ifdef __cplusplus -extern "C" { -#endif - #ifndef EXCLUDE_CSR_WIFI_SME_MODULE #include "csr_msgconv.h" @@ -35,8 +31,4 @@ extern void CsrWifiSmeConverterInit(void); #endif /* EXCLUDE_CSR_WIFI_SME_MODULE */ -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_SME_CONVERTER_INIT_H__ */ diff --git a/drivers/staging/csr/csr_wifi_sme_lib.h b/drivers/staging/csr/csr_wifi_sme_lib.h index 3ca74560825..53cf1268286 100644 --- a/drivers/staging/csr/csr_wifi_sme_lib.h +++ b/drivers/staging/csr/csr_wifi_sme_lib.h @@ -32,11 +32,6 @@ # endif #endif - -#ifdef __cplusplus -extern "C" { -#endif - /*----------------------------------------------------------------------------* * CsrWifiSmeFreeUpstreamMessageContents * @@ -4305,9 +4300,4 @@ extern const char *CsrWifiSmeDownstreamPrimNames[CSR_WIFI_SME_PRIM_DOWNSTREAM_CO #define CsrWifiSmeWpsConfigurationCfmSend(dst__, status__) \ CsrWifiSmeWpsConfigurationCfmSendTo(dst__, CSR_WIFI_SME_IFACEQUEUE, status__) - -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_SME_LIB_H__ */ diff --git a/drivers/staging/csr/csr_wifi_sme_prim.h b/drivers/staging/csr/csr_wifi_sme_prim.h index 55cac5059bf..17ec79c77e5 100644 --- a/drivers/staging/csr/csr_wifi_sme_prim.h +++ b/drivers/staging/csr/csr_wifi_sme_prim.h @@ -20,10 +20,6 @@ #include "csr_result.h" #include "csr_wifi_fsm_event.h" -#ifdef __cplusplus -extern "C" { -#endif - #define CSR_WIFI_SME_PRIM (0x0404) typedef CsrPrim CsrWifiSmePrim; @@ -6510,10 +6506,5 @@ typedef struct CsrResult status; } CsrWifiSmeWpsConfigurationCfm; - -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_SME_PRIM_H__ */ diff --git a/drivers/staging/csr/csr_wifi_sme_sef.h b/drivers/staging/csr/csr_wifi_sme_sef.h index 89650c7fb6f..78b88c06723 100644 --- a/drivers/staging/csr/csr_wifi_sme_sef.h +++ b/drivers/staging/csr/csr_wifi_sme_sef.h @@ -12,11 +12,6 @@ #include "csr_wifi_sme_prim.h" - -#ifdef __cplusplus -extern "C" { -#endif - typedef void (*CsrWifiSmeStateHandlerType)(void *drvpriv, CsrWifiFsmEvent *msg); extern const CsrWifiSmeStateHandlerType @@ -144,8 +139,4 @@ extern void CsrWifiSmeCoreDumpIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); extern void CsrWifiSmeAmpStatusChangeIndHandler(void *drvpriv, CsrWifiFsmEvent *msg); -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_ROUTER_SEF_CSR_WIFI_SME_H__ */ diff --git a/drivers/staging/csr/csr_wifi_sme_serialize.h b/drivers/staging/csr/csr_wifi_sme_serialize.h index e34ae66d2f5..f8526269b20 100644 --- a/drivers/staging/csr/csr_wifi_sme_serialize.h +++ b/drivers/staging/csr/csr_wifi_sme_serialize.h @@ -16,10 +16,6 @@ #include "csr_wifi_msgconv.h" #include "csr_wifi_sme_prim.h" -#ifdef __cplusplus -extern "C" { -#endif - extern void CsrWifiSmePfree(void *ptr); #define CsrWifiSmeActivateReqSer CsrWifiEventSer @@ -666,9 +662,5 @@ extern void CsrWifiSmeCoreDumpIndSerFree(void *msg); #define CsrWifiSmeWpsConfigurationCfmSizeof CsrWifiEventCsrUint16Sizeof #define CsrWifiSmeWpsConfigurationCfmSerFree CsrWifiSmePfree - -#ifdef __cplusplus -} -#endif #endif /* CSR_WIFI_SME_SERIALIZE_H__ */ diff --git a/drivers/staging/csr/csr_wifi_sme_task.h b/drivers/staging/csr/csr_wifi_sme_task.h index a94fe88fa41..1e938c1fa96 100644 --- a/drivers/staging/csr/csr_wifi_sme_task.h +++ b/drivers/staging/csr/csr_wifi_sme_task.h @@ -15,19 +15,11 @@ #include "csr_sched.h" -#ifdef __cplusplus -extern "C" { -#endif - #define CSR_WIFI_SME_LOG_ID 0x1202FFFF extern CsrSchedQid CSR_WIFI_SME_IFACEQUEUE; void CsrWifiSmeInit(void **gash); void CsrWifiSmeDeinit(void **gash); void CsrWifiSmeHandler(void **gash); -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_SME_TASK_H__ */ diff --git a/drivers/staging/csr/csr_wifi_vif_utils.h b/drivers/staging/csr/csr_wifi_vif_utils.h index 042f93ee162..8ff97888996 100644 --- a/drivers/staging/csr/csr_wifi_vif_utils.h +++ b/drivers/staging/csr/csr_wifi_vif_utils.h @@ -11,10 +11,6 @@ #ifndef CSR_WIFI_VIF_UTILS_H #define CSR_WIFI_VIF_UTILS_H -#ifdef __cplusplus -extern "C" { -#endif - /* STANDARD INCLUDES ********************************************************/ /* PROJECT INCLUDES *********************************************************/ @@ -27,9 +23,5 @@ extern "C" { #define CSR_WIFI_NUM_INTERFACES (u8)0x1 #define CSR_WIFI_INTERFACE_IN_USE (u16)0x0 -#ifdef __cplusplus -} -#endif - #endif /* CSR_WIFI_VIF_UTILS_H */ -- cgit v1.2.3 From 0160daf8cefb44ee8cde9dc5be4d7abd124c3192 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 26 Oct 2012 16:34:08 -0700 Subject: Staging: csr: csr_macro.h: remove unused macros Remove a bunch of unused #defines. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_macro.h | 65 ----------------------------------------- 1 file changed, 65 deletions(-) diff --git a/drivers/staging/csr/csr_macro.h b/drivers/staging/csr/csr_macro.h index 3dcb2bd9275..d78ac51dacc 100644 --- a/drivers/staging/csr/csr_macro.h +++ b/drivers/staging/csr/csr_macro.h @@ -15,18 +15,6 @@ #define FALSE (0) #define TRUE (1) -/*------------------------------------------------------------------*/ -/* Bits - intended to operate on u32 values */ -/*------------------------------------------------------------------*/ -#define CSR_MASK_IS_SET(val, mask) (((val) & (mask)) == (mask)) -#define CSR_MASK_IS_UNSET(val, mask) ((((val) & (mask)) ^ mask) == (mask)) -#define CSR_MASK_SET(val, mask) ((val) |= (mask)) -#define CSR_MASK_UNSET(val, mask) ((val) = ((val) ^ (mask)) & (val)) /* Unsets the bits in val that are set in mask */ -#define CSR_BIT_IS_SET(val, bit) ((u8) ((((val) & (1UL << (bit))) != 0))) -#define CSR_BIT_SET(val, bit) ((val) |= (1UL << (bit))) -#define CSR_BIT_UNSET(val, bit) ((val) &= ~(1UL << (bit))) -#define CSR_BIT_TOGGLE(val, bit) ((val) ^= (1UL << (bit))) - /*------------------------------------------------------------------*/ /* Endian conversion */ /*------------------------------------------------------------------*/ @@ -39,59 +27,10 @@ ((u8 *) (ptr))[1] = ((u8) (((uint) >> 8) & 0x000000FF)); \ ((u8 *) (ptr))[2] = ((u8) (((uint) >> 16) & 0x000000FF)); \ ((u8 *) (ptr))[3] = ((u8) (((uint) >> 24) & 0x000000FF)) -#define CSR_GET_UINT16_FROM_BIG_ENDIAN(ptr) (((u16) ((u8 *) (ptr))[1]) | ((u16) ((u8 *) (ptr))[0]) << 8) -#define CSR_GET_UINT24_FROM_BIG_ENDIAN(ptr) (((u32) ((u8 *) (ptr))[2]) | \ - ((u32) ((u8 *) (ptr))[1]) << 8 | ((u32) ((u8 *) (ptr))[0]) << 16) -#define CSR_GET_UINT32_FROM_BIG_ENDIAN(ptr) (((u32) ((u8 *) (ptr))[3]) | ((u32) ((u8 *) (ptr))[2]) << 8 | \ - ((u32) ((u8 *) (ptr))[1]) << 16 | ((u32) ((u8 *) (ptr))[0]) << 24) -#define CSR_COPY_UINT16_TO_BIG_ENDIAN(uint, ptr) ((u8 *) (ptr))[1] = ((u8) ((uint) & 0x00FF)); \ - ((u8 *) (ptr))[0] = ((u8) ((uint) >> 8)) -#define CSR_COPY_UINT24_TO_BIG_ENDIAN(uint, ptr) ((u8 *) (ptr))[2] = ((u8) ((uint) & 0x000000FF)); \ - ((u8 *) (ptr))[1] = ((u8) (((uint) >> 8) & 0x000000FF)); \ - ((u8 *) (ptr))[0] = ((u8) (((uint) >> 16) & 0x000000FF)) -#define CSR_COPY_UINT32_TO_BIG_ENDIAN(uint, ptr) ((u8 *) (ptr))[3] = ((u8) ((uint) & 0x000000FF)); \ - ((u8 *) (ptr))[2] = ((u8) (((uint) >> 8) & 0x000000FF)); \ - ((u8 *) (ptr))[1] = ((u8) (((uint) >> 16) & 0x000000FF)); \ - ((u8 *) (ptr))[0] = ((u8) (((uint) >> 24) & 0x000000FF)) - -/*------------------------------------------------------------------*/ -/* XAP conversion macros */ -/*------------------------------------------------------------------*/ - -#define CSR_LSB16(a) ((u8) ((a) & 0x00ff)) -#define CSR_MSB16(b) ((u8) ((b) >> 8)) - -#define CSR_CONVERT_8_FROM_XAP(output, input) \ - (output) = ((u8) (input));(input) += 2 - -#define CSR_CONVERT_16_FROM_XAP(output, input) \ - (output) = (u16) ((((u16) (input)[1]) << 8) | \ - ((u16) (input)[0]));(input) += 2 - -#define CSR_CONVERT_32_FROM_XAP(output, input) \ - (output) = (((u32) (input)[1]) << 24) | \ - (((u32) (input)[0]) << 16) | \ - (((u32) (input)[3]) << 8) | \ - ((u32) (input)[2]);input += 4 - -#define CSR_ADD_UINT8_TO_XAP(output, input) \ - (output)[0] = (input); \ - (output)[1] = 0;(output) += 2 - -#define CSR_ADD_UINT16_TO_XAP(output, input) \ - (output)[0] = ((u8) ((input) & 0x00FF)); \ - (output)[1] = ((u8) ((input) >> 8));(output) += 2 - -#define CSR_ADD_UINT32_TO_XAP(output, input) \ - (output)[0] = ((u8) (((input) >> 16) & 0x00FF)); \ - (output)[1] = ((u8) ((input) >> 24)); \ - (output)[2] = ((u8) ((input) & 0x00FF)); \ - (output)[3] = ((u8) (((input) >> 8) & 0x00FF));(output) += 4 /*------------------------------------------------------------------*/ /* Misc */ /*------------------------------------------------------------------*/ -#define CSRMAX(a, b) (((a) > (b)) ? (a) : (b)) #define CSRMIN(a, b) (((a) < (b)) ? (a) : (b)) /* Use this macro on unused local variables that cannot be removed (such as @@ -99,8 +38,4 @@ and static code analysis tools like Lint and Valgrind. */ #define CSR_UNUSED(x) ((void) (x)) -#define CSR_TOUPPER(character) (((character) >= 'a') && ((character) <= 'z') ? ((character) - 0x20) : (character)) -#define CSR_TOLOWER(character) (((character) >= 'A') && ((character) <= 'Z') ? ((character) + 0x20) : (character)) -#define CSR_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) - #endif -- cgit v1.2.3 From eaadf9a76e80b00dfac31ee7ee0a5ca8fb284baf Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 26 Oct 2012 16:51:54 -0700 Subject: Staging: telephony: remove unneeded Documentation Joe pointed out that I forgot to remove the documentation, so do that here. Cc: Joe Perches Signed-off-by: Greg Kroah-Hartman --- Documentation/telephony/00-INDEX | 4 - Documentation/telephony/ixj.txt | 394 --------------------------------------- 2 files changed, 398 deletions(-) delete mode 100644 Documentation/telephony/00-INDEX delete mode 100644 Documentation/telephony/ixj.txt diff --git a/Documentation/telephony/00-INDEX b/Documentation/telephony/00-INDEX deleted file mode 100644 index 4ffe0ed5b6f..00000000000 --- a/Documentation/telephony/00-INDEX +++ /dev/null @@ -1,4 +0,0 @@ -00-INDEX - - this file. -ixj.txt - - document describing the Quicknet drivers. diff --git a/Documentation/telephony/ixj.txt b/Documentation/telephony/ixj.txt deleted file mode 100644 index db94fb6c567..00000000000 --- a/Documentation/telephony/ixj.txt +++ /dev/null @@ -1,394 +0,0 @@ -Linux Quicknet-Drivers-Howto -Quicknet Technologies, Inc. (www.quicknet.net) -Version 0.3.4 December 18, 1999 - -1.0 Introduction - -This document describes the first GPL release version of the Linux -driver for the Quicknet Internet PhoneJACK and Internet LineJACK -cards. More information about these cards is available at -www.quicknet.net. The driver version discussed in this document is -0.3.4. - -These cards offer nice telco style interfaces to use your standard -telephone/key system/PBX as the user interface for VoIP applications. -The Internet LineJACK also offers PSTN connectivity for a single line -Internet to PSTN gateway. Of course, you can add more than one card -to a system to obtain multi-line functionality. At this time, the -driver supports the POTS port on both the Internet PhoneJACK and the -Internet LineJACK, but the PSTN port on the latter card is not yet -supported. - -This document, and the drivers for the cards, are intended for a -limited audience that includes technically capable programmers who -would like to experiment with Quicknet cards. The drivers are -considered in ALPHA status and are not yet considered stable enough -for general, widespread use in an unlimited audience. - -That's worth saying again: - -THE LINUX DRIVERS FOR QUICKNET CARDS ARE PRESENTLY IN A ALPHA STATE -AND SHOULD NOT BE CONSIDERED AS READY FOR NORMAL WIDESPREAD USE. - -They are released early in the spirit of Internet development and to -make this technology available to innovators who would benefit from -early exposure. - -When we promote the device driver to "beta" level it will be -considered ready for non-programmer, non-technical users. Until then, -please be aware that these drivers may not be stable and may affect -the performance of your system. - - -1.1 Latest Additions/Improvements - -The 0.3.4 version of the driver is the first GPL release. Several -features had to be removed from the prior binary only module, mostly -for reasons of Intellectual Property rights. We can't release -information that is not ours - so certain aspects of the driver had to -be removed to protect the rights of others. - -Specifically, very old Internet PhoneJACK cards have non-standard -G.723.1 codecs (due to the early nature of the DSPs in those days). -The auto-conversion code to bring those cards into compliance with -today's standards is available as a binary only module to those people -needing it. If you bought your card after 1997 or so, you are OK - -it's only the very old cards that are affected. - -Also, the code to download G.728/G.729/G.729a codecs to the DSP is -available as a binary only module as well. This IP is not ours to -release. - -Hooks are built into the GPL driver to allow it to work with other -companion modules that are completely separate from this module. - -1.2 Copyright, Trademarks, Disclaimer, & Credits - -Copyright - -Copyright (c) 1999 Quicknet Technologies, Inc. Permission is granted -to freely copy and distribute this document provided you preserve it -in its original form. For corrections and minor changes contact the -maintainer at linux@quicknet.net. - -Trademarks - -Internet PhoneJACK and Internet LineJACK are registered trademarks of -Quicknet Technologies, Inc. - -Disclaimer - -Much of the info in this HOWTO is early information released by -Quicknet Technologies, Inc. for the express purpose of allowing early -testing and use of the Linux drivers developed for their products. -While every attempt has been made to be thorough, complete and -accurate, the information contained here may be unreliable and there -are likely a number of errors in this document. Please let the -maintainer know about them. Since this is free documentation, it -should be obvious that neither I nor previous authors can be held -legally responsible for any errors. - -Credits - -This HOWTO was written by: - - Greg Herlein - Ed Okerson - -1.3 Future Plans: You Can Help - -Please let the maintainer know of any errors in facts, opinions, -logic, spelling, grammar, clarity, links, etc. But first, if the date -is over a month old, check to see that you have the latest -version. Please send any info that you think belongs in this document. - -You can also contribute code and/or bug-fixes for the sample -applications. - - -1.4 Where to get things - -Info on latest versions of the driver are here: - -http://web.archive.org/web/*/http://www.quicknet.net/develop.htm - -1.5 Mailing List - -Quicknet operates a mailing list to provide a public forum on using -these drivers. - -To subscribe to the linux-sdk mailing list, send an email to: - - majordomo@linux.quicknet.net - -In the body of the email, type: - - subscribe linux-sdk - -Please delete any signature block that you would normally add to the -bottom of your email - it tends to confuse majordomo. - -To send mail to the list, address your mail to - - linux-sdk@linux.quicknet.net - -Your message will go out to everyone on the list. - -To unsubscribe to the linux-sdk mailing list, send an email to: - - majordomo@linux.quicknet.net - -In the body of the email, type: - - unsubscribe linux-sdk - - - -2.0 Requirements - -2.1 Quicknet Card(s) - -You will need at least one Internet PhoneJACK or Internet LineJACK -cards. These are ISA or PCI bus devices that use Plug-n-Play for -configuration, and use no IRQs. The driver will support up to 16 -cards in any one system, of any mix between the two types. - -Note that you will need two cards to do any useful testing alone, since -you will need a card on both ends of the connection. Of course, if -you are doing collaborative work, perhaps your friends or coworkers -have cards too. If not, we'll gladly sell them some! - - -2.2 ISAPNP - -Since the Quicknet cards are Plug-n-Play devices, you will need the -isapnp tools package to configure the cards, or you can use the isapnp -module to autoconfigure them. The former package probably came with -your Linux distribution. Documentation on this package is available -online at: - -http://mailer.wiwi.uni-marburg.de/linux/LDP/HOWTO/Plug-and-Play-HOWTO.html - -The isapnp autoconfiguration is available on the Quicknet website at: - - http://www.quicknet.net/develop.htm - -though it may be in the kernel by the time you read this. - - -3.0 Card Configuration - -If you did not get your drivers as part of the linux kernel, do the -following to install them: - - a. untar the distribution file. We use the following command: - tar -xvzf ixj-0.x.x.tgz - -This creates a subdirectory holding all the necessary files. Go to that -subdirectory. - - b. run the "ixj_dev_create" script to remove any stray device -files left in the /dev directory, and to create the new officially -designated device files. Note that the old devices were called -/dev/ixj, and the new method uses /dev/phone. - - c. type "make;make install" - this will compile and install the -module. - - d. type "depmod -av" to rebuild all your kernel version dependencies. - - e. if you are using the isapnp module to configure the cards - automatically, then skip to step f. Otherwise, ensure that you - have run the isapnp configuration utility to properly configure - the cards. - - e1. The Internet PhoneJACK has one configuration register that - requires 16 IO ports. The Internet LineJACK card has two - configuration registers and isapnp reports that IO 0 - requires 16 IO ports and IO 1 requires 8. The Quicknet - driver assumes that these registers are configured to be - contiguous, i.e. if IO 0 is set to 0x340 then IO 1 should - be set to 0x350. - - Make sure that none of the cards overlap if you have - multiple cards in the system. - - If you are new to the isapnp tools, you can jumpstart - yourself by doing the following: - - e2. go to the /etc directory and run pnpdump to get a blank - isapnp.conf file. - - pnpdump > /etc/isapnp.conf - - e3. edit the /etc/isapnp.conf file to set the IO warnings and - the register IO addresses. The IO warnings means that you - should find the line in the file that looks like this: - - (CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING - - and you should edit the line to look like this: - - (CONFLICT (IO WARNING)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # - or WARNING - - The next step is to set the IO port addresses. The issue - here is that isapnp does not identify all of the ports out - there. Specifically any device that does not have a driver - or module loaded by Linux will not be registered. This - includes older sound cards and network cards. We have - found that the IO port 0x300 is often used even though - isapnp claims that no-one is using those ports. We - recommend that for a single card installation that port - 0x340 (and 0x350) be used. The IO port line should change - from this: - - (IO 0 (SIZE 16) (BASE 0x0300) (CHECK)) - - to this: - - (IO 0 (SIZE 16) (BASE 0x0340) ) - - e4. if you have multiple Quicknet cards, make sure that you do - not have any overlaps. Be especially careful if you are - mixing Internet PhoneJACK and Internet LineJACK cards in - the same system. In these cases we recommend moving the - IO port addresses to the 0x400 block. Please note that on - a few machines the 0x400 series are used. Feel free to - experiment with other addresses. Our cards have been - proven to work using IO addresses of up to 0xFF0. - - e5. the last step is to uncomment the activation line so the - drivers will be associated with the port. This means the - line (immediately below) the IO line should go from this: - - # (ACT Y) - - to this: - - (ACT Y) - - Once you have finished editing the isapnp.conf file you - must submit it into the pnp driverconfigure the cards. - This is done using the following command: - - isapnp isapnp.conf - - If this works you should see a line that identifies the - Quicknet device, the IO port(s) chosen, and a message - "Enabled OK". - - f. if you are loading the module by hand, use insmod. An example -of this would look like this: - - insmod phonedev - insmod ixj dspio=0x320,0x310 xio=0,0x330 - -Then verify the module loaded by running lsmod. If you are not using a -module that matches your kernel version, you may need to "force" the -load using the -f option in the insmod command. - - insmod phonedev - insmod -f ixj dspio=0x320,0x310 xio=0,0x330 - - -If you are using isapnp to autoconfigure your card, then you do NOT -need any of the above, though you need to use depmod to load the -driver, like this: - - depmod ixj - -which will result in the needed drivers getting loaded automatically. - - g. if you are planning on having the kernel automatically request -the module for you, then you need to edit /etc/conf.modules and add the -following lines: - - options ixj dspio=0x340 xio=0x330 ixjdebug=0 - -If you do this, then when you execute an application that uses the -module the kernel will request that it is loaded. - - h. if you want non-root users to be able to read and write to the -ixj devices (this is a good idea!) you should do the following: - - - decide upon a group name to use and create that group if - needed. Add the user names to that group that you wish to - have access to the device. For example, we typically will - create a group named "ixj" in /etc/group and add all users - to that group that we want to run software that can use the - ixjX devices. - - - change the permissions on the device files, like this: - - chgrp ixj /dev/ixj* - chmod 660 /dev/ixj* - -Once this is done, then non-root users should be able to use the -devices. If you have enabled autoloading of modules, then the user -should be able to open the device and have the module loaded -automatically for them. - - -4.0 Driver Installation problems. - -We have tested these drivers on the 2.2.9, 2.2.10, 2.2.12, and 2.2.13 kernels -and in all cases have eventually been able to get the drivers to load and -run. We have found four types of problems that prevent this from happening. -The problems and solutions are: - - a. A step was missed in the installation. Go back and use section 3 -as a checklist. Many people miss running the ixj_dev_create script and thus -never load the device names into the filesystem. - - b. The kernel is inconsistently linked. We have found this problem in -the Out Of the Box installation of several distributions. The symptoms -are that neither driver will load, and that the unknown symbols include "jiffy" -and "kmalloc". The solution is to recompile both the kernel and the -modules. The command string for the final compile looks like this: - - In the kernel directory: - 1. cp .config /tmp - 2. make mrproper - 3. cp /tmp/.config . - 4. make clean;make bzImage;make modules;make modules_install - -This rebuilds both the kernel and all the modules and makes sure they all -have the same linkages. This generally solves the problem once the new -kernel is installed and the system rebooted. - - c. The kernel has been patched, then unpatched. This happens when -someone decides to use an earlier kernel after they load a later kernel. -The symptoms are proceeding through all three above steps and still not -being able to load the driver. What has happened is that the generated -header files are out of sync with the kernel itself. The solution is -to recompile (again) using "make mrproper". This will remove and then -regenerate all the necessary header files. Once this is done, then you -need to install and reboot the kernel. We have not seen any problem -loading one of our drivers after this treatment. - -5.0 Known Limitations - -We cannot currently play "dial-tone" and listen for DTMF digits at the -same time using the ISA PhoneJACK. This is a bug in the 8020 DSP chip -used on that product. All other Quicknet products function normally -in this regard. We have a work-around, but it's not done yet. Until -then, if you want dial-tone, you can always play a recorded dial-tone -sound into the audio until you have gathered the DTMF digits. - - - - - - - - - - - - - - - - - -- cgit v1.2.3 From d9ff3934171b5cf1ac17e5fcd39f3f324b4724ce Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 26 Oct 2012 17:11:23 -0700 Subject: Staging: csr: remove CSRMIN() macro Use the in-kernel min_t() macro for the one place it was being used. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_macro.h | 2 -- drivers/staging/csr/csr_wifi_hip_xbv.c | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/csr/csr_macro.h b/drivers/staging/csr/csr_macro.h index d78ac51dacc..c47f1d91b6f 100644 --- a/drivers/staging/csr/csr_macro.h +++ b/drivers/staging/csr/csr_macro.h @@ -31,8 +31,6 @@ /*------------------------------------------------------------------*/ /* Misc */ /*------------------------------------------------------------------*/ -#define CSRMIN(a, b) (((a) < (b)) ? (a) : (b)) - /* Use this macro on unused local variables that cannot be removed (such as unused function parameters). This will quell warnings from certain compilers and static code analysis tools like Lint and Valgrind. */ diff --git a/drivers/staging/csr/csr_wifi_hip_xbv.c b/drivers/staging/csr/csr_wifi_hip_xbv.c index 071f80a49f1..050a15fbadf 100644 --- a/drivers/staging/csr/csr_wifi_hip_xbv.c +++ b/drivers/staging/csr/csr_wifi_hip_xbv.c @@ -758,7 +758,7 @@ static u32 write_fwdl_to_ptdl(void *buf, const u32 offset, fwreadfn_t readfn, while (left) { /* Calculate amount to be transferred */ - sec_data_len = CSRMIN(left, PTDL_MAX_SIZE - PTDL_HDR_SIZE); + sec_data_len = min_t(u32, left, PTDL_MAX_SIZE - PTDL_HDR_SIZE); sec_len = sec_data_len + PTDL_HDR_SIZE; /* Write PTDL header + entire PTDL size */ -- cgit v1.2.3 From 7de5ae739a3786c9245af50ea0b4a363c6a0310c Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Tue, 16 Oct 2012 10:43:44 -0300 Subject: [media] exynos-gsc: change driver compatible string As G-Scaler is going to stay unchanged across all exynos5 series SoCs, changing the driver compatible string name to "samsung,exynos5-gsc" from "samsung,exynos5250-gsc". This change is as per the discussion in the devicetree forum. http://www.mail-archive.com/devicetree-discuss@lists.ozlabs.org/msg16448.html Signed-off-by: Shaik Ameer Basha Signed-off-by: Sylwester Nawrocki Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/exynos-gsc/gsc-core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index bfec9e65aef..19cbb12a12a 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -965,8 +965,10 @@ static struct platform_device_id gsc_driver_ids[] = { MODULE_DEVICE_TABLE(platform, gsc_driver_ids); static const struct of_device_id exynos_gsc_match[] = { - { .compatible = "samsung,exynos5250-gsc", - .data = &gsc_v_100_drvdata, }, + { + .compatible = "samsung,exynos5-gsc", + .data = &gsc_v_100_drvdata, + }, {}, }; MODULE_DEVICE_TABLE(of, exynos_gsc_match); -- cgit v1.2.3 From 2cad6a8a4c31175578943f087e1dbef9f52e6ec3 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 26 Oct 2012 23:15:05 +0800 Subject: GPIO: clps711x: use platform_device_unregister in gpio_clps711x_init() platform_device_unregister() only calls platform_device_del() and platform_device_put(), thus use platform_device_unregister() to simplify the code. Also the documents in platform.c shows that platform_device_del and platform_device_put must _only_ be externally called in error cases. All other usage is a bug. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Linus Walleij --- drivers/gpio/gpio-clps711x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c index ad181db7950..ce63b75b13f 100644 --- a/drivers/gpio/gpio-clps711x.c +++ b/drivers/gpio/gpio-clps711x.c @@ -162,8 +162,7 @@ static int __init gpio_clps711x_init(void) GFP_KERNEL); if (!gpio) { dev_err(&pdev->dev, "GPIO allocating memory error\n"); - platform_device_del(pdev); - platform_device_put(pdev); + platform_device_unregister(pdev); return -ENOMEM; } -- cgit v1.2.3 From 55c6659afaa6fd79a3b5a7c2b42bb87e0c11209d Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Sat, 13 Oct 2012 01:14:16 +0800 Subject: srcu: Add DEFINE_SRCU() In old days, we had two different API sets for dynamic-allocated per-CPU data and DEFINE_PER_CPU()-defined per_cpu data, and because SRCU used dynamic-allocated per-CPU data, its srcu_struct structures cannot be declared statically. This commit therefore introduces DEFINE_SRCU() and DEFINE_STATIC_SRCU() to allow statically declared SRCU structures, using the new static per-CPU interfaces. Signed-off-by: Lai Jiangshan Signed-off-by: Paul E. McKenney [ paulmck: Updated for __DELAYED_WORK_INITIALIZER() added argument, fixed whitespace issue. ] --- include/linux/srcu.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/include/linux/srcu.h b/include/linux/srcu.h index 5cce128f196..6eb691b0835 100644 --- a/include/linux/srcu.h +++ b/include/linux/srcu.h @@ -42,6 +42,8 @@ struct rcu_batch { struct rcu_head *head, **tail; }; +#define RCU_BATCH_INIT(name) { NULL, &(name.head) } + struct srcu_struct { unsigned completed; struct srcu_struct_array __percpu *per_cpu_ref; @@ -72,14 +74,42 @@ int __init_srcu_struct(struct srcu_struct *sp, const char *name, __init_srcu_struct((sp), #sp, &__srcu_key); \ }) +#define __SRCU_DEP_MAP_INIT(srcu_name) .dep_map = { .name = #srcu_name }, #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ int init_srcu_struct(struct srcu_struct *sp); +#define __SRCU_DEP_MAP_INIT(srcu_name) #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */ void process_srcu(struct work_struct *work); +#define __SRCU_STRUCT_INIT(name) \ + { \ + .completed = -300, \ + .per_cpu_ref = &name##_srcu_array, \ + .queue_lock = __SPIN_LOCK_UNLOCKED(name.queue_lock), \ + .running = false, \ + .batch_queue = RCU_BATCH_INIT(name.batch_queue), \ + .batch_check0 = RCU_BATCH_INIT(name.batch_check0), \ + .batch_check1 = RCU_BATCH_INIT(name.batch_check1), \ + .batch_done = RCU_BATCH_INIT(name.batch_done), \ + .work = __DELAYED_WORK_INITIALIZER(name.work, process_srcu, 0),\ + __SRCU_DEP_MAP_INIT(name) \ + } + +/* + * define and init a srcu struct at build time. + * dont't call init_srcu_struct() nor cleanup_srcu_struct() on it. + */ +#define DEFINE_SRCU(name) \ + static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\ + struct srcu_struct name = __SRCU_STRUCT_INIT(name); + +#define DEFINE_STATIC_SRCU(name) \ + static DEFINE_PER_CPU(struct srcu_struct_array, name##_srcu_array);\ + static struct srcu_struct name = __SRCU_STRUCT_INIT(name); + /** * call_srcu() - Queue a callback for invocation after an SRCU grace period * @sp: srcu_struct in queue the callback -- cgit v1.2.3 From cda4dc813071e6cb04944c5a140610bd06acd295 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Sat, 13 Oct 2012 01:14:17 +0800 Subject: rcutorture: Use DEFINE_STATIC_SRCU() Use DEFINE_STATIC_SRCU() to simplify the rcutorture.c SRCU test code. Signed-off-by: Lai Jiangshan Reviewed-by: Josh Triplett Signed-off-by: Paul E. McKenney --- kernel/rcutorture.c | 41 ++++++----------------------------------- 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index aaa7b9f3532..f4019720cec 100644 --- a/kernel/rcutorture.c +++ b/kernel/rcutorture.c @@ -339,7 +339,6 @@ rcu_stutter_wait(char *title) struct rcu_torture_ops { void (*init)(void); - void (*cleanup)(void); int (*readlock)(void); void (*read_delay)(struct rcu_random_state *rrsp); void (*readunlock)(int idx); @@ -431,7 +430,6 @@ static void rcu_torture_deferred_free(struct rcu_torture *p) static struct rcu_torture_ops rcu_ops = { .init = NULL, - .cleanup = NULL, .readlock = rcu_torture_read_lock, .read_delay = rcu_read_delay, .readunlock = rcu_torture_read_unlock, @@ -475,7 +473,6 @@ static void rcu_sync_torture_init(void) static struct rcu_torture_ops rcu_sync_ops = { .init = rcu_sync_torture_init, - .cleanup = NULL, .readlock = rcu_torture_read_lock, .read_delay = rcu_read_delay, .readunlock = rcu_torture_read_unlock, @@ -493,7 +490,6 @@ static struct rcu_torture_ops rcu_sync_ops = { static struct rcu_torture_ops rcu_expedited_ops = { .init = rcu_sync_torture_init, - .cleanup = NULL, .readlock = rcu_torture_read_lock, .read_delay = rcu_read_delay, /* just reuse rcu's version. */ .readunlock = rcu_torture_read_unlock, @@ -536,7 +532,6 @@ static void rcu_bh_torture_deferred_free(struct rcu_torture *p) static struct rcu_torture_ops rcu_bh_ops = { .init = NULL, - .cleanup = NULL, .readlock = rcu_bh_torture_read_lock, .read_delay = rcu_read_delay, /* just reuse rcu's version. */ .readunlock = rcu_bh_torture_read_unlock, @@ -553,7 +548,6 @@ static struct rcu_torture_ops rcu_bh_ops = { static struct rcu_torture_ops rcu_bh_sync_ops = { .init = rcu_sync_torture_init, - .cleanup = NULL, .readlock = rcu_bh_torture_read_lock, .read_delay = rcu_read_delay, /* just reuse rcu's version. */ .readunlock = rcu_bh_torture_read_unlock, @@ -570,7 +564,6 @@ static struct rcu_torture_ops rcu_bh_sync_ops = { static struct rcu_torture_ops rcu_bh_expedited_ops = { .init = rcu_sync_torture_init, - .cleanup = NULL, .readlock = rcu_bh_torture_read_lock, .read_delay = rcu_read_delay, /* just reuse rcu's version. */ .readunlock = rcu_bh_torture_read_unlock, @@ -589,19 +582,7 @@ static struct rcu_torture_ops rcu_bh_expedited_ops = { * Definitions for srcu torture testing. */ -static struct srcu_struct srcu_ctl; - -static void srcu_torture_init(void) -{ - init_srcu_struct(&srcu_ctl); - rcu_sync_torture_init(); -} - -static void srcu_torture_cleanup(void) -{ - synchronize_srcu(&srcu_ctl); - cleanup_srcu_struct(&srcu_ctl); -} +DEFINE_STATIC_SRCU(srcu_ctl); static int srcu_torture_read_lock(void) __acquires(&srcu_ctl) { @@ -672,8 +653,7 @@ static int srcu_torture_stats(char *page) } static struct rcu_torture_ops srcu_ops = { - .init = srcu_torture_init, - .cleanup = srcu_torture_cleanup, + .init = rcu_sync_torture_init, .readlock = srcu_torture_read_lock, .read_delay = srcu_read_delay, .readunlock = srcu_torture_read_unlock, @@ -687,8 +667,7 @@ static struct rcu_torture_ops srcu_ops = { }; static struct rcu_torture_ops srcu_sync_ops = { - .init = srcu_torture_init, - .cleanup = srcu_torture_cleanup, + .init = rcu_sync_torture_init, .readlock = srcu_torture_read_lock, .read_delay = srcu_read_delay, .readunlock = srcu_torture_read_unlock, @@ -712,8 +691,7 @@ static void srcu_torture_read_unlock_raw(int idx) __releases(&srcu_ctl) } static struct rcu_torture_ops srcu_raw_ops = { - .init = srcu_torture_init, - .cleanup = srcu_torture_cleanup, + .init = rcu_sync_torture_init, .readlock = srcu_torture_read_lock_raw, .read_delay = srcu_read_delay, .readunlock = srcu_torture_read_unlock_raw, @@ -727,8 +705,7 @@ static struct rcu_torture_ops srcu_raw_ops = { }; static struct rcu_torture_ops srcu_raw_sync_ops = { - .init = srcu_torture_init, - .cleanup = srcu_torture_cleanup, + .init = rcu_sync_torture_init, .readlock = srcu_torture_read_lock_raw, .read_delay = srcu_read_delay, .readunlock = srcu_torture_read_unlock_raw, @@ -747,8 +724,7 @@ static void srcu_torture_synchronize_expedited(void) } static struct rcu_torture_ops srcu_expedited_ops = { - .init = srcu_torture_init, - .cleanup = srcu_torture_cleanup, + .init = rcu_sync_torture_init, .readlock = srcu_torture_read_lock, .read_delay = srcu_read_delay, .readunlock = srcu_torture_read_unlock, @@ -783,7 +759,6 @@ static void rcu_sched_torture_deferred_free(struct rcu_torture *p) static struct rcu_torture_ops sched_ops = { .init = rcu_sync_torture_init, - .cleanup = NULL, .readlock = sched_torture_read_lock, .read_delay = rcu_read_delay, /* just reuse rcu's version. */ .readunlock = sched_torture_read_unlock, @@ -799,7 +774,6 @@ static struct rcu_torture_ops sched_ops = { static struct rcu_torture_ops sched_sync_ops = { .init = rcu_sync_torture_init, - .cleanup = NULL, .readlock = sched_torture_read_lock, .read_delay = rcu_read_delay, /* just reuse rcu's version. */ .readunlock = sched_torture_read_unlock, @@ -814,7 +788,6 @@ static struct rcu_torture_ops sched_sync_ops = { static struct rcu_torture_ops sched_expedited_ops = { .init = rcu_sync_torture_init, - .cleanup = NULL, .readlock = sched_torture_read_lock, .read_delay = rcu_read_delay, /* just reuse rcu's version. */ .readunlock = sched_torture_read_unlock, @@ -1936,8 +1909,6 @@ rcu_torture_cleanup(void) rcu_torture_stats_print(); /* -After- the stats thread is stopped! */ - if (cur_ops->cleanup) - cur_ops->cleanup(); if (atomic_read(&n_rcu_torture_error) || n_rcu_torture_barrier_error) rcu_torture_print_module_parms(cur_ops, "End of test: FAILURE"); else if (n_online_successes != n_online_attempts || -- cgit v1.2.3 From 2c5594df344cd1ff0cc9bf007dea3235582b3acf Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Fri, 26 Oct 2012 11:40:28 +0200 Subject: rcu: Fix unrecovered RCU user mode in syscall_trace_leave() On x86-64 syscall exit, 3 non exclusive events may happen looping in the following order: 1) Check if we need resched for user preemption, if so call schedule_user() 2) Check if we have pending signals, if so call do_notify_resume() 3) Check if we do syscall tracing, if so call syscall_trace_leave() However syscall_trace_leave() has been written assuming it directly follows the syscall and forget about the above possible 1st and 2nd steps. Now schedule_user() and do_notify_resume() exit in RCU user mode because they have most chances to resume userspace immediately and this avoids an rcu_user_enter() call in the syscall fast path. So by the time we call syscall_trace_leave(), we may well be in RCU user mode. To fix this up, simply call rcu_user_exit() in the beginning of this function. This fixes some reported RCU uses in extended quiescent state. Reported-by: Dave Jones Reported-by: Sergey Senozhatsky Signed-off-by: Frederic Weisbecker Tested-by: Sergey Senozhatsky Signed-off-by: Paul E. McKenney --- arch/x86/kernel/ptrace.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index b00b33a1839..eff5b8c6865 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -1511,6 +1511,13 @@ void syscall_trace_leave(struct pt_regs *regs) { bool step; + /* + * We may come here right after calling schedule_user() + * or do_notify_resume(), in which case we can be in RCU + * user mode. + */ + rcu_user_exit(); + audit_syscall_exit(regs); if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) -- cgit v1.2.3 From 8d6b00f5d639cfc28487ef412589e35b4e6ac7c7 Mon Sep 17 00:00:00 2001 From: Paul Parsons Date: Fri, 19 Oct 2012 13:15:30 +0100 Subject: ARM: pxa: hx4700: Fix backlight PWM device number Recent changes to PXA PWM support changed the PXA27X PWM device numbering scheme. The linux-3.5 PXA PWM driver followed the hardware numbering scheme for the 4 PWMs, while the linux-3.6-rc1 PXA PWM driver has adopted a linear numbering scheme: Address Hardware 3.5 pwm_id 3.6-rc1 pwm_id 0x40b00000 PWM0 0 0 0x40b00010 PWM2 2 1 0x40c00000 PWM1 1 2 0x40c00010 PWM3 3 3 The hx4700 backlight uses PWM1 at 0x40c00000. Consequently the pwm_id must be changed from 1 to 2. This patch fixes the backlight PWM device number and at the same time moves from the legacy PWM API (pwm_id) to the new PWM API (pwm_lookup). Signed-off-by: Paul Parsons Cc: Thierry Reding Signed-off-by: Haojian Zhuang --- arch/arm/mach-pxa/hx4700.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c index 5ecbd17b564..e2c6391863f 100644 --- a/arch/arm/mach-pxa/hx4700.c +++ b/arch/arm/mach-pxa/hx4700.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -556,7 +557,7 @@ static struct platform_device hx4700_lcd = { */ static struct platform_pwm_backlight_data backlight_data = { - .pwm_id = 1, + .pwm_id = -1, /* Superseded by pwm_lookup */ .max_brightness = 200, .dft_brightness = 100, .pwm_period_ns = 30923, @@ -571,6 +572,10 @@ static struct platform_device backlight = { }, }; +static struct pwm_lookup hx4700_pwm_lookup[] = { + PWM_LOOKUP("pxa27x-pwm.1", 0, "pwm-backlight", NULL), +}; + /* * USB "Transceiver" */ @@ -872,6 +877,7 @@ static void __init hx4700_init(void) pxa_set_stuart_info(NULL); platform_add_devices(devices, ARRAY_SIZE(devices)); + pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup)); pxa_set_ficp_info(&ficp_info); pxa27x_set_i2c_power_info(NULL); -- cgit v1.2.3 From 510fcb0d331f314cd20d0067d56f29302846f47b Mon Sep 17 00:00:00 2001 From: Marko Katic Date: Thu, 25 Oct 2012 18:51:38 +0200 Subject: ARM: pxa/spitz_pm: Fix hang when resuming from STR Devices that use spitz_pm.c will fail to resume from STR (Suspend To Ram) when the charger plug is inserted or removed when a device is in STR mode. The culprit is a misconfigured gpio line - GPIO18. GPIO18 should be configured as a regular GPIO input but it gets configured as an alternate function GPIO18_RDY. And then later in postsuspend() it gets configured as a regular GPIO18 input line. Fix this by removing the GPIO18_RDY configuration so that GPIO18 only gets configured as a regular gpio input. Signed-off-by: Marko Katic Signed-off-by: Haojian Zhuang --- arch/arm/mach-pxa/spitz_pm.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 438f02fe122..842596d4d31 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -86,10 +86,7 @@ static void spitz_discharge1(int on) gpio_set_value(SPITZ_GPIO_LED_GREEN, on); } -static unsigned long gpio18_config[] = { - GPIO18_RDY, - GPIO18_GPIO, -}; +static unsigned long gpio18_config = GPIO18_GPIO; static void spitz_presuspend(void) { @@ -112,7 +109,7 @@ static void spitz_presuspend(void) PGSR3 &= ~SPITZ_GPIO_G3_STROBE_BIT; PGSR2 |= GPIO_bit(SPITZ_GPIO_KEY_STROBE0); - pxa2xx_mfp_config(&gpio18_config[0], 1); + pxa2xx_mfp_config(&gpio18_config, 1); gpio_request_one(18, GPIOF_OUT_INIT_HIGH, "Unknown"); gpio_free(18); @@ -131,7 +128,6 @@ static void spitz_presuspend(void) static void spitz_postsuspend(void) { - pxa2xx_mfp_config(&gpio18_config[1], 1); } static int spitz_should_wakeup(unsigned int resume_on_alarm) -- cgit v1.2.3 From 9175ce1f1244edd9f4d39605aa06ce5b0a50b8e0 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 26 Oct 2012 13:30:06 -0700 Subject: perf tools: Move parse_events error printing to parse_events_options The callers of parse_events usually have their own error handling. Move the fprintf for a bad event to parse_events_options, which is the only one who should need it. Signed-off-by: Andi Kleen Acked-by: Jiri Olsa Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1351283415-13170-25-git-send-email-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/parse-events.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 3a3efcf3e4e..c0b785b5084 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -827,8 +827,6 @@ int parse_events(struct perf_evlist *evlist, const char *str, * Both call perf_evlist__delete in case of error, so we dont * need to bother. */ - fprintf(stderr, "invalid or unsupported event: '%s'\n", str); - fprintf(stderr, "Run 'perf list' for a list of valid events\n"); return ret; } @@ -836,7 +834,13 @@ int parse_events_option(const struct option *opt, const char *str, int unset __maybe_unused) { struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; - return parse_events(evlist, str, unset); + int ret = parse_events(evlist, str, unset); + + if (ret) { + fprintf(stderr, "invalid or unsupported event: '%s'\n", str); + fprintf(stderr, "Run 'perf list' for a list of valid events\n"); + } + return ret; } int parse_filter(const struct option *opt, const char *str, -- cgit v1.2.3 From b2da55d9441cbdaf73c12403ed801b644d5ae5e3 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 28 Oct 2012 16:01:11 +0100 Subject: Regulator: core: Unregister when gpio request fails. If the gpio_request_one() fails, or returns EPROBE_DEFER, the regulator must be device_unregister()ed. When this is not done, there are WARNING: from sysfs: WARNING: at fs/sysfs/file.c:343 sysfs_open_file+0x238/0x268() Signed-off-by: Andrew Lunn Signed-off-by: Mark Brown --- drivers/regulator/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5c4829cba6a..aa4d28b5984 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3365,7 +3365,7 @@ regulator_register(const struct regulator_desc *regulator_desc, if (ret != 0) { rdev_err(rdev, "Failed to request enable GPIO%d: %d\n", config->ena_gpio, ret); - goto clean; + goto wash; } rdev->ena_gpio = config->ena_gpio; @@ -3449,6 +3449,7 @@ scrub: if (rdev->ena_gpio) gpio_free(rdev->ena_gpio); kfree(rdev->constraints); +wash: device_unregister(&rdev->dev); /* device core frees rdev */ rdev = ERR_PTR(ret); -- cgit v1.2.3 From dffa91230f5202a78ccc97960ae1c84e533b036a Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 27 Oct 2012 19:53:11 +0200 Subject: pinctrl/: at91: fix warnings /opt/work/linux-2.6/drivers/pinctrl/pinctrl-at91.c: In function 'at91_pinctrl_probe_dt': /opt/work/linux-2.6/drivers/pinctrl/pinctrl-at91.c:952:12: warning: assignment discards qualifiers from pointer target type /opt/work/linux-2.6/drivers/pinctrl/pinctrl-at91.c: In function 'at91_gpio_probe': /opt/work/linux-2.6/drivers/pinctrl/pinctrl-at91.c:1517:17: warning: assignment discards qualifiers from pointer target type Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 676b199d6d2..5bb7d515e24 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -838,7 +838,7 @@ static int __devinit at91_pinctrl_probe_dt(struct platform_device *pdev, return -ENODEV; info->dev = &pdev->dev; - info->ops = + info->ops = (struct at91_pinctrl_mux_ops*) of_match_device(at91_pinctrl_of_match, &pdev->dev)->data; at91_pinctrl_child_count(info, np); @@ -1403,7 +1403,7 @@ static int __devinit at91_gpio_probe(struct platform_device *pdev) goto err; } - at91_chip->ops = + at91_chip->ops = (struct at91_pinctrl_mux_ops*) of_match_device(at91_gpio_of_match, &pdev->dev)->data; at91_chip->pioc_virq = irq; at91_chip->pioc_idx = alias_idx; -- cgit v1.2.3 From 2201bbb87ce324cc482479b41196ef3961660c64 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 27 Oct 2012 19:53:12 +0200 Subject: MAINTAINERS: add pinctrl atmel at91 entry Cc: linux-kernel@vger.kernel.org Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Linus Walleij --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index e73060fe078..e3a997e1f94 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5609,6 +5609,12 @@ S: Maintained F: drivers/pinctrl/ F: include/linux/pinctrl/ +PIN CONTROLLER - ATMEL AT91 +M: Jean-Christophe Plagniol-Villard +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: drivers/pinctrl/pinctrl-at91.c + PIN CONTROLLER - ST SPEAR M: Viresh Kumar L: spear-devel@list.st.com -- cgit v1.2.3 From 11aabdcd747d29dd587ff258db0219d1a4e03dfb Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 26 Oct 2012 22:48:02 +0800 Subject: pinctrl/at91: remove duplicated include from pinctrl-at91.c Remove duplicated include. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 5bb7d515e24..62f2fe47b46 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 05daa16a86b1f822eeb4324f8874d4d9b915a717 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 26 Oct 2012 22:50:54 +0800 Subject: pinctrl/at91: using for_each_set_bit to simplify the code Using for_each_set_bit() to simplify the code. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 62f2fe47b46..ddfb5dbd88d 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1219,10 +1219,8 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) continue; } - n = find_first_bit(&isr, BITS_PER_LONG); - while (n < BITS_PER_LONG) { + for_each_set_bit(n, &isr, BITS_PER_LONG) { generic_handle_irq(irq_find_mapping(at91_gpio->domain, n)); - n = find_next_bit(&isr, BITS_PER_LONG, n + 1); } } chained_irq_exit(chip, desc); -- cgit v1.2.3 From a7e35b9c324f73386e33ded83fca2d70771a1f06 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 26 Oct 2012 22:54:34 +0800 Subject: pinctrl/at91: remove unused variable in at91_dt_node_to_map() The variable pin is initialized but never used otherwise, so remove the unused variable. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index ddfb5dbd88d..65f066c4500 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -220,7 +220,6 @@ static int at91_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *parent; int map_num = 1; int i; - struct at91_pmx_pin *pin; /* * first find the group of this node and check if we need create @@ -255,8 +254,6 @@ static int at91_dt_node_to_map(struct pinctrl_dev *pctldev, /* create config map */ new_map++; for (i = 0; i < grp->npins; i++) { - pin = &grp->pins_conf[i]; - new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN; new_map[i].data.configs.group_or_pin = pin_get_name(pctldev, grp->pins[i]); -- cgit v1.2.3 From 748a2b72655334f01aff84a67747a78f8d1c8109 Mon Sep 17 00:00:00 2001 From: Maxime Coquelin Date: Wed, 10 Oct 2012 13:59:02 +0200 Subject: ARM: plat-nomadik: Introduce new DB8540 GPIO registers DB8540's GPIO controller introduce level detection support for both interrupts and wakeups. Signed-off-by: Maxime Coquelin Signed-off-by: Linus Walleij --- arch/arm/plat-nomadik/include/plat/gpio-nomadik.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h index c08a54d9d88..cf81111b79a 100644 --- a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h +++ b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h @@ -38,6 +38,9 @@ #define NMK_GPIO_RWIMSC 0x50 #define NMK_GPIO_FWIMSC 0x54 #define NMK_GPIO_WKS 0x58 +/* These appear in DB8540 and later ASICs */ +#define NMK_GPIO_EDGELEVEL 0x5C +#define NMK_GPIO_LEVEL 0x60 /* Alternate functions: function C is set in hw by setting both A and B */ #define NMK_GPIO_ALT_GPIO 0 -- cgit v1.2.3 From f64228ee23975d3703121a3d27dac488c3c813e9 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Mon, 8 Oct 2012 16:35:09 +0200 Subject: ARM: plat-nomadik: move NMK_GPIO_PER_CHIP into gpio-nomadik.h Move NMK_GPIO_PER_CHIP to gpio-nomadik.h and define it with a shift operator. Signed-off-by: Patrice Chotard Signed-off-by: Linus Walleij --- arch/arm/plat-nomadik/include/plat/gpio-nomadik.h | 3 +++ drivers/pinctrl/pinctrl-nomadik.c | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h index cf81111b79a..a74999438de 100644 --- a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h +++ b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h @@ -18,6 +18,9 @@ * the "gpio" namespace for generic and cross-machine functions */ +#define GPIO_BLOCK_SHIFT 5 +#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT) + /* Register in the logic block */ #define NMK_GPIO_DAT 0x00 #define NMK_GPIO_DATS 0x04 diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index cf82d9ce4de..f5c0da1f3b3 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -60,8 +60,6 @@ static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {} * Symbols in this file are called "nmk_gpio" for "nomadik gpio" */ -#define NMK_GPIO_PER_CHIP 32 - struct nmk_gpio_chip { struct gpio_chip chip; struct irq_domain *domain; -- cgit v1.2.3 From 1d853ca5bae2f728f0e7e1afa98b3a160020af4a Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Mon, 8 Oct 2012 16:50:24 +0200 Subject: pinctrl/nomadik: allow to support several ranges per GPIO bank With DB8500 the number of GPIO chips = number GPIO bank = number of GPIO ranges. With DB8540, a new GPIO range configuration is used, some GPIO banks can have several GPIO ranges. For example, DB8540 GPIO bank0 (GPIO0 to GPIO32) have 2 GPIO ranges: - GPIO0 to GPIO17 : routed - GPIO18 to GPIO21 : hole - GPIO22 to GPIO28 : routed - GPIO29 to GPIO32 : hole Previously, during nmk_pinctrl_probe(), all GPIO ranges were parsed, as GPIO ranges are larger than the number of GPIO chips, a warning occurs. This commit allows each bank to have several GPIO ranges. Signed-off-by: Patrice Chotard Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index f5c0da1f3b3..e30eb34189b 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -1843,11 +1843,11 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) * need this to proceed. */ for (i = 0; i < npct->soc->gpio_num_ranges; i++) { - if (!nmk_gpio_chips[i]) { + if (!nmk_gpio_chips[npct->soc->gpio_ranges[i].id]) { dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); return -EPROBE_DEFER; } - npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[i]->chip; + npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[npct->soc->gpio_ranges[i].id]->chip; } nmk_pinctrl_desc.pins = npct->soc->pins; -- cgit v1.2.3 From bb16bd9b9da49dec4f3856bc520c375e49a1237d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 10 Oct 2012 14:27:58 +0200 Subject: pinctrl/nomadik: move the platform data header This moves the platform data header for the Nomadik pin controller to . Signed-off-by: Linus Walleij --- arch/arm/mach-nomadik/board-nhk8815.c | 2 +- arch/arm/mach-nomadik/cpu-8815.c | 2 +- arch/arm/mach-nomadik/i2c-8815nhk.c | 2 +- arch/arm/mach-ux500/board-mop500-audio.c | 2 +- arch/arm/mach-ux500/board-mop500-pins.c | 2 +- arch/arm/mach-ux500/board-mop500.c | 2 +- arch/arm/mach-ux500/cpu-db8500.c | 4 +- arch/arm/mach-ux500/devices-common.c | 3 +- arch/arm/plat-nomadik/include/plat/gpio-nomadik.h | 108 ---------------------- drivers/pinctrl/pinctrl-nomadik.c | 2 +- drivers/pinctrl/pinctrl-nomadik.h | 2 +- include/linux/platform_data/pinctrl-nomadik.h | 108 ++++++++++++++++++++++ 12 files changed, 119 insertions(+), 120 deletions(-) delete mode 100644 arch/arm/plat-nomadik/include/plat/gpio-nomadik.h create mode 100644 include/linux/platform_data/pinctrl-nomadik.h diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index bfa1eab91f4..3a41ad00bd6 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -32,7 +33,6 @@ #include #include -#include #include #include diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c index b617eaed0ce..1273931303f 100644 --- a/arch/arm/mach-nomadik/cpu-8815.c +++ b/arch/arm/mach-nomadik/cpu-8815.c @@ -26,8 +26,8 @@ #include #include #include +#include -#include #include #include #include diff --git a/arch/arm/mach-nomadik/i2c-8815nhk.c b/arch/arm/mach-nomadik/i2c-8815nhk.c index 6d14454d460..f81496f5790 100644 --- a/arch/arm/mach-nomadik/i2c-8815nhk.c +++ b/arch/arm/mach-nomadik/i2c-8815nhk.c @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include /* diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c index 070629a9562..ea828cc5635 100644 --- a/arch/arm/mach-ux500/board-mop500-audio.c +++ b/arch/arm/mach-ux500/board-mop500-audio.c @@ -7,8 +7,8 @@ #include #include #include +#include -#include #include #include diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c index a267c6d30e3..05f2bb58113 100644 --- a/arch/arm/mach-ux500/board-mop500-pins.c +++ b/arch/arm/mach-ux500/board-mop500-pins.c @@ -9,10 +9,10 @@ #include #include #include +#include #include #include -#include #include diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 416d436111f..0a3dd601a40 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -37,13 +37,13 @@ #include #include #include +#include #include #include #include #include -#include #include #include diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index bcdfe6b1d45..87a8f9fbb10 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -17,14 +17,14 @@ #include #include #include +#include +#include #include #include -#include #include #include #include -#include #include #include "devices-db8500.h" diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c index dfdd4a54668..692a77a1c15 100644 --- a/arch/arm/mach-ux500/devices-common.c +++ b/arch/arm/mach-ux500/devices-common.c @@ -11,8 +11,7 @@ #include #include #include - -#include +#include #include diff --git a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h deleted file mode 100644 index a74999438de..00000000000 --- a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Structures and registers for GPIO access in the Nomadik SoC - * - * Copyright (C) 2008 STMicroelectronics - * Author: Prafulla WADASKAR - * Copyright (C) 2009 Alessandro Rubini - * - * 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. - */ - -#ifndef __PLAT_NOMADIK_GPIO -#define __PLAT_NOMADIK_GPIO - -/* - * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving - * the "gpio" namespace for generic and cross-machine functions - */ - -#define GPIO_BLOCK_SHIFT 5 -#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT) - -/* Register in the logic block */ -#define NMK_GPIO_DAT 0x00 -#define NMK_GPIO_DATS 0x04 -#define NMK_GPIO_DATC 0x08 -#define NMK_GPIO_PDIS 0x0c -#define NMK_GPIO_DIR 0x10 -#define NMK_GPIO_DIRS 0x14 -#define NMK_GPIO_DIRC 0x18 -#define NMK_GPIO_SLPC 0x1c -#define NMK_GPIO_AFSLA 0x20 -#define NMK_GPIO_AFSLB 0x24 -#define NMK_GPIO_LOWEMI 0x28 - -#define NMK_GPIO_RIMSC 0x40 -#define NMK_GPIO_FIMSC 0x44 -#define NMK_GPIO_IS 0x48 -#define NMK_GPIO_IC 0x4c -#define NMK_GPIO_RWIMSC 0x50 -#define NMK_GPIO_FWIMSC 0x54 -#define NMK_GPIO_WKS 0x58 -/* These appear in DB8540 and later ASICs */ -#define NMK_GPIO_EDGELEVEL 0x5C -#define NMK_GPIO_LEVEL 0x60 - -/* Alternate functions: function C is set in hw by setting both A and B */ -#define NMK_GPIO_ALT_GPIO 0 -#define NMK_GPIO_ALT_A 1 -#define NMK_GPIO_ALT_B 2 -#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B) - -#define NMK_GPIO_ALT_CX_SHIFT 2 -#define NMK_GPIO_ALT_C1 ((1< #include #include -#include #include "pinctrl-nomadik.h" diff --git a/drivers/pinctrl/pinctrl-nomadik.h b/drivers/pinctrl/pinctrl-nomadik.h index eef316e979a..bcd4191e10e 100644 --- a/drivers/pinctrl/pinctrl-nomadik.h +++ b/drivers/pinctrl/pinctrl-nomadik.h @@ -1,7 +1,7 @@ #ifndef PINCTRL_PINCTRL_NOMADIK_H #define PINCTRL_PINCTRL_NOMADIK_H -#include +#include /* Package definitions */ #define PINCTRL_NMK_STN8815 0 diff --git a/include/linux/platform_data/pinctrl-nomadik.h b/include/linux/platform_data/pinctrl-nomadik.h new file mode 100644 index 00000000000..a74999438de --- /dev/null +++ b/include/linux/platform_data/pinctrl-nomadik.h @@ -0,0 +1,108 @@ +/* + * Structures and registers for GPIO access in the Nomadik SoC + * + * Copyright (C) 2008 STMicroelectronics + * Author: Prafulla WADASKAR + * Copyright (C) 2009 Alessandro Rubini + * + * 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. + */ + +#ifndef __PLAT_NOMADIK_GPIO +#define __PLAT_NOMADIK_GPIO + +/* + * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving + * the "gpio" namespace for generic and cross-machine functions + */ + +#define GPIO_BLOCK_SHIFT 5 +#define NMK_GPIO_PER_CHIP (1 << GPIO_BLOCK_SHIFT) + +/* Register in the logic block */ +#define NMK_GPIO_DAT 0x00 +#define NMK_GPIO_DATS 0x04 +#define NMK_GPIO_DATC 0x08 +#define NMK_GPIO_PDIS 0x0c +#define NMK_GPIO_DIR 0x10 +#define NMK_GPIO_DIRS 0x14 +#define NMK_GPIO_DIRC 0x18 +#define NMK_GPIO_SLPC 0x1c +#define NMK_GPIO_AFSLA 0x20 +#define NMK_GPIO_AFSLB 0x24 +#define NMK_GPIO_LOWEMI 0x28 + +#define NMK_GPIO_RIMSC 0x40 +#define NMK_GPIO_FIMSC 0x44 +#define NMK_GPIO_IS 0x48 +#define NMK_GPIO_IC 0x4c +#define NMK_GPIO_RWIMSC 0x50 +#define NMK_GPIO_FWIMSC 0x54 +#define NMK_GPIO_WKS 0x58 +/* These appear in DB8540 and later ASICs */ +#define NMK_GPIO_EDGELEVEL 0x5C +#define NMK_GPIO_LEVEL 0x60 + +/* Alternate functions: function C is set in hw by setting both A and B */ +#define NMK_GPIO_ALT_GPIO 0 +#define NMK_GPIO_ALT_A 1 +#define NMK_GPIO_ALT_B 2 +#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B) + +#define NMK_GPIO_ALT_CX_SHIFT 2 +#define NMK_GPIO_ALT_C1 ((1< Date: Wed, 10 Oct 2012 14:35:17 +0200 Subject: pinctrl/nomadik: merge old pincfg header This merges the old header into and rids us of yet one more include. Signed-off-by: Linus Walleij --- arch/arm/mach-nomadik/board-nhk8815.c | 1 - arch/arm/mach-nomadik/i2c-8815nhk.c | 1 - arch/arm/mach-ux500/board-mop500-audio.c | 1 - arch/arm/mach-ux500/board-mop500-pins.c | 1 - arch/arm/plat-nomadik/include/plat/pincfg.h | 173 -------------------------- drivers/pinctrl/pinctrl-nomadik.c | 4 +- include/linux/platform_data/pinctrl-nomadik.h | 158 +++++++++++++++++++++++ 7 files changed, 159 insertions(+), 180 deletions(-) delete mode 100644 arch/arm/plat-nomadik/include/plat/pincfg.h diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 3a41ad00bd6..22ef8a1abe0 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c @@ -34,7 +34,6 @@ #include #include -#include #include #include diff --git a/arch/arm/mach-nomadik/i2c-8815nhk.c b/arch/arm/mach-nomadik/i2c-8815nhk.c index f81496f5790..0c2f6628299 100644 --- a/arch/arm/mach-nomadik/i2c-8815nhk.c +++ b/arch/arm/mach-nomadik/i2c-8815nhk.c @@ -5,7 +5,6 @@ #include #include #include -#include /* * There are two busses in the 8815NHK. diff --git a/arch/arm/mach-ux500/board-mop500-audio.c b/arch/arm/mach-ux500/board-mop500-audio.c index ea828cc5635..33631c9f121 100644 --- a/arch/arm/mach-ux500/board-mop500-audio.c +++ b/arch/arm/mach-ux500/board-mop500-audio.c @@ -9,7 +9,6 @@ #include #include -#include #include #include diff --git a/arch/arm/mach-ux500/board-mop500-pins.c b/arch/arm/mach-ux500/board-mop500-pins.c index 05f2bb58113..c34d4efd0d5 100644 --- a/arch/arm/mach-ux500/board-mop500-pins.c +++ b/arch/arm/mach-ux500/board-mop500-pins.c @@ -12,7 +12,6 @@ #include #include -#include #include diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h deleted file mode 100644 index 3b8ec60af35..00000000000 --- a/arch/arm/plat-nomadik/include/plat/pincfg.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * License terms: GNU General Public License, version 2 - * Author: Rabin Vincent for ST-Ericsson - * - * Based on arch/arm/mach-pxa/include/mach/mfp.h: - * Copyright (C) 2007 Marvell International Ltd. - * eric miao - */ - -#ifndef __PLAT_PINCFG_H -#define __PLAT_PINCFG_H - -/* - * pin configurations are represented by 32-bit integers: - * - * bit 0.. 8 - Pin Number (512 Pins Maximum) - * bit 9..10 - Alternate Function Selection - * bit 11..12 - Pull up/down state - * bit 13 - Sleep mode behaviour - * bit 14 - Direction - * bit 15 - Value (if output) - * bit 16..18 - SLPM pull up/down state - * bit 19..20 - SLPM direction - * bit 21..22 - SLPM Value (if output) - * bit 23..25 - PDIS value (if input) - * bit 26 - Gpio mode - * bit 27 - Sleep mode - * - * to facilitate the definition, the following macros are provided - * - * PIN_CFG_DEFAULT - default config (0): - * pull up/down = disabled - * sleep mode = input/wakeup - * direction = input - * value = low - * SLPM direction = same as normal - * SLPM pull = same as normal - * SLPM value = same as normal - * - * PIN_CFG - default config with alternate function - */ - -typedef unsigned long pin_cfg_t; - -#define PIN_NUM_MASK 0x1ff -#define PIN_NUM(x) ((x) & PIN_NUM_MASK) - -#define PIN_ALT_SHIFT 9 -#define PIN_ALT_MASK (0x3 << PIN_ALT_SHIFT) -#define PIN_ALT(x) (((x) & PIN_ALT_MASK) >> PIN_ALT_SHIFT) -#define PIN_GPIO (NMK_GPIO_ALT_GPIO << PIN_ALT_SHIFT) -#define PIN_ALT_A (NMK_GPIO_ALT_A << PIN_ALT_SHIFT) -#define PIN_ALT_B (NMK_GPIO_ALT_B << PIN_ALT_SHIFT) -#define PIN_ALT_C (NMK_GPIO_ALT_C << PIN_ALT_SHIFT) - -#define PIN_PULL_SHIFT 11 -#define PIN_PULL_MASK (0x3 << PIN_PULL_SHIFT) -#define PIN_PULL(x) (((x) & PIN_PULL_MASK) >> PIN_PULL_SHIFT) -#define PIN_PULL_NONE (NMK_GPIO_PULL_NONE << PIN_PULL_SHIFT) -#define PIN_PULL_UP (NMK_GPIO_PULL_UP << PIN_PULL_SHIFT) -#define PIN_PULL_DOWN (NMK_GPIO_PULL_DOWN << PIN_PULL_SHIFT) - -#define PIN_SLPM_SHIFT 13 -#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT) -#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT) -#define PIN_SLPM_MAKE_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT) -#define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT) -/* These two replace the above in DB8500v2+ */ -#define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT) -#define PIN_SLPM_WAKEUP_DISABLE (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT) -#define PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP PIN_SLPM_WAKEUP_DISABLE - -#define PIN_SLPM_GPIO PIN_SLPM_WAKEUP_ENABLE /* In SLPM, pin is a gpio */ -#define PIN_SLPM_ALTFUNC PIN_SLPM_WAKEUP_DISABLE /* In SLPM, pin is altfunc */ - -#define PIN_DIR_SHIFT 14 -#define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT) -#define PIN_DIR(x) (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT) -#define PIN_DIR_INPUT (0 << PIN_DIR_SHIFT) -#define PIN_DIR_OUTPUT (1 << PIN_DIR_SHIFT) - -#define PIN_VAL_SHIFT 15 -#define PIN_VAL_MASK (0x1 << PIN_VAL_SHIFT) -#define PIN_VAL(x) (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT) -#define PIN_VAL_LOW (0 << PIN_VAL_SHIFT) -#define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT) - -#define PIN_SLPM_PULL_SHIFT 16 -#define PIN_SLPM_PULL_MASK (0x7 << PIN_SLPM_PULL_SHIFT) -#define PIN_SLPM_PULL(x) \ - (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT) -#define PIN_SLPM_PULL_NONE \ - ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT) -#define PIN_SLPM_PULL_UP \ - ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT) -#define PIN_SLPM_PULL_DOWN \ - ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT) - -#define PIN_SLPM_DIR_SHIFT 19 -#define PIN_SLPM_DIR_MASK (0x3 << PIN_SLPM_DIR_SHIFT) -#define PIN_SLPM_DIR(x) \ - (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT) -#define PIN_SLPM_DIR_INPUT ((1 + 0) << PIN_SLPM_DIR_SHIFT) -#define PIN_SLPM_DIR_OUTPUT ((1 + 1) << PIN_SLPM_DIR_SHIFT) - -#define PIN_SLPM_VAL_SHIFT 21 -#define PIN_SLPM_VAL_MASK (0x3 << PIN_SLPM_VAL_SHIFT) -#define PIN_SLPM_VAL(x) \ - (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT) -#define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT) -#define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT) - -#define PIN_SLPM_PDIS_SHIFT 23 -#define PIN_SLPM_PDIS_MASK (0x3 << PIN_SLPM_PDIS_SHIFT) -#define PIN_SLPM_PDIS(x) \ - (((x) & PIN_SLPM_PDIS_MASK) >> PIN_SLPM_PDIS_SHIFT) -#define PIN_SLPM_PDIS_NO_CHANGE (0 << PIN_SLPM_PDIS_SHIFT) -#define PIN_SLPM_PDIS_DISABLED (1 << PIN_SLPM_PDIS_SHIFT) -#define PIN_SLPM_PDIS_ENABLED (2 << PIN_SLPM_PDIS_SHIFT) - -#define PIN_LOWEMI_SHIFT 25 -#define PIN_LOWEMI_MASK (0x1 << PIN_LOWEMI_SHIFT) -#define PIN_LOWEMI(x) (((x) & PIN_LOWEMI_MASK) >> PIN_LOWEMI_SHIFT) -#define PIN_LOWEMI_DISABLED (0 << PIN_LOWEMI_SHIFT) -#define PIN_LOWEMI_ENABLED (1 << PIN_LOWEMI_SHIFT) - -#define PIN_GPIOMODE_SHIFT 26 -#define PIN_GPIOMODE_MASK (0x1 << PIN_GPIOMODE_SHIFT) -#define PIN_GPIOMODE(x) (((x) & PIN_GPIOMODE_MASK) >> PIN_GPIOMODE_SHIFT) -#define PIN_GPIOMODE_DISABLED (0 << PIN_GPIOMODE_SHIFT) -#define PIN_GPIOMODE_ENABLED (1 << PIN_GPIOMODE_SHIFT) - -#define PIN_SLEEPMODE_SHIFT 27 -#define PIN_SLEEPMODE_MASK (0x1 << PIN_SLEEPMODE_SHIFT) -#define PIN_SLEEPMODE(x) (((x) & PIN_SLEEPMODE_MASK) >> PIN_SLEEPMODE_SHIFT) -#define PIN_SLEEPMODE_DISABLED (0 << PIN_SLEEPMODE_SHIFT) -#define PIN_SLEEPMODE_ENABLED (1 << PIN_SLEEPMODE_SHIFT) - - -/* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */ -#define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN) -#define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP) -#define PIN_INPUT_NOPULL (PIN_DIR_INPUT | PIN_PULL_NONE) -#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW) -#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH) - -#define PIN_SLPM_INPUT_PULLDOWN (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN) -#define PIN_SLPM_INPUT_PULLUP (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP) -#define PIN_SLPM_INPUT_NOPULL (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE) -#define PIN_SLPM_OUTPUT_LOW (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW) -#define PIN_SLPM_OUTPUT_HIGH (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH) - -#define PIN_CFG_DEFAULT (0) - -#define PIN_CFG(num, alt) \ - (PIN_CFG_DEFAULT |\ - (PIN_NUM(num) | PIN_##alt)) - -#define PIN_CFG_INPUT(num, alt, pull) \ - (PIN_CFG_DEFAULT |\ - (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull)) - -#define PIN_CFG_OUTPUT(num, alt, val) \ - (PIN_CFG_DEFAULT |\ - (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val)) - -extern int nmk_config_pin(pin_cfg_t cfg, bool sleep); -extern int nmk_config_pins(pin_cfg_t *cfgs, int num); -extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num); - -#endif diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 1e04c1f27dc..984a2eccfa3 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -48,8 +48,6 @@ static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {} #include -#include - #include "pinctrl-nomadik.h" /* @@ -534,7 +532,7 @@ static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep) * and its sleep mode based on the specified configuration. The @cfg is * usually one of the SoC specific macros defined in mach/-pins.h. These * are constructed using, and can be further enhanced with, the macros in - * plat/pincfg.h. + * * * If a pin's mode is set to GPIO, it is configured as an input to avoid * side-effects. The gpio can be manipulated later using standard GPIO API diff --git a/include/linux/platform_data/pinctrl-nomadik.h b/include/linux/platform_data/pinctrl-nomadik.h index a74999438de..f73b2f0c55b 100644 --- a/include/linux/platform_data/pinctrl-nomadik.h +++ b/include/linux/platform_data/pinctrl-nomadik.h @@ -13,6 +13,160 @@ #ifndef __PLAT_NOMADIK_GPIO #define __PLAT_NOMADIK_GPIO +/* + * pin configurations are represented by 32-bit integers: + * + * bit 0.. 8 - Pin Number (512 Pins Maximum) + * bit 9..10 - Alternate Function Selection + * bit 11..12 - Pull up/down state + * bit 13 - Sleep mode behaviour + * bit 14 - Direction + * bit 15 - Value (if output) + * bit 16..18 - SLPM pull up/down state + * bit 19..20 - SLPM direction + * bit 21..22 - SLPM Value (if output) + * bit 23..25 - PDIS value (if input) + * bit 26 - Gpio mode + * bit 27 - Sleep mode + * + * to facilitate the definition, the following macros are provided + * + * PIN_CFG_DEFAULT - default config (0): + * pull up/down = disabled + * sleep mode = input/wakeup + * direction = input + * value = low + * SLPM direction = same as normal + * SLPM pull = same as normal + * SLPM value = same as normal + * + * PIN_CFG - default config with alternate function + */ + +typedef unsigned long pin_cfg_t; + +#define PIN_NUM_MASK 0x1ff +#define PIN_NUM(x) ((x) & PIN_NUM_MASK) + +#define PIN_ALT_SHIFT 9 +#define PIN_ALT_MASK (0x3 << PIN_ALT_SHIFT) +#define PIN_ALT(x) (((x) & PIN_ALT_MASK) >> PIN_ALT_SHIFT) +#define PIN_GPIO (NMK_GPIO_ALT_GPIO << PIN_ALT_SHIFT) +#define PIN_ALT_A (NMK_GPIO_ALT_A << PIN_ALT_SHIFT) +#define PIN_ALT_B (NMK_GPIO_ALT_B << PIN_ALT_SHIFT) +#define PIN_ALT_C (NMK_GPIO_ALT_C << PIN_ALT_SHIFT) + +#define PIN_PULL_SHIFT 11 +#define PIN_PULL_MASK (0x3 << PIN_PULL_SHIFT) +#define PIN_PULL(x) (((x) & PIN_PULL_MASK) >> PIN_PULL_SHIFT) +#define PIN_PULL_NONE (NMK_GPIO_PULL_NONE << PIN_PULL_SHIFT) +#define PIN_PULL_UP (NMK_GPIO_PULL_UP << PIN_PULL_SHIFT) +#define PIN_PULL_DOWN (NMK_GPIO_PULL_DOWN << PIN_PULL_SHIFT) + +#define PIN_SLPM_SHIFT 13 +#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT) +#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT) +#define PIN_SLPM_MAKE_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT) +#define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT) +/* These two replace the above in DB8500v2+ */ +#define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT) +#define PIN_SLPM_WAKEUP_DISABLE (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT) +#define PIN_SLPM_USE_MUX_SETTINGS_IN_SLEEP PIN_SLPM_WAKEUP_DISABLE + +#define PIN_SLPM_GPIO PIN_SLPM_WAKEUP_ENABLE /* In SLPM, pin is a gpio */ +#define PIN_SLPM_ALTFUNC PIN_SLPM_WAKEUP_DISABLE /* In SLPM, pin is altfunc */ + +#define PIN_DIR_SHIFT 14 +#define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT) +#define PIN_DIR(x) (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT) +#define PIN_DIR_INPUT (0 << PIN_DIR_SHIFT) +#define PIN_DIR_OUTPUT (1 << PIN_DIR_SHIFT) + +#define PIN_VAL_SHIFT 15 +#define PIN_VAL_MASK (0x1 << PIN_VAL_SHIFT) +#define PIN_VAL(x) (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT) +#define PIN_VAL_LOW (0 << PIN_VAL_SHIFT) +#define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT) + +#define PIN_SLPM_PULL_SHIFT 16 +#define PIN_SLPM_PULL_MASK (0x7 << PIN_SLPM_PULL_SHIFT) +#define PIN_SLPM_PULL(x) \ + (((x) & PIN_SLPM_PULL_MASK) >> PIN_SLPM_PULL_SHIFT) +#define PIN_SLPM_PULL_NONE \ + ((1 + NMK_GPIO_PULL_NONE) << PIN_SLPM_PULL_SHIFT) +#define PIN_SLPM_PULL_UP \ + ((1 + NMK_GPIO_PULL_UP) << PIN_SLPM_PULL_SHIFT) +#define PIN_SLPM_PULL_DOWN \ + ((1 + NMK_GPIO_PULL_DOWN) << PIN_SLPM_PULL_SHIFT) + +#define PIN_SLPM_DIR_SHIFT 19 +#define PIN_SLPM_DIR_MASK (0x3 << PIN_SLPM_DIR_SHIFT) +#define PIN_SLPM_DIR(x) \ + (((x) & PIN_SLPM_DIR_MASK) >> PIN_SLPM_DIR_SHIFT) +#define PIN_SLPM_DIR_INPUT ((1 + 0) << PIN_SLPM_DIR_SHIFT) +#define PIN_SLPM_DIR_OUTPUT ((1 + 1) << PIN_SLPM_DIR_SHIFT) + +#define PIN_SLPM_VAL_SHIFT 21 +#define PIN_SLPM_VAL_MASK (0x3 << PIN_SLPM_VAL_SHIFT) +#define PIN_SLPM_VAL(x) \ + (((x) & PIN_SLPM_VAL_MASK) >> PIN_SLPM_VAL_SHIFT) +#define PIN_SLPM_VAL_LOW ((1 + 0) << PIN_SLPM_VAL_SHIFT) +#define PIN_SLPM_VAL_HIGH ((1 + 1) << PIN_SLPM_VAL_SHIFT) + +#define PIN_SLPM_PDIS_SHIFT 23 +#define PIN_SLPM_PDIS_MASK (0x3 << PIN_SLPM_PDIS_SHIFT) +#define PIN_SLPM_PDIS(x) \ + (((x) & PIN_SLPM_PDIS_MASK) >> PIN_SLPM_PDIS_SHIFT) +#define PIN_SLPM_PDIS_NO_CHANGE (0 << PIN_SLPM_PDIS_SHIFT) +#define PIN_SLPM_PDIS_DISABLED (1 << PIN_SLPM_PDIS_SHIFT) +#define PIN_SLPM_PDIS_ENABLED (2 << PIN_SLPM_PDIS_SHIFT) + +#define PIN_LOWEMI_SHIFT 25 +#define PIN_LOWEMI_MASK (0x1 << PIN_LOWEMI_SHIFT) +#define PIN_LOWEMI(x) (((x) & PIN_LOWEMI_MASK) >> PIN_LOWEMI_SHIFT) +#define PIN_LOWEMI_DISABLED (0 << PIN_LOWEMI_SHIFT) +#define PIN_LOWEMI_ENABLED (1 << PIN_LOWEMI_SHIFT) + +#define PIN_GPIOMODE_SHIFT 26 +#define PIN_GPIOMODE_MASK (0x1 << PIN_GPIOMODE_SHIFT) +#define PIN_GPIOMODE(x) (((x) & PIN_GPIOMODE_MASK) >> PIN_GPIOMODE_SHIFT) +#define PIN_GPIOMODE_DISABLED (0 << PIN_GPIOMODE_SHIFT) +#define PIN_GPIOMODE_ENABLED (1 << PIN_GPIOMODE_SHIFT) + +#define PIN_SLEEPMODE_SHIFT 27 +#define PIN_SLEEPMODE_MASK (0x1 << PIN_SLEEPMODE_SHIFT) +#define PIN_SLEEPMODE(x) (((x) & PIN_SLEEPMODE_MASK) >> PIN_SLEEPMODE_SHIFT) +#define PIN_SLEEPMODE_DISABLED (0 << PIN_SLEEPMODE_SHIFT) +#define PIN_SLEEPMODE_ENABLED (1 << PIN_SLEEPMODE_SHIFT) + + +/* Shortcuts. Use these instead of separate DIR, PULL, and VAL. */ +#define PIN_INPUT_PULLDOWN (PIN_DIR_INPUT | PIN_PULL_DOWN) +#define PIN_INPUT_PULLUP (PIN_DIR_INPUT | PIN_PULL_UP) +#define PIN_INPUT_NOPULL (PIN_DIR_INPUT | PIN_PULL_NONE) +#define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW) +#define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH) + +#define PIN_SLPM_INPUT_PULLDOWN (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_DOWN) +#define PIN_SLPM_INPUT_PULLUP (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_UP) +#define PIN_SLPM_INPUT_NOPULL (PIN_SLPM_DIR_INPUT | PIN_SLPM_PULL_NONE) +#define PIN_SLPM_OUTPUT_LOW (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_LOW) +#define PIN_SLPM_OUTPUT_HIGH (PIN_SLPM_DIR_OUTPUT | PIN_SLPM_VAL_HIGH) + +#define PIN_CFG_DEFAULT (0) + +#define PIN_CFG(num, alt) \ + (PIN_CFG_DEFAULT |\ + (PIN_NUM(num) | PIN_##alt)) + +#define PIN_CFG_INPUT(num, alt, pull) \ + (PIN_CFG_DEFAULT |\ + (PIN_NUM(num) | PIN_##alt | PIN_INPUT_##pull)) + +#define PIN_CFG_OUTPUT(num, alt, val) \ + (PIN_CFG_DEFAULT |\ + (PIN_NUM(num) | PIN_##alt | PIN_OUTPUT_##val)) + /* * "nmk_gpio" and "NMK_GPIO" stand for "Nomadik GPIO", leaving * the "gpio" namespace for generic and cross-machine functions @@ -72,6 +226,10 @@ enum nmk_gpio_slpm { NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE, }; +/* Older deprecated pin config API that should go away soon */ +extern int nmk_config_pin(pin_cfg_t cfg, bool sleep); +extern int nmk_config_pins(pin_cfg_t *cfgs, int num); +extern int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num); extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode); extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull); #ifdef CONFIG_PINCTRL_NOMADIK -- cgit v1.2.3 From d3cd8d0caaf86e5d67e13f4a1d8626963ad07161 Mon Sep 17 00:00:00 2001 From: Jean-Nicolas Graux Date: Fri, 5 Oct 2012 16:18:39 +0200 Subject: pinctrl/nomadik: update other alternate-C functions on DB8500 In pinctrl-nomadik-db8500.c, add missing definitions that deal with other alternate-C functions. Signed-off-by: Jean-Nicolas Graux Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik-db8500.c | 101 +++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/pinctrl-nomadik-db8500.c index debaa75b055..ef6f26d6ab7 100644 --- a/drivers/pinctrl/pinctrl-nomadik-db8500.c +++ b/drivers/pinctrl/pinctrl-nomadik-db8500.c @@ -600,14 +600,66 @@ static const unsigned usbsim_c_2_pins[] = { DB8500_PIN_AF8 }; static const unsigned i2c3_c_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 }; /* Other C1 column */ +static const unsigned u2rx_oc1_1_pins[] = { DB8500_PIN_AB2 }; +static const unsigned stmape_oc1_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_Y4, + DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 }; +static const unsigned remap0_oc1_1_pins[] = { DB8500_PIN_E1 }; +static const unsigned remap1_oc1_1_pins[] = { DB8500_PIN_E2 }; +static const unsigned ptma9_oc1_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4, + DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H2, + DB8500_PIN_J2, DB8500_PIN_H1 }; static const unsigned kp_oc1_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3, DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6, DB8500_PIN_D6, DB8500_PIN_B7 }; +static const unsigned rf_oc1_1_pins[] = { DB8500_PIN_D8, DB8500_PIN_D9 }; +static const unsigned hxclk_oc1_1_pins[] = { DB8500_PIN_D16 }; +static const unsigned uartmodrx_oc1_1_pins[] = { DB8500_PIN_B17 }; +static const unsigned uartmodtx_oc1_1_pins[] = { DB8500_PIN_C16 }; +static const unsigned stmmod_oc1_1_pins[] = { DB8500_PIN_C19, DB8500_PIN_C17, + DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19 }; +static const unsigned hxgpio_oc1_1_pins[] = { DB8500_PIN_D21, DB8500_PIN_D20, + DB8500_PIN_C20, DB8500_PIN_B21, DB8500_PIN_C21, DB8500_PIN_A22, + DB8500_PIN_B24, DB8500_PIN_C22 }; +static const unsigned rf_oc1_2_pins[] = { DB8500_PIN_C23, DB8500_PIN_D23 }; static const unsigned spi2_oc1_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12, DB8500_PIN_AH12, DB8500_PIN_AH11 }; static const unsigned spi2_oc1_2_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AH12, DB8500_PIN_AH11 }; +/* Other C2 column */ +static const unsigned sbag_oc2_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_AB2, + DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 }; +static const unsigned etmr4_oc2_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4, + DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H2, + DB8500_PIN_J2, DB8500_PIN_H1 }; +static const unsigned ptma9_oc2_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16, + DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17, + DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20, + DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21, + DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 }; + +/* Other C3 column */ +static const unsigned stmmod_oc3_1_pins[] = { DB8500_PIN_AB2, DB8500_PIN_W2, + DB8500_PIN_W3, DB8500_PIN_V3, DB8500_PIN_V2 }; +static const unsigned stmmod_oc3_2_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4, + DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3 }; +static const unsigned uartmodrx_oc3_1_pins[] = { DB8500_PIN_H2 }; +static const unsigned uartmodtx_oc3_1_pins[] = { DB8500_PIN_J2 }; +static const unsigned etmr4_oc3_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16, + DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17, + DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20, + DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21, + DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 }; + +/* Other C4 column */ +static const unsigned sbag_oc4_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4, + DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3, DB8500_PIN_H1 }; +static const unsigned hwobs_oc4_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16, + DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17, + DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20, + DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21, + DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 }; + #define DB8500_PIN_GROUP(a,b) { .name = #a, .pins = a##_pins, \ .npins = ARRAY_SIZE(a##_pins), .altsetting = b } @@ -726,9 +778,34 @@ static const struct nmk_pingroup nmk_db8500_groups[] = { DB8500_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C), DB8500_PIN_GROUP(i2c3_c_2, NMK_GPIO_ALT_C), /* Other alt C1 column */ + DB8500_PIN_GROUP(u2rx_oc1_1, NMK_GPIO_ALT_C1), + DB8500_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C1), + DB8500_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C1), + DB8500_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C1), + DB8500_PIN_GROUP(ptma9_oc1_1, NMK_GPIO_ALT_C1), DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1), + DB8500_PIN_GROUP(rf_oc1_1, NMK_GPIO_ALT_C1), + DB8500_PIN_GROUP(hxclk_oc1_1, NMK_GPIO_ALT_C1), + DB8500_PIN_GROUP(uartmodrx_oc1_1, NMK_GPIO_ALT_C1), + DB8500_PIN_GROUP(uartmodtx_oc1_1, NMK_GPIO_ALT_C1), + DB8500_PIN_GROUP(stmmod_oc1_1, NMK_GPIO_ALT_C1), + DB8500_PIN_GROUP(hxgpio_oc1_1, NMK_GPIO_ALT_C1), + DB8500_PIN_GROUP(rf_oc1_2, NMK_GPIO_ALT_C1), DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C1), DB8500_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C1), + /* Other alt C2 column */ + DB8500_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C2), + DB8500_PIN_GROUP(etmr4_oc2_1, NMK_GPIO_ALT_C2), + DB8500_PIN_GROUP(ptma9_oc2_1, NMK_GPIO_ALT_C2), + /* Other alt C3 column */ + DB8500_PIN_GROUP(stmmod_oc3_1, NMK_GPIO_ALT_C3), + DB8500_PIN_GROUP(stmmod_oc3_2, NMK_GPIO_ALT_C3), + DB8500_PIN_GROUP(uartmodrx_oc3_1, NMK_GPIO_ALT_C3), + DB8500_PIN_GROUP(uartmodtx_oc3_1, NMK_GPIO_ALT_C3), + DB8500_PIN_GROUP(etmr4_oc3_1, NMK_GPIO_ALT_C3), + /* Other alt C4 column */ + DB8500_PIN_GROUP(sbag_oc4_1, NMK_GPIO_ALT_C4), + DB8500_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C4), }; /* We use this macro to define the groups applicable to a function */ @@ -742,7 +819,7 @@ DB8500_FUNC_GROUPS(u1, "u1rxtx_a_1", "u1ctsrts_a_1"); * only available on two pins in alternative function C */ DB8500_FUNC_GROUPS(u2, "u2rxtx_b_1", "u2rxtx_c_1", "u2ctsrts_c_1", - "u2rxtx_c_2", "u2rxtx_c_3"); + "u2rxtx_c_2", "u2rxtx_c_3", "u2rx_oc1_1"); DB8500_FUNC_GROUPS(ipi2c, "ipi2c_a_1", "ipi2c_a_2"); /* * MSP0 can only be on a certain set of pins, but the TX/RX pins can be @@ -784,8 +861,10 @@ DB8500_FUNC_GROUPS(i2c2, "i2c2_b_1", "i2c2_b_2"); * so select one of each. */ DB8500_FUNC_GROUPS(uartmod, "uartmodtx_b_1", "uartmodrx_b_1", "uartmodrx_b_2", - "uartmodrx_c_1", "uartmod_tx_c_1"); -DB8500_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_c_1"); + "uartmodrx_c_1", "uartmod_tx_c_1", "uartmodrx_oc1_1", + "uartmodtx_oc1_1", "uartmodrx_oc3_1", "uartmodtx_oc3_1"); +DB8500_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_c_1", "stmmod_oc1_1", + "stmmod_oc3_1", "stmmod_oc3_2"); DB8500_FUNC_GROUPS(spi3, "spi3_b_1"); /* Select between CS0 on alt B or PS1 on alt C */ DB8500_FUNC_GROUPS(sm, "sm_b_1", "smcs0_b_1", "smcs1_b_1", "smcleale_c_1", @@ -799,13 +878,19 @@ DB8500_FUNC_GROUPS(ipjtag, "ipjtag_c_1"); DB8500_FUNC_GROUPS(slim0, "slim0_c_1"); DB8500_FUNC_GROUPS(ms, "ms_c_1"); DB8500_FUNC_GROUPS(iptrigout, "iptrigout_c_1"); -DB8500_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_c_2"); +DB8500_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_c_2", "stmape_oc1_1"); DB8500_FUNC_GROUPS(mc5, "mc5_c_1"); DB8500_FUNC_GROUPS(usbsim, "usbsim_c_1", "usbsim_c_2"); DB8500_FUNC_GROUPS(i2c3, "i2c3_c_1", "i2c3_c_2"); DB8500_FUNC_GROUPS(spi0, "spi0_c_1"); DB8500_FUNC_GROUPS(spi2, "spi2_oc1_1", "spi2_oc1_2"); - +DB8500_FUNC_GROUPS(remap, "remap0_oc1_1", "remap1_oc1_1"); +DB8500_FUNC_GROUPS(sbag, "sbag_oc2_1", "sbag_oc4_1"); +DB8500_FUNC_GROUPS(ptm, "ptma9_oc1_1", "ptma9_oc2_1"); +DB8500_FUNC_GROUPS(rf, "rf_oc1_1", "rf_oc1_2"); +DB8500_FUNC_GROUPS(hx, "hxclk_oc1_1", "hxgpio_oc1_1"); +DB8500_FUNC_GROUPS(etm, "etmr4_oc2_1", "etmr4_oc3_1"); +DB8500_FUNC_GROUPS(hwobs, "hwobs_oc4_1"); #define FUNCTION(fname) \ { \ .name = #fname, \ @@ -858,6 +943,12 @@ static const struct nmk_function nmk_db8500_functions[] = { FUNCTION(i2c3), FUNCTION(spi0), FUNCTION(spi2), + FUNCTION(remap), + FUNCTION(ptm), + FUNCTION(rf), + FUNCTION(hx), + FUNCTION(etm), + FUNCTION(hwobs), }; static const struct prcm_gpiocr_altcx_pin_desc db8500_altcx_pins[] = { -- cgit v1.2.3 From 2249b19f377f02e1ce9159a42cfcce31ce7cdff5 Mon Sep 17 00:00:00 2001 From: Jean-Nicolas Graux Date: Mon, 15 Oct 2012 09:47:05 +0200 Subject: pinctrl/nomadik: debugfs display of other alternate-C functions In pinctrl debug pins file, enable display of AltCx functions. Signed-off-by: Jean-Nicolas Graux Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik.c | 45 +++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 984a2eccfa3..f2fd99ba40e 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -671,6 +671,35 @@ int nmk_gpio_set_mode(int gpio, int gpio_mode) } EXPORT_SYMBOL(nmk_gpio_set_mode); +static int nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio) +{ + int i; + u16 reg; + u8 bit; + struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); + const struct prcm_gpiocr_altcx_pin_desc *pin_desc; + const u16 *gpiocr_regs; + + for (i = 0; i < npct->soc->npins_altcx; i++) { + if (npct->soc->altcx_pins[i].pin == gpio) + break; + } + if (i == npct->soc->npins_altcx) + return NMK_GPIO_ALT_C; + + pin_desc = npct->soc->altcx_pins + i; + gpiocr_regs = npct->soc->prcm_gpiocr_registers; + for (i = 0; i < PRCM_IDX_GPIOCR_ALTC_MAX; i++) { + if (pin_desc->altcx[i].used == true) { + reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; + bit = pin_desc->altcx[i].control_bit; + if (prcmu_read(reg) & BIT(bit)) + return NMK_GPIO_ALT_C+i+1; + } + } + return NMK_GPIO_ALT_C; +} + int nmk_gpio_get_mode(int gpio) { struct nmk_gpio_chip *nmk_chip; @@ -1059,8 +1088,9 @@ static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset) #include -static void nmk_gpio_dbg_show_one(struct seq_file *s, struct gpio_chip *chip, - unsigned offset, unsigned gpio) +static void nmk_gpio_dbg_show_one(struct seq_file *s, + struct pinctrl_dev *pctldev, struct gpio_chip *chip, + unsigned offset, unsigned gpio) { const char *label = gpiochip_is_requested(chip, offset); struct nmk_gpio_chip *nmk_chip = @@ -1074,12 +1104,18 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s, struct gpio_chip *chip, [NMK_GPIO_ALT_A] = "altA", [NMK_GPIO_ALT_B] = "altB", [NMK_GPIO_ALT_C] = "altC", + [NMK_GPIO_ALT_C+1] = "altC1", + [NMK_GPIO_ALT_C+2] = "altC2", + [NMK_GPIO_ALT_C+3] = "altC3", + [NMK_GPIO_ALT_C+4] = "altC4", }; clk_enable(nmk_chip->clk); is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & bit); pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit); mode = nmk_gpio_get_mode(gpio); + if ((mode == NMK_GPIO_ALT_C) && pctldev) + mode = nmk_prcm_gpiocr_get_mode(pctldev, gpio); seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s", gpio, label ?: "(none)", @@ -1123,13 +1159,14 @@ static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) unsigned gpio = chip->base; for (i = 0; i < chip->ngpio; i++, gpio++) { - nmk_gpio_dbg_show_one(s, chip, i, gpio); + nmk_gpio_dbg_show_one(s, NULL, chip, i, gpio); seq_printf(s, "\n"); } } #else static inline void nmk_gpio_dbg_show_one(struct seq_file *s, + struct pinctrl_dev *pctldev, struct gpio_chip *chip, unsigned offset, unsigned gpio) { @@ -1460,7 +1497,7 @@ static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, return; } chip = range->gc; - nmk_gpio_dbg_show_one(s, chip, offset - chip->base, offset); + nmk_gpio_dbg_show_one(s, pctldev, chip, offset - chip->base, offset); } static struct pinctrl_ops nmk_pinctrl_ops = { -- cgit v1.2.3 From 0c61ae779c4da98d47a8cf39492bca8a92842a25 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Fri, 26 Oct 2012 17:48:31 +0200 Subject: pinctrl/nomadik: db8500: fix kp pin group kp_a_2 pin group was defined but was not declared as a group of kp function. Signed-off-by: Patrice Chotard Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik-db8500.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/pinctrl-nomadik-db8500.c index ef6f26d6ab7..6de52e7c57f 100644 --- a/drivers/pinctrl/pinctrl-nomadik-db8500.c +++ b/drivers/pinctrl/pinctrl-nomadik-db8500.c @@ -691,6 +691,7 @@ static const struct nmk_pingroup nmk_db8500_groups[] = { DB8500_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A), + DB8500_PIN_GROUP(kp_a_2, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(msp2_a_1, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A), @@ -834,7 +835,7 @@ DB8500_FUNC_GROUPS(msp1, "msp1txrx_a_1", "msp1_a_1", "msp1txrx_b_1"); DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1"); DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1", "lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1"); -DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1"); +DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_a_2", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1"); DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1"); DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1"); DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1"); -- cgit v1.2.3 From ebb296c276ca19798c3116220eb8d0b2c0975ae0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Oct 2012 23:18:28 +0200 Subject: perf tools: Move build_id__sprintf into build-id object Moving build_id__sprintf function into build-id object. Signed-off-by: Jiri Olsa Reviewed-by: Namhyung Kim Tested-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351372712-21104-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-buildid-cache.c | 2 +- tools/perf/util/build-id.c | 15 +++++++++++++++ tools/perf/util/build-id.h | 1 + tools/perf/util/header.c | 1 + tools/perf/util/map.c | 1 + tools/perf/util/symbol.c | 15 --------------- tools/perf/util/symbol.h | 1 - 7 files changed, 19 insertions(+), 17 deletions(-) diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index d37e077f4b1..edb26ea78dd 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -13,7 +13,7 @@ #include "util/header.h" #include "util/parse-options.h" #include "util/strlist.h" -#include "util/symbol.h" +#include "util/build-id.h" static int build_id_cache__add_file(const char *filename, const char *debugdir) { diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index 94ca117b8d6..5295625c0c0 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -70,6 +70,21 @@ struct perf_tool build_id__mark_dso_hit_ops = { .build_id = perf_event__process_build_id, }; +int build_id__sprintf(const u8 *build_id, int len, char *bf) +{ + char *bid = bf; + const u8 *raw = build_id; + int i; + + for (i = 0; i < len; ++i) { + sprintf(bid, "%02x", *raw); + ++raw; + bid += 2; + } + + return raw - build_id; +} + char *dso__build_id_filename(struct dso *self, char *bf, size_t size) { char build_id_hex[BUILD_ID_SIZE * 2 + 1]; diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index 45c500bd5b9..f6d9ff9cab2 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -5,6 +5,7 @@ extern struct perf_tool build_id__mark_dso_hit_ops; +int build_id__sprintf(const u8 *build_id, int len, char *bf); char *dso__build_id_filename(struct dso *self, char *bf, size_t size); int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event, diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 7daad237dea..514ed1bd41a 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -23,6 +23,7 @@ #include "pmu.h" #include "vdso.h" #include "strbuf.h" +#include "build-id.h" static bool no_buildid_cache = false; diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 6109fa4d14c..9b40c444039 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -10,6 +10,7 @@ #include "thread.h" #include "strlist.h" #include "vdso.h" +#include "build-id.h" const char *map_type__name[MAP__NR_TYPES] = { [MAP__FUNCTION] = "Functions", diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e2e8c697cff..e36e8c2755b 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -504,21 +504,6 @@ void dso__sort_by_name(struct dso *dso, enum map_type type) &dso->symbols[type]); } -int build_id__sprintf(const u8 *build_id, int len, char *bf) -{ - char *bid = bf; - const u8 *raw = build_id; - int i; - - for (i = 0; i < len; ++i) { - sprintf(bid, "%02x", *raw); - ++raw; - bid += 2; - } - - return raw - build_id; -} - size_t dso__fprintf_buildid(struct dso *dso, FILE *fp) { char sbuild_id[BUILD_ID_SIZE * 2 + 1]; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 8b6ef7fac74..d70f6764524 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -338,7 +338,6 @@ struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, int filename__read_build_id(const char *filename, void *bf, size_t size); int sysfs__read_build_id(const char *filename, void *bf, size_t size); bool __dsos__read_build_ids(struct list_head *head, bool with_hits); -int build_id__sprintf(const u8 *build_id, int len, char *bf); int kallsyms__parse(const char *filename, void *arg, int (*process_symbol)(void *arg, const char *name, char type, u64 start)); -- cgit v1.2.3 From 4383db88a7afb2664941ef1e82d41f5aad8be2ec Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Oct 2012 23:18:29 +0200 Subject: perf tools: Move BUILD_ID_SIZE into build-id object Moving BUILD_ID_SIZE define into build-id object, plus include related changes. Signed-off-by: Jiri Olsa Reviewed-by: Namhyung Kim Tested-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351372712-21104-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-buildid-cache.c | 1 + tools/perf/util/annotate.c | 1 + tools/perf/util/build-id.h | 6 +++++- tools/perf/util/event.h | 3 +-- tools/perf/util/symbol.h | 3 +-- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index edb26ea78dd..fae8b250b2c 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -14,6 +14,7 @@ #include "util/parse-options.h" #include "util/strlist.h" #include "util/build-id.h" +#include "util/symbol.h" static int build_id_cache__add_file(const char *filename, const char *debugdir) { diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index f0a91037137..7a34dd18b74 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -15,6 +15,7 @@ #include "debug.h" #include "annotate.h" #include +#include const char *disassembler_style; const char *objdump_path; diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h index f6d9ff9cab2..a811f5c62e1 100644 --- a/tools/perf/util/build-id.h +++ b/tools/perf/util/build-id.h @@ -1,9 +1,13 @@ #ifndef PERF_BUILD_ID_H_ #define PERF_BUILD_ID_H_ 1 -#include "session.h" +#define BUILD_ID_SIZE 20 + +#include "tool.h" +#include "types.h" extern struct perf_tool build_id__mark_dso_hit_ops; +struct dso; int build_id__sprintf(const u8 *build_id, int len, char *bf); char *dso__build_id_filename(struct dso *self, char *bf, size_t size); diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index da97aff5bd7..0d573ff4771 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -6,6 +6,7 @@ #include "../perf.h" #include "map.h" +#include "build-id.h" /* * PERF_SAMPLE_IP | PERF_SAMPLE_TID | * @@ -96,8 +97,6 @@ struct perf_sample { struct stack_dump user_stack; }; -#define BUILD_ID_SIZE 20 - struct build_id_event { struct perf_event_header header; pid_t pid; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index d70f6764524..6eb7d3b9c88 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -11,6 +11,7 @@ #include #include #include +#include "build-id.h" #ifdef LIBELF_SUPPORT #include @@ -57,8 +58,6 @@ char *strxfrchar(char *s, char from, char to); #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ #endif -#define BUILD_ID_SIZE 20 - /** struct symbol - symtab entry * * @ignore - resolvable but tools ignore it (e.g. idle routines) -- cgit v1.2.3 From b2aff5f615793fa4c1313d82635b83cd7de8d9fd Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Oct 2012 23:18:30 +0200 Subject: perf tools: Move hex2u64 into util object Moving hex2u64 function into util object. Signed-off-by: Jiri Olsa Reviewed-by: Namhyung Kim Tested-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351372712-21104-4-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 33 --------------------------------- tools/perf/util/symbol.h | 1 - tools/perf/util/util.c | 33 +++++++++++++++++++++++++++++++++ tools/perf/util/util.h | 1 + 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e36e8c2755b..08b825799a9 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -2050,39 +2050,6 @@ int machines__create_kernel_maps(struct rb_root *machines, pid_t pid) return machine__create_kernel_maps(machine); } -static int hex(char ch) -{ - if ((ch >= '0') && (ch <= '9')) - return ch - '0'; - if ((ch >= 'a') && (ch <= 'f')) - return ch - 'a' + 10; - if ((ch >= 'A') && (ch <= 'F')) - return ch - 'A' + 10; - return -1; -} - -/* - * While we find nice hex chars, build a long_val. - * Return number of chars processed. - */ -int hex2u64(const char *ptr, u64 *long_val) -{ - const char *p = ptr; - *long_val = 0; - - while (*p) { - const int hex_val = hex(*p); - - if (hex_val < 0) - break; - - *long_val = (*long_val << 4) | hex_val; - p++; - } - - return p - ptr; -} - char *strxfrchar(char *s, char from, char to) { char *p = s; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 6eb7d3b9c88..bc34dc1fb74 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -40,7 +40,6 @@ static inline char *bfd_demangle(void __maybe_unused *v, #endif #endif -int hex2u64(const char *ptr, u64 *val); char *strxfrchar(char *s, char from, char to); /* diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 637b5cc5436..5906e8426cc 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -166,6 +166,39 @@ size_t hex_width(u64 v) return n; } +static int hex(char ch) +{ + if ((ch >= '0') && (ch <= '9')) + return ch - '0'; + if ((ch >= 'a') && (ch <= 'f')) + return ch - 'a' + 10; + if ((ch >= 'A') && (ch <= 'F')) + return ch - 'A' + 10; + return -1; +} + +/* + * While we find nice hex chars, build a long_val. + * Return number of chars processed. + */ +int hex2u64(const char *ptr, u64 *long_val) +{ + const char *p = ptr; + *long_val = 0; + + while (*p) { + const int hex_val = hex(*p); + + if (hex_val < 0) + break; + + *long_val = (*long_val << 4) | hex_val; + p++; + } + + return p - ptr; +} + /* Obtain a backtrace and print it to stdout. */ #ifdef BACKTRACE_SUPPORT void dump_stack(void) diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 0d85209db8f..d6c22c51911 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -262,6 +262,7 @@ bool is_power_of_2(unsigned long n) } size_t hex_width(u64 v); +int hex2u64(const char *ptr, u64 *val); char *rtrim(char *s); -- cgit v1.2.3 From ea36c46be69c6e49c877971c4b3b3876b24b6082 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Oct 2012 23:18:31 +0200 Subject: perf tools: Move strxfrchar into string object Moving strxfrchar function into string object. Signed-off-by: Jiri Olsa Reviewed-by: Namhyung Kim Tested-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351372712-21104-5-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/string.c | 18 ++++++++++++++++++ tools/perf/util/symbol.c | 10 ---------- tools/perf/util/symbol.h | 2 -- tools/perf/util/util.h | 1 + 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 32170590892..346707df04b 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c @@ -313,6 +313,24 @@ int strtailcmp(const char *s1, const char *s2) return 0; } +/** + * strxfrchar - Locate and replace character in @s + * @s: The string to be searched/changed. + * @from: Source character to be replaced. + * @to: Destination character. + * + * Return pointer to the changed string. + */ +char *strxfrchar(char *s, char from, char to) +{ + char *p = s; + + while ((p = strchr(p, from)) != NULL) + *p++ = to; + + return s; +} + /** * rtrim - Removes trailing whitespace from @s. * @s: The string to be stripped. diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 08b825799a9..d3b1ecc00cb 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -2050,16 +2050,6 @@ int machines__create_kernel_maps(struct rb_root *machines, pid_t pid) return machine__create_kernel_maps(machine); } -char *strxfrchar(char *s, char from, char to) -{ - char *p = s; - - while ((p = strchr(p, from)) != NULL) - *p++ = to; - - return s; -} - int machines__create_guest_kernel_maps(struct rb_root *machines) { int ret = 0; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index bc34dc1fb74..45d3df8d36d 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -40,8 +40,6 @@ static inline char *bfd_demangle(void __maybe_unused *v, #endif #endif -char *strxfrchar(char *s, char from, char to); - /* * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP; * for newer versions we can use mmap to reduce memory usage: diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index d6c22c51911..c2330918110 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -240,6 +240,7 @@ void argv_free(char **argv); bool strglobmatch(const char *str, const char *pat); bool strlazymatch(const char *str, const char *pat); int strtailcmp(const char *s1, const char *s2); +char *strxfrchar(char *s, char from, char to); unsigned long convert_unit(unsigned long value, char *unit); int readn(int fd, void *buf, size_t size); -- cgit v1.2.3 From cdd059d731eeb466f51a404ee6cbfafb0fc7c20b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 27 Oct 2012 23:18:32 +0200 Subject: perf tools: Move dso_* related functions into dso object Moving dso_* related functions into dso object. Keeping symbol loading related functions still in the symbol object as it seems more convenient. Signed-off-by: Jiri Olsa Reviewed-by: Namhyung Kim Tested-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351372712-21104-6-git-send-email-jolsa@redhat.com [ committer note: Use "symbol.h" instead of to make it build with O= ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 2 + tools/perf/util/dso.c | 594 ++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/dso.h | 148 ++++++++++++ tools/perf/util/symbol.c | 599 +---------------------------------------------- tools/perf/util/symbol.h | 134 +---------- 5 files changed, 751 insertions(+), 726 deletions(-) create mode 100644 tools/perf/util/dso.c create mode 100644 tools/perf/util/dso.h diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 629fc6a4b0d..ec63d53cd87 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -327,6 +327,7 @@ LIB_H += util/svghelper.h LIB_H += util/tool.h LIB_H += util/run-command.h LIB_H += util/sigchain.h +LIB_H += util/dso.h LIB_H += util/symbol.h LIB_H += util/color.h LIB_H += util/values.h @@ -385,6 +386,7 @@ LIB_OBJS += $(OUTPUT)util/top.o LIB_OBJS += $(OUTPUT)util/usage.o LIB_OBJS += $(OUTPUT)util/wrapper.o LIB_OBJS += $(OUTPUT)util/sigchain.o +LIB_OBJS += $(OUTPUT)util/dso.o LIB_OBJS += $(OUTPUT)util/symbol.o LIB_OBJS += $(OUTPUT)util/symbol-elf.o LIB_OBJS += $(OUTPUT)util/dso-test-data.o diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c new file mode 100644 index 00000000000..db24a3f0c82 --- /dev/null +++ b/tools/perf/util/dso.c @@ -0,0 +1,594 @@ +#include "symbol.h" +#include "dso.h" +#include "util.h" +#include "debug.h" + +char dso__symtab_origin(const struct dso *dso) +{ + static const char origin[] = { + [DSO_BINARY_TYPE__KALLSYMS] = 'k', + [DSO_BINARY_TYPE__VMLINUX] = 'v', + [DSO_BINARY_TYPE__JAVA_JIT] = 'j', + [DSO_BINARY_TYPE__DEBUGLINK] = 'l', + [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B', + [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f', + [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u', + [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b', + [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd', + [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K', + [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g', + [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G', + [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V', + }; + + if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND) + return '!'; + return origin[dso->symtab_type]; +} + +int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, + char *root_dir, char *file, size_t size) +{ + char build_id_hex[BUILD_ID_SIZE * 2 + 1]; + int ret = 0; + + switch (type) { + case DSO_BINARY_TYPE__DEBUGLINK: { + char *debuglink; + + strncpy(file, dso->long_name, size); + debuglink = file + dso->long_name_len; + while (debuglink != file && *debuglink != '/') + debuglink--; + if (*debuglink == '/') + debuglink++; + filename__read_debuglink(dso->long_name, debuglink, + size - (debuglink - file)); + } + break; + case DSO_BINARY_TYPE__BUILD_ID_CACHE: + /* skip the locally configured cache if a symfs is given */ + if (symbol_conf.symfs[0] || + (dso__build_id_filename(dso, file, size) == NULL)) + ret = -1; + break; + + case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: + snprintf(file, size, "%s/usr/lib/debug%s.debug", + symbol_conf.symfs, dso->long_name); + break; + + case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: + snprintf(file, size, "%s/usr/lib/debug%s", + symbol_conf.symfs, dso->long_name); + break; + + case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: + if (!dso->has_build_id) { + ret = -1; + break; + } + + build_id__sprintf(dso->build_id, + sizeof(dso->build_id), + build_id_hex); + snprintf(file, size, + "%s/usr/lib/debug/.build-id/%.2s/%s.debug", + symbol_conf.symfs, build_id_hex, build_id_hex + 2); + break; + + case DSO_BINARY_TYPE__SYSTEM_PATH_DSO: + snprintf(file, size, "%s%s", + symbol_conf.symfs, dso->long_name); + break; + + case DSO_BINARY_TYPE__GUEST_KMODULE: + snprintf(file, size, "%s%s%s", symbol_conf.symfs, + root_dir, dso->long_name); + break; + + case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE: + snprintf(file, size, "%s%s", symbol_conf.symfs, + dso->long_name); + break; + + default: + case DSO_BINARY_TYPE__KALLSYMS: + case DSO_BINARY_TYPE__VMLINUX: + case DSO_BINARY_TYPE__GUEST_KALLSYMS: + case DSO_BINARY_TYPE__GUEST_VMLINUX: + case DSO_BINARY_TYPE__JAVA_JIT: + case DSO_BINARY_TYPE__NOT_FOUND: + ret = -1; + break; + } + + return ret; +} + +static int open_dso(struct dso *dso, struct machine *machine) +{ + char *root_dir = (char *) ""; + char *name; + int fd; + + name = malloc(PATH_MAX); + if (!name) + return -ENOMEM; + + if (machine) + root_dir = machine->root_dir; + + if (dso__binary_type_file(dso, dso->data_type, + root_dir, name, PATH_MAX)) { + free(name); + return -EINVAL; + } + + fd = open(name, O_RDONLY); + free(name); + return fd; +} + +int dso__data_fd(struct dso *dso, struct machine *machine) +{ + static enum dso_binary_type binary_type_data[] = { + DSO_BINARY_TYPE__BUILD_ID_CACHE, + DSO_BINARY_TYPE__SYSTEM_PATH_DSO, + DSO_BINARY_TYPE__NOT_FOUND, + }; + int i = 0; + + if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND) + return open_dso(dso, machine); + + do { + int fd; + + dso->data_type = binary_type_data[i++]; + + fd = open_dso(dso, machine); + if (fd >= 0) + return fd; + + } while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND); + + return -EINVAL; +} + +static void +dso_cache__free(struct rb_root *root) +{ + struct rb_node *next = rb_first(root); + + while (next) { + struct dso_cache *cache; + + cache = rb_entry(next, struct dso_cache, rb_node); + next = rb_next(&cache->rb_node); + rb_erase(&cache->rb_node, root); + free(cache); + } +} + +static struct dso_cache* +dso_cache__find(struct rb_root *root, u64 offset) +{ + struct rb_node **p = &root->rb_node; + struct rb_node *parent = NULL; + struct dso_cache *cache; + + while (*p != NULL) { + u64 end; + + parent = *p; + cache = rb_entry(parent, struct dso_cache, rb_node); + end = cache->offset + DSO__DATA_CACHE_SIZE; + + if (offset < cache->offset) + p = &(*p)->rb_left; + else if (offset >= end) + p = &(*p)->rb_right; + else + return cache; + } + return NULL; +} + +static void +dso_cache__insert(struct rb_root *root, struct dso_cache *new) +{ + struct rb_node **p = &root->rb_node; + struct rb_node *parent = NULL; + struct dso_cache *cache; + u64 offset = new->offset; + + while (*p != NULL) { + u64 end; + + parent = *p; + cache = rb_entry(parent, struct dso_cache, rb_node); + end = cache->offset + DSO__DATA_CACHE_SIZE; + + if (offset < cache->offset) + p = &(*p)->rb_left; + else if (offset >= end) + p = &(*p)->rb_right; + } + + rb_link_node(&new->rb_node, parent, p); + rb_insert_color(&new->rb_node, root); +} + +static ssize_t +dso_cache__memcpy(struct dso_cache *cache, u64 offset, + u8 *data, u64 size) +{ + u64 cache_offset = offset - cache->offset; + u64 cache_size = min(cache->size - cache_offset, size); + + memcpy(data, cache->data + cache_offset, cache_size); + return cache_size; +} + +static ssize_t +dso_cache__read(struct dso *dso, struct machine *machine, + u64 offset, u8 *data, ssize_t size) +{ + struct dso_cache *cache; + ssize_t ret; + int fd; + + fd = dso__data_fd(dso, machine); + if (fd < 0) + return -1; + + do { + u64 cache_offset; + + ret = -ENOMEM; + + cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE); + if (!cache) + break; + + cache_offset = offset & DSO__DATA_CACHE_MASK; + ret = -EINVAL; + + if (-1 == lseek(fd, cache_offset, SEEK_SET)) + break; + + ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE); + if (ret <= 0) + break; + + cache->offset = cache_offset; + cache->size = ret; + dso_cache__insert(&dso->cache, cache); + + ret = dso_cache__memcpy(cache, offset, data, size); + + } while (0); + + if (ret <= 0) + free(cache); + + close(fd); + return ret; +} + +static ssize_t dso_cache_read(struct dso *dso, struct machine *machine, + u64 offset, u8 *data, ssize_t size) +{ + struct dso_cache *cache; + + cache = dso_cache__find(&dso->cache, offset); + if (cache) + return dso_cache__memcpy(cache, offset, data, size); + else + return dso_cache__read(dso, machine, offset, data, size); +} + +ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, + u64 offset, u8 *data, ssize_t size) +{ + ssize_t r = 0; + u8 *p = data; + + do { + ssize_t ret; + + ret = dso_cache_read(dso, machine, offset, p, size); + if (ret < 0) + return ret; + + /* Reached EOF, return what we have. */ + if (!ret) + break; + + BUG_ON(ret > size); + + r += ret; + p += ret; + offset += ret; + size -= ret; + + } while (size); + + return r; +} + +ssize_t dso__data_read_addr(struct dso *dso, struct map *map, + struct machine *machine, u64 addr, + u8 *data, ssize_t size) +{ + u64 offset = map->map_ip(map, addr); + return dso__data_read_offset(dso, machine, offset, data, size); +} + +struct map *dso__new_map(const char *name) +{ + struct map *map = NULL; + struct dso *dso = dso__new(name); + + if (dso) + map = map__new2(0, dso, MAP__FUNCTION); + + return map; +} + +struct dso *dso__kernel_findnew(struct machine *machine, const char *name, + const char *short_name, int dso_type) +{ + /* + * The kernel dso could be created by build_id processing. + */ + struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name); + + /* + * We need to run this in all cases, since during the build_id + * processing we had no idea this was the kernel dso. + */ + if (dso != NULL) { + dso__set_short_name(dso, short_name); + dso->kernel = dso_type; + } + + return dso; +} + +void dso__set_long_name(struct dso *dso, char *name) +{ + if (name == NULL) + return; + dso->long_name = name; + dso->long_name_len = strlen(name); +} + +void dso__set_short_name(struct dso *dso, const char *name) +{ + if (name == NULL) + return; + dso->short_name = name; + dso->short_name_len = strlen(name); +} + +static void dso__set_basename(struct dso *dso) +{ + dso__set_short_name(dso, basename(dso->long_name)); +} + +int dso__name_len(const struct dso *dso) +{ + if (!dso) + return strlen("[unknown]"); + if (verbose) + return dso->long_name_len; + + return dso->short_name_len; +} + +bool dso__loaded(const struct dso *dso, enum map_type type) +{ + return dso->loaded & (1 << type); +} + +bool dso__sorted_by_name(const struct dso *dso, enum map_type type) +{ + return dso->sorted_by_name & (1 << type); +} + +void dso__set_sorted_by_name(struct dso *dso, enum map_type type) +{ + dso->sorted_by_name |= (1 << type); +} + +struct dso *dso__new(const char *name) +{ + struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1); + + if (dso != NULL) { + int i; + strcpy(dso->name, name); + dso__set_long_name(dso, dso->name); + dso__set_short_name(dso, dso->name); + for (i = 0; i < MAP__NR_TYPES; ++i) + dso->symbols[i] = dso->symbol_names[i] = RB_ROOT; + dso->cache = RB_ROOT; + dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND; + dso->data_type = DSO_BINARY_TYPE__NOT_FOUND; + dso->loaded = 0; + dso->sorted_by_name = 0; + dso->has_build_id = 0; + dso->kernel = DSO_TYPE_USER; + dso->needs_swap = DSO_SWAP__UNSET; + INIT_LIST_HEAD(&dso->node); + } + + return dso; +} + +void dso__delete(struct dso *dso) +{ + int i; + for (i = 0; i < MAP__NR_TYPES; ++i) + symbols__delete(&dso->symbols[i]); + if (dso->sname_alloc) + free((char *)dso->short_name); + if (dso->lname_alloc) + free(dso->long_name); + dso_cache__free(&dso->cache); + free(dso); +} + +void dso__set_build_id(struct dso *dso, void *build_id) +{ + memcpy(dso->build_id, build_id, sizeof(dso->build_id)); + dso->has_build_id = 1; +} + +bool dso__build_id_equal(const struct dso *dso, u8 *build_id) +{ + return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0; +} + +void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine) +{ + char path[PATH_MAX]; + + if (machine__is_default_guest(machine)) + return; + sprintf(path, "%s/sys/kernel/notes", machine->root_dir); + if (sysfs__read_build_id(path, dso->build_id, + sizeof(dso->build_id)) == 0) + dso->has_build_id = true; +} + +int dso__kernel_module_get_build_id(struct dso *dso, + const char *root_dir) +{ + char filename[PATH_MAX]; + /* + * kernel module short names are of the form "[module]" and + * we need just "module" here. + */ + const char *name = dso->short_name + 1; + + snprintf(filename, sizeof(filename), + "%s/sys/module/%.*s/notes/.note.gnu.build-id", + root_dir, (int)strlen(name) - 1, name); + + if (sysfs__read_build_id(filename, dso->build_id, + sizeof(dso->build_id)) == 0) + dso->has_build_id = true; + + return 0; +} + +bool __dsos__read_build_ids(struct list_head *head, bool with_hits) +{ + bool have_build_id = false; + struct dso *pos; + + list_for_each_entry(pos, head, node) { + if (with_hits && !pos->hit) + continue; + if (pos->has_build_id) { + have_build_id = true; + continue; + } + if (filename__read_build_id(pos->long_name, pos->build_id, + sizeof(pos->build_id)) > 0) { + have_build_id = true; + pos->has_build_id = true; + } + } + + return have_build_id; +} + +void dsos__add(struct list_head *head, struct dso *dso) +{ + list_add_tail(&dso->node, head); +} + +struct dso *dsos__find(struct list_head *head, const char *name) +{ + struct dso *pos; + + list_for_each_entry(pos, head, node) + if (strcmp(pos->long_name, name) == 0) + return pos; + return NULL; +} + +struct dso *__dsos__findnew(struct list_head *head, const char *name) +{ + struct dso *dso = dsos__find(head, name); + + if (!dso) { + dso = dso__new(name); + if (dso != NULL) { + dsos__add(head, dso); + dso__set_basename(dso); + } + } + + return dso; +} + +size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, + bool with_hits) +{ + struct dso *pos; + size_t ret = 0; + + list_for_each_entry(pos, head, node) { + if (with_hits && !pos->hit) + continue; + ret += dso__fprintf_buildid(pos, fp); + ret += fprintf(fp, " %s\n", pos->long_name); + } + return ret; +} + +size_t __dsos__fprintf(struct list_head *head, FILE *fp) +{ + struct dso *pos; + size_t ret = 0; + + list_for_each_entry(pos, head, node) { + int i; + for (i = 0; i < MAP__NR_TYPES; ++i) + ret += dso__fprintf(pos, i, fp); + } + + return ret; +} + +size_t dso__fprintf_buildid(struct dso *dso, FILE *fp) +{ + char sbuild_id[BUILD_ID_SIZE * 2 + 1]; + + build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); + return fprintf(fp, "%s", sbuild_id); +} + +size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp) +{ + struct rb_node *nd; + size_t ret = fprintf(fp, "dso: %s (", dso->short_name); + + if (dso->short_name != dso->long_name) + ret += fprintf(fp, "%s, ", dso->long_name); + ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type], + dso->loaded ? "" : "NOT "); + ret += dso__fprintf_buildid(dso, fp); + ret += fprintf(fp, ")\n"); + for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) { + struct symbol *pos = rb_entry(nd, struct symbol, rb_node); + ret += symbol__fprintf(pos, fp); + } + + return ret; +} diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h new file mode 100644 index 00000000000..e03276940b9 --- /dev/null +++ b/tools/perf/util/dso.h @@ -0,0 +1,148 @@ +#ifndef __PERF_DSO +#define __PERF_DSO + +#include +#include +#include "types.h" +#include "map.h" + +enum dso_binary_type { + DSO_BINARY_TYPE__KALLSYMS = 0, + DSO_BINARY_TYPE__GUEST_KALLSYMS, + DSO_BINARY_TYPE__VMLINUX, + DSO_BINARY_TYPE__GUEST_VMLINUX, + DSO_BINARY_TYPE__JAVA_JIT, + DSO_BINARY_TYPE__DEBUGLINK, + DSO_BINARY_TYPE__BUILD_ID_CACHE, + DSO_BINARY_TYPE__FEDORA_DEBUGINFO, + DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, + DSO_BINARY_TYPE__BUILDID_DEBUGINFO, + DSO_BINARY_TYPE__SYSTEM_PATH_DSO, + DSO_BINARY_TYPE__GUEST_KMODULE, + DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE, + DSO_BINARY_TYPE__NOT_FOUND, +}; + +enum dso_kernel_type { + DSO_TYPE_USER = 0, + DSO_TYPE_KERNEL, + DSO_TYPE_GUEST_KERNEL +}; + +enum dso_swap_type { + DSO_SWAP__UNSET, + DSO_SWAP__NO, + DSO_SWAP__YES, +}; + +#define DSO__SWAP(dso, type, val) \ +({ \ + type ____r = val; \ + BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \ + if (dso->needs_swap == DSO_SWAP__YES) { \ + switch (sizeof(____r)) { \ + case 2: \ + ____r = bswap_16(val); \ + break; \ + case 4: \ + ____r = bswap_32(val); \ + break; \ + case 8: \ + ____r = bswap_64(val); \ + break; \ + default: \ + BUG_ON(1); \ + } \ + } \ + ____r; \ +}) + +#define DSO__DATA_CACHE_SIZE 4096 +#define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1) + +struct dso_cache { + struct rb_node rb_node; + u64 offset; + u64 size; + char data[0]; +}; + +struct dso { + struct list_head node; + struct rb_root symbols[MAP__NR_TYPES]; + struct rb_root symbol_names[MAP__NR_TYPES]; + struct rb_root cache; + enum dso_kernel_type kernel; + enum dso_swap_type needs_swap; + enum dso_binary_type symtab_type; + enum dso_binary_type data_type; + u8 adjust_symbols:1; + u8 has_build_id:1; + u8 hit:1; + u8 annotate_warned:1; + u8 sname_alloc:1; + u8 lname_alloc:1; + u8 sorted_by_name; + u8 loaded; + u8 build_id[BUILD_ID_SIZE]; + const char *short_name; + char *long_name; + u16 long_name_len; + u16 short_name_len; + char name[0]; +}; + +static inline void dso__set_loaded(struct dso *dso, enum map_type type) +{ + dso->loaded |= (1 << type); +} + +struct dso *dso__new(const char *name); +void dso__delete(struct dso *dso); + +void dso__set_short_name(struct dso *dso, const char *name); +void dso__set_long_name(struct dso *dso, char *name); + +int dso__name_len(const struct dso *dso); + +bool dso__loaded(const struct dso *dso, enum map_type type); + +bool dso__sorted_by_name(const struct dso *dso, enum map_type type); +void dso__set_sorted_by_name(struct dso *dso, enum map_type type); +void dso__sort_by_name(struct dso *dso, enum map_type type); + +void dso__set_build_id(struct dso *dso, void *build_id); +bool dso__build_id_equal(const struct dso *dso, u8 *build_id); +void dso__read_running_kernel_build_id(struct dso *dso, + struct machine *machine); +int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir); + +char dso__symtab_origin(const struct dso *dso); +int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, + char *root_dir, char *file, size_t size); + +int dso__data_fd(struct dso *dso, struct machine *machine); +ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, + u64 offset, u8 *data, ssize_t size); +ssize_t dso__data_read_addr(struct dso *dso, struct map *map, + struct machine *machine, u64 addr, + u8 *data, ssize_t size); + +struct map *dso__new_map(const char *name); +struct dso *dso__kernel_findnew(struct machine *machine, const char *name, + const char *short_name, int dso_type); + +void dsos__add(struct list_head *head, struct dso *dso); +struct dso *dsos__find(struct list_head *head, const char *name); +struct dso *__dsos__findnew(struct list_head *head, const char *name); +bool __dsos__read_build_ids(struct list_head *head, bool with_hits); + +size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, + bool with_hits); +size_t __dsos__fprintf(struct list_head *head, FILE *fp); + +size_t dso__fprintf_buildid(struct dso *dso, FILE *fp); +size_t dso__fprintf_symbols_by_name(struct dso *dso, + enum map_type type, FILE *fp); +size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp); +#endif /* __PERF_DSO */ diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index d3b1ecc00cb..624c65e6ab9 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -23,7 +23,6 @@ #define KSYM_NAME_LEN 256 #endif -static void dso_cache__free(struct rb_root *root); static int dso__load_kernel_sym(struct dso *dso, struct map *map, symbol_filter_t filter); static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map, @@ -56,39 +55,6 @@ static enum dso_binary_type binary_type_symtab[] = { #define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab) -static enum dso_binary_type binary_type_data[] = { - DSO_BINARY_TYPE__BUILD_ID_CACHE, - DSO_BINARY_TYPE__SYSTEM_PATH_DSO, - DSO_BINARY_TYPE__NOT_FOUND, -}; - -#define DSO_BINARY_TYPE__DATA_CNT ARRAY_SIZE(binary_type_data) - -int dso__name_len(const struct dso *dso) -{ - if (!dso) - return strlen("[unknown]"); - if (verbose) - return dso->long_name_len; - - return dso->short_name_len; -} - -bool dso__loaded(const struct dso *dso, enum map_type type) -{ - return dso->loaded & (1 << type); -} - -bool dso__sorted_by_name(const struct dso *dso, enum map_type type) -{ - return dso->sorted_by_name & (1 << type); -} - -static void dso__set_sorted_by_name(struct dso *dso, enum map_type type) -{ - dso->sorted_by_name |= (1 << type); -} - bool symbol_type__is_a(char symbol_type, enum map_type map_type) { symbol_type = toupper(symbol_type); @@ -270,7 +236,7 @@ void symbol__delete(struct symbol *sym) free(((void *)sym) - symbol_conf.priv_size); } -static size_t symbol__fprintf(struct symbol *sym, FILE *fp) +size_t symbol__fprintf(struct symbol *sym, FILE *fp) { return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n", sym->start, sym->end, @@ -301,53 +267,7 @@ size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp) return symbol__fprintf_symname_offs(sym, NULL, fp); } -void dso__set_long_name(struct dso *dso, char *name) -{ - if (name == NULL) - return; - dso->long_name = name; - dso->long_name_len = strlen(name); -} - -static void dso__set_short_name(struct dso *dso, const char *name) -{ - if (name == NULL) - return; - dso->short_name = name; - dso->short_name_len = strlen(name); -} - -static void dso__set_basename(struct dso *dso) -{ - dso__set_short_name(dso, basename(dso->long_name)); -} - -struct dso *dso__new(const char *name) -{ - struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1); - - if (dso != NULL) { - int i; - strcpy(dso->name, name); - dso__set_long_name(dso, dso->name); - dso__set_short_name(dso, dso->name); - for (i = 0; i < MAP__NR_TYPES; ++i) - dso->symbols[i] = dso->symbol_names[i] = RB_ROOT; - dso->cache = RB_ROOT; - dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND; - dso->data_type = DSO_BINARY_TYPE__NOT_FOUND; - dso->loaded = 0; - dso->sorted_by_name = 0; - dso->has_build_id = 0; - dso->kernel = DSO_TYPE_USER; - dso->needs_swap = DSO_SWAP__UNSET; - INIT_LIST_HEAD(&dso->node); - } - - return dso; -} - -static void symbols__delete(struct rb_root *symbols) +void symbols__delete(struct rb_root *symbols) { struct symbol *pos; struct rb_node *next = rb_first(symbols); @@ -360,25 +280,6 @@ static void symbols__delete(struct rb_root *symbols) } } -void dso__delete(struct dso *dso) -{ - int i; - for (i = 0; i < MAP__NR_TYPES; ++i) - symbols__delete(&dso->symbols[i]); - if (dso->sname_alloc) - free((char *)dso->short_name); - if (dso->lname_alloc) - free(dso->long_name); - dso_cache__free(&dso->cache); - free(dso); -} - -void dso__set_build_id(struct dso *dso, void *build_id) -{ - memcpy(dso->build_id, build_id, sizeof(dso->build_id)); - dso->has_build_id = 1; -} - void symbols__insert(struct rb_root *symbols, struct symbol *sym) { struct rb_node **p = &symbols->rb_node; @@ -504,14 +405,6 @@ void dso__sort_by_name(struct dso *dso, enum map_type type) &dso->symbols[type]); } -size_t dso__fprintf_buildid(struct dso *dso, FILE *fp) -{ - char sbuild_id[BUILD_ID_SIZE * 2 + 1]; - - build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); - return fprintf(fp, "%s", sbuild_id); -} - size_t dso__fprintf_symbols_by_name(struct dso *dso, enum map_type type, FILE *fp) { @@ -527,25 +420,6 @@ size_t dso__fprintf_symbols_by_name(struct dso *dso, return ret; } -size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp) -{ - struct rb_node *nd; - size_t ret = fprintf(fp, "dso: %s (", dso->short_name); - - if (dso->short_name != dso->long_name) - ret += fprintf(fp, "%s, ", dso->long_name); - ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type], - dso->loaded ? "" : "NOT "); - ret += dso__fprintf_buildid(dso, fp); - ret += fprintf(fp, ")\n"); - for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) { - struct symbol *pos = rb_entry(nd, struct symbol, rb_node); - ret += symbol__fprintf(pos, fp); - } - - return ret; -} - int kallsyms__parse(const char *filename, void *arg, int (*process_symbol)(void *arg, const char *name, char type, u64 start)) @@ -877,136 +751,6 @@ out_failure: return -1; } -bool dso__build_id_equal(const struct dso *dso, u8 *build_id) -{ - return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0; -} - -bool __dsos__read_build_ids(struct list_head *head, bool with_hits) -{ - bool have_build_id = false; - struct dso *pos; - - list_for_each_entry(pos, head, node) { - if (with_hits && !pos->hit) - continue; - if (pos->has_build_id) { - have_build_id = true; - continue; - } - if (filename__read_build_id(pos->long_name, pos->build_id, - sizeof(pos->build_id)) > 0) { - have_build_id = true; - pos->has_build_id = true; - } - } - - return have_build_id; -} - -char dso__symtab_origin(const struct dso *dso) -{ - static const char origin[] = { - [DSO_BINARY_TYPE__KALLSYMS] = 'k', - [DSO_BINARY_TYPE__VMLINUX] = 'v', - [DSO_BINARY_TYPE__JAVA_JIT] = 'j', - [DSO_BINARY_TYPE__DEBUGLINK] = 'l', - [DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B', - [DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f', - [DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u', - [DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b', - [DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd', - [DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K', - [DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g', - [DSO_BINARY_TYPE__GUEST_KMODULE] = 'G', - [DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V', - }; - - if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND) - return '!'; - return origin[dso->symtab_type]; -} - -int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, - char *root_dir, char *file, size_t size) -{ - char build_id_hex[BUILD_ID_SIZE * 2 + 1]; - int ret = 0; - - switch (type) { - case DSO_BINARY_TYPE__DEBUGLINK: { - char *debuglink; - - strncpy(file, dso->long_name, size); - debuglink = file + dso->long_name_len; - while (debuglink != file && *debuglink != '/') - debuglink--; - if (*debuglink == '/') - debuglink++; - filename__read_debuglink(dso->long_name, debuglink, - size - (debuglink - file)); - } - break; - case DSO_BINARY_TYPE__BUILD_ID_CACHE: - /* skip the locally configured cache if a symfs is given */ - if (symbol_conf.symfs[0] || - (dso__build_id_filename(dso, file, size) == NULL)) - ret = -1; - break; - - case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: - snprintf(file, size, "%s/usr/lib/debug%s.debug", - symbol_conf.symfs, dso->long_name); - break; - - case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: - snprintf(file, size, "%s/usr/lib/debug%s", - symbol_conf.symfs, dso->long_name); - break; - - case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: - if (!dso->has_build_id) { - ret = -1; - break; - } - - build_id__sprintf(dso->build_id, - sizeof(dso->build_id), - build_id_hex); - snprintf(file, size, - "%s/usr/lib/debug/.build-id/%.2s/%s.debug", - symbol_conf.symfs, build_id_hex, build_id_hex + 2); - break; - - case DSO_BINARY_TYPE__SYSTEM_PATH_DSO: - snprintf(file, size, "%s%s", - symbol_conf.symfs, dso->long_name); - break; - - case DSO_BINARY_TYPE__GUEST_KMODULE: - snprintf(file, size, "%s%s%s", symbol_conf.symfs, - root_dir, dso->long_name); - break; - - case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE: - snprintf(file, size, "%s%s", symbol_conf.symfs, - dso->long_name); - break; - - default: - case DSO_BINARY_TYPE__KALLSYMS: - case DSO_BINARY_TYPE__VMLINUX: - case DSO_BINARY_TYPE__GUEST_KALLSYMS: - case DSO_BINARY_TYPE__GUEST_VMLINUX: - case DSO_BINARY_TYPE__JAVA_JIT: - case DSO_BINARY_TYPE__NOT_FOUND: - ret = -1; - break; - } - - return ret; -} - int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) { char *name; @@ -1142,27 +886,6 @@ struct map *map_groups__find_by_name(struct map_groups *mg, return NULL; } -static int dso__kernel_module_get_build_id(struct dso *dso, - const char *root_dir) -{ - char filename[PATH_MAX]; - /* - * kernel module short names are of the form "[module]" and - * we need just "module" here. - */ - const char *name = dso->short_name + 1; - - snprintf(filename, sizeof(filename), - "%s/sys/module/%.*s/notes/.note.gnu.build-id", - root_dir, (int)strlen(name) - 1, name); - - if (sysfs__read_build_id(filename, dso->build_id, - sizeof(dso->build_id)) == 0) - dso->has_build_id = true; - - return 0; -} - static int map_groups__set_modules_path_dir(struct map_groups *mg, const char *dir_name) { @@ -1576,50 +1299,6 @@ out_try_fixup: return err; } -void dsos__add(struct list_head *head, struct dso *dso) -{ - list_add_tail(&dso->node, head); -} - -struct dso *dsos__find(struct list_head *head, const char *name) -{ - struct dso *pos; - - list_for_each_entry(pos, head, node) - if (strcmp(pos->long_name, name) == 0) - return pos; - return NULL; -} - -struct dso *__dsos__findnew(struct list_head *head, const char *name) -{ - struct dso *dso = dsos__find(head, name); - - if (!dso) { - dso = dso__new(name); - if (dso != NULL) { - dsos__add(head, dso); - dso__set_basename(dso); - } - } - - return dso; -} - -size_t __dsos__fprintf(struct list_head *head, FILE *fp) -{ - struct dso *pos; - size_t ret = 0; - - list_for_each_entry(pos, head, node) { - int i; - for (i = 0; i < MAP__NR_TYPES; ++i) - ret += dso__fprintf(pos, i, fp); - } - - return ret; -} - size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp) { struct rb_node *nd; @@ -1634,21 +1313,6 @@ size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp) return ret; } -static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, - bool with_hits) -{ - struct dso *pos; - size_t ret = 0; - - list_for_each_entry(pos, head, node) { - if (with_hits && !pos->hit) - continue; - ret += dso__fprintf_buildid(pos, fp); - ret += fprintf(fp, " %s\n", pos->long_name); - } - return ret; -} - size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp, bool with_hits) { @@ -1669,39 +1333,6 @@ size_t machines__fprintf_dsos_buildid(struct rb_root *machines, return ret; } -static struct dso* -dso__kernel_findnew(struct machine *machine, const char *name, - const char *short_name, int dso_type) -{ - /* - * The kernel dso could be created by build_id processing. - */ - struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name); - - /* - * We need to run this in all cases, since during the build_id - * processing we had no idea this was the kernel dso. - */ - if (dso != NULL) { - dso__set_short_name(dso, short_name); - dso->kernel = dso_type; - } - - return dso; -} - -void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine) -{ - char path[PATH_MAX]; - - if (machine__is_default_guest(machine)) - return; - sprintf(path, "%s/sys/kernel/notes", machine->root_dir); - if (sysfs__read_build_id(path, dso->build_id, - sizeof(dso->build_id)) == 0) - dso->has_build_id = true; -} - static struct dso *machine__get_kernel(struct machine *machine) { const char *vmlinux_name = NULL; @@ -2144,229 +1775,3 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type, return ret; } - -struct map *dso__new_map(const char *name) -{ - struct map *map = NULL; - struct dso *dso = dso__new(name); - - if (dso) - map = map__new2(0, dso, MAP__FUNCTION); - - return map; -} - -static int open_dso(struct dso *dso, struct machine *machine) -{ - char *root_dir = (char *) ""; - char *name; - int fd; - - name = malloc(PATH_MAX); - if (!name) - return -ENOMEM; - - if (machine) - root_dir = machine->root_dir; - - if (dso__binary_type_file(dso, dso->data_type, - root_dir, name, PATH_MAX)) { - free(name); - return -EINVAL; - } - - fd = open(name, O_RDONLY); - free(name); - return fd; -} - -int dso__data_fd(struct dso *dso, struct machine *machine) -{ - int i = 0; - - if (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND) - return open_dso(dso, machine); - - do { - int fd; - - dso->data_type = binary_type_data[i++]; - - fd = open_dso(dso, machine); - if (fd >= 0) - return fd; - - } while (dso->data_type != DSO_BINARY_TYPE__NOT_FOUND); - - return -EINVAL; -} - -static void -dso_cache__free(struct rb_root *root) -{ - struct rb_node *next = rb_first(root); - - while (next) { - struct dso_cache *cache; - - cache = rb_entry(next, struct dso_cache, rb_node); - next = rb_next(&cache->rb_node); - rb_erase(&cache->rb_node, root); - free(cache); - } -} - -static struct dso_cache* -dso_cache__find(struct rb_root *root, u64 offset) -{ - struct rb_node **p = &root->rb_node; - struct rb_node *parent = NULL; - struct dso_cache *cache; - - while (*p != NULL) { - u64 end; - - parent = *p; - cache = rb_entry(parent, struct dso_cache, rb_node); - end = cache->offset + DSO__DATA_CACHE_SIZE; - - if (offset < cache->offset) - p = &(*p)->rb_left; - else if (offset >= end) - p = &(*p)->rb_right; - else - return cache; - } - return NULL; -} - -static void -dso_cache__insert(struct rb_root *root, struct dso_cache *new) -{ - struct rb_node **p = &root->rb_node; - struct rb_node *parent = NULL; - struct dso_cache *cache; - u64 offset = new->offset; - - while (*p != NULL) { - u64 end; - - parent = *p; - cache = rb_entry(parent, struct dso_cache, rb_node); - end = cache->offset + DSO__DATA_CACHE_SIZE; - - if (offset < cache->offset) - p = &(*p)->rb_left; - else if (offset >= end) - p = &(*p)->rb_right; - } - - rb_link_node(&new->rb_node, parent, p); - rb_insert_color(&new->rb_node, root); -} - -static ssize_t -dso_cache__memcpy(struct dso_cache *cache, u64 offset, - u8 *data, u64 size) -{ - u64 cache_offset = offset - cache->offset; - u64 cache_size = min(cache->size - cache_offset, size); - - memcpy(data, cache->data + cache_offset, cache_size); - return cache_size; -} - -static ssize_t -dso_cache__read(struct dso *dso, struct machine *machine, - u64 offset, u8 *data, ssize_t size) -{ - struct dso_cache *cache; - ssize_t ret; - int fd; - - fd = dso__data_fd(dso, machine); - if (fd < 0) - return -1; - - do { - u64 cache_offset; - - ret = -ENOMEM; - - cache = zalloc(sizeof(*cache) + DSO__DATA_CACHE_SIZE); - if (!cache) - break; - - cache_offset = offset & DSO__DATA_CACHE_MASK; - ret = -EINVAL; - - if (-1 == lseek(fd, cache_offset, SEEK_SET)) - break; - - ret = read(fd, cache->data, DSO__DATA_CACHE_SIZE); - if (ret <= 0) - break; - - cache->offset = cache_offset; - cache->size = ret; - dso_cache__insert(&dso->cache, cache); - - ret = dso_cache__memcpy(cache, offset, data, size); - - } while (0); - - if (ret <= 0) - free(cache); - - close(fd); - return ret; -} - -static ssize_t dso_cache_read(struct dso *dso, struct machine *machine, - u64 offset, u8 *data, ssize_t size) -{ - struct dso_cache *cache; - - cache = dso_cache__find(&dso->cache, offset); - if (cache) - return dso_cache__memcpy(cache, offset, data, size); - else - return dso_cache__read(dso, machine, offset, data, size); -} - -ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, - u64 offset, u8 *data, ssize_t size) -{ - ssize_t r = 0; - u8 *p = data; - - do { - ssize_t ret; - - ret = dso_cache_read(dso, machine, offset, p, size); - if (ret < 0) - return ret; - - /* Reached EOF, return what we have. */ - if (!ret) - break; - - BUG_ON(ret > size); - - r += ret; - p += ret; - offset += ret; - size -= ret; - - } while (size); - - return r; -} - -ssize_t dso__data_read_addr(struct dso *dso, struct map *map, - struct machine *machine, u64 addr, - u8 *data, ssize_t size) -{ - u64 offset = map->map_ip(map, addr); - return dso__data_read_offset(dso, machine, offset, data, size); -} diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 45d3df8d36d..863b05bea5f 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -19,6 +19,8 @@ #include #endif +#include "dso.h" + #ifdef HAVE_CPLUS_DEMANGLE extern char *cplus_demangle(const char *, int); @@ -70,6 +72,7 @@ struct symbol { }; void symbol__delete(struct symbol *sym); +void symbols__delete(struct rb_root *symbols); static inline size_t symbol__size(const struct symbol *sym) { @@ -160,70 +163,6 @@ struct addr_location { s32 cpu; }; -enum dso_binary_type { - DSO_BINARY_TYPE__KALLSYMS = 0, - DSO_BINARY_TYPE__GUEST_KALLSYMS, - DSO_BINARY_TYPE__VMLINUX, - DSO_BINARY_TYPE__GUEST_VMLINUX, - DSO_BINARY_TYPE__JAVA_JIT, - DSO_BINARY_TYPE__DEBUGLINK, - DSO_BINARY_TYPE__BUILD_ID_CACHE, - DSO_BINARY_TYPE__FEDORA_DEBUGINFO, - DSO_BINARY_TYPE__UBUNTU_DEBUGINFO, - DSO_BINARY_TYPE__BUILDID_DEBUGINFO, - DSO_BINARY_TYPE__SYSTEM_PATH_DSO, - DSO_BINARY_TYPE__GUEST_KMODULE, - DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE, - DSO_BINARY_TYPE__NOT_FOUND, -}; - -enum dso_kernel_type { - DSO_TYPE_USER = 0, - DSO_TYPE_KERNEL, - DSO_TYPE_GUEST_KERNEL -}; - -enum dso_swap_type { - DSO_SWAP__UNSET, - DSO_SWAP__NO, - DSO_SWAP__YES, -}; - -#define DSO__DATA_CACHE_SIZE 4096 -#define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1) - -struct dso_cache { - struct rb_node rb_node; - u64 offset; - u64 size; - char data[0]; -}; - -struct dso { - struct list_head node; - struct rb_root symbols[MAP__NR_TYPES]; - struct rb_root symbol_names[MAP__NR_TYPES]; - struct rb_root cache; - enum dso_kernel_type kernel; - enum dso_swap_type needs_swap; - enum dso_binary_type symtab_type; - enum dso_binary_type data_type; - u8 adjust_symbols:1; - u8 has_build_id:1; - u8 hit:1; - u8 annotate_warned:1; - u8 sname_alloc:1; - u8 lname_alloc:1; - u8 sorted_by_name; - u8 loaded; - u8 build_id[BUILD_ID_SIZE]; - const char *short_name; - char *long_name; - u16 long_name_len; - u16 short_name_len; - char name[0]; -}; - struct symsrc { char *name; int fd; @@ -254,47 +193,6 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, bool symsrc__has_symtab(struct symsrc *ss); bool symsrc__possibly_runtime(struct symsrc *ss); -#define DSO__SWAP(dso, type, val) \ -({ \ - type ____r = val; \ - BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \ - if (dso->needs_swap == DSO_SWAP__YES) { \ - switch (sizeof(____r)) { \ - case 2: \ - ____r = bswap_16(val); \ - break; \ - case 4: \ - ____r = bswap_32(val); \ - break; \ - case 8: \ - ____r = bswap_64(val); \ - break; \ - default: \ - BUG_ON(1); \ - } \ - } \ - ____r; \ -}) - -struct dso *dso__new(const char *name); -void dso__delete(struct dso *dso); - -int dso__name_len(const struct dso *dso); - -bool dso__loaded(const struct dso *dso, enum map_type type); -bool dso__sorted_by_name(const struct dso *dso, enum map_type type); - -static inline void dso__set_loaded(struct dso *dso, enum map_type type) -{ - dso->loaded |= (1 << type); -} - -void dso__sort_by_name(struct dso *dso, enum map_type type); - -void dsos__add(struct list_head *head, struct dso *dso); -struct dso *dsos__find(struct list_head *head, const char *name); -struct dso *__dsos__findnew(struct list_head *head, const char *name); - int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter); int dso__load_vmlinux(struct dso *dso, struct map *map, const char *vmlinux, symbol_filter_t filter); @@ -307,25 +205,12 @@ int machine__load_kallsyms(struct machine *machine, const char *filename, int machine__load_vmlinux_path(struct machine *machine, enum map_type type, symbol_filter_t filter); -size_t __dsos__fprintf(struct list_head *head, FILE *fp); - size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp, bool with_hits); size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp); size_t machines__fprintf_dsos_buildid(struct rb_root *machines, FILE *fp, bool with_hits); -size_t dso__fprintf_buildid(struct dso *dso, FILE *fp); -size_t dso__fprintf_symbols_by_name(struct dso *dso, - enum map_type type, FILE *fp); -size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp); - -char dso__symtab_origin(const struct dso *dso); -void dso__set_long_name(struct dso *dso, char *name); -void dso__set_build_id(struct dso *dso, void *build_id); -bool dso__build_id_equal(const struct dso *dso, u8 *build_id); -void dso__read_running_kernel_build_id(struct dso *dso, - struct machine *machine); -struct map *dso__new_map(const char *name); + struct symbol *dso__find_symbol(struct dso *dso, enum map_type type, u64 addr); struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, @@ -333,7 +218,6 @@ struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, int filename__read_build_id(const char *filename, void *bf, size_t size); int sysfs__read_build_id(const char *filename, void *bf, size_t size); -bool __dsos__read_build_ids(struct list_head *head, bool with_hits); int kallsyms__parse(const char *filename, void *arg, int (*process_symbol)(void *arg, const char *name, char type, u64 start)); @@ -355,19 +239,11 @@ struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name); size_t symbol__fprintf_symname_offs(const struct symbol *sym, const struct addr_location *al, FILE *fp); size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp); +size_t symbol__fprintf(struct symbol *sym, FILE *fp); bool symbol_type__is_a(char symbol_type, enum map_type map_type); size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp); -int dso__binary_type_file(struct dso *dso, enum dso_binary_type type, - char *root_dir, char *file, size_t size); - -int dso__data_fd(struct dso *dso, struct machine *machine); -ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, - u64 offset, u8 *data, ssize_t size); -ssize_t dso__data_read_addr(struct dso *dso, struct map *map, - struct machine *machine, u64 addr, - u8 *data, ssize_t size); int dso__test_data(void); int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, struct symsrc *runtime_ss, symbol_filter_t filter, -- cgit v1.2.3 From 70cb4e963f77dae90ae2aa3dd9385a43737c469f Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 30 Oct 2012 11:56:02 +0800 Subject: perf tools: Add a global variable "const char *input_name" Currently many perf commands annotate/evlist/report/script/lock etc all support "-i" option to chose a specific perf data, and all of them create a local "input_name" to save the file name for that perf data. Since most of these commands need it, we can add a global variable for it, also it can some other benefits: 1. When calling script browser inside hists/annotation browser, it needs to know the perf data file name to run that script. 2. For further feature like runtime switching to another perf data file, this variable can also help. Signed-off-by: Feng Tang Cc: Andi Kleen Cc: Ingo Molnar Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351569369-26732-2-git-send-email-feng.tang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 5 ++--- tools/perf/builtin-buildid-list.c | 6 ++---- tools/perf/builtin-evlist.c | 5 ++--- tools/perf/builtin-kmem.c | 5 ++--- tools/perf/builtin-lock.c | 2 -- tools/perf/builtin-report.c | 13 ++++++------- tools/perf/builtin-sched.c | 5 ++--- tools/perf/builtin-script.c | 1 - tools/perf/builtin-timechart.c | 5 ++--- tools/perf/perf.c | 1 + tools/perf/perf.h | 1 + 11 files changed, 20 insertions(+), 29 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index c4bb6457b19..cb234765ce3 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -34,7 +34,6 @@ struct perf_annotate { struct perf_tool tool; - char const *input_name; bool force, use_tui, use_stdio; bool full_paths; bool print_line; @@ -175,7 +174,7 @@ static int __cmd_annotate(struct perf_annotate *ann) struct perf_evsel *pos; u64 total_nr_samples; - session = perf_session__new(ann->input_name, O_RDONLY, + session = perf_session__new(input_name, O_RDONLY, ann->force, false, &ann->tool); if (session == NULL) return -ENOMEM; @@ -260,7 +259,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) }, }; const struct option options[] = { - OPT_STRING('i', "input", &annotate.input_name, "file", + OPT_STRING('i', "input", &input_name, "file", "input file name"), OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", "only consider symbols in these dsos"), diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index a0e94fffa03..a82d99fec83 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c @@ -44,8 +44,7 @@ static int filename__fprintf_build_id(const char *name, FILE *fp) return fprintf(fp, "%s\n", sbuild_id); } -static int perf_session__list_build_ids(const char *input_name, - bool force, bool with_hits) +static int perf_session__list_build_ids(bool force, bool with_hits) { struct perf_session *session; @@ -81,7 +80,6 @@ int cmd_buildid_list(int argc, const char **argv, bool show_kernel = false; bool with_hits = false; bool force = false; - const char *input_name = NULL; const struct option options[] = { OPT_BOOLEAN('H', "with-hits", &with_hits, "Show only DSOs with hits"), OPT_STRING('i', "input", &input_name, "file", "input file name"), @@ -101,5 +99,5 @@ int cmd_buildid_list(int argc, const char **argv, if (show_kernel) return sysfs__fprintf_build_id(stdout); - return perf_session__list_build_ids(input_name, force, with_hits); + return perf_session__list_build_ids(force, with_hits); } diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index 997afb82691..c20f1dcfb7e 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c @@ -48,12 +48,12 @@ static int __if_print(bool *first, const char *field, u64 value) #define if_print(field) __if_print(&first, #field, pos->attr.field) -static int __cmd_evlist(const char *input_name, struct perf_attr_details *details) +static int __cmd_evlist(const char *file_name, struct perf_attr_details *details) { struct perf_session *session; struct perf_evsel *pos; - session = perf_session__new(input_name, O_RDONLY, 0, false, NULL); + session = perf_session__new(file_name, O_RDONLY, 0, false, NULL); if (session == NULL) return -ENOMEM; @@ -111,7 +111,6 @@ static int __cmd_evlist(const char *input_name, struct perf_attr_details *detail int cmd_evlist(int argc, const char **argv, const char *prefix __maybe_unused) { struct perf_attr_details details = { .verbose = false, }; - const char *input_name = NULL; const struct option options[] = { OPT_STRING('i', "input", &input_name, "file", "Input file name"), OPT_BOOLEAN('F', "freq", &details.freq, "Show the sample frequency"), diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 14bf82f6365..0b4b796167b 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -477,7 +477,7 @@ static void sort_result(void) __sort_result(&root_caller_stat, &root_caller_sorted, &caller_sort); } -static int __cmd_kmem(const char *input_name) +static int __cmd_kmem(void) { int err = -EINVAL; struct perf_session *session; @@ -743,7 +743,6 @@ static int __cmd_record(int argc, const char **argv) int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) { const char * const default_sort_order = "frag,hit,bytes"; - const char *input_name = NULL; const struct option kmem_options[] = { OPT_STRING('i', "input", &input_name, "file", "input file name"), OPT_CALLBACK_NOOPT(0, "caller", NULL, NULL, @@ -779,7 +778,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) if (list_empty(&alloc_sort)) setup_sorting(&alloc_sort, default_sort_order); - return __cmd_kmem(input_name); + return __cmd_kmem(); } else usage_with_options(kmem_usage, kmem_options); diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 6f5f328157a..42583006974 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -335,8 +335,6 @@ alloc_failed: return NULL; } -static const char *input_name; - struct trace_lock_handler { int (*acquire_event)(struct perf_evsel *evsel, struct perf_sample *sample); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 90d1162bb8b..f07eae73e69 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -40,7 +40,6 @@ struct perf_report { struct perf_tool tool; struct perf_session *session; - char const *input_name; bool force, use_tui, use_gtk, use_stdio; bool hide_unresolved; bool dont_use_callchains; @@ -571,7 +570,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) .pretty_printing_style = "normal", }; const struct option options[] = { - OPT_STRING('i', "input", &report.input_name, "file", + OPT_STRING('i', "input", &input_name, "file", "input file name"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), @@ -657,13 +656,13 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) if (report.inverted_callchain) callchain_param.order = ORDER_CALLER; - if (!report.input_name || !strlen(report.input_name)) { + if (!input_name || !strlen(input_name)) { if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode)) - report.input_name = "-"; + input_name = "-"; else - report.input_name = "perf.data"; + input_name = "perf.data"; } - session = perf_session__new(report.input_name, O_RDONLY, + session = perf_session__new(input_name, O_RDONLY, report.force, false, &report.tool); if (session == NULL) return -ENOMEM; @@ -694,7 +693,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) } - if (strcmp(report.input_name, "-") != 0) + if (strcmp(input_name, "-") != 0) setup_browser(true); else { use_browser = 0; diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 30e53360d3c..cc28b85dabd 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -120,7 +120,6 @@ struct trace_sched_handler { struct perf_sched { struct perf_tool tool; - const char *input_name; const char *sort_order; unsigned long nr_tasks; struct task_desc *pid_to_task[MAX_PID]; @@ -1460,7 +1459,7 @@ static int perf_sched__read_events(struct perf_sched *sched, bool destroy, }; struct perf_session *session; - session = perf_session__new(sched->input_name, O_RDONLY, 0, false, &sched->tool); + session = perf_session__new(input_name, O_RDONLY, 0, false, &sched->tool); if (session == NULL) { pr_debug("No Memory for session\n"); return -1; @@ -1708,7 +1707,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) OPT_END() }; const struct option sched_options[] = { - OPT_STRING('i', "input", &sched.input_name, "file", + OPT_STRING('i', "input", &input_name, "file", "input file name"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 04ceb0779d3..7c6e4b2f401 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1175,7 +1175,6 @@ static int have_cmd(int argc, const char **argv) int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) { bool show_full_info = false; - const char *input_name = NULL; char *rec_script_path = NULL; char *rep_script_path = NULL; struct perf_session *session; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index f251b613b2f..ab4cf232b85 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -965,7 +965,7 @@ static void write_svg_file(const char *filename) svg_close(); } -static int __cmd_timechart(const char *input_name, const char *output_name) +static int __cmd_timechart(const char *output_name) { struct perf_tool perf_timechart = { .comm = process_comm_event, @@ -1061,7 +1061,6 @@ parse_process(const struct option *opt __maybe_unused, const char *arg, int cmd_timechart(int argc, const char **argv, const char *prefix __maybe_unused) { - const char *input_name; const char *output_name = "output.svg"; const struct option options[] = { OPT_STRING('i', "input", &input_name, "file", "input file name"), @@ -1092,5 +1091,5 @@ int cmd_timechart(int argc, const char **argv, setup_pager(); - return __cmd_timechart(input_name, output_name); + return __cmd_timechart(output_name); } diff --git a/tools/perf/perf.c b/tools/perf/perf.c index d480d8a412b..e9683738d89 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -24,6 +24,7 @@ const char perf_more_info_string[] = int use_browser = -1; static int use_pager = -1; +const char *input_name; struct cmd_struct { const char *cmd; diff --git a/tools/perf/perf.h b/tools/perf/perf.h index c50985eaec4..469fbf2daea 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -208,6 +208,7 @@ struct branch_stack { struct branch_entry entries[0]; }; +extern const char *input_name; extern bool perf_host, perf_guest; extern const char perf_version_string[]; -- cgit v1.2.3 From 49e639e256ea18fb92f609dd6be09883cd9d05aa Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 30 Oct 2012 11:56:03 +0800 Subject: perf script: Add more filter to find_scripts() As suggested by Arnaldo, many scripts have their own usages and need capture specific events or tracepoints, so only those scripts whose target events match the events in current perf data file should be listed in the script browser menu. This patch will add the event match checking, by opening "xxx-record" script to cherry pick out all events name and comparing them with those inside the perf data file. Signed-off-by: Feng Tang Cc: Andi Kleen Cc: Ingo Molnar Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351569369-26732-3-git-send-email-feng.tang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 82 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 7c6e4b2f401..b363e7b292b 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1029,6 +1029,68 @@ static int list_available_scripts(const struct option *opt __maybe_unused, exit(0); } +/* + * Some scripts specify the required events in their "xxx-record" file, + * this function will check if the events in perf.data match those + * mentioned in the "xxx-record". + * + * Fixme: All existing "xxx-record" are all in good formats "-e event ", + * which is covered well now. And new parsing code should be added to + * cover the future complexing formats like event groups etc. + */ +static int check_ev_match(char *dir_name, char *scriptname, + struct perf_session *session) +{ + char filename[MAXPATHLEN], evname[128]; + char line[BUFSIZ], *p; + struct perf_evsel *pos; + int match, len; + FILE *fp; + + sprintf(filename, "%s/bin/%s-record", dir_name, scriptname); + + fp = fopen(filename, "r"); + if (!fp) + return -1; + + while (fgets(line, sizeof(line), fp)) { + p = ltrim(line); + if (*p == '#') + continue; + + while (strlen(p)) { + p = strstr(p, "-e"); + if (!p) + break; + + p += 2; + p = ltrim(p); + len = strcspn(p, " \t"); + if (!len) + break; + + snprintf(evname, len + 1, "%s", p); + + match = 0; + list_for_each_entry(pos, + &session->evlist->entries, node) { + if (!strcmp(perf_evsel__name(pos), evname)) { + match = 1; + break; + } + } + + if (!match) { + fclose(fp); + return -1; + } + } + } + + fclose(fp); + return 0; +} + /* * Return -1 if none is found, otherwise the actual scripts number. * @@ -1039,17 +1101,23 @@ static int list_available_scripts(const struct option *opt __maybe_unused, int find_scripts(char **scripts_array, char **scripts_path_array) { struct dirent *script_next, *lang_next, script_dirent, lang_dirent; - char scripts_path[MAXPATHLEN]; + char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; DIR *scripts_dir, *lang_dir; - char lang_path[MAXPATHLEN]; + struct perf_session *session; char *temp; int i = 0; + session = perf_session__new(input_name, O_RDONLY, 0, false, NULL); + if (!session) + return -1; + snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); scripts_dir = opendir(scripts_path); - if (!scripts_dir) + if (!scripts_dir) { + perf_session__delete(session); return -1; + } for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, @@ -1077,10 +1145,18 @@ int find_scripts(char **scripts_array, char **scripts_path_array) snprintf(scripts_array[i], (temp - script_dirent.d_name) + 1, "%s", script_dirent.d_name); + + if (check_ev_match(lang_path, + scripts_array[i], session)) + continue; + i++; } + closedir(lang_dir); } + closedir(scripts_dir); + perf_session__delete(session); return i; } -- cgit v1.2.3 From 66517826664fa910d4bc5f32a5abff6bcd8657c5 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 30 Oct 2012 11:56:04 +0800 Subject: perf scripts browser: Add a browser for perf script Create a script browser, so that user can check all the available scripts for current perf data file and run them inside the main perf report or annotation browsers, for all perf samples or for samples belong to one thread/symbol. Please be noted: current script browser is only for report use, and doesn't cover the record phase, IOW it must run against one existing perf data file. The work flow is, users can use function key to list all the available scripts for current perf data file in system and chose one, which will be executed with popen("perf script -s xxx.xx",) and all the output lines are put into one ui browser, pressing 'q' or left arrow key will make it return to previous browser. Signed-off-by: Feng Tang Cc: Andi Kleen Cc: Ingo Molnar Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351569369-26732-4-git-send-email-feng.tang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 4 + tools/perf/ui/browsers/scripts.c | 189 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/hist.h | 7 ++ 3 files changed, 200 insertions(+) create mode 100644 tools/perf/ui/browsers/scripts.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index ec63d53cd87..7e25f59e5e8 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -593,6 +593,7 @@ ifndef NO_NEWT LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o LIB_OBJS += $(OUTPUT)ui/browsers/hists.o LIB_OBJS += $(OUTPUT)ui/browsers/map.o + LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o LIB_OBJS += $(OUTPUT)ui/progress.o LIB_OBJS += $(OUTPUT)ui/util.o LIB_OBJS += $(OUTPUT)ui/tui/setup.o @@ -909,6 +910,9 @@ $(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< +$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS + $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< + $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c new file mode 100644 index 00000000000..cbbd44b0d93 --- /dev/null +++ b/tools/perf/ui/browsers/scripts.c @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#include +#include "../../util/sort.h" +#include "../../util/util.h" +#include "../../util/hist.h" +#include "../../util/debug.h" +#include "../../util/symbol.h" +#include "../browser.h" +#include "../helpline.h" +#include "../libslang.h" + +/* 2048 lines should be enough for a script output */ +#define MAX_LINES 2048 + +/* 160 bytes for one output line */ +#define AVERAGE_LINE_LEN 160 + +struct script_line { + struct list_head node; + char line[AVERAGE_LINE_LEN]; +}; + +struct perf_script_browser { + struct ui_browser b; + struct list_head entries; + const char *script_name; + int nr_lines; +}; + +#define SCRIPT_NAMELEN 128 +#define SCRIPT_MAX_NO 64 +/* + * Usually the full path for a script is: + * /home/username/libexec/perf-core/scripts/python/xxx.py + * /home/username/libexec/perf-core/scripts/perl/xxx.pl + * So 256 should be long enough to contain the full path. + */ +#define SCRIPT_FULLPATH_LEN 256 + +/* + * When success, will copy the full path of the selected script + * into the buffer pointed by script_name, and return 0. + * Return -1 on failure. + */ +static int list_scripts(char *script_name) +{ + char *buf, *names[SCRIPT_MAX_NO], *paths[SCRIPT_MAX_NO]; + int i, num, choice, ret = -1; + + /* Preset the script name to SCRIPT_NAMELEN */ + buf = malloc(SCRIPT_MAX_NO * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN)); + if (!buf) + return ret; + + for (i = 0; i < SCRIPT_MAX_NO; i++) { + names[i] = buf + i * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN); + paths[i] = names[i] + SCRIPT_NAMELEN; + } + + num = find_scripts(names, paths); + if (num > 0) { + choice = ui__popup_menu(num, names); + if (choice < num && choice >= 0) { + strcpy(script_name, paths[choice]); + ret = 0; + } + } + + free(buf); + return ret; +} + +static void script_browser__write(struct ui_browser *browser, + void *entry, int row) +{ + struct script_line *sline = list_entry(entry, struct script_line, node); + bool current_entry = ui_browser__is_current_entry(browser, row); + + ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED : + HE_COLORSET_NORMAL); + + slsmg_write_nstring(sline->line, browser->width); +} + +static int script_browser__run(struct perf_script_browser *self) +{ + int key; + + if (ui_browser__show(&self->b, self->script_name, + "Press <- or ESC to exit") < 0) + return -1; + + while (1) { + key = ui_browser__run(&self->b, 0); + + /* We can add some special key handling here if needed */ + break; + } + + ui_browser__hide(&self->b); + return key; +} + + +int script_browse(const char *script_opt) +{ + char cmd[SCRIPT_FULLPATH_LEN*2], script_name[SCRIPT_FULLPATH_LEN]; + char *line = NULL; + size_t len = 0; + ssize_t retlen; + int ret = -1, nr_entries = 0; + FILE *fp; + void *buf; + struct script_line *sline; + + struct perf_script_browser script = { + .b = { + .refresh = ui_browser__list_head_refresh, + .seek = ui_browser__list_head_seek, + .write = script_browser__write, + }, + .script_name = script_name, + }; + + INIT_LIST_HEAD(&script.entries); + + /* Save each line of the output in one struct script_line object. */ + buf = zalloc((sizeof(*sline)) * MAX_LINES); + if (!buf) + return -1; + sline = buf; + + memset(script_name, 0, SCRIPT_FULLPATH_LEN); + if (list_scripts(script_name)) + goto exit; + + sprintf(cmd, "perf script -s %s ", script_name); + + if (script_opt) + strcat(cmd, script_opt); + + if (input_name) { + strcat(cmd, " -i "); + strcat(cmd, input_name); + } + + strcat(cmd, " 2>&1"); + + fp = popen(cmd, "r"); + if (!fp) + goto exit; + + while ((retlen = getline(&line, &len, fp)) != -1) { + strncpy(sline->line, line, AVERAGE_LINE_LEN); + + /* If one output line is very large, just cut it short */ + if (retlen >= AVERAGE_LINE_LEN) { + sline->line[AVERAGE_LINE_LEN - 1] = '\0'; + sline->line[AVERAGE_LINE_LEN - 2] = '\n'; + } + list_add_tail(&sline->node, &script.entries); + + if (script.b.width < retlen) + script.b.width = retlen; + + if (nr_entries++ >= MAX_LINES - 1) + break; + sline++; + } + + if (script.b.width > AVERAGE_LINE_LEN) + script.b.width = AVERAGE_LINE_LEN; + + if (line) + free(line); + pclose(fp); + + script.nr_lines = nr_entries; + script.b.nr_entries = nr_entries; + script.b.entries = &script.entries; + + ret = script_browser__run(&script); +exit: + free(buf); + return ret; +} diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index c751624d415..b8746097173 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -165,6 +165,7 @@ int hist_entry__tui_annotate(struct hist_entry *he, int evidx, int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, void(*timer)(void *arg), void *arg, int refresh); +int script_browse(const char *script_opt); #else static inline int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, @@ -186,6 +187,12 @@ static inline int hist_entry__tui_annotate(struct hist_entry *self { return 0; } + +static inline int script_browse(const char *script_opt) +{ + return 0; +} + #define K_LEFT -1 #define K_RIGHT -2 #endif -- cgit v1.2.3 From 79ee47faa77706f568f0329b7475c123b67a3b4a Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 30 Oct 2012 11:56:05 +0800 Subject: perf annotate browser: Integrate script browser into annotation browser Integrate the script browser into annotation, users can press function key 'r' to list all perf scripts and select one of them to run that script, the output will be shown in a separate browser. Signed-off-by: Feng Tang Cc: Andi Kleen Cc: Ingo Molnar Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351569369-26732-5-git-send-email-feng.tang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/annotate.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 8f8cd2d73b3..28f8aab73ae 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -676,8 +676,14 @@ static int annotate_browser__run(struct annotate_browser *browser, int evidx, "o Toggle disassembler output/simplified view\n" "s Toggle source code view\n" "/ Search string\n" + "r Run available scripts\n" "? Search previous string\n"); continue; + case 'r': + { + script_browse(NULL); + continue; + } case 'H': nd = browser->curr_hot; break; -- cgit v1.2.3 From cdbab7c201ab38f7b8d248ebf289025381166526 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 30 Oct 2012 11:56:06 +0800 Subject: perf hists browser: Integrate script browser into main hists browser Integrate the script browser into "perf report" framework, users can use function key 'r' or the drop down menu to list all perf scripts and select one of them, just like they did for the annotation. Signed-off-by: Feng Tang Cc: Andi Kleen Cc: Ingo Molnar Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351569369-26732-6-git-send-email-feng.tang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index ef2f93ca749..fe622845872 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -1141,6 +1141,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, int nr_options = 0; int key = -1; char buf[64]; + char script_opt[64]; if (browser == NULL) return -1; @@ -1159,6 +1160,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, int choice = 0, annotate = -2, zoom_dso = -2, zoom_thread = -2, annotate_f = -2, annotate_t = -2, browse_map = -2; + int scripts_comm = -2, scripts_symbol = -2, scripts_all = -2; nr_options = 0; @@ -1211,6 +1213,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, hist_browser__reset(browser); } continue; + case 'r': + goto do_scripts; case K_F1: case 'h': case '?': @@ -1229,6 +1233,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, "E Expand all callchains\n" "d Zoom into current DSO\n" "t Zoom into current Thread\n" + "r Run available scripts\n" "P Print histograms to perf.hist.N\n" "V Verbose (DSO names in callchains, etc)\n" "/ Filter symbol by name"); @@ -1317,6 +1322,25 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, browser->selection->map != NULL && asprintf(&options[nr_options], "Browse map details") > 0) browse_map = nr_options++; + + /* perf script support */ + if (browser->he_selection) { + struct symbol *sym; + + if (asprintf(&options[nr_options], "Run scripts for samples of thread [%s]", + browser->he_selection->thread->comm) > 0) + scripts_comm = nr_options++; + + sym = browser->he_selection->ms.sym; + if (sym && sym->namelen && + asprintf(&options[nr_options], "Run scripts for samples of symbol [%s]", + sym->name) > 0) + scripts_symbol = nr_options++; + } + + if (asprintf(&options[nr_options], "Run scripts for all samples") > 0) + scripts_all = nr_options++; + add_exit_option: options[nr_options++] = (char *)"Exit"; retry_popup_menu: @@ -1411,6 +1435,20 @@ zoom_out_thread: hists__filter_by_thread(hists); hist_browser__reset(browser); } + /* perf scripts support */ + else if (choice == scripts_all || choice == scripts_comm || + choice == scripts_symbol) { +do_scripts: + memset(script_opt, 0, 64); + + if (choice == scripts_comm) + sprintf(script_opt, " -c %s ", browser->he_selection->thread->comm); + + if (choice == scripts_symbol) + sprintf(script_opt, " -S %s ", browser->he_selection->ms.sym->name); + + script_browse(script_opt); + } } out_free_stack: pstack__delete(fstack); -- cgit v1.2.3 From e84ba4e26833991d1c1c15a592b1474ee2b6dfdb Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 30 Oct 2012 11:56:07 +0800 Subject: perf header: Add is_perf_magic() func With this function, other modules can basically check whether a file is a legal perf data file by checking its first 8 bytes against all possible perf magic numbers. Change the function name from check_perf_magic to more meaningful is_perf_magic as suggested by acme. Signed-off-by: Feng Tang Cc: Andi Kleen Cc: Ingo Molnar Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351569369-26732-7-git-send-email-feng.tang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/header.c | 10 ++++++++++ tools/perf/util/header.h | 1 + 2 files changed, 11 insertions(+) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 514ed1bd41a..195a47a8f05 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -2341,6 +2341,16 @@ static int try_all_pipe_abis(uint64_t hdr_sz, struct perf_header *ph) return -1; } +bool is_perf_magic(u64 magic) +{ + if (!memcmp(&magic, __perf_magic1, sizeof(magic)) + || magic == __perf_magic2 + || magic == __perf_magic2_sw) + return true; + + return false; +} + static int check_magic_endian(u64 magic, uint64_t hdr_sz, bool is_pipe, struct perf_header *ph) { diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 879d215cdac..5f1cd6884f3 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -154,6 +154,7 @@ int perf_event__synthesize_build_id(struct perf_tool *tool, int perf_event__process_build_id(struct perf_tool *tool, union perf_event *event, struct perf_session *session); +bool is_perf_magic(u64 magic); /* * arch specific callback -- cgit v1.2.3 From 0089fa9831f3752869143c7928adb94ac6353085 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 20 Oct 2012 16:33:19 +0200 Subject: perf record: Fix mmap error output condition The mmap_pages default value is not power of 2 (UINT_MAX). Together with perf_evlist__mmap function returning error value different from EPERM, we get misleading error message: "--mmap_pages/-m value must be a power of two." Fixing this by adding extra check for UINT_MAX value for this error condition. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1350743599-4805-12-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 53c9892e96d..5783c322511 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -363,7 +363,8 @@ try_again: "or try again with a smaller value of -m/--mmap_pages.\n" "(current value: %d)\n", opts->mmap_pages); rc = -errno; - } else if (!is_power_of_2(opts->mmap_pages)) { + } else if (!is_power_of_2(opts->mmap_pages) && + (opts->mmap_pages != UINT_MAX)) { pr_err("--mmap_pages/-m value must be a power of two."); rc = -EINVAL; } else { -- cgit v1.2.3 From 0da2e9c24804d787cbc919b3e0d28ee7c00240ff Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 16 Oct 2012 14:51:04 -0300 Subject: perf python: Initialize 'page_size' variable The commit 0c1fe6b: 'perf tools: Have the page size value available for all tools' Broke the python binding because the global variable 'page_size' is initialized on the main() routine, that is not called when using just the python binding, causing evlist.mmap() to fail because it expects that variable to be initialized to the system's page size. Fix it by initializing it on the binding init routine. Reported-by: David Ahern Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-vrvp3azmbfzexnpmkhmvtzzc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/python.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 9181bf212fb..a2657fd9683 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -1015,6 +1015,8 @@ PyMODINIT_FUNC initperf(void) pyrf_cpu_map__setup_types() < 0) return; + page_size = sysconf(_SC_PAGE_SIZE); + Py_INCREF(&pyrf_evlist__type); PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type); -- cgit v1.2.3 From 7d4998f71b292ea8e88d1874b26866092f66412b Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 4 Oct 2012 15:19:08 +0530 Subject: clk: SPEAr: Vco-pll: Fix compilation warning Currently we are getting following warning for SPEAr clk-vco-pll. "warning: i is used uninitialized in this function." This is because we are getting value of i by passing its pointer to another routine. The variables here are really not used uninitialized. Signed-off-by: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/clk-vco-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c index 5f1b6badeb1..1b9b65bca51 100644 --- a/drivers/clk/spear/clk-vco-pll.c +++ b/drivers/clk/spear/clk-vco-pll.c @@ -147,7 +147,7 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long drate, struct clk_pll *pll = to_clk_pll(hw); struct pll_rate_tbl *rtbl = pll->vco->rtbl; unsigned long flags = 0, val; - int i; + int uninitialized_var(i); clk_pll_round_rate_index(hw, drate, NULL, &i); -- cgit v1.2.3 From 119c71276b43e3daf5e7b0661dcf63f224e2fc8d Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 3 Oct 2012 23:38:53 -0700 Subject: clk: Document .is_enabled op Add the missing kernel-doc for this op. Signed-off-by: Stephen Boyd Signed-off-by: Mike Turquette --- include/linux/clk-provider.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index c1273158292..2aa808bdc25 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -53,6 +53,10 @@ struct clk_hw; * @disable: Disable the clock atomically. Called with enable_lock held. * This function must not sleep. * + * @is_enabled: Queries the hardware to determine if the clock is enabled. + * This function must not sleep. Optional, if this op is not + * set then the enable count will be used. + * * @recalc_rate Recalculate the rate of this clock, by quering hardware. The * parent rate is an input parameter. It is up to the caller to * insure that the prepare_mutex is held across this call. -- cgit v1.2.3 From 7ce3e8ccbac708229ba8c40c9c2a43ca7fcdb3ae Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 3 Oct 2012 23:38:54 -0700 Subject: clk: Fix documentation typos Fix some minor typos in the documentation for the ops structure. Signed-off-by: Stephen Boyd Signed-off-by: Mike Turquette --- include/linux/clk-provider.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 2aa808bdc25..e1d83b187df 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -57,9 +57,9 @@ struct clk_hw; * This function must not sleep. Optional, if this op is not * set then the enable count will be used. * - * @recalc_rate Recalculate the rate of this clock, by quering hardware. The + * @recalc_rate Recalculate the rate of this clock, by querying hardware. The * parent rate is an input parameter. It is up to the caller to - * insure that the prepare_mutex is held across this call. + * ensure that the prepare_mutex is held across this call. * Returns the calculated rate. Optional, but recommended - if * this op is not set then clock rate will be initialized to 0. * @@ -93,7 +93,7 @@ struct clk_hw; * implementations to split any work between atomic (enable) and sleepable * (prepare) contexts. If enabling a clock requires code that might sleep, * this must be done in clk_prepare. Clock enable code that will never be - * called in a sleepable context may be implement in clk_enable. + * called in a sleepable context may be implemented in clk_enable. * * Typically, drivers will call clk_prepare when a clock may be needed later * (eg. when a device is opened), and clk_enable when the clock is actually -- cgit v1.2.3 From 2ac6b1f50a397580b8dc28f2833e54af7926fc71 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 3 Oct 2012 23:38:55 -0700 Subject: clk: Don't return negative numbers for unsigned values with !clk Some of the helper functions return negative error codes if passed a NULL clock. This can lead to confusing behavior when the expected return value is unsigned. Fix up these accessors so that they return unsigned values (or bool in the case of is_enabled). This way we can't interpret NULL clocks as having valid and interesting values. Signed-off-by: Stephen Boyd Signed-off-by: Mike Turquette --- drivers/clk/clk.c | 20 ++++++++++---------- include/linux/clk-provider.h | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 56e4495ebeb..bbe52c4ae7c 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -261,7 +261,7 @@ inline struct clk_hw *__clk_get_hw(struct clk *clk) inline u8 __clk_get_num_parents(struct clk *clk) { - return !clk ? -EINVAL : clk->num_parents; + return !clk ? 0 : clk->num_parents; } inline struct clk *__clk_get_parent(struct clk *clk) @@ -269,14 +269,14 @@ inline struct clk *__clk_get_parent(struct clk *clk) return !clk ? NULL : clk->parent; } -inline int __clk_get_enable_count(struct clk *clk) +inline unsigned int __clk_get_enable_count(struct clk *clk) { - return !clk ? -EINVAL : clk->enable_count; + return !clk ? 0 : clk->enable_count; } -inline int __clk_get_prepare_count(struct clk *clk) +inline unsigned int __clk_get_prepare_count(struct clk *clk) { - return !clk ? -EINVAL : clk->prepare_count; + return !clk ? 0 : clk->prepare_count; } unsigned long __clk_get_rate(struct clk *clk) @@ -302,15 +302,15 @@ out: inline unsigned long __clk_get_flags(struct clk *clk) { - return !clk ? -EINVAL : clk->flags; + return !clk ? 0 : clk->flags; } -int __clk_is_enabled(struct clk *clk) +bool __clk_is_enabled(struct clk *clk) { int ret; if (!clk) - return -EINVAL; + return false; /* * .is_enabled is only mandatory for clocks that gate @@ -323,7 +323,7 @@ int __clk_is_enabled(struct clk *clk) ret = clk->ops->is_enabled(clk->hw); out: - return ret; + return !!ret; } static struct clk *__clk_lookup_subtree(const char *name, struct clk *clk) @@ -568,7 +568,7 @@ unsigned long __clk_round_rate(struct clk *clk, unsigned long rate) unsigned long parent_rate = 0; if (!clk) - return -EINVAL; + return 0; if (!clk->ops->round_rate) { if (clk->flags & CLK_SET_RATE_PARENT) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index e1d83b187df..0dce3d31eae 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -339,11 +339,11 @@ const char *__clk_get_name(struct clk *clk); struct clk_hw *__clk_get_hw(struct clk *clk); u8 __clk_get_num_parents(struct clk *clk); struct clk *__clk_get_parent(struct clk *clk); -inline int __clk_get_enable_count(struct clk *clk); -inline int __clk_get_prepare_count(struct clk *clk); +inline unsigned int __clk_get_enable_count(struct clk *clk); +inline unsigned int __clk_get_prepare_count(struct clk *clk); unsigned long __clk_get_rate(struct clk *clk); unsigned long __clk_get_flags(struct clk *clk); -int __clk_is_enabled(struct clk *clk); +bool __clk_is_enabled(struct clk *clk); struct clk *__clk_lookup(const char *name); /* -- cgit v1.2.3 From 686f871b7109e7e253a7a1cef542c00d0ed1a323 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 24 Sep 2012 16:43:17 +0200 Subject: mfd: dbx500: Export prmcu_request_ape_opp_100_voltage This function needs to be exported to let clients be able to request the ape opp 100 voltage. Cc: Samuel Ortiz Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/mfd/db8500-prcmu.c | 4 ++-- include/linux/mfd/db8500-prcmu.h | 4 ++-- include/linux/mfd/dbx500-prcmu.h | 10 ++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 00b8b0f3dfb..3167bfdd13f 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -1169,12 +1169,12 @@ int db8500_prcmu_get_ape_opp(void) } /** - * prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage + * db8500_prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage * @enable: true to request the higher voltage, false to drop a request. * * Calls to this function to enable and disable requests must be balanced. */ -int prcmu_request_ape_opp_100_voltage(bool enable) +int db8500_prcmu_request_ape_opp_100_voltage(bool enable) { int r = 0; u8 header; diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h index b82f6ee66a0..6ee4247df11 100644 --- a/include/linux/mfd/db8500-prcmu.h +++ b/include/linux/mfd/db8500-prcmu.h @@ -515,7 +515,6 @@ enum romcode_read prcmu_get_rc_p2a(void); enum ap_pwrst prcmu_get_xp70_current_state(void); bool prcmu_has_arm_maxopp(void); struct prcmu_fw_version *prcmu_get_fw_version(void); -int prcmu_request_ape_opp_100_voltage(bool enable); int prcmu_release_usb_wakeup_state(void); void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep, struct prcmu_auto_pm_config *idle); @@ -564,6 +563,7 @@ int db8500_prcmu_set_arm_opp(u8 opp); int db8500_prcmu_get_arm_opp(void); int db8500_prcmu_set_ape_opp(u8 opp); int db8500_prcmu_get_ape_opp(void); +int db8500_prcmu_request_ape_opp_100_voltage(bool enable); int db8500_prcmu_set_ddr_opp(u8 opp); int db8500_prcmu_get_ddr_opp(void); @@ -610,7 +610,7 @@ static inline int db8500_prcmu_get_ape_opp(void) return APE_100_OPP; } -static inline int prcmu_request_ape_opp_100_voltage(bool enable) +static inline int db8500_prcmu_request_ape_opp_100_voltage(bool enable) { return 0; } diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h index c410d99bd66..c202d6c4d87 100644 --- a/include/linux/mfd/dbx500-prcmu.h +++ b/include/linux/mfd/dbx500-prcmu.h @@ -336,6 +336,11 @@ static inline int prcmu_get_ape_opp(void) return db8500_prcmu_get_ape_opp(); } +static inline int prcmu_request_ape_opp_100_voltage(bool enable) +{ + return db8500_prcmu_request_ape_opp_100_voltage(enable); +} + static inline void prcmu_system_reset(u16 reset_code) { return db8500_prcmu_system_reset(reset_code); @@ -507,6 +512,11 @@ static inline int prcmu_get_ape_opp(void) return APE_100_OPP; } +static inline int prcmu_request_ape_opp_100_voltage(bool enable) +{ + return 0; +} + static inline int prcmu_set_arm_opp(u8 opp) { return 0; -- cgit v1.2.3 From b0ea0fc753bfda1e9c20af403187758eb32052fd Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 24 Sep 2012 16:43:18 +0200 Subject: clk: ux500: Support prcmu ape opp voltage clock Some scalable prcmu clocks needs to be handled in conjuction with the ape opp 100 voltage. A new prcmu clock type clk_prcmu_opp_volt_scalable is implemented to handle this. Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/clk/ux500/clk-prcmu.c | 55 +++++++++++++++++++++++++++++++++++++++++++ drivers/clk/ux500/clk.h | 6 +++++ 2 files changed, 61 insertions(+) diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c index 930cdfeb47a..04577ca6a30 100644 --- a/drivers/clk/ux500/clk-prcmu.c +++ b/drivers/clk/ux500/clk-prcmu.c @@ -133,6 +133,40 @@ out_error: hw->init->name); } +static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw) +{ + int err; + struct clk_prcmu *clk = to_clk_prcmu(hw); + + err = prcmu_request_ape_opp_100_voltage(true); + if (err) { + pr_err("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n", + __func__, hw->init->name); + return err; + } + + err = prcmu_request_clock(clk->cg_sel, true); + if (err) + prcmu_request_ape_opp_100_voltage(false); + + return err; +} + +static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw) +{ + struct clk_prcmu *clk = to_clk_prcmu(hw); + + if (prcmu_request_clock(clk->cg_sel, false)) + goto out_error; + if (prcmu_request_ape_opp_100_voltage(false)) + goto out_error; + return; + +out_error: + pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, + hw->init->name); +} + static struct clk_ops clk_prcmu_scalable_ops = { .prepare = clk_prcmu_prepare, .unprepare = clk_prcmu_unprepare, @@ -167,6 +201,17 @@ static struct clk_ops clk_prcmu_opp_gate_ops = { .recalc_rate = clk_prcmu_recalc_rate, }; +static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { + .prepare = clk_prcmu_opp_volt_prepare, + .unprepare = clk_prcmu_opp_volt_unprepare, + .enable = clk_prcmu_enable, + .disable = clk_prcmu_disable, + .is_enabled = clk_prcmu_is_enabled, + .recalc_rate = clk_prcmu_recalc_rate, + .round_rate = clk_prcmu_round_rate, + .set_rate = clk_prcmu_set_rate, +}; + static struct clk *clk_reg_prcmu(const char *name, const char *parent_name, u8 cg_sel, @@ -250,3 +295,13 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name, return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags, &clk_prcmu_opp_gate_ops); } + +struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name, + const char *parent_name, + u8 cg_sel, + unsigned long rate, + unsigned long flags) +{ + return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags, + &clk_prcmu_opp_volt_scalable_ops); +} diff --git a/drivers/clk/ux500/clk.h b/drivers/clk/ux500/clk.h index 836d7d16751..f36eeedca49 100644 --- a/drivers/clk/ux500/clk.h +++ b/drivers/clk/ux500/clk.h @@ -45,4 +45,10 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name, u8 cg_sel, unsigned long flags); +struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name, + const char *parent_name, + u8 cg_sel, + unsigned long rate, + unsigned long flags); + #endif /* __UX500_CLK_H */ -- cgit v1.2.3 From 2f896ac0be9a0c7739033ef1f8821223f4a6a908 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 24 Sep 2012 16:43:19 +0200 Subject: clk: ux500: Update sdmmc clock to 100MHz for u8500 For u8500 and using 100MHz as the frequency also requires the ape opp 100 voltage, thus use the prcmu_opp_volt_scalable clock type. Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index ca4a25ed844..7bebf1f62c6 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -170,10 +170,11 @@ void u8500_clk_init(void) clk_register_clkdev(clk, NULL, "mtu0"); clk_register_clkdev(clk, NULL, "mtu1"); - clk = clk_reg_prcmu_gate("sdmmcclk", NULL, PRCMU_SDMMCCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, PRCMU_SDMMCCLK, + 100000000, + CLK_IS_ROOT|CLK_SET_RATE_GATE); clk_register_clkdev(clk, NULL, "sdmmc"); - clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk", PRCMU_PLLDSI, 0, CLK_SET_RATE_GATE); clk_register_clkdev(clk, "dsihs2", "mcde"); -- cgit v1.2.3 From cdfed3b21f10ecd1566c7d5b8d40f05b18d52bda Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 21 Sep 2012 14:35:18 +0800 Subject: clk: fix return value check in of_fixed_clk_setup() In case of error, the function clk_register_fixed_rate() returns ERR_PTR() not NULL pointer. The NULL test in the return value check should be replaced with IS_ERR(). dpatch engine is used to auto generated this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Mike Turquette --- drivers/clk/clk-fixed-rate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index f5ec0eebd4d..af78ed6b67e 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -97,7 +97,7 @@ void __init of_fixed_clk_setup(struct device_node *node) of_property_read_string(node, "clock-output-names", &clk_name); clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, rate); - if (clk) + if (!IS_ERR(clk)) of_clk_add_provider(node, of_clk_src_simple_get, clk); } EXPORT_SYMBOL_GPL(of_fixed_clk_setup); -- cgit v1.2.3 From 2968f85185b5806c7adf80e3329ddfe1ecc1aec4 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 7 Oct 2012 22:02:09 +0800 Subject: clk: fix return value check in sirfsoc_of_clk_init() In case of error, the function clk_register() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR(). dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Mike Turquette --- drivers/clk/clk-prima2.c | 84 ++++++++++++++++++++++++------------------------ 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/drivers/clk/clk-prima2.c b/drivers/clk/clk-prima2.c index 517874fa685..a203ecccdc4 100644 --- a/drivers/clk/clk-prima2.c +++ b/drivers/clk/clk-prima2.c @@ -1054,118 +1054,118 @@ void __init sirfsoc_of_clk_init(void) /* These are always available (RTC and 26MHz OSC)*/ clk = clk_register_fixed_rate(NULL, "rtc", NULL, CLK_IS_ROOT, 32768); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT, 26000000); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register(NULL, &clk_pll1.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register(NULL, &clk_pll2.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register(NULL, &clk_pll3.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register(NULL, &clk_mem.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register(NULL, &clk_sys.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register(NULL, &clk_security.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b8030000.security"); clk = clk_register(NULL, &clk_dsp.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register(NULL, &clk_gps.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "a8010000.gps"); clk = clk_register(NULL, &clk_mf.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register(NULL, &clk_io.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "io"); clk = clk_register(NULL, &clk_cpu.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "cpu"); clk = clk_register(NULL, &clk_uart0.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0050000.uart"); clk = clk_register(NULL, &clk_uart1.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0060000.uart"); clk = clk_register(NULL, &clk_uart2.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0070000.uart"); clk = clk_register(NULL, &clk_tsc.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0110000.tsc"); clk = clk_register(NULL, &clk_i2c0.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b00e0000.i2c"); clk = clk_register(NULL, &clk_i2c1.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b00f0000.i2c"); clk = clk_register(NULL, &clk_spi0.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b00d0000.spi"); clk = clk_register(NULL, &clk_spi1.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0170000.spi"); clk = clk_register(NULL, &clk_pwmc.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0130000.pwm"); clk = clk_register(NULL, &clk_efuse.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0140000.efusesys"); clk = clk_register(NULL, &clk_pulse.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0150000.pulsec"); clk = clk_register(NULL, &clk_dmac0.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b00b0000.dma-controller"); clk = clk_register(NULL, &clk_dmac1.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0160000.dma-controller"); clk = clk_register(NULL, &clk_nand.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0030000.nand"); clk = clk_register(NULL, &clk_audio.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0040000.audio"); clk = clk_register(NULL, &clk_usp0.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0080000.usp"); clk = clk_register(NULL, &clk_usp1.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b0090000.usp"); clk = clk_register(NULL, &clk_usp2.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b00a0000.usp"); clk = clk_register(NULL, &clk_vip.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b00c0000.vip"); clk = clk_register(NULL, &clk_gfx.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "98000000.graphics"); clk = clk_register(NULL, &clk_mm.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "a0000000.multimedia"); clk = clk_register(NULL, &clk_lcd.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "90010000.display"); clk = clk_register(NULL, &clk_vpp.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "90020000.vpp"); clk = clk_register(NULL, &clk_mmc01.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register(NULL, &clk_mmc23.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register(NULL, &clk_mmc45.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register(NULL, &usb_pll_clk_hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk = clk_register(NULL, &clk_usb0.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b00e0000.usb"); clk = clk_register(NULL, &clk_usb1.hw); - BUG_ON(!clk); + BUG_ON(IS_ERR(clk)); clk_register_clkdev(clk, NULL, "b00f0000.usb"); } -- cgit v1.2.3 From f9f8c0438da2c6d6a4cd8af73097add3850d6084 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 14 Sep 2012 17:30:27 +0300 Subject: CLK: clk-twl6040: Initial clock driver for OMAP4+ McPDM fclk clock On OMAP4+ platforms the functional clock for the McPDM IP is suplied by the twl6040 codec (bit clock on the PDM bus). This common clock driver for twl6040 will register the mcpdm_fclk clock to be used by the McPDM driver to make sure that the needed clocks are available when needed. Signed-off-by: Peter Ujfalusi Signed-off-by: Mike Turquette --- drivers/clk/Kconfig | 8 +++ drivers/clk/Makefile | 1 + drivers/clk/clk-twl6040.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 drivers/clk/clk-twl6040.c diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index bace9e98f75..3d0b7843852 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -53,4 +53,12 @@ config COMMON_CLK_MAX77686 ---help--- This driver supports Maxim 77686 crystal oscillator clock. +config CLK_TWL6040 + tristate "External McPDM functional clock from twl6040" + depends on TWL6040_CORE + ---help--- + Enable the external functional clock support on OMAP4+ platforms for + McPDM. McPDM module is using the external bit clock on the McPDM bus + as functional clock. + endmenu diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 71a25b91de0..2701235d575 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o # Chip specific obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o +obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c new file mode 100644 index 00000000000..f4a3389c3d0 --- /dev/null +++ b/drivers/clk/clk-twl6040.c @@ -0,0 +1,126 @@ +/* +* TWL6040 clock module driver for OMAP4 McPDM functional clock +* +* Copyright (C) 2012 Texas Instruments Inc. +* Peter Ujfalusi +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA +* +*/ + +#include +#include +#include +#include +#include +#include + +struct twl6040_clk { + struct twl6040 *twl6040; + struct device *dev; + struct clk_hw mcpdm_fclk; + struct clk *clk; + int enabled; +}; + +static int twl6040_bitclk_is_enabled(struct clk_hw *hw) +{ + struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, + mcpdm_fclk); + return twl6040_clk->enabled; +} + +static int twl6040_bitclk_prepare(struct clk_hw *hw) +{ + struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, + mcpdm_fclk); + int ret; + + ret = twl6040_power(twl6040_clk->twl6040, 1); + if (!ret) + twl6040_clk->enabled = 1; + + return ret; +} + +static void twl6040_bitclk_unprepare(struct clk_hw *hw) +{ + struct twl6040_clk *twl6040_clk = container_of(hw, struct twl6040_clk, + mcpdm_fclk); + int ret; + + ret = twl6040_power(twl6040_clk->twl6040, 0); + if (!ret) + twl6040_clk->enabled = 0; +} + +static const struct clk_ops twl6040_mcpdm_ops = { + .is_enabled = twl6040_bitclk_is_enabled, + .prepare = twl6040_bitclk_prepare, + .unprepare = twl6040_bitclk_unprepare, +}; + +static struct clk_init_data wm831x_clkout_init = { + .name = "mcpdm_fclk", + .ops = &twl6040_mcpdm_ops, + .flags = CLK_IS_ROOT, +}; + +static int __devinit twl6040_clk_probe(struct platform_device *pdev) +{ + struct twl6040 *twl6040 = dev_get_drvdata(pdev->dev.parent); + struct twl6040_clk *clkdata; + + clkdata = devm_kzalloc(&pdev->dev, sizeof(*clkdata), GFP_KERNEL); + if (!clkdata) + return -ENOMEM; + + clkdata->dev = &pdev->dev; + clkdata->twl6040 = twl6040; + + clkdata->mcpdm_fclk.init = &wm831x_clkout_init; + clkdata->clk = clk_register(&pdev->dev, &clkdata->mcpdm_fclk); + if (!clkdata->clk) + return -EINVAL; + + dev_set_drvdata(&pdev->dev, clkdata); + + return 0; +} + +static int __devexit twl6040_clk_remove(struct platform_device *pdev) +{ + struct twl6040_clk *clkdata = dev_get_drvdata(&pdev->dev); + + clk_unregister(clkdata->clk); + + return 0; +} + +static struct platform_driver twl6040_clk_driver = { + .driver = { + .name = "twl6040-clk", + .owner = THIS_MODULE, + }, + .probe = twl6040_clk_probe, + .remove = __devexit_p(twl6040_clk_remove), +}; + +module_platform_driver(twl6040_clk_driver); + +MODULE_DESCRIPTION("TWL6040 clock driver for McPDM functional clock"); +MODULE_AUTHOR("Peter Ujfalusi "); +MODULE_ALIAS("platform:twl6040-clk"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From ed27ff1db869cc81a92bed6defb7d107f5a156ff Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Tue, 18 Sep 2012 15:17:47 +0100 Subject: clk: Versatile Express clock generators ("osc") driver This driver provides a common clock framework hardware driver for Versatile Express clock generators (a.k.a "osc") controlled via the config bus. Signed-off-by: Pawel Moll Signed-off-by: Mike Turquette --- drivers/clk/versatile/Makefile | 1 + drivers/clk/versatile/clk-vexpress-osc.c | 146 +++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 drivers/clk/versatile/clk-vexpress-osc.c diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile index c0a0f647879..1e49a7afcf4 100644 --- a/drivers/clk/versatile/Makefile +++ b/drivers/clk/versatile/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_ICST) += clk-icst.o obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o +obj-$(CONFIG_VEXPRESS_CONFIG) += clk-vexpress-osc.o diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c new file mode 100644 index 00000000000..dcb6ae0a042 --- /dev/null +++ b/drivers/clk/versatile/clk-vexpress-osc.c @@ -0,0 +1,146 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Copyright (C) 2012 ARM Limited + */ + +#define pr_fmt(fmt) "vexpress-osc: " fmt + +#include +#include +#include +#include +#include +#include +#include + +struct vexpress_osc { + struct vexpress_config_func *func; + struct clk_hw hw; + unsigned long rate_min; + unsigned long rate_max; +}; + +#define to_vexpress_osc(osc) container_of(osc, struct vexpress_osc, hw) + +static unsigned long vexpress_osc_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct vexpress_osc *osc = to_vexpress_osc(hw); + u32 rate; + + vexpress_config_read(osc->func, 0, &rate); + + return rate; +} + +static long vexpress_osc_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct vexpress_osc *osc = to_vexpress_osc(hw); + + if (WARN_ON(osc->rate_min && rate < osc->rate_min)) + rate = osc->rate_min; + + if (WARN_ON(osc->rate_max && rate > osc->rate_max)) + rate = osc->rate_max; + + return rate; +} + +static int vexpress_osc_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct vexpress_osc *osc = to_vexpress_osc(hw); + + return vexpress_config_write(osc->func, 0, rate); +} + +static struct clk_ops vexpress_osc_ops = { + .recalc_rate = vexpress_osc_recalc_rate, + .round_rate = vexpress_osc_round_rate, + .set_rate = vexpress_osc_set_rate, +}; + + +struct clk * __init vexpress_osc_setup(struct device *dev) +{ + struct clk_init_data init; + struct vexpress_osc *osc = kzalloc(sizeof(*osc), GFP_KERNEL); + + if (!osc) + return NULL; + + osc->func = vexpress_config_func_get_by_dev(dev); + if (!osc->func) { + kfree(osc); + return NULL; + } + + init.name = dev_name(dev); + init.ops = &vexpress_osc_ops; + init.flags = CLK_IS_ROOT; + init.num_parents = 0; + osc->hw.init = &init; + + return clk_register(NULL, &osc->hw); +} + +void __init vexpress_osc_of_setup(struct device_node *node) +{ + struct clk_init_data init; + struct vexpress_osc *osc; + struct clk *clk; + u32 range[2]; + + osc = kzalloc(sizeof(*osc), GFP_KERNEL); + if (!osc) + goto error; + + osc->func = vexpress_config_func_get_by_node(node); + if (!osc->func) { + pr_err("Failed to obtain config func for node '%s'!\n", + node->name); + goto error; + } + + if (of_property_read_u32_array(node, "freq-range", range, + ARRAY_SIZE(range)) == 0) { + osc->rate_min = range[0]; + osc->rate_max = range[1]; + } + + of_property_read_string(node, "clock-output-names", &init.name); + if (!init.name) + init.name = node->name; + + init.ops = &vexpress_osc_ops; + init.flags = CLK_IS_ROOT; + init.num_parents = 0; + + osc->hw.init = &init; + + clk = clk_register(NULL, &osc->hw); + if (IS_ERR(clk)) { + pr_err("Failed to register clock '%s'!\n", init.name); + goto error; + } + + of_clk_add_provider(node, of_clk_src_simple_get, clk); + + pr_debug("Registered clock '%s'\n", init.name); + + return; + +error: + if (osc->func) + vexpress_config_func_put(osc->func); + kfree(osc); +} -- cgit v1.2.3 From bcd6f569e87471d7f104bd9497f0b516a3b12e32 Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Tue, 18 Sep 2012 15:17:48 +0100 Subject: clk: Common clocks implementation for Versatile Express This patch adds a DT and non-DT based implementation of the common clock infrastructure for Versatile Express platform. It registers (statically or using DT) all required fixed clocks, initialises motherboard's SP810 cell (that provides clocks for SP804 timers) and explicitly registers VE "osc" driver, to make the clock generators available early. Signed-off-by: Pawel Moll Signed-off-by: Mike Turquette --- arch/arm/include/asm/hardware/sp810.h | 2 + drivers/clk/Kconfig | 8 +- drivers/clk/versatile/Makefile | 1 + drivers/clk/versatile/clk-vexpress.c | 142 ++++++++++++++++++++++++++++++++++ 4 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 drivers/clk/versatile/clk-vexpress.c diff --git a/arch/arm/include/asm/hardware/sp810.h b/arch/arm/include/asm/hardware/sp810.h index 6b9b077d86b..afd7e916472 100644 --- a/arch/arm/include/asm/hardware/sp810.h +++ b/arch/arm/include/asm/hardware/sp810.h @@ -56,6 +56,8 @@ #define SCCTRL_TIMEREN1SEL_REFCLK (0 << 17) #define SCCTRL_TIMEREN1SEL_TIMCLK (1 << 17) +#define SCCTRL_TIMERENnSEL_SHIFT(n) (15 + ((n) * 2)) + static inline void sysctl_soft_reset(void __iomem *base) { /* switch to slow mode */ diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 3d0b7843852..823f62d900b 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -42,10 +42,12 @@ config COMMON_CLK_WM831X config COMMON_CLK_VERSATILE bool "Clock driver for ARM Reference designs" - depends on ARCH_INTEGRATOR || ARCH_REALVIEW + depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS ---help--- - Supports clocking on ARM Reference designs Integrator/AP, - Integrator/CP, RealView PB1176, EB, PB11MP and PBX. + Supports clocking on ARM Reference designs: + - Integrator/AP and Integrator/CP + - RealView PB1176, EB, PB11MP and PBX + - Versatile Express config COMMON_CLK_MAX77686 tristate "Clock driver for Maxim 77686 MFD" diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile index 1e49a7afcf4..c776053e5bb 100644 --- a/drivers/clk/versatile/Makefile +++ b/drivers/clk/versatile/Makefile @@ -2,4 +2,5 @@ obj-$(CONFIG_ICST) += clk-icst.o obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o +obj-$(CONFIG_ARCH_VEXPRESS) += clk-vexpress.o obj-$(CONFIG_VEXPRESS_CONFIG) += clk-vexpress-osc.o diff --git a/drivers/clk/versatile/clk-vexpress.c b/drivers/clk/versatile/clk-vexpress.c new file mode 100644 index 00000000000..c742ac7c60b --- /dev/null +++ b/drivers/clk/versatile/clk-vexpress.c @@ -0,0 +1,142 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Copyright (C) 2012 ARM Limited + */ + +#include +#include +#include +#include +#include +#include + +#include + +static struct clk *vexpress_sp810_timerclken[4]; +static DEFINE_SPINLOCK(vexpress_sp810_lock); + +static void __init vexpress_sp810_init(void __iomem *base) +{ + int i; + + if (WARN_ON(!base)) + return; + + for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++) { + char name[12]; + const char *parents[] = { + "v2m:refclk32khz", /* REFCLK */ + "v2m:refclk1mhz" /* TIMCLK */ + }; + + snprintf(name, ARRAY_SIZE(name), "timerclken%d", i); + + vexpress_sp810_timerclken[i] = clk_register_mux(NULL, name, + parents, 2, 0, base + SCCTRL, + SCCTRL_TIMERENnSEL_SHIFT(i), 1, + 0, &vexpress_sp810_lock); + + if (WARN_ON(IS_ERR(vexpress_sp810_timerclken[i]))) + break; + } +} + + +static const char * const vexpress_clk_24mhz_periphs[] __initconst = { + "mb:uart0", "mb:uart1", "mb:uart2", "mb:uart3", + "mb:mmci", "mb:kmi0", "mb:kmi1" +}; + +void __init vexpress_clk_init(void __iomem *sp810_base) +{ + struct clk *clk; + int i; + + clk = clk_register_fixed_rate(NULL, "dummy_apb_pclk", NULL, + CLK_IS_ROOT, 0); + WARN_ON(clk_register_clkdev(clk, "apb_pclk", NULL)); + + clk = clk_register_fixed_rate(NULL, "v2m:clk_24mhz", NULL, + CLK_IS_ROOT, 24000000); + for (i = 0; i < ARRAY_SIZE(vexpress_clk_24mhz_periphs); i++) + WARN_ON(clk_register_clkdev(clk, NULL, + vexpress_clk_24mhz_periphs[i])); + + clk = clk_register_fixed_rate(NULL, "v2m:refclk32khz", NULL, + CLK_IS_ROOT, 32768); + WARN_ON(clk_register_clkdev(clk, NULL, "v2m:wdt")); + + clk = clk_register_fixed_rate(NULL, "v2m:refclk1mhz", NULL, + CLK_IS_ROOT, 1000000); + + vexpress_sp810_init(sp810_base); + + for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++) + WARN_ON(clk_set_parent(vexpress_sp810_timerclken[i], clk)); + + WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[0], + "v2m-timer0", "sp804")); + WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[1], + "v2m-timer1", "sp804")); +} + +#if defined(CONFIG_OF) + +struct clk *vexpress_sp810_of_get(struct of_phandle_args *clkspec, void *data) +{ + if (WARN_ON(clkspec->args_count != 1 || clkspec->args[0] > + ARRAY_SIZE(vexpress_sp810_timerclken))) + return NULL; + + return vexpress_sp810_timerclken[clkspec->args[0]]; +} + +static const __initconst struct of_device_id vexpress_fixed_clk_match[] = { + { .compatible = "fixed-clock", .data = of_fixed_clk_setup, }, + { .compatible = "arm,vexpress-osc", .data = vexpress_osc_of_setup, }, + {} +}; + +void __init vexpress_clk_of_init(void) +{ + struct device_node *node; + struct clk *clk; + struct clk *refclk, *timclk; + + of_clk_init(vexpress_fixed_clk_match); + + node = of_find_compatible_node(NULL, NULL, "arm,sp810"); + vexpress_sp810_init(of_iomap(node, 0)); + of_clk_add_provider(node, vexpress_sp810_of_get, NULL); + + /* Select "better" (faster) parent for SP804 timers */ + refclk = of_clk_get_by_name(node, "refclk"); + timclk = of_clk_get_by_name(node, "timclk"); + if (!WARN_ON(IS_ERR(refclk) || IS_ERR(timclk))) { + int i = 0; + + if (clk_get_rate(refclk) > clk_get_rate(timclk)) + clk = refclk; + else + clk = timclk; + + for (i = 0; i < ARRAY_SIZE(vexpress_sp810_timerclken); i++) + WARN_ON(clk_set_parent(vexpress_sp810_timerclken[i], + clk)); + } + + WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[0], + "v2m-timer0", "sp804")); + WARN_ON(clk_register_clkdev(vexpress_sp810_timerclken[1], + "v2m-timer1", "sp804")); +} + +#endif -- cgit v1.2.3 From 980f58a45e04b248e9dd01b0eba510a3384160db Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 24 Sep 2012 13:38:03 -0700 Subject: clk: wm831x: Fix clk_register() error code checking clk_register() returns an ERR_PTR upon failure, not NULL. Fix these error paths. Acked-by: Mark Brown Signed-off-by: Stephen Boyd Signed-off-by: Mike Turquette --- drivers/clk/clk-wm831x.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c index e7b7765e85f..eb1afafca03 100644 --- a/drivers/clk/clk-wm831x.c +++ b/drivers/clk/clk-wm831x.c @@ -371,20 +371,20 @@ static __devinit int wm831x_clk_probe(struct platform_device *pdev) clkdata->xtal_hw.init = &wm831x_xtal_init; clkdata->xtal = clk_register(&pdev->dev, &clkdata->xtal_hw); - if (!clkdata->xtal) - return -EINVAL; + if (IS_ERR(clkdata->xtal)) + return PTR_ERR(clkdata->xtal); clkdata->fll_hw.init = &wm831x_fll_init; clkdata->fll = clk_register(&pdev->dev, &clkdata->fll_hw); - if (!clkdata->fll) { - ret = -EINVAL; + if (IS_ERR(clkdata->fll)) { + ret = PTR_ERR(clkdata->fll); goto err_xtal; } clkdata->clkout_hw.init = &wm831x_clkout_init; clkdata->clkout = clk_register(&pdev->dev, &clkdata->clkout_hw); - if (!clkdata->clkout) { - ret = -EINVAL; + if (IS_ERR(clkdata->clkout)) { + ret = PTR_ERR(clkdata->clkout); goto err_fll; } -- cgit v1.2.3 From 46c8773a58010d31f228e148b8b774d94cc9810d Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 24 Sep 2012 13:38:04 -0700 Subject: clk: Add devm_clk_{register,unregister}() Some clock drivers can be simplified if devres takes care of unregistering any registered clocks along error paths. Introduce devm_clk_register() so that clock drivers get unregistration for free along with simplified error paths. Signed-off-by: Stephen Boyd Signed-off-by: Mike Turquette --- drivers/clk/clk.c | 111 +++++++++++++++++++++++++++++++++++-------- include/linux/clk-provider.h | 2 + 2 files changed, 92 insertions(+), 21 deletions(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index bbe52c4ae7c..2fd28ddd06c 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -17,6 +17,7 @@ #include #include #include +#include static DEFINE_SPINLOCK(enable_lock); static DEFINE_MUTEX(prepare_lock); @@ -1361,28 +1362,9 @@ struct clk *__clk_register(struct device *dev, struct clk_hw *hw) } EXPORT_SYMBOL_GPL(__clk_register); -/** - * clk_register - allocate a new clock, register it and return an opaque cookie - * @dev: device that is registering this clock - * @hw: link to hardware-specific clock data - * - * clk_register is the primary interface for populating the clock tree with new - * clock nodes. It returns a pointer to the newly allocated struct clk which - * cannot be dereferenced by driver code but may be used in conjuction with the - * rest of the clock API. In the event of an error clk_register will return an - * error code; drivers must test for an error code after calling clk_register. - */ -struct clk *clk_register(struct device *dev, struct clk_hw *hw) +static int _clk_register(struct device *dev, struct clk_hw *hw, struct clk *clk) { int i, ret; - struct clk *clk; - - clk = kzalloc(sizeof(*clk), GFP_KERNEL); - if (!clk) { - pr_err("%s: could not allocate clk\n", __func__); - ret = -ENOMEM; - goto fail_out; - } clk->name = kstrdup(hw->init->name, GFP_KERNEL); if (!clk->name) { @@ -1420,7 +1402,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) ret = __clk_init(dev, clk); if (!ret) - return clk; + return 0; fail_parent_names_copy: while (--i >= 0) @@ -1429,6 +1411,36 @@ fail_parent_names_copy: fail_parent_names: kfree(clk->name); fail_name: + return ret; +} + +/** + * clk_register - allocate a new clock, register it and return an opaque cookie + * @dev: device that is registering this clock + * @hw: link to hardware-specific clock data + * + * clk_register is the primary interface for populating the clock tree with new + * clock nodes. It returns a pointer to the newly allocated struct clk which + * cannot be dereferenced by driver code but may be used in conjuction with the + * rest of the clock API. In the event of an error clk_register will return an + * error code; drivers must test for an error code after calling clk_register. + */ +struct clk *clk_register(struct device *dev, struct clk_hw *hw) +{ + int ret; + struct clk *clk; + + clk = kzalloc(sizeof(*clk), GFP_KERNEL); + if (!clk) { + pr_err("%s: could not allocate clk\n", __func__); + ret = -ENOMEM; + goto fail_out; + } + + ret = _clk_register(dev, hw, clk); + if (!ret) + return clk; + kfree(clk); fail_out: return ERR_PTR(ret); @@ -1444,6 +1456,63 @@ EXPORT_SYMBOL_GPL(clk_register); void clk_unregister(struct clk *clk) {} EXPORT_SYMBOL_GPL(clk_unregister); +static void devm_clk_release(struct device *dev, void *res) +{ + clk_unregister(res); +} + +/** + * devm_clk_register - resource managed clk_register() + * @dev: device that is registering this clock + * @hw: link to hardware-specific clock data + * + * Managed clk_register(). Clocks returned from this function are + * automatically clk_unregister()ed on driver detach. See clk_register() for + * more information. + */ +struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw) +{ + struct clk *clk; + int ret; + + clk = devres_alloc(devm_clk_release, sizeof(*clk), GFP_KERNEL); + if (!clk) + return ERR_PTR(-ENOMEM); + + ret = _clk_register(dev, hw, clk); + if (!ret) { + devres_add(dev, clk); + } else { + devres_free(clk); + clk = ERR_PTR(ret); + } + + return clk; +} +EXPORT_SYMBOL_GPL(devm_clk_register); + +static int devm_clk_match(struct device *dev, void *res, void *data) +{ + struct clk *c = res; + if (WARN_ON(!c)) + return 0; + return c == data; +} + +/** + * devm_clk_unregister - resource managed clk_unregister() + * @clk: clock to unregister + * + * Deallocate a clock allocated with devm_clk_register(). Normally + * this function will not need to be called and the resource management + * code will ensure that the resource is freed. + */ +void devm_clk_unregister(struct device *dev, struct clk *clk) +{ + WARN_ON(devres_release(dev, devm_clk_release, devm_clk_match, clk)); +} +EXPORT_SYMBOL_GPL(devm_clk_unregister); + /*** clk rate change notifiers ***/ /** diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 0dce3d31eae..3593a3ce3f0 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -331,8 +331,10 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name, * error code; drivers must test for an error code after calling clk_register. */ struct clk *clk_register(struct device *dev, struct clk_hw *hw); +struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw); void clk_unregister(struct clk *clk); +void devm_clk_unregister(struct device *dev, struct clk *clk); /* helper functions */ const char *__clk_get_name(struct clk *clk); -- cgit v1.2.3 From 9be9d482bcf5a0a3e0ae131a98573b9e2d358915 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 24 Sep 2012 13:38:05 -0700 Subject: clk: wm831x: Use devm_clk_register() to simplify code Move this driver to use devm_clk_register() to simplify some error paths and reduce lines of code. Acked-by: Mark Brown Signed-off-by: Stephen Boyd Signed-off-by: Mike Turquette --- drivers/clk/clk-wm831x.c | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/drivers/clk/clk-wm831x.c b/drivers/clk/clk-wm831x.c index eb1afafca03..db4fbf20ffd 100644 --- a/drivers/clk/clk-wm831x.c +++ b/drivers/clk/clk-wm831x.c @@ -370,43 +370,27 @@ static __devinit int wm831x_clk_probe(struct platform_device *pdev) clkdata->xtal_ena = ret & WM831X_XTAL_ENA; clkdata->xtal_hw.init = &wm831x_xtal_init; - clkdata->xtal = clk_register(&pdev->dev, &clkdata->xtal_hw); + clkdata->xtal = devm_clk_register(&pdev->dev, &clkdata->xtal_hw); if (IS_ERR(clkdata->xtal)) return PTR_ERR(clkdata->xtal); clkdata->fll_hw.init = &wm831x_fll_init; - clkdata->fll = clk_register(&pdev->dev, &clkdata->fll_hw); - if (IS_ERR(clkdata->fll)) { - ret = PTR_ERR(clkdata->fll); - goto err_xtal; - } + clkdata->fll = devm_clk_register(&pdev->dev, &clkdata->fll_hw); + if (IS_ERR(clkdata->fll)) + return PTR_ERR(clkdata->fll); clkdata->clkout_hw.init = &wm831x_clkout_init; - clkdata->clkout = clk_register(&pdev->dev, &clkdata->clkout_hw); - if (IS_ERR(clkdata->clkout)) { - ret = PTR_ERR(clkdata->clkout); - goto err_fll; - } + clkdata->clkout = devm_clk_register(&pdev->dev, &clkdata->clkout_hw); + if (IS_ERR(clkdata->clkout)) + return PTR_ERR(clkdata->clkout); dev_set_drvdata(&pdev->dev, clkdata); return 0; - -err_fll: - clk_unregister(clkdata->fll); -err_xtal: - clk_unregister(clkdata->xtal); - return ret; } static int __devexit wm831x_clk_remove(struct platform_device *pdev) { - struct wm831x_clk *clkdata = dev_get_drvdata(&pdev->dev); - - clk_unregister(clkdata->clkout); - clk_unregister(clkdata->fll); - clk_unregister(clkdata->xtal); - return 0; } -- cgit v1.2.3 From dcbf832e5823156e8f155359b47bd108cac8ad68 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Fri, 5 Oct 2012 23:07:19 +0200 Subject: vtime: Gather vtime declarations to their own header file These APIs are scattered around and are going to expand a bit. Let's create a dedicated header file for sanity. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Steven Rostedt Cc: Paul Gortmaker --- include/linux/hardirq.h | 11 +---------- include/linux/kernel_stat.h | 9 +-------- include/linux/vtime.h | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 include/linux/vtime.h diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index cab3da3d094..b083a475423 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -4,6 +4,7 @@ #include #include #include +#include #include /* @@ -129,16 +130,6 @@ extern void synchronize_irq(unsigned int irq); # define synchronize_irq(irq) barrier() #endif -struct task_struct; - -#if !defined(CONFIG_VIRT_CPU_ACCOUNTING) && !defined(CONFIG_IRQ_TIME_ACCOUNTING) -static inline void vtime_account(struct task_struct *tsk) -{ -} -#else -extern void vtime_account(struct task_struct *tsk); -#endif - #if defined(CONFIG_TINY_RCU) || defined(CONFIG_TINY_PREEMPT_RCU) static inline void rcu_nmi_enter(void) diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 36d12f0884c..1865b1f2977 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -130,12 +131,4 @@ extern void account_process_tick(struct task_struct *, int user); extern void account_steal_ticks(unsigned long ticks); extern void account_idle_ticks(unsigned long ticks); -#ifdef CONFIG_VIRT_CPU_ACCOUNTING -extern void vtime_task_switch(struct task_struct *prev); -extern void vtime_account_system(struct task_struct *tsk); -extern void vtime_account_idle(struct task_struct *tsk); -#else -static inline void vtime_task_switch(struct task_struct *prev) { } -#endif - #endif /* _LINUX_KERNEL_STAT_H */ diff --git a/include/linux/vtime.h b/include/linux/vtime.h new file mode 100644 index 00000000000..7199c24c820 --- /dev/null +++ b/include/linux/vtime.h @@ -0,0 +1,22 @@ +#ifndef _LINUX_KERNEL_VTIME_H +#define _LINUX_KERNEL_VTIME_H + +struct task_struct; + +#ifdef CONFIG_VIRT_CPU_ACCOUNTING +extern void vtime_task_switch(struct task_struct *prev); +extern void vtime_account_system(struct task_struct *tsk); +extern void vtime_account_idle(struct task_struct *tsk); +#else +static inline void vtime_task_switch(struct task_struct *prev) { } +#endif + +#if !defined(CONFIG_VIRT_CPU_ACCOUNTING) && !defined(CONFIG_IRQ_TIME_ACCOUNTING) +static inline void vtime_account(struct task_struct *tsk) +{ +} +#else +extern void vtime_account(struct task_struct *tsk); +#endif + +#endif /* _LINUX_KERNEL_VTIME_H */ -- cgit v1.2.3 From 11113334d1c5dd5355c86e531c29f1202a855c86 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 24 Oct 2012 18:05:51 +0200 Subject: vtime: Make vtime_account_system() irqsafe vtime_account_system() currently has only one caller with vtime_account() which is irq safe. Now we are going to call it from other places like kvm where irqs are not always disabled by the time we account the cputime. So let's make it irqsafe. The arch implementation part is now prefixed with "__". vtime_account_idle() arch implementation is prefixed accordingly to stay consistent. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Steven Rostedt Cc: Paul Gortmaker Cc: Tony Luck Cc: Fenghua Yu Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Martin Schwidefsky Cc: Heiko Carstens --- arch/ia64/kernel/time.c | 8 ++++---- arch/powerpc/kernel/time.c | 4 ++-- arch/s390/kernel/vtime.c | 4 ++++ include/linux/vtime.h | 4 +++- kernel/sched/cputime.c | 16 +++++++++++++--- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index f6388216080..5e4850305d3 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -106,9 +106,9 @@ void vtime_task_switch(struct task_struct *prev) struct thread_info *ni = task_thread_info(current); if (idle_task(smp_processor_id()) != prev) - vtime_account_system(prev); + __vtime_account_system(prev); else - vtime_account_idle(prev); + __vtime_account_idle(prev); vtime_account_user(prev); @@ -135,14 +135,14 @@ static cputime_t vtime_delta(struct task_struct *tsk) return delta_stime; } -void vtime_account_system(struct task_struct *tsk) +void __vtime_account_system(struct task_struct *tsk) { cputime_t delta = vtime_delta(tsk); account_system_time(tsk, 0, delta, delta); } -void vtime_account_idle(struct task_struct *tsk) +void __vtime_account_idle(struct task_struct *tsk) { account_idle_time(vtime_delta(tsk)); } diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index ce4cb772dc7..0db456f30d4 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -336,7 +336,7 @@ static u64 vtime_delta(struct task_struct *tsk, return delta; } -void vtime_account_system(struct task_struct *tsk) +void __vtime_account_system(struct task_struct *tsk) { u64 delta, sys_scaled, stolen; @@ -346,7 +346,7 @@ void vtime_account_system(struct task_struct *tsk) account_steal_time(stolen); } -void vtime_account_idle(struct task_struct *tsk) +void __vtime_account_idle(struct task_struct *tsk) { u64 delta, sys_scaled, stolen; diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 79033442789..783e988c4e1 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -140,6 +140,10 @@ void vtime_account(struct task_struct *tsk) } EXPORT_SYMBOL_GPL(vtime_account); +void __vtime_account_system(struct task_struct *tsk) +__attribute__((alias("vtime_account"))); +EXPORT_SYMBOL_GPL(__vtime_account_system); + void __kprobes vtime_stop_cpu(void) { struct s390_idle_data *idle = &__get_cpu_var(s390_idle); diff --git a/include/linux/vtime.h b/include/linux/vtime.h index 7199c24c820..b9fc4f9ab47 100644 --- a/include/linux/vtime.h +++ b/include/linux/vtime.h @@ -5,10 +5,12 @@ struct task_struct; #ifdef CONFIG_VIRT_CPU_ACCOUNTING extern void vtime_task_switch(struct task_struct *prev); +extern void __vtime_account_system(struct task_struct *tsk); extern void vtime_account_system(struct task_struct *tsk); -extern void vtime_account_idle(struct task_struct *tsk); +extern void __vtime_account_idle(struct task_struct *tsk); #else static inline void vtime_task_switch(struct task_struct *prev) { } +static inline void vtime_account_system(struct task_struct *tsk) { } #endif #if !defined(CONFIG_VIRT_CPU_ACCOUNTING) && !defined(CONFIG_IRQ_TIME_ACCOUNTING) diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 81b763ba58a..0359f47b0ae 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -433,10 +433,20 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st) *st = cputime.stime; } +void vtime_account_system(struct task_struct *tsk) +{ + unsigned long flags; + + local_irq_save(flags); + __vtime_account_system(tsk); + local_irq_restore(flags); +} +EXPORT_SYMBOL_GPL(vtime_account_system); + /* * Archs that account the whole time spent in the idle task * (outside irq) as idle time can rely on this and just implement - * vtime_account_system() and vtime_account_idle(). Archs that + * __vtime_account_system() and __vtime_account_idle(). Archs that * have other meaning of the idle time (s390 only includes the * time spent by the CPU when it's in low power mode) must override * vtime_account(). @@ -449,9 +459,9 @@ void vtime_account(struct task_struct *tsk) local_irq_save(flags); if (in_interrupt() || !is_idle_task(tsk)) - vtime_account_system(tsk); + __vtime_account_system(tsk); else - vtime_account_idle(tsk); + __vtime_account_idle(tsk); local_irq_restore(flags); } -- cgit v1.2.3 From b080935c8638e08134629d0a9ebdf35669bec14d Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Fri, 5 Oct 2012 23:07:19 +0200 Subject: kvm: Directly account vtime to system on guest switch Switching to or from guest context is done on ioctl context. So by the time we call kvm_guest_enter() or kvm_guest_exit() we know we are not running the idle task. As a result, we can directly account the cputime using vtime_account_system(). There are two good reasons to do this: * We avoid some useless checks on guest switch. It optimizes a bit this fast path. * In the case of CONFIG_IRQ_TIME_ACCOUNTING, calling vtime_account() checks for irq time to account. This is pointless since we know we are not in an irq on guest switch. This is wasting cpu cycles for no good reason. vtime_account_system() OTOH is a no-op in this config option. * We can remove the irq disable/enable around kvm guest switch in s390. A further optimization may consist in introducing a vtime_account_guest() that directly calls account_guest_time(). Signed-off-by: Frederic Weisbecker Cc: Tony Luck Cc: Fenghua Yu Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: Avi Kivity Cc: Marcelo Tosatti Cc: Joerg Roedel Cc: Alexander Graf Cc: Xiantao Zhang Cc: Christian Borntraeger Cc: Cornelia Huck Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Steven Rostedt Cc: Paul Gortmaker --- arch/s390/kvm/kvm-s390.c | 4 ---- include/linux/kvm_host.h | 12 ++++++++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index ecced9d1898..d91a9556800 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -608,9 +608,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) kvm_s390_deliver_pending_interrupts(vcpu); vcpu->arch.sie_block->icptcode = 0; - local_irq_disable(); kvm_guest_enter(); - local_irq_enable(); VCPU_EVENT(vcpu, 6, "entering sie flags %x", atomic_read(&vcpu->arch.sie_block->cpuflags)); trace_kvm_s390_sie_enter(vcpu, @@ -629,9 +627,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", vcpu->arch.sie_block->icptcode); trace_kvm_s390_sie_exit(vcpu, vcpu->arch.sie_block->icptcode); - local_irq_disable(); kvm_guest_exit(); - local_irq_enable(); memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); return rc; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 93bfc9f9815..0e2212fe478 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -737,7 +737,11 @@ static inline int kvm_deassign_device(struct kvm *kvm, static inline void kvm_guest_enter(void) { BUG_ON(preemptible()); - vtime_account(current); + /* + * This is running in ioctl context so we can avoid + * the call to vtime_account() with its unnecessary idle check. + */ + vtime_account_system(current); current->flags |= PF_VCPU; /* KVM does not hold any references to rcu protected data when it * switches CPU into a guest mode. In fact switching to a guest mode @@ -751,7 +755,11 @@ static inline void kvm_guest_enter(void) static inline void kvm_guest_exit(void) { - vtime_account(current); + /* + * This is running in ioctl context so we can avoid + * the call to vtime_account() with its unnecessary idle check. + */ + vtime_account_system(current); current->flags &= ~PF_VCPU; } -- cgit v1.2.3 From fa5058f3b63153e0147ef65bcdb3a4ee63581346 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sat, 6 Oct 2012 04:07:19 +0200 Subject: cputime: Specialize irq vtime hooks With CONFIG_VIRT_CPU_ACCOUNTING, when vtime_account() is called in irq entry/exit, we perform a check on the context: if we are interrupting the idle task we account the pending cputime to idle, otherwise account to system time or its sub-areas: tsk->stime, hardirq time, softirq time, ... However this check for idle only concerns the hardirq entry and softirq entry: * Hardirq may directly interrupt the idle task, in which case we need to flush the pending CPU time to idle. * The idle task may be directly interrupted by a softirq if it calls local_bh_enable(). There is probably no such call in any idle task but we need to cover every case. Ksoftirqd is not concerned because the idle time is flushed on context switch and softirq in the end of hardirq have the idle time already flushed from the hardirq entry. In the other cases we always account to system/irq time: * On hardirq exit we account the time to hardirq time. * On softirq exit we account the time to softirq time. To optimize this and avoid the indirect call to vtime_account() and the checks it performs, specialize the vtime irq APIs and only perform the check on irq entry. Irq exit can directly call vtime_account_system(). CONFIG_IRQ_TIME_ACCOUNTING behaviour doesn't change and directly maps to its own vtime_account() implementation. One may want to take benefits from the new APIs to optimize irq time accounting as well in the future. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Steven Rostedt Cc: Paul Gortmaker --- include/linux/hardirq.h | 4 ++-- include/linux/vtime.h | 25 +++++++++++++++++++++++++ kernel/softirq.c | 6 +++--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index b083a475423..624ef3f45c8 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -153,7 +153,7 @@ extern void rcu_nmi_exit(void); */ #define __irq_enter() \ do { \ - vtime_account(current); \ + vtime_account_irq_enter(current); \ add_preempt_count(HARDIRQ_OFFSET); \ trace_hardirq_enter(); \ } while (0) @@ -169,7 +169,7 @@ extern void irq_enter(void); #define __irq_exit() \ do { \ trace_hardirq_exit(); \ - vtime_account(current); \ + vtime_account_irq_exit(current); \ sub_preempt_count(HARDIRQ_OFFSET); \ } while (0) diff --git a/include/linux/vtime.h b/include/linux/vtime.h index b9fc4f9ab47..c35c02223da 100644 --- a/include/linux/vtime.h +++ b/include/linux/vtime.h @@ -21,4 +21,29 @@ static inline void vtime_account(struct task_struct *tsk) extern void vtime_account(struct task_struct *tsk); #endif +static inline void vtime_account_irq_enter(struct task_struct *tsk) +{ + /* + * Hardirq can interrupt idle task anytime. So we need vtime_account() + * that performs the idle check in CONFIG_VIRT_CPU_ACCOUNTING. + * Softirq can also interrupt idle task directly if it calls + * local_bh_enable(). Such case probably don't exist but we never know. + * Ksoftirqd is not concerned because idle time is flushed on context + * switch. Softirqs in the end of hardirqs are also not a problem because + * the idle time is flushed on hardirq time already. + */ + vtime_account(tsk); +} + +static inline void vtime_account_irq_exit(struct task_struct *tsk) +{ +#ifdef CONFIG_VIRT_CPU_ACCOUNTING + /* On hard|softirq exit we always account to hard|softirq cputime */ + __vtime_account_system(tsk); +#endif +#ifdef CONFIG_IRQ_TIME_ACCOUNTING + vtime_account(tsk); +#endif +} + #endif /* _LINUX_KERNEL_VTIME_H */ diff --git a/kernel/softirq.c b/kernel/softirq.c index cc96bdc0c2c..ed567babe78 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -221,7 +221,7 @@ asmlinkage void __do_softirq(void) current->flags &= ~PF_MEMALLOC; pending = local_softirq_pending(); - vtime_account(current); + vtime_account_irq_enter(current); __local_bh_disable((unsigned long)__builtin_return_address(0), SOFTIRQ_OFFSET); @@ -272,7 +272,7 @@ restart: lockdep_softirq_exit(); - vtime_account(current); + vtime_account_irq_exit(current); __local_bh_enable(SOFTIRQ_OFFSET); tsk_restore_flags(current, old_flags, PF_MEMALLOC); } @@ -341,7 +341,7 @@ static inline void invoke_softirq(void) */ void irq_exit(void) { - vtime_account(current); + vtime_account_irq_exit(current); trace_hardirq_exit(); sub_preempt_count(IRQ_EXIT_OFFSET); if (!in_interrupt() && local_softirq_pending()) -- cgit v1.2.3 From 3e1df4f506836e6bea1ab61cf88c75c8b1840643 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sat, 6 Oct 2012 05:23:22 +0200 Subject: cputime: Separate irqtime accounting from generic vtime vtime_account() doesn't have the same role in CONFIG_VIRT_CPU_ACCOUNTING and CONFIG_IRQ_TIME_ACCOUNTING. In the first case it handles time accounting in any context. In the second case it only handles irq time accounting. So when vtime_account() is called from outside vtime_account_irq_*() this call is pointless to CONFIG_IRQ_TIME_ACCOUNTING. To fix the confusion, change vtime_account() to irqtime_account_irq() in CONFIG_IRQ_TIME_ACCOUNTING. This way we ensure future account_vtime() calls won't waste useless cycles in the irqtime APIs. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Steven Rostedt Cc: Paul Gortmaker --- include/linux/vtime.h | 18 ++++++++---------- kernel/sched/cputime.c | 4 ++-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/include/linux/vtime.h b/include/linux/vtime.h index c35c02223da..0c2a2d30302 100644 --- a/include/linux/vtime.h +++ b/include/linux/vtime.h @@ -8,17 +8,18 @@ extern void vtime_task_switch(struct task_struct *prev); extern void __vtime_account_system(struct task_struct *tsk); extern void vtime_account_system(struct task_struct *tsk); extern void __vtime_account_idle(struct task_struct *tsk); +extern void vtime_account(struct task_struct *tsk); #else static inline void vtime_task_switch(struct task_struct *prev) { } +static inline void __vtime_account_system(struct task_struct *tsk) { } static inline void vtime_account_system(struct task_struct *tsk) { } +static inline void vtime_account(struct task_struct *tsk) { } #endif -#if !defined(CONFIG_VIRT_CPU_ACCOUNTING) && !defined(CONFIG_IRQ_TIME_ACCOUNTING) -static inline void vtime_account(struct task_struct *tsk) -{ -} +#ifdef CONFIG_IRQ_TIME_ACCOUNTING +extern void irqtime_account_irq(struct task_struct *tsk); #else -extern void vtime_account(struct task_struct *tsk); +static inline void irqtime_account_irq(struct task_struct *tsk) { } #endif static inline void vtime_account_irq_enter(struct task_struct *tsk) @@ -33,17 +34,14 @@ static inline void vtime_account_irq_enter(struct task_struct *tsk) * the idle time is flushed on hardirq time already. */ vtime_account(tsk); + irqtime_account_irq(tsk); } static inline void vtime_account_irq_exit(struct task_struct *tsk) { -#ifdef CONFIG_VIRT_CPU_ACCOUNTING /* On hard|softirq exit we always account to hard|softirq cputime */ __vtime_account_system(tsk); -#endif -#ifdef CONFIG_IRQ_TIME_ACCOUNTING - vtime_account(tsk); -#endif + irqtime_account_irq(tsk); } #endif /* _LINUX_KERNEL_VTIME_H */ diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 0359f47b0ae..8d859dae5be 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -43,7 +43,7 @@ DEFINE_PER_CPU(seqcount_t, irq_time_seq); * Called before incrementing preempt_count on {soft,}irq_enter * and before decrementing preempt_count on {soft,}irq_exit. */ -void vtime_account(struct task_struct *curr) +void irqtime_account_irq(struct task_struct *curr) { unsigned long flags; s64 delta; @@ -73,7 +73,7 @@ void vtime_account(struct task_struct *curr) irq_time_write_end(); local_irq_restore(flags); } -EXPORT_SYMBOL_GPL(vtime_account); +EXPORT_SYMBOL_GPL(irqtime_account_irq); static int irqtime_account_hi_update(void) { -- cgit v1.2.3 From 438d2d1329914da8fdf3a8aedac8ce7e5ffad26d Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 27 Oct 2012 02:09:58 -0400 Subject: staging: csr: remove func_enter macro this macro is used for debugging purposes, it actually defined as if (unifi_debug >= 5) { printk("unifi => %s\n", __FUNCTION__); } which produces too many of those prints if the unifi_debug is >=5. remove these calls and the macro itself altogether Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_hip_card_sdio.c | 56 ---------------------------- drivers/staging/csr/csr_wifi_hip_download.c | 4 -- drivers/staging/csr/csr_wifi_hip_dump.c | 17 --------- drivers/staging/csr/drv.c | 16 -------- drivers/staging/csr/firmware.c | 4 -- drivers/staging/csr/io.c | 6 --- drivers/staging/csr/mlme.c | 2 - drivers/staging/csr/monitor.c | 6 --- drivers/staging/csr/netdev.c | 26 ------------- drivers/staging/csr/sdio_mmc.c | 12 ------ drivers/staging/csr/sme_native.c | 10 ----- drivers/staging/csr/sme_sys.c | 4 -- drivers/staging/csr/sme_wext.c | 24 ------------ drivers/staging/csr/unifi_event.c | 4 -- drivers/staging/csr/unifi_os.h | 7 ---- drivers/staging/csr/unifi_pdu_processing.c | 11 ------ drivers/staging/csr/unifi_sme.c | 5 --- 17 files changed, 214 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio.c b/drivers/staging/csr/csr_wifi_hip_card_sdio.c index cf148a0fec6..e7819b1189e 100644 --- a/drivers/staging/csr/csr_wifi_hip_card_sdio.c +++ b/drivers/staging/csr/csr_wifi_hip_card_sdio.c @@ -70,8 +70,6 @@ card_t* unifi_alloc_card(CsrSdioFunction *sdio, void *ospriv) card_t *card; u32 i; - func_enter(); - card = kzalloc(sizeof(card_t), GFP_KERNEL); if (card == NULL) @@ -171,7 +169,6 @@ CsrResult unifi_init_card(card_t *card, s32 led_mask) { CsrResult r; - func_enter(); if (card == NULL) { @@ -223,8 +220,6 @@ CsrResult unifi_init(card_t *card) CsrResult r; CsrResult csrResult; - func_enter(); - if (card == NULL) { func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE); @@ -363,8 +358,6 @@ CsrResult unifi_download(card_t *card, s32 led_mask) CsrResult r; void *dlpriv; - func_enter(); - if (card == NULL) { func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE); @@ -425,8 +418,6 @@ static CsrResult unifi_hip_init(card_t *card) CsrResult r; CsrResult csrResult; - func_enter(); - r = card_hw_init(card); if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) { @@ -609,8 +600,6 @@ static CsrResult card_hw_init(card_t *card) s16 search_4slut_again; CsrResult csrResult; - func_enter(); - /* * The device revision from the TPLMID_MANF and TPLMID_CARD fields * of the CIS are available as @@ -1004,8 +993,6 @@ static CsrResult card_wait_for_unifi_to_reset(card_t *card) u8 io_enable; CsrResult csrResult; - func_enter(); - r = CSR_RESULT_SUCCESS; for (i = 0; i < MAILBOX2_ATTEMPTS; i++) { @@ -1136,8 +1123,6 @@ static CsrResult card_wait_for_unifi_to_disable(card_t *card) u8 io_enable; CsrResult csrResult; - func_enter(); - if (card->chip_id <= SDIO_CARD_ID_UNIFI_2) { unifi_error(card->ospriv, @@ -1238,8 +1223,6 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr) u16 mbox0, mbox1; CsrResult r; - func_enter(); - /* * Wait for UniFi to initialise its data structures by polling * the SHARED_MAILBOX1 register. @@ -1358,7 +1341,6 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr) */ CsrResult unifi_capture_panic(card_t *card) { - func_enter(); /* The firmware must have previously initialised to read the panic addresses * from the SLUT @@ -1405,8 +1387,6 @@ static CsrResult card_access_panic(card_t *card) s32 i; CsrResult r, sr; - func_enter(); - /* A chip version of zero means that the version never got succesfully read * during reset. In this case give up because it will not be possible to * verify the chip version. @@ -1536,8 +1516,6 @@ void unifi_read_panic(card_t *card) CsrResult r; u16 p_code, p_arg; - func_enter(); - /* The firmware must have previously initialised to read the panic addresses * from the SLUT */ @@ -1607,8 +1585,6 @@ static CsrResult card_allocate_memory_resources(card_t *card) s16 n, i, k, r; sdio_config_data_t *cfg_data; - func_enter(); - /* Reset any state carried forward from a previous life */ card->fh_command_queue.q_rd_ptr = 0; card->fh_command_queue.q_wr_ptr = 0; @@ -1781,7 +1757,6 @@ static void unifi_free_bulk_data(card_t *card, bulk_data_desc_t *bulk_data_slot) */ static void card_free_memory_resources(card_t *card) { - func_enter(); unifi_trace(card->ospriv, UDBG1, "Freeing card memory resources.\n"); @@ -1820,8 +1795,6 @@ static void card_init_soft_queues(card_t *card) { s16 i; - func_enter(); - unifi_trace(card->ospriv, UDBG1, "Initialising internal signal queues.\n"); /* Reset any state carried forward from a previous life */ card->fh_command_queue.q_rd_ptr = 0; @@ -1858,7 +1831,6 @@ static void card_init_soft_queues(card_t *card) void unifi_cancel_pending_signals(card_t *card) { s16 i, n, r; - func_enter(); unifi_trace(card->ospriv, UDBG1, "Canceling pending signals.\n"); @@ -1951,7 +1923,6 @@ void unifi_cancel_pending_signals(card_t *card) */ void unifi_free_card(card_t *card) { - func_enter(); #ifdef CSR_PRE_ALLOC_NET_DATA prealloc_netdata_free(card); #endif @@ -1989,8 +1960,6 @@ static CsrResult card_init_slots(card_t *card) CsrResult r; u8 i; - func_enter(); - /* Allocate the buffers we need, only once. */ if (card->memory_resources_allocated == 1) { @@ -2153,8 +2122,6 @@ static void CardReassignDynamicReservation(card_t *card) { u8 i; - func_enter(); - unifi_trace(card->ospriv, UDBG5, "Packets Txed %d %d %d %d\n", card->dynamic_slot_data.packets_txed[0], card->dynamic_slot_data.packets_txed[1], @@ -2206,8 +2173,6 @@ static void CardCheckDynamicReservation(card_t *card, unifi_TrafficQueue queue) q_t *sigq; u16 num_data_slots = card->config_data.num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS; - func_enter(); - /* Calculate the pending queue length */ sigq = &card->fh_traffic_queue[queue]; q_len = CSR_WIFI_HIP_Q_SLOTS_USED(sigq); @@ -2336,8 +2301,6 @@ void CardClearFromHostDataSlot(card_t *card, const s16 slot) u8 queue = card->from_host_data[slot].queue; const void *os_data_ptr = card->from_host_data[slot].bd.os_data_ptr; - func_enter(); - if (card->from_host_data[slot].bd.data_length == 0) { unifi_warning(card->ospriv, @@ -2457,8 +2420,6 @@ u16 CardGetFreeFromHostDataSlots(card_t *card) { u16 i, n = 0; - func_enter(); - /* First two slots reserved for MLME */ for (i = 0; i < card->config_data.num_fromhost_data_slots; i++) { @@ -2506,7 +2467,6 @@ u16 CardAreAllFromHostDataSlotsEmpty(card_t *card) static CsrResult unifi_identify_hw(card_t *card) { - func_enter(); card->chip_id = card->sdio_if->sdioId.cardId; card->function = card->sdio_if->sdioId.sdioFunction; @@ -2541,8 +2501,6 @@ static CsrResult unifi_prepare_hw(card_t *card) CsrResult csrResult; enum unifi_host_state old_state = card->host_state; - func_enter(); - r = unifi_identify_hw(card); if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) { @@ -2625,8 +2583,6 @@ static CsrResult unifi_read_chip_version(card_t *card) CsrResult r; u16 ver; - func_enter(); - gbl_chip_version = ChipHelper_GBL_CHIP_VERSION(card->helper); /* Try to read the chip version from register. */ @@ -2684,8 +2640,6 @@ static CsrResult unifi_reset_hardware(card_t *card) u16 new_block_size = UNIFI_IO_BLOCK_SIZE; CsrResult csrResult; - func_enter(); - /* Errors returned by unifi_prepare_hw() are not critical at this point */ r = unifi_prepare_hw(card); if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) @@ -2818,8 +2772,6 @@ static CsrResult card_reset_method_io_enable(card_t *card) CsrResult r; CsrResult csrResult; - func_enter(); - /* * This resets only function 1, so should be used in * preference to the method below (CSR_FUNC_EN) @@ -2915,8 +2867,6 @@ static CsrResult card_reset_method_dbg_reset(card_t *card) { CsrResult r; - func_enter(); - /* * Prepare UniFi for h/w reset */ @@ -3008,8 +2958,6 @@ CsrResult unifi_card_hard_reset(card_t *card) const struct chip_helper_reset_values *init_data; u32 chunks; - func_enter(); - /* Clear cache of page registers */ card->proc_select = (u32)(-1); card->dmem_page = (u32)(-1); @@ -3097,8 +3045,6 @@ CsrResult CardGenInt(card_t *card) { CsrResult r; - func_enter(); - if (card->chip_id > SDIO_CARD_ID_UNIFI_2) { r = sdio_write_f0(card, SDIO_CSR_FROM_HOST_SCRATCH0, @@ -3388,8 +3334,6 @@ CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQue bulk_data_desc_t *bulkdata = csptr->bulkdata; s16 h, nslots; - func_enter(); - /* Count the number of slots required */ for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) { diff --git a/drivers/staging/csr/csr_wifi_hip_download.c b/drivers/staging/csr/csr_wifi_hip_download.c index 6db672caaa0..b97af470f25 100644 --- a/drivers/staging/csr/csr_wifi_hip_download.c +++ b/drivers/staging/csr/csr_wifi_hip_download.c @@ -327,8 +327,6 @@ CsrResult unifi_dl_firmware(card_t *card, void *dlpriv) xbv1_t *fwinfo; CsrResult r; - func_enter(); - fwinfo = kmalloc(sizeof(xbv1_t), GFP_KERNEL); if (fwinfo == NULL) { @@ -407,8 +405,6 @@ CsrResult unifi_dl_patch(card_t *card, void *dlpriv, u32 boot_ctrl) xbv1_t *fwinfo; CsrResult r; - func_enter(); - unifi_info(card->ospriv, "unifi_dl_patch %p %08x\n", dlpriv, boot_ctrl); fwinfo = kmalloc(sizeof(xbv1_t), GFP_KERNEL); diff --git a/drivers/staging/csr/csr_wifi_hip_dump.c b/drivers/staging/csr/csr_wifi_hip_dump.c index f7523590291..cf33b63b20e 100644 --- a/drivers/staging/csr/csr_wifi_hip_dump.c +++ b/drivers/staging/csr/csr_wifi_hip_dump.c @@ -104,8 +104,6 @@ CsrResult unifi_coredump_request_at_next_reset(card_t *card, s8 enable) { CsrResult r; - func_enter(); - if (enable) { unifi_trace(card->ospriv, UDBG2, "Mini-coredump requested after reset\n"); @@ -145,8 +143,6 @@ CsrResult unifi_coredump_handle_request(card_t *card) { CsrResult r = CSR_RESULT_SUCCESS; - func_enter(); - if (card == NULL) { r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; @@ -194,8 +190,6 @@ CsrResult unifi_coredump_capture(card_t *card, struct unifi_coredump_req *req) static u16 dump_seq_no = 1; u32 time_of_capture; - func_enter(); - if (card->dump_next_write == NULL) { r = CSR_RESULT_SUCCESS; @@ -358,8 +352,6 @@ CsrResult unifi_coredump_get_value(card_t *card, struct unifi_coredump_req *req) s32 i = 0; coredump_buffer *find_dump = NULL; - func_enter(); - if (req == NULL || card == NULL) { r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; @@ -481,8 +473,6 @@ static CsrResult unifi_coredump_read_zone(card_t *card, u16 *zonebuf, const stru { CsrResult r; - func_enter(); - if (zonebuf == NULL || def == NULL) { r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; @@ -551,8 +541,6 @@ static CsrResult unifi_coredump_read_zones(card_t *card, coredump_buffer *dump_b CsrResult r = CSR_RESULT_SUCCESS; s32 i; - func_enter(); - /* Walk the table of coredump zone definitions and read them from the chip */ for (i = 0; (i < HIP_CDUMP_NUM_ZONES) && (r == 0); @@ -590,8 +578,6 @@ static CsrResult unifi_coredump_from_sdio(card_t *card, coredump_buffer *dump_bu CsrResult r; u32 sdio_addr; - func_enter(); - if (dump_buf == NULL) { r = CSR_WIFI_HIP_RESULT_INVALID_VALUE; @@ -743,8 +729,6 @@ CsrResult unifi_coredump_init(card_t *card, u16 num_dump_buffers) u32 i = 0; #endif - func_enter(); - card->request_coredump_on_reset = 0; card->dump_next_write = NULL; card->dump_cur_read = NULL; @@ -826,7 +810,6 @@ void unifi_coredump_free(card_t *card) s16 i = 0; s16 j; - func_enter(); unifi_trace(ospriv, UDBG2, "Core dump de-configured\n"); if (card->dump_buf == NULL) diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c index 249758076a7..b301458142e 100644 --- a/drivers/staging/csr/drv.c +++ b/drivers/staging/csr/drv.c @@ -266,8 +266,6 @@ unifi_open(struct inode *inode, struct file *file) unifi_priv_t *priv; ul_client_t *udi_cli; - func_enter(); - devno = MINOR(inode->i_rdev) >> 1; /* @@ -369,8 +367,6 @@ unifi_release(struct inode *inode, struct file *filp) int devno; unifi_priv_t *priv; - func_enter(); - priv = uf_find_instance(udi_cli->instance); if (!priv) { unifi_error(priv, "unifi_close: instance for device not found\n"); @@ -465,8 +461,6 @@ unifi_read(struct file *filp, char *p, size_t len, loff_t *poff) struct list_head *l; int msglen; - func_enter(); - priv = uf_find_instance(pcli->instance); if (!priv) { unifi_error(priv, "invalid priv\n"); @@ -654,8 +648,6 @@ udi_send_signal_raw(unifi_priv_t *priv, unsigned char *buf, int buflen) int bytecount; CsrResult csrResult; - func_enter(); - /* * The signal is the first thing in buf, the signal id is the * first 16 bits of the signal. @@ -784,8 +776,6 @@ unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff) bulk_data_param_t bulkdata; CsrResult csrResult; - func_enter(); - priv = uf_find_instance(pcli->instance); if (!priv) { unifi_error(priv, "invalid priv\n"); @@ -1657,8 +1647,6 @@ unifi_poll(struct file *filp, poll_table *wait) unsigned int mask = 0; int ready; - func_enter(); - ready = !list_empty(&pcli->udi_log); poll_wait(filp, &pcli->udi_wq, wait); @@ -1784,8 +1772,6 @@ udi_log_event(ul_client_t *pcli, unsigned long n_1000; #endif - func_enter(); - /* Just a sanity check */ if ((signal == NULL) || (signal_len <= 0)) { return; @@ -1921,8 +1907,6 @@ uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length) udi_msg_t *msgptr; u8 *p; - func_enter(); - /* Just a sanity check */ if ((buffer == NULL) || (length <= 0)) { return -EINVAL; diff --git a/drivers/staging/csr/firmware.c b/drivers/staging/csr/firmware.c index b6d8a6e5291..881acc90e53 100644 --- a/drivers/staging/csr/firmware.c +++ b/drivers/staging/csr/firmware.c @@ -62,8 +62,6 @@ unifi_fw_read_start(void *ospriv, s8 is_fw, const card_info_t *info) unifi_priv_t *priv = (unifi_priv_t*)ospriv; CSR_UNUSED(info); - func_enter(); - if (is_fw == UNIFI_FW_STA) { /* F/w may have been released after a previous successful download. */ if (priv->fw_sta.dl_data == NULL) { @@ -105,7 +103,6 @@ unifi_fw_read_stop(void *ospriv, void *dlpriv) { unifi_priv_t *priv = (unifi_priv_t*)ospriv; struct dlpriv *dl_struct = (struct dlpriv *)dlpriv; - func_enter(); if (dl_struct != NULL) { if (dl_struct->dl_data != NULL) { @@ -143,7 +140,6 @@ void * unifi_fw_open_buffer(void *ospriv, void *fwbuf, u32 len) { unifi_priv_t *priv = (unifi_priv_t*)ospriv; - func_enter(); if (fwbuf == NULL) { func_exit(); diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c index 5206cbafff7..95d05264874 100644 --- a/drivers/staging/csr/io.c +++ b/drivers/staging/csr/io.c @@ -85,7 +85,6 @@ static int uf_read_proc(char *page, char **start, off_t offset, int count, static CsrResult signal_buffer_init(unifi_priv_t * priv, int size) { int i; - func_enter(); priv->rxSignalBuffer.writePointer = priv->rxSignalBuffer.readPointer = 0; @@ -264,8 +263,6 @@ register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev) int r = -1; CsrResult csrResult; - func_enter(); - if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) { unifi_error(priv, "register_unifi_sdio: invalid device %d\n", bus_id); @@ -472,7 +469,6 @@ failed0: static void ask_unifi_sdio_cleanup(unifi_priv_t *priv) { - func_enter(); /* * Now clear the flag that says the old instance is in use. @@ -510,8 +506,6 @@ cleanup_unifi_sdio(unifi_priv_t *priv) int i; static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; - func_enter(); - /* Remove the device nodes */ uf_destroy_device_nodes(priv); diff --git a/drivers/staging/csr/mlme.c b/drivers/staging/csr/mlme.c index ed767eccbb3..723ecb37859 100644 --- a/drivers/staging/csr/mlme.c +++ b/drivers/staging/csr/mlme.c @@ -154,8 +154,6 @@ unifi_mlme_blocking_request(unifi_priv_t *priv, ul_client_t *pcli, { int r; - func_enter(); - if (sig->SignalPrimitiveHeader.SignalId == 0) { unifi_error(priv, "unifi_mlme_blocking_request: Invalid Signal Id (0x%x)\n", sig->SignalPrimitiveHeader.SignalId); diff --git a/drivers/staging/csr/monitor.c b/drivers/staging/csr/monitor.c index 7b76f07ff33..60d52f9e8c3 100644 --- a/drivers/staging/csr/monitor.c +++ b/drivers/staging/csr/monitor.c @@ -121,8 +121,6 @@ netrx_radiotap(unifi_priv_t *priv, struct unifi_rx_radiotap_header *unifi_rt; int signal, noise, snr; - func_enter(); - if (ind_data_len <= 0) { unifi_error(priv, "Invalid length in CSR_MA_SNIFFDATA_INDICATION.\n"); return; @@ -255,8 +253,6 @@ netrx_prism(unifi_priv_t *priv, } *avs; int signal, noise, snr; - func_enter(); - if (ind_data_len <= 0) { unifi_error(priv, "Invalid length in CSR_MA_SNIFFDATA_INDICATION.\n"); return; @@ -350,8 +346,6 @@ ma_sniffdata_ind(void *ospriv, struct net_device *dev = priv->netdev; struct sk_buff *skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr; - func_enter(); - if (bulkdata->d[0].data_length == 0) { unifi_warning(priv, "rx: MA-SNIFFDATA indication with zero bulk data\n"); func_exit(); diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 113f2c189a6..ca9cc31f116 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -477,8 +477,6 @@ uf_free_netdevice(unifi_priv_t *priv) int i; unsigned long flags; - func_enter(); - unifi_trace(priv, UDBG1, "uf_free_netdevice\n"); if (!priv) { @@ -577,8 +575,6 @@ uf_net_open(struct net_device *dev) netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); unifi_priv_t *priv = interfacePriv->privPtr; - func_enter(); - /* If we haven't finished UniFi initialisation, we can't start */ if (priv->init_progress != UNIFI_INIT_COMPLETED) { unifi_warning(priv, "%s: unifi not ready, failing net_open\n", __FUNCTION__); @@ -626,8 +622,6 @@ uf_net_stop(struct net_device *dev) netInterface_priv_t *interfacePriv = (netInterface_priv_t*)netdev_priv(dev); unifi_priv_t *priv = interfacePriv->privPtr; - func_enter(); - /* Stop sniffing if in Monitor mode */ if (priv->wext_conf.mode == IW_MODE_MONITOR) { if (priv->card) { @@ -638,8 +632,6 @@ uf_net_stop(struct net_device *dev) } } } -#else - func_enter(); #endif netif_tx_stop_all_queues(dev); @@ -674,7 +666,6 @@ static CSR_PRIORITY uf_get_packet_priority(unifi_priv_t *priv, netInterface_priv { CSR_PRIORITY priority = CSR_CONTENTION; - func_enter(); priority = (CSR_PRIORITY) (skb->priority >> 5); if (priority == CSR_QOS_UP0) { /* 0 */ @@ -749,8 +740,6 @@ get_packet_priority(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr u8 interfaceMode = interfacePriv->interfaceMode; - func_enter(); - /* Priority Mapping for all the Modes */ switch(interfaceMode) { @@ -815,8 +804,6 @@ uf_net_select_queue(struct net_device *dev, struct sk_buff *skb) int proto; CSR_PRIORITY priority; - func_enter(); - memcpy(&ehdr, skb->data, ETH_HLEN); proto = ntohs(ehdr.h_proto); @@ -1759,8 +1746,6 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev) CSR_PRIORITY priority; CsrWifiRouterCtrlPortAction port_action; - func_enter(); - unifi_trace(priv, UDBG5, "unifi_net_xmit: skb = %x\n", skb); memcpy(&ehdr, skb->data, ETH_HLEN); @@ -1876,7 +1861,6 @@ unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue) unifi_priv_t *priv = ospriv; int i; /* used as a loop counter */ - func_enter(); unifi_trace(priv, UDBG2, "Stopping queue %d\n", queue); for(i=0;iVirtualInterfaceIdentifier & 0xff); interfacePriv = priv->interfacePriv[interfaceTag]; @@ -2455,7 +2436,6 @@ static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d const CSR_MA_PACKET_CONFIRM *pkt_cfm = &signal->u.MaPacketConfirm; netInterface_priv_t *interfacePriv; - func_enter(); interfaceTag = (pkt_cfm->VirtualInterfaceIdentifier & 0xff); interfacePriv = priv->interfacePriv[interfaceTag]; @@ -2527,8 +2507,6 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d #endif - func_enter(); - interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff); interfacePriv = priv->interfacePriv[interfaceTag]; @@ -2835,8 +2813,6 @@ netdev_mlme_event_handler(ul_client_t *pcli, const u8 *sig_packed, int sig_len, int id, r; bulk_data_param_t bulkdata; - func_enter(); - /* Just a sanity check */ if (sig_packed == NULL) { return; @@ -3330,8 +3306,6 @@ static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, CSR_PRIORITY UserPriority; CSR_SEQUENCE_NUMBER sn; - func_enter(); - interfaceTag = (pkt_err_ind->VirtualInterfaceIdentifier & 0xff); diff --git a/drivers/staging/csr/sdio_mmc.c b/drivers/staging/csr/sdio_mmc.c index 6b96df11baa..0b90630d332 100644 --- a/drivers/staging/csr/sdio_mmc.c +++ b/drivers/staging/csr/sdio_mmc.c @@ -540,8 +540,6 @@ CsrSdioFunctionEnable(CsrSdioFunction *function) struct sdio_func *func = (struct sdio_func *)function->priv; int err; - func_enter(); - /* Enable UniFi function 1 (the 802.11 part). */ _sdio_claim_host(func); err = sdio_enable_func(func); @@ -574,8 +572,6 @@ CsrSdioFunctionDisable(CsrSdioFunction *function) struct sdio_func *func = (struct sdio_func *)function->priv; int err; - func_enter(); - /* Disable UniFi function 1 (the 802.11 part). */ _sdio_claim_host(func); err = sdio_disable_func(func); @@ -1033,8 +1029,6 @@ uf_glue_sdio_probe(struct sdio_func *func, int instance; CsrSdioFunction *sdio_ctx; - func_enter(); - /* First of all claim the SDIO driver */ sdio_claim_host(func); @@ -1130,8 +1124,6 @@ uf_glue_sdio_remove(struct sdio_func *func) return; } - func_enter(); - unifi_info(NULL, "UniFi card removed\n"); /* Clean up the SDIO function driver */ @@ -1182,8 +1174,6 @@ MODULE_DEVICE_TABLE(sdio, unifi_ids); static int uf_glue_sdio_suspend(struct device *dev) { - func_enter(); - unifi_trace(NULL, UDBG1, "uf_glue_sdio_suspend"); func_exit(); @@ -1207,8 +1197,6 @@ uf_glue_sdio_suspend(struct device *dev) static int uf_glue_sdio_resume(struct device *dev) { - func_enter(); - unifi_trace(NULL, UDBG1, "uf_glue_sdio_resume"); #ifdef ANDROID_BUILD diff --git a/drivers/staging/csr/sme_native.c b/drivers/staging/csr/sme_native.c index 26f10bcbe03..dcecc86fb4a 100644 --- a/drivers/staging/csr/sme_native.c +++ b/drivers/staging/csr/sme_native.c @@ -21,8 +21,6 @@ static const unsigned char wildcard_address[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, int uf_sme_init(unifi_priv_t *priv) { - func_enter(); - sema_init(&priv->mlme_blocking_mutex, 1); #ifdef CSR_SUPPORT_WEXT @@ -46,8 +44,6 @@ void uf_sme_deinit(unifi_priv_t *priv) { - func_enter(); - /* Free memory allocated for the scan table */ /* unifi_clear_scan_table(priv); */ @@ -221,8 +217,6 @@ sme_native_log_event(ul_client_t *pcli, CSR_SIGNAL signal; ul_client_t *client = pcli; - func_enter(); - if (client == NULL) { unifi_error(NULL, "sme_native_log_event: client has exited\n"); return; @@ -460,8 +454,6 @@ sme_native_mlme_event_handler(ul_client_t *pcli, unifi_priv_t *priv = uf_find_instance(pcli->instance); int id, r; - func_enter(); - /* Just a sanity check */ if ((sig_packed == NULL) || (sig_len <= 0)) { return; @@ -573,8 +565,6 @@ unifi_reset_state(unifi_priv_t *priv, unsigned char *macaddr, { int r = 0; - func_enter(); - #ifdef CSR_SUPPORT_WEXT /* The reset clears any 802.11 association. */ priv->wext_conf.flag_associated = 0; diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c index 9c5ca3a9261..c9a819a1686 100644 --- a/drivers/staging/csr/sme_sys.c +++ b/drivers/staging/csr/sme_sys.c @@ -412,8 +412,6 @@ uf_send_gratuitous_arp(unifi_priv_t *priv, u16 interfaceTag) 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x02}; - func_enter(); - csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], sizeof(arp_req)); if (csrResult != CSR_RESULT_SUCCESS) { @@ -2410,8 +2408,6 @@ void uf_send_disconnected_ind_wq(struct work_struct *work) struct list_head send_cfm_list; u8 j; - func_enter(); - if(!staInfo) { return; } diff --git a/drivers/staging/csr/sme_wext.c b/drivers/staging/csr/sme_wext.c index b58c0c6b171..461b8692a05 100644 --- a/drivers/staging/csr/sme_wext.c +++ b/drivers/staging/csr/sme_wext.c @@ -800,7 +800,6 @@ iwprivsconfwapi(struct net_device *dev, struct iw_request_info *info, u8 enable; netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); unifi_priv_t *priv = interfacePriv->privPtr; - func_enter(); unifi_trace(priv, UDBG1, "iwprivsconfwapi\n" ); @@ -837,7 +836,6 @@ iwprivswpikey(struct net_device *dev, struct iw_request_info *info, unifiio_wapi_key_t inKey; netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); unifi_priv_t *priv = interfacePriv->privPtr; - func_enter(); unifi_trace(priv, UDBG1, "iwprivswpikey\n" ); @@ -914,7 +912,6 @@ unifi_siwfreq(struct net_device *dev, struct iw_request_info *info, unifi_priv_t *priv = interfacePriv->privPtr; struct iw_freq *freq = (struct iw_freq *)wrqu; - func_enter(); unifi_trace(priv, UDBG2, "unifi_siwfreq\n"); if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || @@ -950,7 +947,6 @@ unifi_giwfreq(struct net_device *dev, struct iw_request_info *info, int err = 0; CsrWifiSmeConnectionInfo connectionInfo; - func_enter(); unifi_trace(priv, UDBG2, "unifi_giwfreq\n"); CHECK_INITED(priv); @@ -982,7 +978,6 @@ unifi_siwmode(struct net_device *dev, struct iw_request_info *info, netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); unifi_priv_t *priv = interfacePriv->privPtr; - func_enter(); unifi_trace(priv, UDBG2, "unifi_siwmode\n"); if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || @@ -1026,7 +1021,6 @@ unifi_giwmode(struct net_device *dev, struct iw_request_info *info, unifi_priv_t *priv = interfacePriv->privPtr; CsrWifiSmeConnectionConfig connectionConfig; - func_enter(); unifi_trace(priv, UDBG2, "unifi_giwmode\n"); CHECK_INITED(priv); @@ -1192,8 +1186,6 @@ unifi_siwap(struct net_device *dev, struct iw_request_info *info, unifi_priv_t *priv = interfacePriv->privPtr; int err = 0; - func_enter(); - CHECK_INITED(priv); if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || @@ -1255,8 +1247,6 @@ unifi_giwap(struct net_device *dev, struct iw_request_info *info, int r = 0; u8 *bssid; - func_enter(); - CHECK_INITED(priv); unifi_trace(priv, UDBG2, "unifi_giwap\n"); @@ -1302,8 +1292,6 @@ unifi_siwscan(struct net_device *dev, struct iw_request_info *info, struct iw_scan_req *req = (struct iw_scan_req *) extra; #endif - func_enter(); - CHECK_INITED(priv); if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || @@ -1707,7 +1695,6 @@ unifi_siwessid(struct net_device *dev, struct iw_request_info *info, int len; int err = 0; - func_enter(); CHECK_INITED(priv); if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || @@ -1779,7 +1766,6 @@ unifi_giwessid(struct net_device *dev, struct iw_request_info *info, CsrWifiSmeConnectionInfo connectionInfo; int r = 0; - func_enter(); unifi_trace(priv, UDBG2, "unifi_giwessid\n"); CHECK_INITED(priv); @@ -1821,8 +1807,6 @@ unifi_siwrate(struct net_device *dev, struct iw_request_info *info, CsrWifiSmeMibConfig mibConfig; int r; - func_enter(); - CHECK_INITED(priv); unifi_trace(priv, UDBG2, "unifi_siwrate\n"); @@ -1882,7 +1866,6 @@ unifi_giwrate(struct net_device *dev, struct iw_request_info *info, CsrWifiSmeMibConfig mibConfig; CsrWifiSmeConnectionStats connectionStats; - func_enter(); unifi_trace(priv, UDBG2, "unifi_giwrate\n"); CHECK_INITED(priv); @@ -2081,7 +2064,6 @@ unifi_siwencode(struct net_device *dev, struct iw_request_info *info, int privacy = -1; CsrWifiSmeKey sme_key; - func_enter(); unifi_trace(priv, UDBG2, "unifi_siwencode\n"); CHECK_INITED(priv); @@ -2467,7 +2449,6 @@ unifi_siwmlme(struct net_device *dev, struct iw_request_info *info, netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev); unifi_priv_t *priv = interfacePriv->privPtr; struct iw_mlme *mlme = (struct iw_mlme *)extra; - func_enter(); unifi_trace(priv, UDBG2, "unifi_siwmlme\n"); CHECK_INITED(priv); @@ -2529,7 +2510,6 @@ unifi_siwgenie(struct net_device *dev, struct iw_request_info *info, unifi_priv_t *priv = interfacePriv->privPtr; int len; - func_enter(); unifi_trace(priv, UDBG2, "unifi_siwgenie\n"); if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || @@ -2574,7 +2554,6 @@ unifi_giwgenie(struct net_device *dev, struct iw_request_info *info, unifi_priv_t *priv = interfacePriv->privPtr; int len; - func_enter(); unifi_trace(priv, UDBG2, "unifi_giwgenie\n"); if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || @@ -2627,7 +2606,6 @@ _unifi_siwauth(struct net_device *dev, struct iw_request_info *info, unifi_priv_t *priv = interfacePriv->privPtr; CsrWifiSmeAuthModeMask new_auth; - func_enter(); unifi_trace(priv, UDBG2, "unifi_siwauth\n"); if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || @@ -2911,8 +2889,6 @@ _unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info, CsrWifiSmeKey sme_key; CsrWifiSmeKeyType key_type; - func_enter(); - CHECK_INITED(priv); if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP || diff --git a/drivers/staging/csr/unifi_event.c b/drivers/staging/csr/unifi_event.c index c27b23daf39..f684b93e627 100644 --- a/drivers/staging/csr/unifi_event.c +++ b/drivers/staging/csr/unifi_event.c @@ -376,8 +376,6 @@ unifi_process_receive_event(void *ospriv, s16 signal_id; u8 pktIndToSme = FALSE, freeBulkData = FALSE; - func_enter(); - unifi_trace(priv, UDBG5, "unifi_process_receive_event: " "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n", CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*0) & 0xFFFF, @@ -587,7 +585,6 @@ void unifi_rx_queue_flush(void *ospriv) { unifi_priv_t *priv = (unifi_priv_t*)ospriv; - func_enter(); unifi_trace(priv, UDBG4, "rx_wq_handler: RdPtr = %d WritePtr = %d\n", priv->rxSignalBuffer.readPointer,priv->rxSignalBuffer.writePointer); if(priv != NULL) { @@ -655,7 +652,6 @@ unifi_receive_event(void *ospriv, u8 writePointer; int i; rx_buff_struct_t * rx_buff; - func_enter(); unifi_trace(priv, UDBG5, "unifi_receive_event: " "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n", diff --git a/drivers/staging/csr/unifi_os.h b/drivers/staging/csr/unifi_os.h index 4e63a942f1a..13c7d86d7ce 100644 --- a/drivers/staging/csr/unifi_os.h +++ b/drivers/staging/csr/unifi_os.h @@ -61,12 +61,6 @@ extern int unifi_debug; * etc. */ -#define func_enter() \ - do { \ - if (unifi_debug >= 5) { \ - printk("unifi: => %s\n", __FUNCTION__); \ - } \ - } while (0) #define func_exit() \ do { \ if (unifi_debug >= 5) { \ @@ -107,7 +101,6 @@ void unifi_trace(void* ospriv, int level, const char *fmt, ...); #else /* Stubs */ -#define func_enter() #define func_exit() #define func_exit_r(_rc) diff --git a/drivers/staging/csr/unifi_pdu_processing.c b/drivers/staging/csr/unifi_pdu_processing.c index 8f21d98dff2..453a2afd9b8 100644 --- a/drivers/staging/csr/unifi_pdu_processing.c +++ b/drivers/staging/csr/unifi_pdu_processing.c @@ -2023,7 +2023,6 @@ u8 send_multicast_frames(unifi_priv_t *priv, u16 interfaceTag) netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; u32 hostTag = 0xffffffff; - func_enter(); if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_VO)) { while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastMgtFrames))) { buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK); @@ -2123,7 +2122,6 @@ void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,u8 *sigdata, CSR_RESULT_CODE resultCode = CSR_RC_SUCCESS; netInterface_priv_t *interfacePriv; - func_enter(); unifi_trace(priv, UDBG3, "uf_process_ma_vif_availibility_ind: Process signal 0x%.4X\n", *((u16*)sigdata)); @@ -2368,8 +2366,6 @@ void uf_send_buffered_data_from_ac(unifi_priv_t *priv, u8 moreData = FALSE; s8 r =0; - func_enter(); - unifi_trace(priv,UDBG2,"uf_send_buffered_data_from_ac :\n"); while(!isRouterBufferEnabled(priv,queue) && @@ -2415,7 +2411,6 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q) if(!((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) || (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO))) return; - func_enter(); queue = (q<=3)?q:0; @@ -2769,7 +2764,6 @@ void uf_send_qos_null(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRI CSR_RATE transmitRate = 0; - func_enter(); /* Send a Null Frame to Peer, * 32= size of mac header */ csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], MAC_HEADER_SIZE + QOS_CONTROL_HEADER_SIZE); @@ -2841,7 +2835,6 @@ void uf_send_nulldata(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRI CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest; unsigned long lock_flags; - func_enter(); /* Send a Null Frame to Peer, size = 24 for MAC header */ csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], MAC_HEADER_SIZE); @@ -3326,8 +3319,6 @@ void uf_prepare_send_cfm_list_for_queued_pkts(unifi_priv_t * priv, struct list_head *placeHolder; unsigned long lock_flags; - func_enter(); - spin_lock_irqsave(&priv->tx_q_lock,lock_flags); /* Search through the list and if confirmation required for any frames, @@ -3594,7 +3585,6 @@ void resume_unicast_buffered_frames(unifi_priv_t *priv, u16 interfaceTag) int r; unsigned long lock_flags; - func_enter(); while(!isRouterBufferEnabled(priv,3) && ((buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMgtFrames))!=NULL)) { buffered_pkt->transmissionControl &= @@ -3682,7 +3672,6 @@ void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,u16 interface struct list_head *placeHolder; tx_buffered_packets_t *tx_q_item; - func_enter(); if (interfacePriv->noOfbroadcastPktQueued) { /* Update the EOSP to the HEAD of b/c list diff --git a/drivers/staging/csr/unifi_sme.c b/drivers/staging/csr/unifi_sme.c index ff639d47d07..86fcec6c1b4 100644 --- a/drivers/staging/csr/unifi_sme.c +++ b/drivers/staging/csr/unifi_sme.c @@ -78,7 +78,6 @@ sme_log_event(ul_client_t *pcli, CsrResult result = CSR_RESULT_SUCCESS; int r; - func_enter(); /* Just a sanity check */ if ((signal == NULL) || (signal_len <= 0)) { func_exit(); @@ -1158,8 +1157,6 @@ uf_send_m4_ready_wq(struct work_struct *work) CsrWifiMacAddress peer; unsigned long flags; - func_enter(); - /* The peer address was stored in the signal */ spin_lock_irqsave(&priv->m4_lock, flags); memcpy(peer.a, req->Ra.x, sizeof(peer.a)); @@ -1204,8 +1201,6 @@ void uf_send_pkt_to_encrypt(struct work_struct *work) if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) { - func_enter(); - pktBulkDataLength = interfacePriv->wapi_unicast_bulk_data.data_length; if (pktBulkDataLength > 0) { -- cgit v1.2.3 From 75254af8908501f9cfc6be878c595da02859a0b5 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 27 Oct 2012 02:09:59 -0400 Subject: staging: csr: remove func_exit macro this macro is used for debugging purposes, it actually defined as if (unifi_debug >= 5) { printk("unifi: <= %s\n", __FUNCTION__); } which produces too many of those prints if the unifi_debug is >=5. remove these calls and the macro itself altogether Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_hip_card_sdio.c | 37 ------------------------- drivers/staging/csr/csr_wifi_hip_download.c | 3 -- drivers/staging/csr/csr_wifi_hip_dump.c | 4 --- drivers/staging/csr/csr_wifi_hip_send.c | 2 -- drivers/staging/csr/drv.c | 19 ------------- drivers/staging/csr/firmware.c | 5 ---- drivers/staging/csr/io.c | 9 ------ drivers/staging/csr/mlme.c | 1 - drivers/staging/csr/monitor.c | 3 -- drivers/staging/csr/netdev.c | 41 ---------------------------- drivers/staging/csr/sdio_mmc.c | 9 ------ drivers/staging/csr/sme_native.c | 10 ------- drivers/staging/csr/sme_sys.c | 2 -- drivers/staging/csr/sme_wext.c | 23 ---------------- drivers/staging/csr/unifi_event.c | 4 --- drivers/staging/csr/unifi_os.h | 7 ----- drivers/staging/csr/unifi_pdu_processing.c | 11 -------- drivers/staging/csr/unifi_sme.c | 10 ------- 18 files changed, 200 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio.c b/drivers/staging/csr/csr_wifi_hip_card_sdio.c index e7819b1189e..f025efd0679 100644 --- a/drivers/staging/csr/csr_wifi_hip_card_sdio.c +++ b/drivers/staging/csr/csr_wifi_hip_card_sdio.c @@ -146,7 +146,6 @@ card_t* unifi_alloc_card(CsrSdioFunction *sdio, void *ospriv) } } #endif - func_exit(); return card; } /* unifi_alloc_card() */ @@ -196,7 +195,6 @@ CsrResult unifi_init_card(card_t *card, s32 led_mask) return r; } - func_exit(); return CSR_RESULT_SUCCESS; } @@ -389,8 +387,6 @@ CsrResult unifi_download(card_t *card, s32 led_mask) /* Free the firmware file information. */ unifi_fw_read_stop(card->ospriv, dlpriv); - func_exit(); - return CSR_RESULT_SUCCESS; } /* unifi_download() */ @@ -474,8 +470,6 @@ static CsrResult unifi_hip_init(card_t *card) return r; } - func_exit(); - return CSR_RESULT_SUCCESS; } /* unifi_hip_init() */ @@ -967,7 +961,6 @@ static CsrResult card_hw_init(card_t *card) */ unifi_read_panic(card); - func_exit(); return CSR_RESULT_SUCCESS; } /* card_hw_init() */ @@ -1094,7 +1087,6 @@ static CsrResult card_wait_for_unifi_to_reset(card_t *card) r = CSR_RESULT_FAILURE; } - func_exit(); return r; } /* card_wait_for_unifi_to_reset() */ @@ -1128,7 +1120,6 @@ static CsrResult card_wait_for_unifi_to_disable(card_t *card) unifi_error(card->ospriv, "Function reset method not supported for chip_id=%d\n", card->chip_id); - func_exit(); return CSR_RESULT_FAILURE; } @@ -1195,7 +1186,6 @@ static CsrResult card_wait_for_unifi_to_disable(card_t *card) r = CSR_RESULT_FAILURE; } - func_exit(); return r; } /* card_wait_for_unifi_to_reset() */ @@ -1319,7 +1309,6 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr) *paddr = (((u32)mbox1 << 16) | mbox0); - func_exit(); return CSR_RESULT_SUCCESS; } /* card_wait_for_firmware_to_start() */ @@ -1347,7 +1336,6 @@ CsrResult unifi_capture_panic(card_t *card) */ if (!card->panic_data_phy_addr || !card->panic_data_mac_addr) { - func_exit(); return CSR_RESULT_SUCCESS; } @@ -1362,7 +1350,6 @@ CsrResult unifi_capture_panic(card_t *card) unifi_info(card->ospriv, "Unable to read panic codes"); } - func_exit(); return CSR_RESULT_SUCCESS; } @@ -1562,7 +1549,6 @@ void unifi_read_panic(card_t *card) card->last_mac_panic_arg = p_arg; } - func_exit(); } @@ -1712,7 +1698,6 @@ static CsrResult card_allocate_memory_resources(card_t *card) card->memory_resources_allocated = 1; - func_exit(); return CSR_RESULT_SUCCESS; } /* card_allocate_memory_resources() */ @@ -1787,7 +1772,6 @@ static void card_free_memory_resources(card_t *card) card->memory_resources_allocated = 0; - func_exit(); } /* card_free_memory_resources() */ @@ -1811,7 +1795,6 @@ static void card_init_soft_queues(card_t *card) #ifndef CSR_WIFI_HIP_TA_DISABLE unifi_ta_sampling_init(card); #endif - func_exit(); } @@ -1899,7 +1882,6 @@ void unifi_cancel_pending_signals(card_t *card) card_init_soft_queues(card); - func_exit(); } /* unifi_cancel_pending_signals() */ @@ -1938,7 +1920,6 @@ void unifi_free_card(card_t *card) kfree(card); - func_exit(); } /* unifi_free_card() */ @@ -2051,7 +2032,6 @@ static CsrResult card_init_slots(card_t *card) card->dynamic_slot_data.packets_interval = UNIFI_PACKETS_INTERVAL; - func_exit(); return CSR_RESULT_SUCCESS; } /* card_init_slots() */ @@ -2143,7 +2123,6 @@ static void CardReassignDynamicReservation(card_t *card) } card->dynamic_slot_data.total_packets_txed = 0; - func_exit(); } @@ -2180,7 +2159,6 @@ static void CardCheckDynamicReservation(card_t *card, unifi_TrafficQueue queue) if (q_len <= card->dynamic_slot_data.from_host_reserved_slots[queue]) { unifi_trace(card->ospriv, UDBG5, "queue %d q_len %d already has that many reserved slots, exiting\n", queue, q_len); - func_exit(); return; } @@ -2278,7 +2256,6 @@ static void CardCheckDynamicReservation(card_t *card, unifi_TrafficQueue queue) card->dynamic_slot_data.from_host_max_slots[i]); } - func_exit(); } @@ -2306,7 +2283,6 @@ void CardClearFromHostDataSlot(card_t *card, const s16 slot) unifi_warning(card->ospriv, "Surprise: request to clear an already free FH data slot: %d\n", slot); - func_exit(); return; } @@ -2342,7 +2318,6 @@ void CardClearFromHostDataSlot(card_t *card, const s16 slot) unifi_trace(card->ospriv, UDBG4, "CardClearFromHostDataSlot: slot %d recycled %p\n", slot, os_data_ptr); - func_exit(); } /* CardClearFromHostDataSlot() */ @@ -2430,7 +2405,6 @@ u16 CardGetFreeFromHostDataSlots(card_t *card) } } - func_exit(); return n; } /* CardGetFreeFromHostDataSlots() */ @@ -2490,7 +2464,6 @@ static CsrResult unifi_identify_hw(card_t *card) ChipHelper_MarketingName(card->helper), ChipHelper_FriendlyName(card->helper)); - func_exit(); return CSR_RESULT_SUCCESS; } /* unifi_identify_hw() */ @@ -2572,7 +2545,6 @@ static CsrResult unifi_prepare_hw(card_t *card) return r; } - func_exit(); return CSR_RESULT_SUCCESS; } /* unifi_prepare_hw() */ @@ -2842,7 +2814,6 @@ static CsrResult card_reset_method_io_enable(card_t *card) unifi_warning(card->ospriv, "card_reset_method_io_enable failed to reset UniFi\n"); } - func_exit(); return r; } /* card_reset_method_io_enable() */ @@ -2894,7 +2865,6 @@ static CsrResult card_reset_method_dbg_reset(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Can't stop processors\n"); - func_exit(); return r; } @@ -2930,7 +2900,6 @@ static CsrResult card_reset_method_dbg_reset(card_t *card) unifi_warning(card->ospriv, "card_reset_method_dbg_reset failed to reset UniFi\n"); } - func_exit(); return r; } /* card_reset_method_dbg_reset() */ @@ -2976,7 +2945,6 @@ CsrResult unifi_card_hard_reset(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "unifi_card_hard_reset failed to identify h/w\n"); - func_exit(); return r; } @@ -3006,7 +2974,6 @@ CsrResult unifi_card_hard_reset(card_t *card) } if (r == CSR_RESULT_SUCCESS) { - func_exit(); return r; } } @@ -3069,7 +3036,6 @@ CsrResult CardGenInt(card_t *card) card->unifi_interrupt_seq++; - func_exit(); return CSR_RESULT_SUCCESS; } /* CardGenInt() */ @@ -3414,7 +3380,6 @@ CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQue { unifi_trace(card->ospriv, UDBG5, "fh data slot %d: %d\n", i, card->from_host_data[i].bd.data_length); } - func_exit(); return CSR_RESULT_FAILURE; } } @@ -3467,8 +3432,6 @@ CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQue } } - func_exit(); - return CSR_RESULT_SUCCESS; } /* CardWriteBulkData() */ diff --git a/drivers/staging/csr/csr_wifi_hip_download.c b/drivers/staging/csr/csr_wifi_hip_download.c index b97af470f25..4dcb151b897 100644 --- a/drivers/staging/csr/csr_wifi_hip_download.c +++ b/drivers/staging/csr/csr_wifi_hip_download.c @@ -411,7 +411,6 @@ CsrResult unifi_dl_patch(card_t *card, void *dlpriv, u32 boot_ctrl) if (fwinfo == NULL) { unifi_error(card->ospriv, "Failed to allocate memory for patches\n"); - func_exit(); return CSR_WIFI_HIP_RESULT_NO_MEMORY; } @@ -427,7 +426,6 @@ CsrResult unifi_dl_patch(card_t *card, void *dlpriv, u32 boot_ctrl) { kfree(fwinfo); unifi_error(card->ospriv, "Failed to read in patch file\n"); - func_exit(); return CSR_WIFI_HIP_RESULT_INVALID_VALUE; } @@ -442,7 +440,6 @@ CsrResult unifi_dl_patch(card_t *card, void *dlpriv, u32 boot_ctrl) card->build_id, fwinfo->build_id); kfree(fwinfo); #ifndef CSR_WIFI_IGNORE_PATCH_VERSION_MISMATCH - func_exit(); return CSR_WIFI_HIP_RESULT_INVALID_VALUE; #else fwinfo = NULL; diff --git a/drivers/staging/csr/csr_wifi_hip_dump.c b/drivers/staging/csr/csr_wifi_hip_dump.c index cf33b63b20e..c16715165b7 100644 --- a/drivers/staging/csr/csr_wifi_hip_dump.c +++ b/drivers/staging/csr/csr_wifi_hip_dump.c @@ -774,7 +774,6 @@ CsrResult unifi_coredump_init(card_t *card, u16 num_dump_buffers) done: #endif - func_exit(); return CSR_RESULT_SUCCESS; #ifndef UNIFI_DISABLE_COREDUMP @@ -782,7 +781,6 @@ fail: /* Unwind what we allocated so far */ unifi_error(ospriv, "Out of memory allocating core dump node %d\n", i); unifi_coredump_free(card); - func_exit(); return CSR_WIFI_HIP_RESULT_NO_MEMORY; #endif } /* unifi_coreump_init() */ @@ -841,8 +839,6 @@ void unifi_coredump_free(card_t *card) card->dump_buf = NULL; card->dump_next_write = NULL; card->dump_cur_read = NULL; - - func_exit(); } /* unifi_coredump_free() */ diff --git a/drivers/staging/csr/csr_wifi_hip_send.c b/drivers/staging/csr/csr_wifi_hip_send.c index 86aa23cefe3..76429e5e77c 100644 --- a/drivers/staging/csr/csr_wifi_hip_send.c +++ b/drivers/staging/csr/csr_wifi_hip_send.c @@ -270,8 +270,6 @@ static CsrResult send_signal(card_t *card, const u8 *sigptr, u32 siglen, } } - func_exit(); - return CSR_RESULT_SUCCESS; } /* send_signal() */ diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c index b301458142e..a5e5d776747 100644 --- a/drivers/staging/csr/drv.c +++ b/drivers/staging/csr/drv.c @@ -276,7 +276,6 @@ unifi_open(struct inode *inode, struct file *file) priv = uf_get_instance(devno); if (priv == NULL) { unifi_error(NULL, "unifi_open: No device present\n"); - func_exit(); return -ENODEV; } @@ -288,7 +287,6 @@ unifi_open(struct inode *inode, struct file *file) /* Too many clients already using this device */ unifi_error(priv, "Too many clients already open\n"); uf_put_instance(devno); - func_exit(); return -ENOSPC; } unifi_trace(priv, UDBG1, "Client is registered to /dev/unifiudi%d\n", devno); @@ -308,7 +306,6 @@ unifi_open(struct inode *inode, struct file *file) uf_put_instance(devno); unifi_info(priv, "There is already a configuration client using the character device\n"); - func_exit(); return -EBUSY; } #endif /* CSR_SME_USERSPACE */ @@ -329,7 +326,6 @@ unifi_open(struct inode *inode, struct file *file) uf_put_instance(devno); unifi_error(priv, "Too many clients already open\n"); - func_exit(); return -ENOSPC; } @@ -355,7 +351,6 @@ unifi_open(struct inode *inode, struct file *file) */ file->private_data = udi_cli; - func_exit(); return 0; } /* unifi_open() */ @@ -609,7 +604,6 @@ udi_send_signal_unpacked(unifi_priv_t *priv, unsigned char* data, uint data_len) unifi_net_data_free(priv, &bulk_data.d[i]); } } - func_exit(); return -EIO; } @@ -660,7 +654,6 @@ udi_send_signal_raw(unifi_priv_t *priv, unsigned char *buf, int buflen) if ((signal_size <= 0) || (signal_size > buflen)) { unifi_error(priv, "udi_send_signal_raw - Couldn't find length of signal 0x%x\n", sig_id); - func_exit(); return -EINVAL; } unifi_trace(priv, UDBG2, "udi_send_signal_raw: signal 0x%.4X len:%d\n", @@ -705,7 +698,6 @@ udi_send_signal_raw(unifi_priv_t *priv, unsigned char *buf, int buflen) if (bytecount > buflen) { unifi_error(priv, "udi_send_signal_raw: Not enough data (%d instead of %d)\n", buflen, bytecount); - func_exit(); return -EINVAL; } @@ -713,7 +705,6 @@ udi_send_signal_raw(unifi_priv_t *priv, unsigned char *buf, int buflen) r = ul_send_signal_raw(priv, buf, signal_size, &data_ptrs); if (r < 0) { unifi_error(priv, "udi_send_signal_raw: send failed (%d)\n", r); - func_exit(); return -EIO; } @@ -802,7 +793,6 @@ unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff) csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], len); if (csrResult != CSR_RESULT_SUCCESS) { unifi_error(priv, "unifi_write: failed to allocate request_data.\n"); - func_exit(); return -ENOMEM; } @@ -812,7 +802,6 @@ unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff) if (copy_from_user((void*)user_data_buf, p, len)) { unifi_error(priv, "unifi_write: copy from user failed\n"); unifi_net_data_free(priv, &bulkdata.d[0]); - func_exit(); return -EFAULT; } @@ -828,7 +817,6 @@ unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff) unifi_error(priv, "unifi_write - Couldn't find length of signal 0x%x\n", sig_id); unifi_net_data_free(priv, &bulkdata.d[0]); - func_exit(); return -EINVAL; } @@ -839,7 +827,6 @@ unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff) signal_buf = kmalloc(signal_size, GFP_KERNEL); if (!signal_buf) { unifi_net_data_free(priv, &bulkdata.d[0]); - func_exit(); return -ENOMEM; } @@ -1655,8 +1642,6 @@ unifi_poll(struct file *filp, poll_table *wait) mask |= POLLIN | POLLRDNORM; /* readable */ } - func_exit(); - return mask; } /* unifi_poll() */ @@ -1887,7 +1872,6 @@ udi_log_event(ul_client_t *pcli, if (down_interruptible(&pcli->udi_sem)) { printk(KERN_WARNING "udi_log_event_q: Failed to get udi sem\n"); kfree(logptr); - func_exit(); return; } list_add_tail(&logptr->q, &pcli->udi_log); @@ -1896,7 +1880,6 @@ udi_log_event(ul_client_t *pcli, /* Wake any waiting user process */ wake_up_interruptible(&pcli->udi_wq); - func_exit(); } /* udi_log_event() */ #ifdef CSR_SME_USERSPACE @@ -1952,8 +1935,6 @@ uf_sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length) /* It is our responsibility to free the buffer allocated in build_packed_*() */ kfree(buffer); - func_exit(); - return 0; } /* uf_sme_queue_message() */ diff --git a/drivers/staging/csr/firmware.c b/drivers/staging/csr/firmware.c index 881acc90e53..1d1c10392ad 100644 --- a/drivers/staging/csr/firmware.c +++ b/drivers/staging/csr/firmware.c @@ -70,7 +70,6 @@ unifi_fw_read_start(void *ospriv, s8 is_fw, const card_info_t *info) } /* Set up callback struct for readfunc() */ if (priv->fw_sta.dl_data != NULL) { - func_exit(); return &priv->fw_sta; } @@ -78,7 +77,6 @@ unifi_fw_read_start(void *ospriv, s8 is_fw, const card_info_t *info) unifi_error(priv, "downloading firmware... unknown request: %d\n", is_fw); } - func_exit(); return NULL; } /* unifi_fw_read_start() */ @@ -112,7 +110,6 @@ unifi_fw_read_stop(void *ospriv, void *dlpriv) uf_release_firmware(priv, dl_struct); } - func_exit(); } /* unifi_fw_read_stop() */ @@ -142,14 +139,12 @@ unifi_fw_open_buffer(void *ospriv, void *fwbuf, u32 len) unifi_priv_t *priv = (unifi_priv_t*)ospriv; if (fwbuf == NULL) { - func_exit(); return NULL; } priv->fw_conv.dl_data = fwbuf; priv->fw_conv.dl_len = len; priv->fw_conv.fw_desc = NULL; /* No OS f/w resource is associated */ - func_exit(); return &priv->fw_conv; } diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c index 95d05264874..0f40b00ad4d 100644 --- a/drivers/staging/csr/io.c +++ b/drivers/staging/csr/io.c @@ -104,11 +104,9 @@ static CsrResult signal_buffer_init(unifi_priv_t * priv, int size) kfree(priv->rxSignalBuffer.rx_buff[j].bufptr); priv->rxSignalBuffer.rx_buff[j].bufptr = NULL; } - func_exit(); return -1; } } - func_exit(); return 0; } @@ -411,7 +409,6 @@ register_unifi_sdio(CsrSdioFunction *sdio_dev, int bus_id, struct device *dev) up(&Unifi_instance_mutex); - func_exit(); return priv; failed4: @@ -445,7 +442,6 @@ failed0: up(&Unifi_instance_mutex); - func_exit(); return NULL; } /* register_unifi_sdio() */ @@ -481,8 +477,6 @@ ask_unifi_sdio_cleanup(unifi_priv_t *priv) unifi_trace(NULL, UDBG5, "ask_unifi_sdio_cleanup: wake up cleanup workqueue.\n"); wake_up(&Unifi_cleanup_wq); - func_exit(); - } /* ask_unifi_sdio_cleanup() */ @@ -597,8 +591,6 @@ cleanup_unifi_sdio(unifi_priv_t *priv) unifi_trace(NULL, UDBG5, "cleanup_unifi_sdio: DONE.\n"); - func_exit(); - } /* cleanup_unifi_sdio() */ @@ -632,7 +624,6 @@ unregister_unifi_sdio(int bus_id) if (priv == NULL) { unifi_error(priv, "unregister_unifi_sdio: device %d is not registered\n", bus_id); - func_exit(); return; } diff --git a/drivers/staging/csr/mlme.c b/drivers/staging/csr/mlme.c index 723ecb37859..861d6b7687c 100644 --- a/drivers/staging/csr/mlme.c +++ b/drivers/staging/csr/mlme.c @@ -197,7 +197,6 @@ unifi_mlme_blocking_request(unifi_priv_t *priv, ul_client_t *pcli, return r; } - func_exit(); return 0; } /* unifi_mlme_blocking_request() */ diff --git a/drivers/staging/csr/monitor.c b/drivers/staging/csr/monitor.c index 60d52f9e8c3..c8e20e4c611 100644 --- a/drivers/staging/csr/monitor.c +++ b/drivers/staging/csr/monitor.c @@ -202,7 +202,6 @@ netrx_radiotap(unifi_priv_t *priv, priv->stats.rx_packets++; priv->stats.rx_bytes += ind_data_len; - func_exit(); } /* netrx_radiotap() */ #endif /* RADIOTAP */ @@ -314,7 +313,6 @@ netrx_prism(unifi_priv_t *priv, priv->stats.rx_packets++; priv->stats.rx_bytes += ind_data_len; - func_exit(); } /* netrx_prism() */ #endif /* PRISM */ @@ -348,7 +346,6 @@ ma_sniffdata_ind(void *ospriv, if (bulkdata->d[0].data_length == 0) { unifi_warning(priv, "rx: MA-SNIFFDATA indication with zero bulk data\n"); - func_exit(); return; } diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index ca9cc31f116..2d4a4e62221 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -551,7 +551,6 @@ uf_free_netdevice(unifi_priv_t *priv) } } - func_exit(); return 0; } /* uf_free_netdevice() */ @@ -610,7 +609,6 @@ uf_net_open(struct net_device *dev) netif_tx_start_all_queues(dev); - func_exit(); return 0; } /* uf_net_open() */ @@ -636,7 +634,6 @@ uf_net_stop(struct net_device *dev) netif_tx_stop_all_queues(dev); - func_exit(); return 0; } /* uf_net_stop() */ @@ -711,7 +708,6 @@ static CSR_PRIORITY uf_get_packet_priority(unifi_priv_t *priv, netInterface_priv unifi_trace(priv, UDBG5, "Packet priority = %d\n", priority); - func_exit(); return priority; } @@ -776,7 +772,6 @@ get_packet_priority(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr } unifi_trace(priv, UDBG5, "priority = %x\n", priority); - func_exit(); return priority; } @@ -822,7 +817,6 @@ uf_net_select_queue(struct net_device *dev, struct sk_buff *skb) } - func_exit(); return (u16)queue; } /* uf_net_select_queue() */ @@ -1789,7 +1783,6 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev) interfacePriv->stats.tx_dropped++; kfree_skb(skb); - func_exit(); return NETDEV_TX_OK; } @@ -1832,7 +1825,6 @@ uf_net_xmit(struct sk_buff *skb, struct net_device *dev) /* The skb will have been freed by send_XXX_request() */ - func_exit(); return result; } /* uf_net_xmit() */ @@ -1880,7 +1872,6 @@ unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue) unifi_error(priv, "Start buffering %d defaulting to 0\n", queue); } #endif - func_exit(); } /* unifi_pause_xmit() */ @@ -1909,7 +1900,6 @@ unifi_restart_xmit(void *ospriv, unifi_TrafficQueue queue) uf_send_buffered_frames(priv,0); } #endif - func_exit(); } /* unifi_restart_xmit() */ @@ -1945,7 +1935,6 @@ indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_b priv->interfacePriv[ifTag]->stats.rx_frame_errors++; unifi_net_data_free(priv, &bulkdata->d[0]); unifi_notice(priv, "indicate_rx_skb: Discard unknown frame.\n"); - func_exit(); return; } @@ -1957,7 +1946,6 @@ indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_b unifi_net_data_free(priv, &bulkdata->d[0]); unifi_trace(priv, UDBG5, "indicate_rx_skb: Data given to subscription" "API, not being given to kernel\n"); - func_exit(); return; } @@ -1980,7 +1968,6 @@ indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_b priv->interfacePriv[ifTag]->stats.rx_errors++; priv->interfacePriv[ifTag]->stats.rx_length_errors++; unifi_net_data_free(priv, &bulkdata->d[0]); - func_exit(); return; } @@ -2007,7 +1994,6 @@ indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_b priv->interfacePriv[ifTag]->stats.rx_packets++; priv->interfacePriv[ifTag]->stats.rx_bytes += bulkdata->d[0].data_length; - func_exit(); return; } @@ -2168,7 +2154,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) { unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag); unifi_net_data_free(priv,&bulkdata->d[0]); - func_exit(); return; } @@ -2177,14 +2162,12 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) { unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag); unifi_net_data_free(priv, &bulkdata->d[0]); - func_exit(); return; } if (bulkdata->d[0].data_length == 0) { unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__); unifi_net_data_free(priv,&bulkdata->d[0]); - func_exit(); return; } @@ -2306,7 +2289,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]); CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress); unifi_net_data_free(priv, &bulkdata->d[0]); - func_exit(); return; } @@ -2323,7 +2305,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) unifi_net_data_free(priv, &bulkdata->d[0]); unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n", __FUNCTION__, proto, queue ? "Controlled" : "Un-controlled"); - func_exit(); return; } @@ -2331,7 +2312,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) if((dataFrameType == QOS_DATA_NULL) || (dataFrameType == DATA_NULL)){ unifi_trace(priv, UDBG5, "%s: Null Frame Received and Freed\n", __FUNCTION__); unifi_net_data_free(priv, &bulkdata->d[0]); - func_exit(); return; } @@ -2346,7 +2326,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) bulkdata, macHeaderLengthInBytes))) { - func_exit(); return; } unifi_trace(priv, UDBG5, "unifi_rx: no specific AP handling process as normal frame, MAC Header len %d\n",macHeaderLengthInBytes); @@ -2369,7 +2348,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) unifi_trace(priv, UDBG1, "Zero length frame, but not null-data %04x\n", frameControl); } unifi_net_data_free(priv, &bulkdata->d[0]); - func_exit(); return; } @@ -2379,7 +2357,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) unifi_net_data_free(priv, &bulkdata->d[0]); unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n", __FUNCTION__, proto, queue ? "controlled" : "uncontrolled"); - func_exit(); return; } else if ( (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK) || (interfacePriv->connected != UnifiConnected) ) { @@ -2395,7 +2372,6 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) __FUNCTION__, sizeof(rx_buffered_packets_t)); interfacePriv->stats.rx_dropped++; unifi_net_data_free(priv, &bulkdata->d[0]); - func_exit(); return; } @@ -2419,15 +2395,12 @@ unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) list_add_tail(&rx_q_item->q, rx_list); up(&priv->rx_q_sem); - func_exit(); return; } indicate_rx_skb(priv, interfaceTag, da, sa, skb, signal, bulkdata); - func_exit(); - } /* unifi_rx() */ static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata) @@ -2443,7 +2416,6 @@ static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { unifi_error(priv, "%s: MA-PACKET confirm with bad interfaceTag %d\n", __FUNCTION__, interfaceTag); - func_exit(); return; } #ifdef CSR_SUPPORT_SME @@ -2466,7 +2438,6 @@ static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d interfacePriv->m4_hostTag = 0xffffffff; } #endif - func_exit(); return; } @@ -2516,7 +2487,6 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d { unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag); unifi_net_data_free(priv,&bulkdata->d[0]); - func_exit(); return; } @@ -2525,14 +2495,12 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d { unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag); unifi_net_data_free(priv, &bulkdata->d[0]); - func_exit(); return; } if (bulkdata->d[0].data_length == 0) { unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__); unifi_net_data_free(priv,&bulkdata->d[0]); - func_exit(); return; } /* For monitor mode we need to pass this indication to the registered application @@ -2542,7 +2510,6 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d { unifi_warning(priv, "%s: MA-PACKET indication with status = %d\n",__FUNCTION__, pkt_ind->ReceptionStatus); unifi_net_data_free(priv,&bulkdata->d[0]); - func_exit(); return; } @@ -2590,13 +2557,11 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d } #endif unifi_net_data_free(priv,&bulkdata->d[0]); - func_exit(); return; } if(frameType != IEEE802_11_FRAMETYPE_DATA) { unifi_warning(priv, "%s: Non control Non Data frame is received\n",__FUNCTION__); unifi_net_data_free(priv,&bulkdata->d[0]); - func_exit(); return; } @@ -2614,7 +2579,6 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]); CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress); unifi_net_data_free(priv, &bulkdata->d[0]); - func_exit(); return; } @@ -2720,7 +2684,6 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d up(&priv->ba_mutex); process_ba_complete(priv, interfacePriv); - func_exit(); } /* * --------------------------------------------------------------------------- @@ -2877,7 +2840,6 @@ netdev_mlme_event_handler(ul_client_t *pcli, const u8 *sig_packed, int sig_len, break; } - func_exit(); } /* netdev_mlme_event_handler() */ @@ -3313,7 +3275,6 @@ static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { unifi_error(priv, "%s: MaPacketErrorIndication indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag); - func_exit(); return; } @@ -3321,7 +3282,6 @@ static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, UserPriority = pkt_err_ind->UserPriority; if(UserPriority > 15) { unifi_error(priv, "%s: MaPacketErrorIndication indication with bad UserPriority=%d\n", __FUNCTION__, UserPriority); - func_exit(); } sn = pkt_err_ind->SequenceNumber; @@ -3342,7 +3302,6 @@ static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, up(&priv->ba_mutex); process_ba_complete(priv, interfacePriv); - func_exit(); } diff --git a/drivers/staging/csr/sdio_mmc.c b/drivers/staging/csr/sdio_mmc.c index 0b90630d332..862edb8934d 100644 --- a/drivers/staging/csr/sdio_mmc.c +++ b/drivers/staging/csr/sdio_mmc.c @@ -479,7 +479,6 @@ CsrSdioInterruptEnable(CsrSdioFunction *function) #endif _sdio_release_host(func); - func_exit(); if (err) { printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err); return ConvertSdioToCsrSdioResult(err); @@ -506,7 +505,6 @@ CsrSdioInterruptDisable(CsrSdioFunction *function) #endif _sdio_release_host(func); - func_exit(); if (err) { printk(KERN_ERR "unifi: %s: error %d writing IENx\n", __FUNCTION__, err); return ConvertSdioToCsrSdioResult(err); @@ -548,7 +546,6 @@ CsrSdioFunctionEnable(CsrSdioFunction *function) unifi_error(NULL, "Failed to enable SDIO function %d\n", func->num); } - func_exit(); return ConvertSdioToCsrSdioResult(err); } /* CsrSdioFunctionEnable() */ @@ -580,7 +577,6 @@ CsrSdioFunctionDisable(CsrSdioFunction *function) unifi_error(NULL, "Failed to disable SDIO function %d\n", func->num); } - func_exit(); return ConvertSdioToCsrSdioResult(err); } /* CsrSdioFunctionDisable() */ @@ -1096,7 +1092,6 @@ uf_glue_sdio_probe(struct sdio_func *func, wake_lock(&unifi_sdio_wake_lock); #endif - func_exit(); return 0; } /* uf_glue_sdio_probe() */ @@ -1139,8 +1134,6 @@ uf_glue_sdio_remove(struct sdio_func *func) kfree(sdio_ctx); - func_exit(); - } /* uf_glue_sdio_remove */ @@ -1176,7 +1169,6 @@ uf_glue_sdio_suspend(struct device *dev) { unifi_trace(NULL, UDBG1, "uf_glue_sdio_suspend"); - func_exit(); return 0; } /* uf_glue_sdio_suspend */ @@ -1204,7 +1196,6 @@ uf_glue_sdio_resume(struct device *dev) wake_lock(&unifi_sdio_wake_lock); #endif - func_exit(); return 0; } /* uf_glue_sdio_resume */ diff --git a/drivers/staging/csr/sme_native.c b/drivers/staging/csr/sme_native.c index dcecc86fb4a..525fe1bce0e 100644 --- a/drivers/staging/csr/sme_native.c +++ b/drivers/staging/csr/sme_native.c @@ -27,15 +27,11 @@ uf_sme_init(unifi_priv_t *priv) { int r = uf_init_wext_interface(priv); if (r != 0) { - func_exit(); return r; } } #endif - - - func_exit(); return 0; } /* uf_sme_init() */ @@ -54,8 +50,6 @@ uf_sme_deinit(unifi_priv_t *priv) uf_deinit_wext_interface(priv); #endif - - func_exit(); } /* uf_sme_deinit() */ @@ -327,8 +321,6 @@ sme_native_log_event(ul_client_t *pcli, /* Wake any waiting user process */ wake_up_interruptible(&client->udi_wq); - func_exit(); - } /* sme_native_log_event() */ @@ -533,7 +525,6 @@ sme_native_mlme_event_handler(ul_client_t *pcli, break; } - func_exit(); } /* sme_native_mlme_event_handler() */ @@ -570,7 +561,6 @@ unifi_reset_state(unifi_priv_t *priv, unsigned char *macaddr, priv->wext_conf.flag_associated = 0; #endif - func_exit(); return r; } /* unifi_reset_state() */ diff --git a/drivers/staging/csr/sme_sys.c b/drivers/staging/csr/sme_sys.c index c9a819a1686..2b068197ed4 100644 --- a/drivers/staging/csr/sme_sys.c +++ b/drivers/staging/csr/sme_sys.c @@ -477,8 +477,6 @@ uf_send_gratuitous_arp(unifi_priv_t *priv, u16 interfaceTag) return; } - func_exit(); - } #endif /* CSR_WIFI_SEND_GRATUITOUS_ARP */ diff --git a/drivers/staging/csr/sme_wext.c b/drivers/staging/csr/sme_wext.c index 461b8692a05..9b8385b5142 100644 --- a/drivers/staging/csr/sme_wext.c +++ b/drivers/staging/csr/sme_wext.c @@ -823,7 +823,6 @@ iwprivsconfwapi(struct net_device *dev, struct iw_request_info *info, ~(CSR_WIFI_SME_ENCRYPTION_CIPHER_PAIRWISE_SMS4 | CSR_WIFI_SME_ENCRYPTION_CIPHER_GROUP_SMS4); } - func_exit(); return 0; } @@ -880,7 +879,6 @@ iwprivswpikey(struct net_device *dev, struct iw_request_info *info, return convert_sme_error(r); } - func_exit(); return r; } #endif @@ -932,7 +930,6 @@ unifi_siwfreq(struct net_device *dev, struct iw_request_info *info, priv->connection_config.adhocChannel = wext_freq_to_channel(freq->m, freq->e); } - func_exit(); return 0; } /* unifi_siwfreq() */ @@ -966,7 +963,6 @@ unifi_giwfreq(struct net_device *dev, struct iw_request_info *info, (connectionInfo.networkType80211 == CSR_WIFI_SME_RADIO_IF_GHZ_5_0)); freq->e = 6; - func_exit(); return convert_sme_error(err); } /* unifi_giwfreq() */ @@ -1006,7 +1002,6 @@ unifi_siwmode(struct net_device *dev, struct iw_request_info *info, priv->connection_config.ssid.length = 0; memset(priv->connection_config.bssid.a, 0xFF, ETH_ALEN); - func_exit(); return 0; } /* unifi_siwmode() */ @@ -1063,7 +1058,6 @@ unifi_giwmode(struct net_device *dev, struct iw_request_info *info, } unifi_trace(priv, UDBG4, "unifi_giwmode: mode = 0x%x\n", wrqu->mode); - func_exit(); return r; } /* unifi_giwmode() */ @@ -1227,11 +1221,9 @@ unifi_siwap(struct net_device *dev, struct iw_request_info *info, err = sme_mgt_connect(priv); if (err) { unifi_error(priv, "unifi_siwap: Join failed, status %d\n", err); - func_exit(); return convert_sme_error(err); } } - func_exit(); return 0; } /* unifi_siwap() */ @@ -1271,7 +1263,6 @@ unifi_giwap(struct net_device *dev, struct iw_request_info *info, memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); } - func_exit(); return 0; } /* unifi_giwap() */ @@ -1354,7 +1345,6 @@ unifi_siwscan(struct net_device *dev, struct iw_request_info *info, kfree(channel_list); } - func_exit(); return r; } /* unifi_siwscan() */ @@ -1747,11 +1737,9 @@ unifi_siwessid(struct net_device *dev, struct iw_request_info *info, UF_RTNL_LOCK(); if (err) { unifi_error(priv, "unifi_siwessid: Join failed, status %d\n", err); - func_exit(); return convert_sme_error(err); } - func_exit(); return 0; } /* unifi_siwessid() */ @@ -1791,7 +1779,6 @@ unifi_giwessid(struct net_device *dev, struct iw_request_info *info, data->length, essid); } - func_exit(); return 0; } /* unifi_giwessid() */ @@ -1847,7 +1834,6 @@ unifi_siwrate(struct net_device *dev, struct iw_request_info *info, return r; } - func_exit(); return 0; } /* unifi_siwrate() */ @@ -1896,8 +1882,6 @@ unifi_giwrate(struct net_device *dev, struct iw_request_info *info, args->value = bitrate * 500000; args->fixed = !flag; - func_exit(); - return 0; } /* unifi_giwrate() */ @@ -2473,7 +2457,6 @@ unifi_siwmlme(struct net_device *dev, struct iw_request_info *info, return -EOPNOTSUPP; } - func_exit(); return 0; } /* unifi_siwmlme() */ @@ -2528,20 +2511,17 @@ unifi_siwgenie(struct net_device *dev, struct iw_request_info *info, len = wrqu->data.length; if (len == 0) { - func_exit(); return 0; } priv->connection_config.mlmeAssociateReqInformationElements = kmalloc(len, GFP_KERNEL); if (priv->connection_config.mlmeAssociateReqInformationElements == NULL) { - func_exit(); return -ENOMEM; } priv->connection_config.mlmeAssociateReqInformationElementsLength = len; memcpy( priv->connection_config.mlmeAssociateReqInformationElements, extra, len); - func_exit(); return 0; } /* unifi_siwgenie() */ @@ -2578,7 +2558,6 @@ unifi_giwgenie(struct net_device *dev, struct iw_request_info *info, wrqu->data.length = len; memcpy(extra, priv->connection_config.mlmeAssociateReqInformationElements, len); - func_exit(); return 0; } /* unifi_giwgenie() */ @@ -2826,7 +2805,6 @@ _unifi_siwauth(struct net_device *dev, struct iw_request_info *info, } unifi_trace(priv, UDBG2, "authModeMask = %d", priv->connection_config.authModeMask); - func_exit(); return 0; } /* _unifi_siwauth() */ @@ -3037,7 +3015,6 @@ _unifi_siwencodeext(struct net_device *dev, struct iw_request_info *info, return convert_sme_error(r); } - func_exit(); return r; } /* _unifi_siwencodeext() */ diff --git a/drivers/staging/csr/unifi_event.c b/drivers/staging/csr/unifi_event.c index f684b93e627..e81a9987827 100644 --- a/drivers/staging/csr/unifi_event.c +++ b/drivers/staging/csr/unifi_event.c @@ -521,7 +521,6 @@ unifi_process_receive_event(void *ospriv, unifi_net_data_free(priv, (void *)&bulkdata->d[i]); } } - func_exit(); return; } } /* CSR_MA_PACKET_INDICATION_ID */ @@ -571,7 +570,6 @@ unifi_process_receive_event(void *ospriv, } } - func_exit(); } /* unifi_process_receive_event() */ @@ -602,7 +600,6 @@ void unifi_rx_queue_flush(void *ospriv) } priv->rxSignalBuffer.readPointer = readPointer; } - func_exit(); } void rx_wq_handler(struct work_struct *work) @@ -691,6 +688,5 @@ unifi_receive_event(void *ospriv, #else unifi_process_receive_event(ospriv, sigdata, siglen, bulkdata); #endif - func_exit(); } /* unifi_receive_event() */ diff --git a/drivers/staging/csr/unifi_os.h b/drivers/staging/csr/unifi_os.h index 13c7d86d7ce..c72b3a6266a 100644 --- a/drivers/staging/csr/unifi_os.h +++ b/drivers/staging/csr/unifi_os.h @@ -61,12 +61,6 @@ extern int unifi_debug; * etc. */ -#define func_exit() \ - do { \ - if (unifi_debug >= 5) { \ - printk("unifi: <= %s\n", __FUNCTION__); \ - } \ - } while (0) #define func_exit_r(_rc) \ do { \ if (unifi_debug >= 5) { \ @@ -101,7 +95,6 @@ void unifi_trace(void* ospriv, int level, const char *fmt, ...); #else /* Stubs */ -#define func_exit() #define func_exit_r(_rc) #define ASSERT(cond) diff --git a/drivers/staging/csr/unifi_pdu_processing.c b/drivers/staging/csr/unifi_pdu_processing.c index 453a2afd9b8..95efc360cc2 100644 --- a/drivers/staging/csr/unifi_pdu_processing.c +++ b/drivers/staging/csr/unifi_pdu_processing.c @@ -408,7 +408,6 @@ CsrResult enque_tx_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata, unifi_error(priv, "Failed to allocate %d bytes for tx packet record\n", sizeof(tx_buffered_packets_t)); - func_exit(); return CSR_RESULT_FAILURE; } @@ -2131,7 +2130,6 @@ void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,u8 *sigdata, unifi_error(priv, "uf_process_ma_vif_availibility_ind: Received unknown signal 0x%.4X.\n", CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata)); - func_exit(); return; } ind = &signal.u.MaVifAvailabilityIndication; @@ -2394,8 +2392,6 @@ void uf_send_buffered_data_from_ac(unifi_priv_t *priv, } } - func_exit(); - } void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q) @@ -2445,7 +2441,6 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q) interfacePriv->dtimActive = FALSE; } } - func_exit(); return; } if(priv->pausedStaHandle[queue] > 7) { @@ -2536,7 +2531,6 @@ void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q) */ unifi_trace(priv, UDBG4, "csrWifiHipSendBufferedFrames: UAPSD Resume Q=%x\n", queue); resume_suspended_uapsd(priv, interfaceTag); - func_exit(); } @@ -2816,7 +2810,6 @@ void uf_send_qos_null(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRI unifi_net_data_free(priv, &bulkdata.d[0]); } - func_exit(); return; } @@ -2901,7 +2894,6 @@ void uf_send_nulldata(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRI srcStaInfo->nullDataHostTag = INVALID_HOST_TAG; } - func_exit(); return; } @@ -3347,7 +3339,6 @@ void uf_prepare_send_cfm_list_for_queued_pkts(unifi_priv_t * priv, spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); - func_exit(); } @@ -3661,7 +3652,6 @@ void resume_unicast_buffered_frames(unifi_priv_t *priv, u16 interfaceTag) } } } - func_exit(); } void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,u16 interfaceTag) { @@ -3688,7 +3678,6 @@ void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,u16 interface } spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags); } - func_exit(); } /* diff --git a/drivers/staging/csr/unifi_sme.c b/drivers/staging/csr/unifi_sme.c index 86fcec6c1b4..7c6c4138fc7 100644 --- a/drivers/staging/csr/unifi_sme.c +++ b/drivers/staging/csr/unifi_sme.c @@ -80,20 +80,17 @@ sme_log_event(ul_client_t *pcli, /* Just a sanity check */ if ((signal == NULL) || (signal_len <= 0)) { - func_exit(); return; } priv = uf_find_instance(pcli->instance); if (!priv) { unifi_error(priv, "sme_log_event: invalid priv\n"); - func_exit(); return; } if (priv->smepriv == NULL) { unifi_error(priv, "sme_log_event: invalid smepriv\n"); - func_exit(); return; } @@ -108,7 +105,6 @@ sme_log_event(ul_client_t *pcli, if ((unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_DEBUG_STRING_INDICATION_ID) || (unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_DEBUG_WORD16_INDICATION_ID)) { - func_exit(); return; } if (unpacked_signal.SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_INDICATION_ID) @@ -170,7 +166,6 @@ sme_log_event(ul_client_t *pcli, if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { unifi_error(priv, "Bad MA_PACKET_CONFIRM interfaceTag %d\n", interfaceTag); - func_exit(); return; } @@ -218,7 +213,6 @@ sme_log_event(ul_client_t *pcli, } else { unifi_trace(priv, UDBG1, "%s: M4 received from netdevice\n", __FUNCTION__); } - func_exit(); return; } } @@ -247,7 +241,6 @@ sme_log_event(ul_client_t *pcli, dataref1.length, dataref1.data, dataref2.length, dataref2.data); - func_exit(); } /* sme_log_event() */ @@ -1168,8 +1161,6 @@ uf_send_m4_ready_wq(struct work_struct *work) unifi_trace(priv, UDBG1, "M4ReadyToSendInd sent for peer %pMF\n", peer.a); - func_exit(); - } /* uf_send_m4_ready_wq() */ #if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) @@ -1226,7 +1217,6 @@ void uf_send_pkt_to_encrypt(struct work_struct *work) kfree(pktBulkData); /* Would have been copied over by the SME Handler */ - func_exit(); } else { unifi_warning(priv, "uf_send_pkt_to_encrypt() is NOT applicable for interface mode - %d\n",interfacePriv->interfaceMode); } -- cgit v1.2.3 From 1f5466b0a6c82a1489f5d1ff9ef20c919b56a2cc Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 27 Oct 2012 02:10:00 -0400 Subject: staging: csr: remove func_exit_r macro this macro is used for debugging purposes, it actually defined as if (unifi_debug >= 5) { printk("unifi: <= %s %d\n", __FUNCTION__, (int)rc); } which produces too many of those prints if the unifi_debug is >=5. remove these calls and the macro itself altogether Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_hip_card_sdio.c | 69 ---------------------------- drivers/staging/csr/csr_wifi_hip_download.c | 11 ----- drivers/staging/csr/csr_wifi_hip_dump.c | 7 --- drivers/staging/csr/drv.c | 5 -- drivers/staging/csr/sdio_mmc.c | 6 --- drivers/staging/csr/sme_wext.c | 2 - drivers/staging/csr/unifi_os.h | 9 ---- 7 files changed, 109 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio.c b/drivers/staging/csr/csr_wifi_hip_card_sdio.c index f025efd0679..25cabf3234c 100644 --- a/drivers/staging/csr/csr_wifi_hip_card_sdio.c +++ b/drivers/staging/csr/csr_wifi_hip_card_sdio.c @@ -171,27 +171,23 @@ CsrResult unifi_init_card(card_t *card, s32 led_mask) if (card == NULL) { - func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE); return CSR_WIFI_HIP_RESULT_INVALID_VALUE; } r = unifi_init(card); if (r != CSR_RESULT_SUCCESS) { - func_exit_r(r); return r; } r = unifi_hip_init(card); if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE) { - func_exit_r(r); return r; } if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to start host protocol.\n"); - func_exit_r(r); return r; } @@ -220,7 +216,6 @@ CsrResult unifi_init(card_t *card) if (card == NULL) { - func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE); return CSR_WIFI_HIP_RESULT_INVALID_VALUE; } @@ -243,7 +238,6 @@ CsrResult unifi_init(card_t *card) if (csrResult != CSR_RESULT_SUCCESS) { r = ConvertCsrSdioToCsrHipResult(card, csrResult); - func_exit_r(r); return r; } card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ; @@ -261,7 +255,6 @@ CsrResult unifi_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to reset UniFi\n"); - func_exit_r(r); return r; } @@ -271,7 +264,6 @@ CsrResult unifi_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to set power save mode\n"); - func_exit_r(r); return r; } @@ -291,7 +283,6 @@ CsrResult unifi_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to write SHARED_DMEM_PAGE\n"); - func_exit_r(r); return r; } r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW2_PAGE(card->helper) * 2, 0); @@ -302,7 +293,6 @@ CsrResult unifi_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to write PROG_MEM2_PAGE\n"); - func_exit_r(r); return r; } @@ -331,7 +321,6 @@ CsrResult unifi_init(card_t *card) unifi_error(card->ospriv, "Probe for Flash failed\n"); } - func_exit_r(r); return r; } /* unifi_init() */ @@ -358,7 +347,6 @@ CsrResult unifi_download(card_t *card, s32 led_mask) if (card == NULL) { - func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE); return CSR_WIFI_HIP_RESULT_INVALID_VALUE; } @@ -371,7 +359,6 @@ CsrResult unifi_download(card_t *card, s32 led_mask) dlpriv = unifi_dl_fw_read_start(card, UNIFI_FW_STA); if (dlpriv == NULL) { - func_exit_r(CSR_WIFI_HIP_RESULT_NOT_FOUND); return CSR_WIFI_HIP_RESULT_NOT_FOUND; } @@ -380,7 +367,6 @@ CsrResult unifi_download(card_t *card, s32 led_mask) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to download firmware\n"); - func_exit_r(r); return r; } @@ -422,7 +408,6 @@ static CsrResult unifi_hip_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to establish communication with UniFi\n"); - func_exit_r(r); return r; } #ifdef CSR_PRE_ALLOC_NET_DATA @@ -442,7 +427,6 @@ static CsrResult unifi_hip_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Init slots failed: %d\n", r); - func_exit_r(r); return r; } @@ -451,7 +435,6 @@ static CsrResult unifi_hip_init(card_t *card) r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE); if (r != CSR_RESULT_SUCCESS) { - func_exit_r(r); return r; } @@ -466,7 +449,6 @@ static CsrResult unifi_hip_init(card_t *card) r = CardGenInt(card); if (r != CSR_RESULT_SUCCESS) { - func_exit_r(r); return r; } @@ -618,7 +600,6 @@ static CsrResult card_hw_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Firmware hasn't started\n"); - func_exit_r(r); return r; } unifi_trace(card->ospriv, UDBG4, "SLUT addr 0x%lX\n", slut_address); @@ -635,7 +616,6 @@ static CsrResult card_hw_init(card_t *card) if (csrResult != CSR_RESULT_SUCCESS) { r = ConvertCsrSdioToCsrHipResult(card, csrResult); - func_exit_r(r); return r; } card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ; @@ -654,14 +634,12 @@ static CsrResult card_hw_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to read SLUT finger print\n"); - func_exit_r(r); return r; } if (finger_print != SLUT_FINGERPRINT) { unifi_error(card->ospriv, "Failed to find Symbol lookup table fingerprint\n"); - func_exit_r(CSR_RESULT_FAILURE); return CSR_RESULT_FAILURE; } @@ -679,7 +657,6 @@ static CsrResult card_hw_init(card_t *card) r = unifi_card_read16(card, slut_address, &s); if (r != CSR_RESULT_SUCCESS) { - func_exit_r(r); return r; } slut_address += 2; @@ -693,7 +670,6 @@ static CsrResult card_hw_init(card_t *card) r = unifi_read32(card, slut_address, &l); if (r != CSR_RESULT_SUCCESS) { - func_exit_r(r); return r; } slut_address += 4; @@ -722,7 +698,6 @@ static CsrResult card_hw_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to read config data\n"); - func_exit_r(r); return r; } /* .. and then we copy the data to the host structure */ @@ -736,7 +711,6 @@ static CsrResult card_hw_init(card_t *card) { unifi_error(card->ospriv, "From host data slots %d\n", cfg_data->num_fromhost_data_slots); unifi_error(card->ospriv, "need to be (queues * x + 2) (UNIFI_RESERVED_COMMAND_SLOTS for commands)\n"); - func_exit_r(CSR_RESULT_FAILURE); return CSR_RESULT_FAILURE; } @@ -764,7 +738,6 @@ static CsrResult card_hw_init(card_t *card) if ((card->sdio_io_block_size % cfg_data->sig_frag_size) != 0) { unifi_error(card->ospriv, "Configuration error: Can not pad to-host signals.\n"); - func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE); return CSR_WIFI_HIP_RESULT_INVALID_VALUE; } cfg_data->tohost_signal_padding = (u16) (card->sdio_io_block_size / cfg_data->sig_frag_size); @@ -778,7 +751,6 @@ static CsrResult card_hw_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to write To-Host Signal Padding Fragments\n"); - func_exit_r(r); return r; } } @@ -801,7 +773,6 @@ static CsrResult card_hw_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to read build id\n"); - func_exit_r(r); return r; } card->build_id = n; @@ -818,7 +789,6 @@ static CsrResult card_hw_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to read build string\n"); - func_exit_r(r); return r; } break; @@ -836,7 +806,6 @@ static CsrResult card_hw_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to write loader load image command\n"); - func_exit_r(r); return r; } @@ -854,7 +823,6 @@ static CsrResult card_hw_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to patch firmware\n"); - func_exit_r(r); return r; } } @@ -865,7 +833,6 @@ static CsrResult card_hw_init(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to write loader restart command\n"); - func_exit_r(r); return r; } @@ -896,7 +863,6 @@ static CsrResult card_hw_init(card_t *card) if (cfg_data == NULL) { unifi_error(card->ospriv, "Failed to find SDIO_SLOT_CONFIG Symbol\n"); - func_exit_r(CSR_RESULT_FAILURE); return CSR_RESULT_FAILURE; } @@ -913,12 +879,10 @@ static CsrResult card_hw_init(card_t *card) { unifi_error(card->ospriv, "Failed to read init flag at %08lx\n", card->init_flag_addr); - func_exit_r(r); return r; } if (initialised != 0) { - func_exit_r(CSR_RESULT_FAILURE); return CSR_RESULT_FAILURE; } @@ -940,7 +904,6 @@ static CsrResult card_hw_init(card_t *card) unifi_error(card->ospriv, "UniFi f/w protocol major version (%d) is different from driver (v%d.%d)\n", major, UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION); #ifndef CSR_WIFI_DISABLE_HIP_VERSION_CHECK - func_exit_r(CSR_RESULT_FAILURE); return CSR_RESULT_FAILURE; #endif } @@ -950,7 +913,6 @@ static CsrResult card_hw_init(card_t *card) major, minor, UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION); #ifndef CSR_WIFI_DISABLE_HIP_VERSION_CHECK - func_exit_r(CSR_RESULT_FAILURE); return CSR_RESULT_FAILURE; #endif } @@ -1250,7 +1212,6 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to read UniFi Mailbox1 register for second time\n"); - func_exit_r(r); return r; } unifi_trace(card->ospriv, UDBG1, "MAILBOX1 value=0x%04X\n", mbox1); @@ -1269,7 +1230,6 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr) { unifi_trace(card->ospriv, UDBG1, "Timeout waiting for firmware to start, Mailbox1 still 0 after %d ms\n", MAILBOX1_ATTEMPTS * MAILBOX1_TIMEOUT); - func_exit_r(CSR_RESULT_FAILURE); return CSR_RESULT_FAILURE; } @@ -1285,7 +1245,6 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to write f/w startup handshake to MAILBOX2\n"); - func_exit_r(r); return r; } @@ -1303,7 +1262,6 @@ CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to read UniFi Mailbox0 register\n"); - func_exit_r(r); return r; } @@ -1480,7 +1438,6 @@ static CsrResult card_access_panic(card_t *card) } r = ConvertCsrSdioToCsrHipResult(card, sr); - func_exit_r(r); return r; } @@ -1596,7 +1553,6 @@ static CsrResult card_allocate_memory_resources(card_t *card) if (card->fh_buffer.buf == NULL) { unifi_error(card->ospriv, "Failed to allocate memory for F-H signals\n"); - func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY); return CSR_WIFI_HIP_RESULT_NO_MEMORY; } card->fh_buffer.bufsize = UNIFI_FH_BUF_SIZE; @@ -1607,7 +1563,6 @@ static CsrResult card_allocate_memory_resources(card_t *card) if (card->th_buffer.buf == NULL) { unifi_error(card->ospriv, "Failed to allocate memory for T-H signals\n"); - func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY); return CSR_WIFI_HIP_RESULT_NO_MEMORY; } card->th_buffer.bufsize = UNIFI_FH_BUF_SIZE; @@ -1629,7 +1584,6 @@ static CsrResult card_allocate_memory_resources(card_t *card) if (card->from_host_data == NULL) { unifi_error(card->ospriv, "Failed to allocate memory for F-H bulk data array\n"); - func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY); return CSR_WIFI_HIP_RESULT_NO_MEMORY; } @@ -1645,7 +1599,6 @@ static CsrResult card_allocate_memory_resources(card_t *card) if (card->fh_slot_host_tag_record == NULL) { unifi_error(card->ospriv, "Failed to allocate memory for F-H slot host tag mapping array\n"); - func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY); return CSR_WIFI_HIP_RESULT_NO_MEMORY; } @@ -1664,7 +1617,6 @@ static CsrResult card_allocate_memory_resources(card_t *card) if (card->to_host_data == NULL) { unifi_error(card->ospriv, "Failed to allocate memory for T-H bulk data array\n"); - func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY); return CSR_WIFI_HIP_RESULT_NO_MEMORY; } @@ -1957,14 +1909,12 @@ static CsrResult card_init_slots(card_t *card) { unifi_error(card->ospriv, "Failed to allocate card memory resources.\n"); card_free_memory_resources(card); - func_exit_r(r); return r; } if (card->sdio_ctrl_addr == 0) { unifi_error(card->ospriv, "Failed to find config struct!\n"); - func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE); return CSR_WIFI_HIP_RESULT_INVALID_VALUE; } @@ -1987,7 +1937,6 @@ static CsrResult card_init_slots(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to read from-host sig written count\n"); - func_exit_r(r); return r; } card->from_host_signals_w = (s16)s; @@ -2001,7 +1950,6 @@ static CsrResult card_init_slots(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to read to-host sig read count\n"); - func_exit_r(r); return r; } card->to_host_signals_r = (s16)s; @@ -2016,7 +1964,6 @@ static CsrResult card_init_slots(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to write initialised flag\n"); - func_exit_r(r); return r; } @@ -2482,7 +2429,6 @@ static CsrResult unifi_prepare_hw(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to identify hw\n"); - func_exit_r(r); return r; } @@ -2507,7 +2453,6 @@ static CsrResult unifi_prepare_hw(card_t *card) if (csrResult != CSR_RESULT_SUCCESS) { r = ConvertCsrSdioToCsrHipResult(card, csrResult); - func_exit_r(r); return r; } card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ; @@ -2527,7 +2472,6 @@ static CsrResult unifi_prepare_hw(card_t *card) r = ConvertCsrSdioToCsrHipResult(card, csrResult); /* Can't enable WLAN function. Try resetting the SDIO block. */ unifi_error(card->ospriv, "Failed to re-enable function %d.\n", card->function); - func_exit_r(r); return r; } @@ -2541,7 +2485,6 @@ static CsrResult unifi_prepare_hw(card_t *card) r = unifi_read_chip_version(card); if (r != CSR_RESULT_SUCCESS) { - func_exit_r(r); return r; } @@ -2568,7 +2511,6 @@ static CsrResult unifi_read_chip_version(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to read GBL_CHIP_VERSION\n"); - func_exit_r(r); return r; } card->chip_version = ver; @@ -2581,7 +2523,6 @@ static CsrResult unifi_read_chip_version(card_t *card) unifi_info(card->ospriv, "Chip Version 0x%04X\n", card->chip_version); - func_exit_r(r); return r; } /* unifi_read_chip_version() */ @@ -2635,7 +2576,6 @@ static CsrResult unifi_reset_hardware(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "unifi_prepare_hw failed after hard reset\n"); - func_exit_r(r); return r; } } @@ -2655,7 +2595,6 @@ static CsrResult unifi_reset_hardware(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "software hard reset failed\n"); - func_exit_r(r); return r; } @@ -2668,7 +2607,6 @@ static CsrResult unifi_reset_hardware(card_t *card) r = unifi_read_chip_version(card); if (r != CSR_RESULT_SUCCESS) { - func_exit_r(r); return r; } } @@ -2718,7 +2656,6 @@ static CsrResult unifi_reset_hardware(card_t *card) } - func_exit_r(r); return r; } /* unifi_reset_hardware() */ @@ -2793,7 +2730,6 @@ static CsrResult card_reset_method_io_enable(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_warning(card->ospriv, "SDIO error writing SDIO_CSR_FUNC_EN: %d\n", r); - func_exit_r(r); return r; } else @@ -2851,7 +2787,6 @@ static CsrResult card_reset_method_dbg_reset(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to set UNIFI_HOST_STATE_DROWSY\n"); - func_exit_r(r); return r; } CsrThreadSleep(5); @@ -2883,7 +2818,6 @@ static CsrResult card_reset_method_dbg_reset(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_warning(card->ospriv, "SDIO error writing DBG_RESET: %d\n", r); - func_exit_r(r); return r; } @@ -2955,7 +2889,6 @@ CsrResult unifi_card_hard_reset(card_t *card) unifi_error(card->ospriv, "Hard reset (Code download) is unsupported\n"); - func_exit_r(CSR_RESULT_FAILURE); return CSR_RESULT_FAILURE; } @@ -2981,7 +2914,6 @@ CsrResult unifi_card_hard_reset(card_t *card) /* Software hard reset */ r = card_reset_method_dbg_reset(card); - func_exit_r(r); return r; } /* unifi_card_hard_reset() */ @@ -3030,7 +2962,6 @@ CsrResult CardGenInt(card_t *card) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "SDIO error writing UNIFI_SHARED_IO_INTERRUPT: %d\n", r); - func_exit_r(r); return r; } diff --git a/drivers/staging/csr/csr_wifi_hip_download.c b/drivers/staging/csr/csr_wifi_hip_download.c index 4dcb151b897..2f44a383d2c 100644 --- a/drivers/staging/csr/csr_wifi_hip_download.c +++ b/drivers/staging/csr/csr_wifi_hip_download.c @@ -68,7 +68,6 @@ static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Firmware hasn't started\n"); - func_exit_r(r); return r; } *pslut = slut_address; @@ -81,7 +80,6 @@ static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut) if (csrResult != CSR_RESULT_SUCCESS) { r = ConvertCsrSdioToCsrHipResult(card, csrResult); - func_exit_r(r); return r; } card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ; @@ -106,14 +104,12 @@ static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut) if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Failed to read SLUT finger print\n"); - func_exit_r(r); return r; } if (finger_print != SLUT_FINGERPRINT) { unifi_error(card->ospriv, "Failed to find SLUT fingerprint\n"); - func_exit_r(CSR_RESULT_FAILURE); return CSR_RESULT_FAILURE; } @@ -128,7 +124,6 @@ static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut) r = unifi_card_read16(card, slut_address, &id); if (r != CSR_RESULT_SUCCESS) { - func_exit_r(r); return r; } slut_address += 2; @@ -143,7 +138,6 @@ static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut) r = unifi_read32(card, slut_address, &obj); if (r != CSR_RESULT_SUCCESS) { - func_exit_r(r); return r; } slut_address += 4; @@ -161,7 +155,6 @@ static CsrResult _find_in_slut(card_t *card, symbol_t *psym, u32 *pslut) } } - func_exit_r(r); return r; } @@ -279,7 +272,6 @@ static CsrResult do_patch_convert_download(card_t *card, void *dlpriv, xbv1_t *p if (r != CSR_RESULT_SUCCESS) { unifi_error(card->ospriv, "Converted patch download failed\n"); - func_exit_r(r); return r; } else @@ -294,7 +286,6 @@ static CsrResult do_patch_convert_download(card_t *card, void *dlpriv, xbv1_t *p unifi_error(card->ospriv, "Failed to write loader restart cmd\n"); } - func_exit_r(r); return r; } } @@ -374,7 +365,6 @@ CsrResult unifi_dl_firmware(card_t *card, void *dlpriv) } kfree(fwinfo); - func_exit_r(r); return r; } /* unifi_dl_firmware() */ @@ -456,7 +446,6 @@ CsrResult unifi_dl_patch(card_t *card, void *dlpriv, u32 boot_ctrl) kfree(fwinfo); - func_exit_r(r); return r; } /* unifi_dl_patch() */ diff --git a/drivers/staging/csr/csr_wifi_hip_dump.c b/drivers/staging/csr/csr_wifi_hip_dump.c index c16715165b7..7b7eec49d02 100644 --- a/drivers/staging/csr/csr_wifi_hip_dump.c +++ b/drivers/staging/csr/csr_wifi_hip_dump.c @@ -119,7 +119,6 @@ CsrResult unifi_coredump_request_at_next_reset(card_t *card, s8 enable) r = CSR_RESULT_SUCCESS; } - func_exit_r(r); return r; } @@ -156,7 +155,6 @@ CsrResult unifi_coredump_handle_request(card_t *card) } } - func_exit_r(r); return r; } @@ -263,7 +261,6 @@ CsrResult unifi_coredump_capture(card_t *card, struct unifi_coredump_req *req) } done: - func_exit_r(r); return r; } /* unifi_coredump_capture() */ @@ -444,7 +441,6 @@ CsrResult unifi_coredump_get_value(card_t *card, struct unifi_coredump_req *req) req->serial = find_dump->count; done: - func_exit_r(r); return r; } /* unifi_coredump_get_value() */ @@ -511,7 +507,6 @@ static CsrResult unifi_coredump_read_zone(card_t *card, u16 *zonebuf, const stru } done: - func_exit_r(r); return r; } @@ -549,7 +544,6 @@ static CsrResult unifi_coredump_read_zones(card_t *card, coredump_buffer *dump_b r = unifi_coredump_read_zone(card, dump_buf->zone[i], &zonedef_table[i]); } - func_exit_r(r); return r; } @@ -620,7 +614,6 @@ static CsrResult unifi_coredump_from_sdio(card_t *card, coredump_buffer *dump_bu } done: - func_exit_r(r); return r; } /* unifi_coredump_from_sdio() */ diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c index a5e5d776747..e92c8d2f1e8 100644 --- a/drivers/staging/csr/drv.c +++ b/drivers/staging/csr/drv.c @@ -516,7 +516,6 @@ unifi_read(struct file *filp, char *p, size_t len, loff_t *poff) /* It is our resposibility to free the message buffer. */ kfree(logptr); - func_exit_r(msglen); return msglen; } /* unifi_read() */ @@ -729,8 +728,6 @@ udi_send_signal_raw(unifi_priv_t *priv, unsigned char *buf, int buflen) } #endif - func_exit_r(bytecount); - return bytecount; } /* udi_send_signal_raw */ @@ -925,8 +922,6 @@ unifi_write(struct file *filp, const char *p, size_t len, loff_t *poff) kfree(buf); - func_exit_r(bytes_written); - return bytes_written; } /* unifi_write() */ diff --git a/drivers/staging/csr/sdio_mmc.c b/drivers/staging/csr/sdio_mmc.c index 862edb8934d..b6a16de08f4 100644 --- a/drivers/staging/csr/sdio_mmc.c +++ b/drivers/staging/csr/sdio_mmc.c @@ -151,7 +151,6 @@ CsrSdioRead8(CsrSdioFunction *function, u32 address, u8 *data) _sdio_release_host(func); if (err) { - func_exit_r(err); return ConvertSdioToCsrSdioResult(err); } @@ -169,7 +168,6 @@ CsrSdioWrite8(CsrSdioFunction *function, u32 address, u8 data) _sdio_release_host(func); if (err) { - func_exit_r(err); return ConvertSdioToCsrSdioResult(err); } @@ -245,7 +243,6 @@ CsrSdioF0Read8(CsrSdioFunction *function, u32 address, u8 *data) _sdio_release_host(func); if (err) { - func_exit_r(err); return ConvertSdioToCsrSdioResult(err); } @@ -267,7 +264,6 @@ CsrSdioF0Write8(CsrSdioFunction *function, u32 address, u8 data) _sdio_release_host(func); if (err) { - func_exit_r(err); return ConvertSdioToCsrSdioResult(err); } @@ -286,7 +282,6 @@ CsrSdioRead(CsrSdioFunction *function, u32 address, void *data, u32 length) _sdio_release_host(func); if (err) { - func_exit_r(err); return ConvertSdioToCsrSdioResult(err); } @@ -304,7 +299,6 @@ CsrSdioWrite(CsrSdioFunction *function, u32 address, const void *data, u32 lengt _sdio_release_host(func); if (err) { - func_exit_r(err); return ConvertSdioToCsrSdioResult(err); } diff --git a/drivers/staging/csr/sme_wext.c b/drivers/staging/csr/sme_wext.c index 9b8385b5142..5e06a380b40 100644 --- a/drivers/staging/csr/sme_wext.c +++ b/drivers/staging/csr/sme_wext.c @@ -2202,7 +2202,6 @@ unifi_siwencode(struct net_device *dev, struct iw_request_info *info, CSR_WIFI_SME_ENCRYPTION_CIPHER_NONE; } - func_exit_r(rc); return convert_sme_error(rc); } /* unifi_siwencode() */ @@ -2453,7 +2452,6 @@ unifi_siwmlme(struct net_device *dev, struct iw_request_info *info, UF_RTNL_LOCK(); break; default: - func_exit_r(-EOPNOTSUPP); return -EOPNOTSUPP; } diff --git a/drivers/staging/csr/unifi_os.h b/drivers/staging/csr/unifi_os.h index c72b3a6266a..56a26982070 100644 --- a/drivers/staging/csr/unifi_os.h +++ b/drivers/staging/csr/unifi_os.h @@ -61,14 +61,6 @@ extern int unifi_debug; * etc. */ -#define func_exit_r(_rc) \ - do { \ - if (unifi_debug >= 5) { \ - printk("unifi: <= %s %d\n", __FUNCTION__, (int)(_rc)); \ - } \ - } while (0) - - #define ASSERT(cond) \ do { \ if (!(cond)) { \ @@ -95,7 +87,6 @@ void unifi_trace(void* ospriv, int level, const char *fmt, ...); #else /* Stubs */ -#define func_exit_r(_rc) #define ASSERT(cond) -- cgit v1.2.3 From 28c4ff643549f18a6c50df694ce4ba9975b7917f Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sun, 28 Oct 2012 21:41:28 +0900 Subject: staging : csr: Fix typo in csr/netdev.c Correct spelling typos in csr/netdev.c Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/netdev.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/csr/netdev.c b/drivers/staging/csr/netdev.c index 2d4a4e62221..7dad26f7017 100644 --- a/drivers/staging/csr/netdev.c +++ b/drivers/staging/csr/netdev.c @@ -54,7 +54,7 @@ #include -/* Wext handler is suported only if CSR_SUPPORT_WEXT is defined */ +/* Wext handler is supported only if CSR_SUPPORT_WEXT is defined */ #ifdef CSR_SUPPORT_WEXT extern struct iw_handler_def unifi_iw_handler_def; #endif /* CSR_SUPPORT_WEXT */ @@ -88,7 +88,7 @@ typedef int (*tx_signal_handler)(unifi_priv_t *priv, struct sk_buff *skb, const /* * The driver uses the qdisc interface to buffer and control all * outgoing traffic. We create a root qdisc, register our qdisc operations - * and later we create two subsiduary pfifo queues for the uncontrolled + * and later we create two subsidiary pfifo queues for the uncontrolled * and controlled ports. * * The network stack delivers all outgoing packets in our enqueue handler. @@ -1562,7 +1562,7 @@ send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr return -1; } - /* RA adrress must contain the immediate destination MAC address that is similiar to + /* RA address must contain the immediate destination MAC address that is similar to * the Address 1 field of 802.11 Mac header here 4 is: (sizeof(framecontrol) + sizeof (durationID)) * which is address 1 field */ @@ -2504,7 +2504,7 @@ static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_d return; } /* For monitor mode we need to pass this indication to the registered application - handle this seperately*/ + handle this separately*/ /* MIC failure is already taken care of so no need to send the PDUs which are not successfully received in non-monitor mode*/ if(pkt_ind->ReceptionStatus != CSR_RX_SUCCESS) { @@ -3037,13 +3037,13 @@ static void update_expected_sn(unifi_priv_t *priv, u16 gap; gap = (sn - ba_session->expected_sn) & 0xFFF; - unifi_trace(priv, UDBG6, "%s: proccess the frames up to new_expected_sn = %d gap = %d\n", __FUNCTION__, sn, gap); + unifi_trace(priv, UDBG6, "%s: process the frames up to new_expected_sn = %d gap = %d\n", __FUNCTION__, sn, gap); for(j = 0; j < gap && j < ba_session->wind_size; j++) { i = SN_TO_INDEX(ba_session, ba_session->expected_sn); - unifi_trace(priv, UDBG6, "%s: proccess the slot index = %d\n", __FUNCTION__, i); + unifi_trace(priv, UDBG6, "%s: process the slot index = %d\n", __FUNCTION__, i); if(ba_session->buffer[i].active) { add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]); - unifi_trace(priv, UDBG6, "%s: proccess the frame at index = %d expected_sn = %d\n", __FUNCTION__, i, ba_session->expected_sn); + unifi_trace(priv, UDBG6, "%s: process the frame at index = %d expected_sn = %d\n", __FUNCTION__, i, ba_session->expected_sn); FREE_BUFFER_SLOT(ba_session, i); } else { unifi_trace(priv, UDBG6, "%s: empty slot at index = %d\n", __FUNCTION__, i); -- cgit v1.2.3 From b58d6021d4dbc215dc975510bb2509e66e6061be Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Sat, 27 Oct 2012 13:23:47 -0400 Subject: staging: sep: return -EFAULT on copy_from_user failure copy_from_user() returns the number of bytes remaining to be copied, and it fails if user pointer is invalid, so return -EFAULT so that the user gets a FAULT. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index a414e52dd08..2c8df0e6b6d 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -3431,7 +3431,7 @@ static ssize_t sep_create_dcb_dmatables_context(struct sep_device *sep, if (copy_from_user(dcb_args, user_dcb_args, num_dcbs * sizeof(struct build_dcb_struct))) { - error = -EINVAL; + error = -EFAULT; goto end_function; } @@ -3619,7 +3619,7 @@ static ssize_t sep_create_msgarea_context(struct sep_device *sep, /* Copy input data to write() to allocated message buffer */ if (copy_from_user(*msg_region, msg_user, msg_len)) { - error = -EINVAL; + error = -EFAULT; goto end_function; } -- cgit v1.2.3 From 543a09e9cf1485a8b55f6459b28f3fbab7bb55c3 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sun, 28 Oct 2012 06:46:33 +0900 Subject: staging/comedi: Fix trailing statements should be on next line in drivers/quatech_daqp_cs.c fixed below checkpatch errors. - ERROR: trailing statements should be on next line Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index d15bd8ac3d4..806523c4c46 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -395,7 +395,8 @@ static int daqp_ai_insn_read(struct comedi_device *dev, */ while (--counter - && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ; + && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) + ; if (!counter) { printk("daqp: couldn't clear interrupts in status register\n"); return -1; @@ -732,7 +733,8 @@ static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) */ counter = 100; while (--counter - && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ; + && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) + ; if (!counter) { dev_err(dev->class_dev, "couldn't clear interrupts in status register\n"); -- cgit v1.2.3 From 53f63dc7986ef72e5a2b1f046f1f65f484bdb51b Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sun, 28 Oct 2012 06:47:26 +0900 Subject: staging/comedi: Use dev_ printks in drivers/quatech_daqp_cs.c fixed below checkpatch warnings. - WARNING: printk() should include KERN_ facility level Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index 806523c4c46..ee9158b203c 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -300,7 +300,7 @@ static enum irqreturn daqp_interrupt(int irq, void *dev_id) if (status & DAQP_STATUS_DATA_LOST) { s->async->events |= COMEDI_CB_EOA | COMEDI_CB_OVERFLOW; - printk("daqp: data lost\n"); + dev_warn(dev->class_dev, "data lost\n"); daqp_ai_cancel(dev, s); break; } @@ -398,7 +398,8 @@ static int daqp_ai_insn_read(struct comedi_device *dev, && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ; if (!counter) { - printk("daqp: couldn't clear interrupts in status register\n"); + dev_err(dev->class_dev, + "couldn't clear interrupts in status register\n"); return -1; } @@ -824,8 +825,8 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; if (it->options[0] < 0 || it->options[0] >= MAX_DEV || !local) { - printk("comedi%d: No such daqp device %d\n", - dev->minor, it->options[0]); + dev_err(dev->class_dev, "No such daqp device %d\n", + it->options[0]); return -EIO; } -- cgit v1.2.3 From 9d8a20a52cd760d1a8739fc408e68617f9d6577b Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Mon, 29 Oct 2012 22:18:05 +0100 Subject: staging/rtl8192e: Fix compile warning 'is static but declared in .. which is not static' When compiling this driver I get these compile warnings: rtllib.h:2573:2: warning: '______f' is static but declared in inline function 'rtllib_is_empty_essid' which is not static [enabled by default] rtllib.h:2579:3: warning: '______f' is static but declared in inline function 'rtllib_is_empty_essid' which is not static [enabled by default] rtllib.h:2594:2: warning: '______f' is static but declared in inline function 'rtllib_is_valid_mode' which is not static [enabled by default] rtllib.h:2599:2: warning: '______f' is static but declared in inline function 'rtllib_is_valid_mode' which is not static [enabled by default] rtllib.h:2604:2: warning: '______f' is static but declared in inline function 'rtllib_is_valid_mode' which is not static [enabled by default] rtllib.h:2618:3: warning: '______f' is static but declared in inline function 'rtllib_get_hdrlen' which is not static [enabled by default] rtllib.h:2620:3: warning: '______f' is static but declared in inline function 'rtllib_get_hdrlen' which is not static [enabled by default] These functions are declared as extern inline but not 'overloaded' anywhere so we can declare them static inline and get rid of the warnings. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 9ac8d8ea4ae..3485ef1dfab 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -2567,7 +2567,7 @@ static inline void *rtllib_priv(struct net_device *dev) return ((struct rtllib_device *)netdev_priv(dev))->priv; } -extern inline int rtllib_is_empty_essid(const char *essid, int essid_len) +static inline int rtllib_is_empty_essid(const char *essid, int essid_len) { /* Single white space is for Linksys APs */ if (essid_len == 1 && essid[0] == ' ') @@ -2583,7 +2583,7 @@ extern inline int rtllib_is_empty_essid(const char *essid, int essid_len) return 1; } -extern inline int rtllib_is_valid_mode(struct rtllib_device *ieee, int mode) +static inline int rtllib_is_valid_mode(struct rtllib_device *ieee, int mode) { /* * It is possible for both access points and our device to support @@ -2609,7 +2609,7 @@ extern inline int rtllib_is_valid_mode(struct rtllib_device *ieee, int mode) return 0; } -extern inline int rtllib_get_hdrlen(u16 fc) +static inline int rtllib_get_hdrlen(u16 fc) { int hdrlen = RTLLIB_3ADDR_LEN; -- cgit v1.2.3 From f71ccaa4bf8abffbd15012bda7b5da5b6695a879 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Mon, 29 Oct 2012 22:33:20 +0100 Subject: staging/rtl8187se: Fix compile warning 'is static but declared in .. which is not static' When compiling this driver I get these compile warnings: ieee80211.h:1227:2: warning: '______f' is static but declared in inline function 'ieee80211_is_empty_essid' which is not static [enabled by default] ieee80211.h:1233:3: warning: '______f' is static but declared in inline function 'ieee80211_is_empty_essid' which is not static [enabled by default] ieee80211.h:1248:2: warning: '______f' is static but declared in inline function 'ieee80211_is_valid_mode' which is not static [enabled by default] ieee80211.h:1253:2: warning: '______f' is static but declared in inline function 'ieee80211_is_valid_mode' which is not static [enabled by default] ieee80211.h:1258:2: warning: '______f' is static but declared in inline function 'ieee80211_is_valid_mode' which is not static [enabled by default] ieee80211.h:1272:3: warning: '______f' is static but declared in inline function 'ieee80211_get_hdrlen' which is not static [enabled by default] ieee80211.h:1274:3: warning: '______f' is static but declared in inline function 'ieee80211_get_hdrlen' which is not static [enabled by default] These functions are declared as extern inline but not 'overloaded' anywhere so we can declare them static inline and get rid of the warnings. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h index 5f5a30223d5..8fc9f588b05 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h @@ -1221,7 +1221,7 @@ static inline void *ieee80211_priv(struct net_device *dev) return ((struct ieee80211_device *)netdev_priv(dev))->priv; } -extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) +static inline int ieee80211_is_empty_essid(const char *essid, int essid_len) { /* Single white space is for Linksys APs */ if (essid_len == 1 && essid[0] == ' ') @@ -1237,7 +1237,7 @@ extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) return 1; } -extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode) +static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode) { /* * It is possible for both access points and our device to support @@ -1263,7 +1263,7 @@ extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mod return 0; } -extern inline int ieee80211_get_hdrlen(u16 fc) +static inline int ieee80211_get_hdrlen(u16 fc) { int hdrlen = 24; -- cgit v1.2.3 From 7defac36db43df73feef44e0f6edc298868ae1ac Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Mon, 29 Oct 2012 13:50:37 +0800 Subject: staging: dgrp: fix potential NULL defereference issue Fix a coccinelle warning catched by Fengguang's 0-DAY system: + drivers/staging/dgrp/dgrp_net_ops.c:1061:11-27: ERROR: nd is NULL but dereferenced. Put the "done:" label a bit down would solve this issue. Cc: Fengguang Wu Cc: Julia Lawall Cc: Greg Kroah-Hartman Signed-off-by: Yuanhan Liu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgrp/dgrp_net_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index 067d9755544..c409cd03e8c 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c @@ -1057,13 +1057,13 @@ static int dgrp_net_release(struct inode *inode, struct file *file) spin_unlock_irqrestore(&dgrp_poll_data.poll_lock, lock_flags); -done: down(&nd->nd_net_semaphore); dgrp_monitor_message(nd, "Net Close"); up(&nd->nd_net_semaphore); +done: module_put(THIS_MODULE); file->private_data = NULL; return 0; -- cgit v1.2.3 From 3e4cce9dadada9661ee7464904151c5570e7b51c Mon Sep 17 00:00:00 2001 From: Chad Williamson Date: Sun, 28 Oct 2012 16:08:18 -0500 Subject: Staging: silicom: remove code requiring an old LINUX_VERSION_CODE Remove all code and associated preprocessor logic dependent on an old LINUX_VERSION_CODE since such code is dead for an in-kernel driver. Signed-off-by: Chad Williamson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bp_mod.c | 207 +---------------------------- drivers/staging/silicom/bypasslib/bplibk.h | 9 -- 2 files changed, 3 insertions(+), 213 deletions(-) diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index f579f143f85..018b4ff3c3a 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -4319,16 +4319,6 @@ void remove_bypass_wd_auto(bpctl_dev_t *pbpctl_dev) del_timer_sync(&pbpctl_dev->bp_timer); #ifdef BP_SELF_TEST pbpctl_dev_sl = get_status_port_fn(pbpctl_dev); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) - if (pbpctl_dev_sl && (pbpctl_dev_sl->ndev) - && (pbpctl_dev_sl->ndev->hard_start_xmit) - && (pbpctl_dev_sl->hard_start_xmit_save)) { - rtnl_lock(); - pbpctl_dev_sl->ndev->hard_start_xmit = - pbpctl_dev_sl->hard_start_xmit_save; - rtnl_unlock(); - } -#else if (pbpctl_dev_sl && (pbpctl_dev_sl->ndev)) { if ((pbpctl_dev_sl->ndev->netdev_ops) && (pbpctl_dev_sl->old_ops)) { @@ -4342,8 +4332,6 @@ void remove_bypass_wd_auto(bpctl_dev_t *pbpctl_dev) } } - -#endif #endif } @@ -4433,23 +4421,7 @@ int set_bp_self_test(bpctl_dev_t *pbpctl_dev, unsigned int param) if (pbpctl_dev->bp_caps & WD_CTL_CAP) { pbpctl_dev->bp_self_test_flag = param == 0 ? 0 : 1; pbpctl_dev_sl = get_status_port_fn(pbpctl_dev); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) - if ((pbpctl_dev_sl->ndev) && - (pbpctl_dev_sl->ndev->hard_start_xmit)) { - rtnl_lock(); - if (pbpctl_dev->bp_self_test_flag == 1) { - pbpctl_dev_sl->hard_start_xmit_save = - pbpctl_dev_sl->ndev->hard_start_xmit; - pbpctl_dev_sl->ndev->hard_start_xmit = - bp_hard_start_xmit; - } else if (pbpctl_dev_sl->hard_start_xmit_save) { - pbpctl_dev_sl->ndev->hard_start_xmit = - pbpctl_dev_sl->hard_start_xmit_save; - } - rtnl_unlock(); - } -#else if ((pbpctl_dev_sl->ndev) && (pbpctl_dev_sl->ndev->netdev_ops)) { rtnl_lock(); if (pbpctl_dev->bp_self_test_flag == 1) { @@ -4470,7 +4442,6 @@ int set_bp_self_test(bpctl_dev_t *pbpctl_dev, unsigned int param) } rtnl_unlock(); } -#endif set_bypass_wd_auto(pbpctl_dev, param); return 0; @@ -5428,15 +5399,8 @@ static void if_scan_init(void) /* rcu_read_lock(); */ /* rtnl_lock(); */ /* rcu_read_lock(); */ -#if 1 -#if (LINUX_VERSION_CODE >= 0x020618) - for_each_netdev(&init_net, dev) -#elif (LINUX_VERSION_CODE >= 0x20616) - for_each_netdev(dev) -#else - for (dev = dev_base; dev; dev = dev->next) -#endif - { + + for_each_netdev(&init_net, dev) { struct ethtool_drvinfo drvinfo; char cbuf[32]; @@ -5489,22 +5453,14 @@ static void if_scan_init(void) } } -#endif /* rtnl_unlock(); */ /* rcu_read_unlock(); */ } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) -static int device_ioctl(struct inode *inode, /* see include/linux/fs.h */ - struct file *file, /* ditto */ - unsigned int ioctl_num, /* number and param for ioctl */ - unsigned long ioctl_param) -#else -static long device_ioctl(struct file *file, /* ditto */ +static long device_ioctl(struct file *file, /* see include/linux/fs.h */ unsigned int ioctl_num, /* number and param for ioctl */ unsigned long ioctl_param) -#endif { struct bpctl_cmd bpctl_cmd; int dev_idx = 0; @@ -5515,9 +5471,7 @@ static long device_ioctl(struct file *file, /* ditto */ static bpctl_dev_t *pbpctl_dev; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) /* lock_kernel(); */ -#endif lock_bpctl(); /* local_irq_save(flags); */ /* if(!spin_trylock_irqsave(&bpvm_lock)){ @@ -5898,9 +5852,7 @@ static long device_ioctl(struct file *file, /* ditto */ ret = -EFAULT; ret = SUCCESS; bp_exit: -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) /* unlock_kernel(); */ -#endif /* spin_unlock_irqrestore(&bpvm_lock, flags); */ unlock_bpctl(); /* unlock_kernel(); */ @@ -5909,12 +5861,7 @@ static long device_ioctl(struct file *file, /* ditto */ struct file_operations Fops = { .owner = THIS_MODULE, -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) - .ioctl = device_ioctl, -#else .unlocked_ioctl = device_ioctl, -#endif - .open = device_open, .release = device_release, /* a.k.a. close */ }; @@ -6950,15 +6897,8 @@ static int __init bypass_init_module(void) memset(bpctl_dev_arr[idx_dev].bp_tx_data + 7, 0xaa, 5); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)) - bpctl_dev_arr[idx_dev].bp_tx_data[12] = - (ETH_P_BPTEST >> 8) & 0xff; - bpctl_dev_arr[idx_dev].bp_tx_data[13] = - ETH_P_BPTEST & 0xff; -#else *(__be16 *) (bpctl_dev_arr[idx_dev].bp_tx_data + 12) = htons(ETH_P_BPTEST); -#endif } else printk("bp_ctl: Memory allocation error!\n"); @@ -7007,83 +6947,6 @@ static int __init bypass_init_module(void) } } -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) - inter_module_register("is_bypass_sd", THIS_MODULE, &is_bypass_sd); - inter_module_register("get_bypass_slave_sd", THIS_MODULE, - &get_bypass_slave_sd); - inter_module_register("get_bypass_caps_sd", THIS_MODULE, - &get_bypass_caps_sd); - inter_module_register("get_wd_set_caps_sd", THIS_MODULE, - &get_wd_set_caps_sd); - inter_module_register("set_bypass_sd", THIS_MODULE, &set_bypass_sd); - inter_module_register("get_bypass_sd", THIS_MODULE, &get_bypass_sd); - inter_module_register("get_bypass_change_sd", THIS_MODULE, - &get_bypass_change_sd); - inter_module_register("set_dis_bypass_sd", THIS_MODULE, - &set_dis_bypass_sd); - inter_module_register("get_dis_bypass_sd", THIS_MODULE, - &get_dis_bypass_sd); - inter_module_register("set_bypass_pwoff_sd", THIS_MODULE, - &set_bypass_pwoff_sd); - inter_module_register("get_bypass_pwoff_sd", THIS_MODULE, - &get_bypass_pwoff_sd); - inter_module_register("set_bypass_pwup_sd", THIS_MODULE, - &set_bypass_pwup_sd); - inter_module_register("get_bypass_pwup_sd", THIS_MODULE, - &get_bypass_pwup_sd); - inter_module_register("get_bypass_wd_sd", THIS_MODULE, - &get_bypass_wd_sd); - inter_module_register("set_bypass_wd_sd", THIS_MODULE, - &set_bypass_wd_sd); - inter_module_register("get_wd_expire_time_sd", THIS_MODULE, - &get_wd_expire_time_sd); - inter_module_register("reset_bypass_wd_timer_sd", THIS_MODULE, - &reset_bypass_wd_timer_sd); - inter_module_register("set_std_nic_sd", THIS_MODULE, &set_std_nic_sd); - inter_module_register("get_std_nic_sd", THIS_MODULE, &get_std_nic_sd); - inter_module_register("set_tx_sd", THIS_MODULE, &set_tx_sd); - inter_module_register("get_tx_sd", THIS_MODULE, &get_tx_sd); - inter_module_register("set_tpl_sd", THIS_MODULE, &set_tpl_sd); - inter_module_register("get_tpl_sd", THIS_MODULE, &get_tpl_sd); - - inter_module_register("set_bp_hw_reset_sd", THIS_MODULE, - &set_bp_hw_reset_sd); - inter_module_register("get_bp_hw_reset_sd", THIS_MODULE, - &get_bp_hw_reset_sd); - - inter_module_register("set_tap_sd", THIS_MODULE, &set_tap_sd); - inter_module_register("get_tap_sd", THIS_MODULE, &get_tap_sd); - inter_module_register("get_tap_change_sd", THIS_MODULE, - &get_tap_change_sd); - inter_module_register("set_dis_tap_sd", THIS_MODULE, &set_dis_tap_sd); - inter_module_register("get_dis_tap_sd", THIS_MODULE, &get_dis_tap_sd); - inter_module_register("set_tap_pwup_sd", THIS_MODULE, &set_tap_pwup_sd); - inter_module_register("get_tap_pwup_sd", THIS_MODULE, &get_tap_pwup_sd); - inter_module_register("set_bp_disc_sd", THIS_MODULE, &set_bp_disc_sd); - inter_module_register("get_bp_disc_sd", THIS_MODULE, &get_bp_disc_sd); - inter_module_register("get_bp_disc_change_sd", THIS_MODULE, - &get_bp_disc_change_sd); - inter_module_register("set_bp_dis_disc_sd", THIS_MODULE, - &set_bp_dis_disc_sd); - inter_module_register("get_bp_dis_disc_sd", THIS_MODULE, - &get_bp_dis_disc_sd); - inter_module_register("set_bp_disc_pwup_sd", THIS_MODULE, - &set_bp_disc_pwup_sd); - inter_module_register("get_bp_disc_pwup_sd", THIS_MODULE, - &get_bp_disc_pwup_sd); - inter_module_register("set_wd_exp_mode_sd", THIS_MODULE, - &set_wd_exp_mode_sd); - inter_module_register("get_wd_exp_mode_sd", THIS_MODULE, - &get_wd_exp_mode_sd); - inter_module_register("set_wd_autoreset_sd", THIS_MODULE, - &set_wd_autoreset_sd); - inter_module_register("get_wd_autoreset_sd", THIS_MODULE, - &get_wd_autoreset_sd); - inter_module_register("get_bypass_info_sd", THIS_MODULE, - &get_bypass_info_sd); - inter_module_register("bp_if_scan_sd", THIS_MODULE, &bp_if_scan_sd); - -#endif register_netdevice_notifier(&bp_notifier_block); #ifdef BP_PROC_SUPPORT { @@ -7113,58 +6976,8 @@ static int __init bypass_init_module(void) static void __exit bypass_cleanup_module(void) { int i; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) - int ret; -#endif unregister_netdevice_notifier(&bp_notifier_block); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) - inter_module_unregister("is_bypass_sd"); - inter_module_unregister("get_bypass_slave_sd"); - inter_module_unregister("get_bypass_caps_sd"); - inter_module_unregister("get_wd_set_caps_sd"); - inter_module_unregister("set_bypass_sd"); - inter_module_unregister("get_bypass_sd"); - inter_module_unregister("get_bypass_change_sd"); - inter_module_unregister("set_dis_bypass_sd"); - inter_module_unregister("get_dis_bypass_sd"); - inter_module_unregister("set_bypass_pwoff_sd"); - inter_module_unregister("get_bypass_pwoff_sd"); - inter_module_unregister("set_bypass_pwup_sd"); - inter_module_unregister("get_bypass_pwup_sd"); - inter_module_unregister("set_bypass_wd_sd"); - inter_module_unregister("get_bypass_wd_sd"); - inter_module_unregister("get_wd_expire_time_sd"); - inter_module_unregister("reset_bypass_wd_timer_sd"); - inter_module_unregister("set_std_nic_sd"); - inter_module_unregister("get_std_nic_sd"); - inter_module_unregister("set_tx_sd"); - inter_module_unregister("get_tx_sd"); - inter_module_unregister("set_tpl_sd"); - inter_module_unregister("get_tpl_sd"); - inter_module_unregister("set_tap_sd"); - inter_module_unregister("get_tap_sd"); - inter_module_unregister("get_tap_change_sd"); - inter_module_unregister("set_dis_tap_sd"); - inter_module_unregister("get_dis_tap_sd"); - inter_module_unregister("set_tap_pwup_sd"); - inter_module_unregister("get_tap_pwup_sd"); - inter_module_unregister("set_bp_disc_sd"); - inter_module_unregister("get_bp_disc_sd"); - inter_module_unregister("get_bp_disc_change_sd"); - inter_module_unregister("set_bp_dis_disc_sd"); - inter_module_unregister("get_bp_dis_disc_sd"); - inter_module_unregister("set_bp_disc_pwup_sd"); - inter_module_unregister("get_bp_disc_pwup_sd"); - inter_module_unregister("set_wd_exp_mode_sd"); - inter_module_unregister("get_wd_exp_mode_sd"); - inter_module_unregister("set_wd_autoreset_sd"); - inter_module_unregister("get_wd_autoreset_sd"); - inter_module_unregister("get_bypass_info_sd"); - inter_module_unregister("bp_if_scan_sd"); - -#endif - for (i = 0; i < device_num; i++) { /* unsigned long flags; */ #ifdef BP_PROC_SUPPORT @@ -7196,17 +7009,7 @@ static void __exit bypass_cleanup_module(void) /* * Unregister the device */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) - ret = unregister_chrdev(major_num, DEVICE_NAME); -/* -* If there's an error, report it -*/ - if (ret < 0) - printk("Error in module_unregister_chrdev: %d\n", ret); -#else unregister_chrdev(major_num, DEVICE_NAME); - -#endif } module_init(bypass_init_module); @@ -7595,11 +7398,7 @@ static struct proc_dir_entry *proc_getdir(char *name, } if (pde == (struct proc_dir_entry *)0) { /* create the directory */ -#if (LINUX_VERSION_CODE > 0x20300) pde = proc_mkdir(name, proc_dir); -#else - pde = create_proc_entry(name, S_IFDIR, proc_dir); -#endif if (pde == (struct proc_dir_entry *)0) { return pde; diff --git a/drivers/staging/silicom/bypasslib/bplibk.h b/drivers/staging/silicom/bypasslib/bplibk.h index e9db2d114ba..a726d90853e 100644 --- a/drivers/staging/silicom/bypasslib/bplibk.h +++ b/drivers/staging/silicom/bypasslib/bplibk.h @@ -29,16 +29,7 @@ ((pid==INTEL_PEG4BPII_PID)|| \ (pid==INTEL_PEG4BPFII_PID))) -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) -#define pci_get_class pci_find_class - -#define pci_get_device pci_find_device - -#endif - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)) #define EXPORT_SYMBOL_NOVERS EXPORT_SYMBOL -#endif #ifdef BP_VENDOR_SUPPORT char *bp_desc_array[] = -- cgit v1.2.3 From f9c3e4e7a797ec7c0de3ad6372ca332692cd0115 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Sat, 27 Oct 2012 21:44:12 +0100 Subject: staging: comedi: change type of auto-config context Change the type of the context parameter passed to `comedi_auto_config_helper()` from `void *` to `unsigned long`. It's currently just an internal change and all current internal usages pass pointers in the context, but future uses of this function may pass integer values or pointer values at the whim of a lower-level comedi driver and the `unsigned long` type expresses this better as it is commonly used in the Linux kernel to hold such values. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 09e1daf9576..2c3db49c0df 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -837,7 +837,8 @@ static int comedi_auto_config_helper(struct device *hardware_device, struct comedi_driver *driver, int (*attach_wrapper) (struct comedi_device *, - void *), void *context) + unsigned long), + unsigned long context) { int minor; struct comedi_device_file_info *dev_file_info; @@ -878,9 +879,10 @@ comedi_auto_config_helper(struct device *hardware_device, return ret; } -static int comedi_auto_config_wrapper(struct comedi_device *dev, void *context) +static int comedi_auto_config_wrapper(struct comedi_device *dev, + unsigned long context) { - struct comedi_devconfig *it = context; + struct comedi_devconfig *it = (struct comedi_devconfig *)context; struct comedi_driver *driv = dev->driver; if (driv->num_names) { @@ -916,7 +918,8 @@ static int comedi_auto_config(struct device *hardware_device, BUG_ON(num_options > COMEDI_NDEVCONFOPTS); memcpy(it.options, options, num_options * sizeof(int)); return comedi_auto_config_helper(hardware_device, driver, - comedi_auto_config_wrapper, &it); + comedi_auto_config_wrapper, + (unsigned long)&it); } static void comedi_auto_unconfig(struct device *hardware_device) @@ -980,16 +983,18 @@ static int comedi_old_pci_auto_config(struct pci_dev *pcidev, options, ARRAY_SIZE(options)); } -static int comedi_pci_attach_wrapper(struct comedi_device *dev, void *pcidev) +static int comedi_pci_attach_wrapper(struct comedi_device *dev, + unsigned long context) { - return dev->driver->attach_pci(dev, pcidev); + return dev->driver->attach_pci(dev, (struct pci_dev *)context); } static int comedi_new_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) { return comedi_auto_config_helper(&pcidev->dev, driver, - comedi_pci_attach_wrapper, pcidev); + comedi_pci_attach_wrapper, + (unsigned long)pcidev); } int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) @@ -1047,16 +1052,18 @@ static int comedi_old_usb_auto_config(struct usb_interface *intf, return comedi_auto_config(&intf->dev, driver, NULL, 0); } -static int comedi_usb_attach_wrapper(struct comedi_device *dev, void *intf) +static int comedi_usb_attach_wrapper(struct comedi_device *dev, + unsigned long context) { - return dev->driver->attach_usb(dev, intf); + return dev->driver->attach_usb(dev, (struct usb_interface *)context); } static int comedi_new_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { return comedi_auto_config_helper(&intf->dev, driver, - comedi_usb_attach_wrapper, intf); + comedi_usb_attach_wrapper, + (unsigned long)intf); } int comedi_usb_auto_config(struct usb_interface *intf, -- cgit v1.2.3 From 156096a0398fd5c42beeed87ad9b79134d890d22 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Sat, 27 Oct 2012 21:44:13 +0100 Subject: staging: comedi: rename old auto-config functions Rename `comedi_auto_config()` to `comedi_old_auto_config()`, and `comedi_auto_config_wrapper()` to `comedi_old_auto_config_wrapper()`. These functions are deprecated and will be removed once the few remaining low-level comedi drivers that use them have been updated. (The low-level drivers in question support auto-configuration of detected comedi devices, but still use the `attach()` hook in their `struct comedi_driver` to do so.) This internal change frees up the name `comedi_auto_config` for future use. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 2c3db49c0df..4e61f5bd679 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -879,8 +879,8 @@ comedi_auto_config_helper(struct device *hardware_device, return ret; } -static int comedi_auto_config_wrapper(struct comedi_device *dev, - unsigned long context) +static int comedi_old_auto_config_wrapper(struct comedi_device *dev, + unsigned long context) { struct comedi_devconfig *it = (struct comedi_devconfig *)context; struct comedi_driver *driv = dev->driver; @@ -906,9 +906,9 @@ static int comedi_auto_config_wrapper(struct comedi_device *dev, return driv->attach(dev, it); } -static int comedi_auto_config(struct device *hardware_device, - struct comedi_driver *driver, const int *options, - unsigned num_options) +static int comedi_old_auto_config(struct device *hardware_device, + struct comedi_driver *driver, + const int *options, unsigned num_options) { struct comedi_devconfig it; @@ -918,7 +918,7 @@ static int comedi_auto_config(struct device *hardware_device, BUG_ON(num_options > COMEDI_NDEVCONFOPTS); memcpy(it.options, options, num_options * sizeof(int)); return comedi_auto_config_helper(hardware_device, driver, - comedi_auto_config_wrapper, + comedi_old_auto_config_wrapper, (unsigned long)&it); } @@ -979,8 +979,8 @@ static int comedi_old_pci_auto_config(struct pci_dev *pcidev, /* pci slot */ options[1] = PCI_SLOT(pcidev->devfn); - return comedi_auto_config(&pcidev->dev, driver, - options, ARRAY_SIZE(options)); + return comedi_old_auto_config(&pcidev->dev, driver, + options, ARRAY_SIZE(options)); } static int comedi_pci_attach_wrapper(struct comedi_device *dev, @@ -1049,7 +1049,7 @@ EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); static int comedi_old_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { - return comedi_auto_config(&intf->dev, driver, NULL, 0); + return comedi_old_auto_config(&intf->dev, driver, NULL, 0); } static int comedi_usb_attach_wrapper(struct comedi_device *dev, -- cgit v1.2.3 From 8ed705aff0652fdbd2c6b406155d7d480e1aabe0 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Sat, 27 Oct 2012 21:44:14 +0100 Subject: staging: comedi: add generic auto-config functions Add (and export) generic auto-config function `comedi_auto_config()` to allow hardware devices on arbitrary bus types (e.g. platform devices, spi devices, etc.) to be auto-configured as comedi devices. This uses a new `auto_attach()` hook in the `struct comedi_driver`. This new hook will eventually replace the bus-specific `attach_pci()` and `attach_usb()` hooks in the low-level comedi drivers. When the `auto_attach()` hook is called in the low-level driver, the `hw_dev` member of the `struct comedi_device` will have already been set to the hardware device passed to `comedi_auto_config()`. The low-level driver can convert this to some bus-device wrapper structure pointer, possibly with the help of the `context` parameter that is passed unchanged from the `comedi_auto_config()` call. Also export the existing `comedi_auto_unconfig()` function as the matching call to `comedi_auto_config()`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 4 ++++ drivers/staging/comedi/drivers.c | 23 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index d9f2b8bfe6f..2b884a6e028 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -204,6 +204,7 @@ struct comedi_driver { void (*detach) (struct comedi_device *); int (*attach_pci) (struct comedi_device *, struct pci_dev *); int (*attach_usb) (struct comedi_device *, struct usb_interface *); + int (*auto_attach) (struct comedi_device *, unsigned long); /* number of elements in board_name and board_id arrays */ unsigned int num_names; @@ -510,6 +511,9 @@ static inline void *comedi_aux_data(int options[], int n) int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s); void comedi_free_subdevice_minor(struct comedi_subdevice *s); +int comedi_auto_config(struct device *hardware_device, + struct comedi_driver *driver, unsigned long context); +void comedi_auto_unconfig(struct device *hardware_device); int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver); void comedi_pci_auto_unconfig(struct pci_dev *pcidev); diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 4e61f5bd679..d60fa551a53 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -922,7 +922,27 @@ static int comedi_old_auto_config(struct device *hardware_device, (unsigned long)&it); } -static void comedi_auto_unconfig(struct device *hardware_device) +static int comedi_auto_config_wrapper(struct comedi_device *dev, + unsigned long context) +{ + if (!dev->driver->auto_attach) { + dev_warn(dev->class_dev, + "BUG! driver '%s' has no auto_attach handler\n", + dev->driver->driver_name); + return -EINVAL; + } + return dev->driver->auto_attach(dev, context); +} + +int comedi_auto_config(struct device *hardware_device, + struct comedi_driver *driver, unsigned long context) +{ + return comedi_auto_config_helper(hardware_device, driver, + comedi_auto_config_wrapper, context); +} +EXPORT_SYMBOL_GPL(comedi_auto_config); + +void comedi_auto_unconfig(struct device *hardware_device) { int minor; @@ -934,6 +954,7 @@ static void comedi_auto_unconfig(struct device *hardware_device) BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); comedi_free_board_minor(minor); } +EXPORT_SYMBOL_GPL(comedi_auto_unconfig); /** * comedi_pci_enable() - Enable the PCI device and request the regions. -- cgit v1.2.3 From d5121914a22c22d849abb57d086fe408c9ca2c0c Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Sat, 27 Oct 2012 21:44:15 +0100 Subject: staging: comedi: support auto_attach() for PCI and USB Allow `comedi_pci_auto_config()` and `comedi_usb_auto_config()` to use the new `auto_attach()` hook in the low-level driver's `struct comedi_driver` if it is set and the `attach_pci()` or `attach_usb()` hook (for PCI or USB respectively) is `NULL`. Eventually, the `auto_attach()` hook will be the only way of auto-configuring hardware devices as comedi devices and the bus-type specific `attach_pci()` and `attach_usb()` hooks will be removed. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index d60fa551a53..adae25643b1 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -1023,6 +1023,8 @@ int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) if (driver->attach_pci) return comedi_new_pci_auto_config(pcidev, driver); + else if (driver->auto_attach) + return comedi_auto_config(&pcidev->dev, driver, 0); else return comedi_old_pci_auto_config(pcidev, driver); } @@ -1093,6 +1095,8 @@ int comedi_usb_auto_config(struct usb_interface *intf, BUG_ON(intf == NULL); if (driver->attach_usb) return comedi_new_usb_auto_config(intf, driver); + else if (driver->auto_attach) + return comedi_auto_config(&intf->dev, driver, 0); else return comedi_old_usb_auto_config(intf, driver); } -- cgit v1.2.3 From 0a577b823d0202b94eeef0e6b2b5653527fd6134 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Sat, 27 Oct 2012 21:44:16 +0100 Subject: staging: comedi: add comedi to usb interface helper Add inline helper function `comedi_to_usb_interface()` to get the pointer to `struct usb_interface` associated with the comedi device. This pointer is set by the call to `comedi_usb_auto_config()`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 2b884a6e028..4ac2de43cdb 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -41,6 +41,7 @@ #include #include #include +#include #include "comedi.h" @@ -193,8 +194,6 @@ struct comedi_async { unsigned int x); }; -struct usb_interface; - struct comedi_driver { struct comedi_driver *next; @@ -457,6 +456,12 @@ static inline struct pci_dev *comedi_to_pci_dev(struct comedi_device *dev) return dev->hw_dev ? to_pci_dev(dev->hw_dev) : NULL; } +static inline struct usb_interface * +comedi_to_usb_interface(struct comedi_device *dev) +{ + return dev->hw_dev ? to_usb_interface(dev->hw_dev) : NULL; +} + int comedi_buf_put(struct comedi_async *async, short x); int comedi_buf_get(struct comedi_async *async, short *x); -- cgit v1.2.3 From 392ba7bc37b453ae056542045fd7b8b349c7978e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Sat, 27 Oct 2012 21:44:17 +0100 Subject: staging: comedi: vmk80xx: use auto_attach() hook Use the new `auto_attach()` hook in the `struct comedi_driver` instead of the old `attach_usb()` hook. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/vmk80xx.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c index 366490776c5..609dc691599 100644 --- a/drivers/staging/comedi/drivers/vmk80xx.c +++ b/drivers/staging/comedi/drivers/vmk80xx.c @@ -1209,9 +1209,10 @@ static int vmk80xx_attach(struct comedi_device *cdev, } /* called via comedi_usb_auto_config() */ -static int vmk80xx_attach_usb(struct comedi_device *cdev, - struct usb_interface *intf) +static int vmk80xx_auto_attach(struct comedi_device *cdev, + unsigned long context_unused) { + struct usb_interface *intf = comedi_to_usb_interface(cdev); int i; int ret; @@ -1246,7 +1247,7 @@ static struct comedi_driver vmk80xx_driver = { .driver_name = "vmk80xx", .attach = vmk80xx_attach, .detach = vmk80xx_detach, - .attach_usb = vmk80xx_attach_usb, + .auto_attach = vmk80xx_auto_attach, }; static int vmk80xx_usb_probe(struct usb_interface *intf, -- cgit v1.2.3 From 1ed1b3df2e02b8f890e0f3b9d3dad0f39e3418a8 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Sat, 27 Oct 2012 21:44:18 +0100 Subject: staging: comedi: amplc_pci230: use auto_attach() hook Use the new `auto_attach()` hook in the `struct comedi_driver` instead of the old `attach_pci()` hook. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index d66d7d797f7..db67c8313ca 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2843,9 +2843,10 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) return pci230_attach_common(dev, pci_dev); } -static int __devinit pci230_attach_pci(struct comedi_device *dev, - struct pci_dev *pci_dev) +static int __devinit pci230_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pci_dev = comedi_to_pci_dev(dev); int rc; dev_info(dev->class_dev, "amplc_pci230: attach pci %s\n", @@ -2891,7 +2892,7 @@ static struct comedi_driver amplc_pci230_driver = { .driver_name = "amplc_pci230", .module = THIS_MODULE, .attach = pci230_attach, - .attach_pci = pci230_attach_pci, + .auto_attach = pci230_auto_attach, .detach = pci230_detach, .board_name = &pci230_boards[0].name, .offset = sizeof(pci230_boards[0]), -- cgit v1.2.3 From 106b0b4c406db49e75ebb2ac99a56582e959ab71 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 27 Oct 2012 20:47:38 -0400 Subject: Staging: bcm: Change B_UINT32 to u32 cntrl_SignalingInterface.h This patch changes B_UINT32 to u32 in cntrl_SignalingInterface.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/cntrl_SignalingInterface.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 990e809e968..6f01c151204 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -129,17 +129,17 @@ struct bcm_convergence_types { struct bcm_connect_mgr_params { /* 32bitSFID Of The Service Flow */ - B_UINT32 u32SFID; + u32 u32SFID; /* 32bit Maximum Sustained Traffic Rate of the Service Flow */ - B_UINT32 u32MaxSustainedTrafficRate; + u32 u32MaxSustainedTrafficRate; /* 32bit Maximum Traffic Burst allowed for the Service Flow */ - B_UINT32 u32MaxTrafficBurst; + u32 u32MaxTrafficBurst; /* 32bit Minimum Reserved Traffic Rate of the Service Flow */ - B_UINT32 u32MinReservedTrafficRate; + u32 u32MinReservedTrafficRate; /* 32bit Tolerated Jitter of the Service Flow */ - B_UINT32 u32ToleratedJitter; + u32 u32ToleratedJitter; /* 32bit Maximum Latency of the Service Flow */ - B_UINT32 u32MaximumLatency; + u32 u32MaximumLatency; /* 16bitCID Of The Service Flow */ B_UINT16 u16CID; /* 16bit SAID on which the service flow being set up shall be mapped */ @@ -281,7 +281,7 @@ struct bcm_del_request { B_UINT8 u8Padding; /* < Padding byte */ B_UINT16 u16TID; /* < TID */ /* brief 32bitSFID */ - B_UINT32 u32SFID; /* < SFID */ + u32 u32SFID; /* < SFID */ }; struct bcm_del_indication { @@ -293,14 +293,14 @@ struct bcm_del_indication { /* brief 16bitVCID */ B_UINT16 u16VCID; /* < VCID */ /* brief 32bitSFID */ - B_UINT32 u32SFID; /* < SFID */ + u32 u32SFID; /* < SFID */ /* brief 8bit Confirmation code */ B_UINT8 u8ConfirmationCode; /* < Confirmation code */ B_UINT8 u8Padding1[3]; /* < 3 byte Padding */ }; struct bcm_stim_sfhostnotify { - B_UINT32 SFID; /* SFID of the service flow */ + u32 SFID; /* SFID of the service flow */ B_UINT16 newCID; /* the new/changed CID */ B_UINT16 VCID; /* Get new Vcid if the flow has been made active in CID update TLV, but was inactive earlier or the orig vcid */ B_UINT8 RetainSF; /* Indication to Host if the SF is to be retained or deleted; if TRUE-retain else delete */ -- cgit v1.2.3 From 662e2840c8e46195377873900a6ab80eb979481c Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Sat, 27 Oct 2012 20:47:39 -0400 Subject: Staging: bcm: Change B_UINT16 to u16 in cntrl_SignalingInterface.h This patch changes B_UINT16 to u16 in cntrl_SignalingInterface.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/cntrl_SignalingInterface.h | 66 +++++++++++++------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 6f01c151204..5fa4b66f276 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -36,11 +36,11 @@ struct bcm_packet_class_rules { /* 16bit UserPriority Of The Service Flow */ - B_UINT16 u16UserPriority; + u16 u16UserPriority; /* 16bit VLANID Of The Service Flow */ - B_UINT16 u16VLANID; + u16 u16VLANID; /* 16bit Packet Classification RuleIndex Of The Service Flow */ - B_UINT16 u16PacketClassificationRuleIndex; + u16 u16PacketClassificationRuleIndex; /* 8bit Classifier Rule Priority Of The Service Flow */ B_UINT8 u8ClassifierRulePriority; /* Length of IP TypeOfService field */ @@ -89,7 +89,7 @@ struct bcm_packet_class_rules { B_UINT8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES]; /* Action associated with the classifier rule */ B_UINT8 u8ClassifierActionRule; - B_UINT16 u16ValidityBitMap; + u16 u16ValidityBitMap; }; struct bcm_phs_rules { @@ -141,38 +141,38 @@ struct bcm_connect_mgr_params { /* 32bit Maximum Latency of the Service Flow */ u32 u32MaximumLatency; /* 16bitCID Of The Service Flow */ - B_UINT16 u16CID; + u16 u16CID; /* 16bit SAID on which the service flow being set up shall be mapped */ - B_UINT16 u16TargetSAID; + u16 u16TargetSAID; /* 16bit ARQ window size negotiated */ - B_UINT16 u16ARQWindowSize; + u16 u16ARQWindowSize; /* 16bit Total Tx delay incl sending, receiving & processing delays */ - B_UINT16 u16ARQRetryTxTimeOut; + u16 u16ARQRetryTxTimeOut; /* 16bit Total Rx delay incl sending, receiving & processing delays */ - B_UINT16 u16ARQRetryRxTimeOut; + u16 u16ARQRetryRxTimeOut; /* 16bit ARQ block lifetime */ - B_UINT16 u16ARQBlockLifeTime; + u16 u16ARQBlockLifeTime; /* 16bit ARQ Sync loss timeout */ - B_UINT16 u16ARQSyncLossTimeOut; + u16 u16ARQSyncLossTimeOut; /* 16bit ARQ Purge timeout */ - B_UINT16 u16ARQRxPurgeTimeOut; + u16 u16ARQRxPurgeTimeOut; /* TODO::Remove this once we move to a new CORR2 driver * brief Size of an ARQ block */ - B_UINT16 u16ARQBlockSize; + u16 u16ARQBlockSize; /* #endif */ /* 16bit Nominal interval b/w consecutive SDU arrivals at MAC SAP */ - B_UINT16 u16SDUInterArrivalTime; + u16 u16SDUInterArrivalTime; /* 16bit Specifies the time base for rate measurement */ - B_UINT16 u16TimeBase; + u16 u16TimeBase; /* 16bit Interval b/w Successive Grant oppurtunities */ - B_UINT16 u16UnsolicitedGrantInterval; + u16 u16UnsolicitedGrantInterval; /* 16bit Interval b/w Successive Polling grant oppurtunities */ - B_UINT16 u16UnsolicitedPollingInterval; + u16 u16UnsolicitedPollingInterval; /* internal var to get the overhead */ - B_UINT16 u16MacOverhead; + u16 u16MacOverhead; /* MBS contents Identifier */ - B_UINT16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH]; + u16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH]; /* MBS contents Identifier length */ B_UINT8 u8MBSContentsIDLength; /* ServiceClassName Length Of The Service Flow */ @@ -251,11 +251,11 @@ struct bcm_add_request { B_UINT8 u8Type; /* < Type */ B_UINT8 eConnectionDir; /* < Connection direction */ /* brief 16 bit TID */ - B_UINT16 u16TID; /* < 16bit TID */ + u16 u16TID; /* < 16bit TID */ /* brief 16bitCID */ - B_UINT16 u16CID; /* < 16bit CID */ + u16 u16CID; /* < 16bit CID */ /* brief 16bitVCID */ - B_UINT16 u16VCID; /* < 16bit VCID */ + u16 u16VCID; /* < 16bit VCID */ struct bcm_connect_mgr_params *psfParameterSet; /* < connection manager parameters */ }; @@ -263,23 +263,23 @@ struct bcm_add_indication { B_UINT8 u8Type; /* < Type */ B_UINT8 eConnectionDir; /* < Connection Direction */ /* brief 16 bit TID */ - B_UINT16 u16TID; /* < TID */ + u16 u16TID; /* < TID */ /* brief 16bitCID */ - B_UINT16 u16CID; /* < 16bitCID */ + u16 u16CID; /* < 16bitCID */ /* brief 16bitVCID */ - B_UINT16 u16VCID; /* < 16bitVCID */ + u16 u16VCID; /* < 16bitVCID */ struct bcm_connect_mgr_params *psfAuthorizedSet; /* Authorized set of connection manager parameters */ struct bcm_connect_mgr_params *psfAdmittedSet; /* Admitted set of connection manager parameters */ struct bcm_connect_mgr_params *psfActiveSet; /* Activeset of connection manager parameters */ B_UINT8 u8CC; /* Date: Sat, 27 Oct 2012 20:47:40 -0400 Subject: Staging: bcm: Change B_UINT8 to u8 in cntrl_SignalingInterface.h This patch changes B_UINT8 to u8 in cntrl_SignalingInterface.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/cntrl_SignalingInterface.h | 172 ++++++++++++------------- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 5fa4b66f276..8683c2d4276 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -42,85 +42,85 @@ struct bcm_packet_class_rules { /* 16bit Packet Classification RuleIndex Of The Service Flow */ u16 u16PacketClassificationRuleIndex; /* 8bit Classifier Rule Priority Of The Service Flow */ - B_UINT8 u8ClassifierRulePriority; + u8 u8ClassifierRulePriority; /* Length of IP TypeOfService field */ - B_UINT8 u8IPTypeOfServiceLength; + u8 u8IPTypeOfServiceLength; /* 3bytes IP TypeOfService */ - B_UINT8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH]; + u8 u8IPTypeOfService[TYPE_OF_SERVICE_LENGTH]; /* Protocol used in classification of Service Flow */ - B_UINT8 u8Protocol; + u8 u8Protocol; /* Length of IP Masked Source Address */ - B_UINT8 u8IPMaskedSourceAddressLength; + u8 u8IPMaskedSourceAddressLength; /* IP Masked Source Address used in classification for the Service Flow */ - B_UINT8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH]; + u8 u8IPMaskedSourceAddress[IP_MASKED_SRC_ADDRESS_LENGTH]; /* Length of IP Destination Address */ - B_UINT8 u8IPDestinationAddressLength; + u8 u8IPDestinationAddressLength; /* IP Destination Address used in classification for the Service Flow */ - B_UINT8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH]; + u8 u8IPDestinationAddress[IP_MASKED_DEST_ADDRESS_LENGTH]; /* Length of Protocol Source Port Range */ - B_UINT8 u8ProtocolSourcePortRangeLength; + u8 u8ProtocolSourcePortRangeLength; /* Protocol Source Port Range used in the Service Flow */ - B_UINT8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH]; + u8 u8ProtocolSourcePortRange[PROTOCOL_SRC_PORT_RANGE_LENGTH]; /* Length of Protocol Dest Port Range */ - B_UINT8 u8ProtocolDestPortRangeLength; + u8 u8ProtocolDestPortRangeLength; /* Protocol Dest Port Range used in the Service Flow */ - B_UINT8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH]; + u8 u8ProtocolDestPortRange[PROTOCOL_DEST_PORT_RANGE_LENGTH]; /* Length of Ethernet Destination MAC Address */ - B_UINT8 u8EthernetDestMacAddressLength; + u8 u8EthernetDestMacAddressLength; /* Ethernet Destination MAC Address used in classification of the Service Flow */ - B_UINT8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH]; + u8 u8EthernetDestMacAddress[ETHERNET_DEST_MAC_ADDR_LENGTH]; /* Length of Ethernet Source MAC Address */ - B_UINT8 u8EthernetSourceMACAddressLength; + u8 u8EthernetSourceMACAddressLength; /* Ethernet Source MAC Address used in classification of the Service Flow */ - B_UINT8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH]; + u8 u8EthernetSourceMACAddress[ETHERNET_SRC_MAC_ADDR_LENGTH]; /* Length of Ethertype */ - B_UINT8 u8EthertypeLength; + u8 u8EthertypeLength; /* 3bytes Ethertype Of The Service Flow */ - B_UINT8 u8Ethertype[NUM_ETHERTYPE_BYTES]; + u8 u8Ethertype[NUM_ETHERTYPE_BYTES]; /* 8bit Associated PHSI Of The Service Flow */ - B_UINT8 u8AssociatedPHSI; + u8 u8AssociatedPHSI; /* Length of Vendor Specific Classifier Param length Of The Service Flow */ - B_UINT8 u8VendorSpecificClassifierParamLength; + u8 u8VendorSpecificClassifierParamLength; /* Vendor Specific Classifier Param Of The Service Flow */ - B_UINT8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH]; + u8 u8VendorSpecificClassifierParam[VENDOR_CLASSIFIER_PARAM_LENGTH]; /* Length Of IPv6 Flow Lable of the Service Flow */ - B_UINT8 u8IPv6FlowLableLength; + u8 u8IPv6FlowLableLength; /* IPv6 Flow Lable Of The Service Flow */ - B_UINT8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES]; + u8 u8IPv6FlowLable[NUM_IPV6_FLOWLABLE_BYTES]; /* Action associated with the classifier rule */ - B_UINT8 u8ClassifierActionRule; + u8 u8ClassifierActionRule; u16 u16ValidityBitMap; }; struct bcm_phs_rules { /* 8bit PHS Index Of The Service Flow */ - B_UINT8 u8PHSI; + u8 u8PHSI; /* PHSF Length Of The Service Flow */ - B_UINT8 u8PHSFLength; + u8 u8PHSFLength; /* String of bytes containing header information to be suppressed by the sending CS and reconstructed by the receiving CS */ - B_UINT8 u8PHSF[MAX_PHS_LENGTHS]; + u8 u8PHSF[MAX_PHS_LENGTHS]; /* PHSM Length Of The Service Flow */ - B_UINT8 u8PHSMLength; + u8 u8PHSMLength; /* PHS Mask for the SF */ - B_UINT8 u8PHSM[MAX_PHS_LENGTHS]; + u8 u8PHSM[MAX_PHS_LENGTHS]; /* 8bit Total number of bytes to be suppressed for the Service Flow */ - B_UINT8 u8PHSS; + u8 u8PHSS; /* 8bit Indicates whether or not Packet Header contents need to be verified prior to suppression */ - B_UINT8 u8PHSV; + u8 u8PHSV; /* Vendor Specific PHS param Length Of The Service Flow */ - B_UINT8 u8VendorSpecificPHSParamsLength; + u8 u8VendorSpecificPHSParamsLength; /* Vendor Specific PHS param Of The Service Flow */ - B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH]; - B_UINT8 u8Padding[2]; + u8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH]; + u8 u8Padding[2]; }; struct bcm_convergence_types { /* 8bit Phs Classfier Action Of The Service Flow */ - B_UINT8 u8ClassfierDSCAction; + u8 u8ClassfierDSCAction; /* 8bit Phs DSC Action Of The Service Flow */ - B_UINT8 u8PhsDSCAction; + u8 u8PhsDSCAction; /* 16bit Padding */ - B_UINT8 u8Padding[2]; + u8 u8Padding[2]; /* Packet classification rules structure */ struct bcm_packet_class_rules cCPacketClassificationRule; /* Payload header suppression rules structure */ @@ -174,73 +174,73 @@ struct bcm_connect_mgr_params { /* MBS contents Identifier */ u16 u16MBSContentsID[MBS_CONTENTS_ID_LENGTH]; /* MBS contents Identifier length */ - B_UINT8 u8MBSContentsIDLength; + u8 u8MBSContentsIDLength; /* ServiceClassName Length Of The Service Flow */ - B_UINT8 u8ServiceClassNameLength; + u8 u8ServiceClassNameLength; /* 32bytes ServiceClassName Of The Service Flow */ - B_UINT8 u8ServiceClassName[32]; + u8 u8ServiceClassName[32]; /* 8bit Indicates whether or not MBS service is requested for this Serivce Flow */ - B_UINT8 u8MBSService; + u8 u8MBSService; /* 8bit QOS Parameter Set specifies proper application of QoS parameters to Provisioned, Admitted and Active sets */ - B_UINT8 u8QosParamSet; + u8 u8QosParamSet; /* 8bit Traffic Priority Of the Service Flow */ - B_UINT8 u8TrafficPriority; + u8 u8TrafficPriority; /* 8bit Uplink Grant Scheduling Type of The Service Flow */ - B_UINT8 u8ServiceFlowSchedulingType; + u8 u8ServiceFlowSchedulingType; /* 8bit Request transmission Policy of the Service Flow */ - B_UINT8 u8RequesttransmissionPolicy; + u8 u8RequesttransmissionPolicy; /* 8bit Specifies whether SDUs for this Service flow are of FixedLength or Variable length */ - B_UINT8 u8FixedLengthVSVariableLengthSDUIndicator; + u8 u8FixedLengthVSVariableLengthSDUIndicator; /* 8bit Length of the SDU for a fixed length SDU service flow */ - B_UINT8 u8SDUSize; + u8 u8SDUSize; /* 8bit Indicates whether or not ARQ is requested for this connection */ - B_UINT8 u8ARQEnable; + u8 u8ARQEnable; /* < 8bit Indicates whether or not data has tobe delivered in order to higher layer */ - B_UINT8 u8ARQDeliverInOrder; + u8 u8ARQDeliverInOrder; /* 8bit Receiver ARQ ACK processing time */ - B_UINT8 u8RxARQAckProcessingTime; + u8 u8RxARQAckProcessingTime; /* 8bit Convergence Sublayer Specification Of The Service Flow */ - B_UINT8 u8CSSpecification; + u8 u8CSSpecification; /* 8 bit Type of data delivery service */ - B_UINT8 u8TypeOfDataDeliveryService; + u8 u8TypeOfDataDeliveryService; /* 8bit Specifies whether a service flow may generate Paging */ - B_UINT8 u8PagingPreference; + u8 u8PagingPreference; /* 8bit Indicates the MBS Zone through which the connection or virtual connection is valid */ - B_UINT8 u8MBSZoneIdentifierassignment; + u8 u8MBSZoneIdentifierassignment; /* 8bit Specifies whether traffic on SF should generate MOB_TRF_IND to MS in sleep mode */ - B_UINT8 u8TrafficIndicationPreference; + u8 u8TrafficIndicationPreference; /* 8bit Speciifes the length of predefined Global QoS parameter set encoding for this SF */ - B_UINT8 u8GlobalServicesClassNameLength; + u8 u8GlobalServicesClassNameLength; /* 6 byte Speciifes the predefined Global QoS parameter set encoding for this SF */ - B_UINT8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH]; + u8 u8GlobalServicesClassName[GLOBAL_SF_CLASSNAME_LENGTH]; /* 8bit Indicates whether or not SN feedback is enabled for the conn */ - B_UINT8 u8SNFeedbackEnabled; + u8 u8SNFeedbackEnabled; /* Indicates the size of the Fragment Sequence Number for the connection */ - B_UINT8 u8FSNSize; + u8 u8FSNSize; /* 8bit Number of CIDs in active BS list */ - B_UINT8 u8CIDAllocation4activeBSsLength; + u8 u8CIDAllocation4activeBSsLength; /* CIDs of BS in the active list */ - B_UINT8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS]; + u8 u8CIDAllocation4activeBSs[MAX_NUM_ACTIVE_BS]; /* Specifies if PDU extended subheader should be applied on every PDU on this conn */ - B_UINT8 u8PDUSNExtendedSubheader4HarqReordering; + u8 u8PDUSNExtendedSubheader4HarqReordering; /* 8bit Specifies whether the connection uses HARQ or not */ - B_UINT8 u8HARQServiceFlows; + u8 u8HARQServiceFlows; /* Specifies the length of Authorization token */ - B_UINT8 u8AuthTokenLength; + u8 u8AuthTokenLength; /* Specifies the Authorization token */ - B_UINT8 u8AuthToken[AUTH_TOKEN_LENGTH]; + u8 u8AuthToken[AUTH_TOKEN_LENGTH]; /* specifes Number of HARQ channels used to carry data length */ - B_UINT8 u8HarqChannelMappingLength; + u8 u8HarqChannelMappingLength; /* specifes HARQ channels used to carry data */ - B_UINT8 u8HARQChannelMapping[NUM_HARQ_CHANNELS]; + u8 u8HARQChannelMapping[NUM_HARQ_CHANNELS]; /* 8bit Length of Vendor Specific QoS Params */ - B_UINT8 u8VendorSpecificQoSParamLength; + u8 u8VendorSpecificQoSParamLength; /* 1byte Vendor Specific QoS Param Of The Service Flow */ - B_UINT8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM]; + u8 u8VendorSpecificQoSParam[VENDOR_SPECIF_QOS_PARAM]; /* indicates total classifiers in the SF */ - B_UINT8 u8TotalClassifiers; /* < Total number of valid classifiers */ - B_UINT8 bValid; /* < Validity flag */ - B_UINT8 u8Padding; /* < Padding byte */ + u8 u8TotalClassifiers; /* < Total number of valid classifiers */ + u8 bValid; /* < Validity flag */ + u8 u8Padding; /* < Padding byte */ /* * Structure for Convergence SubLayer Types with a maximum of 4 classifiers */ @@ -248,8 +248,8 @@ struct bcm_connect_mgr_params { }; struct bcm_add_request { - B_UINT8 u8Type; /* < Type */ - B_UINT8 eConnectionDir; /* < Connection direction */ + u8 u8Type; /* < Type */ + u8 eConnectionDir; /* < Connection direction */ /* brief 16 bit TID */ u16 u16TID; /* < 16bit TID */ /* brief 16bitCID */ @@ -260,8 +260,8 @@ struct bcm_add_request { }; struct bcm_add_indication { - B_UINT8 u8Type; /* < Type */ - B_UINT8 eConnectionDir; /* < Connection Direction */ + u8 u8Type; /* < Type */ + u8 eConnectionDir; /* < Connection Direction */ /* brief 16 bit TID */ u16 u16TID; /* < TID */ /* brief 16bitCID */ @@ -271,22 +271,22 @@ struct bcm_add_indication { struct bcm_connect_mgr_params *psfAuthorizedSet; /* Authorized set of connection manager parameters */ struct bcm_connect_mgr_params *psfAdmittedSet; /* Admitted set of connection manager parameters */ struct bcm_connect_mgr_params *psfActiveSet; /* Activeset of connection manager parameters */ - B_UINT8 u8CC; /* Date: Mon, 29 Oct 2012 22:02:13 -0600 Subject: ARM: OMAP2+: clockdomain: Fix OMAP4 ISS clk domain to support only SWSUP Since CAM domain (ISS) has no module wake-up dependency with any other clock domain of the device and the dynamic dependency from L3_main_2 is always disabled, the domain needs to be in force wakeup in order to be able to access it for configure (sysconfig) it or use it. Also since there is no clock in the domain managed automatically by the hardware, there is no use to configure automatic clock domain transition. SW should keep the SW_WKUP domain transition as long as a module in the domain is required to be functional. Signed-off-by: Miguel Vadillo Signed-off-by: Benoit Cousson --- arch/arm/mach-omap2/clockdomains44xx_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index b56d06b4878..95192a062d5 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -359,7 +359,7 @@ static struct clockdomain iss_44xx_clkdm = { .clkdm_offs = OMAP4430_CM2_CAM_CAM_CDOFFS, .wkdep_srcs = iss_wkup_sleep_deps, .sleepdep_srcs = iss_wkup_sleep_deps, - .flags = CLKDM_CAN_HWSUP_SWSUP, + .flags = CLKDM_CAN_SWSUP, }; static struct clockdomain l3_dss_44xx_clkdm = { -- cgit v1.2.3 From 613ad0e98c3596cd2524172fae2a795c3fc57e4a Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Mon, 29 Oct 2012 22:02:13 -0600 Subject: ARM: OMAP: hwmod: wait for sysreset complete after enabling hwmod When waking up from off-mode, some IP blocks are reset automatically by hardware. For this reason, software must wait until the reset has completed before attempting to access the IP block. This patch fixes for example the bug introduced by commit 6c31b2150ff96755d24e0ab6d6fea08a7bf5c44c ("mmc: omap_hsmmc: remove access to SYSCONFIG register"), in which the MMC IP block is reset during off-mode entry, but the code expects the module to be already available during the execution of context restore. This version includes a fix from Kevin Hilman for GPIO problems on the 37xx EVM - thanks Kevin. Signed-off-by: Tero Kristo Cc: Paul Walmsley Cc: Benoit Cousson Cc: Venkatraman S Tested-by: Kevin Hilman Cc: Kevin Hilman [paul@pwsan.com: moved softreset wait code into separate function; call from top of _enable_sysc() rather than the bottom; include fix from Kevin Hilman for GPIO sluggishness] Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 60 ++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index b969ab1d258..70267d2cf5e 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -421,6 +421,38 @@ static int _set_softreset(struct omap_hwmod *oh, u32 *v) return 0; } +/** + * _wait_softreset_complete - wait for an OCP softreset to complete + * @oh: struct omap_hwmod * to wait on + * + * Wait until the IP block represented by @oh reports that its OCP + * softreset is complete. This can be triggered by software (see + * _ocp_softreset()) or by hardware upon returning from off-mode (one + * example is HSMMC). Waits for up to MAX_MODULE_SOFTRESET_WAIT + * microseconds. Returns the number of microseconds waited. + */ +static int _wait_softreset_complete(struct omap_hwmod *oh) +{ + struct omap_hwmod_class_sysconfig *sysc; + u32 softrst_mask; + int c = 0; + + sysc = oh->class->sysc; + + if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS) + omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + else if (sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { + softrst_mask = (0x1 << sysc->sysc_fields->srst_shift); + omap_test_timeout(!(omap_hwmod_read(oh, sysc->sysc_offs) + & softrst_mask), + MAX_MODULE_SOFTRESET_WAIT, c); + } + + return c; +} + /** * _set_dmadisable: set OCP_SYSCONFIG.DMADISABLE bit in @v * @oh: struct omap_hwmod * @@ -1282,6 +1314,18 @@ static void _enable_sysc(struct omap_hwmod *oh) if (!oh->class->sysc) return; + /* + * Wait until reset has completed, this is needed as the IP + * block is reset automatically by hardware in some cases + * (off-mode for example), and the drivers require the + * IP to be ready when they access it + */ + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) + _enable_optional_clocks(oh); + _wait_softreset_complete(oh); + if (oh->flags & HWMOD_CONTROL_OPT_CLKS_IN_RESET) + _disable_optional_clocks(oh); + v = oh->_sysc_cache; sf = oh->class->sysc->sysc_flags; @@ -1804,7 +1848,7 @@ static int _am33xx_disable_module(struct omap_hwmod *oh) */ static int _ocp_softreset(struct omap_hwmod *oh) { - u32 v, softrst_mask; + u32 v; int c = 0; int ret = 0; @@ -1834,19 +1878,7 @@ static int _ocp_softreset(struct omap_hwmod *oh) if (oh->class->sysc->srst_udelay) udelay(oh->class->sysc->srst_udelay); - if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) - omap_test_timeout((omap_hwmod_read(oh, - oh->class->sysc->syss_offs) - & SYSS_RESETDONE_MASK), - MAX_MODULE_SOFTRESET_WAIT, c); - else if (oh->class->sysc->sysc_flags & SYSC_HAS_RESET_STATUS) { - softrst_mask = (0x1 << oh->class->sysc->sysc_fields->srst_shift); - omap_test_timeout(!(omap_hwmod_read(oh, - oh->class->sysc->sysc_offs) - & softrst_mask), - MAX_MODULE_SOFTRESET_WAIT, c); - } - + c = _wait_softreset_complete(oh); if (c == MAX_MODULE_SOFTRESET_WAIT) pr_warning("omap_hwmod: %s: softreset failed (waited %d usec)\n", oh->name, MAX_MODULE_SOFTRESET_WAIT); -- cgit v1.2.3 From e6d41e8c697e07832efa4a85bf23438bc4c4e1b2 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 29 Oct 2012 18:40:08 +0100 Subject: x86, AMD: Change Boris' email address Move to private email and put in maintained status. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1351532410-4887-1-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/mcheck/mce_amd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 698b6ec12e0..1ac581f38df 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c @@ -6,7 +6,7 @@ * * Written by Jacob Shin - AMD, Inc. * - * Support: borislav.petkov@amd.com + * Maintained by: Borislav Petkov * * April 2006 * - added support for AMD Family 0x10 processors -- cgit v1.2.3 From 43aff26ce1684dae4bf75437b2733371106aa767 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 29 Oct 2012 18:40:09 +0100 Subject: EDAC: Change Boris' email address My @amd.com address will be invalid soon so move to private email address. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1351532410-4887-2-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- drivers/edac/amd64_edac.h | 2 +- drivers/edac/edac_stub.c | 2 +- drivers/edac/mce_amd_inj.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index 8d4804732ba..8c4139647ef 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h @@ -33,7 +33,7 @@ * detection. The mods to Rev F required more family * information detection. * - * Changes/Fixes by Borislav Petkov : + * Changes/Fixes by Borislav Petkov : * - misc fixes and code cleanups * * This module is based on the following documents diff --git a/drivers/edac/edac_stub.c b/drivers/edac/edac_stub.c index 6c86f6e5455..351945fa2ec 100644 --- a/drivers/edac/edac_stub.c +++ b/drivers/edac/edac_stub.c @@ -5,7 +5,7 @@ * * 2007 (c) MontaVista Software, Inc. * 2010 (c) Advanced Micro Devices Inc. - * Borislav Petkov + * Borislav Petkov * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/edac/mce_amd_inj.c b/drivers/edac/mce_amd_inj.c index 66b5151c108..2ae78f20cc2 100644 --- a/drivers/edac/mce_amd_inj.c +++ b/drivers/edac/mce_amd_inj.c @@ -6,7 +6,7 @@ * This file may be distributed under the terms of the GNU General Public * License version 2. * - * Copyright (c) 2010: Borislav Petkov + * Copyright (c) 2010: Borislav Petkov * Advanced Micro Devices Inc. */ @@ -168,6 +168,6 @@ module_init(edac_init_mce_inject); module_exit(edac_exit_mce_inject); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Borislav Petkov "); +MODULE_AUTHOR("Borislav Petkov "); MODULE_AUTHOR("AMD Inc."); MODULE_DESCRIPTION("MCE injection facility for testing MCE decoding"); -- cgit v1.2.3 From 487ba8e82ab98320e5d7c0f6ff6da3067505ff92 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 29 Oct 2012 18:40:10 +0100 Subject: MAINTAINERS: Change Boris' email address Move to private mail address. Signed-off-by: Borislav Petkov Link: http://lkml.kernel.org/r/1351532410-4887-3-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar --- MAINTAINERS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1fa907441f8..e775b874920 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2707,10 +2707,10 @@ F: include/linux/edac.h EDAC-AMD64 M: Doug Thompson -M: Borislav Petkov +M: Borislav Petkov L: linux-edac@vger.kernel.org W: bluesmoke.sourceforge.net -S: Supported +S: Maintained F: drivers/edac/amd64_edac* EDAC-E752X @@ -3703,7 +3703,7 @@ S: Maintained F: drivers/platform/x86/ideapad-laptop.c IDE/ATAPI DRIVERS -M: Borislav Petkov +M: Borislav Petkov L: linux-ide@vger.kernel.org S: Maintained F: Documentation/cdrom/ide-cd @@ -8147,7 +8147,7 @@ F: drivers/platform/x86 X86 MCE INFRASTRUCTURE M: Tony Luck -M: Borislav Petkov +M: Borislav Petkov L: linux-edac@vger.kernel.org S: Maintained F: arch/x86/kernel/cpu/mcheck/* -- cgit v1.2.3 From 943482d07e926128eed0482b879736f912c429e4 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 29 Oct 2012 18:51:38 +0100 Subject: x86, microcode_amd: Change email addresses, MAINTAINERS entry Signed-off-by: Andreas Herrmann Cc: lm-sensors@lm-sensors.org Cc: oprofile-list@lists.sf.net Cc: Stephane Eranian Cc: Robert Richter Cc: Borislav Petkov Cc: Jorg Roedel Cc: Rafael J. Wysocki Cc: Jean Delvare Cc: Guenter Roeck Link: http://lkml.kernel.org/r/20121029175138.GC5024@tweety Signed-off-by: Ingo Molnar --- MAINTAINERS | 4 ++-- arch/x86/kernel/microcode_amd.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index e775b874920..17403702f56 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -534,9 +534,9 @@ F: drivers/iommu/amd_iommu*.[ch] F: include/linux/amd-iommu.h AMD MICROCODE UPDATE SUPPORT -M: Andreas Herrmann +M: Andreas Herrmann L: amd64-microcode@amd64.org -S: Supported +S: Maintained F: arch/x86/kernel/microcode_amd.c AMS (Apple Motion Sensor) DRIVER diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index 7720ff5a9ee..b3e67ba55b7 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c @@ -8,8 +8,8 @@ * Tigran Aivazian * * Maintainers: - * Andreas Herrmann - * Borislav Petkov + * Andreas Herrmann + * Borislav Petkov * * This driver allows to upgrade microcode on F10h AMD * CPUs and later. -- cgit v1.2.3 From 4cf7e71869268d5c9fa7e8005155aef94e140eb5 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 29 Oct 2012 18:53:25 +0100 Subject: MAINTAINERS: Update email address for Robert Richter Signed-off-by: Robert Richter Signed-off-by: Andreas Herrmann Cc: lm-sensors@lm-sensors.org Cc: oprofile-list@lists.sf.net Cc: Stephane Eranian Cc: Borislav Petkov Cc: =?iso-8859-1?Q?J=F6rg_R=F6del?= Cc: Rafael J. Wysocki Cc: Jean Delvare Cc: Guenter Roeck Link: http://lkml.kernel.org/r/20121029175325.GE5024@tweety Signed-off-by: Ingo Molnar --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 17403702f56..a41344b77b3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5363,7 +5363,7 @@ S: Maintained F: sound/drivers/opl4/ OPROFILE -M: Robert Richter +M: Robert Richter L: oprofile-list@lists.sf.net S: Maintained F: arch/*/include/asm/oprofile*.h -- cgit v1.2.3 From 0d855354ea351bec6b222e9fea86a876cfafdcb6 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Fri, 26 Oct 2012 18:28:56 +0200 Subject: perf, powerpc: Fix hw breakpoints returning -ENOSPC I've been trying to get hardware breakpoints with perf to work on POWER7 but I'm getting the following: % perf record -e mem:0x10000000 true Error: sys_perf_event_open() syscall returned with 28 (No space left on device). /bin/dmesg may provide additional information. Fatal: No CONFIG_PERF_EVENTS=y kernel support configured? true: Terminated (FWIW adding -a and it works fine) Debugging it seems that __reserve_bp_slot() is returning ENOSPC because it thinks there are no free breakpoint slots on this CPU. I have a 2 CPUs, so perf userspace is doing two perf_event_open syscalls to add a counter to each CPU [1]. The first syscall succeeds but the second is failing. On this second syscall, fetch_bp_busy_slots() sets slots.pinned to be 1, despite there being no breakpoint on this CPU. This is because the call the task_bp_pinned, checks all CPUs, rather than just the current CPU. POWER7 only has one hardware breakpoint per CPU (ie. HBP_NUM=1), so we return ENOSPC. The following patch fixes this by checking the associated CPU for each breakpoint in task_bp_pinned. I'm not familiar with this code, so it's provided as a reference to the above issue. Signed-off-by: Michael Neuling Acked-by: Peter Zijlstra Cc: Michael Ellerman Cc: Jovi Zhang Cc: K Prasad Link: http://lkml.kernel.org/r/1351268936-2956-1-git-send-email-fweisbec@gmail.com Signed-off-by: Ingo Molnar --- kernel/events/hw_breakpoint.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index 9a7b487c6fe..fe8a916507e 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c @@ -111,14 +111,16 @@ static unsigned int max_task_bp_pinned(int cpu, enum bp_type_idx type) * Count the number of breakpoints of the same type and same task. * The given event must be not on the list. */ -static int task_bp_pinned(struct perf_event *bp, enum bp_type_idx type) +static int task_bp_pinned(int cpu, struct perf_event *bp, enum bp_type_idx type) { struct task_struct *tsk = bp->hw.bp_target; struct perf_event *iter; int count = 0; list_for_each_entry(iter, &bp_task_head, hw.bp_list) { - if (iter->hw.bp_target == tsk && find_slot_idx(iter) == type) + if (iter->hw.bp_target == tsk && + find_slot_idx(iter) == type && + cpu == iter->cpu) count += hw_breakpoint_weight(iter); } @@ -141,7 +143,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, if (!tsk) slots->pinned += max_task_bp_pinned(cpu, type); else - slots->pinned += task_bp_pinned(bp, type); + slots->pinned += task_bp_pinned(cpu, bp, type); slots->flexible = per_cpu(nr_bp_flexible[type], cpu); return; @@ -154,7 +156,7 @@ fetch_bp_busy_slots(struct bp_busy_slots *slots, struct perf_event *bp, if (!tsk) nr += max_task_bp_pinned(cpu, type); else - nr += task_bp_pinned(bp, type); + nr += task_bp_pinned(cpu, bp, type); if (nr > slots->pinned) slots->pinned = nr; @@ -188,7 +190,7 @@ static void toggle_bp_task_slot(struct perf_event *bp, int cpu, bool enable, int old_idx = 0; int idx = 0; - old_count = task_bp_pinned(bp, type); + old_count = task_bp_pinned(cpu, bp, type); old_idx = old_count - 1; idx = old_idx + weight; -- cgit v1.2.3 From 95d18aa2b6c05351181934b3bc34ce038cc7b637 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Mon, 29 Oct 2012 21:48:17 +0100 Subject: perf/x86: Fix sparse warnings FYI, there are new sparse warnings: arch/x86/kernel/cpu/perf_event.c:1356:18: sparse: symbol 'events_attr' was not declared. Should it be static? This patch makes it static and also adds the static keyword to fix arch/x86/kernel/cpu/perf_event.c:1344:9: warning: symbol 'events_sysfs_show' was not declared. Signed-off-by: Peter Huewe Cc: Peter Zijlstra Cc: Yuanhan Liu Cc: fengguang.wu@intel.com Cc: Jiri Olsa Link: http://lkml.kernel.org/n/tip-lerdpXlnruh0yvWs2owwuizl@git.kernel.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 0a55ab2ff84..4428fd178bc 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -1341,7 +1341,7 @@ static void __init filter_events(struct attribute **attrs) } } -ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, +static ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, char *page) { struct perf_pmu_events_attr *pmu_attr = \ @@ -1373,7 +1373,7 @@ EVENT_ATTR(ref-cycles, REF_CPU_CYCLES ); static struct attribute *empty_attrs; -struct attribute *events_attr[] = { +static struct attribute *events_attr[] = { EVENT_PTR(CPU_CYCLES), EVENT_PTR(INSTRUCTIONS), EVENT_PTR(CACHE_REFERENCES), -- cgit v1.2.3 From f49f4ab95c301dbccad0efe85296d908b8ae7ad4 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 29 Oct 2012 14:40:18 +0100 Subject: x86/ce4100: Fix pm_poweroff The CE4100 platform is currently missing a proper pm_poweroff implementation leading to poweroff making the CPU spin forever and the CE4100 platform does not enter a low-power mode where the external Power Management Unit can properly power off the system. Power off on this platform is implemented pretty much like reboot, by writing to the SoC built-in 8051 microcontroller mapped at I/O port 0xcf9, the value 0x4. Signed-off-by: Florian Fainelli Acked-by: Sebastian Andrzej Siewior Cc: rui.zhang@intel.com Cc: alan@linux.intel.com Link: http://lkml.kernel.org/r/1351518020-25556-2-git-send-email-ffainelli@freebox.fr Signed-off-by: Ingo Molnar --- arch/x86/platform/ce4100/ce4100.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c index 4c61b52191e..5de16e359fe 100644 --- a/arch/x86/platform/ce4100/ce4100.c +++ b/arch/x86/platform/ce4100/ce4100.c @@ -27,6 +27,18 @@ static int ce4100_i8042_detect(void) return 0; } +/* + * The CE4100 platform has an internal 8051 Microcontroller which is + * responsible for signaling to the external Power Management Unit the + * intention to reset, reboot or power off the system. This 8051 device has + * its command register mapped at I/O port 0xcf9 and the value 0x4 is used + * to power off the system. + */ +static void ce4100_power_off(void) +{ + outb(0x4, 0xcf9); +} + #ifdef CONFIG_SERIAL_8250 static unsigned int mem_serial_in(struct uart_port *p, int offset) @@ -143,4 +155,6 @@ void __init x86_ce4100_early_setup(void) x86_init.pci.init_irq = sdv_pci_init; x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck; #endif + + pm_power_off = ce4100_power_off; } -- cgit v1.2.3 From d7959916026aaae60e1878ae33c7503b2cc4471d Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Mon, 29 Oct 2012 14:40:19 +0100 Subject: x86/ce4100: Fix reboot by forcing the reboot method to be KBD The default reboot is via ACPI for this platform, and the CEFDK bootloader actually supports this, but will issue a system power off instead of a real reboot. Setting the reboot method to be KBD instead of ACPI ensures proper system reboot. Acked-by: Sebastian Andrzej Siewior Signed-off-by: Maxime Bizon Signed-off-by: Florian Fainelli Cc: rui.zhang@intel.com Cc: alan@linux.intel.com Link: http://lkml.kernel.org/r/1351518020-25556-3-git-send-email-ffainelli@freebox.fr Signed-off-by: Ingo Molnar --- arch/x86/platform/ce4100/ce4100.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c index 5de16e359fe..92525cb8e54 100644 --- a/arch/x86/platform/ce4100/ce4100.c +++ b/arch/x86/platform/ce4100/ce4100.c @@ -21,6 +21,7 @@ #include #include #include +#include static int ce4100_i8042_detect(void) { @@ -151,6 +152,15 @@ void __init x86_ce4100_early_setup(void) x86_init.mpparse.find_smp_config = x86_init_noop; x86_init.pci.init = ce4100_pci_init; + /* + * By default, the reboot method is ACPI which is supported by the + * CE4100 bootloader CEFDK using FADT.ResetReg Address and ResetValue + * the bootloader will however issue a system power off instead of + * reboot. By using BOOT_KBD we ensure proper system reboot as + * expected. + */ + reboot_type = BOOT_KBD; + #ifdef CONFIG_X86_IO_APIC x86_init.pci.init_irq = sdv_pci_init; x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck; -- cgit v1.2.3 From 37aeec36220c39f1b2e7118287d951fd9cfdd6b7 Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Mon, 29 Oct 2012 14:40:20 +0100 Subject: x86/ce4100: Fix PCI configuration register access for devices without interrupts Some CE4100 devices such as the: - DFX module (01:0b.7) - entertainment encryption device (01:10.0) - multimedia controller (01:12.0) do not have a device interrupt at all. This patch fixes the PCI controller code to declare the missing PCI configuration register space, as well as a fixup method for forcing the interrupt pin to be 0 for these devices. This is required to ensure that pci drivers matching on these devices will be able to honor the various PCI subsystem calls touching the configuration space. Signed-off-by: Maxime Bizon Signed-off-by: Florian Fainelli Acked-by: Sebastian Andrzej Siewior Cc: rui.zhang@intel.com Cc: alan@linux.intel.com Link: http://lkml.kernel.org/r/1351518020-25556-4-git-send-email-ffainelli@freebox.fr Signed-off-by: Ingo Molnar --- arch/x86/pci/ce4100.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/x86/pci/ce4100.c b/arch/x86/pci/ce4100.c index 41bd2a2d2c5..b914e20b5a0 100644 --- a/arch/x86/pci/ce4100.c +++ b/arch/x86/pci/ce4100.c @@ -115,6 +115,16 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value) reg_read(reg, value); } +static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value) +{ + unsigned long flags; + + raw_spin_lock_irqsave(&pci_config_lock, flags); + /* force interrupt pin value to 0 */ + *value = reg->sim_reg.value & 0xfff00ff; + raw_spin_unlock_irqrestore(&pci_config_lock, flags); +} + static struct sim_dev_reg bus1_fixups[] = { DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write) DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write) @@ -144,6 +154,7 @@ static struct sim_dev_reg bus1_fixups[] = { DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write) DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write) DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write) + DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write) DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write) DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write) @@ -161,8 +172,10 @@ static struct sim_dev_reg bus1_fixups[] = { DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write) DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write) DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write) + DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write) DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write) DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write) + DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write) }; static void __init init_sim_regs(void) -- cgit v1.2.3 From 5258f386ea4e8454bc801fb443e8a4217da1947c Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Sun, 28 Oct 2012 12:19:23 -0700 Subject: sched/autogroup: Fix crash on reboot when autogroup is disabled Due to these two commits: 8323f26ce342 sched: Fix race in task_group() 800d4d30c8f2 sched, autogroup: Stop going ahead if autogroup is disabled ... autogroup scheduling's dynamic knobs are wrecked. With both patches applied, all you have to do to crash a box is disable autogroup during boot up, then reboot.. boom, NULL pointer dereference due to 800d4d30 not allowing autogroup to move things, and 8323f26ce making that the only way to switch runqueues. Remove most of the (dysfunctional) knobs and turn the remaining sched_autogroup_enabled knob readonly. If the user fiddles with cgroups hereafter, once tasks are moved, autogroup won't mess with them again unless they call setsid(). No knobs, no glitz, nada, just a cute little thing folks can turn on if they don't want to muck about with cgroups and/or systemd. Signed-off-by: Mike Galbraith Cc: Xiaotian Feng Cc: Peter Zijlstra Cc: Xiaotian Feng Cc: Linus Torvalds Cc: Andrew Morton Cc: Oleg Nesterov Cc: # v3.6 Link: http://lkml.kernel.org/r/1351451963.4999.8.camel@maggy.simpson.net Signed-off-by: Ingo Molnar --- fs/proc/base.c | 78 ----------------------------------------------- kernel/sched/auto_group.c | 68 +++++++---------------------------------- kernel/sched/auto_group.h | 9 +----- kernel/sysctl.c | 6 ++-- 4 files changed, 14 insertions(+), 147 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 1b6c84cbdb7..bb1d9623bad 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1271,81 +1271,6 @@ static const struct file_operations proc_pid_sched_operations = { #endif -#ifdef CONFIG_SCHED_AUTOGROUP -/* - * Print out autogroup related information: - */ -static int sched_autogroup_show(struct seq_file *m, void *v) -{ - struct inode *inode = m->private; - struct task_struct *p; - - p = get_proc_task(inode); - if (!p) - return -ESRCH; - proc_sched_autogroup_show_task(p, m); - - put_task_struct(p); - - return 0; -} - -static ssize_t -sched_autogroup_write(struct file *file, const char __user *buf, - size_t count, loff_t *offset) -{ - struct inode *inode = file->f_path.dentry->d_inode; - struct task_struct *p; - char buffer[PROC_NUMBUF]; - int nice; - int err; - - memset(buffer, 0, sizeof(buffer)); - if (count > sizeof(buffer) - 1) - count = sizeof(buffer) - 1; - if (copy_from_user(buffer, buf, count)) - return -EFAULT; - - err = kstrtoint(strstrip(buffer), 0, &nice); - if (err < 0) - return err; - - p = get_proc_task(inode); - if (!p) - return -ESRCH; - - err = proc_sched_autogroup_set_nice(p, nice); - if (err) - count = err; - - put_task_struct(p); - - return count; -} - -static int sched_autogroup_open(struct inode *inode, struct file *filp) -{ - int ret; - - ret = single_open(filp, sched_autogroup_show, NULL); - if (!ret) { - struct seq_file *m = filp->private_data; - - m->private = inode; - } - return ret; -} - -static const struct file_operations proc_pid_sched_autogroup_operations = { - .open = sched_autogroup_open, - .read = seq_read, - .write = sched_autogroup_write, - .llseek = seq_lseek, - .release = single_release, -}; - -#endif /* CONFIG_SCHED_AUTOGROUP */ - static ssize_t comm_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) { @@ -3035,9 +2960,6 @@ static const struct pid_entry tgid_base_stuff[] = { INF("limits", S_IRUGO, proc_pid_limits), #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations), -#endif -#ifdef CONFIG_SCHED_AUTOGROUP - REG("autogroup", S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations), #endif REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations), #ifdef CONFIG_HAVE_ARCH_TRACEHOOK diff --git a/kernel/sched/auto_group.c b/kernel/sched/auto_group.c index 0984a21076a..0f1bacb005a 100644 --- a/kernel/sched/auto_group.c +++ b/kernel/sched/auto_group.c @@ -110,6 +110,9 @@ out_fail: bool task_wants_autogroup(struct task_struct *p, struct task_group *tg) { + if (!sysctl_sched_autogroup_enabled) + return false; + if (tg != &root_task_group) return false; @@ -143,15 +146,11 @@ autogroup_move_group(struct task_struct *p, struct autogroup *ag) p->signal->autogroup = autogroup_kref_get(ag); - if (!ACCESS_ONCE(sysctl_sched_autogroup_enabled)) - goto out; - t = p; do { sched_move_task(t); } while_each_thread(p, t); -out: unlock_task_sighand(p, &flags); autogroup_kref_put(prev); } @@ -159,8 +158,11 @@ out: /* Allocates GFP_KERNEL, cannot be called under any spinlock */ void sched_autogroup_create_attach(struct task_struct *p) { - struct autogroup *ag = autogroup_create(); + struct autogroup *ag; + if (!sysctl_sched_autogroup_enabled) + return; + ag = autogroup_create(); autogroup_move_group(p, ag); /* drop extra reference added by autogroup_create() */ autogroup_kref_put(ag); @@ -176,11 +178,15 @@ EXPORT_SYMBOL(sched_autogroup_detach); void sched_autogroup_fork(struct signal_struct *sig) { + if (!sysctl_sched_autogroup_enabled) + return; sig->autogroup = autogroup_task_get(current); } void sched_autogroup_exit(struct signal_struct *sig) { + if (!sysctl_sched_autogroup_enabled) + return; autogroup_kref_put(sig->autogroup); } @@ -193,58 +199,6 @@ static int __init setup_autogroup(char *str) __setup("noautogroup", setup_autogroup); -#ifdef CONFIG_PROC_FS - -int proc_sched_autogroup_set_nice(struct task_struct *p, int nice) -{ - static unsigned long next = INITIAL_JIFFIES; - struct autogroup *ag; - int err; - - if (nice < -20 || nice > 19) - return -EINVAL; - - err = security_task_setnice(current, nice); - if (err) - return err; - - if (nice < 0 && !can_nice(current, nice)) - return -EPERM; - - /* this is a heavy operation taking global locks.. */ - if (!capable(CAP_SYS_ADMIN) && time_before(jiffies, next)) - return -EAGAIN; - - next = HZ / 10 + jiffies; - ag = autogroup_task_get(p); - - down_write(&ag->lock); - err = sched_group_set_shares(ag->tg, prio_to_weight[nice + 20]); - if (!err) - ag->nice = nice; - up_write(&ag->lock); - - autogroup_kref_put(ag); - - return err; -} - -void proc_sched_autogroup_show_task(struct task_struct *p, struct seq_file *m) -{ - struct autogroup *ag = autogroup_task_get(p); - - if (!task_group_is_autogroup(ag->tg)) - goto out; - - down_read(&ag->lock); - seq_printf(m, "/autogroup-%ld nice %d\n", ag->id, ag->nice); - up_read(&ag->lock); - -out: - autogroup_kref_put(ag); -} -#endif /* CONFIG_PROC_FS */ - #ifdef CONFIG_SCHED_DEBUG int autogroup_path(struct task_group *tg, char *buf, int buflen) { diff --git a/kernel/sched/auto_group.h b/kernel/sched/auto_group.h index 8bd04714281..4552c6bf79d 100644 --- a/kernel/sched/auto_group.h +++ b/kernel/sched/auto_group.h @@ -4,11 +4,6 @@ #include struct autogroup { - /* - * reference doesn't mean how many thread attach to this - * autogroup now. It just stands for the number of task - * could use this autogroup. - */ struct kref kref; struct task_group *tg; struct rw_semaphore lock; @@ -29,9 +24,7 @@ extern bool task_wants_autogroup(struct task_struct *p, struct task_group *tg); static inline struct task_group * autogroup_task_group(struct task_struct *p, struct task_group *tg) { - int enabled = ACCESS_ONCE(sysctl_sched_autogroup_enabled); - - if (enabled && task_wants_autogroup(p, tg)) + if (task_wants_autogroup(p, tg)) return p->signal->autogroup->tg; return tg; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 81c7b1a1a30..2914d0f752c 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -363,10 +363,8 @@ static struct ctl_table kern_table[] = { .procname = "sched_autogroup_enabled", .data = &sysctl_sched_autogroup_enabled, .maxlen = sizeof(unsigned int), - .mode = 0644, - .proc_handler = proc_dointvec_minmax, - .extra1 = &zero, - .extra2 = &one, + .mode = 0444, + .proc_handler = proc_dointvec, }, #endif #ifdef CONFIG_CFS_BANDWIDTH -- cgit v1.2.3 From fe81ad1c2d8149323e4a63c5a3bf8b170597c8b7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 8 Oct 2012 15:15:46 +0900 Subject: ASoC: wm5102: Write register value corrections after SYSCLK is enabled Evalation of the WM5102 has identified a number of register values which should be written after SYSCLK is enabled on revision A in order to improve performance. Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 552 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 551 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 1722b586bdb..7394e73fa43 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -42,6 +42,556 @@ static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0); +static const struct reg_default wm5102_sysclk_reva_patch[] = { + { 0x3000, 0x2225 }, + { 0x3001, 0x3a03 }, + { 0x3002, 0x0225 }, + { 0x3003, 0x0801 }, + { 0x3004, 0x6249 }, + { 0x3005, 0x0c04 }, + { 0x3006, 0x0225 }, + { 0x3007, 0x5901 }, + { 0x3008, 0xe249 }, + { 0x3009, 0x030d }, + { 0x300a, 0x0249 }, + { 0x300b, 0x2c01 }, + { 0x300c, 0xe249 }, + { 0x300d, 0x4342 }, + { 0x300e, 0xe249 }, + { 0x300f, 0x73c0 }, + { 0x3010, 0x4249 }, + { 0x3011, 0x0c00 }, + { 0x3012, 0x0225 }, + { 0x3013, 0x1f01 }, + { 0x3014, 0x0225 }, + { 0x3015, 0x1e01 }, + { 0x3016, 0x0225 }, + { 0x3017, 0xfa00 }, + { 0x3018, 0x0000 }, + { 0x3019, 0xf000 }, + { 0x301a, 0x0000 }, + { 0x301b, 0xf000 }, + { 0x301c, 0x0000 }, + { 0x301d, 0xf000 }, + { 0x301e, 0x0000 }, + { 0x301f, 0xf000 }, + { 0x3020, 0x0000 }, + { 0x3021, 0xf000 }, + { 0x3022, 0x0000 }, + { 0x3023, 0xf000 }, + { 0x3024, 0x0000 }, + { 0x3025, 0xf000 }, + { 0x3026, 0x0000 }, + { 0x3027, 0xf000 }, + { 0x3028, 0x0000 }, + { 0x3029, 0xf000 }, + { 0x302a, 0x0000 }, + { 0x302b, 0xf000 }, + { 0x302c, 0x0000 }, + { 0x302d, 0xf000 }, + { 0x302e, 0x0000 }, + { 0x302f, 0xf000 }, + { 0x3030, 0x0225 }, + { 0x3031, 0x1a01 }, + { 0x3032, 0x0225 }, + { 0x3033, 0x1e00 }, + { 0x3034, 0x0225 }, + { 0x3035, 0x1f00 }, + { 0x3036, 0x6225 }, + { 0x3037, 0xf800 }, + { 0x3038, 0x0000 }, + { 0x3039, 0xf000 }, + { 0x303a, 0x0000 }, + { 0x303b, 0xf000 }, + { 0x303c, 0x0000 }, + { 0x303d, 0xf000 }, + { 0x303e, 0x0000 }, + { 0x303f, 0xf000 }, + { 0x3040, 0x2226 }, + { 0x3041, 0x3a03 }, + { 0x3042, 0x0226 }, + { 0x3043, 0x0801 }, + { 0x3044, 0x6249 }, + { 0x3045, 0x0c06 }, + { 0x3046, 0x0226 }, + { 0x3047, 0x5901 }, + { 0x3048, 0xe249 }, + { 0x3049, 0x030d }, + { 0x304a, 0x0249 }, + { 0x304b, 0x2c01 }, + { 0x304c, 0xe249 }, + { 0x304d, 0x4342 }, + { 0x304e, 0xe249 }, + { 0x304f, 0x73c0 }, + { 0x3050, 0x4249 }, + { 0x3051, 0x0c00 }, + { 0x3052, 0x0226 }, + { 0x3053, 0x1f01 }, + { 0x3054, 0x0226 }, + { 0x3055, 0x1e01 }, + { 0x3056, 0x0226 }, + { 0x3057, 0xfa00 }, + { 0x3058, 0x0000 }, + { 0x3059, 0xf000 }, + { 0x305a, 0x0000 }, + { 0x305b, 0xf000 }, + { 0x305c, 0x0000 }, + { 0x305d, 0xf000 }, + { 0x305e, 0x0000 }, + { 0x305f, 0xf000 }, + { 0x3060, 0x0000 }, + { 0x3061, 0xf000 }, + { 0x3062, 0x0000 }, + { 0x3063, 0xf000 }, + { 0x3064, 0x0000 }, + { 0x3065, 0xf000 }, + { 0x3066, 0x0000 }, + { 0x3067, 0xf000 }, + { 0x3068, 0x0000 }, + { 0x3069, 0xf000 }, + { 0x306a, 0x0000 }, + { 0x306b, 0xf000 }, + { 0x306c, 0x0000 }, + { 0x306d, 0xf000 }, + { 0x306e, 0x0000 }, + { 0x306f, 0xf000 }, + { 0x3070, 0x0226 }, + { 0x3071, 0x1a01 }, + { 0x3072, 0x0226 }, + { 0x3073, 0x1e00 }, + { 0x3074, 0x0226 }, + { 0x3075, 0x1f00 }, + { 0x3076, 0x6226 }, + { 0x3077, 0xf800 }, + { 0x3078, 0x0000 }, + { 0x3079, 0xf000 }, + { 0x307a, 0x0000 }, + { 0x307b, 0xf000 }, + { 0x307c, 0x0000 }, + { 0x307d, 0xf000 }, + { 0x307e, 0x0000 }, + { 0x307f, 0xf000 }, + { 0x3080, 0x2227 }, + { 0x3081, 0x3a03 }, + { 0x3082, 0x0227 }, + { 0x3083, 0x0801 }, + { 0x3084, 0x6255 }, + { 0x3085, 0x0c04 }, + { 0x3086, 0x0227 }, + { 0x3087, 0x5901 }, + { 0x3088, 0xe255 }, + { 0x3089, 0x030d }, + { 0x308a, 0x0255 }, + { 0x308b, 0x2c01 }, + { 0x308c, 0xe255 }, + { 0x308d, 0x4342 }, + { 0x308e, 0xe255 }, + { 0x308f, 0x73c0 }, + { 0x3090, 0x4255 }, + { 0x3091, 0x0c00 }, + { 0x3092, 0x0227 }, + { 0x3093, 0x1f01 }, + { 0x3094, 0x0227 }, + { 0x3095, 0x1e01 }, + { 0x3096, 0x0227 }, + { 0x3097, 0xfa00 }, + { 0x3098, 0x0000 }, + { 0x3099, 0xf000 }, + { 0x309a, 0x0000 }, + { 0x309b, 0xf000 }, + { 0x309c, 0x0000 }, + { 0x309d, 0xf000 }, + { 0x309e, 0x0000 }, + { 0x309f, 0xf000 }, + { 0x30a0, 0x0000 }, + { 0x30a1, 0xf000 }, + { 0x30a2, 0x0000 }, + { 0x30a3, 0xf000 }, + { 0x30a4, 0x0000 }, + { 0x30a5, 0xf000 }, + { 0x30a6, 0x0000 }, + { 0x30a7, 0xf000 }, + { 0x30a8, 0x0000 }, + { 0x30a9, 0xf000 }, + { 0x30aa, 0x0000 }, + { 0x30ab, 0xf000 }, + { 0x30ac, 0x0000 }, + { 0x30ad, 0xf000 }, + { 0x30ae, 0x0000 }, + { 0x30af, 0xf000 }, + { 0x30b0, 0x0227 }, + { 0x30b1, 0x1a01 }, + { 0x30b2, 0x0227 }, + { 0x30b3, 0x1e00 }, + { 0x30b4, 0x0227 }, + { 0x30b5, 0x1f00 }, + { 0x30b6, 0x6227 }, + { 0x30b7, 0xf800 }, + { 0x30b8, 0x0000 }, + { 0x30b9, 0xf000 }, + { 0x30ba, 0x0000 }, + { 0x30bb, 0xf000 }, + { 0x30bc, 0x0000 }, + { 0x30bd, 0xf000 }, + { 0x30be, 0x0000 }, + { 0x30bf, 0xf000 }, + { 0x30c0, 0x2228 }, + { 0x30c1, 0x3a03 }, + { 0x30c2, 0x0228 }, + { 0x30c3, 0x0801 }, + { 0x30c4, 0x6255 }, + { 0x30c5, 0x0c06 }, + { 0x30c6, 0x0228 }, + { 0x30c7, 0x5901 }, + { 0x30c8, 0xe255 }, + { 0x30c9, 0x030d }, + { 0x30ca, 0x0255 }, + { 0x30cb, 0x2c01 }, + { 0x30cc, 0xe255 }, + { 0x30cd, 0x4342 }, + { 0x30ce, 0xe255 }, + { 0x30cf, 0x73c0 }, + { 0x30d0, 0x4255 }, + { 0x30d1, 0x0c00 }, + { 0x30d2, 0x0228 }, + { 0x30d3, 0x1f01 }, + { 0x30d4, 0x0228 }, + { 0x30d5, 0x1e01 }, + { 0x30d6, 0x0228 }, + { 0x30d7, 0xfa00 }, + { 0x30d8, 0x0000 }, + { 0x30d9, 0xf000 }, + { 0x30da, 0x0000 }, + { 0x30db, 0xf000 }, + { 0x30dc, 0x0000 }, + { 0x30dd, 0xf000 }, + { 0x30de, 0x0000 }, + { 0x30df, 0xf000 }, + { 0x30e0, 0x0000 }, + { 0x30e1, 0xf000 }, + { 0x30e2, 0x0000 }, + { 0x30e3, 0xf000 }, + { 0x30e4, 0x0000 }, + { 0x30e5, 0xf000 }, + { 0x30e6, 0x0000 }, + { 0x30e7, 0xf000 }, + { 0x30e8, 0x0000 }, + { 0x30e9, 0xf000 }, + { 0x30ea, 0x0000 }, + { 0x30eb, 0xf000 }, + { 0x30ec, 0x0000 }, + { 0x30ed, 0xf000 }, + { 0x30ee, 0x0000 }, + { 0x30ef, 0xf000 }, + { 0x30f0, 0x0228 }, + { 0x30f1, 0x1a01 }, + { 0x30f2, 0x0228 }, + { 0x30f3, 0x1e00 }, + { 0x30f4, 0x0228 }, + { 0x30f5, 0x1f00 }, + { 0x30f6, 0x6228 }, + { 0x30f7, 0xf800 }, + { 0x30f8, 0x0000 }, + { 0x30f9, 0xf000 }, + { 0x30fa, 0x0000 }, + { 0x30fb, 0xf000 }, + { 0x30fc, 0x0000 }, + { 0x30fd, 0xf000 }, + { 0x30fe, 0x0000 }, + { 0x30ff, 0xf000 }, + { 0x3100, 0x222b }, + { 0x3101, 0x3a03 }, + { 0x3102, 0x222b }, + { 0x3103, 0x5803 }, + { 0x3104, 0xe26f }, + { 0x3105, 0x030d }, + { 0x3106, 0x626f }, + { 0x3107, 0x2c01 }, + { 0x3108, 0xe26f }, + { 0x3109, 0x4342 }, + { 0x310a, 0xe26f }, + { 0x310b, 0x73c0 }, + { 0x310c, 0x026f }, + { 0x310d, 0x0c00 }, + { 0x310e, 0x022b }, + { 0x310f, 0x1f01 }, + { 0x3110, 0x022b }, + { 0x3111, 0x1e01 }, + { 0x3112, 0x022b }, + { 0x3113, 0xfa00 }, + { 0x3114, 0x0000 }, + { 0x3115, 0xf000 }, + { 0x3116, 0x0000 }, + { 0x3117, 0xf000 }, + { 0x3118, 0x0000 }, + { 0x3119, 0xf000 }, + { 0x311a, 0x0000 }, + { 0x311b, 0xf000 }, + { 0x311c, 0x0000 }, + { 0x311d, 0xf000 }, + { 0x311e, 0x0000 }, + { 0x311f, 0xf000 }, + { 0x3120, 0x022b }, + { 0x3121, 0x0a01 }, + { 0x3122, 0x022b }, + { 0x3123, 0x1e00 }, + { 0x3124, 0x022b }, + { 0x3125, 0x1f00 }, + { 0x3126, 0x622b }, + { 0x3127, 0xf800 }, + { 0x3128, 0x0000 }, + { 0x3129, 0xf000 }, + { 0x312a, 0x0000 }, + { 0x312b, 0xf000 }, + { 0x312c, 0x0000 }, + { 0x312d, 0xf000 }, + { 0x312e, 0x0000 }, + { 0x312f, 0xf000 }, + { 0x3130, 0x0000 }, + { 0x3131, 0xf000 }, + { 0x3132, 0x0000 }, + { 0x3133, 0xf000 }, + { 0x3134, 0x0000 }, + { 0x3135, 0xf000 }, + { 0x3136, 0x0000 }, + { 0x3137, 0xf000 }, + { 0x3138, 0x0000 }, + { 0x3139, 0xf000 }, + { 0x313a, 0x0000 }, + { 0x313b, 0xf000 }, + { 0x313c, 0x0000 }, + { 0x313d, 0xf000 }, + { 0x313e, 0x0000 }, + { 0x313f, 0xf000 }, + { 0x3140, 0x0000 }, + { 0x3141, 0xf000 }, + { 0x3142, 0x0000 }, + { 0x3143, 0xf000 }, + { 0x3144, 0x0000 }, + { 0x3145, 0xf000 }, + { 0x3146, 0x0000 }, + { 0x3147, 0xf000 }, + { 0x3148, 0x0000 }, + { 0x3149, 0xf000 }, + { 0x314a, 0x0000 }, + { 0x314b, 0xf000 }, + { 0x314c, 0x0000 }, + { 0x314d, 0xf000 }, + { 0x314e, 0x0000 }, + { 0x314f, 0xf000 }, + { 0x3150, 0x0000 }, + { 0x3151, 0xf000 }, + { 0x3152, 0x0000 }, + { 0x3153, 0xf000 }, + { 0x3154, 0x0000 }, + { 0x3155, 0xf000 }, + { 0x3156, 0x0000 }, + { 0x3157, 0xf000 }, + { 0x3158, 0x0000 }, + { 0x3159, 0xf000 }, + { 0x315a, 0x0000 }, + { 0x315b, 0xf000 }, + { 0x315c, 0x0000 }, + { 0x315d, 0xf000 }, + { 0x315e, 0x0000 }, + { 0x315f, 0xf000 }, + { 0x3160, 0x0000 }, + { 0x3161, 0xf000 }, + { 0x3162, 0x0000 }, + { 0x3163, 0xf000 }, + { 0x3164, 0x0000 }, + { 0x3165, 0xf000 }, + { 0x3166, 0x0000 }, + { 0x3167, 0xf000 }, + { 0x3168, 0x0000 }, + { 0x3169, 0xf000 }, + { 0x316a, 0x0000 }, + { 0x316b, 0xf000 }, + { 0x316c, 0x0000 }, + { 0x316d, 0xf000 }, + { 0x316e, 0x0000 }, + { 0x316f, 0xf000 }, + { 0x3170, 0x0000 }, + { 0x3171, 0xf000 }, + { 0x3172, 0x0000 }, + { 0x3173, 0xf000 }, + { 0x3174, 0x0000 }, + { 0x3175, 0xf000 }, + { 0x3176, 0x0000 }, + { 0x3177, 0xf000 }, + { 0x3178, 0x0000 }, + { 0x3179, 0xf000 }, + { 0x317a, 0x0000 }, + { 0x317b, 0xf000 }, + { 0x317c, 0x0000 }, + { 0x317d, 0xf000 }, + { 0x317e, 0x0000 }, + { 0x317f, 0xf000 }, + { 0x3180, 0x2001 }, + { 0x3181, 0xf101 }, + { 0x3182, 0x0000 }, + { 0x3183, 0xf000 }, + { 0x3184, 0x0000 }, + { 0x3185, 0xf000 }, + { 0x3186, 0x0000 }, + { 0x3187, 0xf000 }, + { 0x3188, 0x0000 }, + { 0x3189, 0xf000 }, + { 0x318a, 0x0000 }, + { 0x318b, 0xf000 }, + { 0x318c, 0x0000 }, + { 0x318d, 0xf000 }, + { 0x318e, 0x0000 }, + { 0x318f, 0xf000 }, + { 0x3190, 0x0000 }, + { 0x3191, 0xf000 }, + { 0x3192, 0x0000 }, + { 0x3193, 0xf000 }, + { 0x3194, 0x0000 }, + { 0x3195, 0xf000 }, + { 0x3196, 0x0000 }, + { 0x3197, 0xf000 }, + { 0x3198, 0x0000 }, + { 0x3199, 0xf000 }, + { 0x319a, 0x0000 }, + { 0x319b, 0xf000 }, + { 0x319c, 0x0000 }, + { 0x319d, 0xf000 }, + { 0x319e, 0x0000 }, + { 0x319f, 0xf000 }, + { 0x31a0, 0x0000 }, + { 0x31a1, 0xf000 }, + { 0x31a2, 0x0000 }, + { 0x31a3, 0xf000 }, + { 0x31a4, 0x0000 }, + { 0x31a5, 0xf000 }, + { 0x31a6, 0x0000 }, + { 0x31a7, 0xf000 }, + { 0x31a8, 0x0000 }, + { 0x31a9, 0xf000 }, + { 0x31aa, 0x0000 }, + { 0x31ab, 0xf000 }, + { 0x31ac, 0x0000 }, + { 0x31ad, 0xf000 }, + { 0x31ae, 0x0000 }, + { 0x31af, 0xf000 }, + { 0x31b0, 0x0000 }, + { 0x31b1, 0xf000 }, + { 0x31b2, 0x0000 }, + { 0x31b3, 0xf000 }, + { 0x31b4, 0x0000 }, + { 0x31b5, 0xf000 }, + { 0x31b6, 0x0000 }, + { 0x31b7, 0xf000 }, + { 0x31b8, 0x0000 }, + { 0x31b9, 0xf000 }, + { 0x31ba, 0x0000 }, + { 0x31bb, 0xf000 }, + { 0x31bc, 0x0000 }, + { 0x31bd, 0xf000 }, + { 0x31be, 0x0000 }, + { 0x31bf, 0xf000 }, + { 0x31c0, 0x0000 }, + { 0x31c1, 0xf000 }, + { 0x31c2, 0x0000 }, + { 0x31c3, 0xf000 }, + { 0x31c4, 0x0000 }, + { 0x31c5, 0xf000 }, + { 0x31c6, 0x0000 }, + { 0x31c7, 0xf000 }, + { 0x31c8, 0x0000 }, + { 0x31c9, 0xf000 }, + { 0x31ca, 0x0000 }, + { 0x31cb, 0xf000 }, + { 0x31cc, 0x0000 }, + { 0x31cd, 0xf000 }, + { 0x31ce, 0x0000 }, + { 0x31cf, 0xf000 }, + { 0x31d0, 0x0000 }, + { 0x31d1, 0xf000 }, + { 0x31d2, 0x0000 }, + { 0x31d3, 0xf000 }, + { 0x31d4, 0x0000 }, + { 0x31d5, 0xf000 }, + { 0x31d6, 0x0000 }, + { 0x31d7, 0xf000 }, + { 0x31d8, 0x0000 }, + { 0x31d9, 0xf000 }, + { 0x31da, 0x0000 }, + { 0x31db, 0xf000 }, + { 0x31dc, 0x0000 }, + { 0x31dd, 0xf000 }, + { 0x31de, 0x0000 }, + { 0x31df, 0xf000 }, + { 0x31e0, 0x0000 }, + { 0x31e1, 0xf000 }, + { 0x31e2, 0x0000 }, + { 0x31e3, 0xf000 }, + { 0x31e4, 0x0000 }, + { 0x31e5, 0xf000 }, + { 0x31e6, 0x0000 }, + { 0x31e7, 0xf000 }, + { 0x31e8, 0x0000 }, + { 0x31e9, 0xf000 }, + { 0x31ea, 0x0000 }, + { 0x31eb, 0xf000 }, + { 0x31ec, 0x0000 }, + { 0x31ed, 0xf000 }, + { 0x31ee, 0x0000 }, + { 0x31ef, 0xf000 }, + { 0x31f0, 0x0000 }, + { 0x31f1, 0xf000 }, + { 0x31f2, 0x0000 }, + { 0x31f3, 0xf000 }, + { 0x31f4, 0x0000 }, + { 0x31f5, 0xf000 }, + { 0x31f6, 0x0000 }, + { 0x31f7, 0xf000 }, + { 0x31f8, 0x0000 }, + { 0x31f9, 0xf000 }, + { 0x31fa, 0x0000 }, + { 0x31fb, 0xf000 }, + { 0x31fc, 0x0000 }, + { 0x31fd, 0xf000 }, + { 0x31fe, 0x0000 }, + { 0x31ff, 0xf000 }, + { 0x024d, 0xff50 }, + { 0x0252, 0xff50 }, + { 0x0259, 0x0112 }, + { 0x025e, 0x0112 }, +}; + +static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct arizona *arizona = dev_get_drvdata(codec->dev); + struct regmap *regmap = codec->control_data; + const struct reg_default *patch = NULL; + int i, patch_size; + + switch (arizona->rev) { + case 0: + patch = wm5102_sysclk_reva_patch; + patch_size = ARRAY_SIZE(wm5102_sysclk_reva_patch); + break; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (patch) + for (i = 0; i < patch_size; i++) + regmap_write(regmap, patch[i].reg, + patch[i].def); + break; + + default: + break; + } + + return 0; +} + static const struct snd_kcontrol_new wm5102_snd_controls[] = { SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL, ARIZONA_IN1_OSR_SHIFT, 1, 0), @@ -297,7 +847,7 @@ static const struct snd_kcontrol_new wm5102_aec_loopback_mux = static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, - 0, NULL, 0), + 0, wm5102_sysclk_ev, SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1, ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK, -- cgit v1.2.3 From 1234471e2d11e4ee47f6de452dd8b8aeb09b45de Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 23 Oct 2012 22:44:49 +0900 Subject: perf header: Fix numa topology printing Andrew reported that the commit 7e94cfcc9d20 ("perf header: Use pre- processed session env when printing") regresses the header output. It was because of a missed string pointer calculation in the loop. Reported-by: Andrew Jones Tested-by: Andrew Jones Signed-off-by: Namhyung Kim Cc: Andrew Jones Link: http://lkml.kernel.org/r/1350999890-6920-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/header.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 7daad237dea..566b84c695c 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -1378,6 +1378,8 @@ static void print_numa_topology(struct perf_header *ph, int fd __maybe_unused, str = tmp + 1; fprintf(fp, "# node%u cpu list : %s\n", c, str); + + str += strlen(str) + 1; } return; error: -- cgit v1.2.3 From f787d9519fb10411f2948f5b9957a1669879ba84 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 23 Oct 2012 22:44:50 +0900 Subject: perf tools: Fix strbuf_addf() when the buffer needs to grow This was found during chasing down the header output regression. The strbuf_addf() was checking buffer length with a result of vscnprintf() which cannot be greater than that of strbuf_avail(). Since numa topology and pmu mapping info in header were converted to use strbuf, it sometimes caused uninteresting behaviors with the broken strbuf. Fix it by using vsnprintf() which returns desired output string length regardless of the available buffer size and grow the buffer if needed. Reported-by: Andrew Jones Tested-by: Andrew Jones Signed-off-by: Namhyung Kim Cc: Andrew Jones Link: http://lkml.kernel.org/r/1350999890-6920-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/strbuf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c index 2eeb51baf07..cfa906882e2 100644 --- a/tools/perf/util/strbuf.c +++ b/tools/perf/util/strbuf.c @@ -90,17 +90,17 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...) if (!strbuf_avail(sb)) strbuf_grow(sb, 64); va_start(ap, fmt); - len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); + len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); va_end(ap); if (len < 0) - die("your vscnprintf is broken"); + die("your vsnprintf is broken"); if (len > strbuf_avail(sb)) { strbuf_grow(sb, len); va_start(ap, fmt); - len = vscnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); + len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap); va_end(ap); if (len > strbuf_avail(sb)) { - die("this should not happen, your snprintf is broken"); + die("this should not happen, your vsnprintf is broken"); } } strbuf_setlen(sb, sb->len + len); -- cgit v1.2.3 From f6bc8c29383456b89ac1b6f1aa768d195670fb53 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Mon, 29 Oct 2012 16:44:46 +0200 Subject: usb: otg: Fix build errors if USB_MUSB_OMAP2PLUS is selected as module TWL4030_USB & TWL6030_USB must depend on USB_MUSB_OMAP2PLUS in Kconfig else we get build errors with CONFIG_USB_MUSB_HDRC=m CONFIG_USB_MUSB_OMAP2PLUS=m CONFIG_TWL4030_USB=y CONFIG_TWL6030_USB=y LD init/built-in.o drivers/built-in.o: In function `twl4030_usb_irq': drivers/usb/otg/twl4030-usb.c:518: undefined reference to `omap_musb_mailbox' drivers/built-in.o: In function `twl4030_usb_phy_init': drivers/usb/otg/twl4030-usb.c:540: undefined reference to `omap_musb_mailbox' drivers/built-in.o: In function `twl6030_usb_irq': drivers/usb/otg/twl6030-usb.c:230: undefined reference to `omap_musb_mailbox' drivers/usb/otg/twl6030-usb.c:225: undefined reference to `omap_musb_mailbox' drivers/built-in.o: In function `twl6030_usbotg_irq': drivers/usb/otg/twl6030-usb.c:259: undefined reference to `omap_musb_mailbox' CC: Peter Meerwald Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/otg/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index d8c8a42bff3..6223062d5d1 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig @@ -58,7 +58,7 @@ config USB_ULPI_VIEWPORT config TWL4030_USB tristate "TWL4030 USB Transceiver Driver" - depends on TWL4030_CORE && REGULATOR_TWL4030 + depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS select USB_OTG_UTILS help Enable this to support the USB OTG transceiver on TWL4030 @@ -68,7 +68,7 @@ config TWL4030_USB config TWL6030_USB tristate "TWL6030 USB Transceiver Driver" - depends on TWL4030_CORE && OMAP_USB2 + depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS select USB_OTG_UTILS help Enable this to support the USB OTG transceiver on TWL6030 -- cgit v1.2.3 From f57cee11374a0e3056313e0818e3ff2ebd0f496d Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Mon, 29 Oct 2012 20:03:47 +0900 Subject: staging/gdm72xx: Use netdev_ or pr_ printks in gdm_wimax.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_emerg(netdev, ... then dev_emerg(dev, ... then pr_emerg(... to printk(KERN_EMERG ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... and add pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_wimax.c | 60 +++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_wimax.c b/drivers/staging/gdm72xx/gdm_wimax.c index dad6fd3e0a7..c30276987d9 100644 --- a/drivers/staging/gdm72xx/gdm_wimax.c +++ b/drivers/staging/gdm72xx/gdm_wimax.c @@ -11,6 +11,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -274,7 +276,7 @@ static int gdm_wimax_event_init(void) return 0; } - printk(KERN_ERR "Creating WiMax Event netlink is failed\n"); + pr_err("Creating WiMax Event netlink is failed\n"); return -1; } @@ -370,7 +372,7 @@ static int gdm_wimax_event_send(struct net_device *dev, char *buf, int size) e = get_event_entry(); if (!e) { - printk(KERN_ERR "%s: No memory for event\n", __func__); + netdev_err(dev, "%s: No memory for event\n", __func__); spin_unlock_irqrestore(&wm_event.evt_lock, flags); return -ENOMEM; } @@ -436,10 +438,10 @@ static int gdm_wimax_tx(struct sk_buff *skb, struct net_device *dev) #if !defined(LOOPBACK_TEST) if (!fsm) - printk(KERN_ERR "ASSERTION ERROR: fsm is NULL!!\n"); + netdev_err(dev, "ASSERTION ERROR: fsm is NULL!!\n"); else if (fsm->m_status != M_CONNECTED) { - printk(KERN_EMERG "ASSERTION ERROR: Device is NOT ready. status=%d\n", - fsm->m_status); + netdev_emerg(dev, "ASSERTION ERROR: Device is NOT ready. status=%d\n", + fsm->m_status); kfree_skb(skb); return 0; } @@ -625,9 +627,8 @@ static int gdm_wimax_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCG_DATA: case SIOCS_DATA: if (req->data_id >= SIOC_DATA_MAX) { - printk(KERN_ERR - "%s error: data-index(%d) is invalid!!\n", - __func__, req->data_id); + netdev_err(dev, "%s error: data-index(%d) is invalid!!\n", + __func__, req->data_id); return -EOPNOTSUPP; } if (req->cmd == SIOCG_DATA) { @@ -649,7 +650,7 @@ static int gdm_wimax_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } break; default: - printk(KERN_ERR "%s: %x unknown ioctl\n", __func__, cmd); + netdev_err(dev, "%s: %x unknown ioctl\n", __func__, cmd); return -EOPNOTSUPP; } @@ -695,7 +696,7 @@ static void gdm_wimax_prepare_device(struct net_device *dev) hci->length = H2B(len); gdm_wimax_send(nic, hci, HCI_HEADER_SIZE+len); - printk(KERN_INFO "GDM WiMax Set CAPABILITY: 0x%08X\n", DB2H(val)); + netdev_info(dev, "GDM WiMax Set CAPABILITY: 0x%08X\n", DB2H(val)); } static int gdm_wimax_hci_get_tlv(u8 *buf, u8 *T, u16 *L, u8 **V) @@ -729,28 +730,28 @@ static int gdm_wimax_get_prepared_info(struct net_device *dev, char *buf, cmd_len = B2H(*(u16 *)&buf[2]); if (len < cmd_len + HCI_HEADER_SIZE) { - printk(KERN_ERR "%s: invalid length [%d/%d]\n", __func__, - cmd_len + HCI_HEADER_SIZE, len); + netdev_err(dev, "%s: invalid length [%d/%d]\n", __func__, + cmd_len + HCI_HEADER_SIZE, len); return -1; } if (cmd_evt == WIMAX_GET_INFO_RESULT) { if (cmd_len < 2) { - printk(KERN_ERR "%s: len is too short [%x/%d]\n", - __func__, cmd_evt, len); + netdev_err(dev, "%s: len is too short [%x/%d]\n", + __func__, cmd_evt, len); return -1; } pos += gdm_wimax_hci_get_tlv(&buf[pos], &T, &L, &V); if (T == TLV_T(T_MAC_ADDRESS)) { if (L != dev->addr_len) { - printk(KERN_ERR - "%s Invalid inofrmation result T/L " - "[%x/%d]\n", __func__, T, L); + netdev_err(dev, + "%s Invalid inofrmation result T/L [%x/%d]\n", + __func__, T, L); return -1; } - printk(KERN_INFO "MAC change [%pM]->[%pM]\n", - dev->dev_addr, V); + netdev_info(dev, "MAC change [%pM]->[%pM]\n", + dev->dev_addr, V); memcpy(dev->dev_addr, V, dev->addr_len); return 1; } @@ -772,7 +773,7 @@ static void gdm_wimax_netif_rx(struct net_device *dev, char *buf, int len) skb = dev_alloc_skb(len + 2); if (!skb) { - printk(KERN_ERR "%s: dev_alloc_skb failed!\n", __func__); + netdev_err(dev, "%s: dev_alloc_skb failed!\n", __func__); return; } skb_reserve(skb, 2); @@ -787,7 +788,7 @@ static void gdm_wimax_netif_rx(struct net_device *dev, char *buf, int len) ret = in_interrupt() ? netif_rx(skb) : netif_rx_ni(skb); if (ret == NET_RX_DROP) - printk(KERN_ERR "%s skb dropped\n", __func__); + netdev_err(dev, "%s skb dropped\n", __func__); } static void gdm_wimax_transmit_aggr_pkt(struct net_device *dev, char *buf, @@ -802,8 +803,8 @@ static void gdm_wimax_transmit_aggr_pkt(struct net_device *dev, char *buf, hci = (struct hci_s *) buf; if (B2H(hci->cmd_evt) != WIMAX_RX_SDU) { - printk(KERN_ERR "Wrong cmd_evt(0x%04X)\n", - B2H(hci->cmd_evt)); + netdev_err(dev, "Wrong cmd_evt(0x%04X)\n", + B2H(hci->cmd_evt)); break; } @@ -837,8 +838,8 @@ static void gdm_wimax_transmit_pkt(struct net_device *dev, char *buf, int len) if (len < cmd_len + HCI_HEADER_SIZE) { if (len) - printk(KERN_ERR "%s: invalid length [%d/%d]\n", - __func__, cmd_len + HCI_HEADER_SIZE, len); + netdev_err(dev, "%s: invalid length [%d/%d]\n", + __func__, cmd_len + HCI_HEADER_SIZE, len); return; } @@ -918,7 +919,8 @@ static void prepare_rx_complete(void *arg, void *data, int len) gdm_wimax_rcv_with_cb(nic, rx_complete, nic); else { if (ret < 0) - printk(KERN_ERR "get_prepared_info failed(%d)\n", ret); + netdev_err(nic->netdev, + "get_prepared_info failed(%d)\n", ret); gdm_wimax_rcv_with_cb(nic, prepare_rx_complete, nic); #if 0 /* Re-prepare WiMax device */ @@ -952,7 +954,7 @@ int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev) "wm%d", ether_setup); if (dev == NULL) { - printk(KERN_ERR "alloc_etherdev failed\n"); + pr_err("alloc_etherdev failed\n"); return -ENOMEM; } @@ -972,7 +974,7 @@ int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev) /* event socket init */ ret = gdm_wimax_event_init(); if (ret < 0) { - printk(KERN_ERR "Cannot create event.\n"); + pr_err("Cannot create event.\n"); goto cleanup; } @@ -999,7 +1001,7 @@ int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev) return 0; cleanup: - printk(KERN_ERR "register_netdev failed\n"); + pr_err("register_netdev failed\n"); free_netdev(dev); return ret; } -- cgit v1.2.3 From 2d8390223a8909dfddb326fd3d912de80022dd10 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Mon, 29 Oct 2012 20:04:42 +0900 Subject: staging/gdm72xx: Use netdev_ or pr_ printks in gdm_qos.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... - WARNING: Prefer netdev_dbg(netdev, ... then dev_dbg(dev, ... then pr_debug(... to printk(KERN_DEBUG ... and add pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_qos.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index e26c6a8b262..1e630312372 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -11,6 +11,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include @@ -24,15 +26,6 @@ #define B2H(x) __be16_to_cpu(x) -#undef dprintk -#define dprintk(fmt, args ...) printk(KERN_DEBUG "[QoS] " fmt, ## args) -#undef wprintk -#define wprintk(fmt, args ...) \ - printk(KERN_WARNING "[QoS WARNING] " fmt, ## args) -#undef eprintk -#define eprintk(fmt, args ...) printk(KERN_ERR "[QoS ERROR] " fmt, ## args) - - #define MAX_FREE_LIST_CNT 32 static struct { struct list_head head; @@ -95,7 +88,7 @@ static void free_qos_entry_list(struct list_head *free_list) total_free++; } - dprintk("%s: total_free_cnt=%d\n", __func__, total_free); + pr_debug("%s: total_free_cnt=%d\n", __func__, total_free); } void gdm_qos_init(void *nic_ptr) @@ -240,7 +233,9 @@ static u32 extract_qos_list(struct nic *nic, struct list_head *head) qcb->csr[i].qos_buf_count++; if (!list_empty(&qcb->qos_list[i])) - wprintk("QoS Index(%d) is piled!!\n", i); + netdev_warn(nic->netdev, + "Index(%d) is piled!!\n", + i); } } } @@ -280,7 +275,8 @@ int gdm_qos_send_hci_pkt(struct sk_buff *skb, struct net_device *dev) entry = alloc_qos_entry(); entry->skb = skb; entry->dev = dev; - dprintk("qcb->qos_list_cnt=%d\n", qcb->qos_list_cnt); + netdev_dbg(dev, "qcb->qos_list_cnt=%d\n", + qcb->qos_list_cnt); } spin_lock_irqsave(&qcb->qos_lock, flags); @@ -362,7 +358,7 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) index = get_csr(qcb, SFID, 0); if (index == -1) { spin_unlock_irqrestore(&qcb->qos_lock, flags); - eprintk("QoS ERROR: No SF\n"); + netdev_err(nic->netdev, "QoS ERROR: No SF\n"); return; } qcb->csr[index].qos_buf_count = buf[(i*5)+10]; @@ -383,11 +379,12 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) index = get_csr(qcb, SFID, 1); if (index == -1) { - eprintk("QoS ERROR: csr Update Error\n"); + netdev_err(nic->netdev, "QoS ERROR: csr Update Error\n"); return; } - dprintk("QOS_ADD SFID = 0x%x, index=%d\n", SFID, index); + netdev_dbg(nic->netdev, "QOS_ADD SFID = 0x%x, index=%d\n", + SFID, index); spin_lock_irqsave(&qcb->qos_lock, flags); qcb->csr[index].SFID = SFID; @@ -435,11 +432,13 @@ void gdm_recv_qos_hci_packet(void *nic_ptr, u8 *buf, int size) SFID += (buf[pos++]); index = get_csr(qcb, SFID, 1); if (index == -1) { - eprintk("QoS ERROR: Wrong index(%d)\n", index); + netdev_err(nic->netdev, "QoS ERROR: Wrong index(%d)\n", + index); return; } - dprintk("QOS_CHANGE_DEL SFID = 0x%x, index=%d\n", SFID, index); + netdev_dbg(nic->netdev, "QOS_CHANGE_DEL SFID = 0x%x, index=%d\n", + SFID, index); INIT_LIST_HEAD(&free_list); -- cgit v1.2.3 From cade0fe46fde08642674838a0d17389bd1b7ba4b Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Mon, 29 Oct 2012 20:05:02 +0900 Subject: staging/gdm72xx: Use netdev_ or pr_ printks in netlink_k.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... and add pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/netlink_k.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c index 20d0aec52e7..52c25ba5831 100644 --- a/drivers/staging/gdm72xx/netlink_k.c +++ b/drivers/staging/gdm72xx/netlink_k.c @@ -11,6 +11,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -54,8 +56,8 @@ static void netlink_rcv_cb(struct sk_buff *skb) if (skb->len < nlh->nlmsg_len || nlh->nlmsg_len > ND_MAX_MSG_LEN) { - printk(KERN_ERR "Invalid length (%d,%d)\n", skb->len, - nlh->nlmsg_len); + netdev_err(skb->dev, "Invalid length (%d,%d)\n", + skb->len, nlh->nlmsg_len); return; } @@ -69,10 +71,11 @@ static void netlink_rcv_cb(struct sk_buff *skb) rcv_cb(dev, nlh->nlmsg_type, msg, mlen); dev_put(dev); } else - printk(KERN_ERR "dev_get_by_index(%d) " - "is not found.\n", ifindex); + netdev_err(skb->dev, + "dev_get_by_index(%d) is not found.\n", + ifindex); } else - printk(KERN_ERR "Unregistered Callback\n"); + netdev_err(skb->dev, "Unregistered Callback\n"); } } @@ -116,14 +119,14 @@ int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) int ret = 0; if (group > ND_MAX_GROUP) { - printk(KERN_ERR "Group %d is invalied.\n", group); - printk(KERN_ERR "Valid group is 0 ~ %d.\n", ND_MAX_GROUP); + pr_err("Group %d is invalied.\n", group); + pr_err("Valid group is 0 ~ %d.\n", ND_MAX_GROUP); return -EINVAL; } skb = alloc_skb(NLMSG_SPACE(len), GFP_ATOMIC); if (!skb) { - printk(KERN_ERR "netlink_broadcast ret=%d\n", ret); + pr_err("netlink_broadcast ret=%d\n", ret); return -ENOMEM; } @@ -144,8 +147,8 @@ int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) return len; else { if (ret != -ESRCH) { - printk(KERN_ERR "netlink_broadcast g=%d, t=%d, l=%d, r=%d\n", - group, type, len, ret); + pr_err("netlink_broadcast g=%d, t=%d, l=%d, r=%d\n", + group, type, len, ret); } ret = 0; } -- cgit v1.2.3 From c9a796d6a6b8bbfaf5bd6f4fd9fb1c8e04bf9534 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Mon, 29 Oct 2012 20:05:16 +0900 Subject: staging/gdm72xx: Use dev_ printks in gdm_sdio.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_sdio.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_sdio.c b/drivers/staging/gdm72xx/gdm_sdio.c index ca38d719a1f..8b8ed981d10 100644 --- a/drivers/staging/gdm72xx/gdm_sdio.c +++ b/drivers/staging/gdm72xx/gdm_sdio.c @@ -157,7 +157,7 @@ static int init_sdio(struct sdiowm_dev *sdev) tx->sdu_buf = kmalloc(SDU_TX_BUF_SIZE, GFP_KERNEL); if (tx->sdu_buf == NULL) { - printk(KERN_ERR "Failed to allocate SDU tx buffer.\n"); + dev_err(&sdev->func->dev, "Failed to allocate SDU tx buffer.\n"); goto fail; } @@ -186,7 +186,7 @@ static int init_sdio(struct sdiowm_dev *sdev) rx->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL); if (rx->rx_buf == NULL) { - printk(KERN_ERR "Failed to allocate rx buffer.\n"); + dev_err(&sdev->func->dev, "Failed to allocate rx buffer.\n"); goto fail; } @@ -246,7 +246,8 @@ static void send_sdio_pkt(struct sdio_func *func, u8 *data, int len) ret = sdio_memcpy_toio(func, 0, data, n); if (ret < 0) { if (ret != -ENOMEDIUM) - printk(KERN_ERR "gdmwms: %s error: ret = %d\n", + dev_err(&func->dev, + "gdmwms: %s error: ret = %d\n", __func__, ret); goto end_io; } @@ -259,7 +260,8 @@ static void send_sdio_pkt(struct sdio_func *func, u8 *data, int len) ret = sdio_memcpy_toio(func, 0, data + n, remain); if (ret < 0) { if (ret != -ENOMEDIUM) - printk(KERN_ERR "gdmwms: %s error: ret = %d\n", + dev_err(&func->dev, + "gdmwms: %s error: ret = %d\n", __func__, ret); goto end_io; } @@ -522,13 +524,14 @@ static void gdm_sdio_irq(struct sdio_func *func) ret = sdio_memcpy_fromio(func, hdr, 0x0, TYPE_A_LOOKAHEAD_SIZE); if (ret) { - printk(KERN_ERR "Cannot read from function %d\n", func->num); + dev_err(&func->dev, + "Cannot read from function %d\n", func->num); goto done; } len = (hdr[2] << 16) | (hdr[1] << 8) | hdr[0]; if (len > (RX_BUF_SIZE - TYPE_A_HEADER_SIZE)) { - printk(KERN_ERR "Too big Type-A size: %d\n", len); + dev_err(&func->dev, "Too big Type-A size: %d\n", len); goto done; } @@ -562,8 +565,8 @@ static void gdm_sdio_irq(struct sdio_func *func) n = blocks * func->cur_blksize; ret = sdio_memcpy_fromio(func, buf, 0x0, n); if (ret) { - printk(KERN_ERR "Cannot read from function %d\n", - func->num); + dev_err(&func->dev, + "Cannot read from function %d\n", func->num); goto done; } buf += n; @@ -573,8 +576,8 @@ static void gdm_sdio_irq(struct sdio_func *func) if (remain) { ret = sdio_memcpy_fromio(func, buf, 0x0, remain); if (ret) { - printk(KERN_ERR "Cannot read from function %d\n", - func->num); + dev_err(&func->dev, + "Cannot read from function %d\n", func->num); goto done; } } @@ -637,9 +640,9 @@ static int sdio_wimax_probe(struct sdio_func *func, struct phy_dev *phy_dev = NULL; struct sdiowm_dev *sdev = NULL; - printk(KERN_INFO "Found GDM SDIO VID = 0x%04x PID = 0x%04x...\n", - func->vendor, func->device); - printk(KERN_INFO "GCT WiMax driver version %s\n", DRIVER_VERSION); + dev_info(&func->dev, "Found GDM SDIO VID = 0x%04x PID = 0x%04x...\n", + func->vendor, func->device); + dev_info(&func->dev, "GCT WiMax driver version %s\n", DRIVER_VERSION); sdio_claim_host(func); sdio_enable_func(func); -- cgit v1.2.3 From 626e557f3a84f391b8cc5a39ea42c821a1bf67b5 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Mon, 29 Oct 2012 20:05:30 +0900 Subject: staging/gdm72xx: Use dev_ printks in sdio_boot.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/sdio_boot.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/staging/gdm72xx/sdio_boot.c b/drivers/staging/gdm72xx/sdio_boot.c index 38feb1acd8e..6291829dcdc 100644 --- a/drivers/staging/gdm72xx/sdio_boot.c +++ b/drivers/staging/gdm72xx/sdio_boot.c @@ -65,15 +65,15 @@ static int download_image(struct sdio_func *func, const char *img_name) ret = request_firmware(&firm, img_name, &func->dev); if (ret < 0) { - printk(KERN_ERR - "requesting firmware %s failed with error %d\n", + dev_err(&func->dev, + "requesting firmware %s failed with error %d\n", img_name, ret); return ret; } buf = kmalloc(DOWNLOAD_SIZE + TYPE_A_HEADER_SIZE, GFP_KERNEL); if (buf == NULL) { - printk(KERN_ERR "Error: kmalloc\n"); + dev_err(&func->dev, "Error: kmalloc\n"); return -ENOMEM; } @@ -101,8 +101,9 @@ static int download_image(struct sdio_func *func, const char *img_name) memcpy(buf+TYPE_A_HEADER_SIZE, firm->data + pos, len); ret = sdio_memcpy_toio(func, 0, buf, len + TYPE_A_HEADER_SIZE); if (ret < 0) { - printk(KERN_ERR "gdmwm: send image error: " - "packet number = %d ret = %d\n", pno, ret); + dev_err(&func->dev, + "send image error: packet number = %d ret = %d\n", + pno, ret); goto out; } @@ -110,13 +111,14 @@ static int download_image(struct sdio_func *func, const char *img_name) break; if (!ack_ready(func)) { ret = -EIO; - printk(KERN_ERR "gdmwm: Ack is not ready.\n"); + dev_err(&func->dev, "Ack is not ready.\n"); goto out; } ret = sdio_memcpy_fromio(func, buf, 0, TYPE_A_LOOKAHEAD_SIZE); if (ret < 0) { - printk(KERN_ERR "gdmwm: receive ack error: " - "packet number = %d ret = %d\n", pno, ret); + dev_err(&func->dev, + "receive ack error: packet number = %d ret = %d\n", + pno, ret); goto out; } sdio_writeb(func, 0x01, 0x13, &ret); @@ -140,19 +142,20 @@ int sdio_boot(struct sdio_func *func) tx_buf = kmalloc(YMEM0_SIZE, GFP_KERNEL); if (tx_buf == NULL) { - printk(KERN_ERR "Error: kmalloc: %s %d\n", __func__, __LINE__); + dev_err(&func->dev, "Error: kmalloc: %s %d\n", + __func__, __LINE__); return -ENOMEM; } ret = download_image(func, krn_name); if (ret) goto restore_fs; - printk(KERN_INFO "GCT: Kernel download success.\n"); + dev_info(&func->dev, "GCT: Kernel download success.\n"); ret = download_image(func, rfs_name); if (ret) goto restore_fs; - printk(KERN_INFO "GCT: Filesystem download success.\n"); + dev_info(&func->dev, "GCT: Filesystem download success.\n"); restore_fs: kfree(tx_buf); -- cgit v1.2.3 From a7d46832df45a41e880ea39ccd4882d012a589bb Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Mon, 29 Oct 2012 20:05:43 +0900 Subject: staging/gdm72xx: Use dev_ printks in gdm_usb.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/gdm_usb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index 0c9e8958009..0cc63176768 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -305,7 +305,7 @@ static int gdm_usb_send(void *priv_dev, void *data, int len, unsigned long flags; if (!udev->usbdev) { - printk(KERN_ERR "%s: No such device\n", __func__); + dev_err(&usbdev->dev, "%s: No such device\n", __func__); return -ENODEV; } @@ -484,7 +484,7 @@ static int gdm_usb_receive(void *priv_dev, unsigned long flags; if (!udev->usbdev) { - printk(KERN_ERR "%s: No such device\n", __func__); + dev_err(&usbdev->dev, "%s: No such device\n", __func__); return -ENODEV; } @@ -559,9 +559,9 @@ static int gdm_usb_probe(struct usb_interface *intf, idProduct = L2H(usbdev->descriptor.idProduct); bcdDevice = L2H(usbdev->descriptor.bcdDevice); - printk(KERN_INFO "Found GDM USB VID = 0x%04x PID = 0x%04x...\n", - idVendor, idProduct); - printk(KERN_INFO "GCT WiMax driver version %s\n", DRIVER_VERSION); + dev_info(&intf->dev, "Found GDM USB VID = 0x%04x PID = 0x%04x...\n", + idVendor, idProduct); + dev_info(&intf->dev, "GCT WiMax driver version %s\n", DRIVER_VERSION); if (idProduct == EMERGENCY_PID) { -- cgit v1.2.3 From 3800178b94d218cbfe5decf60f48742a73b62301 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Mon, 29 Oct 2012 20:05:57 +0900 Subject: staging/gdm72xx: Use dev_ printks in usb_boot.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gdm72xx/usb_boot.c | 49 +++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/drivers/staging/gdm72xx/usb_boot.c b/drivers/staging/gdm72xx/usb_boot.c index 0787188728a..3e2103ae4ea 100644 --- a/drivers/staging/gdm72xx/usb_boot.c +++ b/drivers/staging/gdm72xx/usb_boot.c @@ -82,7 +82,8 @@ static int gdm_wibro_send(struct usb_device *usbdev, void *data, int len) &actual, 1000); if (ret < 0) { - printk(KERN_ERR "Error : usb_bulk_msg ( result = %d )\n", ret); + dev_err(&usbdev->dev, "Error : usb_bulk_msg ( result = %d )\n", + ret); return ret; } return 0; @@ -97,8 +98,8 @@ static int gdm_wibro_recv(struct usb_device *usbdev, void *data, int len) &actual, 5000); if (ret < 0) { - printk(KERN_ERR "Error : usb_bulk_msg(recv) ( result = %d )\n", - ret); + dev_err(&usbdev->dev, + "Error : usb_bulk_msg(recv) ( result = %d )\n", ret); return ret; } return 0; @@ -150,20 +151,20 @@ int usb_boot(struct usb_device *usbdev, u16 pid) ret = request_firmware(&firm, img_name, &usbdev->dev); if (ret < 0) { - printk(KERN_ERR - "requesting firmware %s failed with error %d\n", + dev_err(&usbdev->dev, + "requesting firmware %s failed with error %d\n", img_name, ret); return ret; } tx_buf = kmalloc(DOWNLOAD_SIZE, GFP_KERNEL); if (tx_buf == NULL) { - printk(KERN_ERR "Error: kmalloc\n"); + dev_err(&usbdev->dev, "Error: kmalloc\n"); return -ENOMEM; } if (firm->size < sizeof(hdr)) { - printk(KERN_ERR "gdmwm: Cannot read the image info.\n"); + dev_err(&usbdev->dev, "Cannot read the image info.\n"); ret = -EIO; goto out; } @@ -172,23 +173,22 @@ int usb_boot(struct usb_device *usbdev, u16 pid) array_le32_to_cpu((u32 *)&hdr, 19); #if 0 if (hdr.magic_code != 0x10767fff) { - printk(KERN_ERR "gdmwm: Invalid magic code 0x%08x\n", + dev_err(&usbdev->dev, "Invalid magic code 0x%08x\n", hdr.magic_code); ret = -EINVAL; goto out; } #endif if (hdr.count > MAX_IMG_CNT) { - printk(KERN_ERR "gdmwm: Too many images. %d\n", hdr.count); + dev_err(&usbdev->dev, "Too many images. %d\n", hdr.count); ret = -EINVAL; goto out; } for (i = 0; i < hdr.count; i++) { if (hdr.offset[i] > hdr.len) { - printk(KERN_ERR "gdmwm: Invalid offset. " - "Entry = %d Offset = 0x%08x " - "Image length = 0x%08x\n", + dev_err(&usbdev->dev, + "Invalid offset. Entry = %d Offset = 0x%08x Image length = 0x%08x\n", i, hdr.offset[i], hdr.len); ret = -EINVAL; goto out; @@ -196,7 +196,7 @@ int usb_boot(struct usb_device *usbdev, u16 pid) pos = hdr.offset[i]; if (firm->size < sizeof(fw_info) + pos) { - printk(KERN_ERR "gdmwm: Cannot read the FW info.\n"); + dev_err(&usbdev->dev, "Cannot read the FW info.\n"); ret = -EIO; goto out; } @@ -205,7 +205,7 @@ int usb_boot(struct usb_device *usbdev, u16 pid) array_le32_to_cpu((u32 *)&fw_info, 8); #if 0 if ((fw_info.id & 0xfffff000) != 0x10767000) { - printk(KERN_ERR "gdmwm: Invalid FW id. 0x%08x\n", + dev_err(&usbdev->dev, "Invalid FW id. 0x%08x\n", fw_info.id); ret = -EIO; goto out; @@ -217,7 +217,7 @@ int usb_boot(struct usb_device *usbdev, u16 pid) pos = hdr.offset[i] + fw_info.kernel_offset; if (firm->size < fw_info.kernel_len + pos) { - printk(KERN_ERR "gdmwm: Kernel FW is too small.\n"); + dev_err(&usbdev->dev, "Kernel FW is too small.\n"); goto out; } @@ -225,24 +225,25 @@ int usb_boot(struct usb_device *usbdev, u16 pid) fw_info.kernel_len, DN_KERNEL_MAGIC_NUMBER); if (ret < 0) goto out; - printk(KERN_INFO "GCT: Kernel download success.\n"); + dev_info(&usbdev->dev, "GCT: Kernel download success.\n"); pos = hdr.offset[i] + fw_info.rootfs_offset; if (firm->size < fw_info.rootfs_len + pos) { - printk(KERN_ERR "gdmwm: Filesystem FW is too small.\n"); + dev_err(&usbdev->dev, "Filesystem FW is too small.\n"); goto out; } ret = download_image(usbdev, firm, pos, fw_info.rootfs_len, DN_ROOTFS_MAGIC_NUMBER); if (ret < 0) goto out; - printk(KERN_INFO "GCT: Filesystem download success.\n"); + dev_info(&usbdev->dev, "GCT: Filesystem download success.\n"); break; } if (i == hdr.count) { - printk(KERN_ERR "Firmware for gsk%x is not installed.\n", pid); + dev_err(&usbdev->dev, "Firmware for gsk%x is not installed.\n", + pid); ret = -EINVAL; } out: @@ -293,15 +294,15 @@ static int em_download_image(struct usb_device *usbdev, const char *img_name, ret = request_firmware(&firm, img_name, &usbdev->dev); if (ret < 0) { - printk(KERN_ERR - "requesting firmware %s failed with error %d\n", + dev_err(&usbdev->dev, + "requesting firmware %s failed with error %d\n", img_name, ret); return ret; } buf = kmalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL); if (buf == NULL) { - printk(KERN_ERR "Error: kmalloc\n"); + dev_err(&usbdev->dev, "Error: kmalloc\n"); return -ENOMEM; } @@ -366,12 +367,12 @@ int usb_emergency(struct usb_device *usbdev) ret = em_download_image(usbdev, kern_name, KERNEL_TYPE_STRING); if (ret < 0) return ret; - printk(KERN_INFO "GCT Emergency: Kernel download success.\n"); + dev_err(&usbdev->dev, "GCT Emergency: Kernel download success.\n"); ret = em_download_image(usbdev, fs_name, FS_TYPE_STRING); if (ret < 0) return ret; - printk(KERN_INFO "GCT Emergency: Filesystem download success.\n"); + dev_info(&usbdev->dev, "GCT Emergency: Filesystem download success.\n"); ret = em_fw_reset(usbdev); -- cgit v1.2.3 From ac56d89aced80133ab9ca783930602c3be4e03c8 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 29 Oct 2012 23:08:46 -0400 Subject: Staging: bcm: Correctly format comments in CmHost.h This patch correctly formats comments in CmHost.h as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.h | 102 +++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index 1c5a07c7bbe..ab5103c41e5 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -1,72 +1,72 @@ -/// ************************************************************************** -/// (c) Beceem Communications Inc. -/// All Rights Reserved -/// -/// \file : CmHost.h -/// \author : Rajeev Tirumala -/// \date : September 8 , 2006 -/// \brief : Definitions for Connection Management Requests structure -/// which we will use to setup our connection structures.Its high -/// time we had a header file for CmHost.cpp to isolate the way -/// f/w sends DSx messages and the way we interpret them in code. -/// Revision History -/// -/// Date Author Version Description -/// 08-Sep-06 Rajeev 0.1 Created -/// ************************************************************************** +/*************************************************************************** + * (c) Beceem Communications Inc. + * All Rights Reserved + * + * file : CmHost.h + * author: Rajeev Tirumala + * date : September 8 , 2006 + * brief : Definitions for Connection Management Requests structure + * which we will use to setup our connection structures.Its high + * time we had a header file for CmHost.cpp to isolate the way + * f/w sends DSx messages and the way we interpret them in code. + * Revision History + * + * Date Author Version Description + * 08-Sep-06 Rajeev 0.1 Created + ***************************************************************************/ #ifndef _CM_HOST_H #define _CM_HOST_H #pragma once #pragma pack (push,4) -#define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 // This contains the pointer -#define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 // 24 K Bytes +#define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 /* This contains the pointer */ +#define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 /* 24 K Bytes */ -/// \brief structure stLocalSFAddRequest +/* brief structure stLocalSFAddRequest */ typedef struct stLocalSFAddRequestAlt{ B_UINT8 u8Type; B_UINT8 u8Direction; B_UINT16 u16TID; - /// \brief 16bitCID + /* brief 16bitCID */ B_UINT16 u16CID; - /// \brief 16bitVCID + /* brief 16bitVCID */ B_UINT16 u16VCID; struct bcm_connect_mgr_params sfParameterSet; - //USE_MEMORY_MANAGER(); + /* USE_MEMORY_MANAGER(); */ }stLocalSFAddRequestAlt; -/// \brief structure stLocalSFAddIndication +/* brief structure stLocalSFAddIndication */ typedef struct stLocalSFAddIndicationAlt{ B_UINT8 u8Type; B_UINT8 u8Direction; B_UINT16 u16TID; - /// \brief 16bitCID +/* brief 16bitCID */ B_UINT16 u16CID; - /// \brief 16bitVCID + /* brief 16bitVCID */ B_UINT16 u16VCID; struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; - B_UINT8 u8CC; /**< Confirmation Code*/ - B_UINT8 u8Padd; /**< 8-bit Padding */ - B_UINT16 u16Padd; /**< 16 bit Padding */ -// USE_MEMORY_MANAGER(); + B_UINT8 u8CC; /* < Confirmation Code */ + B_UINT8 u8Padd; /* < 8-bit Padding */ + B_UINT16 u16Padd; /* < 16 bit Padding */ +/* USE_MEMORY_MANAGER(); */ }stLocalSFAddIndicationAlt; -/// \brief structure stLocalSFAddConfirmation +/* brief structure stLocalSFAddConfirmation */ typedef struct stLocalSFAddConfirmationAlt{ B_UINT8 u8Type; B_UINT8 u8Direction; B_UINT16 u16TID; - /// \brief 16bitCID + /* brief 16bitCID */ B_UINT16 u16CID; - /// \brief 16bitVCID + /* brief 16bitVCID */ B_UINT16 u16VCID; struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; @@ -74,38 +74,38 @@ typedef struct stLocalSFAddConfirmationAlt{ }stLocalSFAddConfirmationAlt; -/// \brief structure stLocalSFChangeRequest +/* brief structure stLocalSFChangeRequest */ typedef struct stLocalSFChangeRequestAlt{ B_UINT8 u8Type; B_UINT8 u8Direction; B_UINT16 u16TID; - /// \brief 16bitCID + /* brief 16bitCID */ B_UINT16 u16CID; - /// \brief 16bitVCID + /* brief 16bitVCID */ B_UINT16 u16VCID; /* - //Pointer location at which following connection manager param Structure can be read - //from the target. We only get the address location and we need to read out the - //entire connection manager param structure at the given location on target - */ + * Pointer location at which following connection manager param Structure can be read + * from the target. We only get the address location and we need to read out the + * entire connection manager param structure at the given location on target + */ struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; - B_UINT8 u8CC; /**< Confirmation Code*/ - B_UINT8 u8Padd; /**< 8-bit Padding */ - B_UINT16 u16Padd; /**< 16 bit */ + B_UINT8 u8CC; /* < Confirmation Code */ + B_UINT8 u8Padd; /* < 8-bit Padding */ + B_UINT16 u16Padd; /* < 16 bit */ }stLocalSFChangeRequestAlt; -/// \brief structure stLocalSFChangeConfirmation +/* brief structure stLocalSFChangeConfirmation */ typedef struct stLocalSFChangeConfirmationAlt{ B_UINT8 u8Type; B_UINT8 u8Direction; B_UINT16 u16TID; - /// \brief 16bitCID + /* brief 16bitCID */ B_UINT16 u16CID; - /// \brief 16bitVCID + /* brief 16bitVCID */ B_UINT16 u16VCID; struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; @@ -113,22 +113,22 @@ typedef struct stLocalSFChangeConfirmationAlt{ }stLocalSFChangeConfirmationAlt; -/// \brief structure stLocalSFChangeIndication +/* brief structure stLocalSFChangeIndication */ typedef struct stLocalSFChangeIndicationAlt{ B_UINT8 u8Type; B_UINT8 u8Direction; B_UINT16 u16TID; - /// \brief 16bitCID + /* brief 16bitCID */ B_UINT16 u16CID; - /// \brief 16bitVCID + /* brief 16bitVCID */ B_UINT16 u16VCID; struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; - B_UINT8 u8CC; /**< Confirmation Code*/ - B_UINT8 u8Padd; /**< 8-bit Padding */ - B_UINT16 u16Padd; /**< 16 bit */ + B_UINT8 u8CC; /* < Confirmation Code */ + B_UINT8 u8Padd; /* < 8-bit Padding */ + B_UINT16 u16Padd; /* < 16 bit */ }stLocalSFChangeIndicationAlt; -- cgit v1.2.3 From feec3d78d10d459d695d3999fdd2df0f63a20e82 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 29 Oct 2012 23:08:47 -0400 Subject: Staging: bcm: Fix all white space issues in CmHost.h This patch fixes all white space issues in CmHost.h as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.h | 129 +++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 72 deletions(-) diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index ab5103c41e5..4c33caa6874 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -18,71 +18,65 @@ #define _CM_HOST_H #pragma once -#pragma pack (push,4) +#pragma pack(push, 4) -#define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 /* This contains the pointer */ -#define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 /* 24 K Bytes */ +#define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 /* This contains the pointer */ +#define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 /* 24 K Bytes */ /* brief structure stLocalSFAddRequest */ -typedef struct stLocalSFAddRequestAlt{ - B_UINT8 u8Type; - B_UINT8 u8Direction; - - B_UINT16 u16TID; +typedef struct stLocalSFAddRequestAlt { + B_UINT8 u8Type; + B_UINT8 u8Direction; + B_UINT16 u16TID; /* brief 16bitCID */ - B_UINT16 u16CID; + B_UINT16 u16CID; /* brief 16bitVCID */ - B_UINT16 u16VCID; - - + B_UINT16 u16VCID; struct bcm_connect_mgr_params sfParameterSet; - /* USE_MEMORY_MANAGER(); */ -}stLocalSFAddRequestAlt; +} stLocalSFAddRequestAlt; /* brief structure stLocalSFAddIndication */ -typedef struct stLocalSFAddIndicationAlt{ - B_UINT8 u8Type; - B_UINT8 u8Direction; - B_UINT16 u16TID; -/* brief 16bitCID */ - B_UINT16 u16CID; +typedef struct stLocalSFAddIndicationAlt { + B_UINT8 u8Type; + B_UINT8 u8Direction; + B_UINT16 u16TID; + /* brief 16bitCID */ + B_UINT16 u16CID; /* brief 16bitVCID */ - B_UINT16 u16VCID; + B_UINT16 u16VCID; struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; - - B_UINT8 u8CC; /* < Confirmation Code */ - B_UINT8 u8Padd; /* < 8-bit Padding */ - B_UINT16 u16Padd; /* < 16 bit Padding */ + B_UINT8 u8CC; /* < Confirmation Code */ + B_UINT8 u8Padd; /* < 8-bit Padding */ + B_UINT16 u16Padd; /* < 16 bit Padding */ /* USE_MEMORY_MANAGER(); */ -}stLocalSFAddIndicationAlt; +} stLocalSFAddIndicationAlt; /* brief structure stLocalSFAddConfirmation */ -typedef struct stLocalSFAddConfirmationAlt{ - B_UINT8 u8Type; - B_UINT8 u8Direction; - B_UINT16 u16TID; +typedef struct stLocalSFAddConfirmationAlt { + B_UINT8 u8Type; + B_UINT8 u8Direction; + B_UINT16 u16TID; /* brief 16bitCID */ - B_UINT16 u16CID; + B_UINT16 u16CID; /* brief 16bitVCID */ - B_UINT16 u16VCID; + B_UINT16 u16VCID; struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; -}stLocalSFAddConfirmationAlt; - +} stLocalSFAddConfirmationAlt; /* brief structure stLocalSFChangeRequest */ -typedef struct stLocalSFChangeRequestAlt{ - B_UINT8 u8Type; - B_UINT8 u8Direction; - B_UINT16 u16TID; +typedef struct stLocalSFChangeRequestAlt { + B_UINT8 u8Type; + B_UINT8 u8Direction; + B_UINT16 u16TID; /* brief 16bitCID */ - B_UINT16 u16CID; + B_UINT16 u16CID; /* brief 16bitVCID */ - B_UINT16 u16VCID; + B_UINT16 u16VCID; /* * Pointer location at which following connection manager param Structure can be read * from the target. We only get the address location and we need to read out the @@ -91,57 +85,48 @@ typedef struct stLocalSFChangeRequestAlt{ struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; - - B_UINT8 u8CC; /* < Confirmation Code */ - B_UINT8 u8Padd; /* < 8-bit Padding */ - B_UINT16 u16Padd; /* < 16 bit */ - -}stLocalSFChangeRequestAlt; + B_UINT8 u8CC; /* < Confirmation Code */ + B_UINT8 u8Padd; /* < 8-bit Padding */ + B_UINT16 u16Padd; /* < 16 bit */ +} stLocalSFChangeRequestAlt; /* brief structure stLocalSFChangeConfirmation */ -typedef struct stLocalSFChangeConfirmationAlt{ - B_UINT8 u8Type; - B_UINT8 u8Direction; - B_UINT16 u16TID; +typedef struct stLocalSFChangeConfirmationAlt { + B_UINT8 u8Type; + B_UINT8 u8Direction; + B_UINT16 u16TID; /* brief 16bitCID */ - B_UINT16 u16CID; + B_UINT16 u16CID; /* brief 16bitVCID */ - B_UINT16 u16VCID; + B_UINT16 u16VCID; struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; - -}stLocalSFChangeConfirmationAlt; +} stLocalSFChangeConfirmationAlt; /* brief structure stLocalSFChangeIndication */ -typedef struct stLocalSFChangeIndicationAlt{ - B_UINT8 u8Type; - B_UINT8 u8Direction; - B_UINT16 u16TID; +typedef struct stLocalSFChangeIndicationAlt { + B_UINT8 u8Type; + B_UINT8 u8Direction; + B_UINT16 u16TID; /* brief 16bitCID */ - B_UINT16 u16CID; + B_UINT16 u16CID; /* brief 16bitVCID */ - B_UINT16 u16VCID; + B_UINT16 u16VCID; struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; + B_UINT8 u8CC; /* < Confirmation Code */ + B_UINT8 u8Padd; /* < 8-bit Padding */ + B_UINT16 u16Padd; /* < 16 bit */ +} stLocalSFChangeIndicationAlt; - B_UINT8 u8CC; /* < Confirmation Code */ - B_UINT8 u8Padd; /* < 8-bit Padding */ - B_UINT16 u16Padd; /* < 16 bit */ - -}stLocalSFChangeIndicationAlt; - -ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer,UINT *puBufferLength); - +ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength); INT AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); - INT FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter); - BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer); - -#pragma pack (pop) +#pragma pack(pop) #endif -- cgit v1.2.3 From 64d74ab6084faa174ea63ae2f33fd930546f47fa Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 29 Oct 2012 23:08:48 -0400 Subject: Staging: bcm: Change B_UINT16 to u16 in CmHost.h This patch changes B_UINT16 to u16 in CmHost.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.h | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index 4c33caa6874..e043a5b49f7 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -27,11 +27,11 @@ typedef struct stLocalSFAddRequestAlt { B_UINT8 u8Type; B_UINT8 u8Direction; - B_UINT16 u16TID; + u16 u16TID; /* brief 16bitCID */ - B_UINT16 u16CID; + u16 u16CID; /* brief 16bitVCID */ - B_UINT16 u16VCID; + u16 u16VCID; struct bcm_connect_mgr_params sfParameterSet; /* USE_MEMORY_MANAGER(); */ } stLocalSFAddRequestAlt; @@ -40,17 +40,17 @@ typedef struct stLocalSFAddRequestAlt { typedef struct stLocalSFAddIndicationAlt { B_UINT8 u8Type; B_UINT8 u8Direction; - B_UINT16 u16TID; + u16 u16TID; /* brief 16bitCID */ - B_UINT16 u16CID; + u16 u16CID; /* brief 16bitVCID */ - B_UINT16 u16VCID; + u16 u16VCID; struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; B_UINT8 u8CC; /* < Confirmation Code */ B_UINT8 u8Padd; /* < 8-bit Padding */ - B_UINT16 u16Padd; /* < 16 bit Padding */ + u16 u16Padd; /* < 16 bit Padding */ /* USE_MEMORY_MANAGER(); */ } stLocalSFAddIndicationAlt; @@ -58,11 +58,11 @@ typedef struct stLocalSFAddIndicationAlt { typedef struct stLocalSFAddConfirmationAlt { B_UINT8 u8Type; B_UINT8 u8Direction; - B_UINT16 u16TID; + u16 u16TID; /* brief 16bitCID */ - B_UINT16 u16CID; + u16 u16CID; /* brief 16bitVCID */ - B_UINT16 u16VCID; + u16 u16VCID; struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; @@ -72,11 +72,11 @@ typedef struct stLocalSFAddConfirmationAlt { typedef struct stLocalSFChangeRequestAlt { B_UINT8 u8Type; B_UINT8 u8Direction; - B_UINT16 u16TID; + u16 u16TID; /* brief 16bitCID */ - B_UINT16 u16CID; + u16 u16CID; /* brief 16bitVCID */ - B_UINT16 u16VCID; + u16 u16VCID; /* * Pointer location at which following connection manager param Structure can be read * from the target. We only get the address location and we need to read out the @@ -87,18 +87,18 @@ typedef struct stLocalSFChangeRequestAlt { struct bcm_connect_mgr_params sfActiveSet; B_UINT8 u8CC; /* < Confirmation Code */ B_UINT8 u8Padd; /* < 8-bit Padding */ - B_UINT16 u16Padd; /* < 16 bit */ + u16 u16Padd; /* < 16 bit */ } stLocalSFChangeRequestAlt; /* brief structure stLocalSFChangeConfirmation */ typedef struct stLocalSFChangeConfirmationAlt { B_UINT8 u8Type; B_UINT8 u8Direction; - B_UINT16 u16TID; + u16 u16TID; /* brief 16bitCID */ - B_UINT16 u16CID; + u16 u16CID; /* brief 16bitVCID */ - B_UINT16 u16VCID; + u16 u16VCID; struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; @@ -108,17 +108,17 @@ typedef struct stLocalSFChangeConfirmationAlt { typedef struct stLocalSFChangeIndicationAlt { B_UINT8 u8Type; B_UINT8 u8Direction; - B_UINT16 u16TID; + u16 u16TID; /* brief 16bitCID */ - B_UINT16 u16CID; + u16 u16CID; /* brief 16bitVCID */ - B_UINT16 u16VCID; + u16 u16VCID; struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; B_UINT8 u8CC; /* < Confirmation Code */ B_UINT8 u8Padd; /* < 8-bit Padding */ - B_UINT16 u16Padd; /* < 16 bit */ + u16 u16Padd; /* < 16 bit */ } stLocalSFChangeIndicationAlt; ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength); -- cgit v1.2.3 From 264af7ec635e6cc2c282d8269f32fe35ce960aba Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 29 Oct 2012 23:08:49 -0400 Subject: Staging: bcm: Change B_UINT8 to u8 in CmHost.h This patch changes B_UINT8 to u8 in CmHost.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index e043a5b49f7..6138f501a18 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -25,8 +25,8 @@ /* brief structure stLocalSFAddRequest */ typedef struct stLocalSFAddRequestAlt { - B_UINT8 u8Type; - B_UINT8 u8Direction; + u8 u8Type; + u8 u8Direction; u16 u16TID; /* brief 16bitCID */ u16 u16CID; @@ -38,8 +38,8 @@ typedef struct stLocalSFAddRequestAlt { /* brief structure stLocalSFAddIndication */ typedef struct stLocalSFAddIndicationAlt { - B_UINT8 u8Type; - B_UINT8 u8Direction; + u8 u8Type; + u8 u8Direction; u16 u16TID; /* brief 16bitCID */ u16 u16CID; @@ -48,16 +48,16 @@ typedef struct stLocalSFAddIndicationAlt { struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; - B_UINT8 u8CC; /* < Confirmation Code */ - B_UINT8 u8Padd; /* < 8-bit Padding */ + u8 u8CC; /* < Confirmation Code */ + u8 u8Padd; /* < 8-bit Padding */ u16 u16Padd; /* < 16 bit Padding */ /* USE_MEMORY_MANAGER(); */ } stLocalSFAddIndicationAlt; /* brief structure stLocalSFAddConfirmation */ typedef struct stLocalSFAddConfirmationAlt { - B_UINT8 u8Type; - B_UINT8 u8Direction; + u8 u8Type; + u8 u8Direction; u16 u16TID; /* brief 16bitCID */ u16 u16CID; @@ -70,8 +70,8 @@ typedef struct stLocalSFAddConfirmationAlt { /* brief structure stLocalSFChangeRequest */ typedef struct stLocalSFChangeRequestAlt { - B_UINT8 u8Type; - B_UINT8 u8Direction; + u8 u8Type; + u8 u8Direction; u16 u16TID; /* brief 16bitCID */ u16 u16CID; @@ -85,15 +85,15 @@ typedef struct stLocalSFChangeRequestAlt { struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; - B_UINT8 u8CC; /* < Confirmation Code */ - B_UINT8 u8Padd; /* < 8-bit Padding */ + u8 u8CC; /* < Confirmation Code */ + u8 u8Padd; /* < 8-bit Padding */ u16 u16Padd; /* < 16 bit */ } stLocalSFChangeRequestAlt; /* brief structure stLocalSFChangeConfirmation */ typedef struct stLocalSFChangeConfirmationAlt { - B_UINT8 u8Type; - B_UINT8 u8Direction; + u8 u8Type; + u8 u8Direction; u16 u16TID; /* brief 16bitCID */ u16 u16CID; @@ -106,8 +106,8 @@ typedef struct stLocalSFChangeConfirmationAlt { /* brief structure stLocalSFChangeIndication */ typedef struct stLocalSFChangeIndicationAlt { - B_UINT8 u8Type; - B_UINT8 u8Direction; + u8 u8Type; + u8 u8Direction; u16 u16TID; /* brief 16bitCID */ u16 u16CID; @@ -116,8 +116,8 @@ typedef struct stLocalSFChangeIndicationAlt { struct bcm_connect_mgr_params sfAuthorizedSet; struct bcm_connect_mgr_params sfAdmittedSet; struct bcm_connect_mgr_params sfActiveSet; - B_UINT8 u8CC; /* < Confirmation Code */ - B_UINT8 u8Padd; /* < 8-bit Padding */ + u8 u8CC; /* < Confirmation Code */ + u8 u8Padd; /* < 8-bit Padding */ u16 u16Padd; /* < 16 bit */ } stLocalSFChangeIndicationAlt; -- cgit v1.2.3 From 049e52c1881ff8b332d37422c7fba5f1c3974e87 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 29 Oct 2012 23:08:50 -0400 Subject: Staging: bcm: Change INT to int in CmHost.h This patch changes INT to int in CmHost.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index 6138f501a18..055d2e0385e 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -122,8 +122,8 @@ typedef struct stLocalSFChangeIndicationAlt { } stLocalSFChangeIndicationAlt; ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength); -INT AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); -INT FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); +int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); +int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter); BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer); -- cgit v1.2.3 From 617849119a1bad8036b6f233015298552087efd6 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 29 Oct 2012 23:08:51 -0400 Subject: Staging: bcm: Change ULONG to unsigned long in CmHost.h This patch changes ULONG to unsigned long in CmHost.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index 055d2e0385e..fd117e72b60 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -121,10 +121,10 @@ typedef struct stLocalSFChangeIndicationAlt { u16 u16Padd; /* < 16 bit */ } stLocalSFChangeIndicationAlt; -ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength); +unsigned long StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength); int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); -ULONG SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter); +unsigned long SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter); BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer); #pragma pack(pop) -- cgit v1.2.3 From 9e90bc86d531a5f6e4caf98c4c91ea3097bf9345 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 29 Oct 2012 23:08:52 -0400 Subject: Staging: bcm: Change UINT to unsigned int in CmHost.h This patch changes UINT to unsigned int in CmHost.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index fd117e72b60..d1a86758345 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -121,7 +121,7 @@ typedef struct stLocalSFChangeIndicationAlt { u16 u16Padd; /* < 16 bit */ } stLocalSFChangeIndicationAlt; -unsigned long StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength); +unsigned long StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, unsigned int *puBufferLength); int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); unsigned long SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter); -- cgit v1.2.3 From b7945344bd153c4f0994c1510f2cd840312d15ae Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 29 Oct 2012 23:08:53 -0400 Subject: Staging: bcm: Change PVOID to void * in CmHost.h This patch changes PVOID to void * in CmHost.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index d1a86758345..7dd05227ca2 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -121,11 +121,11 @@ typedef struct stLocalSFChangeIndicationAlt { u16 u16Padd; /* < 16 bit */ } stLocalSFChangeIndicationAlt; -unsigned long StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, unsigned int *puBufferLength); +unsigned long StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, void *pvBuffer, unsigned int *puBufferLength); int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); int FreeAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); unsigned long SetUpTargetDsxBuffers(struct bcm_mini_adapter *Adapter); -BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer); +BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, void *pvBuffer); #pragma pack(pop) -- cgit v1.2.3 From 497f1d5c5e520dca0285276363349e4ae263d2cb Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 29 Oct 2012 23:08:54 -0400 Subject: Staging: bcm: Remove typedef for stLocalSFChangeIndicationAlt and call directly. This patch removes typedef for stLocalSFChangeIndicationAlt, changes the name of the struct to bcm_change_indication, and removes a comment. In addition, any calls to typedef stLocalSFChangeIndicationAlt are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.c | 20 ++++++++++---------- drivers/staging/bcm/CmHost.h | 5 ++--- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 48302ee7ebf..df538386c77 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1635,7 +1635,7 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* PLength = sizeof(stLocalSFChangeIndicationAlt); - pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication; + pLeader->PLength = sizeof(struct bcm_change_indication); + pstChangeIndication = (struct bcm_change_indication *)pstAddIndication; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC RESPONSE TO MAC %d", pLeader->PLength); - *((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; - ((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP; + *((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; + ((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP; CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp); kfree(pstAddIndication); @@ -1786,17 +1786,17 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* PLength = sizeof(stLocalSFChangeIndicationAlt); - pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication; + pLeader->PLength = sizeof(struct bcm_change_indication); + pstChangeIndication = (struct bcm_change_indication *)pstAddIndication; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSC ACK TO MAC %d", pLeader->PLength); - *((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; - ((stLocalSFChangeIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK; + *((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstChangeIndication; + ((struct bcm_change_indication *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_ACK; } case DSC_ACK: { UINT uiSearchRuleIndex = 0; - pstChangeIndication = (stLocalSFChangeIndicationAlt *)pstAddIndication; + pstChangeIndication = (struct bcm_change_indication *)pstAddIndication; uiSearchRuleIndex = SearchSfid(Adapter, ntohl(pstChangeIndication->sfActiveSet.u32SFID)); if (uiSearchRuleIndex > NO_OF_QUEUES-1) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "SF doesn't exist for which DSC_ACK is received"); diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index 7dd05227ca2..6e79e970069 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -104,8 +104,7 @@ typedef struct stLocalSFChangeConfirmationAlt { struct bcm_connect_mgr_params sfActiveSet; } stLocalSFChangeConfirmationAlt; -/* brief structure stLocalSFChangeIndication */ -typedef struct stLocalSFChangeIndicationAlt { +struct bcm_change_indication { u8 u8Type; u8 u8Direction; u16 u16TID; @@ -119,7 +118,7 @@ typedef struct stLocalSFChangeIndicationAlt { u8 u8CC; /* < Confirmation Code */ u8 u8Padd; /* < 8-bit Padding */ u16 u16Padd; /* < 16 bit */ -} stLocalSFChangeIndicationAlt; +}; unsigned long StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, void *pvBuffer, unsigned int *puBufferLength); int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter); -- cgit v1.2.3 From 611c53f3b1d2108735e9e4647968dd59e09d8480 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 29 Oct 2012 23:08:55 -0400 Subject: Staging: bcm: Remove typedef stLocalSFChangeConfirmationAlt. This patch removes typedef stLocalSFChangeConfirmationAlt in CmHost.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index 6e79e970069..2b963de647d 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -90,20 +90,6 @@ typedef struct stLocalSFChangeRequestAlt { u16 u16Padd; /* < 16 bit */ } stLocalSFChangeRequestAlt; -/* brief structure stLocalSFChangeConfirmation */ -typedef struct stLocalSFChangeConfirmationAlt { - u8 u8Type; - u8 u8Direction; - u16 u16TID; - /* brief 16bitCID */ - u16 u16CID; - /* brief 16bitVCID */ - u16 u16VCID; - struct bcm_connect_mgr_params sfAuthorizedSet; - struct bcm_connect_mgr_params sfAdmittedSet; - struct bcm_connect_mgr_params sfActiveSet; -} stLocalSFChangeConfirmationAlt; - struct bcm_change_indication { u8 u8Type; u8 u8Direction; -- cgit v1.2.3 From a202040a813e9f2cffc4e17f0fff783351043a8f Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 29 Oct 2012 23:08:56 -0400 Subject: Staging: bcm: Remove typedef stLocalSFChangeRequestAlt. This patch removes typedef stLocalSFChangeRequestAlt in CmHost.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.h | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index 2b963de647d..5702ac7dbbe 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -68,28 +68,6 @@ typedef struct stLocalSFAddConfirmationAlt { struct bcm_connect_mgr_params sfActiveSet; } stLocalSFAddConfirmationAlt; -/* brief structure stLocalSFChangeRequest */ -typedef struct stLocalSFChangeRequestAlt { - u8 u8Type; - u8 u8Direction; - u16 u16TID; - /* brief 16bitCID */ - u16 u16CID; - /* brief 16bitVCID */ - u16 u16VCID; - /* - * Pointer location at which following connection manager param Structure can be read - * from the target. We only get the address location and we need to read out the - * entire connection manager param structure at the given location on target - */ - struct bcm_connect_mgr_params sfAuthorizedSet; - struct bcm_connect_mgr_params sfAdmittedSet; - struct bcm_connect_mgr_params sfActiveSet; - u8 u8CC; /* < Confirmation Code */ - u8 u8Padd; /* < 8-bit Padding */ - u16 u16Padd; /* < 16 bit */ -} stLocalSFChangeRequestAlt; - struct bcm_change_indication { u8 u8Type; u8 u8Direction; -- cgit v1.2.3 From a0e9ad31d4a90bb5d999070bec0dff0cc7960603 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 29 Oct 2012 23:08:57 -0400 Subject: Staging: bcm: Remove typedef stLocalSFAddConfirmationAlt. This patch removes typedef stLocalSFAddConfirmationAlt in CmHost.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index 5702ac7dbbe..8572defa83f 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -54,20 +54,6 @@ typedef struct stLocalSFAddIndicationAlt { /* USE_MEMORY_MANAGER(); */ } stLocalSFAddIndicationAlt; -/* brief structure stLocalSFAddConfirmation */ -typedef struct stLocalSFAddConfirmationAlt { - u8 u8Type; - u8 u8Direction; - u16 u16TID; - /* brief 16bitCID */ - u16 u16CID; - /* brief 16bitVCID */ - u16 u16VCID; - struct bcm_connect_mgr_params sfAuthorizedSet; - struct bcm_connect_mgr_params sfAdmittedSet; - struct bcm_connect_mgr_params sfActiveSet; -} stLocalSFAddConfirmationAlt; - struct bcm_change_indication { u8 u8Type; u8 u8Direction; -- cgit v1.2.3 From e07384adc6baea2cb9cd20947f6753b78e5b2b42 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Tue, 30 Oct 2012 11:26:13 +0900 Subject: staging: csr: Remove struct CsrEvent Nobody use struct CsrEvent. So, remove it. Signed-off-by: SeongJae Park Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_framework_ext_types.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/csr/csr_framework_ext_types.h b/drivers/staging/csr/csr_framework_ext_types.h index 627556a04ea..575598cf69b 100644 --- a/drivers/staging/csr/csr_framework_ext_types.h +++ b/drivers/staging/csr/csr_framework_ext_types.h @@ -19,24 +19,10 @@ #ifdef __KERNEL__ -struct CsrEvent { - /* wait_queue for waking the kernel thread */ - wait_queue_head_t wakeup_q; - unsigned int wakeup_flag; -}; - -typedef struct CsrEvent CsrEventHandle; typedef struct semaphore CsrMutexHandle; #else /* __KERNEL __ */ -struct CsrEvent { - pthread_cond_t event; - pthread_mutex_t mutex; - u32 eventBits; -}; - -typedef struct CsrEvent CsrEventHandle; typedef pthread_mutex_t CsrMutexHandle; #endif /* __KERNEL__ */ -- cgit v1.2.3 From 56b468fc709b2b962cd91e6cd9f087c3cd095283 Mon Sep 17 00:00:00 2001 From: Anmol Sarma Date: Tue, 30 Oct 2012 22:35:43 +0530 Subject: Staging: android: binder: Fixed multi-line strings Changed all user visible multi-line strings to single line. Removed 'binder:' prefix on stings. Signed-off-by: Anmol Sarma Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/binder.c | 376 ++++++++++++++++----------------------- 1 file changed, 153 insertions(+), 223 deletions(-) diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c index 9fbc06e5012..4a36e9ab8cf 100644 --- a/drivers/staging/android/binder.c +++ b/drivers/staging/android/binder.c @@ -15,6 +15,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -434,12 +436,12 @@ static void binder_set_nice(long nice) } min_nice = 20 - current->signal->rlim[RLIMIT_NICE].rlim_cur; binder_debug(BINDER_DEBUG_PRIORITY_CAP, - "binder: %d: nice value %ld not allowed use " - "%ld instead\n", current->pid, nice, min_nice); + "%d: nice value %ld not allowed use %ld instead\n", + current->pid, nice, min_nice); set_user_nice(current, min_nice); if (min_nice < 20) return; - binder_user_error("binder: %d RLIMIT_NICE not set\n", current->pid); + binder_user_error("%d RLIMIT_NICE not set\n", current->pid); } static size_t binder_buffer_size(struct binder_proc *proc, @@ -466,8 +468,8 @@ static void binder_insert_free_buffer(struct binder_proc *proc, new_buffer_size = binder_buffer_size(proc, new_buffer); binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: add free buffer, size %zd, " - "at %p\n", proc->pid, new_buffer_size, new_buffer); + "%d: add free buffer, size %zd, at %p\n", + proc->pid, new_buffer_size, new_buffer); while (*p) { parent = *p; @@ -545,7 +547,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, struct mm_struct *mm; binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: %s pages %p-%p\n", proc->pid, + "%d: %s pages %p-%p\n", proc->pid, allocate ? "allocate" : "free", start, end); if (end <= start) @@ -562,7 +564,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, down_write(&mm->mmap_sem); vma = proc->vma; if (vma && mm != proc->vma_vm_mm) { - pr_err("binder: %d: vma mm and task mm mismatch\n", + pr_err("%d: vma mm and task mm mismatch\n", proc->pid); vma = NULL; } @@ -572,8 +574,8 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, goto free_range; if (vma == NULL) { - pr_err("binder: %d: binder_alloc_buf failed to " - "map pages in userspace, no vma\n", proc->pid); + pr_err("%d: binder_alloc_buf failed to map pages in userspace, no vma\n", + proc->pid); goto err_no_vma; } @@ -585,8 +587,8 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, BUG_ON(*page); *page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO); if (*page == NULL) { - pr_err("binder: %d: binder_alloc_buf failed " - "for page at %p\n", proc->pid, page_addr); + pr_err("%d: binder_alloc_buf failed for page at %p\n", + proc->pid, page_addr); goto err_alloc_page_failed; } tmp_area.addr = page_addr; @@ -594,8 +596,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, page_array_ptr = page; ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr); if (ret) { - pr_err("binder: %d: binder_alloc_buf failed " - "to map page at %p in kernel\n", + pr_err("%d: binder_alloc_buf failed to map page at %p in kernel\n", proc->pid, page_addr); goto err_map_kernel_failed; } @@ -603,8 +604,7 @@ static int binder_update_page_range(struct binder_proc *proc, int allocate, (uintptr_t)page_addr + proc->user_buffer_offset; ret = vm_insert_page(vma, user_page_addr, page[0]); if (ret) { - pr_err("binder: %d: binder_alloc_buf failed " - "to map page at %lx in userspace\n", + pr_err("%d: binder_alloc_buf failed to map page at %lx in userspace\n", proc->pid, user_page_addr); goto err_vm_insert_page_failed; } @@ -652,7 +652,7 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, size_t size; if (proc->vma == NULL) { - pr_err("binder: %d: binder_alloc_buf, no vma\n", + pr_err("%d: binder_alloc_buf, no vma\n", proc->pid); return NULL; } @@ -661,16 +661,16 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, ALIGN(offsets_size, sizeof(void *)); if (size < data_size || size < offsets_size) { - binder_user_error("binder: %d: got transaction with invalid " - "size %zd-%zd\n", proc->pid, data_size, offsets_size); + binder_user_error("%d: got transaction with invalid size %zd-%zd\n", + proc->pid, data_size, offsets_size); return NULL; } if (is_async && proc->free_async_space < size + sizeof(struct binder_buffer)) { binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_alloc_buf size %zd" - "failed, no async space left\n", proc->pid, size); + "%d: binder_alloc_buf size %zd failed, no async space left\n", + proc->pid, size); return NULL; } @@ -690,8 +690,8 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, } } if (best_fit == NULL) { - pr_err("binder: %d: binder_alloc_buf size %zd failed, " - "no address space\n", proc->pid, size); + pr_err("%d: binder_alloc_buf size %zd failed, no address space\n", + proc->pid, size); return NULL; } if (n == NULL) { @@ -700,8 +700,8 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, } binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_alloc_buf size %zd got buff" - "er %p size %zd\n", proc->pid, size, buffer, buffer_size); + "%d: binder_alloc_buf size %zd got buffer %p size %zd\n", + proc->pid, size, buffer, buffer_size); has_page_addr = (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK); @@ -729,17 +729,16 @@ static struct binder_buffer *binder_alloc_buf(struct binder_proc *proc, binder_insert_free_buffer(proc, new_buffer); } binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_alloc_buf size %zd got " - "%p\n", proc->pid, size, buffer); + "%d: binder_alloc_buf size %zd got %p\n", + proc->pid, size, buffer); buffer->data_size = data_size; buffer->offsets_size = offsets_size; buffer->async_transaction = is_async; if (is_async) { proc->free_async_space -= size + sizeof(struct binder_buffer); binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, - "binder: %d: binder_alloc_buf size %zd " - "async free %zd\n", proc->pid, size, - proc->free_async_space); + "%d: binder_alloc_buf size %zd async free %zd\n", + proc->pid, size, proc->free_async_space); } return buffer; @@ -770,8 +769,8 @@ static void binder_delete_free_buffer(struct binder_proc *proc, if (buffer_end_page(prev) == buffer_end_page(buffer)) free_page_end = 0; binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: merge free, buffer %p " - "share page with %p\n", proc->pid, buffer, prev); + "%d: merge free, buffer %p share page with %p\n", + proc->pid, buffer, prev); } if (!list_is_last(&buffer->entry, &proc->buffers)) { @@ -783,16 +782,14 @@ static void binder_delete_free_buffer(struct binder_proc *proc, buffer_start_page(buffer)) free_page_start = 0; binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: merge free, buffer" - " %p share page with %p\n", proc->pid, - buffer, prev); + "%d: merge free, buffer %p share page with %p\n", + proc->pid, buffer, prev); } } list_del(&buffer->entry); if (free_page_start || free_page_end) { binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: merge free, buffer %p do " - "not share page%s%s with with %p or %p\n", + "%d: merge free, buffer %p do not share page%s%s with with %p or %p\n", proc->pid, buffer, free_page_start ? "" : " end", free_page_end ? "" : " start", prev, next); binder_update_page_range(proc, 0, free_page_start ? @@ -813,8 +810,8 @@ static void binder_free_buf(struct binder_proc *proc, ALIGN(buffer->offsets_size, sizeof(void *)); binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder: %d: binder_free_buf %p size %zd buffer" - "_size %zd\n", proc->pid, buffer, size, buffer_size); + "%d: binder_free_buf %p size %zd buffer_size %zd\n", + proc->pid, buffer, size, buffer_size); BUG_ON(buffer->free); BUG_ON(size > buffer_size); @@ -826,9 +823,8 @@ static void binder_free_buf(struct binder_proc *proc, proc->free_async_space += size + sizeof(struct binder_buffer); binder_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, - "binder: %d: binder_free_buf size %zd " - "async free %zd\n", proc->pid, size, - proc->free_async_space); + "%d: binder_free_buf size %zd async free %zd\n", + proc->pid, size, proc->free_async_space); } binder_update_page_range(proc, 0, @@ -910,7 +906,7 @@ static struct binder_node *binder_new_node(struct binder_proc *proc, INIT_LIST_HEAD(&node->work.entry); INIT_LIST_HEAD(&node->async_todo); binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d:%d node %d u%p c%p created\n", + "%d:%d node %d u%p c%p created\n", proc->pid, current->pid, node->debug_id, node->ptr, node->cookie); return node; @@ -925,8 +921,8 @@ static int binder_inc_node(struct binder_node *node, int strong, int internal, node->internal_strong_refs == 0 && !(node == binder_context_mgr_node && node->has_strong_ref)) { - pr_err("binder: invalid inc strong " - "node for %d\n", node->debug_id); + pr_err("invalid inc strong node for %d\n", + node->debug_id); return -EINVAL; } node->internal_strong_refs++; @@ -941,8 +937,8 @@ static int binder_inc_node(struct binder_node *node, int strong, int internal, node->local_weak_refs++; if (!node->has_weak_ref && list_empty(&node->work.entry)) { if (target_list == NULL) { - pr_err("binder: invalid inc weak node " - "for %d\n", node->debug_id); + pr_err("invalid inc weak node for %d\n", + node->debug_id); return -EINVAL; } list_add_tail(&node->work.entry, target_list); @@ -978,12 +974,12 @@ static int binder_dec_node(struct binder_node *node, int strong, int internal) if (node->proc) { rb_erase(&node->rb_node, &node->proc->nodes); binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: refless node %d deleted\n", + "refless node %d deleted\n", node->debug_id); } else { hlist_del(&node->dead_node); binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: dead node %d deleted\n", + "dead node %d deleted\n", node->debug_id); } kfree(node); @@ -1069,14 +1065,13 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, hlist_add_head(&new_ref->node_entry, &node->refs); binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d new ref %d desc %d for " - "node %d\n", proc->pid, new_ref->debug_id, - new_ref->desc, node->debug_id); + "%d new ref %d desc %d for node %d\n", + proc->pid, new_ref->debug_id, new_ref->desc, + node->debug_id); } else { binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d new ref %d desc %d for " - "dead node\n", proc->pid, new_ref->debug_id, - new_ref->desc); + "%d new ref %d desc %d for dead node\n", + proc->pid, new_ref->debug_id, new_ref->desc); } return new_ref; } @@ -1084,9 +1079,9 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, static void binder_delete_ref(struct binder_ref *ref) { binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d delete ref %d desc %d for " - "node %d\n", ref->proc->pid, ref->debug_id, - ref->desc, ref->node->debug_id); + "%d delete ref %d desc %d for node %d\n", + ref->proc->pid, ref->debug_id, ref->desc, + ref->node->debug_id); rb_erase(&ref->rb_node_desc, &ref->proc->refs_by_desc); rb_erase(&ref->rb_node_node, &ref->proc->refs_by_node); @@ -1096,9 +1091,8 @@ static void binder_delete_ref(struct binder_ref *ref) binder_dec_node(ref->node, 0, 1); if (ref->death) { binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: %d delete ref %d desc %d " - "has death notification\n", ref->proc->pid, - ref->debug_id, ref->desc); + "%d delete ref %d desc %d has death notification\n", + ref->proc->pid, ref->debug_id, ref->desc); list_del(&ref->death->work.entry); kfree(ref->death); binder_stats_deleted(BINDER_STAT_DEATH); @@ -1134,8 +1128,7 @@ static int binder_dec_ref(struct binder_ref *ref, int strong) { if (strong) { if (ref->strong == 0) { - binder_user_error("binder: %d invalid dec strong, " - "ref %d desc %d s %d w %d\n", + binder_user_error("%d invalid dec strong, ref %d desc %d s %d w %d\n", ref->proc->pid, ref->debug_id, ref->desc, ref->strong, ref->weak); return -EINVAL; @@ -1149,8 +1142,7 @@ static int binder_dec_ref(struct binder_ref *ref, int strong) } } else { if (ref->weak == 0) { - binder_user_error("binder: %d invalid dec weak, " - "ref %d desc %d s %d w %d\n", + binder_user_error("%d invalid dec weak, ref %d desc %d s %d w %d\n", ref->proc->pid, ref->debug_id, ref->desc, ref->strong, ref->weak); return -EINVAL; @@ -1195,8 +1187,7 @@ static void binder_send_failed_reply(struct binder_transaction *t, } if (target_thread->return_error == BR_OK) { binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: send failed reply for " - "transaction %d to %d:%d\n", + "send failed reply for transaction %d to %d:%d\n", t->debug_id, target_thread->proc->pid, target_thread->pid); @@ -1204,9 +1195,8 @@ static void binder_send_failed_reply(struct binder_transaction *t, target_thread->return_error = error_code; wake_up_interruptible(&target_thread->wait); } else { - pr_err("binder: reply failed, target " - "thread, %d:%d, has error code %d " - "already\n", target_thread->proc->pid, + pr_err("reply failed, target thread, %d:%d, has error code %d already\n", + target_thread->proc->pid, target_thread->pid, target_thread->return_error); } @@ -1215,21 +1205,19 @@ static void binder_send_failed_reply(struct binder_transaction *t, struct binder_transaction *next = t->from_parent; binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: send failed reply " - "for transaction %d, target dead\n", + "send failed reply for transaction %d, target dead\n", t->debug_id); binder_pop_transaction(target_thread, t); if (next == NULL) { binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: reply failed," - " no target thread at root\n"); + "reply failed, no target thread at root\n"); return; } t = next; binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: reply failed, no target " - "thread -- retry %d\n", t->debug_id); + "reply failed, no target thread -- retry %d\n", + t->debug_id); } } } @@ -1242,7 +1230,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, int debug_id = buffer->debug_id; binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d buffer release %d, size %zd-%zd, failed at %p\n", + "%d buffer release %d, size %zd-%zd, failed at %p\n", proc->pid, buffer->debug_id, buffer->data_size, buffer->offsets_size, failed_at); @@ -1259,9 +1247,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, if (*offp > buffer->data_size - sizeof(*fp) || buffer->data_size < sizeof(*fp) || !IS_ALIGNED(*offp, sizeof(void *))) { - pr_err("binder: transaction release %d bad" - "offset %zd, size %zd\n", debug_id, - *offp, buffer->data_size); + pr_err("transaction release %d bad offset %zd, size %zd\n", + debug_id, *offp, buffer->data_size); continue; } fp = (struct flat_binder_object *)(buffer->data + *offp); @@ -1270,8 +1257,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, case BINDER_TYPE_WEAK_BINDER: { struct binder_node *node = binder_get_node(proc, fp->binder); if (node == NULL) { - pr_err("binder: transaction release %d" - " bad node %p\n", debug_id, fp->binder); + pr_err("transaction release %d bad node %p\n", + debug_id, fp->binder); break; } binder_debug(BINDER_DEBUG_TRANSACTION, @@ -1283,9 +1270,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, case BINDER_TYPE_WEAK_HANDLE: { struct binder_ref *ref = binder_get_ref(proc, fp->handle); if (ref == NULL) { - pr_err("binder: transaction release %d" - " bad handle %ld\n", debug_id, - fp->handle); + pr_err("transaction release %d bad handle %ld\n", + debug_id, fp->handle); break; } binder_debug(BINDER_DEBUG_TRANSACTION, @@ -1302,8 +1288,8 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, break; default: - pr_err("binder: transaction release %d bad " - "object type %lx\n", debug_id, fp->type); + pr_err("transaction release %d bad object type %lx\n", + debug_id, fp->type); break; } } @@ -1336,17 +1322,14 @@ static void binder_transaction(struct binder_proc *proc, if (reply) { in_reply_to = thread->transaction_stack; if (in_reply_to == NULL) { - binder_user_error("binder: %d:%d got reply transaction " - "with no transaction stack\n", + binder_user_error("%d:%d got reply transaction with no transaction stack\n", proc->pid, thread->pid); return_error = BR_FAILED_REPLY; goto err_empty_call_stack; } binder_set_nice(in_reply_to->saved_priority); if (in_reply_to->to_thread != thread) { - binder_user_error("binder: %d:%d got reply transaction " - "with bad transaction stack," - " transaction %d has target %d:%d\n", + binder_user_error("%d:%d got reply transaction with bad transaction stack, transaction %d has target %d:%d\n", proc->pid, thread->pid, in_reply_to->debug_id, in_reply_to->to_proc ? in_reply_to->to_proc->pid : 0, @@ -1363,9 +1346,7 @@ static void binder_transaction(struct binder_proc *proc, goto err_dead_binder; } if (target_thread->transaction_stack != in_reply_to) { - binder_user_error("binder: %d:%d got reply transaction " - "with bad target transaction stack %d, " - "expected %d\n", + binder_user_error("%d:%d got reply transaction with bad target transaction stack %d, expected %d\n", proc->pid, thread->pid, target_thread->transaction_stack ? target_thread->transaction_stack->debug_id : 0, @@ -1381,8 +1362,7 @@ static void binder_transaction(struct binder_proc *proc, struct binder_ref *ref; ref = binder_get_ref(proc, tr->target.handle); if (ref == NULL) { - binder_user_error("binder: %d:%d got " - "transaction to invalid handle\n", + binder_user_error("%d:%d got transaction to invalid handle\n", proc->pid, thread->pid); return_error = BR_FAILED_REPLY; goto err_invalid_target_handle; @@ -1405,9 +1385,7 @@ static void binder_transaction(struct binder_proc *proc, struct binder_transaction *tmp; tmp = thread->transaction_stack; if (tmp->to_thread != thread) { - binder_user_error("binder: %d:%d got new " - "transaction with bad transaction stack" - ", transaction %d has target %d:%d\n", + binder_user_error("%d:%d got new transaction with bad transaction stack, transaction %d has target %d:%d\n", proc->pid, thread->pid, tmp->debug_id, tmp->to_proc ? tmp->to_proc->pid : 0, tmp->to_thread ? @@ -1452,16 +1430,14 @@ static void binder_transaction(struct binder_proc *proc, if (reply) binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d:%d BC_REPLY %d -> %d:%d, " - "data %p-%p size %zd-%zd\n", + "%d:%d BC_REPLY %d -> %d:%d, data %p-%p size %zd-%zd\n", proc->pid, thread->pid, t->debug_id, target_proc->pid, target_thread->pid, tr->data.ptr.buffer, tr->data.ptr.offsets, tr->data_size, tr->offsets_size); else binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d:%d BC_TRANSACTION %d -> " - "%d - node %d, data %p-%p size %zd-%zd\n", + "%d:%d BC_TRANSACTION %d -> %d - node %d, data %p-%p size %zd-%zd\n", proc->pid, thread->pid, t->debug_id, target_proc->pid, target_node->debug_id, tr->data.ptr.buffer, tr->data.ptr.offsets, @@ -1497,21 +1473,20 @@ static void binder_transaction(struct binder_proc *proc, offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *))); if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) { - binder_user_error("binder: %d:%d got transaction with invalid " - "data ptr\n", proc->pid, thread->pid); + binder_user_error("%d:%d got transaction with invalid data ptr\n", + proc->pid, thread->pid); return_error = BR_FAILED_REPLY; goto err_copy_data_failed; } if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) { - binder_user_error("binder: %d:%d got transaction with invalid " - "offsets ptr\n", proc->pid, thread->pid); + binder_user_error("%d:%d got transaction with invalid offsets ptr\n", + proc->pid, thread->pid); return_error = BR_FAILED_REPLY; goto err_copy_data_failed; } if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) { - binder_user_error("binder: %d:%d got transaction with " - "invalid offsets size, %zd\n", - proc->pid, thread->pid, tr->offsets_size); + binder_user_error("%d:%d got transaction with invalid offsets size, %zd\n", + proc->pid, thread->pid, tr->offsets_size); return_error = BR_FAILED_REPLY; goto err_bad_offset; } @@ -1521,9 +1496,8 @@ static void binder_transaction(struct binder_proc *proc, if (*offp > t->buffer->data_size - sizeof(*fp) || t->buffer->data_size < sizeof(*fp) || !IS_ALIGNED(*offp, sizeof(void *))) { - binder_user_error("binder: %d:%d got transaction with " - "invalid offset, %zd\n", - proc->pid, thread->pid, *offp); + binder_user_error("%d:%d got transaction with invalid offset, %zd\n", + proc->pid, thread->pid, *offp); return_error = BR_FAILED_REPLY; goto err_bad_offset; } @@ -1543,8 +1517,7 @@ static void binder_transaction(struct binder_proc *proc, node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS); } if (fp->cookie != node->cookie) { - binder_user_error("binder: %d:%d sending u%p " - "node %d, cookie mismatch %p != %p\n", + binder_user_error("%d:%d sending u%p node %d, cookie mismatch %p != %p\n", proc->pid, thread->pid, fp->binder, node->debug_id, fp->cookie, node->cookie); @@ -1573,10 +1546,9 @@ static void binder_transaction(struct binder_proc *proc, case BINDER_TYPE_WEAK_HANDLE: { struct binder_ref *ref = binder_get_ref(proc, fp->handle); if (ref == NULL) { - binder_user_error("binder: %d:%d got " - "transaction with invalid " - "handle, %ld\n", proc->pid, - thread->pid, fp->handle); + binder_user_error("%d:%d got transaction with invalid handle, %ld\n", + proc->pid, + thread->pid, fp->handle); return_error = BR_FAILED_REPLY; goto err_binder_get_ref_failed; } @@ -1617,13 +1589,13 @@ static void binder_transaction(struct binder_proc *proc, if (reply) { if (!(in_reply_to->flags & TF_ACCEPT_FDS)) { - binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n", + binder_user_error("%d:%d got reply with fd, %ld, but target does not allow fds\n", proc->pid, thread->pid, fp->handle); return_error = BR_FAILED_REPLY; goto err_fd_not_allowed; } } else if (!target_node->accept_fds) { - binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n", + binder_user_error("%d:%d got transaction with fd, %ld, but target does not allow fds\n", proc->pid, thread->pid, fp->handle); return_error = BR_FAILED_REPLY; goto err_fd_not_allowed; @@ -1631,7 +1603,7 @@ static void binder_transaction(struct binder_proc *proc, file = fget(fp->handle); if (file == NULL) { - binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n", + binder_user_error("%d:%d got transaction with invalid fd, %ld\n", proc->pid, thread->pid, fp->handle); return_error = BR_FAILED_REPLY; goto err_fget_failed; @@ -1651,8 +1623,7 @@ static void binder_transaction(struct binder_proc *proc, } break; default: - binder_user_error("binder: %d:%d got transactio" - "n with invalid object type, %lx\n", + binder_user_error("%d:%d got transaction with invalid object type, %lx\n", proc->pid, thread->pid, fp->type); return_error = BR_FAILED_REPLY; goto err_bad_object_type; @@ -1709,7 +1680,7 @@ err_dead_binder: err_invalid_target_handle: err_no_context_mgr_node: binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: %d:%d transaction failed %d, size %zd-%zd\n", + "%d:%d transaction failed %d, size %zd-%zd\n", proc->pid, thread->pid, return_error, tr->data_size, tr->offsets_size); @@ -1761,18 +1732,14 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, ref = binder_get_ref_for_node(proc, binder_context_mgr_node); if (ref->desc != target) { - binder_user_error("binder: %d:" - "%d tried to acquire " - "reference to desc 0, " - "got %d instead\n", + binder_user_error("%d:%d tried to acquire reference to desc 0, got %d instead\n", proc->pid, thread->pid, ref->desc); } } else ref = binder_get_ref(proc, target); if (ref == NULL) { - binder_user_error("binder: %d:%d refcou" - "nt change on invalid ref %d\n", + binder_user_error("%d:%d refcount change on invalid ref %d\n", proc->pid, thread->pid, target); break; } @@ -1796,7 +1763,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, break; } binder_debug(BINDER_DEBUG_USER_REFS, - "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n", + "%d:%d %s ref %d desc %d s %d w %d for node %d\n", proc->pid, thread->pid, debug_string, ref->debug_id, ref->desc, ref->strong, ref->weak, ref->node->debug_id); break; @@ -1815,8 +1782,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, ptr += sizeof(void *); node = binder_get_node(proc, node_ptr); if (node == NULL) { - binder_user_error("binder: %d:%d " - "%s u%p no match\n", + binder_user_error("%d:%d %s u%p no match\n", proc->pid, thread->pid, cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : @@ -1825,8 +1791,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, break; } if (cookie != node->cookie) { - binder_user_error("binder: %d:%d %s u%p node %d" - " cookie mismatch %p != %p\n", + binder_user_error("%d:%d %s u%p node %d cookie mismatch %p != %p\n", proc->pid, thread->pid, cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", @@ -1836,9 +1801,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, } if (cmd == BC_ACQUIRE_DONE) { if (node->pending_strong_ref == 0) { - binder_user_error("binder: %d:%d " - "BC_ACQUIRE_DONE node %d has " - "no pending acquire request\n", + binder_user_error("%d:%d BC_ACQUIRE_DONE node %d has no pending acquire request\n", proc->pid, thread->pid, node->debug_id); break; @@ -1846,9 +1809,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, node->pending_strong_ref = 0; } else { if (node->pending_weak_ref == 0) { - binder_user_error("binder: %d:%d " - "BC_INCREFS_DONE node %d has " - "no pending increfs request\n", + binder_user_error("%d:%d BC_INCREFS_DONE node %d has no pending increfs request\n", proc->pid, thread->pid, node->debug_id); break; @@ -1857,17 +1818,17 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, } binder_dec_node(node, cmd == BC_ACQUIRE_DONE, 0); binder_debug(BINDER_DEBUG_USER_REFS, - "binder: %d:%d %s node %d ls %d lw %d\n", + "%d:%d %s node %d ls %d lw %d\n", proc->pid, thread->pid, cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE", node->debug_id, node->local_strong_refs, node->local_weak_refs); break; } case BC_ATTEMPT_ACQUIRE: - pr_err("binder: BC_ATTEMPT_ACQUIRE not supported\n"); + pr_err("BC_ATTEMPT_ACQUIRE not supported\n"); return -EINVAL; case BC_ACQUIRE_RESULT: - pr_err("binder: BC_ACQUIRE_RESULT not supported\n"); + pr_err("BC_ACQUIRE_RESULT not supported\n"); return -EINVAL; case BC_FREE_BUFFER: { @@ -1880,20 +1841,17 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, buffer = binder_buffer_lookup(proc, data_ptr); if (buffer == NULL) { - binder_user_error("binder: %d:%d " - "BC_FREE_BUFFER u%p no match\n", + binder_user_error("%d:%d BC_FREE_BUFFER u%p no match\n", proc->pid, thread->pid, data_ptr); break; } if (!buffer->allow_user_free) { - binder_user_error("binder: %d:%d " - "BC_FREE_BUFFER u%p matched " - "unreturned buffer\n", + binder_user_error("%d:%d BC_FREE_BUFFER u%p matched unreturned buffer\n", proc->pid, thread->pid, data_ptr); break; } binder_debug(BINDER_DEBUG_FREE_BUFFER, - "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n", + "%d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n", proc->pid, thread->pid, data_ptr, buffer->debug_id, buffer->transaction ? "active" : "finished"); @@ -1927,19 +1885,15 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, case BC_REGISTER_LOOPER: binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BC_REGISTER_LOOPER\n", + "%d:%d BC_REGISTER_LOOPER\n", proc->pid, thread->pid); if (thread->looper & BINDER_LOOPER_STATE_ENTERED) { thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("binder: %d:%d ERROR:" - " BC_REGISTER_LOOPER called " - "after BC_ENTER_LOOPER\n", + binder_user_error("%d:%d ERROR: BC_REGISTER_LOOPER called after BC_ENTER_LOOPER\n", proc->pid, thread->pid); } else if (proc->requested_threads == 0) { thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("binder: %d:%d ERROR:" - " BC_REGISTER_LOOPER called " - "without request\n", + binder_user_error("%d:%d ERROR: BC_REGISTER_LOOPER called without request\n", proc->pid, thread->pid); } else { proc->requested_threads--; @@ -1949,20 +1903,18 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, break; case BC_ENTER_LOOPER: binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BC_ENTER_LOOPER\n", + "%d:%d BC_ENTER_LOOPER\n", proc->pid, thread->pid); if (thread->looper & BINDER_LOOPER_STATE_REGISTERED) { thread->looper |= BINDER_LOOPER_STATE_INVALID; - binder_user_error("binder: %d:%d ERROR:" - " BC_ENTER_LOOPER called after " - "BC_REGISTER_LOOPER\n", + binder_user_error("%d:%d ERROR: BC_ENTER_LOOPER called after BC_REGISTER_LOOPER\n", proc->pid, thread->pid); } thread->looper |= BINDER_LOOPER_STATE_ENTERED; break; case BC_EXIT_LOOPER: binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BC_EXIT_LOOPER\n", + "%d:%d BC_EXIT_LOOPER\n", proc->pid, thread->pid); thread->looper |= BINDER_LOOPER_STATE_EXITED; break; @@ -1982,8 +1934,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, ptr += sizeof(void *); ref = binder_get_ref(proc, target); if (ref == NULL) { - binder_user_error("binder: %d:%d %s " - "invalid ref %d\n", + binder_user_error("%d:%d %s invalid ref %d\n", proc->pid, thread->pid, cmd == BC_REQUEST_DEATH_NOTIFICATION ? "BC_REQUEST_DEATH_NOTIFICATION" : @@ -1993,7 +1944,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, } binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, - "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n", + "%d:%d %s %p ref %d desc %d s %d w %d for node %d\n", proc->pid, thread->pid, cmd == BC_REQUEST_DEATH_NOTIFICATION ? "BC_REQUEST_DEATH_NOTIFICATION" : @@ -2003,10 +1954,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, if (cmd == BC_REQUEST_DEATH_NOTIFICATION) { if (ref->death) { - binder_user_error("binder: %d:%" - "d BC_REQUEST_DEATH_NOTI" - "FICATION death notific" - "ation already set\n", + binder_user_error("%d:%d BC_REQUEST_DEATH_NOTIFICATION death notification already set\n", proc->pid, thread->pid); break; } @@ -2014,8 +1962,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, if (death == NULL) { thread->return_error = BR_ERROR; binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, - "binder: %d:%d " - "BC_REQUEST_DEATH_NOTIFICATION failed\n", + "%d:%d BC_REQUEST_DEATH_NOTIFICATION failed\n", proc->pid, thread->pid); break; } @@ -2034,20 +1981,13 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, } } else { if (ref->death == NULL) { - binder_user_error("binder: %d:%" - "d BC_CLEAR_DEATH_NOTIFI" - "CATION death notificat" - "ion not active\n", + binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification not active\n", proc->pid, thread->pid); break; } death = ref->death; if (death->cookie != cookie) { - binder_user_error("binder: %d:%" - "d BC_CLEAR_DEATH_NOTIFI" - "CATION death notificat" - "ion cookie mismatch " - "%p != %p\n", + binder_user_error("%d:%d BC_CLEAR_DEATH_NOTIFICATION death notification cookie mismatch %p != %p\n", proc->pid, thread->pid, death->cookie, cookie); break; @@ -2083,11 +2023,10 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, } } binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: %d:%d BC_DEAD_BINDER_DONE %p found %p\n", + "%d:%d BC_DEAD_BINDER_DONE %p found %p\n", proc->pid, thread->pid, cookie, death); if (death == NULL) { - binder_user_error("binder: %d:%d BC_DEAD" - "_BINDER_DONE %p not found\n", + binder_user_error("%d:%d BC_DEAD_BINDER_DONE %p not found\n", proc->pid, thread->pid, cookie); break; } @@ -2105,7 +2044,7 @@ int binder_thread_write(struct binder_proc *proc, struct binder_thread *thread, } break; default: - pr_err("binder: %d:%d unknown command %d\n", + pr_err("%d:%d unknown command %d\n", proc->pid, thread->pid, cmd); return -EINVAL; } @@ -2190,9 +2129,7 @@ retry: if (wait_for_proc_work) { if (!(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED))) { - binder_user_error("binder: %d:%d ERROR: Thread waiting " - "for process work before calling BC_REGISTER_" - "LOOPER or BC_ENTER_LOOPER (state %x)\n", + binder_user_error("%d:%d ERROR: Thread waiting for process work before calling BC_REGISTER_LOOPER or BC_ENTER_LOOPER (state %x)\n", proc->pid, thread->pid, thread->looper); wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); @@ -2251,7 +2188,7 @@ retry: binder_stat_br(proc, thread, cmd); binder_debug(BINDER_DEBUG_TRANSACTION_COMPLETE, - "binder: %d:%d BR_TRANSACTION_COMPLETE\n", + "%d:%d BR_TRANSACTION_COMPLETE\n", proc->pid, thread->pid); list_del(&w->entry); @@ -2298,13 +2235,13 @@ retry: binder_stat_br(proc, thread, cmd); binder_debug(BINDER_DEBUG_USER_REFS, - "binder: %d:%d %s %d u%p c%p\n", + "%d:%d %s %d u%p c%p\n", proc->pid, thread->pid, cmd_name, node->debug_id, node->ptr, node->cookie); } else { list_del_init(&w->entry); if (!weak && !strong) { binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d:%d node %d u%p c%p deleted\n", + "%d:%d node %d u%p c%p deleted\n", proc->pid, thread->pid, node->debug_id, node->ptr, node->cookie); rb_erase(&node->rb_node, &proc->nodes); @@ -2312,7 +2249,7 @@ retry: binder_stats_deleted(BINDER_STAT_NODE); } else { binder_debug(BINDER_DEBUG_INTERNAL_REFS, - "binder: %d:%d node %d u%p c%p state unchanged\n", + "%d:%d node %d u%p c%p state unchanged\n", proc->pid, thread->pid, node->debug_id, node->ptr, node->cookie); } @@ -2337,7 +2274,7 @@ retry: ptr += sizeof(void *); binder_stat_br(proc, thread, cmd); binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION, - "binder: %d:%d %s %p\n", + "%d:%d %s %p\n", proc->pid, thread->pid, cmd == BR_DEAD_BINDER ? "BR_DEAD_BINDER" : @@ -2406,8 +2343,7 @@ retry: trace_binder_transaction_received(t); binder_stat_br(proc, thread, cmd); binder_debug(BINDER_DEBUG_TRANSACTION, - "binder: %d:%d %s %d %d:%d, cmd %d" - "size %zd-%zd ptr %p-%p\n", + "%d:%d %s %d %d:%d, cmd %d size %zd-%zd ptr %p-%p\n", proc->pid, thread->pid, (cmd == BR_TRANSACTION) ? "BR_TRANSACTION" : "BR_REPLY", @@ -2440,7 +2376,7 @@ done: /*spawn a new thread if we leave this out */) { proc->requested_threads++; binder_debug(BINDER_DEBUG_THREADS, - "binder: %d:%d BR_SPAWN_LOOPER\n", + "%d:%d BR_SPAWN_LOOPER\n", proc->pid, thread->pid); if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer)) return -EFAULT; @@ -2465,7 +2401,7 @@ static void binder_release_work(struct list_head *list) binder_send_failed_reply(t, BR_DEAD_REPLY); } else { binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, - "binder: undelivered transaction %d\n", + "undelivered transaction %d\n", t->debug_id); t->buffer->transaction = NULL; kfree(t); @@ -2474,7 +2410,7 @@ static void binder_release_work(struct list_head *list) } break; case BINDER_WORK_TRANSACTION_COMPLETE: { binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, - "binder: undelivered TRANSACTION_COMPLETE\n"); + "undelivered TRANSACTION_COMPLETE\n"); kfree(w); binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE); } break; @@ -2484,13 +2420,13 @@ static void binder_release_work(struct list_head *list) death = container_of(w, struct binder_ref_death, work); binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, - "binder: undelivered death notification, %p\n", + "undelivered death notification, %p\n", death->cookie); kfree(death); binder_stats_deleted(BINDER_STAT_DEATH); } break; default: - pr_err("binder: unexpected work type, %d, not freed\n", + pr_err("unexpected work type, %d, not freed\n", w->type); break; } @@ -2547,8 +2483,8 @@ static int binder_free_thread(struct binder_proc *proc, while (t) { active_transactions++; binder_debug(BINDER_DEBUG_DEAD_TRANSACTION, - "binder: release %d:%d transaction %d " - "%s, still active\n", proc->pid, thread->pid, + "release %d:%d transaction %d %s, still active\n", + proc->pid, thread->pid, t->debug_id, (t->to_thread == thread) ? "in" : "out"); @@ -2641,9 +2577,9 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto err; } binder_debug(BINDER_DEBUG_READ_WRITE, - "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n", - proc->pid, thread->pid, bwr.write_size, bwr.write_buffer, - bwr.read_size, bwr.read_buffer); + "%d:%d write %ld at %08lx, read %ld at %08lx\n", + proc->pid, thread->pid, bwr.write_size, + bwr.write_buffer, bwr.read_size, bwr.read_buffer); if (bwr.write_size > 0) { ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed); @@ -2667,7 +2603,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } } binder_debug(BINDER_DEBUG_READ_WRITE, - "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n", + "%d:%d wrote %ld of %ld, read return %ld of %ld\n", proc->pid, thread->pid, bwr.write_consumed, bwr.write_size, bwr.read_consumed, bwr.read_size); if (copy_to_user(ubuf, &bwr, sizeof(bwr))) { @@ -2684,14 +2620,13 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; case BINDER_SET_CONTEXT_MGR: if (binder_context_mgr_node != NULL) { - pr_err("binder: BINDER_SET_CONTEXT_MGR already set\n"); + pr_err("BINDER_SET_CONTEXT_MGR already set\n"); ret = -EBUSY; goto err; } if (uid_valid(binder_context_mgr_uid)) { if (!uid_eq(binder_context_mgr_uid, current->cred->euid)) { - pr_err("binder: BINDER_SET_" - "CONTEXT_MGR bad uid %d != %d\n", + pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n", from_kuid(&init_user_ns, current->cred->euid), from_kuid(&init_user_ns, binder_context_mgr_uid)); ret = -EPERM; @@ -2710,7 +2645,7 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) binder_context_mgr_node->has_weak_ref = 1; break; case BINDER_THREAD_EXIT: - binder_debug(BINDER_DEBUG_THREADS, "binder: %d:%d exit\n", + binder_debug(BINDER_DEBUG_THREADS, "%d:%d exit\n", proc->pid, thread->pid); binder_free_thread(proc, thread); thread = NULL; @@ -2736,7 +2671,7 @@ err: binder_unlock(__func__); wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); if (ret && ret != -ERESTARTSYS) - pr_info("binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); + pr_info("%d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret); err_unlocked: trace_binder_ioctl_done(ret); return ret; @@ -2746,7 +2681,7 @@ static void binder_vma_open(struct vm_area_struct *vma) { struct binder_proc *proc = vma->vm_private_data; binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", + "%d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, (unsigned long)pgprot_val(vma->vm_page_prot)); @@ -2756,7 +2691,7 @@ static void binder_vma_close(struct vm_area_struct *vma) { struct binder_proc *proc = vma->vm_private_data; binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", + "%d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, (unsigned long)pgprot_val(vma->vm_page_prot)); @@ -3001,9 +2936,8 @@ static void binder_deferred_release(struct binder_proc *proc) } } binder_debug(BINDER_DEBUG_DEAD_BINDER, - "binder: node %d now dead, " - "refs %d, death %d\n", node->debug_id, - incoming_refs, death); + "node %d now dead, refs %d, death %d\n", + node->debug_id, incoming_refs, death); } } outgoing_refs = 0; @@ -3024,8 +2958,7 @@ static void binder_deferred_release(struct binder_proc *proc) if (t) { t->buffer = NULL; buffer->transaction = NULL; - pr_err("binder: release proc %d, " - "transaction %d, not freed\n", + pr_err("release proc %d, transaction %d, not freed\n", proc->pid, t->debug_id); /*BUG();*/ } @@ -3042,8 +2975,7 @@ static void binder_deferred_release(struct binder_proc *proc) if (proc->pages[i]) { void *page_addr = proc->buffer + i * PAGE_SIZE; binder_debug(BINDER_DEBUG_BUFFER_ALLOC, - "binder_release: %d: " - "page %d at %p not freed\n", + "binder_release: %d: page %d at %p not freed\n", proc->pid, i, page_addr); unmap_kernel_range((unsigned long)page_addr, @@ -3059,9 +2991,7 @@ static void binder_deferred_release(struct binder_proc *proc) put_task_struct(proc->tsk); binder_debug(BINDER_DEBUG_OPEN_CLOSE, - "binder_release: %d threads %d, nodes %d (ref %d), " - "refs %d, active transactions %d, buffers %d, " - "pages %d\n", + "binder_release: %d threads %d, nodes %d (ref %d), refs %d, active transactions %d, buffers %d, pages %d\n", proc->pid, threads, nodes, incoming_refs, outgoing_refs, active_transactions, buffers, page_count); -- cgit v1.2.3 From fd711905579fccbbd4b020fd054dfcc4021f15b6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:01:46 -0700 Subject: staging: comedi: rtd520: cleanup pci bar ioremap Use the size returned by pci_resource_len() when ioremap'ing the pci bars instead of assuming a size. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index fc0b1337a47..e33a233d42c 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -147,18 +147,6 @@ Configuration options: Board specific stuff ======================================================================*/ -/* - The board has three memory windows: las0, las1, and lcfg (the PCI chip) - Las1 has the data and can be burst DMAed 32bits at a time. -*/ -#define LCFG_PCIINDEX 0 -/* PCI region 1 is a 256 byte IO space mapping. Use??? */ -#define LAS0_PCIINDEX 2 /* PCI memory resources */ -#define LAS1_PCIINDEX 3 -#define LCFG_PCISIZE 0x100 -#define LAS0_PCISIZE 0x200 -#define LAS1_PCISIZE 0x10 - #define RTD_CLOCK_RATE 8000000 /* 8Mhz onboard clock */ #define RTD_CLOCK_BASE 125 /* clock period in ns */ @@ -1591,7 +1579,6 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct rtdPrivate *devpriv; struct pci_dev *pcidev; struct comedi_subdevice *s; - resource_size_t pci_base; int ret; #ifdef USE_DMA int index; @@ -1626,13 +1613,12 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) } dev->iobase = 1; /* the "detach" needs this */ - /* Initialize the base addresses */ - pci_base = pci_resource_start(pcidev, LAS0_PCIINDEX); - devpriv->las0 = ioremap_nocache(pci_base, LAS0_PCISIZE); - pci_base = pci_resource_start(pcidev, LAS1_PCIINDEX); - devpriv->las1 = ioremap_nocache(pci_base, LAS1_PCISIZE); - pci_base = pci_resource_start(pcidev, LCFG_PCIINDEX); - devpriv->lcfg = ioremap_nocache(pci_base, LCFG_PCISIZE); + devpriv->las0 = ioremap_nocache(pci_resource_start(pcidev, 2), + pci_resource_len(pcidev, 2)); + devpriv->las1 = ioremap_nocache(pci_resource_start(pcidev, 3), + pci_resource_len(pcidev, 3)); + devpriv->lcfg = ioremap_nocache(pci_resource_start(pcidev, 0), + pci_resource_len(pcidev, 0)); if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) return -ENOMEM; -- cgit v1.2.3 From 3d7e44164ca1ee63530eeba4b58d5a6cf02d6390 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:02:03 -0700 Subject: staging: comedi: rtd520: factor out the pci latency quirk Factor the code that checks the pci latency timer out of rtd_attach(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 68 +++++++++++++++++---------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index e33a233d42c..12af8278e56 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1542,6 +1542,40 @@ static int rtd_dio_insn_config(struct comedi_device *dev, return 1; } +/* The RTD driver does this */ +static void rtd_pci_latency_quirk(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + unsigned char pci_latency; + u16 revision; + /*uint32_t epld_version; */ + + pci_read_config_word(pcidev, PCI_REVISION_ID, &revision); + DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision); + + pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency); + if (pci_latency < 32) { + dev_info(dev->class_dev, + "PCI latency changed from %d to %d\n", + pci_latency, 32); + pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32); + } else { + DPRINTK("rtd520: PCI latency = %d\n", pci_latency); + } + +#if 0 + /* + * Undocumented EPLD version (doesn't match RTD driver results) + */ + DPRINTK("rtd520: Reading epld from %p\n", devpriv->las0 + 0); + epld_version = readl(devpriv->las0 + 0); + if ((epld_version & 0xF0) >> 4 == 0x0F) + DPRINTK("rtd520: pre-v8 EPLD. (%x)\n", epld_version); + else + DPRINTK("rtd520: EPLD version %x.\n", epld_version >> 4); +#endif +} + static struct pci_dev *rtd_find_pci(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -1622,39 +1656,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) return -ENOMEM; - { /* The RTD driver does this */ - unsigned char pci_latency; - u16 revision; - /*uint32_t epld_version; */ - - pci_read_config_word(pcidev, PCI_REVISION_ID, - &revision); - DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision); - - pci_read_config_byte(pcidev, - PCI_LATENCY_TIMER, &pci_latency); - if (pci_latency < 32) { - dev_info(dev->class_dev, - "PCI latency changed from %d to %d\n", - pci_latency, 32); - pci_write_config_byte(pcidev, - PCI_LATENCY_TIMER, 32); - } else { - DPRINTK("rtd520: PCI latency = %d\n", pci_latency); - } - - /* - * Undocumented EPLD version (doesn't match RTD driver results) - */ - /*DPRINTK ("rtd520: Reading epld from %p\n", - devpriv->las0+0); - epld_version = readl (devpriv->las0+0); - if ((epld_version & 0xF0) >> 4 == 0x0F) { - DPRINTK("rtd520: pre-v8 EPLD. (%x)\n", epld_version); - } else { - DPRINTK("rtd520: EPLD version %x.\n", epld_version >> 4); - } */ - } + rtd_pci_latency_quirk(dev, pcidev); /* Show board configuration */ dev_info(dev->class_dev, "%s:", dev->board_name); -- cgit v1.2.3 From b155c5fadb3119a17ce4c36326f1975ca9818fb0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:02:19 -0700 Subject: staging: comedi: rtd520: factor out the board init Factor the code that does the low-level init of the board out of rtd_attach(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 61 ++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 12af8278e56..5d68a0080b6 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1542,6 +1542,39 @@ static int rtd_dio_insn_config(struct comedi_device *dev, return 1; } +static void rtd_init_board(struct comedi_device *dev) +{ + struct rtdPrivate *devpriv = dev->private; + + /* initialize board, per RTD spec */ + /* also, initialize shadow registers */ + writel(0, devpriv->las0 + LAS0_BOARD_RESET); + udelay(100); /* needed? */ + writel(0, devpriv->lcfg + LCFG_ITCSR); + devpriv->intMask = 0; + writew(devpriv->intMask, devpriv->las0 + LAS0_IT); + devpriv->intClearMask = ~0; + writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR); + readw(devpriv->las0 + LAS0_CLEAR); + writel(0, devpriv->las0 + LAS0_OVERRUN); + writel(0, devpriv->las0 + LAS0_CGT_CLEAR); + writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR); + writel(0, devpriv->las0 + LAS0_DAC1_RESET); + writel(0, devpriv->las0 + LAS0_DAC2_RESET); + /* clear digital IO fifo */ + devpriv->dioStatus = 0; + writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS); + devpriv->utcCtrl[0] = (0 << 6) | 0x30; + devpriv->utcCtrl[1] = (1 << 6) | 0x30; + devpriv->utcCtrl[2] = (2 << 6) | 0x30; + devpriv->utcCtrl[3] = (3 << 6) | 0x00; + writeb(devpriv->utcCtrl[0], devpriv->las0 + LAS0_UTC_CTRL); + writeb(devpriv->utcCtrl[1], devpriv->las0 + LAS0_UTC_CTRL); + writeb(devpriv->utcCtrl[2], devpriv->las0 + LAS0_UTC_CTRL); + writeb(devpriv->utcCtrl[3], devpriv->las0 + LAS0_UTC_CTRL); + /* TODO: set user out source ??? */ +} + /* The RTD driver does this */ static void rtd_pci_latency_quirk(struct comedi_device *dev, struct pci_dev *pcidev) @@ -1713,33 +1746,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->n_chan = 3; s->maxdata = 0xffff; - /* initialize board, per RTD spec */ - /* also, initialize shadow registers */ - writel(0, devpriv->las0 + LAS0_BOARD_RESET); - udelay(100); /* needed? */ - writel(0, devpriv->lcfg + LCFG_ITCSR); - devpriv->intMask = 0; - writew(devpriv->intMask, devpriv->las0 + LAS0_IT); - devpriv->intClearMask = ~0; - writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR); - readw(devpriv->las0 + LAS0_CLEAR); - writel(0, devpriv->las0 + LAS0_OVERRUN); - writel(0, devpriv->las0 + LAS0_CGT_CLEAR); - writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR); - writel(0, devpriv->las0 + LAS0_DAC1_RESET); - writel(0, devpriv->las0 + LAS0_DAC2_RESET); - /* clear digital IO fifo */ - devpriv->dioStatus = 0; - writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS); - devpriv->utcCtrl[0] = (0 << 6) | 0x30; - devpriv->utcCtrl[1] = (1 << 6) | 0x30; - devpriv->utcCtrl[2] = (2 << 6) | 0x30; - devpriv->utcCtrl[3] = (3 << 6) | 0x00; - writeb(devpriv->utcCtrl[0], devpriv->las0 + LAS0_UTC_CTRL); - writeb(devpriv->utcCtrl[1], devpriv->las0 + LAS0_UTC_CTRL); - writeb(devpriv->utcCtrl[2], devpriv->las0 + LAS0_UTC_CTRL); - writeb(devpriv->utcCtrl[3], devpriv->las0 + LAS0_UTC_CTRL); - /* TODO: set user out source ??? */ + rtd_init_board(dev); /* check if our interrupt is available and get it */ ret = request_irq(pcidev->irq, rtd_interrupt, -- cgit v1.2.3 From 09d93a189ef5f0b90ad8d7cf1d01bfe6cae711b6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:02:39 -0700 Subject: staging: comedi: rtd520: factor out the board reset Factor the common code that does the low-level reset of the board out of rtd_init_board() and rtc_detach(). Fix the if test in rtd_detach() before doing the reset, devpriv->lcfg could be NULL at this point. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 5d68a0080b6..8c249bceb07 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1542,12 +1542,10 @@ static int rtd_dio_insn_config(struct comedi_device *dev, return 1; } -static void rtd_init_board(struct comedi_device *dev) +static void rtd_reset(struct comedi_device *dev) { struct rtdPrivate *devpriv = dev->private; - /* initialize board, per RTD spec */ - /* also, initialize shadow registers */ writel(0, devpriv->las0 + LAS0_BOARD_RESET); udelay(100); /* needed? */ writel(0, devpriv->lcfg + LCFG_ITCSR); @@ -1556,6 +1554,18 @@ static void rtd_init_board(struct comedi_device *dev) devpriv->intClearMask = ~0; writew(devpriv->intClearMask, devpriv->las0 + LAS0_CLEAR); readw(devpriv->las0 + LAS0_CLEAR); +} + +/* + * initialize board, per RTD spec + * also, initialize shadow registers + */ +static void rtd_init_board(struct comedi_device *dev) +{ + struct rtdPrivate *devpriv = dev->private; + + rtd_reset(dev); + writel(0, devpriv->las0 + LAS0_OVERRUN); writel(0, devpriv->las0 + LAS0_CGT_CLEAR); writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR); @@ -1868,15 +1878,8 @@ static void rtd_detach(struct comedi_device *dev) writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + LCFG_ITCSR); } #endif /* USE_DMA */ - if (devpriv->las0) { - writel(0, devpriv->las0 + LAS0_BOARD_RESET); - devpriv->intMask = 0; - writew(devpriv->intMask, devpriv->las0 + LAS0_IT); - devpriv->intClearMask = ~0; - writew(devpriv->intClearMask, - devpriv->las0 + LAS0_CLEAR); - readw(devpriv->las0 + LAS0_CLEAR); - } + if (devpriv->las0 && devpriv->lcfg) + rtd_reset(dev); #ifdef USE_DMA /* release DMA */ for (index = 0; index < DMA_CHAIN_COUNT; index++) { -- cgit v1.2.3 From 60aeb08024dcd8a392917ab72a107ad451a59030 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:03:01 -0700 Subject: staging: comedi: rtd520: remove broken USE_DMA code It appears the dma code in this driver is seriously broken. Enabling USE_DMA causes the driver to not even compile. Just remove all the dma code for now. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 343 -------------------------------- 1 file changed, 343 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 8c249bceb07..3fc4d6878d1 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -113,8 +113,6 @@ Configuration options: /*====================================================================== Driver specific stuff (tunable) ======================================================================*/ -/* Enable this to test the new DMA support. You may get hard lock ups */ -/*#define USE_DMA*/ /* We really only need 2 buffers. More than that means being much smarter about knowing which ones are full. */ @@ -314,21 +312,6 @@ struct rtdPrivate { u16 intClearMask; /* interrupt clear mask */ u8 utcCtrl[4]; /* crtl mode for 3 utc + read back */ u8 dioStatus; /* could be read back (dio0Ctrl) */ -#ifdef USE_DMA - /* - * Always DMA 1/2 FIFO. Buffer (dmaBuff?) is (at least) twice that - * size. After transferring, interrupt processes 1/2 FIFO and - * passes to comedi - */ - s16 dma0Offset; /* current processing offset (0, 1/2) */ - uint16_t *dma0Buff[DMA_CHAIN_COUNT]; /* DMA buffers (for ADC) */ - dma_addr_t dma0BuffPhysAddr[DMA_CHAIN_COUNT]; /* physical addresses */ - struct plx_dma_desc *dma0Chain; /* DMA descriptor ring for dmaBuff */ - dma_addr_t dma0ChainPhysAddr; /* physical addresses */ - /* shadow registers */ - u8 dma0Control; - u8 dma1Control; -#endif /* USE_DMA */ unsigned fifoLen; }; @@ -641,125 +624,6 @@ static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -#ifdef USE_DMA -/* - Terminate a DMA transfer and wait for everything to quiet down -*/ -void abort_dma(struct comedi_device *dev, unsigned int channel) -{ /* DMA channel 0, 1 */ - struct rtdPrivate *devpriv = dev->private; - unsigned long dma_cs_addr; /* the control/status register */ - uint8_t status; - unsigned int ii; - /* unsigned long flags; */ - - dma_cs_addr = (unsigned long)devpriv->lcfg - + ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1); - - /* spinlock for plx dma control/status reg */ - /* spin_lock_irqsave( &dev->spinlock, flags ); */ - - /* abort dma transfer if necessary */ - status = readb(dma_cs_addr); - if ((status & PLX_DMA_EN_BIT) == 0) { /* not enabled (Error?) */ - DPRINTK("rtd520: AbortDma on non-active channel %d (0x%x)\n", - channel, status); - goto abortDmaExit; - } - - /* wait to make sure done bit is zero (needed?) */ - for (ii = 0; (status & PLX_DMA_DONE_BIT) && ii < RTD_DMA_TIMEOUT; ii++) { - WAIT_QUIETLY; - status = readb(dma_cs_addr); - } - if (status & PLX_DMA_DONE_BIT) { - printk("rtd520: Timeout waiting for dma %i done clear\n", - channel); - goto abortDmaExit; - } - - /* disable channel (required) */ - writeb(0, dma_cs_addr); - udelay(1); /* needed?? */ - /* set abort bit for channel */ - writeb(PLX_DMA_ABORT_BIT, dma_cs_addr); - - /* wait for dma done bit to be set */ - status = readb(dma_cs_addr); - for (ii = 0; - (status & PLX_DMA_DONE_BIT) == 0 && ii < RTD_DMA_TIMEOUT; ii++) { - status = readb(dma_cs_addr); - WAIT_QUIETLY; - } - if ((status & PLX_DMA_DONE_BIT) == 0) { - printk("rtd520: Timeout waiting for dma %i done set\n", - channel); - } - -abortDmaExit: - /* spin_unlock_irqrestore( &dev->spinlock, flags ); */ -} - -/* - Process what is in the DMA transfer buffer and pass to comedi - Note: this is not re-entrant -*/ -static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s) -{ - struct rtdPrivate *devpriv = dev->private; - int ii, n; - s16 *dp; - - if (devpriv->aiCount == 0) /* transfer already complete */ - return 0; - - dp = devpriv->dma0Buff[devpriv->dma0Offset]; - for (ii = 0; ii < devpriv->fifoLen / 2;) { /* convert samples */ - short sample; - - if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { - sample = (*dp >> 3) + 2048; /* convert to comedi unsigned data */ - else - sample = *dp >> 3; /* low 3 bits are marker lines */ - - *dp++ = sample; /* put processed value back */ - - if (++s->async->cur_chan >= s->async->cmd.chanlist_len) - s->async->cur_chan = 0; - - ++ii; /* number ready to transfer */ - if (devpriv->aiCount > 0) { /* < 0, means read forever */ - if (--devpriv->aiCount == 0) { /* done */ - /*DPRINTK ("rtd520: Final %d samples\n", ii); */ - break; - } - } - } - - /* now pass the whole array to the comedi buffer */ - dp = devpriv->dma0Buff[devpriv->dma0Offset]; - n = comedi_buf_write_alloc(s->async, ii * sizeof(s16)); - if (n < (ii * sizeof(s16))) { /* any residual is an error */ - DPRINTK("rtd520:ai_process_dma buffer overflow %d samples!\n", - ii - (n / sizeof(s16))); - s->async->events |= COMEDI_CB_ERROR; - return -1; - } - comedi_buf_memcpy_to(s->async, 0, dp, n); - comedi_buf_write_free(s->async, n); - - /* - * always at least 1 scan -- 1/2 FIFO is larger than our max scan list - */ - s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; - - if (++devpriv->dma0Offset >= DMA_CHAIN_COUNT) { /* next buffer */ - devpriv->dma0Offset = 0; - } - return 0; -} -#endif /* USE_DMA */ - /* Handle all rtd520 interrupts. Runs atomically and is never re-entered. @@ -787,39 +651,6 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ DPRINTK("rtd520: FIFO full! fifo_status=0x%x\n", (fifoStatus ^ 0x6666) & 0x7777); /* should be all 0s */ goto abortTransfer; } -#ifdef USE_DMA - if (devpriv->flags & DMA0_ACTIVE) { /* Check DMA */ - u32 istatus = readl(devpriv->lcfg + LCFG_ITCSR); - - if (istatus & ICS_DMA0_A) { - if (ai_process_dma(dev, s) < 0) { - DPRINTK - ("rtd520: comedi read buffer overflow (DMA) with %ld to go!\n", - devpriv->aiCount); - devpriv->dma0Control &= ~PLX_DMA_START_BIT; - devpriv->dma0Control |= PLX_CLEAR_DMA_INTR_BIT; - writeb(devpriv->dma0Control, - devpriv->lcfg + LCFG_DMACSR0); - goto abortTransfer; - } - - /*DPRINTK ("rtd520: DMA transfer: %ld to go, istatus %x\n", - devpriv->aiCount, istatus); */ - devpriv->dma0Control &= ~PLX_DMA_START_BIT; - devpriv->dma0Control |= PLX_CLEAR_DMA_INTR_BIT; - writeb(devpriv->dma0Control, - devpriv->lcfg + LCFG_DMACSR0); - if (0 == devpriv->aiCount) { /* counted down */ - DPRINTK("rtd520: Samples Done (DMA).\n"); - goto transferDone; - } - comedi_event(dev, s); - } else { - /*DPRINTK ("rtd520: No DMA ready: istatus %x\n", istatus); */ - } - } - /* Fall through and check for other interrupt sources */ -#endif /* USE_DMA */ status = readw(devpriv->las0 + LAS0_IT); /* if interrupt was not caused by our board, or handled above */ @@ -898,19 +729,6 @@ transferDone: writel(0, devpriv->las0 + LAS0_ADC_CONVERSION); devpriv->intMask = 0; writew(devpriv->intMask, devpriv->las0 + LAS0_IT); -#ifdef USE_DMA - if (devpriv->flags & DMA0_ACTIVE) { - writel(readl(devpriv->lcfg + LCFG_ITCSR) & ~ICS_DMA0_E, - devpriv->lcfg + LCFG_ITCSR); - abort_dma(dev, 0); - devpriv->flags &= ~DMA0_ACTIVE; - /* if Using DMA, then we should have read everything by now */ - if (devpriv->aiCount > 0) { - DPRINTK("rtd520: Lost DMA data! %ld remain\n", - devpriv->aiCount); - } - } -#endif /* USE_DMA */ if (devpriv->aiCount > 0) { /* there shouldn't be anything left */ fifoStatus = readl(devpriv->las0 + LAS0_ADC); @@ -1144,20 +962,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writel(0, devpriv->las0 + LAS0_ADC_CONVERSION); devpriv->intMask = 0; writew(devpriv->intMask, devpriv->las0 + LAS0_IT); -#ifdef USE_DMA - if (devpriv->flags & DMA0_ACTIVE) { /* cancel anything running */ - writel(readl(devpriv->lcfg + LCFG_ITCSR) & ~ICS_DMA0_E, - devpriv->lcfg + LCFG_ITCSR); - abort_dma(dev, 0); - devpriv->flags &= ~DMA0_ACTIVE; - if (readl(devpriv->lcfg + LCFG_ITCSR) & ICS_DMA0_A) { - devpriv->dma0Control = PLX_CLEAR_DMA_INTR_BIT; - writeb(devpriv->dma0Control, - devpriv->lcfg + LCFG_DMACSR0); - } - } - writel(0, devpriv->las0 + LAS0_DMA0_RESET); -#endif /* USE_DMA */ writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR); writel(0, devpriv->las0 + LAS0_OVERRUN); devpriv->intCount = 0; @@ -1316,32 +1120,9 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writew(devpriv->intMask, devpriv->las0 + LAS0_IT); DPRINTK("rtd520: Transferring every %d\n", devpriv->transCount); } else { /* 1/2 FIFO transfers */ -#ifdef USE_DMA - devpriv->flags |= DMA0_ACTIVE; - - /* point to first transfer in ring */ - devpriv->dma0Offset = 0; - writel(DMA_MODE_BITS, devpriv->lcfg + LCFG_DMAMODE0); - /* point to first block */ - writel(devpriv->dma0Chain[DMA_CHAIN_COUNT - 1].next, - devpriv->lcfg + LCFG_DMADPR0); - writel(DMAS_ADFIFO_HALF_FULL, devpriv->las0 + LAS0_DMA0_SRC); - writel(readl(devpriv->lcfg + LCFG_ITCSR) | ICS_DMA0_E, - devpriv->lcfg + LCFG_ITCSR); - /* Must be 2 steps. See PLX app note about "Starting a DMA transfer" */ - devpriv->dma0Control = PLX_DMA_EN_BIT; - writeb(devpriv->dma0Control, - devpriv->lcfg + LCFG_DMACSR0); - devpriv->dma0Control |= PLX_DMA_START_BIT; - writeb(devpriv->dma0Control, - devpriv->lcfg + LCFG_DMACSR0); - DPRINTK("rtd520: Using DMA0 transfers. plxInt %x RtdInt %x\n", - readl(devpriv->lcfg + LCFG_ITCSR), devpriv->intMask); -#else /* USE_DMA */ devpriv->intMask = IRQM_ADC_ABOUT_CNT; writew(devpriv->intMask, devpriv->las0 + LAS0_IT); DPRINTK("rtd520: Transferring every 1/2 FIFO\n"); -#endif /* USE_DMA */ } /* BUG: start_src is ASSUMED to be TRIG_NOW */ @@ -1366,14 +1147,6 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->intMask = 0; writew(devpriv->intMask, devpriv->las0 + LAS0_IT); devpriv->aiCount = 0; /* stop and don't transfer any more */ -#ifdef USE_DMA - if (devpriv->flags & DMA0_ACTIVE) { - writel(readl(devpriv->lcfg + LCFG_ITCSR) & ~ICS_DMA0_E, - devpriv->lcfg + LCFG_ITCSR); - abort_dma(dev, 0); - devpriv->flags &= ~DMA0_ACTIVE; - } -#endif /* USE_DMA */ status = readw(devpriv->las0 + LAS0_IT); overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff; DPRINTK @@ -1657,18 +1430,9 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; -#ifdef USE_DMA - int index; -#endif dev_info(dev->class_dev, "rtd520 attaching.\n"); -#if defined(CONFIG_COMEDI_DEBUG) && defined(USE_DMA) - /* You can set this a load time: modprobe comedi comedi_debug=1 */ - if (0 == comedi_debug) /* force DMA debug printks */ - comedi_debug = 1; -#endif - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; @@ -1777,78 +1541,6 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->fifoLen = ret; printk("( fifoLen=%d )", devpriv->fifoLen); -#ifdef USE_DMA - if (dev->irq > 0) { - printk("( DMA buff=%d )\n", DMA_CHAIN_COUNT); - /* - * The PLX9080 has 2 DMA controllers, but there could be - * 4 sources: ADC, digital, DAC1, and DAC2. Since only the - * ADC supports cmd mode right now, this isn't an issue (yet) - */ - devpriv->dma0Offset = 0; - - for (index = 0; index < DMA_CHAIN_COUNT; index++) { - devpriv->dma0Buff[index] = - pci_alloc_consistent(pcidev, - sizeof(u16) * - devpriv->fifoLen / 2, - &devpriv-> - dma0BuffPhysAddr[index]); - if (devpriv->dma0Buff[index] == NULL) { - ret = -ENOMEM; - goto rtd_attach_die_error; - } - /*DPRINTK ("buff[%d] @ %p virtual, %x PCI\n", - index, - devpriv->dma0Buff[index], - devpriv->dma0BuffPhysAddr[index]); */ - } - - /* - * setup DMA descriptor ring (use cpu_to_le32 for byte - * ordering?) - */ - devpriv->dma0Chain = - pci_alloc_consistent(pcidev, - sizeof(struct plx_dma_desc) * - DMA_CHAIN_COUNT, - &devpriv->dma0ChainPhysAddr); - for (index = 0; index < DMA_CHAIN_COUNT; index++) { - devpriv->dma0Chain[index].pci_start_addr = - devpriv->dma0BuffPhysAddr[index]; - devpriv->dma0Chain[index].local_start_addr = - DMALADDR_ADC; - devpriv->dma0Chain[index].transfer_size = - sizeof(u16) * devpriv->fifoLen / 2; - devpriv->dma0Chain[index].next = - (devpriv->dma0ChainPhysAddr + ((index + - 1) % - (DMA_CHAIN_COUNT)) - * sizeof(devpriv->dma0Chain[0])) - | DMA_TRANSFER_BITS; - /*DPRINTK ("ring[%d] @%lx PCI: %x, local: %x, N: 0x%x, next: %x\n", - index, - ((long)devpriv->dma0ChainPhysAddr - + (index * sizeof(devpriv->dma0Chain[0]))), - devpriv->dma0Chain[index].pci_start_addr, - devpriv->dma0Chain[index].local_start_addr, - devpriv->dma0Chain[index].transfer_size, - devpriv->dma0Chain[index].next); */ - } - - if (devpriv->dma0Chain == NULL) { - ret = -ENOMEM; - goto rtd_attach_die_error; - } - - writel(DMA_MODE_BITS, devpriv->lcfg + LCFG_DMAMODE0); - /* set DMA trigger source */ - writel(DMAS_ADFIFO_HALF_FULL, devpriv->las0 + LAS0_DMA0_SRC); - } else { - dev_info(dev->class_dev, "( no IRQ->no DMA )"); - } -#endif /* USE_DMA */ - if (dev->irq) writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + LCFG_ITCSR); @@ -1861,46 +1553,11 @@ static void rtd_detach(struct comedi_device *dev) { struct rtdPrivate *devpriv = dev->private; struct pci_dev *pcidev = comedi_to_pci_dev(dev); -#ifdef USE_DMA - int index; -#endif if (devpriv) { /* Shut down any board ops by resetting it */ -#ifdef USE_DMA - if (devpriv->lcfg) { - devpriv->dma0Control = 0; - devpriv->dma1Control = 0; - writeb(devpriv->dma0Control, - devpriv->lcfg + LCFG_DMACSR0); - writeb(devpriv->dma1Control, - devpriv->lcfg + LCFG_DMACSR1); - writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + LCFG_ITCSR); - } -#endif /* USE_DMA */ if (devpriv->las0 && devpriv->lcfg) rtd_reset(dev); -#ifdef USE_DMA - /* release DMA */ - for (index = 0; index < DMA_CHAIN_COUNT; index++) { - if (NULL != devpriv->dma0Buff[index]) { - pci_free_consistent(pcidev, - sizeof(u16) * - devpriv->fifoLen / 2, - devpriv->dma0Buff[index], - devpriv-> - dma0BuffPhysAddr[index]); - devpriv->dma0Buff[index] = NULL; - } - } - if (NULL != devpriv->dma0Chain) { - pci_free_consistent(pcidev, - sizeof(struct plx_dma_desc) * - DMA_CHAIN_COUNT, devpriv->dma0Chain, - devpriv->dma0ChainPhysAddr); - devpriv->dma0Chain = NULL; - } -#endif /* USE_DMA */ if (dev->irq) { writel(readl(devpriv->lcfg + LCFG_ITCSR) & ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E), -- cgit v1.2.3 From edecbd062816e69d7143c58346744ab7585bbb3d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:03:30 -0700 Subject: staging: comedi: rtd520: remove the board attach noise Remove all the kernel noise that is output as the board is attached. Leave a simple dev_info() after the attach is complete. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 3fc4d6878d1..f1cd266c6f4 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1431,8 +1431,6 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; int ret; - dev_info(dev->class_dev, "rtd520 attaching.\n"); - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; @@ -1447,11 +1445,8 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->board_name = thisboard->name; ret = comedi_pci_enable(pcidev, DRV_NAME); - if (ret < 0) { - dev_info(dev->class_dev, - "Failed to enable PCI device and request regions.\n"); + if (ret) return ret; - } dev->iobase = 1; /* the "detach" needs this */ devpriv->las0 = ioremap_nocache(pci_resource_start(pcidev, 2), @@ -1465,9 +1460,6 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) rtd_pci_latency_quirk(dev, pcidev); - /* Show board configuration */ - dev_info(dev->class_dev, "%s:", dev->board_name); - ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; @@ -1525,28 +1517,21 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* check if our interrupt is available and get it */ ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED, DRV_NAME, dev); - - if (ret < 0) { - printk("Could not get interrupt! (%u)\n", - pcidev->irq); + if (ret < 0) return ret; - } dev->irq = pcidev->irq; - dev_info(dev->class_dev, "( irq=%u )", dev->irq); ret = rtd520_probe_fifo_depth(dev); if (ret < 0) return ret; - devpriv->fifoLen = ret; - printk("( fifoLen=%d )", devpriv->fifoLen); if (dev->irq) writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + LCFG_ITCSR); - printk("\ncomedi%d: rtd520 driver attached.\n", dev->minor); + dev_info(dev->class_dev, "%s attached\n", dev->board_name); - return 1; + return 0; } static void rtd_detach(struct comedi_device *dev) -- cgit v1.2.3 From 825ca08e9cca69e03fe056e6de8e2445616a2da8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:03:53 -0700 Subject: staging: comedi: rtd520: convert driver to attach_pci Convert this driver to use the comedi PCI auto config mechanism by adding an attach_pci callback. Since this driver requires no extra configuration options, and the attach callback is now optional, remove it. Use the found 'dev->board_name' for the resource name passed to comedi_pci_enable() and request_irq(). Since this driver no longer walks the pci bus to find the pci_dev, remove the pci_dev_put() in the detach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 59 ++++++++++----------------------- 1 file changed, 18 insertions(+), 41 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index f1cd266c6f4..f7d813cbb43 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -108,8 +108,6 @@ Configuration options: #include "comedi_fc.h" -#define DRV_NAME "rtd520" - /*====================================================================== Driver specific stuff (tunable) ======================================================================*/ @@ -1392,59 +1390,39 @@ static void rtd_pci_latency_quirk(struct comedi_device *dev, #endif } -static struct pci_dev *rtd_find_pci(struct comedi_device *dev, - struct comedi_devconfig *it) +static const void *rtd_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { const struct rtdBoard *thisboard; - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; int i; - for_each_pci_dev(pcidev) { - if (pcidev->vendor != PCI_VENDOR_ID_RTD) - continue; - if (bus || slot) { - if (pcidev->bus->number != bus || - PCI_SLOT(pcidev->devfn) != slot) - continue; - } - for (i = 0; i < ARRAY_SIZE(rtd520Boards); i++) { - thisboard = &rtd520Boards[i]; - if (pcidev->device == thisboard->device_id) { - dev->board_ptr = thisboard; - return pcidev; - } - } + for (i = 0; i < ARRAY_SIZE(rtd520Boards); i++) { + thisboard = &rtd520Boards[i]; + if (pcidev->device == thisboard->device_id) + return thisboard; } - dev_warn(dev->class_dev, - "no supported board found! (req. bus/slot: %d/%d)\n", - bus, slot); return NULL; } -static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ /* board name and options flags */ +static int rtd_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) +{ const struct rtdBoard *thisboard; struct rtdPrivate *devpriv; - struct pci_dev *pcidev; struct comedi_subdevice *s; int ret; + thisboard = rtd_find_boardinfo(dev, pcidev); + if (!thisboard) + return -ENODEV; + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; dev->private = devpriv; - pcidev = rtd_find_pci(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - thisboard = comedi_board(dev); - - dev->board_name = thisboard->name; - - ret = comedi_pci_enable(pcidev, DRV_NAME); + ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; dev->iobase = 1; /* the "detach" needs this */ @@ -1515,8 +1493,8 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) rtd_init_board(dev); /* check if our interrupt is available and get it */ - ret = request_irq(pcidev->irq, rtd_interrupt, - IRQF_SHARED, DRV_NAME, dev); + ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED, + dev->board_name, dev); if (ret < 0) return ret; dev->irq = pcidev->irq; @@ -1559,14 +1537,13 @@ static void rtd_detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - pci_dev_put(pcidev); } } static struct comedi_driver rtd520_driver = { .driver_name = "rtd520", .module = THIS_MODULE, - .attach = rtd_attach, + .attach_pci = rtd_attach_pci, .detach = rtd_detach, }; -- cgit v1.2.3 From 5133f127efac3dd88963074443537027e8d41489 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:04:11 -0700 Subject: staging: comedi: rtd520: remove code in #if 0/#endif blocks All the #if 0'ed out code is either debug or incomplete. Just remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 41 +-------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index f7d813cbb43..8d125d514d9 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -566,15 +566,8 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, d = readw(devpriv->las1 + LAS1_ADC_FIFO); continue; } -#if 0 - if (!(readl(devpriv->las0 + LAS0_ADC) & FS_ADC_NOT_EMPTY)) { - DPRINTK("comedi: READ OOPS on %d of %d\n", ii + 1, - count); - break; - } -#endif - d = readw(devpriv->las1 + LAS1_ADC_FIFO); + d = readw(devpriv->las1 + LAS1_ADC_FIFO); d = d >> 3; /* low 3 bits are marker lines */ if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) { /* convert to comedi unsigned data */ @@ -752,18 +745,6 @@ transferDone: return IRQ_HANDLED; } -#if 0 -/* - return the number of samples available -*/ -static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s) -{ - /* TODO: This needs to mask interrupts, read_dregs, and then re-enable */ - /* Not sure what to do if DMA is active */ - return s->async->buf_write_count - s->async->buf_read_count; -} -#endif - /* cmdtest tests a particular command to see if it is valid. Using the cmdtest ioctl, a user can create a valid cmd @@ -884,12 +865,6 @@ static int rtd_ai_cmdtest(struct comedi_device *dev, } } -#if 0 - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } -#endif if (cmd->stop_src == TRIG_COUNT) { /* TODO check for rounding error due to counter wrap */ @@ -1362,7 +1337,6 @@ static void rtd_pci_latency_quirk(struct comedi_device *dev, { unsigned char pci_latency; u16 revision; - /*uint32_t epld_version; */ pci_read_config_word(pcidev, PCI_REVISION_ID, &revision); DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision); @@ -1376,18 +1350,6 @@ static void rtd_pci_latency_quirk(struct comedi_device *dev, } else { DPRINTK("rtd520: PCI latency = %d\n", pci_latency); } - -#if 0 - /* - * Undocumented EPLD version (doesn't match RTD driver results) - */ - DPRINTK("rtd520: Reading epld from %p\n", devpriv->las0 + 0); - epld_version = readl(devpriv->las0 + 0); - if ((epld_version & 0xF0) >> 4 == 0x0F) - DPRINTK("rtd520: pre-v8 EPLD. (%x)\n", epld_version); - else - DPRINTK("rtd520: EPLD version %x.\n", epld_version >> 4); -#endif } static const void *rtd_find_boardinfo(struct comedi_device *dev, @@ -1460,7 +1422,6 @@ static int rtd_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s->do_cmd = rtd_ai_cmd; s->do_cmdtest = rtd_ai_cmdtest; s->cancel = rtd_ai_cancel; - /* s->poll = rtd_ai_poll; *//* not ready yet */ s = &dev->subdevices[1]; /* analog output subdevice */ -- cgit v1.2.3 From d62bc46866d622950d6afab0d7af61ccc79b9353 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:04:40 -0700 Subject: staging: comedi: rtd520: remove DPRINTK messages These are all development debug messages. A lot of them are in the interrupt routine and probably shouldn't be there. Some of the others are actually commented out. Just remove all of them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 105 ++++---------------------------- 1 file changed, 13 insertions(+), 92 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 8d125d514d9..6af19bcbcfb 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -524,12 +524,8 @@ static int rtd_ai_rinsn(struct comedi_device *dev, break; WAIT_QUIETLY; } - if (ii >= RTD_ADC_TIMEOUT) { - DPRINTK - ("rtd520: Error: ADC never finished! FifoStatus=0x%x\n", - stat ^ 0x6666); + if (ii >= RTD_ADC_TIMEOUT) return -ETIMEDOUT; - } /* read data */ d = readw(devpriv->las1 + LAS1_ADC_FIFO); @@ -638,10 +634,8 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ fifoStatus = readl(devpriv->las0 + LAS0_ADC); /* check for FIFO full, this automatically halts the ADC! */ - if (!(fifoStatus & FS_ADC_NOT_FULL)) { /* 0 -> full */ - DPRINTK("rtd520: FIFO full! fifo_status=0x%x\n", (fifoStatus ^ 0x6666) & 0x7777); /* should be all 0s */ + if (!(fifoStatus & FS_ADC_NOT_FULL)) /* 0 -> full */ goto abortTransfer; - } status = readw(devpriv->las0 + LAS0_IT); /* if interrupt was not caused by our board, or handled above */ @@ -653,53 +647,29 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ counter interrupt, even though we have already finished, we must handle the possibility that there is no data here */ if (!(fifoStatus & FS_ADC_HEMPTY)) { /* 0 -> 1/2 full */ - /*DPRINTK("rtd520: Sample int, reading 1/2FIFO. fifo_status 0x%x\n", - (fifoStatus ^ 0x6666) & 0x7777); */ - if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0) { - DPRINTK - ("rtd520: comedi read buffer overflow (1/2FIFO) with %ld to go!\n", - devpriv->aiCount); + if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0) goto abortTransfer; - } - if (0 == devpriv->aiCount) { /* counted down */ - DPRINTK("rtd520: Samples Done (1/2). fifo_status was 0x%x\n", (fifoStatus ^ 0x6666) & 0x7777); /* should be all 0s */ + + if (0 == devpriv->aiCount) goto transferDone; - } + comedi_event(dev, s); } else if (devpriv->transCount > 0) { /* read often */ - /*DPRINTK("rtd520: Sample int, reading %d fifo_status 0x%x\n", - devpriv->transCount, (fifoStatus ^ 0x6666) & 0x7777); */ if (fifoStatus & FS_ADC_NOT_EMPTY) { /* 1 -> not empty */ - if (ai_read_n(dev, s, devpriv->transCount) < 0) { - DPRINTK - ("rtd520: comedi read buffer overflow (N) with %ld to go!\n", - devpriv->aiCount); + if (ai_read_n(dev, s, devpriv->transCount) < 0) goto abortTransfer; - } - if (0 == devpriv->aiCount) { /* counted down */ - DPRINTK - ("rtd520: Samples Done (N). fifo_status was 0x%x\n", - (fifoStatus ^ 0x6666) & 0x7777); + + if (0 == devpriv->aiCount) goto transferDone; - } + comedi_event(dev, s); } - } else { /* wait for 1/2 FIFO (old) */ - DPRINTK - ("rtd520: Sample int. Wait for 1/2. fifo_status 0x%x\n", - (fifoStatus ^ 0x6666) & 0x7777); } - } else { - DPRINTK("rtd520: unknown interrupt source!\n"); } overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff; - if (overrun) { - DPRINTK - ("rtd520: Interrupt overrun with %ld to go! over_status=0x%x\n", - devpriv->aiCount, overrun); + if (overrun) goto abortTransfer; - } /* clear the interrupt */ devpriv->intClearMask = status; @@ -723,7 +693,6 @@ transferDone: if (devpriv->aiCount > 0) { /* there shouldn't be anything left */ fifoStatus = readl(devpriv->las0 + LAS0_ADC); - DPRINTK("rtd520: Finishing up. %ld remain, fifoStat=%x\n", devpriv->aiCount, (fifoStatus ^ 0x6666) & 0x7777); /* should read all 0s */ ai_read_dregs(dev, s); /* read anything left in FIFO */ } @@ -738,9 +707,6 @@ transferDone: fifoStatus = readl(devpriv->las0 + LAS0_ADC); overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff; - DPRINTK - ("rtd520: Acquisition complete. %ld ints, intStat=%x, overStat=%x\n", - devpriv->intCount, status, overrun); return IRQ_HANDLED; } @@ -939,10 +905,8 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writel(0, devpriv->las0 + LAS0_OVERRUN); devpriv->intCount = 0; - if (!dev->irq) { /* we need interrupts for this */ - DPRINTK("rtd520: ERROR! No interrupt available!\n"); + if (!dev->irq) /* we need interrupts for this */ return -ENXIO; - } /* start configuration */ /* load channel list and reset CGT */ @@ -950,7 +914,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* setup the common case and override if needed */ if (cmd->chanlist_len > 1) { - /*DPRINTK ("rtd520: Multi channel setup\n"); */ /* pacer start source: SOFTWARE */ writel(0, devpriv->las0 + LAS0_PACER_START); /* burst trigger source: PACER */ @@ -958,7 +921,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* ADC conversion trigger source: BURST */ writel(2, devpriv->las0 + LAS0_ADC_CONVERSION); } else { /* single channel */ - /*DPRINTK ("rtd520: single channel setup\n"); */ /* pacer start source: SOFTWARE */ writel(0, devpriv->las0 + LAS0_PACER_START); /* ADC conversion trigger source: PACER */ @@ -1001,11 +963,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writel((devpriv->transCount - 1) & 0xffff, devpriv->las0 + LAS0_ACNT); } - - DPRINTK - ("rtd520: scanLen=%d transferCount=%d fifoLen=%d\n scanTime(ns)=%d flags=0x%x\n", - cmd->chanlist_len, devpriv->transCount, devpriv->fifoLen, - cmd->scan_begin_arg, devpriv->flags); } else { /* unknown timing, just use 1/2 FIFO */ devpriv->transCount = 0; devpriv->flags &= ~SEND_EOS; @@ -1030,10 +987,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) case TRIG_NONE: /* stop when cancel is called */ devpriv->aiCount = -1; /* read forever */ break; - - default: - DPRINTK("rtd520: Warning! ignoring stop_src mode %d\n", - cmd->stop_src); } /* Scan timing */ @@ -1042,7 +995,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) timer = rtd_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_NEAREST); /* set PACER clock */ - /*DPRINTK ("rtd520: loading %d into pacer\n", timer); */ writel(timer & 0xffffff, devpriv->las0 + LAS0_PCLK); break; @@ -1051,10 +1003,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* pacer start source: EXTERNAL */ writel(1, devpriv->las0 + LAS0_PACER_START); break; - - default: - DPRINTK("rtd520: Warning! ignoring scan_begin_src mode %d\n", - cmd->scan_begin_src); } /* Sample timing within a scan */ @@ -1064,7 +1012,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) timer = rtd_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_NEAREST); /* setup BURST clock */ - /*DPRINTK ("rtd520: loading %d into burst\n", timer); */ writel(timer & 0x3ff, devpriv->las0 + LAS0_BCLK); } @@ -1074,10 +1021,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* burst trigger source: EXTERNAL */ writel(2, devpriv->las0 + LAS0_BURST_START); break; - - default: - DPRINTK("rtd520: Warning! ignoring convert_src mode %d\n", - cmd->convert_src); } /* end configuration */ @@ -1091,11 +1034,9 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (devpriv->transCount > 0) { /* transfer every N samples */ devpriv->intMask = IRQM_ADC_ABOUT_CNT; writew(devpriv->intMask, devpriv->las0 + LAS0_IT); - DPRINTK("rtd520: Transferring every %d\n", devpriv->transCount); } else { /* 1/2 FIFO transfers */ devpriv->intMask = IRQM_ADC_ABOUT_CNT; writew(devpriv->intMask, devpriv->las0 + LAS0_IT); - DPRINTK("rtd520: Transferring every 1/2 FIFO\n"); } /* BUG: start_src is ASSUMED to be TRIG_NOW */ @@ -1122,9 +1063,6 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->aiCount = 0; /* stop and don't transfer any more */ status = readw(devpriv->las0 + LAS0_IT); overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff; - DPRINTK - ("rtd520: Acquisition canceled. %ld ints, intStat=%x, overStat=%x\n", - devpriv->intCount, status, overrun); return 0; } @@ -1161,10 +1099,6 @@ static int rtd_ao_winsn(struct comedi_device *dev, val = data[i] << 3; } - DPRINTK - ("comedi: rtd520 DAC chan=%d range=%d writing %d as 0x%x\n", - chan, range, data[i], val); - /* a typical programming sequence */ writew(val, devpriv->las1 + ((chan == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO)); @@ -1180,12 +1114,8 @@ static int rtd_ao_winsn(struct comedi_device *dev, break; WAIT_QUIETLY; } - if (ii >= RTD_DAC_TIMEOUT) { - DPRINTK - ("rtd520: Error: DAC never finished! FifoStatus=0x%x\n", - stat ^ 0x6666); + if (ii >= RTD_DAC_TIMEOUT) return -ETIMEDOUT; - } } /* return the number of samples read/written */ @@ -1238,8 +1168,6 @@ static int rtd_dio_insn_bits(struct comedi_device *dev, * input lines. */ data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff; - /*DPRINTK("rtd520:port_0 wrote: 0x%x read: 0x%x\n", s->state, data[1]); */ - return insn->n; } @@ -1273,7 +1201,6 @@ static int rtd_dio_insn_config(struct comedi_device *dev, return -EINVAL; } - DPRINTK("rtd520: port_0_direction=0x%x (1 means out)\n", s->io_bits); /* TODO support digital match interrupts and strobes */ devpriv->dioStatus = 0x01; /* set direction */ writew(devpriv->dioStatus, devpriv->las0 + LAS0_DIO_STATUS); @@ -1336,10 +1263,6 @@ static void rtd_pci_latency_quirk(struct comedi_device *dev, struct pci_dev *pcidev) { unsigned char pci_latency; - u16 revision; - - pci_read_config_word(pcidev, PCI_REVISION_ID, &revision); - DPRINTK("%s: PCI revision %d.\n", dev->board_name, revision); pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency); if (pci_latency < 32) { @@ -1347,8 +1270,6 @@ static void rtd_pci_latency_quirk(struct comedi_device *dev, "PCI latency changed from %d to %d\n", pci_latency, 32); pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32); - } else { - DPRINTK("rtd520: PCI latency = %d\n", pci_latency); } } -- cgit v1.2.3 From 16756f7c3f0e17a3b4eedd42d8159657769cbbc8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:04:58 -0700 Subject: staging: comedi: rtd520: remove 'intCount' from the private data This variable is cleared when an ai command is initiated and then incremented with each interrupt. Other than that it's never used. Just remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 6af19bcbcfb..f118e85bef7 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -289,7 +289,6 @@ struct rtdPrivate { void __iomem *las1; void __iomem *lcfg; - unsigned long intCount; /* interrupt count */ long aiCount; /* total transfer size (samples) */ int transCount; /* # to transfer data. 0->1/2FIFO */ int flags; /* flag event modes */ @@ -630,8 +629,6 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ if (!dev->attached) return IRQ_NONE; - devpriv->intCount++; /* DEBUG statistics */ - fifoStatus = readl(devpriv->las0 + LAS0_ADC); /* check for FIFO full, this automatically halts the ADC! */ if (!(fifoStatus & FS_ADC_NOT_FULL)) /* 0 -> full */ @@ -903,7 +900,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writew(devpriv->intMask, devpriv->las0 + LAS0_IT); writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR); writel(0, devpriv->las0 + LAS0_OVERRUN); - devpriv->intCount = 0; if (!dev->irq) /* we need interrupts for this */ return -ENXIO; -- cgit v1.2.3 From 3ff20ef30e0782a860b573f7e9e341424b64003f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:05:44 -0700 Subject: staging: comedi: rtd520: fix > 80 char line checkpatch.pl issues This fixes all the remaining checkpatch.pl issues. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 53 ++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index f118e85bef7..3d68c4f2dfa 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -331,9 +331,9 @@ struct rtdPrivate { Sets the original period to be the true value. Note: you have to check if the value is larger than the counter range! */ -static int rtd_ns_to_timer_base(unsigned int *nanosec, /* desired period (in ns) */ +static int rtd_ns_to_timer_base(unsigned int *nanosec, int round_mode, int base) -{ /* clock period (in ns) */ +{ int divider; switch (round_mode) { @@ -386,18 +386,19 @@ static unsigned short rtdConvertChanGain(struct comedi_device *dev, r |= chan & 0xf; /* Note: we also setup the channel list bipolar flag array */ - if (range < thisboard->range10Start) { /* first batch are +-5 */ - r |= 0x000; /* +-5 range */ - r |= (range & 0x7) << 4; /* gain */ + if (range < thisboard->range10Start) { + /* +-5 range */ + r |= 0x000; + r |= (range & 0x7) << 4; CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex); - } else if (range < thisboard->rangeUniStart) { /* second batch are +-10 */ - r |= 0x100; /* +-10 range */ - /* gain */ + } else if (range < thisboard->rangeUniStart) { + /* +-10 range */ + r |= 0x100; r |= ((range - thisboard->range10Start) & 0x7) << 4; CHAN_ARRAY_SET(devpriv->chanBipolar, chanIndex); - } else { /* last batch is +10 */ - r |= 0x200; /* +10 range */ - /* gain */ + } else { + /* +10 range */ + r |= 0x200; r |= ((range - thisboard->rangeUniStart) & 0x7) << 4; CHAN_ARRAY_CLEAR(devpriv->chanBipolar, chanIndex); } @@ -640,10 +641,14 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ return IRQ_HANDLED; if (status & IRQM_ADC_ABOUT_CNT) { /* sample count -> read FIFO */ - /* since the priority interrupt controller may have queued a sample - counter interrupt, even though we have already finished, - we must handle the possibility that there is no data here */ - if (!(fifoStatus & FS_ADC_HEMPTY)) { /* 0 -> 1/2 full */ + /* + * since the priority interrupt controller may have queued + * a sample counter interrupt, even though we have already + * finished, we must handle the possibility that there is + * no data here + */ + if (!(fifoStatus & FS_ADC_HEMPTY)) { + /* FIFO half full */ if (ai_read_n(dev, s, devpriv->fifoLen / 2) < 0) goto abortTransfer; @@ -651,8 +656,9 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */ goto transferDone; comedi_event(dev, s); - } else if (devpriv->transCount > 0) { /* read often */ - if (fifoStatus & FS_ADC_NOT_EMPTY) { /* 1 -> not empty */ + } else if (devpriv->transCount > 0) { + if (fifoStatus & FS_ADC_NOT_EMPTY) { + /* FIFO not empty */ if (ai_read_n(dev, s, devpriv->transCount) < 0) goto abortTransfer; @@ -928,8 +934,11 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* scan_begin_arg is in nanoseconds */ /* find out how many samples to wait before transferring */ if (cmd->flags & TRIG_WAKE_EOS) { - /* this may generate un-sustainable interrupt rates */ - /* the application is responsible for doing the right thing */ + /* + * this may generate un-sustainable interrupt rates + * the application is responsible for doing the + * right thing + */ devpriv->transCount = cmd->chanlist_len; devpriv->flags |= SEND_EOS; } else { @@ -1004,7 +1013,8 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* Sample timing within a scan */ switch (cmd->convert_src) { case TRIG_TIMER: /* periodic */ - if (cmd->chanlist_len > 1) { /* only needed for multi-channel */ + if (cmd->chanlist_len > 1) { + /* only needed for multi-channel */ timer = rtd_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_NEAREST); /* setup BURST clock */ @@ -1098,7 +1108,8 @@ static int rtd_ao_winsn(struct comedi_device *dev, /* a typical programming sequence */ writew(val, devpriv->las1 + ((chan == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO)); - writew(0, devpriv->las0 + ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2)); + writew(0, devpriv->las0 + + ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2)); devpriv->aoValue[chan] = data[i]; /* save for read back */ -- cgit v1.2.3 From 90973498d4f1fcb054d9221b247bff91b0f30808 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:06:03 -0700 Subject: staging: comedi: rtd520: allow attaching without interrupt support Interrupts ares only required for the ai subdevice command support. Allow the driver to attach to the board even if request_irq() fails. Only hook up the command support if the interrupt is available. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 3d68c4f2dfa..3c4aa65ad49 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -907,9 +907,6 @@ static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR); writel(0, devpriv->las0 + LAS0_OVERRUN); - if (!dev->irq) /* we need interrupts for this */ - return -ENXIO; - /* start configuration */ /* load channel list and reset CGT */ rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist); @@ -1328,16 +1325,21 @@ static int rtd_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) rtd_pci_latency_quirk(dev, pcidev); + if (pcidev->irq) { + ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } + ret = comedi_alloc_subdevices(dev, 4); if (ret) return ret; s = &dev->subdevices[0]; - dev->read_subdev = s; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF; s->n_chan = thisboard->aiChans; s->maxdata = (1 << thisboard->aiBits) - 1; if (thisboard->aiMaxGain <= 32) @@ -1347,9 +1349,13 @@ static int rtd_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s->len_chanlist = RTD_MAX_CHANLIST; /* devpriv->fifoLen */ s->insn_read = rtd_ai_rinsn; - s->do_cmd = rtd_ai_cmd; - s->do_cmdtest = rtd_ai_cmdtest; - s->cancel = rtd_ai_cancel; + if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; + s->do_cmd = rtd_ai_cmd; + s->do_cmdtest = rtd_ai_cmdtest; + s->cancel = rtd_ai_cancel; + } s = &dev->subdevices[1]; /* analog output subdevice */ @@ -1381,13 +1387,6 @@ static int rtd_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) rtd_init_board(dev); - /* check if our interrupt is available and get it */ - ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED, - dev->board_name, dev); - if (ret < 0) - return ret; - dev->irq = pcidev->irq; - ret = rtd520_probe_fifo_depth(dev); if (ret < 0) return ret; -- cgit v1.2.3 From 5d55a30c50a3740b415080ce9a9c7b2c642daec7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:06:34 -0700 Subject: staging: comedi: rtd520: remove 'aiChans' and 'aiBits' from boardinfo All the boards supported by this driver have the same number of analog input channels and resolution. Remove the boardinfo for this and just open-code the values in the attach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 3c4aa65ad49..de15350bb60 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -252,8 +252,6 @@ static const struct comedi_lrange rtd_ao_range = { struct rtdBoard { const char *name; int device_id; - int aiChans; - int aiBits; int aiMaxGain; int range10Start; /* start of +-10V range */ int rangeUniStart; /* start of +10V range */ @@ -263,16 +261,12 @@ static const struct rtdBoard rtd520Boards[] = { { .name = "DM7520", .device_id = 0x7520, - .aiChans = 16, - .aiBits = 12, .aiMaxGain = 32, .range10Start = 6, .rangeUniStart = 12, }, { .name = "PCI4520", .device_id = 0x4520, - .aiChans = 16, - .aiBits = 12, .aiMaxGain = 128, .range10Start = 8, .rangeUniStart = 16, @@ -1340,8 +1334,8 @@ static int rtd_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) /* analog input subdevice */ s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF; - s->n_chan = thisboard->aiChans; - s->maxdata = (1 << thisboard->aiBits) - 1; + s->n_chan = 16; + s->maxdata = 0x0fff; if (thisboard->aiMaxGain <= 32) s->range_table = &rtd_ai_7520_range; else @@ -1362,7 +1356,7 @@ static int rtd_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; s->n_chan = 2; - s->maxdata = (1 << thisboard->aiBits) - 1; + s->maxdata = 0x0fff; s->range_table = &rtd_ao_range; s->insn_write = rtd_ao_winsn; s->insn_read = rtd_ao_rinsn; -- cgit v1.2.3 From 8a799460c280568e3c59bcc84f3443035468486f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:07:01 -0700 Subject: staging: comedi: rtd520: remove 'aiMaxGain' from boardinfo This value is only used in the attach to determine which range table the analog input subdevice uses. Remove this variable and just pass the range table pointer in the boardinfo. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index de15350bb60..dc470ef9135 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -252,24 +252,24 @@ static const struct comedi_lrange rtd_ao_range = { struct rtdBoard { const char *name; int device_id; - int aiMaxGain; int range10Start; /* start of +-10V range */ int rangeUniStart; /* start of +10V range */ + const struct comedi_lrange *ai_range; }; static const struct rtdBoard rtd520Boards[] = { { .name = "DM7520", .device_id = 0x7520, - .aiMaxGain = 32, .range10Start = 6, .rangeUniStart = 12, + .ai_range = &rtd_ai_7520_range, }, { .name = "PCI4520", .device_id = 0x4520, - .aiMaxGain = 128, .range10Start = 8, .rangeUniStart = 16, + .ai_range = &rtd_ai_4520_range, }, }; @@ -1336,10 +1336,7 @@ static int rtd_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF; s->n_chan = 16; s->maxdata = 0x0fff; - if (thisboard->aiMaxGain <= 32) - s->range_table = &rtd_ai_7520_range; - else - s->range_table = &rtd_ai_4520_range; + s->range_table = thisboard->ai_range; s->len_chanlist = RTD_MAX_CHANLIST; /* devpriv->fifoLen */ s->insn_read = rtd_ai_rinsn; -- cgit v1.2.3 From 37f97e500db829ad6216776a7f59a3173670477b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:07:21 -0700 Subject: staging: comedi: rtd520: add whitespace to the subdevice init To improve the readability, add some whitespace to the subdevice init. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 59 ++++++++++++++++----------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index dc470ef9135..6c694fba997 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1332,49 +1332,48 @@ static int rtd_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) s = &dev->subdevices[0]; /* analog input subdevice */ - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF; - s->n_chan = 16; - s->maxdata = 0x0fff; - s->range_table = thisboard->ai_range; - - s->len_chanlist = RTD_MAX_CHANLIST; /* devpriv->fifoLen */ - s->insn_read = rtd_ai_rinsn; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF; + s->n_chan = 16; + s->maxdata = 0x0fff; + s->range_table = thisboard->ai_range; + s->len_chanlist = RTD_MAX_CHANLIST; + s->insn_read = rtd_ai_rinsn; if (dev->irq) { dev->read_subdev = s; - s->subdev_flags |= SDF_CMD_READ; - s->do_cmd = rtd_ai_cmd; - s->do_cmdtest = rtd_ai_cmdtest; - s->cancel = rtd_ai_cancel; + s->subdev_flags |= SDF_CMD_READ; + s->do_cmd = rtd_ai_cmd; + s->do_cmdtest = rtd_ai_cmdtest; + s->cancel = rtd_ai_cancel; } s = &dev->subdevices[1]; /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 2; - s->maxdata = 0x0fff; - s->range_table = &rtd_ao_range; - s->insn_write = rtd_ao_winsn; - s->insn_read = rtd_ao_rinsn; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 2; + s->maxdata = 0x0fff; + s->range_table = &rtd_ao_range; + s->insn_write = rtd_ao_winsn; + s->insn_read = rtd_ao_rinsn; s = &dev->subdevices[2]; /* digital i/o subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; /* we only support port 0 right now. Ignoring port 1 and user IO */ - s->n_chan = 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = rtd_dio_insn_bits; - s->insn_config = rtd_dio_insn_config; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = rtd_dio_insn_bits; + s->insn_config = rtd_dio_insn_config; /* timer/counter subdevices (not currently supported) */ s = &dev->subdevices[3]; - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 3; - s->maxdata = 0xffff; + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 3; + s->maxdata = 0xffff; rtd_init_board(dev); -- cgit v1.2.3 From fe559c022444b8335a6417eb31731b5124faf245 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:07:47 -0700 Subject: staging: comedi: rtd520: move #include's to top of file Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 6c694fba997..e42bd6b1153 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -107,6 +107,8 @@ Configuration options: #include "../comedidev.h" #include "comedi_fc.h" +#include "rtd520.h" +#include "plx9080.h" /*====================================================================== Driver specific stuff (tunable) @@ -155,9 +157,6 @@ Configuration options: /* min speed when only 1 channel (no burst counter) */ #define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */ -#include "rtd520.h" -#include "plx9080.h" - /* Setup continuous ring of 1/2 FIFO transfers. See RTD manual p91 */ #define DMA_MODE_BITS (\ PLX_LOCAL_BUS_16_WIDE_BITS \ -- cgit v1.2.3 From 2bb01a014fd35629bd646a693e9d4368e95b2a4a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:08:07 -0700 Subject: staging: comedi: rtd520: remove unused LAS0_SPARE_* defines These register offset defines are not used. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.h b/drivers/staging/comedi/drivers/rtd520.h index a3ec2599c4b..c8bd284ec4b 100644 --- a/drivers/staging/comedi/drivers/rtd520.h +++ b/drivers/staging/comedi/drivers/rtd520.h @@ -29,22 +29,16 @@ LAS0 Runtime Area Local Address Space 0 Offset Read Function Write Function */ -#define LAS0_SPARE_00 0x0000 /* - - */ -#define LAS0_SPARE_04 0x0004 /* - - */ #define LAS0_USER_IO 0x0008 /* Read User Inputs Write User Outputs */ -#define LAS0_SPARE_0C 0x000C /* - - */ #define LAS0_ADC 0x0010 /* Read FIFO Status Software A/D Start */ #define LAS0_DAC1 0x0014 /* - Software D/A1 Update */ #define LAS0_DAC2 0x0018 /* - Software D/A2 Update */ -#define LAS0_SPARE_1C 0x001C /* - - */ -#define LAS0_SPARE_20 0x0020 /* - - */ #define LAS0_DAC 0x0024 /* - Software Simultaneous D/A1 and D/A2 Update */ #define LAS0_PACER 0x0028 /* Software Pacer Start Software Pacer Stop */ #define LAS0_TIMER 0x002C /* Read Timer Counters Status HDIN Software Trigger */ #define LAS0_IT 0x0030 /* Read Interrupt Status Write Interrupt Enable Mask Register */ #define LAS0_CLEAR 0x0034 /* Clear ITs set by Clear Mask Set Interrupt Clear Mask */ #define LAS0_OVERRUN 0x0038 /* Read pending interrupts Clear Overrun Register */ -#define LAS0_SPARE_3C 0x003C /* - - */ /* LAS0 Runtime Area Timer/Counter,Dig.IO -- cgit v1.2.3 From 9ef55e9f0eaa8512dee1edc360915c388a7ac4d9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:08:24 -0700 Subject: staging: comedi: rtd520: cleanup the LAS0_* defines Fixes all the > 80 char checkpatch.pl issues with these defines. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.h | 167 +++++++++++++++----------------- 1 file changed, 78 insertions(+), 89 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.h b/drivers/staging/comedi/drivers/rtd520.h index c8bd284ec4b..7d0b47d6b4a 100644 --- a/drivers/staging/comedi/drivers/rtd520.h +++ b/drivers/staging/comedi/drivers/rtd520.h @@ -26,95 +26,84 @@ */ /* - LAS0 Runtime Area - Local Address Space 0 Offset Read Function Write Function -*/ -#define LAS0_USER_IO 0x0008 /* Read User Inputs Write User Outputs */ -#define LAS0_ADC 0x0010 /* Read FIFO Status Software A/D Start */ -#define LAS0_DAC1 0x0014 /* - Software D/A1 Update */ -#define LAS0_DAC2 0x0018 /* - Software D/A2 Update */ -#define LAS0_DAC 0x0024 /* - Software Simultaneous D/A1 and D/A2 Update */ -#define LAS0_PACER 0x0028 /* Software Pacer Start Software Pacer Stop */ -#define LAS0_TIMER 0x002C /* Read Timer Counters Status HDIN Software Trigger */ -#define LAS0_IT 0x0030 /* Read Interrupt Status Write Interrupt Enable Mask Register */ -#define LAS0_CLEAR 0x0034 /* Clear ITs set by Clear Mask Set Interrupt Clear Mask */ -#define LAS0_OVERRUN 0x0038 /* Read pending interrupts Clear Overrun Register */ - -/* - LAS0 Runtime Area Timer/Counter,Dig.IO - Name Local Address Function -*/ -#define LAS0_PCLK 0x0040 /* Pacer Clock value (24bit) Pacer Clock load (24bit) */ -#define LAS0_BCLK 0x0044 /* Burst Clock value (10bit) Burst Clock load (10bit) */ -#define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter value (10bit) A/D Sample counter load (10bit) */ -#define LAS0_DAC1_UCNT 0x004C /* D/A1 Update counter value (10 bit) D/A1 Update counter load (10bit) */ -#define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter value (10 bit) D/A2 Update counter load (10bit) */ -#define LAS0_DCNT 0x0054 /* Delay counter value (16 bit) Delay counter load (16bit) */ -#define LAS0_ACNT 0x0058 /* About counter value (16 bit) About counter load (16bit) */ -#define LAS0_DAC_CLK 0x005C /* DAC clock value (16bit) DAC clock load (16bit) */ -#define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 User TC 0 value Load count in TC Counter 0 */ -#define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 User TC 1 value Load count in TC Counter 1 */ -#define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 User TC 2 value Load count in TC Counter 2 */ -#define LAS0_UTC_CTRL 0x006C /* 8254 TC Control Word Program counter mode for TC */ -#define LAS0_DIO0 0x0070 /* Digital I/O Port 0 Read Port Digital I/O Port 0 Write Port */ -#define LAS0_DIO1 0x0074 /* Digital I/O Port 1 Read Port Digital I/O Port 1 Write Port */ -#define LAS0_DIO0_CTRL 0x0078 /* Clear digital IRQ status flag/read Clear digital chip/program Port 0 */ -#define LAS0_DIO_STATUS 0x007C /* Read Digital I/O Status word Program digital control register & */ - -/* - LAS0 Setup Area - Name Local Address Function -*/ -#define LAS0_BOARD_RESET 0x0100 /* Board reset */ -#define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */ -#define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */ -#define LAS0_ADC_CONVERSION 0x010C /* A/D Conversion Signal select */ -#define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */ -#define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */ -#define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */ -#define LAS0_ACNT_STOP_ENABLE 0x011C /* About Counter Stop Enable */ -#define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */ -#define LAS0_DIN_START 0x0124 /* High Speed Digital Input Sampling Signal select */ -#define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */ -#define LAS0_ADC_FIFO_CLEAR 0x012C /* A/D FIFO Clear */ -#define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */ -#define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */ -#define LAS0_CG_DATA 0x0138 /* Digital Table Write */ -#define LAS0_CGT_ENABLE 0x013C /* Channel Gain Table Enable */ -#define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */ -#define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */ -#define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */ -#define LAS0_CGT_CLEAR 0x014C /* Clear Channel Gain Table */ -#define LAS0_DAC1_CTRL 0x0150 /* D/A1 output type/range */ -#define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */ -#define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */ -#define LAS0_DAC1_RESET 0x015C /* D/A1 FIFO reset */ -#define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */ -#define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */ -#define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */ -#define LAS0_DAC2_CYCLE 0x016C /* D/A2 cycle mode */ -#define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */ -#define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 FIFO clear */ -#define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */ -#define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */ -#define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */ -#define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */ -#define LAS0_SBUS1_SRC 0x018C /* SyncBus 1 Source select */ -#define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */ -#define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */ -#define LAS0_SBUS2_ENABLE 0x019C /* SyncBus 2 enable */ -#define LAS0_ETRG_POLARITY 0x01A4 /* External Trigger polarity select */ -#define LAS0_EINT_POLARITY 0x01A8 /* External Interrupt polarity select */ -#define LAS0_UTC0_CLOCK 0x01AC /* UTC0 Clock select */ -#define LAS0_UTC0_GATE 0x01B0 /* UTC0 Gate select */ -#define LAS0_UTC1_CLOCK 0x01B4 /* UTC1 Clock select */ -#define LAS0_UTC1_GATE 0x01B8 /* UTC1 Gate select */ -#define LAS0_UTC2_CLOCK 0x01BC /* UTC2 Clock select */ -#define LAS0_UTC2_GATE 0x01C0 /* UTC2 Gate select */ -#define LAS0_UOUT0_SELECT 0x01C4 /* User Output 0 source select */ -#define LAS0_UOUT1_SELECT 0x01C8 /* User Output 1 source select */ -#define LAS0_DMA0_RESET 0x01CC /* DMA0 Request state machine reset */ -#define LAS0_DMA1_RESET 0x01D0 /* DMA1 Request state machine reset */ + * Local Address Space 0 Offsets + */ +#define LAS0_USER_IO 0x0008 /* User I/O */ +#define LAS0_ADC 0x0010 /* FIFO Status/Software A/D Start */ +#define LAS0_DAC1 0x0014 /* Software D/A1 Update (w) */ +#define LAS0_DAC2 0x0018 /* Software D/A2 Update (w) */ +#define LAS0_DAC 0x0024 /* Software Simultaneous Update (w) */ +#define LAS0_PACER 0x0028 /* Software Pacer Start/Stop */ +#define LAS0_TIMER 0x002c /* Timer Status/HDIN Software Trig. */ +#define LAS0_IT 0x0030 /* Interrupt Status/Enable */ +#define LAS0_CLEAR 0x0034 /* Clear/Set Interrupt Clear Mask */ +#define LAS0_OVERRUN 0x0038 /* Pending interrupts/Clear Overrun */ +#define LAS0_PCLK 0x0040 /* Pacer Clock (24bit) */ +#define LAS0_BCLK 0x0044 /* Burst Clock (10bit) */ +#define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter (10bit) */ +#define LAS0_DAC1_UCNT 0x004c /* D/A1 Update counter (10 bit) */ +#define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter (10 bit) */ +#define LAS0_DCNT 0x0054 /* Delay counter (16 bit) */ +#define LAS0_ACNT 0x0058 /* About counter (16 bit) */ +#define LAS0_DAC_CLK 0x005c /* DAC clock (16bit) */ +#define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 */ +#define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 */ +#define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 */ +#define LAS0_UTC_CTRL 0x006c /* 8254 TC Control */ +#define LAS0_DIO0 0x0070 /* Digital I/O Port 0 */ +#define LAS0_DIO1 0x0074 /* Digital I/O Port 1 */ +#define LAS0_DIO0_CTRL 0x0078 /* Digital I/O Control */ +#define LAS0_DIO_STATUS 0x007c /* Digital I/O Status */ +#define LAS0_BOARD_RESET 0x0100 /* Board reset */ +#define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */ +#define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */ +#define LAS0_ADC_CONVERSION 0x010c /* A/D Conversion Signal select */ +#define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */ +#define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */ +#define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */ +#define LAS0_ACNT_STOP_ENABLE 0x011c /* About Counter Stop Enable */ +#define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */ +#define LAS0_DIN_START 0x0124 /* HiSpd DI Sampling Signal select */ +#define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */ +#define LAS0_ADC_FIFO_CLEAR 0x012c /* A/D FIFO Clear */ +#define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */ +#define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */ +#define LAS0_CG_DATA 0x0138 /* Digital Table Write */ +#define LAS0_CGT_ENABLE 0x013c /* Channel Gain Table Enable */ +#define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */ +#define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */ +#define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */ +#define LAS0_CGT_CLEAR 0x014c /* Clear Channel Gain Table */ +#define LAS0_DAC1_CTRL 0x0150 /* D/A1 output type/range */ +#define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */ +#define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */ +#define LAS0_DAC1_RESET 0x015c /* D/A1 FIFO reset */ +#define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */ +#define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */ +#define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */ +#define LAS0_DAC2_CYCLE 0x016c /* D/A2 cycle mode */ +#define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */ +#define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 FIFO clear */ +#define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */ +#define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */ +#define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */ +#define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */ +#define LAS0_SBUS1_SRC 0x018c /* SyncBus 1 Source select */ +#define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */ +#define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */ +#define LAS0_SBUS2_ENABLE 0x019c /* SyncBus 2 enable */ +#define LAS0_ETRG_POLARITY 0x01a4 /* Ext. Trigger polarity select */ +#define LAS0_EINT_POLARITY 0x01a8 /* Ext. Interrupt polarity select */ +#define LAS0_UTC0_CLOCK 0x01ac /* UTC0 Clock select */ +#define LAS0_UTC0_GATE 0x01b0 /* UTC0 Gate select */ +#define LAS0_UTC1_CLOCK 0x01b4 /* UTC1 Clock select */ +#define LAS0_UTC1_GATE 0x01b8 /* UTC1 Gate select */ +#define LAS0_UTC2_CLOCK 0x01bc /* UTC2 Clock select */ +#define LAS0_UTC2_GATE 0x01c0 /* UTC2 Gate select */ +#define LAS0_UOUT0_SELECT 0x01c4 /* User Output 0 source select */ +#define LAS0_UOUT1_SELECT 0x01c8 /* User Output 1 source select */ +#define LAS0_DMA0_RESET 0x01cc /* DMA0 Request state machine reset */ +#define LAS0_DMA1_RESET 0x01d0 /* DMA1 Request state machine reset */ /* LAS1 -- cgit v1.2.3 From f4c1a4f89b1740611fd3c1fa36d810a8629eff23 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:08:48 -0700 Subject: staging: comedi: rtd520: cleanup the LAS1_* defines Fixes all the > 80 char checkpatch.pl issues with these defines. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.h b/drivers/staging/comedi/drivers/rtd520.h index 7d0b47d6b4a..887cd468dc9 100644 --- a/drivers/staging/comedi/drivers/rtd520.h +++ b/drivers/staging/comedi/drivers/rtd520.h @@ -106,13 +106,12 @@ #define LAS0_DMA1_RESET 0x01d0 /* DMA1 Request state machine reset */ /* - LAS1 - Name Local Address Function -*/ -#define LAS1_ADC_FIFO 0x0000 /* Read A/D FIFO (16bit) - */ -#define LAS1_HDIO_FIFO 0x0004 /* Read High Speed Digital Input FIFO (16bit) - */ -#define LAS1_DAC1_FIFO 0x0008 /* - Write D/A1 FIFO (16bit) */ -#define LAS1_DAC2_FIFO 0x000C /* - Write D/A2 FIFO (16bit) */ + * Local Address Space 1 Offsets + */ +#define LAS1_ADC_FIFO 0x0000 /* A/D FIFO (16bit) */ +#define LAS1_HDIO_FIFO 0x0004 /* HiSpd DI FIFO (16bit) */ +#define LAS1_DAC1_FIFO 0x0008 /* D/A1 FIFO (16bit) */ +#define LAS1_DAC2_FIFO 0x000c /* D/A2 FIFO (16bit) */ /* LCFG: PLX 9080 local config & runtime registers -- cgit v1.2.3 From f9301ef8d51a43513da4e4c8e41a1e4cb9bb0884 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:09:04 -0700 Subject: staging: comedi: rtd520: cleanup the LCFG_* defines Fixes all the > 80 char checkpatch.pl issues with these defines. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.h | 35 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.h b/drivers/staging/comedi/drivers/rtd520.h index 887cd468dc9..c521efa273a 100644 --- a/drivers/staging/comedi/drivers/rtd520.h +++ b/drivers/staging/comedi/drivers/rtd520.h @@ -114,24 +114,23 @@ #define LAS1_DAC2_FIFO 0x000c /* D/A2 FIFO (16bit) */ /* - LCFG: PLX 9080 local config & runtime registers - Name Local Address Function -*/ -#define LCFG_ITCSR 0x0068 /* INTCSR, Interrupt Control/Status Register */ -#define LCFG_DMAMODE0 0x0080 /* DMA Channel 0 Mode Register */ -#define LCFG_DMAPADR0 0x0084 /* DMA Channel 0 PCI Address Register */ -#define LCFG_DMALADR0 0x0088 /* DMA Channel 0 Local Address Reg */ -#define LCFG_DMASIZ0 0x008C /* DMA Channel 0 Transfer Size (Bytes) Register */ -#define LCFG_DMADPR0 0x0090 /* DMA Channel 0 Descriptor Pointer Register */ -#define LCFG_DMAMODE1 0x0094 /* DMA Channel 1 Mode Register */ -#define LCFG_DMAPADR1 0x0098 /* DMA Channel 1 PCI Address Register */ -#define LCFG_DMALADR1 0x009C /* DMA Channel 1 Local Address Register */ -#define LCFG_DMASIZ1 0x00A0 /* DMA Channel 1 Transfer Size (Bytes) Register */ -#define LCFG_DMADPR1 0x00A4 /* DMA Channel 1 Descriptor Pointer Register */ -#define LCFG_DMACSR0 0x00A8 /* DMA Channel 0 Command/Status Register */ -#define LCFG_DMACSR1 0x00A9 /* DMA Channel 0 Command/Status Register */ -#define LCFG_DMAARB 0x00AC /* DMA Arbitration Register */ -#define LCFG_DMATHR 0x00B0 /* DMA Threshold Register */ + * PLX 9080 local config & runtime registers + */ +#define LCFG_ITCSR 0x0068 /* Interrupt Control/Status */ +#define LCFG_DMAMODE0 0x0080 /* DMA0 Mode */ +#define LCFG_DMAPADR0 0x0084 /* DMA0 PCI Address */ +#define LCFG_DMALADR0 0x0088 /* DMA0 Local Address */ +#define LCFG_DMASIZ0 0x008c /* DMA0 Transfer Size (Bytes) */ +#define LCFG_DMADPR0 0x0090 /* DMA0 Descriptor Pointer */ +#define LCFG_DMAMODE1 0x0094 /* DMA1 Mode */ +#define LCFG_DMAPADR1 0x0098 /* DMA1 PCI Address */ +#define LCFG_DMALADR1 0x009c /* DMA1 Local Address */ +#define LCFG_DMASIZ1 0x00a0 /* DMA1 Transfer Size (Bytes) */ +#define LCFG_DMADPR1 0x00a4 /* DMA1 Descriptor Pointer */ +#define LCFG_DMACSR0 0x00a8 /* DMA0 Command/Status */ +#define LCFG_DMACSR1 0x00a9 /* DMA0 Command/Status */ +#define LCFG_DMAARB 0x00ac /* DMA Arbitration */ +#define LCFG_DMATHR 0x00b0 /* DMA Threshold */ /*====================================================================== Resister bit definitions -- cgit v1.2.3 From 6478c228950c8f51fa595162569d24f27c5213fc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:09:31 -0700 Subject: staging: comedi: rtd520: cleanup FS_* defines Convert these to bit shifts and cleanup the whitespace and comments. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.h | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.h b/drivers/staging/comedi/drivers/rtd520.h index c521efa273a..e5d21e47907 100644 --- a/drivers/staging/comedi/drivers/rtd520.h +++ b/drivers/staging/comedi/drivers/rtd520.h @@ -132,23 +132,19 @@ #define LCFG_DMAARB 0x00ac /* DMA Arbitration */ #define LCFG_DMATHR 0x00b0 /* DMA Threshold */ -/*====================================================================== - Resister bit definitions -======================================================================*/ - /* FIFO Status Word Bits (RtdFifoStatus) */ -#define FS_DAC1_NOT_EMPTY 0x0001 /* D0 - DAC1 FIFO not empty */ -#define FS_DAC1_HEMPTY 0x0002 /* D1 - DAC1 FIFO half empty */ -#define FS_DAC1_NOT_FULL 0x0004 /* D2 - DAC1 FIFO not full */ -#define FS_DAC2_NOT_EMPTY 0x0010 /* D4 - DAC2 FIFO not empty */ -#define FS_DAC2_HEMPTY 0x0020 /* D5 - DAC2 FIFO half empty */ -#define FS_DAC2_NOT_FULL 0x0040 /* D6 - DAC2 FIFO not full */ -#define FS_ADC_NOT_EMPTY 0x0100 /* D8 - ADC FIFO not empty */ -#define FS_ADC_HEMPTY 0x0200 /* D9 - ADC FIFO half empty */ -#define FS_ADC_NOT_FULL 0x0400 /* D10 - ADC FIFO not full */ -#define FS_DIN_NOT_EMPTY 0x1000 /* D12 - DIN FIFO not empty */ -#define FS_DIN_HEMPTY 0x2000 /* D13 - DIN FIFO half empty */ -#define FS_DIN_NOT_FULL 0x4000 /* D14 - DIN FIFO not full */ +#define FS_DAC1_NOT_EMPTY (1 << 0) /* DAC1 FIFO not empty */ +#define FS_DAC1_HEMPTY (1 << 1) /* DAC1 FIFO half empty */ +#define FS_DAC1_NOT_FULL (1 << 2) /* DAC1 FIFO not full */ +#define FS_DAC2_NOT_EMPTY (1 << 4) /* DAC2 FIFO not empty */ +#define FS_DAC2_HEMPTY (1 << 5) /* DAC2 FIFO half empty */ +#define FS_DAC2_NOT_FULL (1 << 6) /* DAC2 FIFO not full */ +#define FS_ADC_NOT_EMPTY (1 << 8) /* ADC FIFO not empty */ +#define FS_ADC_HEMPTY (1 << 9) /* ADC FIFO half empty */ +#define FS_ADC_NOT_FULL (1 << 10) /* ADC FIFO not full */ +#define FS_DIN_NOT_EMPTY (1 << 12) /* DIN FIFO not empty */ +#define FS_DIN_HEMPTY (1 << 13) /* DIN FIFO half empty */ +#define FS_DIN_NOT_FULL (1 << 14) /* DIN FIFO not full */ /* Timer Status Word Bits (GetTimerStatus) */ #define TS_PCLK_GATE 0x0001 -- cgit v1.2.3 From 65c7815a4c03019ce3a65766e3ff7a2894814c98 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 10:10:14 -0700 Subject: staging: comedi: rtd520: cleanup TS_* defines Convert these to bit shifts and cleanup the whitespace and comments. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.h | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.h b/drivers/staging/comedi/drivers/rtd520.h index e5d21e47907..25188a58145 100644 --- a/drivers/staging/comedi/drivers/rtd520.h +++ b/drivers/staging/comedi/drivers/rtd520.h @@ -147,19 +147,11 @@ #define FS_DIN_NOT_FULL (1 << 14) /* DIN FIFO not full */ /* Timer Status Word Bits (GetTimerStatus) */ -#define TS_PCLK_GATE 0x0001 -/* D0 - Pacer Clock Gate [0 - gated, 1 - enabled] */ -#define TS_BCLK_GATE 0x0002 -/* D1 - Burst Clock Gate [0 - disabled, 1 - running] */ -#define TS_DCNT_GATE 0x0004 -/* D2 - Pacer Clock Delayed Start Trigger [0 - delay over, 1 - delay in */ -/* progress] */ -#define TS_ACNT_GATE 0x0008 -/* D3 - Pacer Clock About Trigger [0 - completed, 1 - in progress] */ -#define TS_PCLK_RUN 0x0010 -/* D4 - Pacer Clock Shutdown Flag [0 - Pacer Clock cannot be start */ -/* triggered only by Software Pacer Start Command, 1 - Pacer Clock can */ -/* be start triggered] */ +#define TS_PCLK_GATE (1 << 0) /* Pacer Clock Gate enabled */ +#define TS_BCLK_GATE (1 << 1) /* Burst Clock Gate running */ +#define TS_DCNT_GATE (1 << 2) /* Pacer Clock Delayed Start Trig. */ +#define TS_ACNT_GATE (1 << 3) /* Pacer Clock About Trig. */ +#define TS_PCLK_RUN (1 << 4) /* Pacer Clock Shutdown Flag */ /* External Trigger polarity select */ /* External Interrupt polarity select */ -- cgit v1.2.3 From 3974c5c08d50fb3a23ec825186a60535264142e8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:51:16 -0700 Subject: staging: comedi: addi_common: move module init code to EOF Move the module_{init,exit} code and associated variables to the end of the file. Use module_comedi_pci_driver() to remove the module init boilerplate. For aesthetic reasons, rename the comedi_driver and pci_driver from driver_* to *_driver. Remove the forward declarations for i_ADDI_{Attach,Detach}. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 77 ++++++++-------------- .../staging/comedi/drivers/addi-data/addi_common.h | 2 - 2 files changed, 29 insertions(+), 50 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index b166698c846..6d7f6ea45c6 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -1401,54 +1401,6 @@ static const struct addi_board boardtypes[] = { #endif }; -static struct comedi_driver driver_addi = { - .driver_name = ADDIDATA_DRIVER_NAME, - .module = THIS_MODULE, - .attach = i_ADDI_Attach, - .detach = i_ADDI_Detach, - .num_names = ARRAY_SIZE(boardtypes), - .board_name = &boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), -}; - -static int __devinit driver_addi_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &driver_addi); -} - -static void __devexit driver_addi_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver driver_addi_pci_driver = { - .id_table = addi_apci_tbl, - .probe = &driver_addi_pci_probe, - .remove = __devexit_p(&driver_addi_pci_remove) -}; - -static int __init driver_addi_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&driver_addi); - if (retval < 0) - return retval; - - driver_addi_pci_driver.name = (char *)driver_addi.driver_name; - return pci_register_driver(&driver_addi_pci_driver); -} - -static void __exit driver_addi_cleanup_module(void) -{ - pci_unregister_driver(&driver_addi_pci_driver); - comedi_driver_unregister(&driver_addi); -} - -module_init(driver_addi_init_module); -module_exit(driver_addi_cleanup_module); - /* +----------------------------------------------------------------------------+ | Function name :static int i_ADDI_Attach(struct comedi_device *dev, | @@ -1938,3 +1890,32 @@ static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_su return insn->n; } + +static struct comedi_driver addi_driver = { + .driver_name = ADDIDATA_DRIVER_NAME, + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(boardtypes), + .board_name = &boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit addi_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &addi_driver); +} + +static void __devexit addi_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static struct pci_driver addi_pci_driver = { + .name = ADDIDATA_DRIVER_NAME, + .id_table = addi_apci_tbl, + .probe = &addi_pci_probe, + .remove = __devexit_p(&addi_pci_remove), +}; +module_comedi_pci_driver(addi_driver, addi_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index b7bbb7164f5..60047dec4af 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -414,8 +414,6 @@ struct addi_private { static unsigned short pci_list_builded; /* set to 1 when list of card is known */ /* Function declarations */ -static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it); -static void i_ADDI_Detach(struct comedi_device *dev); static int i_ADDI_Reset(struct comedi_device *dev); static irqreturn_t v_ADDI_Interrupt(int irq, void *d); -- cgit v1.2.3 From 3d41c44370a9a1e78e53c9997289347ec97d46ee Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:51:33 -0700 Subject: staging: comedi: addi-data: move the main #include's to the drivers The addi-data drivers are all built by the main driver files including addi-data/addi_common.c. That file then includes other files depending on what driver is being compiled. This is makes the code quite messy and hard to follow. Start cleaning it up by removing the unneeded #include's in addi_common.c and moving the some of the comedi #include's into the individual driver files. This is the first step in getting rid of the #ifdef'ery in addi_common.c. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 22 ---------------------- drivers/staging/comedi/drivers/addi_apci_035.c | 6 ++++++ drivers/staging/comedi/drivers/addi_apci_1032.c | 6 ++++++ drivers/staging/comedi/drivers/addi_apci_1500.c | 6 ++++++ drivers/staging/comedi/drivers/addi_apci_1516.c | 6 ++++++ drivers/staging/comedi/drivers/addi_apci_1564.c | 6 ++++++ drivers/staging/comedi/drivers/addi_apci_16xx.c | 6 ++++++ drivers/staging/comedi/drivers/addi_apci_1710.c | 8 ++++++++ drivers/staging/comedi/drivers/addi_apci_2016.c | 6 ++++++ drivers/staging/comedi/drivers/addi_apci_2032.c | 6 ++++++ drivers/staging/comedi/drivers/addi_apci_2200.c | 6 ++++++ drivers/staging/comedi/drivers/addi_apci_3001.c | 6 ++++++ drivers/staging/comedi/drivers/addi_apci_3120.c | 6 ++++++ drivers/staging/comedi/drivers/addi_apci_3200.c | 8 ++++++++ drivers/staging/comedi/drivers/addi_apci_3300.c | 8 ++++++++ drivers/staging/comedi/drivers/addi_apci_3501.c | 6 ++++++ drivers/staging/comedi/drivers/addi_apci_3xxx.c | 6 ++++++ 17 files changed, 102 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 6d7f6ea45c6..9b0f5b2f6a1 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -46,28 +46,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../../comedidev.h" -#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300) -#include -#endif -#include "../comedi_fc.h" - -#include "addi_common.h" -#include "addi_amcc_s5933.h" - #ifndef ADDIDATA_DRIVER_NAME #define ADDIDATA_DRIVER_NAME "addi_common" #endif diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 4c00df4bc15..694b58080a5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_035 1 #define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */ diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 7831ce33b02..bf983fcefab 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_1032 1 #define ADDIDATA_DRIVER_NAME "addi_apci_1032" diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index bfd84f66d9c..20e14acd110 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_1500 1 #define ADDIDATA_DRIVER_NAME "addi_apci_1500" diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index a12e2f42137..09b1c31a40a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_1516 1 #define ADDIDATA_DRIVER_NAME "addi_apci_1516" diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 1b9d598fb6c..72c62635283 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_1564 1 #define ADDIDATA_DRIVER_NAME "addi_apci_1564" diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index d54218d59c5..23093a51d27 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_16XX 1 #define ADDIDATA_DRIVER_NAME "addi_apci_16xx" diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index df6ba8ccf56..4853b31f9e3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -1,3 +1,11 @@ +#include + +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_1710 1 #define ADDIDATA_DRIVER_NAME "addi_apci_1710" diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c index fa50c7bb7ad..a1be859e56e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ b/drivers/staging/comedi/drivers/addi_apci_2016.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_2016 1 #define ADDIDATA_DRIVER_NAME "addi_apci_2016" diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 073a8a56dbe..07446d5d82c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_2032 1 #define ADDIDATA_DRIVER_NAME "addi_apci_2032" diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index adfbb5d410e..0316462bea6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_2200 1 #define ADDIDATA_DRIVER_NAME "addi_apci_2200" diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c index 00ac762965c..71da7b168f6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3001.c +++ b/drivers/staging/comedi/drivers/addi_apci_3001.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_3001 1 #define ADDIDATA_DRIVER_NAME "addi_apci_3001" diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index c35515845cf..db73b736cdd 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_3120 1 #define ADDIDATA_DRIVER_NAME "addi_apci_3120" diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 159313997dc..eb4056bf38f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -1,3 +1,11 @@ +#include + +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_3200 1 #define ADDIDATA_DRIVER_NAME "addi_apci_3200" diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c index 733c69abc43..94be6449a8c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3300.c +++ b/drivers/staging/comedi/drivers/addi_apci_3300.c @@ -1,3 +1,11 @@ +#include + +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_3300 1 #define ADDIDATA_DRIVER_NAME "addi_apci_3300" diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index dd2c1d3bc18..e795f8d4e32 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_3501 1 #define ADDIDATA_DRIVER_NAME "addi_apci_3501" diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index 03161c88eac..fc3d50fcecf 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -1,3 +1,9 @@ +#include "../comedidev.h" +#include "comedi_fc.h" + +#include "addi-data/addi_common.h" +#include "addi-data/addi_amcc_s5933.h" + #define CONFIG_APCI_3XXX 1 #define ADDIDATA_DRIVER_NAME "addi_apci_3xxx" -- cgit v1.2.3 From 02913e06c534c99aa9cc149b738fe932402f61e2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:51:47 -0700 Subject: staging: comedi: addi-data: remove this_board macro This macro relies on a local variable having a specific name. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 8 ++++++-- drivers/staging/comedi/drivers/addi-data/addi_eeprom.c | 1 + drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c | 4 ++++ drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 5 +++++ drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c | 2 ++ 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 9b0f5b2f6a1..985ec8848d3 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -54,8 +54,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour /* Update-0.7.57->0.7.68MODULE_DESCRIPTION("Comedi ADDI-DATA module"); */ /* Update-0.7.57->0.7.68MODULE_LICENSE("GPL"); */ -#define this_board ((const struct addi_board *)dev->board_ptr) - #if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300) /* BYTE b_SaveFPUReg [94]; */ @@ -1401,6 +1399,7 @@ static const struct addi_board boardtypes[] = { static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv; struct comedi_subdevice *s; int ret, pages, i, n_subdevices; @@ -1748,6 +1747,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) static void i_ADDI_Detach(struct comedi_device *dev) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; if (devpriv) { @@ -1801,6 +1801,7 @@ static void i_ADDI_Detach(struct comedi_device *dev) static int i_ADDI_Reset(struct comedi_device *dev) { + const struct addi_board *this_board = comedi_board(dev); this_board->reset(dev); return 0; @@ -1828,6 +1829,8 @@ static int i_ADDI_Reset(struct comedi_device *dev) static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { struct comedi_device *dev = d; + const struct addi_board *this_board = comedi_board(dev); + this_board->interrupt(irq, d); return IRQ_RETVAL(1); } @@ -1856,6 +1859,7 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; unsigned short w_Data; unsigned short w_Address; diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 0883fe0a930..5d31ecdfb8e 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -805,6 +805,7 @@ void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, struct comedi_device *dev) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; unsigned short w_Temp, i, w_Count = 0; unsigned int ui_Temp; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c index 859c593f95a..3f55cd0ae53 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c @@ -93,6 +93,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Command = 0; @@ -287,6 +288,7 @@ int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev, int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Command = 0; @@ -435,6 +437,7 @@ int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev, int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; unsigned char b_Command = (unsigned char) CR_AREF(insn->chanspec); int i_ReturnValue = insn->n; @@ -576,6 +579,7 @@ int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev, int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Command = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 0f7c8260264..0cbe915a5ce 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -147,6 +147,7 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; unsigned short us_ConvertTiming, us_TmpValue, i; unsigned char b_Tmp; @@ -482,6 +483,7 @@ int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_su int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; int err = 0; @@ -684,6 +686,7 @@ int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, struct comedi_subdevice *s) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; unsigned char b_Tmp; unsigned int ui_Tmp, ui_DelayTiming = 0, ui_TimerValue1 = 0, dmalen0 = @@ -1895,6 +1898,7 @@ void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; unsigned int ui_Timervalue2; unsigned short us_TmpValue; @@ -2053,6 +2057,7 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; unsigned int ui_Timervalue2 = 0; unsigned short us_TmpValue; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c index 431df5c90ce..80974f27ff3 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c @@ -110,6 +110,7 @@ static int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_TimeBase = 0; @@ -361,6 +362,7 @@ static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; int i_ReturnValue = insn->n; unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec); -- cgit v1.2.3 From bf6a1578c10a4f3ef94a3c744267f18f9c3642bd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:52:03 -0700 Subject: staging: comedi: addi-data: remove the addi-data #include ifdef'ery Move the addi-data specific #include's from addi_common.h to the individual driver files. The apci-1710, apci-3200, and apci-3300 drivers still have floating point code in them and are currently disabled in the Kconfig and Makefile. For now, move the fpu_{begin,end} functions from addi_common.c to the main driver file so we can get rid of the #ifdef'ery. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 60 ---------------------- drivers/staging/comedi/drivers/addi_apci_035.c | 2 + drivers/staging/comedi/drivers/addi_apci_1032.c | 2 + drivers/staging/comedi/drivers/addi_apci_1500.c | 2 + drivers/staging/comedi/drivers/addi_apci_1516.c | 2 + drivers/staging/comedi/drivers/addi_apci_1564.c | 2 + drivers/staging/comedi/drivers/addi_apci_16xx.c | 2 + drivers/staging/comedi/drivers/addi_apci_1710.c | 12 +++++ drivers/staging/comedi/drivers/addi_apci_2016.c | 2 + drivers/staging/comedi/drivers/addi_apci_2032.c | 2 + drivers/staging/comedi/drivers/addi_apci_2200.c | 2 + drivers/staging/comedi/drivers/addi_apci_3001.c | 2 + drivers/staging/comedi/drivers/addi_apci_3120.c | 2 + drivers/staging/comedi/drivers/addi_apci_3200.c | 12 +++++ drivers/staging/comedi/drivers/addi_apci_3300.c | 12 +++++ drivers/staging/comedi/drivers/addi_apci_3501.c | 2 + drivers/staging/comedi/drivers/addi_apci_3xxx.c | 2 + 17 files changed, 62 insertions(+), 60 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 985ec8848d3..f4311a433a5 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -54,66 +54,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour /* Update-0.7.57->0.7.68MODULE_DESCRIPTION("Comedi ADDI-DATA module"); */ /* Update-0.7.57->0.7.68MODULE_LICENSE("GPL"); */ -#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300) -/* BYTE b_SaveFPUReg [94]; */ - -void fpu_begin(void) -{ - /* asm ("fstenv b_SaveFPUReg"); */ - kernel_fpu_begin(); -} - -void fpu_end(void) -{ - /* asm ("frstor b_SaveFPUReg"); */ - kernel_fpu_end(); -} -#endif - -#include "addi_eeprom.c" -#if (defined (CONFIG_APCI_3120) || defined (CONFIG_APCI_3001)) -#include "hwdrv_apci3120.c" -#endif -#ifdef CONFIG_APCI_1032 -#include "hwdrv_apci1032.c" -#endif -#ifdef CONFIG_APCI_1516 -#include "hwdrv_apci1516.c" -#endif -#ifdef CONFIG_APCI_2016 -#include "hwdrv_apci2016.c" -#endif -#ifdef CONFIG_APCI_2032 -#include "hwdrv_apci2032.c" -#endif -#ifdef CONFIG_APCI_2200 -#include "hwdrv_apci2200.c" -#endif -#ifdef CONFIG_APCI_1564 -#include "hwdrv_apci1564.c" -#endif -#ifdef CONFIG_APCI_1500 -#include "hwdrv_apci1500.c" -#endif -#ifdef CONFIG_APCI_3501 -#include "hwdrv_apci3501.c" -#endif -#ifdef CONFIG_APCI_035 -#include "hwdrv_apci035.c" -#endif -#if (defined (CONFIG_APCI_3200) || defined (CONFIG_APCI_3300)) -#include "hwdrv_apci3200.c" -#endif -#ifdef CONFIG_APCI_1710 -#include "hwdrv_APCI1710.c" -#endif -#ifdef CONFIG_APCI_16XX -#include "hwdrv_apci16xx.c" -#endif -#ifdef CONFIG_APCI_3XXX -#include "hwdrv_apci3xxx.c" -#endif - #ifndef COMEDI_SUBD_TTLIO #define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ #endif diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 694b58080a5..85c7ee474bf 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -10,6 +10,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_035" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci035.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index bf983fcefab..e7a8f92f551 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -8,6 +8,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_1032" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci1032.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 20e14acd110..c2a89c4fa98 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -8,6 +8,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_1500" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci1500.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 09b1c31a40a..2504b641d2e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -8,6 +8,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_1516" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci1516.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 72c62635283..a37b3c4a935 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -8,6 +8,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_1564" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci1564.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 23093a51d27..f8ef19f082b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -8,6 +8,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_16xx" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci16xx.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 4853b31f9e3..fb805d02459 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -6,8 +6,20 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" +static void fpu_begin(void) +{ + kernel_fpu_begin(); +} + +static void fpu_end(void) +{ + kernel_fpu_end(); +} + #define CONFIG_APCI_1710 1 #define ADDIDATA_DRIVER_NAME "addi_apci_1710" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_APCI1710.c" #include "addi-data/addi_common.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c index a1be859e56e..bb2ee960fdd 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ b/drivers/staging/comedi/drivers/addi_apci_2016.c @@ -8,6 +8,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_2016" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci2016.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 07446d5d82c..7733758b756 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -8,6 +8,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_2032" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci2032.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 0316462bea6..ac13fc3502d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -8,6 +8,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_2200" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci2200.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c index 71da7b168f6..084dfcf0cd2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3001.c +++ b/drivers/staging/comedi/drivers/addi_apci_3001.c @@ -8,6 +8,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_3001" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci3120.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index db73b736cdd..6324f7457f4 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -8,6 +8,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_3120" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci3120.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index eb4056bf38f..34ac22a54df 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -6,8 +6,20 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" +static void fpu_begin(void) +{ + kernel_fpu_begin(); +} + +static void fpu_end(void) +{ + kernel_fpu_end(); +} + #define CONFIG_APCI_3200 1 #define ADDIDATA_DRIVER_NAME "addi_apci_3200" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci3200.c" #include "addi-data/addi_common.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c index 94be6449a8c..5d3d567c89d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3300.c +++ b/drivers/staging/comedi/drivers/addi_apci_3300.c @@ -6,8 +6,20 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" +static void fpu_begin(void) +{ + kernel_fpu_begin(); +} + +static void fpu_end(void) +{ + kernel_fpu_end(); +} + #define CONFIG_APCI_3300 1 #define ADDIDATA_DRIVER_NAME "addi_apci_3300" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci3200.c" #include "addi-data/addi_common.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index e795f8d4e32..8fb5b50de20 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -8,6 +8,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_3501" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci3501.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index fc3d50fcecf..c5205d3e25d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -8,6 +8,8 @@ #define ADDIDATA_DRIVER_NAME "addi_apci_3xxx" +#include "addi-data/addi_eeprom.c" +#include "addi-data/hwdrv_apci3xxx.c" #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v1.2.3 From 317285d71acccbda2fbab7e53d6b33c52a151a32 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:52:20 -0700 Subject: staging: comedi: addi-data: remove the MODULE_DEVICE_TABLE #ifdef'ery Move the MODULE_DEVICE_TABLE for each addi-data driver from addi_common.c to the individual driver files. This removes the need #ifdef'ery. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 79 ---------------------- drivers/staging/comedi/drivers/addi_apci_035.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_1032.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_1500.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_1516.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_1564.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_16xx.c | 8 +++ drivers/staging/comedi/drivers/addi_apci_1710.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_2016.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_2032.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_2200.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_3001.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_3120.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_3200.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_3300.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_3501.c | 7 ++ drivers/staging/comedi/drivers/addi_apci_3xxx.c | 30 ++++++++ 17 files changed, 136 insertions(+), 79 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index f4311a433a5..400acaf01b6 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -58,85 +58,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ #endif -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { -#ifdef CONFIG_APCI_3120 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x818D)}, -#endif -#ifdef CONFIG_APCI_1032 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1003)}, -#endif -#ifdef CONFIG_APCI_1516 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1001)}, -#endif -#ifdef CONFIG_APCI_2016 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1002)}, -#endif -#ifdef CONFIG_APCI_2032 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004)}, -#endif -#ifdef CONFIG_APCI_2200 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1005)}, -#endif -#ifdef CONFIG_APCI_1564 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1006)}, -#endif -#ifdef CONFIG_APCI_1500 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x80fc)}, -#endif -#ifdef CONFIG_APCI_3001 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x828D)}, -#endif -#ifdef CONFIG_APCI_3501 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001)}, -#endif -#ifdef CONFIG_APCI_035 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x0300)}, -#endif -#ifdef CONFIG_APCI_3200 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3000)}, -#endif -#ifdef CONFIG_APCI_3300 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3007)}, -#endif -#ifdef CONFIG_APCI_1710 - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, APCI1710_BOARD_DEVICE_ID)}, -#endif -#ifdef CONFIG_APCI_16XX - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1009)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x100A)}, -#endif -#ifdef CONFIG_APCI_3XXX - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3010)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300F)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300E)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3013)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3014)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3015)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3016)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3017)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3018)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3019)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301A)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301B)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301C)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301D)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301E)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301F)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3020)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3021)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3022)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3023)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300B)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3002)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3003)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3004)}, - {PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3024)}, -#endif - {0} -}; - -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); - static const struct addi_board boardtypes[] = { #ifdef CONFIG_APCI_3120 { diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 85c7ee474bf..36eb6ec6936 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -12,6 +12,13 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci035.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x0300) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index e7a8f92f551..67fe895b688 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -10,6 +10,13 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1032.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1003) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index c2a89c4fa98..c60b18b9ff3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -10,6 +10,13 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1500.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x80fc) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 2504b641d2e..480f6702589 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -10,6 +10,13 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1516.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1001) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index a37b3c4a935..811647b0053 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -10,6 +10,13 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1564.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1006) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index f8ef19f082b..36737727ad5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -10,6 +10,14 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci16xx.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1009) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x100a) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index fb805d02459..3402cf537cf 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -22,4 +22,11 @@ static void fpu_end(void) #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_APCI1710.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, APCI1710_BOARD_DEVICE_ID) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c index bb2ee960fdd..58d900f70b3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ b/drivers/staging/comedi/drivers/addi_apci_2016.c @@ -10,6 +10,13 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci2016.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1002) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 7733758b756..bc86d66df19 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -10,6 +10,13 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci2032.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index ac13fc3502d..1b06ba60ca1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -10,6 +10,13 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci2200.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1005) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c index 084dfcf0cd2..ec1d83d1a90 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3001.c +++ b/drivers/staging/comedi/drivers/addi_apci_3001.c @@ -10,6 +10,13 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3120.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x828d) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 6324f7457f4..d109306e187 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -10,6 +10,13 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3120.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x818d) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 34ac22a54df..d89453baa8c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -22,4 +22,11 @@ static void fpu_end(void) #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3200.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3000) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c index 5d3d567c89d..b821573e5f9 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3300.c +++ b/drivers/staging/comedi/drivers/addi_apci_3300.c @@ -22,4 +22,11 @@ static void fpu_end(void) #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3200.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3007) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 8fb5b50de20..a1c6f015382 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -10,6 +10,13 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3501.c" + +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index c5205d3e25d..9739b67d210 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -10,6 +10,36 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3xxx.c" +static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3010) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300f) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300e) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3013) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3014) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3015) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3016) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3017) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3018) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3019) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301a) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301b) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301c) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301d) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301e) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x301f) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3020) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3021) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3022) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3023) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300B) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3002) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3003) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3004) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3024) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, addi_apci_tbl); + #include "addi-data/addi_common.c" MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v1.2.3 From c0a053b8b24d72413a82a16a41f635e6040ccf34 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:52:36 -0700 Subject: staging: comedi: addi-data: remove the boardinfo #ifdef'ery Move the boardinfo for each addi-data driver from addi_common.c to the individual driver files. This removes the need #ifdef'ery. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 1180 -------------------- drivers/staging/comedi/drivers/addi_apci_035.c | 27 + drivers/staging/comedi/drivers/addi_apci_1032.c | 18 + drivers/staging/comedi/drivers/addi_apci_1500.c | 29 + drivers/staging/comedi/drivers/addi_apci_1516.c | 25 + drivers/staging/comedi/drivers/addi_apci_1564.c | 28 + drivers/staging/comedi/drivers/addi_apci_16xx.c | 28 + drivers/staging/comedi/drivers/addi_apci_1710.c | 14 + drivers/staging/comedi/drivers/addi_apci_2016.c | 22 + drivers/staging/comedi/drivers/addi_apci_2032.c | 24 + drivers/staging/comedi/drivers/addi_apci_2200.c | 24 + drivers/staging/comedi/drivers/addi_apci_3001.c | 40 + drivers/staging/comedi/drivers/addi_apci_3120.c | 44 + drivers/staging/comedi/drivers/addi_apci_3200.c | 36 + drivers/staging/comedi/drivers/addi_apci_3300.c | 35 + drivers/staging/comedi/drivers/addi_apci_3501.c | 29 + drivers/staging/comedi/drivers/addi_apci_3xxx.c | 770 +++++++++++++ 17 files changed, 1193 insertions(+), 1180 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 400acaf01b6..c7ea4f827b6 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -58,1186 +58,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ #endif -static const struct addi_board boardtypes[] = { -#ifdef CONFIG_APCI_3120 - { - .pc_DriverName = "apci3120", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, - .i_DeviceId = 0x818D, - .i_IorangeBase0 = AMCC_OP_REG_SIZE, - .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, - .i_IorangeBase2 = 8, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_NbrAoChannel = 8, - .i_AiMaxdata = 0xffff, - .i_AoMaxdata = 0x3fff, - .pr_AiRangelist = &range_apci3120_ai, - .pr_AoRangelist = &range_apci3120_ao, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 0x0f, - .i_Dma = 1, - .i_Timer = 1, - .b_AvailableConvertUnit = 1, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = v_APCI3120_Interrupt, - .reset = i_APCI3120_Reset, - .ai_config = i_APCI3120_InsnConfigAnalogInput, - .ai_read = i_APCI3120_InsnReadAnalogInput, - .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, - .ai_cmd = i_APCI3120_CommandAnalogInput, - .ai_cancel = i_APCI3120_StopCyclicAcquisition, - .ao_write = i_APCI3120_InsnWriteAnalogOutput, - .di_read = i_APCI3120_InsnReadDigitalInput, - .di_bits = i_APCI3120_InsnBitsDigitalInput, - .do_config = i_APCI3120_InsnConfigDigitalOutput, - .do_write = i_APCI3120_InsnWriteDigitalOutput, - .do_bits = i_APCI3120_InsnBitsDigitalOutput, - .timer_config = i_APCI3120_InsnConfigTimer, - .timer_write = i_APCI3120_InsnWriteTimer, - .timer_read = i_APCI3120_InsnReadTimer, - }, -#endif -#ifdef CONFIG_APCI_1032 - { - .pc_DriverName = "apci1032", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1003, - .i_IorangeBase0 = 4, - .i_IorangeBase1 = APCI1032_ADDRESS_RANGE, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_93C76, - .i_NbrDiChannel = 32, - .interrupt = v_APCI1032_Interrupt, - .reset = i_APCI1032_Reset, - .di_config = i_APCI1032_ConfigDigitalInput, - .di_read = i_APCI1032_Read1DigitalInput, - .di_bits = i_APCI1032_ReadMoreDigitalInput, - }, -#endif -#ifdef CONFIG_APCI_1516 - { - .pc_DriverName = "apci1516", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1001, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = APCI1516_ADDRESS_RANGE, - .i_IorangeBase2 = 32, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, - .i_NbrDiChannel = 8, - .i_NbrDoChannel = 8, - .i_Timer = 1, - .reset = i_APCI1516_Reset, - .di_read = i_APCI1516_Read1DigitalInput, - .di_bits = i_APCI1516_ReadMoreDigitalInput, - .do_config = i_APCI1516_ConfigDigitalOutput, - .do_write = i_APCI1516_WriteDigitalOutput, - .do_bits = i_APCI1516_ReadDigitalOutput, - .timer_config = i_APCI1516_ConfigWatchdog, - .timer_write = i_APCI1516_StartStopWriteWatchdog, - .timer_read = i_APCI1516_ReadWatchdog, - }, -#endif -#ifdef CONFIG_APCI_2016 - { - .pc_DriverName = "apci2016", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1002, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = APCI2016_ADDRESS_RANGE, - .i_IorangeBase2 = 32, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, - .i_NbrDoChannel = 16, - .i_Timer = 1, - .reset = i_APCI2016_Reset, - .do_config = i_APCI2016_ConfigDigitalOutput, - .do_write = i_APCI2016_WriteDigitalOutput, - .do_bits = i_APCI2016_BitsDigitalOutput, - .timer_config = i_APCI2016_ConfigWatchdog, - .timer_write = i_APCI2016_StartStopWriteWatchdog, - .timer_read = i_APCI2016_ReadWatchdog, - }, -#endif -#ifdef CONFIG_APCI_2032 - { - .pc_DriverName = "apci2032", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1004, - .i_IorangeBase0 = 4, - .i_IorangeBase1 = APCI2032_ADDRESS_RANGE, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_93C76, - .i_NbrDoChannel = 32, - .i_DoMaxdata = 0xffffffff, - .i_Timer = 1, - .interrupt = v_APCI2032_Interrupt, - .reset = i_APCI2032_Reset, - .do_config = i_APCI2032_ConfigDigitalOutput, - .do_write = i_APCI2032_WriteDigitalOutput, - .do_bits = i_APCI2032_ReadDigitalOutput, - .do_read = i_APCI2032_ReadInterruptStatus, - .timer_config = i_APCI2032_ConfigWatchdog, - .timer_write = i_APCI2032_StartStopWriteWatchdog, - .timer_read = i_APCI2032_ReadWatchdog, - }, -#endif -#ifdef CONFIG_APCI_2200 - { - .pc_DriverName = "apci2200", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1005, - .i_IorangeBase0 = 4, - .i_IorangeBase1 = APCI2200_ADDRESS_RANGE, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_93C76, - .i_NbrDiChannel = 8, - .i_NbrDoChannel = 16, - .i_Timer = 1, - .reset = i_APCI2200_Reset, - .di_read = i_APCI2200_Read1DigitalInput, - .di_bits = i_APCI2200_ReadMoreDigitalInput, - .do_config = i_APCI2200_ConfigDigitalOutput, - .do_write = i_APCI2200_WriteDigitalOutput, - .do_bits = i_APCI2200_ReadDigitalOutput, - .timer_config = i_APCI2200_ConfigWatchdog, - .timer_write = i_APCI2200_StartStopWriteWatchdog, - .timer_read = i_APCI2200_ReadWatchdog, - }, -#endif -#ifdef CONFIG_APCI_1564 - { - .pc_DriverName = "apci1564", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1006, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = APCI1564_ADDRESS_RANGE, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_93C76, - .i_NbrDiChannel = 32, - .i_NbrDoChannel = 32, - .i_DoMaxdata = 0xffffffff, - .i_Timer = 1, - .interrupt = v_APCI1564_Interrupt, - .reset = i_APCI1564_Reset, - .di_config = i_APCI1564_ConfigDigitalInput, - .di_read = i_APCI1564_Read1DigitalInput, - .di_bits = i_APCI1564_ReadMoreDigitalInput, - .do_config = i_APCI1564_ConfigDigitalOutput, - .do_write = i_APCI1564_WriteDigitalOutput, - .do_bits = i_APCI1564_ReadDigitalOutput, - .do_read = i_APCI1564_ReadInterruptStatus, - .timer_config = i_APCI1564_ConfigTimerCounterWatchdog, - .timer_write = i_APCI1564_StartStopWriteTimerCounterWatchdog, - .timer_read = i_APCI1564_ReadTimerCounterWatchdog, - }, -#endif -#ifdef CONFIG_APCI_1500 - { - .pc_DriverName = "apci1500", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, - .i_DeviceId = 0x80fc, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = APCI1500_ADDRESS_RANGE, - .i_IorangeBase2 = 4, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .i_NbrDiChannel = 16, - .i_NbrDoChannel = 16, - .i_DoMaxdata = 0xffff, - .i_Timer = 1, - .interrupt = v_APCI1500_Interrupt, - .reset = i_APCI1500_Reset, - .di_config = i_APCI1500_ConfigDigitalInputEvent, - .di_read = i_APCI1500_Initialisation, - .di_write = i_APCI1500_StartStopInputEvent, - .di_bits = i_APCI1500_ReadMoreDigitalInput, - .do_config = i_APCI1500_ConfigDigitalOutputErrorInterrupt, - .do_write = i_APCI1500_WriteDigitalOutput, - .do_bits = i_APCI1500_ConfigureInterrupt, - .timer_config = i_APCI1500_ConfigCounterTimerWatchdog, - .timer_write = i_APCI1500_StartStopTriggerTimerCounterWatchdog, - .timer_read = i_APCI1500_ReadInterruptMask, - .timer_bits = i_APCI1500_ReadCounterTimerWatchdog, - }, -#endif -#ifdef CONFIG_APCI_3001 - { - .pc_DriverName = "apci3001", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, - .i_DeviceId = 0x828D, - .i_IorangeBase0 = AMCC_OP_REG_SIZE, - .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, - .i_IorangeBase2 = 8, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 0xfff, - .pr_AiRangelist = &range_apci3120_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 0x0f, - .i_Dma = 1, - .i_Timer = 1, - .b_AvailableConvertUnit = 1, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = v_APCI3120_Interrupt, - .reset = i_APCI3120_Reset, - .ai_config = i_APCI3120_InsnConfigAnalogInput, - .ai_read = i_APCI3120_InsnReadAnalogInput, - .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, - .ai_cmd = i_APCI3120_CommandAnalogInput, - .ai_cancel = i_APCI3120_StopCyclicAcquisition, - .di_read = i_APCI3120_InsnReadDigitalInput, - .di_bits = i_APCI3120_InsnBitsDigitalInput, - .do_config = i_APCI3120_InsnConfigDigitalOutput, - .do_write = i_APCI3120_InsnWriteDigitalOutput, - .do_bits = i_APCI3120_InsnBitsDigitalOutput, - .timer_config = i_APCI3120_InsnConfigTimer, - .timer_write = i_APCI3120_InsnWriteTimer, - .timer_read = i_APCI3120_InsnReadTimer, - }, -#endif -#ifdef CONFIG_APCI_3501 - { - .pc_DriverName = "apci3501", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3001, - .i_IorangeBase0 = 64, - .i_IorangeBase1 = APCI3501_ADDRESS_RANGE, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5933, - .i_AoMaxdata = 16383, - .pr_AoRangelist = &range_apci3501_ao, - .i_NbrDiChannel = 2, - .i_NbrDoChannel = 2, - .i_DoMaxdata = 0x3, - .i_Timer = 1, - .interrupt = v_APCI3501_Interrupt, - .reset = i_APCI3501_Reset, - .ao_config = i_APCI3501_ConfigAnalogOutput, - .ao_write = i_APCI3501_WriteAnalogOutput, - .di_bits = i_APCI3501_ReadDigitalInput, - .do_config = i_APCI3501_ConfigDigitalOutput, - .do_write = i_APCI3501_WriteDigitalOutput, - .do_bits = i_APCI3501_ReadDigitalOutput, - .timer_config = i_APCI3501_ConfigTimerCounterWatchdog, - .timer_write = i_APCI3501_StartStopWriteTimerCounterWatchdog, - .timer_read = i_APCI3501_ReadTimerCounterWatchdog, - }, -#endif -#ifdef CONFIG_APCI_035 - { - .pc_DriverName = "apci035", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x0300, - .i_IorangeBase0 = 127, - .i_IorangeBase1 = APCI035_ADDRESS_RANGE, - .i_PCIEeprom = 1, - .pc_EepromChip = ADDIDATA_S5920, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 0xff, - .pr_AiRangelist = &range_apci035_ai, - .i_Timer = 1, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = v_APCI035_Interrupt, - .reset = i_APCI035_Reset, - .ai_config = i_APCI035_ConfigAnalogInput, - .ai_read = i_APCI035_ReadAnalogInput, - .timer_config = i_APCI035_ConfigTimerWatchdog, - .timer_write = i_APCI035_StartStopWriteTimerWatchdog, - .timer_read = i_APCI035_ReadTimerWatchdog, - }, -#endif -#ifdef CONFIG_APCI_3200 - { - .pc_DriverName = "apci3200", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3000, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 4, - .i_IorangeBase3 = 4, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 0x3ffff, - .pr_AiRangelist = &range_apci3200_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = v_APCI3200_Interrupt, - .reset = i_APCI3200_Reset, - .ai_config = i_APCI3200_ConfigAnalogInput, - .ai_read = i_APCI3200_ReadAnalogInput, - .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput, - .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test, - .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, - .ai_cmd = i_APCI3200_CommandAnalogInput, - .ai_cancel = i_APCI3200_StopCyclicAcquisition, - .di_bits = i_APCI3200_ReadDigitalInput, - .do_config = i_APCI3200_ConfigDigitalOutput, - .do_write = i_APCI3200_WriteDigitalOutput, - .do_bits = i_APCI3200_ReadDigitalOutput, - }, -#endif -#ifdef CONFIG_APCI_3300 - /* Begin JK .20.10.2004 = APCI-3300 integration */ - { - .pc_DriverName = "apci3300", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3007, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 4, - .i_IorangeBase3 = 4, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 8, - .i_AiMaxdata = 0x3ffff, - .pr_AiRangelist = &range_apci3300_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = v_APCI3200_Interrupt, - .reset = i_APCI3200_Reset, - .ai_config = i_APCI3200_ConfigAnalogInput, - .ai_read = i_APCI3200_ReadAnalogInput, - .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput, - .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test, - .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, - .ai_cmd = i_APCI3200_CommandAnalogInput, - .ai_cancel = i_APCI3200_StopCyclicAcquisition, - .di_bits = i_APCI3200_ReadDigitalInput, - .do_config = i_APCI3200_ConfigDigitalOutput, - .do_write = i_APCI3200_WriteDigitalOutput, - .do_bits = i_APCI3200_ReadDigitalOutput, - }, -#endif -#ifdef CONFIG_APCI_1710 - { - .pc_DriverName = "apci1710", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, - .i_DeviceId = APCI1710_BOARD_DEVICE_ID, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = 8, - .i_IorangeBase2 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .interrupt = v_APCI1710_Interrupt, - .reset = i_APCI1710_Reset, - }, -#endif -#ifdef CONFIG_APCI_16XX - { - .pc_DriverName = "apci1648", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1009, - .i_IorangeBase0 = 128, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .i_NbrTTLChannel = 48, - .reset = i_APCI16XX_Reset, - .ttl_config = i_APCI16XX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO, - .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue, - .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO, - }, { - .pc_DriverName = "apci1696", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x100A, - .i_IorangeBase0 = 128, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .i_NbrTTLChannel = 96, - .reset = i_APCI16XX_Reset, - .ttl_config = i_APCI16XX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO, - .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue, - .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO, - }, -#endif -#ifdef CONFIG_APCI_3XXX - { - .pc_DriverName = "apci3000-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3010, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3000-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x300F, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_AiMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3000-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x300E, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 4, - .i_NbrAiChannelDiff = 2, - .i_AiChannelList = 4, - .i_AiMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3006-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3013, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3006-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3014, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3006-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3015, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 4, - .i_NbrAiChannelDiff = 2, - .i_AiChannelList = 4, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3010-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3016, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3010-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3017, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_AiMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3010-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3018, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 4, - .i_NbrAiChannelDiff = 2, - .i_AiChannelList = 4, - .i_AiMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3016-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3019, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3016-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301A, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3016-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301B, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 4, - .i_NbrAiChannelDiff = 2, - .i_AiChannelList = 4, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3100-16-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301C, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 4095, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3100-8-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301D, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 4095, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3106-16-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301E, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 65535, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3106-8-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x301F, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 65535, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 10000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3110-16-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3020, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 4095, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3110-8-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3021, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 4095, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3116-16-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3022, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 65535, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3116-8-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3023, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannel = 8, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 8, - .i_NbrAoChannel = 4, - .i_AiMaxdata = 65535, - .i_AoMaxdata = 4095, - .pr_AiRangelist = &range_apci3XXX_ai, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .i_NbrTTLChannel = 24, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, { - .pc_DriverName = "apci3003", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x300B, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 4, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .b_AvailableConvertUnit = 7, - .ui_MinAcquisitiontimeNs = 2500, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - }, { - .pc_DriverName = "apci3002-16", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3002, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannelDiff = 16, - .i_AiChannelList = 16, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - }, { - .pc_DriverName = "apci3002-8", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3003, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 8, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - }, { - .pc_DriverName = "apci3002-4", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3004, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAiChannelDiff = 4, - .i_AiChannelList = 4, - .i_AiMaxdata = 65535, - .pr_AiRangelist = &range_apci3XXX_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 1, - .b_AvailableConvertUnit = 6, - .ui_MinAcquisitiontimeNs = 5000, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ai_config = i_APCI3XXX_InsnConfigAnalogInput, - .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, - }, { - .pc_DriverName = "apci3500", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3024, - .i_IorangeBase0 = 256, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 256, - .i_IorangeBase3 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .pc_EepromChip = ADDIDATA_9054, - .i_NbrAoChannel = 4, - .i_AoMaxdata = 4095, - .pr_AoRangelist = &range_apci3XXX_ao, - .i_NbrTTLChannel = 24, - .interrupt = v_APCI3XXX_Interrupt, - .reset = i_APCI3XXX_Reset, - .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, - .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, - .ttl_read = i_APCI3XXX_InsnReadTTLIO, - .ttl_write = i_APCI3XXX_InsnWriteTTLIO, - }, -#endif -}; - /* +----------------------------------------------------------------------------+ | Function name :static int i_ADDI_Attach(struct comedi_device *dev, | diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 36eb6ec6936..2e3f685fbc5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -13,6 +13,33 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci035.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci035", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x0300, + .i_IorangeBase0 = 127, + .i_IorangeBase1 = APCI035_ADDRESS_RANGE, + .i_PCIEeprom = 1, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 0xff, + .pr_AiRangelist = &range_apci035_ai, + .i_Timer = 1, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI035_Interrupt, + .reset = i_APCI035_Reset, + .ai_config = i_APCI035_ConfigAnalogInput, + .ai_read = i_APCI035_ReadAnalogInput, + .timer_config = i_APCI035_ConfigTimerWatchdog, + .timer_write = i_APCI035_StartStopWriteTimerWatchdog, + .timer_read = i_APCI035_ReadTimerWatchdog, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x0300) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 67fe895b688..cfcba6a268b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -11,6 +11,24 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1032.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci1032", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1003, + .i_IorangeBase0 = 4, + .i_IorangeBase1 = APCI1032_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_93C76, + .i_NbrDiChannel = 32, + .interrupt = v_APCI1032_Interrupt, + .reset = i_APCI1032_Reset, + .di_config = i_APCI1032_ConfigDigitalInput, + .di_read = i_APCI1032_Read1DigitalInput, + .di_bits = i_APCI1032_ReadMoreDigitalInput, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1003) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index c60b18b9ff3..59d762fbcb9 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -11,6 +11,35 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1500.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci1500", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, + .i_DeviceId = 0x80fc, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = APCI1500_ADDRESS_RANGE, + .i_IorangeBase2 = 4, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrDiChannel = 16, + .i_NbrDoChannel = 16, + .i_DoMaxdata = 0xffff, + .i_Timer = 1, + .interrupt = v_APCI1500_Interrupt, + .reset = i_APCI1500_Reset, + .di_config = i_APCI1500_ConfigDigitalInputEvent, + .di_read = i_APCI1500_Initialisation, + .di_write = i_APCI1500_StartStopInputEvent, + .di_bits = i_APCI1500_ReadMoreDigitalInput, + .do_config = i_APCI1500_ConfigDigitalOutputErrorInterrupt, + .do_write = i_APCI1500_WriteDigitalOutput, + .do_bits = i_APCI1500_ConfigureInterrupt, + .timer_config = i_APCI1500_ConfigCounterTimerWatchdog, + .timer_write = i_APCI1500_StartStopTriggerTimerCounterWatchdog, + .timer_read = i_APCI1500_ReadInterruptMask, + .timer_bits = i_APCI1500_ReadCounterTimerWatchdog, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x80fc) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 480f6702589..fdc4b6617b2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -11,6 +11,31 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1516.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci1516", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1001, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = APCI1516_ADDRESS_RANGE, + .i_IorangeBase2 = 32, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrDiChannel = 8, + .i_NbrDoChannel = 8, + .i_Timer = 1, + .reset = i_APCI1516_Reset, + .di_read = i_APCI1516_Read1DigitalInput, + .di_bits = i_APCI1516_ReadMoreDigitalInput, + .do_config = i_APCI1516_ConfigDigitalOutput, + .do_write = i_APCI1516_WriteDigitalOutput, + .do_bits = i_APCI1516_ReadDigitalOutput, + .timer_config = i_APCI1516_ConfigWatchdog, + .timer_write = i_APCI1516_StartStopWriteWatchdog, + .timer_read = i_APCI1516_ReadWatchdog, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1001) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 811647b0053..6bdbf205847 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -11,6 +11,34 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1564.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci1564", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1006, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = APCI1564_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_93C76, + .i_NbrDiChannel = 32, + .i_NbrDoChannel = 32, + .i_DoMaxdata = 0xffffffff, + .i_Timer = 1, + .interrupt = v_APCI1564_Interrupt, + .reset = i_APCI1564_Reset, + .di_config = i_APCI1564_ConfigDigitalInput, + .di_read = i_APCI1564_Read1DigitalInput, + .di_bits = i_APCI1564_ReadMoreDigitalInput, + .do_config = i_APCI1564_ConfigDigitalOutput, + .do_write = i_APCI1564_WriteDigitalOutput, + .do_bits = i_APCI1564_ReadDigitalOutput, + .do_read = i_APCI1564_ReadInterruptStatus, + .timer_config = i_APCI1564_ConfigTimerCounterWatchdog, + .timer_write = i_APCI1564_StartStopWriteTimerCounterWatchdog, + .timer_read = i_APCI1564_ReadTimerCounterWatchdog, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1006) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 36737727ad5..87009c832d2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -11,6 +11,34 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci16xx.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci1648", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1009, + .i_IorangeBase0 = 128, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrTTLChannel = 48, + .reset = i_APCI16XX_Reset, + .ttl_config = i_APCI16XX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO, + .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue, + .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO, + }, { + .pc_DriverName = "apci1696", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x100A, + .i_IorangeBase0 = 128, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrTTLChannel = 96, + .reset = i_APCI16XX_Reset, + .ttl_config = i_APCI16XX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI16XX_InsnBitsReadTTLIO, + .ttl_read = i_APCI16XX_InsnReadTTLIOAllPortValue, + .ttl_write = i_APCI16XX_InsnBitsWriteTTLIO, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1009) }, { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x100a) }, diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 3402cf537cf..58c5121e827 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -23,6 +23,20 @@ static void fpu_end(void) #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_APCI1710.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci1710", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, + .i_DeviceId = APCI1710_BOARD_DEVICE_ID, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = 8, + .i_IorangeBase2 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .interrupt = v_APCI1710_Interrupt, + .reset = i_APCI1710_Reset, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, APCI1710_BOARD_DEVICE_ID) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c index 58d900f70b3..ece4b9db58c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ b/drivers/staging/comedi/drivers/addi_apci_2016.c @@ -11,6 +11,28 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci2016.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci2016", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1002, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = APCI2016_ADDRESS_RANGE, + .i_IorangeBase2 = 32, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrDoChannel = 16, + .i_Timer = 1, + .reset = i_APCI2016_Reset, + .do_config = i_APCI2016_ConfigDigitalOutput, + .do_write = i_APCI2016_WriteDigitalOutput, + .do_bits = i_APCI2016_BitsDigitalOutput, + .timer_config = i_APCI2016_ConfigWatchdog, + .timer_write = i_APCI2016_StartStopWriteWatchdog, + .timer_read = i_APCI2016_ReadWatchdog, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1002) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index bc86d66df19..8dddb65f13b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -11,6 +11,30 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci2032.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci2032", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1004, + .i_IorangeBase0 = 4, + .i_IorangeBase1 = APCI2032_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_93C76, + .i_NbrDoChannel = 32, + .i_DoMaxdata = 0xffffffff, + .i_Timer = 1, + .interrupt = v_APCI2032_Interrupt, + .reset = i_APCI2032_Reset, + .do_config = i_APCI2032_ConfigDigitalOutput, + .do_write = i_APCI2032_WriteDigitalOutput, + .do_bits = i_APCI2032_ReadDigitalOutput, + .do_read = i_APCI2032_ReadInterruptStatus, + .timer_config = i_APCI2032_ConfigWatchdog, + .timer_write = i_APCI2032_StartStopWriteWatchdog, + .timer_read = i_APCI2032_ReadWatchdog, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 1b06ba60ca1..2c6464825b7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -11,6 +11,30 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci2200.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci2200", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1005, + .i_IorangeBase0 = 4, + .i_IorangeBase1 = APCI2200_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_93C76, + .i_NbrDiChannel = 8, + .i_NbrDoChannel = 16, + .i_Timer = 1, + .reset = i_APCI2200_Reset, + .di_read = i_APCI2200_Read1DigitalInput, + .di_bits = i_APCI2200_ReadMoreDigitalInput, + .do_config = i_APCI2200_ConfigDigitalOutput, + .do_write = i_APCI2200_WriteDigitalOutput, + .do_bits = i_APCI2200_ReadDigitalOutput, + .timer_config = i_APCI2200_ConfigWatchdog, + .timer_write = i_APCI2200_StartStopWriteWatchdog, + .timer_read = i_APCI2200_ReadWatchdog, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1005) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c index ec1d83d1a90..d5bc24660d8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3001.c +++ b/drivers/staging/comedi/drivers/addi_apci_3001.c @@ -11,6 +11,46 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3120.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci3001", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, + .i_DeviceId = 0x828D, + .i_IorangeBase0 = AMCC_OP_REG_SIZE, + .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, + .i_IorangeBase2 = 8, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 0xfff, + .pr_AiRangelist = &range_apci3120_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 0x0f, + .i_Dma = 1, + .i_Timer = 1, + .b_AvailableConvertUnit = 1, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI3120_Interrupt, + .reset = i_APCI3120_Reset, + .ai_config = i_APCI3120_InsnConfigAnalogInput, + .ai_read = i_APCI3120_InsnReadAnalogInput, + .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, + .ai_cmd = i_APCI3120_CommandAnalogInput, + .ai_cancel = i_APCI3120_StopCyclicAcquisition, + .di_read = i_APCI3120_InsnReadDigitalInput, + .di_bits = i_APCI3120_InsnBitsDigitalInput, + .do_config = i_APCI3120_InsnConfigDigitalOutput, + .do_write = i_APCI3120_InsnWriteDigitalOutput, + .do_bits = i_APCI3120_InsnBitsDigitalOutput, + .timer_config = i_APCI3120_InsnConfigTimer, + .timer_write = i_APCI3120_InsnWriteTimer, + .timer_read = i_APCI3120_InsnReadTimer, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x828d) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index d109306e187..bd2a654eeba 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -11,6 +11,50 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3120.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci3120", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, + .i_DeviceId = 0x818D, + .i_IorangeBase0 = AMCC_OP_REG_SIZE, + .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, + .i_IorangeBase2 = 8, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 8, + .i_AiMaxdata = 0xffff, + .i_AoMaxdata = 0x3fff, + .pr_AiRangelist = &range_apci3120_ai, + .pr_AoRangelist = &range_apci3120_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 0x0f, + .i_Dma = 1, + .i_Timer = 1, + .b_AvailableConvertUnit = 1, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI3120_Interrupt, + .reset = i_APCI3120_Reset, + .ai_config = i_APCI3120_InsnConfigAnalogInput, + .ai_read = i_APCI3120_InsnReadAnalogInput, + .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, + .ai_cmd = i_APCI3120_CommandAnalogInput, + .ai_cancel = i_APCI3120_StopCyclicAcquisition, + .ao_write = i_APCI3120_InsnWriteAnalogOutput, + .di_read = i_APCI3120_InsnReadDigitalInput, + .di_bits = i_APCI3120_InsnBitsDigitalInput, + .do_config = i_APCI3120_InsnConfigDigitalOutput, + .do_write = i_APCI3120_InsnWriteDigitalOutput, + .do_bits = i_APCI3120_InsnBitsDigitalOutput, + .timer_config = i_APCI3120_InsnConfigTimer, + .timer_write = i_APCI3120_InsnWriteTimer, + .timer_read = i_APCI3120_InsnReadTimer, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x818d) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index d89453baa8c..e3db75cc293 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -23,6 +23,42 @@ static void fpu_end(void) #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3200.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci3200", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3000, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 4, + .i_IorangeBase3 = 4, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 0x3ffff, + .pr_AiRangelist = &range_apci3200_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI3200_Interrupt, + .reset = i_APCI3200_Reset, + .ai_config = i_APCI3200_ConfigAnalogInput, + .ai_read = i_APCI3200_ReadAnalogInput, + .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput, + .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test, + .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, + .ai_cmd = i_APCI3200_CommandAnalogInput, + .ai_cancel = i_APCI3200_StopCyclicAcquisition, + .di_bits = i_APCI3200_ReadDigitalInput, + .do_config = i_APCI3200_ConfigDigitalOutput, + .do_write = i_APCI3200_WriteDigitalOutput, + .do_bits = i_APCI3200_ReadDigitalOutput, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3000) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c index b821573e5f9..81f0549aab4 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3300.c +++ b/drivers/staging/comedi/drivers/addi_apci_3300.c @@ -23,6 +23,41 @@ static void fpu_end(void) #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3200.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci3300", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3007, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 4, + .i_IorangeBase3 = 4, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 8, + .i_AiMaxdata = 0x3ffff, + .pr_AiRangelist = &range_apci3300_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI3200_Interrupt, + .reset = i_APCI3200_Reset, + .ai_config = i_APCI3200_ConfigAnalogInput, + .ai_read = i_APCI3200_ReadAnalogInput, + .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput, + .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test, + .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, + .ai_cmd = i_APCI3200_CommandAnalogInput, + .ai_cancel = i_APCI3200_StopCyclicAcquisition, + .di_bits = i_APCI3200_ReadDigitalInput, + .do_config = i_APCI3200_ConfigDigitalOutput, + .do_write = i_APCI3200_WriteDigitalOutput, + .do_bits = i_APCI3200_ReadDigitalOutput, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3007) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index a1c6f015382..5c95c7d1d21 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -11,6 +11,35 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3501.c" +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci3501", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3001, + .i_IorangeBase0 = 64, + .i_IorangeBase1 = APCI3501_ADDRESS_RANGE, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5933, + .i_AoMaxdata = 16383, + .pr_AoRangelist = &range_apci3501_ao, + .i_NbrDiChannel = 2, + .i_NbrDoChannel = 2, + .i_DoMaxdata = 0x3, + .i_Timer = 1, + .interrupt = v_APCI3501_Interrupt, + .reset = i_APCI3501_Reset, + .ao_config = i_APCI3501_ConfigAnalogOutput, + .ao_write = i_APCI3501_WriteAnalogOutput, + .di_bits = i_APCI3501_ReadDigitalInput, + .do_config = i_APCI3501_ConfigDigitalOutput, + .do_write = i_APCI3501_WriteDigitalOutput, + .do_bits = i_APCI3501_ReadDigitalOutput, + .timer_config = i_APCI3501_ConfigTimerCounterWatchdog, + .timer_write = i_APCI3501_StartStopWriteTimerCounterWatchdog, + .timer_read = i_APCI3501_ReadTimerCounterWatchdog, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001) }, { 0 } diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index 9739b67d210..d2698238676 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -10,6 +10,776 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3xxx.c" + +static const struct addi_board boardtypes[] = { + { + .pc_DriverName = "apci3000-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3010, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3000-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x300F, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3000-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x300E, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 4, + .i_NbrAiChannelDiff = 2, + .i_AiChannelList = 4, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3006-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3013, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3006-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3014, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3006-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3015, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 4, + .i_NbrAiChannelDiff = 2, + .i_AiChannelList = 4, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3010-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3016, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3010-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3017, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3010-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3018, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 4, + .i_NbrAiChannelDiff = 2, + .i_AiChannelList = 4, + .i_AiMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3016-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3019, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3016-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301A, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3016-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301B, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 4, + .i_NbrAiChannelDiff = 2, + .i_AiChannelList = 4, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3100-16-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301C, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 4095, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3100-8-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301D, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 4095, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3106-16-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301E, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 65535, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3106-8-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x301F, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 65535, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 10000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3110-16-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3020, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 4095, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3110-8-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3021, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 4095, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3116-16-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3022, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 65535, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3116-8-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3023, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannel = 8, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 8, + .i_NbrAoChannel = 4, + .i_AiMaxdata = 65535, + .i_AoMaxdata = 4095, + .pr_AiRangelist = &range_apci3XXX_ai, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .i_NbrTTLChannel = 24, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, { + .pc_DriverName = "apci3003", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x300B, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 4, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .b_AvailableConvertUnit = 7, + .ui_MinAcquisitiontimeNs = 2500, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + }, { + .pc_DriverName = "apci3002-16", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3002, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannelDiff = 16, + .i_AiChannelList = 16, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + }, { + .pc_DriverName = "apci3002-8", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3003, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 8, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + }, { + .pc_DriverName = "apci3002-4", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3004, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAiChannelDiff = 4, + .i_AiChannelList = 4, + .i_AiMaxdata = 65535, + .pr_AiRangelist = &range_apci3XXX_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 1, + .b_AvailableConvertUnit = 6, + .ui_MinAcquisitiontimeNs = 5000, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ai_config = i_APCI3XXX_InsnConfigAnalogInput, + .ai_read = i_APCI3XXX_InsnReadAnalogInput, + .di_read = i_APCI3XXX_InsnReadDigitalInput, + .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .do_write = i_APCI3XXX_InsnWriteDigitalOutput, + .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, + .do_read = i_APCI3XXX_InsnReadDigitalOutput, + }, { + .pc_DriverName = "apci3500", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3024, + .i_IorangeBase0 = 256, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 256, + .i_IorangeBase3 = 256, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .pc_EepromChip = ADDIDATA_9054, + .i_NbrAoChannel = 4, + .i_AoMaxdata = 4095, + .pr_AoRangelist = &range_apci3XXX_ao, + .i_NbrTTLChannel = 24, + .interrupt = v_APCI3XXX_Interrupt, + .reset = i_APCI3XXX_Reset, + .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, + .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, + .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, + .ttl_read = i_APCI3XXX_InsnReadTTLIO, + .ttl_write = i_APCI3XXX_InsnWriteTTLIO, + }, +}; + static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3010) }, { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300f) }, -- cgit v1.2.3 From 736994b8f60ded608b063e66b93dfac08c19d8e6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:52:58 -0700 Subject: staging: comedi: addi_common: remove the extra cruft The individual addi-data files all define ADDIDATA_DRIVER_NAME. Remove the #ifndef/#define for it in addi_common.c. Remove the commented out MODULE_* stuff. The individual addi-data drivers have this information. Remove the, badly formatted, function comments. The functions are obvious. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 86 ---------------------- 1 file changed, 86 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index c7ea4f827b6..616906896b8 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -46,38 +46,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -#ifndef ADDIDATA_DRIVER_NAME -#define ADDIDATA_DRIVER_NAME "addi_common" -#endif - -/* Update-0.7.57->0.7.68MODULE_AUTHOR("ADDI-DATA GmbH "); */ -/* Update-0.7.57->0.7.68MODULE_DESCRIPTION("Comedi ADDI-DATA module"); */ -/* Update-0.7.57->0.7.68MODULE_LICENSE("GPL"); */ - #ifndef COMEDI_SUBD_TTLIO #define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ #endif -/* -+----------------------------------------------------------------------------+ -| Function name :static int i_ADDI_Attach(struct comedi_device *dev, | -| struct comedi_devconfig *it) | -| | -+----------------------------------------------------------------------------+ -| Task :Detects the card. | -| Configure the driver for a particular board. | -| This function does all the initializations and memory | -| allocation of data structures for the driver. | -+----------------------------------------------------------------------------+ -| Input Parameters :struct comedi_device *dev | -| struct comedi_devconfig *it | -| | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -| | -+----------------------------------------------------------------------------+ -*/ - static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct addi_board *this_board = comedi_board(dev); @@ -462,24 +434,6 @@ static void i_ADDI_Detach(struct comedi_device *dev) } } -/* -+----------------------------------------------------------------------------+ -| Function name : static int i_ADDI_Reset(struct comedi_device *dev) | -| | -+----------------------------------------------------------------------------+ -| Task : Disables all interrupts, Resets digital output to low, | -| Set all analog output to low | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -| | -+----------------------------------------------------------------------------+ -*/ - static int i_ADDI_Reset(struct comedi_device *dev) { const struct addi_board *this_board = comedi_board(dev); @@ -488,25 +442,6 @@ static int i_ADDI_Reset(struct comedi_device *dev) return 0; } -/* Interrupt function */ -/* -+----------------------------------------------------------------------------+ -| Function name : | -|static void v_ADDI_Interrupt(int irq, void *d) | -| | -+----------------------------------------------------------------------------+ -| Task : Registerd interrupt routine | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : int irq | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { struct comedi_device *dev = d; @@ -516,27 +451,6 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) return IRQ_RETVAL(1); } -/* EEPROM Read Function */ -/* -+----------------------------------------------------------------------------+ -| Function name : | -|INT i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev,struct comedi_subdevice *s, - struct comedi_insn *insn,unsigned int *data) -| | -+----------------------------------------------------------------------------+ -| Task : Read 256 words from EEPROM | -| | -+----------------------------------------------------------------------------+ -| Input Parameters :(struct comedi_device *dev,struct comedi_subdevice *s, - struct comedi_insn *insn,unsigned int *data) | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { -- cgit v1.2.3 From 17d51852b44e0c506e7e3bf0874776853fdc9070 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:53:14 -0700 Subject: staging: comedi: addi_common: remove forward declarations Move some of the functions in this file to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 68 +++++++++++----------- .../staging/comedi/drivers/addi-data/addi_common.h | 7 --- 2 files changed, 34 insertions(+), 41 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 616906896b8..05a01e1c6f3 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -50,6 +50,40 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ #endif +static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; + unsigned short w_Address = CR_CHAN(insn->chanspec); + unsigned short w_Data; + + w_Data = w_EepromReadWord(devpriv->i_IobaseAmcc, + this_board->pc_EepromChip, 0x100 + (2 * w_Address)); + data[0] = w_Data; + + return insn->n; +} + +static irqreturn_t v_ADDI_Interrupt(int irq, void *d) +{ + struct comedi_device *dev = d; + const struct addi_board *this_board = comedi_board(dev); + + this_board->interrupt(irq, d); + return IRQ_RETVAL(1); +} + +static int i_ADDI_Reset(struct comedi_device *dev) +{ + const struct addi_board *this_board = comedi_board(dev); + + this_board->reset(dev); + return 0; +} + static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct addi_board *this_board = comedi_board(dev); @@ -434,40 +468,6 @@ static void i_ADDI_Detach(struct comedi_device *dev) } } -static int i_ADDI_Reset(struct comedi_device *dev) -{ - const struct addi_board *this_board = comedi_board(dev); - - this_board->reset(dev); - return 0; -} - -static irqreturn_t v_ADDI_Interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - const struct addi_board *this_board = comedi_board(dev); - - this_board->interrupt(irq, d); - return IRQ_RETVAL(1); -} - -static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - const struct addi_board *this_board = comedi_board(dev); - struct addi_private *devpriv = dev->private; - unsigned short w_Data; - unsigned short w_Address; - w_Address = CR_CHAN(insn->chanspec); /* address to be read as 0,1,2,3...255 */ - - w_Data = w_EepromReadWord(devpriv->i_IobaseAmcc, - this_board->pc_EepromChip, 0x100 + (2 * w_Address)); - data[0] = w_Data; - /* multiplied by 2 bcozinput will be like 0,1,2...255 */ - return insn->n; - -} - static struct comedi_driver addi_driver = { .driver_name = ADDIDATA_DRIVER_NAME, .module = THIS_MODULE, diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index 60047dec4af..6b71dbbfb22 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -412,10 +412,3 @@ struct addi_private { }; static unsigned short pci_list_builded; /* set to 1 when list of card is known */ - -/* Function declarations */ -static int i_ADDI_Reset(struct comedi_device *dev); - -static irqreturn_t v_ADDI_Interrupt(int irq, void *d); -static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -- cgit v1.2.3 From dcd7ef332acb5e7b84aadb5d0049f605a8dbb5bf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:53:33 -0700 Subject: staging: comedi: hwdrv_apci035: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci035.c | 32 ++++++++++++++-------- .../comedi/drivers/addi-data/hwdrv_apci035.h | 25 ----------------- 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c index 0fde7a39302..6d81575c78d 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c @@ -109,8 +109,10 @@ static int i_Flag = 1; | | +----------------------------------------------------------------------------+ */ -int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Status = 0; @@ -280,8 +282,10 @@ int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subde | | +----------------------------------------------------------------------------+ */ -int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Command = 0; @@ -397,8 +401,10 @@ int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev, | | +----------------------------------------------------------------------------+ */ -int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Status = 0; /* Status register */ @@ -459,8 +465,10 @@ int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevi | | +----------------------------------------------------------------------------+ */ -int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -498,8 +506,10 @@ int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevi | | +----------------------------------------------------------------------------+ */ -int i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI035_ReadAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_CommandRegister = 0; @@ -535,7 +545,7 @@ int i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice | | +----------------------------------------------------------------------------+ */ -int i_APCI035_Reset(struct comedi_device *dev) +static int i_APCI035_Reset(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; int i_Count = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h index 5f1f7f1f4e6..5b5c4a3343e 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h @@ -81,28 +81,3 @@ static struct comedi_lrange range_apci035_ai = { 8, { /* ADDIDATA Enable Disable */ #define ADDIDATA_ENABLE 1 #define ADDIDATA_DISABLE 0 - -/* Hardware Layer functions for Apci035 */ - -/* TIMER */ -/* timer value is passed as u seconds */ -int i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Temperature Related Defines (Analog Input Subdevice) */ - -int i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Interrupt */ -static void v_APCI035_Interrupt(int irq, void *d); - -/* Reset functions */ -int i_APCI035_Reset(struct comedi_device *dev); -- cgit v1.2.3 From 8581342bc74fef2403c693125a1b8139b4258195 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:53:53 -0700 Subject: staging: comedi: hwdrv_apci1032: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1032.c | 20 +++++++++++++------- .../comedi/drivers/addi-data/hwdrv_apci1032.h | 21 --------------------- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index b209cfa0374..e4e85f472f0 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -84,8 +84,10 @@ static unsigned int ui_InterruptStatus; +----------------------------------------------------------------------------+ */ -int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue; @@ -145,8 +147,10 @@ int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subde | | +----------------------------------------------------------------------------+ */ -int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue = 0; @@ -188,8 +192,10 @@ int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdev +----------------------------------------------------------------------------+ */ -int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_PortValue = data[0]; @@ -282,7 +288,7 @@ static void v_APCI1032_Interrupt(int irq, void *d) +----------------------------------------------------------------------------+ */ -int i_APCI1032_Reset(struct comedi_device *dev) +static int i_APCI1032_Reset(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h index 58d2de4720d..f0b32e8a81b 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h @@ -40,24 +40,3 @@ #define ADDIDATA_ENABLE 1 #define ADDIDATA_DISABLE 0 - -/* Hardware Layer functions for Apci1032 */ - -/* -* DI for di read -*/ - -int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Interrupt functions..... */ - -static void v_APCI1032_Interrupt(int irq, void *d); -/* Reset */ -int i_APCI1032_Reset(struct comedi_device *dev); -- cgit v1.2.3 From 04b02aaceeaa78c03ef88466403c0d40a19c312c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:54:08 -0700 Subject: staging: comedi: hwdrv_apci1500: remove forward declarations Remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1500.h | 49 ---------------------- 1 file changed, 49 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h index 1f2bd0ff6a9..989e880a0ed 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h @@ -113,52 +113,3 @@ enum { APCI1500_RW_PORT_B_PATTERN_TRANSITION, APCI1500_RW_PORT_B_PATTERN_MASK }; - - /*----------DIGITAL INPUT----------------*/ -static int i_APCI1500_Initialisation(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -static int i_APCI1500_StartStopInputEvent(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/*---------- DIGITAL OUTPUT------------*/ -static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/*----------TIMER----------------*/ -static int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -static int i_APCI1500_ReadInterruptMask(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/*----------INTERRUPT HANDLER------*/ -static void v_APCI1500_Interrupt(int irq, void *d); -static int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -/*----------RESET---------------*/ -static int i_APCI1500_Reset(struct comedi_device *dev); -- cgit v1.2.3 From 596aa571d8293b9a1ebf81687e4916b948b765dd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:54:26 -0700 Subject: staging: comedi: hwdrv_apci1516: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1516.c | 50 ++++++++++++++-------- .../comedi/drivers/addi-data/hwdrv_apci1516.h | 29 ------------- 2 files changed, 33 insertions(+), 46 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index 04a87453818..a3045f85513 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -73,8 +73,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour | | +----------------------------------------------------------------------------+ */ -int i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1516_Read1DigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue = 0; @@ -116,8 +118,10 @@ int i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdev +----------------------------------------------------------------------------+ */ -int i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_PortValue = data[0]; @@ -173,8 +177,10 @@ int i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub | | +----------------------------------------------------------------------------+ */ -int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -203,8 +209,10 @@ int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd +----------------------------------------------------------------------------+ */ -int i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp, ui_Temp1; @@ -364,8 +372,10 @@ int i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde +----------------------------------------------------------------------------+ */ -int i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -426,8 +436,10 @@ int i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev +----------------------------------------------------------------------------+ */ -int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -474,8 +486,10 @@ int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice +----------------------------------------------------------------------------+ */ -int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -521,8 +535,10 @@ int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_s +----------------------------------------------------------------------------+ */ -int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1516_ReadWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -545,7 +561,7 @@ int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice * +----------------------------------------------------------------------------+ */ -int i_APCI1516_Reset(struct comedi_device *dev) +static int i_APCI1516_Reset(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h index 88e86712e81..aaf564fe5e6 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h @@ -33,32 +33,3 @@ #define APCI1516_WATCHDOG_ENABLEDISABLE 12 #define APCI1516_WATCHDOG_RELOAD_VALUE 4 #define APCI1516_WATCHDOG_STATUS 16 - -/* Hardware Layer functions for Apci1516 */ - -/* Digital Input */ -int i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Digital Output */ -int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* -* TIMER timer value is passed as u seconds -*/ -int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* reset */ -int i_APCI1516_Reset(struct comedi_device *dev); -- cgit v1.2.3 From 5309fea29ef346f163dc4129017eb5a1ce5b87ea Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:54:46 -0700 Subject: staging: comedi: hwdrv_apci1564: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1564.c | 62 ++++++++++++++-------- .../comedi/drivers/addi-data/hwdrv_apci1564.h | 42 --------------- 2 files changed, 41 insertions(+), 63 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 393d6d19802..5fbd03db3ba 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -86,8 +86,10 @@ static unsigned int ui_InterruptData, ui_Type; | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -149,8 +151,10 @@ int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subde | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_Read1DigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue = 0; @@ -192,8 +196,10 @@ int i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdev | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_PortValue = data[0]; @@ -261,8 +267,10 @@ int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ul_Command = 0; @@ -319,8 +327,10 @@ int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp, ui_Temp1; @@ -494,8 +504,10 @@ int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp; @@ -573,8 +585,10 @@ int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; @@ -729,8 +743,10 @@ int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; @@ -826,8 +842,10 @@ int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, | | +----------------------------------------------------------------------------+ */ -int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; @@ -906,8 +924,10 @@ int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { *data = ui_Type; return insn->n; @@ -1118,7 +1138,7 @@ static void v_APCI1564_Interrupt(int irq, void *d) +----------------------------------------------------------------------------+ */ -int i_APCI1564_Reset(struct comedi_device *dev) +static int i_APCI1564_Reset(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h index aa249e91465..df69fd04c55 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h @@ -76,45 +76,3 @@ #define APCI1564_TCW_IRQ 20 #define APCI1564_TCW_WARN_TIMEVAL 24 #define APCI1564_TCW_WARN_TIMEBASE 28 - -/* Hardware Layer functions for Apci1564 */ - -/* -* DI for di read -*/ -int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* DO */ -int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* -* TIMER timer value is passed as u seconds -*/ -int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* intERRUPT */ -static void v_APCI1564_Interrupt(int irq, void *d); - -/* RESET */ -int i_APCI1564_Reset(struct comedi_device *dev); -- cgit v1.2.3 From ba36048cb6a2cb6d21ac4220e2ef7d8f9ff900c3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:55:05 -0700 Subject: staging: comedi: hwdrv_apci16xx: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci16xx.c | 26 ++++++++++----- .../comedi/drivers/addi-data/hwdrv_apci16xx.h | 39 ---------------------- 2 files changed, 17 insertions(+), 48 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c index 3f55cd0ae53..722832b8dc2 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c @@ -90,8 +90,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ -int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; @@ -285,8 +287,10 @@ int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; @@ -434,8 +438,10 @@ int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; @@ -576,8 +582,10 @@ int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; @@ -782,7 +790,7 @@ int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI16XX_Reset(struct comedi_device *dev) +static int i_APCI16XX_Reset(struct comedi_device *dev) { return 0; } diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h index a12df4bc88a..6293633b2a1 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h @@ -38,42 +38,3 @@ #define APCI16XX_TTL_READ_ALL_INPUTS 0 #define APCI16XX_TTL_READ_ALL_OUTPUTS 1 - -#ifdef __KERNEL__ - -/* -+----------------------------------------------------------------------------+ -| TTL INISIALISATION FUNCTION | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); - -/* -+----------------------------------------------------------------------------+ -| TTL INPUT FUNCTION | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); - -int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* -+----------------------------------------------------------------------------+ -| TTL OUTPUT FUNCTIONS | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); - -int i_APCI16XX_Reset(struct comedi_device *dev); -#endif -- cgit v1.2.3 From 38a6e527c8f094692930b3de43a8b2ed1ba3df01 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:55:24 -0700 Subject: staging: comedi: hwdrv_apci2016: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci2016.c | 38 ++++++++++++++-------- .../comedi/drivers/addi-data/hwdrv_apci2016.h | 34 ------------------- 2 files changed, 25 insertions(+), 47 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c index b8721dd16cb..d42bd62e803 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c @@ -75,8 +75,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour | | +----------------------------------------------------------------------------+ */ -int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -113,8 +115,10 @@ int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd | | +----------------------------------------------------------------------------+ */ -int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_NoOfChannel; @@ -270,8 +274,10 @@ int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde | | +----------------------------------------------------------------------------+ */ -int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp; @@ -343,8 +349,10 @@ int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdev | | +----------------------------------------------------------------------------+ */ -int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -387,8 +395,10 @@ int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice | | +----------------------------------------------------------------------------+ */ -int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -435,8 +445,10 @@ int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_s +----------------------------------------------------------------------------+ */ -int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2016_ReadWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -460,7 +472,7 @@ int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice * +----------------------------------------------------------------------------+ */ -int i_APCI2016_Reset(struct comedi_device *dev) +static int i_APCI2016_Reset(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h index 8792da90291..635295eef1c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h @@ -35,37 +35,3 @@ #define APCI2016_WATCHDOG_ENABLEDISABLE 12 #define APCI2016_WATCHDOG_RELOAD_VALUE 4 #define APCI2016_WATCHDOG_STATUS 16 - -/* Hardware Layer functions for Apci2016 */ - -/* DO */ -int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* -* TIMER -* timer value is passed as u seconds -*/ - -int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Interrupt functions..... */ - -/* void v_APCI2016_Interrupt(int irq, void *d); */ - -/* void v_APCI2016_Interrupt(int irq, void *d); */ -/* RESET */ -int i_APCI2016_Reset(struct comedi_device *dev); -- cgit v1.2.3 From 89100c20019e4e654c4a40041b83620f39fc41a0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:55:43 -0700 Subject: staging: comedi: hwdrv_apci2032: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci2032.c | 46 ++++++++++++++-------- .../comedi/drivers/addi-data/hwdrv_apci2032.h | 30 -------------- 2 files changed, 30 insertions(+), 46 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c index ad57f02b5b2..a198e5df210 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c @@ -79,8 +79,10 @@ static unsigned int ui_InterruptData, ui_Type; | | +----------------------------------------------------------------------------+ */ -int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ul_Command = 0; @@ -136,8 +138,10 @@ int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd +----------------------------------------------------------------------------+ */ -int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp, ui_Temp1; @@ -317,8 +321,10 @@ int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde +----------------------------------------------------------------------------+ */ -int i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp; @@ -386,8 +392,10 @@ int i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev | | +----------------------------------------------------------------------------+ */ -int i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2032_ConfigWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -429,8 +437,10 @@ int i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice +----------------------------------------------------------------------------+ */ -int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -476,8 +486,10 @@ int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_s +----------------------------------------------------------------------------+ */ -int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2032_ReadWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -504,7 +516,7 @@ int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice * | | +----------------------------------------------------------------------------+ */ -void v_APCI2032_Interrupt(int irq, void *d) +static void v_APCI2032_Interrupt(int irq, void *d) { struct comedi_device *dev = d; struct addi_private *devpriv = dev->private; @@ -556,8 +568,10 @@ void v_APCI2032_Interrupt(int irq, void *d) +----------------------------------------------------------------------------+ */ -int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { *data = ui_Type; return insn->n; @@ -579,7 +593,7 @@ int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subd +----------------------------------------------------------------------------+ */ -int i_APCI2032_Reset(struct comedi_device *dev) +static int i_APCI2032_Reset(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h index 6300067969c..a156a65a899 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h @@ -50,33 +50,3 @@ #define APCI2032_TCW_PROG 12 #define APCI2032_TCW_TRIG_STATUS 16 #define APCI2032_TCW_IRQ 20 - -/* Hardware Layer functions for Apci2032 */ - -/* DO */ -int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* TIMER - * timer value is passed as u seconds -*/ - -int i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Interrupt functions..... */ - -void v_APCI2032_Interrupt(int irq, void *d); - -/* Reset functions */ -int i_APCI2032_Reset(struct comedi_device *dev); -- cgit v1.2.3 From fddd23d38ce3f3306f459543438021efeb620305 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:56:02 -0700 Subject: staging: comedi: hwdrv_apci2200: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci2200.c | 50 ++++++++++++++-------- .../comedi/drivers/addi-data/hwdrv_apci2200.h | 27 ------------ 2 files changed, 33 insertions(+), 44 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c index db74f774a91..4453ceaca6d 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c @@ -73,8 +73,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour | | +----------------------------------------------------------------------------+ */ -int i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2200_Read1DigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue = 0; @@ -114,8 +116,10 @@ int i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdev +----------------------------------------------------------------------------+ */ -int i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_PortValue = data[0]; @@ -171,8 +175,10 @@ int i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_sub | | +----------------------------------------------------------------------------+ */ -int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -201,8 +207,10 @@ int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd +----------------------------------------------------------------------------+ */ -int i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp, ui_Temp1; @@ -360,8 +368,10 @@ int i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde +----------------------------------------------------------------------------+ */ -int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp; @@ -425,8 +435,10 @@ int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev +----------------------------------------------------------------------------+ */ -int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -473,8 +485,10 @@ int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice +----------------------------------------------------------------------------+ */ -int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -520,8 +534,10 @@ int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_s +----------------------------------------------------------------------------+ */ -int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI2200_ReadWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -546,7 +562,7 @@ int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice * +----------------------------------------------------------------------------+ */ -int i_APCI2200_Reset(struct comedi_device *dev) +static int i_APCI2200_Reset(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h index c4aaa0b9405..6267c8f0d60 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h @@ -31,30 +31,3 @@ #define APCI2200_WATCHDOG_ENABLEDISABLE 12 #define APCI2200_WATCHDOG_RELOAD_VALUE 4 #define APCI2200_WATCHDOG_STATUS 16 - -/* Hardware Layer functions for Apci2200 */ - -/* Digital Input */ -int i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* Digital Output */ -int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* TIMER */ -int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* reset */ -int i_APCI2200_Reset(struct comedi_device *dev); -- cgit v1.2.3 From 1305d30049fb959a5faa04e7ccbaba74042c33c1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:56:19 -0700 Subject: staging: comedi: hwdrv_apci3501: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3501.c | 58 ++++++++++++++-------- .../comedi/drivers/addi-data/hwdrv_apci3501.h | 45 ----------------- 2 files changed, 38 insertions(+), 65 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c index a730a4a52cb..609edd7ce8d 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c @@ -73,8 +73,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ -int i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_ReadDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp; @@ -123,8 +125,10 @@ int i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevi | | +----------------------------------------------------------------------------+ */ -int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -164,8 +168,10 @@ int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd | | +----------------------------------------------------------------------------+ */ -int i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp, ui_Temp1; @@ -253,8 +259,10 @@ int i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde | | +----------------------------------------------------------------------------+ */ -int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp; @@ -304,8 +312,10 @@ int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev | | +----------------------------------------------------------------------------+ */ -int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -344,8 +354,10 @@ int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subde | | +----------------------------------------------------------------------------+ */ -int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0; @@ -419,8 +431,10 @@ int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdev | | +----------------------------------------------------------------------------+ */ -int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; @@ -522,8 +536,10 @@ int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ul_Command1 = 0; @@ -626,8 +642,10 @@ int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -668,7 +686,7 @@ int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI3501_Reset(struct comedi_device *dev) +static int i_APCI3501_Reset(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; int i_Count = 0, i_temp = 0; @@ -721,7 +739,7 @@ int i_APCI3501_Reset(struct comedi_device *dev) | | +----------------------------------------------------------------------------+ */ -void v_APCI3501_Interrupt(int irq, void *d) +static void v_APCI3501_Interrupt(int irq, void *d) { int i_temp; struct comedi_device *dev = d; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h index 81ba7f0f16c..201fc7bf081 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h @@ -50,48 +50,3 @@ static struct comedi_lrange range_apci3501_ao = { 2, { #define APCI3501_TCW_WARN_TIMEBASE 28 #define ADDIDATA_TIMER 0 #define ADDIDATA_WATCHDOG 2 - -/* Hardware Layer functions for Apci3501 */ - -/* AO */ -int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* -* DI for di read INT i_APCI3501_ReadDigitalInput(struct -* comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn -* *insn,unsigned int *data); -*/ - -int i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* DO */ -int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* TIMER - * timer value is passed as u seconds - */ - -int i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -/* Interrupt */ -void v_APCI3501_Interrupt(int irq, void *d); - -/* Reset functions */ -int i_APCI3501_Reset(struct comedi_device *dev); -- cgit v1.2.3 From cdd78fed91f1391e2e31a95285b8530161d0d93a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:56:40 -0700 Subject: staging: comedi: hwdrv_APCI1710: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c index 057ef4eb8db..f28c737a173 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c @@ -56,7 +56,7 @@ You should also find the complete GPL in the COPYING file accompanying this sour #include "APCI1710_Pwm.c" #include "APCI1710_INCCPT.c" -void i_ADDI_AttachPCI1710(struct comedi_device *dev) +static void i_ADDI_AttachPCI1710(struct comedi_device *dev) { struct comedi_subdevice *s; int ret = 0; @@ -195,11 +195,7 @@ void i_ADDI_AttachPCI1710(struct comedi_device *dev) s->insn_bits = i_APCI1710_InsnBitsINCCPT; } -int i_APCI1710_Reset(struct comedi_device *dev); -void v_APCI1710_Interrupt(int irq, void *d); -/* for 1710 */ - -int i_APCI1710_Reset(struct comedi_device *dev) +static int i_APCI1710_Reset(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; int ret; @@ -248,7 +244,7 @@ int i_APCI1710_Reset(struct comedi_device *dev) +----------------------------------------------------------------------------+ */ -void v_APCI1710_Interrupt(int irq, void *d) +static void v_APCI1710_Interrupt(int irq, void *d) { struct comedi_device *dev = d; struct addi_private *devpriv = dev->private; -- cgit v1.2.3 From 7c642f40257b5f3e0693133b2e3835d63ebcfac6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:56:58 -0700 Subject: staging: comedi: APCI1710_Dig_io: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Dig_io.c | 24 ++++++++++++++-------- .../comedi/drivers/addi-data/APCI1710_Dig_io.h | 21 ------------------- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c index 96ca3d26ae6..aa4122e618b 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c @@ -99,8 +99,10 @@ Activates and deactivates the digital output memory. +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned char b_ModulNbr, b_ChannelAMode, b_ChannelBMode; @@ -294,8 +296,10 @@ int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subd * unsigned char_ b_ModulNbr, unsigned char_ b_InputChannel, * unsigned char *_ pb_ChannelStatus) */ -int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -483,8 +487,10 @@ int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev, * _INT_ i_APCI1710_SetDigitalIOChlOn (unsigned char_ b_BoardHandle, * unsigned char_ b_ModulNbr, unsigned char_ b_OutputChannel) */ -int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -734,8 +740,10 @@ int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev, * b_BoardHandle, unsigned char_ b_ModulNbr, unsigned char_ * b_PortValue) */ -int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h index cc3973d7c2a..078380880de 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h @@ -23,24 +23,3 @@ #define APCI1710_DIGIO_MEMORYONOFF 0x10 #define APCI1710_DIGIO_INIT 0x11 - -/* - * DIGITAL I/O INISIALISATION FUNCTION - */ -int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * INPUT OUTPUT FUNCTIONS - */ -int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -- cgit v1.2.3 From 3eaa1151084af59652264e0126a423d82271a4e2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:57:17 -0700 Subject: staging: comedi: APCI1710_Inp_cpt: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Inp_cpt.c | 24 ++++++++++++++------- .../comedi/drivers/addi-data/APCI1710_Inp_cpt.h | 25 ---------------------- 2 files changed, 16 insertions(+), 33 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c index 3aa80090a07..c892d0c569e 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c @@ -123,8 +123,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -414,8 +416,10 @@ int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -709,8 +713,10 @@ int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev, unsigned char *_ pb_Status) */ -int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -836,8 +842,10 @@ int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev, return i_ReturnValue; } -int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h index 31fbb0bec52..c8b90b4103f 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h @@ -20,28 +20,3 @@ #define APCI1710_PULSEENCODER_READ 0 #define APCI1710_PULSEENCODER_WRITE 1 - -int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -/* - * READ PULSE ENCODER FUNCTIONS - */ -int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -/* - * WRITE PULSE ENCODER FUNCTIONS - */ -int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -- cgit v1.2.3 From f459d3ef0a1c3b79107c5120cf04f2bc53af933d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:57:34 -0700 Subject: staging: comedi: APCI1710_Ssi: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/APCI1710_Ssi.c | 18 ++++++++++++------ .../staging/comedi/drivers/addi-data/APCI1710_Ssi.h | 12 ------------ 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c index 298ea485da9..00f8dc38186 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c @@ -119,8 +119,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -387,8 +389,10 @@ pul_Position = (unsigned int *) &data[0]; +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -721,8 +725,10 @@ int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevi +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h index ef4d88789d5..c4f6565aa31 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h @@ -29,15 +29,3 @@ #define APCI1710_SSI_SET_CHANNELOFF 1 #define APCI1710_SSI_READ_1CHANNEL 2 #define APCI1710_SSI_READ_ALLCHANNEL 3 - -/* - * SSI INISIALISATION FUNCTION - */ -int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -- cgit v1.2.3 From 189790cd83afa7570ab66588896dd048d679b76f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:57:52 -0700 Subject: staging: comedi: APCI1710_Tor: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Tor.c | 24 ++++++++++++++-------- .../comedi/drivers/addi-data/APCI1710_Tor.h | 24 ---------------------- 2 files changed, 16 insertions(+), 32 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c index 28322fbfc1d..3594a0487f7 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c @@ -130,8 +130,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -988,8 +990,10 @@ int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1462,8 +1466,10 @@ int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1703,8 +1709,10 @@ int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev, +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h index 537d4755132..c6eb9d1ad3c 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h @@ -31,27 +31,3 @@ #define APCI1710_TOR_GETPROGRESSSTATUS 0 #define APCI1710_TOR_GETCOUNTERVALUE 1 #define APCI1710_TOR_READINTERRUPT 2 - -/* - * TOR_COUNTER INISIALISATION FUNCTION - */ -int i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -int i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -/* - * TOR_COUNTER READ FUNCTION - */ -int i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); -- cgit v1.2.3 From 76e44f8e5770b6e5523f7b732515d05a3eecc243 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 16:58:10 -0700 Subject: staging: comedi: APCI1710_Ttl: remove forward declarations None of the functions in this file are exported. Make all of them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Ttl.c | 24 ++++++++++++++-------- .../comedi/drivers/addi-data/APCI1710_Ttl.h | 22 -------------------- 2 files changed, 16 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c index 4f71a4ce3fb..3bf6929c218 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c @@ -100,8 +100,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -407,8 +409,10 @@ APCI1710_TTL_READCHANNEL +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -657,8 +661,10 @@ int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdev +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -828,8 +834,10 @@ int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,struct comedi +----------------------------------------------------------------------------+ */ -int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h index adcab824b25..2f6a39213b0 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h @@ -20,25 +20,3 @@ #define APCI1710_TTL_READCHANNEL 0 #define APCI1710_TTL_READPORT 1 - -/* - * TTL INISIALISATION FUNCTION - */ -int i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * TTL INPUT FUNCTION - */ -int i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * TTL OUTPUT FUNCTIONS - */ -int i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -- cgit v1.2.3 From 0e77e35bc3c0b6cb2ab90051b1bf79a35e57713f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:02:42 -0700 Subject: staging: comedi: addi_eeprom: remove extra whitespace and comment cruft Remove the extra whitespace and the comment cruft in this file. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 561 --------------------- 1 file changed, 561 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 5d31ecdfb8e..2e46a1764d0 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -77,15 +77,11 @@ struct str_DigitalInputHeader { }; struct str_DigitalOutputHeader { - unsigned short w_Nchannel; }; - /* used for timer as well as watchdog */ - struct str_TimerDetails { - unsigned short w_HeaderSize; unsigned char b_Resolution; unsigned char b_Mode; /* in case of Watchdog it is functionality */ @@ -94,13 +90,10 @@ struct str_TimerDetails { }; struct str_TimerMainHeader { - - unsigned short w_Ntimer; struct str_TimerDetails s_TimerDetails[4]; /* supports 4 timers */ }; - struct str_AnalogOutputHeader { unsigned short w_Nchannel; unsigned char b_Resolution; @@ -114,11 +107,6 @@ struct str_AnalogInputHeader { unsigned char b_Resolution; }; - - /*****************************************/ - /* Read Header Functions */ - /*****************************************/ - int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, struct comedi_device *dev); @@ -142,9 +130,6 @@ int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_AnalogInputHeader *s_Header); - /******************************************/ - /* Eeprom Specific Functions */ - /******************************************/ unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_EepromStartAddress); void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress); @@ -154,654 +139,212 @@ void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromComman unsigned char b_DataLengthInBits); void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value); -/* -+----------------------------------------------------------------------------+ -| Function Name : unsigned short w_EepromReadWord | -| (unsigned short w_PCIBoardEepromAddress, | -| char * pc_PCIChipInformation, | -| unsigned short w_EepromStartAddress) | -+----------------------------------------------------------------------------+ -| Task : Read from eepromn a word | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| unsigned short w_EepromStartAddress : Selected eeprom address | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : Read word value from eeprom | -+----------------------------------------------------------------------------+ -*/ - unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_EepromStartAddress) { - unsigned char b_Counter = 0; - unsigned char b_ReadByte = 0; - unsigned char b_ReadLowByte = 0; - unsigned char b_ReadHighByte = 0; - unsigned char b_SelectedAddressLow = 0; - unsigned char b_SelectedAddressHigh = 0; - unsigned short w_ReadWord = 0; - /**************************/ - /* Test the PCI chip type */ - - /**************************/ - if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) { - for (b_Counter = 0; b_Counter < 2; b_Counter++) { - b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256; /* Read the low 8 bit part */ - b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256; /* Read the high 8 bit part */ - /************************************/ - /* Select the load low address mode */ - - /************************************/ - outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F); - /****************/ - /* Wait on busy */ - - /****************/ - v_EepromWaitBusy(w_PCIBoardEepromAddress); - /************************/ - /* Load the low address */ - - /************************/ - outb(b_SelectedAddressLow, w_PCIBoardEepromAddress + 0x3E); - /****************/ - /* Wait on busy */ - - /****************/ - v_EepromWaitBusy(w_PCIBoardEepromAddress); - /*************************************/ - /* Select the load high address mode */ - - /*************************************/ - outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F); - /****************/ - /* Wait on busy */ - - /****************/ - v_EepromWaitBusy(w_PCIBoardEepromAddress); - /*************************/ - /* Load the high address */ - - /*************************/ - outb(b_SelectedAddressHigh, w_PCIBoardEepromAddress + 0x3E); - /****************/ - /* Wait on busy */ - - /****************/ - v_EepromWaitBusy(w_PCIBoardEepromAddress); - /************************/ - /* Select the READ mode */ - - /************************/ - outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F); - /****************/ - /* Wait on busy */ - - /****************/ - v_EepromWaitBusy(w_PCIBoardEepromAddress); - /*****************************/ - /* Read data into the EEPROM */ - - /*****************************/ - b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E); - /****************/ - /* Wait on busy */ - - /****************/ - v_EepromWaitBusy(w_PCIBoardEepromAddress); - /*********************************/ - /* Select the upper address part */ - - /*********************************/ - if (b_Counter == 0) { - b_ReadLowByte = b_ReadByte; - } /* if(b_Counter==0) */ - else { - b_ReadHighByte = b_ReadByte; - } /* if(b_Counter==0) */ - } /* for (b_Counter=0; b_Counter<2; b_Counter++) */ w_ReadWord = (b_ReadLowByte | (((unsigned short) b_ReadHighByte) * 256)); - } /* end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) */ if (!strcmp(pc_PCIChipInformation, "93C76")) { - - /*************************************/ - /* Read 16 bit from the EEPROM 93C76 */ - - /*************************************/ - v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress, &w_ReadWord); - } return w_ReadWord; - } -/* - -+----------------------------------------------------------------------------+ - -| Function Name : void v_EepromWaitBusy | - -| (unsigned short w_PCIBoardEepromAddress) | - -+----------------------------------------------------------------------------+ - -| Task : Wait the busy flag from PCI controller | - -+----------------------------------------------------------------------------+ - -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom base address | - -+----------------------------------------------------------------------------+ - -| Output Parameters : - | - -+----------------------------------------------------------------------------+ - -| Return Value : - | - -+----------------------------------------------------------------------------+ - -*/ - void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress) { - unsigned char b_EepromBusy = 0; do { - - /*************/ - /* IMPORTANT */ - - /*************/ - - /************************************************************************/ - /* An error has been written in the AMCC 5933 book at the page B-13 */ - /* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and */ - /* the operator register is AMCC_OP_REG_MCSR+3 */ - /* unsigned short read EEPROM=0x8000 andAMCC_OP_REG_MCSR+2 */ - /* unsigned int read EEPROM=0x80000000 and AMCC_OP_REG_MCSR */ - - /************************************************************************/ - b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F); b_EepromBusy = b_EepromBusy & 0x80; - } while (b_EepromBusy == 0x80); - } -/* - -+---------------------------------------------------------------------------------+ - -| Function Name : void v_EepromClock76(unsigned int dw_Address, | - -| unsigned int dw_RegisterValue) | - -+---------------------------------------------------------------------------------+ - -| Task : This function sends the clocking sequence to the EEPROM. | - -+---------------------------------------------------------------------------------+ - -| Input Parameters : unsigned int dw_Address : PCI eeprom base address | - -| unsigned int dw_RegisterValue : PCI eeprom register value to write.| - -+---------------------------------------------------------------------------------+ - -| Output Parameters : - | - -+---------------------------------------------------------------------------------+ - -| Return Value : - | - -+---------------------------------------------------------------------------------+ - -*/ - void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue) { - - /************************/ - /* Set EEPROM clock Low */ - - /************************/ - outl(dw_RegisterValue & 0x6, dw_Address); - /***************/ - /* Wait 0.1 ms */ - - /***************/ - udelay(100); - /*************************/ - /* Set EEPROM clock High */ - - /*************************/ - outl(dw_RegisterValue | 0x1, dw_Address); - /***************/ - /* Wait 0.1 ms */ - - /***************/ - udelay(100); - } -/* - -+---------------------------------------------------------------------------------+ - -| Function Name : void v_EepromSendCommand76(unsigned int dw_Address, | - -| unsigned int dw_EepromCommand, | - -| unsigned char b_DataLengthInBits) | - -+---------------------------------------------------------------------------------+ - -| Task : This function sends a Command to the EEPROM 93C76. | - -+---------------------------------------------------------------------------------+ - -| Input Parameters : unsigned int dw_Address : PCI eeprom base address | - -| unsigned int dw_EepromCommand : PCI eeprom command to write. | - -| unsigned char b_DataLengthInBits : PCI eeprom command data length. | - -+---------------------------------------------------------------------------------+ - -| Output Parameters : - | - -+---------------------------------------------------------------------------------+ - -| Return Value : - | - -+---------------------------------------------------------------------------------+ - -*/ - void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand, unsigned char b_DataLengthInBits) { - char c_BitPos = 0; - unsigned int dw_RegisterValue = 0; - /*****************************/ - /* Enable EEPROM Chip Select */ - - /*****************************/ - dw_RegisterValue = 0x2; - /********************************************************************/ - /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - - /********************************************************************/ - outl(dw_RegisterValue, dw_Address); - /***************/ - /* Wait 0.1 ms */ - - /***************/ - udelay(100); - /*******************************************/ - /* Send EEPROM command - one bit at a time */ - - /*******************************************/ - for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--) { - - /**********************************/ - /* Check if current bit is 0 or 1 */ - - /**********************************/ - if (dw_EepromCommand & (1 << c_BitPos)) { - - /***********/ - /* Write 1 */ - - /***********/ - dw_RegisterValue = dw_RegisterValue | 0x4; - } - else { - - /***********/ - /* Write 0 */ - - /***********/ - dw_RegisterValue = dw_RegisterValue & 0x3; - } - /*********************/ - /* Write the command */ - - /*********************/ - outl(dw_RegisterValue, dw_Address); - /***************/ - /* Wait 0.1 ms */ - - /***************/ - udelay(100); - /****************************/ - /* Trigger the EEPROM clock */ - - /****************************/ - v_EepromClock76(dw_Address, dw_RegisterValue); - } - } -/* - -+---------------------------------------------------------------------------------+ - -| Function Name : void v_EepromCs76Read(unsigned int dw_Address, | - -| unsigned short w_offset, | - -| unsigned short * pw_Value) | - -+---------------------------------------------------------------------------------+ - -| Task : This function read a value from the EEPROM 93C76. | - -+---------------------------------------------------------------------------------+ - -| Input Parameters : unsigned int dw_Address : PCI eeprom base address | - -| unsigned short w_offset : Offset of the address to read | - -| unsigned short * pw_Value : PCI eeprom 16 bit read value. | - -+---------------------------------------------------------------------------------+ - -| Output Parameters : - | - -+---------------------------------------------------------------------------------+ - -| Return Value : - | - -+---------------------------------------------------------------------------------+ - -*/ - void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value) { - char c_BitPos = 0; - unsigned int dw_RegisterValue = 0; - unsigned int dw_RegisterValueRead = 0; - /*************************************************/ - /* Send EEPROM read command and offset to EEPROM */ - - /*************************************************/ - v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2), EE76_CMD_LEN); - /*******************************/ - /* Get the last register value */ - - /*******************************/ - dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2; - /*****************************/ - /* Set the 16-bit value of 0 */ - - /*****************************/ - *pw_Value = 0; - /************************/ - /* Get the 16-bit value */ - - /************************/ - for (c_BitPos = 0; c_BitPos < 16; c_BitPos++) { - - /****************************/ - /* Trigger the EEPROM clock */ - - /****************************/ - v_EepromClock76(dw_Address, dw_RegisterValue); - /**********************/ - /* Get the result bit */ - - /**********************/ - dw_RegisterValueRead = inl(dw_Address); - /***************/ - /* Wait 0.1 ms */ - - /***************/ - udelay(100); - /***************************************/ - /* Get bit value and shift into result */ - - /***************************************/ - if (dw_RegisterValueRead & 0x8) { - - /**********/ - /* Read 1 */ - - /**********/ - *pw_Value = (*pw_Value << 1) | 0x1; - } - else { - - /**********/ - /* Read 0 */ - - /**********/ - *pw_Value = (*pw_Value << 1); - } - } - /*************************/ - /* Clear all EEPROM bits */ - - /*************************/ - dw_RegisterValue = 0x0; - /********************************************************************/ - /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - - /********************************************************************/ - outl(dw_RegisterValue, dw_Address); - /***************/ - /* Wait 0.1 ms */ - - /***************/ - udelay(100); - } - /******************************************/ - /* EEPROM HEADER READ FUNCTIONS */ - /******************************************/ - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, | -| char * pc_PCIChipInformation,struct comedi_device *dev) | -+----------------------------------------------------------------------------+ -| Task : Read from eeprom Main Header | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| struct comedi_device *dev : comedi device structure | -| pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -+----------------------------------------------------------------------------+ -*/ - int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, struct comedi_device *dev) { @@ -924,27 +467,6 @@ int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, return 0; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_EepromReadDigitalInputHeader(unsigned short | -| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | -| unsigned short w_Address,struct str_DigitalInputHeader *s_Header) | -| | -+----------------------------------------------------------------------------+ -| Task : Read Digital Input Header | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| struct str_DigitalInputHeader *s_Header: Digita Input Header | -| Pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -+----------------------------------------------------------------------------+ -*/ int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_DigitalInputHeader *s_Header) @@ -969,27 +491,6 @@ int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, return 0; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_EepromReadDigitalOutputHeader(unsigned short | -| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | -| unsigned short w_Address,struct str_DigitalOutputHeader *s_Header) | -| | -+----------------------------------------------------------------------------+ -| Task : Read Digital Output Header | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| struct str_DigitalOutputHeader *s_Header: Digital Output Header| -| Pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -+----------------------------------------------------------------------------+ -*/ int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_DigitalOutputHeader *s_Header) @@ -1001,26 +502,6 @@ int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, return 0; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, | -| char *pc_PCIChipInformation,WORD w_Address, | -| struct str_TimerMainHeader *s_Header) | -+----------------------------------------------------------------------------+ -| Task : Read Timer or Watchdog Header | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| struct str_TimerMainHeader *s_Header: Timer Header | -| Pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -+----------------------------------------------------------------------------+ -*/ int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_TimerMainHeader *s_Header) @@ -1066,27 +547,6 @@ int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, return 0; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_EepromReadAnlogOutputHeader(unsigned short | -| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | -| unsigned short w_Address,str_AnalogOutputHeader *s_Header) | -+----------------------------------------------------------------------------+ -| Task : Read Nalog Output Header | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| str_AnalogOutputHeader *s_Header:Anlog Output Header | -| Pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -+----------------------------------------------------------------------------+ -*/ - int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, struct str_AnalogOutputHeader *s_Header) @@ -1103,27 +563,6 @@ int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, return 0; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_EepromReadAnlogInputHeader(unsigned short | -| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, | -| unsigned short w_Address,struct str_AnalogInputHeader *s_Header) | -+----------------------------------------------------------------------------+ -| Task : Read Nalog Output Header | -+----------------------------------------------------------------------------+ -| Input Parameters : unsigned short w_PCIBoardEepromAddress : PCI eeprom address | -| | -| char *pc_PCIChipInformation : PCI Chip Type. | -| | -| struct str_AnalogInputHeader *s_Header:Anlog Input Header | -| Pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -+----------------------------------------------------------------------------+ -*/ - /* Reads only for ONE hardware component */ int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_Address, -- cgit v1.2.3 From 6bbdee1435531ba90ed5b9ef0f083bd7598d847b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:03:05 -0700 Subject: staging: comedi: addi_eeprom: make v_EepromWaitBusy() static This function is only used in this file. Move it to remove the need for the forward declaration. Also, remove the comment about an error in the data book. It's not really an error just someones misunderstanding about doing a byte read of a dword register. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 29 ++++++++-------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 2e46a1764d0..4e78e7dc2a2 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -132,13 +132,21 @@ int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_EepromStartAddress); -void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress); void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue); -void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress); void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand, unsigned char b_DataLengthInBits); void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value); +static void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress) +{ + unsigned char b_EepromBusy = 0; + + do { + b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F); + b_EepromBusy = b_EepromBusy & 0x80; + } while (b_EepromBusy == 0x80); +} + unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_EepromStartAddress) { @@ -221,23 +229,6 @@ unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc return w_ReadWord; } -void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress) -{ - unsigned char b_EepromBusy = 0; - - do - { - /* IMPORTANT */ - /* An error has been written in the AMCC 5933 book at the page B-13 */ - /* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and */ - /* the operator register is AMCC_OP_REG_MCSR+3 */ - /* unsigned short read EEPROM=0x8000 andAMCC_OP_REG_MCSR+2 */ - /* unsigned int read EEPROM=0x80000000 and AMCC_OP_REG_MCSR */ - b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F); - b_EepromBusy = b_EepromBusy & 0x80; - } while (b_EepromBusy == 0x80); -} - void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue) { /* Set EEPROM clock Low */ -- cgit v1.2.3 From c598686f5d34897a92226436d2347a38638e4726 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:03:20 -0700 Subject: staging: comedi: addi_eeprom: make the 93c76 eeprom functions static The functions used to read the 93c76 eeprom are only used in this file. Move them to remove the need for the forward declarations. Also, remove some of the more obvious comments and fix a couple coding style issues while moving the functions. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 201 +++++++++------------ 1 file changed, 90 insertions(+), 111 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 4e78e7dc2a2..2eff9a5cc80 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -132,10 +132,96 @@ int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_EepromStartAddress); -void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue); -void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand, - unsigned char b_DataLengthInBits); -void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value); + +static void v_EepromClock76(unsigned int dw_Address, + unsigned int dw_RegisterValue) +{ + /* Set EEPROM clock Low */ + outl(dw_RegisterValue & 0x6, dw_Address); + udelay(100); + + /* Set EEPROM clock High */ + outl(dw_RegisterValue | 0x1, dw_Address); + udelay(100); +} + +static void v_EepromSendCommand76(unsigned int dw_Address, + unsigned int dw_EepromCommand, + unsigned char b_DataLengthInBits) +{ + char c_BitPos = 0; + unsigned int dw_RegisterValue = 0; + + /* Enable EEPROM Chip Select */ + dw_RegisterValue = 0x2; + + /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ + outl(dw_RegisterValue, dw_Address); + udelay(100); + + /* Send EEPROM command - one bit at a time */ + for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--) { + if (dw_EepromCommand & (1 << c_BitPos)) { + /* Write 1 */ + dw_RegisterValue = dw_RegisterValue | 0x4; + } else { + /* Write 0 */ + dw_RegisterValue = dw_RegisterValue & 0x3; + } + + /* Write the command */ + outl(dw_RegisterValue, dw_Address); + udelay(100); + + /* Trigger the EEPROM clock */ + v_EepromClock76(dw_Address, dw_RegisterValue); + } +} + +static void v_EepromCs76Read(unsigned int dw_Address, + unsigned short w_offset, + unsigned short *pw_Value) +{ + char c_BitPos = 0; + unsigned int dw_RegisterValue = 0; + unsigned int dw_RegisterValueRead = 0; + + /* Send EEPROM read command and offset to EEPROM */ + v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2), + EE76_CMD_LEN); + + /* Get the last register value */ + dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2; + + /* Set the 16-bit value of 0 */ + *pw_Value = 0; + + /* Get the 16-bit value */ + for (c_BitPos = 0; c_BitPos < 16; c_BitPos++) { + /* Trigger the EEPROM clock */ + v_EepromClock76(dw_Address, dw_RegisterValue); + + /* Get the result bit */ + dw_RegisterValueRead = inl(dw_Address); + udelay(100); + + /* Get bit value and shift into result */ + if (dw_RegisterValueRead & 0x8) { + /* Read 1 */ + *pw_Value = (*pw_Value << 1) | 0x1; + } else { + /* Read 0 */ + *pw_Value = (*pw_Value << 1); + } + } + + /* Clear all EEPROM bits */ + dw_RegisterValue = 0x0; + + /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ + outl(dw_RegisterValue, dw_Address); + udelay(100); +} static void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress) { @@ -229,113 +315,6 @@ unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc return w_ReadWord; } -void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue) -{ - /* Set EEPROM clock Low */ - outl(dw_RegisterValue & 0x6, dw_Address); - - /* Wait 0.1 ms */ - udelay(100); - - /* Set EEPROM clock High */ - outl(dw_RegisterValue | 0x1, dw_Address); - - /* Wait 0.1 ms */ - udelay(100); -} - -void v_EepromSendCommand76(unsigned int dw_Address, unsigned int dw_EepromCommand, - unsigned char b_DataLengthInBits) -{ - char c_BitPos = 0; - unsigned int dw_RegisterValue = 0; - - /* Enable EEPROM Chip Select */ - dw_RegisterValue = 0x2; - - /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - outl(dw_RegisterValue, dw_Address); - - /* Wait 0.1 ms */ - udelay(100); - - /* Send EEPROM command - one bit at a time */ - for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--) - { - /* Check if current bit is 0 or 1 */ - if (dw_EepromCommand & (1 << c_BitPos)) - { - /* Write 1 */ - dw_RegisterValue = dw_RegisterValue | 0x4; - } - else - { - /* Write 0 */ - dw_RegisterValue = dw_RegisterValue & 0x3; - } - - /* Write the command */ - outl(dw_RegisterValue, dw_Address); - - /* Wait 0.1 ms */ - udelay(100); - - /* Trigger the EEPROM clock */ - v_EepromClock76(dw_Address, dw_RegisterValue); - } -} - -void v_EepromCs76Read(unsigned int dw_Address, unsigned short w_offset, unsigned short *pw_Value) -{ - char c_BitPos = 0; - unsigned int dw_RegisterValue = 0; - unsigned int dw_RegisterValueRead = 0; - - /* Send EEPROM read command and offset to EEPROM */ - v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2), - EE76_CMD_LEN); - - /* Get the last register value */ - dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2; - - /* Set the 16-bit value of 0 */ - *pw_Value = 0; - - /* Get the 16-bit value */ - for (c_BitPos = 0; c_BitPos < 16; c_BitPos++) - { - /* Trigger the EEPROM clock */ - v_EepromClock76(dw_Address, dw_RegisterValue); - - /* Get the result bit */ - dw_RegisterValueRead = inl(dw_Address); - - /* Wait 0.1 ms */ - udelay(100); - - /* Get bit value and shift into result */ - if (dw_RegisterValueRead & 0x8) - { - /* Read 1 */ - *pw_Value = (*pw_Value << 1) | 0x1; - } - else - { - /* Read 0 */ - *pw_Value = (*pw_Value << 1); - } - } - - /* Clear all EEPROM bits */ - dw_RegisterValue = 0x0; - - /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - outl(dw_RegisterValue, dw_Address); - - /* Wait 0.1 ms */ - udelay(100); -} - int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, struct comedi_device *dev) { -- cgit v1.2.3 From aa36c7720aa65417a992c9722a2ee34c74572d50 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:03:36 -0700 Subject: staging: comedi: addi_eeprom: make the eeprom helper functions static The functions used to read the eeprom header information blocks are only used in this file. Move them to remove the need for the forward declarations. The i_EepromReadTimerHeader() function is currently not being used. Block it out with and #if 0/#endif until it's determined if it should be removed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 297 ++++++++++----------- 1 file changed, 142 insertions(+), 155 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 2eff9a5cc80..c42f05c612f 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -110,26 +110,6 @@ struct str_AnalogInputHeader { int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, struct comedi_device *dev); -int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_DigitalInputHeader *s_Header); - -int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_DigitalOutputHeader *s_Header); - -int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_TimerMainHeader *s_Header); - -int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_AnalogOutputHeader *s_Header); - -int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_AnalogInputHeader *s_Header); - unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, unsigned short w_EepromStartAddress); @@ -315,6 +295,148 @@ unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc return w_ReadWord; } +static int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, + char *pc_PCIChipInformation, + unsigned short w_Address, + struct str_DigitalInputHeader *s_Header) +{ + unsigned short w_Temp; + + /* read nbr of channels */ + s_Header->w_Nchannel = + w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, + 0x100 + w_Address + 6); + + /* interruptible or not */ + w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, + pc_PCIChipInformation, 0x100 + w_Address + 8); + s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01; + +/* How many interruptible logic */ + s_Header->w_NinterruptLogic = + w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, + 0x100 + w_Address + 10); + + return 0; +} + +static int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, + char *pc_PCIChipInformation, + unsigned short w_Address, + struct str_DigitalOutputHeader *s_Header) +{ +/* Read Nbr channels */ + s_Header->w_Nchannel = + w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, + 0x100 + w_Address + 6); + return 0; +} + +#if 0 +static int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, + char *pc_PCIChipInformation, + unsigned short w_Address, + struct str_TimerMainHeader *s_Header) +{ + + unsigned short i, w_Size = 0, w_Temp; + +/* Read No of Timer */ + s_Header->w_Ntimer = + w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, + 0x100 + w_Address + 6); +/* Read header size */ + + for (i = 0; i < s_Header->w_Ntimer; i++) { + s_Header->s_TimerDetails[i].w_HeaderSize = + w_EepromReadWord(w_PCIBoardEepromAddress, + pc_PCIChipInformation, + 0x100 + w_Address + 8 + w_Size + 0); + w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, + pc_PCIChipInformation, + 0x100 + w_Address + 8 + w_Size + 2); + + /* Read Resolution */ + s_Header->s_TimerDetails[i].b_Resolution = + (unsigned char) (w_Temp >> 10) & 0x3F; + + /* Read Mode */ + s_Header->s_TimerDetails[i].b_Mode = + (unsigned char) (w_Temp >> 4) & 0x3F; + + w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, + pc_PCIChipInformation, + 0x100 + w_Address + 8 + w_Size + 4); + + /* Read MinTiming */ + s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF; + + /* Read Timebase */ + s_Header->s_TimerDetails[i].b_TimeBase = (unsigned char) (w_Temp) & 0x3F; + w_Size += s_Header->s_TimerDetails[i].w_HeaderSize; + } + + return 0; +} +#endif + +static int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, + char *pc_PCIChipInformation, + unsigned short w_Address, + struct str_AnalogOutputHeader *s_Header) +{ + unsigned short w_Temp; + /* No of channels for 1st hard component */ + w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, + pc_PCIChipInformation, 0x100 + w_Address + 10); + s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; + /* Resolution for 1st hard component */ + w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, + pc_PCIChipInformation, 0x100 + w_Address + 16); + s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF; + return 0; +} + +/* Reads only for ONE hardware component */ +static int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, + char *pc_PCIChipInformation, + unsigned short w_Address, + struct str_AnalogInputHeader *s_Header) +{ + unsigned short w_Temp, w_Offset; + w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, + pc_PCIChipInformation, 0x100 + w_Address + 10); + s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; + s_Header->w_MinConvertTiming = + w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, + 0x100 + w_Address + 16); + s_Header->w_MinDelayTiming = + w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, + 0x100 + w_Address + 30); + w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, + pc_PCIChipInformation, 0x100 + w_Address + 20); + s_Header->b_HasDma = (w_Temp >> 13) & 0x01; /* whether dma present or not */ + + w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72); /* reading Y */ + w_Temp = w_Temp & 0x00FF; + if (w_Temp) /* Y>0 */ + { + w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16))); /* offset of first analog input single header */ + w_Offset = w_Offset + 2; /* resolution */ + } else /* Y=0 */ + { + w_Offset = 74; + w_Offset = w_Offset + 2; /* resolution */ + } + +/* read Resolution */ + w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, + pc_PCIChipInformation, 0x100 + w_Address + w_Offset); + s_Header->b_Resolution = w_Temp & 0x001F; /* last 5 bits */ + + return 0; +} + int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, struct comedi_device *dev) { @@ -436,138 +558,3 @@ int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, return 0; } - -int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_DigitalInputHeader *s_Header) -{ - unsigned short w_Temp; - - /* read nbr of channels */ - s_Header->w_Nchannel = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 6); - - /* interruptible or not */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 8); - s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01; - -/* How many interruptible logic */ - s_Header->w_NinterruptLogic = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 10); - - return 0; -} - -int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_DigitalOutputHeader *s_Header) -{ -/* Read Nbr channels */ - s_Header->w_Nchannel = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 6); - return 0; -} - -int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_TimerMainHeader *s_Header) -{ - - unsigned short i, w_Size = 0, w_Temp; - -/* Read No of Timer */ - s_Header->w_Ntimer = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 6); -/* Read header size */ - - for (i = 0; i < s_Header->w_Ntimer; i++) { - s_Header->s_TimerDetails[i].w_HeaderSize = - w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - 0x100 + w_Address + 8 + w_Size + 0); - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - 0x100 + w_Address + 8 + w_Size + 2); - - /* Read Resolution */ - s_Header->s_TimerDetails[i].b_Resolution = - (unsigned char) (w_Temp >> 10) & 0x3F; - - /* Read Mode */ - s_Header->s_TimerDetails[i].b_Mode = - (unsigned char) (w_Temp >> 4) & 0x3F; - - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - 0x100 + w_Address + 8 + w_Size + 4); - - /* Read MinTiming */ - s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF; - - /* Read Timebase */ - s_Header->s_TimerDetails[i].b_TimeBase = (unsigned char) (w_Temp) & 0x3F; - w_Size += s_Header->s_TimerDetails[i].w_HeaderSize; - } - - return 0; -} - -int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_AnalogOutputHeader *s_Header) -{ - unsigned short w_Temp; - /* No of channels for 1st hard component */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 10); - s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; - /* Resolution for 1st hard component */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 16); - s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF; - return 0; -} - -/* Reads only for ONE hardware component */ -int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, unsigned short w_Address, - struct str_AnalogInputHeader *s_Header) -{ - unsigned short w_Temp, w_Offset; - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 10); - s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; - s_Header->w_MinConvertTiming = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 16); - s_Header->w_MinDelayTiming = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 30); - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 20); - s_Header->b_HasDma = (w_Temp >> 13) & 0x01; /* whether dma present or not */ - - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72); /* reading Y */ - w_Temp = w_Temp & 0x00FF; - if (w_Temp) /* Y>0 */ - { - w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16))); /* offset of first analog input single header */ - w_Offset = w_Offset + 2; /* resolution */ - } else /* Y=0 */ - { - w_Offset = 74; - w_Offset = w_Offset + 2; /* resolution */ - } - -/* read Resolution */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + w_Offset); - s_Header->b_Resolution = w_Temp & 0x001F; /* last 5 bits */ - - return 0; -} -- cgit v1.2.3 From 67ae9a429152a98adbc023c3ce56d85a38c388e2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:03:54 -0700 Subject: staging: comedi: addi_eeprom: remove the last forward declarations None of the functions in this file are exported. Make them static and remove the unnecessary forward declarations. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_eeprom.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index c42f05c612f..b95d4c57177 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -107,12 +107,6 @@ struct str_AnalogInputHeader { unsigned char b_Resolution; }; -int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, struct comedi_device *dev); - -unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, - unsigned short w_EepromStartAddress); - static void v_EepromClock76(unsigned int dw_Address, unsigned int dw_RegisterValue) { @@ -213,8 +207,9 @@ static void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress) } while (b_EepromBusy == 0x80); } -unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, char *pc_PCIChipInformation, - unsigned short w_EepromStartAddress) +static unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, + char *pc_PCIChipInformation, + unsigned short w_EepromStartAddress) { unsigned char b_Counter = 0; unsigned char b_ReadByte = 0; @@ -437,8 +432,9 @@ static int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, return 0; } -int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, - char *pc_PCIChipInformation, struct comedi_device *dev) +static int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, + char *pc_PCIChipInformation, + struct comedi_device *dev) { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; -- cgit v1.2.3 From f9d83443815c29a9bdcfa4d9bcddb66e26655a56 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:04:10 -0700 Subject: staging: comedi: addi_eeprom: rename 'dw_Address'/'w_PCIBoardEepromAddress' This variable is actually the PCI bar 0 i/o address of the device found with pci_resource_start(). For aesthetic reasons, rename it to 'iobase' and change to type to an unsigned long. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 184 ++++++++++----------- 1 file changed, 88 insertions(+), 96 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index b95d4c57177..306edc82fc0 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -107,19 +107,19 @@ struct str_AnalogInputHeader { unsigned char b_Resolution; }; -static void v_EepromClock76(unsigned int dw_Address, +static void v_EepromClock76(unsigned long iobase, unsigned int dw_RegisterValue) { /* Set EEPROM clock Low */ - outl(dw_RegisterValue & 0x6, dw_Address); + outl(dw_RegisterValue & 0x6, iobase); udelay(100); /* Set EEPROM clock High */ - outl(dw_RegisterValue | 0x1, dw_Address); + outl(dw_RegisterValue | 0x1, iobase); udelay(100); } -static void v_EepromSendCommand76(unsigned int dw_Address, +static void v_EepromSendCommand76(unsigned long iobase, unsigned int dw_EepromCommand, unsigned char b_DataLengthInBits) { @@ -130,7 +130,7 @@ static void v_EepromSendCommand76(unsigned int dw_Address, dw_RegisterValue = 0x2; /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - outl(dw_RegisterValue, dw_Address); + outl(dw_RegisterValue, iobase); udelay(100); /* Send EEPROM command - one bit at a time */ @@ -144,15 +144,15 @@ static void v_EepromSendCommand76(unsigned int dw_Address, } /* Write the command */ - outl(dw_RegisterValue, dw_Address); + outl(dw_RegisterValue, iobase); udelay(100); /* Trigger the EEPROM clock */ - v_EepromClock76(dw_Address, dw_RegisterValue); + v_EepromClock76(iobase, dw_RegisterValue); } } -static void v_EepromCs76Read(unsigned int dw_Address, +static void v_EepromCs76Read(unsigned long iobase, unsigned short w_offset, unsigned short *pw_Value) { @@ -161,7 +161,7 @@ static void v_EepromCs76Read(unsigned int dw_Address, unsigned int dw_RegisterValueRead = 0; /* Send EEPROM read command and offset to EEPROM */ - v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2), + v_EepromSendCommand76(iobase, (EE_READ << 4) | (w_offset / 2), EE76_CMD_LEN); /* Get the last register value */ @@ -173,10 +173,10 @@ static void v_EepromCs76Read(unsigned int dw_Address, /* Get the 16-bit value */ for (c_BitPos = 0; c_BitPos < 16; c_BitPos++) { /* Trigger the EEPROM clock */ - v_EepromClock76(dw_Address, dw_RegisterValue); + v_EepromClock76(iobase, dw_RegisterValue); /* Get the result bit */ - dw_RegisterValueRead = inl(dw_Address); + dw_RegisterValueRead = inl(iobase); udelay(100); /* Get bit value and shift into result */ @@ -193,21 +193,21 @@ static void v_EepromCs76Read(unsigned int dw_Address, dw_RegisterValue = 0x0; /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - outl(dw_RegisterValue, dw_Address); + outl(dw_RegisterValue, iobase); udelay(100); } -static void v_EepromWaitBusy(unsigned short w_PCIBoardEepromAddress) +static void v_EepromWaitBusy(unsigned long iobase) { unsigned char b_EepromBusy = 0; do { - b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F); + b_EepromBusy = inb(iobase + 0x3F); b_EepromBusy = b_EepromBusy & 0x80; } while (b_EepromBusy == 0x80); } -static unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, +static unsigned short w_EepromReadWord(unsigned long iobase, char *pc_PCIChipInformation, unsigned short w_EepromStartAddress) { @@ -229,42 +229,40 @@ static unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256; /* Read the high 8 bit part */ /* Select the load low address mode */ - outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F); + outb(NVCMD_LOAD_LOW, iobase + 0x3F); /* Wait on busy */ - v_EepromWaitBusy(w_PCIBoardEepromAddress); + v_EepromWaitBusy(iobase); /* Load the low address */ - outb(b_SelectedAddressLow, - w_PCIBoardEepromAddress + 0x3E); + outb(b_SelectedAddressLow, iobase + 0x3E); /* Wait on busy */ - v_EepromWaitBusy(w_PCIBoardEepromAddress); + v_EepromWaitBusy(iobase); /* Select the load high address mode */ - outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F); + outb(NVCMD_LOAD_HIGH, iobase + 0x3F); /* Wait on busy */ - v_EepromWaitBusy(w_PCIBoardEepromAddress); + v_EepromWaitBusy(iobase); /* Load the high address */ - outb(b_SelectedAddressHigh, - w_PCIBoardEepromAddress + 0x3E); + outb(b_SelectedAddressHigh, iobase + 0x3E); /* Wait on busy */ - v_EepromWaitBusy(w_PCIBoardEepromAddress); + v_EepromWaitBusy(iobase); /* Select the READ mode */ - outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F); + outb(NVCMD_BEGIN_READ, iobase + 0x3F); /* Wait on busy */ - v_EepromWaitBusy(w_PCIBoardEepromAddress); + v_EepromWaitBusy(iobase); /* Read data into the EEPROM */ - b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E); + b_ReadByte = inb(iobase + 0x3E); /* Wait on busy */ - v_EepromWaitBusy(w_PCIBoardEepromAddress); + v_EepromWaitBusy(iobase); /* Select the upper address part */ if (b_Counter == 0) @@ -283,14 +281,13 @@ static unsigned short w_EepromReadWord(unsigned short w_PCIBoardEepromAddress, if (!strcmp(pc_PCIChipInformation, "93C76")) { /* Read 16 bit from the EEPROM 93C76 */ - v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress, - &w_ReadWord); + v_EepromCs76Read(iobase, w_EepromStartAddress, &w_ReadWord); } return w_ReadWord; } -static int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress, +static int i_EepromReadDigitalInputHeader(unsigned long iobase, char *pc_PCIChipInformation, unsigned short w_Address, struct str_DigitalInputHeader *s_Header) @@ -298,37 +295,35 @@ static int i_EepromReadDigitalInputHeader(unsigned short w_PCIBoardEepromAddress unsigned short w_Temp; /* read nbr of channels */ - s_Header->w_Nchannel = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 6); + s_Header->w_Nchannel = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + 6); /* interruptible or not */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 8); + w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + 8); s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01; -/* How many interruptible logic */ - s_Header->w_NinterruptLogic = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 10); + /* How many interruptible logic */ + s_Header->w_NinterruptLogic = w_EepromReadWord(iobase, + pc_PCIChipInformation, + 0x100 + w_Address + 10); return 0; } -static int i_EepromReadDigitalOutputHeader(unsigned short w_PCIBoardEepromAddress, +static int i_EepromReadDigitalOutputHeader(unsigned long iobase, char *pc_PCIChipInformation, unsigned short w_Address, struct str_DigitalOutputHeader *s_Header) { -/* Read Nbr channels */ - s_Header->w_Nchannel = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 6); + /* Read Nbr channels */ + s_Header->w_Nchannel = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + 6); return 0; } #if 0 -static int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, +static int i_EepromReadTimerHeader(unsigned long iobase, char *pc_PCIChipInformation, unsigned short w_Address, struct str_TimerMainHeader *s_Header) @@ -336,20 +331,16 @@ static int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, unsigned short i, w_Size = 0, w_Temp; -/* Read No of Timer */ - s_Header->w_Ntimer = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 6); -/* Read header size */ - + /* Read No of Timer */ + s_Header->w_Ntimer = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + 6); + /* Read header size */ for (i = 0; i < s_Header->w_Ntimer; i++) { s_Header->s_TimerDetails[i].w_HeaderSize = - w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - 0x100 + w_Address + 8 + w_Size + 0); - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - 0x100 + w_Address + 8 + w_Size + 2); + w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + 8 + w_Size + 0); + w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + 8 + w_Size + 2); /* Read Resolution */ s_Header->s_TimerDetails[i].b_Resolution = @@ -359,9 +350,8 @@ static int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, s_Header->s_TimerDetails[i].b_Mode = (unsigned char) (w_Temp >> 4) & 0x3F; - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, - 0x100 + w_Address + 8 + w_Size + 4); + w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + 8 + w_Size + 4); /* Read MinTiming */ s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF; @@ -375,44 +365,46 @@ static int i_EepromReadTimerHeader(unsigned short w_PCIBoardEepromAddress, } #endif -static int i_EepromReadAnlogOutputHeader(unsigned short w_PCIBoardEepromAddress, +static int i_EepromReadAnlogOutputHeader(unsigned long iobase, char *pc_PCIChipInformation, unsigned short w_Address, struct str_AnalogOutputHeader *s_Header) { unsigned short w_Temp; + /* No of channels for 1st hard component */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 10); + w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + 10); s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; /* Resolution for 1st hard component */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 16); + w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + 16); s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF; return 0; } /* Reads only for ONE hardware component */ -static int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, +static int i_EepromReadAnlogInputHeader(unsigned long iobase, char *pc_PCIChipInformation, unsigned short w_Address, struct str_AnalogInputHeader *s_Header) { unsigned short w_Temp, w_Offset; - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 10); + w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + 10); s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; - s_Header->w_MinConvertTiming = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 16); - s_Header->w_MinDelayTiming = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + w_Address + 30); - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + 20); + s_Header->w_MinConvertTiming = w_EepromReadWord(iobase, + pc_PCIChipInformation, + 0x100 + w_Address + 16); + s_Header->w_MinDelayTiming = w_EepromReadWord(iobase, + pc_PCIChipInformation, + 0x100 + w_Address + 30); + w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + 20); s_Header->b_HasDma = (w_Temp >> 13) & 0x01; /* whether dma present or not */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72); /* reading Y */ + w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + 72); /* reading Y */ w_Temp = w_Temp & 0x00FF; if (w_Temp) /* Y>0 */ { @@ -424,15 +416,15 @@ static int i_EepromReadAnlogInputHeader(unsigned short w_PCIBoardEepromAddress, w_Offset = w_Offset + 2; /* resolution */ } -/* read Resolution */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + w_Address + w_Offset); + /* read Resolution */ + w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + w_Address + w_Offset); s_Header->b_Resolution = w_Temp & 0x001F; /* last 5 bits */ return 0; } -static int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, +static int i_EepromReadMainHeader(unsigned long iobase, char *pc_PCIChipInformation, struct comedi_device *dev) { @@ -448,26 +440,26 @@ static int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, struct str_AnalogInputHeader s_AnalogInputHeader; /* Read size */ - s_MainHeader.w_HeaderSize = - w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, - 0x100 + 8); + s_MainHeader.w_HeaderSize = w_EepromReadWord(iobase, + pc_PCIChipInformation, + 0x100 + 8); /* Read nbr of functionality */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + 10); + w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + 10); s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF; /* Read functionality details */ for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { /* Read Type */ - w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + 12 + w_Count); + w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + 12 + w_Count); s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F; w_Count = w_Count + 2; /* Read Address */ s_MainHeader.s_Functions[i].w_Address = - w_EepromReadWord(w_PCIBoardEepromAddress, - pc_PCIChipInformation, 0x100 + 12 + w_Count); + w_EepromReadWord(iobase, pc_PCIChipInformation, + 0x100 + 12 + w_Count); w_Count = w_Count + 2; } @@ -476,7 +468,7 @@ static int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, switch (s_MainHeader.s_Functions[i].b_Type) { case EEPROM_DIGITALINPUT: - i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress, + i_EepromReadDigitalInputHeader(iobase, pc_PCIChipInformation, s_MainHeader.s_Functions[i].w_Address, &s_DigitalInputHeader); @@ -485,7 +477,7 @@ static int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, break; case EEPROM_DIGITALOUTPUT: - i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress, + i_EepromReadDigitalOutputHeader(iobase, pc_PCIChipInformation, s_MainHeader.s_Functions[i].w_Address, &s_DigitalOutputHeader); @@ -498,7 +490,7 @@ static int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, break; case EEPROM_ANALOGINPUT: - i_EepromReadAnlogInputHeader(w_PCIBoardEepromAddress, + i_EepromReadAnlogInputHeader(iobase, pc_PCIChipInformation, s_MainHeader.s_Functions[i].w_Address, &s_AnalogInputHeader); @@ -523,7 +515,7 @@ static int i_EepromReadMainHeader(unsigned short w_PCIBoardEepromAddress, break; case EEPROM_ANALOGOUTPUT: - i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress, + i_EepromReadAnlogOutputHeader(iobase, pc_PCIChipInformation, s_MainHeader.s_Functions[i].w_Address, &s_AnalogOutputHeader); -- cgit v1.2.3 From 6baf51033cf7babf23091725510e4468daac2149 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:04:33 -0700 Subject: staging: comedi: addi_eeprom: rename 'pc_PCIChipInformation' This variable is the pointer to the string name of the eeprom type found on the board. This name comes from the boardinfo of the driver. For aesthetic reasons, rename it to simply 'type'. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 79 ++++++++++------------ 1 file changed, 34 insertions(+), 45 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 306edc82fc0..935da640188 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -208,7 +208,7 @@ static void v_EepromWaitBusy(unsigned long iobase) } static unsigned short w_EepromReadWord(unsigned long iobase, - char *pc_PCIChipInformation, + char *type, unsigned short w_EepromStartAddress) { unsigned char b_Counter = 0; @@ -220,9 +220,7 @@ static unsigned short w_EepromReadWord(unsigned long iobase, unsigned short w_ReadWord = 0; /* Test the PCI chip type */ - if ((!strcmp(pc_PCIChipInformation, "S5920")) || - (!strcmp(pc_PCIChipInformation, "S5933"))) - { + if (!strcmp(type, "S5920") || !strcmp(type, "S5933")) { for (b_Counter = 0; b_Counter < 2; b_Counter++) { b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256; /* Read the low 8 bit part */ @@ -276,10 +274,9 @@ static unsigned short w_EepromReadWord(unsigned long iobase, } /* for (b_Counter=0; b_Counter<2; b_Counter++) */ w_ReadWord = (b_ReadLowByte | (((unsigned short) b_ReadHighByte) * 256)); - } /* end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933"))) */ + } - if (!strcmp(pc_PCIChipInformation, "93C76")) - { + if (!strcmp(type, "93C76")) { /* Read 16 bit from the EEPROM 93C76 */ v_EepromCs76Read(iobase, w_EepromStartAddress, &w_ReadWord); } @@ -288,43 +285,42 @@ static unsigned short w_EepromReadWord(unsigned long iobase, } static int i_EepromReadDigitalInputHeader(unsigned long iobase, - char *pc_PCIChipInformation, + char *type, unsigned short w_Address, struct str_DigitalInputHeader *s_Header) { unsigned short w_Temp; /* read nbr of channels */ - s_Header->w_Nchannel = w_EepromReadWord(iobase, pc_PCIChipInformation, + s_Header->w_Nchannel = w_EepromReadWord(iobase, type, 0x100 + w_Address + 6); /* interruptible or not */ - w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + w_Temp = w_EepromReadWord(iobase, type, 0x100 + w_Address + 8); s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01; /* How many interruptible logic */ - s_Header->w_NinterruptLogic = w_EepromReadWord(iobase, - pc_PCIChipInformation, + s_Header->w_NinterruptLogic = w_EepromReadWord(iobase, type, 0x100 + w_Address + 10); return 0; } static int i_EepromReadDigitalOutputHeader(unsigned long iobase, - char *pc_PCIChipInformation, + char *type, unsigned short w_Address, struct str_DigitalOutputHeader *s_Header) { /* Read Nbr channels */ - s_Header->w_Nchannel = w_EepromReadWord(iobase, pc_PCIChipInformation, + s_Header->w_Nchannel = w_EepromReadWord(iobase, type, 0x100 + w_Address + 6); return 0; } #if 0 static int i_EepromReadTimerHeader(unsigned long iobase, - char *pc_PCIChipInformation, + char *type, unsigned short w_Address, struct str_TimerMainHeader *s_Header) { @@ -332,14 +328,14 @@ static int i_EepromReadTimerHeader(unsigned long iobase, unsigned short i, w_Size = 0, w_Temp; /* Read No of Timer */ - s_Header->w_Ntimer = w_EepromReadWord(iobase, pc_PCIChipInformation, + s_Header->w_Ntimer = w_EepromReadWord(iobase, type, 0x100 + w_Address + 6); /* Read header size */ for (i = 0; i < s_Header->w_Ntimer; i++) { s_Header->s_TimerDetails[i].w_HeaderSize = - w_EepromReadWord(iobase, pc_PCIChipInformation, + w_EepromReadWord(iobase, type, 0x100 + w_Address + 8 + w_Size + 0); - w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + w_Temp = w_EepromReadWord(iobase, type, 0x100 + w_Address + 8 + w_Size + 2); /* Read Resolution */ @@ -350,7 +346,7 @@ static int i_EepromReadTimerHeader(unsigned long iobase, s_Header->s_TimerDetails[i].b_Mode = (unsigned char) (w_Temp >> 4) & 0x3F; - w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + w_Temp = w_EepromReadWord(iobase, type, 0x100 + w_Address + 8 + w_Size + 4); /* Read MinTiming */ @@ -366,18 +362,18 @@ static int i_EepromReadTimerHeader(unsigned long iobase, #endif static int i_EepromReadAnlogOutputHeader(unsigned long iobase, - char *pc_PCIChipInformation, + char *type, unsigned short w_Address, struct str_AnalogOutputHeader *s_Header) { unsigned short w_Temp; /* No of channels for 1st hard component */ - w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + w_Temp = w_EepromReadWord(iobase, type, 0x100 + w_Address + 10); s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; /* Resolution for 1st hard component */ - w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + w_Temp = w_EepromReadWord(iobase, type, 0x100 + w_Address + 16); s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF; return 0; @@ -385,25 +381,23 @@ static int i_EepromReadAnlogOutputHeader(unsigned long iobase, /* Reads only for ONE hardware component */ static int i_EepromReadAnlogInputHeader(unsigned long iobase, - char *pc_PCIChipInformation, + char *type, unsigned short w_Address, struct str_AnalogInputHeader *s_Header) { unsigned short w_Temp, w_Offset; - w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + w_Temp = w_EepromReadWord(iobase, type, 0x100 + w_Address + 10); s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; - s_Header->w_MinConvertTiming = w_EepromReadWord(iobase, - pc_PCIChipInformation, + s_Header->w_MinConvertTiming = w_EepromReadWord(iobase, type, 0x100 + w_Address + 16); - s_Header->w_MinDelayTiming = w_EepromReadWord(iobase, - pc_PCIChipInformation, + s_Header->w_MinDelayTiming = w_EepromReadWord(iobase, type, 0x100 + w_Address + 30); - w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + w_Temp = w_EepromReadWord(iobase, type, 0x100 + w_Address + 20); s_Header->b_HasDma = (w_Temp >> 13) & 0x01; /* whether dma present or not */ - w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + w_Temp = w_EepromReadWord(iobase, type, 0x100 + w_Address + 72); /* reading Y */ w_Temp = w_Temp & 0x00FF; if (w_Temp) /* Y>0 */ @@ -417,7 +411,7 @@ static int i_EepromReadAnlogInputHeader(unsigned long iobase, } /* read Resolution */ - w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + w_Temp = w_EepromReadWord(iobase, type, 0x100 + w_Address + w_Offset); s_Header->b_Resolution = w_Temp & 0x001F; /* last 5 bits */ @@ -425,7 +419,7 @@ static int i_EepromReadAnlogInputHeader(unsigned long iobase, } static int i_EepromReadMainHeader(unsigned long iobase, - char *pc_PCIChipInformation, + char *type, struct comedi_device *dev) { const struct addi_board *this_board = comedi_board(dev); @@ -440,25 +434,24 @@ static int i_EepromReadMainHeader(unsigned long iobase, struct str_AnalogInputHeader s_AnalogInputHeader; /* Read size */ - s_MainHeader.w_HeaderSize = w_EepromReadWord(iobase, - pc_PCIChipInformation, + s_MainHeader.w_HeaderSize = w_EepromReadWord(iobase, type, 0x100 + 8); /* Read nbr of functionality */ - w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + w_Temp = w_EepromReadWord(iobase, type, 0x100 + 10); s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF; /* Read functionality details */ for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { /* Read Type */ - w_Temp = w_EepromReadWord(iobase, pc_PCIChipInformation, + w_Temp = w_EepromReadWord(iobase, type, 0x100 + 12 + w_Count); s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F; w_Count = w_Count + 2; /* Read Address */ s_MainHeader.s_Functions[i].w_Address = - w_EepromReadWord(iobase, pc_PCIChipInformation, + w_EepromReadWord(iobase, type, 0x100 + 12 + w_Count); w_Count = w_Count + 2; } @@ -468,8 +461,7 @@ static int i_EepromReadMainHeader(unsigned long iobase, switch (s_MainHeader.s_Functions[i].b_Type) { case EEPROM_DIGITALINPUT: - i_EepromReadDigitalInputHeader(iobase, - pc_PCIChipInformation, + i_EepromReadDigitalInputHeader(iobase, type, s_MainHeader.s_Functions[i].w_Address, &s_DigitalInputHeader); devpriv->s_EeParameters.i_NbrDiChannel = @@ -477,8 +469,7 @@ static int i_EepromReadMainHeader(unsigned long iobase, break; case EEPROM_DIGITALOUTPUT: - i_EepromReadDigitalOutputHeader(iobase, - pc_PCIChipInformation, + i_EepromReadDigitalOutputHeader(iobase, type, s_MainHeader.s_Functions[i].w_Address, &s_DigitalOutputHeader); devpriv->s_EeParameters.i_NbrDoChannel = @@ -490,8 +481,7 @@ static int i_EepromReadMainHeader(unsigned long iobase, break; case EEPROM_ANALOGINPUT: - i_EepromReadAnlogInputHeader(iobase, - pc_PCIChipInformation, + i_EepromReadAnlogInputHeader(iobase, type, s_MainHeader.s_Functions[i].w_Address, &s_AnalogInputHeader); if (!(strcmp(this_board->pc_DriverName, "apci3200"))) @@ -515,8 +505,7 @@ static int i_EepromReadMainHeader(unsigned long iobase, break; case EEPROM_ANALOGOUTPUT: - i_EepromReadAnlogOutputHeader(iobase, - pc_PCIChipInformation, + i_EepromReadAnlogOutputHeader(iobase, type, s_MainHeader.s_Functions[i].w_Address, &s_AnalogOutputHeader); devpriv->s_EeParameters.i_NbrAoChannel = -- cgit v1.2.3 From d615de255485ad442da80526aa9b9f97a450b607 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:04:48 -0700 Subject: staging: comedi: addi_eeprom: add defines for the 93c76 eeprom bits Define the magic values used for the clock, chip-select, data out, and data in signals to the 93c76 eeprom. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 31 ++++++++++------------ 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 935da640188..6a2c3897d53 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -48,6 +48,11 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ #define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ #define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ + +#define EE93C76_CLK_BIT (1 << 0) +#define EE93C76_CS_BIT (1 << 1) +#define EE93C76_DOUT_BIT (1 << 2) +#define EE93C76_DIN_BIT (1 << 3) #define EE76_CMD_LEN 13 /* bits in instructions */ #define EE_READ 0x0180 /* 01 1000 0000 read instruction */ @@ -110,12 +115,10 @@ struct str_AnalogInputHeader { static void v_EepromClock76(unsigned long iobase, unsigned int dw_RegisterValue) { - /* Set EEPROM clock Low */ - outl(dw_RegisterValue & 0x6, iobase); + outl(dw_RegisterValue & ~EE93C76_CLK_BIT, iobase); udelay(100); - /* Set EEPROM clock High */ - outl(dw_RegisterValue | 0x1, iobase); + outl(dw_RegisterValue | EE93C76_CLK_BIT, iobase); udelay(100); } @@ -123,11 +126,8 @@ static void v_EepromSendCommand76(unsigned long iobase, unsigned int dw_EepromCommand, unsigned char b_DataLengthInBits) { + unsigned int dw_RegisterValue = EE93C76_CS_BIT; char c_BitPos = 0; - unsigned int dw_RegisterValue = 0; - - /* Enable EEPROM Chip Select */ - dw_RegisterValue = 0x2; /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ outl(dw_RegisterValue, iobase); @@ -135,13 +135,10 @@ static void v_EepromSendCommand76(unsigned long iobase, /* Send EEPROM command - one bit at a time */ for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--) { - if (dw_EepromCommand & (1 << c_BitPos)) { - /* Write 1 */ - dw_RegisterValue = dw_RegisterValue | 0x4; - } else { - /* Write 0 */ - dw_RegisterValue = dw_RegisterValue & 0x3; - } + if (dw_EepromCommand & (1 << c_BitPos)) + dw_RegisterValue = dw_RegisterValue | EE93C76_DOUT_BIT; + else + dw_RegisterValue = dw_RegisterValue & ~EE93C76_DOUT_BIT; /* Write the command */ outl(dw_RegisterValue, iobase); @@ -165,7 +162,7 @@ static void v_EepromCs76Read(unsigned long iobase, EE76_CMD_LEN); /* Get the last register value */ - dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2; + dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | EE93C76_CS_BIT; /* Set the 16-bit value of 0 */ *pw_Value = 0; @@ -180,7 +177,7 @@ static void v_EepromCs76Read(unsigned long iobase, udelay(100); /* Get bit value and shift into result */ - if (dw_RegisterValueRead & 0x8) { + if (dw_RegisterValueRead & EE93C76_DIN_BIT) { /* Read 1 */ *pw_Value = (*pw_Value << 1) | 0x1; } else { -- cgit v1.2.3 From 7522e09b6187e5196b48c5759291c1385d200536 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:05:03 -0700 Subject: staging: comedi: addi_eeprom: cleanup v_EepromClock76() Add namespace to the function by renaming the CamelCase function to addi_eeprom_clk_93c76(). Rename the CamelCase parameter, dw_RegisterValue, to simply 'val'. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_eeprom.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 6a2c3897d53..0f7eaae2a5e 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -112,13 +112,12 @@ struct str_AnalogInputHeader { unsigned char b_Resolution; }; -static void v_EepromClock76(unsigned long iobase, - unsigned int dw_RegisterValue) +static void addi_eeprom_clk_93c76(unsigned long iobase, unsigned int val) { - outl(dw_RegisterValue & ~EE93C76_CLK_BIT, iobase); + outl(val & ~EE93C76_CLK_BIT, iobase); udelay(100); - outl(dw_RegisterValue | EE93C76_CLK_BIT, iobase); + outl(val | EE93C76_CLK_BIT, iobase); udelay(100); } @@ -144,8 +143,7 @@ static void v_EepromSendCommand76(unsigned long iobase, outl(dw_RegisterValue, iobase); udelay(100); - /* Trigger the EEPROM clock */ - v_EepromClock76(iobase, dw_RegisterValue); + addi_eeprom_clk_93c76(iobase, dw_RegisterValue); } } @@ -169,8 +167,7 @@ static void v_EepromCs76Read(unsigned long iobase, /* Get the 16-bit value */ for (c_BitPos = 0; c_BitPos < 16; c_BitPos++) { - /* Trigger the EEPROM clock */ - v_EepromClock76(iobase, dw_RegisterValue); + addi_eeprom_clk_93c76(iobase, dw_RegisterValue); /* Get the result bit */ dw_RegisterValueRead = inl(iobase); -- cgit v1.2.3 From 6311e135dff98d956a175f7bf3ad4431c17f3785 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:05:17 -0700 Subject: staging: comedi: addi_eeprom: cleanup v_EepromSendCommand76() Add namespace to the function by renaming the CamelCase function to addi_eeprom_cmd_93c76(). Rename the CamelCase parameters and local variables. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 0f7eaae2a5e..dfe44c937fe 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -121,29 +121,29 @@ static void addi_eeprom_clk_93c76(unsigned long iobase, unsigned int val) udelay(100); } -static void v_EepromSendCommand76(unsigned long iobase, - unsigned int dw_EepromCommand, - unsigned char b_DataLengthInBits) +static void addi_eeprom_cmd_93c76(unsigned long iobase, + unsigned int cmd, + unsigned char len) { - unsigned int dw_RegisterValue = EE93C76_CS_BIT; - char c_BitPos = 0; + unsigned int val = EE93C76_CS_BIT; + int i; /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - outl(dw_RegisterValue, iobase); + outl(val, iobase); udelay(100); /* Send EEPROM command - one bit at a time */ - for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--) { - if (dw_EepromCommand & (1 << c_BitPos)) - dw_RegisterValue = dw_RegisterValue | EE93C76_DOUT_BIT; + for (i = (len - 1); i >= 0; i--) { + if (cmd & (1 << i)) + val |= EE93C76_DOUT_BIT; else - dw_RegisterValue = dw_RegisterValue & ~EE93C76_DOUT_BIT; + val &= ~EE93C76_DOUT_BIT; /* Write the command */ - outl(dw_RegisterValue, iobase); + outl(val, iobase); udelay(100); - addi_eeprom_clk_93c76(iobase, dw_RegisterValue); + addi_eeprom_clk_93c76(iobase, val); } } @@ -156,7 +156,7 @@ static void v_EepromCs76Read(unsigned long iobase, unsigned int dw_RegisterValueRead = 0; /* Send EEPROM read command and offset to EEPROM */ - v_EepromSendCommand76(iobase, (EE_READ << 4) | (w_offset / 2), + addi_eeprom_cmd_93c76(iobase, (EE_READ << 4) | (w_offset / 2), EE76_CMD_LEN); /* Get the last register value */ -- cgit v1.2.3 From c9535c8b235f1071e695838407887460a5ca6ab7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:05:43 -0700 Subject: staging: comedi: addi_eeprom: cleanup v_EepromCs76Read() Add namespace to the function by renaming the CamelCase function to addi_eeprom_read_93c76(). Change the return type of the function to unsigned short and just return the read value instead of passing it through a pointer. Rename the CamelCase parameters and local variables. Make addi_eeprom_cmd_93c76() return the last value so it does not need to be calculated. Rename the EE_READ and EE76_CMD_LEN defines so they have namespace associated with the other 93c76 defines. Cleanup the loop that reads the eeprom bits so it's a bit more concise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 64 +++++++++------------- 1 file changed, 25 insertions(+), 39 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index dfe44c937fe..a96cfea9714 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -53,8 +53,8 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define EE93C76_CS_BIT (1 << 1) #define EE93C76_DOUT_BIT (1 << 2) #define EE93C76_DIN_BIT (1 << 3) -#define EE76_CMD_LEN 13 /* bits in instructions */ -#define EE_READ 0x0180 /* 01 1000 0000 read instruction */ +#define EE93C76_READ_CMD (0x0180 << 4) +#define EE93C76_CMD_LEN 13 #define EEPROM_DIGITALINPUT 0 #define EEPROM_DIGITALOUTPUT 1 @@ -121,9 +121,9 @@ static void addi_eeprom_clk_93c76(unsigned long iobase, unsigned int val) udelay(100); } -static void addi_eeprom_cmd_93c76(unsigned long iobase, - unsigned int cmd, - unsigned char len) +static unsigned int addi_eeprom_cmd_93c76(unsigned long iobase, + unsigned int cmd, + unsigned char len) { unsigned int val = EE93C76_CS_BIT; int i; @@ -145,50 +145,38 @@ static void addi_eeprom_cmd_93c76(unsigned long iobase, addi_eeprom_clk_93c76(iobase, val); } + return val; } -static void v_EepromCs76Read(unsigned long iobase, - unsigned short w_offset, - unsigned short *pw_Value) +static unsigned short addi_eeprom_readw_93c76(unsigned long iobase, + unsigned short addr) { - char c_BitPos = 0; - unsigned int dw_RegisterValue = 0; - unsigned int dw_RegisterValueRead = 0; + unsigned short val = 0; + unsigned int cmd; + unsigned int tmp; + int i; /* Send EEPROM read command and offset to EEPROM */ - addi_eeprom_cmd_93c76(iobase, (EE_READ << 4) | (w_offset / 2), - EE76_CMD_LEN); - - /* Get the last register value */ - dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | EE93C76_CS_BIT; - - /* Set the 16-bit value of 0 */ - *pw_Value = 0; + cmd = EE93C76_READ_CMD | (addr / 2); + cmd = addi_eeprom_cmd_93c76(iobase, cmd, EE93C76_CMD_LEN); /* Get the 16-bit value */ - for (c_BitPos = 0; c_BitPos < 16; c_BitPos++) { - addi_eeprom_clk_93c76(iobase, dw_RegisterValue); + for (i = 0; i < 16; i++) { + addi_eeprom_clk_93c76(iobase, cmd); - /* Get the result bit */ - dw_RegisterValueRead = inl(iobase); + tmp = inl(iobase); udelay(100); - /* Get bit value and shift into result */ - if (dw_RegisterValueRead & EE93C76_DIN_BIT) { - /* Read 1 */ - *pw_Value = (*pw_Value << 1) | 0x1; - } else { - /* Read 0 */ - *pw_Value = (*pw_Value << 1); - } + val <<= 1; + if (tmp & EE93C76_DIN_BIT) + val |= 0x1; } - /* Clear all EEPROM bits */ - dw_RegisterValue = 0x0; - /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */ - outl(dw_RegisterValue, iobase); + outl(0, iobase); udelay(100); + + return val; } static void v_EepromWaitBusy(unsigned long iobase) @@ -270,10 +258,8 @@ static unsigned short w_EepromReadWord(unsigned long iobase, w_ReadWord = (b_ReadLowByte | (((unsigned short) b_ReadHighByte) * 256)); } - if (!strcmp(type, "93C76")) { - /* Read 16 bit from the EEPROM 93C76 */ - v_EepromCs76Read(iobase, w_EepromStartAddress, &w_ReadWord); - } + if (!strcmp(type, "93C76")) + w_ReadWord = addi_eeprom_readw_93c76(iobase, w_EepromStartAddress); return w_ReadWord; } -- cgit v1.2.3 From eddc0578c0da97300649966a10e929e708fd948c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:05:59 -0700 Subject: staging: comedi: addi_eeprom: cleanup v_EepromWaitBusy() Add namespace to the function by renaming the CamelCase function to addi_eeprom_nvram_wait(). Rename the CamelCase local variable. Refactor the do {} while to make the code a bit more concise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 33 +++++++--------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index a96cfea9714..d95cac95929 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -179,14 +179,13 @@ static unsigned short addi_eeprom_readw_93c76(unsigned long iobase, return val; } -static void v_EepromWaitBusy(unsigned long iobase) +static void addi_eeprom_nvram_wait(unsigned long iobase) { - unsigned char b_EepromBusy = 0; + unsigned char val; do { - b_EepromBusy = inb(iobase + 0x3F); - b_EepromBusy = b_EepromBusy & 0x80; - } while (b_EepromBusy == 0x80); + val = inb(iobase + 0x3F); + } while (val & 0x80); } static unsigned short w_EepromReadWord(unsigned long iobase, @@ -210,39 +209,27 @@ static unsigned short w_EepromReadWord(unsigned long iobase, /* Select the load low address mode */ outb(NVCMD_LOAD_LOW, iobase + 0x3F); - - /* Wait on busy */ - v_EepromWaitBusy(iobase); + addi_eeprom_nvram_wait(iobase); /* Load the low address */ outb(b_SelectedAddressLow, iobase + 0x3E); - - /* Wait on busy */ - v_EepromWaitBusy(iobase); + addi_eeprom_nvram_wait(iobase); /* Select the load high address mode */ outb(NVCMD_LOAD_HIGH, iobase + 0x3F); - - /* Wait on busy */ - v_EepromWaitBusy(iobase); + addi_eeprom_nvram_wait(iobase); /* Load the high address */ outb(b_SelectedAddressHigh, iobase + 0x3E); - - /* Wait on busy */ - v_EepromWaitBusy(iobase); + addi_eeprom_nvram_wait(iobase); /* Select the READ mode */ outb(NVCMD_BEGIN_READ, iobase + 0x3F); - - /* Wait on busy */ - v_EepromWaitBusy(iobase); + addi_eeprom_nvram_wait(iobase); /* Read data into the EEPROM */ b_ReadByte = inb(iobase + 0x3E); - - /* Wait on busy */ - v_EepromWaitBusy(iobase); + addi_eeprom_nvram_wait(iobase); /* Select the upper address part */ if (b_Counter == 0) -- cgit v1.2.3 From fc272e0042cae8c13d3484998811309af1a4b11b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:06:14 -0700 Subject: staging: comedi: addi_eeprom: factor out the nvram read code Factor the code that reads the word from the nvram out of the w_EepromReadWord() function. Cleanup the factored out code so it's a bit more concise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 86 ++++++++++------------ 1 file changed, 37 insertions(+), 49 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index d95cac95929..f3170e90c5f 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -188,62 +188,50 @@ static void addi_eeprom_nvram_wait(unsigned long iobase) } while (val & 0x80); } +static unsigned short addi_eeprom_readw_nvram(unsigned long iobase, + unsigned short addr) +{ + unsigned short val = 0; + unsigned char tmp; + unsigned char i; + + for (i = 0; i < 2; i++) { + /* Load the low 8 bit address */ + outb(NVCMD_LOAD_LOW, iobase + 0x3F); + addi_eeprom_nvram_wait(iobase); + outb((addr + i) & 0xff, iobase + 0x3E); + addi_eeprom_nvram_wait(iobase); + + /* Load the high 8 bit address */ + outb(NVCMD_LOAD_HIGH, iobase + 0x3F); + addi_eeprom_nvram_wait(iobase); + outb(((addr + i) >> 8) & 0xff, iobase + 0x3E); + addi_eeprom_nvram_wait(iobase); + + /* Read the eeprom data byte */ + outb(NVCMD_BEGIN_READ, iobase + 0x3F); + addi_eeprom_nvram_wait(iobase); + tmp = inb(iobase + 0x3E); + addi_eeprom_nvram_wait(iobase); + + if (i == 0) + val |= tmp; + else + val |= (tmp << 8); + } + + return val; +} + static unsigned short w_EepromReadWord(unsigned long iobase, char *type, unsigned short w_EepromStartAddress) { - unsigned char b_Counter = 0; - unsigned char b_ReadByte = 0; - unsigned char b_ReadLowByte = 0; - unsigned char b_ReadHighByte = 0; - unsigned char b_SelectedAddressLow = 0; - unsigned char b_SelectedAddressHigh = 0; unsigned short w_ReadWord = 0; /* Test the PCI chip type */ - if (!strcmp(type, "S5920") || !strcmp(type, "S5933")) { - for (b_Counter = 0; b_Counter < 2; b_Counter++) - { - b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256; /* Read the low 8 bit part */ - b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256; /* Read the high 8 bit part */ - - /* Select the load low address mode */ - outb(NVCMD_LOAD_LOW, iobase + 0x3F); - addi_eeprom_nvram_wait(iobase); - - /* Load the low address */ - outb(b_SelectedAddressLow, iobase + 0x3E); - addi_eeprom_nvram_wait(iobase); - - /* Select the load high address mode */ - outb(NVCMD_LOAD_HIGH, iobase + 0x3F); - addi_eeprom_nvram_wait(iobase); - - /* Load the high address */ - outb(b_SelectedAddressHigh, iobase + 0x3E); - addi_eeprom_nvram_wait(iobase); - - /* Select the READ mode */ - outb(NVCMD_BEGIN_READ, iobase + 0x3F); - addi_eeprom_nvram_wait(iobase); - - /* Read data into the EEPROM */ - b_ReadByte = inb(iobase + 0x3E); - addi_eeprom_nvram_wait(iobase); - - /* Select the upper address part */ - if (b_Counter == 0) - { - b_ReadLowByte = b_ReadByte; - } /* if(b_Counter==0) */ - else - { - b_ReadHighByte = b_ReadByte; - } /* if(b_Counter==0) */ - } /* for (b_Counter=0; b_Counter<2; b_Counter++) */ - - w_ReadWord = (b_ReadLowByte | (((unsigned short) b_ReadHighByte) * 256)); - } + if (!strcmp(type, "S5920") || !strcmp(type, "S5933")) + w_ReadWord = addi_eeprom_readw_nvram(iobase, w_EepromStartAddress); if (!strcmp(type, "93C76")) w_ReadWord = addi_eeprom_readw_93c76(iobase, w_EepromStartAddress); -- cgit v1.2.3 From ed4d2b265ed56fb2b182a3bbd051bc3db42c0ae0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:06:42 -0700 Subject: staging: comedi: addi_eeprom: use AMCC_OP_REG_* defines Use the AMCC_OP_REG_* register offset defines for the magic numbers used to read the nvram data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_eeprom.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index f3170e90c5f..6c282ec95c1 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -184,7 +184,7 @@ static void addi_eeprom_nvram_wait(unsigned long iobase) unsigned char val; do { - val = inb(iobase + 0x3F); + val = inb(iobase + AMCC_OP_REG_MCSR_NVCMD); } while (val & 0x80); } @@ -197,21 +197,21 @@ static unsigned short addi_eeprom_readw_nvram(unsigned long iobase, for (i = 0; i < 2; i++) { /* Load the low 8 bit address */ - outb(NVCMD_LOAD_LOW, iobase + 0x3F); + outb(NVCMD_LOAD_LOW, iobase + AMCC_OP_REG_MCSR_NVCMD); addi_eeprom_nvram_wait(iobase); - outb((addr + i) & 0xff, iobase + 0x3E); + outb((addr + i) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); addi_eeprom_nvram_wait(iobase); /* Load the high 8 bit address */ - outb(NVCMD_LOAD_HIGH, iobase + 0x3F); + outb(NVCMD_LOAD_HIGH, iobase + AMCC_OP_REG_MCSR_NVCMD); addi_eeprom_nvram_wait(iobase); - outb(((addr + i) >> 8) & 0xff, iobase + 0x3E); + outb(((addr + i) >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); addi_eeprom_nvram_wait(iobase); /* Read the eeprom data byte */ - outb(NVCMD_BEGIN_READ, iobase + 0x3F); + outb(NVCMD_BEGIN_READ, iobase + AMCC_OP_REG_MCSR_NVCMD); addi_eeprom_nvram_wait(iobase); - tmp = inb(iobase + 0x3E); + tmp = inb(iobase + AMCC_OP_REG_MCSR_NVDATA); addi_eeprom_nvram_wait(iobase); if (i == 0) -- cgit v1.2.3 From 66be78f6883ad7472789d19530b2282c8737ead4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:06:57 -0700 Subject: staging: comedi: addi_eeprom: cleanup v_EepromReadWord() Add namespace to the function by renaming the CamelCase function to addi_eeprom_readw(). Rename the CamelCase parameters and local variables. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 2 +- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 95 +++++++++++----------- 2 files changed, 48 insertions(+), 49 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 05a01e1c6f3..c77e7729621 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -60,7 +60,7 @@ static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, unsigned short w_Address = CR_CHAN(insn->chanspec); unsigned short w_Data; - w_Data = w_EepromReadWord(devpriv->i_IobaseAmcc, + w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, this_board->pc_EepromChip, 0x100 + (2 * w_Address)); data[0] = w_Data; diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 6c282ec95c1..14cbafd6e67 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -223,20 +223,19 @@ static unsigned short addi_eeprom_readw_nvram(unsigned long iobase, return val; } -static unsigned short w_EepromReadWord(unsigned long iobase, - char *type, - unsigned short w_EepromStartAddress) +static unsigned short addi_eeprom_readw(unsigned long iobase, + char *type, + unsigned short addr) { - unsigned short w_ReadWord = 0; + unsigned short val = 0; - /* Test the PCI chip type */ if (!strcmp(type, "S5920") || !strcmp(type, "S5933")) - w_ReadWord = addi_eeprom_readw_nvram(iobase, w_EepromStartAddress); + val = addi_eeprom_readw_nvram(iobase, addr); if (!strcmp(type, "93C76")) - w_ReadWord = addi_eeprom_readw_93c76(iobase, w_EepromStartAddress); + val = addi_eeprom_readw_93c76(iobase, addr); - return w_ReadWord; + return val; } static int i_EepromReadDigitalInputHeader(unsigned long iobase, @@ -247,17 +246,17 @@ static int i_EepromReadDigitalInputHeader(unsigned long iobase, unsigned short w_Temp; /* read nbr of channels */ - s_Header->w_Nchannel = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 6); + s_Header->w_Nchannel = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 6); /* interruptible or not */ - w_Temp = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 8); + w_Temp = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 8); s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01; /* How many interruptible logic */ - s_Header->w_NinterruptLogic = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 10); + s_Header->w_NinterruptLogic = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 10); return 0; } @@ -268,8 +267,8 @@ static int i_EepromReadDigitalOutputHeader(unsigned long iobase, struct str_DigitalOutputHeader *s_Header) { /* Read Nbr channels */ - s_Header->w_Nchannel = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 6); + s_Header->w_Nchannel = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 6); return 0; } @@ -283,15 +282,15 @@ static int i_EepromReadTimerHeader(unsigned long iobase, unsigned short i, w_Size = 0, w_Temp; /* Read No of Timer */ - s_Header->w_Ntimer = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 6); + s_Header->w_Ntimer = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 6); /* Read header size */ for (i = 0; i < s_Header->w_Ntimer; i++) { s_Header->s_TimerDetails[i].w_HeaderSize = - w_EepromReadWord(iobase, type, - 0x100 + w_Address + 8 + w_Size + 0); - w_Temp = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 8 + w_Size + 2); + addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 8 + w_Size + 0); + w_Temp = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 8 + w_Size + 2); /* Read Resolution */ s_Header->s_TimerDetails[i].b_Resolution = @@ -301,8 +300,8 @@ static int i_EepromReadTimerHeader(unsigned long iobase, s_Header->s_TimerDetails[i].b_Mode = (unsigned char) (w_Temp >> 4) & 0x3F; - w_Temp = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 8 + w_Size + 4); + w_Temp = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 8 + w_Size + 4); /* Read MinTiming */ s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF; @@ -324,12 +323,12 @@ static int i_EepromReadAnlogOutputHeader(unsigned long iobase, unsigned short w_Temp; /* No of channels for 1st hard component */ - w_Temp = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 10); + w_Temp = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 10); s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; /* Resolution for 1st hard component */ - w_Temp = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 16); + w_Temp = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 16); s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF; return 0; } @@ -341,19 +340,19 @@ static int i_EepromReadAnlogInputHeader(unsigned long iobase, struct str_AnalogInputHeader *s_Header) { unsigned short w_Temp, w_Offset; - w_Temp = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 10); + w_Temp = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 10); s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; - s_Header->w_MinConvertTiming = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 16); - s_Header->w_MinDelayTiming = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 30); - w_Temp = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 20); + s_Header->w_MinConvertTiming = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 16); + s_Header->w_MinDelayTiming = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 30); + w_Temp = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 20); s_Header->b_HasDma = (w_Temp >> 13) & 0x01; /* whether dma present or not */ - w_Temp = w_EepromReadWord(iobase, type, - 0x100 + w_Address + 72); /* reading Y */ + w_Temp = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + 72); /* reading Y */ w_Temp = w_Temp & 0x00FF; if (w_Temp) /* Y>0 */ { @@ -366,8 +365,8 @@ static int i_EepromReadAnlogInputHeader(unsigned long iobase, } /* read Resolution */ - w_Temp = w_EepromReadWord(iobase, type, - 0x100 + w_Address + w_Offset); + w_Temp = addi_eeprom_readw(iobase, type, + 0x100 + w_Address + w_Offset); s_Header->b_Resolution = w_Temp & 0x001F; /* last 5 bits */ return 0; @@ -389,25 +388,25 @@ static int i_EepromReadMainHeader(unsigned long iobase, struct str_AnalogInputHeader s_AnalogInputHeader; /* Read size */ - s_MainHeader.w_HeaderSize = w_EepromReadWord(iobase, type, - 0x100 + 8); + s_MainHeader.w_HeaderSize = addi_eeprom_readw(iobase, type, + 0x100 + 8); /* Read nbr of functionality */ - w_Temp = w_EepromReadWord(iobase, type, - 0x100 + 10); + w_Temp = addi_eeprom_readw(iobase, type, + 0x100 + 10); s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF; /* Read functionality details */ for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { /* Read Type */ - w_Temp = w_EepromReadWord(iobase, type, - 0x100 + 12 + w_Count); + w_Temp = addi_eeprom_readw(iobase, type, + 0x100 + 12 + w_Count); s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F; w_Count = w_Count + 2; /* Read Address */ s_MainHeader.s_Functions[i].w_Address = - w_EepromReadWord(iobase, type, - 0x100 + 12 + w_Count); + addi_eeprom_readw(iobase, type, + 0x100 + 12 + w_Count); w_Count = w_Count + 2; } -- cgit v1.2.3 From 85c1dcbab4d002e1d6c537d88558bb20326d507d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:07:11 -0700 Subject: staging: comedi: addi_eeprom: move the eeprom offset to addi_eeprom_readw() All the addi_eeprom_readw() calls have the offset to the start of user data (0x100) as part of the address calculation. Create a define for this constant and move it's addition to the address into addi_eeprom_readw(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 2 +- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 57 ++++++++++------------ 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index c77e7729621..9064293c51f 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -61,7 +61,7 @@ static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, unsigned short w_Data; w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, - this_board->pc_EepromChip, 0x100 + (2 * w_Address)); + this_board->pc_EepromChip, 2 * w_Address); data[0] = w_Data; return insn->n; diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 14cbafd6e67..3ea83195437 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -45,6 +45,8 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ +#define NVRAM_USER_DATA_START 0x100 + #define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ #define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ #define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ @@ -229,6 +231,9 @@ static unsigned short addi_eeprom_readw(unsigned long iobase, { unsigned short val = 0; + /* Add the offset to the start of the user data */ + addr += NVRAM_USER_DATA_START; + if (!strcmp(type, "S5920") || !strcmp(type, "S5933")) val = addi_eeprom_readw_nvram(iobase, addr); @@ -246,17 +251,15 @@ static int i_EepromReadDigitalInputHeader(unsigned long iobase, unsigned short w_Temp; /* read nbr of channels */ - s_Header->w_Nchannel = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 6); + s_Header->w_Nchannel = addi_eeprom_readw(iobase, type, w_Address + 6); /* interruptible or not */ - w_Temp = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 8); + w_Temp = addi_eeprom_readw(iobase, type, w_Address + 8); s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01; /* How many interruptible logic */ s_Header->w_NinterruptLogic = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 10); + w_Address + 10); return 0; } @@ -268,7 +271,7 @@ static int i_EepromReadDigitalOutputHeader(unsigned long iobase, { /* Read Nbr channels */ s_Header->w_Nchannel = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 6); + w_Address + 6); return 0; } @@ -283,14 +286,14 @@ static int i_EepromReadTimerHeader(unsigned long iobase, /* Read No of Timer */ s_Header->w_Ntimer = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 6); + w_Address + 6); /* Read header size */ for (i = 0; i < s_Header->w_Ntimer; i++) { s_Header->s_TimerDetails[i].w_HeaderSize = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 8 + w_Size + 0); + w_Address + 8 + w_Size + 0); w_Temp = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 8 + w_Size + 2); + w_Address + 8 + w_Size + 2); /* Read Resolution */ s_Header->s_TimerDetails[i].b_Resolution = @@ -301,7 +304,7 @@ static int i_EepromReadTimerHeader(unsigned long iobase, (unsigned char) (w_Temp >> 4) & 0x3F; w_Temp = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 8 + w_Size + 4); + w_Address + 8 + w_Size + 4); /* Read MinTiming */ s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF; @@ -323,12 +326,10 @@ static int i_EepromReadAnlogOutputHeader(unsigned long iobase, unsigned short w_Temp; /* No of channels for 1st hard component */ - w_Temp = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 10); + w_Temp = addi_eeprom_readw(iobase, type, w_Address + 10); s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; /* Resolution for 1st hard component */ - w_Temp = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 16); + w_Temp = addi_eeprom_readw(iobase, type, w_Address + 16); s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF; return 0; } @@ -340,19 +341,18 @@ static int i_EepromReadAnlogInputHeader(unsigned long iobase, struct str_AnalogInputHeader *s_Header) { unsigned short w_Temp, w_Offset; - w_Temp = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 10); + w_Temp = addi_eeprom_readw(iobase, type, w_Address + 10); s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; s_Header->w_MinConvertTiming = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 16); + w_Address + 16); s_Header->w_MinDelayTiming = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 30); + w_Address + 30); w_Temp = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 20); + w_Address + 20); s_Header->b_HasDma = (w_Temp >> 13) & 0x01; /* whether dma present or not */ - w_Temp = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + 72); /* reading Y */ + /* reading Y */ + w_Temp = addi_eeprom_readw(iobase, type, w_Address + 72); w_Temp = w_Temp & 0x00FF; if (w_Temp) /* Y>0 */ { @@ -365,8 +365,7 @@ static int i_EepromReadAnlogInputHeader(unsigned long iobase, } /* read Resolution */ - w_Temp = addi_eeprom_readw(iobase, type, - 0x100 + w_Address + w_Offset); + w_Temp = addi_eeprom_readw(iobase, type, w_Address + w_Offset); s_Header->b_Resolution = w_Temp & 0x001F; /* last 5 bits */ return 0; @@ -388,25 +387,21 @@ static int i_EepromReadMainHeader(unsigned long iobase, struct str_AnalogInputHeader s_AnalogInputHeader; /* Read size */ - s_MainHeader.w_HeaderSize = addi_eeprom_readw(iobase, type, - 0x100 + 8); + s_MainHeader.w_HeaderSize = addi_eeprom_readw(iobase, type, 8); /* Read nbr of functionality */ - w_Temp = addi_eeprom_readw(iobase, type, - 0x100 + 10); + w_Temp = addi_eeprom_readw(iobase, type, 10); s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF; /* Read functionality details */ for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { /* Read Type */ - w_Temp = addi_eeprom_readw(iobase, type, - 0x100 + 12 + w_Count); + w_Temp = addi_eeprom_readw(iobase, type, 12 + w_Count); s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F; w_Count = w_Count + 2; /* Read Address */ s_MainHeader.s_Functions[i].w_Address = - addi_eeprom_readw(iobase, type, - 0x100 + 12 + w_Count); + addi_eeprom_readw(iobase, type, 12 + w_Count); w_Count = w_Count + 2; } -- cgit v1.2.3 From 7cd25bf08c2bc4794b026feea0230b9caf787744 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:07:30 -0700 Subject: staging: comedi: addi_eeprom: cleanup i_EepromReadMainHeader() Consolidate the two loops used to read the main header data and the individual function header data from the eeprom. The structs used to read the main header are not used outside this function so remove them by reading the eeprom data into local variables used in the loop. Consolidate the 'timer' function cases. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 76 +++++++--------------- 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 3ea83195437..529f9b1341c 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -66,17 +66,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define EEPROM_WATCHDOG 5 #define EEPROM_TIMER_WATCHDOG_COUNTER 10 -struct str_Functionality { - unsigned char b_Type; - unsigned short w_Address; -}; - -struct str_MainHeader { - unsigned short w_HeaderSize; - unsigned char b_Nfunctions; - struct str_Functionality s_Functions[7]; -}; - struct str_DigitalInputHeader { unsigned short w_Nchannel; unsigned char b_Interruptible; @@ -377,50 +366,41 @@ static int i_EepromReadMainHeader(unsigned long iobase, { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; - unsigned short w_Temp, i, w_Count = 0; unsigned int ui_Temp; - struct str_MainHeader s_MainHeader; struct str_DigitalInputHeader s_DigitalInputHeader; struct str_DigitalOutputHeader s_DigitalOutputHeader; /* struct str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; */ struct str_AnalogOutputHeader s_AnalogOutputHeader; struct str_AnalogInputHeader s_AnalogInputHeader; + unsigned short size; + unsigned char nfuncs; + int i; - /* Read size */ - s_MainHeader.w_HeaderSize = addi_eeprom_readw(iobase, type, 8); - - /* Read nbr of functionality */ - w_Temp = addi_eeprom_readw(iobase, type, 10); - s_MainHeader.b_Nfunctions = (unsigned char) w_Temp & 0x00FF; + size = addi_eeprom_readw(iobase, type, 8); + nfuncs = addi_eeprom_readw(iobase, type, 10) & 0xff; /* Read functionality details */ - for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { - /* Read Type */ - w_Temp = addi_eeprom_readw(iobase, type, 12 + w_Count); - s_MainHeader.s_Functions[i].b_Type = (unsigned char) w_Temp & 0x3F; - w_Count = w_Count + 2; - /* Read Address */ - s_MainHeader.s_Functions[i].w_Address = - addi_eeprom_readw(iobase, type, 12 + w_Count); - w_Count = w_Count + 2; - } + for (i = 0; i < nfuncs; i++) { + unsigned short offset = i * 4; + unsigned short addr; + unsigned char func; - /* Display main header info */ - for (i = 0; i < s_MainHeader.b_Nfunctions; i++) { + func = addi_eeprom_readw(iobase, type, 12 + offset) & 0x3f; + addr = addi_eeprom_readw(iobase, type, 14 + offset); - switch (s_MainHeader.s_Functions[i].b_Type) { + switch (func) { case EEPROM_DIGITALINPUT: - i_EepromReadDigitalInputHeader(iobase, type, - s_MainHeader.s_Functions[i].w_Address, - &s_DigitalInputHeader); + i_EepromReadDigitalInputHeader(iobase, type, addr, + &s_DigitalInputHeader); + devpriv->s_EeParameters.i_NbrDiChannel = s_DigitalInputHeader.w_Nchannel; break; case EEPROM_DIGITALOUTPUT: - i_EepromReadDigitalOutputHeader(iobase, type, - s_MainHeader.s_Functions[i].w_Address, - &s_DigitalOutputHeader); + i_EepromReadDigitalOutputHeader(iobase, type, addr, + &s_DigitalOutputHeader); + devpriv->s_EeParameters.i_NbrDoChannel = s_DigitalOutputHeader.w_Nchannel; ui_Temp = 0xffffffff; @@ -430,9 +410,9 @@ static int i_EepromReadMainHeader(unsigned long iobase, break; case EEPROM_ANALOGINPUT: - i_EepromReadAnlogInputHeader(iobase, type, - s_MainHeader.s_Functions[i].w_Address, - &s_AnalogInputHeader); + i_EepromReadAnlogInputHeader(iobase, type, addr, + &s_AnalogInputHeader); + if (!(strcmp(this_board->pc_DriverName, "apci3200"))) devpriv->s_EeParameters.i_NbrAiChannel = s_AnalogInputHeader.w_Nchannel * 4; @@ -454,9 +434,9 @@ static int i_EepromReadMainHeader(unsigned long iobase, break; case EEPROM_ANALOGOUTPUT: - i_EepromReadAnlogOutputHeader(iobase, type, - s_MainHeader.s_Functions[i].w_Address, - &s_AnalogOutputHeader); + i_EepromReadAnlogOutputHeader(iobase, type, addr, + &s_AnalogOutputHeader); + devpriv->s_EeParameters.i_NbrAoChannel = s_AnalogOutputHeader.w_Nchannel; ui_Temp = 0xffff; @@ -466,15 +446,7 @@ static int i_EepromReadMainHeader(unsigned long iobase, break; case EEPROM_TIMER: - /* Timer subdevice present */ - devpriv->s_EeParameters.i_Timer = 1; - break; - case EEPROM_WATCHDOG: - /* Timer subdevice present */ - devpriv->s_EeParameters.i_Timer = 1; - break; - case EEPROM_TIMER_WATCHDOG_COUNTER: /* Timer subdevice present */ devpriv->s_EeParameters.i_Timer = 1; -- cgit v1.2.3 From ef4e05f0c881a8a1152ac6f2e24ed0bccc41d045 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:07:45 -0700 Subject: staging: comedi: addi_eeprom: cleanup i_EepromReadDigitalInputHeader() Add namespace by renaming this CamelCase function to addi_eeprom_read_di_info(). Refactor the function so that it stores the data from the eeprom directly in the private data instead of using the a struct to pass the data back to i_EepromReadMainHeader(). This allows removing the str_DigitalInputHeader struct. Leave the reads of the unused eeprom data for now. The return value is always 0 and it's never checked. Change it to void. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 40 ++++++++-------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 529f9b1341c..438968c261f 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -66,12 +66,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define EEPROM_WATCHDOG 5 #define EEPROM_TIMER_WATCHDOG_COUNTER 10 -struct str_DigitalInputHeader { - unsigned short w_Nchannel; - unsigned char b_Interruptible; - unsigned short w_NinterruptLogic; -}; - struct str_DigitalOutputHeader { unsigned short w_Nchannel; }; @@ -232,25 +226,24 @@ static unsigned short addi_eeprom_readw(unsigned long iobase, return val; } -static int i_EepromReadDigitalInputHeader(unsigned long iobase, - char *type, - unsigned short w_Address, - struct str_DigitalInputHeader *s_Header) +static void addi_eeprom_read_di_info(struct comedi_device *dev, + unsigned long iobase, + char *type, + unsigned short addr) { - unsigned short w_Temp; + struct addi_private *devpriv = dev->private; + unsigned short tmp; - /* read nbr of channels */ - s_Header->w_Nchannel = addi_eeprom_readw(iobase, type, w_Address + 6); + /* Number of channels */ + tmp = addi_eeprom_readw(iobase, type, addr + 6); + devpriv->s_EeParameters.i_NbrDiChannel = tmp; - /* interruptible or not */ - w_Temp = addi_eeprom_readw(iobase, type, w_Address + 8); - s_Header->b_Interruptible = (unsigned char) (w_Temp >> 7) & 0x01; + /* Interruptible or not */ + tmp = addi_eeprom_readw(iobase, type, addr + 8); + tmp = (tmp >> 7) & 0x01; /* How many interruptible logic */ - s_Header->w_NinterruptLogic = addi_eeprom_readw(iobase, type, - w_Address + 10); - - return 0; + tmp = addi_eeprom_readw(iobase, type, addr + 10); } static int i_EepromReadDigitalOutputHeader(unsigned long iobase, @@ -367,7 +360,6 @@ static int i_EepromReadMainHeader(unsigned long iobase, const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; unsigned int ui_Temp; - struct str_DigitalInputHeader s_DigitalInputHeader; struct str_DigitalOutputHeader s_DigitalOutputHeader; /* struct str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; */ struct str_AnalogOutputHeader s_AnalogOutputHeader; @@ -390,11 +382,7 @@ static int i_EepromReadMainHeader(unsigned long iobase, switch (func) { case EEPROM_DIGITALINPUT: - i_EepromReadDigitalInputHeader(iobase, type, addr, - &s_DigitalInputHeader); - - devpriv->s_EeParameters.i_NbrDiChannel = - s_DigitalInputHeader.w_Nchannel; + addi_eeprom_read_di_info(dev, iobase, type, addr); break; case EEPROM_DIGITALOUTPUT: -- cgit v1.2.3 From 7e8ab68fa82904b8de8caee9007d9208642d50f7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:08:00 -0700 Subject: staging: comedi: addi_eeprom: cleanup i_EepromReadDigitalOutputHeader() Add namespace by renaming this CamelCase function to addi_eeprom_read_do_info(). Refactor the function so that it stores the data from the eeprom directly in the private data instead of using the a struct to pass the data back to i_EepromReadMainHeader(). This allows removing the str_DigitalOutputHeader struct. The return value is always 0 and it's never checked. Change it to void. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 35 ++++++++-------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 438968c261f..b5f42ec2e71 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -66,10 +66,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define EEPROM_WATCHDOG 5 #define EEPROM_TIMER_WATCHDOG_COUNTER 10 -struct str_DigitalOutputHeader { - unsigned short w_Nchannel; -}; - /* used for timer as well as watchdog */ struct str_TimerDetails { unsigned short w_HeaderSize; @@ -246,15 +242,19 @@ static void addi_eeprom_read_di_info(struct comedi_device *dev, tmp = addi_eeprom_readw(iobase, type, addr + 10); } -static int i_EepromReadDigitalOutputHeader(unsigned long iobase, - char *type, - unsigned short w_Address, - struct str_DigitalOutputHeader *s_Header) +static void addi_eeprom_read_do_info(struct comedi_device *dev, + unsigned long iobase, + char *type, + unsigned short addr) { - /* Read Nbr channels */ - s_Header->w_Nchannel = addi_eeprom_readw(iobase, type, - w_Address + 6); - return 0; + struct addi_private *devpriv = dev->private; + unsigned short tmp; + + /* Number of channels */ + tmp = addi_eeprom_readw(iobase, type, addr + 6); + devpriv->s_EeParameters.i_NbrDoChannel = tmp; + + devpriv->s_EeParameters.i_DoMaxdata = 0xffffffff >> (32 - tmp); } #if 0 @@ -360,7 +360,6 @@ static int i_EepromReadMainHeader(unsigned long iobase, const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; unsigned int ui_Temp; - struct str_DigitalOutputHeader s_DigitalOutputHeader; /* struct str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; */ struct str_AnalogOutputHeader s_AnalogOutputHeader; struct str_AnalogInputHeader s_AnalogInputHeader; @@ -386,15 +385,7 @@ static int i_EepromReadMainHeader(unsigned long iobase, break; case EEPROM_DIGITALOUTPUT: - i_EepromReadDigitalOutputHeader(iobase, type, addr, - &s_DigitalOutputHeader); - - devpriv->s_EeParameters.i_NbrDoChannel = - s_DigitalOutputHeader.w_Nchannel; - ui_Temp = 0xffffffff; - devpriv->s_EeParameters.i_DoMaxdata = - ui_Temp >> (32 - - devpriv->s_EeParameters.i_NbrDoChannel); + addi_eeprom_read_do_info(dev, iobase, type, addr); break; case EEPROM_ANALOGINPUT: -- cgit v1.2.3 From 6dbae1ff729018a140a2fd7c3352a90597dafae0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:08:17 -0700 Subject: staging: comedi: addi_eeprom: cleanup i_EepromReadAnlogOutputHeader() Add namespace by renaming this CamelCase function to addi_eeprom_read_ao_info(). Refactor the function so that it stores the data from the eeprom directly in the private data instead of using the a struct to pass the data back to i_EepromReadMainHeader(). This allows removing the str_AnalogOutputHeader struct. The return value is always 0 and it's never checked. Change it to void. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 42 ++++++++-------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index b5f42ec2e71..5c35619ab20 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -80,11 +80,6 @@ struct str_TimerMainHeader { struct str_TimerDetails s_TimerDetails[4]; /* supports 4 timers */ }; -struct str_AnalogOutputHeader { - unsigned short w_Nchannel; - unsigned char b_Resolution; -}; - struct str_AnalogInputHeader { unsigned short w_Nchannel; unsigned short w_MinConvertTiming; @@ -300,20 +295,22 @@ static int i_EepromReadTimerHeader(unsigned long iobase, } #endif -static int i_EepromReadAnlogOutputHeader(unsigned long iobase, - char *type, - unsigned short w_Address, - struct str_AnalogOutputHeader *s_Header) +static void addi_eeprom_read_ao_info(struct comedi_device *dev, + unsigned long iobase, + char *type, + unsigned short addr) { - unsigned short w_Temp; + struct addi_private *devpriv = dev->private; + unsigned short tmp; - /* No of channels for 1st hard component */ - w_Temp = addi_eeprom_readw(iobase, type, w_Address + 10); - s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; - /* Resolution for 1st hard component */ - w_Temp = addi_eeprom_readw(iobase, type, w_Address + 16); - s_Header->b_Resolution = (unsigned char) (w_Temp >> 8) & 0xFF; - return 0; + /* No of channels for 1st hard component */ + tmp = addi_eeprom_readw(iobase, type, addr + 10); + devpriv->s_EeParameters.i_NbrAoChannel = (tmp >> 4) & 0x3ff; + + /* Resolution for 1st hard component */ + tmp = addi_eeprom_readw(iobase, type, addr + 16); + tmp = (tmp >> 8) & 0xff; + devpriv->s_EeParameters.i_AoMaxdata = 0xfff >> (16 - tmp); } /* Reads only for ONE hardware component */ @@ -361,7 +358,6 @@ static int i_EepromReadMainHeader(unsigned long iobase, struct addi_private *devpriv = dev->private; unsigned int ui_Temp; /* struct str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; */ - struct str_AnalogOutputHeader s_AnalogOutputHeader; struct str_AnalogInputHeader s_AnalogInputHeader; unsigned short size; unsigned char nfuncs; @@ -413,15 +409,7 @@ static int i_EepromReadMainHeader(unsigned long iobase, break; case EEPROM_ANALOGOUTPUT: - i_EepromReadAnlogOutputHeader(iobase, type, addr, - &s_AnalogOutputHeader); - - devpriv->s_EeParameters.i_NbrAoChannel = - s_AnalogOutputHeader.w_Nchannel; - ui_Temp = 0xffff; - devpriv->s_EeParameters.i_AoMaxdata = - ui_Temp >> (16 - - s_AnalogOutputHeader.b_Resolution); + addi_eeprom_read_ao_info(dev, iobase, type, addr); break; case EEPROM_TIMER: -- cgit v1.2.3 From 2f3da417aaaa470e714ca35e7ee1551ed70cffc5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:08:40 -0700 Subject: staging: comedi: addi_eeprom: cleanup i_EepromReadAnlogInputHeader() Add namespace by renaming this CamelCase function to addi_eeprom_read_ai_info(). Refactor the function so that it stores the data from the eeprom directly in the private data instead of using the a struct to pass the data back to i_EepromReadMainHeader(). This allows removing the str_AnalogInputHeader struct. The return value is always 0 and it's never checked. Change it to void. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 98 ++++++++-------------- 1 file changed, 34 insertions(+), 64 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 5c35619ab20..6f9805a9d88 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -80,14 +80,6 @@ struct str_TimerMainHeader { struct str_TimerDetails s_TimerDetails[4]; /* supports 4 timers */ }; -struct str_AnalogInputHeader { - unsigned short w_Nchannel; - unsigned short w_MinConvertTiming; - unsigned short w_MinDelayTiming; - unsigned char b_HasDma; - unsigned char b_Resolution; -}; - static void addi_eeprom_clk_93c76(unsigned long iobase, unsigned int val) { outl(val & ~EE93C76_CLK_BIT, iobase); @@ -313,52 +305,50 @@ static void addi_eeprom_read_ao_info(struct comedi_device *dev, devpriv->s_EeParameters.i_AoMaxdata = 0xfff >> (16 - tmp); } -/* Reads only for ONE hardware component */ -static int i_EepromReadAnlogInputHeader(unsigned long iobase, - char *type, - unsigned short w_Address, - struct str_AnalogInputHeader *s_Header) +static void addi_eeprom_read_ai_info(struct comedi_device *dev, + unsigned long iobase, + char *type, + unsigned short addr) { - unsigned short w_Temp, w_Offset; - w_Temp = addi_eeprom_readw(iobase, type, w_Address + 10); - s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF; - s_Header->w_MinConvertTiming = addi_eeprom_readw(iobase, type, - w_Address + 16); - s_Header->w_MinDelayTiming = addi_eeprom_readw(iobase, type, - w_Address + 30); - w_Temp = addi_eeprom_readw(iobase, type, - w_Address + 20); - s_Header->b_HasDma = (w_Temp >> 13) & 0x01; /* whether dma present or not */ - - /* reading Y */ - w_Temp = addi_eeprom_readw(iobase, type, w_Address + 72); - w_Temp = w_Temp & 0x00FF; - if (w_Temp) /* Y>0 */ - { - w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16))); /* offset of first analog input single header */ - w_Offset = w_Offset + 2; /* resolution */ - } else /* Y=0 */ - { - w_Offset = 74; - w_Offset = w_Offset + 2; /* resolution */ - } + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; + unsigned short offset; + unsigned short tmp; - /* read Resolution */ - w_Temp = addi_eeprom_readw(iobase, type, w_Address + w_Offset); - s_Header->b_Resolution = w_Temp & 0x001F; /* last 5 bits */ + /* No of channels for 1st hard component */ + tmp = addi_eeprom_readw(iobase, type, addr + 10); + devpriv->s_EeParameters.i_NbrAiChannel = (tmp >> 4) & 0x3ff; + if (!strcmp(this_board->pc_DriverName, "apci3200")) + devpriv->s_EeParameters.i_NbrAiChannel *= 4; - return 0; + tmp = addi_eeprom_readw(iobase, type, addr + 16); + devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = tmp * 1000; + + tmp = addi_eeprom_readw(iobase, type, addr + 30); + devpriv->s_EeParameters.ui_MinDelaytimeNs = tmp * 1000; + + tmp = addi_eeprom_readw(iobase, type, addr + 20); + devpriv->s_EeParameters.i_Dma = (tmp >> 13) & 0x01; + + tmp = addi_eeprom_readw(iobase, type, addr + 72) & 0xff; + if (tmp) { /* > 0 */ + /* offset of first analog input single header */ + offset = 74 + (2 * tmp) + (10 * (1 + (tmp / 16))); + } else { /* = 0 */ + offset = 74; + } + + /* Resolution */ + tmp = addi_eeprom_readw(iobase, type, addr + offset + 2) & 0x1f; + devpriv->s_EeParameters.i_AiMaxdata = 0xffff >> (16 - tmp); } static int i_EepromReadMainHeader(unsigned long iobase, char *type, struct comedi_device *dev) { - const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; - unsigned int ui_Temp; /* struct str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; */ - struct str_AnalogInputHeader s_AnalogInputHeader; unsigned short size; unsigned char nfuncs; int i; @@ -385,27 +375,7 @@ static int i_EepromReadMainHeader(unsigned long iobase, break; case EEPROM_ANALOGINPUT: - i_EepromReadAnlogInputHeader(iobase, type, addr, - &s_AnalogInputHeader); - - if (!(strcmp(this_board->pc_DriverName, "apci3200"))) - devpriv->s_EeParameters.i_NbrAiChannel = - s_AnalogInputHeader.w_Nchannel * 4; - else - devpriv->s_EeParameters.i_NbrAiChannel = - s_AnalogInputHeader.w_Nchannel; - devpriv->s_EeParameters.i_Dma = - s_AnalogInputHeader.b_HasDma; - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = - (unsigned int) s_AnalogInputHeader.w_MinConvertTiming * - 1000; - devpriv->s_EeParameters.ui_MinDelaytimeNs = - (unsigned int) s_AnalogInputHeader.w_MinDelayTiming * - 1000; - ui_Temp = 0xffff; - devpriv->s_EeParameters.i_AiMaxdata = - ui_Temp >> (16 - - s_AnalogInputHeader.b_Resolution); + addi_eeprom_read_ai_info(dev, iobase, type, addr); break; case EEPROM_ANALOGOUTPUT: -- cgit v1.2.3 From 6f98fe207bfc457d9d1d40c4573f3eec8dcb2cae Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:08:55 -0700 Subject: staging: comedi: addi_eeprom: cleanup i_EepromReadTimerHeader() Use this function to set the private data instead of doing it in the i_EepromReadMainHeader() function. Keep the eeprom read code #if 0'ed out for now. Add namespace by renaming this CamelCase function to addi_eeprom_read_timer_info(). Remove the unused str_TimerMainHeader and str_TimerDetails structs. The return value is always 0 and it's never checked. Change it to void. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 90 +++++++++------------- 1 file changed, 36 insertions(+), 54 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 6f9805a9d88..7aa67a88777 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -66,20 +66,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define EEPROM_WATCHDOG 5 #define EEPROM_TIMER_WATCHDOG_COUNTER 10 -/* used for timer as well as watchdog */ -struct str_TimerDetails { - unsigned short w_HeaderSize; - unsigned char b_Resolution; - unsigned char b_Mode; /* in case of Watchdog it is functionality */ - unsigned short w_MinTiming; - unsigned char b_TimeBase; -}; - -struct str_TimerMainHeader { - unsigned short w_Ntimer; - struct str_TimerDetails s_TimerDetails[4]; /* supports 4 timers */ -}; - static void addi_eeprom_clk_93c76(unsigned long iobase, unsigned int val) { outl(val & ~EE93C76_CLK_BIT, iobase); @@ -244,48 +230,47 @@ static void addi_eeprom_read_do_info(struct comedi_device *dev, devpriv->s_EeParameters.i_DoMaxdata = 0xffffffff >> (32 - tmp); } -#if 0 -static int i_EepromReadTimerHeader(unsigned long iobase, - char *type, - unsigned short w_Address, - struct str_TimerMainHeader *s_Header) +static void addi_eeprom_read_timer_info(struct comedi_device *dev, + unsigned long iobase, + char *type, + unsigned short addr) { + struct addi_private *devpriv = dev->private; +#if 0 + unsigned short offset = 0; + unsigned short ntimers; + unsigned short tmp; + int i; - unsigned short i, w_Size = 0, w_Temp; + /* Number of Timers */ + ntimers = addi_eeprom_readw(iobase, type, addr + 6); - /* Read No of Timer */ - s_Header->w_Ntimer = addi_eeprom_readw(iobase, type, - w_Address + 6); /* Read header size */ - for (i = 0; i < s_Header->w_Ntimer; i++) { - s_Header->s_TimerDetails[i].w_HeaderSize = - addi_eeprom_readw(iobase, type, - w_Address + 8 + w_Size + 0); - w_Temp = addi_eeprom_readw(iobase, type, - w_Address + 8 + w_Size + 2); - - /* Read Resolution */ - s_Header->s_TimerDetails[i].b_Resolution = - (unsigned char) (w_Temp >> 10) & 0x3F; - - /* Read Mode */ - s_Header->s_TimerDetails[i].b_Mode = - (unsigned char) (w_Temp >> 4) & 0x3F; - - w_Temp = addi_eeprom_readw(iobase, type, - w_Address + 8 + w_Size + 4); - - /* Read MinTiming */ - s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF; - - /* Read Timebase */ - s_Header->s_TimerDetails[i].b_TimeBase = (unsigned char) (w_Temp) & 0x3F; - w_Size += s_Header->s_TimerDetails[i].w_HeaderSize; + for (i = 0; i < ntimers; i++) { + unsigned short size; + unsigned short res; + unsigned short mode; + unsigned short min_timing; + unsigned short timebase; + + size = addi_eeprom_readw(iobase, type, addr + 8 + offset + 0); + + /* Resolution / Mode */ + tmp = addi_eeprom_readw(iobase, type, addr + 8 + offset + 2); + res = (tmp >> 10) & 0x3f; + mode = (tmp >> 4) & 0x3f; + + /* MinTiming / Timebase */ + tmp = addi_eeprom_readw(iobase, type, addr + 8 + offset + 4); + min_timing = (tmp >> 6) & 0x3ff; + Timebase = tmp & 0x3f; + + offset += size; } - - return 0; -} #endif + /* Timer subdevice present */ + devpriv->s_EeParameters.i_Timer = 1; +} static void addi_eeprom_read_ao_info(struct comedi_device *dev, unsigned long iobase, @@ -347,8 +332,6 @@ static int i_EepromReadMainHeader(unsigned long iobase, char *type, struct comedi_device *dev) { - struct addi_private *devpriv = dev->private; - /* struct str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader; */ unsigned short size; unsigned char nfuncs; int i; @@ -385,8 +368,7 @@ static int i_EepromReadMainHeader(unsigned long iobase, case EEPROM_TIMER: case EEPROM_WATCHDOG: case EEPROM_TIMER_WATCHDOG_COUNTER: - /* Timer subdevice present */ - devpriv->s_EeParameters.i_Timer = 1; + addi_eeprom_read_timer_info(dev, iobase, type, addr); break; } } -- cgit v1.2.3 From a927077c62688d1afefcda6da2a15d14a578a089 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:09:11 -0700 Subject: staging: comedi: addi_eeprom: cleanup i_EepromReadMainHeader() Add namespace by renaming this CamelCase function to addi_eeprom_read_info(). Remove the 'type' parameter. This parameter is a char pointer to the string name of the eeprom type used on the board. This can be found when needed using the dev pointer. Change the parameter order so that the comedi_device pointer is passed first. The return value is always 0 and it's never checked. Change it to void. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 3 +-- drivers/staging/comedi/drivers/addi-data/addi_eeprom.c | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 9064293c51f..79beff15d68 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -217,8 +217,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) printk("\nEnable the interrupt for the controller"); } printk("\nRead Eeprom"); - i_EepromReadMainHeader(io_addr[0], this_board->pc_EepromChip, - dev); + addi_eeprom_read_info(dev, io_addr[0]); } else { printk("\nPCI Eeprom unused"); } diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 7aa67a88777..fff04f81d92 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -328,10 +328,11 @@ static void addi_eeprom_read_ai_info(struct comedi_device *dev, devpriv->s_EeParameters.i_AiMaxdata = 0xffff >> (16 - tmp); } -static int i_EepromReadMainHeader(unsigned long iobase, - char *type, - struct comedi_device *dev) +static void addi_eeprom_read_info(struct comedi_device *dev, + unsigned long iobase) { + const struct addi_board *this_board = comedi_board(dev); + char *type = this_board->pc_EepromChip; unsigned short size; unsigned char nfuncs; int i; @@ -372,6 +373,4 @@ static int i_EepromReadMainHeader(unsigned long iobase, break; } } - - return 0; } -- cgit v1.2.3 From 9e7bdd9e683fd2a3535aca375ce0440fba53a94c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:09:25 -0700 Subject: staging: comedi: addi_eeprom: reformat driver comment Reformat the driver description comment to use the preferred block comment style. The second driver comment block contains the same information as the first one. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 74 +++++++++------------- 1 file changed, 29 insertions(+), 45 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index fff04f81d92..5440798308a 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -1,49 +1,33 @@ -/** -@verbatim - -Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - - ADDI-DATA GmbH - Dieselstrasse 3 - D-77833 Ottersweier - Tel: +19(0)7223/9493-0 - Fax: +49(0)7223/9493-92 - http://www.addi-data.com - info@addi-data.com - -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. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -You should also find the complete GPL in the COPYING file accompanying this source code. - -@endverbatim -*/ /* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-----------------------------------------------------------------------+ - | Project : ADDI DATA | Compiler : GCC | - | Modulname : addi_eeprom.c | Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-----------------------------------------------------------------------+ - | Description : ADDI EEPROM Module | - +-----------------------------------------------------------------------+ - | UPDATE'S | - +-----------------------------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | | | | - | | | | - +----------+-----------+------------------------------------------------+ -*/ + * addi_eeprom.c - ADDI EEPROM Module + * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. + * Project manager: Eric Stolz + * + * ADDI-DATA GmbH + * Dieselstrasse 3 + * D-77833 Ottersweier + * Tel: +19(0)7223/9493-0 + * Fax: +49(0)7223/9493-92 + * http://www.addi-data.com + * info@addi-data.com + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * You should also find the complete GPL in the COPYING file accompanying + * this source code. + */ #define NVRAM_USER_DATA_START 0x100 -- cgit v1.2.3 From 24f78463d58993764faba60ac22a9a637b40e746 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:09:39 -0700 Subject: staging: comedi: addi_eeprom: cleanup the defines Fix the whitespace in the defines. This also fixes a couple checkpatch.pl issues. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_eeprom.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 5440798308a..95a1974abce 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -31,9 +31,9 @@ #define NVRAM_USER_DATA_START 0x100 -#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ -#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ -#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ +#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ +#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */ +#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */ #define EE93C76_CLK_BIT (1 << 0) #define EE93C76_CS_BIT (1 << 1) @@ -42,12 +42,12 @@ #define EE93C76_READ_CMD (0x0180 << 4) #define EE93C76_CMD_LEN 13 -#define EEPROM_DIGITALINPUT 0 -#define EEPROM_DIGITALOUTPUT 1 -#define EEPROM_ANALOGINPUT 2 -#define EEPROM_ANALOGOUTPUT 3 -#define EEPROM_TIMER 4 -#define EEPROM_WATCHDOG 5 +#define EEPROM_DIGITALINPUT 0 +#define EEPROM_DIGITALOUTPUT 1 +#define EEPROM_ANALOGINPUT 2 +#define EEPROM_ANALOGOUTPUT 3 +#define EEPROM_TIMER 4 +#define EEPROM_WATCHDOG 5 #define EEPROM_TIMER_WATCHDOG_COUNTER 10 static void addi_eeprom_clk_93c76(unsigned long iobase, unsigned int val) -- cgit v1.2.3 From 14cb151d29fa0fc0ebe22f01876a4408657a0ac3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:09:54 -0700 Subject: staging: comedi: addi_eeprom: fix remaining checkpatch.pl issues Fix the following checkpatch.pl issues: ERROR: code indent should use tabs where possible WARNING: please, no spaces at the start of a line WARNING: line over 80 characters This file is now checkpatch.pl clean. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_eeprom.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 95a1974abce..68b85e2925c 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -92,7 +92,7 @@ static unsigned short addi_eeprom_readw_93c76(unsigned long iobase, unsigned short val = 0; unsigned int cmd; unsigned int tmp; - int i; + int i; /* Send EEPROM read command and offset to EEPROM */ cmd = EE93C76_READ_CMD | (addr / 2); @@ -143,7 +143,8 @@ static unsigned short addi_eeprom_readw_nvram(unsigned long iobase, /* Load the high 8 bit address */ outb(NVCMD_LOAD_HIGH, iobase + AMCC_OP_REG_MCSR_NVCMD); addi_eeprom_nvram_wait(iobase); - outb(((addr + i) >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); + outb(((addr + i) >> 8) & 0xff, + iobase + AMCC_OP_REG_MCSR_NVDATA); addi_eeprom_nvram_wait(iobase); /* Read the eeprom data byte */ -- cgit v1.2.3 From 5df28346f0fb4565f8ff05ab5cd913676c670ef1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 29 Oct 2012 17:10:14 -0700 Subject: staging: comedi: addi_eeprom: don't pass the eeprom 'type' The eeprom 'type' can be found from the boardinfo when needed. Finding it when needed also makes it clearer what this value is. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_eeprom.c | 24 +++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c index 68b85e2925c..5124ac9f181 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c @@ -182,10 +182,11 @@ static unsigned short addi_eeprom_readw(unsigned long iobase, static void addi_eeprom_read_di_info(struct comedi_device *dev, unsigned long iobase, - char *type, unsigned short addr) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; + char *type = this_board->pc_EepromChip; unsigned short tmp; /* Number of channels */ @@ -202,10 +203,11 @@ static void addi_eeprom_read_di_info(struct comedi_device *dev, static void addi_eeprom_read_do_info(struct comedi_device *dev, unsigned long iobase, - char *type, unsigned short addr) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; + char *type = this_board->pc_EepromChip; unsigned short tmp; /* Number of channels */ @@ -217,11 +219,12 @@ static void addi_eeprom_read_do_info(struct comedi_device *dev, static void addi_eeprom_read_timer_info(struct comedi_device *dev, unsigned long iobase, - char *type, unsigned short addr) { struct addi_private *devpriv = dev->private; #if 0 + const struct addi_board *this_board = comedi_board(dev); + char *type = this_board->pc_EepromChip; unsigned short offset = 0; unsigned short ntimers; unsigned short tmp; @@ -259,10 +262,11 @@ static void addi_eeprom_read_timer_info(struct comedi_device *dev, static void addi_eeprom_read_ao_info(struct comedi_device *dev, unsigned long iobase, - char *type, unsigned short addr) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; + char *type = this_board->pc_EepromChip; unsigned short tmp; /* No of channels for 1st hard component */ @@ -277,11 +281,11 @@ static void addi_eeprom_read_ao_info(struct comedi_device *dev, static void addi_eeprom_read_ai_info(struct comedi_device *dev, unsigned long iobase, - char *type, unsigned short addr) { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; + char *type = this_board->pc_EepromChip; unsigned short offset; unsigned short tmp; @@ -336,25 +340,25 @@ static void addi_eeprom_read_info(struct comedi_device *dev, switch (func) { case EEPROM_DIGITALINPUT: - addi_eeprom_read_di_info(dev, iobase, type, addr); + addi_eeprom_read_di_info(dev, iobase, addr); break; case EEPROM_DIGITALOUTPUT: - addi_eeprom_read_do_info(dev, iobase, type, addr); + addi_eeprom_read_do_info(dev, iobase, addr); break; case EEPROM_ANALOGINPUT: - addi_eeprom_read_ai_info(dev, iobase, type, addr); + addi_eeprom_read_ai_info(dev, iobase, addr); break; case EEPROM_ANALOGOUTPUT: - addi_eeprom_read_ao_info(dev, iobase, type, addr); + addi_eeprom_read_ao_info(dev, iobase, addr); break; case EEPROM_TIMER: case EEPROM_WATCHDOG: case EEPROM_TIMER_WATCHDOG_COUNTER: - addi_eeprom_read_timer_info(dev, iobase, type, addr); + addi_eeprom_read_timer_info(dev, iobase, addr); break; } } -- cgit v1.2.3 From 807e65b0a818cd9b1604144af379bcabd24d4b85 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 30 Oct 2012 13:30:03 +0000 Subject: staging: comedi/drivers: use auto_attach instead of attach_usb Change the usbdux, usbduxfast and usbduxsigma drivers to use the new `auto_attach()` method instead of the `attach_usb()` method. I plan to remove the `attach_usb()` and `attach_pci()` methods from `struct comedi_driver` once nothing is using them. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 11 ++++++----- drivers/staging/comedi/drivers/usbduxfast.c | 11 ++++++----- drivers/staging/comedi/drivers/usbduxsigma.c | 11 ++++++----- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index e89f4e2927b..9629b4f469c 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2375,9 +2375,10 @@ static int usbdux_attach_common(struct comedi_device *dev, return 0; } -static int usbdux_attach_usb(struct comedi_device *dev, - struct usb_interface *uinterf) +static int usbdux_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct usb_interface *uinterf = comedi_to_usb_interface(dev); int ret; struct usbduxsub *this_usbduxsub; @@ -2387,11 +2388,11 @@ static int usbdux_attach_usb(struct comedi_device *dev, this_usbduxsub = usb_get_intfdata(uinterf); if (!this_usbduxsub || !this_usbduxsub->probed) { dev_err(dev->class_dev, - "usbdux: error: attach_usb failed, not connected\n"); + "usbdux: error: auto_attach failed, not connected\n"); ret = -ENODEV; } else if (this_usbduxsub->attached) { dev_err(dev->class_dev, - "error: attach_usb failed, already attached\n"); + "error: auto_attach failed, already attached\n"); ret = -ENODEV; } else ret = usbdux_attach_common(dev, this_usbduxsub); @@ -2415,7 +2416,7 @@ static void usbdux_detach(struct comedi_device *dev) static struct comedi_driver usbdux_driver = { .driver_name = "usbdux", .module = THIS_MODULE, - .attach_usb = usbdux_attach_usb, + .auto_attach = usbdux_auto_attach, .detach = usbdux_detach, }; diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index b4e987b892a..845f240304e 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -1444,9 +1444,10 @@ static int usbduxfast_attach_common(struct comedi_device *dev, return 0; } -static int usbduxfast_attach_usb(struct comedi_device *dev, - struct usb_interface *uinterf) +static int usbduxfast_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct usb_interface *uinterf = comedi_to_usb_interface(dev); int ret; struct usbduxfastsub_s *udfs; @@ -1455,11 +1456,11 @@ static int usbduxfast_attach_usb(struct comedi_device *dev, udfs = usb_get_intfdata(uinterf); if (!udfs || !udfs->probed) { dev_err(dev->class_dev, - "usbduxfast: error: attach_usb failed, not connected\n"); + "usbduxfast: error: auto_attach failed, not connected\n"); ret = -ENODEV; } else if (udfs->attached) { dev_err(dev->class_dev, - "usbduxfast: error: attach_usb failed, already attached\n"); + "usbduxfast: error: auto_attach failed, already attached\n"); ret = -ENODEV; } else ret = usbduxfast_attach_common(dev, udfs); @@ -1485,7 +1486,7 @@ static void usbduxfast_detach(struct comedi_device *dev) static struct comedi_driver usbduxfast_driver = { .driver_name = "usbduxfast", .module = THIS_MODULE, - .attach_usb = usbduxfast_attach_usb, + .auto_attach = usbduxfast_auto_attach, .detach = usbduxfast_detach, }; diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index b1694121f84..972017069e5 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -2359,9 +2359,10 @@ static int usbduxsigma_attach_common(struct comedi_device *dev, return 0; } -static int usbduxsigma_attach_usb(struct comedi_device *dev, - struct usb_interface *uinterf) +static int usbduxsigma_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct usb_interface *uinterf = comedi_to_usb_interface(dev); int ret; struct usbduxsub *uds; @@ -2370,11 +2371,11 @@ static int usbduxsigma_attach_usb(struct comedi_device *dev, uds = usb_get_intfdata(uinterf); if (!uds || !uds->probed) { dev_err(dev->class_dev, - "usbduxsigma: error: attach_usb failed, not connected\n"); + "usbduxsigma: error: auto_attach failed, not connected\n"); ret = -ENODEV; } else if (uds->attached) { dev_err(dev->class_dev, - "usbduxsigma: error: attach_usb failed, already attached\n"); + "usbduxsigma: error: auto_attach failed, already attached\n"); ret = -ENODEV; } else ret = usbduxsigma_attach_common(dev, uds); @@ -2398,7 +2399,7 @@ static void usbduxsigma_detach(struct comedi_device *dev) static struct comedi_driver usbduxsigma_driver = { .driver_name = "usbduxsigma", .module = THIS_MODULE, - .attach_usb = usbduxsigma_attach_usb, + .auto_attach = usbduxsigma_auto_attach, .detach = usbduxsigma_detach, }; -- cgit v1.2.3 From 750af5e568d060ec6994cdcb4e86cdddfcd473c0 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 30 Oct 2012 13:30:04 +0000 Subject: staging: comedi/drivers: use auto_attach instead of attach_pci Change comedi drivers for PCI boards to use the new `auto_attach()` method instead of the `attach_pci()` method. I plan to remove the `attach_pci()` and `attach_usb()` methods from `struct comedi_driver` once nothing is using them. Tag the functions with `__devinit` where they are not already so tagged, as they are only called during PCI probe. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255_pci.c | 7 ++++--- drivers/staging/comedi/drivers/adl_pci6208.c | 7 ++++--- drivers/staging/comedi/drivers/adl_pci7x3x.c | 7 ++++--- drivers/staging/comedi/drivers/adl_pci8164.c | 7 ++++--- drivers/staging/comedi/drivers/adl_pci9111.c | 7 ++++--- drivers/staging/comedi/drivers/adv_pci1710.c | 7 ++++--- drivers/staging/comedi/drivers/adv_pci1723.c | 7 ++++--- drivers/staging/comedi/drivers/adv_pci_dio.c | 7 ++++--- drivers/staging/comedi/drivers/amplc_dio200.c | 13 +++++++------ drivers/staging/comedi/drivers/amplc_pc236.c | 13 +++++++------ drivers/staging/comedi/drivers/amplc_pc263.c | 16 ++++++++++------ drivers/staging/comedi/drivers/amplc_pci224.c | 9 +++++---- drivers/staging/comedi/drivers/amplc_pci230.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas.c | 7 ++++--- drivers/staging/comedi/drivers/cb_pcidda.c | 7 ++++--- drivers/staging/comedi/drivers/cb_pcimdas.c | 7 ++++--- drivers/staging/comedi/drivers/cb_pcimdda.c | 7 ++++--- drivers/staging/comedi/drivers/contec_pci_dio.c | 7 ++++--- drivers/staging/comedi/drivers/daqboard2000.c | 7 ++++--- drivers/staging/comedi/drivers/das08.c | 6 ++++-- drivers/staging/comedi/drivers/dt3000.c | 7 ++++--- drivers/staging/comedi/drivers/dyna_pci10xx.c | 7 ++++--- drivers/staging/comedi/drivers/icp_multi.c | 7 ++++--- drivers/staging/comedi/drivers/ke_counter.c | 7 ++++--- drivers/staging/comedi/drivers/me4000.c | 7 ++++--- drivers/staging/comedi/drivers/me_daq.c | 6 ++++-- drivers/staging/comedi/drivers/ni_6527.c | 7 ++++--- drivers/staging/comedi/drivers/ni_65xx.c | 7 ++++--- drivers/staging/comedi/drivers/ni_660x.c | 7 ++++--- drivers/staging/comedi/drivers/ni_670x.c | 7 ++++--- drivers/staging/comedi/drivers/ni_labpc.c | 7 ++++--- drivers/staging/comedi/drivers/ni_pcidio.c | 7 ++++--- drivers/staging/comedi/drivers/ni_pcimio.c | 7 ++++--- drivers/staging/comedi/drivers/s626.c | 6 ++++-- 34 files changed, 146 insertions(+), 107 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 2bb98d478f3..71ad619d9c6 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -213,9 +213,10 @@ static const void *pci_8255_find_boardinfo(struct comedi_device *dev, return NULL; } -static int pci_8255_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit pci_8255_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct pci_8255_boardinfo *board; struct pci_8255_private *devpriv; struct comedi_subdevice *s; @@ -303,7 +304,7 @@ static void pci_8255_detach(struct comedi_device *dev) static struct comedi_driver pci_8255_driver = { .driver_name = "8255_pci", .module = THIS_MODULE, - .attach_pci = pci_8255_attach_pci, + .auto_attach = pci_8255_auto_attach, .detach = pci_8255_detach, }; diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 350e87dd04d..73fd9750327 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -174,9 +174,10 @@ static const void *pci6208_find_boardinfo(struct comedi_device *dev, return NULL; } -static int pci6208_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit pci6208_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct pci6208_board *boardinfo; struct pci6208_private *devpriv; struct comedi_subdevice *s; @@ -259,7 +260,7 @@ static void pci6208_detach(struct comedi_device *dev) static struct comedi_driver adl_pci6208_driver = { .driver_name = "adl_pci6208", .module = THIS_MODULE, - .attach_pci = pci6208_attach_pci, + .auto_attach = pci6208_auto_attach, .detach = pci6208_detach, }; diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index 8eee2fa0bf0..be01b202197 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -168,9 +168,10 @@ static const void *adl_pci7x3x_find_boardinfo(struct comedi_device *dev, return NULL; } -static int adl_pci7x3x_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit adl_pci7x3x_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct adl_pci7x3x_boardinfo *board; struct comedi_subdevice *s; int subdev; @@ -291,7 +292,7 @@ static void adl_pci7x3x_detach(struct comedi_device *dev) static struct comedi_driver adl_pci7x3x_driver = { .driver_name = "adl_pci7x3x", .module = THIS_MODULE, - .attach_pci = adl_pci7x3x_attach_pci, + .auto_attach = adl_pci7x3x_auto_attach, .detach = adl_pci7x3x_detach, }; diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 9999f938745..41993ec436f 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -212,9 +212,10 @@ static int adl_pci8164_insn_write_buf1(struct comedi_device *dev, return 2; } -static int adl_pci8164_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit adl_pci8164_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret; @@ -287,7 +288,7 @@ static void adl_pci8164_detach(struct comedi_device *dev) static struct comedi_driver adl_pci8164_driver = { .driver_name = "adl_pci8164", .module = THIS_MODULE, - .attach_pci = adl_pci8164_attach_pci, + .auto_attach = adl_pci8164_auto_attach, .detach = adl_pci8164_detach, }; diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 236a88946d0..45f85f64eff 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -879,9 +879,10 @@ static int pci9111_reset(struct comedi_device *dev) return 0; } -static int pci9111_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit pci9111_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct pci9111_private_data *dev_private; struct comedi_subdevice *s; int ret; @@ -975,7 +976,7 @@ static void pci9111_detach(struct comedi_device *dev) static struct comedi_driver adl_pci9111_driver = { .driver_name = "adl_pci9111", .module = THIS_MODULE, - .attach_pci = pci9111_attach_pci, + .auto_attach = pci9111_auto_attach, .detach = pci9111_detach, }; diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index dd83c749e6e..d1f800aa2d3 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1255,9 +1255,10 @@ static const void *pci1710_find_boardinfo(struct comedi_device *dev, return NULL; } -static int pci1710_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit pci1710_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct boardtype *this_board; struct pci1710_private *devpriv; struct comedi_subdevice *s; @@ -1413,7 +1414,7 @@ static void pci1710_detach(struct comedi_device *dev) static struct comedi_driver adv_pci1710_driver = { .driver_name = "adv_pci1710", .module = THIS_MODULE, - .attach_pci = pci1710_attach_pci, + .auto_attach = pci1710_auto_attach, .detach = pci1710_detach, }; diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 7109e7d8b9f..490e4347f11 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -232,9 +232,10 @@ static int pci1723_dio_insn_bits(struct comedi_device *dev, return insn->n; } -static int pci1723_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit pci1723_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct pci1723_private *devpriv; struct comedi_subdevice *s; int ret; @@ -316,7 +317,7 @@ static void pci1723_detach(struct comedi_device *dev) static struct comedi_driver adv_pci1723_driver = { .driver_name = "adv_pci1723", .module = THIS_MODULE, - .attach_pci = pci1723_attach_pci, + .auto_attach = pci1723_auto_attach, .detach = pci1723_detach, }; diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 131eb02324d..bb69c0d71ce 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1090,9 +1090,10 @@ static const void *pci_dio_find_boardinfo(struct comedi_device *dev, return NULL; } -static int pci_dio_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit pci_dio_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct dio_boardtype *this_board; struct pci_dio_private *devpriv; struct comedi_subdevice *s; @@ -1195,7 +1196,7 @@ static void pci_dio_detach(struct comedi_device *dev) static struct comedi_driver adv_pci_dio_driver = { .driver_name = "adv_pci_dio", .module = THIS_MODULE, - .attach_pci = pci_dio_attach_pci, + .auto_attach = pci_dio_auto_attach, .detach = pci_dio_detach, }; diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index ffe3f7385c7..cb75a177c9a 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1943,13 +1943,14 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* - * The attach_pci hook (if non-NULL) is called at PCI probe time in preference - * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should - * be a board entry matching the supplied PCI device. + * The auto_attach hook is called at PCI probe time via + * comedi_pci_auto_config(). dev->board_ptr is NULL on entry. + * There should be a board entry matching the supplied PCI device. */ -static int __devinit dio200_attach_pci(struct comedi_device *dev, - struct pci_dev *pci_dev) +static int __devinit dio200_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pci_dev = comedi_to_pci_dev(dev); const struct dio200_board *thisboard; struct dio200_private *devpriv; resource_size_t base, len; @@ -2074,7 +2075,7 @@ static struct comedi_driver amplc_dio200_driver = { .driver_name = DIO200_DRIVER_NAME, .module = THIS_MODULE, .attach = dio200_attach, - .attach_pci = dio200_attach_pci, + .auto_attach = dio200_auto_attach, .detach = dio200_detach, .board_name = &dio200_boards[0].name, .offset = sizeof(struct dio200_board), diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 8b7e16ee113..ae75754dd77 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -537,13 +537,14 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* - * The attach_pci hook (if non-NULL) is called at PCI probe time in preference - * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should - * be a board entry matching the supplied PCI device. + * The auto_attach hook is called at PCI probe time via + * comedi_pci_auto_config(). dev->board_ptr is NULL on entry. + * There should be a board entry matching the supplied PCI device. */ -static int __devinit pc236_attach_pci(struct comedi_device *dev, - struct pci_dev *pci_dev) +static int __devinit pc236_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pci_dev = comedi_to_pci_dev(dev); struct pc236_private *devpriv; if (!DO_PCI) @@ -607,7 +608,7 @@ static struct comedi_driver amplc_pc236_driver = { .driver_name = PC236_DRIVER_NAME, .module = THIS_MODULE, .attach = pc236_attach, - .attach_pci = pc236_attach_pci, + .auto_attach = pc236_auto_attach, .detach = pc236_detach, .board_name = &pc236_boards[0].name, .offset = sizeof(struct pc236_board), diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 6ffb39c3931..dc9504914e2 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -290,17 +290,21 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) return -EINVAL; } } + /* - * The attach_pci hook (if non-NULL) is called at PCI probe time in preference - * to the "manual" attach hook. dev->board_ptr is NULL on entry. There should - * be a board entry matching the supplied PCI device. + * The auto_attach hook is called at PCI probe time via + * comedi_pci_auto_config(). dev->board_ptr is NULL on entry. + * There should be a board entry matching the supplied PCI device. */ -static int __devinit pc263_attach_pci(struct comedi_device *dev, - struct pci_dev *pci_dev) +static int __devinit pc263_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pci_dev; + if (!DO_PCI) return -EINVAL; + pci_dev = comedi_to_pci_dev(dev); dev_info(dev->class_dev, PC263_DRIVER_NAME ": attach pci %s\n", pci_name(pci_dev)); dev->board_ptr = pc263_find_pci_board(pci_dev); @@ -347,7 +351,7 @@ static struct comedi_driver amplc_pc263_driver = { .driver_name = PC263_DRIVER_NAME, .module = THIS_MODULE, .attach = pc263_attach, - .attach_pci = pc263_attach_pci, + .auto_attach = pc263_auto_attach, .detach = pc263_detach, .board_name = &pc263_boards[0].name, .offset = sizeof(struct pc263_board), diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 610f2ce8fa1..e997f6e446d 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1286,7 +1286,7 @@ static void pci224_report_attach(struct comedi_device *dev, unsigned int irq) } /* - * Common part of attach and attach_pci. + * Common part of attach and auto_attach. */ static int pci224_attach_common(struct comedi_device *dev, struct pci_dev *pci_dev, int *options) @@ -1460,11 +1460,12 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) } static int __devinit -pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) +pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused) { + struct pci_dev *pci_dev = comedi_to_pci_dev(dev); struct pci224_private *devpriv; - dev_info(dev->class_dev, DRIVER_NAME ": attach_pci %s\n", + dev_info(dev->class_dev, DRIVER_NAME ": attach pci %s\n", pci_name(pci_dev)); devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); @@ -1519,7 +1520,7 @@ static struct comedi_driver amplc_pci224_driver = { .module = THIS_MODULE, .attach = pci224_attach, .detach = pci224_detach, - .attach_pci = pci224_attach_pci, + .auto_attach = pci224_auto_attach, .board_name = &pci224_boards[0].name, .offset = sizeof(struct pci224_board), .num_names = ARRAY_SIZE(pci224_boards), diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index db67c8313ca..ef87946e642 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2672,7 +2672,7 @@ static int pci230_alloc_private(struct comedi_device *dev) return 0; } -/* Common part of attach and attach_pci. */ +/* Common part of attach and auto_attach. */ static int pci230_attach_common(struct comedi_device *dev, struct pci_dev *pci_dev) { diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 8e88573d270..e7314e5f726 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1466,9 +1466,10 @@ static const void *cb_pcidas_find_boardinfo(struct comedi_device *dev, return NULL; } -static int cb_pcidas_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit cb_pcidas_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct cb_pcidas_board *thisboard; struct cb_pcidas_private *devpriv; struct comedi_subdevice *s; @@ -1651,7 +1652,7 @@ static void cb_pcidas_detach(struct comedi_device *dev) static struct comedi_driver cb_pcidas_driver = { .driver_name = "cb_pcidas", .module = THIS_MODULE, - .attach_pci = cb_pcidas_attach_pci, + .auto_attach = cb_pcidas_auto_attach, .detach = cb_pcidas_detach, }; diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index eb03032ccfe..083bd8636ef 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -349,9 +349,10 @@ static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev, return NULL; } -static int cb_pcidda_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit cb_pcidda_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct cb_pcidda_board *thisboard; struct cb_pcidda_private *devpriv; struct comedi_subdevice *s; @@ -427,7 +428,7 @@ static void cb_pcidda_detach(struct comedi_device *dev) static struct comedi_driver cb_pcidda_driver = { .driver_name = "cb_pcidda", .module = THIS_MODULE, - .attach_pci = cb_pcidda_attach_pci, + .auto_attach = cb_pcidda_auto_attach, .detach = cb_pcidda_detach, }; diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index b093c9d939d..f75873740bc 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -205,9 +205,10 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, return i; } -static int cb_pcimdas_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit cb_pcimdas_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct cb_pcimdas_private *devpriv; struct comedi_subdevice *s; unsigned long iobase_8255; @@ -288,7 +289,7 @@ static void cb_pcimdas_detach(struct comedi_device *dev) static struct comedi_driver cb_pcimdas_driver = { .driver_name = "cb_pcimdas", .module = THIS_MODULE, - .attach_pci = cb_pcimdas_attach_pci, + .auto_attach = cb_pcimdas_auto_attach, .detach = cb_pcimdas_detach, }; diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 94aa2af57eb..89c70385330 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -151,9 +151,10 @@ static int cb_pcimdda_ao_rinsn(struct comedi_device *dev, return insn->n; } -static int cb_pcimdda_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit cb_pcimdda_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct cb_pcimdda_private *devpriv; struct comedi_subdevice *s; int ret; @@ -211,7 +212,7 @@ static void cb_pcimdda_detach(struct comedi_device *dev) static struct comedi_driver cb_pcimdda_driver = { .driver_name = "cb_pcimdda", .module = THIS_MODULE, - .attach_pci = cb_pcimdda_attach_pci, + .auto_attach = cb_pcimdda_auto_attach, .detach = cb_pcimdda_detach, }; diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 70a9243cf33..c06b7b682f7 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -68,9 +68,10 @@ static int contec_di_insn_bits(struct comedi_device *dev, return insn->n; } -static int contec_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit contec_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret; @@ -119,7 +120,7 @@ static void contec_detach(struct comedi_device *dev) static struct comedi_driver contec_pci_dio_driver = { .driver_name = "contec_pci_dio", .module = THIS_MODULE, - .attach_pci = contec_attach_pci, + .auto_attach = contec_auto_attach, .detach = contec_detach, }; diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index 8bc6189c578..c5aa6b8d8f7 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -688,9 +688,10 @@ static const void *daqboard2000_find_boardinfo(struct comedi_device *dev, return NULL; } -static int daqboard2000_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit daqboard2000_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct daq200_boardtype *board; struct daqboard2000_private *devpriv; struct comedi_subdevice *s; @@ -788,7 +789,7 @@ static void daqboard2000_detach(struct comedi_device *dev) static struct comedi_driver daqboard2000_driver = { .driver_name = "daqboard2000", .module = THIS_MODULE, - .attach_pci = daqboard2000_attach_pci, + .auto_attach = daqboard2000_auto_attach, .detach = daqboard2000_detach, }; diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index d7582b96bf1..cc654542a6d 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -775,14 +775,16 @@ das08_find_pci_board(struct pci_dev *pdev) /* only called in the PCI probe path, via comedi_pci_auto_config() */ static int __devinit __maybe_unused -das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) +das08_auto_attach(struct comedi_device *dev, unsigned long context_unused) { + struct pci_dev *pdev; struct das08_private_struct *devpriv; unsigned long iobase; if (!DO_PCI) return -EINVAL; + pdev = comedi_to_pci_dev(dev); devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; @@ -867,7 +869,7 @@ static struct comedi_driver das08_driver = { .driver_name = DRV_NAME, .module = THIS_MODULE, .attach = das08_attach, - .attach_pci = das08_attach_pci, + .auto_attach = das08_auto_attach, .detach = das08_detach, .board_name = &das08_boards[0].name, .num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct), diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 3897960108a..71c24954640 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -749,9 +749,10 @@ static const void *dt3000_find_boardinfo(struct comedi_device *dev, return NULL; } -static int dt3000_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit dt3000_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct dt3k_boardtype *this_board; struct dt3k_private *devpriv; struct comedi_subdevice *s; @@ -866,7 +867,7 @@ static void dt3000_detach(struct comedi_device *dev) static struct comedi_driver dt3000_driver = { .driver_name = "dt3000", .module = THIS_MODULE, - .attach_pci = dt3000_attach_pci, + .auto_attach = dt3000_auto_attach, .detach = dt3000_detach, }; diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 656d08b20db..363b09d217e 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -177,9 +177,10 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, return insn->n; } -static int dyna_pci10xx_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit dyna_pci10xx_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct dyna_pci10xx_private *devpriv; struct comedi_subdevice *s; int ret; @@ -265,7 +266,7 @@ static void dyna_pci10xx_detach(struct comedi_device *dev) static struct comedi_driver dyna_pci10xx_driver = { .driver_name = "dyna_pci10xx", .module = THIS_MODULE, - .attach_pci = dyna_pci10xx_attach_pci, + .auto_attach = dyna_pci10xx_auto_attach, .detach = dyna_pci10xx_detach, }; diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 51af903773e..e7bb6031e54 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -494,9 +494,10 @@ static int icp_multi_reset(struct comedi_device *dev) return 0; } -static int icp_multi_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit icp_multi_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct icp_multi_private *devpriv; struct comedi_subdevice *s; resource_size_t iobase; @@ -612,7 +613,7 @@ static void icp_multi_detach(struct comedi_device *dev) static struct comedi_driver icp_multi_driver = { .driver_name = "icp_multi", .module = THIS_MODULE, - .attach_pci = icp_multi_attach_pci, + .auto_attach = icp_multi_auto_attach, .detach = icp_multi_detach, }; diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 8780a12ef59..a59a12b4f19 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -87,9 +87,10 @@ static int cnt_rinsn(struct comedi_device *dev, return 1; } -static int cnt_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit cnt_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret; @@ -141,7 +142,7 @@ static void cnt_detach(struct comedi_device *dev) static struct comedi_driver ke_counter_driver = { .driver_name = "ke_counter", .module = THIS_MODULE, - .attach_pci = cnt_attach_pci, + .auto_attach = cnt_auto_attach, .detach = cnt_detach, }; diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 322c8849b52..c85e5e5420b 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1568,9 +1568,10 @@ static const void *me4000_find_boardinfo(struct comedi_device *dev, return NULL; } -static int me4000_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit me4000_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct me4000_board *thisboard; struct me4000_info *info; struct comedi_subdevice *s; @@ -1728,7 +1729,7 @@ static void me4000_detach(struct comedi_device *dev) static struct comedi_driver me4000_driver = { .driver_name = "me4000", .module = THIS_MODULE, - .attach_pci = me4000_attach_pci, + .auto_attach = me4000_auto_attach, .detach = me4000_detach, }; diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 6a2dbdf9f0d..b1fd74c3a61 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -542,8 +542,10 @@ static const void *me_find_boardinfo(struct comedi_device *dev, return NULL; } -static int me_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) +static int __devinit me_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct me_board *board; struct me_private_data *dev_private; struct comedi_subdevice *s; @@ -653,7 +655,7 @@ static void me_detach(struct comedi_device *dev) static struct comedi_driver me_daq_driver = { .driver_name = "me_daq", .module = THIS_MODULE, - .attach_pci = me_attach_pci, + .auto_attach = me_auto_attach, .detach = me_detach, }; diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index d853e75be79..112742ebad9 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -357,9 +357,10 @@ ni6527_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit ni6527_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit ni6527_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct ni6527_private *devpriv; struct comedi_subdevice *s; int ret; @@ -457,7 +458,7 @@ static void ni6527_detach(struct comedi_device *dev) static struct comedi_driver ni6527_driver = { .driver_name = DRIVER_NAME, .module = THIS_MODULE, - .attach_pci = ni6527_attach_pci, + .auto_attach = ni6527_auto_attach, .detach = ni6527_detach, }; diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 19d5e8c96e8..df7a3df83ba 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -627,9 +627,10 @@ ni_65xx_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit ni_65xx_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit ni_65xx_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct ni_65xx_private *devpriv; struct comedi_subdevice *s; unsigned i; @@ -793,7 +794,7 @@ static void ni_65xx_detach(struct comedi_device *dev) static struct comedi_driver ni_65xx_driver = { .driver_name = "ni_65xx", .module = THIS_MODULE, - .attach_pci = ni_65xx_attach_pci, + .auto_attach = ni_65xx_auto_attach, .detach = ni_65xx_detach, }; diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 31805754648..d1561c72e2d 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1166,9 +1166,10 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, return insn->n; } -static int __devinit ni_660x_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit ni_660x_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct ni_660x_board *board; struct ni_660x_private *devpriv; struct comedi_subdevice *s; @@ -1316,7 +1317,7 @@ static void ni_660x_detach(struct comedi_device *dev) static struct comedi_driver ni_660x_driver = { .driver_name = "ni_660x", .module = THIS_MODULE, - .attach_pci = ni_660x_attach_pci, + .auto_attach = ni_660x_auto_attach, .detach = ni_660x_detach, }; diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 2cf4907c366..36462d582e4 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -201,9 +201,10 @@ ni_670x_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit ni_670x_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit ni_670x_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct ni_670x_board *thisboard; struct ni_670x_private *devpriv; struct comedi_subdevice *s; @@ -298,7 +299,7 @@ static void ni_670x_detach(struct comedi_device *dev) static struct comedi_driver ni_670x_driver = { .driver_name = "ni_670x", .module = THIS_MODULE, - .attach_pci = ni_670x_attach_pci, + .auto_attach = ni_670x_auto_attach, .detach = ni_670x_detach, }; diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index ab51c2678b9..f4a0377486e 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -696,9 +696,10 @@ labpc_pci_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit labpc_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit labpc_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct labpc_private *devpriv; unsigned long iobase; unsigned int irq; @@ -2117,7 +2118,7 @@ static struct comedi_driver labpc_driver = { .driver_name = DRV_NAME, .module = THIS_MODULE, .attach = labpc_attach, - .attach_pci = labpc_attach_pci, + .auto_attach = labpc_auto_attach, .detach = labpc_common_detach, .num_names = ARRAY_SIZE(labpc_boards), .board_name = &labpc_boards[0].name, diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 0a556c7f9bc..20e7545204b 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1120,9 +1120,10 @@ nidio_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit nidio_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit nidio_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct nidio96_private *devpriv; struct comedi_subdevice *s; int ret; @@ -1227,7 +1228,7 @@ static void nidio_detach(struct comedi_device *dev) static struct comedi_driver ni_pcidio_driver = { .driver_name = "ni_pcidio", .module = THIS_MODULE, - .attach_pci = nidio_attach_pci, + .auto_attach = nidio_auto_attach, .detach = nidio_detach, }; diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 4adb4ba545c..65e1896c077 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1620,9 +1620,10 @@ pcimio_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit pcimio_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit pcimio_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct ni_private *devpriv; int ret; @@ -1780,7 +1781,7 @@ static int pcimio_dio_change(struct comedi_device *dev, static struct comedi_driver ni_pcimio_driver = { .driver_name = "ni_pcimio", .module = THIS_MODULE, - .attach_pci = pcimio_attach_pci, + .auto_attach = pcimio_auto_attach, .detach = pcimio_detach, }; diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 15755325121..686ee0e8713 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2691,8 +2691,10 @@ static void s626_initialize(struct comedi_device *dev) /* writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER); */ } -static int s626_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) +static int __devinit s626_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct s626_private *devpriv; struct comedi_subdevice *s; int ret; @@ -2858,7 +2860,7 @@ static void s626_detach(struct comedi_device *dev) static struct comedi_driver s626_driver = { .driver_name = "s626", .module = THIS_MODULE, - .attach_pci = s626_attach_pci, + .auto_attach = s626_auto_attach, .detach = s626_detach, }; -- cgit v1.2.3 From c2a6a5528f3144cf42b8b4d0655106f573f71fae Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Thu, 25 Oct 2012 17:14:13 -0500 Subject: staging: drm/omap: only advertise rotation prop if supported For hardware that does not have DMM/TILER, there is no rotation, so no point in getting userspace's hopes up. Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_drv.c | 27 +++++++++++++++------------ drivers/staging/omapdrm/omap_plane.c | 34 ++++++++++++++++++---------------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index ebdb0b67673..053c45dbcc8 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -659,19 +659,22 @@ static void dev_lastclose(struct drm_device *dev) DBG("lastclose: dev=%p", dev); - /* need to restore default rotation state.. not sure if there is - * a cleaner way to restore properties to default state? Maybe - * a flag that properties should automatically be restored to - * default state on lastclose? - */ - for (i = 0; i < priv->num_crtcs; i++) { - drm_object_property_set_value(&priv->crtcs[i]->base, - priv->rotation_prop, 0); - } + if (priv->rotation_prop) { + /* need to restore default rotation state.. not sure + * if there is a cleaner way to restore properties to + * default state? Maybe a flag that properties should + * automatically be restored to default state on + * lastclose? + */ + for (i = 0; i < priv->num_crtcs; i++) { + drm_object_property_set_value(&priv->crtcs[i]->base, + priv->rotation_prop, 0); + } - for (i = 0; i < priv->num_planes; i++) { - drm_object_property_set_value(&priv->planes[i]->base, - priv->rotation_prop, 0); + for (i = 0; i < priv->num_planes; i++) { + drm_object_property_set_value(&priv->planes[i]->base, + priv->rotation_prop, 0); + } } ret = drm_fb_helper_restore_fbdev_mode(priv->fbdev); diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/staging/omapdrm/omap_plane.c index 4bde639dd02..1b3a9febd40 100644 --- a/drivers/staging/omapdrm/omap_plane.c +++ b/drivers/staging/omapdrm/omap_plane.c @@ -416,23 +416,25 @@ void omap_plane_install_properties(struct drm_plane *plane, struct omap_drm_private *priv = dev->dev_private; struct drm_property *prop; - prop = priv->rotation_prop; - if (!prop) { - const struct drm_prop_enum_list props[] = { - { DRM_ROTATE_0, "rotate-0" }, - { DRM_ROTATE_90, "rotate-90" }, - { DRM_ROTATE_180, "rotate-180" }, - { DRM_ROTATE_270, "rotate-270" }, - { DRM_REFLECT_X, "reflect-x" }, - { DRM_REFLECT_Y, "reflect-y" }, - }; - prop = drm_property_create_bitmask(dev, 0, "rotation", - props, ARRAY_SIZE(props)); - if (prop == NULL) - return; - priv->rotation_prop = prop; + if (priv->has_dmm) { + prop = priv->rotation_prop; + if (!prop) { + const struct drm_prop_enum_list props[] = { + { DRM_ROTATE_0, "rotate-0" }, + { DRM_ROTATE_90, "rotate-90" }, + { DRM_ROTATE_180, "rotate-180" }, + { DRM_ROTATE_270, "rotate-270" }, + { DRM_REFLECT_X, "reflect-x" }, + { DRM_REFLECT_Y, "reflect-y" }, + }; + prop = drm_property_create_bitmask(dev, 0, "rotation", + props, ARRAY_SIZE(props)); + if (prop == NULL) + return; + priv->rotation_prop = prop; + } + drm_object_attach_property(obj, prop, 0); } - drm_object_attach_property(obj, prop, 0); prop = priv->zorder_prop; if (!prop) { -- cgit v1.2.3 From e6c5abf2542f1a91d31ae536707c00cf0ceaf376 Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Sat, 27 Oct 2012 11:29:03 +0800 Subject: staging: ced1401: remove useless value cast on kmalloc() Casting value returned by k[cmz]alloc to (struct page * *) is useless. Generated by: scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci Reported-by: Fengguang Wu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ced1401/ced_ioc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/ced1401/ced_ioc.c b/drivers/staging/ced1401/ced_ioc.c index 0adba75be8b..efe6aecbf9b 100644 --- a/drivers/staging/ced1401/ced_ioc.c +++ b/drivers/staging/ced1401/ced_ioc.c @@ -697,8 +697,7 @@ static int SetArea(DEVICE_EXTENSION * pdx, int nArea, char __user * puBuf, return -EFAULT; // ...then we are done // Now allocate space to hold the page pointer and virtual address pointer tables - pPages = - (struct page **)kmalloc(len * sizeof(struct page *), GFP_KERNEL); + pPages = kmalloc(len * sizeof(struct page *), GFP_KERNEL); if (!pPages) { iReturn = U14ERR_NOMEMORY; goto error; -- cgit v1.2.3 From f68f5f20675a30197423cf79b42fd4f05b77af43 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 29 Oct 2012 09:27:50 +0100 Subject: staging: drm/omap: remove global drm_device ptr Not actually used anymore. Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_drv.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 053c45dbcc8..09653b88e0e 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -30,8 +30,6 @@ #define DRIVER_MINOR 0 #define DRIVER_PATCHLEVEL 0 -struct drm_device *drm_device; - static int num_crtc = CONFIG_DRM_OMAP_NUM_CRTCS; MODULE_PARM_DESC(num_crtc, "Number of overlays to use as CRTCs"); @@ -562,8 +560,6 @@ static int dev_load(struct drm_device *dev, unsigned long flags) DBG("load: dev=%p", dev); - drm_device = dev; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { dev_err(dev->dev, "could not allocate priv\n"); -- cgit v1.2.3 From 5e3b08749951e5746d3e747f1ffae37eff2d08d5 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 29 Oct 2012 09:31:12 +0100 Subject: staging: drm/omap: add support for ARCH_MULTIPLATFORM Remove usage of plat/cpu.h and get information from platform data instead. This enables omapdrm to be built with ARCH_MULTIPLATFORM. Signed-off-by: Rob Clark Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap2/drm.c | 7 +++++++ drivers/staging/omapdrm/Kconfig | 2 +- drivers/staging/omapdrm/omap_dmm_tiler.h | 1 - drivers/staging/omapdrm/omap_drv.c | 6 +++++- drivers/staging/omapdrm/omap_drv.h | 2 ++ include/linux/platform_data/omap_drm.h | 1 + 6 files changed, 16 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c index 72e0f01b715..49a7ffb716a 100644 --- a/arch/arm/mach-omap2/drm.c +++ b/arch/arm/mach-omap2/drm.c @@ -23,15 +23,20 @@ #include #include #include +#include #include #include +#include #if defined(CONFIG_DRM_OMAP) || (CONFIG_DRM_OMAP_MODULE) +static struct omap_drm_platform_data platform_data; + static struct platform_device omap_drm_device = { .dev = { .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &platform_data, }, .name = "omapdrm", .id = 0, @@ -52,6 +57,8 @@ static int __init omap_init_drm(void) oh->name); } + platform_data.omaprev = GET_OMAP_REVISION(); + return platform_device_register(&omap_drm_device); } diff --git a/drivers/staging/omapdrm/Kconfig b/drivers/staging/omapdrm/Kconfig index 81a7cba4a0c..b724a413143 100644 --- a/drivers/staging/omapdrm/Kconfig +++ b/drivers/staging/omapdrm/Kconfig @@ -2,7 +2,7 @@ config DRM_OMAP tristate "OMAP DRM" depends on DRM && !CONFIG_FB_OMAP2 - depends on ARCH_OMAP2PLUS + depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM select DRM_KMS_HELPER select OMAP2_DSS select FB_SYS_FILLRECT diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.h b/drivers/staging/omapdrm/omap_dmm_tiler.h index c0271a2ac87..4fdd61e54bd 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.h +++ b/drivers/staging/omapdrm/omap_dmm_tiler.h @@ -16,7 +16,6 @@ #ifndef OMAP_DMM_TILER_H #define OMAP_DMM_TILER_H -#include #include "omap_drv.h" #include "tcm.h" diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 09653b88e0e..6ae2f763b27 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -417,13 +417,14 @@ static void omap_modeset_free(struct drm_device *dev) static int ioctl_get_param(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct omap_drm_private *priv = dev->dev_private; struct drm_omap_param *args = data; DBG("%p: param=%llu", dev, args->param); switch (args->param) { case OMAP_PARAM_CHIPSET_ID: - args->value = GET_OMAP_TYPE; + args->value = priv->omaprev; break; default: DBG("unknown parameter %lld", args->param); @@ -555,6 +556,7 @@ struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { */ static int dev_load(struct drm_device *dev, unsigned long flags) { + struct omap_drm_platform_data *pdata = dev->dev->platform_data; struct omap_drm_private *priv; int ret; @@ -566,6 +568,8 @@ static int dev_load(struct drm_device *dev, unsigned long flags) return -ENOMEM; } + priv->omaprev = pdata->omaprev; + dev->dev_private = priv; priv->wq = alloc_ordered_workqueue("omapdrm", 0); diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h index 9dc72d143ff..8f7c447930f 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/staging/omapdrm/omap_drv.h @@ -40,6 +40,8 @@ #define MAX_MAPPERS 2 struct omap_drm_private { + uint32_t omaprev; + unsigned int num_crtcs; struct drm_crtc *crtcs[8]; diff --git a/include/linux/platform_data/omap_drm.h b/include/linux/platform_data/omap_drm.h index 3da73bdc203..f4e4a237ebd 100644 --- a/include/linux/platform_data/omap_drm.h +++ b/include/linux/platform_data/omap_drm.h @@ -46,6 +46,7 @@ struct omap_kms_platform_data { }; struct omap_drm_platform_data { + uint32_t omaprev; struct omap_kms_platform_data *kms_pdata; }; -- cgit v1.2.3 From c4ff7ef5cf7ee48770db91a88b361ecb7b450a18 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 29 Oct 2012 09:31:14 +0100 Subject: staging: drm/imx: add support for ARCH_MULTIPLATFORM No dependency on plat headers, so only needs Kconfig update to build for ARCH_MULTIPLATFORM. Signed-off-by: Rob Clark Acked-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/imx-drm/Kconfig b/drivers/staging/imx-drm/Kconfig index 14b4449df23..be7e2e30ac1 100644 --- a/drivers/staging/imx-drm/Kconfig +++ b/drivers/staging/imx-drm/Kconfig @@ -3,7 +3,7 @@ config DRM_IMX select DRM_KMS_HELPER select DRM_GEM_CMA_HELPER select DRM_KMS_CMA_HELPER - depends on DRM && ARCH_MXC + depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM) help enable i.MX graphics support -- cgit v1.2.3 From f426a36cecfea2cfd69c28ca5ba4f4bfae913f63 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 25 Oct 2012 14:15:49 -0700 Subject: tools: hv: Return the full kernel version Currently, we are returning the same string for both OSBuildNumber and OSVersion keys. Return the full uts string for the OSBuild key since Windows does not impose any restrictions on this. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Reported-by: Claudio Latini Signed-off-by: Greg Kroah-Hartman --- tools/hv/hv_kvp_daemon.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 5959affd882..6c7bcb9932c 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -88,6 +88,7 @@ static char *os_major = ""; static char *os_minor = ""; static char *processor_arch; static char *os_build; +static char *os_version; static char *lic_version = "Unknown version"; static struct utsname uts_buf; @@ -453,7 +454,9 @@ void kvp_get_os_info(void) char *p, buf[512]; uname(&uts_buf); - os_build = uts_buf.release; + os_version = uts_buf.release; + os_build = strdup(uts_buf.release); + os_name = uts_buf.sysname; processor_arch = uts_buf.machine; @@ -462,7 +465,7 @@ void kvp_get_os_info(void) * string to be of the form: x.y.z * Strip additional information we may have. */ - p = strchr(os_build, '-'); + p = strchr(os_version, '-'); if (p) *p = '\0'; @@ -1649,7 +1652,7 @@ int main(void) strcpy(key_name, "OSMinorVersion"); break; case OSVersion: - strcpy(key_value, os_build); + strcpy(key_value, os_version); strcpy(key_name, "OSVersion"); break; case ProcessorArchitecture: -- cgit v1.2.3 From 3321e738d6f0a82b2c19f9d5890f304dab1e5357 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 25 Oct 2012 14:15:50 -0700 Subject: Tools: hv: Don't return loopback addresses Don't return loopback addresses and further don't terminate the IP address strings with a semicolon. This is the current behavior of Windows guests. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Reported-by: Claudio Latini Signed-off-by: Greg Kroah-Hartman --- tools/hv/hv_kvp_daemon.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 6c7bcb9932c..13c2a142331 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -43,6 +43,7 @@ #include #include #include +#include /* * KVP protocol: The user mode component first registers with the @@ -882,7 +883,7 @@ static int kvp_process_ip_address(void *addrp, addr_length = INET6_ADDRSTRLEN; } - if ((length - *offset) < addr_length + 1) + if ((length - *offset) < addr_length + 2) return HV_E_FAIL; if (str == NULL) { strcpy(buffer, "inet_ntop failed\n"); @@ -890,11 +891,13 @@ static int kvp_process_ip_address(void *addrp, } if (*offset == 0) strcpy(buffer, tmp); - else + else { + strcat(buffer, ";"); strcat(buffer, tmp); - strcat(buffer, ";"); + } *offset += strlen(str) + 1; + return 0; } @@ -956,7 +959,9 @@ kvp_get_ip_info(int family, char *if_name, int op, * supported address families; if not we gather info on * the specified address family. */ - if ((family != 0) && (curp->ifa_addr->sa_family != family)) { + if ((((family != 0) && + (curp->ifa_addr->sa_family != family))) || + (curp->ifa_flags & IFF_LOOPBACK)) { curp = curp->ifa_next; continue; } -- cgit v1.2.3 From f9652875dcd49d400b775aecc8e0bf76e405b70a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 30 Oct 2012 20:00:30 +0100 Subject: PM / QoS: Fix the return value of dev_pm_qos_update_request() Commit e39473d (PM / QoS: Make it possible to expose PM QoS device flags to user space) introduced __dev_pm_qos_update_request() to be called internally by dev_pm_qos_update_request(), but forgot to make the latter actually use the return value of the former. Fix this mistake. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/qos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 167834dcc82..3a7687ae5a4 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -380,7 +380,7 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value) return -EINVAL; mutex_lock(&dev_pm_qos_mtx); - __dev_pm_qos_update_request(req, new_value); + ret = __dev_pm_qos_update_request(req, new_value); mutex_unlock(&dev_pm_qos_mtx); return ret; -- cgit v1.2.3 From 788ca84ac7bb247427da07a430de47007efbfc47 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Tue, 30 Oct 2012 18:38:54 +0000 Subject: staging: et131x: Remove duplicate code for fbr[0, 1] Several places in et131x.c code is duplicated for fbr[0] and fbr[1]. Remove the duplicate lines and use loops to run over both indicies. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 462 ++++++++++++++++------------------------ 1 file changed, 180 insertions(+), 282 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 70fe33b5781..67fa1eff26b 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -176,8 +176,8 @@ MODULE_DESCRIPTION("10/100/1000 Base-T Ethernet Driver for the ET1310 by Agere S #define PARM_DMA_CACHE_DEF 0 /* RX defines */ -#define FBR_CHUNKS 32 -#define MAX_DESC_PER_RING_RX 1024 +#define FBR_CHUNKS 32 +#define MAX_DESC_PER_RING_RX 1024 /* number of RFDs - default and min */ #define RFD_LOW_WATER_MARK 40 @@ -1847,6 +1847,7 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) u32 entry; u32 psr_num_des; unsigned long flags; + u8 id; /* Halt RXDMA to perform the reconfigure. */ et131x_rx_dma_disable(adapter); @@ -1874,56 +1875,52 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) /* These local variables track the PSR in the adapter structure */ rx_local->local_psr_full = 0; - /* Now's the best time to initialize FBR1 contents */ - fbr_entry = (struct fbr_desc *) rx_local->fbr[0]->ring_virtaddr; - for (entry = 0; entry < rx_local->fbr[0]->num_entries; entry++) { - fbr_entry->addr_hi = rx_local->fbr[0]->bus_high[entry]; - fbr_entry->addr_lo = rx_local->fbr[0]->bus_low[entry]; - fbr_entry->word2 = entry; - fbr_entry++; - } + for (id = 0; id < NUM_FBRS; id++) { + u32 *num_des; + u32 *full_offset; + u32 *min_des; + u32 *base_hi; + u32 *base_lo; + + if (id == 0) { + num_des = &rx_dma->fbr1_num_des; + full_offset = &rx_dma->fbr1_full_offset; + min_des = &rx_dma->fbr1_min_des; + base_hi = &rx_dma->fbr1_base_hi; + base_lo = &rx_dma->fbr1_base_lo; + } else { + num_des = &rx_dma->fbr0_num_des; + full_offset = &rx_dma->fbr0_full_offset; + min_des = &rx_dma->fbr0_min_des; + base_hi = &rx_dma->fbr0_base_hi; + base_lo = &rx_dma->fbr0_base_lo; + } - /* Set the address and parameters of Free buffer ring 1 (and 0 if - * required) into the 1310's registers - */ - writel(upper_32_bits(rx_local->fbr[0]->ring_physaddr), - &rx_dma->fbr1_base_hi); - writel(lower_32_bits(rx_local->fbr[0]->ring_physaddr), - &rx_dma->fbr1_base_lo); - writel(rx_local->fbr[0]->num_entries - 1, &rx_dma->fbr1_num_des); - writel(ET_DMA10_WRAP, &rx_dma->fbr1_full_offset); - - /* This variable tracks the free buffer ring 1 full position, so it - * has to match the above. - */ - rx_local->fbr[0]->local_full = ET_DMA10_WRAP; - writel( - ((rx_local->fbr[0]->num_entries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, - &rx_dma->fbr1_min_des); - - /* Now's the best time to initialize FBR0 contents */ - fbr_entry = (struct fbr_desc *) rx_local->fbr[1]->ring_virtaddr; - for (entry = 0; entry < rx_local->fbr[1]->num_entries; entry++) { - fbr_entry->addr_hi = rx_local->fbr[1]->bus_high[entry]; - fbr_entry->addr_lo = rx_local->fbr[1]->bus_low[entry]; - fbr_entry->word2 = entry; - fbr_entry++; - } + /* Now's the best time to initialize FBR contents */ + fbr_entry = (struct fbr_desc *) rx_local->fbr[id]->ring_virtaddr; + for (entry = 0; entry < rx_local->fbr[id]->num_entries; entry++) { + fbr_entry->addr_hi = rx_local->fbr[id]->bus_high[entry]; + fbr_entry->addr_lo = rx_local->fbr[id]->bus_low[entry]; + fbr_entry->word2 = entry; + fbr_entry++; + } - writel(upper_32_bits(rx_local->fbr[1]->ring_physaddr), - &rx_dma->fbr0_base_hi); - writel(lower_32_bits(rx_local->fbr[1]->ring_physaddr), - &rx_dma->fbr0_base_lo); - writel(rx_local->fbr[1]->num_entries - 1, &rx_dma->fbr0_num_des); - writel(ET_DMA10_WRAP, &rx_dma->fbr0_full_offset); + /* Set the address and parameters of Free buffer ring 1 and 0 + * into the 1310's registers + */ + writel(upper_32_bits(rx_local->fbr[id]->ring_physaddr), base_hi); + writel(lower_32_bits(rx_local->fbr[id]->ring_physaddr), base_lo); + writel(rx_local->fbr[id]->num_entries - 1, num_des); + writel(ET_DMA10_WRAP, full_offset); - /* This variable tracks the free buffer ring 0 full position, so it - * has to match the above. - */ - rx_local->fbr[1]->local_full = ET_DMA10_WRAP; - writel( - ((rx_local->fbr[1]->num_entries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, - &rx_dma->fbr0_min_des); + /* This variable tracks the free buffer ring 1 full position, + * so it has to match the above. + */ + rx_local->fbr[id]->local_full = ET_DMA10_WRAP; + writel(((rx_local->fbr[id]->num_entries * + LO_MARK_PERCENT_FOR_RX) / 100) - 1, + min_des); + } /* Program the number of packets we will receive before generating an * interrupt. @@ -2258,7 +2255,8 @@ static inline u32 bump_free_buff_ring(u32 *free_buff_ring, u32 limit) * @mask: correct mask */ static void et131x_align_allocated_memory(struct et131x_adapter *adapter, - dma_addr_t *phys_addr, dma_addr_t *offset, + dma_addr_t *phys_addr, + dma_addr_t *offset, u64 mask) { u64 new_addr = *phys_addr & ~mask; @@ -2286,6 +2284,7 @@ static void et131x_align_allocated_memory(struct et131x_adapter *adapter, */ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) { + u8 id; u32 i, j; u32 bufsize; u32 pktstat_ringsize, fbr_chunksize; @@ -2337,158 +2336,95 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) adapter->rx_ring.fbr[1]->num_entries + adapter->rx_ring.fbr[0]->num_entries; - /* Allocate an area of memory for Free Buffer Ring 1 */ - bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr[0]->num_entries) + - 0xfff; - rx_ring->fbr[0]->ring_virtaddr = dma_alloc_coherent(&adapter->pdev->dev, + for (id = 0; id < NUM_FBRS; id++) { + /* Allocate an area of memory for Free Buffer Ring */ + bufsize = (sizeof(struct fbr_desc) * + rx_ring->fbr[id]->num_entries) + 0xfff; + rx_ring->fbr[id]->ring_virtaddr = + dma_alloc_coherent(&adapter->pdev->dev, bufsize, - &rx_ring->fbr[0]->ring_physaddr, + &rx_ring->fbr[id]->ring_physaddr, GFP_KERNEL); - if (!rx_ring->fbr[0]->ring_virtaddr) { - dev_err(&adapter->pdev->dev, - "Cannot alloc memory for Free Buffer Ring 1\n"); - return -ENOMEM; - } - - /* Align Free Buffer Ring 1 on a 4K boundary */ - et131x_align_allocated_memory(adapter, - &rx_ring->fbr[0]->ring_physaddr, - &rx_ring->fbr[0]->offset, 0x0FFF); - - rx_ring->fbr[0]->ring_virtaddr = - (void *)((u8 *) rx_ring->fbr[0]->ring_virtaddr + - rx_ring->fbr[0]->offset); - - /* Allocate an area of memory for Free Buffer Ring 0 */ - bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr[1]->num_entries) + - 0xfff; - rx_ring->fbr[1]->ring_virtaddr = dma_alloc_coherent(&adapter->pdev->dev, - bufsize, - &rx_ring->fbr[1]->ring_physaddr, - GFP_KERNEL); - if (!rx_ring->fbr[1]->ring_virtaddr) { - dev_err(&adapter->pdev->dev, - "Cannot alloc memory for Free Buffer Ring 0\n"); - return -ENOMEM; - } - - /* Align Free Buffer Ring 0 on a 4K boundary */ - et131x_align_allocated_memory(adapter, - &rx_ring->fbr[1]->ring_physaddr, - &rx_ring->fbr[1]->offset, 0x0FFF); - - rx_ring->fbr[1]->ring_virtaddr = - (void *)((u8 *) rx_ring->fbr[1]->ring_virtaddr + - rx_ring->fbr[1]->offset); - - for (i = 0; i < (rx_ring->fbr[0]->num_entries / FBR_CHUNKS); i++) { - dma_addr_t fbr1_tmp_physaddr; - dma_addr_t fbr1_offset; - u32 fbr1_align; - - /* This code allocates an area of memory big enough for N - * free buffers + (buffer_size - 1) so that the buffers can - * be aligned on 4k boundaries. If each buffer were aligned - * to a buffer_size boundary, the effect would be to double - * the size of FBR0. By allocating N buffers at once, we - * reduce this overhead. - */ - if (rx_ring->fbr[0]->buffsize > 4096) - fbr1_align = 4096; - else - fbr1_align = rx_ring->fbr[0]->buffsize; - - fbr_chunksize = - (FBR_CHUNKS * rx_ring->fbr[0]->buffsize) + fbr1_align - 1; - rx_ring->fbr[0]->mem_virtaddrs[i] = - dma_alloc_coherent(&adapter->pdev->dev, fbr_chunksize, - &rx_ring->fbr[0]->mem_physaddrs[i], - GFP_KERNEL); - - if (!rx_ring->fbr[0]->mem_virtaddrs[i]) { + if (!rx_ring->fbr[id]->ring_virtaddr) { dev_err(&adapter->pdev->dev, - "Could not alloc memory\n"); + "Cannot alloc memory for Free Buffer Ring %d\n", id); return -ENOMEM; } - /* See NOTE in "Save Physical Address" comment above */ - fbr1_tmp_physaddr = rx_ring->fbr[0]->mem_physaddrs[i]; - + /* Align Free Buffer Ring on a 4K boundary */ et131x_align_allocated_memory(adapter, - &fbr1_tmp_physaddr, - &fbr1_offset, (fbr1_align - 1)); + &rx_ring->fbr[id]->ring_physaddr, + &rx_ring->fbr[id]->offset, 0x0FFF); - for (j = 0; j < FBR_CHUNKS; j++) { - u32 index = (i * FBR_CHUNKS) + j; - - /* Save the Virtual address of this index for quick - * access later - */ - rx_ring->fbr[0]->virt[index] = - (u8 *) rx_ring->fbr[0]->mem_virtaddrs[i] + - (j * rx_ring->fbr[0]->buffsize) + fbr1_offset; - - /* now store the physical address in the descriptor - * so the device can access it - */ - rx_ring->fbr[0]->bus_high[index] = - upper_32_bits(fbr1_tmp_physaddr); - rx_ring->fbr[0]->bus_low[index] = - lower_32_bits(fbr1_tmp_physaddr); - - fbr1_tmp_physaddr += rx_ring->fbr[0]->buffsize; - - rx_ring->fbr[0]->buffer1[index] = - rx_ring->fbr[0]->virt[index]; - rx_ring->fbr[0]->buffer2[index] = - rx_ring->fbr[0]->virt[index] - 4; - } + rx_ring->fbr[id]->ring_virtaddr = + (void *)((u8 *) rx_ring->fbr[id]->ring_virtaddr + + rx_ring->fbr[id]->offset); } - /* Same for FBR0 (if in use) */ - for (i = 0; i < (rx_ring->fbr[1]->num_entries / FBR_CHUNKS); i++) { - dma_addr_t fbr0_tmp_physaddr; - dma_addr_t fbr0_offset; + for (id = 0; id < NUM_FBRS; id++) { + for (i = 0; i < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); i++) { + dma_addr_t fbr_tmp_physaddr; + dma_addr_t fbr_offset; + u32 fbr_align; + + /* This code allocates an area of memory big enough for + * N free buffers + (buffer_size - 1) so that the + * buffers can be aligned on 4k boundaries. If each + * buffer were aligned to a buffer_size boundary, the + * effect would be to double the size of FBR0. By + * allocating N buffers at once, we reduce this overhead + */ + if (id == 0 && rx_ring->fbr[id]->buffsize > 4096) + fbr_align = 4096; + else + fbr_align = rx_ring->fbr[id]->buffsize; - fbr_chunksize = - ((FBR_CHUNKS + 1) * rx_ring->fbr[1]->buffsize) - 1; - rx_ring->fbr[1]->mem_virtaddrs[i] = - dma_alloc_coherent(&adapter->pdev->dev, fbr_chunksize, - &rx_ring->fbr[1]->mem_physaddrs[i], - GFP_KERNEL); + fbr_chunksize = (FBR_CHUNKS * + rx_ring->fbr[id]->buffsize) + fbr_align - 1; + rx_ring->fbr[id]->mem_virtaddrs[i] = dma_alloc_coherent( + &adapter->pdev->dev, fbr_chunksize, + &rx_ring->fbr[id]->mem_physaddrs[i], + GFP_KERNEL); - if (!rx_ring->fbr[1]->mem_virtaddrs[i]) { - dev_err(&adapter->pdev->dev, - "Could not alloc memory\n"); - return -ENOMEM; - } + if (!rx_ring->fbr[id]->mem_virtaddrs[i]) { + dev_err(&adapter->pdev->dev, + "Could not alloc memory\n"); + return -ENOMEM; + } - /* See NOTE in "Save Physical Address" comment above */ - fbr0_tmp_physaddr = rx_ring->fbr[1]->mem_physaddrs[i]; + /* See NOTE in "Save Physical Address" comment above */ + fbr_tmp_physaddr = rx_ring->fbr[id]->mem_physaddrs[i]; - et131x_align_allocated_memory(adapter, - &fbr0_tmp_physaddr, - &fbr0_offset, - rx_ring->fbr[1]->buffsize - 1); + et131x_align_allocated_memory(adapter, + &fbr_tmp_physaddr, + &fbr_offset, + (fbr_align - 1)); - for (j = 0; j < FBR_CHUNKS; j++) { - u32 index = (i * FBR_CHUNKS) + j; + for (j = 0; j < FBR_CHUNKS; j++) { + u32 index = (i * FBR_CHUNKS) + j; - rx_ring->fbr[1]->virt[index] = - (u8 *) rx_ring->fbr[1]->mem_virtaddrs[i] + - (j * rx_ring->fbr[1]->buffsize) + fbr0_offset; + /* Save the Virtual address of this index for + * quick access later + */ + rx_ring->fbr[id]->virt[index] = + (u8 *) rx_ring->fbr[id]->mem_virtaddrs[i] + + (j * rx_ring->fbr[id]->buffsize) + fbr_offset; - rx_ring->fbr[1]->bus_high[index] = - upper_32_bits(fbr0_tmp_physaddr); - rx_ring->fbr[1]->bus_low[index] = - lower_32_bits(fbr0_tmp_physaddr); + /* now store the physical address in the + * descriptor so the device can access it + */ + rx_ring->fbr[id]->bus_high[index] = + upper_32_bits(fbr_tmp_physaddr); + rx_ring->fbr[id]->bus_low[index] = + lower_32_bits(fbr_tmp_physaddr); - fbr0_tmp_physaddr += rx_ring->fbr[1]->buffsize; + fbr_tmp_physaddr += rx_ring->fbr[id]->buffsize; - rx_ring->fbr[1]->buffer1[index] = - rx_ring->fbr[1]->virt[index]; - rx_ring->fbr[1]->buffer2[index] = - rx_ring->fbr[1]->virt[index] - 4; + rx_ring->fbr[id]->buffer1[index] = + rx_ring->fbr[id]->virt[index]; + rx_ring->fbr[id]->buffer2[index] = + rx_ring->fbr[id]->virt[index] - 4; + } } } @@ -2557,6 +2493,7 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) */ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) { + u8 id; u32 index; u32 bufsize; u32 pktstat_ringsize; @@ -2578,80 +2515,48 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) kmem_cache_free(adapter->rx_ring.recv_lookaside, rfd); } - /* Free Free Buffer Ring 1 */ - if (rx_ring->fbr[0]->ring_virtaddr) { - /* First the packet memory */ - for (index = 0; index < - (rx_ring->fbr[0]->num_entries / FBR_CHUNKS); index++) { - if (rx_ring->fbr[0]->mem_virtaddrs[index]) { - u32 fbr1_align; - - if (rx_ring->fbr[0]->buffsize > 4096) - fbr1_align = 4096; - else - fbr1_align = rx_ring->fbr[0]->buffsize; - - bufsize = - (rx_ring->fbr[0]->buffsize * FBR_CHUNKS) + - fbr1_align - 1; - - dma_free_coherent(&adapter->pdev->dev, - bufsize, - rx_ring->fbr[0]->mem_virtaddrs[index], - rx_ring->fbr[0]->mem_physaddrs[index]); + /* Free Free Buffer Rings */ + for (id = 0; id < NUM_FBRS; id++) { + if (rx_ring->fbr[id]->ring_virtaddr) { + /* First the packet memory */ + for (index = 0; index < + (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); + index++) { + if (rx_ring->fbr[id]->mem_virtaddrs[index]) { + u32 fbr_align; + + if (rx_ring->fbr[id]->buffsize > 4096) + fbr_align = 4096; + else + fbr_align = rx_ring->fbr[id]->buffsize; + + bufsize = + (rx_ring->fbr[id]->buffsize * FBR_CHUNKS) + + fbr_align - 1; + + dma_free_coherent(&adapter->pdev->dev, + bufsize, + rx_ring->fbr[id]->mem_virtaddrs[index], + rx_ring->fbr[id]->mem_physaddrs[index]); - rx_ring->fbr[0]->mem_virtaddrs[index] = NULL; + rx_ring->fbr[id]->mem_virtaddrs[index] = NULL; + } } - } - - /* Now the FIFO itself */ - rx_ring->fbr[0]->ring_virtaddr = (void *)((u8 *) - rx_ring->fbr[0]->ring_virtaddr - rx_ring->fbr[0]->offset); - - bufsize = - (sizeof(struct fbr_desc) * rx_ring->fbr[0]->num_entries) + - 0xfff; - dma_free_coherent(&adapter->pdev->dev, bufsize, - rx_ring->fbr[0]->ring_virtaddr, - rx_ring->fbr[0]->ring_physaddr); + /* Now the FIFO itself */ + rx_ring->fbr[id]->ring_virtaddr = (void *)((u8 *) + rx_ring->fbr[id]->ring_virtaddr - rx_ring->fbr[id]->offset); - rx_ring->fbr[0]->ring_virtaddr = NULL; - } + bufsize = + (sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries) + + 0xfff; - /* Now the same for Free Buffer Ring 0 */ - if (rx_ring->fbr[1]->ring_virtaddr) { - /* First the packet memory */ - for (index = 0; index < - (rx_ring->fbr[1]->num_entries / FBR_CHUNKS); index++) { - if (rx_ring->fbr[1]->mem_virtaddrs[index]) { - bufsize = - (rx_ring->fbr[1]->buffsize * - (FBR_CHUNKS + 1)) - 1; - - dma_free_coherent(&adapter->pdev->dev, - bufsize, - rx_ring->fbr[1]->mem_virtaddrs[index], - rx_ring->fbr[1]->mem_physaddrs[index]); + dma_free_coherent(&adapter->pdev->dev, bufsize, + rx_ring->fbr[id]->ring_virtaddr, + rx_ring->fbr[id]->ring_physaddr); - rx_ring->fbr[1]->mem_virtaddrs[index] = NULL; - } + rx_ring->fbr[id]->ring_virtaddr = NULL; } - - /* Now the FIFO itself */ - rx_ring->fbr[1]->ring_virtaddr = (void *)((u8 *) - rx_ring->fbr[1]->ring_virtaddr - rx_ring->fbr[1]->offset); - - bufsize = - (sizeof(struct fbr_desc) * rx_ring->fbr[1]->num_entries) + - 0xfff; - - dma_free_coherent(&adapter->pdev->dev, - bufsize, - rx_ring->fbr[1]->ring_virtaddr, - rx_ring->fbr[1]->ring_physaddr); - - rx_ring->fbr[1]->ring_virtaddr = NULL; } /* Free Packet Status Ring */ @@ -2780,43 +2685,36 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) if ( (ring_index == 0 && buff_index < rx_local->fbr[1]->num_entries) || (ring_index == 1 && buff_index < rx_local->fbr[0]->num_entries)) { + u32 *offset; + u8 id; + struct fbr_desc *next; + spin_lock_irqsave(&adapter->fbr_lock, flags); if (ring_index == 1) { - struct fbr_desc *next = (struct fbr_desc *) - (rx_local->fbr[0]->ring_virtaddr) + - INDEX10(rx_local->fbr[0]->local_full); - - /* Handle the Free Buffer Ring advancement here. Write - * the PA / Buffer Index for the returned buffer into - * the oldest (next to be freed)FBR entry - */ - next->addr_hi = rx_local->fbr[0]->bus_high[buff_index]; - next->addr_lo = rx_local->fbr[0]->bus_low[buff_index]; - next->word2 = buff_index; - - writel(bump_free_buff_ring( - &rx_local->fbr[0]->local_full, - rx_local->fbr[0]->num_entries - 1), - &rx_dma->fbr1_full_offset); + id = 0; + offset = &rx_dma->fbr1_full_offset; } else { - struct fbr_desc *next = (struct fbr_desc *) - rx_local->fbr[1]->ring_virtaddr + - INDEX10(rx_local->fbr[1]->local_full); - - /* Handle the Free Buffer Ring advancement here. Write - * the PA / Buffer Index for the returned buffer into - * the oldest (next to be freed) FBR entry - */ - next->addr_hi = rx_local->fbr[1]->bus_high[buff_index]; - next->addr_lo = rx_local->fbr[1]->bus_low[buff_index]; - next->word2 = buff_index; - - writel(bump_free_buff_ring( - &rx_local->fbr[1]->local_full, - rx_local->fbr[1]->num_entries - 1), - &rx_dma->fbr0_full_offset); + id = 1; + offset = &rx_dma->fbr0_full_offset; } + + next = (struct fbr_desc *) (rx_local->fbr[id]->ring_virtaddr) + + INDEX10(rx_local->fbr[id]->local_full); + + /* Handle the Free Buffer Ring advancement here. Write + * the PA / Buffer Index for the returned buffer into + * the oldest (next to be freed)FBR entry + */ + next->addr_hi = rx_local->fbr[id]->bus_high[buff_index]; + next->addr_lo = rx_local->fbr[id]->bus_low[buff_index]; + next->word2 = buff_index; + + writel(bump_free_buff_ring( + &rx_local->fbr[id]->local_full, + rx_local->fbr[id]->num_entries - 1), + offset); + spin_unlock_irqrestore(&adapter->fbr_lock, flags); } else { dev_err(&adapter->pdev->dev, -- cgit v1.2.3 From 242187aa7b015ea11c3d8dc3a86a3dc2b098c79d Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Tue, 30 Oct 2012 18:38:55 +0000 Subject: staging: et131x: Refactor nic_rx_pkts() to remove indenting In nic_rx_pkts() some large chunks of code are indented in 'if (len)' sections. Refactor the code to remove these indents and re-join longer split lines. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 201 ++++++++++++++++++---------------------- 1 file changed, 88 insertions(+), 113 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 67fa1eff26b..2386899ebee 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -2561,9 +2561,8 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) /* Free Packet Status Ring */ if (rx_ring->ps_ring_virtaddr) { - pktstat_ringsize = - sizeof(struct pkt_stat_desc) * - adapter->rx_ring.psr_num_entries; + pktstat_ringsize = sizeof(struct pkt_stat_desc) * + adapter->rx_ring.psr_num_entries; dma_free_coherent(&adapter->pdev->dev, pktstat_ringsize, rx_ring->ps_ring_virtaddr, @@ -2748,7 +2747,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) struct rx_ring *rx_local = &adapter->rx_ring; struct rx_status_block *status; struct pkt_stat_desc *psr; - struct rfd *rfd; + struct rfd *rfd = NULL; u32 i; u8 *buf; unsigned long flags; @@ -2758,6 +2757,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) u32 len; u32 word0; u32 word1; + struct sk_buff *skb = NULL; /* RX Status block is written by the DMA engine prior to every * interrupt. It contains the next to be used entry in the Packet @@ -2768,16 +2768,14 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) /* Check the PSR and wrap bits do not match */ if ((word1 & 0x1FFF) == (rx_local->local_psr_full & 0x1FFF)) - /* Looks like this ring is not updated yet */ - return NULL; + return NULL; /* Looks like this ring is not updated yet */ /* The packet status ring indicates that data is available. */ psr = (struct pkt_stat_desc *) (rx_local->ps_ring_virtaddr) + (rx_local->local_psr_full & 0xFFF); - /* Grab any information that is required once the PSR is - * advanced, since we can no longer rely on the memory being - * accurate + /* Grab any information that is required once the PSR is advanced, + * since we can no longer rely on the memory being accurate */ len = psr->word1 & 0xFFFF; ring_index = (psr->word1 >> 26) & 0x03; @@ -2794,8 +2792,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) rx_local->local_psr_full ^= 0x1000; } - writel(rx_local->local_psr_full, - &adapter->regs->rxdma.psr_full_offset); + writel(rx_local->local_psr_full, &adapter->regs->rxdma.psr_full_offset); if (ring_index > 1 || (ring_index == 0 && @@ -2804,21 +2801,18 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) buff_index > rx_local->fbr[0]->num_entries - 1)) { /* Illegal buffer or ring index cannot be used by S/W*/ dev_err(&adapter->pdev->dev, - "NICRxPkts PSR Entry %d indicates " - "length of %d and/or bad bi(%d)\n", - rx_local->local_psr_full & 0xFFF, - len, buff_index); + "NICRxPkts PSR Entry %d indicates length of %d and/or bad bi(%d)\n", + rx_local->local_psr_full & 0xFFF, len, buff_index); return NULL; } /* Get and fill the RFD. */ spin_lock_irqsave(&adapter->rcv_lock, flags); - rfd = NULL; element = rx_local->recv_list.next; rfd = (struct rfd *) list_entry(element, struct rfd, list_node); - if (rfd == NULL) { + if (!rfd) { spin_unlock_irqrestore(&adapter->rcv_lock, flags); return NULL; } @@ -2831,119 +2825,101 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) rfd->bufferindex = buff_index; rfd->ringindex = ring_index; - /* In V1 silicon, there is a bug which screws up filtering of - * runt packets. Therefore runt packet filtering is disabled - * in the MAC and the packets are dropped here. They are - * also counted here. + /* In V1 silicon, there is a bug which screws up filtering of runt + * packets. Therefore runt packet filtering is disabled in the MAC and + * the packets are dropped here. They are also counted here. */ if (len < (NIC_MIN_PACKET_SIZE + 4)) { adapter->stats.rx_other_errs++; len = 0; } - if (len) { - /* Determine if this is a multicast packet coming in */ - if ((word0 & ALCATEL_MULTICAST_PKT) && - !(word0 & ALCATEL_BROADCAST_PKT)) { - /* Promiscuous mode and Multicast mode are - * not mutually exclusive as was first - * thought. I guess Promiscuous is just - * considered a super-set of the other - * filters. Generally filter is 0x2b when in - * promiscuous mode. - */ - if ((adapter->packet_filter & - ET131X_PACKET_TYPE_MULTICAST) - && !(adapter->packet_filter & - ET131X_PACKET_TYPE_PROMISCUOUS) - && !(adapter->packet_filter & + if (len == 0) { + rfd->len = 0; + goto out; + } + + /* Determine if this is a multicast packet coming in */ + if ((word0 & ALCATEL_MULTICAST_PKT) && + !(word0 & ALCATEL_BROADCAST_PKT)) { + /* Promiscuous mode and Multicast mode are not mutually + * exclusive as was first thought. I guess Promiscuous is just + * considered a super-set of the other filters. Generally filter + * is 0x2b when in promiscuous mode. + */ + if ((adapter->packet_filter & ET131X_PACKET_TYPE_MULTICAST) + && !(adapter->packet_filter & ET131X_PACKET_TYPE_PROMISCUOUS) + && !(adapter->packet_filter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { - /* - * Note - ring_index for fbr[] array is reversed - * 1 for FBR0 etc - */ - buf = rx_local->fbr[(ring_index == 0 ? 1 : 0)]-> - virt[buff_index]; + /* + * Note - ring_index for fbr[] array is reversed + * 1 for FBR0 etc + */ + buf = rx_local->fbr[(ring_index == 0 ? 1 : 0)]-> + virt[buff_index]; - /* Loop through our list to see if the - * destination address of this packet - * matches one in our list. - */ - for (i = 0; i < adapter->multicast_addr_count; - i++) { - if (buf[0] == - adapter->multicast_list[i][0] - && buf[1] == - adapter->multicast_list[i][1] - && buf[2] == - adapter->multicast_list[i][2] - && buf[3] == - adapter->multicast_list[i][3] - && buf[4] == - adapter->multicast_list[i][4] - && buf[5] == - adapter->multicast_list[i][5]) { - break; - } + /* Loop through our list to see if the destination + * address of this packet matches one in our list. + */ + for (i = 0; i < adapter->multicast_addr_count; i++) { + if (buf[0] == adapter->multicast_list[i][0] + && buf[1] == adapter->multicast_list[i][1] + && buf[2] == adapter->multicast_list[i][2] + && buf[3] == adapter->multicast_list[i][3] + && buf[4] == adapter->multicast_list[i][4] + && buf[5] == adapter->multicast_list[i][5]) { + break; } - - /* If our index is equal to the number - * of Multicast address we have, then - * this means we did not find this - * packet's matching address in our - * list. Set the len to zero, - * so we free our RFD when we return - * from this function. - */ - if (i == adapter->multicast_addr_count) - len = 0; } - if (len > 0) - adapter->stats.multicast_pkts_rcvd++; - } else if (word0 & ALCATEL_BROADCAST_PKT) - adapter->stats.broadcast_pkts_rcvd++; - else - /* Not sure what this counter measures in - * promiscuous mode. Perhaps we should check - * the MAC address to see if it is directed - * to us in promiscuous mode. + /* If our index is equal to the number of Multicast + * address we have, then this means we did not find this + * packet's matching address in our list. Set the len to + * zero, so we free our RFD when we return from this + * function. */ - adapter->stats.unicast_pkts_rcvd++; - } + if (i == adapter->multicast_addr_count) + len = 0; + } - if (len > 0) { - struct sk_buff *skb = NULL; + if (len > 0) + adapter->stats.multicast_pkts_rcvd++; + } else if (word0 & ALCATEL_BROADCAST_PKT) { + adapter->stats.broadcast_pkts_rcvd++; + } else { + /* Not sure what this counter measures in promiscuous mode. + * Perhaps we should check the MAC address to see if it is + * directed to us in promiscuous mode. + */ + adapter->stats.unicast_pkts_rcvd++; + } - /*rfd->len = len - 4; */ - rfd->len = len; + if (len == 0) { + rfd->len = 0; + goto out; + } - skb = dev_alloc_skb(rfd->len + 2); - if (!skb) { - dev_err(&adapter->pdev->dev, - "Couldn't alloc an SKB for Rx\n"); - return NULL; - } + rfd->len = len; - adapter->net_stats.rx_bytes += rfd->len; + skb = dev_alloc_skb(rfd->len + 2); + if (!skb) { + dev_err(&adapter->pdev->dev, "Couldn't alloc an SKB for Rx\n"); + return NULL; + } - /* - * Note - ring_index for fbr[] array is reversed, - * 1 for FBR0 etc - */ - memcpy(skb_put(skb, rfd->len), - rx_local->fbr[(ring_index == 0 ? 1 : 0)]->virt[buff_index], - rfd->len); + adapter->net_stats.rx_bytes += rfd->len; - skb->dev = adapter->netdev; - skb->protocol = eth_type_trans(skb, adapter->netdev); - skb->ip_summed = CHECKSUM_NONE; + /* Note - ring_index for fbr[] array is reversed, 1 for FBR0 etc */ + memcpy(skb_put(skb, rfd->len), + rx_local->fbr[(ring_index == 0 ? 1 : 0)]->virt[buff_index], + rfd->len); - netif_rx_ni(skb); - } else { - rfd->len = 0; - } + skb->dev = adapter->netdev; + skb->protocol = eth_type_trans(skb, adapter->netdev); + skb->ip_summed = CHECKSUM_NONE; + netif_rx_ni(skb); +out: nic_return_rfd(adapter, rfd); return rfd; } @@ -3740,7 +3716,7 @@ static struct ethtool_ops et131x_ethtool_ops = { .get_drvinfo = et131x_get_drvinfo, .get_regs_len = et131x_get_regs_len, .get_regs = et131x_get_regs, - .get_link = ethtool_op_get_link, + .get_link = ethtool_op_get_link, }; /** * et131x_hwaddr_init - set up the MAC Address on the ET1310 @@ -3907,8 +3883,7 @@ static void et131x_error_timer_handler(unsigned long data) } /* This is a periodic timer, so reschedule */ - mod_timer(&adapter->error_timer, jiffies + - TX_ERROR_PERIOD * HZ / 1000); + mod_timer(&adapter->error_timer, jiffies + TX_ERROR_PERIOD * HZ / 1000); } /** -- cgit v1.2.3 From 96d3927868c95d464b59a36fced4b184b8e3082d Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Tue, 30 Oct 2012 18:38:56 +0000 Subject: staging: et131x: Update TODO list in README -Added some extra items to the TODO list. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/README | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/et131x/README b/drivers/staging/et131x/README index 82657233c8b..474a6f58f8d 100644 --- a/drivers/staging/et131x/README +++ b/drivers/staging/et131x/README @@ -9,6 +9,7 @@ driver as they did not build properly at the time. TODO: - Use of kmem_cache seems a bit unusual + - some rx packets have CRC/code/frame errors Please send patches to: Greg Kroah-Hartman -- cgit v1.2.3 From 186c426ddfb8ba31eac5c6e82dcbac74f7e531dd Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Tue, 30 Oct 2012 18:38:57 +0000 Subject: staging: et131x: Remove unnecessary NULL pointer assignments During a previous refactoring excerise, two NULL pointer assingments were moved to their respective pointer declarations. Dan Carpenter correctly points out that these assignments are not needed. Removing them. Also two small whitespace changes - rejoining split lines, as they are now less than 80 chars. Reported-by: Dan Carpenter Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 2386899ebee..84544fccfc2 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -2681,8 +2681,7 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) /* We don't use any of the OOB data besides status. Otherwise, we * need to clean up OOB data */ - if ( - (ring_index == 0 && buff_index < rx_local->fbr[1]->num_entries) || + if ((ring_index == 0 && buff_index < rx_local->fbr[1]->num_entries) || (ring_index == 1 && buff_index < rx_local->fbr[0]->num_entries)) { u32 *offset; u8 id; @@ -2709,10 +2708,9 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) next->addr_lo = rx_local->fbr[id]->bus_low[buff_index]; next->word2 = buff_index; - writel(bump_free_buff_ring( - &rx_local->fbr[id]->local_full, - rx_local->fbr[id]->num_entries - 1), - offset); + writel(bump_free_buff_ring(&rx_local->fbr[id]->local_full, + rx_local->fbr[id]->num_entries - 1), + offset); spin_unlock_irqrestore(&adapter->fbr_lock, flags); } else { @@ -2747,7 +2745,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) struct rx_ring *rx_local = &adapter->rx_ring; struct rx_status_block *status; struct pkt_stat_desc *psr; - struct rfd *rfd = NULL; + struct rfd *rfd; u32 i; u8 *buf; unsigned long flags; @@ -2757,7 +2755,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) u32 len; u32 word0; u32 word1; - struct sk_buff *skb = NULL; + struct sk_buff *skb; /* RX Status block is written by the DMA engine prior to every * interrupt. It contains the next to be used entry in the Packet -- cgit v1.2.3 From c35eb3ae5797759d3b7dd05cf211d9b52282f00c Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Tue, 30 Oct 2012 18:38:58 +0000 Subject: staging: et131x: Remove unnecessary PHY register write The PHY registers are now being controlled from the connected phydev, so there shouldn't be any reason for the et131x code to perform any extra setup. Removing the interrupt setup code, and register defines that are now unused. On testing, no changes in behaviour were experienced. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 16 +--------------- drivers/staging/et131x/et131x.h | 4 ---- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 84544fccfc2..daa5247bd01 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -1749,22 +1749,8 @@ static void et1310_phy_power_down(struct et131x_adapter *adapter, bool down) */ static void et131x_xcvr_init(struct et131x_adapter *adapter) { - u16 imr; - u16 isr; u16 lcr2; - et131x_mii_read(adapter, PHY_INTERRUPT_STATUS, &isr); - et131x_mii_read(adapter, PHY_INTERRUPT_MASK, &imr); - - /* Set the link status interrupt only. Bad behavior when link status - * and auto neg are set, we run into a nested interrupt problem - */ - imr |= (ET_PHY_INT_MASK_AUTONEGSTAT | - ET_PHY_INT_MASK_LINKSTAT | - ET_PHY_INT_MASK_ENABLE); - - et131x_mii_write(adapter, PHY_INTERRUPT_MASK, imr); - /* Set the LED behavior such that LED 1 indicates speed (off = * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates * link and activity (on for link, blink off for activity). @@ -1789,7 +1775,7 @@ static void et131x_xcvr_init(struct et131x_adapter *adapter) } /** - * et131x_configure_global_regs - configure JAGCore global regs + * et131x_configure_global_regs - configure JAGCore global regs * @adapter: pointer to our adapter structure * * Used to configure the global registers on the JAGCore diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h index 864379b4e8d..347e63ddde1 100644 --- a/drivers/staging/et131x/et131x.h +++ b/drivers/staging/et131x/et131x.h @@ -1538,10 +1538,6 @@ struct address_map { * 0: int_en */ -#define ET_PHY_INT_MASK_AUTONEGSTAT 0x0100 -#define ET_PHY_INT_MASK_LINKSTAT 0x0004 -#define ET_PHY_INT_MASK_ENABLE 0x0001 - /* MI Register 25: Interrupt Status Reg(0x19) * 15-10: reserved * 9: mdio_sync_lost -- cgit v1.2.3 From f2ec522e78ef5cdc12d1dbecf254cdf31eb2b6d3 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 28 Oct 2012 01:05:51 -0700 Subject: usb: Convert dev_printk(KERN_ to dev_( dev_ calls take less code than dev_printk(KERN_ and reducing object size is good. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 5b131b6477d..fbaf3c3dbf0 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2055,7 +2055,7 @@ static void show_string(struct usb_device *udev, char *id, char *string) { if (!string) return; - dev_printk(KERN_INFO, &udev->dev, "%s: %s\n", id, string); + dev_info(&udev->dev, "%s: %s\n", id, string); } static void announce_device(struct usb_device *udev) -- cgit v1.2.3 From f145b4f4dd70865e15dce92a93ad38b489935293 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 30 Oct 2012 15:18:37 -0400 Subject: staging: csr: io.c: replace spaces with tabs replace the spaces with the tabs at the start of line Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/io.c | 86 ++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/drivers/staging/csr/io.c b/drivers/staging/csr/io.c index 0f40b00ad4d..af9c28f073b 100644 --- a/drivers/staging/csr/io.c +++ b/drivers/staging/csr/io.c @@ -1000,37 +1000,37 @@ uf_remove_os_device(int bus_id) static void uf_sdio_inserted(CsrSdioFunction *sdio_ctx) { - unifi_priv_t *priv; + unifi_priv_t *priv; - unifi_trace(NULL, UDBG5, "uf_sdio_inserted(0x%p), slot_id=%d, dev=%p\n", - sdio_ctx, active_slot, os_devices[active_slot]); + unifi_trace(NULL, UDBG5, "uf_sdio_inserted(0x%p), slot_id=%d, dev=%p\n", + sdio_ctx, active_slot, os_devices[active_slot]); - priv = register_unifi_sdio(sdio_ctx, active_slot, os_devices[active_slot]); - if (priv == NULL) { - CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_FAILURE); - return; - } + priv = register_unifi_sdio(sdio_ctx, active_slot, os_devices[active_slot]); + if (priv == NULL) { + CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_FAILURE); + return; + } - sdio_ctx->driverData = priv; + sdio_ctx->driverData = priv; - CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS); + CsrSdioInsertedAcknowledge(sdio_ctx, CSR_RESULT_SUCCESS); } /* uf_sdio_inserted() */ static void uf_sdio_removed(CsrSdioFunction *sdio_ctx) { - unregister_unifi_sdio(active_slot); - CsrSdioRemovedAcknowledge(sdio_ctx); + unregister_unifi_sdio(active_slot); + CsrSdioRemovedAcknowledge(sdio_ctx); } /* uf_sdio_removed() */ static void uf_sdio_dsr_handler(CsrSdioFunction *sdio_ctx) { - unifi_priv_t *priv = sdio_ctx->driverData; + unifi_priv_t *priv = sdio_ctx->driverData; - unifi_sdio_interrupt_handler(priv->card); + unifi_sdio_interrupt_handler(priv->card); } /* uf_sdio_dsr_handler() */ /* @@ -1052,7 +1052,7 @@ uf_sdio_dsr_handler(CsrSdioFunction *sdio_ctx) static CsrSdioInterruptDsrCallback uf_sdio_int_handler(CsrSdioFunction *sdio_ctx) { - return uf_sdio_dsr_handler; + return uf_sdio_dsr_handler; } /* uf_sdio_int_handler() */ @@ -1060,18 +1060,18 @@ uf_sdio_int_handler(CsrSdioFunction *sdio_ctx) static CsrSdioFunctionId unifi_ids[] = { - { - .manfId = SDIO_MANF_ID_CSR, - .cardId = SDIO_CARD_ID_UNIFI_3, - .sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_3, - .sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE, - }, - { - .manfId = SDIO_MANF_ID_CSR, - .cardId = SDIO_CARD_ID_UNIFI_4, - .sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_4, - .sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE, - } + { + .manfId = SDIO_MANF_ID_CSR, + .cardId = SDIO_CARD_ID_UNIFI_3, + .sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_3, + .sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE, + }, + { + .manfId = SDIO_MANF_ID_CSR, + .cardId = SDIO_CARD_ID_UNIFI_4, + .sdioFunction = SDIO_WLAN_FUNC_ID_UNIFI_4, + .sdioInterface = CSR_SDIO_ANY_SDIO_INTERFACE, + } }; @@ -1080,14 +1080,14 @@ static CsrSdioFunctionId unifi_ids[] = */ static CsrSdioFunctionDriver unifi_sdioFunction_drv = { - .inserted = uf_sdio_inserted, - .removed = uf_sdio_removed, - .intr = uf_sdio_int_handler, - .suspend = uf_lx_suspend, - .resume = uf_lx_resume, - - .ids = unifi_ids, - .idsCount = sizeof(unifi_ids) / sizeof(unifi_ids[0]) + .inserted = uf_sdio_inserted, + .removed = uf_sdio_removed, + .intr = uf_sdio_int_handler, + .suspend = uf_lx_suspend, + .resume = uf_lx_resume, + + .ids = unifi_ids, + .idsCount = sizeof(unifi_ids) / sizeof(unifi_ids[0]) }; @@ -1110,15 +1110,15 @@ static CsrSdioFunctionDriver unifi_sdioFunction_drv = int __init uf_sdio_load(void) { - CsrResult csrResult; + CsrResult csrResult; - csrResult = CsrSdioFunctionDriverRegister(&unifi_sdioFunction_drv); - if (csrResult != CSR_RESULT_SUCCESS) { - unifi_error(NULL, "Failed to register UniFi SDIO driver: csrResult=%d\n", csrResult); - return -EIO; - } + csrResult = CsrSdioFunctionDriverRegister(&unifi_sdioFunction_drv); + if (csrResult != CSR_RESULT_SUCCESS) { + unifi_error(NULL, "Failed to register UniFi SDIO driver: csrResult=%d\n", csrResult); + return -EIO; + } - return 0; + return 0; } /* uf_sdio_load() */ @@ -1126,6 +1126,6 @@ uf_sdio_load(void) void __exit uf_sdio_unload(void) { - CsrSdioFunctionDriverUnregister(&unifi_sdioFunction_drv); + CsrSdioFunctionDriverUnregister(&unifi_sdioFunction_drv); } /* uf_sdio_unload() */ -- cgit v1.2.3 From a319cefe328e824b5fa771b4caa27c6e208707a9 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 30 Oct 2012 15:18:38 -0400 Subject: staging: csr: drv.c: replace spaces with tabs replace spaces at the start of the line with tabs Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/drv.c | 53 +++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c index e92c8d2f1e8..52344d5c200 100644 --- a/drivers/staging/csr/drv.c +++ b/drivers/staging/csr/drv.c @@ -166,33 +166,32 @@ s32 CsrHipResultToStatus(CsrResult csrResult) static const char* trace_putest_cmdid(unifi_putest_command_t putest_cmd) { - switch (putest_cmd) - { - case UNIFI_PUTEST_START: - return "START"; - case UNIFI_PUTEST_STOP: - return "STOP"; - case UNIFI_PUTEST_SET_SDIO_CLOCK: - return "SET CLOCK"; - case UNIFI_PUTEST_CMD52_READ: - return "CMD52R"; - case UNIFI_PUTEST_CMD52_BLOCK_READ: - return "CMD52BR"; - case UNIFI_PUTEST_CMD52_WRITE: - return "CMD52W"; - case UNIFI_PUTEST_DL_FW: - return "D/L FW"; - case UNIFI_PUTEST_DL_FW_BUFF: - return "D/L FW BUFFER"; - case UNIFI_PUTEST_COREDUMP_PREPARE: - return "PREPARE COREDUMP"; - case UNIFI_PUTEST_GP_READ16: - return "GP16R"; - case UNIFI_PUTEST_GP_WRITE16: - return "GP16W"; - default: - return "ERROR: unrecognised command"; - } + switch (putest_cmd) { + case UNIFI_PUTEST_START: + return "START"; + case UNIFI_PUTEST_STOP: + return "STOP"; + case UNIFI_PUTEST_SET_SDIO_CLOCK: + return "SET CLOCK"; + case UNIFI_PUTEST_CMD52_READ: + return "CMD52R"; + case UNIFI_PUTEST_CMD52_BLOCK_READ: + return "CMD52BR"; + case UNIFI_PUTEST_CMD52_WRITE: + return "CMD52W"; + case UNIFI_PUTEST_DL_FW: + return "D/L FW"; + case UNIFI_PUTEST_DL_FW_BUFF: + return "D/L FW BUFFER"; + case UNIFI_PUTEST_COREDUMP_PREPARE: + return "PREPARE COREDUMP"; + case UNIFI_PUTEST_GP_READ16: + return "GP16R"; + case UNIFI_PUTEST_GP_WRITE16: + return "GP16W"; + default: + return "ERROR: unrecognised command"; + } } #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE -- cgit v1.2.3 From ffe6d91cdb3ff26d8287286e2af41ccb1302dfbf Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 30 Oct 2012 15:18:39 -0400 Subject: staging: csr: drv.c: replace spaces with tabs in uf_destroy_device_nodes replace spaces at the start of line with tabs Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/csr/drv.c b/drivers/staging/csr/drv.c index 52344d5c200..4780c32c2fe 100644 --- a/drivers/staging/csr/drv.c +++ b/drivers/staging/csr/drv.c @@ -2018,10 +2018,10 @@ int uf_create_device_nodes(unifi_priv_t *priv, int bus_id) void uf_destroy_device_nodes(unifi_priv_t *priv) { - device_destroy(unifi_class, priv->unifiudi_cdev.dev); - device_destroy(unifi_class, priv->unifi_cdev.dev); - cdev_del(&priv->unifiudi_cdev); - cdev_del(&priv->unifi_cdev); + device_destroy(unifi_class, priv->unifiudi_cdev.dev); + device_destroy(unifi_class, priv->unifi_cdev.dev); + cdev_del(&priv->unifiudi_cdev); + cdev_del(&priv->unifi_cdev); } -- cgit v1.2.3 From 958bcf5b36f5bbe7b5a3bb423181f8b745bfe23b Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 30 Oct 2012 15:18:40 -0400 Subject: staging: csr: os.c: remove col variable theres no point in checking the col variable, its always zero, and wont print a new line, actually its better to have a new line after a set of characters printed, instead of confusing with the concatenated characters when called multiple times at a time. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/os.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/csr/os.c b/drivers/staging/csr/os.c index 35dc9087d79..0d9842a894c 100644 --- a/drivers/staging/csr/os.c +++ b/drivers/staging/csr/os.c @@ -459,7 +459,7 @@ dump16(void *mem, u16 len) void dump_str(void *mem, u16 len) { - int i, col = 0; + int i; unsigned char *pdata = (unsigned char *)mem; #ifdef ANDROID_TIMESTAMP printk("timestamp %s \n", print_time()); @@ -467,9 +467,7 @@ dump_str(void *mem, u16 len) for (i = 0; i < len; i++) { printk("%c", pdata[i]); } - if (col) { - printk("\n"); - } + printk("\n"); } /* dump_str() */ #endif /* CSR_ONLY_NOTES */ -- cgit v1.2.3 From 4933d3935c41b9c2e1e402970ea2b0a41efdf6f2 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 30 Oct 2012 15:18:41 -0400 Subject: staging: csr: os.c: remove braces around single statement blocks remove all braces around single statement if blocks Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/os.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/staging/csr/os.c b/drivers/staging/csr/os.c index 0d9842a894c..37ec59df358 100644 --- a/drivers/staging/csr/os.c +++ b/drivers/staging/csr/os.c @@ -412,9 +412,8 @@ dump(void *mem, u16 len) return; } for (i = 0; i < len; i++) { - if (col == 0) { + if (col == 0) printk("0x%02X: ", i); - } printk(" %02X", pdata[i]); @@ -423,9 +422,8 @@ dump(void *mem, u16 len) col = 0; } } - if (col) { + if (col) printk("\n"); - } } /* dump() */ @@ -438,9 +436,8 @@ dump16(void *mem, u16 len) printk("timestamp %s \n", print_time()); #endif /* ANDROID_TIMESTAMP */ for (i = 0; i < len; i+=2) { - if (col == 0) { + if (col == 0) printk("0x%02X: ", i); - } printk(" %04X", *p++); @@ -449,9 +446,8 @@ dump16(void *mem, u16 len) col = 0; } } - if (col) { + if (col) printk("\n"); - } } -- cgit v1.2.3 From 32a126966fac80ee961167e496a161fa2903e609 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 30 Oct 2012 15:18:42 -0400 Subject: staging: csr: remove csr_lib.h remove this header file as no struct or no function is defined else where in csr. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_lib.h | 180 --------------------- .../staging/csr/csr_serialize_primitive_types.c | 1 - 2 files changed, 181 deletions(-) delete mode 100644 drivers/staging/csr/csr_lib.h diff --git a/drivers/staging/csr/csr_lib.h b/drivers/staging/csr/csr_lib.h deleted file mode 100644 index d661fc4baff..00000000000 --- a/drivers/staging/csr/csr_lib.h +++ /dev/null @@ -1,180 +0,0 @@ -#ifndef CSR_LIB_H__ -#define CSR_LIB_H__ -/***************************************************************************** - - (c) Cambridge Silicon Radio Limited 2010 - All rights reserved and confidential information of CSR - - Refer to LICENSE.txt included with this source for details - on the license terms. - -*****************************************************************************/ - -#include "csr_prim_defs.h" - -typedef struct -{ - CsrPrim type; -} CsrEvent; - -/*----------------------------------------------------------------------------* - * CsrEvent_struct - * - * DESCRIPTION - * Generic message creator. - * Allocates and fills in a message with the signature CsrEvent - * - *----------------------------------------------------------------------------*/ -CsrEvent *CsrEvent_struct(u16 primtype, u16 msgtype); - -typedef struct -{ - CsrPrim type; - u8 value; -} CsrEventCsrUint8; - -/*----------------------------------------------------------------------------* - * CsrEventCsrUint8_struct - * - * DESCRIPTION - * Generic message creator. - * Allocates and fills in a message with the signature CsrEventCsrUint8 - * - *----------------------------------------------------------------------------*/ -CsrEventCsrUint8 *CsrEventCsrUint8_struct(u16 primtype, u16 msgtype, u8 value); - -typedef struct -{ - CsrPrim type; - u16 value; -} CsrEventCsrUint16; - -/*----------------------------------------------------------------------------* - * CsrEventCsrUint16_struct - * - * DESCRIPTION - * Generic message creator. - * Allocates and fills in a message with the signature CsrEventCsrUint16 - * - *----------------------------------------------------------------------------*/ -CsrEventCsrUint16 *CsrEventCsrUint16_struct(u16 primtype, u16 msgtype, u16 value); - -typedef struct -{ - CsrPrim type; - u16 value1; - u8 value2; -} CsrEventCsrUint16CsrUint8; - -/*----------------------------------------------------------------------------* - * CsrEventCsrUint16CsrUint8_struct - * - * DESCRIPTION - * Generic message creator. - * Allocates and fills in a message with the signature CsrEventCsrUint16CsrUint8 - * - *----------------------------------------------------------------------------*/ -CsrEventCsrUint16CsrUint8 *CsrEventCsrUint16CsrUint8_struct(u16 primtype, u16 msgtype, u16 value1, u8 value2); - -typedef struct -{ - CsrPrim type; - u16 value1; - u16 value2; -} CsrEventCsrUint16CsrUint16; - -/*----------------------------------------------------------------------------* - * CsrEventCsrUint16CsrUint16_struct - * - * DESCRIPTION - * Generic message creator. - * Allocates and fills in a message with the signature CsrEventCsrUint16CsrUint16 - * - *----------------------------------------------------------------------------*/ -CsrEventCsrUint16CsrUint16 *CsrEventCsrUint16CsrUint16_struct(u16 primtype, u16 msgtype, u16 value1, u16 value2); - -typedef struct -{ - CsrPrim type; - u16 value1; - u32 value2; -} CsrEventCsrUint16CsrUint32; - -/*----------------------------------------------------------------------------* - * CsrEventCsrUint16_struct - * - * DESCRIPTION - * Generic message creator. - * Allocates and fills in a message with the signature CsrEventCsrUint16 - * - *----------------------------------------------------------------------------*/ -CsrEventCsrUint16CsrUint32 *CsrEventCsrUint16CsrUint32_struct(u16 primtype, u16 msgtype, u16 value1, u32 value2); - -typedef struct -{ - CsrPrim type; - u16 value1; - char *value2; -} CsrEventCsrUint16CsrCharString; - -/*----------------------------------------------------------------------------* - * CsrEventCsrUint16CsrCharString_struct - * - * DESCRIPTION - * Generic message creator. - * Allocates and fills in a message with the signature CsrEventCsrUint16CsrCharString - * - *----------------------------------------------------------------------------*/ -CsrEventCsrUint16CsrCharString *CsrEventCsrUint16CsrCharString_struct(u16 primtype, u16 msgtype, u16 value1, char *value2); - -typedef struct -{ - CsrPrim type; - u32 value; -} CsrEventCsrUint32; - -/*----------------------------------------------------------------------------* - * CsrEventCsrUint32_struct - * - * DESCRIPTION - * Generic message creator. - * Allocates and fills in a message with the signature CsrEventCsrUint32 - * - *----------------------------------------------------------------------------*/ -CsrEventCsrUint32 *CsrEventCsrUint32_struct(u16 primtype, u16 msgtype, u32 value); - -typedef struct -{ - CsrPrim type; - u32 value1; - u16 value2; -} CsrEventCsrUint32CsrUint16; - -/*----------------------------------------------------------------------------* - * CsrEventCsrUint32CsrUint16_struct - * - * DESCRIPTION - * Generic message creator. - * Allocates and fills in a message with the signature CsrEventCsrUint32CsrUint16 - * - *----------------------------------------------------------------------------*/ -CsrEventCsrUint32CsrUint16 *CsrEventCsrUint32CsrUint16_struct(u16 primtype, u16 msgtype, u32 value1, u32 value2); - -typedef struct -{ - CsrPrim type; - u32 value1; - char *value2; -} CsrEventCsrUint32CsrCharString; - -/*----------------------------------------------------------------------------* - * CsrEventCsrUint32CsrCharString_struct - * - * DESCRIPTION - * Generic message creator. - * Allocates and fills in a message with the signature CsrEventCsrUint32CsrCharString - * - *----------------------------------------------------------------------------*/ -CsrEventCsrUint32CsrCharString *CsrEventCsrUint32CsrCharString_struct(u16 primtype, u16 msgtype, u32 value1, char *value2); - -#endif /* CSR_LIB_H__ */ diff --git a/drivers/staging/csr/csr_serialize_primitive_types.c b/drivers/staging/csr/csr_serialize_primitive_types.c index bf5e4ab9f95..9713b9afef6 100644 --- a/drivers/staging/csr/csr_serialize_primitive_types.c +++ b/drivers/staging/csr/csr_serialize_primitive_types.c @@ -13,7 +13,6 @@ #include "csr_prim_defs.h" #include "csr_msgconv.h" #include "csr_macro.h" -#include "csr_lib.h" void CsrUint8Des(u8 *value, u8 *buffer, size_t *offset) { -- cgit v1.2.3 From d0eb3ddb441b6bea138cd77781a310c58ba79479 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Tue, 30 Oct 2012 15:18:43 -0400 Subject: staging: csr: csr_log_configure.h: remove a bunch of function protos all protos that are removed does not have a function definition so remove all of them together Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_log_configure.h | 87 --------------------------------- 1 file changed, 87 deletions(-) diff --git a/drivers/staging/csr/csr_log_configure.h b/drivers/staging/csr/csr_log_configure.h index 31c3361fc67..283647cf970 100644 --- a/drivers/staging/csr/csr_log_configure.h +++ b/drivers/staging/csr/csr_log_configure.h @@ -12,31 +12,6 @@ #include "csr_log.h" -/*---------------------------------*/ -/* Log init/deinit */ -/*---------------------------------*/ -void CsrLogInit(u8 size); -void CsrLogDeinit(void); - -/*---------------------------------*/ -/* Log Framework Tech info */ -/*---------------------------------*/ -void CsrLogTechInfoRegister(void); - -/* Set the logging level for the environment outside the scheduler context */ -void CsrLogLevelEnvironmentSet(CsrLogLevelEnvironment environmentLogLevel); - - -/* Set the logging level for all scheduler tasks */ -/* This function call takes precedence over all previous calls to CsrLogLevelTaskSetSpecific() */ -void CsrLogLevelTaskSetAll(CsrLogLevelTask tasksLogLevelMask); - -/* Set the logging level for a given Task */ -/* This function can be used as a complement to CsrLogLevelTaskSetAll() to add more _or_ less log from a given task than what is set - generally with CsrLogLevelTaskSetAll(). */ -void CsrLogLevelTaskSetSpecific(CsrSchedQid taskId, CsrLogLevelTask taskLogLevelMask); - - /*--------------------------------------------*/ /* Filtering on log text warning levels */ /*--------------------------------------------*/ @@ -61,66 +36,4 @@ typedef u32 CsrLogLevelText; * taskId's in the range 0x0600xxxx to 0x06FFxxxx. And so on for other technologies. */ typedef u32 CsrLogTextTaskId; -/* Set the text logging level for all Tasks */ -/* This function call takes precedence over all previous calls to CsrLogLevelTextSetTask() and CsrLogLevelTextSetTaskSubOrigin() */ -void CsrLogLevelTextSetAll(CsrLogLevelText warningLevelMask); - -/* Set the text logging level for a given Task */ -/* This function call takes precedence over all previous calls to CsrLogLevelTextSetTaskSubOrigin(), but it can be used as a complement to - * CsrLogLevelTextSetAll() to add more _or_ less log from a given task than what is set generally with CsrLogLevelTextSetAll(). */ -void CsrLogLevelTextSetTask(CsrLogTextTaskId taskId, CsrLogLevelText warningLevelMask); - -/* Set the text logging level for a given tasks subOrigin */ -/* This function can be used as a complement to CsrLogLevelTextSetAll() and CsrLogLevelTextSetTask() to add more _or_ less log from a given - * subOrigin within a task than what is set generally with CsrLogLevelTextSetAll() _or_ CsrLogLevelTextSetTask(). */ -void CsrLogLevelTextSetTaskSubOrigin(CsrLogTextTaskId taskId, u16 subOrigin, CsrLogLevelText warningLevelMask); - -/******************************************************************************* - - NAME - CsrLogLevelTextSet - - DESCRIPTION - Set the text logging level for a given origin and optionally sub origin - by name. If either string is NULL or zero length, it is interpreted as - all origins and/or all sub origins respectively. If originName is NULL - or zero length, subOriginName is ignored. - - Passing NULL or zero length strings in both originName and subOriginName - is equivalent to calling CsrLogLevelTextSetAll, and overrides all - previous filter configurations for all origins and sub origins. - - Passing NULL or a zero length string in subOriginName overrides all - previous filter configurations for all sub origins of the specified - origin. - -Note: the supplied strings may be accessed after the function returns -and must remain valid and constant until CsrLogDeinit is called. - -Note: when specifying an origin (originName is not NULL and not zero -length), this function can only be used for origins that use the -csr_log_text_2.h interface for registration and logging. Filtering for -origins that use the legacy csr_log_text.h interface must be be -configured using the legacy filter configuration functions that accept -a CsrLogTextTaskId as origin specifier. However, when not specifying an -origin this function also affects origins that have been registered with -the legacy csr_log_text.h interface. Furthermore, using this function -and the legacy filter configuration functions on the same origin is not -allowed. - -PARAMETERS -originName - a string containing the name of the origin. Can be NULL or -zero length to set the log level for all origins. In this case, the -subOriginName parameter will be ignored. -subOriginName - a string containing the name of the sub origin. Can be -NULL or zero length to set the log level for all sub origins of the -specified origin. -warningLevelMask - The desired log level for the specified origin(s) and -sub origin(s). - - *******************************************************************************/ -void CsrLogLevelTextSet(const char *originName, - const char *subOriginName, - CsrLogLevelText warningLevelMask); - #endif -- cgit v1.2.3 From 8e493ca1767d4951ed1322abaa74d6edbca29918 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 26 Oct 2012 18:44:20 +0200 Subject: USB: usb_wwan: fix bulk-urb allocation Make sure we do not allocate urbs if we do not have a bulk endpoint. Legacy code used incorrect assumption to test for bulk endpoints. Reported-by: Dan Carpenter Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb_wwan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 61a73ad1a18..a3e9c095f0d 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -455,9 +455,6 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, struct usb_serial *serial = port->serial; struct urb *urb; - if (endpoint == -1) - return NULL; /* endpoint not needed */ - urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ if (urb == NULL) { dev_dbg(&serial->interface->dev, @@ -489,6 +486,9 @@ int usb_wwan_port_probe(struct usb_serial_port *port) init_usb_anchor(&portdata->delayed); for (i = 0; i < N_IN_URB; i++) { + if (!port->bulk_in_size) + break; + buffer = (u8 *)__get_free_page(GFP_KERNEL); if (!buffer) goto bail_out_error; @@ -502,8 +502,8 @@ int usb_wwan_port_probe(struct usb_serial_port *port) } for (i = 0; i < N_OUT_URB; i++) { - if (port->bulk_out_endpointAddress == -1) - continue; + if (!port->bulk_out_size) + break; buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); if (!buffer) -- cgit v1.2.3 From d99e65bda806f49e192dd31e9b01959974dea3cd Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 29 Oct 2012 16:45:54 +0000 Subject: USB: fix build with XEN and EARLY_PRINTK_DBGP enabled but USB_SUPPORT disabled Since there's no possible caller of dbgp_external_startup() and dbgp_reset_prep() when !USB_EHCI_HCD, there's no point in building and exporting these functions in that case. This eliminates a build error under the conditions listed in the subject, introduced with the merge f1c6872e4980bc4078cfaead05f892b3d78dea64. Reported-by: Randy Dunlap Signed-off-by: Jan Beulich Cc: Stefano Stabellini Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/early/ehci-dbgp.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index e426ad626d7..4bfa78af379 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -614,12 +615,6 @@ err: return -ENODEV; } -int dbgp_external_startup(struct usb_hcd *hcd) -{ - return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); -} -EXPORT_SYMBOL_GPL(dbgp_external_startup); - static int ehci_reset_port(int port) { u32 portsc; @@ -979,6 +974,7 @@ struct console early_dbgp_console = { .index = -1, }; +#if IS_ENABLED(CONFIG_USB_EHCI_HCD) int dbgp_reset_prep(struct usb_hcd *hcd) { int ret = xen_dbgp_reset_prep(hcd); @@ -1007,6 +1003,13 @@ int dbgp_reset_prep(struct usb_hcd *hcd) } EXPORT_SYMBOL_GPL(dbgp_reset_prep); +int dbgp_external_startup(struct usb_hcd *hcd) +{ + return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); +} +EXPORT_SYMBOL_GPL(dbgp_external_startup); +#endif /* USB_EHCI_HCD */ + #ifdef CONFIG_KGDB static char kgdbdbgp_buf[DBGP_MAX_PACKET]; -- cgit v1.2.3 From 487c151a4a8fd1ab68308102c215158c14ad7c23 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 29 Oct 2012 18:37:31 +0900 Subject: USB: iuu_phoenix: replace strict_strtoul() with kstrtoul() The usage of strict_strtoul() is not preferred, because strict_strtoul() is obsolete. Thus, kstrtoul() should be used. Signed-off-by: Jingoo Han Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/iuu_phoenix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index cd5533e81de..99029ca850c 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -1164,7 +1164,7 @@ static ssize_t store_vcc_mode(struct device *dev, struct iuu_private *priv = usb_get_serial_port_data(port); unsigned long v; - if (strict_strtoul(buf, 10, &v)) { + if (kstrtoul(buf, 10, &v)) { dev_err(dev, "%s - vcc_mode: %s is not a unsigned long\n", __func__, buf); goto fail_store_vcc_mode; -- cgit v1.2.3 From 4f2ab8887479bef2204878ed6d633a515a3e6a0d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 29 Oct 2012 10:56:19 +0100 Subject: USB: cp210x: fix whitespace issues Fix missing and superfluous whitespace. Fix misplaced brackets. Fix indentation. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index eb033fc92a1..1264173a099 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -35,8 +35,7 @@ */ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *); static void cp210x_close(struct usb_serial_port *); -static void cp210x_get_termios(struct tty_struct *, - struct usb_serial_port *port); +static void cp210x_get_termios(struct tty_struct *, struct usb_serial_port *); static void cp210x_get_termios_port(struct usb_serial_port *port, unsigned int *cflagp, unsigned int *baudp); static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *, @@ -169,7 +168,7 @@ struct cp210x_serial_private { static struct usb_serial_driver cp210x_device = { .driver = { .owner = THIS_MODULE, - .name = "cp210x", + .name = "cp210x", }, .id_table = id_table, .num_ports = 1, @@ -179,7 +178,7 @@ static struct usb_serial_driver cp210x_device = { .close = cp210x_close, .break_ctl = cp210x_break_ctl, .set_termios = cp210x_set_termios, - .tiocmget = cp210x_tiocmget, + .tiocmget = cp210x_tiocmget, .tiocmset = cp210x_tiocmset, .attach = cp210x_startup, .release = cp210x_release, @@ -281,7 +280,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, int result, i, length; /* Number of integers required to contain the array */ - length = (((size - 1) | 3) + 1)/4; + length = (((size - 1) | 3) + 1) / 4; buf = kcalloc(length, sizeof(__le32), GFP_KERNEL); if (!buf) { @@ -328,12 +327,11 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, int result, i, length; /* Number of integers required to contain the array */ - length = (((size - 1) | 3) + 1)/4; + length = (((size - 1) | 3) + 1) / 4; buf = kmalloc(length * sizeof(__le32), GFP_KERNEL); if (!buf) { - dev_err(&port->dev, "%s - out of memory.\n", - __func__); + dev_err(&port->dev, "%s - out of memory.\n", __func__); return -ENOMEM; } @@ -384,7 +382,8 @@ static inline int cp210x_set_config_single(struct usb_serial_port *port, * cp210x_quantise_baudrate * Quantises the baud rate as per AN205 Table 1 */ -static unsigned int cp210x_quantise_baudrate(unsigned int baud) { +static unsigned int cp210x_quantise_baudrate(unsigned int baud) +{ if (baud <= 300) baud = 300; else if (baud <= 600) baud = 600; @@ -467,9 +466,7 @@ static void cp210x_get_termios(struct tty_struct *tty, cp210x_get_termios_port(tty->driver_data, &tty->termios.c_cflag, &baud); tty_encode_baud_rate(tty, baud, baud); - } - - else { + } else { unsigned int cflag; cflag = 0; cp210x_get_termios_port(port, &cflag, &baud); @@ -693,8 +690,8 @@ static void cp210x_set_termios(struct tty_struct *tty, break;*/ default: dev_dbg(dev, "cp210x driver does not support the number of bits requested, using 8 bit mode\n"); - bits |= BITS_DATA_8; - break; + bits |= BITS_DATA_8; + break; } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dev_dbg(dev, "Number of data bits requested not supported by device\n"); @@ -767,7 +764,7 @@ static void cp210x_set_termios(struct tty_struct *tty, } -static int cp210x_tiocmset (struct tty_struct *tty, +static int cp210x_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; @@ -809,7 +806,7 @@ static void cp210x_dtr_rts(struct usb_serial_port *p, int on) cp210x_tiocmset_port(p, 0, TIOCM_DTR|TIOCM_RTS); } -static int cp210x_tiocmget (struct tty_struct *tty) +static int cp210x_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; unsigned int control; @@ -829,7 +826,7 @@ static int cp210x_tiocmget (struct tty_struct *tty) return result; } -static void cp210x_break_ctl (struct tty_struct *tty, int break_state) +static void cp210x_break_ctl(struct tty_struct *tty, int break_state) { struct usb_serial_port *port = tty->driver_data; unsigned int state; -- cgit v1.2.3 From d067a3155336894ca19d08b7359f824fbbdbc379 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 29 Oct 2012 10:56:20 +0100 Subject: USB: ftdi_sio: remove unnecessary memset No need to memset a kzalloced struct. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 38151557223..95e317c8762 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1684,7 +1684,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) kref_init(&priv->kref); mutex_init(&priv->cfg_lock); - memset(&priv->icount, 0x00, sizeof(priv->icount)); init_waitqueue_head(&priv->delta_msr_wait); priv->flags = ASYNC_LOW_LATENCY; -- cgit v1.2.3 From 86effe5980e25f4fac10a0f22938c2fcd4a32690 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 29 Oct 2012 16:45:54 +0000 Subject: USB: fix build with XEN and EARLY_PRINTK_DBGP enabled but USB_SUPPORT disabled Since there's no possible caller of dbgp_external_startup() and dbgp_reset_prep() when !USB_EHCI_HCD, there's no point in building and exporting these functions in that case. This eliminates a build error under the conditions listed in the subject, introduced with the merge f1c6872e4980bc4078cfaead05f892b3d78dea64. Reported-by: Randy Dunlap Signed-off-by: Jan Beulich Cc: Stefano Stabellini Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/early/ehci-dbgp.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index e426ad626d7..4bfa78af379 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -614,12 +615,6 @@ err: return -ENODEV; } -int dbgp_external_startup(struct usb_hcd *hcd) -{ - return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); -} -EXPORT_SYMBOL_GPL(dbgp_external_startup); - static int ehci_reset_port(int port) { u32 portsc; @@ -979,6 +974,7 @@ struct console early_dbgp_console = { .index = -1, }; +#if IS_ENABLED(CONFIG_USB_EHCI_HCD) int dbgp_reset_prep(struct usb_hcd *hcd) { int ret = xen_dbgp_reset_prep(hcd); @@ -1007,6 +1003,13 @@ int dbgp_reset_prep(struct usb_hcd *hcd) } EXPORT_SYMBOL_GPL(dbgp_reset_prep); +int dbgp_external_startup(struct usb_hcd *hcd) +{ + return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); +} +EXPORT_SYMBOL_GPL(dbgp_external_startup); +#endif /* USB_EHCI_HCD */ + #ifdef CONFIG_KGDB static char kgdbdbgp_buf[DBGP_MAX_PACKET]; -- cgit v1.2.3 From 81e84424f9da413b4e3edb00e25a19783304c7d1 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 29 Oct 2012 10:56:21 +0100 Subject: USB: ftdi_sio: remove unused private port-data Remove unused port field from private port data. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 95e317c8762..48cbc39e6d8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -73,7 +73,6 @@ struct ftdi_private { char prev_status; /* Used for TIOCMIWAIT */ bool dev_gone; /* Used to abort TIOCMIWAIT */ char transmit_empty; /* If transmitter is empty or not */ - struct usb_serial_port *port; __u16 interface; /* FT2232C, FT2232H or FT4232H port interface (0 for FT232/245) */ @@ -1692,7 +1691,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port) if (quirk && quirk->port_probe) quirk->port_probe(priv); - priv->port = port; usb_set_serial_port_data(port, priv); ftdi_determine_type(port); -- cgit v1.2.3 From fef0b828a3c7a7123aedb4b1d8415369f75e0a58 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 29 Oct 2012 10:56:22 +0100 Subject: USB: ftdi_sio: fix tiocmget indentation Align the modem-control status operands as was originally indented. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 48cbc39e6d8..2ad5e7c7f22 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2372,10 +2372,10 @@ static int ftdi_tiocmget(struct tty_struct *tty) if (ret < 0) goto out; - ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | - (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | - (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | - (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | + ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | + (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | + (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | + (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | priv->last_dtr_rts; out: kfree(buf); -- cgit v1.2.3 From 2c2ee545071c10873b057b04a19d3d2aed04b9cf Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 29 Oct 2012 10:56:23 +0100 Subject: USB: ftdi_sio: fix tiocmget and tiocmset return values Make sure we do not return USB-internal error codes to userspace. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 2ad5e7c7f22..987cc2cafa3 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1091,6 +1091,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set, __func__, (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged", (set & TIOCM_RTS) ? "HIGH" : (clear & TIOCM_RTS) ? "LOW" : "unchanged"); + rv = usb_translate_errors(rv); } else { dev_dbg(dev, "%s - DTR %s, RTS %s\n", __func__, (set & TIOCM_DTR) ? "HIGH" : (clear & TIOCM_DTR) ? "LOW" : "unchanged", @@ -2369,8 +2370,10 @@ static int ftdi_tiocmget(struct tty_struct *tty) FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, 0, priv->interface, buf, len, WDR_TIMEOUT); - if (ret < 0) + if (ret < 0) { + ret = usb_translate_errors(ret); goto out; + } ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | -- cgit v1.2.3 From a4afff6b323a20ddf51d08dec0e2ef4fe8f228ee Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 29 Oct 2012 10:56:24 +0100 Subject: USB: ftdi_sio: refactor modem-control status retrieval Refactor modem-control status retrieval. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 987cc2cafa3..06b5d75dffc 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2330,7 +2330,14 @@ no_c_cflag_changes: } } -static int ftdi_tiocmget(struct tty_struct *tty) +/* + * Get modem-control status. + * + * Returns the number of status bytes retrieved (device dependant), or + * negative error code. + */ +static int ftdi_get_modem_status(struct tty_struct *tty, + unsigned char status[2]) { struct usb_serial_port *port = tty->driver_data; struct ftdi_private *priv = usb_get_serial_port_data(port); @@ -2371,17 +2378,42 @@ static int ftdi_tiocmget(struct tty_struct *tty) 0, priv->interface, buf, len, WDR_TIMEOUT); if (ret < 0) { + dev_err(&port->dev, "failed to get modem status: %d\n", ret); ret = usb_translate_errors(ret); goto out; } + status[0] = buf[0]; + if (ret > 1) + status[1] = buf[1]; + else + status[1] = 0; + + dev_dbg(&port->dev, "%s - 0x%02x%02x\n", __func__, status[0], + status[1]); +out: + kfree(buf); + + return ret; +} + +static int ftdi_tiocmget(struct tty_struct *tty) +{ + struct usb_serial_port *port = tty->driver_data; + struct ftdi_private *priv = usb_get_serial_port_data(port); + unsigned char buf[2]; + int ret; + + ret = ftdi_get_modem_status(tty, buf); + if (ret < 0) + return ret; + ret = (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | (buf[0] & FTDI_SIO_CTS_MASK ? TIOCM_CTS : 0) | (buf[0] & FTDI_SIO_RI_MASK ? TIOCM_RI : 0) | (buf[0] & FTDI_SIO_RLSD_MASK ? TIOCM_CD : 0) | priv->last_dtr_rts; -out: - kfree(buf); + return ret; } -- cgit v1.2.3 From 428d9988557f0f26047af304cf1f3d130b06ed4d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 29 Oct 2012 10:56:25 +0100 Subject: USB: serial: export usb_serial_generic_chars_in_buffer Export generic chars_in_buffer implementation so it can be used in subdrivers in combination with checks of any hardware buffers. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 296612153ea..2ea70a63199 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -262,6 +262,7 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty) dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars); return chars; } +EXPORT_SYMBOL_GPL(usb_serial_generic_chars_in_buffer); static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, int index, gfp_t mem_flags) -- cgit v1.2.3 From 755b6040fa62eab9d9105359cd5884910eef2df4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 29 Oct 2012 10:56:26 +0100 Subject: USB: ftdi_sio: use generic chars_in_buffer Use generic chars_in_buffer rather than copying it's implementation. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 06b5d75dffc..9fe3a2e965a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2093,16 +2093,11 @@ static int ftdi_chars_in_buffer(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct ftdi_private *priv = usb_get_serial_port_data(port); - unsigned long flags; int chars; unsigned char *buf; int ret; - /* Check software buffer (code from - * usb_serial_generic_chars_in_buffer()) */ - spin_lock_irqsave(&port->lock, flags); - chars = kfifo_len(&port->write_fifo) + port->tx_bytes; - spin_unlock_irqrestore(&port->lock, flags); + chars = usb_serial_generic_chars_in_buffer(tty); /* Check hardware buffer */ switch (priv->chip_type) { -- cgit v1.2.3 From 8da636d9b5f3af354458f5b7eadaf51f23017fdc Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 29 Oct 2012 10:56:27 +0100 Subject: USB: ftdi_sio: optimise chars_in_buffer No need to check hardware buffers when we know that the software buffers are non-empty. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 9fe3a2e965a..b8bc9d0cb12 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2098,6 +2098,8 @@ static int ftdi_chars_in_buffer(struct tty_struct *tty) int ret; chars = usb_serial_generic_chars_in_buffer(tty); + if (chars) + return chars; /* Check hardware buffer */ switch (priv->chip_type) { -- cgit v1.2.3 From 5fb0432e64335bcf3f620e2d86a97fba0437c84b Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 29 Oct 2012 10:56:28 +0100 Subject: USB: ftdi_sio: use ftdi_get_modem_status in chars_in_buffer Use ftdi_get_modem_status to check hardware buffers in chars_in_buffer. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 52 +++++++++---------------------------------- 1 file changed, 11 insertions(+), 41 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index b8bc9d0cb12..8c3379b52f2 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -923,6 +923,8 @@ static int ftdi_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static void ftdi_break_ctl(struct tty_struct *tty, int break_state); static int ftdi_chars_in_buffer(struct tty_struct *tty); +static int ftdi_get_modem_status(struct tty_struct *tty, + unsigned char status[2]); static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base); static unsigned short int ftdi_232am_baud_to_divisor(int baud); @@ -2092,55 +2094,23 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state) static int ftdi_chars_in_buffer(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; - struct ftdi_private *priv = usb_get_serial_port_data(port); int chars; - unsigned char *buf; + unsigned char buf[2]; int ret; chars = usb_serial_generic_chars_in_buffer(tty); if (chars) - return chars; - - /* Check hardware buffer */ - switch (priv->chip_type) { - case FT8U232AM: - case FT232BM: - case FT2232C: - case FT232RL: - case FT2232H: - case FT4232H: - case FT232H: - case FTX: - break; - case SIO: - default: - return chars; - } - - buf = kmalloc(2, GFP_KERNEL); - if (!buf) { - dev_err(&port->dev, "kmalloc failed"); - return chars; - } + goto out; - ret = usb_control_msg(port->serial->dev, - usb_rcvctrlpipe(port->serial->dev, 0), - FTDI_SIO_GET_MODEM_STATUS_REQUEST, - FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, - 0, priv->interface, - buf, 2, WDR_TIMEOUT); - - if (ret < 2) { - dev_err(&port->dev, "Unable to read modem and line status: " - "%i\n", ret); - goto chars_in_buffer_out; + /* Check if hardware buffer is empty. */ + ret = ftdi_get_modem_status(tty, buf); + if (ret == 2) { + if (!(buf[1] & FTDI_RS_TEMT)) + chars = 1; } +out: + dev_dbg(&port->dev, "%s - %d\n", __func__, chars); - if (!(buf[1] & FTDI_RS_TEMT)) - chars++; - -chars_in_buffer_out: - kfree(buf); return chars; } -- cgit v1.2.3 From 806df3ac2ac86dd0c2e02ed935b93321424183f9 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 30 Oct 2012 11:22:26 +0900 Subject: USB: ums_realtek: fix build warning When rts51x_read_status() returns USB_STOR_TRANSPORT_ERROR, an error happens. This patch fixes build warning as below: drivers/usb/storage/realtek_cr.c: In function 'init_realtek_cr': drivers/usb/storage/realtek_cr.c:476:33: warning: 'buf[15]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[15]' was declared here drivers/usb/storage/realtek_cr.c:475:33: warning: 'buf[14]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[14]' was declared here drivers/usb/storage/realtek_cr.c:474:50: warning: 'buf[13]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[13]' was declared here drivers/usb/storage/realtek_cr.c:472:30: warning: 'buf[12]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[12]' was declared here drivers/usb/storage/realtek_cr.c:471:31: warning: 'buf[11]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[11]' was declared here drivers/usb/storage/realtek_cr.c:470:31: warning: 'buf[10]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[10]' was declared here drivers/usb/storage/realtek_cr.c:469:30: warning: 'buf[9]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[9]' was declared here drivers/usb/storage/realtek_cr.c:468:27: warning: 'buf[8]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[8]' was declared here drivers/usb/storage/realtek_cr.c:468:43: warning: 'buf[7]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[7]' was declared here drivers/usb/storage/realtek_cr.c:467:30: warning: 'buf[6]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[6]' was declared here drivers/usb/storage/realtek_cr.c:466:30: warning: 'buf[5]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[5]' was declared here drivers/usb/storage/realtek_cr.c:465:28: warning: 'buf[4]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[4]' was declared here drivers/usb/storage/realtek_cr.c:464:24: warning: 'buf[3]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[3]' was declared here drivers/usb/storage/realtek_cr.c:464:40: warning: 'buf[2]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[2]' was declared here drivers/usb/storage/realtek_cr.c:463:24: warning: 'buf[1]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[1]' was declared here drivers/usb/storage/realtek_cr.c:463:40: warning: 'buf[0]' may be used uninitialized in this function [-Wuninitialized] drivers/usb/storage/realtek_cr.c:455:5: note: 'buf[0]' was declared here Signed-off-by: Jingoo Han Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/realtek_cr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index d36446dd7ae..ea5f2586fbd 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -455,7 +455,7 @@ static int rts51x_check_status(struct us_data *us, u8 lun) u8 buf[16]; retval = rts51x_read_status(us, lun, buf, 16, &(chip->status_len)); - if (retval < 0) + if (retval != STATUS_SUCCESS) return -EIO; US_DEBUGP("chip->status_len = %d\n", chip->status_len); -- cgit v1.2.3 From 322337b8fbd8c392246529d5db924820fc0c7381 Mon Sep 17 00:00:00 2001 From: Pritesh Raithatha Date: Tue, 30 Oct 2012 15:37:09 +0530 Subject: ARM: dt: tegra: fix length of pad control and mux registers The reg property contains not . Fix the length values to be length not last_offset. Cc: stable@vger.kernel.org Signed-off-by: Pritesh Raithatha Signed-off-by: Stephen Warren --- arch/arm/boot/dts/tegra30.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi index b1497c7d7d6..df7f2270fc9 100644 --- a/arch/arm/boot/dts/tegra30.dtsi +++ b/arch/arm/boot/dts/tegra30.dtsi @@ -73,8 +73,8 @@ pinmux: pinmux { compatible = "nvidia,tegra30-pinmux"; - reg = <0x70000868 0xd0 /* Pad control registers */ - 0x70003000 0x3e0>; /* Mux registers */ + reg = <0x70000868 0xd4 /* Pad control registers */ + 0x70003000 0x3e4>; /* Mux registers */ }; serial@70006000 { -- cgit v1.2.3 From d2ffc740f33d432949eee7479ac49bafd9f5108a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 25 Oct 2012 16:40:59 +0200 Subject: UM: TTY: fix build errors now that tty->raw is gone Signed-off-by: Jiri Slaby --- arch/um/drivers/chan_kern.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index c3bba73e4be..e9a0abc6a32 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -83,21 +83,8 @@ static const struct chan_ops not_configged_ops = { static void tty_receive_char(struct tty_struct *tty, char ch) { - if (tty == NULL) - return; - - if (I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) { - if (ch == STOP_CHAR(tty)) { - stop_tty(tty); - return; - } - else if (ch == START_CHAR(tty)) { - start_tty(tty); - return; - } - } - - tty_insert_flip_char(tty, ch, TTY_NORMAL); + if (tty) + tty_insert_flip_char(tty, ch, TTY_NORMAL); } static int open_one_chan(struct chan *chan) -- cgit v1.2.3 From 669fef464468d3f02d60a5cf725fc097e03c5cb8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 28 Oct 2012 03:48:57 -0700 Subject: serial: jsm: Convert jsm_printk to jsm_dbg These printks should all be emitted at KERN_DEBUG level. Make them dependent on CONFIG_DEBUG or (#define DEBUG) simplify the code a bit. Add missing newlines where appropriate. Most all of these messages could be deleted too. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm.h | 8 ++- drivers/tty/serial/jsm/jsm_driver.c | 3 +- drivers/tty/serial/jsm/jsm_neo.c | 116 +++++++++++++++++++----------------- drivers/tty/serial/jsm/jsm_tty.c | 102 +++++++++++++++---------------- 4 files changed, 120 insertions(+), 109 deletions(-) diff --git a/drivers/tty/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h index 529bec6edaf..844d5e4eb1a 100644 --- a/drivers/tty/serial/jsm/jsm.h +++ b/drivers/tty/serial/jsm/jsm.h @@ -57,9 +57,11 @@ enum { DBG_CARR = 0x10000, }; -#define jsm_printk(nlevel, klevel, pdev, fmt, args...) \ - if ((DBG_##nlevel & jsm_debug)) \ - dev_printk(KERN_##klevel, pdev->dev, fmt, ## args) +#define jsm_dbg(nlevel, pdev, fmt, ...) \ +do { \ + if (DBG_##nlevel & jsm_debug) \ + dev_dbg(pdev->dev, fmt, ##__VA_ARGS__); \ +} while (0) #define MAXLINES 256 #define MAXPORTS 8 diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index 5ab3c3b595e..8e05ce94bd4 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -107,8 +107,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device brd->irq = pdev->irq; - jsm_printk(INIT, INFO, &brd->pci_dev, - "jsm_found_board - NEO adapter\n"); + jsm_dbg(INIT, &brd->pci_dev, "jsm_found_board - NEO adapter\n"); /* get the PCI Base Address Registers */ brd->membase = pci_resource_start(pdev, 0); diff --git a/drivers/tty/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index 81dfafa11b0..dfaf4882641 100644 --- a/drivers/tty/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c @@ -52,7 +52,7 @@ static void neo_set_cts_flow_control(struct jsm_channel *ch) ier = readb(&ch->ch_neo_uart->ier); efr = readb(&ch->ch_neo_uart->efr); - jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting CTSFLOW\n"); + jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Setting CTSFLOW\n"); /* Turn on auto CTS flow control */ ier |= (UART_17158_IER_CTSDSR); @@ -83,7 +83,7 @@ static void neo_set_rts_flow_control(struct jsm_channel *ch) ier = readb(&ch->ch_neo_uart->ier); efr = readb(&ch->ch_neo_uart->efr); - jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting RTSFLOW\n"); + jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Setting RTSFLOW\n"); /* Turn on auto RTS flow control */ ier |= (UART_17158_IER_RTSDTR); @@ -123,7 +123,7 @@ static void neo_set_ixon_flow_control(struct jsm_channel *ch) ier = readb(&ch->ch_neo_uart->ier); efr = readb(&ch->ch_neo_uart->efr); - jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting IXON FLOW\n"); + jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Setting IXON FLOW\n"); /* Turn off auto CTS flow control */ ier &= ~(UART_17158_IER_CTSDSR); @@ -160,7 +160,7 @@ static void neo_set_ixoff_flow_control(struct jsm_channel *ch) ier = readb(&ch->ch_neo_uart->ier); efr = readb(&ch->ch_neo_uart->efr); - jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Setting IXOFF FLOW\n"); + jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Setting IXOFF FLOW\n"); /* Turn off auto RTS flow control */ ier &= ~(UART_17158_IER_RTSDTR); @@ -198,7 +198,7 @@ static void neo_set_no_input_flow_control(struct jsm_channel *ch) ier = readb(&ch->ch_neo_uart->ier); efr = readb(&ch->ch_neo_uart->efr); - jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Unsetting Input FLOW\n"); + jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Unsetting Input FLOW\n"); /* Turn off auto RTS flow control */ ier &= ~(UART_17158_IER_RTSDTR); @@ -237,7 +237,7 @@ static void neo_set_no_output_flow_control(struct jsm_channel *ch) ier = readb(&ch->ch_neo_uart->ier); efr = readb(&ch->ch_neo_uart->efr); - jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "Unsetting Output FLOW\n"); + jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "Unsetting Output FLOW\n"); /* Turn off auto CTS flow control */ ier &= ~(UART_17158_IER_CTSDSR); @@ -276,7 +276,7 @@ static inline void neo_set_new_start_stop_chars(struct jsm_channel *ch) if (ch->ch_c_cflag & CRTSCTS) return; - jsm_printk(PARAM, INFO, &ch->ch_bd->pci_dev, "start\n"); + jsm_dbg(PARAM, &ch->ch_bd->pci_dev, "start\n"); /* Tell UART what start/stop chars it should be looking for */ writeb(ch->ch_startc, &ch->ch_neo_uart->xonchar1); @@ -455,7 +455,7 @@ static void neo_copy_data_from_uart_to_queue(struct jsm_channel *ch) * I hope thats okay with everyone? Yes? Good. */ while (qleft < 1) { - jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, + jsm_dbg(READ, &ch->ch_bd->pci_dev, "Queue full, dropping DATA:%x LSR:%x\n", ch->ch_rqueue[tail], ch->ch_equeue[tail]); @@ -467,8 +467,8 @@ static void neo_copy_data_from_uart_to_queue(struct jsm_channel *ch) memcpy_fromio(ch->ch_rqueue + head, &ch->ch_neo_uart->txrxburst, 1); ch->ch_equeue[head] = (u8) linestatus; - jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, - "DATA/LSR pair: %x %x\n", ch->ch_rqueue[head], ch->ch_equeue[head]); + jsm_dbg(READ, &ch->ch_bd->pci_dev, "DATA/LSR pair: %x %x\n", + ch->ch_rqueue[head], ch->ch_equeue[head]); /* Ditch any remaining linestatus value. */ linestatus = 0; @@ -521,8 +521,8 @@ static void neo_copy_data_from_queue_to_uart(struct jsm_channel *ch) ch->ch_cached_lsr &= ~(UART_LSR_THRE); writeb(circ->buf[circ->tail], &ch->ch_neo_uart->txrx); - jsm_printk(WRITE, INFO, &ch->ch_bd->pci_dev, - "Tx data: %x\n", circ->buf[circ->tail]); + jsm_dbg(WRITE, &ch->ch_bd->pci_dev, + "Tx data: %x\n", circ->buf[circ->tail]); circ->tail = (circ->tail + 1) & (UART_XMIT_SIZE - 1); ch->ch_txcount++; } @@ -575,8 +575,9 @@ static void neo_parse_modem(struct jsm_channel *ch, u8 signals) { u8 msignals = signals; - jsm_printk(MSIGS, INFO, &ch->ch_bd->pci_dev, - "neo_parse_modem: port: %d msignals: %x\n", ch->ch_portnum, msignals); + jsm_dbg(MSIGS, &ch->ch_bd->pci_dev, + "neo_parse_modem: port: %d msignals: %x\n", + ch->ch_portnum, msignals); /* Scrub off lower bits. They signify delta's, which I don't care about */ /* Keep DDCD and DDSR though */ @@ -606,8 +607,8 @@ static void neo_parse_modem(struct jsm_channel *ch, u8 signals) else ch->ch_mistat &= ~UART_MSR_CTS; - jsm_printk(MSIGS, INFO, &ch->ch_bd->pci_dev, - "Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n", + jsm_dbg(MSIGS, &ch->ch_bd->pci_dev, + "Port: %d DTR: %d RTS: %d CTS: %d DSR: %d " "RI: %d CD: %d\n", ch->ch_portnum, !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_DTR), !!((ch->ch_mistat | ch->ch_mostat) & UART_MCR_RTS), @@ -649,8 +650,8 @@ static void neo_flush_uart_write(struct jsm_channel *ch) /* Check to see if the UART feels it completely flushed the FIFO. */ tmp = readb(&ch->ch_neo_uart->isr_fcr); if (tmp & 4) { - jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, - "Still flushing TX UART... i: %d\n", i); + jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, + "Still flushing TX UART... i: %d\n", i); udelay(10); } else @@ -681,8 +682,8 @@ static void neo_flush_uart_read(struct jsm_channel *ch) /* Check to see if the UART feels it completely flushed the FIFO. */ tmp = readb(&ch->ch_neo_uart->isr_fcr); if (tmp & 2) { - jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, - "Still flushing RX UART... i: %d\n", i); + jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, + "Still flushing RX UART... i: %d\n", i); udelay(10); } else @@ -705,8 +706,9 @@ static void neo_clear_break(struct jsm_channel *ch, int force) writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr); ch->ch_flags &= ~(CH_BREAK_SENDING); - jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, - "clear break Finishing UART_LCR_SBC! finished: %lx\n", jiffies); + jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, + "clear break Finishing UART_LCR_SBC! finished: %lx\n", + jiffies); /* flush write operation */ neo_pci_posting_flush(ch->ch_bd); @@ -748,8 +750,8 @@ static inline void neo_parse_isr(struct jsm_board *brd, u32 port) */ isr &= ~(UART_17158_IIR_FIFO_ENABLED); - jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, - "%s:%d isr: %x\n", __FILE__, __LINE__, isr); + jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d isr: %x\n", + __FILE__, __LINE__, isr); if (isr & (UART_17158_IIR_RDI_TIMEOUT | UART_IIR_RDI)) { /* Read data from uart -> queue */ @@ -772,8 +774,9 @@ static inline void neo_parse_isr(struct jsm_board *brd, u32 port) if (isr & UART_17158_IIR_XONXOFF) { cause = readb(&ch->ch_neo_uart->xoffchar1); - jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, - "Port %d. Got ISR_XONXOFF: cause:%x\n", port, cause); + jsm_dbg(INTR, &ch->ch_bd->pci_dev, + "Port %d. Got ISR_XONXOFF: cause:%x\n", + port, cause); /* * Since the UART detected either an XON or @@ -786,17 +789,19 @@ static inline void neo_parse_isr(struct jsm_board *brd, u32 port) if (brd->channels[port]->ch_flags & CH_STOP) { ch->ch_flags &= ~(CH_STOP); } - jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, - "Port %d. XON detected in incoming data\n", port); + jsm_dbg(INTR, &ch->ch_bd->pci_dev, + "Port %d. XON detected in incoming data\n", + port); } else if (cause == UART_17158_XOFF_DETECT) { if (!(brd->channels[port]->ch_flags & CH_STOP)) { ch->ch_flags |= CH_STOP; - jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, - "Setting CH_STOP\n"); + jsm_dbg(INTR, &ch->ch_bd->pci_dev, + "Setting CH_STOP\n"); } - jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, - "Port: %d. XOFF detected in incoming data\n", port); + jsm_dbg(INTR, &ch->ch_bd->pci_dev, + "Port: %d. XOFF detected in incoming data\n", + port); } spin_unlock_irqrestore(&ch->ch_lock, lock_flags); } @@ -825,8 +830,8 @@ static inline void neo_parse_isr(struct jsm_board *brd, u32 port) } /* Parse any modem signal changes */ - jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, - "MOD_STAT: sending to parse_modem_sigs\n"); + jsm_dbg(INTR, &ch->ch_bd->pci_dev, + "MOD_STAT: sending to parse_modem_sigs\n"); neo_parse_modem(ch, readb(&ch->ch_neo_uart->msr)); } } @@ -849,8 +854,8 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port) linestatus = readb(&ch->ch_neo_uart->lsr); - jsm_printk(INTR, INFO, &ch->ch_bd->pci_dev, - "%s:%d port: %d linestatus: %x\n", __FILE__, __LINE__, port, linestatus); + jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d port: %d linestatus: %x\n", + __FILE__, __LINE__, port, linestatus); ch->ch_cached_lsr |= linestatus; @@ -869,7 +874,7 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port) *to do the special RX+LSR read for this FIFO load. */ if (linestatus & UART_17158_RX_FIFO_DATA_ERROR) - jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, + jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d Port: %d Got an RX error, need to parse LSR\n", __FILE__, __LINE__, port); @@ -880,20 +885,21 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port) if (linestatus & UART_LSR_PE) { ch->ch_err_parity++; - jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, - "%s:%d Port: %d. PAR ERR!\n", __FILE__, __LINE__, port); + jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d Port: %d. PAR ERR!\n", + __FILE__, __LINE__, port); } if (linestatus & UART_LSR_FE) { ch->ch_err_frame++; - jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, - "%s:%d Port: %d. FRM ERR!\n", __FILE__, __LINE__, port); + jsm_dbg(INTR, &ch->ch_bd->pci_dev, "%s:%d Port: %d. FRM ERR!\n", + __FILE__, __LINE__, port); } if (linestatus & UART_LSR_BI) { ch->ch_err_break++; - jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, - "%s:%d Port: %d. BRK INTR!\n", __FILE__, __LINE__, port); + jsm_dbg(INTR, &ch->ch_bd->pci_dev, + "%s:%d Port: %d. BRK INTR!\n", + __FILE__, __LINE__, port); } if (linestatus & UART_LSR_OE) { @@ -904,8 +910,9 @@ static inline void neo_parse_lsr(struct jsm_board *brd, u32 port) * Probably we should eventually have an orun stat in our driver... */ ch->ch_err_overrun++; - jsm_printk(INTR, DEBUG, &ch->ch_bd->pci_dev, - "%s:%d Port: %d. Rx Overrun!\n", __FILE__, __LINE__, port); + jsm_dbg(INTR, &ch->ch_bd->pci_dev, + "%s:%d Port: %d. Rx Overrun!\n", + __FILE__, __LINE__, port); } if (linestatus & UART_LSR_THRE) { @@ -1128,11 +1135,11 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) */ uart_poll = readl(brd->re_map_membase + UART_17158_POLL_ADDR_OFFSET); - jsm_printk(INTR, INFO, &brd->pci_dev, - "%s:%d uart_poll: %x\n", __FILE__, __LINE__, uart_poll); + jsm_dbg(INTR, &brd->pci_dev, "%s:%d uart_poll: %x\n", + __FILE__, __LINE__, uart_poll); if (!uart_poll) { - jsm_printk(INTR, INFO, &brd->pci_dev, + jsm_dbg(INTR, &brd->pci_dev, "Kernel interrupted to me, but no pending interrupts...\n"); spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags); return IRQ_NONE; @@ -1158,15 +1165,15 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) continue; } - jsm_printk(INTR, INFO, &brd->pci_dev, - "%s:%d port: %x type: %x\n", __FILE__, __LINE__, port, type); + jsm_dbg(INTR, &brd->pci_dev, "%s:%d port: %x type: %x\n", + __FILE__, __LINE__, port, type); /* Remove this port + type from uart_poll */ uart_poll &= ~(jsm_offset_table[port]); if (!type) { /* If no type, just ignore it, and move onto next port */ - jsm_printk(INTR, ERR, &brd->pci_dev, + jsm_dbg(INTR, &brd->pci_dev, "Interrupt with no type! port: %d\n", port); continue; } @@ -1231,15 +1238,16 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) * these once and awhile. * Its harmless, just ignore it and move on. */ - jsm_printk(INTR, ERR, &brd->pci_dev, - "%s:%d Unknown Interrupt type: %x\n", __FILE__, __LINE__, type); + jsm_dbg(INTR, &brd->pci_dev, + "%s:%d Unknown Interrupt type: %x\n", + __FILE__, __LINE__, type); continue; } } spin_unlock_irqrestore(&brd->bd_intr_lock, lock_flags); - jsm_printk(INTR, INFO, &brd->pci_dev, "finish.\n"); + jsm_dbg(INTR, &brd->pci_dev, "finish\n"); return IRQ_HANDLED; } diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 71397961773..7d2c1f3aa36 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c @@ -43,7 +43,7 @@ static inline int jsm_get_mstat(struct jsm_channel *ch) unsigned char mstat; unsigned result; - jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "start\n"); + jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "start\n"); mstat = (ch->ch_mostat | ch->ch_mistat); @@ -62,7 +62,7 @@ static inline int jsm_get_mstat(struct jsm_channel *ch) if (mstat & UART_MSR_DCD) result |= TIOCM_CD; - jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); + jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "finish\n"); return result; } @@ -79,14 +79,14 @@ static unsigned int jsm_tty_get_mctrl(struct uart_port *port) int result; struct jsm_channel *channel = (struct jsm_channel *)port; - jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n"); + jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n"); result = jsm_get_mstat(channel); if (result < 0) return -ENXIO; - jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n"); + jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "finish\n"); return result; } @@ -100,7 +100,7 @@ static void jsm_tty_set_mctrl(struct uart_port *port, unsigned int mctrl) { struct jsm_channel *channel = (struct jsm_channel *)port; - jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n"); + jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n"); if (mctrl & TIOCM_RTS) channel->ch_mostat |= UART_MCR_RTS; @@ -114,7 +114,7 @@ static void jsm_tty_set_mctrl(struct uart_port *port, unsigned int mctrl) channel->ch_bd->bd_ops->assert_modem_signals(channel); - jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n"); + jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "finish\n"); udelay(10); } @@ -135,23 +135,23 @@ static void jsm_tty_start_tx(struct uart_port *port) { struct jsm_channel *channel = (struct jsm_channel *)port; - jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n"); + jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n"); channel->ch_flags &= ~(CH_STOP); jsm_tty_write(port); - jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n"); + jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "finish\n"); } static void jsm_tty_stop_tx(struct uart_port *port) { struct jsm_channel *channel = (struct jsm_channel *)port; - jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "start\n"); + jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "start\n"); channel->ch_flags |= (CH_STOP); - jsm_printk(IOCTL, INFO, &channel->ch_bd->pci_dev, "finish\n"); + jsm_dbg(IOCTL, &channel->ch_bd->pci_dev, "finish\n"); } static void jsm_tty_send_xchar(struct uart_port *port, char ch) @@ -216,16 +216,16 @@ static int jsm_tty_open(struct uart_port *port) if (!channel->ch_rqueue) { channel->ch_rqueue = kzalloc(RQUEUESIZE, GFP_KERNEL); if (!channel->ch_rqueue) { - jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev, - "unable to allocate read queue buf"); + jsm_dbg(INIT, &channel->ch_bd->pci_dev, + "unable to allocate read queue buf\n"); return -ENOMEM; } } if (!channel->ch_equeue) { channel->ch_equeue = kzalloc(EQUEUESIZE, GFP_KERNEL); if (!channel->ch_equeue) { - jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev, - "unable to allocate error queue buf"); + jsm_dbg(INIT, &channel->ch_bd->pci_dev, + "unable to allocate error queue buf\n"); return -ENOMEM; } } @@ -234,7 +234,7 @@ static int jsm_tty_open(struct uart_port *port) /* * Initialize if neither terminal is open. */ - jsm_printk(OPEN, INFO, &channel->ch_bd->pci_dev, + jsm_dbg(OPEN, &channel->ch_bd->pci_dev, "jsm_open: initializing channel in open...\n"); /* @@ -270,7 +270,7 @@ static int jsm_tty_open(struct uart_port *port) channel->ch_open_count++; - jsm_printk(OPEN, INFO, &channel->ch_bd->pci_dev, "finish\n"); + jsm_dbg(OPEN, &channel->ch_bd->pci_dev, "finish\n"); return 0; } @@ -280,7 +280,7 @@ static void jsm_tty_close(struct uart_port *port) struct ktermios *ts; struct jsm_channel *channel = (struct jsm_channel *)port; - jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n"); + jsm_dbg(CLOSE, &channel->ch_bd->pci_dev, "start\n"); bd = channel->ch_bd; ts = &port->state->port.tty->termios; @@ -293,7 +293,7 @@ static void jsm_tty_close(struct uart_port *port) * If we have HUPCL set, lower DTR and RTS */ if (channel->ch_c_cflag & HUPCL) { - jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, + jsm_dbg(CLOSE, &channel->ch_bd->pci_dev, "Close. HUPCL set, dropping DTR/RTS\n"); /* Drop RTS/DTR */ @@ -304,7 +304,7 @@ static void jsm_tty_close(struct uart_port *port) /* Turn off UART interrupts for this port */ channel->ch_bd->bd_ops->uart_off(channel); - jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "finish\n"); + jsm_dbg(CLOSE, &channel->ch_bd->pci_dev, "finish\n"); } static void jsm_tty_set_termios(struct uart_port *port, @@ -380,7 +380,7 @@ int __devinit jsm_tty_init(struct jsm_board *brd) if (!brd) return -ENXIO; - jsm_printk(INIT, INFO, &brd->pci_dev, "start\n"); + jsm_dbg(INIT, &brd->pci_dev, "start\n"); /* * Initialize board structure elements. @@ -401,9 +401,9 @@ int __devinit jsm_tty_init(struct jsm_board *brd) */ brd->channels[i] = kzalloc(sizeof(struct jsm_channel), GFP_KERNEL); if (!brd->channels[i]) { - jsm_printk(CORE, ERR, &brd->pci_dev, + jsm_dbg(CORE, &brd->pci_dev, "%s:%d Unable to allocate memory for channel struct\n", - __FILE__, __LINE__); + __FILE__, __LINE__); } } } @@ -431,7 +431,7 @@ int __devinit jsm_tty_init(struct jsm_board *brd) init_waitqueue_head(&ch->ch_flags_wait); } - jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n"); + jsm_dbg(INIT, &brd->pci_dev, "finish\n"); return 0; } @@ -444,7 +444,7 @@ int jsm_uart_port_init(struct jsm_board *brd) if (!brd) return -ENXIO; - jsm_printk(INIT, INFO, &brd->pci_dev, "start\n"); + jsm_dbg(INIT, &brd->pci_dev, "start\n"); /* * Initialize board structure elements. @@ -481,7 +481,7 @@ int jsm_uart_port_init(struct jsm_board *brd) printk(KERN_INFO "jsm: Port %d added\n", i); } - jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n"); + jsm_dbg(INIT, &brd->pci_dev, "finish\n"); return 0; } @@ -493,7 +493,7 @@ int jsm_remove_uart_port(struct jsm_board *brd) if (!brd) return -ENXIO; - jsm_printk(INIT, INFO, &brd->pci_dev, "start\n"); + jsm_dbg(INIT, &brd->pci_dev, "start\n"); /* * Initialize board structure elements. @@ -513,7 +513,7 @@ int jsm_remove_uart_port(struct jsm_board *brd) uart_remove_one_port(&jsm_uart_driver, &brd->channels[i]->uart_port); } - jsm_printk(INIT, INFO, &brd->pci_dev, "finish\n"); + jsm_dbg(INIT, &brd->pci_dev, "finish\n"); return 0; } @@ -531,7 +531,7 @@ void jsm_input(struct jsm_channel *ch) int s = 0; int i = 0; - jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start\n"); + jsm_dbg(READ, &ch->ch_bd->pci_dev, "start\n"); if (!ch) return; @@ -560,7 +560,7 @@ void jsm_input(struct jsm_channel *ch) return; } - jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start\n"); + jsm_dbg(READ, &ch->ch_bd->pci_dev, "start\n"); /* *If the device is not open, or CREAD is off, flush @@ -569,8 +569,9 @@ void jsm_input(struct jsm_channel *ch) if (!tp || !(tp->termios.c_cflag & CREAD) ) { - jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, - "input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum); + jsm_dbg(READ, &ch->ch_bd->pci_dev, + "input. dropping %d bytes on port %d...\n", + data_len, ch->ch_portnum); ch->ch_r_head = tail; /* Force queue flow control to be released, if needed */ @@ -585,17 +586,17 @@ void jsm_input(struct jsm_channel *ch) */ if (ch->ch_flags & CH_STOPI) { spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, + jsm_dbg(READ, &ch->ch_bd->pci_dev, "Port %d throttled, not reading any data. head: %x tail: %x\n", ch->ch_portnum, head, tail); return; } - jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "start 2\n"); + jsm_dbg(READ, &ch->ch_bd->pci_dev, "start 2\n"); if (data_len <= 0) { spin_unlock_irqrestore(&ch->ch_lock, lock_flags); - jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n"); + jsm_dbg(READ, &ch->ch_bd->pci_dev, "jsm_input 1\n"); return; } @@ -653,7 +654,7 @@ void jsm_input(struct jsm_channel *ch) /* Tell the tty layer its okay to "eat" the data now */ tty_flip_buffer_push(tp); - jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); + jsm_dbg(IOCTL, &ch->ch_bd->pci_dev, "finish\n"); } static void jsm_carrier(struct jsm_channel *ch) @@ -663,7 +664,7 @@ static void jsm_carrier(struct jsm_channel *ch) int virt_carrier = 0; int phys_carrier = 0; - jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev, "start\n"); + jsm_dbg(CARR, &ch->ch_bd->pci_dev, "start\n"); if (!ch) return; @@ -673,16 +674,16 @@ static void jsm_carrier(struct jsm_channel *ch) return; if (ch->ch_mistat & UART_MSR_DCD) { - jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev, - "mistat: %x D_CD: %x\n", ch->ch_mistat, ch->ch_mistat & UART_MSR_DCD); + jsm_dbg(CARR, &ch->ch_bd->pci_dev, "mistat: %x D_CD: %x\n", + ch->ch_mistat, ch->ch_mistat & UART_MSR_DCD); phys_carrier = 1; } if (ch->ch_c_cflag & CLOCAL) virt_carrier = 1; - jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev, - "DCD: physical: %d virt: %d\n", phys_carrier, virt_carrier); + jsm_dbg(CARR, &ch->ch_bd->pci_dev, "DCD: physical: %d virt: %d\n", + phys_carrier, virt_carrier); /* * Test for a VIRTUAL carrier transition to HIGH. @@ -694,8 +695,7 @@ static void jsm_carrier(struct jsm_channel *ch) * for carrier in the open routine. */ - jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev, - "carrier: virt DCD rose\n"); + jsm_dbg(CARR, &ch->ch_bd->pci_dev, "carrier: virt DCD rose\n"); if (waitqueue_active(&(ch->ch_flags_wait))) wake_up_interruptible(&ch->ch_flags_wait); @@ -711,7 +711,7 @@ static void jsm_carrier(struct jsm_channel *ch) * for carrier in the open routine. */ - jsm_printk(CARR, INFO, &ch->ch_bd->pci_dev, + jsm_dbg(CARR, &ch->ch_bd->pci_dev, "carrier: physical DCD rose\n"); if (waitqueue_active(&(ch->ch_flags_wait))) @@ -790,8 +790,8 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) if(!(ch->ch_flags & CH_RECEIVER_OFF)) { bd_ops->disable_receiver(ch); ch->ch_flags |= (CH_RECEIVER_OFF); - jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, - "Internal queue hit hilevel mark (%d)! Turning off interrupts.\n", + jsm_dbg(READ, &ch->ch_bd->pci_dev, + "Internal queue hit hilevel mark (%d)! Turning off interrupts\n", qleft); } } @@ -800,8 +800,9 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) if (ch->ch_stops_sent <= MAX_STOPS_SENT) { bd_ops->send_stop_character(ch); ch->ch_stops_sent++; - jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, - "Sending stop char! Times sent: %x\n", ch->ch_stops_sent); + jsm_dbg(READ, &ch->ch_bd->pci_dev, + "Sending stop char! Times sent: %x\n", + ch->ch_stops_sent); } } } @@ -827,8 +828,8 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) if (ch->ch_flags & CH_RECEIVER_OFF) { bd_ops->enable_receiver(ch); ch->ch_flags &= ~(CH_RECEIVER_OFF); - jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, - "Internal queue hit lowlevel mark (%d)! Turning on interrupts.\n", + jsm_dbg(READ, &ch->ch_bd->pci_dev, + "Internal queue hit lowlevel mark (%d)! Turning on interrupts\n", qleft); } } @@ -836,7 +837,8 @@ void jsm_check_queue_flow_control(struct jsm_channel *ch) else if (ch->ch_c_iflag & IXOFF && ch->ch_stops_sent) { ch->ch_stops_sent = 0; bd_ops->send_start_character(ch); - jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "Sending start char!\n"); + jsm_dbg(READ, &ch->ch_bd->pci_dev, + "Sending start char!\n"); } } } -- cgit v1.2.3 From 15a12e83da812e9116577d46b048923587da5000 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 26 Oct 2012 23:04:22 +0800 Subject: serial: 8250_pci: use module_pci_driver to simplify the code Use the module_pci_driver() macro to make the code simpler by eliminating module_init and module_exit calls. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index cec8852dd1b..508063b2a4b 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -4332,18 +4332,7 @@ static struct pci_driver serial_pci_driver = { .err_handler = &serial8250_err_handler, }; -static int __init serial8250_pci_init(void) -{ - return pci_register_driver(&serial_pci_driver); -} - -static void __exit serial8250_pci_exit(void) -{ - pci_unregister_driver(&serial_pci_driver); -} - -module_init(serial8250_pci_init); -module_exit(serial8250_pci_exit); +module_pci_driver(serial_pci_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module"); -- cgit v1.2.3 From bebe73e31d98845c8b63e624c25a5da2d819345a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 29 Oct 2012 15:19:57 +0000 Subject: uart: update the sysfs handler to use uart_get_info The two patches needed are now in the tree. The first added the sysfs interface and directly accesses the uartclk. The second provides a proper interface for getting the values. Wire them together. This formes a basis for both get and set methods for any of the other uart properties and we can now fill them out further. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 0fcfd98a956..477e0790ddf 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2329,15 +2329,15 @@ struct tty_driver *uart_console_device(struct console *co, int *index) static ssize_t uart_get_attr_uartclk(struct device *dev, struct device_attribute *attr, char *buf) { - int ret; + struct serial_struct tmp; struct tty_port *port = dev_get_drvdata(dev); struct uart_state *state = container_of(port, struct uart_state, port); - mutex_lock(&state->port.mutex); - ret = snprintf(buf, PAGE_SIZE, "%d\n", state->uart_port->uartclk); - mutex_unlock(&state->port.mutex); + mutex_lock(&port->mutex); + uart_get_info(port, state, &tmp); + mutex_unlock(&port->mutex); - return ret; + return snprintf(buf, PAGE_SIZE, "%d\n", tmp.baud_base * 16); } static DEVICE_ATTR(uartclk, S_IRUSR | S_IRGRP, uart_get_attr_uartclk, NULL); -- cgit v1.2.3 From 9f1096943a56c35cc85a0729ec759fd8a25e552f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 29 Oct 2012 15:20:25 +0000 Subject: uart: tidy the uart_get_info API We pass both port and state because the original caller had both to hand. With all the attribute callers this won't be true so do the conversion in the function itself. The current callers all do lock/query/unlock. This won't be true for future set based cases but there are plenty of get ones that will exist so split the code with a helper for the future cases. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 477e0790ddf..0c4304ef66d 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -634,10 +634,10 @@ static void uart_unthrottle(struct tty_struct *tty) uart_set_mctrl(port, TIOCM_RTS); } -static void uart_get_info(struct tty_port *port, - struct uart_state *state, +static void do_uart_get_info(struct tty_port *port, struct serial_struct *retinfo) { + struct uart_state *state = container_of(port, struct uart_state, port); struct uart_port *uport = state->uart_port; memset(retinfo, 0, sizeof(*retinfo)); @@ -662,17 +662,21 @@ static void uart_get_info(struct tty_port *port, retinfo->iomem_base = (void *)(unsigned long)uport->mapbase; } -static int uart_get_info_user(struct uart_state *state, - struct serial_struct __user *retinfo) +static void uart_get_info(struct tty_port *port, + struct serial_struct *retinfo) { - struct tty_port *port = &state->port; - struct serial_struct tmp; - /* Ensure the state we copy is consistent and no hardware changes occur as we go */ mutex_lock(&port->mutex); - uart_get_info(port, state, &tmp); + do_uart_get_info(port, retinfo); mutex_unlock(&port->mutex); +} + +static int uart_get_info_user(struct tty_port *port, + struct serial_struct __user *retinfo) +{ + struct serial_struct tmp; + uart_get_info(port, &tmp); if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) return -EFAULT; @@ -1131,7 +1135,7 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, */ switch (cmd) { case TIOCGSERIAL: - ret = uart_get_info_user(state, uarg); + ret = uart_get_info_user(port, uarg); break; case TIOCSSERIAL: @@ -2331,12 +2335,8 @@ static ssize_t uart_get_attr_uartclk(struct device *dev, { struct serial_struct tmp; struct tty_port *port = dev_get_drvdata(dev); - struct uart_state *state = container_of(port, struct uart_state, port); - - mutex_lock(&port->mutex); - uart_get_info(port, state, &tmp); - mutex_unlock(&port->mutex); + uart_get_info(port, &tmp); return snprintf(buf, PAGE_SIZE, "%d\n", tmp.baud_base * 16); } @@ -2356,6 +2356,7 @@ static const struct attribute_group *tty_dev_attr_groups[] = { NULL }; + /** * uart_add_one_port - attach a driver-defined port structure * @drv: pointer to the uart low level driver structure for this port -- cgit v1.2.3 From 373bac4cf4c3198cc6d6b9aec7c5d576a06f1f1c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 29 Oct 2012 15:20:40 +0000 Subject: uart: add other serial core layer get attributes Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-tty | 112 ++++++++++++++++++++++++++++ drivers/tty/serial/serial_core.c | 145 ++++++++++++++++++++++++++++++++++++ 2 files changed, 257 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-tty b/Documentation/ABI/testing/sysfs-tty index 0c430150d92..ad22fb0ee76 100644 --- a/Documentation/ABI/testing/sysfs-tty +++ b/Documentation/ABI/testing/sysfs-tty @@ -26,3 +26,115 @@ Description: UART port in serial_core, that is bound to TTY like ttyS0. uartclk = 16 * baud_base + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/type +Date: October 2012 +Contact: Alan Cox +Description: + Shows the current tty type for this port. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/line +Date: October 2012 +Contact: Alan Cox +Description: + Shows the current tty line number for this port. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/port +Date: October 2012 +Contact: Alan Cox +Description: + Shows the current tty port I/O address for this port. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/irq +Date: October 2012 +Contact: Alan Cox +Description: + Shows the current primary interrupt for this port. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/flags +Date: October 2012 +Contact: Alan Cox +Description: + Show the tty port status flags for this port. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/xmit_fifo_size +Date: October 2012 +Contact: Alan Cox +Description: + Show the transmit FIFO size for this port. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/close_delay +Date: October 2012 +Contact: Alan Cox +Description: + Show the closing delay time for this port in ms. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/closing_wait +Date: October 2012 +Contact: Alan Cox +Description: + Show the close wait time for this port in ms. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/custom_divisor +Date: October 2012 +Contact: Alan Cox +Description: + Show the custom divisor if any that is set on this port. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/io_type +Date: October 2012 +Contact: Alan Cox +Description: + Show the I/O type that is to be used with the iomem base + address. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/iomem_base +Date: October 2012 +Contact: Alan Cox +Description: + The I/O memory base for this port. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. + +What: /sys/class/tty/ttyS0/iomem_reg_shift +Date: October 2012 +Contact: Alan Cox +Description: + Show the register shift indicating the spacing to be used + for accesses on this iomem address. + + These sysfs values expose the TIOCGSERIAL interface via + sysfs rather than via ioctls. diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 0c4304ef66d..d3dd4ad984f 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2340,10 +2340,155 @@ static ssize_t uart_get_attr_uartclk(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", tmp.baud_base * 16); } +static ssize_t uart_get_attr_type(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct serial_struct tmp; + struct tty_port *port = dev_get_drvdata(dev); + + uart_get_info(port, &tmp); + return snprintf(buf, PAGE_SIZE, "%d\n", tmp.type); +} +static ssize_t uart_get_attr_line(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct serial_struct tmp; + struct tty_port *port = dev_get_drvdata(dev); + + uart_get_info(port, &tmp); + return snprintf(buf, PAGE_SIZE, "%d\n", tmp.line); +} + +static ssize_t uart_get_attr_port(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct serial_struct tmp; + struct tty_port *port = dev_get_drvdata(dev); + + uart_get_info(port, &tmp); + return snprintf(buf, PAGE_SIZE, "0x%lX\n", (unsigned long)(tmp.port | (tmp.port_high << HIGH_BITS_OFFSET))); +} + +static ssize_t uart_get_attr_irq(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct serial_struct tmp; + struct tty_port *port = dev_get_drvdata(dev); + + uart_get_info(port, &tmp); + return snprintf(buf, PAGE_SIZE, "%d\n", tmp.irq); +} + +static ssize_t uart_get_attr_flags(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct serial_struct tmp; + struct tty_port *port = dev_get_drvdata(dev); + + uart_get_info(port, &tmp); + return snprintf(buf, PAGE_SIZE, "0x%X\n", tmp.flags); +} + +static ssize_t uart_get_attr_xmit_fifo_size(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct serial_struct tmp; + struct tty_port *port = dev_get_drvdata(dev); + + uart_get_info(port, &tmp); + return snprintf(buf, PAGE_SIZE, "%d\n", tmp.xmit_fifo_size); +} + + +static ssize_t uart_get_attr_close_delay(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct serial_struct tmp; + struct tty_port *port = dev_get_drvdata(dev); + + uart_get_info(port, &tmp); + return snprintf(buf, PAGE_SIZE, "%d\n", tmp.close_delay); +} + + +static ssize_t uart_get_attr_closing_wait(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct serial_struct tmp; + struct tty_port *port = dev_get_drvdata(dev); + + uart_get_info(port, &tmp); + return snprintf(buf, PAGE_SIZE, "%d\n", tmp.closing_wait); +} + +static ssize_t uart_get_attr_custom_divisor(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct serial_struct tmp; + struct tty_port *port = dev_get_drvdata(dev); + + uart_get_info(port, &tmp); + return snprintf(buf, PAGE_SIZE, "%d\n", tmp.custom_divisor); +} + +static ssize_t uart_get_attr_io_type(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct serial_struct tmp; + struct tty_port *port = dev_get_drvdata(dev); + + uart_get_info(port, &tmp); + return snprintf(buf, PAGE_SIZE, "%d\n", tmp.io_type); +} + +static ssize_t uart_get_attr_iomem_base(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct serial_struct tmp; + struct tty_port *port = dev_get_drvdata(dev); + + uart_get_info(port, &tmp); + return snprintf(buf, PAGE_SIZE, "0x%lX\n", (unsigned long)tmp.iomem_base); +} + +static ssize_t uart_get_attr_iomem_reg_shift(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct serial_struct tmp; + struct tty_port *port = dev_get_drvdata(dev); + + uart_get_info(port, &tmp); + return snprintf(buf, PAGE_SIZE, "%d\n", tmp.iomem_reg_shift); +} + +static DEVICE_ATTR(type, S_IRUSR | S_IRGRP, uart_get_attr_type, NULL); +static DEVICE_ATTR(line, S_IRUSR | S_IRGRP, uart_get_attr_line, NULL); +static DEVICE_ATTR(port, S_IRUSR | S_IRGRP, uart_get_attr_port, NULL); +static DEVICE_ATTR(irq, S_IRUSR | S_IRGRP, uart_get_attr_irq, NULL); +static DEVICE_ATTR(flags, S_IRUSR | S_IRGRP, uart_get_attr_flags, NULL); +static DEVICE_ATTR(xmit_fifo_size, S_IRUSR | S_IRGRP, uart_get_attr_xmit_fifo_size, NULL); static DEVICE_ATTR(uartclk, S_IRUSR | S_IRGRP, uart_get_attr_uartclk, NULL); +static DEVICE_ATTR(close_delay, S_IRUSR | S_IRGRP, uart_get_attr_close_delay, NULL); +static DEVICE_ATTR(closing_wait, S_IRUSR | S_IRGRP, uart_get_attr_closing_wait, NULL); +static DEVICE_ATTR(custom_divisor, S_IRUSR | S_IRGRP, uart_get_attr_custom_divisor, NULL); +static DEVICE_ATTR(io_type, S_IRUSR | S_IRGRP, uart_get_attr_io_type, NULL); +static DEVICE_ATTR(iomem_base, S_IRUSR | S_IRGRP, uart_get_attr_iomem_base, NULL); +static DEVICE_ATTR(iomem_reg_shift, S_IRUSR | S_IRGRP, uart_get_attr_iomem_reg_shift, NULL); static struct attribute *tty_dev_attrs[] = { + &dev_attr_type.attr, + &dev_attr_line.attr, + &dev_attr_port.attr, + &dev_attr_irq.attr, + &dev_attr_flags.attr, + &dev_attr_xmit_fifo_size.attr, &dev_attr_uartclk.attr, + &dev_attr_close_delay.attr, + &dev_attr_closing_wait.attr, + &dev_attr_custom_divisor.attr, + &dev_attr_io_type.attr, + &dev_attr_iomem_base.attr, + &dev_attr_iomem_reg_shift.attr, NULL, }; -- cgit v1.2.3 From 2ac4ad2a1468123f6bb439a547880a9c0d302e0a Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Sat, 27 Oct 2012 12:47:12 +0530 Subject: serial/arc-uart: Add new driver Driver for non-standard on-chip UART, instantiated in the ARC (Synopsys) FPGA Boards such as ARCAngel4/ML50x Signed-off-by: Vineet Gupta Reviewed-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 23 ++ drivers/tty/serial/Makefile | 1 + drivers/tty/serial/arc_uart.c | 746 +++++++++++++++++++++++++++++++++++++++ include/uapi/linux/serial_core.h | 2 + 4 files changed, 772 insertions(+) create mode 100644 drivers/tty/serial/arc_uart.c diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 2a53be5f010..b1768012ed2 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1423,4 +1423,27 @@ config SERIAL_EFM32_UART_CONSOLE depends on SERIAL_EFM32_UART=y select SERIAL_CORE_CONSOLE +config SERIAL_ARC + tristate "ARC UART driver support" + select SERIAL_CORE + help + Driver for on-chip UART for ARC(Synopsys) for the legacy + FPGA Boards (ML50x/ARCAngel4) + +config SERIAL_ARC_CONSOLE + bool "Console on ARC UART" + depends on SERIAL_ARC=y + select SERIAL_CORE_CONSOLE + help + Enable system Console on ARC UART + +config SERIAL_ARC_NR_PORTS + int "Number of ARC UART ports" + depends on SERIAL_ARC + range 1 3 + default "1" + help + Set this to the number of serial ports you want the driver + to support. + endmenu diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 4f694dafa71..df1b998c436 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -82,3 +82,4 @@ obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o +obj-$(CONFIG_SERIAL_ARC) += arc_uart.o diff --git a/drivers/tty/serial/arc_uart.c b/drivers/tty/serial/arc_uart.c new file mode 100644 index 00000000000..e9c61d1b1c7 --- /dev/null +++ b/drivers/tty/serial/arc_uart.c @@ -0,0 +1,746 @@ +/* + * ARC On-Chip(fpga) UART Driver + * + * Copyright (C) 2010-2012 Synopsys, Inc. (www.synopsys.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * vineetg: July 10th 2012 + * -Decoupled the driver from arch/arc + * +Using platform_get_resource() for irq/membase (thx to bfin_uart.c) + * +Using early_platform_xxx() for early console (thx to mach-shmobile/xxx) + * + * Vineetg: Aug 21st 2010 + * -Is uart_tx_stopped() not done in tty write path as it has already been + * taken care of, in serial core + * + * Vineetg: Aug 18th 2010 + * -New Serial Core based ARC UART driver + * -Derived largely from blackfin driver albiet with some major tweaks + * + * TODO: + * -check if sysreq works + */ + +#if defined(CONFIG_SERIAL_ARC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/************************************* + * ARC UART Hardware Specs + ************************************/ +#define ARC_UART_TX_FIFO_SIZE 1 + +/* + * UART Register set (this is not a Standards Compliant IP) + * Also each reg is Word aligned, but only 8 bits wide + */ +#define R_ID0 0 +#define R_ID1 4 +#define R_ID2 8 +#define R_ID3 12 +#define R_DATA 16 +#define R_STS 20 +#define R_BAUDL 24 +#define R_BAUDH 28 + +/* Bits for UART Status Reg (R/W) */ +#define RXIENB 0x04 /* Receive Interrupt Enable */ +#define TXIENB 0x40 /* Transmit Interrupt Enable */ + +#define RXEMPTY 0x20 /* Receive FIFO Empty: No char receivede */ +#define TXEMPTY 0x80 /* Transmit FIFO Empty, thus char can be written into */ + +#define RXFULL 0x08 /* Receive FIFO full */ +#define RXFULL1 0x10 /* Receive FIFO has space for 1 char (tot space=4) */ + +#define RXFERR 0x01 /* Frame Error: Stop Bit not detected */ +#define RXOERR 0x02 /* OverFlow Err: Char recv but RXFULL still set */ + +/* Uart bit fiddling helpers: lowest level */ +#define RBASE(uart, reg) (uart->port.membase + reg) +#define UART_REG_SET(u, r, v) writeb((v), RBASE(u, r)) +#define UART_REG_GET(u, r) readb(RBASE(u, r)) + +#define UART_REG_OR(u, r, v) UART_REG_SET(u, r, UART_REG_GET(u, r) | (v)) +#define UART_REG_CLR(u, r, v) UART_REG_SET(u, r, UART_REG_GET(u, r) & ~(v)) + +/* Uart bit fiddling helpers: API level */ +#define UART_SET_DATA(uart, val) UART_REG_SET(uart, R_DATA, val) +#define UART_GET_DATA(uart) UART_REG_GET(uart, R_DATA) + +#define UART_SET_BAUDH(uart, val) UART_REG_SET(uart, R_BAUDH, val) +#define UART_SET_BAUDL(uart, val) UART_REG_SET(uart, R_BAUDL, val) + +#define UART_CLR_STATUS(uart, val) UART_REG_CLR(uart, R_STS, val) +#define UART_GET_STATUS(uart) UART_REG_GET(uart, R_STS) + +#define UART_ALL_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, RXIENB|TXIENB) +#define UART_RX_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, RXIENB) +#define UART_TX_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, TXIENB) + +#define UART_ALL_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, RXIENB|TXIENB) +#define UART_RX_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, RXIENB) +#define UART_TX_IRQ_ENABLE(uart) UART_REG_OR(uart, R_STS, TXIENB) + +#define ARC_SERIAL_DEV_NAME "ttyARC" + +struct arc_uart_port { + struct uart_port port; + unsigned long baud; + int is_emulated; /* H/w vs. Instruction Set Simulator */ +}; + +#define to_arc_port(uport) container_of(uport, struct arc_uart_port, port) + +static struct arc_uart_port arc_uart_ports[CONFIG_SERIAL_ARC_NR_PORTS]; + +#ifdef CONFIG_SERIAL_ARC_CONSOLE +static struct console arc_console; +#endif + +#define DRIVER_NAME "arc-uart" + +static struct uart_driver arc_uart_driver = { + .owner = THIS_MODULE, + .driver_name = DRIVER_NAME, + .dev_name = ARC_SERIAL_DEV_NAME, + .major = 0, + .minor = 0, + .nr = CONFIG_SERIAL_ARC_NR_PORTS, +#ifdef CONFIG_SERIAL_ARC_CONSOLE + .cons = &arc_console, +#endif +}; + +static void arc_serial_stop_rx(struct uart_port *port) +{ + struct arc_uart_port *uart = to_arc_port(port); + + UART_RX_IRQ_DISABLE(uart); +} + +static void arc_serial_stop_tx(struct uart_port *port) +{ + struct arc_uart_port *uart = to_arc_port(port); + + while (!(UART_GET_STATUS(uart) & TXEMPTY)) + cpu_relax(); + + UART_TX_IRQ_DISABLE(uart); +} + +/* + * Return TIOCSER_TEMT when transmitter is not busy. + */ +static unsigned int arc_serial_tx_empty(struct uart_port *port) +{ + struct arc_uart_port *uart = to_arc_port(port); + unsigned int stat; + + stat = UART_GET_STATUS(uart); + if (stat & TXEMPTY) + return TIOCSER_TEMT; + + return 0; +} + +/* + * Driver internal routine, used by both tty(serial core) as well as tx-isr + * -Called under spinlock in either cases + * -also tty->stopped / tty->hw_stopped has already been checked + * = by uart_start( ) before calling us + * = tx_ist checks that too before calling + */ +static void arc_serial_tx_chars(struct arc_uart_port *uart) +{ + struct circ_buf *xmit = &uart->port.state->xmit; + int sent = 0; + unsigned char ch; + + if (unlikely(uart->port.x_char)) { + UART_SET_DATA(uart, uart->port.x_char); + uart->port.icount.tx++; + uart->port.x_char = 0; + sent = 1; + } else if (xmit->tail != xmit->head) { /* TODO: uart_circ_empty */ + ch = xmit->buf[xmit->tail]; + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + uart->port.icount.tx++; + while (!(UART_GET_STATUS(uart) & TXEMPTY)) + cpu_relax(); + UART_SET_DATA(uart, ch); + sent = 1; + } + + /* + * If num chars in xmit buffer are too few, ask tty layer for more. + * By Hard ISR to schedule processing in software interrupt part + */ + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&uart->port); + + if (sent) + UART_TX_IRQ_ENABLE(uart); +} + +/* + * port is locked and interrupts are disabled + * uart_start( ) calls us under the port spinlock irqsave + */ +static void arc_serial_start_tx(struct uart_port *port) +{ + struct arc_uart_port *uart = to_arc_port(port); + + arc_serial_tx_chars(uart); +} + +static void arc_serial_rx_chars(struct arc_uart_port *uart) +{ + struct tty_struct *tty = tty_port_tty_get(&uart->port.state->port); + unsigned int status, ch, flg = 0; + + if (!tty) + return; + + /* + * UART has 4 deep RX-FIFO. Driver's recongnition of this fact + * is very subtle. Here's how ... + * Upon getting a RX-Intr, such that RX-EMPTY=0, meaning data available, + * driver reads the DATA Reg and keeps doing that in a loop, until + * RX-EMPTY=1. Multiple chars being avail, with a single Interrupt, + * before RX-EMPTY=0, implies some sort of buffering going on in the + * controller, which is indeed the Rx-FIFO. + */ + while (!((status = UART_GET_STATUS(uart)) & RXEMPTY)) { + + ch = UART_GET_DATA(uart); + uart->port.icount.rx++; + + if (unlikely(status & (RXOERR | RXFERR))) { + if (status & RXOERR) { + uart->port.icount.overrun++; + flg = TTY_OVERRUN; + UART_CLR_STATUS(uart, RXOERR); + } + + if (status & RXFERR) { + uart->port.icount.frame++; + flg = TTY_FRAME; + UART_CLR_STATUS(uart, RXFERR); + } + } else + flg = TTY_NORMAL; + + if (unlikely(uart_handle_sysrq_char(&uart->port, ch))) + goto done; + + uart_insert_char(&uart->port, status, RXOERR, ch, flg); + +done: + tty_flip_buffer_push(tty); + } + + tty_kref_put(tty); +} + +/* + * A note on the Interrupt handling state machine of this driver + * + * kernel printk writes funnel thru the console driver framework and in order + * to keep things simple as well as efficient, it writes to UART in polled + * mode, in one shot, and exits. + * + * OTOH, Userland output (via tty layer), uses interrupt based writes as there + * can be undeterministic delay between char writes. + * + * Thus Rx-interrupts are always enabled, while tx-interrupts are by default + * disabled. + * + * When tty has some data to send out, serial core calls driver's start_tx + * which + * -checks-if-tty-buffer-has-char-to-send + * -writes-data-to-uart + * -enable-tx-intr + * + * Once data bits are pushed out, controller raises the Tx-room-avail-Interrupt. + * The first thing Tx ISR does is disable further Tx interrupts (as this could + * be the last char to send, before settling down into the quiet polled mode). + * It then calls the exact routine used by tty layer write to send out any + * more char in tty buffer. In case of sending, it re-enables Tx-intr. In case + * of no data, it remains disabled. + * This is how the transmit state machine is dynamically switched on/off + */ + +static irqreturn_t arc_serial_isr(int irq, void *dev_id) +{ + struct arc_uart_port *uart = dev_id; + unsigned int status; + + status = UART_GET_STATUS(uart); + + /* + * Single IRQ for both Rx (data available) Tx (room available) Interrupt + * notifications from the UART Controller. + * To demultiplex between the two, we check the relevant bits + */ + if ((status & RXIENB) && !(status & RXEMPTY)) { + + /* already in ISR, no need of xx_irqsave */ + spin_lock(&uart->port.lock); + arc_serial_rx_chars(uart); + spin_unlock(&uart->port.lock); + } + + if ((status & TXIENB) && (status & TXEMPTY)) { + + /* Unconditionally disable further Tx-Interrupts. + * will be enabled by tx_chars() if needed. + */ + UART_TX_IRQ_DISABLE(uart); + + spin_lock(&uart->port.lock); + + if (!uart_tx_stopped(&uart->port)) + arc_serial_tx_chars(uart); + + spin_unlock(&uart->port.lock); + } + + return IRQ_HANDLED; +} + +static unsigned int arc_serial_get_mctrl(struct uart_port *port) +{ + /* + * Pretend we have a Modem status reg and following bits are + * always set, to satify the serial core state machine + * (DSR) Data Set Ready + * (CTS) Clear To Send + * (CAR) Carrier Detect + */ + return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; +} + +static void arc_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + /* MCR not present */ +} + +/* Enable Modem Status Interrupts */ + +static void arc_serial_enable_ms(struct uart_port *port) +{ + /* MSR not present */ +} + +static void arc_serial_break_ctl(struct uart_port *port, int break_state) +{ + /* ARC UART doesn't support sending Break signal */ +} + +static int arc_serial_startup(struct uart_port *port) +{ + struct arc_uart_port *uart = to_arc_port(port); + + /* Before we hook up the ISR, Disable all UART Interrupts */ + UART_ALL_IRQ_DISABLE(uart); + + if (request_irq(uart->port.irq, arc_serial_isr, 0, "arc uart rx-tx", + uart)) { + dev_warn(uart->port.dev, "Unable to attach ARC UART intr\n"); + return -EBUSY; + } + + UART_RX_IRQ_ENABLE(uart); /* Only Rx IRQ enabled to begin with */ + + return 0; +} + +/* This is not really needed */ +static void arc_serial_shutdown(struct uart_port *port) +{ + struct arc_uart_port *uart = to_arc_port(port); + free_irq(uart->port.irq, uart); +} + +static void +arc_serial_set_termios(struct uart_port *port, struct ktermios *new, + struct ktermios *old) +{ + struct arc_uart_port *uart = to_arc_port(port); + unsigned int baud, uartl, uarth, hw_val; + unsigned long flags; + + /* + * Use the generic handler so that any specially encoded baud rates + * such as SPD_xx flags or "%B0" can be handled + * Max Baud I suppose will not be more than current 115K * 4 + * Formula for ARC UART is: hw-val = ((CLK/(BAUD*4)) -1) + * spread over two 8-bit registers + */ + baud = uart_get_baud_rate(port, new, old, 0, 460800); + + hw_val = port->uartclk / (uart->baud * 4) - 1; + uartl = hw_val & 0xFF; + uarth = (hw_val >> 8) & 0xFF; + + /* + * UART ISS(Instruction Set simulator) emulation has a subtle bug: + * A existing value of Baudh = 0 is used as a indication to startup + * it's internal state machine. + * Thus if baudh is set to 0, 2 times, it chokes. + * This happens with BAUD=115200 and the formaula above + * Until that is fixed, when running on ISS, we will set baudh to !0 + */ + if (uart->is_emulated) + uarth = 1; + + spin_lock_irqsave(&port->lock, flags); + + UART_ALL_IRQ_DISABLE(uart); + + UART_SET_BAUDL(uart, uartl); + UART_SET_BAUDH(uart, uarth); + + UART_RX_IRQ_ENABLE(uart); + + /* + * UART doesn't support Parity/Hardware Flow Control; + * Only supports 8N1 character size + */ + new->c_cflag &= ~(CMSPAR|CRTSCTS|CSIZE); + new->c_cflag |= CS8; + + if (old) + tty_termios_copy_hw(new, old); + + /* Don't rewrite B0 */ + if (tty_termios_baud_rate(new)) + tty_termios_encode_baud_rate(new, baud, baud); + + uart_update_timeout(port, new->c_cflag, baud); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char *arc_serial_type(struct uart_port *port) +{ + struct arc_uart_port *uart = to_arc_port(port); + + return uart->port.type == PORT_ARC ? DRIVER_NAME : NULL; +} + +static void arc_serial_release_port(struct uart_port *port) +{ +} + +static int arc_serial_request_port(struct uart_port *port) +{ + return 0; +} + +/* + * Verify the new serial_struct (for TIOCSSERIAL). + */ +static int +arc_serial_verify_port(struct uart_port *port, struct serial_struct *ser) +{ + if (port->type != PORT_UNKNOWN && ser->type != PORT_ARC) + return -EINVAL; + + return 0; +} + +/* + * Configure/autoconfigure the port. + */ +static void arc_serial_config_port(struct uart_port *port, int flags) +{ + struct arc_uart_port *uart = to_arc_port(port); + + if (flags & UART_CONFIG_TYPE) + uart->port.type = PORT_ARC; +} + +#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_ARC_CONSOLE) + +static void arc_serial_poll_putchar(struct uart_port *port, unsigned char chr) +{ + struct arc_uart_port *uart = to_arc_port(port); + + while (!(UART_GET_STATUS(uart) & TXEMPTY)) + cpu_relax(); + + UART_SET_DATA(uart, chr); +} +#endif + +#ifdef CONFIG_CONSOLE_POLL +static int arc_serial_poll_getchar(struct uart_port *port) +{ + struct arc_uart_port *uart = to_arc_port(port); + unsigned char chr; + + while (!(UART_GET_STATUS(uart) & RXEMPTY)) + cpu_relax(); + + chr = UART_GET_DATA(uart); + return chr; +} +#endif + +static struct uart_ops arc_serial_pops = { + .tx_empty = arc_serial_tx_empty, + .set_mctrl = arc_serial_set_mctrl, + .get_mctrl = arc_serial_get_mctrl, + .stop_tx = arc_serial_stop_tx, + .start_tx = arc_serial_start_tx, + .stop_rx = arc_serial_stop_rx, + .enable_ms = arc_serial_enable_ms, + .break_ctl = arc_serial_break_ctl, + .startup = arc_serial_startup, + .shutdown = arc_serial_shutdown, + .set_termios = arc_serial_set_termios, + .type = arc_serial_type, + .release_port = arc_serial_release_port, + .request_port = arc_serial_request_port, + .config_port = arc_serial_config_port, + .verify_port = arc_serial_verify_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_put_char = arc_serial_poll_putchar, + .poll_get_char = arc_serial_poll_getchar, +#endif +}; + +static int __devinit +arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart) +{ + struct resource *res, *res2; + unsigned long *plat_data; + + if (pdev->id < 0 || pdev->id >= CONFIG_SERIAL_ARC_NR_PORTS) { + dev_err(&pdev->dev, "Wrong uart platform device id.\n"); + return -ENOENT; + } + + plat_data = ((unsigned long *)(pdev->dev.platform_data)); + uart->baud = plat_data[0]; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res2) + return -ENODEV; + + uart->port.mapbase = res->start; + uart->port.membase = ioremap_nocache(res->start, resource_size(res)); + if (!uart->port.membase) + /* No point of dev_err since UART itself is hosed here */ + return -ENXIO; + + uart->port.irq = res2->start; + uart->port.dev = &pdev->dev; + uart->port.iotype = UPIO_MEM; + uart->port.flags = UPF_BOOT_AUTOCONF; + uart->port.line = pdev->id; + uart->port.ops = &arc_serial_pops; + + uart->port.uartclk = plat_data[1]; + uart->port.fifosize = ARC_UART_TX_FIFO_SIZE; + + /* + * uart_insert_char( ) uses it in decideding whether to ignore a + * char or not. Explicitly setting it here, removes the subtelty + */ + uart->port.ignore_status_mask = 0; + + /* Real Hardware vs. emulated to work around a bug */ + uart->is_emulated = !!plat_data[2]; + + return 0; +} + +#ifdef CONFIG_SERIAL_ARC_CONSOLE + +static int __devinit arc_serial_console_setup(struct console *co, char *options) +{ + struct uart_port *port; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + if (co->index < 0 || co->index >= CONFIG_SERIAL_ARC_NR_PORTS) + return -ENODEV; + + /* + * The uart port backing the console (e.g. ttyARC1) might not have been + * init yet. If so, defer the console setup to after the port. + */ + port = &arc_uart_ports[co->index].port; + if (!port->membase) + return -ENODEV; + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + + /* + * Serial core will call port->ops->set_termios( ) + * which will set the baud reg + */ + return uart_set_options(port, co, baud, parity, bits, flow); +} + +static void arc_serial_console_putchar(struct uart_port *port, int ch) +{ + arc_serial_poll_putchar(port, (unsigned char)ch); +} + +/* + * Interrupts are disabled on entering + */ +static void arc_serial_console_write(struct console *co, const char *s, + unsigned int count) +{ + struct uart_port *port = &arc_uart_ports[co->index].port; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + uart_console_write(port, s, count, arc_serial_console_putchar); + spin_unlock_irqrestore(&port->lock, flags); +} + +static struct console arc_console = { + .name = ARC_SERIAL_DEV_NAME, + .write = arc_serial_console_write, + .device = uart_console_device, + .setup = arc_serial_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &arc_uart_driver +}; + +static __init void early_serial_write(struct console *con, const char *s, + unsigned int n) +{ + struct uart_port *port = &arc_uart_ports[con->index].port; + unsigned int i; + + for (i = 0; i < n; i++, s++) { + if (*s == '\n') + arc_serial_poll_putchar(port, '\r'); + arc_serial_poll_putchar(port, *s); + } +} + +static struct __initdata console arc_early_serial_console = { + .name = "early_ARCuart", + .write = early_serial_write, + .flags = CON_PRINTBUFFER | CON_BOOT, + .index = -1 +}; + +static int __devinit arc_serial_probe_earlyprintk(struct platform_device *pdev) +{ + arc_early_serial_console.index = pdev->id; + + arc_uart_init_one(pdev, &arc_uart_ports[pdev->id]); + + arc_serial_console_setup(&arc_early_serial_console, NULL); + + register_console(&arc_early_serial_console); + return 0; +} +#else +static int __devinit arc_serial_probe_earlyprintk(struct platform_device *pdev) +{ + return -ENODEV; +} +#endif /* CONFIG_SERIAL_ARC_CONSOLE */ + +static int __devinit arc_serial_probe(struct platform_device *pdev) +{ + struct arc_uart_port *uart; + int rc; + + if (is_early_platform_device(pdev)) + return arc_serial_probe_earlyprintk(pdev); + + uart = &arc_uart_ports[pdev->id]; + rc = arc_uart_init_one(pdev, uart); + if (rc) + return rc; + + return uart_add_one_port(&arc_uart_driver, &uart->port); +} + +static int __devexit arc_serial_remove(struct platform_device *pdev) +{ + /* This will never be called */ + return 0; +} + +static struct platform_driver arc_platform_driver = { + .probe = arc_serial_probe, + .remove = __devexit_p(arc_serial_remove), + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, +}; + +#ifdef CONFIG_SERIAL_ARC_CONSOLE +/* + * Register an early platform driver of "earlyprintk" class. + * ARCH platform code installs the driver and probes the early devices + * The installation could rely on user specifying earlyprintk=xyx in cmd line + * or it could be done independently, for all "earlyprintk" class drivers. + * [see arch/arc/plat-arcfpga/platform.c] + */ +early_platform_init("earlyprintk", &arc_platform_driver); + +#endif /* CONFIG_SERIAL_ARC_CONSOLE */ + +static int __init arc_serial_init(void) +{ + int ret; + + ret = uart_register_driver(&arc_uart_driver); + if (ret) + return ret; + + ret = platform_driver_register(&arc_platform_driver); + if (ret) + uart_unregister_driver(&arc_uart_driver); + + return ret; +} + +static void __exit arc_serial_exit(void) +{ + platform_driver_unregister(&arc_platform_driver); + uart_unregister_driver(&arc_uart_driver); +} + +module_init(arc_serial_init); +module_exit(arc_serial_exit); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("plat-arcfpga/uart"); +MODULE_AUTHOR("Vineet Gupta"); +MODULE_DESCRIPTION("ARC(Synopsys) On-Chip(fpga) serial driver"); diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 7e1ab20adc0..ebcc73f0418 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -215,5 +215,7 @@ /* Energy Micro efm32 SoC */ #define PORT_EFMUART 100 +/* ARC (Synopsys) on-chip UART */ +#define PORT_ARC 101 #endif /* _UAPILINUX_SERIAL_CORE_H */ -- cgit v1.2.3 From 85b97637bb40a9f486459dd254598759af9c3d50 Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Mon, 29 Oct 2012 11:01:50 +0800 Subject: x86/mce: Do not change worker's running cpu in cmci_rediscover(). cmci_rediscover() used set_cpus_allowed_ptr() to change the current process's running cpu, and migrate itself to the dest cpu. But worker processes are not allowed to be migrated. If current is a worker, the worker will be migrated to another cpu, but the corresponding worker_pool is still on the original cpu. In this case, the following BUG_ON in try_to_wake_up_local() will be triggered: BUG_ON(rq != this_rq()); This will cause the kernel panic. The call trace is like the following: [ 6155.451107] ------------[ cut here ]------------ [ 6155.452019] kernel BUG at kernel/sched/core.c:1654! ...... [ 6155.452019] RIP: 0010:[] [] try_to_wake_up_local+0x115/0x130 ...... [ 6155.452019] Call Trace: [ 6155.452019] [] __schedule+0x764/0x880 [ 6155.452019] [] schedule+0x29/0x70 [ 6155.452019] [] schedule_timeout+0x235/0x2d0 [ 6155.452019] [] ? mark_held_locks+0x8d/0x140 [ 6155.452019] [] ? __lock_release+0x133/0x1a0 [ 6155.452019] [] ? _raw_spin_unlock_irq+0x30/0x50 [ 6155.452019] [] ? trace_hardirqs_on_caller+0x105/0x190 [ 6155.452019] [] wait_for_common+0x12b/0x180 [ 6155.452019] [] ? try_to_wake_up+0x2f0/0x2f0 [ 6155.452019] [] wait_for_completion+0x1d/0x20 [ 6155.452019] [] stop_one_cpu+0x8a/0xc0 [ 6155.452019] [] ? __migrate_task+0x1a0/0x1a0 [ 6155.452019] [] ? complete+0x28/0x60 [ 6155.452019] [] set_cpus_allowed_ptr+0x128/0x130 [ 6155.452019] [] cmci_rediscover+0xf5/0x140 [ 6155.452019] [] mce_cpu_callback+0x18d/0x19d [ 6155.452019] [] notifier_call_chain+0x67/0x150 [ 6155.452019] [] __raw_notifier_call_chain+0xe/0x10 [ 6155.452019] [] __cpu_notify+0x20/0x40 [ 6155.452019] [] cpu_notify_nofail+0x15/0x30 [ 6155.452019] [] _cpu_down+0x262/0x2e0 [ 6155.452019] [] cpu_down+0x36/0x50 [ 6155.452019] [] acpi_processor_remove+0x50/0x11e [ 6155.452019] [] acpi_device_remove+0x90/0xb2 [ 6155.452019] [] __device_release_driver+0x7c/0xf0 [ 6155.452019] [] device_release_driver+0x2f/0x50 [ 6155.452019] [] acpi_bus_remove+0x32/0x6d [ 6155.452019] [] acpi_bus_trim+0x87/0xee [ 6155.452019] [] acpi_bus_hot_remove_device+0x88/0x16b [ 6155.452019] [] acpi_os_execute_deferred+0x27/0x34 [ 6155.452019] [] process_one_work+0x219/0x680 [ 6155.452019] [] ? process_one_work+0x1b8/0x680 [ 6155.452019] [] ? acpi_os_wait_events_complete+0x23/0x23 [ 6155.452019] [] worker_thread+0x12e/0x320 [ 6155.452019] [] ? manage_workers+0x110/0x110 [ 6155.452019] [] kthread+0xc6/0xd0 [ 6155.452019] [] kernel_thread_helper+0x4/0x10 [ 6155.452019] [] ? retint_restore_args+0x13/0x13 [ 6155.452019] [] ? __init_kthread_worker+0x70/0x70 [ 6155.452019] [] ? gs_change+0x13/0x13 This patch removes the set_cpus_allowed_ptr() call, and put the cmci rediscover jobs onto all the other cpus using system_wq. This could bring some delay for the jobs. Signed-off-by: Tang Chen Signed-off-by: Miao Xie Signed-off-by: Tony Luck --- arch/x86/kernel/cpu/mcheck/mce_intel.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index 5f88abf07e9..4f9a3cbfc4a 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c @@ -285,34 +285,39 @@ void cmci_clear(void) raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); } +static long cmci_rediscover_work_func(void *arg) +{ + int banks; + + /* Recheck banks in case CPUs don't all have the same */ + if (cmci_supported(&banks)) + cmci_discover(banks); + + return 0; +} + /* * After a CPU went down cycle through all the others and rediscover * Must run in process context. */ void cmci_rediscover(int dying) { - int banks; - int cpu; - cpumask_var_t old; + int cpu, banks; if (!cmci_supported(&banks)) return; - if (!alloc_cpumask_var(&old, GFP_KERNEL)) - return; - cpumask_copy(old, ¤t->cpus_allowed); for_each_online_cpu(cpu) { if (cpu == dying) continue; - if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) + + if (cpu == smp_processor_id()) { + cmci_rediscover_work_func(NULL); continue; - /* Recheck banks in case CPUs don't all have the same */ - if (cmci_supported(&banks)) - cmci_discover(banks); - } + } - set_cpus_allowed_ptr(current, old); - free_cpumask_var(old); + work_on_cpu(cpu, cmci_rediscover_work_func, NULL); + } } /* -- cgit v1.2.3 From c1c92b6a5b606e39e2181ac8eee2a0ca847542dc Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Tue, 30 Oct 2012 15:48:48 -0700 Subject: openvswitch: Print device when warning about over MTU packets. If an attempt is made to transmit a packet that is over the device's MTU then we log it using the datapath's name. However, it is much more helpful to use the device name instead. Signed-off-by: Jesse Gross --- net/openvswitch/vport-netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index 3c1e58ba714..a9033481fa5 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c @@ -158,7 +158,7 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb) if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n", - ovs_dp_name(vport->dp), + netdev_vport->dev->name, packet_length(skb), mtu); goto error; } -- cgit v1.2.3 From d04d382980c86bdee9960c3eb157a73f8ed230cc Mon Sep 17 00:00:00 2001 From: Mehak Mahajan Date: Tue, 30 Oct 2012 15:50:28 -0700 Subject: openvswitch: Store flow key len if ARP opcode is not request or reply. We currently only extract the ARP payload if the opcode indicates that it is a request or reply. However, we also only set the key length in these situations even though it should still be possible to match on the opcode. There's no real reason to restrict the ARP opcode since all have the same format so this simply removes the check. Signed-off-by: Mehak Mahajan Signed-off-by: Jesse Gross --- net/openvswitch/flow.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 98c70630ad0..733cbf49ed1 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c @@ -702,15 +702,11 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key, /* We only match on the lower 8 bits of the opcode. */ if (ntohs(arp->ar_op) <= 0xff) key->ip.proto = ntohs(arp->ar_op); - - if (key->ip.proto == ARPOP_REQUEST - || key->ip.proto == ARPOP_REPLY) { - memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src)); - memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst)); - memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN); - memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN); - key_len = SW_FLOW_KEY_OFFSET(ipv4.arp); - } + memcpy(&key->ipv4.addr.src, arp->ar_sip, sizeof(key->ipv4.addr.src)); + memcpy(&key->ipv4.addr.dst, arp->ar_tip, sizeof(key->ipv4.addr.dst)); + memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN); + memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN); + key_len = SW_FLOW_KEY_OFFSET(ipv4.arp); } } else if (key->eth.type == htons(ETH_P_IPV6)) { int nh_len; /* IPv6 Header + Extensions */ -- cgit v1.2.3 From b1d6d822550ee4e71ab9d55e65f8e096fb11e62b Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 29 Oct 2012 18:04:53 +0100 Subject: drivers/base: fix typo in comment for arch_setup_pdev_archdata() Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 8727e9c5eea..af1d47f0e99 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -44,7 +44,7 @@ EXPORT_SYMBOL_GPL(platform_bus); * be setup before the platform_notifier is called. So if a user needs to * manipulate any relevant information in the pdev_archdata they can do: * - * platform_devic_alloc() + * platform_device_alloc() * ... manipulate ... * platform_device_add() * -- cgit v1.2.3 From a369a7ebbfce5caa38e3d5645ea050f4590dea7a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 28 Oct 2012 01:05:41 -0700 Subject: drivers: base: Convert dev_printk(KERN_ to dev_( dev_ calls take less code than dev_printk(KERN_ and reducing object size is good. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/base/attribute_container.c | 2 +- drivers/base/devres.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index 8fc200b2e2c..d78b204e65c 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c @@ -158,7 +158,7 @@ attribute_container_add_device(struct device *dev, ic = kzalloc(sizeof(*ic), GFP_KERNEL); if (!ic) { - dev_printk(KERN_ERR, dev, "failed to allocate class container\n"); + dev_err(dev, "failed to allocate class container\n"); continue; } diff --git a/drivers/base/devres.c b/drivers/base/devres.c index 8731979d668..66839066476 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -50,8 +50,8 @@ static void devres_log(struct device *dev, struct devres_node *node, const char *op) { if (unlikely(log_devres)) - dev_printk(KERN_ERR, dev, "DEVRES %3s %p %s (%lu bytes)\n", - op, node, node->name, (unsigned long)node->size); + dev_err(dev, "DEVRES %3s %p %s (%lu bytes)\n", + op, node, node->name, (unsigned long)node->size); } #else /* CONFIG_DEBUG_DEVRES */ #define set_node_dbginfo(node, n, s) do {} while (0) -- cgit v1.2.3 From 7fac0c47ed1835b6eecf899df6980f0287f4c61c Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Tue, 30 Oct 2012 21:50:43 -0400 Subject: Staging: bcm: Remove typedef for stLocalSFAddIndicationAlt and call directly. This patch removes typedef for stLocalSFAddIndicationAlt, changes the name of the struct to bcm_add_indication_alt, and removes a comment. In addition, any calls to typedef stLocalSFAddIndicationAlt are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 4 ++-- drivers/staging/bcm/CmHost.c | 38 +++++++++++++++++++------------------- drivers/staging/bcm/CmHost.h | 6 ++---- drivers/staging/bcm/Misc.c | 2 +- 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 3d02c2ebfb8..4a7e12b6942 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -1060,10 +1060,10 @@ cntrlEnd: if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) return -EFAULT; - if (IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt)) { + if (IoBuffer.OutputLength < sizeof(struct bcm_add_indication_alt)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Mismatch req: %lx needed is =0x%zx!!!", - IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt)); + IoBuffer.OutputLength, sizeof(struct bcm_add_indication_alt)); return -EINVAL; } diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index df538386c77..482e59592cd 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -431,7 +431,7 @@ static VOID CopyToAdapter(register struct bcm_mini_adapter *Adapter, /* "); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Type: 0x%X", pstAddIndication->u8Type); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Direction: 0x%X", pstAddIndication->u8Direction); @@ -1333,13 +1333,13 @@ static ULONG StoreSFParam(struct bcm_mini_adapter *Adapter, PUCHAR pucSrcBuffer, ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBuffer, UINT *puBufferLength) { - stLocalSFAddIndicationAlt *pstAddIndicationAlt = NULL; + struct bcm_add_indication_alt *pstAddIndicationAlt = NULL; struct bcm_add_indication *pstAddIndication = NULL; struct bcm_del_request *pstDeletionRequest; UINT uiSearchRuleIndex; ULONG ulSFID; - pstAddIndicationAlt = (stLocalSFAddIndicationAlt *)(pvBuffer); + pstAddIndicationAlt = (struct bcm_add_indication_alt *)(pvBuffer); /* * In case of DSD Req By MS, we should immediately delete this SF so that @@ -1445,29 +1445,29 @@ ULONG StoreCmControlResponseMessage(struct bcm_mini_adapter *Adapter, PVOID pvBu return 1; } -static inline stLocalSFAddIndicationAlt +static inline struct bcm_add_indication_alt *RestoreCmControlResponseMessage(register struct bcm_mini_adapter *Adapter, register PVOID pvBuffer) { ULONG ulStatus = 0; struct bcm_add_indication *pstAddIndication = NULL; - stLocalSFAddIndicationAlt *pstAddIndicationDest = NULL; + struct bcm_add_indication_alt *pstAddIndicationDest = NULL; pstAddIndication = (struct bcm_add_indication *)(pvBuffer); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "=====>"); if ((pstAddIndication->u8Type == DSD_REQ) || (pstAddIndication->u8Type == DSD_RSP) || (pstAddIndication->u8Type == DSD_ACK)) - return (stLocalSFAddIndicationAlt *)pvBuffer; + return (struct bcm_add_indication_alt *)pvBuffer; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Inside RestoreCmControlResponseMessage "); /* * Need to Allocate memory to contain the SUPER Large structures * Our driver can't create these structures on Stack :( */ - pstAddIndicationDest = kmalloc(sizeof(stLocalSFAddIndicationAlt), GFP_KERNEL); + pstAddIndicationDest = kmalloc(sizeof(struct bcm_add_indication_alt), GFP_KERNEL); if (pstAddIndicationDest) { - memset(pstAddIndicationDest, 0, sizeof(stLocalSFAddIndicationAlt)); + memset(pstAddIndicationDest, 0, sizeof(struct bcm_add_indication_alt)); } else { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Failed to allocate memory for SF Add Indication Structure "); return NULL; @@ -1611,7 +1611,7 @@ int AllocAdapterDsxBuffer(struct bcm_mini_adapter *Adapter) * Need to Allocate memory to contain the SUPER Large structures * Our driver can't create these structures on Stack */ - Adapter->caDsxReqResp = kmalloc(sizeof(stLocalSFAddIndicationAlt)+LEADER_SIZE, GFP_KERNEL); + Adapter->caDsxReqResp = kmalloc(sizeof(struct bcm_add_indication_alt)+LEADER_SIZE, GFP_KERNEL); if (!Adapter->caDsxReqResp) return -ENOMEM; @@ -1634,7 +1634,7 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* u8Type) { case DSA_REQ: { - pLeader->PLength = sizeof(stLocalSFAddIndicationAlt); + pLeader->PLength = sizeof(struct bcm_add_indication_alt); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "Sending DSA Response....\n"); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA RESPONSE TO MAC %d", pLeader->PLength); - *((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) + *((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstAddIndication; - ((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP; + ((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_RSP; BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " VCID = %x", ntohs(pstAddIndication->u16VCID)); CopyBufferToControlPacket(Adapter, (PVOID)Adapter->caDsxReqResp); @@ -1675,12 +1675,12 @@ BOOLEAN CmControlResponseMessage(struct bcm_mini_adapter *Adapter, /* PLength = sizeof(stLocalSFAddIndicationAlt); + pLeader->PLength = sizeof(struct bcm_add_indication_alt); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "SENDING DSA ACK TO MAC %d", pLeader->PLength); - *((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) + *((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE])) = *pstAddIndication; - ((stLocalSFAddIndicationAlt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK; + ((struct bcm_add_indication_alt *)&(Adapter->caDsxReqResp[LEADER_SIZE]))->u8Type = DSA_ACK; } /* no break here..we should go down. */ case DSA_ACK: @@ -1902,7 +1902,7 @@ int get_dsx_sf_data_to_application(struct bcm_mini_adapter *Adapter, UINT uiSFId BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "status =%d", status); psSfInfo = &Adapter->PackInfo[status]; if (psSfInfo->pstSFIndication && copy_to_user(user_buffer, - psSfInfo->pstSFIndication, sizeof(stLocalSFAddIndicationAlt))) { + psSfInfo->pstSFIndication, sizeof(struct bcm_add_indication_alt))) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy to user failed SFID %d, present in queue !!!", uiSFId); status = -EFAULT; return status; diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index 8572defa83f..77f8fae16b6 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -36,8 +36,7 @@ typedef struct stLocalSFAddRequestAlt { /* USE_MEMORY_MANAGER(); */ } stLocalSFAddRequestAlt; -/* brief structure stLocalSFAddIndication */ -typedef struct stLocalSFAddIndicationAlt { +struct bcm_add_indication_alt { u8 u8Type; u8 u8Direction; u16 u16TID; @@ -51,8 +50,7 @@ typedef struct stLocalSFAddIndicationAlt { u8 u8CC; /* < Confirmation Code */ u8 u8Padd; /* < 8-bit Padding */ u16 u16Padd; /* < 16 bit Padding */ -/* USE_MEMORY_MANAGER(); */ -} stLocalSFAddIndicationAlt; +}; struct bcm_change_indication { u8 u8Type; diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index c3866d9f358..453a2fa28b1 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -346,7 +346,7 @@ int CopyBufferToControlPacket(struct bcm_mini_adapter *Adapter, void *ioBuffer) pktlen = pLeader->PLength; Status = StoreCmControlResponseMessage(Adapter, pucAddIndication, &pktlen); if (Status != 1) { - ClearTargetDSXBuffer(Adapter, ((stLocalSFAddIndicationAlt *)pucAddIndication)->u16TID, FALSE); + ClearTargetDSXBuffer(Adapter, ((struct bcm_add_indication_alt *)pucAddIndication)->u16TID, FALSE); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, " Error Restoring The DSX Control Packet. Dsx Buffers on Target may not be Setup Properly "); return STATUS_FAILURE; } -- cgit v1.2.3 From e446f5a8540a845ed92fca4109e67c8f0c76031f Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Tue, 30 Oct 2012 21:50:44 -0400 Subject: Staging: bcm: Remove typedef stLocalSFAddRequestAlt. This patch removes typedef stLocalSFAddRequestAlt in CmHost.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index 77f8fae16b6..eecad8d90ae 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -23,19 +23,6 @@ #define DSX_MESSAGE_EXCHANGE_BUFFER 0xBF60AC84 /* This contains the pointer */ #define DSX_MESSAGE_EXCHANGE_BUFFER_SIZE 72000 /* 24 K Bytes */ -/* brief structure stLocalSFAddRequest */ -typedef struct stLocalSFAddRequestAlt { - u8 u8Type; - u8 u8Direction; - u16 u16TID; - /* brief 16bitCID */ - u16 u16CID; - /* brief 16bitVCID */ - u16 u16VCID; - struct bcm_connect_mgr_params sfParameterSet; - /* USE_MEMORY_MANAGER(); */ -} stLocalSFAddRequestAlt; - struct bcm_add_indication_alt { u8 u8Type; u8 u8Direction; -- cgit v1.2.3 From 2b0c856ad9571013db8fc369194b7108dff3c18e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 22 Oct 2012 10:42:00 +0100 Subject: staging:iio: Consolidate adt7310 and adt7410 driver The adt7310 is the SPI version of the adt7410, so there is no need to have a separate driver for it. The register map layout is a bit different, i.e. the addresses of the register differ, but the individual register layouts are identical. We solve this by adding a small look-up table, which translates adt7410 register addresses to ad7310 register addresses. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/Kconfig | 13 +- drivers/staging/iio/adc/Makefile | 1 - drivers/staging/iio/adc/adt7310.c | 881 -------------------------------------- drivers/staging/iio/adc/adt7410.c | 458 +++++++++++++++----- 4 files changed, 364 insertions(+), 989 deletions(-) delete mode 100644 drivers/staging/iio/adc/adt7310.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index a525143ecbe..71a515d0a6d 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -126,18 +126,11 @@ config AD7192 To compile this driver as a module, choose M here: the module will be called ad7192. -config ADT7310 - tristate "Analog Devices ADT7310 temperature sensor driver" - depends on SPI - help - Say yes here to build support for Analog Devices ADT7310 - temperature sensors. - config ADT7410 - tristate "Analog Devices ADT7410 temperature sensor driver" - depends on I2C + tristate "Analog Devices ADT7310/ADT7410 temperature sensor driver" + depends on I2C || SPI_MASTER help - Say yes here to build support for Analog Devices ADT7410 + Say yes here to build support for Analog Devices ADT7310/ADT7410 temperature sensors. config AD7280 diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 62ee02e80cf..ff561c591d6 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -30,7 +30,6 @@ obj-$(CONFIG_AD7780) += ad7780.o obj-$(CONFIG_AD7793) += ad7793.o obj-$(CONFIG_AD7816) += ad7816.o obj-$(CONFIG_AD7192) += ad7192.o -obj-$(CONFIG_ADT7310) += adt7310.o obj-$(CONFIG_ADT7410) += adt7410.o obj-$(CONFIG_AD7280) += ad7280a.o obj-$(CONFIG_LPC32XX_ADC) += lpc32xx_adc.o diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c deleted file mode 100644 index 72460b6dc2f..00000000000 --- a/drivers/staging/iio/adc/adt7310.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * ADT7310 digital temperature sensor driver supporting ADT7310 - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -/* - * ADT7310 registers definition - */ - -#define ADT7310_STATUS 0 -#define ADT7310_CONFIG 1 -#define ADT7310_TEMPERATURE 2 -#define ADT7310_ID 3 -#define ADT7310_T_CRIT 4 -#define ADT7310_T_HYST 5 -#define ADT7310_T_ALARM_HIGH 6 -#define ADT7310_T_ALARM_LOW 7 - -/* - * ADT7310 status - */ -#define ADT7310_STAT_T_LOW 0x10 -#define ADT7310_STAT_T_HIGH 0x20 -#define ADT7310_STAT_T_CRIT 0x40 -#define ADT7310_STAT_NOT_RDY 0x80 - -/* - * ADT7310 config - */ -#define ADT7310_FAULT_QUEUE_MASK 0x3 -#define ADT7310_CT_POLARITY 0x4 -#define ADT7310_INT_POLARITY 0x8 -#define ADT7310_EVENT_MODE 0x10 -#define ADT7310_MODE_MASK 0x60 -#define ADT7310_ONESHOT 0x20 -#define ADT7310_SPS 0x40 -#define ADT7310_PD 0x60 -#define ADT7310_RESOLUTION 0x80 - -/* - * ADT7310 masks - */ -#define ADT7310_T16_VALUE_SIGN 0x8000 -#define ADT7310_T16_VALUE_FLOAT_OFFSET 7 -#define ADT7310_T16_VALUE_FLOAT_MASK 0x7F -#define ADT7310_T13_VALUE_SIGN 0x1000 -#define ADT7310_T13_VALUE_OFFSET 3 -#define ADT7310_T13_VALUE_FLOAT_OFFSET 4 -#define ADT7310_T13_VALUE_FLOAT_MASK 0xF -#define ADT7310_T_HYST_MASK 0xF -#define ADT7310_DEVICE_ID_MASK 0x7 -#define ADT7310_MANUFACTORY_ID_MASK 0xF8 -#define ADT7310_MANUFACTORY_ID_OFFSET 3 - - -#define ADT7310_CMD_REG_MASK 0x28 -#define ADT7310_CMD_REG_OFFSET 3 -#define ADT7310_CMD_READ 0x40 -#define ADT7310_CMD_CON_READ 0x4 - -#define ADT7310_IRQS 2 - -/* - * struct adt7310_chip_info - chip specifc information - */ - -struct adt7310_chip_info { - struct spi_device *spi_dev; - u8 config; -}; - -/* - * adt7310 register access by SPI - */ - -static int adt7310_spi_read_word(struct adt7310_chip_info *chip, u8 reg, u16 *data) -{ - struct spi_device *spi_dev = chip->spi_dev; - u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; - int ret = 0; - - command |= ADT7310_CMD_READ; - ret = spi_write(spi_dev, &command, sizeof(command)); - if (ret < 0) { - dev_err(&spi_dev->dev, "SPI write command error\n"); - return ret; - } - - ret = spi_read(spi_dev, (u8 *)data, sizeof(*data)); - if (ret < 0) { - dev_err(&spi_dev->dev, "SPI read word error\n"); - return ret; - } - - *data = be16_to_cpu(*data); - - return 0; -} - -static int adt7310_spi_write_word(struct adt7310_chip_info *chip, u8 reg, u16 data) -{ - struct spi_device *spi_dev = chip->spi_dev; - u8 buf[3]; - int ret = 0; - - buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; - buf[1] = (u8)(data >> 8); - buf[2] = (u8)(data & 0xFF); - - ret = spi_write(spi_dev, buf, 3); - if (ret < 0) { - dev_err(&spi_dev->dev, "SPI write word error\n"); - return ret; - } - - return ret; -} - -static int adt7310_spi_read_byte(struct adt7310_chip_info *chip, u8 reg, u8 *data) -{ - struct spi_device *spi_dev = chip->spi_dev; - u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; - int ret = 0; - - command |= ADT7310_CMD_READ; - ret = spi_write(spi_dev, &command, sizeof(command)); - if (ret < 0) { - dev_err(&spi_dev->dev, "SPI write command error\n"); - return ret; - } - - ret = spi_read(spi_dev, data, sizeof(*data)); - if (ret < 0) { - dev_err(&spi_dev->dev, "SPI read byte error\n"); - return ret; - } - - return 0; -} - -static int adt7310_spi_write_byte(struct adt7310_chip_info *chip, u8 reg, u8 data) -{ - struct spi_device *spi_dev = chip->spi_dev; - u8 buf[2]; - int ret = 0; - - buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; - buf[1] = data; - - ret = spi_write(spi_dev, buf, 2); - if (ret < 0) { - dev_err(&spi_dev->dev, "SPI write byte error\n"); - return ret; - } - - return ret; -} - -static ssize_t adt7310_show_mode(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - u8 config; - - config = chip->config & ADT7310_MODE_MASK; - - switch (config) { - case ADT7310_PD: - return sprintf(buf, "power-down\n"); - case ADT7310_ONESHOT: - return sprintf(buf, "one-shot\n"); - case ADT7310_SPS: - return sprintf(buf, "sps\n"); - default: - return sprintf(buf, "full\n"); - } -} - -static ssize_t adt7310_store_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - u16 config; - int ret; - - ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); - if (ret) - return -EIO; - - config = chip->config & (~ADT7310_MODE_MASK); - if (strcmp(buf, "power-down")) - config |= ADT7310_PD; - else if (strcmp(buf, "one-shot")) - config |= ADT7310_ONESHOT; - else if (strcmp(buf, "sps")) - config |= ADT7310_SPS; - - ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); - if (ret) - return -EIO; - - chip->config = config; - - return len; -} - -static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, - adt7310_show_mode, - adt7310_store_mode, - 0); - -static ssize_t adt7310_show_available_modes(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "full\none-shot\nsps\npower-down\n"); -} - -static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7310_show_available_modes, NULL, 0); - -static ssize_t adt7310_show_resolution(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - int ret; - int bits; - - ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); - if (ret) - return -EIO; - - if (chip->config & ADT7310_RESOLUTION) - bits = 16; - else - bits = 13; - - return sprintf(buf, "%d bits\n", bits); -} - -static ssize_t adt7310_store_resolution(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - unsigned long data; - u16 config; - int ret; - - ret = strict_strtoul(buf, 10, &data); - if (ret) - return -EINVAL; - - ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); - if (ret) - return -EIO; - - config = chip->config & (~ADT7310_RESOLUTION); - if (data) - config |= ADT7310_RESOLUTION; - - ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); - if (ret) - return -EIO; - - chip->config = config; - - return len; -} - -static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR, - adt7310_show_resolution, - adt7310_store_resolution, - 0); - -static ssize_t adt7310_show_id(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - u8 id; - int ret; - - ret = adt7310_spi_read_byte(chip, ADT7310_ID, &id); - if (ret) - return -EIO; - - return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n", - id & ADT7310_DEVICE_ID_MASK, - (id & ADT7310_MANUFACTORY_ID_MASK) >> ADT7310_MANUFACTORY_ID_OFFSET); -} - -static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR, - adt7310_show_id, - NULL, - 0); - -static ssize_t adt7310_convert_temperature(struct adt7310_chip_info *chip, - u16 data, char *buf) -{ - char sign = ' '; - - if (chip->config & ADT7310_RESOLUTION) { - if (data & ADT7310_T16_VALUE_SIGN) { - /* convert supplement to positive value */ - data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data); - sign = '-'; - } - return sprintf(buf, "%c%d.%.7d\n", sign, - (data >> ADT7310_T16_VALUE_FLOAT_OFFSET), - (data & ADT7310_T16_VALUE_FLOAT_MASK) * 78125); - } else { - if (data & ADT7310_T13_VALUE_SIGN) { - /* convert supplement to positive value */ - data >>= ADT7310_T13_VALUE_OFFSET; - data = (ADT7310_T13_VALUE_SIGN << 1) - data; - sign = '-'; - } - return sprintf(buf, "%c%d.%.4d\n", sign, - (data >> ADT7310_T13_VALUE_FLOAT_OFFSET), - (data & ADT7310_T13_VALUE_FLOAT_MASK) * 625); - } -} - -static ssize_t adt7310_show_value(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - u8 status; - u16 data; - int ret, i = 0; - - do { - ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status); - if (ret) - return -EIO; - i++; - if (i == 10000) - return -EIO; - } while (status & ADT7310_STAT_NOT_RDY); - - ret = adt7310_spi_read_word(chip, ADT7310_TEMPERATURE, &data); - if (ret) - return -EIO; - - return adt7310_convert_temperature(chip, data, buf); -} - -static IIO_DEVICE_ATTR(value, S_IRUGO, adt7310_show_value, NULL, 0); - -static struct attribute *adt7310_attributes[] = { - &iio_dev_attr_available_modes.dev_attr.attr, - &iio_dev_attr_mode.dev_attr.attr, - &iio_dev_attr_resolution.dev_attr.attr, - &iio_dev_attr_id.dev_attr.attr, - &iio_dev_attr_value.dev_attr.attr, - NULL, -}; - -static const struct attribute_group adt7310_attribute_group = { - .attrs = adt7310_attributes, -}; - -static irqreturn_t adt7310_event_handler(int irq, void *private) -{ - struct iio_dev *indio_dev = private; - struct adt7310_chip_info *chip = iio_priv(indio_dev); - s64 timestamp = iio_get_time_ns(); - u8 status; - int ret; - - ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status); - if (ret) - goto done; - - if (status & ADT7310_STAT_T_HIGH) - iio_push_event(indio_dev, - IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_RISING), - timestamp); - if (status & ADT7310_STAT_T_LOW) - iio_push_event(indio_dev, - IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_FALLING), - timestamp); - if (status & ADT7310_STAT_T_CRIT) - iio_push_event(indio_dev, - IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_RISING), - timestamp); - -done: - return IRQ_HANDLED; -} - -static ssize_t adt7310_show_event_mode(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - int ret; - - ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); - if (ret) - return -EIO; - - if (chip->config & ADT7310_EVENT_MODE) - return sprintf(buf, "interrupt\n"); - else - return sprintf(buf, "comparator\n"); -} - -static ssize_t adt7310_set_event_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - u16 config; - int ret; - - ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); - if (ret) - return -EIO; - - config = chip->config &= ~ADT7310_EVENT_MODE; - if (strcmp(buf, "comparator") != 0) - config |= ADT7310_EVENT_MODE; - - ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); - if (ret) - return -EIO; - - chip->config = config; - - return len; -} - -static ssize_t adt7310_show_available_event_modes(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return sprintf(buf, "comparator\ninterrupt\n"); -} - -static ssize_t adt7310_show_fault_queue(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - int ret; - - ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); - if (ret) - return -EIO; - - return sprintf(buf, "%d\n", chip->config & ADT7310_FAULT_QUEUE_MASK); -} - -static ssize_t adt7310_set_fault_queue(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - unsigned long data; - int ret; - u8 config; - - ret = strict_strtoul(buf, 10, &data); - if (ret || data > 3) - return -EINVAL; - - ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); - if (ret) - return -EIO; - - config = chip->config & ~ADT7310_FAULT_QUEUE_MASK; - config |= data; - ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); - if (ret) - return -EIO; - - chip->config = config; - - return len; -} - -static inline ssize_t adt7310_show_t_bound(struct device *dev, - struct device_attribute *attr, - u8 bound_reg, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - u16 data; - int ret; - - ret = adt7310_spi_read_word(chip, bound_reg, &data); - if (ret) - return -EIO; - - return adt7310_convert_temperature(chip, data, buf); -} - -static inline ssize_t adt7310_set_t_bound(struct device *dev, - struct device_attribute *attr, - u8 bound_reg, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - long tmp1, tmp2; - u16 data; - char *pos; - int ret; - - pos = strchr(buf, '.'); - - ret = strict_strtol(buf, 10, &tmp1); - - if (ret || tmp1 > 127 || tmp1 < -128) - return -EINVAL; - - if (pos) { - len = strlen(pos); - - if (chip->config & ADT7310_RESOLUTION) { - if (len > ADT7310_T16_VALUE_FLOAT_OFFSET) - len = ADT7310_T16_VALUE_FLOAT_OFFSET; - pos[len] = 0; - ret = strict_strtol(pos, 10, &tmp2); - - if (!ret) - tmp2 = (tmp2 / 78125) * 78125; - } else { - if (len > ADT7310_T13_VALUE_FLOAT_OFFSET) - len = ADT7310_T13_VALUE_FLOAT_OFFSET; - pos[len] = 0; - ret = strict_strtol(pos, 10, &tmp2); - - if (!ret) - tmp2 = (tmp2 / 625) * 625; - } - } - - if (tmp1 < 0) - data = (u16)(-tmp1); - else - data = (u16)tmp1; - - if (chip->config & ADT7310_RESOLUTION) { - data = (data << ADT7310_T16_VALUE_FLOAT_OFFSET) | - (tmp2 & ADT7310_T16_VALUE_FLOAT_MASK); - - if (tmp1 < 0) - /* convert positive value to supplyment */ - data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data); - } else { - data = (data << ADT7310_T13_VALUE_FLOAT_OFFSET) | - (tmp2 & ADT7310_T13_VALUE_FLOAT_MASK); - - if (tmp1 < 0) - /* convert positive value to supplyment */ - data = (ADT7310_T13_VALUE_SIGN << 1) - data; - data <<= ADT7310_T13_VALUE_OFFSET; - } - - ret = adt7310_spi_write_word(chip, bound_reg, data); - if (ret) - return -EIO; - - return len; -} - -static ssize_t adt7310_show_t_alarm_high(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return adt7310_show_t_bound(dev, attr, - ADT7310_T_ALARM_HIGH, buf); -} - -static inline ssize_t adt7310_set_t_alarm_high(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - return adt7310_set_t_bound(dev, attr, - ADT7310_T_ALARM_HIGH, buf, len); -} - -static ssize_t adt7310_show_t_alarm_low(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return adt7310_show_t_bound(dev, attr, - ADT7310_T_ALARM_LOW, buf); -} - -static inline ssize_t adt7310_set_t_alarm_low(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - return adt7310_set_t_bound(dev, attr, - ADT7310_T_ALARM_LOW, buf, len); -} - -static ssize_t adt7310_show_t_crit(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return adt7310_show_t_bound(dev, attr, - ADT7310_T_CRIT, buf); -} - -static inline ssize_t adt7310_set_t_crit(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - return adt7310_set_t_bound(dev, attr, - ADT7310_T_CRIT, buf, len); -} - -static ssize_t adt7310_show_t_hyst(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - int ret; - u8 t_hyst; - - ret = adt7310_spi_read_byte(chip, ADT7310_T_HYST, &t_hyst); - if (ret) - return -EIO; - - return sprintf(buf, "%d\n", t_hyst & ADT7310_T_HYST_MASK); -} - -static inline ssize_t adt7310_set_t_hyst(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *dev_info = dev_to_iio_dev(dev); - struct adt7310_chip_info *chip = iio_priv(dev_info); - int ret; - unsigned long data; - u8 t_hyst; - - ret = strict_strtol(buf, 10, &data); - - if (ret || data > ADT7310_T_HYST_MASK) - return -EINVAL; - - t_hyst = (u8)data; - - ret = adt7310_spi_write_byte(chip, ADT7310_T_HYST, t_hyst); - if (ret) - return -EIO; - - return len; -} - -static IIO_DEVICE_ATTR(event_mode, - S_IRUGO | S_IWUSR, - adt7310_show_event_mode, adt7310_set_event_mode, 0); -static IIO_DEVICE_ATTR(available_event_modes, - S_IRUGO | S_IWUSR, - adt7310_show_available_event_modes, NULL, 0); -static IIO_DEVICE_ATTR(fault_queue, - S_IRUGO | S_IWUSR, - adt7310_show_fault_queue, adt7310_set_fault_queue, 0); -static IIO_DEVICE_ATTR(t_alarm_high, - S_IRUGO | S_IWUSR, - adt7310_show_t_alarm_high, adt7310_set_t_alarm_high, 0); -static IIO_DEVICE_ATTR(t_alarm_low, - S_IRUGO | S_IWUSR, - adt7310_show_t_alarm_low, adt7310_set_t_alarm_low, 0); -static IIO_DEVICE_ATTR(t_crit, - S_IRUGO | S_IWUSR, - adt7310_show_t_crit, adt7310_set_t_crit, 0); -static IIO_DEVICE_ATTR(t_hyst, - S_IRUGO | S_IWUSR, - adt7310_show_t_hyst, adt7310_set_t_hyst, 0); - -static struct attribute *adt7310_event_int_attributes[] = { - &iio_dev_attr_event_mode.dev_attr.attr, - &iio_dev_attr_available_event_modes.dev_attr.attr, - &iio_dev_attr_fault_queue.dev_attr.attr, - &iio_dev_attr_t_alarm_high.dev_attr.attr, - &iio_dev_attr_t_alarm_low.dev_attr.attr, - &iio_dev_attr_t_crit.dev_attr.attr, - &iio_dev_attr_t_hyst.dev_attr.attr, - NULL, -}; - -static struct attribute_group adt7310_event_attribute_group = { - .attrs = adt7310_event_int_attributes, - .name = "events", -}; - -static const struct iio_info adt7310_info = { - .attrs = &adt7310_attribute_group, - .event_attrs = &adt7310_event_attribute_group, - .driver_module = THIS_MODULE, -}; - -/* - * device probe and remove - */ - -static int __devinit adt7310_probe(struct spi_device *spi_dev) -{ - struct adt7310_chip_info *chip; - struct iio_dev *indio_dev; - int ret = 0; - unsigned long *adt7310_platform_data = spi_dev->dev.platform_data; - unsigned long irq_flags; - - indio_dev = iio_device_alloc(sizeof(*chip)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_ret; - } - chip = iio_priv(indio_dev); - /* this is only used for device removal purposes */ - dev_set_drvdata(&spi_dev->dev, indio_dev); - - chip->spi_dev = spi_dev; - - indio_dev->dev.parent = &spi_dev->dev; - indio_dev->name = spi_get_device_id(spi_dev)->name; - indio_dev->info = &adt7310_info; - indio_dev->modes = INDIO_DIRECT_MODE; - - /* CT critcal temperature event. line 0 */ - if (spi_dev->irq) { - if (adt7310_platform_data[2]) - irq_flags = adt7310_platform_data[2]; - else - irq_flags = IRQF_TRIGGER_LOW; - ret = request_threaded_irq(spi_dev->irq, - NULL, - &adt7310_event_handler, - irq_flags | IRQF_ONESHOT, - indio_dev->name, - indio_dev); - if (ret) - goto error_free_dev; - } - - /* INT bound temperature alarm event. line 1 */ - if (adt7310_platform_data[0]) { - ret = request_threaded_irq(adt7310_platform_data[0], - NULL, - &adt7310_event_handler, - adt7310_platform_data[1] | - IRQF_ONESHOT, - indio_dev->name, - indio_dev); - if (ret) - goto error_unreg_ct_irq; - } - - if (spi_dev->irq && adt7310_platform_data[0]) { - ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); - if (ret) { - ret = -EIO; - goto error_unreg_int_irq; - } - - /* set irq polarity low level */ - chip->config &= ~ADT7310_CT_POLARITY; - - if (adt7310_platform_data[1] & IRQF_TRIGGER_HIGH) - chip->config |= ADT7310_INT_POLARITY; - else - chip->config &= ~ADT7310_INT_POLARITY; - - ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, chip->config); - if (ret) { - ret = -EIO; - goto error_unreg_int_irq; - } - } - - ret = iio_device_register(indio_dev); - if (ret) - goto error_unreg_int_irq; - - dev_info(&spi_dev->dev, "%s temperature sensor registered.\n", - indio_dev->name); - - return 0; - -error_unreg_int_irq: - free_irq(adt7310_platform_data[0], indio_dev); -error_unreg_ct_irq: - free_irq(spi_dev->irq, indio_dev); -error_free_dev: - iio_device_free(indio_dev); -error_ret: - return ret; -} - -static int __devexit adt7310_remove(struct spi_device *spi_dev) -{ - struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev); - unsigned long *adt7310_platform_data = spi_dev->dev.platform_data; - - iio_device_unregister(indio_dev); - dev_set_drvdata(&spi_dev->dev, NULL); - if (adt7310_platform_data[0]) - free_irq(adt7310_platform_data[0], indio_dev); - if (spi_dev->irq) - free_irq(spi_dev->irq, indio_dev); - iio_device_free(indio_dev); - - return 0; -} - -static const struct spi_device_id adt7310_id[] = { - { "adt7310", 0 }, - {} -}; - -MODULE_DEVICE_TABLE(spi, adt7310_id); - -static struct spi_driver adt7310_driver = { - .driver = { - .name = "adt7310", - .owner = THIS_MODULE, - }, - .probe = adt7310_probe, - .remove = __devexit_p(adt7310_remove), - .id_table = adt7310_id, -}; -module_spi_driver(adt7310_driver); - -MODULE_AUTHOR("Sonic Zhang "); -MODULE_DESCRIPTION("Analog Devices ADT7310 digital" - " temperature sensor driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c index 4157596ea3b..5e93d868b3f 100644 --- a/drivers/staging/iio/adc/adt7410.c +++ b/drivers/staging/iio/adc/adt7410.c @@ -1,5 +1,5 @@ /* - * ADT7410 digital temperature sensor driver supporting ADT7410 + * ADT7410 digital temperature sensor driver supporting ADT7310/ADT7410 * * Copyright 2010 Analog Devices Inc. * @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,19 @@ #define ADT7410_ID 0xB #define ADT7410_RESET 0x2F +/* + * ADT7310 registers definition + */ + +#define ADT7310_STATUS 0 +#define ADT7310_CONFIG 1 +#define ADT7310_TEMPERATURE 2 +#define ADT7310_ID 3 +#define ADT7310_T_CRIT 4 +#define ADT7310_T_HYST 5 +#define ADT7310_T_ALARM_HIGH 6 +#define ADT7310_T_ALARM_LOW 7 + /* * ADT7410 status */ @@ -69,75 +83,52 @@ #define ADT7410_MANUFACTORY_ID_MASK 0xF0 #define ADT7410_MANUFACTORY_ID_OFFSET 4 + +#define ADT7310_CMD_REG_MASK 0x28 +#define ADT7310_CMD_REG_OFFSET 3 +#define ADT7310_CMD_READ 0x40 +#define ADT7310_CMD_CON_READ 0x4 + #define ADT7410_IRQS 2 /* * struct adt7410_chip_info - chip specifc information */ +struct adt7410_chip_info; + +struct adt7410_ops { + int (*read_word)(struct adt7410_chip_info *, u8 reg, u16 *data); + int (*write_word)(struct adt7410_chip_info *, u8 reg, u16 data); + int (*read_byte)(struct adt7410_chip_info *, u8 reg, u8 *data); + int (*write_byte)(struct adt7410_chip_info *, u8 reg, u8 data); +}; + struct adt7410_chip_info { - struct i2c_client *client; + struct device *dev; u8 config; -}; -/* - * adt7410 register access by I2C - */ + const struct adt7410_ops *ops; +}; -static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data) +static int adt7410_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data) { - struct i2c_client *client = chip->client; - int ret = 0; - - ret = i2c_smbus_read_word_data(client, reg); - if (ret < 0) { - dev_err(&client->dev, "I2C read error\n"); - return ret; - } - - *data = swab16((u16)ret); - - return 0; + return chip->ops->read_word(chip, reg, data); } -static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data) +static int adt7410_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data) { - struct i2c_client *client = chip->client; - int ret = 0; - - ret = i2c_smbus_write_word_data(client, reg, swab16(data)); - if (ret < 0) - dev_err(&client->dev, "I2C write error\n"); - - return ret; + return chip->ops->write_word(chip, reg, data); } -static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data) +static int adt7410_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data) { - struct i2c_client *client = chip->client; - int ret = 0; - - ret = i2c_smbus_read_byte_data(client, reg); - if (ret < 0) { - dev_err(&client->dev, "I2C read error\n"); - return ret; - } - - *data = (u8)ret; - - return 0; + return chip->ops->read_byte(chip, reg, data); } -static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data) +static int adt7410_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data) { - struct i2c_client *client = chip->client; - int ret = 0; - - ret = i2c_smbus_write_byte_data(client, reg, data); - if (ret < 0) - dev_err(&client->dev, "I2C write error\n"); - - return ret; + return chip->ops->write_byte(chip, reg, data); } static ssize_t adt7410_show_mode(struct device *dev, @@ -172,7 +163,7 @@ static ssize_t adt7410_store_mode(struct device *dev, u16 config; int ret; - ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); if (ret) return -EIO; @@ -184,7 +175,7 @@ static ssize_t adt7410_store_mode(struct device *dev, else if (strcmp(buf, "sps")) config |= ADT7410_SPS; - ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config); + ret = adt7410_write_byte(chip, ADT7410_CONFIG, config); if (ret) return -EIO; @@ -216,7 +207,7 @@ static ssize_t adt7410_show_resolution(struct device *dev, int ret; int bits; - ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); if (ret) return -EIO; @@ -243,7 +234,7 @@ static ssize_t adt7410_store_resolution(struct device *dev, if (ret) return -EINVAL; - ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); if (ret) return -EIO; @@ -251,7 +242,7 @@ static ssize_t adt7410_store_resolution(struct device *dev, if (data) config |= ADT7410_RESOLUTION; - ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config); + ret = adt7410_write_byte(chip, ADT7410_CONFIG, config); if (ret) return -EIO; @@ -274,7 +265,7 @@ static ssize_t adt7410_show_id(struct device *dev, u8 id; int ret; - ret = adt7410_i2c_read_byte(chip, ADT7410_ID, &id); + ret = adt7410_read_byte(chip, ADT7410_ID, &id); if (ret) return -EIO; @@ -317,7 +308,7 @@ static ssize_t adt7410_show_value(struct device *dev, int ret, i = 0; do { - ret = adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status); + ret = adt7410_read_byte(chip, ADT7410_STATUS, &status); if (ret) return -EIO; i++; @@ -325,7 +316,7 @@ static ssize_t adt7410_show_value(struct device *dev, return -EIO; } while (status & ADT7410_STAT_NOT_RDY); - ret = adt7410_i2c_read_word(chip, ADT7410_TEMPERATURE, &data); + ret = adt7410_read_word(chip, ADT7410_TEMPERATURE, &data); if (ret) return -EIO; @@ -354,7 +345,7 @@ static irqreturn_t adt7410_event_handler(int irq, void *private) s64 timestamp = iio_get_time_ns(); u8 status; - if (adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status)) + if (adt7410_read_byte(chip, ADT7410_STATUS, &status)) return IRQ_HANDLED; if (status & ADT7410_STAT_T_HIGH) @@ -387,7 +378,7 @@ static ssize_t adt7410_show_event_mode(struct device *dev, struct adt7410_chip_info *chip = iio_priv(dev_info); int ret; - ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); if (ret) return -EIO; @@ -407,7 +398,7 @@ static ssize_t adt7410_set_event_mode(struct device *dev, u16 config; int ret; - ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); if (ret) return -EIO; @@ -415,7 +406,7 @@ static ssize_t adt7410_set_event_mode(struct device *dev, if (strcmp(buf, "comparator") != 0) config |= ADT7410_EVENT_MODE; - ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config); + ret = adt7410_write_byte(chip, ADT7410_CONFIG, config); if (ret) return -EIO; @@ -439,7 +430,7 @@ static ssize_t adt7410_show_fault_queue(struct device *dev, struct adt7410_chip_info *chip = iio_priv(dev_info); int ret; - ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); if (ret) return -EIO; @@ -461,13 +452,13 @@ static ssize_t adt7410_set_fault_queue(struct device *dev, if (ret || data > 3) return -EINVAL; - ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); if (ret) return -EIO; config = chip->config & ~ADT7410_FAULT_QUEUE_MASK; config |= data; - ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config); + ret = adt7410_write_byte(chip, ADT7410_CONFIG, config); if (ret) return -EIO; @@ -486,7 +477,7 @@ static inline ssize_t adt7410_show_t_bound(struct device *dev, u16 data; int ret; - ret = adt7410_i2c_read_word(chip, bound_reg, &data); + ret = adt7410_read_word(chip, bound_reg, &data); if (ret) return -EIO; @@ -557,7 +548,7 @@ static inline ssize_t adt7410_set_t_bound(struct device *dev, data <<= ADT7410_T13_VALUE_OFFSET; } - ret = adt7410_i2c_write_word(chip, bound_reg, data); + ret = adt7410_write_word(chip, bound_reg, data); if (ret) return -EIO; @@ -624,7 +615,7 @@ static ssize_t adt7410_show_t_hyst(struct device *dev, int ret; u8 t_hyst; - ret = adt7410_i2c_read_byte(chip, ADT7410_T_HYST, &t_hyst); + ret = adt7410_read_byte(chip, ADT7410_T_HYST, &t_hyst); if (ret) return -EIO; @@ -649,7 +640,7 @@ static inline ssize_t adt7410_set_t_hyst(struct device *dev, t_hyst = (u8)data; - ret = adt7410_i2c_write_byte(chip, ADT7410_T_HYST, t_hyst); + ret = adt7410_write_byte(chip, ADT7410_T_HYST, t_hyst); if (ret) return -EIO; @@ -704,14 +695,14 @@ static const struct iio_info adt7410_info = { * device probe and remove */ -static int __devinit adt7410_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int __devinit adt7410_probe(struct device *dev, int irq, + const char *name, const struct adt7410_ops *ops) { + unsigned long *adt7410_platform_data = dev->platform_data; + unsigned long local_pdata[] = {0, 0}; struct adt7410_chip_info *chip; struct iio_dev *indio_dev; int ret = 0; - unsigned long *adt7410_platform_data = client->dev.platform_data; - unsigned long local_pdata[] = {0, 0}; indio_dev = iio_device_alloc(sizeof(*chip)); if (indio_dev == NULL) { @@ -720,12 +711,13 @@ static int __devinit adt7410_probe(struct i2c_client *client, } chip = iio_priv(indio_dev); /* this is only used for device removal purposes */ - i2c_set_clientdata(client, indio_dev); + dev_set_drvdata(dev, indio_dev); - chip->client = client; + chip->dev = dev; + chip->ops = ops; - indio_dev->name = id->name; - indio_dev->dev.parent = &client->dev; + indio_dev->name = name; + indio_dev->dev.parent = dev; indio_dev->info = &adt7410_info; indio_dev->modes = INDIO_DIRECT_MODE; @@ -733,12 +725,12 @@ static int __devinit adt7410_probe(struct i2c_client *client, adt7410_platform_data = local_pdata; /* CT critcal temperature event. line 0 */ - if (client->irq) { - ret = request_threaded_irq(client->irq, + if (irq) { + ret = request_threaded_irq(irq, NULL, &adt7410_event_handler, IRQF_TRIGGER_LOW | IRQF_ONESHOT, - id->name, + name, indio_dev); if (ret) goto error_free_dev; @@ -751,13 +743,13 @@ static int __devinit adt7410_probe(struct i2c_client *client, &adt7410_event_handler, adt7410_platform_data[1] | IRQF_ONESHOT, - id->name, + name, indio_dev); if (ret) goto error_unreg_ct_irq; } - ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + ret = adt7410_read_byte(chip, ADT7410_CONFIG, &chip->config); if (ret) { ret = -EIO; goto error_unreg_int_irq; @@ -765,7 +757,7 @@ static int __devinit adt7410_probe(struct i2c_client *client, chip->config |= ADT7410_RESOLUTION; - if (client->irq && adt7410_platform_data[0]) { + if (irq && adt7410_platform_data[0]) { /* set irq polarity low level */ chip->config &= ~ADT7410_CT_POLARITY; @@ -776,7 +768,7 @@ static int __devinit adt7410_probe(struct i2c_client *client, chip->config &= ~ADT7410_INT_POLARITY; } - ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, chip->config); + ret = adt7410_write_byte(chip, ADT7410_CONFIG, chip->config); if (ret) { ret = -EIO; goto error_unreg_int_irq; @@ -785,36 +777,117 @@ static int __devinit adt7410_probe(struct i2c_client *client, if (ret) goto error_unreg_int_irq; - dev_info(&client->dev, "%s temperature sensor registered.\n", - id->name); + dev_info(dev, "%s temperature sensor registered.\n", + name); return 0; error_unreg_int_irq: free_irq(adt7410_platform_data[0], indio_dev); error_unreg_ct_irq: - free_irq(client->irq, indio_dev); + free_irq(irq, indio_dev); error_free_dev: iio_device_free(indio_dev); error_ret: return ret; } -static int __devexit adt7410_remove(struct i2c_client *client) +static int __devexit adt7410_remove(struct device *dev, int irq) { - struct iio_dev *indio_dev = i2c_get_clientdata(client); - unsigned long *adt7410_platform_data = client->dev.platform_data; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + unsigned long *adt7410_platform_data = dev->platform_data; iio_device_unregister(indio_dev); if (adt7410_platform_data[0]) free_irq(adt7410_platform_data[0], indio_dev); - if (client->irq) - free_irq(client->irq, indio_dev); + if (irq) + free_irq(irq, indio_dev); iio_device_free(indio_dev); return 0; } +#if IS_ENABLED(CONFIG_I2C) + +static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg, + u16 *data) +{ + struct i2c_client *client = to_i2c_client(chip->dev); + int ret = 0; + + ret = i2c_smbus_read_word_data(client, reg); + if (ret < 0) { + dev_err(&client->dev, "I2C read error\n"); + return ret; + } + + *data = swab16((u16)ret); + + return 0; +} + +static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg, + u16 data) +{ + struct i2c_client *client = to_i2c_client(chip->dev); + int ret = 0; + + ret = i2c_smbus_write_word_data(client, reg, swab16(data)); + if (ret < 0) + dev_err(&client->dev, "I2C write error\n"); + + return ret; +} + +static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg, + u8 *data) +{ + struct i2c_client *client = to_i2c_client(chip->dev); + int ret = 0; + + ret = i2c_smbus_read_byte_data(client, reg); + if (ret < 0) { + dev_err(&client->dev, "I2C read error\n"); + return ret; + } + + *data = (u8)ret; + + return 0; +} + +static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg, + u8 data) +{ + struct i2c_client *client = to_i2c_client(chip->dev); + int ret = 0; + + ret = i2c_smbus_write_byte_data(client, reg, data); + if (ret < 0) + dev_err(&client->dev, "I2C write error\n"); + + return ret; +} + +static const struct adt7410_ops adt7410_i2c_ops = { + .read_word = adt7410_i2c_read_word, + .write_word = adt7410_i2c_write_word, + .read_byte = adt7410_i2c_read_byte, + .write_byte = adt7410_i2c_write_byte, +}; + +static int __devinit adt7410_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + return adt7410_probe(&client->dev, client->irq, id->name, + &adt7410_i2c_ops); +} + +static int __devexit adt7410_i2c_remove(struct i2c_client *client) +{ + return adt7410_remove(&client->dev, client->irq); +} + static const struct i2c_device_id adt7410_id[] = { { "adt7410", 0 }, {} @@ -826,13 +899,204 @@ static struct i2c_driver adt7410_driver = { .driver = { .name = "adt7410", }, - .probe = adt7410_probe, - .remove = __devexit_p(adt7410_remove), + .probe = adt7410_i2c_probe, + .remove = __devexit_p(adt7410_i2c_remove), .id_table = adt7410_id, }; -module_i2c_driver(adt7410_driver); + +static int __init adt7410_i2c_init(void) +{ + return i2c_add_driver(&adt7410_driver); +} + +static void __exit adt7410_i2c_exit(void) +{ + i2c_del_driver(&adt7410_driver); +} + +#else + +static int __init adt7410_i2c_init(void) { return 0; }; +static void __exit adt7410_i2c_exit(void) {}; + +#endif + +#if IS_ENABLED(CONFIG_SPI_MASTER) + +static const u8 adt7371_reg_table[] = { + [ADT7410_TEMPERATURE] = ADT7310_TEMPERATURE, + [ADT7410_STATUS] = ADT7310_STATUS, + [ADT7410_CONFIG] = ADT7310_CONFIG, + [ADT7410_T_ALARM_HIGH] = ADT7310_T_ALARM_HIGH, + [ADT7410_T_ALARM_LOW] = ADT7310_T_ALARM_LOW, + [ADT7410_T_CRIT] = ADT7310_T_CRIT, + [ADT7410_T_HYST] = ADT7310_T_HYST, + [ADT7410_ID] = ADT7310_ID, +}; + +#define AD7310_COMMAND(reg) (adt7371_reg_table[(reg)] << ADT7310_CMD_REG_OFFSET) + +static int adt7310_spi_read_word(struct adt7410_chip_info *chip, + u8 reg, u16 *data) +{ + struct spi_device *spi = to_spi_device(chip->dev); + u8 command = AD7310_COMMAND(reg); + int ret = 0; + + command |= ADT7310_CMD_READ; + ret = spi_write(spi, &command, sizeof(command)); + if (ret < 0) { + dev_err(&spi->dev, "SPI write command error\n"); + return ret; + } + + ret = spi_read(spi, (u8 *)data, sizeof(*data)); + if (ret < 0) { + dev_err(&spi->dev, "SPI read word error\n"); + return ret; + } + + *data = be16_to_cpu(*data); + + return 0; +} + +static int adt7310_spi_write_word(struct adt7410_chip_info *chip, u8 reg, + u16 data) +{ + struct spi_device *spi = to_spi_device(chip->dev); + u8 buf[3]; + int ret = 0; + + buf[0] = AD7310_COMMAND(reg); + buf[1] = (u8)(data >> 8); + buf[2] = (u8)(data & 0xFF); + + ret = spi_write(spi, buf, 3); + if (ret < 0) { + dev_err(&spi->dev, "SPI write word error\n"); + return ret; + } + + return ret; +} + +static int adt7310_spi_read_byte(struct adt7410_chip_info *chip, u8 reg, + u8 *data) +{ + struct spi_device *spi = to_spi_device(chip->dev); + u8 command = AD7310_COMMAND(reg); + int ret = 0; + + command |= ADT7310_CMD_READ; + ret = spi_write(spi, &command, sizeof(command)); + if (ret < 0) { + dev_err(&spi->dev, "SPI write command error\n"); + return ret; + } + + ret = spi_read(spi, data, sizeof(*data)); + if (ret < 0) { + dev_err(&spi->dev, "SPI read byte error\n"); + return ret; + } + + return 0; +} + +static int adt7310_spi_write_byte(struct adt7410_chip_info *chip, u8 reg, + u8 data) +{ + struct spi_device *spi = to_spi_device(chip->dev); + u8 buf[2]; + int ret = 0; + + buf[0] = AD7310_COMMAND(reg); + buf[1] = data; + + ret = spi_write(spi, buf, 2); + if (ret < 0) { + dev_err(&spi->dev, "SPI write byte error\n"); + return ret; + } + + return ret; +} + +static const struct adt7410_ops adt7310_spi_ops = { + .read_word = adt7310_spi_read_word, + .write_word = adt7310_spi_write_word, + .read_byte = adt7310_spi_read_byte, + .write_byte = adt7310_spi_write_byte, +}; + +static int __devinit adt7310_spi_probe(struct spi_device *spi) +{ + return adt7410_probe(&spi->dev, spi->irq, + spi_get_device_id(spi)->name, &adt7310_spi_ops); +} + +static int __devexit adt7310_spi_remove(struct spi_device *spi) +{ + return adt7410_remove(&spi->dev, spi->irq); +} + +static const struct spi_device_id adt7310_id[] = { + { "adt7310", 0 }, + {} +}; +MODULE_DEVICE_TABLE(spi, adt7310_id); + +static struct spi_driver adt7310_driver = { + .driver = { + .name = "adt7310", + .owner = THIS_MODULE, + }, + .probe = adt7310_spi_probe, + .remove = __devexit_p(adt7310_spi_remove), + .id_table = adt7310_id, +}; + +static int __init adt7310_spi_init(void) +{ + return spi_register_driver(&adt7310_driver); +} + +static void adt7310_spi_exit(void) +{ + spi_unregister_driver(&adt7310_driver); +} + +#else + +static int __init adt7310_spi_init(void) { return 0; }; +static void adt7310_spi_exit(void) {}; + +#endif + +static int __init adt7410_init(void) +{ + int ret; + + ret = adt7310_spi_init(); + if (ret) + return ret; + + ret = adt7410_i2c_init(); + if (ret) + adt7310_spi_exit(); + + return ret; +} +module_init(adt7410_init); + +static void __exit adt7410_exit(void) +{ + adt7410_i2c_exit(); + adt7310_spi_exit(); +} +module_exit(adt7410_exit); MODULE_AUTHOR("Sonic Zhang "); -MODULE_DESCRIPTION("Analog Devices ADT7410 digital" - " temperature sensor driver"); +MODULE_DESCRIPTION("Analog Devices ADT7310/ADT7410 digital temperature sensor driver"); MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 6b3aa3131a7804640e7589e5629036f660362f0b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 29 Oct 2012 08:25:00 +0000 Subject: Revert "iio: at91_adc: Use devm_kcalloc to allocate arrays" This reverts commit 45259859492812c8b700ae1d157be01a8d2babfe. This fixes build error because devm_kcalloc does not exist in current tree. Signed-off-by: Axel Lin Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91_adc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index a9176722042..2e2c9a80aa3 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -123,8 +123,10 @@ static int at91_adc_channel_init(struct iio_dev *idev) idev->num_channels = bitmap_weight(&st->channels_mask, st->num_channels) + 1; - chan_array = devm_kcalloc(&idev->dev, idev->num_channels + 1, - sizeof(*chan_array), GFP_KERNEL); + chan_array = devm_kzalloc(&idev->dev, + ((idev->num_channels + 1) * + sizeof(struct iio_chan_spec)), + GFP_KERNEL); if (!chan_array) return -ENOMEM; @@ -268,8 +270,9 @@ static int at91_adc_trigger_init(struct iio_dev *idev) struct at91_adc_state *st = iio_priv(idev); int i, ret; - st->trig = devm_kcalloc(&idev->dev, st->trigger_number, - sizeof(*st->trig), GFP_KERNEL); + st->trig = devm_kzalloc(&idev->dev, + st->trigger_number * sizeof(st->trig), + GFP_KERNEL); if (st->trig == NULL) { ret = -ENOMEM; @@ -451,8 +454,9 @@ static int at91_adc_probe_dt(struct at91_adc_state *st, st->registers->trigger_register = prop; st->trigger_number = of_get_child_count(node); - st->trigger_list = devm_kcalloc(&idev->dev, st->trigger_number, - sizeof(*st->trigger_list), GFP_KERNEL); + st->trigger_list = devm_kzalloc(&idev->dev, st->trigger_number * + sizeof(struct at91_adc_trigger), + GFP_KERNEL); if (!st->trigger_list) { dev_err(&idev->dev, "Could not allocate trigger list memory.\n"); ret = -ENOMEM; -- cgit v1.2.3 From 0c88d23c66884e6ac2995d4d7f881b41e0cfd27c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 24 Oct 2012 08:13:00 +0100 Subject: iio:dac:ad5449: unlock on error path There is an unlock missing on this error path. Signed-off-by: Dan Carpenter Acked-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5449.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/iio/dac/ad5449.c b/drivers/iio/dac/ad5449.c index 5b43030fe6e..0ee6f8eeba8 100644 --- a/drivers/iio/dac/ad5449.c +++ b/drivers/iio/dac/ad5449.c @@ -124,12 +124,13 @@ static int ad5449_read(struct iio_dev *indio_dev, unsigned int addr, ret = spi_sync(st->spi, &msg); if (ret < 0) - return ret; + goto out_unlock; *val = be16_to_cpu(st->data[1]); - mutex_unlock(&indio_dev->mlock); - return 0; +out_unlock: + mutex_unlock(&indio_dev->mlock); + return ret; } static int ad5449_read_raw(struct iio_dev *indio_dev, -- cgit v1.2.3 From 5fb3d522efca4b3a369040d37d1380103411db74 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Mon, 29 Oct 2012 22:11:50 -0600 Subject: ARM: OMAP2+: hwmod: add flag to prevent hwmod code from touching IP block during init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add HWMOD_EXT_OPT_MAIN_CLK flag to indicate that this IP block is dependent on an off-chip functional clock that is not guaranteed to be present during initialization. IP blocks marked with this flag are left in the INITIALIZED state during kernel init. This is a workaround for a hardware problem. It should be possible to guarantee that at least one clock source will be present and active for any IP block's main functional clock. This ensures that the hwmod code can enable and reset the IP block. Resetting the IP block during kernel init prevents any bogus bootloader, ROM code, or previous OS configuration from affecting the kernel. Hopefully a clock multiplexer can be added on future SoCs. N.B., at some point in the future, it should be possible to query the clock framework for this type of information. Then this flag should no longer be needed. Signed-off-by: Paul Walmsley Cc: Benoît Cousson --- arch/arm/mach-omap2/omap_hwmod.c | 3 +++ arch/arm/plat-omap/include/plat/omap_hwmod.h | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 70267d2cf5e..87cc6d058de 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2384,6 +2384,9 @@ static int __init _setup_reset(struct omap_hwmod *oh) if (oh->_state != _HWMOD_STATE_INITIALIZED) return -EINVAL; + if (oh->flags & HWMOD_EXT_OPT_MAIN_CLK) + return -EPERM; + if (oh->rst_lines_cnt == 0) { r = _enable(oh); if (r) { diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index b3349f7b1a2..1db02943802 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -443,6 +443,11 @@ struct omap_hwmod_omap4_prcm { * in order to complete the reset. Optional clocks will be disabled * again after the reset. * HWMOD_16BIT_REG: Module has 16bit registers + * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for + * this IP block comes from an off-chip source and is not always + * enabled. This prevents the hwmod code from being able to + * enable and reset the IP block early. XXX Eventually it should + * be possible to query the clock framework for this information. */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -453,6 +458,7 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_NO_IDLEST (1 << 6) #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) #define HWMOD_16BIT_REG (1 << 8) +#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) /* * omap_hwmod._int_flags definitions -- cgit v1.2.3 From bc05244e65f26b7b6f87e0964bfe277803914ed9 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Mon, 29 Oct 2012 22:02:14 -0600 Subject: ARM: OMAP4: hwmod data: do not enable or reset the McPDM during kernel init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve this kernel boot message: omap_hwmod: mcpdm: cannot be enabled for reset (3) The McPDM on OMAP4 can only receive its functional clock from an off-chip source. This source is not guaranteed to be present on the board, and when present, it is controlled by I2C. This would introduce a board dependency to the early hwmod code which it was not designed to handle. Also, neither the driver for this off-chip clock provider nor the I2C code is available early in boot when the hwmod code is attempting to enable and reset IP blocks. This effectively makes it impossible to enable and reset this device during hwmod init. At its core, this patch is a workaround for an OMAP hardware problem. It should be possible to configure the OMAP to provide any IP block's functional clock from an on-chip source. (This is true for almost every IP block on the chip. As far as I know, McPDM is the only exception.) If the kernel cannot reset and configure IP blocks, it cannot guarantee a sane SoC state. Relying on an optional off-chip clock also creates a board dependency which is beyond the scope of the early hwmod code. This patch works around the issue by marking the McPDM hwmod record with the HWMOD_EXT_OPT_MAIN_CLK flag. This prevents the hwmod code from touching the device early during boot. Signed-off-by: Paul Walmsley Cc: Péter Ujfalusi Cc: Benoît Cousson Acked-by: Peter Ujfalusi --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 652d0285bd6..7bddfa5534f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2125,6 +2125,14 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = { .name = "mcpdm", .class = &omap44xx_mcpdm_hwmod_class, .clkdm_name = "abe_clkdm", + /* + * It's suspected that the McPDM requires an off-chip main + * functional clock, controlled via I2C. This IP block is + * currently reset very early during boot, before I2C is + * available, so it doesn't seem that we have any choice in + * the kernel other than to avoid resetting it. + */ + .flags = HWMOD_EXT_OPT_MAIN_CLK, .mpu_irqs = omap44xx_mcpdm_irqs, .sdma_reqs = omap44xx_mcpdm_sdma_reqs, .main_clk = "mcpdm_fck", -- cgit v1.2.3 From 797b4e145cfaaa787d91ab692b0956f799e77b7a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 29 Oct 2012 00:44:41 -0700 Subject: usb: renesas_usbhs: use devm_request_irq() This patch uses devm_request_irq() instead of request_irq(), and removed free_irq() from driver Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 35c5208f324..2672487f541 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c @@ -151,7 +151,7 @@ int usbhs_mod_probe(struct usbhs_priv *priv) goto mod_init_host_err; /* irq settings */ - ret = request_irq(priv->irq, usbhs_interrupt, + ret = devm_request_irq(dev, priv->irq, usbhs_interrupt, priv->irqflags, dev_name(dev), priv); if (ret) { dev_err(dev, "irq request err\n"); @@ -172,7 +172,6 @@ void usbhs_mod_remove(struct usbhs_priv *priv) { usbhs_mod_host_remove(priv); usbhs_mod_gadget_remove(priv); - free_irq(priv->irq, priv); } /* -- cgit v1.2.3 From 3192fcb234895d9f313e7270702e1dc069d4a73a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 29 Oct 2012 00:45:07 -0700 Subject: usb: renesas_usbhs: fixup unreadable macro mod.h has irq_bempsts/irq_brdysts to keep each irq status, but it was difficult to find where they were used on renesas_usbhs driver by using "grep irq_xxxx" command, since it used irq_##status macro. This patch fixup them Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/fifo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 143c4e9e1be..3818c829082 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -192,8 +192,8 @@ void usbhs_pkt_start(struct usbhs_pipe *pipe) /* * irq enable/disable function */ -#define usbhsf_irq_empty_ctrl(p, e) usbhsf_irq_callback_ctrl(p, bempsts, e) -#define usbhsf_irq_ready_ctrl(p, e) usbhsf_irq_callback_ctrl(p, brdysts, e) +#define usbhsf_irq_empty_ctrl(p, e) usbhsf_irq_callback_ctrl(p, irq_bempsts, e) +#define usbhsf_irq_ready_ctrl(p, e) usbhsf_irq_callback_ctrl(p, irq_brdysts, e) #define usbhsf_irq_callback_ctrl(pipe, status, enable) \ ({ \ struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); \ @@ -202,9 +202,9 @@ void usbhs_pkt_start(struct usbhs_pipe *pipe) if (!mod) \ return; \ if (enable) \ - mod->irq_##status |= status; \ + mod->status |= status; \ else \ - mod->irq_##status &= ~status; \ + mod->status &= ~status; \ usbhs_irq_callback_update(priv, mod); \ }) -- cgit v1.2.3 From 87c2905fd80da736b8f9aa58cbc0c9cf34a11aac Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 29 Oct 2012 00:45:24 -0700 Subject: usb: renesas_usbhs: add DMAEngine support on mod_host This patch enabled dma mapping, and used dma transfer handler on mod_host Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod_host.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 9b69a132329..e856b449e28 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -681,9 +681,9 @@ static int usbhsh_queue_push(struct usb_hcd *hcd, } if (usb_pipein(urb->pipe)) - pipe->handler = &usbhs_fifo_pio_pop_handler; + pipe->handler = &usbhs_fifo_dma_pop_handler; else - pipe->handler = &usbhs_fifo_pio_push_handler; + pipe->handler = &usbhs_fifo_dma_push_handler; buf = (void *)(urb->transfer_buffer + urb->actual_length); len = urb->transfer_buffer_length - urb->actual_length; @@ -916,6 +916,19 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, */ static int usbhsh_dma_map_ctrl(struct usbhs_pkt *pkt, int map) { + if (map) { + struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); + struct urb *urb = ureq->urb; + + /* it can not use scatter/gather */ + if (urb->num_sgs) + return -EINVAL; + + pkt->dma = urb->transfer_dma; + if (!pkt->dma) + return -EINVAL; + } + return 0; } -- cgit v1.2.3 From 585e3931b9363fc72f626001d5d18a790a368dd1 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:14:55 +0200 Subject: usb: gadget: ecm: Add IAD descriptor in SS mode Commit d11519 ("usb: gadget: Add Interface Association Descriptor to ECM") added the IAD descriptor to FS and HS descriptors. The SS descriptor has been left out probably because it has been added "just recently". Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_ecm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 95bc94f8e57..8ab9e9638f9 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -330,6 +330,7 @@ static struct usb_ss_ep_comp_descriptor ss_ecm_bulk_comp_desc = { static struct usb_descriptor_header *ecm_ss_function[] = { /* CDC ECM control descriptors */ + (struct usb_descriptor_header *) &ecm_iad_descriptor, (struct usb_descriptor_header *) &ecm_control_intf, (struct usb_descriptor_header *) &ecm_header_desc, (struct usb_descriptor_header *) &ecm_union_desc, -- cgit v1.2.3 From fad8deb274edcef1c8ca38946338f5f4f8126fe2 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:14:56 +0200 Subject: usb: gadget: tcm_usb_gadget: NULL terminate the FS descriptor list The descriptor list for FS speed was not NULL terminated. This patch fixes this. While here one of the twe two bAlternateSetting assignments for the BOT interface. Both assign 0, one is enough. Cc: stable Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/tcm_usb_gadget.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 97e68b38cfd..49596096b43 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -2139,6 +2139,7 @@ static struct usb_descriptor_header *uasp_fs_function_desc[] = { (struct usb_descriptor_header *) &uasp_status_pipe_desc, (struct usb_descriptor_header *) &uasp_fs_cmd_desc, (struct usb_descriptor_header *) &uasp_cmd_pipe_desc, + NULL, }; static struct usb_descriptor_header *uasp_hs_function_desc[] = { -- cgit v1.2.3 From bcb2f99c6c43a8da6cb4002e8b0acf6f1275f3a8 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:14:57 +0200 Subject: usb: gadget: use a computation macro for INT endpoint interval The 5+4 magic for HS tries to aim 32ms which is also what is intended with 1 << 5 for FS. This little macro should make this easier to understand. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_acm.c | 7 +++---- drivers/usb/gadget/f_ecm.c | 8 ++++---- drivers/usb/gadget/f_ncm.c | 6 +++--- drivers/usb/gadget/f_rndis.c | 8 ++++---- include/linux/usb/composite.h | 2 ++ 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index d672250a61f..7c30bb49850 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -87,7 +87,7 @@ static inline struct f_acm *port_to_acm(struct gserial *p) /* notification endpoint uses smallish and infrequent fixed-size messages */ -#define GS_LOG2_NOTIFY_INTERVAL 5 /* 1 << 5 == 32 msec */ +#define GS_NOTIFY_INTERVAL_MS 32 #define GS_NOTIFY_MAXPACKET 10 /* notification + 2 bytes */ /* interface and class descriptors: */ @@ -167,7 +167,7 @@ static struct usb_endpoint_descriptor acm_fs_notify_desc = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET), - .bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL, + .bInterval = GS_NOTIFY_INTERVAL_MS, }; static struct usb_endpoint_descriptor acm_fs_in_desc = { @@ -199,14 +199,13 @@ static struct usb_descriptor_header *acm_fs_function[] = { }; /* high speed support: */ - static struct usb_endpoint_descriptor acm_hs_notify_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET), - .bInterval = GS_LOG2_NOTIFY_INTERVAL+4, + .bInterval = USB_MS_TO_HS_INTERVAL(GS_NOTIFY_INTERVAL_MS), }; static struct usb_endpoint_descriptor acm_hs_in_desc = { diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 8ab9e9638f9..789242749df 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -91,7 +91,7 @@ static inline unsigned ecm_bitrate(struct usb_gadget *g) * encapsulated commands (vendor-specific, using control-OUT). */ -#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ +#define ECM_STATUS_INTERVAL_MS 32 #define ECM_STATUS_BYTECOUNT 16 /* 8 byte header + data */ @@ -192,7 +192,7 @@ static struct usb_endpoint_descriptor fs_ecm_notify_desc = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT), - .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, + .bInterval = ECM_STATUS_INTERVAL_MS, }; static struct usb_endpoint_descriptor fs_ecm_in_desc = { @@ -239,7 +239,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT), - .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, + .bInterval = USB_MS_TO_HS_INTERVAL(ECM_STATUS_INTERVAL_MS), }; static struct usb_endpoint_descriptor hs_ecm_in_desc = { @@ -288,7 +288,7 @@ static struct usb_endpoint_descriptor ss_ecm_notify_desc = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT), - .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, + .bInterval = USB_MS_TO_HS_INTERVAL(ECM_STATUS_INTERVAL_MS), }; static struct usb_ss_ep_comp_descriptor ss_ecm_intr_comp_desc = { diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c index b651b529c67..4f0950069a4 100644 --- a/drivers/usb/gadget/f_ncm.c +++ b/drivers/usb/gadget/f_ncm.c @@ -121,7 +121,7 @@ static struct usb_cdc_ncm_ntb_parameters ntb_parameters = { * waste less bandwidth. */ -#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ +#define NCM_STATUS_INTERVAL_MS 32 #define NCM_STATUS_BYTECOUNT 16 /* 8 byte header + data */ static struct usb_interface_assoc_descriptor ncm_iad_desc __initdata = { @@ -230,7 +230,7 @@ static struct usb_endpoint_descriptor fs_ncm_notify_desc __initdata = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT), - .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, + .bInterval = NCM_STATUS_INTERVAL_MS, }; static struct usb_endpoint_descriptor fs_ncm_in_desc __initdata = { @@ -275,7 +275,7 @@ static struct usb_endpoint_descriptor hs_ncm_notify_desc __initdata = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(NCM_STATUS_BYTECOUNT), - .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, + .bInterval = USB_MS_TO_HS_INTERVAL(NCM_STATUS_INTERVAL_MS), }; static struct usb_endpoint_descriptor hs_ncm_in_desc __initdata = { .bLength = USB_DT_ENDPOINT_SIZE, diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index b1681e45aca..61f4b13c6cf 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -101,7 +101,7 @@ static unsigned int bitrate(struct usb_gadget *g) /* */ -#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */ +#define RNDIS_STATUS_INTERVAL_MS 32 #define STATUS_BYTECOUNT 8 /* 8 bytes data */ @@ -190,7 +190,7 @@ static struct usb_endpoint_descriptor fs_notify_desc = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), - .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, + .bInterval = RNDIS_STATUS_INTERVAL_MS, }; static struct usb_endpoint_descriptor fs_in_desc = { @@ -236,7 +236,7 @@ static struct usb_endpoint_descriptor hs_notify_desc = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), - .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, + .bInterval = USB_MS_TO_HS_INTERVAL(RNDIS_STATUS_INTERVAL_MS) }; static struct usb_endpoint_descriptor hs_in_desc = { @@ -284,7 +284,7 @@ static struct usb_endpoint_descriptor ss_notify_desc = { .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), - .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, + .bInterval = USB_MS_TO_HS_INTERVAL(RNDIS_STATUS_INTERVAL_MS) }; static struct usb_ss_ep_comp_descriptor ss_intr_comp_desc = { diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index f8dda062180..8634a127bdd 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -38,6 +38,7 @@ #include #include #include +#include /* * USB function drivers should return USB_GADGET_DELAYED_STATUS if they @@ -51,6 +52,7 @@ /* big enough to hold our biggest descriptor */ #define USB_COMP_EP0_BUFSIZ 1024 +#define USB_MS_TO_HS_INTERVAL(x) (ilog2((x * 1000 / 125)) + 1) struct usb_configuration; /** -- cgit v1.2.3 From 64dce9144507d4a6c624fe1b8e0aa88daeae0b9b Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:14:58 +0200 Subject: usb: gadget storage: use a computation macro for INT endpoint interval The 9 for HS means 32ms. Use the macro to make it easier to read. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/storage_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 8d9bcd8207c..14199d70bee 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -441,7 +441,7 @@ fsg_hs_intr_in_desc = { /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(2), - .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */ + .bInterval = USB_MS_TO_HS_INTERVAL(32), /* 32 ms */ }; #ifndef FSG_NO_OTG @@ -509,7 +509,7 @@ fsg_ss_intr_in_desc = { /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ .bmAttributes = USB_ENDPOINT_XFER_INT, .wMaxPacketSize = cpu_to_le16(2), - .bInterval = 9, /* 2**(9-1) = 256 uframes -> 32 ms */ + .bInterval = USB_MS_TO_HS_INTERVAL(32), /* 32 ms */ }; static struct usb_ss_ep_comp_descriptor fsg_ss_intr_in_comp_desc = { -- cgit v1.2.3 From 391aa852a372308c216d8638e57fe8fe560558f2 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:14:59 +0200 Subject: usb: gadget: uac2: add some error recovery in afunc_bind() In case something goes wrong here, don't leak memory / endpoints. Acked-by: Jassi Brar Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uac2.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index d3c6cffccb7..f02b8ece528 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c @@ -978,15 +978,19 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) INTF_SET(agdev->as_in_alt, ret); agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); - if (!agdev->out_ep) + if (!agdev->out_ep) { dev_err(&uac2->pdev.dev, "%s:%d Error!\n", __func__, __LINE__); + goto err; + } agdev->out_ep->driver_data = agdev; agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); - if (!agdev->in_ep) + if (!agdev->in_ep) { dev_err(&uac2->pdev.dev, "%s:%d Error!\n", __func__, __LINE__); + goto err; + } agdev->in_ep->driver_data = agdev; hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; @@ -1005,6 +1009,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) prm->max_psize = 0; dev_err(&uac2->pdev.dev, "%s:%d Error!\n", __func__, __LINE__); + goto err; } prm = &agdev->uac2.p_prm; @@ -1014,9 +1019,23 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) prm->max_psize = 0; dev_err(&uac2->pdev.dev, "%s:%d Error!\n", __func__, __LINE__); + goto err; } - return alsa_uac2_init(agdev); + ret = alsa_uac2_init(agdev); + if (ret) + goto err; + return 0; +err: + kfree(agdev->uac2.p_prm.rbuf); + kfree(agdev->uac2.c_prm.rbuf); + usb_free_descriptors(fn->hs_descriptors); + usb_free_descriptors(fn->descriptors); + if (agdev->in_ep) + agdev->in_ep->driver_data = NULL; + if (agdev->out_ep) + agdev->out_ep->driver_data = NULL; + return -EINVAL; } static void -- cgit v1.2.3 From e79cc615a9bb44da72c499ccfa2c9c4bbea3aa84 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:15:00 +0200 Subject: usb: gadget: network: fix bind() error path I think this is wrong since 72c973dd ("usb: gadget: add usb_endpoint_descriptor to struct usb_ep"). If we fail to allocate an ep or bail out early we shouldn't check for the descriptor which is assigned at ep_enable() time. Cc: Tatyana Brokhman Cc: stable Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_ecm.c | 4 ++-- drivers/usb/gadget/f_eem.c | 5 ++--- drivers/usb/gadget/f_ncm.c | 4 ++-- drivers/usb/gadget/f_rndis.c | 4 ++-- drivers/usb/gadget/f_subset.c | 4 ++-- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 789242749df..a158740255c 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -809,9 +809,9 @@ fail: /* we might as well release our claims on endpoints */ if (ecm->notify) ecm->notify->driver_data = NULL; - if (ecm->port.out_ep->desc) + if (ecm->port.out_ep) ecm->port.out_ep->driver_data = NULL; - if (ecm->port.in_ep->desc) + if (ecm->port.in_ep) ecm->port.in_ep->driver_data = NULL; ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c index 1a7b2dd7d40..a9cf20522ff 100644 --- a/drivers/usb/gadget/f_eem.c +++ b/drivers/usb/gadget/f_eem.c @@ -319,10 +319,9 @@ fail: if (f->hs_descriptors) usb_free_descriptors(f->hs_descriptors); - /* we might as well release our claims on endpoints */ - if (eem->port.out_ep->desc) + if (eem->port.out_ep) eem->port.out_ep->driver_data = NULL; - if (eem->port.in_ep->desc) + if (eem->port.in_ep) eem->port.in_ep->driver_data = NULL; ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c index 4f0950069a4..424fc3d1cc3 100644 --- a/drivers/usb/gadget/f_ncm.c +++ b/drivers/usb/gadget/f_ncm.c @@ -1259,9 +1259,9 @@ fail: /* we might as well release our claims on endpoints */ if (ncm->notify) ncm->notify->driver_data = NULL; - if (ncm->port.out_ep->desc) + if (ncm->port.out_ep) ncm->port.out_ep->driver_data = NULL; - if (ncm->port.in_ep->desc) + if (ncm->port.in_ep) ncm->port.in_ep->driver_data = NULL; ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 61f4b13c6cf..7c27626f023 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -803,9 +803,9 @@ fail: /* we might as well release our claims on endpoints */ if (rndis->notify) rndis->notify->driver_data = NULL; - if (rndis->port.out_ep->desc) + if (rndis->port.out_ep) rndis->port.out_ep->driver_data = NULL; - if (rndis->port.in_ep->desc) + if (rndis->port.in_ep) rndis->port.in_ep->driver_data = NULL; ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index 4060c0bd978..deb437c3b53 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c @@ -370,9 +370,9 @@ fail: usb_free_descriptors(f->hs_descriptors); /* we might as well release our claims on endpoints */ - if (geth->port.out_ep->desc) + if (geth->port.out_ep) geth->port.out_ep->driver_data = NULL; - if (geth->port.in_ep->desc) + if (geth->port.in_ep) geth->port.in_ep->driver_data = NULL; ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); -- cgit v1.2.3 From 1377af2f756f3b5de2850ec0a5edebf227798d02 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:15:01 +0200 Subject: usb: gadget: audio: remove c->highpseed = true from f_midi and uac1 Whether highspeed configuration is valid or not is something that composite decides and not the gadget. That gadget can only provide the required descriptors for it. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_midi.c | 1 - drivers/usb/gadget/f_uac1.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c index 8ed1259fe80..b2522ba3691 100644 --- a/drivers/usb/gadget/f_midi.c +++ b/drivers/usb/gadget/f_midi.c @@ -882,7 +882,6 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f) */ /* copy descriptors, and track endpoint copies */ if (gadget_is_dualspeed(c->cdev->gadget)) { - c->highspeed = true; bulk_in_desc.wMaxPacketSize = cpu_to_le16(512); bulk_out_desc.wMaxPacketSize = cpu_to_le16(512); f->hs_descriptors = usb_copy_descriptors(midi_function); diff --git a/drivers/usb/gadget/f_uac1.c b/drivers/usb/gadget/f_uac1.c index 1a5dcd5565e..c8ed41ba104 100644 --- a/drivers/usb/gadget/f_uac1.c +++ b/drivers/usb/gadget/f_uac1.c @@ -667,7 +667,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) * both speeds */ if (gadget_is_dualspeed(c->cdev->gadget)) { - c->highspeed = true; f->hs_descriptors = usb_copy_descriptors(f_audio_desc); } -- cgit v1.2.3 From d185039f7982eb82cf8d03b6fb6689587ca5af24 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:15:02 +0200 Subject: usb: gadget: midi: free hs descriptors The HS descriptors are only created if HS is supported by the UDC but we never free them. Cc: stable Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_midi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c index b2522ba3691..b978c5d15cb 100644 --- a/drivers/usb/gadget/f_midi.c +++ b/drivers/usb/gadget/f_midi.c @@ -415,6 +415,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) midi->id = NULL; usb_free_descriptors(f->descriptors); + usb_free_descriptors(f->hs_descriptors); kfree(midi); } -- cgit v1.2.3 From 7f2a9268b458b693160f02f0df2bafb83e128750 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:15:03 +0200 Subject: usb: gadget: midi: make FS and HS available This function works only on FS or HS. If the gadget is HS capable only HS descriptors are assigned. If we plug it to an 1.1 host it won't work because we have only 2.0 descriptors. This patch changes the behavior to provide both sets. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_midi.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c index b978c5d15cb..b265ee8fa5a 100644 --- a/drivers/usb/gadget/f_midi.c +++ b/drivers/usb/gadget/f_midi.c @@ -882,18 +882,24 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f) * both speeds */ /* copy descriptors, and track endpoint copies */ + f->descriptors = usb_copy_descriptors(midi_function); + if (!f->descriptors) + goto fail_f_midi; if (gadget_is_dualspeed(c->cdev->gadget)) { bulk_in_desc.wMaxPacketSize = cpu_to_le16(512); bulk_out_desc.wMaxPacketSize = cpu_to_le16(512); f->hs_descriptors = usb_copy_descriptors(midi_function); - } else { - f->descriptors = usb_copy_descriptors(midi_function); + if (!f->hs_descriptors) + goto fail_f_midi; } kfree(midi_function); return 0; +fail_f_midi: + kfree(midi_function); + usb_free_descriptors(f->hs_descriptors); fail: /* we might as well release our claims on endpoints */ if (midi->out_ep) -- cgit v1.2.3 From d0eca719dd11ad0619e8dd6a1f3eceb95b0216dd Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:15:04 +0200 Subject: usb: gadget: phonet: free requests in pn_bind()'s error path Cc: stable Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_phonet.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index 8ee9268fe25..a6c19a486d5 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -531,7 +531,7 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f) req = usb_ep_alloc_request(fp->out_ep, GFP_KERNEL); if (!req) - goto err; + goto err_req; req->complete = pn_rx_complete; fp->out_reqv[i] = req; @@ -540,14 +540,18 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f) /* Outgoing USB requests */ fp->in_req = usb_ep_alloc_request(fp->in_ep, GFP_KERNEL); if (!fp->in_req) - goto err; + goto err_req; INFO(cdev, "USB CDC Phonet function\n"); INFO(cdev, "using %s, OUT %s, IN %s\n", cdev->gadget->name, fp->out_ep->name, fp->in_ep->name); return 0; +err_req: + for (i = 0; i < phonet_rxq_size && fp->out_reqv[i]; i++) + usb_ep_free_request(fp->out_ep, fp->out_reqv[i]); err: + if (fp->out_ep) fp->out_ep->driver_data = NULL; if (fp->in_ep) -- cgit v1.2.3 From 0f9df939385527049c8062a099fbfa1479fe7ce0 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:15:05 +0200 Subject: usb: gadget: uvc: fix error path in uvc_function_bind() The "video->minor = -1" assigment is done in V4L2 by video_register_device() so it is removed here. Now. uvc_function_bind() calls in error case uvc_function_unbind() for cleanup. The problem is that uvc_function_unbind() frees the uvc struct and uvc_bind_config() does as well in error case of usb_add_function(). Removing kfree() in usb_add_function() would make the patch smaller but it would look odd because the new allocated memory is not cleaned up. However it is not guaranteed that if we call usb_add_function() we also get to the bind function. Therefore the patch extracts the conditional cleanup from uvc_function_unbind() applies to uvc_function_bind(). uvc_function_unbind() now contains only the complete cleanup which is required once everything has been registrated. Cc: Laurent Pinchart Cc: Bhupesh Sharma Cc: stable Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uvc.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 2a8bf0655c6..10f13c1213c 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -417,7 +417,6 @@ uvc_register_video(struct uvc_device *uvc) return -ENOMEM; video->parent = &cdev->gadget->dev; - video->minor = -1; video->fops = &uvc_v4l2_fops; video->release = video_device_release; strncpy(video->name, cdev->gadget->name, sizeof(video->name)); @@ -577,23 +576,12 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f) INFO(cdev, "uvc_function_unbind\n"); - if (uvc->vdev) { - if (uvc->vdev->minor == -1) - video_device_release(uvc->vdev); - else - video_unregister_device(uvc->vdev); - uvc->vdev = NULL; - } - - if (uvc->control_ep) - uvc->control_ep->driver_data = NULL; - if (uvc->video.ep) - uvc->video.ep->driver_data = NULL; + video_unregister_device(uvc->vdev); + uvc->control_ep->driver_data = NULL; + uvc->video.ep->driver_data = NULL; - if (uvc->control_req) { - usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); - kfree(uvc->control_buf); - } + usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); + kfree(uvc->control_buf); kfree(f->descriptors); kfree(f->hs_descriptors); @@ -740,7 +728,22 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) return 0; error: - uvc_function_unbind(c, f); + if (uvc->vdev) + video_device_release(uvc->vdev); + + if (uvc->control_ep) + uvc->control_ep->driver_data = NULL; + if (uvc->video.ep) + uvc->video.ep->driver_data = NULL; + + if (uvc->control_req) { + usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); + kfree(uvc->control_buf); + } + + kfree(f->descriptors); + kfree(f->hs_descriptors); + kfree(f->ss_descriptors); return ret; } -- cgit v1.2.3 From 10287baec761d33f0a82d84b46e37a44030350d8 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:15:06 +0200 Subject: usb: gadget: always update HS/SS descriptors and create a copy of them HS and SS descriptors are staticaly created. They are updated during the bind process with the endpoint address, string id or interface numbers. After that, the descriptor chain is linked to struct usb_function which is used by composite in order to serve the GET_DESCRIPTOR requests, number of available configs and so on. There is no need to assign the HS descriptor only if the UDC supports HS speed because composite won't report those to the host if HS support has not been reached. The same reasoning is valid for SS. This patch makes sure each function updates HS/SS descriptors unconditionally and uses the newly introduced helper function to create a copy the descriptors for the speed which is supported by the UDC. While at that, also rename f->descriptors to f->fs_descriptors in order to make it more explicit what that means. Cc: Laurent Pinchart Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 8 +-- drivers/usb/gadget/config.c | 39 +++++++++++++- drivers/usb/gadget/f_acm.c | 45 +++++----------- drivers/usb/gadget/f_ecm.c | 57 ++++++-------------- drivers/usb/gadget/f_eem.c | 46 ++++------------ drivers/usb/gadget/f_fs.c | 4 +- drivers/usb/gadget/f_hid.c | 30 ++++------- drivers/usb/gadget/f_loopback.c | 28 +++++----- drivers/usb/gadget/f_mass_storage.c | 59 +++++++------------- drivers/usb/gadget/f_midi.c | 8 +-- drivers/usb/gadget/f_ncm.c | 32 +++-------- drivers/usb/gadget/f_obex.c | 23 ++++---- drivers/usb/gadget/f_phonet.c | 15 +++--- drivers/usb/gadget/f_rndis.c | 55 +++++-------------- drivers/usb/gadget/f_serial.c | 38 ++++--------- drivers/usb/gadget/f_sourcesink.c | 104 +++++++++++++++++------------------- drivers/usb/gadget/f_subset.c | 48 +++++------------ drivers/usb/gadget/f_uac1.c | 22 +++----- drivers/usb/gadget/f_uac2.c | 16 ++---- drivers/usb/gadget/f_uvc.c | 79 ++++++++++++--------------- drivers/usb/gadget/printer.c | 12 +++-- drivers/usb/gadget/tcm_usb_gadget.c | 10 ++-- include/linux/usb/composite.h | 2 +- include/linux/usb/gadget.h | 7 +++ 24 files changed, 307 insertions(+), 480 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 957f973dd96..2a6bfe759c2 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -107,7 +107,7 @@ int config_ep_by_speed(struct usb_gadget *g, } /* else: fall through */ default: - speed_desc = f->descriptors; + speed_desc = f->fs_descriptors; } /* find descriptors */ for_each_ep_desc(speed_desc, d_spd) { @@ -200,7 +200,7 @@ int usb_add_function(struct usb_configuration *config, * as full speed ... it's the function drivers that will need * to avoid bulk and ISO transfers. */ - if (!config->fullspeed && function->descriptors) + if (!config->fullspeed && function->fs_descriptors) config->fullspeed = true; if (!config->highspeed && function->hs_descriptors) config->highspeed = true; @@ -363,7 +363,7 @@ static int config_buf(struct usb_configuration *config, descriptors = f->hs_descriptors; break; default: - descriptors = f->descriptors; + descriptors = f->fs_descriptors; } if (!descriptors) @@ -620,7 +620,7 @@ static int set_config(struct usb_composite_dev *cdev, descriptors = f->hs_descriptors; break; default: - descriptors = f->descriptors; + descriptors = f->fs_descriptors; } for (; *descriptors; ++descriptors) { diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index e3a98929d34..34e12fc52c2 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -19,7 +19,7 @@ #include #include - +#include /** * usb_descriptor_fillbuf - fill buffer with descriptors @@ -158,3 +158,40 @@ usb_copy_descriptors(struct usb_descriptor_header **src) return ret; } EXPORT_SYMBOL_GPL(usb_copy_descriptors); + +int usb_assign_descriptors(struct usb_function *f, + struct usb_descriptor_header **fs, + struct usb_descriptor_header **hs, + struct usb_descriptor_header **ss) +{ + struct usb_gadget *g = f->config->cdev->gadget; + + if (fs) { + f->fs_descriptors = usb_copy_descriptors(fs); + if (!f->fs_descriptors) + goto err; + } + if (hs && gadget_is_dualspeed(g)) { + f->hs_descriptors = usb_copy_descriptors(hs); + if (!f->hs_descriptors) + goto err; + } + if (ss && gadget_is_superspeed(g)) { + f->ss_descriptors = usb_copy_descriptors(ss); + if (!f->ss_descriptors) + goto err; + } + return 0; +err: + usb_free_all_descriptors(f); + return -ENOMEM; +} +EXPORT_SYMBOL_GPL(usb_assign_descriptors); + +void usb_free_all_descriptors(struct usb_function *f) +{ + usb_free_descriptors(f->fs_descriptors); + usb_free_descriptors(f->hs_descriptors); + usb_free_descriptors(f->ss_descriptors); +} +EXPORT_SYMBOL_GPL(usb_free_all_descriptors); diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 7c30bb49850..308242b5d6e 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -658,37 +658,22 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) acm->notify_req->complete = acm_cdc_notify_complete; acm->notify_req->context = acm; - /* copy descriptors */ - f->descriptors = usb_copy_descriptors(acm_fs_function); - if (!f->descriptors) - goto fail; - /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - acm_hs_in_desc.bEndpointAddress = - acm_fs_in_desc.bEndpointAddress; - acm_hs_out_desc.bEndpointAddress = - acm_fs_out_desc.bEndpointAddress; - acm_hs_notify_desc.bEndpointAddress = - acm_fs_notify_desc.bEndpointAddress; - - /* copy descriptors */ - f->hs_descriptors = usb_copy_descriptors(acm_hs_function); - } - if (gadget_is_superspeed(c->cdev->gadget)) { - acm_ss_in_desc.bEndpointAddress = - acm_fs_in_desc.bEndpointAddress; - acm_ss_out_desc.bEndpointAddress = - acm_fs_out_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->ss_descriptors = usb_copy_descriptors(acm_ss_function); - if (!f->ss_descriptors) - goto fail; - } + acm_hs_in_desc.bEndpointAddress = acm_fs_in_desc.bEndpointAddress; + acm_hs_out_desc.bEndpointAddress = acm_fs_out_desc.bEndpointAddress; + acm_hs_notify_desc.bEndpointAddress = + acm_fs_notify_desc.bEndpointAddress; + + acm_ss_in_desc.bEndpointAddress = acm_fs_in_desc.bEndpointAddress; + acm_ss_out_desc.bEndpointAddress = acm_fs_out_desc.bEndpointAddress; + + status = usb_assign_descriptors(f, acm_fs_function, acm_hs_function, + acm_ss_function); + if (status) + goto fail; DBG(cdev, "acm ttyGS%d: %s speed IN/%s OUT/%s NOTIFY/%s\n", acm->port_num, @@ -720,11 +705,7 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f) { struct f_acm *acm = func_to_acm(f); - if (gadget_is_dualspeed(c->cdev->gadget)) - usb_free_descriptors(f->hs_descriptors); - if (gadget_is_superspeed(c->cdev->gadget)) - usb_free_descriptors(f->ss_descriptors); - usb_free_descriptors(f->descriptors); + usb_free_all_descriptors(f); gs_free_req(acm->notify, acm->notify_req); kfree(acm); } diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index a158740255c..2d3c5a46de8 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -743,42 +743,24 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) ecm->notify_req->context = ecm; ecm->notify_req->complete = ecm_notify_complete; - /* copy descriptors, and track endpoint copies */ - f->descriptors = usb_copy_descriptors(ecm_fs_function); - if (!f->descriptors) - goto fail; - /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - hs_ecm_in_desc.bEndpointAddress = - fs_ecm_in_desc.bEndpointAddress; - hs_ecm_out_desc.bEndpointAddress = - fs_ecm_out_desc.bEndpointAddress; - hs_ecm_notify_desc.bEndpointAddress = - fs_ecm_notify_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->hs_descriptors = usb_copy_descriptors(ecm_hs_function); - if (!f->hs_descriptors) - goto fail; - } - - if (gadget_is_superspeed(c->cdev->gadget)) { - ss_ecm_in_desc.bEndpointAddress = - fs_ecm_in_desc.bEndpointAddress; - ss_ecm_out_desc.bEndpointAddress = - fs_ecm_out_desc.bEndpointAddress; - ss_ecm_notify_desc.bEndpointAddress = - fs_ecm_notify_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->ss_descriptors = usb_copy_descriptors(ecm_ss_function); - if (!f->ss_descriptors) - goto fail; - } + hs_ecm_in_desc.bEndpointAddress = fs_ecm_in_desc.bEndpointAddress; + hs_ecm_out_desc.bEndpointAddress = fs_ecm_out_desc.bEndpointAddress; + hs_ecm_notify_desc.bEndpointAddress = + fs_ecm_notify_desc.bEndpointAddress; + + ss_ecm_in_desc.bEndpointAddress = fs_ecm_in_desc.bEndpointAddress; + ss_ecm_out_desc.bEndpointAddress = fs_ecm_out_desc.bEndpointAddress; + ss_ecm_notify_desc.bEndpointAddress = + fs_ecm_notify_desc.bEndpointAddress; + + status = usb_assign_descriptors(f, ecm_fs_function, ecm_hs_function, + ecm_ss_function); + if (status) + goto fail; /* NOTE: all that is done without knowing or caring about * the network link ... which is unavailable to this code @@ -796,11 +778,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - if (f->descriptors) - usb_free_descriptors(f->descriptors); - if (f->hs_descriptors) - usb_free_descriptors(f->hs_descriptors); - if (ecm->notify_req) { kfree(ecm->notify_req->buf); usb_ep_free_request(ecm->notify, ecm->notify_req); @@ -826,11 +803,7 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f) DBG(c->cdev, "ecm unbind\n"); - if (gadget_is_superspeed(c->cdev->gadget)) - usb_free_descriptors(f->ss_descriptors); - if (gadget_is_dualspeed(c->cdev->gadget)) - usb_free_descriptors(f->hs_descriptors); - usb_free_descriptors(f->descriptors); + usb_free_all_descriptors(f); kfree(ecm->notify_req->buf); usb_ep_free_request(ecm->notify, ecm->notify_req); diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c index a9cf20522ff..cf0ebee8556 100644 --- a/drivers/usb/gadget/f_eem.c +++ b/drivers/usb/gadget/f_eem.c @@ -274,38 +274,20 @@ eem_bind(struct usb_configuration *c, struct usb_function *f) status = -ENOMEM; - /* copy descriptors, and track endpoint copies */ - f->descriptors = usb_copy_descriptors(eem_fs_function); - if (!f->descriptors) - goto fail; - /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - eem_hs_in_desc.bEndpointAddress = - eem_fs_in_desc.bEndpointAddress; - eem_hs_out_desc.bEndpointAddress = - eem_fs_out_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->hs_descriptors = usb_copy_descriptors(eem_hs_function); - if (!f->hs_descriptors) - goto fail; - } + eem_hs_in_desc.bEndpointAddress = eem_fs_in_desc.bEndpointAddress; + eem_hs_out_desc.bEndpointAddress = eem_fs_out_desc.bEndpointAddress; - if (gadget_is_superspeed(c->cdev->gadget)) { - eem_ss_in_desc.bEndpointAddress = - eem_fs_in_desc.bEndpointAddress; - eem_ss_out_desc.bEndpointAddress = - eem_fs_out_desc.bEndpointAddress; + eem_ss_in_desc.bEndpointAddress = eem_fs_in_desc.bEndpointAddress; + eem_ss_out_desc.bEndpointAddress = eem_fs_out_desc.bEndpointAddress; - /* copy descriptors, and track endpoint copies */ - f->ss_descriptors = usb_copy_descriptors(eem_ss_function); - if (!f->ss_descriptors) - goto fail; - } + status = usb_assign_descriptors(f, eem_fs_function, eem_hs_function, + eem_ss_function); + if (status) + goto fail; DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n", gadget_is_superspeed(c->cdev->gadget) ? "super" : @@ -314,11 +296,7 @@ eem_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - if (f->descriptors) - usb_free_descriptors(f->descriptors); - if (f->hs_descriptors) - usb_free_descriptors(f->hs_descriptors); - + usb_free_all_descriptors(f); if (eem->port.out_ep) eem->port.out_ep->driver_data = NULL; if (eem->port.in_ep) @@ -336,11 +314,7 @@ eem_unbind(struct usb_configuration *c, struct usb_function *f) DBG(c->cdev, "eem unbind\n"); - if (gadget_is_superspeed(c->cdev->gadget)) - usb_free_descriptors(f->ss_descriptors); - if (gadget_is_dualspeed(c->cdev->gadget)) - usb_free_descriptors(f->hs_descriptors); - usb_free_descriptors(f->descriptors); + usb_free_all_descriptors(f); kfree(eem); } diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 64c4ec10d1f..4a6961c517f 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -2097,7 +2097,7 @@ static int __ffs_func_bind_do_descs(enum ffs_entity_type type, u8 *valuep, if (isHS) func->function.hs_descriptors[(long)valuep] = desc; else - func->function.descriptors[(long)valuep] = desc; + func->function.fs_descriptors[(long)valuep] = desc; if (!desc || desc->bDescriptorType != USB_DT_ENDPOINT) return 0; @@ -2249,7 +2249,7 @@ static int ffs_func_bind(struct usb_configuration *c, * numbers without worrying that it may be described later on. */ if (likely(full)) { - func->function.descriptors = data->fs_descs; + func->function.fs_descriptors = data->fs_descs; ret = ffs_do_descs(ffs->fs_descs_count, data->raw_descs, sizeof data->raw_descs, diff --git a/drivers/usb/gadget/f_hid.c b/drivers/usb/gadget/f_hid.c index 511e527178e..6e69a8e8d22 100644 --- a/drivers/usb/gadget/f_hid.c +++ b/drivers/usb/gadget/f_hid.c @@ -573,7 +573,6 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) goto fail; hidg_interface_desc.bInterfaceNumber = status; - /* allocate instance-specific endpoints */ status = -ENODEV; ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc); @@ -609,20 +608,15 @@ static int __init hidg_bind(struct usb_configuration *c, struct usb_function *f) hidg_desc.desc[0].wDescriptorLength = cpu_to_le16(hidg->report_desc_length); - /* copy descriptors */ - f->descriptors = usb_copy_descriptors(hidg_fs_descriptors); - if (!f->descriptors) - goto fail; + hidg_hs_in_ep_desc.bEndpointAddress = + hidg_fs_in_ep_desc.bEndpointAddress; + hidg_hs_out_ep_desc.bEndpointAddress = + hidg_fs_out_ep_desc.bEndpointAddress; - if (gadget_is_dualspeed(c->cdev->gadget)) { - hidg_hs_in_ep_desc.bEndpointAddress = - hidg_fs_in_ep_desc.bEndpointAddress; - hidg_hs_out_ep_desc.bEndpointAddress = - hidg_fs_out_ep_desc.bEndpointAddress; - f->hs_descriptors = usb_copy_descriptors(hidg_hs_descriptors); - if (!f->hs_descriptors) - goto fail; - } + status = usb_assign_descriptors(f, hidg_fs_descriptors, + hidg_hs_descriptors, NULL); + if (status) + goto fail; mutex_init(&hidg->lock); spin_lock_init(&hidg->spinlock); @@ -649,9 +643,7 @@ fail: usb_ep_free_request(hidg->in_ep, hidg->req); } - usb_free_descriptors(f->hs_descriptors); - usb_free_descriptors(f->descriptors); - + usb_free_all_descriptors(f); return status; } @@ -668,9 +660,7 @@ static void hidg_unbind(struct usb_configuration *c, struct usb_function *f) kfree(hidg->req->buf); usb_ep_free_request(hidg->in_ep, hidg->req); - /* free descriptors copies */ - usb_free_descriptors(f->hs_descriptors); - usb_free_descriptors(f->descriptors); + usb_free_all_descriptors(f); kfree(hidg->report_desc); kfree(hidg); diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index 7275706caeb..bb39cb2bb3a 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c @@ -177,6 +177,7 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f) struct usb_composite_dev *cdev = c->cdev; struct f_loopback *loop = func_to_loop(f); int id; + int ret; /* allocate interface ID(s) */ id = usb_interface_id(c, f); @@ -201,22 +202,19 @@ autoconf_fail: loop->out_ep->driver_data = cdev; /* claim */ /* support high speed hardware */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - hs_loop_source_desc.bEndpointAddress = - fs_loop_source_desc.bEndpointAddress; - hs_loop_sink_desc.bEndpointAddress = - fs_loop_sink_desc.bEndpointAddress; - f->hs_descriptors = hs_loopback_descs; - } + hs_loop_source_desc.bEndpointAddress = + fs_loop_source_desc.bEndpointAddress; + hs_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress; /* support super speed hardware */ - if (gadget_is_superspeed(c->cdev->gadget)) { - ss_loop_source_desc.bEndpointAddress = - fs_loop_source_desc.bEndpointAddress; - ss_loop_sink_desc.bEndpointAddress = - fs_loop_sink_desc.bEndpointAddress; - f->ss_descriptors = ss_loopback_descs; - } + ss_loop_source_desc.bEndpointAddress = + fs_loop_source_desc.bEndpointAddress; + ss_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress; + + ret = usb_assign_descriptors(f, fs_loopback_descs, hs_loopback_descs, + ss_loopback_descs); + if (ret) + return ret; DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", (gadget_is_superspeed(c->cdev->gadget) ? "super" : @@ -228,6 +226,7 @@ autoconf_fail: static void loopback_unbind(struct usb_configuration *c, struct usb_function *f) { + usb_free_all_descriptors(f); kfree(func_to_loop(f)); } @@ -379,7 +378,6 @@ static int __init loopback_bind_config(struct usb_configuration *c) return -ENOMEM; loop->function.name = "loopback"; - loop->function.descriptors = fs_loopback_descs; loop->function.bind = loopback_bind; loop->function.unbind = loopback_unbind; loop->function.set_alt = loopback_set_alt; diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 3a7668bde3e..3433e432a4a 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -2904,9 +2904,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) } fsg_common_put(common); - usb_free_descriptors(fsg->function.descriptors); - usb_free_descriptors(fsg->function.hs_descriptors); - usb_free_descriptors(fsg->function.ss_descriptors); + usb_free_all_descriptors(&fsg->function); kfree(fsg); } @@ -2916,6 +2914,8 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) struct usb_gadget *gadget = c->cdev->gadget; int i; struct usb_ep *ep; + unsigned max_burst; + int ret; fsg->gadget = gadget; @@ -2939,45 +2939,27 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) ep->driver_data = fsg->common; /* claim the endpoint */ fsg->bulk_out = ep; - /* Copy descriptors */ - f->descriptors = usb_copy_descriptors(fsg_fs_function); - if (unlikely(!f->descriptors)) - return -ENOMEM; - - if (gadget_is_dualspeed(gadget)) { - /* Assume endpoint addresses are the same for both speeds */ - fsg_hs_bulk_in_desc.bEndpointAddress = - fsg_fs_bulk_in_desc.bEndpointAddress; - fsg_hs_bulk_out_desc.bEndpointAddress = - fsg_fs_bulk_out_desc.bEndpointAddress; - f->hs_descriptors = usb_copy_descriptors(fsg_hs_function); - if (unlikely(!f->hs_descriptors)) { - usb_free_descriptors(f->descriptors); - return -ENOMEM; - } - } - - if (gadget_is_superspeed(gadget)) { - unsigned max_burst; + /* Assume endpoint addresses are the same for both speeds */ + fsg_hs_bulk_in_desc.bEndpointAddress = + fsg_fs_bulk_in_desc.bEndpointAddress; + fsg_hs_bulk_out_desc.bEndpointAddress = + fsg_fs_bulk_out_desc.bEndpointAddress; - /* Calculate bMaxBurst, we know packet size is 1024 */ - max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15); + /* Calculate bMaxBurst, we know packet size is 1024 */ + max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15); - fsg_ss_bulk_in_desc.bEndpointAddress = - fsg_fs_bulk_in_desc.bEndpointAddress; - fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst; + fsg_ss_bulk_in_desc.bEndpointAddress = + fsg_fs_bulk_in_desc.bEndpointAddress; + fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst; - fsg_ss_bulk_out_desc.bEndpointAddress = - fsg_fs_bulk_out_desc.bEndpointAddress; - fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst; + fsg_ss_bulk_out_desc.bEndpointAddress = + fsg_fs_bulk_out_desc.bEndpointAddress; + fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst; - f->ss_descriptors = usb_copy_descriptors(fsg_ss_function); - if (unlikely(!f->ss_descriptors)) { - usb_free_descriptors(f->hs_descriptors); - usb_free_descriptors(f->descriptors); - return -ENOMEM; - } - } + ret = usb_assign_descriptors(f, fsg_fs_function, fsg_hs_function, + fsg_ss_function); + if (ret) + goto autoconf_fail; return 0; @@ -2986,7 +2968,6 @@ autoconf_fail: return -ENOTSUPP; } - /****************************** ADD FUNCTION ******************************/ static struct usb_gadget_strings *fsg_strings_array[] = { diff --git a/drivers/usb/gadget/f_midi.c b/drivers/usb/gadget/f_midi.c index b265ee8fa5a..263e721c269 100644 --- a/drivers/usb/gadget/f_midi.c +++ b/drivers/usb/gadget/f_midi.c @@ -414,8 +414,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) kfree(midi->id); midi->id = NULL; - usb_free_descriptors(f->descriptors); - usb_free_descriptors(f->hs_descriptors); + usb_free_all_descriptors(f); kfree(midi); } @@ -882,9 +881,10 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f) * both speeds */ /* copy descriptors, and track endpoint copies */ - f->descriptors = usb_copy_descriptors(midi_function); - if (!f->descriptors) + f->fs_descriptors = usb_copy_descriptors(midi_function); + if (!f->fs_descriptors) goto fail_f_midi; + if (gadget_is_dualspeed(c->cdev->gadget)) { bulk_in_desc.wMaxPacketSize = cpu_to_le16(512); bulk_out_desc.wMaxPacketSize = cpu_to_le16(512); diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c index 424fc3d1cc3..326d7e6c297 100644 --- a/drivers/usb/gadget/f_ncm.c +++ b/drivers/usb/gadget/f_ncm.c @@ -1208,30 +1208,18 @@ ncm_bind(struct usb_configuration *c, struct usb_function *f) ncm->notify_req->context = ncm; ncm->notify_req->complete = ncm_notify_complete; - /* copy descriptors, and track endpoint copies */ - f->descriptors = usb_copy_descriptors(ncm_fs_function); - if (!f->descriptors) - goto fail; - /* * support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - hs_ncm_in_desc.bEndpointAddress = - fs_ncm_in_desc.bEndpointAddress; - hs_ncm_out_desc.bEndpointAddress = - fs_ncm_out_desc.bEndpointAddress; - hs_ncm_notify_desc.bEndpointAddress = - fs_ncm_notify_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->hs_descriptors = usb_copy_descriptors(ncm_hs_function); - if (!f->hs_descriptors) - goto fail; - } + hs_ncm_in_desc.bEndpointAddress = fs_ncm_in_desc.bEndpointAddress; + hs_ncm_out_desc.bEndpointAddress = fs_ncm_out_desc.bEndpointAddress; + hs_ncm_notify_desc.bEndpointAddress = + fs_ncm_notify_desc.bEndpointAddress; + status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function, + NULL); /* * NOTE: all that is done without knowing or caring about * the network link ... which is unavailable to this code @@ -1248,9 +1236,7 @@ ncm_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - if (f->descriptors) - usb_free_descriptors(f->descriptors); - + usb_free_all_descriptors(f); if (ncm->notify_req) { kfree(ncm->notify_req->buf); usb_ep_free_request(ncm->notify, ncm->notify_req); @@ -1276,9 +1262,7 @@ ncm_unbind(struct usb_configuration *c, struct usb_function *f) DBG(c->cdev, "ncm unbind\n"); - if (gadget_is_dualspeed(c->cdev->gadget)) - usb_free_descriptors(f->hs_descriptors); - usb_free_descriptors(f->descriptors); + usb_free_all_descriptors(f); kfree(ncm->notify_req->buf); usb_ep_free_request(ncm->notify, ncm->notify_req); diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c index 5f400f66aa9..d74491ad82c 100644 --- a/drivers/usb/gadget/f_obex.c +++ b/drivers/usb/gadget/f_obex.c @@ -331,23 +331,19 @@ obex_bind(struct usb_configuration *c, struct usb_function *f) obex->port.out = ep; ep->driver_data = cdev; /* claim */ - /* copy descriptors, and track endpoint copies */ - f->descriptors = usb_copy_descriptors(fs_function); - /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - obex_hs_ep_in_desc.bEndpointAddress = - obex_fs_ep_in_desc.bEndpointAddress; - obex_hs_ep_out_desc.bEndpointAddress = - obex_fs_ep_out_desc.bEndpointAddress; + obex_hs_ep_in_desc.bEndpointAddress = + obex_fs_ep_in_desc.bEndpointAddress; + obex_hs_ep_out_desc.bEndpointAddress = + obex_fs_ep_out_desc.bEndpointAddress; - /* copy descriptors, and track endpoint copies */ - f->hs_descriptors = usb_copy_descriptors(hs_function); - } + status = usb_assign_descriptors(f, fs_function, hs_function, NULL); + if (status) + goto fail; /* Avoid letting this gadget enumerate until the userspace * OBEX server is active. @@ -368,6 +364,7 @@ obex_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: + usb_free_all_descriptors(f); /* we might as well release our claims on endpoints */ if (obex->port.out) obex->port.out->driver_data = NULL; @@ -382,9 +379,7 @@ fail: static void obex_unbind(struct usb_configuration *c, struct usb_function *f) { - if (gadget_is_dualspeed(c->cdev->gadget)) - usb_free_descriptors(f->hs_descriptors); - usb_free_descriptors(f->descriptors); + usb_free_all_descriptors(f); kfree(func_to_obex(f)); } diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index a6c19a486d5..b21ab558b6c 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c @@ -515,14 +515,14 @@ int pn_bind(struct usb_configuration *c, struct usb_function *f) fp->in_ep = ep; ep->driver_data = fp; /* Claim */ - pn_hs_sink_desc.bEndpointAddress = - pn_fs_sink_desc.bEndpointAddress; - pn_hs_source_desc.bEndpointAddress = - pn_fs_source_desc.bEndpointAddress; + pn_hs_sink_desc.bEndpointAddress = pn_fs_sink_desc.bEndpointAddress; + pn_hs_source_desc.bEndpointAddress = pn_fs_source_desc.bEndpointAddress; /* Do not try to bind Phonet twice... */ - fp->function.descriptors = fs_pn_function; - fp->function.hs_descriptors = hs_pn_function; + status = usb_assign_descriptors(f, fs_pn_function, hs_pn_function, + NULL); + if (status) + goto err; /* Incoming USB requests */ status = -ENOMEM; @@ -551,7 +551,7 @@ err_req: for (i = 0; i < phonet_rxq_size && fp->out_reqv[i]; i++) usb_ep_free_request(fp->out_ep, fp->out_reqv[i]); err: - + usb_free_all_descriptors(f); if (fp->out_ep) fp->out_ep->driver_data = NULL; if (fp->in_ep) @@ -573,6 +573,7 @@ pn_unbind(struct usb_configuration *c, struct usb_function *f) if (fp->out_reqv[i]) usb_ep_free_request(fp->out_ep, fp->out_reqv[i]); + usb_free_all_descriptors(f); kfree(fp); } diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 7c27626f023..e7c25105bd8 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -722,42 +722,22 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) rndis->notify_req->context = rndis; rndis->notify_req->complete = rndis_response_complete; - /* copy descriptors, and track endpoint copies */ - f->descriptors = usb_copy_descriptors(eth_fs_function); - if (!f->descriptors) - goto fail; - /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - hs_in_desc.bEndpointAddress = - fs_in_desc.bEndpointAddress; - hs_out_desc.bEndpointAddress = - fs_out_desc.bEndpointAddress; - hs_notify_desc.bEndpointAddress = - fs_notify_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->hs_descriptors = usb_copy_descriptors(eth_hs_function); - if (!f->hs_descriptors) - goto fail; - } + hs_in_desc.bEndpointAddress = fs_in_desc.bEndpointAddress; + hs_out_desc.bEndpointAddress = fs_out_desc.bEndpointAddress; + hs_notify_desc.bEndpointAddress = fs_notify_desc.bEndpointAddress; - if (gadget_is_superspeed(c->cdev->gadget)) { - ss_in_desc.bEndpointAddress = - fs_in_desc.bEndpointAddress; - ss_out_desc.bEndpointAddress = - fs_out_desc.bEndpointAddress; - ss_notify_desc.bEndpointAddress = - fs_notify_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->ss_descriptors = usb_copy_descriptors(eth_ss_function); - if (!f->ss_descriptors) - goto fail; - } + ss_in_desc.bEndpointAddress = fs_in_desc.bEndpointAddress; + ss_out_desc.bEndpointAddress = fs_out_desc.bEndpointAddress; + ss_notify_desc.bEndpointAddress = fs_notify_desc.bEndpointAddress; + + status = usb_assign_descriptors(f, eth_fs_function, eth_hs_function, + eth_ss_function); + if (status) + goto fail; rndis->port.open = rndis_open; rndis->port.close = rndis_close; @@ -788,12 +768,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - if (gadget_is_superspeed(c->cdev->gadget) && f->ss_descriptors) - usb_free_descriptors(f->ss_descriptors); - if (gadget_is_dualspeed(c->cdev->gadget) && f->hs_descriptors) - usb_free_descriptors(f->hs_descriptors); - if (f->descriptors) - usb_free_descriptors(f->descriptors); + usb_free_all_descriptors(f); if (rndis->notify_req) { kfree(rndis->notify_req->buf); @@ -822,11 +797,7 @@ rndis_unbind(struct usb_configuration *c, struct usb_function *f) rndis_exit(); rndis_string_defs[0].id = 0; - if (gadget_is_superspeed(c->cdev->gadget)) - usb_free_descriptors(f->ss_descriptors); - if (gadget_is_dualspeed(c->cdev->gadget)) - usb_free_descriptors(f->hs_descriptors); - usb_free_descriptors(f->descriptors); + usb_free_all_descriptors(f); kfree(rndis->notify_req->buf); usb_ep_free_request(rndis->notify, rndis->notify_req); diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c index 07197d63d9b..98fa7795df5 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/f_serial.c @@ -213,34 +213,20 @@ gser_bind(struct usb_configuration *c, struct usb_function *f) gser->port.out = ep; ep->driver_data = cdev; /* claim */ - /* copy descriptors, and track endpoint copies */ - f->descriptors = usb_copy_descriptors(gser_fs_function); - /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - gser_hs_in_desc.bEndpointAddress = - gser_fs_in_desc.bEndpointAddress; - gser_hs_out_desc.bEndpointAddress = - gser_fs_out_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->hs_descriptors = usb_copy_descriptors(gser_hs_function); - } - if (gadget_is_superspeed(c->cdev->gadget)) { - gser_ss_in_desc.bEndpointAddress = - gser_fs_in_desc.bEndpointAddress; - gser_ss_out_desc.bEndpointAddress = - gser_fs_out_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->ss_descriptors = usb_copy_descriptors(gser_ss_function); - if (!f->ss_descriptors) - goto fail; - } + gser_hs_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress; + gser_hs_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress; + gser_ss_in_desc.bEndpointAddress = gser_fs_in_desc.bEndpointAddress; + gser_ss_out_desc.bEndpointAddress = gser_fs_out_desc.bEndpointAddress; + + status = usb_assign_descriptors(f, gser_fs_function, gser_hs_function, + gser_ss_function); + if (status) + goto fail; DBG(cdev, "generic ttyGS%d: %s speed IN/%s OUT/%s\n", gser->port_num, gadget_is_superspeed(c->cdev->gadget) ? "super" : @@ -263,11 +249,7 @@ fail: static void gser_unbind(struct usb_configuration *c, struct usb_function *f) { - if (gadget_is_dualspeed(c->cdev->gadget)) - usb_free_descriptors(f->hs_descriptors); - if (gadget_is_superspeed(c->cdev->gadget)) - usb_free_descriptors(f->ss_descriptors); - usb_free_descriptors(f->descriptors); + usb_free_all_descriptors(f); kfree(func_to_gser(f)); } diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index 3c126fde6e7..102d49beb9d 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c @@ -319,6 +319,7 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f) struct usb_composite_dev *cdev = c->cdev; struct f_sourcesink *ss = func_to_ss(f); int id; + int ret; /* allocate interface ID(s) */ id = usb_interface_id(c, f); @@ -387,64 +388,57 @@ no_iso: isoc_maxpacket = 1024; /* support high speed hardware */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - hs_source_desc.bEndpointAddress = - fs_source_desc.bEndpointAddress; - hs_sink_desc.bEndpointAddress = - fs_sink_desc.bEndpointAddress; + hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; + hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; - /* - * Fill in the HS isoc descriptors from the module parameters. - * We assume that the user knows what they are doing and won't - * give parameters that their UDC doesn't support. - */ - hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket; - hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11; - hs_iso_source_desc.bInterval = isoc_interval; - hs_iso_source_desc.bEndpointAddress = - fs_iso_source_desc.bEndpointAddress; - - hs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket; - hs_iso_sink_desc.wMaxPacketSize |= isoc_mult << 11; - hs_iso_sink_desc.bInterval = isoc_interval; - hs_iso_sink_desc.bEndpointAddress = - fs_iso_sink_desc.bEndpointAddress; - - f->hs_descriptors = hs_source_sink_descs; - } + /* + * Fill in the HS isoc descriptors from the module parameters. + * We assume that the user knows what they are doing and won't + * give parameters that their UDC doesn't support. + */ + hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket; + hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11; + hs_iso_source_desc.bInterval = isoc_interval; + hs_iso_source_desc.bEndpointAddress = + fs_iso_source_desc.bEndpointAddress; + + hs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket; + hs_iso_sink_desc.wMaxPacketSize |= isoc_mult << 11; + hs_iso_sink_desc.bInterval = isoc_interval; + hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress; /* support super speed hardware */ - if (gadget_is_superspeed(c->cdev->gadget)) { - ss_source_desc.bEndpointAddress = - fs_source_desc.bEndpointAddress; - ss_sink_desc.bEndpointAddress = - fs_sink_desc.bEndpointAddress; + ss_source_desc.bEndpointAddress = + fs_source_desc.bEndpointAddress; + ss_sink_desc.bEndpointAddress = + fs_sink_desc.bEndpointAddress; - /* - * Fill in the SS isoc descriptors from the module parameters. - * We assume that the user knows what they are doing and won't - * give parameters that their UDC doesn't support. - */ - ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket; - ss_iso_source_desc.bInterval = isoc_interval; - ss_iso_source_comp_desc.bmAttributes = isoc_mult; - ss_iso_source_comp_desc.bMaxBurst = isoc_maxburst; - ss_iso_source_comp_desc.wBytesPerInterval = - isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1); - ss_iso_source_desc.bEndpointAddress = - fs_iso_source_desc.bEndpointAddress; - - ss_iso_sink_desc.wMaxPacketSize = isoc_maxpacket; - ss_iso_sink_desc.bInterval = isoc_interval; - ss_iso_sink_comp_desc.bmAttributes = isoc_mult; - ss_iso_sink_comp_desc.bMaxBurst = isoc_maxburst; - ss_iso_sink_comp_desc.wBytesPerInterval = - isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1); - ss_iso_sink_desc.bEndpointAddress = - fs_iso_sink_desc.bEndpointAddress; - - f->ss_descriptors = ss_source_sink_descs; - } + /* + * Fill in the SS isoc descriptors from the module parameters. + * We assume that the user knows what they are doing and won't + * give parameters that their UDC doesn't support. + */ + ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket; + ss_iso_source_desc.bInterval = isoc_interval; + ss_iso_source_comp_desc.bmAttributes = isoc_mult; + ss_iso_source_comp_desc.bMaxBurst = isoc_maxburst; + ss_iso_source_comp_desc.wBytesPerInterval = + isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1); + ss_iso_source_desc.bEndpointAddress = + fs_iso_source_desc.bEndpointAddress; + + ss_iso_sink_desc.wMaxPacketSize = isoc_maxpacket; + ss_iso_sink_desc.bInterval = isoc_interval; + ss_iso_sink_comp_desc.bmAttributes = isoc_mult; + ss_iso_sink_comp_desc.bMaxBurst = isoc_maxburst; + ss_iso_sink_comp_desc.wBytesPerInterval = + isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1); + ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress; + + ret = usb_assign_descriptors(f, fs_source_sink_descs, + hs_source_sink_descs, ss_source_sink_descs); + if (ret) + return ret; DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n", (gadget_is_superspeed(c->cdev->gadget) ? "super" : @@ -458,6 +452,7 @@ no_iso: static void sourcesink_unbind(struct usb_configuration *c, struct usb_function *f) { + usb_free_all_descriptors(f); kfree(func_to_ss(f)); } @@ -773,7 +768,6 @@ static int __init sourcesink_bind_config(struct usb_configuration *c) return -ENOMEM; ss->function.name = "source/sink"; - ss->function.descriptors = fs_source_sink_descs; ss->function.bind = sourcesink_bind; ss->function.unbind = sourcesink_unbind; ss->function.set_alt = sourcesink_set_alt; diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index deb437c3b53..856dbae586f 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c @@ -319,38 +319,22 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) geth->port.out_ep = ep; ep->driver_data = cdev; /* claim */ - /* copy descriptors, and track endpoint copies */ - f->descriptors = usb_copy_descriptors(fs_eth_function); - if (!f->descriptors) - goto fail; - /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at * both speeds */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - hs_subset_in_desc.bEndpointAddress = - fs_subset_in_desc.bEndpointAddress; - hs_subset_out_desc.bEndpointAddress = - fs_subset_out_desc.bEndpointAddress; - - /* copy descriptors, and track endpoint copies */ - f->hs_descriptors = usb_copy_descriptors(hs_eth_function); - if (!f->hs_descriptors) - goto fail; - } + hs_subset_in_desc.bEndpointAddress = fs_subset_in_desc.bEndpointAddress; + hs_subset_out_desc.bEndpointAddress = + fs_subset_out_desc.bEndpointAddress; - if (gadget_is_superspeed(c->cdev->gadget)) { - ss_subset_in_desc.bEndpointAddress = - fs_subset_in_desc.bEndpointAddress; - ss_subset_out_desc.bEndpointAddress = - fs_subset_out_desc.bEndpointAddress; + ss_subset_in_desc.bEndpointAddress = fs_subset_in_desc.bEndpointAddress; + ss_subset_out_desc.bEndpointAddress = + fs_subset_out_desc.bEndpointAddress; - /* copy descriptors, and track endpoint copies */ - f->ss_descriptors = usb_copy_descriptors(ss_eth_function); - if (!f->ss_descriptors) - goto fail; - } + status = usb_assign_descriptors(f, fs_eth_function, hs_eth_function, + ss_eth_function); + if (status) + goto fail; /* NOTE: all that is done without knowing or caring about * the network link ... which is unavailable to this code @@ -364,11 +348,7 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - if (f->descriptors) - usb_free_descriptors(f->descriptors); - if (f->hs_descriptors) - usb_free_descriptors(f->hs_descriptors); - + usb_free_all_descriptors(f); /* we might as well release our claims on endpoints */ if (geth->port.out_ep) geth->port.out_ep->driver_data = NULL; @@ -383,11 +363,7 @@ fail: static void geth_unbind(struct usb_configuration *c, struct usb_function *f) { - if (gadget_is_superspeed(c->cdev->gadget)) - usb_free_descriptors(f->ss_descriptors); - if (gadget_is_dualspeed(c->cdev->gadget)) - usb_free_descriptors(f->hs_descriptors); - usb_free_descriptors(f->descriptors); + usb_free_all_descriptors(f); geth_string_defs[1].s = NULL; kfree(func_to_geth(f)); } diff --git a/drivers/usb/gadget/f_uac1.c b/drivers/usb/gadget/f_uac1.c index c8ed41ba104..f570e667a64 100644 --- a/drivers/usb/gadget/f_uac1.c +++ b/drivers/usb/gadget/f_uac1.c @@ -630,7 +630,7 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) struct usb_composite_dev *cdev = c->cdev; struct f_audio *audio = func_to_audio(f); int status; - struct usb_ep *ep; + struct usb_ep *ep = NULL; f_audio_build_desc(audio); @@ -659,21 +659,14 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) status = -ENOMEM; /* copy descriptors, and track endpoint copies */ - f->descriptors = usb_copy_descriptors(f_audio_desc); - - /* - * support all relevant hardware speeds... we expect that when - * hardware is dual speed, all bulk-capable endpoints work at - * both speeds - */ - if (gadget_is_dualspeed(c->cdev->gadget)) { - f->hs_descriptors = usb_copy_descriptors(f_audio_desc); - } - + status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL); + if (status) + goto fail; return 0; fail: - + if (ep) + ep->driver_data = NULL; return status; } @@ -682,8 +675,7 @@ f_audio_unbind(struct usb_configuration *c, struct usb_function *f) { struct f_audio *audio = func_to_audio(f); - usb_free_descriptors(f->descriptors); - usb_free_descriptors(f->hs_descriptors); + usb_free_all_descriptors(f); kfree(audio); } diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index f02b8ece528..730a260e184 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c @@ -998,9 +998,9 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress; hs_epin_desc.wMaxPacketSize = fs_epin_desc.wMaxPacketSize; - fn->descriptors = usb_copy_descriptors(fs_audio_desc); - if (gadget_is_dualspeed(gadget)) - fn->hs_descriptors = usb_copy_descriptors(hs_audio_desc); + ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL); + if (ret) + goto err; prm = &agdev->uac2.c_prm; prm->max_psize = hs_epout_desc.wMaxPacketSize; @@ -1029,8 +1029,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) err: kfree(agdev->uac2.p_prm.rbuf); kfree(agdev->uac2.c_prm.rbuf); - usb_free_descriptors(fn->hs_descriptors); - usb_free_descriptors(fn->descriptors); + usb_free_all_descriptors(fn); if (agdev->in_ep) agdev->in_ep->driver_data = NULL; if (agdev->out_ep) @@ -1042,8 +1041,6 @@ static void afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn) { struct audio_dev *agdev = func_to_agdev(fn); - struct usb_composite_dev *cdev = cfg->cdev; - struct usb_gadget *gadget = cdev->gadget; struct uac2_rtd_params *prm; alsa_uac2_exit(agdev); @@ -1053,10 +1050,7 @@ afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn) prm = &agdev->uac2.c_prm; kfree(prm->rbuf); - - if (gadget_is_dualspeed(gadget)) - usb_free_descriptors(fn->hs_descriptors); - usb_free_descriptors(fn->descriptors); + usb_free_all_descriptors(fn); if (agdev->in_ep) agdev->in_ep->driver_data = NULL; diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 10f13c1213c..28ff2546a5b 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -583,9 +583,7 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f) usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); kfree(uvc->control_buf); - kfree(f->descriptors); - kfree(f->hs_descriptors); - kfree(f->ss_descriptors); + usb_free_all_descriptors(f); kfree(uvc); } @@ -651,49 +649,40 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) /* sanity check the streaming endpoint module parameters */ if (streaming_maxpacket > 1024) streaming_maxpacket = 1024; + /* + * Fill in the HS descriptors from the module parameters for the Video + * Streaming endpoint. + * NOTE: We assume that the user knows what they are doing and won't + * give parameters that their UDC doesn't support. + */ + uvc_hs_streaming_ep.wMaxPacketSize = streaming_maxpacket; + uvc_hs_streaming_ep.wMaxPacketSize |= streaming_mult << 11; + uvc_hs_streaming_ep.bInterval = streaming_interval; + uvc_hs_streaming_ep.bEndpointAddress = + uvc_fs_streaming_ep.bEndpointAddress; - /* Copy descriptors for FS. */ - f->descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); - - /* support high speed hardware */ - if (gadget_is_dualspeed(cdev->gadget)) { - /* - * Fill in the HS descriptors from the module parameters for the - * Video Streaming endpoint. - * NOTE: We assume that the user knows what they are doing and - * won't give parameters that their UDC doesn't support. - */ - uvc_hs_streaming_ep.wMaxPacketSize = streaming_maxpacket; - uvc_hs_streaming_ep.wMaxPacketSize |= streaming_mult << 11; - uvc_hs_streaming_ep.bInterval = streaming_interval; - uvc_hs_streaming_ep.bEndpointAddress = - uvc_fs_streaming_ep.bEndpointAddress; - - /* Copy descriptors. */ - f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH); - } + /* + * Fill in the SS descriptors from the module parameters for the Video + * Streaming endpoint. + * NOTE: We assume that the user knows what they are doing and won't + * give parameters that their UDC doesn't support. + */ + uvc_ss_streaming_ep.wMaxPacketSize = streaming_maxpacket; + uvc_ss_streaming_ep.bInterval = streaming_interval; + uvc_ss_streaming_comp.bmAttributes = streaming_mult; + uvc_ss_streaming_comp.bMaxBurst = streaming_maxburst; + uvc_ss_streaming_comp.wBytesPerInterval = + streaming_maxpacket * (streaming_mult + 1) * + (streaming_maxburst + 1); + uvc_ss_streaming_ep.bEndpointAddress = + uvc_fs_streaming_ep.bEndpointAddress; - /* support super speed hardware */ - if (gadget_is_superspeed(c->cdev->gadget)) { - /* - * Fill in the SS descriptors from the module parameters for the - * Video Streaming endpoint. - * NOTE: We assume that the user knows what they are doing and - * won't give parameters that their UDC doesn't support. - */ - uvc_ss_streaming_ep.wMaxPacketSize = streaming_maxpacket; - uvc_ss_streaming_ep.bInterval = streaming_interval; - uvc_ss_streaming_comp.bmAttributes = streaming_mult; - uvc_ss_streaming_comp.bMaxBurst = streaming_maxburst; - uvc_ss_streaming_comp.wBytesPerInterval = - streaming_maxpacket * (streaming_mult + 1) * - (streaming_maxburst + 1); - uvc_ss_streaming_ep.bEndpointAddress = - uvc_fs_streaming_ep.bEndpointAddress; - - /* Copy descriptors. */ + /* Copy descriptors */ + f->fs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); + if (gadget_is_dualspeed(cdev->gadget)) + f->hs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_HIGH); + if (gadget_is_superspeed(c->cdev->gadget)) f->ss_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_SUPER); - } /* Preallocate control endpoint request. */ uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL); @@ -741,9 +730,7 @@ error: kfree(uvc->control_buf); } - kfree(f->descriptors); - kfree(f->hs_descriptors); - kfree(f->ss_descriptors); + usb_free_all_descriptors(f); return ret; } diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index e156e3f2672..35bcc83d1e0 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -983,8 +983,10 @@ static int __init printer_func_bind(struct usb_configuration *c, { struct printer_dev *dev = container_of(f, struct printer_dev, function); struct usb_composite_dev *cdev = c->cdev; - struct usb_ep *in_ep, *out_ep; + struct usb_ep *in_ep; + struct usb_ep *out_ep = NULL; int id; + int ret; id = usb_interface_id(c, f); if (id < 0) @@ -1010,6 +1012,11 @@ autoconf_fail: hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; + ret = usb_assign_descriptors(f, fs_printer_function, + hs_printer_function, NULL); + if (ret) + return ret; + dev->in_ep = in_ep; dev->out_ep = out_ep; return 0; @@ -1018,6 +1025,7 @@ autoconf_fail: static void printer_func_unbind(struct usb_configuration *c, struct usb_function *f) { + usb_free_all_descriptors(f); } static int printer_func_set_alt(struct usb_function *f, @@ -1110,8 +1118,6 @@ static int __init printer_bind_config(struct usb_configuration *c) dev = &usb_printer_gadget; dev->function.name = shortname; - dev->function.descriptors = fs_printer_function; - dev->function.hs_descriptors = hs_printer_function; dev->function.bind = printer_func_bind; dev->function.setup = printer_func_setup; dev->function.unbind = printer_func_unbind; diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 49596096b43..27a2337f986 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -2240,6 +2240,7 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f) struct usb_gadget *gadget = c->cdev->gadget; struct usb_ep *ep; int iface; + int ret; iface = usb_interface_id(c, f); if (iface < 0) @@ -2290,6 +2291,11 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f) uasp_ss_status_desc.bEndpointAddress; uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress; + ret = usb_assign_descriptors(f, uasp_fs_function_desc, + uasp_hs_function_desc, uasp_ss_function_desc); + if (ret) + goto ep_fail; + return 0; ep_fail: pr_err("Can't claim all required eps\n"); @@ -2305,6 +2311,7 @@ static void usbg_unbind(struct usb_configuration *c, struct usb_function *f) { struct f_uas *fu = to_f_uas(f); + usb_free_all_descriptors(f); kfree(fu); } @@ -2385,9 +2392,6 @@ static int usbg_cfg_bind(struct usb_configuration *c) if (!fu) return -ENOMEM; fu->function.name = "Target Function"; - fu->function.descriptors = uasp_fs_function_desc; - fu->function.hs_descriptors = uasp_hs_function_desc; - fu->function.ss_descriptors = uasp_ss_function_desc; fu->function.bind = usbg_bind; fu->function.unbind = usbg_unbind; fu->function.set_alt = usbg_set_alt; diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 8634a127bdd..b09c37e04a9 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -119,7 +119,7 @@ struct usb_configuration; struct usb_function { const char *name; struct usb_gadget_strings **strings; - struct usb_descriptor_header **descriptors; + struct usb_descriptor_header **fs_descriptors; struct usb_descriptor_header **hs_descriptors; struct usb_descriptor_header **ss_descriptors; diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 5b6e5088824..0af6569b8cc 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -939,6 +939,13 @@ static inline void usb_free_descriptors(struct usb_descriptor_header **v) kfree(v); } +struct usb_function; +int usb_assign_descriptors(struct usb_function *f, + struct usb_descriptor_header **fs, + struct usb_descriptor_header **hs, + struct usb_descriptor_header **ss); +void usb_free_all_descriptors(struct usb_function *f); + /*-------------------------------------------------------------------------*/ /* utility to simplify map/unmap of usb_requests to/from DMA */ -- cgit v1.2.3 From b7c041aadad561a84d17851f69414060f8389ce1 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:15:07 +0200 Subject: usb: gadget: remove DMA_ADDR_INVALID from f_uac2 and gadgetfs DMA_ADDR_INVALID is used by the UDC driver and the gadgets should provide only a buffer address. Everything else should be taken core of by the UDC and udc-core. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uac2.c | 3 --- drivers/usb/gadget/inode.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index 730a260e184..86f8ac79142 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c @@ -50,8 +50,6 @@ static int c_ssize = 2; module_param(c_ssize, uint, S_IRUGO); MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); -#define DMA_ADDR_INVALID (~(dma_addr_t)0) - #define ALT_SET(x, a) do {(x) &= ~0xff; (x) |= (a); } while (0) #define ALT_GET(x) ((x) & 0xff) #define INTF_SET(x, i) do {(x) &= 0xff; (x) |= ((i) << 8); } while (0) @@ -1130,7 +1128,6 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt) prm->ureq[i].pp = prm; req->zero = 0; - req->dma = DMA_ADDR_INVALID; req->context = &prm->ureq[i]; req->length = prm->max_psize; req->complete = agdev_iso_complete; diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 76494cabf4e..8ac840f25ba 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -76,7 +76,6 @@ MODULE_LICENSE ("GPL"); /*----------------------------------------------------------------------*/ #define GADGETFS_MAGIC 0xaee71ee7 -#define DMA_ADDR_INVALID (~(dma_addr_t)0) /* /dev/gadget/$CHIP represents ep0 and the whole device */ enum ep0_state { @@ -918,7 +917,6 @@ static void clean_req (struct usb_ep *ep, struct usb_request *req) if (req->buf != dev->rbuf) { kfree(req->buf); req->buf = dev->rbuf; - req->dma = DMA_ADDR_INVALID; } req->complete = epio_complete; dev->setup_out_ready = 0; @@ -1408,7 +1406,6 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) dev->setup_abort = 1; req->buf = dev->rbuf; - req->dma = DMA_ADDR_INVALID; req->context = NULL; value = -EOPNOTSUPP; switch (ctrl->bRequest) { -- cgit v1.2.3 From 4ce63571d6a34e151f1525d2dcb5559293d8ad54 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:15:08 +0200 Subject: usb: gadget: uac2: provide a variable for interface and alt settings This patch removes the shifting and masking of interface and its alt setting and provides its own variable. This looks better and is smaller: text data bss dec hex filename x86-32 6940 956 56 7952 1f10 gadget/audio.o.old 6908 956 56 7920 1ef0 gadget/audio.o.new arm 7914 956 56 8926 22de gadget/audio.o.old 7886 956 56 8898 22c2 gadget/audio.o.new Acked-by: Jassi Brar Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uac2.c | 50 +++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index 86f8ac79142..503dd978259 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c @@ -50,11 +50,6 @@ static int c_ssize = 2; module_param(c_ssize, uint, S_IRUGO); MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); -#define ALT_SET(x, a) do {(x) &= ~0xff; (x) |= (a); } while (0) -#define ALT_GET(x) ((x) & 0xff) -#define INTF_SET(x, i) do {(x) &= 0xff; (x) |= ((i) << 8); } while (0) -#define INTF_GET(x) ((x >> 8) & 0xff) - /* Keep everyone on toes */ #define USB_XFERS 2 @@ -142,8 +137,9 @@ static struct snd_pcm_hardware uac2_pcm_hardware = { }; struct audio_dev { - /* Currently active {Interface[15:8] | AltSettings[7:0]} */ - __u16 ac_alt, as_out_alt, as_in_alt; + u8 ac_intf, ac_alt; + u8 as_out_intf, as_out_alt; + u8 as_in_intf, as_in_alt; struct usb_ep *in_ep, *out_ep; struct usb_function func; @@ -950,8 +946,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) return ret; } std_ac_if_desc.bInterfaceNumber = ret; - ALT_SET(agdev->ac_alt, 0); - INTF_SET(agdev->ac_alt, ret); + agdev->ac_intf = ret; + agdev->ac_alt = 0; ret = usb_interface_id(cfg, fn); if (ret < 0) { @@ -961,8 +957,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) } std_as_out_if0_desc.bInterfaceNumber = ret; std_as_out_if1_desc.bInterfaceNumber = ret; - ALT_SET(agdev->as_out_alt, 0); - INTF_SET(agdev->as_out_alt, ret); + agdev->as_out_intf = ret; + agdev->as_out_alt = 0; ret = usb_interface_id(cfg, fn); if (ret < 0) { @@ -972,8 +968,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) } std_as_in_if0_desc.bInterfaceNumber = ret; std_as_in_if1_desc.bInterfaceNumber = ret; - ALT_SET(agdev->as_in_alt, 0); - INTF_SET(agdev->as_in_alt, ret); + agdev->as_in_intf = ret; + agdev->as_in_alt = 0; agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); if (!agdev->out_ep) { @@ -1075,7 +1071,7 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt) return -EINVAL; } - if (intf == INTF_GET(agdev->ac_alt)) { + if (intf == agdev->ac_intf) { /* Control I/f has only 1 AltSetting - 0 */ if (alt) { dev_err(&uac2->pdev.dev, @@ -1085,16 +1081,16 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt) return 0; } - if (intf == INTF_GET(agdev->as_out_alt)) { + if (intf == agdev->as_out_intf) { ep = agdev->out_ep; prm = &uac2->c_prm; config_ep_by_speed(gadget, fn, ep); - ALT_SET(agdev->as_out_alt, alt); - } else if (intf == INTF_GET(agdev->as_in_alt)) { + agdev->as_out_alt = alt; + } else if (intf == agdev->as_in_intf) { ep = agdev->in_ep; prm = &uac2->p_prm; config_ep_by_speed(gadget, fn, ep); - ALT_SET(agdev->as_in_alt, alt); + agdev->as_in_alt = alt; } else { dev_err(&uac2->pdev.dev, "%s:%d Error!\n", __func__, __LINE__); @@ -1146,12 +1142,12 @@ afunc_get_alt(struct usb_function *fn, unsigned intf) struct audio_dev *agdev = func_to_agdev(fn); struct snd_uac2_chip *uac2 = &agdev->uac2; - if (intf == INTF_GET(agdev->ac_alt)) - return ALT_GET(agdev->ac_alt); - else if (intf == INTF_GET(agdev->as_out_alt)) - return ALT_GET(agdev->as_out_alt); - else if (intf == INTF_GET(agdev->as_in_alt)) - return ALT_GET(agdev->as_in_alt); + if (intf == agdev->ac_intf) + return agdev->ac_alt; + else if (intf == agdev->as_out_intf) + return agdev->as_out_alt; + else if (intf == agdev->as_in_intf) + return agdev->as_in_alt; else dev_err(&uac2->pdev.dev, "%s:%d Invalid Interface %d!\n", @@ -1167,10 +1163,10 @@ afunc_disable(struct usb_function *fn) struct snd_uac2_chip *uac2 = &agdev->uac2; free_ep(&uac2->p_prm, agdev->in_ep); - ALT_SET(agdev->as_in_alt, 0); + agdev->as_in_alt = 0; free_ep(&uac2->c_prm, agdev->out_ep); - ALT_SET(agdev->as_out_alt, 0); + agdev->as_out_alt = 0; } static int @@ -1277,7 +1273,7 @@ setup_rq_inf(struct usb_function *fn, const struct usb_ctrlrequest *cr) u16 w_index = le16_to_cpu(cr->wIndex); u8 intf = w_index & 0xff; - if (intf != INTF_GET(agdev->ac_alt)) { + if (intf != agdev->ac_intf) { dev_err(&uac2->pdev.dev, "%s:%d Error!\n", __func__, __LINE__); return -EOPNOTSUPP; -- cgit v1.2.3 From b36c347966160ecfe420cd47a5a1f81ddaffc007 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:15:09 +0200 Subject: usb: gadget: uac2: use the strings directly There is no need for this variable in between. Acked-by: Jassi Brar Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uac2.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index 503dd978259..2840f181906 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c @@ -520,32 +520,22 @@ enum { STR_AS_IN_ALT1, }; -static const char ifassoc[] = "Source/Sink"; -static const char ifctrl[] = "Topology Control"; static char clksrc_in[8]; static char clksrc_out[8]; -static const char usb_it[] = "USBH Out"; -static const char io_it[] = "USBD Out"; -static const char usb_ot[] = "USBH In"; -static const char io_ot[] = "USBD In"; -static const char out_alt0[] = "Playback Inactive"; -static const char out_alt1[] = "Playback Active"; -static const char in_alt0[] = "Capture Inactive"; -static const char in_alt1[] = "Capture Active"; static struct usb_string strings_fn[] = { - [STR_ASSOC].s = ifassoc, - [STR_IF_CTRL].s = ifctrl, + [STR_ASSOC].s = "Source/Sink", + [STR_IF_CTRL].s = "Topology Control", [STR_CLKSRC_IN].s = clksrc_in, [STR_CLKSRC_OUT].s = clksrc_out, - [STR_USB_IT].s = usb_it, - [STR_IO_IT].s = io_it, - [STR_USB_OT].s = usb_ot, - [STR_IO_OT].s = io_ot, - [STR_AS_OUT_ALT0].s = out_alt0, - [STR_AS_OUT_ALT1].s = out_alt1, - [STR_AS_IN_ALT0].s = in_alt0, - [STR_AS_IN_ALT1].s = in_alt1, + [STR_USB_IT].s = "USBH Out", + [STR_IO_IT].s = "USBD Out", + [STR_USB_OT].s = "USBH In", + [STR_IO_OT].s = "USBD In", + [STR_AS_OUT_ALT0].s = "Playback Inactive", + [STR_AS_OUT_ALT1].s = "Playback Active", + [STR_AS_IN_ALT0].s = "Capture Inactive", + [STR_AS_IN_ALT1].s = "Capture Active", { }, }; -- cgit v1.2.3 From 1616e99d42a8b427b8dcada347ef0ee0df1a1b7b Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 22 Oct 2012 22:15:10 +0200 Subject: usb: gadget: let f_* use usb_string_ids_tab() where it makes sense Instead of calling usb_string_id() multiple times I replace it with one usb_string_ids_tab(). The NULL pointer in struct usb_string with "" and are not overwritten in fail or unbind case. The conditional assignment remains because some gadgets recycle the string ID because the same descriptor (and string ID) is used if we have more than one config descriptor. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_acm.c | 27 ++++-------- drivers/usb/gadget/f_ecm.c | 42 ++++-------------- drivers/usb/gadget/f_ncm.c | 40 +++++------------ drivers/usb/gadget/f_obex.c | 19 +++----- drivers/usb/gadget/f_rndis.c | 27 +++--------- drivers/usb/gadget/f_subset.c | 23 +++------- drivers/usb/gadget/f_uac2.c | 100 +++++++----------------------------------- drivers/usb/gadget/f_uvc.c | 26 ++++------- 8 files changed, 71 insertions(+), 233 deletions(-) diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 308242b5d6e..549174466c2 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -705,6 +705,7 @@ acm_unbind(struct usb_configuration *c, struct usb_function *f) { struct f_acm *acm = func_to_acm(f); + acm_string_defs[0].id = 0; usb_free_all_descriptors(f); gs_free_req(acm->notify, acm->notify_req); kfree(acm); @@ -742,27 +743,15 @@ int acm_bind_config(struct usb_configuration *c, u8 port_num) */ /* maybe allocate device-global string IDs, and patch descriptors */ - if (acm_string_defs[ACM_CTRL_IDX].id == 0) { - status = usb_string_id(c->cdev); + if (acm_string_defs[0].id == 0) { + status = usb_string_ids_tab(c->cdev, acm_string_defs); if (status < 0) return status; - acm_string_defs[ACM_CTRL_IDX].id = status; - - acm_control_interface_desc.iInterface = status; - - status = usb_string_id(c->cdev); - if (status < 0) - return status; - acm_string_defs[ACM_DATA_IDX].id = status; - - acm_data_interface_desc.iInterface = status; - - status = usb_string_id(c->cdev); - if (status < 0) - return status; - acm_string_defs[ACM_IAD_IDX].id = status; - - acm_iad_descriptor.iFunction = status; + acm_control_interface_desc.iInterface = + acm_string_defs[ACM_CTRL_IDX].id; + acm_data_interface_desc.iInterface = + acm_string_defs[ACM_DATA_IDX].id; + acm_iad_descriptor.iFunction = acm_string_defs[ACM_IAD_IDX].id; } /* allocate and initialize one new instance */ diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 2d3c5a46de8..83420a310fb 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -354,7 +354,7 @@ static struct usb_descriptor_header *ecm_ss_function[] = { static struct usb_string ecm_string_defs[] = { [0].s = "CDC Ethernet Control Model (ECM)", - [1].s = NULL /* DYNAMIC */, + [1].s = "", [2].s = "CDC Ethernet Data", [3].s = "CDC ECM", { } /* end of list */ @@ -803,12 +803,11 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f) DBG(c->cdev, "ecm unbind\n"); + ecm_string_defs[0].id = 0; usb_free_all_descriptors(f); kfree(ecm->notify_req->buf); usb_ep_free_request(ecm->notify, ecm->notify_req); - - ecm_string_defs[1].s = NULL; kfree(ecm); } @@ -833,36 +832,15 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) if (!can_support_ecm(c->cdev->gadget) || !ethaddr) return -EINVAL; - /* maybe allocate device-global string IDs */ if (ecm_string_defs[0].id == 0) { - - /* control interface label */ - status = usb_string_id(c->cdev); - if (status < 0) + status = usb_string_ids_tab(c->cdev, ecm_string_defs); + if (status) return status; - ecm_string_defs[0].id = status; - ecm_control_intf.iInterface = status; - /* data interface label */ - status = usb_string_id(c->cdev); - if (status < 0) - return status; - ecm_string_defs[2].id = status; - ecm_data_intf.iInterface = status; - - /* MAC address */ - status = usb_string_id(c->cdev); - if (status < 0) - return status; - ecm_string_defs[1].id = status; - ecm_desc.iMACAddress = status; - - /* IAD label */ - status = usb_string_id(c->cdev); - if (status < 0) - return status; - ecm_string_defs[3].id = status; - ecm_iad_descriptor.iFunction = status; + ecm_control_intf.iInterface = ecm_string_defs[0].id; + ecm_data_intf.iInterface = ecm_string_defs[2].id; + ecm_desc.iMACAddress = ecm_string_defs[1].id; + ecm_iad_descriptor.iFunction = ecm_string_defs[3].id; } /* allocate and initialize one new instance */ @@ -887,9 +865,7 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) ecm->port.func.disable = ecm_disable; status = usb_add_function(c, &ecm->port.func); - if (status) { - ecm_string_defs[1].s = NULL; + if (status) kfree(ecm); - } return status; } diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c index 326d7e6c297..f1f66e9c76b 100644 --- a/drivers/usb/gadget/f_ncm.c +++ b/drivers/usb/gadget/f_ncm.c @@ -321,7 +321,7 @@ static struct usb_descriptor_header *ncm_hs_function[] __initdata = { static struct usb_string ncm_string_defs[] = { [STRING_CTRL_IDX].s = "CDC Network Control Model (NCM)", - [STRING_MAC_IDX].s = NULL /* DYNAMIC */, + [STRING_MAC_IDX].s = "", [STRING_DATA_IDX].s = "CDC Network Data", [STRING_IAD_IDX].s = "CDC NCM", { } /* end of list */ @@ -1262,12 +1262,12 @@ ncm_unbind(struct usb_configuration *c, struct usb_function *f) DBG(c->cdev, "ncm unbind\n"); + ncm_string_defs[0].id = 0; usb_free_all_descriptors(f); kfree(ncm->notify_req->buf); usb_ep_free_request(ncm->notify, ncm->notify_req); - ncm_string_defs[1].s = NULL; kfree(ncm); } @@ -1291,37 +1291,19 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) if (!can_support_ecm(c->cdev->gadget) || !ethaddr) return -EINVAL; - /* maybe allocate device-global string IDs */ if (ncm_string_defs[0].id == 0) { - - /* control interface label */ - status = usb_string_id(c->cdev); + status = usb_string_ids_tab(c->cdev, ncm_string_defs); if (status < 0) return status; - ncm_string_defs[STRING_CTRL_IDX].id = status; - ncm_control_intf.iInterface = status; + ncm_control_intf.iInterface = + ncm_string_defs[STRING_CTRL_IDX].id; - /* data interface label */ - status = usb_string_id(c->cdev); - if (status < 0) - return status; - ncm_string_defs[STRING_DATA_IDX].id = status; + status = ncm_string_defs[STRING_DATA_IDX].id; ncm_data_nop_intf.iInterface = status; ncm_data_intf.iInterface = status; - /* MAC address */ - status = usb_string_id(c->cdev); - if (status < 0) - return status; - ncm_string_defs[STRING_MAC_IDX].id = status; - ecm_desc.iMACAddress = status; - - /* IAD */ - status = usb_string_id(c->cdev); - if (status < 0) - return status; - ncm_string_defs[STRING_IAD_IDX].id = status; - ncm_iad_desc.iFunction = status; + ecm_desc.iMACAddress = ncm_string_defs[STRING_MAC_IDX].id; + ncm_iad_desc.iFunction = ncm_string_defs[STRING_IAD_IDX].id; } /* allocate and initialize one new instance */ @@ -1331,7 +1313,7 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) /* export host's Ethernet address in CDC format */ snprintf(ncm->ethaddr, sizeof ncm->ethaddr, "%pm", ethaddr); - ncm_string_defs[1].s = ncm->ethaddr; + ncm_string_defs[STRING_MAC_IDX].s = ncm->ethaddr; spin_lock_init(&ncm->lock); ncm_reset_values(ncm); @@ -1351,9 +1333,7 @@ int __init ncm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) ncm->port.unwrap = ncm_unwrap_ntb; status = usb_add_function(c, &ncm->port.func); - if (status) { - ncm_string_defs[1].s = NULL; + if (status) kfree(ncm); - } return status; } diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c index d74491ad82c..d8dd8782768 100644 --- a/drivers/usb/gadget/f_obex.c +++ b/drivers/usb/gadget/f_obex.c @@ -379,6 +379,7 @@ fail: static void obex_unbind(struct usb_configuration *c, struct usb_function *f) { + obex_string_defs[OBEX_CTRL_IDX].id = 0; usb_free_all_descriptors(f); kfree(func_to_obex(f)); } @@ -418,22 +419,16 @@ int __init obex_bind_config(struct usb_configuration *c, u8 port_num) if (!can_support_obex(c)) return -EINVAL; - /* maybe allocate device-global string IDs, and patch descriptors */ if (obex_string_defs[OBEX_CTRL_IDX].id == 0) { - status = usb_string_id(c->cdev); + status = usb_string_ids_tab(c->cdev, obex_string_defs); if (status < 0) return status; - obex_string_defs[OBEX_CTRL_IDX].id = status; + obex_control_intf.iInterface = + obex_string_defs[OBEX_CTRL_IDX].id; - obex_control_intf.iInterface = status; - - status = usb_string_id(c->cdev); - if (status < 0) - return status; - obex_string_defs[OBEX_DATA_IDX].id = status; - - obex_data_nop_intf.iInterface = - obex_data_intf.iInterface = status; + status = obex_string_defs[OBEX_DATA_IDX].id; + obex_data_nop_intf.iInterface = status; + obex_data_intf.iInterface = status; } /* allocate and initialize one new instance */ diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index e7c25105bd8..71beeb83355 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -795,8 +795,8 @@ rndis_unbind(struct usb_configuration *c, struct usb_function *f) rndis_deregister(rndis->config); rndis_exit(); - rndis_string_defs[0].id = 0; + rndis_string_defs[0].id = 0; usb_free_all_descriptors(f); kfree(rndis->notify_req->buf); @@ -822,34 +822,19 @@ rndis_bind_config_vendor(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], if (!can_support_rndis(c) || !ethaddr) return -EINVAL; - /* maybe allocate device-global string IDs */ if (rndis_string_defs[0].id == 0) { - /* ... and setup RNDIS itself */ status = rndis_init(); if (status < 0) return status; - /* control interface label */ - status = usb_string_id(c->cdev); - if (status < 0) + status = usb_string_ids_tab(c->cdev, rndis_string_defs); + if (status) return status; - rndis_string_defs[0].id = status; - rndis_control_intf.iInterface = status; - /* data interface label */ - status = usb_string_id(c->cdev); - if (status < 0) - return status; - rndis_string_defs[1].id = status; - rndis_data_intf.iInterface = status; - - /* IAD iFunction label */ - status = usb_string_id(c->cdev); - if (status < 0) - return status; - rndis_string_defs[2].id = status; - rndis_iad_descriptor.iFunction = status; + rndis_control_intf.iInterface = rndis_string_defs[0].id; + rndis_data_intf.iInterface = rndis_string_defs[1].id; + rndis_iad_descriptor.iFunction = rndis_string_defs[2].id; } /* allocate and initialize one new instance */ diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index 856dbae586f..f172bd152fb 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c @@ -236,7 +236,7 @@ static struct usb_descriptor_header *ss_eth_function[] = { static struct usb_string geth_string_defs[] = { [0].s = "CDC Ethernet Subset/SAFE", - [1].s = NULL /* DYNAMIC */, + [1].s = "", { } /* end of list */ }; @@ -363,8 +363,8 @@ fail: static void geth_unbind(struct usb_configuration *c, struct usb_function *f) { + geth_string_defs[0].id = 0; usb_free_all_descriptors(f); - geth_string_defs[1].s = NULL; kfree(func_to_geth(f)); } @@ -390,20 +390,11 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) /* maybe allocate device-global string IDs */ if (geth_string_defs[0].id == 0) { - - /* interface label */ - status = usb_string_id(c->cdev); - if (status < 0) - return status; - geth_string_defs[0].id = status; - subset_data_intf.iInterface = status; - - /* MAC address */ - status = usb_string_id(c->cdev); + status = usb_string_ids_tab(c->cdev, geth_string_defs); if (status < 0) return status; - geth_string_defs[1].id = status; - ether_desc.iMACAddress = status; + subset_data_intf.iInterface = geth_string_defs[0].id; + ether_desc.iMACAddress = geth_string_defs[1].id; } /* allocate and initialize one new instance */ @@ -425,9 +416,7 @@ int geth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) geth->port.func.disable = geth_disable; status = usb_add_function(c, &geth->port.func); - if (status) { - geth_string_defs[1].s = NULL; + if (status) kfree(geth); - } return status; } diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index 2840f181906..91396a1683e 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c @@ -1312,7 +1312,7 @@ afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr) static int audio_bind_config(struct usb_configuration *cfg) { - int id, res; + int res; agdev_g = kzalloc(sizeof *agdev_g, GFP_KERNEL); if (agdev_g == NULL) { @@ -1320,89 +1320,21 @@ static int audio_bind_config(struct usb_configuration *cfg) return -ENOMEM; } - id = usb_string_id(cfg->cdev); - if (id < 0) - return id; - - strings_fn[STR_ASSOC].id = id; - iad_desc.iFunction = id, - - id = usb_string_id(cfg->cdev); - if (id < 0) - return id; - - strings_fn[STR_IF_CTRL].id = id; - std_ac_if_desc.iInterface = id, - - id = usb_string_id(cfg->cdev); - if (id < 0) - return id; - - strings_fn[STR_CLKSRC_IN].id = id; - in_clk_src_desc.iClockSource = id, - - id = usb_string_id(cfg->cdev); - if (id < 0) - return id; - - strings_fn[STR_CLKSRC_OUT].id = id; - out_clk_src_desc.iClockSource = id, - - id = usb_string_id(cfg->cdev); - if (id < 0) - return id; - - strings_fn[STR_USB_IT].id = id; - usb_out_it_desc.iTerminal = id, - - id = usb_string_id(cfg->cdev); - if (id < 0) - return id; - - strings_fn[STR_IO_IT].id = id; - io_in_it_desc.iTerminal = id; - - id = usb_string_id(cfg->cdev); - if (id < 0) - return id; - - strings_fn[STR_USB_OT].id = id; - usb_in_ot_desc.iTerminal = id; - - id = usb_string_id(cfg->cdev); - if (id < 0) - return id; - - strings_fn[STR_IO_OT].id = id; - io_out_ot_desc.iTerminal = id; - - id = usb_string_id(cfg->cdev); - if (id < 0) - return id; - - strings_fn[STR_AS_OUT_ALT0].id = id; - std_as_out_if0_desc.iInterface = id; - - id = usb_string_id(cfg->cdev); - if (id < 0) - return id; - - strings_fn[STR_AS_OUT_ALT1].id = id; - std_as_out_if1_desc.iInterface = id; - - id = usb_string_id(cfg->cdev); - if (id < 0) - return id; - - strings_fn[STR_AS_IN_ALT0].id = id; - std_as_in_if0_desc.iInterface = id; - - id = usb_string_id(cfg->cdev); - if (id < 0) - return id; - - strings_fn[STR_AS_IN_ALT1].id = id; - std_as_in_if1_desc.iInterface = id; + res = usb_string_ids_tab(cfg->cdev, strings_fn); + if (res) + return res; + iad_desc.iFunction = strings_fn[STR_ASSOC].id; + std_ac_if_desc.iInterface = strings_fn[STR_IF_CTRL].id; + in_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_IN].id; + out_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_OUT].id; + usb_out_it_desc.iTerminal = strings_fn[STR_USB_IT].id; + io_in_it_desc.iTerminal = strings_fn[STR_IO_IT].id; + usb_in_ot_desc.iTerminal = strings_fn[STR_USB_OT].id; + io_out_ot_desc.iTerminal = strings_fn[STR_IO_OT].id; + std_as_out_if0_desc.iInterface = strings_fn[STR_AS_OUT_ALT0].id; + std_as_out_if1_desc.iInterface = strings_fn[STR_AS_OUT_ALT1].id; + std_as_in_if0_desc.iInterface = strings_fn[STR_AS_IN_ALT0].id; + std_as_in_if1_desc.iInterface = strings_fn[STR_AS_IN_ALT1].id; agdev_g->func.name = "uac2_func"; agdev_g->func.strings = fn_strings; diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c index 28ff2546a5b..5b629876941 100644 --- a/drivers/usb/gadget/f_uvc.c +++ b/drivers/usb/gadget/f_uvc.c @@ -580,6 +580,7 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f) uvc->control_ep->driver_data = NULL; uvc->video.ep->driver_data = NULL; + uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = 0; usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); kfree(uvc->control_buf); @@ -798,25 +799,16 @@ uvc_bind_config(struct usb_configuration *c, uvc->desc.hs_streaming = hs_streaming; uvc->desc.ss_streaming = ss_streaming; - /* maybe allocate device-global string IDs, and patch descriptors */ + /* Allocate string descriptor numbers. */ if (uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id == 0) { - /* Allocate string descriptor numbers. */ - ret = usb_string_id(c->cdev); - if (ret < 0) + ret = usb_string_ids_tab(c->cdev, uvc_en_us_strings); + if (ret) goto error; - uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = ret; - uvc_iad.iFunction = ret; - - ret = usb_string_id(c->cdev); - if (ret < 0) - goto error; - uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id = ret; - uvc_control_intf.iInterface = ret; - - ret = usb_string_id(c->cdev); - if (ret < 0) - goto error; - uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id = ret; + uvc_iad.iFunction = + uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id; + uvc_control_intf.iInterface = + uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id; + ret = uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id; uvc_streaming_intf_alt0.iInterface = ret; uvc_streaming_intf_alt1.iInterface = ret; } -- cgit v1.2.3 From b2113136a5701a7aaffee96c0423e7a620124328 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 30 Oct 2012 12:53:17 +0100 Subject: usb: gadget: dummy_hdc: prepare for multiple instances This patch replaces the single pdev variable by an array. One change: The device id is no longer -1 (i.e. none) but 0. This is prepation work for multiple instances of the dummy_hcd + udc which should help to test gadget framework with multiple UDCs. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 0f7541be28f..dffcf34d18d 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -2627,9 +2627,9 @@ static struct platform_driver dummy_hcd_driver = { }; /*-------------------------------------------------------------------------*/ - -static struct platform_device *the_udc_pdev; -static struct platform_device *the_hcd_pdev; +#define MAX_NUM_UDC 1 +static struct platform_device *the_udc_pdev[MAX_NUM_UDC]; +static struct platform_device *the_hcd_pdev[MAX_NUM_UDC]; static int __init init(void) { @@ -2641,11 +2641,11 @@ static int __init init(void) if (!mod_data.is_high_speed && mod_data.is_super_speed) return -EINVAL; - the_hcd_pdev = platform_device_alloc(driver_name, -1); - if (!the_hcd_pdev) + the_hcd_pdev[0] = platform_device_alloc(driver_name, 0); + if (!the_hcd_pdev[0]) return retval; - the_udc_pdev = platform_device_alloc(gadget_name, -1); - if (!the_udc_pdev) + the_udc_pdev[0] = platform_device_alloc(gadget_name, 0); + if (!the_udc_pdev[0]) goto err_alloc_udc; retval = platform_driver_register(&dummy_hcd_driver); @@ -2655,7 +2655,7 @@ static int __init init(void) if (retval < 0) goto err_register_udc_driver; - retval = platform_device_add(the_hcd_pdev); + retval = platform_device_add(the_hcd_pdev[0]); if (retval < 0) goto err_add_hcd; if (!the_controller.hs_hcd || @@ -2667,10 +2667,10 @@ static int __init init(void) retval = -EINVAL; goto err_add_udc; } - retval = platform_device_add(the_udc_pdev); + retval = platform_device_add(the_udc_pdev[0]); if (retval < 0) goto err_add_udc; - if (!platform_get_drvdata(the_udc_pdev)) { + if (!platform_get_drvdata(the_udc_pdev[0])) { /* * The udc was added successfully but its probe function failed * for some reason. @@ -2681,25 +2681,25 @@ static int __init init(void) return retval; err_probe_udc: - platform_device_del(the_udc_pdev); + platform_device_del(the_udc_pdev[0]); err_add_udc: - platform_device_del(the_hcd_pdev); + platform_device_del(the_hcd_pdev[0]); err_add_hcd: platform_driver_unregister(&dummy_udc_driver); err_register_udc_driver: platform_driver_unregister(&dummy_hcd_driver); err_register_hcd_driver: - platform_device_put(the_udc_pdev); + platform_device_put(the_udc_pdev[0]); err_alloc_udc: - platform_device_put(the_hcd_pdev); + platform_device_put(the_hcd_pdev[0]); return retval; } module_init(init); static void __exit cleanup(void) { - platform_device_unregister(the_udc_pdev); - platform_device_unregister(the_hcd_pdev); + platform_device_unregister(the_udc_pdev[0]); + platform_device_unregister(the_hcd_pdev[0]); platform_driver_unregister(&dummy_udc_driver); platform_driver_unregister(&dummy_hcd_driver); } -- cgit v1.2.3 From c7a1db457bfca045a0960f4eaaffd6539afbf8d7 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 29 Oct 2012 18:09:55 +0100 Subject: usb: gadget: dummy_hcd: add setup / cleanup of multiple HW intances This patch creates & adds multiple instances of the HCD and UDC. We have a new module option "num" which says how many emulated UDCs + HCDs we want. The default value is one and currently the maximum is one as well. This will change soon. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 97 +++++++++++++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 25 deletions(-) diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index dffcf34d18d..70f70ea133d 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -63,16 +63,20 @@ MODULE_LICENSE("GPL"); struct dummy_hcd_module_parameters { bool is_super_speed; bool is_high_speed; + unsigned int num; }; static struct dummy_hcd_module_parameters mod_data = { .is_super_speed = false, .is_high_speed = true, + .num = 1, }; module_param_named(is_super_speed, mod_data.is_super_speed, bool, S_IRUGO); MODULE_PARM_DESC(is_super_speed, "true to simulate SuperSpeed connection"); module_param_named(is_high_speed, mod_data.is_high_speed, bool, S_IRUGO); MODULE_PARM_DESC(is_high_speed, "true to simulate HighSpeed connection"); +module_param_named(num, mod_data.num, uint, S_IRUGO); +MODULE_PARM_DESC(num, "number of emulated controllers"); /*-------------------------------------------------------------------------*/ /* gadget side driver data structres */ @@ -2634,6 +2638,7 @@ static struct platform_device *the_hcd_pdev[MAX_NUM_UDC]; static int __init init(void) { int retval = -ENOMEM; + int i; if (usb_disabled()) return -ENODEV; @@ -2641,12 +2646,29 @@ static int __init init(void) if (!mod_data.is_high_speed && mod_data.is_super_speed) return -EINVAL; - the_hcd_pdev[0] = platform_device_alloc(driver_name, 0); - if (!the_hcd_pdev[0]) - return retval; - the_udc_pdev[0] = platform_device_alloc(gadget_name, 0); - if (!the_udc_pdev[0]) - goto err_alloc_udc; + if (mod_data.num < 1 || mod_data.num > MAX_NUM_UDC) { + pr_err("Number of emulated UDC must be in range of 1…%d\n", + MAX_NUM_UDC); + return -EINVAL; + } + for (i = 0; i < mod_data.num; i++) { + the_hcd_pdev[i] = platform_device_alloc(driver_name, i); + if (!the_hcd_pdev[i]) { + i--; + while (i >= 0) + platform_device_put(the_hcd_pdev[i--]); + return retval; + } + } + for (i = 0; i < mod_data.num; i++) { + the_udc_pdev[i] = platform_device_alloc(gadget_name, i); + if (!the_udc_pdev[i]) { + i--; + while (i >= 0) + platform_device_put(the_udc_pdev[i--]); + goto err_alloc_udc; + } + } retval = platform_driver_register(&dummy_hcd_driver); if (retval < 0) @@ -2655,9 +2677,15 @@ static int __init init(void) if (retval < 0) goto err_register_udc_driver; - retval = platform_device_add(the_hcd_pdev[0]); - if (retval < 0) - goto err_add_hcd; + for (i = 0; i < mod_data.num; i++) { + retval = platform_device_add(the_hcd_pdev[i]); + if (retval < 0) { + i--; + while (i >= 0) + platform_device_del(the_hcd_pdev[i--]); + goto err_add_hcd; + } + } if (!the_controller.hs_hcd || (!the_controller.ss_hcd && mod_data.is_super_speed)) { /* @@ -2667,39 +2695,58 @@ static int __init init(void) retval = -EINVAL; goto err_add_udc; } - retval = platform_device_add(the_udc_pdev[0]); - if (retval < 0) - goto err_add_udc; - if (!platform_get_drvdata(the_udc_pdev[0])) { - /* - * The udc was added successfully but its probe function failed - * for some reason. - */ - retval = -EINVAL; - goto err_probe_udc; + + + for (i = 0; i < mod_data.num; i++) { + retval = platform_device_add(the_udc_pdev[i]); + if (retval < 0) { + i--; + while (i >= 0) + platform_device_del(the_udc_pdev[i]); + goto err_add_udc; + } + } + + for (i = 0; i < mod_data.num; i++) { + if (!platform_get_drvdata(the_udc_pdev[i])) { + /* + * The udc was added successfully but its probe + * function failed for some reason. + */ + retval = -EINVAL; + goto err_probe_udc; + } } return retval; err_probe_udc: - platform_device_del(the_udc_pdev[0]); + for (i = 0; i < mod_data.num; i++) + platform_device_del(the_udc_pdev[i]); err_add_udc: - platform_device_del(the_hcd_pdev[0]); + for (i = 0; i < mod_data.num; i++) + platform_device_del(the_hcd_pdev[i]); err_add_hcd: platform_driver_unregister(&dummy_udc_driver); err_register_udc_driver: platform_driver_unregister(&dummy_hcd_driver); err_register_hcd_driver: - platform_device_put(the_udc_pdev[0]); + for (i = 0; i < mod_data.num; i++) + platform_device_put(the_udc_pdev[i]); err_alloc_udc: - platform_device_put(the_hcd_pdev[0]); + for (i = 0; i < mod_data.num; i++) + platform_device_put(the_hcd_pdev[i]); return retval; } module_init(init); static void __exit cleanup(void) { - platform_device_unregister(the_udc_pdev[0]); - platform_device_unregister(the_hcd_pdev[0]); + int i; + + for (i = 0; i < mod_data.num; i++) { + platform_device_unregister(the_udc_pdev[i]); + platform_device_unregister(the_hcd_pdev[i]); + } platform_driver_unregister(&dummy_udc_driver); platform_driver_unregister(&dummy_hcd_driver); } -- cgit v1.2.3 From b100a2f34dc160502bf7d3006cd8294303bbfacb Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 29 Oct 2012 18:09:56 +0100 Subject: usb: gadget: dummy_hcd: remove global the_controller variable The one thing that makes two UDCs+HCDs impossible is the global the_controller variable. This patch changes this. After device allocation we allocate the "the_controller" variable and pass it as platform_data to the UDC and its companion. We can have now multiple instances dummy hcd and therefore I change the limit from one to two. I was able to test this with g_ncm adn g_zero: |# lsusb |Bus 001 Device 002: ID 0525:a4a0 Netchip Technology, Inc. Linux-USB "Gadget Zero" |Bus 002 Device 002: ID 0525:a4a1 Netchip Technology, Inc. Linux-USB Ethernet Gadget |Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub |Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub I was able to start testusb -a and ifconfig usb[01] up with no complains. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 71 +++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 70f70ea133d..95d584dbed1 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -242,8 +242,6 @@ static inline struct dummy *gadget_dev_to_dummy(struct device *dev) return container_of(dev, struct dummy, gadget.dev); } -static struct dummy the_controller; - /*-------------------------------------------------------------------------*/ /* SLAVE/GADGET SIDE UTILITY ROUTINES */ @@ -977,9 +975,10 @@ static void init_dummy_udc_hw(struct dummy *dum) static int dummy_udc_probe(struct platform_device *pdev) { - struct dummy *dum = &the_controller; + struct dummy *dum; int rc; + dum = *((void **)dev_get_platdata(&pdev->dev)); dum->gadget.name = gadget_name; dum->gadget.ops = &dummy_ops; dum->gadget.max_speed = USB_SPEED_SUPER; @@ -2402,10 +2401,13 @@ static int dummy_h_get_frame(struct usb_hcd *hcd) static int dummy_setup(struct usb_hcd *hcd) { + struct dummy *dum; + + dum = *((void **)dev_get_platdata(hcd->self.controller)); hcd->self.sg_tablesize = ~0; if (usb_hcd_is_primary_hcd(hcd)) { - the_controller.hs_hcd = hcd_to_dummy_hcd(hcd); - the_controller.hs_hcd->dum = &the_controller; + dum->hs_hcd = hcd_to_dummy_hcd(hcd); + dum->hs_hcd->dum = dum; /* * Mark the first roothub as being USB 2.0. * The USB 3.0 roothub will be registered later by @@ -2414,8 +2416,8 @@ static int dummy_setup(struct usb_hcd *hcd) hcd->speed = HCD_USB2; hcd->self.root_hub->speed = USB_SPEED_HIGH; } else { - the_controller.ss_hcd = hcd_to_dummy_hcd(hcd); - the_controller.ss_hcd->dum = &the_controller; + dum->ss_hcd = hcd_to_dummy_hcd(hcd); + dum->ss_hcd->dum = dum; hcd->speed = HCD_USB3; hcd->self.root_hub->speed = USB_SPEED_SUPER; } @@ -2528,11 +2530,13 @@ static struct hc_driver dummy_hcd = { static int dummy_hcd_probe(struct platform_device *pdev) { + struct dummy *dum; struct usb_hcd *hs_hcd; struct usb_hcd *ss_hcd; int retval; dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); + dum = *((void **)dev_get_platdata(&pdev->dev)); if (!mod_data.is_super_speed) dummy_hcd.flags = HCD_USB2; @@ -2565,7 +2569,7 @@ dealloc_usb2_hcd: usb_remove_hcd(hs_hcd); put_usb2_hcd: usb_put_hcd(hs_hcd); - the_controller.hs_hcd = the_controller.ss_hcd = NULL; + dum->hs_hcd = dum->ss_hcd = NULL; return retval; } @@ -2583,8 +2587,8 @@ static int dummy_hcd_remove(struct platform_device *pdev) usb_remove_hcd(dummy_hcd_to_hcd(dum->hs_hcd)); usb_put_hcd(dummy_hcd_to_hcd(dum->hs_hcd)); - the_controller.hs_hcd = NULL; - the_controller.ss_hcd = NULL; + dum->hs_hcd = NULL; + dum->ss_hcd = NULL; return 0; } @@ -2631,7 +2635,7 @@ static struct platform_driver dummy_hcd_driver = { }; /*-------------------------------------------------------------------------*/ -#define MAX_NUM_UDC 1 +#define MAX_NUM_UDC 2 static struct platform_device *the_udc_pdev[MAX_NUM_UDC]; static struct platform_device *the_hcd_pdev[MAX_NUM_UDC]; @@ -2639,6 +2643,7 @@ static int __init init(void) { int retval = -ENOMEM; int i; + struct dummy *dum[MAX_NUM_UDC]; if (usb_disabled()) return -ENODEV; @@ -2651,6 +2656,7 @@ static int __init init(void) MAX_NUM_UDC); return -EINVAL; } + for (i = 0; i < mod_data.num; i++) { the_hcd_pdev[i] = platform_device_alloc(driver_name, i); if (!the_hcd_pdev[i]) { @@ -2669,10 +2675,23 @@ static int __init init(void) goto err_alloc_udc; } } + for (i = 0; i < mod_data.num; i++) { + dum[i] = kzalloc(sizeof(struct dummy), GFP_KERNEL); + if (!dum[i]) + goto err_add_pdata; + retval = platform_device_add_data(the_hcd_pdev[i], &dum[i], + sizeof(void *)); + if (retval) + goto err_add_pdata; + retval = platform_device_add_data(the_udc_pdev[i], &dum[i], + sizeof(void *)); + if (retval) + goto err_add_pdata; + } retval = platform_driver_register(&dummy_hcd_driver); if (retval < 0) - goto err_register_hcd_driver; + goto err_add_pdata; retval = platform_driver_register(&dummy_udc_driver); if (retval < 0) goto err_register_udc_driver; @@ -2686,17 +2705,18 @@ static int __init init(void) goto err_add_hcd; } } - if (!the_controller.hs_hcd || - (!the_controller.ss_hcd && mod_data.is_super_speed)) { - /* - * The hcd was added successfully but its probe function failed - * for some reason. - */ - retval = -EINVAL; - goto err_add_udc; + for (i = 0; i < mod_data.num; i++) { + if (!dum[i]->hs_hcd || + (!dum[i]->ss_hcd && mod_data.is_super_speed)) { + /* + * The hcd was added successfully but its probe + * function failed for some reason. + */ + retval = -EINVAL; + goto err_add_udc; + } } - for (i = 0; i < mod_data.num; i++) { retval = platform_device_add(the_udc_pdev[i]); if (retval < 0) { @@ -2729,7 +2749,9 @@ err_add_hcd: platform_driver_unregister(&dummy_udc_driver); err_register_udc_driver: platform_driver_unregister(&dummy_hcd_driver); -err_register_hcd_driver: +err_add_pdata: + for (i = 0; i < mod_data.num; i++) + kfree(dum[i]); for (i = 0; i < mod_data.num; i++) platform_device_put(the_udc_pdev[i]); err_alloc_udc: @@ -2744,8 +2766,13 @@ static void __exit cleanup(void) int i; for (i = 0; i < mod_data.num; i++) { + struct dummy *dum; + + dum = *((void **)dev_get_platdata(&the_udc_pdev[i]->dev)); + platform_device_unregister(the_udc_pdev[i]); platform_device_unregister(the_hcd_pdev[i]); + kfree(dum); } platform_driver_unregister(&dummy_udc_driver); platform_driver_unregister(&dummy_hcd_driver); -- cgit v1.2.3 From 124dafde8f8174caf5cef1c3eaba001657d66f4f Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 29 Oct 2012 18:09:53 +0100 Subject: usb: dwc3: remove custom unique id handling The lockless implementation of the unique id is quite impressive (:P) but dirver's core can handle it, we can remove it and make our code a little smaller. Cc: Anton Tikhomirov Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 39 --------------------------------------- drivers/usb/dwc3/core.h | 3 --- drivers/usb/dwc3/dwc3-exynos.c | 13 ++----------- drivers/usb/dwc3/dwc3-omap.c | 16 ++-------------- drivers/usb/dwc3/dwc3-pci.c | 16 ++-------------- 5 files changed, 6 insertions(+), 81 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b923183c43c..d8d327a5e53 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -66,45 +66,6 @@ MODULE_PARM_DESC(maximum_speed, "Maximum supported speed."); /* -------------------------------------------------------------------------- */ -#define DWC3_DEVS_POSSIBLE 32 - -static DECLARE_BITMAP(dwc3_devs, DWC3_DEVS_POSSIBLE); - -int dwc3_get_device_id(void) -{ - int id; - -again: - id = find_first_zero_bit(dwc3_devs, DWC3_DEVS_POSSIBLE); - if (id < DWC3_DEVS_POSSIBLE) { - int old; - - old = test_and_set_bit(id, dwc3_devs); - if (old) - goto again; - } else { - pr_err("dwc3: no space for new device\n"); - id = -ENOMEM; - } - - return id; -} -EXPORT_SYMBOL_GPL(dwc3_get_device_id); - -void dwc3_put_device_id(int id) -{ - int ret; - - if (id < 0) - return; - - ret = test_bit(id, dwc3_devs); - WARN(!ret, "dwc3: ID %d not in use\n", id); - smp_mb__before_clear_bit(); - clear_bit(id, dwc3_devs); -} -EXPORT_SYMBOL_GPL(dwc3_put_device_id); - void dwc3_set_mode(struct dwc3 *dwc, u32 mode) { u32 reg; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 243affc9343..49995634426 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -868,7 +868,4 @@ void dwc3_host_exit(struct dwc3 *dwc); int dwc3_gadget_init(struct dwc3 *dwc); void dwc3_gadget_exit(struct dwc3 *dwc); -extern int dwc3_get_device_id(void); -extern void dwc3_put_device_id(int id); - #endif /* __DRIVERS_USB_DWC3_CORE_H */ diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index ca6597853f9..586f1051b05 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -94,7 +94,6 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev) struct dwc3_exynos *exynos; struct clk *clk; - int devid; int ret = -ENOMEM; exynos = kzalloc(sizeof(*exynos), GFP_KERNEL); @@ -105,20 +104,16 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev) platform_set_drvdata(pdev, exynos); - devid = dwc3_get_device_id(); - if (devid < 0) - goto err1; - ret = dwc3_exynos_register_phys(exynos); if (ret) { dev_err(&pdev->dev, "couldn't register PHYs\n"); goto err1; } - dwc3 = platform_device_alloc("dwc3", devid); + dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); if (!dwc3) { dev_err(&pdev->dev, "couldn't allocate dwc3 device\n"); - goto err2; + goto err1; } clk = clk_get(&pdev->dev, "usbdrd30"); @@ -170,8 +165,6 @@ err4: clk_put(clk); err3: platform_device_put(dwc3); -err2: - dwc3_put_device_id(devid); err1: kfree(exynos); err0: @@ -187,8 +180,6 @@ static int __devexit dwc3_exynos_remove(struct platform_device *pdev) platform_device_unregister(exynos->usb2_phy); platform_device_unregister(exynos->usb3_phy); - dwc3_put_device_id(exynos->dwc3->id); - if (pdata && pdata->phy_exit) pdata->phy_exit(pdev, pdata->phy_type); diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index ee57a10d90d..900d435f41d 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -272,7 +272,6 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev) struct resource *res; struct device *dev = &pdev->dev; - int devid; int size; int ret = -ENOMEM; int irq; @@ -315,14 +314,10 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev) return ret; } - devid = dwc3_get_device_id(); - if (devid < 0) - return -ENODEV; - - dwc3 = platform_device_alloc("dwc3", devid); + dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); if (!dwc3) { dev_err(dev, "couldn't allocate dwc3 device\n"); - goto err1; + return -ENOMEM; } context = devm_kzalloc(dev, resource_size(res), GFP_KERNEL); @@ -423,10 +418,6 @@ static int __devinit dwc3_omap_probe(struct platform_device *pdev) err2: platform_device_put(dwc3); - -err1: - dwc3_put_device_id(devid); - return ret; } @@ -437,9 +428,6 @@ static int __devexit dwc3_omap_remove(struct platform_device *pdev) platform_device_unregister(omap->dwc3); platform_device_unregister(omap->usb2_phy); platform_device_unregister(omap->usb3_phy); - - dwc3_put_device_id(omap->dwc3->id); - return 0; } diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 94f550e37f9..13962597f3f 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -119,7 +119,6 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci, struct platform_device *dwc3; struct dwc3_pci *glue; int ret = -ENOMEM; - int devid; struct device *dev = &pci->dev; glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); @@ -145,13 +144,7 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci, return ret; } - devid = dwc3_get_device_id(); - if (devid < 0) { - ret = -ENOMEM; - goto err1; - } - - dwc3 = platform_device_alloc("dwc3", devid); + dwc3 = platform_device_alloc("dwc3", PLATFORM_DEVID_AUTO); if (!dwc3) { dev_err(dev, "couldn't allocate dwc3 device\n"); ret = -ENOMEM; @@ -172,7 +165,7 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci, ret = platform_device_add_resources(dwc3, res, ARRAY_SIZE(res)); if (ret) { dev_err(dev, "couldn't add resources to dwc3 device\n"); - goto err2; + goto err1; } pci_set_drvdata(pci, glue); @@ -195,10 +188,6 @@ static int __devinit dwc3_pci_probe(struct pci_dev *pci, err3: pci_set_drvdata(pci, NULL); platform_device_put(dwc3); - -err2: - dwc3_put_device_id(devid); - err1: pci_disable_device(pci); @@ -211,7 +200,6 @@ static void __devexit dwc3_pci_remove(struct pci_dev *pci) platform_device_unregister(glue->usb2_phy); platform_device_unregister(glue->usb3_phy); - dwc3_put_device_id(glue->dwc3->id); platform_device_unregister(glue->dwc3); pci_set_drvdata(pci, NULL); pci_disable_device(pci); -- cgit v1.2.3 From b11e94d03726c5dbee0d9a841a025313504e90f4 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 30 Oct 2012 19:52:23 +0100 Subject: usb: musb: read MUSB_POWER register only when required. This is part of the workaround for AM35x advisory Advisory 1.1.20. The advisory says that the IPSS bridge can't handle 8 & 16 bit read access. An 8bit read access to MUSB_POWER results in an 32bit read access which also reads INTRTX and therefore may lose interrupts. This patch tries to minimize reads to MUSB_POWER and perform them only when required. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index bb56a0e8b23..d156fe8bebf 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -467,12 +467,12 @@ void musb_hnp_stop(struct musb *musb) */ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, - u8 devctl, u8 power) + u8 devctl) { struct usb_otg *otg = musb->xceiv->otg; irqreturn_t handled = IRQ_NONE; - dev_dbg(musb->controller, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, + dev_dbg(musb->controller, "<== DevCtl=%02x, int_usb=0x%x\n", devctl, int_usb); /* in host mode, the peripheral may issue remote wakeup. @@ -485,6 +485,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if (devctl & MUSB_DEVCTL_HM) { void __iomem *mbase = musb->mregs; + u8 power; switch (musb->xceiv->state) { case OTG_STATE_A_SUSPEND: @@ -492,6 +493,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, * will stop RESUME signaling */ + power = musb_readb(musb->mregs, MUSB_POWER); if (power & MUSB_POWER_SUSPENDM) { /* spurious */ musb->int_usb &= ~MUSB_INTR_SUSPEND; @@ -655,8 +657,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, } if (int_usb & MUSB_INTR_SUSPEND) { - dev_dbg(musb->controller, "SUSPEND (%s) devctl %02x power %02x\n", - otg_state_string(musb->xceiv->state), devctl, power); + dev_dbg(musb->controller, "SUSPEND (%s) devctl %02x\n", + otg_state_string(musb->xceiv->state), devctl); handled = IRQ_HANDLED; switch (musb->xceiv->state) { @@ -1560,12 +1562,11 @@ static irqreturn_t generic_interrupt(int irq, void *__hci) irqreturn_t musb_interrupt(struct musb *musb) { irqreturn_t retval = IRQ_NONE; - u8 devctl, power; + u8 devctl; int ep_num; u32 reg; devctl = musb_readb(musb->mregs, MUSB_DEVCTL); - power = musb_readb(musb->mregs, MUSB_POWER); dev_dbg(musb->controller, "** IRQ %s usb%04x tx%04x rx%04x\n", (devctl & MUSB_DEVCTL_HM) ? "host" : "peripheral", @@ -1576,7 +1577,7 @@ irqreturn_t musb_interrupt(struct musb *musb) */ if (musb->int_usb) retval |= musb_stage0_irq(musb, musb->int_usb, - devctl, power); + devctl); /* "stage 1" is handling endpoint irqs */ -- cgit v1.2.3 From 515ba29cd7b571da45365e4db80c1b6905869ef3 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 30 Oct 2012 19:52:24 +0100 Subject: usb: musb: avoid FADDR read access This is part of the workaround for AM35x advisory Advisory 1.1.20. The advisory says that the IPSS bridge can't handle 8 & 16 bit read access. An 8bit read access to FADDR results in an 32bit read access which also reads INTRTX and therefore may lose interrupts. This patch removes any reads to FADDR as they are not really required. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 3 +-- drivers/usb/musb/musb_gadget_ep0.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d0b87e7b4ab..b430f158e66 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -2154,10 +2154,9 @@ __acquires(musb->lock) u8 devctl = musb_readb(mbase, MUSB_DEVCTL); u8 power; - dev_dbg(musb->controller, "<== %s addr=%x driver '%s'\n", + dev_dbg(musb->controller, "<== %s driver '%s'\n", (devctl & MUSB_DEVCTL_BDEVICE) ? "B-Device" : "A-Device", - musb_readb(mbase, MUSB_FADDR), musb->gadget_driver ? musb->gadget_driver->driver.name : NULL diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c index e40d7647caf..c9c1ac4e075 100644 --- a/drivers/usb/musb/musb_gadget_ep0.c +++ b/drivers/usb/musb/musb_gadget_ep0.c @@ -673,10 +673,8 @@ irqreturn_t musb_g_ep0_irq(struct musb *musb) csr = musb_readw(regs, MUSB_CSR0); len = musb_readb(regs, MUSB_COUNT0); - dev_dbg(musb->controller, "csr %04x, count %d, myaddr %d, ep0stage %s\n", - csr, len, - musb_readb(mbase, MUSB_FADDR), - decode_ep0stage(musb->ep0_state)); + dev_dbg(musb->controller, "csr %04x, count %d, ep0stage %s\n", + csr, len, decode_ep0stage(musb->ep0_state)); if (csr & MUSB_CSR0_P_DATAEND) { /* -- cgit v1.2.3 From af5ec14d40e0da1de17fcca2b41c76fae5c2cb9d Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 30 Oct 2012 19:52:25 +0100 Subject: usb: musb: Perform only write access on MUSB_INTRRXE This is part of the workaround for AM35x advisory Advisory 1.1.20. The advisory says that the IPSS bridge can't handle 8 & 16 bit read access. An 16bit read access to MUSB_INTRRXE results in an 32bit read access which also reads INTRUSB and therefore may lose interrupts. This patch uses a shadow register of MUSB_INTRRXE so we only perform write access to it. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 10 ++++++---- drivers/usb/musb/musb_core.h | 3 ++- drivers/usb/musb/musb_gadget.c | 10 ++++------ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index d156fe8bebf..7ff1986e5e5 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -725,7 +725,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, /* REVISIT HNP; just force disconnect */ } musb_writew(musb->mregs, MUSB_INTRTXE, musb->epmask); - musb_writew(musb->mregs, MUSB_INTRRXE, musb->epmask & 0xfffe); + musb->intrrxe = musb->epmask & 0xfffe; + musb_writew(musb->mregs, MUSB_INTRRXE, musb->intrrxe); musb_writeb(musb->mregs, MUSB_INTRUSBE, 0xf7); musb->port1_status &= ~(USB_PORT_STAT_LOW_SPEED |USB_PORT_STAT_HIGH_SPEED @@ -947,7 +948,8 @@ void musb_start(struct musb *musb) /* Set INT enable registers, enable interrupts */ musb_writew(regs, MUSB_INTRTXE, musb->epmask); - musb_writew(regs, MUSB_INTRRXE, musb->epmask & 0xfffe); + musb->intrrxe = musb->epmask & 0xfffe; + musb_writew(regs, MUSB_INTRRXE, musb->intrrxe); musb_writeb(regs, MUSB_INTRUSBE, 0xf7); musb_writeb(regs, MUSB_TESTMODE, 0); @@ -986,6 +988,7 @@ static void musb_generic_disable(struct musb *musb) /* disable interrupts */ musb_writeb(mbase, MUSB_INTRUSBE, 0); musb_writew(mbase, MUSB_INTRTXE, 0); + musb->intrrxe = 0; musb_writew(mbase, MUSB_INTRRXE, 0); /* off */ @@ -2122,7 +2125,6 @@ static void musb_save_context(struct musb *musb) musb->context.busctl = musb_read_ulpi_buscontrol(musb->mregs); musb->context.power = musb_readb(musb_base, MUSB_POWER); musb->context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); - musb->context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE); musb->context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE); musb->context.index = musb_readb(musb_base, MUSB_INDEX); musb->context.devctl = musb_readb(musb_base, MUSB_DEVCTL); @@ -2196,7 +2198,7 @@ static void musb_restore_context(struct musb *musb) musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl); musb_writeb(musb_base, MUSB_POWER, musb->context.power); musb_writew(musb_base, MUSB_INTRTXE, musb->context.intrtxe); - musb_writew(musb_base, MUSB_INTRRXE, musb->context.intrrxe); + musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe); musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index c158aacd6de..60b92cbdc7f 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -288,7 +288,7 @@ struct musb_csr_regs { struct musb_context_registers { u8 power; - u16 intrtxe, intrrxe; + u16 intrtxe; u8 intrusbe; u16 frame; u8 index, testmode; @@ -313,6 +313,7 @@ struct musb { struct work_struct irq_work; u16 hwvers; + u16 intrrxe; /* this hub status bit is reserved by USB 2.0 and not seen by usbcore */ #define MUSB_PORT_STAT_RESUME (1 << 31) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index b430f158e66..bb684f0f790 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1108,7 +1108,6 @@ static int musb_gadget_enable(struct usb_ep *ep, musb_writew(regs, MUSB_TXCSR, csr); } else { - u16 int_rxe = musb_readw(mbase, MUSB_INTRRXE); if (hw_ep->is_shared_fifo) musb_ep->is_in = 0; @@ -1120,8 +1119,8 @@ static int musb_gadget_enable(struct usb_ep *ep, goto fail; } - int_rxe |= (1 << epnum); - musb_writew(mbase, MUSB_INTRRXE, int_rxe); + musb->intrrxe |= (1 << epnum); + musb_writew(mbase, MUSB_INTRRXE, musb->intrrxe); /* REVISIT if can_bulk_combine() use by updating "tmp" * likewise high bandwidth periodic rx @@ -1214,9 +1213,8 @@ static int musb_gadget_disable(struct usb_ep *ep) musb_writew(musb->mregs, MUSB_INTRTXE, int_txe); musb_writew(epio, MUSB_TXMAXP, 0); } else { - u16 int_rxe = musb_readw(musb->mregs, MUSB_INTRRXE); - int_rxe &= ~(1 << epnum); - musb_writew(musb->mregs, MUSB_INTRRXE, int_rxe); + musb->intrrxe &= ~(1 << epnum); + musb_writew(musb->mregs, MUSB_INTRRXE, musb->intrrxe); musb_writew(epio, MUSB_RXMAXP, 0); } -- cgit v1.2.3 From b18d26f6ad8f00ea5f7c6a12ea52627ca3c3c6e2 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 30 Oct 2012 19:52:26 +0100 Subject: usb: musb: Perform only write access on MUSB_INTRTXE This is part of the workaround for AM35x advisory Advisory 1.1.20. The advisory says that the IPSS bridge can't handle 8 & 16 bit read access. An 16bit read access to MUSB_INTRTXE results in an 32bit read access which also reads INTRRX and therefore may lose interrupts. This patch uses a shadow register of MUSB_INTRTXE so we only perform write access to it. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 10 ++++++---- drivers/usb/musb/musb_core.h | 2 +- drivers/usb/musb/musb_gadget.c | 17 +++++++---------- drivers/usb/musb/musb_host.c | 2 +- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 7ff1986e5e5..25a0d8e1be5 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -724,7 +724,8 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, if (is_peripheral_active(musb)) { /* REVISIT HNP; just force disconnect */ } - musb_writew(musb->mregs, MUSB_INTRTXE, musb->epmask); + musb->intrtxe = musb->epmask; + musb_writew(musb->mregs, MUSB_INTRTXE, musb->intrtxe); musb->intrrxe = musb->epmask & 0xfffe; musb_writew(musb->mregs, MUSB_INTRRXE, musb->intrrxe); musb_writeb(musb->mregs, MUSB_INTRUSBE, 0xf7); @@ -947,7 +948,8 @@ void musb_start(struct musb *musb) dev_dbg(musb->controller, "<== devctl %02x\n", devctl); /* Set INT enable registers, enable interrupts */ - musb_writew(regs, MUSB_INTRTXE, musb->epmask); + musb->intrtxe = musb->epmask; + musb_writew(regs, MUSB_INTRTXE, musb->intrtxe); musb->intrrxe = musb->epmask & 0xfffe; musb_writew(regs, MUSB_INTRRXE, musb->intrrxe); musb_writeb(regs, MUSB_INTRUSBE, 0xf7); @@ -987,6 +989,7 @@ static void musb_generic_disable(struct musb *musb) /* disable interrupts */ musb_writeb(mbase, MUSB_INTRUSBE, 0); + musb->intrtxe = 0; musb_writew(mbase, MUSB_INTRTXE, 0); musb->intrrxe = 0; musb_writew(mbase, MUSB_INTRRXE, 0); @@ -2124,7 +2127,6 @@ static void musb_save_context(struct musb *musb) musb->context.testmode = musb_readb(musb_base, MUSB_TESTMODE); musb->context.busctl = musb_read_ulpi_buscontrol(musb->mregs); musb->context.power = musb_readb(musb_base, MUSB_POWER); - musb->context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); musb->context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE); musb->context.index = musb_readb(musb_base, MUSB_INDEX); musb->context.devctl = musb_readb(musb_base, MUSB_DEVCTL); @@ -2197,7 +2199,7 @@ static void musb_restore_context(struct musb *musb) musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode); musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl); musb_writeb(musb_base, MUSB_POWER, musb->context.power); - musb_writew(musb_base, MUSB_INTRTXE, musb->context.intrtxe); + musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe); musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe); musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 60b92cbdc7f..0cef3ceb52c 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -288,7 +288,6 @@ struct musb_csr_regs { struct musb_context_registers { u8 power; - u16 intrtxe; u8 intrusbe; u16 frame; u8 index, testmode; @@ -314,6 +313,7 @@ struct musb { u16 hwvers; u16 intrrxe; + u16 intrtxe; /* this hub status bit is reserved by USB 2.0 and not seen by usbcore */ #define MUSB_PORT_STAT_RESUME (1 << 31) diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index bb684f0f790..28b9790e84e 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1068,7 +1068,6 @@ static int musb_gadget_enable(struct usb_ep *ep, */ musb_ep_select(mbase, epnum); if (usb_endpoint_dir_in(desc)) { - u16 int_txe = musb_readw(mbase, MUSB_INTRTXE); if (hw_ep->is_shared_fifo) musb_ep->is_in = 1; @@ -1080,8 +1079,8 @@ static int musb_gadget_enable(struct usb_ep *ep, goto fail; } - int_txe |= (1 << epnum); - musb_writew(mbase, MUSB_INTRTXE, int_txe); + musb->intrtxe |= (1 << epnum); + musb_writew(mbase, MUSB_INTRTXE, musb->intrtxe); /* REVISIT if can_bulk_split(), use by updating "tmp"; * likewise high bandwidth periodic tx @@ -1208,9 +1207,8 @@ static int musb_gadget_disable(struct usb_ep *ep) /* zero the endpoint sizes */ if (musb_ep->is_in) { - u16 int_txe = musb_readw(musb->mregs, MUSB_INTRTXE); - int_txe &= ~(1 << epnum); - musb_writew(musb->mregs, MUSB_INTRTXE, int_txe); + musb->intrtxe &= ~(1 << epnum); + musb_writew(musb->mregs, MUSB_INTRTXE, musb->intrtxe); musb_writew(epio, MUSB_TXMAXP, 0); } else { musb->intrrxe &= ~(1 << epnum); @@ -1530,7 +1528,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep) void __iomem *epio = musb->endpoints[epnum].regs; void __iomem *mbase; unsigned long flags; - u16 csr, int_txe; + u16 csr; mbase = musb->mregs; @@ -1538,8 +1536,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep) musb_ep_select(mbase, (u8) epnum); /* disable interrupts */ - int_txe = musb_readw(mbase, MUSB_INTRTXE); - musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum)); + musb_writew(mbase, MUSB_INTRTXE, musb->intrtxe & ~(1 << epnum)); if (musb_ep->is_in) { csr = musb_readw(epio, MUSB_TXCSR); @@ -1563,7 +1560,7 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep) } /* re-enable interrupt */ - musb_writew(mbase, MUSB_INTRTXE, int_txe); + musb_writew(mbase, MUSB_INTRTXE, musb->intrtxe); spin_unlock_irqrestore(&musb->lock, flags); } diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 3df6a76b851..e9f0fd9ddd2 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -740,7 +740,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum, csr = musb_readw(epio, MUSB_TXCSR); /* disable interrupt in case we flush */ - int_txe = musb_readw(mbase, MUSB_INTRTXE); + int_txe = musb->intrtxe; musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum)); /* general endpoint setup */ -- cgit v1.2.3 From d30ff29562ecbf79e82df72724d0c6180f2e2c06 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 30 Oct 2012 00:06:46 +0900 Subject: perf tools: Warn about missing libelf When perf detects no libelf during the build, it'll use internal mini elf parser instead of libelf. But as it only supports minimal functionalities, it also disables support to 'probe' builtin command. Currently it didn't warned to user. Fix it. $ sudo apt-get remove libelf-dev $ make CHK -fstack-protector-all CHK -Wstack-protector CHK -Wvolatile-register-var CHK bionic CHK libelf CHK glibc Makefile:491: No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev CHK libunwind CHK libaudit $ make NO_LIBELF=1 CHK -fstack-protector-all CHK -Wstack-protector CHK -Wvolatile-register-var CHK bionic CHK libaudit Reported-by: Peter Zijlstra Signed-off-by: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-8ww8zc4hhpxabfskxs3u5ede@git.kernel.org [ committer note: The package needed is elfutils-libelf-devel, not elfutils-devel ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 7e25f59e5e8..b1801e0693c 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -490,6 +490,8 @@ ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y) LIBC_SUPPORT := 1 endif ifeq ($(LIBC_SUPPORT),1) + msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev); + NO_LIBELF := 1 NO_DWARF := 1 NO_DEMANGLE := 1 -- cgit v1.2.3 From cd69ef88a7cbe5ad404454ed8f491e6b16b4e86f Mon Sep 17 00:00:00 2001 From: Joonsoo Kim Date: Mon, 29 Oct 2012 22:41:06 +0900 Subject: perf tools: Add info about cross compiling for Android ARM Without defining ARCH=arm, building perf for Android ARM will fail, because it needs architecture specific files. So add related relevant information to the android documentation. Signed-off-by: Joonsoo Kim Reviewed-by: Namhyung Kim Cc: David Ahern Cc: Ingo Molnar Cc: Irina Tirdea Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1351518066-4791-1-git-send-email-js1304@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/android.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/android.txt b/tools/perf/Documentation/android.txt index a39dbbb44c4..8484c3a04a6 100644 --- a/tools/perf/Documentation/android.txt +++ b/tools/perf/Documentation/android.txt @@ -48,7 +48,10 @@ For x86: II. Compile perf for Android ------------------------------------------------ You need to run make with the NDK toolchain and sysroot defined above: - make CROSS_COMPILE=${NDK_TOOLCHAIN} CFLAGS="--sysroot=${NDK_SYSROOT}" +For arm: + make ARCH=arm CROSS_COMPILE=${NDK_TOOLCHAIN} CFLAGS="--sysroot=${NDK_SYSROOT}" +For x86: + make ARCH=x86 CROSS_COMPILE=${NDK_TOOLCHAIN} CFLAGS="--sysroot=${NDK_SYSROOT}" III. Install perf ----------------------------------------------- -- cgit v1.2.3 From acddedfba0df1e47fa99035a04661082b679ee9c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 30 Oct 2012 09:46:00 +0100 Subject: perf tools: Speed up the perf build time by simplifying the perf --version string generation Building perf is pretty slow on trees that have a lot of commits relative to the nearest Git tag. This slowness manifests itself during version string generation: $ perf stat --null --repeat 3 --sync --pre "rm -f PERF-VERSION-FILE" util/PERF-VERSION-GEN PERF_VERSION = 3.7.rc3.1458.g5399b3b PERF_VERSION = 3.7.rc3.1458.g5399b3b PERF_VERSION = 3.7.rc3.1458.g5399b3b Performance counter stats for 'util/PERF-VERSION-GEN' (3 runs): 2.857503976 seconds time elapsed ( +- 0.22% ) The build can be even slower than that, when one over NFS volumes. The reason for the slowness is that util/PERF-VERSION-GEN uses "git describe" to generate the string, which has to count the "number of commits distance" from the nearest tag - the ".1458." count in the output above. For that Git had to extract and decompress 1458 Git objects, which takes time and bandwidth. But this "number of commits" value is mostly irrelevant in practice. We either want to know an approximate tag name, or we want to know the precise sha1. So this patch simplifies the version string to: PERF_VERSION = 3.7.rc3.g5399b3b.dirty which speeds up the version string generation script by an order of magnitude: $ perf stat --null --repeat 3 --sync --pre "rm -f PERF-VERSION-FILE" util/PERF-VERSION-GEN PERF_VERSION = 3.7.rc3.g5399b3b.dirty PERF_VERSION = 3.7.rc3.g5399b3b.dirty PERF_VERSION = 3.7.rc3.g5399b3b.dirty Performance counter stats for 'util/PERF-VERSION-GEN' (3 runs): 0.307633559 seconds time elapsed ( +- 0.84% ) Signed-off-by: Ingo Molnar Cc: Andrew Vagin Cc: Borislav Petkov Cc: David Howells Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt Link: http://lkml.kernel.org/r/20121030084600.GB8245@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/PERF-VERSION-GEN | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN index 95264f30417..f6e8ee29f2a 100755 --- a/tools/perf/util/PERF-VERSION-GEN +++ b/tools/perf/util/PERF-VERSION-GEN @@ -12,7 +12,7 @@ LF=' # First check if there is a .git to get the version from git describe # otherwise try to get the version from the kernel makefile if test -d ../../.git -o -f ../../.git && - VN=$(git describe --match 'v[0-9].[0-9]*' --abbrev=4 HEAD 2>/dev/null) && + VN=$(echo $(git tag -l "v[0-9].[0-9]*" | tail -1)"-g"$(git log -1 --abbrev=4 --pretty=format:"%h" HEAD) 2>/dev/null) && case "$VN" in *$LF*) (exit 1) ;; v[0-9]*) -- cgit v1.2.3 From 0e2af956693a8797d658d076ff4c0da4147f0131 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 30 Oct 2012 09:54:41 +0100 Subject: perf tools: Further speed up the perf build There's another source of overhead in the perf version string generator: git update-index -q --refresh ... which will iterate the whole checked out tree. This can be pretty slow on NFS volumes, but takes some time even with local SSD disks and a fully cached kernel tree: $ perf stat --null --repeat 3 --pre "rm -f PERF-VERSION-FILE" util/PERF-VERSION-GEN PERF_VERSION = 3.7.rc3.g5399b3b.dirty PERF_VERSION = 3.7.rc3.g5399b3b.dirty PERF_VERSION = 3.7.rc3.g5399b3b.dirty Performance counter stats for 'util/PERF-VERSION-GEN' (3 runs): 0.306999221 seconds time elapsed ( +- 0.56% ) So remove the .dirty differentiator as well - it adds little information because locally patched git trees are common, but seldom are the perf tools modified. So a lot of version strings are reported as 'dirty' while in fact they are pristine perf builds. For example 99% of my perf builds are not patched but the kernel tree is slightly patched, which adds the .dirty tag. Eliminating that tag speeds up version generation by another order of magnitude: $ perf stat --null --repeat 3 --sync --pre "rm -f PERF-VERSION-FILE" util/PERF-VERSION-GEN PERF_VERSION = 3.7.rc3.g4b0bd3 PERF_VERSION = 3.7.rc3.g4b0bd3 PERF_VERSION = 3.7.rc3.g4b0bd3 Performance counter stats for 'util/PERF-VERSION-GEN' (3 runs): 0.021270923 seconds time elapsed ( +- 1.94% ) (Also clean up some of the comments around this code.) Signed-off-by: Ingo Molnar Cc: Andrew Vagin Cc: Borislav Petkov Cc: David Howells Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt Link: http://lkml.kernel.org/r/20121030085441.GC8245@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/PERF-VERSION-GEN | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN index f6e8ee29f2a..ac418a1255e 100755 --- a/tools/perf/util/PERF-VERSION-GEN +++ b/tools/perf/util/PERF-VERSION-GEN @@ -9,17 +9,12 @@ GVF=${OUTPUT}PERF-VERSION-FILE LF=' ' +# # First check if there is a .git to get the version from git describe -# otherwise try to get the version from the kernel makefile +# otherwise try to get the version from the kernel Makefile +# if test -d ../../.git -o -f ../../.git && - VN=$(echo $(git tag -l "v[0-9].[0-9]*" | tail -1)"-g"$(git log -1 --abbrev=4 --pretty=format:"%h" HEAD) 2>/dev/null) && - case "$VN" in - *$LF*) (exit 1) ;; - v[0-9]*) - git update-index -q --refresh - test -z "$(git diff-index --name-only HEAD --)" || - VN="$VN-dirty" ;; - esac + VN=$(echo $(git tag -l "v[0-9].[0-9]*" | tail -1)"-g"$(git log -1 --abbrev=4 --pretty=format:"%h" HEAD) 2>/dev/null) then VN=$(echo "$VN" | sed -e 's/-/./g'); else -- cgit v1.2.3 From 688b2c2f17943d48bccbaad4c43430ee68c4c1cd Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 30 Oct 2012 13:44:40 -0200 Subject: perf tools: Handle --version string generation on machines without git If git is installed we'll have a 'perf --version' output of this form: $ make -j8 -C tools/perf/ O=/home/acme/git/build/perf install $ perf --version perf version 3.7.rc3.g3afad6 Now on a machine without git installed: $ mv /home/acme/bin/git /home/acme/bin/git.OFF $ make -j8 -C tools/perf/ O=/home/acme/git/build/perf install $ perf --version perf version 3.7.0-rc2 That is, no error message due to git not being installed will appear on the screen and instead the version string in the top level Makefile will be used. Requested-by: Ingo Molnar Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-am6yp6phvxyjmyndxogpunjv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/PERF-VERSION-GEN | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN index ac418a1255e..6aa34e5afdc 100755 --- a/tools/perf/util/PERF-VERSION-GEN +++ b/tools/perf/util/PERF-VERSION-GEN @@ -14,8 +14,9 @@ LF=' # otherwise try to get the version from the kernel Makefile # if test -d ../../.git -o -f ../../.git && - VN=$(echo $(git tag -l "v[0-9].[0-9]*" | tail -1)"-g"$(git log -1 --abbrev=4 --pretty=format:"%h" HEAD) 2>/dev/null) + VN=$(git tag 2>/dev/null | tail -1 | grep -E "v[0-9].[0-9]*") then + VN=$(echo $VN"-g"$(git log -1 --abbrev=4 --pretty=format:"%h" HEAD)) VN=$(echo "$VN" | sed -e 's/-/./g'); else VN=$(MAKEFLAGS= make -sC ../.. kernelversion) -- cgit v1.2.3 From ffadcf090d468e9c4938b718649f38dd10cfdb02 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 30 Oct 2012 17:34:08 -0700 Subject: perf annotate: Handle XBEGIN like a jump So that the browser still shows the abort label. Signed-off-by: Andi Kleen Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1351643663-23828-18-git-send-email-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 7a34dd18b74..b14d4df9f14 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -401,6 +401,8 @@ static struct ins instructions[] = { { .name = "testb", .ops = &mov_ops, }, { .name = "testl", .ops = &mov_ops, }, { .name = "xadd", .ops = &mov_ops, }, + { .name = "xbeginl", .ops = &jump_ops, }, + { .name = "xbeginq", .ops = &jump_ops, }, }; static int ins__cmp(const void *name, const void *insp) -- cgit v1.2.3 From 35f5149ead73e8e635b417b6c3aece43ffdfe5bc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 31 Oct 2012 15:50:34 +0100 Subject: mac80211: do not call ieee80211_configure_filter if no interfaces are up Drivers are not expected to handle it before drv_start has been called. It will be called again after an interface has been brought up. Signed-off-by: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 05f3a313db8..7371f676cf4 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2594,6 +2594,9 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, else local->probe_req_reg--; + if (!local->open_count) + break; + ieee80211_queue_work(&local->hw, &local->reconfig_filter); break; default: -- cgit v1.2.3 From bca1e29fb54c51856dda6772d488d41b10ed91da Mon Sep 17 00:00:00 2001 From: David Spinadel Date: Mon, 29 Oct 2012 14:49:41 +0200 Subject: mac80211: init sched_scan_ies In case that there is an unsupported band, the ie will be unallocated and the free will crash. Cc: stable@vger.kernel.org Signed-off-by: David Spinadel Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index c4cdbde24fd..43e60b5a754 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -917,7 +917,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, struct cfg80211_sched_scan_request *req) { struct ieee80211_local *local = sdata->local; - struct ieee80211_sched_scan_ies sched_scan_ies; + struct ieee80211_sched_scan_ies sched_scan_ies = {}; int ret, i; mutex_lock(&local->mtx); -- cgit v1.2.3 From dc53eda5a025f3e7503219477a8aefb8842ed74b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:42 +0100 Subject: perf tools: Remove BINDIR define from exec_cmd.o compilation It's not needed. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index b1801e0693c..3e807d7ab8e 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -893,7 +893,6 @@ $(OUTPUT)%.s: %.S $(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \ - '-DBINDIR="$(bindir_relative_SQ)"' \ '-DPREFIX="$(prefix_SQ)"' \ $< -- cgit v1.2.3 From c77d8d7030128e61e206658815b96a6befed9d06 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Thu, 1 Nov 2012 00:00:55 +0800 Subject: perf browser: Don't show scripts menu for 'perf top' As 'perf top' has no data files to run scripts against. Also add a is_report_browser() helper function to judge whether the running browser is for 'perf report'. Signed-off-by: Feng Tang Cc: Andi Kleen Cc: Ingo Molnar Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351699257-5102-1-git-send-email-feng.tang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index fe622845872..082078ae9a6 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -1127,6 +1127,12 @@ static inline void free_popup_options(char **options, int n) } } +/* Check whether the browser is for 'top' or 'report' */ +static inline bool is_report_browser(void *timer) +{ + return timer == NULL; +} + static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, const char *helpline, const char *ev_name, bool left_exits, @@ -1214,7 +1220,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, } continue; case 'r': - goto do_scripts; + if (is_report_browser(timer)) + goto do_scripts; + continue; case K_F1: case 'h': case '?': @@ -1233,7 +1241,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, "E Expand all callchains\n" "d Zoom into current DSO\n" "t Zoom into current Thread\n" - "r Run available scripts\n" + "r Run available scripts('perf report' only)\n" "P Print histograms to perf.hist.N\n" "V Verbose (DSO names in callchains, etc)\n" "/ Filter symbol by name"); -- cgit v1.2.3 From 945aea220bb8f4bb37950549cc0b93bbec24c460 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:43 +0100 Subject: perf tests: Move test objects into 'tests' directory Separating test objects into 'tests' directory. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 9 +- tools/perf/builtin-test.c | 1559 ----------------------------------- tools/perf/tests/builtin-test.c | 1559 +++++++++++++++++++++++++++++++++++ tools/perf/tests/dso-data.c | 153 ++++ tools/perf/tests/parse-events.c | 1116 +++++++++++++++++++++++++ tools/perf/util/dso-test-data.c | 153 ---- tools/perf/util/parse-events-test.c | 1116 ------------------------- 7 files changed, 2833 insertions(+), 2832 deletions(-) delete mode 100644 tools/perf/builtin-test.c create mode 100644 tools/perf/tests/builtin-test.c create mode 100644 tools/perf/tests/dso-data.c create mode 100644 tools/perf/tests/parse-events.c delete mode 100644 tools/perf/util/dso-test-data.c delete mode 100644 tools/perf/util/parse-events-test.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 3e807d7ab8e..2d3427f65b5 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -169,7 +169,7 @@ endif ### --- END CONFIGURATION SECTION --- -BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE +BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -Iutil -I. -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE BASIC_LDFLAGS = ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y) @@ -371,7 +371,6 @@ LIB_OBJS += $(OUTPUT)util/help.o LIB_OBJS += $(OUTPUT)util/levenshtein.o LIB_OBJS += $(OUTPUT)util/parse-options.o LIB_OBJS += $(OUTPUT)util/parse-events.o -LIB_OBJS += $(OUTPUT)util/parse-events-test.o LIB_OBJS += $(OUTPUT)util/path.o LIB_OBJS += $(OUTPUT)util/rbtree.o LIB_OBJS += $(OUTPUT)util/bitmap.o @@ -389,7 +388,6 @@ LIB_OBJS += $(OUTPUT)util/sigchain.o LIB_OBJS += $(OUTPUT)util/dso.o LIB_OBJS += $(OUTPUT)util/symbol.o LIB_OBJS += $(OUTPUT)util/symbol-elf.o -LIB_OBJS += $(OUTPUT)util/dso-test-data.o LIB_OBJS += $(OUTPUT)util/color.o LIB_OBJS += $(OUTPUT)util/pager.o LIB_OBJS += $(OUTPUT)util/header.o @@ -430,6 +428,9 @@ LIB_OBJS += $(OUTPUT)ui/stdio/hist.o LIB_OBJS += $(OUTPUT)arch/common.o +LIB_OBJS += $(OUTPUT)tests/parse-events.o +LIB_OBJS += $(OUTPUT)tests/dso-data.o + BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o BUILTIN_OBJS += $(OUTPUT)builtin-bench.o # Benchmark modules @@ -459,8 +460,8 @@ BUILTIN_OBJS += $(OUTPUT)builtin-probe.o BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o BUILTIN_OBJS += $(OUTPUT)builtin-lock.o BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o -BUILTIN_OBJS += $(OUTPUT)builtin-test.o BUILTIN_OBJS += $(OUTPUT)builtin-inject.o +BUILTIN_OBJS += $(OUTPUT)tests/builtin-test.o PERFLIBS = $(LIB_FILE) $(LIBTRACEEVENT) diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c deleted file mode 100644 index a04276e81f4..00000000000 --- a/tools/perf/builtin-test.c +++ /dev/null @@ -1,1559 +0,0 @@ -/* - * builtin-test.c - * - * Builtin regression testing command: ever growing number of sanity tests - */ -#include "builtin.h" - -#include "util/cache.h" -#include "util/color.h" -#include "util/debug.h" -#include "util/debugfs.h" -#include "util/evlist.h" -#include "util/parse-options.h" -#include "util/parse-events.h" -#include "util/symbol.h" -#include "util/thread_map.h" -#include "util/pmu.h" -#include "event-parse.h" -#include "../../include/linux/hw_breakpoint.h" - -#include - -static int vmlinux_matches_kallsyms_filter(struct map *map __maybe_unused, - struct symbol *sym) -{ - bool *visited = symbol__priv(sym); - *visited = true; - return 0; -} - -static int test__vmlinux_matches_kallsyms(void) -{ - int err = -1; - struct rb_node *nd; - struct symbol *sym; - struct map *kallsyms_map, *vmlinux_map; - struct machine kallsyms, vmlinux; - enum map_type type = MAP__FUNCTION; - struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", }; - - /* - * Step 1: - * - * Init the machines that will hold kernel, modules obtained from - * both vmlinux + .ko files and from /proc/kallsyms split by modules. - */ - machine__init(&kallsyms, "", HOST_KERNEL_ID); - machine__init(&vmlinux, "", HOST_KERNEL_ID); - - /* - * Step 2: - * - * Create the kernel maps for kallsyms and the DSO where we will then - * load /proc/kallsyms. Also create the modules maps from /proc/modules - * and find the .ko files that match them in /lib/modules/`uname -r`/. - */ - if (machine__create_kernel_maps(&kallsyms) < 0) { - pr_debug("machine__create_kernel_maps "); - return -1; - } - - /* - * Step 3: - * - * Load and split /proc/kallsyms into multiple maps, one per module. - */ - if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type, NULL) <= 0) { - pr_debug("dso__load_kallsyms "); - goto out; - } - - /* - * Step 4: - * - * kallsyms will be internally on demand sorted by name so that we can - * find the reference relocation * symbol, i.e. the symbol we will use - * to see if the running kernel was relocated by checking if it has the - * same value in the vmlinux file we load. - */ - kallsyms_map = machine__kernel_map(&kallsyms, type); - - sym = map__find_symbol_by_name(kallsyms_map, ref_reloc_sym.name, NULL); - if (sym == NULL) { - pr_debug("dso__find_symbol_by_name "); - goto out; - } - - ref_reloc_sym.addr = sym->start; - - /* - * Step 5: - * - * Now repeat step 2, this time for the vmlinux file we'll auto-locate. - */ - if (machine__create_kernel_maps(&vmlinux) < 0) { - pr_debug("machine__create_kernel_maps "); - goto out; - } - - vmlinux_map = machine__kernel_map(&vmlinux, type); - map__kmap(vmlinux_map)->ref_reloc_sym = &ref_reloc_sym; - - /* - * Step 6: - * - * Locate a vmlinux file in the vmlinux path that has a buildid that - * matches the one of the running kernel. - * - * While doing that look if we find the ref reloc symbol, if we find it - * we'll have its ref_reloc_symbol.unrelocated_addr and then - * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines - * to fixup the symbols. - */ - if (machine__load_vmlinux_path(&vmlinux, type, - vmlinux_matches_kallsyms_filter) <= 0) { - pr_debug("machine__load_vmlinux_path "); - goto out; - } - - err = 0; - /* - * Step 7: - * - * Now look at the symbols in the vmlinux DSO and check if we find all of them - * in the kallsyms dso. For the ones that are in both, check its names and - * end addresses too. - */ - for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) { - struct symbol *pair, *first_pair; - bool backwards = true; - - sym = rb_entry(nd, struct symbol, rb_node); - - if (sym->start == sym->end) - continue; - - first_pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL); - pair = first_pair; - - if (pair && pair->start == sym->start) { -next_pair: - if (strcmp(sym->name, pair->name) == 0) { - /* - * kallsyms don't have the symbol end, so we - * set that by using the next symbol start - 1, - * in some cases we get this up to a page - * wrong, trace_kmalloc when I was developing - * this code was one such example, 2106 bytes - * off the real size. More than that and we - * _really_ have a problem. - */ - s64 skew = sym->end - pair->end; - if (llabs(skew) < page_size) - continue; - - pr_debug("%#" PRIx64 ": diff end addr for %s v: %#" PRIx64 " k: %#" PRIx64 "\n", - sym->start, sym->name, sym->end, pair->end); - } else { - struct rb_node *nnd; -detour: - nnd = backwards ? rb_prev(&pair->rb_node) : - rb_next(&pair->rb_node); - if (nnd) { - struct symbol *next = rb_entry(nnd, struct symbol, rb_node); - - if (next->start == sym->start) { - pair = next; - goto next_pair; - } - } - - if (backwards) { - backwards = false; - pair = first_pair; - goto detour; - } - - pr_debug("%#" PRIx64 ": diff name v: %s k: %s\n", - sym->start, sym->name, pair->name); - } - } else - pr_debug("%#" PRIx64 ": %s not on kallsyms\n", sym->start, sym->name); - - err = -1; - } - - if (!verbose) - goto out; - - pr_info("Maps only in vmlinux:\n"); - - for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) { - struct map *pos = rb_entry(nd, struct map, rb_node), *pair; - /* - * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while - * the kernel will have the path for the vmlinux file being used, - * so use the short name, less descriptive but the same ("[kernel]" in - * both cases. - */ - pair = map_groups__find_by_name(&kallsyms.kmaps, type, - (pos->dso->kernel ? - pos->dso->short_name : - pos->dso->name)); - if (pair) - pair->priv = 1; - else - map__fprintf(pos, stderr); - } - - pr_info("Maps in vmlinux with a different name in kallsyms:\n"); - - for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) { - struct map *pos = rb_entry(nd, struct map, rb_node), *pair; - - pair = map_groups__find(&kallsyms.kmaps, type, pos->start); - if (pair == NULL || pair->priv) - continue; - - if (pair->start == pos->start) { - pair->priv = 1; - pr_info(" %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as", - pos->start, pos->end, pos->pgoff, pos->dso->name); - if (pos->pgoff != pair->pgoff || pos->end != pair->end) - pr_info(": \n*%" PRIx64 "-%" PRIx64 " %" PRIx64 "", - pair->start, pair->end, pair->pgoff); - pr_info(" %s\n", pair->dso->name); - pair->priv = 1; - } - } - - pr_info("Maps only in kallsyms:\n"); - - for (nd = rb_first(&kallsyms.kmaps.maps[type]); - nd; nd = rb_next(nd)) { - struct map *pos = rb_entry(nd, struct map, rb_node); - - if (!pos->priv) - map__fprintf(pos, stderr); - } -out: - return err; -} - -#include "util/cpumap.h" -#include "util/evsel.h" -#include - -static int trace_event__id(const char *evname) -{ - char *filename; - int err = -1, fd; - - if (asprintf(&filename, - "%s/syscalls/%s/id", - tracing_events_path, evname) < 0) - return -1; - - fd = open(filename, O_RDONLY); - if (fd >= 0) { - char id[16]; - if (read(fd, id, sizeof(id)) > 0) - err = atoi(id); - close(fd); - } - - free(filename); - return err; -} - -static int test__open_syscall_event(void) -{ - int err = -1, fd; - struct thread_map *threads; - struct perf_evsel *evsel; - struct perf_event_attr attr; - unsigned int nr_open_calls = 111, i; - int id = trace_event__id("sys_enter_open"); - - if (id < 0) { - pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); - return -1; - } - - threads = thread_map__new(-1, getpid(), UINT_MAX); - if (threads == NULL) { - pr_debug("thread_map__new\n"); - return -1; - } - - memset(&attr, 0, sizeof(attr)); - attr.type = PERF_TYPE_TRACEPOINT; - attr.config = id; - evsel = perf_evsel__new(&attr, 0); - if (evsel == NULL) { - pr_debug("perf_evsel__new\n"); - goto out_thread_map_delete; - } - - if (perf_evsel__open_per_thread(evsel, threads) < 0) { - pr_debug("failed to open counter: %s, " - "tweak /proc/sys/kernel/perf_event_paranoid?\n", - strerror(errno)); - goto out_evsel_delete; - } - - for (i = 0; i < nr_open_calls; ++i) { - fd = open("/etc/passwd", O_RDONLY); - close(fd); - } - - if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) { - pr_debug("perf_evsel__read_on_cpu\n"); - goto out_close_fd; - } - - if (evsel->counts->cpu[0].val != nr_open_calls) { - pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n", - nr_open_calls, evsel->counts->cpu[0].val); - goto out_close_fd; - } - - err = 0; -out_close_fd: - perf_evsel__close_fd(evsel, 1, threads->nr); -out_evsel_delete: - perf_evsel__delete(evsel); -out_thread_map_delete: - thread_map__delete(threads); - return err; -} - -#include - -static int test__open_syscall_event_on_all_cpus(void) -{ - int err = -1, fd, cpu; - struct thread_map *threads; - struct cpu_map *cpus; - struct perf_evsel *evsel; - struct perf_event_attr attr; - unsigned int nr_open_calls = 111, i; - cpu_set_t cpu_set; - int id = trace_event__id("sys_enter_open"); - - if (id < 0) { - pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); - return -1; - } - - threads = thread_map__new(-1, getpid(), UINT_MAX); - if (threads == NULL) { - pr_debug("thread_map__new\n"); - return -1; - } - - cpus = cpu_map__new(NULL); - if (cpus == NULL) { - pr_debug("cpu_map__new\n"); - goto out_thread_map_delete; - } - - - CPU_ZERO(&cpu_set); - - memset(&attr, 0, sizeof(attr)); - attr.type = PERF_TYPE_TRACEPOINT; - attr.config = id; - evsel = perf_evsel__new(&attr, 0); - if (evsel == NULL) { - pr_debug("perf_evsel__new\n"); - goto out_thread_map_delete; - } - - if (perf_evsel__open(evsel, cpus, threads) < 0) { - pr_debug("failed to open counter: %s, " - "tweak /proc/sys/kernel/perf_event_paranoid?\n", - strerror(errno)); - goto out_evsel_delete; - } - - for (cpu = 0; cpu < cpus->nr; ++cpu) { - unsigned int ncalls = nr_open_calls + cpu; - /* - * XXX eventually lift this restriction in a way that - * keeps perf building on older glibc installations - * without CPU_ALLOC. 1024 cpus in 2010 still seems - * a reasonable upper limit tho :-) - */ - if (cpus->map[cpu] >= CPU_SETSIZE) { - pr_debug("Ignoring CPU %d\n", cpus->map[cpu]); - continue; - } - - CPU_SET(cpus->map[cpu], &cpu_set); - if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { - pr_debug("sched_setaffinity() failed on CPU %d: %s ", - cpus->map[cpu], - strerror(errno)); - goto out_close_fd; - } - for (i = 0; i < ncalls; ++i) { - fd = open("/etc/passwd", O_RDONLY); - close(fd); - } - CPU_CLR(cpus->map[cpu], &cpu_set); - } - - /* - * Here we need to explicitely preallocate the counts, as if - * we use the auto allocation it will allocate just for 1 cpu, - * as we start by cpu 0. - */ - if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) { - pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr); - goto out_close_fd; - } - - err = 0; - - for (cpu = 0; cpu < cpus->nr; ++cpu) { - unsigned int expected; - - if (cpus->map[cpu] >= CPU_SETSIZE) - continue; - - if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) { - pr_debug("perf_evsel__read_on_cpu\n"); - err = -1; - break; - } - - expected = nr_open_calls + cpu; - if (evsel->counts->cpu[cpu].val != expected) { - pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n", - expected, cpus->map[cpu], evsel->counts->cpu[cpu].val); - err = -1; - } - } - -out_close_fd: - perf_evsel__close_fd(evsel, 1, threads->nr); -out_evsel_delete: - perf_evsel__delete(evsel); -out_thread_map_delete: - thread_map__delete(threads); - return err; -} - -/* - * This test will generate random numbers of calls to some getpid syscalls, - * then establish an mmap for a group of events that are created to monitor - * the syscalls. - * - * It will receive the events, using mmap, use its PERF_SAMPLE_ID generated - * sample.id field to map back to its respective perf_evsel instance. - * - * Then it checks if the number of syscalls reported as perf events by - * the kernel corresponds to the number of syscalls made. - */ -static int test__basic_mmap(void) -{ - int err = -1; - union perf_event *event; - struct thread_map *threads; - struct cpu_map *cpus; - struct perf_evlist *evlist; - struct perf_event_attr attr = { - .type = PERF_TYPE_TRACEPOINT, - .read_format = PERF_FORMAT_ID, - .sample_type = PERF_SAMPLE_ID, - .watermark = 0, - }; - cpu_set_t cpu_set; - const char *syscall_names[] = { "getsid", "getppid", "getpgrp", - "getpgid", }; - pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp, - (void*)getpgid }; -#define nsyscalls ARRAY_SIZE(syscall_names) - int ids[nsyscalls]; - unsigned int nr_events[nsyscalls], - expected_nr_events[nsyscalls], i, j; - struct perf_evsel *evsels[nsyscalls], *evsel; - - for (i = 0; i < nsyscalls; ++i) { - char name[64]; - - snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]); - ids[i] = trace_event__id(name); - if (ids[i] < 0) { - pr_debug("Is debugfs mounted on /sys/kernel/debug?\n"); - return -1; - } - nr_events[i] = 0; - expected_nr_events[i] = random() % 257; - } - - threads = thread_map__new(-1, getpid(), UINT_MAX); - if (threads == NULL) { - pr_debug("thread_map__new\n"); - return -1; - } - - cpus = cpu_map__new(NULL); - if (cpus == NULL) { - pr_debug("cpu_map__new\n"); - goto out_free_threads; - } - - CPU_ZERO(&cpu_set); - CPU_SET(cpus->map[0], &cpu_set); - sched_setaffinity(0, sizeof(cpu_set), &cpu_set); - if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { - pr_debug("sched_setaffinity() failed on CPU %d: %s ", - cpus->map[0], strerror(errno)); - goto out_free_cpus; - } - - evlist = perf_evlist__new(cpus, threads); - if (evlist == NULL) { - pr_debug("perf_evlist__new\n"); - goto out_free_cpus; - } - - /* anonymous union fields, can't be initialized above */ - attr.wakeup_events = 1; - attr.sample_period = 1; - - for (i = 0; i < nsyscalls; ++i) { - attr.config = ids[i]; - evsels[i] = perf_evsel__new(&attr, i); - if (evsels[i] == NULL) { - pr_debug("perf_evsel__new\n"); - goto out_free_evlist; - } - - perf_evlist__add(evlist, evsels[i]); - - if (perf_evsel__open(evsels[i], cpus, threads) < 0) { - pr_debug("failed to open counter: %s, " - "tweak /proc/sys/kernel/perf_event_paranoid?\n", - strerror(errno)); - goto out_close_fd; - } - } - - if (perf_evlist__mmap(evlist, 128, true) < 0) { - pr_debug("failed to mmap events: %d (%s)\n", errno, - strerror(errno)); - goto out_close_fd; - } - - for (i = 0; i < nsyscalls; ++i) - for (j = 0; j < expected_nr_events[i]; ++j) { - int foo = syscalls[i](); - ++foo; - } - - while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) { - struct perf_sample sample; - - if (event->header.type != PERF_RECORD_SAMPLE) { - pr_debug("unexpected %s event\n", - perf_event__name(event->header.type)); - goto out_munmap; - } - - err = perf_evlist__parse_sample(evlist, event, &sample); - if (err) { - pr_err("Can't parse sample, err = %d\n", err); - goto out_munmap; - } - - evsel = perf_evlist__id2evsel(evlist, sample.id); - if (evsel == NULL) { - pr_debug("event with id %" PRIu64 - " doesn't map to an evsel\n", sample.id); - goto out_munmap; - } - nr_events[evsel->idx]++; - } - - list_for_each_entry(evsel, &evlist->entries, node) { - if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) { - pr_debug("expected %d %s events, got %d\n", - expected_nr_events[evsel->idx], - perf_evsel__name(evsel), nr_events[evsel->idx]); - goto out_munmap; - } - } - - err = 0; -out_munmap: - perf_evlist__munmap(evlist); -out_close_fd: - for (i = 0; i < nsyscalls; ++i) - perf_evsel__close_fd(evsels[i], 1, threads->nr); -out_free_evlist: - perf_evlist__delete(evlist); -out_free_cpus: - cpu_map__delete(cpus); -out_free_threads: - thread_map__delete(threads); - return err; -#undef nsyscalls -} - -static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t **maskp, - size_t *sizep) -{ - cpu_set_t *mask; - size_t size; - int i, cpu = -1, nrcpus = 1024; -realloc: - mask = CPU_ALLOC(nrcpus); - size = CPU_ALLOC_SIZE(nrcpus); - CPU_ZERO_S(size, mask); - - if (sched_getaffinity(pid, size, mask) == -1) { - CPU_FREE(mask); - if (errno == EINVAL && nrcpus < (1024 << 8)) { - nrcpus = nrcpus << 2; - goto realloc; - } - perror("sched_getaffinity"); - return -1; - } - - for (i = 0; i < nrcpus; i++) { - if (CPU_ISSET_S(i, size, mask)) { - if (cpu == -1) { - cpu = i; - *maskp = mask; - *sizep = size; - } else - CPU_CLR_S(i, size, mask); - } - } - - if (cpu == -1) - CPU_FREE(mask); - - return cpu; -} - -static int test__PERF_RECORD(void) -{ - struct perf_record_opts opts = { - .target = { - .uid = UINT_MAX, - .uses_mmap = true, - }, - .no_delay = true, - .freq = 10, - .mmap_pages = 256, - }; - cpu_set_t *cpu_mask = NULL; - size_t cpu_mask_size = 0; - struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); - struct perf_evsel *evsel; - struct perf_sample sample; - const char *cmd = "sleep"; - const char *argv[] = { cmd, "1", NULL, }; - char *bname; - u64 prev_time = 0; - bool found_cmd_mmap = false, - found_libc_mmap = false, - found_vdso_mmap = false, - found_ld_mmap = false; - int err = -1, errs = 0, i, wakeups = 0; - u32 cpu; - int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, }; - - if (evlist == NULL || argv == NULL) { - pr_debug("Not enough memory to create evlist\n"); - goto out; - } - - /* - * We need at least one evsel in the evlist, use the default - * one: "cycles". - */ - err = perf_evlist__add_default(evlist); - if (err < 0) { - pr_debug("Not enough memory to create evsel\n"); - goto out_delete_evlist; - } - - /* - * Create maps of threads and cpus to monitor. In this case - * we start with all threads and cpus (-1, -1) but then in - * perf_evlist__prepare_workload we'll fill in the only thread - * we're monitoring, the one forked there. - */ - err = perf_evlist__create_maps(evlist, &opts.target); - if (err < 0) { - pr_debug("Not enough memory to create thread/cpu maps\n"); - goto out_delete_evlist; - } - - /* - * Prepare the workload in argv[] to run, it'll fork it, and then wait - * for perf_evlist__start_workload() to exec it. This is done this way - * so that we have time to open the evlist (calling sys_perf_event_open - * on all the fds) and then mmap them. - */ - err = perf_evlist__prepare_workload(evlist, &opts, argv); - if (err < 0) { - pr_debug("Couldn't run the workload!\n"); - goto out_delete_evlist; - } - - /* - * Config the evsels, setting attr->comm on the first one, etc. - */ - evsel = perf_evlist__first(evlist); - evsel->attr.sample_type |= PERF_SAMPLE_CPU; - evsel->attr.sample_type |= PERF_SAMPLE_TID; - evsel->attr.sample_type |= PERF_SAMPLE_TIME; - perf_evlist__config_attrs(evlist, &opts); - - err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask, - &cpu_mask_size); - if (err < 0) { - pr_debug("sched__get_first_possible_cpu: %s\n", strerror(errno)); - goto out_delete_evlist; - } - - cpu = err; - - /* - * So that we can check perf_sample.cpu on all the samples. - */ - if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, cpu_mask) < 0) { - pr_debug("sched_setaffinity: %s\n", strerror(errno)); - goto out_free_cpu_mask; - } - - /* - * Call sys_perf_event_open on all the fds on all the evsels, - * grouping them if asked to. - */ - err = perf_evlist__open(evlist); - if (err < 0) { - pr_debug("perf_evlist__open: %s\n", strerror(errno)); - goto out_delete_evlist; - } - - /* - * mmap the first fd on a given CPU and ask for events for the other - * fds in the same CPU to be injected in the same mmap ring buffer - * (using ioctl(PERF_EVENT_IOC_SET_OUTPUT)). - */ - err = perf_evlist__mmap(evlist, opts.mmap_pages, false); - if (err < 0) { - pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); - goto out_delete_evlist; - } - - /* - * Now that all is properly set up, enable the events, they will - * count just on workload.pid, which will start... - */ - perf_evlist__enable(evlist); - - /* - * Now! - */ - perf_evlist__start_workload(evlist); - - while (1) { - int before = total_events; - - for (i = 0; i < evlist->nr_mmaps; i++) { - union perf_event *event; - - while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { - const u32 type = event->header.type; - const char *name = perf_event__name(type); - - ++total_events; - if (type < PERF_RECORD_MAX) - nr_events[type]++; - - err = perf_evlist__parse_sample(evlist, event, &sample); - if (err < 0) { - if (verbose) - perf_event__fprintf(event, stderr); - pr_debug("Couldn't parse sample\n"); - goto out_err; - } - - if (verbose) { - pr_info("%" PRIu64" %d ", sample.time, sample.cpu); - perf_event__fprintf(event, stderr); - } - - if (prev_time > sample.time) { - pr_debug("%s going backwards in time, prev=%" PRIu64 ", curr=%" PRIu64 "\n", - name, prev_time, sample.time); - ++errs; - } - - prev_time = sample.time; - - if (sample.cpu != cpu) { - pr_debug("%s with unexpected cpu, expected %d, got %d\n", - name, cpu, sample.cpu); - ++errs; - } - - if ((pid_t)sample.pid != evlist->workload.pid) { - pr_debug("%s with unexpected pid, expected %d, got %d\n", - name, evlist->workload.pid, sample.pid); - ++errs; - } - - if ((pid_t)sample.tid != evlist->workload.pid) { - pr_debug("%s with unexpected tid, expected %d, got %d\n", - name, evlist->workload.pid, sample.tid); - ++errs; - } - - if ((type == PERF_RECORD_COMM || - type == PERF_RECORD_MMAP || - type == PERF_RECORD_FORK || - type == PERF_RECORD_EXIT) && - (pid_t)event->comm.pid != evlist->workload.pid) { - pr_debug("%s with unexpected pid/tid\n", name); - ++errs; - } - - if ((type == PERF_RECORD_COMM || - type == PERF_RECORD_MMAP) && - event->comm.pid != event->comm.tid) { - pr_debug("%s with different pid/tid!\n", name); - ++errs; - } - - switch (type) { - case PERF_RECORD_COMM: - if (strcmp(event->comm.comm, cmd)) { - pr_debug("%s with unexpected comm!\n", name); - ++errs; - } - break; - case PERF_RECORD_EXIT: - goto found_exit; - case PERF_RECORD_MMAP: - bname = strrchr(event->mmap.filename, '/'); - if (bname != NULL) { - if (!found_cmd_mmap) - found_cmd_mmap = !strcmp(bname + 1, cmd); - if (!found_libc_mmap) - found_libc_mmap = !strncmp(bname + 1, "libc", 4); - if (!found_ld_mmap) - found_ld_mmap = !strncmp(bname + 1, "ld", 2); - } else if (!found_vdso_mmap) - found_vdso_mmap = !strcmp(event->mmap.filename, "[vdso]"); - break; - - case PERF_RECORD_SAMPLE: - /* Just ignore samples for now */ - break; - default: - pr_debug("Unexpected perf_event->header.type %d!\n", - type); - ++errs; - } - } - } - - /* - * We don't use poll here because at least at 3.1 times the - * PERF_RECORD_{!SAMPLE} events don't honour - * perf_event_attr.wakeup_events, just PERF_EVENT_SAMPLE does. - */ - if (total_events == before && false) - poll(evlist->pollfd, evlist->nr_fds, -1); - - sleep(1); - if (++wakeups > 5) { - pr_debug("No PERF_RECORD_EXIT event!\n"); - break; - } - } - -found_exit: - if (nr_events[PERF_RECORD_COMM] > 1) { - pr_debug("Excessive number of PERF_RECORD_COMM events!\n"); - ++errs; - } - - if (nr_events[PERF_RECORD_COMM] == 0) { - pr_debug("Missing PERF_RECORD_COMM for %s!\n", cmd); - ++errs; - } - - if (!found_cmd_mmap) { - pr_debug("PERF_RECORD_MMAP for %s missing!\n", cmd); - ++errs; - } - - if (!found_libc_mmap) { - pr_debug("PERF_RECORD_MMAP for %s missing!\n", "libc"); - ++errs; - } - - if (!found_ld_mmap) { - pr_debug("PERF_RECORD_MMAP for %s missing!\n", "ld"); - ++errs; - } - - if (!found_vdso_mmap) { - pr_debug("PERF_RECORD_MMAP for %s missing!\n", "[vdso]"); - ++errs; - } -out_err: - perf_evlist__munmap(evlist); -out_free_cpu_mask: - CPU_FREE(cpu_mask); -out_delete_evlist: - perf_evlist__delete(evlist); -out: - return (err < 0 || errs > 0) ? -1 : 0; -} - - -#if defined(__x86_64__) || defined(__i386__) - -#define barrier() asm volatile("" ::: "memory") - -static u64 rdpmc(unsigned int counter) -{ - unsigned int low, high; - - asm volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (counter)); - - return low | ((u64)high) << 32; -} - -static u64 rdtsc(void) -{ - unsigned int low, high; - - asm volatile("rdtsc" : "=a" (low), "=d" (high)); - - return low | ((u64)high) << 32; -} - -static u64 mmap_read_self(void *addr) -{ - struct perf_event_mmap_page *pc = addr; - u32 seq, idx, time_mult = 0, time_shift = 0; - u64 count, cyc = 0, time_offset = 0, enabled, running, delta; - - do { - seq = pc->lock; - barrier(); - - enabled = pc->time_enabled; - running = pc->time_running; - - if (enabled != running) { - cyc = rdtsc(); - time_mult = pc->time_mult; - time_shift = pc->time_shift; - time_offset = pc->time_offset; - } - - idx = pc->index; - count = pc->offset; - if (idx) - count += rdpmc(idx - 1); - - barrier(); - } while (pc->lock != seq); - - if (enabled != running) { - u64 quot, rem; - - quot = (cyc >> time_shift); - rem = cyc & ((1 << time_shift) - 1); - delta = time_offset + quot * time_mult + - ((rem * time_mult) >> time_shift); - - enabled += delta; - if (idx) - running += delta; - - quot = count / running; - rem = count % running; - count = quot * enabled + (rem * enabled) / running; - } - - return count; -} - -/* - * If the RDPMC instruction faults then signal this back to the test parent task: - */ -static void segfault_handler(int sig __maybe_unused, - siginfo_t *info __maybe_unused, - void *uc __maybe_unused) -{ - exit(-1); -} - -static int __test__rdpmc(void) -{ - volatile int tmp = 0; - u64 i, loops = 1000; - int n; - int fd; - void *addr; - struct perf_event_attr attr = { - .type = PERF_TYPE_HARDWARE, - .config = PERF_COUNT_HW_INSTRUCTIONS, - .exclude_kernel = 1, - }; - u64 delta_sum = 0; - struct sigaction sa; - - sigfillset(&sa.sa_mask); - sa.sa_sigaction = segfault_handler; - sigaction(SIGSEGV, &sa, NULL); - - fd = sys_perf_event_open(&attr, 0, -1, -1, 0); - if (fd < 0) { - pr_err("Error: sys_perf_event_open() syscall returned " - "with %d (%s)\n", fd, strerror(errno)); - return -1; - } - - addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0); - if (addr == (void *)(-1)) { - pr_err("Error: mmap() syscall returned with (%s)\n", - strerror(errno)); - goto out_close; - } - - for (n = 0; n < 6; n++) { - u64 stamp, now, delta; - - stamp = mmap_read_self(addr); - - for (i = 0; i < loops; i++) - tmp++; - - now = mmap_read_self(addr); - loops *= 10; - - delta = now - stamp; - pr_debug("%14d: %14Lu\n", n, (long long)delta); - - delta_sum += delta; - } - - munmap(addr, page_size); - pr_debug(" "); -out_close: - close(fd); - - if (!delta_sum) - return -1; - - return 0; -} - -static int test__rdpmc(void) -{ - int status = 0; - int wret = 0; - int ret; - int pid; - - pid = fork(); - if (pid < 0) - return -1; - - if (!pid) { - ret = __test__rdpmc(); - - exit(ret); - } - - wret = waitpid(pid, &status, 0); - if (wret < 0 || status) - return -1; - - return 0; -} - -#endif - -static int test__perf_pmu(void) -{ - return perf_pmu__test(); -} - -static int perf_evsel__roundtrip_cache_name_test(void) -{ - char name[128]; - int type, op, err = 0, ret = 0, i, idx; - struct perf_evsel *evsel; - struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); - - if (evlist == NULL) - return -ENOMEM; - - for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { - for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { - /* skip invalid cache type */ - if (!perf_evsel__is_cache_op_valid(type, op)) - continue; - - for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { - __perf_evsel__hw_cache_type_op_res_name(type, op, i, - name, sizeof(name)); - err = parse_events(evlist, name, 0); - if (err) - ret = err; - } - } - } - - idx = 0; - evsel = perf_evlist__first(evlist); - - for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { - for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { - /* skip invalid cache type */ - if (!perf_evsel__is_cache_op_valid(type, op)) - continue; - - for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { - __perf_evsel__hw_cache_type_op_res_name(type, op, i, - name, sizeof(name)); - if (evsel->idx != idx) - continue; - - ++idx; - - if (strcmp(perf_evsel__name(evsel), name)) { - pr_debug("%s != %s\n", perf_evsel__name(evsel), name); - ret = -1; - } - - evsel = perf_evsel__next(evsel); - } - } - } - - perf_evlist__delete(evlist); - return ret; -} - -static int __perf_evsel__name_array_test(const char *names[], int nr_names) -{ - int i, err; - struct perf_evsel *evsel; - struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); - - if (evlist == NULL) - return -ENOMEM; - - for (i = 0; i < nr_names; ++i) { - err = parse_events(evlist, names[i], 0); - if (err) { - pr_debug("failed to parse event '%s', err %d\n", - names[i], err); - goto out_delete_evlist; - } - } - - err = 0; - list_for_each_entry(evsel, &evlist->entries, node) { - if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) { - --err; - pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]); - } - } - -out_delete_evlist: - perf_evlist__delete(evlist); - return err; -} - -#define perf_evsel__name_array_test(names) \ - __perf_evsel__name_array_test(names, ARRAY_SIZE(names)) - -static int perf_evsel__roundtrip_name_test(void) -{ - int err = 0, ret = 0; - - err = perf_evsel__name_array_test(perf_evsel__hw_names); - if (err) - ret = err; - - err = perf_evsel__name_array_test(perf_evsel__sw_names); - if (err) - ret = err; - - err = perf_evsel__roundtrip_cache_name_test(); - if (err) - ret = err; - - return ret; -} - -static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name, - int size, bool should_be_signed) -{ - struct format_field *field = perf_evsel__field(evsel, name); - int is_signed; - int ret = 0; - - if (field == NULL) { - pr_debug("%s: \"%s\" field not found!\n", evsel->name, name); - return -1; - } - - is_signed = !!(field->flags | FIELD_IS_SIGNED); - if (should_be_signed && !is_signed) { - pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n", - evsel->name, name, is_signed, should_be_signed); - ret = -1; - } - - if (field->size != size) { - pr_debug("%s: \"%s\" size (%d) should be %d!\n", - evsel->name, name, field->size, size); - ret = -1; - } - - return ret; -} - -static int perf_evsel__tp_sched_test(void) -{ - struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch", 0); - int ret = 0; - - if (evsel == NULL) { - pr_debug("perf_evsel__new\n"); - return -1; - } - - if (perf_evsel__test_field(evsel, "prev_comm", 16, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "prev_pid", 4, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "prev_prio", 4, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "prev_state", 8, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "next_comm", 16, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "next_pid", 4, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "next_prio", 4, true)) - ret = -1; - - perf_evsel__delete(evsel); - - evsel = perf_evsel__newtp("sched", "sched_wakeup", 0); - - if (perf_evsel__test_field(evsel, "comm", 16, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "pid", 4, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "prio", 4, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "success", 4, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "target_cpu", 4, true)) - ret = -1; - - return ret; -} - -static int test__syscall_open_tp_fields(void) -{ - struct perf_record_opts opts = { - .target = { - .uid = UINT_MAX, - .uses_mmap = true, - }, - .no_delay = true, - .freq = 1, - .mmap_pages = 256, - .raw_samples = true, - }; - const char *filename = "/etc/passwd"; - int flags = O_RDONLY | O_DIRECTORY; - struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); - struct perf_evsel *evsel; - int err = -1, i, nr_events = 0, nr_polls = 0; - - if (evlist == NULL) { - pr_debug("%s: perf_evlist__new\n", __func__); - goto out; - } - - evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0); - if (evsel == NULL) { - pr_debug("%s: perf_evsel__newtp\n", __func__); - goto out_delete_evlist; - } - - perf_evlist__add(evlist, evsel); - - err = perf_evlist__create_maps(evlist, &opts.target); - if (err < 0) { - pr_debug("%s: perf_evlist__create_maps\n", __func__); - goto out_delete_evlist; - } - - perf_evsel__config(evsel, &opts, evsel); - - evlist->threads->map[0] = getpid(); - - err = perf_evlist__open(evlist); - if (err < 0) { - pr_debug("perf_evlist__open: %s\n", strerror(errno)); - goto out_delete_evlist; - } - - err = perf_evlist__mmap(evlist, UINT_MAX, false); - if (err < 0) { - pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); - goto out_delete_evlist; - } - - perf_evlist__enable(evlist); - - /* - * Generate the event: - */ - open(filename, flags); - - while (1) { - int before = nr_events; - - for (i = 0; i < evlist->nr_mmaps; i++) { - union perf_event *event; - - while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { - const u32 type = event->header.type; - int tp_flags; - struct perf_sample sample; - - ++nr_events; - - if (type != PERF_RECORD_SAMPLE) - continue; - - err = perf_evsel__parse_sample(evsel, event, &sample); - if (err) { - pr_err("Can't parse sample, err = %d\n", err); - goto out_munmap; - } - - tp_flags = perf_evsel__intval(evsel, &sample, "flags"); - - if (flags != tp_flags) { - pr_debug("%s: Expected flags=%#x, got %#x\n", - __func__, flags, tp_flags); - goto out_munmap; - } - - goto out_ok; - } - } - - if (nr_events == before) - poll(evlist->pollfd, evlist->nr_fds, 10); - - if (++nr_polls > 5) { - pr_debug("%s: no events!\n", __func__); - goto out_munmap; - } - } -out_ok: - err = 0; -out_munmap: - perf_evlist__munmap(evlist); -out_delete_evlist: - perf_evlist__delete(evlist); -out: - return err; -} - -static struct test { - const char *desc; - int (*func)(void); -} tests[] = { - { - .desc = "vmlinux symtab matches kallsyms", - .func = test__vmlinux_matches_kallsyms, - }, - { - .desc = "detect open syscall event", - .func = test__open_syscall_event, - }, - { - .desc = "detect open syscall event on all cpus", - .func = test__open_syscall_event_on_all_cpus, - }, - { - .desc = "read samples using the mmap interface", - .func = test__basic_mmap, - }, - { - .desc = "parse events tests", - .func = parse_events__test, - }, -#if defined(__x86_64__) || defined(__i386__) - { - .desc = "x86 rdpmc test", - .func = test__rdpmc, - }, -#endif - { - .desc = "Validate PERF_RECORD_* events & perf_sample fields", - .func = test__PERF_RECORD, - }, - { - .desc = "Test perf pmu format parsing", - .func = test__perf_pmu, - }, - { - .desc = "Test dso data interface", - .func = dso__test_data, - }, - { - .desc = "roundtrip evsel->name check", - .func = perf_evsel__roundtrip_name_test, - }, - { - .desc = "Check parsing of sched tracepoints fields", - .func = perf_evsel__tp_sched_test, - }, - { - .desc = "Generate and check syscalls:sys_enter_open event fields", - .func = test__syscall_open_tp_fields, - }, - { - .func = NULL, - }, -}; - -static bool perf_test__matches(int curr, int argc, const char *argv[]) -{ - int i; - - if (argc == 0) - return true; - - for (i = 0; i < argc; ++i) { - char *end; - long nr = strtoul(argv[i], &end, 10); - - if (*end == '\0') { - if (nr == curr + 1) - return true; - continue; - } - - if (strstr(tests[curr].desc, argv[i])) - return true; - } - - return false; -} - -static int __cmd_test(int argc, const char *argv[]) -{ - int i = 0; - int width = 0; - - while (tests[i].func) { - int len = strlen(tests[i].desc); - - if (width < len) - width = len; - ++i; - } - - i = 0; - while (tests[i].func) { - int curr = i++, err; - - if (!perf_test__matches(curr, argc, argv)) - continue; - - pr_info("%2d: %-*s:", i, width, tests[curr].desc); - pr_debug("\n--- start ---\n"); - err = tests[curr].func(); - pr_debug("---- end ----\n%s:", tests[curr].desc); - if (err) - color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n"); - else - pr_info(" Ok\n"); - } - - return 0; -} - -static int perf_test__list(int argc, const char **argv) -{ - int i = 0; - - while (tests[i].func) { - int curr = i++; - - if (argc > 1 && !strstr(tests[curr].desc, argv[1])) - continue; - - pr_info("%2d: %s\n", i, tests[curr].desc); - } - - return 0; -} - -int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused) -{ - const char * const test_usage[] = { - "perf test [] [{list |[|]}]", - NULL, - }; - const struct option test_options[] = { - OPT_INCR('v', "verbose", &verbose, - "be more verbose (show symbol address, etc)"), - OPT_END() - }; - - argc = parse_options(argc, argv, test_options, test_usage, 0); - if (argc >= 1 && !strcmp(argv[0], "list")) - return perf_test__list(argc, argv); - - symbol_conf.priv_size = sizeof(int); - symbol_conf.sort_by_name = true; - symbol_conf.try_vmlinux_path = true; - - if (symbol__init() < 0) - return -1; - - return __cmd_test(argc, argv); -} diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c new file mode 100644 index 00000000000..f6c642415c4 --- /dev/null +++ b/tools/perf/tests/builtin-test.c @@ -0,0 +1,1559 @@ +/* + * builtin-test.c + * + * Builtin regression testing command: ever growing number of sanity tests + */ +#include "builtin.h" + +#include "util/cache.h" +#include "util/color.h" +#include "util/debug.h" +#include "util/debugfs.h" +#include "util/evlist.h" +#include "util/parse-options.h" +#include "util/parse-events.h" +#include "util/symbol.h" +#include "util/thread_map.h" +#include "util/pmu.h" +#include "event-parse.h" +#include "../../include/linux/hw_breakpoint.h" + +#include + +static int vmlinux_matches_kallsyms_filter(struct map *map __maybe_unused, + struct symbol *sym) +{ + bool *visited = symbol__priv(sym); + *visited = true; + return 0; +} + +static int test__vmlinux_matches_kallsyms(void) +{ + int err = -1; + struct rb_node *nd; + struct symbol *sym; + struct map *kallsyms_map, *vmlinux_map; + struct machine kallsyms, vmlinux; + enum map_type type = MAP__FUNCTION; + struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", }; + + /* + * Step 1: + * + * Init the machines that will hold kernel, modules obtained from + * both vmlinux + .ko files and from /proc/kallsyms split by modules. + */ + machine__init(&kallsyms, "", HOST_KERNEL_ID); + machine__init(&vmlinux, "", HOST_KERNEL_ID); + + /* + * Step 2: + * + * Create the kernel maps for kallsyms and the DSO where we will then + * load /proc/kallsyms. Also create the modules maps from /proc/modules + * and find the .ko files that match them in /lib/modules/`uname -r`/. + */ + if (machine__create_kernel_maps(&kallsyms) < 0) { + pr_debug("machine__create_kernel_maps "); + return -1; + } + + /* + * Step 3: + * + * Load and split /proc/kallsyms into multiple maps, one per module. + */ + if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type, NULL) <= 0) { + pr_debug("dso__load_kallsyms "); + goto out; + } + + /* + * Step 4: + * + * kallsyms will be internally on demand sorted by name so that we can + * find the reference relocation * symbol, i.e. the symbol we will use + * to see if the running kernel was relocated by checking if it has the + * same value in the vmlinux file we load. + */ + kallsyms_map = machine__kernel_map(&kallsyms, type); + + sym = map__find_symbol_by_name(kallsyms_map, ref_reloc_sym.name, NULL); + if (sym == NULL) { + pr_debug("dso__find_symbol_by_name "); + goto out; + } + + ref_reloc_sym.addr = sym->start; + + /* + * Step 5: + * + * Now repeat step 2, this time for the vmlinux file we'll auto-locate. + */ + if (machine__create_kernel_maps(&vmlinux) < 0) { + pr_debug("machine__create_kernel_maps "); + goto out; + } + + vmlinux_map = machine__kernel_map(&vmlinux, type); + map__kmap(vmlinux_map)->ref_reloc_sym = &ref_reloc_sym; + + /* + * Step 6: + * + * Locate a vmlinux file in the vmlinux path that has a buildid that + * matches the one of the running kernel. + * + * While doing that look if we find the ref reloc symbol, if we find it + * we'll have its ref_reloc_symbol.unrelocated_addr and then + * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines + * to fixup the symbols. + */ + if (machine__load_vmlinux_path(&vmlinux, type, + vmlinux_matches_kallsyms_filter) <= 0) { + pr_debug("machine__load_vmlinux_path "); + goto out; + } + + err = 0; + /* + * Step 7: + * + * Now look at the symbols in the vmlinux DSO and check if we find all of them + * in the kallsyms dso. For the ones that are in both, check its names and + * end addresses too. + */ + for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) { + struct symbol *pair, *first_pair; + bool backwards = true; + + sym = rb_entry(nd, struct symbol, rb_node); + + if (sym->start == sym->end) + continue; + + first_pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL); + pair = first_pair; + + if (pair && pair->start == sym->start) { +next_pair: + if (strcmp(sym->name, pair->name) == 0) { + /* + * kallsyms don't have the symbol end, so we + * set that by using the next symbol start - 1, + * in some cases we get this up to a page + * wrong, trace_kmalloc when I was developing + * this code was one such example, 2106 bytes + * off the real size. More than that and we + * _really_ have a problem. + */ + s64 skew = sym->end - pair->end; + if (llabs(skew) < page_size) + continue; + + pr_debug("%#" PRIx64 ": diff end addr for %s v: %#" PRIx64 " k: %#" PRIx64 "\n", + sym->start, sym->name, sym->end, pair->end); + } else { + struct rb_node *nnd; +detour: + nnd = backwards ? rb_prev(&pair->rb_node) : + rb_next(&pair->rb_node); + if (nnd) { + struct symbol *next = rb_entry(nnd, struct symbol, rb_node); + + if (next->start == sym->start) { + pair = next; + goto next_pair; + } + } + + if (backwards) { + backwards = false; + pair = first_pair; + goto detour; + } + + pr_debug("%#" PRIx64 ": diff name v: %s k: %s\n", + sym->start, sym->name, pair->name); + } + } else + pr_debug("%#" PRIx64 ": %s not on kallsyms\n", sym->start, sym->name); + + err = -1; + } + + if (!verbose) + goto out; + + pr_info("Maps only in vmlinux:\n"); + + for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) { + struct map *pos = rb_entry(nd, struct map, rb_node), *pair; + /* + * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while + * the kernel will have the path for the vmlinux file being used, + * so use the short name, less descriptive but the same ("[kernel]" in + * both cases. + */ + pair = map_groups__find_by_name(&kallsyms.kmaps, type, + (pos->dso->kernel ? + pos->dso->short_name : + pos->dso->name)); + if (pair) + pair->priv = 1; + else + map__fprintf(pos, stderr); + } + + pr_info("Maps in vmlinux with a different name in kallsyms:\n"); + + for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) { + struct map *pos = rb_entry(nd, struct map, rb_node), *pair; + + pair = map_groups__find(&kallsyms.kmaps, type, pos->start); + if (pair == NULL || pair->priv) + continue; + + if (pair->start == pos->start) { + pair->priv = 1; + pr_info(" %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as", + pos->start, pos->end, pos->pgoff, pos->dso->name); + if (pos->pgoff != pair->pgoff || pos->end != pair->end) + pr_info(": \n*%" PRIx64 "-%" PRIx64 " %" PRIx64 "", + pair->start, pair->end, pair->pgoff); + pr_info(" %s\n", pair->dso->name); + pair->priv = 1; + } + } + + pr_info("Maps only in kallsyms:\n"); + + for (nd = rb_first(&kallsyms.kmaps.maps[type]); + nd; nd = rb_next(nd)) { + struct map *pos = rb_entry(nd, struct map, rb_node); + + if (!pos->priv) + map__fprintf(pos, stderr); + } +out: + return err; +} + +#include "util/cpumap.h" +#include "util/evsel.h" +#include + +static int trace_event__id(const char *evname) +{ + char *filename; + int err = -1, fd; + + if (asprintf(&filename, + "%s/syscalls/%s/id", + tracing_events_path, evname) < 0) + return -1; + + fd = open(filename, O_RDONLY); + if (fd >= 0) { + char id[16]; + if (read(fd, id, sizeof(id)) > 0) + err = atoi(id); + close(fd); + } + + free(filename); + return err; +} + +static int test__open_syscall_event(void) +{ + int err = -1, fd; + struct thread_map *threads; + struct perf_evsel *evsel; + struct perf_event_attr attr; + unsigned int nr_open_calls = 111, i; + int id = trace_event__id("sys_enter_open"); + + if (id < 0) { + pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); + return -1; + } + + threads = thread_map__new(-1, getpid(), UINT_MAX); + if (threads == NULL) { + pr_debug("thread_map__new\n"); + return -1; + } + + memset(&attr, 0, sizeof(attr)); + attr.type = PERF_TYPE_TRACEPOINT; + attr.config = id; + evsel = perf_evsel__new(&attr, 0); + if (evsel == NULL) { + pr_debug("perf_evsel__new\n"); + goto out_thread_map_delete; + } + + if (perf_evsel__open_per_thread(evsel, threads) < 0) { + pr_debug("failed to open counter: %s, " + "tweak /proc/sys/kernel/perf_event_paranoid?\n", + strerror(errno)); + goto out_evsel_delete; + } + + for (i = 0; i < nr_open_calls; ++i) { + fd = open("/etc/passwd", O_RDONLY); + close(fd); + } + + if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) { + pr_debug("perf_evsel__read_on_cpu\n"); + goto out_close_fd; + } + + if (evsel->counts->cpu[0].val != nr_open_calls) { + pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n", + nr_open_calls, evsel->counts->cpu[0].val); + goto out_close_fd; + } + + err = 0; +out_close_fd: + perf_evsel__close_fd(evsel, 1, threads->nr); +out_evsel_delete: + perf_evsel__delete(evsel); +out_thread_map_delete: + thread_map__delete(threads); + return err; +} + +#include + +static int test__open_syscall_event_on_all_cpus(void) +{ + int err = -1, fd, cpu; + struct thread_map *threads; + struct cpu_map *cpus; + struct perf_evsel *evsel; + struct perf_event_attr attr; + unsigned int nr_open_calls = 111, i; + cpu_set_t cpu_set; + int id = trace_event__id("sys_enter_open"); + + if (id < 0) { + pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); + return -1; + } + + threads = thread_map__new(-1, getpid(), UINT_MAX); + if (threads == NULL) { + pr_debug("thread_map__new\n"); + return -1; + } + + cpus = cpu_map__new(NULL); + if (cpus == NULL) { + pr_debug("cpu_map__new\n"); + goto out_thread_map_delete; + } + + + CPU_ZERO(&cpu_set); + + memset(&attr, 0, sizeof(attr)); + attr.type = PERF_TYPE_TRACEPOINT; + attr.config = id; + evsel = perf_evsel__new(&attr, 0); + if (evsel == NULL) { + pr_debug("perf_evsel__new\n"); + goto out_thread_map_delete; + } + + if (perf_evsel__open(evsel, cpus, threads) < 0) { + pr_debug("failed to open counter: %s, " + "tweak /proc/sys/kernel/perf_event_paranoid?\n", + strerror(errno)); + goto out_evsel_delete; + } + + for (cpu = 0; cpu < cpus->nr; ++cpu) { + unsigned int ncalls = nr_open_calls + cpu; + /* + * XXX eventually lift this restriction in a way that + * keeps perf building on older glibc installations + * without CPU_ALLOC. 1024 cpus in 2010 still seems + * a reasonable upper limit tho :-) + */ + if (cpus->map[cpu] >= CPU_SETSIZE) { + pr_debug("Ignoring CPU %d\n", cpus->map[cpu]); + continue; + } + + CPU_SET(cpus->map[cpu], &cpu_set); + if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { + pr_debug("sched_setaffinity() failed on CPU %d: %s ", + cpus->map[cpu], + strerror(errno)); + goto out_close_fd; + } + for (i = 0; i < ncalls; ++i) { + fd = open("/etc/passwd", O_RDONLY); + close(fd); + } + CPU_CLR(cpus->map[cpu], &cpu_set); + } + + /* + * Here we need to explicitely preallocate the counts, as if + * we use the auto allocation it will allocate just for 1 cpu, + * as we start by cpu 0. + */ + if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) { + pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr); + goto out_close_fd; + } + + err = 0; + + for (cpu = 0; cpu < cpus->nr; ++cpu) { + unsigned int expected; + + if (cpus->map[cpu] >= CPU_SETSIZE) + continue; + + if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) { + pr_debug("perf_evsel__read_on_cpu\n"); + err = -1; + break; + } + + expected = nr_open_calls + cpu; + if (evsel->counts->cpu[cpu].val != expected) { + pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n", + expected, cpus->map[cpu], evsel->counts->cpu[cpu].val); + err = -1; + } + } + +out_close_fd: + perf_evsel__close_fd(evsel, 1, threads->nr); +out_evsel_delete: + perf_evsel__delete(evsel); +out_thread_map_delete: + thread_map__delete(threads); + return err; +} + +/* + * This test will generate random numbers of calls to some getpid syscalls, + * then establish an mmap for a group of events that are created to monitor + * the syscalls. + * + * It will receive the events, using mmap, use its PERF_SAMPLE_ID generated + * sample.id field to map back to its respective perf_evsel instance. + * + * Then it checks if the number of syscalls reported as perf events by + * the kernel corresponds to the number of syscalls made. + */ +static int test__basic_mmap(void) +{ + int err = -1; + union perf_event *event; + struct thread_map *threads; + struct cpu_map *cpus; + struct perf_evlist *evlist; + struct perf_event_attr attr = { + .type = PERF_TYPE_TRACEPOINT, + .read_format = PERF_FORMAT_ID, + .sample_type = PERF_SAMPLE_ID, + .watermark = 0, + }; + cpu_set_t cpu_set; + const char *syscall_names[] = { "getsid", "getppid", "getpgrp", + "getpgid", }; + pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp, + (void*)getpgid }; +#define nsyscalls ARRAY_SIZE(syscall_names) + int ids[nsyscalls]; + unsigned int nr_events[nsyscalls], + expected_nr_events[nsyscalls], i, j; + struct perf_evsel *evsels[nsyscalls], *evsel; + + for (i = 0; i < nsyscalls; ++i) { + char name[64]; + + snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]); + ids[i] = trace_event__id(name); + if (ids[i] < 0) { + pr_debug("Is debugfs mounted on /sys/kernel/debug?\n"); + return -1; + } + nr_events[i] = 0; + expected_nr_events[i] = random() % 257; + } + + threads = thread_map__new(-1, getpid(), UINT_MAX); + if (threads == NULL) { + pr_debug("thread_map__new\n"); + return -1; + } + + cpus = cpu_map__new(NULL); + if (cpus == NULL) { + pr_debug("cpu_map__new\n"); + goto out_free_threads; + } + + CPU_ZERO(&cpu_set); + CPU_SET(cpus->map[0], &cpu_set); + sched_setaffinity(0, sizeof(cpu_set), &cpu_set); + if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { + pr_debug("sched_setaffinity() failed on CPU %d: %s ", + cpus->map[0], strerror(errno)); + goto out_free_cpus; + } + + evlist = perf_evlist__new(cpus, threads); + if (evlist == NULL) { + pr_debug("perf_evlist__new\n"); + goto out_free_cpus; + } + + /* anonymous union fields, can't be initialized above */ + attr.wakeup_events = 1; + attr.sample_period = 1; + + for (i = 0; i < nsyscalls; ++i) { + attr.config = ids[i]; + evsels[i] = perf_evsel__new(&attr, i); + if (evsels[i] == NULL) { + pr_debug("perf_evsel__new\n"); + goto out_free_evlist; + } + + perf_evlist__add(evlist, evsels[i]); + + if (perf_evsel__open(evsels[i], cpus, threads) < 0) { + pr_debug("failed to open counter: %s, " + "tweak /proc/sys/kernel/perf_event_paranoid?\n", + strerror(errno)); + goto out_close_fd; + } + } + + if (perf_evlist__mmap(evlist, 128, true) < 0) { + pr_debug("failed to mmap events: %d (%s)\n", errno, + strerror(errno)); + goto out_close_fd; + } + + for (i = 0; i < nsyscalls; ++i) + for (j = 0; j < expected_nr_events[i]; ++j) { + int foo = syscalls[i](); + ++foo; + } + + while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) { + struct perf_sample sample; + + if (event->header.type != PERF_RECORD_SAMPLE) { + pr_debug("unexpected %s event\n", + perf_event__name(event->header.type)); + goto out_munmap; + } + + err = perf_evlist__parse_sample(evlist, event, &sample); + if (err) { + pr_err("Can't parse sample, err = %d\n", err); + goto out_munmap; + } + + evsel = perf_evlist__id2evsel(evlist, sample.id); + if (evsel == NULL) { + pr_debug("event with id %" PRIu64 + " doesn't map to an evsel\n", sample.id); + goto out_munmap; + } + nr_events[evsel->idx]++; + } + + list_for_each_entry(evsel, &evlist->entries, node) { + if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) { + pr_debug("expected %d %s events, got %d\n", + expected_nr_events[evsel->idx], + perf_evsel__name(evsel), nr_events[evsel->idx]); + goto out_munmap; + } + } + + err = 0; +out_munmap: + perf_evlist__munmap(evlist); +out_close_fd: + for (i = 0; i < nsyscalls; ++i) + perf_evsel__close_fd(evsels[i], 1, threads->nr); +out_free_evlist: + perf_evlist__delete(evlist); +out_free_cpus: + cpu_map__delete(cpus); +out_free_threads: + thread_map__delete(threads); + return err; +#undef nsyscalls +} + +static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t **maskp, + size_t *sizep) +{ + cpu_set_t *mask; + size_t size; + int i, cpu = -1, nrcpus = 1024; +realloc: + mask = CPU_ALLOC(nrcpus); + size = CPU_ALLOC_SIZE(nrcpus); + CPU_ZERO_S(size, mask); + + if (sched_getaffinity(pid, size, mask) == -1) { + CPU_FREE(mask); + if (errno == EINVAL && nrcpus < (1024 << 8)) { + nrcpus = nrcpus << 2; + goto realloc; + } + perror("sched_getaffinity"); + return -1; + } + + for (i = 0; i < nrcpus; i++) { + if (CPU_ISSET_S(i, size, mask)) { + if (cpu == -1) { + cpu = i; + *maskp = mask; + *sizep = size; + } else + CPU_CLR_S(i, size, mask); + } + } + + if (cpu == -1) + CPU_FREE(mask); + + return cpu; +} + +static int test__PERF_RECORD(void) +{ + struct perf_record_opts opts = { + .target = { + .uid = UINT_MAX, + .uses_mmap = true, + }, + .no_delay = true, + .freq = 10, + .mmap_pages = 256, + }; + cpu_set_t *cpu_mask = NULL; + size_t cpu_mask_size = 0; + struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); + struct perf_evsel *evsel; + struct perf_sample sample; + const char *cmd = "sleep"; + const char *argv[] = { cmd, "1", NULL, }; + char *bname; + u64 prev_time = 0; + bool found_cmd_mmap = false, + found_libc_mmap = false, + found_vdso_mmap = false, + found_ld_mmap = false; + int err = -1, errs = 0, i, wakeups = 0; + u32 cpu; + int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, }; + + if (evlist == NULL || argv == NULL) { + pr_debug("Not enough memory to create evlist\n"); + goto out; + } + + /* + * We need at least one evsel in the evlist, use the default + * one: "cycles". + */ + err = perf_evlist__add_default(evlist); + if (err < 0) { + pr_debug("Not enough memory to create evsel\n"); + goto out_delete_evlist; + } + + /* + * Create maps of threads and cpus to monitor. In this case + * we start with all threads and cpus (-1, -1) but then in + * perf_evlist__prepare_workload we'll fill in the only thread + * we're monitoring, the one forked there. + */ + err = perf_evlist__create_maps(evlist, &opts.target); + if (err < 0) { + pr_debug("Not enough memory to create thread/cpu maps\n"); + goto out_delete_evlist; + } + + /* + * Prepare the workload in argv[] to run, it'll fork it, and then wait + * for perf_evlist__start_workload() to exec it. This is done this way + * so that we have time to open the evlist (calling sys_perf_event_open + * on all the fds) and then mmap them. + */ + err = perf_evlist__prepare_workload(evlist, &opts, argv); + if (err < 0) { + pr_debug("Couldn't run the workload!\n"); + goto out_delete_evlist; + } + + /* + * Config the evsels, setting attr->comm on the first one, etc. + */ + evsel = perf_evlist__first(evlist); + evsel->attr.sample_type |= PERF_SAMPLE_CPU; + evsel->attr.sample_type |= PERF_SAMPLE_TID; + evsel->attr.sample_type |= PERF_SAMPLE_TIME; + perf_evlist__config_attrs(evlist, &opts); + + err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask, + &cpu_mask_size); + if (err < 0) { + pr_debug("sched__get_first_possible_cpu: %s\n", strerror(errno)); + goto out_delete_evlist; + } + + cpu = err; + + /* + * So that we can check perf_sample.cpu on all the samples. + */ + if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, cpu_mask) < 0) { + pr_debug("sched_setaffinity: %s\n", strerror(errno)); + goto out_free_cpu_mask; + } + + /* + * Call sys_perf_event_open on all the fds on all the evsels, + * grouping them if asked to. + */ + err = perf_evlist__open(evlist); + if (err < 0) { + pr_debug("perf_evlist__open: %s\n", strerror(errno)); + goto out_delete_evlist; + } + + /* + * mmap the first fd on a given CPU and ask for events for the other + * fds in the same CPU to be injected in the same mmap ring buffer + * (using ioctl(PERF_EVENT_IOC_SET_OUTPUT)). + */ + err = perf_evlist__mmap(evlist, opts.mmap_pages, false); + if (err < 0) { + pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); + goto out_delete_evlist; + } + + /* + * Now that all is properly set up, enable the events, they will + * count just on workload.pid, which will start... + */ + perf_evlist__enable(evlist); + + /* + * Now! + */ + perf_evlist__start_workload(evlist); + + while (1) { + int before = total_events; + + for (i = 0; i < evlist->nr_mmaps; i++) { + union perf_event *event; + + while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { + const u32 type = event->header.type; + const char *name = perf_event__name(type); + + ++total_events; + if (type < PERF_RECORD_MAX) + nr_events[type]++; + + err = perf_evlist__parse_sample(evlist, event, &sample); + if (err < 0) { + if (verbose) + perf_event__fprintf(event, stderr); + pr_debug("Couldn't parse sample\n"); + goto out_err; + } + + if (verbose) { + pr_info("%" PRIu64" %d ", sample.time, sample.cpu); + perf_event__fprintf(event, stderr); + } + + if (prev_time > sample.time) { + pr_debug("%s going backwards in time, prev=%" PRIu64 ", curr=%" PRIu64 "\n", + name, prev_time, sample.time); + ++errs; + } + + prev_time = sample.time; + + if (sample.cpu != cpu) { + pr_debug("%s with unexpected cpu, expected %d, got %d\n", + name, cpu, sample.cpu); + ++errs; + } + + if ((pid_t)sample.pid != evlist->workload.pid) { + pr_debug("%s with unexpected pid, expected %d, got %d\n", + name, evlist->workload.pid, sample.pid); + ++errs; + } + + if ((pid_t)sample.tid != evlist->workload.pid) { + pr_debug("%s with unexpected tid, expected %d, got %d\n", + name, evlist->workload.pid, sample.tid); + ++errs; + } + + if ((type == PERF_RECORD_COMM || + type == PERF_RECORD_MMAP || + type == PERF_RECORD_FORK || + type == PERF_RECORD_EXIT) && + (pid_t)event->comm.pid != evlist->workload.pid) { + pr_debug("%s with unexpected pid/tid\n", name); + ++errs; + } + + if ((type == PERF_RECORD_COMM || + type == PERF_RECORD_MMAP) && + event->comm.pid != event->comm.tid) { + pr_debug("%s with different pid/tid!\n", name); + ++errs; + } + + switch (type) { + case PERF_RECORD_COMM: + if (strcmp(event->comm.comm, cmd)) { + pr_debug("%s with unexpected comm!\n", name); + ++errs; + } + break; + case PERF_RECORD_EXIT: + goto found_exit; + case PERF_RECORD_MMAP: + bname = strrchr(event->mmap.filename, '/'); + if (bname != NULL) { + if (!found_cmd_mmap) + found_cmd_mmap = !strcmp(bname + 1, cmd); + if (!found_libc_mmap) + found_libc_mmap = !strncmp(bname + 1, "libc", 4); + if (!found_ld_mmap) + found_ld_mmap = !strncmp(bname + 1, "ld", 2); + } else if (!found_vdso_mmap) + found_vdso_mmap = !strcmp(event->mmap.filename, "[vdso]"); + break; + + case PERF_RECORD_SAMPLE: + /* Just ignore samples for now */ + break; + default: + pr_debug("Unexpected perf_event->header.type %d!\n", + type); + ++errs; + } + } + } + + /* + * We don't use poll here because at least at 3.1 times the + * PERF_RECORD_{!SAMPLE} events don't honour + * perf_event_attr.wakeup_events, just PERF_EVENT_SAMPLE does. + */ + if (total_events == before && false) + poll(evlist->pollfd, evlist->nr_fds, -1); + + sleep(1); + if (++wakeups > 5) { + pr_debug("No PERF_RECORD_EXIT event!\n"); + break; + } + } + +found_exit: + if (nr_events[PERF_RECORD_COMM] > 1) { + pr_debug("Excessive number of PERF_RECORD_COMM events!\n"); + ++errs; + } + + if (nr_events[PERF_RECORD_COMM] == 0) { + pr_debug("Missing PERF_RECORD_COMM for %s!\n", cmd); + ++errs; + } + + if (!found_cmd_mmap) { + pr_debug("PERF_RECORD_MMAP for %s missing!\n", cmd); + ++errs; + } + + if (!found_libc_mmap) { + pr_debug("PERF_RECORD_MMAP for %s missing!\n", "libc"); + ++errs; + } + + if (!found_ld_mmap) { + pr_debug("PERF_RECORD_MMAP for %s missing!\n", "ld"); + ++errs; + } + + if (!found_vdso_mmap) { + pr_debug("PERF_RECORD_MMAP for %s missing!\n", "[vdso]"); + ++errs; + } +out_err: + perf_evlist__munmap(evlist); +out_free_cpu_mask: + CPU_FREE(cpu_mask); +out_delete_evlist: + perf_evlist__delete(evlist); +out: + return (err < 0 || errs > 0) ? -1 : 0; +} + + +#if defined(__x86_64__) || defined(__i386__) + +#define barrier() asm volatile("" ::: "memory") + +static u64 rdpmc(unsigned int counter) +{ + unsigned int low, high; + + asm volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (counter)); + + return low | ((u64)high) << 32; +} + +static u64 rdtsc(void) +{ + unsigned int low, high; + + asm volatile("rdtsc" : "=a" (low), "=d" (high)); + + return low | ((u64)high) << 32; +} + +static u64 mmap_read_self(void *addr) +{ + struct perf_event_mmap_page *pc = addr; + u32 seq, idx, time_mult = 0, time_shift = 0; + u64 count, cyc = 0, time_offset = 0, enabled, running, delta; + + do { + seq = pc->lock; + barrier(); + + enabled = pc->time_enabled; + running = pc->time_running; + + if (enabled != running) { + cyc = rdtsc(); + time_mult = pc->time_mult; + time_shift = pc->time_shift; + time_offset = pc->time_offset; + } + + idx = pc->index; + count = pc->offset; + if (idx) + count += rdpmc(idx - 1); + + barrier(); + } while (pc->lock != seq); + + if (enabled != running) { + u64 quot, rem; + + quot = (cyc >> time_shift); + rem = cyc & ((1 << time_shift) - 1); + delta = time_offset + quot * time_mult + + ((rem * time_mult) >> time_shift); + + enabled += delta; + if (idx) + running += delta; + + quot = count / running; + rem = count % running; + count = quot * enabled + (rem * enabled) / running; + } + + return count; +} + +/* + * If the RDPMC instruction faults then signal this back to the test parent task: + */ +static void segfault_handler(int sig __maybe_unused, + siginfo_t *info __maybe_unused, + void *uc __maybe_unused) +{ + exit(-1); +} + +static int __test__rdpmc(void) +{ + volatile int tmp = 0; + u64 i, loops = 1000; + int n; + int fd; + void *addr; + struct perf_event_attr attr = { + .type = PERF_TYPE_HARDWARE, + .config = PERF_COUNT_HW_INSTRUCTIONS, + .exclude_kernel = 1, + }; + u64 delta_sum = 0; + struct sigaction sa; + + sigfillset(&sa.sa_mask); + sa.sa_sigaction = segfault_handler; + sigaction(SIGSEGV, &sa, NULL); + + fd = sys_perf_event_open(&attr, 0, -1, -1, 0); + if (fd < 0) { + pr_err("Error: sys_perf_event_open() syscall returned " + "with %d (%s)\n", fd, strerror(errno)); + return -1; + } + + addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0); + if (addr == (void *)(-1)) { + pr_err("Error: mmap() syscall returned with (%s)\n", + strerror(errno)); + goto out_close; + } + + for (n = 0; n < 6; n++) { + u64 stamp, now, delta; + + stamp = mmap_read_self(addr); + + for (i = 0; i < loops; i++) + tmp++; + + now = mmap_read_self(addr); + loops *= 10; + + delta = now - stamp; + pr_debug("%14d: %14Lu\n", n, (long long)delta); + + delta_sum += delta; + } + + munmap(addr, page_size); + pr_debug(" "); +out_close: + close(fd); + + if (!delta_sum) + return -1; + + return 0; +} + +static int test__rdpmc(void) +{ + int status = 0; + int wret = 0; + int ret; + int pid; + + pid = fork(); + if (pid < 0) + return -1; + + if (!pid) { + ret = __test__rdpmc(); + + exit(ret); + } + + wret = waitpid(pid, &status, 0); + if (wret < 0 || status) + return -1; + + return 0; +} + +#endif + +static int test__perf_pmu(void) +{ + return perf_pmu__test(); +} + +static int perf_evsel__roundtrip_cache_name_test(void) +{ + char name[128]; + int type, op, err = 0, ret = 0, i, idx; + struct perf_evsel *evsel; + struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); + + if (evlist == NULL) + return -ENOMEM; + + for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { + for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { + /* skip invalid cache type */ + if (!perf_evsel__is_cache_op_valid(type, op)) + continue; + + for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { + __perf_evsel__hw_cache_type_op_res_name(type, op, i, + name, sizeof(name)); + err = parse_events(evlist, name, 0); + if (err) + ret = err; + } + } + } + + idx = 0; + evsel = perf_evlist__first(evlist); + + for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { + for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { + /* skip invalid cache type */ + if (!perf_evsel__is_cache_op_valid(type, op)) + continue; + + for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { + __perf_evsel__hw_cache_type_op_res_name(type, op, i, + name, sizeof(name)); + if (evsel->idx != idx) + continue; + + ++idx; + + if (strcmp(perf_evsel__name(evsel), name)) { + pr_debug("%s != %s\n", perf_evsel__name(evsel), name); + ret = -1; + } + + evsel = perf_evsel__next(evsel); + } + } + } + + perf_evlist__delete(evlist); + return ret; +} + +static int __perf_evsel__name_array_test(const char *names[], int nr_names) +{ + int i, err; + struct perf_evsel *evsel; + struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); + + if (evlist == NULL) + return -ENOMEM; + + for (i = 0; i < nr_names; ++i) { + err = parse_events(evlist, names[i], 0); + if (err) { + pr_debug("failed to parse event '%s', err %d\n", + names[i], err); + goto out_delete_evlist; + } + } + + err = 0; + list_for_each_entry(evsel, &evlist->entries, node) { + if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) { + --err; + pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]); + } + } + +out_delete_evlist: + perf_evlist__delete(evlist); + return err; +} + +#define perf_evsel__name_array_test(names) \ + __perf_evsel__name_array_test(names, ARRAY_SIZE(names)) + +static int perf_evsel__roundtrip_name_test(void) +{ + int err = 0, ret = 0; + + err = perf_evsel__name_array_test(perf_evsel__hw_names); + if (err) + ret = err; + + err = perf_evsel__name_array_test(perf_evsel__sw_names); + if (err) + ret = err; + + err = perf_evsel__roundtrip_cache_name_test(); + if (err) + ret = err; + + return ret; +} + +static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name, + int size, bool should_be_signed) +{ + struct format_field *field = perf_evsel__field(evsel, name); + int is_signed; + int ret = 0; + + if (field == NULL) { + pr_debug("%s: \"%s\" field not found!\n", evsel->name, name); + return -1; + } + + is_signed = !!(field->flags | FIELD_IS_SIGNED); + if (should_be_signed && !is_signed) { + pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n", + evsel->name, name, is_signed, should_be_signed); + ret = -1; + } + + if (field->size != size) { + pr_debug("%s: \"%s\" size (%d) should be %d!\n", + evsel->name, name, field->size, size); + ret = -1; + } + + return ret; +} + +static int perf_evsel__tp_sched_test(void) +{ + struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch", 0); + int ret = 0; + + if (evsel == NULL) { + pr_debug("perf_evsel__new\n"); + return -1; + } + + if (perf_evsel__test_field(evsel, "prev_comm", 16, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "prev_pid", 4, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "prev_prio", 4, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "prev_state", 8, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "next_comm", 16, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "next_pid", 4, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "next_prio", 4, true)) + ret = -1; + + perf_evsel__delete(evsel); + + evsel = perf_evsel__newtp("sched", "sched_wakeup", 0); + + if (perf_evsel__test_field(evsel, "comm", 16, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "pid", 4, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "prio", 4, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "success", 4, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "target_cpu", 4, true)) + ret = -1; + + return ret; +} + +static int test__syscall_open_tp_fields(void) +{ + struct perf_record_opts opts = { + .target = { + .uid = UINT_MAX, + .uses_mmap = true, + }, + .no_delay = true, + .freq = 1, + .mmap_pages = 256, + .raw_samples = true, + }; + const char *filename = "/etc/passwd"; + int flags = O_RDONLY | O_DIRECTORY; + struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); + struct perf_evsel *evsel; + int err = -1, i, nr_events = 0, nr_polls = 0; + + if (evlist == NULL) { + pr_debug("%s: perf_evlist__new\n", __func__); + goto out; + } + + evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0); + if (evsel == NULL) { + pr_debug("%s: perf_evsel__newtp\n", __func__); + goto out_delete_evlist; + } + + perf_evlist__add(evlist, evsel); + + err = perf_evlist__create_maps(evlist, &opts.target); + if (err < 0) { + pr_debug("%s: perf_evlist__create_maps\n", __func__); + goto out_delete_evlist; + } + + perf_evsel__config(evsel, &opts, evsel); + + evlist->threads->map[0] = getpid(); + + err = perf_evlist__open(evlist); + if (err < 0) { + pr_debug("perf_evlist__open: %s\n", strerror(errno)); + goto out_delete_evlist; + } + + err = perf_evlist__mmap(evlist, UINT_MAX, false); + if (err < 0) { + pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); + goto out_delete_evlist; + } + + perf_evlist__enable(evlist); + + /* + * Generate the event: + */ + open(filename, flags); + + while (1) { + int before = nr_events; + + for (i = 0; i < evlist->nr_mmaps; i++) { + union perf_event *event; + + while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { + const u32 type = event->header.type; + int tp_flags; + struct perf_sample sample; + + ++nr_events; + + if (type != PERF_RECORD_SAMPLE) + continue; + + err = perf_evsel__parse_sample(evsel, event, &sample); + if (err) { + pr_err("Can't parse sample, err = %d\n", err); + goto out_munmap; + } + + tp_flags = perf_evsel__intval(evsel, &sample, "flags"); + + if (flags != tp_flags) { + pr_debug("%s: Expected flags=%#x, got %#x\n", + __func__, flags, tp_flags); + goto out_munmap; + } + + goto out_ok; + } + } + + if (nr_events == before) + poll(evlist->pollfd, evlist->nr_fds, 10); + + if (++nr_polls > 5) { + pr_debug("%s: no events!\n", __func__); + goto out_munmap; + } + } +out_ok: + err = 0; +out_munmap: + perf_evlist__munmap(evlist); +out_delete_evlist: + perf_evlist__delete(evlist); +out: + return err; +} + +static struct test { + const char *desc; + int (*func)(void); +} tests[] = { + { + .desc = "vmlinux symtab matches kallsyms", + .func = test__vmlinux_matches_kallsyms, + }, + { + .desc = "detect open syscall event", + .func = test__open_syscall_event, + }, + { + .desc = "detect open syscall event on all cpus", + .func = test__open_syscall_event_on_all_cpus, + }, + { + .desc = "read samples using the mmap interface", + .func = test__basic_mmap, + }, + { + .desc = "parse events tests", + .func = parse_events__test, + }, +#if defined(__x86_64__) || defined(__i386__) + { + .desc = "x86 rdpmc test", + .func = test__rdpmc, + }, +#endif + { + .desc = "Validate PERF_RECORD_* events & perf_sample fields", + .func = test__PERF_RECORD, + }, + { + .desc = "Test perf pmu format parsing", + .func = test__perf_pmu, + }, + { + .desc = "Test dso data interface", + .func = dso__test_data, + }, + { + .desc = "roundtrip evsel->name check", + .func = perf_evsel__roundtrip_name_test, + }, + { + .desc = "Check parsing of sched tracepoints fields", + .func = perf_evsel__tp_sched_test, + }, + { + .desc = "Generate and check syscalls:sys_enter_open event fields", + .func = test__syscall_open_tp_fields, + }, + { + .func = NULL, + }, +}; + +static bool perf_test__matches(int curr, int argc, const char *argv[]) +{ + int i; + + if (argc == 0) + return true; + + for (i = 0; i < argc; ++i) { + char *end; + long nr = strtoul(argv[i], &end, 10); + + if (*end == '\0') { + if (nr == curr + 1) + return true; + continue; + } + + if (strstr(tests[curr].desc, argv[i])) + return true; + } + + return false; +} + +static int __cmd_test(int argc, const char *argv[]) +{ + int i = 0; + int width = 0; + + while (tests[i].func) { + int len = strlen(tests[i].desc); + + if (width < len) + width = len; + ++i; + } + + i = 0; + while (tests[i].func) { + int curr = i++, err; + + if (!perf_test__matches(curr, argc, argv)) + continue; + + pr_info("%2d: %-*s:", i, width, tests[curr].desc); + pr_debug("\n--- start ---\n"); + err = tests[curr].func(); + pr_debug("---- end ----\n%s:", tests[curr].desc); + if (err) + color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n"); + else + pr_info(" Ok\n"); + } + + return 0; +} + +static int perf_test__list(int argc, const char **argv) +{ + int i = 0; + + while (tests[i].func) { + int curr = i++; + + if (argc > 1 && !strstr(tests[curr].desc, argv[1])) + continue; + + pr_info("%2d: %s\n", i, tests[curr].desc); + } + + return 0; +} + +int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused) +{ + const char * const test_usage[] = { + "perf test [] [{list |[|]}]", + NULL, + }; + const struct option test_options[] = { + OPT_INCR('v', "verbose", &verbose, + "be more verbose (show symbol address, etc)"), + OPT_END() + }; + + argc = parse_options(argc, argv, test_options, test_usage, 0); + if (argc >= 1 && !strcmp(argv[0], "list")) + return perf_test__list(argc, argv); + + symbol_conf.priv_size = sizeof(int); + symbol_conf.sort_by_name = true; + symbol_conf.try_vmlinux_path = true; + + if (symbol__init() < 0) + return -1; + + return __cmd_test(argc, argv); +} diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c new file mode 100644 index 00000000000..c6caedeb1d6 --- /dev/null +++ b/tools/perf/tests/dso-data.c @@ -0,0 +1,153 @@ +#include "util.h" + +#include +#include +#include +#include +#include + +#include "symbol.h" + +#define TEST_ASSERT_VAL(text, cond) \ +do { \ + if (!(cond)) { \ + pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \ + return -1; \ + } \ +} while (0) + +static char *test_file(int size) +{ + static char buf_templ[] = "/tmp/test-XXXXXX"; + char *templ = buf_templ; + int fd, i; + unsigned char *buf; + + fd = mkstemp(templ); + + buf = malloc(size); + if (!buf) { + close(fd); + return NULL; + } + + for (i = 0; i < size; i++) + buf[i] = (unsigned char) ((int) i % 10); + + if (size != write(fd, buf, size)) + templ = NULL; + + close(fd); + return templ; +} + +#define TEST_FILE_SIZE (DSO__DATA_CACHE_SIZE * 20) + +struct test_data_offset { + off_t offset; + u8 data[10]; + int size; +}; + +struct test_data_offset offsets[] = { + /* Fill first cache page. */ + { + .offset = 10, + .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + .size = 10, + }, + /* Read first cache page. */ + { + .offset = 10, + .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + .size = 10, + }, + /* Fill cache boundary pages. */ + { + .offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10, + .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + .size = 10, + }, + /* Read cache boundary pages. */ + { + .offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10, + .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + .size = 10, + }, + /* Fill final cache page. */ + { + .offset = TEST_FILE_SIZE - 10, + .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + .size = 10, + }, + /* Read final cache page. */ + { + .offset = TEST_FILE_SIZE - 10, + .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, + .size = 10, + }, + /* Read final cache page. */ + { + .offset = TEST_FILE_SIZE - 3, + .data = { 7, 8, 9, 0, 0, 0, 0, 0, 0, 0 }, + .size = 3, + }, +}; + +int dso__test_data(void) +{ + struct machine machine; + struct dso *dso; + char *file = test_file(TEST_FILE_SIZE); + size_t i; + + TEST_ASSERT_VAL("No test file", file); + + memset(&machine, 0, sizeof(machine)); + + dso = dso__new((const char *)file); + + /* Basic 10 bytes tests. */ + for (i = 0; i < ARRAY_SIZE(offsets); i++) { + struct test_data_offset *data = &offsets[i]; + ssize_t size; + u8 buf[10]; + + memset(buf, 0, 10); + size = dso__data_read_offset(dso, &machine, data->offset, + buf, 10); + + TEST_ASSERT_VAL("Wrong size", size == data->size); + TEST_ASSERT_VAL("Wrong data", !memcmp(buf, data->data, 10)); + } + + /* Read cross multiple cache pages. */ + { + ssize_t size; + int c; + u8 *buf; + + buf = malloc(TEST_FILE_SIZE); + TEST_ASSERT_VAL("ENOMEM\n", buf); + + /* First iteration to fill caches, second one to read them. */ + for (c = 0; c < 2; c++) { + memset(buf, 0, TEST_FILE_SIZE); + size = dso__data_read_offset(dso, &machine, 10, + buf, TEST_FILE_SIZE); + + TEST_ASSERT_VAL("Wrong size", + size == (TEST_FILE_SIZE - 10)); + + for (i = 0; i < (size_t)size; i++) + TEST_ASSERT_VAL("Wrong data", + buf[i] == (i % 10)); + } + + free(buf); + } + + dso__delete(dso); + unlink(file); + return 0; +} diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c new file mode 100644 index 00000000000..b49c2eebff3 --- /dev/null +++ b/tools/perf/tests/parse-events.c @@ -0,0 +1,1116 @@ + +#include "parse-events.h" +#include "evsel.h" +#include "evlist.h" +#include "sysfs.h" +#include "../../../include/linux/hw_breakpoint.h" + +#define TEST_ASSERT_VAL(text, cond) \ +do { \ + if (!(cond)) { \ + pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \ + return -1; \ + } \ +} while (0) + +#define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \ + PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD) + +static int test__checkevent_tracepoint(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong sample_type", + PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); + TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); + return 0; +} + +static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel; + + TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); + + list_for_each_entry(evsel, &evlist->entries, node) { + TEST_ASSERT_VAL("wrong type", + PERF_TYPE_TRACEPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong sample_type", + PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); + TEST_ASSERT_VAL("wrong sample_period", + 1 == evsel->attr.sample_period); + } + return 0; +} + +static int test__checkevent_raw(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 0x1a == evsel->attr.config); + return 0; +} + +static int test__checkevent_numeric(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); + return 0; +} + +static int test__checkevent_symbolic_name(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); + return 0; +} + +static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); + TEST_ASSERT_VAL("wrong period", + 100000 == evsel->attr.sample_period); + TEST_ASSERT_VAL("wrong config1", + 0 == evsel->attr.config1); + TEST_ASSERT_VAL("wrong config2", + 1 == evsel->attr.config2); + return 0; +} + +static int test__checkevent_symbolic_alias(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config); + return 0; +} + +static int test__checkevent_genhw(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->attr.config); + return 0; +} + +static int test__checkevent_breakpoint(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) == + evsel->attr.bp_type); + TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_4 == + evsel->attr.bp_len); + return 0; +} + +static int test__checkevent_breakpoint_x(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + TEST_ASSERT_VAL("wrong bp_type", + HW_BREAKPOINT_X == evsel->attr.bp_type); + TEST_ASSERT_VAL("wrong bp_len", sizeof(long) == evsel->attr.bp_len); + return 0; +} + +static int test__checkevent_breakpoint_r(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", + PERF_TYPE_BREAKPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + TEST_ASSERT_VAL("wrong bp_type", + HW_BREAKPOINT_R == evsel->attr.bp_type); + TEST_ASSERT_VAL("wrong bp_len", + HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); + return 0; +} + +static int test__checkevent_breakpoint_w(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", + PERF_TYPE_BREAKPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + TEST_ASSERT_VAL("wrong bp_type", + HW_BREAKPOINT_W == evsel->attr.bp_type); + TEST_ASSERT_VAL("wrong bp_len", + HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); + return 0; +} + +static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", + PERF_TYPE_BREAKPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); + TEST_ASSERT_VAL("wrong bp_type", + (HW_BREAKPOINT_R|HW_BREAKPOINT_W) == evsel->attr.bp_type); + TEST_ASSERT_VAL("wrong bp_len", + HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); + return 0; +} + +static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + + return test__checkevent_tracepoint(evlist); +} + +static int +test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel; + + TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); + + list_for_each_entry(evsel, &evlist->entries, node) { + TEST_ASSERT_VAL("wrong exclude_user", + !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", + evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + } + + return test__checkevent_tracepoint_multi(evlist); +} + +static int test__checkevent_raw_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + + return test__checkevent_raw(evlist); +} + +static int test__checkevent_numeric_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + + return test__checkevent_numeric(evlist); +} + +static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + + return test__checkevent_symbolic_name(evlist); +} + +static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); + + return test__checkevent_symbolic_name(evlist); +} + +static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + + return test__checkevent_symbolic_name(evlist); +} + +static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + + return test__checkevent_symbolic_alias(evlist); +} + +static int test__checkevent_genhw_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + + return test__checkevent_genhw(evlist); +} + +static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong name", + !strcmp(perf_evsel__name(evsel), "mem:0:u")); + + return test__checkevent_breakpoint(evlist); +} + +static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong name", + !strcmp(perf_evsel__name(evsel), "mem:0:x:k")); + + return test__checkevent_breakpoint_x(evlist); +} + +static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong name", + !strcmp(perf_evsel__name(evsel), "mem:0:r:hp")); + + return test__checkevent_breakpoint_r(evlist); +} + +static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong name", + !strcmp(perf_evsel__name(evsel), "mem:0:w:up")); + + return test__checkevent_breakpoint_w(evlist); +} + +static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong name", + !strcmp(perf_evsel__name(evsel), "mem:0:rw:kp")); + + return test__checkevent_breakpoint_rw(evlist); +} + +static int test__checkevent_pmu(struct perf_evlist *evlist) +{ + + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 10 == evsel->attr.config); + TEST_ASSERT_VAL("wrong config1", 1 == evsel->attr.config1); + TEST_ASSERT_VAL("wrong config2", 3 == evsel->attr.config2); + TEST_ASSERT_VAL("wrong period", 1000 == evsel->attr.sample_period); + + return 0; +} + +static int test__checkevent_list(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); + + /* r1 */ + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); + TEST_ASSERT_VAL("wrong config1", 0 == evsel->attr.config1); + TEST_ASSERT_VAL("wrong config2", 0 == evsel->attr.config2); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + + /* syscalls:sys_enter_open:k */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong sample_type", + PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); + TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + + /* 1:1:hp */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); + + return 0; +} + +static int test__checkevent_pmu_name(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel = perf_evlist__first(evlist); + + /* cpu/config=1,name=krava/u */ + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); + TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava")); + + /* cpu/config=2/u" */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); + TEST_ASSERT_VAL("wrong name", + !strcmp(perf_evsel__name(evsel), "cpu/config=2/u")); + + return 0; +} + +static int test__checkevent_pmu_events(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel; + + evsel = list_entry(evlist->entries.next, struct perf_evsel, node); + TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); + TEST_ASSERT_VAL("wrong exclude_user", + !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", + evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + + return 0; +} + +static int test__checkterms_simple(struct list_head *terms) +{ + struct parse_events__term *term; + + /* config=10 */ + term = list_entry(terms->next, struct parse_events__term, list); + TEST_ASSERT_VAL("wrong type term", + term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG); + TEST_ASSERT_VAL("wrong type val", + term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); + TEST_ASSERT_VAL("wrong val", term->val.num == 10); + TEST_ASSERT_VAL("wrong config", !term->config); + + /* config1 */ + term = list_entry(term->list.next, struct parse_events__term, list); + TEST_ASSERT_VAL("wrong type term", + term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG1); + TEST_ASSERT_VAL("wrong type val", + term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); + TEST_ASSERT_VAL("wrong val", term->val.num == 1); + TEST_ASSERT_VAL("wrong config", !term->config); + + /* config2=3 */ + term = list_entry(term->list.next, struct parse_events__term, list); + TEST_ASSERT_VAL("wrong type term", + term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG2); + TEST_ASSERT_VAL("wrong type val", + term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); + TEST_ASSERT_VAL("wrong val", term->val.num == 3); + TEST_ASSERT_VAL("wrong config", !term->config); + + /* umask=1*/ + term = list_entry(term->list.next, struct parse_events__term, list); + TEST_ASSERT_VAL("wrong type term", + term->type_term == PARSE_EVENTS__TERM_TYPE_USER); + TEST_ASSERT_VAL("wrong type val", + term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); + TEST_ASSERT_VAL("wrong val", term->val.num == 1); + TEST_ASSERT_VAL("wrong config", !strcmp(term->config, "umask")); + + return 0; +} + +static int test__group1(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel, *leader; + + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + + /* instructions:k */ + evsel = leader = perf_evlist__first(evlist); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + + /* cycles:upp */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + /* use of precise requires exclude_guest */ + TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2); + TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); + + return 0; +} + +static int test__group2(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel, *leader; + + TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); + + /* faults + :ku modifier */ + evsel = leader = perf_evlist__first(evlist); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + + /* cache-references + :u modifier */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_CACHE_REFERENCES == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); + + /* cycles:k */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + + return 0; +} + +static int test__group3(struct perf_evlist *evlist __maybe_unused) +{ + struct perf_evsel *evsel, *leader; + + TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries); + + /* group1 syscalls:sys_enter_open:H */ + evsel = leader = perf_evlist__first(evlist); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); + TEST_ASSERT_VAL("wrong sample_type", + PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); + TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + TEST_ASSERT_VAL("wrong group name", + !strcmp(leader->group_name, "group1")); + + /* group1 cycles:kppp */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + /* use of precise requires exclude_guest */ + TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 3); + TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); + TEST_ASSERT_VAL("wrong group name", !evsel->group_name); + + /* group2 cycles + G modifier */ + evsel = leader = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + TEST_ASSERT_VAL("wrong group name", + !strcmp(leader->group_name, "group2")); + + /* group2 1:3 + G modifier */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", 3 == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); + + /* instructions:u */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + + return 0; +} + +static int test__group4(struct perf_evlist *evlist __maybe_unused) +{ + struct perf_evsel *evsel, *leader; + + TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); + + /* cycles:u + p */ + evsel = leader = perf_evlist__first(evlist); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + /* use of precise requires exclude_guest */ + TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 1); + TEST_ASSERT_VAL("wrong group name", !evsel->group_name); + TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + + /* instructions:kp + p */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); + /* use of precise requires exclude_guest */ + TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2); + TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); + + return 0; +} + +static int test__group5(struct perf_evlist *evlist __maybe_unused) +{ + struct perf_evsel *evsel, *leader; + + TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries); + + /* cycles + G */ + evsel = leader = perf_evlist__first(evlist); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong group name", !evsel->group_name); + TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + + /* instructions + G */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); + + /* cycles:G */ + evsel = leader = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong group name", !evsel->group_name); + TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + + /* instructions:G */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); + + /* cycles */ + evsel = perf_evsel__next(evsel); + TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); + TEST_ASSERT_VAL("wrong config", + PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); + TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); + TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); + TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); + TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); + TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); + TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); + TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + + return 0; +} + +struct test__event_st { + const char *name; + __u32 type; + int (*check)(struct perf_evlist *evlist); +}; + +static struct test__event_st test__events[] = { + [0] = { + .name = "syscalls:sys_enter_open", + .check = test__checkevent_tracepoint, + }, + [1] = { + .name = "syscalls:*", + .check = test__checkevent_tracepoint_multi, + }, + [2] = { + .name = "r1a", + .check = test__checkevent_raw, + }, + [3] = { + .name = "1:1", + .check = test__checkevent_numeric, + }, + [4] = { + .name = "instructions", + .check = test__checkevent_symbolic_name, + }, + [5] = { + .name = "cycles/period=100000,config2/", + .check = test__checkevent_symbolic_name_config, + }, + [6] = { + .name = "faults", + .check = test__checkevent_symbolic_alias, + }, + [7] = { + .name = "L1-dcache-load-miss", + .check = test__checkevent_genhw, + }, + [8] = { + .name = "mem:0", + .check = test__checkevent_breakpoint, + }, + [9] = { + .name = "mem:0:x", + .check = test__checkevent_breakpoint_x, + }, + [10] = { + .name = "mem:0:r", + .check = test__checkevent_breakpoint_r, + }, + [11] = { + .name = "mem:0:w", + .check = test__checkevent_breakpoint_w, + }, + [12] = { + .name = "syscalls:sys_enter_open:k", + .check = test__checkevent_tracepoint_modifier, + }, + [13] = { + .name = "syscalls:*:u", + .check = test__checkevent_tracepoint_multi_modifier, + }, + [14] = { + .name = "r1a:kp", + .check = test__checkevent_raw_modifier, + }, + [15] = { + .name = "1:1:hp", + .check = test__checkevent_numeric_modifier, + }, + [16] = { + .name = "instructions:h", + .check = test__checkevent_symbolic_name_modifier, + }, + [17] = { + .name = "faults:u", + .check = test__checkevent_symbolic_alias_modifier, + }, + [18] = { + .name = "L1-dcache-load-miss:kp", + .check = test__checkevent_genhw_modifier, + }, + [19] = { + .name = "mem:0:u", + .check = test__checkevent_breakpoint_modifier, + }, + [20] = { + .name = "mem:0:x:k", + .check = test__checkevent_breakpoint_x_modifier, + }, + [21] = { + .name = "mem:0:r:hp", + .check = test__checkevent_breakpoint_r_modifier, + }, + [22] = { + .name = "mem:0:w:up", + .check = test__checkevent_breakpoint_w_modifier, + }, + [23] = { + .name = "r1,syscalls:sys_enter_open:k,1:1:hp", + .check = test__checkevent_list, + }, + [24] = { + .name = "instructions:G", + .check = test__checkevent_exclude_host_modifier, + }, + [25] = { + .name = "instructions:H", + .check = test__checkevent_exclude_guest_modifier, + }, + [26] = { + .name = "mem:0:rw", + .check = test__checkevent_breakpoint_rw, + }, + [27] = { + .name = "mem:0:rw:kp", + .check = test__checkevent_breakpoint_rw_modifier, + }, + [28] = { + .name = "{instructions:k,cycles:upp}", + .check = test__group1, + }, + [29] = { + .name = "{faults:k,cache-references}:u,cycles:k", + .check = test__group2, + }, + [30] = { + .name = "group1{syscalls:sys_enter_open:H,cycles:kppp},group2{cycles,1:3}:G,instructions:u", + .check = test__group3, + }, + [31] = { + .name = "{cycles:u,instructions:kp}:p", + .check = test__group4, + }, + [32] = { + .name = "{cycles,instructions}:G,{cycles:G,instructions:G},cycles", + .check = test__group5, + }, +}; + +static struct test__event_st test__events_pmu[] = { + [0] = { + .name = "cpu/config=10,config1,config2=3,period=1000/u", + .check = test__checkevent_pmu, + }, + [1] = { + .name = "cpu/config=1,name=krava/u,cpu/config=2/u", + .check = test__checkevent_pmu_name, + }, +}; + +struct test__term { + const char *str; + __u32 type; + int (*check)(struct list_head *terms); +}; + +static struct test__term test__terms[] = { + [0] = { + .str = "config=10,config1,config2=3,umask=1", + .check = test__checkterms_simple, + }, +}; + +static int test_event(struct test__event_st *e) +{ + struct perf_evlist *evlist; + int ret; + + evlist = perf_evlist__new(NULL, NULL); + if (evlist == NULL) + return -ENOMEM; + + ret = parse_events(evlist, e->name, 0); + if (ret) { + pr_debug("failed to parse event '%s', err %d\n", + e->name, ret); + return ret; + } + + ret = e->check(evlist); + perf_evlist__delete(evlist); + + return ret; +} + +static int test_events(struct test__event_st *events, unsigned cnt) +{ + int ret1, ret2 = 0; + unsigned i; + + for (i = 0; i < cnt; i++) { + struct test__event_st *e = &events[i]; + + pr_debug("running test %d '%s'\n", i, e->name); + ret1 = test_event(e); + if (ret1) + ret2 = ret1; + } + + return ret2; +} + +static int test_term(struct test__term *t) +{ + struct list_head *terms; + int ret; + + terms = malloc(sizeof(*terms)); + if (!terms) + return -ENOMEM; + + INIT_LIST_HEAD(terms); + + ret = parse_events_terms(terms, t->str); + if (ret) { + pr_debug("failed to parse terms '%s', err %d\n", + t->str , ret); + return ret; + } + + ret = t->check(terms); + parse_events__free_terms(terms); + + return ret; +} + +static int test_terms(struct test__term *terms, unsigned cnt) +{ + int ret = 0; + unsigned i; + + for (i = 0; i < cnt; i++) { + struct test__term *t = &terms[i]; + + pr_debug("running test %d '%s'\n", i, t->str); + ret = test_term(t); + if (ret) + break; + } + + return ret; +} + +static int test_pmu(void) +{ + struct stat st; + char path[PATH_MAX]; + int ret; + + snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/format/", + sysfs_find_mountpoint()); + + ret = stat(path, &st); + if (ret) + pr_debug("omitting PMU cpu tests\n"); + return !ret; +} + +static int test_pmu_events(void) +{ + struct stat st; + char path[PATH_MAX]; + struct dirent *ent; + DIR *dir; + int ret; + + snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/events/", + sysfs_find_mountpoint()); + + ret = stat(path, &st); + if (ret) { + pr_debug("ommiting PMU cpu events tests\n"); + return 0; + } + + dir = opendir(path); + if (!dir) { + pr_debug("can't open pmu event dir"); + return -1; + } + + while (!ret && (ent = readdir(dir))) { +#define MAX_NAME 100 + struct test__event_st e; + char name[MAX_NAME]; + + if (!strcmp(ent->d_name, ".") || + !strcmp(ent->d_name, "..")) + continue; + + snprintf(name, MAX_NAME, "cpu/event=%s/u", ent->d_name); + + e.name = name; + e.check = test__checkevent_pmu_events; + + ret = test_event(&e); +#undef MAX_NAME + } + + closedir(dir); + return ret; +} + +int parse_events__test(void) +{ + int ret1, ret2 = 0; + +#define TEST_EVENTS(tests) \ +do { \ + ret1 = test_events(tests, ARRAY_SIZE(tests)); \ + if (!ret2) \ + ret2 = ret1; \ +} while (0) + + TEST_EVENTS(test__events); + + if (test_pmu()) + TEST_EVENTS(test__events_pmu); + + if (test_pmu()) { + int ret = test_pmu_events(); + if (ret) + return ret; + } + + ret1 = test_terms(test__terms, ARRAY_SIZE(test__terms)); + if (!ret2) + ret2 = ret1; + + return ret2; +} diff --git a/tools/perf/util/dso-test-data.c b/tools/perf/util/dso-test-data.c deleted file mode 100644 index c6caedeb1d6..00000000000 --- a/tools/perf/util/dso-test-data.c +++ /dev/null @@ -1,153 +0,0 @@ -#include "util.h" - -#include -#include -#include -#include -#include - -#include "symbol.h" - -#define TEST_ASSERT_VAL(text, cond) \ -do { \ - if (!(cond)) { \ - pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \ - return -1; \ - } \ -} while (0) - -static char *test_file(int size) -{ - static char buf_templ[] = "/tmp/test-XXXXXX"; - char *templ = buf_templ; - int fd, i; - unsigned char *buf; - - fd = mkstemp(templ); - - buf = malloc(size); - if (!buf) { - close(fd); - return NULL; - } - - for (i = 0; i < size; i++) - buf[i] = (unsigned char) ((int) i % 10); - - if (size != write(fd, buf, size)) - templ = NULL; - - close(fd); - return templ; -} - -#define TEST_FILE_SIZE (DSO__DATA_CACHE_SIZE * 20) - -struct test_data_offset { - off_t offset; - u8 data[10]; - int size; -}; - -struct test_data_offset offsets[] = { - /* Fill first cache page. */ - { - .offset = 10, - .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, - .size = 10, - }, - /* Read first cache page. */ - { - .offset = 10, - .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, - .size = 10, - }, - /* Fill cache boundary pages. */ - { - .offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10, - .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, - .size = 10, - }, - /* Read cache boundary pages. */ - { - .offset = DSO__DATA_CACHE_SIZE - DSO__DATA_CACHE_SIZE % 10, - .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, - .size = 10, - }, - /* Fill final cache page. */ - { - .offset = TEST_FILE_SIZE - 10, - .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, - .size = 10, - }, - /* Read final cache page. */ - { - .offset = TEST_FILE_SIZE - 10, - .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, - .size = 10, - }, - /* Read final cache page. */ - { - .offset = TEST_FILE_SIZE - 3, - .data = { 7, 8, 9, 0, 0, 0, 0, 0, 0, 0 }, - .size = 3, - }, -}; - -int dso__test_data(void) -{ - struct machine machine; - struct dso *dso; - char *file = test_file(TEST_FILE_SIZE); - size_t i; - - TEST_ASSERT_VAL("No test file", file); - - memset(&machine, 0, sizeof(machine)); - - dso = dso__new((const char *)file); - - /* Basic 10 bytes tests. */ - for (i = 0; i < ARRAY_SIZE(offsets); i++) { - struct test_data_offset *data = &offsets[i]; - ssize_t size; - u8 buf[10]; - - memset(buf, 0, 10); - size = dso__data_read_offset(dso, &machine, data->offset, - buf, 10); - - TEST_ASSERT_VAL("Wrong size", size == data->size); - TEST_ASSERT_VAL("Wrong data", !memcmp(buf, data->data, 10)); - } - - /* Read cross multiple cache pages. */ - { - ssize_t size; - int c; - u8 *buf; - - buf = malloc(TEST_FILE_SIZE); - TEST_ASSERT_VAL("ENOMEM\n", buf); - - /* First iteration to fill caches, second one to read them. */ - for (c = 0; c < 2; c++) { - memset(buf, 0, TEST_FILE_SIZE); - size = dso__data_read_offset(dso, &machine, 10, - buf, TEST_FILE_SIZE); - - TEST_ASSERT_VAL("Wrong size", - size == (TEST_FILE_SIZE - 10)); - - for (i = 0; i < (size_t)size; i++) - TEST_ASSERT_VAL("Wrong data", - buf[i] == (i % 10)); - } - - free(buf); - } - - dso__delete(dso); - unlink(file); - return 0; -} diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c deleted file mode 100644 index b49c2eebff3..00000000000 --- a/tools/perf/util/parse-events-test.c +++ /dev/null @@ -1,1116 +0,0 @@ - -#include "parse-events.h" -#include "evsel.h" -#include "evlist.h" -#include "sysfs.h" -#include "../../../include/linux/hw_breakpoint.h" - -#define TEST_ASSERT_VAL(text, cond) \ -do { \ - if (!(cond)) { \ - pr_debug("FAILED %s:%d %s\n", __FILE__, __LINE__, text); \ - return -1; \ - } \ -} while (0) - -#define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \ - PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD) - -static int test__checkevent_tracepoint(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong sample_type", - PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); - TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); - return 0; -} - -static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel; - - TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); - - list_for_each_entry(evsel, &evlist->entries, node) { - TEST_ASSERT_VAL("wrong type", - PERF_TYPE_TRACEPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong sample_type", - PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); - TEST_ASSERT_VAL("wrong sample_period", - 1 == evsel->attr.sample_period); - } - return 0; -} - -static int test__checkevent_raw(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0x1a == evsel->attr.config); - return 0; -} - -static int test__checkevent_numeric(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); - return 0; -} - -static int test__checkevent_symbolic_name(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); - return 0; -} - -static int test__checkevent_symbolic_name_config(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong period", - 100000 == evsel->attr.sample_period); - TEST_ASSERT_VAL("wrong config1", - 0 == evsel->attr.config1); - TEST_ASSERT_VAL("wrong config2", - 1 == evsel->attr.config2); - return 0; -} - -static int test__checkevent_symbolic_alias(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config); - return 0; -} - -static int test__checkevent_genhw(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HW_CACHE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", (1 << 16) == evsel->attr.config); - return 0; -} - -static int test__checkevent_breakpoint(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); - TEST_ASSERT_VAL("wrong bp_type", (HW_BREAKPOINT_R | HW_BREAKPOINT_W) == - evsel->attr.bp_type); - TEST_ASSERT_VAL("wrong bp_len", HW_BREAKPOINT_LEN_4 == - evsel->attr.bp_len); - return 0; -} - -static int test__checkevent_breakpoint_x(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_BREAKPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); - TEST_ASSERT_VAL("wrong bp_type", - HW_BREAKPOINT_X == evsel->attr.bp_type); - TEST_ASSERT_VAL("wrong bp_len", sizeof(long) == evsel->attr.bp_len); - return 0; -} - -static int test__checkevent_breakpoint_r(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", - PERF_TYPE_BREAKPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); - TEST_ASSERT_VAL("wrong bp_type", - HW_BREAKPOINT_R == evsel->attr.bp_type); - TEST_ASSERT_VAL("wrong bp_len", - HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); - return 0; -} - -static int test__checkevent_breakpoint_w(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", - PERF_TYPE_BREAKPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); - TEST_ASSERT_VAL("wrong bp_type", - HW_BREAKPOINT_W == evsel->attr.bp_type); - TEST_ASSERT_VAL("wrong bp_len", - HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); - return 0; -} - -static int test__checkevent_breakpoint_rw(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", - PERF_TYPE_BREAKPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 0 == evsel->attr.config); - TEST_ASSERT_VAL("wrong bp_type", - (HW_BREAKPOINT_R|HW_BREAKPOINT_W) == evsel->attr.bp_type); - TEST_ASSERT_VAL("wrong bp_len", - HW_BREAKPOINT_LEN_4 == evsel->attr.bp_len); - return 0; -} - -static int test__checkevent_tracepoint_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - - return test__checkevent_tracepoint(evlist); -} - -static int -test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel; - - TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); - - list_for_each_entry(evsel, &evlist->entries, node) { - TEST_ASSERT_VAL("wrong exclude_user", - !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", - evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - } - - return test__checkevent_tracepoint_multi(evlist); -} - -static int test__checkevent_raw_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); - - return test__checkevent_raw(evlist); -} - -static int test__checkevent_numeric_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); - - return test__checkevent_numeric(evlist); -} - -static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - - return test__checkevent_symbolic_name(evlist); -} - -static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - - return test__checkevent_symbolic_name(evlist); -} - -static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - - return test__checkevent_symbolic_name(evlist); -} - -static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - - return test__checkevent_symbolic_alias(evlist); -} - -static int test__checkevent_genhw_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); - - return test__checkevent_genhw(evlist); -} - -static int test__checkevent_breakpoint_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong name", - !strcmp(perf_evsel__name(evsel), "mem:0:u")); - - return test__checkevent_breakpoint(evlist); -} - -static int test__checkevent_breakpoint_x_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong name", - !strcmp(perf_evsel__name(evsel), "mem:0:x:k")); - - return test__checkevent_breakpoint_x(evlist); -} - -static int test__checkevent_breakpoint_r_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong name", - !strcmp(perf_evsel__name(evsel), "mem:0:r:hp")); - - return test__checkevent_breakpoint_r(evlist); -} - -static int test__checkevent_breakpoint_w_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong name", - !strcmp(perf_evsel__name(evsel), "mem:0:w:up")); - - return test__checkevent_breakpoint_w(evlist); -} - -static int test__checkevent_breakpoint_rw_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong name", - !strcmp(perf_evsel__name(evsel), "mem:0:rw:kp")); - - return test__checkevent_breakpoint_rw(evlist); -} - -static int test__checkevent_pmu(struct perf_evlist *evlist) -{ - - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 10 == evsel->attr.config); - TEST_ASSERT_VAL("wrong config1", 1 == evsel->attr.config1); - TEST_ASSERT_VAL("wrong config2", 3 == evsel->attr.config2); - TEST_ASSERT_VAL("wrong period", 1000 == evsel->attr.sample_period); - - return 0; -} - -static int test__checkevent_list(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); - - /* r1 */ - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); - TEST_ASSERT_VAL("wrong config1", 0 == evsel->attr.config1); - TEST_ASSERT_VAL("wrong config2", 0 == evsel->attr.config2); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - - /* syscalls:sys_enter_open:k */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong sample_type", - PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); - TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - - /* 1:1:hp */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip); - - return 0; -} - -static int test__checkevent_pmu_name(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = perf_evlist__first(evlist); - - /* cpu/config=1,name=krava/u */ - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 1 == evsel->attr.config); - TEST_ASSERT_VAL("wrong name", !strcmp(perf_evsel__name(evsel), "krava")); - - /* cpu/config=2/u" */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 2 == evsel->attr.config); - TEST_ASSERT_VAL("wrong name", - !strcmp(perf_evsel__name(evsel), "cpu/config=2/u")); - - return 0; -} - -static int test__checkevent_pmu_events(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel; - - evsel = list_entry(evlist->entries.next, struct perf_evsel, node); - TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_RAW == evsel->attr.type); - TEST_ASSERT_VAL("wrong exclude_user", - !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", - evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - - return 0; -} - -static int test__checkterms_simple(struct list_head *terms) -{ - struct parse_events__term *term; - - /* config=10 */ - term = list_entry(terms->next, struct parse_events__term, list); - TEST_ASSERT_VAL("wrong type term", - term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG); - TEST_ASSERT_VAL("wrong type val", - term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - TEST_ASSERT_VAL("wrong val", term->val.num == 10); - TEST_ASSERT_VAL("wrong config", !term->config); - - /* config1 */ - term = list_entry(term->list.next, struct parse_events__term, list); - TEST_ASSERT_VAL("wrong type term", - term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG1); - TEST_ASSERT_VAL("wrong type val", - term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - TEST_ASSERT_VAL("wrong val", term->val.num == 1); - TEST_ASSERT_VAL("wrong config", !term->config); - - /* config2=3 */ - term = list_entry(term->list.next, struct parse_events__term, list); - TEST_ASSERT_VAL("wrong type term", - term->type_term == PARSE_EVENTS__TERM_TYPE_CONFIG2); - TEST_ASSERT_VAL("wrong type val", - term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - TEST_ASSERT_VAL("wrong val", term->val.num == 3); - TEST_ASSERT_VAL("wrong config", !term->config); - - /* umask=1*/ - term = list_entry(term->list.next, struct parse_events__term, list); - TEST_ASSERT_VAL("wrong type term", - term->type_term == PARSE_EVENTS__TERM_TYPE_USER); - TEST_ASSERT_VAL("wrong type val", - term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - TEST_ASSERT_VAL("wrong val", term->val.num == 1); - TEST_ASSERT_VAL("wrong config", !strcmp(term->config, "umask")); - - return 0; -} - -static int test__group1(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel, *leader; - - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); - - /* instructions:k */ - evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); - - /* cycles:upp */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - /* use of precise requires exclude_guest */ - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2); - TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); - - return 0; -} - -static int test__group2(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel, *leader; - - TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries); - - /* faults + :ku modifier */ - evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_SOFTWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_SW_PAGE_FAULTS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); - - /* cache-references + :u modifier */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CACHE_REFERENCES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); - - /* cycles:k */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); - - return 0; -} - -static int test__group3(struct perf_evlist *evlist __maybe_unused) -{ - struct perf_evsel *evsel, *leader; - - TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries); - - /* group1 syscalls:sys_enter_open:H */ - evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); - TEST_ASSERT_VAL("wrong sample_type", - PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); - TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); - TEST_ASSERT_VAL("wrong group name", - !strcmp(leader->group_name, "group1")); - - /* group1 cycles:kppp */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - /* use of precise requires exclude_guest */ - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 3); - TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); - TEST_ASSERT_VAL("wrong group name", !evsel->group_name); - - /* group2 cycles + G modifier */ - evsel = leader = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); - TEST_ASSERT_VAL("wrong group name", - !strcmp(leader->group_name, "group2")); - - /* group2 1:3 + G modifier */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", 1 == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", 3 == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); - - /* instructions:u */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); - - return 0; -} - -static int test__group4(struct perf_evlist *evlist __maybe_unused) -{ - struct perf_evsel *evsel, *leader; - - TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries); - - /* cycles:u + p */ - evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - /* use of precise requires exclude_guest */ - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 1); - TEST_ASSERT_VAL("wrong group name", !evsel->group_name); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); - - /* instructions:kp + p */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv); - /* use of precise requires exclude_guest */ - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2); - TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); - - return 0; -} - -static int test__group5(struct perf_evlist *evlist __maybe_unused) -{ - struct perf_evsel *evsel, *leader; - - TEST_ASSERT_VAL("wrong number of entries", 5 == evlist->nr_entries); - - /* cycles + G */ - evsel = leader = perf_evlist__first(evlist); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong group name", !evsel->group_name); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); - - /* instructions + G */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); - - /* cycles:G */ - evsel = leader = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong group name", !evsel->group_name); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); - - /* instructions:G */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == leader); - - /* cycles */ - evsel = perf_evsel__next(evsel); - TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type); - TEST_ASSERT_VAL("wrong config", - PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config); - TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); - TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); - TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv); - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); - - return 0; -} - -struct test__event_st { - const char *name; - __u32 type; - int (*check)(struct perf_evlist *evlist); -}; - -static struct test__event_st test__events[] = { - [0] = { - .name = "syscalls:sys_enter_open", - .check = test__checkevent_tracepoint, - }, - [1] = { - .name = "syscalls:*", - .check = test__checkevent_tracepoint_multi, - }, - [2] = { - .name = "r1a", - .check = test__checkevent_raw, - }, - [3] = { - .name = "1:1", - .check = test__checkevent_numeric, - }, - [4] = { - .name = "instructions", - .check = test__checkevent_symbolic_name, - }, - [5] = { - .name = "cycles/period=100000,config2/", - .check = test__checkevent_symbolic_name_config, - }, - [6] = { - .name = "faults", - .check = test__checkevent_symbolic_alias, - }, - [7] = { - .name = "L1-dcache-load-miss", - .check = test__checkevent_genhw, - }, - [8] = { - .name = "mem:0", - .check = test__checkevent_breakpoint, - }, - [9] = { - .name = "mem:0:x", - .check = test__checkevent_breakpoint_x, - }, - [10] = { - .name = "mem:0:r", - .check = test__checkevent_breakpoint_r, - }, - [11] = { - .name = "mem:0:w", - .check = test__checkevent_breakpoint_w, - }, - [12] = { - .name = "syscalls:sys_enter_open:k", - .check = test__checkevent_tracepoint_modifier, - }, - [13] = { - .name = "syscalls:*:u", - .check = test__checkevent_tracepoint_multi_modifier, - }, - [14] = { - .name = "r1a:kp", - .check = test__checkevent_raw_modifier, - }, - [15] = { - .name = "1:1:hp", - .check = test__checkevent_numeric_modifier, - }, - [16] = { - .name = "instructions:h", - .check = test__checkevent_symbolic_name_modifier, - }, - [17] = { - .name = "faults:u", - .check = test__checkevent_symbolic_alias_modifier, - }, - [18] = { - .name = "L1-dcache-load-miss:kp", - .check = test__checkevent_genhw_modifier, - }, - [19] = { - .name = "mem:0:u", - .check = test__checkevent_breakpoint_modifier, - }, - [20] = { - .name = "mem:0:x:k", - .check = test__checkevent_breakpoint_x_modifier, - }, - [21] = { - .name = "mem:0:r:hp", - .check = test__checkevent_breakpoint_r_modifier, - }, - [22] = { - .name = "mem:0:w:up", - .check = test__checkevent_breakpoint_w_modifier, - }, - [23] = { - .name = "r1,syscalls:sys_enter_open:k,1:1:hp", - .check = test__checkevent_list, - }, - [24] = { - .name = "instructions:G", - .check = test__checkevent_exclude_host_modifier, - }, - [25] = { - .name = "instructions:H", - .check = test__checkevent_exclude_guest_modifier, - }, - [26] = { - .name = "mem:0:rw", - .check = test__checkevent_breakpoint_rw, - }, - [27] = { - .name = "mem:0:rw:kp", - .check = test__checkevent_breakpoint_rw_modifier, - }, - [28] = { - .name = "{instructions:k,cycles:upp}", - .check = test__group1, - }, - [29] = { - .name = "{faults:k,cache-references}:u,cycles:k", - .check = test__group2, - }, - [30] = { - .name = "group1{syscalls:sys_enter_open:H,cycles:kppp},group2{cycles,1:3}:G,instructions:u", - .check = test__group3, - }, - [31] = { - .name = "{cycles:u,instructions:kp}:p", - .check = test__group4, - }, - [32] = { - .name = "{cycles,instructions}:G,{cycles:G,instructions:G},cycles", - .check = test__group5, - }, -}; - -static struct test__event_st test__events_pmu[] = { - [0] = { - .name = "cpu/config=10,config1,config2=3,period=1000/u", - .check = test__checkevent_pmu, - }, - [1] = { - .name = "cpu/config=1,name=krava/u,cpu/config=2/u", - .check = test__checkevent_pmu_name, - }, -}; - -struct test__term { - const char *str; - __u32 type; - int (*check)(struct list_head *terms); -}; - -static struct test__term test__terms[] = { - [0] = { - .str = "config=10,config1,config2=3,umask=1", - .check = test__checkterms_simple, - }, -}; - -static int test_event(struct test__event_st *e) -{ - struct perf_evlist *evlist; - int ret; - - evlist = perf_evlist__new(NULL, NULL); - if (evlist == NULL) - return -ENOMEM; - - ret = parse_events(evlist, e->name, 0); - if (ret) { - pr_debug("failed to parse event '%s', err %d\n", - e->name, ret); - return ret; - } - - ret = e->check(evlist); - perf_evlist__delete(evlist); - - return ret; -} - -static int test_events(struct test__event_st *events, unsigned cnt) -{ - int ret1, ret2 = 0; - unsigned i; - - for (i = 0; i < cnt; i++) { - struct test__event_st *e = &events[i]; - - pr_debug("running test %d '%s'\n", i, e->name); - ret1 = test_event(e); - if (ret1) - ret2 = ret1; - } - - return ret2; -} - -static int test_term(struct test__term *t) -{ - struct list_head *terms; - int ret; - - terms = malloc(sizeof(*terms)); - if (!terms) - return -ENOMEM; - - INIT_LIST_HEAD(terms); - - ret = parse_events_terms(terms, t->str); - if (ret) { - pr_debug("failed to parse terms '%s', err %d\n", - t->str , ret); - return ret; - } - - ret = t->check(terms); - parse_events__free_terms(terms); - - return ret; -} - -static int test_terms(struct test__term *terms, unsigned cnt) -{ - int ret = 0; - unsigned i; - - for (i = 0; i < cnt; i++) { - struct test__term *t = &terms[i]; - - pr_debug("running test %d '%s'\n", i, t->str); - ret = test_term(t); - if (ret) - break; - } - - return ret; -} - -static int test_pmu(void) -{ - struct stat st; - char path[PATH_MAX]; - int ret; - - snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/format/", - sysfs_find_mountpoint()); - - ret = stat(path, &st); - if (ret) - pr_debug("omitting PMU cpu tests\n"); - return !ret; -} - -static int test_pmu_events(void) -{ - struct stat st; - char path[PATH_MAX]; - struct dirent *ent; - DIR *dir; - int ret; - - snprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu/events/", - sysfs_find_mountpoint()); - - ret = stat(path, &st); - if (ret) { - pr_debug("ommiting PMU cpu events tests\n"); - return 0; - } - - dir = opendir(path); - if (!dir) { - pr_debug("can't open pmu event dir"); - return -1; - } - - while (!ret && (ent = readdir(dir))) { -#define MAX_NAME 100 - struct test__event_st e; - char name[MAX_NAME]; - - if (!strcmp(ent->d_name, ".") || - !strcmp(ent->d_name, "..")) - continue; - - snprintf(name, MAX_NAME, "cpu/event=%s/u", ent->d_name); - - e.name = name; - e.check = test__checkevent_pmu_events; - - ret = test_event(&e); -#undef MAX_NAME - } - - closedir(dir); - return ret; -} - -int parse_events__test(void) -{ - int ret1, ret2 = 0; - -#define TEST_EVENTS(tests) \ -do { \ - ret1 = test_events(tests, ARRAY_SIZE(tests)); \ - if (!ret2) \ - ret2 = ret1; \ -} while (0) - - TEST_EVENTS(test__events); - - if (test_pmu()) - TEST_EVENTS(test__events_pmu); - - if (test_pmu()) { - int ret = test_pmu_events(); - if (ret) - return ret; - } - - ret1 = test_terms(test__terms, ARRAY_SIZE(test__terms)); - if (!ret2) - ret2 = ret1; - - return ret2; -} -- cgit v1.2.3 From 52502bf201a85b5b51a384037a002d0b39093df0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 31 Oct 2012 15:52:47 +0100 Subject: perf tests: Add framework for automated perf_event_attr tests The idea is run perf session with kidnapping sys_perf_event_open function. For each sys_perf_event_open call we store the perf_event_attr data to the file to be checked later against what we expect. You can run this by: $ python ./tests/attr.py -d ./tests/attr/ -p ./perf -v v2 changes: - preserve errno value in the hook Signed-off-by: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20121031145247.GB1027@krava.brq.redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 + tools/perf/perf.c | 2 + tools/perf/perf.h | 16 ++- tools/perf/tests/attr.c | 140 +++++++++++++++++++++ tools/perf/tests/attr.py | 313 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 470 insertions(+), 2 deletions(-) create mode 100644 tools/perf/tests/attr.c create mode 100644 tools/perf/tests/attr.py diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 2d3427f65b5..1da87a30c73 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -430,6 +430,7 @@ LIB_OBJS += $(OUTPUT)arch/common.o LIB_OBJS += $(OUTPUT)tests/parse-events.o LIB_OBJS += $(OUTPUT)tests/dso-data.o +LIB_OBJS += $(OUTPUT)tests/attr.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o BUILTIN_OBJS += $(OUTPUT)builtin-bench.o diff --git a/tools/perf/perf.c b/tools/perf/perf.c index e9683738d89..a0ae2902f9c 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -484,6 +484,8 @@ int main(int argc, const char **argv) } cmd = argv[0]; + test_attr__init(); + /* * We use PATH to find perf commands, but we prepend some higher * precedence paths: the "--exec-path" option, the PERF_EXEC_PATH diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 469fbf2daea..00472646b3b 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -174,13 +174,25 @@ static inline unsigned long long rdclock(void) (void) (&_min1 == &_min2); \ _min1 < _min2 ? _min1 : _min2; }) +extern bool test_attr__enabled; +void test_attr__init(void); +void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, + int fd, int group_fd, unsigned long flags); + static inline int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, unsigned long flags) { - return syscall(__NR_perf_event_open, attr, pid, cpu, - group_fd, flags); + int fd; + + fd = syscall(__NR_perf_event_open, attr, pid, cpu, + group_fd, flags); + + if (unlikely(test_attr__enabled)) + test_attr__open(attr, pid, cpu, fd, group_fd, flags); + + return fd; } #define MAX_COUNTERS 256 diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c new file mode 100644 index 00000000000..55e9a873a5c --- /dev/null +++ b/tools/perf/tests/attr.c @@ -0,0 +1,140 @@ + +/* + * The struct perf_event_attr test support. + * + * This test is embedded inside into perf directly and is governed + * by the PERF_TEST_ATTR environment variable and hook inside + * sys_perf_event_open function. + * + * The general idea is to store 'struct perf_event_attr' details for + * each event created within single perf command. Each event details + * are stored into separate text file. Once perf command is finished + * these files can be checked for values we expect for command. + * + * Besides 'struct perf_event_attr' values we also store 'fd' and + * 'group_fd' values to allow checking for groups created. + * + * This all is triggered by setting PERF_TEST_ATTR environment variable. + * It must contain name of existing directory with access and write + * permissions. All the event text files are stored there. + */ + +#include +#include +#include +#include +#include +#include "../perf.h" +#include "util.h" + +#define ENV "PERF_TEST_ATTR" + +bool test_attr__enabled; + +static char *dir; + +void test_attr__init(void) +{ + dir = getenv(ENV); + test_attr__enabled = (dir != NULL); +} + +#define BUFSIZE 1024 + +#define WRITE_ASS(str, fmt, data) \ +do { \ + char buf[BUFSIZE]; \ + size_t size; \ + \ + size = snprintf(buf, BUFSIZE, #str "=%"fmt "\n", data); \ + if (1 != fwrite(buf, size, 1, file)) { \ + perror("test attr - failed to write event file"); \ + fclose(file); \ + return -1; \ + } \ + \ +} while (0) + +static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu, + int fd, int group_fd, unsigned long flags) +{ + FILE *file; + char path[PATH_MAX]; + + snprintf(path, PATH_MAX, "%s/event-%d-%llu-%d", dir, + attr->type, attr->config, fd); + + file = fopen(path, "w+"); + if (!file) { + perror("test attr - failed to open event file"); + return -1; + } + + if (fprintf(file, "[event-%d-%llu-%d]\n", + attr->type, attr->config, fd) < 0) { + perror("test attr - failed to write event file"); + fclose(file); + return -1; + } + + /* syscall arguments */ + WRITE_ASS(fd, "d", fd); + WRITE_ASS(group_fd, "d", group_fd); + WRITE_ASS(cpu, "d", cpu); + WRITE_ASS(pid, "d", pid); + WRITE_ASS(flags, "lu", flags); + + /* struct perf_event_attr */ + WRITE_ASS(type, PRIu32, attr->type); + WRITE_ASS(size, PRIu32, attr->size); + WRITE_ASS(config, "llu", attr->config); + WRITE_ASS(sample_period, "llu", attr->sample_period); + WRITE_ASS(sample_type, "llu", attr->sample_type); + WRITE_ASS(read_format, "llu", attr->read_format); + WRITE_ASS(disabled, "d", attr->disabled); + WRITE_ASS(inherit, "d", attr->inherit); + WRITE_ASS(pinned, "d", attr->pinned); + WRITE_ASS(exclusive, "d", attr->exclusive); + WRITE_ASS(exclude_user, "d", attr->exclude_user); + WRITE_ASS(exclude_kernel, "d", attr->exclude_kernel); + WRITE_ASS(exclude_hv, "d", attr->exclude_hv); + WRITE_ASS(exclude_idle, "d", attr->exclude_idle); + WRITE_ASS(mmap, "d", attr->mmap); + WRITE_ASS(comm, "d", attr->comm); + WRITE_ASS(freq, "d", attr->freq); + WRITE_ASS(inherit_stat, "d", attr->inherit_stat); + WRITE_ASS(enable_on_exec, "d", attr->enable_on_exec); + WRITE_ASS(task, "d", attr->task); + WRITE_ASS(watermask, "d", attr->watermark); + WRITE_ASS(precise_ip, "d", attr->precise_ip); + WRITE_ASS(mmap_data, "d", attr->mmap_data); + WRITE_ASS(sample_id_all, "d", attr->sample_id_all); + WRITE_ASS(exclude_host, "d", attr->exclude_host); + WRITE_ASS(exclude_guest, "d", attr->exclude_guest); + WRITE_ASS(exclude_callchain_kernel, "d", + attr->exclude_callchain_kernel); + WRITE_ASS(exclude_callchain_user, "d", + attr->exclude_callchain_user); + WRITE_ASS(wakeup_events, PRIu32, attr->wakeup_events); + WRITE_ASS(bp_type, PRIu32, attr->bp_type); + WRITE_ASS(config1, "llu", attr->config1); + WRITE_ASS(config2, "llu", attr->config2); + WRITE_ASS(branch_sample_type, "llu", attr->branch_sample_type); + WRITE_ASS(sample_regs_user, "llu", attr->sample_regs_user); + WRITE_ASS(sample_stack_user, PRIu32, attr->sample_stack_user); + WRITE_ASS(optional, "d", 0); + + fclose(file); + return 0; +} + +void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, + int fd, int group_fd, unsigned long flags) +{ + int errno_saved = errno; + + if (store_event(attr, pid, cpu, fd, group_fd, flags)) + die("test attr FAILED"); + + errno = errno_saved; +} diff --git a/tools/perf/tests/attr.py b/tools/perf/tests/attr.py new file mode 100644 index 00000000000..e98c726ac81 --- /dev/null +++ b/tools/perf/tests/attr.py @@ -0,0 +1,313 @@ +#! /usr/bin/python + +import os +import sys +import glob +import optparse +import tempfile +import logging +import shutil +import ConfigParser + +class Fail(Exception): + def __init__(self, test, msg): + self.msg = msg + self.test = test + def getMsg(self): + return '\'%s\' - %s' % (self.test.path, self.msg) + +class Unsup(Exception): + def __init__(self, test): + self.test = test + def getMsg(self): + return '\'%s\'' % self.test.path + +class Event(dict): + terms = [ + 'flags', + 'type', + 'size', + 'config', + 'sample_period', + 'sample_type', + 'read_format', + 'disabled', + 'inherit', + 'pinned', + 'exclusive', + 'exclude_user', + 'exclude_kernel', + 'exclude_hv', + 'exclude_idle', + 'mmap', + 'comm', + 'freq', + 'inherit_stat', + 'enable_on_exec', + 'task', + 'watermask', + 'precise_ip', + 'mmap_data', + 'sample_id_all', + 'exclude_host', + 'exclude_guest', + 'exclude_callchain_kernel', + 'exclude_callchain_user', + 'wakeup_events', + 'bp_type', + 'config1', + 'config2', + 'branch_sample_type', + 'sample_regs_user', + 'sample_stack_user', + ] + + def add(self, data): + for key, val in data: + log.debug(" %s = %s" % (key, val)) + self[key] = val + + def __init__(self, name, data, base): + log.info(" Event %s" % name); + self.name = name; + self.group = '' + self.add(base) + self.add(data) + + def compare_data(self, a, b): + a_list = a.split('|') + b_list = b.split('|') + + for a_item in a_list: + for b_item in b_list: + if (a_item == b_item): + return True + elif (a_item == '*') or (b_item == '*'): + return True + + return False + + def equal(self, other): + for t in Event.terms: + log.debug(" [%s] %s %s" % (t, self[t], other[t])); + if not self.has_key(t) or not other.has_key(t): + return False + if not self.compare_data(self[t], other[t]): + return False + return True + + def is_optional(self): + if self['optional'] == '1': + return True + else: + return False + +class Test(object): + def __init__(self, path, options): + parser = ConfigParser.SafeConfigParser() + parser.read(path) + + log.warning("running '%s'" % path) + + self.path = path + self.test_dir = options.test_dir + self.perf = options.perf + self.command = parser.get('config', 'command') + self.args = parser.get('config', 'args') + + try: + self.ret = parser.get('config', 'ret') + except: + self.ret = 0 + + self.expect = {} + self.result = {} + log.info(" loading expected events"); + self.load_events(path, self.expect) + + def is_event(self, name): + if name.find("event") == -1: + return False + else: + return True + + def load_events(self, path, events): + parser_event = ConfigParser.SafeConfigParser() + parser_event.read(path) + + for section in filter(self.is_event, parser_event.sections()): + + parser_items = parser_event.items(section); + base_items = {} + + if (':' in section): + base = section[section.index(':') + 1:] + parser_base = ConfigParser.SafeConfigParser() + parser_base.read(self.test_dir + '/' + base) + base_items = parser_base.items('event') + + e = Event(section, parser_items, base_items) + events[section] = e + + def run_cmd(self, tempdir): + cmd = "PERF_TEST_ATTR=%s %s %s -o %s/perf.data %s" % (tempdir, + self.perf, self.command, tempdir, self.args) + ret = os.WEXITSTATUS(os.system(cmd)) + + log.info(" running '%s' ret %d " % (cmd, ret)) + + if ret != int(self.ret): + raise Unsup(self) + + def compare(self, expect, result): + match = {} + + log.info(" compare"); + + # For each expected event find all matching + # events in result. Fail if there's not any. + for exp_name, exp_event in expect.items(): + exp_list = [] + log.debug(" matching [%s]" % exp_name) + for res_name, res_event in result.items(): + log.debug(" to [%s]" % res_name) + if (exp_event.equal(res_event)): + exp_list.append(res_name) + log.debug(" ->OK") + else: + log.debug(" ->FAIL"); + + log.info(" match: [%s] optional(%d) matches %s" % + (exp_name, exp_event.is_optional(), str(exp_list))) + + # we did not any matching event - fail + if (not exp_list) and (not exp_event.is_optional()): + raise Fail(self, 'match failure'); + + match[exp_name] = exp_list + + # For each defined group in the expected events + # check we match the same group in the result. + for exp_name, exp_event in expect.items(): + group = exp_event.group + + if (group == ''): + continue + + # XXX group matching does not account for + # optional events as above matching does + for res_name in match[exp_name]: + res_group = result[res_name].group + if res_group not in match[group]: + raise Fail(self, 'group failure') + + log.info(" group: [%s] matches group leader %s" % + (exp_name, str(match[group]))) + + log.info(" matched") + + def resolve_groups(self, events): + for name, event in events.items(): + group_fd = event['group_fd']; + if group_fd == '-1': + continue; + + for iname, ievent in events.items(): + if (ievent['fd'] == group_fd): + event.group = iname + log.debug('[%s] has group leader [%s]' % (name, iname)) + break; + + def run(self): + tempdir = tempfile.mkdtemp(); + + # run the test script + self.run_cmd(tempdir); + + # load events expectation for the test + log.info(" loading result events"); + for f in glob.glob(tempdir + '/event*'): + self.load_events(f, self.result); + + # resolve group_fd to event names + self.resolve_groups(self.expect); + self.resolve_groups(self.result); + + # do the expectation - results matching - both ways + self.compare(self.expect, self.result) + self.compare(self.result, self.expect) + + # cleanup + shutil.rmtree(tempdir) + + +def run_tests(options): + for f in glob.glob(options.test_dir + '/' + options.test): + try: + Test(f, options).run() + except Unsup, obj: + log.warning("unsupp %s" % obj.getMsg()) + +def setup_log(verbose): + global log + level = logging.CRITICAL + + if verbose == 1: + level = logging.WARNING + if verbose == 2: + level = logging.INFO + if verbose >= 3: + level = logging.DEBUG + + log = logging.getLogger('test') + log.setLevel(level) + ch = logging.StreamHandler() + ch.setLevel(level) + formatter = logging.Formatter('%(message)s') + ch.setFormatter(formatter) + log.addHandler(ch) + +USAGE = '''%s [OPTIONS] + -d dir # tests dir + -p path # perf binary + -t test # single test + -v # verbose level +''' % sys.argv[0] + +def main(): + parser = optparse.OptionParser(usage=USAGE) + + parser.add_option("-t", "--test", + action="store", type="string", dest="test") + parser.add_option("-d", "--test-dir", + action="store", type="string", dest="test_dir") + parser.add_option("-p", "--perf", + action="store", type="string", dest="perf") + parser.add_option("-v", "--verbose", + action="count", dest="verbose") + + options, args = parser.parse_args() + if args: + parser.error('FAILED wrong arguments %s' % ' '.join(args)) + return -1 + + setup_log(options.verbose) + + if not options.test_dir: + print 'FAILED no -d option specified' + sys.exit(-1) + + if not options.test: + options.test = 'test*' + + try: + run_tests(options) + + except Fail, obj: + print "FAILED %s" % obj.getMsg(); + sys.exit(-1) + + sys.exit(0) + +if __name__ == '__main__': + main() -- cgit v1.2.3 From bcbec053d2197031d04b8e040c61695b5d7a949d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 31 Oct 2012 11:59:52 +0100 Subject: USB: serial: remove driver version information Remove all MODULE_VERSION macros and driver-version information (except for garmin_gps which uses it in a status reply). It is the kernel version that matters and not some private version scheme which rarely even gets updated. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/aircable.c | 5 ----- drivers/usb/serial/ark3116.c | 5 ----- drivers/usb/serial/belkin_sa.c | 5 ----- drivers/usb/serial/cp210x.c | 5 ----- drivers/usb/serial/cyberjack.c | 5 ----- drivers/usb/serial/cypress_m8.c | 5 ----- drivers/usb/serial/digi_acceleport.c | 4 ---- drivers/usb/serial/empeg.c | 4 ---- drivers/usb/serial/hp4x.c | 5 ----- drivers/usb/serial/io_edgeport.c | 4 ---- drivers/usb/serial/io_ti.c | 4 ---- drivers/usb/serial/ipaq.c | 5 ----- drivers/usb/serial/ipw.c | 4 ---- drivers/usb/serial/iuu_phoenix.c | 6 ------ drivers/usb/serial/keyspan.c | 4 ---- drivers/usb/serial/keyspan_pda.c | 4 ---- drivers/usb/serial/kl5kusb105.c | 4 ---- drivers/usb/serial/kobil_sct.c | 2 -- drivers/usb/serial/mct_u232.c | 4 ---- drivers/usb/serial/metro-usb.c | 2 -- drivers/usb/serial/mos7720.c | 4 ---- drivers/usb/serial/mos7840.c | 4 ---- drivers/usb/serial/omninet.c | 4 ---- drivers/usb/serial/option.c | 2 -- drivers/usb/serial/oti6858.c | 2 -- drivers/usb/serial/quatech2.c | 2 -- drivers/usb/serial/siemens_mpi.c | 2 -- drivers/usb/serial/sierra.c | 3 +-- drivers/usb/serial/spcp8x5.c | 4 ---- drivers/usb/serial/ssu100.c | 2 -- drivers/usb/serial/usb_wwan.c | 2 -- drivers/usb/serial/vivopay-serial.c | 3 --- 32 files changed, 1 insertion(+), 119 deletions(-) diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 54e1bb6372e..6d110a3bc7e 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c @@ -68,10 +68,6 @@ #define THROTTLED 0x01 #define ACTUALLY_THROTTLED 0x02 -/* - * Version Information - */ -#define DRIVER_VERSION "v2.0" #define DRIVER_AUTHOR "Naranjo, Manuel Francisco , Johan Hovold " #define DRIVER_DESC "AIRcable USB Driver" @@ -192,5 +188,4 @@ module_usb_serial_driver(serial_drivers, id_table); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index bd50a8a41a0..a88882c0e23 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -37,11 +37,6 @@ #include #include -/* - * Version information - */ - -#define DRIVER_VERSION "v0.7" #define DRIVER_AUTHOR "Bart Hartgers " #define DRIVER_DESC "USB ARK3116 serial/IrDA driver" #define DRIVER_DEV_DESC "ARK3116 RS232/IrDA" diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index ea29556f0d7..b72a4c16670 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -37,10 +37,6 @@ #include #include "belkin_sa.h" -/* - * Version Information - */ -#define DRIVER_VERSION "v1.3" #define DRIVER_AUTHOR "William Greathouse " #define DRIVER_DESC "USB Belkin Serial converter driver" @@ -509,5 +505,4 @@ module_usb_serial_driver(serial_drivers, id_table); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 1264173a099..2858d8a9eac 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -24,10 +24,6 @@ #include #include -/* - * Version Information - */ -#define DRIVER_VERSION "v0.09" #define DRIVER_DESC "Silicon Labs CP210x RS232 serial adaptor driver" /* @@ -871,5 +867,4 @@ static void cp210x_release(struct usb_serial *serial) module_usb_serial_driver(serial_drivers, id_table); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 4ee77dcbe69..69a4fa1cee2 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -43,10 +43,6 @@ #define CYBERJACK_LOCAL_BUF_SIZE 32 -/* - * Version Information - */ -#define DRIVER_VERSION "v1.01" #define DRIVER_AUTHOR "Matthias Bruestle" #define DRIVER_DESC "REINER SCT cyberJack pinpad/e-com USB Chipcard Reader Driver" @@ -441,5 +437,4 @@ module_usb_serial_driver(serial_drivers, id_table); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index f0da1279c11..fd8c35fd452 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -50,10 +50,6 @@ static bool stats; static int interval; static bool unstable_bauds; -/* - * Version Information - */ -#define DRIVER_VERSION "v1.10" #define DRIVER_AUTHOR "Lonnie Mendez , Neil Whelchel " #define DRIVER_DESC "Cypress USB to Serial Driver" @@ -1303,7 +1299,6 @@ module_usb_serial_driver(serial_drivers, id_table_combined); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); module_param(stats, bool, S_IRUGO | S_IWUSR); diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index b50fa1c6d88..45d4af62967 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -32,10 +32,6 @@ /* Defines */ -/* - * Version Information - */ -#define DRIVER_VERSION "v1.80.1.2" #define DRIVER_AUTHOR "Peter Berger , Al Borchers " #define DRIVER_DESC "Digi AccelePort USB-2/USB-4 Serial Converter driver" diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 43ede4a1e12..0f658618db1 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -28,10 +28,6 @@ #include #include -/* - * Version Information - */ -#define DRIVER_VERSION "v1.3" #define DRIVER_AUTHOR "Greg Kroah-Hartman , Gary Brubaker " #define DRIVER_DESC "USB Empeg Mark I/II Driver" diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index 0bbaf21a9d1..2cba60d90c7 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c @@ -20,10 +20,6 @@ #include #include -/* - * Version Information - */ -#define DRIVER_VERSION "v1.00" #define DRIVER_DESC "HP4x (48/49) Generic Serial driver" #define HP_VENDOR_ID 0x03f0 @@ -52,5 +48,4 @@ static struct usb_serial_driver * const serial_drivers[] = { module_usb_serial_driver(serial_drivers, id_table); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 5acc0d13864..7b770c7f8b1 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -51,10 +51,6 @@ #include "io_ionsp.h" /* info for the iosp messages */ #include "io_16654.h" /* 16654 UART defines */ -/* - * Version Information - */ -#define DRIVER_VERSION "v2.7" #define DRIVER_AUTHOR "Greg Kroah-Hartman and David Iacovelli" #define DRIVER_DESC "Edgeport USB Serial Driver" diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 60023c2d2a3..58184f3de68 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -40,10 +40,6 @@ #include "io_usbvend.h" #include "io_ti.h" -/* - * Version Information - */ -#define DRIVER_VERSION "v0.7mode043006" #define DRIVER_AUTHOR "Greg Kroah-Hartman and David Iacovelli" #define DRIVER_DESC "Edgeport USB Serial Driver" diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 1068bf22e27..76c9a847da5 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -25,11 +25,6 @@ #define KP_RETRIES 100 -/* - * Version Information - */ - -#define DRIVER_VERSION "v1.0" #define DRIVER_AUTHOR "Ganesh Varadarajan " #define DRIVER_DESC "USB PocketPC PDA driver" diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 4264821a3b3..155eab14b30 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c @@ -49,10 +49,6 @@ #include #include "usb-wwan.h" -/* - * Version Information - */ -#define DRIVER_VERSION "v0.4" #define DRIVER_AUTHOR "Roelf Diedericks" #define DRIVER_DESC "IPWireless tty driver" diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 99029ca850c..1e1fbed65ef 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -32,10 +32,6 @@ #include "iuu_phoenix.h" #include -/* - * Version Information - */ -#define DRIVER_VERSION "v0.12" #define DRIVER_DESC "Infinity USB Unlimited Phoenix driver" static const struct usb_device_id id_table[] = { @@ -1232,8 +1228,6 @@ MODULE_AUTHOR("Alain Degreffe eczema@ecze.com"); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); - module_param(xmas, bool, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(xmas, "Xmas colors enabled or not"); diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 7179b0c5f81..991ca6a690a 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -44,10 +44,6 @@ #include #include "keyspan.h" -/* - * Version Information - */ -#define DRIVER_VERSION "v1.1.5" #define DRIVER_AUTHOR "Hugh Blemings " #define DRIVER_DESC "USB Keyspan PDA Converter driver" diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 1f4517864cd..fc9e14a1e9b 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -49,10 +49,6 @@ #include #include "kl5kusb105.h" -/* - * Version Information - */ -#define DRIVER_VERSION "v0.4" #define DRIVER_AUTHOR "Utz-Uwe Haus , Johan Hovold " #define DRIVER_DESC "KLSI KL5KUSB105 chipset USB->Serial Converter driver" diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index c9ca7a5b12e..b747ba615d0 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -38,8 +38,6 @@ #include #include "kobil_sct.h" -/* Version Information */ -#define DRIVER_VERSION "21/05/2004" #define DRIVER_AUTHOR "KOBIL Systems GmbH - http://www.kobil.com" #define DRIVER_DESC "KOBIL USB Smart Card Terminal Driver (experimental)" diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 8a208100410..b6911757c85 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -38,10 +38,6 @@ #include #include "mct_u232.h" -/* - * Version Information - */ -#define DRIVER_VERSION "z2.1" /* Linux in-kernel version */ #define DRIVER_AUTHOR "Wolfgang Grandegger " #define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver" diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index 6f29c74eb76..3d258448c29 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c @@ -20,8 +20,6 @@ #include #include -/* Version Information */ -#define DRIVER_VERSION "v1.2.0.0" #define DRIVER_DESC "Metrologic Instruments Inc. - USB-POS driver" /* Product information. */ diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 75267421aad..f57a6b1fe78 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -36,10 +36,6 @@ #include #include -/* - * Version Information - */ -#define DRIVER_VERSION "2.1" #define DRIVER_AUTHOR "Aspire Communications pvt Ltd." #define DRIVER_DESC "Moschip USB Serial Driver" diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 1cf3375ec1a..66d9e088d9d 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -35,10 +35,6 @@ #include #include -/* - * Version Information - */ -#define DRIVER_VERSION "1.3.2" #define DRIVER_DESC "Moschip 7840/7820 USB Serial Driver" /* diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 9ab73d29577..7818af931a4 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -23,10 +23,6 @@ #include #include -/* - * Version Information - */ -#define DRIVER_VERSION "v1.1" #define DRIVER_AUTHOR "Alessandro Zummo" #define DRIVER_DESC "USB ZyXEL omni.net LCD PLUS Driver" diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 5dee7d61241..e9cffac49cd 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -28,7 +28,6 @@ device features. */ -#define DRIVER_VERSION "v0.7.2" #define DRIVER_AUTHOR "Matthias Urlichs " #define DRIVER_DESC "USB Driver for GSM modems" @@ -1509,5 +1508,4 @@ static int option_send_setup(struct usb_serial_port *port) MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index cee9a52ca89..d217fd6ee43 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -57,7 +57,6 @@ #define OTI6858_DESCRIPTION \ "Ours Technology Inc. OTi-6858 USB to serial adapter driver" #define OTI6858_AUTHOR "Tomasz Michal Lukaszewski " -#define OTI6858_VERSION "0.2" static const struct usb_device_id id_table[] = { { USB_DEVICE(OTI6858_VENDOR_ID, OTI6858_PRODUCT_ID) }, @@ -899,5 +898,4 @@ module_usb_serial_driver(serial_drivers, id_table); MODULE_DESCRIPTION(OTI6858_DESCRIPTION); MODULE_AUTHOR(OTI6858_AUTHOR); -MODULE_VERSION(OTI6858_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index ffcfc962ab1..d152be97d04 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -65,8 +65,6 @@ #define QT2_WRITE_BUFFER_SIZE 512 /* size of write buffer */ #define QT2_WRITE_CONTROL_SIZE 5 /* control bytes used for a write */ -/* Version Information */ -#define DRIVER_VERSION "v0.1" #define DRIVER_DESC "Quatech 2nd gen USB to Serial Driver" #define USB_VENDOR_ID_QUATECH 0x061d diff --git a/drivers/usb/serial/siemens_mpi.c b/drivers/usb/serial/siemens_mpi.c index e4a1787cdba..a76b1ae54a2 100644 --- a/drivers/usb/serial/siemens_mpi.c +++ b/drivers/usb/serial/siemens_mpi.c @@ -16,8 +16,6 @@ #include #include -/* Version Information */ -#define DRIVER_VERSION "Version 0.1 09/26/2005" #define DRIVER_AUTHOR "Thomas Hergenhahn@web.de http://libnodave.sf.net" #define DRIVER_DESC "Driver for Siemens USB/MPI adapter" diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 270860f6bb2..af06f2f5f38 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -18,7 +18,7 @@ */ /* Uncomment to log function calls */ /* #define DEBUG */ -#define DRIVER_VERSION "v.1.7.16" + #define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer" #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" @@ -1078,7 +1078,6 @@ module_usb_serial_driver(serial_drivers, id_table); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); module_param(nmea, bool, S_IRUGO | S_IWUSR); diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 769c137f897..a42536af125 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -28,9 +28,6 @@ #include #include - -/* Version Information */ -#define DRIVER_VERSION "v0.10" #define DRIVER_DESC "SPCP8x5 USB to serial adaptor driver" #define SPCP8x5_007_VID 0x04FC @@ -651,5 +648,4 @@ static struct usb_serial_driver * const serial_drivers[] = { module_usb_serial_driver(serial_drivers, id_table); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 868d1e6852e..4543ea35022 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c @@ -46,8 +46,6 @@ #define FULLPWRBIT 0x00000080 #define NEXT_BOARD_POWER_BIT 0x00000004 -/* Version Information */ -#define DRIVER_VERSION "v0.1" #define DRIVER_DESC "Quatech SSU-100 USB to Serial Driver" #define USB_VENDOR_ID_QUATECH 0x061d /* Quatech VID */ diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 61a73ad1a18..2be2b5b639a 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -19,7 +19,6 @@ - controlling the baud rate doesn't make sense */ -#define DRIVER_VERSION "v0.7.2" #define DRIVER_AUTHOR "Matthias Urlichs " #define DRIVER_DESC "USB Driver for GSM modems" @@ -710,5 +709,4 @@ EXPORT_SYMBOL(usb_wwan_resume); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/serial/vivopay-serial.c b/drivers/usb/serial/vivopay-serial.c index 0c0aa876c20..6299526ff8c 100644 --- a/drivers/usb/serial/vivopay-serial.c +++ b/drivers/usb/serial/vivopay-serial.c @@ -10,8 +10,6 @@ #include #include - -#define DRIVER_VERSION "v1.0" #define DRIVER_DESC "ViVOpay USB Serial Driver" #define VIVOPAY_VENDOR_ID 0x1d5f @@ -42,5 +40,4 @@ module_usb_serial_driver(serial_drivers, id_table); MODULE_AUTHOR("Forest Bond "); MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 571e41214e988bc38c99d804e6d8e1ea1d016342 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 31 Oct 2012 13:09:07 -0400 Subject: USB: remove iteration limit in hub_tt_work() This patch (as1621) removes the limit on the number of loops allowed in hub_tt_work(). The value is arbitrary, and it's silly to have a limit in the first place -- anything beyond the limit would not get handled. Besides, it's most unlikely that we'll ever need to clear more than a couple of TT buffers at any time. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index fbaf3c3dbf0..90accdefdc7 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -741,7 +741,6 @@ static void hub_tt_work(struct work_struct *work) struct usb_hub *hub = container_of(work, struct usb_hub, tt.clear_work); unsigned long flags; - int limit = 100; spin_lock_irqsave (&hub->tt.lock, flags); while (!list_empty(&hub->tt.clear_list)) { @@ -751,9 +750,6 @@ static void hub_tt_work(struct work_struct *work) const struct hc_driver *drv; int status; - if (!hub->quiescing && --limit < 0) - break; - next = hub->tt.clear_list.next; clear = list_entry (next, struct usb_tt_clear, clear_list); list_del (&clear->clear_list); -- cgit v1.2.3 From 4968f951913997adc8c68c4e986e8168ee1d2998 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 31 Oct 2012 13:12:11 -0400 Subject: USB: EHCI: remove unused Link Power Management code This patch (as1622) removes the USB-2.1 Link Power Management code from the ehci-hcd driver. This code was never integrated with usbcore, it is full of bugs, and it was not getting used by anybody. However, the debugging code for dumping the LPM-related fields in the EHCI registers is left in place. In theory it might be useful to see these values, even though we don't use them. This essentially amounts to a partial revert of commit aa4d8342988d0c1a79ff19b2ede1e81dfbb16ea5 (USB: EHCI: EHCI 1.1 addendum: preparation) and an almost full revert of commit 48f24970144479c29b8cee6d2e1dbedf6dcf9cfb (USB: EHCI: EHCI 1.1 addendum: Basic LPM feature support) plus its follow-ons. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-dbg.c | 97 --------------------------------------- drivers/usb/host/ehci-hcd.c | 18 -------- drivers/usb/host/ehci-hub.c | 5 -- drivers/usb/host/ehci-lpm.c | 101 ----------------------------------------- drivers/usb/host/ehci-pci.c | 13 +----- drivers/usb/host/ehci-vt8500.c | 5 -- drivers/usb/host/ehci.h | 1 - 7 files changed, 1 insertion(+), 239 deletions(-) delete mode 100644 drivers/usb/host/ehci-lpm.c diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index dfd3bf3aa4d..70b496dc18a 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -337,11 +337,6 @@ static int debug_async_open(struct inode *, struct file *); static int debug_periodic_open(struct inode *, struct file *); static int debug_registers_open(struct inode *, struct file *); static int debug_async_open(struct inode *, struct file *); -static ssize_t debug_lpm_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos); -static ssize_t debug_lpm_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos); -static int debug_lpm_close(struct inode *inode, struct file *file); static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*); static int debug_close(struct inode *, struct file *); @@ -367,14 +362,6 @@ static const struct file_operations debug_registers_fops = { .release = debug_close, .llseek = default_llseek, }; -static const struct file_operations debug_lpm_fops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = debug_lpm_read, - .write = debug_lpm_write, - .release = debug_lpm_close, - .llseek = noop_llseek, -}; static struct dentry *ehci_debug_root; @@ -956,86 +943,6 @@ static int debug_registers_open(struct inode *inode, struct file *file) return file->private_data ? 0 : -ENOMEM; } -static int debug_lpm_close(struct inode *inode, struct file *file) -{ - return 0; -} - -static ssize_t debug_lpm_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - /* TODO: show lpm stats */ - return 0; -} - -static ssize_t debug_lpm_write(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct usb_hcd *hcd; - struct ehci_hcd *ehci; - char buf[50]; - size_t len; - u32 temp; - unsigned long port; - u32 __iomem *portsc ; - u32 params; - - hcd = bus_to_hcd(file->private_data); - ehci = hcd_to_ehci(hcd); - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - buf[len] = '\0'; - if (len > 0 && buf[len - 1] == '\n') - buf[len - 1] = '\0'; - - if (strncmp(buf, "enable", 5) == 0) { - if (strict_strtoul(buf + 7, 10, &port)) - return -EINVAL; - params = ehci_readl(ehci, &ehci->caps->hcs_params); - if (port > HCS_N_PORTS(params)) { - ehci_dbg(ehci, "ERR: LPM on bad port %lu\n", port); - return -ENODEV; - } - portsc = &ehci->regs->port_status[port-1]; - temp = ehci_readl(ehci, portsc); - if (!(temp & PORT_DEV_ADDR)) { - ehci_dbg(ehci, "LPM: no device attached\n"); - return -ENODEV; - } - temp |= PORT_LPM; - ehci_writel(ehci, temp, portsc); - printk(KERN_INFO "force enable LPM for port %lu\n", port); - } else if (strncmp(buf, "hird=", 5) == 0) { - unsigned long hird; - if (strict_strtoul(buf + 5, 16, &hird)) - return -EINVAL; - printk(KERN_INFO "setting hird %s %lu\n", buf + 6, hird); - ehci->command = (ehci->command & ~CMD_HIRD) | (hird << 24); - ehci_writel(ehci, ehci->command, &ehci->regs->command); - } else if (strncmp(buf, "disable", 7) == 0) { - if (strict_strtoul(buf + 8, 10, &port)) - return -EINVAL; - params = ehci_readl(ehci, &ehci->caps->hcs_params); - if (port > HCS_N_PORTS(params)) { - ehci_dbg(ehci, "ERR: LPM off bad port %lu\n", port); - return -ENODEV; - } - portsc = &ehci->regs->port_status[port-1]; - temp = ehci_readl(ehci, portsc); - if (!(temp & PORT_DEV_ADDR)) { - ehci_dbg(ehci, "ERR: no device attached\n"); - return -ENODEV; - } - temp &= ~PORT_LPM; - ehci_writel(ehci, temp, portsc); - printk(KERN_INFO "disabled LPM for port %lu\n", port); - } else - return -EOPNOTSUPP; - return count; -} - static inline void create_debug_files (struct ehci_hcd *ehci) { struct usb_bus *bus = &ehci_to_hcd(ehci)->self; @@ -1056,10 +963,6 @@ static inline void create_debug_files (struct ehci_hcd *ehci) &debug_registers_fops)) goto file_error; - if (!debugfs_create_file("lpm", S_IRUGO|S_IWUSR, ehci->debug_dir, bus, - &debug_lpm_fops)) - goto file_error; - return; file_error: diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 9c2afb516fe..68dd1c99b1f 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include @@ -108,11 +107,6 @@ static bool ignore_oc = 0; module_param (ignore_oc, bool, S_IRUGO); MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); -/* for link power management(LPM) feature */ -static unsigned int hird; -module_param(hird, int, S_IRUGO); -MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us"); - #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) /*-------------------------------------------------------------------------*/ @@ -318,7 +312,6 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); #include "ehci-timer.c" #include "ehci-hub.c" -#include "ehci-lpm.c" #include "ehci-mem.c" #include "ehci-q.c" #include "ehci-sched.c" @@ -580,17 +573,6 @@ static int ehci_init(struct usb_hcd *hcd) temp &= ~(3 << 2); temp |= (EHCI_TUNE_FLS << 2); } - if (HCC_LPM(hcc_params)) { - /* support link power management EHCI 1.1 addendum */ - ehci_dbg(ehci, "support lpm\n"); - ehci->has_lpm = 1; - if (hird > 0xf) { - ehci_dbg(ehci, "hird %d invalid, use default 0", - hird); - hird = 0; - } - temp |= hird << 24; - } ehci->command = temp; /* Accept arbitrarily long scatter-gather lists */ diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index a7ec827ca2c..a2c56cdd2c3 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -777,11 +777,6 @@ static int ehci_hub_control ( status_reg); break; case USB_PORT_FEAT_C_CONNECTION: - if (ehci->has_lpm) { - /* clear PORTSC bits on disconnect */ - temp &= ~PORT_LPM; - temp &= ~PORT_DEV_ADDR; - } ehci_writel(ehci, temp | PORT_CSC, status_reg); break; case USB_PORT_FEAT_C_OVER_CURRENT: diff --git a/drivers/usb/host/ehci-lpm.c b/drivers/usb/host/ehci-lpm.c deleted file mode 100644 index 6b092c1dff6..00000000000 --- a/drivers/usb/host/ehci-lpm.c +++ /dev/null @@ -1,101 +0,0 @@ -/* ehci-lpm.c EHCI HCD LPM support code - * Copyright (c) 2008 - 2010, Intel Corporation. - * Author: Jacob Pan - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* this file is part of ehci-hcd.c */ - -static int ehci_lpm_set_da(struct ehci_hcd *ehci, int dev_addr, int port_num) -{ - u32 __iomem portsc; - - ehci_dbg(ehci, "set dev address %d for port %d\n", dev_addr, port_num); - if (port_num > HCS_N_PORTS(ehci->hcs_params)) { - ehci_dbg(ehci, "invalid port number %d\n", port_num); - return -ENODEV; - } - portsc = ehci_readl(ehci, &ehci->regs->port_status[port_num-1]); - portsc &= ~PORT_DEV_ADDR; - portsc |= dev_addr<<25; - ehci_writel(ehci, portsc, &ehci->regs->port_status[port_num-1]); - return 0; -} - -/* - * this function is used to check if the device support LPM - * if yes, mark the PORTSC register with PORT_LPM bit - */ -static int ehci_lpm_check(struct ehci_hcd *ehci, int port) -{ - u32 __iomem *portsc ; - u32 val32; - int retval; - - portsc = &ehci->regs->port_status[port-1]; - val32 = ehci_readl(ehci, portsc); - if (!(val32 & PORT_DEV_ADDR)) { - ehci_dbg(ehci, "LPM: no device attached\n"); - return -ENODEV; - } - val32 |= PORT_LPM; - ehci_writel(ehci, val32, portsc); - msleep(5); - val32 |= PORT_SUSPEND; - ehci_dbg(ehci, "Sending LPM 0x%08x to port %d\n", val32, port); - ehci_writel(ehci, val32, portsc); - /* wait for ACK */ - msleep(10); - retval = handshake(ehci, &ehci->regs->port_status[port-1], PORT_SSTS, - PORTSC_SUSPEND_STS_ACK, 125); - dbg_port(ehci, "LPM", port, val32); - if (retval != -ETIMEDOUT) { - ehci_dbg(ehci, "LPM: device ACK for LPM\n"); - val32 |= PORT_LPM; - /* - * now device should be in L1 sleep, let's wake up the device - * so that we can complete enumeration. - */ - ehci_writel(ehci, val32, portsc); - msleep(10); - val32 |= PORT_RESUME; - ehci_writel(ehci, val32, portsc); - } else { - ehci_dbg(ehci, "LPM: device does not ACK, disable LPM %d\n", - retval); - val32 &= ~PORT_LPM; - retval = -ETIMEDOUT; - ehci_writel(ehci, val32, portsc); - } - - return retval; -} - -static int __maybe_unused ehci_update_device(struct usb_hcd *hcd, - struct usb_device *udev) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int rc = 0; - - if (!udev->parent) /* udev is root hub itself, impossible */ - rc = -1; - /* we only support lpm device connected to root hub yet */ - if (ehci->has_lpm && !udev->parent->parent) { - rc = ehci_lpm_set_da(ehci, udev->devnum, udev->portnum); - if (!rc) - rc = ehci_lpm_check(ehci, udev->portnum); - } - return rc; -} diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 7880ba621f8..e17330ae0ae 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -202,11 +202,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) break; case PCI_VENDOR_ID_INTEL: ehci->need_io_watchdog = 0; - if (pdev->device == 0x0806 || pdev->device == 0x0811 - || pdev->device == 0x0829) { - ehci_info(ehci, "disable lpm for langwell/penwell\n"); - ehci->has_lpm = 0; - } break; case PCI_VENDOR_ID_NVIDIA: switch (pdev->device) { @@ -216,8 +211,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) * devices with PPCD enabled. */ case 0x0d9d: - ehci_info(ehci, "disable lpm/ppcd for nvidia mcp89"); - ehci->has_lpm = 0; + ehci_info(ehci, "disable ppcd for nvidia mcp89\n"); ehci->has_ppcd = 0; ehci->command &= ~CMD_PPCEE; break; @@ -425,11 +419,6 @@ static const struct hc_driver ehci_pci_hc_driver = { .relinquish_port = ehci_relinquish_port, .port_handed_over = ehci_port_handed_over, - /* - * call back when device connected and addressed - */ - .update_device = ehci_update_device, - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, }; diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c index c6fe0bb619c..11695d5b9d8 100644 --- a/drivers/usb/host/ehci-vt8500.c +++ b/drivers/usb/host/ehci-vt8500.c @@ -61,11 +61,6 @@ static const struct hc_driver vt8500_ehci_hc_driver = { .relinquish_port = ehci_relinquish_port, .port_handed_over = ehci_port_handed_over, - /* - * call back when device connected and addressed - */ - .update_device = ehci_update_device, - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, }; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index ec948c3b1ce..2262dcdaa3c 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -206,7 +206,6 @@ struct ehci_hcd { /* one per controller */ #define OHCI_HCCTRL_LEN 0x4 __hc32 *ohci_hcctrl_reg; unsigned has_hostpc:1; - unsigned has_lpm:1; /* support link power management */ unsigned has_ppcd:1; /* support per-port change bits */ u8 sbrn; /* packed release number */ -- cgit v1.2.3 From c73cee717e7d5da0698acb720ad1219646fe4f46 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 31 Oct 2012 13:21:06 -0400 Subject: USB: EHCI: remove ehci_port_power() routine This patch (as1623) removes the ehci_port_power() routine and all the places that call it. There's no reason for ehci-hcd to change the port power settings; the hub driver takes care of all that stuff. There is one exception: When the controller is resumed from hibernation or following a loss of power, the ports that are supposed to be handed over to a companion controller must be powered on first. Otherwise the handover won't work. This process is not visible to the hub driver, so it has to be handled in ehci-hcd. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-cns3xxx/cns3420vb.c | 1 - arch/mips/ath79/dev-usb.c | 2 -- arch/mips/loongson1/common/platform.c | 1 - drivers/usb/chipidea/host.c | 18 +----------------- drivers/usb/host/ehci-atmel.c | 9 +-------- drivers/usb/host/ehci-fsl.c | 1 - drivers/usb/host/ehci-grlib.c | 18 +----------------- drivers/usb/host/ehci-hcd.c | 21 --------------------- drivers/usb/host/ehci-hub.c | 13 +++++++++++++ drivers/usb/host/ehci-msm.c | 1 - drivers/usb/host/ehci-mxc.c | 8 +------- drivers/usb/host/ehci-octeon.c | 3 --- drivers/usb/host/ehci-omap.c | 3 --- drivers/usb/host/ehci-orion.c | 16 +--------------- drivers/usb/host/ehci-pci.c | 1 - drivers/usb/host/ehci-platform.c | 5 ----- drivers/usb/host/ehci-pmcmsp.c | 1 - drivers/usb/host/ehci-sh.c | 9 +-------- drivers/usb/host/ehci-spear.c | 9 +-------- drivers/usb/host/ehci-tegra.c | 8 +------- include/linux/usb/ehci_pdriver.h | 2 -- 21 files changed, 21 insertions(+), 129 deletions(-) diff --git a/arch/arm/mach-cns3xxx/cns3420vb.c b/arch/arm/mach-cns3xxx/cns3420vb.c index 8a00cee8222..ae305397003 100644 --- a/arch/arm/mach-cns3xxx/cns3420vb.c +++ b/arch/arm/mach-cns3xxx/cns3420vb.c @@ -162,7 +162,6 @@ static void csn3xxx_usb_power_off(struct platform_device *pdev) } static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = { - .port_power_off = 1, .power_on = csn3xxx_usb_power_on, .power_off = csn3xxx_usb_power_off, }; diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c index 072bb9be230..bd2bc108e1b 100644 --- a/arch/mips/ath79/dev-usb.c +++ b/arch/mips/ath79/dev-usb.c @@ -50,13 +50,11 @@ static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32); static struct usb_ehci_pdata ath79_ehci_pdata_v1 = { .has_synopsys_hc_bug = 1, - .port_power_off = 1, }; static struct usb_ehci_pdata ath79_ehci_pdata_v2 = { .caps_offset = 0x100, .has_tt = 1, - .port_power_off = 1, }; static struct platform_device ath79_ehci_device = { diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c index 2874bf22441..0412ad61e29 100644 --- a/arch/mips/loongson1/common/platform.c +++ b/arch/mips/loongson1/common/platform.c @@ -109,7 +109,6 @@ static struct resource ls1x_ehci_resources[] = { }; static struct usb_ehci_pdata ls1x_ehci_pdata = { - .port_power_off = 1, }; struct platform_device ls1x_ehci_device = { diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index ebff9f4f56e..ebc041ff9cd 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -31,22 +31,6 @@ #include "bits.h" #include "host.h" -static int ci_ehci_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int ret; - - hcd->has_tt = 1; - - ret = ehci_setup(hcd); - if (ret) - return ret; - - ehci_port_power(ehci, 0); - - return ret; -} - static const struct hc_driver ci_ehci_hc_driver = { .description = "ehci_hcd", .product_desc = "ChipIdea HDRC EHCI", @@ -61,7 +45,7 @@ static const struct hc_driver ci_ehci_hc_driver = { /* * basic lifecycle operations */ - .reset = ci_ehci_setup, + .reset = ehci_setup, .start = ehci_run, .stop = ehci_stop, .shutdown = ehci_shutdown, diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 411bb74152e..d23321ec0e4 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -53,18 +53,11 @@ static void atmel_stop_ehci(struct platform_device *pdev) static int ehci_atmel_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; /* registers start at offset 0x0 */ ehci->caps = hcd->regs; - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 0); - - return retval; + return ehci_setup(hcd); } static const struct hc_driver ehci_atmel_hc_driver = { diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 0d2f35ca93f..fd9b5424b86 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -349,7 +349,6 @@ static int ehci_fsl_reinit(struct ehci_hcd *ehci) { if (ehci_fsl_usb_setup(ehci)) return -EINVAL; - ehci_port_power(ehci, 0); return 0; } diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c index 3180cb3624d..da4269550fb 100644 --- a/drivers/usb/host/ehci-grlib.c +++ b/drivers/usb/host/ehci-grlib.c @@ -34,22 +34,6 @@ #define GRUSBHC_HCIVERSION 0x0100 /* Known value of cap. reg. HCIVERSION */ -/* called during probe() after chip reset completes */ -static int ehci_grlib_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; - - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 1); - - return retval; -} - - static const struct hc_driver ehci_grlib_hc_driver = { .description = hcd_name, .product_desc = "GRLIB GRUSBHC EHCI", @@ -64,7 +48,7 @@ static const struct hc_driver ehci_grlib_hc_driver = { /* * basic lifecycle operations */ - .reset = ehci_grlib_setup, + .reset = ehci_setup, .start = ehci_run, .stop = ehci_stop, .shutdown = ehci_shutdown, diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 68dd1c99b1f..ab4a769a410 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -371,24 +371,6 @@ static void ehci_shutdown(struct usb_hcd *hcd) hrtimer_cancel(&ehci->hrtimer); } -static void ehci_port_power (struct ehci_hcd *ehci, int is_on) -{ - unsigned port; - - if (!HCS_PPC (ehci->hcs_params)) - return; - - ehci_dbg (ehci, "...power%s ports...\n", is_on ? "up" : "down"); - for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) - (void) ehci_hub_control(ehci_to_hcd(ehci), - is_on ? SetPortFeature : ClearPortFeature, - USB_PORT_FEAT_POWER, - port--, NULL, 0); - /* Flush those writes */ - ehci_readl(ehci, &ehci->regs->command); - msleep(20); -} - /*-------------------------------------------------------------------------*/ /* @@ -1184,9 +1166,6 @@ static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated) ehci->rh_state = EHCI_RH_SUSPENDED; spin_unlock_irq(&ehci->lock); - /* here we "know" root ports should always stay powered */ - ehci_port_power(ehci, 1); - return 1; } diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index a2c56cdd2c3..a59c61fea09 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -56,6 +56,19 @@ static void ehci_handover_companion_ports(struct ehci_hcd *ehci) if (!ehci->owned_ports) return; + /* Make sure the ports are powered */ + port = HCS_N_PORTS(ehci->hcs_params); + while (port--) { + if (test_bit(port, &ehci->owned_ports)) { + reg = &ehci->regs->port_status[port]; + status = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; + if (!(status & PORT_POWER)) { + status |= PORT_POWER; + ehci_writel(ehci, status, reg); + } + } + } + /* Give the connections some time to appear */ msleep(20); diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 4af4dc5b618..7fa1ba4de78 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -53,7 +53,6 @@ static int ehci_msm_reset(struct usb_hcd *hcd) /* Disable streaming mode and select host mode */ writel(0x13, USB_USBMODE); - ehci_port_power(ehci, 1); return 0; } diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index 4a08fc0b27c..a37224a4a49 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -40,16 +40,10 @@ struct ehci_mxc_priv { static int ehci_mxc_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; hcd->has_tt = 1; - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 0); - return 0; + return ehci_setup(hcd); } static const struct hc_driver ehci_mxc_hc_driver = { diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c index ba26957abf4..a89750fff4f 100644 --- a/drivers/usb/host/ehci-octeon.c +++ b/drivers/usb/host/ehci-octeon.c @@ -159,9 +159,6 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev) platform_set_drvdata(pdev, hcd); - /* root ports should always stay powered */ - ehci_port_power(ehci, 1); - return 0; err3: ehci_octeon_stop(); diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index d7fe287d067..44e7d0f638e 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -146,9 +146,6 @@ static int omap_ehci_init(struct usb_hcd *hcd) gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1); } - /* root ports should always stay powered */ - ehci_port_power(ehci, 1); - return rc; } diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 9c2717d6673..96da679bece 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -101,20 +101,6 @@ static void orion_usb_phy_v1_setup(struct usb_hcd *hcd) wrl(USB_MODE, 0x13); } -static int ehci_orion_setup(struct usb_hcd *hcd) -{ - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; - - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 0); - - return retval; -} - static const struct hc_driver ehci_orion_hc_driver = { .description = hcd_name, .product_desc = "Marvell Orion EHCI", @@ -129,7 +115,7 @@ static const struct hc_driver ehci_orion_hc_driver = { /* * basic lifecycle operations */ - .reset = ehci_orion_setup, + .reset = ehci_setup, .start = ehci_run, .stop = ehci_stop, .shutdown = ehci_shutdown, diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index e17330ae0ae..c92dcaee0d4 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -297,7 +297,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) ehci_warn(ehci, "selective suspend/wakeup unavailable\n"); #endif - ehci_port_power(ehci, 1); retval = ehci_pci_reinit(ehci, pdev); done: return retval; diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 272728c48c9..6e6c23bdb48 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -40,11 +40,6 @@ static int ehci_platform_reset(struct usb_hcd *hcd) if (pdata->no_io_watchdog) ehci->need_io_watchdog = 0; - if (pdata->port_power_on) - ehci_port_power(ehci, 1); - if (pdata->port_power_off) - ehci_port_power(ehci, 0); - return 0; } diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c index 087aee2a904..363890ee41d 100644 --- a/drivers/usb/host/ehci-pmcmsp.c +++ b/drivers/usb/host/ehci-pmcmsp.c @@ -90,7 +90,6 @@ static int ehci_msp_setup(struct usb_hcd *hcd) return retval; usb_hcd_tdi_set_mode(ehci); - ehci_port_power(ehci, 0); return retval; } diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index 6081e1ed3ac..0c90a24fa98 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -21,17 +21,10 @@ struct ehci_sh_priv { static int ehci_sh_reset(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int ret; ehci->caps = hcd->regs; - ret = ehci_setup(hcd); - if (unlikely(ret)) - return ret; - - ehci_port_power(ehci, 0); - - return ret; + return ehci_setup(hcd); } static const struct hc_driver ehci_sh_hc_driver = { diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c index c718a065e15..719ca48a471 100644 --- a/drivers/usb/host/ehci-spear.c +++ b/drivers/usb/host/ehci-spear.c @@ -37,18 +37,11 @@ static void spear_stop_ehci(struct spear_ehci *ehci) static int ehci_spear_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval = 0; /* registers start at offset 0x0 */ ehci->caps = hcd->regs; - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 0); - - return retval; + return ehci_setup(hcd); } static const struct hc_driver ehci_spear_hc_driver = { diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 2de089001ae..94ee3212094 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -280,7 +280,6 @@ static void tegra_ehci_shutdown(struct usb_hcd *hcd) static int tegra_ehci_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - int retval; /* EHCI registers start at offset 0x100 */ ehci->caps = hcd->regs + 0x100; @@ -288,12 +287,7 @@ static int tegra_ehci_setup(struct usb_hcd *hcd) /* switch to host mode */ hcd->has_tt = 1; - retval = ehci_setup(hcd); - if (retval) - return retval; - - ehci_port_power(ehci, 1); - return retval; + return ehci_setup(hcd); } struct dma_aligned_buffer { diff --git a/include/linux/usb/ehci_pdriver.h b/include/linux/usb/ehci_pdriver.h index 67ac74bde6d..99238b096f7 100644 --- a/include/linux/usb/ehci_pdriver.h +++ b/include/linux/usb/ehci_pdriver.h @@ -41,8 +41,6 @@ struct usb_ehci_pdata { unsigned has_synopsys_hc_bug:1; unsigned big_endian_desc:1; unsigned big_endian_mmio:1; - unsigned port_power_on:1; - unsigned port_power_off:1; unsigned no_io_watchdog:1; /* Turn on all power and clocks */ -- cgit v1.2.3 From 1b95bee5630766448f40eecaa08b722f256335ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 31 Oct 2012 06:08:38 +0100 Subject: USB: option: never bind to a usb-storage interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are many modems in addition to the D-Link DWM 652 exposing the CD interface in modem mode, and some expose an integrated card reader as well. Always ignore these interfaces. Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e9cffac49cd..2f01b2dce5b 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1340,13 +1340,8 @@ static int option_probe(struct usb_serial *serial, &serial->interface->cur_altsetting->desc; struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; - /* - * D-Link DWM 652 still exposes CD-Rom emulation interface in modem - * mode. - */ - if (dev_desc->idVendor == DLINK_VENDOR_ID && - dev_desc->idProduct == DLINK_PRODUCT_DWM_652 && - iface_desc->bInterfaceClass == 0x08) + /* Never bind to the CD-Rom emulation interface */ + if (iface_desc->bInterfaceClass == 0x08) return -ENODEV; /* Bandrich modem and AT command interface is 0xff */ -- cgit v1.2.3 From 17b72feb2be14e6d37023267dc0e199e8e0e3fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 31 Oct 2012 06:08:39 +0100 Subject: USB: add USB_DEVICE_INTERFACE_CLASS macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Matching on device and interface class with with unspecified subclass and protocol is sometimes useful. This is slightly different from USB_DEVICE_AND_INTERFACE_INFO which requires the full interface class/subclass/protocol triplet. Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/linux/usb.h b/include/linux/usb.h index f51f9981de1..689b14b26c8 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -807,6 +807,22 @@ static inline int usb_make_path(struct usb_device *dev, char *buf, size_t size) .bcdDevice_lo = (lo), \ .bcdDevice_hi = (hi) +/** + * USB_DEVICE_INTERFACE_CLASS - describe a usb device with a specific interface class + * @vend: the 16 bit USB Vendor ID + * @prod: the 16 bit USB Product ID + * @cl: bInterfaceClass value + * + * This macro is used to create a struct usb_device_id that matches a + * specific interface class of devices. + */ +#define USB_DEVICE_INTERFACE_CLASS(vend, prod, cl) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ + USB_DEVICE_ID_MATCH_INT_CLASS, \ + .idVendor = (vend), \ + .idProduct = (prod), \ + .bInterfaceClass = (cl) + /** * USB_DEVICE_INTERFACE_PROTOCOL - describe a usb device with a specific interface protocol * @vend: the 16 bit USB Vendor ID -- cgit v1.2.3 From dbdf680703b98b5a17f84816ca92d70c21ada038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 31 Oct 2012 06:08:40 +0100 Subject: USB: option: replace vendor probe rule with match flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need for a vendor specific probe exception just to match on the interface class. Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 71 +++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 2f01b2dce5b..05fa671e13d 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -732,23 +732,23 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, { USB_DEVICE(YISO_VENDOR_ID, YISO_PRODUCT_U893) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1005) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1006) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1007) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1008) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1009) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100A) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100B) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100C) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100D) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100E) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100F) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1010) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1011) }, - { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1005, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1006, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1007, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1008, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1009, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100A, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100B, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100C, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100D, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100E, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100F, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1010, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1011, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012, 0xff) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ @@ -1164,22 +1164,22 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) }, { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, /* Pirelli */ - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, - { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_1, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_C100_2, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1004, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1005, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1006, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1007, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1008, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1009, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100A, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100B, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100C, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100D, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100E, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012, 0xff) }, /* Cinterion */ { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, @@ -1344,11 +1344,6 @@ static int option_probe(struct usb_serial *serial, if (iface_desc->bInterfaceClass == 0x08) return -ENODEV; - /* Bandrich modem and AT command interface is 0xff */ - if ((dev_desc->idVendor == BANDRICH_VENDOR_ID || - dev_desc->idVendor == PIRELLI_VENDOR_ID) && - iface_desc->bInterfaceClass != 0xff) - return -ENODEV; /* * Don't bind reserved interfaces (like network ones) which often have * the same class/subclass/protocol as the serial interfaces. Look at -- cgit v1.2.3 From 7c83b4483606f5fe14127249336ac53ef177a63a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 31 Oct 2012 06:08:41 +0100 Subject: USB: option: idVendor and idProduct are __le16 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The exception is needed on big endian systems too. Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 05fa671e13d..5839f4d662d 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1358,9 +1358,9 @@ static int option_probe(struct usb_serial *serial, * Don't bind network interface on Samsung GT-B3730, it is handled by * a separate module. */ - if (dev_desc->idVendor == SAMSUNG_VENDOR_ID && - dev_desc->idProduct == SAMSUNG_PRODUCT_GT_B3730 && - iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) + if (dev_desc->idVendor == cpu_to_le16(SAMSUNG_VENDOR_ID) && + dev_desc->idProduct == cpu_to_le16(SAMSUNG_PRODUCT_GT_B3730) && + iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) return -ENODEV; /* Store device id so we can use it during attach. */ -- cgit v1.2.3 From 2bbf0a1427c377350f001fbc6260995334739ad7 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Wed, 31 Oct 2012 17:20:50 +0100 Subject: x86, amd: Disable way access filter on Piledriver CPUs The Way Access Filter in recent AMD CPUs may hurt the performance of some workloads, caused by aliasing issues in the L1 cache. This patch disables it on the affected CPUs. The issue is similar to that one of last year: http://lkml.indiana.edu/hypermail/linux/kernel/1107.3/00041.html This new patch does not replace the old one, we just need another quirk for newer CPUs. The performance penalty without the patch depends on the circumstances, but is a bit less than the last year's 3%. The workloads affected would be those that access code from the same physical page under different virtual addresses, so different processes using the same libraries with ASLR or multiple instances of PIE-binaries. The code needs to be accessed simultaneously from both cores of the same compute unit. More details can be found here: http://developer.amd.com/Assets/SharedL1InstructionCacheonAMD15hCPU.pdf CPUs affected are anything with the core known as Piledriver. That includes the new parts of the AMD A-Series (aka Trinity) and the just released new CPUs of the FX-Series (aka Vishera). The model numbering is a bit odd here: FX CPUs have model 2, A-Series has model 10h, with possible extensions to 1Fh. Hence the range of model ids. Signed-off-by: Andre Przywara Link: http://lkml.kernel.org/r/1351700450-9277-1-git-send-email-osp@andrep.de Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/amd.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index f7e98a2c0d1..1b7d1656a04 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -631,6 +631,20 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) } } + /* + * The way access filter has a performance penalty on some workloads. + * Disable it on the affected CPUs. + */ + if ((c->x86 == 0x15) && + (c->x86_model >= 0x02) && (c->x86_model < 0x20)) { + u64 val; + + if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) { + val |= 0x1E; + wrmsrl_safe(0xc0011021, val); + } + } + cpu_detect_cache_sizes(c); /* Multi core CPU? */ -- cgit v1.2.3 From bcd83ea6cbfee54e33d1527b87538dc99ca2137b Mon Sep 17 00:00:00 2001 From: Daniel Walter Date: Wed, 26 Sep 2012 22:08:38 +0200 Subject: tracing: Replace strict_strto* with kstrto* * remove old string conversions with kstrto* Link: http://lkml.kernel.org/r/20120926200838.GC1244@0x90.at Signed-off-by: Daniel Walter Signed-off-by: Steven Rostedt --- kernel/trace/ftrace.c | 2 +- kernel/trace/trace.c | 2 +- kernel/trace/trace_events_filter.c | 4 ++-- kernel/trace/trace_functions.c | 2 +- kernel/trace/trace_kprobe.c | 2 +- kernel/trace/trace_probe.c | 14 +++++++------- kernel/trace/trace_uprobe.c | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 9dcf15d3838..60ad606dc85 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -4381,7 +4381,7 @@ ftrace_pid_write(struct file *filp, const char __user *ubuf, if (strlen(tmp) == 0) return 1; - ret = strict_strtol(tmp, 10, &val); + ret = kstrtol(tmp, 10, &val); if (ret < 0) return ret; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 31e4f55773f..f6928edacd6 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -431,7 +431,7 @@ static int __init set_tracing_thresh(char *str) if (!str) return 0; - ret = strict_strtoul(str, 0, &threshold); + ret = kstrtoul(str, 0, &threshold); if (ret < 0) return 0; tracing_thresh = threshold * 1000; diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index c154797a7ff..e5b0ca8b8d4 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -1000,9 +1000,9 @@ static int init_pred(struct filter_parse_state *ps, } } else { if (field->is_signed) - ret = strict_strtoll(pred->regex.pattern, 0, &val); + ret = kstrtoll(pred->regex.pattern, 0, &val); else - ret = strict_strtoull(pred->regex.pattern, 0, &val); + ret = kstrtoull(pred->regex.pattern, 0, &val); if (ret) { parse_error(ps, FILT_ERR_ILLEGAL_INTVAL, 0); return -EINVAL; diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 507a7a9630b..618dcf8bdb8 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -366,7 +366,7 @@ ftrace_trace_onoff_callback(struct ftrace_hash *hash, * We use the callback data field (which is a pointer) * as our counter. */ - ret = strict_strtoul(number, 0, (unsigned long *)&count); + ret = kstrtoul(number, 0, (unsigned long *)&count); if (ret) return ret; diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1a2117043bb..5a3c533ef06 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -444,7 +444,7 @@ static int create_trace_probe(int argc, char **argv) return -EINVAL; } /* an address specified */ - ret = strict_strtoul(&argv[1][0], 0, (unsigned long *)&addr); + ret = kstrtoul(&argv[1][0], 0, (unsigned long *)&addr); if (ret) { pr_info("Failed to parse address.\n"); return ret; diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index daa9980153a..412e959709b 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -441,7 +441,7 @@ static const struct fetch_type *find_fetch_type(const char *type) goto fail; type++; - if (strict_strtoul(type, 0, &bs)) + if (kstrtoul(type, 0, &bs)) goto fail; switch (bs) { @@ -501,8 +501,8 @@ int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset) tmp = strchr(symbol, '+'); if (tmp) { - /* skip sign because strict_strtol doesn't accept '+' */ - ret = strict_strtoul(tmp + 1, 0, offset); + /* skip sign because kstrtoul doesn't accept '+' */ + ret = kstrtoul(tmp + 1, 0, offset); if (ret) return ret; @@ -533,7 +533,7 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t, else ret = -EINVAL; } else if (isdigit(arg[5])) { - ret = strict_strtoul(arg + 5, 10, ¶m); + ret = kstrtoul(arg + 5, 10, ¶m); if (ret || param > PARAM_MAX_STACK) ret = -EINVAL; else { @@ -579,7 +579,7 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t, case '@': /* memory or symbol */ if (isdigit(arg[1])) { - ret = strict_strtoul(arg + 1, 0, ¶m); + ret = kstrtoul(arg + 1, 0, ¶m); if (ret) break; @@ -597,14 +597,14 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t, break; case '+': /* deref memory */ - arg++; /* Skip '+', because strict_strtol() rejects it. */ + arg++; /* Skip '+', because kstrtol() rejects it. */ case '-': tmp = strchr(arg, '('); if (!tmp) break; *tmp = '\0'; - ret = strict_strtol(arg, 0, &offset); + ret = kstrtol(arg, 0, &offset); if (ret) break; diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 03003cd7dd9..4ff9ca4f359 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -252,7 +252,7 @@ static int create_trace_uprobe(int argc, char **argv) if (ret) goto fail_address_parse; - ret = strict_strtoul(arg, 0, &offset); + ret = kstrtoul(arg, 0, &offset); if (ret) goto fail_address_parse; -- cgit v1.2.3 From 6f4156723c084bfc0c0f72205c541fafb8ad3ded Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 5 Oct 2012 12:13:07 -0400 Subject: tracing: Allow tracers to start at core initcall There's times during debugging that it is helpful to see traces of early boot functions. But the tracers are initialized at device_initcall() which is quite late during the boot process. Setting the kernel command line parameter ftrace=function will not show anything until the function tracer is initialized. This prevents being able to trace functions before device_initcall(). There's no reason that the tracers need to be initialized so late in the boot process. Move them up to core_initcall() as they still need to come after early_initcall() which initializes the tracing buffers. Cc: Thomas Gleixner Signed-off-by: Steven Rostedt --- kernel/trace/ftrace.c | 4 ++-- kernel/trace/trace_branch.c | 2 +- kernel/trace/trace_functions.c | 3 +-- kernel/trace/trace_functions_graph.c | 2 +- kernel/trace/trace_irqsoff.c | 2 +- kernel/trace/trace_sched_wakeup.c | 2 +- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 60ad606dc85..4451aa3a55a 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2868,7 +2868,7 @@ static int __init ftrace_mod_cmd_init(void) { return register_ftrace_command(&ftrace_mod_cmd); } -device_initcall(ftrace_mod_cmd_init); +core_initcall(ftrace_mod_cmd_init); static void function_trace_probe_call(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *op, struct pt_regs *pt_regs) @@ -4055,7 +4055,7 @@ static int __init ftrace_nodyn_init(void) ftrace_enabled = 1; return 0; } -device_initcall(ftrace_nodyn_init); +core_initcall(ftrace_nodyn_init); static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; } static inline void ftrace_startup_enable(int command) { } diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c index 8d3538b4ea5..bd3e0eef4ea 100644 --- a/kernel/trace/trace_branch.c +++ b/kernel/trace/trace_branch.c @@ -199,7 +199,7 @@ __init static int init_branch_tracer(void) } return register_tracer(&branch_trace); } -device_initcall(init_branch_tracer); +core_initcall(init_branch_tracer); #else static inline diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 618dcf8bdb8..bb227e380cb 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -411,5 +411,4 @@ static __init int init_function_trace(void) init_func_cmd_traceon(); return register_tracer(&function_trace); } -device_initcall(init_function_trace); - +core_initcall(init_function_trace); diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 99b4378393d..a84b55879bc 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -1474,4 +1474,4 @@ static __init int init_graph_trace(void) return register_tracer(&graph_trace); } -device_initcall(init_graph_trace); +core_initcall(init_graph_trace); diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index d98ee8283b2..11edebda454 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -698,4 +698,4 @@ __init static int init_irqsoff_tracer(void) return 0; } -device_initcall(init_irqsoff_tracer); +core_initcall(init_irqsoff_tracer); diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 02170c00c41..2f6af783369 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -637,4 +637,4 @@ __init static int init_wakeup_tracer(void) return 0; } -device_initcall(init_wakeup_tracer); +core_initcall(init_wakeup_tracer); -- cgit v1.2.3 From f43c738bfa8608424610e4fc1aef4d4644e2ce11 Mon Sep 17 00:00:00 2001 From: Hiraku Toyooka Date: Tue, 2 Oct 2012 17:27:10 +0900 Subject: tracing: Change tracer's integer flags to bool print_max and use_max_tr in struct tracer are "int" variables and used like flags. This is wasteful, so change the type to "bool". Link: http://lkml.kernel.org/r/20121002082710.9807.86393.stgit@falsita Signed-off-by: Hiraku Toyooka Signed-off-by: Steven Rostedt --- kernel/trace/trace.h | 4 ++-- kernel/trace/trace_irqsoff.c | 12 ++++++------ kernel/trace/trace_sched_wakeup.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index c15f528c1af..c56a233c006 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -285,8 +285,8 @@ struct tracer { int (*set_flag)(u32 old_flags, u32 bit, int set); struct tracer *next; struct tracer_flags *flags; - int print_max; - int use_max_tr; + bool print_max; + bool use_max_tr; }; diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 11edebda454..5ffce7b0f33 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -604,7 +604,7 @@ static struct tracer irqsoff_tracer __read_mostly = .reset = irqsoff_tracer_reset, .start = irqsoff_tracer_start, .stop = irqsoff_tracer_stop, - .print_max = 1, + .print_max = true, .print_header = irqsoff_print_header, .print_line = irqsoff_print_line, .flags = &tracer_flags, @@ -614,7 +614,7 @@ static struct tracer irqsoff_tracer __read_mostly = #endif .open = irqsoff_trace_open, .close = irqsoff_trace_close, - .use_max_tr = 1, + .use_max_tr = true, }; # define register_irqsoff(trace) register_tracer(&trace) #else @@ -637,7 +637,7 @@ static struct tracer preemptoff_tracer __read_mostly = .reset = irqsoff_tracer_reset, .start = irqsoff_tracer_start, .stop = irqsoff_tracer_stop, - .print_max = 1, + .print_max = true, .print_header = irqsoff_print_header, .print_line = irqsoff_print_line, .flags = &tracer_flags, @@ -647,7 +647,7 @@ static struct tracer preemptoff_tracer __read_mostly = #endif .open = irqsoff_trace_open, .close = irqsoff_trace_close, - .use_max_tr = 1, + .use_max_tr = true, }; # define register_preemptoff(trace) register_tracer(&trace) #else @@ -672,7 +672,7 @@ static struct tracer preemptirqsoff_tracer __read_mostly = .reset = irqsoff_tracer_reset, .start = irqsoff_tracer_start, .stop = irqsoff_tracer_stop, - .print_max = 1, + .print_max = true, .print_header = irqsoff_print_header, .print_line = irqsoff_print_line, .flags = &tracer_flags, @@ -682,7 +682,7 @@ static struct tracer preemptirqsoff_tracer __read_mostly = #endif .open = irqsoff_trace_open, .close = irqsoff_trace_close, - .use_max_tr = 1, + .use_max_tr = true, }; # define register_preemptirqsoff(trace) register_tracer(&trace) diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 2f6af783369..bc64fc13755 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -589,7 +589,7 @@ static struct tracer wakeup_tracer __read_mostly = .reset = wakeup_tracer_reset, .start = wakeup_tracer_start, .stop = wakeup_tracer_stop, - .print_max = 1, + .print_max = true, .print_header = wakeup_print_header, .print_line = wakeup_print_line, .flags = &tracer_flags, @@ -599,7 +599,7 @@ static struct tracer wakeup_tracer __read_mostly = #endif .open = wakeup_trace_open, .close = wakeup_trace_close, - .use_max_tr = 1, + .use_max_tr = true, }; static struct tracer wakeup_rt_tracer __read_mostly = @@ -610,7 +610,7 @@ static struct tracer wakeup_rt_tracer __read_mostly = .start = wakeup_tracer_start, .stop = wakeup_tracer_stop, .wait_pipe = poll_wait_pipe, - .print_max = 1, + .print_max = true, .print_header = wakeup_print_header, .print_line = wakeup_print_line, .flags = &tracer_flags, @@ -620,7 +620,7 @@ static struct tracer wakeup_rt_tracer __read_mostly = #endif .open = wakeup_trace_open, .close = wakeup_trace_close, - .use_max_tr = 1, + .use_max_tr = true, }; __init static int init_wakeup_tracer(void) -- cgit v1.2.3 From 884bfe89a462fcc85c8abd96171519cf2fe70929 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Fri, 15 Jul 2011 14:23:58 -0700 Subject: ring-buffer: Add a 'dropped events' counter The existing 'overrun' counter is incremented when the ring buffer wraps around, with overflow on (the default). We wanted a way to count requests lost from the buffer filling up with overflow off, too. I decided to add a new counter instead of retro-fitting the existing one because it seems like a different statistic to count conceptually, and also because of how the code was structured. Link: http://lkml.kernel.org/r/1310765038-26399-1-git-send-email-slavapestov@google.com Signed-off-by: Slava Pestov Signed-off-by: Steven Rostedt --- include/linux/ring_buffer.h | 1 + kernel/trace/ring_buffer.c | 41 +++++++++++++++++++++++++++++++++++------ kernel/trace/trace.c | 3 +++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 6c8835f74f7..2007375cfe7 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -166,6 +166,7 @@ unsigned long ring_buffer_overruns(struct ring_buffer *buffer); unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu); unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu); unsigned long ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu); +unsigned long ring_buffer_dropped_events_cpu(struct ring_buffer *buffer, int cpu); u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu); void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer, diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index b979426d16c..0ebeb1d76dd 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -460,9 +460,10 @@ struct ring_buffer_per_cpu { unsigned long lost_events; unsigned long last_overrun; local_t entries_bytes; - local_t commit_overrun; - local_t overrun; local_t entries; + local_t overrun; + local_t commit_overrun; + local_t dropped_events; local_t committing; local_t commits; unsigned long read; @@ -2155,8 +2156,10 @@ rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer, * If we are not in overwrite mode, * this is easy, just stop here. */ - if (!(buffer->flags & RB_FL_OVERWRITE)) + if (!(buffer->flags & RB_FL_OVERWRITE)) { + local_inc(&cpu_buffer->dropped_events); goto out_reset; + } ret = rb_handle_head_page(cpu_buffer, tail_page, @@ -2995,7 +2998,8 @@ unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu) EXPORT_SYMBOL_GPL(ring_buffer_entries_cpu); /** - * ring_buffer_overrun_cpu - get the number of overruns in a cpu_buffer + * ring_buffer_overrun_cpu - get the number of overruns caused by the ring + * buffer wrapping around (only if RB_FL_OVERWRITE is on). * @buffer: The ring buffer * @cpu: The per CPU buffer to get the number of overruns from */ @@ -3015,7 +3019,9 @@ unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu) EXPORT_SYMBOL_GPL(ring_buffer_overrun_cpu); /** - * ring_buffer_commit_overrun_cpu - get the number of overruns caused by commits + * ring_buffer_commit_overrun_cpu - get the number of overruns caused by + * commits failing due to the buffer wrapping around while there are uncommitted + * events, such as during an interrupt storm. * @buffer: The ring buffer * @cpu: The per CPU buffer to get the number of overruns from */ @@ -3035,6 +3041,28 @@ ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu) } EXPORT_SYMBOL_GPL(ring_buffer_commit_overrun_cpu); +/** + * ring_buffer_dropped_events_cpu - get the number of dropped events caused by + * the ring buffer filling up (only if RB_FL_OVERWRITE is off). + * @buffer: The ring buffer + * @cpu: The per CPU buffer to get the number of overruns from + */ +unsigned long +ring_buffer_dropped_events_cpu(struct ring_buffer *buffer, int cpu) +{ + struct ring_buffer_per_cpu *cpu_buffer; + unsigned long ret; + + if (!cpumask_test_cpu(cpu, buffer->cpumask)) + return 0; + + cpu_buffer = buffer->buffers[cpu]; + ret = local_read(&cpu_buffer->dropped_events); + + return ret; +} +EXPORT_SYMBOL_GPL(ring_buffer_dropped_events_cpu); + /** * ring_buffer_entries - get the number of entries in a buffer * @buffer: The ring buffer @@ -3864,9 +3892,10 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer) local_set(&cpu_buffer->reader_page->page->commit, 0); cpu_buffer->reader_page->read = 0; - local_set(&cpu_buffer->commit_overrun, 0); local_set(&cpu_buffer->entries_bytes, 0); local_set(&cpu_buffer->overrun, 0); + local_set(&cpu_buffer->commit_overrun, 0); + local_set(&cpu_buffer->dropped_events, 0); local_set(&cpu_buffer->entries, 0); local_set(&cpu_buffer->committing, 0); local_set(&cpu_buffer->commits, 0); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index f6928edacd6..36c213fbfce 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4385,6 +4385,9 @@ tracing_stats_read(struct file *filp, char __user *ubuf, usec_rem = do_div(t, USEC_PER_SEC); trace_seq_printf(s, "now ts: %5llu.%06lu\n", t, usec_rem); + cnt = ring_buffer_dropped_events_cpu(tr->buffer, cpu); + trace_seq_printf(s, "dropped events: %ld\n", cnt); + count = simple_read_from_buffer(ubuf, count, ppos, s->buffer, s->len); kfree(s); -- cgit v1.2.3 From b382ede6b5eb8188926b72a9ef42fd2354342a97 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 10 Oct 2012 21:44:34 -0400 Subject: tracing: Expand ring buffer when trace_printk() is used Since tracing is not used by 99% of Linux users, even though tracing may be configured in, it does not make sense to allocate 1.4 Megs per CPU for the ring buffers if they are not used. Thus, on boot up the ring buffers are set to a minimal size until something needs the and they are expanded. This works well for events and tracers (function, etc), but for the asynchronous use of trace_printk() which can write to the ring buffer at any time, does not expand the buffers. On boot up a check is made to see if any trace_printk() is used to see if the trace_printk() temp buffer pages should be allocated. This same code can be used to expand the buffers as well. Suggested-by: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 36c213fbfce..a5411b7414b 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1571,6 +1571,9 @@ void trace_printk_init_buffers(void) pr_info("ftrace: Allocated trace_printk buffers\n"); + /* Expand the buffers to set size */ + tracing_update_buffers(); + buffers_allocated = 1; } @@ -3030,6 +3033,10 @@ static int __tracing_resize_ring_buffer(unsigned long size, int cpu) */ ring_buffer_expanded = 1; + /* May be called before buffers are initialized */ + if (!global_trace.buffer) + return 0; + ret = ring_buffer_resize(global_trace.buffer, size, cpu); if (ret < 0) return ret; -- cgit v1.2.3 From 81698831bc462ff16f76bc11249a1e492424da4c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 11 Oct 2012 10:15:05 -0400 Subject: tracing: Enable comm recording if trace_printk() is used If comm recording is not enabled when trace_printk() is used then you just get this type of output: [ adding trace_printk("hello! %d", irq); in do_IRQ ] <...>-2843 [001] d.h. 80.812300: do_IRQ: hello! 14 <...>-2734 [002] d.h2 80.824664: do_IRQ: hello! 14 <...>-2713 [003] d.h. 80.829971: do_IRQ: hello! 14 <...>-2814 [000] d.h. 80.833026: do_IRQ: hello! 14 By enabling the comm recorder when trace_printk is enabled: hackbench-6715 [001] d.h. 193.233776: do_IRQ: hello! 21 sshd-2659 [001] d.h. 193.665862: do_IRQ: hello! 21 -0 [001] d.h1 193.665996: do_IRQ: hello! 21 Suggested-by: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 36 ++++++++++++++++++++++++++++++++++-- kernel/trace/trace.h | 1 + kernel/trace/trace_events.c | 3 +++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index a5411b7414b..b90a827a464 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1559,10 +1559,10 @@ static int alloc_percpu_trace_buffer(void) return -ENOMEM; } +static int buffers_allocated; + void trace_printk_init_buffers(void) { - static int buffers_allocated; - if (buffers_allocated) return; @@ -1575,6 +1575,34 @@ void trace_printk_init_buffers(void) tracing_update_buffers(); buffers_allocated = 1; + + /* + * trace_printk_init_buffers() can be called by modules. + * If that happens, then we need to start cmdline recording + * directly here. If the global_trace.buffer is already + * allocated here, then this was called by module code. + */ + if (global_trace.buffer) + tracing_start_cmdline_record(); +} + +void trace_printk_start_comm(void) +{ + /* Start tracing comms if trace printk is set */ + if (!buffers_allocated) + return; + tracing_start_cmdline_record(); +} + +static void trace_printk_start_stop_comm(int enabled) +{ + if (!buffers_allocated) + return; + + if (enabled) + tracing_start_cmdline_record(); + else + tracing_stop_cmdline_record(); } /** @@ -2797,6 +2825,9 @@ static void set_tracer_flags(unsigned int mask, int enabled) if (mask == TRACE_ITER_OVERWRITE) ring_buffer_change_overwrite(global_trace.buffer, enabled); + + if (mask == TRACE_ITER_PRINTK) + trace_printk_start_stop_comm(enabled); } static ssize_t @@ -5099,6 +5130,7 @@ __init static int tracer_alloc_buffers(void) /* Only allocate trace_printk buffers if a trace_printk exists */ if (__stop___trace_bprintk_fmt != __start___trace_bprintk_fmt) + /* Must be called before global_trace.buffer is allocated */ trace_printk_init_buffers(); /* To save memory, keep the ring buffer size to its minimum */ diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index c56a233c006..7824a55bd3f 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -841,6 +841,7 @@ extern const char *__start___trace_bprintk_fmt[]; extern const char *__stop___trace_bprintk_fmt[]; void trace_printk_init_buffers(void); +void trace_printk_start_comm(void); #undef FTRACE_ENTRY #define FTRACE_ENTRY(call, struct_name, id, tstruct, print, filter) \ diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index d608d09d08c..dec47e70e25 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -1489,6 +1489,9 @@ static __init int event_trace_enable(void) if (ret) pr_warn("Failed to enable trace event: %s\n", token); } + + trace_printk_start_comm(); + return 0; } -- cgit v1.2.3 From 2b70e59043f5a5ec083ea50cd2640aa49c64c675 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 11 Oct 2012 11:14:14 -0400 Subject: tracing: Have tracing_sched_wakeup_trace() use standard unlock_commit The functon tracing_sched_wakeup_trace() does an open coded unlock commit and save stack. This is what the trace_nowake_buffer_unlock_commit() is for. Signed-off-by: Steven Rostedt --- kernel/trace/trace_sched_switch.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index 7e62c0a1845..b0a136ac382 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -102,9 +102,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr, entry->next_cpu = task_cpu(wakee); if (!filter_check_discard(call, entry, buffer, event)) - ring_buffer_unlock_commit(buffer, event); - ftrace_trace_stack(tr->buffer, flags, 6, pc); - ftrace_trace_userstack(tr->buffer, flags, pc); + trace_nowake_buffer_unlock_commit(buffer, event, flags, pc); } static void -- cgit v1.2.3 From 7ffbd48d5cab22bcd1120eb2349db1319e2d827a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 11 Oct 2012 12:14:25 -0400 Subject: tracing: Cache comms only after an event occurred Whenever an event is registered, the comm of tasks are saved at every task switch instead of saving them at every event. But if an event isn't executed much, the comm cache will be filled up by tasks that did not record the event and you lose out on the comms that did. Here's an example, if you enable the following events: echo 1 > /debug/tracing/events/kvm/kvm_cr/enable echo 1 > /debug/tracing/events/net/net_dev_xmit/enable Note, there's no kvm running on this machine so the first event will never be triggered, but because it is enabled, the storing of comms will continue. If we now disable the network event: echo 0 > /debug/tracing/events/net/net_dev_xmit/enable and look at the trace: cat /debug/tracing/trace sshd-2672 [001] ..s2 375.731616: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0 sshd-2672 [001] ..s1 375.731617: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0 sshd-2672 [001] ..s2 375.859356: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0 sshd-2672 [001] ..s1 375.859357: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0 sshd-2672 [001] ..s2 375.947351: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0 sshd-2672 [001] ..s1 375.947352: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0 sshd-2672 [001] ..s2 376.035383: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0 sshd-2672 [001] ..s1 376.035383: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0 sshd-2672 [001] ..s2 377.563806: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=226 rc=0 sshd-2672 [001] ..s1 377.563807: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=226 rc=0 sshd-2672 [001] ..s2 377.563834: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6be0 len=114 rc=0 sshd-2672 [001] ..s1 377.563842: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6be0 len=114 rc=0 We see that process 2672 which triggered the events has the comm "sshd". But if we run hackbench for a bit and look again: cat /debug/tracing/trace <...>-2672 [001] ..s2 375.731616: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0 <...>-2672 [001] ..s1 375.731617: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0 <...>-2672 [001] ..s2 375.859356: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0 <...>-2672 [001] ..s1 375.859357: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0 <...>-2672 [001] ..s2 375.947351: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0 <...>-2672 [001] ..s1 375.947352: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0 <...>-2672 [001] ..s2 376.035383: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=242 rc=0 <...>-2672 [001] ..s1 376.035383: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=242 rc=0 <...>-2672 [001] ..s2 377.563806: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6de0 len=226 rc=0 <...>-2672 [001] ..s1 377.563807: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6de0 len=226 rc=0 <...>-2672 [001] ..s2 377.563834: net_dev_xmit: dev=eth0 skbaddr=ffff88005cbb6be0 len=114 rc=0 <...>-2672 [001] ..s1 377.563842: net_dev_xmit: dev=br0 skbaddr=ffff88005cbb6be0 len=114 rc=0 The stored "sshd" comm has been flushed out and we get a useless "<...>". But by only storing comms after a trace event occurred, we can run hackbench all day and still get the same output. Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 35 +++++++++++++++++++++++++++-------- kernel/trace/trace.h | 3 +++ kernel/trace/trace_branch.c | 2 +- kernel/trace/trace_functions_graph.c | 4 ++-- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b90a827a464..88111b08b2c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -77,6 +77,13 @@ static int dummy_set_flag(u32 old_flags, u32 bit, int set) return 0; } +/* + * To prevent the comm cache from being overwritten when no + * tracing is active, only save the comm when a trace event + * occurred. + */ +static DEFINE_PER_CPU(bool, trace_cmdline_save); + /* * Kill all tracing for good (never come back). * It is initialized to 1 but will turn to zero if the initialization @@ -1135,6 +1142,11 @@ void tracing_record_cmdline(struct task_struct *tsk) !tracing_is_on()) return; + if (!__this_cpu_read(trace_cmdline_save)) + return; + + __this_cpu_write(trace_cmdline_save, false); + trace_save_cmdline(tsk); } @@ -1178,13 +1190,20 @@ trace_buffer_lock_reserve(struct ring_buffer *buffer, return event; } +void +__buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event) +{ + __this_cpu_write(trace_cmdline_save, true); + ring_buffer_unlock_commit(buffer, event); +} + static inline void __trace_buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event, unsigned long flags, int pc, int wake) { - ring_buffer_unlock_commit(buffer, event); + __buffer_unlock_commit(buffer, event); ftrace_trace_stack(buffer, flags, 6, pc); ftrace_trace_userstack(buffer, flags, pc); @@ -1232,7 +1251,7 @@ void trace_nowake_buffer_unlock_commit_regs(struct ring_buffer *buffer, unsigned long flags, int pc, struct pt_regs *regs) { - ring_buffer_unlock_commit(buffer, event); + __buffer_unlock_commit(buffer, event); ftrace_trace_stack_regs(buffer, flags, 0, pc, regs); ftrace_trace_userstack(buffer, flags, pc); @@ -1269,7 +1288,7 @@ trace_function(struct trace_array *tr, entry->parent_ip = parent_ip; if (!filter_check_discard(call, entry, buffer, event)) - ring_buffer_unlock_commit(buffer, event); + __buffer_unlock_commit(buffer, event); } void @@ -1362,7 +1381,7 @@ static void __ftrace_trace_stack(struct ring_buffer *buffer, entry->size = trace.nr_entries; if (!filter_check_discard(call, entry, buffer, event)) - ring_buffer_unlock_commit(buffer, event); + __buffer_unlock_commit(buffer, event); out: /* Again, don't let gcc optimize things here */ @@ -1458,7 +1477,7 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc) save_stack_trace_user(&trace); if (!filter_check_discard(call, entry, buffer, event)) - ring_buffer_unlock_commit(buffer, event); + __buffer_unlock_commit(buffer, event); out_drop_count: __this_cpu_dec(user_stack_count); @@ -1653,7 +1672,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) memcpy(entry->buf, tbuffer, sizeof(u32) * len); if (!filter_check_discard(call, entry, buffer, event)) { - ring_buffer_unlock_commit(buffer, event); + __buffer_unlock_commit(buffer, event); ftrace_trace_stack(buffer, flags, 6, pc); } @@ -1724,7 +1743,7 @@ int trace_array_vprintk(struct trace_array *tr, memcpy(&entry->buf, tbuffer, len); entry->buf[len] = '\0'; if (!filter_check_discard(call, entry, buffer, event)) { - ring_buffer_unlock_commit(buffer, event); + __buffer_unlock_commit(buffer, event); ftrace_trace_stack(buffer, flags, 6, pc); } out: @@ -3993,7 +4012,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, } else entry->buf[cnt] = '\0'; - ring_buffer_unlock_commit(buffer, event); + __buffer_unlock_commit(buffer, event); written = cnt; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 7824a55bd3f..839ae003a05 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -359,6 +359,9 @@ struct trace_entry *tracing_get_trace_entry(struct trace_array *tr, struct trace_entry *trace_find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts); +void __buffer_unlock_commit(struct ring_buffer *buffer, + struct ring_buffer_event *event); + int trace_empty(struct trace_iterator *iter); void *trace_find_next_entry_inc(struct trace_iterator *iter); diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c index bd3e0eef4ea..95e96842ed2 100644 --- a/kernel/trace/trace_branch.c +++ b/kernel/trace/trace_branch.c @@ -77,7 +77,7 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect) entry->correct = val == expect; if (!filter_check_discard(call, entry, buffer, event)) - ring_buffer_unlock_commit(buffer, event); + __buffer_unlock_commit(buffer, event); out: atomic_dec(&tr->data[cpu]->disabled); diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index a84b55879bc..4edb4b74eb7 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -223,7 +223,7 @@ int __trace_graph_entry(struct trace_array *tr, entry = ring_buffer_event_data(event); entry->graph_ent = *trace; if (!filter_current_check_discard(buffer, call, entry, event)) - ring_buffer_unlock_commit(buffer, event); + __buffer_unlock_commit(buffer, event); return 1; } @@ -327,7 +327,7 @@ void __trace_graph_return(struct trace_array *tr, entry = ring_buffer_event_data(event); entry->ret = *trace; if (!filter_current_check_discard(buffer, call, entry, event)) - ring_buffer_unlock_commit(buffer, event); + __buffer_unlock_commit(buffer, event); } void trace_graph_return(struct ftrace_graph_ret *trace) -- cgit v1.2.3 From 01e3e710a9265fb7092efd67243d7b6dd6e2548a Mon Sep 17 00:00:00 2001 From: David Sharp Date: Thu, 7 Jun 2012 16:46:24 -0700 Subject: tracing: Trivial cleanup Remove ftrace_format_syscall() declaration; it is neither defined nor used. Also update a comment and formatting. Link: http://lkml.kernel.org/r/1339112785-21806-1-git-send-email-vnagarnaik@google.com Signed-off-by: David Sharp Signed-off-by: Vaibhav Nagarnaik Signed-off-by: Steven Rostedt --- include/trace/syscall.h | 2 -- kernel/trace/ring_buffer.c | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/include/trace/syscall.h b/include/trace/syscall.h index 31966a4fb8c..0c95796177d 100644 --- a/include/trace/syscall.h +++ b/include/trace/syscall.h @@ -39,8 +39,6 @@ extern int reg_event_syscall_enter(struct ftrace_event_call *call); extern void unreg_event_syscall_enter(struct ftrace_event_call *call); extern int reg_event_syscall_exit(struct ftrace_event_call *call); extern void unreg_event_syscall_exit(struct ftrace_event_call *call); -extern int -ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s); enum print_line_t print_syscall_enter(struct trace_iterator *iter, int flags, struct trace_event *event); enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags, diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 0ebeb1d76dd..23a384b9251 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1821,7 +1821,7 @@ rb_add_time_stamp(struct ring_buffer_event *event, u64 delta) } /** - * ring_buffer_update_event - update event type and data + * rb_update_event - update event type and data * @event: the even to update * @type: the type of event * @length: the size of the event field in the ring buffer @@ -2723,8 +2723,8 @@ EXPORT_SYMBOL_GPL(ring_buffer_discard_commit); * and not the length of the event which would hold the header. */ int ring_buffer_write(struct ring_buffer *buffer, - unsigned long length, - void *data) + unsigned long length, + void *data) { struct ring_buffer_per_cpu *cpu_buffer; struct ring_buffer_event *event; -- cgit v1.2.3 From 6f86ab9fcaef122abb837819139eadac1a0ca966 Mon Sep 17 00:00:00 2001 From: Vaibhav Nagarnaik Date: Thu, 7 Jun 2012 16:46:25 -0700 Subject: tracing: Cleanup unnecessary function declarations The functions defined in include/trace/syscalls.h are not used directly since struct ftrace_event_class was introduced. Remove them from the header file and rearrange the ftrace_event_class declarations in trace_syscalls.c. Link: http://lkml.kernel.org/r/1339112785-21806-2-git-send-email-vnagarnaik@google.com Signed-off-by: Vaibhav Nagarnaik Signed-off-by: Steven Rostedt --- include/trace/syscall.h | 21 --------------- kernel/trace/trace_syscalls.c | 61 ++++++++++++++++++++----------------------- 2 files changed, 29 insertions(+), 53 deletions(-) diff --git a/include/trace/syscall.h b/include/trace/syscall.h index 0c95796177d..84bc4197e73 100644 --- a/include/trace/syscall.h +++ b/include/trace/syscall.h @@ -31,25 +31,4 @@ struct syscall_metadata { struct ftrace_event_call *exit_event; }; -#ifdef CONFIG_FTRACE_SYSCALLS -extern unsigned long arch_syscall_addr(int nr); -extern int init_syscall_trace(struct ftrace_event_call *call); - -extern int reg_event_syscall_enter(struct ftrace_event_call *call); -extern void unreg_event_syscall_enter(struct ftrace_event_call *call); -extern int reg_event_syscall_exit(struct ftrace_event_call *call); -extern void unreg_event_syscall_exit(struct ftrace_event_call *call); -enum print_line_t print_syscall_enter(struct trace_iterator *iter, int flags, - struct trace_event *event); -enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags, - struct trace_event *event); -#endif - -#ifdef CONFIG_PERF_EVENTS -int perf_sysenter_enable(struct ftrace_event_call *call); -void perf_sysenter_disable(struct ftrace_event_call *call); -int perf_sysexit_enable(struct ftrace_event_call *call); -void perf_sysexit_disable(struct ftrace_event_call *call); -#endif - #endif /* _TRACE_SYSCALL_H */ diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 2485a7d09b1..7609dd6714c 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -21,9 +21,6 @@ static int syscall_enter_register(struct ftrace_event_call *event, static int syscall_exit_register(struct ftrace_event_call *event, enum trace_reg type, void *data); -static int syscall_enter_define_fields(struct ftrace_event_call *call); -static int syscall_exit_define_fields(struct ftrace_event_call *call); - static struct list_head * syscall_get_enter_fields(struct ftrace_event_call *call) { @@ -32,30 +29,6 @@ syscall_get_enter_fields(struct ftrace_event_call *call) return &entry->enter_fields; } -struct trace_event_functions enter_syscall_print_funcs = { - .trace = print_syscall_enter, -}; - -struct trace_event_functions exit_syscall_print_funcs = { - .trace = print_syscall_exit, -}; - -struct ftrace_event_class event_class_syscall_enter = { - .system = "syscalls", - .reg = syscall_enter_register, - .define_fields = syscall_enter_define_fields, - .get_fields = syscall_get_enter_fields, - .raw_init = init_syscall_trace, -}; - -struct ftrace_event_class event_class_syscall_exit = { - .system = "syscalls", - .reg = syscall_exit_register, - .define_fields = syscall_exit_define_fields, - .fields = LIST_HEAD_INIT(event_class_syscall_exit.fields), - .raw_init = init_syscall_trace, -}; - extern struct syscall_metadata *__start_syscalls_metadata[]; extern struct syscall_metadata *__stop_syscalls_metadata[]; @@ -432,7 +405,7 @@ void unreg_event_syscall_exit(struct ftrace_event_call *call) mutex_unlock(&syscall_trace_lock); } -int init_syscall_trace(struct ftrace_event_call *call) +static int init_syscall_trace(struct ftrace_event_call *call) { int id; int num; @@ -457,6 +430,30 @@ int init_syscall_trace(struct ftrace_event_call *call) return id; } +struct trace_event_functions enter_syscall_print_funcs = { + .trace = print_syscall_enter, +}; + +struct trace_event_functions exit_syscall_print_funcs = { + .trace = print_syscall_exit, +}; + +struct ftrace_event_class event_class_syscall_enter = { + .system = "syscalls", + .reg = syscall_enter_register, + .define_fields = syscall_enter_define_fields, + .get_fields = syscall_get_enter_fields, + .raw_init = init_syscall_trace, +}; + +struct ftrace_event_class event_class_syscall_exit = { + .system = "syscalls", + .reg = syscall_exit_register, + .define_fields = syscall_exit_define_fields, + .fields = LIST_HEAD_INIT(event_class_syscall_exit.fields), + .raw_init = init_syscall_trace, +}; + unsigned long __init __weak arch_syscall_addr(int nr) { return (unsigned long)sys_call_table[nr]; @@ -537,7 +534,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL); } -int perf_sysenter_enable(struct ftrace_event_call *call) +static int perf_sysenter_enable(struct ftrace_event_call *call) { int ret = 0; int num; @@ -558,7 +555,7 @@ int perf_sysenter_enable(struct ftrace_event_call *call) return ret; } -void perf_sysenter_disable(struct ftrace_event_call *call) +static void perf_sysenter_disable(struct ftrace_event_call *call) { int num; @@ -615,7 +612,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL); } -int perf_sysexit_enable(struct ftrace_event_call *call) +static int perf_sysexit_enable(struct ftrace_event_call *call) { int ret = 0; int num; @@ -636,7 +633,7 @@ int perf_sysexit_enable(struct ftrace_event_call *call) return ret; } -void perf_sysexit_disable(struct ftrace_event_call *call) +static void perf_sysexit_disable(struct ftrace_event_call *call) { int num; -- cgit v1.2.3 From 60efc15ae96c7aace8060411b0d5add20e1ab21e Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Thu, 25 Oct 2012 15:41:51 +0200 Subject: linux/kernel.h: Remove duplicate trace_printk declaration !CONFIG_TRACING both declares and defines (empty) trace_printk. The first one is not redundant so it can be removed. Link: http://lkml.kernel.org/r/1351172511-18125-1-git-send-email-mhocko@suse.cz Signed-off-by: Michal Hocko Signed-off-by: Steven Rostedt --- include/linux/kernel.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index a123b13b70f..7785d5df6d8 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -527,9 +527,6 @@ __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap); extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode); #else -static inline __printf(1, 2) -int trace_printk(const char *fmt, ...); - static inline void tracing_start(void) { } static inline void tracing_stop(void) { } static inline void ftrace_off_permanent(void) { } @@ -539,8 +536,8 @@ static inline void tracing_on(void) { } static inline void tracing_off(void) { } static inline int tracing_is_on(void) { return 0; } -static inline int -trace_printk(const char *fmt, ...) +static inline __printf(1, 2) +int trace_printk(const char *fmt, ...) { return 0; } -- cgit v1.2.3 From 37b51fdddf64e7ba0971d070428655f8d6f36578 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Tue, 30 Oct 2012 22:40:23 +0300 Subject: staging: zram: factor-out zram_decompress_page() function zram_bvec_read() shared decompress functionality with zram_read_before_write() function. Factor-out and make commonly used zram_decompress_page() function, which also simplified error handling in zram_bvec_read(). Signed-off-by: Sergey Senozhatsky Reviewed-by: Nitin Gupta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_drv.c | 113 +++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 65 deletions(-) diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 6edefde2372..fb4a7c94aed 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -183,62 +183,25 @@ static inline int is_partial_io(struct bio_vec *bvec) return bvec->bv_len != PAGE_SIZE; } -static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, - u32 index, int offset, struct bio *bio) +static int zram_decompress_page(struct zram *zram, char *mem, u32 index) { - int ret; - size_t clen; - struct page *page; - unsigned char *user_mem, *cmem, *uncmem = NULL; - - page = bvec->bv_page; - - if (zram_test_flag(zram, index, ZRAM_ZERO)) { - handle_zero_page(bvec); - return 0; - } + int ret = LZO_E_OK; + size_t clen = PAGE_SIZE; + unsigned char *cmem; + unsigned long handle = zram->table[index].handle; - /* Requested page is not present in compressed area */ - if (unlikely(!zram->table[index].handle)) { - pr_debug("Read before write: sector=%lu, size=%u", - (ulong)(bio->bi_sector), bio->bi_size); - handle_zero_page(bvec); + if (!handle || zram_test_flag(zram, index, ZRAM_ZERO)) { + memset(mem, 0, PAGE_SIZE); return 0; } - if (is_partial_io(bvec)) { - /* Use a temporary buffer to decompress the page */ - uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!uncmem) { - pr_info("Error allocating temp memory!\n"); - return -ENOMEM; - } - } - - user_mem = kmap_atomic(page); - if (!is_partial_io(bvec)) - uncmem = user_mem; - clen = PAGE_SIZE; - - cmem = zs_map_object(zram->mem_pool, zram->table[index].handle, - ZS_MM_RO); - - if (zram->table[index].size == PAGE_SIZE) { - memcpy(uncmem, cmem, PAGE_SIZE); - ret = LZO_E_OK; - } else { + cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_RO); + if (zram->table[index].size == PAGE_SIZE) + memcpy(mem, cmem, PAGE_SIZE); + else ret = lzo1x_decompress_safe(cmem, zram->table[index].size, - uncmem, &clen); - } - - if (is_partial_io(bvec)) { - memcpy(user_mem + bvec->bv_offset, uncmem + offset, - bvec->bv_len); - kfree(uncmem); - } - - zs_unmap_object(zram->mem_pool, zram->table[index].handle); - kunmap_atomic(user_mem); + mem, &clen); + zs_unmap_object(zram->mem_pool, handle); /* Should NEVER happen. Return bio error if it does. */ if (unlikely(ret != LZO_E_OK)) { @@ -247,36 +210,56 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, return ret; } - flush_dcache_page(page); - return 0; } -static int zram_read_before_write(struct zram *zram, char *mem, u32 index) +static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, + u32 index, int offset, struct bio *bio) { int ret; - size_t clen = PAGE_SIZE; - unsigned char *cmem; - unsigned long handle = zram->table[index].handle; + struct page *page; + unsigned char *user_mem, *uncmem = NULL; - if (zram_test_flag(zram, index, ZRAM_ZERO) || !handle) { - memset(mem, 0, PAGE_SIZE); + page = bvec->bv_page; + + if (unlikely(!zram->table[index].handle) || + zram_test_flag(zram, index, ZRAM_ZERO)) { + handle_zero_page(bvec); return 0; } - cmem = zs_map_object(zram->mem_pool, handle, ZS_MM_RO); - ret = lzo1x_decompress_safe(cmem, zram->table[index].size, - mem, &clen); - zs_unmap_object(zram->mem_pool, handle); + user_mem = kmap_atomic(page); + if (is_partial_io(bvec)) + /* Use a temporary buffer to decompress the page */ + uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL); + else + uncmem = user_mem; + if (!uncmem) { + pr_info("Unable to allocate temp memory\n"); + ret = -ENOMEM; + goto out_cleanup; + } + + ret = zram_decompress_page(zram, uncmem, index); /* Should NEVER happen. Return bio error if it does. */ if (unlikely(ret != LZO_E_OK)) { pr_err("Decompression failed! err=%d, page=%u\n", ret, index); zram_stat64_inc(zram, &zram->stats.failed_reads); - return ret; + goto out_cleanup; } - return 0; + if (is_partial_io(bvec)) + memcpy(user_mem + bvec->bv_offset, uncmem + offset, + bvec->bv_len); + + flush_dcache_page(page); + ret = 0; +out_cleanup: + kunmap_atomic(user_mem); + if (is_partial_io(bvec)) + kfree(uncmem); + return ret; } static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, @@ -302,7 +285,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, ret = -ENOMEM; goto out; } - ret = zram_read_before_write(zram, uncmem, index); + ret = zram_decompress_page(zram, uncmem, index); if (ret) { kfree(uncmem); goto out; -- cgit v1.2.3 From 26907840e63b3187266db1865e76ea9e98b01b19 Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Tue, 30 Oct 2012 22:42:31 +0300 Subject: staging: zram: handle mem suffixes in disk size zram_sysfs parameter Use memparse() to allow mem suffixes in disksize sysfs number. Examples: echo 256K > /sys/block/zram0/disksize echo 512M > /sys/block/zram0/disksize echo 1G > /sys/block/zram0/disksize Signed-off-by: Sergey Senozhatsky Reviewed-by: Nitin Gupta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/zram_sysfs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c index edb0ed4125d..de1eacf65db 100644 --- a/drivers/staging/zram/zram_sysfs.c +++ b/drivers/staging/zram/zram_sysfs.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "zram_drv.h" @@ -54,13 +55,12 @@ static ssize_t disksize_show(struct device *dev, static ssize_t disksize_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - int ret; u64 disksize; struct zram *zram = dev_to_zram(dev); - ret = kstrtoull(buf, 10, &disksize); - if (ret) - return ret; + disksize = memparse(buf, NULL); + if (!disksize) + return -EINVAL; down_write(&zram->init_lock); if (zram->init_done) { -- cgit v1.2.3 From 01e14a4c586ffc6e1c7b748eb8354806ccfec813 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Tue, 30 Oct 2012 21:23:29 +0000 Subject: staging: et131x: Add ethtool printout to match MII regs In the ethtool call et131x_get_regs(), some MII regs are missing. Add them to the regs returned. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index daa5247bd01..1534582eedc 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -3587,7 +3587,12 @@ static void et131x_get_regs(struct net_device *netdev, et131x_mii_read(adapter, 0x08, (u16 *)®s_buff[num++]); et131x_mii_read(adapter, MII_CTRL1000, (u16 *)®s_buff[num++]); et131x_mii_read(adapter, MII_STAT1000, (u16 *)®s_buff[num++]); + et131x_mii_read(adapter, 0x0b, (u16 *)®s_buff[num++]); + et131x_mii_read(adapter, 0x0c, (u16 *)®s_buff[num++]); + et131x_mii_read(adapter, MII_MMD_CTRL, (u16 *)®s_buff[num++]); + et131x_mii_read(adapter, MII_MMD_DATA, (u16 *)®s_buff[num++]); et131x_mii_read(adapter, MII_ESTATUS, (u16 *)®s_buff[num++]); + et131x_mii_read(adapter, PHY_INDEX_REG, (u16 *)®s_buff[num++]); et131x_mii_read(adapter, PHY_DATA_REG, (u16 *)®s_buff[num++]); et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, @@ -3596,6 +3601,7 @@ static void et131x_get_regs(struct net_device *netdev, (u16 *)®s_buff[num++]); et131x_mii_read(adapter, PHY_LOOPBACK_CONTROL+1, (u16 *)®s_buff[num++]); + et131x_mii_read(adapter, PHY_REGISTER_MGMT_CONTROL, (u16 *)®s_buff[num++]); et131x_mii_read(adapter, PHY_CONFIG, (u16 *)®s_buff[num++]); -- cgit v1.2.3 From 5df395404b43cfd111c36822b2e691619a408024 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 31 Oct 2012 11:56:23 +0000 Subject: staging: comedi: rtd520: use auto_attach instead of attach_pci Change the rtd520 driver to use the new `auto_attach()` method in `struct comedi_driver` instead of the `attach_pci()` method. I plan to remove the `attach_pci()` and `attach_usb()` methods once nothing is using them. Tag the new `rtd520_auto_attach()` function definition with `__devinit` as it is only called during PCI probe. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index e42bd6b1153..23b76d0b1a5 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1284,8 +1284,10 @@ static const void *rtd_find_boardinfo(struct comedi_device *dev, return NULL; } -static int rtd_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) +static int __devinit rtd_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct rtdBoard *thisboard; struct rtdPrivate *devpriv; struct comedi_subdevice *s; @@ -1420,7 +1422,7 @@ static void rtd_detach(struct comedi_device *dev) static struct comedi_driver rtd520_driver = { .driver_name = "rtd520", .module = THIS_MODULE, - .attach_pci = rtd_attach_pci, + .auto_attach = rtd_auto_attach, .detach = rtd_detach, }; -- cgit v1.2.3 From 984a4a0378f609fc943e77d1beda900e8a6abaaf Mon Sep 17 00:00:00 2001 From: Xiaotian Feng Date: Wed, 31 Oct 2012 18:56:48 +0800 Subject: staging: ozwpan: use tasklet_kill in device remove/release process Some driver uses tasklet_disable in device remove/release process, tasklet_disable will inc tasklet->count and return. If the tasklet is not handled yet under some softirq pressure, the tasklet will be placed on the tasklet_vec, never have a chance to be excuted. This might lead to a heavy loaded ksoftirqd, wakeup with pending_softirq, but tasklet is disabled. tasklet_kill should be used in this case. Signed-off-by: Xiaotian Feng Cc: Rupesh Gujare Cc: Chris Kelly Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozhcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 2e087acf157..33c0009b308 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -2304,8 +2304,8 @@ error: */ void oz_hcd_term(void) { - tasklet_disable(&g_urb_process_tasklet); - tasklet_disable(&g_urb_cancel_tasklet); + tasklet_kill(&g_urb_process_tasklet); + tasklet_kill(&g_urb_cancel_tasklet); platform_device_unregister(g_plat_dev); platform_driver_unregister(&g_oz_plat_drv); oz_trace("Pending urbs:%d\n", atomic_read(&g_pending_urbs)); -- cgit v1.2.3 From 4d0c8ee85994c862db7e5121de92cdb6cee5fa63 Mon Sep 17 00:00:00 2001 From: Edgar Neukirchner Date: Wed, 31 Oct 2012 15:48:58 +0100 Subject: Staging: rtl8192e: rtllib_tx.c: fixed an asterisk coding style issue Fixed coding style issue Signed-off-by: Edgar Neukirchner Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtllib_tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 42900ee4825..759d7c7d78e 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -287,7 +287,7 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, { struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; struct tx_ts_record *pTxTs = NULL; - struct rtllib_hdr_1addr* hdr = (struct rtllib_hdr_1addr *)skb->data; + struct rtllib_hdr_1addr *hdr = (struct rtllib_hdr_1addr *)skb->data; if (rtllib_act_scanning(ieee, false)) return; -- cgit v1.2.3 From 9b2b9a348ec4012c6807c6648f76da03c120bd7a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:55:22 -0700 Subject: staging: comedi: hwrdv_apci035: absorb private header The header file hwdrv_apci035.h is only included by the source file hwrdv_apci035.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci035.c | 74 +++++++++++++++++-- .../comedi/drivers/addi-data/hwdrv_apci035.h | 83 ---------------------- 2 files changed, 68 insertions(+), 89 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c index 6d81575c78d..799bc0417ba 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c @@ -46,12 +46,74 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci035.h" +/* Card Specific information */ +#define APCI035_ADDRESS_RANGE 255 + +/* Timer / Watchdog Related Defines */ +#define APCI035_TCW_SYNC_ENABLEDISABLE 0 +#define APCI035_TCW_RELOAD_VALUE 4 +#define APCI035_TCW_TIMEBASE 8 +#define APCI035_TCW_PROG 12 +#define APCI035_TCW_TRIG_STATUS 16 +#define APCI035_TCW_IRQ 20 +#define APCI035_TCW_WARN_TIMEVAL 24 +#define APCI035_TCW_WARN_TIMEBASE 28 + +#define ADDIDATA_TIMER 0 +/* #define ADDIDATA_WATCHDOG 1 */ + +#define APCI035_TW1 0 +#define APCI035_TW2 32 +#define APCI035_TW3 64 +#define APCI035_TW4 96 + +#define APCI035_AI_OFFSET 0 +#define APCI035_TEMP 128 +#define APCI035_ALR_SEQ 4 +#define APCI035_START_STOP_INDEX 8 +#define APCI035_ALR_START_STOP 12 +#define APCI035_ALR_IRQ 16 +#define APCI035_EOS 20 +#define APCI035_CHAN_NO 24 +#define APCI035_CHAN_VAL 28 +#define APCI035_CONV_TIME_TIME_BASE 36 +#define APCI035_RELOAD_CONV_TIME_VAL 32 +#define APCI035_DELAY_TIME_TIME_BASE 44 +#define APCI035_RELOAD_DELAY_TIME_VAL 40 +#define ENABLE_EXT_TRIG 1 +#define ENABLE_EXT_GATE 2 +#define ENABLE_EXT_TRIG_GATE 3 + +#define ANALOG_INPUT 0 +#define TEMPERATURE 1 +#define RESISTANCE 2 + +#define ADDIDATA_GREATER_THAN_TEST 0 +#define ADDIDATA_LESS_THAN_TEST 1 + +#define APCI035_MAXVOLT 2.5 + +#define ADDIDATA_UNIPOLAR 1 +#define ADDIDATA_BIPOLAR 2 + +/* ADDIDATA Enable Disable */ +#define ADDIDATA_ENABLE 1 +#define ADDIDATA_DISABLE 0 + +/* ANALOG INPUT RANGE */ +static struct comedi_lrange range_apci035_ai = { + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1) + } +}; + static int i_WatchdogNbr = 0; static int i_Temp = 0; static int i_Flag = 1; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h deleted file mode 100644 index 5b5c4a3343e..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ - -/* Card Specific information */ -#define APCI035_ADDRESS_RANGE 255 - -/* ANALOG INPUT RANGE */ -static struct comedi_lrange range_apci035_ai = { 8, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - -/* Timer / Watchdog Related Defines */ -#define APCI035_TCW_SYNC_ENABLEDISABLE 0 -#define APCI035_TCW_RELOAD_VALUE 4 -#define APCI035_TCW_TIMEBASE 8 -#define APCI035_TCW_PROG 12 -#define APCI035_TCW_TRIG_STATUS 16 -#define APCI035_TCW_IRQ 20 -#define APCI035_TCW_WARN_TIMEVAL 24 -#define APCI035_TCW_WARN_TIMEBASE 28 - -#define ADDIDATA_TIMER 0 -/* #define ADDIDATA_WATCHDOG 1 */ - -#define APCI035_TW1 0 -#define APCI035_TW2 32 -#define APCI035_TW3 64 -#define APCI035_TW4 96 - -#define APCI035_AI_OFFSET 0 -#define APCI035_TEMP 128 -#define APCI035_ALR_SEQ 4 -#define APCI035_START_STOP_INDEX 8 -#define APCI035_ALR_START_STOP 12 -#define APCI035_ALR_IRQ 16 -#define APCI035_EOS 20 -#define APCI035_CHAN_NO 24 -#define APCI035_CHAN_VAL 28 -#define APCI035_CONV_TIME_TIME_BASE 36 -#define APCI035_RELOAD_CONV_TIME_VAL 32 -#define APCI035_DELAY_TIME_TIME_BASE 44 -#define APCI035_RELOAD_DELAY_TIME_VAL 40 -#define ENABLE_EXT_TRIG 1 -#define ENABLE_EXT_GATE 2 -#define ENABLE_EXT_TRIG_GATE 3 - -#define ANALOG_INPUT 0 -#define TEMPERATURE 1 -#define RESISTANCE 2 - -#define ADDIDATA_GREATER_THAN_TEST 0 -#define ADDIDATA_LESS_THAN_TEST 1 - -#define APCI035_MAXVOLT 2.5 - -#define ADDIDATA_UNIPOLAR 1 -#define ADDIDATA_BIPOLAR 2 - -/* ADDIDATA Enable Disable */ -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 -- cgit v1.2.3 From 618a97e8a2fe6a36259d90560f0ea5f7976a505f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:55:45 -0700 Subject: staging: comedi: hwrdv_apci1032: absorb private header The header file hwdrv_apci1032.h is only included by the source file hwrdv_apci1032.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1032.c | 31 ++++++++++++---- .../comedi/drivers/addi-data/hwdrv_apci1032.h | 42 ---------------------- 2 files changed, 24 insertions(+), 49 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index e4e85f472f0..7b19b09a572 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -46,13 +46,30 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci1032.h" -#include +/********* Definitions for APCI-1032 card *****/ + +#define APCI1032_ADDRESS_RANGE 20 +/* DIGITAL INPUT DEFINE */ + +#define APCI1032_DIGITAL_IP 0 +#define APCI1032_DIGITAL_IP_INTERRUPT_MODE1 4 +#define APCI1032_DIGITAL_IP_INTERRUPT_MODE2 8 +#define APCI1032_DIGITAL_IP_IRQ 16 + +/* Digital Input IRQ Function Selection */ +#define ADDIDATA_OR 0 +#define ADDIDATA_AND 1 + +/* Digital Input Interrupt Status */ +#define APCI1032_DIGITAL_IP_INTERRUPT_STATUS 12 + +/* Digital Input Interrupt Enable Disable. */ +#define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE 0x4 +#define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE 0xfffffffb + +/* ADDIDATA Enable Disable */ +#define ADDIDATA_ENABLE 1 +#define ADDIDATA_DISABLE 0 static unsigned int ui_InterruptStatus; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h deleted file mode 100644 index f0b32e8a81b..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ - -/********* Definitions for APCI-1032 card *****/ - -#define APCI1032_ADDRESS_RANGE 20 -/* DIGITAL INPUT DEFINE */ - -#define APCI1032_DIGITAL_IP 0 -#define APCI1032_DIGITAL_IP_INTERRUPT_MODE1 4 -#define APCI1032_DIGITAL_IP_INTERRUPT_MODE2 8 -#define APCI1032_DIGITAL_IP_IRQ 16 - -/* Digital Input IRQ Function Selection */ -#define ADDIDATA_OR 0 -#define ADDIDATA_AND 1 - -/* Digital Input Interrupt Status */ -#define APCI1032_DIGITAL_IP_INTERRUPT_STATUS 12 - -/* Digital Input Interrupt Enable Disable. */ -#define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE 0x4 -#define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB - -/* ADDIDATA Enable Disable */ - -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 -- cgit v1.2.3 From 89c6d640205f8acd2c0bc0ab27629de6779a7300 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:56:02 -0700 Subject: staging: comedi: hwrdv_apci1500: absorb private header The header file hwdrv_apci1500.h is only included by the source file hwrdv_apci1500.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1500.c | 100 +++++++++++++++++- .../comedi/drivers/addi-data/hwdrv_apci1500.h | 115 --------------------- 2 files changed, 99 insertions(+), 116 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c index cc47821a745..771a3054f92 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c @@ -45,7 +45,105 @@ You should also find the complete GPL in the COPYING file accompanying this sour | | | | +----------+-----------+------------------------------------------------+ */ -#include "hwdrv_apci1500.h" + +/********* Definitions for APCI-1500 card *****/ + +/* Card Specific information */ +#define APCI1500_ADDRESS_RANGE 4 + +/* DIGITAL INPUT-OUTPUT DEFINE */ + +#define APCI1500_DIGITAL_OP 2 +#define APCI1500_DIGITAL_IP 0 +#define APCI1500_AND 2 +#define APCI1500_OR 4 +#define APCI1500_OR_PRIORITY 6 +#define APCI1500_CLK_SELECT 0 +#define COUNTER1 0 +#define COUNTER2 1 +#define COUNTER3 2 +#define APCI1500_COUNTER 0x20 +#define APCI1500_TIMER 0 +#define APCI1500_WATCHDOG 0 +#define APCI1500_SINGLE 0 +#define APCI1500_CONTINUOUS 0x80 +#define APCI1500_DISABLE 0 +#define APCI1500_ENABLE 1 +#define APCI1500_SOFTWARE_TRIGGER 0x4 +#define APCI1500_HARDWARE_TRIGGER 0x10 +#define APCI1500_SOFTWARE_GATE 0 +#define APCI1500_HARDWARE_GATE 0x8 +#define START 0 +#define STOP 1 +#define TRIGGER 2 + +/* + * Zillog I/O enumeration + */ +enum { + APCI1500_Z8536_PORT_C, + APCI1500_Z8536_PORT_B, + APCI1500_Z8536_PORT_A, + APCI1500_Z8536_CONTROL_REGISTER +}; + +/* + * Z8536 CIO Internal Address + */ +enum { + APCI1500_RW_MASTER_INTERRUPT_CONTROL, + APCI1500_RW_MASTER_CONFIGURATION_CONTROL, + APCI1500_RW_PORT_A_INTERRUPT_CONTROL, + APCI1500_RW_PORT_B_INTERRUPT_CONTROL, + APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR, + APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY, + APCI1500_RW_PORT_C_DATA_DIRECTION, + APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL, + + APCI1500_RW_PORT_A_COMMAND_AND_STATUS, + APCI1500_RW_PORT_B_COMMAND_AND_STATUS, + APCI1500_RW_CPT_TMR1_CMD_STATUS, + APCI1500_RW_CPT_TMR2_CMD_STATUS, + APCI1500_RW_CPT_TMR3_CMD_STATUS, + APCI1500_RW_PORT_A_DATA, + APCI1500_RW_PORT_B_DATA, + APCI1500_RW_PORT_C_DATA, + + APCI1500_R_CPT_TMR1_VALUE_HIGH, + APCI1500_R_CPT_TMR1_VALUE_LOW, + APCI1500_R_CPT_TMR2_VALUE_HIGH, + APCI1500_R_CPT_TMR2_VALUE_LOW, + APCI1500_R_CPT_TMR3_VALUE_HIGH, + APCI1500_R_CPT_TMR3_VALUE_LOW, + APCI1500_RW_CPT_TMR1_TIME_CST_HIGH, + APCI1500_RW_CPT_TMR1_TIME_CST_LOW, + APCI1500_RW_CPT_TMR2_TIME_CST_HIGH, + APCI1500_RW_CPT_TMR2_TIME_CST_LOW, + APCI1500_RW_CPT_TMR3_TIME_CST_HIGH, + APCI1500_RW_CPT_TMR3_TIME_CST_LOW, + APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION, + APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION, + APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION, + APCI1500_R_CURRENT_VECTOR, + + APCI1500_RW_PORT_A_SPECIFICATION, + APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION, + APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY, + APCI1500_RW_PORT_A_DATA_DIRECTION, + APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL, + APCI1500_RW_PORT_A_PATTERN_POLARITY, + APCI1500_RW_PORT_A_PATTERN_TRANSITION, + APCI1500_RW_PORT_A_PATTERN_MASK, + + APCI1500_RW_PORT_B_SPECIFICATION, + APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION, + APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY, + APCI1500_RW_PORT_B_DATA_DIRECTION, + APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL, + APCI1500_RW_PORT_B_PATTERN_POLARITY, + APCI1500_RW_PORT_B_PATTERN_TRANSITION, + APCI1500_RW_PORT_B_PATTERN_MASK +}; static int i_TimerCounter1Init = 0; static int i_TimerCounter2Init = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h deleted file mode 100644 index 989e880a0ed..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ - -/********* Definitions for APCI-1500 card *****/ - -/* Card Specific information */ -#define APCI1500_ADDRESS_RANGE 4 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI1500_DIGITAL_OP 2 -#define APCI1500_DIGITAL_IP 0 -#define APCI1500_AND 2 -#define APCI1500_OR 4 -#define APCI1500_OR_PRIORITY 6 -#define APCI1500_CLK_SELECT 0 -#define COUNTER1 0 -#define COUNTER2 1 -#define COUNTER3 2 -#define APCI1500_COUNTER 0x20 -#define APCI1500_TIMER 0 -#define APCI1500_WATCHDOG 0 -#define APCI1500_SINGLE 0 -#define APCI1500_CONTINUOUS 0x80 -#define APCI1500_DISABLE 0 -#define APCI1500_ENABLE 1 -#define APCI1500_SOFTWARE_TRIGGER 0x4 -#define APCI1500_HARDWARE_TRIGGER 0x10 -#define APCI1500_SOFTWARE_GATE 0 -#define APCI1500_HARDWARE_GATE 0x8 -#define START 0 -#define STOP 1 -#define TRIGGER 2 - -/* - * Zillog I/O enumeration - */ -enum { - APCI1500_Z8536_PORT_C, - APCI1500_Z8536_PORT_B, - APCI1500_Z8536_PORT_A, - APCI1500_Z8536_CONTROL_REGISTER -}; - -/* - * Z8536 CIO Internal Address - */ -enum { - APCI1500_RW_MASTER_INTERRUPT_CONTROL, - APCI1500_RW_MASTER_CONFIGURATION_CONTROL, - APCI1500_RW_PORT_A_INTERRUPT_CONTROL, - APCI1500_RW_PORT_B_INTERRUPT_CONTROL, - APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR, - APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY, - APCI1500_RW_PORT_C_DATA_DIRECTION, - APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL, - - APCI1500_RW_PORT_A_COMMAND_AND_STATUS, - APCI1500_RW_PORT_B_COMMAND_AND_STATUS, - APCI1500_RW_CPT_TMR1_CMD_STATUS, - APCI1500_RW_CPT_TMR2_CMD_STATUS, - APCI1500_RW_CPT_TMR3_CMD_STATUS, - APCI1500_RW_PORT_A_DATA, - APCI1500_RW_PORT_B_DATA, - APCI1500_RW_PORT_C_DATA, - - APCI1500_R_CPT_TMR1_VALUE_HIGH, - APCI1500_R_CPT_TMR1_VALUE_LOW, - APCI1500_R_CPT_TMR2_VALUE_HIGH, - APCI1500_R_CPT_TMR2_VALUE_LOW, - APCI1500_R_CPT_TMR3_VALUE_HIGH, - APCI1500_R_CPT_TMR3_VALUE_LOW, - APCI1500_RW_CPT_TMR1_TIME_CST_HIGH, - APCI1500_RW_CPT_TMR1_TIME_CST_LOW, - APCI1500_RW_CPT_TMR2_TIME_CST_HIGH, - APCI1500_RW_CPT_TMR2_TIME_CST_LOW, - APCI1500_RW_CPT_TMR3_TIME_CST_HIGH, - APCI1500_RW_CPT_TMR3_TIME_CST_LOW, - APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION, - APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION, - APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION, - APCI1500_R_CURRENT_VECTOR, - - APCI1500_RW_PORT_A_SPECIFICATION, - APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION, - APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY, - APCI1500_RW_PORT_A_DATA_DIRECTION, - APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL, - APCI1500_RW_PORT_A_PATTERN_POLARITY, - APCI1500_RW_PORT_A_PATTERN_TRANSITION, - APCI1500_RW_PORT_A_PATTERN_MASK, - - APCI1500_RW_PORT_B_SPECIFICATION, - APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION, - APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY, - APCI1500_RW_PORT_B_DATA_DIRECTION, - APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL, - APCI1500_RW_PORT_B_PATTERN_POLARITY, - APCI1500_RW_PORT_B_PATTERN_TRANSITION, - APCI1500_RW_PORT_B_PATTERN_MASK -}; -- cgit v1.2.3 From 89bfdc0f5c6099d058da20919220fdd5936a24b4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:56:19 -0700 Subject: staging: comedi: hwrdv_apci1516: absorb private header The header file hwdrv_apci1516.h is only included by the source file hwrdv_apci1516.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1516.c | 24 +++++++++++---- .../comedi/drivers/addi-data/hwdrv_apci1516.h | 35 ---------------------- 2 files changed, 18 insertions(+), 41 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index a3045f85513..7504c520600 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -46,12 +46,24 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci1516.h" +/********* Definitions for APCI-1516 card *****/ + +/* Card Specific information */ +#define APCI1516_ADDRESS_RANGE 8 + +/* DIGITAL INPUT-OUTPUT DEFINE */ + +#define APCI1516_DIGITAL_OP 4 +#define APCI1516_DIGITAL_OP_RW 4 +#define APCI1516_DIGITAL_IP 0 + +/* TIMER COUNTER WATCHDOG DEFINES */ + +#define ADDIDATA_WATCHDOG 2 +#define APCI1516_DIGITAL_OP_WATCHDOG 0 +#define APCI1516_WATCHDOG_ENABLEDISABLE 12 +#define APCI1516_WATCHDOG_RELOAD_VALUE 4 +#define APCI1516_WATCHDOG_STATUS 16 /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h deleted file mode 100644 index aaf564fe5e6..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ - -/********* Definitions for APCI-1516 card *****/ - -/* Card Specific information */ -#define APCI1516_ADDRESS_RANGE 8 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI1516_DIGITAL_OP 4 -#define APCI1516_DIGITAL_OP_RW 4 -#define APCI1516_DIGITAL_IP 0 - -/* TIMER COUNTER WATCHDOG DEFINES */ - -#define ADDIDATA_WATCHDOG 2 -#define APCI1516_DIGITAL_OP_WATCHDOG 0 -#define APCI1516_WATCHDOG_ENABLEDISABLE 12 -#define APCI1516_WATCHDOG_RELOAD_VALUE 4 -#define APCI1516_WATCHDOG_STATUS 16 -- cgit v1.2.3 From 441617a3a0483d561c91b929cc7e8fb7e47fdf12 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:56:38 -0700 Subject: staging: comedi: hwrdv_apci1564: absorb private header The header file hwdrv_apci1564.h is only included by the source file hwrdv_apci1564.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1564.c | 69 ++++++++++++++++--- .../comedi/drivers/addi-data/hwdrv_apci1564.h | 78 ---------------------- 2 files changed, 61 insertions(+), 86 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 5fbd03db3ba..ef5e778748b 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -46,14 +46,67 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ - -#include -#include "hwdrv_apci1564.h" +/********* Definitions for APCI-1564 card *****/ + +#define APCI1564_ADDRESS_RANGE 128 + +/* DIGITAL INPUT-OUTPUT DEFINE */ +/* Input defines */ +#define APCI1564_DIGITAL_IP 0x04 +#define APCI1564_DIGITAL_IP_INTERRUPT_MODE1 4 +#define APCI1564_DIGITAL_IP_INTERRUPT_MODE2 8 +#define APCI1564_DIGITAL_IP_IRQ 16 + +/* Output defines */ +#define APCI1564_DIGITAL_OP 0x18 +#define APCI1564_DIGITAL_OP_RW 0 +#define APCI1564_DIGITAL_OP_INTERRUPT 4 +#define APCI1564_DIGITAL_OP_IRQ 12 + +/* Digital Input IRQ Function Selection */ +#define ADDIDATA_OR 0 +#define ADDIDATA_AND 1 + +/* Digital Input Interrupt Status */ +#define APCI1564_DIGITAL_IP_INTERRUPT_STATUS 12 + +/* Digital Output Interrupt Status */ +#define APCI1564_DIGITAL_OP_INTERRUPT_STATUS 8 + +/* Digital Input Interrupt Enable Disable. */ +#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4 +#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xfffffffb + +/* Digital Output Interrupt Enable Disable. */ +#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1 +#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xfffffffe +#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2 +#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xfffffffd + +/* ADDIDATA Enable Disable */ + +#define ADDIDATA_ENABLE 1 +#define ADDIDATA_DISABLE 0 + +/* TIMER COUNTER WATCHDOG DEFINES */ + +#define ADDIDATA_TIMER 0 +#define ADDIDATA_COUNTER 1 +#define ADDIDATA_WATCHDOG 2 +#define APCI1564_DIGITAL_OP_WATCHDOG 0x28 +#define APCI1564_TIMER 0x48 +#define APCI1564_COUNTER1 0x0 +#define APCI1564_COUNTER2 0x20 +#define APCI1564_COUNTER3 0x40 +#define APCI1564_COUNTER4 0x60 +#define APCI1564_TCW_SYNC_ENABLEDISABLE 0 +#define APCI1564_TCW_RELOAD_VALUE 4 +#define APCI1564_TCW_TIMEBASE 8 +#define APCI1564_TCW_PROG 12 +#define APCI1564_TCW_TRIG_STATUS 16 +#define APCI1564_TCW_IRQ 20 +#define APCI1564_TCW_WARN_TIMEVAL 24 +#define APCI1564_TCW_WARN_TIMEBASE 28 /* Global variables */ static unsigned int ui_InterruptStatus_1564 = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h deleted file mode 100644 index df69fd04c55..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ - -/********* Definitions for APCI-1564 card *****/ - -#define APCI1564_ADDRESS_RANGE 128 - -/* DIGITAL INPUT-OUTPUT DEFINE */ -/* Input defines */ -#define APCI1564_DIGITAL_IP 0x04 -#define APCI1564_DIGITAL_IP_INTERRUPT_MODE1 4 -#define APCI1564_DIGITAL_IP_INTERRUPT_MODE2 8 -#define APCI1564_DIGITAL_IP_IRQ 16 - -/* Output defines */ -#define APCI1564_DIGITAL_OP 0x18 -#define APCI1564_DIGITAL_OP_RW 0 -#define APCI1564_DIGITAL_OP_INTERRUPT 4 -#define APCI1564_DIGITAL_OP_IRQ 12 - -/* Digital Input IRQ Function Selection */ -#define ADDIDATA_OR 0 -#define ADDIDATA_AND 1 - -/* Digital Input Interrupt Status */ -#define APCI1564_DIGITAL_IP_INTERRUPT_STATUS 12 - -/* Digital Output Interrupt Status */ -#define APCI1564_DIGITAL_OP_INTERRUPT_STATUS 8 - -/* Digital Input Interrupt Enable Disable. */ -#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4 -#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB - -/* Digital Output Interrupt Enable Disable. */ -#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1 -#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE -#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2 -#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD - -/* ADDIDATA Enable Disable */ - -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - -/* TIMER COUNTER WATCHDOG DEFINES */ - -#define ADDIDATA_TIMER 0 -#define ADDIDATA_COUNTER 1 -#define ADDIDATA_WATCHDOG 2 -#define APCI1564_DIGITAL_OP_WATCHDOG 0x28 -#define APCI1564_TIMER 0x48 -#define APCI1564_COUNTER1 0x0 -#define APCI1564_COUNTER2 0x20 -#define APCI1564_COUNTER3 0x40 -#define APCI1564_COUNTER4 0x60 -#define APCI1564_TCW_SYNC_ENABLEDISABLE 0 -#define APCI1564_TCW_RELOAD_VALUE 4 -#define APCI1564_TCW_TIMEBASE 8 -#define APCI1564_TCW_PROG 12 -#define APCI1564_TCW_TRIG_STATUS 16 -#define APCI1564_TCW_IRQ 20 -#define APCI1564_TCW_WARN_TIMEVAL 24 -#define APCI1564_TCW_WARN_TIMEBASE 28 -- cgit v1.2.3 From afad945a8aa508c6a4bfa8d9cb616dbe6d17962e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:56:59 -0700 Subject: staging: comedi: hwrdv_apci16xx: absorb private header The header file hwdrv_apci16xx.h is only included by the source file hwrdv_apci16xx.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci16xx.c | 28 +++++++++++---- .../comedi/drivers/addi-data/hwdrv_apci16xx.h | 40 ---------------------- 2 files changed, 22 insertions(+), 46 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c index 722832b8dc2..b71b7bb944b 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c @@ -47,13 +47,29 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ +#ifndef COMEDI_SUBD_TTLIO +#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ +#endif + +#ifndef ADDIDATA_ENABLE +#define ADDIDATA_ENABLE 1 +#define ADDIDATA_DISABLE 0 +#endif + +#define APCI16XX_TTL_INIT 0 +#define APCI16XX_TTL_INITDIRECTION 1 +#define APCI16XX_TTL_OUTPUTMEMORY 2 + +#define APCI16XX_TTL_READCHANNEL 0 +#define APCI16XX_TTL_READPORT 1 + +#define APCI16XX_TTL_WRITECHANNEL_ON 0 +#define APCI16XX_TTL_WRITECHANNEL_OFF 1 +#define APCI16XX_TTL_WRITEPORT_ON 2 +#define APCI16XX_TTL_WRITEPORT_OFF 3 -#include "hwdrv_apci16xx.h" +#define APCI16XX_TTL_READ_ALL_INPUTS 0 +#define APCI16XX_TTL_READ_ALL_OUTPUTS 1 /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h deleted file mode 100644 index 6293633b2a1..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data-com - * info@addi-data.com - * - * 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. - */ - -#ifndef COMEDI_SUBD_TTLIO -#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ -#endif - -#ifndef ADDIDATA_ENABLE -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 -#endif - -#define APCI16XX_TTL_INIT 0 -#define APCI16XX_TTL_INITDIRECTION 1 -#define APCI16XX_TTL_OUTPUTMEMORY 2 - -#define APCI16XX_TTL_READCHANNEL 0 -#define APCI16XX_TTL_READPORT 1 - -#define APCI16XX_TTL_WRITECHANNEL_ON 0 -#define APCI16XX_TTL_WRITECHANNEL_OFF 1 -#define APCI16XX_TTL_WRITEPORT_ON 2 -#define APCI16XX_TTL_WRITEPORT_OFF 3 - -#define APCI16XX_TTL_READ_ALL_INPUTS 0 -#define APCI16XX_TTL_READ_ALL_OUTPUTS 1 -- cgit v1.2.3 From c89f3871846e28e12c5f15e3c7d043ca92ee25ef Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:57:13 -0700 Subject: staging: comedi: hwrdv_apci2016: absorb private header The header file hwdrv_apci2016.h is only included by the source file hwrdv_apci2016.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci2016.c | 27 ++++++++++++---- .../comedi/drivers/addi-data/hwdrv_apci2016.h | 37 ---------------------- 2 files changed, 21 insertions(+), 43 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c index d42bd62e803..5342832b809 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c @@ -46,12 +46,27 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci2016.h" +/********* Definitions for APCI-2016 card *****/ + +#define APCI2016_ADDRESS_RANGE 8 + +/* DIGITAL INPUT-OUTPUT DEFINE */ + +#define APCI2016_DIGITAL_OP 0x04 +#define APCI2016_DIGITAL_OP_RW 4 + +/* ADDIDATA Enable Disable */ + +#define ADDIDATA_ENABLE 1 +#define ADDIDATA_DISABLE 0 + +/* TIMER COUNTER WATCHDOG DEFINES */ + +#define ADDIDATA_WATCHDOG 2 +#define APCI2016_DIGITAL_OP_WATCHDOG 0 +#define APCI2016_WATCHDOG_ENABLEDISABLE 12 +#define APCI2016_WATCHDOG_RELOAD_VALUE 4 +#define APCI2016_WATCHDOG_STATUS 16 /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h deleted file mode 100644 index 635295eef1c..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ -/********* Definitions for APCI-2016 card *****/ - -#define APCI2016_ADDRESS_RANGE 8 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI2016_DIGITAL_OP 0x04 -#define APCI2016_DIGITAL_OP_RW 4 - -/* ADDIDATA Enable Disable */ - -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - -/* TIMER COUNTER WATCHDOG DEFINES */ - -#define ADDIDATA_WATCHDOG 2 -#define APCI2016_DIGITAL_OP_WATCHDOG 0 -#define APCI2016_WATCHDOG_ENABLEDISABLE 12 -#define APCI2016_WATCHDOG_RELOAD_VALUE 4 -#define APCI2016_WATCHDOG_STATUS 16 -- cgit v1.2.3 From 1417b5f932960653f9dac043dc45bb129ddbce1f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:57:29 -0700 Subject: staging: comedi: hwrdv_apci2032: absorb private header The header file hwdrv_apci2032.h is only included by the source file hwrdv_apci2032.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci2032.c | 42 ++++++++++++++--- .../comedi/drivers/addi-data/hwdrv_apci2032.h | 52 ---------------------- 2 files changed, 36 insertions(+), 58 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c index a198e5df210..557df247b7f 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c @@ -46,14 +46,44 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ +/********* Definitions for APCI-2032 card *****/ + +/* Card Specific information */ +#define APCI2032_ADDRESS_RANGE 63 + +/* DIGITAL INPUT-OUTPUT DEFINE */ + +#define APCI2032_DIGITAL_OP 0 +#define APCI2032_DIGITAL_OP_RW 0 +#define APCI2032_DIGITAL_OP_INTERRUPT 4 +#define APCI2032_DIGITAL_OP_IRQ 12 + +/* Digital Output Interrupt Status */ +#define APCI2032_DIGITAL_OP_INTERRUPT_STATUS 8 + +/* Digital Output Interrupt Enable Disable. */ +#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1 +#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xfffffffe +#define APCI2032_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2 +#define APCI2032_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xfffffffd + +/* ADDIDATA Enable Disable */ + +#define ADDIDATA_ENABLE 1 +#define ADDIDATA_DISABLE 0 + +/* TIMER COUNTER WATCHDOG DEFINES */ + +#define ADDIDATA_WATCHDOG 2 +#define APCI2032_DIGITAL_OP_WATCHDOG 16 +#define APCI2032_TCW_RELOAD_VALUE 4 +#define APCI2032_TCW_TIMEBASE 8 +#define APCI2032_TCW_PROG 12 +#define APCI2032_TCW_TRIG_STATUS 16 +#define APCI2032_TCW_IRQ 20 -#include "hwdrv_apci2032.h" static unsigned int ui_InterruptData, ui_Type; + /* +----------------------------------------------------------------------------+ | Function Name : int i_APCI2032_ConfigDigitalOutput | diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h deleted file mode 100644 index a156a65a899..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ - -/********* Definitions for APCI-2032 card *****/ - -/* Card Specific information */ -#define APCI2032_ADDRESS_RANGE 63 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI2032_DIGITAL_OP 0 -#define APCI2032_DIGITAL_OP_RW 0 -#define APCI2032_DIGITAL_OP_INTERRUPT 4 -#define APCI2032_DIGITAL_OP_IRQ 12 - -/* Digital Output Interrupt Status */ -#define APCI2032_DIGITAL_OP_INTERRUPT_STATUS 8 - -/* Digital Output Interrupt Enable Disable. */ -#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1 -#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE -#define APCI2032_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2 -#define APCI2032_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD - -/* ADDIDATA Enable Disable */ - -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - -/* TIMER COUNTER WATCHDOG DEFINES */ - -#define ADDIDATA_WATCHDOG 2 -#define APCI2032_DIGITAL_OP_WATCHDOG 16 -#define APCI2032_TCW_RELOAD_VALUE 4 -#define APCI2032_TCW_TIMEBASE 8 -#define APCI2032_TCW_PROG 12 -#define APCI2032_TCW_TRIG_STATUS 16 -#define APCI2032_TCW_IRQ 20 -- cgit v1.2.3 From 7526eabe6af0a11d75ec58b064bd1c5b4bfb1cad Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:57:44 -0700 Subject: staging: comedi: hwrdv_apci2200: absorb private header The header file hwdrv_apci2200.h is only included by the source file hwrdv_apci2200.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci2200.c | 22 +++++++++++---- .../comedi/drivers/addi-data/hwdrv_apci2200.h | 33 ---------------------- 2 files changed, 16 insertions(+), 39 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c index 4453ceaca6d..94c884d31b1 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c @@ -46,12 +46,22 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci2200.h" +/********* Definitions for APCI-2200 card *****/ + +/* Card Specific information */ +#define APCI2200_ADDRESS_RANGE 64 + +/* DIGITAL INPUT-OUTPUT DEFINE */ + +#define APCI2200_DIGITAL_OP 4 +#define APCI2200_DIGITAL_IP 0 + +/* TIMER COUNTER WATCHDOG DEFINES */ + +#define APCI2200_WATCHDOG 0x08 +#define APCI2200_WATCHDOG_ENABLEDISABLE 12 +#define APCI2200_WATCHDOG_RELOAD_VALUE 4 +#define APCI2200_WATCHDOG_STATUS 16 /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h deleted file mode 100644 index 6267c8f0d60..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ - -/********* Definitions for APCI-2200 card *****/ - -/* Card Specific information */ -#define APCI2200_ADDRESS_RANGE 64 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI2200_DIGITAL_OP 4 -#define APCI2200_DIGITAL_IP 0 - -/* TIMER COUNTER WATCHDOG DEFINES */ - -#define APCI2200_WATCHDOG 0x08 -#define APCI2200_WATCHDOG_ENABLEDISABLE 12 -#define APCI2200_WATCHDOG_RELOAD_VALUE 4 -#define APCI2200_WATCHDOG_STATUS 16 -- cgit v1.2.3 From c919d71c7e3cd4573c6d4c49806105513492400f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:57:59 -0700 Subject: staging: comedi: hwrdv_apci3501: absorb private header The header file hwdrv_apci3501.h is only included by the source file hwrdv_apci3501.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3501.c | 43 +++++++++++++++--- .../comedi/drivers/addi-data/hwdrv_apci3501.h | 52 ---------------------- 2 files changed, 37 insertions(+), 58 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c index 609edd7ce8d..c92ec8fc932 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c @@ -46,12 +46,43 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci3501.h" +/* Card Specific information */ +#define APCI3501_ADDRESS_RANGE 255 + +#define APCI3501_DIGITAL_IP 0x50 +#define APCI3501_DIGITAL_OP 0x40 +#define APCI3501_ANALOG_OUTPUT 0x00 + +/* Analog Output related Defines */ +#define APCI3501_AO_VOLT_MODE 0 +#define APCI3501_AO_PROG 4 +#define APCI3501_AO_TRIG_SCS 8 +#define UNIPOLAR 0 +#define BIPOLAR 1 +#define MODE0 0 +#define MODE1 1 + +/* Watchdog Related Defines */ + +#define APCI3501_WATCHDOG 0x20 +#define APCI3501_TCW_SYNC_ENABLEDISABLE 0 +#define APCI3501_TCW_RELOAD_VALUE 4 +#define APCI3501_TCW_TIMEBASE 8 +#define APCI3501_TCW_PROG 12 +#define APCI3501_TCW_TRIG_STATUS 16 +#define APCI3501_TCW_IRQ 20 +#define APCI3501_TCW_WARN_TIMEVAL 24 +#define APCI3501_TCW_WARN_TIMEBASE 28 +#define ADDIDATA_TIMER 0 +#define ADDIDATA_WATCHDOG 2 + +/* ANALOG OUTPUT RANGE */ +static struct comedi_lrange range_apci3501_ao = { + 2, { + BIP_RANGE(10), + UNI_RANGE(10) + } +}; /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h deleted file mode 100644 index 201fc7bf081..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ - -/* Card Specific information */ -#define APCI3501_ADDRESS_RANGE 255 - -#define APCI3501_DIGITAL_IP 0x50 -#define APCI3501_DIGITAL_OP 0x40 -#define APCI3501_ANALOG_OUTPUT 0x00 - -/* Analog Output related Defines */ -#define APCI3501_AO_VOLT_MODE 0 -#define APCI3501_AO_PROG 4 -#define APCI3501_AO_TRIG_SCS 8 -#define UNIPOLAR 0 -#define BIPOLAR 1 -#define MODE0 0 -#define MODE1 1 -/* ANALOG OUTPUT RANGE */ -static struct comedi_lrange range_apci3501_ao = { 2, { - BIP_RANGE(10), - UNI_RANGE(10) - } -}; - -/* Watchdog Related Defines */ - -#define APCI3501_WATCHDOG 0x20 -#define APCI3501_TCW_SYNC_ENABLEDISABLE 0 -#define APCI3501_TCW_RELOAD_VALUE 4 -#define APCI3501_TCW_TIMEBASE 8 -#define APCI3501_TCW_PROG 12 -#define APCI3501_TCW_TRIG_STATUS 16 -#define APCI3501_TCW_IRQ 20 -#define APCI3501_TCW_WARN_TIMEVAL 24 -#define APCI3501_TCW_WARN_TIMEBASE 28 -#define ADDIDATA_TIMER 0 -#define ADDIDATA_WATCHDOG 2 -- cgit v1.2.3 From 4ebd3047461cd547a1c654be04b91c0495b82677 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:58:14 -0700 Subject: staging: comedi: hwrdv_apci3xxx: absorb private header The header file hwdrv_apci3xxx.h is only included by the source file hwrdv_apci3xxx.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3xxx.c | 35 +++++++++++++++- .../comedi/drivers/addi-data/hwdrv_apci3xxx.h | 48 ---------------------- 2 files changed, 34 insertions(+), 49 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c index 80974f27ff3..23984bfcce3 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c @@ -44,7 +44,40 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -#include "hwdrv_apci3xxx.h" +#ifndef COMEDI_SUBD_TTLIO +#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ +#endif + +#ifndef ADDIDATA_ENABLE +#define ADDIDATA_ENABLE 1 +#define ADDIDATA_DISABLE 0 +#endif + +#define APCI3XXX_SINGLE 0 +#define APCI3XXX_DIFF 1 +#define APCI3XXX_CONFIGURATION 0 + +#define APCI3XXX_TTL_INIT_DIRECTION_PORT2 0 + +static const struct comedi_lrange range_apci3XXX_ai = { + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1) + } +}; + +static const struct comedi_lrange range_apci3XXX_ao = { + 2, { + BIP_RANGE(10), + UNI_RANGE(10) + } +}; /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h deleted file mode 100644 index e10b7e51033..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ - -#ifndef COMEDI_SUBD_TTLIO -#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ -#endif - -#ifndef ADDIDATA_ENABLE -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 -#endif - -#define APCI3XXX_SINGLE 0 -#define APCI3XXX_DIFF 1 -#define APCI3XXX_CONFIGURATION 0 - -#define APCI3XXX_TTL_INIT_DIRECTION_PORT2 0 - -#ifdef __KERNEL__ - -static const struct comedi_lrange range_apci3XXX_ai = { 8, {BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1)} -}; - -static const struct comedi_lrange range_apci3XXX_ao = { 2, {BIP_RANGE(10), - UNI_RANGE(10)} -}; -#endif -- cgit v1.2.3 From 8f8a3534791b5ed0561b87f0e39c93eb8c6b609c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:59:19 -0700 Subject: staging: comedi: hwdrv_apci3120: remove forward declarations This source file is #include'd when building the addi_apci_3001 and addi_apci_3120 drivers. All the functions in this file are actually static and should not be exported to the kernel. Move some of the functions to remove the need for the forward declarations and make all of the functions in this file static. Note, this patch does not try to fix any of the coding style issues in the functions. Also, remove most of the big comment blocks preceding each function. Leave the 'task' information for some of them to assist in later cleanup. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 1471 +++++++------------- .../comedi/drivers/addi-data/hwdrv_apci3120.h | 72 - 2 files changed, 537 insertions(+), 1006 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 0cbe915a5ce..573297830d4 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -55,27 +55,10 @@ static unsigned int ui_Temp; +----------------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev,| -| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Calls card specific function | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int i; @@ -122,30 +105,69 @@ int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_su } /* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, | -| struct comedi_subdevice *s,struct comedi_insn *insn, unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : card specific function | -| Reads analog input in synchronous mode | -| EOC and EOS is selected as per configured | -| if no conversion time is set uses default conversion | -| time 10 microsec. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ + * This function will first check channel list is ok or not and then + * initialize the sequence RAM with the polarity, Gain,Channel number. + * If the last argument of function "check"is 1 then it only checks + * the channel list is ok or not. + */ +static int i_APCI3120_SetupChannelList(struct comedi_device *dev, + struct comedi_subdevice *s, + int n_chan, + unsigned int *chanlist, + char check) +{ + struct addi_private *devpriv = dev->private; + unsigned int i; /* , differencial=0, bipolar=0; */ + unsigned int gain; + unsigned short us_TmpValue; + + /* correct channel and range number check itself comedi/range.c */ + if (n_chan < 1) { + if (!check) + comedi_error(dev, "range/channel list is empty!"); + return 0; + } + /* All is ok, so we can setup channel/range list */ + if (check) + return 1; + + /* Code to set the PA and PR...Here it set PA to 0.. */ + devpriv->us_OutputRegister = + devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR; + devpriv->us_OutputRegister = ((n_chan - 1) & 0xf) << 8; + outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + + for (i = 0; i < n_chan; i++) { + /* store range list to card */ + us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number; */ + + if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) + us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */ + else + us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */ + + gain = CR_RANGE(chanlist[i]); /* get gain number */ + us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */ + us_TmpValue |= i << 8; /* To select the RAM LOCATION.... */ + outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS); + + printk("\n Gain = %i", + (((unsigned char)CR_RANGE(chanlist[i]) & 0x03) << 2)); + printk("\n Channel = %i", CR_CHAN(chanlist[i])); + printk("\n Polarity = %i", us_TmpValue & APCI3120_UNIPOLAR); + } + return 1; /* we can serve this with scan logic */ +} -int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +/* + * Reads analog input in synchronous mode EOC and EOS is selected + * as per configured if no conversion time is set uses default + * conversion time 10 microsec. + */ +static int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; @@ -390,25 +412,83 @@ int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subd } +static int i_APCI3120_Reset(struct comedi_device *dev) +{ + struct addi_private *devpriv = dev->private; + unsigned int i; + unsigned short us_TmpValue; + + devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; + devpriv->b_EocEosInterrupt = APCI3120_DISABLE; + devpriv->b_InterruptMode = APCI3120_EOC_MODE; + devpriv->ui_EocEosConversionTime = 0; /* set eoc eos conv time to 0 */ + devpriv->b_OutputMemoryStatus = 0; + + /* variables used in timer subdevice */ + devpriv->b_Timer2Mode = 0; + devpriv->b_Timer2Interrupt = 0; + devpriv->b_ExttrigEnable = 0; /* Disable ext trigger */ + + /* Disable all interrupts, watchdog for the anolog output */ + devpriv->b_ModeSelectRegister = 0; + outb(devpriv->b_ModeSelectRegister, + dev->iobase + APCI3120_WRITE_MODE_SELECT); + + /* Disables all counters, ext trigger and clears PA, PR */ + devpriv->us_OutputRegister = 0; + outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + /* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev,| -| struct comedi_subdevice *s)| -| | -+----------------------------------------------------------------------------+ -| Task : Stops Cyclic acquisition | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| | -+----------------------------------------------------------------------------+ -| Return Value :0 | -| | -+----------------------------------------------------------------------------+ -*/ + * Code to set the all anolog o/p channel to 0v 8191 is decimal + * value for zero(0 v)volt in bipolar mode(default) + */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 1 */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 2 */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 3 */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 4 */ + + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 5 */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 6 */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 7 */ + outw(8191 | APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 8 */ + + /* Reset digital output to L0W */ + +/* ES05 outb(0x0,dev->iobase+APCI3120_DIGITAL_OUTPUT); */ + udelay(10); + + inw(dev->iobase + 0); /* make a dummy read */ + inb(dev->iobase + APCI3120_RESET_FIFO); /* flush FIFO */ + inw(dev->iobase + APCI3120_RD_STATUS); /* flush A/D status register */ + + /* code to reset the RAM sequence */ + for (i = 0; i < 16; i++) { + us_TmpValue = i << 8; /* select the location */ + outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS); + } + return 0; +} + +static int i_APCI3120_ExttrigEnable(struct comedi_device *dev) +{ + struct addi_private *devpriv = dev->private; + + devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER; + outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + return 0; +} -int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s) +static int i_APCI3120_ExttrigDisable(struct comedi_device *dev) +{ + struct addi_private *devpriv = dev->private; + + devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER; + outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + return 0; +} + +static int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, + struct comedi_subdevice *s) { struct addi_private *devpriv = dev->private; @@ -461,27 +541,9 @@ int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_su return 0; } -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev| -| ,struct comedi_subdevice *s,struct comedi_cmd *cmd) | -| | -+----------------------------------------------------------------------------+ -| Task : Test validity for a command for cyclic anlog input | -| acquisition | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_cmd *cmd | -+----------------------------------------------------------------------------+ -| Return Value :0 | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd) +static int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; @@ -591,100 +653,14 @@ int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s } /* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, | -| struct comedi_subdevice *s) | -| | -+----------------------------------------------------------------------------+ -| Task : Does asynchronous acquisition | -| Determines the mode 1 or 2. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s) -{ - struct addi_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; - - /* loading private structure with cmd structure inputs */ - devpriv->ui_AiFlags = cmd->flags; - devpriv->ui_AiNbrofChannels = cmd->chanlist_len; - devpriv->ui_AiScanLength = cmd->scan_end_arg; - devpriv->pui_AiChannelList = cmd->chanlist; - - /* UPDATE-0.7.57->0.7.68devpriv->AiData=s->async->data; */ - devpriv->AiData = s->async->prealloc_buf; - /* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */ - devpriv->ui_AiDataLength = s->async->prealloc_bufsz; - - if (cmd->stop_src == TRIG_COUNT) - devpriv->ui_AiNbrofScans = cmd->stop_arg; - else - devpriv->ui_AiNbrofScans = 0; - - devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */ - devpriv->ui_AiTimer1 = 0; - if ((devpriv->ui_AiNbrofScans == 0) || (devpriv->ui_AiNbrofScans == -1)) - devpriv->b_AiContinuous = 1; /* user want neverending analog acquisition */ - /* stopped using cancel */ - - if (cmd->start_src == TRIG_EXT) - devpriv->b_ExttrigEnable = APCI3120_ENABLE; - else - devpriv->b_ExttrigEnable = APCI3120_DISABLE; - - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* mode 1 or 3 */ - if (cmd->convert_src == TRIG_TIMER) { - /* mode 1 */ - - devpriv->ui_AiTimer0 = cmd->convert_arg; /* timer constant in nano seconds */ - /* return this_board->ai_cmd(1,dev,s); */ - return i_APCI3120_CyclicAnalogInput(1, dev, s); - } - - } - if ((cmd->scan_begin_src == TRIG_TIMER) - && (cmd->convert_src == TRIG_TIMER)) { - /* mode 2 */ - devpriv->ui_AiTimer1 = cmd->scan_begin_arg; - devpriv->ui_AiTimer0 = cmd->convert_arg; /* variable changed timer2 to timer0 */ - /* return this_board->ai_cmd(2,dev,s); */ - return i_APCI3120_CyclicAnalogInput(2, dev, s); - } - return -1; -} - -/* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_CyclicAnalogInput(int mode, | -| struct comedi_device * dev,struct comedi_subdevice * s) | -+----------------------------------------------------------------------------+ -| Task : This is used for analog input cyclic acquisition | -| Performs the command operations. | -| If DMA is configured does DMA initialization | -| otherwise does the acquisition with EOS interrupt. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, - struct comedi_subdevice *s) + * This is used for analog input cyclic acquisition. + * Performs the command operations. + * If DMA is configured does DMA initialization otherwise does the + * acquisition with EOS interrupt. + */ +static int i_APCI3120_CyclicAnalogInput(int mode, + struct comedi_device *dev, + struct comedi_subdevice *s) { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; @@ -1196,237 +1172,268 @@ int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, } /* -+----------------------------------------------------------------------------+ -| intERNAL FUNCTIONS | -+----------------------------------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_Reset(struct comedi_device *dev) | -| | -| | -+----------------------------------------------------------------------------+ -| Task : Hardware reset function | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_Reset(struct comedi_device *dev) + * Does asynchronous acquisition. + * Determines the mode 1 or 2. + */ +static int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s) { struct addi_private *devpriv = dev->private; - unsigned int i; - unsigned short us_TmpValue; + struct comedi_cmd *cmd = &s->async->cmd; - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - devpriv->ui_EocEosConversionTime = 0; /* set eoc eos conv time to 0 */ - devpriv->b_OutputMemoryStatus = 0; + /* loading private structure with cmd structure inputs */ + devpriv->ui_AiFlags = cmd->flags; + devpriv->ui_AiNbrofChannels = cmd->chanlist_len; + devpriv->ui_AiScanLength = cmd->scan_end_arg; + devpriv->pui_AiChannelList = cmd->chanlist; - /* variables used in timer subdevice */ - devpriv->b_Timer2Mode = 0; - devpriv->b_Timer2Interrupt = 0; - devpriv->b_ExttrigEnable = 0; /* Disable ext trigger */ + /* UPDATE-0.7.57->0.7.68devpriv->AiData=s->async->data; */ + devpriv->AiData = s->async->prealloc_buf; + /* UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len; */ + devpriv->ui_AiDataLength = s->async->prealloc_bufsz; - /* Disable all interrupts, watchdog for the anolog output */ - devpriv->b_ModeSelectRegister = 0; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); + if (cmd->stop_src == TRIG_COUNT) + devpriv->ui_AiNbrofScans = cmd->stop_arg; + else + devpriv->ui_AiNbrofScans = 0; - /* Disables all counters, ext trigger and clears PA, PR */ - devpriv->us_OutputRegister = 0; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - -/* - * Code to set the all anolog o/p channel to 0v 8191 is decimal - * value for zero(0 v)volt in bipolar mode(default) - */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 1 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 2 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 3 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase + APCI3120_ANALOG_OUTPUT_1); /* channel 4 */ - - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 5 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 6 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 7 */ - outw(8191 | APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase + APCI3120_ANALOG_OUTPUT_2); /* channel 8 */ + devpriv->ui_AiTimer0 = 0; /* variables changed to timer0,timer1 */ + devpriv->ui_AiTimer1 = 0; + if ((devpriv->ui_AiNbrofScans == 0) || (devpriv->ui_AiNbrofScans == -1)) + devpriv->b_AiContinuous = 1; /* user want neverending analog acquisition */ + /* stopped using cancel */ - /* Reset digital output to L0W */ + if (cmd->start_src == TRIG_EXT) + devpriv->b_ExttrigEnable = APCI3120_ENABLE; + else + devpriv->b_ExttrigEnable = APCI3120_DISABLE; -/* ES05 outb(0x0,dev->iobase+APCI3120_DIGITAL_OUTPUT); */ - udelay(10); + if (cmd->scan_begin_src == TRIG_FOLLOW) { + /* mode 1 or 3 */ + if (cmd->convert_src == TRIG_TIMER) { + /* mode 1 */ - inw(dev->iobase + 0); /* make a dummy read */ - inb(dev->iobase + APCI3120_RESET_FIFO); /* flush FIFO */ - inw(dev->iobase + APCI3120_RD_STATUS); /* flush A/D status register */ + devpriv->ui_AiTimer0 = cmd->convert_arg; /* timer constant in nano seconds */ + /* return this_board->ai_cmd(1,dev,s); */ + return i_APCI3120_CyclicAnalogInput(1, dev, s); + } - /* code to reset the RAM sequence */ - for (i = 0; i < 16; i++) { - us_TmpValue = i << 8; /* select the location */ - outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS); } - return 0; + if ((cmd->scan_begin_src == TRIG_TIMER) + && (cmd->convert_src == TRIG_TIMER)) { + /* mode 2 */ + devpriv->ui_AiTimer1 = cmd->scan_begin_arg; + devpriv->ui_AiTimer0 = cmd->convert_arg; /* variable changed timer2 to timer0 */ + /* return this_board->ai_cmd(2,dev,s); */ + return i_APCI3120_CyclicAnalogInput(2, dev, s); + } + return -1; } /* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_SetupChannelList(struct comedi_device * dev, | -| struct comedi_subdevice * s, int n_chan,unsigned int *chanlist| -| ,char check) | -| | -+----------------------------------------------------------------------------+ -| Task :This function will first check channel list is ok or not| -|and then initialize the sequence RAM with the polarity, Gain,Channel number | -|If the last argument of function "check"is 1 then it only checks the channel| -|list is ok or not. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device * dev | -| struct comedi_subdevice * s | -| int n_chan | - unsigned int *chanlist - char check -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ + * This function copies the data from DMA buffer to the Comedi buffer. + */ +static void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, + struct comedi_subdevice *s, + short *dma_buffer, + unsigned int num_samples) +{ + struct addi_private *devpriv = dev->private; + + devpriv->ui_AiActualScan += + (s->async->cur_chan + num_samples) / devpriv->ui_AiScanLength; + s->async->cur_chan += num_samples; + s->async->cur_chan %= devpriv->ui_AiScanLength; + + cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short)); +} -int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevice *s, - int n_chan, unsigned int *chanlist, char check) +/* + * This is a handler for the DMA interrupt. + * This function copies the data to Comedi Buffer. + * For continuous DMA it reinitializes the DMA operation. + * For single mode DMA it stop the acquisition. + */ +static void v_APCI3120_InterruptDma(int irq, void *d) { + struct comedi_device *dev = d; struct addi_private *devpriv = dev->private; - unsigned int i; /* , differencial=0, bipolar=0; */ - unsigned int gain; - unsigned short us_TmpValue; + struct comedi_subdevice *s = &dev->subdevices[0]; + unsigned int next_dma_buf, samplesinbuf; + unsigned long low_word, high_word, var; + unsigned int ui_Tmp; - /* correct channel and range number check itself comedi/range.c */ - if (n_chan < 1) { - if (!check) - comedi_error(dev, "range/channel list is empty!"); - return 0; + samplesinbuf = + devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] - + inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC); + + if (samplesinbuf < + devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) { + comedi_error(dev, "Interrupted DMA transfer!"); } - /* All is ok, so we can setup channel/range list */ - if (check) - return 1; + if (samplesinbuf & 1) { + comedi_error(dev, "Odd count of bytes in DMA ring!"); + i_APCI3120_StopCyclicAcquisition(dev, s); + devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; - /* Code to set the PA and PR...Here it set PA to 0.. */ - devpriv->us_OutputRegister = - devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR; - devpriv->us_OutputRegister = ((n_chan - 1) & 0xf) << 8; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); + return; + } + samplesinbuf = samplesinbuf >> 1; /* number of received samples */ + if (devpriv->b_DmaDoubleBuffer) { + /* switch DMA buffers if is used double buffering */ + next_dma_buf = 1 - devpriv->ui_DmaActualBuffer; - for (i = 0; i < n_chan; i++) { - /* store range list to card */ - us_TmpValue = CR_CHAN(chanlist[i]); /* get channel number; */ + ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; + outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); - if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) - us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); /* set bipolar */ - else - us_TmpValue |= APCI3120_UNIPOLAR; /* enable unipolar...... */ + /* changed since 16 bit interface for add on */ + outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, + devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* 0x1000 is out putted in windows driver */ - gain = CR_RANGE(chanlist[i]); /* get gain number */ - us_TmpValue |= ((gain & 0x03) << 4); /* <<4 for G0 and G1 bit in RAM */ - us_TmpValue |= i << 8; /* To select the RAM LOCATION.... */ - outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS); + var = devpriv->ul_DmaBufferHw[next_dma_buf]; + low_word = var & 0xffff; + var = devpriv->ul_DmaBufferHw[next_dma_buf]; + high_word = var / 65536; + + /* DMA Start Address Low */ + outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); + outw(low_word, devpriv->i_IobaseAddon + 2); + + /* DMA Start Address High */ + outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); + outw(high_word, devpriv->i_IobaseAddon + 2); + + var = devpriv->ui_DmaBufferUsesize[next_dma_buf]; + low_word = var & 0xffff; + var = devpriv->ui_DmaBufferUsesize[next_dma_buf]; + high_word = var / 65536; + + /* Nbr of acquisition LOW */ + outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); + outw(low_word, devpriv->i_IobaseAddon + 2); + + /* Nbr of acquisition HIGH */ + outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); + outw(high_word, devpriv->i_IobaseAddon + 2); + +/* + * To configure A2P FIFO + * ENABLE A2P FIFO WRITE AND ENABLE AMWEN + * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 + */ + outw(3, devpriv->i_IobaseAddon + 4); + /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ + outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | + APCI3120_ENABLE_WRITE_TC_INT), + devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); - printk("\n Gain = %i", - (((unsigned char)CR_RANGE(chanlist[i]) & 0x03) << 2)); - printk("\n Channel = %i", CR_CHAN(chanlist[i])); - printk("\n Polarity = %i", us_TmpValue & APCI3120_UNIPOLAR); } - return 1; /* we can serve this with scan logic */ -} + if (samplesinbuf) { + v_APCI3120_InterruptDmaMoveBlock16bit(dev, s, + devpriv->ul_DmaBufferVirtual[devpriv-> + ui_DmaActualBuffer], samplesinbuf); + + if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS)) { + s->async->events |= COMEDI_CB_EOS; + comedi_event(dev, s); + } + } + if (!devpriv->b_AiContinuous) + if (devpriv->ui_AiActualScan >= devpriv->ui_AiNbrofScans) { + /* all data sampled */ + i_APCI3120_StopCyclicAcquisition(dev, s); + devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; + s->async->events |= COMEDI_CB_EOA; + comedi_event(dev, s); + return; + } + + if (devpriv->b_DmaDoubleBuffer) { /* switch dma buffers */ + devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer; + } else { +/* + * restart DMA if is not used double buffering + * ADDED REINITIALISE THE DMA + */ + ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; + outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); + /* changed since 16 bit interface for add on */ + outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, + devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); + outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* */ /* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_ExttrigEnable(struct comedi_device * dev) | -| | -| | -+----------------------------------------------------------------------------+ -| Task : Enable the external trigger | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device * dev | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -| | -+----------------------------------------------------------------------------+ -*/ + * A2P FIFO MANAGEMENT + * A2P fifo reset & transfer control enable + */ + outl(APCI3120_A2P_FIFO_MANAGEMENT, + devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); -int i_APCI3120_ExttrigEnable(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; + var = devpriv->ul_DmaBufferHw[0]; + low_word = var & 0xffff; + var = devpriv->ul_DmaBufferHw[0]; + high_word = var / 65536; + outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); + outw(low_word, devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); + outw(high_word, devpriv->i_IobaseAddon + 2); - devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - return 0; -} + var = devpriv->ui_DmaBufferUsesize[0]; + low_word = var & 0xffff; /* changed */ + var = devpriv->ui_DmaBufferUsesize[0]; + high_word = var / 65536; + outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); + outw(low_word, devpriv->i_IobaseAddon + 2); + outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); + outw(high_word, devpriv->i_IobaseAddon + 2); /* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_ExttrigDisable(struct comedi_device * dev) | -| | -+----------------------------------------------------------------------------+ -| Task : Disables the external trigger | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device * dev | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -| | -+----------------------------------------------------------------------------+ -*/ + * To configure A2P FIFO + * ENABLE A2P FIFO WRITE AND ENABLE AMWEN + * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 + */ + outw(3, devpriv->i_IobaseAddon + 4); + /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ + outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | + APCI3120_ENABLE_WRITE_TC_INT), + devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); + } +} -int i_APCI3120_ExttrigDisable(struct comedi_device *dev) +/* + * This function handles EOS interrupt. + * This function copies the acquired data(from FIFO) to Comedi buffer. + */ +static int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; + int n_chan, i; + struct comedi_subdevice *s = &dev->subdevices[0]; + int err = 1; - devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER; - outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS); - return 0; -} + n_chan = devpriv->ui_AiNbrofChannels; -/* -+----------------------------------------------------------------------------+ -| intERRUPT FUNCTIONS | -+----------------------------------------------------------------------------+ -*/ + s->async->events = 0; -/* -+----------------------------------------------------------------------------+ -| Function name : void v_APCI3120_Interrupt(int irq, void *d) | -| | -| | -+----------------------------------------------------------------------------+ -| Task :Interrupt handler for APCI3120 | -| When interrupt occurs this gets called. | -| First it finds which interrupt has been generated and | -| handles corresponding interrupt | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : int irq | -| void *d | -| | -+----------------------------------------------------------------------------+ -| Return Value : void | -| | -+----------------------------------------------------------------------------+ -*/ + for (i = 0; i < n_chan; i++) + err &= comedi_buf_put(s->async, inw(dev->iobase + 0)); + + s->async->events |= COMEDI_CB_EOS; + + if (err == 0) + s->async->events |= COMEDI_CB_OVERFLOW; + + comedi_event(dev, s); + + return 0; +} -void v_APCI3120_Interrupt(int irq, void *d) +static void v_APCI3120_Interrupt(int irq, void *d) { struct comedi_device *dev = d; struct addi_private *devpriv = dev->private; @@ -1519,384 +1526,115 @@ void v_APCI3120_Interrupt(int irq, void *d) } else { devpriv->b_ModeSelectRegister = devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - devpriv->b_EocEosInterrupt = APCI3120_DISABLE; /* Default settings */ - devpriv->b_InterruptMode = APCI3120_EOC_MODE; - } - - } - /* Timer2 interrupt */ - if (int_daq & 0x1) { - - switch (devpriv->b_Timer2Mode) { - case APCI3120_COUNTER: - - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT; - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - - /* stop timer 2 */ - devpriv->us_OutputRegister = - devpriv-> - us_OutputRegister & APCI3120_DISABLE_ALL_TIMER; - outw(devpriv->us_OutputRegister, - dev->iobase + APCI3120_WR_ADDRESS); - - /* stop timer 0 and timer 1 */ - i_APCI3120_StopCyclicAcquisition(dev, s); - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; - - /* UPDATE-0.7.57->0.7.68comedi_done(dev,s); */ - s->async->events |= COMEDI_CB_EOA; - comedi_event(dev, s); - - break; - - case APCI3120_TIMER: - - /* Send a signal to from kernel to user space */ - send_sig(SIGIO, devpriv->tsk_Current, 0); - break; - - case APCI3120_WATCHDOG: - - /* Send a signal to from kernel to user space */ - send_sig(SIGIO, devpriv->tsk_Current, 0); - break; - - default: - - /* disable Timer Interrupt */ - - devpriv->b_ModeSelectRegister = - devpriv-> - b_ModeSelectRegister & - APCI3120_DISABLE_TIMER_INT; - - outb(devpriv->b_ModeSelectRegister, - dev->iobase + APCI3120_WRITE_MODE_SELECT); - - } - - b_DummyRead = inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); - - } - - if ((int_daq & 0x4) && (devpriv->b_InterruptMode == APCI3120_DMA_MODE)) { - if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) { - - /****************************/ - /* Clear Timer Write TC int */ - /****************************/ - - outl(APCI3120_CLEAR_WRITE_TC_INT, - devpriv->i_IobaseAmcc + - APCI3120_AMCC_OP_REG_INTCSR); - - /************************************/ - /* Clears the timer status register */ - /************************************/ - inw(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); - v_APCI3120_InterruptDma(irq, d); /* do some data transfer */ - } else { - /* Stops the Timer */ - outw(devpriv-> - us_OutputRegister & APCI3120_DISABLE_TIMER0 & - APCI3120_DISABLE_TIMER1, - dev->iobase + APCI3120_WR_ADDRESS); - } - - } - - return; -} - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) | -| | -| | -+----------------------------------------------------------------------------+ -| Task : This function handles EOS interrupt. | -| This function copies the acquired data(from FIFO) | -| to Comedi buffer. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| | -| | -+----------------------------------------------------------------------------+ -| Return Value : 0 | -| | -+----------------------------------------------------------------------------+ -*/ - - -int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - int n_chan, i; - struct comedi_subdevice *s = &dev->subdevices[0]; - int err = 1; - - n_chan = devpriv->ui_AiNbrofChannels; - - s->async->events = 0; - - for (i = 0; i < n_chan; i++) - err &= comedi_buf_put(s->async, inw(dev->iobase + 0)); - - s->async->events |= COMEDI_CB_EOS; - - if (err == 0) - s->async->events |= COMEDI_CB_OVERFLOW; - - comedi_event(dev, s); - - return 0; -} - -/* -+----------------------------------------------------------------------------+ -| Function name : void v_APCI3120_InterruptDma(int irq, void *d) | -| | -+----------------------------------------------------------------------------+ -| Task : This is a handler for the DMA interrupt | -| This function copies the data to Comedi Buffer. | -| For continuous DMA it reinitializes the DMA operation. | -| For single mode DMA it stop the acquisition. | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : int irq, void *d | -| | -+----------------------------------------------------------------------------+ -| Return Value : void | -| | -+----------------------------------------------------------------------------+ -*/ - -void v_APCI3120_InterruptDma(int irq, void *d) -{ - struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; - struct comedi_subdevice *s = &dev->subdevices[0]; - unsigned int next_dma_buf, samplesinbuf; - unsigned long low_word, high_word, var; - unsigned int ui_Tmp; - - samplesinbuf = - devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] - - inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC); - - if (samplesinbuf < - devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) { - comedi_error(dev, "Interrupted DMA transfer!"); - } - if (samplesinbuf & 1) { - comedi_error(dev, "Odd count of bytes in DMA ring!"); - i_APCI3120_StopCyclicAcquisition(dev, s); - devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; - - return; - } - samplesinbuf = samplesinbuf >> 1; /* number of received samples */ - if (devpriv->b_DmaDoubleBuffer) { - /* switch DMA buffers if is used double buffering */ - next_dma_buf = 1 - devpriv->ui_DmaActualBuffer; - - ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); - - /* changed since 16 bit interface for add on */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, - devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* 0x1000 is out putted in windows driver */ - - var = devpriv->ul_DmaBufferHw[next_dma_buf]; - low_word = var & 0xffff; - var = devpriv->ul_DmaBufferHw[next_dma_buf]; - high_word = var / 65536; - - /* DMA Start Address Low */ - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); - - /* DMA Start Address High */ - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); - - var = devpriv->ui_DmaBufferUsesize[next_dma_buf]; - low_word = var & 0xffff; - var = devpriv->ui_DmaBufferUsesize[next_dma_buf]; - high_word = var / 65536; - - /* Nbr of acquisition LOW */ - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); - - /* Nbr of acquisition HIGH */ - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); - -/* - * To configure A2P FIFO - * ENABLE A2P FIFO WRITE AND ENABLE AMWEN - * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 - */ - outw(3, devpriv->i_IobaseAddon + 4); - /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ - outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | - APCI3120_ENABLE_WRITE_TC_INT), - devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); - - } - if (samplesinbuf) { - v_APCI3120_InterruptDmaMoveBlock16bit(dev, s, - devpriv->ul_DmaBufferVirtual[devpriv-> - ui_DmaActualBuffer], samplesinbuf); - - if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS)) { - s->async->events |= COMEDI_CB_EOS; - comedi_event(dev, s); + b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT; + outb(devpriv->b_ModeSelectRegister, + dev->iobase + APCI3120_WRITE_MODE_SELECT); + devpriv->b_EocEosInterrupt = APCI3120_DISABLE; /* Default settings */ + devpriv->b_InterruptMode = APCI3120_EOC_MODE; } + } - if (!devpriv->b_AiContinuous) - if (devpriv->ui_AiActualScan >= devpriv->ui_AiNbrofScans) { - /* all data sampled */ + /* Timer2 interrupt */ + if (int_daq & 0x1) { + + switch (devpriv->b_Timer2Mode) { + case APCI3120_COUNTER: + + devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; + devpriv->b_ModeSelectRegister = + devpriv-> + b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT; + outb(devpriv->b_ModeSelectRegister, + dev->iobase + APCI3120_WRITE_MODE_SELECT); + + /* stop timer 2 */ + devpriv->us_OutputRegister = + devpriv-> + us_OutputRegister & APCI3120_DISABLE_ALL_TIMER; + outw(devpriv->us_OutputRegister, + dev->iobase + APCI3120_WR_ADDRESS); + + /* stop timer 0 and timer 1 */ i_APCI3120_StopCyclicAcquisition(dev, s); devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE; + + /* UPDATE-0.7.57->0.7.68comedi_done(dev,s); */ s->async->events |= COMEDI_CB_EOA; comedi_event(dev, s); - return; - } - if (devpriv->b_DmaDoubleBuffer) { /* switch dma buffers */ - devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer; - } else { -/* - * restart DMA if is not used double buffering - * ADDED REINITIALISE THE DMA - */ - ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; - outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); + break; - /* changed since 16 bit interface for add on */ - outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW, - devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); - outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* */ -/* - * A2P FIFO MANAGEMENT - * A2P fifo reset & transfer control enable - */ - outl(APCI3120_A2P_FIFO_MANAGEMENT, - devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); + case APCI3120_TIMER: - var = devpriv->ul_DmaBufferHw[0]; - low_word = var & 0xffff; - var = devpriv->ul_DmaBufferHw[0]; - high_word = var / 65536; - outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); + /* Send a signal to from kernel to user space */ + send_sig(SIGIO, devpriv->tsk_Current, 0); + break; - var = devpriv->ui_DmaBufferUsesize[0]; - low_word = var & 0xffff; /* changed */ - var = devpriv->ui_DmaBufferUsesize[0]; - high_word = var / 65536; - outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); - outw(low_word, devpriv->i_IobaseAddon + 2); - outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); - outw(high_word, devpriv->i_IobaseAddon + 2); + case APCI3120_WATCHDOG: + + /* Send a signal to from kernel to user space */ + send_sig(SIGIO, devpriv->tsk_Current, 0); + break; + + default: + + /* disable Timer Interrupt */ + + devpriv->b_ModeSelectRegister = + devpriv-> + b_ModeSelectRegister & + APCI3120_DISABLE_TIMER_INT; + + outb(devpriv->b_ModeSelectRegister, + dev->iobase + APCI3120_WRITE_MODE_SELECT); + + } + + b_DummyRead = inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); -/* - * To configure A2P FIFO - * ENABLE A2P FIFO WRITE AND ENABLE AMWEN - * AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03 - */ - outw(3, devpriv->i_IobaseAddon + 4); - /* initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI) */ - outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 | - APCI3120_ENABLE_WRITE_TC_INT), - devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); } -} -/* -+----------------------------------------------------------------------------+ -| Function name :void v_APCI3120_InterruptDmaMoveBlock16bit(comedi_device| -|*dev,struct comedi_subdevice *s,short *dma,short *data,int n) | -| | -+----------------------------------------------------------------------------+ -| Task : This function copies the data from DMA buffer to the | -| Comedi buffer | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| short *dma | -| short *data,int n | -+----------------------------------------------------------------------------+ -| Return Value : void | -| | -+----------------------------------------------------------------------------+ -*/ + if ((int_daq & 0x4) && (devpriv->b_InterruptMode == APCI3120_DMA_MODE)) { + if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) { -void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, - struct comedi_subdevice *s, short *dma_buffer, unsigned int num_samples) -{ - struct addi_private *devpriv = dev->private; + /****************************/ + /* Clear Timer Write TC int */ + /****************************/ - devpriv->ui_AiActualScan += - (s->async->cur_chan + num_samples) / devpriv->ui_AiScanLength; - s->async->cur_chan += num_samples; - s->async->cur_chan %= devpriv->ui_AiScanLength; + outl(APCI3120_CLEAR_WRITE_TC_INT, + devpriv->i_IobaseAmcc + + APCI3120_AMCC_OP_REG_INTCSR); - cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short)); -} + /************************************/ + /* Clears the timer status register */ + /************************************/ + inw(dev->iobase + APCI3120_TIMER_STATUS_REGISTER); + v_APCI3120_InterruptDma(irq, d); /* do some data transfer */ + } else { + /* Stops the Timer */ + outw(devpriv-> + us_OutputRegister & APCI3120_DISABLE_TIMER0 & + APCI3120_DISABLE_TIMER1, + dev->iobase + APCI3120_WR_ADDRESS); + } -/* -+----------------------------------------------------------------------------+ -| TIMER SUBDEVICE | -+----------------------------------------------------------------------------+ -*/ + } -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, | -| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task :Configure Timer 2 | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -| | -| data[0]= TIMER configure as timer | -| = WATCHDOG configure as watchdog | -| data[1] = Timer constant | -| data[2] = Timer2 interrupt (1)enable or(0) disable | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ + return; +} -int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +/* + * Configure Timer 2 + * + * data[0] = TIMER configure as timer + * = WATCHDOG configure as watchdog + * data[1] = Timer constant + * data[2] = Timer2 interrupt (1)enable or(0) disable + */ +static int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; @@ -2027,35 +1765,21 @@ int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevic } /* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, | -| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : To start and stop the timer | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -| | -| data[0] = 1 (start) | -| data[0] = 0 (stop ) | -| data[0] = 2 (write new value) | -| data[1]= new value | -| | -| devpriv->b_Timer2Mode = 0 DISABLE | -| 1 Timer | -| 2 Watch dog | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * To start and stop the timer + * + * data[0] = 1 (start) + * = 0 (stop) + * = 2 (write new value) + * data[1] = new value + * + * devpriv->b_Timer2Mode = 0 DISABLE + * = 1 Timer + * = 2 Watch dog + */ +static int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; @@ -2217,30 +1941,17 @@ int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice } /* -+----------------------------------------------------------------------------+ -| Function name : int i_APCI3120_InsnReadTimer(struct comedi_device *dev, | -| struct comedi_subdevice *s,struct comedi_insn *insn, unsigned int *data) | -| | -| | -+----------------------------------------------------------------------------+ -| Task : read the Timer value | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -| | -+----------------------------------------------------------------------------+ -| Return Value : | -| for Timer: data[0]= Timer constant | -| | -| for watchdog: data[0]=0 (still running) | -| data[0]=1 (run down) | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Read the Timer value + * + * for Timer: data[0]= Timer constant + * + * for watchdog: data[0] = 0 (still running) + * = 1 (run down) + */ +static int i_APCI3120_InsnReadTimer(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned char b_Tmp; @@ -2288,35 +1999,12 @@ int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice } /* -+----------------------------------------------------------------------------+ -| DIGITAL INPUT SUBDEVICE | -+----------------------------------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, | -| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) | -| | -| | -+----------------------------------------------------------------------------+ -| Task : Reads the value of the specified Digital input channel| -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) + * Reads the value of the specified Digital input channel + */ +static int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Chan, ui_TmpValue; @@ -2342,26 +2030,13 @@ int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, } /* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, | -|struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Reads the value of the Digital input Port i.e.4channels| -| value is returned in data[0] | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ -int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Reads the value of the Digital input Port i.e.4channels + * value is returned in data[0] + */ +static int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue; @@ -2378,31 +2053,12 @@ int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_sub } /* -+----------------------------------------------------------------------------+ -| DIGITAL OUTPUT SUBDEVICE | -+----------------------------------------------------------------------------+ -*/ -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device | -| *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task :Configure the output memory ON or OFF | -| | -+----------------------------------------------------------------------------+ -| Input Parameters :struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) + * Configure the output memory ON or OFF + */ +static int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -2426,31 +2082,16 @@ int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev, } /* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, | -| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : write diatal output port | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -| data[0] Value to be written -| data[1] :1 Set digital o/p ON -| data[1] 2 Set digital o/p OFF with memory ON -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) + * Write diatal output port + * + * data[0] = Value to be written + * data[1] = 1 Set digital o/p ON + * = 2 Set digital o/p OFF with memory ON + */ +static int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -2481,31 +2122,16 @@ int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, } /* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,| -|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Write digiatl output | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | - data[0] Value to be written - data[1] :1 Set digital o/p ON - data[1] 2 Set digital o/p OFF with memory ON -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) + * Write digital output + * + * data[0] = Value to be written + * data[1] = 1 Set digital o/p ON + * = 2 Set digital o/p OFF with memory ON + */ +static int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp1; @@ -2555,35 +2181,11 @@ int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, } -/* -+----------------------------------------------------------------------------+ -| ANALOG OUTPUT SUBDEVICE | -+----------------------------------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,| -|struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Write analog output | -| | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev | -| struct comedi_subdevice *s | -| struct comedi_insn *insn | -| unsigned int *data | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +#ifdef CONFIG_APCI_3120 +static int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Range, ui_Channel; @@ -2638,3 +2240,4 @@ int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, return insn->n; } +#endif diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h index 0cd1e3d867d..c3b270c95d7 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h @@ -174,75 +174,3 @@ struct str_AnalogReadInformation { unsigned int ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; /* Gain of each channel */ }; - - -/* Function Declaration For APCI-3120 */ - -/* Internal functions */ -int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevice *s, - int n_chan, unsigned int *chanlist, char check); -int i_APCI3120_ExttrigEnable(struct comedi_device *dev); -int i_APCI3120_ExttrigDisable(struct comedi_device *dev); -int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s); -int i_APCI3120_Reset(struct comedi_device *dev); -int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev, - struct comedi_subdevice *s); -/* Interrupt functions */ -void v_APCI3120_Interrupt(int irq, void *d); -/* UPDATE-0.7.57->0.7.68 void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,struct comedi_subdevice *s,short *dma,short *data,int n); */ -void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev, - struct comedi_subdevice *s, - short *dma_buffer, - unsigned int num_samples); -int i_APCI3120_InterruptHandleEos(struct comedi_device *dev); -void v_APCI3120_InterruptDma(int irq, void *d); - -/* TIMER */ - -int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* -* DI for di read -*/ - -int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* DO */ -/* int i_APCI3120_WriteDigitalOutput(struct comedi_device *dev, - * unsigned char data); - */ -int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* AO */ -/* int i_APCI3120_Write1AnalogValue(struct comedi_device *dev,UINT ui_Range, - * UINT ui_Channel,UINT data ); - */ - -int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* AI HArdware layer */ - -int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); -int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s); -/* int i_APCI3120_CancelAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s); */ -int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s); -- cgit v1.2.3 From 0d0c706d46451023196bc9f293aa715627ff5276 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:59:35 -0700 Subject: staging: comedi: hwrdv_apci3120: absorb private header The header file hwdrv_apci3120.h is only included by the source file hwrdv_apci3120.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 168 +++++++++++++++++++- .../comedi/drivers/addi-data/hwdrv_apci3120.h | 176 --------------------- 2 files changed, 167 insertions(+), 177 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 573297830d4..a60d8dc6441 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -44,7 +44,173 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -#include "hwdrv_apci3120.h" +/* used for test on mixture of BIP/UNI ranges */ +#define APCI3120_BIPOLAR_RANGES 4 + +#define APCI3120_ADDRESS_RANGE 16 + +#define APCI3120_DISABLE 0 +#define APCI3120_ENABLE 1 + +#define APCI3120_START 1 +#define APCI3120_STOP 0 + +#define APCI3120_EOC_MODE 1 +#define APCI3120_EOS_MODE 2 +#define APCI3120_DMA_MODE 3 + +/* DIGITAL INPUT-OUTPUT DEFINE */ + +#define APCI3120_DIGITAL_OUTPUT 0x0d +#define APCI3120_RD_STATUS 0x02 +#define APCI3120_RD_FIFO 0x00 + +/* digital output insn_write ON /OFF selection */ +#define APCI3120_SET4DIGITALOUTPUTON 1 +#define APCI3120_SET4DIGITALOUTPUTOFF 0 + +/* analog output SELECT BIT */ +#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000 +#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000 +#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000 +#define APCI3120_ANALOG_OP_CHANNEL_4 0xc000 +#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000 +#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000 +#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000 +#define APCI3120_ANALOG_OP_CHANNEL_8 0xc000 + +/* Enable external trigger bit in nWrAddress */ +#define APCI3120_ENABLE_EXT_TRIGGER 0x8000 + +/* ANALOG OUTPUT AND INPUT DEFINE */ +#define APCI3120_UNIPOLAR 0x80 +#define APCI3120_BIPOLAR 0x00 +#define APCI3120_ANALOG_OUTPUT_1 0x08 +#define APCI3120_ANALOG_OUTPUT_2 0x0a +#define APCI3120_1_GAIN 0x00 +#define APCI3120_2_GAIN 0x10 +#define APCI3120_5_GAIN 0x20 +#define APCI3120_10_GAIN 0x30 +#define APCI3120_SEQ_RAM_ADDRESS 0x06 +#define APCI3120_RESET_FIFO 0x0c +#define APCI3120_TIMER_0_MODE_2 0x01 +#define APCI3120_TIMER_0_MODE_4 0x2 +#define APCI3120_SELECT_TIMER_0_WORD 0x00 +#define APCI3120_ENABLE_TIMER0 0x1000 +#define APCI3120_CLEAR_PR 0xf0ff +#define APCI3120_CLEAR_PA 0xfff0 +#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA) + +/* nWrMode_Select */ +#define APCI3120_ENABLE_SCAN 0x8 +#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN) +#define APCI3120_ENABLE_EOS_INT 0x2 + +#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT) +#define APCI3120_ENABLE_EOC_INT 0x1 +#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT) +#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER \ + (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) +#define APCI3120_DISABLE_ALL_INTERRUPT \ + (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) + +/* status register bits */ +#define APCI3120_EOC 0x8000 +#define APCI3120_EOS 0x2000 + +/* software trigger dummy register */ +#define APCI3120_START_CONVERSION 0x02 + +/* TIMER DEFINE */ +#define APCI3120_QUARTZ_A 70 +#define APCI3120_QUARTZ_B 50 +#define APCI3120_TIMER 1 +#define APCI3120_WATCHDOG 2 +#define APCI3120_TIMER_DISABLE 0 +#define APCI3120_TIMER_ENABLE 1 +#define APCI3120_ENABLE_TIMER2 0x4000 +#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2) +#define APCI3120_ENABLE_TIMER_INT 0x04 +#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT) +#define APCI3120_WRITE_MODE_SELECT 0x0e +#define APCI3120_SELECT_TIMER_0_WORD 0x00 +#define APCI3120_SELECT_TIMER_1_WORD 0x01 +#define APCI3120_TIMER_1_MODE_2 0x4 + +/* $$ BIT FOR MODE IN nCsTimerCtr1 */ +#define APCI3120_TIMER_2_MODE_0 0x0 +#define APCI3120_TIMER_2_MODE_2 0x10 +#define APCI3120_TIMER_2_MODE_5 0x30 + +/* $$ BIT FOR MODE IN nCsTimerCtr0 */ +#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02 +#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03 + +#define APCI3120_TIMER_CRT0 0x0d +#define APCI3120_TIMER_CRT1 0x0c + +#define APCI3120_TIMER_VALUE 0x04 +#define APCI3120_TIMER_STATUS_REGISTER 0x0d +#define APCI3120_RD_STATUS 0x02 +#define APCI3120_WR_ADDRESS 0x00 +#define APCI3120_ENABLE_WATCHDOG 0x20 +#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG) +#define APCI3120_ENABLE_TIMER_COUNTER 0x10 +#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER) +#define APCI3120_FC_TIMER 0x1000 +#define APCI3120_ENABLE_TIMER0 0x1000 +#define APCI3120_ENABLE_TIMER1 0x2000 +#define APCI3120_ENABLE_TIMER2 0x4000 +#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0) +#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1) +#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2) + +#define APCI3120_TIMER2_SELECT_EOS 0xc0 +#define APCI3120_COUNTER 3 +#define APCI3120_DISABLE_ALL_TIMER (APCI3120_DISABLE_TIMER0 & \ + APCI3120_DISABLE_TIMER1 & \ + APCI3120_DISABLE_TIMER2) + +#define MAX_ANALOGINPUT_CHANNELS 32 + +struct str_AnalogReadInformation { + /* EOC or EOS */ + unsigned char b_Type; + /* Interrupt use or not */ + unsigned char b_InterruptFlag; + /* Selection of the conversion time */ + unsigned int ui_ConvertTiming; + /* Number of channel to read */ + unsigned char b_NbrOfChannel; + /* Number of the channel to be read */ + unsigned int ui_ChannelList[MAX_ANALOGINPUT_CHANNELS]; + /* Gain of each channel */ + unsigned int ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; +}; + +/* ANALOG INPUT RANGE */ +static const struct comedi_lrange range_apci3120_ai = { + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1) + } +}; + +/* ANALOG OUTPUT RANGE */ +static const struct comedi_lrange range_apci3120_ao = { + 2, { + BIP_RANGE(10), + UNI_RANGE(10) + } +}; + + static unsigned int ui_Temp; /* FUNCTION DEFINITIONS */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h deleted file mode 100644 index c3b270c95d7..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h +++ /dev/null @@ -1,176 +0,0 @@ - -/* hwdrv_apci3120.h */ - -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ - -/* comedi related defines */ - -/* ANALOG INPUT RANGE */ -static const struct comedi_lrange range_apci3120_ai = { 8, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - -/* ANALOG OUTPUT RANGE */ -static const struct comedi_lrange range_apci3120_ao = { 2, { - BIP_RANGE(10), - UNI_RANGE(10) - } -}; - -#define APCI3120_BIPOLAR_RANGES 4 /* used for test on mixture of BIP/UNI ranges */ - -#define APCI3120_ADDRESS_RANGE 16 - -#define APCI3120_DISABLE 0 -#define APCI3120_ENABLE 1 - -#define APCI3120_START 1 -#define APCI3120_STOP 0 - -#define APCI3120_EOC_MODE 1 -#define APCI3120_EOS_MODE 2 -#define APCI3120_DMA_MODE 3 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI3120_DIGITAL_OUTPUT 0x0D -#define APCI3120_RD_STATUS 0x02 -#define APCI3120_RD_FIFO 0x00 - -/* digital output insn_write ON /OFF selection */ -#define APCI3120_SET4DIGITALOUTPUTON 1 -#define APCI3120_SET4DIGITALOUTPUTOFF 0 - -/* analog output SELECT BIT */ -#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000 -#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000 -#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000 -#define APCI3120_ANALOG_OP_CHANNEL_4 0xC000 -#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000 -#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000 -#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000 -#define APCI3120_ANALOG_OP_CHANNEL_8 0xC000 - -/* Enable external trigger bit in nWrAddress */ -#define APCI3120_ENABLE_EXT_TRIGGER 0x8000 - -/* ANALOG OUTPUT AND INPUT DEFINE */ -#define APCI3120_UNIPOLAR 0x80 /* $$ RAM sequence polarity BIT */ -#define APCI3120_BIPOLAR 0x00 /* $$ RAM sequence polarity BIT */ -#define APCI3120_ANALOG_OUTPUT_1 0x08 /* (ADDRESS ) */ -#define APCI3120_ANALOG_OUTPUT_2 0x0A /* (ADDRESS ) */ -#define APCI3120_1_GAIN 0x00 /* $$ RAM sequence Gain Bits for gain 1 */ -#define APCI3120_2_GAIN 0x10 /* $$ RAM sequence Gain Bits for gain 2 */ -#define APCI3120_5_GAIN 0x20 /* $$ RAM sequence Gain Bits for gain 5 */ -#define APCI3120_10_GAIN 0x30 /* $$ RAM sequence Gain Bits for gain 10 */ -#define APCI3120_SEQ_RAM_ADDRESS 0x06 /* $$ EARLIER NAMED APCI3120_FIFO_ADDRESS */ -#define APCI3120_RESET_FIFO 0x0C /* (ADDRESS) */ -#define APCI3120_TIMER_0_MODE_2 0x01 /* $$ Bits for timer mode */ -#define APCI3120_TIMER_0_MODE_4 0x2 -#define APCI3120_SELECT_TIMER_0_WORD 0x00 -#define APCI3120_ENABLE_TIMER0 0x1000 /* $$Gatebit 0 in nWrAddress */ -#define APCI3120_CLEAR_PR 0xF0FF -#define APCI3120_CLEAR_PA 0xFFF0 -#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA) - -/* nWrMode_Select */ -#define APCI3120_ENABLE_SCAN 0x8 /* $$ bit in nWrMode_Select */ -#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN) -#define APCI3120_ENABLE_EOS_INT 0x2 /* $$ bit in nWrMode_Select */ - -#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT) -#define APCI3120_ENABLE_EOC_INT 0x1 -#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT) -#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) -#define APCI3120_DISABLE_ALL_INTERRUPT (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT) - -/* status register bits */ -#define APCI3120_EOC 0x8000 -#define APCI3120_EOS 0x2000 - -/* software trigger dummy register */ -#define APCI3120_START_CONVERSION 0x02 /* (ADDRESS) */ - -/* TIMER DEFINE */ -#define APCI3120_QUARTZ_A 70 -#define APCI3120_QUARTZ_B 50 -#define APCI3120_TIMER 1 -#define APCI3120_WATCHDOG 2 -#define APCI3120_TIMER_DISABLE 0 -#define APCI3120_TIMER_ENABLE 1 -#define APCI3120_ENABLE_TIMER2 0x4000 /* $$ gatebit 2 in nWrAddress */ -#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2) -#define APCI3120_ENABLE_TIMER_INT 0x04 /* $$ ENAIRQ_FC_Bit in nWrModeSelect */ -#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT) -#define APCI3120_WRITE_MODE_SELECT 0x0E /* (ADDRESS) */ -#define APCI3120_SELECT_TIMER_0_WORD 0x00 -#define APCI3120_SELECT_TIMER_1_WORD 0x01 -#define APCI3120_TIMER_1_MODE_2 0x4 - -/* $$ BIT FOR MODE IN nCsTimerCtr1 */ -#define APCI3120_TIMER_2_MODE_0 0x0 -#define APCI3120_TIMER_2_MODE_2 0x10 -#define APCI3120_TIMER_2_MODE_5 0x30 - -/* $$ BIT FOR MODE IN nCsTimerCtr0 */ -#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02 -#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03 - -#define APCI3120_TIMER_CRT0 0x0D /* (ADDRESS for cCsTimerCtr0) */ -#define APCI3120_TIMER_CRT1 0x0C /* (ADDRESS for cCsTimerCtr1) */ - -#define APCI3120_TIMER_VALUE 0x04 /* ADDRESS for nCsTimerWert */ -#define APCI3120_TIMER_STATUS_REGISTER 0x0D /* ADDRESS for delete timer 2 interrupt */ -#define APCI3120_RD_STATUS 0x02 /* ADDRESS */ -#define APCI3120_WR_ADDRESS 0x00 /* ADDRESS */ -#define APCI3120_ENABLE_WATCHDOG 0x20 /* $$BIT in nWrMode_Select */ -#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG) -#define APCI3120_ENABLE_TIMER_COUNTER 0x10 /* $$BIT in nWrMode_Select */ -#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER) -#define APCI3120_FC_TIMER 0x1000 /* bit in status register */ -#define APCI3120_ENABLE_TIMER0 0x1000 -#define APCI3120_ENABLE_TIMER1 0x2000 -#define APCI3120_ENABLE_TIMER2 0x4000 -#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0) -#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1) -#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2) - -#define APCI3120_TIMER2_SELECT_EOS 0xC0 /* ADDED on 20-6 */ -#define APCI3120_COUNTER 3 /* on 20-6 */ -#define APCI3120_DISABLE_ALL_TIMER (APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1 & APCI3120_DISABLE_TIMER2) /* on 20-6 */ - -#define MAX_ANALOGINPUT_CHANNELS 32 - -struct str_AnalogReadInformation { - - unsigned char b_Type; /* EOC or EOS */ - unsigned char b_InterruptFlag; /* Interrupt use or not */ - unsigned int ui_ConvertTiming; /* Selection of the conversion time */ - unsigned char b_NbrOfChannel; /* Number of channel to read */ - unsigned int ui_ChannelList[MAX_ANALOGINPUT_CHANNELS]; /* Number of the channel to be read */ - unsigned int ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; /* Gain of each channel */ - -}; -- cgit v1.2.3 From fcea74fe31d838e2320160a741d9c135f6934368 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 16:59:49 -0700 Subject: staging: comedi: APCI1710_Ttl: absorb private header The header file APCI1710_Ttl.h is only included by the source file APCI1710_Ttl.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Ttl.c | 10 ++++------ .../comedi/drivers/addi-data/APCI1710_Ttl.h | 22 ---------------------- 2 files changed, 4 insertions(+), 28 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c index 3bf6929c218..c8238b8921c 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c @@ -52,13 +52,11 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ +#define APCI1710_TTL_INIT 0 +#define APCI1710_TTL_INITDIRECTION 1 -#include "APCI1710_Ttl.h" +#define APCI1710_TTL_READCHANNEL 0 +#define APCI1710_TTL_READPORT 1 /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h deleted file mode 100644 index 2f6a39213b0..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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 APCI1710_TTL_INIT 0 -#define APCI1710_TTL_INITDIRECTION 1 - -#define APCI1710_TTL_READCHANNEL 0 -#define APCI1710_TTL_READPORT 1 -- cgit v1.2.3 From b629be25caba04c6ec57ee79dca99ba23ffd9a61 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:00:07 -0700 Subject: staging: comedi: APCI1710_Tor: absorb private header The header file APCI1710_Tor.h is only included by the source file APCI1710_Tor.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Tor.c | 21 ++++++++++---- .../comedi/drivers/addi-data/APCI1710_Tor.h | 33 ---------------------- 2 files changed, 15 insertions(+), 39 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c index 3594a0487f7..3bc9826ce40 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c @@ -52,13 +52,22 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ +#define APCI1710_30MHZ 30 +#define APCI1710_33MHZ 33 +#define APCI1710_40MHZ 40 + +#define APCI1710_GATE_INPUT 10 + +#define APCI1710_TOR_SIMPLE_MODE 2 +#define APCI1710_TOR_DOUBLE_MODE 3 +#define APCI1710_TOR_QUADRUPLE_MODE 4 + +#define APCI1710_SINGLE 0 +#define APCI1710_CONTINUOUS 1 -#include "APCI1710_Tor.h" +#define APCI1710_TOR_GETPROGRESSSTATUS 0 +#define APCI1710_TOR_GETCOUNTERVALUE 1 +#define APCI1710_TOR_READINTERRUPT 2 /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h deleted file mode 100644 index c6eb9d1ad3c..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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 APCI1710_30MHZ 30 -#define APCI1710_33MHZ 33 -#define APCI1710_40MHZ 40 - -#define APCI1710_GATE_INPUT 10 - -#define APCI1710_TOR_SIMPLE_MODE 2 -#define APCI1710_TOR_DOUBLE_MODE 3 -#define APCI1710_TOR_QUADRUPLE_MODE 4 - -#define APCI1710_SINGLE 0 -#define APCI1710_CONTINUOUS 1 - -#define APCI1710_TOR_GETPROGRESSSTATUS 0 -#define APCI1710_TOR_GETCOUNTERVALUE 1 -#define APCI1710_TOR_READINTERRUPT 2 -- cgit v1.2.3 From e595e926fa892902eff3e189caa6fe5a21e5c69d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:00:21 -0700 Subject: staging: comedi: APCI1710_Ssi: absorb private header The header file APCI1710_Ssi.h is only included by the source file APCI1710_Ssi.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Ssi.c | 19 ++++++++----- .../comedi/drivers/addi-data/APCI1710_Ssi.h | 31 ---------------------- 2 files changed, 13 insertions(+), 37 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c index 00f8dc38186..1e05732e9f3 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c @@ -40,13 +40,20 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ +#define APCI1710_30MHZ 30 +#define APCI1710_33MHZ 33 +#define APCI1710_40MHZ 40 + +#define APCI1710_BINARY_MODE 0x1 +#define APCI1710_GRAY_MODE 0x0 + +#define APCI1710_SSI_READ1VALUE 1 +#define APCI1710_SSI_READALLVALUE 2 -#include "APCI1710_Ssi.h" +#define APCI1710_SSI_SET_CHANNELON 0 +#define APCI1710_SSI_SET_CHANNELOFF 1 +#define APCI1710_SSI_READ_1CHANNEL 2 +#define APCI1710_SSI_READ_ALLCHANNEL 3 /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h deleted file mode 100644 index c4f6565aa31..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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 APCI1710_30MHZ 30 -#define APCI1710_33MHZ 33 -#define APCI1710_40MHZ 40 - -#define APCI1710_BINARY_MODE 0x1 -#define APCI1710_GRAY_MODE 0x0 - -#define APCI1710_SSI_READ1VALUE 1 -#define APCI1710_SSI_READALLVALUE 2 - -#define APCI1710_SSI_SET_CHANNELON 0 -#define APCI1710_SSI_SET_CHANNELOFF 1 -#define APCI1710_SSI_READ_1CHANNEL 2 -#define APCI1710_SSI_READ_ALLCHANNEL 3 -- cgit v1.2.3 From ce114dc0227df6fad77764bf19e50a0e5de20a04 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:00:38 -0700 Subject: staging: comedi: APCI1710_Inp_cpt: absorb private header The header file APCI1710_Inp_cpt.h is only included by the source file APCI1710_Inp_cpt.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Inp_cpt.c | 10 ++++------ .../comedi/drivers/addi-data/APCI1710_Inp_cpt.h | 22 ---------------------- 2 files changed, 4 insertions(+), 28 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c index c892d0c569e..be0c6adbdc9 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c @@ -49,13 +49,11 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ +#define APCI1710_SINGLE 0 +#define APCI1710_CONTINUOUS 1 -#include "APCI1710_Inp_cpt.h" +#define APCI1710_PULSEENCODER_READ 0 +#define APCI1710_PULSEENCODER_WRITE 1 /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h deleted file mode 100644 index c8b90b4103f..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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 APCI1710_SINGLE 0 -#define APCI1710_CONTINUOUS 1 - -#define APCI1710_PULSEENCODER_READ 0 -#define APCI1710_PULSEENCODER_WRITE 1 -- cgit v1.2.3 From 86bb50385e962a38ef37fca1cd493b5278cb5085 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:00:54 -0700 Subject: staging: comedi: APCI1710_Dig_io: absorb private header The header file APCI1710_Dig_io.h is only included by the source file APCI1710_Dig_io.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Dig_io.c | 16 ++++++++------ .../comedi/drivers/addi-data/APCI1710_Dig_io.h | 25 ---------------------- 2 files changed, 10 insertions(+), 31 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c index aa4122e618b..6b38ce7a275 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c @@ -52,12 +52,16 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "APCI1710_Dig_io.h" +/* Digital Output ON or OFF */ +#define APCI1710_ON 1 +#define APCI1710_OFF 0 + +/* Digital I/O */ +#define APCI1710_INPUT 0 +#define APCI1710_OUTPUT 1 + +#define APCI1710_DIGIO_MEMORYONOFF 0x10 +#define APCI1710_DIGIO_INIT 0x11 /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h deleted file mode 100644 index 078380880de..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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 APCI1710_ON 1 /* Digital Output ON or OFF */ -#define APCI1710_OFF 0 - -#define APCI1710_INPUT 0 /* Digital I/O */ -#define APCI1710_OUTPUT 1 - -#define APCI1710_DIGIO_MEMORYONOFF 0x10 -#define APCI1710_DIGIO_INIT 0x11 -- cgit v1.2.3 From a3e7f885c93266c34b60550eb9f14797fb44ab43 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:01:13 -0700 Subject: staging: comedi: APCI1710_82x54: remove forward declarations This source file is #include'd when building the addi_apci_1710 driver. All the functions in this file are actually static and should not be exported to the kernel. Move some of the functions to remove the need for the forward declarations and make all of the functions in this file static. Note, this patch does not try to fix any of the coding style issues in the functions. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_82x54.c | 183 +++++++++++---------- .../comedi/drivers/addi-data/APCI1710_82x54.h | 41 ----- 2 files changed, 93 insertions(+), 131 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c index 8656d0ef2c8..64d286d3cd9 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c @@ -218,9 +218,10 @@ int i_InsnConfig_InitTimer(struct comedi_device *dev,struct comedi_subdevice *s, | -9: Selection from hardware gate level is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -447,10 +448,10 @@ i_ReturnValue=insn->n; | See function "i_APCI1710_SetBoardIntRoutineX" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -590,9 +591,10 @@ int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,struct comedi_sub | "i_APCI1710_InitTimer" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -668,70 +670,6 @@ int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_su return i_ReturnValue; } -/* -+----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev, -struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read write functions for Timer | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned char b_BitsType; - int i_ReturnValue = 0; - b_BitsType = data[0]; - - printk("\n82X54"); - - switch (b_BitsType) { - case APCI1710_TIMER_READVALUE: - i_ReturnValue = i_APCI1710_ReadTimerValue(dev, - (unsigned char)CR_AREF(insn->chanspec), - (unsigned char)CR_CHAN(insn->chanspec), - (unsigned int *) &data[0]); - break; - - case APCI1710_TIMER_GETOUTPUTLEVEL: - i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev, - (unsigned char)CR_AREF(insn->chanspec), - (unsigned char)CR_CHAN(insn->chanspec), - (unsigned char *) &data[0]); - break; - - case APCI1710_TIMER_GETPROGRESSSTATUS: - i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev, - (unsigned char)CR_AREF(insn->chanspec), - (unsigned char)CR_CHAN(insn->chanspec), - (unsigned char *)&data[0]); - break; - - case APCI1710_TIMER_WRITEVALUE: - i_ReturnValue = i_APCI1710_WriteTimerValue(dev, - (unsigned char)CR_AREF(insn->chanspec), - (unsigned char)CR_CHAN(insn->chanspec), - (unsigned int)data[1]); - - break; - - default: - printk("Bits Config Parameter Wrong\n"); - i_ReturnValue = -1; - } - - if (i_ReturnValue >= 0) - i_ReturnValue = insn->n; - return i_ReturnValue; -} - /* +----------------------------------------------------------------------------+ | Function Name : _INT_ i_APCI1710_ReadTimerValue | @@ -761,10 +699,10 @@ int i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice | "i_APCI1710_InitTimer" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ReadTimerValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned int *pul_TimerValue) +static int i_APCI1710_ReadTimerValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_TimerNbr, + unsigned int *pul_TimerValue) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -850,10 +788,10 @@ int i_APCI1710_ReadTimerValue(struct comedi_device *dev, | "i_APCI1710_InitTimer" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned char *pb_OutputLevel) +static int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_TimerNbr, + unsigned char *pb_OutputLevel) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -930,10 +868,10 @@ int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev, | "i_APCI1710_InitTimer" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned char *pb_TimerStatus) +static int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_TimerNbr, + unsigned char *pb_TimerStatus) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1010,10 +948,10 @@ int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev, | "i_APCI1710_InitTimer" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_WriteTimerValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned int ul_WriteValue) +static int i_APCI1710_WriteTimerValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_TimerNbr, + unsigned int ul_WriteValue) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1051,3 +989,68 @@ int i_APCI1710_WriteTimerValue(struct comedi_device *dev, return i_ReturnValue; } + +/* ++----------------------------------------------------------------------------+ +| Function Name :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev, +struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | ++----------------------------------------------------------------------------+ +| Task : Read write functions for Timer | ++----------------------------------------------------------------------------+ +| Input Parameters : ++----------------------------------------------------------------------------+ +| Output Parameters : - | ++----------------------------------------------------------------------------+ +| Return Value : ++----------------------------------------------------------------------------+ +*/ +static int i_APCI1710_InsnBitsTimer(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned char b_BitsType; + int i_ReturnValue = 0; + b_BitsType = data[0]; + + printk("\n82X54"); + + switch (b_BitsType) { + case APCI1710_TIMER_READVALUE: + i_ReturnValue = i_APCI1710_ReadTimerValue(dev, + (unsigned char)CR_AREF(insn->chanspec), + (unsigned char)CR_CHAN(insn->chanspec), + (unsigned int *) &data[0]); + break; + + case APCI1710_TIMER_GETOUTPUTLEVEL: + i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev, + (unsigned char)CR_AREF(insn->chanspec), + (unsigned char)CR_CHAN(insn->chanspec), + (unsigned char *) &data[0]); + break; + + case APCI1710_TIMER_GETPROGRESSSTATUS: + i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev, + (unsigned char)CR_AREF(insn->chanspec), + (unsigned char)CR_CHAN(insn->chanspec), + (unsigned char *)&data[0]); + break; + + case APCI1710_TIMER_WRITEVALUE: + i_ReturnValue = i_APCI1710_WriteTimerValue(dev, + (unsigned char)CR_AREF(insn->chanspec), + (unsigned char)CR_CHAN(insn->chanspec), + (unsigned int)data[1]); + + break; + + default: + printk("Bits Config Parameter Wrong\n"); + i_ReturnValue = -1; + } + + if (i_ReturnValue >= 0) + i_ReturnValue = insn->n; + return i_ReturnValue; +} diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h index 81346dbc35f..85a70f32362 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h @@ -30,44 +30,3 @@ #define APCI1710_10MHZ 10 #endif /* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */ - -/* - * 82X54 TIMER INISIALISATION FUNCTION - */ -int i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * 82X54 READ FUNCTION - */ -int i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -/* - * 82X54 READ & WRITE FUNCTION - */ -int i_APCI1710_ReadTimerValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned int *pul_TimerValue); - -int i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned char *pb_OutputLevel); - -int i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned char *pb_TimerStatus); - -/* - * 82X54 WRITE FUNCTION - */ -int i_APCI1710_WriteTimerValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_TimerNbr, - unsigned int ul_WriteValue); -- cgit v1.2.3 From f1975596f50d6b35ce2de41b04bd971117241519 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:01:28 -0700 Subject: staging: comedi: APCI1710_82x54: absorb private header The header file APCI1710_82x54.h is only included by the source file APCI1710_82x54.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_82x54.c | 14 +++++++++- .../comedi/drivers/addi-data/APCI1710_82x54.h | 32 ---------------------- 2 files changed, 13 insertions(+), 33 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c index 64d286d3cd9..d0702084caa 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c @@ -18,7 +18,19 @@ | Description : APCI-1710 82X54 timer module | */ -#include "APCI1710_82x54.h" +#define APCI1710_PCI_BUS_CLOCK 0 +#define APCI1710_FRONT_CONNECTOR_INPUT 1 +#define APCI1710_TIMER_READVALUE 0 +#define APCI1710_TIMER_GETOUTPUTLEVEL 1 +#define APCI1710_TIMER_GETPROGRESSSTATUS 2 +#define APCI1710_TIMER_WRITEVALUE 3 + +#define APCI1710_TIMER_READINTERRUPT 1 +#define APCI1710_TIMER_READALLTIMER 2 + +#ifndef APCI1710_10MHZ +#define APCI1710_10MHZ 10 +#endif /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h deleted file mode 100644 index 85a70f32362..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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 APCI1710_PCI_BUS_CLOCK 0 -#define APCI1710_FRONT_CONNECTOR_INPUT 1 -#define APCI1710_TIMER_READVALUE 0 -#define APCI1710_TIMER_GETOUTPUTLEVEL 1 -#define APCI1710_TIMER_GETPROGRESSSTATUS 2 -#define APCI1710_TIMER_WRITEVALUE 3 - -#define APCI1710_TIMER_READINTERRUPT 1 -#define APCI1710_TIMER_READALLTIMER 2 - -/* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */ -#ifndef APCI1710_10MHZ -#define APCI1710_10MHZ 10 -#endif -/* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */ -- cgit v1.2.3 From 924cd1cb9109d5f762926e8d37538acb9c2c9e69 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:01:46 -0700 Subject: staging: comedi: APCI1710_Chrono: remove forward declarations This source file is #include'd when building the addi_apci_1710 driver. All the functions in this file are actually static and should not be exported to the kernel. Move some of the functions to remove the need for the forward declarations and make all of the functions in this file static. Note, this patch does not try to fix any of the coding style issues in the functions. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Chrono.c | 218 +++++++++++---------- .../comedi/drivers/addi-data/APCI1710_Chrono.h | 41 ---- 2 files changed, 112 insertions(+), 147 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c index a30fb0ddb74..cad1b2ca474 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c @@ -130,9 +130,10 @@ You should also find the complete GPL in the COPYING file accompanying this sour | this CHRONOS version | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -840,9 +841,10 @@ struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -8: data[0] wrong input | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1077,88 +1079,6 @@ int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev, return i_ReturnValue; } -/* -+----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s, -struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read functions for Timer | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned char b_ReadType; - int i_ReturnValue = insn->n; - - b_ReadType = CR_CHAN(insn->chanspec); - - switch (b_ReadType) { - case APCI1710_CHRONO_PROGRESS_STATUS: - i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); - break; - - case APCI1710_CHRONO_READVALUE: - i_ReturnValue = i_APCI1710_ReadChronoValue(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned int) insn->unused[0], - (unsigned char *) &data[0], (unsigned int *) &data[1]); - break; - - case APCI1710_CHRONO_CONVERTVALUE: - i_ReturnValue = i_APCI1710_ConvertChronoValue(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned int) insn->unused[0], - (unsigned int *) &data[0], - (unsigned char *) &data[1], - (unsigned char *) &data[2], - (unsigned int *) &data[3], - (unsigned int *) &data[4], (unsigned int *) &data[5]); - break; - - case APCI1710_CHRONO_READINTERRUPT: - printk("In Chrono Read Interrupt\n"); - - data[0] = devpriv->s_InterruptParameters. - s_FIFOInterruptParameters[devpriv-> - s_InterruptParameters.ui_Read].b_OldModuleMask; - data[1] = devpriv->s_InterruptParameters. - s_FIFOInterruptParameters[devpriv-> - s_InterruptParameters.ui_Read].ul_OldInterruptMask; - data[2] = devpriv->s_InterruptParameters. - s_FIFOInterruptParameters[devpriv-> - s_InterruptParameters.ui_Read].ul_OldCounterLatchValue; - - /**************************/ - /* Increment the read FIFO */ - /***************************/ - - devpriv-> - s_InterruptParameters. - ui_Read = (devpriv-> - s_InterruptParameters. - ui_Read + 1) % APCI1710_SAVE_INTERRUPT; - break; - - default: - printk("ReadType Parameter wrong\n"); - } - - if (i_ReturnValue >= 0) - i_ReturnValue = insn->n; - return i_ReturnValue; - -} - /* +----------------------------------------------------------------------------+ | Function Name : _INT_ i_APCI1710_GetChronoProgressStatus | @@ -1196,9 +1116,9 @@ int i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice | "i_APCI1710_InitChrono" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_ChronoStatus) +static int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_ChronoStatus) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1358,10 +1278,11 @@ int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev, | directly the chronometer measured timing. | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ReadChronoValue(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned int ui_TimeOut, unsigned char *pb_ChronoStatus, unsigned int *pul_ChronoValue) +static int i_APCI1710_ReadChronoValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned int ui_TimeOut, + unsigned char *pb_ChronoStatus, + unsigned int *pul_ChronoValue) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1622,14 +1543,15 @@ int i_APCI1710_ReadChronoValue(struct comedi_device *dev, | "i_APCI1710_InitChrono" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned int ul_ChronoValue, - unsigned int *pul_Hour, - unsigned char *pb_Minute, - unsigned char *pb_Second, - unsigned int *pui_MilliSecond, unsigned int *pui_MicroSecond, unsigned int *pui_NanoSecond) +static int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned int ul_ChronoValue, + unsigned int *pul_Hour, + unsigned char *pb_Minute, + unsigned char *pb_Second, + unsigned int *pui_MilliSecond, + unsigned int *pui_MicroSecond, + unsigned int *pui_NanoSecond) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1760,6 +1682,89 @@ int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, return i_ReturnValue; } +/* ++----------------------------------------------------------------------------+ +| Function Name :INT i_APCI1710_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s, +struct comedi_insn *insn,unsigned int *data) | ++----------------------------------------------------------------------------+ +| Task : Read functions for Timer | ++----------------------------------------------------------------------------+ +| Input Parameters : ++----------------------------------------------------------------------------+ +| Output Parameters : - | ++----------------------------------------------------------------------------+ +| Return Value : ++----------------------------------------------------------------------------+ +*/ +static int i_APCI1710_InsnReadChrono(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct addi_private *devpriv = dev->private; + unsigned char b_ReadType; + int i_ReturnValue = insn->n; + + b_ReadType = CR_CHAN(insn->chanspec); + + switch (b_ReadType) { + case APCI1710_CHRONO_PROGRESS_STATUS: + i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_CHRONO_READVALUE: + i_ReturnValue = i_APCI1710_ReadChronoValue(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned int) insn->unused[0], + (unsigned char *) &data[0], (unsigned int *) &data[1]); + break; + + case APCI1710_CHRONO_CONVERTVALUE: + i_ReturnValue = i_APCI1710_ConvertChronoValue(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned int) insn->unused[0], + (unsigned int *) &data[0], + (unsigned char *) &data[1], + (unsigned char *) &data[2], + (unsigned int *) &data[3], + (unsigned int *) &data[4], (unsigned int *) &data[5]); + break; + + case APCI1710_CHRONO_READINTERRUPT: + printk("In Chrono Read Interrupt\n"); + + data[0] = devpriv->s_InterruptParameters. + s_FIFOInterruptParameters[devpriv-> + s_InterruptParameters.ui_Read].b_OldModuleMask; + data[1] = devpriv->s_InterruptParameters. + s_FIFOInterruptParameters[devpriv-> + s_InterruptParameters.ui_Read].ul_OldInterruptMask; + data[2] = devpriv->s_InterruptParameters. + s_FIFOInterruptParameters[devpriv-> + s_InterruptParameters.ui_Read].ul_OldCounterLatchValue; + + /**************************/ + /* Increment the read FIFO */ + /***************************/ + + devpriv-> + s_InterruptParameters. + ui_Read = (devpriv-> + s_InterruptParameters. + ui_Read + 1) % APCI1710_SAVE_INTERRUPT; + break; + + default: + printk("ReadType Parameter wrong\n"); + } + + if (i_ReturnValue >= 0) + i_ReturnValue = insn->n; + return i_ReturnValue; + +} + /* +----------------------------------------------------------------------------+ | Function Name : int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,struct comedi_subdevice *s, @@ -1880,9 +1885,10 @@ int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, | "i_APCI1710_InitChrono" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h index 29bad1d144a..11a20d16171 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h @@ -31,44 +31,3 @@ #define APCI1710_CHRONO_SET_CHANNELOFF 1 #define APCI1710_CHRONO_READ_CHANNEL 2 #define APCI1710_CHRONO_READ_PORT 3 - -/* - * CHRONOMETER INISIALISATION FUNCTION - */ -int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data); - -/* - * CHRONOMETER READ FUNCTION - */ -int i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_ChronoStatus); - -int i_APCI1710_ReadChronoValue(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned int ui_TimeOut, unsigned char *pb_ChronoStatus, - unsigned int *pul_ChronoValue); - -int i_APCI1710_ConvertChronoValue(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned int ul_ChronoValue, - unsigned int *pul_Hour, - unsigned char *pb_Minute, - unsigned char *pb_Second, - unsigned int *pui_MilliSecond, unsigned int *pui_MicroSecond, - unsigned int *pui_NanoSecond); - -/* - * CHRONOMETER DIGITAL INPUT OUTPUT FUNCTION - */ -int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -- cgit v1.2.3 From efc87d0bc1604257136a9f322ca0b56cdaaf4996 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:02:05 -0700 Subject: staging: comedi: APCI1710_Chrono: absorb private header The header file APCI1710_Chrono.h is only included by the source file APCI1710_Chrono.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Chrono.c | 22 +++++++++++---- .../comedi/drivers/addi-data/APCI1710_Chrono.h | 33 ---------------------- 2 files changed, 16 insertions(+), 39 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c index cad1b2ca474..5bd7fe64637 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c @@ -52,12 +52,22 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ -#include "APCI1710_Chrono.h" +#define APCI1710_30MHZ 30 +#define APCI1710_33MHZ 33 +#define APCI1710_40MHZ 40 + +#define APCI1710_SINGLE 0 +#define APCI1710_CONTINUOUS 1 + +#define APCI1710_CHRONO_PROGRESS_STATUS 0 +#define APCI1710_CHRONO_READVALUE 1 +#define APCI1710_CHRONO_CONVERTVALUE 2 +#define APCI1710_CHRONO_READINTERRUPT 3 + +#define APCI1710_CHRONO_SET_CHANNELON 0 +#define APCI1710_CHRONO_SET_CHANNELOFF 1 +#define APCI1710_CHRONO_READ_CHANNEL 2 +#define APCI1710_CHRONO_READ_PORT 3 /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h deleted file mode 100644 index 11a20d16171..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data-com - * info@addi-data.com - * - * 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 APCI1710_30MHZ 30 -#define APCI1710_33MHZ 33 -#define APCI1710_40MHZ 40 - -#define APCI1710_SINGLE 0 -#define APCI1710_CONTINUOUS 1 - -#define APCI1710_CHRONO_PROGRESS_STATUS 0 -#define APCI1710_CHRONO_READVALUE 1 -#define APCI1710_CHRONO_CONVERTVALUE 2 -#define APCI1710_CHRONO_READINTERRUPT 3 - -#define APCI1710_CHRONO_SET_CHANNELON 0 -#define APCI1710_CHRONO_SET_CHANNELOFF 1 -#define APCI1710_CHRONO_READ_CHANNEL 2 -#define APCI1710_CHRONO_READ_PORT 3 -- cgit v1.2.3 From 4d1fa9bd7477dbfa77d61458cf311e2e494f3407 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:02:37 -0700 Subject: staging: comedi: APCI1710_INCCPT: remove forward declarations This source file is #include'd when building the addi_apci_1710 driver. All the functions in this file are actually static and should not be exported to the kernel. Move some of the functions to remove the need for the forward declarations and make all of the functions in this file static. Note, this patch does not try to fix any of the coding style issues in the functions. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_INCCPT.c | 726 ++++++++++----------- .../comedi/drivers/addi-data/APCI1710_INCCPT.h | 139 ---- 2 files changed, 339 insertions(+), 526 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c index 834685b1885..7c997f65d28 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c @@ -59,88 +59,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #include "APCI1710_INCCPT.h" -/* -+----------------------------------------------------------------------------+ -| int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev,struct comedi_subdevice *s, -struct comedi_insn *insn,unsigned int *data) - -+----------------------------------------------------------------------------+ -| Task : Configuration function for INC_CPT | -+----------------------------------------------------------------------------+ -| Input Parameters : | -+----------------------------------------------------------------------------+ -| Output Parameters : *data -+----------------------------------------------------------------------------+ -| Return Value : | -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_ConfigType; - int i_ReturnValue = 0; - - ui_ConfigType = CR_CHAN(insn->chanspec); - - printk("\nINC_CPT"); - - devpriv->tsk_Current = current; /* Save the current process task structure */ - switch (ui_ConfigType) { - case APCI1710_INCCPT_INITCOUNTER: - i_ReturnValue = i_APCI1710_InitCounter(dev, - CR_AREF(insn->chanspec), - (unsigned char) data[0], - (unsigned char) data[1], - (unsigned char) data[2], (unsigned char) data[3], (unsigned char) data[4]); - break; - - case APCI1710_INCCPT_COUNTERAUTOTEST: - i_ReturnValue = i_APCI1710_CounterAutoTest(dev, - (unsigned char *) &data[0]); - break; - - case APCI1710_INCCPT_INITINDEX: - i_ReturnValue = i_APCI1710_InitIndex(dev, - CR_AREF(insn->chanspec), - (unsigned char) data[0], - (unsigned char) data[1], (unsigned char) data[2], (unsigned char) data[3]); - break; - - case APCI1710_INCCPT_INITREFERENCE: - i_ReturnValue = i_APCI1710_InitReference(dev, - CR_AREF(insn->chanspec), (unsigned char) data[0]); - break; - - case APCI1710_INCCPT_INITEXTERNALSTROBE: - i_ReturnValue = i_APCI1710_InitExternalStrobe(dev, - CR_AREF(insn->chanspec), - (unsigned char) data[0], (unsigned char) data[1]); - break; - - case APCI1710_INCCPT_INITCOMPARELOGIC: - i_ReturnValue = i_APCI1710_InitCompareLogic(dev, - CR_AREF(insn->chanspec), (unsigned int) data[0]); - break; - - case APCI1710_INCCPT_INITFREQUENCYMEASUREMENT: - i_ReturnValue = i_APCI1710_InitFrequencyMeasurement(dev, - CR_AREF(insn->chanspec), - (unsigned char) data[0], - (unsigned char) data[1], (unsigned int) data[2], (unsigned int *) &data[0]); - break; - - default: - printk("Insn Config : Config Parameter Wrong\n"); - - } - - if (i_ReturnValue >= 0) - i_ReturnValue = insn->n; - return i_ReturnValue; -} - /* +----------------------------------------------------------------------------+ | Function Name : _INT_ i_APCI1710_InitCounter | @@ -300,13 +218,13 @@ int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevi | wrong. | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitCounter(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_CounterRange, - unsigned char b_FirstCounterModus, - unsigned char b_FirstCounterOption, - unsigned char b_SecondCounterModus, unsigned char b_SecondCounterOption) +static int i_APCI1710_InitCounter(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_CounterRange, + unsigned char b_FirstCounterModus, + unsigned char b_FirstCounterOption, + unsigned char b_SecondCounterModus, + unsigned char b_SecondCounterOption) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -547,8 +465,8 @@ int i_APCI1710_InitCounter(struct comedi_device *dev, | -2: No counter module found | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_CounterAutoTest(struct comedi_device *dev, unsigned char *pb_TestStatus) +static int i_APCI1710_CounterAutoTest(struct comedi_device *dev, + unsigned char *pb_TestStatus) { struct addi_private *devpriv = dev->private; unsigned char b_ModulCpt = 0; @@ -711,11 +629,12 @@ int i_APCI1710_CounterAutoTest(struct comedi_device *dev, unsigned char *pb_Test | See function "i_APCI1710_SetBoardIntRoutineX" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitIndex(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_ReferenceAction, - unsigned char b_IndexOperation, unsigned char b_AutoMode, unsigned char b_InterruptEnable) +static int i_APCI1710_InitIndex(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_ReferenceAction, + unsigned char b_IndexOperation, + unsigned char b_AutoMode, + unsigned char b_InterruptEnable) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1156,9 +1075,9 @@ int i_APCI1710_InitIndex(struct comedi_device *dev, | -4: Reference level parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitReference(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_ReferenceLevel) +static int i_APCI1710_InitReference(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_ReferenceLevel) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1282,9 +1201,10 @@ int i_APCI1710_InitReference(struct comedi_device *dev, | -5: External strobe level parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitExternalStrobe(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_ExternalStrobe, unsigned char b_ExternalStrobeLevel) +static int i_APCI1710_InitExternalStrobe(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_ExternalStrobe, + unsigned char b_ExternalStrobeLevel) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1397,9 +1317,9 @@ int i_APCI1710_InitExternalStrobe(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitCompareLogic(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned int ui_CompareValue) +static int i_APCI1710_InitCompareLogic(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned int ui_CompareValue) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1494,12 +1414,12 @@ int i_APCI1710_InitCompareLogic(struct comedi_device *dev, | -7: 40MHz quartz not on board | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PCIInputClock, - unsigned char b_TimingUnity, - unsigned int ul_TimingInterval, unsigned int *pul_RealTimingInterval) +static int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PCIInputClock, + unsigned char b_TimingUnity, + unsigned int ul_TimingInterval, + unsigned int *pul_RealTimingInterval) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -2004,74 +1924,70 @@ int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev, return i_ReturnValue; } -/*########################################################################### */ - - /* INSN BITS */ -/*########################################################################### */ - /* -+----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev,struct comedi_subdevice *s, -struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Set & Clear Functions for INC_CPT | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Configuration function for INC_CPT + */ +static int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_BitsType; + unsigned int ui_ConfigType; int i_ReturnValue = 0; - ui_BitsType = CR_CHAN(insn->chanspec); - devpriv->tsk_Current = current; /* Save the current process task structure */ + ui_ConfigType = CR_CHAN(insn->chanspec); - switch (ui_BitsType) { - case APCI1710_INCCPT_CLEARCOUNTERVALUE: - i_ReturnValue = i_APCI1710_ClearCounterValue(dev, - (unsigned char) CR_AREF(insn->chanspec)); + printk("\nINC_CPT"); + + devpriv->tsk_Current = current; /* Save the current process task structure */ + switch (ui_ConfigType) { + case APCI1710_INCCPT_INITCOUNTER: + i_ReturnValue = i_APCI1710_InitCounter(dev, + CR_AREF(insn->chanspec), + (unsigned char) data[0], + (unsigned char) data[1], + (unsigned char) data[2], (unsigned char) data[3], (unsigned char) data[4]); break; - case APCI1710_INCCPT_CLEARALLCOUNTERVALUE: - i_ReturnValue = i_APCI1710_ClearAllCounterValue(dev); + case APCI1710_INCCPT_COUNTERAUTOTEST: + i_ReturnValue = i_APCI1710_CounterAutoTest(dev, + (unsigned char *) &data[0]); break; - case APCI1710_INCCPT_SETINPUTFILTER: - i_ReturnValue = i_APCI1710_SetInputFilter(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) data[0], (unsigned char) data[1]); + case APCI1710_INCCPT_INITINDEX: + i_ReturnValue = i_APCI1710_InitIndex(dev, + CR_AREF(insn->chanspec), + (unsigned char) data[0], + (unsigned char) data[1], (unsigned char) data[2], (unsigned char) data[3]); break; - case APCI1710_INCCPT_LATCHCOUNTER: - i_ReturnValue = i_APCI1710_LatchCounter(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); + case APCI1710_INCCPT_INITREFERENCE: + i_ReturnValue = i_APCI1710_InitReference(dev, + CR_AREF(insn->chanspec), (unsigned char) data[0]); break; - case APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE: - i_ReturnValue = i_APCI1710_SetIndexAndReferenceSource(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); + case APCI1710_INCCPT_INITEXTERNALSTROBE: + i_ReturnValue = i_APCI1710_InitExternalStrobe(dev, + CR_AREF(insn->chanspec), + (unsigned char) data[0], (unsigned char) data[1]); break; - case APCI1710_INCCPT_SETDIGITALCHLON: - i_ReturnValue = i_APCI1710_SetDigitalChlOn(dev, - (unsigned char) CR_AREF(insn->chanspec)); + case APCI1710_INCCPT_INITCOMPARELOGIC: + i_ReturnValue = i_APCI1710_InitCompareLogic(dev, + CR_AREF(insn->chanspec), (unsigned int) data[0]); break; - case APCI1710_INCCPT_SETDIGITALCHLOFF: - i_ReturnValue = i_APCI1710_SetDigitalChlOff(dev, - (unsigned char) CR_AREF(insn->chanspec)); + case APCI1710_INCCPT_INITFREQUENCYMEASUREMENT: + i_ReturnValue = i_APCI1710_InitFrequencyMeasurement(dev, + CR_AREF(insn->chanspec), + (unsigned char) data[0], + (unsigned char) data[1], (unsigned int) data[2], (unsigned int *) &data[0]); break; default: - printk("Bits Config Parameter Wrong\n"); + printk("Insn Config : Config Parameter Wrong\n"); + } if (i_ReturnValue >= 0) @@ -2101,8 +2017,8 @@ int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ClearCounterValue(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_ClearCounterValue(struct comedi_device *dev, + unsigned char b_ModulNbr) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -2162,8 +2078,7 @@ int i_APCI1710_ClearCounterValue(struct comedi_device *dev, unsigned char b_Modu | -2: No counter module found | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev) +static int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; unsigned char b_ModulCpt = 0; @@ -2309,9 +2224,10 @@ int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev) | -6: 40MHz quartz not on board | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_SetInputFilter(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_PCIInputClock, unsigned char b_Filter) +static int i_APCI1710_SetInputFilter(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PCIInputClock, + unsigned char b_Filter) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -2574,9 +2490,9 @@ int i_APCI1710_SetInputFilter(struct comedi_device *dev, | -4: The selected latch register parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_LatchCounter(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_LatchReg) +static int i_APCI1710_LatchCounter(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_LatchReg) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -2672,9 +2588,9 @@ int i_APCI1710_LatchCounter(struct comedi_device *dev, | -4: The source selection is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_SourceSelection) +static int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_SourceSelection) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -2810,8 +2726,8 @@ int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, + unsigned char b_ModulNbr) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -2891,8 +2807,8 @@ int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, unsigned char b_ModulN | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, + unsigned char b_ModulNbr) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -2950,89 +2866,59 @@ int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, unsigned char b_Modul return i_ReturnValue; } -/*########################################################################### */ - - /* INSN WRITE */ -/*########################################################################### */ - /* -+----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,struct comedi_subdevice *s, -struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Enable Disable functions for INC_CPT | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ -int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Set & Clear Functions for INC_CPT + */ +static int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_WriteType; + unsigned int ui_BitsType; int i_ReturnValue = 0; - ui_WriteType = CR_CHAN(insn->chanspec); + ui_BitsType = CR_CHAN(insn->chanspec); devpriv->tsk_Current = current; /* Save the current process task structure */ - switch (ui_WriteType) { - case APCI1710_INCCPT_ENABLELATCHINTERRUPT: - i_ReturnValue = i_APCI1710_EnableLatchInterrupt(dev, + switch (ui_BitsType) { + case APCI1710_INCCPT_CLEARCOUNTERVALUE: + i_ReturnValue = i_APCI1710_ClearCounterValue(dev, (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_DISABLELATCHINTERRUPT: - i_ReturnValue = i_APCI1710_DisableLatchInterrupt(dev, - (unsigned char) CR_AREF(insn->chanspec)); + case APCI1710_INCCPT_CLEARALLCOUNTERVALUE: + i_ReturnValue = i_APCI1710_ClearAllCounterValue(dev); break; - case APCI1710_INCCPT_WRITE16BITCOUNTERVALUE: - i_ReturnValue = i_APCI1710_Write16BitCounterValue(dev, + case APCI1710_INCCPT_SETINPUTFILTER: + i_ReturnValue = i_APCI1710_SetInputFilter(dev, (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) data[0], (unsigned int) data[1]); - break; - - case APCI1710_INCCPT_WRITE32BITCOUNTERVALUE: - i_ReturnValue = i_APCI1710_Write32BitCounterValue(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned int) data[0]); - - break; - - case APCI1710_INCCPT_ENABLEINDEX: - i_APCI1710_EnableIndex(dev, (unsigned char) CR_AREF(insn->chanspec)); + (unsigned char) data[0], (unsigned char) data[1]); break; - case APCI1710_INCCPT_DISABLEINDEX: - i_ReturnValue = i_APCI1710_DisableIndex(dev, - (unsigned char) CR_AREF(insn->chanspec)); + case APCI1710_INCCPT_LATCHCOUNTER: + i_ReturnValue = i_APCI1710_LatchCounter(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); break; - case APCI1710_INCCPT_ENABLECOMPARELOGIC: - i_ReturnValue = i_APCI1710_EnableCompareLogic(dev, - (unsigned char) CR_AREF(insn->chanspec)); + case APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE: + i_ReturnValue = i_APCI1710_SetIndexAndReferenceSource(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); break; - case APCI1710_INCCPT_DISABLECOMPARELOGIC: - i_ReturnValue = i_APCI1710_DisableCompareLogic(dev, + case APCI1710_INCCPT_SETDIGITALCHLON: + i_ReturnValue = i_APCI1710_SetDigitalChlOn(dev, (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT: - i_ReturnValue = i_APCI1710_EnableFrequencyMeasurement(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); - break; - - case APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT: - i_ReturnValue = i_APCI1710_DisableFrequencyMeasurement(dev, + case APCI1710_INCCPT_SETDIGITALCHLOFF: + i_ReturnValue = i_APCI1710_SetDigitalChlOff(dev, (unsigned char) CR_AREF(insn->chanspec)); break; default: - printk("Write Config Parameter Wrong\n"); + printk("Bits Config Parameter Wrong\n"); } if (i_ReturnValue >= 0) @@ -3065,8 +2951,8 @@ int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevic | "i_APCI1710_SetBoardIntRoutine" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, + unsigned char b_ModulNbr) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -3152,8 +3038,8 @@ int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, unsigned char b_M | "i_APCI1710_SetBoardIntRoutine" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, + unsigned char b_ModulNbr) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -3251,9 +3137,10 @@ int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, unsigned char b_ | -4: The selected 16-Bit counter parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_SelectedCounter, unsigned int ui_WriteValue) +static int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_SelectedCounter, + unsigned int ui_WriteValue) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -3337,9 +3224,9 @@ int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned int ul_WriteValue) +static int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned int ul_WriteValue) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -3405,8 +3292,8 @@ int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev, | "i_APCI1710_InitIndex" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_EnableIndex(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_EnableIndex(struct comedi_device *dev, + unsigned char b_ModulNbr) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -3504,8 +3391,8 @@ int i_APCI1710_EnableIndex(struct comedi_device *dev, unsigned char b_ModulNbr) | "i_APCI1710_InitIndex" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_DisableIndex(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_DisableIndex(struct comedi_device *dev, + unsigned char b_ModulNbr) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -3604,8 +3491,8 @@ int i_APCI1710_DisableIndex(struct comedi_device *dev, unsigned char b_ModulNbr) | See function "i_APCI1710_SetBoardIntRoutineX" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, + unsigned char b_ModulNbr) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -3705,8 +3592,8 @@ int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, unsigned char b_Mod | See function "i_APCI1710_InitCompareLogic" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, + unsigned char b_ModulNbr) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -3815,9 +3702,9 @@ int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, unsigned char b_Mo | -6: Interrupt function not initialised. | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_InterruptEnable) +static int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_InterruptEnable) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -3963,8 +3850,8 @@ int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev, | See function "i_APCI1710_InitFrequencyMeasurement" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev, unsigned char b_ModulNbr) +static int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev, + unsigned char b_ModulNbr) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -4058,135 +3945,80 @@ int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev, unsigned c return i_ReturnValue; } -/*########################################################################### */ - - /* INSN READ */ - -/*########################################################################### */ - /* -+----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,struct comedi_subdevice *s, -struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read and Get functions for INC_CPT | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ -int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Enable Disable functions for INC_CPT + */ +static int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_ReadType; + unsigned int ui_WriteType; int i_ReturnValue = 0; - ui_ReadType = CR_CHAN(insn->chanspec); - + ui_WriteType = CR_CHAN(insn->chanspec); devpriv->tsk_Current = current; /* Save the current process task structure */ - switch (ui_ReadType) { - case APCI1710_INCCPT_READLATCHREGISTERSTATUS: - i_ReturnValue = i_APCI1710_ReadLatchRegisterStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) CR_RANGE(insn->chanspec), (unsigned char *) &data[0]); - break; - case APCI1710_INCCPT_READLATCHREGISTERVALUE: - i_ReturnValue = i_APCI1710_ReadLatchRegisterValue(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) CR_RANGE(insn->chanspec), (unsigned int *) &data[0]); - printk("Latch Register Value %d\n", data[0]); - break; - - case APCI1710_INCCPT_READ16BITCOUNTERVALUE: - i_ReturnValue = i_APCI1710_Read16BitCounterValue(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) CR_RANGE(insn->chanspec), (unsigned int *) &data[0]); + switch (ui_WriteType) { + case APCI1710_INCCPT_ENABLELATCHINTERRUPT: + i_ReturnValue = i_APCI1710_EnableLatchInterrupt(dev, + (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_READ32BITCOUNTERVALUE: - i_ReturnValue = i_APCI1710_Read32BitCounterValue(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned int *) &data[0]); + case APCI1710_INCCPT_DISABLELATCHINTERRUPT: + i_ReturnValue = i_APCI1710_DisableLatchInterrupt(dev, + (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_GETINDEXSTATUS: - i_ReturnValue = i_APCI1710_GetIndexStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + case APCI1710_INCCPT_WRITE16BITCOUNTERVALUE: + i_ReturnValue = i_APCI1710_Write16BitCounterValue(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char) data[0], (unsigned int) data[1]); break; - case APCI1710_INCCPT_GETREFERENCESTATUS: - i_ReturnValue = i_APCI1710_GetReferenceStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); - break; + case APCI1710_INCCPT_WRITE32BITCOUNTERVALUE: + i_ReturnValue = i_APCI1710_Write32BitCounterValue(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned int) data[0]); - case APCI1710_INCCPT_GETUASSTATUS: - i_ReturnValue = i_APCI1710_GetUASStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); break; - case APCI1710_INCCPT_GETCBSTATUS: - i_ReturnValue = i_APCI1710_GetCBStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + case APCI1710_INCCPT_ENABLEINDEX: + i_APCI1710_EnableIndex(dev, (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_GET16BITCBSTATUS: - i_ReturnValue = i_APCI1710_Get16BitCBStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char *) &data[0], (unsigned char *) &data[1]); + case APCI1710_INCCPT_DISABLEINDEX: + i_ReturnValue = i_APCI1710_DisableIndex(dev, + (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_GETUDSTATUS: - i_ReturnValue = i_APCI1710_GetUDStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); - + case APCI1710_INCCPT_ENABLECOMPARELOGIC: + i_ReturnValue = i_APCI1710_EnableCompareLogic(dev, + (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS: - i_ReturnValue = i_APCI1710_GetInterruptUDLatchedStatus(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + case APCI1710_INCCPT_DISABLECOMPARELOGIC: + i_ReturnValue = i_APCI1710_DisableCompareLogic(dev, + (unsigned char) CR_AREF(insn->chanspec)); break; - case APCI1710_INCCPT_READFREQUENCYMEASUREMENT: - i_ReturnValue = i_APCI1710_ReadFrequencyMeasurement(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char *) &data[0], - (unsigned char *) &data[1], (unsigned int *) &data[2]); + case APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT: + i_ReturnValue = i_APCI1710_EnableFrequencyMeasurement(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); break; - case APCI1710_INCCPT_READINTERRUPT: - data[0] = devpriv->s_InterruptParameters. - s_FIFOInterruptParameters[devpriv-> - s_InterruptParameters.ui_Read].b_OldModuleMask; - data[1] = devpriv->s_InterruptParameters. - s_FIFOInterruptParameters[devpriv-> - s_InterruptParameters.ui_Read].ul_OldInterruptMask; - data[2] = devpriv->s_InterruptParameters. - s_FIFOInterruptParameters[devpriv-> - s_InterruptParameters.ui_Read].ul_OldCounterLatchValue; - - /**************************/ - /* Increment the read FIFO */ - /***************************/ - - devpriv-> - s_InterruptParameters. - ui_Read = (devpriv->s_InterruptParameters. - ui_Read + 1) % APCI1710_SAVE_INTERRUPT; - + case APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT: + i_ReturnValue = i_APCI1710_DisableFrequencyMeasurement(dev, + (unsigned char) CR_AREF(insn->chanspec)); break; default: - printk("ReadType Parameter wrong\n"); + printk("Write Config Parameter Wrong\n"); } if (i_ReturnValue >= 0) i_ReturnValue = insn->n; return i_ReturnValue; - } /* @@ -4222,9 +4054,10 @@ int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice | -4: The selected latch register parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_LatchReg, unsigned char *pb_LatchStatus) +static int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_LatchReg, + unsigned char *pb_LatchStatus) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -4310,9 +4143,10 @@ int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev, | -4: The selected latch register parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_LatchReg, unsigned int *pul_LatchValue) +static int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_LatchReg, + unsigned int *pul_LatchValue) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -4395,9 +4229,10 @@ int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev, | -4: The selected 16-Bit counter parameter is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_SelectedCounter, unsigned int *pui_CounterValue) +static int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_SelectedCounter, + unsigned int *pui_CounterValue) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -4491,9 +4326,9 @@ int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned int *pul_CounterValue) +static int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned int *pul_CounterValue) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -4568,9 +4403,9 @@ int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev, | "i_APCI1710_InitIndex" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetIndexStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_IndexStatus) +static int i_APCI1710_GetIndexStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_IndexStatus) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -4653,9 +4488,9 @@ int i_APCI1710_GetIndexStatus(struct comedi_device *dev, | "i_APCI1710_InitReference" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetReferenceStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_ReferenceStatus) +static int i_APCI1710_GetReferenceStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_ReferenceStatus) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -4738,9 +4573,9 @@ int i_APCI1710_GetReferenceStatus(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetUASStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_UASStatus) +static int i_APCI1710_GetUASStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_UASStatus) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -4807,9 +4642,9 @@ int i_APCI1710_GetUASStatus(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetCBStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_CBStatus) +static int i_APCI1710_GetCBStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_CBStatus) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -4890,9 +4725,10 @@ int i_APCI1710_GetCBStatus(struct comedi_device *dev, | -5: Firmware revision error | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_CBStatusCounter0, unsigned char *pb_CBStatusCounter1) +static int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_CBStatusCounter0, + unsigned char *pb_CBStatusCounter1) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -5004,9 +4840,9 @@ int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev, | "i_APCI1710_InitCounter" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetUDStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_UDStatus) +static int i_APCI1710_GetUDStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_UDStatus) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -5079,9 +4915,9 @@ int i_APCI1710_GetUDStatus(struct comedi_device *dev, | See function "i_APCI1710_SetBoardIntRoutineX" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_UDStatus) +static int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_UDStatus) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -5185,10 +5021,11 @@ int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev, | See function "i_APCI1710_InitFrequencyMeasurement" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char *pb_Status, unsigned char *pb_UDStatus, unsigned int *pul_ReadValue) +static int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char *pb_Status, + unsigned char *pb_UDStatus, + unsigned int *pul_ReadValue) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -5403,3 +5240,118 @@ int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev, return i_ReturnValue; } +/* + * Read and Get functions for INC_CPT + */ +static int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct addi_private *devpriv = dev->private; + unsigned int ui_ReadType; + int i_ReturnValue = 0; + + ui_ReadType = CR_CHAN(insn->chanspec); + + devpriv->tsk_Current = current; /* Save the current process task structure */ + switch (ui_ReadType) { + case APCI1710_INCCPT_READLATCHREGISTERSTATUS: + i_ReturnValue = i_APCI1710_ReadLatchRegisterStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char) CR_RANGE(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_INCCPT_READLATCHREGISTERVALUE: + i_ReturnValue = i_APCI1710_ReadLatchRegisterValue(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char) CR_RANGE(insn->chanspec), (unsigned int *) &data[0]); + printk("Latch Register Value %d\n", data[0]); + break; + + case APCI1710_INCCPT_READ16BITCOUNTERVALUE: + i_ReturnValue = i_APCI1710_Read16BitCounterValue(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char) CR_RANGE(insn->chanspec), (unsigned int *) &data[0]); + break; + + case APCI1710_INCCPT_READ32BITCOUNTERVALUE: + i_ReturnValue = i_APCI1710_Read32BitCounterValue(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned int *) &data[0]); + break; + + case APCI1710_INCCPT_GETINDEXSTATUS: + i_ReturnValue = i_APCI1710_GetIndexStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_INCCPT_GETREFERENCESTATUS: + i_ReturnValue = i_APCI1710_GetReferenceStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_INCCPT_GETUASSTATUS: + i_ReturnValue = i_APCI1710_GetUASStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_INCCPT_GETCBSTATUS: + i_ReturnValue = i_APCI1710_GetCBStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_INCCPT_GET16BITCBSTATUS: + i_ReturnValue = i_APCI1710_Get16BitCBStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char *) &data[0], (unsigned char *) &data[1]); + break; + + case APCI1710_INCCPT_GETUDSTATUS: + i_ReturnValue = i_APCI1710_GetUDStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + + break; + + case APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS: + i_ReturnValue = i_APCI1710_GetInterruptUDLatchedStatus(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]); + break; + + case APCI1710_INCCPT_READFREQUENCYMEASUREMENT: + i_ReturnValue = i_APCI1710_ReadFrequencyMeasurement(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char *) &data[0], + (unsigned char *) &data[1], (unsigned int *) &data[2]); + break; + + case APCI1710_INCCPT_READINTERRUPT: + data[0] = devpriv->s_InterruptParameters. + s_FIFOInterruptParameters[devpriv-> + s_InterruptParameters.ui_Read].b_OldModuleMask; + data[1] = devpriv->s_InterruptParameters. + s_FIFOInterruptParameters[devpriv-> + s_InterruptParameters.ui_Read].ul_OldInterruptMask; + data[2] = devpriv->s_InterruptParameters. + s_FIFOInterruptParameters[devpriv-> + s_InterruptParameters.ui_Read].ul_OldCounterLatchValue; + + /**************************/ + /* Increment the read FIFO */ + /***************************/ + + devpriv-> + s_InterruptParameters. + ui_Read = (devpriv->s_InterruptParameters. + ui_Read + 1) % APCI1710_SAVE_INTERRUPT; + + break; + + default: + printk("ReadType Parameter wrong\n"); + } + + if (i_ReturnValue >= 0) + i_ReturnValue = insn->n; + return i_ReturnValue; + +} diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h index 358298bfc64..ff3ea6e191e 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h @@ -130,142 +130,3 @@ #define APCI1710_INCCPT_DISABLECOMPARELOGIC 407 #define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT 408 #define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT 409 - -/************ Main Functions *************/ -int i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int * data); - -int i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice * s, - struct comedi_insn *insn, unsigned int * data); - -int i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevice * s, - struct comedi_insn *insn, unsigned int * data); - -int i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice * s, - struct comedi_insn *insn, unsigned int * data); - -/*********** Supplementary Functions********/ - -/* INSN CONFIG */ -int i_APCI1710_InitCounter(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_CounterRange, - unsigned char b_FirstCounterModus, - unsigned char b_FirstCounterOption, - unsigned char b_SecondCounterModus, - unsigned char b_SecondCounterOption); - -int i_APCI1710_CounterAutoTest(struct comedi_device *dev, unsigned char * pb_TestStatus); - -int i_APCI1710_InitIndex(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_ReferenceAction, - unsigned char b_IndexOperation, unsigned char b_AutoMode, - unsigned char b_InterruptEnable); - -int i_APCI1710_InitReference(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_ReferenceLevel); - -int i_APCI1710_InitExternalStrobe(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_ExternalStrobe, - unsigned char b_ExternalStrobeLevel); - -int i_APCI1710_InitCompareLogic(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned int ui_CompareValue); - -int i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PCIInputClock, - unsigned char b_TimingUnity, - unsigned int ul_TimingInterval, - unsigned int *pul_RealTimingInterval); - -/* INSN BITS */ -int i_APCI1710_ClearCounterValue(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_ClearAllCounterValue(struct comedi_device *dev); - -int i_APCI1710_SetInputFilter(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_PCIInputClock, - unsigned char b_Filter); - -int i_APCI1710_LatchCounter(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_LatchReg); - -int i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_SourceSelection); - -int i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, unsigned char b_ModulNbr); - -/* INSN WRITE */ -int i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_Write16BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_SelectedCounter, - unsigned int ui_WriteValue); - -int i_APCI1710_Write32BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned int ul_WriteValue); - -int i_APCI1710_EnableIndex(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_DisableIndex(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_EnableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_DisableCompareLogic(struct comedi_device *dev, unsigned char b_ModulNbr); - -int i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_InterruptEnable); - -int i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr); - -/* INSN READ */ -int i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_LatchReg, - unsigned char *pb_LatchStatus); - -int i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_LatchReg, - unsigned int *pul_LatchValue); - -int i_APCI1710_Read16BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char b_SelectedCounter, - unsigned int *pui_CounterValue); - -int i_APCI1710_Read32BitCounterValue(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned int *pul_CounterValue); - -int i_APCI1710_GetIndexStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_IndexStatus); - -int i_APCI1710_GetReferenceStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_ReferenceStatus); - -int i_APCI1710_GetUASStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_UASStatus); - -int i_APCI1710_GetCBStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_CBStatus); - -int i_APCI1710_Get16BitCBStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_CBStatusCounter0, - unsigned char *pb_CBStatusCounter1); - -int i_APCI1710_GetUDStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_UDStatus); - -int i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev, - unsigned char b_ModulNbr, unsigned char *pb_UDStatus); - -int i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char *pb_Status, unsigned char *pb_UDStatus, - unsigned int *pul_ReadValue); -- cgit v1.2.3 From ae1e6be6c8163addf68f238dc72fcc2fb26be3aa Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:02:55 -0700 Subject: staging: comedi: APCI1710_INCCPT: absorb private header The header file APCI1710_INCCPT.h is only included by the source file APCI1710_INCCPT.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_INCCPT.c | 122 +++++++++++++++++-- .../comedi/drivers/addi-data/APCI1710_INCCPT.h | 132 --------------------- 2 files changed, 115 insertions(+), 139 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c index 7c997f65d28..70a7f953fa2 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c @@ -51,13 +51,121 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ - -#include "APCI1710_INCCPT.h" +#define APCI1710_16BIT_COUNTER 0x10 +#define APCI1710_32BIT_COUNTER 0x0 +#define APCI1710_QUADRUPLE_MODE 0x0 +#define APCI1710_DOUBLE_MODE 0x3 +#define APCI1710_SIMPLE_MODE 0xF +#define APCI1710_DIRECT_MODE 0x80 +#define APCI1710_HYSTERESIS_ON 0x60 +#define APCI1710_HYSTERESIS_OFF 0x0 +#define APCI1710_INCREMENT 0x60 +#define APCI1710_DECREMENT 0x0 +#define APCI1710_LATCH_COUNTER 0x1 +#define APCI1710_CLEAR_COUNTER 0x0 +#define APCI1710_LOW 0x0 +#define APCI1710_HIGH 0x1 + +/*********************/ +/* Version 0600-0229 */ +/*********************/ +#define APCI1710_HIGH_EDGE_CLEAR_COUNTER 0x0 +#define APCI1710_HIGH_EDGE_LATCH_COUNTER 0x1 +#define APCI1710_LOW_EDGE_CLEAR_COUNTER 0x2 +#define APCI1710_LOW_EDGE_LATCH_COUNTER 0x3 +#define APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER 0x4 +#define APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER 0x5 +#define APCI1710_SOURCE_0 0x0 +#define APCI1710_SOURCE_1 0x1 + +#define APCI1710_30MHZ 30 +#define APCI1710_33MHZ 33 +#define APCI1710_40MHZ 40 + +#define APCI1710_ENABLE_LATCH_INT 0x80 +#define APCI1710_DISABLE_LATCH_INT (~APCI1710_ENABLE_LATCH_INT) + +#define APCI1710_INDEX_LATCH_COUNTER 0x10 +#define APCI1710_INDEX_AUTO_MODE 0x8 +#define APCI1710_ENABLE_INDEX 0x4 +#define APCI1710_DISABLE_INDEX (~APCI1710_ENABLE_INDEX) +#define APCI1710_ENABLE_LATCH_AND_CLEAR 0x8 +#define APCI1710_DISABLE_LATCH_AND_CLEAR (~APCI1710_ENABLE_LATCH_AND_CLEAR) +#define APCI1710_SET_LOW_INDEX_LEVEL 0x4 +#define APCI1710_SET_HIGH_INDEX_LEVEL (~APCI1710_SET_LOW_INDEX_LEVEL) +#define APCI1710_INVERT_INDEX_RFERENCE 0x2 +#define APCI1710_DEFAULT_INDEX_RFERENCE (~APCI1710_INVERT_INDEX_RFERENCE) + +#define APCI1710_ENABLE_INDEX_INT 0x1 +#define APCI1710_DISABLE_INDEX_INT (~APCI1710_ENABLE_INDEX_INT) + +#define APCI1710_ENABLE_FREQUENCY 0x4 +#define APCI1710_DISABLE_FREQUENCY (~APCI1710_ENABLE_FREQUENCY) + +#define APCI1710_ENABLE_FREQUENCY_INT 0x8 +#define APCI1710_DISABLE_FREQUENCY_INT (~APCI1710_ENABLE_FREQUENCY_INT) + +#define APCI1710_ENABLE_40MHZ_FREQUENCY 0x40 +#define APCI1710_DISABLE_40MHZ_FREQUENCY (~APCI1710_ENABLE_40MHZ_FREQUENCY) + +#define APCI1710_ENABLE_40MHZ_FILTER 0x80 +#define APCI1710_DISABLE_40MHZ_FILTER (~APCI1710_ENABLE_40MHZ_FILTER) + +#define APCI1710_ENABLE_COMPARE_INT 0x2 +#define APCI1710_DISABLE_COMPARE_INT (~APCI1710_ENABLE_COMPARE_INT) + +#define APCI1710_ENABLE_INDEX_ACTION 0x20 +#define APCI1710_DISABLE_INDEX_ACTION (~APCI1710_ENABLE_INDEX_ACTION) +#define APCI1710_REFERENCE_HIGH 0x40 +#define APCI1710_REFERENCE_LOW (~APCI1710_REFERENCE_HIGH) + +#define APCI1710_TOR_GATE_LOW 0x40 +#define APCI1710_TOR_GATE_HIGH (~APCI1710_TOR_GATE_LOW) + +/* INSN CONFIG */ +#define APCI1710_INCCPT_INITCOUNTER 100 +#define APCI1710_INCCPT_COUNTERAUTOTEST 101 +#define APCI1710_INCCPT_INITINDEX 102 +#define APCI1710_INCCPT_INITREFERENCE 103 +#define APCI1710_INCCPT_INITEXTERNALSTROBE 104 +#define APCI1710_INCCPT_INITCOMPARELOGIC 105 +#define APCI1710_INCCPT_INITFREQUENCYMEASUREMENT 106 + +/* INSN READ */ +#define APCI1710_INCCPT_READLATCHREGISTERSTATUS 200 +#define APCI1710_INCCPT_READLATCHREGISTERVALUE 201 +#define APCI1710_INCCPT_READ16BITCOUNTERVALUE 202 +#define APCI1710_INCCPT_READ32BITCOUNTERVALUE 203 +#define APCI1710_INCCPT_GETINDEXSTATUS 204 +#define APCI1710_INCCPT_GETREFERENCESTATUS 205 +#define APCI1710_INCCPT_GETUASSTATUS 206 +#define APCI1710_INCCPT_GETCBSTATUS 207 +#define APCI1710_INCCPT_GET16BITCBSTATUS 208 +#define APCI1710_INCCPT_GETUDSTATUS 209 +#define APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS 210 +#define APCI1710_INCCPT_READFREQUENCYMEASUREMENT 211 +#define APCI1710_INCCPT_READINTERRUPT 212 + +/* INSN BITS */ +#define APCI1710_INCCPT_CLEARCOUNTERVALUE 300 +#define APCI1710_INCCPT_CLEARALLCOUNTERVALUE 301 +#define APCI1710_INCCPT_SETINPUTFILTER 302 +#define APCI1710_INCCPT_LATCHCOUNTER 303 +#define APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE 304 +#define APCI1710_INCCPT_SETDIGITALCHLON 305 +#define APCI1710_INCCPT_SETDIGITALCHLOFF 306 + +/* INSN WRITE */ +#define APCI1710_INCCPT_ENABLELATCHINTERRUPT 400 +#define APCI1710_INCCPT_DISABLELATCHINTERRUPT 401 +#define APCI1710_INCCPT_WRITE16BITCOUNTERVALUE 402 +#define APCI1710_INCCPT_WRITE32BITCOUNTERVALUE 403 +#define APCI1710_INCCPT_ENABLEINDEX 404 +#define APCI1710_INCCPT_DISABLEINDEX 405 +#define APCI1710_INCCPT_ENABLECOMPARELOGIC 406 +#define APCI1710_INCCPT_DISABLECOMPARELOGIC 407 +#define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT 408 +#define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT 409 /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h deleted file mode 100644 index ff3ea6e191e..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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 APCI1710_16BIT_COUNTER 0x10 -#define APCI1710_32BIT_COUNTER 0x0 -#define APCI1710_QUADRUPLE_MODE 0x0 -#define APCI1710_DOUBLE_MODE 0x3 -#define APCI1710_SIMPLE_MODE 0xF -#define APCI1710_DIRECT_MODE 0x80 -#define APCI1710_HYSTERESIS_ON 0x60 -#define APCI1710_HYSTERESIS_OFF 0x0 -#define APCI1710_INCREMENT 0x60 -#define APCI1710_DECREMENT 0x0 -#define APCI1710_LATCH_COUNTER 0x1 -#define APCI1710_CLEAR_COUNTER 0x0 -#define APCI1710_LOW 0x0 -#define APCI1710_HIGH 0x1 - -/*********************/ -/* Version 0600-0229 */ -/*********************/ -#define APCI1710_HIGH_EDGE_CLEAR_COUNTER 0x0 -#define APCI1710_HIGH_EDGE_LATCH_COUNTER 0x1 -#define APCI1710_LOW_EDGE_CLEAR_COUNTER 0x2 -#define APCI1710_LOW_EDGE_LATCH_COUNTER 0x3 -#define APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER 0x4 -#define APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER 0x5 -#define APCI1710_SOURCE_0 0x0 -#define APCI1710_SOURCE_1 0x1 - -#define APCI1710_30MHZ 30 -#define APCI1710_33MHZ 33 -#define APCI1710_40MHZ 40 - -#define APCI1710_ENABLE_LATCH_INT 0x80 -#define APCI1710_DISABLE_LATCH_INT (~APCI1710_ENABLE_LATCH_INT) - -#define APCI1710_INDEX_LATCH_COUNTER 0x10 -#define APCI1710_INDEX_AUTO_MODE 0x8 -#define APCI1710_ENABLE_INDEX 0x4 -#define APCI1710_DISABLE_INDEX (~APCI1710_ENABLE_INDEX) -#define APCI1710_ENABLE_LATCH_AND_CLEAR 0x8 -#define APCI1710_DISABLE_LATCH_AND_CLEAR (~APCI1710_ENABLE_LATCH_AND_CLEAR) -#define APCI1710_SET_LOW_INDEX_LEVEL 0x4 -#define APCI1710_SET_HIGH_INDEX_LEVEL (~APCI1710_SET_LOW_INDEX_LEVEL) -#define APCI1710_INVERT_INDEX_RFERENCE 0x2 -#define APCI1710_DEFAULT_INDEX_RFERENCE (~APCI1710_INVERT_INDEX_RFERENCE) - -#define APCI1710_ENABLE_INDEX_INT 0x1 -#define APCI1710_DISABLE_INDEX_INT (~APCI1710_ENABLE_INDEX_INT) - -#define APCI1710_ENABLE_FREQUENCY 0x4 -#define APCI1710_DISABLE_FREQUENCY (~APCI1710_ENABLE_FREQUENCY) - -#define APCI1710_ENABLE_FREQUENCY_INT 0x8 -#define APCI1710_DISABLE_FREQUENCY_INT (~APCI1710_ENABLE_FREQUENCY_INT) - -#define APCI1710_ENABLE_40MHZ_FREQUENCY 0x40 -#define APCI1710_DISABLE_40MHZ_FREQUENCY (~APCI1710_ENABLE_40MHZ_FREQUENCY) - -#define APCI1710_ENABLE_40MHZ_FILTER 0x80 -#define APCI1710_DISABLE_40MHZ_FILTER (~APCI1710_ENABLE_40MHZ_FILTER) - -#define APCI1710_ENABLE_COMPARE_INT 0x2 -#define APCI1710_DISABLE_COMPARE_INT (~APCI1710_ENABLE_COMPARE_INT) - -#define APCI1710_ENABLE_INDEX_ACTION 0x20 -#define APCI1710_DISABLE_INDEX_ACTION (~APCI1710_ENABLE_INDEX_ACTION) -#define APCI1710_REFERENCE_HIGH 0x40 -#define APCI1710_REFERENCE_LOW (~APCI1710_REFERENCE_HIGH) - -#define APCI1710_TOR_GATE_LOW 0x40 -#define APCI1710_TOR_GATE_HIGH (~APCI1710_TOR_GATE_LOW) - -/* INSN CONFIG */ -#define APCI1710_INCCPT_INITCOUNTER 100 -#define APCI1710_INCCPT_COUNTERAUTOTEST 101 -#define APCI1710_INCCPT_INITINDEX 102 -#define APCI1710_INCCPT_INITREFERENCE 103 -#define APCI1710_INCCPT_INITEXTERNALSTROBE 104 -#define APCI1710_INCCPT_INITCOMPARELOGIC 105 -#define APCI1710_INCCPT_INITFREQUENCYMEASUREMENT 106 - -/* INSN READ */ -#define APCI1710_INCCPT_READLATCHREGISTERSTATUS 200 -#define APCI1710_INCCPT_READLATCHREGISTERVALUE 201 -#define APCI1710_INCCPT_READ16BITCOUNTERVALUE 202 -#define APCI1710_INCCPT_READ32BITCOUNTERVALUE 203 -#define APCI1710_INCCPT_GETINDEXSTATUS 204 -#define APCI1710_INCCPT_GETREFERENCESTATUS 205 -#define APCI1710_INCCPT_GETUASSTATUS 206 -#define APCI1710_INCCPT_GETCBSTATUS 207 -#define APCI1710_INCCPT_GET16BITCBSTATUS 208 -#define APCI1710_INCCPT_GETUDSTATUS 209 -#define APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS 210 -#define APCI1710_INCCPT_READFREQUENCYMEASUREMENT 211 -#define APCI1710_INCCPT_READINTERRUPT 212 - -/* INSN BITS */ -#define APCI1710_INCCPT_CLEARCOUNTERVALUE 300 -#define APCI1710_INCCPT_CLEARALLCOUNTERVALUE 301 -#define APCI1710_INCCPT_SETINPUTFILTER 302 -#define APCI1710_INCCPT_LATCHCOUNTER 303 -#define APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE 304 -#define APCI1710_INCCPT_SETDIGITALCHLON 305 -#define APCI1710_INCCPT_SETDIGITALCHLOFF 306 - -/* INSN WRITE */ -#define APCI1710_INCCPT_ENABLELATCHINTERRUPT 400 -#define APCI1710_INCCPT_DISABLELATCHINTERRUPT 401 -#define APCI1710_INCCPT_WRITE16BITCOUNTERVALUE 402 -#define APCI1710_INCCPT_WRITE32BITCOUNTERVALUE 403 -#define APCI1710_INCCPT_ENABLEINDEX 404 -#define APCI1710_INCCPT_DISABLEINDEX 405 -#define APCI1710_INCCPT_ENABLECOMPARELOGIC 406 -#define APCI1710_INCCPT_DISABLECOMPARELOGIC 407 -#define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT 408 -#define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT 409 -- cgit v1.2.3 From ebffb128ec32ea82869abad47fae25649994e978 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:03:11 -0700 Subject: staging: comedi: APCI1710_Pwm: remove forward declarations This source file is #include'd when building the addi_apci_1710 driver. All the functions in this file are actually static and should not be exported to the kernel. Move some of the functions to remove the need for the forward declarations and make all of the functions in this file static. Note, this patch does not try to fix any of the coding style issues in the functions. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Pwm.c | 256 ++++++++++----------- .../comedi/drivers/addi-data/APCI1710_Pwm.h | 49 ---- 2 files changed, 122 insertions(+), 183 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c index 9a01ea05b40..f5b2a8a7954 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c @@ -55,65 +55,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #include "APCI1710_Pwm.h" -/* -+----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnConfigPWM(struct comedi_device *dev, -struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Pwm Init and Get Pwm Initialisation | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - unsigned char b_ConfigType; - int i_ReturnValue = 0; - b_ConfigType = CR_CHAN(insn->chanspec); - - switch (b_ConfigType) { - case APCI1710_PWM_INIT: - i_ReturnValue = i_APCI1710_InitPWM(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */ - (unsigned char) data[0], /* b_PWM */ - (unsigned char) data[1], /* b_ClockSelection */ - (unsigned char) data[2], /* b_TimingUnit */ - (unsigned int) data[3], /* ul_LowTiming */ - (unsigned int) data[4], /* ul_HighTiming */ - (unsigned int *) &data[0], /* pul_RealLowTiming */ - (unsigned int *) &data[1] /* pul_RealHighTiming */ - ); - break; - - case APCI1710_PWM_GETINITDATA: - i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */ - (unsigned char) data[0], /* b_PWM */ - (unsigned char *) &data[0], /* pb_TimingUnit */ - (unsigned int *) &data[1], /* pul_LowTiming */ - (unsigned int *) &data[2], /* pul_HighTiming */ - (unsigned char *) &data[3], /* pb_StartLevel */ - (unsigned char *) &data[4], /* pb_StopMode */ - (unsigned char *) &data[5], /* pb_StopLevel */ - (unsigned char *) &data[6], /* pb_ExternGate */ - (unsigned char *) &data[7], /* pb_InterruptEnable */ - (unsigned char *) &data[8] /* pb_Enable */ - ); - break; - - default: - printk(" Config Parameter Wrong\n"); - } - - if (i_ReturnValue >= 0) - i_ReturnValue = insn->n; - return i_ReturnValue; -} - /* +----------------------------------------------------------------------------+ | Function Name : _INT_ i_APCI1710_InitPWM | @@ -178,15 +119,15 @@ int i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice | this board | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InitPWM(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, - unsigned char b_ClockSelection, - unsigned char b_TimingUnit, - unsigned int ul_LowTiming, - unsigned int ul_HighTiming, - unsigned int *pul_RealLowTiming, unsigned int *pul_RealHighTiming) +static int i_APCI1710_InitPWM(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PWM, + unsigned char b_ClockSelection, + unsigned char b_TimingUnit, + unsigned int ul_LowTiming, + unsigned int ul_HighTiming, + unsigned int *pul_RealLowTiming, + unsigned int *pul_RealHighTiming) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1534,17 +1475,18 @@ int i_APCI1710_InitPWM(struct comedi_device *dev, | "i_APCI1710_InitPWM" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, - unsigned char *pb_TimingUnit, - unsigned int *pul_LowTiming, - unsigned int *pul_HighTiming, - unsigned char *pb_StartLevel, - unsigned char *pb_StopMode, - unsigned char *pb_StopLevel, - unsigned char *pb_ExternGate, unsigned char *pb_InterruptEnable, unsigned char *pb_Enable) +static int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PWM, + unsigned char *pb_TimingUnit, + unsigned int *pul_LowTiming, + unsigned int *pul_HighTiming, + unsigned char *pb_StartLevel, + unsigned char *pb_StopMode, + unsigned char *pb_StopLevel, + unsigned char *pb_ExternGate, + unsigned char *pb_InterruptEnable, + unsigned char *pb_Enable) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -1671,51 +1613,47 @@ int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev, } /* -+----------------------------------------------------------------------------+ -| Function Name :INT i_APCI1710_InsnWritePWM(struct comedi_device *dev, -struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Pwm Enable Disable and Set New Timing | -+----------------------------------------------------------------------------+ -| Input Parameters : -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : -+----------------------------------------------------------------------------+ -*/ - -int i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Pwm Init and Get Pwm Initialisation + */ +static int i_APCI1710_InsnConfigPWM(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned char b_WriteType; + unsigned char b_ConfigType; int i_ReturnValue = 0; - b_WriteType = CR_CHAN(insn->chanspec); - - switch (b_WriteType) { - case APCI1710_PWM_ENABLE: - i_ReturnValue = i_APCI1710_EnablePWM(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) data[0], - (unsigned char) data[1], - (unsigned char) data[2], - (unsigned char) data[3], (unsigned char) data[4], (unsigned char) data[5]); - break; + b_ConfigType = CR_CHAN(insn->chanspec); - case APCI1710_PWM_DISABLE: - i_ReturnValue = i_APCI1710_DisablePWM(dev, - (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); + switch (b_ConfigType) { + case APCI1710_PWM_INIT: + i_ReturnValue = i_APCI1710_InitPWM(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */ + (unsigned char) data[0], /* b_PWM */ + (unsigned char) data[1], /* b_ClockSelection */ + (unsigned char) data[2], /* b_TimingUnit */ + (unsigned int) data[3], /* ul_LowTiming */ + (unsigned int) data[4], /* ul_HighTiming */ + (unsigned int *) &data[0], /* pul_RealLowTiming */ + (unsigned int *) &data[1] /* pul_RealHighTiming */ + ); break; - case APCI1710_PWM_NEWTIMING: - i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev, - (unsigned char) CR_AREF(insn->chanspec), - (unsigned char) data[0], - (unsigned char) data[1], (unsigned int) data[2], (unsigned int) data[3]); + case APCI1710_PWM_GETINITDATA: + i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */ + (unsigned char) data[0], /* b_PWM */ + (unsigned char *) &data[0], /* pb_TimingUnit */ + (unsigned int *) &data[1], /* pul_LowTiming */ + (unsigned int *) &data[2], /* pul_HighTiming */ + (unsigned char *) &data[3], /* pb_StartLevel */ + (unsigned char *) &data[4], /* pb_StopMode */ + (unsigned char *) &data[5], /* pb_StopLevel */ + (unsigned char *) &data[6], /* pb_ExternGate */ + (unsigned char *) &data[7], /* pb_InterruptEnable */ + (unsigned char *) &data[8] /* pb_Enable */ + ); break; default: - printk("Write Config Parameter Wrong\n"); + printk(" Config Parameter Wrong\n"); } if (i_ReturnValue >= 0) @@ -1807,13 +1745,14 @@ int i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice * | See function "i_APCI1710_SetBoardIntRoutineX" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_EnablePWM(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, - unsigned char b_StartLevel, - unsigned char b_StopMode, - unsigned char b_StopLevel, unsigned char b_ExternGate, unsigned char b_InterruptEnable) +static int i_APCI1710_EnablePWM(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PWM, + unsigned char b_StartLevel, + unsigned char b_StopMode, + unsigned char b_StopLevel, + unsigned char b_ExternGate, + unsigned char b_InterruptEnable) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -2064,8 +2003,9 @@ int i_APCI1710_EnablePWM(struct comedi_device *dev, | "i_APCI1710_EnablePWM" | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_DisablePWM(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_PWM) +static int i_APCI1710_DisablePWM(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PWM) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -2192,10 +2132,12 @@ int i_APCI1710_DisablePWM(struct comedi_device *dev, unsigned char b_ModulNbr, u | -8: High base timing selection is wrong | +----------------------------------------------------------------------------+ */ - -int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, unsigned char b_TimingUnit, unsigned int ul_LowTiming, unsigned int ul_HighTiming) +static int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev, + unsigned char b_ModulNbr, + unsigned char b_PWM, + unsigned char b_TimingUnit, + unsigned int ul_LowTiming, + unsigned int ul_HighTiming) { struct addi_private *devpriv = dev->private; unsigned char b_ClockSelection; @@ -3419,6 +3361,49 @@ int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev, return i_ReturnValue; } +/* + * Pwm Enable Disable and Set New Timing + */ +static int i_APCI1710_InsnWritePWM(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned char b_WriteType; + int i_ReturnValue = 0; + b_WriteType = CR_CHAN(insn->chanspec); + + switch (b_WriteType) { + case APCI1710_PWM_ENABLE: + i_ReturnValue = i_APCI1710_EnablePWM(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char) data[0], + (unsigned char) data[1], + (unsigned char) data[2], + (unsigned char) data[3], (unsigned char) data[4], (unsigned char) data[5]); + break; + + case APCI1710_PWM_DISABLE: + i_ReturnValue = i_APCI1710_DisablePWM(dev, + (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]); + break; + + case APCI1710_PWM_NEWTIMING: + i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev, + (unsigned char) CR_AREF(insn->chanspec), + (unsigned char) data[0], + (unsigned char) data[1], (unsigned int) data[2], (unsigned int) data[3]); + break; + + default: + printk("Write Config Parameter Wrong\n"); + } + + if (i_ReturnValue >= 0) + i_ReturnValue = insn->n; + return i_ReturnValue; +} + /* +----------------------------------------------------------------------------+ | Function Name : _INT_ i_APCI1710_GetPWMStatus | @@ -3464,9 +3449,10 @@ int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev, | -6: PWM not enabled see function "i_APCI1710_EnablePWM"| +----------------------------------------------------------------------------+ */ - -int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; int i_ReturnValue = 0; @@ -3566,8 +3552,10 @@ int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_sub return i_ReturnValue; } -int i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h index d8ad0b9cf50..be5259075dc 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h @@ -25,52 +25,3 @@ #define APCI1710_PWM_DISABLE 0 #define APCI1710_PWM_ENABLE 1 #define APCI1710_PWM_NEWTIMING 2 - -int i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InitPWM(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, - unsigned char b_ClockSelection, - unsigned char b_TimingUnit, - unsigned int ul_LowTiming, - unsigned int ul_HighTiming, - unsigned int *pul_RealLowTiming, unsigned int *pul_RealHighTiming); - -int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, - unsigned char *pb_TimingUnit, - unsigned int *pul_LowTiming, - unsigned int *pul_HighTiming, - unsigned char *pb_StartLevel, - unsigned char *pb_StopMode, - unsigned char *pb_StopLevel, - unsigned char *pb_ExternGate, - unsigned char *pb_InterruptEnable, unsigned char *pb_Enable); - -int i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_EnablePWM(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, - unsigned char b_StartLevel, - unsigned char b_StopMode, - unsigned char b_StopLevel, unsigned char b_ExternGate, - unsigned char b_InterruptEnable); - -int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev, - unsigned char b_ModulNbr, - unsigned char b_PWM, unsigned char b_TimingUnit, - unsigned int ul_LowTiming, unsigned int ul_HighTiming); - -int i_APCI1710_DisablePWM(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_PWM); - -int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); - -int i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -- cgit v1.2.3 From bbb19fc5a6aef865619fcd0b4b5479f65ae5fd49 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:03:25 -0700 Subject: staging: comedi: APCI1710_Pwm: absorb private header The header file APCI1710_Pwm.h is only included by the source file APCI1710_Pwm.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/APCI1710_Pwm.c | 15 +++++++----- .../comedi/drivers/addi-data/APCI1710_Pwm.h | 27 ---------------------- 2 files changed, 9 insertions(+), 33 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c index f5b2a8a7954..a211e78dd3b 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c @@ -47,13 +47,16 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ */ -/* -+----------------------------------------------------------------------------+ -| Included files | -+----------------------------------------------------------------------------+ -*/ +#define APCI1710_30MHZ 30 +#define APCI1710_33MHZ 33 +#define APCI1710_40MHZ 40 + +#define APCI1710_PWM_INIT 0 +#define APCI1710_PWM_GETINITDATA 1 -#include "APCI1710_Pwm.h" +#define APCI1710_PWM_DISABLE 0 +#define APCI1710_PWM_ENABLE 1 +#define APCI1710_PWM_NEWTIMING 2 /* +----------------------------------------------------------------------------+ diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h deleted file mode 100644 index be5259075dc..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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 APCI1710_30MHZ 30 -#define APCI1710_33MHZ 33 -#define APCI1710_40MHZ 40 - -#define APCI1710_PWM_INIT 0 -#define APCI1710_PWM_GETINITDATA 1 - -#define APCI1710_PWM_DISABLE 0 -#define APCI1710_PWM_ENABLE 1 -#define APCI1710_PWM_NEWTIMING 2 -- cgit v1.2.3 From fddc1ced98d12cf282280abec5dc698501214640 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:04:12 -0700 Subject: staging: comedi: hwdrv_apci3200: remove forward declarations This source file is #include'd when building the addi_apci_3200 and addi_apci_3300 driver. All the functions in this file are actually static and should not be exported to the kernel. Move some of the functions to remove the need for the forward declarations and make all of the functions in this file static. Note, this patch does not try to fix any of the coding style issues in the functions. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3200.c | 3087 +++++++++----------- .../comedi/drivers/addi-data/hwdrv_apci3200.h | 36 - 2 files changed, 1348 insertions(+), 1775 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index 7f5efa39cb7..1c0bf27696c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -94,27 +94,10 @@ struct str_BoardInfos s_BoardInfos[100]; /* 100 will be the max number of board #define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */ #define NVCMD_BEGIN_WRITE (0x6 << 5) /* EEPROM begin write command */ -/*+----------------------------------------------------------------------------+*/ -/*| Function Name : int i_AddiHeaderRW_ReadEeprom |*/ -/*| (int i_NbOfWordsToRead, |*/ -/*| unsigned int dw_PCIBoardEepromAddress, |*/ -/*| unsigned short w_EepromStartAddress, |*/ -/*| unsigned short * pw_DataRead) |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Task : Read word from the 5920 eeprom. |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Input Parameters : int i_NbOfWordsToRead : Nbr. of word to read |*/ -/*| unsigned int dw_PCIBoardEepromAddress : Address of the eeprom |*/ -/*| unsigned short w_EepromStartAddress : Eeprom start address |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Output Parameters : unsigned short * pw_DataRead : Read data |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Return Value : - |*/ -/*+----------------------------------------------------------------------------+*/ - -int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead, - unsigned int dw_PCIBoardEepromAddress, - unsigned short w_EepromStartAddress, unsigned short *pw_DataRead) +static int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead, + unsigned int dw_PCIBoardEepromAddress, + unsigned short w_EepromStartAddress, + unsigned short *pw_DataRead) { unsigned int dw_eeprom_busy = 0; int i_Counter = 0; @@ -241,20 +224,8 @@ int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead, return 0; } -/*+----------------------------------------------------------------------------+*/ -/*| Function Name : void v_GetAPCI3200EepromCalibrationValue (void) |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Task : Read calibration value from the APCI-3200 eeprom. |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Input Parameters : - |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Output Parameters : - |*/ -/*+----------------------------------------------------------------------------+*/ -/*| Return Value : - |*/ -/*+----------------------------------------------------------------------------+*/ - -void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress, - struct str_BoardInfos *BoardInformations) +static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress, + struct str_BoardInfos *BoardInformations) { unsigned short w_AnalogInputMainHeaderAddress; unsigned short w_AnalogInputComponentAddress; @@ -448,9 +419,11 @@ void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress, } } -int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev, - unsigned int ui_Channel_num, unsigned int *CJCCurrentSource, - unsigned int *ChannelCurrentSource, unsigned int *ChannelGainFactor) +static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev, + unsigned int ui_Channel_num, + unsigned int *CJCCurrentSource, + unsigned int *ChannelCurrentSource, + unsigned int *ChannelGainFactor) { int i_DiffChannel = 0; int i_Module = 0; @@ -520,33 +493,19 @@ int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev, return 0; } -/* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadDigitalInput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read value of the selected channel or port | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int ui_NoOfChannels : No Of Channels To read for Port - Channel Numberfor single channel - | unsigned int data[0] : 0: Read single channel - 1: Read port value - data[1] Port number - +----------------------------------------------------------------------------+ - | Output Parameters : -- data[0] :Read status value - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Read value of the selected channel or port + * + * data[0] = 0: Read single channel + * = 1 Read port value + * data[1] = Port number + * + * data[0] : Read status value + */ +static int i_APCI3200_ReadDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp = 0; @@ -587,26 +546,15 @@ int i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevi } /* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ConfigDigitalOutput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Configures The Digital Output Subdevice. | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | data[0] :1 Memory enable - 0 Memory Disable - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Configures The Digital Output Subdevice. + * + * data[0] = 1 Memory enable + * = 0 Memory Disable + */ +static int i_APCI3200_ConfigDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; @@ -625,34 +573,19 @@ int i_APCI3200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subd } /* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_WriteDigitalOutput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : writes To the digital Output Subdevice | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | struct comedi_subdevice *s : Subdevice Pointer | - | struct comedi_insn *insn : Insn Structure Pointer | - | unsigned int *data : Data Pointer contains | - | configuration parameters as below | - | data[0] :Value to output - data[1] : 0 o/p single channel - 1 o/p port - data[2] : port no - data[3] :0 set the digital o/p on - 1 set the digital o/p off - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Writes To the digital Output Subdevice + * + * data[0] = Value to output + * data[1] = 0 o/p single channel + * = 1 o/p port + * data[2] = port no + * data[3] = 0 set the digital o/p on + * = 1 set the digital o/p off + */ +static int i_APCI3200_WriteDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp = 0, ui_Temp1 = 0; @@ -744,30 +677,16 @@ int i_APCI3200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde } /* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadDigitalOutput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read value of the selected channel or port | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int ui_NoOfChannels : No Of Channels To read | - | unsigned int *data : Data Pointer to read status | - data[0] :0 read single channel - 1 read port value - data[1] port no - - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + * Read value of the selected channel or port + * + * data[0] = 0 read single channel + * = 1 read port value + * data[1] = port no + */ +static int i_APCI3200_ReadDigitalOutput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Temp; @@ -806,881 +725,360 @@ int i_APCI3200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdev return insn->n; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ConfigAnalogInput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Configures The Analog Input Subdevice | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | struct comedi_subdevice *s : Subdevice Pointer | - | struct comedi_insn *insn : Insn Structure Pointer | - | unsigned int *data : Data Pointer contains | - | configuration parameters as below | - | | - | data[0] - | 0:Normal AI | - | 1:RTD | - | 2:THERMOCOUPLE | - | data[1] : Gain To Use | - | | - | data[2] : Polarity - | 0:Bipolar | - | 1:Unipolar | - | | - | data[3] : Offset Range - | | - | data[4] : Coupling - | 0:DC Coupling | - | 1:AC Coupling | - | | - | data[5] :Differential/Single - | 0:Single | - | 1:Differential | - | | - | data[6] :TimerReloadValue - | | - | data[7] :ConvertingTimeUnit - | | - | data[8] :0 Analog voltage measurement - 1 Resistance measurement - 2 Temperature measurement - | data[9] :Interrupt - | 0:Disable - | 1:Enable - data[10] :Type of Thermocouple - | data[11] : 0: single channel - Module Number - | - | data[12] - | 0:Single Read - | 1:Read more channel - 2:Single scan - | 3:Continuous Scan - data[13] :Number of channels to read - | data[14] :RTD connection type - :0:RTD not used - 1:RTD 2 wire connection - 2:RTD 3 wire connection - 3:RTD 4 wire connection - | | - | | - | | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ul_Config = 0, ul_Temp = 0; + unsigned int ui_EOC = 0; unsigned int ui_ChannelNo = 0; - unsigned int ui_Dummy = 0; - int i_err = 0; + unsigned int ui_CommandRegister = 0; - /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_ChannelNo=i_ChannelNo; */ + ui_ChannelNo = s_BoardInfos[dev->minor].i_ChannelNo; -#ifdef PRINT_INFO - int i = 0, i2 = 0; -#endif - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /*********************************/ + /* Write the channel to configure */ + /*********************************/ + /* Begin JK 20.10.2004: Bad channel value is used when using differential mode */ + /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */ + /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */ + outl(0 | s_BoardInfos[dev->minor].i_ChannelNo, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4); + /* End JK 20.10.2004: Bad channel value is used when using differential mode */ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* Initialize the structure */ - if (s_BoardInfos[dev->minor].b_StructInitialized != 1) { - s_BoardInfos[dev->minor].i_CJCAvailable = 1; - s_BoardInfos[dev->minor].i_CJCPolarity = 0; - s_BoardInfos[dev->minor].i_CJCGain = 2; /* changed from 0 to 2 */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - s_BoardInfos[dev->minor].i_AutoCalibration = 0; /* : auto calibration */ - s_BoardInfos[dev->minor].i_ChannelCount = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - s_BoardInfos[dev->minor].ui_Channel_num = 0; - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].b_StructInitialized = 1; + /*******************************/ + /* Set the convert timing unit */ + /*******************************/ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; - /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - s_BoardInfos[dev->minor].i_ConnectionType = 0; - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ + outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - memset(s_BoardInfos[dev->minor].s_Module, 0, - sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE])); + /**************************/ + /* Set the convert timing */ + /**************************/ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; - v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc, - &s_BoardInfos[dev->minor]); + /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ + outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); -#ifdef PRINT_INFO - for (i = 0; i < MAX_MODULE; i++) { - printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i, - s_BoardInfos[dev->minor].s_Module[i]. - ul_CurrentSourceCJC); + /**************************************************************************/ + /* Set the start end stop index to the selected channel and set the start */ + /**************************************************************************/ - for (i2 = 0; i2 < 5; i2++) { - printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]); - } + ui_CommandRegister = ui_ChannelNo | (ui_ChannelNo << 8) | 0x80000; - for (i2 = 0; i2 < 8; i2++) { - printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]); - } + /*********************************/ + /*Test if the interrupt is enable */ + /*********************************/ - for (i2 = 0; i2 < 8; i2++) { - printk("\n s_Module[%i].w_GainValue [%i] = %u", - i, i2, - s_BoardInfos[dev->minor].s_Module[i]. - w_GainValue[i2]); - } - } -#endif - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } + /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ + if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) { + /************************/ + /* Enable the interrupt */ + /************************/ + ui_CommandRegister = ui_CommandRegister | 0x00100000; + } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ - if (data[0] != 0 && data[0] != 1 && data[0] != 2) { - printk("\nThe selection of acquisition type is in error\n"); - i_err++; - } /* if(data[0]!=0 && data[0]!=1 && data[0]!=2) */ - if (data[0] == 1) { - if (data[14] != 0 && data[14] != 1 && data[14] != 2 - && data[14] != 4) { - printk("\n Error in selection of RTD connection type\n"); - i_err++; - } /* if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4) */ - } /* if(data[0]==1 ) */ - if (data[1] < 0 || data[1] > 7) { - printk("\nThe selection of gain is in error\n"); - i_err++; - } /* if(data[1]<0 || data[1]>7) */ - if (data[2] != 0 && data[2] != 1) { - printk("\nThe selection of polarity is in error\n"); - i_err++; - } /* if(data[2]!=0 && data[2]!=1) */ - if (data[3] != 0) { - printk("\nThe selection of offset range is in error\n"); - i_err++; - } /* if(data[3]!=0) */ - if (data[4] != 0 && data[4] != 1) { - printk("\nThe selection of coupling is in error\n"); - i_err++; - } /* if(data[4]!=0 && data[4]!=1) */ - if (data[5] != 0 && data[5] != 1) { - printk("\nThe selection of single/differential mode is in error\n"); - i_err++; - } /* if(data[5]!=0 && data[5]!=1) */ - if (data[8] != 0 && data[8] != 1 && data[2] != 2) { - printk("\nError in selection of functionality\n"); - } /* if(data[8]!=0 && data[8]!=1 && data[2]!=2) */ - if (data[12] == 0 || data[12] == 1) { - if (data[6] != 20 && data[6] != 40 && data[6] != 80 - && data[6] != 160) { - printk("\nThe selection of conversion time reload value is in error\n"); - i_err++; - } /* if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 ) */ - if (data[7] != 2) { - printk("\nThe selection of conversion time unit is in error\n"); - i_err++; - } /* if(data[7]!=2) */ - } - if (data[9] != 0 && data[9] != 1) { - printk("\nThe selection of interrupt enable is in error\n"); - i_err++; - } /* if(data[9]!=0 && data[9]!=1) */ - if (data[11] < 0 || data[11] > 4) { - printk("\nThe selection of module is in error\n"); - i_err++; - } /* if(data[11] <0 || data[11]>1) */ - if (data[12] < 0 || data[12] > 3) { - printk("\nThe selection of singlechannel/scan selection is in error\n"); - i_err++; - } /* if(data[12] < 0 || data[12]> 3) */ - if (data[13] < 0 || data[13] > 16) { - printk("\nThe selection of number of channels is in error\n"); - i_err++; - } /* if(data[13] <0 ||data[13] >15) */ + /******************************/ + /* Write the command register */ + /******************************/ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* - i_ChannelCount=data[13]; - i_ScanType=data[12]; - i_ADDIDATAPolarity = data[2]; - i_ADDIDATAGain=data[1]; - i_ADDIDATAConversionTime=data[6]; - i_ADDIDATAConversionTimeUnit=data[7]; - i_ADDIDATAType=data[0]; - */ + /* outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8); */ + outl(ui_CommandRegister, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - /* Save acquisition configuration for the actual board */ - s_BoardInfos[dev->minor].i_ChannelCount = data[13]; - s_BoardInfos[dev->minor].i_ScanType = data[12]; - s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2]; - s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1]; - s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6]; - s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7]; - s_BoardInfos[dev->minor].i_ADDIDATAType = data[0]; - /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - s_BoardInfos[dev->minor].i_ConnectionType = data[5]; - /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* END JK 06.07.04: Management of sevrals boards */ + /*****************************/ + /*Test if interrupt is enable */ + /*****************************/ + /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ + if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) { + do { + /*************************/ + /*Read the EOC Status bit */ + /*************************/ - /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); /* 7 is the maximal number of channels */ - /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ + ui_EOC = inl(devpriv->iobase + + s_BoardInfos[dev->minor].i_Offset + 20) & 1; - /* BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards */ - /* while(i_InterruptFlag==1) */ - while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { -#ifndef MSXBOX - udelay(1); -#else - /* In the case where the driver is compiled for the MSX-Box */ - /* we used a printk to have a little delay because udelay */ - /* seems to be broken under the MSX-Box. */ - /* This solution hat to be studied. */ - printk(""); -#endif - } - /* END JK 02.07.04 : This while can't be do, it block the process when using severals boards */ - - ui_ChannelNo = CR_CHAN(insn->chanspec); /* get the channel */ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=ui_ChannelNo; */ - /* ui_Channel_num =ui_ChannelNo; */ - - s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo; - s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo; + } while (ui_EOC != 1); - /* END JK 06.07.04: Management of sevrals boards */ + /***************************************/ + /* Read the digital value of the input */ + /***************************************/ - if (data[5] == 0) { - if (ui_ChannelNo < 0 || ui_ChannelNo > 15) { - printk("\nThe Selection of the channel is in error\n"); - i_err++; - } /* if(ui_ChannelNo<0 || ui_ChannelNo>15) */ - } /* if(data[5]==0) */ - else { - if (data[14] == 2) { - if (ui_ChannelNo < 0 || ui_ChannelNo > 3) { - printk("\nThe Selection of the channel is in error\n"); - i_err++; - } /* if(ui_ChannelNo<0 || ui_ChannelNo>3) */ - } /* if(data[14]==2) */ - else { - if (ui_ChannelNo < 0 || ui_ChannelNo > 7) { - printk("\nThe Selection of the channel is in error\n"); - i_err++; - } /* if(ui_ChannelNo<0 || ui_ChannelNo>7) */ - } /* elseif(data[14]==2) */ - } /* elseif(data[5]==0) */ - if (data[12] == 0 || data[12] == 1) { - switch (data[5]) { - case 0: - if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=3) */ - if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=64; */ - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=7) */ - if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=8 && ui_ChannelNo <=11) */ - if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=12 && ui_ChannelNo <=15) */ - break; - case 1: - if (data[14] == 2) { - if (ui_ChannelNo == 0) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==0 ) */ - if (ui_ChannelNo == 1) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==1) */ - if (ui_ChannelNo == 2) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==2 ) */ - if (ui_ChannelNo == 3) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo ==3) */ + /* data[0] = inl (devpriv->iobase+i_Offset + 28); */ + data[0] = + inl(devpriv->iobase + + s_BoardInfos[dev->minor].i_Offset + 28); + /* END JK 06.07.04: Management of sevrals boards */ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=0; */ - s_BoardInfos[dev->minor].i_ChannelNo = 0; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = 0; - break; - } /* if(data[14]==2) */ - if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=1) */ - if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=i_ChannelNo-2; */ - /* i_Offset=64; */ - s_BoardInfos[dev->minor].i_ChannelNo = - s_BoardInfos[dev->minor].i_ChannelNo - - 2; - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = ui_ChannelNo - 2; - } /* if(ui_ChannelNo >=2 && ui_ChannelNo <=3) */ - if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=i_ChannelNo-4; */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_ChannelNo = - s_BoardInfos[dev->minor].i_ChannelNo - - 4; - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = ui_ChannelNo - 4; - } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=5) */ - if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_ChannelNo=i_ChannelNo-6; */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_ChannelNo = - s_BoardInfos[dev->minor].i_ChannelNo - - 6; - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - ui_ChannelNo = ui_ChannelNo - 6; - } /* if(ui_ChannelNo >=6 && ui_ChannelNo <=7) */ - break; + } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ + return 0; +} - default: - printk("\n This selection of polarity does not exist\n"); - i_err++; - } /* switch(data[2]) */ - } /* if(data[12]==0 || data[12]==1) */ - else { - switch (data[11]) { - case 1: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=0; */ - s_BoardInfos[dev->minor].i_Offset = 0; - /* END JK 06.07.04: Management of sevrals boards */ - break; - case 2: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=64; */ - s_BoardInfos[dev->minor].i_Offset = 64; - /* END JK 06.07.04: Management of sevrals boards */ - break; - case 3: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=128; */ - s_BoardInfos[dev->minor].i_Offset = 128; - /* END JK 06.07.04: Management of sevrals boards */ - break; - case 4: - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Offset=192; */ - s_BoardInfos[dev->minor].i_Offset = 192; - /* END JK 06.07.04: Management of sevrals boards */ - break; - default: - printk("\nError in module selection\n"); - i_err++; - } /* switch(data[11]) */ - } /* elseif(data[12]==0 || data[12]==1) */ - if (i_err) { - i_APCI3200_Reset(dev); - return -EINVAL; - } - /* if(i_ScanType!=1) */ - if (s_BoardInfos[dev->minor].i_ScanType != 1) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Count=0; */ - /* i_Sum=0; */ - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(i_ScanType!=1) */ +static int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, + unsigned int *data) +{ + struct addi_private *devpriv = dev->private; + unsigned int ui_Temp = 0, ui_EOC = 0; + unsigned int ui_CommandRegister = 0; - ul_Config = - data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) | - (data[4] << 9); /* BEGIN JK 06.07.04: Management of sevrals boards */ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ /*********************************/ /* Write the channel to configure */ /*********************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4); */ - outl(0 | ui_ChannelNo, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4); - /* END JK 06.07.04: Management of sevrals boards */ + /* Begin JK 20.10.2004: This seems not necessary ! */ + /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */ + /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */ + /* End JK 20.10.2004: This seems not necessary ! */ - /* BEGIN JK 06.07.04: Management of sevrals boards */ + /*******************************/ + /* Set the convert timing unit */ + /*******************************/ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ + /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ + outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); /**************************/ - /* Reset the configuration */ + /* Set the convert timing */ /**************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl(0 , devpriv->iobase+i_Offset + 0x0); */ - outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0); - /* END JK 06.07.04: Management of sevrals boards */ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ + outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); + /*****************************/ + /*Read the calibration offset */ + /*****************************/ + /* ui_Temp = inl(devpriv->iobase+i_Offset + 12); */ + ui_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /* BEGIN JK 06.07.04: Management of sevrals boards */ + /*********************************/ + /*Configure the Offset Conversion */ + /*********************************/ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ + /* outl((ui_Temp | 0x00020000), devpriv->iobase+i_Offset + 12); */ + outl((ui_Temp | 0x00020000), + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); + /*******************************/ + /*Initialise ui_CommandRegister */ + /*******************************/ - /***************************/ - /* Write the configuration */ - /***************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl(ul_Config , devpriv->iobase+i_Offset + 0x0); */ - outl(ul_Config, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0); - /* END JK 06.07.04: Management of sevrals boards */ + ui_CommandRegister = 0; + + /*********************************/ + /*Test if the interrupt is enable */ + /*********************************/ + + /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ + if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) { + + /**********************/ + /*Enable the interrupt */ + /**********************/ + + ui_CommandRegister = ui_CommandRegister | 0x00100000; + + } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ + + /**********************/ + /*Start the conversion */ + /**********************/ + ui_CommandRegister = ui_CommandRegister | 0x00080000; /***************************/ - /*Reset the calibration bit */ + /*Write the command regiter */ /***************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ul_Temp = inl(devpriv->iobase+i_Offset + 12); */ - ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /* END JK 06.07.04: Management of sevrals boards */ - - /* BEGIN JK 06.07.04: Management of sevrals boards */ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; - /* END JK 06.07.04: Management of sevrals boards */ + /* outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8); */ + outl(ui_CommandRegister, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12); */ - outl((ul_Temp & 0xFFF9FFFF), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /* END JK 06.07.04: Management of sevrals boards */ + /*****************************/ + /*Test if interrupt is enable */ + /*****************************/ - if (data[9] == 1) { - devpriv->tsk_Current = current; - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_InterruptFlag=1; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 1; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(data[9]==1) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* else if(data[9]==1) */ + /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ + if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Initialised=1; */ - s_BoardInfos[dev->minor].i_Initialised = 1; - /* END JK 06.07.04: Management of sevrals boards */ + do { + /*******************/ + /*Read the EOC flag */ + /*******************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_ScanType==1) */ - if (s_BoardInfos[dev->minor].i_ScanType == 1) - /* END JK 06.07.04: Management of sevrals boards */ - { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* i_Sum=i_Sum+1; */ - s_BoardInfos[dev->minor].i_Sum = - s_BoardInfos[dev->minor].i_Sum + 1; - /* END JK 06.07.04: Management of sevrals boards */ + /* ui_EOC = inl (devpriv->iobase+i_Offset + 20) & 1; */ + ui_EOC = inl(devpriv->iobase + + s_BoardInfos[dev->minor].i_Offset + 20) & 1; - insn->unused[0] = 0; - i_APCI3200_ReadAnalogInput(dev, s, insn, &ui_Dummy); - } + } while (ui_EOC != 1); - return insn->n; + /**************************************************/ + /*Read the digital value of the calibration Offset */ + /**************************************************/ + + /* data[0] = inl(devpriv->iobase+i_Offset+ 28); */ + data[0] = + inl(devpriv->iobase + + s_BoardInfos[dev->minor].i_Offset + 28); + } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ + return 0; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadAnalogInput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read value of the selected channel | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int ui_NoOfChannels : No Of Channels To read | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : Digital Value Of Input | - | data[1] : Calibration Offset Value | - | data[2] : Calibration Gain Value - | data[3] : CJC value - | data[4] : CJC offset value - | data[5] : CJC gain value - | Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values - | data[6] : CJC current source from eeprom - | data[7] : Channel current source from eeprom - | data[8] : Channle gain factor from eeprom - | End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, + unsigned int *data) { - unsigned int ui_DummyValue = 0; - int i_ConvertCJCCalibration; - int i = 0; - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_Initialised==0) */ - if (s_BoardInfos[dev->minor].i_Initialised == 0) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_APCI3200_Reset(dev); - return -EINVAL; - } /* if(i_Initialised==0); */ + struct addi_private *devpriv = dev->private; + unsigned int ui_EOC = 0; + int ui_CommandRegister = 0; -#ifdef PRINT_INFO - printk("\n insn->unused[0] = %i", insn->unused[0]); -#endif + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /*********************************/ + /* Write the channel to configure */ + /*********************************/ + /* Begin JK 20.10.2004: This seems not necessary ! */ + /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */ + /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */ + /* End JK 20.10.2004: This seems not necessary ! */ - switch (insn->unused[0]) { - case 0: + /***************************/ + /*Read the calibration gain */ + /***************************/ + /*******************************/ + /* Set the convert timing unit */ + /*******************************/ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ + outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); + /**************************/ + /* Set the convert timing */ + /**************************/ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ + outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); + /*******************************/ + /*Configure the Gain Conversion */ + /*******************************/ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* outl(0x00040000 , devpriv->iobase+i_Offset + 12); */ + outl(0x00040000, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - i_APCI3200_Read1AnalogInputChannel(dev, s, insn, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+0]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 0] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ + /*******************************/ + /*Initialise ui_CommandRegister */ + /*******************************/ - /* Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - i_APCI3200_GetChannelCalibrationValue(dev, - s_BoardInfos[dev->minor].ui_Channel_num, - &s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 6], - &s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 7], - &s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev->minor]. - i_Count + 8]); + ui_CommandRegister = 0; -#ifdef PRINT_INFO - printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]); + /*********************************/ + /*Test if the interrupt is enable */ + /*********************************/ - printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]); + /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ + if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) { - printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]); -#endif + /**********************/ + /*Enable the interrupt */ + /**********************/ - /* End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + ui_CommandRegister = ui_CommandRegister | 0x00100000; - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */ - if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2) - && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE) - && (s_BoardInfos[dev->minor].i_CJCAvailable == 1)) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_APCI3200_ReadCJCValue(dev, &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 3] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 3]=0; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 3] = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */ + } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */ - if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) - && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_APCI3200_ReadCalibrationOffsetValue(dev, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 1] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - i_APCI3200_ReadCalibrationGainValue(dev, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos[dev-> - minor].i_Count + 2] = ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */ + /**********************/ + /*Start the conversion */ + /**********************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1)) */ - if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2) - && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE) - && (s_BoardInfos[dev->minor].i_CJCAvailable == 1)) - /* END JK 06.07.04: Management of sevrals boards */ - { - /**********************************************************/ - /*Test if the Calibration channel must be read for the CJC */ - /**********************************************************/ - /**********************************/ - /*Test if the polarity is the same */ - /**********************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ - if (s_BoardInfos[dev->minor].i_CJCPolarity != - s_BoardInfos[dev->minor].i_ADDIDATAPolarity) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_ConvertCJCCalibration = 1; - } /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_CJCGain==i_ADDIDATAGain) */ - if (s_BoardInfos[dev->minor].i_CJCGain == - s_BoardInfos[dev->minor].i_ADDIDATAGain) - /* END JK 06.07.04: Management of sevrals boards */ - { - i_ConvertCJCCalibration = 0; - } /* if(i_CJCGain==i_ADDIDATAGain) */ - else { - i_ConvertCJCCalibration = 1; - } /* elseif(i_CJCGain==i_ADDIDATAGain) */ - } /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */ - if (i_ConvertCJCCalibration == 1) { - i_APCI3200_ReadCJCCalOffset(dev, - &ui_DummyValue); - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+4]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 4] = - ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ + ui_CommandRegister = ui_CommandRegister | 0x00080000; + /***************************/ + /*Write the command regiter */ + /***************************/ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8); */ + outl(ui_CommandRegister, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue); + /*****************************/ + /*Test if interrupt is enable */ + /*****************************/ - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+5]=ui_DummyValue; */ - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 5] = - ui_DummyValue; - /* END JK 06.07.04: Management of sevrals boards */ - } /* if(i_ConvertCJCCalibration==1) */ - else { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_InterruptChannelValue[i_Count+4]=0; */ - /* ui_InterruptChannelValue[i_Count+5]=0; */ + /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ + if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) { - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 4] = 0; - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[s_BoardInfos - [dev->minor].i_Count + 5] = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } /* elseif(i_ConvertCJCCalibration==1) */ - } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */ + do { - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* if(i_ScanType!=1) */ - if (s_BoardInfos[dev->minor].i_ScanType != 1) { - /* i_Count=0; */ - s_BoardInfos[dev->minor].i_Count = 0; - } /* if(i_ScanType!=1) */ - else { - /* i_Count=i_Count +6; */ - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6; */ - s_BoardInfos[dev->minor].i_Count = - s_BoardInfos[dev->minor].i_Count + 9; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } /* else if(i_ScanType!=1) */ + /*******************/ + /*Read the EOC flag */ + /*******************/ - /* if((i_ScanType==1) &&(i_InterruptFlag==1)) */ - if ((s_BoardInfos[dev->minor].i_ScanType == 1) - && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) { - /* i_Count=i_Count-6; */ - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6; */ - s_BoardInfos[dev->minor].i_Count = - s_BoardInfos[dev->minor].i_Count - 9; - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } - /* if(i_ScanType==0) */ - if (s_BoardInfos[dev->minor].i_ScanType == 0) { - /* - data[0]= ui_InterruptChannelValue[0]; - data[1]= ui_InterruptChannelValue[1]; - data[2]= ui_InterruptChannelValue[2]; - data[3]= ui_InterruptChannelValue[3]; - data[4]= ui_InterruptChannelValue[4]; - data[5]= ui_InterruptChannelValue[5]; - */ -#ifdef PRINT_INFO - printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];"); -#endif - data[0] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[0]; - data[1] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[1]; - data[2] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[2]; - data[3] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[3]; - data[4] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[4]; - data[5] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[5]; + /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ + ui_EOC = inl(devpriv->iobase + + s_BoardInfos[dev->minor].i_Offset + 20) & 1; - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /* printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]); */ - i_APCI3200_GetChannelCalibrationValue(dev, - s_BoardInfos[dev->minor].ui_Channel_num, - &data[6], &data[7], &data[8]); - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - } - break; - case 1: + } while (ui_EOC != 1); - for (i = 0; i < insn->n; i++) { - /* data[i]=ui_InterruptChannelValue[i]; */ - data[i] = - s_BoardInfos[dev->minor]. - ui_InterruptChannelValue[i]; - } + /************************************************/ + /*Read the digital value of the calibration Gain */ + /************************************************/ - /* i_Count=0; */ - /* i_Sum=0; */ - /* if(i_ScanType==1) */ - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - if (s_BoardInfos[dev->minor].i_ScanType == 1) { - /* i_Initialised=0; */ - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - /* END JK 06.07.04: Management of sevrals boards */ - } - break; - default: - printk("\nThe parameters passed are in error\n"); - i_APCI3200_Reset(dev); - return -EINVAL; - } /* switch(insn->unused[0]) */ + /* data[0] = inl(devpriv->iobase+i_Offset + 28); */ + data[0] = + inl(devpriv->iobase + + s_BoardInfos[dev->minor].i_Offset + 28); - return insn->n; + } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ + return 0; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_Read1AnalogInputChannel | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read value of the selected channel | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int ui_NoOfChannel : Channel No to read | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : Digital Value read | - | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3200_ReadCJCValue(struct comedi_device *dev, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_EOC = 0; - unsigned int ui_ChannelNo = 0; - unsigned int ui_CommandRegister = 0; - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* ui_ChannelNo=i_ChannelNo; */ - ui_ChannelNo = s_BoardInfos[dev->minor].i_ChannelNo; + int ui_CommandRegister = 0; - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /*********************************/ - /* Write the channel to configure */ - /*********************************/ - /* Begin JK 20.10.2004: Bad channel value is used when using differential mode */ - /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */ - /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */ - outl(0 | s_BoardInfos[dev->minor].i_ChannelNo, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4); - /* End JK 20.10.2004: Bad channel value is used when using differential mode */ + /******************************/ + /*Set the converting time unit */ + /******************************/ - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; @@ -1688,7 +1086,6 @@ int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ /* Set the convert timing */ /**************************/ @@ -1700,44 +1097,58 @@ int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - /**************************************************************************/ - /* Set the start end stop index to the selected channel and set the start */ - /**************************************************************************/ - - ui_CommandRegister = ui_ChannelNo | (ui_ChannelNo << 8) | 0x80000; + /******************************/ + /*Configure the CJC Conversion */ + /******************************/ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* outl( 0x00000400 , devpriv->iobase+i_Offset + 4); */ + outl(0x00000400, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); + /*******************************/ + /*Initialise dw_CommandRegister */ + /*******************************/ + ui_CommandRegister = 0; /*********************************/ /*Test if the interrupt is enable */ /*********************************/ - /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) { - /************************/ - /* Enable the interrupt */ - /************************/ + /**********************/ + /*Enable the interrupt */ + /**********************/ ui_CommandRegister = ui_CommandRegister | 0x00100000; - } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ + } - /******************************/ - /* Write the command register */ - /******************************/ + /**********************/ + /*Start the conversion */ + /**********************/ + + ui_CommandRegister = ui_CommandRegister | 0x00080000; + + /***************************/ + /*Write the command regiter */ + /***************************/ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; - - /* outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8); */ + /* outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8); */ outl(ui_CommandRegister, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); /*****************************/ /*Test if interrupt is enable */ /*****************************/ + /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) { do { - /*************************/ - /*Read the EOC Status bit */ - /*************************/ + + /*******************/ + /*Read the EOC flag */ + /*******************/ /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ ui_EOC = inl(devpriv->iobase + @@ -1745,58 +1156,29 @@ int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, } while (ui_EOC != 1); - /***************************************/ - /* Read the digital value of the input */ - /***************************************/ + /***********************************/ + /*Read the digital value of the CJC */ + /***********************************/ - /* data[0] = inl (devpriv->iobase+i_Offset + 28); */ + /* data[0] = inl(devpriv->iobase+i_Offset + 28); */ data[0] = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 28); - /* END JK 06.07.04: Management of sevrals boards */ - } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ + } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ return 0; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadCalibrationOffsetValue | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read calibration offset value of the selected channel| - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : Calibration offset Value | - | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned int *data) +static int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_Temp = 0, ui_EOC = 0; - unsigned int ui_CommandRegister = 0; - - /* BEGIN JK 06.07.04: Management of sevrals boards */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /*********************************/ - /* Write the channel to configure */ - /*********************************/ - /* Begin JK 20.10.2004: This seems not necessary ! */ - /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */ - /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */ - /* End JK 20.10.2004: This seems not necessary ! */ + unsigned int ui_EOC = 0; + int ui_CommandRegister = 0; + /*******************************************/ + /*Read calibration offset value for the CJC */ + /*******************************************/ /*******************************/ /* Set the convert timing unit */ /*******************************/ @@ -1815,80 +1197,69 @@ int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned in /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - /*****************************/ - /*Read the calibration offset */ - /*****************************/ - /* ui_Temp = inl(devpriv->iobase+i_Offset + 12); */ - ui_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - + /******************************/ + /*Configure the CJC Conversion */ + /******************************/ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* outl(0x00000400 , devpriv->iobase+i_Offset + 4); */ + outl(0x00000400, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); /*********************************/ /*Configure the Offset Conversion */ /*********************************/ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; - /* outl((ui_Temp | 0x00020000), devpriv->iobase+i_Offset + 12); */ - outl((ui_Temp | 0x00020000), + /* outl(0x00020000, devpriv->iobase+i_Offset + 12); */ + outl(0x00020000, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); /*******************************/ /*Initialise ui_CommandRegister */ /*******************************/ - ui_CommandRegister = 0; - /*********************************/ /*Test if the interrupt is enable */ /*********************************/ /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) { - /**********************/ /*Enable the interrupt */ /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ + } /**********************/ /*Start the conversion */ /**********************/ ui_CommandRegister = ui_CommandRegister | 0x00080000; - /***************************/ /*Write the command regiter */ /***************************/ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8); */ + /* outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8); */ outl(ui_CommandRegister, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - - /*****************************/ - /*Test if interrupt is enable */ - /*****************************/ - /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) { - do { /*******************/ /*Read the EOC flag */ /*******************/ - - /* ui_EOC = inl (devpriv->iobase+i_Offset + 20) & 1; */ + /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ ui_EOC = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 20) & 1; - } while (ui_EOC != 1); /**************************************************/ /*Read the digital value of the calibration Offset */ /**************************************************/ - - /* data[0] = inl(devpriv->iobase+i_Offset+ 28); */ + /* data[0] = inl(devpriv->iobase+i_Offset + 28); */ data[0] = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 28); @@ -1896,46 +1267,13 @@ int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned in return 0; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadCalibrationGainValue | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read calibration gain value of the selected channel | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : Calibration gain Value Of Input | - | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int *data) +static int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_EOC = 0; int ui_CommandRegister = 0; - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /*********************************/ - /* Write the channel to configure */ - /*********************************/ - /* Begin JK 20.10.2004: This seems not necessary ! */ - /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */ - /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */ - /* End JK 20.10.2004: This seems not necessary ! */ - - /***************************/ - /*Read the calibration gain */ - /***************************/ /*******************************/ /* Set the convert timing unit */ /*******************************/ @@ -1954,41 +1292,42 @@ int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); + /******************************/ + /*Configure the CJC Conversion */ + /******************************/ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* outl(0x00000400,devpriv->iobase+i_Offset + 4); */ + outl(0x00000400, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); /*******************************/ /*Configure the Gain Conversion */ /*******************************/ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; - /* outl(0x00040000 , devpriv->iobase+i_Offset + 12); */ + /* outl(0x00040000,devpriv->iobase+i_Offset + 12); */ outl(0x00040000, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); /*******************************/ - /*Initialise ui_CommandRegister */ + /*Initialise dw_CommandRegister */ /*******************************/ - ui_CommandRegister = 0; - /*********************************/ /*Test if the interrupt is enable */ /*********************************/ - /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) { - /**********************/ /*Enable the interrupt */ /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - - } /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ - + } /**********************/ /*Start the conversion */ /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00080000; /***************************/ /*Write the command regiter */ @@ -1996,426 +1335,861 @@ int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8); */ + /* outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8); */ outl(ui_CommandRegister, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - - /*****************************/ - /*Test if interrupt is enable */ - /*****************************/ - /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) { - do { - /*******************/ /*Read the EOC flag */ /*******************/ - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ ui_EOC = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 20) & 1; - } while (ui_EOC != 1); - /************************************************/ /*Read the digital value of the calibration Gain */ /************************************************/ - - /* data[0] = inl(devpriv->iobase+i_Offset + 28); */ + /* data[0] = inl (devpriv->iobase+i_Offset + 28); */ data[0] = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 28); - } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ return 0; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadCJCValue | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read CJC value of the selected channel | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : CJC Value | - | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data) +static int i_APCI3200_Reset(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - int ui_CommandRegister = 0; + int i_Temp; + unsigned int dw_Dummy; - /******************************/ - /*Set the converting time unit */ - /******************************/ + /* i_InterruptFlag=0; */ + /* i_Initialised==0; */ + /* i_Count=0; */ + /* i_Sum=0; */ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; + s_BoardInfos[dev->minor].i_InterruptFlag = 0; + s_BoardInfos[dev->minor].i_Initialised = 0; + s_BoardInfos[dev->minor].i_Count = 0; + s_BoardInfos[dev->minor].i_Sum = 0; + s_BoardInfos[dev->minor].b_StructInitialized = 0; - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; + outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); + /* Enable the interrupt for the controller */ + dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); + outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); + outl(0, devpriv->i_IobaseAddon); /* Resets the output */ + /***************/ + /*Empty the buffer */ + /**************/ + for (i_Temp = 0; i_Temp <= 95; i_Temp++) { + /* ui_InterruptChannelValue[i_Temp]=0; */ + s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0; + } /* for(i_Temp=0;i_Temp<=95;i_Temp++) */ + /*****************************/ + /*Reset the START and IRQ bit */ + /*****************************/ + for (i_Temp = 0; i_Temp <= 192;) { + while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ; + outl(0, devpriv->iobase + i_Temp + 8); + i_Temp = i_Temp + 64; + } /* for(i_Temp=0;i_Temp<=192;i_Temp+64) */ + return 0; +} - /******************************/ - /*Configure the CJC Conversion */ - /******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; +/* + * Read value of the selected channel + * + * data[0] : Digital Value Of Input + * data[1] : Calibration Offset Value + * data[2] : Calibration Gain Value + * data[3] : CJC value + * data[4] : CJC offset value + * data[5] : CJC gain value + * data[6] : CJC current source from eeprom + * data[7] : Channel current source from eeprom + * data[8] : Channle gain factor from eeprom + */ +static int i_APCI3200_ReadAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int ui_DummyValue = 0; + int i_ConvertCJCCalibration; + int i = 0; - /* outl( 0x00000400 , devpriv->iobase+i_Offset + 4); */ - outl(0x00000400, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /*******************************/ - /*Initialise dw_CommandRegister */ - /*******************************/ - ui_CommandRegister = 0; - /*********************************/ - /*Test if the interrupt is enable */ - /*********************************/ - /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) { - /**********************/ - /*Enable the interrupt */ - /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if(i_Initialised==0) */ + if (s_BoardInfos[dev->minor].i_Initialised == 0) + /* END JK 06.07.04: Management of sevrals boards */ + { + i_APCI3200_Reset(dev); + return -EINVAL; + } /* if(i_Initialised==0); */ - /**********************/ - /*Start the conversion */ - /**********************/ +#ifdef PRINT_INFO + printk("\n insn->unused[0] = %i", insn->unused[0]); +#endif - ui_CommandRegister = ui_CommandRegister | 0x00080000; + switch (insn->unused[0]) { + case 0: - /***************************/ - /*Write the command regiter */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); + i_APCI3200_Read1AnalogInputChannel(dev, s, insn, + &ui_DummyValue); + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count+0]=ui_DummyValue; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev->minor]. + i_Count + 0] = ui_DummyValue; + /* END JK 06.07.04: Management of sevrals boards */ - /*****************************/ - /*Test if interrupt is enable */ - /*****************************/ + /* Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + i_APCI3200_GetChannelCalibrationValue(dev, + s_BoardInfos[dev->minor].ui_Channel_num, + &s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev->minor]. + i_Count + 6], + &s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev->minor]. + i_Count + 7], + &s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev->minor]. + i_Count + 8]); - /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) { - do { +#ifdef PRINT_INFO + printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]); - /*******************/ - /*Read the EOC flag */ - /*******************/ + printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]); - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; + printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]); +#endif - } while (ui_EOC != 1); + /* End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - /***********************************/ - /*Read the digital value of the CJC */ - /***********************************/ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */ + if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2) + && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE) + && (s_BoardInfos[dev->minor].i_CJCAvailable == 1)) + /* END JK 06.07.04: Management of sevrals boards */ + { + i_APCI3200_ReadCJCValue(dev, &ui_DummyValue); + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev-> + minor].i_Count + 3] = ui_DummyValue; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */ + else { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count + 3]=0; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev-> + minor].i_Count + 3] = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */ - /* data[0] = inl(devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */ + if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) + && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)) + /* END JK 06.07.04: Management of sevrals boards */ + { + i_APCI3200_ReadCalibrationOffsetValue(dev, + &ui_DummyValue); + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev-> + minor].i_Count + 1] = ui_DummyValue; + /* END JK 06.07.04: Management of sevrals boards */ + i_APCI3200_ReadCalibrationGainValue(dev, + &ui_DummyValue); + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos[dev-> + minor].i_Count + 2] = ui_DummyValue; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */ - } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ - return 0; -} + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1)) */ + if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2) + && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE) + && (s_BoardInfos[dev->minor].i_CJCAvailable == 1)) + /* END JK 06.07.04: Management of sevrals boards */ + { + /**********************************************************/ + /*Test if the Calibration channel must be read for the CJC */ + /**********************************************************/ + /**********************************/ + /*Test if the polarity is the same */ + /**********************************/ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ + if (s_BoardInfos[dev->minor].i_CJCPolarity != + s_BoardInfos[dev->minor].i_ADDIDATAPolarity) + /* END JK 06.07.04: Management of sevrals boards */ + { + i_ConvertCJCCalibration = 1; + } /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */ + else { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if(i_CJCGain==i_ADDIDATAGain) */ + if (s_BoardInfos[dev->minor].i_CJCGain == + s_BoardInfos[dev->minor].i_ADDIDATAGain) + /* END JK 06.07.04: Management of sevrals boards */ + { + i_ConvertCJCCalibration = 0; + } /* if(i_CJCGain==i_ADDIDATAGain) */ + else { + i_ConvertCJCCalibration = 1; + } /* elseif(i_CJCGain==i_ADDIDATAGain) */ + } /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */ + if (i_ConvertCJCCalibration == 1) { + i_APCI3200_ReadCJCCalOffset(dev, + &ui_DummyValue); + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count+4]=ui_DummyValue; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos + [dev->minor].i_Count + 4] = + ui_DummyValue; + /* END JK 06.07.04: Management of sevrals boards */ -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadCJCCalOffset | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read CJC calibration offset value of the selected channel - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : CJC calibration offset Value - | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - int ui_CommandRegister = 0; + i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue); - /*******************************************/ - /*Read calibration offset value for the CJC */ - /*******************************************/ - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - /******************************/ - /*Configure the CJC Conversion */ - /******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00000400 , devpriv->iobase+i_Offset + 4); */ - outl(0x00000400, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /*********************************/ - /*Configure the Offset Conversion */ - /*********************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00020000, devpriv->iobase+i_Offset + 12); */ - outl(0x00020000, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); - /*******************************/ - /*Initialise ui_CommandRegister */ - /*******************************/ - ui_CommandRegister = 0; - /*********************************/ - /*Test if the interrupt is enable */ - /*********************************/ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count+5]=ui_DummyValue; */ + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos + [dev->minor].i_Count + 5] = + ui_DummyValue; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(i_ConvertCJCCalibration==1) */ + else { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ui_InterruptChannelValue[i_Count+4]=0; */ + /* ui_InterruptChannelValue[i_Count+5]=0; */ - /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) { - /**********************/ - /*Enable the interrupt */ - /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00100000; + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos + [dev->minor].i_Count + 4] = 0; + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[s_BoardInfos + [dev->minor].i_Count + 5] = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* elseif(i_ConvertCJCCalibration==1) */ + } /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */ - } + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if(i_ScanType!=1) */ + if (s_BoardInfos[dev->minor].i_ScanType != 1) { + /* i_Count=0; */ + s_BoardInfos[dev->minor].i_Count = 0; + } /* if(i_ScanType!=1) */ + else { + /* i_Count=i_Count +6; */ + /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6; */ + s_BoardInfos[dev->minor].i_Count = + s_BoardInfos[dev->minor].i_Count + 9; + /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + } /* else if(i_ScanType!=1) */ - /**********************/ - /*Start the conversion */ - /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00080000; - /***************************/ - /*Write the command regiter */ - /***************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) { - do { - /*******************/ - /*Read the EOC flag */ - /*******************/ - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - } while (ui_EOC != 1); + /* if((i_ScanType==1) &&(i_InterruptFlag==1)) */ + if ((s_BoardInfos[dev->minor].i_ScanType == 1) + && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) { + /* i_Count=i_Count-6; */ + /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6; */ + s_BoardInfos[dev->minor].i_Count = + s_BoardInfos[dev->minor].i_Count - 9; + /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + } + /* if(i_ScanType==0) */ + if (s_BoardInfos[dev->minor].i_ScanType == 0) { + /* + data[0]= ui_InterruptChannelValue[0]; + data[1]= ui_InterruptChannelValue[1]; + data[2]= ui_InterruptChannelValue[2]; + data[3]= ui_InterruptChannelValue[3]; + data[4]= ui_InterruptChannelValue[4]; + data[5]= ui_InterruptChannelValue[5]; + */ +#ifdef PRINT_INFO + printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];"); +#endif + data[0] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[0]; + data[1] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[1]; + data[2] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[2]; + data[3] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[3]; + data[4] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[4]; + data[5] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[5]; - /**************************************************/ - /*Read the digital value of the calibration Offset */ - /**************************************************/ - /* data[0] = inl(devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ - return 0; + /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + /* printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]); */ + i_APCI3200_GetChannelCalibrationValue(dev, + s_BoardInfos[dev->minor].ui_Channel_num, + &data[6], &data[7], &data[8]); + /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + } + break; + case 1: + + for (i = 0; i < insn->n; i++) { + /* data[i]=ui_InterruptChannelValue[i]; */ + data[i] = + s_BoardInfos[dev->minor]. + ui_InterruptChannelValue[i]; + } + + /* i_Count=0; */ + /* i_Sum=0; */ + /* if(i_ScanType==1) */ + s_BoardInfos[dev->minor].i_Count = 0; + s_BoardInfos[dev->minor].i_Sum = 0; + if (s_BoardInfos[dev->minor].i_ScanType == 1) { + /* i_Initialised=0; */ + /* i_InterruptFlag=0; */ + s_BoardInfos[dev->minor].i_Initialised = 0; + s_BoardInfos[dev->minor].i_InterruptFlag = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } + break; + default: + printk("\nThe parameters passed are in error\n"); + i_APCI3200_Reset(dev); + return -EINVAL; + } /* switch(insn->unused[0]) */ + + return insn->n; } /* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_ReadCJCGainValue | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Read CJC calibration gain value - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | unsigned int ui_NoOfChannels : No Of Channels To read | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : CJC calibration gain value - | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data) + * Configures The Analog Input Subdevice + * + * data[0] = 0 Normal AI + * = 1 RTD + * = 2 THERMOCOUPLE + * data[1] = Gain To Use + * data[2] = 0 Bipolar + * = 1 Unipolar + * data[3] = Offset Range + * data[4] = 0 DC Coupling + * = 1 AC Coupling + * data[5] = 0 Single + * = 1 Differential + * data[6] = TimerReloadValue + * data[7] = ConvertingTimeUnit + * data[8] = 0 Analog voltage measurement + * = 1 Resistance measurement + * = 2 Temperature measurement + * data[9] = 0 Interrupt Disable + * = 1 INterrupt Enable + * data[10] = Type of Thermocouple + * data[11] = single channel Module Number + * data[12] = 0 Single Read + * = 1 Read more channel + * = 2 Single scan + * = 3 Continuous Scan + * data[13] = Number of channels to read + * data[14] = 0 RTD not used + * = 1 RTD 2 wire connection + * = 2 RTD 3 wire connection + * = 3 RTD 4 wire connection + */ +static int i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_EOC = 0; - int ui_CommandRegister = 0; + unsigned int ul_Config = 0, ul_Temp = 0; + unsigned int ui_ChannelNo = 0; + unsigned int ui_Dummy = 0; + int i_err = 0; - /*******************************/ - /* Set the convert timing unit */ - /*******************************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36); - /**************************/ - /* Set the convert timing */ - /**************************/ + /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + +#ifdef PRINT_INFO + int i = 0, i2 = 0; +#endif + /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* Initialize the structure */ + if (s_BoardInfos[dev->minor].b_StructInitialized != 1) { + s_BoardInfos[dev->minor].i_CJCAvailable = 1; + s_BoardInfos[dev->minor].i_CJCPolarity = 0; + s_BoardInfos[dev->minor].i_CJCGain = 2; /* changed from 0 to 2 */ + s_BoardInfos[dev->minor].i_InterruptFlag = 0; + s_BoardInfos[dev->minor].i_AutoCalibration = 0; /* : auto calibration */ + s_BoardInfos[dev->minor].i_ChannelCount = 0; + s_BoardInfos[dev->minor].i_Sum = 0; + s_BoardInfos[dev->minor].ui_Channel_num = 0; + s_BoardInfos[dev->minor].i_Count = 0; + s_BoardInfos[dev->minor].i_Initialised = 0; + s_BoardInfos[dev->minor].b_StructInitialized = 1; + + /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + s_BoardInfos[dev->minor].i_ConnectionType = 0; + /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + + /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + memset(s_BoardInfos[dev->minor].s_Module, 0, + sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE])); + + v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc, + &s_BoardInfos[dev->minor]); + +#ifdef PRINT_INFO + for (i = 0; i < MAX_MODULE; i++) { + printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i, + s_BoardInfos[dev->minor].s_Module[i]. + ul_CurrentSourceCJC); + + for (i2 = 0; i2 < 5; i2++) { + printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]); + } + + for (i2 = 0; i2 < 8; i2++) { + printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]); + } + + for (i2 = 0; i2 < 8; i2++) { + printk("\n s_Module[%i].w_GainValue [%i] = %u", + i, i2, + s_BoardInfos[dev->minor].s_Module[i]. + w_GainValue[i2]); + } + } +#endif + /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + } + + if (data[0] != 0 && data[0] != 1 && data[0] != 2) { + printk("\nThe selection of acquisition type is in error\n"); + i_err++; + } /* if(data[0]!=0 && data[0]!=1 && data[0]!=2) */ + if (data[0] == 1) { + if (data[14] != 0 && data[14] != 1 && data[14] != 2 + && data[14] != 4) { + printk("\n Error in selection of RTD connection type\n"); + i_err++; + } /* if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4) */ + } /* if(data[0]==1 ) */ + if (data[1] < 0 || data[1] > 7) { + printk("\nThe selection of gain is in error\n"); + i_err++; + } /* if(data[1]<0 || data[1]>7) */ + if (data[2] != 0 && data[2] != 1) { + printk("\nThe selection of polarity is in error\n"); + i_err++; + } /* if(data[2]!=0 && data[2]!=1) */ + if (data[3] != 0) { + printk("\nThe selection of offset range is in error\n"); + i_err++; + } /* if(data[3]!=0) */ + if (data[4] != 0 && data[4] != 1) { + printk("\nThe selection of coupling is in error\n"); + i_err++; + } /* if(data[4]!=0 && data[4]!=1) */ + if (data[5] != 0 && data[5] != 1) { + printk("\nThe selection of single/differential mode is in error\n"); + i_err++; + } /* if(data[5]!=0 && data[5]!=1) */ + if (data[8] != 0 && data[8] != 1 && data[2] != 2) { + printk("\nError in selection of functionality\n"); + } /* if(data[8]!=0 && data[8]!=1 && data[2]!=2) */ + if (data[12] == 0 || data[12] == 1) { + if (data[6] != 20 && data[6] != 40 && data[6] != 80 + && data[6] != 160) { + printk("\nThe selection of conversion time reload value is in error\n"); + i_err++; + } /* if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 ) */ + if (data[7] != 2) { + printk("\nThe selection of conversion time unit is in error\n"); + i_err++; + } /* if(data[7]!=2) */ + } + if (data[9] != 0 && data[9] != 1) { + printk("\nThe selection of interrupt enable is in error\n"); + i_err++; + } /* if(data[9]!=0 && data[9]!=1) */ + if (data[11] < 0 || data[11] > 4) { + printk("\nThe selection of module is in error\n"); + i_err++; + } /* if(data[11] <0 || data[11]>1) */ + if (data[12] < 0 || data[12] > 3) { + printk("\nThe selection of singlechannel/scan selection is in error\n"); + i_err++; + } /* if(data[12] < 0 || data[12]> 3) */ + if (data[13] < 0 || data[13] > 16) { + printk("\nThe selection of number of channels is in error\n"); + i_err++; + } /* if(data[13] <0 ||data[13] >15) */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* + i_ChannelCount=data[13]; + i_ScanType=data[12]; + i_ADDIDATAPolarity = data[2]; + i_ADDIDATAGain=data[1]; + i_ADDIDATAConversionTime=data[6]; + i_ADDIDATAConversionTimeUnit=data[7]; + i_ADDIDATAType=data[0]; + */ + + /* Save acquisition configuration for the actual board */ + s_BoardInfos[dev->minor].i_ChannelCount = data[13]; + s_BoardInfos[dev->minor].i_ScanType = data[12]; + s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2]; + s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1]; + s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6]; + s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7]; + s_BoardInfos[dev->minor].i_ADDIDATAType = data[0]; + /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + s_BoardInfos[dev->minor].i_ConnectionType = data[5]; + /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* END JK 06.07.04: Management of sevrals boards */ + + /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); /* 7 is the maximal number of channels */ + /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + + /* BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards */ + /* while(i_InterruptFlag==1) */ + while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) { +#ifndef MSXBOX + udelay(1); +#else + /* In the case where the driver is compiled for the MSX-Box */ + /* we used a printk to have a little delay because udelay */ + /* seems to be broken under the MSX-Box. */ + /* This solution hat to be studied. */ + printk(""); +#endif + } + /* END JK 02.07.04 : This while can't be do, it block the process when using severals boards */ + + ui_ChannelNo = CR_CHAN(insn->chanspec); /* get the channel */ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_ChannelNo=ui_ChannelNo; */ + /* ui_Channel_num =ui_ChannelNo; */ + + s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo; + s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo; + + /* END JK 06.07.04: Management of sevrals boards */ + + if (data[5] == 0) { + if (ui_ChannelNo < 0 || ui_ChannelNo > 15) { + printk("\nThe Selection of the channel is in error\n"); + i_err++; + } /* if(ui_ChannelNo<0 || ui_ChannelNo>15) */ + } /* if(data[5]==0) */ + else { + if (data[14] == 2) { + if (ui_ChannelNo < 0 || ui_ChannelNo > 3) { + printk("\nThe Selection of the channel is in error\n"); + i_err++; + } /* if(ui_ChannelNo<0 || ui_ChannelNo>3) */ + } /* if(data[14]==2) */ + else { + if (ui_ChannelNo < 0 || ui_ChannelNo > 7) { + printk("\nThe Selection of the channel is in error\n"); + i_err++; + } /* if(ui_ChannelNo<0 || ui_ChannelNo>7) */ + } /* elseif(data[14]==2) */ + } /* elseif(data[5]==0) */ + if (data[12] == 0 || data[12] == 1) { + switch (data[5]) { + case 0: + if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=0; */ + s_BoardInfos[dev->minor].i_Offset = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=3) */ + if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=64; */ + s_BoardInfos[dev->minor].i_Offset = 64; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=7) */ + if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=128; */ + s_BoardInfos[dev->minor].i_Offset = 128; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo >=8 && ui_ChannelNo <=11) */ + if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=192; */ + s_BoardInfos[dev->minor].i_Offset = 192; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo >=12 && ui_ChannelNo <=15) */ + break; + case 1: + if (data[14] == 2) { + if (ui_ChannelNo == 0) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=0; */ + s_BoardInfos[dev->minor].i_Offset = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo ==0 ) */ + if (ui_ChannelNo == 1) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=0; */ + s_BoardInfos[dev->minor].i_Offset = 64; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo ==1) */ + if (ui_ChannelNo == 2) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=128; */ + s_BoardInfos[dev->minor].i_Offset = 128; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo ==2 ) */ + if (ui_ChannelNo == 3) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=192; */ + s_BoardInfos[dev->minor].i_Offset = 192; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo ==3) */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_ChannelNo=0; */ + s_BoardInfos[dev->minor].i_ChannelNo = 0; + /* END JK 06.07.04: Management of sevrals boards */ + ui_ChannelNo = 0; + break; + } /* if(data[14]==2) */ + if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=0; */ + s_BoardInfos[dev->minor].i_Offset = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(ui_ChannelNo >=0 && ui_ChannelNo <=1) */ + if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_ChannelNo=i_ChannelNo-2; */ + /* i_Offset=64; */ + s_BoardInfos[dev->minor].i_ChannelNo = + s_BoardInfos[dev->minor].i_ChannelNo - + 2; + s_BoardInfos[dev->minor].i_Offset = 64; + /* END JK 06.07.04: Management of sevrals boards */ + ui_ChannelNo = ui_ChannelNo - 2; + } /* if(ui_ChannelNo >=2 && ui_ChannelNo <=3) */ + if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_ChannelNo=i_ChannelNo-4; */ + /* i_Offset=128; */ + s_BoardInfos[dev->minor].i_ChannelNo = + s_BoardInfos[dev->minor].i_ChannelNo - + 4; + s_BoardInfos[dev->minor].i_Offset = 128; + /* END JK 06.07.04: Management of sevrals boards */ + ui_ChannelNo = ui_ChannelNo - 4; + } /* if(ui_ChannelNo >=4 && ui_ChannelNo <=5) */ + if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_ChannelNo=i_ChannelNo-6; */ + /* i_Offset=192; */ + s_BoardInfos[dev->minor].i_ChannelNo = + s_BoardInfos[dev->minor].i_ChannelNo - + 6; + s_BoardInfos[dev->minor].i_Offset = 192; + /* END JK 06.07.04: Management of sevrals boards */ + ui_ChannelNo = ui_ChannelNo - 6; + } /* if(ui_ChannelNo >=6 && ui_ChannelNo <=7) */ + break; + + default: + printk("\n This selection of polarity does not exist\n"); + i_err++; + } /* switch(data[2]) */ + } /* if(data[12]==0 || data[12]==1) */ + else { + switch (data[11]) { + case 1: + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=0; */ + s_BoardInfos[dev->minor].i_Offset = 0; + /* END JK 06.07.04: Management of sevrals boards */ + break; + case 2: + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=64; */ + s_BoardInfos[dev->minor].i_Offset = 64; + /* END JK 06.07.04: Management of sevrals boards */ + break; + case 3: + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=128; */ + s_BoardInfos[dev->minor].i_Offset = 128; + /* END JK 06.07.04: Management of sevrals boards */ + break; + case 4: + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Offset=192; */ + s_BoardInfos[dev->minor].i_Offset = 192; + /* END JK 06.07.04: Management of sevrals boards */ + break; + default: + printk("\nError in module selection\n"); + i_err++; + } /* switch(data[11]) */ + } /* elseif(data[12]==0 || data[12]==1) */ + if (i_err) { + i_APCI3200_Reset(dev); + return -EINVAL; + } + /* if(i_ScanType!=1) */ + if (s_BoardInfos[dev->minor].i_ScanType != 1) { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Count=0; */ + /* i_Sum=0; */ + s_BoardInfos[dev->minor].i_Count = 0; + s_BoardInfos[dev->minor].i_Sum = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(i_ScanType!=1) */ + + ul_Config = + data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) | + (data[4] << 9); + /* BEGIN JK 06.07.04: Management of sevrals boards */ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; - /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */ - outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32); - /******************************/ - /*Configure the CJC Conversion */ - /******************************/ + /* END JK 06.07.04: Management of sevrals boards */ + /*********************************/ + /* Write the channel to configure */ + /*********************************/ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4); */ + outl(0 | ui_ChannelNo, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4); + /* END JK 06.07.04: Management of sevrals boards */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl(0x00000400,devpriv->iobase+i_Offset + 4); */ - outl(0x00000400, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4); - /*******************************/ - /*Configure the Gain Conversion */ - /*******************************/ + 12) >> 19) & 1) != 1) ; + /* END JK 06.07.04: Management of sevrals boards */ + /**************************/ + /* Reset the configuration */ + /**************************/ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* outl(0 , devpriv->iobase+i_Offset + 0x0); */ + outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0); + /* END JK 06.07.04: Management of sevrals boards */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; - /* outl(0x00040000,devpriv->iobase+i_Offset + 12); */ - outl(0x00040000, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); + /* END JK 06.07.04: Management of sevrals boards */ - /*******************************/ - /*Initialise dw_CommandRegister */ - /*******************************/ - ui_CommandRegister = 0; - /*********************************/ - /*Test if the interrupt is enable */ - /*********************************/ - /* if (i_InterruptFlag == ADDIDATA_ENABLE) */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) { - /**********************/ - /*Enable the interrupt */ - /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00100000; - } - /**********************/ - /*Start the conversion */ - /**********************/ - ui_CommandRegister = ui_CommandRegister | 0x00080000; /***************************/ - /*Write the command regiter */ + /* Write the configuration */ + /***************************/ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* outl(ul_Config , devpriv->iobase+i_Offset + 0x0); */ + outl(ul_Config, + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0); + /* END JK 06.07.04: Management of sevrals boards */ + + /***************************/ + /*Reset the calibration bit */ /***************************/ + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* ul_Temp = inl(devpriv->iobase+i_Offset + 12); */ + ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); + /* END JK 06.07.04: Management of sevrals boards */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12) >> 19) & 1) != 1) ; - /* outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8); */ - outl(ui_CommandRegister, - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ - if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) { - do { - /*******************/ - /*Read the EOC flag */ - /*******************/ - /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */ - ui_EOC = inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 20) & 1; - } while (ui_EOC != 1); - /************************************************/ - /*Read the digital value of the calibration Gain */ - /************************************************/ - /* data[0] = inl (devpriv->iobase+i_Offset + 28); */ - data[0] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - } /* if (i_InterruptFlag == ADDIDATA_DISABLE) */ - return 0; -} + /* END JK 06.07.04: Management of sevrals boards */ -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_InsnBits_AnalogInput_Test | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Tests the Selected Anlog Input Channel | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | struct comedi_subdevice *s : Subdevice Pointer | - | struct comedi_insn *insn : Insn Structure Pointer | - | unsigned int *data : Data Pointer contains | - | configuration parameters as below | - | - | - | data[0] : 0 TestAnalogInputShortCircuit - | 1 TestAnalogInputConnection | + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12); */ + outl((ul_Temp & 0xFFF9FFFF), + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12); + /* END JK 06.07.04: Management of sevrals boards */ - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - | data[0] : Digital value obtained | - | data[1] : calibration offset | - | data[2] : calibration gain | - | | - | | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ + if (data[9] == 1) { + devpriv->tsk_Current = current; + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_InterruptFlag=1; */ + s_BoardInfos[dev->minor].i_InterruptFlag = 1; + /* END JK 06.07.04: Management of sevrals boards */ + } /* if(data[9]==1) */ + else { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_InterruptFlag=0; */ + s_BoardInfos[dev->minor].i_InterruptFlag = 0; + /* END JK 06.07.04: Management of sevrals boards */ + } /* else if(data[9]==1) */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Initialised=1; */ + s_BoardInfos[dev->minor].i_Initialised = 1; + /* END JK 06.07.04: Management of sevrals boards */ + + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* if(i_ScanType==1) */ + if (s_BoardInfos[dev->minor].i_ScanType == 1) + /* END JK 06.07.04: Management of sevrals boards */ + { + /* BEGIN JK 06.07.04: Management of sevrals boards */ + /* i_Sum=i_Sum+1; */ + s_BoardInfos[dev->minor].i_Sum = + s_BoardInfos[dev->minor].i_Sum + 1; + /* END JK 06.07.04: Management of sevrals boards */ + + insn->unused[0] = 0; + i_APCI3200_ReadAnalogInput(dev, s, insn, &ui_Dummy); + } -int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) + return insn->n; +} + +/* + * Tests the Selected Anlog Input Channel + * + * data[0] = 0 TestAnalogInputShortCircuit + * = 1 TestAnalogInputConnection + * + * data[0] : Digital value obtained + * data[1] : calibration offset + * data[2] : calibration gain + */ +static int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_Configuration = 0; @@ -2519,61 +2293,18 @@ int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev, return insn->n; } -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_InsnWriteReleaseAnalogInput | - | (struct comedi_device *dev,struct comedi_subdevice *s, | - | struct comedi_insn *insn,unsigned int *data) | - +----------------------------------------------------------------------------+ - | Task : Resets the channels | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | struct comedi_subdevice *s : Subdevice Pointer | - | struct comedi_insn *insn : Insn Structure Pointer | - | unsigned int *data : Data Pointer - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) +static int i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { i_APCI3200_Reset(dev); return insn->n; } -/* - +----------------------------------------------------------------------------+ - | Function name :int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev| - | ,struct comedi_subdevice *s,struct comedi_cmd *cmd) | - | | - +----------------------------------------------------------------------------+ - | Task : Test validity for a command for cyclic anlog input | - | acquisition | - | | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev | - | struct comedi_subdevice *s | - | struct comedi_cmd *cmd | - | | - | - | | - | | - | | - +----------------------------------------------------------------------------+ - | Return Value :0 | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd) +static int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) { int err = 0; @@ -2733,25 +2464,8 @@ int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s return 0; } -/* - +----------------------------------------------------------------------------+ - | Function name :int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev,| - | struct comedi_subdevice *s)| - | | - +----------------------------------------------------------------------------+ - | Task : Stop the acquisition | - | | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev | - | struct comedi_subdevice *s | - | | - +----------------------------------------------------------------------------+ - | Return Value :0 | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s) +static int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, + struct comedi_subdevice *s) { struct addi_private *devpriv = dev->private; unsigned int ui_Configuration = 0; @@ -2784,26 +2498,11 @@ int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_su } /* - +----------------------------------------------------------------------------+ - | Function name : int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, | - | struct comedi_subdevice *s) | - | | - +----------------------------------------------------------------------------+ - | Task : Does asynchronous acquisition | - | Determines the mode 1 or 2. | - | | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev | - | struct comedi_subdevice *s | - | | - | | - +----------------------------------------------------------------------------+ - | Return Value : | - | | - +----------------------------------------------------------------------------+ -*/ - -int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s) + * Does asynchronous acquisition + * Determines the mode 1 or 2. + */ +static int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, + struct comedi_subdevice *s) { struct addi_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; @@ -2964,93 +2663,165 @@ int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subde ui_Configuration = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - /*******************/ - /*Set the START bit */ - /*******************/ - /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ - while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + - 12) >> 19) & 1) != 1) ; - /* outl((ui_Configuration | 0x00080000),devpriv->iobase+i_Offset + 8); */ - outl((ui_Configuration | 0x00080000), - devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); - return 0; -} + /*******************/ + /*Set the START bit */ + /*******************/ + /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */ + while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + + 12) >> 19) & 1) != 1) ; + /* outl((ui_Configuration | 0x00080000),devpriv->iobase+i_Offset + 8); */ + outl((ui_Configuration | 0x00080000), + devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8); + return 0; +} + +/* + * This function copies the acquired data(from FIFO) to Comedi buffer. + */ +static int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) +{ + struct addi_private *devpriv = dev->private; + unsigned int ui_StatusRegister = 0; + struct comedi_subdevice *s = &dev->subdevices[0]; + + /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* comedi_async *async = s->async; */ + /* UINT *data; */ + /* data=async->data+async->buf_int_ptr;//new samples added from here onwards */ + int n = 0, i = 0; + /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + + /************************************/ + /*Read the interrupt status register */ + /************************************/ + /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */ + ui_StatusRegister = + inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16); + + /*************************/ + /*Test if interrupt occur */ + /*************************/ + + if ((ui_StatusRegister & 0x2) == 0x2) { + /*************************/ + /*Read the channel number */ + /*************************/ + /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */ + /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* This value is not used */ + /* ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24); */ + s->async->events = 0; + /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + + /*************************************/ + /*Read the digital Analog Input value */ + /*************************************/ + + /* data[i_Count] = inl(devpriv->iobase+i_Offset + 28); */ + /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28); */ + s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev-> + minor].i_Count] = + inl(devpriv->iobase + + s_BoardInfos[dev->minor].i_Offset + 28); + /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + + /* if((i_Count == (i_LastChannel-i_FirstChannel+3))) */ + if ((s_BoardInfos[dev->minor].i_Count == + (s_BoardInfos[dev->minor].i_LastChannel - + s_BoardInfos[dev->minor]. + i_FirstChannel + 3))) { + + /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + s_BoardInfos[dev->minor].i_Count++; + + for (i = s_BoardInfos[dev->minor].i_FirstChannel; + i <= s_BoardInfos[dev->minor].i_LastChannel; + i++) { + i_APCI3200_GetChannelCalibrationValue(dev, i, + &s_BoardInfos[dev->minor]. + ui_ScanValueArray[s_BoardInfos[dev-> + minor].i_Count + ((i - + s_BoardInfos + [dev->minor]. + i_FirstChannel) + * 3)], + &s_BoardInfos[dev->minor]. + ui_ScanValueArray[s_BoardInfos[dev-> + minor].i_Count + ((i - + s_BoardInfos + [dev->minor]. + i_FirstChannel) + * 3) + 1], + &s_BoardInfos[dev->minor]. + ui_ScanValueArray[s_BoardInfos[dev-> + minor].i_Count + ((i - + s_BoardInfos + [dev->minor]. + i_FirstChannel) + * 3) + 2]); + } + + /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ + + /* i_Count=-1; */ + + s_BoardInfos[dev->minor].i_Count = -1; -/* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI3200_Reset(struct comedi_device *dev) | - | | - +----------------------------------------------------------------------------+ - | Task :Resets the registers of the card | - +----------------------------------------------------------------------------+ - | Input Parameters : | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : | - | | - +----------------------------------------------------------------------------+ -*/ + /* async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */ + /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */ + /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */ + /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */ + /* comedi_eos(dev,s); */ -int i_APCI3200_Reset(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - int i_Temp; - unsigned int dw_Dummy; + /* Set the event type (Comedi Buffer End Of Scan) */ + s->async->events |= COMEDI_CB_EOS; - /* i_InterruptFlag=0; */ - /* i_Initialised==0; */ - /* i_Count=0; */ - /* i_Sum=0; */ + /* Test if enougth memory is available and allocate it for 7 values */ + /* n = comedi_buf_write_alloc(s->async, 7*sizeof(unsigned int)); */ + n = comedi_buf_write_alloc(s->async, + (7 + 12) * sizeof(unsigned int)); - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - s_BoardInfos[dev->minor].i_Initialised = 0; - s_BoardInfos[dev->minor].i_Count = 0; - s_BoardInfos[dev->minor].i_Sum = 0; - s_BoardInfos[dev->minor].b_StructInitialized = 0; + /* If not enough memory available, event is set to Comedi Buffer Error */ + if (n > ((7 + 12) * sizeof(unsigned int))) { + printk("\ncomedi_buf_write_alloc n = %i", n); + s->async->events |= COMEDI_CB_ERROR; + } + /* Write all 7 scan values in the comedi buffer */ + comedi_buf_memcpy_to(s->async, 0, + (unsigned int *) s_BoardInfos[dev->minor]. + ui_ScanValueArray, (7 + 12) * sizeof(unsigned int)); - outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); + /* Update comedi buffer pinters indexes */ + comedi_buf_write_free(s->async, + (7 + 12) * sizeof(unsigned int)); - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - outl(0, devpriv->i_IobaseAddon); /* Resets the output */ - /***************/ - /*Empty the buffer */ - /**************/ - for (i_Temp = 0; i_Temp <= 95; i_Temp++) { - /* ui_InterruptChannelValue[i_Temp]=0; */ - s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0; - } /* for(i_Temp=0;i_Temp<=95;i_Temp++) */ - /*****************************/ - /*Reset the START and IRQ bit */ - /*****************************/ - for (i_Temp = 0; i_Temp <= 192;) { - while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ; - outl(0, devpriv->iobase + i_Temp + 8); - i_Temp = i_Temp + 64; - } /* for(i_Temp=0;i_Temp<=192;i_Temp+64) */ + /* Send events */ + comedi_event(dev, s); + /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + + /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + /* */ + /* if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over */ + /* { */ + /* /* buffer rollover */ */ + /* s->async->buf_int_ptr=0; */ + /* comedi_eobuf(dev,s); */ + /* } */ + /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ + } + /* i_Count++; */ + s_BoardInfos[dev->minor].i_Count++; + } + /* i_InterruptFlag=0; */ + s_BoardInfos[dev->minor].i_InterruptFlag = 0; return 0; } -/* - +----------------------------------------------------------------------------+ - | Function Name : static void v_APCI3200_Interrupt | - | (int irq , void *d) | - +----------------------------------------------------------------------------+ - | Task : Interrupt processing Routine | - +----------------------------------------------------------------------------+ - | Input Parameters : int irq : irq number | - | void *d : void pointer | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ -*/ -void v_APCI3200_Interrupt(int irq, void *d) +static void v_APCI3200_Interrupt(int irq, void *d) { struct comedi_device *dev = d; struct addi_private *devpriv = dev->private; @@ -3472,165 +3243,3 @@ void v_APCI3200_Interrupt(int irq, void *d) } /* switch(i_ScanType) */ return; } - -/* - +----------------------------------------------------------------------------+ - | Function name :int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) | - | | - | | - +----------------------------------------------------------------------------+ - | Task : . | - | This function copies the acquired data(from FIFO) | - | to Comedi buffer. | - | | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev | - | | - | | - +----------------------------------------------------------------------------+ - | Return Value : 0 | - | | - +----------------------------------------------------------------------------+ -*/ -int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_StatusRegister = 0; - struct comedi_subdevice *s = &dev->subdevices[0]; - - /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* comedi_async *async = s->async; */ - /* UINT *data; */ - /* data=async->data+async->buf_int_ptr;//new samples added from here onwards */ - int n = 0, i = 0; - /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /************************************/ - /*Read the interrupt status register */ - /************************************/ - /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */ - ui_StatusRegister = - inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16); - - /*************************/ - /*Test if interrupt occur */ - /*************************/ - - if ((ui_StatusRegister & 0x2) == 0x2) { - /*************************/ - /*Read the channel number */ - /*************************/ - /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */ - /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* This value is not used */ - /* ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24); */ - s->async->events = 0; - /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /*************************************/ - /*Read the digital Analog Input value */ - /*************************************/ - - /* data[i_Count] = inl(devpriv->iobase+i_Offset + 28); */ - /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28); */ - s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count] = - inl(devpriv->iobase + - s_BoardInfos[dev->minor].i_Offset + 28); - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* if((i_Count == (i_LastChannel-i_FirstChannel+3))) */ - if ((s_BoardInfos[dev->minor].i_Count == - (s_BoardInfos[dev->minor].i_LastChannel - - s_BoardInfos[dev->minor]. - i_FirstChannel + 3))) { - - /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - s_BoardInfos[dev->minor].i_Count++; - - for (i = s_BoardInfos[dev->minor].i_FirstChannel; - i <= s_BoardInfos[dev->minor].i_LastChannel; - i++) { - i_APCI3200_GetChannelCalibrationValue(dev, i, - &s_BoardInfos[dev->minor]. - ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count + ((i - - s_BoardInfos - [dev->minor]. - i_FirstChannel) - * 3)], - &s_BoardInfos[dev->minor]. - ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count + ((i - - s_BoardInfos - [dev->minor]. - i_FirstChannel) - * 3) + 1], - &s_BoardInfos[dev->minor]. - ui_ScanValueArray[s_BoardInfos[dev-> - minor].i_Count + ((i - - s_BoardInfos - [dev->minor]. - i_FirstChannel) - * 3) + 2]); - } - - /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - - /* i_Count=-1; */ - - s_BoardInfos[dev->minor].i_Count = -1; - - /* async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */ - /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */ - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */ - /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */ - /* comedi_eos(dev,s); */ - - /* Set the event type (Comedi Buffer End Of Scan) */ - s->async->events |= COMEDI_CB_EOS; - - /* Test if enougth memory is available and allocate it for 7 values */ - /* n = comedi_buf_write_alloc(s->async, 7*sizeof(unsigned int)); */ - n = comedi_buf_write_alloc(s->async, - (7 + 12) * sizeof(unsigned int)); - - /* If not enough memory available, event is set to Comedi Buffer Error */ - if (n > ((7 + 12) * sizeof(unsigned int))) { - printk("\ncomedi_buf_write_alloc n = %i", n); - s->async->events |= COMEDI_CB_ERROR; - } - /* Write all 7 scan values in the comedi buffer */ - comedi_buf_memcpy_to(s->async, 0, - (unsigned int *) s_BoardInfos[dev->minor]. - ui_ScanValueArray, (7 + 12) * sizeof(unsigned int)); - - /* Update comedi buffer pinters indexes */ - comedi_buf_write_free(s->async, - (7 + 12) * sizeof(unsigned int)); - - /* Send events */ - comedi_event(dev, s); - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - /* */ - /* if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over */ - /* { */ - /* /* buffer rollover */ */ - /* s->async->buf_int_ptr=0; */ - /* comedi_eobuf(dev,s); */ - /* } */ - /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - } - /* i_Count++; */ - s_BoardInfos[dev->minor].i_Count++; - } - /* i_InterruptFlag=0; */ - s_BoardInfos[dev->minor].i_InterruptFlag = 0; - return 0; -} diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h index afa7ba304b3..e98a4d9e2e4 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h @@ -152,39 +152,3 @@ struct str_BoardInfos { }; /* END JK 06.07.04: Management of sevrals boards */ - -/* Hardware Layer functions for Apci3200 */ - -/* AI */ - -int i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3200_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s); -int i_APCI3200_InterruptHandleEos(struct comedi_device *dev); -int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); -int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s); -int i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -/* Interrupt */ -void v_APCI3200_Interrupt(int irq, void *d); -int i_APCI3200_InterruptHandleEos(struct comedi_device *dev); -/* Reset functions */ -int i_APCI3200_Reset(struct comedi_device *dev); - -int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data); -int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data); -int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int *data); -int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned int *data); -int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data); -- cgit v1.2.3 From c0567adc9d2635c798b0bd474614e30a81a60cdd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:04:30 -0700 Subject: staging: comedi: hwdrv_apci3200: absorb private header The header file hwdrv_apci3200.h is only included by the source file hwdrv_apci3200.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3200.c | 130 ++++++++++++++++- .../comedi/drivers/addi-data/hwdrv_apci3200.h | 154 --------------------- 2 files changed, 123 insertions(+), 161 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index 1c0bf27696c..f2330774a6f 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -51,15 +51,131 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/* - +----------------------------------------------------------------------------+ - | Included files | - +----------------------------------------------------------------------------+ -*/ -#include "hwdrv_apci3200.h" - /* #define PRINT_INFO */ +/* Card Specific information */ +/* #define APCI3200_ADDRESS_RANGE 264 */ + +/* Analog Input related Defines */ +#define APCI3200_AI_OFFSET_GAIN 0 +#define APCI3200_AI_SC_TEST 4 +#define APCI3200_AI_IRQ 8 +#define APCI3200_AI_AUTOCAL 12 +#define APCI3200_RELOAD_CONV_TIME_VAL 32 +#define APCI3200_CONV_TIME_TIME_BASE 36 +#define APCI3200_RELOAD_DELAY_TIME_VAL 40 +#define APCI3200_DELAY_TIME_TIME_BASE 44 +#define APCI3200_AI_MODULE1 0 +#define APCI3200_AI_MODULE2 64 +#define APCI3200_AI_MODULE3 128 +#define APCI3200_AI_MODULE4 192 +#define TRUE 1 +#define FALSE 0 +#define APCI3200_AI_EOSIRQ 16 +#define APCI3200_AI_EOS 20 +#define APCI3200_AI_CHAN_ID 24 +#define APCI3200_AI_CHAN_VAL 28 +#define ANALOG_INPUT 0 +#define TEMPERATURE 1 +#define RESISTANCE 2 + +#define ENABLE_EXT_TRIG 1 +#define ENABLE_EXT_GATE 2 +#define ENABLE_EXT_TRIG_GATE 3 + +#define APCI3200_MAXVOLT 2.5 +#define ADDIDATA_GREATER_THAN_TEST 0 +#define ADDIDATA_LESS_THAN_TEST 1 + +#define ADDIDATA_UNIPOLAR 1 +#define ADDIDATA_BIPOLAR 2 + +#define MAX_MODULE 4 + +/* ANALOG INPUT RANGE */ +static const struct comedi_lrange range_apci3200_ai = { + 8, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1), + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1) + } +}; + +static const struct comedi_lrange range_apci3300_ai = { + 4, { + UNI_RANGE(10), + UNI_RANGE(5), + UNI_RANGE(2), + UNI_RANGE(1) + } +}; + +int MODULE_NO; +struct { + int i_Gain; + int i_Polarity; + int i_OffsetRange; + int i_Coupling; + int i_SingleDiff; + int i_AutoCalibration; + unsigned int ui_ReloadValue; + unsigned int ui_TimeUnitReloadVal; + int i_Interrupt; + int i_ModuleSelection; +} Config_Parameters_Module1, Config_Parameters_Module2, + Config_Parameters_Module3, Config_Parameters_Module4; + + +struct str_ADDIDATA_RTDStruct { + unsigned int ul_NumberOfValue; + unsigned int *pul_ResistanceValue; + unsigned int *pul_TemperatureValue; +}; + +struct str_Module { + unsigned long ul_CurrentSourceCJC; + unsigned long ul_CurrentSource[5]; + unsigned long ul_GainFactor[8]; /* Gain Factor */ + unsigned int w_GainValue[10]; +}; + +struct str_BoardInfos { + + int i_CJCAvailable; + int i_CJCPolarity; + int i_CJCGain; + int i_InterruptFlag; + int i_ADDIDATAPolarity; + int i_ADDIDATAGain; + int i_AutoCalibration; + int i_ADDIDATAConversionTime; + int i_ADDIDATAConversionTimeUnit; + int i_ADDIDATAType; + int i_ChannelNo; + int i_ChannelCount; + int i_ScanType; + int i_FirstChannel; + int i_LastChannel; + int i_Sum; + int i_Offset; + unsigned int ui_Channel_num; + int i_Count; + int i_Initialised; + unsigned int ui_InterruptChannelValue[144]; /* Buffer */ + unsigned char b_StructInitialized; + /* 7 is the maximal number of channels */ + unsigned int ui_ScanValueArray[7 + 12]; + + int i_ConnectionType; + int i_NbrOfModule; + struct str_Module s_Module[MAX_MODULE]; +}; + /* BEGIN JK 06.07.04: Management of sevrals boards */ /* int i_CJCAvailable=1; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h deleted file mode 100644 index e98a4d9e2e4..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ - -/* Card Specific information */ -/* #define APCI3200_ADDRESS_RANGE 264 */ - -int MODULE_NO; -struct { - int i_Gain; - int i_Polarity; - int i_OffsetRange; - int i_Coupling; - int i_SingleDiff; - int i_AutoCalibration; - unsigned int ui_ReloadValue; - unsigned int ui_TimeUnitReloadVal; - int i_Interrupt; - int i_ModuleSelection; -} Config_Parameters_Module1, Config_Parameters_Module2, - Config_Parameters_Module3, Config_Parameters_Module4; - -/* ANALOG INPUT RANGE */ -static const struct comedi_lrange range_apci3200_ai = { 8, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1), - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - -static const struct comedi_lrange range_apci3300_ai = { 4, { - UNI_RANGE(10), - UNI_RANGE(5), - UNI_RANGE(2), - UNI_RANGE(1) - } -}; - -/* Analog Input related Defines */ -#define APCI3200_AI_OFFSET_GAIN 0 -#define APCI3200_AI_SC_TEST 4 -#define APCI3200_AI_IRQ 8 -#define APCI3200_AI_AUTOCAL 12 -#define APCI3200_RELOAD_CONV_TIME_VAL 32 -#define APCI3200_CONV_TIME_TIME_BASE 36 -#define APCI3200_RELOAD_DELAY_TIME_VAL 40 -#define APCI3200_DELAY_TIME_TIME_BASE 44 -#define APCI3200_AI_MODULE1 0 -#define APCI3200_AI_MODULE2 64 -#define APCI3200_AI_MODULE3 128 -#define APCI3200_AI_MODULE4 192 -#define TRUE 1 -#define FALSE 0 -#define APCI3200_AI_EOSIRQ 16 -#define APCI3200_AI_EOS 20 -#define APCI3200_AI_CHAN_ID 24 -#define APCI3200_AI_CHAN_VAL 28 -#define ANALOG_INPUT 0 -#define TEMPERATURE 1 -#define RESISTANCE 2 - -#define ENABLE_EXT_TRIG 1 -#define ENABLE_EXT_GATE 2 -#define ENABLE_EXT_TRIG_GATE 3 - -#define APCI3200_MAXVOLT 2.5 -#define ADDIDATA_GREATER_THAN_TEST 0 -#define ADDIDATA_LESS_THAN_TEST 1 - -#define ADDIDATA_UNIPOLAR 1 -#define ADDIDATA_BIPOLAR 2 - -/* BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ -#define MAX_MODULE 4 -/* END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - -struct str_ADDIDATA_RTDStruct { - unsigned int ul_NumberOfValue; - unsigned int *pul_ResistanceValue; - unsigned int *pul_TemperatureValue; -}; - -/* BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ -struct str_Module { - - /* Begin JK 05/08/2003 change for Linux */ - unsigned long ul_CurrentSourceCJC; - unsigned long ul_CurrentSource[5]; - /* End JK 05/08/2003 change for Linux */ - - /* Begin CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1 */ - unsigned long ul_GainFactor[8]; /* Gain Factor */ - unsigned int w_GainValue[10]; - /* End CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1 */ -}; - -/* END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - -/* BEGIN JK 06.07.04: Management of sevrals boards */ -struct str_BoardInfos { - - int i_CJCAvailable; - int i_CJCPolarity; - int i_CJCGain; - int i_InterruptFlag; - int i_ADDIDATAPolarity; - int i_ADDIDATAGain; - int i_AutoCalibration; - int i_ADDIDATAConversionTime; - int i_ADDIDATAConversionTimeUnit; - int i_ADDIDATAType; - int i_ChannelNo; - int i_ChannelCount; - int i_ScanType; - int i_FirstChannel; - int i_LastChannel; - int i_Sum; - int i_Offset; - unsigned int ui_Channel_num; - int i_Count; - int i_Initialised; - /* UINT ui_InterruptChannelValue[96]; //Buffer */ - unsigned int ui_InterruptChannelValue[144]; /* Buffer */ - unsigned char b_StructInitialized; - /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - unsigned int ui_ScanValueArray[7 + 12]; /* 7 is the maximal number of channels */ - /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */ - - /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ - int i_ConnectionType; - int i_NbrOfModule; - struct str_Module s_Module[MAX_MODULE]; - /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */ -}; - -/* END JK 06.07.04: Management of sevrals boards */ -- cgit v1.2.3 From 3f38a6ad8012e19a7257226f83fc831ff998e199 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 17:04:45 -0700 Subject: staging: comedi: hwdrv_APCI1710: absorb private header The header file hwdrv_APCi1710.h is only included by the source file hwdrv_APCI1710.c. Absorb the header into the source and delete the header. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_APCI1710.c | 57 +++++++++++++++++- .../comedi/drivers/addi-data/hwdrv_APCI1710.h | 70 ---------------------- 2 files changed, 56 insertions(+), 71 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c index f28c737a173..b05f8505c89 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c @@ -44,7 +44,35 @@ You should also find the complete GPL in the COPYING file accompanying this sour | | | | +----------+-----------+------------------------------------------------+ */ -#include "hwdrv_APCI1710.h" + +#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ +#define COMEDI_SUBD_PWM 12 /* Pulse width Measurement */ +#define COMEDI_SUBD_SSI 13 /* Synchronous serial interface */ +#define COMEDI_SUBD_TOR 14 /* Tor counter */ +#define COMEDI_SUBD_CHRONO 15 /* Chrono meter */ +#define COMEDI_SUBD_PULSEENCODER 16 /* Pulse Encoder INP CPT */ +#define COMEDI_SUBD_INCREMENTALCOUNTER 17 /* Incremental Counter */ + +#define APCI1710_BOARD_NAME "apci1710" +#define APCI1710_BOARD_DEVICE_ID 0x818F +#define APCI1710_ADDRESS_RANGE 256 +#define APCI1710_CONFIG_ADDRESS_RANGE 8 +#define APCI1710_INCREMENTAL_COUNTER 0x53430000UL +#define APCI1710_SSI_COUNTER 0x53490000UL +#define APCI1710_TTL_IO 0x544C0000UL +#define APCI1710_DIGITAL_IO 0x44490000UL +#define APCI1710_82X54_TIMER 0x49430000UL +#define APCI1710_CHRONOMETER 0x43480000UL +#define APCI1710_PULSE_ENCODER 0x495A0000UL +#define APCI1710_TOR_COUNTER 0x544F0000UL +#define APCI1710_PWM 0x50570000UL +#define APCI1710_ETM 0x45540000UL +#define APCI1710_CDA 0x43440000UL +#define APCI1710_DISABLE 0 +#define APCI1710_ENABLE 1 +#define APCI1710_SYNCHRONOUS_MODE 1 +#define APCI1710_ASYNCHRONOUS_MODE 0 + #include "APCI1710_Inp_cpt.c" #include "APCI1710_Ssi.c" @@ -56,6 +84,33 @@ You should also find the complete GPL in the COPYING file accompanying this sour #include "APCI1710_Pwm.c" #include "APCI1710_INCCPT.c" +static const struct comedi_lrange range_apci1710_ttl = { + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1) + } +}; + +static const struct comedi_lrange range_apci1710_ssi = { + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1) + } +}; + +static const struct comedi_lrange range_apci1710_inccpt = { + 4, { + BIP_RANGE(10), + BIP_RANGE(5), + BIP_RANGE(2), + BIP_RANGE(1) + } +}; + static void i_ADDI_AttachPCI1710(struct comedi_device *dev) { struct comedi_subdevice *s; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h deleted file mode 100644 index dab528e68c2..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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 COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ -#define COMEDI_SUBD_PWM 12 /* Pulse width Measurement */ -#define COMEDI_SUBD_SSI 13 /* Synchronous serial interface */ -#define COMEDI_SUBD_TOR 14 /* Tor counter */ -#define COMEDI_SUBD_CHRONO 15 /* Chrono meter */ -#define COMEDI_SUBD_PULSEENCODER 16 /* Pulse Encoder INP CPT */ -#define COMEDI_SUBD_INCREMENTALCOUNTER 17 /* Incremental Counter */ - -#define APCI1710_BOARD_NAME "apci1710" -#define APCI1710_BOARD_DEVICE_ID 0x818F -#define APCI1710_ADDRESS_RANGE 256 -#define APCI1710_CONFIG_ADDRESS_RANGE 8 -#define APCI1710_INCREMENTAL_COUNTER 0x53430000UL -#define APCI1710_SSI_COUNTER 0x53490000UL -#define APCI1710_TTL_IO 0x544C0000UL -#define APCI1710_DIGITAL_IO 0x44490000UL -#define APCI1710_82X54_TIMER 0x49430000UL -#define APCI1710_CHRONOMETER 0x43480000UL -#define APCI1710_PULSE_ENCODER 0x495A0000UL -#define APCI1710_TOR_COUNTER 0x544F0000UL -#define APCI1710_PWM 0x50570000UL -#define APCI1710_ETM 0x45540000UL -#define APCI1710_CDA 0x43440000UL -#define APCI1710_DISABLE 0 -#define APCI1710_ENABLE 1 -#define APCI1710_SYNCHRONOUS_MODE 1 -#define APCI1710_ASYNCHRONOUS_MODE 0 - -/* MODULE INFO STRUCTURE */ - -static const struct comedi_lrange range_apci1710_ttl = { 4, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1) - } -}; - -static const struct comedi_lrange range_apci1710_ssi = { 4, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1) - } -}; - -static const struct comedi_lrange range_apci1710_inccpt = { 4, { - BIP_RANGE(10), - BIP_RANGE(5), - BIP_RANGE(2), - BIP_RANGE(1) - } -}; -- cgit v1.2.3 From c33ef61ff9f731efa4a630a9566a4cdf8945f4af Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 18:06:13 -0700 Subject: staging: comedi: addi_apci_*: remove unneeded CONFIG_APCI_* defines These defines were needed for the #ifdef'ery that used to exist in addi_common.c. Since that has been removed these are no longer used. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_035.c | 2 -- drivers/staging/comedi/drivers/addi_apci_1032.c | 2 -- drivers/staging/comedi/drivers/addi_apci_1500.c | 2 -- drivers/staging/comedi/drivers/addi_apci_1516.c | 2 -- drivers/staging/comedi/drivers/addi_apci_1564.c | 2 -- drivers/staging/comedi/drivers/addi_apci_16xx.c | 2 -- drivers/staging/comedi/drivers/addi_apci_2016.c | 2 -- drivers/staging/comedi/drivers/addi_apci_2032.c | 2 -- drivers/staging/comedi/drivers/addi_apci_2200.c | 2 -- drivers/staging/comedi/drivers/addi_apci_3001.c | 2 -- drivers/staging/comedi/drivers/addi_apci_3200.c | 2 -- drivers/staging/comedi/drivers/addi_apci_3300.c | 2 -- drivers/staging/comedi/drivers/addi_apci_3501.c | 2 -- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 2 -- 14 files changed, 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 2e3f685fbc5..7f456e7cfda 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define CONFIG_APCI_035 1 - #define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */ #define ADDIDATA_DRIVER_NAME "addi_apci_035" diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index cfcba6a268b..19794f1da9c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define CONFIG_APCI_1032 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_1032" #include "addi-data/addi_eeprom.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 59d762fbcb9..ee7cdfb74ca 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define CONFIG_APCI_1500 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_1500" #include "addi-data/addi_eeprom.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index fdc4b6617b2..8f45496a0de 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define CONFIG_APCI_1516 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_1516" #include "addi-data/addi_eeprom.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 6bdbf205847..0a631e1fe78 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define CONFIG_APCI_1564 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_1564" #include "addi-data/addi_eeprom.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 87009c832d2..ab2b59927be 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define CONFIG_APCI_16XX 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_16xx" #include "addi-data/addi_eeprom.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c index ece4b9db58c..5e1d34bf729 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ b/drivers/staging/comedi/drivers/addi_apci_2016.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define CONFIG_APCI_2016 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_2016" #include "addi-data/addi_eeprom.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 8dddb65f13b..b587bbca062 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define CONFIG_APCI_2032 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_2032" #include "addi-data/addi_eeprom.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 2c6464825b7..983447516ff 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define CONFIG_APCI_2200 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_2200" #include "addi-data/addi_eeprom.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c index d5bc24660d8..fff4a832215 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3001.c +++ b/drivers/staging/comedi/drivers/addi_apci_3001.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define CONFIG_APCI_3001 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_3001" #include "addi-data/addi_eeprom.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index e3db75cc293..7a688925a3c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -16,8 +16,6 @@ static void fpu_end(void) kernel_fpu_end(); } -#define CONFIG_APCI_3200 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_3200" #include "addi-data/addi_eeprom.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c index 81f0549aab4..9a9a5d10033 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3300.c +++ b/drivers/staging/comedi/drivers/addi_apci_3300.c @@ -16,8 +16,6 @@ static void fpu_end(void) kernel_fpu_end(); } -#define CONFIG_APCI_3300 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_3300" #include "addi-data/addi_eeprom.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 5c95c7d1d21..49f0d1930d6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define CONFIG_APCI_3501 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_3501" #include "addi-data/addi_eeprom.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index d2698238676..edc0eb0d113 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define CONFIG_APCI_3XXX 1 - #define ADDIDATA_DRIVER_NAME "addi_apci_3xxx" #include "addi-data/addi_eeprom.c" -- cgit v1.2.3 From 20a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 30 Oct 2012 18:06:33 -0700 Subject: staging: comedi: addi_apci_*: add module_comedi_pci_driver() Pull the module init code out of addi_common.c and add it to each addi-data driver. Rename the data and functions so they have namespace associated with the drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 30 ----------------- drivers/staging/comedi/drivers/addi_apci_035.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_1032.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_1500.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_1516.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_1564.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_16xx.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_1710.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_2016.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_2032.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_2200.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_3001.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_3120.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_3200.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_3300.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_3501.c | 38 ++++++++++++++++++---- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 38 ++++++++++++++++++---- 17 files changed, 512 insertions(+), 126 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 79beff15d68..652b5abe3d4 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -107,7 +107,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) v_pci_card_list_init(this_board->i_VendorId, 1); /* 1 for displaying the list.. */ pci_list_builded = 1; } - /* printk("comedi%d: "ADDIDATA_DRIVER_NAME": board=%s",dev->minor,this_board->pc_DriverName); */ if ((this_board->i_Dma) && (it->options[2] == 0)) { i_Dma = 1; @@ -466,32 +465,3 @@ static void i_ADDI_Detach(struct comedi_device *dev) } } } - -static struct comedi_driver addi_driver = { - .driver_name = ADDIDATA_DRIVER_NAME, - .module = THIS_MODULE, - .attach = i_ADDI_Attach, - .detach = i_ADDI_Detach, - .num_names = ARRAY_SIZE(boardtypes), - .board_name = &boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), -}; - -static int __devinit addi_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &addi_driver); -} - -static void __devexit addi_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static struct pci_driver addi_pci_driver = { - .name = ADDIDATA_DRIVER_NAME, - .id_table = addi_apci_tbl, - .probe = &addi_pci_probe, - .remove = __devexit_p(&addi_pci_remove), -}; -module_comedi_pci_driver(addi_driver, addi_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 7f456e7cfda..812092f7fba 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -6,12 +6,11 @@ #define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */ -#define ADDIDATA_DRIVER_NAME "addi_apci_035" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci035.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci035_boardtypes[] = { { .pc_DriverName = "apci035", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -38,13 +37,40 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci035_driver = { + .driver_name = "addi_apci_035", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci035_boardtypes), + .board_name = &apci035_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci035_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci035_driver); +} + +static void __devexit apci035_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci035_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x0300) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci035_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci035_pci_driver = { + .name = "addi_apci_035", + .id_table = apci035_pci_table, + .probe = apci035_pci_probe, + .remove = __devexit_p(apci035_pci_remove), +}; +module_comedi_pci_driver(apci035_driver, apci035_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 19794f1da9c..f787604c311 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -4,12 +4,11 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_1032" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1032.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci1032_boardtypes[] = { { .pc_DriverName = "apci1032", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -27,13 +26,40 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci1032_driver = { + .driver_name = "addi_apci_1032", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci1032_boardtypes), + .board_name = &apci1032_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci1032_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci1032_driver); +} + +static void __devexit apci1032_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci1032_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1003) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci1032_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci1032_pci_driver = { + .name = "addi_apci_1032", + .id_table = apci1032_pci_table, + .probe = apci1032_pci_probe, + .remove = __devexit_p(apci1032_pci_remove), +}; +module_comedi_pci_driver(apci1032_driver, apci1032_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index ee7cdfb74ca..51f9e85459c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -4,12 +4,11 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_1500" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1500.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci1500_boardtypes[] = { { .pc_DriverName = "apci1500", .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, @@ -38,13 +37,40 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci1500_driver = { + .driver_name = "addi_apci_1500", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci1500_boardtypes), + .board_name = &apci1500_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci1500_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci1500_driver); +} + +static void __devexit apci1500_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci1500_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x80fc) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci1500_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci1500_pci_driver = { + .name = "addi_apci_1500", + .id_table = apci1500_pci_table, + .probe = apci1500_pci_probe, + .remove = __devexit_p(apci1500_pci_remove), +}; +module_comedi_pci_driver(apci1500_driver, apci1500_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 8f45496a0de..ba7ffad4534 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -4,12 +4,11 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_1516" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1516.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci1516_boardtypes[] = { { .pc_DriverName = "apci1516", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -34,13 +33,40 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci1516_driver = { + .driver_name = "addi_apci_1516", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci1516_boardtypes), + .board_name = &apci1516_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci1516_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci1516_driver); +} + +static void __devexit apci1516_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci1516_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1001) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci1516_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci1516_pci_driver = { + .name = "addi_apci_1516", + .id_table = apci1516_pci_table, + .probe = apci1516_pci_probe, + .remove = __devexit_p(apci1516_pci_remove), +}; +module_comedi_pci_driver(apci1516_driver, apci1516_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 0a631e1fe78..c44007b0c91 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -4,12 +4,11 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_1564" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1564.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci1564_boardtypes[] = { { .pc_DriverName = "apci1564", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -37,13 +36,40 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci1564_driver = { + .driver_name = "addi_apci_1564", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci1564_boardtypes), + .board_name = &apci1564_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci1564_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci1564_driver); +} + +static void __devexit apci1564_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci1564_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1006) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci1564_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci1564_pci_driver = { + .name = "addi_apci_1564", + .id_table = apci1564_pci_table, + .probe = apci1564_pci_probe, + .remove = __devexit_p(apci1564_pci_remove), +}; +module_comedi_pci_driver(apci1564_driver, apci1564_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index ab2b59927be..18182a14d21 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -4,12 +4,11 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_16xx" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci16xx.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci16xx_boardtypes[] = { { .pc_DriverName = "apci1648", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -37,14 +36,41 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci16xx_driver = { + .driver_name = "addi_apci_16xx", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci16xx_boardtypes), + .board_name = &apci16xx_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci16xx_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci16xx_driver); +} + +static void __devexit apci16xx_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci16xx_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1009) }, { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x100a) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci16xx_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci16xx_pci_driver = { + .name = "addi_apci_16xx", + .id_table = apci16xx_pci_table, + .probe = apci16xx_pci_probe, + .remove = __devexit_p(apci16xx_pci_remove), +}; +module_comedi_pci_driver(apci16xx_driver, apci16xx_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 58c5121e827..ff0131710cc 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -18,12 +18,11 @@ static void fpu_end(void) #define CONFIG_APCI_1710 1 -#define ADDIDATA_DRIVER_NAME "addi_apci_1710" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_APCI1710.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci1710_boardtypes[] = { { .pc_DriverName = "apci1710", .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, @@ -37,10 +36,37 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci1710_driver = { + .driver_name = "addi_apci_1710", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci1710_boardtypes), + .board_name = &apci1710_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci1710_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci1710_driver); +} + +static void __devexit apci1710_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci1710_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, APCI1710_BOARD_DEVICE_ID) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci1710_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci1710_pci_driver = { + .name = "addi_apci_1710", + .id_table = apci1710_pci_table, + .probe = apci1710_pci_probe, + .remove = __devexit_p(apci1710_pci_remove), +}; +module_comedi_pci_driver(apci1710_driver, apci1710_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c index 5e1d34bf729..26426085f97 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ b/drivers/staging/comedi/drivers/addi_apci_2016.c @@ -4,12 +4,11 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_2016" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci2016.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci2016_boardtypes[] = { { .pc_DriverName = "apci2016", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -31,13 +30,40 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci2016_driver = { + .driver_name = "addi_apci_2016", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci2016_boardtypes), + .board_name = &apci2016_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci2016_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci2016_driver); +} + +static void __devexit apci2016_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci2016_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1002) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci2016_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci2016_pci_driver = { + .name = "addi_apci_2016", + .id_table = apci2016_pci_table, + .probe = apci2016_pci_probe, + .remove = __devexit_p(apci2016_pci_remove), +}; +module_comedi_pci_driver(apci2016_driver, apci2016_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index b587bbca062..32214198a90 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -4,12 +4,11 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_2032" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci2032.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci2032_boardtypes[] = { { .pc_DriverName = "apci2032", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -33,13 +32,40 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci2032_driver = { + .driver_name = "addi_apci_2032", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci2032_boardtypes), + .board_name = &apci2032_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci2032_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci2032_driver); +} + +static void __devexit apci2032_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci2032_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci2032_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci2032_pci_driver = { + .name = "addi_apci_2032", + .id_table = apci2032_pci_table, + .probe = apci2032_pci_probe, + .remove = __devexit_p(apci2032_pci_remove), +}; +module_comedi_pci_driver(apci2032_driver, apci2032_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 983447516ff..6c8a2223520 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -4,12 +4,11 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_2200" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci2200.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci2200_boardtypes[] = { { .pc_DriverName = "apci2200", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -33,13 +32,40 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci2200_driver = { + .driver_name = "addi_apci_2200", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci2200_boardtypes), + .board_name = &apci2200_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci2200_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci2200_driver); +} + +static void __devexit apci2200_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci2200_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1005) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci2200_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci2200_pci_driver = { + .name = "addi_apci_2200", + .id_table = apci2200_pci_table, + .probe = apci2200_pci_probe, + .remove = __devexit_p(apci2200_pci_remove), +}; +module_comedi_pci_driver(apci2200_driver, apci2200_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c index fff4a832215..bfeac4451fb 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3001.c +++ b/drivers/staging/comedi/drivers/addi_apci_3001.c @@ -4,12 +4,11 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_3001" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3120.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci3001_boardtypes[] = { { .pc_DriverName = "apci3001", .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, @@ -49,13 +48,40 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci3001_driver = { + .driver_name = "addi_apci_3001", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci3001_boardtypes), + .board_name = &apci3001_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci3001_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci3001_driver); +} + +static void __devexit apci3001_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci3001_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x828d) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci3001_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci3001_pci_driver = { + .name = "addi_apci_3001", + .id_table = apci3001_pci_table, + .probe = apci3001_pci_probe, + .remove = __devexit_p(apci3001_pci_remove), +}; +module_comedi_pci_driver(apci3001_driver, apci3001_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index bd2a654eeba..1df67cea347 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -6,12 +6,11 @@ #define CONFIG_APCI_3120 1 -#define ADDIDATA_DRIVER_NAME "addi_apci_3120" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3120.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci3120_boardtypes[] = { { .pc_DriverName = "apci3120", .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, @@ -55,13 +54,40 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci3120_driver = { + .driver_name = "addi_apci_3120", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci3120_boardtypes), + .board_name = &apci3120_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci3120_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci3120_driver); +} + +static void __devexit apci3120_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci3120_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x818d) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci3120_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci3120_pci_driver = { + .name = "addi_apci_3120", + .id_table = apci3120_pci_table, + .probe = apci3120_pci_probe, + .remove = __devexit_p(apci3120_pci_remove), +}; +module_comedi_pci_driver(apci3120_driver, apci3120_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 7a688925a3c..cc3e8142635 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -16,12 +16,11 @@ static void fpu_end(void) kernel_fpu_end(); } -#define ADDIDATA_DRIVER_NAME "addi_apci_3200" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3200.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci3200_boardtypes[] = { { .pc_DriverName = "apci3200", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -57,10 +56,37 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static DEFINE_PCI_DEVICE_TABLE(apci3200_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3000) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci3200_pci_table); -#include "addi-data/addi_common.c" +static struct comedi_driver apci3200_driver = { + .driver_name = "addi_apci_3200", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci3200_boardtypes), + .board_name = &apci3200_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci3200_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci3200_driver); +} + +static void __devexit apci3200_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static struct pci_driver apci3200_pci_driver = { + .name = "addi_apci_3200", + .id_table = apci3200_pci_table, + .probe = apci3200_pci_probe, + .remove = __devexit_p(apci3200_pci_remove), +}; +module_comedi_pci_driver(apci3200_driver, apci3200_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c index 9a9a5d10033..172b5ceed83 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3300.c +++ b/drivers/staging/comedi/drivers/addi_apci_3300.c @@ -16,12 +16,11 @@ static void fpu_end(void) kernel_fpu_end(); } -#define ADDIDATA_DRIVER_NAME "addi_apci_3300" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3200.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci3300_boardtypes[] = { { .pc_DriverName = "apci3300", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -56,10 +55,37 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci3300_driver = { + .driver_name = "addi_apci_3300", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci3300_boardtypes), + .board_name = &apci3300_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci3300_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci3300_driver); +} + +static void __devexit apci3300_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci3300_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3007) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci3300_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci3300_pci_driver = { + .name = "addi_apci_3300", + .id_table = apci3300_pci_table, + .probe = apci3300_pci_probe, + .remove = __devexit_p(apci3300_pci_remove), +}; +module_comedi_pci_driver(apci3300_driver, apci3300_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 49f0d1930d6..6543ba86820 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -4,12 +4,11 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_3501" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3501.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci3501_boardtypes[] = { { .pc_DriverName = "apci3501", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -38,13 +37,40 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static DEFINE_PCI_DEVICE_TABLE(apci3501_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci3501_pci_table); -#include "addi-data/addi_common.c" +static struct comedi_driver apci3501_driver = { + .driver_name = "addi_apci_3501", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci3501_boardtypes), + .board_name = &apci3501_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci3501_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci3501_driver); +} + +static void __devexit apci3501_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static struct pci_driver apci3501_pci_driver = { + .name = "addi_apci_3501", + .id_table = apci3501_pci_table, + .probe = apci3501_pci_probe, + .remove = __devexit_p(apci3501_pci_remove), +}; +module_comedi_pci_driver(apci3501_driver, apci3501_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index edc0eb0d113..86e17809b02 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -4,12 +4,11 @@ #include "addi-data/addi_common.h" #include "addi-data/addi_amcc_s5933.h" -#define ADDIDATA_DRIVER_NAME "addi_apci_3xxx" - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3xxx.c" +#include "addi-data/addi_common.c" -static const struct addi_board boardtypes[] = { +static const struct addi_board apci3xxx_boardtypes[] = { { .pc_DriverName = "apci3000-16", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -778,7 +777,28 @@ static const struct addi_board boardtypes[] = { }, }; -static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { +static struct comedi_driver apci3xxx_driver = { + .driver_name = "addi_apci_3xxx", + .module = THIS_MODULE, + .attach = i_ADDI_Attach, + .detach = i_ADDI_Detach, + .num_names = ARRAY_SIZE(apci3xxx_boardtypes), + .board_name = &apci3xxx_boardtypes[0].pc_DriverName, + .offset = sizeof(struct addi_board), +}; + +static int __devinit apci3xxx_pci_probe(struct pci_dev *dev, + const struct pci_device_id *ent) +{ + return comedi_pci_auto_config(dev, &apci3xxx_driver); +} + +static void __devexit apci3xxx_pci_remove(struct pci_dev *dev) +{ + comedi_pci_auto_unconfig(dev); +} + +static DEFINE_PCI_DEVICE_TABLE(apci3xxx_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3010) }, { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300f) }, { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x300e) }, @@ -806,9 +826,15 @@ static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3024) }, { 0 } }; -MODULE_DEVICE_TABLE(pci, addi_apci_tbl); +MODULE_DEVICE_TABLE(pci, apci3xxx_pci_table); -#include "addi-data/addi_common.c" +static struct pci_driver apci3xxx_pci_driver = { + .name = "addi_apci_3xxx", + .id_table = apci3xxx_pci_table, + .probe = apci3xxx_pci_probe, + .remove = __devexit_p(apci3xxx_pci_remove), +}; +module_comedi_pci_driver(apci3xxx_driver, apci3xxx_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); MODULE_DESCRIPTION("Comedi low-level driver"); -- cgit v1.2.3 From 39300ffb9b6666714c60735cf854e1280e4e75f4 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 1 Nov 2012 00:16:34 -0400 Subject: tools/power turbostat: Repair Segmentation fault when using -i option Fix regression caused by commit 8e180f3cb6b7510a3bdf14e16ce87c9f5d86f102 (tools/power turbostat: add [-d MSR#][-D MSR#] options to print counter deltas) Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 2655ae9a3ad..9942dee3df4 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -1594,7 +1594,7 @@ void cmdline(int argc, char **argv) progname = argv[0]; - while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) { + while ((opt = getopt(argc, argv, "+pPSvi:sc:sC:m:M:")) != -1) { switch (opt) { case 'p': show_core_only++; -- cgit v1.2.3 From d91bb17c2a874493603c4d99db305d8caf2d180c Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 1 Nov 2012 00:08:19 -0400 Subject: tools/power turbostat: graceful fail on garbage input When invald MSR's are specified on the command line, turbostat should simply print an error and exit. Signed-off-by: Len Brown --- tools/power/x86/turbostat/turbostat.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 9942dee3df4..ea095abbe97 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -206,8 +206,10 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) retval = pread(fd, msr, sizeof *msr, offset); close(fd); - if (retval != sizeof *msr) + if (retval != sizeof *msr) { + fprintf(stderr, "%s offset 0x%zx read failed\n", pathname, offset); return -1; + } return 0; } @@ -1101,7 +1103,9 @@ void turbostat_loop() restart: retval = for_all_cpus(get_counters, EVEN_COUNTERS); - if (retval) { + if (retval < -1) { + exit(retval); + } else if (retval == -1) { re_initialize(); goto restart; } @@ -1114,7 +1118,9 @@ restart: } sleep(interval_sec); retval = for_all_cpus(get_counters, ODD_COUNTERS); - if (retval) { + if (retval < -1) { + exit(retval); + } else if (retval == -1) { re_initialize(); goto restart; } @@ -1126,7 +1132,9 @@ restart: flush_stdout(); sleep(interval_sec); retval = for_all_cpus(get_counters, EVEN_COUNTERS); - if (retval) { + if (retval < -1) { + exit(retval); + } else if (retval == -1) { re_initialize(); goto restart; } @@ -1545,8 +1553,11 @@ void turbostat_init() int fork_it(char **argv) { pid_t child_pid; + int status; - for_all_cpus(get_counters, EVEN_COUNTERS); + status = for_all_cpus(get_counters, EVEN_COUNTERS); + if (status) + exit(status); /* clear affinity side-effect of get_counters() */ sched_setaffinity(0, cpu_present_setsize, cpu_present_set); gettimeofday(&tv_even, (struct timezone *)NULL); @@ -1556,7 +1567,6 @@ int fork_it(char **argv) /* child */ execvp(argv[0], argv); } else { - int status; /* parent */ if (child_pid == -1) { @@ -1568,7 +1578,7 @@ int fork_it(char **argv) signal(SIGQUIT, SIG_IGN); if (waitpid(child_pid, &status, 0) == -1) { perror("wait"); - exit(1); + exit(status); } } /* @@ -1585,7 +1595,7 @@ int fork_it(char **argv) fprintf(stderr, "%.6f sec\n", tv_delta.tv_sec + tv_delta.tv_usec/1000000.0); - return 0; + return status; } void cmdline(int argc, char **argv) -- cgit v1.2.3 From 1789e52acc90c87484a109d6349eefe63cabb257 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 31 Oct 2012 19:03:11 -0700 Subject: usb: phy: add R-Car USB phy driver This patch adds Renesas R-Car USB phy driver. It supports R8A7779 chip at this point. R-Car has some USB controllers, but has only one phy-initializer. So, this driver is counting users. Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- drivers/usb/phy/Kconfig | 12 +++ drivers/usb/phy/Makefile | 1 + drivers/usb/phy/rcar-phy.c | 220 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 drivers/usb/phy/rcar-phy.c diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 63c339b3e67..7eb73c561bd 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -32,3 +32,15 @@ config MV_U3D_PHY help Enable this to support Marvell USB 3.0 phy controller for Marvell SoC. + +config USB_RCAR_PHY + tristate "Renesas R-Car USB phy support" + depends on USB || USB_GADGET + select USB_OTG_UTILS + help + Say Y here to add support for the Renesas R-Car USB phy driver. + This chip is typically used as USB phy for USB host, gadget. + This driver supports: R8A7779 + + To compile this driver as a module, choose M here: the + module will be called rcar-phy. diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index b069f29f122..1a579a860a0 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_OMAP_USB2) += omap-usb2.o obj-$(CONFIG_USB_ISP1301) += isp1301.o obj-$(CONFIG_MV_U3D_PHY) += mv_u3d_phy.o obj-$(CONFIG_USB_EHCI_TEGRA) += tegra_usb_phy.o +obj-$(CONFIG_USB_RCAR_PHY) += rcar-phy.o diff --git a/drivers/usb/phy/rcar-phy.c b/drivers/usb/phy/rcar-phy.c new file mode 100644 index 00000000000..792f505d630 --- /dev/null +++ b/drivers/usb/phy/rcar-phy.c @@ -0,0 +1,220 @@ +/* + * Renesas R-Car USB phy driver + * + * Copyright (C) 2012 Renesas Solutions Corp. + * Kuninori Morimoto + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +/* USBH common register */ +#define USBPCTRL0 0x0800 +#define USBPCTRL1 0x0804 +#define USBST 0x0808 +#define USBEH0 0x080C +#define USBOH0 0x081C +#define USBCTL0 0x0858 +#define EIIBC1 0x0094 +#define EIIBC2 0x009C + +/* USBPCTRL1 */ +#define PHY_RST (1 << 2) +#define PLL_ENB (1 << 1) +#define PHY_ENB (1 << 0) + +/* USBST */ +#define ST_ACT (1 << 31) +#define ST_PLL (1 << 30) + +struct rcar_usb_phy_priv { + struct usb_phy phy; + spinlock_t lock; + + void __iomem *reg0; + void __iomem *reg1; + int counter; +}; + +#define usb_phy_to_priv(p) container_of(p, struct rcar_usb_phy_priv, phy) + + +/* + * USB initial/install operation. + * + * This function setup USB phy. + * The used value and setting order came from + * [USB :: Initial setting] on datasheet. + */ +static int rcar_usb_phy_init(struct usb_phy *phy) +{ + struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy); + struct device *dev = phy->dev; + void __iomem *reg0 = priv->reg0; + void __iomem *reg1 = priv->reg1; + int i; + u32 val; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (priv->counter++ == 0) { + + /* + * USB phy start-up + */ + + /* (1) USB-PHY standby release */ + iowrite32(PHY_ENB, (reg0 + USBPCTRL1)); + + /* (2) start USB-PHY internal PLL */ + iowrite32(PHY_ENB | PLL_ENB, (reg0 + USBPCTRL1)); + + /* (3) USB module status check */ + for (i = 0; i < 1024; i++) { + udelay(10); + val = ioread32(reg0 + USBST); + if (val == (ST_ACT | ST_PLL)) + break; + } + + if (val != (ST_ACT | ST_PLL)) { + dev_err(dev, "USB phy not ready\n"); + goto phy_init_end; + } + + /* (4) USB-PHY reset clear */ + iowrite32(PHY_ENB | PLL_ENB | PHY_RST, (reg0 + USBPCTRL1)); + + /* set platform specific port settings */ + iowrite32(0x00000000, (reg0 + USBPCTRL0)); + + /* + * EHCI IP internal buffer setting + * EHCI IP internal buffer enable + * + * These are recommended value of a datasheet + * see [USB :: EHCI internal buffer setting] + */ + iowrite32(0x00ff0040, (reg0 + EIIBC1)); + iowrite32(0x00ff0040, (reg1 + EIIBC1)); + + iowrite32(0x00000001, (reg0 + EIIBC2)); + iowrite32(0x00000001, (reg1 + EIIBC2)); + + /* + * Bus alignment settings + */ + + /* (1) EHCI bus alignment (little endian) */ + iowrite32(0x00000000, (reg0 + USBEH0)); + + /* (1) OHCI bus alignment (little endian) */ + iowrite32(0x00000000, (reg0 + USBOH0)); + } + +phy_init_end: + spin_unlock_irqrestore(&priv->lock, flags); + + return 0; +} + +static void rcar_usb_phy_shutdown(struct usb_phy *phy) +{ + struct rcar_usb_phy_priv *priv = usb_phy_to_priv(phy); + void __iomem *reg0 = priv->reg0; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + + if (priv->counter-- == 1) { /* last user */ + iowrite32(0x00000000, (reg0 + USBPCTRL0)); + iowrite32(0x00000000, (reg0 + USBPCTRL1)); + } + + spin_unlock_irqrestore(&priv->lock, flags); +} + +static int __devinit rcar_usb_phy_probe(struct platform_device *pdev) +{ + struct rcar_usb_phy_priv *priv; + struct resource *res0, *res1; + struct device *dev = &pdev->dev; + void __iomem *reg0, *reg1; + int ret; + + res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); + res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res0 || !res1) { + dev_err(dev, "Not enough platform resources\n"); + return -EINVAL; + } + + /* + * CAUTION + * + * Because this phy address is also mapped under OHCI/EHCI address area, + * this driver can't use devm_request_and_ioremap(dev, res) here + */ + reg0 = devm_ioremap_nocache(dev, res0->start, resource_size(res0)); + reg1 = devm_ioremap_nocache(dev, res1->start, resource_size(res1)); + if (!reg0 || !reg1) { + dev_err(dev, "ioremap error\n"); + return -ENOMEM; + } + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(dev, "priv data allocation error\n"); + return -ENOMEM; + } + + priv->reg0 = reg0; + priv->reg1 = reg1; + priv->counter = 0; + priv->phy.dev = dev; + priv->phy.label = dev_name(dev); + priv->phy.init = rcar_usb_phy_init; + priv->phy.shutdown = rcar_usb_phy_shutdown; + spin_lock_init(&priv->lock); + + ret = usb_add_phy(&priv->phy, USB_PHY_TYPE_USB2); + if (ret < 0) { + dev_err(dev, "usb phy addition error\n"); + return ret; + } + + platform_set_drvdata(pdev, priv); + + return ret; +} + +static int __devexit rcar_usb_phy_remove(struct platform_device *pdev) +{ + struct rcar_usb_phy_priv *priv = platform_get_drvdata(pdev); + + usb_remove_phy(&priv->phy); + + return 0; +} + +static struct platform_driver rcar_usb_phy_driver = { + .driver = { + .name = "rcar_usb_phy", + }, + .probe = rcar_usb_phy_probe, + .remove = __devexit_p(rcar_usb_phy_remove), +}; + +module_platform_driver(rcar_usb_phy_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Renesas R-Car USB phy"); +MODULE_AUTHOR("Kuninori Morimoto "); -- cgit v1.2.3 From 2f7711642559851c187d09795a3eb51c2bde36ec Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 31 Oct 2012 16:12:43 +0100 Subject: usb: musb: remove hand-crafted id handling This replaced the handcrafted id handling by the PLATFORM_DEVID_AUTO value which should do the same thing. This patch probably also fixes ux500 because I did not find the "musbid" variable to remove. And we close a tiny-unlikely race window becuase the old code gave the id back before device was destroyed in the remove case. [ balbi@ti.com : fixed up two failed hunks when applying patch ] Cc: B, Ravi Cc: Santhapuri, Damodar Cc: Mian Yousaf Kaukab Cc: Bob Liu Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/musb/am35x.c | 18 ++---------------- drivers/usb/musb/blackfin.c | 18 ++---------------- drivers/usb/musb/da8xx.c | 18 ++---------------- drivers/usb/musb/davinci.c | 18 ++---------------- drivers/usb/musb/musb_core.c | 30 ------------------------------ drivers/usb/musb/musb_core.h | 2 -- drivers/usb/musb/musb_dsps.c | 26 +++++--------------------- drivers/usb/musb/omap2430.c | 24 +++++------------------- drivers/usb/musb/tusb6010.c | 18 ++---------------- drivers/usb/musb/ux500.c | 18 ++---------------- 10 files changed, 22 insertions(+), 168 deletions(-) diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index fdfd779c35b..3ff30b9a589 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -459,7 +459,6 @@ static int __devinit am35x_probe(struct platform_device *pdev) struct clk *clk; int ret = -ENOMEM; - int musbid; glue = kzalloc(sizeof(*glue), GFP_KERNEL); if (!glue) { @@ -467,18 +466,10 @@ static int __devinit am35x_probe(struct platform_device *pdev) goto err0; } - /* get the musb id */ - musbid = musb_get_id(&pdev->dev, GFP_KERNEL); - if (musbid < 0) { - dev_err(&pdev->dev, "failed to allocate musb id\n"); - ret = -ENOMEM; - goto err1; - } - - musb = platform_device_alloc("musb-hdrc", musbid); + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); if (!musb) { dev_err(&pdev->dev, "failed to allocate musb device\n"); - goto err2; + goto err1; } phy_clk = clk_get(&pdev->dev, "fck"); @@ -507,7 +498,6 @@ static int __devinit am35x_probe(struct platform_device *pdev) goto err6; } - musb->id = musbid; musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &am35x_dmamask; musb->dev.coherent_dma_mask = am35x_dmamask; @@ -557,9 +547,6 @@ err4: err3: platform_device_put(musb); -err2: - musb_put_id(&pdev->dev, musbid); - err1: kfree(glue); @@ -571,7 +558,6 @@ static int __devexit am35x_remove(struct platform_device *pdev) { struct am35x_glue *glue = platform_get_drvdata(pdev); - musb_put_id(&pdev->dev, glue->musb->id); platform_device_unregister(glue->musb); clk_disable(glue->clk); clk_disable(glue->phy_clk); diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 307e726a2bd..7e4d60a4172 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -455,7 +455,6 @@ static int __devinit bfin_probe(struct platform_device *pdev) struct bfin_glue *glue; int ret = -ENOMEM; - int musbid; glue = kzalloc(sizeof(*glue), GFP_KERNEL); if (!glue) { @@ -463,21 +462,12 @@ static int __devinit bfin_probe(struct platform_device *pdev) goto err0; } - /* get the musb id */ - musbid = musb_get_id(&pdev->dev, GFP_KERNEL); - if (musbid < 0) { - dev_err(&pdev->dev, "failed to allocate musb id\n"); - ret = -ENOMEM; - goto err1; - } - - musb = platform_device_alloc("musb-hdrc", musbid); + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); if (!musb) { dev_err(&pdev->dev, "failed to allocate musb device\n"); - goto err2; + goto err1; } - musb->id = musbid; musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &bfin_dmamask; musb->dev.coherent_dma_mask = bfin_dmamask; @@ -513,9 +503,6 @@ static int __devinit bfin_probe(struct platform_device *pdev) err3: platform_device_put(musb); -err2: - musb_put_id(&pdev->dev, musbid); - err1: kfree(glue); @@ -527,7 +514,6 @@ static int __devexit bfin_remove(struct platform_device *pdev) { struct bfin_glue *glue = platform_get_drvdata(pdev); - musb_put_id(&pdev->dev, glue->musb->id); platform_device_unregister(glue->musb); kfree(glue); diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index e94f556c6ae..67b8ae704e9 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -480,7 +480,6 @@ static int __devinit da8xx_probe(struct platform_device *pdev) struct clk *clk; int ret = -ENOMEM; - int musbid; glue = kzalloc(sizeof(*glue), GFP_KERNEL); if (!glue) { @@ -488,18 +487,10 @@ static int __devinit da8xx_probe(struct platform_device *pdev) goto err0; } - /* get the musb id */ - musbid = musb_get_id(&pdev->dev, GFP_KERNEL); - if (musbid < 0) { - dev_err(&pdev->dev, "failed to allocate musb id\n"); - ret = -ENOMEM; - goto err1; - } - - musb = platform_device_alloc("musb-hdrc", musbid); + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); if (!musb) { dev_err(&pdev->dev, "failed to allocate musb device\n"); - goto err2; + goto err1; } clk = clk_get(&pdev->dev, "usb20"); @@ -515,7 +506,6 @@ static int __devinit da8xx_probe(struct platform_device *pdev) goto err4; } - musb->id = musbid; musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &da8xx_dmamask; musb->dev.coherent_dma_mask = da8xx_dmamask; @@ -558,9 +548,6 @@ err4: err3: platform_device_put(musb); -err2: - musb_put_id(&pdev->dev, musbid); - err1: kfree(glue); @@ -572,7 +559,6 @@ static int __devexit da8xx_remove(struct platform_device *pdev) { struct da8xx_glue *glue = platform_get_drvdata(pdev); - musb_put_id(&pdev->dev, glue->musb->id); platform_device_unregister(glue->musb); clk_disable(glue->clk); clk_put(glue->clk); diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 959a6d71e1d..b3c0a943950 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -512,7 +512,6 @@ static int __devinit davinci_probe(struct platform_device *pdev) struct clk *clk; int ret = -ENOMEM; - int musbid; glue = kzalloc(sizeof(*glue), GFP_KERNEL); if (!glue) { @@ -520,18 +519,10 @@ static int __devinit davinci_probe(struct platform_device *pdev) goto err0; } - /* get the musb id */ - musbid = musb_get_id(&pdev->dev, GFP_KERNEL); - if (musbid < 0) { - dev_err(&pdev->dev, "failed to allocate musb id\n"); - ret = -ENOMEM; - goto err1; - } - - musb = platform_device_alloc("musb-hdrc", musbid); + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); if (!musb) { dev_err(&pdev->dev, "failed to allocate musb device\n"); - goto err2; + goto err1; } clk = clk_get(&pdev->dev, "usb"); @@ -547,7 +538,6 @@ static int __devinit davinci_probe(struct platform_device *pdev) goto err4; } - musb->id = musbid; musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &davinci_dmamask; musb->dev.coherent_dma_mask = davinci_dmamask; @@ -590,9 +580,6 @@ err4: err3: platform_device_put(musb); -err2: - musb_put_id(&pdev->dev, musbid); - err1: kfree(glue); @@ -604,7 +591,6 @@ static int __devexit davinci_remove(struct platform_device *pdev) { struct davinci_glue *glue = platform_get_drvdata(pdev); - musb_put_id(&pdev->dev, glue->musb->id); platform_device_unregister(glue->musb); clk_disable(glue->clk); clk_put(glue->clk); diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 25a0d8e1be5..78037bfad96 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -116,7 +116,6 @@ #define MUSB_DRIVER_NAME "musb-hdrc" const char musb_driver_name[] = MUSB_DRIVER_NAME; -static DEFINE_IDA(musb_ida); MODULE_DESCRIPTION(DRIVER_INFO); MODULE_AUTHOR(DRIVER_AUTHOR); @@ -133,35 +132,6 @@ static inline struct musb *dev_to_musb(struct device *dev) /*-------------------------------------------------------------------------*/ -int musb_get_id(struct device *dev, gfp_t gfp_mask) -{ - int ret; - int id; - - ret = ida_pre_get(&musb_ida, gfp_mask); - if (!ret) { - dev_err(dev, "failed to reserve resource for id\n"); - return -ENOMEM; - } - - ret = ida_get_new(&musb_ida, &id); - if (ret < 0) { - dev_err(dev, "failed to allocate a new id\n"); - return ret; - } - - return id; -} -EXPORT_SYMBOL_GPL(musb_get_id); - -void musb_put_id(struct device *dev, int id) -{ - - dev_dbg(dev, "removing id %d\n", id); - ida_remove(&musb_ida, id); -} -EXPORT_SYMBOL_GPL(musb_put_id); - #ifndef CONFIG_BLACKFIN static int musb_ulpi_read(struct usb_phy *phy, u32 offset) { diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 0cef3ceb52c..7fb4819a6f1 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -522,8 +522,6 @@ extern const char musb_driver_name[]; extern void musb_start(struct musb *musb); extern void musb_stop(struct musb *musb); -extern int musb_get_id(struct device *dev, gfp_t gfp_mask); -extern void musb_put_id(struct device *dev, int id); extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src); extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst); diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 828d2a216d9..2d2cd37bc7b 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -459,7 +459,7 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) struct resource *res; struct resource resources[2]; char res_name[10]; - int ret, musbid; + int ret; /* get memory resource */ sprintf(res_name, "musb%d", id); @@ -484,22 +484,14 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) resources[1] = *res; resources[1].name = "mc"; - /* get the musb id */ - musbid = musb_get_id(dev, GFP_KERNEL); - if (musbid < 0) { - dev_err(dev, "failed to allocate musb id\n"); - ret = -ENOMEM; - goto err0; - } /* allocate the child platform device */ - musb = platform_device_alloc("musb-hdrc", musbid); + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); if (!musb) { dev_err(dev, "failed to allocate musb device\n"); ret = -ENOMEM; - goto err1; + goto err0; } - musb->id = musbid; musb->dev.parent = dev; musb->dev.dma_mask = &musb_dmamask; musb->dev.coherent_dma_mask = musb_dmamask; @@ -556,18 +548,10 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) err2: platform_device_put(musb); -err1: - musb_put_id(dev, musbid); err0: return ret; } -static void dsps_delete_musb_pdev(struct dsps_glue *glue, u8 id) -{ - musb_put_id(glue->dev, glue->musb[id]->id); - platform_device_unregister(glue->musb[id]); -} - static int __devinit dsps_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -627,7 +611,7 @@ static int __devinit dsps_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to create child pdev\n"); /* release resources of previously created instances */ for (i--; i >= 0 ; i--) - dsps_delete_musb_pdev(glue, i); + platform_device_unregister(glue->musb[i]); goto err3; } } @@ -652,7 +636,7 @@ static int __devexit dsps_remove(struct platform_device *pdev) /* delete the child platform device */ for (i = 0; i < wrp->instances ; i++) - dsps_delete_musb_pdev(glue, i); + platform_device_unregister(glue->musb[i]); /* disable usbss clocks */ pm_runtime_put(&pdev->dev); diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index a538fe17a96..dddd8f71a17 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -478,7 +478,6 @@ static int __devinit omap2430_probe(struct platform_device *pdev) struct musb_hdrc_config *config; struct resource *res; int ret = -ENOMEM; - int musbid; glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL); if (!glue) { @@ -486,21 +485,12 @@ static int __devinit omap2430_probe(struct platform_device *pdev) goto err0; } - /* get the musb id */ - musbid = musb_get_id(&pdev->dev, GFP_KERNEL); - if (musbid < 0) { - dev_err(&pdev->dev, "failed to allocate musb id\n"); - ret = -ENOMEM; - goto err0; - } - - musb = platform_device_alloc("musb-hdrc", musbid); + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); if (!musb) { dev_err(&pdev->dev, "failed to allocate musb device\n"); - goto err1; + goto err0; } - musb->id = musbid; musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &omap2430_dmamask; musb->dev.coherent_dma_mask = omap2430_dmamask; @@ -521,7 +511,7 @@ static int __devinit omap2430_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to allocate musb platfrom data\n"); ret = -ENOMEM; - goto err1; + goto err2; } data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); @@ -529,14 +519,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev) dev_err(&pdev->dev, "failed to allocate musb board data\n"); ret = -ENOMEM; - goto err1; + goto err2; } config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); if (!data) { dev_err(&pdev->dev, "failed to allocate musb hdrc config\n"); - goto err1; + goto err2; } of_property_read_u32(np, "mode", (u32 *)&pdata->mode); @@ -589,9 +579,6 @@ static int __devinit omap2430_probe(struct platform_device *pdev) err2: platform_device_put(musb); -err1: - musb_put_id(&pdev->dev, musbid); - err0: return ret; } @@ -601,7 +588,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev) struct omap2430_glue *glue = platform_get_drvdata(pdev); cancel_work_sync(&glue->omap_musb_mailbox_work); - musb_put_id(&pdev->dev, glue->musb->id); platform_device_unregister(glue->musb); return 0; diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 4454561c6f5..812719b683d 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1160,7 +1160,6 @@ static int __devinit tusb_probe(struct platform_device *pdev) struct tusb6010_glue *glue; int ret = -ENOMEM; - int musbid; glue = kzalloc(sizeof(*glue), GFP_KERNEL); if (!glue) { @@ -1168,21 +1167,12 @@ static int __devinit tusb_probe(struct platform_device *pdev) goto err0; } - /* get the musb id */ - musbid = musb_get_id(&pdev->dev, GFP_KERNEL); - if (musbid < 0) { - dev_err(&pdev->dev, "failed to allocate musb id\n"); - ret = -ENOMEM; - goto err1; - } - - musb = platform_device_alloc("musb-hdrc", musbid); + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); if (!musb) { dev_err(&pdev->dev, "failed to allocate musb device\n"); - goto err2; + goto err1; } - musb->id = musbid; musb->dev.parent = &pdev->dev; musb->dev.dma_mask = &tusb_dmamask; musb->dev.coherent_dma_mask = tusb_dmamask; @@ -1218,9 +1208,6 @@ static int __devinit tusb_probe(struct platform_device *pdev) err3: platform_device_put(musb); -err2: - musb_put_id(&pdev->dev, musbid); - err1: kfree(glue); @@ -1232,7 +1219,6 @@ static int __devexit tusb_remove(struct platform_device *pdev) { struct tusb6010_glue *glue = platform_get_drvdata(pdev); - musb_put_id(&pdev->dev, glue->musb->id); platform_device_unregister(glue->musb); kfree(glue); diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 4197f307ae0..5e9053eb429 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -65,7 +65,6 @@ static int __devinit ux500_probe(struct platform_device *pdev) struct platform_device *musb; struct ux500_glue *glue; struct clk *clk; - int ret = -ENOMEM; glue = kzalloc(sizeof(*glue), GFP_KERNEL); @@ -74,18 +73,10 @@ static int __devinit ux500_probe(struct platform_device *pdev) goto err0; } - /* get the musb id */ - musbid = musb_get_id(&pdev->dev, GFP_KERNEL); - if (musbid < 0) { - dev_err(&pdev->dev, "failed to allocate musb id\n"); - ret = -ENOMEM; - goto err1; - } - - musb = platform_device_alloc("musb-hdrc", musbid); + musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO); if (!musb) { dev_err(&pdev->dev, "failed to allocate musb device\n"); - goto err2; + goto err1; } clk = clk_get(&pdev->dev, "usb"); @@ -101,7 +92,6 @@ static int __devinit ux500_probe(struct platform_device *pdev) goto err4; } - musb->id = musbid; musb->dev.parent = &pdev->dev; musb->dev.dma_mask = pdev->dev.dma_mask; musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; @@ -144,9 +134,6 @@ err4: err3: platform_device_put(musb); -err2: - musb_put_id(&pdev->dev, musbid); - err1: kfree(glue); @@ -158,7 +145,6 @@ static int __devexit ux500_remove(struct platform_device *pdev) { struct ux500_glue *glue = platform_get_drvdata(pdev); - musb_put_id(&pdev->dev, glue->musb->id); platform_device_unregister(glue->musb); clk_disable(glue->clk); clk_put(glue->clk); -- cgit v1.2.3 From 59fa6245192159ab5e1e17b8e31f15afa9cff4bf Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 23 Oct 2012 22:29:38 +0200 Subject: futex: Handle futex_pi OWNER_DIED take over correctly Siddhesh analyzed a failure in the take over of pi futexes in case the owner died and provided a workaround. See: http://sourceware.org/bugzilla/show_bug.cgi?id=14076 The detailed problem analysis shows: Futex F is initialized with PTHREAD_PRIO_INHERIT and PTHREAD_MUTEX_ROBUST_NP attributes. T1 lock_futex_pi(F); T2 lock_futex_pi(F); --> T2 blocks on the futex and creates pi_state which is associated to T1. T1 exits --> exit_robust_list() runs --> Futex F userspace value TID field is set to 0 and FUTEX_OWNER_DIED bit is set. T3 lock_futex_pi(F); --> Succeeds due to the check for F's userspace TID field == 0 --> Claims ownership of the futex and sets its own TID into the userspace TID field of futex F --> returns to user space T1 --> exit_pi_state_list() --> Transfers pi_state to waiter T2 and wakes T2 via rt_mutex_unlock(&pi_state->mutex) T2 --> acquires pi_state->mutex and gains real ownership of the pi_state --> Claims ownership of the futex and sets its own TID into the userspace TID field of futex F --> returns to user space T3 --> observes inconsistent state This problem is independent of UP/SMP, preemptible/non preemptible kernels, or process shared vs. private. The only difference is that certain configurations are more likely to expose it. So as Siddhesh correctly analyzed the following check in futex_lock_pi_atomic() is the culprit: if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { We check the userspace value for a TID value of 0 and take over the futex unconditionally if that's true. AFAICT this check is there as it is correct for a different corner case of futexes: the WAITERS bit became stale. Now the proposed change - if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { + if (unlikely(ownerdied || + !(curval & (FUTEX_TID_MASK | FUTEX_WAITERS)))) { solves the problem, but it's not obvious why and it wreckages the "stale WAITERS bit" case. What happens is, that due to the WAITERS bit being set (T2 is blocked on that futex) it enforces T3 to go through lookup_pi_state(), which in the above case returns an existing pi_state and therefor forces T3 to legitimately fight with T2 over the ownership of the pi_state (via pi_state->mutex). Probelm solved! Though that does not work for the "WAITERS bit is stale" problem because if lookup_pi_state() does not find existing pi_state it returns -ERSCH (due to TID == 0) which causes futex_lock_pi() to return -ESRCH to user space because the OWNER_DIED bit is not set. Now there is a different solution to that problem. Do not look at the user space value at all and enforce a lookup of possibly available pi_state. If pi_state can be found, then the new incoming locker T3 blocks on that pi_state and legitimately races with T2 to acquire the rt_mutex and the pi_state and therefor the proper ownership of the user space futex. lookup_pi_state() has the correct order of checks. It first tries to find a pi_state associated with the user space futex and only if that fails it checks for futex TID value = 0. If no pi_state is available nothing can create new state at that point because this happens with the hash bucket lock held. So the above scenario changes to: T1 lock_futex_pi(F); T2 lock_futex_pi(F); --> T2 blocks on the futex and creates pi_state which is associated to T1. T1 exits --> exit_robust_list() runs --> Futex F userspace value TID field is set to 0 and FUTEX_OWNER_DIED bit is set. T3 lock_futex_pi(F); --> Finds pi_state and blocks on pi_state->rt_mutex T1 --> exit_pi_state_list() --> Transfers pi_state to waiter T2 and wakes it via rt_mutex_unlock(&pi_state->mutex) T2 --> acquires pi_state->mutex and gains ownership of the pi_state --> Claims ownership of the futex and sets its own TID into the userspace TID field of futex F --> returns to user space This covers all gazillion points on which T3 might come in between T1's exit_robust_list() clearing the TID field and T2 fixing it up. It also solves the "WAITERS bit stale" problem by forcing the take over. Another benefit of changing the code this way is that it makes it less dependent on untrusted user space values and therefor minimizes the possible wreckage which might be inflicted. As usual after staring for too long at the futex code my brain hurts so much that I really want to ditch that whole optimization of avoiding the syscall for the non contended case for PI futexes and rip out the maze of corner case handling code. Unfortunately we can't as user space relies on that existing behaviour, but at least thinking about it helps me to preserve my mental sanity. Maybe we should nevertheless :) Reported-and-tested-by: Siddhesh Poyarekar Link: http://lkml.kernel.org/r/alpine.LFD.2.02.1210232138540.2756@ionos Acked-by: Darren Hart Cc: stable@vger.kernel.org Signed-off-by: Thomas Gleixner --- kernel/futex.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/kernel/futex.c b/kernel/futex.c index 3717e7b306e..20ef219bbe9 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -716,7 +716,7 @@ static int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, struct futex_pi_state **ps, struct task_struct *task, int set_waiters) { - int lock_taken, ret, ownerdied = 0; + int lock_taken, ret, force_take = 0; u32 uval, newval, curval, vpid = task_pid_vnr(task); retry: @@ -755,17 +755,15 @@ retry: newval = curval | FUTEX_WAITERS; /* - * There are two cases, where a futex might have no owner (the - * owner TID is 0): OWNER_DIED. We take over the futex in this - * case. We also do an unconditional take over, when the owner - * of the futex died. - * - * This is safe as we are protected by the hash bucket lock ! + * Should we force take the futex? See below. */ - if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { - /* Keep the OWNER_DIED bit */ + if (unlikely(force_take)) { + /* + * Keep the OWNER_DIED and the WAITERS bit and set the + * new TID value. + */ newval = (curval & ~FUTEX_TID_MASK) | vpid; - ownerdied = 0; + force_take = 0; lock_taken = 1; } @@ -775,7 +773,7 @@ retry: goto retry; /* - * We took the lock due to owner died take over. + * We took the lock due to forced take over. */ if (unlikely(lock_taken)) return 1; @@ -790,20 +788,25 @@ retry: switch (ret) { case -ESRCH: /* - * No owner found for this futex. Check if the - * OWNER_DIED bit is set to figure out whether - * this is a robust futex or not. + * We failed to find an owner for this + * futex. So we have no pi_state to block + * on. This can happen in two cases: + * + * 1) The owner died + * 2) A stale FUTEX_WAITERS bit + * + * Re-read the futex value. */ if (get_futex_value_locked(&curval, uaddr)) return -EFAULT; /* - * We simply start over in case of a robust - * futex. The code above will take the futex - * and return happy. + * If the owner died or we have a stale + * WAITERS bit the owner TID in the user space + * futex is 0. */ - if (curval & FUTEX_OWNER_DIED) { - ownerdied = 1; + if (!(curval & FUTEX_TID_MASK)) { + force_take = 1; goto retry; } default: -- cgit v1.2.3 From 293a7a0a165c4f8327bbcf396cee9ec672727c98 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 16 Oct 2012 15:07:49 -0700 Subject: genirq: Provide means to retrigger parent Attempts to retrigger nested threaded IRQs currently fail because they have no primary handler. In order to support retrigger of nested IRQs, the parent IRQ needs to be retriggered. To fix, when an IRQ needs to be resent, if the interrupt has a parent IRQ and runs in the context of the parent IRQ, then resend the parent. Also, handle_nested_irq() needs to clear the replay flag like the other handlers, otherwise check_irq_resend() will set it and it will never be cleared. Without clearing, it results in the first resend working fine, but check_irq_resend() returning early on subsequent resends because the replay flag is still set. Problem discovered on ARM/OMAP platforms where a nested IRQ that's also a wakeup IRQ happens late in suspend and needed to be retriggered during the resume process. [khilman@ti.com: changelog edits, clear IRQS_REPLAY in handle_nested_irq()] Reported-by: Kevin Hilman Tested-by: Kevin Hilman Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/1350425269-11489-1-git-send-email-khilman@deeprootsystems.com Signed-off-by: Thomas Gleixner --- include/linux/irq.h | 9 +++++++++ include/linux/irqdesc.h | 3 +++ kernel/irq/chip.c | 1 + kernel/irq/manage.c | 16 ++++++++++++++++ kernel/irq/resend.c | 8 ++++++++ 5 files changed, 37 insertions(+) diff --git a/include/linux/irq.h b/include/linux/irq.h index 216b0ba109d..526f10a637c 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -392,6 +392,15 @@ static inline void irq_move_masked_irq(struct irq_data *data) { } extern int no_irq_affinity; +#ifdef CONFIG_HARDIRQS_SW_RESEND +int irq_set_parent(int irq, int parent_irq); +#else +static inline int irq_set_parent(int irq, int parent_irq) +{ + return 0; +} +#endif + /* * Built-in IRQ handlers for various IRQ types, * callable via desc->handle_irq() diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h index 0ba014c5505..623325e2ff9 100644 --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h @@ -11,6 +11,8 @@ struct irq_affinity_notify; struct proc_dir_entry; struct module; +struct irq_desc; + /** * struct irq_desc - interrupt descriptor * @irq_data: per irq and chip data passed down to chip functions @@ -65,6 +67,7 @@ struct irq_desc { #ifdef CONFIG_PROC_FS struct proc_dir_entry *dir; #endif + int parent_irq; struct module *owner; const char *name; } ____cacheline_internodealigned_in_smp; diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 57d86d07221..3aca9f29d30 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -272,6 +272,7 @@ void handle_nested_irq(unsigned int irq) raw_spin_lock_irq(&desc->lock); + desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING); kstat_incr_irqs_this_cpu(irq, desc); action = desc->action; diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 4c69326aa77..d06a396c7ce 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -616,6 +616,22 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, return ret; } +#ifdef CONFIG_HARDIRQS_SW_RESEND +int irq_set_parent(int irq, int parent_irq) +{ + unsigned long flags; + struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); + + if (!desc) + return -EINVAL; + + desc->parent_irq = parent_irq; + + irq_put_desc_unlock(desc, flags); + return 0; +} +#endif + /* * Default primary interrupt handler for threaded interrupts. Is * assigned as primary handler when request_threaded_irq is called diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c index 6454db7b6a4..9065107f083 100644 --- a/kernel/irq/resend.c +++ b/kernel/irq/resend.c @@ -74,6 +74,14 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq) if (!desc->irq_data.chip->irq_retrigger || !desc->irq_data.chip->irq_retrigger(&desc->irq_data)) { #ifdef CONFIG_HARDIRQS_SW_RESEND + /* + * If the interrupt has a parent irq and runs + * in the thread context of the parent irq, + * retrigger the parent. + */ + if (desc->parent_irq && + irq_settings_is_nested_thread(desc)) + irq = desc->parent_irq; /* Set it pending and activate the softirq: */ set_bit(irq, irqs_resend); tasklet_schedule(&resend_tasklet); -- cgit v1.2.3 From f3de44edf376d18773febca6a37800c042bada7d Mon Sep 17 00:00:00 2001 From: Sankara Muthukrishnan Date: Wed, 31 Oct 2012 15:41:23 -0500 Subject: irq: Set CPU affinity right on thread creation As irq_thread_check_affinity is called ONLY inside the while loop in the irq thread, the core affinity is set only when an interrupt occurs. This patch sets the core affinity right after the irq thread is created and before it waits for interrupts. In real-tiime targets that do not typically change the core affinity of irqs during run-time, this patch will save additional latency of an irq thread in setting the core affinity during the first interrupt occurrence for that irq. Signed-off-by: Sankara S Muthukrishnan Acked-by: Steven Rostedt Link: http://lkml.kernel.org/r/CAFQPvXeVZ858WFYimEU5uvLNxLDd6bJMmqWihFmbCf3ntokz0A@mail.gmail.com Signed-off-by: Thomas Gleixner --- kernel/irq/manage.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index d06a396c7ce..1cbd572f6ad 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -849,6 +849,8 @@ static int irq_thread(void *data) init_task_work(&on_exit_work, irq_thread_dtor); task_work_add(current, &on_exit_work, false); + irq_thread_check_affinity(desc, action); + while (!irq_wait_for_interrupt(action)) { irqreturn_t action_ret; -- cgit v1.2.3 From b8f61116c1ce342804a0897b0a80eb4df5f19453 Mon Sep 17 00:00:00 2001 From: Chuansheng Liu Date: Thu, 25 Oct 2012 01:07:35 +0800 Subject: tick: Correct the comments for tick_sched_timer() In the comments of function tick_sched_timer(), the sentence "timer->base->cpu_base->lock held" is not right. In function __run_hrtimer(), before call timer->function(), the cpu_base->lock has been unlocked. Signed-off-by: liu chuansheng Cc: fei.li@intel.com Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351098455.15558.1421.camel@cliu38-desktop-build Signed-off-by: Thomas Gleixner --- kernel/time/tick-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 766d4c47a4a..77729cc3750 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -809,7 +809,7 @@ void tick_check_idle(int cpu) #ifdef CONFIG_HIGH_RES_TIMERS /* * We rearm the timer until we get disabled by the idle code. - * Called with interrupts disabled and timer->base->cpu_base->lock held. + * Called with interrupts disabled. */ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) { -- cgit v1.2.3 From 9f4c3f1cde541d477633479a0203ef8a834ee5f9 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 31 Oct 2012 01:20:05 -0200 Subject: ASoC: mxs-saif: Add MODULE_ALIAS Add MODULE_ALIAS information. Signed-off-by: Fabio Estevam Acked-by: Dong Aisheng Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-saif.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index aa037b292f3..93380cc7cf9 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -812,3 +812,4 @@ module_platform_driver(mxs_saif_driver); MODULE_AUTHOR("Freescale Semiconductor, Inc."); MODULE_DESCRIPTION("MXS ASoC SAIF driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:mxs-saif"); -- cgit v1.2.3 From 92db8be4ca6c9005fedf2219fc0f4507919c2477 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:54:43 -0700 Subject: staging: comedi: addi-data: remove v_pci_card_list_display() This function dumps a list of all the add-data PCI cards found. This information is just noise. Remove the function. Also, remove the parameter from v_pci_card_list_init() that caused this information to be dumped. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/addi_amcc_s5933.h | 30 ++-------------------- .../staging/comedi/drivers/addi-data/addi_common.c | 2 +- 2 files changed, 3 insertions(+), 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h index 95f7dc61cd0..c836b3bd74d 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h @@ -212,7 +212,7 @@ static const int i_ADDIDATADeviceID[] = { 0x15B8, 0x10E8 }; /****************************************************************************/ -void v_pci_card_list_init(unsigned short pci_vendor, char display); +void v_pci_card_list_init(unsigned short pci_vendor); void v_pci_card_list_cleanup(unsigned short pci_vendor); struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id, unsigned short @@ -230,7 +230,6 @@ struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, int pci_card_alloc(struct pcilst_struct *amcc, int master); int i_pci_card_free(struct pcilst_struct *amcc); -void v_pci_card_list_display(void); int i_pci_card_data(struct pcilst_struct *amcc, unsigned char *pci_bus, unsigned char *pci_slot, unsigned char *pci_func, resource_size_t * io_addr, @@ -239,7 +238,7 @@ int i_pci_card_data(struct pcilst_struct *amcc, /****************************************************************************/ /* build list of amcc cards in this system */ -void v_pci_card_list_init(unsigned short pci_vendor, char display) +void v_pci_card_list_init(unsigned short pci_vendor) { struct pci_dev *pcidev = NULL; struct pcilst_struct *amcc, *last; @@ -279,9 +278,6 @@ void v_pci_card_list_init(unsigned short pci_vendor, char display) } } } - - if (display) - v_pci_card_list_display(); } /****************************************************************************/ @@ -384,28 +380,6 @@ int i_pci_card_free(struct pcilst_struct *amcc) return 0; } -/****************************************************************************/ -/* display list of found cards */ -void v_pci_card_list_display(void) -{ - struct pcilst_struct *amcc, *next; - - printk(KERN_DEBUG "List of pci cards\n"); - printk(KERN_DEBUG "bus:slot:func vendor device io_amcc io_daq irq used\n"); - - for (amcc = amcc_devices; amcc; amcc = next) { - next = amcc->next; - printk - ("%2d %2d %2d 0x%4x 0x%4x 0x%8llx 0x%8llx %2u %2d\n", - amcc->pci_bus, amcc->pci_slot, amcc->pci_func, - amcc->vendor, amcc->device, - (unsigned long long)amcc->io_addr[0], - (unsigned long long)amcc->io_addr[2], amcc->irq, - amcc->used); - - } -} - /****************************************************************************/ /* return all card information for driver */ int i_pci_card_data(struct pcilst_struct *amcc, diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 652b5abe3d4..0413a143991 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -104,7 +104,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->private = devpriv; if (!pci_list_builded) { - v_pci_card_list_init(this_board->i_VendorId, 1); /* 1 for displaying the list.. */ + v_pci_card_list_init(this_board->i_VendorId); pci_list_builded = 1; } -- cgit v1.2.3 From 48d1db9311827b4639d34220da7736a04dcf02c9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:55:00 -0700 Subject: staging: comedi: addi-data: remove the board attach noise Remove all the kernel messages from i_ADDI_Attach(). These are just additional boot noise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 33 ++-------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 0413a143991..48a90013973 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -125,7 +125,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) if ((i_pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0], &irq)) < 0) { i_pci_card_free(card); - printk(" - Can't get AMCC data!\n"); return -EIO; } @@ -133,7 +132,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) iobase_main = io_addr[1]; iobase_addon = io_addr[2]; iobase_reserved = io_addr[3]; - printk("\nBus %d: Slot %d: Funct%d\nBase0: 0x%8llx\nBase1: 0x%8llx\nBase2: 0x%8llx\nBase3: 0x%8llx\n", pci_bus, pci_slot, pci_func, (unsigned long long)io_addr[0], (unsigned long long)io_addr[1], (unsigned long long)io_addr[2], (unsigned long long)io_addr[3]); if ((this_board->pc_EepromChip == NULL) || (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { @@ -159,10 +157,8 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->amcc = card; devpriv->iobase = (int) io_addr[2]; devpriv->i_IobaseReserved = (int) io_addr[3]; - printk("\nioremap begin"); devpriv->dw_AiBase = ioremap(io_addr[3], this_board->i_IorangeBase3); - printk("\nioremap end"); } /* Initialize parameters that can be overridden in EEPROM */ @@ -185,24 +181,15 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) if (irq > 0) { if (request_irq(irq, v_ADDI_Interrupt, IRQF_SHARED, this_board->pc_DriverName, dev) < 0) { - printk(", unable to allocate IRQ %u, DISABLING IT", - irq); irq = 0; /* Can't use IRQ */ - } else { - printk("\nirq=%u", irq); } - } else { - printk(", IRQ disabled"); } - printk("\nOption %d %d %d\n", it->options[0], it->options[1], - it->options[2]); dev->irq = irq; /* Read eepeom and fill addi_board Structure */ if (this_board->i_PCIEeprom) { - printk("\nPCI Eeprom used"); if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { /* Set 3 wait stait */ if (!(strcmp(this_board->pc_DriverName, "apci035"))) { @@ -213,12 +200,8 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Enable the interrupt for the controller */ dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - printk("\nEnable the interrupt for the controller"); } - printk("\nRead Eeprom"); addi_eeprom_read_info(dev, io_addr[0]); - } else { - printk("\nPCI Eeprom unused"); } if (it->options[2] > 0) { @@ -228,7 +211,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) } if (devpriv->s_EeParameters.i_Dma) { - printk("\nDMA used"); if (devpriv->us_UseDma == ADDI_ENABLE) { /* alloc DMA buffers */ devpriv->b_DmaDoubleBuffer = 0; @@ -252,21 +234,11 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) ul_DmaBufferVirtual[i]); } } - if (!devpriv->ul_DmaBufferVirtual[0]) { - printk - (", Can't allocate DMA buffer, DMA disabled!"); + if (!devpriv->ul_DmaBufferVirtual[0]) devpriv->us_UseDma = ADDI_DISABLE; - } - if (devpriv->ul_DmaBufferVirtual[1]) { + if (devpriv->ul_DmaBufferVirtual[1]) devpriv->b_DmaDoubleBuffer = 1; - } - } - - if ((devpriv->us_UseDma == ADDI_ENABLE)) { - printk("\nDMA ENABLED\n"); - } else { - printk("\nDMA DISABLED\n"); } } @@ -424,7 +396,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) } } - printk("\ni_ADDI_Attach end\n"); i_ADDI_Reset(dev); devpriv->b_ValidDriver = 1; return 0; -- cgit v1.2.3 From 7954006f0d5feb391efe3cc1b836b57fa9908ecf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:55:21 -0700 Subject: staging: comedi: addi-data: remove unused parameters from i_pci_card_data() The pci_bus, pci_slot, and pci_func data returned by i_pci_card_data() are not used. Remove them from the parameters to the function and also remove the local variables in i_ADDI_Attach() that held the returned data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h | 9 ++------- drivers/staging/comedi/drivers/addi-data/addi_common.c | 4 +--- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h index c836b3bd74d..b09b8e558b7 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h @@ -231,8 +231,7 @@ struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, int pci_card_alloc(struct pcilst_struct *amcc, int master); int i_pci_card_free(struct pcilst_struct *amcc); int i_pci_card_data(struct pcilst_struct *amcc, - unsigned char *pci_bus, unsigned char *pci_slot, - unsigned char *pci_func, resource_size_t * io_addr, + resource_size_t *io_addr, unsigned int *irq); /****************************************************************************/ @@ -383,17 +382,13 @@ int i_pci_card_free(struct pcilst_struct *amcc) /****************************************************************************/ /* return all card information for driver */ int i_pci_card_data(struct pcilst_struct *amcc, - unsigned char *pci_bus, unsigned char *pci_slot, - unsigned char *pci_func, resource_size_t * io_addr, + resource_size_t *io_addr, unsigned int *irq) { int i; if (!amcc) return -1; - *pci_bus = amcc->pci_bus; - *pci_slot = amcc->pci_slot; - *pci_func = amcc->pci_func; for (i = 0; i < 5; i++) io_addr[i] = amcc->io_addr[i]; *irq = amcc->irq; diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 48a90013973..33159eca911 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -95,7 +95,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned int irq; resource_size_t iobase_a, iobase_main, iobase_addon, iobase_reserved; struct pcilst_struct *card = NULL; - unsigned char pci_bus, pci_slot, pci_func; int i_Dma = 0; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); @@ -122,8 +121,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->allocated = 1; - if ((i_pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0], - &irq)) < 0) { + if ((i_pci_card_data(card, &io_addr[0], &irq)) < 0) { i_pci_card_free(card); return -EIO; } -- cgit v1.2.3 From e6fee79e0dcb4dd0c22cde52dfea633b46e6e5df Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:55:37 -0700 Subject: staging: comedi: addi-data: remove irq parameter from i_pci_card_data() The irq parameter passed to i_pci_card_data() is used to get the pci_dev irq that is cached in the card data. This information can easily be found when needed in i_ADDI_Attach() from the 'card' pointer to the card data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_amcc_s5933.h | 7 ++----- drivers/staging/comedi/drivers/addi-data/addi_common.c | 15 ++++++--------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h index b09b8e558b7..0d10ec7288e 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h @@ -231,8 +231,7 @@ struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, int pci_card_alloc(struct pcilst_struct *amcc, int master); int i_pci_card_free(struct pcilst_struct *amcc); int i_pci_card_data(struct pcilst_struct *amcc, - resource_size_t *io_addr, - unsigned int *irq); + resource_size_t *io_addr); /****************************************************************************/ @@ -382,8 +381,7 @@ int i_pci_card_free(struct pcilst_struct *amcc) /****************************************************************************/ /* return all card information for driver */ int i_pci_card_data(struct pcilst_struct *amcc, - resource_size_t *io_addr, - unsigned int *irq) + resource_size_t *io_addr) { int i; @@ -391,7 +389,6 @@ int i_pci_card_data(struct pcilst_struct *amcc, return -1; for (i = 0; i < 5; i++) io_addr[i] = amcc->io_addr[i]; - *irq = amcc->irq; return 0; } diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 33159eca911..8ebfb2b81b5 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -92,7 +92,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) int ret, pages, i, n_subdevices; unsigned int dw_Dummy; resource_size_t io_addr[5]; - unsigned int irq; resource_size_t iobase_a, iobase_main, iobase_addon, iobase_reserved; struct pcilst_struct *card = NULL; int i_Dma = 0; @@ -121,7 +120,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->allocated = 1; - if ((i_pci_card_data(card, &io_addr[0], &irq)) < 0) { + if ((i_pci_card_data(card, &io_addr[0])) < 0) { i_pci_card_free(card); return -EIO; } @@ -176,15 +175,13 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) /* ## */ - if (irq > 0) { - if (request_irq(irq, v_ADDI_Interrupt, IRQF_SHARED, - this_board->pc_DriverName, dev) < 0) { - irq = 0; /* Can't use IRQ */ - } + if (card->irq > 0) { + ret = request_irq(card->irq, v_ADDI_Interrupt, IRQF_SHARED, + this_board->pc_DriverName, dev); + if (ret == 0) + dev->irq = card->irq; } - dev->irq = irq; - /* Read eepeom and fill addi_board Structure */ if (this_board->i_PCIEeprom) { -- cgit v1.2.3 From e864e2c8e87ce2d8196f5fbc30591a6ea386ee5f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:55:54 -0700 Subject: staging: comedi: addi-data: remove io_addr array from card data The io_addr array in the card data holds the PCI bar base addresses returned by pci_resource_start(). Remove this array and just use pci_resource_start() where needed in i_ADDI_Attach(). This also allows getting rid of i_pci_card_data() since it now does nothing. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/addi_amcc_s5933.h | 29 ---------------------- .../staging/comedi/drivers/addi-data/addi_common.c | 26 ++++++++----------- 2 files changed, 10 insertions(+), 45 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h index 0d10ec7288e..27c3fbaea01 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h @@ -201,7 +201,6 @@ struct pcilst_struct { unsigned char pci_bus; unsigned char pci_slot; unsigned char pci_func; - resource_size_t io_addr[5]; unsigned int irq; }; @@ -230,8 +229,6 @@ struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, int pci_card_alloc(struct pcilst_struct *amcc, int master); int i_pci_card_free(struct pcilst_struct *amcc); -int i_pci_card_data(struct pcilst_struct *amcc, - resource_size_t *io_addr); /****************************************************************************/ @@ -240,7 +237,6 @@ void v_pci_card_list_init(unsigned short pci_vendor) { struct pci_dev *pcidev = NULL; struct pcilst_struct *amcc, *last; - int i; int i_Count = 0; amcc_devices = NULL; last = NULL; @@ -265,12 +261,6 @@ void v_pci_card_list_init(unsigned short pci_vendor) amcc->pci_bus = pcidev->bus->number; amcc->pci_slot = PCI_SLOT(pcidev->devfn); amcc->pci_func = PCI_FUNC(pcidev->devfn); - /* Note: resources may be invalid if PCI device - * not enabled, but they are corrected in - * pci_card_alloc. */ - for (i = 0; i < 5; i++) - amcc->io_addr[i] = - pci_resource_start(pcidev, i); amcc->irq = pcidev->irq; } @@ -345,8 +335,6 @@ int i_find_free_pci_card_by_position(unsigned short vendor_id, /* mark card as used */ int pci_card_alloc(struct pcilst_struct *amcc, int master) { - int i; - if (!amcc) return -1; @@ -354,9 +342,6 @@ int pci_card_alloc(struct pcilst_struct *amcc, int master) return 1; if (comedi_pci_enable(amcc->pcidev, "addi_amcc_s5933")) return -1; - /* Resources will be accurate now. */ - for (i = 0; i < 5; i++) - amcc->io_addr[i] = pci_resource_start(amcc->pcidev, i); if (master) pci_set_master(amcc->pcidev); amcc->used = 1; @@ -378,20 +363,6 @@ int i_pci_card_free(struct pcilst_struct *amcc) return 0; } -/****************************************************************************/ -/* return all card information for driver */ -int i_pci_card_data(struct pcilst_struct *amcc, - resource_size_t *io_addr) -{ - int i; - - if (!amcc) - return -1; - for (i = 0; i < 5; i++) - io_addr[i] = amcc->io_addr[i]; - return 0; -} - /****************************************************************************/ /* select and alloc card */ struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 8ebfb2b81b5..b6130f8c40a 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -91,7 +91,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; int ret, pages, i, n_subdevices; unsigned int dw_Dummy; - resource_size_t io_addr[5]; resource_size_t iobase_a, iobase_main, iobase_addon, iobase_reserved; struct pcilst_struct *card = NULL; int i_Dma = 0; @@ -120,15 +119,10 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->allocated = 1; - if ((i_pci_card_data(card, &io_addr[0])) < 0) { - i_pci_card_free(card); - return -EIO; - } - - iobase_a = io_addr[0]; - iobase_main = io_addr[1]; - iobase_addon = io_addr[2]; - iobase_reserved = io_addr[3]; + iobase_a = pci_resource_start(card->pcidev, 0); + iobase_main = pci_resource_start(card->pcidev, 1); + iobase_addon = pci_resource_start(card->pcidev, 2); + iobase_reserved = pci_resource_start(card->pcidev, 3); if ((this_board->pc_EepromChip == NULL) || (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { @@ -150,11 +144,11 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->i_IobaseReserved = (int) iobase_reserved; } else { dev->board_name = this_board->pc_DriverName; - dev->iobase = (unsigned long)io_addr[2]; + dev->iobase = pci_resource_start(card->pcidev, 2); devpriv->amcc = card; - devpriv->iobase = (int) io_addr[2]; - devpriv->i_IobaseReserved = (int) io_addr[3]; - devpriv->dw_AiBase = ioremap(io_addr[3], + devpriv->iobase = pci_resource_start(card->pcidev, 2); + devpriv->i_IobaseReserved = pci_resource_start(card->pcidev, 3); + devpriv->dw_AiBase = ioremap(pci_resource_start(card->pcidev, 3), this_board->i_IorangeBase3); } @@ -196,7 +190,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); } - addi_eeprom_read_info(dev, io_addr[0]); + addi_eeprom_read_info(dev, pci_resource_start(card->pcidev, 0)); } if (it->options[2] > 0) { @@ -242,7 +236,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) i_ADDI_AttachPCI1710(dev); /* save base address */ - devpriv->s_BoardInfos.ui_Address = io_addr[2]; + devpriv->s_BoardInfos.ui_Address = pci_resource_start(card->pcidev, 2); #endif } else { n_subdevices = 7; -- cgit v1.2.3 From ef34724df277f3a43a7b29d03be69f4c84fed5a8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:56:11 -0700 Subject: staging: comedi: addi-data: absorb pci_card_alloc() into i_ADDI_Attach() The function pci_card_alloc() enables the pci device by calling comedi_pci_enable() and then optionally calls pci_set_master() to enable bus mastering for DMA. Absorb this code directly into i_ADDI_Attach() as is more typical for comedi PCI drivers. Also, remove the now unused i_Master parameter from ptr_select_and_alloc_pci_card(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/addi_amcc_s5933.h | 31 ++-------------------- .../staging/comedi/drivers/addi-data/addi_common.c | 8 +++++- 2 files changed, 9 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h index 27c3fbaea01..b3035b5947d 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h @@ -224,10 +224,8 @@ int i_find_free_pci_card_by_position(unsigned short vendor_id, struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, - unsigned short pci_slot, - int i_Master); + unsigned short pci_slot); -int pci_card_alloc(struct pcilst_struct *amcc, int master); int i_pci_card_free(struct pcilst_struct *amcc); /****************************************************************************/ @@ -331,24 +329,6 @@ int i_find_free_pci_card_by_position(unsigned short vendor_id, return 1; } -/****************************************************************************/ -/* mark card as used */ -int pci_card_alloc(struct pcilst_struct *amcc, int master) -{ - if (!amcc) - return -1; - - if (amcc->used) - return 1; - if (comedi_pci_enable(amcc->pcidev, "addi_amcc_s5933")) - return -1; - if (master) - pci_set_master(amcc->pcidev); - amcc->used = 1; - - return 0; -} - /****************************************************************************/ /* mark card as free */ int i_pci_card_free(struct pcilst_struct *amcc) @@ -368,8 +348,7 @@ int i_pci_card_free(struct pcilst_struct *amcc) struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, - unsigned short pci_slot, - int i_Master) + unsigned short pci_slot) { struct pcilst_struct *card; @@ -395,12 +374,6 @@ struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, } } - if (pci_card_alloc(card, i_Master) != 0) { - printk(" - Can't allocate card!\n"); - return NULL; - - } - return card; } #endif diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index b6130f8c40a..6ed851fef07 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -112,11 +112,17 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) card = ptr_select_and_alloc_pci_card(this_board->i_VendorId, this_board->i_DeviceId, it->options[0], - it->options[1], i_Dma); + it->options[1]); if (card == NULL) return -EIO; + ret = comedi_pci_enable(card->pcidev, "addi_amcc_s5933"); + if (ret) + return ret; + if (i_Dma) + pci_set_master(card->pcidev); + card->used = 1; devpriv->allocated = 1; iobase_a = pci_resource_start(card->pcidev, 0); -- cgit v1.2.3 From b0d116876cc6e8ce8c2bd21d116f0c238cfe48ba Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:56:27 -0700 Subject: staging: comedi: addi-data: add a 'pcidev' local var to i_ADDI_Attach() Add a local variable for the pci_dev pointer to make the code a bit cleaner. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 26 ++++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 6ed851fef07..249fa903959 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -87,6 +87,7 @@ static int i_ADDI_Reset(struct comedi_device *dev) static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct addi_board *this_board = comedi_board(dev); + struct pci_dev *pcidev; struct addi_private *devpriv; struct comedi_subdevice *s; int ret, pages, i, n_subdevices; @@ -116,19 +117,20 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) if (card == NULL) return -EIO; + pcidev = card->pcidev; - ret = comedi_pci_enable(card->pcidev, "addi_amcc_s5933"); + ret = comedi_pci_enable(pcidev, "addi_amcc_s5933"); if (ret) return ret; if (i_Dma) - pci_set_master(card->pcidev); + pci_set_master(pcidev); card->used = 1; devpriv->allocated = 1; - iobase_a = pci_resource_start(card->pcidev, 0); - iobase_main = pci_resource_start(card->pcidev, 1); - iobase_addon = pci_resource_start(card->pcidev, 2); - iobase_reserved = pci_resource_start(card->pcidev, 3); + iobase_a = pci_resource_start(pcidev, 0); + iobase_main = pci_resource_start(pcidev, 1); + iobase_addon = pci_resource_start(pcidev, 2); + iobase_reserved = pci_resource_start(pcidev, 3); if ((this_board->pc_EepromChip == NULL) || (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { @@ -150,11 +152,11 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) devpriv->i_IobaseReserved = (int) iobase_reserved; } else { dev->board_name = this_board->pc_DriverName; - dev->iobase = pci_resource_start(card->pcidev, 2); + dev->iobase = pci_resource_start(pcidev, 2); devpriv->amcc = card; - devpriv->iobase = pci_resource_start(card->pcidev, 2); - devpriv->i_IobaseReserved = pci_resource_start(card->pcidev, 3); - devpriv->dw_AiBase = ioremap(pci_resource_start(card->pcidev, 3), + devpriv->iobase = pci_resource_start(pcidev, 2); + devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); + devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), this_board->i_IorangeBase3); } @@ -196,7 +198,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); } - addi_eeprom_read_info(dev, pci_resource_start(card->pcidev, 0)); + addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); } if (it->options[2] > 0) { @@ -242,7 +244,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) i_ADDI_AttachPCI1710(dev); /* save base address */ - devpriv->s_BoardInfos.ui_Address = pci_resource_start(card->pcidev, 2); + devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2); #endif } else { n_subdevices = 7; -- cgit v1.2.3 From ade6c03da5918ce25889d4a1d87453af5fbb8b9a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:56:42 -0700 Subject: staging: comedi: addi-data: remove 'irq' from the card data This information can be found when needed in i_ADDI_Attach() by using the pci_dev pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h | 3 --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h index b3035b5947d..08b32406e04 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h @@ -201,7 +201,6 @@ struct pcilst_struct { unsigned char pci_bus; unsigned char pci_slot; unsigned char pci_func; - unsigned int irq; }; /* ptr to root list of all amcc devices */ @@ -259,8 +258,6 @@ void v_pci_card_list_init(unsigned short pci_vendor) amcc->pci_bus = pcidev->bus->number; amcc->pci_slot = PCI_SLOT(pcidev->devfn); amcc->pci_func = PCI_FUNC(pcidev->devfn); - amcc->irq = pcidev->irq; - } } } diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 249fa903959..ae85f64406b 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -177,11 +177,11 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) /* ## */ - if (card->irq > 0) { - ret = request_irq(card->irq, v_ADDI_Interrupt, IRQF_SHARED, + if (pcidev->irq > 0) { + ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, this_board->pc_DriverName, dev); if (ret == 0) - dev->irq = card->irq; + dev->irq = pcidev->irq; } /* Read eepeom and fill addi_board Structure */ -- cgit v1.2.3 From f7a9fd153b0b3268ece704c68419ee060780bc0d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:57:07 -0700 Subject: staging: comedi: addi-data: remove attach option to disable dma This pci driver currently uses the comedi legacy attach mechanism which allows the user to pass configuration options to the driver when it is attached to the comedi subsystem. The use of these configuration options is preventing the conversion of the addi-data drivers to the comedi auto attach mechanism. For the addi-data drivers, option[2] is used to enable/disable dma. The default (0) action is to enable dma is the driver supports it. Remove this configuration option and just enable dma if it is supported. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index ae85f64406b..2dab403ac26 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -40,9 +40,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour | option[0] - PCI bus number - if bus number and slot number are 0, | | then driver search for first unused card | | option[1] - PCI slot number | - | | - | option[2] = 0 - DMA ENABLE | - | = 1 - DMA DISABLE | +----------+-----------+------------------------------------------------+ */ @@ -94,7 +91,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned int dw_Dummy; resource_size_t iobase_a, iobase_main, iobase_addon, iobase_reserved; struct pcilst_struct *card = NULL; - int i_Dma = 0; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) @@ -106,10 +102,6 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) pci_list_builded = 1; } - if ((this_board->i_Dma) && (it->options[2] == 0)) { - i_Dma = 1; - } - card = ptr_select_and_alloc_pci_card(this_board->i_VendorId, this_board->i_DeviceId, it->options[0], @@ -122,7 +114,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) ret = comedi_pci_enable(pcidev, "addi_amcc_s5933"); if (ret) return ret; - if (i_Dma) + if (this_board->i_Dma) pci_set_master(pcidev); card->used = 1; devpriv->allocated = 1; -- cgit v1.2.3 From a43163c9bb1ca5f00e67fb7f3dd91ee1e327f00f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:57:22 -0700 Subject: staging: comedi: addi-data: remove i_pci_card_free() This function calls comedi_pci_disable() to disable the pci device when detached. It's only called from i_ADDI_Detach(). Move the code there and delete the function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_amcc_s5933.h | 16 ---------------- drivers/staging/comedi/drivers/addi-data/addi_common.c | 12 ++++++++---- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h index 08b32406e04..2011f4bb304 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h @@ -225,8 +225,6 @@ struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, unsigned short pci_bus, unsigned short pci_slot); -int i_pci_card_free(struct pcilst_struct *amcc); - /****************************************************************************/ /* build list of amcc cards in this system */ @@ -326,20 +324,6 @@ int i_find_free_pci_card_by_position(unsigned short vendor_id, return 1; } -/****************************************************************************/ -/* mark card as free */ -int i_pci_card_free(struct pcilst_struct *amcc) -{ - if (!amcc) - return -1; - - if (!amcc->used) - return 1; - amcc->used = 0; - comedi_pci_disable(amcc->pcidev); - return 0; -} - /****************************************************************************/ /* select and alloc card */ struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 2dab403ac26..f6c36ac93b2 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -402,8 +402,10 @@ static void i_ADDI_Detach(struct comedi_device *dev) free_irq(dev->irq, dev); if ((this_board->pc_EepromChip == NULL) || (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { - if (devpriv->allocated) - i_pci_card_free(devpriv->amcc); + if (devpriv->allocated) { + comedi_pci_disable(devpriv->amcc->pcidev); + devpriv->amcc->used = 0; + } if (devpriv->ul_DmaBufferVirtual[0]) { free_pages((unsigned long)devpriv-> ul_DmaBufferVirtual[0], @@ -416,8 +418,10 @@ static void i_ADDI_Detach(struct comedi_device *dev) } } else { iounmap(devpriv->dw_AiBase); - if (devpriv->allocated) - i_pci_card_free(devpriv->amcc); + if (devpriv->allocated) { + comedi_pci_disable(devpriv->amcc->pcidev); + devpriv->amcc->used = 0; + } } if (pci_list_builded) { v_pci_card_list_cleanup(this_board->i_VendorId); -- cgit v1.2.3 From 41be28db534330192bbbec9783e6d43d4432a7fb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:57:37 -0700 Subject: staging: comedi: addi-data: use attach_pci callback Use the comedi pci auto config mechanism to attach the addi-data drivers. This allows removing all the PCI bus walking code. Add a function, addi_find_boardinfo(), to find the driver specific boardinfo. Since this function is currently in the common code we have to use the pointer to the boardinfo that is stored in the comedi_driver pointer. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/addi_amcc_s5933.h | 167 --------------------- .../staging/comedi/drivers/addi-data/addi_common.c | 85 +++++------ .../staging/comedi/drivers/addi-data/addi_common.h | 3 - drivers/staging/comedi/drivers/addi_apci_035.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1500.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1516.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1564.c | 2 +- drivers/staging/comedi/drivers/addi_apci_16xx.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1710.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2016.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3001.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3300.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3501.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 2 +- 19 files changed, 52 insertions(+), 235 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h index 2011f4bb304..bef74792352 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h @@ -190,171 +190,4 @@ #define TARGET_ABORT_INT 0x00200000L #define BUS_MASTER_INT 0x00200000L -/****************************************************************************/ - -struct pcilst_struct { - struct pcilst_struct *next; - int used; - struct pci_dev *pcidev; - unsigned short vendor; - unsigned short device; - unsigned char pci_bus; - unsigned char pci_slot; - unsigned char pci_func; -}; - -/* ptr to root list of all amcc devices */ -static struct pcilst_struct *amcc_devices; - -static const int i_ADDIDATADeviceID[] = { 0x15B8, 0x10E8 }; - -/****************************************************************************/ - -void v_pci_card_list_init(unsigned short pci_vendor); -void v_pci_card_list_cleanup(unsigned short pci_vendor); -struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id, - unsigned short - device_id); -int i_find_free_pci_card_by_position(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot, - struct pcilst_struct **card); -struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot); - -/****************************************************************************/ - -/* build list of amcc cards in this system */ -void v_pci_card_list_init(unsigned short pci_vendor) -{ - struct pci_dev *pcidev = NULL; - struct pcilst_struct *amcc, *last; - int i_Count = 0; - amcc_devices = NULL; - last = NULL; - - for_each_pci_dev(pcidev) { - for (i_Count = 0; i_Count < 2; i_Count++) { - pci_vendor = i_ADDIDATADeviceID[i_Count]; - if (pcidev->vendor == pci_vendor) { - amcc = kzalloc(sizeof(*amcc), GFP_KERNEL); - if (amcc == NULL) - continue; - - amcc->pcidev = pcidev; - if (last) - last->next = amcc; - else - amcc_devices = amcc; - last = amcc; - - amcc->vendor = pcidev->vendor; - amcc->device = pcidev->device; - amcc->pci_bus = pcidev->bus->number; - amcc->pci_slot = PCI_SLOT(pcidev->devfn); - amcc->pci_func = PCI_FUNC(pcidev->devfn); - } - } - } -} - -/****************************************************************************/ -/* free up list of amcc cards in this system */ -void v_pci_card_list_cleanup(unsigned short pci_vendor) -{ - struct pcilst_struct *amcc, *next; - - for (amcc = amcc_devices; amcc; amcc = next) { - next = amcc->next; - kfree(amcc); - } - - amcc_devices = NULL; -} - -/****************************************************************************/ -/* find first unused card with this device_id */ -struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id, - unsigned short device_id) -{ - struct pcilst_struct *amcc, *next; - - for (amcc = amcc_devices; amcc; amcc = next) { - next = amcc->next; - if ((!amcc->used) && (amcc->device == device_id) - && (amcc->vendor == vendor_id)) - return amcc; - - } - - return NULL; -} - -/****************************************************************************/ -/* find card on requested position */ -int i_find_free_pci_card_by_position(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot, - struct pcilst_struct **card) -{ - struct pcilst_struct *amcc, *next; - - *card = NULL; - for (amcc = amcc_devices; amcc; amcc = next) { - next = amcc->next; - if ((amcc->vendor == vendor_id) && (amcc->device == device_id) - && (amcc->pci_bus == pci_bus) - && (amcc->pci_slot == pci_slot)) { - if (!(amcc->used)) { - *card = amcc; - return 0; /* ok, card is found */ - } else { - printk(" - \nCard on requested position is used b:s %d:%d!\n", - pci_bus, pci_slot); - return 2; /* card exist but is used */ - } - } - } - - /* no card found */ - return 1; -} - -/****************************************************************************/ -/* select and alloc card */ -struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id, - unsigned short device_id, - unsigned short pci_bus, - unsigned short pci_slot) -{ - struct pcilst_struct *card; - - if ((pci_bus < 1) & (pci_slot < 1)) { - /* use autodetection */ - card = ptr_find_free_pci_card_by_device(vendor_id, device_id); - if (card == NULL) { - printk(" - Unused card not found in system!\n"); - return NULL; - } - } else { - switch (i_find_free_pci_card_by_position(vendor_id, device_id, - pci_bus, pci_slot, - &card)) { - case 1: - printk(" - Card not found on requested position b:s %d:%d!\n", - pci_bus, pci_slot); - return NULL; - case 2: - printk(" - Card on requested position is used b:s %d:%d!\n", - pci_bus, pci_slot); - return NULL; - } - } - - return card; -} #endif diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index f6c36ac93b2..5cfd85d429b 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -36,11 +36,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour +-----------------------------------------------------------------------+ | Description : ADDI COMMON Main Module | +-----------------------------------------------------------------------+ - | CONFIG OPTIONS | - | option[0] - PCI bus number - if bus number and slot number are 0, | - | then driver search for first unused card | - | option[1] - PCI slot number | - +----------+-----------+------------------------------------------------+ */ #ifndef COMEDI_SUBD_TTLIO @@ -81,42 +76,49 @@ static int i_ADDI_Reset(struct comedi_device *dev) return 0; } -static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) +static const void *addi_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - const struct addi_board *this_board = comedi_board(dev); - struct pci_dev *pcidev; + const void *p = dev->driver->board_name; + const struct addi_board *this_board; + int i; + + for (i = 0; i < dev->driver->num_names; i++) { + this_board = p; + if (this_board->i_VendorId == pcidev->vendor && + this_board->i_DeviceId == pcidev->device) + return this_board; + p += dev->driver->offset; + } + return NULL; +} + +static int addi_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const struct addi_board *this_board; struct addi_private *devpriv; struct comedi_subdevice *s; int ret, pages, i, n_subdevices; unsigned int dw_Dummy; resource_size_t iobase_a, iobase_main, iobase_addon, iobase_reserved; - struct pcilst_struct *card = NULL; + + this_board = addi_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->pc_DriverName; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; dev->private = devpriv; - if (!pci_list_builded) { - v_pci_card_list_init(this_board->i_VendorId); - pci_list_builded = 1; - } - - card = ptr_select_and_alloc_pci_card(this_board->i_VendorId, - this_board->i_DeviceId, - it->options[0], - it->options[1]); - - if (card == NULL) - return -EIO; - pcidev = card->pcidev; - - ret = comedi_pci_enable(pcidev, "addi_amcc_s5933"); + ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; if (this_board->i_Dma) pci_set_master(pcidev); - card->used = 1; devpriv->allocated = 1; iobase_a = pci_resource_start(pcidev, 0); @@ -136,16 +138,12 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) dev->iobase = (unsigned long)iobase_a; /* DAQ base address... */ } - dev->board_name = this_board->pc_DriverName; - devpriv->amcc = card; devpriv->iobase = (int) dev->iobase; devpriv->i_IobaseAmcc = (int) iobase_a; /* AMCC base address... */ devpriv->i_IobaseAddon = (int) iobase_addon; /* ADD ON base address.... */ devpriv->i_IobaseReserved = (int) iobase_reserved; } else { - dev->board_name = this_board->pc_DriverName; dev->iobase = pci_resource_start(pcidev, 2); - devpriv->amcc = card; devpriv->iobase = pci_resource_start(pcidev, 2); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), @@ -171,7 +169,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, - this_board->pc_DriverName, dev); + dev->board_name, dev); if (ret == 0) dev->irq = pcidev->irq; } @@ -181,7 +179,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) if (this_board->i_PCIEeprom) { if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { /* Set 3 wait stait */ - if (!(strcmp(this_board->pc_DriverName, "apci035"))) { + if (!(strcmp(dev->board_name, "apci035"))) { outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); } else { outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); @@ -193,11 +191,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); } - if (it->options[2] > 0) { - devpriv->us_UseDma = ADDI_DISABLE; - } else { - devpriv->us_UseDma = ADDI_ENABLE; - } + devpriv->us_UseDma = ADDI_ENABLE; if (devpriv->s_EeParameters.i_Dma) { if (devpriv->us_UseDma == ADDI_ENABLE) { @@ -231,7 +225,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) } } - if (!strcmp(this_board->pc_DriverName, "apci1710")) { + if (!strcmp(dev->board_name, "apci1710")) { #ifdef CONFIG_APCI_1710 i_ADDI_AttachPCI1710(dev); @@ -393,6 +387,7 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) static void i_ADDI_Detach(struct comedi_device *dev) { const struct addi_board *this_board = comedi_board(dev); + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct addi_private *devpriv = dev->private; if (devpriv) { @@ -402,10 +397,8 @@ static void i_ADDI_Detach(struct comedi_device *dev) free_irq(dev->irq, dev); if ((this_board->pc_EepromChip == NULL) || (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { - if (devpriv->allocated) { - comedi_pci_disable(devpriv->amcc->pcidev); - devpriv->amcc->used = 0; - } + if (devpriv->allocated) + comedi_pci_disable(pcidev); if (devpriv->ul_DmaBufferVirtual[0]) { free_pages((unsigned long)devpriv-> ul_DmaBufferVirtual[0], @@ -418,14 +411,8 @@ static void i_ADDI_Detach(struct comedi_device *dev) } } else { iounmap(devpriv->dw_AiBase); - if (devpriv->allocated) { - comedi_pci_disable(devpriv->amcc->pcidev); - devpriv->amcc->used = 0; - } - } - if (pci_list_builded) { - v_pci_card_list_cleanup(this_board->i_VendorId); - pci_list_builded = 0; + if (devpriv->allocated) + comedi_pci_disable(pcidev); } } } diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index 6b71dbbfb22..c72e79d2c27 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -312,7 +312,6 @@ struct addi_private { int i_IobaseAddon; /* addon base address */ int i_IobaseReserved; void __iomem *dw_AiBase; - struct pcilst_struct *amcc; /* ptr too AMCC data */ unsigned char allocated; /* we have blocked card */ unsigned char b_ValidDriver; /* driver is ok */ unsigned char b_AiContinuous; /* we do unlimited AI */ @@ -410,5 +409,3 @@ struct addi_private { /* Minimum Delay in Nano secs */ } s_EeParameters; }; - -static unsigned short pci_list_builded; /* set to 1 when list of card is known */ diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 812092f7fba..5403ae838f7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -40,7 +40,7 @@ static const struct addi_board apci035_boardtypes[] = { static struct comedi_driver apci035_driver = { .driver_name = "addi_apci_035", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci035_boardtypes), .board_name = &apci035_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index f787604c311..2b63d0c3894 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -29,7 +29,7 @@ static const struct addi_board apci1032_boardtypes[] = { static struct comedi_driver apci1032_driver = { .driver_name = "addi_apci_1032", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci1032_boardtypes), .board_name = &apci1032_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 51f9e85459c..804ce736c48 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -40,7 +40,7 @@ static const struct addi_board apci1500_boardtypes[] = { static struct comedi_driver apci1500_driver = { .driver_name = "addi_apci_1500", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci1500_boardtypes), .board_name = &apci1500_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index ba7ffad4534..480c285a874 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -36,7 +36,7 @@ static const struct addi_board apci1516_boardtypes[] = { static struct comedi_driver apci1516_driver = { .driver_name = "addi_apci_1516", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci1516_boardtypes), .board_name = &apci1516_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index c44007b0c91..10a7dbcbf99 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -39,7 +39,7 @@ static const struct addi_board apci1564_boardtypes[] = { static struct comedi_driver apci1564_driver = { .driver_name = "addi_apci_1564", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci1564_boardtypes), .board_name = &apci1564_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 18182a14d21..b00e1a47cff 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -39,7 +39,7 @@ static const struct addi_board apci16xx_boardtypes[] = { static struct comedi_driver apci16xx_driver = { .driver_name = "addi_apci_16xx", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci16xx_boardtypes), .board_name = &apci16xx_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index ff0131710cc..8fae5b2f4f7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -39,7 +39,7 @@ static const struct addi_board apci1710_boardtypes[] = { static struct comedi_driver apci1710_driver = { .driver_name = "addi_apci_1710", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci1710_boardtypes), .board_name = &apci1710_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c index 26426085f97..e0420860a4d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ b/drivers/staging/comedi/drivers/addi_apci_2016.c @@ -33,7 +33,7 @@ static const struct addi_board apci2016_boardtypes[] = { static struct comedi_driver apci2016_driver = { .driver_name = "addi_apci_2016", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci2016_boardtypes), .board_name = &apci2016_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 32214198a90..fd415248fb2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -35,7 +35,7 @@ static const struct addi_board apci2032_boardtypes[] = { static struct comedi_driver apci2032_driver = { .driver_name = "addi_apci_2032", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci2032_boardtypes), .board_name = &apci2032_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 6c8a2223520..3d4c9a9a840 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -35,7 +35,7 @@ static const struct addi_board apci2200_boardtypes[] = { static struct comedi_driver apci2200_driver = { .driver_name = "addi_apci_2200", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci2200_boardtypes), .board_name = &apci2200_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c index bfeac4451fb..c875f8cdafd 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3001.c +++ b/drivers/staging/comedi/drivers/addi_apci_3001.c @@ -51,7 +51,7 @@ static const struct addi_board apci3001_boardtypes[] = { static struct comedi_driver apci3001_driver = { .driver_name = "addi_apci_3001", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci3001_boardtypes), .board_name = &apci3001_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 1df67cea347..e027f4709ca 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -57,7 +57,7 @@ static const struct addi_board apci3120_boardtypes[] = { static struct comedi_driver apci3120_driver = { .driver_name = "addi_apci_3120", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci3120_boardtypes), .board_name = &apci3120_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index cc3e8142635..28def40b830 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -65,7 +65,7 @@ MODULE_DEVICE_TABLE(pci, apci3200_pci_table); static struct comedi_driver apci3200_driver = { .driver_name = "addi_apci_3200", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci3200_boardtypes), .board_name = &apci3200_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c index 172b5ceed83..c57cacf0b32 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3300.c +++ b/drivers/staging/comedi/drivers/addi_apci_3300.c @@ -58,7 +58,7 @@ static const struct addi_board apci3300_boardtypes[] = { static struct comedi_driver apci3300_driver = { .driver_name = "addi_apci_3300", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci3300_boardtypes), .board_name = &apci3300_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 6543ba86820..35948161760 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -46,7 +46,7 @@ MODULE_DEVICE_TABLE(pci, apci3501_pci_table); static struct comedi_driver apci3501_driver = { .driver_name = "addi_apci_3501", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci3501_boardtypes), .board_name = &apci3501_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index 86e17809b02..22b13987ea3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -780,7 +780,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { static struct comedi_driver apci3xxx_driver = { .driver_name = "addi_apci_3xxx", .module = THIS_MODULE, - .attach = i_ADDI_Attach, + .attach_pci = addi_attach_pci, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci3xxx_boardtypes), .board_name = &apci3xxx_boardtypes[0].pc_DriverName, -- cgit v1.2.3 From 0fcdafb83b9b4e5c48410b3ca91b1f237ad60dbc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:57:52 -0700 Subject: staging: comedi: addi-data: cleanup reading of the PCI bars Read the PCI bars directly into the private data variables and remove all the local variables used for them in addi_attach_pci(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 32 +++++++--------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 5cfd85d429b..a9295f2d2a5 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -101,7 +101,6 @@ static int addi_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int ret, pages, i, n_subdevices; unsigned int dw_Dummy; - resource_size_t iobase_a, iobase_main, iobase_addon, iobase_reserved; this_board = addi_find_boardinfo(dev, pcidev); if (!this_board) @@ -121,34 +120,23 @@ static int addi_attach_pci(struct comedi_device *dev, pci_set_master(pcidev); devpriv->allocated = 1; - iobase_a = pci_resource_start(pcidev, 0); - iobase_main = pci_resource_start(pcidev, 1); - iobase_addon = pci_resource_start(pcidev, 2); - iobase_reserved = pci_resource_start(pcidev, 3); + if (!this_board->pc_EepromChip || + !strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { + if (this_board->i_IorangeBase1) + dev->iobase = pci_resource_start(pcidev, 1); + else + dev->iobase = pci_resource_start(pcidev, 0); - if ((this_board->pc_EepromChip == NULL) - || (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { - /************************************/ - /* Test if more that 1 address used */ - /************************************/ - - if (this_board->i_IorangeBase1 != 0) { - dev->iobase = (unsigned long)iobase_main; /* DAQ base address... */ - } else { - dev->iobase = (unsigned long)iobase_a; /* DAQ base address... */ - } - - devpriv->iobase = (int) dev->iobase; - devpriv->i_IobaseAmcc = (int) iobase_a; /* AMCC base address... */ - devpriv->i_IobaseAddon = (int) iobase_addon; /* ADD ON base address.... */ - devpriv->i_IobaseReserved = (int) iobase_reserved; + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); } else { dev->iobase = pci_resource_start(pcidev, 2); devpriv->iobase = pci_resource_start(pcidev, 2); - devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), this_board->i_IorangeBase3); } + devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); /* Initialize parameters that can be overridden in EEPROM */ devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; -- cgit v1.2.3 From 342481929705695b0cae6c75ed7180ef5143feff Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:58:09 -0700 Subject: staging: comedi: addi-data: remove 'allocated' from the private data This variable is only used as a flag to indicate that the pci device has been enabled. Use the comedi_device 'iobase' variable to indicate this instead. This is how it's normally handled in the comedi pci drivers. Make the call to comedi_pci_disabled() in i_ADDI_Detach() common and move it to the end of the function. Both the if and else case require it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 9 ++++----- drivers/staging/comedi/drivers/addi-data/addi_common.h | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index a9295f2d2a5..02d1015f3b9 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -118,7 +118,6 @@ static int addi_attach_pci(struct comedi_device *dev, return ret; if (this_board->i_Dma) pci_set_master(pcidev); - devpriv->allocated = 1; if (!this_board->pc_EepromChip || !strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { @@ -385,8 +384,6 @@ static void i_ADDI_Detach(struct comedi_device *dev) free_irq(dev->irq, dev); if ((this_board->pc_EepromChip == NULL) || (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { - if (devpriv->allocated) - comedi_pci_disable(pcidev); if (devpriv->ul_DmaBufferVirtual[0]) { free_pages((unsigned long)devpriv-> ul_DmaBufferVirtual[0], @@ -399,8 +396,10 @@ static void i_ADDI_Detach(struct comedi_device *dev) } } else { iounmap(devpriv->dw_AiBase); - if (devpriv->allocated) - comedi_pci_disable(pcidev); } } + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } } diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index c72e79d2c27..2773359e54e 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -312,7 +312,6 @@ struct addi_private { int i_IobaseAddon; /* addon base address */ int i_IobaseReserved; void __iomem *dw_AiBase; - unsigned char allocated; /* we have blocked card */ unsigned char b_ValidDriver; /* driver is ok */ unsigned char b_AiContinuous; /* we do unlimited AI */ unsigned char b_AiInitialisation; -- cgit v1.2.3 From ae0e3b8b159499658dabe54753b5d306045928db Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:58:25 -0700 Subject: staging: comedi: addi-data: remove 'b_ValidDriver' from the private data This variable is only used in the detach of the addi-data boards to indicate that the attach of the board was successful and that the reset function can be called. We can use the dev->iobase variable to indicate this instead. Once this variable is set the attach always completes. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 3 +-- drivers/staging/comedi/drivers/addi-data/addi_common.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 02d1015f3b9..b533c23ca24 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -367,7 +367,6 @@ static int addi_attach_pci(struct comedi_device *dev, } i_ADDI_Reset(dev); - devpriv->b_ValidDriver = 1; return 0; } @@ -378,7 +377,7 @@ static void i_ADDI_Detach(struct comedi_device *dev) struct addi_private *devpriv = dev->private; if (devpriv) { - if (devpriv->b_ValidDriver) + if (dev->iobase) i_ADDI_Reset(dev); if (dev->irq) free_irq(dev->irq, dev); diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index 2773359e54e..97760cc73f1 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -312,7 +312,6 @@ struct addi_private { int i_IobaseAddon; /* addon base address */ int i_IobaseReserved; void __iomem *dw_AiBase; - unsigned char b_ValidDriver; /* driver is ok */ unsigned char b_AiContinuous; /* we do unlimited AI */ unsigned char b_AiInitialisation; unsigned int ui_AiActualScan; /* how many scans we finished */ -- cgit v1.2.3 From bf36f012c7ddaff083bb0ef187feddf4d85507a0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:58:40 -0700 Subject: staging: comedi: addi-data: remove addi_amcc_s5933.h Now that the PCI bus walking has been removed from the addi-data drivers, the only differenced between addi_amcc_s9533.h and the standard comedi amcc_s5933.h is the additional defines for the apci3120 "ADDON RELATED ADDITIONS". Move those defines to hwdrv_apci3120.c. Modify all the addi-data drivers to then include the standard comedi amcc_s5933.h header and delete the duplicate in addi-data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/addi_amcc_s5933.h | 193 --------------------- .../staging/comedi/drivers/addi-data/addi_common.h | 1 - .../comedi/drivers/addi-data/hwdrv_apci3120.c | 31 ++++ drivers/staging/comedi/drivers/addi_apci_035.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1500.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1516.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1564.c | 2 +- drivers/staging/comedi/drivers/addi_apci_16xx.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1710.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2016.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3001.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3300.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3501.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 2 +- 19 files changed, 47 insertions(+), 210 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h deleted file mode 100644 index bef74792352..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - * - * ADDI-DATA GmbH - * Dieselstrasse 3 - * D-77833 Ottersweier - * Tel: +19(0)7223/9493-0 - * Fax: +49(0)7223/9493-92 - * http://www.addi-data.com - * info@addi-data.com - * - * 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. - */ - -/* Header file for AMCC s 5933 */ - -#ifndef _AMCC_S5933_H_ -#define _AMCC_S5933_H_ - -#include "../../comedidev.h" - -/* written on base0 */ -#define FIFO_ADVANCE_ON_BYTE_2 0x20000000 - -/* added for step 6 dma written on base2 */ -#define AMWEN_ENABLE 0x02 - -#define A2P_FIFO_WRITE_ENABLE 0x01 - -/* for transfer count enable bit */ -#define AGCSTS_TC_ENABLE 0x10000000 - -/* - * ADDON RELATED ADDITIONS - */ -/* Constant */ -#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00 -#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200 -#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L -#define APCI3120_AMWEN_ENABLE 0x02 -#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01 -#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L -#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L -#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L -#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0 -#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0 -#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0 - -/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */ -#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C -#define APCI3120_ADD_ON_AGCSTS_HIGH (APCI3120_ADD_ON_AGCSTS_LOW + 2) -#define APCI3120_ADD_ON_MWAR_LOW 0x24 -#define APCI3120_ADD_ON_MWAR_HIGH (APCI3120_ADD_ON_MWAR_LOW + 2) -#define APCI3120_ADD_ON_MWTC_LOW 0x058 -#define APCI3120_ADD_ON_MWTC_HIGH (APCI3120_ADD_ON_MWTC_LOW + 2) - -/* AMCC */ -#define APCI3120_AMCC_OP_MCSR 0x3C -#define APCI3120_AMCC_OP_REG_INTCSR 0x38 - -/* - * AMCC Operation Register Offsets - PCI - */ -#define AMCC_OP_REG_OMB1 0x00 -#define AMCC_OP_REG_OMB2 0x04 -#define AMCC_OP_REG_OMB3 0x08 -#define AMCC_OP_REG_OMB4 0x0c -#define AMCC_OP_REG_IMB1 0x10 -#define AMCC_OP_REG_IMB2 0x14 -#define AMCC_OP_REG_IMB3 0x18 -#define AMCC_OP_REG_IMB4 0x1c -#define AMCC_OP_REG_FIFO 0x20 -#define AMCC_OP_REG_MWAR 0x24 -#define AMCC_OP_REG_MWTC 0x28 -#define AMCC_OP_REG_MRAR 0x2c -#define AMCC_OP_REG_MRTC 0x30 -#define AMCC_OP_REG_MBEF 0x34 -#define AMCC_OP_REG_INTCSR 0x38 -/* int source */ -#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) -/* FIFO ctrl */ -#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) -#define AMCC_OP_REG_MCSR 0x3c -/* Data in byte 2 */ -#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) -/* Command in byte 3 */ -#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) - -#define AMCC_FIFO_DEPTH_DWORD 8 -#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof(u32)) - -/* - * AMCC Operation Registers Size - PCI - */ -#define AMCC_OP_REG_SIZE 64 /* in bytes */ - -/* - * AMCC Operation Register Offsets - Add-on - */ -#define AMCC_OP_REG_AIMB1 0x00 -#define AMCC_OP_REG_AIMB2 0x04 -#define AMCC_OP_REG_AIMB3 0x08 -#define AMCC_OP_REG_AIMB4 0x0c -#define AMCC_OP_REG_AOMB1 0x10 -#define AMCC_OP_REG_AOMB2 0x14 -#define AMCC_OP_REG_AOMB3 0x18 -#define AMCC_OP_REG_AOMB4 0x1c -#define AMCC_OP_REG_AFIFO 0x20 -#define AMCC_OP_REG_AMWAR 0x24 -#define AMCC_OP_REG_APTA 0x28 -#define AMCC_OP_REG_APTD 0x2c -#define AMCC_OP_REG_AMRAR 0x30 -#define AMCC_OP_REG_AMBEF 0x34 -#define AMCC_OP_REG_AINT 0x38 -#define AMCC_OP_REG_AGCSTS 0x3c -#define AMCC_OP_REG_AMWTC 0x58 -#define AMCC_OP_REG_AMRTC 0x5c - -/* - * AMCC - Add-on General Control/Status Register - */ -#define AGCSTS_CONTROL_MASK 0xfffff000 -#define AGCSTS_NV_ACC_MASK 0xe0000000 -#define AGCSTS_RESET_MASK 0x0e000000 -#define AGCSTS_NV_DA_MASK 0x00ff0000 -#define AGCSTS_BIST_MASK 0x0000f000 -#define AGCSTS_STATUS_MASK 0x000000ff -#define AGCSTS_TCZERO_MASK 0x000000c0 -#define AGCSTS_FIFO_ST_MASK 0x0000003f - -#define AGCSTS_RESET_MBFLAGS 0x08000000 -#define AGCSTS_RESET_P2A_FIFO 0x04000000 -#define AGCSTS_RESET_A2P_FIFO 0x02000000 -#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO) - -#define AGCSTS_A2P_TCOUNT 0x00000080 -#define AGCSTS_P2A_TCOUNT 0x00000040 - -#define AGCSTS_FS_P2A_EMPTY 0x00000020 -#define AGCSTS_FS_P2A_HALF 0x00000010 -#define AGCSTS_FS_P2A_FULL 0x00000008 - -#define AGCSTS_FS_A2P_EMPTY 0x00000004 -#define AGCSTS_FS_A2P_HALF 0x00000002 -#define AGCSTS_FS_A2P_FULL 0x00000001 - -/* - * AMCC - Add-on Interrupt Control/Status Register - */ -#define AINT_INT_MASK 0x00ff0000 -#define AINT_SEL_MASK 0x0000ffff -#define AINT_IS_ENSEL_MASK 0x00001f1f - -#define AINT_INT_ASSERTED 0x00800000 -#define AINT_BM_ERROR 0x00200000 -#define AINT_BIST_INT 0x00100000 - -#define AINT_RT_COMPLETE 0x00080000 -#define AINT_WT_COMPLETE 0x00040000 - -#define AINT_OUT_MB_INT 0x00020000 -#define AINT_IN_MB_INT 0x00010000 - -#define AINT_READ_COMPL 0x00008000 -#define AINT_WRITE_COMPL 0x00004000 - -#define AINT_OMB_ENABLE 0x00001000 -#define AINT_OMB_SELECT 0x00000c00 -#define AINT_OMB_BYTE 0x00000300 - -#define AINT_IMB_ENABLE 0x00000010 -#define AINT_IMB_SELECT 0x0000000c -#define AINT_IMB_BYTE 0x00000003 - -/* Enable Bus Mastering */ -#define EN_A2P_TRANSFERS 0x00000400 -/* FIFO Flag Reset */ -#define RESET_A2P_FLAGS 0x04000000L -/* FIFO Relative Priority */ -#define A2P_HI_PRIORITY 0x00000100L -/* Identify Interrupt Sources */ -#define ANY_S593X_INT 0x00800000L -#define READ_TC_INT 0x00080000L -#define WRITE_TC_INT 0x00040000L -#define IN_MB_INT 0x00020000L -#define MASTER_ABORT_INT 0x00100000L -#define TARGET_ABORT_INT 0x00200000L -#define BUS_MASTER_INT 0x00200000L - -#endif diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index 97760cc73f1..7419f344025 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -31,7 +31,6 @@ #include #include #include "../../comedidev.h" -#include "addi_amcc_s5933.h" #define ERROR -1 #define SUCCESS 1 diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index a60d8dc6441..47ec2083c58 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -44,6 +44,37 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ +/* + * ADDON RELATED ADDITIONS + */ +/* Constant */ +#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00 +#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200 +#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L +#define APCI3120_AMWEN_ENABLE 0x02 +#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01 +#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L +#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L +#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L +#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0 +#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0 +#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0 + +/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */ +#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C +#define APCI3120_ADD_ON_AGCSTS_HIGH (APCI3120_ADD_ON_AGCSTS_LOW + 2) +#define APCI3120_ADD_ON_MWAR_LOW 0x24 +#define APCI3120_ADD_ON_MWAR_HIGH (APCI3120_ADD_ON_MWAR_LOW + 2) +#define APCI3120_ADD_ON_MWTC_LOW 0x058 +#define APCI3120_ADD_ON_MWTC_HIGH (APCI3120_ADD_ON_MWTC_LOW + 2) + +/* AMCC */ +#define APCI3120_AMCC_OP_MCSR 0x3C +#define APCI3120_AMCC_OP_REG_INTCSR 0x38 + +/* for transfer count enable bit */ +#define AGCSTS_TC_ENABLE 0x10000000 + /* used for test on mixture of BIP/UNI ranges */ #define APCI3120_BIPOLAR_RANGES 4 diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 5403ae838f7..43b83cf4810 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #define ADDIDATA_WATCHDOG 2 /* Or shold it be something else */ diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 2b63d0c3894..1db3e15ed4b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1032.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 804ce736c48..4fe98e5ce75 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1500.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 480c285a874..59c0c65ac18 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1516.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 10a7dbcbf99..1dcaadade21 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1564.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index b00e1a47cff..14283aad0e4 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci16xx.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 8fae5b2f4f7..6337aceaf24 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -2,9 +2,9 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" static void fpu_begin(void) { diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c index e0420860a4d..7c71981de7d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ b/drivers/staging/comedi/drivers/addi_apci_2016.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci2016.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index fd415248fb2..92650480cd3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci2032.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 3d4c9a9a840..becb2b4d11c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci2200.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c index c875f8cdafd..90506a3d1dc 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3001.c +++ b/drivers/staging/comedi/drivers/addi_apci_3001.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3120.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index e027f4709ca..5db6bfc0e22 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #define CONFIG_APCI_3120 1 diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 28def40b830..926fd79c11b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -2,9 +2,9 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" static void fpu_begin(void) { diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c index c57cacf0b32..e57ef667c8b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3300.c +++ b/drivers/staging/comedi/drivers/addi_apci_3300.c @@ -2,9 +2,9 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" static void fpu_begin(void) { diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 35948161760..14ee4e0c5a9 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3501.c" diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index 22b13987ea3..00c972e140f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -1,8 +1,8 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/addi_amcc_s5933.h" #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3xxx.c" -- cgit v1.2.3 From 91952b78069b5029b3c7d705f7b51b107b9792e8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:58:56 -0700 Subject: staging: comedi: addi-data: remove duplicate #include's All these #include's have already been handled. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index 7419f344025..2451a942a9a 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -15,22 +15,8 @@ * any later version. */ -#include -#include #include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include "../../comedidev.h" #define ERROR -1 #define SUCCESS 1 -- cgit v1.2.3 From e53b9d6d8b4cad51dd9e52c1d7ed549faab1d091 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:59:15 -0700 Subject: staging: comedi: addi-data: remove duplicate ADDIDATA_{ENABLE,DISABLE} defines These are defined in addi_common.h, the hwdrv_* files do not need to redefined them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c | 4 ---- drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c | 4 ---- drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c | 5 ----- drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c | 5 ----- drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c | 5 ----- drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c | 5 ----- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c | 5 ----- 7 files changed, 33 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c index 799bc0417ba..3d66e48e0cf 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c @@ -96,10 +96,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define ADDIDATA_UNIPOLAR 1 #define ADDIDATA_BIPOLAR 2 -/* ADDIDATA Enable Disable */ -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - /* ANALOG INPUT RANGE */ static struct comedi_lrange range_apci035_ai = { 8, { diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index 7b19b09a572..30a44aea0c2 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -67,10 +67,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE 0x4 #define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE 0xfffffffb -/* ADDIDATA Enable Disable */ -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - static unsigned int ui_InterruptStatus; /* diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index ef5e778748b..0f734d5be4c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -83,11 +83,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2 #define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xfffffffd -/* ADDIDATA Enable Disable */ - -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - /* TIMER COUNTER WATCHDOG DEFINES */ #define ADDIDATA_TIMER 0 diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c index b71b7bb944b..5958a9cb2a3 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c @@ -51,11 +51,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ #endif -#ifndef ADDIDATA_ENABLE -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 -#endif - #define APCI16XX_TTL_INIT 0 #define APCI16XX_TTL_INITDIRECTION 1 #define APCI16XX_TTL_OUTPUTMEMORY 2 diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c index 5342832b809..b7192875b00 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c @@ -55,11 +55,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define APCI2016_DIGITAL_OP 0x04 #define APCI2016_DIGITAL_OP_RW 4 -/* ADDIDATA Enable Disable */ - -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - /* TIMER COUNTER WATCHDOG DEFINES */ #define ADDIDATA_WATCHDOG 2 diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c index 557df247b7f..ebe6d1d4fe6 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c @@ -67,11 +67,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define APCI2032_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2 #define APCI2032_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xfffffffd -/* ADDIDATA Enable Disable */ - -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 - /* TIMER COUNTER WATCHDOG DEFINES */ #define ADDIDATA_WATCHDOG 2 diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c index 23984bfcce3..d1b0ee6b628 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c @@ -48,11 +48,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ #endif -#ifndef ADDIDATA_ENABLE -#define ADDIDATA_ENABLE 1 -#define ADDIDATA_DISABLE 0 -#endif - #define APCI3XXX_SINGLE 0 #define APCI3XXX_DIFF 1 #define APCI3XXX_CONFIGURATION 0 -- cgit v1.2.3 From f2f8486e7a215705c18eb07ce6cecb7b32a29eba Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 31 Oct 2012 16:59:30 -0700 Subject: staging: comedi: addi-data: remove ERROR and SUCCESS defines These are not used. Remove them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h index 2451a942a9a..6d8b29f945d 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.h +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h @@ -18,9 +18,6 @@ #include #include -#define ERROR -1 -#define SUCCESS 1 - #define LOBYTE(W) (unsigned char)((W) & 0xFF) #define HIBYTE(W) (unsigned char)(((W) >> 8) & 0xFF) #define MAKEWORD(H, L) (unsigned short)((L) | ((H) << 8)) -- cgit v1.2.3 From 8db0bc7fc2ab49e51adc419c848b4d3f8121dae8 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 1 Nov 2012 13:47:45 +0800 Subject: Staging: silicom: remove unused including Remove including that don't need it. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bp_mod.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/silicom/bp_mod.c b/drivers/staging/silicom/bp_mod.c index 018b4ff3c3a..58c5f5cf4ce 100644 --- a/drivers/staging/silicom/bp_mod.c +++ b/drivers/staging/silicom/bp_mod.c @@ -9,7 +9,6 @@ /* */ /* */ /******************************************************************************/ -#include #include /* We're doing kernel work */ #include /* Specifically, a module */ -- cgit v1.2.3 From f489e2d0eeb103a57c55d3a78989ee2c347756b6 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 1 Nov 2012 13:47:19 +0800 Subject: Staging: silicom: bypasslib: remove unused including Remove including that don't need it. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/silicom/bypasslib/bplibk.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/silicom/bypasslib/bplibk.h b/drivers/staging/silicom/bypasslib/bplibk.h index a726d90853e..d8c1d27650b 100644 --- a/drivers/staging/silicom/bypasslib/bplibk.h +++ b/drivers/staging/silicom/bypasslib/bplibk.h @@ -15,7 +15,6 @@ #include "bp_ioctl.h" #include "libbp_sd.h" -#include #define IF_NAME "eth" #define SILICOM_VID 0x1374 -- cgit v1.2.3 From 31d7424be0f3ef613b01ac1c9b9ec59b49e59287 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Thu, 1 Nov 2012 11:37:46 +0900 Subject: staging/comedi: fix the spaces issue at the start of line in drivers/ni_mio_cs.c fixed below checkpatch warnings. - WARNING: please, no spaces at the start of a line Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index b5b43e41f3f..69a42c5dddc 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -175,7 +175,7 @@ struct ni_private { struct pcmcia_device *link; - NI_PRIVATE_COMMON}; +NI_PRIVATE_COMMON}; /* How we access registers */ -- cgit v1.2.3 From d03bf7ad255cc29204b06761e5f8c3adb3173024 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Thu, 1 Nov 2012 11:39:03 +0900 Subject: staging/comedi: fix the initialize statics issue in drivers/ni_mio_cs.c fixed below checkpatch error. - ERROR: do not initialise statics to 0 or NULL Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index 69a42c5dddc..f8446849b2e 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -251,7 +251,7 @@ static void mio_cs_config(struct pcmcia_device *link); static void cs_release(struct pcmcia_device *link); static void cs_detach(struct pcmcia_device *); -static struct pcmcia_device *cur_dev = NULL; +static struct pcmcia_device *cur_dev; static int cs_attach(struct pcmcia_device *link) { -- cgit v1.2.3 From a29f7a9525f9d8bae1614c0295a008029dfd3079 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Thu, 1 Nov 2012 11:39:18 +0900 Subject: staging/comedi: Use dev_ printks in drivers/ni_mio_cs.c fixed below checkpatch warnings. - WARNING: printk() should include KERN_ facility level Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_cs.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c index f8446849b2e..76c6a13ea9d 100644 --- a/drivers/staging/comedi/drivers/ni_mio_cs.c +++ b/drivers/staging/comedi/drivers/ni_mio_cs.c @@ -340,13 +340,15 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) irq = link->irq; - printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ", - dev->minor, dev->driver->driver_name, dev->iobase, irq); + dev->board_ptr = ni_boards + ni_getboardtype(dev, link); #if 0 { int i; + printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ", + dev->minor, dev->driver->driver_name, dev->iobase, irq); + printk(" board fingerprint:"); for (i = 0; i < 32; i += 2) { printk(" %04x %02x", inw(dev->iobase + i), @@ -357,18 +359,17 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (i = 0; i < 10; i++) printk(" 0x%04x", win_in(i)); printk("\n"); + + printk("boardtype.name: %s\n", boardtype.name); } #endif - dev->board_ptr = ni_boards + ni_getboardtype(dev, link); - - printk(" %s", boardtype.name); dev->board_name = boardtype.name; ret = request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS, "ni_mio_cs", dev); if (ret < 0) { - printk(" irq not available\n"); + dev_err(dev->class_dev, "irq not available\n"); return -EINVAL; } dev->irq = irq; @@ -401,7 +402,8 @@ static int ni_getboardtype(struct comedi_device *dev, return i; } - printk("unknown board 0x%04x -- pretend it is a ", link->card_id); + dev_err(dev->class_dev, + "unknown board 0x%04x -- pretend it is a ", link->card_id); return 0; } -- cgit v1.2.3 From 99633048bf82327e5ef752627e27a0f031701000 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 14:02:13 +0000 Subject: staging: comedi: skel: remove thisboard macro This driver's `thisboard` macro relies on a local variable having a specific name. Replace it with a local variable of the same name in the functions that use it. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index e1b78a11196..76c6df45baa 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -125,11 +125,6 @@ static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = { MODULE_DEVICE_TABLE(pci, skel_pci_table); -/* - * Useful for shorthand access to the particular board structure - */ -#define thisboard ((const struct skel_board *)dev->board_ptr) - /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device struct. @@ -205,6 +200,7 @@ static int skel_ns_to_timer(unsigned int *ns, int round); */ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) { + const struct skel_board *thisboard; struct skel_private *devpriv; struct comedi_subdevice *s; int ret; @@ -218,9 +214,9 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) */ /* dev->board_ptr = skel_probe(dev, it); */ + thisboard = comedi_board(dev); /* - * Initialize dev->board_name. Note that we can use the "thisboard" - * macro now, since we just initialized it in the last line. + * Initialize dev->board_name. */ dev->board_name = thisboard->name; @@ -300,6 +296,7 @@ static void skel_detach(struct comedi_device *dev) static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct skel_board *thisboard = comedi_board(dev); int n, i; unsigned int d; unsigned int status; -- cgit v1.2.3 From b0a42b3456d6d05cb3155f4c2cb43d42490595d0 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 14:02:14 +0000 Subject: staging: comedi: skel: replace pr_...() with dev_...() Use the dev_info() etc. instead of pr_info() etc. Remove a couple of them that seemed a bit pointless. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 76c6df45baa..a6bd960629f 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -205,8 +205,6 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; int ret; - pr_info("comedi%d: skel: ", dev->minor); - /* * If you can probe the device to determine what device in a series * it is, this is the place to do it. Otherwise, dev->board_ptr @@ -272,7 +270,7 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } - pr_info("attached\n"); + dev_info(dev->class_dev, "skel: attached\n"); return 0; } @@ -322,9 +320,7 @@ static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, break; } if (i == TIMEOUT) { - /* printk() should be used instead of printk() - * whenever the code can be called from real-time. */ - pr_info("timeout\n"); + dev_warn(dev->class_dev, "ai timeout\n"); return -ETIMEDOUT; } @@ -499,7 +495,6 @@ static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, int i; int chan = CR_CHAN(insn->chanspec); - pr_info("skel_ao_winsn\n"); /* Writing a list of values to an AO channel is probably not * very useful, but that's how the interface is defined. */ for (i = 0; i < insn->n; i++) { -- cgit v1.2.3 From 6bdc31dbabc6d099859a4eb44449c3a8bd406a32 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 14:02:15 +0000 Subject: staging: comedi: skel: remove driver_ prefix Remove the `driver_` prefix from variable and function names. Rename `driver_skel` to `skel_driver`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index a6bd960629f..67285359b91 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -148,7 +148,7 @@ struct skel_private { */ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it); static void skel_detach(struct comedi_device *dev); -static struct comedi_driver driver_skel = { +static struct comedi_driver skel_driver = { .driver_name = "dummy", .module = THIS_MODULE, .attach = skel_attach, @@ -582,45 +582,45 @@ static int skel_dio_insn_config(struct comedi_device *dev, } #ifdef CONFIG_COMEDI_PCI_DRIVERS -static int __devinit driver_skel_pci_probe(struct pci_dev *dev, +static int __devinit skel_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { - return comedi_pci_auto_config(dev, &driver_skel); + return comedi_pci_auto_config(dev, &skel_driver); } -static void __devexit driver_skel_pci_remove(struct pci_dev *dev) +static void __devexit skel_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -static struct pci_driver driver_skel_pci_driver = { +static struct pci_driver skel_pci_driver = { .id_table = skel_pci_table, - .probe = &driver_skel_pci_probe, - .remove = __devexit_p(&driver_skel_pci_remove) + .probe = &skel_pci_probe, + .remove = __devexit_p(&skel_pci_remove) }; -static int __init driver_skel_init_module(void) +static int __init skel_init_module(void) { int retval; - retval = comedi_driver_register(&driver_skel); + retval = comedi_driver_register(&skel_driver); if (retval < 0) return retval; - driver_skel_pci_driver.name = (char *)driver_skel.driver_name; - return pci_register_driver(&driver_skel_pci_driver); + skel_pci_driver.name = (char *)skel_driver.driver_name; + return pci_register_driver(&skel_pci_driver); } -static void __exit driver_skel_cleanup_module(void) +static void __exit skel_cleanup_module(void) { - pci_unregister_driver(&driver_skel_pci_driver); - comedi_driver_unregister(&driver_skel); + pci_unregister_driver(&skel_pci_driver); + comedi_driver_unregister(&skel_driver); } -module_init(driver_skel_init_module); -module_exit(driver_skel_cleanup_module); +module_init(skel_init_module); +module_exit(skel_cleanup_module); #else -module_comedi_driver(driver_skel); +module_comedi_driver(skel_driver); #endif MODULE_AUTHOR("Comedi http://www.comedi.org"); -- cgit v1.2.3 From b61b2b1f588ba8b0a5eef64a78687fe5cc80d337 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 14:02:16 +0000 Subject: staging: comedi: skel: use module_comedi_pci_driver() Use the `module_comedi_pci_driver()` macro to register the module as a comedi PCI driver instead of adding the boiler-plate code in full. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 67285359b91..d628339261c 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -598,27 +598,7 @@ static struct pci_driver skel_pci_driver = { .probe = &skel_pci_probe, .remove = __devexit_p(&skel_pci_remove) }; - -static int __init skel_init_module(void) -{ - int retval; - - retval = comedi_driver_register(&skel_driver); - if (retval < 0) - return retval; - - skel_pci_driver.name = (char *)skel_driver.driver_name; - return pci_register_driver(&skel_pci_driver); -} - -static void __exit skel_cleanup_module(void) -{ - pci_unregister_driver(&skel_pci_driver); - comedi_driver_unregister(&skel_driver); -} - -module_init(skel_init_module); -module_exit(skel_cleanup_module); +module_comedi_pci_driver(skel_driver, skel_pci_driver); #else module_comedi_driver(skel_driver); #endif -- cgit v1.2.3 From d8cba40472d9f2cd6590a1f96f0a1be19ff52645 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 14:02:17 +0000 Subject: staging: comedi: skel: remove most forward declarations Move `skel_attach()`, `skel_detach()` and `skel_driver` down the file so that a bunch of forward declarations can be removed. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 274 ++++++++++++++++------------------ 1 file changed, 129 insertions(+), 145 deletions(-) diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index d628339261c..65b645c9159 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -140,153 +140,8 @@ struct skel_private { unsigned int ao_readback[2]; }; -/* - * The struct comedi_driver structure tells the Comedi core module - * which functions to call to configure/deconfigure (attach/detach) - * the board, and also about the kernel module that contains - * the device code. - */ -static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it); -static void skel_detach(struct comedi_device *dev); -static struct comedi_driver skel_driver = { - .driver_name = "dummy", - .module = THIS_MODULE, - .attach = skel_attach, - .detach = skel_detach, -/* It is not necessary to implement the following members if you are - * writing a driver for a ISA PnP or PCI card */ - /* Most drivers will support multiple types of boards by - * having an array of board structures. These were defined - * in skel_boards[] above. Note that the element 'name' - * was first in the structure -- Comedi uses this fact to - * extract the name of the board without knowing any details - * about the structure except for its length. - * When a device is attached (by comedi_config), the name - * of the device is given to Comedi, and Comedi tries to - * match it by going through the list of board names. If - * there is a match, the address of the pointer is put - * into dev->board_ptr and driver->attach() is called. - * - * Note that these are not necessary if you can determine - * the type of board in software. ISA PnP, PCI, and PCMCIA - * devices are such boards. - */ - .board_name = &skel_boards[0].name, - .offset = sizeof(struct skel_board), - .num_names = ARRAY_SIZE(skel_boards), -}; - -static int skel_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int skel_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int skel_dio_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int skel_dio_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int skel_ai_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd); static int skel_ns_to_timer(unsigned int *ns, int round); -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - const struct skel_board *thisboard; - struct skel_private *devpriv; - struct comedi_subdevice *s; - int ret; - -/* - * If you can probe the device to determine what device in a series - * it is, this is the place to do it. Otherwise, dev->board_ptr - * should already be initialized. - */ - /* dev->board_ptr = skel_probe(dev, it); */ - - thisboard = comedi_board(dev); -/* - * Initialize dev->board_name. - */ - dev->board_name = thisboard->name; - - /* Allocate the private data */ - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); - if (!devpriv) - return -ENOMEM; - dev->private = devpriv; - - ret = comedi_alloc_subdevices(dev, 3); - if (ret) - return ret; - - s = &dev->subdevices[0]; - /* dev->read_subdev=s; */ - /* analog input subdevice */ - s->type = COMEDI_SUBD_AI; - /* we support single-ended (ground) and differential */ - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; - s->n_chan = thisboard->ai_chans; - s->maxdata = (1 << thisboard->ai_bits) - 1; - s->range_table = &range_bipolar10; - s->len_chanlist = 16; /* This is the maximum chanlist length that - the board can handle */ - s->insn_read = skel_ai_rinsn; -/* -* s->subdev_flags |= SDF_CMD_READ; -* s->do_cmd = skel_ai_cmd; -*/ - s->do_cmdtest = skel_ai_cmdtest; - - s = &dev->subdevices[1]; - /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE; - s->n_chan = 1; - s->maxdata = 0xffff; - s->range_table = &range_bipolar5; - s->insn_write = skel_ao_winsn; - s->insn_read = skel_ao_rinsn; - - s = &dev->subdevices[2]; - /* digital i/o subdevice */ - if (thisboard->have_dio) { - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; - s->n_chan = 16; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = skel_dio_insn_bits; - s->insn_config = skel_dio_insn_config; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - dev_info(dev->class_dev, "skel: attached\n"); - - return 0; -} - -/* - * _detach is called to deconfigure a device. It should deallocate - * resources. - * This function is also called when _attach() fails, so it should be - * careful not to release resources that were not necessarily - * allocated by _attach(). dev->private and dev->subdevices are - * deallocated automatically by the core. - */ -static void skel_detach(struct comedi_device *dev) -{ -} - /* * "instructions" read/write data in "one-shot" or "software-triggered" * mode. @@ -581,6 +436,135 @@ static int skel_dio_insn_config(struct comedi_device *dev, return insn->n; } +/* + * Attach is called by the Comedi core to configure the driver + * for a particular board. If you specified a board_name array + * in the driver structure, dev->board_ptr contains that + * address. + */ +static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + const struct skel_board *thisboard; + struct skel_private *devpriv; + struct comedi_subdevice *s; + int ret; + +/* + * If you can probe the device to determine what device in a series + * it is, this is the place to do it. Otherwise, dev->board_ptr + * should already be initialized. + */ + /* dev->board_ptr = skel_probe(dev, it); */ + + thisboard = comedi_board(dev); +/* + * Initialize dev->board_name. + */ + dev->board_name = thisboard->name; + + /* Allocate the private data */ + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + ret = comedi_alloc_subdevices(dev, 3); + if (ret) + return ret; + + s = &dev->subdevices[0]; + /* dev->read_subdev=s; */ + /* analog input subdevice */ + s->type = COMEDI_SUBD_AI; + /* we support single-ended (ground) and differential */ + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; + s->n_chan = thisboard->ai_chans; + s->maxdata = (1 << thisboard->ai_bits) - 1; + s->range_table = &range_bipolar10; + s->len_chanlist = 16; /* This is the maximum chanlist length that + the board can handle */ + s->insn_read = skel_ai_rinsn; +/* +* s->subdev_flags |= SDF_CMD_READ; +* s->do_cmd = skel_ai_cmd; +*/ + s->do_cmdtest = skel_ai_cmdtest; + + s = &dev->subdevices[1]; + /* analog output subdevice */ + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE; + s->n_chan = 1; + s->maxdata = 0xffff; + s->range_table = &range_bipolar5; + s->insn_write = skel_ao_winsn; + s->insn_read = skel_ao_rinsn; + + s = &dev->subdevices[2]; + /* digital i/o subdevice */ + if (thisboard->have_dio) { + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 16; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = skel_dio_insn_bits; + s->insn_config = skel_dio_insn_config; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + dev_info(dev->class_dev, "skel: attached\n"); + + return 0; +} + +/* + * _detach is called to deconfigure a device. It should deallocate + * resources. + * This function is also called when _attach() fails, so it should be + * careful not to release resources that were not necessarily + * allocated by _attach(). dev->private and dev->subdevices are + * deallocated automatically by the core. + */ +static void skel_detach(struct comedi_device *dev) +{ +} + +/* + * The struct comedi_driver structure tells the Comedi core module + * which functions to call to configure/deconfigure (attach/detach) + * the board, and also about the kernel module that contains + * the device code. + */ +static struct comedi_driver skel_driver = { + .driver_name = "dummy", + .module = THIS_MODULE, + .attach = skel_attach, + .detach = skel_detach, +/* It is not necessary to implement the following members if you are + * writing a driver for a ISA PnP or PCI card */ + /* Most drivers will support multiple types of boards by + * having an array of board structures. These were defined + * in skel_boards[] above. Note that the element 'name' + * was first in the structure -- Comedi uses this fact to + * extract the name of the board without knowing any details + * about the structure except for its length. + * When a device is attached (by comedi_config), the name + * of the device is given to Comedi, and Comedi tries to + * match it by going through the list of board names. If + * there is a match, the address of the pointer is put + * into dev->board_ptr and driver->attach() is called. + * + * Note that these are not necessary if you can determine + * the type of board in software. ISA PnP, PCI, and PCMCIA + * devices are such boards. + */ + .board_name = &skel_boards[0].name, + .offset = sizeof(struct skel_board), + .num_names = ARRAY_SIZE(skel_boards), +}; + #ifdef CONFIG_COMEDI_PCI_DRIVERS static int __devinit skel_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) -- cgit v1.2.3 From 753b18d39f346a7bb5c39884a727ebfbf147f72d Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 14:02:18 +0000 Subject: staging: comedi: skel: remove remaining forward declaration Move `skel_ns_to_timer()` up so it's forward declaration can be removed. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 65b645c9159..49110aaa197 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -140,7 +140,22 @@ struct skel_private { unsigned int ao_readback[2]; }; -static int skel_ns_to_timer(unsigned int *ns, int round); +/* This function doesn't require a particular form, this is just + * what happens to be used in some of the drivers. It should + * convert ns nanoseconds to a counter value suitable for programming + * the device. Also, it should adjust ns so that it cooresponds to + * the actual time that the device will use. */ +static int skel_ns_to_timer(unsigned int *ns, int round) +{ + /* trivial timer */ + /* if your timing is done through two cascaded timers, the + * i8253_cascade_ns_to_timer() function in 8253.h can be + * very helpful. There are also i8254_load() and i8254_mm_load() + * which can be used to load values into the ubiquitous 8254 counters + */ + + return *ns; +} /* * "instructions" read/write data in "one-shot" or "software-triggered" @@ -326,23 +341,6 @@ static int skel_ai_cmdtest(struct comedi_device *dev, return 0; } -/* This function doesn't require a particular form, this is just - * what happens to be used in some of the drivers. It should - * convert ns nanoseconds to a counter value suitable for programming - * the device. Also, it should adjust ns so that it cooresponds to - * the actual time that the device will use. */ -static int skel_ns_to_timer(unsigned int *ns, int round) -{ - /* trivial timer */ - /* if your timing is done through two cascaded timers, the - * i8253_cascade_ns_to_timer() function in 8253.h can be - * very helpful. There are also i8254_load() and i8254_mm_load() - * which can be used to load values into the ubiquitous 8254 counters - */ - - return *ns; -} - static int skel_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { -- cgit v1.2.3 From d8d7a823409281501f782982a8f272af5f83f66a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 14:02:19 +0000 Subject: staging: comedi: skel: move skel_pci_table Move `skel_pci_table[]` closer to `skel_pci_table` so it falls within the same `#ifdef`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 49110aaa197..ccc1e9b3d26 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -112,19 +112,6 @@ static const struct skel_board skel_boards[] = { }, }; -/* This is used by modprobe to translate PCI IDs to drivers. Should - * only be used for PCI and ISA-PnP devices */ -/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded - * upstream. */ -#define PCI_VENDOR_ID_SKEL 0xdafe -static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0100) }, - { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0200) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, skel_pci_table); - /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, feel free to suggest moving the variable to the struct comedi_device struct. @@ -564,6 +551,19 @@ static struct comedi_driver skel_driver = { }; #ifdef CONFIG_COMEDI_PCI_DRIVERS + +/* This is used by modprobe to translate PCI IDs to drivers. Should + * only be used for PCI and ISA-PnP devices */ +/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded + * upstream. */ +#define PCI_VENDOR_ID_SKEL 0xdafe +static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0100) }, + { PCI_DEVICE(PCI_VENDOR_ID_SKEL, 0x0200) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, skel_pci_table); + static int __devinit skel_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { -- cgit v1.2.3 From 6192756574a9b1eb86ae9501c5f4bd29e7e5606e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 14:02:20 +0000 Subject: staging: comedi: skel: do auto-attachment of PCI devices This driver is an example of how to write a Comedi driver and includes some code for handling PCI devices, but not very much. It calls `comedi_pci_auto_config()` at PCI probe time. That normally expects to call the comedi driver's `auto_attach()` hook (or the deprecated `attach_pci()` hook), but will fall back to using the `attach()` hook that should only be used for attaching devices "manually" via the `COMEDI_DEVCONFIG` ioctl. Add an `auto_attach()` hook (`skel_auto_attach()`) to handle auto-attachment of supported PCI devices. Add comments to the `attach()` hook (`skel_attach()`) to indicate that it shouldn't generally allow PCI devices to be attached that way (and probably isn't needed at all for PCI-only Comedi drivers). Add code to the `detach()` hook (`skel_detach()`) to disable PCI devices enabled by the `auto_attach()` hook. `skel_auto_attach()` calls new function `skel_find_pci_board()` to find a matching element in `skel_boards[]`. PCI device ID information has been added to `skel_boards[]` to give the function something to look for. Remove the `pci_dev` member of `struct skel_private` as drivers now use the `hw_dev` member of `struct comedi_device` to get at the PCI device. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 222 +++++++++++++++++++++++++++++----- 1 file changed, 195 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index ccc1e9b3d26..162bf266f76 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -92,6 +92,7 @@ Configuration Options: */ struct skel_board { const char *name; + unsigned int devid; int ai_chans; int ai_bits; int have_dio; @@ -100,12 +101,14 @@ struct skel_board { static const struct skel_board skel_boards[] = { { .name = "skel-100", + .devid = 0x100, .ai_chans = 16, .ai_bits = 12, .have_dio = 1, }, { .name = "skel-200", + .devid = 0x200, .ai_chans = 8, .ai_bits = 16, .have_dio = 0, @@ -120,9 +123,6 @@ struct skel_private { int data; - /* would be useful for a PCI device */ - struct pci_dev *pci_dev; - /* Used for AO readback */ unsigned int ao_readback[2]; }; @@ -421,37 +421,30 @@ static int skel_dio_insn_config(struct comedi_device *dev, return insn->n; } -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. If you specified a board_name array - * in the driver structure, dev->board_ptr contains that - * address. - */ -static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static const struct skel_board *skel_find_pci_board(struct pci_dev *pcidev) { - const struct skel_board *thisboard; - struct skel_private *devpriv; - struct comedi_subdevice *s; - int ret; + unsigned int i; /* - * If you can probe the device to determine what device in a series - * it is, this is the place to do it. Otherwise, dev->board_ptr - * should already be initialized. + * This example code assumes all the entries in skel_boards[] are PCI boards + * and all use the same PCI vendor ID. If skel_boards[] contains a mixture + * of PCI and non-PCI boards, this loop should skip over the non-PCI boards. */ - /* dev->board_ptr = skel_probe(dev, it); */ + for (i = 0; i < ARRAY_SIZE(skel_boards); i++) + if (/* skel_boards[i].bustype == pci_bustype && */ + pcidev->device == skel_boards[i].devid) + return &skel_boards[i]; + return NULL; +} - thisboard = comedi_board(dev); /* - * Initialize dev->board_name. + * Handle common part of skel_attach() and skel_auto_attach(). */ - dev->board_name = thisboard->name; - - /* Allocate the private data */ - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); - if (!devpriv) - return -ENOMEM; - dev->private = devpriv; +static int skel_common_attach(struct comedi_device *dev) +{ + const struct skel_board *thisboard = comedi_board(dev); + struct comedi_subdevice *s; + int ret; ret = comedi_alloc_subdevices(dev, 3); if (ret) @@ -504,6 +497,146 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) return 0; } +/* + * _attach is called by the Comedi core to configure the driver + * for a particular board in response to the COMEDI_DEVCONFIG ioctl for + * a matching board or driver name. If you specified a board_name array + * in the driver structure, dev->board_ptr contains that address. + * + * Drivers that handle only PCI or USB devices do not usually support + * manual attachment of those devices via the COMEDI_DEVCONFIG ioctl, so + * those drivers do not have an _attach function; they just have an + * _auto_attach function instead. (See skel_auto_attach() for an example + * of such a function.) + */ +static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) +{ + const struct skel_board *thisboard; + struct skel_private *devpriv; + +/* + * If you can probe the device to determine what device in a series + * it is, this is the place to do it. Otherwise, dev->board_ptr + * should already be initialized. + */ + /* dev->board_ptr = skel_probe(dev, it); */ + + thisboard = comedi_board(dev); + +/* + * Initialize dev->board_name. + */ + dev->board_name = thisboard->name; + + /* Allocate the private data */ + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + +/* + * Supported boards are usually either auto-attached via the + * Comedi driver's _auto_attach routine, or manually attached via the + * Comedi driver's _attach routine. In most cases, attempts to + * manual attach boards that are usually auto-attached should be + * rejected by this function. + */ +/* + * if (thisboard->bustype == pci_bustype) { + * dev_err(dev->class_dev, + * "Manual attachment of PCI board '%s' not supported\n", + * thisboard->name); + * } + */ + +/* + * For ISA boards, get the i/o base address from it->options[], + * request the i/o region and set dev->iobase * from it->options[]. + * If using interrupts, get the IRQ number from it->options[]. + */ + + /* + * Call a common function to handle the remaining things to do for + * attaching ISA or PCI boards. (Extra parameters could be added + * to pass additional information such as IRQ number.) + */ + return skel_common_attach(dev); +} + +/* + * _auto_attach is called via comedi_pci_auto_config() (or + * comedi_usb_auto_config(), etc.) to handle devices that can be attached + * to the Comedi core automatically without the COMEDI_DEVCONFIG ioctl. + * + * For PCI devices, comedi_pci_auto_config() is usually called directly from + * the struct pci_driver probe() function, so this _auto_attach() function + * can be tagged __devinit. + * + * The context parameter is usually unused, but if the driver called + * comedi_auto_config() directly instead of the comedi_pci_auto_config() + * wrapper function, this will be a copy of the context passed to + * comedi_auto_config(). + */ +static int __devinit skel_auto_attach(struct comedi_device *dev, + unsigned long context) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct skel_board *thisboard; + struct skel_private *devpriv; + int ret; + + /* Hack to allow unused code to be optimized out. */ + if (!IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS)) + return -EINVAL; + + /* Find a matching board in skel_boards[]. */ + thisboard = skel_find_pci_board(pcidev); + if (!thisboard) { + dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); + return -EINVAL; + } + + /* + * Point the struct comedi_device to the matching board info + * and set the board name. + */ + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; + + /* Allocate the private data */ + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + /* Enable the PCI device. */ + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + + /* + * Record the fact that the PCI device is enabled so that it can + * be disabled during _detach(). + * + * For this example driver, we assume PCI BAR 0 is the main I/O + * region for the board registers and use dev->iobase to hold the + * I/O base address and to indicate that the PCI device has been + * enabled. + * + * (For boards with memory-mapped registers, dev->iobase is not + * usually needed for register access, so can just be set to 1 + * to indicate that the PCI device has been enabled.) + */ + dev->iobase = pci_resource_start(pcidev, 0); + + /* + * Call a common function to handle the remaining things to do for + * attaching ISA or PCI boards. (Extra parameters could be added + * to pass additional information such as IRQ number.) + */ + return skel_common_attach(dev); +} + /* * _detach is called to deconfigure a device. It should deallocate * resources. @@ -514,6 +647,40 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) */ static void skel_detach(struct comedi_device *dev) { + const struct skel_board *thisboard = comedi_board(dev); + struct skel_private *devpriv = dev->private; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + + if (!thisboard || !devpriv) + return; + +/* + * Do common stuff such as freeing IRQ, unmapping remapped memory + * regions, etc., being careful to check that the stuff is valid given + * that _detach() is called even when _attach() or _auto_attach() return + * an error. + */ + + if (IS_ENABLED(CONFIG_COMEDI_PCI_DRIVERS) /* && + thisboard->bustype == pci_bustype */) { + /* + * PCI board + * + * If PCI device enabled by _auto_attach() (or _attach()), + * disable it here. + */ + if (pcidev && dev->iobase) + comedi_pci_disable(pcidev); + } else { + /* + * ISA board + * + * If I/O regions successfully requested by _attach(), + * release them here. + */ + if (dev->iobase) + release_region(dev->iobase, SKEL_SIZE); + } } /* @@ -526,6 +693,7 @@ static struct comedi_driver skel_driver = { .driver_name = "dummy", .module = THIS_MODULE, .attach = skel_attach, + .auto_attach = skel_auto_attach, .detach = skel_detach, /* It is not necessary to implement the following members if you are * writing a driver for a ISA PnP or PCI card */ -- cgit v1.2.3 From d05b25b97c6444fc3db4f9f70d7edbdb754a2e1a Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 1 Nov 2012 02:24:35 -0400 Subject: staging: csr: inet.c: single statement if blocks doesn't need braces remove braces to single statement if blocks Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/inet.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/csr/inet.c b/drivers/staging/csr/inet.c index b4acb54ecc6..85062061757 100644 --- a/drivers/staging/csr/inet.c +++ b/drivers/staging/csr/inet.c @@ -93,14 +93,12 @@ static struct notifier_block uf_inetaddr_notifier = { void uf_register_inet_notifier(void) { - if (atomic_inc_return(&inet_notif_refs) == 1) { + if (atomic_inc_return(&inet_notif_refs) == 1) register_inetaddr_notifier(&uf_inetaddr_notifier); - } } void uf_unregister_inet_notifier(void) { - if (atomic_dec_return(&inet_notif_refs) == 0) { + if (atomic_dec_return(&inet_notif_refs) == 0) unregister_inetaddr_notifier(&uf_inetaddr_notifier); - } } -- cgit v1.2.3 From 79caaba624a1c762a9a607c58a0b84899f21a7a6 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 1 Nov 2012 02:24:36 -0400 Subject: staging: csr: inet.c: replaces spaces with tabs replace spaces with tabs at the start of line Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/inet.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/csr/inet.c b/drivers/staging/csr/inet.c index 85062061757..b3ef818fef3 100644 --- a/drivers/staging/csr/inet.c +++ b/drivers/staging/csr/inet.c @@ -93,12 +93,12 @@ static struct notifier_block uf_inetaddr_notifier = { void uf_register_inet_notifier(void) { - if (atomic_inc_return(&inet_notif_refs) == 1) - register_inetaddr_notifier(&uf_inetaddr_notifier); + if (atomic_inc_return(&inet_notif_refs) == 1) + register_inetaddr_notifier(&uf_inetaddr_notifier); } void uf_unregister_inet_notifier(void) { - if (atomic_dec_return(&inet_notif_refs) == 0) - unregister_inetaddr_notifier(&uf_inetaddr_notifier); + if (atomic_dec_return(&inet_notif_refs) == 0) + unregister_inetaddr_notifier(&uf_inetaddr_notifier); } -- cgit v1.2.3 From dc958bbad339e153b045c91debcf8d0ef9e46c27 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 1 Nov 2012 02:24:37 -0400 Subject: staging: csr: sme_blocking.c: replace spaces with tabs replace spaces at the beginning of the line with tabs in sme_mgt_packet_filter_set Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/sme_blocking.c | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/staging/csr/sme_blocking.c b/drivers/staging/csr/sme_blocking.c index 543e8f2c407..0e40eed26b3 100644 --- a/drivers/staging/csr/sme_blocking.c +++ b/drivers/staging/csr/sme_blocking.c @@ -1272,30 +1272,30 @@ int sme_mgt_connection_stats_get(unifi_priv_t *priv, CsrWifiSmeConnectionStats * int sme_mgt_packet_filter_set(unifi_priv_t *priv) { - CsrWifiIp4Address ipAddress = {{0xFF, 0xFF, 0xFF, 0xFF }}; - if (priv->smepriv == NULL) { - unifi_error(priv, "sme_mgt_packet_filter_set: invalid smepriv\n"); - return -EIO; - } - if (priv->packet_filters.arp_filter) { - ipAddress.a[0] = (priv->sta_ip_address ) & 0xFF; - ipAddress.a[1] = (priv->sta_ip_address >> 8) & 0xFF; - ipAddress.a[2] = (priv->sta_ip_address >> 16) & 0xFF; - ipAddress.a[3] = (priv->sta_ip_address >> 24) & 0xFF; - } - - unifi_trace(priv, UDBG5, - "sme_mgt_packet_filter_set: IP address %d.%d.%d.%d\n", - ipAddress.a[0], ipAddress.a[1], - ipAddress.a[2], ipAddress.a[3]); - - /* Doesn't block for a confirm */ - CsrWifiSmePacketFilterSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE, - priv->packet_filters.tclas_ies_length, - priv->filter_tclas_ies, - priv->packet_filters.filter_mode, - ipAddress); - return 0; + CsrWifiIp4Address ipAddress = {{0xFF, 0xFF, 0xFF, 0xFF }}; + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_packet_filter_set: invalid smepriv\n"); + return -EIO; + } + if (priv->packet_filters.arp_filter) { + ipAddress.a[0] = (priv->sta_ip_address ) & 0xFF; + ipAddress.a[1] = (priv->sta_ip_address >> 8) & 0xFF; + ipAddress.a[2] = (priv->sta_ip_address >> 16) & 0xFF; + ipAddress.a[3] = (priv->sta_ip_address >> 24) & 0xFF; + } + + unifi_trace(priv, UDBG5, + "sme_mgt_packet_filter_set: IP address %d.%d.%d.%d\n", + ipAddress.a[0], ipAddress.a[1], + ipAddress.a[2], ipAddress.a[3]); + + /* Doesn't block for a confirm */ + CsrWifiSmePacketFilterSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE, + priv->packet_filters.tclas_ies_length, + priv->filter_tclas_ies, + priv->packet_filters.filter_mode, + ipAddress); + return 0; } int sme_mgt_tspec(unifi_priv_t *priv, CsrWifiSmeListAction action, -- cgit v1.2.3 From 3b7ffa6fc0ed5ca53cfc5f499869634a92be449a Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 1 Nov 2012 02:24:38 -0400 Subject: staging: csr: sme_blocking.c: replace spaces with the tabs in sme_mgt_tspec replace spaces at start of line with tabs in sme_mgt_tspec Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/sme_blocking.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/staging/csr/sme_blocking.c b/drivers/staging/csr/sme_blocking.c index 0e40eed26b3..3fddd733e7b 100644 --- a/drivers/staging/csr/sme_blocking.c +++ b/drivers/staging/csr/sme_blocking.c @@ -1301,29 +1301,29 @@ int sme_mgt_packet_filter_set(unifi_priv_t *priv) int sme_mgt_tspec(unifi_priv_t *priv, CsrWifiSmeListAction action, u32 tid, CsrWifiSmeDataBlock *tspec, CsrWifiSmeDataBlock *tclas) { - int r; + int r; - if (priv->smepriv == NULL) { - unifi_error(priv, "sme_mgt_tspec: invalid smepriv\n"); - return -EIO; - } + if (priv->smepriv == NULL) { + unifi_error(priv, "sme_mgt_tspec: invalid smepriv\n"); + return -EIO; + } - r = sme_init_request(priv); - if (r) { - return -EIO; - } + r = sme_init_request(priv); + if (r) { + return -EIO; + } - CsrWifiSmeTspecReqSend(0, CSR_WIFI_INTERFACE_IN_USE, - action, tid, TRUE, 0, - tspec->length, tspec->data, - tclas->length, tclas->data); - r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { - return r; - } + CsrWifiSmeTspecReqSend(0, CSR_WIFI_INTERFACE_IN_USE, + action, tid, TRUE, 0, + tspec->length, tspec->data, + tclas->length, tclas->data); + r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) { + return r; + } - unifi_trace(priv, UDBG4, "sme_mgt_tspec: <-- (status=%d)\n", priv->sme_reply.reply_status); - return convert_sme_error(priv->sme_reply.reply_status); + unifi_trace(priv, UDBG4, "sme_mgt_tspec: <-- (status=%d)\n", priv->sme_reply.reply_status); + return convert_sme_error(priv->sme_reply.reply_status); } -- cgit v1.2.3 From 6d700d72c9053a1a6816f4237b6d9528f7cf2564 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 1 Nov 2012 02:24:39 -0400 Subject: staging: csr: sme_blocking.c: remove braces around single statement blocks remove the braces around single statement if blocks Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/sme_blocking.c | 219 +++++++++++++------------------------ 1 file changed, 74 insertions(+), 145 deletions(-) diff --git a/drivers/staging/csr/sme_blocking.c b/drivers/staging/csr/sme_blocking.c index 3fddd733e7b..f79811e2d7e 100644 --- a/drivers/staging/csr/sme_blocking.c +++ b/drivers/staging/csr/sme_blocking.c @@ -270,17 +270,15 @@ int sme_mgt_wifi_off(unifi_priv_t *priv) } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } /* Stop the SME */ CsrWifiSmeWifiOffReqSend(0); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_mgt_wifi_off: unifi_mgt_wifi_off_req <-- (r=%d, status=%d)\n", @@ -300,16 +298,14 @@ int sme_mgt_key(unifi_priv_t *priv, CsrWifiSmeKey *sme_key, } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeKeyReqSend(0, CSR_WIFI_INTERFACE_IN_USE, action, *sme_key); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } return convert_sme_error(priv->sme_reply.reply_status); } @@ -332,9 +328,8 @@ int sme_mgt_scan_full(unifi_priv_t *priv, unifi_trace(priv, UDBG4, "sme_mgt_scan_full: -->\n"); r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } /* If a channel list is provided, do an active scan */ if (is_active) { @@ -354,16 +349,14 @@ int sme_mgt_scan_full(unifi_priv_t *priv, 0, NULL); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_mgt_scan_full: <-- (status=%d)\n", priv->sme_reply.reply_status); - if (priv->sme_reply.reply_status == CSR_WIFI_RESULT_UNAVAILABLE) { + if (priv->sme_reply.reply_status == CSR_WIFI_RESULT_UNAVAILABLE) return 0; /* initial scan already underway */ - } else { + else return convert_sme_error(priv->sme_reply.reply_status); - } } @@ -385,15 +378,13 @@ int sme_mgt_scan_results_get_async(unifi_priv_t *priv, } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeScanResultsGetReqSend(0); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT); - if (r) { + if (r) return r; - } scan_result_list_count = priv->sme_reply.reply_scan_results_count; scan_result_list = priv->sme_reply.reply_scan_results; @@ -454,20 +445,17 @@ int sme_mgt_connect(unifi_priv_t *priv) priv->connection_config.ssid.ssid); r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeConnectReqSend(0, CSR_WIFI_INTERFACE_IN_USE, priv->connection_config); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } - if (priv->sme_reply.reply_status) { + if (priv->sme_reply.reply_status) unifi_trace(priv, UDBG1, "sme_mgt_connect: failed with SME status %d\n", priv->sme_reply.reply_status); - } return convert_sme_error(priv->sme_reply.reply_status); } @@ -483,15 +471,13 @@ int sme_mgt_disconnect(unifi_priv_t *priv) } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeDisconnectReqSend(0, CSR_WIFI_INTERFACE_IN_USE); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_mgt_disconnect: <-- (status=%d)\n", priv->sme_reply.reply_status); return convert_sme_error(priv->sme_reply.reply_status); @@ -510,16 +496,14 @@ int sme_mgt_pmkid(unifi_priv_t *priv, } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmePmkidReqSend(0, CSR_WIFI_INTERFACE_IN_USE, action, pmkid_list->pmkidsCount, pmkid_list->pmkids); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_mgt_pmkid: <-- (status=%d)\n", priv->sme_reply.reply_status); return convert_sme_error(priv->sme_reply.reply_status); @@ -537,9 +521,8 @@ int sme_mgt_mib_get(unifi_priv_t *priv, } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } priv->mib_cfm_buffer = varbind; priv->mib_cfm_buffer_length = MAX_VARBIND_LENGTH; @@ -571,15 +554,13 @@ int sme_mgt_mib_set(unifi_priv_t *priv, } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeMibSetReqSend(0, length, varbind); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_mgt_mib_set: <-- (status=%d)\n", priv->sme_reply.reply_status); return convert_sme_error(priv->sme_reply.reply_status); @@ -598,16 +579,14 @@ int sme_mgt_power_config_set(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerCon } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmePowerConfigSetReqSend(0, *powerConfig); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_mgt_set_value_async: unifi_mgt_set_value_req <-- (r=%d status=%d)\n", @@ -637,29 +616,26 @@ int sme_mgt_sme_config_set(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, C } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeSmeStaConfigSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE, *staConfig); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } + unifi_trace(priv, UDBG4, "sme_mgt_sme_config_set: CsrWifiSmeSmeStaConfigSetReq <-- (r=%d status=%d)\n", r, priv->sme_reply.reply_status); r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeSmeCommonConfigSetReqSend(0, *deviceConfig); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_mgt_sme_config_set: CsrWifiSmeSmeCommonConfigSetReq <-- (r=%d status=%d)\n", @@ -693,16 +669,14 @@ int sme_mgt_mib_config_set(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig) } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeMibConfigSetReqSend(0, *mibConfig); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_mgt_mib_config_set: unifi_mgt_set_mib_config_req <-- (r=%d status=%d)\n", @@ -732,16 +706,14 @@ int sme_mgt_coex_config_set(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeCoexConfigSetReqSend(0, *coexConfig); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_mgt_coex_config_set: unifi_mgt_set_mib_config_req <-- (r=%d status=%d)\n", @@ -773,16 +745,14 @@ int sme_mgt_host_config_set(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeHostConfigSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE, *hostConfig); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_mgt_host_config_set: unifi_mgt_set_host_config_req <-- (r=%d status=%d)\n", @@ -815,16 +785,14 @@ int sme_mgt_versions_get(unifi_priv_t *priv, CsrWifiSmeVersions *versions) unifi_trace(priv, UDBG4, "sme_mgt_versions_get: unifi_mgt_versions_get_req -->\n"); r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeVersionsGetReqSend(0); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } /* store the reply */ if (versions != NULL) { @@ -861,16 +829,14 @@ int sme_mgt_power_config_get(unifi_priv_t *priv, CsrWifiSmePowerConfig *powerCon unifi_trace(priv, UDBG4, "sme_mgt_power_config_get: unifi_mgt_power_config_req -->\n"); r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmePowerConfigGetReqSend(0); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } /* store the reply */ if (powerConfig != NULL) { @@ -905,23 +871,20 @@ int sme_mgt_host_config_get(unifi_priv_t *priv, CsrWifiSmeHostConfig *hostConfig unifi_trace(priv, UDBG4, "sme_mgt_host_config_get: unifi_mgt_host_config_get_req -->\n"); r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeHostConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } /* store the reply */ - if (hostConfig != NULL) { + if (hostConfig != NULL) memcpy((unsigned char*)hostConfig, (unsigned char*)&priv->sme_reply.hostConfig, sizeof(CsrWifiSmeHostConfig)); - } unifi_trace(priv, UDBG4, "sme_mgt_host_config_get: unifi_mgt_host_config_get_req <-- (r=%d status=%d)\n", @@ -951,41 +914,35 @@ int sme_mgt_sme_config_get(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, C /* Common device config */ r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeSmeCommonConfigGetReqSend(0); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } /* store the reply */ - if (deviceConfig != NULL) { + if (deviceConfig != NULL) memcpy((unsigned char*)deviceConfig, (unsigned char*)&priv->sme_reply.deviceConfig, sizeof(CsrWifiSmeDeviceConfig)); - } /* STA config */ r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeSmeStaConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } /* store the reply */ - if (staConfig != NULL) { + if (staConfig != NULL) memcpy((unsigned char*)staConfig, (unsigned char*)&priv->sme_reply.staConfig, sizeof(CsrWifiSmeStaConfig)); - } unifi_trace(priv, UDBG4, "sme_mgt_sme_config_get: unifi_mgt_sme_config_get_req <-- (r=%d status=%d)\n", @@ -1014,23 +971,20 @@ int sme_mgt_coex_info_get(unifi_priv_t *priv, CsrWifiSmeCoexInfo *coexInfo) unifi_trace(priv, UDBG4, "sme_mgt_coex_info_get: unifi_mgt_coex_info_get_req -->\n"); r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeCoexInfoGetReqSend(0); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } /* store the reply */ - if (coexInfo != NULL) { + if (coexInfo != NULL) memcpy((unsigned char*)coexInfo, (unsigned char*)&priv->sme_reply.coexInfo, sizeof(CsrWifiSmeCoexInfo)); - } unifi_trace(priv, UDBG4, "sme_mgt_coex_info_get: unifi_mgt_coex_info_get_req <-- (r=%d status=%d)\n", @@ -1060,23 +1014,20 @@ int sme_mgt_coex_config_get(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig unifi_trace(priv, UDBG4, "sme_mgt_coex_config_get: unifi_mgt_coex_config_get_req -->\n"); r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeCoexConfigGetReqSend(0); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } /* store the reply */ - if (coexConfig != NULL) { + if (coexConfig != NULL) memcpy((unsigned char*)coexConfig, (unsigned char*)&priv->sme_reply.coexConfig, sizeof(CsrWifiSmeCoexConfig)); - } unifi_trace(priv, UDBG4, "sme_mgt_coex_config_get: unifi_mgt_coex_config_get_req <-- (r=%d status=%d)\n", @@ -1104,23 +1055,20 @@ int sme_mgt_mib_config_get(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig) unifi_trace(priv, UDBG4, "sme_mgt_mib_config_get: unifi_mgt_mib_config_get_req -->\n"); r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeMibConfigGetReqSend(0); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } /* store the reply */ - if (mibConfig != NULL) { + if (mibConfig != NULL) memcpy((unsigned char*)mibConfig, (unsigned char*)&priv->sme_reply.mibConfig, sizeof(CsrWifiSmeMibConfig)); - } unifi_trace(priv, UDBG4, "sme_mgt_mib_config_get: unifi_mgt_mib_config_get_req <-- (r=%d status=%d)\n", @@ -1148,23 +1096,20 @@ int sme_mgt_connection_info_get(unifi_priv_t *priv, CsrWifiSmeConnectionInfo *co unifi_trace(priv, UDBG4, "sme_mgt_connection_info_get: unifi_mgt_connection_info_get_req -->\n"); r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeConnectionInfoGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } /* store the reply */ - if (connectionInfo != NULL) { + if (connectionInfo != NULL) memcpy((unsigned char*)connectionInfo, (unsigned char*)&priv->sme_reply.connectionInfo, sizeof(CsrWifiSmeConnectionInfo)); - } unifi_trace(priv, UDBG4, "sme_mgt_connection_info_get: unifi_mgt_connection_info_get_req <-- (r=%d status=%d)\n", @@ -1192,23 +1137,20 @@ int sme_mgt_connection_config_get(unifi_priv_t *priv, CsrWifiSmeConnectionConfig unifi_trace(priv, UDBG4, "sme_mgt_connection_config_get: unifi_mgt_connection_config_get_req -->\n"); r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeConnectionConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } /* store the reply */ - if (connectionConfig != NULL) { + if (connectionConfig != NULL) memcpy((unsigned char*)connectionConfig, (unsigned char*)&priv->sme_reply.connectionConfig, sizeof(CsrWifiSmeConnectionConfig)); - } unifi_trace(priv, UDBG4, "sme_mgt_connection_config_get: unifi_mgt_connection_config_get_req <-- (r=%d status=%d)\n", @@ -1236,23 +1178,20 @@ int sme_mgt_connection_stats_get(unifi_priv_t *priv, CsrWifiSmeConnectionStats * unifi_trace(priv, UDBG4, "sme_mgt_connection_stats_get: unifi_mgt_connection_stats_get_req -->\n"); r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeConnectionStatsGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } /* store the reply */ - if (connectionStats != NULL) { + if (connectionStats != NULL) memcpy((unsigned char*)connectionStats, (unsigned char*)&priv->sme_reply.connectionStats, sizeof(CsrWifiSmeConnectionStats)); - } unifi_trace(priv, UDBG4, "sme_mgt_connection_stats_get: unifi_mgt_connection_stats_get_req <-- (r=%d status=%d)\n", @@ -1309,18 +1248,16 @@ int sme_mgt_tspec(unifi_priv_t *priv, CsrWifiSmeListAction action, } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiSmeTspecReqSend(0, CSR_WIFI_INTERFACE_IN_USE, action, tid, TRUE, 0, tspec->length, tspec->data, tclas->length, tclas->data); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_mgt_tspec: <-- (status=%d)\n", priv->sme_reply.reply_status); return convert_sme_error(priv->sme_reply.reply_status); @@ -1339,9 +1276,8 @@ int sme_sys_suspend(unifi_priv_t *priv) } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } /* Suspend the SME, which MAY cause it to power down UniFi */ CsrWifiRouterCtrlSuspendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, 0, priv->wol_suspend); @@ -1427,17 +1363,15 @@ int sme_sys_resume(unifi_priv_t *priv) } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiRouterCtrlResumeIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, priv->wol_suspend); r = sme_wait_for_reply(priv, UNIFI_SME_SYS_LONG_TIMEOUT); - if (r) { + if (r) unifi_notice(priv, "resume: SME did not reply, return success anyway\n"); - } return 0; } @@ -1453,16 +1387,14 @@ int sme_ap_stop(unifi_priv_t *priv,u16 interface_tag) } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiNmeApStopReqSend(0,interface_tag); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_ap_stop <-- (r=%d status=%d)\n", @@ -1484,9 +1416,8 @@ int sme_ap_start(unifi_priv_t *priv,u16 interface_tag, } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiNmeApStartReqSend(0,interface_tag,CSR_WIFI_AP_TYPE_LEGACY,FALSE, ap_config->ssid,1,ap_config->channel, @@ -1494,9 +1425,8 @@ int sme_ap_start(unifi_priv_t *priv,u16 interface_tag, p2p_go_param,FALSE); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); - if (r) { + if (r) return r; - } unifi_trace(priv, UDBG4, "sme_ap_start <-- (r=%d status=%d)\n", @@ -1518,9 +1448,8 @@ int sme_ap_config(unifi_priv_t *priv, } r = sme_init_request(priv); - if (r) { + if (r) return -EIO; - } CsrWifiNmeApConfigSetReqSend(0,*group_security_config, *ap_mac_config); -- cgit v1.2.3 From a6de05d87aa8604acf062ce42ace21e08986d2a9 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 1 Nov 2012 02:24:40 -0400 Subject: staging: csr: sme_blocking.c: add missing check for return of sme_wait_for_reply sme_ap_config misses a check of the return of the sme_wait_for_reply as all other functions do here, for the return of sme_wait_for_reply add the check and fail if it returns other than 0. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/sme_blocking.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/csr/sme_blocking.c b/drivers/staging/csr/sme_blocking.c index f79811e2d7e..d88ccd5bd42 100644 --- a/drivers/staging/csr/sme_blocking.c +++ b/drivers/staging/csr/sme_blocking.c @@ -1455,6 +1455,8 @@ int sme_ap_config(unifi_priv_t *priv, *ap_mac_config); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); + if (r) + return r; unifi_trace(priv, UDBG4, "sme_ap_config <-- (r=%d status=%d)\n", -- cgit v1.2.3 From 1454201f2d40f210af7421eb85937a8127ea9100 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 1 Nov 2012 02:24:41 -0400 Subject: staging: csr: csr_wifi_nme_lib.h: remove function prototypes the function definitions are missing for these prototypes, so remove all these. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_nme_lib.h | 54 ---------------------------------- 1 file changed, 54 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_nme_lib.h b/drivers/staging/csr/csr_wifi_nme_lib.h index 1b1e0376a86..5a1f132009b 100644 --- a/drivers/staging/csr/csr_wifi_nme_lib.h +++ b/drivers/staging/csr/csr_wifi_nme_lib.h @@ -27,60 +27,6 @@ #error CSR_WIFI_NME_ENABLE MUST be defined inorder to use csr_wifi_nme_lib.h #endif -/*----------------------------------------------------------------------------* - * CsrWifiNmeFreeUpstreamMessageContents - * - * DESCRIPTION - * Free the allocated memory in a CSR_WIFI_NME upstream message. Does not - * free the message itself, and can only be used for upstream messages. - * - * PARAMETERS - * Deallocates the resources in a CSR_WIFI_NME upstream message - *----------------------------------------------------------------------------*/ -void CsrWifiNmeFreeUpstreamMessageContents(u16 eventClass, void *message); - -/*----------------------------------------------------------------------------* - * CsrWifiNmeFreeDownstreamMessageContents - * - * DESCRIPTION - * Free the allocated memory in a CSR_WIFI_NME downstream message. Does not - * free the message itself, and can only be used for downstream messages. - * - * PARAMETERS - * Deallocates the resources in a CSR_WIFI_NME downstream message - *----------------------------------------------------------------------------*/ -void CsrWifiNmeFreeDownstreamMessageContents(u16 eventClass, void *message); - -/*----------------------------------------------------------------------------* - * Enum to string functions - *----------------------------------------------------------------------------*/ -const char* CsrWifiNmeAuthModeToString(CsrWifiNmeAuthMode value); -const char* CsrWifiNmeBssTypeToString(CsrWifiNmeBssType value); -const char* CsrWifiNmeCcxOptionsMaskToString(CsrWifiNmeCcxOptionsMask value); -const char* CsrWifiNmeConfigActionToString(CsrWifiNmeConfigAction value); -const char* CsrWifiNmeConnectionStatusToString(CsrWifiNmeConnectionStatus value); -const char* CsrWifiNmeCredentialTypeToString(CsrWifiNmeCredentialType value); -const char* CsrWifiNmeEapMethodToString(CsrWifiNmeEapMethod value); -const char* CsrWifiNmeEncryptionToString(CsrWifiNmeEncryption value); -const char* CsrWifiNmeIndicationsToString(CsrWifiNmeIndications value); -const char* CsrWifiNmeSecErrorToString(CsrWifiNmeSecError value); -const char* CsrWifiNmeSimCardTypeToString(CsrWifiNmeSimCardType value); -const char* CsrWifiNmeUmtsAuthResultToString(CsrWifiNmeUmtsAuthResult value); -const char* CsrWifiNmeWmmQosInfoToString(CsrWifiNmeWmmQosInfo value); - - -/*----------------------------------------------------------------------------* - * CsrPrim Type toString function. - * Converts a message type to the String name of the Message - *----------------------------------------------------------------------------*/ -const char* CsrWifiNmePrimTypeToString(CsrPrim msgType); - -/*----------------------------------------------------------------------------* - * Lookup arrays for PrimType name Strings - *----------------------------------------------------------------------------*/ -extern const char *CsrWifiNmeUpstreamPrimNames[CSR_WIFI_NME_PRIM_UPSTREAM_COUNT]; -extern const char *CsrWifiNmeDownstreamPrimNames[CSR_WIFI_NME_PRIM_DOWNSTREAM_COUNT]; - /******************************************************************************* NAME -- cgit v1.2.3 From 4a530183f5caa0df3a353ee75b8baa231b489ebd Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 1 Nov 2012 02:24:42 -0400 Subject: staging: csr: csr_wifi_nme_ap_lib.h: remove the function prototypes these function prototypes are missing the function definition, remove them all. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_nme_ap_lib.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_nme_ap_lib.h b/drivers/staging/csr/csr_wifi_nme_ap_lib.h index 7d2fccde9fb..6d8df836681 100644 --- a/drivers/staging/csr/csr_wifi_nme_ap_lib.h +++ b/drivers/staging/csr/csr_wifi_nme_ap_lib.h @@ -53,24 +53,6 @@ void CsrWifiNmeApFreeUpstreamMessageContents(u16 eventClass, void *message); *----------------------------------------------------------------------------*/ void CsrWifiNmeApFreeDownstreamMessageContents(u16 eventClass, void *message); -/*----------------------------------------------------------------------------* - * Enum to string functions - *----------------------------------------------------------------------------*/ -const char* CsrWifiNmeApPersCredentialTypeToString(CsrWifiNmeApPersCredentialType value); - - -/*----------------------------------------------------------------------------* - * CsrPrim Type toString function. - * Converts a message type to the String name of the Message - *----------------------------------------------------------------------------*/ -const char* CsrWifiNmeApPrimTypeToString(CsrPrim msgType); - -/*----------------------------------------------------------------------------* - * Lookup arrays for PrimType name Strings - *----------------------------------------------------------------------------*/ -extern const char *CsrWifiNmeApUpstreamPrimNames[CSR_WIFI_NME_AP_PRIM_UPSTREAM_COUNT]; -extern const char *CsrWifiNmeApDownstreamPrimNames[CSR_WIFI_NME_AP_PRIM_DOWNSTREAM_COUNT]; - /******************************************************************************* NAME -- cgit v1.2.3 From 986842dd579aa6a797ed2dee8c35e45ad4c6ec89 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Thu, 1 Nov 2012 02:24:43 -0400 Subject: staging: csr: csr_wifi_nme_task.h: remove function prototypes there are function definitions missing for these prototypes, so remove all 3 function protos. Signed-off-by: Devendra Naga Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_nme_task.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_nme_task.h b/drivers/staging/csr/csr_wifi_nme_task.h index 8a1aae66140..84e973a59bb 100644 --- a/drivers/staging/csr/csr_wifi_nme_task.h +++ b/drivers/staging/csr/csr_wifi_nme_task.h @@ -22,9 +22,6 @@ #define CSR_WIFI_NME_LOG_ID 0x1203FFFF extern CsrSchedQid CSR_WIFI_NME_IFACEQUEUE; -void CsrWifiNmeInit(void **gash); -void CsrWifiNmeDeinit(void **gash); -void CsrWifiNmeHandler(void **gash); #endif /* CSR_WIFI_NME_TASK_H__ */ -- cgit v1.2.3 From 31fe99048859b13a87f476016e7bb5c2b5220c36 Mon Sep 17 00:00:00 2001 From: chao bi Date: Wed, 31 Oct 2012 16:54:07 +0800 Subject: serial:ifx6x60:Prevent data transfer when IFX6x60 port is shutdown This patch is to implement following 2 places to avoid potential error when IFX6x60 port shutdown: 1) Clear Flag IFX_SPI_STATE_IO_AVAILABLE to disable data transfer when Modem port is shutdown; 2) Clear Flag IFX_SPI_STATE_IO_IN_PROGRESS and IFX_SPI_STATE_IO_READY when reopen port. This is because last port shutdown may happen when SPI/DMA transfer is in progress, if the last data transfer is not completed(for example due to modem reset), the Flag IFX_SPI_STATE_IO_IN_PROGRESS will be set forever, so when IFX port is activated again, IFX_SPI_STATE_IO_IN_PROGRESS will prevent transferring data forever. And if don't clear IFX_SPI_STATE_IO_READY, it may cause one more SPI frame transferring in spit there is not data need to be transfer. cc: liu chuansheng cc: Chen Jun Signed-off-by: channing Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 11 ++++++++++- drivers/tty/serial/ifx6x60.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index e595c832be2..fbda37415f0 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -569,12 +569,19 @@ static int ifx_port_activate(struct tty_port *port, struct tty_struct *tty) /* clear any old data; can't do this in 'close' */ kfifo_reset(&ifx_dev->tx_fifo); + /* clear any flag which may be set in port shutdown procedure */ + clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags); + clear_bit(IFX_SPI_STATE_IO_READY, &ifx_dev->flags); + /* put port data into this tty */ tty->driver_data = ifx_dev; /* allows flip string push from int context */ tty->low_latency = 1; + /* set flag to allows data transfer */ + set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); + return 0; } @@ -590,6 +597,7 @@ static void ifx_port_shutdown(struct tty_port *port) struct ifx_spi_device *ifx_dev = container_of(port, struct ifx_spi_device, tty_port); + clear_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags); mrdy_set_low(ifx_dev); clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags); tasklet_kill(&ifx_dev->io_work_tasklet); @@ -745,7 +753,8 @@ static void ifx_spi_io(unsigned long data) int retval; struct ifx_spi_device *ifx_dev = (struct ifx_spi_device *) data; - if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags)) { + if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags) && + test_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags)) { if (ifx_dev->gpio.unack_srdy_int_nb > 0) ifx_dev->gpio.unack_srdy_int_nb--; diff --git a/drivers/tty/serial/ifx6x60.h b/drivers/tty/serial/ifx6x60.h index d8869f5a463..4fbddc29783 100644 --- a/drivers/tty/serial/ifx6x60.h +++ b/drivers/tty/serial/ifx6x60.h @@ -41,6 +41,7 @@ #define IFX_SPI_STATE_IO_IN_PROGRESS 1 #define IFX_SPI_STATE_IO_READY 2 #define IFX_SPI_STATE_TIMER_PENDING 3 +#define IFX_SPI_STATE_IO_AVAILABLE 4 /* flow control bitfields */ #define IFX_SPI_DCD 0 -- cgit v1.2.3 From 76cc43868c1e9d6344ad6c4992c4f6abd5204a8f Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 1 Nov 2012 13:27:34 +0800 Subject: tty: of_serial: fix return value check in of_platform_serial_setup() In case of error, the function clk_get() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR(). dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/of_serial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 533ccfe7709..b9fdccb2259 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -66,10 +66,10 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, /* Get clk rate through clk driver if present */ info->clk = clk_get(&ofdev->dev, NULL); - if (info->clk == NULL) { + if (IS_ERR(info->clk)) { dev_warn(&ofdev->dev, "clk or clock-frequency not defined\n"); - return -ENODEV; + return PTR_ERR(info->clk); } clk_prepare_enable(info->clk); -- cgit v1.2.3 From 3e0232039967d7a1a06c013d097458b4d5892af1 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 1 Nov 2012 11:12:58 -0400 Subject: USB: EHCI: prepare to make ehci-hcd a library module This patch (as1624) prepares ehci-hcd for being split up into a core library and separate platform driver modules. A generic ehci_hc_driver structure is created, containing all the "standard" values, and a new mechanism is added whereby a driver module can specify a set of overrides to those values. In addition the ehci_setup(), ehci_suspend(), and ehci_resume() routines need to be EXPORTed for use by the drivers. As a side effect of this change, a few routines no longer need to be marked __maybe_unused. Signed-off-by: Alan Stern CC: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 73 +++++++++++++++++++++++++++++++++++++++++++-- drivers/usb/host/ehci-hub.c | 6 ++-- drivers/usb/host/ehci.h | 17 +++++++++++ 3 files changed, 89 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index ab4a769a410..dee3541bfae 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -649,7 +649,7 @@ static int ehci_run (struct usb_hcd *hcd) return 0; } -static int ehci_setup(struct usb_hcd *hcd) +int ehci_setup(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); int retval; @@ -680,6 +680,7 @@ static int ehci_setup(struct usb_hcd *hcd) return 0; } +EXPORT_SYMBOL_GPL(ehci_setup); /*-------------------------------------------------------------------------*/ @@ -1085,7 +1086,7 @@ static int ehci_get_frame (struct usb_hcd *hcd) /* These routines handle the generic parts of controller suspend/resume */ -static int __maybe_unused ehci_suspend(struct usb_hcd *hcd, bool do_wakeup) +int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); @@ -1108,9 +1109,10 @@ static int __maybe_unused ehci_suspend(struct usb_hcd *hcd, bool do_wakeup) return 0; } +EXPORT_SYMBOL_GPL(ehci_suspend); /* Returns 0 if power was preserved, 1 if power was lost */ -static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated) +int ehci_resume(struct usb_hcd *hcd, bool hibernated) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); @@ -1168,11 +1170,76 @@ static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated) return 1; } +EXPORT_SYMBOL_GPL(ehci_resume); #endif /*-------------------------------------------------------------------------*/ +/* + * Generic structure: This gets copied for platform drivers so that + * individual entries can be overridden as needed. + */ + +static const struct hc_driver ehci_hc_driver = { + .description = hcd_name, + .product_desc = "EHCI Host Controller", + .hcd_priv_size = sizeof(struct ehci_hcd), + + /* + * generic hardware linkage + */ + .irq = ehci_irq, + .flags = HCD_MEMORY | HCD_USB2, + + /* + * basic lifecycle operations + */ + .reset = ehci_setup, + .start = ehci_run, + .stop = ehci_stop, + .shutdown = ehci_shutdown, + + /* + * managing i/o requests and associated device resources + */ + .urb_enqueue = ehci_urb_enqueue, + .urb_dequeue = ehci_urb_dequeue, + .endpoint_disable = ehci_endpoint_disable, + .endpoint_reset = ehci_endpoint_reset, + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, + + /* + * scheduling support + */ + .get_frame_number = ehci_get_frame, + + /* + * root hub support + */ + .hub_status_data = ehci_hub_status_data, + .hub_control = ehci_hub_control, + .bus_suspend = ehci_bus_suspend, + .bus_resume = ehci_bus_resume, + .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, +}; + +void ehci_init_driver(struct hc_driver *drv, + const struct ehci_driver_overrides *over) +{ + /* Copy the generic table to drv and then apply the overrides */ + *drv = ehci_hc_driver; + + drv->product_desc = over->product_desc; + drv->hcd_priv_size += over->extra_priv_size; + if (over->reset) + drv->reset = over->reset; +} +EXPORT_SYMBOL_GPL(ehci_init_driver); + +/*-------------------------------------------------------------------------*/ + /* * The EHCI in ChipIdea HDRC cannot be a separate module or device, * because its registers (and irq) are shared between host/gadget/otg diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index a59c61fea09..4ccb97c0678 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -1109,8 +1109,7 @@ error_exit: return retval; } -static void __maybe_unused ehci_relinquish_port(struct usb_hcd *hcd, - int portnum) +static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); @@ -1119,8 +1118,7 @@ static void __maybe_unused ehci_relinquish_port(struct usb_hcd *hcd, set_owner(ehci, --portnum, PORT_OWNER); } -static int __maybe_unused ehci_port_handed_over(struct usb_hcd *hcd, - int portnum) +static int ehci_port_handed_over(struct usb_hcd *hcd, int portnum) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); u32 __iomem *reg; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2262dcdaa3c..24a8ada4701 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -781,4 +781,21 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) /*-------------------------------------------------------------------------*/ +/* Declarations of things exported for use by ehci platform drivers */ + +struct ehci_driver_overrides { + const char *product_desc; + size_t extra_priv_size; + int (*reset)(struct usb_hcd *hcd); +}; + +extern void ehci_init_driver(struct hc_driver *drv, + const struct ehci_driver_overrides *over); +extern int ehci_setup(struct usb_hcd *hcd); + +#ifdef CONFIG_PM +extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup); +extern int ehci_resume(struct usb_hcd *hcd, bool hibernated); +#endif /* CONFIG_PM */ + #endif /* __LINUX_EHCI_HCD_H */ -- cgit v1.2.3 From adfa79d1c06a32650332930ca4c488ca570b3407 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 1 Nov 2012 11:13:04 -0400 Subject: USB: EHCI: make ehci-pci a separate driver This patch (as1625) splits the PCI portion of ehci-hcd out into its own separate driver module, called ehci-pci. Consistently with the current practice, the decision whether to build this module is not user-configurable. If EHCI and PCI are enabled then the module will be built, always. Signed-off-by: Alan Stern CC: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 5 +++ drivers/usb/host/Makefile | 2 + drivers/usb/host/ehci-hcd.c | 26 +++--------- drivers/usb/host/ehci-pci.c | 101 +++++++++++++++++++++----------------------- 4 files changed, 60 insertions(+), 74 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 8cc06f054c6..10130f47fc7 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -95,6 +95,11 @@ config USB_EHCI_TT_NEWSCHED If unsure, say Y. +config USB_EHCI_PCI + tristate + depends on USB_EHCI_HCD && PCI + default y + config USB_EHCI_HCD_PMC_MSP tristate "EHCI support for on-chip PMC MSP71xx USB controller" depends on USB_EHCI_HCD && MSP_HAS_USB diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 332ed897a6f..a8390b091c4 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -24,6 +24,8 @@ obj-$(CONFIG_USB_WHCI_HCD) += whci/ obj-$(CONFIG_PCI) += pci-quirks.o obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o +obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o + obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index dee3541bfae..7113d6ad24f 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1252,11 +1252,6 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR (DRIVER_AUTHOR); MODULE_LICENSE ("GPL"); -#ifdef CONFIG_PCI -#include "ehci-pci.c" -#define PCI_DRIVER ehci_pci_driver -#endif - #ifdef CONFIG_USB_EHCI_FSL #include "ehci-fsl.c" #define PLATFORM_DRIVER ehci_fsl_driver @@ -1367,9 +1362,11 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_platform_driver #endif -#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ - !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ - !defined(XILINX_OF_PLATFORM_DRIVER) +#if !IS_ENABLED(CONFIG_USB_EHCI_PCI) && \ + !defined(PLATFORM_DRIVER) && \ + !defined(PS3_SYSTEM_BUS_DRIVER) && \ + !defined(OF_PLATFORM_DRIVER) && \ + !defined(XILINX_OF_PLATFORM_DRIVER) #error "missing bus glue for ehci-hcd" #endif @@ -1406,12 +1403,6 @@ static int __init ehci_hcd_init(void) goto clean0; #endif -#ifdef PCI_DRIVER - retval = pci_register_driver(&PCI_DRIVER); - if (retval < 0) - goto clean1; -#endif - #ifdef PS3_SYSTEM_BUS_DRIVER retval = ps3_ehci_driver_register(&PS3_SYSTEM_BUS_DRIVER); if (retval < 0) @@ -1443,10 +1434,6 @@ clean3: ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); clean2: #endif -#ifdef PCI_DRIVER - pci_unregister_driver(&PCI_DRIVER); -clean1: -#endif #ifdef PLATFORM_DRIVER platform_driver_unregister(&PLATFORM_DRIVER); clean0: @@ -1472,9 +1459,6 @@ static void __exit ehci_hcd_cleanup(void) #ifdef PLATFORM_DRIVER platform_driver_unregister(&PLATFORM_DRIVER); #endif -#ifdef PCI_DRIVER - pci_unregister_driver(&PCI_DRIVER); -#endif #ifdef PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); #endif diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index c92dcaee0d4..46018e97524 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -18,9 +18,18 @@ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef CONFIG_PCI -#error "This file is PCI bus glue. CONFIG_PCI must be defined." -#endif +#include +#include +#include +#include +#include + +#include "ehci.h" +#include "pci-quirks.h" + +#define DRIVER_DESC "EHCI PCI platform driver" + +static const char hcd_name[] = "ehci-pci"; /* defined here to avoid adding to pci_ids.h for single instance use */ #define PCI_DEVICE_ID_INTEL_CE4100_USB 0x2e70 @@ -315,11 +324,6 @@ done: * Also they depend on separate root hub suspend/resume. */ -static int ehci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) -{ - return ehci_suspend(hcd, do_wakeup); -} - static bool usb_is_intel_switchable_ehci(struct pci_dev *pdev) { return pdev->class == PCI_CLASS_SERIAL_USB_EHCI && @@ -370,55 +374,18 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) (void) ehci_pci_reinit(ehci, pdev); return 0; } -#endif - -static const struct hc_driver ehci_pci_hc_driver = { - .description = hcd_name, - .product_desc = "EHCI Host Controller", - .hcd_priv_size = sizeof(struct ehci_hcd), - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - - /* - * basic lifecycle operations - */ - .reset = ehci_pci_setup, - .start = ehci_run, -#ifdef CONFIG_PM - .pci_suspend = ehci_pci_suspend, - .pci_resume = ehci_pci_resume, -#endif - .stop = ehci_stop, - .shutdown = ehci_shutdown, +#else - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, +#define ehci_suspend NULL +#define ehci_pci_resume NULL +#endif /* CONFIG_PM */ - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, +static struct hc_driver __read_mostly ehci_pci_hc_driver; - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, +static const struct ehci_driver_overrides overrides = { + .product_desc = "EHCI PCI host controller", + .reset = ehci_pci_setup, }; /*-------------------------------------------------------------------------*/ @@ -451,3 +418,31 @@ static struct pci_driver ehci_pci_driver = { }, #endif }; + +static int __init ehci_pci_init(void) +{ + if (usb_disabled()) + return -ENODEV; + + pr_info("%s: " DRIVER_DESC "\n", hcd_name); + + ehci_init_driver(&ehci_pci_hc_driver, &overrides); + + /* Entries for the PCI suspend/resume callbacks are special */ + ehci_pci_hc_driver.pci_suspend = ehci_suspend; + ehci_pci_hc_driver.pci_resume = ehci_pci_resume; + + return pci_register_driver(&ehci_pci_driver); +} +module_init(ehci_pci_init); + +static void __exit ehci_pci_cleanup(void) +{ + pci_unregister_driver(&ehci_pci_driver); +} +module_exit(ehci_pci_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("David Brownell"); +MODULE_AUTHOR("Alan Stern"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 99f91934a907df31ba878dfdd090002049dc476a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 1 Nov 2012 11:13:08 -0400 Subject: USB: EHCI: make ehci-platform a separate driver This patch (as1626) splits the ehci-platform code from ehci-hcd out into its own separate driver module. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 2 +- drivers/usb/host/Makefile | 1 + drivers/usb/host/ehci-hcd.c | 6 +--- drivers/usb/host/ehci-platform.c | 66 ++++++++++++++++++++++------------------ 4 files changed, 40 insertions(+), 35 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 10130f47fc7..d6bb128ce21 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -430,7 +430,7 @@ config USB_OHCI_HCD_PLATFORM If unsure, say N. config USB_EHCI_HCD_PLATFORM - bool "Generic EHCI driver for a platform device" + tristate "Generic EHCI driver for a platform device" depends on USB_EHCI_HCD default n ---help--- diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index a8390b091c4..1eb4c3006e9 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_PCI) += pci-quirks.o obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o +obj-$(CONFIG_USB_EHCI_HCD_PLATFORM) += ehci-platform.o obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 7113d6ad24f..4a466d7730c 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1357,12 +1357,8 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_hcd_sead3_driver #endif -#ifdef CONFIG_USB_EHCI_HCD_PLATFORM -#include "ehci-platform.c" -#define PLATFORM_DRIVER ehci_platform_driver -#endif - #if !IS_ENABLED(CONFIG_USB_EHCI_PCI) && \ + !IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \ !defined(PLATFORM_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && \ !defined(OF_PLATFORM_DRIVER) && \ diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 6e6c23bdb48..f97fe3a4d81 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -18,9 +18,19 @@ * * Licensed under the GNU/GPL. See COPYING for details. */ +#include +#include #include +#include +#include #include +#include "ehci.h" + +#define DRIVER_DESC "EHCI generic platform driver" + +static const char hcd_name[] = "ehci-platform"; + static int ehci_platform_reset(struct usb_hcd *hcd) { struct platform_device *pdev = to_platform_device(hcd->self.controller); @@ -43,36 +53,11 @@ static int ehci_platform_reset(struct usb_hcd *hcd) return 0; } -static const struct hc_driver ehci_platform_hc_driver = { - .description = hcd_name, - .product_desc = "Generic Platform EHCI Controller", - .hcd_priv_size = sizeof(struct ehci_hcd), - - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - - .reset = ehci_platform_reset, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, +static struct hc_driver __read_mostly ehci_platform_hc_driver; - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - - .get_frame_number = ehci_get_frame, - - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, -#if defined(CONFIG_PM) - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, -#endif - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, +static const struct ehci_driver_overrides platform_overrides = { + .product_desc = "Generic Platform EHCI controller", + .reset = ehci_platform_reset, }; static int __devinit ehci_platform_probe(struct platform_device *dev) @@ -218,3 +203,26 @@ static struct platform_driver ehci_platform_driver = { .pm = &ehci_platform_pm_ops, } }; + +static int __init ehci_platform_init(void) +{ + if (usb_disabled()) + return -ENODEV; + + pr_info("%s: " DRIVER_DESC "\n", hcd_name); + + ehci_init_driver(&ehci_platform_hc_driver, &platform_overrides); + return platform_driver_register(&ehci_platform_driver); +} +module_init(ehci_platform_init); + +static void __exit ehci_platform_cleanup(void) +{ + platform_driver_unregister(&ehci_platform_driver); +} +module_exit(ehci_platform_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Hauke Mehrtens"); +MODULE_AUTHOR("Alan Stern"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From bb3215e97bb1ab917ed858322a9399fb32e69e49 Mon Sep 17 00:00:00 2001 From: Tekkaman Ninja Date: Sun, 28 Oct 2012 11:17:59 +0800 Subject: Documentation: Fixes a term's translation in Documentation/zh_CN/arm64/memory.txt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a term's translation in Documentation/zh_CN/arm64/memory.txt The modification is based on Catalin Marinas 's suggestion: "memory" in "ffffffc000000000 ffffffffffffffff 256GB memory" should be treated as "kernel logical memory map", so the translation should be "内核逻辑内存映射". Signed-off-by: Fu Wei Signed-off-by: Greg Kroah-Hartman --- Documentation/zh_CN/arm64/memory.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/zh_CN/arm64/memory.txt b/Documentation/zh_CN/arm64/memory.txt index 83b51931470..2a744997d30 100644 --- a/Documentation/zh_CN/arm64/memory.txt +++ b/Documentation/zh_CN/arm64/memory.txt @@ -61,7 +61,7 @@ ffffffbe00000000 ffffffbffbffffff ~8GB [防护页,未来用于 vmmemap] ffffffbffc000000 ffffffbfffffffff 64MB 模块 -ffffffc000000000 ffffffffffffffff 256GB 内存空间 +ffffffc000000000 ffffffffffffffff 256GB 内核逻辑内存映射 4KB 页大小的转换表查找: -- cgit v1.2.3 From b0d0cf77e72a9d233015f8f21e9dfc9d9b5d0711 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 1 Nov 2012 21:17:13 +0200 Subject: mei: mei_write: revamp function flow Use goto statement for error handling instead of deeper if constructs and rename label 'unlock_dev' to more appropriate 'err' Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 88 ++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index ed4943f6b6c..7a03d772fb1 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -543,24 +543,24 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (dev->dev_state != MEI_DEV_ENABLED) { rets = -ENODEV; - goto unlock_dev; + goto err; } i = mei_me_cl_by_id(dev, cl->me_client_id); if (i < 0) { rets = -ENODEV; - goto unlock_dev; + goto err; } if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { rets = -EMSGSIZE; - goto unlock_dev; + goto err; } if (cl->state != MEI_FILE_CONNECTED) { rets = -ENODEV; dev_err(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d", cl->host_client_id, cl->me_client_id); - goto unlock_dev; + goto err; } if (cl == &dev->iamthif_cl) { write_cb = find_amthi_read_list_entry(dev, file); @@ -599,17 +599,17 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (!write_cb) { dev_err(&dev->pdev->dev, "write cb allocation failed\n"); rets = -ENOMEM; - goto unlock_dev; + goto err; } rets = mei_io_cb_alloc_req_buf(write_cb, length); if (rets) - goto unlock_dev; + goto err; dev_dbg(&dev->pdev->dev, "cb request size = %zd\n", length); rets = copy_from_user(write_cb->request_buffer.data, ubuf, length); if (rets) - goto unlock_dev; + goto err; cl->sm_state = 0; if (length == 4 && @@ -624,7 +624,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (cl == &dev->iamthif_cl) { rets = mei_io_cb_alloc_resp_buf(write_cb, dev->iamthif_mtu); if (rets) - goto unlock_dev; + goto err; write_cb->major_file_operations = MEI_IOCTL; @@ -641,7 +641,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (rets) { dev_err(&dev->pdev->dev, "amthi write failed with status = %d\n", rets); - goto unlock_dev; + goto err; } } mutex_unlock(&dev->device_lock); @@ -654,51 +654,51 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, cl->host_client_id, cl->me_client_id); rets = mei_flow_ctrl_creds(dev, cl); if (rets < 0) - goto unlock_dev; + goto err; - if (rets && dev->mei_host_buffer_is_empty) { - rets = 0; - dev->mei_host_buffer_is_empty = false; - if (length > mei_hbuf_max_data(dev)) { - mei_hdr.length = mei_hbuf_max_data(dev); - mei_hdr.msg_complete = 0; - } else { - mei_hdr.length = length; - mei_hdr.msg_complete = 1; - } - mei_hdr.host_addr = cl->host_client_id; - mei_hdr.me_addr = cl->me_client_id; - mei_hdr.reserved = 0; - dev_dbg(&dev->pdev->dev, "call mei_write_message header=%08x.\n", - *((u32 *) &mei_hdr)); - if (mei_write_message(dev, &mei_hdr, - (unsigned char *) (write_cb->request_buffer.data), - mei_hdr.length)) { - rets = -ENODEV; - goto unlock_dev; - } + if (rets == 0 || dev->mei_host_buffer_is_empty == false) { + write_cb->buf_idx = 0; + mei_hdr.msg_complete = 0; cl->writing_state = MEI_WRITING; - write_cb->buf_idx = mei_hdr.length; - if (mei_hdr.msg_complete) { - if (mei_flow_ctrl_reduce(dev, cl)) { - rets = -ENODEV; - goto unlock_dev; - } - list_add_tail(&write_cb->list, &dev->write_waiting_list.list); - } else { - list_add_tail(&write_cb->list, &dev->write_list.list); - } + goto out; + } + dev->mei_host_buffer_is_empty = false; + if (length > mei_hbuf_max_data(dev)) { + mei_hdr.length = mei_hbuf_max_data(dev); + mei_hdr.msg_complete = 0; } else { + mei_hdr.length = length; + mei_hdr.msg_complete = 1; + } + mei_hdr.host_addr = cl->host_client_id; + mei_hdr.me_addr = cl->me_client_id; + mei_hdr.reserved = 0; + dev_dbg(&dev->pdev->dev, "call mei_write_message header=%08x.\n", + *((u32 *) &mei_hdr)); + if (mei_write_message(dev, &mei_hdr, + write_cb->request_buffer.data, mei_hdr.length)) { + rets = -ENODEV; + goto err; + } + cl->writing_state = MEI_WRITING; + write_cb->buf_idx = mei_hdr.length; - write_cb->buf_idx = 0; - cl->writing_state = MEI_WRITING; +out: + if (mei_hdr.msg_complete) { + if (mei_flow_ctrl_reduce(dev, cl)) { + rets = -ENODEV; + goto err; + } + list_add_tail(&write_cb->list, &dev->write_waiting_list.list); + } else { list_add_tail(&write_cb->list, &dev->write_list.list); } + mutex_unlock(&dev->device_lock); return length; -unlock_dev: +err: mutex_unlock(&dev->device_lock); mei_io_cb_free(write_cb); return rets; -- cgit v1.2.3 From 3870c3206b96c900ce29c8068bd5ad46fae71f5b Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 1 Nov 2012 21:17:14 +0200 Subject: mei: normalize timeouts definitions 1. The hardware book defines timeouts in seconds so we stick to this and define the wrapper function mei_secs_to_jiffies around msecs_to_jiffies to use be used instead multiplying by HZ 2. We add name space prefix MEI_ to all timer defines Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw.h | 14 +++++++------- drivers/misc/mei/init.c | 18 +++++++++--------- drivers/misc/mei/interrupt.c | 4 ++-- drivers/misc/mei/iorw.c | 8 ++++---- drivers/misc/mei/main.c | 2 +- drivers/misc/mei/mei_dev.h | 5 +++++ drivers/misc/mei/wd.c | 2 +- 7 files changed, 29 insertions(+), 24 deletions(-) diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h index 9700532f02f..f21721aa4dc 100644 --- a/drivers/misc/mei/hw.h +++ b/drivers/misc/mei/hw.h @@ -20,16 +20,16 @@ #include /* - * Timeouts + * Timeouts in Seconds */ -#define MEI_INTEROP_TIMEOUT (HZ * 7) -#define MEI_CONNECT_TIMEOUT 3 /* at least 2 seconds */ +#define MEI_INTEROP_TIMEOUT 7 /* Timeout on ready message */ +#define MEI_CONNECT_TIMEOUT 3 /* HPS: at least 2 seconds */ -#define CONNECT_TIMEOUT 15 /* HPS definition */ -#define INIT_CLIENTS_TIMEOUT 15 /* HPS definition */ +#define MEI_CL_CONNECT_TIMEOUT 15 /* HPS: Client Connect Timeout */ +#define MEI_CLIENTS_INIT_TIMEOUT 15 /* HPS: Clients Enumeration Timeout */ -#define IAMTHIF_STALL_TIMER 12 /* seconds */ -#define IAMTHIF_READ_TIMER 10000 /* ms */ +#define MEI_IAMTHIF_STALL_TIMER 12 /* HPS */ +#define MEI_IAMTHIF_READ_TIMER 10 /* HPS */ /* * Internal Clients Number diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 1f13eb97a10..e6951ec4840 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -184,7 +184,8 @@ int mei_hw_init(struct mei_device *dev) if (!dev->recvd_msg) { mutex_unlock(&dev->device_lock); err = wait_event_interruptible_timeout(dev->wait_recvd_msg, - dev->recvd_msg, MEI_INTEROP_TIMEOUT); + dev->recvd_msg, + mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT)); mutex_lock(&dev->device_lock); } @@ -381,7 +382,7 @@ void mei_host_start_message(struct mei_device *dev) mei_reset(dev, 1); } dev->init_clients_state = MEI_START_MESSAGE; - dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; + dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; return ; } @@ -414,7 +415,7 @@ void mei_host_enum_clients_message(struct mei_device *dev) mei_reset(dev, 1); } dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE; - dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; + dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; return; } @@ -502,7 +503,7 @@ int mei_host_client_properties(struct mei_device *dev) return -EIO; } - dev->init_clients_timer = INIT_CLIENTS_TIMEOUT; + dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; dev->me_client_index = b; return 1; } @@ -621,7 +622,7 @@ void mei_host_init_iamthif(struct mei_device *dev) dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; dev->iamthif_cl.host_client_id = 0; } else { - dev->iamthif_cl.timer_count = CONNECT_TIMEOUT; + dev->iamthif_cl.timer_count = MEI_CONNECT_TIMEOUT; } } @@ -658,9 +659,8 @@ struct mei_cl *mei_cl_allocate(struct mei_device *dev) */ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) { - int rets, err; - long timeout = 15; /* 15 seconds */ struct mei_cl_cb *cb; + int rets, err; if (!dev || !cl) return -ENODEV; @@ -690,8 +690,8 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) mutex_unlock(&dev->device_lock); err = wait_event_timeout(dev->wait_recvd_msg, - (MEI_FILE_DISCONNECTED == cl->state), - timeout * HZ); + MEI_FILE_DISCONNECTED == cl->state, + mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); mutex_lock(&dev->device_lock); if (MEI_FILE_DISCONNECTED == cl->state) { diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 5c65bac2fde..248f581bde3 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -269,7 +269,7 @@ static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots) dev->iamthif_flow_control_pending = false; dev->iamthif_msg_buf_index = 0; dev->iamthif_msg_buf_size = 0; - dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER; + dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER; dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); return 0; } @@ -1379,7 +1379,7 @@ void mei_timer(struct work_struct *work) if (dev->iamthif_timer) { timeout = dev->iamthif_timer + - msecs_to_jiffies(IAMTHIF_READ_TIMER); + mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER); dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", dev->iamthif_timer); diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index 541c157f325..8026cbf755d 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -173,7 +173,7 @@ int mei_ioctl_connect_client(struct file *file, struct mei_cl *cl; struct mei_cl *cl_pos = NULL; struct mei_cl *cl_next = NULL; - long timeout = CONNECT_TIMEOUT; + long timeout = mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT); int i; int err; int rets; @@ -291,8 +291,7 @@ int mei_ioctl_connect_client(struct file *file, mutex_unlock(&dev->device_lock); err = wait_event_timeout(dev->wait_recvd_msg, (MEI_FILE_CONNECTED == cl->state || - MEI_FILE_DISCONNECTED == cl->state), - timeout * HZ); + MEI_FILE_DISCONNECTED == cl->state), timeout); mutex_lock(&dev->device_lock); if (MEI_FILE_CONNECTED == cl->state) { @@ -415,7 +414,8 @@ int amthi_read(struct mei_device *dev, struct file *file, dev->iamthif_timer = 0; if (cb) { - timeout = cb->read_time + msecs_to_jiffies(IAMTHIF_READ_TIMER); + timeout = cb->read_time + + mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER); dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n", timeout); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 7a03d772fb1..659727a7901 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -567,7 +567,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, if (write_cb) { timeout = write_cb->read_time + - msecs_to_jiffies(IAMTHIF_READ_TIMER); + mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER); if (time_after(jiffies, timeout) || cl->reading_state == MEI_READ_COMPLETE) { diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 6adcb3f6621..32c951ab122 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -270,6 +270,11 @@ struct mei_device { bool iamthif_canceled; }; +static inline unsigned long mei_secs_to_jiffies(unsigned long sec) +{ + return msecs_to_jiffies(sec * MSEC_PER_SEC); +} + /* * mei init function prototypes diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index d96c537f046..8edb054d4b3 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -85,7 +85,7 @@ int mei_wd_host_init(struct mei_device *dev) dev->wd_cl.host_client_id = 0; return -EIO; } - dev->wd_cl.timer_count = CONNECT_TIMEOUT; + dev->wd_cl.timer_count = MEI_CONNECT_TIMEOUT; return 0; } -- cgit v1.2.3 From 19838fb85306905a373b6449c1428791d653fc21 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 1 Nov 2012 21:17:15 +0200 Subject: mei: extract AMTHI functions into the amthif.c file Move AMT Host Interface functions into the new amthif.c file. All functions has now common prefix: mei_amthif_ Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/Makefile | 1 + drivers/misc/mei/amthif.c | 572 +++++++++++++++++++++++++++++++++++++++++++ drivers/misc/mei/init.c | 73 +----- drivers/misc/mei/interrupt.c | 218 +---------------- drivers/misc/mei/iorw.c | 266 -------------------- drivers/misc/mei/main.c | 10 +- drivers/misc/mei/mei_dev.h | 29 ++- 7 files changed, 613 insertions(+), 556 deletions(-) create mode 100644 drivers/misc/mei/amthif.c diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile index 57168db6c7e..0017842e166 100644 --- a/drivers/misc/mei/Makefile +++ b/drivers/misc/mei/Makefile @@ -8,4 +8,5 @@ mei-objs += interrupt.o mei-objs += interface.o mei-objs += iorw.o mei-objs += main.o +mei-objs += amthif.o mei-objs += wd.o diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c new file mode 100644 index 00000000000..392203d8d25 --- /dev/null +++ b/drivers/misc/mei/amthif.c @@ -0,0 +1,572 @@ +/* + * + * Intel Management Engine Interface (Intel MEI) Linux driver + * Copyright (c) 2003-2012, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "mei_dev.h" +#include "hw.h" +#include +#include "interface.h" + +const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, + 0xa8, 0x46, 0xe0, 0xff, 0x65, + 0x81, 0x4c); + +/** + * mei_amthif_reset_params - initializes mei device iamthif + * + * @dev: the device structure + */ +void mei_amthif_reset_params(struct mei_device *dev) +{ + /* reset iamthif parameters. */ + dev->iamthif_current_cb = NULL; + dev->iamthif_msg_buf_size = 0; + dev->iamthif_msg_buf_index = 0; + dev->iamthif_canceled = false; + dev->iamthif_ioctl = false; + dev->iamthif_state = MEI_IAMTHIF_IDLE; + dev->iamthif_timer = 0; +} + +/** + * mei_amthif_host_init_ - mei initialization amthif client. + * + * @dev: the device structure + * + */ +void mei_amthif_host_init(struct mei_device *dev) +{ + int i; + unsigned char *msg_buf; + + mei_cl_init(&dev->iamthif_cl, dev); + dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; + + /* find ME amthi client */ + i = mei_me_cl_update_filext(dev, &dev->iamthif_cl, + &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID); + if (i < 0) { + dev_dbg(&dev->pdev->dev, "failed to find iamthif client.\n"); + return; + } + + /* Assign iamthif_mtu to the value received from ME */ + + dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length; + dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n", + dev->me_clients[i].props.max_msg_length); + + kfree(dev->iamthif_msg_buf); + dev->iamthif_msg_buf = NULL; + + /* allocate storage for ME message buffer */ + msg_buf = kcalloc(dev->iamthif_mtu, + sizeof(unsigned char), GFP_KERNEL); + if (!msg_buf) { + dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n"); + return; + } + + dev->iamthif_msg_buf = msg_buf; + + if (mei_connect(dev, &dev->iamthif_cl)) { + dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n"); + dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; + dev->iamthif_cl.host_client_id = 0; + } else { + dev->iamthif_cl.timer_count = MEI_CONNECT_TIMEOUT; + } +} + +/** + * mei_amthif_find_read_list_entry - finds a amthilist entry for current file + * + * @dev: the device structure + * @file: pointer to file object + * + * returns returned a list entry on success, NULL on failure. + */ +struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, + struct file *file) +{ + struct mei_cl *cl_temp; + struct mei_cl_cb *pos = NULL; + struct mei_cl_cb *next = NULL; + + list_for_each_entry_safe(pos, next, + &dev->amthi_read_complete_list.list, list) { + cl_temp = (struct mei_cl *)pos->file_private; + if (cl_temp && cl_temp == &dev->iamthif_cl && + pos->file_object == file) + return pos; + } + return NULL; +} + + +/** + * mei_amthif_read - read data from AMTHIF client + * + * @dev: the device structure + * @if_num: minor number + * @file: pointer to file object + * @*ubuf: pointer to user data in user space + * @length: data length to read + * @offset: data read offset + * + * Locking: called under "dev->device_lock" lock + * + * returns + * returned data length on success, + * zero if no data to read, + * negative on failure. + */ +int mei_amthif_read(struct mei_device *dev, struct file *file, + char __user *ubuf, size_t length, loff_t *offset) +{ + int rets; + int wait_ret; + struct mei_cl_cb *cb = NULL; + struct mei_cl *cl = file->private_data; + unsigned long timeout; + int i; + + /* Only Posible if we are in timeout */ + if (!cl || cl != &dev->iamthif_cl) { + dev_dbg(&dev->pdev->dev, "bad file ext.\n"); + return -ETIMEDOUT; + } + + i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id); + + if (i < 0) { + dev_dbg(&dev->pdev->dev, "amthi client not found.\n"); + return -ENODEV; + } + dev_dbg(&dev->pdev->dev, "checking amthi data\n"); + cb = mei_amthif_find_read_list_entry(dev, file); + + /* Check for if we can block or not*/ + if (cb == NULL && file->f_flags & O_NONBLOCK) + return -EAGAIN; + + + dev_dbg(&dev->pdev->dev, "waiting for amthi data\n"); + while (cb == NULL) { + /* unlock the Mutex */ + mutex_unlock(&dev->device_lock); + + wait_ret = wait_event_interruptible(dev->iamthif_cl.wait, + (cb = mei_amthif_find_read_list_entry(dev, file))); + + if (wait_ret) + return -ERESTARTSYS; + + dev_dbg(&dev->pdev->dev, "woke up from sleep\n"); + + /* Locking again the Mutex */ + mutex_lock(&dev->device_lock); + } + + + dev_dbg(&dev->pdev->dev, "Got amthi data\n"); + dev->iamthif_timer = 0; + + if (cb) { + timeout = cb->read_time + + mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER); + dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n", + timeout); + + if (time_after(jiffies, timeout)) { + dev_dbg(&dev->pdev->dev, "amthi Time out\n"); + /* 15 sec for the message has expired */ + list_del(&cb->list); + rets = -ETIMEDOUT; + goto free; + } + } + /* if the whole message will fit remove it from the list */ + if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset)) + list_del(&cb->list); + else if (cb->buf_idx > 0 && cb->buf_idx <= *offset) { + /* end of the message has been reached */ + list_del(&cb->list); + rets = 0; + goto free; + } + /* else means that not full buffer will be read and do not + * remove message from deletion list + */ + + dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n", + cb->response_buffer.size); + dev_dbg(&dev->pdev->dev, "amthi cb->buf_idx - %lu\n", cb->buf_idx); + + /* length is being turncated to PAGE_SIZE, however, + * the buf_idx may point beyond */ + length = min_t(size_t, length, (cb->buf_idx - *offset)); + + if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) + rets = -EFAULT; + else { + rets = length; + if ((*offset + length) < cb->buf_idx) { + *offset += length; + goto out; + } + } +free: + dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n"); + *offset = 0; + mei_io_cb_free(cb); +out: + return rets; +} + +/** + * mei_amthif_write - write amthif data to amthif client + * + * @dev: the device structure + * @cb: mei call back struct + * + * returns 0 on success, <0 on failure. + */ +int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) +{ + struct mei_msg_hdr mei_hdr; + int ret; + + if (!dev || !cb) + return -ENODEV; + + dev_dbg(&dev->pdev->dev, "write data to amthi client.\n"); + + dev->iamthif_state = MEI_IAMTHIF_WRITING; + dev->iamthif_current_cb = cb; + dev->iamthif_file_object = cb->file_object; + dev->iamthif_canceled = false; + dev->iamthif_ioctl = true; + dev->iamthif_msg_buf_size = cb->request_buffer.size; + memcpy(dev->iamthif_msg_buf, cb->request_buffer.data, + cb->request_buffer.size); + + ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl); + if (ret < 0) + return ret; + + if (ret && dev->mei_host_buffer_is_empty) { + ret = 0; + dev->mei_host_buffer_is_empty = false; + if (cb->request_buffer.size > mei_hbuf_max_data(dev)) { + mei_hdr.length = mei_hbuf_max_data(dev); + mei_hdr.msg_complete = 0; + } else { + mei_hdr.length = cb->request_buffer.size; + mei_hdr.msg_complete = 1; + } + + mei_hdr.host_addr = dev->iamthif_cl.host_client_id; + mei_hdr.me_addr = dev->iamthif_cl.me_client_id; + mei_hdr.reserved = 0; + dev->iamthif_msg_buf_index += mei_hdr.length; + if (mei_write_message(dev, &mei_hdr, + (unsigned char *)(dev->iamthif_msg_buf), + mei_hdr.length)) + return -ENODEV; + + if (mei_hdr.msg_complete) { + if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl)) + return -ENODEV; + dev->iamthif_flow_control_pending = true; + dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; + dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n"); + dev->iamthif_current_cb = cb; + dev->iamthif_file_object = cb->file_object; + list_add_tail(&cb->list, &dev->write_waiting_list.list); + } else { + dev_dbg(&dev->pdev->dev, "message does not complete, so add amthi cb to write list.\n"); + list_add_tail(&cb->list, &dev->write_list.list); + } + } else { + if (!(dev->mei_host_buffer_is_empty)) + dev_dbg(&dev->pdev->dev, "host buffer is not empty"); + + dev_dbg(&dev->pdev->dev, "No flow control credentials, so add iamthif cb to write list.\n"); + list_add_tail(&cb->list, &dev->write_list.list); + } + return 0; +} + +/** + * mei_amthif_run_next_cmd + * + * @dev: the device structure + * + * returns 0 on success, <0 on failure. + */ +void mei_amthif_run_next_cmd(struct mei_device *dev) +{ + struct mei_cl *cl_tmp; + struct mei_cl_cb *pos = NULL; + struct mei_cl_cb *next = NULL; + int status; + + if (!dev) + return; + + dev->iamthif_msg_buf_size = 0; + dev->iamthif_msg_buf_index = 0; + dev->iamthif_canceled = false; + dev->iamthif_ioctl = true; + dev->iamthif_state = MEI_IAMTHIF_IDLE; + dev->iamthif_timer = 0; + dev->iamthif_file_object = NULL; + + dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n"); + + list_for_each_entry_safe(pos, next, &dev->amthi_cmd_list.list, list) { + list_del(&pos->list); + cl_tmp = (struct mei_cl *)pos->file_private; + + if (cl_tmp && cl_tmp == &dev->iamthif_cl) { + status = mei_amthif_write(dev, pos); + if (status) { + dev_dbg(&dev->pdev->dev, + "amthi write failed status = %d\n", + status); + return; + } + break; + } + } +} + +/** + * mei_amthif_irq_process_completed - processes completed iamthif operation. + * + * @dev: the device structure. + * @slots: free slots. + * @cb_pos: callback block. + * @cl: private data of the file object. + * @cmpl_list: complete list. + * + * returns 0, OK; otherwise, error. + */ +int mei_amthif_irq_process_completed(struct mei_device *dev, s32 *slots, + struct mei_cl_cb *cb_pos, + struct mei_cl *cl, + struct mei_cl_cb *cmpl_list) +{ + struct mei_msg_hdr *mei_hdr; + + if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + + dev->iamthif_msg_buf_size - + dev->iamthif_msg_buf_index)) { + mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + mei_hdr->host_addr = cl->host_client_id; + mei_hdr->me_addr = cl->me_client_id; + mei_hdr->length = dev->iamthif_msg_buf_size - + dev->iamthif_msg_buf_index; + mei_hdr->msg_complete = 1; + mei_hdr->reserved = 0; + + *slots -= mei_data2slots(mei_hdr->length); + + if (mei_write_message(dev, mei_hdr, + (dev->iamthif_msg_buf + + dev->iamthif_msg_buf_index), + mei_hdr->length)) { + dev->iamthif_state = MEI_IAMTHIF_IDLE; + cl->status = -ENODEV; + list_del(&cb_pos->list); + return -ENODEV; + } else { + if (mei_flow_ctrl_reduce(dev, cl)) + return -ENODEV; + dev->iamthif_msg_buf_index += mei_hdr->length; + cb_pos->buf_idx = dev->iamthif_msg_buf_index; + cl->status = 0; + dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; + dev->iamthif_flow_control_pending = true; + /* save iamthif cb sent to amthi client */ + dev->iamthif_current_cb = cb_pos; + list_move_tail(&cb_pos->list, + &dev->write_waiting_list.list); + + } + } else if (*slots == dev->hbuf_depth) { + /* buffer is still empty */ + mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + mei_hdr->host_addr = cl->host_client_id; + mei_hdr->me_addr = cl->me_client_id; + mei_hdr->length = + (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); + mei_hdr->msg_complete = 0; + mei_hdr->reserved = 0; + + *slots -= mei_data2slots(mei_hdr->length); + + if (mei_write_message(dev, mei_hdr, + (dev->iamthif_msg_buf + + dev->iamthif_msg_buf_index), + mei_hdr->length)) { + cl->status = -ENODEV; + list_del(&cb_pos->list); + } else { + dev->iamthif_msg_buf_index += mei_hdr->length; + } + return -EMSGSIZE; + } else { + return -EBADMSG; + } + + return 0; +} + +/** + * mei_amthif_irq_read_message - read routine after ISR to + * handle the read amthi message + * + * @complete_list: An instance of our list structure + * @dev: the device structure + * @mei_hdr: header of amthi message + * + * returns 0 on success, <0 on failure. + */ +int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list, + struct mei_device *dev, struct mei_msg_hdr *mei_hdr) +{ + struct mei_cl *cl; + struct mei_cl_cb *cb; + unsigned char *buffer; + + BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id); + BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING); + + buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index; + BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length); + + mei_read_slots(dev, buffer, mei_hdr->length); + + dev->iamthif_msg_buf_index += mei_hdr->length; + + if (!mei_hdr->msg_complete) + return 0; + + dev_dbg(&dev->pdev->dev, + "amthi_message_buffer_index =%d\n", + mei_hdr->length); + + dev_dbg(&dev->pdev->dev, "completed amthi read.\n "); + if (!dev->iamthif_current_cb) + return -ENODEV; + + cb = dev->iamthif_current_cb; + dev->iamthif_current_cb = NULL; + + cl = (struct mei_cl *)cb->file_private; + if (!cl) + return -ENODEV; + + dev->iamthif_stall_timer = 0; + cb->buf_idx = dev->iamthif_msg_buf_index; + cb->read_time = jiffies; + if (dev->iamthif_ioctl && cl == &dev->iamthif_cl) { + /* found the iamthif cb */ + dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n "); + dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n "); + list_add_tail(&cb->list, &complete_list->list); + } + return 0; +} + +/** + * mei_amthif_irq_read - prepares to read amthif data. + * + * @dev: the device structure. + * @slots: free slots. + * + * returns 0, OK; otherwise, error. + */ +int mei_amthif_irq_read(struct mei_device *dev, s32 *slots) +{ + + if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + + sizeof(struct hbm_flow_control))) { + return -EMSGSIZE; + } + *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); + if (mei_send_flow_control(dev, &dev->iamthif_cl)) { + dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); + return -EIO; + } + + dev_dbg(&dev->pdev->dev, "iamthif flow control success\n"); + dev->iamthif_state = MEI_IAMTHIF_READING; + dev->iamthif_flow_control_pending = false; + dev->iamthif_msg_buf_index = 0; + dev->iamthif_msg_buf_size = 0; + dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER; + dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); + return 0; +} + +/** + * mei_amthif_complete - complete amthif callback. + * + * @dev: the device structure. + * @cb_pos: callback block. + */ +void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb) +{ + if (dev->iamthif_canceled != 1) { + dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE; + dev->iamthif_stall_timer = 0; + memcpy(cb->response_buffer.data, + dev->iamthif_msg_buf, + dev->iamthif_msg_buf_index); + list_add_tail(&cb->list, &dev->amthi_read_complete_list.list); + dev_dbg(&dev->pdev->dev, "amthi read completed\n"); + dev->iamthif_timer = jiffies; + dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", + dev->iamthif_timer); + } else { + mei_amthif_run_next_cmd(dev); + } + + dev_dbg(&dev->pdev->dev, "completing amthi call back.\n"); + wake_up_interruptible(&dev->iamthif_cl.wait); +} + + diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index e6951ec4840..4a8eb920f7f 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -43,10 +43,6 @@ const char *mei_dev_state_str(int state) } -const uuid_le mei_amthi_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac, - 0xa8, 0x46, 0xe0, 0xff, 0x65, - 0x81, 0x4c); - /** * mei_io_list_flush - removes list entry belonging to cl. * @@ -91,23 +87,6 @@ int mei_cl_flush_queues(struct mei_cl *cl) -/** - * mei_reset_iamthif_params - initializes mei device iamthif - * - * @dev: the device structure - */ -static void mei_reset_iamthif_params(struct mei_device *dev) -{ - /* reset iamthif parameters. */ - dev->iamthif_current_cb = NULL; - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = false; - dev->iamthif_ioctl = false; - dev->iamthif_state = MEI_IAMTHIF_IDLE; - dev->iamthif_timer = 0; -} - /** * init_mei_device - allocates and initializes the mei device structure * @@ -313,7 +292,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) mei_remove_client_from_file_list(dev, dev->iamthif_cl.host_client_id); - mei_reset_iamthif_params(dev); + mei_amthif_reset_params(dev); dev->extra_write_index = 0; } @@ -576,56 +555,6 @@ int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl, return -ENOENT; } -/** - * host_init_iamthif - mei initialization iamthif client. - * - * @dev: the device structure - * - */ -void mei_host_init_iamthif(struct mei_device *dev) -{ - int i; - unsigned char *msg_buf; - - mei_cl_init(&dev->iamthif_cl, dev); - dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; - - /* find ME amthi client */ - i = mei_me_cl_update_filext(dev, &dev->iamthif_cl, - &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID); - if (i < 0) { - dev_dbg(&dev->pdev->dev, "failed to find iamthif client.\n"); - return; - } - - /* Assign iamthif_mtu to the value received from ME */ - - dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length; - dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n", - dev->me_clients[i].props.max_msg_length); - - kfree(dev->iamthif_msg_buf); - dev->iamthif_msg_buf = NULL; - - /* allocate storage for ME message buffer */ - msg_buf = kcalloc(dev->iamthif_mtu, - sizeof(unsigned char), GFP_KERNEL); - if (!msg_buf) { - dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n"); - return; - } - - dev->iamthif_msg_buf = msg_buf; - - if (mei_connect(dev, &dev->iamthif_cl)) { - dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n"); - dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; - dev->iamthif_cl.host_client_id = 0; - } else { - dev->iamthif_cl.timer_count = MEI_CONNECT_TIMEOUT; - } -} - /** * mei_alloc_file_private - allocates a private file structure and sets it up. * @file: the file structure diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 248f581bde3..62f8b65fd11 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -73,92 +73,6 @@ static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos) } } -/** - * _mei_cmpl_iamthif - processes completed iamthif operation. - * - * @dev: the device structure. - * @cb_pos: callback block. - */ -static void _mei_cmpl_iamthif(struct mei_device *dev, struct mei_cl_cb *cb_pos) -{ - if (dev->iamthif_canceled != 1) { - dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE; - dev->iamthif_stall_timer = 0; - memcpy(cb_pos->response_buffer.data, - dev->iamthif_msg_buf, - dev->iamthif_msg_buf_index); - list_add_tail(&cb_pos->list, &dev->amthi_read_complete_list.list); - dev_dbg(&dev->pdev->dev, "amthi read completed\n"); - dev->iamthif_timer = jiffies; - dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", - dev->iamthif_timer); - } else { - mei_run_next_iamthif_cmd(dev); - } - - dev_dbg(&dev->pdev->dev, "completing amthi call back.\n"); - wake_up_interruptible(&dev->iamthif_cl.wait); -} - - -/** - * mei_irq_thread_read_amthi_message - bottom half read routine after ISR to - * handle the read amthi message data processing. - * - * @complete_list: An instance of our list structure - * @dev: the device structure - * @mei_hdr: header of amthi message - * - * returns 0 on success, <0 on failure. - */ -static int mei_irq_thread_read_amthi_message(struct mei_cl_cb *complete_list, - struct mei_device *dev, - struct mei_msg_hdr *mei_hdr) -{ - struct mei_cl *cl; - struct mei_cl_cb *cb; - unsigned char *buffer; - - BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id); - BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING); - - buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index; - BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length); - - mei_read_slots(dev, buffer, mei_hdr->length); - - dev->iamthif_msg_buf_index += mei_hdr->length; - - if (!mei_hdr->msg_complete) - return 0; - - dev_dbg(&dev->pdev->dev, - "amthi_message_buffer_index =%d\n", - mei_hdr->length); - - dev_dbg(&dev->pdev->dev, "completed amthi read.\n "); - if (!dev->iamthif_current_cb) - return -ENODEV; - - cb = dev->iamthif_current_cb; - dev->iamthif_current_cb = NULL; - - cl = (struct mei_cl *)cb->file_private; - if (!cl) - return -ENODEV; - - dev->iamthif_stall_timer = 0; - cb->buf_idx = dev->iamthif_msg_buf_index; - cb->read_time = jiffies; - if (dev->iamthif_ioctl && cl == &dev->iamthif_cl) { - /* found the iamthif cb */ - dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n "); - dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n "); - list_add_tail(&cb->list, &complete_list->list); - } - return 0; -} - /** * _mei_irq_thread_state_ok - checks if mei header matches file private data * @@ -243,37 +157,6 @@ quit: return 0; } -/** - * _mei_irq_thread_iamthif_read - prepares to read iamthif data. - * - * @dev: the device structure. - * @slots: free slots. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots) -{ - - if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr) - + sizeof(struct hbm_flow_control))) { - return -EMSGSIZE; - } - *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); - if (mei_send_flow_control(dev, &dev->iamthif_cl)) { - dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); - return -EIO; - } - - dev_dbg(&dev->pdev->dev, "iamthif flow control success\n"); - dev->iamthif_state = MEI_IAMTHIF_READING; - dev->iamthif_flow_control_pending = false; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_msg_buf_size = 0; - dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER; - dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev); - return 0; -} - /** * _mei_irq_thread_close - processes close related operation. * @@ -370,7 +253,7 @@ static void mei_client_connect_response(struct mei_device *dev, mei_watchdog_register(dev); /* next step in the state maching */ - mei_host_init_iamthif(dev); + mei_amthif_host_init(dev); return; } @@ -728,7 +611,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, * will be received */ if (mei_wd_host_init(dev)) - mei_host_init_iamthif(dev); + mei_amthif_host_init(dev); } } else { @@ -963,87 +846,6 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, return 0; } -/** - * _mei_irq_thread_cmpl_iamthif - processes completed iamthif operation. - * - * @dev: the device structure. - * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. - * @cmpl_list: complete list. - * - * returns 0, OK; otherwise, error. - */ -static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_cl_cb *cmpl_list) -{ - struct mei_msg_hdr *mei_hdr; - - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - dev->iamthif_msg_buf_size - - dev->iamthif_msg_buf_index)) { - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = dev->iamthif_msg_buf_size - - dev->iamthif_msg_buf_index; - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - *slots -= mei_data2slots(mei_hdr->length); - - if (mei_write_message(dev, mei_hdr, - (dev->iamthif_msg_buf + - dev->iamthif_msg_buf_index), - mei_hdr->length)) { - dev->iamthif_state = MEI_IAMTHIF_IDLE; - cl->status = -ENODEV; - list_del(&cb_pos->list); - return -ENODEV; - } else { - if (mei_flow_ctrl_reduce(dev, cl)) - return -ENODEV; - dev->iamthif_msg_buf_index += mei_hdr->length; - cb_pos->buf_idx = dev->iamthif_msg_buf_index; - cl->status = 0; - dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; - dev->iamthif_flow_control_pending = true; - /* save iamthif cb sent to amthi client */ - dev->iamthif_current_cb = cb_pos; - list_move_tail(&cb_pos->list, &dev->write_waiting_list.list); - - } - } else if (*slots == dev->hbuf_depth) { - /* buffer is still empty */ - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = - (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); - mei_hdr->msg_complete = 0; - mei_hdr->reserved = 0; - - *slots -= mei_data2slots(mei_hdr->length); - - if (mei_write_message(dev, mei_hdr, - (dev->iamthif_msg_buf + - dev->iamthif_msg_buf_index), - mei_hdr->length)) { - cl->status = -ENODEV; - list_del(&cb_pos->list); - } else { - dev->iamthif_msg_buf_index += mei_hdr->length; - } - return -EMSGSIZE; - } else { - return -EBADMSG; - } - - return 0; -} - /** * mei_irq_thread_read_handler - bottom half read routine after ISR to * handle the read processing. @@ -1117,8 +919,8 @@ static int mei_irq_thread_read_handler(struct mei_cl_cb *cmpl_list, dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n"); dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length); - ret = mei_irq_thread_read_amthi_message(cmpl_list, - dev, mei_hdr); + + ret = mei_amthif_irq_read_message(cmpl_list, dev, mei_hdr); if (ret) goto end; @@ -1195,7 +997,7 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, if (cl == &dev->iamthif_cl) { dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n"); if (dev->iamthif_flow_control_pending) { - ret = _mei_irq_thread_iamthif_read(dev, slots); + ret = mei_amthif_irq_read(dev, slots); if (ret) return ret; } @@ -1300,8 +1102,8 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, cl->host_client_id); continue; } - ret = _mei_irq_thread_cmpl_iamthif(dev, slots, pos, - cl, cmpl_list); + ret = mei_amthif_irq_process_completed(dev, slots, pos, + cl, cmpl_list); if (ret) return ret; @@ -1372,7 +1174,7 @@ void mei_timer(struct work_struct *work) dev->iamthif_current_cb = NULL; dev->iamthif_file_object = NULL; - mei_run_next_iamthif_cmd(dev); + mei_amthif_run_next_cmd(dev); } } @@ -1409,7 +1211,7 @@ void mei_timer(struct work_struct *work) dev->iamthif_file_object->private_data = NULL; dev->iamthif_file_object = NULL; dev->iamthif_timer = 0; - mei_run_next_iamthif_cmd(dev); + mei_amthif_run_next_cmd(dev); } } @@ -1524,7 +1326,7 @@ end: _mei_cmpl(cl, cb_pos); cb_pos = NULL; } else if (cl == &dev->iamthif_cl) { - _mei_cmpl_iamthif(dev, cb_pos); + mei_amthif_complete(dev, cb_pos); } } } diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index 8026cbf755d..a1d9ba1a06e 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -319,152 +319,6 @@ end: return rets; } -/** - * find_amthi_read_list_entry - finds a amthilist entry for current file - * - * @dev: the device structure - * @file: pointer to file object - * - * returns returned a list entry on success, NULL on failure. - */ -struct mei_cl_cb *find_amthi_read_list_entry( - struct mei_device *dev, - struct file *file) -{ - struct mei_cl *cl_temp; - struct mei_cl_cb *pos = NULL; - struct mei_cl_cb *next = NULL; - - list_for_each_entry_safe(pos, next, - &dev->amthi_read_complete_list.list, list) { - cl_temp = (struct mei_cl *)pos->file_private; - if (cl_temp && cl_temp == &dev->iamthif_cl && - pos->file_object == file) - return pos; - } - return NULL; -} - -/** - * amthi_read - read data from AMTHI client - * - * @dev: the device structure - * @if_num: minor number - * @file: pointer to file object - * @*ubuf: pointer to user data in user space - * @length: data length to read - * @offset: data read offset - * - * Locking: called under "dev->device_lock" lock - * - * returns - * returned data length on success, - * zero if no data to read, - * negative on failure. - */ -int amthi_read(struct mei_device *dev, struct file *file, - char __user *ubuf, size_t length, loff_t *offset) -{ - int rets; - int wait_ret; - struct mei_cl_cb *cb = NULL; - struct mei_cl *cl = file->private_data; - unsigned long timeout; - int i; - - /* Only Posible if we are in timeout */ - if (!cl || cl != &dev->iamthif_cl) { - dev_dbg(&dev->pdev->dev, "bad file ext.\n"); - return -ETIMEDOUT; - } - - i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id); - - if (i < 0) { - dev_dbg(&dev->pdev->dev, "amthi client not found.\n"); - return -ENODEV; - } - dev_dbg(&dev->pdev->dev, "checking amthi data\n"); - cb = find_amthi_read_list_entry(dev, file); - - /* Check for if we can block or not*/ - if (cb == NULL && file->f_flags & O_NONBLOCK) - return -EAGAIN; - - - dev_dbg(&dev->pdev->dev, "waiting for amthi data\n"); - while (cb == NULL) { - /* unlock the Mutex */ - mutex_unlock(&dev->device_lock); - - wait_ret = wait_event_interruptible(dev->iamthif_cl.wait, - (cb = find_amthi_read_list_entry(dev, file))); - - if (wait_ret) - return -ERESTARTSYS; - - dev_dbg(&dev->pdev->dev, "woke up from sleep\n"); - - /* Locking again the Mutex */ - mutex_lock(&dev->device_lock); - } - - - dev_dbg(&dev->pdev->dev, "Got amthi data\n"); - dev->iamthif_timer = 0; - - if (cb) { - timeout = cb->read_time + - mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER); - dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n", - timeout); - - if (time_after(jiffies, timeout)) { - dev_dbg(&dev->pdev->dev, "amthi Time out\n"); - /* 15 sec for the message has expired */ - list_del(&cb->list); - rets = -ETIMEDOUT; - goto free; - } - } - /* if the whole message will fit remove it from the list */ - if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset)) - list_del(&cb->list); - else if (cb->buf_idx > 0 && cb->buf_idx <= *offset) { - /* end of the message has been reached */ - list_del(&cb->list); - rets = 0; - goto free; - } - /* else means that not full buffer will be read and do not - * remove message from deletion list - */ - - dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n", - cb->response_buffer.size); - dev_dbg(&dev->pdev->dev, "amthi cb->buf_idx - %lu\n", cb->buf_idx); - - /* length is being turncated to PAGE_SIZE, however, - * the buf_idx may point beyond */ - length = min_t(size_t, length, (cb->buf_idx - *offset)); - - if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) - rets = -EFAULT; - else { - rets = length; - if ((*offset + length) < cb->buf_idx) { - *offset += length; - goto out; - } - } -free: - dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n"); - *offset = 0; - mei_io_cb_free(cb); -out: - return rets; -} - /** * mei_start_read - the start read client message function. * @@ -524,123 +378,3 @@ err: return rets; } -/** - * amthi_write - write iamthif data to amthi client - * - * @dev: the device structure - * @cb: mei call back struct - * - * returns 0 on success, <0 on failure. - */ -int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb) -{ - struct mei_msg_hdr mei_hdr; - int ret; - - if (!dev || !cb) - return -ENODEV; - - dev_dbg(&dev->pdev->dev, "write data to amthi client.\n"); - - dev->iamthif_state = MEI_IAMTHIF_WRITING; - dev->iamthif_current_cb = cb; - dev->iamthif_file_object = cb->file_object; - dev->iamthif_canceled = false; - dev->iamthif_ioctl = true; - dev->iamthif_msg_buf_size = cb->request_buffer.size; - memcpy(dev->iamthif_msg_buf, cb->request_buffer.data, - cb->request_buffer.size); - - ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl); - if (ret < 0) - return ret; - - if (ret && dev->mei_host_buffer_is_empty) { - ret = 0; - dev->mei_host_buffer_is_empty = false; - if (cb->request_buffer.size > mei_hbuf_max_data(dev)) { - mei_hdr.length = mei_hbuf_max_data(dev); - mei_hdr.msg_complete = 0; - } else { - mei_hdr.length = cb->request_buffer.size; - mei_hdr.msg_complete = 1; - } - - mei_hdr.host_addr = dev->iamthif_cl.host_client_id; - mei_hdr.me_addr = dev->iamthif_cl.me_client_id; - mei_hdr.reserved = 0; - dev->iamthif_msg_buf_index += mei_hdr.length; - if (mei_write_message(dev, &mei_hdr, - (unsigned char *)(dev->iamthif_msg_buf), - mei_hdr.length)) - return -ENODEV; - - if (mei_hdr.msg_complete) { - if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl)) - return -ENODEV; - dev->iamthif_flow_control_pending = true; - dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; - dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n"); - dev->iamthif_current_cb = cb; - dev->iamthif_file_object = cb->file_object; - list_add_tail(&cb->list, &dev->write_waiting_list.list); - } else { - dev_dbg(&dev->pdev->dev, "message does not complete, " - "so add amthi cb to write list.\n"); - list_add_tail(&cb->list, &dev->write_list.list); - } - } else { - if (!(dev->mei_host_buffer_is_empty)) - dev_dbg(&dev->pdev->dev, "host buffer is not empty"); - - dev_dbg(&dev->pdev->dev, "No flow control credentials, " - "so add iamthif cb to write list.\n"); - list_add_tail(&cb->list, &dev->write_list.list); - } - return 0; -} - -/** - * iamthif_ioctl_send_msg - send cmd data to amthi client - * - * @dev: the device structure - * - * returns 0 on success, <0 on failure. - */ -void mei_run_next_iamthif_cmd(struct mei_device *dev) -{ - struct mei_cl *cl_tmp; - struct mei_cl_cb *pos = NULL; - struct mei_cl_cb *next = NULL; - int status; - - if (!dev) - return; - - dev->iamthif_msg_buf_size = 0; - dev->iamthif_msg_buf_index = 0; - dev->iamthif_canceled = false; - dev->iamthif_ioctl = true; - dev->iamthif_state = MEI_IAMTHIF_IDLE; - dev->iamthif_timer = 0; - dev->iamthif_file_object = NULL; - - dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n"); - - list_for_each_entry_safe(pos, next, &dev->amthi_cmd_list.list, list) { - list_del(&pos->list); - cl_tmp = (struct mei_cl *)pos->file_private; - - if (cl_tmp && cl_tmp == &dev->iamthif_cl) { - status = amthi_write(dev, pos); - if (status) { - dev_dbg(&dev->pdev->dev, - "amthi write failed status = %d\n", - status); - return; - } - break; - } - } -} - diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 659727a7901..f69e0856f98 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -349,7 +349,7 @@ static int mei_release(struct inode *inode, struct file *file) dev->iamthif_canceled = true; if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) { dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n"); - mei_run_next_iamthif_cmd(dev); + mei_amthif_run_next_cmd(dev); } } @@ -410,7 +410,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf, } if (cl == &dev->iamthif_cl) { - rets = amthi_read(dev, file, ubuf, length, offset); + rets = mei_amthif_read(dev, file, ubuf, length, offset); goto out; } @@ -563,7 +563,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, goto err; } if (cl == &dev->iamthif_cl) { - write_cb = find_amthi_read_list_entry(dev, file); + write_cb = mei_amthif_find_read_list_entry(dev, file); if (write_cb) { timeout = write_cb->read_time + @@ -636,7 +636,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, list_add_tail(&write_cb->list, &dev->amthi_cmd_list.list); } else { dev_dbg(&dev->pdev->dev, "call amthi write\n"); - rets = amthi_write(dev, write_cb); + rets = mei_amthif_write(dev, write_cb); if (rets) { dev_err(&dev->pdev->dev, "amthi write failed with status = %d\n", @@ -823,7 +823,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait) dev->iamthif_file_object == file) { mask |= (POLLIN | POLLRDNORM); dev_dbg(&dev->pdev->dev, "run next amthi cb\n"); - mei_run_next_iamthif_cmd(dev); + mei_amthif_run_next_cmd(dev); } goto out; } diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 32c951ab122..57a5a4e4ee4 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -286,7 +286,6 @@ int mei_task_initialize_clients(void *data); int mei_initialize_clients(struct mei_device *dev); int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl); void mei_remove_client_from_file_list(struct mei_device *dev, u8 host_client_id); -void mei_host_init_iamthif(struct mei_device *dev); void mei_allocate_me_clients_storage(struct mei_device *dev); @@ -362,17 +361,37 @@ int mei_ioctl_connect_client(struct file *file, int mei_start_read(struct mei_device *dev, struct mei_cl *cl); -int amthi_write(struct mei_device *dev, struct mei_cl_cb *priv_cb); -int amthi_read(struct mei_device *dev, struct file *file, +/* + * AMTHIF - AMT Host Interface Functions + */ +void mei_amthif_reset_params(struct mei_device *dev); + +void mei_amthif_host_init(struct mei_device *dev); + +int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb); + +int mei_amthif_read(struct mei_device *dev, struct file *file, char __user *ubuf, size_t length, loff_t *offset); -struct mei_cl_cb *find_amthi_read_list_entry(struct mei_device *dev, +struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, struct file *file); -void mei_run_next_iamthif_cmd(struct mei_device *dev); +void mei_amthif_run_next_cmd(struct mei_device *dev); + + +int mei_amthif_read_message(struct mei_cl_cb *complete_list, + struct mei_device *dev, struct mei_msg_hdr *mei_hdr); +int mei_amthif_irq_process_completed(struct mei_device *dev, s32 *slots, + struct mei_cl_cb *cb_pos, + struct mei_cl *cl, + struct mei_cl_cb *cmpl_list); +void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb); +int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list, + struct mei_device *dev, struct mei_msg_hdr *mei_hdr); +int mei_amthif_irq_read(struct mei_device *dev, s32 *slots); /* * Register Access Function -- cgit v1.2.3 From 15ea19105bdeef36820ade6754b9b7f1e3511e98 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 1 Nov 2012 21:17:16 +0200 Subject: mei: mei_clear_list: kill file_temp file_temp is used only once, so there is no any benefit of creating a temporary variable Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index f69e0856f98..d8221a5a7ee 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -103,18 +103,16 @@ static DEFINE_MUTEX(mei_mutex); * returns true if callback removed from the list, false otherwise */ static bool mei_clear_list(struct mei_device *dev, - struct file *file, struct list_head *mei_cb_list) + const struct file *file, struct list_head *mei_cb_list) { struct mei_cl_cb *cb_pos = NULL; struct mei_cl_cb *cb_next = NULL; - struct file *file_temp; bool removed = false; /* list all list member */ list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) { - file_temp = (struct file *)cb_pos->file_object; /* check if list member associated with a file */ - if (file_temp == file) { + if (file == cb_pos->file_object) { /* remove member from the list */ list_del(&cb_pos->list); /* check if cb equal to current iamthif cb */ -- cgit v1.2.3 From c7d3df354dcb7477900b29a1200744a8c976c03a Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 1 Nov 2012 21:17:17 +0200 Subject: mei: use internal watchdog device registration tracking remove bool wd_interface_reg as watchdog device already keeps track of its registration Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/init.c | 2 -- drivers/misc/mei/mei_dev.h | 1 - drivers/misc/mei/wd.c | 5 +---- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 4a8eb920f7f..8c3c2689f70 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -111,8 +111,6 @@ struct mei_device *mei_device_init(struct pci_dev *pdev) init_waitqueue_head(&dev->wait_stop_wd); dev->dev_state = MEI_DEV_INITIALIZING; dev->iamthif_state = MEI_IAMTHIF_IDLE; - dev->wd_interface_reg = false; - mei_io_list_init(&dev->read_list); mei_io_list_init(&dev->write_list); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 57a5a4e4ee4..8b96d99b857 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -249,7 +249,6 @@ struct mei_device { struct mei_cl wd_cl; enum mei_wd_states wd_state; - bool wd_interface_reg; bool wd_pending; u16 wd_timeout; unsigned char wd_data[MEI_WD_START_MSG_SIZE]; diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 8edb054d4b3..4fc2b3d4680 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -360,23 +360,20 @@ void mei_watchdog_register(struct mei_device *dev) if (watchdog_register_device(&amt_wd_dev)) { dev_err(&dev->pdev->dev, "wd: unable to register watchdog device.\n"); - dev->wd_interface_reg = false; return; } dev_dbg(&dev->pdev->dev, "wd: successfully register watchdog interface.\n"); - dev->wd_interface_reg = true; watchdog_set_drvdata(&amt_wd_dev, dev); } void mei_watchdog_unregister(struct mei_device *dev) { - if (!dev->wd_interface_reg) + if (test_bit(WDOG_UNREGISTERED, &amt_wd_dev.status)) return; watchdog_set_drvdata(&amt_wd_dev, NULL); watchdog_unregister_device(&amt_wd_dev); - dev->wd_interface_reg = false; } -- cgit v1.2.3 From ab5c4a56d46f6a41d238aa6546f900407c9be275 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Thu, 1 Nov 2012 21:17:18 +0200 Subject: mei: move amthif specific code from mei_write to mei_amthif_write For sake of amthif consolidation move amthif specific code from mei_write to mei_amthif_write The original mei_amthif_write to mei_amthif_send_cmd as this function deals with sending single command while mei_amthif_write is interface function called from the main driver which in turns calls mei_amthif_send_cmd Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 39 ++++++++++++++++++++++++++++++++++++--- drivers/misc/mei/main.c | 25 +++++-------------------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 392203d8d25..96db3ad2125 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -255,14 +255,15 @@ out: } /** - * mei_amthif_write - write amthif data to amthif client + * mei_amthif_send_cmd - send amthif command to the ME * * @dev: the device structure * @cb: mei call back struct * * returns 0 on success, <0 on failure. + * */ -int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) +static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb) { struct mei_msg_hdr mei_hdr; int ret; @@ -328,6 +329,38 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) return 0; } +/** + * mei_amthif_write - write amthif data to amthif client + * + * @dev: the device structure + * @cb: mei call back struct + * + * returns 0 on success, <0 on failure. + * + */ +int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) +{ + int ret; + + if (!dev || !cb) + return -ENODEV; + + ret = mei_io_cb_alloc_resp_buf(cb, dev->iamthif_mtu); + if (ret) + return ret; + + cb->major_file_operations = MEI_IOCTL; + + if (!list_empty(&dev->amthi_cmd_list.list) || + dev->iamthif_state != MEI_IAMTHIF_IDLE) { + dev_dbg(&dev->pdev->dev, + "amthif state = %d\n", dev->iamthif_state); + dev_dbg(&dev->pdev->dev, "AMTHIF: add cb to the wait list\n"); + list_add_tail(&cb->list, &dev->amthi_cmd_list.list); + return 0; + } + return mei_amthif_send_cmd(dev, cb); +} /** * mei_amthif_run_next_cmd * @@ -360,7 +393,7 @@ void mei_amthif_run_next_cmd(struct mei_device *dev) cl_tmp = (struct mei_cl *)pos->file_private; if (cl_tmp && cl_tmp == &dev->iamthif_cl) { - status = mei_amthif_write(dev, pos); + status = mei_amthif_send_cmd(dev, pos); if (status) { dev_dbg(&dev->pdev->dev, "amthi write failed status = %d\n", diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index d8221a5a7ee..ff50cc14cc3 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -620,27 +620,12 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT; if (cl == &dev->iamthif_cl) { - rets = mei_io_cb_alloc_resp_buf(write_cb, dev->iamthif_mtu); - if (rets) - goto err; + rets = mei_amthif_write(dev, write_cb); - write_cb->major_file_operations = MEI_IOCTL; - - if (!list_empty(&dev->amthi_cmd_list.list) || - dev->iamthif_state != MEI_IAMTHIF_IDLE) { - dev_dbg(&dev->pdev->dev, "amthi_state = %d\n", - (int) dev->iamthif_state); - dev_dbg(&dev->pdev->dev, "add amthi cb to amthi cmd waiting list\n"); - list_add_tail(&write_cb->list, &dev->amthi_cmd_list.list); - } else { - dev_dbg(&dev->pdev->dev, "call amthi write\n"); - rets = mei_amthif_write(dev, write_cb); - - if (rets) { - dev_err(&dev->pdev->dev, "amthi write failed with status = %d\n", - rets); - goto err; - } + if (rets) { + dev_err(&dev->pdev->dev, + "amthi write failed with status = %d\n", rets); + goto err; } mutex_unlock(&dev->device_lock); return length; -- cgit v1.2.3 From 4e95df1f482412162ef03fe3a877aa95706b36b9 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 16:28:27 +0000 Subject: staging: comedi: gsc_hpdi: use auto_attach method This driver does not need to support manual attachment of supported PCI devices. Replace the `attach()` hook (`hpdi_attach()`) with an `auto_attach()` hook (`hpdi_auto_attach()`). This will be called via `comedi_pci_auto_config()` at PCI probe time. This driver no longer increments the PCI reference during attachment, so remove the call to `pci_dev_put()` when detaching the device. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 59 ++++++++++++------------------- 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 48092958d73..f468c1efab9 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -472,51 +472,37 @@ static int setup_dma_descriptors(struct comedi_device *dev, return transfer_size; } -static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it) +static const struct hpdi_board *hpdi_find_board(struct pci_dev *pcidev) { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(hpdi_boards); i++) + if (pcidev->device == hpdi_boards[i].device_id && + pcidev->subsystem_device == hpdi_boards[i].subdevice_id) + return &hpdi_boards[i]; + return NULL; +} + +static int __devinit hpdi_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct hpdi_private *devpriv; - struct pci_dev *pcidev; int i; int retval; - dev_dbg(dev->class_dev, "gsc_hpdi\n"); + dev->board_ptr = hpdi_find_board(pcidev); + if (!dev->board_ptr) { + dev_err(dev->class_dev, "gsc_hpdi: pci %s not supported\n", + pci_name(pcidev)); + return -EINVAL; + } devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; dev->private = devpriv; - - pcidev = NULL; - for (i = 0; i < ARRAY_SIZE(hpdi_boards) && - dev->board_ptr == NULL; i++) { - do { - pcidev = pci_get_subsys(PCI_VENDOR_ID_PLX, - hpdi_boards[i].device_id, - PCI_VENDOR_ID_PLX, - hpdi_boards[i].subdevice_id, - pcidev); - /* was a particular bus/slot requested? */ - if (it->options[0] || it->options[1]) { - /* are we on the wrong bus/slot? */ - if (pcidev->bus->number != it->options[0] || - PCI_SLOT(pcidev->devfn) != it->options[1]) - continue; - } - if (pcidev) { - devpriv->hw_dev = pcidev; - dev->board_ptr = hpdi_boards + i; - break; - } - } while (pcidev != NULL); - } - if (dev->board_ptr == NULL) { - dev_warn(dev->class_dev, "no hpdi card found\n"); - return -EIO; - } - - dev_warn(dev->class_dev, - "found %s on bus %i, slot %i\n", board(dev)->name, - pcidev->bus->number, PCI_SLOT(pcidev->devfn)); + devpriv->hw_dev = pcidev; if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { dev_warn(dev->class_dev, @@ -624,7 +610,6 @@ static void hpdi_detach(struct comedi_device *dev) devpriv-> dma_desc_phys_addr); if (devpriv->hpdi_phys_iobase) comedi_pci_disable(devpriv->hw_dev); - pci_dev_put(devpriv->hw_dev); } } @@ -974,7 +959,7 @@ static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static struct comedi_driver gsc_hpdi_driver = { .driver_name = "gsc_hpdi", .module = THIS_MODULE, - .attach = hpdi_attach, + .auto_attach = hpdi_auto_attach, .detach = hpdi_detach, }; -- cgit v1.2.3 From fd67ad4433a91c6c14188d5250ebdd86d4995f79 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 16:28:28 +0000 Subject: staging: comedi: gsc_hpdi: remove devpriv->hw_dev The `hw_dev` member of `struct hpdi_private` is used to point to the `struct pci_dev`. This is redundant as the `struct comedi_device` already has a pointer to the `struct device` within the `struct pci_dev` and there is a convenient inline function, `comedi_to_pci_dev(dev)` that returns a pointer to the `struct pci_dev`. Remove the redundant `hw_dev` member and use alternate ways to get at the `struct pci_dev`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 38 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index f468c1efab9..7c25e7fa8c4 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -213,8 +213,6 @@ static inline struct hpdi_board *board(const struct comedi_device *dev) } struct hpdi_private { - - struct pci_dev *hw_dev; /* pointer to board's pci_dev struct */ /* base addresses (physical) */ resource_size_t plx9080_phys_iobase; resource_size_t hpdi_phys_iobase; @@ -502,7 +500,6 @@ static int __devinit hpdi_auto_attach(struct comedi_device *dev, if (!devpriv) return -ENOMEM; dev->private = devpriv; - devpriv->hw_dev = pcidev; if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { dev_warn(dev->class_dev, @@ -550,18 +547,17 @@ static int __devinit hpdi_auto_attach(struct comedi_device *dev, /* allocate pci dma buffers */ for (i = 0; i < NUM_DMA_BUFFERS; i++) { devpriv->dio_buffer[i] = - pci_alloc_consistent(devpriv->hw_dev, DMA_BUFFER_SIZE, + pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, &devpriv->dio_buffer_phys_addr[i]); DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n", devpriv->dio_buffer[i], (unsigned long)devpriv->dio_buffer_phys_addr[i]); } /* allocate dma descriptors */ - devpriv->dma_desc = pci_alloc_consistent(devpriv->hw_dev, - sizeof(struct plx_dma_desc) * - NUM_DMA_DESCRIPTORS, - &devpriv-> - dma_desc_phys_addr); + devpriv->dma_desc = pci_alloc_consistent(pcidev, + sizeof(struct plx_dma_desc) * + NUM_DMA_DESCRIPTORS, + &devpriv->dma_desc_phys_addr); if (devpriv->dma_desc_phys_addr & 0xf) { dev_warn(dev->class_dev, " dma descriptors not quad-word aligned (bug)\n"); @@ -581,12 +577,13 @@ static int __devinit hpdi_auto_attach(struct comedi_device *dev, static void hpdi_detach(struct comedi_device *dev) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct hpdi_private *devpriv = dev->private; unsigned int i; if (dev->irq) free_irq(dev->irq, dev); - if (devpriv && devpriv->hw_dev) { + if (devpriv) { if (devpriv->plx9080_iobase) { disable_plx_interrupts(dev); iounmap(devpriv->plx9080_iobase); @@ -596,20 +593,21 @@ static void hpdi_detach(struct comedi_device *dev) /* free pci dma buffers */ for (i = 0; i < NUM_DMA_BUFFERS; i++) { if (devpriv->dio_buffer[i]) - pci_free_consistent(devpriv->hw_dev, - DMA_BUFFER_SIZE, - devpriv->dio_buffer[i], - devpriv->dio_buffer_phys_addr[i]); + pci_free_consistent(pcidev, + DMA_BUFFER_SIZE, + devpriv->dio_buffer[i], + devpriv-> + dio_buffer_phys_addr[i]); } /* free dma descriptors */ if (devpriv->dma_desc) - pci_free_consistent(devpriv->hw_dev, - sizeof(struct plx_dma_desc) * - NUM_DMA_DESCRIPTORS, - devpriv->dma_desc, - devpriv-> dma_desc_phys_addr); + pci_free_consistent(pcidev, + sizeof(struct plx_dma_desc) * + NUM_DMA_DESCRIPTORS, + devpriv->dma_desc, + devpriv->dma_desc_phys_addr); if (devpriv->hpdi_phys_iobase) - comedi_pci_disable(devpriv->hw_dev); + comedi_pci_disable(pcidev); } } -- cgit v1.2.3 From 594985d6615cc214dbfaf18fb6325d89a3c82e84 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 16:28:29 +0000 Subject: staging: comedi: gsc_hpdi: don't store physical base addresses In `struct hpdi_private`, the `plx9080_phys_iobase` and `hpdi_phys_iobase` hold the physical memory addresses from the PCI BARs used by this driver. The physical addresses are only really needed when ioremapping the resources when the device is being attached by `hpdi_auto_attach()`. A non-zero value of the `hpdi_phys_iobase` is also used to indicate that a call to `comedi_pci_enable()` was successful so that `comedi_pci_disable()` should be called when the device is detached by `hpdi_detach()`. Remove the `plx9080_phys_iobase` and `hpdi_phys_iobase` members and use `dev->iobase` as a flag to indicate whether `comedi_pci_disable()` needs to be called by `hpdi_detach()`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 7c25e7fa8c4..816296b04e6 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -213,9 +213,6 @@ static inline struct hpdi_board *board(const struct comedi_device *dev) } struct hpdi_private { - /* base addresses (physical) */ - resource_size_t plx9080_phys_iobase; - resource_size_t hpdi_phys_iobase; /* base addresses (ioremapped) */ void __iomem *plx9080_iobase; void __iomem *hpdi_iobase; @@ -506,23 +503,18 @@ static int __devinit hpdi_auto_attach(struct comedi_device *dev, "failed enable PCI device and request regions\n"); return -EIO; } + dev->iobase = 1; /* the "detach" needs this */ pci_set_master(pcidev); /* Initialize dev->board_name */ dev->board_name = board(dev)->name; - devpriv->plx9080_phys_iobase = - pci_resource_start(pcidev, PLX9080_BADDRINDEX); - devpriv->hpdi_phys_iobase = - pci_resource_start(pcidev, HPDI_BADDRINDEX); - - /* remap, won't work with 2.0 kernels but who cares */ - devpriv->plx9080_iobase = ioremap(devpriv->plx9080_phys_iobase, - pci_resource_len(pcidev, - PLX9080_BADDRINDEX)); + devpriv->plx9080_iobase = + ioremap(pci_resource_start(pcidev, PLX9080_BADDRINDEX), + pci_resource_len(pcidev, PLX9080_BADDRINDEX)); devpriv->hpdi_iobase = - ioremap(devpriv->hpdi_phys_iobase, - pci_resource_len(pcidev, HPDI_BADDRINDEX)); + ioremap(pci_resource_start(pcidev, HPDI_BADDRINDEX), + pci_resource_len(pcidev, HPDI_BADDRINDEX)); if (!devpriv->plx9080_iobase || !devpriv->hpdi_iobase) { dev_warn(dev->class_dev, "failed to remap io memory\n"); return -ENOMEM; @@ -606,7 +598,7 @@ static void hpdi_detach(struct comedi_device *dev) NUM_DMA_DESCRIPTORS, devpriv->dma_desc, devpriv->dma_desc_phys_addr); - if (devpriv->hpdi_phys_iobase) + if (dev->iobase) comedi_pci_disable(pcidev); } } -- cgit v1.2.3 From 6526cd1ad04adc2ca54d34d1f003b8bb5318d337 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 16:28:30 +0000 Subject: staging: comedi: gsc_hpdi: remove board(dev) function The `board(dev)` function just casts `dev->board_ptr` to a pointer to the private data type `struct hpdi_private` and returns it. It's only called from one function: `hpdi_auto_attach()`. Remove `board()` and use a local variable to point to the `struct hpdi_private` data structure. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 816296b04e6..2246338611a 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -207,11 +207,6 @@ static const struct hpdi_board hpdi_boards[] = { #endif }; -static inline struct hpdi_board *board(const struct comedi_device *dev) -{ - return (struct hpdi_board *)dev->board_ptr; -} - struct hpdi_private { /* base addresses (ioremapped) */ void __iomem *plx9080_iobase; @@ -482,16 +477,19 @@ static int __devinit hpdi_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct hpdi_board *thisboard; struct hpdi_private *devpriv; int i; int retval; - dev->board_ptr = hpdi_find_board(pcidev); - if (!dev->board_ptr) { + thisboard = hpdi_find_board(pcidev); + if (!thisboard) { dev_err(dev->class_dev, "gsc_hpdi: pci %s not supported\n", pci_name(pcidev)); return -EINVAL; } + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) @@ -506,9 +504,6 @@ static int __devinit hpdi_auto_attach(struct comedi_device *dev, dev->iobase = 1; /* the "detach" needs this */ pci_set_master(pcidev); - /* Initialize dev->board_name */ - dev->board_name = board(dev)->name; - devpriv->plx9080_iobase = ioremap(pci_resource_start(pcidev, PLX9080_BADDRINDEX), pci_resource_len(pcidev, PLX9080_BADDRINDEX)); -- cgit v1.2.3 From 21309dabd3eec2827c7604a0cba19f3e795c33d7 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 16:28:31 +0000 Subject: staging: comedi: gsc_hpdi: make board name pointer const Change the type of the `name` member of `struct hpdi_board` from `char *` to `const char *` as it should not be modifiable. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 2246338611a..adcc002bba6 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -186,8 +186,7 @@ static unsigned int fifo_size(uint32_t fifo_size_bits) } struct hpdi_board { - - char *name; + const char *name; /* board name */ int device_id; /* pci device id */ int subdevice_id; /* pci subdevice id */ }; -- cgit v1.2.3 From 3dd5ca831317a752095040d403e80cf7a6a783b5 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 16:28:32 +0000 Subject: staging: comedi: gsc_hpdi: use board name to request resources When requesting PCI region resources and IRQ, use the board name as the resource owner string instead of the driver name. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index adcc002bba6..4f829b666fe 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -495,7 +495,7 @@ static int __devinit hpdi_auto_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { + if (comedi_pci_enable(pcidev, dev->board_name)) { dev_warn(dev->class_dev, "failed enable PCI device and request regions\n"); return -EIO; @@ -521,7 +521,7 @@ static int __devinit hpdi_auto_attach(struct comedi_device *dev, /* get irq */ if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, - dev->driver->driver_name, dev)) { + dev->board_name, dev)) { dev_warn(dev->class_dev, "unable to allocate irq %u\n", pcidev->irq); return -EINVAL; -- cgit v1.2.3 From 871e1d0545436f7c21b1b103601e1fe3920a6e4c Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 16:28:33 +0000 Subject: staging: comedi: gsc_hpdi: change DEBUG_PRINT() Change the `DEBUG_PRINT(format, args...)` macro used by this module to use either `pr_debug()` (if macro `HPDI_DEBUG` is defined) or `no_printk()` instead of `printk()` or nothing. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 4f829b666fe..c056c259ddb 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -45,6 +45,8 @@ support could be added to this driver. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include "../comedidev.h" #include @@ -64,9 +66,9 @@ static int dio_config_block_size(struct comedi_device *dev, unsigned int *data); /* #define HPDI_DEBUG enable debugging code */ #ifdef HPDI_DEBUG -#define DEBUG_PRINT(format, args...) printk(format , ## args) +#define DEBUG_PRINT(format, args...) pr_debug(format , ## args) #else -#define DEBUG_PRINT(format, args...) +#define DEBUG_PRINT(format, args...) no_printk(pr_fmt(format), ## args) #endif #define TIMER_BASE 50 /* 20MHz master clock */ -- cgit v1.2.3 From 50a24814958ff9cba0e74bfa900bfac698c2ce23 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 16:28:34 +0000 Subject: staging: comedi: gsc_hpdi: update driver description comment Reformat the comment used to describe the Comedi driver to use the usual block comment style. Update the information reflecting the fact that the driver no longer supports manual attachment of devices via the `COMEDI_DEVCONFIG` ioctl. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index c056c259ddb..77b86820d7b 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -26,24 +26,24 @@ ************************************************************************/ /* - -Driver: gsc_hpdi -Description: General Standards Corporation High - Speed Parallel Digital Interface rs485 boards -Author: Frank Mori Hess -Status: only receive mode works, transmit not supported -Updated: 2003-02-20 -Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi), - PMC-HPDI32 - -Configuration options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - -There are some additional hpdi models available from GSC for which -support could be added to this driver. - -*/ + * Driver: gsc_hpdi + * Description: General Standards Corporation High + * Speed Parallel Digital Interface rs485 boards + * Author: Frank Mori Hess + * Status: only receive mode works, transmit not supported + * Updated: Thu, 01 Nov 2012 16:17:38 +0000 + * Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi), + * PMC-HPDI32 + * + * Configuration options: + * None. + * + * Manual configuration of supported devices is not supported; they are + * configured automatically. + * + * There are some additional hpdi models available from GSC for which + * support could be added to this driver. + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -- cgit v1.2.3 From 10db292fb43045881135fa7f8457e9399108a985 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 11:08:37 -0700 Subject: staging: comedi: addi_apci_1710: separate from addi_common.c This addi-data driver uses a private function to initialize all the subdevices during the attach of the board. Copy the code in addi_common.c to this driver and remove the #include that caused addi_common.c to be compiled with this driver. This will allow removing the special handling for the apci1710 board in the common code. Rename the attach_pci and detach functions so they have namespace associated with this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1710.c | 370 +++++++++++++++++++++++- 1 file changed, 367 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 6337aceaf24..36dde3a4b19 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -20,7 +20,10 @@ static void fpu_end(void) #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_APCI1710.c" -#include "addi-data/addi_common.c" + +#ifndef COMEDI_SUBD_TTLIO +#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ +#endif static const struct addi_board apci1710_boardtypes[] = { { @@ -36,11 +39,372 @@ static const struct addi_board apci1710_boardtypes[] = { }, }; +static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; + unsigned short w_Address = CR_CHAN(insn->chanspec); + unsigned short w_Data; + + w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, + this_board->pc_EepromChip, 2 * w_Address); + data[0] = w_Data; + + return insn->n; +} + +static irqreturn_t v_ADDI_Interrupt(int irq, void *d) +{ + struct comedi_device *dev = d; + const struct addi_board *this_board = comedi_board(dev); + + this_board->interrupt(irq, d); + return IRQ_RETVAL(1); +} + +static int i_ADDI_Reset(struct comedi_device *dev) +{ + const struct addi_board *this_board = comedi_board(dev); + + this_board->reset(dev); + return 0; +} + +static const void *addi_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const void *p = dev->driver->board_name; + const struct addi_board *this_board; + int i; + + for (i = 0; i < dev->driver->num_names; i++) { + this_board = p; + if (this_board->i_VendorId == pcidev->vendor && + this_board->i_DeviceId == pcidev->device) + return this_board; + p += dev->driver->offset; + } + return NULL; +} + +static int apci1710_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const struct addi_board *this_board; + struct addi_private *devpriv; + struct comedi_subdevice *s; + int ret, pages, i, n_subdevices; + unsigned int dw_Dummy; + + this_board = addi_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->pc_DriverName; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + if (this_board->i_Dma) + pci_set_master(pcidev); + + if (!this_board->pc_EepromChip || + !strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { + if (this_board->i_IorangeBase1) + dev->iobase = pci_resource_start(pcidev, 1); + else + dev->iobase = pci_resource_start(pcidev, 0); + + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); + } else { + dev->iobase = pci_resource_start(pcidev, 2); + devpriv->iobase = pci_resource_start(pcidev, 2); + devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), + this_board->i_IorangeBase3); + } + devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); + + /* Initialize parameters that can be overridden in EEPROM */ + devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; + devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; + devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; + devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; + devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; + devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; + devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; + devpriv->s_EeParameters.i_Dma = this_board->i_Dma; + devpriv->s_EeParameters.i_Timer = this_board->i_Timer; + devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = + this_board->ui_MinAcquisitiontimeNs; + devpriv->s_EeParameters.ui_MinDelaytimeNs = + this_board->ui_MinDelaytimeNs; + + /* ## */ + + if (pcidev->irq > 0) { + ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } + + /* Read eepeom and fill addi_board Structure */ + + if (this_board->i_PCIEeprom) { + if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { + /* Set 3 wait stait */ + if (!(strcmp(dev->board_name, "apci035"))) { + outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); + } else { + outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); + } + /* Enable the interrupt for the controller */ + dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); + outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); + } + addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); + } + + devpriv->us_UseDma = ADDI_ENABLE; + + if (devpriv->s_EeParameters.i_Dma) { + if (devpriv->us_UseDma == ADDI_ENABLE) { + /* alloc DMA buffers */ + devpriv->b_DmaDoubleBuffer = 0; + for (i = 0; i < 2; i++) { + for (pages = 4; pages >= 0; pages--) { + devpriv->ul_DmaBufferVirtual[i] = + (void *) __get_free_pages(GFP_KERNEL, pages); + + if (devpriv->ul_DmaBufferVirtual[i]) + break; + } + if (devpriv->ul_DmaBufferVirtual[i]) { + devpriv->ui_DmaBufferPages[i] = pages; + devpriv->ui_DmaBufferSize[i] = + PAGE_SIZE * pages; + devpriv->ui_DmaBufferSamples[i] = + devpriv-> + ui_DmaBufferSize[i] >> 1; + devpriv->ul_DmaBufferHw[i] = + virt_to_bus((void *)devpriv-> + ul_DmaBufferVirtual[i]); + } + } + if (!devpriv->ul_DmaBufferVirtual[0]) + devpriv->us_UseDma = ADDI_DISABLE; + + if (devpriv->ul_DmaBufferVirtual[1]) + devpriv->b_DmaDoubleBuffer = 1; + } + } + + if (!strcmp(dev->board_name, "apci1710")) { +#ifdef CONFIG_APCI_1710 + i_ADDI_AttachPCI1710(dev); + + /* save base address */ + devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2); +#endif + } else { + n_subdevices = 7; + ret = comedi_alloc_subdevices(dev, n_subdevices); + if (ret) + return ret; + + /* Allocate and Initialise AI Subdevice Structures */ + s = &dev->subdevices[0]; + if ((devpriv->s_EeParameters.i_NbrAiChannel) + || (this_board->i_NbrAiChannelDiff)) { + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_COMMON | SDF_GROUND + | SDF_DIFF; + if (devpriv->s_EeParameters.i_NbrAiChannel) { + s->n_chan = + devpriv->s_EeParameters.i_NbrAiChannel; + devpriv->b_SingelDiff = 0; + } else { + s->n_chan = this_board->i_NbrAiChannelDiff; + devpriv->b_SingelDiff = 1; + } + s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; + s->len_chanlist = this_board->i_AiChannelList; + s->range_table = this_board->pr_AiRangelist; + + /* Set the initialisation flag */ + devpriv->b_AiInitialisation = 1; + + s->insn_config = this_board->ai_config; + s->insn_read = this_board->ai_read; + s->insn_write = this_board->ai_write; + s->insn_bits = this_board->ai_bits; + s->do_cmdtest = this_board->ai_cmdtest; + s->do_cmd = this_board->ai_cmd; + s->cancel = this_board->ai_cancel; + + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise AO Subdevice Structures */ + s = &dev->subdevices[1]; + if (devpriv->s_EeParameters.i_NbrAoChannel) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; + s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrAoChannel; + s->range_table = this_board->pr_AoRangelist; + s->insn_config = this_board->ao_config; + s->insn_write = this_board->ao_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DI Subdevice Structures */ + s = &dev->subdevices[2]; + if (devpriv->s_EeParameters.i_NbrDiChannel) { + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; + s->maxdata = 1; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDiChannel; + s->range_table = &range_digital; + s->io_bits = 0; /* all bits input */ + s->insn_config = this_board->di_config; + s->insn_read = this_board->di_read; + s->insn_write = this_board->di_write; + s->insn_bits = this_board->di_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DO Subdevice Structures */ + s = &dev->subdevices[3]; + if (devpriv->s_EeParameters.i_NbrDoChannel) { + s->type = COMEDI_SUBD_DO; + s->subdev_flags = + SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; + s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDoChannel; + s->range_table = &range_digital; + s->io_bits = 0xf; /* all bits output */ + + /* insn_config - for digital output memory */ + s->insn_config = this_board->do_config; + s->insn_write = this_board->do_write; + s->insn_bits = this_board->do_bits; + s->insn_read = this_board->do_read; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise Timer Subdevice Structures */ + s = &dev->subdevices[4]; + if (devpriv->s_EeParameters.i_Timer) { + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + + s->insn_write = this_board->timer_write; + s->insn_read = this_board->timer_read; + s->insn_config = this_board->timer_config; + s->insn_bits = this_board->timer_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise TTL */ + s = &dev->subdevices[5]; + if (this_board->i_NbrTTLChannel) { + s->type = COMEDI_SUBD_TTLIO; + s->subdev_flags = + SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = this_board->i_NbrTTLChannel; + s->maxdata = 1; + s->io_bits = 0; /* all bits input */ + s->len_chanlist = this_board->i_NbrTTLChannel; + s->range_table = &range_digital; + s->insn_config = this_board->ttl_config; + s->insn_bits = this_board->ttl_bits; + s->insn_read = this_board->ttl_read; + s->insn_write = this_board->ttl_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* EEPROM */ + s = &dev->subdevices[6]; + if (this_board->i_PCIEeprom) { + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE | SDF_INTERNAL; + s->n_chan = 256; + s->maxdata = 0xffff; + s->insn_read = i_ADDIDATA_InsnReadEeprom; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + } + + i_ADDI_Reset(dev); + return 0; +} + +static void apci1710_detach(struct comedi_device *dev) +{ + const struct addi_board *this_board = comedi_board(dev); + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct addi_private *devpriv = dev->private; + + if (devpriv) { + if (dev->iobase) + i_ADDI_Reset(dev); + if (dev->irq) + free_irq(dev->irq, dev); + if ((this_board->pc_EepromChip == NULL) || + (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { + if (devpriv->ul_DmaBufferVirtual[0]) { + free_pages((unsigned long)devpriv-> + ul_DmaBufferVirtual[0], + devpriv->ui_DmaBufferPages[0]); + } + if (devpriv->ul_DmaBufferVirtual[1]) { + free_pages((unsigned long)devpriv-> + ul_DmaBufferVirtual[1], + devpriv->ui_DmaBufferPages[1]); + } + } else { + iounmap(devpriv->dw_AiBase); + } + } + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } +} + static struct comedi_driver apci1710_driver = { .driver_name = "addi_apci_1710", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, - .detach = i_ADDI_Detach, + .attach_pci = apci1710_attach_pci, + .detach = apci1710_detach, .num_names = ARRAY_SIZE(apci1710_boardtypes), .board_name = &apci1710_boardtypes[0].pc_DriverName, .offset = sizeof(struct addi_board), -- cgit v1.2.3 From c9ab760d63d33efee64bbe26b2002e459c3c4c57 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 11:08:56 -0700 Subject: staging: comedi: addi-data: remove special handling for apci1710 Now that the addi_apci_1710 driver is not using addi_common.c we can remove the CONFIG_APCI_1710 define and all the special handling for the initialization of it's subdevices. Also remove the i_ADDIDATA_InsnReadEeprom() function from the addi_apci_1710 driver. This board does not have an eeprom subdevice and does not use this function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 279 ++++++++++----------- drivers/staging/comedi/drivers/addi_apci_1710.c | 173 +------------ 2 files changed, 137 insertions(+), 315 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index b533c23ca24..75f3dbdbed6 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -212,158 +212,149 @@ static int addi_attach_pci(struct comedi_device *dev, } } - if (!strcmp(dev->board_name, "apci1710")) { -#ifdef CONFIG_APCI_1710 - i_ADDI_AttachPCI1710(dev); + n_subdevices = 7; + ret = comedi_alloc_subdevices(dev, n_subdevices); + if (ret) + return ret; - /* save base address */ - devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2); -#endif - } else { - n_subdevices = 7; - ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret) - return ret; - - /* Allocate and Initialise AI Subdevice Structures */ - s = &dev->subdevices[0]; - if ((devpriv->s_EeParameters.i_NbrAiChannel) - || (this_board->i_NbrAiChannelDiff)) { - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND - | SDF_DIFF; - if (devpriv->s_EeParameters.i_NbrAiChannel) { - s->n_chan = - devpriv->s_EeParameters.i_NbrAiChannel; - devpriv->b_SingelDiff = 0; - } else { - s->n_chan = this_board->i_NbrAiChannelDiff; - devpriv->b_SingelDiff = 1; - } - s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; - s->len_chanlist = this_board->i_AiChannelList; - s->range_table = this_board->pr_AiRangelist; + /* Allocate and Initialise AI Subdevice Structures */ + s = &dev->subdevices[0]; + if ((devpriv->s_EeParameters.i_NbrAiChannel) + || (this_board->i_NbrAiChannelDiff)) { + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_COMMON | SDF_GROUND + | SDF_DIFF; + if (devpriv->s_EeParameters.i_NbrAiChannel) { + s->n_chan = + devpriv->s_EeParameters.i_NbrAiChannel; + devpriv->b_SingelDiff = 0; + } else { + s->n_chan = this_board->i_NbrAiChannelDiff; + devpriv->b_SingelDiff = 1; + } + s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; + s->len_chanlist = this_board->i_AiChannelList; + s->range_table = this_board->pr_AiRangelist; - /* Set the initialisation flag */ - devpriv->b_AiInitialisation = 1; + /* Set the initialisation flag */ + devpriv->b_AiInitialisation = 1; - s->insn_config = this_board->ai_config; - s->insn_read = this_board->ai_read; - s->insn_write = this_board->ai_write; - s->insn_bits = this_board->ai_bits; - s->do_cmdtest = this_board->ai_cmdtest; - s->do_cmd = this_board->ai_cmd; - s->cancel = this_board->ai_cancel; + s->insn_config = this_board->ai_config; + s->insn_read = this_board->ai_read; + s->insn_write = this_board->ai_write; + s->insn_bits = this_board->ai_bits; + s->do_cmdtest = this_board->ai_cmdtest; + s->do_cmd = this_board->ai_cmd; + s->cancel = this_board->ai_cancel; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + } else { + s->type = COMEDI_SUBD_UNUSED; + } - /* Allocate and Initialise AO Subdevice Structures */ - s = &dev->subdevices[1]; - if (devpriv->s_EeParameters.i_NbrAoChannel) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; - s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrAoChannel; - s->range_table = this_board->pr_AoRangelist; - s->insn_config = this_board->ao_config; - s->insn_write = this_board->ao_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - /* Allocate and Initialise DI Subdevice Structures */ - s = &dev->subdevices[2]; - if (devpriv->s_EeParameters.i_NbrDiChannel) { - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; - s->maxdata = 1; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDiChannel; - s->range_table = &range_digital; - s->io_bits = 0; /* all bits input */ - s->insn_config = this_board->di_config; - s->insn_read = this_board->di_read; - s->insn_write = this_board->di_write; - s->insn_bits = this_board->di_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - /* Allocate and Initialise DO Subdevice Structures */ - s = &dev->subdevices[3]; - if (devpriv->s_EeParameters.i_NbrDoChannel) { - s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; - s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDoChannel; - s->range_table = &range_digital; - s->io_bits = 0xf; /* all bits output */ - - /* insn_config - for digital output memory */ - s->insn_config = this_board->do_config; - s->insn_write = this_board->do_write; - s->insn_bits = this_board->do_bits; - s->insn_read = this_board->do_read; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + /* Allocate and Initialise AO Subdevice Structures */ + s = &dev->subdevices[1]; + if (devpriv->s_EeParameters.i_NbrAoChannel) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; + s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrAoChannel; + s->range_table = this_board->pr_AoRangelist; + s->insn_config = this_board->ao_config; + s->insn_write = this_board->ao_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DI Subdevice Structures */ + s = &dev->subdevices[2]; + if (devpriv->s_EeParameters.i_NbrDiChannel) { + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; + s->maxdata = 1; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDiChannel; + s->range_table = &range_digital; + s->io_bits = 0; /* all bits input */ + s->insn_config = this_board->di_config; + s->insn_read = this_board->di_read; + s->insn_write = this_board->di_write; + s->insn_bits = this_board->di_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DO Subdevice Structures */ + s = &dev->subdevices[3]; + if (devpriv->s_EeParameters.i_NbrDoChannel) { + s->type = COMEDI_SUBD_DO; + s->subdev_flags = + SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; + s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDoChannel; + s->range_table = &range_digital; + s->io_bits = 0xf; /* all bits output */ + + /* insn_config - for digital output memory */ + s->insn_config = this_board->do_config; + s->insn_write = this_board->do_write; + s->insn_bits = this_board->do_bits; + s->insn_read = this_board->do_read; + } else { + s->type = COMEDI_SUBD_UNUSED; + } - /* Allocate and Initialise Timer Subdevice Structures */ - s = &dev->subdevices[4]; - if (devpriv->s_EeParameters.i_Timer) { - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; - s->range_table = &range_digital; - - s->insn_write = this_board->timer_write; - s->insn_read = this_board->timer_read; - s->insn_config = this_board->timer_config; - s->insn_bits = this_board->timer_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + /* Allocate and Initialise Timer Subdevice Structures */ + s = &dev->subdevices[4]; + if (devpriv->s_EeParameters.i_Timer) { + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + + s->insn_write = this_board->timer_write; + s->insn_read = this_board->timer_read; + s->insn_config = this_board->timer_config; + s->insn_bits = this_board->timer_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } - /* Allocate and Initialise TTL */ - s = &dev->subdevices[5]; - if (this_board->i_NbrTTLChannel) { - s->type = COMEDI_SUBD_TTLIO; - s->subdev_flags = - SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrTTLChannel; - s->maxdata = 1; - s->io_bits = 0; /* all bits input */ - s->len_chanlist = this_board->i_NbrTTLChannel; - s->range_table = &range_digital; - s->insn_config = this_board->ttl_config; - s->insn_bits = this_board->ttl_bits; - s->insn_read = this_board->ttl_read; - s->insn_write = this_board->ttl_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + /* Allocate and Initialise TTL */ + s = &dev->subdevices[5]; + if (this_board->i_NbrTTLChannel) { + s->type = COMEDI_SUBD_TTLIO; + s->subdev_flags = + SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = this_board->i_NbrTTLChannel; + s->maxdata = 1; + s->io_bits = 0; /* all bits input */ + s->len_chanlist = this_board->i_NbrTTLChannel; + s->range_table = &range_digital; + s->insn_config = this_board->ttl_config; + s->insn_bits = this_board->ttl_bits; + s->insn_read = this_board->ttl_read; + s->insn_write = this_board->ttl_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } - /* EEPROM */ - s = &dev->subdevices[6]; - if (this_board->i_PCIEeprom) { - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 256; - s->maxdata = 0xffff; - s->insn_read = i_ADDIDATA_InsnReadEeprom; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + /* EEPROM */ + s = &dev->subdevices[6]; + if (this_board->i_PCIEeprom) { + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE | SDF_INTERNAL; + s->n_chan = 256; + s->maxdata = 0xffff; + s->insn_read = i_ADDIDATA_InsnReadEeprom; + } else { + s->type = COMEDI_SUBD_UNUSED; } i_ADDI_Reset(dev); diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 36dde3a4b19..ed5c7141293 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -16,8 +16,6 @@ static void fpu_end(void) kernel_fpu_end(); } -#define CONFIG_APCI_1710 1 - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_APCI1710.c" @@ -39,23 +37,6 @@ static const struct addi_board apci1710_boardtypes[] = { }, }; -static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = comedi_board(dev); - struct addi_private *devpriv = dev->private; - unsigned short w_Address = CR_CHAN(insn->chanspec); - unsigned short w_Data; - - w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, - this_board->pc_EepromChip, 2 * w_Address); - data[0] = w_Data; - - return insn->n; -} - static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { struct comedi_device *dev = d; @@ -209,159 +190,9 @@ static int apci1710_attach_pci(struct comedi_device *dev, } } - if (!strcmp(dev->board_name, "apci1710")) { -#ifdef CONFIG_APCI_1710 - i_ADDI_AttachPCI1710(dev); - - /* save base address */ - devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2); -#endif - } else { - n_subdevices = 7; - ret = comedi_alloc_subdevices(dev, n_subdevices); - if (ret) - return ret; - - /* Allocate and Initialise AI Subdevice Structures */ - s = &dev->subdevices[0]; - if ((devpriv->s_EeParameters.i_NbrAiChannel) - || (this_board->i_NbrAiChannelDiff)) { - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND - | SDF_DIFF; - if (devpriv->s_EeParameters.i_NbrAiChannel) { - s->n_chan = - devpriv->s_EeParameters.i_NbrAiChannel; - devpriv->b_SingelDiff = 0; - } else { - s->n_chan = this_board->i_NbrAiChannelDiff; - devpriv->b_SingelDiff = 1; - } - s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; - s->len_chanlist = this_board->i_AiChannelList; - s->range_table = this_board->pr_AiRangelist; - - /* Set the initialisation flag */ - devpriv->b_AiInitialisation = 1; - - s->insn_config = this_board->ai_config; - s->insn_read = this_board->ai_read; - s->insn_write = this_board->ai_write; - s->insn_bits = this_board->ai_bits; - s->do_cmdtest = this_board->ai_cmdtest; - s->do_cmd = this_board->ai_cmd; - s->cancel = this_board->ai_cancel; - - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* Allocate and Initialise AO Subdevice Structures */ - s = &dev->subdevices[1]; - if (devpriv->s_EeParameters.i_NbrAoChannel) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; - s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrAoChannel; - s->range_table = this_board->pr_AoRangelist; - s->insn_config = this_board->ao_config; - s->insn_write = this_board->ao_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - /* Allocate and Initialise DI Subdevice Structures */ - s = &dev->subdevices[2]; - if (devpriv->s_EeParameters.i_NbrDiChannel) { - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; - s->maxdata = 1; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDiChannel; - s->range_table = &range_digital; - s->io_bits = 0; /* all bits input */ - s->insn_config = this_board->di_config; - s->insn_read = this_board->di_read; - s->insn_write = this_board->di_write; - s->insn_bits = this_board->di_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - /* Allocate and Initialise DO Subdevice Structures */ - s = &dev->subdevices[3]; - if (devpriv->s_EeParameters.i_NbrDoChannel) { - s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; - s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDoChannel; - s->range_table = &range_digital; - s->io_bits = 0xf; /* all bits output */ - - /* insn_config - for digital output memory */ - s->insn_config = this_board->do_config; - s->insn_write = this_board->do_write; - s->insn_bits = this_board->do_bits; - s->insn_read = this_board->do_read; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + i_ADDI_AttachPCI1710(dev); - /* Allocate and Initialise Timer Subdevice Structures */ - s = &dev->subdevices[4]; - if (devpriv->s_EeParameters.i_Timer) { - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; - s->range_table = &range_digital; - - s->insn_write = this_board->timer_write; - s->insn_read = this_board->timer_read; - s->insn_config = this_board->timer_config; - s->insn_bits = this_board->timer_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* Allocate and Initialise TTL */ - s = &dev->subdevices[5]; - if (this_board->i_NbrTTLChannel) { - s->type = COMEDI_SUBD_TTLIO; - s->subdev_flags = - SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrTTLChannel; - s->maxdata = 1; - s->io_bits = 0; /* all bits input */ - s->len_chanlist = this_board->i_NbrTTLChannel; - s->range_table = &range_digital; - s->insn_config = this_board->ttl_config; - s->insn_bits = this_board->ttl_bits; - s->insn_read = this_board->ttl_read; - s->insn_write = this_board->ttl_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* EEPROM */ - s = &dev->subdevices[6]; - if (this_board->i_PCIEeprom) { - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 256; - s->maxdata = 0xffff; - s->insn_read = i_ADDIDATA_InsnReadEeprom; - } else { - s->type = COMEDI_SUBD_UNUSED; - } - } + devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2); i_ADDI_Reset(dev); return 0; -- cgit v1.2.3 From 678e4e27bc31c78b3a7171d6e26d7825c46d5c36 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 11:09:12 -0700 Subject: staging: comedi: addi_apci_1710: cleanup addi_find_boardinfo() This driver uses the comedi PCI auto attach mechanism and the comedi core does not use the boardinfo during the attach. Now that this driver has the attach separated from addi_common.c we can remove passing the boardinfo in the comedi_driver and cleanup the code that finds the boardinfo. Also, rename addi_find_boardinfo() so it has namespace associated with this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1710.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index ed5c7141293..a5cfc9b9193 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -54,19 +54,17 @@ static int i_ADDI_Reset(struct comedi_device *dev) return 0; } -static const void *addi_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) +static const void *apci1710_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - const void *p = dev->driver->board_name; const struct addi_board *this_board; int i; - for (i = 0; i < dev->driver->num_names; i++) { - this_board = p; + for (i = 0; i < ARRAY_SIZE(apci1710_boardtypes); i++) { + this_board = &apci1710_boardtypes[i]; if (this_board->i_VendorId == pcidev->vendor && this_board->i_DeviceId == pcidev->device) return this_board; - p += dev->driver->offset; } return NULL; } @@ -80,7 +78,7 @@ static int apci1710_attach_pci(struct comedi_device *dev, int ret, pages, i, n_subdevices; unsigned int dw_Dummy; - this_board = addi_find_boardinfo(dev, pcidev); + this_board = apci1710_find_boardinfo(dev, pcidev); if (!this_board) return -ENODEV; dev->board_ptr = this_board; @@ -236,9 +234,6 @@ static struct comedi_driver apci1710_driver = { .module = THIS_MODULE, .attach_pci = apci1710_attach_pci, .detach = apci1710_detach, - .num_names = ARRAY_SIZE(apci1710_boardtypes), - .board_name = &apci1710_boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), }; static int __devinit apci1710_pci_probe(struct pci_dev *dev, -- cgit v1.2.3 From 48562c361fb11f30ae856065d335a0ae1516edde Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 11:09:27 -0700 Subject: staging: comedi: addi_apci_1710: remove i_ADDI_Reset This driver is now separate from the "common" code used with the addi-data drivers. There is no need to use i_ADDI_Reset() to call the correct "reset" function. Remove the i_ADDI_Reset() function and the 'reset' pointer to the real function from the boardinfo and just call the function directly where needed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1710.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index a5cfc9b9193..fdc9060d6c4 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -33,7 +33,6 @@ static const struct addi_board apci1710_boardtypes[] = { .i_IorangeBase2 = 256, .i_PCIEeprom = ADDIDATA_NO_EEPROM, .interrupt = v_APCI1710_Interrupt, - .reset = i_APCI1710_Reset, }, }; @@ -46,14 +45,6 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) return IRQ_RETVAL(1); } -static int i_ADDI_Reset(struct comedi_device *dev) -{ - const struct addi_board *this_board = comedi_board(dev); - - this_board->reset(dev); - return 0; -} - static const void *apci1710_find_boardinfo(struct comedi_device *dev, struct pci_dev *pcidev) { @@ -192,7 +183,7 @@ static int apci1710_attach_pci(struct comedi_device *dev, devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2); - i_ADDI_Reset(dev); + i_APCI1710_Reset(dev); return 0; } @@ -204,7 +195,7 @@ static void apci1710_detach(struct comedi_device *dev) if (devpriv) { if (dev->iobase) - i_ADDI_Reset(dev); + i_APCI1710_Reset(dev); if (dev->irq) free_irq(dev->irq, dev); if ((this_board->pc_EepromChip == NULL) || -- cgit v1.2.3 From ae6195f58313bee2abbf50de3bc778554821b4ac Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 11:09:43 -0700 Subject: staging: comedi: addi_apci_1710: remove eeprom handling code The apci1710 board does not have an eeprom. Remove the unnecessary code to handle it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1710.c | 43 +++++-------------------- 1 file changed, 8 insertions(+), 35 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index fdc9060d6c4..d608c8bd8e2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -31,7 +31,6 @@ static const struct addi_board apci1710_boardtypes[] = { .i_IorangeBase0 = 128, .i_IorangeBase1 = 8, .i_IorangeBase2 = 256, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, .interrupt = v_APCI1710_Interrupt, }, }; @@ -67,7 +66,6 @@ static int apci1710_attach_pci(struct comedi_device *dev, struct addi_private *devpriv; struct comedi_subdevice *s; int ret, pages, i, n_subdevices; - unsigned int dw_Dummy; this_board = apci1710_find_boardinfo(dev, pcidev); if (!this_board) @@ -86,22 +84,14 @@ static int apci1710_attach_pci(struct comedi_device *dev, if (this_board->i_Dma) pci_set_master(pcidev); - if (!this_board->pc_EepromChip || - !strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { - if (this_board->i_IorangeBase1) - dev->iobase = pci_resource_start(pcidev, 1); - else - dev->iobase = pci_resource_start(pcidev, 0); - - devpriv->iobase = dev->iobase; - devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); - devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - } else { - dev->iobase = pci_resource_start(pcidev, 2); - devpriv->iobase = pci_resource_start(pcidev, 2); - devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), - this_board->i_IorangeBase3); - } + if (this_board->i_IorangeBase1) + dev->iobase = pci_resource_start(pcidev, 1); + else + dev->iobase = pci_resource_start(pcidev, 0); + + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); /* Initialize parameters that can be overridden in EEPROM */ @@ -128,23 +118,6 @@ static int apci1710_attach_pci(struct comedi_device *dev, dev->irq = pcidev->irq; } - /* Read eepeom and fill addi_board Structure */ - - if (this_board->i_PCIEeprom) { - if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { - /* Set 3 wait stait */ - if (!(strcmp(dev->board_name, "apci035"))) { - outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); - } else { - outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); - } - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - } - addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); - } - devpriv->us_UseDma = ADDI_ENABLE; if (devpriv->s_EeParameters.i_Dma) { -- cgit v1.2.3 From b0b5ece1bf94db7113e0e66adedc226aa690e3de Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 11:10:02 -0700 Subject: staging: comedi: addi_apci_1710: remove dma setup/free code This driver does not use dma. Remove the code that sets up the dma and allocates the buffers in the attach and the code that frees the buffers in the detach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1710.c | 65 ++----------------------- 1 file changed, 5 insertions(+), 60 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index d608c8bd8e2..a494929b0e5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -65,7 +65,7 @@ static int apci1710_attach_pci(struct comedi_device *dev, const struct addi_board *this_board; struct addi_private *devpriv; struct comedi_subdevice *s; - int ret, pages, i, n_subdevices; + int ret; this_board = apci1710_find_boardinfo(dev, pcidev); if (!this_board) @@ -81,8 +81,6 @@ static int apci1710_attach_pci(struct comedi_device *dev, ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - if (this_board->i_Dma) - pci_set_master(pcidev); if (this_board->i_IorangeBase1) dev->iobase = pci_resource_start(pcidev, 1); @@ -118,40 +116,6 @@ static int apci1710_attach_pci(struct comedi_device *dev, dev->irq = pcidev->irq; } - devpriv->us_UseDma = ADDI_ENABLE; - - if (devpriv->s_EeParameters.i_Dma) { - if (devpriv->us_UseDma == ADDI_ENABLE) { - /* alloc DMA buffers */ - devpriv->b_DmaDoubleBuffer = 0; - for (i = 0; i < 2; i++) { - for (pages = 4; pages >= 0; pages--) { - devpriv->ul_DmaBufferVirtual[i] = - (void *) __get_free_pages(GFP_KERNEL, pages); - - if (devpriv->ul_DmaBufferVirtual[i]) - break; - } - if (devpriv->ul_DmaBufferVirtual[i]) { - devpriv->ui_DmaBufferPages[i] = pages; - devpriv->ui_DmaBufferSize[i] = - PAGE_SIZE * pages; - devpriv->ui_DmaBufferSamples[i] = - devpriv-> - ui_DmaBufferSize[i] >> 1; - devpriv->ul_DmaBufferHw[i] = - virt_to_bus((void *)devpriv-> - ul_DmaBufferVirtual[i]); - } - } - if (!devpriv->ul_DmaBufferVirtual[0]) - devpriv->us_UseDma = ADDI_DISABLE; - - if (devpriv->ul_DmaBufferVirtual[1]) - devpriv->b_DmaDoubleBuffer = 1; - } - } - i_ADDI_AttachPCI1710(dev); devpriv->s_BoardInfos.ui_Address = pci_resource_start(pcidev, 2); @@ -162,31 +126,12 @@ static int apci1710_attach_pci(struct comedi_device *dev, static void apci1710_detach(struct comedi_device *dev) { - const struct addi_board *this_board = comedi_board(dev); struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct addi_private *devpriv = dev->private; - if (devpriv) { - if (dev->iobase) - i_APCI1710_Reset(dev); - if (dev->irq) - free_irq(dev->irq, dev); - if ((this_board->pc_EepromChip == NULL) || - (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { - if (devpriv->ul_DmaBufferVirtual[0]) { - free_pages((unsigned long)devpriv-> - ul_DmaBufferVirtual[0], - devpriv->ui_DmaBufferPages[0]); - } - if (devpriv->ul_DmaBufferVirtual[1]) { - free_pages((unsigned long)devpriv-> - ul_DmaBufferVirtual[1], - devpriv->ui_DmaBufferPages[1]); - } - } else { - iounmap(devpriv->dw_AiBase); - } - } + if (dev->iobase) + i_APCI1710_Reset(dev); + if (dev->irq) + free_irq(dev->irq, dev); if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); -- cgit v1.2.3 From 06f1b1346fb238befb7ffc5906798d2e035e7648 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 11:10:19 -0700 Subject: staging: comedi: addi_apci_1710: remove the eeprom parameters This driver does not have an eeprom and does not use the data saved in devpriv->s_EeParameters. Remove the code that initalizes the eeprom parameters. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1710.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index a494929b0e5..02a2ac9baaa 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -92,23 +92,6 @@ static int apci1710_attach_pci(struct comedi_device *dev, devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); - /* Initialize parameters that can be overridden in EEPROM */ - devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; - devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; - devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; - devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; - devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; - devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; - devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; - devpriv->s_EeParameters.i_Dma = this_board->i_Dma; - devpriv->s_EeParameters.i_Timer = this_board->i_Timer; - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = - this_board->ui_MinAcquisitiontimeNs; - devpriv->s_EeParameters.ui_MinDelaytimeNs = - this_board->ui_MinDelaytimeNs; - - /* ## */ - if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, dev->board_name, dev); -- cgit v1.2.3 From ff2d6d340f8ddc074584dd9b285823c3e576549b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 11:10:35 -0700 Subject: staging: comedi: addi_apci_1710: remove the 'i_IorangeBase*' These values in the boardinfor were used in the common addi-data attach code to work out use of the PCI bars. Since this driver has a localized attach we already know the use of the bars so this information in the boardinfo is unnecessary. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1710.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 02a2ac9baaa..6bfbebeeb20 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -28,9 +28,6 @@ static const struct addi_board apci1710_boardtypes[] = { .pc_DriverName = "apci1710", .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, .i_DeviceId = APCI1710_BOARD_DEVICE_ID, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = 8, - .i_IorangeBase2 = 256, .interrupt = v_APCI1710_Interrupt, }, }; -- cgit v1.2.3 From 65d4919bd08d9cec55b04288198bb2f6e3666a31 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 11:10:51 -0700 Subject: staging: comedi: addi_apci_1710: remove COMEDI_SUBD_TTLIO define This define exists in hwdrv_APCI1710.c, where it's actually used. Remove the duplicate define. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1710.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 6bfbebeeb20..a142129e7f7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -19,10 +19,6 @@ static void fpu_end(void) #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_APCI1710.c" -#ifndef COMEDI_SUBD_TTLIO -#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ -#endif - static const struct addi_board apci1710_boardtypes[] = { { .pc_DriverName = "apci1710", -- cgit v1.2.3 From 9f4f2c6806851ec67a9d6426c8797c591c5d789d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 11:11:14 -0700 Subject: staging: comedi: addi_apci_1710: add the missing MODULE_* information This driver is missing the MODULE_* information. Add the standard comedi info. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1710.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index a142129e7f7..66dd94c2690 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -145,3 +145,7 @@ static struct pci_driver apci1710_pci_driver = { .remove = __devexit_p(apci1710_pci_remove), }; module_comedi_pci_driver(apci1710_driver, apci1710_pci_driver); + +MODULE_AUTHOR("Comedi http://www.comedi.org"); +MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From b7703d7d4866424a99fc80efa070842f51b9fe66 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 18:34:35 +0000 Subject: staging: comedi: jr3_pci: use auto_attach method This driver does not need to support manual attachment of supported PCI devices. Replace the `attach()` hook (`jr3_pci_attach()`) with an `auto_attach()` hook (`jr3_pci_auto_attach()`). This will be called via `comedi_pci_auto_config()` at PCI probe time. This driver no longer increments the PCI reference count during attachment, so remove the call to `pci_dev_put()` when detaching the device. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/jr3_pci.c | 91 ++++++++++---------------------- 1 file changed, 28 insertions(+), 63 deletions(-) diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 68400f13af0..235ec8d2202 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -744,17 +744,14 @@ static void jr3_pci_poll_dev(unsigned long data) add_timer(&devpriv->timer); } -static int jr3_pci_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { - int result = 0; - struct pci_dev *card = NULL; - int opt_bus, opt_slot, i; + int result; + struct pci_dev *card = comedi_to_pci_dev(dev); + int i; struct jr3_pci_dev_private *devpriv; - opt_bus = it->options[0]; - opt_slot = it->options[1]; - if (sizeof(struct jr3_channel) != 0xc00) { dev_err(dev->class_dev, "sizeof(struct jr3_channel) = %x [expected %x]\n", @@ -767,58 +764,29 @@ static int jr3_pci_attach(struct comedi_device *dev, return -ENOMEM; dev->private = devpriv; - card = NULL; init_timer(&devpriv->timer); - while (1) { - card = pci_get_device(PCI_VENDOR_ID_JR3, PCI_ANY_ID, card); - if (card == NULL) { - /* No card found */ - break; - } else { - switch (card->device) { - case PCI_DEVICE_ID_JR3_1_CHANNEL:{ - devpriv->n_channels = 1; - } - break; - case PCI_DEVICE_ID_JR3_1_CHANNEL_NEW:{ - devpriv->n_channels = 1; - } - break; - case PCI_DEVICE_ID_JR3_2_CHANNEL:{ - devpriv->n_channels = 2; - } - break; - case PCI_DEVICE_ID_JR3_3_CHANNEL:{ - devpriv->n_channels = 3; - } - break; - case PCI_DEVICE_ID_JR3_4_CHANNEL:{ - devpriv->n_channels = 4; - } - break; - default:{ - devpriv->n_channels = 0; - } - } - if (devpriv->n_channels >= 1) { - if (opt_bus == 0 && opt_slot == 0) { - /* Take first available card */ - break; - } else if (opt_bus == card->bus->number && - opt_slot == PCI_SLOT(card->devfn)) { - /* Take requested card */ - break; - } - } - } - } - if (!card) { - dev_err(dev->class_dev, "no jr3_pci found\n"); - return -EIO; - } else { - devpriv->pci_dev = card; - dev->board_name = "jr3_pci"; + switch (card->device) { + case PCI_DEVICE_ID_JR3_1_CHANNEL: + case PCI_DEVICE_ID_JR3_1_CHANNEL_NEW: + devpriv->n_channels = 1; + break; + case PCI_DEVICE_ID_JR3_2_CHANNEL: + devpriv->n_channels = 2; + break; + case PCI_DEVICE_ID_JR3_3_CHANNEL: + devpriv->n_channels = 3; + break; + case PCI_DEVICE_ID_JR3_4_CHANNEL: + devpriv->n_channels = 4; + break; + default: + dev_err(dev->class_dev, "jr3_pci: pci %s not supported\n", + pci_name(card)); + return -EINVAL; + break; } + devpriv->pci_dev = card; + dev->board_name = "jr3_pci"; result = comedi_pci_enable(card, "jr3_pci"); if (result < 0) @@ -892,7 +860,7 @@ static int jr3_pci_attach(struct comedi_device *dev, dev_dbg(dev->class_dev, "Firmare load %d\n", result); if (result < 0) - goto out; + return result; /* * TODO: use firmware to load preferred offset tables. Suggested * format: @@ -925,7 +893,6 @@ static int jr3_pci_attach(struct comedi_device *dev, devpriv->timer.expires = jiffies + msecs_to_jiffies(1000); add_timer(&devpriv->timer); -out: return result; } @@ -945,15 +912,13 @@ static void jr3_pci_detach(struct comedi_device *dev) iounmap(devpriv->iobase); if (devpriv->pci_enabled) comedi_pci_disable(devpriv->pci_dev); - if (devpriv->pci_dev) - pci_dev_put(devpriv->pci_dev); } } static struct comedi_driver jr3_pci_driver = { .driver_name = "jr3_pci", .module = THIS_MODULE, - .attach = jr3_pci_attach, + .auto_attach = jr3_pci_auto_attach, .detach = jr3_pci_detach, }; -- cgit v1.2.3 From 6af0cf7678de21ca4d20980debbfc852640055ae Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 18:34:36 +0000 Subject: staging: comedi: jr3_pci: rename card variable The local variable `card` in `jr3_pci_auto_attach()` is used to point to the PCI device `struct pci_dev`. Rename it to `pcidev`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/jr3_pci.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 235ec8d2202..fe48d88b03d 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -748,7 +748,7 @@ static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, unsigned long context_unused) { int result; - struct pci_dev *card = comedi_to_pci_dev(dev); + struct pci_dev *pcidev = comedi_to_pci_dev(dev); int i; struct jr3_pci_dev_private *devpriv; @@ -765,7 +765,7 @@ static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, dev->private = devpriv; init_timer(&devpriv->timer); - switch (card->device) { + switch (pcidev->device) { case PCI_DEVICE_ID_JR3_1_CHANNEL: case PCI_DEVICE_ID_JR3_1_CHANNEL_NEW: devpriv->n_channels = 1; @@ -781,19 +781,19 @@ static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, break; default: dev_err(dev->class_dev, "jr3_pci: pci %s not supported\n", - pci_name(card)); + pci_name(pcidev)); return -EINVAL; break; } - devpriv->pci_dev = card; + devpriv->pci_dev = pcidev; dev->board_name = "jr3_pci"; - result = comedi_pci_enable(card, "jr3_pci"); + result = comedi_pci_enable(pcidev, "jr3_pci"); if (result < 0) return -EIO; devpriv->pci_enabled = 1; - devpriv->iobase = ioremap(pci_resource_start(card, 0), + devpriv->iobase = ioremap(pci_resource_start(pcidev, 0), offsetof(struct jr3_t, channel[devpriv->n_channels])); if (!devpriv->iobase) return -ENOMEM; -- cgit v1.2.3 From 19d6ce544631bd6cc1649696423715c7142e85b8 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 18:34:37 +0000 Subject: staging: comedi: jr3_pci: remove devpriv->pci_dev The `pci_dev` member of `struct jr3_pci_dev_private` is used to point to the `struct pci_dev`. This is redundant as the `struct comedi_device` already has a pointer to the `struct device` within the `struct pci_dev` and there is a convenient inline function, `comedi_to_pci_dev(dev)` that returns a pointer to the `struct pci_dev`. Remove the redundant `pci_dev` member and use alternate ways to get at the `struct pci_dev`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/jr3_pci.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index fe48d88b03d..40a5b7fe3ba 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -59,8 +59,6 @@ Devices: [JR3] PCI force sensor board (jr3_pci) #define PCI_DEVICE_ID_JR3_4_CHANNEL 0x3114 struct jr3_pci_dev_private { - - struct pci_dev *pci_dev; int pci_enabled; struct jr3_t __iomem *iobase; int n_channels; @@ -68,7 +66,6 @@ struct jr3_pci_dev_private { }; struct poll_delay_t { - int min; int max; }; @@ -98,15 +95,15 @@ struct jr3_pci_subdev_private { }; /* Hotplug firmware loading stuff */ -static int comedi_load_firmware(struct comedi_device *dev, char *name, +static int comedi_load_firmware(struct comedi_device *dev, const char *name, int (*cb)(struct comedi_device *dev, const u8 *data, size_t size)) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); int result = 0; const struct firmware *fw; char *firmware_path; static const char *prefix = "comedi/"; - struct jr3_pci_dev_private *devpriv = dev->private; firmware_path = kmalloc(strlen(prefix) + strlen(name) + 1, GFP_KERNEL); if (!firmware_path) { @@ -115,8 +112,7 @@ static int comedi_load_firmware(struct comedi_device *dev, char *name, firmware_path[0] = '\0'; strcat(firmware_path, prefix); strcat(firmware_path, name); - result = request_firmware(&fw, firmware_path, - &devpriv->pci_dev->dev); + result = request_firmware(&fw, firmware_path, &pcidev->dev); if (result == 0) { if (!cb) result = -EINVAL; @@ -785,7 +781,6 @@ static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, return -EINVAL; break; } - devpriv->pci_dev = pcidev; dev->board_name = "jr3_pci"; result = comedi_pci_enable(pcidev, "jr3_pci"); @@ -899,6 +894,7 @@ static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, static void jr3_pci_detach(struct comedi_device *dev) { int i; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct jr3_pci_dev_private *devpriv = dev->private; if (devpriv) { @@ -911,7 +907,7 @@ static void jr3_pci_detach(struct comedi_device *dev) if (devpriv->iobase) iounmap(devpriv->iobase); if (devpriv->pci_enabled) - comedi_pci_disable(devpriv->pci_dev); + comedi_pci_disable(pcidev); } } -- cgit v1.2.3 From ed610aa04c283e1dbe4de769a58fec27b1259d3d Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 18:34:38 +0000 Subject: staging: comedi: jr3_pci: remove devpriv->pci_enabled The `pci_enabled` member of `struct jr3_pci_dev_private` is used to indicate whether the call to `comedi_pci_enable()` was successful. The 'detach' routine `jr3_pci_detach()` uses this to decide whether to call `comedi_pci_disable()`. The `iobase` member of `struct comedi_device` is not used by this driver so it can be used for the same purpose. Remove the `pci_enabled` member and use the spare `dev->iobase` instead. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/jr3_pci.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 40a5b7fe3ba..af3209977a8 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -59,7 +59,6 @@ Devices: [JR3] PCI force sensor board (jr3_pci) #define PCI_DEVICE_ID_JR3_4_CHANNEL 0x3114 struct jr3_pci_dev_private { - int pci_enabled; struct jr3_t __iomem *iobase; int n_channels; struct timer_list timer; @@ -787,7 +786,7 @@ static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, if (result < 0) return -EIO; - devpriv->pci_enabled = 1; + dev->iobase = 1; /* the "detach" needs this */ devpriv->iobase = ioremap(pci_resource_start(pcidev, 0), offsetof(struct jr3_t, channel[devpriv->n_channels])); if (!devpriv->iobase) @@ -906,7 +905,7 @@ static void jr3_pci_detach(struct comedi_device *dev) } if (devpriv->iobase) iounmap(devpriv->iobase); - if (devpriv->pci_enabled) + if (dev->iobase) comedi_pci_disable(pcidev); } } -- cgit v1.2.3 From a1d16659538a5e9788524322a601382d5e14f08a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 18:34:39 +0000 Subject: staging: comedi: jr3_pci: remove noisy printk This driver seems to generate a lot of printk output every time the driver polls the device. This may have been useful during development but shouldn't be used in production. Just get rid of it all. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/jr3_pci.c | 63 -------------------------------- 1 file changed, 63 deletions(-) diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index af3209977a8..9035e84029f 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -192,10 +192,6 @@ struct six_axis_t { static void set_full_scales(struct jr3_channel __iomem *channel, struct six_axis_t full_scale) { - printk("%d %d %d %d %d %d\n", - full_scale.fx, - full_scale.fy, - full_scale.fz, full_scale.mx, full_scale.my, full_scale.mz); set_s16(&channel->full_scale.fx, full_scale.fx); set_s16(&channel->full_scale.fy, full_scale.fy); set_s16(&channel->full_scale.fz, full_scale.fz); @@ -491,7 +487,6 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s) int errors = get_u16(&channel->errors); if (errors != p->errors) { - printk("Errors: %x -> %x\n", p->errors, errors); p->errors = errors; } if (errors & (watch_dog | watch_dog2 | sensor_change)) { @@ -531,14 +526,6 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s) p->serial_no = get_u16(&channel->serial_no); - printk - ("Setting transform for channel %d\n", - p->channel_no); - printk("Sensor Model = %i\n", - p->model_no); - printk("Sensor Serial = %i\n", - p->serial_no); - /* Transformation all zeros */ for (i = 0; i < ARRAY_SIZE(transf.link); i++) { transf.link[i].link_type = @@ -555,9 +542,6 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s) } break; case state_jr3_init_transform_complete:{ if (!is_complete(channel)) { - printk - ("state_jr3_init_transform_complete complete = %d\n", - is_complete(channel)); result = poll_delay_min_max(20, 100); } else { /* Set full scale */ @@ -566,26 +550,8 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s) min_full_scale = get_min_full_scales(channel); - printk("Obtained Min. Full Scales:\n"); - printk(KERN_DEBUG "%i ", (min_full_scale).fx); - printk(KERN_CONT "%i ", (min_full_scale).fy); - printk(KERN_CONT "%i ", (min_full_scale).fz); - printk(KERN_CONT "%i ", (min_full_scale).mx); - printk(KERN_CONT "%i ", (min_full_scale).my); - printk(KERN_CONT "%i ", (min_full_scale).mz); - printk(KERN_CONT "\n"); - max_full_scale = get_max_full_scales(channel); - printk("Obtained Max. Full Scales:\n"); - printk(KERN_DEBUG "%i ", (max_full_scale).fx); - printk(KERN_CONT "%i ", (max_full_scale).fy); - printk(KERN_CONT "%i ", (max_full_scale).fz); - printk(KERN_CONT "%i ", (max_full_scale).mx); - printk(KERN_CONT "%i ", (max_full_scale).my); - printk(KERN_CONT "%i ", (max_full_scale).mz); - printk(KERN_CONT "\n"); - set_full_scales(channel, max_full_scale); @@ -597,9 +563,6 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s) break; case state_jr3_init_set_full_scale_complete:{ if (!is_complete(channel)) { - printk - ("state_jr3_init_set_full_scale_complete complete = %d\n", - is_complete(channel)); result = poll_delay_min_max(20, 100); } else { struct force_array __iomem *full_scale; @@ -637,20 +600,6 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s) p->range[8].range.min = 0; p->range[8].range.max = 65535; - { - int i; - for (i = 0; i < 9; i++) { - printk("%d %d - %d\n", - i, - p-> - range[i].range. - min, - p-> - range[i].range. - max); - } - } - use_offset(channel, 0); p->state = state_jr3_init_use_offset_complete; @@ -660,20 +609,8 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s) break; case state_jr3_init_use_offset_complete:{ if (!is_complete(channel)) { - printk - ("state_jr3_init_use_offset_complete complete = %d\n", - is_complete(channel)); result = poll_delay_min_max(20, 100); } else { - printk - ("Default offsets %d %d %d %d %d %d\n", - get_s16(&channel->offsets.fx), - get_s16(&channel->offsets.fy), - get_s16(&channel->offsets.fz), - get_s16(&channel->offsets.mx), - get_s16(&channel->offsets.my), - get_s16(&channel->offsets.mz)); - set_s16(&channel->offsets.fx, 0); set_s16(&channel->offsets.fy, 0); set_s16(&channel->offsets.fz, 0); -- cgit v1.2.3 From 10ba619d90c31fe4216590013114ec4c8456e6d4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 18:34:40 +0000 Subject: staging: comedi: jr3_pci: update driver description comment Reformat the comment used to describe the Comedi driver to use the usual block comment style. Update the information reflecting the fact that the driver no longer supports manual attachment of devices via the `COMEDI_DEVCONFIG` ioctl and `attach()` method. Also, in the instructions indicating where to put the firmware file, mention the expected name of the file since the driver requests the firmware file by name. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/jr3_pci.c | 38 +++++++++++++++++--------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 9035e84029f..c5d1d693d0d 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -21,24 +21,26 @@ */ /* -Driver: jr3_pci -Description: JR3/PCI force sensor board -Author: Anders Blomdell -Status: works -Devices: [JR3] PCI force sensor board (jr3_pci) - - The DSP on the board requires initialization code, which can - be loaded by placing it in /lib/firmware/comedi. - The initialization code should be somewhere on the media you got - with your card. One version is available from http://www.comedi.org - in the comedi_nonfree_firmware tarball. - - Configuration options: - [0] - PCI bus number - if bus number and slot number are 0, - then driver search for first unused card - [1] - PCI slot number - -*/ + * Driver: jr3_pci + * Description: JR3/PCI force sensor board + * Author: Anders Blomdell + * Updated: Thu, 01 Nov 2012 17:34:55 +0000 + * Status: works + * Devices: [JR3] PCI force sensor board (jr3_pci) + * + * Configuration options: + * None + * + * Manual configuration of comedi devices is not supported by this + * driver; supported PCI devices are configured as comedi devices + * automatically. + * + * The DSP on the board requires initialization code, which can be + * loaded by placing it in /lib/firmware/comedi. The initialization + * code should be somewhere on the media you got with your card. One + * version is available from http://www.comedi.org in the + * comedi_nonfree_firmware tarball. The file is called "jr3pci.idm". + */ #include "../comedidev.h" -- cgit v1.2.3 From abcdc99f7cb387fdc1d18fb0bc5f50b75a0f2d71 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 1 Nov 2012 18:34:41 +0000 Subject: staging: comedi: jr3_pci: CodingStyle fixes Follow coding style for whitespace, operator placement, use of braces, etc. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/jr3_pci.c | 393 +++++++++++++++---------------- 1 file changed, 188 insertions(+), 205 deletions(-) diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index c5d1d693d0d..364541d0f47 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -154,7 +154,6 @@ static void set_transforms(struct jr3_channel __iomem *channel, num &= 0x000f; /* Make sure that 0 <= num <= 15 */ for (i = 0; i < 8; i++) { - set_u16(&channel->transforms[num].link[i].link_type, transf.link[i].link_type); udelay(1); @@ -266,71 +265,53 @@ static int jr3_pci_ai_insn_read(struct comedi_device *dev, } else { int F = 0; switch (axis) { - case 0:{ - F = get_s16 - (&p->channel->filter - [filter].fx); - } + case 0: + F = get_s16(&p->channel-> + filter[filter].fx); break; - case 1:{ - F = get_s16 - (&p->channel->filter - [filter].fy); - } + case 1: + F = get_s16(&p->channel-> + filter[filter].fy); break; - case 2:{ - F = get_s16 - (&p->channel->filter - [filter].fz); - } + case 2: + F = get_s16(&p->channel-> + filter[filter].fz); break; - case 3:{ - F = get_s16 - (&p->channel->filter - [filter].mx); - } + case 3: + F = get_s16(&p->channel-> + filter[filter].mx); break; - case 4:{ - F = get_s16 - (&p->channel->filter - [filter].my); - } + case 4: + F = get_s16(&p->channel-> + filter[filter].my); break; - case 5:{ - F = get_s16 - (&p->channel->filter - [filter].mz); - } + case 5: + F = get_s16(&p->channel-> + filter[filter].mz); break; - case 6:{ - F = get_s16 - (&p->channel->filter - [filter].v1); - } + case 6: + F = get_s16(&p->channel-> + filter[filter].v1); break; - case 7:{ - F = get_s16 - (&p->channel->filter - [filter].v2); - } + case 7: + F = get_s16(&p->channel-> + filter[filter].v2); break; } data[i] = F + 0x4000; } } else if (channel == 56) { - if (p->state != state_jr3_done) { + if (p->state != state_jr3_done) data[i] = 0; - } else { + else data[i] = - get_u16(&p->channel->model_no); - } + get_u16(&p->channel->model_no); } else if (channel == 57) { - if (p->state != state_jr3_done) { + if (p->state != state_jr3_done) data[i] = 0; - } else { + else data[i] = - get_u16(&p->channel->serial_no); - } + get_u16(&p->channel->serial_no); } } } @@ -361,8 +342,8 @@ static int read_idm_word(const u8 *data, size_t size, int *pos, int result = 0; if (pos && val) { /* Skip over non hex */ - for (; *pos < size && !isxdigit(data[*pos]); (*pos)++) { - } + for (; *pos < size && !isxdigit(data[*pos]); (*pos)++) + ; /* Collect value */ *val = 0; for (; *pos < size; (*pos)++) { @@ -371,8 +352,9 @@ static int read_idm_word(const u8 *data, size_t size, int *pos, if (value >= 0) { result = 1; *val = (*val << 4) + value; - } else + } else { break; + } } } return result; @@ -422,37 +404,38 @@ static int jr3_download_firmware(struct comedi_device *dev, const u8 * data, pos = 0; while (more) { unsigned int count, addr; - more = more - && read_idm_word(data, size, &pos, &count); + more = more && + read_idm_word(data, size, &pos, &count); if (more && count == 0xffff) break; - more = more - && read_idm_word(data, size, &pos, &addr); + more = more && + read_idm_word(data, size, &pos, &addr); dev_dbg(dev->class_dev, "Loading#%d %4.4x bytes at %4.4x\n", i, count, addr); while (more && count > 0) { if (addr & 0x4000) { - /* 16 bit data, never seen in real life!! */ + /* 16 bit data, never seen + * in real life!! */ unsigned int data1; - more = more - && read_idm_word(data, + more = more && + read_idm_word(data, size, &pos, &data1); count--; - /* printk("jr3_data, not tested\n"); */ - /* jr3[addr + 0x20000 * pnum] = data1; */ + /* jr3[addr + 0x20000 * pnum] = + data1; */ } else { /* Download 24 bit program */ unsigned int data1, data2; - more = more - && read_idm_word(data, + more = more && + read_idm_word(data, size, &pos, &data1); - more = more - && read_idm_word(data, size, + more = more && + read_idm_word(data, size, &pos, &data2); count -= 2; @@ -467,7 +450,6 @@ static int jr3_download_firmware(struct comedi_device *dev, const u8 * data, [i].program_high [addr], data2); udelay(1); - } } addr++; @@ -497,142 +479,141 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s) } switch (p->state) { - case state_jr3_poll:{ + case state_jr3_poll: { u16 model_no = get_u16(&channel->model_no); u16 serial_no = get_u16(&channel->serial_no); if ((errors & (watch_dog | watch_dog2)) || model_no == 0 || serial_no == 0) { -/* - * Still no sensor, keep on polling. Since it takes up to 10 seconds - * for offsets to stabilize, polling each second should suffice. - */ + /* + * Still no sensor, keep on polling. + * Since it takes up to 10 seconds + * for offsets to stabilize, polling + * each second should suffice. + */ result = poll_delay_min_max(1000, 2000); } else { p->retries = 0; p->state = - state_jr3_init_wait_for_offset; + state_jr3_init_wait_for_offset; result = poll_delay_min_max(1000, 2000); } } break; - case state_jr3_init_wait_for_offset:{ - p->retries++; - if (p->retries < 10) { - /* Wait for offeset to stabilize (< 10 s according to manual) */ - result = poll_delay_min_max(1000, 2000); - } else { - struct transform_t transf; - - p->model_no = - get_u16(&channel->model_no); - p->serial_no = - get_u16(&channel->serial_no); - - /* Transformation all zeros */ - for (i = 0; i < ARRAY_SIZE(transf.link); i++) { - transf.link[i].link_type = - (enum link_types)0; - transf.link[i].link_amount = 0; - } - - set_transforms(channel, transf, 0); - use_transform(channel, 0); - p->state = - state_jr3_init_transform_complete; - result = poll_delay_min_max(20, 100); /* Allow 20 ms for completion */ + case state_jr3_init_wait_for_offset: + p->retries++; + if (p->retries < 10) { + /* Wait for offeset to stabilize + * (< 10 s according to manual) */ + result = poll_delay_min_max(1000, 2000); + } else { + struct transform_t transf; + + p->model_no = get_u16(&channel->model_no); + p->serial_no = get_u16(&channel->serial_no); + + /* Transformation all zeros */ + for (i = 0; i < ARRAY_SIZE(transf.link); i++) { + transf.link[i].link_type = + (enum link_types)0; + transf.link[i].link_amount = 0; } - } break; - case state_jr3_init_transform_complete:{ - if (!is_complete(channel)) { - result = poll_delay_min_max(20, 100); - } else { - /* Set full scale */ - struct six_axis_t min_full_scale; - struct six_axis_t max_full_scale; - - min_full_scale = - get_min_full_scales(channel); - max_full_scale = - get_max_full_scales(channel); - set_full_scales(channel, - max_full_scale); - p->state = - state_jr3_init_set_full_scale_complete; - result = poll_delay_min_max(20, 100); /* Allow 20 ms for completion */ - } + set_transforms(channel, transf, 0); + use_transform(channel, 0); + p->state = state_jr3_init_transform_complete; + /* Allow 20 ms for completion */ + result = poll_delay_min_max(20, 100); } break; - case state_jr3_init_set_full_scale_complete:{ - if (!is_complete(channel)) { - result = poll_delay_min_max(20, 100); - } else { - struct force_array __iomem *full_scale; - - /* Use ranges in kN or we will overflow arount 2000N! */ - full_scale = &channel->full_scale; - p->range[0].range.min = - -get_s16(&full_scale->fx) * 1000; - p->range[0].range.max = - get_s16(&full_scale->fx) * 1000; - p->range[1].range.min = - -get_s16(&full_scale->fy) * 1000; - p->range[1].range.max = - get_s16(&full_scale->fy) * 1000; - p->range[2].range.min = - -get_s16(&full_scale->fz) * 1000; - p->range[2].range.max = - get_s16(&full_scale->fz) * 1000; - p->range[3].range.min = - -get_s16(&full_scale->mx) * 100; - p->range[3].range.max = - get_s16(&full_scale->mx) * 100; - p->range[4].range.min = - -get_s16(&full_scale->my) * 100; - p->range[4].range.max = - get_s16(&full_scale->my) * 100; - p->range[5].range.min = - -get_s16(&full_scale->mz) * 100; - p->range[5].range.max = - get_s16(&full_scale->mz) * 100; - p->range[6].range.min = -get_s16(&full_scale->v1) * 100; /* ?? */ - p->range[6].range.max = get_s16(&full_scale->v1) * 100; /* ?? */ - p->range[7].range.min = -get_s16(&full_scale->v2) * 100; /* ?? */ - p->range[7].range.max = get_s16(&full_scale->v2) * 100; /* ?? */ - p->range[8].range.min = 0; - p->range[8].range.max = 65535; - - use_offset(channel, 0); - p->state = - state_jr3_init_use_offset_complete; - result = poll_delay_min_max(40, 100); /* Allow 40 ms for completion */ - } + case state_jr3_init_transform_complete: + if (!is_complete(channel)) { + result = poll_delay_min_max(20, 100); + } else { + /* Set full scale */ + struct six_axis_t min_full_scale; + struct six_axis_t max_full_scale; + + min_full_scale = get_min_full_scales(channel); + max_full_scale = get_max_full_scales(channel); + set_full_scales(channel, max_full_scale); + + p->state = + state_jr3_init_set_full_scale_complete; + /* Allow 20 ms for completion */ + result = poll_delay_min_max(20, 100); } break; - case state_jr3_init_use_offset_complete:{ - if (!is_complete(channel)) { - result = poll_delay_min_max(20, 100); - } else { - set_s16(&channel->offsets.fx, 0); - set_s16(&channel->offsets.fy, 0); - set_s16(&channel->offsets.fz, 0); - set_s16(&channel->offsets.mx, 0); - set_s16(&channel->offsets.my, 0); - set_s16(&channel->offsets.mz, 0); - - set_offset(channel); - - p->state = state_jr3_done; - } + case state_jr3_init_set_full_scale_complete: + if (!is_complete(channel)) { + result = poll_delay_min_max(20, 100); + } else { + struct force_array __iomem *full_scale; + + /* Use ranges in kN or we will + * overflow around 2000N! */ + full_scale = &channel->full_scale; + p->range[0].range.min = + -get_s16(&full_scale->fx) * 1000; + p->range[0].range.max = + get_s16(&full_scale->fx) * 1000; + p->range[1].range.min = + -get_s16(&full_scale->fy) * 1000; + p->range[1].range.max = + get_s16(&full_scale->fy) * 1000; + p->range[2].range.min = + -get_s16(&full_scale->fz) * 1000; + p->range[2].range.max = + get_s16(&full_scale->fz) * 1000; + p->range[3].range.min = + -get_s16(&full_scale->mx) * 100; + p->range[3].range.max = + get_s16(&full_scale->mx) * 100; + p->range[4].range.min = + -get_s16(&full_scale->my) * 100; + p->range[4].range.max = + get_s16(&full_scale->my) * 100; + p->range[5].range.min = + -get_s16(&full_scale->mz) * 100; + p->range[5].range.max = + get_s16(&full_scale->mz) * 100; /* ?? */ + p->range[6].range.min = + -get_s16(&full_scale->v1) * 100;/* ?? */ + p->range[6].range.max = + get_s16(&full_scale->v1) * 100; /* ?? */ + p->range[7].range.min = + -get_s16(&full_scale->v2) * 100;/* ?? */ + p->range[7].range.max = + get_s16(&full_scale->v2) * 100; /* ?? */ + p->range[8].range.min = 0; + p->range[8].range.max = 65535; + + use_offset(channel, 0); + p->state = state_jr3_init_use_offset_complete; + /* Allow 40 ms for completion */ + result = poll_delay_min_max(40, 100); } break; - case state_jr3_done:{ - poll_delay_min_max(10000, 20000); + case state_jr3_init_use_offset_complete: + if (!is_complete(channel)) { + result = poll_delay_min_max(20, 100); + } else { + set_s16(&channel->offsets.fx, 0); + set_s16(&channel->offsets.fy, 0); + set_s16(&channel->offsets.fz, 0); + set_s16(&channel->offsets.mx, 0); + set_s16(&channel->offsets.my, 0); + set_s16(&channel->offsets.mz, 0); + + set_offset(channel); + + p->state = state_jr3_done; } break; - default:{ - poll_delay_min_max(1000, 2000); - } + case state_jr3_done: + poll_delay_min_max(10000, 20000); + break; + default: + poll_delay_min_max(1000, 2000); break; } } @@ -654,22 +635,21 @@ static void jr3_pci_poll_dev(unsigned long data) /* Poll all channels that are ready to be polled */ for (i = 0; i < devpriv->n_channels; i++) { struct jr3_pci_subdev_private *subdevpriv = - dev->subdevices[i].private; + dev->subdevices[i].private; if (now > subdevpriv->next_time_min) { struct poll_delay_t sub_delay; sub_delay = jr3_pci_poll_subdevice(&dev->subdevices[i]); subdevpriv->next_time_min = - jiffies + msecs_to_jiffies(sub_delay.min); + jiffies + msecs_to_jiffies(sub_delay.min); subdevpriv->next_time_max = - jiffies + msecs_to_jiffies(sub_delay.max); - if (sub_delay.max && sub_delay.max < delay) { -/* -* Wake up as late as possible -> poll as many channels as possible -* at once -*/ + jiffies + msecs_to_jiffies(sub_delay.max); + if (sub_delay.max && sub_delay.max < delay) + /* + * Wake up as late as possible -> + * poll as many channels as possible at once. + */ delay = sub_delay.max; - } } } spin_unlock_irqrestore(&dev->spinlock, flags); @@ -727,7 +707,8 @@ static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, dev->iobase = 1; /* the "detach" needs this */ devpriv->iobase = ioremap(pci_resource_start(pcidev, 0), - offsetof(struct jr3_t, channel[devpriv->n_channels])); + offsetof(struct jr3_t, + channel[devpriv->n_channels])); if (!devpriv->iobase) return -ENOMEM; @@ -742,7 +723,8 @@ static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, dev->subdevices[i].n_chan = 8 * 7 + 2; dev->subdevices[i].insn_read = jr3_pci_ai_insn_read; dev->subdevices[i].private = - kzalloc(sizeof(struct jr3_pci_subdev_private), GFP_KERNEL); + kzalloc(sizeof(struct jr3_pci_subdev_private), + GFP_KERNEL); if (dev->subdevices[i].private) { struct jr3_pci_subdev_private *p; int j; @@ -772,15 +754,15 @@ static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, p->range[8].range.max = 65536; p->range_table_list[56] = - (struct comedi_lrange *)&p->range[8]; + (struct comedi_lrange *)&p->range[8]; p->range_table_list[57] = - (struct comedi_lrange *)&p->range[8]; + (struct comedi_lrange *)&p->range[8]; p->maxdata_list[56] = 0xffff; p->maxdata_list[57] = 0xffff; /* Channel specific range and maxdata */ dev->subdevices[i].range_table = NULL; dev->subdevices[i].range_table_list = - p->range_table_list; + p->range_table_list; dev->subdevices[i].maxdata = 0; dev->subdevices[i].maxdata_list = p->maxdata_list; } @@ -794,18 +776,19 @@ static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, if (result < 0) return result; -/* - * TODO: use firmware to load preferred offset tables. Suggested - * format: - * model serial Fx Fy Fz Mx My Mz\n - * - * comedi_load_firmware(dev, "jr3_offsets_table", jr3_download_firmware); - */ + /* + * TODO: use firmware to load preferred offset tables. Suggested + * format: + * model serial Fx Fy Fz Mx My Mz\n + * + * comedi_load_firmware(dev, "jr3_offsets_table", + * jr3_download_firmware); + */ -/* - * It takes a few milliseconds for software to settle as much as we - * can read firmware version - */ + /* + * It takes a few milliseconds for software to settle as much as we + * can read firmware version + */ msleep_interruptible(25); for (i = 0; i < 0x18; i++) { dev_dbg(dev->class_dev, "%c\n", -- cgit v1.2.3 From bf779746f928de99eba84de0a72a5bbfa87ca680 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:45 +0100 Subject: perf tests: Add attr record basic test Adding test to validate perf_event_attr data for command: 'record' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-5-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/base-record | 40 +++++++++++++++++++++++++++++++++ tools/perf/tests/attr/test-record-basic | 5 +++++ 2 files changed, 45 insertions(+) create mode 100644 tools/perf/tests/attr/base-record create mode 100644 tools/perf/tests/attr/test-record-basic diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record new file mode 100644 index 00000000000..07beef57855 --- /dev/null +++ b/tools/perf/tests/attr/base-record @@ -0,0 +1,40 @@ +[event] +fd=1 +group_fd=-1 +flags=0 +type=0|1 +size=96 +config=0 +sample_period=4000 +sample_type=263 +read_format=7 +disabled=1 +inherit=1 +pinned=0 +exclusive=0 +exclude_user=0 +exclude_kernel=0 +exclude_hv=0 +exclude_idle=0 +mmap=1 +comm=1 +freq=1 +inherit_stat=0 +enable_on_exec=1 +task=0 +watermask=0 +precise_ip=0 +mmap_data=0 +sample_id_all=1 +exclude_host=0 +exclude_guest=1 +exclude_callchain_kernel=0 +exclude_callchain_user=0 +wakeup_events=0 +bp_type=0 +config1=0 +config2=0 +branch_sample_type=0 +sample_regs_user=0 +sample_stack_user=0 +optional=0 diff --git a/tools/perf/tests/attr/test-record-basic b/tools/perf/tests/attr/test-record-basic new file mode 100644 index 00000000000..55c0428370c --- /dev/null +++ b/tools/perf/tests/attr/test-record-basic @@ -0,0 +1,5 @@ +[config] +command = record +args = kill >/dev/null 2>&1 + +[event:base-record] -- cgit v1.2.3 From d898b241215daf6f2e654b32ebb8341bffc98cc5 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:02:05 +0100 Subject: perf tests: Add attr tests under builtin test command The test attr suite is run only if it's run under perf source directory, or tests are found in installed path. Otherwise tests are omitted (notification is displayed) and finished as successful. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-25-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 9 +++++++++ tools/perf/perf.h | 1 + tools/perf/tests/attr.c | 35 +++++++++++++++++++++++++++++++++++ tools/perf/tests/builtin-test.c | 4 ++++ 4 files changed, 49 insertions(+) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 1da87a30c73..4ffcd02404f 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -898,6 +898,11 @@ $(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS '-DPREFIX="$(prefix_SQ)"' \ $< +$(OUTPUT)tests/attr.o: tests/attr.c $(OUTPUT)PERF-CFLAGS + $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ + '-DBINDIR="$(bindir_SQ)"' \ + $< + $(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< @@ -1062,6 +1067,10 @@ install: all try-install-man $(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d' $(INSTALL) bash_completion '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf' + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests' + $(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests' + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr' + $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr' install-python_ext: $(PYTHON_WORD) util/setup.py --quiet install --root='/$(DESTDIR_SQ)' diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 00472646b3b..054182e41dc 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -178,6 +178,7 @@ extern bool test_attr__enabled; void test_attr__init(void); void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, int fd, int group_fd, unsigned long flags); +int test_attr__run(void); static inline int sys_perf_event_open(struct perf_event_attr *attr, diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index 55e9a873a5c..aacad82634c 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -26,9 +26,12 @@ #include #include "../perf.h" #include "util.h" +#include "exec_cmd.h" #define ENV "PERF_TEST_ATTR" +extern int verbose; + bool test_attr__enabled; static char *dir; @@ -138,3 +141,35 @@ void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, errno = errno_saved; } + +static int run_dir(const char *d, const char *perf) +{ + char cmd[3*PATH_MAX]; + + snprintf(cmd, 3*PATH_MAX, "python %s/attr.py -d %s/attr/ -p %s %s", + d, d, perf, verbose ? "-v" : ""); + + return system(cmd); +} + +int test_attr__run(void) +{ + struct stat st; + char path_perf[PATH_MAX]; + char path_dir[PATH_MAX]; + + /* First try developement tree tests. */ + if (!lstat("./tests", &st)) + return run_dir("./tests", "./perf"); + + /* Then installed path. */ + snprintf(path_dir, PATH_MAX, "%s/tests", perf_exec_path()); + snprintf(path_perf, PATH_MAX, "%s/perf", BINDIR); + + if (!lstat(path_dir, &st) && + !lstat(path_perf, &st)) + return run_dir(path_dir, path_perf); + + fprintf(stderr, " (ommitted)"); + return 0; +} diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index f6c642415c4..1aa9e992704 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -1454,6 +1454,10 @@ static struct test { .desc = "Generate and check syscalls:sys_enter_open event fields", .func = test__syscall_open_tp_fields, }, + { + .desc = "struct perf_event_attr setup", + .func = test_attr__run, + }, { .func = NULL, }, -- cgit v1.2.3 From 4f59de0bc6a545d730c054e765cf3e7de1f3cf4f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:46 +0100 Subject: perf tests: Add attr record group test Adding test to validate perf_event_attr data for command: 'record --group -e cycles,instructions' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-6-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-group | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-group diff --git a/tools/perf/tests/attr/test-record-group b/tools/perf/tests/attr/test-record-group new file mode 100644 index 00000000000..b945f770dc9 --- /dev/null +++ b/tools/perf/tests/attr/test-record-group @@ -0,0 +1,17 @@ +[config] +command = record +args = --group -e cycles,instructions kill >/dev/null 2>&1 + +[event-1:base-record] +fd=1 +group_fd=-1 +sample_type=327 + +[event-2:base-record] +fd=2 +group_fd=1 +config=1 +sample_type=327 +mmap=0 +comm=0 +enable_on_exec=0 -- cgit v1.2.3 From 76062f61ff934ac9f22183c10494228852d26d47 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:47 +0100 Subject: perf tests: Add attr record event syntax group test Adding test to validate perf_event_attr data for command: 'record group -e {cycles,instructions}' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-7-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-group1 | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-group1 diff --git a/tools/perf/tests/attr/test-record-group1 b/tools/perf/tests/attr/test-record-group1 new file mode 100644 index 00000000000..39bf8609538 --- /dev/null +++ b/tools/perf/tests/attr/test-record-group1 @@ -0,0 +1,20 @@ +[config] +command = record +args = -e '{cycles,instructions}' kill >/tmp/krava 2>&1 + +[event-1:base-record] +fd=1 +group_fd=-1 +sample_type=327 + +[event-2:base-record] +fd=2 +group_fd=1 +type=0 +config=1 +sample_type=327 +mmap=0 +comm=0 +# TODO this is disabled for --group option, enabled otherwise +# check why.. +enable_on_exec=1 -- cgit v1.2.3 From 44cfcf4cc6bcb67a01046f7f5c88187d1dafa775 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:48 +0100 Subject: perf tests: Add attr record freq test Adding test to validate perf_event_attr data for command: 'record -F 100' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-8-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-freq | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-freq diff --git a/tools/perf/tests/attr/test-record-freq b/tools/perf/tests/attr/test-record-freq new file mode 100644 index 00000000000..600d0f8f258 --- /dev/null +++ b/tools/perf/tests/attr/test-record-freq @@ -0,0 +1,6 @@ +[config] +command = record +args = -F 100 kill >/dev/null 2>&1 + +[event:base-record] +sample_period=100 -- cgit v1.2.3 From a0f25be079ac10631e8e3a84a2fa8fb55c1e2a7f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:49 +0100 Subject: perf tests: Add attr record count test Adding test to validate perf_event_attr data for command: 'record -c 123' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-9-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-count | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-count diff --git a/tools/perf/tests/attr/test-record-count b/tools/perf/tests/attr/test-record-count new file mode 100644 index 00000000000..2f841de56f6 --- /dev/null +++ b/tools/perf/tests/attr/test-record-count @@ -0,0 +1,8 @@ +[config] +command = record +args = -c 123 kill >/dev/null 2>&1 + +[event:base-record] +sample_period=123 +sample_type=7 +freq=0 -- cgit v1.2.3 From 8b96829468123431f925223f94a62b3372d8fd5e Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:50 +0100 Subject: perf tests: Add attr record graph test Adding tests to validate perf_event_attr data for commands: 'record -g --' 'record -g fp 'record -g dwarf Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-10-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-graph-default | 6 ++++++ tools/perf/tests/attr/test-record-graph-dwarf | 10 ++++++++++ tools/perf/tests/attr/test-record-graph-fp | 6 ++++++ 3 files changed, 22 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-graph-default create mode 100644 tools/perf/tests/attr/test-record-graph-dwarf create mode 100644 tools/perf/tests/attr/test-record-graph-fp diff --git a/tools/perf/tests/attr/test-record-graph-default b/tools/perf/tests/attr/test-record-graph-default new file mode 100644 index 00000000000..833d1849d76 --- /dev/null +++ b/tools/perf/tests/attr/test-record-graph-default @@ -0,0 +1,6 @@ +[config] +command = record +args = -g -- kill >/dev/null 2>&1 + +[event:base-record] +sample_type=295 diff --git a/tools/perf/tests/attr/test-record-graph-dwarf b/tools/perf/tests/attr/test-record-graph-dwarf new file mode 100644 index 00000000000..e93e082f520 --- /dev/null +++ b/tools/perf/tests/attr/test-record-graph-dwarf @@ -0,0 +1,10 @@ +[config] +command = record +args = -g dwarf -- kill >/dev/null 2>&1 + +[event:base-record] +sample_type=12583 +exclude_callchain_user=1 +sample_stack_user=8192 +# TODO different for each arch, no support for that now +sample_regs_user=* diff --git a/tools/perf/tests/attr/test-record-graph-fp b/tools/perf/tests/attr/test-record-graph-fp new file mode 100644 index 00000000000..7cef3743f03 --- /dev/null +++ b/tools/perf/tests/attr/test-record-graph-fp @@ -0,0 +1,6 @@ +[config] +command = record +args = -g fp kill >/dev/null 2>&1 + +[event:base-record] +sample_type=295 -- cgit v1.2.3 From da98f8df49eb799b37587eb4a13ea7a1a9f9e47c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:51 +0100 Subject: perf tests: Add attr record period test Adding test to validate perf_event_attr data for command: 'record -c 100 -P' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-11-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-period | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-period diff --git a/tools/perf/tests/attr/test-record-period b/tools/perf/tests/attr/test-record-period new file mode 100644 index 00000000000..8abc5314fc5 --- /dev/null +++ b/tools/perf/tests/attr/test-record-period @@ -0,0 +1,7 @@ +[config] +command = record +args = -c 100 -P kill >/dev/null 2>&1 + +[event:base-record] +sample_period=100 +freq=0 -- cgit v1.2.3 From 55adeee3aaf745cc8b4e7c5976afbab95bde5697 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:52 +0100 Subject: perf tests: Add attr record no samples test Adding test to validate perf_event_attr data for command: 'record -n' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-12-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-no-samples | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-no-samples diff --git a/tools/perf/tests/attr/test-record-no-samples b/tools/perf/tests/attr/test-record-no-samples new file mode 100644 index 00000000000..d0141b2418b --- /dev/null +++ b/tools/perf/tests/attr/test-record-no-samples @@ -0,0 +1,6 @@ +[config] +command = record +args = -n kill >/dev/null 2>&1 + +[event:base-record] +sample_period=0 -- cgit v1.2.3 From 0a3021c56b81eb3202a506e4d85cb8d99052f28f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:53 +0100 Subject: perf tests: Add attr record no-inherit test Adding test to validate perf_event_attr data for command: 'record -i' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-13-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-no-inherit | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-no-inherit diff --git a/tools/perf/tests/attr/test-record-no-inherit b/tools/perf/tests/attr/test-record-no-inherit new file mode 100644 index 00000000000..9079a25cd64 --- /dev/null +++ b/tools/perf/tests/attr/test-record-no-inherit @@ -0,0 +1,7 @@ +[config] +command = record +args = -i kill >/dev/null 2>&1 + +[event:base-record] +sample_type=259 +inherit=0 -- cgit v1.2.3 From 9eaee2cdcf9ead20f234b15ed26f82a96a4fa8fb Mon Sep 17 00:00:00 2001 From: "Lan,Tianyu" Date: Thu, 1 Nov 2012 22:45:30 +0100 Subject: PM / QoS: Fix a free error in the dev_pm_qos_constraints_destroy() Free a wrong point to struct dev_pm_qos->latency which suppose to be the point to struct dev_pm_qos. The patch is to fix the issue. Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/base/power/qos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 3a7687ae5a4..31d3f4842b9 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -253,7 +253,7 @@ void dev_pm_qos_constraints_destroy(struct device *dev) spin_unlock_irq(&dev->power.lock); kfree(c->notifiers); - kfree(c); + kfree(qos); out: mutex_unlock(&dev_pm_qos_mtx); -- cgit v1.2.3 From fad109452e0562e896ee0ede27552931c761b0ad Mon Sep 17 00:00:00 2001 From: Kumar Amit Mehta Date: Fri, 2 Nov 2012 07:28:00 +0000 Subject: staging: iio: adc: ad7280a.c: fixed macro coding style remove unnecessary semicolon from the macro definition Signed-off-by: Kumar Amit Mehta Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7280a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c index cfc39a70312..e7cb3b2fe67 100644 --- a/drivers/staging/iio/adc/ad7280a.c +++ b/drivers/staging/iio/adc/ad7280a.c @@ -117,7 +117,7 @@ */ #define POLYNOM 0x2F #define POLYNOM_ORDER 8 -#define HIGHBIT 1 << (POLYNOM_ORDER - 1); +#define HIGHBIT (1 << (POLYNOM_ORDER - 1)) struct ad7280_state { struct spi_device *spi; -- cgit v1.2.3 From 8f1b7eb11422d28fbc7432f0dee2f97aead09417 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 22 Oct 2012 12:15:00 +0100 Subject: iio: Do not accept multiple '.' in fixed point numbers Currently when parsing a fix-point number we silently skip any additional '.' found in the string. E.g. '1.2.3.4' gets parsed as '1.234'. This patch disallows this and returns an error if more than one '.' is encountered. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 37650a72b31..0994239361b 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -454,7 +454,7 @@ static ssize_t iio_write_channel_info(struct device *dev, break; else return -EINVAL; - } else if (*buf == '.') { + } else if (*buf == '.' && integer_part) { integer_part = false; } else { return -EINVAL; -- cgit v1.2.3 From 02330acda7ef88865e62e2763df2cdd735607cb4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 22 Oct 2012 12:15:00 +0100 Subject: iio: Reject trailing garbage when parsing fixed point numbers When parsing a fixed point number IIO stops parsing the string once it has reached the last requested decimal place. This means that the remainder of the string is silently accepted regardless, of whether it is part of a valid number or not. This patch modifies the code to scan the whole string and only accept valid numbers. Since fract_mult is 0 after the last decimal place any digit that may follows won't affect the result. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 0994239361b..7bb570b7a4a 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -445,8 +445,6 @@ static ssize_t iio_write_channel_info(struct device *dev, integer = integer*10 + *buf - '0'; else { fract += fract_mult*(*buf - '0'); - if (fract_mult == 1) - break; fract_mult /= 10; } } else if (*buf == '\n') { -- cgit v1.2.3 From ef4f92c064697a66a2a61977dd690af40dc01ff0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 22 Oct 2012 12:15:00 +0100 Subject: iio: Accept a leading '+' sign when parsing fixed point numbers If we encounter a leading '+' sign just skip over it. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 7bb570b7a4a..cd700368eed 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -437,6 +437,8 @@ static ssize_t iio_write_channel_info(struct device *dev, if (buf[0] == '-') { negative = true; buf++; + } else if (buf[0] == '+') { + buf++; } while (*buf) { -- cgit v1.2.3 From 1e45cf3c493cb76618558201a8ef6f3a065f9073 Mon Sep 17 00:00:00 2001 From: Bryan Freed Date: Thu, 25 Oct 2012 00:39:00 +0100 Subject: iio: isl29018: Support suspend and resume. The driver leaves the device in power-down state anyway, so there is nothing to do on suspend. On resume, we just have to make sure the range and ADC values are updated in the device since it may have been powered down in suspend. Signed-off-by: Bryan Freed Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/isl29018.c | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 6ee5567d981..3b03f6f5c40 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -67,6 +67,7 @@ struct isl29018_chip { unsigned int range; unsigned int adc_bit; int prox_scheme; + bool suspended; }; static int isl29018_set_range(struct isl29018_chip *chip, unsigned long range, @@ -368,6 +369,10 @@ static int isl29018_read_raw(struct iio_dev *indio_dev, struct isl29018_chip *chip = iio_priv(indio_dev); mutex_lock(&chip->lock); + if (chip->suspended) { + mutex_unlock(&chip->lock); + return -EBUSY; + } switch (mask) { case IIO_CHAN_INFO_RAW: case IIO_CHAN_INFO_PROCESSED: @@ -561,6 +566,7 @@ static int __devinit isl29018_probe(struct i2c_client *client, chip->lux_scale = 1; chip->range = 1000; chip->adc_bit = 16; + chip->suspended = false; chip->regmap = devm_regmap_init_i2c(client, &isl29018_regmap_config); if (IS_ERR(chip->regmap)) { @@ -603,6 +609,44 @@ static int __devexit isl29018_remove(struct i2c_client *client) return 0; } +#ifdef CONFIG_PM_SLEEP +static int isl29018_suspend(struct device *dev) +{ + struct isl29018_chip *chip = iio_priv(dev_get_drvdata(dev)); + + mutex_lock(&chip->lock); + + /* Since this driver uses only polling commands, we are by default in + * auto shutdown (ie, power-down) mode. + * So we do not have much to do here. + */ + chip->suspended = true; + + mutex_unlock(&chip->lock); + return 0; +} + +static int isl29018_resume(struct device *dev) +{ + struct isl29018_chip *chip = iio_priv(dev_get_drvdata(dev)); + int err; + + mutex_lock(&chip->lock); + + err = isl29018_chip_init(chip); + if (!err) + chip->suspended = false; + + mutex_unlock(&chip->lock); + return err; +} + +static SIMPLE_DEV_PM_OPS(isl29018_pm_ops, isl29018_suspend, isl29018_resume); +#define ISL29018_PM_OPS (&isl29018_pm_ops) +#else +#define ISL29018_PM_OPS NULL +#endif + static const struct i2c_device_id isl29018_id[] = { {"isl29018", 0}, {} @@ -620,6 +664,7 @@ static struct i2c_driver isl29018_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "isl29018", + .pm = ISL29018_PM_OPS, .owner = THIS_MODULE, .of_match_table = isl29018_of_match, }, -- cgit v1.2.3 From 279f1461432ccdec0b98c0bcbe0a8e2c0f6fdda5 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Mon, 22 Oct 2012 14:37:58 -0700 Subject: x86: apic: Use tsc deadline for oneshot when available If the TSC deadline mode is supported, LAPIC timer one-shot mode can be implemented using IA32_TSC_DEADLINE MSR. An interrupt will be generated when the TSC value equals or exceeds the value in the IA32_TSC_DEADLINE MSR. This enables us to skip the APIC calibration during boot. Also, in xapic mode, this enables us to skip the uncached apic access to re-arm the APIC timer. As this timer ticks at the high frequency TSC rate, we use the TSC_DIVISOR (32) to work with the 32-bit restrictions in the clockevent API's to avoid 64-bit divides etc (frequency is u32 and "unsigned long" in the set_next_event(), max_delta limits the next event to 32-bit for 32-bit kernel). Signed-off-by: Suresh Siddha Cc: venki@google.com Cc: len.brown@intel.com Link: http://lkml.kernel.org/r/1350941878.6017.31.camel@sbsiddha-desk.sc.intel.com Signed-off-by: Thomas Gleixner --- Documentation/kernel-parameters.txt | 4 ++ arch/x86/include/asm/msr-index.h | 2 + arch/x86/kernel/apic/apic.c | 73 +++++++++++++++++++++++++++---------- 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 9776f068306..4aa9ca0de63 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1304,6 +1304,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. lapic [X86-32,APIC] Enable the local APIC even if BIOS disabled it. + lapic= [x86,APIC] "notscdeadline" Do not use TSC deadline + value for LAPIC timer one-shot implementation. Default + back to the programmable timer unit in the LAPIC. + lapic_timer_c2_ok [X86,APIC] trust the local apic timer in C2 power state. diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 7f0edceb756..e400cdb2dd6 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -337,6 +337,8 @@ #define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38) #define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39) +#define MSR_IA32_TSC_DEADLINE 0x000006E0 + /* P4/Xeon+ specific */ #define MSR_IA32_MCG_EAX 0x00000180 #define MSR_IA32_MCG_EBX 0x00000181 diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index b17416e72fb..b994cc84aa7 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -90,21 +90,6 @@ EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid); */ DEFINE_EARLY_PER_CPU_READ_MOSTLY(int, x86_cpu_to_logical_apicid, BAD_APICID); -/* - * Knob to control our willingness to enable the local APIC. - * - * +1=force-enable - */ -static int force_enable_local_apic __initdata; -/* - * APIC command line parameters - */ -static int __init parse_lapic(char *arg) -{ - force_enable_local_apic = 1; - return 0; -} -early_param("lapic", parse_lapic); /* Local APIC was disabled by the BIOS and enabled by the kernel */ static int enabled_via_apicbase; @@ -133,6 +118,25 @@ static inline void imcr_apic_to_pic(void) } #endif +/* + * Knob to control our willingness to enable the local APIC. + * + * +1=force-enable + */ +static int force_enable_local_apic __initdata; +/* + * APIC command line parameters + */ +static int __init parse_lapic(char *arg) +{ + if (config_enabled(CONFIG_X86_32) && !arg) + force_enable_local_apic = 1; + else if (!strncmp(arg, "notscdeadline", 13)) + setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER); + return 0; +} +early_param("lapic", parse_lapic); + #ifdef CONFIG_X86_64 static int apic_calibrate_pmtmr __initdata; static __init int setup_apicpmtimer(char *s) @@ -315,6 +319,7 @@ int lapic_get_maxlvt(void) /* Clock divisor */ #define APIC_DIVISOR 16 +#define TSC_DIVISOR 32 /* * This function sets up the local APIC timer, with a timeout of @@ -333,6 +338,9 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) lvtt_value = LOCAL_TIMER_VECTOR; if (!oneshot) lvtt_value |= APIC_LVT_TIMER_PERIODIC; + else if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) + lvtt_value |= APIC_LVT_TIMER_TSCDEADLINE; + if (!lapic_is_integrated()) lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV); @@ -341,6 +349,11 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen) apic_write(APIC_LVTT, lvtt_value); + if (lvtt_value & APIC_LVT_TIMER_TSCDEADLINE) { + printk_once(KERN_DEBUG "TSC deadline timer enabled\n"); + return; + } + /* * Divide PICLK by 16 */ @@ -453,6 +466,16 @@ static int lapic_next_event(unsigned long delta, return 0; } +static int lapic_next_deadline(unsigned long delta, + struct clock_event_device *evt) +{ + u64 tsc; + + rdtscll(tsc); + wrmsrl(MSR_IA32_TSC_DEADLINE, tsc + (((u64) delta) * TSC_DIVISOR)); + return 0; +} + /* * Setup the lapic timer in periodic or oneshot mode */ @@ -533,7 +556,15 @@ static void __cpuinit setup_APIC_timer(void) memcpy(levt, &lapic_clockevent, sizeof(*levt)); levt->cpumask = cpumask_of(smp_processor_id()); - clockevents_register_device(levt); + if (this_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) { + levt->features &= ~(CLOCK_EVT_FEAT_PERIODIC | + CLOCK_EVT_FEAT_DUMMY); + levt->set_next_event = lapic_next_deadline; + clockevents_config_and_register(levt, + (tsc_khz / TSC_DIVISOR) * 1000, + 0xF, ~0UL); + } else + clockevents_register_device(levt); } /* @@ -661,7 +692,9 @@ static int __init calibrate_APIC_clock(void) * in the clockevent structure and return. */ - if (lapic_timer_frequency) { + if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) { + return 0; + } else if (lapic_timer_frequency) { apic_printk(APIC_VERBOSE, "lapic timer already calibrated %d\n", lapic_timer_frequency); lapic_clockevent.mult = div_sc(lapic_timer_frequency/APIC_DIVISOR, @@ -674,6 +707,9 @@ static int __init calibrate_APIC_clock(void) return 0; } + apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n" + "calibrating APIC timer ...\n"); + local_irq_disable(); /* Replace the global interrupt handler */ @@ -811,9 +847,6 @@ void __init setup_boot_APIC_clock(void) return; } - apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n" - "calibrating APIC timer ...\n"); - if (calibrate_APIC_clock()) { /* No broadcast on UP ! */ if (num_possible_cpus() > 1) -- cgit v1.2.3 From 436ede8942ab43474182c6454f420d71f7bb1163 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Nov 2012 13:10:09 +0100 Subject: PM / QoS: Document request manipulation requirement for flags In fact, the callers of dev_pm_qos_add_request(), dev_pm_qos_update_request() and dev_pm_qos_remove_request() for requests of type DEV_PM_QOS_FLAGS need to ensure that the target device is not RPM_SUSPENDED before using any of these functions (or be prepared for the new PM QoS flags to take effect after the device has been resumed). Document this in their kerneldoc comments. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/qos.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 31d3f4842b9..081db2d25da 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -277,6 +277,9 @@ void dev_pm_qos_constraints_destroy(struct device *dev) * -EINVAL in case of wrong parameters, -ENOMEM if there's not enough memory * to allocate for data structures, -ENODEV if the device has just been removed * from the system. + * + * Callers should ensure that the target device is not RPM_SUSPENDED before + * using this function for requests of type DEV_PM_QOS_FLAGS. */ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, enum dev_pm_qos_req_type type, s32 value) @@ -367,6 +370,9 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req, * 0 if the aggregated constraint value has not changed, * -EINVAL in case of wrong parameters, -ENODEV if the device has been * removed from the system + * + * Callers should ensure that the target device is not RPM_SUSPENDED before + * using this function for requests of type DEV_PM_QOS_FLAGS. */ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value) { @@ -398,6 +404,9 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_update_request); * 0 if the aggregated constraint value has not changed, * -EINVAL in case of wrong parameters, -ENODEV if the device has been * removed from the system + * + * Callers should ensure that the target device is not RPM_SUSPENDED before + * using this function for requests of type DEV_PM_QOS_FLAGS. */ int dev_pm_qos_remove_request(struct dev_pm_qos_request *req) { -- cgit v1.2.3 From 213a79656462176b553c6f9cdf96e14313e43bcf Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Fri, 2 Nov 2012 13:02:53 +0000 Subject: ASoC: bells: Add missing select of WM0010 Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index e7b83179aca..fa166bd87ed 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -207,6 +207,7 @@ config SND_SOC_BELLS select SND_SOC_WM5102 select SND_SOC_WM5110 select SND_SOC_WM9081 + select SND_SOC_WM0010 config SND_SOC_LOWLAND tristate "Audio support for Wolfson Lowland" -- cgit v1.2.3 From 4868ce57bfe1810262231dd8fe83fbba0ab59f13 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Fri, 2 Nov 2012 13:02:54 +0000 Subject: ASoC: bells: Select WM1250-EV1 Springbank audio I/O module Ensure we select the WM1250-EV1 as the current software system configuration demands it. Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index fa166bd87ed..3c7c3a59ed3 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -208,6 +208,7 @@ config SND_SOC_BELLS select SND_SOC_WM5110 select SND_SOC_WM9081 select SND_SOC_WM0010 + select SND_SOC_WM1250_EV1 config SND_SOC_LOWLAND tristate "Audio support for Wolfson Lowland" -- cgit v1.2.3 From 60303ed3f4b9332b9aa9bc17c68bc174e7343e2d Mon Sep 17 00:00:00 2001 From: David Sharp Date: Thu, 11 Oct 2012 16:27:52 -0700 Subject: tracing: Reset ring buffer when changing trace_clocks Because the "tsc" clock isn't in nanoseconds, the ring buffer must be reset when changing clocks so that incomparable timestamps don't end up in the same trace. Tested: Confirmed switching clocks resets the trace buffer. Google-Bug-Id: 6980623 Link: http://lkml.kernel.org/r/1349998076-15495-3-git-send-email-dhsharp@google.com Cc: Masami Hiramatsu Signed-off-by: David Sharp Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 88111b08b2c..6ed6013dff2 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4073,6 +4073,14 @@ static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf, if (max_tr.buffer) ring_buffer_set_clock(max_tr.buffer, trace_clocks[i].func); + /* + * New clock may not be consistent with the previous clock. + * Reset the buffer so that it doesn't have incomparable timestamps. + */ + tracing_reset_online_cpus(&global_trace); + if (max_tr.buffer) + tracing_reset_online_cpus(&max_tr); + mutex_unlock(&trace_types_lock); *fpos += cnt; -- cgit v1.2.3 From 50ecf2c3afead23a05227ab004e4212eca08c207 Mon Sep 17 00:00:00 2001 From: Yoshihiro YUNOMAE Date: Thu, 11 Oct 2012 16:27:54 -0700 Subject: ring-buffer: Change unsigned long type of ring_buffer_oldest_event_ts() to u64 ring_buffer_oldest_event_ts() should return a value of u64 type, because ring_buffer_per_cpu->buffer_page->buffer_data_page->time_stamp is u64 type. Link: http://lkml.kernel.org/r/1349998076-15495-5-git-send-email-dhsharp@google.com Cc: Frederic Weisbecker Cc: Vaibhav Nagarnaik Signed-off-by: Yoshihiro YUNOMAE Signed-off-by: David Sharp Signed-off-by: Steven Rostedt --- include/linux/ring_buffer.h | 2 +- kernel/trace/ring_buffer.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 2007375cfe7..519777e3fa0 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -159,7 +159,7 @@ int ring_buffer_record_is_on(struct ring_buffer *buffer); void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu); void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu); -unsigned long ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu); +u64 ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu); unsigned long ring_buffer_bytes_cpu(struct ring_buffer *buffer, int cpu); unsigned long ring_buffer_entries(struct ring_buffer *buffer); unsigned long ring_buffer_overruns(struct ring_buffer *buffer); diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 23a384b9251..3c7834c24e5 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -2932,12 +2932,12 @@ rb_num_of_entries(struct ring_buffer_per_cpu *cpu_buffer) * @buffer: The ring buffer * @cpu: The per CPU buffer to read from. */ -unsigned long ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu) +u64 ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu) { unsigned long flags; struct ring_buffer_per_cpu *cpu_buffer; struct buffer_page *bpage; - unsigned long ret; + u64 ret; if (!cpumask_test_cpu(cpu, buffer->cpumask)) return 0; -- cgit v1.2.3 From 15075cac423d634ddf39dac66f943b3bce847f87 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 3 May 2012 14:57:28 -0400 Subject: tracing: Separate open function from set_event and available_events The open function used by available_events is the same as set_event even though it uses different seq functions. This causes a side effect of writing into available_events clearing all events, even though available_events is suppose to be read only. There's no reason to keep a single function for just the open and have both use different functions for everything else. It is a little confusing and causes strange behavior. Just have each have their own function. Signed-off-by: Steven Rostedt --- kernel/trace/trace_events.c | 46 ++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index dec47e70e25..cb2df3b70f7 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -491,19 +491,6 @@ static void t_stop(struct seq_file *m, void *p) mutex_unlock(&event_mutex); } -static int -ftrace_event_seq_open(struct inode *inode, struct file *file) -{ - const struct seq_operations *seq_ops; - - if ((file->f_mode & FMODE_WRITE) && - (file->f_flags & O_TRUNC)) - ftrace_clear_events(); - - seq_ops = inode->i_private; - return seq_open(file, seq_ops); -} - static ssize_t event_enable_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) @@ -980,6 +967,9 @@ show_header(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) return r; } +static int ftrace_event_avail_open(struct inode *inode, struct file *file); +static int ftrace_event_set_open(struct inode *inode, struct file *file); + static const struct seq_operations show_event_seq_ops = { .start = t_start, .next = t_next, @@ -995,14 +985,14 @@ static const struct seq_operations show_set_event_seq_ops = { }; static const struct file_operations ftrace_avail_fops = { - .open = ftrace_event_seq_open, + .open = ftrace_event_avail_open, .read = seq_read, .llseek = seq_lseek, .release = seq_release, }; static const struct file_operations ftrace_set_event_fops = { - .open = ftrace_event_seq_open, + .open = ftrace_event_set_open, .read = seq_read, .write = ftrace_event_write, .llseek = seq_lseek, @@ -1078,6 +1068,26 @@ static struct dentry *event_trace_events_dir(void) return d_events; } +static int +ftrace_event_avail_open(struct inode *inode, struct file *file) +{ + const struct seq_operations *seq_ops = &show_event_seq_ops; + + return seq_open(file, seq_ops); +} + +static int +ftrace_event_set_open(struct inode *inode, struct file *file) +{ + const struct seq_operations *seq_ops = &show_set_event_seq_ops; + + if ((file->f_mode & FMODE_WRITE) && + (file->f_flags & O_TRUNC)) + ftrace_clear_events(); + + return seq_open(file, seq_ops); +} + static struct dentry * event_subsystem_dir(const char *name, struct dentry *d_events) { @@ -1508,15 +1518,13 @@ static __init int event_trace_init(void) return 0; entry = debugfs_create_file("available_events", 0444, d_tracer, - (void *)&show_event_seq_ops, - &ftrace_avail_fops); + NULL, &ftrace_avail_fops); if (!entry) pr_warning("Could not create debugfs " "'available_events' entry\n"); entry = debugfs_create_file("set_event", 0644, d_tracer, - (void *)&show_set_event_seq_ops, - &ftrace_set_event_fops); + NULL, &ftrace_set_event_fops); if (!entry) pr_warning("Could not create debugfs " "'set_event' entry\n"); -- cgit v1.2.3 From c7b84ecada9a8b7fe3e6c081e70801703897ed5d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 11 May 2012 20:54:53 -0400 Subject: tracing: Remove unused function unregister_tracer() The function register_tracer() is only used by kernel core code, that never needs to remove the tracer. As trace_events have become the main way to add new tracing to the kernel, the need to unregister a tracer has diminished. Remove the unused function unregister_tracer(). If a need arises where we need it, then we can always add it back. Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 26 -------------------------- kernel/trace/trace.h | 1 - 2 files changed, 27 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 6ed6013dff2..d1d8039578a 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -882,32 +882,6 @@ int register_tracer(struct tracer *type) return ret; } -void unregister_tracer(struct tracer *type) -{ - struct tracer **t; - - mutex_lock(&trace_types_lock); - for (t = &trace_types; *t; t = &(*t)->next) { - if (*t == type) - goto found; - } - pr_info("Tracer %s not registered\n", type->name); - goto out; - - found: - *t = (*t)->next; - - if (type == current_trace && tracer_enabled) { - tracer_enabled = 0; - tracing_stop(); - if (current_trace->stop) - current_trace->stop(&global_trace); - current_trace = &nop_trace; - } -out: - mutex_unlock(&trace_types_lock); -} - void tracing_reset(struct trace_array *tr, int cpu) { struct ring_buffer *buffer = tr->buffer; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 839ae003a05..3e8a176f64e 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -410,7 +410,6 @@ void tracing_sched_switch_assign_trace(struct trace_array *tr); void tracing_stop_sched_switch_record(void); void tracing_start_sched_switch_record(void); int register_tracer(struct tracer *type); -void unregister_tracer(struct tracer *type); int is_tracing_stopped(void); enum trace_file_type { TRACE_FILE_LAT_FMT = 1, -- cgit v1.2.3 From 0fb9656d957d79dbe7ae155bb6533b1d465e4a50 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 11 May 2012 14:25:30 -0400 Subject: tracing: Make tracing_enabled be equal to tracing_on The tracing_enabled file has been deprecated as it never was able to serve its purpose well. The tracing_on file has taken over. Instead of having code to keep tracing_enabled, have the tracing_enabled file just set tracing_on, and remove the tracing_enabled variable. This allows us to remove the tracing_enabled file. The reason that the remove is in a different change set and not removed here is in case we find some lonely userspace tool that requires the file to exist. Then the removal patch will get reverted, but this one will not. Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 79 +++---------------------------------------- kernel/trace/trace_selftest.c | 12 ------- 2 files changed, 5 insertions(+), 86 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d1d8039578a..3c9b96aee51 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -205,20 +205,9 @@ static struct trace_array max_tr; static DEFINE_PER_CPU(struct trace_array_cpu, max_tr_data); -/* tracer_enabled is used to toggle activation of a tracer */ -static int tracer_enabled = 1; - -/** - * tracing_is_enabled - return tracer_enabled status - * - * This function is used by other tracers to know the status - * of the tracer_enabled flag. Tracers may use this function - * to know if it should enable their features when starting - * up. See irqsoff tracer for an example (start_irqsoff_tracer). - */ int tracing_is_enabled(void) { - return tracer_enabled; + return tracing_is_on(); } /* @@ -1112,8 +1101,7 @@ void trace_find_cmdline(int pid, char comm[]) void tracing_record_cmdline(struct task_struct *tsk) { - if (atomic_read(&trace_record_cmdline_disabled) || !tracer_enabled || - !tracing_is_on()) + if (atomic_read(&trace_record_cmdline_disabled) || !tracing_is_on()) return; if (!__this_cpu_read(trace_cmdline_save)) @@ -2966,56 +2954,6 @@ static const struct file_operations tracing_saved_cmdlines_fops = { .llseek = generic_file_llseek, }; -static ssize_t -tracing_ctrl_read(struct file *filp, char __user *ubuf, - size_t cnt, loff_t *ppos) -{ - char buf[64]; - int r; - - r = sprintf(buf, "%u\n", tracer_enabled); - return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); -} - -static ssize_t -tracing_ctrl_write(struct file *filp, const char __user *ubuf, - size_t cnt, loff_t *ppos) -{ - struct trace_array *tr = filp->private_data; - unsigned long val; - int ret; - - ret = kstrtoul_from_user(ubuf, cnt, 10, &val); - if (ret) - return ret; - - val = !!val; - - mutex_lock(&trace_types_lock); - if (tracer_enabled ^ val) { - - /* Only need to warn if this is used to change the state */ - WARN_ONCE(1, "tracing_enabled is deprecated. Use tracing_on"); - - if (val) { - tracer_enabled = 1; - if (current_trace->start) - current_trace->start(tr); - tracing_start(); - } else { - tracer_enabled = 0; - tracing_stop(); - if (current_trace->stop) - current_trace->stop(tr); - } - } - mutex_unlock(&trace_types_lock); - - *ppos += cnt; - - return cnt; -} - static ssize_t tracing_set_trace_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) @@ -3469,7 +3407,7 @@ static int tracing_wait_pipe(struct file *filp) return -EINTR; /* - * We block until we read something and tracing is disabled. + * We block until we read something and tracing is enabled. * We still block if tracing is disabled, but we have never * read anything. This allows a user to cat this file, and * then enable tracing. But after we have read something, @@ -3477,7 +3415,7 @@ static int tracing_wait_pipe(struct file *filp) * * iter->pos will be 0 if we haven't read anything. */ - if (!tracer_enabled && iter->pos) + if (tracing_is_enabled() && iter->pos) break; } @@ -4076,13 +4014,6 @@ static const struct file_operations tracing_max_lat_fops = { .llseek = generic_file_llseek, }; -static const struct file_operations tracing_ctrl_fops = { - .open = tracing_open_generic, - .read = tracing_ctrl_read, - .write = tracing_ctrl_write, - .llseek = generic_file_llseek, -}; - static const struct file_operations set_tracer_fops = { .open = tracing_open_generic, .read = tracing_set_trace_read, @@ -4858,7 +4789,7 @@ static __init int tracer_init_debugfs(void) d_tracer = tracing_init_dentry(); trace_create_file("tracing_enabled", 0644, d_tracer, - &global_trace, &tracing_ctrl_fops); + &global_trace, &rb_simple_fops); trace_create_file("trace_options", 0644, d_tracer, NULL, &tracing_iter_fops); diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 2c00a691a54..091b815f7b0 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -320,7 +320,6 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, int (*func)(void)) { int save_ftrace_enabled = ftrace_enabled; - int save_tracer_enabled = tracer_enabled; unsigned long count; char *func_name; int ret; @@ -331,7 +330,6 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, /* enable tracing, and record the filter function */ ftrace_enabled = 1; - tracer_enabled = 1; /* passed in by parameter to fool gcc from optimizing */ func(); @@ -395,7 +393,6 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, out: ftrace_enabled = save_ftrace_enabled; - tracer_enabled = save_tracer_enabled; /* Enable tracing on all functions again */ ftrace_set_global_filter(NULL, 0, 1); @@ -452,7 +449,6 @@ static int trace_selftest_function_recursion(void) { int save_ftrace_enabled = ftrace_enabled; - int save_tracer_enabled = tracer_enabled; char *func_name; int len; int ret; @@ -465,7 +461,6 @@ trace_selftest_function_recursion(void) /* enable tracing, and record the filter function */ ftrace_enabled = 1; - tracer_enabled = 1; /* Handle PPC64 '.' name */ func_name = "*" __stringify(DYN_FTRACE_TEST_NAME); @@ -534,7 +529,6 @@ trace_selftest_function_recursion(void) ret = 0; out: ftrace_enabled = save_ftrace_enabled; - tracer_enabled = save_tracer_enabled; return ret; } @@ -569,7 +563,6 @@ static int trace_selftest_function_regs(void) { int save_ftrace_enabled = ftrace_enabled; - int save_tracer_enabled = tracer_enabled; char *func_name; int len; int ret; @@ -586,7 +579,6 @@ trace_selftest_function_regs(void) /* enable tracing, and record the filter function */ ftrace_enabled = 1; - tracer_enabled = 1; /* Handle PPC64 '.' name */ func_name = "*" __stringify(DYN_FTRACE_TEST_NAME); @@ -648,7 +640,6 @@ trace_selftest_function_regs(void) ret = 0; out: ftrace_enabled = save_ftrace_enabled; - tracer_enabled = save_tracer_enabled; return ret; } @@ -662,7 +653,6 @@ int trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) { int save_ftrace_enabled = ftrace_enabled; - int save_tracer_enabled = tracer_enabled; unsigned long count; int ret; @@ -671,7 +661,6 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) /* start the tracing */ ftrace_enabled = 1; - tracer_enabled = 1; ret = tracer_init(trace, tr); if (ret) { @@ -708,7 +697,6 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) ret = trace_selftest_function_regs(); out: ftrace_enabled = save_ftrace_enabled; - tracer_enabled = save_tracer_enabled; /* kill ftrace totally if we failed */ if (ret) -- cgit v1.2.3 From 02404baf1b47123f1c88c9f9f1f3b00e1e2b10db Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 1 Nov 2012 11:51:40 -0400 Subject: tracing: Remove deprecated tracing_enabled file The tracing_enabled file was used as a quick way to stop tracers, and try to bring down overhead for things like the latency tracers (irqsoff, wakeup, etc). But it didn't work that well. The tracing_on file was created as a really fast way to stop recording into the ftrace ring buffer and can interact with the kernel. That is a tracing_off() call in the kernel can disable recording of events, and then from userspace one could echo 1 into the tracing_on file to continue it. The tracing_enabled function did too much to allow for this. The tracing_on has taken over as a way to start and stop tracing and the tracing_enabled file should not be used. But because of its existance, it still confuses people. Over a year ago the following commit was added: commit 6752ab4a9c30d5411b2dfdb251a3f1cb18aae487 Author: Steven Rostedt Date: Tue Feb 8 13:54:06 2011 -0500 tracing: Deprecate tracing_enabled for tracing_on This commit added a WARN_ON() if the tracing_enabled file's variable was changed. After this was added, only LatencyTop complained, and they soon fixed their tool as there was no reason that LatencyTop should touch this file as it was using the perf ring buffers which this file does not interact with. But since that time no one else has complained about this WARN_ON(). Thus it is safe to assume that this file is no longer needed. Time to get rid of it. Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 3c9b96aee51..d5cbc0d3f20 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4788,9 +4788,6 @@ static __init int tracer_init_debugfs(void) d_tracer = tracing_init_dentry(); - trace_create_file("tracing_enabled", 0644, d_tracer, - &global_trace, &rb_simple_fops); - trace_create_file("trace_options", 0644, d_tracer, NULL, &tracing_iter_fops); -- cgit v1.2.3 From 0d5c6e1c19bab82fad4837108c2902f557d62a04 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 1 Nov 2012 20:54:21 -0400 Subject: tracing: Use irq_work for wake ups and remove *_nowake_*() functions Have the ring buffer commit function use the irq_work infrastructure to wake up any waiters waiting on the ring buffer for new data. The irq_work was created for such a purpose, where doing the actual wake up at the time of adding data is too dangerous, as an event or function trace may be in the midst of the work queue locks and cause deadlocks. The irq_work will either delay the action to the next timer interrupt, or trigger an IPI to itself forcing an interrupt to do the work (in a safe location). With irq_work, all ring buffer commits can safely do wakeups, removing the need for the ring buffer commit "nowake" variants, which were used by events and function tracing. All commits can now safely use the normal commit, and the "nowake" variants can be removed. Cc: Peter Zijlstra Signed-off-by: Steven Rostedt --- include/linux/ftrace_event.h | 14 ++--- include/trace/ftrace.h | 3 +- kernel/trace/Kconfig | 1 + kernel/trace/trace.c | 121 +++++++++++++++++++++----------------- kernel/trace/trace.h | 5 -- kernel/trace/trace_events.c | 2 +- kernel/trace/trace_kprobe.c | 8 +-- kernel/trace/trace_sched_switch.c | 2 +- kernel/trace/trace_selftest.c | 1 + 9 files changed, 84 insertions(+), 73 deletions(-) diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 642928cf57b..b80c8ddfbbd 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -127,13 +127,13 @@ trace_current_buffer_lock_reserve(struct ring_buffer **current_buffer, void trace_current_buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event, unsigned long flags, int pc); -void trace_nowake_buffer_unlock_commit(struct ring_buffer *buffer, - struct ring_buffer_event *event, - unsigned long flags, int pc); -void trace_nowake_buffer_unlock_commit_regs(struct ring_buffer *buffer, - struct ring_buffer_event *event, - unsigned long flags, int pc, - struct pt_regs *regs); +void trace_buffer_unlock_commit(struct ring_buffer *buffer, + struct ring_buffer_event *event, + unsigned long flags, int pc); +void trace_buffer_unlock_commit_regs(struct ring_buffer *buffer, + struct ring_buffer_event *event, + unsigned long flags, int pc, + struct pt_regs *regs); void trace_current_buffer_discard_commit(struct ring_buffer *buffer, struct ring_buffer_event *event); diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index a763888a36f..698f2a89032 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -545,8 +545,7 @@ ftrace_raw_event_##call(void *__data, proto) \ { assign; } \ \ if (!filter_current_check_discard(buffer, event_call, entry, event)) \ - trace_nowake_buffer_unlock_commit(buffer, \ - event, irq_flags, pc); \ + trace_buffer_unlock_commit(buffer, event, irq_flags, pc); \ } /* * The ftrace_test_probe is compiled out, it is only here as a build time check diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 4cea4f41c1d..5d89335a485 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -119,6 +119,7 @@ config TRACING select BINARY_PRINTF select EVENT_TRACING select TRACE_CLOCK + select IRQ_WORK config GENERIC_TRACER bool diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d5cbc0d3f20..37d1c703e3e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,14 @@ static int dummy_set_flag(u32 old_flags, u32 bit, int set) */ static DEFINE_PER_CPU(bool, trace_cmdline_save); +/* + * When a reader is waiting for data, then this variable is + * set to true. + */ +static bool trace_wakeup_needed; + +static struct irq_work trace_work_wakeup; + /* * Kill all tracing for good (never come back). * It is initialized to 1 but will turn to zero if the initialization @@ -329,12 +338,18 @@ unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK | static int trace_stop_count; static DEFINE_RAW_SPINLOCK(tracing_start_lock); -static void wakeup_work_handler(struct work_struct *work) +/** + * trace_wake_up - wake up tasks waiting for trace input + * + * Schedules a delayed work to wake up any task that is blocked on the + * trace_wait queue. These is used with trace_poll for tasks polling the + * trace. + */ +static void trace_wake_up(struct irq_work *work) { - wake_up(&trace_wait); -} + wake_up_all(&trace_wait); -static DECLARE_DELAYED_WORK(wakeup_work, wakeup_work_handler); +} /** * tracing_on - enable tracing buffers @@ -389,22 +404,6 @@ int tracing_is_on(void) } EXPORT_SYMBOL_GPL(tracing_is_on); -/** - * trace_wake_up - wake up tasks waiting for trace input - * - * Schedules a delayed work to wake up any task that is blocked on the - * trace_wait queue. These is used with trace_poll for tasks polling the - * trace. - */ -void trace_wake_up(void) -{ - const unsigned long delay = msecs_to_jiffies(2); - - if (trace_flags & TRACE_ITER_BLOCK) - return; - schedule_delayed_work(&wakeup_work, delay); -} - static int __init set_buf_size(char *str) { unsigned long buf_size; @@ -753,6 +752,40 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) } #endif /* CONFIG_TRACER_MAX_TRACE */ +static void default_wait_pipe(struct trace_iterator *iter) +{ + DEFINE_WAIT(wait); + + prepare_to_wait(&trace_wait, &wait, TASK_INTERRUPTIBLE); + + /* + * The events can happen in critical sections where + * checking a work queue can cause deadlocks. + * After adding a task to the queue, this flag is set + * only to notify events to try to wake up the queue + * using irq_work. + * + * We don't clear it even if the buffer is no longer + * empty. The flag only causes the next event to run + * irq_work to do the work queue wake up. The worse + * that can happen if we race with !trace_empty() is that + * an event will cause an irq_work to try to wake up + * an empty queue. + * + * There's no reason to protect this flag either, as + * the work queue and irq_work logic will do the necessary + * synchronization for the wake ups. The only thing + * that is necessary is that the wake up happens after + * a task has been queued. It's OK for spurious wake ups. + */ + trace_wakeup_needed = true; + + if (trace_empty(iter)) + schedule(); + + finish_wait(&trace_wait, &wait); +} + /** * register_tracer - register a tracer with the ftrace system. * @type - the plugin for the tracer @@ -1156,30 +1189,32 @@ void __buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event) { __this_cpu_write(trace_cmdline_save, true); + if (trace_wakeup_needed) { + trace_wakeup_needed = false; + /* irq_work_queue() supplies it's own memory barriers */ + irq_work_queue(&trace_work_wakeup); + } ring_buffer_unlock_commit(buffer, event); } static inline void __trace_buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event, - unsigned long flags, int pc, - int wake) + unsigned long flags, int pc) { __buffer_unlock_commit(buffer, event); ftrace_trace_stack(buffer, flags, 6, pc); ftrace_trace_userstack(buffer, flags, pc); - - if (wake) - trace_wake_up(); } void trace_buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event, unsigned long flags, int pc) { - __trace_buffer_unlock_commit(buffer, event, flags, pc, 1); + __trace_buffer_unlock_commit(buffer, event, flags, pc); } +EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit); struct ring_buffer_event * trace_current_buffer_lock_reserve(struct ring_buffer **current_rb, @@ -1196,29 +1231,21 @@ void trace_current_buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event, unsigned long flags, int pc) { - __trace_buffer_unlock_commit(buffer, event, flags, pc, 1); + __trace_buffer_unlock_commit(buffer, event, flags, pc); } EXPORT_SYMBOL_GPL(trace_current_buffer_unlock_commit); -void trace_nowake_buffer_unlock_commit(struct ring_buffer *buffer, - struct ring_buffer_event *event, - unsigned long flags, int pc) -{ - __trace_buffer_unlock_commit(buffer, event, flags, pc, 0); -} -EXPORT_SYMBOL_GPL(trace_nowake_buffer_unlock_commit); - -void trace_nowake_buffer_unlock_commit_regs(struct ring_buffer *buffer, - struct ring_buffer_event *event, - unsigned long flags, int pc, - struct pt_regs *regs) +void trace_buffer_unlock_commit_regs(struct ring_buffer *buffer, + struct ring_buffer_event *event, + unsigned long flags, int pc, + struct pt_regs *regs) { __buffer_unlock_commit(buffer, event); ftrace_trace_stack_regs(buffer, flags, 0, pc, regs); ftrace_trace_userstack(buffer, flags, pc); } -EXPORT_SYMBOL_GPL(trace_nowake_buffer_unlock_commit_regs); +EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit_regs); void trace_current_buffer_discard_commit(struct ring_buffer *buffer, struct ring_buffer_event *event) @@ -3354,19 +3381,6 @@ tracing_poll_pipe(struct file *filp, poll_table *poll_table) } } - -void default_wait_pipe(struct trace_iterator *iter) -{ - DEFINE_WAIT(wait); - - prepare_to_wait(&trace_wait, &wait, TASK_INTERRUPTIBLE); - - if (trace_empty(iter)) - schedule(); - - finish_wait(&trace_wait, &wait); -} - /* * This is a make-shift waitqueue. * A tracer might use this callback on some rare cases: @@ -5107,6 +5121,7 @@ __init static int tracer_alloc_buffers(void) #endif trace_init_cmdlines(); + init_irq_work(&trace_work_wakeup, trace_wake_up); register_tracer(&nop_trace); current_trace = &nop_trace; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 3e8a176f64e..55010ed175f 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -327,7 +327,6 @@ trace_buffer_iter(struct trace_iterator *iter, int cpu) int tracer_init(struct tracer *t, struct trace_array *tr); int tracing_is_enabled(void); -void trace_wake_up(void); void tracing_reset(struct trace_array *tr, int cpu); void tracing_reset_online_cpus(struct trace_array *tr); void tracing_reset_current(int cpu); @@ -349,9 +348,6 @@ trace_buffer_lock_reserve(struct ring_buffer *buffer, unsigned long len, unsigned long flags, int pc); -void trace_buffer_unlock_commit(struct ring_buffer *buffer, - struct ring_buffer_event *event, - unsigned long flags, int pc); struct trace_entry *tracing_get_trace_entry(struct trace_array *tr, struct trace_array_cpu *data); @@ -370,7 +366,6 @@ void trace_init_global_iter(struct trace_iterator *iter); void tracing_iter_reset(struct trace_iterator *iter, int cpu); -void default_wait_pipe(struct trace_iterator *iter); void poll_wait_pipe(struct trace_iterator *iter); void ftrace(struct trace_array *tr, diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index cb2df3b70f7..880073d0b94 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -1760,7 +1760,7 @@ function_test_events_call(unsigned long ip, unsigned long parent_ip, entry->ip = ip; entry->parent_ip = parent_ip; - trace_nowake_buffer_unlock_commit(buffer, event, flags, pc); + trace_buffer_unlock_commit(buffer, event, flags, pc); out: atomic_dec(&per_cpu(ftrace_test_event_disable, cpu)); diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 5a3c533ef06..1865d5f7653 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -751,8 +751,8 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); if (!filter_current_check_discard(buffer, call, entry, event)) - trace_nowake_buffer_unlock_commit_regs(buffer, event, - irq_flags, pc, regs); + trace_buffer_unlock_commit_regs(buffer, event, + irq_flags, pc, regs); } /* Kretprobe handler */ @@ -784,8 +784,8 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri, store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); if (!filter_current_check_discard(buffer, call, entry, event)) - trace_nowake_buffer_unlock_commit_regs(buffer, event, - irq_flags, pc, regs); + trace_buffer_unlock_commit_regs(buffer, event, + irq_flags, pc, regs); } /* Event entry printers */ diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index b0a136ac382..3374c792ccd 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -102,7 +102,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr, entry->next_cpu = task_cpu(wakee); if (!filter_check_discard(call, entry, buffer, event)) - trace_nowake_buffer_unlock_commit(buffer, event, flags, pc); + trace_buffer_unlock_commit(buffer, event, flags, pc); } static void diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 091b815f7b0..47623169a81 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -1094,6 +1094,7 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr) tracing_stop(); /* check both trace buffers */ ret = trace_test_buffer(tr, NULL); + printk("ret = %d\n", ret); if (!ret) ret = trace_test_buffer(&max_tr, &count); -- cgit v1.2.3 From 7bcfaf54f591a0775254c4ea679faf615152ee3a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 1 Nov 2012 22:56:07 -0400 Subject: tracing: Add trace_options kernel command line parameter Add trace_options to the kernel command line parameter to be able to set options at early boot. For example, to enable stack dumps of events, add the following: trace_options=stacktrace This along with the trace_event option, you can get not only traces of the events but also the stack dumps with them. Requested-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Steven Rostedt --- Documentation/kernel-parameters.txt | 16 +++++++++++ kernel/trace/trace.c | 54 ++++++++++++++++++++++++++----------- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 9776f068306..2b48c52464a 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2859,6 +2859,22 @@ bytes respectively. Such letter suffixes can also be entirely omitted. to facilitate early boot debugging. See also Documentation/trace/events.txt + trace_options=[option-list] + [FTRACE] Enable or disable tracer options at boot. + The option-list is a comma delimited list of options + that can be enabled or disabled just as if you were + to echo the option name into + + /sys/kernel/debug/tracing/trace_options + + For example, to enable stacktrace option (to dump the + stack trace of each event), add to the command line: + + trace_options=stacktrace + + See also Documentation/trace/ftrace.txt "trace options" + section. + transparent_hugepage= [KNL] Format: [always|madvise|never] diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 37d1c703e3e..c1434b5ce4d 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -155,6 +155,18 @@ static int __init set_ftrace_dump_on_oops(char *str) } __setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops); + +static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata; +static char *trace_boot_options __initdata; + +static int __init set_trace_boot_options(char *str) +{ + strncpy(trace_boot_options_buf, str, MAX_TRACER_SIZE); + trace_boot_options = trace_boot_options_buf; + return 0; +} +__setup("trace_options=", set_trace_boot_options); + unsigned long long ns2usecs(cycle_t nsec) { nsec += 500; @@ -2838,24 +2850,14 @@ static void set_tracer_flags(unsigned int mask, int enabled) trace_printk_start_stop_comm(enabled); } -static ssize_t -tracing_trace_options_write(struct file *filp, const char __user *ubuf, - size_t cnt, loff_t *ppos) +static int trace_set_options(char *option) { - char buf[64]; char *cmp; int neg = 0; - int ret; + int ret = 0; int i; - if (cnt >= sizeof(buf)) - return -EINVAL; - - if (copy_from_user(&buf, ubuf, cnt)) - return -EFAULT; - - buf[cnt] = 0; - cmp = strstrip(buf); + cmp = strstrip(option); if (strncmp(cmp, "no", 2) == 0) { neg = 1; @@ -2874,10 +2876,25 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, mutex_lock(&trace_types_lock); ret = set_tracer_option(current_trace, cmp, neg); mutex_unlock(&trace_types_lock); - if (ret) - return ret; } + return ret; +} + +static ssize_t +tracing_trace_options_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + char buf[64]; + + if (cnt >= sizeof(buf)) + return -EINVAL; + + if (copy_from_user(&buf, ubuf, cnt)) + return -EFAULT; + + trace_set_options(buf); + *ppos += cnt; return cnt; @@ -5133,6 +5150,13 @@ __init static int tracer_alloc_buffers(void) register_die_notifier(&trace_die_notifier); + while (trace_boot_options) { + char *option; + + option = strsep(&trace_boot_options, ","); + trace_set_options(option); + } + return 0; out_free_cpumask: -- cgit v1.2.3 From f55f14752ecaccf7d6a52fd13929b73fcb191f19 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 1 Nov 2012 15:57:11 -0200 Subject: ASoC: mxs-saif: Fix channel swap for 24-bit format Playing 24-bit format file leads to channel swap on mx28 and the reason is that the current driver performs one write/read to/from the SAIF_DATA register to trigger the transfer. This approach works fine for S16_LE case because SAIF_DATA is a 32-bit register and thus is capable of storing the 16-bit left and right channels, but for the S24_LE case it can only store one channel, so in order to not lose the FIFO sync an extra read/write is needed. Reported-by: Dan Winner Signed-off-by: Fabio Estevam Tested-by: Dan Winner Acked-by: Dong Aisheng Signed-off-by: Mark Brown --- sound/soc/mxs/mxs-saif.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 93380cc7cf9..c294fbb523f 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -523,16 +523,24 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { /* - * write a data to saif data register to trigger - * the transfer + * write data to saif data register to trigger + * the transfer. + * For 24-bit format the 32-bit FIFO register stores + * only one channel, so we need to write twice. + * This is also safe for the other non 24-bit formats. */ __raw_writel(0, saif->base + SAIF_DATA); + __raw_writel(0, saif->base + SAIF_DATA); } else { /* - * read a data from saif data register to trigger - * the receive + * read data from saif data register to trigger + * the receive. + * For 24-bit format the 32-bit FIFO register stores + * only one channel, so we need to read twice. + * This is also safe for the other non 24-bit formats. */ __raw_readl(saif->base + SAIF_DATA); + __raw_readl(saif->base + SAIF_DATA); } master_saif->ongoing = 1; -- cgit v1.2.3 From 28696f434fef0efa97534b59986ad33b9c4df7f8 Mon Sep 17 00:00:00 2001 From: Salman Qazi Date: Mon, 1 Oct 2012 17:29:25 -0700 Subject: x86: Don't clobber top of pt_regs in nested NMI The nested NMI modifies the place (instruction, flags and stack) that the first NMI will iret to. However, the copy of registers modified is exactly the one that is the part of pt_regs in the first NMI. This can change the behaviour of the first NMI. In particular, Google's arch_trigger_all_cpu_backtrace handler also prints regions of memory surrounding addresses appearing in registers. This results in handled exceptions, after which nested NMIs start coming in. These nested NMIs change the value of registers in pt_regs. This can cause the original NMI handler to produce incorrect output. We solve this problem by interchanging the position of the preserved copy of the iret registers ("saved") and the copy subject to being trampled by nested NMI ("copied"). Link: http://lkml.kernel.org/r/20121002002919.27236.14388.stgit@dungbeetle.mtv.corp.google.com Signed-off-by: Salman Qazi [ Added a needed CFI_ADJUST_CFA_OFFSET ] Signed-off-by: Steven Rostedt --- arch/x86/kernel/entry_64.S | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index b51b2c7ee51..811795db4fc 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -1699,9 +1699,10 @@ nested_nmi: 1: /* Set up the interrupted NMIs stack to jump to repeat_nmi */ - leaq -6*8(%rsp), %rdx + leaq -1*8(%rsp), %rdx movq %rdx, %rsp - CFI_ADJUST_CFA_OFFSET 6*8 + CFI_ADJUST_CFA_OFFSET 1*8 + leaq -10*8(%rsp), %rdx pushq_cfi $__KERNEL_DS pushq_cfi %rdx pushfq_cfi @@ -1709,8 +1710,8 @@ nested_nmi: pushq_cfi $repeat_nmi /* Put stack back */ - addq $(11*8), %rsp - CFI_ADJUST_CFA_OFFSET -11*8 + addq $(6*8), %rsp + CFI_ADJUST_CFA_OFFSET -6*8 nested_nmi_out: popq_cfi %rdx @@ -1736,18 +1737,18 @@ first_nmi: * +-------------------------+ * | NMI executing variable | * +-------------------------+ - * | Saved SS | - * | Saved Return RSP | - * | Saved RFLAGS | - * | Saved CS | - * | Saved RIP | - * +-------------------------+ * | copied SS | * | copied Return RSP | * | copied RFLAGS | * | copied CS | * | copied RIP | * +-------------------------+ + * | Saved SS | + * | Saved Return RSP | + * | Saved RFLAGS | + * | Saved CS | + * | Saved RIP | + * +-------------------------+ * | pt_regs | * +-------------------------+ * @@ -1763,9 +1764,14 @@ first_nmi: /* Set the NMI executing variable on the stack. */ pushq_cfi $1 + /* + * Leave room for the "copied" frame + */ + subq $(5*8), %rsp + /* Copy the stack frame to the Saved frame */ .rept 5 - pushq_cfi 6*8(%rsp) + pushq_cfi 11*8(%rsp) .endr CFI_DEF_CFA_OFFSET SS+8-RIP @@ -1786,12 +1792,15 @@ repeat_nmi: * is benign for the non-repeat case, where 1 was pushed just above * to this very stack slot). */ - movq $1, 5*8(%rsp) + movq $1, 10*8(%rsp) /* Make another copy, this one may be modified by nested NMIs */ + addq $(10*8), %rsp + CFI_ADJUST_CFA_OFFSET -10*8 .rept 5 - pushq_cfi 4*8(%rsp) + pushq_cfi -6*8(%rsp) .endr + subq $(5*8), %rsp CFI_DEF_CFA_OFFSET SS+8-RIP end_repeat_nmi: @@ -1842,8 +1851,12 @@ nmi_swapgs: SWAPGS_UNSAFE_STACK nmi_restore: RESTORE_ALL 8 + + /* Pop the extra iret frame */ + addq $(5*8), %rsp + /* Clear the NMI executing stack variable */ - movq $0, 10*8(%rsp) + movq $0, 5*8(%rsp) jmp irq_return CFI_ENDPROC END(nmi) -- cgit v1.2.3 From d1bb67a7a2a5a5ff49b0ef4d191725769243e639 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 2 Nov 2012 10:13:24 -0400 Subject: USB: EHCI: fix build error in ehci-platform.c under PowerPC This patch (as1628) fixes a build error in the ehci-platform driver when compiled for the PowerPC architecture. The error was introduced by commit 99f91934a907df31ba878dfdd090002049dc476a (USB: EHCI: make ehci-platform a separate driver). The fix is simple; a few additional header-file #includes are needed. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-platform.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index f97fe3a4d81..feeedf84011 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -19,6 +19,8 @@ * Licensed under the GNU/GPL. See COPYING for details. */ #include +#include +#include #include #include #include -- cgit v1.2.3 From 57465109ce6c62e57b98788496c823c2067253c0 Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Thu, 1 Nov 2012 11:05:28 -0700 Subject: USB: ohci-exynos: initialize registers pointer earlier In the former code, we have a race condition between the first interrupt and the regs field initilization in the usb_hcd structure. If the OHCI irq fires before hcd->regs is set, we are getting a null pointer dereference in ohci_irq. When calling usb_add_hcd(), it first executes the reset() callback, then enables the ohci interrupt, and finally executes the start() callback. So moving the ohci_init() call which actually initializes the reg field from start() to reset() should remove the race. Tested by enabling the external HSIC hub in the bootloader on an exynos5 machine and booting. With the former code, this triggers an early interrupt about 50% of the boots and a subsequent kernel panic in ohci_irq when trying to access the registers. Cc: Olof Johansson Cc: Doug Anderson Cc: Arjun.K.V Cc: Vikas Sajjan Cc: Abhilash Kesavan Signed-off-by: Vincent Palatin Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-exynos.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index 2f303295b42..6a30fc5bec9 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -23,6 +23,11 @@ struct exynos_ohci_hcd { struct clk *clk; }; +static int ohci_exynos_reset(struct usb_hcd *hcd) +{ + return ohci_init(hcd_to_ohci(hcd)); +} + static int ohci_exynos_start(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); @@ -30,10 +35,6 @@ static int ohci_exynos_start(struct usb_hcd *hcd) ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci); - ret = ohci_init(ohci); - if (ret < 0) - return ret; - ret = ohci_run(ohci); if (ret < 0) { dev_err(hcd->self.controller, "can't start %s\n", @@ -53,6 +54,7 @@ static const struct hc_driver exynos_ohci_hc_driver = { .irq = ohci_irq, .flags = HCD_MEMORY|HCD_USB11, + .reset = ohci_exynos_reset, .start = ohci_exynos_start, .stop = ohci_stop, .shutdown = ohci_shutdown, -- cgit v1.2.3 From 09f6ffde2ecef4cc4e2a5edaa303210cabd96f57 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 2 Nov 2012 12:34:41 -0400 Subject: USB: EHCI: fix build error by making ChipIdea host a normal EHCI driver This patch (as1627) splits the ehci-hcd core code, which has become a separate library module, out from the ChipIdea host driver. Instead of #include-ing ehci-hcd.c directly, the ChipIdea module will now use the ehci-hcd library in a normal fashion. This fixes a build error caused by commit 3e0232039967d7a1a06c013d097458b4d5892af1 (USB: EHCI: prepare to make ehci-hcd a library module); I had forgotten about the unorthodox way the ChipIdea driver uses the ehci-hcd code. Signed-off-by: Alan Stern Acked-by: Alexander Shishkin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/Kconfig | 1 + drivers/usb/chipidea/host.c | 51 ++++++-------------------------------------- drivers/usb/host/ehci-hcd.c | 11 +--------- 3 files changed, 9 insertions(+), 54 deletions(-) diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig index 1ea932a1368..608a2aeb400 100644 --- a/drivers/usb/chipidea/Kconfig +++ b/drivers/usb/chipidea/Kconfig @@ -20,6 +20,7 @@ config USB_CHIPIDEA_UDC config USB_CHIPIDEA_HOST bool "ChipIdea host controller" depends on USB=y || USB=USB_CHIPIDEA + depends on USB_EHCI_HCD select USB_EHCI_ROOT_HUB_TT help Say Y here to enable host controller functionality of the diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index ebc041ff9cd..30b17ae5aa2 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -25,57 +25,18 @@ #include #define CHIPIDEA_EHCI -#include "../host/ehci-hcd.c" +#include "../host/ehci.h" #include "ci.h" #include "bits.h" #include "host.h" -static const struct hc_driver ci_ehci_hc_driver = { - .description = "ehci_hcd", - .product_desc = "ChipIdea HDRC EHCI", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2, - - /* - * basic lifecycle operations - */ - .reset = ehci_setup, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, +static const struct ehci_driver_overrides ci_overrides = { + .product_desc = "ChipIdea HDRC EHCI host controller", }; +static struct hc_driver __read_mostly ci_ehci_hc_driver; + static irqreturn_t host_irq(struct ci13xxx *ci) { return usb_hcd_irq(ci->irq, ci->hcd); @@ -141,5 +102,7 @@ int ci_hdrc_host_init(struct ci13xxx *ci) rdrv->name = "host"; ci->roles[CI_ROLE_HOST] = rdrv; + ehci_init_driver(&ci_ehci_hc_driver, &ci_overrides); + return 0; } diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 4a466d7730c..28f694eb624 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1240,14 +1240,6 @@ EXPORT_SYMBOL_GPL(ehci_init_driver); /*-------------------------------------------------------------------------*/ -/* - * The EHCI in ChipIdea HDRC cannot be a separate module or device, - * because its registers (and irq) are shared between host/gadget/otg - * functions and in order to facilitate role switching we cannot - * give the ehci driver exclusive access to those. - */ -#ifndef CHIPIDEA_EHCI - MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR (DRIVER_AUTHOR); MODULE_LICENSE ("GPL"); @@ -1359,6 +1351,7 @@ MODULE_LICENSE ("GPL"); #if !IS_ENABLED(CONFIG_USB_EHCI_PCI) && \ !IS_ENABLED(CONFIG_USB_EHCI_HCD_PLATFORM) && \ + !defined(CONFIG_USB_CHIPIDEA_HOST) && \ !defined(PLATFORM_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && \ !defined(OF_PLATFORM_DRIVER) && \ @@ -1464,5 +1457,3 @@ static void __exit ehci_hcd_cleanup(void) clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded); } module_exit(ehci_hcd_cleanup); - -#endif /* CHIPIDEA_EHCI */ -- cgit v1.2.3 From bc8d51ea7e8ae0abb90fa89407b55a7e0bcb0a2a Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 2 Nov 2012 17:09:00 +0000 Subject: fix build of EHCI debug port code when USB_CHIPIDEA but !USB_EHCI_HCD Relax condition of building the reset interface stubs in drivers/usb/early/ehci-dbgp.c from USB_EHCI_HCD to just USB, to also cover the chipidea driver re-using code from ehci-hcd. Reported-by: Randy Dunlap Signed-off-by: Jan Beulich Acked-by: Alan Stern Cc: Konrad Rzeszutek Wilk Cc: Stefano Stabellini Signed-off-by: Greg Kroah-Hartman --- drivers/usb/early/ehci-dbgp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 4bfa78af379..5e29ddeb4d3 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c @@ -974,7 +974,7 @@ struct console early_dbgp_console = { .index = -1, }; -#if IS_ENABLED(CONFIG_USB_EHCI_HCD) +#if IS_ENABLED(CONFIG_USB) int dbgp_reset_prep(struct usb_hcd *hcd) { int ret = xen_dbgp_reset_prep(hcd); @@ -1008,7 +1008,7 @@ int dbgp_external_startup(struct usb_hcd *hcd) return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup(); } EXPORT_SYMBOL_GPL(dbgp_external_startup); -#endif /* USB_EHCI_HCD */ +#endif /* USB */ #ifdef CONFIG_KGDB -- cgit v1.2.3 From 973781a821fe537ef1cb8ef227266faeed094ef6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:24:06 -0700 Subject: staging: comedi: addi_apci_3120: merge in addi_apci_3001 driver The addi_apci_3120 and addi_apci_3001 drivers share the same low-level board support code (hwdrv_apci3120). Merge the boardinfo and PCI_DEVICE information from the addi_apci_3001 driver into the addi_apci_3120 driver and delete then delete the addi_apci_3001 driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 14 +--- drivers/staging/comedi/drivers/Makefile | 1 - drivers/staging/comedi/drivers/addi_apci_3001.c | 88 ------------------------- drivers/staging/comedi/drivers/addi_apci_3120.c | 37 +++++++++++ 4 files changed, 39 insertions(+), 101 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi_apci_3001.c diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 21a6748d7ad..6246bed00ef 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -647,22 +647,12 @@ config COMEDI_ADDI_APCI_2200 To compile this driver as a module, choose M here: the module will be called addi_apci_2200. -config COMEDI_ADDI_APCI_3001 - tristate "ADDI-DATA APCI_3001 support" - depends on VIRT_TO_BUS - select COMEDI_FC - ---help--- - Enable support for ADDI-DATA APCI_3001 cards - - To compile this driver as a module, choose M here: the module will be - called addi_apci_3001. - config COMEDI_ADDI_APCI_3120 - tristate "ADDI-DATA APCI_3520 support" + tristate "ADDI-DATA APCI_3120/3001 support" depends on VIRT_TO_BUS select COMEDI_FC ---help--- - Enable support for ADDI-DATA APCI_3520 cards + Enable support for ADDI-DATA APCI_3120/3001 cards To compile this driver as a module, choose M here: the module will be called addi_apci_3120. diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index a2787c0ca32..c784bedb911 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -65,7 +65,6 @@ obj-$(CONFIG_COMEDI_ADDI_APCI_16XX) += addi_apci_16xx.o obj-$(CONFIG_COMEDI_ADDI_APCI_2016) += addi_apci_2016.o obj-$(CONFIG_COMEDI_ADDI_APCI_2032) += addi_apci_2032.o obj-$(CONFIG_COMEDI_ADDI_APCI_2200) += addi_apci_2200.o -obj-$(CONFIG_COMEDI_ADDI_APCI_3001) += addi_apci_3001.o obj-$(CONFIG_COMEDI_ADDI_APCI_3120) += addi_apci_3120.o obj-$(CONFIG_COMEDI_ADDI_APCI_3501) += addi_apci_3501.o obj-$(CONFIG_COMEDI_ADDI_APCI_3XXX) += addi_apci_3xxx.o diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c deleted file mode 100644 index 90506a3d1dc..00000000000 --- a/drivers/staging/comedi/drivers/addi_apci_3001.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "../comedidev.h" -#include "comedi_fc.h" -#include "amcc_s5933.h" - -#include "addi-data/addi_common.h" - -#include "addi-data/addi_eeprom.c" -#include "addi-data/hwdrv_apci3120.c" -#include "addi-data/addi_common.c" - -static const struct addi_board apci3001_boardtypes[] = { - { - .pc_DriverName = "apci3001", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, - .i_DeviceId = 0x828D, - .i_IorangeBase0 = AMCC_OP_REG_SIZE, - .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, - .i_IorangeBase2 = 8, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, - .i_NbrAiChannel = 16, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 16, - .i_AiMaxdata = 0xfff, - .pr_AiRangelist = &range_apci3120_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .i_DoMaxdata = 0x0f, - .i_Dma = 1, - .i_Timer = 1, - .b_AvailableConvertUnit = 1, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = v_APCI3120_Interrupt, - .reset = i_APCI3120_Reset, - .ai_config = i_APCI3120_InsnConfigAnalogInput, - .ai_read = i_APCI3120_InsnReadAnalogInput, - .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, - .ai_cmd = i_APCI3120_CommandAnalogInput, - .ai_cancel = i_APCI3120_StopCyclicAcquisition, - .di_read = i_APCI3120_InsnReadDigitalInput, - .di_bits = i_APCI3120_InsnBitsDigitalInput, - .do_config = i_APCI3120_InsnConfigDigitalOutput, - .do_write = i_APCI3120_InsnWriteDigitalOutput, - .do_bits = i_APCI3120_InsnBitsDigitalOutput, - .timer_config = i_APCI3120_InsnConfigTimer, - .timer_write = i_APCI3120_InsnWriteTimer, - .timer_read = i_APCI3120_InsnReadTimer, - }, -}; - -static struct comedi_driver apci3001_driver = { - .driver_name = "addi_apci_3001", - .module = THIS_MODULE, - .attach_pci = addi_attach_pci, - .detach = i_ADDI_Detach, - .num_names = ARRAY_SIZE(apci3001_boardtypes), - .board_name = &apci3001_boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), -}; - -static int __devinit apci3001_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &apci3001_driver); -} - -static void __devexit apci3001_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static DEFINE_PCI_DEVICE_TABLE(apci3001_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x828d) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, apci3001_pci_table); - -static struct pci_driver apci3001_pci_driver = { - .name = "addi_apci_3001", - .id_table = apci3001_pci_table, - .probe = apci3001_pci_probe, - .remove = __devexit_p(apci3001_pci_remove), -}; -module_comedi_pci_driver(apci3001_driver, apci3001_pci_driver); - -MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 5db6bfc0e22..979b8a9703a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -51,6 +51,42 @@ static const struct addi_board apci3120_boardtypes[] = { .timer_config = i_APCI3120_InsnConfigTimer, .timer_write = i_APCI3120_InsnWriteTimer, .timer_read = i_APCI3120_InsnReadTimer, + }, { + .pc_DriverName = "apci3001", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, + .i_DeviceId = 0x828D, + .i_IorangeBase0 = AMCC_OP_REG_SIZE, + .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, + .i_IorangeBase2 = 8, + .i_PCIEeprom = ADDIDATA_NO_EEPROM, + .i_NbrAiChannel = 16, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 16, + .i_AiMaxdata = 0xfff, + .pr_AiRangelist = &range_apci3120_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .i_DoMaxdata = 0x0f, + .i_Dma = 1, + .i_Timer = 1, + .b_AvailableConvertUnit = 1, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI3120_Interrupt, + .reset = i_APCI3120_Reset, + .ai_config = i_APCI3120_InsnConfigAnalogInput, + .ai_read = i_APCI3120_InsnReadAnalogInput, + .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, + .ai_cmd = i_APCI3120_CommandAnalogInput, + .ai_cancel = i_APCI3120_StopCyclicAcquisition, + .di_read = i_APCI3120_InsnReadDigitalInput, + .di_bits = i_APCI3120_InsnBitsDigitalInput, + .do_config = i_APCI3120_InsnConfigDigitalOutput, + .do_write = i_APCI3120_InsnWriteDigitalOutput, + .do_bits = i_APCI3120_InsnBitsDigitalOutput, + .timer_config = i_APCI3120_InsnConfigTimer, + .timer_write = i_APCI3120_InsnWriteTimer, + .timer_read = i_APCI3120_InsnReadTimer, }, }; @@ -77,6 +113,7 @@ static void __devexit apci3120_pci_remove(struct pci_dev *dev) static DEFINE_PCI_DEVICE_TABLE(apci3120_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x818d) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA_OLD, 0x828d) }, { 0 } }; MODULE_DEVICE_TABLE(pci, apci3120_pci_table); -- cgit v1.2.3 From 33db6ebe0a124ef2ffb65c5f2ce4104e08fcec9c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:24:22 -0700 Subject: staging: comedi: addi_apci_3120: remove CONFIG_APCI_3120 define Now that the apci3001 and apci3120 boards are merged we can remove this unnecessary define. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 2 -- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 47ec2083c58..2514d685c14 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -2378,7 +2378,6 @@ static int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, } -#ifdef CONFIG_APCI_3120 static int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -2437,4 +2436,3 @@ static int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, return insn->n; } -#endif diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 979b8a9703a..3c8a6a272c8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -4,8 +4,6 @@ #include "addi-data/addi_common.h" -#define CONFIG_APCI_3120 1 - #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3120.c" #include "addi-data/addi_common.c" -- cgit v1.2.3 From bb6986f022a0faaf959bb39153c07424ced87aab Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:24:38 -0700 Subject: staging: comedi: addi_apci_3120: separate from addi_common.c The addi_apci_3120 driver is the only addi-data driver that supports dma. Copy the code in addi_common.c to this driver and remove the #include that caused addi_common.c to be compiled with this driver. This will allow removing the special handling for allocating and freeing the dma buffers in the common code. Rename the attach_pci and detach functions so they have namespace associated with this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 361 +++++++++++++++++++++++- 1 file changed, 358 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 3c8a6a272c8..05ff3e20968 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -6,7 +6,10 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3120.c" -#include "addi-data/addi_common.c" + +#ifndef COMEDI_SUBD_TTLIO +#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ +#endif static const struct addi_board apci3120_boardtypes[] = { { @@ -88,11 +91,363 @@ static const struct addi_board apci3120_boardtypes[] = { }, }; +static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; + unsigned short w_Address = CR_CHAN(insn->chanspec); + unsigned short w_Data; + + w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, + this_board->pc_EepromChip, 2 * w_Address); + data[0] = w_Data; + + return insn->n; +} + +static irqreturn_t v_ADDI_Interrupt(int irq, void *d) +{ + struct comedi_device *dev = d; + const struct addi_board *this_board = comedi_board(dev); + + this_board->interrupt(irq, d); + return IRQ_RETVAL(1); +} + +static int i_ADDI_Reset(struct comedi_device *dev) +{ + const struct addi_board *this_board = comedi_board(dev); + + this_board->reset(dev); + return 0; +} + +static const void *addi_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const void *p = dev->driver->board_name; + const struct addi_board *this_board; + int i; + + for (i = 0; i < dev->driver->num_names; i++) { + this_board = p; + if (this_board->i_VendorId == pcidev->vendor && + this_board->i_DeviceId == pcidev->device) + return this_board; + p += dev->driver->offset; + } + return NULL; +} + +static int apci3120_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const struct addi_board *this_board; + struct addi_private *devpriv; + struct comedi_subdevice *s; + int ret, pages, i, n_subdevices; + unsigned int dw_Dummy; + + this_board = addi_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->pc_DriverName; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + if (this_board->i_Dma) + pci_set_master(pcidev); + + if (!this_board->pc_EepromChip || + !strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { + if (this_board->i_IorangeBase1) + dev->iobase = pci_resource_start(pcidev, 1); + else + dev->iobase = pci_resource_start(pcidev, 0); + + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); + } else { + dev->iobase = pci_resource_start(pcidev, 2); + devpriv->iobase = pci_resource_start(pcidev, 2); + devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), + this_board->i_IorangeBase3); + } + devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); + + /* Initialize parameters that can be overridden in EEPROM */ + devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; + devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; + devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; + devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; + devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; + devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; + devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; + devpriv->s_EeParameters.i_Dma = this_board->i_Dma; + devpriv->s_EeParameters.i_Timer = this_board->i_Timer; + devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = + this_board->ui_MinAcquisitiontimeNs; + devpriv->s_EeParameters.ui_MinDelaytimeNs = + this_board->ui_MinDelaytimeNs; + + /* ## */ + + if (pcidev->irq > 0) { + ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } + + /* Read eepeom and fill addi_board Structure */ + + if (this_board->i_PCIEeprom) { + if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { + /* Set 3 wait stait */ + if (!(strcmp(dev->board_name, "apci035"))) { + outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); + } else { + outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); + } + /* Enable the interrupt for the controller */ + dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); + outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); + } + addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); + } + + devpriv->us_UseDma = ADDI_ENABLE; + + if (devpriv->s_EeParameters.i_Dma) { + if (devpriv->us_UseDma == ADDI_ENABLE) { + /* alloc DMA buffers */ + devpriv->b_DmaDoubleBuffer = 0; + for (i = 0; i < 2; i++) { + for (pages = 4; pages >= 0; pages--) { + devpriv->ul_DmaBufferVirtual[i] = + (void *) __get_free_pages(GFP_KERNEL, pages); + + if (devpriv->ul_DmaBufferVirtual[i]) + break; + } + if (devpriv->ul_DmaBufferVirtual[i]) { + devpriv->ui_DmaBufferPages[i] = pages; + devpriv->ui_DmaBufferSize[i] = + PAGE_SIZE * pages; + devpriv->ui_DmaBufferSamples[i] = + devpriv-> + ui_DmaBufferSize[i] >> 1; + devpriv->ul_DmaBufferHw[i] = + virt_to_bus((void *)devpriv-> + ul_DmaBufferVirtual[i]); + } + } + if (!devpriv->ul_DmaBufferVirtual[0]) + devpriv->us_UseDma = ADDI_DISABLE; + + if (devpriv->ul_DmaBufferVirtual[1]) + devpriv->b_DmaDoubleBuffer = 1; + } + } + + n_subdevices = 7; + ret = comedi_alloc_subdevices(dev, n_subdevices); + if (ret) + return ret; + + /* Allocate and Initialise AI Subdevice Structures */ + s = &dev->subdevices[0]; + if ((devpriv->s_EeParameters.i_NbrAiChannel) + || (this_board->i_NbrAiChannelDiff)) { + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_COMMON | SDF_GROUND + | SDF_DIFF; + if (devpriv->s_EeParameters.i_NbrAiChannel) { + s->n_chan = + devpriv->s_EeParameters.i_NbrAiChannel; + devpriv->b_SingelDiff = 0; + } else { + s->n_chan = this_board->i_NbrAiChannelDiff; + devpriv->b_SingelDiff = 1; + } + s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; + s->len_chanlist = this_board->i_AiChannelList; + s->range_table = this_board->pr_AiRangelist; + + /* Set the initialisation flag */ + devpriv->b_AiInitialisation = 1; + + s->insn_config = this_board->ai_config; + s->insn_read = this_board->ai_read; + s->insn_write = this_board->ai_write; + s->insn_bits = this_board->ai_bits; + s->do_cmdtest = this_board->ai_cmdtest; + s->do_cmd = this_board->ai_cmd; + s->cancel = this_board->ai_cancel; + + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise AO Subdevice Structures */ + s = &dev->subdevices[1]; + if (devpriv->s_EeParameters.i_NbrAoChannel) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; + s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrAoChannel; + s->range_table = this_board->pr_AoRangelist; + s->insn_config = this_board->ao_config; + s->insn_write = this_board->ao_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DI Subdevice Structures */ + s = &dev->subdevices[2]; + if (devpriv->s_EeParameters.i_NbrDiChannel) { + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; + s->maxdata = 1; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDiChannel; + s->range_table = &range_digital; + s->io_bits = 0; /* all bits input */ + s->insn_config = this_board->di_config; + s->insn_read = this_board->di_read; + s->insn_write = this_board->di_write; + s->insn_bits = this_board->di_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DO Subdevice Structures */ + s = &dev->subdevices[3]; + if (devpriv->s_EeParameters.i_NbrDoChannel) { + s->type = COMEDI_SUBD_DO; + s->subdev_flags = + SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; + s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDoChannel; + s->range_table = &range_digital; + s->io_bits = 0xf; /* all bits output */ + + /* insn_config - for digital output memory */ + s->insn_config = this_board->do_config; + s->insn_write = this_board->do_write; + s->insn_bits = this_board->do_bits; + s->insn_read = this_board->do_read; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise Timer Subdevice Structures */ + s = &dev->subdevices[4]; + if (devpriv->s_EeParameters.i_Timer) { + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + + s->insn_write = this_board->timer_write; + s->insn_read = this_board->timer_read; + s->insn_config = this_board->timer_config; + s->insn_bits = this_board->timer_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise TTL */ + s = &dev->subdevices[5]; + if (this_board->i_NbrTTLChannel) { + s->type = COMEDI_SUBD_TTLIO; + s->subdev_flags = + SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = this_board->i_NbrTTLChannel; + s->maxdata = 1; + s->io_bits = 0; /* all bits input */ + s->len_chanlist = this_board->i_NbrTTLChannel; + s->range_table = &range_digital; + s->insn_config = this_board->ttl_config; + s->insn_bits = this_board->ttl_bits; + s->insn_read = this_board->ttl_read; + s->insn_write = this_board->ttl_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* EEPROM */ + s = &dev->subdevices[6]; + if (this_board->i_PCIEeprom) { + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE | SDF_INTERNAL; + s->n_chan = 256; + s->maxdata = 0xffff; + s->insn_read = i_ADDIDATA_InsnReadEeprom; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + i_ADDI_Reset(dev); + return 0; +} + +static void apci3120_detach(struct comedi_device *dev) +{ + const struct addi_board *this_board = comedi_board(dev); + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct addi_private *devpriv = dev->private; + + if (devpriv) { + if (dev->iobase) + i_ADDI_Reset(dev); + if (dev->irq) + free_irq(dev->irq, dev); + if ((this_board->pc_EepromChip == NULL) || + (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { + if (devpriv->ul_DmaBufferVirtual[0]) { + free_pages((unsigned long)devpriv-> + ul_DmaBufferVirtual[0], + devpriv->ui_DmaBufferPages[0]); + } + if (devpriv->ul_DmaBufferVirtual[1]) { + free_pages((unsigned long)devpriv-> + ul_DmaBufferVirtual[1], + devpriv->ui_DmaBufferPages[1]); + } + } else { + iounmap(devpriv->dw_AiBase); + } + } + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } +} + static struct comedi_driver apci3120_driver = { .driver_name = "addi_apci_3120", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, - .detach = i_ADDI_Detach, + .attach_pci = apci3120_attach_pci, + .detach = apci3120_detach, .num_names = ARRAY_SIZE(apci3120_boardtypes), .board_name = &apci3120_boardtypes[0].pc_DriverName, .offset = sizeof(struct addi_board), -- cgit v1.2.3 From e50e2420d6d8effa2c9806d81f065807949e3960 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:24:55 -0700 Subject: staging: comedi: addi_common: remove dma setup/free code None of the addi-data drivers that use the "common" code in addi_common.c support dma. Remove the code that sets up the dma and allocates the buffers in the attach and the code that frees the buffers in the detach. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/addi-data/addi_common.c | 54 +--------------------- 1 file changed, 2 insertions(+), 52 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 75f3dbdbed6..d2d57e5862e 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -99,7 +99,7 @@ static int addi_attach_pci(struct comedi_device *dev, const struct addi_board *this_board; struct addi_private *devpriv; struct comedi_subdevice *s; - int ret, pages, i, n_subdevices; + int ret, n_subdevices; unsigned int dw_Dummy; this_board = addi_find_boardinfo(dev, pcidev); @@ -116,8 +116,6 @@ static int addi_attach_pci(struct comedi_device *dev, ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - if (this_board->i_Dma) - pci_set_master(pcidev); if (!this_board->pc_EepromChip || !strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { @@ -178,40 +176,6 @@ static int addi_attach_pci(struct comedi_device *dev, addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); } - devpriv->us_UseDma = ADDI_ENABLE; - - if (devpriv->s_EeParameters.i_Dma) { - if (devpriv->us_UseDma == ADDI_ENABLE) { - /* alloc DMA buffers */ - devpriv->b_DmaDoubleBuffer = 0; - for (i = 0; i < 2; i++) { - for (pages = 4; pages >= 0; pages--) { - devpriv->ul_DmaBufferVirtual[i] = - (void *) __get_free_pages(GFP_KERNEL, pages); - - if (devpriv->ul_DmaBufferVirtual[i]) - break; - } - if (devpriv->ul_DmaBufferVirtual[i]) { - devpriv->ui_DmaBufferPages[i] = pages; - devpriv->ui_DmaBufferSize[i] = - PAGE_SIZE * pages; - devpriv->ui_DmaBufferSamples[i] = - devpriv-> - ui_DmaBufferSize[i] >> 1; - devpriv->ul_DmaBufferHw[i] = - virt_to_bus((void *)devpriv-> - ul_DmaBufferVirtual[i]); - } - } - if (!devpriv->ul_DmaBufferVirtual[0]) - devpriv->us_UseDma = ADDI_DISABLE; - - if (devpriv->ul_DmaBufferVirtual[1]) - devpriv->b_DmaDoubleBuffer = 1; - } - } - n_subdevices = 7; ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret) @@ -363,7 +327,6 @@ static int addi_attach_pci(struct comedi_device *dev, static void i_ADDI_Detach(struct comedi_device *dev) { - const struct addi_board *this_board = comedi_board(dev); struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct addi_private *devpriv = dev->private; @@ -372,21 +335,8 @@ static void i_ADDI_Detach(struct comedi_device *dev) i_ADDI_Reset(dev); if (dev->irq) free_irq(dev->irq, dev); - if ((this_board->pc_EepromChip == NULL) || - (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { - if (devpriv->ul_DmaBufferVirtual[0]) { - free_pages((unsigned long)devpriv-> - ul_DmaBufferVirtual[0], - devpriv->ui_DmaBufferPages[0]); - } - if (devpriv->ul_DmaBufferVirtual[1]) { - free_pages((unsigned long)devpriv-> - ul_DmaBufferVirtual[1], - devpriv->ui_DmaBufferPages[1]); - } - } else { + if (devpriv->dw_AiBase) iounmap(devpriv->dw_AiBase); - } } if (pcidev) { if (dev->iobase) -- cgit v1.2.3 From 887f706edf86fe90d04f0df83704d612722e3d36 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:25:11 -0700 Subject: staging: comedi: addi_apci_3120: remove eeprom handling code The boards supported by this driver do not have an eeprom. Remove the unnecessary code to handle it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 70 +++---------------------- 1 file changed, 8 insertions(+), 62 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 05ff3e20968..3acc595497e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -4,7 +4,6 @@ #include "addi-data/addi_common.h" -#include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci3120.c" #ifndef COMEDI_SUBD_TTLIO @@ -19,7 +18,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_IorangeBase0 = AMCC_OP_REG_SIZE, .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, .i_IorangeBase2 = 8, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, .i_NbrAiChannel = 16, .i_NbrAiChannelDiff = 8, .i_AiChannelList = 16, @@ -59,7 +57,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_IorangeBase0 = AMCC_OP_REG_SIZE, .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, .i_IorangeBase2 = 8, - .i_PCIEeprom = ADDIDATA_NO_EEPROM, .i_NbrAiChannel = 16, .i_NbrAiChannelDiff = 8, .i_AiChannelList = 16, @@ -91,23 +88,6 @@ static const struct addi_board apci3120_boardtypes[] = { }, }; -static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = comedi_board(dev); - struct addi_private *devpriv = dev->private; - unsigned short w_Address = CR_CHAN(insn->chanspec); - unsigned short w_Data; - - w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, - this_board->pc_EepromChip, 2 * w_Address); - data[0] = w_Data; - - return insn->n; -} - static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { struct comedi_device *dev = d; @@ -149,7 +129,6 @@ static int apci3120_attach_pci(struct comedi_device *dev, struct addi_private *devpriv; struct comedi_subdevice *s; int ret, pages, i, n_subdevices; - unsigned int dw_Dummy; this_board = addi_find_boardinfo(dev, pcidev); if (!this_board) @@ -168,22 +147,14 @@ static int apci3120_attach_pci(struct comedi_device *dev, if (this_board->i_Dma) pci_set_master(pcidev); - if (!this_board->pc_EepromChip || - !strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { - if (this_board->i_IorangeBase1) - dev->iobase = pci_resource_start(pcidev, 1); - else - dev->iobase = pci_resource_start(pcidev, 0); + if (this_board->i_IorangeBase1) + dev->iobase = pci_resource_start(pcidev, 1); + else + dev->iobase = pci_resource_start(pcidev, 0); - devpriv->iobase = dev->iobase; - devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); - devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - } else { - dev->iobase = pci_resource_start(pcidev, 2); - devpriv->iobase = pci_resource_start(pcidev, 2); - devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), - this_board->i_IorangeBase3); - } + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); /* Initialize parameters that can be overridden in EEPROM */ @@ -210,23 +181,6 @@ static int apci3120_attach_pci(struct comedi_device *dev, dev->irq = pcidev->irq; } - /* Read eepeom and fill addi_board Structure */ - - if (this_board->i_PCIEeprom) { - if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { - /* Set 3 wait stait */ - if (!(strcmp(dev->board_name, "apci035"))) { - outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); - } else { - outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); - } - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - } - addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); - } - devpriv->us_UseDma = ADDI_ENABLE; if (devpriv->s_EeParameters.i_Dma) { @@ -396,15 +350,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, /* EEPROM */ s = &dev->subdevices[6]; - if (this_board->i_PCIEeprom) { - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 256; - s->maxdata = 0xffff; - s->insn_read = i_ADDIDATA_InsnReadEeprom; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; i_ADDI_Reset(dev); return 0; -- cgit v1.2.3 From 4ee6d2743a7a8fc4a7ce770cd5b9296e70552edf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:25:27 -0700 Subject: staging: comedi: addi_apci_3120: board does not have ttl i/o The boards supported by this driver do not have ttl i/o. Remove the unnecessary code to initialize the subdevice. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 3acc595497e..d405b3bf873 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -331,22 +331,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, /* Allocate and Initialise TTL */ s = &dev->subdevices[5]; - if (this_board->i_NbrTTLChannel) { - s->type = COMEDI_SUBD_TTLIO; - s->subdev_flags = - SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrTTLChannel; - s->maxdata = 1; - s->io_bits = 0; /* all bits input */ - s->len_chanlist = this_board->i_NbrTTLChannel; - s->range_table = &range_digital; - s->insn_config = this_board->ttl_config; - s->insn_bits = this_board->ttl_bits; - s->insn_read = this_board->ttl_read; - s->insn_write = this_board->ttl_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; /* EEPROM */ s = &dev->subdevices[6]; -- cgit v1.2.3 From 48fdf084180e30e7ad3a46b93eab0c75d3700f84 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:25:44 -0700 Subject: staging: comedi: addi_apci_3120: remove need for s_EeParameters The boards supported by this driver do not have an eeprom. Remove the need for the devpriv->s_EeParameters values by just using the values from the boardinfo directly. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 28 +++++------ drivers/staging/comedi/drivers/addi_apci_3120.c | 56 +++++++--------------- 2 files changed, 31 insertions(+), 53 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 2514d685c14..73af970a44e 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -257,6 +257,7 @@ static int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; unsigned int i; @@ -272,7 +273,7 @@ static int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, for (i = 0; i < data[3]; i++) { if (CR_CHAN(data[4 + i]) >= - devpriv->s_EeParameters.i_NbrAiChannel) { + this_board->i_NbrAiChannel) { printk("bad channel list\n"); return -2; } @@ -743,7 +744,6 @@ static int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_cmd *cmd) { const struct addi_board *this_board = comedi_board(dev); - struct addi_private *devpriv = dev->private; int err = 0; /* Step 1 : check if triggers are trivially valid */ @@ -778,9 +778,9 @@ static int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER) { /* Test Delay timing */ if (cmd->scan_begin_arg < - devpriv->s_EeParameters.ui_MinDelaytimeNs) { + this_board->ui_MinDelaytimeNs) { cmd->scan_begin_arg = - devpriv->s_EeParameters.ui_MinDelaytimeNs; + this_board->ui_MinDelaytimeNs; err++; } } @@ -789,18 +789,16 @@ static int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER) { if ((cmd->convert_arg) && (cmd->convert_arg < - devpriv->s_EeParameters. - ui_MinAcquisitiontimeNs)) { - cmd->convert_arg = devpriv->s_EeParameters. - ui_MinAcquisitiontimeNs; + this_board->ui_MinAcquisitiontimeNs)) { + cmd->convert_arg = + this_board->ui_MinAcquisitiontimeNs; err++; } } else { if (cmd->convert_arg < - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs - ) { - cmd->convert_arg = devpriv->s_EeParameters. - ui_MinAcquisitiontimeNs; + this_board->ui_MinAcquisitiontimeNs) { + cmd->convert_arg = + this_board->ui_MinAcquisitiontimeNs; err++; } @@ -2290,9 +2288,10 @@ static int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; - if ((data[0] > devpriv->s_EeParameters.i_DoMaxdata) || (data[0] < 0)) { + if ((data[0] > this_board->i_DoMaxdata) || (data[0] < 0)) { comedi_error(dev, "Data is not valid !!! \n"); return -EINVAL; @@ -2330,6 +2329,7 @@ static int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; unsigned int ui_Temp1; unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ @@ -2339,7 +2339,7 @@ static int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, "Not a valid Data !!! ,Data should be 1 or 0\n"); return -EINVAL; } - if (ui_NoOfChannel > devpriv->s_EeParameters.i_NbrDoChannel - 1) { + if (ui_NoOfChannel > this_board->i_NbrDoChannel - 1) { comedi_error(dev, "This board doesn't have specified channel !!! \n"); return -EINVAL; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index d405b3bf873..26adc83465d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -157,23 +157,6 @@ static int apci3120_attach_pci(struct comedi_device *dev, devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); - /* Initialize parameters that can be overridden in EEPROM */ - devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; - devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; - devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; - devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; - devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; - devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; - devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; - devpriv->s_EeParameters.i_Dma = this_board->i_Dma; - devpriv->s_EeParameters.i_Timer = this_board->i_Timer; - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = - this_board->ui_MinAcquisitiontimeNs; - devpriv->s_EeParameters.ui_MinDelaytimeNs = - this_board->ui_MinDelaytimeNs; - - /* ## */ - if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, dev->board_name, dev); @@ -183,7 +166,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, devpriv->us_UseDma = ADDI_ENABLE; - if (devpriv->s_EeParameters.i_Dma) { + if (this_board->i_Dma) { if (devpriv->us_UseDma == ADDI_ENABLE) { /* alloc DMA buffers */ devpriv->b_DmaDoubleBuffer = 0; @@ -222,22 +205,20 @@ static int apci3120_attach_pci(struct comedi_device *dev, /* Allocate and Initialise AI Subdevice Structures */ s = &dev->subdevices[0]; - if ((devpriv->s_EeParameters.i_NbrAiChannel) - || (this_board->i_NbrAiChannelDiff)) { + if (this_board->i_NbrAiChannel || (this_board->i_NbrAiChannelDiff)) { dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; - if (devpriv->s_EeParameters.i_NbrAiChannel) { - s->n_chan = - devpriv->s_EeParameters.i_NbrAiChannel; + if (this_board->i_NbrAiChannel) { + s->n_chan = this_board->i_NbrAiChannel; devpriv->b_SingelDiff = 0; } else { s->n_chan = this_board->i_NbrAiChannelDiff; devpriv->b_SingelDiff = 1; } - s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; + s->maxdata = this_board->i_AiMaxdata; s->len_chanlist = this_board->i_AiChannelList; s->range_table = this_board->pr_AiRangelist; @@ -258,13 +239,12 @@ static int apci3120_attach_pci(struct comedi_device *dev, /* Allocate and Initialise AO Subdevice Structures */ s = &dev->subdevices[1]; - if (devpriv->s_EeParameters.i_NbrAoChannel) { + if (this_board->i_NbrAoChannel) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; - s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrAoChannel; + s->n_chan = this_board->i_NbrAoChannel; + s->maxdata = this_board->i_AoMaxdata; + s->len_chanlist = this_board->i_NbrAoChannel; s->range_table = this_board->pr_AoRangelist; s->insn_config = this_board->ao_config; s->insn_write = this_board->ao_write; @@ -273,13 +253,12 @@ static int apci3120_attach_pci(struct comedi_device *dev, } /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[2]; - if (devpriv->s_EeParameters.i_NbrDiChannel) { + if (this_board->i_NbrDiChannel) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; + s->n_chan = this_board->i_NbrDiChannel; s->maxdata = 1; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDiChannel; + s->len_chanlist = this_board->i_NbrDiChannel; s->range_table = &range_digital; s->io_bits = 0; /* all bits input */ s->insn_config = this_board->di_config; @@ -291,14 +270,13 @@ static int apci3120_attach_pci(struct comedi_device *dev, } /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[3]; - if (devpriv->s_EeParameters.i_NbrDoChannel) { + if (this_board->i_NbrDoChannel) { s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; - s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDoChannel; + s->n_chan = this_board->i_NbrDoChannel; + s->maxdata = this_board->i_DoMaxdata; + s->len_chanlist = this_board->i_NbrDoChannel; s->range_table = &range_digital; s->io_bits = 0xf; /* all bits output */ @@ -313,7 +291,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[4]; - if (devpriv->s_EeParameters.i_Timer) { + if (this_board->i_Timer) { s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 1; -- cgit v1.2.3 From 4fbe36f2e9eb913f1c58800cc52e62769ebfd2dc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:26:00 -0700 Subject: staging: comedi: addi_apci_3120: remove test for dma support The boards supported by this driver support dma. Remove the tests for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 55 +++++++++++-------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 26adc83465d..f2f706914c9 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -29,7 +29,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, - .i_Dma = 1, .i_Timer = 1, .b_AvailableConvertUnit = 1, .ui_MinAcquisitiontimeNs = 10000, @@ -65,7 +64,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, - .i_Dma = 1, .i_Timer = 1, .b_AvailableConvertUnit = 1, .ui_MinAcquisitiontimeNs = 10000, @@ -144,8 +142,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; - if (this_board->i_Dma) - pci_set_master(pcidev); + pci_set_master(pcidev); if (this_board->i_IorangeBase1) dev->iobase = pci_resource_start(pcidev, 1); @@ -166,37 +163,31 @@ static int apci3120_attach_pci(struct comedi_device *dev, devpriv->us_UseDma = ADDI_ENABLE; - if (this_board->i_Dma) { - if (devpriv->us_UseDma == ADDI_ENABLE) { - /* alloc DMA buffers */ - devpriv->b_DmaDoubleBuffer = 0; - for (i = 0; i < 2; i++) { - for (pages = 4; pages >= 0; pages--) { - devpriv->ul_DmaBufferVirtual[i] = - (void *) __get_free_pages(GFP_KERNEL, pages); - - if (devpriv->ul_DmaBufferVirtual[i]) - break; - } - if (devpriv->ul_DmaBufferVirtual[i]) { - devpriv->ui_DmaBufferPages[i] = pages; - devpriv->ui_DmaBufferSize[i] = - PAGE_SIZE * pages; - devpriv->ui_DmaBufferSamples[i] = - devpriv-> - ui_DmaBufferSize[i] >> 1; - devpriv->ul_DmaBufferHw[i] = - virt_to_bus((void *)devpriv-> - ul_DmaBufferVirtual[i]); - } - } - if (!devpriv->ul_DmaBufferVirtual[0]) - devpriv->us_UseDma = ADDI_DISABLE; + /* Allocate DMA buffers */ + devpriv->b_DmaDoubleBuffer = 0; + for (i = 0; i < 2; i++) { + for (pages = 4; pages >= 0; pages--) { + devpriv->ul_DmaBufferVirtual[i] = + (void *) __get_free_pages(GFP_KERNEL, pages); - if (devpriv->ul_DmaBufferVirtual[1]) - devpriv->b_DmaDoubleBuffer = 1; + if (devpriv->ul_DmaBufferVirtual[i]) + break; + } + if (devpriv->ul_DmaBufferVirtual[i]) { + devpriv->ui_DmaBufferPages[i] = pages; + devpriv->ui_DmaBufferSize[i] = PAGE_SIZE * pages; + devpriv->ui_DmaBufferSamples[i] = + devpriv->ui_DmaBufferSize[i] >> 1; + devpriv->ul_DmaBufferHw[i] = + virt_to_bus((void *)devpriv-> + ul_DmaBufferVirtual[i]); } } + if (!devpriv->ul_DmaBufferVirtual[0]) + devpriv->us_UseDma = ADDI_DISABLE; + + if (devpriv->ul_DmaBufferVirtual[1]) + devpriv->b_DmaDoubleBuffer = 1; n_subdevices = 7; ret = comedi_alloc_subdevices(dev, n_subdevices); -- cgit v1.2.3 From 53b168b938101fc16bc8a980950458aa41a83aa8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:26:16 -0700 Subject: staging: comedi: addi_apci_3120: remove test for timer support The boards supported by this driver support a timer subdevice. Remove the tests for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 28 ++++++++++--------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index f2f706914c9..83f4ce8cc2d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -29,7 +29,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, - .i_Timer = 1, .b_AvailableConvertUnit = 1, .ui_MinAcquisitiontimeNs = 10000, .ui_MinDelaytimeNs = 100000, @@ -64,7 +63,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, - .i_Timer = 1, .b_AvailableConvertUnit = 1, .ui_MinAcquisitiontimeNs = 10000, .ui_MinDelaytimeNs = 100000, @@ -282,21 +280,17 @@ static int apci3120_attach_pci(struct comedi_device *dev, /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[4]; - if (this_board->i_Timer) { - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; - s->range_table = &range_digital; - - s->insn_write = this_board->timer_write; - s->insn_read = this_board->timer_read; - s->insn_config = this_board->timer_config; - s->insn_bits = this_board->timer_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + + s->insn_write = this_board->timer_write; + s->insn_read = this_board->timer_read; + s->insn_config = this_board->timer_config; + s->insn_bits = this_board->timer_bits; /* Allocate and Initialise TTL */ s = &dev->subdevices[5]; -- cgit v1.2.3 From 43deb75dcc9073bc3d51347da16df74569a6d7ba Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:26:31 -0700 Subject: staging: comedi: addi_apci_3120: remove test for DO subdevice The boards supported by this driver all have digital outputs. Remove the test for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 30 +++++++++++-------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 83f4ce8cc2d..5f82f10ba58 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -259,24 +259,20 @@ static int apci3120_attach_pci(struct comedi_device *dev, } /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[3]; - if (this_board->i_NbrDoChannel) { - s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrDoChannel; - s->maxdata = this_board->i_DoMaxdata; - s->len_chanlist = this_board->i_NbrDoChannel; - s->range_table = &range_digital; - s->io_bits = 0xf; /* all bits output */ + s->type = COMEDI_SUBD_DO; + s->subdev_flags = + SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = this_board->i_NbrDoChannel; + s->maxdata = this_board->i_DoMaxdata; + s->len_chanlist = this_board->i_NbrDoChannel; + s->range_table = &range_digital; + s->io_bits = 0xf; /* all bits output */ - /* insn_config - for digital output memory */ - s->insn_config = this_board->do_config; - s->insn_write = this_board->do_write; - s->insn_bits = this_board->do_bits; - s->insn_read = this_board->do_read; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + /* insn_config - for digital output memory */ + s->insn_config = this_board->do_config; + s->insn_write = this_board->do_write; + s->insn_bits = this_board->do_bits; + s->insn_read = this_board->do_read; /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[4]; -- cgit v1.2.3 From f2c872e1983cfcc9e46e90bbdbb139d5c8698244 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:26:45 -0700 Subject: staging: comedi: addi_apci_3120: remove test for DI subdevice The boards supported by this driver all have digital inputs. Remove the test for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 28 ++++++++++++------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 5f82f10ba58..3282c54f611 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -240,23 +240,21 @@ static int apci3120_attach_pci(struct comedi_device *dev, } else { s->type = COMEDI_SUBD_UNUSED; } + /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[2]; - if (this_board->i_NbrDiChannel) { - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrDiChannel; - s->maxdata = 1; - s->len_chanlist = this_board->i_NbrDiChannel; - s->range_table = &range_digital; - s->io_bits = 0; /* all bits input */ - s->insn_config = this_board->di_config; - s->insn_read = this_board->di_read; - s->insn_write = this_board->di_write; - s->insn_bits = this_board->di_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = this_board->i_NbrDiChannel; + s->maxdata = 1; + s->len_chanlist = this_board->i_NbrDiChannel; + s->range_table = &range_digital; + s->io_bits = 0; /* all bits input */ + s->insn_config = this_board->di_config; + s->insn_read = this_board->di_read; + s->insn_write = this_board->di_write; + s->insn_bits = this_board->di_bits; + /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; -- cgit v1.2.3 From 50231a91efda18612ebe76ed51ff970707756f34 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:27:03 -0700 Subject: staging: comedi: addi_apci_3120: remove test for AI subdevice The boards supported by this driver all have analog inputs. Remove the test for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 53 +++++++++++-------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 3282c54f611..9bf2ebab9ea 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -194,37 +194,32 @@ static int apci3120_attach_pci(struct comedi_device *dev, /* Allocate and Initialise AI Subdevice Structures */ s = &dev->subdevices[0]; - if (this_board->i_NbrAiChannel || (this_board->i_NbrAiChannelDiff)) { - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND - | SDF_DIFF; - if (this_board->i_NbrAiChannel) { - s->n_chan = this_board->i_NbrAiChannel; - devpriv->b_SingelDiff = 0; - } else { - s->n_chan = this_board->i_NbrAiChannelDiff; - devpriv->b_SingelDiff = 1; - } - s->maxdata = this_board->i_AiMaxdata; - s->len_chanlist = this_board->i_AiChannelList; - s->range_table = this_board->pr_AiRangelist; - - /* Set the initialisation flag */ - devpriv->b_AiInitialisation = 1; - - s->insn_config = this_board->ai_config; - s->insn_read = this_board->ai_read; - s->insn_write = this_board->ai_write; - s->insn_bits = this_board->ai_bits; - s->do_cmdtest = this_board->ai_cmdtest; - s->do_cmd = this_board->ai_cmd; - s->cancel = this_board->ai_cancel; - + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_COMMON | SDF_GROUND + | SDF_DIFF; + if (this_board->i_NbrAiChannel) { + s->n_chan = this_board->i_NbrAiChannel; + devpriv->b_SingelDiff = 0; } else { - s->type = COMEDI_SUBD_UNUSED; + s->n_chan = this_board->i_NbrAiChannelDiff; + devpriv->b_SingelDiff = 1; } + s->maxdata = this_board->i_AiMaxdata; + s->len_chanlist = this_board->i_AiChannelList; + s->range_table = this_board->pr_AiRangelist; + + /* Set the initialisation flag */ + devpriv->b_AiInitialisation = 1; + + s->insn_config = this_board->ai_config; + s->insn_read = this_board->ai_read; + s->insn_write = this_board->ai_write; + s->insn_bits = this_board->ai_bits; + s->do_cmdtest = this_board->ai_cmdtest; + s->do_cmd = this_board->ai_cmd; + s->cancel = this_board->ai_cancel; /* Allocate and Initialise AO Subdevice Structures */ s = &dev->subdevices[1]; -- cgit v1.2.3 From 8f1ff0a38a18fd21696df8b1c1307265aa9db6ae Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:27:18 -0700 Subject: staging: comedi: addi_apci_3120: clarify timer subdevice init The two boards supported by this driver use the same functions for the comedi operations. Remove this data from the boardinfo to clarify the subdevice init. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 9bf2ebab9ea..03edcc8dc87 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -45,9 +45,6 @@ static const struct addi_board apci3120_boardtypes[] = { .do_config = i_APCI3120_InsnConfigDigitalOutput, .do_write = i_APCI3120_InsnWriteDigitalOutput, .do_bits = i_APCI3120_InsnBitsDigitalOutput, - .timer_config = i_APCI3120_InsnConfigTimer, - .timer_write = i_APCI3120_InsnWriteTimer, - .timer_read = i_APCI3120_InsnReadTimer, }, { .pc_DriverName = "apci3001", .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, @@ -78,9 +75,6 @@ static const struct addi_board apci3120_boardtypes[] = { .do_config = i_APCI3120_InsnConfigDigitalOutput, .do_write = i_APCI3120_InsnWriteDigitalOutput, .do_bits = i_APCI3120_InsnBitsDigitalOutput, - .timer_config = i_APCI3120_InsnConfigTimer, - .timer_write = i_APCI3120_InsnWriteTimer, - .timer_read = i_APCI3120_InsnReadTimer, }, }; @@ -276,10 +270,9 @@ static int apci3120_attach_pci(struct comedi_device *dev, s->len_chanlist = 1; s->range_table = &range_digital; - s->insn_write = this_board->timer_write; - s->insn_read = this_board->timer_read; - s->insn_config = this_board->timer_config; - s->insn_bits = this_board->timer_bits; + s->insn_write = i_APCI3120_InsnWriteTimer; + s->insn_read = i_APCI3120_InsnReadTimer; + s->insn_config = i_APCI3120_InsnConfigTimer; /* Allocate and Initialise TTL */ s = &dev->subdevices[5]; -- cgit v1.2.3 From d8b29d6aa677ec0c3428d8d61a59c2bc61290eb7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:27:33 -0700 Subject: staging: comedi: addi_apci_3120: clarify DO subdevice init The two boards supported by this driver use the same functions for the comedi operations. Remove this data from the boardinfo to clarify the subdevice init. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 03edcc8dc87..3a1b1e46ffd 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -42,9 +42,6 @@ static const struct addi_board apci3120_boardtypes[] = { .ao_write = i_APCI3120_InsnWriteAnalogOutput, .di_read = i_APCI3120_InsnReadDigitalInput, .di_bits = i_APCI3120_InsnBitsDigitalInput, - .do_config = i_APCI3120_InsnConfigDigitalOutput, - .do_write = i_APCI3120_InsnWriteDigitalOutput, - .do_bits = i_APCI3120_InsnBitsDigitalOutput, }, { .pc_DriverName = "apci3001", .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, @@ -72,9 +69,6 @@ static const struct addi_board apci3120_boardtypes[] = { .ai_cancel = i_APCI3120_StopCyclicAcquisition, .di_read = i_APCI3120_InsnReadDigitalInput, .di_bits = i_APCI3120_InsnBitsDigitalInput, - .do_config = i_APCI3120_InsnConfigDigitalOutput, - .do_write = i_APCI3120_InsnWriteDigitalOutput, - .do_bits = i_APCI3120_InsnBitsDigitalOutput, }, }; @@ -256,10 +250,9 @@ static int apci3120_attach_pci(struct comedi_device *dev, s->io_bits = 0xf; /* all bits output */ /* insn_config - for digital output memory */ - s->insn_config = this_board->do_config; - s->insn_write = this_board->do_write; - s->insn_bits = this_board->do_bits; - s->insn_read = this_board->do_read; + s->insn_config = i_APCI3120_InsnConfigDigitalOutput; + s->insn_write = i_APCI3120_InsnWriteDigitalOutput; + s->insn_bits = i_APCI3120_InsnBitsDigitalOutput; /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[4]; -- cgit v1.2.3 From e0f8f2d26d8ec9cd6597fa119107c5d6d2d0343e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:27:47 -0700 Subject: The two boards supported by this driver use the same functions for the comedi operations. Remove this data from the boardinfo to clarify the subdevice init. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 3a1b1e46ffd..b0b91e51c2f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -40,8 +40,6 @@ static const struct addi_board apci3120_boardtypes[] = { .ai_cmd = i_APCI3120_CommandAnalogInput, .ai_cancel = i_APCI3120_StopCyclicAcquisition, .ao_write = i_APCI3120_InsnWriteAnalogOutput, - .di_read = i_APCI3120_InsnReadDigitalInput, - .di_bits = i_APCI3120_InsnBitsDigitalInput, }, { .pc_DriverName = "apci3001", .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, @@ -67,8 +65,6 @@ static const struct addi_board apci3120_boardtypes[] = { .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, .ai_cmd = i_APCI3120_CommandAnalogInput, .ai_cancel = i_APCI3120_StopCyclicAcquisition, - .di_read = i_APCI3120_InsnReadDigitalInput, - .di_bits = i_APCI3120_InsnBitsDigitalInput, }, }; @@ -233,10 +229,8 @@ static int apci3120_attach_pci(struct comedi_device *dev, s->len_chanlist = this_board->i_NbrDiChannel; s->range_table = &range_digital; s->io_bits = 0; /* all bits input */ - s->insn_config = this_board->di_config; - s->insn_read = this_board->di_read; - s->insn_write = this_board->di_write; - s->insn_bits = this_board->di_bits; + s->insn_read = i_APCI3120_InsnReadDigitalInput; + s->insn_bits = i_APCI3120_InsnBitsDigitalInput; /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[3]; -- cgit v1.2.3 From 2a8796d65cec1985148e08308adef3e7f5eccbda Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:28:11 -0700 Subject: staging: comedi: addi_apci_3120: clarify AI subdevice init The two boards supported by this driver use the same functions for the comedi operations. Remove this data from the boardinfo to clarify the subdevice init. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index b0b91e51c2f..e4be0e66a6f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -34,11 +34,6 @@ static const struct addi_board apci3120_boardtypes[] = { .ui_MinDelaytimeNs = 100000, .interrupt = v_APCI3120_Interrupt, .reset = i_APCI3120_Reset, - .ai_config = i_APCI3120_InsnConfigAnalogInput, - .ai_read = i_APCI3120_InsnReadAnalogInput, - .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, - .ai_cmd = i_APCI3120_CommandAnalogInput, - .ai_cancel = i_APCI3120_StopCyclicAcquisition, .ao_write = i_APCI3120_InsnWriteAnalogOutput, }, { .pc_DriverName = "apci3001", @@ -60,11 +55,6 @@ static const struct addi_board apci3120_boardtypes[] = { .ui_MinDelaytimeNs = 100000, .interrupt = v_APCI3120_Interrupt, .reset = i_APCI3120_Reset, - .ai_config = i_APCI3120_InsnConfigAnalogInput, - .ai_read = i_APCI3120_InsnReadAnalogInput, - .ai_cmdtest = i_APCI3120_CommandTestAnalogInput, - .ai_cmd = i_APCI3120_CommandAnalogInput, - .ai_cancel = i_APCI3120_StopCyclicAcquisition, }, }; @@ -197,13 +187,11 @@ static int apci3120_attach_pci(struct comedi_device *dev, /* Set the initialisation flag */ devpriv->b_AiInitialisation = 1; - s->insn_config = this_board->ai_config; - s->insn_read = this_board->ai_read; - s->insn_write = this_board->ai_write; - s->insn_bits = this_board->ai_bits; - s->do_cmdtest = this_board->ai_cmdtest; - s->do_cmd = this_board->ai_cmd; - s->cancel = this_board->ai_cancel; + s->insn_config = i_APCI3120_InsnConfigAnalogInput; + s->insn_read = i_APCI3120_InsnReadAnalogInput; + s->do_cmdtest = i_APCI3120_CommandTestAnalogInput; + s->do_cmd = i_APCI3120_CommandAnalogInput; + s->cancel = i_APCI3120_StopCyclicAcquisition; /* Allocate and Initialise AO Subdevice Structures */ s = &dev->subdevices[1]; -- cgit v1.2.3 From f538c37ded4b33765cc942b1e2e64f1504db4101 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:28:24 -0700 Subject: staging: comedi: addi_apci_3120: remove i_ADDI_Reset() This driver is now separate from the "common" code used with the addi-data drivers. There is no need to use i_ADDI_Reset() to call the correct "reset" function. Remove the i_ADDI_Reset() function and the 'reset' pointer to the real function from the boardinfo and just call the function directly where needed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index e4be0e66a6f..dfe4ba173f8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -33,7 +33,6 @@ static const struct addi_board apci3120_boardtypes[] = { .ui_MinAcquisitiontimeNs = 10000, .ui_MinDelaytimeNs = 100000, .interrupt = v_APCI3120_Interrupt, - .reset = i_APCI3120_Reset, .ao_write = i_APCI3120_InsnWriteAnalogOutput, }, { .pc_DriverName = "apci3001", @@ -54,7 +53,6 @@ static const struct addi_board apci3120_boardtypes[] = { .ui_MinAcquisitiontimeNs = 10000, .ui_MinDelaytimeNs = 100000, .interrupt = v_APCI3120_Interrupt, - .reset = i_APCI3120_Reset, }, }; @@ -67,14 +65,6 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) return IRQ_RETVAL(1); } -static int i_ADDI_Reset(struct comedi_device *dev) -{ - const struct addi_board *this_board = comedi_board(dev); - - this_board->reset(dev); - return 0; -} - static const void *addi_find_boardinfo(struct comedi_device *dev, struct pci_dev *pcidev) { @@ -257,7 +247,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, s = &dev->subdevices[6]; s->type = COMEDI_SUBD_UNUSED; - i_ADDI_Reset(dev); + i_APCI3120_Reset(dev); return 0; } @@ -269,7 +259,7 @@ static void apci3120_detach(struct comedi_device *dev) if (devpriv) { if (dev->iobase) - i_ADDI_Reset(dev); + i_APCI3120_Reset(dev); if (dev->irq) free_irq(dev->irq, dev); if ((this_board->pc_EepromChip == NULL) || -- cgit v1.2.3 From aea9c4e284a10f7154ecc4af50d0a2778053aacb Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:28:41 -0700 Subject: staging: comedi: addi_apci_3120: fix the number of subdevices The addi-data "common" code always allocates 7 subdevices. This driver is now separate from that code so we can remove the unused subdevices. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index dfe4ba173f8..9ef9275c877 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -88,7 +88,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, const struct addi_board *this_board; struct addi_private *devpriv; struct comedi_subdevice *s; - int ret, pages, i, n_subdevices; + int ret, pages, i; this_board = addi_find_boardinfo(dev, pcidev); if (!this_board) @@ -151,8 +151,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, if (devpriv->ul_DmaBufferVirtual[1]) devpriv->b_DmaDoubleBuffer = 1; - n_subdevices = 7; - ret = comedi_alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, 5); if (ret) return ret; @@ -239,14 +238,6 @@ static int apci3120_attach_pci(struct comedi_device *dev, s->insn_read = i_APCI3120_InsnReadTimer; s->insn_config = i_APCI3120_InsnConfigTimer; - /* Allocate and Initialise TTL */ - s = &dev->subdevices[5]; - s->type = COMEDI_SUBD_UNUSED; - - /* EEPROM */ - s = &dev->subdevices[6]; - s->type = COMEDI_SUBD_UNUSED; - i_APCI3120_Reset(dev); return 0; } -- cgit v1.2.3 From 65fe75a627dee4fcf23c8872213e88a273d735ec Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:28:57 -0700 Subject: staging: comedi: addi_apci_3120: remove the 'i_IorangeBase*' These values in the boardinfor were used in the common addi-data attach code to work out use of the PCI bars. Since this driver has a localized attach we already know the use of the bars so this information in the boardinfo is unnecessary. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 9ef9275c877..7a18f7a381a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -15,9 +15,6 @@ static const struct addi_board apci3120_boardtypes[] = { .pc_DriverName = "apci3120", .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, .i_DeviceId = 0x818D, - .i_IorangeBase0 = AMCC_OP_REG_SIZE, - .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, - .i_IorangeBase2 = 8, .i_NbrAiChannel = 16, .i_NbrAiChannelDiff = 8, .i_AiChannelList = 16, @@ -38,9 +35,6 @@ static const struct addi_board apci3120_boardtypes[] = { .pc_DriverName = "apci3001", .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, .i_DeviceId = 0x828D, - .i_IorangeBase0 = AMCC_OP_REG_SIZE, - .i_IorangeBase1 = APCI3120_ADDRESS_RANGE, - .i_IorangeBase2 = 8, .i_NbrAiChannel = 16, .i_NbrAiChannelDiff = 8, .i_AiChannelList = 16, @@ -106,11 +100,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, return ret; pci_set_master(pcidev); - if (this_board->i_IorangeBase1) - dev->iobase = pci_resource_start(pcidev, 1); - else - dev->iobase = pci_resource_start(pcidev, 0); - + dev->iobase = pci_resource_start(pcidev, 1); devpriv->iobase = dev->iobase; devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); -- cgit v1.2.3 From 1ba296b95613d279e9bb6ec93420a42159074782 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:29:13 -0700 Subject: staging: comedi: addi_apci_3120: remove 'pr_AiRangelist' Both boards supported by this driver have the same analog input ranges. Remove the boardinfo for it and just init the subdevice directly. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 7a18f7a381a..a2fe789f01e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -21,7 +21,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrAoChannel = 8, .i_AiMaxdata = 0xffff, .i_AoMaxdata = 0x3fff, - .pr_AiRangelist = &range_apci3120_ai, .pr_AoRangelist = &range_apci3120_ao, .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, @@ -39,7 +38,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrAiChannelDiff = 8, .i_AiChannelList = 16, .i_AiMaxdata = 0xfff, - .pr_AiRangelist = &range_apci3120_ai, .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, @@ -161,7 +159,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, } s->maxdata = this_board->i_AiMaxdata; s->len_chanlist = this_board->i_AiChannelList; - s->range_table = this_board->pr_AiRangelist; + s->range_table = &range_apci3120_ai; /* Set the initialisation flag */ devpriv->b_AiInitialisation = 1; -- cgit v1.2.3 From 97e998de5dd8c06900badb6822bf81497448c92a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:29:30 -0700 Subject: staging: comedi: addi_apci_3120: remove 'ui_MinAcquisitiontimeNs' Both boards supported by this driver have the same minimum acquisition time.. Remove the boardinfo for it and just open code the value in i_APCI3120_CommandTestAnalogInput(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 15 +++++---------- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 -- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 73af970a44e..ac2e4110f2f 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -787,20 +787,15 @@ static int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, if (cmd->convert_src == TRIG_TIMER) { /* Test Acquisition timing */ if (cmd->scan_begin_src == TRIG_TIMER) { - if ((cmd->convert_arg) - && (cmd->convert_arg < - this_board->ui_MinAcquisitiontimeNs)) { - cmd->convert_arg = - this_board->ui_MinAcquisitiontimeNs; + if (cmd->convert_arg && + (cmd->convert_arg < 10000)) { + cmd->convert_arg = 10000; err++; } } else { - if (cmd->convert_arg < - this_board->ui_MinAcquisitiontimeNs) { - cmd->convert_arg = - this_board->ui_MinAcquisitiontimeNs; + if (cmd->convert_arg < 10000) { + cmd->convert_arg = 10000; err++; - } } } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index a2fe789f01e..8e32fbbf354 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -26,7 +26,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, .b_AvailableConvertUnit = 1, - .ui_MinAcquisitiontimeNs = 10000, .ui_MinDelaytimeNs = 100000, .interrupt = v_APCI3120_Interrupt, .ao_write = i_APCI3120_InsnWriteAnalogOutput, @@ -42,7 +41,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, .b_AvailableConvertUnit = 1, - .ui_MinAcquisitiontimeNs = 10000, .ui_MinDelaytimeNs = 100000, .interrupt = v_APCI3120_Interrupt, }, -- cgit v1.2.3 From dfb8a4abe90db760b87308f47f8a74eb17288ba1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:29:46 -0700 Subject: staging: comedi: addi_apci_3120: remove 'ui_MinDelaytimeNs' Both boards supported by this driver have the same minimum delay time. Remove the boardinfo for it and just open code the value in i_APCI3120_CommandTestAnalogInput(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c | 6 ++---- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index ac2e4110f2f..094691769bd 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -777,10 +777,8 @@ static int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, } if (cmd->scan_begin_src == TRIG_TIMER) { /* Test Delay timing */ - if (cmd->scan_begin_arg < - this_board->ui_MinDelaytimeNs) { - cmd->scan_begin_arg = - this_board->ui_MinDelaytimeNs; + if (cmd->scan_begin_arg < 100000) { + cmd->scan_begin_arg = 100000; err++; } } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 8e32fbbf354..9ec6bb19954 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -26,7 +26,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, .b_AvailableConvertUnit = 1, - .ui_MinDelaytimeNs = 100000, .interrupt = v_APCI3120_Interrupt, .ao_write = i_APCI3120_InsnWriteAnalogOutput, }, { @@ -41,7 +40,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, .b_AvailableConvertUnit = 1, - .ui_MinDelaytimeNs = 100000, .interrupt = v_APCI3120_Interrupt, }, }; -- cgit v1.2.3 From 2e8fcd182002b37378caea900296026577aced03 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:30:02 -0700 Subject: staging: comedi: addi_apci_3120: remove 'b_AvailableConvertUnit' This boardinfo value is not used by the driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 9ec6bb19954..9eb49ed5955 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -25,7 +25,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, - .b_AvailableConvertUnit = 1, .interrupt = v_APCI3120_Interrupt, .ao_write = i_APCI3120_InsnWriteAnalogOutput, }, { @@ -39,7 +38,6 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, - .b_AvailableConvertUnit = 1, .interrupt = v_APCI3120_Interrupt, }, }; -- cgit v1.2.3 From 0bb482e25c6c4e5084a0e0847307736bf090adec Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:30:17 -0700 Subject: staging: comedi: addi_apci_3120: clarify AO subdevice init Only the apci3120 board supports an analog output subdevice. The boardinfo indicates this by setting the 'i_NbrAoChannel' value. The range table as well as the function used for the insn_write operation are fixed for the analog outputs. Remove this information from the boardinfo and use it directly in the subdevice init. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 9eb49ed5955..6ca3a3c6613 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -21,12 +21,10 @@ static const struct addi_board apci3120_boardtypes[] = { .i_NbrAoChannel = 8, .i_AiMaxdata = 0xffff, .i_AoMaxdata = 0x3fff, - .pr_AoRangelist = &range_apci3120_ao, .i_NbrDiChannel = 4, .i_NbrDoChannel = 4, .i_DoMaxdata = 0x0f, .interrupt = v_APCI3120_Interrupt, - .ao_write = i_APCI3120_InsnWriteAnalogOutput, }, { .pc_DriverName = "apci3001", .i_VendorId = PCI_VENDOR_ID_ADDIDATA_OLD, @@ -172,9 +170,8 @@ static int apci3120_attach_pci(struct comedi_device *dev, s->n_chan = this_board->i_NbrAoChannel; s->maxdata = this_board->i_AoMaxdata; s->len_chanlist = this_board->i_NbrAoChannel; - s->range_table = this_board->pr_AoRangelist; - s->insn_config = this_board->ao_config; - s->insn_write = this_board->ao_write; + s->range_table = &range_apci3120_ao; + s->insn_write = i_APCI3120_InsnWriteAnalogOutput; } else { s->type = COMEDI_SUBD_UNUSED; } -- cgit v1.2.3 From 97641816b58fccaf157ab5093f55f0a319d7a55f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:30:37 -0700 Subject: staging: comedi: addi_apci_3120: cleanup apci3120_detach() This driver always tried to allocate the dma buffers so they need to be free'd when the board is detached. Remove the unneeded tests for the eeprom chip and bring the code back an indent. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 6ca3a3c6613..e87d400df4f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -223,7 +223,6 @@ static int apci3120_attach_pci(struct comedi_device *dev, static void apci3120_detach(struct comedi_device *dev) { - const struct addi_board *this_board = comedi_board(dev); struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct addi_private *devpriv = dev->private; @@ -232,20 +231,15 @@ static void apci3120_detach(struct comedi_device *dev) i_APCI3120_Reset(dev); if (dev->irq) free_irq(dev->irq, dev); - if ((this_board->pc_EepromChip == NULL) || - (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { - if (devpriv->ul_DmaBufferVirtual[0]) { - free_pages((unsigned long)devpriv-> - ul_DmaBufferVirtual[0], - devpriv->ui_DmaBufferPages[0]); - } - if (devpriv->ul_DmaBufferVirtual[1]) { - free_pages((unsigned long)devpriv-> - ul_DmaBufferVirtual[1], - devpriv->ui_DmaBufferPages[1]); - } - } else { - iounmap(devpriv->dw_AiBase); + if (devpriv->ul_DmaBufferVirtual[0]) { + free_pages((unsigned long)devpriv-> + ul_DmaBufferVirtual[0], + devpriv->ui_DmaBufferPages[0]); + } + if (devpriv->ul_DmaBufferVirtual[1]) { + free_pages((unsigned long)devpriv-> + ul_DmaBufferVirtual[1], + devpriv->ui_DmaBufferPages[1]); } } if (pcidev) { -- cgit v1.2.3 From 7dd2358156285dc525d309dd1347d4fdab5c0773 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:30:53 -0700 Subject: staging: comedi: addi_apci_3120: remove COMEDI_SUBD_TTLIO define This define is not used by the driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index e87d400df4f..9b9ca004635 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -6,10 +6,6 @@ #include "addi-data/hwdrv_apci3120.c" -#ifndef COMEDI_SUBD_TTLIO -#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ -#endif - static const struct addi_board apci3120_boardtypes[] = { { .pc_DriverName = "apci3120", -- cgit v1.2.3 From 60eebfad7a2191176fd8af323c1fc6821c8cd61a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Thu, 1 Nov 2012 17:31:10 -0700 Subject: staging: comedi: addi_apci_3120: cleanup addi_find_boardinfo() This driver uses the comedi PCI auto attach mechanism and the comedi core does not use the boardinfo during the attach. Now that this driver has the attach separated from addi_common.c we can remove passing the boardinfo in the comedi_driver and cleanup the code that finds the boardinfo. Also, rename addi_find_boardinfo() so it has namespace associated with this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3120.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 9b9ca004635..da3112624b7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -45,19 +45,17 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) return IRQ_RETVAL(1); } -static const void *addi_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) +static const void *apci3120_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - const void *p = dev->driver->board_name; const struct addi_board *this_board; int i; - for (i = 0; i < dev->driver->num_names; i++) { - this_board = p; + for (i = 0; i < ARRAY_SIZE(apci3120_boardtypes); i++) { + this_board = &apci3120_boardtypes[i]; if (this_board->i_VendorId == pcidev->vendor && this_board->i_DeviceId == pcidev->device) return this_board; - p += dev->driver->offset; } return NULL; } @@ -70,7 +68,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, struct comedi_subdevice *s; int ret, pages, i; - this_board = addi_find_boardinfo(dev, pcidev); + this_board = apci3120_find_boardinfo(dev, pcidev); if (!this_board) return -ENODEV; dev->board_ptr = this_board; @@ -249,9 +247,6 @@ static struct comedi_driver apci3120_driver = { .module = THIS_MODULE, .attach_pci = apci3120_attach_pci, .detach = apci3120_detach, - .num_names = ARRAY_SIZE(apci3120_boardtypes), - .board_name = &apci3120_boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), }; static int __devinit apci3120_pci_probe(struct pci_dev *dev, -- cgit v1.2.3 From 4ab07c96d2f1a98ef8561bad61c92ffc2652cbda Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Thu, 1 Nov 2012 22:56:42 +0000 Subject: staging: et131x: Remove unused buffer[1,2] variables. The fbr_lookup struct variables buffer1 and buffer2 are only assigned and never used, so remove them. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 1534582eedc..d1f519267f5 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -284,8 +284,6 @@ struct rx_status_block { */ struct fbr_lookup { void *virt[MAX_DESC_PER_RING_RX]; - void *buffer1[MAX_DESC_PER_RING_RX]; - void *buffer2[MAX_DESC_PER_RING_RX]; u32 bus_high[MAX_DESC_PER_RING_RX]; u32 bus_low[MAX_DESC_PER_RING_RX]; void *ring_virtaddr; @@ -2405,11 +2403,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) lower_32_bits(fbr_tmp_physaddr); fbr_tmp_physaddr += rx_ring->fbr[id]->buffsize; - - rx_ring->fbr[id]->buffer1[index] = - rx_ring->fbr[id]->virt[index]; - rx_ring->fbr[id]->buffer2[index] = - rx_ring->fbr[id]->virt[index] - 4; } } } -- cgit v1.2.3 From f0ada6784f680d844d890f5c240d19c8649594e5 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Thu, 1 Nov 2012 22:56:43 +0000 Subject: staging: et131x: Align ring_index and fbr[] indicies A ring_index value of 0 is being used to reference the free buffer ring fbr[1] and ring_index=1 is used to reference fbr[0]. Avoid this confusing referencing by swapping the indicies so that ring_index=0 refers to fbr[0] and vice versa. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 105 ++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 62 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index d1f519267f5..69a07299b74 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -299,11 +299,6 @@ struct fbr_lookup { /* * struct rx_ring is the sructure representing the adaptor's local * reference(s) to the rings - * - ****************************************************************************** - * IMPORTANT NOTE :- fbr_lookup *fbr[NUM_FBRS] uses index 0 to refer to FBR1 - * and index 1 to refer to FRB0 - ****************************************************************************** */ struct rx_ring { struct fbr_lookup *fbr[NUM_FBRS]; @@ -856,27 +851,27 @@ static void et131x_rx_dma_enable(struct et131x_adapter *adapter) /* Setup the receive dma configuration register for normal operation */ u32 csr = 0x2000; /* FBR1 enable */ - if (adapter->rx_ring.fbr[0]->buffsize == 4096) + if (adapter->rx_ring.fbr[1]->buffsize == 4096) csr |= 0x0800; - else if (adapter->rx_ring.fbr[0]->buffsize == 8192) + else if (adapter->rx_ring.fbr[1]->buffsize == 8192) csr |= 0x1000; - else if (adapter->rx_ring.fbr[0]->buffsize == 16384) + else if (adapter->rx_ring.fbr[1]->buffsize == 16384) csr |= 0x1800; csr |= 0x0400; /* FBR0 enable */ - if (adapter->rx_ring.fbr[1]->buffsize == 256) + if (adapter->rx_ring.fbr[0]->buffsize == 256) csr |= 0x0100; - else if (adapter->rx_ring.fbr[1]->buffsize == 512) + else if (adapter->rx_ring.fbr[0]->buffsize == 512) csr |= 0x0200; - else if (adapter->rx_ring.fbr[1]->buffsize == 1024) + else if (adapter->rx_ring.fbr[0]->buffsize == 1024) csr |= 0x0300; writel(csr, &adapter->regs->rxdma.csr); csr = readl(&adapter->regs->rxdma.csr); - if ((csr & 0x00020000) != 0) { + if (csr & 0x00020000) { udelay(5); csr = readl(&adapter->regs->rxdma.csr); - if ((csr & 0x00020000) != 0) { + if (csr & 0x00020000) { dev_err(&adapter->pdev->dev, "RX Dma failed to exit halt state. CSR 0x%08x\n", csr); @@ -1867,17 +1862,17 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) u32 *base_lo; if (id == 0) { - num_des = &rx_dma->fbr1_num_des; - full_offset = &rx_dma->fbr1_full_offset; - min_des = &rx_dma->fbr1_min_des; - base_hi = &rx_dma->fbr1_base_hi; - base_lo = &rx_dma->fbr1_base_lo; - } else { num_des = &rx_dma->fbr0_num_des; full_offset = &rx_dma->fbr0_full_offset; min_des = &rx_dma->fbr0_min_des; base_hi = &rx_dma->fbr0_base_hi; base_lo = &rx_dma->fbr0_base_lo; + } else { + num_des = &rx_dma->fbr1_num_des; + full_offset = &rx_dma->fbr1_full_offset; + min_des = &rx_dma->fbr1_min_des; + base_hi = &rx_dma->fbr1_base_hi; + base_lo = &rx_dma->fbr1_base_lo; } /* Now's the best time to initialize FBR contents */ @@ -2278,8 +2273,8 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) rx_ring = &adapter->rx_ring; /* Alloc memory for the lookup table */ - rx_ring->fbr[1] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL); rx_ring->fbr[0] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL); + rx_ring->fbr[1] = kmalloc(sizeof(struct fbr_lookup), GFP_KERNEL); /* The first thing we will do is configure the sizes of the buffer * rings. These will change based on jumbo packet support. Larger @@ -2300,25 +2295,25 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) */ if (adapter->registry_jumbo_packet < 2048) { - rx_ring->fbr[1]->buffsize = 256; - rx_ring->fbr[1]->num_entries = 512; - rx_ring->fbr[0]->buffsize = 2048; + rx_ring->fbr[0]->buffsize = 256; rx_ring->fbr[0]->num_entries = 512; + rx_ring->fbr[1]->buffsize = 2048; + rx_ring->fbr[1]->num_entries = 512; } else if (adapter->registry_jumbo_packet < 4096) { - rx_ring->fbr[1]->buffsize = 512; - rx_ring->fbr[1]->num_entries = 1024; - rx_ring->fbr[0]->buffsize = 4096; - rx_ring->fbr[0]->num_entries = 512; + rx_ring->fbr[0]->buffsize = 512; + rx_ring->fbr[0]->num_entries = 1024; + rx_ring->fbr[1]->buffsize = 4096; + rx_ring->fbr[1]->num_entries = 512; } else { - rx_ring->fbr[1]->buffsize = 1024; - rx_ring->fbr[1]->num_entries = 768; - rx_ring->fbr[0]->buffsize = 16384; - rx_ring->fbr[0]->num_entries = 128; + rx_ring->fbr[0]->buffsize = 1024; + rx_ring->fbr[0]->num_entries = 768; + rx_ring->fbr[1]->buffsize = 16384; + rx_ring->fbr[1]->num_entries = 128; } adapter->rx_ring.psr_num_entries = - adapter->rx_ring.fbr[1]->num_entries + - adapter->rx_ring.fbr[0]->num_entries; + adapter->rx_ring.fbr[0]->num_entries + + adapter->rx_ring.fbr[1]->num_entries; for (id = 0; id < NUM_FBRS; id++) { /* Allocate an area of memory for Free Buffer Ring */ @@ -2565,8 +2560,8 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) } /* Free the FBR Lookup Table */ - kfree(rx_ring->fbr[1]); kfree(rx_ring->fbr[0]); + kfree(rx_ring->fbr[1]); /* Reset Counters */ rx_ring->num_ready_recv = 0; @@ -2660,36 +2655,31 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) /* We don't use any of the OOB data besides status. Otherwise, we * need to clean up OOB data */ - if ((ring_index == 0 && buff_index < rx_local->fbr[1]->num_entries) || - (ring_index == 1 && buff_index < rx_local->fbr[0]->num_entries)) { + if (buff_index < rx_local->fbr[ring_index]->num_entries) { u32 *offset; - u8 id; struct fbr_desc *next; spin_lock_irqsave(&adapter->fbr_lock, flags); - if (ring_index == 1) { - id = 0; - offset = &rx_dma->fbr1_full_offset; - } else { - id = 1; + if (ring_index == 0) offset = &rx_dma->fbr0_full_offset; - } + else + offset = &rx_dma->fbr1_full_offset; - next = (struct fbr_desc *) (rx_local->fbr[id]->ring_virtaddr) + - INDEX10(rx_local->fbr[id]->local_full); + next = (struct fbr_desc *) (rx_local->fbr[ring_index]->ring_virtaddr) + + INDEX10(rx_local->fbr[ring_index]->local_full); /* Handle the Free Buffer Ring advancement here. Write * the PA / Buffer Index for the returned buffer into * the oldest (next to be freed)FBR entry */ - next->addr_hi = rx_local->fbr[id]->bus_high[buff_index]; - next->addr_lo = rx_local->fbr[id]->bus_low[buff_index]; + next->addr_hi = rx_local->fbr[ring_index]->bus_high[buff_index]; + next->addr_lo = rx_local->fbr[ring_index]->bus_low[buff_index]; next->word2 = buff_index; - writel(bump_free_buff_ring(&rx_local->fbr[id]->local_full, - rx_local->fbr[id]->num_entries - 1), - offset); + writel(bump_free_buff_ring(&rx_local->fbr[ring_index]->local_full, + rx_local->fbr[ring_index]->num_entries - 1), + offset); spin_unlock_irqrestore(&adapter->fbr_lock, flags); } else { @@ -2772,10 +2762,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) writel(rx_local->local_psr_full, &adapter->regs->rxdma.psr_full_offset); if (ring_index > 1 || - (ring_index == 0 && - buff_index > rx_local->fbr[1]->num_entries - 1) || - (ring_index == 1 && - buff_index > rx_local->fbr[0]->num_entries - 1)) { + buff_index > rx_local->fbr[ring_index]->num_entries - 1) { /* Illegal buffer or ring index cannot be used by S/W*/ dev_err(&adapter->pdev->dev, "NICRxPkts PSR Entry %d indicates length of %d and/or bad bi(%d)\n", @@ -2828,12 +2815,7 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) && !(adapter->packet_filter & ET131X_PACKET_TYPE_PROMISCUOUS) && !(adapter->packet_filter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { - /* - * Note - ring_index for fbr[] array is reversed - * 1 for FBR0 etc - */ - buf = rx_local->fbr[(ring_index == 0 ? 1 : 0)]-> - virt[buff_index]; + buf = rx_local->fbr[ring_index]->virt[buff_index]; /* Loop through our list to see if the destination * address of this packet matches one in our list. @@ -2886,9 +2868,8 @@ static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) adapter->net_stats.rx_bytes += rfd->len; - /* Note - ring_index for fbr[] array is reversed, 1 for FBR0 etc */ memcpy(skb_put(skb, rfd->len), - rx_local->fbr[(ring_index == 0 ? 1 : 0)]->virt[buff_index], + rx_local->fbr[ring_index]->virt[buff_index], rfd->len); skb->dev = adapter->netdev; -- cgit v1.2.3 From 32adf1e5533c9cb9fa8c2ad04a806500c518fb1f Mon Sep 17 00:00:00 2001 From: Kumar Amit Mehta Date: Fri, 2 Nov 2012 02:19:45 -0700 Subject: staging: wlan-ng: hfa384x_usb.c: fixed a coding style issue checkpatch.pl throws error message for the current code. This patch fixes coding style issue. Signed-off-by: Kumar Amit Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/hfa384x_usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c index f180c3d8b01..c1a8cb62515 100644 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ b/drivers/staging/wlan-ng/hfa384x_usb.c @@ -171,11 +171,11 @@ static void hfa384x_ctlxout_callback(struct urb *urb); static void hfa384x_usbin_callback(struct urb *urb); static void -hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t * usbin); +hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin); static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb); -static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t * usbin); +static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin); static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout); @@ -285,7 +285,7 @@ static inline const char *ctlxstr(CTLX_STATE s) return ctlx_str[s]; }; -static inline hfa384x_usbctlx_t *get_active_ctlx(hfa384x_t * hw) +static inline hfa384x_usbctlx_t *get_active_ctlx(hfa384x_t *hw) { return list_entry(hw->ctlxq.active.next, hfa384x_usbctlx_t, list); } -- cgit v1.2.3 From bb29ea142d0e990b6c54d18860b7f7d4a5a5a337 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Fri, 2 Nov 2012 13:55:48 +0900 Subject: staging/comedi: Use dev_ printks in ni_tiocmd.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... - WARNING: Prefer netdev_notice(netdev, ... then dev_notice(dev, ... then pr_notice(... to printk(KERN_NOTICE ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tiocmd.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 8ee93d359be..11a377a6c27 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -173,7 +173,8 @@ static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async) static int ni_tio_output_cmd(struct ni_gpct *counter, struct comedi_async *async) { - printk(KERN_ERR "ni_tio: output commands not yet implemented.\n"); + dev_err(counter->counter_dev->dev->class_dev, + "output commands not yet implemented.\n"); return -ENOTSUPP; counter->mite_chan->dir = COMEDI_OUTPUT; @@ -219,7 +220,10 @@ int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async) spin_lock_irqsave(&counter->lock, flags); if (counter->mite_chan == NULL) { - printk(KERN_ERR "ni_tio: commands only supported with DMA. Interrupt-driven commands not yet implemented.\n"); + dev_err(counter->counter_dev->dev->class_dev, + "commands only supported with DMA. "); + dev_err(counter->counter_dev->dev->class_dev, + "Interrupt-driven commands not yet implemented.\n"); retval = -EIO; } else { retval = ni_tio_cmd_setup(counter, async); @@ -427,8 +431,9 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, NITIO_Gxx_Joint_Status2_Reg (counter->counter_index)) & Gi_Permanent_Stale_Bit(counter->counter_index)) { - printk(KERN_INFO "%s: Gi_Permanent_Stale_Data detected.\n", - __func__); + dev_info(counter->counter_dev->dev->class_dev, + "%s: Gi_Permanent_Stale_Data detected.\n", + __func__); if (perm_stale_data) *perm_stale_data = 1; } @@ -448,7 +453,8 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error, &perm_stale_data, NULL); if (gate_error) { - printk(KERN_NOTICE "%s: Gi_Gate_Error detected.\n", __func__); + dev_notice(counter->counter_dev->dev->class_dev, + "%s: Gi_Gate_Error detected.\n", __func__); s->async->events |= COMEDI_CB_OVERFLOW; } if (perm_stale_data) @@ -459,8 +465,8 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, if (read_register(counter, NITIO_Gi_DMA_Status_Reg (counter->counter_index)) & Gi_DRQ_Error_Bit) { - printk(KERN_NOTICE "%s: Gi_DRQ_Error detected.\n", - __func__); + dev_notice(counter->counter_dev->dev->class_dev, + "%s: Gi_DRQ_Error detected.\n", __func__); s->async->events |= COMEDI_CB_OVERFLOW; } break; -- cgit v1.2.3 From 5c032faa82ff8a9416fc567f4e79dd626e945cec Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:13 -0400 Subject: Staging: bcm: Fix all white space issues in InterfaceAdapter.h This patch fixes all white space issues in InterfaceAdapter.h as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 90 +++++++++++++++------------------- 1 file changed, 40 insertions(+), 50 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index 4607c265d98..9a0fbefad77 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -3,56 +3,54 @@ typedef struct _BULK_ENDP_IN { - PCHAR bulk_in_buffer; - size_t bulk_in_size; - UCHAR bulk_in_endpointAddr; - UINT bulk_in_pipe; -}BULK_ENDP_IN, *PBULK_ENDP_IN; + PCHAR bulk_in_buffer; + size_t bulk_in_size; + UCHAR bulk_in_endpointAddr; + UINT bulk_in_pipe; +} BULK_ENDP_IN, *PBULK_ENDP_IN; typedef struct _BULK_ENDP_OUT { - UCHAR bulk_out_buffer; - size_t bulk_out_size; - UCHAR bulk_out_endpointAddr; - UINT bulk_out_pipe; - //this is used when int out endpoint is used as bulk out end point - UCHAR int_out_interval; -}BULK_ENDP_OUT, *PBULK_ENDP_OUT; + UCHAR bulk_out_buffer; + size_t bulk_out_size; + UCHAR bulk_out_endpointAddr; + UINT bulk_out_pipe; + //this is used when int out endpoint is used as bulk out end point + UCHAR int_out_interval; +} BULK_ENDP_OUT, *PBULK_ENDP_OUT; typedef struct _INTR_ENDP_IN { - PCHAR int_in_buffer; - size_t int_in_size; - UCHAR int_in_endpointAddr; - UCHAR int_in_interval; - UINT int_in_pipe; -}INTR_ENDP_IN, *PINTR_ENDP_IN; + PCHAR int_in_buffer; + size_t int_in_size; + UCHAR int_in_endpointAddr; + UCHAR int_in_interval; + UINT int_in_pipe; +} INTR_ENDP_IN, *PINTR_ENDP_IN; typedef struct _INTR_ENDP_OUT { - PCHAR int_out_buffer; - size_t int_out_size; - UCHAR int_out_endpointAddr; - UCHAR int_out_interval; - UINT int_out_pipe; -}INTR_ENDP_OUT, *PINTR_ENDP_OUT; - + PCHAR int_out_buffer; + size_t int_out_size; + UCHAR int_out_endpointAddr; + UCHAR int_out_interval; + UINT int_out_pipe; +} INTR_ENDP_OUT, *PINTR_ENDP_OUT; typedef struct _USB_TCB { struct urb *urb; PVOID psIntfAdapter; BOOLEAN bUsed; -}USB_TCB, *PUSB_TCB; - +} USB_TCB, *PUSB_TCB; typedef struct _USB_RCB { struct urb *urb; PVOID psIntfAdapter; BOOLEAN bUsed; -}USB_RCB, *PUSB_RCB; +} USB_RCB, *PUSB_RCB; /* //This is the interface specific Sub-Adapter @@ -60,9 +58,8 @@ typedef struct _USB_RCB */ typedef struct _S_INTERFACE_ADAPTER { - struct usb_device * udev; - struct usb_interface * interface; - + struct usb_device *udev; + struct usb_interface *interface; /* Bulk endpoint in info */ BULK_ENDP_IN sBulkIn; /* Bulk endpoint out info */ @@ -71,27 +68,20 @@ typedef struct _S_INTERFACE_ADAPTER INTR_ENDP_IN sIntrIn; /* Interrupt endpoint out info */ INTR_ENDP_OUT sIntrOut; - - - - ULONG ulInterruptData[2]; - + ULONG ulInterruptData[2]; struct urb *psInterruptUrb; - - USB_TCB asUsbTcb[MAXIMUM_USB_TCB]; - USB_RCB asUsbRcb[MAXIMUM_USB_RCB]; - atomic_t uNumTcbUsed; - atomic_t uCurrTcb; - atomic_t uNumRcbUsed; - atomic_t uCurrRcb; - + USB_TCB asUsbTcb[MAXIMUM_USB_TCB]; + USB_RCB asUsbRcb[MAXIMUM_USB_RCB]; + atomic_t uNumTcbUsed; + atomic_t uCurrTcb; + atomic_t uNumRcbUsed; + atomic_t uCurrRcb; struct bcm_mini_adapter *psAdapter; - BOOLEAN bFlashBoot; - BOOLEAN bHighSpeedDevice ; - - BOOLEAN bSuspended; - BOOLEAN bPreparingForBusSuspend; + BOOLEAN bFlashBoot; + BOOLEAN bHighSpeedDevice; + BOOLEAN bSuspended; + BOOLEAN bPreparingForBusSuspend; struct work_struct usbSuspendWork; -}S_INTERFACE_ADAPTER,*PS_INTERFACE_ADAPTER; +} S_INTERFACE_ADAPTER, *PS_INTERFACE_ADAPTER; #endif -- cgit v1.2.3 From d0d634d31ae5922a4cba58ae11c1455bc6ca798a Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:14 -0400 Subject: Staging: bcm: Correctly format comments in InterfaceAdapter.h This patch correctly formats comments in InterfaceAdapter.h as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index 9a0fbefad77..ec37e3fef99 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -16,7 +16,7 @@ typedef struct _BULK_ENDP_OUT size_t bulk_out_size; UCHAR bulk_out_endpointAddr; UINT bulk_out_pipe; - //this is used when int out endpoint is used as bulk out end point + /* this is used when int out endpoint is used as bulk out end point */ UCHAR int_out_interval; } BULK_ENDP_OUT, *PBULK_ENDP_OUT; @@ -53,9 +53,9 @@ typedef struct _USB_RCB } USB_RCB, *PUSB_RCB; /* -//This is the interface specific Sub-Adapter -//Structure. -*/ + * This is the interface specific Sub-Adapter + * Structure. + */ typedef struct _S_INTERFACE_ADAPTER { struct usb_device *udev; -- cgit v1.2.3 From 5e1db5adb42746dca94cb26774091474d934f301 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:15 -0400 Subject: Staging: bcm: Correctly format braces in InterfaceAdapter.h This patch correctly formats braces in InterfaceAdapter.h as reported by checkpatch.pl. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index ec37e3fef99..6d411ba2f53 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -1,8 +1,7 @@ #ifndef _INTERFACE_ADAPTER_H #define _INTERFACE_ADAPTER_H -typedef struct _BULK_ENDP_IN -{ +typedef struct _BULK_ENDP_IN { PCHAR bulk_in_buffer; size_t bulk_in_size; UCHAR bulk_in_endpointAddr; @@ -10,8 +9,7 @@ typedef struct _BULK_ENDP_IN } BULK_ENDP_IN, *PBULK_ENDP_IN; -typedef struct _BULK_ENDP_OUT -{ +typedef struct _BULK_ENDP_OUT { UCHAR bulk_out_buffer; size_t bulk_out_size; UCHAR bulk_out_endpointAddr; @@ -20,8 +18,7 @@ typedef struct _BULK_ENDP_OUT UCHAR int_out_interval; } BULK_ENDP_OUT, *PBULK_ENDP_OUT; -typedef struct _INTR_ENDP_IN -{ +typedef struct _INTR_ENDP_IN { PCHAR int_in_buffer; size_t int_in_size; UCHAR int_in_endpointAddr; @@ -29,8 +26,7 @@ typedef struct _INTR_ENDP_IN UINT int_in_pipe; } INTR_ENDP_IN, *PINTR_ENDP_IN; -typedef struct _INTR_ENDP_OUT -{ +typedef struct _INTR_ENDP_OUT { PCHAR int_out_buffer; size_t int_out_size; UCHAR int_out_endpointAddr; @@ -38,15 +34,13 @@ typedef struct _INTR_ENDP_OUT UINT int_out_pipe; } INTR_ENDP_OUT, *PINTR_ENDP_OUT; -typedef struct _USB_TCB -{ +typedef struct _USB_TCB { struct urb *urb; PVOID psIntfAdapter; BOOLEAN bUsed; } USB_TCB, *PUSB_TCB; -typedef struct _USB_RCB -{ +typedef struct _USB_RCB { struct urb *urb; PVOID psIntfAdapter; BOOLEAN bUsed; @@ -56,8 +50,7 @@ typedef struct _USB_RCB * This is the interface specific Sub-Adapter * Structure. */ -typedef struct _S_INTERFACE_ADAPTER -{ +typedef struct _S_INTERFACE_ADAPTER { struct usb_device *udev; struct usb_interface *interface; /* Bulk endpoint in info */ -- cgit v1.2.3 From 5806627215dc2c5a33b78c0d3ae756ef2f3d5017 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:16 -0400 Subject: Staging: bcm: Change PCHAR to char * in InterfaceAdapter.h This patch changes PCHAR to char * in InterfaceAdapter.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index 6d411ba2f53..ea1e6c9049a 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -2,7 +2,7 @@ #define _INTERFACE_ADAPTER_H typedef struct _BULK_ENDP_IN { - PCHAR bulk_in_buffer; + char *bulk_in_buffer; size_t bulk_in_size; UCHAR bulk_in_endpointAddr; UINT bulk_in_pipe; @@ -19,7 +19,7 @@ typedef struct _BULK_ENDP_OUT { } BULK_ENDP_OUT, *PBULK_ENDP_OUT; typedef struct _INTR_ENDP_IN { - PCHAR int_in_buffer; + char *int_in_buffer; size_t int_in_size; UCHAR int_in_endpointAddr; UCHAR int_in_interval; @@ -27,7 +27,7 @@ typedef struct _INTR_ENDP_IN { } INTR_ENDP_IN, *PINTR_ENDP_IN; typedef struct _INTR_ENDP_OUT { - PCHAR int_out_buffer; + char *int_out_buffer; size_t int_out_size; UCHAR int_out_endpointAddr; UCHAR int_out_interval; -- cgit v1.2.3 From d231be575123c6261077bbaffb01e218255f413f Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:17 -0400 Subject: Staging: bcm: Change UCHAR to unsigned char in InterfaceAdapter.h This patch changes UCHAR to unsigned char in InterfaceAdapter.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index ea1e6c9049a..598960ea23f 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -4,33 +4,33 @@ typedef struct _BULK_ENDP_IN { char *bulk_in_buffer; size_t bulk_in_size; - UCHAR bulk_in_endpointAddr; + unsigned char bulk_in_endpointAddr; UINT bulk_in_pipe; } BULK_ENDP_IN, *PBULK_ENDP_IN; typedef struct _BULK_ENDP_OUT { - UCHAR bulk_out_buffer; + unsigned char bulk_out_buffer; size_t bulk_out_size; - UCHAR bulk_out_endpointAddr; + unsigned char bulk_out_endpointAddr; UINT bulk_out_pipe; /* this is used when int out endpoint is used as bulk out end point */ - UCHAR int_out_interval; + unsigned char int_out_interval; } BULK_ENDP_OUT, *PBULK_ENDP_OUT; typedef struct _INTR_ENDP_IN { char *int_in_buffer; size_t int_in_size; - UCHAR int_in_endpointAddr; - UCHAR int_in_interval; + unsigned char int_in_endpointAddr; + unsigned char int_in_interval; UINT int_in_pipe; } INTR_ENDP_IN, *PINTR_ENDP_IN; typedef struct _INTR_ENDP_OUT { char *int_out_buffer; size_t int_out_size; - UCHAR int_out_endpointAddr; - UCHAR int_out_interval; + unsigned char int_out_endpointAddr; + unsigned char int_out_interval; UINT int_out_pipe; } INTR_ENDP_OUT, *PINTR_ENDP_OUT; -- cgit v1.2.3 From decb16b3176ccb3182cc68521595c6a66f43bb01 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:18 -0400 Subject: Staging: bcm: Change UINT to unsigned int in InterfaceAdapter.h This patch changes UINT to unsigned int in InterfaceAdapter.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index 598960ea23f..47af307b2c0 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -5,7 +5,7 @@ typedef struct _BULK_ENDP_IN { char *bulk_in_buffer; size_t bulk_in_size; unsigned char bulk_in_endpointAddr; - UINT bulk_in_pipe; + unsigned int bulk_in_pipe; } BULK_ENDP_IN, *PBULK_ENDP_IN; @@ -13,7 +13,7 @@ typedef struct _BULK_ENDP_OUT { unsigned char bulk_out_buffer; size_t bulk_out_size; unsigned char bulk_out_endpointAddr; - UINT bulk_out_pipe; + unsigned int bulk_out_pipe; /* this is used when int out endpoint is used as bulk out end point */ unsigned char int_out_interval; } BULK_ENDP_OUT, *PBULK_ENDP_OUT; @@ -23,7 +23,7 @@ typedef struct _INTR_ENDP_IN { size_t int_in_size; unsigned char int_in_endpointAddr; unsigned char int_in_interval; - UINT int_in_pipe; + unsigned int int_in_pipe; } INTR_ENDP_IN, *PINTR_ENDP_IN; typedef struct _INTR_ENDP_OUT { @@ -31,7 +31,7 @@ typedef struct _INTR_ENDP_OUT { size_t int_out_size; unsigned char int_out_endpointAddr; unsigned char int_out_interval; - UINT int_out_pipe; + unsigned int int_out_pipe; } INTR_ENDP_OUT, *PINTR_ENDP_OUT; typedef struct _USB_TCB { -- cgit v1.2.3 From 60896e6b8116f1251d87341b64d63a22d4c53280 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:19 -0400 Subject: Staging: bcm: Change PVOID to void * in InterfaceAdapter.h This patch changes PVOID to void * in InterfaceAdapter.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index 47af307b2c0..363d609d14f 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -36,13 +36,13 @@ typedef struct _INTR_ENDP_OUT { typedef struct _USB_TCB { struct urb *urb; - PVOID psIntfAdapter; + void *psIntfAdapter; BOOLEAN bUsed; } USB_TCB, *PUSB_TCB; typedef struct _USB_RCB { struct urb *urb; - PVOID psIntfAdapter; + void *psIntfAdapter; BOOLEAN bUsed; } USB_RCB, *PUSB_RCB; -- cgit v1.2.3 From 48df0187d45a230f1173a48dc47f5d1db601e139 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:20 -0400 Subject: Staging: bcm: Change BOOLEAN to bool in InterfaceAdapter.h This patch changes BOOLEAN to bool in InterfaceAdapter.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index 363d609d14f..9e6fee0d00f 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -37,13 +37,13 @@ typedef struct _INTR_ENDP_OUT { typedef struct _USB_TCB { struct urb *urb; void *psIntfAdapter; - BOOLEAN bUsed; + bool bUsed; } USB_TCB, *PUSB_TCB; typedef struct _USB_RCB { struct urb *urb; void *psIntfAdapter; - BOOLEAN bUsed; + bool bUsed; } USB_RCB, *PUSB_RCB; /* @@ -70,10 +70,10 @@ typedef struct _S_INTERFACE_ADAPTER { atomic_t uNumRcbUsed; atomic_t uCurrRcb; struct bcm_mini_adapter *psAdapter; - BOOLEAN bFlashBoot; - BOOLEAN bHighSpeedDevice; - BOOLEAN bSuspended; - BOOLEAN bPreparingForBusSuspend; + bool bFlashBoot; + bool bHighSpeedDevice; + bool bSuspended; + bool bPreparingForBusSuspend; struct work_struct usbSuspendWork; } S_INTERFACE_ADAPTER, *PS_INTERFACE_ADAPTER; -- cgit v1.2.3 From d6861cfef2e42fecd5f0d51554493e45df6612a6 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:21 -0400 Subject: Staging: bcm: Remove typedef for _S_INTERFACE_ADAPTER and call directly. This patch removes typedef for _S_INTERFACE_ADAPTER, changes the name of the struct to bcm_interface_adapter. In addition, any calls to typedefs S_INTERFACE_ADAPTER, or *PS_INTERFACE_ADAPTER are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 2 +- drivers/staging/bcm/Bcmnet.c | 6 +++--- drivers/staging/bcm/InterfaceAdapter.h | 4 ++-- drivers/staging/bcm/InterfaceDld.c | 4 ++-- drivers/staging/bcm/InterfaceIdleMode.c | 2 +- drivers/staging/bcm/InterfaceInit.c | 22 +++++++++++----------- drivers/staging/bcm/InterfaceInit.h | 2 +- drivers/staging/bcm/InterfaceIsr.c | 6 +++--- drivers/staging/bcm/InterfaceIsr.h | 4 ++-- drivers/staging/bcm/InterfaceMisc.c | 16 ++++++++-------- drivers/staging/bcm/InterfaceMisc.h | 6 +++--- drivers/staging/bcm/InterfaceRx.c | 8 ++++---- drivers/staging/bcm/InterfaceRx.h | 2 +- drivers/staging/bcm/InterfaceTx.c | 8 ++++---- drivers/staging/bcm/Misc.c | 12 ++++++------ drivers/staging/bcm/Transmit.c | 2 +- 16 files changed, 53 insertions(+), 53 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 4a7e12b6942..31a1a2ba7ef 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -895,7 +895,7 @@ cntrlEnd: mdelay(10); /* Wait for MailBox Interrupt */ - if (StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter)) + if (StartInterruptUrb((struct bcm_interface_adapter *)Adapter->pvInterfaceAdapter)) BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n"); timeout = 5*HZ; diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 6e8c7f52321..a3b91c7ee8f 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -142,7 +142,7 @@ static void bcm_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(dev); - PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter; + struct bcm_interface_adapter *psIntfAdapter = Adapter->pvInterfaceAdapter; struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface); strcpy(info->driver, DRV_NAME); @@ -186,7 +186,7 @@ static const struct ethtool_ops bcm_ethtool_ops = { int register_networkdev(struct bcm_mini_adapter *Adapter) { struct net_device *net = Adapter->dev; - PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter; + struct bcm_interface_adapter *IntfAdapter = Adapter->pvInterfaceAdapter; struct usb_interface *udev = IntfAdapter->interface; struct usb_device *xdev = IntfAdapter->udev; @@ -227,7 +227,7 @@ int register_networkdev(struct bcm_mini_adapter *Adapter) void unregister_networkdev(struct bcm_mini_adapter *Adapter) { struct net_device *net = Adapter->dev; - PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter; + struct bcm_interface_adapter *IntfAdapter = Adapter->pvInterfaceAdapter; struct usb_interface *udev = IntfAdapter->interface; struct usb_device *xdev = IntfAdapter->udev; diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index 9e6fee0d00f..79139d96a40 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -50,7 +50,7 @@ typedef struct _USB_RCB { * This is the interface specific Sub-Adapter * Structure. */ -typedef struct _S_INTERFACE_ADAPTER { +struct bcm_interface_adapter { struct usb_device *udev; struct usb_interface *interface; /* Bulk endpoint in info */ @@ -75,6 +75,6 @@ typedef struct _S_INTERFACE_ADAPTER { bool bSuspended; bool bPreparingForBusSuspend; struct work_struct usbSuspendWork; -} S_INTERFACE_ADAPTER, *PS_INTERFACE_ADAPTER; +}; #endif diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c index 3a89e33733e..87117a797d5 100644 --- a/drivers/staging/bcm/InterfaceDld.c +++ b/drivers/staging/bcm/InterfaceDld.c @@ -6,7 +6,7 @@ int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc) mm_segment_t oldfs = {0}; int errno = 0, len = 0; /* ,is_config_file = 0 */ loff_t pos = 0; - PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; + struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg; /* struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; */ char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); @@ -61,7 +61,7 @@ int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, unsigned int on_c loff_t pos = 0; static int fw_down; INT Status = STATUS_SUCCESS; - PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; + struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg; int bytes; buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA); diff --git a/drivers/staging/bcm/InterfaceIdleMode.c b/drivers/staging/bcm/InterfaceIdleMode.c index 4f2f490921e..a1bf21579d3 100644 --- a/drivers/staging/bcm/InterfaceIdleMode.c +++ b/drivers/staging/bcm/InterfaceIdleMode.c @@ -156,7 +156,7 @@ static int InterfaceAbortIdlemode(struct bcm_mini_adapter *Adapter, unsigned int int lenwritten = 0; unsigned char aucAbortPattern[8]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; - PS_INTERFACE_ADAPTER psInterfaceAdapter = Adapter->pvInterfaceAdapter; + struct bcm_interface_adapter *psInterfaceAdapter = Adapter->pvInterfaceAdapter; //Abort Bus suspend if its already suspended if((TRUE == psInterfaceAdapter->bSuspended) && (TRUE == Adapter->bDoSuspend)) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index b05f5f73548..bf5c9826752 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -22,9 +22,9 @@ static const u32 default_msg = | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; -static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter); +static int InterfaceAdapterInit(struct bcm_interface_adapter *Adapter); -static void InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) +static void InterfaceAdapterFree(struct bcm_interface_adapter *psIntfAdapter) { int i = 0; @@ -79,7 +79,7 @@ static void ConfigureEndPointTypesThroughEEPROM(struct bcm_mini_adapter *Adapter ulReg = ntohl(EP2_CFG_REG); BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x132, 4, TRUE); - if (((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE) { + if (((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE) { ulReg = ntohl(EP2_CFG_INT); BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE); } else { @@ -145,7 +145,7 @@ static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_devi struct usb_device *udev = interface_to_usbdev(intf); int retval; struct bcm_mini_adapter *psAdapter; - PS_INTERFACE_ADAPTER psIntfAdapter; + struct bcm_interface_adapter *psIntfAdapter; struct net_device *ndev; /* Reserve one extra queue for the bit-bucket */ @@ -189,7 +189,7 @@ static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_devi } /* Allocate interface adapter structure */ - psIntfAdapter = kzalloc(sizeof(S_INTERFACE_ADAPTER), GFP_KERNEL); + psIntfAdapter = kzalloc(sizeof(struct bcm_interface_adapter), GFP_KERNEL); if (psIntfAdapter == NULL) { dev_err(&udev->dev, DRV_NAME ": no memory for Interface adapter\n"); AdapterFree(psAdapter); @@ -257,7 +257,7 @@ static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_devi static void usbbcm_disconnect(struct usb_interface *intf) { - PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); + struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf); struct bcm_mini_adapter *psAdapter; struct usb_device *udev = interface_to_usbdev(intf); @@ -276,7 +276,7 @@ static void usbbcm_disconnect(struct usb_interface *intf) usb_put_dev(udev); } -static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) +static int AllocUsbCb(struct bcm_interface_adapter *psIntfAdapter) { int i = 0; @@ -311,7 +311,7 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) return 0; } -static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter) +static int device_run(struct bcm_interface_adapter *psIntfAdapter) { int value = 0; UINT status = STATUS_SUCCESS; @@ -421,7 +421,7 @@ static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descrip return bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd); } -static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) +static int InterfaceAdapterInit(struct bcm_interface_adapter *psIntfAdapter) { struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; @@ -619,7 +619,7 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message) { - PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); + struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf); psIntfAdapter->bSuspended = TRUE; @@ -646,7 +646,7 @@ static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message) static int InterfaceResume(struct usb_interface *intf) { - PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); + struct bcm_interface_adapter *psIntfAdapter = usb_get_intfdata(intf); mdelay(100); psIntfAdapter->bSuspended = FALSE; diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h index 866924e35f9..71e80f3bd4c 100644 --- a/drivers/staging/bcm/InterfaceInit.h +++ b/drivers/staging/bcm/InterfaceInit.h @@ -21,6 +21,6 @@ int InterfaceInitialize(void); int InterfaceExit(void); -int usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter); +int usbbcm_worker_thread(struct bcm_interface_adapter *psIntfAdapter); #endif diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c index 6ee3428daa5..8322f1b76e2 100644 --- a/drivers/staging/bcm/InterfaceIsr.c +++ b/drivers/staging/bcm/InterfaceIsr.c @@ -4,7 +4,7 @@ static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/) { int status = urb->status; - PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)urb->context; + struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)urb->context; struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter ; if (netif_msg_intr(Adapter)) @@ -114,7 +114,7 @@ static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/) } -int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter) +int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter) { psIntfAdapter->psInterruptUrb = usb_alloc_urb(0, GFP_KERNEL); if (!psIntfAdapter->psInterruptUrb) @@ -143,7 +143,7 @@ int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter) } -INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter) +INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter) { INT status = 0; diff --git a/drivers/staging/bcm/InterfaceIsr.h b/drivers/staging/bcm/InterfaceIsr.h index 40399788c41..3073bd71cfe 100644 --- a/drivers/staging/bcm/InterfaceIsr.h +++ b/drivers/staging/bcm/InterfaceIsr.h @@ -1,10 +1,10 @@ #ifndef _INTERFACE_ISR_H #define _INTERFACE_ISR_H -int CreateInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter); +int CreateInterruptUrb(struct bcm_interface_adapter *psIntfAdapter); -INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter); +INT StartInterruptUrb(struct bcm_interface_adapter *psIntfAdapter); VOID InterfaceEnableInterrupt(struct bcm_mini_adapter *Adapter); diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index 9c832b32383..afca010f9db 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -1,6 +1,6 @@ #include "headers.h" -int InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, +int InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter, unsigned int addr, void *buff, int len) @@ -48,7 +48,7 @@ int InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, return bytes; } -int InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, +int InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter, unsigned int addr, void *buff, int len) @@ -104,7 +104,7 @@ int BcmRDM(void *arg, void *buff, int len) { - return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); + return InterfaceRDM((struct bcm_interface_adapter*)arg, addr, buff, len); } int BcmWRM(void *arg, @@ -112,12 +112,12 @@ int BcmWRM(void *arg, void *buff, int len) { - return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len); + return InterfaceWRM((struct bcm_interface_adapter *)arg, addr, buff, len); } int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter) { - PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter); + struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter); int status = STATUS_SUCCESS; /* @@ -154,7 +154,7 @@ int Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter) return status; } -void Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) +void Bcm_kill_all_URBs(struct bcm_interface_adapter *psIntfAdapter) { struct urb *tempUrb = NULL; unsigned int i; @@ -206,9 +206,9 @@ void Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) void putUsbSuspend(struct work_struct *work) { - PS_INTERFACE_ADAPTER psIntfAdapter = NULL; + struct bcm_interface_adapter *psIntfAdapter = NULL; struct usb_interface *intf = NULL; - psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER, usbSuspendWork); + psIntfAdapter = container_of(work, struct bcm_interface_adapter, usbSuspendWork); intf = psIntfAdapter->interface; if (psIntfAdapter->bSuspended == FALSE) diff --git a/drivers/staging/bcm/InterfaceMisc.h b/drivers/staging/bcm/InterfaceMisc.h index 1dfabdc3aad..bce6869a747 100644 --- a/drivers/staging/bcm/InterfaceMisc.h +++ b/drivers/staging/bcm/InterfaceMisc.h @@ -2,13 +2,13 @@ #define __INTERFACE_MISC_H INT -InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, +InterfaceRDM(struct bcm_interface_adapter *psIntfAdapter, UINT addr, PVOID buff, INT len); INT -InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, +InterfaceWRM(struct bcm_interface_adapter *psIntfAdapter, UINT addr, PVOID buff, INT len); @@ -35,7 +35,7 @@ int BcmWRM(PVOID arg, INT Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter *Adapter); -VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter); +VOID Bcm_kill_all_URBs(struct bcm_interface_adapter *psIntfAdapter); #define DISABLE_USB_ZERO_LEN_INT 0x0F011878 diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c index 8a9f90fbdf1..74b6a3f3fb6 100644 --- a/drivers/staging/bcm/InterfaceRx.c +++ b/drivers/staging/bcm/InterfaceRx.c @@ -13,7 +13,7 @@ static int SearchVcid(struct bcm_mini_adapter *Adapter,unsigned short usVcid) static PUSB_RCB -GetBulkInRcb(PS_INTERFACE_ADAPTER psIntfAdapter) +GetBulkInRcb(struct bcm_interface_adapter *psIntfAdapter) { PUSB_RCB pRcb = NULL; UINT index = 0; @@ -44,7 +44,7 @@ static void read_bulk_callback(struct urb *urb) int process_done = 1; //int idleflag = 0 ; PUSB_RCB pRcb = (PUSB_RCB)urb->context; - PS_INTERFACE_ADAPTER psIntfAdapter = pRcb->psIntfAdapter; + struct bcm_interface_adapter *psIntfAdapter = pRcb->psIntfAdapter; struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; struct bcm_leader *pLeader = urb->transfer_buffer; @@ -196,7 +196,7 @@ static void read_bulk_callback(struct urb *urb) atomic_dec(&psIntfAdapter->uNumRcbUsed); } -static int ReceiveRcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_RCB pRcb) +static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter, PUSB_RCB pRcb) { struct urb *urb = pRcb->urb; int retval = 0; @@ -240,7 +240,7 @@ Return: TRUE - If Rx was successful. Other - If an error occurred. */ -BOOLEAN InterfaceRx (PS_INTERFACE_ADAPTER psIntfAdapter) +BOOLEAN InterfaceRx (struct bcm_interface_adapter *psIntfAdapter) { USHORT RxDescCount = NUM_RX_DESC - atomic_read(&psIntfAdapter->uNumRcbUsed); PUSB_RCB pRcb = NULL; diff --git a/drivers/staging/bcm/InterfaceRx.h b/drivers/staging/bcm/InterfaceRx.h index 96e81a1d37b..424645e9e47 100644 --- a/drivers/staging/bcm/InterfaceRx.h +++ b/drivers/staging/bcm/InterfaceRx.h @@ -1,7 +1,7 @@ #ifndef _INTERFACE_RX_H #define _INTERFACE_RX_H -BOOLEAN InterfaceRx(PS_INTERFACE_ADAPTER Adapter); +BOOLEAN InterfaceRx(struct bcm_interface_adapter *Adapter); #endif diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c index 7e2b53be4d9..da7e2b603ae 100644 --- a/drivers/staging/bcm/InterfaceTx.c +++ b/drivers/staging/bcm/InterfaceTx.c @@ -4,7 +4,7 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) { PUSB_TCB pTcb= (PUSB_TCB)urb->context; - PS_INTERFACE_ADAPTER psIntfAdapter = pTcb->psIntfAdapter; + struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter; struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer; struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter ; BOOLEAN bpowerDownMsg = FALSE ; @@ -107,7 +107,7 @@ err_exit : } -static PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter) +static PUSB_TCB GetBulkOutTcb(struct bcm_interface_adapter *psIntfAdapter) { PUSB_TCB pTcb = NULL; UINT index = 0; @@ -128,7 +128,7 @@ static PUSB_TCB GetBulkOutTcb(PS_INTERFACE_ADAPTER psIntfAdapter) return pTcb; } -static int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len) +static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len) { struct urb *urb = pTcb->urb; @@ -184,7 +184,7 @@ int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len) { PUSB_TCB pTcb= NULL; - PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; + struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg; pTcb= GetBulkOutTcb(psIntfAdapter); if(pTcb == NULL) { diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 453a2fa28b1..9e9a93627dd 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -611,7 +611,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter) up(&Adapter->rdmwrmsync); /* Killing all URBS. */ if (Adapter->bDoSuspend == TRUE) - Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); + Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); } else { Adapter->bPreparingForLowPowerMode = FALSE; } @@ -627,7 +627,7 @@ void SendIdleModeResponse(struct bcm_mini_adapter *Adapter) if ((status != STATUS_SUCCESS)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "fail to send the Idle mode Request\n"); Adapter->bPreparingForLowPowerMode = FALSE; - StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); + StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); } do_gettimeofday(&tv); BCM_DEBUG_PRINT(Adapter, DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec * 1000 + tv.tv_usec / 1000); @@ -778,11 +778,11 @@ int reset_card_proc(struct bcm_mini_adapter *ps_adapter) { int retval = STATUS_SUCCESS; struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev); - PS_INTERFACE_ADAPTER psIntfAdapter = NULL; + struct bcm_interface_adapter *psIntfAdapter = NULL; unsigned int value = 0, uiResetValue = 0; int bytes; - psIntfAdapter = ((PS_INTERFACE_ADAPTER)(ps_adapter->pvInterfaceAdapter)); + psIntfAdapter = ((struct bcm_interface_adapter *)(ps_adapter->pvInterfaceAdapter)); ps_adapter->bDDRInitDone = FALSE; if (ps_adapter->chip_id >= T3LPB) { @@ -1372,7 +1372,7 @@ static void SendShutModeResponse(struct bcm_mini_adapter *Adapter) up(&Adapter->rdmwrmsync); /* Killing all URBS. */ if (Adapter->bDoSuspend == TRUE) - Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); + Bcm_kill_all_URBs((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); } else { Adapter->bPreparingForLowPowerMode = FALSE; } @@ -1388,7 +1388,7 @@ static void SendShutModeResponse(struct bcm_mini_adapter *Adapter) if ((Status != STATUS_SUCCESS)) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL, "fail to send the Idle mode Request\n"); Adapter->bPreparingForLowPowerMode = FALSE; - StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); + StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); } } diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 27e8c890777..f8dc3e20b47 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -205,7 +205,7 @@ int tx_pkt_handler(struct bcm_mini_adapter *Adapter /**< pointer to adapter obje if (Adapter->bEndPointHalted == TRUE) { Bcm_clear_halt_of_endpoints(Adapter); Adapter->bEndPointHalted = FALSE; - StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); + StartInterruptUrb((struct bcm_interface_adapter *)(Adapter->pvInterfaceAdapter)); } if (Adapter->LinkUpStatus && !Adapter->IdleMode) { -- cgit v1.2.3 From 71dd092f360906bb5ddea88bf842a98e26c22683 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:22 -0400 Subject: Staging: bcm: Remove typedef for _USB_RCB and call directly. This patch removes typedef for _USB_RCB, changes the name of the struct to bcm_usb_rcb. In addition, any calls to typedefs USB_RCB, or *PUSB_RCB are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 6 +++--- drivers/staging/bcm/InterfaceRx.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index 79139d96a40..1955c924be4 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -40,11 +40,11 @@ typedef struct _USB_TCB { bool bUsed; } USB_TCB, *PUSB_TCB; -typedef struct _USB_RCB { +struct bcm_usb_rcb { struct urb *urb; void *psIntfAdapter; bool bUsed; -} USB_RCB, *PUSB_RCB; +}; /* * This is the interface specific Sub-Adapter @@ -64,7 +64,7 @@ struct bcm_interface_adapter { ULONG ulInterruptData[2]; struct urb *psInterruptUrb; USB_TCB asUsbTcb[MAXIMUM_USB_TCB]; - USB_RCB asUsbRcb[MAXIMUM_USB_RCB]; + struct bcm_usb_rcb asUsbRcb[MAXIMUM_USB_RCB]; atomic_t uNumTcbUsed; atomic_t uCurrTcb; atomic_t uNumRcbUsed; diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c index 74b6a3f3fb6..26f5bc76111 100644 --- a/drivers/staging/bcm/InterfaceRx.c +++ b/drivers/staging/bcm/InterfaceRx.c @@ -12,10 +12,10 @@ static int SearchVcid(struct bcm_mini_adapter *Adapter,unsigned short usVcid) } -static PUSB_RCB +static struct bcm_usb_rcb * GetBulkInRcb(struct bcm_interface_adapter *psIntfAdapter) { - PUSB_RCB pRcb = NULL; + struct bcm_usb_rcb *pRcb = NULL; UINT index = 0; if((atomic_read(&psIntfAdapter->uNumRcbUsed) < MAXIMUM_USB_RCB) && @@ -43,7 +43,7 @@ static void read_bulk_callback(struct urb *urb) UINT uiIndex=0; int process_done = 1; //int idleflag = 0 ; - PUSB_RCB pRcb = (PUSB_RCB)urb->context; + struct bcm_usb_rcb *pRcb = (struct bcm_usb_rcb *)urb->context; struct bcm_interface_adapter *psIntfAdapter = pRcb->psIntfAdapter; struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; struct bcm_leader *pLeader = urb->transfer_buffer; @@ -196,7 +196,7 @@ static void read_bulk_callback(struct urb *urb) atomic_dec(&psIntfAdapter->uNumRcbUsed); } -static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter, PUSB_RCB pRcb) +static int ReceiveRcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_usb_rcb *pRcb) { struct urb *urb = pRcb->urb; int retval = 0; @@ -243,7 +243,7 @@ Return: TRUE - If Rx was successful. BOOLEAN InterfaceRx (struct bcm_interface_adapter *psIntfAdapter) { USHORT RxDescCount = NUM_RX_DESC - atomic_read(&psIntfAdapter->uNumRcbUsed); - PUSB_RCB pRcb = NULL; + struct bcm_usb_rcb *pRcb = NULL; // RxDescCount = psIntfAdapter->psAdapter->CurrNumRecvDescs - // psIntfAdapter->psAdapter->PrevNumRecvDescs; -- cgit v1.2.3 From e8355aa36c1ad3a63860fe30a74d2befc1148b5b Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:23 -0400 Subject: Staging: bcm: Remove typedef for _USB_TCB and call directly. This patch removes typedef for _USB_TCB, changes the name of the struct to bcm_usb_tcb. In addition, any calls to typedefs USB_TCB, or *PUSB_TCB are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 6 +++--- drivers/staging/bcm/InterfaceTx.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index 1955c924be4..de7d7c2e3bf 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -34,11 +34,11 @@ typedef struct _INTR_ENDP_OUT { unsigned int int_out_pipe; } INTR_ENDP_OUT, *PINTR_ENDP_OUT; -typedef struct _USB_TCB { +struct bcm_usb_tcb { struct urb *urb; void *psIntfAdapter; bool bUsed; -} USB_TCB, *PUSB_TCB; +}; struct bcm_usb_rcb { struct urb *urb; @@ -63,7 +63,7 @@ struct bcm_interface_adapter { INTR_ENDP_OUT sIntrOut; ULONG ulInterruptData[2]; struct urb *psInterruptUrb; - USB_TCB asUsbTcb[MAXIMUM_USB_TCB]; + struct bcm_usb_tcb asUsbTcb[MAXIMUM_USB_TCB]; struct bcm_usb_rcb asUsbRcb[MAXIMUM_USB_RCB]; atomic_t uNumTcbUsed; atomic_t uCurrTcb; diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c index da7e2b603ae..b8c785556dd 100644 --- a/drivers/staging/bcm/InterfaceTx.c +++ b/drivers/staging/bcm/InterfaceTx.c @@ -3,7 +3,7 @@ /*this is transmit call-back(BULK OUT)*/ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) { - PUSB_TCB pTcb= (PUSB_TCB)urb->context; + struct bcm_usb_tcb *pTcb= (struct bcm_usb_tcb *)urb->context; struct bcm_interface_adapter *psIntfAdapter = pTcb->psIntfAdapter; struct bcm_link_request *pControlMsg = (struct bcm_link_request *)urb->transfer_buffer; struct bcm_mini_adapter *psAdapter = psIntfAdapter->psAdapter ; @@ -107,9 +107,9 @@ err_exit : } -static PUSB_TCB GetBulkOutTcb(struct bcm_interface_adapter *psIntfAdapter) +static struct bcm_usb_tcb *GetBulkOutTcb(struct bcm_interface_adapter *psIntfAdapter) { - PUSB_TCB pTcb = NULL; + struct bcm_usb_tcb *pTcb = NULL; UINT index = 0; if((atomic_read(&psIntfAdapter->uNumTcbUsed) < MAXIMUM_USB_TCB) && @@ -128,7 +128,7 @@ static PUSB_TCB GetBulkOutTcb(struct bcm_interface_adapter *psIntfAdapter) return pTcb; } -static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, PUSB_TCB pTcb, PVOID data, int len) +static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, struct bcm_usb_tcb *pTcb, PVOID data, int len) { struct urb *urb = pTcb->urb; @@ -182,7 +182,7 @@ static int TransmitTcb(struct bcm_interface_adapter *psIntfAdapter, PUSB_TCB pTc int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len) { - PUSB_TCB pTcb= NULL; + struct bcm_usb_tcb *pTcb= NULL; struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg; pTcb= GetBulkOutTcb(psIntfAdapter); -- cgit v1.2.3 From de89ec45569e96193f5e1264b87cc7aaed060dfa Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:24 -0400 Subject: Staging: bcm: Remove typedef for _INTR_ENDP_OUT and call directly. This patch removes typedef for _INTR_ENDP_OUT, changes the name of the struct to bcm_intr_endpoint_out. In addition, any calls to typedefs INTR_ENDP_OUT, or *PINTR_ENDP_OUT are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index de7d7c2e3bf..846bca0bf2d 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -26,13 +26,13 @@ typedef struct _INTR_ENDP_IN { unsigned int int_in_pipe; } INTR_ENDP_IN, *PINTR_ENDP_IN; -typedef struct _INTR_ENDP_OUT { +struct bcm_intr_endpoint_out { char *int_out_buffer; size_t int_out_size; unsigned char int_out_endpointAddr; unsigned char int_out_interval; unsigned int int_out_pipe; -} INTR_ENDP_OUT, *PINTR_ENDP_OUT; +}; struct bcm_usb_tcb { struct urb *urb; @@ -60,7 +60,7 @@ struct bcm_interface_adapter { /* Interrupt endpoint in info */ INTR_ENDP_IN sIntrIn; /* Interrupt endpoint out info */ - INTR_ENDP_OUT sIntrOut; + struct bcm_intr_endpoint_out sIntrOut; ULONG ulInterruptData[2]; struct urb *psInterruptUrb; struct bcm_usb_tcb asUsbTcb[MAXIMUM_USB_TCB]; -- cgit v1.2.3 From 89a02bfe0fe8176d3fe8ec065fffb05a860f713e Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:25 -0400 Subject: Staging: bcm: Remove typedef for _INTR_ENDP_IN and call directly. This patch removes typedef for _INTR_ENDP_IN, changes the name of the struct to bcm_intr_endpoint_in. In addition, any calls to typedefs INTR_ENDP_IN, or *PINTR_ENDP_IN are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index 846bca0bf2d..a30448049b5 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -18,13 +18,13 @@ typedef struct _BULK_ENDP_OUT { unsigned char int_out_interval; } BULK_ENDP_OUT, *PBULK_ENDP_OUT; -typedef struct _INTR_ENDP_IN { +struct bcm_intr_endpoint_in { char *int_in_buffer; size_t int_in_size; unsigned char int_in_endpointAddr; unsigned char int_in_interval; unsigned int int_in_pipe; -} INTR_ENDP_IN, *PINTR_ENDP_IN; +}; struct bcm_intr_endpoint_out { char *int_out_buffer; @@ -58,7 +58,7 @@ struct bcm_interface_adapter { /* Bulk endpoint out info */ BULK_ENDP_OUT sBulkOut; /* Interrupt endpoint in info */ - INTR_ENDP_IN sIntrIn; + struct bcm_intr_endpoint_in sIntrIn; /* Interrupt endpoint out info */ struct bcm_intr_endpoint_out sIntrOut; ULONG ulInterruptData[2]; -- cgit v1.2.3 From c1fa1eb38f15dd9998a7cc2fe4f54eb95d14208c Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:26 -0400 Subject: Staging: bcm: Remove typedef for _BULK_ENDP_OUT and call directly. This patch removes typedef for _BULK_ENDP_OUT, changes the name of the struct to bcm_bulk_endpoint_out. In addition, any calls to typedefs BULK_ENDP_OUT, or *PBULK_ENDP_OUT are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index a30448049b5..1ca1a88c1c8 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -8,15 +8,14 @@ typedef struct _BULK_ENDP_IN { unsigned int bulk_in_pipe; } BULK_ENDP_IN, *PBULK_ENDP_IN; - -typedef struct _BULK_ENDP_OUT { +struct bcm_bulk_endpoint_out { unsigned char bulk_out_buffer; size_t bulk_out_size; unsigned char bulk_out_endpointAddr; unsigned int bulk_out_pipe; /* this is used when int out endpoint is used as bulk out end point */ unsigned char int_out_interval; -} BULK_ENDP_OUT, *PBULK_ENDP_OUT; +}; struct bcm_intr_endpoint_in { char *int_in_buffer; @@ -56,7 +55,7 @@ struct bcm_interface_adapter { /* Bulk endpoint in info */ BULK_ENDP_IN sBulkIn; /* Bulk endpoint out info */ - BULK_ENDP_OUT sBulkOut; + struct bcm_bulk_endpoint_out sBulkOut; /* Interrupt endpoint in info */ struct bcm_intr_endpoint_in sIntrIn; /* Interrupt endpoint out info */ -- cgit v1.2.3 From 85b331afb29a25fe770750c7dc169688a1c7f9ec Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:27 -0400 Subject: Staging: bcm: Remove typedef for _BULK_ENDP_IN and call directly. This patch removes typedef for _BULK_ENDP_IN, changes the name of the struct to bcm_bulk_endpoint_in. In addition, any calls to typedefs BULK_ENDP_IN, or *PBULK_ENDP_IN are changed to call the struct directly. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index 1ca1a88c1c8..f6e26007db7 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -1,12 +1,12 @@ #ifndef _INTERFACE_ADAPTER_H #define _INTERFACE_ADAPTER_H -typedef struct _BULK_ENDP_IN { +struct bcm_bulk_endpoint_in { char *bulk_in_buffer; size_t bulk_in_size; unsigned char bulk_in_endpointAddr; unsigned int bulk_in_pipe; -} BULK_ENDP_IN, *PBULK_ENDP_IN; +}; struct bcm_bulk_endpoint_out { unsigned char bulk_out_buffer; @@ -53,7 +53,7 @@ struct bcm_interface_adapter { struct usb_device *udev; struct usb_interface *interface; /* Bulk endpoint in info */ - BULK_ENDP_IN sBulkIn; + struct bcm_bulk_endpoint_in sBulkIn; /* Bulk endpoint out info */ struct bcm_bulk_endpoint_out sBulkOut; /* Interrupt endpoint in info */ -- cgit v1.2.3 From 38d6d8de76bdde708ee5bc7d2087f9968a0c5ddd Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Thu, 1 Nov 2012 23:42:28 -0400 Subject: Staging: bcm: Change ULONG to unsigned long in InterfaceAdapter.h This patch changes ULONG to unsigned long in InterfaceAdapter.h. Signed-off-by: Kevin McKinney Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceAdapter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/bcm/InterfaceAdapter.h b/drivers/staging/bcm/InterfaceAdapter.h index f6e26007db7..06a6b18bca4 100644 --- a/drivers/staging/bcm/InterfaceAdapter.h +++ b/drivers/staging/bcm/InterfaceAdapter.h @@ -60,7 +60,7 @@ struct bcm_interface_adapter { struct bcm_intr_endpoint_in sIntrIn; /* Interrupt endpoint out info */ struct bcm_intr_endpoint_out sIntrOut; - ULONG ulInterruptData[2]; + unsigned long ulInterruptData[2]; struct urb *psInterruptUrb; struct bcm_usb_tcb asUsbTcb[MAXIMUM_USB_TCB]; struct bcm_usb_rcb asUsbRcb[MAXIMUM_USB_RCB]; -- cgit v1.2.3 From f41d2573b22c5eafff868824004095fff92b0e8c Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 13:52:29 +0000 Subject: staging: comedi: adl_pci9118: replace printks Replace or remove the `printk()` calls in this driver. Call new function `pci9118_report_attach()` to report successful attachment of the board. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 110 +++++++++++++-------------- 1 file changed, 52 insertions(+), 58 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index a5d0be21eff..01c9ba3ccac 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -356,10 +356,8 @@ static int check_channel_list(struct comedi_device *dev, return 0; } if ((frontadd + n_chan + backadd) > s->len_chanlist) { - printk - ("comedi%d: range/channel list is too long for " - "actual configuration (%d>%d)!", - dev->minor, n_chan, s->len_chanlist - frontadd - backadd); + comedi_error(dev, + "range/channel list is too long for actual configuration!\n"); return 0; } @@ -890,11 +888,10 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, if (devpriv->ai16bits == 0) { if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) { /* data dropout! */ - printk - ("comedi: A/D SAMPL - data dropout: " - "received channel %d, expected %d!\n", - sampl & 0x000f, - devpriv->chanlist[s->async->cur_chan]); + dev_info(dev->class_dev, + "A/D SAMPL - data dropout: received channel %d, expected %d!\n", + sampl & 0x000f, + devpriv->chanlist[s->async->cur_chan]); s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; pci9118_ai_cancel(dev, s); comedi_event(dev, s); @@ -1316,21 +1313,18 @@ static int Compute_and_setup_dma(struct comedi_device *dev) if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) { /* uff, too short DMA buffer, disable EOS support! */ devpriv->ai_flags &= (~TRIG_WAKE_EOS); - printk - ("comedi%d: WAR: DMA0 buf too short, can't " - "support TRIG_WAKE_EOS (%d<%d)\n", - dev->minor, dmalen0, - devpriv->ai_n_realscanlen << 1); + dev_info(dev->class_dev, + "WAR: DMA0 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n", + dmalen0, devpriv->ai_n_realscanlen << 1); } else { /* short first DMA buffer to one scan */ dmalen0 = devpriv->ai_n_realscanlen << 1; if (devpriv->useeoshandle) dmalen0 += 2; if (dmalen0 < 4) { - printk - ("comedi%d: ERR: DMA0 buf len bug? " - "(%d<4)\n", - dev->minor, dmalen0); + dev_info(dev->class_dev, + "ERR: DMA0 buf len bug? (%d<4)\n", + dmalen0); dmalen0 = 4; } } @@ -1339,21 +1333,18 @@ static int Compute_and_setup_dma(struct comedi_device *dev) if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) { /* uff, too short DMA buffer, disable EOS support! */ devpriv->ai_flags &= (~TRIG_WAKE_EOS); - printk - ("comedi%d: WAR: DMA1 buf too short, " - "can't support TRIG_WAKE_EOS (%d<%d)\n", - dev->minor, dmalen1, - devpriv->ai_n_realscanlen << 1); + dev_info(dev->class_dev, + "WAR: DMA1 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n", + dmalen1, devpriv->ai_n_realscanlen << 1); } else { /* short second DMA buffer to one scan */ dmalen1 = devpriv->ai_n_realscanlen << 1; if (devpriv->useeoshandle) dmalen1 -= 2; if (dmalen1 < 4) { - printk - ("comedi%d: ERR: DMA1 buf len bug? " - "(%d<4)\n", - dev->minor, dmalen1); + dev_info(dev->class_dev, + "ERR: DMA1 buf len bug? (%d<4)\n", + dmalen1); dmalen1 = 4; } } @@ -1888,20 +1879,36 @@ static struct pci_dev *pci9118_find_pci(struct comedi_device *dev, */ if (comedi_pci_enable(pcidev, "adl_pci9118")) continue; - printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", - pcidev->bus->number, - PCI_SLOT(pcidev->devfn), - PCI_FUNC(pcidev->devfn), - (unsigned long)pci_resource_start(pcidev, 2), - (unsigned long)pci_resource_start(pcidev, 0)); return pcidev; } - printk(KERN_ERR - "comedi%d: no supported board found! (req. bus/slot : %d/%d)\n", - dev->minor, bus, slot); + dev_err(dev->class_dev, + "no supported board found! (req. bus/slot : %d/%d)\n", + bus, slot); return NULL; } +static void pci9118_report_attach(struct comedi_device *dev, unsigned int irq) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pci9118_private *devpriv = dev->private; + char irqbuf[30]; + char muxbuf[30]; + + if (irq) + snprintf(irqbuf, sizeof(irqbuf), "irq %u%s", irq, + (dev->irq ? "" : " UNAVAILABLE")); + else + snprintf(irqbuf, sizeof(irqbuf), "irq DISABLED"); + if (devpriv->usemux) + snprintf(muxbuf, sizeof(muxbuf), "ext mux %u chans", + devpriv->usemux); + else + snprintf(muxbuf, sizeof(muxbuf), "no ext mux"); + dev_info(dev->class_dev, "%s (pci %s, %s, %sbus master, %s) attached\n", + dev->board_name, pci_name(pcidev), irqbuf, + (devpriv->master ? "" : "no "), muxbuf); +} + static int pci9118_attach(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -1914,8 +1921,6 @@ static int pci9118_attach(struct comedi_device *dev, unsigned int irq; u16 u16w; - printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name); - if (it->options[3] & 1) master = 0; /* user don't want use bus master */ else @@ -1946,19 +1951,14 @@ static int pci9118_attach(struct comedi_device *dev, irq = 0; /* user don't want use IRQ */ if (irq > 0) { if (request_irq(irq, interrupt_pci9118, IRQF_SHARED, - "ADLink PCI-9118", dev)) { - printk(", unable to allocate IRQ %d, DISABLING IT", - irq); - irq = 0; /* Can't use IRQ */ - } else { - printk(", irq=%u", irq); - } - } else { - printk(", IRQ disabled"); + "ADLink PCI-9118", dev)) + dev_warn(dev->class_dev, + "unable to allocate IRQ %u, DISABLING IT\n", + irq); + else + dev->irq = irq; } - dev->irq = irq; - if (master) { /* alloc DMA buffers */ devpriv->dma_doublebuf = 0; for (i = 0; i < 2; i++) { @@ -1980,7 +1980,8 @@ static int pci9118_attach(struct comedi_device *dev, } } if (!devpriv->dmabuf_virt[0]) { - printk(", Can't allocate DMA buffer, DMA disabled!"); + dev_warn(dev->class_dev, + "Can't allocate DMA buffer, DMA disabled!\n"); master = 0; } @@ -1990,11 +1991,6 @@ static int pci9118_attach(struct comedi_device *dev, } devpriv->master = master; - if (devpriv->master) - printk(", bus master"); - else - printk(", no bus master"); - devpriv->usemux = 0; if (it->options[2] > 0) { devpriv->usemux = it->options[2]; @@ -2005,7 +2001,6 @@ static int pci9118_attach(struct comedi_device *dev, devpriv->usemux = 128; /* max 128 channels with softare S&H! */ } - printk(", ext. mux %d channels", devpriv->usemux); } devpriv->softsshdelay = it->options[4]; @@ -2019,8 +2014,6 @@ static int pci9118_attach(struct comedi_device *dev, devpriv->softsshhold = 0x80; } - printk(".\n"); - pci_read_config_word(pcidev, PCI_COMMAND, &u16w); pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64); /* Enable parity check for parity error */ @@ -2095,6 +2088,7 @@ static int pci9118_attach(struct comedi_device *dev, devpriv->ai16bits = 0; break; } + pci9118_report_attach(dev, irq); return 0; } -- cgit v1.2.3 From f3b81d54585b2b050257228555f15c0e507024d1 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 13:52:30 +0000 Subject: staging: comedi: adl_pci9118: split pci9118_attach() Split most of the functionality of the attach routine `pci9118_attach()` into a new function `pci9118_common_attach()` that can be called when auto-attachment of devices is supported. Move the enabling of the PCI device and its i/o regions into this function. Do the requesting of the interrupt near the end of the function so it doesn't get enabled before the device is ready. Note that auto-attachment of PCI devices is currently broken in this driver because the list of board names referred to by the `struct comedi_driver` does not contain a "wildcard" entry matching the comedi driver name. This won't be a problem once support for the `auto_attach()` method is added. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 143 ++++++++++++++------------- 1 file changed, 77 insertions(+), 66 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 01c9ba3ccac..cc46d641aaf 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -1873,12 +1873,6 @@ static struct pci_dev *pci9118_find_pci(struct comedi_device *dev, PCI_SLOT(pcidev->devfn) != slot) continue; } - /* - * Look for device that isn't in use. - * Enable PCI device and request regions. - */ - if (comedi_pci_enable(pcidev, "adl_pci9118")) - continue; return pcidev; } dev_err(dev->class_dev, @@ -1909,56 +1903,33 @@ static void pci9118_report_attach(struct comedi_device *dev, unsigned int irq) (devpriv->master ? "" : "no "), muxbuf); } -static int pci9118_attach(struct comedi_device *dev, - struct comedi_devconfig *it) +static int pci9118_common_attach(struct comedi_device *dev, int disable_irq, + int master, int ext_mux, int softsshdelay, + int hw_err_mask) { const struct boardtype *this_board = comedi_board(dev); - struct pci9118_private *devpriv; - struct pci_dev *pcidev; + struct pci9118_private *devpriv = dev->private; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct comedi_subdevice *s; int ret, pages, i; - unsigned short master; unsigned int irq; u16 u16w; - if (it->options[3] & 1) - master = 0; /* user don't want use bus master */ - else - master = 1; - - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); - if (!devpriv) - return -ENOMEM; - dev->private = devpriv; - - pcidev = pci9118_find_pci(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - + dev->board_name = this_board->name; + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) { + dev_err(dev->class_dev, + "cannot enable PCI device %s\n", pci_name(pcidev)); + return ret; + } if (master) pci_set_master(pcidev); - irq = pcidev->irq; devpriv->iobase_a = pci_resource_start(pcidev, 0); dev->iobase = pci_resource_start(pcidev, 2); - dev->board_name = this_board->name; - pci9118_reset(dev); - if (it->options[3] & 2) - irq = 0; /* user don't want use IRQ */ - if (irq > 0) { - if (request_irq(irq, interrupt_pci9118, IRQF_SHARED, - "ADLink PCI-9118", dev)) - dev_warn(dev->class_dev, - "unable to allocate IRQ %u, DISABLING IT\n", - irq); - else - dev->irq = irq; - } - if (master) { /* alloc DMA buffers */ devpriv->dma_doublebuf = 0; for (i = 0; i < 2; i++) { @@ -1984,32 +1955,29 @@ static int pci9118_attach(struct comedi_device *dev, "Can't allocate DMA buffer, DMA disabled!\n"); master = 0; } - if (devpriv->dmabuf_virt[1]) devpriv->dma_doublebuf = 1; - } - devpriv->master = master; - devpriv->usemux = 0; - if (it->options[2] > 0) { - devpriv->usemux = it->options[2]; - if (devpriv->usemux > 256) - devpriv->usemux = 256; /* max 256 channels! */ - if (it->options[4] > 0) - if (devpriv->usemux > 128) { - devpriv->usemux = 128; - /* max 128 channels with softare S&H! */ - } + + if (ext_mux > 0) { + if (ext_mux > 256) + ext_mux = 256; /* max 256 channels! */ + if (softsshdelay > 0) + if (ext_mux > 128) + ext_mux = 128; + devpriv->usemux = ext_mux; + } else { + devpriv->usemux = 0; } - devpriv->softsshdelay = it->options[4]; - if (devpriv->softsshdelay < 0) { - /* select sample&hold signal polarity */ - devpriv->softsshdelay = -devpriv->softsshdelay; + if (softsshdelay < 0) { + /* select sample&hold signal polarity */ + devpriv->softsshdelay = -softsshdelay; devpriv->softsshsample = 0x80; devpriv->softsshhold = 0x00; } else { + devpriv->softsshdelay = softsshdelay; devpriv->softsshsample = 0x00; devpriv->softsshhold = 0x80; } @@ -2036,12 +2004,7 @@ static int pci9118_attach(struct comedi_device *dev, s->range_table = this_board->rangelist_ai; s->cancel = pci9118_ai_cancel; s->insn_read = pci9118_insn_read_ai; - if (dev->irq) { - s->subdev_flags |= SDF_CMD_READ; - s->do_cmdtest = pci9118_ai_cmdtest; - s->do_cmd = pci9118_ai_cmd; - s->munge = pci9118_ai_munge; - } + s->munge = pci9118_ai_munge; s = &dev->subdevices[1]; s->type = COMEDI_SUBD_AO; @@ -2077,8 +2040,8 @@ static int pci9118_attach(struct comedi_device *dev, devpriv->i8254_osc_base = 250; /* 250ns=4MHz */ devpriv->ai_maskharderr = 0x10a; /* default measure crash condition */ - if (it->options[5]) /* disable some requested */ - devpriv->ai_maskharderr &= ~it->options[5]; + if (hw_err_mask) /* disable some requested */ + devpriv->ai_maskharderr &= ~hw_err_mask; switch (this_board->ai_maxdata) { case 0xffff: @@ -2088,10 +2051,58 @@ static int pci9118_attach(struct comedi_device *dev, devpriv->ai16bits = 0; break; } + + if (disable_irq) + irq = 0; + else + irq = pcidev->irq; + if (irq > 0) { + if (request_irq(irq, interrupt_pci9118, IRQF_SHARED, + dev->board_name, dev)) { + dev_warn(dev->class_dev, + "unable to allocate IRQ %u, DISABLING IT\n", + irq); + } else { + dev->irq = irq; + /* Enable AI commands */ + s = &dev->subdevices[0]; + s->subdev_flags |= SDF_CMD_READ; + s->do_cmdtest = pci9118_ai_cmdtest; + s->do_cmd = pci9118_ai_cmd; + } + } + pci9118_report_attach(dev, irq); return 0; } +static int pci9118_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + struct pci9118_private *devpriv; + struct pci_dev *pcidev; + int ext_mux, disable_irq, master, softsshdelay, hw_err_mask; + + ext_mux = it->options[2]; + master = ((it->options[3] & 1) == 0); + disable_irq = ((it->options[3] & 2) != 0); + softsshdelay = it->options[4]; + hw_err_mask = it->options[5]; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + pcidev = pci9118_find_pci(dev, it); + if (!pcidev) + return -EIO; + comedi_set_hw_dev(dev, &pcidev->dev); + + return pci9118_common_attach(dev, disable_irq, master, ext_mux, + softsshdelay, hw_err_mask); +} + static void pci9118_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); -- cgit v1.2.3 From 00d9319475a80d372de726c7cabbfb45d7531a24 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 13:52:31 +0000 Subject: staging: comedi: adl_pci9118: cards have same vendor ID Don't bother recording the PCI vendor ID of each board in `boardtypes[]` as they are all the same and the code doesn't use it anyway. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index cc46d641aaf..0bd720b0ba6 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -208,8 +208,7 @@ static const struct comedi_lrange range_pci9118hg = { 8, { struct boardtype { const char *name; /* board name */ - int vendor_id; /* PCI vendor a device ID of card */ - int device_id; + int device_id; /* PCI device ID of card */ int iorange_amcc; /* iorange for own S5933 region */ int iorange_9118; /* pass thru card region size */ int n_aichan; /* num of A/D chans */ @@ -2131,7 +2130,6 @@ static void pci9118_detach(struct comedi_device *dev) static const struct boardtype boardtypes[] = { { .name = "pci9118dg", - .vendor_id = PCI_VENDOR_ID_AMCC, .device_id = 0x80d9, .iorange_amcc = AMCC_OP_REG_SIZE, .iorange_9118 = IORANGE_9118, @@ -2149,7 +2147,6 @@ static const struct boardtype boardtypes[] = { .half_fifo_size = 512, }, { .name = "pci9118hg", - .vendor_id = PCI_VENDOR_ID_AMCC, .device_id = 0x80d9, .iorange_amcc = AMCC_OP_REG_SIZE, .iorange_9118 = IORANGE_9118, @@ -2167,7 +2164,6 @@ static const struct boardtype boardtypes[] = { .half_fifo_size = 512, }, { .name = "pci9118hr", - .vendor_id = PCI_VENDOR_ID_AMCC, .device_id = 0x80d9, .iorange_amcc = AMCC_OP_REG_SIZE, .iorange_9118 = IORANGE_9118, -- cgit v1.2.3 From 15358a7f777529500cb1fcb089c09fb792fecf30 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 13:52:32 +0000 Subject: staging: comedi: adl_pci9118: support auto-attachment Support auto-attachment of supported PCI devices by adding the `auto_attach()` hook (`pci9118_auto_attach()`) to the `struct comedi_driver`. This is called via `comedi_pci_auto_attach()` at PCI probe time. Previously, the driver's call to `comedi_pci_auto_config()` would fall back to the old method of auto-attaching devices and would fail because it couldn't find a board name matching the driver name. The new method doesn't care about that. There are still a few problems. All the boards supported by this driver have the same PCI vendor and device ID, so it will just pick the first supported board type, "pci9118dg". (Other supported board types have different AI ranges or different AI speeds, but are otherwise the same.) Also, manual attachment of devices allows several optional features to be configured, such as use of an external multiplexord, specified sample&hold delays and options to ignore certain hardware errors. These will all be set to defaults for auto-attached devices. A future version of the driver may address these issues via configurable device attributes. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 167 ++++++++++++++++++--------- 1 file changed, 112 insertions(+), 55 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 0bd720b0ba6..2b1d21bd324 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -62,6 +62,20 @@ Configuration options: 256|=ignore nFull - A/D FIFO Full status */ + +/* + * FIXME + * + * All the supported boards have the same PCI vendor and device IDs, so + * auto-attachment of PCI devices will always find the first board type. + * + * Perhaps the boards have different subdevice IDs that we could use to + * distinguish them? + * + * Need some device attributes so the board type can be corrected after + * attachment if necessary, and possibly to set other options supported by + * manual attachment. + */ #include "../comedidev.h" #include @@ -232,6 +246,61 @@ struct boardtype { }; +static const struct boardtype boardtypes[] = { + { + .name = "pci9118dg", + .device_id = 0x80d9, + .iorange_amcc = AMCC_OP_REG_SIZE, + .iorange_9118 = IORANGE_9118, + .n_aichan = 16, + .n_aichand = 8, + .mux_aichan = 256, + .n_aichanlist = PCI9118_CHANLEN, + .n_aochan = 2, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci9118dg_hr, + .rangelist_ao = &range_bipolar10, + .ai_ns_min = 3000, + .ai_pacer_min = 12, + .half_fifo_size = 512, + }, { + .name = "pci9118hg", + .device_id = 0x80d9, + .iorange_amcc = AMCC_OP_REG_SIZE, + .iorange_9118 = IORANGE_9118, + .n_aichan = 16, + .n_aichand = 8, + .mux_aichan = 256, + .n_aichanlist = PCI9118_CHANLEN, + .n_aochan = 2, + .ai_maxdata = 0x0fff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci9118hg, + .rangelist_ao = &range_bipolar10, + .ai_ns_min = 3000, + .ai_pacer_min = 12, + .half_fifo_size = 512, + }, { + .name = "pci9118hr", + .device_id = 0x80d9, + .iorange_amcc = AMCC_OP_REG_SIZE, + .iorange_9118 = IORANGE_9118, + .n_aichan = 16, + .n_aichand = 8, + .mux_aichan = 256, + .n_aichanlist = PCI9118_CHANLEN, + .n_aochan = 2, + .ai_maxdata = 0xffff, + .ao_maxdata = 0x0fff, + .rangelist_ai = &range_pci9118dg_hr, + .rangelist_ao = &range_bipolar10, + .ai_ns_min = 10000, + .ai_pacer_min = 40, + .half_fifo_size = 512, + }, +}; + struct pci9118_private { unsigned long iobase_a; /* base+size for AMCC chip */ unsigned int master; /* master capable */ @@ -1853,6 +1922,20 @@ static int pci9118_reset(struct comedi_device *dev) return 0; } +/* + * FIXME - this is pretty ineffective because all the supported board types + * have the same device ID! + */ +static const struct boardtype *pci9118_find_boardinfo(struct pci_dev *pcidev) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(boardtypes); i++) + if (pcidev->device == boardtypes[i].device_id) + return &boardtypes[i]; + return NULL; +} + static struct pci_dev *pci9118_find_pci(struct comedi_device *dev, struct comedi_devconfig *it) { @@ -2102,6 +2185,34 @@ static int pci9118_attach(struct comedi_device *dev, softsshdelay, hw_err_mask); } +static int __devinit pci9118_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pci9118_private *devpriv; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + dev->board_ptr = pci9118_find_boardinfo(pcidev); + if (dev->board_ptr == NULL) { + dev_err(dev->class_dev, + "adl_pci9118: cannot determine board type for pci %s\n", + pci_name(pcidev)); + return -EINVAL; + } + /* + * Need to 'get' the PCI device to match the 'put' in pci9118_detach(). + * (The 'put' also matches the implicit 'get' by pci9118_find_pci().) + */ + pci_dev_get(pcidev); + /* Don't disable irq, use bus master, no external mux, + * no sample-hold delay, no error mask. */ + return pci9118_common_attach(dev, 0, 1, 0, 0, 0); +} + static void pci9118_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -2127,65 +2238,11 @@ static void pci9118_detach(struct comedi_device *dev) } } -static const struct boardtype boardtypes[] = { - { - .name = "pci9118dg", - .device_id = 0x80d9, - .iorange_amcc = AMCC_OP_REG_SIZE, - .iorange_9118 = IORANGE_9118, - .n_aichan = 16, - .n_aichand = 8, - .mux_aichan = 256, - .n_aichanlist = PCI9118_CHANLEN, - .n_aochan = 2, - .ai_maxdata = 0x0fff, - .ao_maxdata = 0x0fff, - .rangelist_ai = &range_pci9118dg_hr, - .rangelist_ao = &range_bipolar10, - .ai_ns_min = 3000, - .ai_pacer_min = 12, - .half_fifo_size = 512, - }, { - .name = "pci9118hg", - .device_id = 0x80d9, - .iorange_amcc = AMCC_OP_REG_SIZE, - .iorange_9118 = IORANGE_9118, - .n_aichan = 16, - .n_aichand = 8, - .mux_aichan = 256, - .n_aichanlist = PCI9118_CHANLEN, - .n_aochan = 2, - .ai_maxdata = 0x0fff, - .ao_maxdata = 0x0fff, - .rangelist_ai = &range_pci9118hg, - .rangelist_ao = &range_bipolar10, - .ai_ns_min = 3000, - .ai_pacer_min = 12, - .half_fifo_size = 512, - }, { - .name = "pci9118hr", - .device_id = 0x80d9, - .iorange_amcc = AMCC_OP_REG_SIZE, - .iorange_9118 = IORANGE_9118, - .n_aichan = 16, - .n_aichand = 8, - .mux_aichan = 256, - .n_aichanlist = PCI9118_CHANLEN, - .n_aochan = 2, - .ai_maxdata = 0xffff, - .ao_maxdata = 0x0fff, - .rangelist_ai = &range_pci9118dg_hr, - .rangelist_ao = &range_bipolar10, - .ai_ns_min = 10000, - .ai_pacer_min = 40, - .half_fifo_size = 512, - }, -}; - static struct comedi_driver adl_pci9118_driver = { .driver_name = "adl_pci9118", .module = THIS_MODULE, .attach = pci9118_attach, + .auto_attach = pci9118_auto_attach, .detach = pci9118_detach, .num_names = ARRAY_SIZE(boardtypes), .board_name = &boardtypes[0].name, -- cgit v1.2.3 From 6acf5a8c931da9d26c8dd77d784daaf07fa2bff0 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 2 Nov 2012 14:02:40 +0000 Subject: x86: hpet: Fix masking of MSI interrupts HPET_TN_FSB is not a proper mask bit; it merely toggles between MSI and legacy interrupt delivery. The proper mask bit is HPET_TN_ENABLE, so use both bits when (un)masking the interrupt. Signed-off-by: Jan Beulich Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/5093E09002000078000A60E6@nat28.tlf.novell.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/hpet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 1460a5df92f..e28670f9a58 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -434,7 +434,7 @@ void hpet_msi_unmask(struct irq_data *data) /* unmask it */ cfg = hpet_readl(HPET_Tn_CFG(hdev->num)); - cfg |= HPET_TN_FSB; + cfg |= HPET_TN_ENABLE | HPET_TN_FSB; hpet_writel(cfg, HPET_Tn_CFG(hdev->num)); } @@ -445,7 +445,7 @@ void hpet_msi_mask(struct irq_data *data) /* mask it */ cfg = hpet_readl(HPET_Tn_CFG(hdev->num)); - cfg &= ~HPET_TN_FSB; + cfg &= ~(HPET_TN_ENABLE | HPET_TN_FSB); hpet_writel(cfg, HPET_Tn_CFG(hdev->num)); } -- cgit v1.2.3 From 5074b85bdd3a464efe7b6de2ec163f4c07696a20 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 2 Nov 2012 14:00:29 +0000 Subject: x86: hpet: Fix inverted return value check in arch_setup_hpet_msi() setup_hpet_msi_remapped() returns a negative error indicator on error - check for this rather than for a boolean false indication, and pass on that error code rather than a meaningless "-1". Signed-off-by: Jan Beulich Cc: David Woodhouse Link: http://lkml.kernel.org/r/5093E00D02000078000A60E2@nat28.tlf.novell.com Signed-off-by: Thomas Gleixner --- arch/x86/kernel/apic/io_apic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 1817fa91102..b134f0b7ed2 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -3317,8 +3317,9 @@ int arch_setup_hpet_msi(unsigned int irq, unsigned int id) int ret; if (irq_remapping_enabled) { - if (!setup_hpet_msi_remapped(irq, id)) - return -1; + ret = setup_hpet_msi_remapped(irq, id); + if (ret) + return ret; } ret = msi_compose_msg(NULL, irq, &msg, id); -- cgit v1.2.3 From f57d56dd29003435d1bfc0e675896c368180f8ec Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 28 Oct 2012 18:17:11 +0100 Subject: uprobes/powerpc: Don't clear TIF_UPROBE in do_notify_resume() Cleanup. No need to clear TIF_UPROBE, uprobe_notify_resume() does this. Signed-off-by: Oleg Nesterov Acked-by: Ananth N Mavinakayanahalli Acked-by: Srikar Dronamraju --- arch/powerpc/kernel/signal.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index a2dc75793bd..3b997118df5 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -158,10 +158,8 @@ static int do_signal(struct pt_regs *regs) void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) { - if (thread_info_flags & _TIF_UPROBE) { - clear_thread_flag(TIF_UPROBE); + if (thread_info_flags & _TIF_UPROBE) uprobe_notify_resume(regs); - } if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); -- cgit v1.2.3 From 65b2c8f0e53347583168423de0f32227d8baf01b Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 28 Oct 2012 16:55:36 +0100 Subject: uprobes/powerpc: Do not use arch_uprobe_*_step() helpers No functional changes. powerpc is the only user of arch_uprobe_enable/disable_step() helpers, but they should die. They can not be used correctly, every arch needs its own implementation (like x86 does). And they do not really help even as initial-and-almost-working code, arch_uprobe_*_xol() hooks can easily use user_enable/disable_single_step() directly. Change arch_uprobe_*_step() to do nothing, and convert powerpc to use ptrace helpers. This is equally wrong, powerpc needs the arch-specific fixes. Signed-off-by: Oleg Nesterov Acked-by: Ananth N Mavinakayanahalli Acked-by: Srikar Dronamraju --- arch/powerpc/kernel/uprobes.c | 6 ++++++ kernel/events/uprobes.c | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c index d2d46d1014f..bc77834dbf4 100644 --- a/arch/powerpc/kernel/uprobes.c +++ b/arch/powerpc/kernel/uprobes.c @@ -64,6 +64,8 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) autask->saved_trap_nr = current->thread.trap_nr; current->thread.trap_nr = UPROBE_TRAP_NR; regs->nip = current->utask->xol_vaddr; + + user_enable_single_step(current); return 0; } @@ -119,6 +121,8 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) * to be executed. */ regs->nip = utask->vaddr + MAX_UINSN_BYTES; + + user_disable_single_step(current); return 0; } @@ -162,6 +166,8 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) current->thread.trap_nr = utask->autask.saved_trap_nr; instruction_pointer_set(regs, utask->vaddr); + + user_disable_single_step(current); } /* diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 5cc4e7e42e6..abbfd8440a6 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1432,12 +1432,10 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) void __weak arch_uprobe_enable_step(struct arch_uprobe *arch) { - user_enable_single_step(current); } void __weak arch_uprobe_disable_step(struct arch_uprobe *arch) { - user_disable_single_step(current); } /* -- cgit v1.2.3 From 4dc316c64594d1a5ef2d61fba5ae0fe7fe18cdca Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 28 Oct 2012 17:57:30 +0100 Subject: uprobes/x86: Cleanup the single-stepping code No functional changes. Now that default arch_uprobe_enable/disable_step() helpers do nothing, x86 has no reason to reimplement them. Change arch_uprobe_*_xol() hooks to do the necessary work and remove the x86-specific hooks. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju --- arch/x86/kernel/uprobes.c | 54 +++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index aafa5557b39..c71025b6746 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c @@ -478,6 +478,11 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) regs->ip = current->utask->xol_vaddr; pre_xol_rip_insn(auprobe, regs, autask); + autask->saved_tf = !!(regs->flags & X86_EFLAGS_TF); + regs->flags |= X86_EFLAGS_TF; + if (test_tsk_thread_flag(current, TIF_BLOCKSTEP)) + set_task_blockstep(current, false); + return 0; } @@ -603,6 +608,16 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) if (auprobe->fixups & UPROBE_FIX_CALL) result = adjust_ret_addr(regs->sp, correction); + /* + * arch_uprobe_pre_xol() doesn't save the state of TIF_BLOCKSTEP + * so we can get an extra SIGTRAP if we do not clear TF. We need + * to examine the opcode to make it right. + */ + if (utask->autask.saved_tf) + send_sig(SIGTRAP, current, 0); + else if (!(auprobe->fixups & UPROBE_FIX_SETF)) + regs->flags &= ~X86_EFLAGS_TF; + return result; } @@ -647,6 +662,10 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) current->thread.trap_nr = utask->autask.saved_trap_nr; handle_riprel_post_xol(auprobe, regs, NULL); instruction_pointer_set(regs, utask->vaddr); + + /* clear TF if it was set by us in arch_uprobe_pre_xol() */ + if (!utask->autask.saved_tf) + regs->flags &= ~X86_EFLAGS_TF; } /* @@ -676,38 +695,3 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) send_sig(SIGTRAP, current, 0); return ret; } - -void arch_uprobe_enable_step(struct arch_uprobe *auprobe) -{ - struct task_struct *task = current; - struct arch_uprobe_task *autask = &task->utask->autask; - struct pt_regs *regs = task_pt_regs(task); - - autask->saved_tf = !!(regs->flags & X86_EFLAGS_TF); - - regs->flags |= X86_EFLAGS_TF; - if (test_tsk_thread_flag(task, TIF_BLOCKSTEP)) - set_task_blockstep(task, false); -} - -void arch_uprobe_disable_step(struct arch_uprobe *auprobe) -{ - struct task_struct *task = current; - struct arch_uprobe_task *autask = &task->utask->autask; - bool trapped = (task->utask->state == UTASK_SSTEP_TRAPPED); - struct pt_regs *regs = task_pt_regs(task); - /* - * The state of TIF_BLOCKSTEP was not saved so we can get an extra - * SIGTRAP if we do not clear TF. We need to examine the opcode to - * make it right. - */ - if (unlikely(trapped)) { - if (!autask->saved_tf) - regs->flags &= ~X86_EFLAGS_TF; - } else { - if (autask->saved_tf) - send_sig(SIGTRAP, task, 0); - else if (!(auprobe->fixups & UPROBE_FIX_SETF)) - regs->flags &= ~X86_EFLAGS_TF; - } -} -- cgit v1.2.3 From 19f5ee2716373519fda2129e9333f4c3847aa742 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Sun, 28 Oct 2012 18:14:14 +0100 Subject: uprobes: Kill arch_uprobe_enable/disable_step() hooks Kill arch_uprobe_enable/disable_step() hooks, they do nothing and nobody needs them. Signed-off-by: Oleg Nesterov Acked-by: Srikar Dronamraju --- include/linux/uprobes.h | 2 -- kernel/events/uprobes.c | 10 ---------- 2 files changed, 12 deletions(-) diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index 24594571c5a..2615c4d7788 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h @@ -101,8 +101,6 @@ extern void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm); extern void uprobe_free_utask(struct task_struct *t); extern void uprobe_copy_process(struct task_struct *t); extern unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs); -extern void __weak arch_uprobe_enable_step(struct arch_uprobe *arch); -extern void __weak arch_uprobe_disable_step(struct arch_uprobe *arch); extern int uprobe_post_sstep_notifier(struct pt_regs *regs); extern int uprobe_pre_sstep_notifier(struct pt_regs *regs); extern void uprobe_notify_resume(struct pt_regs *regs); diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index abbfd8440a6..39c75cc51ef 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1430,14 +1430,6 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) return uprobe; } -void __weak arch_uprobe_enable_step(struct arch_uprobe *arch) -{ -} - -void __weak arch_uprobe_disable_step(struct arch_uprobe *arch) -{ -} - /* * Run handler and ask thread to singlestep. * Ensure all non-fatal signals cannot interrupt thread while it singlesteps. @@ -1491,7 +1483,6 @@ static void handle_swbp(struct pt_regs *regs) goto out; if (!pre_ssout(uprobe, regs, bp_vaddr)) { - arch_uprobe_enable_step(&uprobe->arch); utask->active_uprobe = uprobe; utask->state = UTASK_SSTEP; return; @@ -1523,7 +1514,6 @@ static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs) else WARN_ON_ONCE(1); - arch_uprobe_disable_step(&uprobe->arch); put_uprobe(uprobe); utask->active_uprobe = NULL; utask->state = UTASK_RUNNING; -- cgit v1.2.3 From cdb2fac78321a8d621b5612c7ddfe96bdbe7d267 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Sat, 3 Nov 2012 12:39:27 -0400 Subject: USB: EHCI: fix build error in ChipIdea host driver This patch (as1629) fixes a build error in the ChipIdea host driver when compiled for the ARM architecture. The error was introduced by commit 99f91934a907df31ba878dfdd090002049dc476a (USB: EHCI: make ehci-platform a separate driver). The fix is simple; an additional header-file #include is needed. Signed-off-by: Alan Stern Tested-by: Fengguang Wu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/host.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index 30b17ae5aa2..fed97d32389 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include -- cgit v1.2.3 From ea2ccb3e0271067ae8ed213b306d7545f5d1f8ce Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 30 Oct 2012 10:26:00 +0000 Subject: staging:iio:adis16400: Fix adis16334 sampling frequency control Setting the sampling frequency for the adis16334 differs from the other devices. This patch introduces two new callback functions to the adis16400 chip_info struct which are used to specify how to read and write the current sample rate. The patch also introduces the proper implementations for these callbacks for the adis16334. Related to this is that the adis16334 has no slow mode and so we do not limit the SPI clock rate to 300kHz during initialization. The patch adds a new flag for devices which do have a slow mode. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/imu/adis16400.h | 11 ++- drivers/staging/iio/imu/adis16400_core.c | 122 +++++++++++++++++++++++-------- 2 files changed, 101 insertions(+), 32 deletions(-) diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h index 77c601da184..07a6aea75fe 100644 --- a/drivers/staging/iio/imu/adis16400.h +++ b/drivers/staging/iio/imu/adis16400.h @@ -123,6 +123,9 @@ /* SLP_CNT */ #define ADIS16400_SLP_CNT_POWER_OFF (1<<8) +#define ADIS16334_RATE_DIV_SHIFT 8 +#define ADIS16334_RATE_INT_CLK BIT(0) + #define ADIS16400_MAX_TX 24 #define ADIS16400_MAX_RX 24 @@ -130,8 +133,10 @@ #define ADIS16400_SPI_BURST (u32)(1000 * 1000) #define ADIS16400_SPI_FAST (u32)(2000 * 1000) -#define ADIS16400_HAS_PROD_ID 1 -#define ADIS16400_NO_BURST 2 +#define ADIS16400_HAS_PROD_ID BIT(0) +#define ADIS16400_NO_BURST BIT(1) +#define ADIS16400_HAS_SLOW_MODE BIT(2) + struct adis16400_chip_info { const struct iio_chan_spec *channels; const int num_channels; @@ -142,6 +147,8 @@ struct adis16400_chip_info { int temp_scale_nano; int temp_offset; unsigned long default_scan_mask; + int (*set_freq)(struct iio_dev *indio_dev, unsigned int freq); + int (*get_freq)(struct iio_dev *indio_dev); }; /** diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index baec6a1f23a..86192df2f79 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -161,10 +161,39 @@ error_ret: return ret; } -static int adis16400_get_freq(struct iio_dev *indio_dev) +static int adis16334_get_freq(struct iio_dev *indio_dev) { + int ret; u16 t; + + ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_SMPL_PRD, &t); + if (ret < 0) + return ret; + + t >>= ADIS16334_RATE_DIV_SHIFT; + + return (8192 >> t) / 10; +} + +static int adis16334_set_freq(struct iio_dev *indio_dev, unsigned int freq) +{ + unsigned int t; + + t = ilog2(8192 / (freq * 10)); + + if (t > 0x31) + t = 0x31; + + t <<= ADIS16334_RATE_DIV_SHIFT; + t |= ADIS16334_RATE_INT_CLK; + + return adis16400_spi_write_reg_16(indio_dev, ADIS16400_SMPL_PRD, t); +} + +static int adis16400_get_freq(struct iio_dev *indio_dev) +{ int sps, ret; + u16 t; ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_SMPL_PRD, &t); if (ret < 0) @@ -175,13 +204,33 @@ static int adis16400_get_freq(struct iio_dev *indio_dev) return sps; } +static int adis16400_set_freq(struct iio_dev *indio_dev, unsigned int freq) +{ + struct adis16400_state *st = iio_priv(indio_dev); + unsigned int t; + + t = 1638 / freq; + if (t > 0) + t--; + t &= ADIS16400_SMPL_PRD_DIV_MASK; + if ((t & ADIS16400_SMPL_PRD_DIV_MASK) >= 0x0A) + st->us->max_speed_hz = ADIS16400_SPI_SLOW; + else + st->us->max_speed_hz = ADIS16400_SPI_FAST; + + return adis16400_spi_write_reg_8(indio_dev, + ADIS16400_SMPL_PRD, t); +} + static ssize_t adis16400_read_frequency(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adis16400_state *st = iio_priv(indio_dev); int ret, len = 0; - ret = adis16400_get_freq(indio_dev); + + ret = st->variant->get_freq(indio_dev); if (ret < 0) return ret; len = sprintf(buf, "%d SPS\n", ret); @@ -229,7 +278,6 @@ static ssize_t adis16400_write_frequency(struct device *dev, struct adis16400_state *st = iio_priv(indio_dev); long val; int ret; - u8 t; ret = strict_strtol(buf, 10, &val); if (ret) @@ -239,18 +287,7 @@ static ssize_t adis16400_write_frequency(struct device *dev, mutex_lock(&indio_dev->mlock); - t = (1638 / val); - if (t > 0) - t--; - t &= ADIS16400_SMPL_PRD_DIV_MASK; - if ((t & ADIS16400_SMPL_PRD_DIV_MASK) >= 0x0A) - st->us->max_speed_hz = ADIS16400_SPI_SLOW; - else - st->us->max_speed_hz = ADIS16400_SPI_FAST; - - ret = adis16400_spi_write_reg_8(indio_dev, - ADIS16400_SMPL_PRD, - t); + st->variant->set_freq(indio_dev, val); /* Also update the filter */ mutex_unlock(&indio_dev->mlock); @@ -380,8 +417,11 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev) u16 prod_id, smp_prd; struct adis16400_state *st = iio_priv(indio_dev); - /* use low spi speed for init */ - st->us->max_speed_hz = ADIS16400_SPI_SLOW; + /* use low spi speed for init if the device has a slow mode */ + if (st->variant->flags & ADIS16400_HAS_SLOW_MODE) + st->us->max_speed_hz = ADIS16400_SPI_SLOW; + else + st->us->max_speed_hz = ADIS16400_SPI_FAST; st->us->mode = SPI_MODE_3; spi_setup(st->us); @@ -422,11 +462,16 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev) st->us->chip_select, st->us->irq); } /* use high spi speed if possible */ - ret = adis16400_spi_read_reg_16(indio_dev, - ADIS16400_SMPL_PRD, &smp_prd); - if (!ret && (smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) { - st->us->max_speed_hz = ADIS16400_SPI_SLOW; - spi_setup(st->us); + if (st->variant->flags & ADIS16400_HAS_SLOW_MODE) { + ret = adis16400_spi_read_reg_16(indio_dev, + ADIS16400_SMPL_PRD, &smp_prd); + if (ret) + goto err_ret; + + if ((smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) { + st->us->max_speed_hz = ADIS16400_SPI_FAST; + spi_setup(st->us); + } } err_ret: @@ -503,7 +548,7 @@ static int adis16400_write_raw(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); st->filt_int = val; /* Work out update to current value */ - sps = adis16400_get_freq(indio_dev); + sps = st->variant->get_freq(indio_dev); if (sps < 0) { mutex_unlock(&indio_dev->mlock); return sps; @@ -601,7 +646,7 @@ static int adis16400_read_raw(struct iio_dev *indio_dev, mutex_unlock(&indio_dev->mlock); return ret; } - ret = adis16400_get_freq(indio_dev); + val16 = st->variant->get_freq(indio_dev); if (ret > 0) *val = ret/adis16400_3db_divisors[val16 & 0x03]; *val2 = 0; @@ -1060,6 +1105,7 @@ static struct adis16400_chip_info adis16400_chips[] = { [ADIS16300] = { .channels = adis16300_channels, .num_channels = ARRAY_SIZE(adis16300_channels), + .flags = ADIS16400_HAS_SLOW_MODE, .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .accel_scale_micro = 5884, .temp_scale_nano = 140000000, /* 0.14 C */ @@ -1070,6 +1116,8 @@ static struct adis16400_chip_info adis16400_chips[] = { (1 << ADIS16400_SCAN_TEMP) | (1 << ADIS16400_SCAN_ADC_0) | (1 << ADIS16300_SCAN_INCLI_X) | (1 << ADIS16300_SCAN_INCLI_Y) | (1 << 14), + .set_freq = adis16400_set_freq, + .get_freq = adis16400_get_freq, }, [ADIS16334] = { .channels = adis16334_channels, @@ -1082,6 +1130,8 @@ static struct adis16400_chip_info adis16400_chips[] = { (1 << ADIS16400_SCAN_GYRO_Y) | (1 << ADIS16400_SCAN_GYRO_Z) | (1 << ADIS16400_SCAN_ACC_X) | (1 << ADIS16400_SCAN_ACC_Y) | (1 << ADIS16400_SCAN_ACC_Z), + .set_freq = adis16334_set_freq, + .get_freq = adis16334_get_freq, }, [ADIS16350] = { .channels = adis16350_channels, @@ -1091,62 +1141,74 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_scale_nano = 145300000, /* 0.1453 C */ .temp_offset = 25000000 / 145300, /* 25 C = 0x00 */ .default_scan_mask = 0x7FF, - .flags = ADIS16400_NO_BURST, + .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE, + .set_freq = adis16400_set_freq, + .get_freq = adis16400_get_freq, }, [ADIS16360] = { .channels = adis16350_channels, .num_channels = ARRAY_SIZE(adis16350_channels), - .flags = ADIS16400_HAS_PROD_ID, + .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE, .product_id = 0x3FE8, .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */ .temp_scale_nano = 136000000, /* 0.136 C */ .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .default_scan_mask = 0x7FF, + .set_freq = adis16400_set_freq, + .get_freq = adis16400_get_freq, }, [ADIS16362] = { .channels = adis16350_channels, .num_channels = ARRAY_SIZE(adis16350_channels), - .flags = ADIS16400_HAS_PROD_ID, + .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE, .product_id = 0x3FEA, .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .accel_scale_micro = IIO_G_TO_M_S_2(333), /* 0.333 mg */ .temp_scale_nano = 136000000, /* 0.136 C */ .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .default_scan_mask = 0x7FF, + .set_freq = adis16400_set_freq, + .get_freq = adis16400_get_freq, }, [ADIS16364] = { .channels = adis16350_channels, .num_channels = ARRAY_SIZE(adis16350_channels), - .flags = ADIS16400_HAS_PROD_ID, + .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE, .product_id = 0x3FEC, .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */ .temp_scale_nano = 136000000, /* 0.136 C */ .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .default_scan_mask = 0x7FF, + .set_freq = adis16400_set_freq, + .get_freq = adis16400_get_freq, }, [ADIS16365] = { .channels = adis16350_channels, .num_channels = ARRAY_SIZE(adis16350_channels), - .flags = ADIS16400_HAS_PROD_ID, + .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE, .product_id = 0x3FED, .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */ .temp_scale_nano = 136000000, /* 0.136 C */ .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .default_scan_mask = 0x7FF, + .set_freq = adis16400_set_freq, + .get_freq = adis16400_get_freq, }, [ADIS16400] = { .channels = adis16400_channels, .num_channels = ARRAY_SIZE(adis16400_channels), - .flags = ADIS16400_HAS_PROD_ID, + .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE, .product_id = 0x4015, .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */ .default_scan_mask = 0xFFF, .temp_scale_nano = 140000000, /* 0.14 C */ .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ + .set_freq = adis16400_set_freq, + .get_freq = adis16400_get_freq, } }; -- cgit v1.2.3 From fc8850c0a1fcbbf75cf37969be54a5c01445d9aa Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 30 Oct 2012 10:26:00 +0000 Subject: staging:iio:adis16400: Fix product id check The product id check currently ANDs the read id with 0xF000 and compares the result to the product id from the chip info. Since none of the product ids in the chip info table end in 0x000 the check will always fail. Furthermore it is also wrong, the product id in the PROD_ID register will always match the part number of the device. Some of the ADIS16XXX devices are identical from a software point of view with the product id register having a different content. If we keep the current scheme of storing the product id in the chip info table this would require us to have multiple almost identical chip info table entries. So instead this patch changes the code to parse the product id from the device name. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/imu/adis16400.h | 1 - drivers/staging/iio/imu/adis16400_core.c | 13 ++++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h index 07a6aea75fe..7a105e96646 100644 --- a/drivers/staging/iio/imu/adis16400.h +++ b/drivers/staging/iio/imu/adis16400.h @@ -140,7 +140,6 @@ struct adis16400_chip_info { const struct iio_chan_spec *channels; const int num_channels; - const int product_id; const long flags; unsigned int gyro_scale_micro; unsigned int accel_scale_micro; diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 86192df2f79..b876d823eb5 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -415,6 +415,7 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev) { int ret; u16 prod_id, smp_prd; + unsigned int device_id; struct adis16400_state *st = iio_priv(indio_dev); /* use low spi speed for init if the device has a slow mode */ @@ -454,8 +455,11 @@ static int adis16400_initial_setup(struct iio_dev *indio_dev) if (ret) goto err_ret; - if ((prod_id & 0xF000) != st->variant->product_id) - dev_warn(&indio_dev->dev, "incorrect id"); + sscanf(indio_dev->name, "adis%u\n", &device_id); + + if (prod_id != device_id) + dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.", + device_id, prod_id); dev_info(&indio_dev->dev, "%s: prod_id 0x%04x at CS%d (irq %d)\n", indio_dev->name, prod_id, @@ -1149,7 +1153,6 @@ static struct adis16400_chip_info adis16400_chips[] = { .channels = adis16350_channels, .num_channels = ARRAY_SIZE(adis16350_channels), .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE, - .product_id = 0x3FE8, .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */ .temp_scale_nano = 136000000, /* 0.136 C */ @@ -1162,7 +1165,6 @@ static struct adis16400_chip_info adis16400_chips[] = { .channels = adis16350_channels, .num_channels = ARRAY_SIZE(adis16350_channels), .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE, - .product_id = 0x3FEA, .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .accel_scale_micro = IIO_G_TO_M_S_2(333), /* 0.333 mg */ .temp_scale_nano = 136000000, /* 0.136 C */ @@ -1175,7 +1177,6 @@ static struct adis16400_chip_info adis16400_chips[] = { .channels = adis16350_channels, .num_channels = ARRAY_SIZE(adis16350_channels), .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE, - .product_id = 0x3FEC, .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */ .temp_scale_nano = 136000000, /* 0.136 C */ @@ -1188,7 +1189,6 @@ static struct adis16400_chip_info adis16400_chips[] = { .channels = adis16350_channels, .num_channels = ARRAY_SIZE(adis16350_channels), .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE, - .product_id = 0x3FED, .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */ .temp_scale_nano = 136000000, /* 0.136 C */ @@ -1201,7 +1201,6 @@ static struct adis16400_chip_info adis16400_chips[] = { .channels = adis16400_channels, .num_channels = ARRAY_SIZE(adis16400_channels), .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE, - .product_id = 0x4015, .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */ .default_scan_mask = 0xFFF, -- cgit v1.2.3 From a7462e640dbbb0fe3840f460266699a52b1d32f0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 30 Oct 2012 10:26:00 +0000 Subject: staging:iio:adis16400: Remove now duplicated chip_table entry The ADIS1360 and ADIS13605 are very similar and do have the same software interface. The only difference is the contents of the PROD_ID register. Since we now read the product id from the device name instead of the chip_info struct we can use the same chip_table entry for both the ADIS1360 and ADIS13605. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/imu/adis16400_core.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index b876d823eb5..a4718c537e7 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -38,7 +38,6 @@ enum adis16400_chip_variant { ADIS16360, ADIS16362, ADIS16364, - ADIS16365, ADIS16400, }; @@ -1185,18 +1184,6 @@ static struct adis16400_chip_info adis16400_chips[] = { .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, }, - [ADIS16365] = { - .channels = adis16350_channels, - .num_channels = ARRAY_SIZE(adis16350_channels), - .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE, - .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ - .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */ - .temp_scale_nano = 136000000, /* 0.136 C */ - .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ - .default_scan_mask = 0x7FF, - .set_freq = adis16400_set_freq, - .get_freq = adis16400_get_freq, - }, [ADIS16400] = { .channels = adis16400_channels, .num_channels = ARRAY_SIZE(adis16400_channels), @@ -1309,7 +1296,7 @@ static const struct spi_device_id adis16400_id[] = { {"adis16360", ADIS16360}, {"adis16362", ADIS16362}, {"adis16364", ADIS16364}, - {"adis16365", ADIS16365}, + {"adis16365", ADIS16360}, {"adis16400", ADIS16400}, {"adis16405", ADIS16400}, {} -- cgit v1.2.3 From 3c7f0c2b1150eae8683a98a5a9143d81edfc2762 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 30 Oct 2012 10:26:00 +0000 Subject: staging:iio:adis16400: Set the PROD_ID flag for the adis16334 The adis16334 has the PROD_ID register so set the PROD_ID flag in its chip info. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/imu/adis16400_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index a4718c537e7..c3f9bb95c7b 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -1125,6 +1125,7 @@ static struct adis16400_chip_info adis16400_chips[] = { [ADIS16334] = { .channels = adis16334_channels, .num_channels = ARRAY_SIZE(adis16334_channels), + .flags = ADIS16400_HAS_PROD_ID, .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */ .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */ .temp_scale_nano = 67850000, /* 0.06785 C */ -- cgit v1.2.3 From 1631081993b1e6a6d668b3eb089904b88f0efc2b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 31 Oct 2012 17:03:33 +0800 Subject: gpio: em: Fix build errors Fix below build errors: CC [M] drivers/gpio/gpio-em.o drivers/gpio/gpio-em.c: In function 'em_gio_probe': drivers/gpio/gpio-em.c:306: error: 'err' undeclared (first use in this function) drivers/gpio/gpio-em.c:306: error: (Each undeclared identifier is reported only once drivers/gpio/gpio-em.c:306: error: for each function it appears in.) drivers/gpio/gpio-em.c:308: error: label 'err3' used but not defined drivers/gpio/gpio-em.c:279: error: label 'err2' used but not defined drivers/gpio/gpio-em.c:265: error: label 'err1' used but not defined drivers/gpio/gpio-em.c:250: error: label 'err0' used but not defined drivers/gpio/gpio-em.c:309: warning: no return statement in function returning non-void drivers/gpio/gpio-em.c: At top level: drivers/gpio/gpio-em.c:311: error: expected identifier or '(' before 'if' drivers/gpio/gpio-em.c:317: error: expected identifier or '(' before 'if' drivers/gpio/gpio-em.c:323: warning: data definition has no type or storage class drivers/gpio/gpio-em.c:323: warning: type defaults to 'int' in declaration of 'ret' drivers/gpio/gpio-em.c:323: error: 'gpio_chip' undeclared here (not in a function) drivers/gpio/gpio-em.c:323: error: initializer element is not constant drivers/gpio/gpio-em.c:324: error: expected identifier or '(' before 'if' drivers/gpio/gpio-em.c:328: error: expected identifier or '(' before 'return' drivers/gpio/gpio-em.c:330: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:332: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:334: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:336: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:338: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:340: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:342: error: expected '=', ',', ';', 'asm' or '__attribute__' before ':' token drivers/gpio/gpio-em.c:344: error: expected identifier or '(' before '}' token drivers/gpio/gpio-em.c: In function 'em_gio_remove': drivers/gpio/gpio-em.c:361: error: implicit declaration of function 'em_gio_irq_domain_cleanup' make[2]: *** [drivers/gpio/gpio-em.o] Error 1 make[1]: *** [drivers/gpio] Error 2 make: *** [drivers] Error 2 Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/gpio/gpio-em.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index 88bdfe37816..b00706329d2 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -302,8 +302,8 @@ static int __devinit em_gio_probe(struct platform_device *pdev) p->irq_domain = irq_domain_add_linear(pdev->dev.of_node, pdata->number_of_pins, &em_gio_irq_domain_ops, p); - if (!p->irq_domain) - err = -ENXIO; + if (!p->irq_domain) { + ret = -ENXIO; dev_err(&pdev->dev, "cannot initialize irq domain\n"); goto err3; } @@ -358,7 +358,7 @@ static int __devexit em_gio_remove(struct platform_device *pdev) free_irq(irq[1]->start, pdev); free_irq(irq[0]->start, pdev); - em_gio_irq_domain_cleanup(p); + irq_domain_remove(p->irq_domain); iounmap(p->base1); iounmap(p->base0); kfree(p); -- cgit v1.2.3 From 5c868fc629b0e645a68aec3a6834d965e71531f4 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Fri, 2 Nov 2012 16:02:25 +0100 Subject: gpio-pch: Set parent dev for gpio chip This will show the gpio chip as a child node under /sys/bus/pci/devices/xxxx:xx:xx.x/ Signed-off-by: Alexander Stein Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index 4ad0c4f9171..e3a14fef79e 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -215,6 +215,7 @@ static void pch_gpio_setup(struct pch_gpio *chip) struct gpio_chip *gpio = &chip->gpio; gpio->label = dev_name(chip->dev); + gpio->dev = chip->dev; gpio->owner = THIS_MODULE; gpio->direction_input = pch_gpio_direction_input; gpio->get = pch_gpio_get; -- cgit v1.2.3 From 8c995d6dd66a713dba2a3de4924108318af7bbf0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 4 Nov 2012 23:30:42 +0800 Subject: pinctrl: nomadik: Add terminating entry for platform_device_id table The platform_device_id table is supposed to be zero-terminated. Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index f2fd99ba40e..22f69375bb3 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -1922,6 +1922,7 @@ static const struct platform_device_id nmk_pinctrl_id[] = { { "pinctrl-stn8815", PINCTRL_NMK_STN8815 }, { "pinctrl-db8500", PINCTRL_NMK_DB8500 }, { "pinctrl-db8540", PINCTRL_NMK_DB8540 }, + { } }; static struct platform_driver nmk_pinctrl_driver = { -- cgit v1.2.3 From 987c285c2ae2e4e32aca3a9b3252d28171c75711 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Mon, 5 Nov 2012 10:27:52 +0200 Subject: mac80211: sync acccess to tx_filtered/ps_tx_buf queues These are accessed without a lock when ending STA PSM. If the sta_cleanup timer accesses these lists at the same time, we might crash. This may fix some mysterious crashes we had during ieee80211_sta_ps_deliver_wakeup. Cc: stable@vger.kernel.org Signed-off-by: Arik Nemtsov Signed-off-by: Ido Yariv Signed-off-by: Johannes Berg --- net/mac80211/sta_info.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 797dd36a220..89ccd3ec7eb 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -961,6 +961,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) struct ieee80211_local *local = sdata->local; struct sk_buff_head pending; int filtered = 0, buffered = 0, ac; + unsigned long flags; clear_sta_flag(sta, WLAN_STA_SP); @@ -976,12 +977,16 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { int count = skb_queue_len(&pending), tmp; + spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags); skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending); + spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags); tmp = skb_queue_len(&pending); filtered += tmp - count; count = tmp; + spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags); skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending); + spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags); tmp = skb_queue_len(&pending); buffered += tmp - count; } -- cgit v1.2.3 From f6f94f6660dbe34039e5c86a46c7845589e7ee0c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 5 Nov 2012 21:23:50 +0800 Subject: pinctrl: at91: Staticize non-exported symbols Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 65f066c4500..b9e2cbd2ea7 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -566,9 +566,9 @@ static int at91_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, return 0; } -int at91_gpio_request_enable(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned offset) +static int at91_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) { struct at91_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); struct at91_gpio_chip *at91_chip; @@ -598,9 +598,9 @@ int at91_gpio_request_enable(struct pinctrl_dev *pctldev, return 0; } -void at91_gpio_disable_free(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned offset) +static void at91_gpio_disable_free(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) { struct at91_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); @@ -952,7 +952,7 @@ err: return ret; } -int __devexit at91_pinctrl_remove(struct platform_device *pdev) +static int __devexit at91_pinctrl_remove(struct platform_device *pdev) { struct at91_pinctrl *info = platform_get_drvdata(pdev); @@ -1249,9 +1249,11 @@ static int at91_gpio_irq_map(struct irq_domain *h, unsigned int virq, return 0; } -int at91_gpio_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, unsigned int *out_type) +static int at91_gpio_irq_domain_xlate(struct irq_domain *d, + struct device_node *ctrlr, + const u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, + unsigned int *out_type) { struct at91_gpio_chip *at91_gpio = d->host_data; int ret; -- cgit v1.2.3 From 7c34158231b2eda8dcbd297be2bb1559e69cb433 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 4 Nov 2012 09:29:17 +0100 Subject: iwlwifi: handle DMA mapping failures The RX replenish code doesn't handle DMA mapping failures, which will cause issues if there actually is a failure. This was reported by Shuah Khan who found a DMA mapping framework warning ("device driver failed to check map error"). Cc: stable@vger.kernel.org Reported-by: Shuah Khan Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/rx.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 17c8e5d8268..bb69f8f90b3 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -321,6 +321,14 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority) dma_map_page(trans->dev, page, 0, PAGE_SIZE << trans_pcie->rx_page_order, DMA_FROM_DEVICE); + if (dma_mapping_error(trans->dev, rxb->page_dma)) { + rxb->page = NULL; + spin_lock_irqsave(&rxq->lock, flags); + list_add(&rxb->list, &rxq->rx_used); + spin_unlock_irqrestore(&rxq->lock, flags); + __free_pages(page, trans_pcie->rx_page_order); + return; + } /* dma address must be no more than 36 bits */ BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); /* and also 256 byte aligned! */ @@ -488,8 +496,19 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, dma_map_page(trans->dev, rxb->page, 0, PAGE_SIZE << trans_pcie->rx_page_order, DMA_FROM_DEVICE); - list_add_tail(&rxb->list, &rxq->rx_free); - rxq->free_count++; + if (dma_mapping_error(trans->dev, rxb->page_dma)) { + /* + * free the page(s) as well to not break + * the invariant that the items on the used + * list have no page(s) + */ + __free_pages(rxb->page, trans_pcie->rx_page_order); + rxb->page = NULL; + list_add_tail(&rxb->list, &rxq->rx_used); + } else { + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; + } } else list_add_tail(&rxb->list, &rxq->rx_used); spin_unlock_irqrestore(&rxq->lock, flags); -- cgit v1.2.3 From 23823641ff8415ef500483af06a58069f7470d23 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:54 +0100 Subject: perf tests: Add attr record data test Adding test to validate perf_event_attr data for command: 'record -d' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-14-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-data | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-data diff --git a/tools/perf/tests/attr/test-record-data b/tools/perf/tests/attr/test-record-data new file mode 100644 index 00000000000..6627c3e7534 --- /dev/null +++ b/tools/perf/tests/attr/test-record-data @@ -0,0 +1,8 @@ +[config] +command = record +args = -d kill >/dev/null 2>&1 + +[event:base-record] +sample_period=4000 +sample_type=271 +mmap_data=1 -- cgit v1.2.3 From 813105858a85c9a98fc686fbe6788dc217cc9ab3 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:55 +0100 Subject: perf tests: Add attr record raw test Adding test to validate perf_event_attr data for command: 'record -R' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-15-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-raw | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-raw diff --git a/tools/perf/tests/attr/test-record-raw b/tools/perf/tests/attr/test-record-raw new file mode 100644 index 00000000000..4a8ef25b5f4 --- /dev/null +++ b/tools/perf/tests/attr/test-record-raw @@ -0,0 +1,7 @@ +[config] +command = record +args = -R kill >/dev/null 2>&1 + +[event:base-record] +sample_period=4000 +sample_type=1415 -- cgit v1.2.3 From f2e264ce36cbac642a63c23725da712bf00d508b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:56 +0100 Subject: perf tests: Add attr record no delay test Adding test to validate perf_event_attr data for command: 'record -D' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-16-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-no-delay | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-no-delay diff --git a/tools/perf/tests/attr/test-record-no-delay b/tools/perf/tests/attr/test-record-no-delay new file mode 100644 index 00000000000..f253b78cdbf --- /dev/null +++ b/tools/perf/tests/attr/test-record-no-delay @@ -0,0 +1,9 @@ +[config] +command = record +args = -D kill >/dev/null 2>&1 + +[event:base-record] +sample_period=4000 +sample_type=263 +watermark=0 +wakeup_events=1 -- cgit v1.2.3 From 2fa10f2fe370f2da6c48dae5a154bfcd74848538 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:57 +0100 Subject: perf tests: Add attr record branch any test Adding test to validate perf_event_attr data for command: 'record -b' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-17-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-branch-any | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-branch-any diff --git a/tools/perf/tests/attr/test-record-branch-any b/tools/perf/tests/attr/test-record-branch-any new file mode 100644 index 00000000000..1421960ed4e --- /dev/null +++ b/tools/perf/tests/attr/test-record-branch-any @@ -0,0 +1,8 @@ +[config] +command = record +args = -b kill >/dev/null 2>&1 + +[event:base-record] +sample_period=4000 +sample_type=2311 +branch_sample_type=8 -- cgit v1.2.3 From 9c90178412813368b7f040793c4af2fdfed3634d Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:01:58 +0100 Subject: perf tests: Add attr record branch filter tests Adding test to validate perf_event_attr data for command: 'record -j any' 'record -j any_call' 'record -j any_ret' 'record -j hv' 'record -j ind_call' 'record -j k' 'record -j u' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-18-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-record-branch-filter-any | 8 ++++++++ tools/perf/tests/attr/test-record-branch-filter-any_call | 8 ++++++++ tools/perf/tests/attr/test-record-branch-filter-any_ret | 8 ++++++++ tools/perf/tests/attr/test-record-branch-filter-hv | 8 ++++++++ tools/perf/tests/attr/test-record-branch-filter-ind_call | 8 ++++++++ tools/perf/tests/attr/test-record-branch-filter-k | 8 ++++++++ tools/perf/tests/attr/test-record-branch-filter-u | 8 ++++++++ 7 files changed, 56 insertions(+) create mode 100644 tools/perf/tests/attr/test-record-branch-filter-any create mode 100644 tools/perf/tests/attr/test-record-branch-filter-any_call create mode 100644 tools/perf/tests/attr/test-record-branch-filter-any_ret create mode 100644 tools/perf/tests/attr/test-record-branch-filter-hv create mode 100644 tools/perf/tests/attr/test-record-branch-filter-ind_call create mode 100644 tools/perf/tests/attr/test-record-branch-filter-k create mode 100644 tools/perf/tests/attr/test-record-branch-filter-u diff --git a/tools/perf/tests/attr/test-record-branch-filter-any b/tools/perf/tests/attr/test-record-branch-filter-any new file mode 100644 index 00000000000..915c4df0e0c --- /dev/null +++ b/tools/perf/tests/attr/test-record-branch-filter-any @@ -0,0 +1,8 @@ +[config] +command = record +args = -j any kill >/dev/null 2>&1 + +[event:base-record] +sample_period=4000 +sample_type=2311 +branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-branch-filter-any_call b/tools/perf/tests/attr/test-record-branch-filter-any_call new file mode 100644 index 00000000000..8708dbd4f37 --- /dev/null +++ b/tools/perf/tests/attr/test-record-branch-filter-any_call @@ -0,0 +1,8 @@ +[config] +command = record +args = -j any_call kill >/dev/null 2>&1 + +[event:base-record] +sample_period=4000 +sample_type=2311 +branch_sample_type=16 diff --git a/tools/perf/tests/attr/test-record-branch-filter-any_ret b/tools/perf/tests/attr/test-record-branch-filter-any_ret new file mode 100644 index 00000000000..0d3607a6dcb --- /dev/null +++ b/tools/perf/tests/attr/test-record-branch-filter-any_ret @@ -0,0 +1,8 @@ +[config] +command = record +args = -j any_ret kill >/dev/null 2>&1 + +[event:base-record] +sample_period=4000 +sample_type=2311 +branch_sample_type=32 diff --git a/tools/perf/tests/attr/test-record-branch-filter-hv b/tools/perf/tests/attr/test-record-branch-filter-hv new file mode 100644 index 00000000000..f25526740ce --- /dev/null +++ b/tools/perf/tests/attr/test-record-branch-filter-hv @@ -0,0 +1,8 @@ +[config] +command = record +args = -j hv kill >/dev/null 2>&1 + +[event:base-record] +sample_period=4000 +sample_type=2311 +branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-branch-filter-ind_call b/tools/perf/tests/attr/test-record-branch-filter-ind_call new file mode 100644 index 00000000000..e862dd17912 --- /dev/null +++ b/tools/perf/tests/attr/test-record-branch-filter-ind_call @@ -0,0 +1,8 @@ +[config] +command = record +args = -j ind_call kill >/dev/null 2>&1 + +[event:base-record] +sample_period=4000 +sample_type=2311 +branch_sample_type=64 diff --git a/tools/perf/tests/attr/test-record-branch-filter-k b/tools/perf/tests/attr/test-record-branch-filter-k new file mode 100644 index 00000000000..182971e898f --- /dev/null +++ b/tools/perf/tests/attr/test-record-branch-filter-k @@ -0,0 +1,8 @@ +[config] +command = record +args = -j k kill >/dev/null 2>&1 + +[event:base-record] +sample_period=4000 +sample_type=2311 +branch_sample_type=8 diff --git a/tools/perf/tests/attr/test-record-branch-filter-u b/tools/perf/tests/attr/test-record-branch-filter-u new file mode 100644 index 00000000000..83449ef9e68 --- /dev/null +++ b/tools/perf/tests/attr/test-record-branch-filter-u @@ -0,0 +1,8 @@ +[config] +command = record +args = -j u kill >/dev/null 2>&1 + +[event:base-record] +sample_period=4000 +sample_type=2311 +branch_sample_type=8 -- cgit v1.2.3 From 9602681f705830955eff1c2dd18283e5a01be58c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:02:00 +0100 Subject: perf tests: Add attr stat no-inherit test Adding test to validate perf_event_attr data for command: 'stat -i' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-20-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-stat-no-inherit | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tools/perf/tests/attr/test-stat-no-inherit diff --git a/tools/perf/tests/attr/test-stat-no-inherit b/tools/perf/tests/attr/test-stat-no-inherit new file mode 100644 index 00000000000..d54b2a1e3e2 --- /dev/null +++ b/tools/perf/tests/attr/test-stat-no-inherit @@ -0,0 +1,7 @@ +[config] +command = stat +args = -i -e cycles kill >/dev/null 2>&1 +ret = 1 + +[event:base-stat] +inherit=0 -- cgit v1.2.3 From a6d3476c58763b35104d815757faed5bdf040cea Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:02:01 +0100 Subject: perf tests: Add attr stat group test Adding test to validate perf_event_attr data for command: 'stat --group -e cycles,instructions' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-21-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-stat-group | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tools/perf/tests/attr/test-stat-group diff --git a/tools/perf/tests/attr/test-stat-group b/tools/perf/tests/attr/test-stat-group new file mode 100644 index 00000000000..fdc1596a886 --- /dev/null +++ b/tools/perf/tests/attr/test-stat-group @@ -0,0 +1,15 @@ +[config] +command = stat +args = --group -e cycles,instructions kill >/dev/null 2>&1 +ret = 1 + +[event-1:base-stat] +fd=1 +group_fd=-1 + +[event-2:base-stat] +fd=2 +group_fd=1 +config=1 +disabled=0 +enable_on_exec=0 -- cgit v1.2.3 From 28ae79cfb622cf471d45f1b3f38609d8766e8a95 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:02:02 +0100 Subject: perf tests: Add attr stat event syntax group test Adding test to validate perf_event_attr data for command: 'stat -e {cycles,instructions}' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-22-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-stat-group1 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tools/perf/tests/attr/test-stat-group1 diff --git a/tools/perf/tests/attr/test-stat-group1 b/tools/perf/tests/attr/test-stat-group1 new file mode 100644 index 00000000000..5ae2718de86 --- /dev/null +++ b/tools/perf/tests/attr/test-stat-group1 @@ -0,0 +1,17 @@ +[config] +command = stat +args = -e '{cycles,instructions}' kill >/dev/null 2>&1 +ret = 1 + +[event-1:base-stat] +fd=1 +group_fd=-1 + +[event-2:base-stat] +fd=2 +group_fd=1 +config=1 +# TODO both disabled and enable_on_exec are disabled for --group option, +# enabled otherwise, check why.. +disabled=1 +enable_on_exec=1 -- cgit v1.2.3 From 149960a0dd4222fbd6678876c005b8b1c85f8e6a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:02:03 +0100 Subject: perf tests: Add attr stat default test Adding test to validate perf_event_attr data for command: 'stat' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-23-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-stat-default | 64 +++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 tools/perf/tests/attr/test-stat-default diff --git a/tools/perf/tests/attr/test-stat-default b/tools/perf/tests/attr/test-stat-default new file mode 100644 index 00000000000..19270f54c96 --- /dev/null +++ b/tools/perf/tests/attr/test-stat-default @@ -0,0 +1,64 @@ +[config] +command = stat +args = kill >/dev/null 2>&1 +ret = 1 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK +[event1:base-stat] +fd=1 +type=1 +config=1 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES +[event2:base-stat] +fd=2 +type=1 +config=3 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS +[event3:base-stat] +fd=3 +type=1 +config=4 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS +[event4:base-stat] +fd=4 +type=1 +config=2 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES +[event5:base-stat] +fd=5 +type=0 +config=0 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND +[event6:base-stat] +fd=6 +type=0 +config=7 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND +[event7:base-stat] +fd=7 +type=0 +config=8 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS +[event8:base-stat] +fd=8 +type=0 +config=1 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS +[event9:base-stat] +fd=9 +type=0 +config=4 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES +[event10:base-stat] +fd=10 +type=0 +config=5 -- cgit v1.2.3 From 8a6408a04bf98c853a047412f20f9c73669058be Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:02:04 +0100 Subject: perf tests: Add attr stat default test Adding test to validate perf_event_attr data for commands: 'stat -d' 'stat -dd' 'stat -ddd' Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-24-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/test-stat-detailed-1 | 101 +++++++++++++++++ tools/perf/tests/attr/test-stat-detailed-2 | 155 ++++++++++++++++++++++++++ tools/perf/tests/attr/test-stat-detailed-3 | 173 +++++++++++++++++++++++++++++ 3 files changed, 429 insertions(+) create mode 100644 tools/perf/tests/attr/test-stat-detailed-1 create mode 100644 tools/perf/tests/attr/test-stat-detailed-2 create mode 100644 tools/perf/tests/attr/test-stat-detailed-3 diff --git a/tools/perf/tests/attr/test-stat-detailed-1 b/tools/perf/tests/attr/test-stat-detailed-1 new file mode 100644 index 00000000000..51426b87153 --- /dev/null +++ b/tools/perf/tests/attr/test-stat-detailed-1 @@ -0,0 +1,101 @@ +[config] +command = stat +args = -d kill >/dev/null 2>&1 +ret = 1 + + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK +[event1:base-stat] +fd=1 +type=1 +config=1 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES +[event2:base-stat] +fd=2 +type=1 +config=3 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS +[event3:base-stat] +fd=3 +type=1 +config=4 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS +[event4:base-stat] +fd=4 +type=1 +config=2 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES +[event5:base-stat] +fd=5 +type=0 +config=0 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND +[event6:base-stat] +fd=6 +type=0 +config=7 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND +[event7:base-stat] +fd=7 +type=0 +config=8 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS +[event8:base-stat] +fd=8 +type=0 +config=1 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS +[event9:base-stat] +fd=9 +type=0 +config=4 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES +[event10:base-stat] +fd=10 +type=0 +config=5 + +# PERF_TYPE_HW_CACHE / +# PERF_COUNT_HW_CACHE_L1D << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event11:base-stat] +fd=11 +type=3 +config=0 + +# PERF_TYPE_HW_CACHE / +# PERF_COUNT_HW_CACHE_L1D << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event12:base-stat] +fd=12 +type=3 +config=65536 + +# PERF_TYPE_HW_CACHE / +# PERF_COUNT_HW_CACHE_LL << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event13:base-stat] +fd=13 +type=3 +config=2 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_LL << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event14:base-stat] +fd=14 +type=3 +config=65538 diff --git a/tools/perf/tests/attr/test-stat-detailed-2 b/tools/perf/tests/attr/test-stat-detailed-2 new file mode 100644 index 00000000000..8de5acc31c2 --- /dev/null +++ b/tools/perf/tests/attr/test-stat-detailed-2 @@ -0,0 +1,155 @@ +[config] +command = stat +args = -dd kill >/dev/null 2>&1 +ret = 1 + + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK +[event1:base-stat] +fd=1 +type=1 +config=1 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES +[event2:base-stat] +fd=2 +type=1 +config=3 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS +[event3:base-stat] +fd=3 +type=1 +config=4 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS +[event4:base-stat] +fd=4 +type=1 +config=2 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES +[event5:base-stat] +fd=5 +type=0 +config=0 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND +[event6:base-stat] +fd=6 +type=0 +config=7 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND +[event7:base-stat] +fd=7 +type=0 +config=8 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS +[event8:base-stat] +fd=8 +type=0 +config=1 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS +[event9:base-stat] +fd=9 +type=0 +config=4 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES +[event10:base-stat] +fd=10 +type=0 +config=5 + +# PERF_TYPE_HW_CACHE / +# PERF_COUNT_HW_CACHE_L1D << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event11:base-stat] +fd=11 +type=3 +config=0 + +# PERF_TYPE_HW_CACHE / +# PERF_COUNT_HW_CACHE_L1D << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event12:base-stat] +fd=12 +type=3 +config=65536 + +# PERF_TYPE_HW_CACHE / +# PERF_COUNT_HW_CACHE_LL << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event13:base-stat] +fd=13 +type=3 +config=2 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_LL << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event14:base-stat] +fd=14 +type=3 +config=65538 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_L1I << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event15:base-stat] +fd=15 +type=3 +config=1 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_L1I << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event16:base-stat] +fd=16 +type=3 +config=65537 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_DTLB << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event17:base-stat] +fd=17 +type=3 +config=3 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_DTLB << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event18:base-stat] +fd=18 +type=3 +config=65539 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_ITLB << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event19:base-stat] +fd=19 +type=3 +config=4 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_ITLB << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event20:base-stat] +fd=20 +type=3 +config=65540 diff --git a/tools/perf/tests/attr/test-stat-detailed-3 b/tools/perf/tests/attr/test-stat-detailed-3 new file mode 100644 index 00000000000..0a1f45bf7d7 --- /dev/null +++ b/tools/perf/tests/attr/test-stat-detailed-3 @@ -0,0 +1,173 @@ +[config] +command = stat +args = -ddd kill >/dev/null 2>&1 +ret = 1 + + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_TASK_CLOCK +[event1:base-stat] +fd=1 +type=1 +config=1 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CONTEXT_SWITCHES +[event2:base-stat] +fd=2 +type=1 +config=3 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_CPU_MIGRATIONS +[event3:base-stat] +fd=3 +type=1 +config=4 + +# PERF_TYPE_SOFTWARE / PERF_COUNT_SW_PAGE_FAULTS +[event4:base-stat] +fd=4 +type=1 +config=2 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_CPU_CYCLES +[event5:base-stat] +fd=5 +type=0 +config=0 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_FRONTEND +[event6:base-stat] +fd=6 +type=0 +config=7 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_STALLED_CYCLES_BACKEND +[event7:base-stat] +fd=7 +type=0 +config=8 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_INSTRUCTIONS +[event8:base-stat] +fd=8 +type=0 +config=1 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_INSTRUCTIONS +[event9:base-stat] +fd=9 +type=0 +config=4 + +# PERF_TYPE_HARDWARE / PERF_COUNT_HW_BRANCH_MISSES +[event10:base-stat] +fd=10 +type=0 +config=5 + +# PERF_TYPE_HW_CACHE / +# PERF_COUNT_HW_CACHE_L1D << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event11:base-stat] +fd=11 +type=3 +config=0 + +# PERF_TYPE_HW_CACHE / +# PERF_COUNT_HW_CACHE_L1D << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event12:base-stat] +fd=12 +type=3 +config=65536 + +# PERF_TYPE_HW_CACHE / +# PERF_COUNT_HW_CACHE_LL << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event13:base-stat] +fd=13 +type=3 +config=2 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_LL << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event14:base-stat] +fd=14 +type=3 +config=65538 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_L1I << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event15:base-stat] +fd=15 +type=3 +config=1 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_L1I << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event16:base-stat] +fd=16 +type=3 +config=65537 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_DTLB << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event17:base-stat] +fd=17 +type=3 +config=3 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_DTLB << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event18:base-stat] +fd=18 +type=3 +config=65539 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_ITLB << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event19:base-stat] +fd=19 +type=3 +config=4 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_ITLB << 0 | +# (PERF_COUNT_HW_CACHE_OP_READ << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event20:base-stat] +fd=20 +type=3 +config=65540 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_L1D << 0 | +# (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) +[event21:base-stat] +fd=21 +type=3 +config=512 + +# PERF_TYPE_HW_CACHE, +# PERF_COUNT_HW_CACHE_L1D << 0 | +# (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) | +# (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) +[event22:base-stat] +fd=22 +type=3 +config=66048 -- cgit v1.2.3 From b84800a31502ab75c0032192de01e61a0d517f38 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 30 Oct 2012 23:02:06 +0100 Subject: perf tests: Add documentation for attr tests Adding documentation for attr tests. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351634526-1516-26-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/README | 64 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 tools/perf/tests/attr/README diff --git a/tools/perf/tests/attr/README b/tools/perf/tests/attr/README new file mode 100644 index 00000000000..d102957cd59 --- /dev/null +++ b/tools/perf/tests/attr/README @@ -0,0 +1,64 @@ +The struct perf_event_attr test (attr tests) support +==================================================== +This testing support is embedded into perf directly and is governed +by the PERF_TEST_ATTR environment variable and hook inside the +sys_perf_event_open function. + +The general idea is to store 'struct perf_event_attr' details for +each event created within single perf command. Each event details +are stored into separate text file. Once perf command is finished +these files are checked for values we expect for command. + +The attr tests consist of following parts: + +tests/attr.c +------------ +This is the sys_perf_event_open hook implementation. The hook +is triggered when the PERF_TEST_ATTR environment variable is +defined. It must contain name of existing directory with access +and write permissions. + +For each sys_perf_event_open call event details are stored in +separate file. Besides 'struct perf_event_attr' values we also +store 'fd' and 'group_fd' values to allow checking for groups. + +tests/attr.py +------------- +This is the python script that does all the hard work. It reads +the test definition, executes it and checks results. + +tests/attr/ +----------- +Directory containing all attr test definitions. +Following tests are defined (with perf commands): + + perf record kill (test-record-basic) + perf record -b kill (test-record-branch-any) + perf record -j any kill (test-record-branch-filter-any) + perf record -j any_call kill (test-record-branch-filter-any_call) + perf record -j any_ret kill (test-record-branch-filter-any_ret) + perf record -j hv kill (test-record-branch-filter-hv) + perf record -j ind_call kill (test-record-branch-filter-ind_call) + perf record -j k kill (test-record-branch-filter-k) + perf record -j u kill (test-record-branch-filter-u) + perf record -c 123 kill (test-record-count) + perf record -d kill (test-record-data) + perf record -F 100 kill (test-record-freq) + perf record -g -- kill (test-record-graph-default) + perf record -g dwarf -- kill (test-record-graph-dwarf) + perf record -g fp kill (test-record-graph-fp) + perf record --group -e cycles,instructions kill (test-record-group) + perf record -e '{cycles,instructions}' kill (test-record-group1) + perf record -D kill (test-record-no-delay) + perf record -i kill (test-record-no-inherit) + perf record -n kill (test-record-no-samples) + perf record -c 100 -P kill (test-record-period) + perf record -R kill (test-record-raw) + perf stat -e cycles kill (test-stat-basic) + perf stat kill (test-stat-default) + perf stat -d kill (test-stat-detailed-1) + perf stat -dd kill (test-stat-detailed-2) + perf stat -ddd kill (test-stat-detailed-3) + perf stat --group -e cycles,instructions kill (test-stat-group) + perf stat -e '{cycles,instructions}' kill (test-stat-group1) + perf stat -i -e cycles kill (test-stat-no-inherit) -- cgit v1.2.3 From 48ed0ece1b8063313284812ef048b26c3c4250af Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 2 Nov 2012 14:50:04 +0900 Subject: perf tools: Use normalized arch name for searching objdump path David reported that perf report for i686 target data on x86_64 host failed to work because it tried to find out cross-compiled objdump. However objdump for x86_64 is compatible to i686 so that it doesn't need to do it at all. To prevent similar artifacts, normalize arch name when comparing host and file architectures. Reported-by: David Ahern Signed-off-by: Namhyung Kim Reviewed-by: David Ahern Tested-by: David Ahern Cc: David Ahern Cc: Ingo Molnar Cc: Irina Tirdea Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351835406-15208-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/common.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index 2367b253f03..5683529135b 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c @@ -93,16 +93,46 @@ static int lookup_triplets(const char *const *triplets, const char *name) return -1; } +/* + * Return architecture name in a normalized form. + * The conversion logic comes from the Makefile. + */ +static const char *normalize_arch(char *arch) +{ + if (!strcmp(arch, "x86_64")) + return "x86"; + if (arch[0] == 'i' && arch[2] == '8' && arch[3] == '6') + return "x86"; + if (!strcmp(arch, "sun4u") || !strncmp(arch, "sparc", 5)) + return "sparc"; + if (!strncmp(arch, "arm", 3) || !strcmp(arch, "sa110")) + return "arm"; + if (!strncmp(arch, "s390", 4)) + return "s390"; + if (!strncmp(arch, "parisc", 6)) + return "parisc"; + if (!strncmp(arch, "powerpc", 7) || !strncmp(arch, "ppc", 3)) + return "powerpc"; + if (!strncmp(arch, "mips", 4)) + return "mips"; + if (!strncmp(arch, "sh", 2) && isdigit(arch[2])) + return "sh"; + + return arch; +} + static int perf_session_env__lookup_binutils_path(struct perf_session_env *env, const char *name, const char **path) { int idx; - char *arch, *cross_env; + const char *arch, *cross_env; struct utsname uts; const char *const *path_list; char *buf = NULL; + arch = normalize_arch(env->arch); + if (uname(&uts) < 0) goto out; @@ -110,7 +140,7 @@ static int perf_session_env__lookup_binutils_path(struct perf_session_env *env, * We don't need to try to find objdump path for native system. * Just use default binutils path (e.g.: "objdump"). */ - if (!strcmp(uts.machine, env->arch)) + if (!strcmp(normalize_arch(uts.machine), arch)) goto out; cross_env = getenv("CROSS_COMPILE"); @@ -127,8 +157,6 @@ static int perf_session_env__lookup_binutils_path(struct perf_session_env *env, free(buf); } - arch = env->arch; - if (!strcmp(arch, "arm")) path_list = arm_triplets; else if (!strcmp(arch, "powerpc")) @@ -139,9 +167,7 @@ static int perf_session_env__lookup_binutils_path(struct perf_session_env *env, path_list = s390_triplets; else if (!strcmp(arch, "sparc")) path_list = sparc_triplets; - else if (!strcmp(arch, "x86") || !strcmp(arch, "i386") || - !strcmp(arch, "i486") || !strcmp(arch, "i586") || - !strcmp(arch, "i686")) + else if (!strcmp(arch, "x86")) path_list = x86_triplets; else if (!strcmp(arch, "mips")) path_list = mips_triplets; -- cgit v1.2.3 From 9783adf777a445a1e9d0db4857a3a896a9f42d4a Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 2 Nov 2012 14:50:05 +0900 Subject: perf tools: Introduce struct hist_browser_timer Currently various hist browser functions receive 3 arguments for refreshing histogram but only used from a few places. Also it's only for perf top command so that it can be NULL for other (and probably most) cases. Pack them into a struct in order to reduce number of those unused arguments. This is a mechanical change and does not intend a functional change. Signed-off-by: Namhyung Kim Tested-by: David Ahern Cc: David Ahern Cc: Ingo Molnar Cc: Irina Tirdea Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351835406-15208-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-report.c | 4 ++-- tools/perf/builtin-top.c | 9 +++++--- tools/perf/ui/browsers/annotate.c | 27 +++++++++++------------- tools/perf/ui/browsers/hists.c | 43 +++++++++++++++++---------------------- tools/perf/ui/gtk/browser.c | 4 +--- tools/perf/util/annotate.h | 8 ++++---- tools/perf/util/hist.h | 28 ++++++++++++------------- 8 files changed, 58 insertions(+), 67 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index cb234765ce3..dc870cf31b7 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -139,7 +139,7 @@ find_next: } if (use_browser > 0) { - key = hist_entry__tui_annotate(he, evidx, NULL, NULL, 0); + key = hist_entry__tui_annotate(he, evidx, NULL); switch (key) { case K_RIGHT: next = rb_next(nd); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index f07eae73e69..234f34d466e 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -428,10 +428,10 @@ static int __cmd_report(struct perf_report *rep) if (use_browser > 0) { if (use_browser == 1) { perf_evlist__tui_browse_hists(session->evlist, help, - NULL, NULL, 0); + NULL); } else if (use_browser == 2) { perf_evlist__gtk_browse_hists(session->evlist, help, - NULL, NULL, 0); + NULL); } } else perf_evlist__tty_browse_hists(session->evlist, rep, help); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index f2ecd498c72..102b43c9905 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -582,6 +582,11 @@ static void *display_thread_tui(void *arg) struct perf_evsel *pos; struct perf_top *top = arg; const char *help = "For a higher level overview, try: perf top --sort comm,dso"; + struct hist_browser_timer hbt = { + .timer = perf_top__sort_new_samples, + .arg = top, + .refresh = top->delay_secs, + }; perf_top__sort_new_samples(top); @@ -593,9 +598,7 @@ static void *display_thread_tui(void *arg) list_for_each_entry(pos, &top->evlist->entries, node) pos->hists.uid_filter_str = top->target.uid_str; - perf_evlist__tui_browse_hists(top->evlist, help, - perf_top__sort_new_samples, - top, top->delay_secs); + perf_evlist__tui_browse_hists(top->evlist, help, &hbt); exit_browser(0); exit(0); diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 28f8aab73ae..3eff17f703f 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -386,9 +386,8 @@ static void annotate_browser__init_asm_mode(struct annotate_browser *browser) browser->b.nr_entries = browser->nr_asm_entries; } -static bool annotate_browser__callq(struct annotate_browser *browser, - int evidx, void (*timer)(void *arg), - void *arg, int delay_secs) +static bool annotate_browser__callq(struct annotate_browser *browser, int evidx, + struct hist_browser_timer *hbt) { struct map_symbol *ms = browser->b.priv; struct disasm_line *dl = browser->selection; @@ -418,7 +417,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser, } pthread_mutex_unlock(¬es->lock); - symbol__tui_annotate(target, ms->map, evidx, timer, arg, delay_secs); + symbol__tui_annotate(target, ms->map, evidx, hbt); ui_browser__show_title(&browser->b, sym->name); return true; } @@ -602,13 +601,13 @@ static void annotate_browser__update_addr_width(struct annotate_browser *browser } static int annotate_browser__run(struct annotate_browser *browser, int evidx, - void(*timer)(void *arg), - void *arg, int delay_secs) + struct hist_browser_timer *hbt) { struct rb_node *nd = NULL; struct map_symbol *ms = browser->b.priv; struct symbol *sym = ms->sym; const char *help = "Press 'h' for help on key bindings"; + int delay_secs = hbt ? hbt->refresh : 0; int key; if (ui_browser__show(&browser->b, sym->name, help) < 0) @@ -639,8 +638,8 @@ static int annotate_browser__run(struct annotate_browser *browser, int evidx, switch (key) { case K_TIMER: - if (timer != NULL) - timer(arg); + if (hbt) + hbt->timer(hbt->arg); if (delay_secs != 0) symbol__annotate_decay_histogram(sym, evidx); @@ -740,7 +739,7 @@ show_help: goto show_sup_ins; goto out; } else if (!(annotate_browser__jump(browser) || - annotate_browser__callq(browser, evidx, timer, arg, delay_secs))) { + annotate_browser__callq(browser, evidx, hbt))) { show_sup_ins: ui_helpline__puts("Actions are only available for 'callq', 'retq' & jump instructions."); } @@ -763,10 +762,9 @@ out: } int hist_entry__tui_annotate(struct hist_entry *he, int evidx, - void(*timer)(void *arg), void *arg, int delay_secs) + struct hist_browser_timer *hbt) { - return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx, - timer, arg, delay_secs); + return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx, hbt); } static void annotate_browser__mark_jump_targets(struct annotate_browser *browser, @@ -816,8 +814,7 @@ static inline int width_jumps(int n) } int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, - void(*timer)(void *arg), void *arg, - int delay_secs) + struct hist_browser_timer *hbt) { struct disasm_line *pos, *n; struct annotation *notes; @@ -899,7 +896,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, annotate_browser__update_addr_width(&browser); - ret = annotate_browser__run(&browser, evidx, timer, arg, delay_secs); + ret = annotate_browser__run(&browser, evidx, hbt); list_for_each_entry_safe(pos, n, ¬es->src->source, node) { list_del(&pos->node); disasm_line__free(pos); diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 082078ae9a6..c7d32edb805 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -310,10 +310,11 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser) } static int hist_browser__run(struct hist_browser *browser, const char *ev_name, - void(*timer)(void *arg), void *arg, int delay_secs) + struct hist_browser_timer *hbt) { int key; char title[160]; + int delay_secs = hbt ? hbt->refresh : 0; browser->b.entries = &browser->hists->entries; browser->b.nr_entries = browser->hists->nr_entries; @@ -330,7 +331,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, switch (key) { case K_TIMER: - timer(arg); + hbt->timer(hbt->arg); ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries); if (browser->hists->stats.nr_lost_warned != @@ -1136,8 +1137,7 @@ static inline bool is_report_browser(void *timer) static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, const char *helpline, const char *ev_name, bool left_exits, - void(*timer)(void *arg), void *arg, - int delay_secs) + struct hist_browser_timer *hbt) { struct hists *hists = &evsel->hists; struct hist_browser *browser = hist_browser__new(hists); @@ -1148,6 +1148,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, int key = -1; char buf[64]; char script_opt[64]; + int delay_secs = hbt ? hbt->refresh : 0; if (browser == NULL) return -1; @@ -1170,7 +1171,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, nr_options = 0; - key = hist_browser__run(browser, ev_name, timer, arg, delay_secs); + key = hist_browser__run(browser, ev_name, hbt); if (browser->he_selection != NULL) { thread = hist_browser__selected_thread(browser); @@ -1220,7 +1221,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, } continue; case 'r': - if (is_report_browser(timer)) + if (is_report_browser(hbt)) goto do_scripts; continue; case K_F1: @@ -1388,8 +1389,7 @@ do_annotate: * Don't let this be freed, say, by hists__decay_entry. */ he->used = true; - err = hist_entry__tui_annotate(he, evsel->idx, - timer, arg, delay_secs); + err = hist_entry__tui_annotate(he, evsel->idx, hbt); he->used = false; /* * offer option to annotate the other branch source or target @@ -1512,11 +1512,12 @@ static void perf_evsel_menu__write(struct ui_browser *browser, static int perf_evsel_menu__run(struct perf_evsel_menu *menu, int nr_events, const char *help, - void(*timer)(void *arg), void *arg, int delay_secs) + struct hist_browser_timer *hbt) { struct perf_evlist *evlist = menu->b.priv; struct perf_evsel *pos; const char *ev_name, *title = "Available samples"; + int delay_secs = hbt ? hbt->refresh : 0; int key; if (ui_browser__show(&menu->b, title, @@ -1528,7 +1529,7 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, switch (key) { case K_TIMER: - timer(arg); + hbt->timer(hbt->arg); if (!menu->lost_events_warned && menu->lost_events) { ui_browser__warn_lost_events(&menu->b); @@ -1546,12 +1547,11 @@ browse_hists: * Give the calling tool a chance to populate the non * default evsel resorted hists tree. */ - if (timer) - timer(arg); + if (hbt) + hbt->timer(hbt->arg); ev_name = perf_evsel__name(pos); key = perf_evsel__hists_browse(pos, nr_events, help, - ev_name, true, timer, - arg, delay_secs); + ev_name, true, hbt); ui_browser__show_title(&menu->b, title); switch (key) { case K_TAB: @@ -1599,8 +1599,7 @@ out: static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, - void(*timer)(void *arg), void *arg, - int delay_secs) + struct hist_browser_timer *hbt) { struct perf_evsel *pos; struct perf_evsel_menu menu = { @@ -1624,23 +1623,19 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, menu.b.width = line_len; } - return perf_evsel_menu__run(&menu, evlist->nr_entries, help, timer, - arg, delay_secs); + return perf_evsel_menu__run(&menu, evlist->nr_entries, help, hbt); } int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, - void(*timer)(void *arg), void *arg, - int delay_secs) + struct hist_browser_timer *hbt) { if (evlist->nr_entries == 1) { struct perf_evsel *first = list_entry(evlist->entries.next, struct perf_evsel, node); const char *ev_name = perf_evsel__name(first); return perf_evsel__hists_browse(first, evlist->nr_entries, help, - ev_name, false, timer, arg, - delay_secs); + ev_name, false, hbt); } - return __perf_evlist__tui_browse_hists(evlist, help, - timer, arg, delay_secs); + return __perf_evlist__tui_browse_hists(evlist, help, hbt); } diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c index 4125c628411..253b6219a39 100644 --- a/tools/perf/ui/gtk/browser.c +++ b/tools/perf/ui/gtk/browser.c @@ -237,9 +237,7 @@ static GtkWidget *perf_gtk__setup_statusbar(void) int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help, - void (*timer) (void *arg)__maybe_unused, - void *arg __maybe_unused, - int delay_secs __maybe_unused) + struct hist_browser_timer *hbt __maybe_unused) { struct perf_evsel *pos; GtkWidget *vbox; diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index a4dd25a61a0..c6272011625 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -5,6 +5,7 @@ #include #include "types.h" #include "symbol.h" +#include "hist.h" #include #include #include @@ -140,14 +141,13 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx, #ifdef NEWT_SUPPORT int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, - void(*timer)(void *arg), void *arg, int delay_secs); + struct hist_browser_timer *hbt); #else static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused, struct map *map __maybe_unused, int evidx __maybe_unused, - void(*timer)(void *arg) __maybe_unused, - void *arg __maybe_unused, - int delay_secs __maybe_unused) + struct hist_browser_timer *hbt + __maybe_unused) { return 0; } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index b8746097173..96664cce7c7 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -157,22 +157,25 @@ int hist_entry__period_snprintf(struct perf_hpp *hpp, struct hist_entry *he, struct perf_evlist; +struct hist_browser_timer { + void (*timer)(void *arg); + void *arg; + int refresh; +}; + #ifdef NEWT_SUPPORT #include "../ui/keysyms.h" int hist_entry__tui_annotate(struct hist_entry *he, int evidx, - void(*timer)(void *arg), void *arg, int delay_secs); + struct hist_browser_timer *hbt); int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, - void(*timer)(void *arg), void *arg, - int refresh); + struct hist_browser_timer *hbt); int script_browse(const char *script_opt); #else static inline int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, const char *help __maybe_unused, - void(*timer)(void *arg) __maybe_unused, - void *arg __maybe_unused, - int refresh __maybe_unused) + struct hist_browser_timer *hbt __maybe_unused) { return 0; } @@ -180,10 +183,8 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, static inline int hist_entry__tui_annotate(struct hist_entry *self __maybe_unused, int evidx __maybe_unused, - void(*timer)(void *arg) - __maybe_unused, - void *arg __maybe_unused, - int delay_secs __maybe_unused) + struct hist_browser_timer *hbt + __maybe_unused) { return 0; } @@ -199,15 +200,12 @@ static inline int script_browse(const char *script_opt) #ifdef GTK2_SUPPORT int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help, - void(*timer)(void *arg), void *arg, - int refresh); + struct hist_browser_timer *hbt __maybe_unused); #else static inline int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused, const char *help __maybe_unused, - void(*timer)(void *arg) __maybe_unused, - void *arg __maybe_unused, - int refresh __maybe_unused) + struct hist_browser_timer *hbt __maybe_unused) { return 0; } -- cgit v1.2.3 From 68d807586ba83d9cb77f12c8fb7c97ea438d34ad Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 2 Nov 2012 14:50:06 +0900 Subject: perf report: Postpone objdump check until annotation requested David reported that current perf report refused to run on a data file captured from a different machine because of objdump. Since the objdump tools won't be used unless annotation was requested, checking its presence at init time doesn't make sense. Reported-by: David Ahern Signed-off-by: Namhyung Kim Reviewed-by: David Ahern Tested-by: David Ahern Cc: Ingo Molnar Cc: Irina Tirdea Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1351835406-15208-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 9 ++------- tools/perf/builtin-top.c | 3 ++- tools/perf/ui/browsers/hists.c | 22 ++++++++++++++++------ tools/perf/util/hist.h | 7 +++++-- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 234f34d466e..fc251005dd3 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -428,7 +428,8 @@ static int __cmd_report(struct perf_report *rep) if (use_browser > 0) { if (use_browser == 1) { perf_evlist__tui_browse_hists(session->evlist, help, - NULL); + NULL, + &session->header.env); } else if (use_browser == 2) { perf_evlist__gtk_browse_hists(session->evlist, help, NULL); @@ -672,12 +673,6 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) has_br_stack = perf_header__has_feat(&session->header, HEADER_BRANCH_STACK); - if (!objdump_path) { - ret = perf_session_env__lookup_objdump(&session->header.env); - if (ret) - goto error; - } - if (sort__branch_mode == -1 && has_br_stack) sort__branch_mode = 1; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 102b43c9905..c9ff3950cd4 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -598,7 +598,8 @@ static void *display_thread_tui(void *arg) list_for_each_entry(pos, &top->evlist->entries, node) pos->hists.uid_filter_str = top->target.uid_str; - perf_evlist__tui_browse_hists(top->evlist, help, &hbt); + perf_evlist__tui_browse_hists(top->evlist, help, &hbt, + &top->session->header.env); exit_browser(0); exit(0); diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index c7d32edb805..ccc4bd16142 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -11,6 +11,7 @@ #include "../../util/pstack.h" #include "../../util/sort.h" #include "../../util/util.h" +#include "../../arch/common.h" #include "../browser.h" #include "../helpline.h" @@ -1137,7 +1138,8 @@ static inline bool is_report_browser(void *timer) static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, const char *helpline, const char *ev_name, bool left_exits, - struct hist_browser_timer *hbt) + struct hist_browser_timer *hbt, + struct perf_session_env *env) { struct hists *hists = &evsel->hists; struct hist_browser *browser = hist_browser__new(hists); @@ -1367,6 +1369,9 @@ retry_popup_menu: struct hist_entry *he; int err; do_annotate: + if (!objdump_path && perf_session_env__lookup_objdump(env)) + continue; + he = hist_browser__selected_entry(browser); if (he == NULL) continue; @@ -1470,6 +1475,7 @@ struct perf_evsel_menu { struct ui_browser b; struct perf_evsel *selection; bool lost_events, lost_events_warned; + struct perf_session_env *env; }; static void perf_evsel_menu__write(struct ui_browser *browser, @@ -1551,7 +1557,8 @@ browse_hists: hbt->timer(hbt->arg); ev_name = perf_evsel__name(pos); key = perf_evsel__hists_browse(pos, nr_events, help, - ev_name, true, hbt); + ev_name, true, hbt, + menu->env); ui_browser__show_title(&menu->b, title); switch (key) { case K_TAB: @@ -1599,7 +1606,8 @@ out: static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, - struct hist_browser_timer *hbt) + struct hist_browser_timer *hbt, + struct perf_session_env *env) { struct perf_evsel *pos; struct perf_evsel_menu menu = { @@ -1611,6 +1619,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, .nr_entries = evlist->nr_entries, .priv = evlist, }, + .env = env, }; ui_helpline__push("Press ESC to exit"); @@ -1627,15 +1636,16 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, } int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, - struct hist_browser_timer *hbt) + struct hist_browser_timer *hbt, + struct perf_session_env *env) { if (evlist->nr_entries == 1) { struct perf_evsel *first = list_entry(evlist->entries.next, struct perf_evsel, node); const char *ev_name = perf_evsel__name(first); return perf_evsel__hists_browse(first, evlist->nr_entries, help, - ev_name, false, hbt); + ev_name, false, hbt, env); } - return __perf_evlist__tui_browse_hists(evlist, help, hbt); + return __perf_evlist__tui_browse_hists(evlist, help, hbt, env); } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 96664cce7c7..a4f45dd0469 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -4,6 +4,7 @@ #include #include #include "callchain.h" +#include "header.h" extern struct callchain_param callchain_param; @@ -169,13 +170,15 @@ int hist_entry__tui_annotate(struct hist_entry *he, int evidx, struct hist_browser_timer *hbt); int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, - struct hist_browser_timer *hbt); + struct hist_browser_timer *hbt, + struct perf_session_env *env); int script_browse(const char *script_opt); #else static inline int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, const char *help __maybe_unused, - struct hist_browser_timer *hbt __maybe_unused) + struct hist_browser_timer *hbt __maybe_unused, + struct perf_session_env *env __maybe_unused) { return 0; } -- cgit v1.2.3 From df4c6de857774252702acc20d4b0eddb329d8808 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 5 Nov 2012 16:49:36 +0100 Subject: perf tests: Add missing attr stat basic test Adding test to validate perf_event_attr data for command: 'stat -e cycles' Reported-by: Namhyung Kim Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352130579-13451-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr/base-stat | 40 +++++++++++++++++++++++++++++++++++ tools/perf/tests/attr/test-stat-basic | 6 ++++++ 2 files changed, 46 insertions(+) create mode 100644 tools/perf/tests/attr/base-stat create mode 100644 tools/perf/tests/attr/test-stat-basic diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat new file mode 100644 index 00000000000..6e1bb8e4e60 --- /dev/null +++ b/tools/perf/tests/attr/base-stat @@ -0,0 +1,40 @@ +[event] +fd=1 +group_fd=-1 +flags=0 +type=0 +size=96 +config=0 +sample_period=0 +sample_type=0 +read_format=3 +disabled=1 +inherit=1 +pinned=0 +exclusive=0 +exclude_user=0 +exclude_kernel=0 +exclude_hv=0 +exclude_idle=0 +mmap=0 +comm=0 +freq=0 +inherit_stat=0 +enable_on_exec=1 +task=0 +watermask=0 +precise_ip=0 +mmap_data=0 +sample_id_all=0 +exclude_host=0 +exclude_guest=1 +exclude_callchain_kernel=0 +exclude_callchain_user=0 +wakeup_events=0 +bp_type=0 +config1=0 +config2=0 +branch_sample_type=0 +sample_regs_user=0 +sample_stack_user=0 +optional=0 diff --git a/tools/perf/tests/attr/test-stat-basic b/tools/perf/tests/attr/test-stat-basic new file mode 100644 index 00000000000..74e17881f2b --- /dev/null +++ b/tools/perf/tests/attr/test-stat-basic @@ -0,0 +1,6 @@ +[config] +command = stat +args = -e cycles kill >/dev/null 2>&1 +ret = 1 + +[event:base-stat] -- cgit v1.2.3 From 89f552d684925ef9f1dca8b4b2b18fb981dc3d8c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 5 Nov 2012 16:49:37 +0100 Subject: perf tests: Factor attr tests WRITE_ASS macro Changing WRITE_ASS macro per Namhyung's comments, so the main usage case takes only attr field name and format string. Suggested-by: Namhyung Kim Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352130579-13451-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr.c | 89 +++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index aacad82634c..1389d69d5fd 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -44,7 +44,7 @@ void test_attr__init(void) #define BUFSIZE 1024 -#define WRITE_ASS(str, fmt, data) \ +#define __WRITE_ASS(str, fmt, data) \ do { \ char buf[BUFSIZE]; \ size_t size; \ @@ -58,6 +58,8 @@ do { \ \ } while (0) +#define WRITE_ASS(field, fmt) __WRITE_ASS(field, fmt, attr->field) + static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu, int fd, int group_fd, unsigned long flags) { @@ -81,51 +83,50 @@ static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu, } /* syscall arguments */ - WRITE_ASS(fd, "d", fd); - WRITE_ASS(group_fd, "d", group_fd); - WRITE_ASS(cpu, "d", cpu); - WRITE_ASS(pid, "d", pid); - WRITE_ASS(flags, "lu", flags); + __WRITE_ASS(fd, "d", fd); + __WRITE_ASS(group_fd, "d", group_fd); + __WRITE_ASS(cpu, "d", cpu); + __WRITE_ASS(pid, "d", pid); + __WRITE_ASS(flags, "lu", flags); /* struct perf_event_attr */ - WRITE_ASS(type, PRIu32, attr->type); - WRITE_ASS(size, PRIu32, attr->size); - WRITE_ASS(config, "llu", attr->config); - WRITE_ASS(sample_period, "llu", attr->sample_period); - WRITE_ASS(sample_type, "llu", attr->sample_type); - WRITE_ASS(read_format, "llu", attr->read_format); - WRITE_ASS(disabled, "d", attr->disabled); - WRITE_ASS(inherit, "d", attr->inherit); - WRITE_ASS(pinned, "d", attr->pinned); - WRITE_ASS(exclusive, "d", attr->exclusive); - WRITE_ASS(exclude_user, "d", attr->exclude_user); - WRITE_ASS(exclude_kernel, "d", attr->exclude_kernel); - WRITE_ASS(exclude_hv, "d", attr->exclude_hv); - WRITE_ASS(exclude_idle, "d", attr->exclude_idle); - WRITE_ASS(mmap, "d", attr->mmap); - WRITE_ASS(comm, "d", attr->comm); - WRITE_ASS(freq, "d", attr->freq); - WRITE_ASS(inherit_stat, "d", attr->inherit_stat); - WRITE_ASS(enable_on_exec, "d", attr->enable_on_exec); - WRITE_ASS(task, "d", attr->task); - WRITE_ASS(watermask, "d", attr->watermark); - WRITE_ASS(precise_ip, "d", attr->precise_ip); - WRITE_ASS(mmap_data, "d", attr->mmap_data); - WRITE_ASS(sample_id_all, "d", attr->sample_id_all); - WRITE_ASS(exclude_host, "d", attr->exclude_host); - WRITE_ASS(exclude_guest, "d", attr->exclude_guest); - WRITE_ASS(exclude_callchain_kernel, "d", - attr->exclude_callchain_kernel); - WRITE_ASS(exclude_callchain_user, "d", - attr->exclude_callchain_user); - WRITE_ASS(wakeup_events, PRIu32, attr->wakeup_events); - WRITE_ASS(bp_type, PRIu32, attr->bp_type); - WRITE_ASS(config1, "llu", attr->config1); - WRITE_ASS(config2, "llu", attr->config2); - WRITE_ASS(branch_sample_type, "llu", attr->branch_sample_type); - WRITE_ASS(sample_regs_user, "llu", attr->sample_regs_user); - WRITE_ASS(sample_stack_user, PRIu32, attr->sample_stack_user); - WRITE_ASS(optional, "d", 0); + WRITE_ASS(type, PRIu32); + WRITE_ASS(size, PRIu32); + WRITE_ASS(config, "llu"); + WRITE_ASS(sample_period, "llu"); + WRITE_ASS(sample_type, "llu"); + WRITE_ASS(read_format, "llu"); + WRITE_ASS(disabled, "d"); + WRITE_ASS(inherit, "d"); + WRITE_ASS(pinned, "d"); + WRITE_ASS(exclusive, "d"); + WRITE_ASS(exclude_user, "d"); + WRITE_ASS(exclude_kernel, "d"); + WRITE_ASS(exclude_hv, "d"); + WRITE_ASS(exclude_idle, "d"); + WRITE_ASS(mmap, "d"); + WRITE_ASS(comm, "d"); + WRITE_ASS(freq, "d"); + WRITE_ASS(inherit_stat, "d"); + WRITE_ASS(enable_on_exec, "d"); + WRITE_ASS(task, "d"); + WRITE_ASS(watermask, "d"); + WRITE_ASS(precise_ip, "d"); + WRITE_ASS(mmap_data, "d"); + WRITE_ASS(sample_id_all, "d"); + WRITE_ASS(exclude_host, "d"); + WRITE_ASS(exclude_guest, "d"); + WRITE_ASS(exclude_callchain_kernel, "d"); + WRITE_ASS(exclude_callchain_user, "d"); + WRITE_ASS(wakeup_events, PRIu32); + WRITE_ASS(bp_type, PRIu32); + WRITE_ASS(config1, "llu"); + WRITE_ASS(config2, "llu"); + WRITE_ASS(branch_sample_type, "llu"); + WRITE_ASS(sample_regs_user, "llu"); + WRITE_ASS(sample_stack_user, PRIu32); + + __WRITE_ASS(optional, "d", 0); fclose(file); return 0; -- cgit v1.2.3 From 45e4089bc6398da2cf0609b614bc519970cb8442 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 5 Nov 2012 16:49:38 +0100 Subject: perf tests: Fix attr watermark field name typo Currently the 'watermark' field is coded as 'watermask'. As the type is global through the framework and tests, the typo spawned no error. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352130579-13451-4-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr.c | 2 +- tools/perf/tests/attr.py | 2 +- tools/perf/tests/attr/base-record | 2 +- tools/perf/tests/attr/base-stat | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index 1389d69d5fd..6fa84b7065c 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -110,7 +110,7 @@ static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu, WRITE_ASS(inherit_stat, "d"); WRITE_ASS(enable_on_exec, "d"); WRITE_ASS(task, "d"); - WRITE_ASS(watermask, "d"); + WRITE_ASS(watermark, "d"); WRITE_ASS(precise_ip, "d"); WRITE_ASS(mmap_data, "d"); WRITE_ASS(sample_id_all, "d"); diff --git a/tools/perf/tests/attr.py b/tools/perf/tests/attr.py index e98c726ac81..28c0481bc98 100644 --- a/tools/perf/tests/attr.py +++ b/tools/perf/tests/attr.py @@ -45,7 +45,7 @@ class Event(dict): 'inherit_stat', 'enable_on_exec', 'task', - 'watermask', + 'watermark', 'precise_ip', 'mmap_data', 'sample_id_all', diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record index 07beef57855..8262794734e 100644 --- a/tools/perf/tests/attr/base-record +++ b/tools/perf/tests/attr/base-record @@ -22,7 +22,7 @@ freq=1 inherit_stat=0 enable_on_exec=1 task=0 -watermask=0 +watermark=0 precise_ip=0 mmap_data=0 sample_id_all=1 diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat index 6e1bb8e4e60..46f8851eaf4 100644 --- a/tools/perf/tests/attr/base-stat +++ b/tools/perf/tests/attr/base-stat @@ -22,7 +22,7 @@ freq=0 inherit_stat=0 enable_on_exec=1 task=0 -watermask=0 +watermark=0 precise_ip=0 mmap_data=0 sample_id_all=0 -- cgit v1.2.3 From 8dfec403e39b7c37fd6e8813bacc01da1e1210ab Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 5 Nov 2012 16:49:39 +0100 Subject: perf tests: Removing 'optional' field Since we allow multiple values in event field assignment, there's no need for 'optional' field.. old version removal leftover. Adding some comments into attr.py script regarding the test event load. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352130579-13451-5-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr.c | 2 -- tools/perf/tests/attr.py | 29 ++++++++++++++++++----------- tools/perf/tests/attr/base-record | 1 - tools/perf/tests/attr/base-stat | 1 - 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index 6fa84b7065c..6e2feee8db2 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -126,8 +126,6 @@ static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu, WRITE_ASS(sample_regs_user, "llu"); WRITE_ASS(sample_stack_user, PRIu32); - __WRITE_ASS(optional, "d", 0); - fclose(file); return 0; } diff --git a/tools/perf/tests/attr.py b/tools/perf/tests/attr.py index 28c0481bc98..9b25b33cf3e 100644 --- a/tools/perf/tests/attr.py +++ b/tools/perf/tests/attr.py @@ -75,6 +75,7 @@ class Event(dict): self.add(data) def compare_data(self, a, b): + # Allow multiple values in assignment separated by '|' a_list = a.split('|') b_list = b.split('|') @@ -96,12 +97,17 @@ class Event(dict): return False return True - def is_optional(self): - if self['optional'] == '1': - return True - else: - return False - +# Test file description needs to have following sections: +# [config] +# - just single instance in file +# - needs to specify: +# 'command' - perf command name +# 'args' - special command arguments +# 'ret' - expected command return value (0 by default) +# +# [eventX:base] +# - one or multiple instances in file +# - expected values assignments class Test(object): def __init__(self, path, options): parser = ConfigParser.SafeConfigParser() @@ -135,11 +141,15 @@ class Test(object): parser_event = ConfigParser.SafeConfigParser() parser_event.read(path) + # The event record section header contains 'event' word, + # optionaly followed by ':' allowing to load 'parent + # event' first as a base for section in filter(self.is_event, parser_event.sections()): parser_items = parser_event.items(section); base_items = {} + # Read parent event if there's any if (':' in section): base = section[section.index(':') + 1:] parser_base = ConfigParser.SafeConfigParser() @@ -177,11 +187,10 @@ class Test(object): else: log.debug(" ->FAIL"); - log.info(" match: [%s] optional(%d) matches %s" % - (exp_name, exp_event.is_optional(), str(exp_list))) + log.info(" match: [%s] matches %s" % (exp_name, str(exp_list))) # we did not any matching event - fail - if (not exp_list) and (not exp_event.is_optional()): + if (not exp_list): raise Fail(self, 'match failure'); match[exp_name] = exp_list @@ -194,8 +203,6 @@ class Test(object): if (group == ''): continue - # XXX group matching does not account for - # optional events as above matching does for res_name in match[exp_name]: res_group = result[res_name].group if res_group not in match[group]: diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record index 8262794734e..f1485d8e6a0 100644 --- a/tools/perf/tests/attr/base-record +++ b/tools/perf/tests/attr/base-record @@ -37,4 +37,3 @@ config2=0 branch_sample_type=0 sample_regs_user=0 sample_stack_user=0 -optional=0 diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat index 46f8851eaf4..4bd79a82784 100644 --- a/tools/perf/tests/attr/base-stat +++ b/tools/perf/tests/attr/base-stat @@ -37,4 +37,3 @@ config2=0 branch_sample_type=0 sample_regs_user=0 sample_stack_user=0 -optional=0 -- cgit v1.2.3 From bd6880477a3d73270edead88f4b806504998e5d8 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 5 Nov 2012 09:56:00 +0000 Subject: staging:iio:ad7887: Preallocate sample buffer We know that the sample buffer will at most need to hold two 16 bit samples and the 64 bit aligned 64 bit timestamp. Preallocate a buffer large enough to hold this instead of allocating and freeing it each time a sample is read. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7887.h | 6 ++++-- drivers/staging/iio/adc/ad7887_ring.c | 15 ++------------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h index 2e09e54fc9c..71e50925e06 100644 --- a/drivers/staging/iio/adc/ad7887.h +++ b/drivers/staging/iio/adc/ad7887.h @@ -72,9 +72,11 @@ struct ad7887_state { /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. + * Buffer needs to be large enough to hold two 16 bit samples and a + * 64 bit aligned 64 bit timestamp. */ - - unsigned char data[4] ____cacheline_aligned; + unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)] + ____cacheline_aligned; }; enum ad7887_supported_device_ids { diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index b39923bbeed..f11925e62cd 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -73,31 +73,20 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct ad7887_state *st = iio_priv(indio_dev); s64 time_ns; - __u8 *buf; int b_sent; - unsigned int bytes = bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength) * - st->chip_info->channel[0].scan_type.storagebits / 8; - - buf = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (buf == NULL) - goto done; - b_sent = spi_sync(st->spi, st->ring_msg); if (b_sent) goto done; time_ns = iio_get_time_ns(); - memcpy(buf, st->data, bytes); if (indio_dev->scan_timestamp) - memcpy(buf + indio_dev->scan_bytes - sizeof(s64), + memcpy(st->data + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); - iio_push_to_buffer(indio_dev->buffer, buf); + iio_push_to_buffer(indio_dev->buffer, st->data); done: - kfree(buf); iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; -- cgit v1.2.3 From bf5d2613c9083b8d4f4e98f5b25553fc938b50c6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 5 Nov 2012 09:56:00 +0000 Subject: staging:iio:ad7887: Rework regulator handling Rework the regulator handling of the ad7887 driver to match more closely what we do for other drivers. Only request the regulator if a external reference is used, but treat it as an error if requesting the regulator fails. Also remove the possibility to specify the reference voltage via platform data and always use the regulator for this. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7887.h | 3 -- drivers/staging/iio/adc/ad7887_core.c | 52 ++++++++++++++++------------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h index 71e50925e06..25d5b4008b2 100644 --- a/drivers/staging/iio/adc/ad7887.h +++ b/drivers/staging/iio/adc/ad7887.h @@ -30,8 +30,6 @@ enum ad7887_channels { */ struct ad7887_platform_data { - /* External Vref voltage applied */ - u16 vref_mv; /* * AD7887: * In single channel mode en_dual = flase, AIN1/Vref pins assumes its @@ -63,7 +61,6 @@ struct ad7887_state { struct spi_device *spi; const struct ad7887_chip_info *chip_info; struct regulator *reg; - u16 int_vref_mv; struct spi_transfer xfer[4]; struct spi_message msg[3]; struct spi_message *ring_msg; diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c index 551790584a1..cf33ba63c6c 100644 --- a/drivers/staging/iio/adc/ad7887_core.c +++ b/drivers/staging/iio/adc/ad7887_core.c @@ -39,7 +39,6 @@ static int ad7887_read_raw(struct iio_dev *indio_dev, { int ret; struct ad7887_state *st = iio_priv(indio_dev); - unsigned int scale_uv; switch (m) { case IIO_CHAN_INFO_RAW: @@ -56,11 +55,18 @@ static int ad7887_read_raw(struct iio_dev *indio_dev, RES_MASK(st->chip_info->channel[0].scan_type.realbits); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - scale_uv = (st->int_vref_mv * 1000) - >> st->chip_info->channel[0].scan_type.realbits; - *val = scale_uv/1000; - *val2 = (scale_uv%1000)*1000; - return IIO_VAL_INT_PLUS_MICRO; + if (st->reg) { + *val = regulator_get_voltage(st->reg); + if (*val < 0) + return *val; + *val /= 1000; + } else { + *val = st->chip_info->int_vref_mv; + } + + *val2 = st->chip_info->channel[0].scan_type.realbits; + + return IIO_VAL_FRACTIONAL_LOG2; } return -EINVAL; } @@ -105,21 +111,24 @@ static int __devinit ad7887_probe(struct spi_device *spi) { struct ad7887_platform_data *pdata = spi->dev.platform_data; struct ad7887_state *st; - int ret, voltage_uv = 0; struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); + int ret; if (indio_dev == NULL) return -ENOMEM; st = iio_priv(indio_dev); - st->reg = regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(st->reg)) { + if (!pdata || !pdata->use_onchip_ref) { + st->reg = regulator_get(&spi->dev, "vref"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto error_free; + } + ret = regulator_enable(st->reg); if (ret) goto error_put_reg; - - voltage_uv = regulator_get_voltage(st->reg); } st->chip_info = @@ -176,23 +185,9 @@ static int __devinit ad7887_probe(struct spi_device *spi) spi_message_init(&st->msg[AD7887_CH1]); spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]); - if (pdata && pdata->vref_mv) - st->int_vref_mv = pdata->vref_mv; - else if (voltage_uv) - st->int_vref_mv = voltage_uv / 1000; - else - dev_warn(&spi->dev, "reference voltage unspecified\n"); - indio_dev->channels = st->chip_info->channel; indio_dev->num_channels = 3; } else { - if (pdata && pdata->vref_mv) - st->int_vref_mv = pdata->vref_mv; - else if (pdata && pdata->use_onchip_ref) - st->int_vref_mv = st->chip_info->int_vref_mv; - else - dev_warn(&spi->dev, "reference voltage unspecified\n"); - indio_dev->channels = &st->chip_info->channel[1]; indio_dev->num_channels = 2; } @@ -209,11 +204,12 @@ static int __devinit ad7887_probe(struct spi_device *spi) error_unregister_ring: ad7887_ring_cleanup(indio_dev); error_disable_reg: - if (!IS_ERR(st->reg)) + if (st->reg) regulator_disable(st->reg); error_put_reg: - if (!IS_ERR(st->reg)) + if (st->reg) regulator_put(st->reg); +error_free: iio_device_free(indio_dev); return ret; @@ -226,7 +222,7 @@ static int __devexit ad7887_remove(struct spi_device *spi) iio_device_unregister(indio_dev); ad7887_ring_cleanup(indio_dev); - if (!IS_ERR(st->reg)) { + if (st->reg) { regulator_disable(st->reg); regulator_put(st->reg); } -- cgit v1.2.3 From 65dd3d3d7a9bca683599b214229c546392394622 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 5 Nov 2012 09:56:00 +0000 Subject: staging:iio:ad7887: Squash everything into one file The recent cleanups have decimated the drivers code size by quite a bit. It is only a few hundred lines in total now and we also always build buffer support, so there really is no need to spread the driver out over multiple files. Putting everything into one file also allows to reduce the code size a bit more by removing a few lines of boilerplate code. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/Makefile | 2 - drivers/staging/iio/adc/ad7887.c | 380 ++++++++++++++++++++++++++++++++++ drivers/staging/iio/adc/ad7887.h | 66 ------ drivers/staging/iio/adc/ad7887_core.c | 253 ---------------------- drivers/staging/iio/adc/ad7887_ring.c | 111 ---------- 5 files changed, 380 insertions(+), 432 deletions(-) create mode 100644 drivers/staging/iio/adc/ad7887.c delete mode 100644 drivers/staging/iio/adc/ad7887_core.c delete mode 100644 drivers/staging/iio/adc/ad7887_ring.c diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index ff561c591d6..8036fd14f68 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -17,8 +17,6 @@ ad799x-y := ad799x_core.o ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o obj-$(CONFIG_AD799X) += ad799x.o -ad7887-y := ad7887_core.o -ad7887-$(CONFIG_IIO_BUFFER) += ad7887_ring.o obj-$(CONFIG_AD7887) += ad7887.o ad7298-y := ad7298_core.o diff --git a/drivers/staging/iio/adc/ad7887.c b/drivers/staging/iio/adc/ad7887.c new file mode 100644 index 00000000000..88ffc4620fc --- /dev/null +++ b/drivers/staging/iio/adc/ad7887.c @@ -0,0 +1,380 @@ +/* + * AD7887 SPI ADC driver + * + * Copyright 2010-2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "ad7887.h" + +#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */ +#define AD7887_DUAL (1 << 4) /* dual-channel mode */ +#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */ +#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */ +#define AD7887_PM_MODE1 (0) /* CS based shutdown */ +#define AD7887_PM_MODE2 (1) /* full on */ +#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */ +#define AD7887_PM_MODE4 (3) /* standby mode */ + +enum ad7887_channels { + AD7887_CH0, + AD7887_CH0_CH1, + AD7887_CH1, +}; + +#define RES_MASK(bits) ((1 << (bits)) - 1) + +/** + * struct ad7887_chip_info - chip specifc information + * @int_vref_mv: the internal reference voltage + * @channel: channel specification + */ +struct ad7887_chip_info { + u16 int_vref_mv; + struct iio_chan_spec channel[3]; +}; + +struct ad7887_state { + struct spi_device *spi; + const struct ad7887_chip_info *chip_info; + struct regulator *reg; + struct spi_transfer xfer[4]; + struct spi_message msg[3]; + struct spi_message *ring_msg; + unsigned char tx_cmd_buf[8]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + * Buffer needs to be large enough to hold two 16 bit samples and a + * 64 bit aligned 64 bit timestamp. + */ + unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)] + ____cacheline_aligned; +}; + +enum ad7887_supported_device_ids { + ID_AD7887 +}; + +static int ad7887_ring_preenable(struct iio_dev *indio_dev) +{ + struct ad7887_state *st = iio_priv(indio_dev); + int ret; + + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; + + /* We know this is a single long so can 'cheat' */ + switch (*indio_dev->active_scan_mask) { + case (1 << 0): + st->ring_msg = &st->msg[AD7887_CH0]; + break; + case (1 << 1): + st->ring_msg = &st->msg[AD7887_CH1]; + /* Dummy read: push CH1 setting down to hardware */ + spi_sync(st->spi, st->ring_msg); + break; + case ((1 << 1) | (1 << 0)): + st->ring_msg = &st->msg[AD7887_CH0_CH1]; + break; + } + + return 0; +} + +static int ad7887_ring_postdisable(struct iio_dev *indio_dev) +{ + struct ad7887_state *st = iio_priv(indio_dev); + + /* dummy read: restore default CH0 settin */ + return spi_sync(st->spi, &st->msg[AD7887_CH0]); +} + +/** + * ad7887_trigger_handler() bh of trigger launched polling to ring buffer + * + * Currently there is no option in this driver to disable the saving of + * timestamps within the ring. + **/ +static irqreturn_t ad7887_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad7887_state *st = iio_priv(indio_dev); + s64 time_ns; + int b_sent; + + b_sent = spi_sync(st->spi, st->ring_msg); + if (b_sent) + goto done; + + time_ns = iio_get_time_ns(); + + if (indio_dev->scan_timestamp) + memcpy(st->data + indio_dev->scan_bytes - sizeof(s64), + &time_ns, sizeof(time_ns)); + + iio_push_to_buffer(indio_dev->buffer, st->data); +done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = { + .preenable = &ad7887_ring_preenable, + .postenable = &iio_triggered_buffer_postenable, + .predisable = &iio_triggered_buffer_predisable, + .postdisable = &ad7887_ring_postdisable, +}; + +static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch) +{ + int ret = spi_sync(st->spi, &st->msg[ch]); + if (ret) + return ret; + + return (st->data[(ch * 2)] << 8) | st->data[(ch * 2) + 1]; +} + +static int ad7887_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + int ret; + struct ad7887_state *st = iio_priv(indio_dev); + + switch (m) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&indio_dev->mlock); + if (iio_buffer_enabled(indio_dev)) + ret = -EBUSY; + else + ret = ad7887_scan_direct(st, chan->address); + mutex_unlock(&indio_dev->mlock); + + if (ret < 0) + return ret; + *val = (ret >> st->chip_info->channel[0].scan_type.shift) & + RES_MASK(st->chip_info->channel[0].scan_type.realbits); + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + if (st->reg) { + *val = regulator_get_voltage(st->reg); + if (*val < 0) + return *val; + *val /= 1000; + } else { + *val = st->chip_info->int_vref_mv; + } + + *val2 = st->chip_info->channel[0].scan_type.realbits; + + return IIO_VAL_FRACTIONAL_LOG2; + } + return -EINVAL; +} + + +static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { + /* + * More devices added in future + */ + [ID_AD7887] = { + .channel[0] = { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = 1, + .scan_index = 1, + .scan_type = IIO_ST('u', 12, 16, 0), + }, + .channel[1] = { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = 0, + .scan_index = 0, + .scan_type = IIO_ST('u', 12, 16, 0), + }, + .channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2), + .int_vref_mv = 2500, + }, +}; + +static const struct iio_info ad7887_info = { + .read_raw = &ad7887_read_raw, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad7887_probe(struct spi_device *spi) +{ + struct ad7887_platform_data *pdata = spi->dev.platform_data; + struct ad7887_state *st; + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); + int ret; + + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + if (!pdata || !pdata->use_onchip_ref) { + st->reg = regulator_get(&spi->dev, "vref"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto error_free; + } + + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + st->chip_info = + &ad7887_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + + spi_set_drvdata(spi, indio_dev); + st->spi = spi; + + /* Estabilish that the iio_dev is a child of the spi device */ + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->info = &ad7887_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + /* Setup default message */ + + st->tx_cmd_buf[0] = AD7887_CH_AIN0 | AD7887_PM_MODE4 | + ((pdata && pdata->use_onchip_ref) ? + 0 : AD7887_REF_DIS); + + st->xfer[0].rx_buf = &st->data[0]; + st->xfer[0].tx_buf = &st->tx_cmd_buf[0]; + st->xfer[0].len = 2; + + spi_message_init(&st->msg[AD7887_CH0]); + spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]); + + if (pdata && pdata->en_dual) { + st->tx_cmd_buf[0] |= AD7887_DUAL | AD7887_REF_DIS; + + st->tx_cmd_buf[2] = AD7887_CH_AIN1 | AD7887_DUAL | + AD7887_REF_DIS | AD7887_PM_MODE4; + st->tx_cmd_buf[4] = AD7887_CH_AIN0 | AD7887_DUAL | + AD7887_REF_DIS | AD7887_PM_MODE4; + st->tx_cmd_buf[6] = AD7887_CH_AIN1 | AD7887_DUAL | + AD7887_REF_DIS | AD7887_PM_MODE4; + + st->xfer[1].rx_buf = &st->data[0]; + st->xfer[1].tx_buf = &st->tx_cmd_buf[2]; + st->xfer[1].len = 2; + + st->xfer[2].rx_buf = &st->data[2]; + st->xfer[2].tx_buf = &st->tx_cmd_buf[4]; + st->xfer[2].len = 2; + + spi_message_init(&st->msg[AD7887_CH0_CH1]); + spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]); + spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]); + + st->xfer[3].rx_buf = &st->data[0]; + st->xfer[3].tx_buf = &st->tx_cmd_buf[6]; + st->xfer[3].len = 2; + + spi_message_init(&st->msg[AD7887_CH1]); + spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]); + + indio_dev->channels = st->chip_info->channel; + indio_dev->num_channels = 3; + } else { + indio_dev->channels = &st->chip_info->channel[1]; + indio_dev->num_channels = 2; + } + + ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + &ad7887_trigger_handler, &ad7887_ring_setup_ops); + if (ret) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_unregister_ring; + + return 0; +error_unregister_ring: + iio_triggered_buffer_cleanup(indio_dev); +error_disable_reg: + if (st->reg) + regulator_disable(st->reg); +error_put_reg: + if (st->reg) + regulator_put(st->reg); +error_free: + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit ad7887_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7887_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + if (st->reg) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad7887_id[] = { + {"ad7887", ID_AD7887}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad7887_id); + +static struct spi_driver ad7887_driver = { + .driver = { + .name = "ad7887", + .owner = THIS_MODULE, + }, + .probe = ad7887_probe, + .remove = __devexit_p(ad7887_remove), + .id_table = ad7887_id, +}; +module_spi_driver(ad7887_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7887 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h index 25d5b4008b2..b9078fc2aa1 100644 --- a/drivers/staging/iio/adc/ad7887.h +++ b/drivers/staging/iio/adc/ad7887.h @@ -8,23 +8,6 @@ #ifndef IIO_ADC_AD7887_H_ #define IIO_ADC_AD7887_H_ -#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */ -#define AD7887_DUAL (1 << 4) /* dual-channel mode */ -#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */ -#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */ -#define AD7887_PM_MODE1 (0) /* CS based shutdown */ -#define AD7887_PM_MODE2 (1) /* full on */ -#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */ -#define AD7887_PM_MODE4 (3) /* standby mode */ - -enum ad7887_channels { - AD7887_CH0, - AD7887_CH0_CH1, - AD7887_CH1, -}; - -#define RES_MASK(bits) ((1 << (bits)) - 1) /* TODO: move this into a common header */ - /* * TODO: struct ad7887_platform_data needs to go into include/linux/iio */ @@ -46,53 +29,4 @@ struct ad7887_platform_data { bool use_onchip_ref; }; -/** - * struct ad7887_chip_info - chip specifc information - * @int_vref_mv: the internal reference voltage - * @channel: channel specification - */ - -struct ad7887_chip_info { - u16 int_vref_mv; - struct iio_chan_spec channel[3]; -}; - -struct ad7887_state { - struct spi_device *spi; - const struct ad7887_chip_info *chip_info; - struct regulator *reg; - struct spi_transfer xfer[4]; - struct spi_message msg[3]; - struct spi_message *ring_msg; - unsigned char tx_cmd_buf[8]; - - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - * Buffer needs to be large enough to hold two 16 bit samples and a - * 64 bit aligned 64 bit timestamp. - */ - unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)] - ____cacheline_aligned; -}; - -enum ad7887_supported_device_ids { - ID_AD7887 -}; - -#ifdef CONFIG_IIO_BUFFER -int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev); -void ad7887_ring_cleanup(struct iio_dev *indio_dev); -#else /* CONFIG_IIO_BUFFER */ - -static inline int -ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void ad7887_ring_cleanup(struct iio_dev *indio_dev) -{ -} -#endif /* CONFIG_IIO_BUFFER */ #endif /* IIO_ADC_AD7887_H_ */ diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c deleted file mode 100644 index cf33ba63c6c..00000000000 --- a/drivers/staging/iio/adc/ad7887_core.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * AD7887 SPI ADC driver - * - * Copyright 2010-2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -#include "ad7887.h" - -static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch) -{ - int ret = spi_sync(st->spi, &st->msg[ch]); - if (ret) - return ret; - - return (st->data[(ch * 2)] << 8) | st->data[(ch * 2) + 1]; -} - -static int ad7887_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long m) -{ - int ret; - struct ad7887_state *st = iio_priv(indio_dev); - - switch (m) { - case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) - ret = -EBUSY; - else - ret = ad7887_scan_direct(st, chan->address); - mutex_unlock(&indio_dev->mlock); - - if (ret < 0) - return ret; - *val = (ret >> st->chip_info->channel[0].scan_type.shift) & - RES_MASK(st->chip_info->channel[0].scan_type.realbits); - return IIO_VAL_INT; - case IIO_CHAN_INFO_SCALE: - if (st->reg) { - *val = regulator_get_voltage(st->reg); - if (*val < 0) - return *val; - *val /= 1000; - } else { - *val = st->chip_info->int_vref_mv; - } - - *val2 = st->chip_info->channel[0].scan_type.realbits; - - return IIO_VAL_FRACTIONAL_LOG2; - } - return -EINVAL; -} - - -static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { - /* - * More devices added in future - */ - [ID_AD7887] = { - .channel[0] = { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = 1, - .scan_index = 1, - .scan_type = IIO_ST('u', 12, 16, 0), - }, - .channel[1] = { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = 0, - .scan_index = 0, - .scan_type = IIO_ST('u', 12, 16, 0), - }, - .channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2), - .int_vref_mv = 2500, - }, -}; - -static const struct iio_info ad7887_info = { - .read_raw = &ad7887_read_raw, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad7887_probe(struct spi_device *spi) -{ - struct ad7887_platform_data *pdata = spi->dev.platform_data; - struct ad7887_state *st; - struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); - int ret; - - if (indio_dev == NULL) - return -ENOMEM; - - st = iio_priv(indio_dev); - - if (!pdata || !pdata->use_onchip_ref) { - st->reg = regulator_get(&spi->dev, "vref"); - if (IS_ERR(st->reg)) { - ret = PTR_ERR(st->reg); - goto error_free; - } - - ret = regulator_enable(st->reg); - if (ret) - goto error_put_reg; - } - - st->chip_info = - &ad7887_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - - spi_set_drvdata(spi, indio_dev); - st->spi = spi; - - /* Estabilish that the iio_dev is a child of the spi device */ - indio_dev->dev.parent = &spi->dev; - indio_dev->name = spi_get_device_id(spi)->name; - indio_dev->info = &ad7887_info; - indio_dev->modes = INDIO_DIRECT_MODE; - - /* Setup default message */ - - st->tx_cmd_buf[0] = AD7887_CH_AIN0 | AD7887_PM_MODE4 | - ((pdata && pdata->use_onchip_ref) ? - 0 : AD7887_REF_DIS); - - st->xfer[0].rx_buf = &st->data[0]; - st->xfer[0].tx_buf = &st->tx_cmd_buf[0]; - st->xfer[0].len = 2; - - spi_message_init(&st->msg[AD7887_CH0]); - spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]); - - if (pdata && pdata->en_dual) { - st->tx_cmd_buf[0] |= AD7887_DUAL | AD7887_REF_DIS; - - st->tx_cmd_buf[2] = AD7887_CH_AIN1 | AD7887_DUAL | - AD7887_REF_DIS | AD7887_PM_MODE4; - st->tx_cmd_buf[4] = AD7887_CH_AIN0 | AD7887_DUAL | - AD7887_REF_DIS | AD7887_PM_MODE4; - st->tx_cmd_buf[6] = AD7887_CH_AIN1 | AD7887_DUAL | - AD7887_REF_DIS | AD7887_PM_MODE4; - - st->xfer[1].rx_buf = &st->data[0]; - st->xfer[1].tx_buf = &st->tx_cmd_buf[2]; - st->xfer[1].len = 2; - - st->xfer[2].rx_buf = &st->data[2]; - st->xfer[2].tx_buf = &st->tx_cmd_buf[4]; - st->xfer[2].len = 2; - - spi_message_init(&st->msg[AD7887_CH0_CH1]); - spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]); - spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]); - - st->xfer[3].rx_buf = &st->data[0]; - st->xfer[3].tx_buf = &st->tx_cmd_buf[6]; - st->xfer[3].len = 2; - - spi_message_init(&st->msg[AD7887_CH1]); - spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]); - - indio_dev->channels = st->chip_info->channel; - indio_dev->num_channels = 3; - } else { - indio_dev->channels = &st->chip_info->channel[1]; - indio_dev->num_channels = 2; - } - - ret = ad7887_register_ring_funcs_and_init(indio_dev); - if (ret) - goto error_disable_reg; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_unregister_ring; - - return 0; -error_unregister_ring: - ad7887_ring_cleanup(indio_dev); -error_disable_reg: - if (st->reg) - regulator_disable(st->reg); -error_put_reg: - if (st->reg) - regulator_put(st->reg); -error_free: - iio_device_free(indio_dev); - - return ret; -} - -static int __devexit ad7887_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad7887_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - ad7887_ring_cleanup(indio_dev); - if (st->reg) { - regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_device_free(indio_dev); - - return 0; -} - -static const struct spi_device_id ad7887_id[] = { - {"ad7887", ID_AD7887}, - {} -}; -MODULE_DEVICE_TABLE(spi, ad7887_id); - -static struct spi_driver ad7887_driver = { - .driver = { - .name = "ad7887", - .owner = THIS_MODULE, - }, - .probe = ad7887_probe, - .remove = __devexit_p(ad7887_remove), - .id_table = ad7887_id, -}; -module_spi_driver(ad7887_driver); - -MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD7887 ADC"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c deleted file mode 100644 index f11925e62cd..00000000000 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2010-2012 Analog Devices Inc. - * Copyright (C) 2008 Jonathan Cameron - * - * Licensed under the GPL-2. - * - * ad7887_ring.c - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ad7887.h" - -/** - * ad7887_ring_preenable() setup the parameters of the ring before enabling - * - * The complex nature of the setting of the nuber of bytes per datum is due - * to this driver currently ensuring that the timestamp is stored at an 8 - * byte boundary. - **/ -static int ad7887_ring_preenable(struct iio_dev *indio_dev) -{ - struct ad7887_state *st = iio_priv(indio_dev); - int ret; - - ret = iio_sw_buffer_preenable(indio_dev); - if (ret < 0) - return ret; - - /* We know this is a single long so can 'cheat' */ - switch (*indio_dev->active_scan_mask) { - case (1 << 0): - st->ring_msg = &st->msg[AD7887_CH0]; - break; - case (1 << 1): - st->ring_msg = &st->msg[AD7887_CH1]; - /* Dummy read: push CH1 setting down to hardware */ - spi_sync(st->spi, st->ring_msg); - break; - case ((1 << 1) | (1 << 0)): - st->ring_msg = &st->msg[AD7887_CH0_CH1]; - break; - } - - return 0; -} - -static int ad7887_ring_postdisable(struct iio_dev *indio_dev) -{ - struct ad7887_state *st = iio_priv(indio_dev); - - /* dummy read: restore default CH0 settin */ - return spi_sync(st->spi, &st->msg[AD7887_CH0]); -} - -/** - * ad7887_trigger_handler() bh of trigger launched polling to ring buffer - * - * Currently there is no option in this driver to disable the saving of - * timestamps within the ring. - **/ -static irqreturn_t ad7887_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct ad7887_state *st = iio_priv(indio_dev); - s64 time_ns; - int b_sent; - - b_sent = spi_sync(st->spi, st->ring_msg); - if (b_sent) - goto done; - - time_ns = iio_get_time_ns(); - - if (indio_dev->scan_timestamp) - memcpy(st->data + indio_dev->scan_bytes - sizeof(s64), - &time_ns, sizeof(time_ns)); - - iio_push_to_buffer(indio_dev->buffer, st->data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = { - .preenable = &ad7887_ring_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, - .postdisable = &ad7887_ring_postdisable, -}; - -int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) -{ - return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - &ad7887_trigger_handler, &ad7887_ring_setup_ops); -} - -void ad7887_ring_cleanup(struct iio_dev *indio_dev) -{ - iio_triggered_buffer_cleanup(indio_dev); -} -- cgit v1.2.3 From 5daa751f89eb3e73424d0cb5c204f9e0bc14e25c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 5 Nov 2012 09:56:00 +0000 Subject: staging:iio:ad7887: Use proper kernel doc Use proper kernel doc to document the platform data struct. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7887.h | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h index b9078fc2aa1..16c2d05e5e0 100644 --- a/drivers/staging/iio/adc/ad7887.h +++ b/drivers/staging/iio/adc/ad7887.h @@ -12,21 +12,20 @@ * TODO: struct ad7887_platform_data needs to go into include/linux/iio */ + +/** + * struct ad7887_platform_data - AD7887 ADC driver platform data + * @en_dual: Whether to use dual channel mode. If set to true AIN1 becomes the + * second input channel, and Vref is internally connected to Vdd. If set to + * false the device is used in single channel mode and AIN1/Vref is used as + * VREF input. + * @use_onchip_ref: Whether to use the onchip reference. If set to true the + * internal 2.5V reference is used. If set to false a external reference is + * used. + */ struct ad7887_platform_data { - /* - * AD7887: - * In single channel mode en_dual = flase, AIN1/Vref pins assumes its - * Vref function. In dual channel mode en_dual = true, AIN1 becomes the - * second input channel, and Vref is internally connected to Vdd. - */ - bool en_dual; - /* - * AD7887: - * use_onchip_ref = true, the Vref is internally connected to the 2.500V - * Voltage reference. If use_onchip_ref = false, the reference voltage - * is supplied by AIN1/Vref - */ - bool use_onchip_ref; + bool en_dual; + bool use_onchip_ref; }; #endif /* IIO_ADC_AD7887_H_ */ -- cgit v1.2.3 From fce7c3eac7d4ca77ada5bf8332f867219fbb5068 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 5 Nov 2012 09:56:00 +0000 Subject: staging:iio:ad7887: Allow to use internal ref in two channel mode While it is not recommended to use the internal reference in two channel mode in order to obtain optimal performance it is still possible to use it. While we are at it also get rid of the duplicate tx_cmd_buf entries. There are only two unique entries. One for channel 1 and one for channel 2. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7887.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/drivers/staging/iio/adc/ad7887.c b/drivers/staging/iio/adc/ad7887.c index 88ffc4620fc..3ac0c305e12 100644 --- a/drivers/staging/iio/adc/ad7887.c +++ b/drivers/staging/iio/adc/ad7887.c @@ -59,7 +59,7 @@ struct ad7887_state { struct spi_transfer xfer[4]; struct spi_message msg[3]; struct spi_message *ring_msg; - unsigned char tx_cmd_buf[8]; + unsigned char tx_cmd_buf[4]; /* * DMA (thus cache coherency maintenance) requires the @@ -238,6 +238,7 @@ static int __devinit ad7887_probe(struct spi_device *spi) struct ad7887_platform_data *pdata = spi->dev.platform_data; struct ad7887_state *st; struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); + uint8_t mode; int ret; if (indio_dev == NULL) @@ -271,9 +272,13 @@ static int __devinit ad7887_probe(struct spi_device *spi) /* Setup default message */ - st->tx_cmd_buf[0] = AD7887_CH_AIN0 | AD7887_PM_MODE4 | - ((pdata && pdata->use_onchip_ref) ? - 0 : AD7887_REF_DIS); + mode = AD7887_PM_MODE4; + if (!pdata || !pdata->use_onchip_ref) + mode |= AD7887_REF_DIS; + if (pdata && pdata->en_dual) + mode |= AD7887_DUAL; + + st->tx_cmd_buf[0] = AD7887_CH_AIN0 | mode; st->xfer[0].rx_buf = &st->data[0]; st->xfer[0].tx_buf = &st->tx_cmd_buf[0]; @@ -283,29 +288,22 @@ static int __devinit ad7887_probe(struct spi_device *spi) spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]); if (pdata && pdata->en_dual) { - st->tx_cmd_buf[0] |= AD7887_DUAL | AD7887_REF_DIS; - - st->tx_cmd_buf[2] = AD7887_CH_AIN1 | AD7887_DUAL | - AD7887_REF_DIS | AD7887_PM_MODE4; - st->tx_cmd_buf[4] = AD7887_CH_AIN0 | AD7887_DUAL | - AD7887_REF_DIS | AD7887_PM_MODE4; - st->tx_cmd_buf[6] = AD7887_CH_AIN1 | AD7887_DUAL | - AD7887_REF_DIS | AD7887_PM_MODE4; + st->tx_cmd_buf[2] = AD7887_CH_AIN1 | mode; st->xfer[1].rx_buf = &st->data[0]; st->xfer[1].tx_buf = &st->tx_cmd_buf[2]; st->xfer[1].len = 2; st->xfer[2].rx_buf = &st->data[2]; - st->xfer[2].tx_buf = &st->tx_cmd_buf[4]; + st->xfer[2].tx_buf = &st->tx_cmd_buf[0]; st->xfer[2].len = 2; spi_message_init(&st->msg[AD7887_CH0_CH1]); spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]); spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]); - st->xfer[3].rx_buf = &st->data[0]; - st->xfer[3].tx_buf = &st->tx_cmd_buf[6]; + st->xfer[3].rx_buf = &st->data[2]; + st->xfer[3].tx_buf = &st->tx_cmd_buf[2]; st->xfer[3].len = 2; spi_message_init(&st->msg[AD7887_CH1]); -- cgit v1.2.3 From 98efb70adde96d86df29b4754f265b2c8bba01b2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 5 Nov 2012 09:56:00 +0000 Subject: staging:iio:ad7887: Use passed in chan spec in ad7887_read_raw Use the passed in chan spec in ad7887_read_raw instead of alawys using the first chan spec entry from the chip info data. Since all channels have the same shift and realbits from a functional point of view it does not matter which chan spec is used, but the patch makes the a bit more clear. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7887.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/adc/ad7887.c b/drivers/staging/iio/adc/ad7887.c index 3ac0c305e12..72cfe191cd8 100644 --- a/drivers/staging/iio/adc/ad7887.c +++ b/drivers/staging/iio/adc/ad7887.c @@ -177,8 +177,8 @@ static int ad7887_read_raw(struct iio_dev *indio_dev, if (ret < 0) return ret; - *val = (ret >> st->chip_info->channel[0].scan_type.shift) & - RES_MASK(st->chip_info->channel[0].scan_type.realbits); + *val = ret >> chan->scan_type.shift; + *val &= RES_MASK(chan->scan_type.realbits); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: if (st->reg) { @@ -190,7 +190,7 @@ static int ad7887_read_raw(struct iio_dev *indio_dev, *val = st->chip_info->int_vref_mv; } - *val2 = st->chip_info->channel[0].scan_type.realbits; + *val2 = chan->scan_type.realbits; return IIO_VAL_FRACTIONAL_LOG2; } -- cgit v1.2.3 From 4eb3ccf157639a9d9c7829de94017c46c73d9cc4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 5 Nov 2012 09:56:00 +0000 Subject: staging:iio: Move the ad7887 driver out of staging The driver does not expose any custom API to userspace and none of the standard static code checker tools report any issues, so move it out of staging. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 13 ++ drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ad7887.c | 378 +++++++++++++++++++++++++++++++++++ drivers/staging/iio/adc/Kconfig | 13 -- drivers/staging/iio/adc/Makefile | 2 - drivers/staging/iio/adc/ad7887.c | 378 ----------------------------------- drivers/staging/iio/adc/ad7887.h | 31 --- include/linux/platform_data/ad7887.h | 26 +++ 8 files changed, 418 insertions(+), 424 deletions(-) create mode 100644 drivers/iio/adc/ad7887.c delete mode 100644 drivers/staging/iio/adc/ad7887.c delete mode 100644 drivers/staging/iio/adc/ad7887.h create mode 100644 include/linux/platform_data/ad7887.h diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 49275812033..706386ba02e 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -45,6 +45,19 @@ config AD7476 To compile this driver as a module, choose M here: the module will be called ad7476. +config AD7887 + tristate "Analog Devices AD7887 ADC driver" + depends on SPI + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Analog Devices + AD7887 SPI analog to digital converter (ADC). + If unsure, say N (but it's safe to say "Y"). + + To compile this driver as a module, choose M here: the + module will be called ad7887. + config AT91_ADC tristate "Atmel AT91 ADC" depends on ARCH_AT91 diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 900995d5e17..034eacb8f7c 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -6,5 +6,6 @@ obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o obj-$(CONFIG_AD7266) += ad7266.o obj-$(CONFIG_AD7476) += ad7476.o obj-$(CONFIG_AD7791) += ad7791.o +obj-$(CONFIG_AD7887) += ad7887.o obj-$(CONFIG_AT91_ADC) += at91_adc.o obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c new file mode 100644 index 00000000000..fd62309b4d3 --- /dev/null +++ b/drivers/iio/adc/ad7887.c @@ -0,0 +1,378 @@ +/* + * AD7887 SPI ADC driver + * + * Copyright 2010-2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */ +#define AD7887_DUAL (1 << 4) /* dual-channel mode */ +#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */ +#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */ +#define AD7887_PM_MODE1 (0) /* CS based shutdown */ +#define AD7887_PM_MODE2 (1) /* full on */ +#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */ +#define AD7887_PM_MODE4 (3) /* standby mode */ + +enum ad7887_channels { + AD7887_CH0, + AD7887_CH0_CH1, + AD7887_CH1, +}; + +#define RES_MASK(bits) ((1 << (bits)) - 1) + +/** + * struct ad7887_chip_info - chip specifc information + * @int_vref_mv: the internal reference voltage + * @channel: channel specification + */ +struct ad7887_chip_info { + u16 int_vref_mv; + struct iio_chan_spec channel[3]; +}; + +struct ad7887_state { + struct spi_device *spi; + const struct ad7887_chip_info *chip_info; + struct regulator *reg; + struct spi_transfer xfer[4]; + struct spi_message msg[3]; + struct spi_message *ring_msg; + unsigned char tx_cmd_buf[4]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + * Buffer needs to be large enough to hold two 16 bit samples and a + * 64 bit aligned 64 bit timestamp. + */ + unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)] + ____cacheline_aligned; +}; + +enum ad7887_supported_device_ids { + ID_AD7887 +}; + +static int ad7887_ring_preenable(struct iio_dev *indio_dev) +{ + struct ad7887_state *st = iio_priv(indio_dev); + int ret; + + ret = iio_sw_buffer_preenable(indio_dev); + if (ret < 0) + return ret; + + /* We know this is a single long so can 'cheat' */ + switch (*indio_dev->active_scan_mask) { + case (1 << 0): + st->ring_msg = &st->msg[AD7887_CH0]; + break; + case (1 << 1): + st->ring_msg = &st->msg[AD7887_CH1]; + /* Dummy read: push CH1 setting down to hardware */ + spi_sync(st->spi, st->ring_msg); + break; + case ((1 << 1) | (1 << 0)): + st->ring_msg = &st->msg[AD7887_CH0_CH1]; + break; + } + + return 0; +} + +static int ad7887_ring_postdisable(struct iio_dev *indio_dev) +{ + struct ad7887_state *st = iio_priv(indio_dev); + + /* dummy read: restore default CH0 settin */ + return spi_sync(st->spi, &st->msg[AD7887_CH0]); +} + +/** + * ad7887_trigger_handler() bh of trigger launched polling to ring buffer + * + * Currently there is no option in this driver to disable the saving of + * timestamps within the ring. + **/ +static irqreturn_t ad7887_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad7887_state *st = iio_priv(indio_dev); + s64 time_ns; + int b_sent; + + b_sent = spi_sync(st->spi, st->ring_msg); + if (b_sent) + goto done; + + time_ns = iio_get_time_ns(); + + if (indio_dev->scan_timestamp) + memcpy(st->data + indio_dev->scan_bytes - sizeof(s64), + &time_ns, sizeof(time_ns)); + + iio_push_to_buffer(indio_dev->buffer, st->data); +done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = { + .preenable = &ad7887_ring_preenable, + .postenable = &iio_triggered_buffer_postenable, + .predisable = &iio_triggered_buffer_predisable, + .postdisable = &ad7887_ring_postdisable, +}; + +static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch) +{ + int ret = spi_sync(st->spi, &st->msg[ch]); + if (ret) + return ret; + + return (st->data[(ch * 2)] << 8) | st->data[(ch * 2) + 1]; +} + +static int ad7887_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + int ret; + struct ad7887_state *st = iio_priv(indio_dev); + + switch (m) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&indio_dev->mlock); + if (iio_buffer_enabled(indio_dev)) + ret = -EBUSY; + else + ret = ad7887_scan_direct(st, chan->address); + mutex_unlock(&indio_dev->mlock); + + if (ret < 0) + return ret; + *val = ret >> chan->scan_type.shift; + *val &= RES_MASK(chan->scan_type.realbits); + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + if (st->reg) { + *val = regulator_get_voltage(st->reg); + if (*val < 0) + return *val; + *val /= 1000; + } else { + *val = st->chip_info->int_vref_mv; + } + + *val2 = chan->scan_type.realbits; + + return IIO_VAL_FRACTIONAL_LOG2; + } + return -EINVAL; +} + + +static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { + /* + * More devices added in future + */ + [ID_AD7887] = { + .channel[0] = { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 1, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = 1, + .scan_index = 1, + .scan_type = IIO_ST('u', 12, 16, 0), + }, + .channel[1] = { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT, + .address = 0, + .scan_index = 0, + .scan_type = IIO_ST('u', 12, 16, 0), + }, + .channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2), + .int_vref_mv = 2500, + }, +}; + +static const struct iio_info ad7887_info = { + .read_raw = &ad7887_read_raw, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad7887_probe(struct spi_device *spi) +{ + struct ad7887_platform_data *pdata = spi->dev.platform_data; + struct ad7887_state *st; + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); + uint8_t mode; + int ret; + + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + if (!pdata || !pdata->use_onchip_ref) { + st->reg = regulator_get(&spi->dev, "vref"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto error_free; + } + + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + st->chip_info = + &ad7887_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + + spi_set_drvdata(spi, indio_dev); + st->spi = spi; + + /* Estabilish that the iio_dev is a child of the spi device */ + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->info = &ad7887_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + /* Setup default message */ + + mode = AD7887_PM_MODE4; + if (!pdata || !pdata->use_onchip_ref) + mode |= AD7887_REF_DIS; + if (pdata && pdata->en_dual) + mode |= AD7887_DUAL; + + st->tx_cmd_buf[0] = AD7887_CH_AIN0 | mode; + + st->xfer[0].rx_buf = &st->data[0]; + st->xfer[0].tx_buf = &st->tx_cmd_buf[0]; + st->xfer[0].len = 2; + + spi_message_init(&st->msg[AD7887_CH0]); + spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]); + + if (pdata && pdata->en_dual) { + st->tx_cmd_buf[2] = AD7887_CH_AIN1 | mode; + + st->xfer[1].rx_buf = &st->data[0]; + st->xfer[1].tx_buf = &st->tx_cmd_buf[2]; + st->xfer[1].len = 2; + + st->xfer[2].rx_buf = &st->data[2]; + st->xfer[2].tx_buf = &st->tx_cmd_buf[0]; + st->xfer[2].len = 2; + + spi_message_init(&st->msg[AD7887_CH0_CH1]); + spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]); + spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]); + + st->xfer[3].rx_buf = &st->data[2]; + st->xfer[3].tx_buf = &st->tx_cmd_buf[2]; + st->xfer[3].len = 2; + + spi_message_init(&st->msg[AD7887_CH1]); + spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]); + + indio_dev->channels = st->chip_info->channel; + indio_dev->num_channels = 3; + } else { + indio_dev->channels = &st->chip_info->channel[1]; + indio_dev->num_channels = 2; + } + + ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + &ad7887_trigger_handler, &ad7887_ring_setup_ops); + if (ret) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_unregister_ring; + + return 0; +error_unregister_ring: + iio_triggered_buffer_cleanup(indio_dev); +error_disable_reg: + if (st->reg) + regulator_disable(st->reg); +error_put_reg: + if (st->reg) + regulator_put(st->reg); +error_free: + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit ad7887_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7887_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + if (st->reg) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad7887_id[] = { + {"ad7887", ID_AD7887}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad7887_id); + +static struct spi_driver ad7887_driver = { + .driver = { + .name = "ad7887", + .owner = THIS_MODULE, + }, + .probe = ad7887_probe, + .remove = __devexit_p(ad7887_remove), + .id_table = ad7887_id, +}; +module_spi_driver(ad7887_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7887 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 71a515d0a6d..eba64fb64d8 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -68,19 +68,6 @@ config AD799X_RING_BUFFER Say yes here to include ring buffer support in the AD799X ADC driver. -config AD7887 - tristate "Analog Devices AD7887 ADC driver" - depends on SPI - select IIO_BUFFER - select IIO_TRIGGERED_BUFFER - help - Say yes here to build support for Analog Devices - AD7887 SPI analog to digital converter (ADC). - If unsure, say N (but it's safe to say "Y"). - - To compile this driver as a module, choose M here: the - module will be called ad7887. - config AD7780 tristate "Analog Devices AD7780 and similar ADCs driver" depends on SPI diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 8036fd14f68..c56b41ee285 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -17,8 +17,6 @@ ad799x-y := ad799x_core.o ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o obj-$(CONFIG_AD799X) += ad799x.o -obj-$(CONFIG_AD7887) += ad7887.o - ad7298-y := ad7298_core.o ad7298-$(CONFIG_IIO_BUFFER) += ad7298_ring.o obj-$(CONFIG_AD7298) += ad7298.o diff --git a/drivers/staging/iio/adc/ad7887.c b/drivers/staging/iio/adc/ad7887.c deleted file mode 100644 index 72cfe191cd8..00000000000 --- a/drivers/staging/iio/adc/ad7887.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * AD7887 SPI ADC driver - * - * Copyright 2010-2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "ad7887.h" - -#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */ -#define AD7887_DUAL (1 << 4) /* dual-channel mode */ -#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */ -#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */ -#define AD7887_PM_MODE1 (0) /* CS based shutdown */ -#define AD7887_PM_MODE2 (1) /* full on */ -#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */ -#define AD7887_PM_MODE4 (3) /* standby mode */ - -enum ad7887_channels { - AD7887_CH0, - AD7887_CH0_CH1, - AD7887_CH1, -}; - -#define RES_MASK(bits) ((1 << (bits)) - 1) - -/** - * struct ad7887_chip_info - chip specifc information - * @int_vref_mv: the internal reference voltage - * @channel: channel specification - */ -struct ad7887_chip_info { - u16 int_vref_mv; - struct iio_chan_spec channel[3]; -}; - -struct ad7887_state { - struct spi_device *spi; - const struct ad7887_chip_info *chip_info; - struct regulator *reg; - struct spi_transfer xfer[4]; - struct spi_message msg[3]; - struct spi_message *ring_msg; - unsigned char tx_cmd_buf[4]; - - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - * Buffer needs to be large enough to hold two 16 bit samples and a - * 64 bit aligned 64 bit timestamp. - */ - unsigned char data[ALIGN(4, sizeof(s64)) + sizeof(s64)] - ____cacheline_aligned; -}; - -enum ad7887_supported_device_ids { - ID_AD7887 -}; - -static int ad7887_ring_preenable(struct iio_dev *indio_dev) -{ - struct ad7887_state *st = iio_priv(indio_dev); - int ret; - - ret = iio_sw_buffer_preenable(indio_dev); - if (ret < 0) - return ret; - - /* We know this is a single long so can 'cheat' */ - switch (*indio_dev->active_scan_mask) { - case (1 << 0): - st->ring_msg = &st->msg[AD7887_CH0]; - break; - case (1 << 1): - st->ring_msg = &st->msg[AD7887_CH1]; - /* Dummy read: push CH1 setting down to hardware */ - spi_sync(st->spi, st->ring_msg); - break; - case ((1 << 1) | (1 << 0)): - st->ring_msg = &st->msg[AD7887_CH0_CH1]; - break; - } - - return 0; -} - -static int ad7887_ring_postdisable(struct iio_dev *indio_dev) -{ - struct ad7887_state *st = iio_priv(indio_dev); - - /* dummy read: restore default CH0 settin */ - return spi_sync(st->spi, &st->msg[AD7887_CH0]); -} - -/** - * ad7887_trigger_handler() bh of trigger launched polling to ring buffer - * - * Currently there is no option in this driver to disable the saving of - * timestamps within the ring. - **/ -static irqreturn_t ad7887_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct ad7887_state *st = iio_priv(indio_dev); - s64 time_ns; - int b_sent; - - b_sent = spi_sync(st->spi, st->ring_msg); - if (b_sent) - goto done; - - time_ns = iio_get_time_ns(); - - if (indio_dev->scan_timestamp) - memcpy(st->data + indio_dev->scan_bytes - sizeof(s64), - &time_ns, sizeof(time_ns)); - - iio_push_to_buffer(indio_dev->buffer, st->data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -static const struct iio_buffer_setup_ops ad7887_ring_setup_ops = { - .preenable = &ad7887_ring_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, - .postdisable = &ad7887_ring_postdisable, -}; - -static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch) -{ - int ret = spi_sync(st->spi, &st->msg[ch]); - if (ret) - return ret; - - return (st->data[(ch * 2)] << 8) | st->data[(ch * 2) + 1]; -} - -static int ad7887_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long m) -{ - int ret; - struct ad7887_state *st = iio_priv(indio_dev); - - switch (m) { - case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) - ret = -EBUSY; - else - ret = ad7887_scan_direct(st, chan->address); - mutex_unlock(&indio_dev->mlock); - - if (ret < 0) - return ret; - *val = ret >> chan->scan_type.shift; - *val &= RES_MASK(chan->scan_type.realbits); - return IIO_VAL_INT; - case IIO_CHAN_INFO_SCALE: - if (st->reg) { - *val = regulator_get_voltage(st->reg); - if (*val < 0) - return *val; - *val /= 1000; - } else { - *val = st->chip_info->int_vref_mv; - } - - *val2 = chan->scan_type.realbits; - - return IIO_VAL_FRACTIONAL_LOG2; - } - return -EINVAL; -} - - -static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { - /* - * More devices added in future - */ - [ID_AD7887] = { - .channel[0] = { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = 1, - .scan_index = 1, - .scan_type = IIO_ST('u', 12, 16, 0), - }, - .channel[1] = { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = 0, - .scan_index = 0, - .scan_type = IIO_ST('u', 12, 16, 0), - }, - .channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2), - .int_vref_mv = 2500, - }, -}; - -static const struct iio_info ad7887_info = { - .read_raw = &ad7887_read_raw, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad7887_probe(struct spi_device *spi) -{ - struct ad7887_platform_data *pdata = spi->dev.platform_data; - struct ad7887_state *st; - struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); - uint8_t mode; - int ret; - - if (indio_dev == NULL) - return -ENOMEM; - - st = iio_priv(indio_dev); - - if (!pdata || !pdata->use_onchip_ref) { - st->reg = regulator_get(&spi->dev, "vref"); - if (IS_ERR(st->reg)) { - ret = PTR_ERR(st->reg); - goto error_free; - } - - ret = regulator_enable(st->reg); - if (ret) - goto error_put_reg; - } - - st->chip_info = - &ad7887_chip_info_tbl[spi_get_device_id(spi)->driver_data]; - - spi_set_drvdata(spi, indio_dev); - st->spi = spi; - - /* Estabilish that the iio_dev is a child of the spi device */ - indio_dev->dev.parent = &spi->dev; - indio_dev->name = spi_get_device_id(spi)->name; - indio_dev->info = &ad7887_info; - indio_dev->modes = INDIO_DIRECT_MODE; - - /* Setup default message */ - - mode = AD7887_PM_MODE4; - if (!pdata || !pdata->use_onchip_ref) - mode |= AD7887_REF_DIS; - if (pdata && pdata->en_dual) - mode |= AD7887_DUAL; - - st->tx_cmd_buf[0] = AD7887_CH_AIN0 | mode; - - st->xfer[0].rx_buf = &st->data[0]; - st->xfer[0].tx_buf = &st->tx_cmd_buf[0]; - st->xfer[0].len = 2; - - spi_message_init(&st->msg[AD7887_CH0]); - spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]); - - if (pdata && pdata->en_dual) { - st->tx_cmd_buf[2] = AD7887_CH_AIN1 | mode; - - st->xfer[1].rx_buf = &st->data[0]; - st->xfer[1].tx_buf = &st->tx_cmd_buf[2]; - st->xfer[1].len = 2; - - st->xfer[2].rx_buf = &st->data[2]; - st->xfer[2].tx_buf = &st->tx_cmd_buf[0]; - st->xfer[2].len = 2; - - spi_message_init(&st->msg[AD7887_CH0_CH1]); - spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]); - spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]); - - st->xfer[3].rx_buf = &st->data[2]; - st->xfer[3].tx_buf = &st->tx_cmd_buf[2]; - st->xfer[3].len = 2; - - spi_message_init(&st->msg[AD7887_CH1]); - spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]); - - indio_dev->channels = st->chip_info->channel; - indio_dev->num_channels = 3; - } else { - indio_dev->channels = &st->chip_info->channel[1]; - indio_dev->num_channels = 2; - } - - ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - &ad7887_trigger_handler, &ad7887_ring_setup_ops); - if (ret) - goto error_disable_reg; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_unregister_ring; - - return 0; -error_unregister_ring: - iio_triggered_buffer_cleanup(indio_dev); -error_disable_reg: - if (st->reg) - regulator_disable(st->reg); -error_put_reg: - if (st->reg) - regulator_put(st->reg); -error_free: - iio_device_free(indio_dev); - - return ret; -} - -static int __devexit ad7887_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad7887_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - iio_triggered_buffer_cleanup(indio_dev); - if (st->reg) { - regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_device_free(indio_dev); - - return 0; -} - -static const struct spi_device_id ad7887_id[] = { - {"ad7887", ID_AD7887}, - {} -}; -MODULE_DEVICE_TABLE(spi, ad7887_id); - -static struct spi_driver ad7887_driver = { - .driver = { - .name = "ad7887", - .owner = THIS_MODULE, - }, - .probe = ad7887_probe, - .remove = __devexit_p(ad7887_remove), - .id_table = ad7887_id, -}; -module_spi_driver(ad7887_driver); - -MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD7887 ADC"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h deleted file mode 100644 index 16c2d05e5e0..00000000000 --- a/drivers/staging/iio/adc/ad7887.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * AD7887 SPI ADC driver - * - * Copyright 2010 Analog Devices Inc. - * - * Licensed under the GPL-2 or later. - */ -#ifndef IIO_ADC_AD7887_H_ -#define IIO_ADC_AD7887_H_ - -/* - * TODO: struct ad7887_platform_data needs to go into include/linux/iio - */ - - -/** - * struct ad7887_platform_data - AD7887 ADC driver platform data - * @en_dual: Whether to use dual channel mode. If set to true AIN1 becomes the - * second input channel, and Vref is internally connected to Vdd. If set to - * false the device is used in single channel mode and AIN1/Vref is used as - * VREF input. - * @use_onchip_ref: Whether to use the onchip reference. If set to true the - * internal 2.5V reference is used. If set to false a external reference is - * used. - */ -struct ad7887_platform_data { - bool en_dual; - bool use_onchip_ref; -}; - -#endif /* IIO_ADC_AD7887_H_ */ diff --git a/include/linux/platform_data/ad7887.h b/include/linux/platform_data/ad7887.h new file mode 100644 index 00000000000..1e06eac3174 --- /dev/null +++ b/include/linux/platform_data/ad7887.h @@ -0,0 +1,26 @@ +/* + * AD7887 SPI ADC driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ +#ifndef IIO_ADC_AD7887_H_ +#define IIO_ADC_AD7887_H_ + +/** + * struct ad7887_platform_data - AD7887 ADC driver platform data + * @en_dual: Whether to use dual channel mode. If set to true AIN1 becomes the + * second input channel, and Vref is internally connected to Vdd. If set to + * false the device is used in single channel mode and AIN1/Vref is used as + * VREF input. + * @use_onchip_ref: Whether to use the onchip reference. If set to true the + * internal 2.5V reference is used. If set to false a external reference is + * used. + */ +struct ad7887_platform_data { + bool en_dual; + bool use_onchip_ref; +}; + +#endif /* IIO_ADC_AD7887_H_ */ -- cgit v1.2.3 From 73c503cb981394872db41dd5cde385cb5373b4b9 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 5 Nov 2012 15:46:36 -0800 Subject: ARM: OMAP4: PM: fix regulator name for VDD_MPU commit 24d7b40a (ARM: OMAP2+: PM: MPU DVFS: use generic CPU device for MPU-SS) updated the regulator name used for the MPU regulator, but only updated OMAP3, not OMAP4. Fix the OMAP4 name as well, otherwise CPUfreq fails to find the MPU regulator. Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/twl-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 635e109f5ad..44c42057b61 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -366,7 +366,7 @@ static struct regulator_init_data omap4_clk32kg_idata = { }; static struct regulator_consumer_supply omap4_vdd1_supply[] = { - REGULATOR_SUPPLY("vcc", "mpu.0"), + REGULATOR_SUPPLY("vcc", "cpu0"), }; static struct regulator_consumer_supply omap4_vdd2_supply[] = { -- cgit v1.2.3 From b91524ee48771586b99bfbed9d4607c3e407d7cb Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 19:17:57 +0000 Subject: staging: comedi: cb_pcidas64: use auto_attach method This driver does not need to support manual attachment of supported PCI devices. Replace the `attach()` hook with an `auto_attach()` hook. This will be called via `comedi_pci_auto_config()` at PCI probe time. The `auto_attach()` calls new function `cb_pcidas64_find_pci_board()` to find the correct entry in `pcidas64_boards[]` for the PCI device. This driver no longer increments the PCI reference count during attachment, so remove the call to `pci_dev_put()` when detaching the device. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 57 +++++++++------------------- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 0ae7ef5856c..69db96ff3d5 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1645,57 +1645,38 @@ static inline void warn_external_queue(struct comedi_device *dev) "Use internal AI channel queue (channels must be consecutive and use same range/aref)"); } -static struct pci_dev *cb_pcidas64_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) +static const struct pcidas64_board +*cb_pcidas64_find_pci_board(struct pci_dev *pcidev) { - struct pci_dev *pcidev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - int i; + unsigned int i; - for_each_pci_dev(pcidev) { - if (bus || slot) { - if (bus != pcidev->bus->number || - slot != PCI_SLOT(pcidev->devfn)) - continue; - } - if (pcidev->vendor != PCI_VENDOR_ID_CB) - continue; - - for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++) { - if (pcidas64_boards[i].device_id != pcidev->device) - continue; - dev->board_ptr = pcidas64_boards + i; - return pcidev; - } - } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); + for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++) + if (pcidev->device == pcidas64_boards[i].device_id) + return &pcidas64_boards[i]; return NULL; } -/* - * Attach is called by the Comedi core to configure the driver - * for a particular board. - */ -static int attach(struct comedi_device *dev, struct comedi_devconfig *it) +static int __devinit auto_attach(struct comedi_device *dev, + unsigned long context_unused) { struct pcidas64_private *devpriv; - struct pci_dev *pcidev; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); uint32_t local_range, local_decode; int retval; + dev->board_ptr = cb_pcidas64_find_pci_board(pcidev); + if (!dev->board_ptr) { + dev_err(dev->class_dev, + "cb_pcidas64: does not support pci %s\n", + pci_name(pcidev)); + return -EINVAL; + } + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; dev->private = devpriv; - pcidev = cb_pcidas64_find_pci_dev(dev, it); - if (!pcidev) - return -EIO; - comedi_set_hw_dev(dev, &pcidev->dev); - if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { dev_warn(dev->class_dev, "failed to enable PCI device and request regions\n"); @@ -1838,8 +1819,6 @@ static void detach(struct comedi_device *dev) if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); - - pci_dev_put(pcidev); } } @@ -4240,7 +4219,7 @@ static void i2c_write(struct comedi_device *dev, unsigned int address, static struct comedi_driver cb_pcidas64_driver = { .driver_name = "cb_pcidas64", .module = THIS_MODULE, - .attach = attach, + .auto_attach = auto_attach, .detach = detach, }; -- cgit v1.2.3 From 65998b1ba4908115e86d490a7decea60e708be75 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 19:17:58 +0000 Subject: staging: comedi: cb_pcidas64: fix printks Replace `printk` calls with something else. For the `DEBUG_PRINT()` macro, use `pr_debug()` (if `PCIDAS64_DEBUG macro defined) or `no_printk()`. Fix a few `DEBUG_PRINT()` calls due to compiler warnings and add newlines where they are missing. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 69db96ff3d5..a431b6d3eae 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -83,6 +83,8 @@ TODO: make ao fifo size adjustable like ai fifo */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "../comedidev.h" #include #include @@ -96,9 +98,9 @@ TODO: /* #define PCIDAS64_DEBUG enable debugging code */ #ifdef PCIDAS64_DEBUG -#define DEBUG_PRINT(format, args...) printk(format , ## args) +#define DEBUG_PRINT(format, args...) pr_debug(format, ## args) #else -#define DEBUG_PRINT(format, args...) +#define DEBUG_PRINT(format, args...) no_printk(format, ## args) #endif #define TIMER_BASE 25 /* 40MHz master clock */ @@ -1580,8 +1582,8 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) if (devpriv->ai_dma_desc == NULL) return -ENOMEM; - DEBUG_PRINT("ai dma descriptors start at bus addr 0x%x\n", - devpriv->ai_dma_desc_bus_addr); + DEBUG_PRINT("ai dma descriptors start at bus addr 0x%llx\n", + (unsigned long long)devpriv->ai_dma_desc_bus_addr); if (ao_cmd_is_supported(board(dev))) { devpriv->ao_dma_desc = pci_alloc_consistent(pcidev, @@ -1591,8 +1593,8 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) if (devpriv->ao_dma_desc == NULL) return -ENOMEM; - DEBUG_PRINT("ao dma descriptors start at bus addr 0x%x\n", - devpriv->ao_dma_desc_bus_addr); + DEBUG_PRINT("ao dma descriptors start at bus addr 0x%llx\n", + (unsigned long long)devpriv->ao_dma_desc_bus_addr); } /* initialize dma descriptors */ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { @@ -1944,7 +1946,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, DEBUG_PRINT(" looped %i times waiting for data\n", i); if (i == timeout) { comedi_error(dev, " analog input read insn timed out"); - printk(" status 0x%x\n", bits); + dev_info(dev->class_dev, "status 0x%x\n", bits); return -ETIME; } if (board(dev)->layout == LAYOUT_4020) @@ -3100,15 +3102,13 @@ static irqreturn_t handle_interrupt(int irq, void *d) plx_status = readl(devpriv->plx9080_iobase + PLX_INTRCS_REG); status = readw(devpriv->main_iobase + HW_STATUS_REG); - DEBUG_PRINT("cb_pcidas64: hw status 0x%x ", status); - DEBUG_PRINT("plx status 0x%x\n", plx_status); + DEBUG_PRINT("hw status 0x%x, plx status 0x%x\n", status, plx_status); /* an interrupt before all the postconfig stuff gets done could * cause a NULL dereference if we continue through the * interrupt handler */ if (dev->attached == 0) { - DEBUG_PRINT("cb_pcidas64: premature interrupt, ignoring", - status); + DEBUG_PRINT("premature interrupt, ignoring\n"); return IRQ_HANDLED; } handle_ai_interrupt(dev, status, plx_status); @@ -3290,8 +3290,9 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev, buffer_index = devpriv->ao_dma_index; prev_buffer_index = prev_ao_dma_index(dev); - DEBUG_PRINT("attempting to load ao buffer %i (0x%x)\n", buffer_index, - devpriv->ao_buffer_bus_addr[buffer_index]); + DEBUG_PRINT("attempting to load ao buffer %i (0x%llx)\n", buffer_index, + (unsigned long long)devpriv->ao_buffer_bus_addr[ + buffer_index]); num_bytes = comedi_buf_read_n_available(dev->write_subdev->async); if (num_bytes > DMA_BUFFER_SIZE) -- cgit v1.2.3 From 46ca84c4659f24776f7b901dd6054e3c6dfc115e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 19:17:59 +0000 Subject: staging: comedi: cb_pcidas64: whitespace/brace changes Some whitespace changes, mostly to fix lines > 80 characters and operator placement. Add/remove some braces according to CodingStyle. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 560 +++++++++++++++------------ 1 file changed, 311 insertions(+), 249 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index a431b6d3eae..c95756f0eb6 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -74,12 +74,14 @@ https://bugs.comedi.org. TODO: make it return error if user attempts an ai command that uses the - external queue, and an ao command simultaneously - user counter subdevice + external queue, and an ao command simultaneously user counter subdevice there are a number of boards this driver will support when they are - fully released, but does not yet since the pci device id numbers - are not yet available. - support prescaled 100khz clock for slow pacing (not available on 6000 series?) + fully released, but does not yet since the pci device id numbers + are not yet available. + + support prescaled 100khz clock for slow pacing (not available on 6000 + series?) + make ao fifo size adjustable like ai fifo */ @@ -104,7 +106,9 @@ TODO: #endif #define TIMER_BASE 25 /* 40MHz master clock */ -#define PRESCALED_TIMER_BASE 10000 /* 100kHz 'prescaled' clock for slow acquisition, maybe I'll support this someday */ +/* 100kHz 'prescaled' clock for slow acquisition, + * maybe I'll support this someday */ +#define PRESCALED_TIMER_BASE 10000 #define DMA_BUFFER_SIZE 0x1000 /* maximum value that can be loaded into board's 24-bit counters*/ @@ -128,26 +132,36 @@ enum write_only_registers { ADC_CONTROL0_REG = 0x10, /* adc control register 0 */ ADC_CONTROL1_REG = 0x12, /* adc control register 1 */ CALIBRATION_REG = 0x14, - ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16, /* lower 16 bits of adc sample interval counter */ - ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18, /* upper 8 bits of adc sample interval counter */ - ADC_DELAY_INTERVAL_LOWER_REG = 0x1a, /* lower 16 bits of delay interval counter */ - ADC_DELAY_INTERVAL_UPPER_REG = 0x1c, /* upper 8 bits of delay interval counter */ - ADC_COUNT_LOWER_REG = 0x1e, /* lower 16 bits of hardware conversion/scan counter */ - ADC_COUNT_UPPER_REG = 0x20, /* upper 8 bits of hardware conversion/scan counter */ + /* lower 16 bits of adc sample interval counter */ + ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16, + /* upper 8 bits of adc sample interval counter */ + ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18, + /* lower 16 bits of delay interval counter */ + ADC_DELAY_INTERVAL_LOWER_REG = 0x1a, + /* upper 8 bits of delay interval counter */ + ADC_DELAY_INTERVAL_UPPER_REG = 0x1c, + /* lower 16 bits of hardware conversion/scan counter */ + ADC_COUNT_LOWER_REG = 0x1e, + /* upper 8 bits of hardware conversion/scan counter */ + ADC_COUNT_UPPER_REG = 0x20, ADC_START_REG = 0x22, /* software trigger to start acquisition */ ADC_CONVERT_REG = 0x24, /* initiates single conversion */ ADC_QUEUE_CLEAR_REG = 0x26, /* clears adc queue */ ADC_QUEUE_LOAD_REG = 0x28, /* loads adc queue */ ADC_BUFFER_CLEAR_REG = 0x2a, - ADC_QUEUE_HIGH_REG = 0x2c, /* high channel for internal queue, use adc_chan_bits() inline above */ + /* high channel for internal queue, use adc_chan_bits() inline above */ + ADC_QUEUE_HIGH_REG = 0x2c, DAC_CONTROL0_REG = 0x50, /* dac control register 0 */ DAC_CONTROL1_REG = 0x52, /* dac control register 0 */ - DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54, /* lower 16 bits of dac sample interval counter */ - DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56, /* upper 8 bits of dac sample interval counter */ + /* lower 16 bits of dac sample interval counter */ + DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54, + /* upper 8 bits of dac sample interval counter */ + DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56, DAC_SELECT_REG = 0x60, DAC_START_REG = 0x64, DAC_BUFFER_CLEAR_REG = 0x66, /* clear dac buffer */ }; + static inline unsigned int dac_convert_reg(unsigned int channel) { return 0x70 + (2 * (channel & 0x1)); @@ -164,7 +178,9 @@ static inline unsigned int dac_msb_4020_reg(unsigned int channel) } enum read_only_registers { - HW_STATUS_REG = 0x0, /* hardware status register, reading this apparently clears pending interrupts as well */ + /* hardware status register, + * reading this apparently clears pending interrupts as well */ + HW_STATUS_REG = 0x0, PIPE1_READ_REG = 0x4, ADC_READ_PNTR_REG = 0x8, LOWER_XFER_REG = 0x10, @@ -174,9 +190,11 @@ enum read_only_registers { enum read_write_registers { I8255_4020_REG = 0x48, /* 8255 offset, for 4020 only */ - ADC_QUEUE_FIFO_REG = 0x100, /* external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG */ + /* external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG */ + ADC_QUEUE_FIFO_REG = 0x100, ADC_FIFO_REG = 0x200, /* adc data fifo */ - DAC_FIFO_REG = 0x300, /* dac data fifo, has weird interactions with external channel queue */ + /* dac data fifo, has weird interactions with external channel queue */ + DAC_FIFO_REG = 0x300, }; /* devpriv->dio_counter_iobase registers */ @@ -191,13 +209,13 @@ enum dio_counter_registers { /* bit definitions for write-only registers */ enum intr_enable_contents { - ADC_INTR_SRC_MASK = 0x3, /* bits that set adc interrupt source */ - ADC_INTR_QFULL_BITS = 0x0, /* interrupt fifo quater full */ + ADC_INTR_SRC_MASK = 0x3, /* adc interrupt source mask */ + ADC_INTR_QFULL_BITS = 0x0, /* interrupt fifo quarter full */ ADC_INTR_EOC_BITS = 0x1, /* interrupt end of conversion */ ADC_INTR_EOSCAN_BITS = 0x2, /* interrupt end of scan */ - ADC_INTR_EOSEQ_BITS = 0x3, /* interrupt end of sequence (probably wont use this it's pretty fancy) */ + ADC_INTR_EOSEQ_BITS = 0x3, /* interrupt end of sequence mask */ EN_ADC_INTR_SRC_BIT = 0x4, /* enable adc interrupt source */ - EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc acquisition done interrupt */ + EN_ADC_DONE_INTR_BIT = 0x8, /* enable adc acquisition done intr */ DAC_INTR_SRC_MASK = 0x30, DAC_INTR_QEMPTY_BITS = 0x0, DAC_INTR_HIGH_CHAN_BITS = 0x10, @@ -211,25 +229,33 @@ enum intr_enable_contents { }; enum hw_config_contents { - MASTER_CLOCK_4020_MASK = 0x3, /* bits that specify master clock source for 4020 */ - INTERNAL_CLOCK_4020_BITS = 0x1, /* use 40 MHz internal master clock for 4020 */ + MASTER_CLOCK_4020_MASK = 0x3, /* master clock source mask for 4020 */ + INTERNAL_CLOCK_4020_BITS = 0x1, /* use 40 MHz internal master clock */ BNC_CLOCK_4020_BITS = 0x2, /* use BNC input for master clock */ EXT_CLOCK_4020_BITS = 0x3, /* use dio input for master clock */ - EXT_QUEUE_BIT = 0x200, /* use external channel/gain queue (more versatile than internal queue) */ - SLOW_DAC_BIT = 0x400, /* use 225 nanosec strobe when loading dac instead of 50 nanosec */ - HW_CONFIG_DUMMY_BITS = 0x2000, /* bit with unknown function yet given as default value in pci-das64 manual */ - DMA_CH_SELECT_BIT = 0x8000, /* bit selects channels 1/0 for analog input/output, otherwise 0/1 */ - FIFO_SIZE_REG = 0x4, /* allows adjustment of fifo sizes */ + EXT_QUEUE_BIT = 0x200, /* use external channel/gain queue */ + /* use 225 nanosec strobe when loading dac instead of 50 nanosec */ + SLOW_DAC_BIT = 0x400, + /* bit with unknown function yet given as default value in pci-das64 + * manual */ + HW_CONFIG_DUMMY_BITS = 0x2000, + /* bit selects channels 1/0 for analog input/output, otherwise 0/1 */ + DMA_CH_SELECT_BIT = 0x8000, + FIFO_SIZE_REG = 0x4, /* allows adjustment of fifo sizes */ DAC_FIFO_SIZE_MASK = 0xff00, /* bits that set dac fifo size */ - DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */ + DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */ }; #define DAC_FIFO_SIZE 0x2000 enum daq_atrig_low_4020_contents { - EXT_AGATE_BNC_BIT = 0x8000, /* use trig/ext clk bnc input for analog gate signal */ - EXT_STOP_TRIG_BNC_BIT = 0x4000, /* use trig/ext clk bnc input for external stop trigger signal */ - EXT_START_TRIG_BNC_BIT = 0x2000, /* use trig/ext clk bnc input for external start trigger signal */ + /* use trig/ext clk bnc input for analog gate signal */ + EXT_AGATE_BNC_BIT = 0x8000, + /* use trig/ext clk bnc input for external stop trigger signal */ + EXT_STOP_TRIG_BNC_BIT = 0x4000, + /* use trig/ext clk bnc input for external start trigger signal */ + EXT_START_TRIG_BNC_BIT = 0x2000, }; + static inline uint16_t analog_trig_low_threshold_bits(uint16_t threshold) { return threshold & 0xfff; @@ -247,14 +273,17 @@ enum adc_control0_contents { ADC_START_TRIG_ANALOG_BITS = 0x30, ADC_START_TRIG_MASK = 0x30, ADC_START_TRIG_FALLING_BIT = 0x40, /* trig 1 uses falling edge */ - ADC_EXT_CONV_FALLING_BIT = 0x800, /* external pacing uses falling edge */ - ADC_SAMPLE_COUNTER_EN_BIT = 0x1000, /* enable hardware scan counter */ + /* external pacing uses falling edge */ + ADC_EXT_CONV_FALLING_BIT = 0x800, + /* enable hardware scan counter */ + ADC_SAMPLE_COUNTER_EN_BIT = 0x1000, ADC_DMA_DISABLE_BIT = 0x4000, /* disables dma */ ADC_ENABLE_BIT = 0x8000, /* master adc enable */ }; enum adc_control1_contents { - ADC_QUEUE_CONFIG_BIT = 0x1, /* should be set for boards with > 16 channels */ + /* should be set for boards with > 16 channels */ + ADC_QUEUE_CONFIG_BIT = 0x1, CONVERT_POLARITY_BIT = 0x10, EOC_POLARITY_BIT = 0x20, ADC_SW_GATE_BIT = 0x40, /* software gate of adc */ @@ -263,10 +292,11 @@ enum adc_control1_contents { ADC_LO_CHANNEL_4020_MASK = 0x300, ADC_HI_CHANNEL_4020_MASK = 0xc00, TWO_CHANNEL_4020_BITS = 0x1000, /* two channel mode for 4020 */ - FOUR_CHANNEL_4020_BITS = 0x2000, /* four channel mode for 4020 */ + FOUR_CHANNEL_4020_BITS = 0x2000, /* four channel mode for 4020 */ CHANNEL_MODE_4020_MASK = 0x3000, ADC_MODE_MASK = 0xf000, }; + static inline uint16_t adc_lo_chan_4020_bits(unsigned int channel) { return (channel & 0x3) << 8; @@ -289,9 +319,10 @@ enum calibration_contents { CAL_EN_64XX_BIT = 0x40, /* calibration enable for 64xx series */ SERIAL_DATA_IN_BIT = 0x80, SERIAL_CLOCK_BIT = 0x100, - CAL_EN_60XX_BIT = 0x200, /* calibration enable for 60xx series */ + CAL_EN_60XX_BIT = 0x200, /* calibration enable for 60xx series */ CAL_GAIN_BIT = 0x800, }; + /* calibration sources for 6025 are: * 0 : ground * 1 : 10V @@ -302,6 +333,7 @@ enum calibration_contents { * 6 : dac channel 0 * 7 : dac channel 1 */ + static inline uint16_t adc_src_bits(unsigned int source) { return (source & 0xf) << 3; @@ -315,10 +347,12 @@ static inline uint16_t adc_convert_chan_4020_bits(unsigned int channel) enum adc_queue_load_contents { UNIP_BIT = 0x800, /* unipolar/bipolar bit */ ADC_SE_DIFF_BIT = 0x1000, /* single-ended/ differential bit */ - ADC_COMMON_BIT = 0x2000, /* non-referenced single-ended (common-mode input) */ + /* non-referenced single-ended (common-mode input) */ + ADC_COMMON_BIT = 0x2000, QUEUE_EOSEQ_BIT = 0x4000, /* queue end of sequence */ QUEUE_EOSCAN_BIT = 0x8000, /* queue end of scan */ }; + static inline uint16_t adc_chan_bits(unsigned int channel) { return channel & 0x3f; @@ -365,6 +399,7 @@ enum hw_status_contents { EXT_INTR_PENDING_BIT = 0x100, ADC_STOP_BIT = 0x200, }; + static inline uint16_t pipe_full_bits(uint16_t hw_status_bits) { return (hw_status_bits >> 10) & 0x3; @@ -393,9 +428,12 @@ enum i2c_addresses { }; enum range_cal_i2c_contents { - ADC_SRC_4020_MASK = 0x70, /* bits that set what source the adc converter measures */ - BNC_TRIG_THRESHOLD_0V_BIT = 0x80, /* make bnc trig/ext clock threshold 0V instead of 2.5V */ + /* bits that set what source the adc converter measures */ + ADC_SRC_4020_MASK = 0x70, + /* make bnc trig/ext clock threshold 0V instead of 2.5V */ + BNC_TRIG_THRESHOLD_0V_BIT = 0x80, }; + static inline uint8_t adc_src_4020_bits(unsigned int source) { return (source << 4) & ADC_SRC_4020_MASK; @@ -562,11 +600,12 @@ struct pcidas64_board { const struct comedi_lrange *ai_range_table; int ao_nchan; /* number of analog out channels */ int ao_bits; /* analog output resolution */ - int ao_scan_speed; /* analog output speed (for a scan, not conversion) */ + int ao_scan_speed; /* analog output scan speed */ const struct comedi_lrange *ao_range_table; const int *ao_range_code; const struct hw_fifo_info *const ai_fifo; - enum register_layout layout; /* different board families have slightly different registers */ + /* different board families have slightly different registers */ + enum register_layout layout; unsigned has_8255:1; }; @@ -1041,8 +1080,10 @@ static inline unsigned short se_diff_bit_6xxx(struct comedi_device *dev, }; struct ext_clock_info { - unsigned int divisor; /* master clock divisor to use for scans with external master clock */ - unsigned int chanspec; /* chanspec for master clock input when used as scan begin src */ + /* master clock divisor to use for scans with external master clock */ + unsigned int divisor; + /* chanspec for master clock input when used as scan begin src */ + unsigned int chanspec; }; /* this structure is for data unique to this hardware driver. */ @@ -1058,30 +1099,52 @@ struct pcidas64_private { /* local address (used by dma controller) */ uint32_t local0_iobase; uint32_t local1_iobase; - volatile unsigned int ai_count; /* number of analog input samples remaining */ - uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT]; /* dma buffers for analog input */ - dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT]; /* physical addresses of ai dma buffers */ - struct plx_dma_desc *ai_dma_desc; /* array of ai dma descriptors read by plx9080, allocated to get proper alignment */ - dma_addr_t ai_dma_desc_bus_addr; /* physical address of ai dma descriptor array */ - volatile unsigned int ai_dma_index; /* index of the ai dma descriptor/buffer that is currently being used */ - uint16_t *ao_buffer[AO_DMA_RING_COUNT]; /* dma buffers for analog output */ - dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT]; /* physical addresses of ao dma buffers */ + /* number of analog input samples remaining */ + volatile unsigned int ai_count; + /* dma buffers for analog input */ + uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT]; + /* physical addresses of ai dma buffers */ + dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT]; + /* array of ai dma descriptors read by plx9080, + * allocated to get proper alignment */ + struct plx_dma_desc *ai_dma_desc; + /* physical address of ai dma descriptor array */ + dma_addr_t ai_dma_desc_bus_addr; + /* index of the ai dma descriptor/buffer + * that is currently being used */ + volatile unsigned int ai_dma_index; + /* dma buffers for analog output */ + uint16_t *ao_buffer[AO_DMA_RING_COUNT]; + /* physical addresses of ao dma buffers */ + dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT]; struct plx_dma_desc *ao_dma_desc; dma_addr_t ao_dma_desc_bus_addr; - volatile unsigned int ao_dma_index; /* keeps track of buffer where the next ao sample should go */ - volatile unsigned long ao_count; /* number of analog output samples remaining */ - volatile unsigned int ao_value[2]; /* remember what the analog outputs are set to, to allow readback */ + /* keeps track of buffer where the next ao sample should go */ + volatile unsigned int ao_dma_index; + /* number of analog output samples remaining */ + volatile unsigned long ao_count; + /* remember what the analog outputs are set to, to allow readback */ + volatile unsigned int ao_value[2]; unsigned int hw_revision; /* stc chip hardware revision number */ - volatile unsigned int intr_enable_bits; /* last bits sent to INTR_ENABLE_REG register */ - volatile uint16_t adc_control1_bits; /* last bits sent to ADC_CONTROL1_REG register */ - volatile uint16_t fifo_size_bits; /* last bits sent to FIFO_SIZE_REG register */ - volatile uint16_t hw_config_bits; /* last bits sent to HW_CONFIG_REG register */ + /* last bits sent to INTR_ENABLE_REG register */ + volatile unsigned int intr_enable_bits; + /* last bits sent to ADC_CONTROL1_REG register */ + volatile uint16_t adc_control1_bits; + /* last bits sent to FIFO_SIZE_REG register */ + volatile uint16_t fifo_size_bits; + /* last bits sent to HW_CONFIG_REG register */ + volatile uint16_t hw_config_bits; volatile uint16_t dac_control1_bits; - volatile uint32_t plx_control_bits; /* last bits written to plx9080 control register */ - volatile uint32_t plx_intcsr_bits; /* last bits written to plx interrupt control and status register */ - volatile int calibration_source; /* index of calibration source readable through ai ch0 */ - volatile uint8_t i2c_cal_range_bits; /* bits written to i2c calibration/range register */ - volatile unsigned int ext_trig_falling; /* configure digital triggers to trigger on falling edge */ + /* last bits written to plx9080 control register */ + volatile uint32_t plx_control_bits; + /* last bits written to plx interrupt control and status register */ + volatile uint32_t plx_intcsr_bits; + /* index of calibration source readable through ai ch0 */ + volatile int calibration_source; + /* bits written to i2c calibration/range register */ + volatile uint8_t i2c_cal_range_bits; + /* configure digital triggers to trigger on falling edge */ + volatile unsigned int ext_trig_falling; /* states of various devices stored to enable read-back */ unsigned int ad8402_state[2]; unsigned int caldac_state[8]; @@ -1147,7 +1210,8 @@ static void caldac_write(struct comedi_device *dev, unsigned int channel, unsigned int value); static int caldac_8800_write(struct comedi_device *dev, unsigned int address, uint8_t value); -/* static int dac_1590_write(struct comedi_device *dev, unsigned int dac_a, unsigned int dac_b); */ +/* static int dac_1590_write(struct comedi_device *dev, unsigned int dac_a, + * unsigned int dac_b); */ static int caldac_i2c_write(struct comedi_device *dev, unsigned int caldac_channel, unsigned int value); static void abort_dma(struct comedi_device *dev, unsigned int channel); @@ -1169,7 +1233,7 @@ static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev, unsigned int range_index) { const struct comedi_krange *range = - &board(dev)->ai_range_table->range[range_index]; + &board(dev)->ai_range_table->range[range_index]; unsigned int bits = 0; switch (range->max) { @@ -1246,7 +1310,7 @@ static void init_plx9080(struct comedi_device *dev) void __iomem *plx_iobase = devpriv->plx9080_iobase; devpriv->plx_control_bits = - readl(devpriv->plx9080_iobase + PLX_CONTROL_REG); + readl(devpriv->plx9080_iobase + PLX_CONTROL_REG); /* plx9080 dump */ DEBUG_PRINT(" plx interrupt status 0x%x\n", @@ -1300,9 +1364,11 @@ static void init_plx9080(struct comedi_device *dev) bits |= PLX_EN_BTERM_BIT; /* enable dma chaining */ bits |= PLX_EN_CHAIN_BIT; - /* enable interrupt on dma done (probably don't need this, since chain never finishes) */ + /* enable interrupt on dma done + * (probably don't need this, since chain never finishes) */ bits |= PLX_EN_DMA_DONE_INTR_BIT; - /* don't increment local address during transfers (we are transferring from a fixed fifo register) */ + /* don't increment local address during transfers + * (we are transferring from a fixed fifo register) */ bits |= PLX_LOCAL_ADDR_CONST_BIT; /* route dma interrupt to pci bus */ bits |= PLX_DMA_INTR_PCI_BIT; @@ -1311,11 +1377,10 @@ static void init_plx9080(struct comedi_device *dev) /* enable local burst mode */ bits |= PLX_DMA_LOCAL_BURST_EN_BIT; /* 4020 uses 32 bit dma */ - if (board(dev)->layout == LAYOUT_4020) { + if (board(dev)->layout == LAYOUT_4020) bits |= PLX_LOCAL_BUS_32_WIDE_BITS; - } else { /* localspace0 bus is 16 bits wide */ + else /* localspace0 bus is 16 bits wide */ bits |= PLX_LOCAL_BUS_16_WIDE_BITS; - } writel(bits, plx_iobase + PLX_DMA1_MODE_REG); if (ao_cmd_is_supported(board(dev))) writel(bits, plx_iobase + PLX_DMA0_MODE_REG); @@ -1363,7 +1428,8 @@ static int setup_subdevices(struct comedi_device *dev) s->cancel = ai_cancel; if (board(dev)->layout == LAYOUT_4020) { uint8_t data; - /* set adc to read from inputs (not internal calibration sources) */ + /* set adc to read from inputs + * (not internal calibration sources) */ devpriv->i2c_cal_range_bits = adc_src_4020_bits(4); /* set channels to +-5 volt input ranges */ for (i = 0; i < s->n_chan; i++) @@ -1376,8 +1442,8 @@ static int setup_subdevices(struct comedi_device *dev) s = &dev->subdevices[1]; if (board(dev)->ao_nchan) { s->type = COMEDI_SUBD_AO; - s->subdev_flags = - SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | + SDF_GROUND | SDF_CMD_WRITE; s->n_chan = board(dev)->ao_nchan; s->maxdata = (1 << board(dev)->ao_bits) - 1; s->range_table = board(dev)->ao_range_table; @@ -1422,13 +1488,12 @@ static int setup_subdevices(struct comedi_device *dev) s = &dev->subdevices[4]; if (board(dev)->has_8255) { if (board(dev)->layout == LAYOUT_4020) { - dio_8255_iobase = - devpriv->main_iobase + I8255_4020_REG; + dio_8255_iobase = devpriv->main_iobase + I8255_4020_REG; subdev_8255_init(dev, s, dio_callback_4020, (unsigned long)dio_8255_iobase); } else { dio_8255_iobase = - devpriv->dio_counter_iobase + DIO_8255_OFFSET; + devpriv->dio_counter_iobase + DIO_8255_OFFSET; subdev_8255_init(dev, s, dio_callback, (unsigned long)dio_8255_iobase); } @@ -1511,7 +1576,8 @@ static void init_stc_registers(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); - /* bit should be set for 6025, although docs say boards with <= 16 chans should be cleared XXX */ + /* bit should be set for 6025, + * although docs say boards with <= 16 chans should be cleared XXX */ if (1) devpriv->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT; writew(devpriv->adc_control1_bits, @@ -1538,8 +1604,9 @@ static void init_stc_registers(struct comedi_device *dev) board(dev)->ai_fifo->max_segment_length); devpriv->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT; - devpriv->intr_enable_bits = /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */ - EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT; + devpriv->intr_enable_bits = + /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */ + EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT; writew(devpriv->intr_enable_bits, devpriv->main_iobase + INTR_ENABLE_REG); @@ -1555,8 +1622,8 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) /* alocate pci dma buffers */ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { devpriv->ai_buffer[i] = - pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, - &devpriv->ai_buffer_bus_addr[i]); + pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, + &devpriv->ai_buffer_bus_addr[i]); if (devpriv->ai_buffer[i] == NULL) return -ENOMEM; @@ -1564,10 +1631,9 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) for (i = 0; i < AO_DMA_RING_COUNT; i++) { if (ao_cmd_is_supported(board(dev))) { devpriv->ao_buffer[i] = - pci_alloc_consistent(pcidev, - DMA_BUFFER_SIZE, - &devpriv-> - ao_buffer_bus_addr[i]); + pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, + &devpriv-> + ao_buffer_bus_addr[i]); if (devpriv->ao_buffer[i] == NULL) return -ENOMEM; @@ -1575,10 +1641,9 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) } /* allocate dma descriptors */ devpriv->ai_dma_desc = - pci_alloc_consistent(pcidev, - sizeof(struct plx_dma_desc) * - ai_dma_ring_count(board(dev)), - &devpriv->ai_dma_desc_bus_addr); + pci_alloc_consistent(pcidev, sizeof(struct plx_dma_desc) * + ai_dma_ring_count(board(dev)), + &devpriv->ai_dma_desc_bus_addr); if (devpriv->ai_dma_desc == NULL) return -ENOMEM; @@ -1586,10 +1651,10 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) (unsigned long long)devpriv->ai_dma_desc_bus_addr); if (ao_cmd_is_supported(board(dev))) { devpriv->ao_dma_desc = - pci_alloc_consistent(pcidev, - sizeof(struct plx_dma_desc) * - AO_DMA_RING_COUNT, - &devpriv->ao_dma_desc_bus_addr); + pci_alloc_consistent(pcidev, + sizeof(struct plx_dma_desc) * + AO_DMA_RING_COUNT, + &devpriv->ao_dma_desc_bus_addr); if (devpriv->ao_dma_desc == NULL) return -ENOMEM; @@ -1599,41 +1664,37 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) /* initialize dma descriptors */ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { devpriv->ai_dma_desc[i].pci_start_addr = - cpu_to_le32(devpriv->ai_buffer_bus_addr[i]); + cpu_to_le32(devpriv->ai_buffer_bus_addr[i]); if (board(dev)->layout == LAYOUT_4020) devpriv->ai_dma_desc[i].local_start_addr = - cpu_to_le32(devpriv->local1_iobase + - ADC_FIFO_REG); + cpu_to_le32(devpriv->local1_iobase + + ADC_FIFO_REG); else devpriv->ai_dma_desc[i].local_start_addr = - cpu_to_le32(devpriv->local0_iobase + - ADC_FIFO_REG); + cpu_to_le32(devpriv->local0_iobase + + ADC_FIFO_REG); devpriv->ai_dma_desc[i].transfer_size = cpu_to_le32(0); devpriv->ai_dma_desc[i].next = - cpu_to_le32((devpriv->ai_dma_desc_bus_addr + ((i + - 1) % - ai_dma_ring_count - (board - (dev))) * - sizeof(devpriv->ai_dma_desc[0])) | - PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | - PLX_XFER_LOCAL_TO_PCI); + cpu_to_le32((devpriv->ai_dma_desc_bus_addr + + ((i + 1) % ai_dma_ring_count(board(dev))) * + sizeof(devpriv->ai_dma_desc[0])) | + PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | + PLX_XFER_LOCAL_TO_PCI); } if (ao_cmd_is_supported(board(dev))) { for (i = 0; i < AO_DMA_RING_COUNT; i++) { devpriv->ao_dma_desc[i].pci_start_addr = - cpu_to_le32(devpriv->ao_buffer_bus_addr[i]); + cpu_to_le32(devpriv->ao_buffer_bus_addr[i]); devpriv->ao_dma_desc[i].local_start_addr = - cpu_to_le32(devpriv->local0_iobase + - DAC_FIFO_REG); - devpriv->ao_dma_desc[i].transfer_size = - cpu_to_le32(0); + cpu_to_le32(devpriv->local0_iobase + + DAC_FIFO_REG); + devpriv->ao_dma_desc[i].transfer_size = cpu_to_le32(0); devpriv->ao_dma_desc[i].next = - cpu_to_le32((devpriv->ao_dma_desc_bus_addr + - ((i + 1) % (AO_DMA_RING_COUNT)) * - sizeof(devpriv->ao_dma_desc[0])) | - PLX_DESC_IN_PCI_BIT | - PLX_INTR_TERM_COUNT); + cpu_to_le32((devpriv->ao_dma_desc_bus_addr + + ((i + 1) % (AO_DMA_RING_COUNT)) * + sizeof(devpriv->ao_dma_desc[0])) | + PLX_DESC_IN_PCI_BIT | + PLX_INTR_TERM_COUNT); } } return 0; @@ -1692,21 +1753,21 @@ static int __devinit auto_attach(struct comedi_device *dev, dev->iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX); devpriv->plx9080_phys_iobase = - pci_resource_start(pcidev, PLX9080_BADDRINDEX); + pci_resource_start(pcidev, PLX9080_BADDRINDEX); devpriv->main_phys_iobase = dev->iobase; devpriv->dio_counter_phys_iobase = - pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX); + pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX); /* remap, won't work with 2.0 kernels but who cares */ - devpriv->plx9080_iobase = ioremap(devpriv->plx9080_phys_iobase, - pci_resource_len(pcidev, - PLX9080_BADDRINDEX)); + devpriv->plx9080_iobase = + ioremap(devpriv->plx9080_phys_iobase, + pci_resource_len(pcidev, PLX9080_BADDRINDEX)); devpriv->main_iobase = - ioremap(devpriv->main_phys_iobase, - pci_resource_len(pcidev, MAIN_BADDRINDEX)); + ioremap(devpriv->main_phys_iobase, + pci_resource_len(pcidev, MAIN_BADDRINDEX)); devpriv->dio_counter_iobase = - ioremap(devpriv->dio_counter_phys_iobase, - pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX)); + ioremap(devpriv->dio_counter_phys_iobase, + pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX)); if (!devpriv->plx9080_iobase || !devpriv->main_iobase || !devpriv->dio_counter_iobase) { @@ -1720,22 +1781,18 @@ static int __devinit auto_attach(struct comedi_device *dev, devpriv->dio_counter_iobase); /* figure out what local addresses are */ - local_range = - readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) & LRNG_MEM_MASK; - local_decode = - readl(devpriv->plx9080_iobase + - PLX_LAS0MAP_REG) & local_range & LMAP_MEM_MASK; - devpriv->local0_iobase = - ((uint32_t) devpriv->main_phys_iobase & ~local_range) | - local_decode; - local_range = - readl(devpriv->plx9080_iobase + PLX_LAS1RNG_REG) & LRNG_MEM_MASK; - local_decode = - readl(devpriv->plx9080_iobase + - PLX_LAS1MAP_REG) & local_range & LMAP_MEM_MASK; - devpriv->local1_iobase = - ((uint32_t) devpriv->dio_counter_phys_iobase & ~local_range) | - local_decode; + local_range = readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) & + LRNG_MEM_MASK; + local_decode = readl(devpriv->plx9080_iobase + PLX_LAS0MAP_REG) & + local_range & LMAP_MEM_MASK; + devpriv->local0_iobase = ((uint32_t)devpriv->main_phys_iobase & + ~local_range) | local_decode; + local_range = readl(devpriv->plx9080_iobase + PLX_LAS1RNG_REG) & + LRNG_MEM_MASK; + local_decode = readl(devpriv->plx9080_iobase + PLX_LAS1MAP_REG) & + local_range & LMAP_MEM_MASK; + devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase & + ~local_range) | local_decode; DEBUG_PRINT(" local 0 io addr 0x%x\n", devpriv->local0_iobase); DEBUG_PRINT(" local 1 io addr 0x%x\n", devpriv->local1_iobase); @@ -1745,7 +1802,7 @@ static int __devinit auto_attach(struct comedi_device *dev, return retval; devpriv->hw_revision = - hw_revision(dev, readw(devpriv->main_iobase + HW_STATUS_REG)); + hw_revision(dev, readw(devpriv->main_iobase + HW_STATUS_REG)); dev_dbg(dev->class_dev, "stc hardware revision %i\n", devpriv->hw_revision); init_plx9080(dev); @@ -1764,7 +1821,6 @@ static int __devinit auto_attach(struct comedi_device *dev, if (retval < 0) return retval; - return 0; } @@ -1866,12 +1922,14 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, cal_en_bit = CAL_EN_60XX_BIT; else cal_en_bit = CAL_EN_64XX_BIT; - /* select internal reference source to connect to channel 0 */ + /* select internal reference source to connect + * to channel 0 */ writew(cal_en_bit | adc_src_bits(devpriv->calibration_source), devpriv->main_iobase + CALIBRATION_REG); } else { - /* make sure internal calibration source is turned off */ + /* make sure internal calibration source + * is turned off */ writew(0, devpriv->main_iobase + CALIBRATION_REG); } /* load internal queue */ @@ -1895,7 +1953,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, if (insn->chanspec & CR_ALT_SOURCE) { DEBUG_PRINT("reading calibration source\n"); devpriv->i2c_cal_range_bits |= - adc_src_4020_bits(devpriv->calibration_source); + adc_src_4020_bits(devpriv->calibration_source); } else { /* select BNC inputs */ devpriv->i2c_cal_range_bits |= adc_src_4020_bits(4); } @@ -1903,21 +1961,21 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, if (range == 0) devpriv->i2c_cal_range_bits |= attenuate_bit(channel); else - devpriv->i2c_cal_range_bits &= - ~attenuate_bit(channel); - /* update calibration/range i2c register only if necessary, as it is very slow */ + devpriv->i2c_cal_range_bits &= ~attenuate_bit(channel); + /* update calibration/range i2c register only if necessary, + * as it is very slow */ if (old_cal_range_bits != devpriv->i2c_cal_range_bits) { uint8_t i2c_data = devpriv->i2c_cal_range_bits; i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data, sizeof(i2c_data)); } - /* 4020 manual asks that sample interval register to be set before writing to convert register. - * Using somewhat arbitrary setting of 4 master clock ticks = 0.1 usec */ - writew(0, - devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); - writew(2, - devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); + /* 4020 manual asks that sample interval register to be set + * before writing to convert register. + * Using somewhat arbitrary setting of 4 master clock ticks + * = 0.1 usec */ + writew(0, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); + writew(2, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG); } for (n = 0; n < insn->n; n++) { @@ -1950,12 +2008,10 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, return -ETIME; } if (board(dev)->layout == LAYOUT_4020) - data[n] = - readl(devpriv->dio_counter_iobase + - ADC_FIFO_REG) & 0xffff; + data[n] = readl(devpriv->dio_counter_iobase + + ADC_FIFO_REG) & 0xffff; else - data[n] = - readw(devpriv->main_iobase + PIPE1_READ_REG); + data[n] = readw(devpriv->main_iobase + PIPE1_READ_REG); } return n; @@ -1994,8 +2050,8 @@ static int ai_config_block_size(struct comedi_device *dev, unsigned int *data) requested_block_size = data[1]; if (requested_block_size) { - fifo_size = - requested_block_size * fifo->num_segments / bytes_in_sample; + fifo_size = requested_block_size * fifo->num_segments / + bytes_in_sample; retval = set_ai_fifo_size(dev, fifo_size); if (retval < 0) @@ -2101,10 +2157,9 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, else triggers |= TRIG_EXT; err |= cfc_check_trigger_src(&cmd->convert_src, triggers); - err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); err |= cfc_check_trigger_src(&cmd->stop_src, - TRIG_COUNT | TRIG_EXT | TRIG_NONE); + TRIG_COUNT | TRIG_EXT | TRIG_NONE); if (err) return 1; @@ -2141,12 +2196,13 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, err++; } if (cmd->scan_begin_src == TRIG_TIMER) { - /* if scans are timed faster than conversion rate allows */ + /* if scans are timed faster than + * conversion rate allows */ if (cmd->convert_arg * cmd->chanlist_len > cmd->scan_begin_arg) { cmd->scan_begin_arg = - cmd->convert_arg * - cmd->chanlist_len; + cmd->convert_arg * + cmd->chanlist_len; err++; } } @@ -2272,9 +2328,8 @@ static inline unsigned int dma_transfer_size(struct comedi_device *dev) struct pcidas64_private *devpriv = dev->private; unsigned int num_samples; - num_samples = - devpriv->ai_fifo_segment_length * - board(dev)->ai_fifo->sample_packing_ratio; + num_samples = devpriv->ai_fifo_segment_length * + board(dev)->ai_fifo->sample_packing_ratio; if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t)) num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t); @@ -2306,9 +2361,9 @@ static void disable_ai_interrupts(struct comedi_device *dev) spin_lock_irqsave(&dev->spinlock, flags); devpriv->intr_enable_bits &= - ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT & - ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT & - ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK; + ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT & + ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT & + ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK; writew(devpriv->intr_enable_bits, devpriv->main_iobase + INTR_ENABLE_REG); spin_unlock_irqrestore(&dev->spinlock, flags); @@ -2324,8 +2379,9 @@ static void enable_ai_interrupts(struct comedi_device *dev, unsigned long flags; bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT | - EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT; - /* Use pio transfer and interrupt on end of conversion if TRIG_WAKE_EOS flag is set. */ + EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT; + /* Use pio transfer and interrupt on end of conversion + * if TRIG_WAKE_EOS flag is set. */ if (cmd->flags & TRIG_WAKE_EOS) { /* 4020 doesn't support pio transfers except for fifo dregs */ if (board(dev)->layout != LAYOUT_4020) @@ -2350,12 +2406,13 @@ static uint32_t ai_scan_counter_6xxx(struct comedi_device *dev, struct comedi_cmd *cmd) { uint32_t count; + /* figure out how long we need to delay at end of scan */ switch (cmd->scan_begin_src) { case TRIG_TIMER: count = (cmd->scan_begin_arg - - (cmd->convert_arg * (cmd->chanlist_len - 1))) - / TIMER_BASE; + (cmd->convert_arg * (cmd->chanlist_len - 1))) / + TIMER_BASE; break; case TRIG_FOLLOW: count = cmd->convert_arg / TIMER_BASE; @@ -2477,6 +2534,7 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) static int use_internal_queue_6xxx(const struct comedi_cmd *cmd) { int i; + for (i = 0; i + 1 < cmd->chanlist_len; i++) { if (CR_CHAN(cmd->chanlist[i + 1]) != CR_CHAN(cmd->chanlist[i]) + 1) @@ -2539,8 +2597,8 @@ static int setup_channel_queue(struct comedi_device *dev, for (i = 0; i < cmd->chanlist_len; i++) { bits = 0; /* set channel */ - bits |= - adc_chan_bits(CR_CHAN(cmd->chanlist[i])); + bits |= adc_chan_bits(CR_CHAN(cmd-> + chanlist[i])); /* set gain */ bits |= ai_range_bits_6xxx(dev, CR_RANGE(cmd-> @@ -2556,13 +2614,13 @@ static int setup_channel_queue(struct comedi_device *dev, /* mark end of queue */ if (i == cmd->chanlist_len - 1) bits |= QUEUE_EOSCAN_BIT | - QUEUE_EOSEQ_BIT; + QUEUE_EOSEQ_BIT; writew(bits, devpriv->main_iobase + ADC_QUEUE_FIFO_REG); - DEBUG_PRINT - ("wrote 0x%x to external channel queue\n", - bits); + DEBUG_PRINT( + "wrote 0x%x to external channel queue\n", + bits); } /* doing a queue clear is not specified in board docs, * but required for reliable operation */ @@ -2571,8 +2629,7 @@ static int setup_channel_queue(struct comedi_device *dev, writew(0, devpriv->main_iobase + ADC_QUEUE_LOAD_REG); } } else { - unsigned short old_cal_range_bits = - devpriv->i2c_cal_range_bits; + unsigned short old_cal_range_bits = devpriv->i2c_cal_range_bits; devpriv->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK; /* select BNC inputs */ @@ -2584,12 +2641,13 @@ static int setup_channel_queue(struct comedi_device *dev, if (range == 0) devpriv->i2c_cal_range_bits |= - attenuate_bit(channel); + attenuate_bit(channel); else devpriv->i2c_cal_range_bits &= - ~attenuate_bit(channel); + ~attenuate_bit(channel); } - /* update calibration/range i2c register only if necessary, as it is very slow */ + /* update calibration/range i2c register only if necessary, + * as it is very slow */ if (old_cal_range_bits != devpriv->i2c_cal_range_bits) { uint8_t i2c_data = devpriv->i2c_cal_range_bits; i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data, @@ -2662,9 +2720,11 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) if (board(dev)->layout != LAYOUT_4020) { devpriv->adc_control1_bits &= ~ADC_MODE_MASK; if (cmd->convert_src == TRIG_EXT) - devpriv->adc_control1_bits |= adc_mode_bits(13); /* good old mode 13 */ + /* good old mode 13 */ + devpriv->adc_control1_bits |= adc_mode_bits(13); else - devpriv->adc_control1_bits |= adc_mode_bits(8); /* mode 8. What else could you need? */ + /* mode 8. What else could you need? */ + devpriv->adc_control1_bits |= adc_mode_bits(8); } else { devpriv->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK; if (cmd->chanlist_len == 4) @@ -2673,12 +2733,11 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->adc_control1_bits |= TWO_CHANNEL_4020_BITS; devpriv->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK; devpriv->adc_control1_bits |= - adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0])); + adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0])); devpriv->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK; devpriv->adc_control1_bits |= - adc_hi_chan_4020_bits(CR_CHAN - (cmd-> - chanlist[cmd->chanlist_len - 1])); + adc_hi_chan_4020_bits(CR_CHAN(cmd->chanlist + [cmd->chanlist_len - 1])); } writew(devpriv->adc_control1_bits, devpriv->main_iobase + ADC_CONTROL1_REG); @@ -2695,8 +2754,8 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* set dma transfer size */ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) devpriv->ai_dma_desc[i].transfer_size = - cpu_to_le32(dma_transfer_size(dev) * - sizeof(uint16_t)); + cpu_to_le32(dma_transfer_size(dev) * + sizeof(uint16_t)); /* give location of first dma descriptor */ load_first_dma_descriptor(dev, 1, @@ -2763,18 +2822,19 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) do { /* get least significant 15 bits */ - read_index = - readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; - write_index = - readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; - /* Get most significant bits (grey code). Different boards use different code - * so use a scheme that doesn't depend on encoding. This read must + read_index = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & + 0x7fff; + write_index = readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & + 0x7fff; + /* Get most significant bits (grey code). + * Different boards use different code so use a scheme + * that doesn't depend on encoding. This read must * occur after reading least significant 15 bits to avoid race * with fifo switching to next segment. */ prepost_bits = readw(devpriv->main_iobase + PREPOST_REG); - /* if read and write pointers are not on the same fifo segment, read to the - * end of the read segment */ + /* if read and write pointers are not on the same fifo segment, + * read to the end of the read segment */ read_segment = adc_upper_read_ptr_code(prepost_bits); write_segment = adc_upper_write_ptr_code(prepost_bits); @@ -2784,7 +2844,7 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) if (read_segment != write_segment) num_samples = - devpriv->ai_fifo_segment_length - read_index; + devpriv->ai_fifo_segment_length - read_index; else num_samples = write_index - read_index; @@ -2814,10 +2874,10 @@ static void pio_drain_ai_fifo_16(struct comedi_device *dev) } while (read_segment != write_segment); } -/* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of pointers. - * The pci-4020 hardware only supports - * dma transfers (it only supports the use of pio for draining the last remaining - * points from the fifo when a data acquisition operation has completed). +/* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of + * pointers. The pci-4020 hardware only supports dma transfers (it only + * supports the use of pio for draining the last remaining points from the + * fifo when a data acquisition operation has completed). */ static void pio_drain_ai_fifo_32(struct comedi_device *dev) { @@ -2829,9 +2889,9 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) unsigned int max_transfer = 100000; uint32_t fifo_data; int write_code = - readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; + readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff; int read_code = - readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; + readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; if (cmd->stop_src == TRIG_COUNT) { if (max_transfer > devpriv->ai_count) @@ -2846,8 +2906,8 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) cfc_write_to_buffer(s, (fifo_data >> 16) & 0xffff); i++; } - read_code = - readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & 0x7fff; + read_code = readw(devpriv->main_iobase + ADC_READ_PNTR_REG) & + 0x7fff; } devpriv->ai_count -= i; } @@ -2880,8 +2940,8 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) /* loop until we have read all the full buffers */ for (j = 0, next_transfer_addr = readl(pci_addr_reg); (next_transfer_addr < - devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] - || next_transfer_addr >= + devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] || + next_transfer_addr >= devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] + DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board(dev)); j++) { /* transfer data from dma buffer to comedi buffer */ @@ -2893,19 +2953,18 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) } cfc_write_array_to_buffer(dev->read_subdev, devpriv->ai_buffer[devpriv-> - ai_dma_index], + ai_dma_index], num_samples * sizeof(uint16_t)); - devpriv->ai_dma_index = - (devpriv->ai_dma_index + - 1) % ai_dma_ring_count(board(dev)); + devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) % + ai_dma_ring_count(board(dev)); DEBUG_PRINT("next buffer addr 0x%lx\n", (unsigned long)devpriv-> ai_buffer_bus_addr[devpriv->ai_dma_index]); DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr); } - /* XXX check for dma ring buffer overrun (use end-of-chain bit to mark last - * unused buffer) */ + /* XXX check for dma ring buffer overrun + * (use end-of-chain bit to mark last unused buffer) */ } static void handle_ai_interrupt(struct comedi_device *dev, @@ -2989,7 +3048,7 @@ static int last_ao_dma_load_completed(struct comedi_device *dev) return 0; transfer_address = - readl(devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); + readl(devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG); if (transfer_address != devpriv->ao_buffer_bus_addr[buffer_index]) return 0; @@ -3030,7 +3089,7 @@ static void restart_ao_dma(struct comedi_device *dev) unsigned int dma_desc_bits; dma_desc_bits = - readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); + readl(devpriv->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG); dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT; DEBUG_PRINT("restarting ao dma, descriptor reg 0x%x\n", dma_desc_bits); load_first_dma_descriptor(dev, 0, dma_desc_bits); @@ -3058,8 +3117,8 @@ static void handle_ao_interrupt(struct comedi_device *dev, spin_lock_irqsave(&dev->spinlock, flags); dma0_status = readb(devpriv->plx9080_iobase + PLX_DMA0_CS_REG); if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */ - if ((dma0_status & PLX_DMA_EN_BIT) - && !(dma0_status & PLX_DMA_DONE_BIT)) + if ((dma0_status & PLX_DMA_EN_BIT) && + !(dma0_status & PLX_DMA_DONE_BIT)) writeb(PLX_DMA_EN_BIT | PLX_CLEAR_DMA_INTR_BIT, devpriv->plx9080_iobase + PLX_DMA0_CS_REG); else @@ -3074,8 +3133,9 @@ static void handle_ao_interrupt(struct comedi_device *dev, restart_ao_dma(dev); } DEBUG_PRINT(" cleared dma ch0 interrupt\n"); - } else + } else { spin_unlock_irqrestore(&dev->spinlock, flags); + } if ((status & DAC_DONE_BIT)) { async->events |= COMEDI_CB_EOA; @@ -3207,7 +3267,7 @@ static void set_dac_control0_reg(struct comedi_device *dev, { struct pcidas64_private *devpriv = dev->private; unsigned int bits = DAC_ENABLE_BIT | WAVEFORM_GATE_LEVEL_BIT | - WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT; + WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT; if (cmd->start_src == TRIG_EXT) { bits |= WAVEFORM_TRIG_EXT_BITS; @@ -3311,7 +3371,7 @@ static unsigned int load_ao_dma_buffer(struct comedi_device *dev, ao_buffer[buffer_index], num_bytes); devpriv->ao_dma_desc[buffer_index].transfer_size = - cpu_to_le32(num_bytes); + cpu_to_le32(num_bytes); /* set end of chain bit so we catch underruns */ next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next); next_bits |= PLX_END_OF_CHAIN_BIT; @@ -3334,7 +3394,7 @@ static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) unsigned int num_bytes; unsigned int next_transfer_addr; void __iomem *pci_addr_reg = - devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; + devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; unsigned int buffer_index; do { @@ -3342,8 +3402,8 @@ static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) /* don't overwrite data that hasn't been transferred yet */ next_transfer_addr = readl(pci_addr_reg); if (next_transfer_addr >= - devpriv->ao_buffer_bus_addr[buffer_index] - && next_transfer_addr < + devpriv->ao_buffer_bus_addr[buffer_index] && + next_transfer_addr < devpriv->ao_buffer_bus_addr[buffer_index] + DMA_BUFFER_SIZE) return; @@ -3459,7 +3519,7 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT); err |= cfc_check_trigger_src(&cmd->scan_begin_src, - TRIG_TIMER | TRIG_EXT); + TRIG_TIMER | TRIG_EXT); err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); @@ -3492,8 +3552,8 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, } if (get_ao_divisor(cmd->scan_begin_arg, cmd->flags) > max_counter_value) { - cmd->scan_begin_arg = - (max_counter_value + 2) * TIMER_BASE; + cmd->scan_begin_arg = (max_counter_value + 2) * + TIMER_BASE; err++; } } @@ -3514,8 +3574,8 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (cmd->scan_begin_src == TRIG_TIMER) { tmp_arg = cmd->scan_begin_arg; - cmd->scan_begin_arg = - get_divisor(cmd->scan_begin_arg, cmd->flags) * TIMER_BASE; + cmd->scan_begin_arg = get_divisor(cmd->scan_begin_arg, + cmd->flags) * TIMER_BASE; if (tmp_arg != cmd->scan_begin_arg) err++; } @@ -3771,7 +3831,7 @@ static uint16_t read_eeprom(struct comedi_device *dev, uint8_t address) unsigned int bitstream = (read_command << 8) | address; unsigned int bit; void __iomem * const plx_control_addr = - devpriv->plx9080_iobase + PLX_CONTROL_REG; + devpriv->plx9080_iobase + PLX_CONTROL_REG; uint16_t value; static const int value_length = 16; static const int eeprom_udelay = 1; @@ -3844,7 +3904,7 @@ static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) unsigned int convert_divisor = 0, scan_divisor; static const int min_convert_divisor = 3; static const int max_convert_divisor = - max_counter_value + min_convert_divisor; + max_counter_value + min_convert_divisor; static const int min_scan_divisor_4020 = 2; unsigned long long max_scan_divisor, min_scan_divisor; @@ -3852,16 +3912,17 @@ static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) if (board(dev)->layout == LAYOUT_4020) { cmd->convert_arg = 0; } else { - convert_divisor = - get_divisor(cmd->convert_arg, cmd->flags); + convert_divisor = get_divisor(cmd->convert_arg, + cmd->flags); if (convert_divisor > max_convert_divisor) convert_divisor = max_convert_divisor; if (convert_divisor < min_convert_divisor) convert_divisor = min_convert_divisor; cmd->convert_arg = convert_divisor * TIMER_BASE; } - } else if (cmd->convert_src == TRIG_NOW) + } else if (cmd->convert_src == TRIG_NOW) { cmd->convert_arg = 0; + } if (cmd->scan_begin_src == TRIG_TIMER) { scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags); @@ -3869,8 +3930,8 @@ static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) /* XXX check for integer overflows */ min_scan_divisor = convert_divisor * cmd->chanlist_len; max_scan_divisor = - (convert_divisor * cmd->chanlist_len - 1) + - max_counter_value; + (convert_divisor * cmd->chanlist_len - 1) + + max_counter_value; } else { min_scan_divisor = min_scan_divisor_4020; max_scan_divisor = max_counter_value + min_scan_divisor; @@ -3940,8 +4001,8 @@ static unsigned int ai_fifo_size(struct comedi_device *dev) struct pcidas64_private *devpriv = dev->private; return devpriv->ai_fifo_segment_length * - board(dev)->ai_fifo->num_segments * - board(dev)->ai_fifo->sample_packing_ratio; + board(dev)->ai_fifo->num_segments * + board(dev)->ai_fifo->sample_packing_ratio; } static int set_ai_fifo_segment_length(struct comedi_device *dev, @@ -4187,7 +4248,8 @@ static void i2c_write(struct comedi_device *dev, unsigned int address, uint8_t bitstream; static const int read_bit = 0x1; -/* XXX need mutex to prevent simultaneous attempts to access eeprom and i2c bus */ + /* XXX need mutex to prevent simultaneous attempts to access + * eeprom and i2c bus */ /* make sure we dont send anything to eeprom */ devpriv->plx_control_bits &= ~CTL_EE_CS; -- cgit v1.2.3 From 4dba6c02cd2bd4714db4f0ccd3ebc3983ff0e039 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 19:18:00 +0000 Subject: staging: comedi: comedidev.h: make comedi_board() parameter const The inline function `comedi_board(dev)` merely returns `dev->board_ptr`. It does not modify any members of `*dev` so make its parameter a const pointer. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 4ac2de43cdb..5af3579337e 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -247,7 +247,7 @@ struct comedi_device { void (*close) (struct comedi_device *dev); }; -static inline const void *comedi_board(struct comedi_device *dev) +static inline const void *comedi_board(const struct comedi_device *dev) { return dev->board_ptr; } -- cgit v1.2.3 From b07244ceeadd30be344cb49f9bc96f8b8b36a6a4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 19:18:01 +0000 Subject: staging: comedi: cb_pcidas64: remove board(dev) inline The `board(dev)` inline function returns `dev->board_ptr` cast from `const void *` to `struct pcidas64_board *`. It really ought to return a `const struct pcidas64_board *`. Rather than fix the function, just remove it and replace the calls with a local variable `thisboard` in the functions that call it. `thisboard` is set to the result of the common inline function `comedi_board(dev)` defined in "comedidev.h". Fix a little resulting fall-out from the inline function `ai_dma_ring_count(board)` whose parameter should have been a const pointer. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 195 ++++++++++++++++----------- 1 file changed, 114 insertions(+), 81 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index c95756f0eb6..803220be6b2 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -635,7 +635,7 @@ static const struct hw_fifo_info ai_fifo_60xx = { #define MAX_AI_DMA_RING_COUNT (0x80000 / DMA_BUFFER_SIZE) #define MIN_AI_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE) #define AO_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE) -static inline unsigned int ai_dma_ring_count(struct pcidas64_board *board) +static inline unsigned int ai_dma_ring_count(const struct pcidas64_board *board) { if (board->layout == LAYOUT_4020) return MAX_AI_DMA_RING_COUNT; @@ -1064,16 +1064,13 @@ static const struct pcidas64_board pcidas64_boards[] = { #endif }; -static inline struct pcidas64_board *board(const struct comedi_device *dev) -{ - return (struct pcidas64_board *)dev->board_ptr; -} - static inline unsigned short se_diff_bit_6xxx(struct comedi_device *dev, int use_differential) { - if ((board(dev)->layout == LAYOUT_64XX && !use_differential) || - (board(dev)->layout == LAYOUT_60XX && use_differential)) + const struct pcidas64_board *thisboard = comedi_board(dev); + + if ((thisboard->layout == LAYOUT_64XX && !use_differential) || + (thisboard->layout == LAYOUT_60XX && use_differential)) return ADC_SE_DIFF_BIT; else return 0; @@ -1232,8 +1229,9 @@ static void load_ao_dma(struct comedi_device *dev, static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev, unsigned int range_index) { + const struct pcidas64_board *thisboard = comedi_board(dev); const struct comedi_krange *range = - &board(dev)->ai_range_table->range[range_index]; + &thisboard->ai_range_table->range[range_index]; unsigned int bits = 0; switch (range->max) { @@ -1276,7 +1274,9 @@ static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev, static unsigned int hw_revision(const struct comedi_device *dev, uint16_t hw_status_bits) { - if (board(dev)->layout == LAYOUT_4020) + const struct pcidas64_board *thisboard = comedi_board(dev); + + if (thisboard->layout == LAYOUT_4020) return (hw_status_bits >> 13) & 0x7; return (hw_status_bits >> 12) & 0xf; @@ -1286,7 +1286,8 @@ static void set_dac_range_bits(struct comedi_device *dev, volatile uint16_t *bits, unsigned int channel, unsigned int range) { - unsigned int code = board(dev)->ao_range_code[range]; + const struct pcidas64_board *thisboard = comedi_board(dev); + unsigned int code = thisboard->ao_range_code[range]; if (channel > 1) comedi_error(dev, "bug! bad channel?"); @@ -1305,6 +1306,7 @@ static inline int ao_cmd_is_supported(const struct pcidas64_board *board) /* initialize plx9080 chip */ static void init_plx9080(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; uint32_t bits; void __iomem *plx_iobase = devpriv->plx9080_iobase; @@ -1377,12 +1379,12 @@ static void init_plx9080(struct comedi_device *dev) /* enable local burst mode */ bits |= PLX_DMA_LOCAL_BURST_EN_BIT; /* 4020 uses 32 bit dma */ - if (board(dev)->layout == LAYOUT_4020) + if (thisboard->layout == LAYOUT_4020) bits |= PLX_LOCAL_BUS_32_WIDE_BITS; else /* localspace0 bus is 16 bits wide */ bits |= PLX_LOCAL_BUS_16_WIDE_BITS; writel(bits, plx_iobase + PLX_DMA1_MODE_REG); - if (ao_cmd_is_supported(board(dev))) + if (ao_cmd_is_supported(thisboard)) writel(bits, plx_iobase + PLX_DMA0_MODE_REG); /* enable interrupts on plx 9080 */ @@ -1397,6 +1399,7 @@ static void init_plx9080(struct comedi_device *dev) */ static int setup_subdevices(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s; void __iomem *dio_8255_iobase; @@ -1412,21 +1415,21 @@ static int setup_subdevices(struct comedi_device *dev) dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ; - if (board(dev)->layout == LAYOUT_60XX) + if (thisboard->layout == LAYOUT_60XX) s->subdev_flags |= SDF_COMMON | SDF_DIFF; - else if (board(dev)->layout == LAYOUT_64XX) + else if (thisboard->layout == LAYOUT_64XX) s->subdev_flags |= SDF_DIFF; /* XXX Number of inputs in differential mode is ignored */ - s->n_chan = board(dev)->ai_se_chans; + s->n_chan = thisboard->ai_se_chans; s->len_chanlist = 0x2000; - s->maxdata = (1 << board(dev)->ai_bits) - 1; - s->range_table = board(dev)->ai_range_table; + s->maxdata = (1 << thisboard->ai_bits) - 1; + s->range_table = thisboard->ai_range_table; s->insn_read = ai_rinsn; s->insn_config = ai_config_insn; s->do_cmd = ai_cmd; s->do_cmdtest = ai_cmdtest; s->cancel = ai_cancel; - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->layout == LAYOUT_4020) { uint8_t data; /* set adc to read from inputs * (not internal calibration sources) */ @@ -1440,20 +1443,20 @@ static int setup_subdevices(struct comedi_device *dev) /* analog output subdevice */ s = &dev->subdevices[1]; - if (board(dev)->ao_nchan) { + if (thisboard->ao_nchan) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; - s->n_chan = board(dev)->ao_nchan; - s->maxdata = (1 << board(dev)->ao_bits) - 1; - s->range_table = board(dev)->ao_range_table; + s->n_chan = thisboard->ao_nchan; + s->maxdata = (1 << thisboard->ao_bits) - 1; + s->range_table = thisboard->ao_range_table; s->insn_read = ao_readback_insn; s->insn_write = ao_winsn; - if (ao_cmd_is_supported(board(dev))) { + if (ao_cmd_is_supported(thisboard)) { dev->write_subdev = s; s->do_cmdtest = ao_cmdtest; s->do_cmd = ao_cmd; - s->len_chanlist = board(dev)->ao_nchan; + s->len_chanlist = thisboard->ao_nchan; s->cancel = ao_cancel; } } else { @@ -1462,7 +1465,7 @@ static int setup_subdevices(struct comedi_device *dev) /* digital input */ s = &dev->subdevices[2]; - if (board(dev)->layout == LAYOUT_64XX) { + if (thisboard->layout == LAYOUT_64XX) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 4; @@ -1473,7 +1476,7 @@ static int setup_subdevices(struct comedi_device *dev) s->type = COMEDI_SUBD_UNUSED; /* digital output */ - if (board(dev)->layout == LAYOUT_64XX) { + if (thisboard->layout == LAYOUT_64XX) { s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; @@ -1486,8 +1489,8 @@ static int setup_subdevices(struct comedi_device *dev) /* 8255 */ s = &dev->subdevices[4]; - if (board(dev)->has_8255) { - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->has_8255) { + if (thisboard->layout == LAYOUT_4020) { dio_8255_iobase = devpriv->main_iobase + I8255_4020_REG; subdev_8255_init(dev, s, dio_callback_4020, (unsigned long)dio_8255_iobase); @@ -1502,7 +1505,7 @@ static int setup_subdevices(struct comedi_device *dev) /* 8 channel dio for 60xx */ s = &dev->subdevices[5]; - if (board(dev)->layout == LAYOUT_60XX) { + if (thisboard->layout == LAYOUT_60XX) { s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_WRITABLE | SDF_READABLE; s->n_chan = 8; @@ -1518,7 +1521,7 @@ static int setup_subdevices(struct comedi_device *dev) s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; s->n_chan = 8; - if (board(dev)->layout == LAYOUT_4020) + if (thisboard->layout == LAYOUT_4020) s->maxdata = 0xfff; else s->maxdata = 0xff; @@ -1529,7 +1532,7 @@ static int setup_subdevices(struct comedi_device *dev) /* 2 channel ad8402 potentiometer */ s = &dev->subdevices[7]; - if (board(dev)->layout == LAYOUT_64XX) { + if (thisboard->layout == LAYOUT_64XX) { s->type = COMEDI_SUBD_CALIB; s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; s->n_chan = 2; @@ -1570,6 +1573,7 @@ static void disable_plx_interrupts(struct comedi_device *dev) static void init_stc_registers(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; uint16_t bits; unsigned long flags; @@ -1587,7 +1591,7 @@ static void init_stc_registers(struct comedi_device *dev) writew(0xff, devpriv->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG); bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT; - if (board(dev)->layout == LAYOUT_4020) + if (thisboard->layout == LAYOUT_4020) bits |= INTERNAL_CLOCK_4020_BITS; devpriv->hw_config_bits |= bits; writew(devpriv->hw_config_bits, @@ -1601,7 +1605,7 @@ static void init_stc_registers(struct comedi_device *dev) /* set fifos to maximum size */ devpriv->fifo_size_bits |= DAC_FIFO_BITS; set_ai_fifo_segment_length(dev, - board(dev)->ai_fifo->max_segment_length); + thisboard->ai_fifo->max_segment_length); devpriv->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT; devpriv->intr_enable_bits = @@ -1615,12 +1619,13 @@ static void init_stc_registers(struct comedi_device *dev) static int alloc_and_init_dma_members(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct pcidas64_private *devpriv = dev->private; int i; /* alocate pci dma buffers */ - for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { + for (i = 0; i < ai_dma_ring_count(thisboard); i++) { devpriv->ai_buffer[i] = pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, &devpriv->ai_buffer_bus_addr[i]); @@ -1629,7 +1634,7 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) } for (i = 0; i < AO_DMA_RING_COUNT; i++) { - if (ao_cmd_is_supported(board(dev))) { + if (ao_cmd_is_supported(thisboard)) { devpriv->ao_buffer[i] = pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE, &devpriv-> @@ -1642,14 +1647,14 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) /* allocate dma descriptors */ devpriv->ai_dma_desc = pci_alloc_consistent(pcidev, sizeof(struct plx_dma_desc) * - ai_dma_ring_count(board(dev)), + ai_dma_ring_count(thisboard), &devpriv->ai_dma_desc_bus_addr); if (devpriv->ai_dma_desc == NULL) return -ENOMEM; DEBUG_PRINT("ai dma descriptors start at bus addr 0x%llx\n", (unsigned long long)devpriv->ai_dma_desc_bus_addr); - if (ao_cmd_is_supported(board(dev))) { + if (ao_cmd_is_supported(thisboard)) { devpriv->ao_dma_desc = pci_alloc_consistent(pcidev, sizeof(struct plx_dma_desc) * @@ -1662,10 +1667,10 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) (unsigned long long)devpriv->ao_dma_desc_bus_addr); } /* initialize dma descriptors */ - for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { + for (i = 0; i < ai_dma_ring_count(thisboard); i++) { devpriv->ai_dma_desc[i].pci_start_addr = cpu_to_le32(devpriv->ai_buffer_bus_addr[i]); - if (board(dev)->layout == LAYOUT_4020) + if (thisboard->layout == LAYOUT_4020) devpriv->ai_dma_desc[i].local_start_addr = cpu_to_le32(devpriv->local1_iobase + ADC_FIFO_REG); @@ -1676,12 +1681,12 @@ static int alloc_and_init_dma_members(struct comedi_device *dev) devpriv->ai_dma_desc[i].transfer_size = cpu_to_le32(0); devpriv->ai_dma_desc[i].next = cpu_to_le32((devpriv->ai_dma_desc_bus_addr + - ((i + 1) % ai_dma_ring_count(board(dev))) * + ((i + 1) % ai_dma_ring_count(thisboard)) * sizeof(devpriv->ai_dma_desc[0])) | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI); } - if (ao_cmd_is_supported(board(dev))) { + if (ao_cmd_is_supported(thisboard)) { for (i = 0; i < AO_DMA_RING_COUNT; i++) { devpriv->ao_dma_desc[i].pci_start_addr = cpu_to_le32(devpriv->ao_buffer_bus_addr[i]); @@ -1722,6 +1727,7 @@ static const struct pcidas64_board static int __devinit auto_attach(struct comedi_device *dev, unsigned long context_unused) { + const struct pcidas64_board *thisboard; struct pcidas64_private *devpriv; struct pci_dev *pcidev = comedi_to_pci_dev(dev); uint32_t local_range, local_decode; @@ -1734,6 +1740,7 @@ static int __devinit auto_attach(struct comedi_device *dev, pci_name(pcidev)); return -EINVAL; } + thisboard = comedi_board(dev); devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) @@ -1748,7 +1755,7 @@ static int __devinit auto_attach(struct comedi_device *dev, pci_set_master(pcidev); /* Initialize dev->board_name */ - dev->board_name = board(dev)->name; + dev->board_name = thisboard->name; dev->iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX); @@ -1826,6 +1833,7 @@ static int __devinit auto_attach(struct comedi_device *dev, static void detach(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct pcidas64_private *devpriv = dev->private; unsigned int i; @@ -1843,7 +1851,7 @@ static void detach(struct comedi_device *dev) if (devpriv->dio_counter_iobase) iounmap(devpriv->dio_counter_iobase); /* free pci dma buffers */ - for (i = 0; i < ai_dma_ring_count(board(dev)); i++) { + for (i = 0; i < ai_dma_ring_count(thisboard); i++) { if (devpriv->ai_buffer[i]) pci_free_consistent(pcidev, DMA_BUFFER_SIZE, @@ -1861,7 +1869,7 @@ static void detach(struct comedi_device *dev) if (devpriv->ai_dma_desc) pci_free_consistent(pcidev, sizeof(struct plx_dma_desc) * - ai_dma_ring_count(board(dev)), + ai_dma_ring_count(thisboard), devpriv->ai_dma_desc, devpriv->ai_dma_desc_bus_addr); if (devpriv->ao_dma_desc) @@ -1883,6 +1891,7 @@ static void detach(struct comedi_device *dev) static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; unsigned int bits = 0, n, i; unsigned int channel, range, aref; @@ -1907,7 +1916,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, devpriv->main_iobase + ADC_CONTROL1_REG); spin_unlock_irqrestore(&dev->spinlock, flags); - if (board(dev)->layout != LAYOUT_4020) { + if (thisboard->layout != LAYOUT_4020) { /* use internal queue */ devpriv->hw_config_bits &= ~EXT_QUEUE_BIT; writew(devpriv->hw_config_bits, @@ -1918,7 +1927,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int cal_en_bit; DEBUG_PRINT("reading calibration source\n"); - if (board(dev)->layout == LAYOUT_60XX) + if (thisboard->layout == LAYOUT_60XX) cal_en_bit = CAL_EN_60XX_BIT; else cal_en_bit = CAL_EN_64XX_BIT; @@ -1991,7 +2000,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, for (i = 0; i < timeout; i++) { bits = readw(devpriv->main_iobase + HW_STATUS_REG); DEBUG_PRINT(" pipe bits 0x%x\n", pipe_full_bits(bits)); - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->layout == LAYOUT_4020) { if (readw(devpriv->main_iobase + ADC_WRITE_PNTR_REG)) break; @@ -2007,7 +2016,7 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, dev_info(dev->class_dev, "status 0x%x\n", bits); return -ETIME; } - if (board(dev)->layout == LAYOUT_4020) + if (thisboard->layout == LAYOUT_4020) data[n] = readl(devpriv->dio_counter_iobase + ADC_FIFO_REG) & 0xffff; else @@ -2020,11 +2029,12 @@ static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static int ai_config_calibration_source(struct comedi_device *dev, unsigned int *data) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; unsigned int source = data[1]; int num_calibration_sources; - if (board(dev)->layout == LAYOUT_60XX) + if (thisboard->layout == LAYOUT_60XX) num_calibration_sources = 16; else num_calibration_sources = 8; @@ -2042,8 +2052,9 @@ static int ai_config_calibration_source(struct comedi_device *dev, static int ai_config_block_size(struct comedi_device *dev, unsigned int *data) { + const struct pcidas64_board *thisboard = comedi_board(dev); int fifo_size; - const struct hw_fifo_info *const fifo = board(dev)->ai_fifo; + const struct hw_fifo_info *const fifo = thisboard->ai_fifo; unsigned int block_size, requested_block_size; int retval; @@ -2096,8 +2107,9 @@ static int ai_config_master_clock_4020(struct comedi_device *dev, /* XXX could add support for 60xx series */ static int ai_config_master_clock(struct comedi_device *dev, unsigned int *data) { + const struct pcidas64_board *thisboard = comedi_board(dev); - switch (board(dev)->layout) { + switch (thisboard->layout) { case LAYOUT_4020: return ai_config_master_clock_4020(dev, data); break; @@ -2134,6 +2146,7 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct pcidas64_board *thisboard = comedi_board(dev); int err = 0; unsigned int tmp_arg, tmp_arg2; int i; @@ -2145,14 +2158,14 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); triggers = TRIG_TIMER; - if (board(dev)->layout == LAYOUT_4020) + if (thisboard->layout == LAYOUT_4020) triggers |= TRIG_OTHER; else triggers |= TRIG_FOLLOW; err |= cfc_check_trigger_src(&cmd->scan_begin_src, triggers); triggers = TRIG_TIMER; - if (board(dev)->layout == LAYOUT_4020) + if (thisboard->layout == LAYOUT_4020) triggers |= TRIG_NOW; else triggers |= TRIG_EXT; @@ -2185,14 +2198,14 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, /* step 3: make sure arguments are trivially compatible */ if (cmd->convert_src == TRIG_TIMER) { - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->layout == LAYOUT_4020) { if (cmd->convert_arg) { cmd->convert_arg = 0; err++; } } else { - if (cmd->convert_arg < board(dev)->ai_speed) { - cmd->convert_arg = board(dev)->ai_speed; + if (cmd->convert_arg < thisboard->ai_speed) { + cmd->convert_arg = thisboard->ai_speed; err++; } if (cmd->scan_begin_src == TRIG_TIMER) { @@ -2267,7 +2280,7 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, } } /* check 4020 chanlist */ - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->layout == LAYOUT_4020) { unsigned int first_channel = CR_CHAN(cmd->chanlist[0]); for (i = 1; i < cmd->chanlist_len; i++) { if (CR_CHAN(cmd->chanlist[i]) != @@ -2325,11 +2338,12 @@ static void setup_sample_counters(struct comedi_device *dev, static inline unsigned int dma_transfer_size(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; unsigned int num_samples; num_samples = devpriv->ai_fifo_segment_length * - board(dev)->ai_fifo->sample_packing_ratio; + thisboard->ai_fifo->sample_packing_ratio; if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t)) num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t); @@ -2374,6 +2388,7 @@ static void disable_ai_interrupts(struct comedi_device *dev) static void enable_ai_interrupts(struct comedi_device *dev, const struct comedi_cmd *cmd) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; uint32_t bits; unsigned long flags; @@ -2384,7 +2399,7 @@ static void enable_ai_interrupts(struct comedi_device *dev, * if TRIG_WAKE_EOS flag is set. */ if (cmd->flags & TRIG_WAKE_EOS) { /* 4020 doesn't support pio transfers except for fifo dregs */ - if (board(dev)->layout != LAYOUT_4020) + if (thisboard->layout != LAYOUT_4020) bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT; } spin_lock_irqsave(&dev->spinlock, flags); @@ -2471,7 +2486,9 @@ static void select_master_clock_4020(struct comedi_device *dev, static void select_master_clock(struct comedi_device *dev, const struct comedi_cmd *cmd) { - switch (board(dev)->layout) { + const struct pcidas64_board *thisboard = comedi_board(dev); + + switch (thisboard->layout) { case LAYOUT_4020: select_master_clock_4020(dev, cmd); break; @@ -2501,6 +2518,7 @@ static inline void dma_start_sync(struct comedi_device *dev, static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; uint32_t convert_counter = 0, scan_counter = 0; @@ -2508,7 +2526,7 @@ static void set_ai_pacing(struct comedi_device *dev, struct comedi_cmd *cmd) select_master_clock(dev, cmd); - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->layout == LAYOUT_4020) { convert_counter = ai_convert_counter_4020(dev, cmd); } else { convert_counter = ai_convert_counter_6xxx(dev, cmd); @@ -2551,11 +2569,12 @@ static int use_internal_queue_6xxx(const struct comedi_cmd *cmd) static int setup_channel_queue(struct comedi_device *dev, const struct comedi_cmd *cmd) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; unsigned short bits; int i; - if (board(dev)->layout != LAYOUT_4020) { + if (thisboard->layout != LAYOUT_4020) { if (use_internal_queue_6xxx(cmd)) { devpriv->hw_config_bits &= ~EXT_QUEUE_BIT; writew(devpriv->hw_config_bits, @@ -2689,6 +2708,7 @@ static inline void load_first_dma_descriptor(struct comedi_device *dev, static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; struct comedi_async *async = s->async; struct comedi_cmd *cmd = &async->cmd; @@ -2717,7 +2737,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* set mode, allow conversions through software gate */ devpriv->adc_control1_bits |= ADC_SW_GATE_BIT; devpriv->adc_control1_bits &= ~ADC_DITHER_BIT; - if (board(dev)->layout != LAYOUT_4020) { + if (thisboard->layout != LAYOUT_4020) { devpriv->adc_control1_bits &= ~ADC_MODE_MASK; if (cmd->convert_src == TRIG_EXT) /* good old mode 13 */ @@ -2748,11 +2768,11 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) writew(0, devpriv->main_iobase + ADC_BUFFER_CLEAR_REG); if ((cmd->flags & TRIG_WAKE_EOS) == 0 || - board(dev)->layout == LAYOUT_4020) { + thisboard->layout == LAYOUT_4020) { devpriv->ai_dma_index = 0; /* set dma transfer size */ - for (i = 0; i < ai_dma_ring_count(board(dev)); i++) + for (i = 0; i < ai_dma_ring_count(thisboard); i++) devpriv->ai_dma_desc[i].transfer_size = cpu_to_le32(dma_transfer_size(dev) * sizeof(uint16_t)); @@ -2767,7 +2787,7 @@ static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) dma_start_sync(dev, 1); } - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->layout == LAYOUT_4020) { /* set source for external triggers */ bits = 0; if (cmd->start_src == TRIG_EXT && CR_CHAN(cmd->start_arg)) @@ -2915,7 +2935,9 @@ static void pio_drain_ai_fifo_32(struct comedi_device *dev) /* empty fifo */ static void pio_drain_ai_fifo(struct comedi_device *dev) { - if (board(dev)->layout == LAYOUT_4020) + const struct pcidas64_board *thisboard = comedi_board(dev); + + if (thisboard->layout == LAYOUT_4020) pio_drain_ai_fifo_32(dev); else pio_drain_ai_fifo_16(dev); @@ -2923,6 +2945,7 @@ static void pio_drain_ai_fifo(struct comedi_device *dev) static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; struct comedi_async *async = dev->read_subdev->async; uint32_t next_transfer_addr; @@ -2943,7 +2966,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] || next_transfer_addr >= devpriv->ai_buffer_bus_addr[devpriv->ai_dma_index] + - DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board(dev)); j++) { + DMA_BUFFER_SIZE) && j < ai_dma_ring_count(thisboard); j++) { /* transfer data from dma buffer to comedi buffer */ num_samples = dma_transfer_size(dev); if (async->cmd.stop_src == TRIG_COUNT) { @@ -2956,7 +2979,7 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel) ai_dma_index], num_samples * sizeof(uint16_t)); devpriv->ai_dma_index = (devpriv->ai_dma_index + 1) % - ai_dma_ring_count(board(dev)); + ai_dma_ring_count(thisboard); DEBUG_PRINT("next buffer addr 0x%lx\n", (unsigned long)devpriv-> @@ -2971,6 +2994,7 @@ static void handle_ai_interrupt(struct comedi_device *dev, unsigned short status, unsigned int plx_status) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; struct comedi_async *async = s->async; @@ -3005,7 +3029,7 @@ static void handle_ai_interrupt(struct comedi_device *dev, if ((status & ADC_DONE_BIT) || ((cmd->flags & TRIG_WAKE_EOS) && (status & ADC_INTR_PENDING_BIT) && - (board(dev)->layout != LAYOUT_4020))) { + (thisboard->layout != LAYOUT_4020))) { DEBUG_PRINT("pio fifo drain\n"); spin_lock_irqsave(&dev->spinlock, flags); if (devpriv->ai_cmd_running) { @@ -3223,6 +3247,7 @@ static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); int range = CR_RANGE(insn->chanspec); @@ -3236,7 +3261,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, devpriv->main_iobase + DAC_CONTROL1_REG); /* write to channel */ - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->layout == LAYOUT_4020) { writew(data[0] & 0xff, devpriv->main_iobase + dac_lsb_4020_reg(chan)); writew((data[0] >> 8) & 0xf, @@ -3449,9 +3474,11 @@ static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) static inline int external_ai_queue_in_use(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); + if (dev->read_subdev->busy) return 0; - if (board(dev)->layout == LAYOUT_4020) + if (thisboard->layout == LAYOUT_4020) return 0; else if (use_internal_queue_6xxx(&dev->read_subdev->async->cmd)) return 0; @@ -3511,6 +3538,7 @@ static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { + const struct pcidas64_board *thisboard = comedi_board(dev); int err = 0; unsigned int tmp_arg; int i; @@ -3546,8 +3574,8 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, /* step 3: make sure arguments are trivially compatible */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < board(dev)->ao_scan_speed) { - cmd->scan_begin_arg = board(dev)->ao_scan_speed; + if (cmd->scan_begin_arg < thisboard->ao_scan_speed) { + cmd->scan_begin_arg = thisboard->ao_scan_speed; err++; } if (get_ao_divisor(cmd->scan_begin_arg, @@ -3714,11 +3742,12 @@ static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s, static void caldac_write(struct comedi_device *dev, unsigned int channel, unsigned int value) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; devpriv->caldac_state[channel] = value; - switch (board(dev)->layout) { + switch (thisboard->layout) { case LAYOUT_60XX: case LAYOUT_64XX: caldac_8800_write(dev, channel, value); @@ -3901,6 +3930,7 @@ static int eeprom_read_insn(struct comedi_device *dev, */ static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) { + const struct pcidas64_board *thisboard = comedi_board(dev); unsigned int convert_divisor = 0, scan_divisor; static const int min_convert_divisor = 3; static const int max_convert_divisor = @@ -3909,7 +3939,7 @@ static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) unsigned long long max_scan_divisor, min_scan_divisor; if (cmd->convert_src == TRIG_TIMER) { - if (board(dev)->layout == LAYOUT_4020) { + if (thisboard->layout == LAYOUT_4020) { cmd->convert_arg = 0; } else { convert_divisor = get_divisor(cmd->convert_arg, @@ -3976,9 +4006,10 @@ static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags) /* adjusts the size of hardware fifo (which determines block size for dma xfers) */ static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples) { + const struct pcidas64_board *thisboard = comedi_board(dev); unsigned int num_fifo_entries; int retval; - const struct hw_fifo_info *const fifo = board(dev)->ai_fifo; + const struct hw_fifo_info *const fifo = thisboard->ai_fifo; num_fifo_entries = num_samples / fifo->sample_packing_ratio; @@ -3998,19 +4029,21 @@ static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples) /* query length of fifo */ static unsigned int ai_fifo_size(struct comedi_device *dev) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; return devpriv->ai_fifo_segment_length * - board(dev)->ai_fifo->num_segments * - board(dev)->ai_fifo->sample_packing_ratio; + thisboard->ai_fifo->num_segments * + thisboard->ai_fifo->sample_packing_ratio; } static int set_ai_fifo_segment_length(struct comedi_device *dev, unsigned int num_entries) { + const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; static const int increment_size = 0x100; - const struct hw_fifo_info *const fifo = board(dev)->ai_fifo; + const struct hw_fifo_info *const fifo = thisboard->ai_fifo; unsigned int num_increments; uint16_t bits; -- cgit v1.2.3 From 9c7a00f572266305322824403241c4aa21f46b8a Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 19:18:02 +0000 Subject: staging: comedi: cb_pcidas64: fix forward declarations 1 Move `setup_subdevices()` and remove a load of forward declarations. Added a forward declaration of `setup_subdevices()` temporarily. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 386 ++++++++++++--------------- 1 file changed, 168 insertions(+), 218 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 803220be6b2..2d3f58628ee 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1151,64 +1151,16 @@ struct pcidas64_private { short ao_bounce_buffer[DAC_FIFO_SIZE]; }; -static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ao_readback_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s); -static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); -static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s); +static int setup_subdevices(struct comedi_device *dev); static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *subdev, unsigned int trig_num); -static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd); static irqreturn_t handle_interrupt(int irq, void *d); -static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s); -static int dio_callback(int dir, int port, int data, unsigned long arg); -static int dio_callback_4020(int dir, int port, int data, unsigned long arg); -static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int dio_60xx_config_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int calib_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_insn *insn, - unsigned int *data); -static int calib_write_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int ad8402_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static void ad8402_write(struct comedi_device *dev, unsigned int channel, - unsigned int value); -static int ad8402_write_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); -static int eeprom_read_insn(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data); static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd); static unsigned int get_divisor(unsigned int ns, unsigned int flags); static void i2c_write(struct comedi_device *dev, unsigned int address, const uint8_t *data, unsigned int length); -static void caldac_write(struct comedi_device *dev, unsigned int channel, - unsigned int value); static int caldac_8800_write(struct comedi_device *dev, unsigned int address, uint8_t value); -/* static int dac_1590_write(struct comedi_device *dev, unsigned int dac_a, - * unsigned int dac_b); */ static int caldac_i2c_write(struct comedi_device *dev, unsigned int caldac_channel, unsigned int value); static void abort_dma(struct comedi_device *dev, unsigned int channel); @@ -1220,8 +1172,6 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev, unsigned int num_entries); static void disable_ai_pacing(struct comedi_device *dev); static void disable_ai_interrupts(struct comedi_device *dev); -static void enable_ai_interrupts(struct comedi_device *dev, - const struct comedi_cmd *cmd); static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags); static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd); @@ -1395,173 +1345,6 @@ static void init_plx9080(struct comedi_device *dev) devpriv->plx9080_iobase + PLX_INTRCS_REG); } -/* Allocate and initialize the subdevice structures. - */ -static int setup_subdevices(struct comedi_device *dev) -{ - const struct pcidas64_board *thisboard = comedi_board(dev); - struct pcidas64_private *devpriv = dev->private; - struct comedi_subdevice *s; - void __iomem *dio_8255_iobase; - int i; - int ret; - - ret = comedi_alloc_subdevices(dev, 10); - if (ret) - return ret; - - s = &dev->subdevices[0]; - /* analog input subdevice */ - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ; - if (thisboard->layout == LAYOUT_60XX) - s->subdev_flags |= SDF_COMMON | SDF_DIFF; - else if (thisboard->layout == LAYOUT_64XX) - s->subdev_flags |= SDF_DIFF; - /* XXX Number of inputs in differential mode is ignored */ - s->n_chan = thisboard->ai_se_chans; - s->len_chanlist = 0x2000; - s->maxdata = (1 << thisboard->ai_bits) - 1; - s->range_table = thisboard->ai_range_table; - s->insn_read = ai_rinsn; - s->insn_config = ai_config_insn; - s->do_cmd = ai_cmd; - s->do_cmdtest = ai_cmdtest; - s->cancel = ai_cancel; - if (thisboard->layout == LAYOUT_4020) { - uint8_t data; - /* set adc to read from inputs - * (not internal calibration sources) */ - devpriv->i2c_cal_range_bits = adc_src_4020_bits(4); - /* set channels to +-5 volt input ranges */ - for (i = 0; i < s->n_chan; i++) - devpriv->i2c_cal_range_bits |= attenuate_bit(i); - data = devpriv->i2c_cal_range_bits; - i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data)); - } - - /* analog output subdevice */ - s = &dev->subdevices[1]; - if (thisboard->ao_nchan) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | - SDF_GROUND | SDF_CMD_WRITE; - s->n_chan = thisboard->ao_nchan; - s->maxdata = (1 << thisboard->ao_bits) - 1; - s->range_table = thisboard->ao_range_table; - s->insn_read = ao_readback_insn; - s->insn_write = ao_winsn; - if (ao_cmd_is_supported(thisboard)) { - dev->write_subdev = s; - s->do_cmdtest = ao_cmdtest; - s->do_cmd = ao_cmd; - s->len_chanlist = thisboard->ao_nchan; - s->cancel = ao_cancel; - } - } else { - s->type = COMEDI_SUBD_UNUSED; - } - - /* digital input */ - s = &dev->subdevices[2]; - if (thisboard->layout == LAYOUT_64XX) { - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; - s->n_chan = 4; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = di_rbits; - } else - s->type = COMEDI_SUBD_UNUSED; - - /* digital output */ - if (thisboard->layout == LAYOUT_64XX) { - s = &dev->subdevices[3]; - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 4; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = do_wbits; - } else - s->type = COMEDI_SUBD_UNUSED; - - /* 8255 */ - s = &dev->subdevices[4]; - if (thisboard->has_8255) { - if (thisboard->layout == LAYOUT_4020) { - dio_8255_iobase = devpriv->main_iobase + I8255_4020_REG; - subdev_8255_init(dev, s, dio_callback_4020, - (unsigned long)dio_8255_iobase); - } else { - dio_8255_iobase = - devpriv->dio_counter_iobase + DIO_8255_OFFSET; - subdev_8255_init(dev, s, dio_callback, - (unsigned long)dio_8255_iobase); - } - } else - s->type = COMEDI_SUBD_UNUSED; - - /* 8 channel dio for 60xx */ - s = &dev->subdevices[5]; - if (thisboard->layout == LAYOUT_60XX) { - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 8; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_config = dio_60xx_config_insn; - s->insn_bits = dio_60xx_wbits; - } else - s->type = COMEDI_SUBD_UNUSED; - - /* caldac */ - s = &dev->subdevices[6]; - s->type = COMEDI_SUBD_CALIB; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; - s->n_chan = 8; - if (thisboard->layout == LAYOUT_4020) - s->maxdata = 0xfff; - else - s->maxdata = 0xff; - s->insn_read = calib_read_insn; - s->insn_write = calib_write_insn; - for (i = 0; i < s->n_chan; i++) - caldac_write(dev, i, s->maxdata / 2); - - /* 2 channel ad8402 potentiometer */ - s = &dev->subdevices[7]; - if (thisboard->layout == LAYOUT_64XX) { - s->type = COMEDI_SUBD_CALIB; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; - s->n_chan = 2; - s->insn_read = ad8402_read_insn; - s->insn_write = ad8402_write_insn; - s->maxdata = 0xff; - for (i = 0; i < s->n_chan; i++) - ad8402_write(dev, i, s->maxdata / 2); - } else - s->type = COMEDI_SUBD_UNUSED; - - /* serial EEPROM, if present */ - s = &dev->subdevices[8]; - if (readl(devpriv->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) { - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 128; - s->maxdata = 0xffff; - s->insn_read = eeprom_read_insn; - } else - s->type = COMEDI_SUBD_UNUSED; - - /* user counter subd XXX */ - s = &dev->subdevices[9]; - s->type = COMEDI_SUBD_UNUSED; - - return 0; -} - static void disable_plx_interrupts(struct comedi_device *dev) { struct pcidas64_private *devpriv = dev->private; @@ -4312,6 +4095,173 @@ static void i2c_write(struct comedi_device *dev, unsigned int address, i2c_stop(dev); } +/* Allocate and initialize the subdevice structures. + */ +static int setup_subdevices(struct comedi_device *dev) +{ + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; + struct comedi_subdevice *s; + void __iomem *dio_8255_iobase; + int i; + int ret; + + ret = comedi_alloc_subdevices(dev, 10); + if (ret) + return ret; + + s = &dev->subdevices[0]; + /* analog input subdevice */ + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ; + if (thisboard->layout == LAYOUT_60XX) + s->subdev_flags |= SDF_COMMON | SDF_DIFF; + else if (thisboard->layout == LAYOUT_64XX) + s->subdev_flags |= SDF_DIFF; + /* XXX Number of inputs in differential mode is ignored */ + s->n_chan = thisboard->ai_se_chans; + s->len_chanlist = 0x2000; + s->maxdata = (1 << thisboard->ai_bits) - 1; + s->range_table = thisboard->ai_range_table; + s->insn_read = ai_rinsn; + s->insn_config = ai_config_insn; + s->do_cmd = ai_cmd; + s->do_cmdtest = ai_cmdtest; + s->cancel = ai_cancel; + if (thisboard->layout == LAYOUT_4020) { + uint8_t data; + /* set adc to read from inputs + * (not internal calibration sources) */ + devpriv->i2c_cal_range_bits = adc_src_4020_bits(4); + /* set channels to +-5 volt input ranges */ + for (i = 0; i < s->n_chan; i++) + devpriv->i2c_cal_range_bits |= attenuate_bit(i); + data = devpriv->i2c_cal_range_bits; + i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data)); + } + + /* analog output subdevice */ + s = &dev->subdevices[1]; + if (thisboard->ao_nchan) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | + SDF_GROUND | SDF_CMD_WRITE; + s->n_chan = thisboard->ao_nchan; + s->maxdata = (1 << thisboard->ao_bits) - 1; + s->range_table = thisboard->ao_range_table; + s->insn_read = ao_readback_insn; + s->insn_write = ao_winsn; + if (ao_cmd_is_supported(thisboard)) { + dev->write_subdev = s; + s->do_cmdtest = ao_cmdtest; + s->do_cmd = ao_cmd; + s->len_chanlist = thisboard->ao_nchan; + s->cancel = ao_cancel; + } + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* digital input */ + s = &dev->subdevices[2]; + if (thisboard->layout == LAYOUT_64XX) { + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 4; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = di_rbits; + } else + s->type = COMEDI_SUBD_UNUSED; + + /* digital output */ + if (thisboard->layout == LAYOUT_64XX) { + s = &dev->subdevices[3]; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 4; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = do_wbits; + } else + s->type = COMEDI_SUBD_UNUSED; + + /* 8255 */ + s = &dev->subdevices[4]; + if (thisboard->has_8255) { + if (thisboard->layout == LAYOUT_4020) { + dio_8255_iobase = devpriv->main_iobase + I8255_4020_REG; + subdev_8255_init(dev, s, dio_callback_4020, + (unsigned long)dio_8255_iobase); + } else { + dio_8255_iobase = + devpriv->dio_counter_iobase + DIO_8255_OFFSET; + subdev_8255_init(dev, s, dio_callback, + (unsigned long)dio_8255_iobase); + } + } else + s->type = COMEDI_SUBD_UNUSED; + + /* 8 channel dio for 60xx */ + s = &dev->subdevices[5]; + if (thisboard->layout == LAYOUT_60XX) { + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 8; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_config = dio_60xx_config_insn; + s->insn_bits = dio_60xx_wbits; + } else + s->type = COMEDI_SUBD_UNUSED; + + /* caldac */ + s = &dev->subdevices[6]; + s->type = COMEDI_SUBD_CALIB; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; + s->n_chan = 8; + if (thisboard->layout == LAYOUT_4020) + s->maxdata = 0xfff; + else + s->maxdata = 0xff; + s->insn_read = calib_read_insn; + s->insn_write = calib_write_insn; + for (i = 0; i < s->n_chan; i++) + caldac_write(dev, i, s->maxdata / 2); + + /* 2 channel ad8402 potentiometer */ + s = &dev->subdevices[7]; + if (thisboard->layout == LAYOUT_64XX) { + s->type = COMEDI_SUBD_CALIB; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; + s->n_chan = 2; + s->insn_read = ad8402_read_insn; + s->insn_write = ad8402_write_insn; + s->maxdata = 0xff; + for (i = 0; i < s->n_chan; i++) + ad8402_write(dev, i, s->maxdata / 2); + } else + s->type = COMEDI_SUBD_UNUSED; + + /* serial EEPROM, if present */ + s = &dev->subdevices[8]; + if (readl(devpriv->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) { + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE | SDF_INTERNAL; + s->n_chan = 128; + s->maxdata = 0xffff; + s->insn_read = eeprom_read_insn; + } else + s->type = COMEDI_SUBD_UNUSED; + + /* user counter subd XXX */ + s = &dev->subdevices[9]; + s->type = COMEDI_SUBD_UNUSED; + + return 0; +} + static struct comedi_driver cb_pcidas64_driver = { .driver_name = "cb_pcidas64", .module = THIS_MODULE, -- cgit v1.2.3 From a299d8817d9656bc5fc9192f0369b2202d5b5a01 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 19:18:03 +0000 Subject: staging: comedi: cb_pcidas64: fix forward declarations 2 Move `cb_pcidas64_find_pci_board()`, `auto_attach()` and `detach()` and remove the forward declaration of `setup_subdevices()`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 351 +++++++++++++-------------- 1 file changed, 175 insertions(+), 176 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 2d3f58628ee..a88e879c8d9 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1151,7 +1151,6 @@ struct pcidas64_private { short ao_bounce_buffer[DAC_FIFO_SIZE]; }; -static int setup_subdevices(struct comedi_device *dev); static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *subdev, unsigned int trig_num); static irqreturn_t handle_interrupt(int irq, void *d); @@ -1496,181 +1495,6 @@ static inline void warn_external_queue(struct comedi_device *dev) "Use internal AI channel queue (channels must be consecutive and use same range/aref)"); } -static const struct pcidas64_board -*cb_pcidas64_find_pci_board(struct pci_dev *pcidev) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++) - if (pcidev->device == pcidas64_boards[i].device_id) - return &pcidas64_boards[i]; - return NULL; -} - -static int __devinit auto_attach(struct comedi_device *dev, - unsigned long context_unused) -{ - const struct pcidas64_board *thisboard; - struct pcidas64_private *devpriv; - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - uint32_t local_range, local_decode; - int retval; - - dev->board_ptr = cb_pcidas64_find_pci_board(pcidev); - if (!dev->board_ptr) { - dev_err(dev->class_dev, - "cb_pcidas64: does not support pci %s\n", - pci_name(pcidev)); - return -EINVAL; - } - thisboard = comedi_board(dev); - - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); - if (!devpriv) - return -ENOMEM; - dev->private = devpriv; - - if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { - dev_warn(dev->class_dev, - "failed to enable PCI device and request regions\n"); - return -EIO; - } - pci_set_master(pcidev); - - /* Initialize dev->board_name */ - dev->board_name = thisboard->name; - - dev->iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX); - - devpriv->plx9080_phys_iobase = - pci_resource_start(pcidev, PLX9080_BADDRINDEX); - devpriv->main_phys_iobase = dev->iobase; - devpriv->dio_counter_phys_iobase = - pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX); - - /* remap, won't work with 2.0 kernels but who cares */ - devpriv->plx9080_iobase = - ioremap(devpriv->plx9080_phys_iobase, - pci_resource_len(pcidev, PLX9080_BADDRINDEX)); - devpriv->main_iobase = - ioremap(devpriv->main_phys_iobase, - pci_resource_len(pcidev, MAIN_BADDRINDEX)); - devpriv->dio_counter_iobase = - ioremap(devpriv->dio_counter_phys_iobase, - pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX)); - - if (!devpriv->plx9080_iobase || !devpriv->main_iobase - || !devpriv->dio_counter_iobase) { - dev_warn(dev->class_dev, "failed to remap io memory\n"); - return -ENOMEM; - } - - DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase); - DEBUG_PRINT(" main remapped to 0x%p\n", devpriv->main_iobase); - DEBUG_PRINT(" diocounter remapped to 0x%p\n", - devpriv->dio_counter_iobase); - - /* figure out what local addresses are */ - local_range = readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) & - LRNG_MEM_MASK; - local_decode = readl(devpriv->plx9080_iobase + PLX_LAS0MAP_REG) & - local_range & LMAP_MEM_MASK; - devpriv->local0_iobase = ((uint32_t)devpriv->main_phys_iobase & - ~local_range) | local_decode; - local_range = readl(devpriv->plx9080_iobase + PLX_LAS1RNG_REG) & - LRNG_MEM_MASK; - local_decode = readl(devpriv->plx9080_iobase + PLX_LAS1MAP_REG) & - local_range & LMAP_MEM_MASK; - devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase & - ~local_range) | local_decode; - - DEBUG_PRINT(" local 0 io addr 0x%x\n", devpriv->local0_iobase); - DEBUG_PRINT(" local 1 io addr 0x%x\n", devpriv->local1_iobase); - - retval = alloc_and_init_dma_members(dev); - if (retval < 0) - return retval; - - devpriv->hw_revision = - hw_revision(dev, readw(devpriv->main_iobase + HW_STATUS_REG)); - dev_dbg(dev->class_dev, "stc hardware revision %i\n", - devpriv->hw_revision); - init_plx9080(dev); - init_stc_registers(dev); - /* get irq */ - if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, - "cb_pcidas64", dev)) { - dev_dbg(dev->class_dev, "unable to allocate irq %u\n", - pcidev->irq); - return -EINVAL; - } - dev->irq = pcidev->irq; - dev_dbg(dev->class_dev, "irq %u\n", dev->irq); - - retval = setup_subdevices(dev); - if (retval < 0) - return retval; - - return 0; -} - -static void detach(struct comedi_device *dev) -{ - const struct pcidas64_board *thisboard = comedi_board(dev); - struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct pcidas64_private *devpriv = dev->private; - unsigned int i; - - if (dev->irq) - free_irq(dev->irq, dev); - if (devpriv) { - if (pcidev) { - if (devpriv->plx9080_iobase) { - disable_plx_interrupts(dev); - iounmap(devpriv->plx9080_iobase); - } - if (devpriv->main_iobase) - iounmap(devpriv->main_iobase); - if (devpriv->dio_counter_iobase) - iounmap(devpriv->dio_counter_iobase); - /* free pci dma buffers */ - for (i = 0; i < ai_dma_ring_count(thisboard); i++) { - if (devpriv->ai_buffer[i]) - pci_free_consistent(pcidev, - DMA_BUFFER_SIZE, - devpriv->ai_buffer[i], - devpriv->ai_buffer_bus_addr[i]); - } - for (i = 0; i < AO_DMA_RING_COUNT; i++) { - if (devpriv->ao_buffer[i]) - pci_free_consistent(pcidev, - DMA_BUFFER_SIZE, - devpriv->ao_buffer[i], - devpriv->ao_buffer_bus_addr[i]); - } - /* free dma descriptors */ - if (devpriv->ai_dma_desc) - pci_free_consistent(pcidev, - sizeof(struct plx_dma_desc) * - ai_dma_ring_count(thisboard), - devpriv->ai_dma_desc, - devpriv->ai_dma_desc_bus_addr); - if (devpriv->ao_dma_desc) - pci_free_consistent(pcidev, - sizeof(struct plx_dma_desc) * - AO_DMA_RING_COUNT, - devpriv->ao_dma_desc, - devpriv->ao_dma_desc_bus_addr); - } - } - if (dev->subdevices) - subdev_8255_cleanup(dev, &dev->subdevices[4]); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); - } -} - static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -4262,6 +4086,181 @@ static int setup_subdevices(struct comedi_device *dev) return 0; } +static const struct pcidas64_board +*cb_pcidas64_find_pci_board(struct pci_dev *pcidev) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++) + if (pcidev->device == pcidas64_boards[i].device_id) + return &pcidas64_boards[i]; + return NULL; +} + +static int __devinit auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + const struct pcidas64_board *thisboard; + struct pcidas64_private *devpriv; + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + uint32_t local_range, local_decode; + int retval; + + dev->board_ptr = cb_pcidas64_find_pci_board(pcidev); + if (!dev->board_ptr) { + dev_err(dev->class_dev, + "cb_pcidas64: does not support pci %s\n", + pci_name(pcidev)); + return -EINVAL; + } + thisboard = comedi_board(dev); + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + if (comedi_pci_enable(pcidev, dev->driver->driver_name)) { + dev_warn(dev->class_dev, + "failed to enable PCI device and request regions\n"); + return -EIO; + } + pci_set_master(pcidev); + + /* Initialize dev->board_name */ + dev->board_name = thisboard->name; + + dev->iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX); + + devpriv->plx9080_phys_iobase = + pci_resource_start(pcidev, PLX9080_BADDRINDEX); + devpriv->main_phys_iobase = dev->iobase; + devpriv->dio_counter_phys_iobase = + pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX); + + /* remap, won't work with 2.0 kernels but who cares */ + devpriv->plx9080_iobase = + ioremap(devpriv->plx9080_phys_iobase, + pci_resource_len(pcidev, PLX9080_BADDRINDEX)); + devpriv->main_iobase = + ioremap(devpriv->main_phys_iobase, + pci_resource_len(pcidev, MAIN_BADDRINDEX)); + devpriv->dio_counter_iobase = + ioremap(devpriv->dio_counter_phys_iobase, + pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX)); + + if (!devpriv->plx9080_iobase || !devpriv->main_iobase + || !devpriv->dio_counter_iobase) { + dev_warn(dev->class_dev, "failed to remap io memory\n"); + return -ENOMEM; + } + + DEBUG_PRINT(" plx9080 remapped to 0x%p\n", devpriv->plx9080_iobase); + DEBUG_PRINT(" main remapped to 0x%p\n", devpriv->main_iobase); + DEBUG_PRINT(" diocounter remapped to 0x%p\n", + devpriv->dio_counter_iobase); + + /* figure out what local addresses are */ + local_range = readl(devpriv->plx9080_iobase + PLX_LAS0RNG_REG) & + LRNG_MEM_MASK; + local_decode = readl(devpriv->plx9080_iobase + PLX_LAS0MAP_REG) & + local_range & LMAP_MEM_MASK; + devpriv->local0_iobase = ((uint32_t)devpriv->main_phys_iobase & + ~local_range) | local_decode; + local_range = readl(devpriv->plx9080_iobase + PLX_LAS1RNG_REG) & + LRNG_MEM_MASK; + local_decode = readl(devpriv->plx9080_iobase + PLX_LAS1MAP_REG) & + local_range & LMAP_MEM_MASK; + devpriv->local1_iobase = ((uint32_t)devpriv->dio_counter_phys_iobase & + ~local_range) | local_decode; + + DEBUG_PRINT(" local 0 io addr 0x%x\n", devpriv->local0_iobase); + DEBUG_PRINT(" local 1 io addr 0x%x\n", devpriv->local1_iobase); + + retval = alloc_and_init_dma_members(dev); + if (retval < 0) + return retval; + + devpriv->hw_revision = + hw_revision(dev, readw(devpriv->main_iobase + HW_STATUS_REG)); + dev_dbg(dev->class_dev, "stc hardware revision %i\n", + devpriv->hw_revision); + init_plx9080(dev); + init_stc_registers(dev); + /* get irq */ + if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, + "cb_pcidas64", dev)) { + dev_dbg(dev->class_dev, "unable to allocate irq %u\n", + pcidev->irq); + return -EINVAL; + } + dev->irq = pcidev->irq; + dev_dbg(dev->class_dev, "irq %u\n", dev->irq); + + retval = setup_subdevices(dev); + if (retval < 0) + return retval; + + return 0; +} + +static void detach(struct comedi_device *dev) +{ + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct pcidas64_private *devpriv = dev->private; + unsigned int i; + + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv) { + if (pcidev) { + if (devpriv->plx9080_iobase) { + disable_plx_interrupts(dev); + iounmap(devpriv->plx9080_iobase); + } + if (devpriv->main_iobase) + iounmap(devpriv->main_iobase); + if (devpriv->dio_counter_iobase) + iounmap(devpriv->dio_counter_iobase); + /* free pci dma buffers */ + for (i = 0; i < ai_dma_ring_count(thisboard); i++) { + if (devpriv->ai_buffer[i]) + pci_free_consistent(pcidev, + DMA_BUFFER_SIZE, + devpriv->ai_buffer[i], + devpriv->ai_buffer_bus_addr[i]); + } + for (i = 0; i < AO_DMA_RING_COUNT; i++) { + if (devpriv->ao_buffer[i]) + pci_free_consistent(pcidev, + DMA_BUFFER_SIZE, + devpriv->ao_buffer[i], + devpriv->ao_buffer_bus_addr[i]); + } + /* free dma descriptors */ + if (devpriv->ai_dma_desc) + pci_free_consistent(pcidev, + sizeof(struct plx_dma_desc) * + ai_dma_ring_count(thisboard), + devpriv->ai_dma_desc, + devpriv->ai_dma_desc_bus_addr); + if (devpriv->ao_dma_desc) + pci_free_consistent(pcidev, + sizeof(struct plx_dma_desc) * + AO_DMA_RING_COUNT, + devpriv->ao_dma_desc, + devpriv->ao_dma_desc_bus_addr); + } + } + if (dev->subdevices) + subdev_8255_cleanup(dev, &dev->subdevices[4]); + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } +} + static struct comedi_driver cb_pcidas64_driver = { .driver_name = "cb_pcidas64", .module = THIS_MODULE, -- cgit v1.2.3 From 012e642c01d3c11ac5e50187a0684bd006d29f71 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 19:18:04 +0000 Subject: staging: comedi: cb_pcidas64: fix forward declarations 3 Move `abort_dma()`, `disable_ai_pacing()`, `i2c_high_udelay`, `i2c_low_udelay`, `i2c_set_sda()`, `i2c_set_scl()`, `i2c_write_byte()`, `i2c_read_ack()`, `i2c_start()`, `i2c_stop()`, `i2c_write()`, `get_divisor()`, `check_adc_timing()`, `disable_ai_pacing()`, `abort_dma()`, `get_ao_divisor()`, `ao_inttrig()`, `caldac_8800_write()`, `caldac_i2c_write()`, `check_adc_timing()`, `get_divisor()`, and `get_ao_divisor()`, and remove their forward declarations. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 768 +++++++++++++-------------- 1 file changed, 377 insertions(+), 391 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index a88e879c8d9..f767cdb9fc0 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1151,27 +1151,13 @@ struct pcidas64_private { short ao_bounce_buffer[DAC_FIFO_SIZE]; }; -static int ao_inttrig(struct comedi_device *dev, - struct comedi_subdevice *subdev, unsigned int trig_num); -static irqreturn_t handle_interrupt(int irq, void *d); -static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd); -static unsigned int get_divisor(unsigned int ns, unsigned int flags); -static void i2c_write(struct comedi_device *dev, unsigned int address, - const uint8_t *data, unsigned int length); -static int caldac_8800_write(struct comedi_device *dev, unsigned int address, - uint8_t value); -static int caldac_i2c_write(struct comedi_device *dev, - unsigned int caldac_channel, unsigned int value); -static void abort_dma(struct comedi_device *dev, unsigned int channel); static void disable_plx_interrupts(struct comedi_device *dev); static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples); static unsigned int ai_fifo_size(struct comedi_device *dev); static int set_ai_fifo_segment_length(struct comedi_device *dev, unsigned int num_entries); -static void disable_ai_pacing(struct comedi_device *dev); static void disable_ai_interrupts(struct comedi_device *dev); -static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags); static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd); @@ -1252,6 +1238,19 @@ static inline int ao_cmd_is_supported(const struct pcidas64_board *board) return board->ao_nchan && board->layout != LAYOUT_4020; } +static void abort_dma(struct comedi_device *dev, unsigned int channel) +{ + struct pcidas64_private *devpriv = dev->private; + unsigned long flags; + + /* spinlock for plx dma control/status reg */ + spin_lock_irqsave(&dev->spinlock, flags); + + plx9080_abort_dma(devpriv->plx9080_iobase, channel); + + spin_unlock_irqrestore(&dev->spinlock, flags); +} + /* initialize plx9080 chip */ static void init_plx9080(struct comedi_device *dev) { @@ -1353,6 +1352,24 @@ static void disable_plx_interrupts(struct comedi_device *dev) devpriv->plx9080_iobase + PLX_INTRCS_REG); } +static void disable_ai_pacing(struct comedi_device *dev) +{ + struct pcidas64_private *devpriv = dev->private; + unsigned long flags; + + disable_ai_interrupts(dev); + + spin_lock_irqsave(&dev->spinlock, flags); + devpriv->adc_control1_bits &= ~ADC_SW_GATE_BIT; + writew(devpriv->adc_control1_bits, + devpriv->main_iobase + ADC_CONTROL1_REG); + spin_unlock_irqrestore(&dev->spinlock, flags); + + /* disable pacing, triggering, etc */ + writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT, + devpriv->main_iobase + ADC_CONTROL0_REG); +} + static void init_stc_registers(struct comedi_device *dev) { const struct pcidas64_board *thisboard = comedi_board(dev); @@ -1495,6 +1512,135 @@ static inline void warn_external_queue(struct comedi_device *dev) "Use internal AI channel queue (channels must be consecutive and use same range/aref)"); } +/* Their i2c requires a huge delay on setting clock or data high for some reason */ +static const int i2c_high_udelay = 1000; +static const int i2c_low_udelay = 10; + +/* set i2c data line high or low */ +static void i2c_set_sda(struct comedi_device *dev, int state) +{ + struct pcidas64_private *devpriv = dev->private; + static const int data_bit = CTL_EE_W; + void __iomem *plx_control_addr = devpriv->plx9080_iobase + + PLX_CONTROL_REG; + + if (state) { + /* set data line high */ + devpriv->plx_control_bits &= ~data_bit; + writel(devpriv->plx_control_bits, plx_control_addr); + udelay(i2c_high_udelay); + } else { /* set data line low */ + + devpriv->plx_control_bits |= data_bit; + writel(devpriv->plx_control_bits, plx_control_addr); + udelay(i2c_low_udelay); + } +} + +/* set i2c clock line high or low */ +static void i2c_set_scl(struct comedi_device *dev, int state) +{ + struct pcidas64_private *devpriv = dev->private; + static const int clock_bit = CTL_USERO; + void __iomem *plx_control_addr = devpriv->plx9080_iobase + + PLX_CONTROL_REG; + + if (state) { + /* set clock line high */ + devpriv->plx_control_bits &= ~clock_bit; + writel(devpriv->plx_control_bits, plx_control_addr); + udelay(i2c_high_udelay); + } else { /* set clock line low */ + + devpriv->plx_control_bits |= clock_bit; + writel(devpriv->plx_control_bits, plx_control_addr); + udelay(i2c_low_udelay); + } +} + +static void i2c_write_byte(struct comedi_device *dev, uint8_t byte) +{ + uint8_t bit; + unsigned int num_bits = 8; + + DEBUG_PRINT("writing to i2c byte 0x%x\n", byte); + + for (bit = 1 << (num_bits - 1); bit; bit >>= 1) { + i2c_set_scl(dev, 0); + if ((byte & bit)) + i2c_set_sda(dev, 1); + else + i2c_set_sda(dev, 0); + i2c_set_scl(dev, 1); + } +} + +/* we can't really read the lines, so fake it */ +static int i2c_read_ack(struct comedi_device *dev) +{ + i2c_set_scl(dev, 0); + i2c_set_sda(dev, 1); + i2c_set_scl(dev, 1); + + return 0; /* return fake acknowledge bit */ +} + +/* send start bit */ +static void i2c_start(struct comedi_device *dev) +{ + i2c_set_scl(dev, 1); + i2c_set_sda(dev, 1); + i2c_set_sda(dev, 0); +} + +/* send stop bit */ +static void i2c_stop(struct comedi_device *dev) +{ + i2c_set_scl(dev, 0); + i2c_set_sda(dev, 0); + i2c_set_scl(dev, 1); + i2c_set_sda(dev, 1); +} + +static void i2c_write(struct comedi_device *dev, unsigned int address, + const uint8_t *data, unsigned int length) +{ + struct pcidas64_private *devpriv = dev->private; + unsigned int i; + uint8_t bitstream; + static const int read_bit = 0x1; + + /* XXX need mutex to prevent simultaneous attempts to access + * eeprom and i2c bus */ + + /* make sure we dont send anything to eeprom */ + devpriv->plx_control_bits &= ~CTL_EE_CS; + + i2c_stop(dev); + i2c_start(dev); + + /* send address and write bit */ + bitstream = (address << 1) & ~read_bit; + i2c_write_byte(dev, bitstream); + + /* get acknowledge */ + if (i2c_read_ack(dev) != 0) { + comedi_error(dev, "i2c write failed: no acknowledge"); + i2c_stop(dev); + return; + } + /* write data bytes */ + for (i = 0; i < length; i++) { + i2c_write_byte(dev, data[i]); + if (i2c_read_ack(dev) != 0) { + comedi_error(dev, "i2c write failed: no acknowledge"); + i2c_stop(dev); + return; + } + } + i2c_stop(dev); +} + static int ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { @@ -1750,6 +1896,80 @@ static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, return -EINVAL; } +/* Gets nearest achievable timing given master clock speed, does not + * take into account possible minimum/maximum divisor values. Used + * by other timing checking functions. */ +static unsigned int get_divisor(unsigned int ns, unsigned int flags) +{ + unsigned int divisor; + + switch (flags & TRIG_ROUND_MASK) { + case TRIG_ROUND_UP: + divisor = (ns + TIMER_BASE - 1) / TIMER_BASE; + break; + case TRIG_ROUND_DOWN: + divisor = ns / TIMER_BASE; + break; + case TRIG_ROUND_NEAREST: + default: + divisor = (ns + TIMER_BASE / 2) / TIMER_BASE; + break; + } + return divisor; +} + +/* utility function that rounds desired timing to an achievable time, and + * sets cmd members appropriately. + * adc paces conversions from master clock by dividing by (x + 3) where x is 24 bit number + */ +static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) +{ + const struct pcidas64_board *thisboard = comedi_board(dev); + unsigned int convert_divisor = 0, scan_divisor; + static const int min_convert_divisor = 3; + static const int max_convert_divisor = + max_counter_value + min_convert_divisor; + static const int min_scan_divisor_4020 = 2; + unsigned long long max_scan_divisor, min_scan_divisor; + + if (cmd->convert_src == TRIG_TIMER) { + if (thisboard->layout == LAYOUT_4020) { + cmd->convert_arg = 0; + } else { + convert_divisor = get_divisor(cmd->convert_arg, + cmd->flags); + if (convert_divisor > max_convert_divisor) + convert_divisor = max_convert_divisor; + if (convert_divisor < min_convert_divisor) + convert_divisor = min_convert_divisor; + cmd->convert_arg = convert_divisor * TIMER_BASE; + } + } else if (cmd->convert_src == TRIG_NOW) { + cmd->convert_arg = 0; + } + + if (cmd->scan_begin_src == TRIG_TIMER) { + scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags); + if (cmd->convert_src == TRIG_TIMER) { + /* XXX check for integer overflows */ + min_scan_divisor = convert_divisor * cmd->chanlist_len; + max_scan_divisor = + (convert_divisor * cmd->chanlist_len - 1) + + max_counter_value; + } else { + min_scan_divisor = min_scan_divisor_4020; + max_scan_divisor = max_counter_value + min_scan_divisor; + } + if (scan_divisor > max_scan_divisor) + scan_divisor = max_scan_divisor; + if (scan_divisor < min_scan_divisor) + scan_divisor = min_scan_divisor; + cmd->scan_begin_arg = scan_divisor * TIMER_BASE; + } + + return; +} + static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { @@ -1957,24 +2177,6 @@ static inline unsigned int dma_transfer_size(struct comedi_device *dev) return num_samples; } -static void disable_ai_pacing(struct comedi_device *dev) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned long flags; - - disable_ai_interrupts(dev); - - spin_lock_irqsave(&dev->spinlock, flags); - devpriv->adc_control1_bits &= ~ADC_SW_GATE_BIT; - writew(devpriv->adc_control1_bits, - devpriv->main_iobase + ADC_CONTROL1_REG); - spin_unlock_irqrestore(&dev->spinlock, flags); - - /* disable pacing, triggering, etc */ - writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT, - devpriv->main_iobase + ADC_CONTROL0_REG); -} - static void disable_ai_interrupts(struct comedi_device *dev) { struct pcidas64_private *devpriv = dev->private; @@ -2817,19 +3019,6 @@ static irqreturn_t handle_interrupt(int irq, void *d) return IRQ_HANDLED; } -static void abort_dma(struct comedi_device *dev, unsigned int channel) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned long flags; - - /* spinlock for plx dma control/status reg */ - spin_lock_irqsave(&dev->spinlock, flags); - - plx9080_abort_dma(devpriv->plx9080_iobase, channel); - - spin_unlock_irqrestore(&dev->spinlock, flags); -} - static int ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { struct pcidas64_private *devpriv = dev->private; @@ -2952,6 +3141,11 @@ static void set_dac_select_reg(struct comedi_device *dev, writew(bits, devpriv->main_iobase + DAC_SELECT_REG); } +static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags) +{ + return get_divisor(ns, flags) - 2; +} + static void set_dac_interval_regs(struct comedi_device *dev, const struct comedi_cmd *cmd) { @@ -3092,6 +3286,30 @@ static inline int external_ai_queue_in_use(struct comedi_device *dev) return 1; } +static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, + unsigned int trig_num) +{ + struct pcidas64_private *devpriv = dev->private; + struct comedi_cmd *cmd = &s->async->cmd; + int retval; + + if (trig_num != 0) + return -EINVAL; + + retval = prep_ao_dma(dev, cmd); + if (retval < 0) + return -EPIPE; + + set_dac_control0_reg(dev, cmd); + + if (cmd->start_src == TRIG_INT) + writew(0, devpriv->main_iobase + DAC_START_REG); + + s->async->inttrig = NULL; + + return 0; +} + static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { struct pcidas64_private *devpriv = dev->private; @@ -3118,30 +3336,6 @@ static int ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -static int ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned int trig_num) -{ - struct pcidas64_private *devpriv = dev->private; - struct comedi_cmd *cmd = &s->async->cmd; - int retval; - - if (trig_num != 0) - return -EINVAL; - - retval = prep_ao_dma(dev, cmd); - if (retval < 0) - return -EPIPE; - - set_dac_control0_reg(dev, cmd); - - if (cmd->start_src == TRIG_INT) - writew(0, devpriv->main_iobase + DAC_START_REG); - - s->async->inttrig = NULL; - - return 0; -} - static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { @@ -3346,6 +3540,120 @@ static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice *s, return insn->n; } +/* pci-6025 8800 caldac: + * address 0 == dac channel 0 offset + * address 1 == dac channel 0 gain + * address 2 == dac channel 1 offset + * address 3 == dac channel 1 gain + * address 4 == fine adc offset + * address 5 == coarse adc offset + * address 6 == coarse adc gain + * address 7 == fine adc gain + */ +/* pci-6402/16 uses all 8 channels for dac: + * address 0 == dac channel 0 fine gain + * address 1 == dac channel 0 coarse gain + * address 2 == dac channel 0 coarse offset + * address 3 == dac channel 1 coarse offset + * address 4 == dac channel 1 fine gain + * address 5 == dac channel 1 coarse gain + * address 6 == dac channel 0 fine offset + * address 7 == dac channel 1 fine offset +*/ + +static int caldac_8800_write(struct comedi_device *dev, unsigned int address, + uint8_t value) +{ + struct pcidas64_private *devpriv = dev->private; + static const int num_caldac_channels = 8; + static const int bitstream_length = 11; + unsigned int bitstream = ((address & 0x7) << 8) | value; + unsigned int bit, register_bits; + static const int caldac_8800_udelay = 1; + + if (address >= num_caldac_channels) { + comedi_error(dev, "illegal caldac channel"); + return -1; + } + for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { + register_bits = 0; + if (bitstream & bit) + register_bits |= SERIAL_DATA_IN_BIT; + udelay(caldac_8800_udelay); + writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); + register_bits |= SERIAL_CLOCK_BIT; + udelay(caldac_8800_udelay); + writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); + } + udelay(caldac_8800_udelay); + writew(SELECT_8800_BIT, devpriv->main_iobase + CALIBRATION_REG); + udelay(caldac_8800_udelay); + writew(0, devpriv->main_iobase + CALIBRATION_REG); + udelay(caldac_8800_udelay); + return 0; +} + +/* 4020 caldacs */ +static int caldac_i2c_write(struct comedi_device *dev, + unsigned int caldac_channel, unsigned int value) +{ + uint8_t serial_bytes[3]; + uint8_t i2c_addr; + enum pointer_bits { + /* manual has gain and offset bits switched */ + OFFSET_0_2 = 0x1, + GAIN_0_2 = 0x2, + OFFSET_1_3 = 0x4, + GAIN_1_3 = 0x8, + }; + enum data_bits { + NOT_CLEAR_REGISTERS = 0x20, + }; + + switch (caldac_channel) { + case 0: /* chan 0 offset */ + i2c_addr = CALDAC0_I2C_ADDR; + serial_bytes[0] = OFFSET_0_2; + break; + case 1: /* chan 1 offset */ + i2c_addr = CALDAC0_I2C_ADDR; + serial_bytes[0] = OFFSET_1_3; + break; + case 2: /* chan 2 offset */ + i2c_addr = CALDAC1_I2C_ADDR; + serial_bytes[0] = OFFSET_0_2; + break; + case 3: /* chan 3 offset */ + i2c_addr = CALDAC1_I2C_ADDR; + serial_bytes[0] = OFFSET_1_3; + break; + case 4: /* chan 0 gain */ + i2c_addr = CALDAC0_I2C_ADDR; + serial_bytes[0] = GAIN_0_2; + break; + case 5: /* chan 1 gain */ + i2c_addr = CALDAC0_I2C_ADDR; + serial_bytes[0] = GAIN_1_3; + break; + case 6: /* chan 2 gain */ + i2c_addr = CALDAC1_I2C_ADDR; + serial_bytes[0] = GAIN_0_2; + break; + case 7: /* chan 3 gain */ + i2c_addr = CALDAC1_I2C_ADDR; + serial_bytes[0] = GAIN_1_3; + break; + default: + comedi_error(dev, "invalid caldac channel\n"); + return -1; + break; + } + serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf); + serial_bytes[2] = value & 0xff; + i2c_write(dev, i2c_addr, serial_bytes, 3); + return 0; +} + static void caldac_write(struct comedi_device *dev, unsigned int channel, unsigned int value) { @@ -3531,85 +3839,6 @@ static int eeprom_read_insn(struct comedi_device *dev, return 1; } -/* utility function that rounds desired timing to an achievable time, and - * sets cmd members appropriately. - * adc paces conversions from master clock by dividing by (x + 3) where x is 24 bit number - */ -static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd) -{ - const struct pcidas64_board *thisboard = comedi_board(dev); - unsigned int convert_divisor = 0, scan_divisor; - static const int min_convert_divisor = 3; - static const int max_convert_divisor = - max_counter_value + min_convert_divisor; - static const int min_scan_divisor_4020 = 2; - unsigned long long max_scan_divisor, min_scan_divisor; - - if (cmd->convert_src == TRIG_TIMER) { - if (thisboard->layout == LAYOUT_4020) { - cmd->convert_arg = 0; - } else { - convert_divisor = get_divisor(cmd->convert_arg, - cmd->flags); - if (convert_divisor > max_convert_divisor) - convert_divisor = max_convert_divisor; - if (convert_divisor < min_convert_divisor) - convert_divisor = min_convert_divisor; - cmd->convert_arg = convert_divisor * TIMER_BASE; - } - } else if (cmd->convert_src == TRIG_NOW) { - cmd->convert_arg = 0; - } - - if (cmd->scan_begin_src == TRIG_TIMER) { - scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags); - if (cmd->convert_src == TRIG_TIMER) { - /* XXX check for integer overflows */ - min_scan_divisor = convert_divisor * cmd->chanlist_len; - max_scan_divisor = - (convert_divisor * cmd->chanlist_len - 1) + - max_counter_value; - } else { - min_scan_divisor = min_scan_divisor_4020; - max_scan_divisor = max_counter_value + min_scan_divisor; - } - if (scan_divisor > max_scan_divisor) - scan_divisor = max_scan_divisor; - if (scan_divisor < min_scan_divisor) - scan_divisor = min_scan_divisor; - cmd->scan_begin_arg = scan_divisor * TIMER_BASE; - } - - return; -} - -/* Gets nearest achievable timing given master clock speed, does not - * take into account possible minimum/maximum divisor values. Used - * by other timing checking functions. */ -static unsigned int get_divisor(unsigned int ns, unsigned int flags) -{ - unsigned int divisor; - - switch (flags & TRIG_ROUND_MASK) { - case TRIG_ROUND_UP: - divisor = (ns + TIMER_BASE - 1) / TIMER_BASE; - break; - case TRIG_ROUND_DOWN: - divisor = ns / TIMER_BASE; - break; - case TRIG_ROUND_NEAREST: - default: - divisor = (ns + TIMER_BASE / 2) / TIMER_BASE; - break; - } - return divisor; -} - -static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags) -{ - return get_divisor(ns, flags) - 2; -} - /* adjusts the size of hardware fifo (which determines block size for dma xfers) */ static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples) { @@ -3676,249 +3905,6 @@ static int set_ai_fifo_segment_length(struct comedi_device *dev, return devpriv->ai_fifo_segment_length; } -/* pci-6025 8800 caldac: - * address 0 == dac channel 0 offset - * address 1 == dac channel 0 gain - * address 2 == dac channel 1 offset - * address 3 == dac channel 1 gain - * address 4 == fine adc offset - * address 5 == coarse adc offset - * address 6 == coarse adc gain - * address 7 == fine adc gain - */ -/* pci-6402/16 uses all 8 channels for dac: - * address 0 == dac channel 0 fine gain - * address 1 == dac channel 0 coarse gain - * address 2 == dac channel 0 coarse offset - * address 3 == dac channel 1 coarse offset - * address 4 == dac channel 1 fine gain - * address 5 == dac channel 1 coarse gain - * address 6 == dac channel 0 fine offset - * address 7 == dac channel 1 fine offset -*/ - -static int caldac_8800_write(struct comedi_device *dev, unsigned int address, - uint8_t value) -{ - struct pcidas64_private *devpriv = dev->private; - static const int num_caldac_channels = 8; - static const int bitstream_length = 11; - unsigned int bitstream = ((address & 0x7) << 8) | value; - unsigned int bit, register_bits; - static const int caldac_8800_udelay = 1; - - if (address >= num_caldac_channels) { - comedi_error(dev, "illegal caldac channel"); - return -1; - } - for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { - register_bits = 0; - if (bitstream & bit) - register_bits |= SERIAL_DATA_IN_BIT; - udelay(caldac_8800_udelay); - writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); - register_bits |= SERIAL_CLOCK_BIT; - udelay(caldac_8800_udelay); - writew(register_bits, devpriv->main_iobase + CALIBRATION_REG); - } - udelay(caldac_8800_udelay); - writew(SELECT_8800_BIT, devpriv->main_iobase + CALIBRATION_REG); - udelay(caldac_8800_udelay); - writew(0, devpriv->main_iobase + CALIBRATION_REG); - udelay(caldac_8800_udelay); - return 0; -} - -/* 4020 caldacs */ -static int caldac_i2c_write(struct comedi_device *dev, - unsigned int caldac_channel, unsigned int value) -{ - uint8_t serial_bytes[3]; - uint8_t i2c_addr; - enum pointer_bits { - /* manual has gain and offset bits switched */ - OFFSET_0_2 = 0x1, - GAIN_0_2 = 0x2, - OFFSET_1_3 = 0x4, - GAIN_1_3 = 0x8, - }; - enum data_bits { - NOT_CLEAR_REGISTERS = 0x20, - }; - - switch (caldac_channel) { - case 0: /* chan 0 offset */ - i2c_addr = CALDAC0_I2C_ADDR; - serial_bytes[0] = OFFSET_0_2; - break; - case 1: /* chan 1 offset */ - i2c_addr = CALDAC0_I2C_ADDR; - serial_bytes[0] = OFFSET_1_3; - break; - case 2: /* chan 2 offset */ - i2c_addr = CALDAC1_I2C_ADDR; - serial_bytes[0] = OFFSET_0_2; - break; - case 3: /* chan 3 offset */ - i2c_addr = CALDAC1_I2C_ADDR; - serial_bytes[0] = OFFSET_1_3; - break; - case 4: /* chan 0 gain */ - i2c_addr = CALDAC0_I2C_ADDR; - serial_bytes[0] = GAIN_0_2; - break; - case 5: /* chan 1 gain */ - i2c_addr = CALDAC0_I2C_ADDR; - serial_bytes[0] = GAIN_1_3; - break; - case 6: /* chan 2 gain */ - i2c_addr = CALDAC1_I2C_ADDR; - serial_bytes[0] = GAIN_0_2; - break; - case 7: /* chan 3 gain */ - i2c_addr = CALDAC1_I2C_ADDR; - serial_bytes[0] = GAIN_1_3; - break; - default: - comedi_error(dev, "invalid caldac channel\n"); - return -1; - break; - } - serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf); - serial_bytes[2] = value & 0xff; - i2c_write(dev, i2c_addr, serial_bytes, 3); - return 0; -} - -/* Their i2c requires a huge delay on setting clock or data high for some reason */ -static const int i2c_high_udelay = 1000; -static const int i2c_low_udelay = 10; - -/* set i2c data line high or low */ -static void i2c_set_sda(struct comedi_device *dev, int state) -{ - struct pcidas64_private *devpriv = dev->private; - static const int data_bit = CTL_EE_W; - void __iomem *plx_control_addr = devpriv->plx9080_iobase + - PLX_CONTROL_REG; - - if (state) { - /* set data line high */ - devpriv->plx_control_bits &= ~data_bit; - writel(devpriv->plx_control_bits, plx_control_addr); - udelay(i2c_high_udelay); - } else { /* set data line low */ - - devpriv->plx_control_bits |= data_bit; - writel(devpriv->plx_control_bits, plx_control_addr); - udelay(i2c_low_udelay); - } -} - -/* set i2c clock line high or low */ -static void i2c_set_scl(struct comedi_device *dev, int state) -{ - struct pcidas64_private *devpriv = dev->private; - static const int clock_bit = CTL_USERO; - void __iomem *plx_control_addr = devpriv->plx9080_iobase + - PLX_CONTROL_REG; - - if (state) { - /* set clock line high */ - devpriv->plx_control_bits &= ~clock_bit; - writel(devpriv->plx_control_bits, plx_control_addr); - udelay(i2c_high_udelay); - } else { /* set clock line low */ - - devpriv->plx_control_bits |= clock_bit; - writel(devpriv->plx_control_bits, plx_control_addr); - udelay(i2c_low_udelay); - } -} - -static void i2c_write_byte(struct comedi_device *dev, uint8_t byte) -{ - uint8_t bit; - unsigned int num_bits = 8; - - DEBUG_PRINT("writing to i2c byte 0x%x\n", byte); - - for (bit = 1 << (num_bits - 1); bit; bit >>= 1) { - i2c_set_scl(dev, 0); - if ((byte & bit)) - i2c_set_sda(dev, 1); - else - i2c_set_sda(dev, 0); - i2c_set_scl(dev, 1); - } -} - -/* we can't really read the lines, so fake it */ -static int i2c_read_ack(struct comedi_device *dev) -{ - i2c_set_scl(dev, 0); - i2c_set_sda(dev, 1); - i2c_set_scl(dev, 1); - - return 0; /* return fake acknowledge bit */ -} - -/* send start bit */ -static void i2c_start(struct comedi_device *dev) -{ - i2c_set_scl(dev, 1); - i2c_set_sda(dev, 1); - i2c_set_sda(dev, 0); -} - -/* send stop bit */ -static void i2c_stop(struct comedi_device *dev) -{ - i2c_set_scl(dev, 0); - i2c_set_sda(dev, 0); - i2c_set_scl(dev, 1); - i2c_set_sda(dev, 1); -} - -static void i2c_write(struct comedi_device *dev, unsigned int address, - const uint8_t *data, unsigned int length) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned int i; - uint8_t bitstream; - static const int read_bit = 0x1; - - /* XXX need mutex to prevent simultaneous attempts to access - * eeprom and i2c bus */ - - /* make sure we dont send anything to eeprom */ - devpriv->plx_control_bits &= ~CTL_EE_CS; - - i2c_stop(dev); - i2c_start(dev); - - /* send address and write bit */ - bitstream = (address << 1) & ~read_bit; - i2c_write_byte(dev, bitstream); - - /* get acknowledge */ - if (i2c_read_ack(dev) != 0) { - comedi_error(dev, "i2c write failed: no acknowledge"); - i2c_stop(dev); - return; - } - /* write data bytes */ - for (i = 0; i < length; i++) { - i2c_write_byte(dev, data[i]); - if (i2c_read_ack(dev) != 0) { - comedi_error(dev, "i2c write failed: no acknowledge"); - i2c_stop(dev); - return; - } - } - i2c_stop(dev); -} - /* Allocate and initialize the subdevice structures. */ static int setup_subdevices(struct comedi_device *dev) -- cgit v1.2.3 From dd379fa23feda77e3fee1a65bb65ab72019b77dc Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 19:18:05 +0000 Subject: staging: comedi: cb_pcidas64: fix forward declararions 4 Move `disable_plx_interrupts()`, `disable_ai_interrupts()`, `enable_ai_interrupts()`, `set_ai_fifo_segment_length()`, `set_ai_fifo_size()`, `ai_fifo_size()`, `load_ao_dma_buffer()`, and `load_ao_dma()`, and remove forward declarations of these functions. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 386 +++++++++++++-------------- 1 file changed, 188 insertions(+), 198 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index f767cdb9fc0..771f0433a79 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -1151,16 +1151,6 @@ struct pcidas64_private { short ao_bounce_buffer[DAC_FIFO_SIZE]; }; -static void disable_plx_interrupts(struct comedi_device *dev); -static int set_ai_fifo_size(struct comedi_device *dev, - unsigned int num_samples); -static unsigned int ai_fifo_size(struct comedi_device *dev); -static int set_ai_fifo_segment_length(struct comedi_device *dev, - unsigned int num_entries); -static void disable_ai_interrupts(struct comedi_device *dev); -static void load_ao_dma(struct comedi_device *dev, - const struct comedi_cmd *cmd); - static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev, unsigned int range_index) { @@ -1251,6 +1241,57 @@ static void abort_dma(struct comedi_device *dev, unsigned int channel) spin_unlock_irqrestore(&dev->spinlock, flags); } +static void disable_plx_interrupts(struct comedi_device *dev) +{ + struct pcidas64_private *devpriv = dev->private; + + devpriv->plx_intcsr_bits = 0; + writel(devpriv->plx_intcsr_bits, + devpriv->plx9080_iobase + PLX_INTRCS_REG); +} + +static void disable_ai_interrupts(struct comedi_device *dev) +{ + struct pcidas64_private *devpriv = dev->private; + unsigned long flags; + + spin_lock_irqsave(&dev->spinlock, flags); + devpriv->intr_enable_bits &= + ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT & + ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT & + ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK; + writew(devpriv->intr_enable_bits, + devpriv->main_iobase + INTR_ENABLE_REG); + spin_unlock_irqrestore(&dev->spinlock, flags); + + DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); +} + +static void enable_ai_interrupts(struct comedi_device *dev, + const struct comedi_cmd *cmd) +{ + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; + uint32_t bits; + unsigned long flags; + + bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT | + EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT; + /* Use pio transfer and interrupt on end of conversion + * if TRIG_WAKE_EOS flag is set. */ + if (cmd->flags & TRIG_WAKE_EOS) { + /* 4020 doesn't support pio transfers except for fifo dregs */ + if (thisboard->layout != LAYOUT_4020) + bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT; + } + spin_lock_irqsave(&dev->spinlock, flags); + devpriv->intr_enable_bits |= bits; + writew(devpriv->intr_enable_bits, + devpriv->main_iobase + INTR_ENABLE_REG); + DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); + spin_unlock_irqrestore(&dev->spinlock, flags); +} + /* initialize plx9080 chip */ static void init_plx9080(struct comedi_device *dev) { @@ -1343,15 +1384,6 @@ static void init_plx9080(struct comedi_device *dev) devpriv->plx9080_iobase + PLX_INTRCS_REG); } -static void disable_plx_interrupts(struct comedi_device *dev) -{ - struct pcidas64_private *devpriv = dev->private; - - devpriv->plx_intcsr_bits = 0; - writel(devpriv->plx_intcsr_bits, - devpriv->plx9080_iobase + PLX_INTRCS_REG); -} - static void disable_ai_pacing(struct comedi_device *dev) { struct pcidas64_private *devpriv = dev->private; @@ -1370,6 +1402,72 @@ static void disable_ai_pacing(struct comedi_device *dev) devpriv->main_iobase + ADC_CONTROL0_REG); } +static int set_ai_fifo_segment_length(struct comedi_device *dev, + unsigned int num_entries) +{ + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; + static const int increment_size = 0x100; + const struct hw_fifo_info *const fifo = thisboard->ai_fifo; + unsigned int num_increments; + uint16_t bits; + + if (num_entries < increment_size) + num_entries = increment_size; + if (num_entries > fifo->max_segment_length) + num_entries = fifo->max_segment_length; + + /* 1 == 256 entries, 2 == 512 entries, etc */ + num_increments = (num_entries + increment_size / 2) / increment_size; + + bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask; + devpriv->fifo_size_bits &= ~fifo->fifo_size_reg_mask; + devpriv->fifo_size_bits |= bits; + writew(devpriv->fifo_size_bits, + devpriv->main_iobase + FIFO_SIZE_REG); + + devpriv->ai_fifo_segment_length = num_increments * increment_size; + + DEBUG_PRINT("set hardware fifo segment length to %i\n", + devpriv->ai_fifo_segment_length); + + return devpriv->ai_fifo_segment_length; +} + +/* adjusts the size of hardware fifo (which determines block size for dma xfers) */ +static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples) +{ + const struct pcidas64_board *thisboard = comedi_board(dev); + unsigned int num_fifo_entries; + int retval; + const struct hw_fifo_info *const fifo = thisboard->ai_fifo; + + num_fifo_entries = num_samples / fifo->sample_packing_ratio; + + retval = set_ai_fifo_segment_length(dev, + num_fifo_entries / + fifo->num_segments); + if (retval < 0) + return retval; + + num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio; + + DEBUG_PRINT("set hardware fifo size to %i\n", num_samples); + + return num_samples; +} + +/* query length of fifo */ +static unsigned int ai_fifo_size(struct comedi_device *dev) +{ + const struct pcidas64_board *thisboard = comedi_board(dev); + struct pcidas64_private *devpriv = dev->private; + + return devpriv->ai_fifo_segment_length * + thisboard->ai_fifo->num_segments * + thisboard->ai_fifo->sample_packing_ratio; +} + static void init_stc_registers(struct comedi_device *dev) { const struct pcidas64_board *thisboard = comedi_board(dev); @@ -2177,48 +2275,6 @@ static inline unsigned int dma_transfer_size(struct comedi_device *dev) return num_samples; } -static void disable_ai_interrupts(struct comedi_device *dev) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned long flags; - - spin_lock_irqsave(&dev->spinlock, flags); - devpriv->intr_enable_bits &= - ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT & - ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT & - ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK; - writew(devpriv->intr_enable_bits, - devpriv->main_iobase + INTR_ENABLE_REG); - spin_unlock_irqrestore(&dev->spinlock, flags); - - DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); -} - -static void enable_ai_interrupts(struct comedi_device *dev, - const struct comedi_cmd *cmd) -{ - const struct pcidas64_board *thisboard = comedi_board(dev); - struct pcidas64_private *devpriv = dev->private; - uint32_t bits; - unsigned long flags; - - bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT | - EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT; - /* Use pio transfer and interrupt on end of conversion - * if TRIG_WAKE_EOS flag is set. */ - if (cmd->flags & TRIG_WAKE_EOS) { - /* 4020 doesn't support pio transfers except for fifo dregs */ - if (thisboard->layout != LAYOUT_4020) - bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT; - } - spin_lock_irqsave(&dev->spinlock, flags); - devpriv->intr_enable_bits |= bits; - writew(devpriv->intr_enable_bits, - devpriv->main_iobase + INTR_ENABLE_REG); - DEBUG_PRINT("intr enable bits 0x%x\n", devpriv->intr_enable_bits); - spin_unlock_irqrestore(&dev->spinlock, flags); -} - static uint32_t ai_convert_counter_6xxx(const struct comedi_device *dev, const struct comedi_cmd *cmd) { @@ -2930,6 +2986,77 @@ static void restart_ao_dma(struct comedi_device *dev) dma_start_sync(dev, 0); } +static unsigned int load_ao_dma_buffer(struct comedi_device *dev, + const struct comedi_cmd *cmd) +{ + struct pcidas64_private *devpriv = dev->private; + unsigned int num_bytes, buffer_index, prev_buffer_index; + unsigned int next_bits; + + buffer_index = devpriv->ao_dma_index; + prev_buffer_index = prev_ao_dma_index(dev); + + DEBUG_PRINT("attempting to load ao buffer %i (0x%llx)\n", buffer_index, + (unsigned long long)devpriv->ao_buffer_bus_addr[ + buffer_index]); + + num_bytes = comedi_buf_read_n_available(dev->write_subdev->async); + if (num_bytes > DMA_BUFFER_SIZE) + num_bytes = DMA_BUFFER_SIZE; + if (cmd->stop_src == TRIG_COUNT && num_bytes > devpriv->ao_count) + num_bytes = devpriv->ao_count; + num_bytes -= num_bytes % bytes_in_sample; + + if (num_bytes == 0) + return 0; + + DEBUG_PRINT("loading %i bytes\n", num_bytes); + + num_bytes = cfc_read_array_from_buffer(dev->write_subdev, + devpriv-> + ao_buffer[buffer_index], + num_bytes); + devpriv->ao_dma_desc[buffer_index].transfer_size = + cpu_to_le32(num_bytes); + /* set end of chain bit so we catch underruns */ + next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next); + next_bits |= PLX_END_OF_CHAIN_BIT; + devpriv->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits); + /* clear end of chain bit on previous buffer now that we have set it + * for the last buffer */ + next_bits = le32_to_cpu(devpriv->ao_dma_desc[prev_buffer_index].next); + next_bits &= ~PLX_END_OF_CHAIN_BIT; + devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits); + + devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT; + devpriv->ao_count -= num_bytes; + + return num_bytes; +} + +static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) +{ + struct pcidas64_private *devpriv = dev->private; + unsigned int num_bytes; + unsigned int next_transfer_addr; + void __iomem *pci_addr_reg = + devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; + unsigned int buffer_index; + + do { + buffer_index = devpriv->ao_dma_index; + /* don't overwrite data that hasn't been transferred yet */ + next_transfer_addr = readl(pci_addr_reg); + if (next_transfer_addr >= + devpriv->ao_buffer_bus_addr[buffer_index] && + next_transfer_addr < + devpriv->ao_buffer_bus_addr[buffer_index] + + DMA_BUFFER_SIZE) + return; + num_bytes = load_ao_dma_buffer(dev, cmd); + } while (num_bytes >= DMA_BUFFER_SIZE); +} + static void handle_ao_interrupt(struct comedi_device *dev, unsigned short status, unsigned int plx_status) { @@ -3166,77 +3293,6 @@ static void set_dac_interval_regs(struct comedi_device *dev, devpriv->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG); } -static unsigned int load_ao_dma_buffer(struct comedi_device *dev, - const struct comedi_cmd *cmd) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned int num_bytes, buffer_index, prev_buffer_index; - unsigned int next_bits; - - buffer_index = devpriv->ao_dma_index; - prev_buffer_index = prev_ao_dma_index(dev); - - DEBUG_PRINT("attempting to load ao buffer %i (0x%llx)\n", buffer_index, - (unsigned long long)devpriv->ao_buffer_bus_addr[ - buffer_index]); - - num_bytes = comedi_buf_read_n_available(dev->write_subdev->async); - if (num_bytes > DMA_BUFFER_SIZE) - num_bytes = DMA_BUFFER_SIZE; - if (cmd->stop_src == TRIG_COUNT && num_bytes > devpriv->ao_count) - num_bytes = devpriv->ao_count; - num_bytes -= num_bytes % bytes_in_sample; - - if (num_bytes == 0) - return 0; - - DEBUG_PRINT("loading %i bytes\n", num_bytes); - - num_bytes = cfc_read_array_from_buffer(dev->write_subdev, - devpriv-> - ao_buffer[buffer_index], - num_bytes); - devpriv->ao_dma_desc[buffer_index].transfer_size = - cpu_to_le32(num_bytes); - /* set end of chain bit so we catch underruns */ - next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next); - next_bits |= PLX_END_OF_CHAIN_BIT; - devpriv->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits); - /* clear end of chain bit on previous buffer now that we have set it - * for the last buffer */ - next_bits = le32_to_cpu(devpriv->ao_dma_desc[prev_buffer_index].next); - next_bits &= ~PLX_END_OF_CHAIN_BIT; - devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits); - - devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT; - devpriv->ao_count -= num_bytes; - - return num_bytes; -} - -static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) -{ - struct pcidas64_private *devpriv = dev->private; - unsigned int num_bytes; - unsigned int next_transfer_addr; - void __iomem *pci_addr_reg = - devpriv->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG; - unsigned int buffer_index; - - do { - buffer_index = devpriv->ao_dma_index; - /* don't overwrite data that hasn't been transferred yet */ - next_transfer_addr = readl(pci_addr_reg); - if (next_transfer_addr >= - devpriv->ao_buffer_bus_addr[buffer_index] && - next_transfer_addr < - devpriv->ao_buffer_bus_addr[buffer_index] + - DMA_BUFFER_SIZE) - return; - num_bytes = load_ao_dma_buffer(dev, cmd); - } while (num_bytes >= DMA_BUFFER_SIZE); -} - static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) { struct pcidas64_private *devpriv = dev->private; @@ -3839,72 +3895,6 @@ static int eeprom_read_insn(struct comedi_device *dev, return 1; } -/* adjusts the size of hardware fifo (which determines block size for dma xfers) */ -static int set_ai_fifo_size(struct comedi_device *dev, unsigned int num_samples) -{ - const struct pcidas64_board *thisboard = comedi_board(dev); - unsigned int num_fifo_entries; - int retval; - const struct hw_fifo_info *const fifo = thisboard->ai_fifo; - - num_fifo_entries = num_samples / fifo->sample_packing_ratio; - - retval = set_ai_fifo_segment_length(dev, - num_fifo_entries / - fifo->num_segments); - if (retval < 0) - return retval; - - num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio; - - DEBUG_PRINT("set hardware fifo size to %i\n", num_samples); - - return num_samples; -} - -/* query length of fifo */ -static unsigned int ai_fifo_size(struct comedi_device *dev) -{ - const struct pcidas64_board *thisboard = comedi_board(dev); - struct pcidas64_private *devpriv = dev->private; - - return devpriv->ai_fifo_segment_length * - thisboard->ai_fifo->num_segments * - thisboard->ai_fifo->sample_packing_ratio; -} - -static int set_ai_fifo_segment_length(struct comedi_device *dev, - unsigned int num_entries) -{ - const struct pcidas64_board *thisboard = comedi_board(dev); - struct pcidas64_private *devpriv = dev->private; - static const int increment_size = 0x100; - const struct hw_fifo_info *const fifo = thisboard->ai_fifo; - unsigned int num_increments; - uint16_t bits; - - if (num_entries < increment_size) - num_entries = increment_size; - if (num_entries > fifo->max_segment_length) - num_entries = fifo->max_segment_length; - - /* 1 == 256 entries, 2 == 512 entries, etc */ - num_increments = (num_entries + increment_size / 2) / increment_size; - - bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask; - devpriv->fifo_size_bits &= ~fifo->fifo_size_reg_mask; - devpriv->fifo_size_bits |= bits; - writew(devpriv->fifo_size_bits, - devpriv->main_iobase + FIFO_SIZE_REG); - - devpriv->ai_fifo_segment_length = num_increments * increment_size; - - DEBUG_PRINT("set hardware fifo segment length to %i\n", - devpriv->ai_fifo_segment_length); - - return devpriv->ai_fifo_segment_length; -} - /* Allocate and initialize the subdevice structures. */ static int setup_subdevices(struct comedi_device *dev) -- cgit v1.2.3 From 11aade26508cb7a06b24dfabe76f0cbafd0acf29 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 2 Nov 2012 19:18:06 +0000 Subject: staging: comedi: cb_pcidas64: update driver comment Update the comedi driver comment to reflect the fact that manual attachment of devices is no longer supported. Also replace the request to file a bug report about unidentified PCI device IDs with a request to let the maintainers know about such devices. Reformat the comment using the usual block comment style. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 66 ++++++++++++++-------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 771f0433a79..68a12890322 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -36,39 +36,39 @@ ************************************************************************/ /* - -Driver: cb_pcidas64 -Description: MeasurementComputing PCI-DAS64xx, 60XX, and 4020 series with the PLX 9080 PCI controller -Author: Frank Mori Hess -Status: works -Updated: 2002-10-09 -Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64), - PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16, - PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR, - PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14, - PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6013, PCI-DAS6014, - PCI-DAS6023, PCI-DAS6025, PCI-DAS6030, - PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034, - PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052, - PCI-DAS6070, PCI-DAS6071, PCI-DAS4020/12 - -Configuration options: - [0] - PCI bus of device (optional) - [1] - PCI slot of device (optional) - -These boards may be autocalibrated with the comedi_calibrate utility. - -To select the bnc trigger input on the 4020 (instead of the dio input), -specify a nonzero channel in the chanspec. If you wish to use an external -master clock on the 4020, you may do so by setting the scan_begin_src -to TRIG_OTHER, and using an INSN_CONFIG_TIMER_1 configuration insn -to configure the divisor to use for the external clock. - -Some devices are not identified because the PCI device IDs are not yet -known. If you have such a board, please file a bug report at -https://bugs.comedi.org. - -*/ + * Driver: cb_pcidas64 + * Description: MeasurementComputing PCI-DAS64xx, 60XX, and 4020 series + * with the PLX 9080 PCI controller + * Author: Frank Mori Hess + * Status: works + * Updated: Fri, 02 Nov 2012 18:58:55 +0000 + * Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64), + * PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16, + * PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR, + * PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14, + * PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6013, PCI-DAS6014, + * PCI-DAS6023, PCI-DAS6025, PCI-DAS6030, + * PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034, + * PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052, + * PCI-DAS6070, PCI-DAS6071, PCI-DAS4020/12 + * + * Configuration options: + * None. + * + * Manual attachment of PCI cards with the comedi_config utility is not + * supported by this driver; they are attached automatically. + * + * These boards may be autocalibrated with the comedi_calibrate utility. + * + * To select the bnc trigger input on the 4020 (instead of the dio input), + * specify a nonzero channel in the chanspec. If you wish to use an external + * master clock on the 4020, you may do so by setting the scan_begin_src + * to TRIG_OTHER, and using an INSN_CONFIG_TIMER_1 configuration insn + * to configure the divisor to use for the external clock. + * + * Some devices are not identified because the PCI device IDs are not yet + * known. If you have such a board, please let the maintainers know. + */ /* -- cgit v1.2.3 From 2bb8b1dfe6837ca300a36e7d5c5c9a272aefe5a6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:34:23 -0700 Subject: staging: comedi: addi_apci_1032: separate from addi_common.c The addi_apci_1032 driver is a simple digital input board with 32 optically isolated inputs. Using the addi-data "common" code introduces a lot of bloat. Copy the code in addi_common.c to this driver and remove the #include that caused addi_common.c to be compiled with this driver. This will allow removing the special handling for allocating and freeing the dma buffers in the common code. Rename the attach_pci and detach functions so they have namespace associated with this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 311 +++++++++++++++++++++++- 1 file changed, 308 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 1db3e15ed4b..0ba363ce264 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -6,7 +6,10 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1032.c" -#include "addi-data/addi_common.c" + +#ifndef COMEDI_SUBD_TTLIO +#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ +#endif static const struct addi_board apci1032_boardtypes[] = { { @@ -26,11 +29,313 @@ static const struct addi_board apci1032_boardtypes[] = { }, }; +static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; + unsigned short w_Address = CR_CHAN(insn->chanspec); + unsigned short w_Data; + + w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, + this_board->pc_EepromChip, 2 * w_Address); + data[0] = w_Data; + + return insn->n; +} + +static irqreturn_t v_ADDI_Interrupt(int irq, void *d) +{ + struct comedi_device *dev = d; + const struct addi_board *this_board = comedi_board(dev); + + this_board->interrupt(irq, d); + return IRQ_RETVAL(1); +} + +static int i_ADDI_Reset(struct comedi_device *dev) +{ + const struct addi_board *this_board = comedi_board(dev); + + this_board->reset(dev); + return 0; +} + +static const void *addi_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const void *p = dev->driver->board_name; + const struct addi_board *this_board; + int i; + + for (i = 0; i < dev->driver->num_names; i++) { + this_board = p; + if (this_board->i_VendorId == pcidev->vendor && + this_board->i_DeviceId == pcidev->device) + return this_board; + p += dev->driver->offset; + } + return NULL; +} + +static int apci1032_attach_pci(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const struct addi_board *this_board; + struct addi_private *devpriv; + struct comedi_subdevice *s; + int ret, n_subdevices; + unsigned int dw_Dummy; + + this_board = addi_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->pc_DriverName; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + + if (!this_board->pc_EepromChip || + !strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { + if (this_board->i_IorangeBase1) + dev->iobase = pci_resource_start(pcidev, 1); + else + dev->iobase = pci_resource_start(pcidev, 0); + + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); + } else { + dev->iobase = pci_resource_start(pcidev, 2); + devpriv->iobase = pci_resource_start(pcidev, 2); + devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), + this_board->i_IorangeBase3); + } + devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); + + /* Initialize parameters that can be overridden in EEPROM */ + devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; + devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; + devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; + devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; + devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; + devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; + devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; + devpriv->s_EeParameters.i_Dma = this_board->i_Dma; + devpriv->s_EeParameters.i_Timer = this_board->i_Timer; + devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = + this_board->ui_MinAcquisitiontimeNs; + devpriv->s_EeParameters.ui_MinDelaytimeNs = + this_board->ui_MinDelaytimeNs; + + /* ## */ + + if (pcidev->irq > 0) { + ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } + + /* Read eepeom and fill addi_board Structure */ + + if (this_board->i_PCIEeprom) { + if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { + /* Set 3 wait stait */ + if (!(strcmp(dev->board_name, "apci035"))) { + outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); + } else { + outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); + } + /* Enable the interrupt for the controller */ + dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); + outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); + } + addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); + } + + n_subdevices = 7; + ret = comedi_alloc_subdevices(dev, n_subdevices); + if (ret) + return ret; + + /* Allocate and Initialise AI Subdevice Structures */ + s = &dev->subdevices[0]; + if ((devpriv->s_EeParameters.i_NbrAiChannel) + || (this_board->i_NbrAiChannelDiff)) { + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_COMMON | SDF_GROUND + | SDF_DIFF; + if (devpriv->s_EeParameters.i_NbrAiChannel) { + s->n_chan = + devpriv->s_EeParameters.i_NbrAiChannel; + devpriv->b_SingelDiff = 0; + } else { + s->n_chan = this_board->i_NbrAiChannelDiff; + devpriv->b_SingelDiff = 1; + } + s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; + s->len_chanlist = this_board->i_AiChannelList; + s->range_table = this_board->pr_AiRangelist; + + /* Set the initialisation flag */ + devpriv->b_AiInitialisation = 1; + + s->insn_config = this_board->ai_config; + s->insn_read = this_board->ai_read; + s->insn_write = this_board->ai_write; + s->insn_bits = this_board->ai_bits; + s->do_cmdtest = this_board->ai_cmdtest; + s->do_cmd = this_board->ai_cmd; + s->cancel = this_board->ai_cancel; + + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise AO Subdevice Structures */ + s = &dev->subdevices[1]; + if (devpriv->s_EeParameters.i_NbrAoChannel) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; + s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrAoChannel; + s->range_table = this_board->pr_AoRangelist; + s->insn_config = this_board->ao_config; + s->insn_write = this_board->ao_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DI Subdevice Structures */ + s = &dev->subdevices[2]; + if (devpriv->s_EeParameters.i_NbrDiChannel) { + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; + s->maxdata = 1; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDiChannel; + s->range_table = &range_digital; + s->io_bits = 0; /* all bits input */ + s->insn_config = this_board->di_config; + s->insn_read = this_board->di_read; + s->insn_write = this_board->di_write; + s->insn_bits = this_board->di_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DO Subdevice Structures */ + s = &dev->subdevices[3]; + if (devpriv->s_EeParameters.i_NbrDoChannel) { + s->type = COMEDI_SUBD_DO; + s->subdev_flags = + SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; + s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDoChannel; + s->range_table = &range_digital; + s->io_bits = 0xf; /* all bits output */ + + /* insn_config - for digital output memory */ + s->insn_config = this_board->do_config; + s->insn_write = this_board->do_write; + s->insn_bits = this_board->do_bits; + s->insn_read = this_board->do_read; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise Timer Subdevice Structures */ + s = &dev->subdevices[4]; + if (devpriv->s_EeParameters.i_Timer) { + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + + s->insn_write = this_board->timer_write; + s->insn_read = this_board->timer_read; + s->insn_config = this_board->timer_config; + s->insn_bits = this_board->timer_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise TTL */ + s = &dev->subdevices[5]; + if (this_board->i_NbrTTLChannel) { + s->type = COMEDI_SUBD_TTLIO; + s->subdev_flags = + SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = this_board->i_NbrTTLChannel; + s->maxdata = 1; + s->io_bits = 0; /* all bits input */ + s->len_chanlist = this_board->i_NbrTTLChannel; + s->range_table = &range_digital; + s->insn_config = this_board->ttl_config; + s->insn_bits = this_board->ttl_bits; + s->insn_read = this_board->ttl_read; + s->insn_write = this_board->ttl_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* EEPROM */ + s = &dev->subdevices[6]; + if (this_board->i_PCIEeprom) { + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE | SDF_INTERNAL; + s->n_chan = 256; + s->maxdata = 0xffff; + s->insn_read = i_ADDIDATA_InsnReadEeprom; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + i_ADDI_Reset(dev); + return 0; +} + +static void apci1032_detach(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct addi_private *devpriv = dev->private; + + if (devpriv) { + if (dev->iobase) + i_ADDI_Reset(dev); + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv->dw_AiBase) + iounmap(devpriv->dw_AiBase); + } + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } +} + static struct comedi_driver apci1032_driver = { .driver_name = "addi_apci_1032", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, - .detach = i_ADDI_Detach, + .attach_pci = apci1032_attach_pci, + .detach = apci1032_detach, .num_names = ARRAY_SIZE(apci1032_boardtypes), .board_name = &apci1032_boardtypes[0].pc_DriverName, .offset = sizeof(struct addi_board), -- cgit v1.2.3 From a486baa6cf2f900f252686cc63afc165db11b6e2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:34:40 -0700 Subject: staging: comedi: addi_apci_1032: remove i_ADDI_Reset() This driver is now separate from the "common" code used with the addi-data drivers. There is no need to use i_ADDI_Reset() to call the correct "reset" function. Remove the i_ADDI_Reset() function and the 'reset' pointer to the real function from the boardinfo and just call the function directly where needed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 0ba363ce264..bc153c300ef 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -22,7 +22,6 @@ static const struct addi_board apci1032_boardtypes[] = { .pc_EepromChip = ADDIDATA_93C76, .i_NbrDiChannel = 32, .interrupt = v_APCI1032_Interrupt, - .reset = i_APCI1032_Reset, .di_config = i_APCI1032_ConfigDigitalInput, .di_read = i_APCI1032_Read1DigitalInput, .di_bits = i_APCI1032_ReadMoreDigitalInput, @@ -55,14 +54,6 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) return IRQ_RETVAL(1); } -static int i_ADDI_Reset(struct comedi_device *dev) -{ - const struct addi_board *this_board = comedi_board(dev); - - this_board->reset(dev); - return 0; -} - static const void *addi_find_boardinfo(struct comedi_device *dev, struct pci_dev *pcidev) { @@ -308,7 +299,7 @@ static int apci1032_attach_pci(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - i_ADDI_Reset(dev); + i_APCI1032_Reset(dev); return 0; } @@ -319,7 +310,7 @@ static void apci1032_detach(struct comedi_device *dev) if (devpriv) { if (dev->iobase) - i_ADDI_Reset(dev); + i_APCI1032_Reset(dev); if (dev->irq) free_irq(dev->irq, dev); if (devpriv->dw_AiBase) -- cgit v1.2.3 From 166d15fd1ef33c60af722f68fe9bd149c969567d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:34:57 -0700 Subject: staging: comedi: addi_apci_1032: board does not have ttl i/o This board does not have ttl i/o. Remove the subdevice init for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index bc153c300ef..d44ab6fd7fe 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -7,10 +7,6 @@ #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1032.c" -#ifndef COMEDI_SUBD_TTLIO -#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ -#endif - static const struct addi_board apci1032_boardtypes[] = { { .pc_DriverName = "apci1032", @@ -270,22 +266,7 @@ static int apci1032_attach_pci(struct comedi_device *dev, /* Allocate and Initialise TTL */ s = &dev->subdevices[5]; - if (this_board->i_NbrTTLChannel) { - s->type = COMEDI_SUBD_TTLIO; - s->subdev_flags = - SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrTTLChannel; - s->maxdata = 1; - s->io_bits = 0; /* all bits input */ - s->len_chanlist = this_board->i_NbrTTLChannel; - s->range_table = &range_digital; - s->insn_config = this_board->ttl_config; - s->insn_bits = this_board->ttl_bits; - s->insn_read = this_board->ttl_read; - s->insn_write = this_board->ttl_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; /* EEPROM */ s = &dev->subdevices[6]; -- cgit v1.2.3 From df9133bf19c8fab1ac8932fe4a6e12de6f8f4ddf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:35:13 -0700 Subject: staging: comedi: addi_apci_1032: board does not have a timer This board does not have a timer. Remove the subdevice init for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index d44ab6fd7fe..b34001a539a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -248,21 +248,7 @@ static int apci1032_attach_pci(struct comedi_device *dev, /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[4]; - if (devpriv->s_EeParameters.i_Timer) { - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = 1; - s->maxdata = 0; - s->len_chanlist = 1; - s->range_table = &range_digital; - - s->insn_write = this_board->timer_write; - s->insn_read = this_board->timer_read; - s->insn_config = this_board->timer_config; - s->insn_bits = this_board->timer_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; /* Allocate and Initialise TTL */ s = &dev->subdevices[5]; -- cgit v1.2.3 From 5dbdbf67c3574cec17640ad63109b3b2ef322617 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:35:30 -0700 Subject: staging: comedi: addi_apci_1032: board does not have digital outputs This board does not have digital outputs. Remove the subdevice init for them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index b34001a539a..5ba28613b2c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -224,27 +224,10 @@ static int apci1032_attach_pci(struct comedi_device *dev, } else { s->type = COMEDI_SUBD_UNUSED; } + /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[3]; - if (devpriv->s_EeParameters.i_NbrDoChannel) { - s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; - s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDoChannel; - s->range_table = &range_digital; - s->io_bits = 0xf; /* all bits output */ - - /* insn_config - for digital output memory */ - s->insn_config = this_board->do_config; - s->insn_write = this_board->do_write; - s->insn_bits = this_board->do_bits; - s->insn_read = this_board->do_read; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[4]; -- cgit v1.2.3 From f2a3ac3b030eb2240f8ab8e5bee04378707a0193 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:35:52 -0700 Subject: staging: comedi: addi_apci_1032: board does not have analog inputs This board does not have analog inputs. Remove the subdevice init for them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 34 +------------------------ 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 5ba28613b2c..c3f5292a7d2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -157,39 +157,7 @@ static int apci1032_attach_pci(struct comedi_device *dev, /* Allocate and Initialise AI Subdevice Structures */ s = &dev->subdevices[0]; - if ((devpriv->s_EeParameters.i_NbrAiChannel) - || (this_board->i_NbrAiChannelDiff)) { - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND - | SDF_DIFF; - if (devpriv->s_EeParameters.i_NbrAiChannel) { - s->n_chan = - devpriv->s_EeParameters.i_NbrAiChannel; - devpriv->b_SingelDiff = 0; - } else { - s->n_chan = this_board->i_NbrAiChannelDiff; - devpriv->b_SingelDiff = 1; - } - s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; - s->len_chanlist = this_board->i_AiChannelList; - s->range_table = this_board->pr_AiRangelist; - - /* Set the initialisation flag */ - devpriv->b_AiInitialisation = 1; - - s->insn_config = this_board->ai_config; - s->insn_read = this_board->ai_read; - s->insn_write = this_board->ai_write; - s->insn_bits = this_board->ai_bits; - s->do_cmdtest = this_board->ai_cmdtest; - s->do_cmd = this_board->ai_cmd; - s->cancel = this_board->ai_cancel; - - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; /* Allocate and Initialise AO Subdevice Structures */ s = &dev->subdevices[1]; -- cgit v1.2.3 From 9559ff7e7ef0f0412fda8b28f0674e871f19dd05 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:36:09 -0700 Subject: staging: comedi: addi_apci_1032: board does not have analog outputs This board does not have analog outputs. Remove the subdevice init for them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index c3f5292a7d2..5a0cd1c1054 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -161,19 +161,8 @@ static int apci1032_attach_pci(struct comedi_device *dev, /* Allocate and Initialise AO Subdevice Structures */ s = &dev->subdevices[1]; - if (devpriv->s_EeParameters.i_NbrAoChannel) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; - s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrAoChannel; - s->range_table = this_board->pr_AoRangelist; - s->insn_config = this_board->ao_config; - s->insn_write = this_board->ao_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; + /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[2]; if (devpriv->s_EeParameters.i_NbrDiChannel) { -- cgit v1.2.3 From 4c2c1488d382ab79ca364e1ce988a21df9627bf5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:36:27 -0700 Subject: staging: comedi: addi_apci_1032: board has 32 digital inputs This board always has 32 digital inputs. Remove the test when initializing the subdevice. Also, since this board is the only one supported by this driver, remove the boardinfo about the digital inputs and just use the data directly in the subdevice init. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 28 ++++++++----------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 5a0cd1c1054..70cada42dd1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -18,9 +18,6 @@ static const struct addi_board apci1032_boardtypes[] = { .pc_EepromChip = ADDIDATA_93C76, .i_NbrDiChannel = 32, .interrupt = v_APCI1032_Interrupt, - .di_config = i_APCI1032_ConfigDigitalInput, - .di_read = i_APCI1032_Read1DigitalInput, - .di_bits = i_APCI1032_ReadMoreDigitalInput, }, }; @@ -165,22 +162,15 @@ static int apci1032_attach_pci(struct comedi_device *dev, /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[2]; - if (devpriv->s_EeParameters.i_NbrDiChannel) { - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; - s->maxdata = 1; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDiChannel; - s->range_table = &range_digital; - s->io_bits = 0; /* all bits input */ - s->insn_config = this_board->di_config; - s->insn_read = this_board->di_read; - s->insn_write = this_board->di_write; - s->insn_bits = this_board->di_bits; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 32; + s->maxdata = 1; + s->len_chanlist = 32; + s->range_table = &range_digital; + s->insn_config = i_APCI1032_ConfigDigitalInput; + s->insn_read = i_APCI1032_Read1DigitalInput; + s->insn_bits = i_APCI1032_ReadMoreDigitalInput; /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[3]; -- cgit v1.2.3 From 05f22ad7d2c0cc7db70554745bacdddf48452d22 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:36:53 -0700 Subject: staging: comedi: addi_apci_1032: simplify the PCI bar reading This board has a 93c76 eeprom. Knowing this information allows simplifying the code that reads the PCI bars to get the iobase addresses used in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 70cada42dd1..8ea9feac4e2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -88,22 +88,10 @@ static int apci1032_attach_pci(struct comedi_device *dev, if (ret) return ret; - if (!this_board->pc_EepromChip || - !strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { - if (this_board->i_IorangeBase1) - dev->iobase = pci_resource_start(pcidev, 1); - else - dev->iobase = pci_resource_start(pcidev, 0); - - devpriv->iobase = dev->iobase; - devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); - devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - } else { - dev->iobase = pci_resource_start(pcidev, 2); - devpriv->iobase = pci_resource_start(pcidev, 2); - devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), - this_board->i_IorangeBase3); - } + dev->iobase = pci_resource_start(pcidev, 2); + devpriv->iobase = pci_resource_start(pcidev, 2); + devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), + this_board->i_IorangeBase3); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); /* Initialize parameters that can be overridden in EEPROM */ -- cgit v1.2.3 From 09284a77b2ef7e5fcedb91164a05495732140496 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:37:08 -0700 Subject: staging: comedi: addi_apci_1032: remove dw_AiBase This board does not use the ioremap'ed PCI bar 3 memory address. Remove the ioremap and iounmap of that region. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 8ea9feac4e2..384ccf64db2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -90,8 +90,6 @@ static int apci1032_attach_pci(struct comedi_device *dev, dev->iobase = pci_resource_start(pcidev, 2); devpriv->iobase = pci_resource_start(pcidev, 2); - devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), - this_board->i_IorangeBase3); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); /* Initialize parameters that can be overridden in EEPROM */ @@ -198,8 +196,6 @@ static void apci1032_detach(struct comedi_device *dev) i_APCI1032_Reset(dev); if (dev->irq) free_irq(dev->irq, dev); - if (devpriv->dw_AiBase) - iounmap(devpriv->dw_AiBase); } if (pcidev) { if (dev->iobase) -- cgit v1.2.3 From e0085d1fc9f2068be61e3ec23e1bb95f64fecffe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:37:24 -0700 Subject: staging: comedi: addi_apci_1032: remove i_IorangeBase[01] This boardinfo is no longer required by the driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 384ccf64db2..625d7009e4d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -12,8 +12,6 @@ static const struct addi_board apci1032_boardtypes[] = { .pc_DriverName = "apci1032", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x1003, - .i_IorangeBase0 = 4, - .i_IorangeBase1 = APCI1032_ADDRESS_RANGE, .i_PCIEeprom = ADDIDATA_EEPROM, .pc_EepromChip = ADDIDATA_93C76, .i_NbrDiChannel = 32, -- cgit v1.2.3 From 427ee2be54d9a30861226cc65b16659a01b140f3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:37:40 -0700 Subject: staging: comedi: addi_apci_1032: remove use of devpriv->iobase Currently, devpriv->iobase is used to hold the PCI bar 2 base address used to read/write the registers on the board. The same information is stored in the comedi_device dev->iobase. Use that instead. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1032.c | 42 +++++++++++----------- drivers/staging/comedi/drivers/addi_apci_1032.c | 1 - 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index 30a44aea0c2..72e4480fb5c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -116,26 +116,26 @@ static int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, ul_Command1 = ul_Command1 | data[2]; ul_Command2 = ul_Command2 | data[3]; outl(ul_Command1, - devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); + dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); outl(ul_Command2, - devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); + dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); if (data[1] == ADDIDATA_OR) { - outl(0x4, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); + outl(0x4, dev->iobase + APCI1032_DIGITAL_IP_IRQ); ui_TmpValue = - inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); + inl(dev->iobase + APCI1032_DIGITAL_IP_IRQ); } /* if (data[1] == ADDIDATA_OR) */ else - outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); + outl(0x6, dev->iobase + APCI1032_DIGITAL_IP_IRQ); /* else if(data[1] == ADDIDATA_OR) */ } /* if( data[0] == ADDIDATA_ENABLE) */ else { ul_Command1 = ul_Command1 & 0xFFFF0000; ul_Command2 = ul_Command2 & 0xFFFF0000; outl(ul_Command1, - devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); + dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); outl(ul_Command2, - devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); - outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); + dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); + outl(0x0, dev->iobase + APCI1032_DIGITAL_IP_IRQ); } /* else if ( data[0] == ADDIDATA_ENABLE) */ return insn->n; @@ -165,13 +165,12 @@ static int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue = 0; unsigned int ui_Channel; ui_Channel = CR_CHAN(insn->chanspec); if (ui_Channel <= 31) { - ui_TmpValue = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP); + ui_TmpValue = (unsigned int) inl(dev->iobase + APCI1032_DIGITAL_IP); /* * since only 1 channel reqd to bring it to last bit it is rotated 8 * +(chan - 1) times then ANDed with 1 for last bit. @@ -210,14 +209,13 @@ static int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; unsigned int ui_PortValue = data[0]; unsigned int ui_Mask = 0; unsigned int ui_NoOfChannels; ui_NoOfChannels = CR_CHAN(insn->chanspec); if (data[1] == 0) { - *data = (unsigned int) inl(devpriv->iobase + APCI1032_DIGITAL_IP); + *data = (unsigned int) inl(dev->iobase + APCI1032_DIGITAL_IP); switch (ui_NoOfChannels) { case 2: ui_Mask = 3; @@ -275,14 +273,14 @@ static void v_APCI1032_Interrupt(int irq, void *d) unsigned int ui_Temp; /* disable the interrupt */ - ui_Temp = inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); + ui_Temp = inl(dev->iobase + APCI1032_DIGITAL_IP_IRQ); outl(ui_Temp & APCI1032_DIGITAL_IP_INTERRUPT_DISABLE, - devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); + dev->iobase + APCI1032_DIGITAL_IP_IRQ); ui_InterruptStatus = - inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); + inl(dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF; send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - outl(ui_Temp, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); /* enable the interrupt */ + outl(ui_Temp, dev->iobase + APCI1032_DIGITAL_IP_IRQ); /* enable the interrupt */ return; } @@ -303,11 +301,13 @@ static void v_APCI1032_Interrupt(int irq, void *d) static int i_APCI1032_Reset(struct comedi_device *dev) { - struct addi_private *devpriv = dev->private; + /* disable the interrupts */ + outl(0x0, dev->iobase + APCI1032_DIGITAL_IP_IRQ); + /* Reset the interrupt status register */ + inl(dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); + /* Disable the and/or interrupt */ + outl(0x0, dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); + outl(0x0, dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); - outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); /* disable the interrupts */ - inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); /* Reset the interrupt status register */ - outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); /* Disable the and/or interrupt */ - outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); return 0; } diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 625d7009e4d..eca5c5da687 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -87,7 +87,6 @@ static int apci1032_attach_pci(struct comedi_device *dev, return ret; dev->iobase = pci_resource_start(pcidev, 2); - devpriv->iobase = pci_resource_start(pcidev, 2); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); /* Initialize parameters that can be overridden in EEPROM */ -- cgit v1.2.3 From cea5d88c340873bd2f8735342bc79292f98b9944 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:37:56 -0700 Subject: staging: comedi: addi_apci_1032: remove i_IobaseReserved PCI bar 3 is not used by this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index eca5c5da687..ab9453d828a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -87,7 +87,6 @@ static int apci1032_attach_pci(struct comedi_device *dev, return ret; dev->iobase = pci_resource_start(pcidev, 2); - devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); /* Initialize parameters that can be overridden in EEPROM */ devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; -- cgit v1.2.3 From b1b640a8d8f1f1111d393dd07c8453550fb7cfae Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:38:11 -0700 Subject: staging: comedi: addi_apci_1032: remove unnecessary eeprom code Now that this driver is separate from the "common" addi-data code, the eeprom does not contain any information required to make this driver work. Remove the unneeded initalization of the 's_EeParameters' and the code that reads the eeprom to fill in the parameters. Also, since reading the eeprom is not really interesting, remove the EEPROM subdevice. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 63 +------------------------ 1 file changed, 1 insertion(+), 62 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index ab9453d828a..159e70d1e84 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -4,7 +4,6 @@ #include "addi-data/addi_common.h" -#include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1032.c" static const struct addi_board apci1032_boardtypes[] = { @@ -19,23 +18,6 @@ static const struct addi_board apci1032_boardtypes[] = { }, }; -static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = comedi_board(dev); - struct addi_private *devpriv = dev->private; - unsigned short w_Address = CR_CHAN(insn->chanspec); - unsigned short w_Data; - - w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, - this_board->pc_EepromChip, 2 * w_Address); - data[0] = w_Data; - - return insn->n; -} - static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { struct comedi_device *dev = d; @@ -69,7 +51,6 @@ static int apci1032_attach_pci(struct comedi_device *dev, struct addi_private *devpriv; struct comedi_subdevice *s; int ret, n_subdevices; - unsigned int dw_Dummy; this_board = addi_find_boardinfo(dev, pcidev); if (!this_board) @@ -88,23 +69,6 @@ static int apci1032_attach_pci(struct comedi_device *dev, dev->iobase = pci_resource_start(pcidev, 2); - /* Initialize parameters that can be overridden in EEPROM */ - devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; - devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; - devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; - devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; - devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; - devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; - devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; - devpriv->s_EeParameters.i_Dma = this_board->i_Dma; - devpriv->s_EeParameters.i_Timer = this_board->i_Timer; - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = - this_board->ui_MinAcquisitiontimeNs; - devpriv->s_EeParameters.ui_MinDelaytimeNs = - this_board->ui_MinDelaytimeNs; - - /* ## */ - if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, dev->board_name, dev); @@ -112,23 +76,6 @@ static int apci1032_attach_pci(struct comedi_device *dev, dev->irq = pcidev->irq; } - /* Read eepeom and fill addi_board Structure */ - - if (this_board->i_PCIEeprom) { - if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { - /* Set 3 wait stait */ - if (!(strcmp(dev->board_name, "apci035"))) { - outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); - } else { - outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); - } - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - } - addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); - } - n_subdevices = 7; ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret) @@ -168,15 +115,7 @@ static int apci1032_attach_pci(struct comedi_device *dev, /* EEPROM */ s = &dev->subdevices[6]; - if (this_board->i_PCIEeprom) { - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 256; - s->maxdata = 0xffff; - s->insn_read = i_ADDIDATA_InsnReadEeprom; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; i_APCI1032_Reset(dev); return 0; -- cgit v1.2.3 From feae759ffe973179020a14c93d94d7936e407d48 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:38:26 -0700 Subject: staging: comedi: addi_apci_1032: call v_APCI1032_Interrupt() directly Remove the boardinfo about the 'interrupt' function and just call it directly. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 159e70d1e84..7e606620ef6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -14,16 +14,12 @@ static const struct addi_board apci1032_boardtypes[] = { .i_PCIEeprom = ADDIDATA_EEPROM, .pc_EepromChip = ADDIDATA_93C76, .i_NbrDiChannel = 32, - .interrupt = v_APCI1032_Interrupt, }, }; static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { - struct comedi_device *dev = d; - const struct addi_board *this_board = comedi_board(dev); - - this_board->interrupt(irq, d); + v_APCI1032_Interrupt(irq, d); return IRQ_RETVAL(1); } -- cgit v1.2.3 From ac467b5e21f6c1e888f57abe0ee4e35b28849549 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:38:41 -0700 Subject: staging: comedi: addi_apci_1032: remove the boardinfo This driver supports only one boardtype. Since this driver uses the comedi auto attach mechanism, the information left in the boaridnfo is not required to attach this driver to the comedi subsystem. Remove the boardinfo data and its use in the driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 38 +------------------------ 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 7e606620ef6..45b254834f8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -6,53 +6,20 @@ #include "addi-data/hwdrv_apci1032.c" -static const struct addi_board apci1032_boardtypes[] = { - { - .pc_DriverName = "apci1032", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1003, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_93C76, - .i_NbrDiChannel = 32, - }, -}; - static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { v_APCI1032_Interrupt(irq, d); return IRQ_RETVAL(1); } -static const void *addi_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - const void *p = dev->driver->board_name; - const struct addi_board *this_board; - int i; - - for (i = 0; i < dev->driver->num_names; i++) { - this_board = p; - if (this_board->i_VendorId == pcidev->vendor && - this_board->i_DeviceId == pcidev->device) - return this_board; - p += dev->driver->offset; - } - return NULL; -} - static int apci1032_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { - const struct addi_board *this_board; struct addi_private *devpriv; struct comedi_subdevice *s; int ret, n_subdevices; - this_board = addi_find_boardinfo(dev, pcidev); - if (!this_board) - return -ENODEV; - dev->board_ptr = this_board; - dev->board_name = this_board->pc_DriverName; + dev->board_name = dev->driver->driver_name; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) @@ -139,9 +106,6 @@ static struct comedi_driver apci1032_driver = { .module = THIS_MODULE, .attach_pci = apci1032_attach_pci, .detach = apci1032_detach, - .num_names = ARRAY_SIZE(apci1032_boardtypes), - .board_name = &apci1032_boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), }; static int __devinit apci1032_pci_probe(struct pci_dev *dev, -- cgit v1.2.3 From c0133ee10a2542d2a8964321d7d50414b05e0a6a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:38:56 -0700 Subject: staging: comedi: addi_apci_1032: cleanup the register map defines For aesthetic reasons, rename the defines used for the register map so they are a bit shorter. Define, and use, the bits in the interrupt control register. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1032.c | 75 ++++++++++------------ 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index 72e4480fb5c..767392a9ac8 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -46,27 +46,22 @@ You should also find the complete GPL in the COPYING file accompanying this sour +----------+-----------+------------------------------------------------+ */ -/********* Definitions for APCI-1032 card *****/ - -#define APCI1032_ADDRESS_RANGE 20 -/* DIGITAL INPUT DEFINE */ - -#define APCI1032_DIGITAL_IP 0 -#define APCI1032_DIGITAL_IP_INTERRUPT_MODE1 4 -#define APCI1032_DIGITAL_IP_INTERRUPT_MODE2 8 -#define APCI1032_DIGITAL_IP_IRQ 16 +/* + * I/O Register Map + */ +#define APCI1032_DI_REG 0x00 +#define APCI1032_MODE1_REG 0x04 +#define APCI1032_MODE2_REG 0x08 +#define APCI1032_STATUS_REG 0x0c +#define APCI1032_CTRL_REG 0x10 +#define APCI1032_CTRL_INT_OR (0 << 1) +#define APCI1032_CTRL_INT_AND (1 << 1) +#define APCI1032_CTRL_INT_ENA (1 << 2) /* Digital Input IRQ Function Selection */ #define ADDIDATA_OR 0 #define ADDIDATA_AND 1 -/* Digital Input Interrupt Status */ -#define APCI1032_DIGITAL_IP_INTERRUPT_STATUS 12 - -/* Digital Input Interrupt Enable Disable. */ -#define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE 0x4 -#define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE 0xfffffffb - static unsigned int ui_InterruptStatus; /* @@ -115,27 +110,27 @@ static int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, if (data[0] == ADDIDATA_ENABLE) { ul_Command1 = ul_Command1 | data[2]; ul_Command2 = ul_Command2 | data[3]; - outl(ul_Command1, - dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); - outl(ul_Command2, - dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); + outl(ul_Command1, dev->iobase + APCI1032_MODE1_REG); + outl(ul_Command2, dev->iobase + APCI1032_MODE2_REG); if (data[1] == ADDIDATA_OR) { - outl(0x4, dev->iobase + APCI1032_DIGITAL_IP_IRQ); + outl(APCI1032_CTRL_INT_ENA | + APCI1032_CTRL_INT_OR, + dev->iobase + APCI1032_CTRL_REG); ui_TmpValue = - inl(dev->iobase + APCI1032_DIGITAL_IP_IRQ); + inl(dev->iobase + APCI1032_CTRL_REG); } /* if (data[1] == ADDIDATA_OR) */ else - outl(0x6, dev->iobase + APCI1032_DIGITAL_IP_IRQ); + outl(APCI1032_CTRL_INT_ENA | + APCI1032_CTRL_INT_AND, + dev->iobase + APCI1032_CTRL_REG); /* else if(data[1] == ADDIDATA_OR) */ } /* if( data[0] == ADDIDATA_ENABLE) */ else { ul_Command1 = ul_Command1 & 0xFFFF0000; ul_Command2 = ul_Command2 & 0xFFFF0000; - outl(ul_Command1, - dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); - outl(ul_Command2, - dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); - outl(0x0, dev->iobase + APCI1032_DIGITAL_IP_IRQ); + outl(ul_Command1, dev->iobase + APCI1032_MODE1_REG); + outl(ul_Command2, dev->iobase + APCI1032_MODE2_REG); + outl(0x0, dev->iobase + APCI1032_CTRL_REG); } /* else if ( data[0] == ADDIDATA_ENABLE) */ return insn->n; @@ -170,7 +165,7 @@ static int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, ui_Channel = CR_CHAN(insn->chanspec); if (ui_Channel <= 31) { - ui_TmpValue = (unsigned int) inl(dev->iobase + APCI1032_DIGITAL_IP); + ui_TmpValue = inl(dev->iobase + APCI1032_DI_REG); /* * since only 1 channel reqd to bring it to last bit it is rotated 8 * +(chan - 1) times then ANDed with 1 for last bit. @@ -215,7 +210,7 @@ static int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, ui_NoOfChannels = CR_CHAN(insn->chanspec); if (data[1] == 0) { - *data = (unsigned int) inl(dev->iobase + APCI1032_DIGITAL_IP); + *data = inl(dev->iobase + APCI1032_DI_REG); switch (ui_NoOfChannels) { case 2: ui_Mask = 3; @@ -273,14 +268,14 @@ static void v_APCI1032_Interrupt(int irq, void *d) unsigned int ui_Temp; /* disable the interrupt */ - ui_Temp = inl(dev->iobase + APCI1032_DIGITAL_IP_IRQ); - outl(ui_Temp & APCI1032_DIGITAL_IP_INTERRUPT_DISABLE, - dev->iobase + APCI1032_DIGITAL_IP_IRQ); - ui_InterruptStatus = - inl(dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); + ui_Temp = inl(dev->iobase + APCI1032_CTRL_REG); + outl(ui_Temp & ~APCI1032_CTRL_INT_ENA, + dev->iobase + APCI1032_CTRL_REG); + ui_InterruptStatus = inl(dev->iobase + APCI1032_STATUS_REG); ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF; send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - outl(ui_Temp, dev->iobase + APCI1032_DIGITAL_IP_IRQ); /* enable the interrupt */ + /* enable the interrupt */ + outl(ui_Temp, dev->iobase + APCI1032_CTRL_REG); return; } @@ -302,12 +297,12 @@ static void v_APCI1032_Interrupt(int irq, void *d) static int i_APCI1032_Reset(struct comedi_device *dev) { /* disable the interrupts */ - outl(0x0, dev->iobase + APCI1032_DIGITAL_IP_IRQ); + outl(0x0, dev->iobase + APCI1032_CTRL_REG); /* Reset the interrupt status register */ - inl(dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); + inl(dev->iobase + APCI1032_STATUS_REG); /* Disable the and/or interrupt */ - outl(0x0, dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); - outl(0x0, dev->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2); + outl(0x0, dev->iobase + APCI1032_MODE1_REG); + outl(0x0, dev->iobase + APCI1032_MODE2_REG); return 0; } -- cgit v1.2.3 From 274113fd788eefa573eba55f47068cf6052beef0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:39:12 -0700 Subject: staging: comedi: addi_apci_1032: cleanup i_APCI1032_Reset() Move this function from hwdrv_apci1032.c. Remove the unnecessary comment and rename the CamelCase function to apci1032_reset(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1032.c | 28 ---------------------- drivers/staging/comedi/drivers/addi_apci_1032.c | 17 +++++++++++-- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index 767392a9ac8..337a46ef0cf 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -278,31 +278,3 @@ static void v_APCI1032_Interrupt(int irq, void *d) outl(ui_Temp, dev->iobase + APCI1032_CTRL_REG); return; } - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1032_Reset(struct comedi_device *dev) | | -+----------------------------------------------------------------------------+ -| Task :resets all the registers | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI1032_Reset(struct comedi_device *dev) -{ - /* disable the interrupts */ - outl(0x0, dev->iobase + APCI1032_CTRL_REG); - /* Reset the interrupt status register */ - inl(dev->iobase + APCI1032_STATUS_REG); - /* Disable the and/or interrupt */ - outl(0x0, dev->iobase + APCI1032_MODE1_REG); - outl(0x0, dev->iobase + APCI1032_MODE2_REG); - - return 0; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 45b254834f8..717e122ef94 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -12,6 +12,19 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) return IRQ_RETVAL(1); } +static int apci1032_reset(struct comedi_device *dev) +{ + /* disable the interrupts */ + outl(0x0, dev->iobase + APCI1032_CTRL_REG); + /* Reset the interrupt status register */ + inl(dev->iobase + APCI1032_STATUS_REG); + /* Disable the and/or interrupt */ + outl(0x0, dev->iobase + APCI1032_MODE1_REG); + outl(0x0, dev->iobase + APCI1032_MODE2_REG); + + return 0; +} + static int apci1032_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { @@ -80,7 +93,7 @@ static int apci1032_attach_pci(struct comedi_device *dev, s = &dev->subdevices[6]; s->type = COMEDI_SUBD_UNUSED; - i_APCI1032_Reset(dev); + apci1032_reset(dev); return 0; } @@ -91,7 +104,7 @@ static void apci1032_detach(struct comedi_device *dev) if (devpriv) { if (dev->iobase) - i_APCI1032_Reset(dev); + apci1032_reset(dev); if (dev->irq) free_irq(dev->irq, dev); } -- cgit v1.2.3 From d6d708485505f7696411e8e7bfecc9162961595f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:39:30 -0700 Subject: staging: comedi: addi_apci_1032: fix i_APCI1032_ReadMoreDigitalInput() This function is the insn_bits operation for the digital input subdevice. According to the comedi API it's supposed return the status of the inputs in data[1]. The addi-drivers abuse the API and try to make it conform to their own use. Fix this function so it follows the comedi API. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1032.c | 37 +--------------------- 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index 337a46ef0cf..aa4f022b9c7 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -204,43 +204,8 @@ static int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - unsigned int ui_PortValue = data[0]; - unsigned int ui_Mask = 0; - unsigned int ui_NoOfChannels; + data[1] = inl(dev->iobase + APCI1032_DI_REG); - ui_NoOfChannels = CR_CHAN(insn->chanspec); - if (data[1] == 0) { - *data = inl(dev->iobase + APCI1032_DI_REG); - switch (ui_NoOfChannels) { - case 2: - ui_Mask = 3; - *data = (*data >> (2 * ui_PortValue)) & ui_Mask; - break; - case 4: - ui_Mask = 15; - *data = (*data >> (4 * ui_PortValue)) & ui_Mask; - break; - case 8: - ui_Mask = 255; - *data = (*data >> (8 * ui_PortValue)) & ui_Mask; - break; - case 16: - ui_Mask = 65535; - *data = (*data >> (16 * ui_PortValue)) & ui_Mask; - break; - case 31: - break; - default: - /* comedi_error(dev," \nchan spec wrong\n"); */ - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch(ui_NoOfChannels) */ - } /* if(data[1]==0) */ - else { - if (data[1] == 1) - *data = ui_InterruptStatus; - /* if(data[1]==1) */ - } /* else if(data[1]==0) */ return insn->n; } -- cgit v1.2.3 From b4c137506e85b2f2cfe41eb73aa7ece9f39ade40 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:39:46 -0700 Subject: staging: comedi: addi_apci_1032: remove i_APCI1032_Read1DigitalInput() This function is the insn_read operation for the digital input subdevice. This operation can be emulated by the comedi core now that the insn_bits operation follows the comedi API. Remove this now unnecessary function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1032.c | 43 ---------------------- drivers/staging/comedi/drivers/addi_apci_1032.c | 1 - 2 files changed, 44 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index aa4f022b9c7..be3577687b5 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -136,49 +136,6 @@ static int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1032_Read1DigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the digital input | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_Channel : Channel number to read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI1032_Read1DigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - unsigned int ui_TmpValue = 0; - unsigned int ui_Channel; - ui_Channel = CR_CHAN(insn->chanspec); - - if (ui_Channel <= 31) { - ui_TmpValue = inl(dev->iobase + APCI1032_DI_REG); -/* -* since only 1 channel reqd to bring it to last bit it is rotated 8 -* +(chan - 1) times then ANDed with 1 for last bit. -*/ - *data = (ui_TmpValue >> ui_Channel) & 0x1; - } /* if(ui_Channel >= 0 && ui_Channel <=31) */ - else { - /* comedi_error(dev," \n chan spec wrong\n"); */ - return -EINVAL; /* "sorry channel spec wrong " */ - } /* else if(ui_Channel >= 0 && ui_Channel <=31) */ - return insn->n; -} - /* +----------------------------------------------------------------------------+ | Function Name : int i_APCI1032_ReadMoreDigitalInput | diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 717e122ef94..77e78df65b8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -74,7 +74,6 @@ static int apci1032_attach_pci(struct comedi_device *dev, s->len_chanlist = 32; s->range_table = &range_digital; s->insn_config = i_APCI1032_ConfigDigitalInput; - s->insn_read = i_APCI1032_Read1DigitalInput; s->insn_bits = i_APCI1032_ReadMoreDigitalInput; /* Allocate and Initialise DO Subdevice Structures */ -- cgit v1.2.3 From a3de4cd33c63c256b2521e61e487ae99cf313d94 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:40:02 -0700 Subject: staging: comedi: addi_apci_1032: cleanup i_APCI1032_ReadMoreDigitalInput() Move this function from hwdrv_apci1032.c. Remove the unnecessary comment and rename the CamelCase function to apci1032_di_insn_bits(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1032.c | 30 ---------------------- drivers/staging/comedi/drivers/addi_apci_1032.c | 12 ++++++++- 2 files changed, 11 insertions(+), 31 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index be3577687b5..3e3c229dba9 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -136,36 +136,6 @@ static int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1032_ReadMoreDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the Requested digital inputs | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To be Read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - data[1] = inl(dev->iobase + APCI1032_DI_REG); - - return insn->n; -} - /* +----------------------------------------------------------------------------+ | Function Name : static void v_APCI1032_Interrupt | diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 77e78df65b8..9e60d1f30e6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -12,6 +12,16 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) return IRQ_RETVAL(1); } +static int apci1032_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + data[1] = inl(dev->iobase + APCI1032_DI_REG); + + return insn->n; +} + static int apci1032_reset(struct comedi_device *dev) { /* disable the interrupts */ @@ -74,7 +84,7 @@ static int apci1032_attach_pci(struct comedi_device *dev, s->len_chanlist = 32; s->range_table = &range_digital; s->insn_config = i_APCI1032_ConfigDigitalInput; - s->insn_bits = i_APCI1032_ReadMoreDigitalInput; + s->insn_bits = apci1032_di_insn_bits; /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[3]; -- cgit v1.2.3 From b37f84d56af3efcadd3fc01630f029382707e312 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:40:18 -0700 Subject: staging: comedi: addi_apci_1032: only allocate one subdevice There is only one subdevice used in the driver. Remove the unused subdevice init and only allcoate space for the one used. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 31 +++---------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 9e60d1f30e6..1b4d6983aa5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -40,7 +40,7 @@ static int apci1032_attach_pci(struct comedi_device *dev, { struct addi_private *devpriv; struct comedi_subdevice *s; - int ret, n_subdevices; + int ret; dev->board_name = dev->driver->driver_name; @@ -62,21 +62,12 @@ static int apci1032_attach_pci(struct comedi_device *dev, dev->irq = pcidev->irq; } - n_subdevices = 7; - ret = comedi_alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, 1); if (ret) return ret; - /* Allocate and Initialise AI Subdevice Structures */ - s = &dev->subdevices[0]; - s->type = COMEDI_SUBD_UNUSED; - - /* Allocate and Initialise AO Subdevice Structures */ - s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_UNUSED; - /* Allocate and Initialise DI Subdevice Structures */ - s = &dev->subdevices[2]; + s = &dev->subdevices[0]; s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE; s->n_chan = 32; @@ -86,22 +77,6 @@ static int apci1032_attach_pci(struct comedi_device *dev, s->insn_config = i_APCI1032_ConfigDigitalInput; s->insn_bits = apci1032_di_insn_bits; - /* Allocate and Initialise DO Subdevice Structures */ - s = &dev->subdevices[3]; - s->type = COMEDI_SUBD_UNUSED; - - /* Allocate and Initialise Timer Subdevice Structures */ - s = &dev->subdevices[4]; - s->type = COMEDI_SUBD_UNUSED; - - /* Allocate and Initialise TTL */ - s = &dev->subdevices[5]; - s->type = COMEDI_SUBD_UNUSED; - - /* EEPROM */ - s = &dev->subdevices[6]; - s->type = COMEDI_SUBD_UNUSED; - apci1032_reset(dev); return 0; } -- cgit v1.2.3 From 12d606f75422f4989a853c7c52b06a3b15ef59a2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:40:34 -0700 Subject: staging: comedi: addi_apci_1032: cleanup v_ADDI_Interrupt() There is no need for this function to call v_APCI1032_Interrupt() in hwdrv_apci1032.c to reset the board. Just move the code from v_APCI1032_Interrupt() directly into this function. Rename the CamelCase function to apci1032_interrupt(). Rename the CamelCase local variable used to read/write the control register. Change the return from IRQ_RETVAL(1) to IRQ_HANDLED. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1032.c | 35 ---------------------- drivers/staging/comedi/drivers/addi_apci_1032.c | 22 +++++++++++--- 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c index 3e3c229dba9..6ee5d5d6d10 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c @@ -135,38 +135,3 @@ static int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, return insn->n; } - -/* -+----------------------------------------------------------------------------+ -| Function Name : static void v_APCI1032_Interrupt | -| (int irq , void *d) | -+----------------------------------------------------------------------------+ -| Task : Interrupt handler for the interruptible digital inputs | -+----------------------------------------------------------------------------+ -| Input Parameters : int irq : irq number | -| void *d : void pointer | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static void v_APCI1032_Interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; - unsigned int ui_Temp; - - /* disable the interrupt */ - ui_Temp = inl(dev->iobase + APCI1032_CTRL_REG); - outl(ui_Temp & ~APCI1032_CTRL_INT_ENA, - dev->iobase + APCI1032_CTRL_REG); - ui_InterruptStatus = inl(dev->iobase + APCI1032_STATUS_REG); - ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF; - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ - /* enable the interrupt */ - outl(ui_Temp, dev->iobase + APCI1032_CTRL_REG); - return; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 1b4d6983aa5..ab346719671 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -6,10 +6,24 @@ #include "addi-data/hwdrv_apci1032.c" -static irqreturn_t v_ADDI_Interrupt(int irq, void *d) +static irqreturn_t apci1032_interrupt(int irq, void *d) { - v_APCI1032_Interrupt(irq, d); - return IRQ_RETVAL(1); + struct comedi_device *dev = d; + struct addi_private *devpriv = dev->private; + unsigned int ctrl; + + /* disable the interrupt */ + ctrl = inl(dev->iobase + APCI1032_CTRL_REG); + outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG); + + ui_InterruptStatus = inl(dev->iobase + APCI1032_STATUS_REG); + ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF; + send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ + + /* enable the interrupt */ + outl(ctrl, dev->iobase + APCI1032_CTRL_REG); + + return IRQ_HANDLED; } static int apci1032_di_insn_bits(struct comedi_device *dev, @@ -56,7 +70,7 @@ static int apci1032_attach_pci(struct comedi_device *dev, dev->iobase = pci_resource_start(pcidev, 2); if (pcidev->irq > 0) { - ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + ret = request_irq(pcidev->irq, apci1032_interrupt, IRQF_SHARED, dev->board_name, dev); if (ret == 0) dev->irq = pcidev->irq; -- cgit v1.2.3 From 6a3734af9aa8b036765b678b1b69b5672fa13679 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:40:50 -0700 Subject: staging: comedi: addi_apci_1032: merge in hwdrv_apci1032.c Merge the remaining code from hwdrv_apci1032.c into the driver and delete the now unused file. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1032.c | 137 --------------------- drivers/staging/comedi/drivers/addi_apci_1032.c | 101 ++++++++++++++- 2 files changed, 100 insertions(+), 138 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c deleted file mode 100644 index 6ee5d5d6d10..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c +++ /dev/null @@ -1,137 +0,0 @@ -/** -@verbatim - -Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - - ADDI-DATA GmbH - Dieselstrasse 3 - D-77833 Ottersweier - Tel: +19(0)7223/9493-0 - Fax: +49(0)7223/9493-92 - http://www.addi-data.com - info@addi-data.com - -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. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -You should also find the complete GPL in the COPYING file accompanying this source code. - -@endverbatim -*/ -/* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-------------------------------+---------------------------------------+ - | Project : APCI-1032 | Compiler : GCC | - | Module name : hwdrv_apci1032.c| Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-------------------------------+---------------------------------------+ - | Description : Hardware Layer Access For APCI-1032 | - +-----------------------------------------------------------------------+ - | UPDATES | - +----------+-----------+------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | | | | - | | | | - | | | | - +----------+-----------+------------------------------------------------+ -*/ - -/* - * I/O Register Map - */ -#define APCI1032_DI_REG 0x00 -#define APCI1032_MODE1_REG 0x04 -#define APCI1032_MODE2_REG 0x08 -#define APCI1032_STATUS_REG 0x0c -#define APCI1032_CTRL_REG 0x10 -#define APCI1032_CTRL_INT_OR (0 << 1) -#define APCI1032_CTRL_INT_AND (1 << 1) -#define APCI1032_CTRL_INT_ENA (1 << 2) - -/* Digital Input IRQ Function Selection */ -#define ADDIDATA_OR 0 -#define ADDIDATA_AND 1 - -static unsigned int ui_InterruptStatus; - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1032_ConfigDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Configures the digital input Subdevice | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| | -| data[0] : 1 Enable Digital Input Interrupt | -| 0 Disable Digital Input Interrupt | -| data[1] : 0 ADDIDATA Interrupt OR LOGIC | -| : 1 ADDIDATA Interrupt AND LOGIC | -| data[2] : Interrupt mask for the mode 1 | -| data[3] : Interrupt mask for the mode 2 | -| | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_TmpValue; - unsigned int ul_Command1 = 0; - unsigned int ul_Command2 = 0; - - devpriv->tsk_Current = current; - - /*******************************/ - /* Set the digital input logic */ - /*******************************/ - if (data[0] == ADDIDATA_ENABLE) { - ul_Command1 = ul_Command1 | data[2]; - ul_Command2 = ul_Command2 | data[3]; - outl(ul_Command1, dev->iobase + APCI1032_MODE1_REG); - outl(ul_Command2, dev->iobase + APCI1032_MODE2_REG); - if (data[1] == ADDIDATA_OR) { - outl(APCI1032_CTRL_INT_ENA | - APCI1032_CTRL_INT_OR, - dev->iobase + APCI1032_CTRL_REG); - ui_TmpValue = - inl(dev->iobase + APCI1032_CTRL_REG); - } /* if (data[1] == ADDIDATA_OR) */ - else - outl(APCI1032_CTRL_INT_ENA | - APCI1032_CTRL_INT_AND, - dev->iobase + APCI1032_CTRL_REG); - /* else if(data[1] == ADDIDATA_OR) */ - } /* if( data[0] == ADDIDATA_ENABLE) */ - else { - ul_Command1 = ul_Command1 & 0xFFFF0000; - ul_Command2 = ul_Command2 & 0xFFFF0000; - outl(ul_Command1, dev->iobase + APCI1032_MODE1_REG); - outl(ul_Command2, dev->iobase + APCI1032_MODE2_REG); - outl(0x0, dev->iobase + APCI1032_CTRL_REG); - } /* else if ( data[0] == ADDIDATA_ENABLE) */ - - return insn->n; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index ab346719671..3d5cbbfc8b3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -1,10 +1,109 @@ +/* + * addi_apci_1032.c + * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. + * Project manager: Eric Stolz + * + * ADDI-DATA GmbH + * Dieselstrasse 3 + * D-77833 Ottersweier + * Tel: +19(0)7223/9493-0 + * Fax: +49(0)7223/9493-92 + * http://www.addi-data.com + * info@addi-data.com + * + * 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + * + * You should also find the complete GPL in the COPYING file accompanying this + * source code. + */ + #include "../comedidev.h" #include "comedi_fc.h" #include "amcc_s5933.h" #include "addi-data/addi_common.h" -#include "addi-data/hwdrv_apci1032.c" +/* + * I/O Register Map + */ +#define APCI1032_DI_REG 0x00 +#define APCI1032_MODE1_REG 0x04 +#define APCI1032_MODE2_REG 0x08 +#define APCI1032_STATUS_REG 0x0c +#define APCI1032_CTRL_REG 0x10 +#define APCI1032_CTRL_INT_OR (0 << 1) +#define APCI1032_CTRL_INT_AND (1 << 1) +#define APCI1032_CTRL_INT_ENA (1 << 2) + +/* Digital Input IRQ Function Selection */ +#define ADDIDATA_OR 0 +#define ADDIDATA_AND 1 + +static unsigned int ui_InterruptStatus; + +/* + * data[0] : 1 Enable Digital Input Interrupt + * 0 Disable Digital Input Interrupt + * data[1] : 0 ADDIDATA Interrupt OR LOGIC + * : 1 ADDIDATA Interrupt AND LOGIC + * data[2] : Interrupt mask for the mode 1 + * data[3] : Interrupt mask for the mode 2 + */ +static int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct addi_private *devpriv = dev->private; + unsigned int ui_TmpValue; + unsigned int ul_Command1 = 0; + unsigned int ul_Command2 = 0; + + devpriv->tsk_Current = current; + + /*******************************/ + /* Set the digital input logic */ + /*******************************/ + if (data[0] == ADDIDATA_ENABLE) { + ul_Command1 = ul_Command1 | data[2]; + ul_Command2 = ul_Command2 | data[3]; + outl(ul_Command1, dev->iobase + APCI1032_MODE1_REG); + outl(ul_Command2, dev->iobase + APCI1032_MODE2_REG); + if (data[1] == ADDIDATA_OR) { + outl(APCI1032_CTRL_INT_ENA | + APCI1032_CTRL_INT_OR, + dev->iobase + APCI1032_CTRL_REG); + ui_TmpValue = + inl(dev->iobase + APCI1032_CTRL_REG); + } /* if (data[1] == ADDIDATA_OR) */ + else + outl(APCI1032_CTRL_INT_ENA | + APCI1032_CTRL_INT_AND, + dev->iobase + APCI1032_CTRL_REG); + /* else if(data[1] == ADDIDATA_OR) */ + } /* if( data[0] == ADDIDATA_ENABLE) */ + else { + ul_Command1 = ul_Command1 & 0xFFFF0000; + ul_Command2 = ul_Command2 & 0xFFFF0000; + outl(ul_Command1, dev->iobase + APCI1032_MODE1_REG); + outl(ul_Command2, dev->iobase + APCI1032_MODE2_REG); + outl(0x0, dev->iobase + APCI1032_CTRL_REG); + } /* else if ( data[0] == ADDIDATA_ENABLE) */ + + return insn->n; +} static irqreturn_t apci1032_interrupt(int irq, void *d) { -- cgit v1.2.3 From 6835a17a910cf68b500b7542f3eeea6c0f212ede Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:41:13 -0700 Subject: staging: comedi: addi_apci_1032: add a subdevice for the interrupt support This board supports a single interrupt that can be generated by an AND/OR combination of 16 of the input channels. Create a separate subdevice, similar to the comedi_parport driver, to handle this interrupt. Move the i_APCI1032_ConfigDigitalInput() operation from the digital input subdevice to this new subdevice. Rename the CamelCase function to apci1032_intr_insn_config(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 3d5cbbfc8b3..bdfc8854606 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -61,10 +61,10 @@ static unsigned int ui_InterruptStatus; * data[2] : Interrupt mask for the mode 1 * data[3] : Interrupt mask for the mode 2 */ -static int i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci1032_intr_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue; @@ -175,7 +175,7 @@ static int apci1032_attach_pci(struct comedi_device *dev, dev->irq = pcidev->irq; } - ret = comedi_alloc_subdevices(dev, 1); + ret = comedi_alloc_subdevices(dev, 2); if (ret) return ret; @@ -187,9 +187,18 @@ static int apci1032_attach_pci(struct comedi_device *dev, s->maxdata = 1; s->len_chanlist = 32; s->range_table = &range_digital; - s->insn_config = i_APCI1032_ConfigDigitalInput; s->insn_bits = apci1032_di_insn_bits; + if (dev->irq) { + s = &dev->subdevices[1]; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = 1; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_config = apci1032_intr_insn_config; + } + apci1032_reset(dev); return 0; } -- cgit v1.2.3 From 14696bbec450bbc13773a8a8f85577469435fa77 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:41:36 -0700 Subject: staging: comedi: addi_apci_1032: remove send_sig() use The addi-data drivers use send_sig() to let the user know when an interrupt has occurred. The "standard" way to do this in the comedi subsystem is to have a subdevice that supports asynchronous commands and use comedi_event() to signal the user. Remove the send_sig() usage in this driver. This also allows removing the dev->private usage since tsk_Current was the only member still being used in the private data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index bdfc8854606..5a300d93ce1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -66,13 +66,10 @@ static int apci1032_intr_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; unsigned int ui_TmpValue; unsigned int ul_Command1 = 0; unsigned int ul_Command2 = 0; - devpriv->tsk_Current = current; - /*******************************/ /* Set the digital input logic */ /*******************************/ @@ -108,7 +105,6 @@ static int apci1032_intr_insn_config(struct comedi_device *dev, static irqreturn_t apci1032_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct addi_private *devpriv = dev->private; unsigned int ctrl; /* disable the interrupt */ @@ -117,7 +113,6 @@ static irqreturn_t apci1032_interrupt(int irq, void *d) ui_InterruptStatus = inl(dev->iobase + APCI1032_STATUS_REG); ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF; - send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ /* enable the interrupt */ outl(ctrl, dev->iobase + APCI1032_CTRL_REG); @@ -151,17 +146,11 @@ static int apci1032_reset(struct comedi_device *dev) static int apci1032_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { - struct addi_private *devpriv; struct comedi_subdevice *s; int ret; dev->board_name = dev->driver->driver_name; - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); - if (!devpriv) - return -ENOMEM; - dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; @@ -206,14 +195,11 @@ static int apci1032_attach_pci(struct comedi_device *dev, static void apci1032_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct addi_private *devpriv = dev->private; - if (devpriv) { - if (dev->iobase) - apci1032_reset(dev); - if (dev->irq) - free_irq(dev->irq, dev); - } + if (dev->iobase) + apci1032_reset(dev); + if (dev->irq) + free_irq(dev->irq, dev); if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); -- cgit v1.2.3 From 4cde0a6d51807b5b956f2cc7878a8c4872d8bde5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:41:52 -0700 Subject: staging: comedi: addi_apci_1032: hook-up the interrupt subdevice The board supported by this driver can generate an interrupt based on the state of input channels 0-15. The apci1032_intr_insn_config() function is used to configure which inputs are used to generate the interrupt. Currently this function is broken since it does not follow the comedi API for insn_config functions. Fix this function by implementing the, currently unused, config instruction INSN_CONFIG_DIGITAL_TRIG. Add the remaining subdevice operations necessary for the interrupt subdevice to support async commands. Fix the subdevice initialization so that if the interrupt is not available the subdevice is set as COMEDI_SUBD_UNUSED. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 250 +++++++++++++++++------- 1 file changed, 184 insertions(+), 66 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 5a300d93ce1..b2736356d85 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -33,8 +33,6 @@ #include "comedi_fc.h" #include "amcc_s5933.h" -#include "addi-data/addi_common.h" - /* * I/O Register Map */ @@ -47,72 +45,191 @@ #define APCI1032_CTRL_INT_AND (1 << 1) #define APCI1032_CTRL_INT_ENA (1 << 2) -/* Digital Input IRQ Function Selection */ -#define ADDIDATA_OR 0 -#define ADDIDATA_AND 1 +struct apci1032_private { + unsigned int mode1; /* rising-edge/high level channels */ + unsigned int mode2; /* falling-edge/low level channels */ + unsigned int ctrl; /* interrupt mode OR (edge) . AND (level) */ +}; -static unsigned int ui_InterruptStatus; +static int apci1032_reset(struct comedi_device *dev) +{ + /* disable the interrupts */ + outl(0x0, dev->iobase + APCI1032_CTRL_REG); + /* Reset the interrupt status register */ + inl(dev->iobase + APCI1032_STATUS_REG); + /* Disable the and/or interrupt */ + outl(0x0, dev->iobase + APCI1032_MODE1_REG); + outl(0x0, dev->iobase + APCI1032_MODE2_REG); + + return 0; +} /* - * data[0] : 1 Enable Digital Input Interrupt - * 0 Disable Digital Input Interrupt - * data[1] : 0 ADDIDATA Interrupt OR LOGIC - * : 1 ADDIDATA Interrupt AND LOGIC - * data[2] : Interrupt mask for the mode 1 - * data[3] : Interrupt mask for the mode 2 + * Change-Of-State (COS) interrupt configuration + * + * Channels 0 to 15 are interruptible. These channels can be configured + * to generate interrupts based on AND/OR logic for the desired channels. + * + * OR logic + * - reacts to rising or falling edges + * - interrupt is generated when any enabled channel + * meet the desired interrupt condition + * + * AND logic + * - reacts to changes in level of the selected inputs + * - interrupt is generated when all enabled channels + * meet the desired interrupt condition + * - after an interrupt, a change in level must occur on + * the selected inputs to release the IRQ logic + * + * The COS interrupt must be configured before it can be enabled. + * + * data[0] : INSN_CONFIG_DIGITAL_TRIG + * data[1] : 0 = OR (edge) interrupts + * 1 = AND (level) interrupts + * data[2] : rising-edge/high level channels + * data[3] : falling-edge/low level channels */ -static int apci1032_intr_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci1032_cos_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - unsigned int ui_TmpValue; - unsigned int ul_Command1 = 0; - unsigned int ul_Command2 = 0; - - /*******************************/ - /* Set the digital input logic */ - /*******************************/ - if (data[0] == ADDIDATA_ENABLE) { - ul_Command1 = ul_Command1 | data[2]; - ul_Command2 = ul_Command2 | data[3]; - outl(ul_Command1, dev->iobase + APCI1032_MODE1_REG); - outl(ul_Command2, dev->iobase + APCI1032_MODE2_REG); - if (data[1] == ADDIDATA_OR) { - outl(APCI1032_CTRL_INT_ENA | - APCI1032_CTRL_INT_OR, - dev->iobase + APCI1032_CTRL_REG); - ui_TmpValue = - inl(dev->iobase + APCI1032_CTRL_REG); - } /* if (data[1] == ADDIDATA_OR) */ - else - outl(APCI1032_CTRL_INT_ENA | - APCI1032_CTRL_INT_AND, - dev->iobase + APCI1032_CTRL_REG); - /* else if(data[1] == ADDIDATA_OR) */ - } /* if( data[0] == ADDIDATA_ENABLE) */ - else { - ul_Command1 = ul_Command1 & 0xFFFF0000; - ul_Command2 = ul_Command2 & 0xFFFF0000; - outl(ul_Command1, dev->iobase + APCI1032_MODE1_REG); - outl(ul_Command2, dev->iobase + APCI1032_MODE2_REG); - outl(0x0, dev->iobase + APCI1032_CTRL_REG); - } /* else if ( data[0] == ADDIDATA_ENABLE) */ + struct apci1032_private *devpriv = dev->private; + + switch (data[0]) { + case INSN_CONFIG_DIGITAL_TRIG: + devpriv->mode1 = data[2]; + devpriv->mode2 = data[3]; + + if (devpriv->mode1 || devpriv->mode2) { + devpriv->ctrl = APCI1032_CTRL_INT_ENA; + if (data[1] == 1) + devpriv->ctrl = APCI1032_CTRL_INT_AND; + else + devpriv->ctrl = APCI1032_CTRL_INT_OR; + } else { + devpriv->ctrl = 0; + apci1032_reset(dev); + } + break; + default: + return -EINVAL; + } return insn->n; } +static int apci1032_cos_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + data[1] = s->state; + + return 0; +} + +static int apci1032_cos_cmdtest(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) +{ + int err = 0; + + /* Step 1 : check if triggers are trivially valid */ + + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); + + if (err) + return 1; + + /* Step 2a : make sure trigger sources are unique */ + /* Step 2b : and mutually compatible */ + + if (err) + return 2; + + /* step 3: */ + + if (cmd->start_arg != 0) { + cmd->start_arg = 0; + err++; + } + if (cmd->scan_begin_arg != 0) { + cmd->scan_begin_arg = 0; + err++; + } + if (cmd->convert_arg != 0) { + cmd->convert_arg = 0; + err++; + } + if (cmd->scan_end_arg != 1) { + cmd->scan_end_arg = 1; + err++; + } + if (cmd->stop_arg != 0) { + cmd->stop_arg = 0; + err++; + } + + if (err) + return 3; + + /* step 4: ignored */ + + if (err) + return 4; + + return 0; +} + +/* + * Change-Of-State (COS) 'do_cmd' operation + * + * Enable the COS interrupt as configured by apci1032_cos_insn_config(). + */ +static int apci1032_cos_cmd(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct apci1032_private *devpriv = dev->private; + + if (!devpriv->ctrl) { + dev_warn(dev->class_dev, + "Interrupts disabled due to mode configuration!\n"); + return -EINVAL; + } + + outl(devpriv->mode1, dev->iobase + APCI1032_MODE1_REG); + outl(devpriv->mode2, dev->iobase + APCI1032_MODE2_REG); + outl(devpriv->ctrl, dev->iobase + APCI1032_CTRL_REG); + + return 0; +} + +static int apci1032_cos_cancel(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + return apci1032_reset(dev); +} + static irqreturn_t apci1032_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct comedi_subdevice *s = dev->read_subdev; unsigned int ctrl; /* disable the interrupt */ ctrl = inl(dev->iobase + APCI1032_CTRL_REG); outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG); - ui_InterruptStatus = inl(dev->iobase + APCI1032_STATUS_REG); - ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF; + s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff; + comedi_buf_put(s->async, s->state); + s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + comedi_event(dev, s); /* enable the interrupt */ outl(ctrl, dev->iobase + APCI1032_CTRL_REG); @@ -130,27 +247,20 @@ static int apci1032_di_insn_bits(struct comedi_device *dev, return insn->n; } -static int apci1032_reset(struct comedi_device *dev) -{ - /* disable the interrupts */ - outl(0x0, dev->iobase + APCI1032_CTRL_REG); - /* Reset the interrupt status register */ - inl(dev->iobase + APCI1032_STATUS_REG); - /* Disable the and/or interrupt */ - outl(0x0, dev->iobase + APCI1032_MODE1_REG); - outl(0x0, dev->iobase + APCI1032_MODE2_REG); - - return 0; -} - static int apci1032_attach_pci(struct comedi_device *dev, struct pci_dev *pcidev) { + struct apci1032_private *devpriv; struct comedi_subdevice *s; int ret; dev->board_name = dev->driver->driver_name; + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + ret = comedi_pci_enable(pcidev, dev->board_name); if (ret) return ret; @@ -178,14 +288,22 @@ static int apci1032_attach_pci(struct comedi_device *dev, s->range_table = &range_digital; s->insn_bits = apci1032_di_insn_bits; + /* Change-Of-State (COS) interrupt subdevice */ + s = &dev->subdevices[1]; if (dev->irq) { - s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_DI; + dev->read_subdev = s; + s->type = COMEDI_SUBD_DI | SDF_CMD_READ; s->subdev_flags = SDF_READABLE; s->n_chan = 1; s->maxdata = 1; s->range_table = &range_digital; - s->insn_config = apci1032_intr_insn_config; + s->insn_config = apci1032_cos_insn_config; + s->insn_bits = apci1032_cos_insn_bits; + s->do_cmdtest = apci1032_cos_cmdtest; + s->do_cmd = apci1032_cos_cmd; + s->cancel = apci1032_cos_cancel; + } else { + s->type = COMEDI_SUBD_UNUSED; } apci1032_reset(dev); -- cgit v1.2.3 From 39c2ec30c28b70683ee6bfc3d2e8cfe3b6a086ab Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:42:09 -0700 Subject: staging: comedi: addi_apci_1032: remove len_chanlist on di subdevice This value is only needed for subdevices that support async commands. The comedi core will default the value to 1 when it is not initialized. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index b2736356d85..f9c2e628601 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -284,7 +284,6 @@ static int apci1032_attach_pci(struct comedi_device *dev, s->subdev_flags = SDF_READABLE; s->n_chan = 32; s->maxdata = 1; - s->len_chanlist = 32; s->range_table = &range_digital; s->insn_bits = apci1032_di_insn_bits; -- cgit v1.2.3 From 346cf14a962e8ea0d27681de1e930c7c63c43a4b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 5 Nov 2012 14:42:25 -0700 Subject: staging: comedi: addi_apci_1032: remove unnecessary include The header amcc_s5933.h is not needed. Remove the include. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index f9c2e628601..2f23a173064 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -31,7 +31,6 @@ #include "../comedidev.h" #include "comedi_fc.h" -#include "amcc_s5933.h" /* * I/O Register Map -- cgit v1.2.3 From 279dda68e2dcb19c46cb62dd2899d8dac6a9b7aa Mon Sep 17 00:00:00 2001 From: Hojung Youn Date: Sat, 3 Nov 2012 06:10:17 +0900 Subject: staging: csr: csr_wifi_hip_unifi_signal_names: fix indent Fixed indent style in the csr_wifi_hip_unifi_signal_names.c file that were identified by checkpatch.pl tool. All whitespaced indents are converted into tab characters, except ones in the topmost commentation. Signed-off-by: Hojung Youn Signed-off-by: Greg Kroah-Hartman --- .../staging/csr/csr_wifi_hip_unifi_signal_names.c | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c b/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c index 7c13df295c1..ddccf91bd13 100644 --- a/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c +++ b/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c @@ -12,35 +12,35 @@ struct sig_name { - s16 id; - const char *name; + s16 id; + const char *name; }; static const struct sig_name Unifi_bulkcmd_names[] = { - { 0, "SignalCmd" }, - { 1, "CopyToHost" }, - { 2, "CopyToHostAck" }, - { 3, "CopyFromHost" }, - { 4, "CopyFromHostAck" }, - { 5, "ClearSlot" }, - { 6, "CopyOverlay" }, - { 7, "CopyOverlayAck" }, - { 8, "CopyFromHostAndClearSlot" }, - { 15, "Padding" } + { 0, "SignalCmd" }, + { 1, "CopyToHost" }, + { 2, "CopyToHostAck" }, + { 3, "CopyFromHost" }, + { 4, "CopyFromHostAck" }, + { 5, "ClearSlot" }, + { 6, "CopyOverlay" }, + { 7, "CopyOverlayAck" }, + { 8, "CopyFromHostAndClearSlot" }, + { 15, "Padding" } }; const char* lookup_bulkcmd_name(u16 id) { - if (id < 9) - { - return Unifi_bulkcmd_names[id].name; - } - if (id == 15) - { - return "Padding"; - } - - return "UNKNOWN"; + if (id < 9) + { + return Unifi_bulkcmd_names[id].name; + } + if (id == 15) + { + return "Padding"; + } + + return "UNKNOWN"; } -- cgit v1.2.3 From a90770e0c33dd94375a81836daa91839f51a81ce Mon Sep 17 00:00:00 2001 From: Hojung Youn Date: Sat, 3 Nov 2012 06:10:18 +0900 Subject: staging: csr: csr_wifi_hip_unifi_signal_names: fix brackets Fixed brackets' positions in the csr_wifi_hip_unifi_signal_names.c file that were identified by checkpatch.pl tool. Some brackets are removed which are not needed by the rule of CodingStyle documentation. Signed-off-by: Hojung Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c b/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c index ddccf91bd13..df32580bbfd 100644 --- a/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c +++ b/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c @@ -10,8 +10,7 @@ #include "csr_wifi_hip_unifi.h" -struct sig_name -{ +struct sig_name { s16 id; const char *name; }; @@ -32,13 +31,9 @@ static const struct sig_name Unifi_bulkcmd_names[] = { const char* lookup_bulkcmd_name(u16 id) { if (id < 9) - { return Unifi_bulkcmd_names[id].name; - } if (id == 15) - { return "Padding"; - } return "UNKNOWN"; } -- cgit v1.2.3 From 65dbeb195ad1070fcee669edca2a30916ca59f6d Mon Sep 17 00:00:00 2001 From: Hojung Youn Date: Sat, 3 Nov 2012 06:10:19 +0900 Subject: staging: csr: csr_wifi_hip_unifi_signal_names: fix whitespaced paddings Fixed whitespace paddings in the csr_wifi_hip_unifi_signal_names.c file that were, though, not identified by checkpatch.pl tool. Signed-off-by: Hojung Youn Signed-off-by: Greg Kroah-Hartman --- .../staging/csr/csr_wifi_hip_unifi_signal_names.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c b/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c index df32580bbfd..d57364198cd 100644 --- a/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c +++ b/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c @@ -11,21 +11,21 @@ #include "csr_wifi_hip_unifi.h" struct sig_name { - s16 id; + s16 id; const char *name; }; static const struct sig_name Unifi_bulkcmd_names[] = { - { 0, "SignalCmd" }, - { 1, "CopyToHost" }, - { 2, "CopyToHostAck" }, - { 3, "CopyFromHost" }, - { 4, "CopyFromHostAck" }, - { 5, "ClearSlot" }, - { 6, "CopyOverlay" }, - { 7, "CopyOverlayAck" }, - { 8, "CopyFromHostAndClearSlot" }, - { 15, "Padding" } + { 0, "SignalCmd" }, + { 1, "CopyToHost" }, + { 2, "CopyToHostAck" }, + { 3, "CopyFromHost" }, + { 4, "CopyFromHostAck" }, + { 5, "ClearSlot" }, + { 6, "CopyOverlay" }, + { 7, "CopyOverlayAck" }, + { 8, "CopyFromHostAndClearSlot" }, + { 15, "Padding" } }; const char* lookup_bulkcmd_name(u16 id) -- cgit v1.2.3 From fb7d2ebd217a2a3cead4402b47c65c25881a2f75 Mon Sep 17 00:00:00 2001 From: Hojung Youn Date: Sat, 3 Nov 2012 06:10:20 +0900 Subject: staging: csr: csr_wifi_hip_unifi_signal_names: Fix pointer position Fixed pointers' positions in the csr_wifi_hip_unifi_signal_names.c file that were identifed by checkpatch.pl tool. Signed-off-by: Hojung Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c b/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c index d57364198cd..9a3528599f3 100644 --- a/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c +++ b/drivers/staging/csr/csr_wifi_hip_unifi_signal_names.c @@ -28,7 +28,7 @@ static const struct sig_name Unifi_bulkcmd_names[] = { { 15, "Padding" } }; -const char* lookup_bulkcmd_name(u16 id) +const char *lookup_bulkcmd_name(u16 id) { if (id < 9) return Unifi_bulkcmd_names[id].name; -- cgit v1.2.3 From 55c6f4cb6ef49afbb86222c6a3ff85329199c729 Mon Sep 17 00:00:00 2001 From: Eric Millbrandt Date: Fri, 2 Nov 2012 17:05:44 -0400 Subject: ASoC: wm8978: pll incorrectly configured when codec is master When MCLK is supplied externally and BCLK and LRC are configured as outputs (codec is master), the PLL values are only calculated correctly on the first transmission. On subsequent transmissions, at differenct sample rates, the wrong PLL values are used. Test for f_opclk instead of f_pllout to determine if the PLL values are needed. Signed-off-by: Eric Millbrandt Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/wm8978.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 5421fd9fbcb..4c0a8e49613 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -782,7 +782,7 @@ static int wm8978_hw_params(struct snd_pcm_substream *substream, wm8978->mclk_idx = -1; f_sel = wm8978->f_mclk; } else { - if (!wm8978->f_pllout) { + if (!wm8978->f_opclk) { /* We only enter here, if OPCLK is not used */ int ret = wm8978_configure_pll(codec); if (ret < 0) -- cgit v1.2.3 From 4a8dece21eea0ad6aca442272673d48693cd93b4 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 5 Nov 2012 13:51:51 +0200 Subject: drm/i915/crt: fix DPMS standby and suspend mode handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PCH platforms and VLV should map DPMS standby and suspend modes to off, but due to a buggy reversed comparison this is done on pre-PCH platforms instead. Reported-by: Loïc Yhuel Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=56754 Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_crt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index b726b478a4f..6345878ae1e 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -143,7 +143,7 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode) int old_dpms; /* PCH platforms and VLV only support on/off. */ - if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON) + if (INTEL_INFO(dev)->gen >= 5 && mode != DRM_MODE_DPMS_ON) mode = DRM_MODE_DPMS_OFF; if (mode == connector->dpms) -- cgit v1.2.3 From accefdd4b234f029a530928ee930b9dcac88fe84 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Sat, 3 Nov 2012 18:00:27 +0530 Subject: usb: dwc3: exynos: add support for device tree This patch adds support to parse probe data for dwc3-exynos driver using device tree. Signed-off-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-exynos.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index 586f1051b05..6471d786b3c 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "core.h" @@ -87,6 +88,8 @@ err1: return ret; } +static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32); + static int __devinit dwc3_exynos_probe(struct platform_device *pdev) { struct dwc3_exynos_data *pdata = pdev->dev.platform_data; @@ -102,6 +105,14 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev) goto err0; } + /* + * Right now device-tree probed devices don't get dma_mask set. + * Since shared usb code relies on it, set it here for now. + * Once we move to full device tree support this will vanish off. + */ + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &dwc3_exynos_dma_mask; + platform_set_drvdata(pdev, exynos); ret = dwc3_exynos_register_phys(exynos); @@ -191,11 +202,20 @@ static int __devexit dwc3_exynos_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_OF +static const struct of_device_id exynos_dwc3_match[] = { + { .compatible = "samsung,exynos-dwc3" }, + {}, +}; +MODULE_DEVICE_TABLE(of, exynos_dwc3_match); +#endif + static struct platform_driver dwc3_exynos_driver = { .probe = dwc3_exynos_probe, .remove = __devexit_p(dwc3_exynos_remove), .driver = { .name = "exynos-dwc3", + .of_match_table = of_match_ptr(exynos_dwc3_match), }, }; -- cgit v1.2.3 From 7947699a4e0d960c36e01b01a4e518f35eea2265 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Sat, 3 Nov 2012 18:00:28 +0530 Subject: usb: dwc3: exynos: remove platform data support We are removing plat data which was used till now to init and exit phy. We no longer need this since dwc3-core takes care of initializing and shutting-down the phy using usb_phy_init() and usb_phy_shutdown(). Signed-off-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-exynos.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index 6471d786b3c..dc35c5476f3 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -92,7 +92,6 @@ static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32); static int __devinit dwc3_exynos_probe(struct platform_device *pdev) { - struct dwc3_exynos_data *pdata = pdev->dev.platform_data; struct platform_device *dwc3; struct dwc3_exynos *exynos; struct clk *clk; @@ -145,14 +144,6 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev) clk_enable(exynos->clk); - /* PHY initialization */ - if (!pdata) { - dev_dbg(&pdev->dev, "missing platform data\n"); - } else { - if (pdata->phy_init) - pdata->phy_init(pdev, pdata->phy_type); - } - ret = platform_device_add_resources(dwc3, pdev->resource, pdev->num_resources); if (ret) { @@ -169,9 +160,6 @@ static int __devinit dwc3_exynos_probe(struct platform_device *pdev) return 0; err4: - if (pdata && pdata->phy_exit) - pdata->phy_exit(pdev, pdata->phy_type); - clk_disable(clk); clk_put(clk); err3: @@ -185,15 +173,11 @@ err0: static int __devexit dwc3_exynos_remove(struct platform_device *pdev) { struct dwc3_exynos *exynos = platform_get_drvdata(pdev); - struct dwc3_exynos_data *pdata = pdev->dev.platform_data; platform_device_unregister(exynos->dwc3); platform_device_unregister(exynos->usb2_phy); platform_device_unregister(exynos->usb3_phy); - if (pdata && pdata->phy_exit) - pdata->phy_exit(pdev, pdata->phy_type); - clk_disable(exynos->clk); clk_put(exynos->clk); -- cgit v1.2.3 From 12fc9266dec3706ece7c4aafefc60d429149c3bd Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Fri, 2 Nov 2012 22:02:28 +0530 Subject: usb: musb: dsps: remove platform callback dsps wrapper is dt only, it cannot execute platform callbacks. Presence of this would cause NULL dereference, hence remove it. Signed-off-by: Afzal Mohammed Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 2d2cd37bc7b..465bbf7e384 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -365,11 +365,9 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) static int dsps_musb_init(struct musb *musb) { struct device *dev = musb->controller; - struct musb_hdrc_platform_data *plat = dev->platform_data; struct platform_device *pdev = to_platform_device(dev); struct dsps_glue *glue = dev_get_drvdata(dev->parent); const struct dsps_musb_wrapper *wrp = glue->wrp; - struct omap_musb_board_data *data = plat->board_data; void __iomem *reg_base = musb->ctrl_base; u32 rev, val; int status; @@ -394,10 +392,6 @@ static int dsps_musb_init(struct musb *musb) /* Reset the musb */ dsps_writel(reg_base, wrp->control, (1 << wrp->reset)); - /* Start the on-chip PHY and its PLL. */ - if (data->set_phy_power) - data->set_phy_power(1); - musb->isr = dsps_interrupt; /* reset the otgdisable bit, needed for host mode to work */ @@ -418,17 +412,11 @@ err0: static int dsps_musb_exit(struct musb *musb) { struct device *dev = musb->controller; - struct musb_hdrc_platform_data *plat = dev->platform_data; - struct omap_musb_board_data *data = plat->board_data; struct platform_device *pdev = to_platform_device(dev); struct dsps_glue *glue = dev_get_drvdata(dev->parent); del_timer_sync(&glue->timer[pdev->id]); - /* Shutdown the on-chip PHY and its PLL. */ - if (data->set_phy_power) - data->set_phy_power(0); - /* NOP driver needs change if supporting dual instance */ usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); @@ -649,25 +637,11 @@ static int __devexit dsps_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int dsps_suspend(struct device *dev) { - struct musb_hdrc_platform_data *plat = dev->platform_data; - struct omap_musb_board_data *data = plat->board_data; - - /* Shutdown the on-chip PHY and its PLL. */ - if (data->set_phy_power) - data->set_phy_power(0); - return 0; } static int dsps_resume(struct device *dev) { - struct musb_hdrc_platform_data *plat = dev->platform_data; - struct omap_musb_board_data *data = plat->board_data; - - /* Start the on-chip PHY and its PLL. */ - if (data->set_phy_power) - data->set_phy_power(1); - return 0; } #endif -- cgit v1.2.3 From 3b46dd76a9b3ce25a5177f61eed844f85ddb3ca6 Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Fri, 2 Nov 2012 22:02:35 +0530 Subject: usb: musb: dsps: reduce musb instance to one Currently multiple phy's of the same type are not supported, hence reduce musb instances to one. This helps in supporting at least one instance of musb, rather than having none. Even without this, it was observed that both instances were working (by luck), but this holds good iff wrapper is part of Image. And it is not correct for both controller's to be associated with same phy, here it was working because phy is a nop one. And having wrapper as a module and rmmod'ing would crash. This can be reverted once multi phy support for same type is available and driver is enhanced to make use of it. Signed-off-by: Afzal Mohammed Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 465bbf7e384..72d74601798 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -676,7 +676,7 @@ static const struct dsps_musb_wrapper ti81xx_driver_data __devinitconst = { .rxep_bitmap = (0xfffe << 16), .musb_core_offset = 0x400, .poll_seconds = 2, - .instances = 2, + .instances = 1, }; static const struct platform_device_id musb_dsps_id_table[] __devinitconst = { -- cgit v1.2.3 From 3e594b18f1871a758812aa5e705873012cabf0e8 Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Fri, 2 Nov 2012 22:02:41 +0530 Subject: usb: musb: dsps: get resources by index dsps wrapper is now dt only. This requires that resources be obtained using index and not name, modify accordingly. Signed-off-by: Afzal Mohammed Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 72d74601798..b159fc92f84 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -449,22 +449,20 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) char res_name[10]; int ret; - /* get memory resource */ - sprintf(res_name, "musb%d", id); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name); + /* first resource is for usbss, so start index from 1 */ + res = platform_get_resource(pdev, IORESOURCE_MEM, id + 1); if (!res) { - dev_err(dev, "%s get mem resource failed\n", res_name); + dev_err(dev, "failed to get memory for instance %d\n", id); ret = -ENODEV; goto err0; } res->parent = NULL; resources[0] = *res; - /* get irq resource */ - sprintf(res_name, "musb%d-irq", id); - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name); + /* first resource is for usbss, so start index from 1 */ + res = platform_get_resource(pdev, IORESOURCE_IRQ, id + 1); if (!res) { - dev_err(dev, "%s get irq resource failed\n", res_name); + dev_err(dev, "failed to get irq for instance %d\n", id); ret = -ENODEV; goto err0; } -- cgit v1.2.3 From c68bb4c679e68b2814bc5de812665fbd37f8a9b1 Mon Sep 17 00:00:00 2001 From: "Santhapuri, Damodar" Date: Fri, 2 Nov 2012 22:02:53 +0530 Subject: usb: musb: dsps: control module handling (quirk) am335x uses nop transceiver driver and need to enable builtin phy by writing into usb_ctrl register available in system control module register space. This is being added at musb glue driver layer until a separate system control module driver is available. Proper solution is to make use of control module driver, but it is not expected to be ready soon. Other options available are providing control module register space as memory resource via DT or using omap hwmod. DT approach has been rejected by Rob Herring, while resources are being moved from hwmod to DT. And both of the above approaches require that control module registers be configured in wrapper itself requring a quirk in driver as well as DT or hwmod. Here another option is used, providing driver with control module register physical address. Even though this a hack, there is no other option left till control module driver is ready. As of now only am335x is using dsps wrapper, and so driver is made aware of am335x control module physical address. Please note that this is a temporary arrangment till omap control module driver is available. [afzal@ti.com: limit quirk to dsps wrapper] Signed-off-by: Santhapuri, Damodar Signed-off-by: Ajay Kumar Gupta Signed-off-by: Ravi Babu Signed-off-by: Afzal Mohammed Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 69 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index b159fc92f84..6053af1f57c 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -124,8 +124,44 @@ struct dsps_glue { const struct dsps_musb_wrapper *wrp; /* wrapper register offsets */ struct timer_list timer[2]; /* otg_workaround timer */ unsigned long last_timer[2]; /* last timer data for each instance */ + u32 __iomem *usb_ctrl[2]; }; +#define DSPS_AM33XX_CONTROL_MODULE_PHYS_0 0x44e10620 +#define DSPS_AM33XX_CONTROL_MODULE_PHYS_1 0x44e10628 + +static const resource_size_t dsps_control_module_phys[] = { + DSPS_AM33XX_CONTROL_MODULE_PHYS_0, + DSPS_AM33XX_CONTROL_MODULE_PHYS_1, +}; + +/** + * musb_dsps_phy_control - phy on/off + * @glue: struct dsps_glue * + * @id: musb instance + * @on: flag for phy to be switched on or off + * + * This is to enable the PHY using usb_ctrl register in system control + * module space. + * + * XXX: This function will be removed once we have a seperate driver for + * control module + */ +static void musb_dsps_phy_control(struct dsps_glue *glue, u8 id, u8 on) +{ + u32 usbphycfg; + + usbphycfg = readl(glue->usb_ctrl[id]); + + if (on) { + usbphycfg &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN); + usbphycfg |= USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN; + } else { + usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN; + } + + writel(usbphycfg, glue->usb_ctrl[id]); +} /** * dsps_musb_enable - enable interrupts */ @@ -392,6 +428,9 @@ static int dsps_musb_init(struct musb *musb) /* Reset the musb */ dsps_writel(reg_base, wrp->control, (1 << wrp->reset)); + /* Start the on-chip PHY and its PLL. */ + musb_dsps_phy_control(glue, pdev->id, 1); + musb->isr = dsps_interrupt; /* reset the otgdisable bit, needed for host mode to work */ @@ -417,6 +456,9 @@ static int dsps_musb_exit(struct musb *musb) del_timer_sync(&glue->timer[pdev->id]); + /* Shutdown the on-chip PHY and its PLL. */ + musb_dsps_phy_control(glue, pdev->id, 0); + /* NOP driver needs change if supporting dual instance */ usb_put_phy(musb->xceiv); usb_nop_xceiv_unregister(); @@ -449,6 +491,17 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) char res_name[10]; int ret; + resources[0].start = dsps_control_module_phys[id]; + resources[0].end = resources[0].start + SZ_4 - 1; + resources[0].flags = IORESOURCE_MEM; + + glue->usb_ctrl[id] = devm_request_and_ioremap(&pdev->dev, resources); + if (glue->usb_ctrl[id] == NULL) { + dev_err(dev, "Failed to obtain usb_ctrl%d memory\n", id); + ret = -ENODEV; + goto err0; + } + /* first resource is for usbss, so start index from 1 */ res = platform_get_resource(pdev, IORESOURCE_MEM, id + 1); if (!res) { @@ -635,11 +688,27 @@ static int __devexit dsps_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int dsps_suspend(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev->parent); + struct dsps_glue *glue = platform_get_drvdata(pdev); + const struct dsps_musb_wrapper *wrp = glue->wrp; + int i; + + for (i = 0; i < wrp->instances; i++) + musb_dsps_phy_control(glue, i, 0); + return 0; } static int dsps_resume(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev->parent); + struct dsps_glue *glue = platform_get_drvdata(pdev); + const struct dsps_musb_wrapper *wrp = glue->wrp; + int i; + + for (i = 0; i < wrp->instances; i++) + musb_dsps_phy_control(glue, i, 1); + return 0; } #endif -- cgit v1.2.3 From 984e833c2bb6cba11e7cbc84c0dfb7b43792ff80 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Thu, 1 Nov 2012 00:03:51 +0900 Subject: usb: fix typo in drivers/usb Correct spelling typo in debug messages within drivers/usb. Acked-by: Greg Kroah-Hartman Signed-off-by: Masanari Iida Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 2 +- drivers/usb/gadget/tcm_usb_gadget.c | 2 +- drivers/usb/musb/musb_dsps.c | 2 +- drivers/usb/renesas_usbhs/fifo.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 6ae70cba0c4..c19f7f13790 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2126,7 +2126,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count, tmp_reg = fsl_readl(&dr_regs->usbintr); t = scnprintf(next, size, - "USB Intrrupt Enable Reg:\n" + "USB Interrupt Enable Reg:\n" "Sleep Enable: %d SOF Received Enable: %d " "Reset Enable: %d\n" "System Error Enable: %d " diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c index 27a2337f986..4f7f76f00c7 100644 --- a/drivers/usb/gadget/tcm_usb_gadget.c +++ b/drivers/usb/gadget/tcm_usb_gadget.c @@ -1384,7 +1384,7 @@ static struct se_node_acl *usbg_alloc_fabric_acl(struct se_portal_group *se_tpg) nacl = kzalloc(sizeof(struct usbg_nacl), GFP_KERNEL); if (!nacl) { - printk(KERN_ERR "Unable to alocate struct usbg_nacl\n"); + printk(KERN_ERR "Unable to allocate struct usbg_nacl\n"); return NULL; } diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 444346e1e10..2cb8780d0da 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -296,7 +296,7 @@ static irqreturn_t dsps_interrupt(int irq, void *hci) * Also, DRVVBUS pulses for SRP (but not at 5V) ... */ if (usbintr & MUSB_INTR_BABBLE) - pr_info("CAUTION: musb: Babble Interrupt Occured\n"); + pr_info("CAUTION: musb: Babble Interrupt Occurred\n"); if (usbintr & ((1 << wrp->drvvbus) << wrp->usb_shift)) { int drvvbus = dsps_readl(reg_base, wrp->status); diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 3818c829082..77f1adc2a4f 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -163,7 +163,7 @@ static int usbhsf_pkt_handler(struct usbhs_pipe *pipe, int type) func = pkt->handler->dma_done; break; default: - dev_err(dev, "unknown pkt hander\n"); + dev_err(dev, "unknown pkt handler\n"); goto __usbhs_pkt_handler_end; } -- cgit v1.2.3 From 24e4c1c30da3926db547aab4ec873afdc60bd3ee Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 6 Nov 2012 00:11:32 -0800 Subject: usb: renesas_usbhs: remove debug information from usbhsh_hub_status_data() Because usbhsh_hub_status_data() will be called many times, there are too many obstructive/useless debug informations if driver has #define DEBUG. Thus, other important dev_dbg() information will hide. This patch removed obstructive/useless dev_dbg(). Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod_host.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index e856b449e28..33f70638723 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -1080,8 +1080,6 @@ static void usbhsh_endpoint_disable(struct usb_hcd *hcd, static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) { struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); - struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); - struct device *dev = usbhs_priv_to_dev(priv); int roothub_id = 1; /* only 1 root hub */ /* @@ -1093,8 +1091,6 @@ static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) else *buf = 0; - dev_dbg(dev, "%s (%02x)\n", __func__, *buf); - return !!(*buf); } -- cgit v1.2.3 From 7b332e5fef480ee14d133d9b83af22d03819368e Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 6 Nov 2012 00:11:53 -0800 Subject: usb: renesas_usbhs: host: add endpoint user counter renesas_usbhs attaches pipe to endpoint when urb was queued, and it will be detached when transfer was done. Multi device controlling was enabled by this behavior. Now renesas_usbhs driver tried to wait until detaching if urb was queued to endpoint which already has been attached to pipe, and it created strange driver behavior. But it can re-use this attached pipe if multi urb was queued. This patch implements it. Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod_host.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 33f70638723..73c5039f767 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -85,6 +85,7 @@ struct usbhsh_ep { struct usbhsh_device *udev; /* attached udev */ struct usb_host_endpoint *ep; struct list_head ep_list; /* list to usbhsh_device */ + unsigned int counter; /* pipe attach counter */ }; #define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ @@ -271,8 +272,12 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv, /******************** spin lock ********************/ usbhs_lock(priv, flags); - if (unlikely(usbhsh_uep_to_pipe(uep))) { - dev_err(dev, "uep already has pipe\n"); + /* + * if uep has been attached to pipe, + * reuse it + */ + if (usbhsh_uep_to_pipe(uep)) { + ret = 0; goto usbhsh_pipe_attach_done; } @@ -320,6 +325,9 @@ static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv, } usbhsh_pipe_attach_done: + if (0 == ret) + uep->counter++; + usbhs_unlock(priv, flags); /******************** spin unlock ******************/ @@ -341,7 +349,7 @@ static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv, if (unlikely(!pipe)) { dev_err(dev, "uep doens't have pipe\n"); - } else { + } else if (1 == uep->counter--) { /* last user */ struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep); struct usbhsh_device *udev = usbhsh_uep_to_udev(uep); @@ -386,6 +394,7 @@ static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv, /* * init endpoint */ + uep->counter = 0; INIT_LIST_HEAD(&uep->ep_list); list_add_tail(&uep->ep_list, &udev->ep_list_head); @@ -954,7 +963,6 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *ep = urb->ep; struct usbhsh_device *new_udev = NULL; int is_dir_in = usb_pipein(urb->pipe); - int i; int ret; dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); @@ -1000,13 +1008,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, * attach pipe to endpoint * see [image of mod_host] */ - for (i = 0; i < 1024; i++) { - ret = usbhsh_pipe_attach(hpriv, urb); - if (ret < 0) - msleep(100); - else - break; - } + ret = usbhsh_pipe_attach(hpriv, urb); if (ret < 0) { dev_err(dev, "pipe attach failed\n"); goto usbhsh_urb_enqueue_error_free_endpoint; -- cgit v1.2.3 From 8b416b0b25d5d8ddb3a91c1d20e1373582c50405 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Mon, 5 Nov 2012 22:26:40 +0300 Subject: usb: musb: cppi_dma: export cppi_interrupt() Now that DaVinci glue layer can be modular, we must export cppi_interrupt() that it may call... Cc: stable@vger.kernel.org # 3.0+ Signed-off-by: Sergei Shtylyov Signed-off-by: Felipe Balbi --- drivers/usb/musb/cppi_dma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index e19da82b478..3a6c2fd1f91 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c @@ -1314,6 +1314,7 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +EXPORT_SYMBOL_GPL(cppi_interrupt); /* Instantiate a software object representing a DMA controller. */ struct dma_controller *__devinit -- cgit v1.2.3 From baef653a500476ccb2d08cf4bb648c56c0170e21 Mon Sep 17 00:00:00 2001 From: Philippe De Swert Date: Tue, 6 Nov 2012 15:32:13 +0200 Subject: usb: musb: remove generic_interrupt This patch is based on the discussion of a previous patch to fix an issue where the omap2430 musb driver is not working for N9/N950. Moving all the interrupt handling to the devices. Avoids inclusion of generic interrupt and breakage due to sometimes misleading CONFIG options. This makes sure usb always works if on of the subdrivers is chosen. Tested on Nokia N9/N950. Partially clean up CONFIG_SOC_OMAP3430 which is not necessary in the cases where I removed it. Also helps with the removal work of those options that Tony Lindgren predicted would happen at some point. Signed-off-by: Philippe De Swert Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 31 ++----------------------------- drivers/usb/musb/musbhsdma.h | 4 ---- drivers/usb/musb/omap2430.c | 22 ++++++++++++++++++++++ drivers/usb/musb/ux500.c | 22 ++++++++++++++++++++++ 4 files changed, 46 insertions(+), 33 deletions(-) diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 78037bfad96..774d8154a28 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1501,33 +1501,6 @@ static int __devinit musb_core_init(u16 musb_type, struct musb *musb) /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \ - defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500) - -static irqreturn_t generic_interrupt(int irq, void *__hci) -{ - unsigned long flags; - irqreturn_t retval = IRQ_NONE; - struct musb *musb = __hci; - - spin_lock_irqsave(&musb->lock, flags); - - musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); - musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); - musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); - - if (musb->int_usb || musb->int_tx || musb->int_rx) - retval = musb_interrupt(musb); - - spin_unlock_irqrestore(&musb->lock, flags); - - return retval; -} - -#else -#define generic_interrupt NULL -#endif - /* * handle all the irqs defined by the HDRC core. for now we expect: other * irq sources (phy, dma, etc) will be handled first, musb->int_* values @@ -1896,7 +1869,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb->ops = plat->platform_ops; /* The musb_platform_init() call: - * - adjusts musb->mregs and musb->isr if needed, + * - adjusts musb->mregs + * - sets the musb->isr * - may initialize an integrated tranceiver * - initializes musb->xceiv, usually by otg_get_phy() * - stops powering VBUS @@ -1906,7 +1880,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) * external/discrete ones in various flavors (twl4030 family, * isp1504, non-OTG, etc) mostly hooking up through ULPI. */ - musb->isr = generic_interrupt; status = musb_platform_init(musb); if (status < 0) goto fail1; diff --git a/drivers/usb/musb/musbhsdma.h b/drivers/usb/musb/musbhsdma.h index 320fd4afb93..f7b13fd2525 100644 --- a/drivers/usb/musb/musbhsdma.h +++ b/drivers/usb/musb/musbhsdma.h @@ -31,10 +31,6 @@ * */ -#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) -#include "omap2430.h" -#endif - #ifndef CONFIG_BLACKFIN #define MUSB_HSDMA_BASE 0x200 diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index dddd8f71a17..32f531e7a2e 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -333,6 +333,26 @@ static void omap_musb_mailbox_work(struct work_struct *mailbox_work) omap_musb_set_mailbox(glue); } +static irqreturn_t omap2430_musb_interrupt(int irq, void *__hci) +{ + unsigned long flags; + irqreturn_t retval = IRQ_NONE; + struct musb *musb = __hci; + + spin_lock_irqsave(&musb->lock, flags); + + musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); + musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); + musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); + + if (musb->int_usb || musb->int_tx || musb->int_rx) + retval = musb_interrupt(musb); + + spin_unlock_irqrestore(&musb->lock, flags); + + return retval; +} + static int omap2430_musb_init(struct musb *musb) { u32 l; @@ -352,6 +372,8 @@ static int omap2430_musb_init(struct musb *musb) return -ENODEV; } + musb->isr = omap2430_musb_interrupt; + status = pm_runtime_get_sync(dev); if (status < 0) { dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 5e9053eb429..286f1be6594 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -36,6 +36,26 @@ struct ux500_glue { }; #define glue_to_musb(g) platform_get_drvdata(g->musb) +static irqreturn_t ux500_musb_interrupt(int irq, void *__hci) +{ + unsigned long flags; + irqreturn_t retval = IRQ_NONE; + struct musb *musb = __hci; + + spin_lock_irqsave(&musb->lock, flags); + + musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); + musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); + musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); + + if (musb->int_usb || musb->int_tx || musb->int_rx) + retval = musb_interrupt(musb); + + spin_unlock_irqrestore(&musb->lock, flags); + + return retval; +} + static int ux500_musb_init(struct musb *musb) { musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); @@ -44,6 +64,8 @@ static int ux500_musb_init(struct musb *musb) return -ENODEV; } + musb->isr = ux500_musb_interrupt; + return 0; } -- cgit v1.2.3 From e32643544d8d9e7776daf0a4e803c57b54ba77f0 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 25 Oct 2012 22:20:37 -0500 Subject: ARM: highbank: retry wfi on reset request In some cases, an interrupt can occur and prevent cause failure to enter wfi. This causes reset to hang. Retrying the wfi should be enough to prevent reset from hanging. Signed-off-by: Rob Herring Signed-off-by: Olof Johansson --- arch/arm/mach-highbank/system.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-highbank/system.c b/arch/arm/mach-highbank/system.c index 82c27230d4a..86e37cd9376 100644 --- a/arch/arm/mach-highbank/system.c +++ b/arch/arm/mach-highbank/system.c @@ -28,6 +28,7 @@ void highbank_restart(char mode, const char *cmd) hignbank_set_pwr_soft_reset(); scu_power_mode(scu_base_addr, SCU_PM_POWEROFF); - cpu_do_idle(); + while (1) + cpu_do_idle(); } -- cgit v1.2.3 From 64e104771351d365e51e588a0e9a656ae6ed2f50 Mon Sep 17 00:00:00 2001 From: Aristeu Rozanski Date: Tue, 6 Nov 2012 07:25:04 -0800 Subject: device_cgroup: fix unchecked cgroup parent usage In 4cef7299b478687 ("device_cgroup: add proper checking when changing default behavior") the cgroup parent usage is unchecked. root will not have a parent and trying to use device.{allow,deny} will cause problems. For some reason my stressing scripts didn't test the root directory so I didn't catch it on my regular tests. Signed-off-by: Aristeu Rozanski Cc: Li Zefan Cc: James Morris Cc: Pavel Emelyanov Acked-by: Serge E. Hallyn Cc: Jiri Slaby Cc: Tejun Heo Signed-off-by: Tejun Heo --- security/device_cgroup.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 842c254396d..96d87eab166 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -352,6 +352,8 @@ static int parent_has_perm(struct dev_cgroup *childcg, */ static inline int may_allow_all(struct dev_cgroup *parent) { + if (!parent) + return 1; return parent->behavior == DEVCG_DEFAULT_ALLOW; } @@ -376,11 +378,14 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, int count, rc; struct dev_exception_item ex; struct cgroup *p = devcgroup->css.cgroup; - struct dev_cgroup *parent = cgroup_to_devcgroup(p->parent); + struct dev_cgroup *parent = NULL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; + if (p->parent) + parent = cgroup_to_devcgroup(p->parent); + memset(&ex, 0, sizeof(ex)); b = buffer; @@ -391,11 +396,14 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, if (!may_allow_all(parent)) return -EPERM; dev_exception_clean(devcgroup); + devcgroup->behavior = DEVCG_DEFAULT_ALLOW; + if (!parent) + break; + rc = dev_exceptions_copy(&devcgroup->exceptions, &parent->exceptions); if (rc) return rc; - devcgroup->behavior = DEVCG_DEFAULT_ALLOW; break; case DEVCG_DENY: dev_exception_clean(devcgroup); -- cgit v1.2.3 From 36e42a323cf0de26bd819448b024d3851fc0d865 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 1 Nov 2012 22:02:50 -0600 Subject: irqchip: irq-bcm2835: Add terminating entry for of_device_id table The of_device_id table is supposed to be zero-terminated. Signed-off-by: Axel Lin Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- drivers/irqchip/irq-bcm2835.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c index dc670ccc697..16c78f1c5ef 100644 --- a/drivers/irqchip/irq-bcm2835.c +++ b/drivers/irqchip/irq-bcm2835.c @@ -168,7 +168,8 @@ static int __init armctrl_of_init(struct device_node *node, } static struct of_device_id irq_of_match[] __initconst = { - { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init } + { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init }, + { } }; void __init bcm2835_init_irq(void) -- cgit v1.2.3 From 201e72acb2d3821e2de9ce6091e98859c316b29a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 6 Nov 2012 09:17:37 -0800 Subject: device_cgroup: fix RCU usage dev_cgroup->exceptions is protected with devcgroup_mutex for writes and RCU for reads; however, RCU usage isn't correct. * dev_exception_clean() doesn't use RCU variant of list_del() and kfree(). The function can race with may_access() and may_access() may end up dereferencing already freed memory. Use list_del_rcu() and kfree_rcu() instead. * may_access() may be called only with RCU read locked but doesn't use RCU safe traversal over ->exceptions. Use list_for_each_entry_rcu(). Signed-off-by: Tejun Heo Acked-by: Serge E. Hallyn Cc: stable@vger.kernel.org Cc: Aristeu Rozanski Cc: Li Zefan --- security/device_cgroup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 96d87eab166..b08d20c66c2 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -164,8 +164,8 @@ static void dev_exception_clean(struct dev_cgroup *dev_cgroup) struct dev_exception_item *ex, *tmp; list_for_each_entry_safe(ex, tmp, &dev_cgroup->exceptions, list) { - list_del(&ex->list); - kfree(ex); + list_del_rcu(&ex->list); + kfree_rcu(ex, rcu); } } @@ -298,7 +298,7 @@ static int may_access(struct dev_cgroup *dev_cgroup, struct dev_exception_item *ex; bool match = false; - list_for_each_entry(ex, &dev_cgroup->exceptions, list) { + list_for_each_entry_rcu(ex, &dev_cgroup->exceptions, list) { if ((refex->type & DEV_BLOCK) && !(ex->type & DEV_BLOCK)) continue; if ((refex->type & DEV_CHAR) && !(ex->type & DEV_CHAR)) -- cgit v1.2.3 From 31df3bb78be614fb9125abe56972dfee79bd3e18 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 31 Oct 2012 22:07:39 +0100 Subject: iwlwifi: use ieee80211_free_txskb To let mac80211 clean up any TX information when a frame is dropped, use ieee80211_free_txskb(). Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 2 +- drivers/net/wireless/iwlwifi/dvm/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index ff8162d4c45..fa4d1b8cd9f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -521,7 +521,7 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); if (iwlagn_tx_skb(priv, control->sta, skb)) - dev_kfree_skb_any(skb); + ieee80211_free_txskb(hw, skb); } static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 7ff3f143067..408132cf83c 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -2114,7 +2114,7 @@ static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) info = IEEE80211_SKB_CB(skb); iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); - dev_kfree_skb_any(skb); + ieee80211_free_txskb(priv->hw, skb); } static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) -- cgit v1.2.3 From 6268f74990c7fab6727bcb2dc82b3c4d4b302317 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 6 Nov 2012 16:33:18 +0000 Subject: ASoC: bells: Correct type in sub speaker DAI name for WM5102 Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/samsung/bells.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index b0d46d63d55..b56b9a3c616 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c @@ -247,7 +247,7 @@ static struct snd_soc_dai_link bells_dai_wm5110[] = { { .name = "Sub", .stream_name = "Sub", - .cpu_dai_name = "wm5110-aif3", + .cpu_dai_name = "wm5102-aif3", .codec_dai_name = "wm9081-hifi", .codec_name = "wm9081.1-006c", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF -- cgit v1.2.3 From 5c855c8e2be67f2d5a989ef1190098f924f9f820 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 7 Nov 2012 20:38:35 +0800 Subject: ASoC: cs42l52: fix the return value of cs42l52_set_fmt() Fix the return value of cs42l52_set_fmt() when clock inversion is not allowed and also remove the useless variable ret. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) [We had been assigning to ret but then ignoring the value we assgined -- broonie] Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/cs42l52.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 61599298fb2..f91136caa4c 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -773,7 +773,6 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_codec *codec = codec_dai->codec; struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); - int ret = 0; u8 iface = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -822,7 +821,7 @@ static int cs42l52_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) case SND_SOC_DAIFMT_NB_IF: break; default: - ret = -EINVAL; + return -EINVAL; } cs42l52->config.format = iface; snd_soc_write(codec, CS42L52_IFACE_CTL1, cs42l52->config.format); -- cgit v1.2.3 From 0133370f93eae5ed3c0f16d9da2b7add7dda6076 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 2 Nov 2012 13:44:46 +0530 Subject: drivers: bus: ocp2scp: add pdata support ocp2scp was not having pdata support which makes *musb* fail for non-dt boot in OMAP platform. The pdata will have information about the devices that is connected to ocp2scp. ocp2scp driver will now make use of this information to create the devices that is attached to ocp2scp. This is needed to fix MUSB regression caused by commit c9e4412a (arm: omap: phy: remove unused functions from omap-phy-internal.c) Signed-off-by: Kishon Vijay Abraham I Acked-by: Felipe Balbi [tony@atomide.com: updated comments for regression info] Signed-off-by: Tony Lindgren --- drivers/bus/omap-ocp2scp.c | 68 ++++++++++++++++++++++++++++-- include/linux/platform_data/omap_ocp2scp.h | 31 ++++++++++++++ 2 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 include/linux/platform_data/omap_ocp2scp.h diff --git a/drivers/bus/omap-ocp2scp.c b/drivers/bus/omap-ocp2scp.c index ff63560b846..0c48b0e05ed 100644 --- a/drivers/bus/omap-ocp2scp.c +++ b/drivers/bus/omap-ocp2scp.c @@ -22,6 +22,26 @@ #include #include #include +#include + +/** + * _count_resources - count for the number of resources + * @res: struct resource * + * + * Count and return the number of resources populated for the device that is + * connected to ocp2scp. + */ +static unsigned _count_resources(struct resource *res) +{ + int cnt = 0; + + while (res->start != res->end) { + cnt++; + res++; + } + + return cnt; +} static int ocp2scp_remove_devices(struct device *dev, void *c) { @@ -34,20 +54,62 @@ static int ocp2scp_remove_devices(struct device *dev, void *c) static int __devinit omap_ocp2scp_probe(struct platform_device *pdev) { - int ret; - struct device_node *np = pdev->dev.of_node; + int ret; + unsigned res_cnt, i; + struct device_node *np = pdev->dev.of_node; + struct platform_device *pdev_child; + struct omap_ocp2scp_platform_data *pdata = pdev->dev.platform_data; + struct omap_ocp2scp_dev *dev; if (np) { ret = of_platform_populate(np, NULL, NULL, &pdev->dev); if (ret) { - dev_err(&pdev->dev, "failed to add resources for ocp2scp child\n"); + dev_err(&pdev->dev, + "failed to add resources for ocp2scp child\n"); goto err0; } + } else if (pdata) { + for (i = 0, dev = *pdata->devices; i < pdata->dev_cnt; i++, + dev++) { + res_cnt = _count_resources(dev->res); + + pdev_child = platform_device_alloc(dev->drv_name, + PLATFORM_DEVID_AUTO); + if (!pdev_child) { + dev_err(&pdev->dev, + "failed to allocate mem for ocp2scp child\n"); + goto err0; + } + + ret = platform_device_add_resources(pdev_child, + dev->res, res_cnt); + if (ret) { + dev_err(&pdev->dev, + "failed to add resources for ocp2scp child\n"); + goto err1; + } + + pdev_child->dev.parent = &pdev->dev; + + ret = platform_device_add(pdev_child); + if (ret) { + dev_err(&pdev->dev, + "failed to register ocp2scp child device\n"); + goto err1; + } + } + } else { + dev_err(&pdev->dev, "OCP2SCP initialized without plat data\n"); + return -EINVAL; } + pm_runtime_enable(&pdev->dev); return 0; +err1: + platform_device_put(pdev_child); + err0: device_for_each_child(&pdev->dev, NULL, ocp2scp_remove_devices); diff --git a/include/linux/platform_data/omap_ocp2scp.h b/include/linux/platform_data/omap_ocp2scp.h new file mode 100644 index 00000000000..5c6c3939355 --- /dev/null +++ b/include/linux/platform_data/omap_ocp2scp.h @@ -0,0 +1,31 @@ +/* + * omap_ocp2scp.h -- ocp2scp header file + * + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com + * 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. + * + * Author: Kishon Vijay Abraham I + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __DRIVERS_OMAP_OCP2SCP_H +#define __DRIVERS_OMAP_OCP2SCP_H + +struct omap_ocp2scp_dev { + const char *drv_name; + struct resource *res; +}; + +struct omap_ocp2scp_platform_data { + int dev_cnt; + struct omap_ocp2scp_dev **devices; +}; +#endif /* __DRIVERS_OMAP_OCP2SCP_H */ -- cgit v1.2.3 From 637874ddb94a78e07ca8ce76ca500c62c4583535 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Sat, 27 Oct 2012 19:05:55 +0530 Subject: ARM: OMAP4: add _dev_attr_ to ocp2scp for representing usb_phy In order to reflect devices(usb_phy) attached to ocp2scp bus, ocp2scp is assigned a device attribute to represent the attached devices. This is needed to fix MUSB regression caused by commit c9e4412a (arm: omap: phy: remove unused functions from omap-phy-internal.c) Signed-off-by: Kishon Vijay Abraham I Cc: Benoit Cousson [tony@atomide.com: updated comments for regression info] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 652d0285bd6..cf579b55571 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -2681,6 +2682,32 @@ static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = { .sysc = &omap44xx_ocp2scp_sysc, }; +/* ocp2scp dev_attr */ +static struct resource omap44xx_usb_phy_and_pll_addrs[] = { + { + .name = "usb_phy", + .start = 0x4a0ad080, + .end = 0x4a0ae000, + .flags = IORESOURCE_MEM, + }, + { + /* XXX: Remove this once control module driver is in place */ + .name = "ctrl_dev", + .start = 0x4a002300, + .end = 0x4a002303, + .flags = IORESOURCE_MEM, + }, + { } +}; + +static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = { + { + .drv_name = "omap-usb2", + .res = omap44xx_usb_phy_and_pll_addrs, + }, + { } +}; + /* ocp2scp_usb_phy */ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .name = "ocp2scp_usb_phy", @@ -2694,6 +2721,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .modulemode = MODULEMODE_HWCTRL, }, }, + .dev_attr = ocp2scp_dev_attr, }; /* -- cgit v1.2.3 From 459bc971eba0fe84b3fe857cf0a71c5fd102f06b Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Sat, 27 Oct 2012 19:05:56 +0530 Subject: ARM: OMAP: ocp2scp: create omap device for ocp2scp Platfrom device for ocp2scp is created using omap_device_build in devices file. This is used for both omap4(musb) and omap5(dwc3). This is needed to fix MUSB regression caused by commit c9e4412a (arm: omap: phy: remove unused functions from omap-phy-internal.c) Signed-off-by: Kishon Vijay Abraham I [tony@atomide.com: updated comments for regression info] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/devices.c | 79 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index cba60e05e32..c72b5a72772 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -613,6 +614,83 @@ static void omap_init_vout(void) static inline void omap_init_vout(void) {} #endif +#if defined(CONFIG_OMAP_OCP2SCP) || defined(CONFIG_OMAP_OCP2SCP_MODULE) +static int count_ocp2scp_devices(struct omap_ocp2scp_dev *ocp2scp_dev) +{ + int cnt = 0; + + while (ocp2scp_dev->drv_name != NULL) { + cnt++; + ocp2scp_dev++; + } + + return cnt; +} + +static void omap_init_ocp2scp(void) +{ + struct omap_hwmod *oh; + struct platform_device *pdev; + int bus_id = -1, dev_cnt = 0, i; + struct omap_ocp2scp_dev *ocp2scp_dev; + const char *oh_name, *name; + struct omap_ocp2scp_platform_data *pdata; + + if (!cpu_is_omap44xx()) + return; + + oh_name = "ocp2scp_usb_phy"; + name = "omap-ocp2scp"; + + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("%s: could not find omap_hwmod for %s\n", __func__, + oh_name); + return; + } + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) { + pr_err("%s: No memory for ocp2scp pdata\n", __func__); + return; + } + + ocp2scp_dev = oh->dev_attr; + dev_cnt = count_ocp2scp_devices(ocp2scp_dev); + + if (!dev_cnt) { + pr_err("%s: No devices connected to ocp2scp\n", __func__); + kfree(pdata); + return; + } + + pdata->devices = kzalloc(sizeof(struct omap_ocp2scp_dev *) + * dev_cnt, GFP_KERNEL); + if (!pdata->devices) { + pr_err("%s: No memory for ocp2scp pdata devices\n", __func__); + kfree(pdata); + return; + } + + for (i = 0; i < dev_cnt; i++, ocp2scp_dev++) + pdata->devices[i] = ocp2scp_dev; + + pdata->dev_cnt = dev_cnt; + + pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL, + 0, false); + if (IS_ERR(pdev)) { + pr_err("Could not build omap_device for %s %s\n", + name, oh_name); + kfree(pdata->devices); + kfree(pdata); + return; + } +} +#else +static inline void omap_init_ocp2scp(void) { } +#endif + /*-------------------------------------------------------------------------*/ static int __init omap2_init_devices(void) @@ -640,6 +718,7 @@ static int __init omap2_init_devices(void) omap_init_sham(); omap_init_aes(); omap_init_vout(); + omap_init_ocp2scp(); return 0; } -- cgit v1.2.3 From 5e767ab928088ca2a835b94b94dd286c2ca840ea Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 8 Oct 2012 10:47:34 +0200 Subject: ARM: OMAP: Add maintainer entry for IGEP machines Enric and I have been mantained this machine and while we are moving to device trees, it is good that people cc us when reporting bugs or regression on the board file until we have proper DT support. Signed-off-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 59203e77ce9..8a398b0cc4e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -841,6 +841,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git F: arch/arm/mach-sa1100/jornada720.c F: arch/arm/mach-sa1100/include/mach/jornada720.h +ARM/IGEP MACHINE SUPPORT +M: Enric Balletbo i Serra +M: Javier Martinez Canillas +L: linux-omap@vger.kernel.org +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/mach-omap2/board-igep0020.c + ARM/INCOME PXA270 SUPPORT M: Marek Vasut L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -- cgit v1.2.3 From cbf6bae1044286a89955d7c4b3a8d6d84a9916b3 Mon Sep 17 00:00:00 2001 From: Anders Hedlund Date: Mon, 29 Oct 2012 20:25:42 +0100 Subject: ARM: OMAP3: igep0020: Set WIFI/BT GPIO pins in correct mux mode Setup the WIFI/BT GPIO pin muxes to enable WIFI/BT functionality. This is needed to fix regression caused by recent versions of u-boot that only mux essential pins. Signed-off-by: Anders Hedlund Cc: Jonas Zetterberg Cc: Enric Balletbo i Serra Cc: Javier Martinez Canillas Cc: Matthias Brugger [tony@atomide.com: updated comments to describe regression] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-igep0020.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c index 48d5e41dfbf..37859069444 100644 --- a/arch/arm/mach-omap2/board-igep0020.c +++ b/arch/arm/mach-omap2/board-igep0020.c @@ -580,6 +580,11 @@ static void __init igep_wlan_bt_init(void) } else return; + /* Make sure that the GPIO pins are muxed correctly */ + omap_mux_init_gpio(igep_wlan_bt_gpios[0].gpio, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(igep_wlan_bt_gpios[1].gpio, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(igep_wlan_bt_gpios[2].gpio, OMAP_PIN_OUTPUT); + err = gpio_request_array(igep_wlan_bt_gpios, ARRAY_SIZE(igep_wlan_bt_gpios)); if (err) { -- cgit v1.2.3 From 2d9e7ea690d76b95a7eb3fd8eb3823b4f5946050 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 6 Nov 2012 17:23:35 +0100 Subject: [media] dvb_usb_v2: fix pid_filter callback error logging Code block braces were missing which leds broken error logging and compiler warning. drivers/media/usb/dvb-usb-v2/dvb_usb_core.c: In function 'dvb_usb_ctrl_feed': drivers/media/usb/dvb-usb-v2/dvb_usb_core.c:291:12: warning: 'ret' may be used uninitialized in this function [-Wuninitialized] Reported-by: Stephen Rothwell Reported-by: Milan Tuma Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 9859d2a2449..ba51f65204d 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -283,14 +283,13 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, /* activate the pid on the device pid filter */ if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER && - adap->pid_filtering && - adap->props->pid_filter) + adap->pid_filtering && adap->props->pid_filter) { ret = adap->props->pid_filter(adap, dvbdmxfeed->index, dvbdmxfeed->pid, (count == 1) ? 1 : 0); - if (ret < 0) - dev_err(&d->udev->dev, "%s: pid_filter() " \ - "failed=%d\n", KBUILD_MODNAME, - ret); + if (ret < 0) + dev_err(&d->udev->dev, "%s: pid_filter() failed=%d\n", + KBUILD_MODNAME, ret); + } /* start feeding if it is first pid */ if (adap->feed_count == 1 && count == 1) { -- cgit v1.2.3 From 6d369a09ccd8104b35646b507112d3ddca4344eb Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 8 Nov 2012 11:26:34 +0000 Subject: x86: Export asm/{svm.h,vmx.h,perf_regs.h} Export asm/{svm.h,vmx.h,perf_regs.h} so that they can be disintegrated. It looks from previous commits that the first two should have been exported, but the header-y lines weren't added to the Kbuild. I'm guessing that asm/perf_regs.h should be exported too. Signed-off-by: David Howells --- arch/x86/include/asm/Kbuild | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild index 66e5f0ef052..79fd8a3418f 100644 --- a/arch/x86/include/asm/Kbuild +++ b/arch/x86/include/asm/Kbuild @@ -12,6 +12,7 @@ header-y += mce.h header-y += msr-index.h header-y += msr.h header-y += mtrr.h +header-y += perf_regs.h header-y += posix_types_32.h header-y += posix_types_64.h header-y += posix_types_x32.h @@ -19,8 +20,10 @@ header-y += prctl.h header-y += processor-flags.h header-y += ptrace-abi.h header-y += sigcontext32.h +header-y += svm.h header-y += ucontext.h header-y += vm86.h +header-y += vmx.h header-y += vsyscall.h genhdr-y += unistd_32.h -- cgit v1.2.3 From f48283367fd2679906e06bdd9e886eec1ee59eb1 Mon Sep 17 00:00:00 2001 From: Jonas Aaberg Date: Thu, 25 Oct 2012 08:46:53 +0200 Subject: ARM: ux500: add PRCM register base for pinctrl This adds the PRCM register range base as a resource to the pinctrl driver do we can break the dependency to the PRCMU driver and handle these registers in the driver alone. Cc: arm@kernel.org Signed-off-by: Jonas Aaberg Acked-by: Arnd Bergmann Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/cpu-db8500.c | 2 +- arch/arm/mach-ux500/devices-common.h | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 87a8f9fbb10..113d9c47a84 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -158,7 +158,7 @@ static void __init db8500_add_gpios(struct device *parent) dbx500_add_gpios(parent, ARRAY_AND_SIZE(db8500_gpio_base), IRQ_DB8500_GPIO0, &pdata); - dbx500_add_pinctrl(parent, "pinctrl-db8500"); + dbx500_add_pinctrl(parent, "pinctrl-db8500", U8500_PRCMU_BASE); } static int usb_db8500_rx_dma_cfg[] = { diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h index 7fbf0ba336e..96fa4ac89e2 100644 --- a/arch/arm/mach-ux500/devices-common.h +++ b/arch/arm/mach-ux500/devices-common.h @@ -129,12 +129,18 @@ void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num, int irq, struct nmk_gpio_platform_data *pdata); static inline void -dbx500_add_pinctrl(struct device *parent, const char *name) +dbx500_add_pinctrl(struct device *parent, const char *name, + resource_size_t base) { + struct resource res[] = { + DEFINE_RES_MEM(base, SZ_8K), + }; struct platform_device_info pdevinfo = { .parent = parent, .name = name, .id = -1, + .res = res, + .num_res = ARRAY_SIZE(res), }; platform_device_register_full(&pdevinfo); -- cgit v1.2.3 From e32672f0bc7ec8421aa8e580e9f2216d3bec2505 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 8 Nov 2012 15:26:41 +0200 Subject: usb: dwc3: core: don't kfree() devm_kzalloc()'ed memory commit 380f0d2 (usb: dwc3: core: switch event buffer allocation to devm_kzalloc()) was incomplete leaving a trailing kfree(evt) in an error exit path. Fix this problem by removing the trailing kfree(evt). Cc: Julia Lawall Reported-by: Fengguang Wu Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index d8d327a5e53..2bd007d1646 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -153,10 +153,8 @@ dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length) evt->length = length; evt->buf = dma_alloc_coherent(dwc->dev, length, &evt->dma, GFP_KERNEL); - if (!evt->buf) { - kfree(evt); + if (!evt->buf) return ERR_PTR(-ENOMEM); - } return evt; } -- cgit v1.2.3 From 1c90ee0b3e30235165180a1a8ee3fb3cbe47d295 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 6 Nov 2012 16:15:09 -0800 Subject: usb: renesas_usbhs: use transfer counter if IN direction bulk pipe received data will break if it was bulk pipe and large data size, because pipe kept BUF PID even though it doesn't have enough buffer. To avoid this issue, renesas_usbhs can use transfer counter. Pipe PID will be NAK if it didn't have enough buffer by this patch. renesas_usbhs has strange address mapping. Thus, it is difficult to calculate transfer counter setting address. This patch use fixed table for it. Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/fifo.c | 4 ++ drivers/usb/renesas_usbhs/pipe.c | 101 +++++++++++++++++++++++++++++++++++++++ drivers/usb/renesas_usbhs/pipe.h | 1 + 3 files changed, 106 insertions(+) diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 77f1adc2a4f..72ad3758bd4 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -488,6 +488,8 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done) usbhs_pipe_data_sequence(pipe, pkt->sequence); pkt->sequence = -1; /* -1 sequence will be ignored */ + usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length); + ret = usbhsf_fifo_select(pipe, fifo, 1); if (ret < 0) return 0; @@ -594,6 +596,7 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) usbhs_pipe_data_sequence(pipe, pkt->sequence); pkt->sequence = -1; /* -1 sequence will be ignored */ + usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length); usbhs_pipe_enable(pipe); usbhsf_rx_irq_ctrl(pipe, 1); @@ -795,6 +798,7 @@ static void xfer_work(struct work_struct *work) dev_dbg(dev, " %s %d (%d/ %d)\n", fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); + usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); usbhsf_dma_start(pipe, fifo); dma_async_issue_pending(chan); } diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index 122526cfd32..7926e1c700f 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c @@ -92,6 +92,82 @@ static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val) __usbhsp_pipe_xxx_set(pipe, DCPCFG, PIPECFG, mask, val); } +/* + * PIPEnTRN/PIPEnTRE functions + */ +static void usbhsp_pipe_trn_set(struct usbhs_pipe *pipe, u16 mask, u16 val) +{ + struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); + struct device *dev = usbhs_priv_to_dev(priv); + int num = usbhs_pipe_number(pipe); + u16 reg; + + /* + * It is impossible to calculate address, + * since PIPEnTRN addresses were mapped randomly. + */ +#define CASE_PIPExTRN(a) \ + case 0x ## a: \ + reg = PIPE ## a ## TRN; \ + break; + + switch (num) { + CASE_PIPExTRN(1); + CASE_PIPExTRN(2); + CASE_PIPExTRN(3); + CASE_PIPExTRN(4); + CASE_PIPExTRN(5); + CASE_PIPExTRN(B); + CASE_PIPExTRN(C); + CASE_PIPExTRN(D); + CASE_PIPExTRN(E); + CASE_PIPExTRN(F); + CASE_PIPExTRN(9); + CASE_PIPExTRN(A); + default: + dev_err(dev, "unknown pipe (%d)\n", num); + return; + } + __usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val); +} + +static void usbhsp_pipe_tre_set(struct usbhs_pipe *pipe, u16 mask, u16 val) +{ + struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); + struct device *dev = usbhs_priv_to_dev(priv); + int num = usbhs_pipe_number(pipe); + u16 reg; + + /* + * It is impossible to calculate address, + * since PIPEnTRE addresses were mapped randomly. + */ +#define CASE_PIPExTRE(a) \ + case 0x ## a: \ + reg = PIPE ## a ## TRE; \ + break; + + switch (num) { + CASE_PIPExTRE(1); + CASE_PIPExTRE(2); + CASE_PIPExTRE(3); + CASE_PIPExTRE(4); + CASE_PIPExTRE(5); + CASE_PIPExTRE(B); + CASE_PIPExTRE(C); + CASE_PIPExTRE(D); + CASE_PIPExTRE(E); + CASE_PIPExTRE(F); + CASE_PIPExTRE(9); + CASE_PIPExTRE(A); + default: + dev_err(dev, "unknown pipe (%d)\n", num); + return; + } + + __usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val); +} + /* * PIPEBUF */ @@ -264,6 +340,31 @@ int usbhs_pipe_is_stall(struct usbhs_pipe *pipe) return (int)(pid == PID_STALL10 || pid == PID_STALL11); } +void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len) +{ + if (!usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK)) + return; + + /* + * clear and disable transfer counter for IN/OUT pipe + */ + usbhsp_pipe_tre_set(pipe, TRCLR | TRENB, TRCLR); + + /* + * Only IN direction bulk pipe can use transfer count. + * Without using this function, + * received data will break if it was large data size. + * see PIPEnTRN/PIPEnTRE for detail + */ + if (usbhs_pipe_is_dir_in(pipe)) { + int maxp = usbhs_pipe_get_maxpacket(pipe); + + usbhsp_pipe_trn_set(pipe, 0xffff, DIV_ROUND_UP(len, maxp)); + usbhsp_pipe_tre_set(pipe, TRENB, TRENB); /* enable */ + } +} + + /* * pipe setup */ diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h index 08786c06dcf..01b1820eccc 100644 --- a/drivers/usb/renesas_usbhs/pipe.h +++ b/drivers/usb/renesas_usbhs/pipe.h @@ -88,6 +88,7 @@ void usbhs_pipe_enable(struct usbhs_pipe *pipe); void usbhs_pipe_disable(struct usbhs_pipe *pipe); void usbhs_pipe_stall(struct usbhs_pipe *pipe); int usbhs_pipe_is_stall(struct usbhs_pipe *pipe); +void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len); void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo); void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel, u16 epnum, u16 maxp); -- cgit v1.2.3 From 77614e0250611fbeeb94b12e0a0b7f281fe61329 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 6 Nov 2012 22:52:35 +0100 Subject: arch: Change defconfigs to point to g_mass_storage. The File-backed Storage Gadget (g_file_storage) is being removed, since it has been replaced by Mass Storage Gadget (g_mass_storage). This commit changes defconfigs point to the new gadget. Signed-off-by: Michal Nazarewicz Acked-by: Nicolas Ferre (AT91) Acked-by: Tony Lindgren (OMAP1) Acked-by: Hans-Christian Egtvedt (AVR32) Signed-off-by: Felipe Balbi --- arch/arm/configs/afeb9260_defconfig | 2 +- arch/arm/configs/at91sam9260_defconfig | 2 +- arch/arm/configs/at91sam9261_defconfig | 2 +- arch/arm/configs/at91sam9263_defconfig | 2 +- arch/arm/configs/at91sam9g20_defconfig | 2 +- arch/arm/configs/corgi_defconfig | 2 +- arch/arm/configs/davinci_all_defconfig | 2 +- arch/arm/configs/h7202_defconfig | 3 +-- arch/arm/configs/magician_defconfig | 2 +- arch/arm/configs/mini2440_defconfig | 2 +- arch/arm/configs/omap1_defconfig | 3 +-- arch/arm/configs/prima2_defconfig | 1 - arch/arm/configs/spitz_defconfig | 2 +- arch/arm/configs/stamp9g20_defconfig | 2 +- arch/arm/configs/viper_defconfig | 2 +- arch/arm/configs/zeus_defconfig | 2 +- arch/avr32/configs/atngw100_defconfig | 2 +- arch/avr32/configs/atngw100_evklcd100_defconfig | 2 +- arch/avr32/configs/atngw100_evklcd101_defconfig | 2 +- arch/avr32/configs/atngw100_mrmt_defconfig | 2 +- arch/avr32/configs/atngw100mkii_defconfig | 2 +- arch/avr32/configs/atngw100mkii_evklcd100_defconfig | 2 +- arch/avr32/configs/atngw100mkii_evklcd101_defconfig | 2 +- arch/avr32/configs/atstk1002_defconfig | 2 +- arch/avr32/configs/atstk1003_defconfig | 2 +- arch/avr32/configs/atstk1004_defconfig | 2 +- arch/avr32/configs/atstk1006_defconfig | 2 +- arch/avr32/configs/favr-32_defconfig | 2 +- arch/avr32/configs/hammerhead_defconfig | 2 +- arch/blackfin/configs/CM-BF527_defconfig | 2 +- arch/blackfin/configs/CM-BF548_defconfig | 2 +- arch/blackfin/configs/CM-BF561_defconfig | 2 +- arch/mips/configs/bcm47xx_defconfig | 2 +- arch/mips/configs/mtx1_defconfig | 2 +- arch/sh/configs/ecovec24_defconfig | 2 +- arch/sh/configs/se7724_defconfig | 2 +- 36 files changed, 35 insertions(+), 38 deletions(-) diff --git a/arch/arm/configs/afeb9260_defconfig b/arch/arm/configs/afeb9260_defconfig index c285a9d777d..a8dbc1e0525 100644 --- a/arch/arm/configs/afeb9260_defconfig +++ b/arch/arm/configs/afeb9260_defconfig @@ -79,7 +79,7 @@ CONFIG_USB_STORAGE=y CONFIG_USB_GADGET=y CONFIG_USB_ZERO=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_RTC_CLASS=y CONFIG_RTC_DEBUG=y diff --git a/arch/arm/configs/at91sam9260_defconfig b/arch/arm/configs/at91sam9260_defconfig index 505b3765f87..0ea5d2c97fc 100644 --- a/arch/arm/configs/at91sam9260_defconfig +++ b/arch/arm/configs/at91sam9260_defconfig @@ -75,7 +75,7 @@ CONFIG_USB_STORAGE_DEBUG=y CONFIG_USB_GADGET=y CONFIG_USB_ZERO=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_AT91SAM9=y diff --git a/arch/arm/configs/at91sam9261_defconfig b/arch/arm/configs/at91sam9261_defconfig index 1e8712ef062..c87beb973b3 100644 --- a/arch/arm/configs/at91sam9261_defconfig +++ b/arch/arm/configs/at91sam9261_defconfig @@ -125,7 +125,7 @@ CONFIG_USB_GADGET=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_MMC=y CONFIG_MMC_ATMELMCI=m diff --git a/arch/arm/configs/at91sam9263_defconfig b/arch/arm/configs/at91sam9263_defconfig index d2050cada82..c5212f43eee 100644 --- a/arch/arm/configs/at91sam9263_defconfig +++ b/arch/arm/configs/at91sam9263_defconfig @@ -133,7 +133,7 @@ CONFIG_USB_GADGET=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_MMC=y CONFIG_SDIO_UART=m diff --git a/arch/arm/configs/at91sam9g20_defconfig b/arch/arm/configs/at91sam9g20_defconfig index e1b0e80b54a..3b1881033ad 100644 --- a/arch/arm/configs/at91sam9g20_defconfig +++ b/arch/arm/configs/at91sam9g20_defconfig @@ -96,7 +96,7 @@ CONFIG_USB_STORAGE=y CONFIG_USB_GADGET=y CONFIG_USB_ZERO=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_MMC=y CONFIG_MMC_ATMELMCI=m diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index 4b8a25d9e68..1fd1d1de322 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig @@ -218,7 +218,7 @@ CONFIG_USB_GADGET=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_MMC=y CONFIG_MMC_PXA=y diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig index 67b5abb6f85..4ea7c95719d 100644 --- a/arch/arm/configs/davinci_all_defconfig +++ b/arch/arm/configs/davinci_all_defconfig @@ -144,7 +144,7 @@ CONFIG_USB_GADGET_DEBUG_FS=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_G_PRINTER=m CONFIG_USB_CDC_COMPOSITE=m diff --git a/arch/arm/configs/h7202_defconfig b/arch/arm/configs/h7202_defconfig index 69405a76242..e16d3f372e2 100644 --- a/arch/arm/configs/h7202_defconfig +++ b/arch/arm/configs/h7202_defconfig @@ -34,8 +34,7 @@ CONFIG_FB_MODE_HELPERS=y CONFIG_USB_GADGET=m CONFIG_USB_ZERO=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m -CONFIG_USB_FILE_STORAGE_TEST=y +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_EXT2_FS=y CONFIG_TMPFS=y diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig index a691ef4c600..557dd291288 100644 --- a/arch/arm/configs/magician_defconfig +++ b/arch/arm/configs/magician_defconfig @@ -136,7 +136,7 @@ CONFIG_USB_PXA27X=y CONFIG_USB_ETH=m # CONFIG_USB_ETH_RNDIS is not set CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_USB_GPIO_VBUS=y diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig index 00630e6af45..a07948a87ca 100644 --- a/arch/arm/configs/mini2440_defconfig +++ b/arch/arm/configs/mini2440_defconfig @@ -240,7 +240,7 @@ CONFIG_USB_GADGET_S3C2410=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig index dde2a1af7b3..42eab9a2a0f 100644 --- a/arch/arm/configs/omap1_defconfig +++ b/arch/arm/configs/omap1_defconfig @@ -214,8 +214,7 @@ CONFIG_USB_TEST=y CONFIG_USB_GADGET=y CONFIG_USB_ETH=m # CONFIG_USB_ETH_RNDIS is not set -CONFIG_USB_FILE_STORAGE=m -CONFIG_USB_FILE_STORAGE_TEST=y +CONFIG_USB_MASS_STORAGE=m CONFIG_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y diff --git a/arch/arm/configs/prima2_defconfig b/arch/arm/configs/prima2_defconfig index 807d4e2acb1..6a936c7c078 100644 --- a/arch/arm/configs/prima2_defconfig +++ b/arch/arm/configs/prima2_defconfig @@ -37,7 +37,6 @@ CONFIG_SPI_SIRF=y CONFIG_SPI_SPIDEV=y # CONFIG_HWMON is not set CONFIG_USB_GADGET=y -CONFIG_USB_FILE_STORAGE=m CONFIG_USB_MASS_STORAGE=m CONFIG_MMC=y CONFIG_MMC_SDHCI=y diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig index df77931a432..2e0419d1b96 100644 --- a/arch/arm/configs/spitz_defconfig +++ b/arch/arm/configs/spitz_defconfig @@ -214,7 +214,7 @@ CONFIG_USB_GADGET_DUMMY_HCD=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_MMC=y CONFIG_MMC_PXA=y diff --git a/arch/arm/configs/stamp9g20_defconfig b/arch/arm/configs/stamp9g20_defconfig index 52f1488591c..b845f5519bc 100644 --- a/arch/arm/configs/stamp9g20_defconfig +++ b/arch/arm/configs/stamp9g20_defconfig @@ -97,7 +97,7 @@ CONFIG_USB_STORAGE=y CONFIG_USB_GADGET=m CONFIG_USB_ZERO=m CONFIG_USB_ETH=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_MMC=y CONFIG_MMC_ATMELMCI=y diff --git a/arch/arm/configs/viper_defconfig b/arch/arm/configs/viper_defconfig index 1d01ddd3312..d36e0d3c86e 100644 --- a/arch/arm/configs/viper_defconfig +++ b/arch/arm/configs/viper_defconfig @@ -139,7 +139,7 @@ CONFIG_USB_SERIAL_MCT_U232=m CONFIG_USB_GADGET=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_G_PRINTER=m CONFIG_RTC_CLASS=y diff --git a/arch/arm/configs/zeus_defconfig b/arch/arm/configs/zeus_defconfig index 547a3c1e59d..731d4f98531 100644 --- a/arch/arm/configs/zeus_defconfig +++ b/arch/arm/configs/zeus_defconfig @@ -143,7 +143,7 @@ CONFIG_USB_GADGET=m CONFIG_USB_PXA27X=y CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_G_PRINTER=m CONFIG_MMC=y diff --git a/arch/avr32/configs/atngw100_defconfig b/arch/avr32/configs/atngw100_defconfig index a06bfccc284..f4025db184f 100644 --- a/arch/avr32/configs/atngw100_defconfig +++ b/arch/avr32/configs/atngw100_defconfig @@ -109,7 +109,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350 CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/avr32/configs/atngw100_evklcd100_defconfig b/arch/avr32/configs/atngw100_evklcd100_defconfig index d8f1fe80d21..c76a49b9e9d 100644 --- a/arch/avr32/configs/atngw100_evklcd100_defconfig +++ b/arch/avr32/configs/atngw100_evklcd100_defconfig @@ -125,7 +125,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350 CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/avr32/configs/atngw100_evklcd101_defconfig b/arch/avr32/configs/atngw100_evklcd101_defconfig index d4c5b19ec95..2d8ab089a64 100644 --- a/arch/avr32/configs/atngw100_evklcd101_defconfig +++ b/arch/avr32/configs/atngw100_evklcd101_defconfig @@ -124,7 +124,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350 CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/avr32/configs/atngw100_mrmt_defconfig b/arch/avr32/configs/atngw100_mrmt_defconfig index 77ca4f905d2..b189e0cab04 100644 --- a/arch/avr32/configs/atngw100_mrmt_defconfig +++ b/arch/avr32/configs/atngw100_mrmt_defconfig @@ -99,7 +99,7 @@ CONFIG_SND_ATMEL_AC97C=m # CONFIG_SND_SPI is not set CONFIG_USB_GADGET=m CONFIG_USB_GADGET_DEBUG_FILES=y -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_MMC=y CONFIG_MMC_ATMELMCI=y diff --git a/arch/avr32/configs/atngw100mkii_defconfig b/arch/avr32/configs/atngw100mkii_defconfig index 6e0dca4d313..2e4de42a53c 100644 --- a/arch/avr32/configs/atngw100mkii_defconfig +++ b/arch/avr32/configs/atngw100mkii_defconfig @@ -111,7 +111,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350 CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/avr32/configs/atngw100mkii_evklcd100_defconfig b/arch/avr32/configs/atngw100mkii_evklcd100_defconfig index 7f2a344a5fa..fad3cd22dfd 100644 --- a/arch/avr32/configs/atngw100mkii_evklcd100_defconfig +++ b/arch/avr32/configs/atngw100mkii_evklcd100_defconfig @@ -128,7 +128,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350 CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/avr32/configs/atngw100mkii_evklcd101_defconfig b/arch/avr32/configs/atngw100mkii_evklcd101_defconfig index 085eeba88f6..29986230aaa 100644 --- a/arch/avr32/configs/atngw100mkii_evklcd101_defconfig +++ b/arch/avr32/configs/atngw100mkii_evklcd101_defconfig @@ -127,7 +127,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=350 CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/avr32/configs/atstk1002_defconfig b/arch/avr32/configs/atstk1002_defconfig index d1a887e6405..a582465e1ce 100644 --- a/arch/avr32/configs/atstk1002_defconfig +++ b/arch/avr32/configs/atstk1002_defconfig @@ -126,7 +126,7 @@ CONFIG_USB_GADGET=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/avr32/configs/atstk1003_defconfig b/arch/avr32/configs/atstk1003_defconfig index 956f2819ad4..57a79df2ce5 100644 --- a/arch/avr32/configs/atstk1003_defconfig +++ b/arch/avr32/configs/atstk1003_defconfig @@ -105,7 +105,7 @@ CONFIG_USB_GADGET=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/avr32/configs/atstk1004_defconfig b/arch/avr32/configs/atstk1004_defconfig index 40c69f38c61..1a49bd8c634 100644 --- a/arch/avr32/configs/atstk1004_defconfig +++ b/arch/avr32/configs/atstk1004_defconfig @@ -104,7 +104,7 @@ CONFIG_USB_GADGET=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/avr32/configs/atstk1006_defconfig b/arch/avr32/configs/atstk1006_defconfig index 511eb8af356..206a1b67f76 100644 --- a/arch/avr32/configs/atstk1006_defconfig +++ b/arch/avr32/configs/atstk1006_defconfig @@ -129,7 +129,7 @@ CONFIG_USB_GADGET=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/avr32/configs/favr-32_defconfig b/arch/avr32/configs/favr-32_defconfig index 19973b06170..0421498d666 100644 --- a/arch/avr32/configs/favr-32_defconfig +++ b/arch/avr32/configs/favr-32_defconfig @@ -117,7 +117,7 @@ CONFIG_USB_GADGET=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/avr32/configs/hammerhead_defconfig b/arch/avr32/configs/hammerhead_defconfig index 6f45681196d..82f24eb251b 100644 --- a/arch/avr32/configs/hammerhead_defconfig +++ b/arch/avr32/configs/hammerhead_defconfig @@ -127,7 +127,7 @@ CONFIG_USB_GADGET=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_MMC=m CONFIG_MMC_ATMELMCI=m diff --git a/arch/blackfin/configs/CM-BF527_defconfig b/arch/blackfin/configs/CM-BF527_defconfig index c280a50e794..f59c80ee78e 100644 --- a/arch/blackfin/configs/CM-BF527_defconfig +++ b/arch/blackfin/configs/CM-BF527_defconfig @@ -106,7 +106,7 @@ CONFIG_MUSB_PIO_ONLY=y CONFIG_USB_STORAGE=m CONFIG_USB_GADGET=m CONFIG_USB_ETH=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_G_PRINTER=m CONFIG_RTC_CLASS=y diff --git a/arch/blackfin/configs/CM-BF548_defconfig b/arch/blackfin/configs/CM-BF548_defconfig index 349922be01f..e961483f187 100644 --- a/arch/blackfin/configs/CM-BF548_defconfig +++ b/arch/blackfin/configs/CM-BF548_defconfig @@ -107,7 +107,7 @@ CONFIG_USB_ZERO=m CONFIG_USB_ETH=m # CONFIG_USB_ETH_RNDIS is not set CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_G_PRINTER=m CONFIG_MMC=m diff --git a/arch/blackfin/configs/CM-BF561_defconfig b/arch/blackfin/configs/CM-BF561_defconfig index 0456deaa2d6..24936b91a6e 100644 --- a/arch/blackfin/configs/CM-BF561_defconfig +++ b/arch/blackfin/configs/CM-BF561_defconfig @@ -83,7 +83,7 @@ CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y CONFIG_USB_GADGET=m CONFIG_USB_ETH=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_G_PRINTER=m CONFIG_MMC=y diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index b6fde2bb51b..4ca8e5c9922 100644 --- a/arch/mips/configs/bcm47xx_defconfig +++ b/arch/mips/configs/bcm47xx_defconfig @@ -473,7 +473,7 @@ CONFIG_USB_GADGET_NET2280=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_MIDI_GADGET=m CONFIG_LEDS_CLASS=y diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index 46c61edcdf7..a0277d4fd04 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -661,7 +661,7 @@ CONFIG_USB_GADGET_NET2280=y CONFIG_USB_ZERO=m CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_USB_MIDI_GADGET=m CONFIG_MMC=m diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig index 911e30c9abf..c6c2becdc8a 100644 --- a/arch/sh/configs/ecovec24_defconfig +++ b/arch/sh/configs/ecovec24_defconfig @@ -112,7 +112,7 @@ CONFIG_USB_MON=y CONFIG_USB_R8A66597_HCD=y CONFIG_USB_STORAGE=y CONFIG_USB_GADGET=y -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_MMC=y CONFIG_MMC_SPI=y CONFIG_MMC_SDHI=y diff --git a/arch/sh/configs/se7724_defconfig b/arch/sh/configs/se7724_defconfig index ed35093e375..1faa788aeca 100644 --- a/arch/sh/configs/se7724_defconfig +++ b/arch/sh/configs/se7724_defconfig @@ -109,7 +109,7 @@ CONFIG_USB_STORAGE=y CONFIG_USB_GADGET=y CONFIG_USB_ETH=m CONFIG_USB_GADGETFS=m -CONFIG_USB_FILE_STORAGE=m +CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m CONFIG_MMC=y CONFIG_MMC_SPI=y -- cgit v1.2.3 From fa06920a3ece1ed43333992d35c0044e7a6c048a Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 6 Nov 2012 22:52:36 +0100 Subject: usb: gadget: Remove File-backed Storage Gadget (g_file_storage). The File-backed Storage Gadget (g_file_storage) gadget has been replaced with Mass Storage Gadget (g_mass_storage) which uses the composite framework. This commit removes g_file_storage (and most references to it). Signed-off-by: Michal Nazarewicz Acked-by: Alan Stern Signed-off-by: Felipe Balbi --- Documentation/DocBook/gadget.tmpl | 2 +- Documentation/usb/mass-storage.txt | 15 +- drivers/usb/gadget/Kconfig | 29 +- drivers/usb/gadget/Makefile | 2 - drivers/usb/gadget/file_storage.c | 3656 ------------------------------------ drivers/usb/gadget/net2280.c | 2 +- drivers/usb/gadget/pxa27x_udc.h | 2 +- 7 files changed, 12 insertions(+), 3696 deletions(-) delete mode 100644 drivers/usb/gadget/file_storage.c diff --git a/Documentation/DocBook/gadget.tmpl b/Documentation/DocBook/gadget.tmpl index 6ef2f0073e5..4017f147ba2 100644 --- a/Documentation/DocBook/gadget.tmpl +++ b/Documentation/DocBook/gadget.tmpl @@ -671,7 +671,7 @@ than a kernel driver. There's a USB Mass Storage class driver, which provides a different solution for interoperability with systems such as MS-Windows and MacOS. -That File-backed Storage driver uses a +That Mass Storage driver uses a file or block device as backing store for a drive, like the loop driver. The USB host uses the BBB, CB, or CBI versions of the mass diff --git a/Documentation/usb/mass-storage.txt b/Documentation/usb/mass-storage.txt index e9b9334627b..59063ad7a60 100644 --- a/Documentation/usb/mass-storage.txt +++ b/Documentation/usb/mass-storage.txt @@ -20,9 +20,9 @@ This document describes how to use the gadget from user space, its relation to mass storage function (or MSF) and different gadgets - using it, and how it differs from File Storage Gadget (or FSG). It - will talk only briefly about how to use MSF within composite - gadgets. + using it, and how it differs from File Storage Gadget (or FSG) + (which is no longer included in Linux). It will talk only briefly + about how to use MSF within composite gadgets. * Module parameters @@ -198,16 +198,15 @@ The Mass Storage Function and thus the Mass Storage Gadget has been based on the File Storage Gadget. The difference between the two is that MSG is a composite gadget (ie. uses the composite framework) - while file storage gadget is a traditional gadget. From userspace + while file storage gadget was a traditional gadget. From userspace point of view this distinction does not really matter, but from kernel hacker's point of view, this means that (i) MSG does not duplicate code needed for handling basic USB protocol commands and (ii) MSF can be used in any other composite gadget. - Because of that, File Storage Gadget has been deprecated and - scheduled to be removed in Linux 3.8. All users need to transition - to the Mass Storage Gadget by that time. The two gadgets behave - mostly the same from the outside except: + Because of that, File Storage Gadget has been removed in Linux 3.8. + All users need to transition to the Mass Storage Gadget. The two + gadgets behave mostly the same from the outside except: 1. In FSG the “removable” and “cdrom” module parameters set the flag for all logical units whereas in MSG they accept a list of y/n diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index dfb51a45496..63b5869e094 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -721,31 +721,6 @@ config USB_FUNCTIONFS_GENERIC Include a configuration with the Function Filesystem alone with no Ethernet interface. -config USB_FILE_STORAGE - tristate "File-backed Storage Gadget (DEPRECATED)" - depends on BLOCK - help - The File-backed Storage Gadget acts as a USB Mass Storage - disk drive. As its storage repository it can use a regular - file or a block device (in much the same way as the "loop" - device driver), specified as a module parameter. - - Say "y" to link the driver statically, or "m" to build a - dynamically linked module called "g_file_storage". - - NOTE: This driver is deprecated. Its replacement is the - Mass Storage Gadget. - -config USB_FILE_STORAGE_TEST - bool "File-backed Storage Gadget testing version" - depends on USB_FILE_STORAGE - default n - help - Say "y" to generate the larger testing version of the - File-backed Storage Gadget, useful for probing the - behavior of USB Mass Storage hosts. Not needed for - normal operation. - config USB_MASS_STORAGE tristate "Mass Storage Gadget" depends on BLOCK @@ -756,8 +731,8 @@ config USB_MASS_STORAGE device (in much the same way as the "loop" device driver), specified as a module parameter or sysfs option. - This driver is an updated replacement for the deprecated - File-backed Storage Gadget (g_file_storage). + This driver is a replacement for now removed File-backed + Storage Gadget (g_file_storage). Say "y" to link the driver statically, or "m" to build a dynamically linked module called "g_mass_storage". diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 307be5fa824..8b4acfd92aa 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -44,7 +44,6 @@ g_ether-y := ether.o g_serial-y := serial.o g_midi-y := gmidi.o gadgetfs-y := inode.o -g_file_storage-y := file_storage.o g_mass_storage-y := mass_storage.o g_printer-y := printer.o g_cdc-y := cdc2.o @@ -62,7 +61,6 @@ obj-$(CONFIG_USB_AUDIO) += g_audio.o obj-$(CONFIG_USB_ETH) += g_ether.o obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o obj-$(CONFIG_USB_FUNCTIONFS) += g_ffs.o -obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o obj-$(CONFIG_USB_MASS_STORAGE) += g_mass_storage.o obj-$(CONFIG_USB_G_SERIAL) += g_serial.o obj-$(CONFIG_USB_G_PRINTER) += g_printer.o diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c deleted file mode 100644 index 3f7d640b675..00000000000 --- a/drivers/usb/gadget/file_storage.c +++ /dev/null @@ -1,3656 +0,0 @@ -/* - * file_storage.c -- File-backed USB Storage Gadget, for USB development - * - * Copyright (C) 2003-2008 Alan Stern - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The names of the above-listed copyright holders may not be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -/* - * The File-backed Storage Gadget acts as a USB Mass Storage device, - * appearing to the host as a disk drive or as a CD-ROM drive. In addition - * to providing an example of a genuinely useful gadget driver for a USB - * device, it also illustrates a technique of double-buffering for increased - * throughput. Last but not least, it gives an easy way to probe the - * behavior of the Mass Storage drivers in a USB host. - * - * Backing storage is provided by a regular file or a block device, specified - * by the "file" module parameter. Access can be limited to read-only by - * setting the optional "ro" module parameter. (For CD-ROM emulation, - * access is always read-only.) The gadget will indicate that it has - * removable media if the optional "removable" module parameter is set. - * - * The gadget supports the Control-Bulk (CB), Control-Bulk-Interrupt (CBI), - * and Bulk-Only (also known as Bulk-Bulk-Bulk or BBB) transports, selected - * by the optional "transport" module parameter. It also supports the - * following protocols: RBC (0x01), ATAPI or SFF-8020i (0x02), QIC-157 (0c03), - * UFI (0x04), SFF-8070i (0x05), and transparent SCSI (0x06), selected by - * the optional "protocol" module parameter. In addition, the default - * Vendor ID, Product ID, release number and serial number can be overridden. - * - * There is support for multiple logical units (LUNs), each of which has - * its own backing file. The number of LUNs can be set using the optional - * "luns" module parameter (anywhere from 1 to 8), and the corresponding - * files are specified using comma-separated lists for "file" and "ro". - * The default number of LUNs is taken from the number of "file" elements; - * it is 1 if "file" is not given. If "removable" is not set then a backing - * file must be specified for each LUN. If it is set, then an unspecified - * or empty backing filename means the LUN's medium is not loaded. Ideally - * each LUN would be settable independently as a disk drive or a CD-ROM - * drive, but currently all LUNs have to be the same type. The CD-ROM - * emulation includes a single data track and no audio tracks; hence there - * need be only one backing file per LUN. - * - * Requirements are modest; only a bulk-in and a bulk-out endpoint are - * needed (an interrupt-out endpoint is also needed for CBI). The memory - * requirement amounts to two 16K buffers, size configurable by a parameter. - * Support is included for both full-speed and high-speed operation. - * - * Note that the driver is slightly non-portable in that it assumes a - * single memory/DMA buffer will be useable for bulk-in, bulk-out, and - * interrupt-in endpoints. With most device controllers this isn't an - * issue, but there may be some with hardware restrictions that prevent - * a buffer from being used by more than one endpoint. - * - * Module options: - * - * file=filename[,filename...] - * Required if "removable" is not set, names of - * the files or block devices used for - * backing storage - * serial=HHHH... Required serial number (string of hex chars) - * ro=b[,b...] Default false, booleans for read-only access - * removable Default false, boolean for removable media - * luns=N Default N = number of filenames, number of - * LUNs to support - * nofua=b[,b...] Default false, booleans for ignore FUA flag - * in SCSI WRITE(10,12) commands - * stall Default determined according to the type of - * USB device controller (usually true), - * boolean to permit the driver to halt - * bulk endpoints - * cdrom Default false, boolean for whether to emulate - * a CD-ROM drive - * transport=XXX Default BBB, transport name (CB, CBI, or BBB) - * protocol=YYY Default SCSI, protocol name (RBC, 8020 or - * ATAPI, QIC, UFI, 8070, or SCSI; - * also 1 - 6) - * vendor=0xVVVV Default 0x0525 (NetChip), USB Vendor ID - * product=0xPPPP Default 0xa4a5 (FSG), USB Product ID - * release=0xRRRR Override the USB release number (bcdDevice) - * buflen=N Default N=16384, buffer size used (will be - * rounded down to a multiple of - * PAGE_CACHE_SIZE) - * - * If CONFIG_USB_FILE_STORAGE_TEST is not set, only the "file", "serial", "ro", - * "removable", "luns", "nofua", "stall", and "cdrom" options are available; - * default values are used for everything else. - * - * The pathnames of the backing files and the ro settings are available in - * the attribute files "file", "nofua", and "ro" in the lun subdirectory of - * the gadget's sysfs directory. If the "removable" option is set, writing to - * these files will simulate ejecting/loading the medium (writing an empty - * line means eject) and adjusting a write-enable tab. Changes to the ro - * setting are not allowed when the medium is loaded or if CD-ROM emulation - * is being used. - * - * This gadget driver is heavily based on "Gadget Zero" by David Brownell. - * The driver's SCSI command interface was based on the "Information - * technology - Small Computer System Interface - 2" document from - * X3T9.2 Project 375D, Revision 10L, 7-SEP-93, available at - * . The single exception - * is opcode 0x23 (READ FORMAT CAPACITIES), which was based on the - * "Universal Serial Bus Mass Storage Class UFI Command Specification" - * document, Revision 1.0, December 14, 1998, available at - * . - */ - - -/* - * Driver Design - * - * The FSG driver is fairly straightforward. There is a main kernel - * thread that handles most of the work. Interrupt routines field - * callbacks from the controller driver: bulk- and interrupt-request - * completion notifications, endpoint-0 events, and disconnect events. - * Completion events are passed to the main thread by wakeup calls. Many - * ep0 requests are handled at interrupt time, but SetInterface, - * SetConfiguration, and device reset requests are forwarded to the - * thread in the form of "exceptions" using SIGUSR1 signals (since they - * should interrupt any ongoing file I/O operations). - * - * The thread's main routine implements the standard command/data/status - * parts of a SCSI interaction. It and its subroutines are full of tests - * for pending signals/exceptions -- all this polling is necessary since - * the kernel has no setjmp/longjmp equivalents. (Maybe this is an - * indication that the driver really wants to be running in userspace.) - * An important point is that so long as the thread is alive it keeps an - * open reference to the backing file. This will prevent unmounting - * the backing file's underlying filesystem and could cause problems - * during system shutdown, for example. To prevent such problems, the - * thread catches INT, TERM, and KILL signals and converts them into - * an EXIT exception. - * - * In normal operation the main thread is started during the gadget's - * fsg_bind() callback and stopped during fsg_unbind(). But it can also - * exit when it receives a signal, and there's no point leaving the - * gadget running when the thread is dead. So just before the thread - * exits, it deregisters the gadget driver. This makes things a little - * tricky: The driver is deregistered at two places, and the exiting - * thread can indirectly call fsg_unbind() which in turn can tell the - * thread to exit. The first problem is resolved through the use of the - * REGISTERED atomic bitflag; the driver will only be deregistered once. - * The second problem is resolved by having fsg_unbind() check - * fsg->state; it won't try to stop the thread if the state is already - * FSG_STATE_TERMINATED. - * - * To provide maximum throughput, the driver uses a circular pipeline of - * buffer heads (struct fsg_buffhd). In principle the pipeline can be - * arbitrarily long; in practice the benefits don't justify having more - * than 2 stages (i.e., double buffering). But it helps to think of the - * pipeline as being a long one. Each buffer head contains a bulk-in and - * a bulk-out request pointer (since the buffer can be used for both - * output and input -- directions always are given from the host's - * point of view) as well as a pointer to the buffer and various state - * variables. - * - * Use of the pipeline follows a simple protocol. There is a variable - * (fsg->next_buffhd_to_fill) that points to the next buffer head to use. - * At any time that buffer head may still be in use from an earlier - * request, so each buffer head has a state variable indicating whether - * it is EMPTY, FULL, or BUSY. Typical use involves waiting for the - * buffer head to be EMPTY, filling the buffer either by file I/O or by - * USB I/O (during which the buffer head is BUSY), and marking the buffer - * head FULL when the I/O is complete. Then the buffer will be emptied - * (again possibly by USB I/O, during which it is marked BUSY) and - * finally marked EMPTY again (possibly by a completion routine). - * - * A module parameter tells the driver to avoid stalling the bulk - * endpoints wherever the transport specification allows. This is - * necessary for some UDCs like the SuperH, which cannot reliably clear a - * halt on a bulk endpoint. However, under certain circumstances the - * Bulk-only specification requires a stall. In such cases the driver - * will halt the endpoint and set a flag indicating that it should clear - * the halt in software during the next device reset. Hopefully this - * will permit everything to work correctly. Furthermore, although the - * specification allows the bulk-out endpoint to halt when the host sends - * too much data, implementing this would cause an unavoidable race. - * The driver will always use the "no-stall" approach for OUT transfers. - * - * One subtle point concerns sending status-stage responses for ep0 - * requests. Some of these requests, such as device reset, can involve - * interrupting an ongoing file I/O operation, which might take an - * arbitrarily long time. During that delay the host might give up on - * the original ep0 request and issue a new one. When that happens the - * driver should not notify the host about completion of the original - * request, as the host will no longer be waiting for it. So the driver - * assigns to each ep0 request a unique tag, and it keeps track of the - * tag value of the request associated with a long-running exception - * (device-reset, interface-change, or configuration-change). When the - * exception handler is finished, the status-stage response is submitted - * only if the current ep0 request tag is equal to the exception request - * tag. Thus only the most recently received ep0 request will get a - * status-stage response. - * - * Warning: This driver source file is too long. It ought to be split up - * into a header file plus about 3 separate .c files, to handle the details - * of the Gadget, USB Mass Storage, and SCSI protocols. - */ - - -/* #define VERBOSE_DEBUG */ -/* #define DUMP_MSGS */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "gadget_chips.h" - -#define DRIVER_DESC "File-backed Storage Gadget" -#define DRIVER_NAME "g_file_storage" -#define DRIVER_VERSION "1 September 2010" - -static char fsg_string_manufacturer[64]; -static const char fsg_string_product[] = DRIVER_DESC; -static const char fsg_string_config[] = "Self-powered"; -static const char fsg_string_interface[] = "Mass Storage"; - - -#include "storage_common.c" - - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_AUTHOR("Alan Stern"); -MODULE_LICENSE("Dual BSD/GPL"); - -/* - * This driver assumes self-powered hardware and has no way for users to - * trigger remote wakeup. It uses autoconfiguration to select endpoints - * and endpoint addresses. - */ - - -/*-------------------------------------------------------------------------*/ - - -/* Encapsulate the module parameter settings */ - -static struct { - char *file[FSG_MAX_LUNS]; - char *serial; - bool ro[FSG_MAX_LUNS]; - bool nofua[FSG_MAX_LUNS]; - unsigned int num_filenames; - unsigned int num_ros; - unsigned int num_nofuas; - unsigned int nluns; - - bool removable; - bool can_stall; - bool cdrom; - - char *transport_parm; - char *protocol_parm; - unsigned short vendor; - unsigned short product; - unsigned short release; - unsigned int buflen; - - int transport_type; - char *transport_name; - int protocol_type; - char *protocol_name; - -} mod_data = { // Default values - .transport_parm = "BBB", - .protocol_parm = "SCSI", - .removable = 0, - .can_stall = 1, - .cdrom = 0, - .vendor = FSG_VENDOR_ID, - .product = FSG_PRODUCT_ID, - .release = 0xffff, // Use controller chip type - .buflen = 16384, - }; - - -module_param_array_named(file, mod_data.file, charp, &mod_data.num_filenames, - S_IRUGO); -MODULE_PARM_DESC(file, "names of backing files or devices"); - -module_param_named(serial, mod_data.serial, charp, S_IRUGO); -MODULE_PARM_DESC(serial, "USB serial number"); - -module_param_array_named(ro, mod_data.ro, bool, &mod_data.num_ros, S_IRUGO); -MODULE_PARM_DESC(ro, "true to force read-only"); - -module_param_array_named(nofua, mod_data.nofua, bool, &mod_data.num_nofuas, - S_IRUGO); -MODULE_PARM_DESC(nofua, "true to ignore SCSI WRITE(10,12) FUA bit"); - -module_param_named(luns, mod_data.nluns, uint, S_IRUGO); -MODULE_PARM_DESC(luns, "number of LUNs"); - -module_param_named(removable, mod_data.removable, bool, S_IRUGO); -MODULE_PARM_DESC(removable, "true to simulate removable media"); - -module_param_named(stall, mod_data.can_stall, bool, S_IRUGO); -MODULE_PARM_DESC(stall, "false to prevent bulk stalls"); - -module_param_named(cdrom, mod_data.cdrom, bool, S_IRUGO); -MODULE_PARM_DESC(cdrom, "true to emulate cdrom instead of disk"); - -/* In the non-TEST version, only the module parameters listed above - * are available. */ -#ifdef CONFIG_USB_FILE_STORAGE_TEST - -module_param_named(transport, mod_data.transport_parm, charp, S_IRUGO); -MODULE_PARM_DESC(transport, "type of transport (BBB, CBI, or CB)"); - -module_param_named(protocol, mod_data.protocol_parm, charp, S_IRUGO); -MODULE_PARM_DESC(protocol, "type of protocol (RBC, 8020, QIC, UFI, " - "8070, or SCSI)"); - -module_param_named(vendor, mod_data.vendor, ushort, S_IRUGO); -MODULE_PARM_DESC(vendor, "USB Vendor ID"); - -module_param_named(product, mod_data.product, ushort, S_IRUGO); -MODULE_PARM_DESC(product, "USB Product ID"); - -module_param_named(release, mod_data.release, ushort, S_IRUGO); -MODULE_PARM_DESC(release, "USB release number"); - -module_param_named(buflen, mod_data.buflen, uint, S_IRUGO); -MODULE_PARM_DESC(buflen, "I/O buffer size"); - -#endif /* CONFIG_USB_FILE_STORAGE_TEST */ - - -/* - * These definitions will permit the compiler to avoid generating code for - * parts of the driver that aren't used in the non-TEST version. Even gcc - * can recognize when a test of a constant expression yields a dead code - * path. - */ - -#ifdef CONFIG_USB_FILE_STORAGE_TEST - -#define transport_is_bbb() (mod_data.transport_type == USB_PR_BULK) -#define transport_is_cbi() (mod_data.transport_type == USB_PR_CBI) -#define protocol_is_scsi() (mod_data.protocol_type == USB_SC_SCSI) - -#else - -#define transport_is_bbb() 1 -#define transport_is_cbi() 0 -#define protocol_is_scsi() 1 - -#endif /* CONFIG_USB_FILE_STORAGE_TEST */ - - -/*-------------------------------------------------------------------------*/ - - -struct fsg_dev { - /* lock protects: state, all the req_busy's, and cbbuf_cmnd */ - spinlock_t lock; - struct usb_gadget *gadget; - - /* filesem protects: backing files in use */ - struct rw_semaphore filesem; - - /* reference counting: wait until all LUNs are released */ - struct kref ref; - - struct usb_ep *ep0; // Handy copy of gadget->ep0 - struct usb_request *ep0req; // For control responses - unsigned int ep0_req_tag; - const char *ep0req_name; - - struct usb_request *intreq; // For interrupt responses - int intreq_busy; - struct fsg_buffhd *intr_buffhd; - - unsigned int bulk_out_maxpacket; - enum fsg_state state; // For exception handling - unsigned int exception_req_tag; - - u8 config, new_config; - - unsigned int running : 1; - unsigned int bulk_in_enabled : 1; - unsigned int bulk_out_enabled : 1; - unsigned int intr_in_enabled : 1; - unsigned int phase_error : 1; - unsigned int short_packet_received : 1; - unsigned int bad_lun_okay : 1; - - unsigned long atomic_bitflags; -#define REGISTERED 0 -#define IGNORE_BULK_OUT 1 -#define SUSPENDED 2 - - struct usb_ep *bulk_in; - struct usb_ep *bulk_out; - struct usb_ep *intr_in; - - struct fsg_buffhd *next_buffhd_to_fill; - struct fsg_buffhd *next_buffhd_to_drain; - - int thread_wakeup_needed; - struct completion thread_notifier; - struct task_struct *thread_task; - - int cmnd_size; - u8 cmnd[MAX_COMMAND_SIZE]; - enum data_direction data_dir; - u32 data_size; - u32 data_size_from_cmnd; - u32 tag; - unsigned int lun; - u32 residue; - u32 usb_amount_left; - - /* The CB protocol offers no way for a host to know when a command - * has completed. As a result the next command may arrive early, - * and we will still have to handle it. For that reason we need - * a buffer to store new commands when using CB (or CBI, which - * does not oblige a host to wait for command completion either). */ - int cbbuf_cmnd_size; - u8 cbbuf_cmnd[MAX_COMMAND_SIZE]; - - unsigned int nluns; - struct fsg_lun *luns; - struct fsg_lun *curlun; - /* Must be the last entry */ - struct fsg_buffhd buffhds[]; -}; - -typedef void (*fsg_routine_t)(struct fsg_dev *); - -static int exception_in_progress(struct fsg_dev *fsg) -{ - return (fsg->state > FSG_STATE_IDLE); -} - -/* Make bulk-out requests be divisible by the maxpacket size */ -static void set_bulk_out_req_length(struct fsg_dev *fsg, - struct fsg_buffhd *bh, unsigned int length) -{ - unsigned int rem; - - bh->bulk_out_intended_length = length; - rem = length % fsg->bulk_out_maxpacket; - if (rem > 0) - length += fsg->bulk_out_maxpacket - rem; - bh->outreq->length = length; -} - -static struct fsg_dev *the_fsg; -static struct usb_gadget_driver fsg_driver; - - -/*-------------------------------------------------------------------------*/ - -static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) -{ - const char *name; - - if (ep == fsg->bulk_in) - name = "bulk-in"; - else if (ep == fsg->bulk_out) - name = "bulk-out"; - else - name = ep->name; - DBG(fsg, "%s set halt\n", name); - return usb_ep_set_halt(ep); -} - - -/*-------------------------------------------------------------------------*/ - -/* - * DESCRIPTORS ... most are static, but strings and (full) configuration - * descriptors are built on demand. Also the (static) config and interface - * descriptors are adjusted during fsg_bind(). - */ - -/* There is only one configuration. */ -#define CONFIG_VALUE 1 - -static struct usb_device_descriptor -device_desc = { - .bLength = sizeof device_desc, - .bDescriptorType = USB_DT_DEVICE, - - .bcdUSB = cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_PER_INTERFACE, - - /* The next three values can be overridden by module parameters */ - .idVendor = cpu_to_le16(FSG_VENDOR_ID), - .idProduct = cpu_to_le16(FSG_PRODUCT_ID), - .bcdDevice = cpu_to_le16(0xffff), - - .iManufacturer = FSG_STRING_MANUFACTURER, - .iProduct = FSG_STRING_PRODUCT, - .iSerialNumber = FSG_STRING_SERIAL, - .bNumConfigurations = 1, -}; - -static struct usb_config_descriptor -config_desc = { - .bLength = sizeof config_desc, - .bDescriptorType = USB_DT_CONFIG, - - /* wTotalLength computed by usb_gadget_config_buf() */ - .bNumInterfaces = 1, - .bConfigurationValue = CONFIG_VALUE, - .iConfiguration = FSG_STRING_CONFIG, - .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, - .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2, -}; - - -static struct usb_qualifier_descriptor -dev_qualifier = { - .bLength = sizeof dev_qualifier, - .bDescriptorType = USB_DT_DEVICE_QUALIFIER, - - .bcdUSB = cpu_to_le16(0x0200), - .bDeviceClass = USB_CLASS_PER_INTERFACE, - - .bNumConfigurations = 1, -}; - -static int populate_bos(struct fsg_dev *fsg, u8 *buf) -{ - memcpy(buf, &fsg_bos_desc, USB_DT_BOS_SIZE); - buf += USB_DT_BOS_SIZE; - - memcpy(buf, &fsg_ext_cap_desc, USB_DT_USB_EXT_CAP_SIZE); - buf += USB_DT_USB_EXT_CAP_SIZE; - - memcpy(buf, &fsg_ss_cap_desc, USB_DT_USB_SS_CAP_SIZE); - - return USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE - + USB_DT_USB_EXT_CAP_SIZE; -} - -/* - * Config descriptors must agree with the code that sets configurations - * and with code managing interfaces and their altsettings. They must - * also handle different speeds and other-speed requests. - */ -static int populate_config_buf(struct usb_gadget *gadget, - u8 *buf, u8 type, unsigned index) -{ - enum usb_device_speed speed = gadget->speed; - int len; - const struct usb_descriptor_header **function; - - if (index > 0) - return -EINVAL; - - if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG) - speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed; - function = gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH - ? (const struct usb_descriptor_header **)fsg_hs_function - : (const struct usb_descriptor_header **)fsg_fs_function; - - /* for now, don't advertise srp-only devices */ - if (!gadget_is_otg(gadget)) - function++; - - len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function); - ((struct usb_config_descriptor *) buf)->bDescriptorType = type; - return len; -} - - -/*-------------------------------------------------------------------------*/ - -/* These routines may be called in process context or in_irq */ - -/* Caller must hold fsg->lock */ -static void wakeup_thread(struct fsg_dev *fsg) -{ - /* Tell the main thread that something has happened */ - fsg->thread_wakeup_needed = 1; - if (fsg->thread_task) - wake_up_process(fsg->thread_task); -} - - -static void raise_exception(struct fsg_dev *fsg, enum fsg_state new_state) -{ - unsigned long flags; - - /* Do nothing if a higher-priority exception is already in progress. - * If a lower-or-equal priority exception is in progress, preempt it - * and notify the main thread by sending it a signal. */ - spin_lock_irqsave(&fsg->lock, flags); - if (fsg->state <= new_state) { - fsg->exception_req_tag = fsg->ep0_req_tag; - fsg->state = new_state; - if (fsg->thread_task) - send_sig_info(SIGUSR1, SEND_SIG_FORCED, - fsg->thread_task); - } - spin_unlock_irqrestore(&fsg->lock, flags); -} - - -/*-------------------------------------------------------------------------*/ - -/* The disconnect callback and ep0 routines. These always run in_irq, - * except that ep0_queue() is called in the main thread to acknowledge - * completion of various requests: set config, set interface, and - * Bulk-only device reset. */ - -static void fsg_disconnect(struct usb_gadget *gadget) -{ - struct fsg_dev *fsg = get_gadget_data(gadget); - - DBG(fsg, "disconnect or port reset\n"); - raise_exception(fsg, FSG_STATE_DISCONNECT); -} - - -static int ep0_queue(struct fsg_dev *fsg) -{ - int rc; - - rc = usb_ep_queue(fsg->ep0, fsg->ep0req, GFP_ATOMIC); - if (rc != 0 && rc != -ESHUTDOWN) { - - /* We can't do much more than wait for a reset */ - WARNING(fsg, "error in submission: %s --> %d\n", - fsg->ep0->name, rc); - } - return rc; -} - -static void ep0_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct fsg_dev *fsg = ep->driver_data; - - if (req->actual > 0) - dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual); - if (req->status || req->actual != req->length) - DBG(fsg, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, req->length); - if (req->status == -ECONNRESET) // Request was cancelled - usb_ep_fifo_flush(ep); - - if (req->status == 0 && req->context) - ((fsg_routine_t) (req->context))(fsg); -} - - -/*-------------------------------------------------------------------------*/ - -/* Bulk and interrupt endpoint completion handlers. - * These always run in_irq. */ - -static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct fsg_dev *fsg = ep->driver_data; - struct fsg_buffhd *bh = req->context; - - if (req->status || req->actual != req->length) - DBG(fsg, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, req->length); - if (req->status == -ECONNRESET) // Request was cancelled - usb_ep_fifo_flush(ep); - - /* Hold the lock while we update the request and buffer states */ - smp_wmb(); - spin_lock(&fsg->lock); - bh->inreq_busy = 0; - bh->state = BUF_STATE_EMPTY; - wakeup_thread(fsg); - spin_unlock(&fsg->lock); -} - -static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct fsg_dev *fsg = ep->driver_data; - struct fsg_buffhd *bh = req->context; - - dump_msg(fsg, "bulk-out", req->buf, req->actual); - if (req->status || req->actual != bh->bulk_out_intended_length) - DBG(fsg, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, - bh->bulk_out_intended_length); - if (req->status == -ECONNRESET) // Request was cancelled - usb_ep_fifo_flush(ep); - - /* Hold the lock while we update the request and buffer states */ - smp_wmb(); - spin_lock(&fsg->lock); - bh->outreq_busy = 0; - bh->state = BUF_STATE_FULL; - wakeup_thread(fsg); - spin_unlock(&fsg->lock); -} - - -#ifdef CONFIG_USB_FILE_STORAGE_TEST -static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) -{ - struct fsg_dev *fsg = ep->driver_data; - struct fsg_buffhd *bh = req->context; - - if (req->status || req->actual != req->length) - DBG(fsg, "%s --> %d, %u/%u\n", __func__, - req->status, req->actual, req->length); - if (req->status == -ECONNRESET) // Request was cancelled - usb_ep_fifo_flush(ep); - - /* Hold the lock while we update the request and buffer states */ - smp_wmb(); - spin_lock(&fsg->lock); - fsg->intreq_busy = 0; - bh->state = BUF_STATE_EMPTY; - wakeup_thread(fsg); - spin_unlock(&fsg->lock); -} - -#else -static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) -{} -#endif /* CONFIG_USB_FILE_STORAGE_TEST */ - - -/*-------------------------------------------------------------------------*/ - -/* Ep0 class-specific handlers. These always run in_irq. */ - -#ifdef CONFIG_USB_FILE_STORAGE_TEST -static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) -{ - struct usb_request *req = fsg->ep0req; - static u8 cbi_reset_cmnd[6] = { - SEND_DIAGNOSTIC, 4, 0xff, 0xff, 0xff, 0xff}; - - /* Error in command transfer? */ - if (req->status || req->length != req->actual || - req->actual < 6 || req->actual > MAX_COMMAND_SIZE) { - - /* Not all controllers allow a protocol stall after - * receiving control-out data, but we'll try anyway. */ - fsg_set_halt(fsg, fsg->ep0); - return; // Wait for reset - } - - /* Is it the special reset command? */ - if (req->actual >= sizeof cbi_reset_cmnd && - memcmp(req->buf, cbi_reset_cmnd, - sizeof cbi_reset_cmnd) == 0) { - - /* Raise an exception to stop the current operation - * and reinitialize our state. */ - DBG(fsg, "cbi reset request\n"); - raise_exception(fsg, FSG_STATE_RESET); - return; - } - - VDBG(fsg, "CB[I] accept device-specific command\n"); - spin_lock(&fsg->lock); - - /* Save the command for later */ - if (fsg->cbbuf_cmnd_size) - WARNING(fsg, "CB[I] overwriting previous command\n"); - fsg->cbbuf_cmnd_size = req->actual; - memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); - - wakeup_thread(fsg); - spin_unlock(&fsg->lock); -} - -#else -static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) -{} -#endif /* CONFIG_USB_FILE_STORAGE_TEST */ - - -static int class_setup_req(struct fsg_dev *fsg, - const struct usb_ctrlrequest *ctrl) -{ - struct usb_request *req = fsg->ep0req; - int value = -EOPNOTSUPP; - u16 w_index = le16_to_cpu(ctrl->wIndex); - u16 w_value = le16_to_cpu(ctrl->wValue); - u16 w_length = le16_to_cpu(ctrl->wLength); - - if (!fsg->config) - return value; - - /* Handle Bulk-only class-specific requests */ - if (transport_is_bbb()) { - switch (ctrl->bRequest) { - - case US_BULK_RESET_REQUEST: - if (ctrl->bRequestType != (USB_DIR_OUT | - USB_TYPE_CLASS | USB_RECIP_INTERFACE)) - break; - if (w_index != 0 || w_value != 0 || w_length != 0) { - value = -EDOM; - break; - } - - /* Raise an exception to stop the current operation - * and reinitialize our state. */ - DBG(fsg, "bulk reset request\n"); - raise_exception(fsg, FSG_STATE_RESET); - value = DELAYED_STATUS; - break; - - case US_BULK_GET_MAX_LUN: - if (ctrl->bRequestType != (USB_DIR_IN | - USB_TYPE_CLASS | USB_RECIP_INTERFACE)) - break; - if (w_index != 0 || w_value != 0 || w_length != 1) { - value = -EDOM; - break; - } - VDBG(fsg, "get max LUN\n"); - *(u8 *) req->buf = fsg->nluns - 1; - value = 1; - break; - } - } - - /* Handle CBI class-specific requests */ - else { - switch (ctrl->bRequest) { - - case USB_CBI_ADSC_REQUEST: - if (ctrl->bRequestType != (USB_DIR_OUT | - USB_TYPE_CLASS | USB_RECIP_INTERFACE)) - break; - if (w_index != 0 || w_value != 0) { - value = -EDOM; - break; - } - if (w_length > MAX_COMMAND_SIZE) { - value = -EOVERFLOW; - break; - } - value = w_length; - fsg->ep0req->context = received_cbi_adsc; - break; - } - } - - if (value == -EOPNOTSUPP) - VDBG(fsg, - "unknown class-specific control req " - "%02x.%02x v%04x i%04x l%u\n", - ctrl->bRequestType, ctrl->bRequest, - le16_to_cpu(ctrl->wValue), w_index, w_length); - return value; -} - - -/*-------------------------------------------------------------------------*/ - -/* Ep0 standard request handlers. These always run in_irq. */ - -static int standard_setup_req(struct fsg_dev *fsg, - const struct usb_ctrlrequest *ctrl) -{ - struct usb_request *req = fsg->ep0req; - int value = -EOPNOTSUPP; - u16 w_index = le16_to_cpu(ctrl->wIndex); - u16 w_value = le16_to_cpu(ctrl->wValue); - - /* Usually this just stores reply data in the pre-allocated ep0 buffer, - * but config change events will also reconfigure hardware. */ - switch (ctrl->bRequest) { - - case USB_REQ_GET_DESCRIPTOR: - if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | - USB_RECIP_DEVICE)) - break; - switch (w_value >> 8) { - - case USB_DT_DEVICE: - VDBG(fsg, "get device descriptor\n"); - device_desc.bMaxPacketSize0 = fsg->ep0->maxpacket; - value = sizeof device_desc; - memcpy(req->buf, &device_desc, value); - break; - case USB_DT_DEVICE_QUALIFIER: - VDBG(fsg, "get device qualifier\n"); - if (!gadget_is_dualspeed(fsg->gadget) || - fsg->gadget->speed == USB_SPEED_SUPER) - break; - /* - * Assume ep0 uses the same maxpacket value for both - * speeds - */ - dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; - value = sizeof dev_qualifier; - memcpy(req->buf, &dev_qualifier, value); - break; - - case USB_DT_OTHER_SPEED_CONFIG: - VDBG(fsg, "get other-speed config descriptor\n"); - if (!gadget_is_dualspeed(fsg->gadget) || - fsg->gadget->speed == USB_SPEED_SUPER) - break; - goto get_config; - case USB_DT_CONFIG: - VDBG(fsg, "get configuration descriptor\n"); -get_config: - value = populate_config_buf(fsg->gadget, - req->buf, - w_value >> 8, - w_value & 0xff); - break; - - case USB_DT_STRING: - VDBG(fsg, "get string descriptor\n"); - - /* wIndex == language code */ - value = usb_gadget_get_string(&fsg_stringtab, - w_value & 0xff, req->buf); - break; - - case USB_DT_BOS: - VDBG(fsg, "get bos descriptor\n"); - - if (gadget_is_superspeed(fsg->gadget)) - value = populate_bos(fsg, req->buf); - break; - } - - break; - - /* One config, two speeds */ - case USB_REQ_SET_CONFIGURATION: - if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | - USB_RECIP_DEVICE)) - break; - VDBG(fsg, "set configuration\n"); - if (w_value == CONFIG_VALUE || w_value == 0) { - fsg->new_config = w_value; - - /* Raise an exception to wipe out previous transaction - * state (queued bufs, etc) and set the new config. */ - raise_exception(fsg, FSG_STATE_CONFIG_CHANGE); - value = DELAYED_STATUS; - } - break; - case USB_REQ_GET_CONFIGURATION: - if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | - USB_RECIP_DEVICE)) - break; - VDBG(fsg, "get configuration\n"); - *(u8 *) req->buf = fsg->config; - value = 1; - break; - - case USB_REQ_SET_INTERFACE: - if (ctrl->bRequestType != (USB_DIR_OUT| USB_TYPE_STANDARD | - USB_RECIP_INTERFACE)) - break; - if (fsg->config && w_index == 0) { - - /* Raise an exception to wipe out previous transaction - * state (queued bufs, etc) and install the new - * interface altsetting. */ - raise_exception(fsg, FSG_STATE_INTERFACE_CHANGE); - value = DELAYED_STATUS; - } - break; - case USB_REQ_GET_INTERFACE: - if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_STANDARD | - USB_RECIP_INTERFACE)) - break; - if (!fsg->config) - break; - if (w_index != 0) { - value = -EDOM; - break; - } - VDBG(fsg, "get interface\n"); - *(u8 *) req->buf = 0; - value = 1; - break; - - default: - VDBG(fsg, - "unknown control req %02x.%02x v%04x i%04x l%u\n", - ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, le16_to_cpu(ctrl->wLength)); - } - - return value; -} - - -static int fsg_setup(struct usb_gadget *gadget, - const struct usb_ctrlrequest *ctrl) -{ - struct fsg_dev *fsg = get_gadget_data(gadget); - int rc; - int w_length = le16_to_cpu(ctrl->wLength); - - ++fsg->ep0_req_tag; // Record arrival of a new request - fsg->ep0req->context = NULL; - fsg->ep0req->length = 0; - dump_msg(fsg, "ep0-setup", (u8 *) ctrl, sizeof(*ctrl)); - - if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) - rc = class_setup_req(fsg, ctrl); - else - rc = standard_setup_req(fsg, ctrl); - - /* Respond with data/status or defer until later? */ - if (rc >= 0 && rc != DELAYED_STATUS) { - rc = min(rc, w_length); - fsg->ep0req->length = rc; - fsg->ep0req->zero = rc < w_length; - fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ? - "ep0-in" : "ep0-out"); - rc = ep0_queue(fsg); - } - - /* Device either stalls (rc < 0) or reports success */ - return rc; -} - - -/*-------------------------------------------------------------------------*/ - -/* All the following routines run in process context */ - - -/* Use this for bulk or interrupt transfers, not ep0 */ -static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, - struct usb_request *req, int *pbusy, - enum fsg_buffer_state *state) -{ - int rc; - - if (ep == fsg->bulk_in) - dump_msg(fsg, "bulk-in", req->buf, req->length); - else if (ep == fsg->intr_in) - dump_msg(fsg, "intr-in", req->buf, req->length); - - spin_lock_irq(&fsg->lock); - *pbusy = 1; - *state = BUF_STATE_BUSY; - spin_unlock_irq(&fsg->lock); - rc = usb_ep_queue(ep, req, GFP_KERNEL); - if (rc != 0) { - *pbusy = 0; - *state = BUF_STATE_EMPTY; - - /* We can't do much more than wait for a reset */ - - /* Note: currently the net2280 driver fails zero-length - * submissions if DMA is enabled. */ - if (rc != -ESHUTDOWN && !(rc == -EOPNOTSUPP && - req->length == 0)) - WARNING(fsg, "error in submission: %s --> %d\n", - ep->name, rc); - } -} - - -static int sleep_thread(struct fsg_dev *fsg) -{ - int rc = 0; - - /* Wait until a signal arrives or we are woken up */ - for (;;) { - try_to_freeze(); - set_current_state(TASK_INTERRUPTIBLE); - if (signal_pending(current)) { - rc = -EINTR; - break; - } - if (fsg->thread_wakeup_needed) - break; - schedule(); - } - __set_current_state(TASK_RUNNING); - fsg->thread_wakeup_needed = 0; - return rc; -} - - -/*-------------------------------------------------------------------------*/ - -static int do_read(struct fsg_dev *fsg) -{ - struct fsg_lun *curlun = fsg->curlun; - u32 lba; - struct fsg_buffhd *bh; - int rc; - u32 amount_left; - loff_t file_offset, file_offset_tmp; - unsigned int amount; - ssize_t nread; - - /* Get the starting Logical Block Address and check that it's - * not too big */ - if (fsg->cmnd[0] == READ_6) - lba = get_unaligned_be24(&fsg->cmnd[1]); - else { - lba = get_unaligned_be32(&fsg->cmnd[2]); - - /* We allow DPO (Disable Page Out = don't save data in the - * cache) and FUA (Force Unit Access = don't read from the - * cache), but we don't implement them. */ - if ((fsg->cmnd[1] & ~0x18) != 0) { - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - } - if (lba >= curlun->num_sectors) { - curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - return -EINVAL; - } - file_offset = ((loff_t) lba) << curlun->blkbits; - - /* Carry out the file reads */ - amount_left = fsg->data_size_from_cmnd; - if (unlikely(amount_left == 0)) - return -EIO; // No default reply - - for (;;) { - - /* Figure out how much we need to read: - * Try to read the remaining amount. - * But don't read more than the buffer size. - * And don't try to read past the end of the file. - */ - amount = min((unsigned int) amount_left, mod_data.buflen); - amount = min((loff_t) amount, - curlun->file_length - file_offset); - - /* Wait for the next buffer to become available */ - bh = fsg->next_buffhd_to_fill; - while (bh->state != BUF_STATE_EMPTY) { - rc = sleep_thread(fsg); - if (rc) - return rc; - } - - /* If we were asked to read past the end of file, - * end with an empty buffer. */ - if (amount == 0) { - curlun->sense_data = - SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - curlun->sense_data_info = file_offset >> curlun->blkbits; - curlun->info_valid = 1; - bh->inreq->length = 0; - bh->state = BUF_STATE_FULL; - break; - } - - /* Perform the read */ - file_offset_tmp = file_offset; - nread = vfs_read(curlun->filp, - (char __user *) bh->buf, - amount, &file_offset_tmp); - VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, - (unsigned long long) file_offset, - (int) nread); - if (signal_pending(current)) - return -EINTR; - - if (nread < 0) { - LDBG(curlun, "error in file read: %d\n", - (int) nread); - nread = 0; - } else if (nread < amount) { - LDBG(curlun, "partial file read: %d/%u\n", - (int) nread, amount); - nread = round_down(nread, curlun->blksize); - } - file_offset += nread; - amount_left -= nread; - fsg->residue -= nread; - - /* Except at the end of the transfer, nread will be - * equal to the buffer size, which is divisible by the - * bulk-in maxpacket size. - */ - bh->inreq->length = nread; - bh->state = BUF_STATE_FULL; - - /* If an error occurred, report it and its position */ - if (nread < amount) { - curlun->sense_data = SS_UNRECOVERED_READ_ERROR; - curlun->sense_data_info = file_offset >> curlun->blkbits; - curlun->info_valid = 1; - break; - } - - if (amount_left == 0) - break; // No more left to read - - /* Send this buffer and go read some more */ - bh->inreq->zero = 0; - start_transfer(fsg, fsg->bulk_in, bh->inreq, - &bh->inreq_busy, &bh->state); - fsg->next_buffhd_to_fill = bh->next; - } - - return -EIO; // No default reply -} - - -/*-------------------------------------------------------------------------*/ - -static int do_write(struct fsg_dev *fsg) -{ - struct fsg_lun *curlun = fsg->curlun; - u32 lba; - struct fsg_buffhd *bh; - int get_some_more; - u32 amount_left_to_req, amount_left_to_write; - loff_t usb_offset, file_offset, file_offset_tmp; - unsigned int amount; - ssize_t nwritten; - int rc; - - if (curlun->ro) { - curlun->sense_data = SS_WRITE_PROTECTED; - return -EINVAL; - } - spin_lock(&curlun->filp->f_lock); - curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait - spin_unlock(&curlun->filp->f_lock); - - /* Get the starting Logical Block Address and check that it's - * not too big */ - if (fsg->cmnd[0] == WRITE_6) - lba = get_unaligned_be24(&fsg->cmnd[1]); - else { - lba = get_unaligned_be32(&fsg->cmnd[2]); - - /* We allow DPO (Disable Page Out = don't save data in the - * cache) and FUA (Force Unit Access = write directly to the - * medium). We don't implement DPO; we implement FUA by - * performing synchronous output. */ - if ((fsg->cmnd[1] & ~0x18) != 0) { - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - /* FUA */ - if (!curlun->nofua && (fsg->cmnd[1] & 0x08)) { - spin_lock(&curlun->filp->f_lock); - curlun->filp->f_flags |= O_DSYNC; - spin_unlock(&curlun->filp->f_lock); - } - } - if (lba >= curlun->num_sectors) { - curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - return -EINVAL; - } - - /* Carry out the file writes */ - get_some_more = 1; - file_offset = usb_offset = ((loff_t) lba) << curlun->blkbits; - amount_left_to_req = amount_left_to_write = fsg->data_size_from_cmnd; - - while (amount_left_to_write > 0) { - - /* Queue a request for more data from the host */ - bh = fsg->next_buffhd_to_fill; - if (bh->state == BUF_STATE_EMPTY && get_some_more) { - - /* Figure out how much we want to get: - * Try to get the remaining amount, - * but not more than the buffer size. - */ - amount = min(amount_left_to_req, mod_data.buflen); - - /* Beyond the end of the backing file? */ - if (usb_offset >= curlun->file_length) { - get_some_more = 0; - curlun->sense_data = - SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - curlun->sense_data_info = usb_offset >> curlun->blkbits; - curlun->info_valid = 1; - continue; - } - - /* Get the next buffer */ - usb_offset += amount; - fsg->usb_amount_left -= amount; - amount_left_to_req -= amount; - if (amount_left_to_req == 0) - get_some_more = 0; - - /* Except at the end of the transfer, amount will be - * equal to the buffer size, which is divisible by - * the bulk-out maxpacket size. - */ - set_bulk_out_req_length(fsg, bh, amount); - start_transfer(fsg, fsg->bulk_out, bh->outreq, - &bh->outreq_busy, &bh->state); - fsg->next_buffhd_to_fill = bh->next; - continue; - } - - /* Write the received data to the backing file */ - bh = fsg->next_buffhd_to_drain; - if (bh->state == BUF_STATE_EMPTY && !get_some_more) - break; // We stopped early - if (bh->state == BUF_STATE_FULL) { - smp_rmb(); - fsg->next_buffhd_to_drain = bh->next; - bh->state = BUF_STATE_EMPTY; - - /* Did something go wrong with the transfer? */ - if (bh->outreq->status != 0) { - curlun->sense_data = SS_COMMUNICATION_FAILURE; - curlun->sense_data_info = file_offset >> curlun->blkbits; - curlun->info_valid = 1; - break; - } - - amount = bh->outreq->actual; - if (curlun->file_length - file_offset < amount) { - LERROR(curlun, - "write %u @ %llu beyond end %llu\n", - amount, (unsigned long long) file_offset, - (unsigned long long) curlun->file_length); - amount = curlun->file_length - file_offset; - } - - /* Don't accept excess data. The spec doesn't say - * what to do in this case. We'll ignore the error. - */ - amount = min(amount, bh->bulk_out_intended_length); - - /* Don't write a partial block */ - amount = round_down(amount, curlun->blksize); - if (amount == 0) - goto empty_write; - - /* Perform the write */ - file_offset_tmp = file_offset; - nwritten = vfs_write(curlun->filp, - (char __user *) bh->buf, - amount, &file_offset_tmp); - VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, - (unsigned long long) file_offset, - (int) nwritten); - if (signal_pending(current)) - return -EINTR; // Interrupted! - - if (nwritten < 0) { - LDBG(curlun, "error in file write: %d\n", - (int) nwritten); - nwritten = 0; - } else if (nwritten < amount) { - LDBG(curlun, "partial file write: %d/%u\n", - (int) nwritten, amount); - nwritten = round_down(nwritten, curlun->blksize); - } - file_offset += nwritten; - amount_left_to_write -= nwritten; - fsg->residue -= nwritten; - - /* If an error occurred, report it and its position */ - if (nwritten < amount) { - curlun->sense_data = SS_WRITE_ERROR; - curlun->sense_data_info = file_offset >> curlun->blkbits; - curlun->info_valid = 1; - break; - } - - empty_write: - /* Did the host decide to stop early? */ - if (bh->outreq->actual < bh->bulk_out_intended_length) { - fsg->short_packet_received = 1; - break; - } - continue; - } - - /* Wait for something to happen */ - rc = sleep_thread(fsg); - if (rc) - return rc; - } - - return -EIO; // No default reply -} - - -/*-------------------------------------------------------------------------*/ - -static int do_synchronize_cache(struct fsg_dev *fsg) -{ - struct fsg_lun *curlun = fsg->curlun; - int rc; - - /* We ignore the requested LBA and write out all file's - * dirty data buffers. */ - rc = fsg_lun_fsync_sub(curlun); - if (rc) - curlun->sense_data = SS_WRITE_ERROR; - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -static void invalidate_sub(struct fsg_lun *curlun) -{ - struct file *filp = curlun->filp; - struct inode *inode = filp->f_path.dentry->d_inode; - unsigned long rc; - - rc = invalidate_mapping_pages(inode->i_mapping, 0, -1); - VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc); -} - -static int do_verify(struct fsg_dev *fsg) -{ - struct fsg_lun *curlun = fsg->curlun; - u32 lba; - u32 verification_length; - struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; - loff_t file_offset, file_offset_tmp; - u32 amount_left; - unsigned int amount; - ssize_t nread; - - /* Get the starting Logical Block Address and check that it's - * not too big */ - lba = get_unaligned_be32(&fsg->cmnd[2]); - if (lba >= curlun->num_sectors) { - curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - return -EINVAL; - } - - /* We allow DPO (Disable Page Out = don't save data in the - * cache) but we don't implement it. */ - if ((fsg->cmnd[1] & ~0x10) != 0) { - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - - verification_length = get_unaligned_be16(&fsg->cmnd[7]); - if (unlikely(verification_length == 0)) - return -EIO; // No default reply - - /* Prepare to carry out the file verify */ - amount_left = verification_length << curlun->blkbits; - file_offset = ((loff_t) lba) << curlun->blkbits; - - /* Write out all the dirty buffers before invalidating them */ - fsg_lun_fsync_sub(curlun); - if (signal_pending(current)) - return -EINTR; - - invalidate_sub(curlun); - if (signal_pending(current)) - return -EINTR; - - /* Just try to read the requested blocks */ - while (amount_left > 0) { - - /* Figure out how much we need to read: - * Try to read the remaining amount, but not more than - * the buffer size. - * And don't try to read past the end of the file. - */ - amount = min((unsigned int) amount_left, mod_data.buflen); - amount = min((loff_t) amount, - curlun->file_length - file_offset); - if (amount == 0) { - curlun->sense_data = - SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - curlun->sense_data_info = file_offset >> curlun->blkbits; - curlun->info_valid = 1; - break; - } - - /* Perform the read */ - file_offset_tmp = file_offset; - nread = vfs_read(curlun->filp, - (char __user *) bh->buf, - amount, &file_offset_tmp); - VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, - (unsigned long long) file_offset, - (int) nread); - if (signal_pending(current)) - return -EINTR; - - if (nread < 0) { - LDBG(curlun, "error in file verify: %d\n", - (int) nread); - nread = 0; - } else if (nread < amount) { - LDBG(curlun, "partial file verify: %d/%u\n", - (int) nread, amount); - nread = round_down(nread, curlun->blksize); - } - if (nread == 0) { - curlun->sense_data = SS_UNRECOVERED_READ_ERROR; - curlun->sense_data_info = file_offset >> curlun->blkbits; - curlun->info_valid = 1; - break; - } - file_offset += nread; - amount_left -= nread; - } - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -static int do_inquiry(struct fsg_dev *fsg, struct fsg_buffhd *bh) -{ - u8 *buf = (u8 *) bh->buf; - - static char vendor_id[] = "Linux "; - static char product_disk_id[] = "File-Stor Gadget"; - static char product_cdrom_id[] = "File-CD Gadget "; - - if (!fsg->curlun) { // Unsupported LUNs are okay - fsg->bad_lun_okay = 1; - memset(buf, 0, 36); - buf[0] = 0x7f; // Unsupported, no device-type - buf[4] = 31; // Additional length - return 36; - } - - memset(buf, 0, 8); - buf[0] = (mod_data.cdrom ? TYPE_ROM : TYPE_DISK); - if (mod_data.removable) - buf[1] = 0x80; - buf[2] = 2; // ANSI SCSI level 2 - buf[3] = 2; // SCSI-2 INQUIRY data format - buf[4] = 31; // Additional length - // No special options - sprintf(buf + 8, "%-8s%-16s%04x", vendor_id, - (mod_data.cdrom ? product_cdrom_id : - product_disk_id), - mod_data.release); - return 36; -} - - -static int do_request_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = fsg->curlun; - u8 *buf = (u8 *) bh->buf; - u32 sd, sdinfo; - int valid; - - /* - * From the SCSI-2 spec., section 7.9 (Unit attention condition): - * - * If a REQUEST SENSE command is received from an initiator - * with a pending unit attention condition (before the target - * generates the contingent allegiance condition), then the - * target shall either: - * a) report any pending sense data and preserve the unit - * attention condition on the logical unit, or, - * b) report the unit attention condition, may discard any - * pending sense data, and clear the unit attention - * condition on the logical unit for that initiator. - * - * FSG normally uses option a); enable this code to use option b). - */ -#if 0 - if (curlun && curlun->unit_attention_data != SS_NO_SENSE) { - curlun->sense_data = curlun->unit_attention_data; - curlun->unit_attention_data = SS_NO_SENSE; - } -#endif - - if (!curlun) { // Unsupported LUNs are okay - fsg->bad_lun_okay = 1; - sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; - sdinfo = 0; - valid = 0; - } else { - sd = curlun->sense_data; - sdinfo = curlun->sense_data_info; - valid = curlun->info_valid << 7; - curlun->sense_data = SS_NO_SENSE; - curlun->sense_data_info = 0; - curlun->info_valid = 0; - } - - memset(buf, 0, 18); - buf[0] = valid | 0x70; // Valid, current error - buf[2] = SK(sd); - put_unaligned_be32(sdinfo, &buf[3]); /* Sense information */ - buf[7] = 18 - 8; // Additional sense length - buf[12] = ASC(sd); - buf[13] = ASCQ(sd); - return 18; -} - - -static int do_read_capacity(struct fsg_dev *fsg, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = fsg->curlun; - u32 lba = get_unaligned_be32(&fsg->cmnd[2]); - int pmi = fsg->cmnd[8]; - u8 *buf = (u8 *) bh->buf; - - /* Check the PMI and LBA fields */ - if (pmi > 1 || (pmi == 0 && lba != 0)) { - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - - put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); - /* Max logical block */ - put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */ - return 8; -} - - -static int do_read_header(struct fsg_dev *fsg, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = fsg->curlun; - int msf = fsg->cmnd[1] & 0x02; - u32 lba = get_unaligned_be32(&fsg->cmnd[2]); - u8 *buf = (u8 *) bh->buf; - - if ((fsg->cmnd[1] & ~0x02) != 0) { /* Mask away MSF */ - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - if (lba >= curlun->num_sectors) { - curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; - return -EINVAL; - } - - memset(buf, 0, 8); - buf[0] = 0x01; /* 2048 bytes of user data, rest is EC */ - store_cdrom_address(&buf[4], msf, lba); - return 8; -} - - -static int do_read_toc(struct fsg_dev *fsg, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = fsg->curlun; - int msf = fsg->cmnd[1] & 0x02; - int start_track = fsg->cmnd[6]; - u8 *buf = (u8 *) bh->buf; - - if ((fsg->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */ - start_track > 1) { - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - - memset(buf, 0, 20); - buf[1] = (20-2); /* TOC data length */ - buf[2] = 1; /* First track number */ - buf[3] = 1; /* Last track number */ - buf[5] = 0x16; /* Data track, copying allowed */ - buf[6] = 0x01; /* Only track is number 1 */ - store_cdrom_address(&buf[8], msf, 0); - - buf[13] = 0x16; /* Lead-out track is data */ - buf[14] = 0xAA; /* Lead-out track number */ - store_cdrom_address(&buf[16], msf, curlun->num_sectors); - return 20; -} - - -static int do_mode_sense(struct fsg_dev *fsg, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = fsg->curlun; - int mscmnd = fsg->cmnd[0]; - u8 *buf = (u8 *) bh->buf; - u8 *buf0 = buf; - int pc, page_code; - int changeable_values, all_pages; - int valid_page = 0; - int len, limit; - - if ((fsg->cmnd[1] & ~0x08) != 0) { // Mask away DBD - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - pc = fsg->cmnd[2] >> 6; - page_code = fsg->cmnd[2] & 0x3f; - if (pc == 3) { - curlun->sense_data = SS_SAVING_PARAMETERS_NOT_SUPPORTED; - return -EINVAL; - } - changeable_values = (pc == 1); - all_pages = (page_code == 0x3f); - - /* Write the mode parameter header. Fixed values are: default - * medium type, no cache control (DPOFUA), and no block descriptors. - * The only variable value is the WriteProtect bit. We will fill in - * the mode data length later. */ - memset(buf, 0, 8); - if (mscmnd == MODE_SENSE) { - buf[2] = (curlun->ro ? 0x80 : 0x00); // WP, DPOFUA - buf += 4; - limit = 255; - } else { // MODE_SENSE_10 - buf[3] = (curlun->ro ? 0x80 : 0x00); // WP, DPOFUA - buf += 8; - limit = 65535; // Should really be mod_data.buflen - } - - /* No block descriptors */ - - /* The mode pages, in numerical order. The only page we support - * is the Caching page. */ - if (page_code == 0x08 || all_pages) { - valid_page = 1; - buf[0] = 0x08; // Page code - buf[1] = 10; // Page length - memset(buf+2, 0, 10); // None of the fields are changeable - - if (!changeable_values) { - buf[2] = 0x04; // Write cache enable, - // Read cache not disabled - // No cache retention priorities - put_unaligned_be16(0xffff, &buf[4]); - /* Don't disable prefetch */ - /* Minimum prefetch = 0 */ - put_unaligned_be16(0xffff, &buf[8]); - /* Maximum prefetch */ - put_unaligned_be16(0xffff, &buf[10]); - /* Maximum prefetch ceiling */ - } - buf += 12; - } - - /* Check that a valid page was requested and the mode data length - * isn't too long. */ - len = buf - buf0; - if (!valid_page || len > limit) { - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - - /* Store the mode data length */ - if (mscmnd == MODE_SENSE) - buf0[0] = len - 1; - else - put_unaligned_be16(len - 2, buf0); - return len; -} - - -static int do_start_stop(struct fsg_dev *fsg) -{ - struct fsg_lun *curlun = fsg->curlun; - int loej, start; - - if (!mod_data.removable) { - curlun->sense_data = SS_INVALID_COMMAND; - return -EINVAL; - } - - // int immed = fsg->cmnd[1] & 0x01; - loej = fsg->cmnd[4] & 0x02; - start = fsg->cmnd[4] & 0x01; - -#ifdef CONFIG_USB_FILE_STORAGE_TEST - if ((fsg->cmnd[1] & ~0x01) != 0 || // Mask away Immed - (fsg->cmnd[4] & ~0x03) != 0) { // Mask LoEj, Start - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - - if (!start) { - - /* Are we allowed to unload the media? */ - if (curlun->prevent_medium_removal) { - LDBG(curlun, "unload attempt prevented\n"); - curlun->sense_data = SS_MEDIUM_REMOVAL_PREVENTED; - return -EINVAL; - } - if (loej) { // Simulate an unload/eject - up_read(&fsg->filesem); - down_write(&fsg->filesem); - fsg_lun_close(curlun); - up_write(&fsg->filesem); - down_read(&fsg->filesem); - } - } else { - - /* Our emulation doesn't support mounting; the medium is - * available for use as soon as it is loaded. */ - if (!fsg_lun_is_open(curlun)) { - curlun->sense_data = SS_MEDIUM_NOT_PRESENT; - return -EINVAL; - } - } -#endif - return 0; -} - - -static int do_prevent_allow(struct fsg_dev *fsg) -{ - struct fsg_lun *curlun = fsg->curlun; - int prevent; - - if (!mod_data.removable) { - curlun->sense_data = SS_INVALID_COMMAND; - return -EINVAL; - } - - prevent = fsg->cmnd[4] & 0x01; - if ((fsg->cmnd[4] & ~0x01) != 0) { // Mask away Prevent - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - - if (curlun->prevent_medium_removal && !prevent) - fsg_lun_fsync_sub(curlun); - curlun->prevent_medium_removal = prevent; - return 0; -} - - -static int do_read_format_capacities(struct fsg_dev *fsg, - struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = fsg->curlun; - u8 *buf = (u8 *) bh->buf; - - buf[0] = buf[1] = buf[2] = 0; - buf[3] = 8; // Only the Current/Maximum Capacity Descriptor - buf += 4; - - put_unaligned_be32(curlun->num_sectors, &buf[0]); - /* Number of blocks */ - put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */ - buf[4] = 0x02; /* Current capacity */ - return 12; -} - - -static int do_mode_select(struct fsg_dev *fsg, struct fsg_buffhd *bh) -{ - struct fsg_lun *curlun = fsg->curlun; - - /* We don't support MODE SELECT */ - curlun->sense_data = SS_INVALID_COMMAND; - return -EINVAL; -} - - -/*-------------------------------------------------------------------------*/ - -static int halt_bulk_in_endpoint(struct fsg_dev *fsg) -{ - int rc; - - rc = fsg_set_halt(fsg, fsg->bulk_in); - if (rc == -EAGAIN) - VDBG(fsg, "delayed bulk-in endpoint halt\n"); - while (rc != 0) { - if (rc != -EAGAIN) { - WARNING(fsg, "usb_ep_set_halt -> %d\n", rc); - rc = 0; - break; - } - - /* Wait for a short time and then try again */ - if (msleep_interruptible(100) != 0) - return -EINTR; - rc = usb_ep_set_halt(fsg->bulk_in); - } - return rc; -} - -static int wedge_bulk_in_endpoint(struct fsg_dev *fsg) -{ - int rc; - - DBG(fsg, "bulk-in set wedge\n"); - rc = usb_ep_set_wedge(fsg->bulk_in); - if (rc == -EAGAIN) - VDBG(fsg, "delayed bulk-in endpoint wedge\n"); - while (rc != 0) { - if (rc != -EAGAIN) { - WARNING(fsg, "usb_ep_set_wedge -> %d\n", rc); - rc = 0; - break; - } - - /* Wait for a short time and then try again */ - if (msleep_interruptible(100) != 0) - return -EINTR; - rc = usb_ep_set_wedge(fsg->bulk_in); - } - return rc; -} - -static int throw_away_data(struct fsg_dev *fsg) -{ - struct fsg_buffhd *bh; - u32 amount; - int rc; - - while ((bh = fsg->next_buffhd_to_drain)->state != BUF_STATE_EMPTY || - fsg->usb_amount_left > 0) { - - /* Throw away the data in a filled buffer */ - if (bh->state == BUF_STATE_FULL) { - smp_rmb(); - bh->state = BUF_STATE_EMPTY; - fsg->next_buffhd_to_drain = bh->next; - - /* A short packet or an error ends everything */ - if (bh->outreq->actual < bh->bulk_out_intended_length || - bh->outreq->status != 0) { - raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); - return -EINTR; - } - continue; - } - - /* Try to submit another request if we need one */ - bh = fsg->next_buffhd_to_fill; - if (bh->state == BUF_STATE_EMPTY && fsg->usb_amount_left > 0) { - amount = min(fsg->usb_amount_left, - (u32) mod_data.buflen); - - /* Except at the end of the transfer, amount will be - * equal to the buffer size, which is divisible by - * the bulk-out maxpacket size. - */ - set_bulk_out_req_length(fsg, bh, amount); - start_transfer(fsg, fsg->bulk_out, bh->outreq, - &bh->outreq_busy, &bh->state); - fsg->next_buffhd_to_fill = bh->next; - fsg->usb_amount_left -= amount; - continue; - } - - /* Otherwise wait for something to happen */ - rc = sleep_thread(fsg); - if (rc) - return rc; - } - return 0; -} - - -static int finish_reply(struct fsg_dev *fsg) -{ - struct fsg_buffhd *bh = fsg->next_buffhd_to_fill; - int rc = 0; - - switch (fsg->data_dir) { - case DATA_DIR_NONE: - break; // Nothing to send - - /* If we don't know whether the host wants to read or write, - * this must be CB or CBI with an unknown command. We mustn't - * try to send or receive any data. So stall both bulk pipes - * if we can and wait for a reset. */ - case DATA_DIR_UNKNOWN: - if (mod_data.can_stall) { - fsg_set_halt(fsg, fsg->bulk_out); - rc = halt_bulk_in_endpoint(fsg); - } - break; - - /* All but the last buffer of data must have already been sent */ - case DATA_DIR_TO_HOST: - if (fsg->data_size == 0) - ; // Nothing to send - - /* If there's no residue, simply send the last buffer */ - else if (fsg->residue == 0) { - bh->inreq->zero = 0; - start_transfer(fsg, fsg->bulk_in, bh->inreq, - &bh->inreq_busy, &bh->state); - fsg->next_buffhd_to_fill = bh->next; - } - - /* There is a residue. For CB and CBI, simply mark the end - * of the data with a short packet. However, if we are - * allowed to stall, there was no data at all (residue == - * data_size), and the command failed (invalid LUN or - * sense data is set), then halt the bulk-in endpoint - * instead. */ - else if (!transport_is_bbb()) { - if (mod_data.can_stall && - fsg->residue == fsg->data_size && - (!fsg->curlun || fsg->curlun->sense_data != SS_NO_SENSE)) { - bh->state = BUF_STATE_EMPTY; - rc = halt_bulk_in_endpoint(fsg); - } else { - bh->inreq->zero = 1; - start_transfer(fsg, fsg->bulk_in, bh->inreq, - &bh->inreq_busy, &bh->state); - fsg->next_buffhd_to_fill = bh->next; - } - } - - /* - * For Bulk-only, mark the end of the data with a short - * packet. If we are allowed to stall, halt the bulk-in - * endpoint. (Note: This violates the Bulk-Only Transport - * specification, which requires us to pad the data if we - * don't halt the endpoint. Presumably nobody will mind.) - */ - else { - bh->inreq->zero = 1; - start_transfer(fsg, fsg->bulk_in, bh->inreq, - &bh->inreq_busy, &bh->state); - fsg->next_buffhd_to_fill = bh->next; - if (mod_data.can_stall) - rc = halt_bulk_in_endpoint(fsg); - } - break; - - /* We have processed all we want from the data the host has sent. - * There may still be outstanding bulk-out requests. */ - case DATA_DIR_FROM_HOST: - if (fsg->residue == 0) - ; // Nothing to receive - - /* Did the host stop sending unexpectedly early? */ - else if (fsg->short_packet_received) { - raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); - rc = -EINTR; - } - - /* We haven't processed all the incoming data. Even though - * we may be allowed to stall, doing so would cause a race. - * The controller may already have ACK'ed all the remaining - * bulk-out packets, in which case the host wouldn't see a - * STALL. Not realizing the endpoint was halted, it wouldn't - * clear the halt -- leading to problems later on. */ -#if 0 - else if (mod_data.can_stall) { - fsg_set_halt(fsg, fsg->bulk_out); - raise_exception(fsg, FSG_STATE_ABORT_BULK_OUT); - rc = -EINTR; - } -#endif - - /* We can't stall. Read in the excess data and throw it - * all away. */ - else - rc = throw_away_data(fsg); - break; - } - return rc; -} - - -static int send_status(struct fsg_dev *fsg) -{ - struct fsg_lun *curlun = fsg->curlun; - struct fsg_buffhd *bh; - int rc; - u8 status = US_BULK_STAT_OK; - u32 sd, sdinfo = 0; - - /* Wait for the next buffer to become available */ - bh = fsg->next_buffhd_to_fill; - while (bh->state != BUF_STATE_EMPTY) { - rc = sleep_thread(fsg); - if (rc) - return rc; - } - - if (curlun) { - sd = curlun->sense_data; - sdinfo = curlun->sense_data_info; - } else if (fsg->bad_lun_okay) - sd = SS_NO_SENSE; - else - sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; - - if (fsg->phase_error) { - DBG(fsg, "sending phase-error status\n"); - status = US_BULK_STAT_PHASE; - sd = SS_INVALID_COMMAND; - } else if (sd != SS_NO_SENSE) { - DBG(fsg, "sending command-failure status\n"); - status = US_BULK_STAT_FAIL; - VDBG(fsg, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;" - " info x%x\n", - SK(sd), ASC(sd), ASCQ(sd), sdinfo); - } - - if (transport_is_bbb()) { - struct bulk_cs_wrap *csw = bh->buf; - - /* Store and send the Bulk-only CSW */ - csw->Signature = cpu_to_le32(US_BULK_CS_SIGN); - csw->Tag = fsg->tag; - csw->Residue = cpu_to_le32(fsg->residue); - csw->Status = status; - - bh->inreq->length = US_BULK_CS_WRAP_LEN; - bh->inreq->zero = 0; - start_transfer(fsg, fsg->bulk_in, bh->inreq, - &bh->inreq_busy, &bh->state); - - } else if (mod_data.transport_type == USB_PR_CB) { - - /* Control-Bulk transport has no status phase! */ - return 0; - - } else { // USB_PR_CBI - struct interrupt_data *buf = bh->buf; - - /* Store and send the Interrupt data. UFI sends the ASC - * and ASCQ bytes. Everything else sends a Type (which - * is always 0) and the status Value. */ - if (mod_data.protocol_type == USB_SC_UFI) { - buf->bType = ASC(sd); - buf->bValue = ASCQ(sd); - } else { - buf->bType = 0; - buf->bValue = status; - } - fsg->intreq->length = CBI_INTERRUPT_DATA_LEN; - - fsg->intr_buffhd = bh; // Point to the right buffhd - fsg->intreq->buf = bh->inreq->buf; - fsg->intreq->context = bh; - start_transfer(fsg, fsg->intr_in, fsg->intreq, - &fsg->intreq_busy, &bh->state); - } - - fsg->next_buffhd_to_fill = bh->next; - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -/* Check whether the command is properly formed and whether its data size - * and direction agree with the values we already have. */ -static int check_command(struct fsg_dev *fsg, int cmnd_size, - enum data_direction data_dir, unsigned int mask, - int needs_medium, const char *name) -{ - int i; - int lun = fsg->cmnd[1] >> 5; - static const char dirletter[4] = {'u', 'o', 'i', 'n'}; - char hdlen[20]; - struct fsg_lun *curlun; - - /* Adjust the expected cmnd_size for protocol encapsulation padding. - * Transparent SCSI doesn't pad. */ - if (protocol_is_scsi()) - ; - - /* There's some disagreement as to whether RBC pads commands or not. - * We'll play it safe and accept either form. */ - else if (mod_data.protocol_type == USB_SC_RBC) { - if (fsg->cmnd_size == 12) - cmnd_size = 12; - - /* All the other protocols pad to 12 bytes */ - } else - cmnd_size = 12; - - hdlen[0] = 0; - if (fsg->data_dir != DATA_DIR_UNKNOWN) - sprintf(hdlen, ", H%c=%u", dirletter[(int) fsg->data_dir], - fsg->data_size); - VDBG(fsg, "SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n", - name, cmnd_size, dirletter[(int) data_dir], - fsg->data_size_from_cmnd, fsg->cmnd_size, hdlen); - - /* We can't reply at all until we know the correct data direction - * and size. */ - if (fsg->data_size_from_cmnd == 0) - data_dir = DATA_DIR_NONE; - if (fsg->data_dir == DATA_DIR_UNKNOWN) { // CB or CBI - fsg->data_dir = data_dir; - fsg->data_size = fsg->data_size_from_cmnd; - - } else { // Bulk-only - if (fsg->data_size < fsg->data_size_from_cmnd) { - - /* Host data size < Device data size is a phase error. - * Carry out the command, but only transfer as much - * as we are allowed. */ - fsg->data_size_from_cmnd = fsg->data_size; - fsg->phase_error = 1; - } - } - fsg->residue = fsg->usb_amount_left = fsg->data_size; - - /* Conflicting data directions is a phase error */ - if (fsg->data_dir != data_dir && fsg->data_size_from_cmnd > 0) { - fsg->phase_error = 1; - return -EINVAL; - } - - /* Verify the length of the command itself */ - if (cmnd_size != fsg->cmnd_size) { - - /* Special case workaround: There are plenty of buggy SCSI - * implementations. Many have issues with cbw->Length - * field passing a wrong command size. For those cases we - * always try to work around the problem by using the length - * sent by the host side provided it is at least as large - * as the correct command length. - * Examples of such cases would be MS-Windows, which issues - * REQUEST SENSE with cbw->Length == 12 where it should - * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and - * REQUEST SENSE with cbw->Length == 10 where it should - * be 6 as well. - */ - if (cmnd_size <= fsg->cmnd_size) { - DBG(fsg, "%s is buggy! Expected length %d " - "but we got %d\n", name, - cmnd_size, fsg->cmnd_size); - cmnd_size = fsg->cmnd_size; - } else { - fsg->phase_error = 1; - return -EINVAL; - } - } - - /* Check that the LUN values are consistent */ - if (transport_is_bbb()) { - if (fsg->lun != lun) - DBG(fsg, "using LUN %d from CBW, " - "not LUN %d from CDB\n", - fsg->lun, lun); - } - - /* Check the LUN */ - curlun = fsg->curlun; - if (curlun) { - if (fsg->cmnd[0] != REQUEST_SENSE) { - curlun->sense_data = SS_NO_SENSE; - curlun->sense_data_info = 0; - curlun->info_valid = 0; - } - } else { - fsg->bad_lun_okay = 0; - - /* INQUIRY and REQUEST SENSE commands are explicitly allowed - * to use unsupported LUNs; all others may not. */ - if (fsg->cmnd[0] != INQUIRY && - fsg->cmnd[0] != REQUEST_SENSE) { - DBG(fsg, "unsupported LUN %d\n", fsg->lun); - return -EINVAL; - } - } - - /* If a unit attention condition exists, only INQUIRY and - * REQUEST SENSE commands are allowed; anything else must fail. */ - if (curlun && curlun->unit_attention_data != SS_NO_SENSE && - fsg->cmnd[0] != INQUIRY && - fsg->cmnd[0] != REQUEST_SENSE) { - curlun->sense_data = curlun->unit_attention_data; - curlun->unit_attention_data = SS_NO_SENSE; - return -EINVAL; - } - - /* Check that only command bytes listed in the mask are non-zero */ - fsg->cmnd[1] &= 0x1f; // Mask away the LUN - for (i = 1; i < cmnd_size; ++i) { - if (fsg->cmnd[i] && !(mask & (1 << i))) { - if (curlun) - curlun->sense_data = SS_INVALID_FIELD_IN_CDB; - return -EINVAL; - } - } - - /* If the medium isn't mounted and the command needs to access - * it, return an error. */ - if (curlun && !fsg_lun_is_open(curlun) && needs_medium) { - curlun->sense_data = SS_MEDIUM_NOT_PRESENT; - return -EINVAL; - } - - return 0; -} - -/* wrapper of check_command for data size in blocks handling */ -static int check_command_size_in_blocks(struct fsg_dev *fsg, int cmnd_size, - enum data_direction data_dir, unsigned int mask, - int needs_medium, const char *name) -{ - if (fsg->curlun) - fsg->data_size_from_cmnd <<= fsg->curlun->blkbits; - return check_command(fsg, cmnd_size, data_dir, - mask, needs_medium, name); -} - -static int do_scsi_command(struct fsg_dev *fsg) -{ - struct fsg_buffhd *bh; - int rc; - int reply = -EINVAL; - int i; - static char unknown[16]; - - dump_cdb(fsg); - - /* Wait for the next buffer to become available for data or status */ - bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill; - while (bh->state != BUF_STATE_EMPTY) { - rc = sleep_thread(fsg); - if (rc) - return rc; - } - fsg->phase_error = 0; - fsg->short_packet_received = 0; - - down_read(&fsg->filesem); // We're using the backing file - switch (fsg->cmnd[0]) { - - case INQUIRY: - fsg->data_size_from_cmnd = fsg->cmnd[4]; - if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, - (1<<4), 0, - "INQUIRY")) == 0) - reply = do_inquiry(fsg, bh); - break; - - case MODE_SELECT: - fsg->data_size_from_cmnd = fsg->cmnd[4]; - if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, - (1<<1) | (1<<4), 0, - "MODE SELECT(6)")) == 0) - reply = do_mode_select(fsg, bh); - break; - - case MODE_SELECT_10: - fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); - if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, - (1<<1) | (3<<7), 0, - "MODE SELECT(10)")) == 0) - reply = do_mode_select(fsg, bh); - break; - - case MODE_SENSE: - fsg->data_size_from_cmnd = fsg->cmnd[4]; - if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, - (1<<1) | (1<<2) | (1<<4), 0, - "MODE SENSE(6)")) == 0) - reply = do_mode_sense(fsg, bh); - break; - - case MODE_SENSE_10: - fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); - if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, - (1<<1) | (1<<2) | (3<<7), 0, - "MODE SENSE(10)")) == 0) - reply = do_mode_sense(fsg, bh); - break; - - case ALLOW_MEDIUM_REMOVAL: - fsg->data_size_from_cmnd = 0; - if ((reply = check_command(fsg, 6, DATA_DIR_NONE, - (1<<4), 0, - "PREVENT-ALLOW MEDIUM REMOVAL")) == 0) - reply = do_prevent_allow(fsg); - break; - - case READ_6: - i = fsg->cmnd[4]; - fsg->data_size_from_cmnd = (i == 0) ? 256 : i; - if ((reply = check_command_size_in_blocks(fsg, 6, - DATA_DIR_TO_HOST, - (7<<1) | (1<<4), 1, - "READ(6)")) == 0) - reply = do_read(fsg); - break; - - case READ_10: - fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); - if ((reply = check_command_size_in_blocks(fsg, 10, - DATA_DIR_TO_HOST, - (1<<1) | (0xf<<2) | (3<<7), 1, - "READ(10)")) == 0) - reply = do_read(fsg); - break; - - case READ_12: - fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]); - if ((reply = check_command_size_in_blocks(fsg, 12, - DATA_DIR_TO_HOST, - (1<<1) | (0xf<<2) | (0xf<<6), 1, - "READ(12)")) == 0) - reply = do_read(fsg); - break; - - case READ_CAPACITY: - fsg->data_size_from_cmnd = 8; - if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, - (0xf<<2) | (1<<8), 1, - "READ CAPACITY")) == 0) - reply = do_read_capacity(fsg, bh); - break; - - case READ_HEADER: - if (!mod_data.cdrom) - goto unknown_cmnd; - fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); - if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, - (3<<7) | (0x1f<<1), 1, - "READ HEADER")) == 0) - reply = do_read_header(fsg, bh); - break; - - case READ_TOC: - if (!mod_data.cdrom) - goto unknown_cmnd; - fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); - if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, - (7<<6) | (1<<1), 1, - "READ TOC")) == 0) - reply = do_read_toc(fsg, bh); - break; - - case READ_FORMAT_CAPACITIES: - fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); - if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, - (3<<7), 1, - "READ FORMAT CAPACITIES")) == 0) - reply = do_read_format_capacities(fsg, bh); - break; - - case REQUEST_SENSE: - fsg->data_size_from_cmnd = fsg->cmnd[4]; - if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, - (1<<4), 0, - "REQUEST SENSE")) == 0) - reply = do_request_sense(fsg, bh); - break; - - case START_STOP: - fsg->data_size_from_cmnd = 0; - if ((reply = check_command(fsg, 6, DATA_DIR_NONE, - (1<<1) | (1<<4), 0, - "START-STOP UNIT")) == 0) - reply = do_start_stop(fsg); - break; - - case SYNCHRONIZE_CACHE: - fsg->data_size_from_cmnd = 0; - if ((reply = check_command(fsg, 10, DATA_DIR_NONE, - (0xf<<2) | (3<<7), 1, - "SYNCHRONIZE CACHE")) == 0) - reply = do_synchronize_cache(fsg); - break; - - case TEST_UNIT_READY: - fsg->data_size_from_cmnd = 0; - reply = check_command(fsg, 6, DATA_DIR_NONE, - 0, 1, - "TEST UNIT READY"); - break; - - /* Although optional, this command is used by MS-Windows. We - * support a minimal version: BytChk must be 0. */ - case VERIFY: - fsg->data_size_from_cmnd = 0; - if ((reply = check_command(fsg, 10, DATA_DIR_NONE, - (1<<1) | (0xf<<2) | (3<<7), 1, - "VERIFY")) == 0) - reply = do_verify(fsg); - break; - - case WRITE_6: - i = fsg->cmnd[4]; - fsg->data_size_from_cmnd = (i == 0) ? 256 : i; - if ((reply = check_command_size_in_blocks(fsg, 6, - DATA_DIR_FROM_HOST, - (7<<1) | (1<<4), 1, - "WRITE(6)")) == 0) - reply = do_write(fsg); - break; - - case WRITE_10: - fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); - if ((reply = check_command_size_in_blocks(fsg, 10, - DATA_DIR_FROM_HOST, - (1<<1) | (0xf<<2) | (3<<7), 1, - "WRITE(10)")) == 0) - reply = do_write(fsg); - break; - - case WRITE_12: - fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]); - if ((reply = check_command_size_in_blocks(fsg, 12, - DATA_DIR_FROM_HOST, - (1<<1) | (0xf<<2) | (0xf<<6), 1, - "WRITE(12)")) == 0) - reply = do_write(fsg); - break; - - /* Some mandatory commands that we recognize but don't implement. - * They don't mean much in this setting. It's left as an exercise - * for anyone interested to implement RESERVE and RELEASE in terms - * of Posix locks. */ - case FORMAT_UNIT: - case RELEASE: - case RESERVE: - case SEND_DIAGNOSTIC: - // Fall through - - default: - unknown_cmnd: - fsg->data_size_from_cmnd = 0; - sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]); - if ((reply = check_command(fsg, fsg->cmnd_size, - DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) { - fsg->curlun->sense_data = SS_INVALID_COMMAND; - reply = -EINVAL; - } - break; - } - up_read(&fsg->filesem); - - if (reply == -EINTR || signal_pending(current)) - return -EINTR; - - /* Set up the single reply buffer for finish_reply() */ - if (reply == -EINVAL) - reply = 0; // Error reply length - if (reply >= 0 && fsg->data_dir == DATA_DIR_TO_HOST) { - reply = min((u32) reply, fsg->data_size_from_cmnd); - bh->inreq->length = reply; - bh->state = BUF_STATE_FULL; - fsg->residue -= reply; - } // Otherwise it's already set - - return 0; -} - - -/*-------------------------------------------------------------------------*/ - -static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) -{ - struct usb_request *req = bh->outreq; - struct bulk_cb_wrap *cbw = req->buf; - - /* Was this a real packet? Should it be ignored? */ - if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags)) - return -EINVAL; - - /* Is the CBW valid? */ - if (req->actual != US_BULK_CB_WRAP_LEN || - cbw->Signature != cpu_to_le32( - US_BULK_CB_SIGN)) { - DBG(fsg, "invalid CBW: len %u sig 0x%x\n", - req->actual, - le32_to_cpu(cbw->Signature)); - - /* The Bulk-only spec says we MUST stall the IN endpoint - * (6.6.1), so it's unavoidable. It also says we must - * retain this state until the next reset, but there's - * no way to tell the controller driver it should ignore - * Clear-Feature(HALT) requests. - * - * We aren't required to halt the OUT endpoint; instead - * we can simply accept and discard any data received - * until the next reset. */ - wedge_bulk_in_endpoint(fsg); - set_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); - return -EINVAL; - } - - /* Is the CBW meaningful? */ - if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~US_BULK_FLAG_IN || - cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) { - DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " - "cmdlen %u\n", - cbw->Lun, cbw->Flags, cbw->Length); - - /* We can do anything we want here, so let's stall the - * bulk pipes if we are allowed to. */ - if (mod_data.can_stall) { - fsg_set_halt(fsg, fsg->bulk_out); - halt_bulk_in_endpoint(fsg); - } - return -EINVAL; - } - - /* Save the command for later */ - fsg->cmnd_size = cbw->Length; - memcpy(fsg->cmnd, cbw->CDB, fsg->cmnd_size); - if (cbw->Flags & US_BULK_FLAG_IN) - fsg->data_dir = DATA_DIR_TO_HOST; - else - fsg->data_dir = DATA_DIR_FROM_HOST; - fsg->data_size = le32_to_cpu(cbw->DataTransferLength); - if (fsg->data_size == 0) - fsg->data_dir = DATA_DIR_NONE; - fsg->lun = cbw->Lun; - fsg->tag = cbw->Tag; - return 0; -} - - -static int get_next_command(struct fsg_dev *fsg) -{ - struct fsg_buffhd *bh; - int rc = 0; - - if (transport_is_bbb()) { - - /* Wait for the next buffer to become available */ - bh = fsg->next_buffhd_to_fill; - while (bh->state != BUF_STATE_EMPTY) { - rc = sleep_thread(fsg); - if (rc) - return rc; - } - - /* Queue a request to read a Bulk-only CBW */ - set_bulk_out_req_length(fsg, bh, US_BULK_CB_WRAP_LEN); - start_transfer(fsg, fsg->bulk_out, bh->outreq, - &bh->outreq_busy, &bh->state); - - /* We will drain the buffer in software, which means we - * can reuse it for the next filling. No need to advance - * next_buffhd_to_fill. */ - - /* Wait for the CBW to arrive */ - while (bh->state != BUF_STATE_FULL) { - rc = sleep_thread(fsg); - if (rc) - return rc; - } - smp_rmb(); - rc = received_cbw(fsg, bh); - bh->state = BUF_STATE_EMPTY; - - } else { // USB_PR_CB or USB_PR_CBI - - /* Wait for the next command to arrive */ - while (fsg->cbbuf_cmnd_size == 0) { - rc = sleep_thread(fsg); - if (rc) - return rc; - } - - /* Is the previous status interrupt request still busy? - * The host is allowed to skip reading the status, - * so we must cancel it. */ - if (fsg->intreq_busy) - usb_ep_dequeue(fsg->intr_in, fsg->intreq); - - /* Copy the command and mark the buffer empty */ - fsg->data_dir = DATA_DIR_UNKNOWN; - spin_lock_irq(&fsg->lock); - fsg->cmnd_size = fsg->cbbuf_cmnd_size; - memcpy(fsg->cmnd, fsg->cbbuf_cmnd, fsg->cmnd_size); - fsg->cbbuf_cmnd_size = 0; - spin_unlock_irq(&fsg->lock); - - /* Use LUN from the command */ - fsg->lun = fsg->cmnd[1] >> 5; - } - - /* Update current lun */ - if (fsg->lun >= 0 && fsg->lun < fsg->nluns) - fsg->curlun = &fsg->luns[fsg->lun]; - else - fsg->curlun = NULL; - - return rc; -} - - -/*-------------------------------------------------------------------------*/ - -static int enable_endpoint(struct fsg_dev *fsg, struct usb_ep *ep, - const struct usb_endpoint_descriptor *d) -{ - int rc; - - ep->driver_data = fsg; - ep->desc = d; - rc = usb_ep_enable(ep); - if (rc) - ERROR(fsg, "can't enable %s, result %d\n", ep->name, rc); - return rc; -} - -static int alloc_request(struct fsg_dev *fsg, struct usb_ep *ep, - struct usb_request **preq) -{ - *preq = usb_ep_alloc_request(ep, GFP_ATOMIC); - if (*preq) - return 0; - ERROR(fsg, "can't allocate request for %s\n", ep->name); - return -ENOMEM; -} - -/* - * Reset interface setting and re-init endpoint state (toggle etc). - * Call with altsetting < 0 to disable the interface. The only other - * available altsetting is 0, which enables the interface. - */ -static int do_set_interface(struct fsg_dev *fsg, int altsetting) -{ - int rc = 0; - int i; - const struct usb_endpoint_descriptor *d; - - if (fsg->running) - DBG(fsg, "reset interface\n"); - -reset: - /* Deallocate the requests */ - for (i = 0; i < fsg_num_buffers; ++i) { - struct fsg_buffhd *bh = &fsg->buffhds[i]; - - if (bh->inreq) { - usb_ep_free_request(fsg->bulk_in, bh->inreq); - bh->inreq = NULL; - } - if (bh->outreq) { - usb_ep_free_request(fsg->bulk_out, bh->outreq); - bh->outreq = NULL; - } - } - if (fsg->intreq) { - usb_ep_free_request(fsg->intr_in, fsg->intreq); - fsg->intreq = NULL; - } - - /* Disable the endpoints */ - if (fsg->bulk_in_enabled) { - usb_ep_disable(fsg->bulk_in); - fsg->bulk_in_enabled = 0; - } - if (fsg->bulk_out_enabled) { - usb_ep_disable(fsg->bulk_out); - fsg->bulk_out_enabled = 0; - } - if (fsg->intr_in_enabled) { - usb_ep_disable(fsg->intr_in); - fsg->intr_in_enabled = 0; - } - - fsg->running = 0; - if (altsetting < 0 || rc != 0) - return rc; - - DBG(fsg, "set interface %d\n", altsetting); - - /* Enable the endpoints */ - d = fsg_ep_desc(fsg->gadget, - &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc, - &fsg_ss_bulk_in_desc); - if ((rc = enable_endpoint(fsg, fsg->bulk_in, d)) != 0) - goto reset; - fsg->bulk_in_enabled = 1; - - d = fsg_ep_desc(fsg->gadget, - &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc, - &fsg_ss_bulk_out_desc); - if ((rc = enable_endpoint(fsg, fsg->bulk_out, d)) != 0) - goto reset; - fsg->bulk_out_enabled = 1; - fsg->bulk_out_maxpacket = usb_endpoint_maxp(d); - clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); - - if (transport_is_cbi()) { - d = fsg_ep_desc(fsg->gadget, - &fsg_fs_intr_in_desc, &fsg_hs_intr_in_desc, - &fsg_ss_intr_in_desc); - if ((rc = enable_endpoint(fsg, fsg->intr_in, d)) != 0) - goto reset; - fsg->intr_in_enabled = 1; - } - - /* Allocate the requests */ - for (i = 0; i < fsg_num_buffers; ++i) { - struct fsg_buffhd *bh = &fsg->buffhds[i]; - - if ((rc = alloc_request(fsg, fsg->bulk_in, &bh->inreq)) != 0) - goto reset; - if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0) - goto reset; - bh->inreq->buf = bh->outreq->buf = bh->buf; - bh->inreq->context = bh->outreq->context = bh; - bh->inreq->complete = bulk_in_complete; - bh->outreq->complete = bulk_out_complete; - } - if (transport_is_cbi()) { - if ((rc = alloc_request(fsg, fsg->intr_in, &fsg->intreq)) != 0) - goto reset; - fsg->intreq->complete = intr_in_complete; - } - - fsg->running = 1; - for (i = 0; i < fsg->nluns; ++i) - fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED; - return rc; -} - - -/* - * Change our operational configuration. This code must agree with the code - * that returns config descriptors, and with interface altsetting code. - * - * It's also responsible for power management interactions. Some - * configurations might not work with our current power sources. - * For now we just assume the gadget is always self-powered. - */ -static int do_set_config(struct fsg_dev *fsg, u8 new_config) -{ - int rc = 0; - - /* Disable the single interface */ - if (fsg->config != 0) { - DBG(fsg, "reset config\n"); - fsg->config = 0; - rc = do_set_interface(fsg, -1); - } - - /* Enable the interface */ - if (new_config != 0) { - fsg->config = new_config; - if ((rc = do_set_interface(fsg, 0)) != 0) - fsg->config = 0; // Reset on errors - else - INFO(fsg, "%s config #%d\n", - usb_speed_string(fsg->gadget->speed), - fsg->config); - } - return rc; -} - - -/*-------------------------------------------------------------------------*/ - -static void handle_exception(struct fsg_dev *fsg) -{ - siginfo_t info; - int sig; - int i; - int num_active; - struct fsg_buffhd *bh; - enum fsg_state old_state; - u8 new_config; - struct fsg_lun *curlun; - unsigned int exception_req_tag; - int rc; - - /* Clear the existing signals. Anything but SIGUSR1 is converted - * into a high-priority EXIT exception. */ - for (;;) { - sig = dequeue_signal_lock(current, ¤t->blocked, &info); - if (!sig) - break; - if (sig != SIGUSR1) { - if (fsg->state < FSG_STATE_EXIT) - DBG(fsg, "Main thread exiting on signal\n"); - raise_exception(fsg, FSG_STATE_EXIT); - } - } - - /* Cancel all the pending transfers */ - if (fsg->intreq_busy) - usb_ep_dequeue(fsg->intr_in, fsg->intreq); - for (i = 0; i < fsg_num_buffers; ++i) { - bh = &fsg->buffhds[i]; - if (bh->inreq_busy) - usb_ep_dequeue(fsg->bulk_in, bh->inreq); - if (bh->outreq_busy) - usb_ep_dequeue(fsg->bulk_out, bh->outreq); - } - - /* Wait until everything is idle */ - for (;;) { - num_active = fsg->intreq_busy; - for (i = 0; i < fsg_num_buffers; ++i) { - bh = &fsg->buffhds[i]; - num_active += bh->inreq_busy + bh->outreq_busy; - } - if (num_active == 0) - break; - if (sleep_thread(fsg)) - return; - } - - /* Clear out the controller's fifos */ - if (fsg->bulk_in_enabled) - usb_ep_fifo_flush(fsg->bulk_in); - if (fsg->bulk_out_enabled) - usb_ep_fifo_flush(fsg->bulk_out); - if (fsg->intr_in_enabled) - usb_ep_fifo_flush(fsg->intr_in); - - /* Reset the I/O buffer states and pointers, the SCSI - * state, and the exception. Then invoke the handler. */ - spin_lock_irq(&fsg->lock); - - for (i = 0; i < fsg_num_buffers; ++i) { - bh = &fsg->buffhds[i]; - bh->state = BUF_STATE_EMPTY; - } - fsg->next_buffhd_to_fill = fsg->next_buffhd_to_drain = - &fsg->buffhds[0]; - - exception_req_tag = fsg->exception_req_tag; - new_config = fsg->new_config; - old_state = fsg->state; - - if (old_state == FSG_STATE_ABORT_BULK_OUT) - fsg->state = FSG_STATE_STATUS_PHASE; - else { - for (i = 0; i < fsg->nluns; ++i) { - curlun = &fsg->luns[i]; - curlun->prevent_medium_removal = 0; - curlun->sense_data = curlun->unit_attention_data = - SS_NO_SENSE; - curlun->sense_data_info = 0; - curlun->info_valid = 0; - } - fsg->state = FSG_STATE_IDLE; - } - spin_unlock_irq(&fsg->lock); - - /* Carry out any extra actions required for the exception */ - switch (old_state) { - default: - break; - - case FSG_STATE_ABORT_BULK_OUT: - send_status(fsg); - spin_lock_irq(&fsg->lock); - if (fsg->state == FSG_STATE_STATUS_PHASE) - fsg->state = FSG_STATE_IDLE; - spin_unlock_irq(&fsg->lock); - break; - - case FSG_STATE_RESET: - /* In case we were forced against our will to halt a - * bulk endpoint, clear the halt now. (The SuperH UDC - * requires this.) */ - if (test_and_clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags)) - usb_ep_clear_halt(fsg->bulk_in); - - if (transport_is_bbb()) { - if (fsg->ep0_req_tag == exception_req_tag) - ep0_queue(fsg); // Complete the status stage - - } else if (transport_is_cbi()) - send_status(fsg); // Status by interrupt pipe - - /* Technically this should go here, but it would only be - * a waste of time. Ditto for the INTERFACE_CHANGE and - * CONFIG_CHANGE cases. */ - // for (i = 0; i < fsg->nluns; ++i) - // fsg->luns[i].unit_attention_data = SS_RESET_OCCURRED; - break; - - case FSG_STATE_INTERFACE_CHANGE: - rc = do_set_interface(fsg, 0); - if (fsg->ep0_req_tag != exception_req_tag) - break; - if (rc != 0) // STALL on errors - fsg_set_halt(fsg, fsg->ep0); - else // Complete the status stage - ep0_queue(fsg); - break; - - case FSG_STATE_CONFIG_CHANGE: - rc = do_set_config(fsg, new_config); - if (fsg->ep0_req_tag != exception_req_tag) - break; - if (rc != 0) // STALL on errors - fsg_set_halt(fsg, fsg->ep0); - else // Complete the status stage - ep0_queue(fsg); - break; - - case FSG_STATE_DISCONNECT: - for (i = 0; i < fsg->nluns; ++i) - fsg_lun_fsync_sub(fsg->luns + i); - do_set_config(fsg, 0); // Unconfigured state - break; - - case FSG_STATE_EXIT: - case FSG_STATE_TERMINATED: - do_set_config(fsg, 0); // Free resources - spin_lock_irq(&fsg->lock); - fsg->state = FSG_STATE_TERMINATED; // Stop the thread - spin_unlock_irq(&fsg->lock); - break; - } -} - - -/*-------------------------------------------------------------------------*/ - -static int fsg_main_thread(void *fsg_) -{ - struct fsg_dev *fsg = fsg_; - - /* Allow the thread to be killed by a signal, but set the signal mask - * to block everything but INT, TERM, KILL, and USR1. */ - allow_signal(SIGINT); - allow_signal(SIGTERM); - allow_signal(SIGKILL); - allow_signal(SIGUSR1); - - /* Allow the thread to be frozen */ - set_freezable(); - - /* Arrange for userspace references to be interpreted as kernel - * pointers. That way we can pass a kernel pointer to a routine - * that expects a __user pointer and it will work okay. */ - set_fs(get_ds()); - - /* The main loop */ - while (fsg->state != FSG_STATE_TERMINATED) { - if (exception_in_progress(fsg) || signal_pending(current)) { - handle_exception(fsg); - continue; - } - - if (!fsg->running) { - sleep_thread(fsg); - continue; - } - - if (get_next_command(fsg)) - continue; - - spin_lock_irq(&fsg->lock); - if (!exception_in_progress(fsg)) - fsg->state = FSG_STATE_DATA_PHASE; - spin_unlock_irq(&fsg->lock); - - if (do_scsi_command(fsg) || finish_reply(fsg)) - continue; - - spin_lock_irq(&fsg->lock); - if (!exception_in_progress(fsg)) - fsg->state = FSG_STATE_STATUS_PHASE; - spin_unlock_irq(&fsg->lock); - - if (send_status(fsg)) - continue; - - spin_lock_irq(&fsg->lock); - if (!exception_in_progress(fsg)) - fsg->state = FSG_STATE_IDLE; - spin_unlock_irq(&fsg->lock); - } - - spin_lock_irq(&fsg->lock); - fsg->thread_task = NULL; - spin_unlock_irq(&fsg->lock); - - /* If we are exiting because of a signal, unregister the - * gadget driver. */ - if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) - usb_gadget_unregister_driver(&fsg_driver); - - /* Let the unbind and cleanup routines know the thread has exited */ - complete_and_exit(&fsg->thread_notifier, 0); -} - - -/*-------------------------------------------------------------------------*/ - - -/* The write permissions and store_xxx pointers are set in fsg_bind() */ -static DEVICE_ATTR(ro, 0444, fsg_show_ro, NULL); -static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, NULL); -static DEVICE_ATTR(file, 0444, fsg_show_file, NULL); - - -/*-------------------------------------------------------------------------*/ - -static void fsg_release(struct kref *ref) -{ - struct fsg_dev *fsg = container_of(ref, struct fsg_dev, ref); - - kfree(fsg->luns); - kfree(fsg); -} - -static void lun_release(struct device *dev) -{ - struct rw_semaphore *filesem = dev_get_drvdata(dev); - struct fsg_dev *fsg = - container_of(filesem, struct fsg_dev, filesem); - - kref_put(&fsg->ref, fsg_release); -} - -static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget) -{ - struct fsg_dev *fsg = get_gadget_data(gadget); - int i; - struct fsg_lun *curlun; - struct usb_request *req = fsg->ep0req; - - DBG(fsg, "unbind\n"); - clear_bit(REGISTERED, &fsg->atomic_bitflags); - - /* If the thread isn't already dead, tell it to exit now */ - if (fsg->state != FSG_STATE_TERMINATED) { - raise_exception(fsg, FSG_STATE_EXIT); - wait_for_completion(&fsg->thread_notifier); - - /* The cleanup routine waits for this completion also */ - complete(&fsg->thread_notifier); - } - - /* Unregister the sysfs attribute files and the LUNs */ - for (i = 0; i < fsg->nluns; ++i) { - curlun = &fsg->luns[i]; - if (curlun->registered) { - device_remove_file(&curlun->dev, &dev_attr_nofua); - device_remove_file(&curlun->dev, &dev_attr_ro); - device_remove_file(&curlun->dev, &dev_attr_file); - fsg_lun_close(curlun); - device_unregister(&curlun->dev); - curlun->registered = 0; - } - } - - /* Free the data buffers */ - for (i = 0; i < fsg_num_buffers; ++i) - kfree(fsg->buffhds[i].buf); - - /* Free the request and buffer for endpoint 0 */ - if (req) { - kfree(req->buf); - usb_ep_free_request(fsg->ep0, req); - } - - set_gadget_data(gadget, NULL); -} - - -static int __init check_parameters(struct fsg_dev *fsg) -{ - int prot; - - /* Store the default values */ - mod_data.transport_type = USB_PR_BULK; - mod_data.transport_name = "Bulk-only"; - mod_data.protocol_type = USB_SC_SCSI; - mod_data.protocol_name = "Transparent SCSI"; - - /* Some peripheral controllers are known not to be able to - * halt bulk endpoints correctly. If one of them is present, - * disable stalls. - */ - if (gadget_is_at91(fsg->gadget)) - mod_data.can_stall = 0; - - if (mod_data.release == 0xffff) - mod_data.release = get_default_bcdDevice(); - - prot = simple_strtol(mod_data.protocol_parm, NULL, 0); - -#ifdef CONFIG_USB_FILE_STORAGE_TEST - if (strnicmp(mod_data.transport_parm, "BBB", 10) == 0) { - ; // Use default setting - } else if (strnicmp(mod_data.transport_parm, "CB", 10) == 0) { - mod_data.transport_type = USB_PR_CB; - mod_data.transport_name = "Control-Bulk"; - } else if (strnicmp(mod_data.transport_parm, "CBI", 10) == 0) { - mod_data.transport_type = USB_PR_CBI; - mod_data.transport_name = "Control-Bulk-Interrupt"; - } else { - ERROR(fsg, "invalid transport: %s\n", mod_data.transport_parm); - return -EINVAL; - } - - if (strnicmp(mod_data.protocol_parm, "SCSI", 10) == 0 || - prot == USB_SC_SCSI) { - ; // Use default setting - } else if (strnicmp(mod_data.protocol_parm, "RBC", 10) == 0 || - prot == USB_SC_RBC) { - mod_data.protocol_type = USB_SC_RBC; - mod_data.protocol_name = "RBC"; - } else if (strnicmp(mod_data.protocol_parm, "8020", 4) == 0 || - strnicmp(mod_data.protocol_parm, "ATAPI", 10) == 0 || - prot == USB_SC_8020) { - mod_data.protocol_type = USB_SC_8020; - mod_data.protocol_name = "8020i (ATAPI)"; - } else if (strnicmp(mod_data.protocol_parm, "QIC", 3) == 0 || - prot == USB_SC_QIC) { - mod_data.protocol_type = USB_SC_QIC; - mod_data.protocol_name = "QIC-157"; - } else if (strnicmp(mod_data.protocol_parm, "UFI", 10) == 0 || - prot == USB_SC_UFI) { - mod_data.protocol_type = USB_SC_UFI; - mod_data.protocol_name = "UFI"; - } else if (strnicmp(mod_data.protocol_parm, "8070", 4) == 0 || - prot == USB_SC_8070) { - mod_data.protocol_type = USB_SC_8070; - mod_data.protocol_name = "8070i"; - } else { - ERROR(fsg, "invalid protocol: %s\n", mod_data.protocol_parm); - return -EINVAL; - } - - mod_data.buflen &= PAGE_CACHE_MASK; - if (mod_data.buflen <= 0) { - ERROR(fsg, "invalid buflen\n"); - return -ETOOSMALL; - } - -#endif /* CONFIG_USB_FILE_STORAGE_TEST */ - - /* Serial string handling. - * On a real device, the serial string would be loaded - * from permanent storage. */ - if (mod_data.serial) { - const char *ch; - unsigned len = 0; - - /* Sanity check : - * The CB[I] specification limits the serial string to - * 12 uppercase hexadecimal characters. - * BBB need at least 12 uppercase hexadecimal characters, - * with a maximum of 126. */ - for (ch = mod_data.serial; *ch; ++ch) { - ++len; - if ((*ch < '0' || *ch > '9') && - (*ch < 'A' || *ch > 'F')) { /* not uppercase hex */ - WARNING(fsg, - "Invalid serial string character: %c\n", - *ch); - goto no_serial; - } - } - if (len > 126 || - (mod_data.transport_type == USB_PR_BULK && len < 12) || - (mod_data.transport_type != USB_PR_BULK && len > 12)) { - WARNING(fsg, "Invalid serial string length!\n"); - goto no_serial; - } - fsg_strings[FSG_STRING_SERIAL - 1].s = mod_data.serial; - } else { - WARNING(fsg, "No serial-number string provided!\n"); - no_serial: - device_desc.iSerialNumber = 0; - } - - return 0; -} - - -static int __init fsg_bind(struct usb_gadget *gadget, - struct usb_gadget_driver *driver) -{ - struct fsg_dev *fsg = the_fsg; - int rc; - int i; - struct fsg_lun *curlun; - struct usb_ep *ep; - struct usb_request *req; - char *pathbuf, *p; - - fsg->gadget = gadget; - set_gadget_data(gadget, fsg); - fsg->ep0 = gadget->ep0; - fsg->ep0->driver_data = fsg; - - if ((rc = check_parameters(fsg)) != 0) - goto out; - - if (mod_data.removable) { // Enable the store_xxx attributes - dev_attr_file.attr.mode = 0644; - dev_attr_file.store = fsg_store_file; - if (!mod_data.cdrom) { - dev_attr_ro.attr.mode = 0644; - dev_attr_ro.store = fsg_store_ro; - } - } - - /* Only for removable media? */ - dev_attr_nofua.attr.mode = 0644; - dev_attr_nofua.store = fsg_store_nofua; - - /* Find out how many LUNs there should be */ - i = mod_data.nluns; - if (i == 0) - i = max(mod_data.num_filenames, 1u); - if (i > FSG_MAX_LUNS) { - ERROR(fsg, "invalid number of LUNs: %d\n", i); - rc = -EINVAL; - goto out; - } - - /* Create the LUNs, open their backing files, and register the - * LUN devices in sysfs. */ - fsg->luns = kzalloc(i * sizeof(struct fsg_lun), GFP_KERNEL); - if (!fsg->luns) { - rc = -ENOMEM; - goto out; - } - fsg->nluns = i; - - for (i = 0; i < fsg->nluns; ++i) { - curlun = &fsg->luns[i]; - curlun->cdrom = !!mod_data.cdrom; - curlun->ro = mod_data.cdrom || mod_data.ro[i]; - curlun->initially_ro = curlun->ro; - curlun->removable = mod_data.removable; - curlun->nofua = mod_data.nofua[i]; - curlun->dev.release = lun_release; - curlun->dev.parent = &gadget->dev; - curlun->dev.driver = &fsg_driver.driver; - dev_set_drvdata(&curlun->dev, &fsg->filesem); - dev_set_name(&curlun->dev,"%s-lun%d", - dev_name(&gadget->dev), i); - - kref_get(&fsg->ref); - rc = device_register(&curlun->dev); - if (rc) { - INFO(fsg, "failed to register LUN%d: %d\n", i, rc); - put_device(&curlun->dev); - goto out; - } - curlun->registered = 1; - - rc = device_create_file(&curlun->dev, &dev_attr_ro); - if (rc) - goto out; - rc = device_create_file(&curlun->dev, &dev_attr_nofua); - if (rc) - goto out; - rc = device_create_file(&curlun->dev, &dev_attr_file); - if (rc) - goto out; - - if (mod_data.file[i] && *mod_data.file[i]) { - rc = fsg_lun_open(curlun, mod_data.file[i]); - if (rc) - goto out; - } else if (!mod_data.removable) { - ERROR(fsg, "no file given for LUN%d\n", i); - rc = -EINVAL; - goto out; - } - } - - /* Find all the endpoints we will use */ - usb_ep_autoconfig_reset(gadget); - ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc); - if (!ep) - goto autoconf_fail; - ep->driver_data = fsg; // claim the endpoint - fsg->bulk_in = ep; - - ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc); - if (!ep) - goto autoconf_fail; - ep->driver_data = fsg; // claim the endpoint - fsg->bulk_out = ep; - - if (transport_is_cbi()) { - ep = usb_ep_autoconfig(gadget, &fsg_fs_intr_in_desc); - if (!ep) - goto autoconf_fail; - ep->driver_data = fsg; // claim the endpoint - fsg->intr_in = ep; - } - - /* Fix up the descriptors */ - device_desc.idVendor = cpu_to_le16(mod_data.vendor); - device_desc.idProduct = cpu_to_le16(mod_data.product); - device_desc.bcdDevice = cpu_to_le16(mod_data.release); - - i = (transport_is_cbi() ? 3 : 2); // Number of endpoints - fsg_intf_desc.bNumEndpoints = i; - fsg_intf_desc.bInterfaceSubClass = mod_data.protocol_type; - fsg_intf_desc.bInterfaceProtocol = mod_data.transport_type; - fsg_fs_function[i + FSG_FS_FUNCTION_PRE_EP_ENTRIES] = NULL; - - if (gadget_is_dualspeed(gadget)) { - fsg_hs_function[i + FSG_HS_FUNCTION_PRE_EP_ENTRIES] = NULL; - - /* Assume endpoint addresses are the same for both speeds */ - fsg_hs_bulk_in_desc.bEndpointAddress = - fsg_fs_bulk_in_desc.bEndpointAddress; - fsg_hs_bulk_out_desc.bEndpointAddress = - fsg_fs_bulk_out_desc.bEndpointAddress; - fsg_hs_intr_in_desc.bEndpointAddress = - fsg_fs_intr_in_desc.bEndpointAddress; - } - - if (gadget_is_superspeed(gadget)) { - unsigned max_burst; - - fsg_ss_function[i + FSG_SS_FUNCTION_PRE_EP_ENTRIES] = NULL; - - /* Calculate bMaxBurst, we know packet size is 1024 */ - max_burst = min_t(unsigned, mod_data.buflen / 1024, 15); - - /* Assume endpoint addresses are the same for both speeds */ - fsg_ss_bulk_in_desc.bEndpointAddress = - fsg_fs_bulk_in_desc.bEndpointAddress; - fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst; - - fsg_ss_bulk_out_desc.bEndpointAddress = - fsg_fs_bulk_out_desc.bEndpointAddress; - fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst; - } - - if (gadget_is_otg(gadget)) - fsg_otg_desc.bmAttributes |= USB_OTG_HNP; - - rc = -ENOMEM; - - /* Allocate the request and buffer for endpoint 0 */ - fsg->ep0req = req = usb_ep_alloc_request(fsg->ep0, GFP_KERNEL); - if (!req) - goto out; - req->buf = kmalloc(EP0_BUFSIZE, GFP_KERNEL); - if (!req->buf) - goto out; - req->complete = ep0_complete; - - /* Allocate the data buffers */ - for (i = 0; i < fsg_num_buffers; ++i) { - struct fsg_buffhd *bh = &fsg->buffhds[i]; - - /* Allocate for the bulk-in endpoint. We assume that - * the buffer will also work with the bulk-out (and - * interrupt-in) endpoint. */ - bh->buf = kmalloc(mod_data.buflen, GFP_KERNEL); - if (!bh->buf) - goto out; - bh->next = bh + 1; - } - fsg->buffhds[fsg_num_buffers - 1].next = &fsg->buffhds[0]; - - /* This should reflect the actual gadget power source */ - usb_gadget_set_selfpowered(gadget); - - snprintf(fsg_string_manufacturer, sizeof fsg_string_manufacturer, - "%s %s with %s", - init_utsname()->sysname, init_utsname()->release, - gadget->name); - - fsg->thread_task = kthread_create(fsg_main_thread, fsg, - "file-storage-gadget"); - if (IS_ERR(fsg->thread_task)) { - rc = PTR_ERR(fsg->thread_task); - goto out; - } - - INFO(fsg, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); - INFO(fsg, "NOTE: This driver is deprecated. " - "Consider using g_mass_storage instead.\n"); - INFO(fsg, "Number of LUNs=%d\n", fsg->nluns); - - pathbuf = kmalloc(PATH_MAX, GFP_KERNEL); - for (i = 0; i < fsg->nluns; ++i) { - curlun = &fsg->luns[i]; - if (fsg_lun_is_open(curlun)) { - p = NULL; - if (pathbuf) { - p = d_path(&curlun->filp->f_path, - pathbuf, PATH_MAX); - if (IS_ERR(p)) - p = NULL; - } - LINFO(curlun, "ro=%d, nofua=%d, file: %s\n", - curlun->ro, curlun->nofua, (p ? p : "(error)")); - } - } - kfree(pathbuf); - - DBG(fsg, "transport=%s (x%02x)\n", - mod_data.transport_name, mod_data.transport_type); - DBG(fsg, "protocol=%s (x%02x)\n", - mod_data.protocol_name, mod_data.protocol_type); - DBG(fsg, "VendorID=x%04x, ProductID=x%04x, Release=x%04x\n", - mod_data.vendor, mod_data.product, mod_data.release); - DBG(fsg, "removable=%d, stall=%d, cdrom=%d, buflen=%u\n", - mod_data.removable, mod_data.can_stall, - mod_data.cdrom, mod_data.buflen); - DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task)); - - set_bit(REGISTERED, &fsg->atomic_bitflags); - - /* Tell the thread to start working */ - wake_up_process(fsg->thread_task); - return 0; - -autoconf_fail: - ERROR(fsg, "unable to autoconfigure all endpoints\n"); - rc = -ENOTSUPP; - -out: - fsg->state = FSG_STATE_TERMINATED; // The thread is dead - fsg_unbind(gadget); - complete(&fsg->thread_notifier); - return rc; -} - - -/*-------------------------------------------------------------------------*/ - -static void fsg_suspend(struct usb_gadget *gadget) -{ - struct fsg_dev *fsg = get_gadget_data(gadget); - - DBG(fsg, "suspend\n"); - set_bit(SUSPENDED, &fsg->atomic_bitflags); -} - -static void fsg_resume(struct usb_gadget *gadget) -{ - struct fsg_dev *fsg = get_gadget_data(gadget); - - DBG(fsg, "resume\n"); - clear_bit(SUSPENDED, &fsg->atomic_bitflags); -} - - -/*-------------------------------------------------------------------------*/ - -static __refdata struct usb_gadget_driver fsg_driver = { - .max_speed = USB_SPEED_SUPER, - .function = (char *) fsg_string_product, - .bind = fsg_bind, - .unbind = fsg_unbind, - .disconnect = fsg_disconnect, - .setup = fsg_setup, - .suspend = fsg_suspend, - .resume = fsg_resume, - - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - // .release = ... - // .suspend = ... - // .resume = ... - }, -}; - - -static int __init fsg_alloc(void) -{ - struct fsg_dev *fsg; - - fsg = kzalloc(sizeof *fsg + - fsg_num_buffers * sizeof *(fsg->buffhds), GFP_KERNEL); - - if (!fsg) - return -ENOMEM; - spin_lock_init(&fsg->lock); - init_rwsem(&fsg->filesem); - kref_init(&fsg->ref); - init_completion(&fsg->thread_notifier); - - the_fsg = fsg; - return 0; -} - - -static int __init fsg_init(void) -{ - int rc; - struct fsg_dev *fsg; - - rc = fsg_num_buffers_validate(); - if (rc != 0) - return rc; - - if ((rc = fsg_alloc()) != 0) - return rc; - fsg = the_fsg; - rc = usb_gadget_probe_driver(&fsg_driver); - if (rc != 0) - kref_put(&fsg->ref, fsg_release); - return rc; -} -module_init(fsg_init); - - -static void __exit fsg_cleanup(void) -{ - struct fsg_dev *fsg = the_fsg; - - /* Unregister the driver iff the thread hasn't already done so */ - if (test_and_clear_bit(REGISTERED, &fsg->atomic_bitflags)) - usb_gadget_unregister_driver(&fsg_driver); - - /* Wait for the thread to finish up */ - wait_for_completion(&fsg->thread_notifier); - - kref_put(&fsg->ref, fsg_release); -} -module_exit(fsg_cleanup); diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index ac335af154b..708c0b55dcc 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -9,7 +9,7 @@ * CODE STATUS HIGHLIGHTS * * This driver should work well with most "gadget" drivers, including - * the File Storage, Serial, and Ethernet/RNDIS gadget drivers + * the Mass Storage, Serial, and Ethernet/RNDIS gadget drivers * as well as Gadget Zero and Gadgetfs. * * DMA is enabled by default. Drivers using transfer queues might use diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h index a1d268c6f2c..79d81a4b234 100644 --- a/drivers/usb/gadget/pxa27x_udc.h +++ b/drivers/usb/gadget/pxa27x_udc.h @@ -418,7 +418,7 @@ struct udc_stats { * @irq: udc irq * @clk: udc clock * @usb_gadget: udc gadget structure - * @driver: bound gadget (zero, g_ether, g_file_storage, ...) + * @driver: bound gadget (zero, g_ether, g_mass_storage, ...) * @dev: device * @mach: machine info, used to activate specific GPIO * @transceiver: external transceiver to handle vbus sense and D+ pullup -- cgit v1.2.3 From c7800a34acac2dcb3e8d8038013e2dbea76bd8a9 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 6 Nov 2012 22:52:37 +0100 Subject: usb: gadget: storage_common: Remove FSG specific definitions. Since g_file_storage has been removed, this commit removes code from the storage_common.c file which has been used by file_storage.c only (and not by f_mass_storage.c). Signed-off-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/storage_common.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 14199d70bee..b381e0ca279 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -78,34 +78,6 @@ #define LWARN(lun, fmt, args...) dev_warn(&(lun)->dev, fmt, ## args) #define LINFO(lun, fmt, args...) dev_info(&(lun)->dev, fmt, ## args) -/* - * Keep those macros in sync with those in - * include/linux/usb/composite.h or else GCC will complain. If they - * are identical (the same names of arguments, white spaces in the - * same places) GCC will allow redefinition otherwise (even if some - * white space is removed or added) warning will be issued. - * - * Those macros are needed here because File Storage Gadget does not - * include the composite.h header. For composite gadgets those macros - * are redundant since composite.h is included any way. - * - * One could check whether those macros are already defined (which - * would indicate composite.h had been included) or not (which would - * indicate we were in FSG) but this is not done because a warning is - * desired if definitions here differ from the ones in composite.h. - * - * We want the definitions to match and be the same in File Storage - * Gadget as well as Mass Storage Function (and so composite gadgets - * using MSF). If someone changes them in composite.h it will produce - * a warning in this file when building MSF. - */ -#define DBG(d, fmt, args...) dev_dbg(&(d)->gadget->dev , fmt , ## args) -#define VDBG(d, fmt, args...) dev_vdbg(&(d)->gadget->dev , fmt , ## args) -#define ERROR(d, fmt, args...) dev_err(&(d)->gadget->dev , fmt , ## args) -#define WARNING(d, fmt, args...) dev_warn(&(d)->gadget->dev , fmt , ## args) -#define INFO(d, fmt, args...) dev_info(&(d)->gadget->dev , fmt , ## args) - - #ifdef DUMP_MSGS -- cgit v1.2.3 From 8575f7a70610c89135c374e4305421c41e39e810 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 6 Nov 2012 22:52:38 +0100 Subject: usb: gadget: storage_common: Drop #ifdefs used for the sake of FSG. storage_common.c has been used by both file_storage.c and f_mass_storage.c which had some different requirements in a few places. To accomodate for that, storage_common.c provided configuratian macros which were to be defined (or not) prior to the file #inclusion. Because now file_storage.c is no longer with us, we can remove support for those macros and thus simplify the code slightly. Signed-off-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_mass_storage.c | 4 -- drivers/usb/gadget/storage_common.c | 130 ------------------------------------ 2 files changed, 134 deletions(-) diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 3433e432a4a..5d027b3e1ef 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -228,10 +228,6 @@ static const char fsg_string_interface[] = "Mass Storage"; -#define FSG_NO_DEVICE_STRINGS 1 -#define FSG_NO_OTG 1 -#define FSG_NO_INTR_EP 1 - #include "storage_common.c" diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index b381e0ca279..1b5bc6969a0 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -11,30 +11,10 @@ * (at your option) any later version. */ - /* * This file requires the following identifiers used in USB strings to * be defined (each of type pointer to char): - * - fsg_string_manufacturer -- name of the manufacturer - * - fsg_string_product -- name of the product - * - fsg_string_config -- name of the configuration * - fsg_string_interface -- name of the interface - * The first four are only needed when FSG_DESCRIPTORS_DEVICE_STRINGS - * macro is defined prior to including this file. - */ - -/* - * When FSG_NO_INTR_EP is defined fsg_fs_intr_in_desc and - * fsg_hs_intr_in_desc objects as well as - * FSG_FS_FUNCTION_PRE_EP_ENTRIES and FSG_HS_FUNCTION_PRE_EP_ENTRIES - * macros are not defined. - * - * When FSG_NO_DEVICE_STRINGS is defined FSG_STRING_MANUFACTURER, - * FSG_STRING_PRODUCT, FSG_STRING_SERIAL and FSG_STRING_CONFIG are not - * defined (as well as corresponding entries in string tables are - * missing) and FSG_STRING_INTERFACE has value of zero. - * - * When FSG_NO_OTG is defined fsg_otg_desc won't be defined. */ /* @@ -280,26 +260,10 @@ static inline u32 get_unaligned_be24(u8 *buf) enum { -#ifndef FSG_NO_DEVICE_STRINGS - FSG_STRING_MANUFACTURER = 1, - FSG_STRING_PRODUCT, - FSG_STRING_SERIAL, - FSG_STRING_CONFIG, -#endif FSG_STRING_INTERFACE }; -#ifndef FSG_NO_OTG -static struct usb_otg_descriptor -fsg_otg_desc = { - .bLength = sizeof fsg_otg_desc, - .bDescriptorType = USB_DT_OTG, - - .bmAttributes = USB_OTG_SRP, -}; -#endif - /* There is only one interface. */ static struct usb_interface_descriptor @@ -339,37 +303,10 @@ fsg_fs_bulk_out_desc = { /* wMaxPacketSize set by autoconfiguration */ }; -#ifndef FSG_NO_INTR_EP - -static struct usb_endpoint_descriptor -fsg_fs_intr_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(2), - .bInterval = 32, /* frames -> 32 ms */ -}; - -#ifndef FSG_NO_OTG -# define FSG_FS_FUNCTION_PRE_EP_ENTRIES 2 -#else -# define FSG_FS_FUNCTION_PRE_EP_ENTRIES 1 -#endif - -#endif - static struct usb_descriptor_header *fsg_fs_function[] = { -#ifndef FSG_NO_OTG - (struct usb_descriptor_header *) &fsg_otg_desc, -#endif (struct usb_descriptor_header *) &fsg_intf_desc, (struct usb_descriptor_header *) &fsg_fs_bulk_in_desc, (struct usb_descriptor_header *) &fsg_fs_bulk_out_desc, -#ifndef FSG_NO_INTR_EP - (struct usb_descriptor_header *) &fsg_fs_intr_in_desc, -#endif NULL, }; @@ -403,37 +340,11 @@ fsg_hs_bulk_out_desc = { .bInterval = 1, /* NAK every 1 uframe */ }; -#ifndef FSG_NO_INTR_EP - -static struct usb_endpoint_descriptor -fsg_hs_intr_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(2), - .bInterval = USB_MS_TO_HS_INTERVAL(32), /* 32 ms */ -}; - -#ifndef FSG_NO_OTG -# define FSG_HS_FUNCTION_PRE_EP_ENTRIES 2 -#else -# define FSG_HS_FUNCTION_PRE_EP_ENTRIES 1 -#endif - -#endif static struct usb_descriptor_header *fsg_hs_function[] = { -#ifndef FSG_NO_OTG - (struct usb_descriptor_header *) &fsg_otg_desc, -#endif (struct usb_descriptor_header *) &fsg_intf_desc, (struct usb_descriptor_header *) &fsg_hs_bulk_in_desc, (struct usb_descriptor_header *) &fsg_hs_bulk_out_desc, -#ifndef FSG_NO_INTR_EP - (struct usb_descriptor_header *) &fsg_hs_intr_in_desc, -#endif NULL, }; @@ -471,34 +382,6 @@ static struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = { /*.bMaxBurst = DYNAMIC, */ }; -#ifndef FSG_NO_INTR_EP - -static struct usb_endpoint_descriptor -fsg_ss_intr_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = cpu_to_le16(2), - .bInterval = USB_MS_TO_HS_INTERVAL(32), /* 32 ms */ -}; - -static struct usb_ss_ep_comp_descriptor fsg_ss_intr_in_comp_desc = { - .bLength = sizeof(fsg_ss_bulk_in_comp_desc), - .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, - - .wBytesPerInterval = cpu_to_le16(2), -}; - -#ifndef FSG_NO_OTG -# define FSG_SS_FUNCTION_PRE_EP_ENTRIES 2 -#else -# define FSG_SS_FUNCTION_PRE_EP_ENTRIES 1 -#endif - -#endif - static __maybe_unused struct usb_ext_cap_descriptor fsg_ext_cap_desc = { .bLength = USB_DT_USB_EXT_CAP_SIZE, .bDescriptorType = USB_DT_DEVICE_CAPABILITY, @@ -535,18 +418,11 @@ static __maybe_unused struct usb_bos_descriptor fsg_bos_desc = { }; static struct usb_descriptor_header *fsg_ss_function[] = { -#ifndef FSG_NO_OTG - (struct usb_descriptor_header *) &fsg_otg_desc, -#endif (struct usb_descriptor_header *) &fsg_intf_desc, (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc, (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc, (struct usb_descriptor_header *) &fsg_ss_bulk_out_desc, (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc, -#ifndef FSG_NO_INTR_EP - (struct usb_descriptor_header *) &fsg_ss_intr_in_desc, - (struct usb_descriptor_header *) &fsg_ss_intr_in_comp_desc, -#endif NULL, }; @@ -566,12 +442,6 @@ fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ static struct usb_string fsg_strings[] = { -#ifndef FSG_NO_DEVICE_STRINGS - {FSG_STRING_MANUFACTURER, fsg_string_manufacturer}, - {FSG_STRING_PRODUCT, fsg_string_product}, - {FSG_STRING_SERIAL, ""}, - {FSG_STRING_CONFIG, fsg_string_config}, -#endif {FSG_STRING_INTERFACE, fsg_string_interface}, {} }; -- cgit v1.2.3 From fea20dbcfd6673d73d510984589897bd921c8a1d Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 6 Nov 2012 22:52:39 +0100 Subject: usb: gadget: storage_common: Make fsg_lun_is_open() a function. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since function-line macros are to be avoided, this commit replaces the fsg_lun_is_open() macro with a static inline function. While at it, this commit also adds “inline” modifier to the fsg_lun_from_dev() function. Signed-off-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/storage_common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 1b5bc6969a0..0e3ae43454a 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -155,9 +155,12 @@ struct fsg_lun { struct device dev; }; -#define fsg_lun_is_open(curlun) ((curlun)->filp != NULL) +static inline bool fsg_lun_is_open(struct fsg_lun *curlun) +{ + return curlun->filp != NULL; +} -static struct fsg_lun *fsg_lun_from_dev(struct device *dev) +static inline struct fsg_lun *fsg_lun_from_dev(struct device *dev) { return container_of(dev, struct fsg_lun, dev); } -- cgit v1.2.3 From be44f1c80b998b00cfa1759f4ba88f6497810963 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 6 Nov 2012 22:52:40 +0100 Subject: usb: gadget: Remove reference to is_dualspeed from sysfs. This commit removes the /sys/devices/platform//udc//is_dualspeed file and is_dualspeeed line from /sys/devices/platform/ci13xxx_*/udc/device file. The is_dualspeed file is superseded by maximum_speed in the same directory and is_dualspeed line in device file is superseded by max_speed line in the same file. The maximum_speed/max_speed specifies maximum speed supported by UDC. To check if dualspeeed is supported, check if the value is >= 3. Signed-off-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/debug.c | 3 --- drivers/usb/gadget/udc-core.c | 11 ----------- 2 files changed, 14 deletions(-) diff --git a/drivers/usb/chipidea/debug.c b/drivers/usb/chipidea/debug.c index c6f50a25756..3bc244d2636 100644 --- a/drivers/usb/chipidea/debug.c +++ b/drivers/usb/chipidea/debug.c @@ -160,9 +160,6 @@ static ssize_t show_device(struct device *dev, struct device_attribute *attr, gadget->speed); n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed = %d\n", gadget->max_speed); - /* TODO: Scheduled for removal in 3.8. */ - n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n", - gadget_is_dualspeed(gadget)); n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n", gadget->is_otg); n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n", diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index f3cd9690b10..4d90a800063 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -439,16 +439,6 @@ static DEVICE_ATTR(name, S_IRUSR, usb_udc_##param##_show, NULL) static USB_UDC_SPEED_ATTR(current_speed, speed); static USB_UDC_SPEED_ATTR(maximum_speed, max_speed); -/* TODO: Scheduled for removal in 3.8. */ -static ssize_t usb_udc_is_dualspeed_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); - return snprintf(buf, PAGE_SIZE, "%d\n", - gadget_is_dualspeed(udc->gadget)); -} -static DEVICE_ATTR(is_dualspeed, S_IRUSR, usb_udc_is_dualspeed_show, NULL); - #define USB_UDC_ATTR(name) \ ssize_t usb_udc_##name##_show(struct device *dev, \ struct device_attribute *attr, char *buf) \ @@ -472,7 +462,6 @@ static struct attribute *usb_udc_attrs[] = { &dev_attr_current_speed.attr, &dev_attr_maximum_speed.attr, - &dev_attr_is_dualspeed.attr, &dev_attr_is_otg.attr, &dev_attr_is_a_peripheral.attr, &dev_attr_b_hnp_enable.attr, -- cgit v1.2.3 From 23834e533184bd2185bce500c789f86b3668739b Mon Sep 17 00:00:00 2001 From: Ian Coolidge Date: Tue, 6 Nov 2012 13:00:10 -0800 Subject: usb: gadget: g_ether: fix frame size check Checking skb->len against ETH_FRAME_LEN assumes a 1514 ethernet frame size. With an 802.1Q VLAN header, ethernet frame length can now be 1518. Validate frame length against that. Signed-off-by: Ian Coolidge Signed-off-by: Felipe Balbi --- drivers/usb/gadget/u_ether.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 6458764994e..4ec3c0d7a18 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "u_ether.h" @@ -295,7 +296,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) while (skb2) { if (status < 0 || ETH_HLEN > skb2->len - || skb2->len > ETH_FRAME_LEN) { + || skb2->len > VLAN_ETH_FRAME_LEN) { dev->net->stats.rx_errors++; dev->net->stats.rx_length_errors++; DBG(dev, "rx length %d\n", skb2->len); -- cgit v1.2.3 From f72e3b78867142a19b77f1de0698ce8b03dc6cbd Mon Sep 17 00:00:00 2001 From: Dmytro Milinevskyy Date: Fri, 5 Oct 2012 01:44:04 +0300 Subject: usb: gadget: ncm: correct endianess conversion Convert USB descriptor's fields to CPU byte order before using locally in USB NCM gadget driver. Tested on MIPS32 big-endian device. Signed-off-by: Dmytro Milinevskyy Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_ncm.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/f_ncm.c b/drivers/usb/gadget/f_ncm.c index f1f66e9c76b..6c8362f937b 100644 --- a/drivers/usb/gadget/f_ncm.c +++ b/drivers/usb/gadget/f_ncm.c @@ -102,7 +102,7 @@ static inline unsigned ncm_bitrate(struct usb_gadget *g) USB_CDC_NCM_NTB32_SUPPORTED) static struct usb_cdc_ncm_ntb_parameters ntb_parameters = { - .wLength = sizeof ntb_parameters, + .wLength = cpu_to_le16(sizeof(ntb_parameters)), .bmNtbFormatsSupported = cpu_to_le16(FORMATS_SUPPORTED), .dwNtbInMaxSize = cpu_to_le32(NTB_DEFAULT_IN_SIZE), .wNdpInDivisor = cpu_to_le16(4), @@ -869,15 +869,19 @@ static struct sk_buff *ncm_wrap_ntb(struct gether *port, struct sk_buff *skb2; int ncb_len = 0; __le16 *tmp; - int div = ntb_parameters.wNdpInDivisor; - int rem = ntb_parameters.wNdpInPayloadRemainder; + int div; + int rem; int pad; - int ndp_align = ntb_parameters.wNdpInAlignment; + int ndp_align; int ndp_pad; unsigned max_size = ncm->port.fixed_in_len; struct ndp_parser_opts *opts = ncm->parser_opts; unsigned crc_len = ncm->is_crc ? sizeof(uint32_t) : 0; + div = le16_to_cpu(ntb_parameters.wNdpInDivisor); + rem = le16_to_cpu(ntb_parameters.wNdpInPayloadRemainder); + ndp_align = le16_to_cpu(ntb_parameters.wNdpInAlignment); + ncb_len += opts->nth_size; ndp_pad = ALIGN(ncb_len, ndp_align) - ncb_len; ncb_len += ndp_pad; -- cgit v1.2.3 From 4552cf0f774ae3d24bf31e91324586274a552a66 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 7 Nov 2012 16:27:10 +0900 Subject: perf machine: Set kernel data mapping length Currently only text (function) mapping was set, so that the kernel data addresses couldn't parsed correctly. Fix it. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1352273234-28912-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/machine.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 502eec0d477..4c6754ac6b2 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -84,15 +84,19 @@ int machine__process_lost_event(struct machine *machine __maybe_unused, static void machine__set_kernel_mmap_len(struct machine *machine, union perf_event *event) { - machine->vmlinux_maps[MAP__FUNCTION]->start = event->mmap.start; - machine->vmlinux_maps[MAP__FUNCTION]->end = (event->mmap.start + - event->mmap.len); - /* - * Be a bit paranoid here, some perf.data file came with - * a zero sized synthesized MMAP event for the kernel. - */ - if (machine->vmlinux_maps[MAP__FUNCTION]->end == 0) - machine->vmlinux_maps[MAP__FUNCTION]->end = ~0ULL; + int i; + + for (i = 0; i < MAP__NR_TYPES; i++) { + machine->vmlinux_maps[i]->start = event->mmap.start; + machine->vmlinux_maps[i]->end = (event->mmap.start + + event->mmap.len); + /* + * Be a bit paranoid here, some perf.data file came with + * a zero sized synthesized MMAP event for the kernel. + */ + if (machine->vmlinux_maps[i]->end == 0) + machine->vmlinux_maps[i]->end = ~0ULL; + } } static int machine__process_kernel_mmap_event(struct machine *machine, -- cgit v1.2.3 From 1e82574d1db1451f137cb520f21b9176f05284c9 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 7 Nov 2012 16:27:11 +0900 Subject: perf tools: Fix detection of stack area Output of /proc//maps contains helpful information to anonymous mappings like stack, heap, ... For the case of stack, it can show multiple stack area for each thread in the process: $ cat /proc/$(pidof gnome-shell)/maps | grep stack 7fe019946000-7fe01a146000 rw-p 00000000 00:00 0 [stack:1624] 7fe040e32000-7fe041632000 rw-p 00000000 00:00 0 [stack:1451] 7fe041643000-7fe041e43000 rw-p 00000000 00:00 0 [stack:1450] 7fe04204b000-7fe04284b000 rw-p 00000000 00:00 0 [stack:1449] 7fe042a7e000-7fe04327e000 rw-p 00000000 00:00 0 [stack:1446] 7fe0432ff000-7fe043aff000 rw-p 00000000 00:00 0 [stack:1445] 7fe043b00000-7fe044300000 rw-p 00000000 00:00 0 [stack:1444] 7fe044301000-7fe044b01000 rw-p 00000000 00:00 0 [stack:1443] 7fe044b02000-7fe045302000 rw-p 00000000 00:00 0 [stack:1442] 7fe045303000-7fe045b03000 rw-p 00000000 00:00 0 [stack:1441] 7fe045b04000-7fe046304000 rw-p 00000000 00:00 0 [stack:1440] 7fe046305000-7fe046b05000 rw-p 00000000 00:00 0 [stack:1439] 7fe046b06000-7fe047306000 rw-p 00000000 00:00 0 [stack:1438] 7fff4b16f000-7fff4b190000 rw-p 00000000 00:00 0 [stack] However perf only knew about the main thread's. Fix it. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1352273234-28912-4-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 9b40c444039..579187865f0 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -24,7 +24,7 @@ static inline int is_anon_memory(const char *filename) static inline int is_no_dso_memory(const char *filename) { - return !strcmp(filename, "[stack]") || + return !strncmp(filename, "[stack", 6) || !strcmp(filename, "[heap]"); } -- cgit v1.2.3 From 580e338d7e9dc4947cba2e1021e78e76ebe0869e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 7 Nov 2012 16:27:14 +0900 Subject: perf hists: Free branch_info when freeing hist_entry Those data should be free along with the associated hist_entry, otherwise it'll be leaked. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1352273234-28912-7-git-send-email-namhyung@kernel.org [ committer note: mem_info is not yet in perf/core, free just branch_info ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 277947a669b..a1b823f8c17 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -410,6 +410,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right) void hist_entry__free(struct hist_entry *he) { + free(he->branch_info); free(he); } -- cgit v1.2.3 From d4fcf0a8b96b23a245a21065c9424e09c8080819 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 8 Nov 2012 17:01:01 +0100 Subject: perf tests: Move attr.py temp dir cleanup into finally section Currently if there's 'Unsup' exception raised, we do not clean up the temp directory. Solving this by adding 'finally' to make the cleanup in any case. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352390461-15404-1-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/attr.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/tools/perf/tests/attr.py b/tools/perf/tests/attr.py index 9b25b33cf3e..e702b82dcb8 100644 --- a/tools/perf/tests/attr.py +++ b/tools/perf/tests/attr.py @@ -228,24 +228,26 @@ class Test(object): def run(self): tempdir = tempfile.mkdtemp(); - # run the test script - self.run_cmd(tempdir); + try: + # run the test script + self.run_cmd(tempdir); - # load events expectation for the test - log.info(" loading result events"); - for f in glob.glob(tempdir + '/event*'): - self.load_events(f, self.result); + # load events expectation for the test + log.info(" loading result events"); + for f in glob.glob(tempdir + '/event*'): + self.load_events(f, self.result); - # resolve group_fd to event names - self.resolve_groups(self.expect); - self.resolve_groups(self.result); + # resolve group_fd to event names + self.resolve_groups(self.expect); + self.resolve_groups(self.result); - # do the expectation - results matching - both ways - self.compare(self.expect, self.result) - self.compare(self.result, self.expect) + # do the expectation - results matching - both ways + self.compare(self.expect, self.result) + self.compare(self.result, self.expect) - # cleanup - shutil.rmtree(tempdir) + finally: + # cleanup + shutil.rmtree(tempdir) def run_tests(options): -- cgit v1.2.3 From 1fa0bc3f8d4f9bbcde5b1f962b006906cc80b2dc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 3 Nov 2012 19:27:57 +0100 Subject: perf tools: Add LIBDW_DIR Makefile variable to for alternate libdw Adding LIBDW_DIR Makefile variable to be able to specify alternate libdw library location. To use it run make like: $ make LIBDW_DIR=/opt/libdw/ Signed-off-by: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-n2uv8c9ti6b26fioaw2rq5yv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 4ffcd02404f..cca5bb8334a 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -501,7 +501,14 @@ ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y) msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static); endif else - FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS) + # for linking with debug library, run like: + # make DEBUG=1 LIBDW_DIR=/opt/libdw/ + ifdef LIBDW_DIR + LIBDW_CFLAGS := -I$(LIBDW_DIR)/include + LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib + endif + + FLAGS_DWARF=$(ALL_CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y) msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev); NO_DWARF := 1 @@ -556,7 +563,8 @@ ifndef NO_DWARF ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled); else - BASIC_CFLAGS += -DDWARF_SUPPORT + BASIC_CFLAGS := -DDWARF_SUPPORT $(LIBDW_CFLAGS) $(BASIC_CFLAGS) + BASIC_LDFLAGS := $(LIBDW_LDFLAGS) $(BASIC_LDFLAGS) EXTLIBS += -lelf -ldw LIB_OBJS += $(OUTPUT)util/probe-finder.o LIB_OBJS += $(OUTPUT)util/dwarf-aux.o -- cgit v1.2.3 From eef9ba98b9ee96f52e544b09f581c397d8cc8265 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 5 Nov 2012 14:50:52 +0100 Subject: perf tools: Add arbitary aliases and support names with - - Add missing scanner symbol for arbitrary aliases inside the config region. - looks nicer than _, so allow - in the event names. Used for various of the arch perfmon and Haswell events. Signed-off-by: Andi Kleen Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352123463-7346-6-git-send-email-eranian@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/parse-events.l | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index c87efc12579..66959fab663 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -81,6 +81,7 @@ num_dec [0-9]+ num_hex 0x[a-fA-F0-9]+ num_raw_hex [a-fA-F0-9]+ name [a-zA-Z_*?][a-zA-Z0-9_*?]* +name_minus [a-zA-Z_*?][a-zA-Z0-9\-_*?]* modifier_event [ukhpGH]{1,8} modifier_bp [rwx]{1,3} @@ -168,6 +169,7 @@ period { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); } branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); } , { return ','; } "/" { BEGIN(INITIAL); return '/'; } +{name_minus} { return str(yyscanner, PE_NAME); } } mem: { BEGIN(mem); return PE_PREFIX_MEM; } -- cgit v1.2.3 From 57d34a6cee1399bfedaa73add1915951cbe75cab Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 19 Oct 2012 09:48:30 -0700 Subject: rcu: Update docs to include kfree_rcu() Mention kfree_rcu() in the call_rcu() section. Additionally fix the example code for list replacement that used the wrong structure element. Signed-off-by: Kees Cook Signed-off-by: Paul E. McKenney --- Documentation/RCU/listRCU.txt | 2 +- Documentation/RCU/whatisRCU.txt | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Documentation/RCU/listRCU.txt b/Documentation/RCU/listRCU.txt index 4349c1487e9..adb5a378284 100644 --- a/Documentation/RCU/listRCU.txt +++ b/Documentation/RCU/listRCU.txt @@ -205,7 +205,7 @@ RCU ("read-copy update") its name. The RCU code is as follows: audit_copy_rule(&ne->rule, &e->rule); ne->rule.action = newaction; ne->rule.file_count = newfield_count; - list_replace_rcu(e, ne); + list_replace_rcu(&e->list, &ne->list); call_rcu(&e->rcu, audit_free_rule); return 0; } diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index bf0f6de2aa0..160ac5557e9 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt @@ -499,6 +499,8 @@ The foo_reclaim() function might appear as follows: { struct foo *fp = container_of(rp, struct foo, rcu); + foo_cleanup(fp->a); + kfree(fp); } @@ -521,6 +523,12 @@ o Use call_rcu() -after- removing a data element from an read-side critical sections that might be referencing that data item. +If the callback for call_rcu() is not doing anything more than calling +kfree() on the structure, you can use kfree_rcu() instead of call_rcu() +to avoid having to write your own callback: + + kfree_rcu(old_fp, rcu); + Again, see checklist.txt for additional rules governing the use of RCU. @@ -773,8 +781,8 @@ a single atomic update, converting to RCU will require special care. Also, the presence of synchronize_rcu() means that the RCU version of delete() can now block. If this is a problem, there is a callback-based -mechanism that never blocks, namely call_rcu(), that can be used in -place of synchronize_rcu(). +mechanism that never blocks, namely call_rcu() or kfree_rcu(), that can +be used in place of synchronize_rcu(). 7. FULL LIST OF RCU APIs @@ -813,6 +821,7 @@ RCU: Critical sections Grace period Barrier rcu_read_unlock synchronize_rcu rcu_dereference synchronize_rcu_expedited call_rcu + kfree_rcu bh: Critical sections Grace period Barrier -- cgit v1.2.3 From a4d611fdca0d696f9b8ffb007a119944ed5275fa Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sat, 27 Oct 2012 16:34:51 -0700 Subject: rcu: Document alternative RCU/reference-count algorithms The approach for mixing RCU and reference counting listed in the RCU documentation only describes one possible approach. This approach can result in failure on the read side, which is nice if you want fresh data, but not so good if you want simple code. This commit therefore adds two additional approaches that feature unconditional reference-count acquisition by RCU readers. These approaches are very similar to that used in the security code. Signed-off-by: Paul E. McKenney --- Documentation/RCU/rcuref.txt | 61 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/Documentation/RCU/rcuref.txt b/Documentation/RCU/rcuref.txt index 4202ad09313..141d531aa14 100644 --- a/Documentation/RCU/rcuref.txt +++ b/Documentation/RCU/rcuref.txt @@ -20,7 +20,7 @@ release_referenced() delete() { { ... write_lock(&list_lock); atomic_dec(&el->rc, relfunc) ... - ... delete_element + ... remove_element } write_unlock(&list_lock); ... if (atomic_dec_and_test(&el->rc)) @@ -52,7 +52,7 @@ release_referenced() delete() { { ... spin_lock(&list_lock); if (atomic_dec_and_test(&el->rc)) ... - call_rcu(&el->head, el_free); delete_element + call_rcu(&el->head, el_free); remove_element ... spin_unlock(&list_lock); } ... if (atomic_dec_and_test(&el->rc)) @@ -64,3 +64,60 @@ Sometimes, a reference to the element needs to be obtained in the update (write) stream. In such cases, atomic_inc_not_zero() might be overkill, since we hold the update-side spinlock. One might instead use atomic_inc() in such cases. + +It is not always convenient to deal with "FAIL" in the +search_and_reference() code path. In such cases, the +atomic_dec_and_test() may be moved from delete() to el_free() +as follows: + +1. 2. +add() search_and_reference() +{ { + alloc_object rcu_read_lock(); + ... search_for_element + atomic_set(&el->rc, 1); atomic_inc(&el->rc); + spin_lock(&list_lock); ... + + add_element rcu_read_unlock(); + ... } + spin_unlock(&list_lock); 4. +} delete() +3. { +release_referenced() spin_lock(&list_lock); +{ ... + ... remove_element + if (atomic_dec_and_test(&el->rc)) spin_unlock(&list_lock); + kfree(el); ... + ... call_rcu(&el->head, el_free); +} ... +5. } +void el_free(struct rcu_head *rhp) +{ + release_referenced(); +} + +The key point is that the initial reference added by add() is not removed +until after a grace period has elapsed following removal. This means that +search_and_reference() cannot find this element, which means that the value +of el->rc cannot increase. Thus, once it reaches zero, there are no +readers that can or ever will be able to reference the element. The +element can therefore safely be freed. This in turn guarantees that if +any reader finds the element, that reader may safely acquire a reference +without checking the value of the reference counter. + +In cases where delete() can sleep, synchronize_rcu() can be called from +delete(), so that el_free() can be subsumed into delete as follows: + +4. +delete() +{ + spin_lock(&list_lock); + ... + remove_element + spin_unlock(&list_lock); + ... + synchronize_rcu(); + if (atomic_dec_and_test(&el->rc)) + kfree(el); + ... +} -- cgit v1.2.3 From 7b2e6011f150c42235c4a541d20cf6891afe878a Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 8 Oct 2012 10:54:03 -0700 Subject: rcu: Rename ->onofflock to ->orphan_lock The ->onofflock field in the rcu_state structure at one time synchronized CPU-hotplug operations for RCU. However, its scope has decreased over time so that it now only protects the lists of orphaned RCU callbacks. This commit therefore renames it to ->orphan_lock to reflect its current use. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutree.c | 12 ++++++------ kernel/rcutree.h | 7 +++---- kernel/rcutree_plugin.h | 3 ++- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/kernel/rcutree.c b/kernel/rcutree.c index ac8aed8ee41..89148860e2b 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -70,7 +70,7 @@ static struct lock_class_key rcu_fqs_class[RCU_NUM_LVLS]; .fqs_state = RCU_GP_IDLE, \ .gpnum = -300, \ .completed = -300, \ - .onofflock = __RAW_SPIN_LOCK_UNLOCKED(&sname##_state.onofflock), \ + .orphan_lock = __RAW_SPIN_LOCK_UNLOCKED(&sname##_state.orphan_lock), \ .orphan_nxttail = &sname##_state.orphan_nxtlist, \ .orphan_donetail = &sname##_state.orphan_donelist, \ .barrier_mutex = __MUTEX_INITIALIZER(sname##_state.barrier_mutex), \ @@ -1573,7 +1573,7 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp) /* * Send the specified CPU's RCU callbacks to the orphanage. The * specified CPU must be offline, and the caller must hold the - * ->onofflock. + * ->orphan_lock. */ static void rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp, @@ -1623,7 +1623,7 @@ rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp, /* * Adopt the RCU callbacks from the specified rcu_state structure's - * orphanage. The caller must hold the ->onofflock. + * orphanage. The caller must hold the ->orphan_lock. */ static void rcu_adopt_orphan_cbs(struct rcu_state *rsp) { @@ -1702,7 +1702,7 @@ static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp) /* Exclude any attempts to start a new grace period. */ mutex_lock(&rsp->onoff_mutex); - raw_spin_lock_irqsave(&rsp->onofflock, flags); + raw_spin_lock_irqsave(&rsp->orphan_lock, flags); /* Orphan the dead CPU's callbacks, and adopt them if appropriate. */ rcu_send_cbs_to_orphanage(cpu, rsp, rnp, rdp); @@ -1729,10 +1729,10 @@ static void rcu_cleanup_dead_cpu(int cpu, struct rcu_state *rsp) /* * We still hold the leaf rcu_node structure lock here, and * irqs are still disabled. The reason for this subterfuge is - * because invoking rcu_report_unblock_qs_rnp() with ->onofflock + * because invoking rcu_report_unblock_qs_rnp() with ->orphan_lock * held leads to deadlock. */ - raw_spin_unlock(&rsp->onofflock); /* irqs remain disabled. */ + raw_spin_unlock(&rsp->orphan_lock); /* irqs remain disabled. */ rnp = rdp->mynode; if (need_report & RCU_OFL_TASKS_NORM_GP) rcu_report_unblock_qs_rnp(rnp, flags); diff --git a/kernel/rcutree.h b/kernel/rcutree.h index a240f032848..a7c945d149c 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h @@ -383,9 +383,8 @@ struct rcu_state { /* End of fields guarded by root rcu_node's lock. */ - raw_spinlock_t onofflock ____cacheline_internodealigned_in_smp; - /* exclude on/offline and */ - /* starting new GP. */ + raw_spinlock_t orphan_lock ____cacheline_internodealigned_in_smp; + /* Protect following fields. */ struct rcu_head *orphan_nxtlist; /* Orphaned callbacks that */ /* need a grace period. */ struct rcu_head **orphan_nxttail; /* Tail of above. */ @@ -394,7 +393,7 @@ struct rcu_state { struct rcu_head **orphan_donetail; /* Tail of above. */ long qlen_lazy; /* Number of lazy callbacks. */ long qlen; /* Total number of callbacks. */ - /* End of fields guarded by onofflock. */ + /* End of fields guarded by orphan_lock. */ struct mutex onoff_mutex; /* Coordinate hotplug & GPs. */ diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index f9211548818..2b281cf0b6f 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h @@ -757,7 +757,8 @@ static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp, * grace period for the specified rcu_node structure. If there are no such * tasks, report it up the rcu_node hierarchy. * - * Caller must hold sync_rcu_preempt_exp_mutex and rsp->onofflock. + * Caller must hold sync_rcu_preempt_exp_mutex and must exclude + * CPU hotplug operations. */ static void sync_rcu_preempt_exp_init(struct rcu_state *rsp, struct rcu_node *rnp) -- cgit v1.2.3 From 1924bcb0259711eea98491a7942d1ffbf677e114 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 11 Oct 2012 12:30:37 -0700 Subject: rcu: Avoid counter wrap in synchronize_sched_expedited() There is a counter scheme similar to ticket locking that synchronize_sched_expedited() uses to service multiple concurrent callers with the same expedited grace period. Upon entry, a sync_sched_expedited_started variable is atomically incremented, and upon completion of a expedited grace period a separate sync_sched_expedited_done variable is atomically incremented. However, if a synchronize_sched_expedited() is delayed while in try_stop_cpus(), concurrent invocations will increment the sync_sched_expedited_started counter, which will eventually overflow. If the original synchronize_sched_expedited() resumes execution just as the counter overflows, a concurrent invocation could incorrectly conclude that an expedited grace period elapsed in zero time, which would be bad. One could rely on counter size to prevent this from happening in practice, but the goal is to formally validate this code, so it needs to be fixed anyway. This commit therefore checks the gap between the two counters before incrementing sync_sched_expedited_started, and if the gap is too large, does a normal grace period instead. Overflow is thus only possible if there are more than about 3.5 billion threads on 32-bit systems, which can be excluded until such time as task_struct fits into a single byte and 4G/4G patches are accepted into mainline. It is also easy to encode this limitation into mechanical theorem provers. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutree.c | 62 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 89148860e2b..678905555ca 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -2249,8 +2249,8 @@ void synchronize_rcu_bh(void) } EXPORT_SYMBOL_GPL(synchronize_rcu_bh); -static atomic_t sync_sched_expedited_started = ATOMIC_INIT(0); -static atomic_t sync_sched_expedited_done = ATOMIC_INIT(0); +static atomic_long_t sync_sched_expedited_started = ATOMIC_LONG_INIT(0); +static atomic_long_t sync_sched_expedited_done = ATOMIC_LONG_INIT(0); static int synchronize_sched_expedited_cpu_stop(void *data) { @@ -2308,10 +2308,30 @@ static int synchronize_sched_expedited_cpu_stop(void *data) */ void synchronize_sched_expedited(void) { - int firstsnap, s, snap, trycount = 0; + long firstsnap, s, snap; + int trycount = 0; - /* Note that atomic_inc_return() implies full memory barrier. */ - firstsnap = snap = atomic_inc_return(&sync_sched_expedited_started); + /* + * If we are in danger of counter wrap, just do synchronize_sched(). + * By allowing sync_sched_expedited_started to advance no more than + * ULONG_MAX/8 ahead of sync_sched_expedited_done, we are ensuring + * that more than 3.5 billion CPUs would be required to force a + * counter wrap on a 32-bit system. Quite a few more CPUs would of + * course be required on a 64-bit system. + */ + if (ULONG_CMP_GE((ulong)atomic_read(&sync_sched_expedited_started), + (ulong)atomic_read(&sync_sched_expedited_done) + + ULONG_MAX / 8)) { + synchronize_sched(); + return; + } + + /* + * Take a ticket. Note that atomic_inc_return() implies a + * full memory barrier. + */ + snap = atomic_long_inc_return(&sync_sched_expedited_started); + firstsnap = snap; get_online_cpus(); WARN_ON_ONCE(cpu_is_offline(raw_smp_processor_id())); @@ -2324,6 +2344,13 @@ void synchronize_sched_expedited(void) NULL) == -EAGAIN) { put_online_cpus(); + /* Check to see if someone else did our work for us. */ + s = atomic_long_read(&sync_sched_expedited_done); + if (ULONG_CMP_GE((ulong)s, (ulong)firstsnap)) { + smp_mb(); /* ensure test happens before caller kfree */ + return; + } + /* No joy, try again later. Or just synchronize_sched(). */ if (trycount++ < 10) { udelay(trycount * num_online_cpus()); @@ -2332,23 +2359,22 @@ void synchronize_sched_expedited(void) return; } - /* Check to see if someone else did our work for us. */ - s = atomic_read(&sync_sched_expedited_done); - if (UINT_CMP_GE((unsigned)s, (unsigned)firstsnap)) { + /* Recheck to see if someone else did our work for us. */ + s = atomic_long_read(&sync_sched_expedited_done); + if (ULONG_CMP_GE((ulong)s, (ulong)firstsnap)) { smp_mb(); /* ensure test happens before caller kfree */ return; } /* * Refetching sync_sched_expedited_started allows later - * callers to piggyback on our grace period. We subtract - * 1 to get the same token that the last incrementer got. - * We retry after they started, so our grace period works - * for them, and they started after our first try, so their - * grace period works for us. + * callers to piggyback on our grace period. We retry + * after they started, so our grace period works for them, + * and they started after our first try, so their grace + * period works for us. */ get_online_cpus(); - snap = atomic_read(&sync_sched_expedited_started); + snap = atomic_long_read(&sync_sched_expedited_started); smp_mb(); /* ensure read is before try_stop_cpus(). */ } @@ -2356,15 +2382,15 @@ void synchronize_sched_expedited(void) * Everyone up to our most recent fetch is covered by our grace * period. Update the counter, but only if our work is still * relevant -- which it won't be if someone who started later - * than we did beat us to the punch. + * than we did already did their update. */ do { - s = atomic_read(&sync_sched_expedited_done); - if (UINT_CMP_GE((unsigned)s, (unsigned)snap)) { + s = atomic_long_read(&sync_sched_expedited_done); + if (ULONG_CMP_GE((ulong)s, (ulong)snap)) { smp_mb(); /* ensure test happens before caller kfree */ break; } - } while (atomic_cmpxchg(&sync_sched_expedited_done, s, snap) != s); + } while (atomic_long_cmpxchg(&sync_sched_expedited_done, s, snap) != s); put_online_cpus(); } -- cgit v1.2.3 From 40694d6644d5cca28531707559466122eb212d8b Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 11 Oct 2012 15:24:03 -0700 Subject: rcu: Move synchronize_sched_expedited() state to rcu_state Tracing (debugfs) of expedited RCU primitives is required, which in turn requires that the relevant data be located where the tracing code can find it, not in its current static global variables in kernel/rcutree.c. This commit therefore moves sync_sched_expedited_started and sync_sched_expedited_done to the rcu_state structure, as fields ->expedited_start and ->expedited_done, respectively. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutree.c | 20 +++++++++----------- kernel/rcutree.h | 3 +++ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 678905555ca..3c72e5e5528 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -2249,9 +2249,6 @@ void synchronize_rcu_bh(void) } EXPORT_SYMBOL_GPL(synchronize_rcu_bh); -static atomic_long_t sync_sched_expedited_started = ATOMIC_LONG_INIT(0); -static atomic_long_t sync_sched_expedited_done = ATOMIC_LONG_INIT(0); - static int synchronize_sched_expedited_cpu_stop(void *data) { /* @@ -2310,6 +2307,7 @@ void synchronize_sched_expedited(void) { long firstsnap, s, snap; int trycount = 0; + struct rcu_state *rsp = &rcu_sched_state; /* * If we are in danger of counter wrap, just do synchronize_sched(). @@ -2319,8 +2317,8 @@ void synchronize_sched_expedited(void) * counter wrap on a 32-bit system. Quite a few more CPUs would of * course be required on a 64-bit system. */ - if (ULONG_CMP_GE((ulong)atomic_read(&sync_sched_expedited_started), - (ulong)atomic_read(&sync_sched_expedited_done) + + if (ULONG_CMP_GE((ulong)atomic_long_read(&rsp->expedited_start), + (ulong)atomic_long_read(&rsp->expedited_done) + ULONG_MAX / 8)) { synchronize_sched(); return; @@ -2330,7 +2328,7 @@ void synchronize_sched_expedited(void) * Take a ticket. Note that atomic_inc_return() implies a * full memory barrier. */ - snap = atomic_long_inc_return(&sync_sched_expedited_started); + snap = atomic_long_inc_return(&rsp->expedited_start); firstsnap = snap; get_online_cpus(); WARN_ON_ONCE(cpu_is_offline(raw_smp_processor_id())); @@ -2345,7 +2343,7 @@ void synchronize_sched_expedited(void) put_online_cpus(); /* Check to see if someone else did our work for us. */ - s = atomic_long_read(&sync_sched_expedited_done); + s = atomic_long_read(&rsp->expedited_done); if (ULONG_CMP_GE((ulong)s, (ulong)firstsnap)) { smp_mb(); /* ensure test happens before caller kfree */ return; @@ -2360,7 +2358,7 @@ void synchronize_sched_expedited(void) } /* Recheck to see if someone else did our work for us. */ - s = atomic_long_read(&sync_sched_expedited_done); + s = atomic_long_read(&rsp->expedited_done); if (ULONG_CMP_GE((ulong)s, (ulong)firstsnap)) { smp_mb(); /* ensure test happens before caller kfree */ return; @@ -2374,7 +2372,7 @@ void synchronize_sched_expedited(void) * period works for us. */ get_online_cpus(); - snap = atomic_long_read(&sync_sched_expedited_started); + snap = atomic_long_read(&rsp->expedited_start); smp_mb(); /* ensure read is before try_stop_cpus(). */ } @@ -2385,12 +2383,12 @@ void synchronize_sched_expedited(void) * than we did already did their update. */ do { - s = atomic_long_read(&sync_sched_expedited_done); + s = atomic_long_read(&rsp->expedited_done); if (ULONG_CMP_GE((ulong)s, (ulong)snap)) { smp_mb(); /* ensure test happens before caller kfree */ break; } - } while (atomic_long_cmpxchg(&sync_sched_expedited_done, s, snap) != s); + } while (atomic_long_cmpxchg(&rsp->expedited_done, s, snap) != s); put_online_cpus(); } diff --git a/kernel/rcutree.h b/kernel/rcutree.h index a7c945d149c..88f3d9d5971 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h @@ -404,6 +404,9 @@ struct rcu_state { /* _rcu_barrier(). */ /* End of fields guarded by barrier_mutex. */ + atomic_long_t expedited_start; /* Starting ticket. */ + atomic_long_t expedited_done; /* Done ticket. */ + unsigned long jiffies_force_qs; /* Time at which to invoke */ /* force_quiescent_state(). */ unsigned long n_force_qs; /* Number of calls to */ -- cgit v1.2.3 From a30489c5228fba6f16b4c740a0292879ef13371e Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 11 Oct 2012 16:18:09 -0700 Subject: rcu: Instrument synchronize_rcu_expedited() for debugfs tracing This commit adds the counters to rcu_state and updates them in synchronize_rcu_expedited() to provide the data needed for debugfs tracing. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutree.c | 18 +++++++++++++++--- kernel/rcutree.h | 9 +++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 3c72e5e5528..b966d56ebb5 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -2321,6 +2321,7 @@ void synchronize_sched_expedited(void) (ulong)atomic_long_read(&rsp->expedited_done) + ULONG_MAX / 8)) { synchronize_sched(); + atomic_long_inc(&rsp->expedited_wrap); return; } @@ -2341,11 +2342,14 @@ void synchronize_sched_expedited(void) synchronize_sched_expedited_cpu_stop, NULL) == -EAGAIN) { put_online_cpus(); + atomic_long_inc(&rsp->expedited_tryfail); /* Check to see if someone else did our work for us. */ s = atomic_long_read(&rsp->expedited_done); if (ULONG_CMP_GE((ulong)s, (ulong)firstsnap)) { - smp_mb(); /* ensure test happens before caller kfree */ + /* ensure test happens before caller kfree */ + smp_mb__before_atomic_inc(); /* ^^^ */ + atomic_long_inc(&rsp->expedited_workdone1); return; } @@ -2354,13 +2358,16 @@ void synchronize_sched_expedited(void) udelay(trycount * num_online_cpus()); } else { synchronize_sched(); + atomic_long_inc(&rsp->expedited_normal); return; } /* Recheck to see if someone else did our work for us. */ s = atomic_long_read(&rsp->expedited_done); if (ULONG_CMP_GE((ulong)s, (ulong)firstsnap)) { - smp_mb(); /* ensure test happens before caller kfree */ + /* ensure test happens before caller kfree */ + smp_mb__before_atomic_inc(); /* ^^^ */ + atomic_long_inc(&rsp->expedited_workdone2); return; } @@ -2375,6 +2382,7 @@ void synchronize_sched_expedited(void) snap = atomic_long_read(&rsp->expedited_start); smp_mb(); /* ensure read is before try_stop_cpus(). */ } + atomic_long_inc(&rsp->expedited_stoppedcpus); /* * Everyone up to our most recent fetch is covered by our grace @@ -2383,12 +2391,16 @@ void synchronize_sched_expedited(void) * than we did already did their update. */ do { + atomic_long_inc(&rsp->expedited_done_tries); s = atomic_long_read(&rsp->expedited_done); if (ULONG_CMP_GE((ulong)s, (ulong)snap)) { - smp_mb(); /* ensure test happens before caller kfree */ + /* ensure test happens before caller kfree */ + smp_mb__before_atomic_inc(); /* ^^^ */ + atomic_long_inc(&rsp->expedited_done_lost); break; } } while (atomic_long_cmpxchg(&rsp->expedited_done, s, snap) != s); + atomic_long_inc(&rsp->expedited_done_exit); put_online_cpus(); } diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 88f3d9d5971..d274af35721 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h @@ -406,6 +406,15 @@ struct rcu_state { atomic_long_t expedited_start; /* Starting ticket. */ atomic_long_t expedited_done; /* Done ticket. */ + atomic_long_t expedited_wrap; /* # near-wrap incidents. */ + atomic_long_t expedited_tryfail; /* # acquisition failures. */ + atomic_long_t expedited_workdone1; /* # done by others #1. */ + atomic_long_t expedited_workdone2; /* # done by others #2. */ + atomic_long_t expedited_normal; /* # fallbacks to normal. */ + atomic_long_t expedited_stoppedcpus; /* # successful stop_cpus. */ + atomic_long_t expedited_done_tries; /* # tries to update _done. */ + atomic_long_t expedited_done_lost; /* # times beaten to _done. */ + atomic_long_t expedited_done_exit; /* # times exited _done loop. */ unsigned long jiffies_force_qs; /* Time at which to invoke */ /* force_quiescent_state(). */ -- cgit v1.2.3 From 573bcd40d221bd6d7cebf27dee120bd242f5feb5 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 20 Sep 2012 08:51:02 +0800 Subject: rcu: Create directory for each flavor of rcu This patch will create subdirectory according to each flavor of rcu, the new structure will be: /debugfs/rcu/ -> rsp_0 -> rsp_1 -> ... So we can go to '/debugfs/rcu/rsp_0' and get the cpu info of rsp_0 there. The flavors of RCU are currently rcu_bh, rcu_preempt, and rcu_sched. Signed-off-by: Michael Wang Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index 693513bc50e..62223a27f98 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -446,12 +446,20 @@ static struct dentry *rcudir; static int __init rcutree_trace_init(void) { + struct rcu_state *rsp; struct dentry *retval; + struct dentry *rspdir; rcudir = debugfs_create_dir("rcu", NULL); if (!rcudir) goto free_out; + for_each_rcu_flavor(rsp) { + rspdir = debugfs_create_dir(rsp->name, rcudir); + if (!rspdir) + goto free_out; + } + retval = debugfs_create_file("rcubarrier", 0444, rcudir, NULL, &rcubarrier_fops); if (!retval) -- cgit v1.2.3 From 374b928ee8061fdbb0b527fb3924080ba2437767 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 20 Sep 2012 08:51:03 +0800 Subject: rcu: Fundamental facility for 'CPU units sequence reading' This patch add the fundamental facility used by the following patches, so we can implement the 'CPU units sequence reading' later. This helps us avoid losing data when there are too many CPUs and too small of a buffer, since this new approach allows userspace to read out the data one CPU at a time. Thus, if the buffer is not large enough, userspace will get whatever CPUs fit, and can then issue another read for the remainder of the data. Signed-off-by: Michael Wang Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index 62223a27f98..0dfe9b512f0 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -46,6 +46,36 @@ #define RCU_TREE_NONCORE #include "rcutree.h" +static int r_open(struct inode *inode, struct file *file, + const struct seq_operations *op) +{ + int ret = seq_open(file, op); + if (!ret) { + struct seq_file *m = (struct seq_file *)file->private_data; + m->private = inode->i_private; + } + return ret; +} + +static void *r_start(struct seq_file *m, loff_t *pos) +{ + struct rcu_state *rsp = (struct rcu_state *)m->private; + *pos = cpumask_next(*pos - 1, cpu_possible_mask); + if ((*pos) < nr_cpu_ids) + return per_cpu_ptr(rsp->rda, *pos); + return NULL; +} + +static void *r_next(struct seq_file *m, void *v, loff_t *pos) +{ + (*pos)++; + return r_start(m, pos); +} + +static void r_stop(struct seq_file *m, void *v) +{ +} + static int show_rcubarrier(struct seq_file *m, void *unused) { struct rcu_state *rsp; -- cgit v1.2.3 From 878eda72e24d11e463a25b1dc7097a8d953f17cb Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 20 Sep 2012 08:51:04 +0800 Subject: rcu: Optimize the 'rcudata' for RCU trace This patch implements the new 'rcudata' interface under each rsp directory, by using the 'CPU units sequence reading', thus avoiding loss of tracing data. Signed-off-by: Michael Wang Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index 0dfe9b512f0..a11522f62c7 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -174,6 +174,32 @@ static const struct file_operations rcudata_fops = { .release = single_release, }; +static int new_show_rcudata(struct seq_file *m, void *v) +{ + print_one_rcu_data(m, (struct rcu_data *)v); + return 0; +} + +static const struct seq_operations new_rcudate_op = { + .start = r_start, + .next = r_next, + .stop = r_stop, + .show = new_show_rcudata, +}; + +static int new_rcudata_open(struct inode *inode, struct file *file) +{ + return r_open(inode, file, &new_rcudate_op); +} + +static const struct file_operations new_rcudata_fops = { + .owner = THIS_MODULE, + .open = new_rcudata_open, + .read = seq_read, + .llseek = no_llseek, + .release = seq_release, +}; + static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp) { if (!rdp->beenonline) @@ -488,6 +514,11 @@ static int __init rcutree_trace_init(void) rspdir = debugfs_create_dir(rsp->name, rcudir); if (!rspdir) goto free_out; + + retval = debugfs_create_file("rcudata", 0444, + rspdir, rsp, &new_rcudata_fops); + if (!retval) + goto free_out; } retval = debugfs_create_file("rcubarrier", 0444, rcudir, -- cgit v1.2.3 From d29200efa2ad7a1dc516a1048faf98dcc01b9fef Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 20 Sep 2012 08:51:05 +0800 Subject: rcu: Optimize the 'rcudata.csv' for RCU trace This patch implements the new 'rcudata.csv' interface under each rsp directory, by using the 'CPU units sequence reading', thus avoiding loss of tracing data. Signed-off-by: Michael Wang Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index a11522f62c7..e387a642632 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -267,6 +267,43 @@ static const struct file_operations rcudata_csv_fops = { .release = single_release, }; +static int new_show_rcudata_csv(struct seq_file *m, void *v) +{ + struct rcu_data *rdp = (struct rcu_data *)v; + if (cpumask_first(cpu_possible_mask) == rdp->cpu) { + seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pq\","); + seq_puts(m, "\"dt\",\"dt nesting\",\"dt NMI nesting\",\"df\","); + seq_puts(m, "\"of\",\"qll\",\"ql\",\"qs\""); +#ifdef CONFIG_RCU_BOOST + seq_puts(m, "\"kt\",\"ktl\""); +#endif /* #ifdef CONFIG_RCU_BOOST */ + seq_puts(m, ",\"b\",\"ci\",\"co\",\"ca\"\n"); + } + + print_one_rcu_data_csv(m, rdp); + return 0; +} + +static const struct seq_operations new_rcudate_csv_op = { + .start = r_start, + .next = r_next, + .stop = r_stop, + .show = new_show_rcudata_csv, +}; + +static int new_rcudata_csv_open(struct inode *inode, struct file *file) +{ + return r_open(inode, file, &new_rcudate_csv_op); +} + +static const struct file_operations new_rcudata_csv_fops = { + .owner = THIS_MODULE, + .open = new_rcudata_csv_open, + .read = seq_read, + .llseek = no_llseek, + .release = seq_release, +}; + #ifdef CONFIG_RCU_BOOST static void print_one_rcu_node_boost(struct seq_file *m, struct rcu_node *rnp) @@ -519,6 +556,11 @@ static int __init rcutree_trace_init(void) rspdir, rsp, &new_rcudata_fops); if (!retval) goto free_out; + + retval = debugfs_create_file("rcudata.csv", 0444, + rspdir, rsp, &new_rcudata_csv_fops); + if (!retval) + goto free_out; } retval = debugfs_create_file("rcubarrier", 0444, rcudir, -- cgit v1.2.3 From 51d0f16d49f6a99189e80c50e18a12325664ef41 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 20 Sep 2012 08:51:06 +0800 Subject: rcu: Optimize the 'rcu_pending' for RCU trace This patch implements the new 'rcu_pending' interface under each rsp directory, by using the 'CPU units sequence reading', thus avoiding loss of tracing data. Signed-off-by: Michael Wang Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index e387a642632..8b248672221 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -467,6 +467,8 @@ static const struct file_operations rcugp_fops = { static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp) { + if (!rdp->beenonline) + return; seq_printf(m, "%3d%cnp=%ld ", rdp->cpu, cpu_is_offline(rdp->cpu) ? '!' : ' ', @@ -485,16 +487,12 @@ static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp) static int show_rcu_pending(struct seq_file *m, void *unused) { int cpu; - struct rcu_data *rdp; struct rcu_state *rsp; for_each_rcu_flavor(rsp) { seq_printf(m, "%s:\n", rsp->name); - for_each_possible_cpu(cpu) { - rdp = per_cpu_ptr(rsp->rda, cpu); - if (rdp->beenonline) - print_one_rcu_pending(m, rdp); - } + for_each_possible_cpu(cpu) + print_one_rcu_pending(m, per_cpu_ptr(rsp->rda, cpu)); } return 0; } @@ -512,6 +510,32 @@ static const struct file_operations rcu_pending_fops = { .release = single_release, }; +static int new_show_rcu_pending(struct seq_file *m, void *v) +{ + print_one_rcu_pending(m, (struct rcu_data *)v); + return 0; +} + +static const struct seq_operations new_rcu_pending_op = { + .start = r_start, + .next = r_next, + .stop = r_stop, + .show = new_show_rcu_pending, +}; + +static int new_rcu_pending_open(struct inode *inode, struct file *file) +{ + return r_open(inode, file, &new_rcu_pending_op); +} + +static const struct file_operations new_rcu_pending_fops = { + .owner = THIS_MODULE, + .open = new_rcu_pending_open, + .read = seq_read, + .llseek = no_llseek, + .release = seq_release, +}; + static int show_rcutorture(struct seq_file *m, void *unused) { seq_printf(m, "rcutorture test sequence: %lu %s\n", @@ -561,6 +585,11 @@ static int __init rcutree_trace_init(void) rspdir, rsp, &new_rcudata_csv_fops); if (!retval) goto free_out; + + retval = debugfs_create_file("rcu_pending", 0444, + rspdir, rsp, &new_rcu_pending_fops); + if (!retval) + goto free_out; } retval = debugfs_create_file("rcubarrier", 0444, rcudir, -- cgit v1.2.3 From c011c41f11c4bf9b0c8d489a458770c24aeb2ebd Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 20 Sep 2012 08:51:07 +0800 Subject: rcu: Replace the old interface with the new one This patch removed the old RCU debugfs interface and replaced it with the new one. Signed-off-by: Michael Wang Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 148 ++++++++----------------------------------------- 1 file changed, 24 insertions(+), 124 deletions(-) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index 8b248672221..0e2ab6427b6 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -148,53 +148,27 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); } -static int show_rcudata(struct seq_file *m, void *unused) -{ - int cpu; - struct rcu_state *rsp; - - for_each_rcu_flavor(rsp) { - seq_printf(m, "%s:\n", rsp->name); - for_each_possible_cpu(cpu) - print_one_rcu_data(m, per_cpu_ptr(rsp->rda, cpu)); - } - return 0; -} - -static int rcudata_open(struct inode *inode, struct file *file) -{ - return single_open(file, show_rcudata, NULL); -} - -static const struct file_operations rcudata_fops = { - .owner = THIS_MODULE, - .open = rcudata_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int new_show_rcudata(struct seq_file *m, void *v) +static int show_rcudata(struct seq_file *m, void *v) { print_one_rcu_data(m, (struct rcu_data *)v); return 0; } -static const struct seq_operations new_rcudate_op = { +static const struct seq_operations rcudate_op = { .start = r_start, .next = r_next, .stop = r_stop, - .show = new_show_rcudata, + .show = show_rcudata, }; -static int new_rcudata_open(struct inode *inode, struct file *file) +static int rcudata_open(struct inode *inode, struct file *file) { - return r_open(inode, file, &new_rcudate_op); + return r_open(inode, file, &rcudate_op); } -static const struct file_operations new_rcudata_fops = { +static const struct file_operations rcudata_fops = { .owner = THIS_MODULE, - .open = new_rcudata_open, + .open = rcudata_open, .read = seq_read, .llseek = no_llseek, .release = seq_release, @@ -234,40 +208,7 @@ static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp) rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); } -static int show_rcudata_csv(struct seq_file *m, void *unused) -{ - int cpu; - struct rcu_state *rsp; - - seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pq\","); - seq_puts(m, "\"dt\",\"dt nesting\",\"dt NMI nesting\",\"df\","); - seq_puts(m, "\"of\",\"qll\",\"ql\",\"qs\""); -#ifdef CONFIG_RCU_BOOST - seq_puts(m, "\"kt\",\"ktl\""); -#endif /* #ifdef CONFIG_RCU_BOOST */ - seq_puts(m, ",\"b\",\"ci\",\"co\",\"ca\"\n"); - for_each_rcu_flavor(rsp) { - seq_printf(m, "\"%s:\"\n", rsp->name); - for_each_possible_cpu(cpu) - print_one_rcu_data_csv(m, per_cpu_ptr(rsp->rda, cpu)); - } - return 0; -} - -static int rcudata_csv_open(struct inode *inode, struct file *file) -{ - return single_open(file, show_rcudata_csv, NULL); -} - -static const struct file_operations rcudata_csv_fops = { - .owner = THIS_MODULE, - .open = rcudata_csv_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int new_show_rcudata_csv(struct seq_file *m, void *v) +static int show_rcudata_csv(struct seq_file *m, void *v) { struct rcu_data *rdp = (struct rcu_data *)v; if (cpumask_first(cpu_possible_mask) == rdp->cpu) { @@ -284,21 +225,21 @@ static int new_show_rcudata_csv(struct seq_file *m, void *v) return 0; } -static const struct seq_operations new_rcudate_csv_op = { +static const struct seq_operations rcudate_csv_op = { .start = r_start, .next = r_next, .stop = r_stop, - .show = new_show_rcudata_csv, + .show = show_rcudata_csv, }; -static int new_rcudata_csv_open(struct inode *inode, struct file *file) +static int rcudata_csv_open(struct inode *inode, struct file *file) { - return r_open(inode, file, &new_rcudate_csv_op); + return r_open(inode, file, &rcudate_csv_op); } -static const struct file_operations new_rcudata_csv_fops = { +static const struct file_operations rcudata_csv_fops = { .owner = THIS_MODULE, - .open = new_rcudata_csv_open, + .open = rcudata_csv_open, .read = seq_read, .llseek = no_llseek, .release = seq_release, @@ -484,53 +425,27 @@ static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp) rdp->n_rp_need_nothing); } -static int show_rcu_pending(struct seq_file *m, void *unused) -{ - int cpu; - struct rcu_state *rsp; - - for_each_rcu_flavor(rsp) { - seq_printf(m, "%s:\n", rsp->name); - for_each_possible_cpu(cpu) - print_one_rcu_pending(m, per_cpu_ptr(rsp->rda, cpu)); - } - return 0; -} - -static int rcu_pending_open(struct inode *inode, struct file *file) -{ - return single_open(file, show_rcu_pending, NULL); -} - -static const struct file_operations rcu_pending_fops = { - .owner = THIS_MODULE, - .open = rcu_pending_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int new_show_rcu_pending(struct seq_file *m, void *v) +static int show_rcu_pending(struct seq_file *m, void *v) { print_one_rcu_pending(m, (struct rcu_data *)v); return 0; } -static const struct seq_operations new_rcu_pending_op = { +static const struct seq_operations rcu_pending_op = { .start = r_start, .next = r_next, .stop = r_stop, - .show = new_show_rcu_pending, + .show = show_rcu_pending, }; -static int new_rcu_pending_open(struct inode *inode, struct file *file) +static int rcu_pending_open(struct inode *inode, struct file *file) { - return r_open(inode, file, &new_rcu_pending_op); + return r_open(inode, file, &rcu_pending_op); } -static const struct file_operations new_rcu_pending_fops = { +static const struct file_operations rcu_pending_fops = { .owner = THIS_MODULE, - .open = new_rcu_pending_open, + .open = rcu_pending_open, .read = seq_read, .llseek = no_llseek, .release = seq_release, @@ -577,17 +492,17 @@ static int __init rcutree_trace_init(void) goto free_out; retval = debugfs_create_file("rcudata", 0444, - rspdir, rsp, &new_rcudata_fops); + rspdir, rsp, &rcudata_fops); if (!retval) goto free_out; retval = debugfs_create_file("rcudata.csv", 0444, - rspdir, rsp, &new_rcudata_csv_fops); + rspdir, rsp, &rcudata_csv_fops); if (!retval) goto free_out; retval = debugfs_create_file("rcu_pending", 0444, - rspdir, rsp, &new_rcu_pending_fops); + rspdir, rsp, &rcu_pending_fops); if (!retval) goto free_out; } @@ -597,16 +512,6 @@ static int __init rcutree_trace_init(void) if (!retval) goto free_out; - retval = debugfs_create_file("rcudata", 0444, rcudir, - NULL, &rcudata_fops); - if (!retval) - goto free_out; - - retval = debugfs_create_file("rcudata.csv", 0444, rcudir, - NULL, &rcudata_csv_fops); - if (!retval) - goto free_out; - if (rcu_boost_trace_create_file(rcudir)) goto free_out; @@ -619,11 +524,6 @@ static int __init rcutree_trace_init(void) if (!retval) goto free_out; - retval = debugfs_create_file("rcu_pending", 0444, rcudir, - NULL, &rcu_pending_fops); - if (!retval) - goto free_out; - retval = debugfs_create_file("rcutorture", 0444, rcudir, NULL, &rcutorture_fops); if (!retval) -- cgit v1.2.3 From 5f4ee1fa16fa1bee673b75722ca43350a74fba36 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 20 Sep 2012 08:51:08 +0800 Subject: rcu: Remove the interface "rcudata.csv" This patch removes the interface "rcudata.csv" since it is apparently not used. Signed-off-by: Michael Wang Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 76 -------------------------------------------------- 1 file changed, 76 deletions(-) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index 0e2ab6427b6..bcc4865fea8 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -174,77 +174,6 @@ static const struct file_operations rcudata_fops = { .release = seq_release, }; -static void print_one_rcu_data_csv(struct seq_file *m, struct rcu_data *rdp) -{ - if (!rdp->beenonline) - return; - seq_printf(m, "%d,%s,%lu,%lu,%d,%d", - rdp->cpu, - cpu_is_offline(rdp->cpu) ? "\"N\"" : "\"Y\"", - rdp->completed, rdp->gpnum, - rdp->passed_quiesce, rdp->qs_pending); - seq_printf(m, ",%d,%llx,%d,%lu", - atomic_read(&rdp->dynticks->dynticks), - rdp->dynticks->dynticks_nesting, - rdp->dynticks->dynticks_nmi_nesting, - rdp->dynticks_fqs); - seq_printf(m, ",%lu", rdp->offline_fqs); - seq_printf(m, ",%ld,%ld,\"%c%c%c%c\"", rdp->qlen_lazy, rdp->qlen, - ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] != - rdp->nxttail[RCU_NEXT_TAIL]], - ".R"[rdp->nxttail[RCU_WAIT_TAIL] != - rdp->nxttail[RCU_NEXT_READY_TAIL]], - ".W"[rdp->nxttail[RCU_DONE_TAIL] != - rdp->nxttail[RCU_WAIT_TAIL]], - ".D"[&rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL]]); -#ifdef CONFIG_RCU_BOOST - seq_printf(m, ",%d,\"%c\"", - per_cpu(rcu_cpu_has_work, rdp->cpu), - convert_kthread_status(per_cpu(rcu_cpu_kthread_status, - rdp->cpu))); -#endif /* #ifdef CONFIG_RCU_BOOST */ - seq_printf(m, ",%ld", rdp->blimit); - seq_printf(m, ",%lu,%lu,%lu\n", - rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); -} - -static int show_rcudata_csv(struct seq_file *m, void *v) -{ - struct rcu_data *rdp = (struct rcu_data *)v; - if (cpumask_first(cpu_possible_mask) == rdp->cpu) { - seq_puts(m, "\"CPU\",\"Online?\",\"c\",\"g\",\"pq\",\"pq\","); - seq_puts(m, "\"dt\",\"dt nesting\",\"dt NMI nesting\",\"df\","); - seq_puts(m, "\"of\",\"qll\",\"ql\",\"qs\""); -#ifdef CONFIG_RCU_BOOST - seq_puts(m, "\"kt\",\"ktl\""); -#endif /* #ifdef CONFIG_RCU_BOOST */ - seq_puts(m, ",\"b\",\"ci\",\"co\",\"ca\"\n"); - } - - print_one_rcu_data_csv(m, rdp); - return 0; -} - -static const struct seq_operations rcudate_csv_op = { - .start = r_start, - .next = r_next, - .stop = r_stop, - .show = show_rcudata_csv, -}; - -static int rcudata_csv_open(struct inode *inode, struct file *file) -{ - return r_open(inode, file, &rcudate_csv_op); -} - -static const struct file_operations rcudata_csv_fops = { - .owner = THIS_MODULE, - .open = rcudata_csv_open, - .read = seq_read, - .llseek = no_llseek, - .release = seq_release, -}; - #ifdef CONFIG_RCU_BOOST static void print_one_rcu_node_boost(struct seq_file *m, struct rcu_node *rnp) @@ -496,11 +425,6 @@ static int __init rcutree_trace_init(void) if (!retval) goto free_out; - retval = debugfs_create_file("rcudata.csv", 0444, - rspdir, rsp, &rcudata_csv_fops); - if (!retval) - goto free_out; - retval = debugfs_create_file("rcu_pending", 0444, rspdir, rsp, &rcu_pending_fops); if (!retval) -- cgit v1.2.3 From 42c3533eee88e012e1aa3c4d6d2cc53354130e24 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 28 Sep 2012 10:49:58 -0700 Subject: rcu: Fix tracing formatting The rcu_state structure's ->completed field is unsigned long, so this commit adjusts show_one_rcugp()'s printf() format to suit. Also add the required ACCESS_ONCE() directives while we are in this function. Signed-off-by: Paul E. McKenney --- kernel/rcutree.c | 4 ++-- kernel/rcutree_trace.c | 21 ++++++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/kernel/rcutree.c b/kernel/rcutree.c index b966d56ebb5..8ed9c481db0 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -68,8 +68,8 @@ static struct lock_class_key rcu_fqs_class[RCU_NUM_LVLS]; .level = { &sname##_state.node[0] }, \ .call = cr, \ .fqs_state = RCU_GP_IDLE, \ - .gpnum = -300, \ - .completed = -300, \ + .gpnum = 0UL - 300UL, \ + .completed = 0UL - 300UL, \ .orphan_lock = __RAW_SPIN_LOCK_UNLOCKED(&sname##_state.orphan_lock), \ .orphan_nxttail = &sname##_state.orphan_nxtlist, \ .orphan_donetail = &sname##_state.orphan_donelist, \ diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index bcc4865fea8..3312ed7e411 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -46,6 +46,8 @@ #define RCU_TREE_NONCORE #include "rcutree.h" +#define ulong2long(a) (*(long *)(&(a))) + static int r_open(struct inode *inode, struct file *file, const struct seq_operations *op) { @@ -116,10 +118,10 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) { if (!rdp->beenonline) return; - seq_printf(m, "%3d%cc=%lu g=%lu pq=%d qp=%d", + seq_printf(m, "%3d%cc=%ld g=%ld pq=%d qp=%d", rdp->cpu, cpu_is_offline(rdp->cpu) ? '!' : ' ', - rdp->completed, rdp->gpnum, + ulong2long(rdp->completed), ulong2long(rdp->gpnum), rdp->passed_quiesce, rdp->qs_pending); seq_printf(m, " dt=%d/%llx/%d df=%lu", atomic_read(&rdp->dynticks->dynticks), @@ -246,8 +248,9 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp) struct rcu_node *rnp; gpnum = rsp->gpnum; - seq_printf(m, "%s: c=%lu g=%lu s=%d jfq=%ld j=%x ", - rsp->name, rsp->completed, gpnum, rsp->fqs_state, + seq_printf(m, "%s: c=%ld g=%ld s=%d jfq=%ld j=%x ", + rsp->name, ulong2long(rsp->completed), ulong2long(gpnum), + rsp->fqs_state, (long)(rsp->jiffies_force_qs - jiffies), (int)(jiffies & 0xffff)); seq_printf(m, "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld/%ld\n", @@ -301,16 +304,16 @@ static void show_one_rcugp(struct seq_file *m, struct rcu_state *rsp) struct rcu_node *rnp = &rsp->node[0]; raw_spin_lock_irqsave(&rnp->lock, flags); - completed = rsp->completed; - gpnum = rsp->gpnum; - if (rsp->completed == rsp->gpnum) + completed = ACCESS_ONCE(rsp->completed); + gpnum = ACCESS_ONCE(rsp->gpnum); + if (completed == gpnum) gpage = 0; else gpage = jiffies - rsp->gp_start; gpmax = rsp->gp_max; raw_spin_unlock_irqrestore(&rnp->lock, flags); - seq_printf(m, "%s: completed=%ld gpnum=%lu age=%ld max=%ld\n", - rsp->name, completed, gpnum, gpage, gpmax); + seq_printf(m, "%s: completed=%ld gpnum=%ld age=%ld max=%ld\n", + rsp->name, ulong2long(completed), ulong2long(gpnum), gpage, gpmax); } static int show_rcugp(struct seq_file *m, void *unused) -- cgit v1.2.3 From c25e557f5d49a7cb94fad473f5ced75b6c7ce094 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Mon, 8 Oct 2012 16:59:16 +0800 Subject: rcu: split 'rcubarrier' to each flavor This patch add new 'rcubarrier' to each flavor's folder, now we could use: 'cat /debugfs/rcu/rsp/rcubarrier' to get the selected rsp info. Signed-off-by: Michael Wang Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index 3312ed7e411..65b6265531f 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -103,6 +103,28 @@ static const struct file_operations rcubarrier_fops = { .release = single_release, }; +static int new_show_rcubarrier(struct seq_file *m, void *v) +{ + struct rcu_state *rsp = (struct rcu_state *)m->private; + seq_printf(m, "bcc: %d nbd: %lu\n", + atomic_read(&rsp->barrier_cpu_count), + rsp->n_barrier_done); + return 0; +} + +static int new_rcubarrier_open(struct inode *inode, struct file *file) +{ + return single_open(file, new_show_rcubarrier, inode->i_private); +} + +static const struct file_operations new_rcubarrier_fops = { + .owner = THIS_MODULE, + .open = new_rcubarrier_open, + .read = seq_read, + .llseek = no_llseek, + .release = seq_release, +}; + #ifdef CONFIG_RCU_BOOST static char convert_kthread_status(unsigned int kthread_status) @@ -432,6 +454,11 @@ static int __init rcutree_trace_init(void) rspdir, rsp, &rcu_pending_fops); if (!retval) goto free_out; + + retval = debugfs_create_file("rcubarrier", 0444, + rspdir, rsp, &new_rcubarrier_fops); + if (!retval) + goto free_out; } retval = debugfs_create_file("rcubarrier", 0444, rcudir, -- cgit v1.2.3 From 29c67764f121a0980eb30d0314821ea631e6cfaf Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Mon, 8 Oct 2012 16:59:17 +0800 Subject: rcu: split 'rcuboost' to each flavor This patch add new 'rcuboost' to each flavor's folder, now we could use: 'cat /debugfs/rcu/rsp/rcuboost' to get the selected rsp info. Signed-off-by: Michael Wang Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index 65b6265531f..cae417de4b9 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -241,7 +241,7 @@ static const struct file_operations rcu_node_boost_fops = { .owner = THIS_MODULE, .open = rcu_node_boost_open, .read = seq_read, - .llseek = seq_lseek, + .llseek = no_llseek, .release = single_release, }; @@ -459,6 +459,15 @@ static int __init rcutree_trace_init(void) rspdir, rsp, &new_rcubarrier_fops); if (!retval) goto free_out; + +#ifdef CONFIG_RCU_BOOST + if (rsp == &rcu_preempt_state) { + retval = debugfs_create_file("rcuboost", 0444, + rspdir, NULL, &rcu_node_boost_fops); + if (!retval) + goto free_out; + } +#endif } retval = debugfs_create_file("rcubarrier", 0444, rcudir, -- cgit v1.2.3 From 66b38bc52bd1e0d00987e23bf7153c46201ff2ba Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Mon, 8 Oct 2012 16:59:18 +0800 Subject: rcu: split 'rcugp' to each flavor This patch add new 'rcugp' to each flavor's folder, now we could use: 'cat /debugfs/rcu/rsp/rcugp' to get the selected rsp info. Signed-off-by: Michael Wang Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index cae417de4b9..c90d2a917de 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -360,6 +360,26 @@ static const struct file_operations rcugp_fops = { .release = single_release, }; +static int new_show_rcugp(struct seq_file *m, void *v) +{ + struct rcu_state *rsp = (struct rcu_state *)m->private; + show_one_rcugp(m, rsp); + return 0; +} + +static int new_rcugp_open(struct inode *inode, struct file *file) +{ + return single_open(file, new_show_rcugp, inode->i_private); +} + +static const struct file_operations new_rcugp_fops = { + .owner = THIS_MODULE, + .open = new_rcugp_open, + .read = seq_read, + .llseek = no_llseek, + .release = seq_release, +}; + static void print_one_rcu_pending(struct seq_file *m, struct rcu_data *rdp) { if (!rdp->beenonline) @@ -468,6 +488,12 @@ static int __init rcutree_trace_init(void) goto free_out; } #endif + + retval = debugfs_create_file("rcugp", 0444, + rspdir, rsp, &new_rcugp_fops); + if (!retval) + goto free_out; + } retval = debugfs_create_file("rcubarrier", 0444, rcudir, -- cgit v1.2.3 From a608d84bdb832a86ad3fdb0767df31fcda9fe280 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Mon, 8 Oct 2012 16:59:19 +0800 Subject: rcu: split 'rcuhier' to each flavor This patch add new 'rcuhier' to each flavor's folder, now we could use: 'cat /debugfs/rcu/rsp/rcuhier' to get the selected rsp info. Signed-off-by: Michael Wang Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index c90d2a917de..107997ecdee 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -316,6 +316,26 @@ static const struct file_operations rcuhier_fops = { .release = single_release, }; +static int new_show_rcuhier(struct seq_file *m, void *v) +{ + struct rcu_state *rsp = (struct rcu_state *)m->private; + print_one_rcu_state(m, rsp); + return 0; +} + +static int new_rcuhier_open(struct inode *inode, struct file *file) +{ + return single_open(file, new_show_rcuhier, inode->i_private); +} + +static const struct file_operations new_rcuhier_fops = { + .owner = THIS_MODULE, + .open = new_rcuhier_open, + .read = seq_read, + .llseek = no_llseek, + .release = seq_release, +}; + static void show_one_rcugp(struct seq_file *m, struct rcu_state *rsp) { unsigned long flags; @@ -494,6 +514,10 @@ static int __init rcutree_trace_init(void) if (!retval) goto free_out; + retval = debugfs_create_file("rcuhier", 0444, + rspdir, rsp, &new_rcuhier_fops); + if (!retval) + goto free_out; } retval = debugfs_create_file("rcubarrier", 0444, rcudir, -- cgit v1.2.3 From 6ee0886ff6c81526bf6ad8521d843b934aafa5aa Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 11 Oct 2012 14:26:42 -0700 Subject: rcu: Remove old debugfs interfaces and also RCU flavor name This commit removes the old debugfs interfaces, so that the new directory-per-RCU-flavor versions remain. Because the RCU flavor is given by the directory name, there is no need to print it out, so remove the name from the printout. Signed-off-by: Michael Wang Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 190 ++++++++++++------------------------------------- 1 file changed, 44 insertions(+), 146 deletions(-) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index 107997ecdee..967115c508b 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -78,32 +78,7 @@ static void r_stop(struct seq_file *m, void *v) { } -static int show_rcubarrier(struct seq_file *m, void *unused) -{ - struct rcu_state *rsp; - - for_each_rcu_flavor(rsp) - seq_printf(m, "%s: bcc: %d nbd: %lu\n", - rsp->name, - atomic_read(&rsp->barrier_cpu_count), - rsp->n_barrier_done); - return 0; -} - -static int rcubarrier_open(struct inode *inode, struct file *file) -{ - return single_open(file, show_rcubarrier, NULL); -} - -static const struct file_operations rcubarrier_fops = { - .owner = THIS_MODULE, - .open = rcubarrier_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int new_show_rcubarrier(struct seq_file *m, void *v) +static int show_rcubarrier(struct seq_file *m, void *v) { struct rcu_state *rsp = (struct rcu_state *)m->private; seq_printf(m, "bcc: %d nbd: %lu\n", @@ -112,14 +87,14 @@ static int new_show_rcubarrier(struct seq_file *m, void *v) return 0; } -static int new_rcubarrier_open(struct inode *inode, struct file *file) +static int rcubarrier_open(struct inode *inode, struct file *file) { - return single_open(file, new_show_rcubarrier, inode->i_private); + return single_open(file, show_rcubarrier, inode->i_private); } -static const struct file_operations new_rcubarrier_fops = { +static const struct file_operations rcubarrier_fops = { .owner = THIS_MODULE, - .open = new_rcubarrier_open, + .open = rcubarrier_open, .read = seq_read, .llseek = no_llseek, .release = seq_release, @@ -245,23 +220,7 @@ static const struct file_operations rcu_node_boost_fops = { .release = single_release, }; -/* - * Create the rcuboost debugfs entry. Standard error return. - */ -static int rcu_boost_trace_create_file(struct dentry *rcudir) -{ - return !debugfs_create_file("rcuboost", 0444, rcudir, NULL, - &rcu_node_boost_fops); -} - -#else /* #ifdef CONFIG_RCU_BOOST */ - -static int rcu_boost_trace_create_file(struct dentry *rcudir) -{ - return 0; /* There cannot be an error if we didn't create it! */ -} - -#endif /* #else #ifdef CONFIG_RCU_BOOST */ +#endif /* #ifdef CONFIG_RCU_BOOST */ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp) { @@ -270,8 +229,8 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp) struct rcu_node *rnp; gpnum = rsp->gpnum; - seq_printf(m, "%s: c=%ld g=%ld s=%d jfq=%ld j=%x ", - rsp->name, ulong2long(rsp->completed), ulong2long(gpnum), + seq_printf(m, "c=%ld g=%ld s=%d jfq=%ld j=%x ", + ulong2long(rsp->completed), ulong2long(gpnum), rsp->fqs_state, (long)(rsp->jiffies_force_qs - jiffies), (int)(jiffies & 0xffff)); @@ -294,44 +253,22 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp) seq_puts(m, "\n"); } -static int show_rcuhier(struct seq_file *m, void *unused) +static int show_rcuhier(struct seq_file *m, void *v) { - struct rcu_state *rsp; - - for_each_rcu_flavor(rsp) - print_one_rcu_state(m, rsp); + struct rcu_state *rsp = (struct rcu_state *)m->private; + print_one_rcu_state(m, rsp); return 0; } static int rcuhier_open(struct inode *inode, struct file *file) { - return single_open(file, show_rcuhier, NULL); + return single_open(file, show_rcuhier, inode->i_private); } static const struct file_operations rcuhier_fops = { .owner = THIS_MODULE, .open = rcuhier_open, .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int new_show_rcuhier(struct seq_file *m, void *v) -{ - struct rcu_state *rsp = (struct rcu_state *)m->private; - print_one_rcu_state(m, rsp); - return 0; -} - -static int new_rcuhier_open(struct inode *inode, struct file *file) -{ - return single_open(file, new_show_rcuhier, inode->i_private); -} - -static const struct file_operations new_rcuhier_fops = { - .owner = THIS_MODULE, - .open = new_rcuhier_open, - .read = seq_read, .llseek = no_llseek, .release = seq_release, }; @@ -354,48 +291,26 @@ static void show_one_rcugp(struct seq_file *m, struct rcu_state *rsp) gpage = jiffies - rsp->gp_start; gpmax = rsp->gp_max; raw_spin_unlock_irqrestore(&rnp->lock, flags); - seq_printf(m, "%s: completed=%ld gpnum=%ld age=%ld max=%ld\n", - rsp->name, ulong2long(completed), ulong2long(gpnum), gpage, gpmax); + seq_printf(m, "completed=%ld gpnum=%ld age=%ld max=%ld\n", + ulong2long(completed), ulong2long(gpnum), gpage, gpmax); } -static int show_rcugp(struct seq_file *m, void *unused) +static int show_rcugp(struct seq_file *m, void *v) { - struct rcu_state *rsp; - - for_each_rcu_flavor(rsp) - show_one_rcugp(m, rsp); + struct rcu_state *rsp = (struct rcu_state *)m->private; + show_one_rcugp(m, rsp); return 0; } static int rcugp_open(struct inode *inode, struct file *file) { - return single_open(file, show_rcugp, NULL); + return single_open(file, show_rcugp, inode->i_private); } static const struct file_operations rcugp_fops = { .owner = THIS_MODULE, .open = rcugp_open, .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int new_show_rcugp(struct seq_file *m, void *v) -{ - struct rcu_state *rsp = (struct rcu_state *)m->private; - show_one_rcugp(m, rsp); - return 0; -} - -static int new_rcugp_open(struct inode *inode, struct file *file) -{ - return single_open(file, new_show_rcugp, inode->i_private); -} - -static const struct file_operations new_rcugp_fops = { - .owner = THIS_MODULE, - .open = new_rcugp_open, - .read = seq_read, .llseek = no_llseek, .release = seq_release, }; @@ -485,57 +400,40 @@ static int __init rcutree_trace_init(void) if (!rspdir) goto free_out; - retval = debugfs_create_file("rcudata", 0444, - rspdir, rsp, &rcudata_fops); - if (!retval) - goto free_out; + retval = debugfs_create_file("rcudata", 0444, + rspdir, rsp, &rcudata_fops); + if (!retval) + goto free_out; - retval = debugfs_create_file("rcu_pending", 0444, - rspdir, rsp, &rcu_pending_fops); - if (!retval) - goto free_out; + retval = debugfs_create_file("rcu_pending", 0444, + rspdir, rsp, &rcu_pending_fops); + if (!retval) + goto free_out; - retval = debugfs_create_file("rcubarrier", 0444, - rspdir, rsp, &new_rcubarrier_fops); - if (!retval) - goto free_out; + retval = debugfs_create_file("rcubarrier", 0444, + rspdir, rsp, &rcubarrier_fops); + if (!retval) + goto free_out; #ifdef CONFIG_RCU_BOOST - if (rsp == &rcu_preempt_state) { - retval = debugfs_create_file("rcuboost", 0444, - rspdir, NULL, &rcu_node_boost_fops); - if (!retval) - goto free_out; - } -#endif - - retval = debugfs_create_file("rcugp", 0444, - rspdir, rsp, &new_rcugp_fops); + if (rsp == &rcu_preempt_state) { + retval = debugfs_create_file("rcuboost", 0444, + rspdir, NULL, &rcu_node_boost_fops); if (!retval) goto free_out; + } +#endif - retval = debugfs_create_file("rcuhier", 0444, - rspdir, rsp, &new_rcuhier_fops); - if (!retval) - goto free_out; - } - - retval = debugfs_create_file("rcubarrier", 0444, rcudir, - NULL, &rcubarrier_fops); - if (!retval) - goto free_out; - - if (rcu_boost_trace_create_file(rcudir)) - goto free_out; - - retval = debugfs_create_file("rcugp", 0444, rcudir, NULL, &rcugp_fops); - if (!retval) - goto free_out; + retval = debugfs_create_file("rcugp", 0444, + rspdir, rsp, &rcugp_fops); + if (!retval) + goto free_out; - retval = debugfs_create_file("rcuhier", 0444, rcudir, - NULL, &rcuhier_fops); - if (!retval) - goto free_out; + retval = debugfs_create_file("rcuhier", 0444, + rspdir, rsp, &rcuhier_fops); + if (!retval) + goto free_out; + } retval = debugfs_create_file("rcutorture", 0444, rcudir, NULL, &rcutorture_fops); -- cgit v1.2.3 From 7bd8f2a74bcbd39f4277766f4d49441c45dd10a0 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 11 Oct 2012 17:14:32 -0700 Subject: rcu: Add tracing for synchronize_sched_expedited() This commit adds a per-RCU-flavor "rcuexp" file that dumps out statistics for synchonize_sched_expedited(). Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutree_trace.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index 967115c508b..f9512687a6e 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -173,6 +173,38 @@ static const struct file_operations rcudata_fops = { .release = seq_release, }; +static int show_rcuexp(struct seq_file *m, void *v) +{ + struct rcu_state *rsp = (struct rcu_state *)m->private; + + seq_printf(m, "s=%lu d=%lu w=%lu tf=%lu wd1=%lu wd2=%lu n=%lu sc=%lu dt=%lu dl=%lu dx=%lu\n", + atomic_long_read(&rsp->expedited_start), + atomic_long_read(&rsp->expedited_done), + atomic_long_read(&rsp->expedited_wrap), + atomic_long_read(&rsp->expedited_tryfail), + atomic_long_read(&rsp->expedited_workdone1), + atomic_long_read(&rsp->expedited_workdone2), + atomic_long_read(&rsp->expedited_normal), + atomic_long_read(&rsp->expedited_stoppedcpus), + atomic_long_read(&rsp->expedited_done_tries), + atomic_long_read(&rsp->expedited_done_lost), + atomic_long_read(&rsp->expedited_done_exit)); + return 0; +} + +static int rcuexp_open(struct inode *inode, struct file *file) +{ + return single_open(file, show_rcuexp, inode->i_private); +} + +static const struct file_operations rcuexp_fops = { + .owner = THIS_MODULE, + .open = rcuexp_open, + .read = seq_read, + .llseek = no_llseek, + .release = seq_release, +}; + #ifdef CONFIG_RCU_BOOST static void print_one_rcu_node_boost(struct seq_file *m, struct rcu_node *rnp) @@ -405,6 +437,11 @@ static int __init rcutree_trace_init(void) if (!retval) goto free_out; + retval = debugfs_create_file("rcuexp", 0444, + rspdir, rsp, &rcuexp_fops); + if (!retval) + goto free_out; + retval = debugfs_create_file("rcu_pending", 0444, rspdir, rsp, &rcu_pending_fops); if (!retval) -- cgit v1.2.3 From ff6f7778a66edc033044a6baa2459ce79519e571 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 7 Nov 2012 10:30:15 +0900 Subject: perf tools: Don't try to lookup objdump for live mode Arnaldo reported that annotation during perf top resulted in a segfault. It was because the env->arch was NULL and we don't set it for a live session. In fact, no need to look up objdump in this case since we can use system's default (native) objdump. Reported-by: Arnaldo Carvalho de Melo Signed-off-by: Namhyung Kim Cc: David Ahern Cc: Ingo Molnar Cc: Irina Tirdea Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352251815-12615-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/common.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index 5683529135b..3e975cb6232 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c @@ -199,6 +199,13 @@ out_error: int perf_session_env__lookup_objdump(struct perf_session_env *env) { + /* + * For live mode, env->arch will be NULL and we can use + * the native objdump tool. + */ + if (env->arch == NULL) + return 0; + return perf_session_env__lookup_binutils_path(env, "objdump", &objdump_path); } -- cgit v1.2.3 From b821c7325354c589ccc9611cf9e6b0d7490ed6a6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 25 Oct 2012 14:42:45 -0200 Subject: perf diff: Start moving to support matching more than two hists We want to match more than two hists, so that we can match more than two perf.data files and moreover, match hist_entries (buckets) in multiple events in a group. So the "baseline"/"leader" will instead of a ->pair pointer, use a list_head, that will link to the pairs and hists__match use it. Following that perf_evlist__link will link the hists in its evsel groups. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-2kbmzepoi544ygj9godseqpv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-diff.c | 21 ++++++++++++--------- tools/perf/ui/hist.c | 10 +++++----- tools/perf/util/hist.c | 2 ++ tools/perf/util/sort.h | 27 +++++++++++++++++++++++---- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 380683de1df..8a9db38e562 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -154,7 +154,7 @@ static double get_period_percent(struct hist_entry *he, u64 period) double perf_diff__compute_delta(struct hist_entry *he) { - struct hist_entry *pair = he->pair; + struct hist_entry *pair = hist_entry__next_pair(he); double new_percent = get_period_percent(he, he->stat.period); double old_percent = pair ? get_period_percent(pair, pair->stat.period) : 0.0; @@ -165,7 +165,7 @@ double perf_diff__compute_delta(struct hist_entry *he) double perf_diff__compute_ratio(struct hist_entry *he) { - struct hist_entry *pair = he->pair; + struct hist_entry *pair = hist_entry__next_pair(he); double new_period = he->stat.period; double old_period = pair ? pair->stat.period : 0; @@ -176,7 +176,7 @@ double perf_diff__compute_ratio(struct hist_entry *he) s64 perf_diff__compute_wdiff(struct hist_entry *he) { - struct hist_entry *pair = he->pair; + struct hist_entry *pair = hist_entry__next_pair(he); u64 new_period = he->stat.period; u64 old_period = pair ? pair->stat.period : 0; @@ -193,7 +193,7 @@ s64 perf_diff__compute_wdiff(struct hist_entry *he) static int formula_delta(struct hist_entry *he, char *buf, size_t size) { - struct hist_entry *pair = he->pair; + struct hist_entry *pair = hist_entry__next_pair(he); if (!pair) return -1; @@ -207,7 +207,7 @@ static int formula_delta(struct hist_entry *he, char *buf, size_t size) static int formula_ratio(struct hist_entry *he, char *buf, size_t size) { - struct hist_entry *pair = he->pair; + struct hist_entry *pair = hist_entry__next_pair(he); double new_period = he->stat.period; double old_period = pair ? pair->stat.period : 0; @@ -219,7 +219,7 @@ static int formula_ratio(struct hist_entry *he, char *buf, size_t size) static int formula_wdiff(struct hist_entry *he, char *buf, size_t size) { - struct hist_entry *pair = he->pair; + struct hist_entry *pair = hist_entry__next_pair(he); u64 new_period = he->stat.period; u64 old_period = pair ? pair->stat.period : 0; @@ -359,8 +359,11 @@ static void hists__match(struct hists *older, struct hists *newer) struct rb_node *nd; for (nd = rb_first(&newer->entries); nd; nd = rb_next(nd)) { - struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node); - pos->pair = hists__find_entry(older, pos); + struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node), + *pair = hists__find_entry(older, pos); + + if (pair) + hist__entry_add_pair(pos, pair); } } @@ -402,7 +405,7 @@ static void hists__baseline_only(struct hists *hists) struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&he->rb_node); - if (!he->pair) { + if (!hist_entry__next_pair(he)) { rb_erase(&he->rb_node, &hists->entries); hist_entry__free(he); } diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 4f5f4756faa..aa84130024d 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -161,7 +161,7 @@ static int hpp__width_baseline(struct perf_hpp *hpp __maybe_unused) static double baseline_percent(struct hist_entry *he) { - struct hist_entry *pair = he->pair; + struct hist_entry *pair = hist_entry__next_pair(he); struct hists *pair_hists = pair ? pair->hists : NULL; double percent = 0.0; @@ -179,7 +179,7 @@ static int hpp__color_baseline(struct perf_hpp *hpp, struct hist_entry *he) { double percent = baseline_percent(he); - if (he->pair) + if (hist_entry__has_pairs(he)) return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%%", percent); else return scnprintf(hpp->buf, hpp->size, " "); @@ -190,7 +190,7 @@ static int hpp__entry_baseline(struct perf_hpp *hpp, struct hist_entry *he) double percent = baseline_percent(he); const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%%"; - if (he->pair || symbol_conf.field_sep) + if (hist_entry__has_pairs(he) || symbol_conf.field_sep) return scnprintf(hpp->buf, hpp->size, fmt, percent); else return scnprintf(hpp->buf, hpp->size, " "); @@ -248,7 +248,7 @@ static int hpp__width_period_baseline(struct perf_hpp *hpp __maybe_unused) static int hpp__entry_period_baseline(struct perf_hpp *hpp, struct hist_entry *he) { - struct hist_entry *pair = he->pair; + struct hist_entry *pair = hist_entry__next_pair(he); u64 period = pair ? pair->stat.period : 0; const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%12" PRIu64; @@ -354,7 +354,7 @@ static int hpp__width_displ(struct perf_hpp *hpp __maybe_unused) static int hpp__entry_displ(struct perf_hpp *hpp, struct hist_entry *he) { - struct hist_entry *pair = he->pair; + struct hist_entry *pair = hist_entry__next_pair(he); long displacement = pair ? pair->position - he->position : 0; const char *fmt = symbol_conf.field_sep ? "%s" : "%6.6s"; char buf[32] = " "; diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index a1b823f8c17..f42de79d2e6 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -244,6 +244,8 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) he->ms.map->referenced = true; if (symbol_conf.use_callchain) callchain_init(he->callchain); + + INIT_LIST_HEAD(&he->pairs.node); } return he; diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 13761d83a5a..b4e8c3ba559 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -77,6 +77,10 @@ struct hist_entry_diff { struct hist_entry { struct rb_node rb_node_in; struct rb_node rb_node; + union { + struct list_head node; + struct list_head head; + } pairs; struct he_stat stat; struct map_symbol ms; struct thread *thread; @@ -96,15 +100,30 @@ struct hist_entry { char *srcline; struct symbol *parent; unsigned long position; - union { - struct hist_entry *pair; - struct rb_root sorted_chain; - }; + struct rb_root sorted_chain; struct branch_info *branch_info; struct hists *hists; struct callchain_root callchain[0]; }; +static inline bool hist_entry__has_pairs(struct hist_entry *he) +{ + return !list_empty(&he->pairs.node); +} + +static inline struct hist_entry *hist_entry__next_pair(struct hist_entry *he) +{ + if (hist_entry__has_pairs(he)) + return list_entry(he->pairs.node.next, struct hist_entry, pairs.node); + return NULL; +} + +static inline void hist__entry_add_pair(struct hist_entry *he, + struct hist_entry *pair) +{ + list_add_tail(&he->pairs.head, &pair->pairs.node); +} + enum sort_type { SORT_PID, SORT_COMM, -- cgit v1.2.3 From 95529be47855be6350dfd0b9cd09ea863ca7421f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 8 Nov 2012 17:54:33 -0300 Subject: perf diff: Move hists__match to the hists lib Its not 'diff' specific and will be useful for other use cases, like bucketizing multiple events in a single session. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-o35urjgxfxxm70aw1wa81s4w@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-diff.c | 35 +---------------------------------- tools/perf/util/hist.c | 37 +++++++++++++++++++++++++++++++++++++ tools/perf/util/hist.h | 2 ++ 3 files changed, 40 insertions(+), 34 deletions(-) diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 8a9db38e562..e99fb3bc1c2 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -334,39 +334,6 @@ static void hists__name_resort(struct hists *self, bool sort) self->entries = tmp; } -static struct hist_entry *hists__find_entry(struct hists *self, - struct hist_entry *he) -{ - struct rb_node *n = self->entries.rb_node; - - while (n) { - struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node); - int64_t cmp = hist_entry__cmp(he, iter); - - if (cmp < 0) - n = n->rb_left; - else if (cmp > 0) - n = n->rb_right; - else - return iter; - } - - return NULL; -} - -static void hists__match(struct hists *older, struct hists *newer) -{ - struct rb_node *nd; - - for (nd = rb_first(&newer->entries); nd; nd = rb_next(nd)) { - struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node), - *pair = hists__find_entry(older, pos); - - if (pair) - hist__entry_add_pair(pos, pair); - } -} - static struct perf_evsel *evsel_match(struct perf_evsel *evsel, struct perf_evlist *evlist) { @@ -520,7 +487,7 @@ static void hists__compute_resort(struct hists *hists) static void hists__process(struct hists *old, struct hists *new) { - hists__match(old, new); + hists__match(new, old); if (show_baseline_only) hists__baseline_only(new); diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index f42de79d2e6..c1de3b05fe0 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -716,3 +716,40 @@ void hists__inc_nr_events(struct hists *hists, u32 type) ++hists->stats.nr_events[0]; ++hists->stats.nr_events[type]; } + +static struct hist_entry *hists__find_entry(struct hists *hists, + struct hist_entry *he) +{ + struct rb_node *n = hists->entries.rb_node; + + while (n) { + struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node); + int64_t cmp = hist_entry__cmp(he, iter); + + if (cmp < 0) + n = n->rb_left; + else if (cmp > 0) + n = n->rb_right; + else + return iter; + } + + return NULL; +} + +/* + * Look for pairs to link to the leader buckets (hist_entries): + */ +void hists__match(struct hists *leader, struct hists *other) +{ + struct rb_node *nd; + struct hist_entry *pos, *pair; + + for (nd = rb_first(&leader->entries); nd; nd = rb_next(nd)) { + pos = rb_entry(nd, struct hist_entry, rb_node); + pair = hists__find_entry(other, pos); + + if (pair) + hist__entry_add_pair(pos, pair); + } +} diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index a4f45dd0469..ff1c3963e04 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -115,6 +115,8 @@ bool hists__new_col_len(struct hists *self, enum hist_column col, u16 len); void hists__reset_col_len(struct hists *hists); void hists__calc_col_len(struct hists *hists, struct hist_entry *he); +void hists__match(struct hists *leader, struct hists *other); + struct perf_hpp { char *buf; size_t size; -- cgit v1.2.3 From 494d70a18137d18f0728fab7ad4f56aba29d1982 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 8 Nov 2012 18:03:09 -0300 Subject: perf hists: Introduce hists__link That given two hists will find the hist_entries (buckets) in the second hists that are for the same bucket in the first and link them, then it will look for all buckets in the second that don't have a counterpart in the first and will create a dummy counterpart that will then be linked to the entry in the second. For multiple events this will be done pairing the leader with all the other events in the group, so that in the end the leader will have all the buckets in all the hists in a group, dummy or not while the other hists will be left untouched. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-l9l9ieozqdhn9lieokd95okw@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/hist.h | 1 + 2 files changed, 61 insertions(+) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index c1de3b05fe0..7c6e73b1b7e 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -717,6 +717,42 @@ void hists__inc_nr_events(struct hists *hists, u32 type) ++hists->stats.nr_events[type]; } +static struct hist_entry *hists__add_dummy_entry(struct hists *hists, + struct hist_entry *pair) +{ + struct rb_node **p = &hists->entries.rb_node; + struct rb_node *parent = NULL; + struct hist_entry *he; + int cmp; + + while (*p != NULL) { + parent = *p; + he = rb_entry(parent, struct hist_entry, rb_node); + + cmp = hist_entry__cmp(pair, he); + + if (!cmp) + goto out; + + if (cmp < 0) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + + he = hist_entry__new(pair); + if (he) { + he->stat.nr_events = 0; + he->stat.period = 0; + he->hists = hists; + rb_link_node(&he->rb_node, parent, p); + rb_insert_color(&he->rb_node, &hists->entries); + hists__inc_nr_entries(hists, he); + } +out: + return he; +} + static struct hist_entry *hists__find_entry(struct hists *hists, struct hist_entry *he) { @@ -753,3 +789,27 @@ void hists__match(struct hists *leader, struct hists *other) hist__entry_add_pair(pos, pair); } } + +/* + * Look for entries in the other hists that are not present in the leader, if + * we find them, just add a dummy entry on the leader hists, with period=0, + * nr_events=0, to serve as the list header. + */ +int hists__link(struct hists *leader, struct hists *other) +{ + struct rb_node *nd; + struct hist_entry *pos, *pair; + + for (nd = rb_first(&other->entries); nd; nd = rb_next(nd)) { + pos = rb_entry(nd, struct hist_entry, rb_node); + + if (!hist_entry__has_pairs(pos)) { + pair = hists__add_dummy_entry(leader, pos); + if (pair == NULL) + return -1; + hist__entry_add_pair(pair, pos); + } + } + + return 0; +} diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index ff1c3963e04..1278c2c72a9 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -116,6 +116,7 @@ void hists__reset_col_len(struct hists *hists); void hists__calc_col_len(struct hists *hists, struct hist_entry *he); void hists__match(struct hists *leader, struct hists *other); +int hists__link(struct hists *leader, struct hists *other); struct perf_hpp { char *buf; -- cgit v1.2.3 From bfaef4b46b17ff053dc38f979cec364b0715cabb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 8 Nov 2012 18:08:26 -0300 Subject: perf diff: Use hists__link when not pairing just with baseline Previously there were blind spots because we were not looking at symbols that didn't ocurred in the latest run: # perf record usleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.018 MB perf.data (~801 samples) ] # perf record usleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.018 MB perf.data (~801 samples) ] Before: # perf diff # Event 'cycles' # # Baseline Delta Shared Object Symbol # ........ ....... ................. ............................. # +10.38% [kernel.kallsyms] [k] get_empty_filp +9.51% [kernel.kallsyms] [k] update_sd_lb_stats +9.41% libpopt.so.0.0.0 [.] _init +9.29% [kernel.kallsyms] [k] vma_interval_tree_insert 9.05% +0.12% [kernel.kallsyms] [k] do_sys_open +9.14% [kernel.kallsyms] [k] kfree +8.98% [kernel.kallsyms] [k] free_pages_and_swap_cache +8.78% [kernel.kallsyms] [k] unmap_page_range 9.36% -0.90% [kernel.kallsyms] [k] zap_pte_range 7.60% +0.09% [kernel.kallsyms] [k] find_next_bit +4.37% [kernel.kallsyms] [k] place_entity +3.38% [kernel.kallsyms] [k] __do_page_fault +0.80% [kernel.kallsyms] [k] native_apic_mem_write 0.21% +0.43% [kernel.kallsyms] [k] native_write_msr_safe # So 9.05 + 9.36 + 7.60 + 0.21 != 100% Now using the recently introduced hists__link we can see the whole picture: # perf diff # Event 'cycles' # # Baseline Delta Shared Object Symbol # ........ ....... ................. ............................. # 8.44% -8.44% [kernel.kallsyms] [k] _raw_spin_lock 9.05% -9.05% [kernel.kallsyms] [k] sha_transform 10.55% -10.55% [kernel.kallsyms] [k] __d_lookup_rcu +10.38% [kernel.kallsyms] [k] get_empty_filp 17.70% -17.70% [kernel.kallsyms] [k] kmem_cache_free +9.51% [kernel.kallsyms] [k] update_sd_lb_stats +9.41% libpopt.so.0.0.0 [.] _init +9.29% [kernel.kallsyms] [k] vma_interval_tree_insert 9.05% +0.12% [kernel.kallsyms] [k] do_sys_open +9.14% [kernel.kallsyms] [k] kfree +8.98% [kernel.kallsyms] [k] free_pages_and_swap_cache +8.78% [kernel.kallsyms] [k] unmap_page_range 9.36% -0.90% [kernel.kallsyms] [k] zap_pte_range 7.60% +0.09% [kernel.kallsyms] [k] find_next_bit +4.37% [kernel.kallsyms] [k] place_entity +3.38% [kernel.kallsyms] [k] __do_page_fault 4.01% -4.01% [kernel.kallsyms] [k] handle_pte_fault 9.27% -9.27% [kernel.kallsyms] [k] find_get_page 0.78% -0.78% [kernel.kallsyms] [k] rcu_irq_enter 0.57% -0.57% [kernel.kallsyms] [k] finish_task_switch 4.25% -4.25% [kernel.kallsyms] [k] run_timer_softirq +0.80% [kernel.kallsyms] [k] native_apic_mem_write 0.21% +0.43% [kernel.kallsyms] [k] native_write_msr_safe 9.16% -9.16% ld-2.12.so [.] close # Now: 8.44 + 9.05 + 10.55 + 17.70 + 9.05 + 9.36 + 7.60 + 4.01 + 9.27 + 0.78 + 0.57 + 4.25 + 0.21 + 9.16 == 100% Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-jeq55qdgby1745bs8r9sscdh@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-diff.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index e99fb3bc1c2..93b852f8a5d 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -491,6 +491,8 @@ static void hists__process(struct hists *old, struct hists *new) if (show_baseline_only) hists__baseline_only(new); + else + hists__link(new, old); if (sort_compute) { hists__precompute(new); -- cgit v1.2.3 From 8939ddc76a2f3399be98a60246ae0b365442f008 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 7 Nov 2012 20:31:32 +0530 Subject: gpio: tegra: fix suspend/resume apis Following are changes done to fix the suspend/resume functionality of tegra gpio driver: - Protect suspend/resume callbacks with CONFIG_PM_SLEEP because CONFIG_PM doesn't actually enable any of the PM callbacks, it only allows to enable CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME. This means if CONFIG_PM is used to protect system sleep callbacks then it may end up unreferenced if only runtime PM is enabled. - Fix the suspend/resume APIs declaration as per callback prototype. Signed-off-by: Laxman Dewangan Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index c7c175a4aff..da32754fb25 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -64,7 +65,7 @@ struct tegra_gpio_bank { int bank; int irq; spinlock_t lvl_lock[4]; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP u32 cnf[4]; u32 out[4]; u32 oe[4]; @@ -285,8 +286,8 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) } -#ifdef CONFIG_PM -void tegra_gpio_resume(void) +#ifdef CONFIG_PM_SLEEP +static int tegra_gpio_resume(struct device *dev) { unsigned long flags; int b; @@ -308,9 +309,10 @@ void tegra_gpio_resume(void) } local_irq_restore(flags); + return 0; } -void tegra_gpio_suspend(void) +static int tegra_gpio_suspend(struct device *dev) { unsigned long flags; int b; @@ -330,6 +332,7 @@ void tegra_gpio_suspend(void) } } local_irq_restore(flags); + return 0; } static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable) @@ -345,11 +348,15 @@ static struct irq_chip tegra_gpio_irq_chip = { .irq_mask = tegra_gpio_irq_mask, .irq_unmask = tegra_gpio_irq_unmask, .irq_set_type = tegra_gpio_irq_set_type, -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP .irq_set_wake = tegra_gpio_wake_enable, #endif }; +static const struct dev_pm_ops tegra_gpio_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(tegra_gpio_suspend, tegra_gpio_resume) +}; + struct tegra_gpio_soc_config { u32 bank_stride; u32 upper_offset; @@ -489,6 +496,7 @@ static struct platform_driver tegra_gpio_driver = { .driver = { .name = "tegra-gpio", .owner = THIS_MODULE, + .pm = &tegra_gpio_pm_ops, .of_match_table = tegra_gpio_of_match, }, .probe = tegra_gpio_probe, -- cgit v1.2.3 From 924a09873c658a23e416258c6f81348cba2cfe87 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 8 Nov 2012 10:45:24 +0800 Subject: gpio: tegra: Staticize non-exported symbols Both tegra_gpio_request() and tegra_gpio_free() are not referenced outside of this file, make them static. Signed-off-by: Axel Lin Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index da32754fb25..5ad4ceb14da 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -118,12 +118,12 @@ static void tegra_gpio_disable(int gpio) } EXPORT_SYMBOL_GPL(tegra_gpio_disable); -int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) +static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) { return pinctrl_request_gpio(offset); } -void tegra_gpio_free(struct gpio_chip *chip, unsigned offset) +static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset) { pinctrl_free_gpio(offset); tegra_gpio_disable(offset); -- cgit v1.2.3 From 65b6ca466748a8e0a906e40a470e1582bc565d79 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 8 Nov 2012 10:47:02 +0800 Subject: gpio: tegra: Drop exporting static functions Both tegra_gpio_enable() and tegra_gpio_disable() are static functions, it does not make sense to export them. Signed-off-by: Axel Lin Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 5ad4ceb14da..cfd9b723002 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -110,13 +110,11 @@ static void tegra_gpio_enable(int gpio) { tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); } -EXPORT_SYMBOL_GPL(tegra_gpio_enable); static void tegra_gpio_disable(int gpio) { tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); } -EXPORT_SYMBOL_GPL(tegra_gpio_disable); static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) { -- cgit v1.2.3 From 3764bdde1dc2fe53a87db1777440c2532cfccd58 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 8 Nov 2012 10:27:29 +0800 Subject: gpio: mvebu: Set free callback for gpio_chip We call pinctrl_request_gpio() in request callback, thus we need to call pinctrl_free_gpio() in free callback. Both mvebu_gpio_request() and mvebu_gpio_free() are not referenced outside of this file, make them static. Signed-off-by: Axel Lin Acked-by: Thomas Petazzoni Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mvebu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index e0bde063221..8b306570356 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -163,12 +163,12 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip) * Functions implementing the gpio_chip methods */ -int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin) +static int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin) { return pinctrl_request_gpio(chip->base + pin); } -void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin) +static void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin) { pinctrl_free_gpio(chip->base + pin); } @@ -518,6 +518,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) mvchip->chip.label = dev_name(&pdev->dev); mvchip->chip.dev = &pdev->dev; mvchip->chip.request = mvebu_gpio_request; + mvchip->chip.free = mvebu_gpio_free; mvchip->chip.direction_input = mvebu_gpio_direction_input; mvchip->chip.get = mvebu_gpio_get; mvchip->chip.direction_output = mvebu_gpio_direction_output; -- cgit v1.2.3 From d75542263a0b005876d112bbf9ffb23180cc3149 Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Tue, 6 Nov 2012 20:47:24 +0530 Subject: Revert "usb: musb: dsps: remove explicit NOP device creation" This reverts commit d8c3ef256f88b7c6ecd673d03073b5645be9c5e4. Above mentioned change was made along with multi usb phy change and adding DT support for nop transceiver. But other two changes did not make it to mainline. This in effect makes dsps musb wrapper unusable even for single instance. Hence revert it so that at least single instance can be supported. Cc: stable@vger.kernel.org # v3.7 Signed-off-by: Afzal Mohammed Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 6053af1f57c..e770f7984b5 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -411,7 +411,8 @@ static int dsps_musb_init(struct musb *musb) /* mentor core register starts at offset of 0x400 from musb base */ musb->mregs += wrp->musb_core_offset; - /* Get the NOP PHY */ + /* NOP driver needs change if supporting dual instance */ + usb_nop_xceiv_register(); musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); if (IS_ERR_OR_NULL(musb->xceiv)) return -ENODEV; -- cgit v1.2.3 From d928cd2ef8f7f4194e479d4a66452901ec82ccda Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Tue, 6 Nov 2012 20:47:35 +0530 Subject: usb: musb: dsps: document dt bindings properly DT bindings normally use '-' (hyphens) instead of '_' (underscore), driver has it the proper way, but binding documentation does not reflect it, fix it. Signed-off-by: Afzal Mohammed Signed-off-by: Felipe Balbi --- Documentation/devicetree/bindings/usb/am33xx-usb.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/am33xx-usb.txt b/Documentation/devicetree/bindings/usb/am33xx-usb.txt index ca8fa56e9f0..a92250512a4 100644 --- a/Documentation/devicetree/bindings/usb/am33xx-usb.txt +++ b/Documentation/devicetree/bindings/usb/am33xx-usb.txt @@ -3,12 +3,12 @@ AM33XX MUSB GLUE - ti,hwmods : must be "usb_otg_hs" - multipoint : Should be "1" indicating the musb controller supports multipoint. This is a MUSB configuration-specific setting. - - num_eps : Specifies the number of endpoints. This is also a + - num-eps : Specifies the number of endpoints. This is also a MUSB configuration-specific setting. Should be set to "16" - - ram_bits : Specifies the ram address size. Should be set to "12" - - port0_mode : Should be "3" to represent OTG. "1" signifies HOST and "2" + - ram-bits : Specifies the ram address size. Should be set to "12" + - port0-mode : Should be "3" to represent OTG. "1" signifies HOST and "2" represents PERIPHERAL. - - port1_mode : Should be "1" to represent HOST. "3" signifies OTG and "2" + - port1-mode : Should be "1" to represent HOST. "3" signifies OTG and "2" represents PERIPHERAL. - power : Should be "250". This signifies the controller can supply upto 500mA when operating in host mode. -- cgit v1.2.3 From cfff2f999d9baa561f20d999c8b83b03f078fb8f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 9 Nov 2012 09:47:27 +0100 Subject: mac80211: fix memory leak in device registration error path If the cipher suites need to be allocated, but this allocation fails, this leaks the internal scan request. Fix that by going to the correct error handling label. Signed-off-by: Johannes Berg --- net/mac80211/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c80c4490351..f57f597972f 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -871,8 +871,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.wiphy->cipher_suites, sizeof(u32) * local->hw.wiphy->n_cipher_suites, GFP_KERNEL); - if (!suites) - return -ENOMEM; + if (!suites) { + result = -ENOMEM; + goto fail_wiphy_register; + } for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { u32 suite = local->hw.wiphy->cipher_suites[r]; if (suite == WLAN_CIPHER_SUITE_WEP40 || -- cgit v1.2.3 From f3f09d5a4462929609342460d756fab2e8151421 Mon Sep 17 00:00:00 2001 From: Kautuk Consul Date: Sat, 31 Mar 2012 08:05:17 -0400 Subject: unicore32/mm/fault.c: Port OOM changes to do_pf Commit d065bd810b6deb67d4897a14bfe21f8eb526ba99 (mm: retry page fault when blocking on disk transfer) and commit 37b23e0525d393d48a7d59f870b3bc061a30ccdb (x86,mm: make pagefault killable) The above commits introduced changes into the x86 pagefault handler for making the page fault handler retryable as well as killable. These changes reduce the mmap_sem hold time, which is crucial during OOM killer invocation. Port these changes to unicore32. Signed-off-by: Kautuk Consul Acked-by: Guan Xuetao --- arch/unicore32/mm/fault.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c index 2eeb9c04cab..f9b5c10bcce 100644 --- a/arch/unicore32/mm/fault.c +++ b/arch/unicore32/mm/fault.c @@ -168,7 +168,7 @@ static inline bool access_error(unsigned int fsr, struct vm_area_struct *vma) } static int __do_pf(struct mm_struct *mm, unsigned long addr, unsigned int fsr, - struct task_struct *tsk) + unsigned int flags, struct task_struct *tsk) { struct vm_area_struct *vma; int fault; @@ -194,14 +194,7 @@ good_area: * If for any reason at all we couldn't handle the fault, make * sure we exit gracefully rather than endlessly redo the fault. */ - fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, - (!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); - if (unlikely(fault & VM_FAULT_ERROR)) - return fault; - if (fault & VM_FAULT_MAJOR) - tsk->maj_flt++; - else - tsk->min_flt++; + fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, flags); return fault; check_stack: @@ -216,6 +209,8 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) struct task_struct *tsk; struct mm_struct *mm; int fault, sig, code; + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | + ((!(fsr ^ 0x12)) ? FAULT_FLAG_WRITE : 0); tsk = current; mm = tsk->mm; @@ -236,6 +231,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (!user_mode(regs) && !search_exception_tables(regs->UCreg_pc)) goto no_context; +retry: down_read(&mm->mmap_sem); } else { /* @@ -251,7 +247,28 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) #endif } - fault = __do_pf(mm, addr, fsr, tsk); + fault = __do_pf(mm, addr, fsr, flags, tsk); + + /* If we need to retry but a fatal signal is pending, handle the + * signal first. We do not need to release the mmap_sem because + * it would already be released in __lock_page_or_retry in + * mm/filemap.c. */ + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) + return 0; + + if (!(fault & VM_FAULT_ERROR) && (flags & FAULT_FLAG_ALLOW_RETRY)) { + if (fault & VM_FAULT_MAJOR) + tsk->maj_flt++; + else + tsk->min_flt++; + if (fault & VM_FAULT_RETRY) { + /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk + * of starvation. */ + flags &= ~FAULT_FLAG_ALLOW_RETRY; + goto retry; + } + } + up_read(&mm->mmap_sem); /* -- cgit v1.2.3 From 446d141e1c84d34c70592b53443b06533703c324 Mon Sep 17 00:00:00 2001 From: Guan Xuetao Date: Thu, 12 Apr 2012 09:18:46 +0800 Subject: UniCore32 bugfix: add missed CONFIG_ZONE_DMA Because our PCI-bus handler confines dma zone into 128M, we should add CONFIG_ZONE_DMA for all boards. Otherwise, all memory bigger than 128M will be pushed into ZONE_MOVABLE. Cc: Arnd Bergmann Signed-off-by: Liu Guoli Signed-off-by: Guan Xuetao --- arch/unicore32/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index e5c5473e69c..5b95ba4e0c7 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -64,6 +64,9 @@ config GENERIC_CALIBRATE_DELAY config ARCH_MAY_HAVE_PC_FDC bool +config ZONE_DMA + def_bool y + config NEED_DMA_MAP_STATE def_bool y -- cgit v1.2.3 From 195d4577d1d7ab1f0398b3190547c116b56f435f Mon Sep 17 00:00:00 2001 From: Guan Xuetao Date: Thu, 14 Jun 2012 15:39:48 +0800 Subject: UniCore32-bugfix: fix mismatch return value of __xchg_bad_pointer When disintegrate system.h, I left an error in asm/cmpxchg.h, which will result in following error: arch/unicore32/include/asm/cmpxchg.h: In function '__xchg': arch/unicore32/include/asm/cmpxchg.h:38: error: void value not ignored as it ought to be Signed-off-by: Guan Xuetao --- arch/unicore32/include/asm/cmpxchg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/unicore32/include/asm/cmpxchg.h b/arch/unicore32/include/asm/cmpxchg.h index df4d5acfd19..8e797ad4fa2 100644 --- a/arch/unicore32/include/asm/cmpxchg.h +++ b/arch/unicore32/include/asm/cmpxchg.h @@ -35,7 +35,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, : "memory", "cc"); break; default: - ret = __xchg_bad_pointer(); + __xchg_bad_pointer(); } return ret; -- cgit v1.2.3 From 10e1e99e55378a65529c48753703c069aebce7af Mon Sep 17 00:00:00 2001 From: Guan Xuetao Date: Thu, 14 Jun 2012 11:38:25 +0800 Subject: UniCore32-bugfix: Remove definitions in asm/bug.h to solve difference between native and cross compiler For kernel/bound.c being compiled by native compiler, it will generate following errors in gcc 4.4.3: CC kernel/bounds.s In file included from include/linux/bug.h:4, from include/linux/page-flags.h:9, from kernel/bounds.c:9: arch/unicore32/include/asm/bug.h:22: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void' arch/unicore32/include/asm/bug.h:23: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void' So, we moved definitions in asm/bug.h to arch/unicore32/kernel/setup.h to solve the problem. Signed-off-by: Guan Xuetao --- arch/unicore32/include/asm/bug.h | 5 ----- arch/unicore32/kernel/setup.h | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/unicore32/include/asm/bug.h b/arch/unicore32/include/asm/bug.h index b1ff8cadb08..93a56f3e234 100644 --- a/arch/unicore32/include/asm/bug.h +++ b/arch/unicore32/include/asm/bug.h @@ -19,9 +19,4 @@ extern void die(const char *msg, struct pt_regs *regs, int err); extern void uc32_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, unsigned long err, unsigned long trap); -extern asmlinkage void __backtrace(void); -extern asmlinkage void c_backtrace(unsigned long fp, int pmode); - -extern void __show_regs(struct pt_regs *); - #endif /* __UNICORE_BUG_H__ */ diff --git a/arch/unicore32/kernel/setup.h b/arch/unicore32/kernel/setup.h index f23955028a1..30f749da8f7 100644 --- a/arch/unicore32/kernel/setup.h +++ b/arch/unicore32/kernel/setup.h @@ -30,4 +30,10 @@ extern char __vectors_start[], __vectors_end[]; extern void kernel_thread_helper(void); extern void __init early_signal_init(void); + +extern asmlinkage void __backtrace(void); +extern asmlinkage void c_backtrace(unsigned long fp, int pmode); + +extern void __show_regs(struct pt_regs *); + #endif -- cgit v1.2.3 From e8ce15a6d7ecdbabd8d04d78e065a2706459194f Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 9 Oct 2012 09:47:48 +0100 Subject: UAPI: (Scripted) Disintegrate arch/unicore32/include/asm Signed-off-by: David Howells Acked-by: Arnd Bergmann Acked-by: Thomas Gleixner Acked-by: Michael Kerrisk Acked-by: Paul E. McKenney Acked-by: Dave Jones --- arch/unicore32/include/asm/Kbuild | 1 - arch/unicore32/include/asm/byteorder.h | 24 -------- arch/unicore32/include/asm/kvm_para.h | 1 - arch/unicore32/include/asm/ptrace.h | 76 +---------------------- arch/unicore32/include/asm/sigcontext.h | 29 --------- arch/unicore32/include/asm/unistd.h | 14 ----- arch/unicore32/include/uapi/asm/Kbuild | 5 ++ arch/unicore32/include/uapi/asm/byteorder.h | 24 ++++++++ arch/unicore32/include/uapi/asm/kvm_para.h | 1 + arch/unicore32/include/uapi/asm/ptrace.h | 90 ++++++++++++++++++++++++++++ arch/unicore32/include/uapi/asm/sigcontext.h | 29 +++++++++ arch/unicore32/include/uapi/asm/unistd.h | 14 +++++ 12 files changed, 164 insertions(+), 144 deletions(-) delete mode 100644 arch/unicore32/include/asm/byteorder.h delete mode 100644 arch/unicore32/include/asm/kvm_para.h delete mode 100644 arch/unicore32/include/asm/sigcontext.h delete mode 100644 arch/unicore32/include/asm/unistd.h create mode 100644 arch/unicore32/include/uapi/asm/byteorder.h create mode 100644 arch/unicore32/include/uapi/asm/kvm_para.h create mode 100644 arch/unicore32/include/uapi/asm/ptrace.h create mode 100644 arch/unicore32/include/uapi/asm/sigcontext.h create mode 100644 arch/unicore32/include/uapi/asm/unistd.h diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild index c910c9857e1..601e92f18af 100644 --- a/arch/unicore32/include/asm/Kbuild +++ b/arch/unicore32/include/asm/Kbuild @@ -1,4 +1,3 @@ -include include/asm-generic/Kbuild.asm generic-y += atomic.h generic-y += auxvec.h diff --git a/arch/unicore32/include/asm/byteorder.h b/arch/unicore32/include/asm/byteorder.h deleted file mode 100644 index ebe1b3fef3e..00000000000 --- a/arch/unicore32/include/asm/byteorder.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * linux/arch/unicore32/include/asm/byteorder.h - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Copyright (C) 2001-2010 GUAN Xue-tao - * - * 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. - * - * UniCore ONLY support Little Endian mode, the data bus is connected such - * that byte accesses appear as: - * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31 - * and word accesses (data or instruction) appear as: - * d0...d31 - */ -#ifndef __UNICORE_BYTEORDER_H__ -#define __UNICORE_BYTEORDER_H__ - -#include - -#endif - diff --git a/arch/unicore32/include/asm/kvm_para.h b/arch/unicore32/include/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b95..00000000000 --- a/arch/unicore32/include/asm/kvm_para.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/arch/unicore32/include/asm/ptrace.h b/arch/unicore32/include/asm/ptrace.h index b9caf9b0997..726749dab52 100644 --- a/arch/unicore32/include/asm/ptrace.h +++ b/arch/unicore32/include/asm/ptrace.h @@ -12,80 +12,10 @@ #ifndef __UNICORE_PTRACE_H__ #define __UNICORE_PTRACE_H__ -#define PTRACE_GET_THREAD_AREA 22 - -/* - * PSR bits - */ -#define USER_MODE 0x00000010 -#define REAL_MODE 0x00000011 -#define INTR_MODE 0x00000012 -#define PRIV_MODE 0x00000013 -#define ABRT_MODE 0x00000017 -#define EXTN_MODE 0x0000001b -#define SUSR_MODE 0x0000001f -#define MODE_MASK 0x0000001f -#define PSR_R_BIT 0x00000040 -#define PSR_I_BIT 0x00000080 -#define PSR_V_BIT 0x10000000 -#define PSR_C_BIT 0x20000000 -#define PSR_Z_BIT 0x40000000 -#define PSR_S_BIT 0x80000000 - -/* - * Groups of PSR bits - */ -#define PSR_f 0xff000000 /* Flags */ -#define PSR_c 0x000000ff /* Control */ +#include #ifndef __ASSEMBLY__ -/* - * This struct defines the way the registers are stored on the - * stack during a system call. Note that sizeof(struct pt_regs) - * has to be a multiple of 8. - */ -struct pt_regs { - unsigned long uregs[34]; -}; - -#define UCreg_asr uregs[32] -#define UCreg_pc uregs[31] -#define UCreg_lr uregs[30] -#define UCreg_sp uregs[29] -#define UCreg_ip uregs[28] -#define UCreg_fp uregs[27] -#define UCreg_26 uregs[26] -#define UCreg_25 uregs[25] -#define UCreg_24 uregs[24] -#define UCreg_23 uregs[23] -#define UCreg_22 uregs[22] -#define UCreg_21 uregs[21] -#define UCreg_20 uregs[20] -#define UCreg_19 uregs[19] -#define UCreg_18 uregs[18] -#define UCreg_17 uregs[17] -#define UCreg_16 uregs[16] -#define UCreg_15 uregs[15] -#define UCreg_14 uregs[14] -#define UCreg_13 uregs[13] -#define UCreg_12 uregs[12] -#define UCreg_11 uregs[11] -#define UCreg_10 uregs[10] -#define UCreg_09 uregs[9] -#define UCreg_08 uregs[8] -#define UCreg_07 uregs[7] -#define UCreg_06 uregs[6] -#define UCreg_05 uregs[5] -#define UCreg_04 uregs[4] -#define UCreg_03 uregs[3] -#define UCreg_02 uregs[2] -#define UCreg_01 uregs[1] -#define UCreg_00 uregs[0] -#define UCreg_ORIG_00 uregs[33] - -#ifdef __KERNEL__ - #define user_mode(regs) \ (processor_mode(regs) == USER_MODE) @@ -125,9 +55,5 @@ static inline int valid_user_regs(struct pt_regs *regs) #define instruction_pointer(regs) ((regs)->UCreg_pc) -#endif /* __KERNEL__ */ - #endif /* __ASSEMBLY__ */ - #endif - diff --git a/arch/unicore32/include/asm/sigcontext.h b/arch/unicore32/include/asm/sigcontext.h deleted file mode 100644 index 6a2d7671c05..00000000000 --- a/arch/unicore32/include/asm/sigcontext.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * linux/arch/unicore32/include/asm/sigcontext.h - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Copyright (C) 2001-2010 GUAN Xue-tao - * - * 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. - */ -#ifndef __UNICORE_SIGCONTEXT_H__ -#define __UNICORE_SIGCONTEXT_H__ - -#include -/* - * Signal context structure - contains all info to do with the state - * before the signal handler was invoked. Note: only add new entries - * to the end of the structure. - */ -struct sigcontext { - unsigned long trap_no; - unsigned long error_code; - unsigned long oldmask; - unsigned long fault_address; - struct pt_regs regs; -}; - -#endif diff --git a/arch/unicore32/include/asm/unistd.h b/arch/unicore32/include/asm/unistd.h deleted file mode 100644 index 2abcf61c615..00000000000 --- a/arch/unicore32/include/asm/unistd.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * linux/arch/unicore32/include/asm/unistd.h - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Copyright (C) 2001-2010 GUAN Xue-tao - * - * 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. - */ - -/* Use the standard ABI for syscalls. */ -#include diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild index baebb3da1d4..a44b1c453d1 100644 --- a/arch/unicore32/include/uapi/asm/Kbuild +++ b/arch/unicore32/include/uapi/asm/Kbuild @@ -1,3 +1,8 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm +header-y += byteorder.h +header-y += kvm_para.h +header-y += ptrace.h +header-y += sigcontext.h +header-y += unistd.h diff --git a/arch/unicore32/include/uapi/asm/byteorder.h b/arch/unicore32/include/uapi/asm/byteorder.h new file mode 100644 index 00000000000..ebe1b3fef3e --- /dev/null +++ b/arch/unicore32/include/uapi/asm/byteorder.h @@ -0,0 +1,24 @@ +/* + * linux/arch/unicore32/include/asm/byteorder.h + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * 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. + * + * UniCore ONLY support Little Endian mode, the data bus is connected such + * that byte accesses appear as: + * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31 + * and word accesses (data or instruction) appear as: + * d0...d31 + */ +#ifndef __UNICORE_BYTEORDER_H__ +#define __UNICORE_BYTEORDER_H__ + +#include + +#endif + diff --git a/arch/unicore32/include/uapi/asm/kvm_para.h b/arch/unicore32/include/uapi/asm/kvm_para.h new file mode 100644 index 00000000000..14fab8f0b95 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/kvm_para.h @@ -0,0 +1 @@ +#include diff --git a/arch/unicore32/include/uapi/asm/ptrace.h b/arch/unicore32/include/uapi/asm/ptrace.h new file mode 100644 index 00000000000..187aa2e98a5 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/ptrace.h @@ -0,0 +1,90 @@ +/* + * linux/arch/unicore32/include/asm/ptrace.h + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * 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. + */ +#ifndef _UAPI__UNICORE_PTRACE_H__ +#define _UAPI__UNICORE_PTRACE_H__ + +#define PTRACE_GET_THREAD_AREA 22 + +/* + * PSR bits + */ +#define USER_MODE 0x00000010 +#define REAL_MODE 0x00000011 +#define INTR_MODE 0x00000012 +#define PRIV_MODE 0x00000013 +#define ABRT_MODE 0x00000017 +#define EXTN_MODE 0x0000001b +#define SUSR_MODE 0x0000001f +#define MODE_MASK 0x0000001f +#define PSR_R_BIT 0x00000040 +#define PSR_I_BIT 0x00000080 +#define PSR_V_BIT 0x10000000 +#define PSR_C_BIT 0x20000000 +#define PSR_Z_BIT 0x40000000 +#define PSR_S_BIT 0x80000000 + +/* + * Groups of PSR bits + */ +#define PSR_f 0xff000000 /* Flags */ +#define PSR_c 0x000000ff /* Control */ + +#ifndef __ASSEMBLY__ + +/* + * This struct defines the way the registers are stored on the + * stack during a system call. Note that sizeof(struct pt_regs) + * has to be a multiple of 8. + */ +struct pt_regs { + unsigned long uregs[34]; +}; + +#define UCreg_asr uregs[32] +#define UCreg_pc uregs[31] +#define UCreg_lr uregs[30] +#define UCreg_sp uregs[29] +#define UCreg_ip uregs[28] +#define UCreg_fp uregs[27] +#define UCreg_26 uregs[26] +#define UCreg_25 uregs[25] +#define UCreg_24 uregs[24] +#define UCreg_23 uregs[23] +#define UCreg_22 uregs[22] +#define UCreg_21 uregs[21] +#define UCreg_20 uregs[20] +#define UCreg_19 uregs[19] +#define UCreg_18 uregs[18] +#define UCreg_17 uregs[17] +#define UCreg_16 uregs[16] +#define UCreg_15 uregs[15] +#define UCreg_14 uregs[14] +#define UCreg_13 uregs[13] +#define UCreg_12 uregs[12] +#define UCreg_11 uregs[11] +#define UCreg_10 uregs[10] +#define UCreg_09 uregs[9] +#define UCreg_08 uregs[8] +#define UCreg_07 uregs[7] +#define UCreg_06 uregs[6] +#define UCreg_05 uregs[5] +#define UCreg_04 uregs[4] +#define UCreg_03 uregs[3] +#define UCreg_02 uregs[2] +#define UCreg_01 uregs[1] +#define UCreg_00 uregs[0] +#define UCreg_ORIG_00 uregs[33] + + +#endif /* __ASSEMBLY__ */ + +#endif /* _UAPI__UNICORE_PTRACE_H__ */ diff --git a/arch/unicore32/include/uapi/asm/sigcontext.h b/arch/unicore32/include/uapi/asm/sigcontext.h new file mode 100644 index 00000000000..6a2d7671c05 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/sigcontext.h @@ -0,0 +1,29 @@ +/* + * linux/arch/unicore32/include/asm/sigcontext.h + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * 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. + */ +#ifndef __UNICORE_SIGCONTEXT_H__ +#define __UNICORE_SIGCONTEXT_H__ + +#include +/* + * Signal context structure - contains all info to do with the state + * before the signal handler was invoked. Note: only add new entries + * to the end of the structure. + */ +struct sigcontext { + unsigned long trap_no; + unsigned long error_code; + unsigned long oldmask; + unsigned long fault_address; + struct pt_regs regs; +}; + +#endif diff --git a/arch/unicore32/include/uapi/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h new file mode 100644 index 00000000000..2abcf61c615 --- /dev/null +++ b/arch/unicore32/include/uapi/asm/unistd.h @@ -0,0 +1,14 @@ +/* + * linux/arch/unicore32/include/asm/unistd.h + * + * Code specific to PKUnity SoC and UniCore ISA + * + * Copyright (C) 2001-2010 GUAN Xue-tao + * + * 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. + */ + +/* Use the standard ABI for syscalls. */ +#include -- cgit v1.2.3 From ddd2d384b019d1733335c0fca7eccae3c29d2a14 Mon Sep 17 00:00:00 2001 From: Guan Xuetao Date: Mon, 15 Oct 2012 14:41:36 +0800 Subject: unicore32: Use Kbuild infrastructure for kvm_para.h All the headers but kvm_para.h use the Kbuild infrastructure to get to the asm-generic headers. Cc: linux-kbuild@vger.kernel.org Signed-off-by: Steven Rostedt Signed-off-by: Guan Xuetao --- arch/unicore32/include/uapi/asm/Kbuild | 2 ++ arch/unicore32/include/uapi/asm/kvm_para.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) delete mode 100644 arch/unicore32/include/uapi/asm/kvm_para.h diff --git a/arch/unicore32/include/uapi/asm/Kbuild b/arch/unicore32/include/uapi/asm/Kbuild index a44b1c453d1..0514d7ad685 100644 --- a/arch/unicore32/include/uapi/asm/Kbuild +++ b/arch/unicore32/include/uapi/asm/Kbuild @@ -6,3 +6,5 @@ header-y += kvm_para.h header-y += ptrace.h header-y += sigcontext.h header-y += unistd.h + +generic-y += kvm_para.h diff --git a/arch/unicore32/include/uapi/asm/kvm_para.h b/arch/unicore32/include/uapi/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b95..00000000000 --- a/arch/unicore32/include/uapi/asm/kvm_para.h +++ /dev/null @@ -1 +0,0 @@ -#include -- cgit v1.2.3 From 38e993535edda089a6956bf12a1dde2602649de9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 13 Oct 2012 17:35:21 -0400 Subject: unicore32: switch to generic kernel_thread()/kernel_execve() Signed-off-by: Al Viro Acked-and-Tested-by: Guan Xuetao --- arch/unicore32/Kconfig | 2 ++ arch/unicore32/include/asm/processor.h | 5 --- arch/unicore32/kernel/entry.S | 15 ++++----- arch/unicore32/kernel/process.c | 58 ++++++++-------------------------- arch/unicore32/kernel/sys.c | 42 ------------------------ 5 files changed, 23 insertions(+), 99 deletions(-) diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index 5b95ba4e0c7..fda37c941c1 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -16,6 +16,8 @@ config UNICORE32 select ARCH_WANT_FRAME_POINTERS select GENERIC_IOMAP select MODULES_USE_ELF_REL + select GENERIC_KERNEL_THREAD + select GENERIC_KERNEL_EXECVE help UniCore-32 is 32-bit Instruction Set Architecture, including a series of low-power-consumption RISC chip diff --git a/arch/unicore32/include/asm/processor.h b/arch/unicore32/include/asm/processor.h index 14382cb0965..4eaa4216766 100644 --- a/arch/unicore32/include/asm/processor.h +++ b/arch/unicore32/include/asm/processor.h @@ -72,11 +72,6 @@ unsigned long get_wchan(struct task_struct *p); #define cpu_relax() barrier() -/* - * Create a new kernel thread - */ -extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); - #define task_pt_regs(p) \ ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S index dcb87ab19dd..32648c99483 100644 --- a/arch/unicore32/kernel/entry.S +++ b/arch/unicore32/kernel/entry.S @@ -573,17 +573,16 @@ ENDPROC(ret_to_user) */ ENTRY(ret_from_fork) b.l schedule_tail - get_thread_info tsk - ldw r1, [tsk+], #TI_FLAGS @ check for syscall tracing - mov why, #1 - cand.a r1, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? - beq ret_slow_syscall - mov r1, sp - mov r0, #1 @ trace exit [IP = 1] - b.l syscall_trace b ret_slow_syscall ENDPROC(ret_from_fork) +ENTRY(ret_from_kernel_thread) + b.l schedule_tail + mov r0, r5 + adr lr, ret_slow_syscall + mov pc, r4 +ENDPROC(ret_from_kernel_thread) + /*============================================================================= * SWI handler *----------------------------------------------------------------------------- diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c index b008586dad7..a8fe265ce2c 100644 --- a/arch/unicore32/kernel/process.c +++ b/arch/unicore32/kernel/process.c @@ -258,6 +258,7 @@ void release_thread(struct task_struct *dead_task) } asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); +asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); int copy_thread(unsigned long clone_flags, unsigned long stack_start, @@ -266,17 +267,22 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, struct thread_info *thread = task_thread_info(p); struct pt_regs *childregs = task_pt_regs(p); - *childregs = *regs; - childregs->UCreg_00 = 0; - childregs->UCreg_sp = stack_start; - memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); thread->cpu_context.sp = (unsigned long)childregs; - thread->cpu_context.pc = (unsigned long)ret_from_fork; - - if (clone_flags & CLONE_SETTLS) - childregs->UCreg_16 = regs->UCreg_03; + if (unlikely(!regs)) { + thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread; + thread->cpu_context.r4 = stack_start; + thread->cpu_context.r5 = stk_sz; + memset(childregs, 0, sizeof(struct pt_regs)); + } else { + thread->cpu_context.pc = (unsigned long)ret_from_fork; + *childregs = *regs; + childregs->UCreg_00 = 0; + childregs->UCreg_sp = stack_start; + if (clone_flags & CLONE_SETTLS) + childregs->UCreg_16 = regs->UCreg_03; + } return 0; } @@ -305,42 +311,6 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fp) } EXPORT_SYMBOL(dump_fpu); -/* - * Shuffle the argument into the correct register before calling the - * thread function. r1 is the thread argument, r2 is the pointer to - * the thread function, and r3 points to the exit function. - */ -asm(".pushsection .text\n" -" .align\n" -" .type kernel_thread_helper, #function\n" -"kernel_thread_helper:\n" -" mov.a asr, r7\n" -" mov r0, r4\n" -" mov lr, r6\n" -" mov pc, r5\n" -" .size kernel_thread_helper, . - kernel_thread_helper\n" -" .popsection"); - -/* - * Create a kernel thread. - */ -pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof(regs)); - - regs.UCreg_04 = (unsigned long)arg; - regs.UCreg_05 = (unsigned long)fn; - regs.UCreg_06 = (unsigned long)do_exit; - regs.UCreg_07 = PRIV_MODE; - regs.UCreg_pc = (unsigned long)kernel_thread_helper; - regs.UCreg_asr = regs.UCreg_07 | PSR_I_BIT; - - return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -} -EXPORT_SYMBOL(kernel_thread); - unsigned long get_wchan(struct task_struct *p) { struct stackframe frame; diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c index fabdee96110..8b6e4cc5739 100644 --- a/arch/unicore32/kernel/sys.c +++ b/arch/unicore32/kernel/sys.c @@ -63,48 +63,6 @@ out: return error; } -int kernel_execve(const char *filename, - const char *const argv[], - const char *const envp[]) -{ - struct pt_regs regs; - int ret; - - memset(®s, 0, sizeof(struct pt_regs)); - ret = do_execve(filename, - (const char __user *const __user *)argv, - (const char __user *const __user *)envp, ®s); - if (ret < 0) - goto out; - - /* - * Save argc to the register structure for userspace. - */ - regs.UCreg_00 = ret; - - /* - * We were successful. We won't be returning to our caller, but - * instead to user space by manipulating the kernel stack. - */ - asm("add r0, %0, %1\n\t" - "mov r1, %2\n\t" - "mov r2, %3\n\t" - "mov r22, #0\n\t" /* not a syscall */ - "mov r23, %0\n\t" /* thread structure */ - "b.l memmove\n\t" /* copy regs to top of stack */ - "mov sp, r0\n\t" /* reposition stack pointer */ - "b ret_to_user" - : - : "r" (current_thread_info()), - "Ir" (THREAD_START_SP - sizeof(regs)), - "r" (®s), - "Ir" (sizeof(regs)) - : "r0", "r1", "r2", "r3", "ip", "lr", "memory"); - - out: - return ret; -} - /* Note: used by the compat code even in 64-bit Linux. */ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, -- cgit v1.2.3 From 60541d778e536455970281de25b2476e01c03aef Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 13 Oct 2012 17:36:40 -0400 Subject: unicore32: switch to generic sys_execve() Signed-off-by: Al Viro Acked-and-Tested-by: Guan Xuetao --- arch/unicore32/include/uapi/asm/unistd.h | 1 + arch/unicore32/kernel/entry.S | 5 ----- arch/unicore32/kernel/sys.c | 21 --------------------- 3 files changed, 1 insertion(+), 26 deletions(-) diff --git a/arch/unicore32/include/uapi/asm/unistd.h b/arch/unicore32/include/uapi/asm/unistd.h index 2abcf61c615..d18a3be89b3 100644 --- a/arch/unicore32/include/uapi/asm/unistd.h +++ b/arch/unicore32/include/uapi/asm/unistd.h @@ -12,3 +12,4 @@ /* Use the standard ABI for syscalls. */ #include +#define __ARCH_WANT_SYS_EXECVE diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S index 32648c99483..7049350c790 100644 --- a/arch/unicore32/kernel/entry.S +++ b/arch/unicore32/kernel/entry.S @@ -668,11 +668,6 @@ __cr_alignment: #endif .ltorg -ENTRY(sys_execve) - add r3, sp, #S_OFF - b __sys_execve -ENDPROC(sys_execve) - ENTRY(sys_clone) add ip, sp, #S_OFF stw ip, [sp+], #4 diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c index 8b6e4cc5739..9680134b31f 100644 --- a/arch/unicore32/kernel/sys.c +++ b/arch/unicore32/kernel/sys.c @@ -42,27 +42,6 @@ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp, parent_tid, child_tid); } -/* sys_execve() executes a new program. - * This is called indirectly via a small wrapper - */ -asmlinkage long __sys_execve(const char __user *filename, - const char __user *const __user *argv, - const char __user *const __user *envp, - struct pt_regs *regs) -{ - int error; - struct filename *fn; - - fn = getname(filename); - error = PTR_ERR(fn); - if (IS_ERR(fn)) - goto out; - error = do_execve(fn->name, argv, envp, regs); - putname(fn); -out: - return error; -} - /* Note: used by the compat code even in 64-bit Linux. */ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, -- cgit v1.2.3 From c284464658acab50c67ff65ff3dc9215a0231ad2 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 23 Oct 2012 13:01:43 -0700 Subject: arch/unicore32: remove CONFIG_EXPERIMENTAL This config item has not carried much meaning for a while now and is almost always enabled by default. As agreed during the Linux kernel summit, remove it. CC: Guan Xuetao Signed-off-by: Kees Cook Acked-by: Guan Xuetao --- arch/unicore32/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index fda37c941c1..c4fbb21e802 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -221,7 +221,7 @@ config PUV3_GPIO bool depends on !ARCH_FPGA select GENERIC_GPIO - select GPIO_SYSFS if EXPERIMENTAL + select GPIO_SYSFS default y if PUV3_NB0916 -- cgit v1.2.3 From 4870639a754991a52fc8f4ba82f0d9c247c33659 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 7 Nov 2012 12:54:21 +0100 Subject: MIPS: compat: Fix use of TIF_32BIT_ADDR vs _TIF_32BIT_ADDR Signed-off-by: Ralf Baechle --- arch/mips/include/asm/thread_info.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 8debe9e9175..d8323ea9d5e 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -115,7 +115,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); #ifdef CONFIG_MIPS32_O32 #define TIF_32BIT TIF_32BIT_REGS #elif defined(CONFIG_MIPS32_N32) -#define TIF_32BIT _TIF_32BIT_ADDR +#define TIF_32BIT TIF_32BIT_ADDR #endif /* CONFIG_MIPS32_O32 */ #define _TIF_SYSCALL_TRACE (1< Date: Thu, 8 Nov 2012 23:59:31 +0100 Subject: MIPS: compat: Implement is_compat_task() by testing for 32-bit address space. So far is_compat_task() was testing for 32-bit registers if O32 support was enabled and if O32 support was disabled but N32 enabled it was testing for 32-bit address space. So if both O32 and N32 were enabled a N32 task was not considered a compat task, whops. This still leaves potential cases where O32 and N32 need different treatment unsolved. But that's another commit. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/compat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h index 58277e0e9cd..3c5d1464b7b 100644 --- a/arch/mips/include/asm/compat.h +++ b/arch/mips/include/asm/compat.h @@ -290,7 +290,7 @@ struct compat_shmid64_ds { static inline int is_compat_task(void) { - return test_thread_flag(TIF_32BIT); + return test_thread_flag(TIF_32BIT_ADDR); } #endif /* _ASM_COMPAT_H */ -- cgit v1.2.3 From 34d875d7b579baab2f2f6dfd8e8533602d9dbf33 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 9 Nov 2012 00:28:59 +0100 Subject: MIPS: compat: Delete now unused TIF_32BIT. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/thread_info.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index d8323ea9d5e..18806a52061 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -112,12 +112,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ -#ifdef CONFIG_MIPS32_O32 -#define TIF_32BIT TIF_32BIT_REGS -#elif defined(CONFIG_MIPS32_N32) -#define TIF_32BIT TIF_32BIT_ADDR -#endif /* CONFIG_MIPS32_O32 */ - #define _TIF_SYSCALL_TRACE (1< Date: Thu, 6 Sep 2012 11:36:54 -0400 Subject: MIPS: bitops.h: Change use of 'unsigned short' to 'int' [ralf@linux-mips.org: No functional change but it's consistent with how use types elsewhere in the code.] Signed-off-by: Jim Quinlan Cc: linux-mips@linux-mips.org Cc: David Daney Cc: Kevin Cernekee cernekee@gmail.com Cc: Jim Quinlan Patchwork: https://patchwork.linux-mips.org/patch/4319/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/bitops.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 82ad35ce2b4..455664cf535 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -57,7 +57,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long temp; if (kernel_uses_llsc && R10000_LLSC_WAR) { @@ -118,7 +118,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long temp; if (kernel_uses_llsc && R10000_LLSC_WAR) { @@ -191,7 +191,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad */ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; if (kernel_uses_llsc && R10000_LLSC_WAR) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); @@ -244,7 +244,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) static inline int test_and_set_bit(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long res; smp_mb__before_llsc(); @@ -310,7 +310,7 @@ static inline int test_and_set_bit(unsigned long nr, static inline int test_and_set_bit_lock(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long res; if (kernel_uses_llsc && R10000_LLSC_WAR) { @@ -373,7 +373,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, static inline int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long res; smp_mb__before_llsc(); @@ -457,7 +457,7 @@ static inline int test_and_clear_bit(unsigned long nr, static inline int test_and_change_bit(unsigned long nr, volatile unsigned long *addr) { - unsigned short bit = nr & SZLONG_MASK; + int bit = nr & SZLONG_MASK; unsigned long res; smp_mb__before_llsc(); -- cgit v1.2.3 From 92d11594f688c8b55b51e80f2eac4417396237a4 Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Thu, 6 Sep 2012 11:36:55 -0400 Subject: MIPS: Remove irqflags.h dependency from bitops.h The "else clause" of most functions in bitops.h invoked raw_local_irq_{save,restore}() and in doing so had a dependency on irqflags.h. This fix moves said code to bitops.c, removing the dependency. Signed-off-by: Jim Quinlan Cc: linux-mips@linux-mips.org Cc: David Daney Cc: Kevin Cernekee cernekee@gmail.com Cc: Jim Quinlan Patchwork: https://patchwork.linux-mips.org/patch/4320/ Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/executive/cvmx-l2c.c | 1 + arch/mips/include/asm/bitops.h | 114 +++++------------ arch/mips/include/asm/io.h | 1 + arch/mips/lib/Makefile | 2 +- arch/mips/lib/bitops.c | 179 +++++++++++++++++++++++++++ 5 files changed, 214 insertions(+), 83 deletions(-) create mode 100644 arch/mips/lib/bitops.c diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c index d38246e33dd..9f883bf7695 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-l2c.c +++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c @@ -30,6 +30,7 @@ * measurement, and debugging facilities. */ +#include #include #include #include diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 455664cf535..46ac73abd5e 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h @@ -14,7 +14,6 @@ #endif #include -#include #include #include #include /* sigh ... */ @@ -44,6 +43,24 @@ #define smp_mb__before_clear_bit() smp_mb__before_llsc() #define smp_mb__after_clear_bit() smp_llsc_mb() + +/* + * These are the "slower" versions of the functions and are in bitops.c. + * These functions call raw_local_irq_{save,restore}(). + */ +void __mips_set_bit(unsigned long nr, volatile unsigned long *addr); +void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr); +void __mips_change_bit(unsigned long nr, volatile unsigned long *addr); +int __mips_test_and_set_bit(unsigned long nr, + volatile unsigned long *addr); +int __mips_test_and_set_bit_lock(unsigned long nr, + volatile unsigned long *addr); +int __mips_test_and_clear_bit(unsigned long nr, + volatile unsigned long *addr); +int __mips_test_and_change_bit(unsigned long nr, + volatile unsigned long *addr); + + /* * set_bit - Atomically set a bit in memory * @nr: the bit to set @@ -92,17 +109,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "+m" (*m) : "ir" (1UL << bit)); } while (unlikely(!temp)); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - *a |= mask; - raw_local_irq_restore(flags); - } + } else + __mips_set_bit(nr, addr); } /* @@ -153,17 +161,8 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "+m" (*m) : "ir" (~(1UL << bit))); } while (unlikely(!temp)); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - *a &= ~mask; - raw_local_irq_restore(flags); - } + } else + __mips_clear_bit(nr, addr); } /* @@ -220,17 +219,8 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) : "=&r" (temp), "+m" (*m) : "ir" (1UL << bit)); } while (unlikely(!temp)); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - *a ^= mask; - raw_local_irq_restore(flags); - } + } else + __mips_change_bit(nr, addr); } /* @@ -281,18 +271,8 @@ static inline int test_and_set_bit(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a |= mask; - raw_local_irq_restore(flags); - } + } else + res = __mips_test_and_set_bit(nr, addr); smp_llsc_mb(); @@ -345,18 +325,8 @@ static inline int test_and_set_bit_lock(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a |= mask; - raw_local_irq_restore(flags); - } + } else + res = __mips_test_and_set_bit_lock(nr, addr); smp_llsc_mb(); @@ -428,18 +398,8 @@ static inline int test_and_clear_bit(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a &= ~mask; - raw_local_irq_restore(flags); - } + } else + res = __mips_test_and_clear_bit(nr, addr); smp_llsc_mb(); @@ -494,18 +454,8 @@ static inline int test_and_change_bit(unsigned long nr, } while (unlikely(!res)); res = temp & (1UL << bit); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a ^= mask; - raw_local_irq_restore(flags); - } + } else + res = __mips_test_and_change_bit(nr, addr); smp_llsc_mb(); diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 29d9c23c20c..ff2e0345e01 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index c4a82e841c7..a7b89371435 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for MIPS-specific library files.. # -lib-y += csum_partial.o delay.o memcpy.o memset.o \ +lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ strlen_user.o strncpy_user.o strnlen_user.o uncached.o obj-y += iomap.o diff --git a/arch/mips/lib/bitops.c b/arch/mips/lib/bitops.c new file mode 100644 index 00000000000..239a9c957b0 --- /dev/null +++ b/arch/mips/lib/bitops.c @@ -0,0 +1,179 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 1994-1997, 99, 2000, 06, 07 Ralf Baechle (ralf@linux-mips.org) + * Copyright (c) 1999, 2000 Silicon Graphics, Inc. + */ +#include +#include +#include + + +/** + * __mips_set_bit - Atomically set a bit in memory. This is called by + * set_bit() if it cannot find a faster solution. + * @nr: the bit to set + * @addr: the address to start counting from + */ +void __mips_set_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + *a |= mask; + raw_local_irq_restore(flags); +} +EXPORT_SYMBOL(__mips_set_bit); + + +/** + * __mips_clear_bit - Clears a bit in memory. This is called by clear_bit() if + * it cannot find a faster solution. + * @nr: Bit to clear + * @addr: Address to start counting from + */ +void __mips_clear_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + *a &= ~mask; + raw_local_irq_restore(flags); +} +EXPORT_SYMBOL(__mips_clear_bit); + + +/** + * __mips_change_bit - Toggle a bit in memory. This is called by change_bit() + * if it cannot find a faster solution. + * @nr: Bit to change + * @addr: Address to start counting from + */ +void __mips_change_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + *a ^= mask; + raw_local_irq_restore(flags); +} +EXPORT_SYMBOL(__mips_change_bit); + + +/** + * __mips_test_and_set_bit - Set a bit and return its old value. This is + * called by test_and_set_bit() if it cannot find a faster solution. + * @nr: Bit to set + * @addr: Address to count from + */ +int __mips_test_and_set_bit(unsigned long nr, + volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + unsigned long res; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a |= mask; + raw_local_irq_restore(flags); + return res; +} +EXPORT_SYMBOL(__mips_test_and_set_bit); + + +/** + * __mips_test_and_set_bit_lock - Set a bit and return its old value. This is + * called by test_and_set_bit_lock() if it cannot find a faster solution. + * @nr: Bit to set + * @addr: Address to count from + */ +int __mips_test_and_set_bit_lock(unsigned long nr, + volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + unsigned long res; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a |= mask; + raw_local_irq_restore(flags); + return res; +} +EXPORT_SYMBOL(__mips_test_and_set_bit_lock); + + +/** + * __mips_test_and_clear_bit - Clear a bit and return its old value. This is + * called by test_and_clear_bit() if it cannot find a faster solution. + * @nr: Bit to clear + * @addr: Address to count from + */ +int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + unsigned long res; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a &= ~mask; + raw_local_irq_restore(flags); + return res; +} +EXPORT_SYMBOL(__mips_test_and_clear_bit); + + +/** + * __mips_test_and_change_bit - Change a bit and return its old value. This is + * called by test_and_change_bit() if it cannot find a faster solution. + * @nr: Bit to change + * @addr: Address to count from + */ +int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr) +{ + volatile unsigned long *a = addr; + unsigned bit = nr & SZLONG_MASK; + unsigned long mask; + unsigned long flags; + unsigned long res; + + a += nr >> SZLONG_LOG; + mask = 1UL << bit; + raw_local_irq_save(flags); + res = (mask & *a); + *a ^= mask; + raw_local_irq_restore(flags); + return res; +} +EXPORT_SYMBOL(__mips_test_and_change_bit); -- cgit v1.2.3 From e97c5b609880d97313b13eb71830fca62cee50c2 Mon Sep 17 00:00:00 2001 From: Jim Quinlan Date: Thu, 6 Sep 2012 11:36:56 -0400 Subject: MIPS: Make irqflags.h functions preempt-safe for non-mipsr2 cpus For non MIPSr2 processors, such as the BMIPS 5000, calls to arch_local_irq_disable() and others may be preempted, and in doing so a stale value may be restored to c0_status. This fix disables preemption for such processors prior to the call and enables it after the call. Those functions that needed this fix have been "outlined" to mips-atomic.c, as they are no longer good candidates for inlining. This bug was observed in a BMIPS 5000, occuring once every few hours in a continuous reboot test. It was traced to the write_lock_irq() function which was being invoked in release_task() in exit.c. By placing a number of "nops" inbetween the mfc0/mtc0 pair in arch_local_irq_disable(), which is called by write_lock_irq(), we were able to greatly increase the occurance of this bug. Similarly, the application of this commit silenced the bug. Signed-off-by: Jim Quinlan Cc: linux-mips@linux-mips.org Cc: David Daney Cc: Kevin Cernekee cernekee@gmail.com Cc: Jim Quinlan Patchwork: https://patchwork.linux-mips.org/patch/4321/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/irqflags.h | 207 ++++++++++++++------------------------- arch/mips/lib/Makefile | 3 +- arch/mips/lib/mips-atomic.c | 176 +++++++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+), 133 deletions(-) create mode 100644 arch/mips/lib/mips-atomic.c diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index 309cbcd6909..9f3384c789d 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h @@ -16,83 +16,13 @@ #include #include -__asm__( - " .macro arch_local_irq_enable \n" - " .set push \n" - " .set reorder \n" - " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" - " ori $1, 0x400 \n" - " xori $1, 0x400 \n" - " mtc0 $1, $2, 1 \n" -#elif defined(CONFIG_CPU_MIPSR2) - " ei \n" -#else - " mfc0 $1,$12 \n" - " ori $1,0x1f \n" - " xori $1,0x1e \n" - " mtc0 $1,$12 \n" -#endif - " irq_enable_hazard \n" - " .set pop \n" - " .endm"); +#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) -extern void smtc_ipi_replay(void); - -static inline void arch_local_irq_enable(void) -{ -#ifdef CONFIG_MIPS_MT_SMTC - /* - * SMTC kernel needs to do a software replay of queued - * IPIs, at the cost of call overhead on each local_irq_enable() - */ - smtc_ipi_replay(); -#endif - __asm__ __volatile__( - "arch_local_irq_enable" - : /* no outputs */ - : /* no inputs */ - : "memory"); -} - - -/* - * For cli() we have to insert nops to make sure that the new value - * has actually arrived in the status register before the end of this - * macro. - * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs - * no nops at all. - */ -/* - * For TX49, operating only IE bit is not enough. - * - * If mfc0 $12 follows store and the mfc0 is last instruction of a - * page and fetching the next instruction causes TLB miss, the result - * of the mfc0 might wrongly contain EXL bit. - * - * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 - * - * Workaround: mask EXL bit of the result or place a nop before mfc0. - */ __asm__( " .macro arch_local_irq_disable\n" " .set push \n" " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 $1, $2, 1 \n" - " ori $1, 0x400 \n" - " .set noreorder \n" - " mtc0 $1, $2, 1 \n" -#elif defined(CONFIG_CPU_MIPSR2) " di \n" -#else - " mfc0 $1,$12 \n" - " ori $1,0x1f \n" - " xori $1,0x1f \n" - " .set noreorder \n" - " mtc0 $1,$12 \n" -#endif " irq_disable_hazard \n" " .set pop \n" " .endm \n"); @@ -106,46 +36,14 @@ static inline void arch_local_irq_disable(void) : "memory"); } -__asm__( - " .macro arch_local_save_flags flags \n" - " .set push \n" - " .set reorder \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 \\flags, $2, 1 \n" -#else - " mfc0 \\flags, $12 \n" -#endif - " .set pop \n" - " .endm \n"); - -static inline unsigned long arch_local_save_flags(void) -{ - unsigned long flags; - asm volatile("arch_local_save_flags %0" : "=r" (flags)); - return flags; -} __asm__( " .macro arch_local_irq_save result \n" " .set push \n" " .set reorder \n" " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - " mfc0 \\result, $2, 1 \n" - " ori $1, \\result, 0x400 \n" - " .set noreorder \n" - " mtc0 $1, $2, 1 \n" - " andi \\result, \\result, 0x400 \n" -#elif defined(CONFIG_CPU_MIPSR2) " di \\result \n" " andi \\result, 1 \n" -#else - " mfc0 \\result, $12 \n" - " ori $1, \\result, 0x1f \n" - " xori $1, 0x1f \n" - " .set noreorder \n" - " mtc0 $1, $12 \n" -#endif " irq_disable_hazard \n" " .set pop \n" " .endm \n"); @@ -160,61 +58,37 @@ static inline unsigned long arch_local_irq_save(void) return flags; } + __asm__( " .macro arch_local_irq_restore flags \n" " .set push \n" " .set noreorder \n" " .set noat \n" -#ifdef CONFIG_MIPS_MT_SMTC - "mfc0 $1, $2, 1 \n" - "andi \\flags, 0x400 \n" - "ori $1, 0x400 \n" - "xori $1, 0x400 \n" - "or \\flags, $1 \n" - "mtc0 \\flags, $2, 1 \n" -#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) +#if defined(CONFIG_IRQ_CPU) /* * Slow, but doesn't suffer from a relatively unlikely race * condition we're having since days 1. */ " beqz \\flags, 1f \n" - " di \n" + " di \n" " ei \n" "1: \n" -#elif defined(CONFIG_CPU_MIPSR2) +#else /* * Fast, dangerous. Life is fun, life is good. */ " mfc0 $1, $12 \n" " ins $1, \\flags, 0, 1 \n" " mtc0 $1, $12 \n" -#else - " mfc0 $1, $12 \n" - " andi \\flags, 1 \n" - " ori $1, 0x1f \n" - " xori $1, 0x1f \n" - " or \\flags, $1 \n" - " mtc0 \\flags, $12 \n" #endif " irq_disable_hazard \n" " .set pop \n" " .endm \n"); - static inline void arch_local_irq_restore(unsigned long flags) { unsigned long __tmp1; -#ifdef CONFIG_MIPS_MT_SMTC - /* - * SMTC kernel needs to do a software replay of queued - * IPIs, at the cost of branch and call overhead on each - * local_irq_restore() - */ - if (unlikely(!(flags & 0x0400))) - smtc_ipi_replay(); -#endif - __asm__ __volatile__( "arch_local_irq_restore\t%0" : "=r" (__tmp1) @@ -232,6 +106,75 @@ static inline void __arch_local_irq_restore(unsigned long flags) : "0" (flags) : "memory"); } +#else +/* Functions that require preempt_{dis,en}able() are in mips-atomic.c */ +void arch_local_irq_disable(void); +unsigned long arch_local_irq_save(void); +void arch_local_irq_restore(unsigned long flags); +void __arch_local_irq_restore(unsigned long flags); +#endif /* if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_MIPS_MT_SMTC) */ + + +__asm__( + " .macro arch_local_irq_enable \n" + " .set push \n" + " .set reorder \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" + " ori $1, 0x400 \n" + " xori $1, 0x400 \n" + " mtc0 $1, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) + " ei \n" +#else + " mfc0 $1,$12 \n" + " ori $1,0x1f \n" + " xori $1,0x1e \n" + " mtc0 $1,$12 \n" +#endif + " irq_enable_hazard \n" + " .set pop \n" + " .endm"); + +extern void smtc_ipi_replay(void); + +static inline void arch_local_irq_enable(void) +{ +#ifdef CONFIG_MIPS_MT_SMTC + /* + * SMTC kernel needs to do a software replay of queued + * IPIs, at the cost of call overhead on each local_irq_enable() + */ + smtc_ipi_replay(); +#endif + __asm__ __volatile__( + "arch_local_irq_enable" + : /* no outputs */ + : /* no inputs */ + : "memory"); +} + + +__asm__( + " .macro arch_local_save_flags flags \n" + " .set push \n" + " .set reorder \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 \\flags, $2, 1 \n" +#else + " mfc0 \\flags, $12 \n" +#endif + " .set pop \n" + " .endm \n"); + +static inline unsigned long arch_local_save_flags(void) +{ + unsigned long flags; + asm volatile("arch_local_save_flags %0" : "=r" (flags)); + return flags; +} + static inline int arch_irqs_disabled_flags(unsigned long flags) { @@ -245,7 +188,7 @@ static inline int arch_irqs_disabled_flags(unsigned long flags) #endif } -#endif +#endif /* #ifndef __ASSEMBLY__ */ /* * Do the CPU's IRQ-state tracing from assembly code. diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index a7b89371435..eeddc58802e 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -3,7 +3,8 @@ # lib-y += bitops.o csum_partial.o delay.o memcpy.o memset.o \ - strlen_user.o strncpy_user.o strnlen_user.o uncached.o + mips-atomic.o strlen_user.o strncpy_user.o \ + strnlen_user.o uncached.o obj-y += iomap.o obj-$(CONFIG_PCI) += iomap-pci.o diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c new file mode 100644 index 00000000000..e091430dbeb --- /dev/null +++ b/arch/mips/lib/mips-atomic.c @@ -0,0 +1,176 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle + * Copyright (C) 1996 by Paul M. Antoine + * Copyright (C) 1999 Silicon Graphics + * Copyright (C) 2000 MIPS Technologies, Inc. + */ +#include +#include +#include +#include +#include + +#if !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) + +/* + * For cli() we have to insert nops to make sure that the new value + * has actually arrived in the status register before the end of this + * macro. + * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs + * no nops at all. + */ +/* + * For TX49, operating only IE bit is not enough. + * + * If mfc0 $12 follows store and the mfc0 is last instruction of a + * page and fetching the next instruction causes TLB miss, the result + * of the mfc0 might wrongly contain EXL bit. + * + * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 + * + * Workaround: mask EXL bit of the result or place a nop before mfc0. + */ +__asm__( + " .macro arch_local_irq_disable\n" + " .set push \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 $1, $2, 1 \n" + " ori $1, 0x400 \n" + " .set noreorder \n" + " mtc0 $1, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) + /* see irqflags.h for inline function */ +#else + " mfc0 $1,$12 \n" + " ori $1,0x1f \n" + " xori $1,0x1f \n" + " .set noreorder \n" + " mtc0 $1,$12 \n" +#endif + " irq_disable_hazard \n" + " .set pop \n" + " .endm \n"); + +void arch_local_irq_disable(void) +{ + preempt_disable(); + __asm__ __volatile__( + "arch_local_irq_disable" + : /* no outputs */ + : /* no inputs */ + : "memory"); + preempt_enable(); +} +EXPORT_SYMBOL(arch_local_irq_disable); + + +__asm__( + " .macro arch_local_irq_save result \n" + " .set push \n" + " .set reorder \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + " mfc0 \\result, $2, 1 \n" + " ori $1, \\result, 0x400 \n" + " .set noreorder \n" + " mtc0 $1, $2, 1 \n" + " andi \\result, \\result, 0x400 \n" +#elif defined(CONFIG_CPU_MIPSR2) + /* see irqflags.h for inline function */ +#else + " mfc0 \\result, $12 \n" + " ori $1, \\result, 0x1f \n" + " xori $1, 0x1f \n" + " .set noreorder \n" + " mtc0 $1, $12 \n" +#endif + " irq_disable_hazard \n" + " .set pop \n" + " .endm \n"); + +unsigned long arch_local_irq_save(void) +{ + unsigned long flags; + preempt_disable(); + asm volatile("arch_local_irq_save\t%0" + : "=r" (flags) + : /* no inputs */ + : "memory"); + preempt_enable(); + return flags; +} +EXPORT_SYMBOL(arch_local_irq_save); + + +__asm__( + " .macro arch_local_irq_restore flags \n" + " .set push \n" + " .set noreorder \n" + " .set noat \n" +#ifdef CONFIG_MIPS_MT_SMTC + "mfc0 $1, $2, 1 \n" + "andi \\flags, 0x400 \n" + "ori $1, 0x400 \n" + "xori $1, 0x400 \n" + "or \\flags, $1 \n" + "mtc0 \\flags, $2, 1 \n" +#elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) + /* see irqflags.h for inline function */ +#elif defined(CONFIG_CPU_MIPSR2) + /* see irqflags.h for inline function */ +#else + " mfc0 $1, $12 \n" + " andi \\flags, 1 \n" + " ori $1, 0x1f \n" + " xori $1, 0x1f \n" + " or \\flags, $1 \n" + " mtc0 \\flags, $12 \n" +#endif + " irq_disable_hazard \n" + " .set pop \n" + " .endm \n"); + +void arch_local_irq_restore(unsigned long flags) +{ + unsigned long __tmp1; + +#ifdef CONFIG_MIPS_MT_SMTC + /* + * SMTC kernel needs to do a software replay of queued + * IPIs, at the cost of branch and call overhead on each + * local_irq_restore() + */ + if (unlikely(!(flags & 0x0400))) + smtc_ipi_replay(); +#endif + preempt_disable(); + __asm__ __volatile__( + "arch_local_irq_restore\t%0" + : "=r" (__tmp1) + : "0" (flags) + : "memory"); + preempt_enable(); +} +EXPORT_SYMBOL(arch_local_irq_restore); + + +void __arch_local_irq_restore(unsigned long flags) +{ + unsigned long __tmp1; + + preempt_disable(); + __asm__ __volatile__( + "arch_local_irq_restore\t%0" + : "=r" (__tmp1) + : "0" (flags) + : "memory"); + preempt_enable(); +} +EXPORT_SYMBOL(__arch_local_irq_restore); + +#endif /* !defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT_SMTC) */ -- cgit v1.2.3 From f1671bf5f0721356f0c7bc1b2fec54b1aaf40418 Mon Sep 17 00:00:00 2001 From: Jonas Aaberg Date: Thu, 25 Oct 2012 08:40:42 +0200 Subject: pinctrl/nomadik: make independent of prcmu driver Currently there are some unnecessary criss-cross dependencies between the PRCMU driver in MFD and a lot of other drivers, mainly because other drivers need to poke around in the PRCM register range. In cases like this there are actually just a few select registers that the pinctrl driver need to read/modify/write, and it turns out that no other driver is actually using these registers, so there are no concurrency issues whatsoever. So: don't let the location of the register range complicate things, just poke into these registers directly and skip a layer of indirection. Take this opportunity to add kerneldoc to the pinctrl state container. Cc: Loic Pallardy Signed-off-by: Jonas Aaberg Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik.c | 59 ++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 22f69375bb3..6a95d0438b6 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -30,20 +30,6 @@ #include /* Since we request GPIOs from ourself */ #include -/* - * For the U8500 archs, use the PRCMU register interface, for the older - * Nomadik, provide some stubs. The functions using these will only be - * called on the U8500 series. - */ -#ifdef CONFIG_ARCH_U8500 -#include -#else -static inline u32 prcmu_read(unsigned int reg) { - return 0; -} -static inline void prcmu_write(unsigned int reg, u32 value) {} -static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {} -#endif #include #include @@ -82,10 +68,18 @@ struct nmk_gpio_chip { u32 lowemi; }; +/** + * struct nmk_pinctrl - state container for the Nomadik pin controller + * @dev: containing device pointer + * @pctl: corresponding pin controller device + * @soc: SoC data for this specific chip + * @prcm_base: PRCM register range virtual base + */ struct nmk_pinctrl { struct device *dev; struct pinctrl_dev *pctl; const struct nmk_pinctrl_soc_data *soc; + void __iomem *prcm_base; }; static struct nmk_gpio_chip * @@ -247,6 +241,15 @@ nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset) dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio); } +static void nmk_write_masked(void __iomem *reg, u32 mask, u32 value) +{ + u32 val; + + val = readl(reg); + val = ((val & ~mask) | (value & mask)); + writel(val, reg); +} + static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, unsigned offset, unsigned alt_num) { @@ -285,8 +288,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, if (pin_desc->altcx[i].used == true) { reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; bit = pin_desc->altcx[i].control_bit; - if (prcmu_read(reg) & BIT(bit)) { - prcmu_write_masked(reg, BIT(bit), 0); + if (readl(npct->prcm_base + reg) & BIT(bit)) { + nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0); dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", offset, i+1); @@ -314,8 +317,8 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, if (pin_desc->altcx[i].used == true) { reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; bit = pin_desc->altcx[i].control_bit; - if (prcmu_read(reg) & BIT(bit)) { - prcmu_write_masked(reg, BIT(bit), 0); + if (readl(npct->prcm_base + reg) & BIT(bit)) { + nmk_write_masked(npct->prcm_base + reg, BIT(bit), 0); dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n", offset, i+1); @@ -327,7 +330,7 @@ static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct, bit = pin_desc->altcx[alt_index].control_bit; dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n", offset, alt_index+1); - prcmu_write_masked(reg, BIT(bit), BIT(bit)); + nmk_write_masked(npct->prcm_base + reg, BIT(bit), BIT(bit)); } static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, @@ -693,7 +696,7 @@ static int nmk_prcm_gpiocr_get_mode(struct pinctrl_dev *pctldev, int gpio) if (pin_desc->altcx[i].used == true) { reg = gpiocr_regs[pin_desc->altcx[i].reg_index]; bit = pin_desc->altcx[i].control_bit; - if (prcmu_read(reg) & BIT(bit)) + if (readl(npct->prcm_base + reg) & BIT(bit)) return NMK_GPIO_ALT_C+i+1; } } @@ -1851,6 +1854,7 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) const struct platform_device_id *platid = platform_get_device_id(pdev); struct device_node *np = pdev->dev.of_node; struct nmk_pinctrl *npct; + struct resource *res; unsigned int version = 0; int i; @@ -1872,6 +1876,20 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) if (version == PINCTRL_NMK_DB8540) nmk_pinctrl_db8540_init(&npct->soc); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) { + npct->prcm_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!npct->prcm_base) { + dev_err(&pdev->dev, + "failed to ioremap PRCM registers\n"); + return -ENOMEM; + } + } else { + dev_info(&pdev->dev, + "No PRCM base, assume no ALT-Cx control is available\n"); + } + /* * We need all the GPIO drivers to probe FIRST, or we will not be able * to obtain references to the struct gpio_chip * for them, and we @@ -1888,6 +1906,7 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) nmk_pinctrl_desc.pins = npct->soc->pins; nmk_pinctrl_desc.npins = npct->soc->npins; npct->dev = &pdev->dev; + npct->pctl = pinctrl_register(&nmk_pinctrl_desc, &pdev->dev, npct); if (!npct->pctl) { dev_err(&pdev->dev, "could not register Nomadik pinctrl driver\n"); -- cgit v1.2.3 From 9b472600b02f6771c04455f8a0019e2a98e0db88 Mon Sep 17 00:00:00 2001 From: Jean-Nicolas Graux Date: Wed, 7 Nov 2012 16:09:16 +0100 Subject: pinctrl/nomadik: db8540: fix moduartstmmux_oc4_1 pin group definition. One group definition was missing, so add it. Signed-off-by: Jean-Nicolas Graux Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik-db8540.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-nomadik-db8540.c b/drivers/pinctrl/pinctrl-nomadik-db8540.c index 52fc30181f7..bce0583738e 100644 --- a/drivers/pinctrl/pinctrl-nomadik-db8540.c +++ b/drivers/pinctrl/pinctrl-nomadik-db8540.c @@ -822,6 +822,7 @@ static const struct nmk_pingroup nmk_db8540_groups[] = { DB8540_PIN_GROUP(modaccuarttxrx_oc4_1, NMK_GPIO_ALT_C4), DB8540_PIN_GROUP(modaccuartrtscts_oc4_1, NMK_GPIO_ALT_C4), DB8540_PIN_GROUP(stmmod_oc4_1, NMK_GPIO_ALT_C4), + DB8540_PIN_GROUP(moduartstmmux_oc4_1, NMK_GPIO_ALT_C4), }; -- cgit v1.2.3 From 69d2591a829132492662bbfe164fcde5e44ad1c4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 9 Nov 2012 11:32:52 -0300 Subject: perf machine: Move more methods to machine.[ch] This time out of map.[ch] mostly, just code move plus a buch of 'self' removal, using machine or machines instead. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-j1vtux3vnu6wzmrjutpxnjcz@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 1 + tools/perf/tests/dso-data.c | 1 + tools/perf/util/dso.c | 1 + tools/perf/util/machine.c | 183 ++++++++++++++++++++++++++++++++++++++++ tools/perf/util/machine.h | 131 +++++++++++++++++++++++++++- tools/perf/util/map.c | 179 --------------------------------------- tools/perf/util/map.h | 93 -------------------- tools/perf/util/session.h | 5 +- tools/perf/util/symbol.c | 1 + tools/perf/util/symbol.h | 20 ----- 10 files changed, 318 insertions(+), 297 deletions(-) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 1aa9e992704..b5a544d1b38 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -10,6 +10,7 @@ #include "util/debug.h" #include "util/debugfs.h" #include "util/evlist.h" +#include "util/machine.h" #include "util/parse-options.h" #include "util/parse-events.h" #include "util/symbol.h" diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index c6caedeb1d6..0cd42fc9bc1 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -6,6 +6,7 @@ #include #include +#include "machine.h" #include "symbol.h" #define TEST_ASSERT_VAL(text, cond) \ diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index db24a3f0c82..d6d9a465acd 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1,5 +1,6 @@ #include "symbol.h" #include "dso.h" +#include "machine.h" #include "util.h" #include "debug.h" diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 4c6754ac6b2..1f09d0581e6 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -2,9 +2,192 @@ #include "event.h" #include "machine.h" #include "map.h" +#include "strlist.h" #include "thread.h" #include +int machine__init(struct machine *machine, const char *root_dir, pid_t pid) +{ + map_groups__init(&machine->kmaps); + RB_CLEAR_NODE(&machine->rb_node); + INIT_LIST_HEAD(&machine->user_dsos); + INIT_LIST_HEAD(&machine->kernel_dsos); + + machine->threads = RB_ROOT; + INIT_LIST_HEAD(&machine->dead_threads); + machine->last_match = NULL; + + machine->kmaps.machine = machine; + machine->pid = pid; + + machine->root_dir = strdup(root_dir); + if (machine->root_dir == NULL) + return -ENOMEM; + + if (pid != HOST_KERNEL_ID) { + struct thread *thread = machine__findnew_thread(machine, pid); + char comm[64]; + + if (thread == NULL) + return -ENOMEM; + + snprintf(comm, sizeof(comm), "[guest/%d]", pid); + thread__set_comm(thread, comm); + } + + return 0; +} + +static void dsos__delete(struct list_head *dsos) +{ + struct dso *pos, *n; + + list_for_each_entry_safe(pos, n, dsos, node) { + list_del(&pos->node); + dso__delete(pos); + } +} + +void machine__exit(struct machine *machine) +{ + map_groups__exit(&machine->kmaps); + dsos__delete(&machine->user_dsos); + dsos__delete(&machine->kernel_dsos); + free(machine->root_dir); + machine->root_dir = NULL; +} + +void machine__delete(struct machine *machine) +{ + machine__exit(machine); + free(machine); +} + +struct machine *machines__add(struct rb_root *machines, pid_t pid, + const char *root_dir) +{ + struct rb_node **p = &machines->rb_node; + struct rb_node *parent = NULL; + struct machine *pos, *machine = malloc(sizeof(*machine)); + + if (machine == NULL) + return NULL; + + if (machine__init(machine, root_dir, pid) != 0) { + free(machine); + return NULL; + } + + while (*p != NULL) { + parent = *p; + pos = rb_entry(parent, struct machine, rb_node); + if (pid < pos->pid) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + + rb_link_node(&machine->rb_node, parent, p); + rb_insert_color(&machine->rb_node, machines); + + return machine; +} + +struct machine *machines__find(struct rb_root *machines, pid_t pid) +{ + struct rb_node **p = &machines->rb_node; + struct rb_node *parent = NULL; + struct machine *machine; + struct machine *default_machine = NULL; + + while (*p != NULL) { + parent = *p; + machine = rb_entry(parent, struct machine, rb_node); + if (pid < machine->pid) + p = &(*p)->rb_left; + else if (pid > machine->pid) + p = &(*p)->rb_right; + else + return machine; + if (!machine->pid) + default_machine = machine; + } + + return default_machine; +} + +struct machine *machines__findnew(struct rb_root *machines, pid_t pid) +{ + char path[PATH_MAX]; + const char *root_dir = ""; + struct machine *machine = machines__find(machines, pid); + + if (machine && (machine->pid == pid)) + goto out; + + if ((pid != HOST_KERNEL_ID) && + (pid != DEFAULT_GUEST_KERNEL_ID) && + (symbol_conf.guestmount)) { + sprintf(path, "%s/%d", symbol_conf.guestmount, pid); + if (access(path, R_OK)) { + static struct strlist *seen; + + if (!seen) + seen = strlist__new(true, NULL); + + if (!strlist__has_entry(seen, path)) { + pr_err("Can't access file %s\n", path); + strlist__add(seen, path); + } + machine = NULL; + goto out; + } + root_dir = path; + } + + machine = machines__add(machines, pid, root_dir); +out: + return machine; +} + +void machines__process(struct rb_root *machines, + machine__process_t process, void *data) +{ + struct rb_node *nd; + + for (nd = rb_first(machines); nd; nd = rb_next(nd)) { + struct machine *pos = rb_entry(nd, struct machine, rb_node); + process(pos, data); + } +} + +char *machine__mmap_name(struct machine *machine, char *bf, size_t size) +{ + if (machine__is_host(machine)) + snprintf(bf, size, "[%s]", "kernel.kallsyms"); + else if (machine__is_default_guest(machine)) + snprintf(bf, size, "[%s]", "guest.kernel.kallsyms"); + else { + snprintf(bf, size, "[%s.%d]", "guest.kernel.kallsyms", + machine->pid); + } + + return bf; +} + +void machines__set_id_hdr_size(struct rb_root *machines, u16 id_hdr_size) +{ + struct rb_node *node; + struct machine *machine; + + for (node = rb_first(machines); node; node = rb_next(node)) { + machine = rb_entry(node, struct machine, rb_node); + machine->id_hdr_size = id_hdr_size; + } + + return; +} + static struct thread *__machine__findnew_thread(struct machine *machine, pid_t pid, bool create) { diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index df152f1768b..b7cde7467d5 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -2,11 +2,40 @@ #define __PERF_MACHINE_H #include +#include +#include "map.h" +struct branch_stack; +struct perf_evsel; +struct perf_sample; +struct symbol; struct thread; -struct machine; union perf_event; +/* Native host kernel uses -1 as pid index in machine */ +#define HOST_KERNEL_ID (-1) +#define DEFAULT_GUEST_KERNEL_ID (0) + +struct machine { + struct rb_node rb_node; + pid_t pid; + u16 id_hdr_size; + char *root_dir; + struct rb_root threads; + struct list_head dead_threads; + struct thread *last_match; + struct list_head user_dsos; + struct list_head kernel_dsos; + struct map_groups kmaps; + struct map *vmlinux_maps[MAP__NR_TYPES]; +}; + +static inline +struct map *machine__kernel_map(struct machine *machine, enum map_type type) +{ + return machine->vmlinux_maps[type]; +} + struct thread *machine__find_thread(struct machine *machine, pid_t pid); int machine__process_comm_event(struct machine *machine, union perf_event *event); @@ -16,4 +45,104 @@ int machine__process_lost_event(struct machine *machine, union perf_event *event int machine__process_mmap_event(struct machine *machine, union perf_event *event); int machine__process_event(struct machine *machine, union perf_event *event); +typedef void (*machine__process_t)(struct machine *machine, void *data); + +void machines__process(struct rb_root *machines, + machine__process_t process, void *data); + +struct machine *machines__add(struct rb_root *machines, pid_t pid, + const char *root_dir); +struct machine *machines__find_host(struct rb_root *machines); +struct machine *machines__find(struct rb_root *machines, pid_t pid); +struct machine *machines__findnew(struct rb_root *machines, pid_t pid); + +void machines__set_id_hdr_size(struct rb_root *machines, u16 id_hdr_size); +char *machine__mmap_name(struct machine *machine, char *bf, size_t size); + +int machine__init(struct machine *machine, const char *root_dir, pid_t pid); +void machine__exit(struct machine *machine); +void machine__delete(struct machine *machine); + + +struct branch_info *machine__resolve_bstack(struct machine *machine, + struct thread *thread, + struct branch_stack *bs); +int machine__resolve_callchain(struct machine *machine, + struct perf_evsel *evsel, + struct thread *thread, + struct perf_sample *sample, + struct symbol **parent); + +/* + * Default guest kernel is defined by parameter --guestkallsyms + * and --guestmodules + */ +static inline bool machine__is_default_guest(struct machine *machine) +{ + return machine ? machine->pid == DEFAULT_GUEST_KERNEL_ID : false; +} + +static inline bool machine__is_host(struct machine *machine) +{ + return machine ? machine->pid == HOST_KERNEL_ID : false; +} + +struct thread *machine__findnew_thread(struct machine *machine, pid_t pid); +void machine__remove_thread(struct machine *machine, struct thread *th); + +size_t machine__fprintf(struct machine *machine, FILE *fp); + +static inline +struct symbol *machine__find_kernel_symbol(struct machine *machine, + enum map_type type, u64 addr, + struct map **mapp, + symbol_filter_t filter) +{ + return map_groups__find_symbol(&machine->kmaps, type, addr, + mapp, filter); +} + +static inline +struct symbol *machine__find_kernel_function(struct machine *machine, u64 addr, + struct map **mapp, + symbol_filter_t filter) +{ + return machine__find_kernel_symbol(machine, MAP__FUNCTION, addr, + mapp, filter); +} + +static inline +struct symbol *machine__find_kernel_function_by_name(struct machine *machine, + const char *name, + struct map **mapp, + symbol_filter_t filter) +{ + return map_groups__find_function_by_name(&machine->kmaps, name, mapp, + filter); +} + +struct map *machine__new_module(struct machine *machine, u64 start, + const char *filename); + +int machine__load_kallsyms(struct machine *machine, const char *filename, + enum map_type type, symbol_filter_t filter); +int machine__load_vmlinux_path(struct machine *machine, enum map_type type, + symbol_filter_t filter); + +size_t machine__fprintf_dsos_buildid(struct machine *machine, + FILE *fp, bool with_hits); +size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp); +size_t machines__fprintf_dsos_buildid(struct rb_root *machines, + FILE *fp, bool with_hits); + +void machine__destroy_kernel_maps(struct machine *machine); +int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel); +int machine__create_kernel_maps(struct machine *machine); + +int machines__create_kernel_maps(struct rb_root *machines, pid_t pid); +int machines__create_guest_kernel_maps(struct rb_root *machines); +void machines__destroy_guest_kernel_maps(struct rb_root *machines); + +size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp); + #endif /* __PERF_MACHINE_H */ diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 579187865f0..0328d45c4f2 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -590,182 +590,3 @@ struct map *maps__find(struct rb_root *maps, u64 ip) return NULL; } - -int machine__init(struct machine *self, const char *root_dir, pid_t pid) -{ - map_groups__init(&self->kmaps); - RB_CLEAR_NODE(&self->rb_node); - INIT_LIST_HEAD(&self->user_dsos); - INIT_LIST_HEAD(&self->kernel_dsos); - - self->threads = RB_ROOT; - INIT_LIST_HEAD(&self->dead_threads); - self->last_match = NULL; - - self->kmaps.machine = self; - self->pid = pid; - self->root_dir = strdup(root_dir); - if (self->root_dir == NULL) - return -ENOMEM; - - if (pid != HOST_KERNEL_ID) { - struct thread *thread = machine__findnew_thread(self, pid); - char comm[64]; - - if (thread == NULL) - return -ENOMEM; - - snprintf(comm, sizeof(comm), "[guest/%d]", pid); - thread__set_comm(thread, comm); - } - - return 0; -} - -static void dsos__delete(struct list_head *self) -{ - struct dso *pos, *n; - - list_for_each_entry_safe(pos, n, self, node) { - list_del(&pos->node); - dso__delete(pos); - } -} - -void machine__exit(struct machine *self) -{ - map_groups__exit(&self->kmaps); - dsos__delete(&self->user_dsos); - dsos__delete(&self->kernel_dsos); - free(self->root_dir); - self->root_dir = NULL; -} - -void machine__delete(struct machine *self) -{ - machine__exit(self); - free(self); -} - -struct machine *machines__add(struct rb_root *self, pid_t pid, - const char *root_dir) -{ - struct rb_node **p = &self->rb_node; - struct rb_node *parent = NULL; - struct machine *pos, *machine = malloc(sizeof(*machine)); - - if (!machine) - return NULL; - - if (machine__init(machine, root_dir, pid) != 0) { - free(machine); - return NULL; - } - - while (*p != NULL) { - parent = *p; - pos = rb_entry(parent, struct machine, rb_node); - if (pid < pos->pid) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; - } - - rb_link_node(&machine->rb_node, parent, p); - rb_insert_color(&machine->rb_node, self); - - return machine; -} - -struct machine *machines__find(struct rb_root *self, pid_t pid) -{ - struct rb_node **p = &self->rb_node; - struct rb_node *parent = NULL; - struct machine *machine; - struct machine *default_machine = NULL; - - while (*p != NULL) { - parent = *p; - machine = rb_entry(parent, struct machine, rb_node); - if (pid < machine->pid) - p = &(*p)->rb_left; - else if (pid > machine->pid) - p = &(*p)->rb_right; - else - return machine; - if (!machine->pid) - default_machine = machine; - } - - return default_machine; -} - -struct machine *machines__findnew(struct rb_root *self, pid_t pid) -{ - char path[PATH_MAX]; - const char *root_dir = ""; - struct machine *machine = machines__find(self, pid); - - if (machine && (machine->pid == pid)) - goto out; - - if ((pid != HOST_KERNEL_ID) && - (pid != DEFAULT_GUEST_KERNEL_ID) && - (symbol_conf.guestmount)) { - sprintf(path, "%s/%d", symbol_conf.guestmount, pid); - if (access(path, R_OK)) { - static struct strlist *seen; - - if (!seen) - seen = strlist__new(true, NULL); - - if (!strlist__has_entry(seen, path)) { - pr_err("Can't access file %s\n", path); - strlist__add(seen, path); - } - machine = NULL; - goto out; - } - root_dir = path; - } - - machine = machines__add(self, pid, root_dir); - -out: - return machine; -} - -void machines__process(struct rb_root *self, machine__process_t process, void *data) -{ - struct rb_node *nd; - - for (nd = rb_first(self); nd; nd = rb_next(nd)) { - struct machine *pos = rb_entry(nd, struct machine, rb_node); - process(pos, data); - } -} - -char *machine__mmap_name(struct machine *self, char *bf, size_t size) -{ - if (machine__is_host(self)) - snprintf(bf, size, "[%s]", "kernel.kallsyms"); - else if (machine__is_default_guest(self)) - snprintf(bf, size, "[%s]", "guest.kernel.kallsyms"); - else - snprintf(bf, size, "[%s.%d]", "guest.kernel.kallsyms", self->pid); - - return bf; -} - -void machines__set_id_hdr_size(struct rb_root *machines, u16 id_hdr_size) -{ - struct rb_node *node; - struct machine *machine; - - for (node = rb_first(machines); node; node = rb_next(node)) { - machine = rb_entry(node, struct machine, rb_node); - machine->id_hdr_size = id_hdr_size; - } - - return; -} diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index d2250fc97e2..bcb39e2a696 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -57,30 +57,6 @@ struct map_groups { struct machine *machine; }; -/* Native host kernel uses -1 as pid index in machine */ -#define HOST_KERNEL_ID (-1) -#define DEFAULT_GUEST_KERNEL_ID (0) - -struct machine { - struct rb_node rb_node; - pid_t pid; - u16 id_hdr_size; - char *root_dir; - struct rb_root threads; - struct list_head dead_threads; - struct thread *last_match; - struct list_head user_dsos; - struct list_head kernel_dsos; - struct map_groups kmaps; - struct map *vmlinux_maps[MAP__NR_TYPES]; -}; - -static inline -struct map *machine__kernel_map(struct machine *self, enum map_type type) -{ - return self->vmlinux_maps[type]; -} - static inline struct kmap *map__kmap(struct map *self) { return (struct kmap *)(self + 1); @@ -143,44 +119,9 @@ int map_groups__clone(struct map_groups *mg, size_t map_groups__fprintf(struct map_groups *mg, int verbose, FILE *fp); size_t map_groups__fprintf_maps(struct map_groups *mg, int verbose, FILE *fp); -typedef void (*machine__process_t)(struct machine *self, void *data); - -void machines__process(struct rb_root *self, machine__process_t process, void *data); -struct machine *machines__add(struct rb_root *self, pid_t pid, - const char *root_dir); -struct machine *machines__find_host(struct rb_root *self); -struct machine *machines__find(struct rb_root *self, pid_t pid); -struct machine *machines__findnew(struct rb_root *self, pid_t pid); -void machines__set_id_hdr_size(struct rb_root *self, u16 id_hdr_size); -char *machine__mmap_name(struct machine *self, char *bf, size_t size); -int machine__init(struct machine *self, const char *root_dir, pid_t pid); -void machine__exit(struct machine *self); -void machine__delete(struct machine *self); - -struct perf_evsel; -struct perf_sample; -int machine__resolve_callchain(struct machine *machine, - struct perf_evsel *evsel, - struct thread *thread, - struct perf_sample *sample, - struct symbol **parent); int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name, u64 addr); -/* - * Default guest kernel is defined by parameter --guestkallsyms - * and --guestmodules - */ -static inline bool machine__is_default_guest(struct machine *self) -{ - return self ? self->pid == DEFAULT_GUEST_KERNEL_ID : false; -} - -static inline bool machine__is_host(struct machine *self) -{ - return self ? self->pid == HOST_KERNEL_ID : false; -} - static inline void map_groups__insert(struct map_groups *mg, struct map *map) { maps__insert(&mg->maps[map->type], map); @@ -209,29 +150,6 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg, struct map **mapp, symbol_filter_t filter); - -struct thread *machine__findnew_thread(struct machine *machine, pid_t pid); -void machine__remove_thread(struct machine *machine, struct thread *th); - -size_t machine__fprintf(struct machine *machine, FILE *fp); - -static inline -struct symbol *machine__find_kernel_symbol(struct machine *self, - enum map_type type, u64 addr, - struct map **mapp, - symbol_filter_t filter) -{ - return map_groups__find_symbol(&self->kmaps, type, addr, mapp, filter); -} - -static inline -struct symbol *machine__find_kernel_function(struct machine *self, u64 addr, - struct map **mapp, - symbol_filter_t filter) -{ - return machine__find_kernel_symbol(self, MAP__FUNCTION, addr, mapp, filter); -} - static inline struct symbol *map_groups__find_function_by_name(struct map_groups *mg, const char *name, struct map **mapp, @@ -240,22 +158,11 @@ struct symbol *map_groups__find_function_by_name(struct map_groups *mg, return map_groups__find_symbol_by_name(mg, MAP__FUNCTION, name, mapp, filter); } -static inline -struct symbol *machine__find_kernel_function_by_name(struct machine *self, - const char *name, - struct map **mapp, - symbol_filter_t filter) -{ - return map_groups__find_function_by_name(&self->kmaps, name, mapp, - filter); -} - int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map, int verbose, FILE *fp); struct map *map_groups__find_by_name(struct map_groups *mg, enum map_type type, const char *name); -struct map *machine__new_module(struct machine *self, u64 start, const char *filename); void map_groups__flush(struct map_groups *mg); diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index dd6426163ba..18d1222b05a 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -4,6 +4,7 @@ #include "hist.h" #include "event.h" #include "header.h" +#include "machine.h" #include "symbol.h" #include "thread.h" #include @@ -68,10 +69,6 @@ int perf_session__resolve_callchain(struct perf_session *self, struct perf_evsel struct ip_callchain *chain, struct symbol **parent); -struct branch_info *machine__resolve_bstack(struct machine *self, - struct thread *thread, - struct branch_stack *bs); - bool perf_session__has_traces(struct perf_session *self, const char *msg); void mem_bswap_64(void *src, int byte_size); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 624c65e6ab9..295f8d4feed 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -12,6 +12,7 @@ #include "build-id.h" #include "util.h" #include "debug.h" +#include "machine.h" #include "symbol.h" #include "strlist.h" diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 863b05bea5f..04ccf296208 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -200,16 +200,6 @@ int dso__load_vmlinux_path(struct dso *dso, struct map *map, symbol_filter_t filter); int dso__load_kallsyms(struct dso *dso, const char *filename, struct map *map, symbol_filter_t filter); -int machine__load_kallsyms(struct machine *machine, const char *filename, - enum map_type type, symbol_filter_t filter); -int machine__load_vmlinux_path(struct machine *machine, enum map_type type, - symbol_filter_t filter); - -size_t machine__fprintf_dsos_buildid(struct machine *machine, - FILE *fp, bool with_hits); -size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp); -size_t machines__fprintf_dsos_buildid(struct rb_root *machines, - FILE *fp, bool with_hits); struct symbol *dso__find_symbol(struct dso *dso, enum map_type type, u64 addr); @@ -224,14 +214,6 @@ int kallsyms__parse(const char *filename, void *arg, int filename__read_debuglink(const char *filename, char *debuglink, size_t size); -void machine__destroy_kernel_maps(struct machine *machine); -int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel); -int machine__create_kernel_maps(struct machine *machine); - -int machines__create_kernel_maps(struct rb_root *machines, pid_t pid); -int machines__create_guest_kernel_maps(struct rb_root *machines); -void machines__destroy_guest_kernel_maps(struct rb_root *machines); - int symbol__init(void); void symbol__exit(void); void symbol__elf_init(void); @@ -242,8 +224,6 @@ size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp); size_t symbol__fprintf(struct symbol *sym, FILE *fp); bool symbol_type__is_a(char symbol_type, enum map_type map_type); -size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp); - int dso__test_data(void); int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, struct symsrc *runtime_ss, symbol_filter_t filter, -- cgit v1.2.3 From 41269386b0898b12f82e290604691111a0cdf75b Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 7 Nov 2012 23:52:52 +0100 Subject: [media] dvb_usb_v2: switch interruptible mutex to normal Fixes error: dvb_usb_v2: pid_filter() failed=-4 error code -4 is EINTR, Interrupted system call That error blocks I/O in some cases as -EINTR error was returned by the mutex which was protecting USB control messages. We want configure hardware to sleep mode on every case after tuning is stopped. That kind of behavior blocks it, leaving hardware some unwanted state in worst case. That error was seen every time when af9015 was plugged to USB1.1 which leads use of hardware PID filters. Stop tuning (tzap) with ctrl+c failed as driver tries to remove hardware PID filters. Tested with every hardware which uses routine in question. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c index 0431beed0ef..5716662b483 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c @@ -32,9 +32,7 @@ int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, return -EINVAL; } - ret = mutex_lock_interruptible(&d->usb_mutex); - if (ret < 0) - return ret; + mutex_lock(&d->usb_mutex); dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf); -- cgit v1.2.3 From 12f8f74b2a4d26c4facfa7ef99487cf0930f6ef7 Mon Sep 17 00:00:00 2001 From: Zheng Liu Date: Thu, 8 Nov 2012 16:58:46 -0800 Subject: perf test: fix a build error on builtin-test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recently I build perf and get a build error on builtin-test.c. The error is as following: $ make CC perf.o CC builtin-test.o cc1: warnings being treated as errors builtin-test.c: In function ‘sched__get_first_possible_cpu’: builtin-test.c:977: warning: implicit declaration of function ‘CPU_ALLOC’ builtin-test.c:977: warning: nested extern declaration of ‘CPU_ALLOC’ builtin-test.c:977: warning: assignment makes pointer from integer without a cast builtin-test.c:978: warning: implicit declaration of function ‘CPU_ALLOC_SIZE’ builtin-test.c:978: warning: nested extern declaration of ‘CPU_ALLOC_SIZE’ builtin-test.c:979: warning: implicit declaration of function ‘CPU_ZERO_S’ builtin-test.c:979: warning: nested extern declaration of ‘CPU_ZERO_S’ builtin-test.c:982: warning: implicit declaration of function ‘CPU_FREE’ builtin-test.c:982: warning: nested extern declaration of ‘CPU_FREE’ builtin-test.c:992: warning: implicit declaration of function ‘CPU_ISSET_S’ builtin-test.c:992: warning: nested extern declaration of ‘CPU_ISSET_S’ builtin-test.c:998: warning: implicit declaration of function ‘CPU_CLR_S’ builtin-test.c:998: warning: nested extern declaration of ‘CPU_CLR_S’ make: *** [builtin-test.o] Error 1 This problem is introduced in 3e7c439a. CPU_ALLOC and related macros are missing in sched__get_first_possible_cpu function. In 54489c18, commiter mentioned that CPU_ALLOC has been removed. So CPU_ALLOC calls in this function are removed to let perf to be built. Signed-off-by: Vinson Lee Signed-off-by: Zheng Liu Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Vinson Lee Cc: Zheng Liu Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/1352422726-31114-1-git-send-email-vlee@twitter.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index b5a544d1b38..5d4354e2445 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -605,19 +605,13 @@ out_free_threads: #undef nsyscalls } -static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t **maskp, - size_t *sizep) +static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp) { - cpu_set_t *mask; - size_t size; int i, cpu = -1, nrcpus = 1024; realloc: - mask = CPU_ALLOC(nrcpus); - size = CPU_ALLOC_SIZE(nrcpus); - CPU_ZERO_S(size, mask); + CPU_ZERO(maskp); - if (sched_getaffinity(pid, size, mask) == -1) { - CPU_FREE(mask); + if (sched_getaffinity(pid, sizeof(*maskp), maskp) == -1) { if (errno == EINVAL && nrcpus < (1024 << 8)) { nrcpus = nrcpus << 2; goto realloc; @@ -627,19 +621,14 @@ realloc: } for (i = 0; i < nrcpus; i++) { - if (CPU_ISSET_S(i, size, mask)) { - if (cpu == -1) { + if (CPU_ISSET(i, maskp)) { + if (cpu == -1) cpu = i; - *maskp = mask; - *sizep = size; - } else - CPU_CLR_S(i, size, mask); + else + CPU_CLR(i, maskp); } } - if (cpu == -1) - CPU_FREE(mask); - return cpu; } @@ -654,8 +643,8 @@ static int test__PERF_RECORD(void) .freq = 10, .mmap_pages = 256, }; - cpu_set_t *cpu_mask = NULL; - size_t cpu_mask_size = 0; + cpu_set_t cpu_mask; + size_t cpu_mask_size = sizeof(cpu_mask); struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); struct perf_evsel *evsel; struct perf_sample sample; @@ -719,8 +708,7 @@ static int test__PERF_RECORD(void) evsel->attr.sample_type |= PERF_SAMPLE_TIME; perf_evlist__config_attrs(evlist, &opts); - err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask, - &cpu_mask_size); + err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask); if (err < 0) { pr_debug("sched__get_first_possible_cpu: %s\n", strerror(errno)); goto out_delete_evlist; @@ -731,9 +719,9 @@ static int test__PERF_RECORD(void) /* * So that we can check perf_sample.cpu on all the samples. */ - if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, cpu_mask) < 0) { + if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) { pr_debug("sched_setaffinity: %s\n", strerror(errno)); - goto out_free_cpu_mask; + goto out_delete_evlist; } /* @@ -917,8 +905,6 @@ found_exit: } out_err: perf_evlist__munmap(evlist); -out_free_cpu_mask: - CPU_FREE(cpu_mask); out_delete_evlist: perf_evlist__delete(evlist); out: -- cgit v1.2.3 From c36a7ff4578ab6294885aef5ef241aeec4cdb1f0 Mon Sep 17 00:00:00 2001 From: Jiri Engelthaler Date: Thu, 20 Sep 2012 16:49:50 +0200 Subject: mtd: slram: invalid checking of absolute end address Fixed parsing end absolute address. Signed-off-by: Jiri Engelthaler Cc: stable@vger.kernel.org Signed-off-by: Artem Bityutskiy --- drivers/mtd/devices/slram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index 8f52fc858e4..5a5cd2ace4a 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c @@ -240,7 +240,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength) if (*(szlength) != '+') { devlength = simple_strtoul(szlength, &buffer, 0); - devlength = handle_unit(devlength, buffer) - devstart; + devlength = handle_unit(devlength, buffer); if (devlength < devstart) goto err_out; -- cgit v1.2.3 From 0131950ebd146b5e31508233352d6f4625af25b1 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sat, 22 Sep 2012 11:42:31 +0530 Subject: mtd: onenand: Make flexonenand_set_boundary static Fixes the following sparse warning: drivers/mtd/onenand/onenand_base.c:3697:5: warning: symbol 'flexonenand_set_boundary' was not declared. Should it be static? Signed-off-by: Sachin Kamat Acked-by: Kyungmin Park Signed-off-by: Artem Bityutskiy --- drivers/mtd/onenand/onenand_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 7153e0d2710..b3f41f20062 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -3694,7 +3694,7 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int * flexonenand_set_boundary - Writes the SLC boundary * @param mtd - mtd info structure */ -int flexonenand_set_boundary(struct mtd_info *mtd, int die, +static int flexonenand_set_boundary(struct mtd_info *mtd, int die, int boundary, int lock) { struct onenand_chip *this = mtd->priv; -- cgit v1.2.3 From 5ffd3412ae5536a4c57469cb8ea31887121dcb2e Mon Sep 17 00:00:00 2001 From: Thomas Betker Date: Wed, 17 Oct 2012 22:59:30 +0200 Subject: jffs2: Fix lock acquisition order bug in jffs2_write_begin jffs2_write_begin() first acquires the page lock, then f->sem. This causes an AB-BA deadlock with jffs2_garbage_collect_live(), which first acquires f->sem, then the page lock: jffs2_garbage_collect_live mutex_lock(&f->sem) (A) jffs2_garbage_collect_dnode jffs2_gc_fetch_page read_cache_page_async do_read_cache_page lock_page(page) (B) jffs2_write_begin grab_cache_page_write_begin find_lock_page lock_page(page) (B) mutex_lock(&f->sem) (A) We fix this by restructuring jffs2_write_begin() to take f->sem before the page lock. However, we make sure that f->sem is not held when calling jffs2_reserve_space(), as this is not permitted by the locking rules. The deadlock above was observed multiple times on an SoC with a dual ARMv7 (Cortex-A9), running the long-term 3.4.11 kernel; it occurred when using scp to copy files from a host system to the ARM target system. The fix was heavily tested on the same target system. Cc: stable@vger.kernel.org Signed-off-by: Thomas Betker Acked-by: Joakim Tjernlund Signed-off-by: Artem Bityutskiy --- fs/jffs2/file.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 60ef3fb707f..1506673c087 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -138,33 +138,39 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, struct page *pg; struct inode *inode = mapping->host; struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); + struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); + struct jffs2_raw_inode ri; + uint32_t alloc_len = 0; pgoff_t index = pos >> PAGE_CACHE_SHIFT; uint32_t pageofs = index << PAGE_CACHE_SHIFT; int ret = 0; + jffs2_dbg(1, "%s()\n", __func__); + + if (pageofs > inode->i_size) { + ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, + ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); + if (ret) + return ret; + } + + mutex_lock(&f->sem); pg = grab_cache_page_write_begin(mapping, index, flags); - if (!pg) + if (!pg) { + if (alloc_len) + jffs2_complete_reservation(c); + mutex_unlock(&f->sem); return -ENOMEM; + } *pagep = pg; - jffs2_dbg(1, "%s()\n", __func__); - - if (pageofs > inode->i_size) { + if (alloc_len) { /* Make new hole frag from old EOF to new page */ - struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); - struct jffs2_raw_inode ri; struct jffs2_full_dnode *fn; - uint32_t alloc_len; jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", (unsigned int)inode->i_size, pageofs); - ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, - ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); - if (ret) - goto out_page; - - mutex_lock(&f->sem); memset(&ri, 0, sizeof(ri)); ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); @@ -191,7 +197,6 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, if (IS_ERR(fn)) { ret = PTR_ERR(fn); jffs2_complete_reservation(c); - mutex_unlock(&f->sem); goto out_page; } ret = jffs2_add_full_dnode_to_inode(c, f, fn); @@ -206,12 +211,10 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, jffs2_mark_node_obsolete(c, fn->raw); jffs2_free_full_dnode(fn); jffs2_complete_reservation(c); - mutex_unlock(&f->sem); goto out_page; } jffs2_complete_reservation(c); inode->i_size = pageofs; - mutex_unlock(&f->sem); } /* @@ -220,18 +223,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, * case of a short-copy. */ if (!PageUptodate(pg)) { - mutex_lock(&f->sem); ret = jffs2_do_readpage_nolock(inode, pg); - mutex_unlock(&f->sem); if (ret) goto out_page; } + mutex_unlock(&f->sem); jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags); return ret; out_page: unlock_page(pg); page_cache_release(pg); + mutex_unlock(&f->sem); return ret; } -- cgit v1.2.3 From 476e44cb19f1fbf2d5883dddcc0ce31b33b45915 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 19 Oct 2012 20:10:46 +0300 Subject: Bluetooth: Fix having bogus entries in mgmt_read_index_list reply The mgmt_read_index_list uses one loop to calculate the max needed size of its response with the help of an upper-bound of the controller count. The second loop is more strict as it checks for HCI_SETUP (which might have gotten set after the first loop) and could result in some indexes being skipped. Because of this the function needs to readjust the event length and index count after filling in the response array. Signed-off-by: Johan Hedberg Cc: stable@vger.kernel.org Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index aa2ea0a8142..2cfabe27d3e 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -326,7 +326,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, struct hci_dev *d; size_t rp_len; u16 count; - int i, err; + int err; BT_DBG("sock %p", sk); @@ -347,9 +347,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, return -ENOMEM; } - rp->num_controllers = cpu_to_le16(count); - - i = 0; + count = 0; list_for_each_entry(d, &hci_dev_list, list) { if (test_bit(HCI_SETUP, &d->dev_flags)) continue; @@ -357,10 +355,13 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, if (!mgmt_valid_hdev(d)) continue; - rp->index[i++] = cpu_to_le16(d->id); + rp->index[count++] = cpu_to_le16(d->id); BT_DBG("Added hci%u", d->id); } + rp->num_controllers = cpu_to_le16(count); + rp_len = sizeof(*rp) + (2 * count); + read_unlock(&hci_dev_list_lock); err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp, -- cgit v1.2.3 From 896ea28ea824d49671fc7e9315d9c5be491a644f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20S=C3=A9rgio?= Date: Thu, 25 Oct 2012 16:55:51 -0300 Subject: Bluetooth: Fix error status when pairing fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When pairing fails due to wrong confirm value, the management layer doesn't report a proper error status. It sends MGMT_STATUS_CONNECT_FAILED instead of MGMT_STATUS_AUTH_FAILED. Most of management functions that receive a status as a parameter expects for it to be encoded as a HCI status. But when a SMP pairing fails, the SMP layer sends the SMP reason as the error status to the management layer. This commit maps all SMP reasons to HCI_ERROR_AUTH_FAILURE, which will be converted to MGMT_STATUS_AUTH_FAILED in the management layer. Reported-by: Claudio Takahasi Reviewed-by: João Paulo Rechi Vita Signed-off-by: Paulo Sérgio Signed-off-by: Gustavo Padovan --- net/bluetooth/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 2ac8d50861e..a5923378bdf 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -267,7 +267,7 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags); mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, - hcon->dst_type, reason); + hcon->dst_type, HCI_ERROR_AUTH_FAILURE); cancel_delayed_work_sync(&conn->security_timer); -- cgit v1.2.3 From fbe96d6ff9f4e361e1b2ec0a30140e17af7e3854 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 30 Oct 2012 01:35:40 -0700 Subject: Bluetooth: Notify about device registration before power on It is important that the monitor interface gets notified about a new device before its power on procedure has been started. For some reason that is no longer working as expected and the power on procedure runs first. It is safe to just notify about device registration and trigger the power on procedure afterwards. Signed-off-by: Marcel Holtmann Acked-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- net/bluetooth/hci_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8a0ce706aeb..a0a2f97b9c6 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1754,11 +1754,11 @@ int hci_register_dev(struct hci_dev *hdev) if (hdev->dev_type != HCI_AMP) set_bit(HCI_AUTO_OFF, &hdev->dev_flags); - schedule_work(&hdev->power_on); - hci_notify(hdev, HCI_DEV_REG); hci_dev_hold(hdev); + schedule_work(&hdev->power_on); + return id; err_wqueue: -- cgit v1.2.3 From acd9454433e28c1a365d8b069813c35c1c3a8ac3 Mon Sep 17 00:00:00 2001 From: Marcos Chaparro Date: Tue, 6 Nov 2012 16:19:11 -0300 Subject: Bluetooth: ath3k: Add support for VAIO VPCEH [0489:e027] Added Atheros AR3011 internal bluetooth device found in Sony VAIO VPCEH to the devices list. Before this, the bluetooth module was identified as an Foxconn / Hai bluetooth device [0489:e027], now it claims to be an AtherosAR3011 Bluetooth [0cf3:3005]. T: Bus=01 Lev=02 Prnt=02 Port=04 Cnt=02 Dev#= 4 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e027 Rev= 0.01 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms Signed-off-by: Marcos Chaparro Signed-off-by: Gustavo Padovan --- drivers/bluetooth/ath3k.c | 1 + drivers/bluetooth/btusb.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index fc2de5528dc..b00000e8aef 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -67,6 +67,7 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x13d3, 0x3304) }, { USB_DEVICE(0x0930, 0x0215) }, { USB_DEVICE(0x0489, 0xE03D) }, + { USB_DEVICE(0x0489, 0xE027) }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03F0, 0x311D) }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index debda27df9b..ee82f2fb65f 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -124,6 +124,7 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, -- cgit v1.2.3 From 482049f75750d73358e65236b933417b69f9cc25 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 8 Nov 2012 10:25:26 +0100 Subject: Bluetooth: Fix memory leak when removing a UUID When removing a UUID from the list in the remove_uuid() function we must also kfree the entry in addition to removing it from the list. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- net/bluetooth/mgmt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 2cfabe27d3e..91de4239da6 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1367,6 +1367,7 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, continue; list_del(&match->list); + kfree(match); found++; } -- cgit v1.2.3 From 20f544eea03db4b498942558b882d463ce575c3e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 8 Nov 2012 14:06:28 +0100 Subject: mac80211: don't send null data packet when not associated On resume or firmware recovery, mac80211 sends a null data packet to see if the AP is still around and hasn't disconnected us. However, it always does this even if it wasn't even connected before, leading to a warning in the new channel context code. Fix this by checking that it's associated. Cc: stable@vger.kernel.org Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/util.c b/net/mac80211/util.c index e6e4bda0528..fa1d343faa4 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1491,6 +1491,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type != NL80211_IFTYPE_STATION) continue; + if (!sdata->u.mgd.associated) + continue; ieee80211_send_nullfunc(local, sdata, 0); } -- cgit v1.2.3 From 445632ad6dda42f4d3f9df2569a852ca0d4ea608 Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Thu, 8 Nov 2012 12:03:12 -0600 Subject: ASoC: dapm: Use card_list during DAPM shutdown DAPM shutdown incorrectly uses "list" field of codec struct while iterating over probed components (codec_dev_list). "list" field refers to codecs registered in the system, "card_list" field is used for probed components. Signed-off-by: Misael Lopez Cruz Signed-off-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/soc-dapm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d0a4be38dc0..6e35bcae02d 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -3745,7 +3745,7 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card) { struct snd_soc_codec *codec; - list_for_each_entry(codec, &card->codec_dev_list, list) { + list_for_each_entry(codec, &card->codec_dev_list, card_list) { soc_dapm_shutdown_codec(&codec->dapm); if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) snd_soc_dapm_set_bias_level(&codec->dapm, -- cgit v1.2.3 From d055852ee86703d48b0c571e94bd2eb33aa9b91d Mon Sep 17 00:00:00 2001 From: Mukund Navada Date: Fri, 9 Nov 2012 11:53:40 +0530 Subject: ASoC: core: Double control update err for snd_soc_put_volsw_sx snd_soc_put_volsw_sx function fails to update second control if first control is updated by snd_soc_update_bits_locked. Signed-off-by: Mukund Navada Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/soc-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d1198627fc4..10d21be383f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2786,8 +2786,9 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, val = (ucontrol->value.integer.value[0] + min) & mask; val = val << shift; - if (snd_soc_update_bits_locked(codec, reg, val_mask, val)) - return err; + err = snd_soc_update_bits_locked(codec, reg, val_mask, val); + if (err < 0) + return err; if (snd_soc_volsw_is_stereo(mc)) { val_mask = mask << rshift; -- cgit v1.2.3 From 2ba34aaa6db8b61cf1fa14132f885ba6bc7c9ae0 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Sat, 10 Nov 2012 02:27:13 +0900 Subject: perf annotate: Whitespace fixups Some lines are indented by whitespace characters rather than tabs. Fix them. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1352482044-3443-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index b14d4df9f14..435bf6d1a77 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -171,15 +171,15 @@ static int lock__parse(struct ins_operands *ops) if (disasm_line__parse(ops->raw, &name, &ops->locked.ops->raw) < 0) goto out_free_ops; - ops->locked.ins = ins__find(name); - if (ops->locked.ins == NULL) - goto out_free_ops; + ops->locked.ins = ins__find(name); + if (ops->locked.ins == NULL) + goto out_free_ops; - if (!ops->locked.ins->ops) - return 0; + if (!ops->locked.ins->ops) + return 0; - if (ops->locked.ins->ops->parse) - ops->locked.ins->ops->parse(ops->locked.ops); + if (ops->locked.ins->ops->parse) + ops->locked.ins->ops->parse(ops->locked.ops); return 0; -- cgit v1.2.3 From 32ae1efd9d40645601cd4e09fa83a2711dd1ad6d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Sat, 10 Nov 2012 02:27:15 +0900 Subject: perf annotate: Don't try to follow jump target on PLT symbols The perf annotate browser on TUI can identify a jump target for a selected instruction. It assumes that the jump target is within the function but it's not the case of PLT symbols which have offset out of the function as a target. Since it caused a segmentation fault, do not try to follow jump target on the PLT symbols. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1352482044-3443-5-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/annotate.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 3eff17f703f..5dab3ca9698 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -188,6 +188,12 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser) struct disasm_line *cursor = ab->selection, *target; struct browser_disasm_line *btarget, *bcursor; unsigned int from, to; + struct map_symbol *ms = ab->b.priv; + struct symbol *sym = ms->sym; + + /* PLT symbols contain external offsets */ + if (strstr(sym->name, "@plt")) + return; if (!cursor || !cursor->ins || !ins__is_jump(cursor->ins) || !disasm_line__has_offset(cursor)) @@ -771,6 +777,12 @@ static void annotate_browser__mark_jump_targets(struct annotate_browser *browser size_t size) { u64 offset; + struct map_symbol *ms = browser->b.priv; + struct symbol *sym = ms->sym; + + /* PLT symbols contain external offsets */ + if (strstr(sym->name, "@plt")) + return; for (offset = 0; offset < size; ++offset) { struct disasm_line *dl = browser->offsets[offset], *dlt; -- cgit v1.2.3 From 411279658adf6a4f5bb25ec032a39ae905bcf234 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 9 Nov 2012 14:58:49 +0900 Subject: perf annotate: Merge same lines in summary view The --print-line option of perf annotate command shows summary for each source line. But it didn't merge same lines so that it can appear multiple times. * before: Sorted summary for file /home/namhyung/bin/mcol ---------------------------------------------- 21.71 /home/namhyung/tmp/mcol.c:26 20.66 /home/namhyung/tmp/mcol.c:25 9.53 /home/namhyung/tmp/mcol.c:24 7.68 /home/namhyung/tmp/mcol.c:25 7.67 /home/namhyung/tmp/mcol.c:25 7.66 /home/namhyung/tmp/mcol.c:26 7.49 /home/namhyung/tmp/mcol.c:26 6.92 /home/namhyung/tmp/mcol.c:25 6.81 /home/namhyung/tmp/mcol.c:25 1.07 /home/namhyung/tmp/mcol.c:26 0.52 /home/namhyung/tmp/mcol.c:25 0.51 /home/namhyung/tmp/mcol.c:25 0.51 /home/namhyung/tmp/mcol.c:24 * after: Sorted summary for file /home/namhyung/bin/mcol ---------------------------------------------- 50.77 /home/namhyung/tmp/mcol.c:25 37.94 /home/namhyung/tmp/mcol.c:26 10.04 /home/namhyung/tmp/mcol.c:24 To do that, introduce percent_sum field so that the normal line-by-line output doesn't get changed. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352440729-21848-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 55 +++++++++++++++++++++++++++++++++++++++++++--- tools/perf/util/annotate.h | 1 + 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 435bf6d1a77..07aaeea6000 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -858,12 +858,41 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin struct source_line *iter; struct rb_node **p = &root->rb_node; struct rb_node *parent = NULL; + int ret; while (*p != NULL) { parent = *p; iter = rb_entry(parent, struct source_line, node); - if (src_line->percent > iter->percent) + ret = strcmp(iter->path, src_line->path); + if (ret == 0) { + iter->percent_sum += src_line->percent; + return; + } + + if (ret < 0) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + + src_line->percent_sum = src_line->percent; + + rb_link_node(&src_line->node, parent, p); + rb_insert_color(&src_line->node, root); +} + +static void __resort_source_line(struct rb_root *root, struct source_line *src_line) +{ + struct source_line *iter; + struct rb_node **p = &root->rb_node; + struct rb_node *parent = NULL; + + while (*p != NULL) { + parent = *p; + iter = rb_entry(parent, struct source_line, node); + + if (src_line->percent_sum > iter->percent_sum) p = &(*p)->rb_left; else p = &(*p)->rb_right; @@ -873,6 +902,24 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin rb_insert_color(&src_line->node, root); } +static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root) +{ + struct source_line *src_line; + struct rb_node *node; + + node = rb_first(src_root); + while (node) { + struct rb_node *next; + + src_line = rb_entry(node, struct source_line, node); + next = rb_next(node); + rb_erase(node, src_root); + + __resort_source_line(dest_root, src_line); + node = next; + } +} + static void symbol__free_source_line(struct symbol *sym, int len) { struct annotation *notes = symbol__annotation(sym); @@ -897,6 +944,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, struct source_line *src_line; struct annotation *notes = symbol__annotation(sym); struct sym_hist *h = annotation__histogram(notes, evidx); + struct rb_root tmp_root = RB_ROOT; if (!h->sum) return 0; @@ -931,12 +979,13 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, goto next; strcpy(src_line[i].path, path); - insert_source_line(root, &src_line[i]); + insert_source_line(&tmp_root, &src_line[i]); next: pclose(fp); } + resort_source_line(root, &tmp_root); return 0; } @@ -960,7 +1009,7 @@ static void print_summary(struct rb_root *root, const char *filename) char *path; src_line = rb_entry(node, struct source_line, node); - percent = src_line->percent; + percent = src_line->percent_sum; color = get_percent_color(percent); path = src_line->path; diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index c6272011625..8eec94358a4 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -76,6 +76,7 @@ struct sym_hist { struct source_line { struct rb_node node; double percent; + double percent_sum; char *path; }; -- cgit v1.2.3 From ca383a4df77a07e607123d7763facdc00ce32796 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 9 Nov 2012 15:18:57 -0300 Subject: tools lib traceevent: Add __maybe_unused to unused parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing the build on 32-bit Fedora 14: tools/lib/traceevent/event-parse.c: In function ‘print_event_fields’: tools/lib/traceevent/event-parse.c:3934:69: error: unused parameter ‘size’ tools/lib/traceevent/event-parse.c: In function ‘pevent_strerror’: tools/lib/traceevent/event-parse.c:5074:36: error: unused parameter ‘pevent’ Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt Link: http://lkml.kernel.org/n/tip-soe4gqcz8fd4ecik6exvyqox@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index f2989c525e4..0dcc18ce554 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -3931,7 +3931,8 @@ static int is_printable_array(char *p, unsigned int len) return 1; } -static void print_event_fields(struct trace_seq *s, void *data, int size, +static void print_event_fields(struct trace_seq *s, void *data, + int size __maybe_unused, struct event_format *event) { struct format_field *field; @@ -5070,8 +5071,8 @@ static const char * const pevent_error_str[] = { }; #undef _PE -int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum, - char *buf, size_t buflen) +int pevent_strerror(struct pevent *pevent __maybe_unused, + enum pevent_errno errnum, char *buf, size_t buflen) { int idx; const char *msg; -- cgit v1.2.3 From 8a38cce4c900307e947eda774f844caf5b9a7083 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 9 Nov 2012 15:32:00 -0300 Subject: tools lib traceevent: Avoid comparisions between signed/unsigned Fixing this warning-as-error on f14 32-bit: tools/lib/traceevent/event-parse.c:5564:17: error: comparison between signed and unsigned integer expressions tools/lib/traceevent/event-parse.c:5586:17: error: comparison between signed and unsigned integer expressions Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt Link: http://lkml.kernel.org/n/tip-stmix8hy4nu5ervpynn8yj2z@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 0dcc18ce554..6b647c17fff 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -5561,7 +5561,7 @@ void pevent_free(struct pevent *pevent) } if (pevent->func_map) { - for (i = 0; i < pevent->func_count; i++) { + for (i = 0; i < (int)pevent->func_count; i++) { free(pevent->func_map[i].func); free(pevent->func_map[i].mod); } @@ -5583,7 +5583,7 @@ void pevent_free(struct pevent *pevent) } if (pevent->printk_map) { - for (i = 0; i < pevent->printk_count; i++) + for (i = 0; i < (int)pevent->printk_count; i++) free(pevent->printk_map[i].printk); free(pevent->printk_map); } -- cgit v1.2.3 From e46466b8bd5918626250dc0d6cb6c2147a611087 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 9 Nov 2012 15:42:26 -0300 Subject: tools lib traceevent: No need to check for < 0 on an unsigned enum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc on f14 32-bit complains: tools/lib/traceevent/event-parse.c: In function ‘pevent_register_print_function’: tools/lib/traceevent/event-parse.c:5366:3: error: comparison of unsigned expression < 0 is always false This is because: enum pevent_func_arg_type type; this enum doesn't have any negative value, so gcc makes it an 'unsigned int'. Fix it by removing the < 0 test. Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt Link: http://lkml.kernel.org/n/tip-6vnd6ud6fbpn48zax4a5ru01@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 6b647c17fff..38d6595891a 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -5363,7 +5363,7 @@ int pevent_register_print_function(struct pevent *pevent, if (type == PEVENT_FUNC_ARG_VOID) break; - if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) { + if (type >= PEVENT_FUNC_ARG_MAX_TYPES) { do_warning("Invalid argument type %d", type); ret = PEVENT_ERRNO__INVALID_ARG_TYPE; goto out_free; -- cgit v1.2.3 From 7a905611644c015e68a955f263fd0a4b7b20879d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 9 Nov 2012 15:50:33 -0300 Subject: tools lib traceevent: Handle INVALID_ARG_TYPE errno in pevent_strerror MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc on f14 32-bit rightly complains: tools/lib/traceevent/event-parse.c:5097:2: error: enumeration value ‘PEVENT_ERRNO__INVALID_ARG_TYPE’ not handled in switch The entry for it is in the error strings array pevent_error_str[]: _PE(INVALID_ARG_TYPE, "invalid argument type") It was just not being handled on the pevent_strerror switch, fix it. Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt Link: http://lkml.kernel.org/n/tip-c68zkvxw4289uqbosfkz963g@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 38d6595891a..669953ab32e 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -5101,6 +5101,7 @@ int pevent_strerror(struct pevent *pevent __maybe_unused, case PEVENT_ERRNO__READ_FORMAT_FAILED: case PEVENT_ERRNO__READ_PRINT_FAILED: case PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED: + case PEVENT_ERRNO__INVALID_ARG_TYPE: snprintf(buf, buflen, "%s", msg); break; -- cgit v1.2.3 From 27f94d52394003d444a383eaf8d4824daf32432e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 9 Nov 2012 17:40:47 -0300 Subject: tools lib traceevent: Use 'const' in variables pointing to const strings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing the build on fedora 14, 32-bit: tools/lib/traceevent/event-parse.c: In function ‘find_cmdline’: tools/lib/traceevent/event-parse.c:183:3: error: return discards qualifiers from pointer target type tools/lib/traceevent/event-parse.c:186:3: error: return discards qualifiers from pointer target type tools/lib/traceevent/event-parse.c:195:2: error: return discards qualifiers from pointer target type tools/lib/traceevent/event-parse.c: In function ‘process_func_handler’: tools/lib/traceevent/event-parse.c:2658:9: error: assignment discards qualifiers from pointer target type tools/lib/traceevent/event-parse.c:2660:9: error: assignment discards qualifiers from pointer target type tools/lib/traceevent/event-parse.c: In function ‘print_mac_arg’: tools/lib/traceevent/event-parse.c:3892:14: error: initialization discards qualifiers from pointer target type tools/lib/traceevent/event-parse.c:3906:7: error: assignment discards qualifiers from pointer target type tools/lib/traceevent/event-parse.c: In function ‘pevent_print_event’: tools/lib/traceevent/event-parse.c:4412:24: error: initialization discards qualifiers from pointer target type Cc: David Ahern Cc: Frederic Weisbecker Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Steven Rostedt Link: http://lkml.kernel.org/n/tip-0k5g8urwu7vwkgbcbt2x05fe@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 669953ab32e..5a824e355d0 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -174,7 +174,7 @@ static int cmdline_init(struct pevent *pevent) return 0; } -static char *find_cmdline(struct pevent *pevent, int pid) +static const char *find_cmdline(struct pevent *pevent, int pid) { const struct cmdline *comm; struct cmdline key; @@ -2637,7 +2637,7 @@ process_func_handler(struct event_format *event, struct pevent_function_handler struct print_arg *farg; enum event_type type; char *token; - char *test; + const char *test; int i; arg->type = PRINT_FUNC; @@ -3889,7 +3889,7 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size, struct event_format *event, struct print_arg *arg) { unsigned char *buf; - char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"; + const char *fmt = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x"; if (arg->type == PRINT_FUNC) { process_defined_func(s, data, size, event, arg); @@ -4409,7 +4409,7 @@ void pevent_event_info(struct trace_seq *s, struct event_format *event, void pevent_print_event(struct pevent *pevent, struct trace_seq *s, struct pevent_record *record) { - static char *spaces = " "; /* 20 spaces */ + static const char *spaces = " "; /* 20 spaces */ struct event_format *event; unsigned long secs; unsigned long usecs; -- cgit v1.2.3 From 50545e1d237b0fa790bd824bf5a945ddb8c48351 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 10 Oct 2012 13:42:22 +0200 Subject: ARM: ux500: Remove cpufreq platform device The cpufreq device is already added from the prcmu driver as a mfd child device. Signed-off-by: Ulf Hansson Acked-by: Jonas Aaberg Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- arch/arm/mach-ux500/cpu-db8500.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index bcdfe6b1d45..41b27799dbd 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -214,9 +214,6 @@ struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500) db8500_add_gpios(parent); db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); - platform_device_register_data(parent, - "cpufreq-u8500", -1, NULL, 0); - for (i = 0; i < ARRAY_SIZE(platform_devs); i++) platform_devs[i]->dev.parent = parent; @@ -236,9 +233,6 @@ struct device * __init u8500_of_init_devices(void) db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); - platform_device_register_data(parent, - "cpufreq-u8500", -1, NULL, 0); - u8500_dma40_device.dev.parent = parent; /* -- cgit v1.2.3 From c280f45fb84bf49731c2b5122c997a9669e763ce Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 10 Oct 2012 13:42:23 +0200 Subject: mfd: db8500: Provide cpufreq table as platform data The cpufreq table needs dynamically update due to what the PRCMU firmware is supporting. The table is then provided through to the mfd child device as platform data. Signed-off-by: Ulf Hansson Acked-by: Jonas Aaberg Acked-by: Linus Walleij Acked-by: Samuel Ortiz Signed-off-by: Mike Turquette --- drivers/mfd/db8500-prcmu.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 3167bfdd13f..ea156501889 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -3002,6 +3003,15 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { }, }; +/* CPU FREQ table, may be changed due to if MAX_OPP is supported. */ +static struct cpufreq_frequency_table db8500_cpufreq_table[] = { + { .frequency = 200000, .index = ARM_EXTCLK,}, + { .frequency = 400000, .index = ARM_50_OPP,}, + { .frequency = 800000, .index = ARM_100_OPP,}, + { .frequency = CPUFREQ_TABLE_END,}, /* To be used for MAX_OPP. */ + { .frequency = CPUFREQ_TABLE_END,}, +}; + static struct resource ab8500_resources[] = { [0] = { .start = IRQ_DB8500_AB8500, @@ -3020,6 +3030,8 @@ static struct mfd_cell db8500_prcmu_devs[] = { { .name = "cpufreq-u8500", .of_compatible = "stericsson,cpufreq-u8500", + .platform_data = &db8500_cpufreq_table, + .pdata_size = sizeof(db8500_cpufreq_table), }, { .name = "ab8500-core", @@ -3030,6 +3042,14 @@ static struct mfd_cell db8500_prcmu_devs[] = { }, }; +static void db8500_prcmu_update_cpufreq(void) +{ + if (prcmu_has_arm_maxopp()) { + db8500_cpufreq_table[3].frequency = 1000000; + db8500_cpufreq_table[3].index = ARM_MAX_OPP; + } +} + /** * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic * @@ -3074,6 +3094,8 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev) if (cpu_is_u8500v20_or_later()) prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); + db8500_prcmu_update_cpufreq(); + err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL); if (err) { -- cgit v1.2.3 From b46894447170963d7a29050b79fe532deab0966f Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 10 Oct 2012 13:42:24 +0200 Subject: cpufreq: db8500: Register as a platform driver To fetch the mfd child device we register the cpufreq driver as a platform driver. Signed-off-by: Ulf Hansson Acked-by: Jonas Aaberg Acked-by: Rafael J. Wysocki Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/cpufreq/db8500-cpufreq.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/db8500-cpufreq.c b/drivers/cpufreq/db8500-cpufreq.c index 74b830b635a..7d61a6c3e70 100644 --- a/drivers/cpufreq/db8500-cpufreq.c +++ b/drivers/cpufreq/db8500-cpufreq.c @@ -8,10 +8,12 @@ * Author: Jonas Aaberg * */ +#include #include #include #include #include +#include #include #include @@ -159,12 +161,28 @@ static struct cpufreq_driver db8500_cpufreq_driver = { .attr = db8500_cpufreq_attr, }; +static int db8500_cpufreq_probe(struct platform_device *pdev) +{ + return cpufreq_register_driver(&db8500_cpufreq_driver); +} + +static struct platform_driver db8500_cpufreq_plat_driver = { + .driver = { + .name = "cpufreq-u8500", + .owner = THIS_MODULE, + }, + .probe = db8500_cpufreq_probe, +}; + static int __init db8500_cpufreq_register(void) { if (!cpu_is_u8500_family()) return -ENODEV; pr_info("cpufreq for DB8500 started\n"); - return cpufreq_register_driver(&db8500_cpufreq_driver); + return platform_driver_register(&db8500_cpufreq_plat_driver); } device_initcall(db8500_cpufreq_register); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("cpufreq driver for DB8500"); -- cgit v1.2.3 From fdb44464ce844dc72e194a6671996fa8cfdbc532 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 10 Oct 2012 13:42:25 +0200 Subject: cpufreq: db8500: Fetch cpufreq table from platform data By fetching the table as platform data we do not need the internally hardcoded cpufreq table anymore. Moreover the corresponding arm_opp idx2opp table, used for mapping frequency to correct opp bits is also removed. This due to that the opp bits is put directly in the index field of the cpufreq table. Signed-off-by: Ulf Hansson Acked-by: Jonas Aaberg Acked-by: Rafael J. Wysocki Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/cpufreq/db8500-cpufreq.c | 67 +++++++++++++++------------------------- 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/drivers/cpufreq/db8500-cpufreq.c b/drivers/cpufreq/db8500-cpufreq.c index 7d61a6c3e70..dea9a49023d 100644 --- a/drivers/cpufreq/db8500-cpufreq.c +++ b/drivers/cpufreq/db8500-cpufreq.c @@ -17,36 +17,7 @@ #include #include -static struct cpufreq_frequency_table freq_table[] = { - [0] = { - .index = 0, - .frequency = 200000, - }, - [1] = { - .index = 1, - .frequency = 400000, - }, - [2] = { - .index = 2, - .frequency = 800000, - }, - [3] = { - /* Used for MAX_OPP, if available */ - .index = 3, - .frequency = CPUFREQ_TABLE_END, - }, - [4] = { - .index = 4, - .frequency = CPUFREQ_TABLE_END, - }, -}; - -static enum arm_opp idx2opp[] = { - ARM_EXTCLK, - ARM_50_OPP, - ARM_100_OPP, - ARM_MAX_OPP -}; +static struct cpufreq_frequency_table *freq_table; static struct freq_attr *db8500_cpufreq_attr[] = { &cpufreq_freq_attr_scaling_available_freqs, @@ -88,7 +59,7 @@ static int db8500_cpufreq_target(struct cpufreq_policy *policy, cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); /* request the PRCM unit for opp change */ - if (prcmu_set_arm_opp(idx2opp[idx])) { + if (prcmu_set_arm_opp(freq_table[idx].index)) { pr_err("db8500-cpufreq: Failed to set OPP level\n"); return -EINVAL; } @@ -102,25 +73,30 @@ static int db8500_cpufreq_target(struct cpufreq_policy *policy, static unsigned int db8500_cpufreq_getspeed(unsigned int cpu) { - int i; + int i = 0; /* request the prcm to get the current ARM opp */ - for (i = 0; prcmu_get_arm_opp() != idx2opp[i]; i++) - ; - return freq_table[i].frequency; + int opp = prcmu_get_arm_opp(); + + while (freq_table[i].frequency != CPUFREQ_TABLE_END) { + if (opp == freq_table[i].index) + return freq_table[i].frequency; + i++; + } + + /* We could not find a corresponding opp frequency. */ + return 0; } static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy) { - int i, res; - - BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table)); - - if (prcmu_has_arm_maxopp()) - freq_table[3].frequency = 1000000; + int i = 0; + int res; pr_info("db8500-cpufreq : Available frequencies:\n"); - for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) + while (freq_table[i].frequency != CPUFREQ_TABLE_END) { pr_info(" %d Mhz\n", freq_table[i].frequency/1000); + i++; + } /* get policy fields based on the table */ res = cpufreq_frequency_table_cpuinfo(policy, freq_table); @@ -163,6 +139,13 @@ static struct cpufreq_driver db8500_cpufreq_driver = { static int db8500_cpufreq_probe(struct platform_device *pdev) { + freq_table = dev_get_platdata(&pdev->dev); + + if (!freq_table) { + pr_err("db8500-cpufreq: Failed to fetch cpufreq table\n"); + return -ENODEV; + } + return cpufreq_register_driver(&db8500_cpufreq_driver); } -- cgit v1.2.3 From b2302c873bb7959958ffad4625a0876fc9294640 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 10 Oct 2012 13:42:26 +0200 Subject: mfd: db8500: Connect ARMSS clk to ARM OPP ARMSS clk directly maps it's frequency towards the cpufreq table. To be able to update the ARMSS clk rate, a new set_rate function for the ARMSS clk is added, which also will trigger a corresponding ARM OPP request. Additionally an ARMSS clk round_rate function is added to fetch valid cpufreq frequencies. Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Samuel Ortiz Signed-off-by: Mike Turquette --- drivers/mfd/db8500-prcmu.c | 78 +++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index ea156501889..b96661d453a 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -421,9 +421,6 @@ static struct { static atomic_t ac_wake_req_state = ATOMIC_INIT(0); -/* Functions definition */ -static void compute_armss_rate(void); - /* Spinlocks */ static DEFINE_SPINLOCK(prcmu_lock); static DEFINE_SPINLOCK(clkout_lock); @@ -1020,7 +1017,6 @@ int db8500_prcmu_set_arm_opp(u8 opp) (mb1_transfer.ack.arm_opp != opp)) r = -EIO; - compute_armss_rate(); mutex_unlock(&mb1_transfer.lock); return r; @@ -1670,13 +1666,8 @@ static unsigned long clock_rate(u8 clock) else return 0; } -static unsigned long latest_armss_rate; -static unsigned long armss_rate(void) -{ - return latest_armss_rate; -} -static void compute_armss_rate(void) +static unsigned long armss_rate(void) { u32 r; unsigned long rate; @@ -1701,7 +1692,7 @@ static void compute_armss_rate(void) rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV); } - latest_armss_rate = rate; + return rate; } static unsigned long dsiclk_rate(u8 n) @@ -1821,6 +1812,35 @@ static long round_clock_rate(u8 clock, unsigned long rate) return rounded_rate; } +/* CPU FREQ table, may be changed due to if MAX_OPP is supported. */ +static struct cpufreq_frequency_table db8500_cpufreq_table[] = { + { .frequency = 200000, .index = ARM_EXTCLK,}, + { .frequency = 400000, .index = ARM_50_OPP,}, + { .frequency = 800000, .index = ARM_100_OPP,}, + { .frequency = CPUFREQ_TABLE_END,}, /* To be used for MAX_OPP. */ + { .frequency = CPUFREQ_TABLE_END,}, +}; + +static long round_armss_rate(unsigned long rate) +{ + long freq = 0; + int i = 0; + + /* cpufreq table frequencies is in KHz. */ + rate = rate / 1000; + + /* Find the corresponding arm opp from the cpufreq table. */ + while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) { + freq = db8500_cpufreq_table[i].frequency; + if (freq == rate) + break; + i++; + } + + /* Return the last valid value, even if a match was not found. */ + return freq * 1000; +} + #define MIN_PLL_VCO_RATE 600000000ULL #define MAX_PLL_VCO_RATE 1680640000ULL @@ -1892,6 +1912,8 @@ long prcmu_round_clock_rate(u8 clock, unsigned long rate) { if (clock < PRCMU_NUM_REG_CLOCKS) return round_clock_rate(clock, rate); + else if (clock == PRCMU_ARMSS) + return round_armss_rate(rate); else if (clock == PRCMU_PLLDSI) return round_plldsi_rate(rate); else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK)) @@ -1951,6 +1973,27 @@ static void set_clock_rate(u8 clock, unsigned long rate) spin_unlock_irqrestore(&clk_mgt_lock, flags); } +static int set_armss_rate(unsigned long rate) +{ + int i = 0; + + /* cpufreq table frequencies is in KHz. */ + rate = rate / 1000; + + /* Find the corresponding arm opp from the cpufreq table. */ + while (db8500_cpufreq_table[i].frequency != CPUFREQ_TABLE_END) { + if (db8500_cpufreq_table[i].frequency == rate) + break; + i++; + } + + if (db8500_cpufreq_table[i].frequency != rate) + return -EINVAL; + + /* Set the new arm opp. */ + return db8500_prcmu_set_arm_opp(db8500_cpufreq_table[i].index); +} + static int set_plldsi_rate(unsigned long rate) { unsigned long src_rate; @@ -2031,6 +2074,8 @@ int prcmu_set_clock_rate(u8 clock, unsigned long rate) { if (clock < PRCMU_NUM_REG_CLOCKS) set_clock_rate(clock, rate); + else if (clock == PRCMU_ARMSS) + return set_armss_rate(rate); else if (clock == PRCMU_PLLDSI) return set_plldsi_rate(rate); else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK)) @@ -2755,8 +2800,6 @@ void __init db8500_prcmu_early_init(void) init_completion(&mb5_transfer.work); INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work); - - compute_armss_rate(); } static void __init init_prcm_registers(void) @@ -3003,15 +3046,6 @@ static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { }, }; -/* CPU FREQ table, may be changed due to if MAX_OPP is supported. */ -static struct cpufreq_frequency_table db8500_cpufreq_table[] = { - { .frequency = 200000, .index = ARM_EXTCLK,}, - { .frequency = 400000, .index = ARM_50_OPP,}, - { .frequency = 800000, .index = ARM_100_OPP,}, - { .frequency = CPUFREQ_TABLE_END,}, /* To be used for MAX_OPP. */ - { .frequency = CPUFREQ_TABLE_END,}, -}; - static struct resource ab8500_resources[] = { [0] = { .start = IRQ_DB8500_AB8500, -- cgit v1.2.3 From a816d250e866b01bd18b0dd2bcbe5f1951310094 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 10 Oct 2012 13:42:27 +0200 Subject: clk: ux500: Support for prcmu_scalable_rate clock The prcmu_scalable_rate clock can change rate but is not gateable. Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/clk/ux500/clk-prcmu.c | 17 +++++++++++++++++ drivers/clk/ux500/clk.h | 6 ++++++ 2 files changed, 23 insertions(+) diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c index 04577ca6a30..74faa7e3cf5 100644 --- a/drivers/clk/ux500/clk-prcmu.c +++ b/drivers/clk/ux500/clk-prcmu.c @@ -187,6 +187,13 @@ static struct clk_ops clk_prcmu_gate_ops = { .recalc_rate = clk_prcmu_recalc_rate, }; +static struct clk_ops clk_prcmu_scalable_rate_ops = { + .is_enabled = clk_prcmu_is_enabled, + .recalc_rate = clk_prcmu_recalc_rate, + .round_rate = clk_prcmu_round_rate, + .set_rate = clk_prcmu_set_rate, +}; + static struct clk_ops clk_prcmu_rate_ops = { .is_enabled = clk_prcmu_is_enabled, .recalc_rate = clk_prcmu_recalc_rate, @@ -278,6 +285,16 @@ struct clk *clk_reg_prcmu_gate(const char *name, &clk_prcmu_gate_ops); } +struct clk *clk_reg_prcmu_scalable_rate(const char *name, + const char *parent_name, + u8 cg_sel, + unsigned long rate, + unsigned long flags) +{ + return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags, + &clk_prcmu_scalable_rate_ops); +} + struct clk *clk_reg_prcmu_rate(const char *name, const char *parent_name, u8 cg_sel, diff --git a/drivers/clk/ux500/clk.h b/drivers/clk/ux500/clk.h index f36eeedca49..c3e449169a8 100644 --- a/drivers/clk/ux500/clk.h +++ b/drivers/clk/ux500/clk.h @@ -35,6 +35,12 @@ struct clk *clk_reg_prcmu_gate(const char *name, u8 cg_sel, unsigned long flags); +struct clk *clk_reg_prcmu_scalable_rate(const char *name, + const char *parent_name, + u8 cg_sel, + unsigned long rate, + unsigned long flags); + struct clk *clk_reg_prcmu_rate(const char *name, const char *parent_name, u8 cg_sel, -- cgit v1.2.3 From d6e99fa4f45a5f3c3029979680cf69c5a0579e6b Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 10 Oct 2012 13:42:28 +0200 Subject: clk: ux500: Add armss clk and fixup smp_twd clk for u8500 The new armss clk is a prcmu_scalable_rate clk which represents the ARMSS clk. This then makes it possible to convert the smp_twd clk to a fixed factor clock type, using a fixed divider of 2 and with the armss clk as parent. Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 7bebf1f62c6..955110db244 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -206,16 +206,18 @@ void u8500_clk_init(void) clk_register_clkdev(clk, "dsilp2", "dsilink.2"); clk_register_clkdev(clk, "dsilp2", "mcde"); - clk = clk_reg_prcmu_rate("smp_twd", NULL, PRCMU_ARMSS, - CLK_IS_ROOT|CLK_GET_RATE_NOCACHE| - CLK_IGNORE_UNUSED); + clk = clk_reg_prcmu_scalable_rate("armss", NULL, + PRCMU_ARMSS, 0, CLK_IS_ROOT|CLK_IGNORE_UNUSED); + clk_register_clkdev(clk, "armss", NULL); + + clk = clk_register_fixed_factor(NULL, "smp_twd", "armss", + CLK_IGNORE_UNUSED, 1, 2); clk_register_clkdev(clk, NULL, "smp_twd"); /* * FIXME: Add special handled PRCMU clocks here: - * 1. clk_arm, use PRCMU_ARMCLK. - * 2. clkout0yuv, use PRCMU as parent + need regulator + pinctrl. - * 3. ab9540_clkout1yuv, see clkout0yuv + * 1. clkout0yuv, use PRCMU as parent + need regulator + pinctrl. + * 2. ab9540_clkout1yuv, see clkout0yuv */ /* PRCC P-clocks */ -- cgit v1.2.3 From 78e30d12168b540d426e4584b3d485e80fbc2a51 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 10 Oct 2012 13:42:29 +0200 Subject: cpufreq: db8500: Use armss clk to update frequency Using the armss clk to update the frequency makes the driver no more directly dependant on the prmcu API. Signed-off-by: Ulf Hansson Cc: Rafael J. Wysocki Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/cpufreq/db8500-cpufreq.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/cpufreq/db8500-cpufreq.c b/drivers/cpufreq/db8500-cpufreq.c index dea9a49023d..4f154bc0ebe 100644 --- a/drivers/cpufreq/db8500-cpufreq.c +++ b/drivers/cpufreq/db8500-cpufreq.c @@ -14,10 +14,11 @@ #include #include #include -#include +#include #include static struct cpufreq_frequency_table *freq_table; +static struct clk *armss_clk; static struct freq_attr *db8500_cpufreq_attr[] = { &cpufreq_freq_attr_scaling_available_freqs, @@ -58,9 +59,9 @@ static int db8500_cpufreq_target(struct cpufreq_policy *policy, for_each_cpu(freqs.cpu, policy->cpus) cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - /* request the PRCM unit for opp change */ - if (prcmu_set_arm_opp(freq_table[idx].index)) { - pr_err("db8500-cpufreq: Failed to set OPP level\n"); + /* update armss clk frequency */ + if (clk_set_rate(armss_clk, freq_table[idx].frequency * 1000)) { + pr_err("db8500-cpufreq: Failed to update armss clk\n"); return -EINVAL; } @@ -74,16 +75,16 @@ static int db8500_cpufreq_target(struct cpufreq_policy *policy, static unsigned int db8500_cpufreq_getspeed(unsigned int cpu) { int i = 0; - /* request the prcm to get the current ARM opp */ - int opp = prcmu_get_arm_opp(); + unsigned long freq = clk_get_rate(armss_clk) / 1000; while (freq_table[i].frequency != CPUFREQ_TABLE_END) { - if (opp == freq_table[i].index) + if (freq <= freq_table[i].frequency) return freq_table[i].frequency; i++; } - /* We could not find a corresponding opp frequency. */ + /* We could not find a corresponding frequency. */ + pr_err("db8500-cpufreq: Failed to find cpufreq speed\n"); return 0; } @@ -92,6 +93,12 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy) int i = 0; int res; + armss_clk = clk_get(NULL, "armss"); + if (IS_ERR(armss_clk)) { + pr_err("db8500-cpufreq : Failed to get armss clk\n"); + return PTR_ERR(armss_clk); + } + pr_info("db8500-cpufreq : Available frequencies:\n"); while (freq_table[i].frequency != CPUFREQ_TABLE_END) { pr_info(" %d Mhz\n", freq_table[i].frequency/1000); @@ -104,6 +111,7 @@ static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy) cpufreq_frequency_table_get_attr(freq_table, policy->cpu); else { pr_err("db8500-cpufreq : Failed to read policy table\n"); + clk_put(armss_clk); return res; } -- cgit v1.2.3 From 0de9f23a2859a4aec5db210887c7457e0c24b9ca Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 9 Oct 2012 10:46:00 +0800 Subject: clk: fix return value check in bcm2835_init_clocks() In case of error, the function clk_register_fixed_rate() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR(). dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Acked-by: Stephen Warren Signed-off-by: Mike Turquette --- drivers/clk/clk-bcm2835.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/clk-bcm2835.c index 67ad16b20b8..b61ee2c5af8 100644 --- a/drivers/clk/clk-bcm2835.c +++ b/drivers/clk/clk-bcm2835.c @@ -33,17 +33,17 @@ void __init bcm2835_init_clocks(void) clk = clk_register_fixed_rate(NULL, "sys_pclk", NULL, CLK_IS_ROOT, 250000000); - if (!clk) + if (IS_ERR(clk)) pr_err("sys_pclk not registered\n"); clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 126000000); - if (!clk) + if (IS_ERR(clk)) pr_err("apb_pclk not registered\n"); clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT, 3000000); - if (!clk) + if (IS_ERR(clk)) pr_err("uart0_pclk not registered\n"); ret = clk_register_clkdev(clk, NULL, "20201000.uart"); if (ret) @@ -51,7 +51,7 @@ void __init bcm2835_init_clocks(void) clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT, 125000000); - if (!clk) + if (IS_ERR(clk)) pr_err("uart1_pclk not registered\n"); ret = clk_register_clkdev(clk, NULL, "20215000.uart"); if (ret) -- cgit v1.2.3 From 973e1d1de0f8af2be7f8c94418f2cda559bd7543 Mon Sep 17 00:00:00 2001 From: Tony Prisk Date: Thu, 18 Oct 2012 22:26:53 +1300 Subject: CLK: vt8500: Fix SDMMC clk special cases This patch adds some additional handling for the SDMMC special case in round_rate and set_rate which results in invalid divisor messages at boot time. Signed-off-by: Tony Prisk Signed-off-by: Mike Turquette --- drivers/clk/clk-vt8500.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index a885600f527..fe25570874d 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -120,8 +120,17 @@ static unsigned long vt8500_dclk_recalc_rate(struct clk_hw *hw, static long vt8500_dclk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { + struct clk_device *cdev = to_clk_device(hw); u32 divisor = *prate / rate; + /* + * If this is a request for SDMMC we have to adjust the divisor + * when >31 to use the fixed predivisor + */ + if ((cdev->div_mask == 0x3F) && (divisor > 31)) { + divisor = 64 * ((divisor / 64) + 1); + } + return *prate / divisor; } @@ -135,6 +144,15 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate, if (divisor == cdev->div_mask + 1) divisor = 0; + /* SDMMC mask may need to be corrected before testing if its valid */ + if ((cdev->div_mask == 0x3F) && (divisor > 31)) { + /* + * Bit 5 is a fixed /64 predivisor. If the requested divisor + * is >31 then correct for the fixed divisor being required. + */ + divisor = 0x20 + (divisor / 64); + } + if (divisor > cdev->div_mask) { pr_err("%s: invalid divisor for clock\n", __func__); return -EINVAL; -- cgit v1.2.3 From 1c73491a571c234d9b0b5e83f19e40cbb2c1b633 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:57:57 +0200 Subject: clk: ux500: Register i2c clock lookups for u8500 Cc: Ben Dooks Cc: Wolfram Sang Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Ulf Hansson Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 955110db244..c33b09c583f 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -231,6 +231,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, BIT(2), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1"); + clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, BIT(3), 0); clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, @@ -242,6 +244,7 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, BIT(6), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2"); clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, BIT(7), 0); @@ -258,11 +261,14 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, BIT(10), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4"); + clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, BIT(11), 0); clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, BIT(0), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3"); clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, BIT(1), 0); @@ -287,7 +293,6 @@ void u8500_clk_init(void) BIT(6), 0); clk_register_clkdev(clk, "apb_pclk", "sdi1"); - clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, BIT(7), 0); clk_register_clkdev(clk, "apb_pclk", "sdi3"); @@ -321,8 +326,10 @@ void u8500_clk_init(void) BIT(1), 0); clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, BIT(2), 0); + clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, BIT(3), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0"); clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, BIT(4), 0); @@ -404,6 +411,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.1"); + clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", @@ -415,17 +424,23 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.2"); + clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); /* FIXME: Redefinition of BIT(3). */ + clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.4"); + clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); /* Periph2 */ clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.3"); clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); @@ -455,8 +470,10 @@ void u8500_clk_init(void) U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); + clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.0"); clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); -- cgit v1.2.3 From eb1d7eae04ed961f81b1ce67da7e384ff74f94c6 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:57:58 +0200 Subject: clk: ux500: Register ssp clock lookups for u8500 Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index c33b09c583f..9be9b67a1f7 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -324,8 +324,11 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, BIT(1), 0); + clk_register_clkdev(clk, "apb_pclk", "ssp0"); + clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, BIT(2), 0); + clk_register_clkdev(clk, "apb_pclk", "ssp1"); clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, BIT(3), 0); @@ -468,8 +471,11 @@ void u8500_clk_init(void) /* Periph3 */ clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "ssp0"); + clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "ssp1"); clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); -- cgit v1.2.3 From b89f8b5ec85e99386f6a705a90f895fcb9287c08 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:57:59 +0200 Subject: clk: ux500: Register msp clock lookups for u8500 Cc: Mark Brown Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 9be9b67a1f7..e48d803773d 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -235,8 +235,13 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, BIT(3), 0); + clk_register_clkdev(clk, "apb_pclk", "msp0"); + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.0"); + clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, BIT(4), 0); + clk_register_clkdev(clk, "apb_pclk", "msp1"); + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.1"); clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE, BIT(5), 0); @@ -265,6 +270,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, BIT(11), 0); + clk_register_clkdev(clk, "apb_pclk", "msp3"); + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.3"); clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, BIT(0), 0); @@ -288,6 +295,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE, BIT(5), 0); + clk_register_clkdev(clk, "apb_pclk", "msp2"); + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.2"); clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE, BIT(6), 0); @@ -418,8 +427,13 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "msp0"); + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.0"); + clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "msp1"); + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.1"); clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk", U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE); @@ -439,6 +453,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "msp3"); + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.3"); /* Periph2 */ clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", @@ -451,6 +467,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "msp2"); + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.2"); clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk", U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE); -- cgit v1.2.3 From 86497f54556d70df60ef3030bddcb544f1fb8746 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:58:00 +0200 Subject: clk: ux500: Update rtc clock lookup for u8500 Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index e48d803773d..668839ff67f 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -40,7 +40,7 @@ void u8500_clk_init(void) CLK_IS_ROOT|CLK_IGNORE_UNUSED, 32768); clk_register_clkdev(clk, "clk32k", NULL); - clk_register_clkdev(clk, NULL, "rtc-pl031"); + clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); /* PRCMU clocks */ fw_version = prcmu_get_fw_version(); -- cgit v1.2.3 From 4a0ae7befc92765c05b4bdd79e931a2058ea9fb7 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:58:01 +0200 Subject: clk: ux500: Register slimbus clock lookups for u8500 At the same time the prcc bit for the kclk is corrected to bit 8 instead of 3. Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 668839ff67f..4ec6f60e372 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -257,6 +257,7 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE, BIT(8), 0); + clk_register_clkdev(clk, "apb_pclk", "slimbus0"); clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE, BIT(9), 0); @@ -444,8 +445,8 @@ void u8500_clk_init(void) clk_register_clkdev(clk, NULL, "nmk-i2c.2"); clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", - U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); - /* FIXME: Redefinition of BIT(3). */ + U8500_CLKRST1_BASE, BIT(8), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "slimbus0"); clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); -- cgit v1.2.3 From 40a812044a11a8fd32202cd22bb76329dd188094 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 8 Nov 2012 09:03:47 -0800 Subject: Input: MT - document new 'flags' argument of input_mt_init_slots() Fixes new kernel-doc warning in input-mt.c: Warning(drivers/input/input-mt.c:38): No description found for parameter 'flags' Reported-by: Randy Dunlap Signed-off-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- drivers/input/input-mt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index c0ec7d42c3b..1abbc170d8b 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -26,10 +26,14 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src) * input_mt_init_slots() - initialize MT input slots * @dev: input device supporting MT events and finger tracking * @num_slots: number of slots used by the device + * @flags: mt tasks to handle in core * * This function allocates all necessary memory for MT slot handling * in the input device, prepares the ABS_MT_SLOT and * ABS_MT_TRACKING_ID events for use and sets up appropriate buffers. + * Depending on the flags set, it also performs pointer emulation and + * frame synchronization. + * * May be called repeatedly. Returns -EINVAL if attempting to * reinitialize with a different number of slots. */ -- cgit v1.2.3 From 84b36ce5f79c01f792c623f14e92ed86cdccb42f Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 30 Jun 2012 20:06:00 +0100 Subject: staging:iio: Add support for multiple buffers Route all buffer writes through the demux. Addition or removal of a buffer results in tear down and setup of all the buffers for a given device. Signed-off-by: Jonathan Cameron Tested-by: srinivas pandruvada --- drivers/iio/accel/hid-sensor-accel-3d.c | 15 +- drivers/iio/adc/ad7266.c | 3 +- drivers/iio/adc/ad7476.c | 2 +- drivers/iio/adc/ad7887.c | 2 +- drivers/iio/adc/ad_sigma_delta.c | 2 +- drivers/iio/adc/at91_adc.c | 3 +- drivers/iio/gyro/hid-sensor-gyro-3d.c | 15 +- drivers/iio/industrialio-buffer.c | 380 ++++++++++++++++-------- drivers/iio/industrialio-core.c | 1 + drivers/iio/light/adjd_s311.c | 3 +- drivers/iio/light/hid-sensor-als.c | 15 +- drivers/iio/magnetometer/hid-sensor-magn-3d.c | 15 +- drivers/staging/iio/accel/adis16201_ring.c | 2 +- drivers/staging/iio/accel/adis16203_ring.c | 2 +- drivers/staging/iio/accel/adis16204_ring.c | 2 +- drivers/staging/iio/accel/adis16209_ring.c | 2 +- drivers/staging/iio/accel/adis16240_ring.c | 2 +- drivers/staging/iio/accel/lis3l02dq_ring.c | 2 +- drivers/staging/iio/adc/ad7298_ring.c | 2 +- drivers/staging/iio/adc/ad7606_ring.c | 2 +- drivers/staging/iio/adc/ad799x_ring.c | 2 +- drivers/staging/iio/adc/max1363_ring.c | 2 +- drivers/staging/iio/adc/mxs-lradc.c | 3 +- drivers/staging/iio/gyro/adis16260_ring.c | 2 +- drivers/staging/iio/iio_simple_dummy_buffer.c | 5 +- drivers/staging/iio/impedance-analyzer/ad5933.c | 4 +- drivers/staging/iio/imu/adis16400_ring.c | 5 +- drivers/staging/iio/meter/ade7758_ring.c | 2 +- include/linux/iio/buffer.h | 24 +- include/linux/iio/iio.h | 2 + 30 files changed, 313 insertions(+), 210 deletions(-) diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index 314a4057879..a95cda0e387 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -197,21 +197,8 @@ static const struct iio_info accel_3d_info = { /* Function to push data to buffer */ static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) { - struct iio_buffer *buffer = indio_dev->buffer; - int datum_sz; - dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); - if (!buffer) { - dev_err(&indio_dev->dev, "Buffer == NULL\n"); - return; - } - datum_sz = buffer->access->get_bytes_per_datum(buffer); - if (len > datum_sz) { - dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len, - datum_sz); - return; - } - iio_push_to_buffer(buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); } /* Callback handler to send event after all samples are received and captured */ diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c index b11f214779a..a6f4fc5f820 100644 --- a/drivers/iio/adc/ad7266.c +++ b/drivers/iio/adc/ad7266.c @@ -91,7 +91,6 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; - struct iio_buffer *buffer = indio_dev->buffer; struct ad7266_state *st = iio_priv(indio_dev); int ret; @@ -99,7 +98,7 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p) if (ret == 0) { if (indio_dev->scan_timestamp) ((s64 *)st->data)[1] = pf->timestamp; - iio_push_to_buffer(buffer, (u8 *)st->data); + iio_push_to_buffers(indio_dev, (u8 *)st->data); } iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index 7f2f45a0a48..330248bfeba 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -76,7 +76,7 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) ((s64 *)st->data)[1] = time_ns; - iio_push_to_buffer(indio_dev->buffer, st->data); + iio_push_to_buffers(indio_dev, st->data); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/adc/ad7887.c b/drivers/iio/adc/ad7887.c index fd62309b4d3..81153fafac7 100644 --- a/drivers/iio/adc/ad7887.c +++ b/drivers/iio/adc/ad7887.c @@ -134,7 +134,7 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p) memcpy(st->data + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); - iio_push_to_buffer(indio_dev->buffer, st->data); + iio_push_to_buffers(indio_dev, st->data); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index 67baa1363d7..afe6d78c8ff 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -391,7 +391,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p) break; } - iio_push_to_buffer(indio_dev->buffer, (uint8_t *)data); + iio_push_to_buffers(indio_dev, (uint8_t *)data); iio_trigger_notify_done(indio_dev->trig); sigma_delta->irq_dis = false; diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 2e2c9a80aa3..03b85940f4b 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -65,7 +65,6 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *idev = pf->indio_dev; struct at91_adc_state *st = iio_priv(idev); - struct iio_buffer *buffer = idev->buffer; int i, j = 0; for (i = 0; i < idev->masklength; i++) { @@ -81,7 +80,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p) *timestamp = pf->timestamp; } - iio_push_to_buffer(buffer, st->buffer); + iio_push_to_buffers(indio_dev, (u8 *)st->buffer); iio_trigger_notify_done(idev->trig); diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index 4c56ada51c3..02ef989b830 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -197,21 +197,8 @@ static const struct iio_info gyro_3d_info = { /* Function to push data to buffer */ static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) { - struct iio_buffer *buffer = indio_dev->buffer; - int datum_sz; - dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); - if (!buffer) { - dev_err(&indio_dev->dev, "Buffer == NULL\n"); - return; - } - datum_sz = buffer->access->get_bytes_per_datum(buffer); - if (len > datum_sz) { - dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len, - datum_sz); - return; - } - iio_push_to_buffer(buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); } /* Callback handler to send event after all samples are received and captured */ diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 722a83fd8d8..aaadd32f9f0 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -31,6 +31,18 @@ static const char * const iio_endian_prefix[] = { [IIO_LE] = "le", }; +static bool iio_buffer_is_active(struct iio_dev *indio_dev, + struct iio_buffer *buf) +{ + struct list_head *p; + + list_for_each(p, &indio_dev->buffer_list) + if (p == &buf->buffer_list) + return true; + + return false; +} + /** * iio_buffer_read_first_n_outer() - chrdev read for buffer access * @@ -134,7 +146,7 @@ static ssize_t iio_scan_el_store(struct device *dev, if (ret < 0) return ret; mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { + if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) { ret = -EBUSY; goto error_ret; } @@ -180,12 +192,11 @@ static ssize_t iio_scan_el_ts_store(struct device *dev, return ret; mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { + if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) { ret = -EBUSY; goto error_ret; } indio_dev->buffer->scan_timestamp = state; - indio_dev->scan_timestamp = state; error_ret: mutex_unlock(&indio_dev->mlock); @@ -385,7 +396,7 @@ ssize_t iio_buffer_write_length(struct device *dev, return len; mutex_lock(&indio_dev->mlock); - if (iio_buffer_enabled(indio_dev)) { + if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) { ret = -EBUSY; } else { if (buffer->access->set_length) @@ -398,102 +409,14 @@ ssize_t iio_buffer_write_length(struct device *dev, } EXPORT_SYMBOL(iio_buffer_write_length); -ssize_t iio_buffer_store_enable(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret; - bool requested_state, current_state; - int previous_mode; - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct iio_buffer *buffer = indio_dev->buffer; - - mutex_lock(&indio_dev->mlock); - previous_mode = indio_dev->currentmode; - requested_state = !(buf[0] == '0'); - current_state = iio_buffer_enabled(indio_dev); - if (current_state == requested_state) { - printk(KERN_INFO "iio-buffer, current state requested again\n"); - goto done; - } - if (requested_state) { - if (indio_dev->setup_ops->preenable) { - ret = indio_dev->setup_ops->preenable(indio_dev); - if (ret) { - printk(KERN_ERR - "Buffer not started: " - "buffer preenable failed\n"); - goto error_ret; - } - } - if (buffer->access->request_update) { - ret = buffer->access->request_update(buffer); - if (ret) { - printk(KERN_INFO - "Buffer not started: " - "buffer parameter update failed\n"); - goto error_ret; - } - } - /* Definitely possible for devices to support both of these. */ - if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) { - if (!indio_dev->trig) { - printk(KERN_INFO - "Buffer not started: no trigger\n"); - ret = -EINVAL; - goto error_ret; - } - indio_dev->currentmode = INDIO_BUFFER_TRIGGERED; - } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) - indio_dev->currentmode = INDIO_BUFFER_HARDWARE; - else { /* should never be reached */ - ret = -EINVAL; - goto error_ret; - } - - if (indio_dev->setup_ops->postenable) { - ret = indio_dev->setup_ops->postenable(indio_dev); - if (ret) { - printk(KERN_INFO - "Buffer not started: " - "postenable failed\n"); - indio_dev->currentmode = previous_mode; - if (indio_dev->setup_ops->postdisable) - indio_dev->setup_ops-> - postdisable(indio_dev); - goto error_ret; - } - } - } else { - if (indio_dev->setup_ops->predisable) { - ret = indio_dev->setup_ops->predisable(indio_dev); - if (ret) - goto error_ret; - } - indio_dev->currentmode = INDIO_DIRECT_MODE; - if (indio_dev->setup_ops->postdisable) { - ret = indio_dev->setup_ops->postdisable(indio_dev); - if (ret) - goto error_ret; - } - } -done: - mutex_unlock(&indio_dev->mlock); - return len; - -error_ret: - mutex_unlock(&indio_dev->mlock); - return ret; -} -EXPORT_SYMBOL(iio_buffer_store_enable); - ssize_t iio_buffer_show_enable(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); - return sprintf(buf, "%d\n", iio_buffer_enabled(indio_dev)); + return sprintf(buf, "%d\n", + iio_buffer_is_active(indio_dev, + indio_dev->buffer)); } EXPORT_SYMBOL(iio_buffer_show_enable); @@ -537,35 +460,220 @@ static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask, return bytes; } -int iio_sw_buffer_preenable(struct iio_dev *indio_dev) +int iio_update_buffers(struct iio_dev *indio_dev, + struct iio_buffer *insert_buffer, + struct iio_buffer *remove_buffer) { - struct iio_buffer *buffer = indio_dev->buffer; - dev_dbg(&indio_dev->dev, "%s\n", __func__); + int ret; + int success = 0; + struct iio_buffer *buffer; + unsigned long *compound_mask; + const unsigned long *old_mask; - /* How much space will the demuxed element take? */ - indio_dev->scan_bytes = - iio_compute_scan_bytes(indio_dev, buffer->scan_mask, - buffer->scan_timestamp); - buffer->access->set_bytes_per_datum(buffer, indio_dev->scan_bytes); + /* Wind down existing buffers - iff there are any */ + if (!list_empty(&indio_dev->buffer_list)) { + if (indio_dev->setup_ops->predisable) { + ret = indio_dev->setup_ops->predisable(indio_dev); + if (ret) + goto error_ret; + } + indio_dev->currentmode = INDIO_DIRECT_MODE; + if (indio_dev->setup_ops->postdisable) { + ret = indio_dev->setup_ops->postdisable(indio_dev); + if (ret) + goto error_ret; + } + } + /* Keep a copy of current setup to allow roll back */ + old_mask = indio_dev->active_scan_mask; + if (!indio_dev->available_scan_masks) + indio_dev->active_scan_mask = NULL; + + if (remove_buffer) + list_del(&remove_buffer->buffer_list); + if (insert_buffer) + list_add(&insert_buffer->buffer_list, &indio_dev->buffer_list); + + /* If no buffers in list, we are done */ + if (list_empty(&indio_dev->buffer_list)) { + indio_dev->currentmode = INDIO_DIRECT_MODE; + if (indio_dev->available_scan_masks == NULL) + kfree(old_mask); + return 0; + } /* What scan mask do we actually have ?*/ - if (indio_dev->available_scan_masks) + compound_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength), + sizeof(long), GFP_KERNEL); + if (compound_mask == NULL) { + if (indio_dev->available_scan_masks == NULL) + kfree(old_mask); + return -ENOMEM; + } + indio_dev->scan_timestamp = 0; + + list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) { + bitmap_or(compound_mask, compound_mask, buffer->scan_mask, + indio_dev->masklength); + indio_dev->scan_timestamp |= buffer->scan_timestamp; + } + if (indio_dev->available_scan_masks) { indio_dev->active_scan_mask = iio_scan_mask_match(indio_dev->available_scan_masks, indio_dev->masklength, - buffer->scan_mask); - else - indio_dev->active_scan_mask = buffer->scan_mask; - - if (indio_dev->active_scan_mask == NULL) - return -EINVAL; + compound_mask); + if (indio_dev->active_scan_mask == NULL) { + /* + * Roll back. + * Note can only occur when adding a buffer. + */ + list_del(&insert_buffer->buffer_list); + indio_dev->active_scan_mask = old_mask; + success = -EINVAL; + } + } else { + indio_dev->active_scan_mask = compound_mask; + } iio_update_demux(indio_dev); - if (indio_dev->info->update_scan_mode) - return indio_dev->info + /* Wind up again */ + if (indio_dev->setup_ops->preenable) { + ret = indio_dev->setup_ops->preenable(indio_dev); + if (ret) { + printk(KERN_ERR + "Buffer not started:" + "buffer preenable failed\n"); + goto error_remove_inserted; + } + } + indio_dev->scan_bytes = + iio_compute_scan_bytes(indio_dev, + indio_dev->active_scan_mask, + indio_dev->scan_timestamp); + list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) + if (buffer->access->request_update) { + ret = buffer->access->request_update(buffer); + if (ret) { + printk(KERN_INFO + "Buffer not started:" + "buffer parameter update failed\n"); + goto error_run_postdisable; + } + } + if (indio_dev->info->update_scan_mode) { + ret = indio_dev->info ->update_scan_mode(indio_dev, indio_dev->active_scan_mask); + if (ret < 0) { + printk(KERN_INFO "update scan mode failed\n"); + goto error_run_postdisable; + } + } + /* Definitely possible for devices to support both of these.*/ + if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) { + if (!indio_dev->trig) { + printk(KERN_INFO "Buffer not started: no trigger\n"); + ret = -EINVAL; + /* Can only occur on first buffer */ + goto error_run_postdisable; + } + indio_dev->currentmode = INDIO_BUFFER_TRIGGERED; + } else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) { + indio_dev->currentmode = INDIO_BUFFER_HARDWARE; + } else { /* should never be reached */ + ret = -EINVAL; + goto error_run_postdisable; + } + + if (indio_dev->setup_ops->postenable) { + ret = indio_dev->setup_ops->postenable(indio_dev); + if (ret) { + printk(KERN_INFO + "Buffer not started: postenable failed\n"); + indio_dev->currentmode = INDIO_DIRECT_MODE; + if (indio_dev->setup_ops->postdisable) + indio_dev->setup_ops->postdisable(indio_dev); + goto error_disable_all_buffers; + } + } + + if (indio_dev->available_scan_masks) + kfree(compound_mask); + else + kfree(old_mask); + + return success; + +error_disable_all_buffers: + indio_dev->currentmode = INDIO_DIRECT_MODE; +error_run_postdisable: + if (indio_dev->setup_ops->postdisable) + indio_dev->setup_ops->postdisable(indio_dev); +error_remove_inserted: + + if (insert_buffer) + list_del(&insert_buffer->buffer_list); + indio_dev->active_scan_mask = old_mask; + kfree(compound_mask); +error_ret: + + return ret; +} +EXPORT_SYMBOL_GPL(iio_update_buffers); + +ssize_t iio_buffer_store_enable(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + int ret; + bool requested_state; + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct iio_buffer *pbuf = indio_dev->buffer; + bool inlist; + + ret = strtobool(buf, &requested_state); + if (ret < 0) + return ret; + + mutex_lock(&indio_dev->mlock); + + /* Find out if it is in the list */ + inlist = iio_buffer_is_active(indio_dev, pbuf); + /* Already in desired state */ + if (inlist == requested_state) + goto done; + + if (requested_state) + ret = iio_update_buffers(indio_dev, + indio_dev->buffer, NULL); + else + ret = iio_update_buffers(indio_dev, + NULL, indio_dev->buffer); + + if (ret < 0) + goto done; +done: + mutex_unlock(&indio_dev->mlock); + return (ret < 0) ? ret : len; +} +EXPORT_SYMBOL(iio_buffer_store_enable); + +int iio_sw_buffer_preenable(struct iio_dev *indio_dev) +{ + struct iio_buffer *buffer; + unsigned bytes; + dev_dbg(&indio_dev->dev, "%s\n", __func__); + + list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) + if (buffer->access->set_bytes_per_datum) { + bytes = iio_compute_scan_bytes(indio_dev, + buffer->scan_mask, + buffer->scan_timestamp); + + buffer->access->set_bytes_per_datum(buffer, bytes); + } return 0; } EXPORT_SYMBOL(iio_sw_buffer_preenable); @@ -599,7 +707,11 @@ static bool iio_validate_scan_mask(struct iio_dev *indio_dev, * iio_scan_mask_set() - set particular bit in the scan mask * @buffer: the buffer whose scan mask we are interested in * @bit: the bit to be set. - **/ + * + * Note that at this point we have no way of knowing what other + * buffers might request, hence this code only verifies that the + * individual buffers request is plausible. + */ int iio_scan_mask_set(struct iio_dev *indio_dev, struct iio_buffer *buffer, int bit) { @@ -682,13 +794,12 @@ static unsigned char *iio_demux(struct iio_buffer *buffer, return buffer->demux_bounce; } -int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data) +static int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data) { unsigned char *dataout = iio_demux(buffer, data); return buffer->access->store_to(buffer, dataout); } -EXPORT_SYMBOL_GPL(iio_push_to_buffer); static void iio_buffer_demux_free(struct iio_buffer *buffer) { @@ -699,10 +810,26 @@ static void iio_buffer_demux_free(struct iio_buffer *buffer) } } -int iio_update_demux(struct iio_dev *indio_dev) + +int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data) +{ + int ret; + struct iio_buffer *buf; + + list_for_each_entry(buf, &indio_dev->buffer_list, buffer_list) { + ret = iio_push_to_buffer(buf, data); + if (ret < 0) + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(iio_push_to_buffers); + +static int iio_buffer_update_demux(struct iio_dev *indio_dev, + struct iio_buffer *buffer) { const struct iio_chan_spec *ch; - struct iio_buffer *buffer = indio_dev->buffer; int ret, in_ind = -1, out_ind, length; unsigned in_loc = 0, out_loc = 0; struct iio_demux_table *p; @@ -787,4 +914,23 @@ error_clear_mux_table: return ret; } + +int iio_update_demux(struct iio_dev *indio_dev) +{ + struct iio_buffer *buffer; + int ret; + + list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) { + ret = iio_buffer_update_demux(indio_dev, buffer); + if (ret < 0) + goto error_clear_mux_table; + } + return 0; + +error_clear_mux_table: + list_for_each_entry(buffer, &indio_dev->buffer_list, buffer_list) + iio_buffer_demux_free(buffer); + + return ret; +} EXPORT_SYMBOL_GPL(iio_update_demux); diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index cd700368eed..060a4045be8 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -856,6 +856,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) return NULL; } dev_set_name(&dev->dev, "iio:device%d", dev->id); + INIT_LIST_HEAD(&dev->buffer_list); } return dev; diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 164b62b91a4..36d210a06b2 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c @@ -164,7 +164,6 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adjd_s311_data *data = iio_priv(indio_dev); - struct iio_buffer *buffer = indio_dev->buffer; s64 time_ns = iio_get_time_ns(); int len = 0; int i, j = 0; @@ -187,7 +186,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64))) = time_ns; - iio_push_to_buffer(buffer, (u8 *)data->buffer); + iio_push_to_buffers(indio_dev, (u8 *)data->buffer); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index 96e3691e42c..8e1f69844ee 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c @@ -176,21 +176,8 @@ static const struct iio_info als_info = { /* Function to push data to buffer */ static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) { - struct iio_buffer *buffer = indio_dev->buffer; - int datum_sz; - dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); - if (!buffer) { - dev_err(&indio_dev->dev, "Buffer == NULL\n"); - return; - } - datum_sz = buffer->access->get_bytes_per_datum(buffer); - if (len > datum_sz) { - dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len, - datum_sz); - return; - } - iio_push_to_buffer(buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); } /* Callback handler to send event after all samples are received and captured */ diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c index c4f0d274f57..d1b5fb74b9b 100644 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c @@ -198,21 +198,8 @@ static const struct iio_info magn_3d_info = { /* Function to push data to buffer */ static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len) { - struct iio_buffer *buffer = indio_dev->buffer; - int datum_sz; - dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); - if (!buffer) { - dev_err(&indio_dev->dev, "Buffer == NULL\n"); - return; - } - datum_sz = buffer->access->get_bytes_per_datum(buffer); - if (len > datum_sz) { - dev_err(&indio_dev->dev, "Datum size mismatch %d:%d\n", len, - datum_sz); - return; - } - iio_push_to_buffer(buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); } /* Callback handler to send event after all samples are received and captured */ diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c index 97c09f0c26a..e14ca60092a 100644 --- a/drivers/staging/iio/accel/adis16201_ring.c +++ b/drivers/staging/iio/accel/adis16201_ring.c @@ -82,7 +82,7 @@ static irqreturn_t adis16201_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c index 7507e1a0459..eba2e285c84 100644 --- a/drivers/staging/iio/accel/adis16203_ring.c +++ b/drivers/staging/iio/accel/adis16203_ring.c @@ -81,7 +81,7 @@ static irqreturn_t adis16203_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c index 4c976bec986..3611a13836c 100644 --- a/drivers/staging/iio/accel/adis16204_ring.c +++ b/drivers/staging/iio/accel/adis16204_ring.c @@ -78,7 +78,7 @@ static irqreturn_t adis16204_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index f939e29d6c8..6af9a5dbc70 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -78,7 +78,7 @@ static irqreturn_t adis16209_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c index caff8e25e0a..e2ac8a8c810 100644 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -76,7 +76,7 @@ static irqreturn_t adis16240_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 24635271653..bc38651c315 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -154,7 +154,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64))) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index c2906a85fed..b3dd514b962 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -93,7 +93,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) indio_dev->masklength); i++) buf[i] = be16_to_cpu(st->rx_buf[i]); - iio_push_to_buffer(indio_dev->buffer, (u8 *)buf); + iio_push_to_buffers(indio_dev, (u8 *)buf); done: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index ba04d0ffd4f..2b25cb07fe4 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -83,7 +83,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s) if (indio_dev->scan_timestamp) *((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns; - iio_push_to_buffer(indio_dev->buffer, buf); + iio_push_to_buffers(indio_dev, buf); done: gpio_set_value(st->pdata->gpio_convst, 0); iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 86026d9b20b..2c5f38475a8 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -77,7 +77,7 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p) memcpy(rxbuf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); - iio_push_to_buffer(indio_dev->buffer, rxbuf); + iio_push_to_buffers(indio_dev, rxbuf); done: kfree(rxbuf); out: diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index 5f74f3b7671..688304bdbaf 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -80,7 +80,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); - iio_push_to_buffer(indio_dev->buffer, rxbuf); + iio_push_to_buffers(indio_dev, rxbuf); done_free: kfree(rxbuf); diff --git a/drivers/staging/iio/adc/mxs-lradc.c b/drivers/staging/iio/adc/mxs-lradc.c index df5bba284b7..3b467d8c588 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -237,7 +237,6 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *iio = pf->indio_dev; struct mxs_lradc *lradc = iio_priv(iio); - struct iio_buffer *buffer = iio->buffer; const uint32_t chan_value = LRADC_CH_ACCUMULATE | ((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET); int i, j = 0; @@ -256,7 +255,7 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p) *timestamp = pf->timestamp; } - iio_push_to_buffer(buffer, (u8 *)lradc->buffer); + iio_push_to_buffers(iio, (u8 *)lradc->buffer); iio_trigger_notify_done(iio->trig); diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c index e294cb49736..d6c48f850a9 100644 --- a/drivers/staging/iio/gyro/adis16260_ring.c +++ b/drivers/staging/iio/gyro/adis16260_ring.c @@ -81,7 +81,7 @@ static irqreturn_t adis16260_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); kfree(data); done: diff --git a/drivers/staging/iio/iio_simple_dummy_buffer.c b/drivers/staging/iio/iio_simple_dummy_buffer.c index 697d9700db2..dee16f0e757 100644 --- a/drivers/staging/iio/iio_simple_dummy_buffer.c +++ b/drivers/staging/iio/iio_simple_dummy_buffer.c @@ -46,7 +46,6 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; - struct iio_buffer *buffer = indio_dev->buffer; int len = 0; u16 *data; @@ -76,7 +75,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) i < bitmap_weight(indio_dev->active_scan_mask, indio_dev->masklength); i++, j++) { - j = find_next_bit(buffer->scan_mask, + j = find_next_bit(indio_dev->active_scan_mask, indio_dev->masklength, j); /* random access read from the 'device' */ data[i] = fakedata[j]; @@ -87,7 +86,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) if (indio_dev->scan_timestamp) *(s64 *)((u8 *)data + ALIGN(len, sizeof(s64))) = iio_get_time_ns(); - iio_push_to_buffer(buffer, (u8 *)data); + iio_push_to_buffers(indio_dev, (u8 *)data); kfree(data); diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index de21d47f33e..b1fef147d5b 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -647,7 +647,6 @@ static void ad5933_work(struct work_struct *work) struct ad5933_state *st = container_of(work, struct ad5933_state, work.work); struct iio_dev *indio_dev = i2c_get_clientdata(st->client); - struct iio_buffer *ring = indio_dev->buffer; signed short buf[2]; unsigned char status; @@ -677,8 +676,7 @@ static void ad5933_work(struct work_struct *work) } else { buf[0] = be16_to_cpu(buf[0]); } - /* save datum to the ring */ - iio_push_to_buffer(ring, (u8 *)buf); + iio_push_to_buffers(indio_dev, (u8 *)buf); } else { /* no data available - try again later */ schedule_delayed_work(&st->work, st->poll_time_jiffies); diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c index 260bdd1a468..d46c1e38cf7 100644 --- a/drivers/staging/iio/imu/adis16400_ring.c +++ b/drivers/staging/iio/imu/adis16400_ring.c @@ -114,7 +114,6 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adis16400_state *st = iio_priv(indio_dev); - struct iio_buffer *ring = indio_dev->buffer; int i = 0, j, ret = 0; s16 *data; @@ -148,9 +147,9 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) } } /* Guaranteed to be aligned with 8 byte boundary */ - if (ring->scan_timestamp) + if (indio_dev->scan_timestamp) *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - iio_push_to_buffer(ring, (u8 *) data); + iio_push_to_buffers(indio_dev, (u8 *) data); done: kfree(data); diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index 9e49baccf66..4552a4c7fe3 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -73,7 +73,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) dat64[1] = pf->timestamp; - iio_push_to_buffer(indio_dev->buffer, (u8 *)dat64); + iio_push_to_buffers(indio_dev, (u8 *)dat64); iio_trigger_notify_done(indio_dev->trig); diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index c629b3a1d9a..02704056918 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -66,7 +66,8 @@ struct iio_buffer_access_funcs { * @stufftoread: [INTERN] flag to indicate new data. * @demux_list: [INTERN] list of operations required to demux the scan. * @demux_bounce: [INTERN] buffer for doing gather from incoming scan. - **/ + * @buffer_list: [INTERN] entry in the devices list of current buffers. + */ struct iio_buffer { int length; int bytes_per_datum; @@ -81,8 +82,21 @@ struct iio_buffer { const struct attribute_group *attrs; struct list_head demux_list; unsigned char *demux_bounce; + struct list_head buffer_list; }; +/** + * iio_update_buffers() - add or remove buffer from active list + * @indio_dev: device to add buffer to + * @insert_buffer: buffer to insert + * @remove_buffer: buffer_to_remove + * + * Note this will tear down the all buffering and build it up again + */ +int iio_update_buffers(struct iio_dev *indio_dev, + struct iio_buffer *insert_buffer, + struct iio_buffer *remove_buffer); + /** * iio_buffer_init() - Initialize the buffer structure * @buffer: buffer to be initialized @@ -115,11 +129,11 @@ int iio_scan_mask_set(struct iio_dev *indio_dev, struct iio_buffer *buffer, int bit); /** - * iio_push_to_buffer() - push to a registered buffer. - * @buffer: IIO buffer structure for device - * @data: the data to push to the buffer + * iio_push_to_buffers() - push to a registered buffer. + * @indio_dev: iio_dev structure for device. + * @data: Full scan. */ -int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data); +int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data); int iio_update_demux(struct iio_dev *indio_dev); diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 7806c24e5bc..adca93a999a 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -410,6 +410,7 @@ struct iio_buffer_setup_ops { * and owner * @event_interface: [INTERN] event chrdevs associated with interrupt lines * @buffer: [DRIVER] any buffer present + * @buffer_list: [INTERN] list of all buffers currently attached * @scan_bytes: [INTERN] num bytes captured to be fed to buffer demux * @mlock: [INTERN] lock used to prevent simultaneous device state * changes @@ -448,6 +449,7 @@ struct iio_dev { struct iio_event_interface *event_interface; struct iio_buffer *buffer; + struct list_head buffer_list; int scan_bytes; struct mutex mlock; -- cgit v1.2.3 From 0464415dd21785aa8e8b12dbc939fcb5ca52f464 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 30 Jun 2012 20:06:00 +0100 Subject: staging:iio:in kernel users: Add a data field for channel specific info. Used to allow information about a given channel mapping to be passed through from board files to the consumer drivers. Signed-off-by: Jonathan Cameron --- drivers/iio/inkern.c | 1 + include/linux/iio/consumer.h | 2 ++ include/linux/iio/machine.h | 2 ++ 3 files changed, 5 insertions(+) diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index b394621d362..d55e98fb300 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -203,6 +203,7 @@ struct iio_channel *iio_channel_get_all(const char *name) if (name && strcmp(name, c->map->consumer_dev_name) != 0) continue; chans[mapind].indio_dev = c->indio_dev; + chans[mapind].data = c->map->consumer_data; chans[mapind].channel = iio_chan_spec_from_name(chans[mapind].indio_dev, c->map->adc_channel_label); diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index e875bcf0478..57efee63a6d 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -18,10 +18,12 @@ struct iio_chan_spec; * struct iio_channel - everything needed for a consumer to use a channel * @indio_dev: Device on which the channel exists. * @channel: Full description of the channel. + * @data: Data about the channel used by consumer. */ struct iio_channel { struct iio_dev *indio_dev; const struct iio_chan_spec *channel; + void *data; }; /** diff --git a/include/linux/iio/machine.h b/include/linux/iio/machine.h index 809a3f08d5a..1601a2a63a7 100644 --- a/include/linux/iio/machine.h +++ b/include/linux/iio/machine.h @@ -19,11 +19,13 @@ * @consumer_dev_name: Name to uniquely identify the consumer device. * @consumer_channel: Unique name used to identify the channel on the * consumer side. + * @consumer_data: Data about the channel for use by the consumer driver. */ struct iio_map { const char *adc_channel_label; const char *consumer_dev_name; const char *consumer_channel; + void *consumer_data; }; #endif -- cgit v1.2.3 From 92d1079b281f89f1c65c6aece3cfab4fb422c797 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 30 Jun 2012 20:06:00 +0100 Subject: staging:iio: add a callback buffer for in kernel push interface This callback buffer is meant to be opaque to users, but basically adds a very simple pass through buffer to which data may be pushed when it is inserted into the buffer list. Signed-off-by: Jonathan Cameron --- drivers/iio/Kconfig | 6 +++ drivers/iio/Makefile | 1 + drivers/iio/buffer_cb.c | 113 +++++++++++++++++++++++++++++++++++++++++++ include/linux/iio/consumer.h | 46 ++++++++++++++++++ 4 files changed, 166 insertions(+) create mode 100644 drivers/iio/buffer_cb.c diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index fc937aca71f..65ae734c607 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -20,6 +20,12 @@ config IIO_BUFFER if IIO_BUFFER +config IIO_BUFFER_CB +boolean "IIO callback buffer used for push in-kernel interfaces" + help + Should be selected by any drivers that do-inkernel push + usage. That is, those where the data is pushed to the consumer. + config IIO_KFIFO_BUF select IIO_TRIGGER tristate "Industrial I/O buffering based on kfifo" diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index 761f2b65ac5..31d76a07ec6 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_IIO) += industrialio.o industrialio-y := industrialio-core.o industrialio-event.o inkern.o industrialio-$(CONFIG_IIO_BUFFER) += industrialio-buffer.o industrialio-$(CONFIG_IIO_TRIGGER) += industrialio-trigger.o +industrialio-$(CONFIG_IIO_BUFFER_CB) += buffer_cb.o obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o diff --git a/drivers/iio/buffer_cb.c b/drivers/iio/buffer_cb.c new file mode 100644 index 00000000000..4d40e24f372 --- /dev/null +++ b/drivers/iio/buffer_cb.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include + +struct iio_cb_buffer { + struct iio_buffer buffer; + int (*cb)(u8 *data, void *private); + void *private; + struct iio_channel *channels; +}; + +static int iio_buffer_cb_store_to(struct iio_buffer *buffer, u8 *data) +{ + struct iio_cb_buffer *cb_buff = container_of(buffer, + struct iio_cb_buffer, + buffer); + + return cb_buff->cb(data, cb_buff->private); +} + +static struct iio_buffer_access_funcs iio_cb_access = { + .store_to = &iio_buffer_cb_store_to, +}; + +struct iio_cb_buffer *iio_channel_get_all_cb(const char *name, + int (*cb)(u8 *data, + void *private), + void *private) +{ + int ret; + struct iio_cb_buffer *cb_buff; + struct iio_dev *indio_dev; + struct iio_channel *chan; + + cb_buff = kzalloc(sizeof(*cb_buff), GFP_KERNEL); + if (cb_buff == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + cb_buff->private = private; + cb_buff->cb = cb; + cb_buff->buffer.access = &iio_cb_access; + INIT_LIST_HEAD(&cb_buff->buffer.demux_list); + + cb_buff->channels = iio_channel_get_all(name); + if (IS_ERR(cb_buff->channels)) { + ret = PTR_ERR(cb_buff->channels); + goto error_free_cb_buff; + } + + indio_dev = cb_buff->channels[0].indio_dev; + cb_buff->buffer.scan_mask + = kcalloc(BITS_TO_LONGS(indio_dev->masklength), sizeof(long), + GFP_KERNEL); + if (cb_buff->buffer.scan_mask == NULL) { + ret = -ENOMEM; + goto error_release_channels; + } + chan = &cb_buff->channels[0]; + while (chan->indio_dev) { + if (chan->indio_dev != indio_dev) { + ret = -EINVAL; + goto error_release_channels; + } + set_bit(chan->channel->scan_index, + cb_buff->buffer.scan_mask); + chan++; + } + + return cb_buff; + +error_release_channels: + iio_channel_release_all(cb_buff->channels); +error_free_cb_buff: + kfree(cb_buff); +error_ret: + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(iio_channel_get_all_cb); + +int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff) +{ + return iio_update_buffers(cb_buff->channels[0].indio_dev, + &cb_buff->buffer, + NULL); +} +EXPORT_SYMBOL_GPL(iio_channel_start_all_cb); + +void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff) +{ + iio_update_buffers(cb_buff->channels[0].indio_dev, + NULL, + &cb_buff->buffer); +} +EXPORT_SYMBOL_GPL(iio_channel_stop_all_cb); + +void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buff) +{ + iio_channel_release_all(cb_buff->channels); + kfree(cb_buff); +} +EXPORT_SYMBOL_GPL(iio_channel_release_all_cb); + +struct iio_channel +*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer) +{ + return cb_buffer->channels; +} +EXPORT_SYMBOL_GPL(iio_channel_cb_get_channels); diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index 57efee63a6d..126c0a9375f 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -61,6 +61,52 @@ struct iio_channel *iio_channel_get_all(const char *name); */ void iio_channel_release_all(struct iio_channel *chan); +struct iio_cb_buffer; +/** + * iio_channel_get_all_cb() - register callback for triggered capture + * @name: Name of client device. + * @cb: Callback function. + * @private: Private data passed to callback. + * + * NB right now we have no ability to mux data from multiple devices. + * So if the channels requested come from different devices this will + * fail. + */ +struct iio_cb_buffer *iio_channel_get_all_cb(const char *name, + int (*cb)(u8 *data, + void *private), + void *private); +/** + * iio_channel_release_all_cb() - release and unregister the callback. + * @cb_buffer: The callback buffer that was allocated. + */ +void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buffer); + +/** + * iio_channel_start_all_cb() - start the flow of data through callback. + * @cb_buff: The callback buffer we are starting. + */ +int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff); + +/** + * iio_channel_stop_all_cb() - stop the flow of data through the callback. + * @cb_buff: The callback buffer we are stopping. + */ +void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff); + +/** + * iio_channel_cb_get_channels() - get access to the underlying channels. + * @cb_buff: The callback buffer from whom we want the channel + * information. + * + * This function allows one to obtain information about the channels. + * Whilst this may allow direct reading if all buffers are disabled, the + * primary aim is to allow drivers that are consuming a channel to query + * things like scaling of the channel. + */ +struct iio_channel +*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer); + /** * iio_read_channel_raw() - read from a given channel * @chan: The channel being queried. -- cgit v1.2.3 From 0d331e4fd26c6caafa27ff4048294b2bb9263b2a Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 19 May 2012 15:27:51 +0100 Subject: staging:iio:adc:max1363 ring_sw->kfifo conversion We are moving towards scrapping ring_sw so this move is necessary. Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/Kconfig | 2 +- drivers/staging/iio/adc/max1363_ring.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index eba64fb64d8..e662a5c55b5 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -149,7 +149,7 @@ config MAX1363_RING_BUFFER bool "Maxim max1363: use ring buffer" depends on MAX1363 select IIO_BUFFER - select IIO_SW_RING + select IIO_KFIFO_BUF help Say yes here to include ring buffer support in the MAX1363 ADC driver. diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index 688304bdbaf..41af17b5e74 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -16,7 +16,7 @@ #include #include -#include "../ring_sw.h" +#include #include #include "max1363.h" @@ -101,7 +101,7 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) struct max1363_state *st = iio_priv(indio_dev); int ret = 0; - indio_dev->buffer = iio_sw_rb_allocate(indio_dev); + indio_dev->buffer = iio_kfifo_allocate(indio_dev); if (!indio_dev->buffer) { ret = -ENOMEM; goto error_ret; @@ -126,7 +126,7 @@ int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) return 0; error_deallocate_sw_rb: - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); error_ret: return ret; } @@ -135,5 +135,5 @@ void max1363_ring_cleanup(struct iio_dev *indio_dev) { /* ensure that the trigger has been detached */ iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); + iio_kfifo_free(indio_dev->buffer); } -- cgit v1.2.3 From b3bcbfcfece186f3a3799460aea3da30577615f9 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 6 Oct 2012 14:10:05 +0100 Subject: staging:iio:adc:max1363 consolidate files. For a long while now the max1363 core has selected the buffer anyway. For a while I meant to make the separation work again, but given how long it has been it is probably time to conclude it will never happen and settle for tidying up what we have. Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/Kconfig | 16 +- drivers/staging/iio/adc/Makefile | 3 - drivers/staging/iio/adc/max1363.c | 1705 ++++++++++++++++++++++++++++++++ drivers/staging/iio/adc/max1363.h | 177 ---- drivers/staging/iio/adc/max1363_core.c | 1444 --------------------------- drivers/staging/iio/adc/max1363_ring.c | 139 --- 6 files changed, 1710 insertions(+), 1774 deletions(-) create mode 100644 drivers/staging/iio/adc/max1363.c delete mode 100644 drivers/staging/iio/adc/max1363.h delete mode 100644 drivers/staging/iio/adc/max1363_core.c delete mode 100644 drivers/staging/iio/adc/max1363_ring.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index e662a5c55b5..4d348048b39 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -133,8 +133,10 @@ config AD7280 config MAX1363 tristate "Maxim max1363 ADC driver" depends on I2C - select IIO_TRIGGER if IIO_BUFFER + select IIO_TRIGGER select MAX1363_RING_BUFFER + select IIO_BUFFER + select IIO_KFIFO_BUF help Say yes here to build support for many Maxim i2c analog to digital converters (ADC). (max1361, max1362, max1363, max1364, max1036, @@ -143,16 +145,8 @@ config MAX1363 max11602, max11603, max11604, max11605, max11606, max11607, max11608, max11609, max11610, max11611, max11612, max11613, max11614, max11615, max11616, max11617, max11644, max11645, - max11646, max11647) Provides direct access via sysfs. - -config MAX1363_RING_BUFFER - bool "Maxim max1363: use ring buffer" - depends on MAX1363 - select IIO_BUFFER - select IIO_KFIFO_BUF - help - Say yes here to include ring buffer support in the MAX1363 - ADC driver. + max11646, max11647) Provides direct access via sysfs and buffered + data via the iio dev interface. config LPC32XX_ADC tristate "NXP LPC32XX ADC" diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index c56b41ee285..33979e62871 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -2,9 +2,6 @@ # Makefile for industrial I/O ADC drivers # -max1363-y := max1363_core.o -max1363-y += max1363_ring.o - obj-$(CONFIG_MAX1363) += max1363.o ad7606-y := ad7606_core.o diff --git a/drivers/staging/iio/adc/max1363.c b/drivers/staging/iio/adc/max1363.c new file mode 100644 index 00000000000..72715a4d594 --- /dev/null +++ b/drivers/staging/iio/adc/max1363.c @@ -0,0 +1,1705 @@ + /* + * iio/adc/max1363.c + * Copyright (C) 2008-2010 Jonathan Cameron + * + * based on linux/drivers/i2c/chips/max123x + * Copyright (C) 2002-2004 Stefan Eletzhofer + * + * based on linux/drivers/acron/char/pcf8583.c + * Copyright (C) 2000 Russell King + * + * 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. + * + * max1363.c + * + * Partial support for max1363 and similar chips. + * + * Not currently implemented. + * + * - Control of internal reference. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MAX1363_SETUP_BYTE(a) ((a) | 0x80) + +/* There is a fair bit more defined here than currently + * used, but the intention is to support everything these + * chips do in the long run */ + +/* see data sheets */ +/* max1363 and max1236, max1237, max1238, max1239 */ +#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD 0x00 +#define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF 0x20 +#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT 0x40 +#define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT 0x60 +#define MAX1363_SETUP_POWER_UP_INT_REF 0x10 +#define MAX1363_SETUP_POWER_DOWN_INT_REF 0x00 + +/* think about includeing max11600 etc - more settings */ +#define MAX1363_SETUP_EXT_CLOCK 0x08 +#define MAX1363_SETUP_INT_CLOCK 0x00 +#define MAX1363_SETUP_UNIPOLAR 0x00 +#define MAX1363_SETUP_BIPOLAR 0x04 +#define MAX1363_SETUP_RESET 0x00 +#define MAX1363_SETUP_NORESET 0x02 +/* max1363 only - though don't care on others. + * For now monitor modes are not implemented as the relevant + * line is not connected on my test board. + * The definitions are here as I intend to add this soon. + */ +#define MAX1363_SETUP_MONITOR_SETUP 0x01 + +/* Specific to the max1363 */ +#define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4)) +#define MAX1363_MON_INT_ENABLE 0x01 + +/* defined for readability reasons */ +/* All chips */ +#define MAX1363_CONFIG_BYTE(a) ((a)) + +#define MAX1363_CONFIG_SE 0x01 +#define MAX1363_CONFIG_DE 0x00 +#define MAX1363_CONFIG_SCAN_TO_CS 0x00 +#define MAX1363_CONFIG_SCAN_SINGLE_8 0x20 +#define MAX1363_CONFIG_SCAN_MONITOR_MODE 0x40 +#define MAX1363_CONFIG_SCAN_SINGLE_1 0x60 +/* max123{6-9} only */ +#define MAX1236_SCAN_MID_TO_CHANNEL 0x40 + +/* max1363 only - merely part of channel selects or don't care for others*/ +#define MAX1363_CONFIG_EN_MON_MODE_READ 0x18 + +#define MAX1363_CHANNEL_SEL(a) ((a) << 1) + +/* max1363 strictly 0x06 - but doesn't matter */ +#define MAX1363_CHANNEL_SEL_MASK 0x1E +#define MAX1363_SCAN_MASK 0x60 +#define MAX1363_SE_DE_MASK 0x01 + +#define MAX1363_MAX_CHANNELS 25 +/** + * struct max1363_mode - scan mode information + * @conf: The corresponding value of the configuration register + * @modemask: Bit mask corresponding to channels enabled in this mode + */ +struct max1363_mode { + int8_t conf; + DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS); +}; + +/* This must be maintained along side the max1363_mode_table in max1363_core */ +enum max1363_modes { + /* Single read of a single channel */ + _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, + /* Differential single read */ + d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, + d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, + /* Scan to channel and mid to channel where overlapping */ + s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6, + s6to7, s0to7, s6to8, s0to8, s6to9, + s0to9, s6to10, s0to10, s6to11, s0to11, + /* Differential scan to channel and mid to channel where overlapping */ + d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9, + d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2, + d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8, + d7m6to11m10, d1m0to11m10, +}; + +/** + * struct max1363_chip_info - chip specifc information + * @name: indentification string for chip + * @bits: accuracy of the adc in bits + * @int_vref_mv: the internal reference voltage + * @info: iio core function callbacks structure + * @mode_list: array of available scan modes + * @num_modes: the number of scan modes available + * @default_mode: the scan mode in which the chip starts up + * @channel: channel specification + * @num_channels: number of channels + */ +struct max1363_chip_info { + const struct iio_info *info; + const struct iio_chan_spec *channels; + int num_channels; + const enum max1363_modes *mode_list; + enum max1363_modes default_mode; + u16 int_vref_mv; + u8 num_modes; + u8 bits; +}; + +/** + * struct max1363_state - driver instance specific data + * @client: i2c_client + * @setupbyte: cache of current device setup byte + * @configbyte: cache of current device config byte + * @chip_info: chip model specific constants, available modes etc + * @current_mode: the scan mode of this chip + * @requestedmask: a valid requested set of channels + * @reg: supply regulator + * @monitor_on: whether monitor mode is enabled + * @monitor_speed: parameter corresponding to device monitor speed setting + * @mask_high: bitmask for enabled high thresholds + * @mask_low: bitmask for enabled low thresholds + * @thresh_high: high threshold values + * @thresh_low: low threshold values + */ +struct max1363_state { + struct i2c_client *client; + u8 setupbyte; + u8 configbyte; + const struct max1363_chip_info *chip_info; + const struct max1363_mode *current_mode; + u32 requestedmask; + struct regulator *reg; + + /* Using monitor modes and buffer at the same time is + currently not supported */ + bool monitor_on; + unsigned int monitor_speed:3; + u8 mask_high; + u8 mask_low; + /* 4x unipolar first then the fours bipolar ones */ + s16 thresh_high[8]; + s16 thresh_low[8]; +}; + +#define MAX1363_MODE_SINGLE(_num, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ + | MAX1363_CONFIG_SCAN_SINGLE_1 \ + | MAX1363_CONFIG_SE, \ + .modemask[0] = _mask, \ + } + +#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ + | MAX1363_CONFIG_SCAN_TO_CS \ + | MAX1363_CONFIG_SE, \ + .modemask[0] = _mask, \ + } + +/* note not available for max1363 hence naming */ +#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ + | MAX1236_SCAN_MID_TO_CHANNEL \ + | MAX1363_CONFIG_SE, \ + .modemask[0] = _mask \ +} + +#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_nump) \ + | MAX1363_CONFIG_SCAN_SINGLE_1 \ + | MAX1363_CONFIG_DE, \ + .modemask[0] = _mask \ + } + +/* Can't think how to automate naming so specify for now */ +#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ + | MAX1363_CONFIG_SCAN_TO_CS \ + | MAX1363_CONFIG_DE, \ + .modemask[0] = _mask \ + } + +/* note only available for max1363 hence naming */ +#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ + | MAX1236_SCAN_MID_TO_CHANNEL \ + | MAX1363_CONFIG_SE, \ + .modemask[0] = _mask \ +} + +static const struct max1363_mode max1363_mode_table[] = { + /* All of the single channel options first */ + MAX1363_MODE_SINGLE(0, 1 << 0), + MAX1363_MODE_SINGLE(1, 1 << 1), + MAX1363_MODE_SINGLE(2, 1 << 2), + MAX1363_MODE_SINGLE(3, 1 << 3), + MAX1363_MODE_SINGLE(4, 1 << 4), + MAX1363_MODE_SINGLE(5, 1 << 5), + MAX1363_MODE_SINGLE(6, 1 << 6), + MAX1363_MODE_SINGLE(7, 1 << 7), + MAX1363_MODE_SINGLE(8, 1 << 8), + MAX1363_MODE_SINGLE(9, 1 << 9), + MAX1363_MODE_SINGLE(10, 1 << 10), + MAX1363_MODE_SINGLE(11, 1 << 11), + + MAX1363_MODE_DIFF_SINGLE(0, 1, 1 << 12), + MAX1363_MODE_DIFF_SINGLE(2, 3, 1 << 13), + MAX1363_MODE_DIFF_SINGLE(4, 5, 1 << 14), + MAX1363_MODE_DIFF_SINGLE(6, 7, 1 << 15), + MAX1363_MODE_DIFF_SINGLE(8, 9, 1 << 16), + MAX1363_MODE_DIFF_SINGLE(10, 11, 1 << 17), + MAX1363_MODE_DIFF_SINGLE(1, 0, 1 << 18), + MAX1363_MODE_DIFF_SINGLE(3, 2, 1 << 19), + MAX1363_MODE_DIFF_SINGLE(5, 4, 1 << 20), + MAX1363_MODE_DIFF_SINGLE(7, 6, 1 << 21), + MAX1363_MODE_DIFF_SINGLE(9, 8, 1 << 22), + MAX1363_MODE_DIFF_SINGLE(11, 10, 1 << 23), + + /* The multichannel scans next */ + MAX1363_MODE_SCAN_TO_CHANNEL(1, 0x003), + MAX1363_MODE_SCAN_TO_CHANNEL(2, 0x007), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(2, 3, 0x00C), + MAX1363_MODE_SCAN_TO_CHANNEL(3, 0x00F), + MAX1363_MODE_SCAN_TO_CHANNEL(4, 0x01F), + MAX1363_MODE_SCAN_TO_CHANNEL(5, 0x03F), + MAX1363_MODE_SCAN_TO_CHANNEL(6, 0x07F), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 7, 0x0C0), + MAX1363_MODE_SCAN_TO_CHANNEL(7, 0x0FF), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 8, 0x1C0), + MAX1363_MODE_SCAN_TO_CHANNEL(8, 0x1FF), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 9, 0x3C0), + MAX1363_MODE_SCAN_TO_CHANNEL(9, 0x3FF), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 10, 0x7C0), + MAX1363_MODE_SCAN_TO_CHANNEL(10, 0x7FF), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 11, 0xFC0), + MAX1363_MODE_SCAN_TO_CHANNEL(11, 0xFFF), + + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(2, 2, 0x003000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(4, 3, 0x007000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(6, 4, 0x00F000), + MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(8, 2, 0x018000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(8, 5, 0x01F000), + MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(10, 3, 0x038000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(10, 6, 0x3F000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(3, 2, 0x0C0000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(5, 3, 0x1C0000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(7, 4, 0x3C0000), + MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(9, 2, 0x600000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(9, 5, 0x7C0000), + MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(11, 3, 0xE00000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(11, 6, 0xFC0000), +}; + +static const struct max1363_mode +*max1363_match_mode(const unsigned long *mask, +const struct max1363_chip_info *ci) +{ + int i; + if (mask) + for (i = 0; i < ci->num_modes; i++) + if (bitmap_subset(mask, + max1363_mode_table[ci->mode_list[i]]. + modemask, + MAX1363_MAX_CHANNELS)) + return &max1363_mode_table[ci->mode_list[i]]; + return NULL; +} + +static int max1363_write_basic_config(struct i2c_client *client, + unsigned char d1, + unsigned char d2) +{ + u8 tx_buf[2] = {d1, d2}; + + return i2c_master_send(client, tx_buf, 2); +} + +static int max1363_set_scan_mode(struct max1363_state *st) +{ + st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK + | MAX1363_SCAN_MASK + | MAX1363_SE_DE_MASK); + st->configbyte |= st->current_mode->conf; + + return max1363_write_basic_config(st->client, + st->setupbyte, + st->configbyte); +} + +static int max1363_read_single_chan(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + long m) +{ + int ret = 0; + s32 data; + char rxbuf[2]; + struct max1363_state *st = iio_priv(indio_dev); + struct i2c_client *client = st->client; + + mutex_lock(&indio_dev->mlock); + /* + * If monitor mode is enabled, the method for reading a single + * channel will have to be rather different and has not yet + * been implemented. + * + * Also, cannot read directly if buffered capture enabled. + */ + if (st->monitor_on || iio_buffer_enabled(indio_dev)) { + ret = -EBUSY; + goto error_ret; + } + + /* Check to see if current scan mode is correct */ + if (st->current_mode != &max1363_mode_table[chan->address]) { + /* Update scan mode if needed */ + st->current_mode = &max1363_mode_table[chan->address]; + ret = max1363_set_scan_mode(st); + if (ret < 0) + goto error_ret; + } + if (st->chip_info->bits != 8) { + /* Get reading */ + data = i2c_master_recv(client, rxbuf, 2); + if (data < 0) { + ret = data; + goto error_ret; + } + data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8; + } else { + /* Get reading */ + data = i2c_master_recv(client, rxbuf, 1); + if (data < 0) { + ret = data; + goto error_ret; + } + data = rxbuf[0]; + } + *val = data; +error_ret: + mutex_unlock(&indio_dev->mlock); + return ret; + +} + +static int max1363_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct max1363_state *st = iio_priv(indio_dev); + int ret; + switch (m) { + case IIO_CHAN_INFO_RAW: + ret = max1363_read_single_chan(indio_dev, chan, val, m); + if (ret < 0) + return ret; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + if ((1 << (st->chip_info->bits + 1)) > + st->chip_info->int_vref_mv) { + *val = 0; + *val2 = 500000; + return IIO_VAL_INT_PLUS_MICRO; + } else { + *val = (st->chip_info->int_vref_mv) + >> st->chip_info->bits; + return IIO_VAL_INT; + } + default: + return -EINVAL; + } + return 0; +} + +/* Applies to max1363 */ +static const enum max1363_modes max1363_mode_list[] = { + _s0, _s1, _s2, _s3, + s0to1, s0to2, s0to3, + d0m1, d2m3, d1m0, d3m2, + d0m1to2m3, d1m0to3m2, +}; + +#define MAX1363_EV_M \ + (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) \ + | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)) +#define MAX1363_INFO_MASK (IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT) +#define MAX1363_CHAN_U(num, addr, si, bits, evmask) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = num, \ + .address = addr, \ + .info_mask = MAX1363_INFO_MASK, \ + .datasheet_name = "AIN"#num, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = bits, \ + .storagebits = (bits > 8) ? 16 : 8, \ + .endianness = IIO_BE, \ + }, \ + .scan_index = si, \ + .event_mask = evmask, \ + } + +/* bipolar channel */ +#define MAX1363_CHAN_B(num, num2, addr, si, bits, evmask) \ + { \ + .type = IIO_VOLTAGE, \ + .differential = 1, \ + .indexed = 1, \ + .channel = num, \ + .channel2 = num2, \ + .address = addr, \ + .info_mask = MAX1363_INFO_MASK, \ + .datasheet_name = "AIN"#num"-AIN"#num2, \ + .scan_type = { \ + .sign = 's', \ + .realbits = bits, \ + .storagebits = (bits > 8) ? 16 : 8, \ + .endianness = IIO_BE, \ + }, \ + .scan_index = si, \ + .event_mask = evmask, \ + } + +#define MAX1363_4X_CHANS(bits, em) { \ + MAX1363_CHAN_U(0, _s0, 0, bits, em), \ + MAX1363_CHAN_U(1, _s1, 1, bits, em), \ + MAX1363_CHAN_U(2, _s2, 2, bits, em), \ + MAX1363_CHAN_U(3, _s3, 3, bits, em), \ + MAX1363_CHAN_B(0, 1, d0m1, 4, bits, em), \ + MAX1363_CHAN_B(2, 3, d2m3, 5, bits, em), \ + MAX1363_CHAN_B(1, 0, d1m0, 6, bits, em), \ + MAX1363_CHAN_B(3, 2, d3m2, 7, bits, em), \ + IIO_CHAN_SOFT_TIMESTAMP(8) \ + } + +static const struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8, 0); +static const struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10, 0); +static const struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12, 0); +static const struct iio_chan_spec max1361_channels[] = + MAX1363_4X_CHANS(10, MAX1363_EV_M); +static const struct iio_chan_spec max1363_channels[] = + MAX1363_4X_CHANS(12, MAX1363_EV_M); + +/* Applies to max1236, max1237 */ +static const enum max1363_modes max1236_mode_list[] = { + _s0, _s1, _s2, _s3, + s0to1, s0to2, s0to3, + d0m1, d2m3, d1m0, d3m2, + d0m1to2m3, d1m0to3m2, + s2to3, +}; + +/* Applies to max1238, max1239 */ +static const enum max1363_modes max1238_mode_list[] = { + _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, + s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, + s0to7, s0to8, s0to9, s0to10, s0to11, + d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, + d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, + d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11, + d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10, + s6to7, s6to8, s6to9, s6to10, s6to11, + d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10, +}; + +#define MAX1363_12X_CHANS(bits) { \ + MAX1363_CHAN_U(0, _s0, 0, bits, 0), \ + MAX1363_CHAN_U(1, _s1, 1, bits, 0), \ + MAX1363_CHAN_U(2, _s2, 2, bits, 0), \ + MAX1363_CHAN_U(3, _s3, 3, bits, 0), \ + MAX1363_CHAN_U(4, _s4, 4, bits, 0), \ + MAX1363_CHAN_U(5, _s5, 5, bits, 0), \ + MAX1363_CHAN_U(6, _s6, 6, bits, 0), \ + MAX1363_CHAN_U(7, _s7, 7, bits, 0), \ + MAX1363_CHAN_U(8, _s8, 8, bits, 0), \ + MAX1363_CHAN_U(9, _s9, 9, bits, 0), \ + MAX1363_CHAN_U(10, _s10, 10, bits, 0), \ + MAX1363_CHAN_U(11, _s11, 11, bits, 0), \ + MAX1363_CHAN_B(0, 1, d0m1, 12, bits, 0), \ + MAX1363_CHAN_B(2, 3, d2m3, 13, bits, 0), \ + MAX1363_CHAN_B(4, 5, d4m5, 14, bits, 0), \ + MAX1363_CHAN_B(6, 7, d6m7, 15, bits, 0), \ + MAX1363_CHAN_B(8, 9, d8m9, 16, bits, 0), \ + MAX1363_CHAN_B(10, 11, d10m11, 17, bits, 0), \ + MAX1363_CHAN_B(1, 0, d1m0, 18, bits, 0), \ + MAX1363_CHAN_B(3, 2, d3m2, 19, bits, 0), \ + MAX1363_CHAN_B(5, 4, d5m4, 20, bits, 0), \ + MAX1363_CHAN_B(7, 6, d7m6, 21, bits, 0), \ + MAX1363_CHAN_B(9, 8, d9m8, 22, bits, 0), \ + MAX1363_CHAN_B(11, 10, d11m10, 23, bits, 0), \ + IIO_CHAN_SOFT_TIMESTAMP(24) \ + } +static const struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8); +static const struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10); +static const struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12); + +static const enum max1363_modes max11607_mode_list[] = { + _s0, _s1, _s2, _s3, + s0to1, s0to2, s0to3, + s2to3, + d0m1, d2m3, d1m0, d3m2, + d0m1to2m3, d1m0to3m2, +}; + +static const enum max1363_modes max11608_mode_list[] = { + _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, + s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s0to7, + s6to7, + d0m1, d2m3, d4m5, d6m7, + d1m0, d3m2, d5m4, d7m6, + d0m1to2m3, d0m1to4m5, d0m1to6m7, + d1m0to3m2, d1m0to5m4, d1m0to7m6, +}; + +#define MAX1363_8X_CHANS(bits) { \ + MAX1363_CHAN_U(0, _s0, 0, bits, 0), \ + MAX1363_CHAN_U(1, _s1, 1, bits, 0), \ + MAX1363_CHAN_U(2, _s2, 2, bits, 0), \ + MAX1363_CHAN_U(3, _s3, 3, bits, 0), \ + MAX1363_CHAN_U(4, _s4, 4, bits, 0), \ + MAX1363_CHAN_U(5, _s5, 5, bits, 0), \ + MAX1363_CHAN_U(6, _s6, 6, bits, 0), \ + MAX1363_CHAN_U(7, _s7, 7, bits, 0), \ + MAX1363_CHAN_B(0, 1, d0m1, 8, bits, 0), \ + MAX1363_CHAN_B(2, 3, d2m3, 9, bits, 0), \ + MAX1363_CHAN_B(4, 5, d4m5, 10, bits, 0), \ + MAX1363_CHAN_B(6, 7, d6m7, 11, bits, 0), \ + MAX1363_CHAN_B(1, 0, d1m0, 12, bits, 0), \ + MAX1363_CHAN_B(3, 2, d3m2, 13, bits, 0), \ + MAX1363_CHAN_B(5, 4, d5m4, 14, bits, 0), \ + MAX1363_CHAN_B(7, 6, d7m6, 15, bits, 0), \ + IIO_CHAN_SOFT_TIMESTAMP(16) \ +} +static const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8); +static const struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10); +static const struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12); + +static const enum max1363_modes max11644_mode_list[] = { + _s0, _s1, s0to1, d0m1, d1m0, +}; + +#define MAX1363_2X_CHANS(bits) { \ + MAX1363_CHAN_U(0, _s0, 0, bits, 0), \ + MAX1363_CHAN_U(1, _s1, 1, bits, 0), \ + MAX1363_CHAN_B(0, 1, d0m1, 2, bits, 0), \ + MAX1363_CHAN_B(1, 0, d1m0, 3, bits, 0), \ + IIO_CHAN_SOFT_TIMESTAMP(4) \ + } + +static const struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10); +static const struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12); + +enum { max1361, + max1362, + max1363, + max1364, + max1036, + max1037, + max1038, + max1039, + max1136, + max1137, + max1138, + max1139, + max1236, + max1237, + max1238, + max1239, + max11600, + max11601, + max11602, + max11603, + max11604, + max11605, + max11606, + max11607, + max11608, + max11609, + max11610, + max11611, + max11612, + max11613, + max11614, + max11615, + max11616, + max11617, + max11644, + max11645, + max11646, + max11647 +}; + +static const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600, + 8300, 4200, 2000, 1000 }; + +static ssize_t max1363_monitor_show_freq(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct max1363_state *st = iio_priv(dev_to_iio_dev(dev)); + return sprintf(buf, "%d\n", max1363_monitor_speeds[st->monitor_speed]); +} + +static ssize_t max1363_monitor_store_freq(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct max1363_state *st = iio_priv(indio_dev); + int i, ret; + unsigned long val; + bool found = false; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + return -EINVAL; + for (i = 0; i < ARRAY_SIZE(max1363_monitor_speeds); i++) + if (val == max1363_monitor_speeds[i]) { + found = true; + break; + } + if (!found) + return -EINVAL; + + mutex_lock(&indio_dev->mlock); + st->monitor_speed = i; + mutex_unlock(&indio_dev->mlock); + + return 0; +} + +static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, + max1363_monitor_show_freq, + max1363_monitor_store_freq); + +static IIO_CONST_ATTR(sampling_frequency_available, + "133000 665000 33300 16600 8300 4200 2000 1000"); + +static int max1363_read_thresh(struct iio_dev *indio_dev, + u64 event_code, + int *val) +{ + struct max1363_state *st = iio_priv(indio_dev); + if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) + *val = st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)]; + else + *val = st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)]; + return 0; +} + +static int max1363_write_thresh(struct iio_dev *indio_dev, + u64 event_code, + int val) +{ + struct max1363_state *st = iio_priv(indio_dev); + /* make it handle signed correctly as well */ + switch (st->chip_info->bits) { + case 10: + if (val > 0x3FF) + return -EINVAL; + break; + case 12: + if (val > 0xFFF) + return -EINVAL; + break; + } + + switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { + case IIO_EV_DIR_FALLING: + st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val; + break; + case IIO_EV_DIR_RISING: + st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val; + break; + } + + return 0; +} + +static const u64 max1363_event_codes[] = { + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), +}; + +static irqreturn_t max1363_event_handler(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct max1363_state *st = iio_priv(indio_dev); + s64 timestamp = iio_get_time_ns(); + unsigned long mask, loc; + u8 rx; + u8 tx[2] = { st->setupbyte, + MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 }; + + i2c_master_recv(st->client, &rx, 1); + mask = rx; + for_each_set_bit(loc, &mask, 8) + iio_push_event(indio_dev, max1363_event_codes[loc], timestamp); + i2c_master_send(st->client, tx, 2); + + return IRQ_HANDLED; +} + +static int max1363_read_event_config(struct iio_dev *indio_dev, + u64 event_code) +{ + struct max1363_state *st = iio_priv(indio_dev); + + int val; + int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code); + mutex_lock(&indio_dev->mlock); + if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) + val = (1 << number) & st->mask_low; + else + val = (1 << number) & st->mask_high; + mutex_unlock(&indio_dev->mlock); + + return val; +} + +static int max1363_monitor_mode_update(struct max1363_state *st, int enabled) +{ + u8 *tx_buf; + int ret, i = 3, j; + unsigned long numelements; + int len; + const long *modemask; + + if (!enabled) { + /* transition to ring capture is not currently supported */ + st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP; + st->configbyte &= ~MAX1363_SCAN_MASK; + st->monitor_on = false; + return max1363_write_basic_config(st->client, + st->setupbyte, + st->configbyte); + } + + /* Ensure we are in the relevant mode */ + st->setupbyte |= MAX1363_SETUP_MONITOR_SETUP; + st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK + | MAX1363_SCAN_MASK + | MAX1363_SE_DE_MASK); + st->configbyte |= MAX1363_CONFIG_SCAN_MONITOR_MODE; + if ((st->mask_low | st->mask_high) & 0x0F) { + st->configbyte |= max1363_mode_table[s0to3].conf; + modemask = max1363_mode_table[s0to3].modemask; + } else if ((st->mask_low | st->mask_high) & 0x30) { + st->configbyte |= max1363_mode_table[d0m1to2m3].conf; + modemask = max1363_mode_table[d0m1to2m3].modemask; + } else { + st->configbyte |= max1363_mode_table[d1m0to3m2].conf; + modemask = max1363_mode_table[d1m0to3m2].modemask; + } + numelements = bitmap_weight(modemask, MAX1363_MAX_CHANNELS); + len = 3 * numelements + 3; + tx_buf = kmalloc(len, GFP_KERNEL); + if (!tx_buf) { + ret = -ENOMEM; + goto error_ret; + } + tx_buf[0] = st->configbyte; + tx_buf[1] = st->setupbyte; + tx_buf[2] = (st->monitor_speed << 1); + + /* + * So we need to do yet another bit of nefarious scan mode + * setup to match what we need. + */ + for (j = 0; j < 8; j++) + if (test_bit(j, modemask)) { + /* Establish the mode is in the scan */ + if (st->mask_low & (1 << j)) { + tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF; + tx_buf[i + 1] = (st->thresh_low[j] << 4) & 0xF0; + } else if (j < 4) { + tx_buf[i] = 0; + tx_buf[i + 1] = 0; + } else { + tx_buf[i] = 0x80; + tx_buf[i + 1] = 0; + } + if (st->mask_high & (1 << j)) { + tx_buf[i + 1] |= + (st->thresh_high[j] >> 8) & 0x0F; + tx_buf[i + 2] = st->thresh_high[j] & 0xFF; + } else if (j < 4) { + tx_buf[i + 1] |= 0x0F; + tx_buf[i + 2] = 0xFF; + } else { + tx_buf[i + 1] |= 0x07; + tx_buf[i + 2] = 0xFF; + } + i += 3; + } + + + ret = i2c_master_send(st->client, tx_buf, len); + if (ret < 0) + goto error_ret; + if (ret != len) { + ret = -EIO; + goto error_ret; + } + + /* + * Now that we hopefully have sensible thresholds in place it is + * time to turn the interrupts on. + * It is unclear from the data sheet if this should be necessary + * (i.e. whether monitor mode setup is atomic) but it appears to + * be in practice. + */ + tx_buf[0] = st->setupbyte; + tx_buf[1] = MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0; + ret = i2c_master_send(st->client, tx_buf, 2); + if (ret < 0) + goto error_ret; + if (ret != 2) { + ret = -EIO; + goto error_ret; + } + ret = 0; + st->monitor_on = true; +error_ret: + + kfree(tx_buf); + + return ret; +} + +/* + * To keep this manageable we always use one of 3 scan modes. + * Scan 0...3, 0-1,2-3 and 1-0,3-2 + */ + +static inline int __max1363_check_event_mask(int thismask, int checkmask) +{ + int ret = 0; + /* Is it unipolar */ + if (thismask < 4) { + if (checkmask & ~0x0F) { + ret = -EBUSY; + goto error_ret; + } + } else if (thismask < 6) { + if (checkmask & ~0x30) { + ret = -EBUSY; + goto error_ret; + } + } else if (checkmask & ~0xC0) + ret = -EBUSY; +error_ret: + return ret; +} + +static int max1363_write_event_config(struct iio_dev *indio_dev, + u64 event_code, + int state) +{ + int ret = 0; + struct max1363_state *st = iio_priv(indio_dev); + u16 unifiedmask; + int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code); + + mutex_lock(&indio_dev->mlock); + unifiedmask = st->mask_low | st->mask_high; + if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) { + + if (state == 0) + st->mask_low &= ~(1 << number); + else { + ret = __max1363_check_event_mask((1 << number), + unifiedmask); + if (ret) + goto error_ret; + st->mask_low |= (1 << number); + } + } else { + if (state == 0) + st->mask_high &= ~(1 << number); + else { + ret = __max1363_check_event_mask((1 << number), + unifiedmask); + if (ret) + goto error_ret; + st->mask_high |= (1 << number); + } + } + + max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low)); +error_ret: + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +/* + * As with scan_elements, only certain sets of these can + * be combined. + */ +static struct attribute *max1363_event_attributes[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + NULL, +}; + +static struct attribute_group max1363_event_attribute_group = { + .attrs = max1363_event_attributes, + .name = "events", +}; + +#define MAX1363_EVENT_FUNCS \ + +static int max1363_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct max1363_state *st = iio_priv(indio_dev); + + /* + * Need to figure out the current mode based upon the requested + * scan mask in iio_dev + */ + st->current_mode = max1363_match_mode(scan_mask, st->chip_info); + if (!st->current_mode) + return -EINVAL; + max1363_set_scan_mode(st); + return 0; +} + +static const struct iio_info max1238_info = { + .read_raw = &max1363_read_raw, + .driver_module = THIS_MODULE, + .update_scan_mode = &max1363_update_scan_mode, +}; + +static const struct iio_info max1363_info = { + .read_event_value = &max1363_read_thresh, + .write_event_value = &max1363_write_thresh, + .read_event_config = &max1363_read_event_config, + .write_event_config = &max1363_write_event_config, + .read_raw = &max1363_read_raw, + .update_scan_mode = &max1363_update_scan_mode, + .driver_module = THIS_MODULE, + .event_attrs = &max1363_event_attribute_group, +}; + +/* max1363 and max1368 tested - rest from data sheet */ +static const struct max1363_chip_info max1363_chip_info_tbl[] = { + [max1361] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max1363_mode_list, + .num_modes = ARRAY_SIZE(max1363_mode_list), + .default_mode = s0to3, + .channels = max1361_channels, + .num_channels = ARRAY_SIZE(max1361_channels), + .info = &max1363_info, + }, + [max1362] = { + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max1363_mode_list, + .num_modes = ARRAY_SIZE(max1363_mode_list), + .default_mode = s0to3, + .channels = max1361_channels, + .num_channels = ARRAY_SIZE(max1361_channels), + .info = &max1363_info, + }, + [max1363] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max1363_mode_list, + .num_modes = ARRAY_SIZE(max1363_mode_list), + .default_mode = s0to3, + .channels = max1363_channels, + .num_channels = ARRAY_SIZE(max1363_channels), + .info = &max1363_info, + }, + [max1364] = { + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max1363_mode_list, + .num_modes = ARRAY_SIZE(max1363_mode_list), + .default_mode = s0to3, + .channels = max1363_channels, + .num_channels = ARRAY_SIZE(max1363_channels), + .info = &max1363_info, + }, + [max1036] = { + .bits = 8, + .int_vref_mv = 4096, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1036_channels, + .num_channels = ARRAY_SIZE(max1036_channels), + }, + [max1037] = { + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1036_channels, + .num_channels = ARRAY_SIZE(max1036_channels), + }, + [max1038] = { + .bits = 8, + .int_vref_mv = 4096, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1038_channels, + .num_channels = ARRAY_SIZE(max1038_channels), + }, + [max1039] = { + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1038_channels, + .num_channels = ARRAY_SIZE(max1038_channels), + }, + [max1136] = { + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1136_channels, + .num_channels = ARRAY_SIZE(max1136_channels), + }, + [max1137] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1136_channels, + .num_channels = ARRAY_SIZE(max1136_channels), + }, + [max1138] = { + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1138_channels, + .num_channels = ARRAY_SIZE(max1138_channels), + }, + [max1139] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1138_channels, + .num_channels = ARRAY_SIZE(max1138_channels), + }, + [max1236] = { + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1236_channels, + .num_channels = ARRAY_SIZE(max1236_channels), + }, + [max1237] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1236_channels, + .num_channels = ARRAY_SIZE(max1236_channels), + }, + [max1238] = { + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max1239] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11600] = { + .bits = 8, + .int_vref_mv = 4096, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1036_channels, + .num_channels = ARRAY_SIZE(max1036_channels), + }, + [max11601] = { + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1036_channels, + .num_channels = ARRAY_SIZE(max1036_channels), + }, + [max11602] = { + .bits = 8, + .int_vref_mv = 4096, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .info = &max1238_info, + .channels = max11602_channels, + .num_channels = ARRAY_SIZE(max11602_channels), + }, + [max11603] = { + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .info = &max1238_info, + .channels = max11602_channels, + .num_channels = ARRAY_SIZE(max11602_channels), + }, + [max11604] = { + .bits = 8, + .int_vref_mv = 4098, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11605] = { + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11606] = { + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1136_channels, + .num_channels = ARRAY_SIZE(max1136_channels), + }, + [max11607] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1136_channels, + .num_channels = ARRAY_SIZE(max1136_channels), + }, + [max11608] = { + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .info = &max1238_info, + .channels = max11608_channels, + .num_channels = ARRAY_SIZE(max11608_channels), + }, + [max11609] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .info = &max1238_info, + .channels = max11608_channels, + .num_channels = ARRAY_SIZE(max11608_channels), + }, + [max11610] = { + .bits = 10, + .int_vref_mv = 4098, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11611] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11612] = { + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1363_channels, + .num_channels = ARRAY_SIZE(max1363_channels), + }, + [max11613] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1363_channels, + .num_channels = ARRAY_SIZE(max1363_channels), + }, + [max11614] = { + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .info = &max1238_info, + .channels = max11614_channels, + .num_channels = ARRAY_SIZE(max11614_channels), + }, + [max11615] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .info = &max1238_info, + .channels = max11614_channels, + .num_channels = ARRAY_SIZE(max11614_channels), + }, + [max11616] = { + .bits = 12, + .int_vref_mv = 4098, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11617] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11644] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max11644_mode_list, + .num_modes = ARRAY_SIZE(max11644_mode_list), + .default_mode = s0to1, + .info = &max1238_info, + .channels = max11644_channels, + .num_channels = ARRAY_SIZE(max11644_channels), + }, + [max11645] = { + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max11644_mode_list, + .num_modes = ARRAY_SIZE(max11644_mode_list), + .default_mode = s0to1, + .info = &max1238_info, + .channels = max11644_channels, + .num_channels = ARRAY_SIZE(max11644_channels), + }, + [max11646] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max11644_mode_list, + .num_modes = ARRAY_SIZE(max11644_mode_list), + .default_mode = s0to1, + .info = &max1238_info, + .channels = max11646_channels, + .num_channels = ARRAY_SIZE(max11646_channels), + }, + [max11647] = { + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max11644_mode_list, + .num_modes = ARRAY_SIZE(max11644_mode_list), + .default_mode = s0to1, + .info = &max1238_info, + .channels = max11646_channels, + .num_channels = ARRAY_SIZE(max11646_channels), + }, +}; + + + +static int max1363_initial_setup(struct max1363_state *st) +{ + st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD + | MAX1363_SETUP_POWER_UP_INT_REF + | MAX1363_SETUP_INT_CLOCK + | MAX1363_SETUP_UNIPOLAR + | MAX1363_SETUP_NORESET; + + /* Set scan mode writes the config anyway so wait until then*/ + st->setupbyte = MAX1363_SETUP_BYTE(st->setupbyte); + st->current_mode = &max1363_mode_table[st->chip_info->default_mode]; + st->configbyte = MAX1363_CONFIG_BYTE(st->configbyte); + + return max1363_set_scan_mode(st); +} + +static int __devinit max1363_alloc_scan_masks(struct iio_dev *indio_dev) +{ + struct max1363_state *st = iio_priv(indio_dev); + unsigned long *masks; + int i; + + masks = kzalloc(BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*sizeof(long)* + (st->chip_info->num_modes + 1), GFP_KERNEL); + if (!masks) + return -ENOMEM; + + for (i = 0; i < st->chip_info->num_modes; i++) + bitmap_copy(masks + BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*i, + max1363_mode_table[st->chip_info->mode_list[i]] + .modemask, MAX1363_MAX_CHANNELS); + + indio_dev->available_scan_masks = masks; + + return 0; +} + + +static irqreturn_t max1363_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct max1363_state *st = iio_priv(indio_dev); + s64 time_ns; + __u8 *rxbuf; + int b_sent; + size_t d_size; + unsigned long numvals = bitmap_weight(st->current_mode->modemask, + MAX1363_MAX_CHANNELS); + + /* Ensure the timestamp is 8 byte aligned */ + if (st->chip_info->bits != 8) + d_size = numvals*2; + else + d_size = numvals; + if (indio_dev->scan_timestamp) { + d_size += sizeof(s64); + if (d_size % sizeof(s64)) + d_size += sizeof(s64) - (d_size % sizeof(s64)); + } + /* Monitor mode prevents reading. Whilst not currently implemented + * might as well have this test in here in the meantime as it does + * no harm. + */ + if (numvals == 0) + goto done; + + rxbuf = kmalloc(d_size, GFP_KERNEL); + if (rxbuf == NULL) + goto done; + if (st->chip_info->bits != 8) + b_sent = i2c_master_recv(st->client, rxbuf, numvals*2); + else + b_sent = i2c_master_recv(st->client, rxbuf, numvals); + if (b_sent < 0) + goto done_free; + + time_ns = iio_get_time_ns(); + + if (indio_dev->scan_timestamp) + memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); + iio_push_to_buffers(indio_dev, rxbuf); + +done_free: + kfree(rxbuf); +done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static const struct iio_buffer_setup_ops max1363_ring_setup_ops = { + .postenable = &iio_triggered_buffer_postenable, + .preenable = &iio_sw_buffer_preenable, + .predisable = &iio_triggered_buffer_predisable, +}; + +static int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) +{ + struct max1363_state *st = iio_priv(indio_dev); + int ret = 0; + + indio_dev->buffer = iio_kfifo_allocate(indio_dev); + if (!indio_dev->buffer) { + ret = -ENOMEM; + goto error_ret; + } + indio_dev->pollfunc = iio_alloc_pollfunc(NULL, + &max1363_trigger_handler, + IRQF_ONESHOT, + indio_dev, + "%s_consumer%d", + st->client->name, + indio_dev->id); + if (indio_dev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_deallocate_sw_rb; + } + /* Ring buffer functions - here trigger setup related */ + indio_dev->setup_ops = &max1363_ring_setup_ops; + + /* Flag that polled ring buffering is possible */ + indio_dev->modes |= INDIO_BUFFER_TRIGGERED; + + return 0; + +error_deallocate_sw_rb: + iio_kfifo_free(indio_dev->buffer); +error_ret: + return ret; +} + +static void max1363_ring_cleanup(struct iio_dev *indio_dev) +{ + /* ensure that the trigger has been detached */ + iio_dealloc_pollfunc(indio_dev->pollfunc); + iio_kfifo_free(indio_dev->buffer); +} + +static int __devinit max1363_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + struct max1363_state *st; + struct iio_dev *indio_dev; + struct regulator *reg; + + reg = regulator_get(&client->dev, "vcc"); + if (IS_ERR(reg)) { + ret = PTR_ERR(reg); + goto error_out; + } + + ret = regulator_enable(reg); + if (ret) + goto error_put_reg; + + indio_dev = iio_device_alloc(sizeof(struct max1363_state)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + ret = iio_map_array_register(indio_dev, client->dev.platform_data); + if (ret < 0) + goto error_free_device; + st = iio_priv(indio_dev); + st->reg = reg; + /* this is only used for device removal purposes */ + i2c_set_clientdata(client, indio_dev); + + st->chip_info = &max1363_chip_info_tbl[id->driver_data]; + st->client = client; + + ret = max1363_alloc_scan_masks(indio_dev); + if (ret) + goto error_unregister_map; + + /* Estabilish that the iio_dev is a child of the i2c device */ + indio_dev->dev.parent = &client->dev; + indio_dev->name = id->name; + indio_dev->channels = st->chip_info->channels; + indio_dev->num_channels = st->chip_info->num_channels; + indio_dev->info = st->chip_info->info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->chip_info->channels; + indio_dev->num_channels = st->chip_info->num_channels; + ret = max1363_initial_setup(st); + if (ret < 0) + goto error_free_available_scan_masks; + + ret = max1363_register_ring_funcs_and_init(indio_dev); + if (ret) + goto error_free_available_scan_masks; + + ret = iio_buffer_register(indio_dev, + st->chip_info->channels, + st->chip_info->num_channels); + if (ret) + goto error_cleanup_ring; + + if (client->irq) { + ret = request_threaded_irq(st->client->irq, + NULL, + &max1363_event_handler, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "max1363_event", + indio_dev); + + if (ret) + goto error_uninit_ring; + } + + ret = iio_device_register(indio_dev); + if (ret < 0) + goto error_free_irq; + + return 0; +error_free_irq: + free_irq(st->client->irq, indio_dev); +error_uninit_ring: + iio_buffer_unregister(indio_dev); +error_cleanup_ring: + max1363_ring_cleanup(indio_dev); +error_free_available_scan_masks: + kfree(indio_dev->available_scan_masks); +error_unregister_map: + iio_map_array_unregister(indio_dev, client->dev.platform_data); +error_free_device: + iio_device_free(indio_dev); +error_disable_reg: + regulator_disable(reg); +error_put_reg: + regulator_put(reg); +error_out: + return ret; +} + +static int __devexit max1363_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct max1363_state *st = iio_priv(indio_dev); + struct regulator *reg = st->reg; + + iio_device_unregister(indio_dev); + if (client->irq) + free_irq(st->client->irq, indio_dev); + iio_buffer_unregister(indio_dev); + max1363_ring_cleanup(indio_dev); + kfree(indio_dev->available_scan_masks); + if (!IS_ERR(reg)) { + regulator_disable(reg); + regulator_put(reg); + } + iio_map_array_unregister(indio_dev, client->dev.platform_data); + iio_device_free(indio_dev); + + return 0; +} + +static const struct i2c_device_id max1363_id[] = { + { "max1361", max1361 }, + { "max1362", max1362 }, + { "max1363", max1363 }, + { "max1364", max1364 }, + { "max1036", max1036 }, + { "max1037", max1037 }, + { "max1038", max1038 }, + { "max1039", max1039 }, + { "max1136", max1136 }, + { "max1137", max1137 }, + { "max1138", max1138 }, + { "max1139", max1139 }, + { "max1236", max1236 }, + { "max1237", max1237 }, + { "max1238", max1238 }, + { "max1239", max1239 }, + { "max11600", max11600 }, + { "max11601", max11601 }, + { "max11602", max11602 }, + { "max11603", max11603 }, + { "max11604", max11604 }, + { "max11605", max11605 }, + { "max11606", max11606 }, + { "max11607", max11607 }, + { "max11608", max11608 }, + { "max11609", max11609 }, + { "max11610", max11610 }, + { "max11611", max11611 }, + { "max11612", max11612 }, + { "max11613", max11613 }, + { "max11614", max11614 }, + { "max11615", max11615 }, + { "max11616", max11616 }, + { "max11617", max11617 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, max1363_id); + +static struct i2c_driver max1363_driver = { + .driver = { + .name = "max1363", + }, + .probe = max1363_probe, + .remove = __devexit_p(max1363_remove), + .id_table = max1363_id, +}; +module_i2c_driver(max1363_driver); + +MODULE_AUTHOR("Jonathan Cameron "); +MODULE_DESCRIPTION("Maxim 1363 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/max1363.h b/drivers/staging/iio/adc/max1363.h deleted file mode 100644 index c746918683f..00000000000 --- a/drivers/staging/iio/adc/max1363.h +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef _MAX1363_H_ -#define _MAX1363_H_ - -#define MAX1363_SETUP_BYTE(a) ((a) | 0x80) - -/* There is a fair bit more defined here than currently - * used, but the intention is to support everything these - * chips do in the long run */ - -/* see data sheets */ -/* max1363 and max1236, max1237, max1238, max1239 */ -#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD 0x00 -#define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF 0x20 -#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT 0x40 -#define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT 0x60 -#define MAX1363_SETUP_POWER_UP_INT_REF 0x10 -#define MAX1363_SETUP_POWER_DOWN_INT_REF 0x00 - -/* think about includeing max11600 etc - more settings */ -#define MAX1363_SETUP_EXT_CLOCK 0x08 -#define MAX1363_SETUP_INT_CLOCK 0x00 -#define MAX1363_SETUP_UNIPOLAR 0x00 -#define MAX1363_SETUP_BIPOLAR 0x04 -#define MAX1363_SETUP_RESET 0x00 -#define MAX1363_SETUP_NORESET 0x02 -/* max1363 only - though don't care on others. - * For now monitor modes are not implemented as the relevant - * line is not connected on my test board. - * The definitions are here as I intend to add this soon. - */ -#define MAX1363_SETUP_MONITOR_SETUP 0x01 - -/* Specific to the max1363 */ -#define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4)) -#define MAX1363_MON_INT_ENABLE 0x01 - -/* defined for readability reasons */ -/* All chips */ -#define MAX1363_CONFIG_BYTE(a) ((a)) - -#define MAX1363_CONFIG_SE 0x01 -#define MAX1363_CONFIG_DE 0x00 -#define MAX1363_CONFIG_SCAN_TO_CS 0x00 -#define MAX1363_CONFIG_SCAN_SINGLE_8 0x20 -#define MAX1363_CONFIG_SCAN_MONITOR_MODE 0x40 -#define MAX1363_CONFIG_SCAN_SINGLE_1 0x60 -/* max123{6-9} only */ -#define MAX1236_SCAN_MID_TO_CHANNEL 0x40 - -/* max1363 only - merely part of channel selects or don't care for others*/ -#define MAX1363_CONFIG_EN_MON_MODE_READ 0x18 - -#define MAX1363_CHANNEL_SEL(a) ((a) << 1) - -/* max1363 strictly 0x06 - but doesn't matter */ -#define MAX1363_CHANNEL_SEL_MASK 0x1E -#define MAX1363_SCAN_MASK 0x60 -#define MAX1363_SE_DE_MASK 0x01 - -#define MAX1363_MAX_CHANNELS 25 -/** - * struct max1363_mode - scan mode information - * @conf: The corresponding value of the configuration register - * @modemask: Bit mask corresponding to channels enabled in this mode - */ -struct max1363_mode { - int8_t conf; - DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS); -}; - -/* This must be maintained along side the max1363_mode_table in max1363_core */ -enum max1363_modes { - /* Single read of a single channel */ - _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, - /* Differential single read */ - d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, - d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, - /* Scan to channel and mid to channel where overlapping */ - s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6, - s6to7, s0to7, s6to8, s0to8, s6to9, - s0to9, s6to10, s0to10, s6to11, s0to11, - /* Differential scan to channel and mid to channel where overlapping */ - d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9, - d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2, - d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8, - d7m6to11m10, d1m0to11m10, -}; - -/** - * struct max1363_chip_info - chip specifc information - * @name: indentification string for chip - * @bits: accuracy of the adc in bits - * @int_vref_mv: the internal reference voltage - * @info: iio core function callbacks structure - * @mode_list: array of available scan modes - * @num_modes: the number of scan modes available - * @default_mode: the scan mode in which the chip starts up - * @channel: channel specification - * @num_channels: number of channels - */ -struct max1363_chip_info { - const struct iio_info *info; - const struct iio_chan_spec *channels; - int num_channels; - const enum max1363_modes *mode_list; - enum max1363_modes default_mode; - u16 int_vref_mv; - u8 num_modes; - u8 bits; -}; - -/** - * struct max1363_state - driver instance specific data - * @client: i2c_client - * @setupbyte: cache of current device setup byte - * @configbyte: cache of current device config byte - * @chip_info: chip model specific constants, available modes etc - * @current_mode: the scan mode of this chip - * @requestedmask: a valid requested set of channels - * @reg: supply regulator - * @monitor_on: whether monitor mode is enabled - * @monitor_speed: parameter corresponding to device monitor speed setting - * @mask_high: bitmask for enabled high thresholds - * @mask_low: bitmask for enabled low thresholds - * @thresh_high: high threshold values - * @thresh_low: low threshold values - */ -struct max1363_state { - struct i2c_client *client; - u8 setupbyte; - u8 configbyte; - const struct max1363_chip_info *chip_info; - const struct max1363_mode *current_mode; - u32 requestedmask; - struct regulator *reg; - - /* Using monitor modes and buffer at the same time is - currently not supported */ - bool monitor_on; - unsigned int monitor_speed:3; - u8 mask_high; - u8 mask_low; - /* 4x unipolar first then the fours bipolar ones */ - s16 thresh_high[8]; - s16 thresh_low[8]; -}; - -const struct max1363_mode -*max1363_match_mode(const unsigned long *mask, - const struct max1363_chip_info *ci); - -int max1363_set_scan_mode(struct max1363_state *st); - -#ifdef CONFIG_MAX1363_RING_BUFFER -int max1363_update_scan_mode(struct iio_dev *indio_dev, - const unsigned long *scan_mask); -int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev); -void max1363_ring_cleanup(struct iio_dev *indio_dev); - -#else /* CONFIG_MAX1363_RING_BUFFER */ -int max1363_update_scan_mode(struct iio_dev *indio_dev, - const long *scan_mask) -{ - return 0; -} - -static inline int -max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void max1363_ring_cleanup(struct iio_dev *indio_dev) -{ -} -#endif /* CONFIG_MAX1363_RING_BUFFER */ -#endif /* _MAX1363_H_ */ diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c deleted file mode 100644 index d7b4ffcfa05..00000000000 --- a/drivers/staging/iio/adc/max1363_core.c +++ /dev/null @@ -1,1444 +0,0 @@ - /* - * iio/adc/max1363.c - * Copyright (C) 2008-2010 Jonathan Cameron - * - * based on linux/drivers/i2c/chips/max123x - * Copyright (C) 2002-2004 Stefan Eletzhofer - * - * based on linux/drivers/acron/char/pcf8583.c - * Copyright (C) 2000 Russell King - * - * 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. - * - * max1363.c - * - * Partial support for max1363 and similar chips. - * - * Not currently implemented. - * - * - Control of internal reference. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "max1363.h" - -#define MAX1363_MODE_SINGLE(_num, _mask) { \ - .conf = MAX1363_CHANNEL_SEL(_num) \ - | MAX1363_CONFIG_SCAN_SINGLE_1 \ - | MAX1363_CONFIG_SE, \ - .modemask[0] = _mask, \ - } - -#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) { \ - .conf = MAX1363_CHANNEL_SEL(_num) \ - | MAX1363_CONFIG_SCAN_TO_CS \ - | MAX1363_CONFIG_SE, \ - .modemask[0] = _mask, \ - } - -/* note not available for max1363 hence naming */ -#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) { \ - .conf = MAX1363_CHANNEL_SEL(_num) \ - | MAX1236_SCAN_MID_TO_CHANNEL \ - | MAX1363_CONFIG_SE, \ - .modemask[0] = _mask \ -} - -#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) { \ - .conf = MAX1363_CHANNEL_SEL(_nump) \ - | MAX1363_CONFIG_SCAN_SINGLE_1 \ - | MAX1363_CONFIG_DE, \ - .modemask[0] = _mask \ - } - -/* Can't think how to automate naming so specify for now */ -#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) { \ - .conf = MAX1363_CHANNEL_SEL(_num) \ - | MAX1363_CONFIG_SCAN_TO_CS \ - | MAX1363_CONFIG_DE, \ - .modemask[0] = _mask \ - } - -/* note only available for max1363 hence naming */ -#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) { \ - .conf = MAX1363_CHANNEL_SEL(_num) \ - | MAX1236_SCAN_MID_TO_CHANNEL \ - | MAX1363_CONFIG_SE, \ - .modemask[0] = _mask \ -} - -static const struct max1363_mode max1363_mode_table[] = { - /* All of the single channel options first */ - MAX1363_MODE_SINGLE(0, 1 << 0), - MAX1363_MODE_SINGLE(1, 1 << 1), - MAX1363_MODE_SINGLE(2, 1 << 2), - MAX1363_MODE_SINGLE(3, 1 << 3), - MAX1363_MODE_SINGLE(4, 1 << 4), - MAX1363_MODE_SINGLE(5, 1 << 5), - MAX1363_MODE_SINGLE(6, 1 << 6), - MAX1363_MODE_SINGLE(7, 1 << 7), - MAX1363_MODE_SINGLE(8, 1 << 8), - MAX1363_MODE_SINGLE(9, 1 << 9), - MAX1363_MODE_SINGLE(10, 1 << 10), - MAX1363_MODE_SINGLE(11, 1 << 11), - - MAX1363_MODE_DIFF_SINGLE(0, 1, 1 << 12), - MAX1363_MODE_DIFF_SINGLE(2, 3, 1 << 13), - MAX1363_MODE_DIFF_SINGLE(4, 5, 1 << 14), - MAX1363_MODE_DIFF_SINGLE(6, 7, 1 << 15), - MAX1363_MODE_DIFF_SINGLE(8, 9, 1 << 16), - MAX1363_MODE_DIFF_SINGLE(10, 11, 1 << 17), - MAX1363_MODE_DIFF_SINGLE(1, 0, 1 << 18), - MAX1363_MODE_DIFF_SINGLE(3, 2, 1 << 19), - MAX1363_MODE_DIFF_SINGLE(5, 4, 1 << 20), - MAX1363_MODE_DIFF_SINGLE(7, 6, 1 << 21), - MAX1363_MODE_DIFF_SINGLE(9, 8, 1 << 22), - MAX1363_MODE_DIFF_SINGLE(11, 10, 1 << 23), - - /* The multichannel scans next */ - MAX1363_MODE_SCAN_TO_CHANNEL(1, 0x003), - MAX1363_MODE_SCAN_TO_CHANNEL(2, 0x007), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(2, 3, 0x00C), - MAX1363_MODE_SCAN_TO_CHANNEL(3, 0x00F), - MAX1363_MODE_SCAN_TO_CHANNEL(4, 0x01F), - MAX1363_MODE_SCAN_TO_CHANNEL(5, 0x03F), - MAX1363_MODE_SCAN_TO_CHANNEL(6, 0x07F), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 7, 0x0C0), - MAX1363_MODE_SCAN_TO_CHANNEL(7, 0x0FF), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 8, 0x1C0), - MAX1363_MODE_SCAN_TO_CHANNEL(8, 0x1FF), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 9, 0x3C0), - MAX1363_MODE_SCAN_TO_CHANNEL(9, 0x3FF), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 10, 0x7C0), - MAX1363_MODE_SCAN_TO_CHANNEL(10, 0x7FF), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 11, 0xFC0), - MAX1363_MODE_SCAN_TO_CHANNEL(11, 0xFFF), - - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(2, 2, 0x003000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(4, 3, 0x007000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(6, 4, 0x00F000), - MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(8, 2, 0x018000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(8, 5, 0x01F000), - MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(10, 3, 0x038000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(10, 6, 0x3F000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(3, 2, 0x0C0000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(5, 3, 0x1C0000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(7, 4, 0x3C0000), - MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(9, 2, 0x600000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(9, 5, 0x7C0000), - MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(11, 3, 0xE00000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(11, 6, 0xFC0000), -}; - -const struct max1363_mode -*max1363_match_mode(const unsigned long *mask, -const struct max1363_chip_info *ci) -{ - int i; - if (mask) - for (i = 0; i < ci->num_modes; i++) - if (bitmap_subset(mask, - max1363_mode_table[ci->mode_list[i]]. - modemask, - MAX1363_MAX_CHANNELS)) - return &max1363_mode_table[ci->mode_list[i]]; - return NULL; -} - -static int max1363_write_basic_config(struct i2c_client *client, - unsigned char d1, - unsigned char d2) -{ - u8 tx_buf[2] = {d1, d2}; - - return i2c_master_send(client, tx_buf, 2); -} - -int max1363_set_scan_mode(struct max1363_state *st) -{ - st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK - | MAX1363_SCAN_MASK - | MAX1363_SE_DE_MASK); - st->configbyte |= st->current_mode->conf; - - return max1363_write_basic_config(st->client, - st->setupbyte, - st->configbyte); -} - -static int max1363_read_single_chan(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - long m) -{ - int ret = 0; - s32 data; - char rxbuf[2]; - struct max1363_state *st = iio_priv(indio_dev); - struct i2c_client *client = st->client; - - mutex_lock(&indio_dev->mlock); - /* - * If monitor mode is enabled, the method for reading a single - * channel will have to be rather different and has not yet - * been implemented. - * - * Also, cannot read directly if buffered capture enabled. - */ - if (st->monitor_on || iio_buffer_enabled(indio_dev)) { - ret = -EBUSY; - goto error_ret; - } - - /* Check to see if current scan mode is correct */ - if (st->current_mode != &max1363_mode_table[chan->address]) { - /* Update scan mode if needed */ - st->current_mode = &max1363_mode_table[chan->address]; - ret = max1363_set_scan_mode(st); - if (ret < 0) - goto error_ret; - } - if (st->chip_info->bits != 8) { - /* Get reading */ - data = i2c_master_recv(client, rxbuf, 2); - if (data < 0) { - ret = data; - goto error_ret; - } - data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8; - } else { - /* Get reading */ - data = i2c_master_recv(client, rxbuf, 1); - if (data < 0) { - ret = data; - goto error_ret; - } - data = rxbuf[0]; - } - *val = data; -error_ret: - mutex_unlock(&indio_dev->mlock); - return ret; - -} - -static int max1363_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long m) -{ - struct max1363_state *st = iio_priv(indio_dev); - int ret; - switch (m) { - case IIO_CHAN_INFO_RAW: - ret = max1363_read_single_chan(indio_dev, chan, val, m); - if (ret < 0) - return ret; - return IIO_VAL_INT; - case IIO_CHAN_INFO_SCALE: - if ((1 << (st->chip_info->bits + 1)) > - st->chip_info->int_vref_mv) { - *val = 0; - *val2 = 500000; - return IIO_VAL_INT_PLUS_MICRO; - } else { - *val = (st->chip_info->int_vref_mv) - >> st->chip_info->bits; - return IIO_VAL_INT; - } - default: - return -EINVAL; - } - return 0; -} - -/* Applies to max1363 */ -static const enum max1363_modes max1363_mode_list[] = { - _s0, _s1, _s2, _s3, - s0to1, s0to2, s0to3, - d0m1, d2m3, d1m0, d3m2, - d0m1to2m3, d1m0to3m2, -}; - -#define MAX1363_EV_M \ - (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) \ - | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)) -#define MAX1363_INFO_MASK (IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT) -#define MAX1363_CHAN_U(num, addr, si, bits, evmask) \ - { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = num, \ - .address = addr, \ - .info_mask = MAX1363_INFO_MASK, \ - .datasheet_name = "AIN"#num, \ - .scan_type = { \ - .sign = 'u', \ - .realbits = bits, \ - .storagebits = (bits > 8) ? 16 : 8, \ - .endianness = IIO_BE, \ - }, \ - .scan_index = si, \ - .event_mask = evmask, \ - } - -/* bipolar channel */ -#define MAX1363_CHAN_B(num, num2, addr, si, bits, evmask) \ - { \ - .type = IIO_VOLTAGE, \ - .differential = 1, \ - .indexed = 1, \ - .channel = num, \ - .channel2 = num2, \ - .address = addr, \ - .info_mask = MAX1363_INFO_MASK, \ - .datasheet_name = "AIN"#num"-AIN"#num2, \ - .scan_type = { \ - .sign = 's', \ - .realbits = bits, \ - .storagebits = (bits > 8) ? 16 : 8, \ - .endianness = IIO_BE, \ - }, \ - .scan_index = si, \ - .event_mask = evmask, \ - } - -#define MAX1363_4X_CHANS(bits, em) { \ - MAX1363_CHAN_U(0, _s0, 0, bits, em), \ - MAX1363_CHAN_U(1, _s1, 1, bits, em), \ - MAX1363_CHAN_U(2, _s2, 2, bits, em), \ - MAX1363_CHAN_U(3, _s3, 3, bits, em), \ - MAX1363_CHAN_B(0, 1, d0m1, 4, bits, em), \ - MAX1363_CHAN_B(2, 3, d2m3, 5, bits, em), \ - MAX1363_CHAN_B(1, 0, d1m0, 6, bits, em), \ - MAX1363_CHAN_B(3, 2, d3m2, 7, bits, em), \ - IIO_CHAN_SOFT_TIMESTAMP(8) \ - } - -static const struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8, 0); -static const struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10, 0); -static const struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12, 0); -static const struct iio_chan_spec max1361_channels[] = - MAX1363_4X_CHANS(10, MAX1363_EV_M); -static const struct iio_chan_spec max1363_channels[] = - MAX1363_4X_CHANS(12, MAX1363_EV_M); - -/* Applies to max1236, max1237 */ -static const enum max1363_modes max1236_mode_list[] = { - _s0, _s1, _s2, _s3, - s0to1, s0to2, s0to3, - d0m1, d2m3, d1m0, d3m2, - d0m1to2m3, d1m0to3m2, - s2to3, -}; - -/* Applies to max1238, max1239 */ -static const enum max1363_modes max1238_mode_list[] = { - _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, - s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, - s0to7, s0to8, s0to9, s0to10, s0to11, - d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, - d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, - d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11, - d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10, - s6to7, s6to8, s6to9, s6to10, s6to11, - d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10, -}; - -#define MAX1363_12X_CHANS(bits) { \ - MAX1363_CHAN_U(0, _s0, 0, bits, 0), \ - MAX1363_CHAN_U(1, _s1, 1, bits, 0), \ - MAX1363_CHAN_U(2, _s2, 2, bits, 0), \ - MAX1363_CHAN_U(3, _s3, 3, bits, 0), \ - MAX1363_CHAN_U(4, _s4, 4, bits, 0), \ - MAX1363_CHAN_U(5, _s5, 5, bits, 0), \ - MAX1363_CHAN_U(6, _s6, 6, bits, 0), \ - MAX1363_CHAN_U(7, _s7, 7, bits, 0), \ - MAX1363_CHAN_U(8, _s8, 8, bits, 0), \ - MAX1363_CHAN_U(9, _s9, 9, bits, 0), \ - MAX1363_CHAN_U(10, _s10, 10, bits, 0), \ - MAX1363_CHAN_U(11, _s11, 11, bits, 0), \ - MAX1363_CHAN_B(0, 1, d0m1, 12, bits, 0), \ - MAX1363_CHAN_B(2, 3, d2m3, 13, bits, 0), \ - MAX1363_CHAN_B(4, 5, d4m5, 14, bits, 0), \ - MAX1363_CHAN_B(6, 7, d6m7, 15, bits, 0), \ - MAX1363_CHAN_B(8, 9, d8m9, 16, bits, 0), \ - MAX1363_CHAN_B(10, 11, d10m11, 17, bits, 0), \ - MAX1363_CHAN_B(1, 0, d1m0, 18, bits, 0), \ - MAX1363_CHAN_B(3, 2, d3m2, 19, bits, 0), \ - MAX1363_CHAN_B(5, 4, d5m4, 20, bits, 0), \ - MAX1363_CHAN_B(7, 6, d7m6, 21, bits, 0), \ - MAX1363_CHAN_B(9, 8, d9m8, 22, bits, 0), \ - MAX1363_CHAN_B(11, 10, d11m10, 23, bits, 0), \ - IIO_CHAN_SOFT_TIMESTAMP(24) \ - } -static const struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8); -static const struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10); -static const struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12); - -static const enum max1363_modes max11607_mode_list[] = { - _s0, _s1, _s2, _s3, - s0to1, s0to2, s0to3, - s2to3, - d0m1, d2m3, d1m0, d3m2, - d0m1to2m3, d1m0to3m2, -}; - -static const enum max1363_modes max11608_mode_list[] = { - _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, - s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s0to7, - s6to7, - d0m1, d2m3, d4m5, d6m7, - d1m0, d3m2, d5m4, d7m6, - d0m1to2m3, d0m1to4m5, d0m1to6m7, - d1m0to3m2, d1m0to5m4, d1m0to7m6, -}; - -#define MAX1363_8X_CHANS(bits) { \ - MAX1363_CHAN_U(0, _s0, 0, bits, 0), \ - MAX1363_CHAN_U(1, _s1, 1, bits, 0), \ - MAX1363_CHAN_U(2, _s2, 2, bits, 0), \ - MAX1363_CHAN_U(3, _s3, 3, bits, 0), \ - MAX1363_CHAN_U(4, _s4, 4, bits, 0), \ - MAX1363_CHAN_U(5, _s5, 5, bits, 0), \ - MAX1363_CHAN_U(6, _s6, 6, bits, 0), \ - MAX1363_CHAN_U(7, _s7, 7, bits, 0), \ - MAX1363_CHAN_B(0, 1, d0m1, 8, bits, 0), \ - MAX1363_CHAN_B(2, 3, d2m3, 9, bits, 0), \ - MAX1363_CHAN_B(4, 5, d4m5, 10, bits, 0), \ - MAX1363_CHAN_B(6, 7, d6m7, 11, bits, 0), \ - MAX1363_CHAN_B(1, 0, d1m0, 12, bits, 0), \ - MAX1363_CHAN_B(3, 2, d3m2, 13, bits, 0), \ - MAX1363_CHAN_B(5, 4, d5m4, 14, bits, 0), \ - MAX1363_CHAN_B(7, 6, d7m6, 15, bits, 0), \ - IIO_CHAN_SOFT_TIMESTAMP(16) \ -} -static const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8); -static const struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10); -static const struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12); - -static const enum max1363_modes max11644_mode_list[] = { - _s0, _s1, s0to1, d0m1, d1m0, -}; - -#define MAX1363_2X_CHANS(bits) { \ - MAX1363_CHAN_U(0, _s0, 0, bits, 0), \ - MAX1363_CHAN_U(1, _s1, 1, bits, 0), \ - MAX1363_CHAN_B(0, 1, d0m1, 2, bits, 0), \ - MAX1363_CHAN_B(1, 0, d1m0, 3, bits, 0), \ - IIO_CHAN_SOFT_TIMESTAMP(4) \ - } - -static const struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10); -static const struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12); - -enum { max1361, - max1362, - max1363, - max1364, - max1036, - max1037, - max1038, - max1039, - max1136, - max1137, - max1138, - max1139, - max1236, - max1237, - max1238, - max1239, - max11600, - max11601, - max11602, - max11603, - max11604, - max11605, - max11606, - max11607, - max11608, - max11609, - max11610, - max11611, - max11612, - max11613, - max11614, - max11615, - max11616, - max11617, - max11644, - max11645, - max11646, - max11647 -}; - -static const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600, - 8300, 4200, 2000, 1000 }; - -static ssize_t max1363_monitor_show_freq(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct max1363_state *st = iio_priv(dev_to_iio_dev(dev)); - return sprintf(buf, "%d\n", max1363_monitor_speeds[st->monitor_speed]); -} - -static ssize_t max1363_monitor_store_freq(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct max1363_state *st = iio_priv(indio_dev); - int i, ret; - unsigned long val; - bool found = false; - - ret = strict_strtoul(buf, 10, &val); - if (ret) - return -EINVAL; - for (i = 0; i < ARRAY_SIZE(max1363_monitor_speeds); i++) - if (val == max1363_monitor_speeds[i]) { - found = true; - break; - } - if (!found) - return -EINVAL; - - mutex_lock(&indio_dev->mlock); - st->monitor_speed = i; - mutex_unlock(&indio_dev->mlock); - - return 0; -} - -static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, - max1363_monitor_show_freq, - max1363_monitor_store_freq); - -static IIO_CONST_ATTR(sampling_frequency_available, - "133000 665000 33300 16600 8300 4200 2000 1000"); - -static int max1363_read_thresh(struct iio_dev *indio_dev, - u64 event_code, - int *val) -{ - struct max1363_state *st = iio_priv(indio_dev); - if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) - *val = st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)]; - else - *val = st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)]; - return 0; -} - -static int max1363_write_thresh(struct iio_dev *indio_dev, - u64 event_code, - int val) -{ - struct max1363_state *st = iio_priv(indio_dev); - /* make it handle signed correctly as well */ - switch (st->chip_info->bits) { - case 10: - if (val > 0x3FF) - return -EINVAL; - break; - case 12: - if (val > 0xFFF) - return -EINVAL; - break; - } - - switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { - case IIO_EV_DIR_FALLING: - st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val; - break; - case IIO_EV_DIR_RISING: - st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val; - break; - } - - return 0; -} - -static const u64 max1363_event_codes[] = { - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), -}; - -static irqreturn_t max1363_event_handler(int irq, void *private) -{ - struct iio_dev *indio_dev = private; - struct max1363_state *st = iio_priv(indio_dev); - s64 timestamp = iio_get_time_ns(); - unsigned long mask, loc; - u8 rx; - u8 tx[2] = { st->setupbyte, - MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 }; - - i2c_master_recv(st->client, &rx, 1); - mask = rx; - for_each_set_bit(loc, &mask, 8) - iio_push_event(indio_dev, max1363_event_codes[loc], timestamp); - i2c_master_send(st->client, tx, 2); - - return IRQ_HANDLED; -} - -static int max1363_read_event_config(struct iio_dev *indio_dev, - u64 event_code) -{ - struct max1363_state *st = iio_priv(indio_dev); - - int val; - int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code); - mutex_lock(&indio_dev->mlock); - if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) - val = (1 << number) & st->mask_low; - else - val = (1 << number) & st->mask_high; - mutex_unlock(&indio_dev->mlock); - - return val; -} - -static int max1363_monitor_mode_update(struct max1363_state *st, int enabled) -{ - u8 *tx_buf; - int ret, i = 3, j; - unsigned long numelements; - int len; - const long *modemask; - - if (!enabled) { - /* transition to ring capture is not currently supported */ - st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP; - st->configbyte &= ~MAX1363_SCAN_MASK; - st->monitor_on = false; - return max1363_write_basic_config(st->client, - st->setupbyte, - st->configbyte); - } - - /* Ensure we are in the relevant mode */ - st->setupbyte |= MAX1363_SETUP_MONITOR_SETUP; - st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK - | MAX1363_SCAN_MASK - | MAX1363_SE_DE_MASK); - st->configbyte |= MAX1363_CONFIG_SCAN_MONITOR_MODE; - if ((st->mask_low | st->mask_high) & 0x0F) { - st->configbyte |= max1363_mode_table[s0to3].conf; - modemask = max1363_mode_table[s0to3].modemask; - } else if ((st->mask_low | st->mask_high) & 0x30) { - st->configbyte |= max1363_mode_table[d0m1to2m3].conf; - modemask = max1363_mode_table[d0m1to2m3].modemask; - } else { - st->configbyte |= max1363_mode_table[d1m0to3m2].conf; - modemask = max1363_mode_table[d1m0to3m2].modemask; - } - numelements = bitmap_weight(modemask, MAX1363_MAX_CHANNELS); - len = 3 * numelements + 3; - tx_buf = kmalloc(len, GFP_KERNEL); - if (!tx_buf) { - ret = -ENOMEM; - goto error_ret; - } - tx_buf[0] = st->configbyte; - tx_buf[1] = st->setupbyte; - tx_buf[2] = (st->monitor_speed << 1); - - /* - * So we need to do yet another bit of nefarious scan mode - * setup to match what we need. - */ - for (j = 0; j < 8; j++) - if (test_bit(j, modemask)) { - /* Establish the mode is in the scan */ - if (st->mask_low & (1 << j)) { - tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF; - tx_buf[i + 1] = (st->thresh_low[j] << 4) & 0xF0; - } else if (j < 4) { - tx_buf[i] = 0; - tx_buf[i + 1] = 0; - } else { - tx_buf[i] = 0x80; - tx_buf[i + 1] = 0; - } - if (st->mask_high & (1 << j)) { - tx_buf[i + 1] |= - (st->thresh_high[j] >> 8) & 0x0F; - tx_buf[i + 2] = st->thresh_high[j] & 0xFF; - } else if (j < 4) { - tx_buf[i + 1] |= 0x0F; - tx_buf[i + 2] = 0xFF; - } else { - tx_buf[i + 1] |= 0x07; - tx_buf[i + 2] = 0xFF; - } - i += 3; - } - - - ret = i2c_master_send(st->client, tx_buf, len); - if (ret < 0) - goto error_ret; - if (ret != len) { - ret = -EIO; - goto error_ret; - } - - /* - * Now that we hopefully have sensible thresholds in place it is - * time to turn the interrupts on. - * It is unclear from the data sheet if this should be necessary - * (i.e. whether monitor mode setup is atomic) but it appears to - * be in practice. - */ - tx_buf[0] = st->setupbyte; - tx_buf[1] = MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0; - ret = i2c_master_send(st->client, tx_buf, 2); - if (ret < 0) - goto error_ret; - if (ret != 2) { - ret = -EIO; - goto error_ret; - } - ret = 0; - st->monitor_on = true; -error_ret: - - kfree(tx_buf); - - return ret; -} - -/* - * To keep this manageable we always use one of 3 scan modes. - * Scan 0...3, 0-1,2-3 and 1-0,3-2 - */ - -static inline int __max1363_check_event_mask(int thismask, int checkmask) -{ - int ret = 0; - /* Is it unipolar */ - if (thismask < 4) { - if (checkmask & ~0x0F) { - ret = -EBUSY; - goto error_ret; - } - } else if (thismask < 6) { - if (checkmask & ~0x30) { - ret = -EBUSY; - goto error_ret; - } - } else if (checkmask & ~0xC0) - ret = -EBUSY; -error_ret: - return ret; -} - -static int max1363_write_event_config(struct iio_dev *indio_dev, - u64 event_code, - int state) -{ - int ret = 0; - struct max1363_state *st = iio_priv(indio_dev); - u16 unifiedmask; - int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code); - - mutex_lock(&indio_dev->mlock); - unifiedmask = st->mask_low | st->mask_high; - if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) { - - if (state == 0) - st->mask_low &= ~(1 << number); - else { - ret = __max1363_check_event_mask((1 << number), - unifiedmask); - if (ret) - goto error_ret; - st->mask_low |= (1 << number); - } - } else { - if (state == 0) - st->mask_high &= ~(1 << number); - else { - ret = __max1363_check_event_mask((1 << number), - unifiedmask); - if (ret) - goto error_ret; - st->mask_high |= (1 << number); - } - } - - max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low)); -error_ret: - mutex_unlock(&indio_dev->mlock); - - return ret; -} - -/* - * As with scan_elements, only certain sets of these can - * be combined. - */ -static struct attribute *max1363_event_attributes[] = { - &iio_dev_attr_sampling_frequency.dev_attr.attr, - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - NULL, -}; - -static struct attribute_group max1363_event_attribute_group = { - .attrs = max1363_event_attributes, - .name = "events", -}; - -#define MAX1363_EVENT_FUNCS \ - - -static const struct iio_info max1238_info = { - .read_raw = &max1363_read_raw, - .driver_module = THIS_MODULE, - .update_scan_mode = &max1363_update_scan_mode, -}; - -static const struct iio_info max1363_info = { - .read_event_value = &max1363_read_thresh, - .write_event_value = &max1363_write_thresh, - .read_event_config = &max1363_read_event_config, - .write_event_config = &max1363_write_event_config, - .read_raw = &max1363_read_raw, - .update_scan_mode = &max1363_update_scan_mode, - .driver_module = THIS_MODULE, - .event_attrs = &max1363_event_attribute_group, -}; - -/* max1363 and max1368 tested - rest from data sheet */ -static const struct max1363_chip_info max1363_chip_info_tbl[] = { - [max1361] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max1363_mode_list, - .num_modes = ARRAY_SIZE(max1363_mode_list), - .default_mode = s0to3, - .channels = max1361_channels, - .num_channels = ARRAY_SIZE(max1361_channels), - .info = &max1363_info, - }, - [max1362] = { - .bits = 10, - .int_vref_mv = 4096, - .mode_list = max1363_mode_list, - .num_modes = ARRAY_SIZE(max1363_mode_list), - .default_mode = s0to3, - .channels = max1361_channels, - .num_channels = ARRAY_SIZE(max1361_channels), - .info = &max1363_info, - }, - [max1363] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max1363_mode_list, - .num_modes = ARRAY_SIZE(max1363_mode_list), - .default_mode = s0to3, - .channels = max1363_channels, - .num_channels = ARRAY_SIZE(max1363_channels), - .info = &max1363_info, - }, - [max1364] = { - .bits = 12, - .int_vref_mv = 4096, - .mode_list = max1363_mode_list, - .num_modes = ARRAY_SIZE(max1363_mode_list), - .default_mode = s0to3, - .channels = max1363_channels, - .num_channels = ARRAY_SIZE(max1363_channels), - .info = &max1363_info, - }, - [max1036] = { - .bits = 8, - .int_vref_mv = 4096, - .mode_list = max1236_mode_list, - .num_modes = ARRAY_SIZE(max1236_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1036_channels, - .num_channels = ARRAY_SIZE(max1036_channels), - }, - [max1037] = { - .bits = 8, - .int_vref_mv = 2048, - .mode_list = max1236_mode_list, - .num_modes = ARRAY_SIZE(max1236_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1036_channels, - .num_channels = ARRAY_SIZE(max1036_channels), - }, - [max1038] = { - .bits = 8, - .int_vref_mv = 4096, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1038_channels, - .num_channels = ARRAY_SIZE(max1038_channels), - }, - [max1039] = { - .bits = 8, - .int_vref_mv = 2048, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1038_channels, - .num_channels = ARRAY_SIZE(max1038_channels), - }, - [max1136] = { - .bits = 10, - .int_vref_mv = 4096, - .mode_list = max1236_mode_list, - .num_modes = ARRAY_SIZE(max1236_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1136_channels, - .num_channels = ARRAY_SIZE(max1136_channels), - }, - [max1137] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max1236_mode_list, - .num_modes = ARRAY_SIZE(max1236_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1136_channels, - .num_channels = ARRAY_SIZE(max1136_channels), - }, - [max1138] = { - .bits = 10, - .int_vref_mv = 4096, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1138_channels, - .num_channels = ARRAY_SIZE(max1138_channels), - }, - [max1139] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1138_channels, - .num_channels = ARRAY_SIZE(max1138_channels), - }, - [max1236] = { - .bits = 12, - .int_vref_mv = 4096, - .mode_list = max1236_mode_list, - .num_modes = ARRAY_SIZE(max1236_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1236_channels, - .num_channels = ARRAY_SIZE(max1236_channels), - }, - [max1237] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max1236_mode_list, - .num_modes = ARRAY_SIZE(max1236_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1236_channels, - .num_channels = ARRAY_SIZE(max1236_channels), - }, - [max1238] = { - .bits = 12, - .int_vref_mv = 4096, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max1239] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11600] = { - .bits = 8, - .int_vref_mv = 4096, - .mode_list = max11607_mode_list, - .num_modes = ARRAY_SIZE(max11607_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1036_channels, - .num_channels = ARRAY_SIZE(max1036_channels), - }, - [max11601] = { - .bits = 8, - .int_vref_mv = 2048, - .mode_list = max11607_mode_list, - .num_modes = ARRAY_SIZE(max11607_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1036_channels, - .num_channels = ARRAY_SIZE(max1036_channels), - }, - [max11602] = { - .bits = 8, - .int_vref_mv = 4096, - .mode_list = max11608_mode_list, - .num_modes = ARRAY_SIZE(max11608_mode_list), - .default_mode = s0to7, - .info = &max1238_info, - .channels = max11602_channels, - .num_channels = ARRAY_SIZE(max11602_channels), - }, - [max11603] = { - .bits = 8, - .int_vref_mv = 2048, - .mode_list = max11608_mode_list, - .num_modes = ARRAY_SIZE(max11608_mode_list), - .default_mode = s0to7, - .info = &max1238_info, - .channels = max11602_channels, - .num_channels = ARRAY_SIZE(max11602_channels), - }, - [max11604] = { - .bits = 8, - .int_vref_mv = 4098, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11605] = { - .bits = 8, - .int_vref_mv = 2048, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11606] = { - .bits = 10, - .int_vref_mv = 4096, - .mode_list = max11607_mode_list, - .num_modes = ARRAY_SIZE(max11607_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1136_channels, - .num_channels = ARRAY_SIZE(max1136_channels), - }, - [max11607] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max11607_mode_list, - .num_modes = ARRAY_SIZE(max11607_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1136_channels, - .num_channels = ARRAY_SIZE(max1136_channels), - }, - [max11608] = { - .bits = 10, - .int_vref_mv = 4096, - .mode_list = max11608_mode_list, - .num_modes = ARRAY_SIZE(max11608_mode_list), - .default_mode = s0to7, - .info = &max1238_info, - .channels = max11608_channels, - .num_channels = ARRAY_SIZE(max11608_channels), - }, - [max11609] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max11608_mode_list, - .num_modes = ARRAY_SIZE(max11608_mode_list), - .default_mode = s0to7, - .info = &max1238_info, - .channels = max11608_channels, - .num_channels = ARRAY_SIZE(max11608_channels), - }, - [max11610] = { - .bits = 10, - .int_vref_mv = 4098, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11611] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11612] = { - .bits = 12, - .int_vref_mv = 4096, - .mode_list = max11607_mode_list, - .num_modes = ARRAY_SIZE(max11607_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1363_channels, - .num_channels = ARRAY_SIZE(max1363_channels), - }, - [max11613] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max11607_mode_list, - .num_modes = ARRAY_SIZE(max11607_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1363_channels, - .num_channels = ARRAY_SIZE(max1363_channels), - }, - [max11614] = { - .bits = 12, - .int_vref_mv = 4096, - .mode_list = max11608_mode_list, - .num_modes = ARRAY_SIZE(max11608_mode_list), - .default_mode = s0to7, - .info = &max1238_info, - .channels = max11614_channels, - .num_channels = ARRAY_SIZE(max11614_channels), - }, - [max11615] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max11608_mode_list, - .num_modes = ARRAY_SIZE(max11608_mode_list), - .default_mode = s0to7, - .info = &max1238_info, - .channels = max11614_channels, - .num_channels = ARRAY_SIZE(max11614_channels), - }, - [max11616] = { - .bits = 12, - .int_vref_mv = 4098, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11617] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11644] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max11644_mode_list, - .num_modes = ARRAY_SIZE(max11644_mode_list), - .default_mode = s0to1, - .info = &max1238_info, - .channels = max11644_channels, - .num_channels = ARRAY_SIZE(max11644_channels), - }, - [max11645] = { - .bits = 12, - .int_vref_mv = 4096, - .mode_list = max11644_mode_list, - .num_modes = ARRAY_SIZE(max11644_mode_list), - .default_mode = s0to1, - .info = &max1238_info, - .channels = max11644_channels, - .num_channels = ARRAY_SIZE(max11644_channels), - }, - [max11646] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max11644_mode_list, - .num_modes = ARRAY_SIZE(max11644_mode_list), - .default_mode = s0to1, - .info = &max1238_info, - .channels = max11646_channels, - .num_channels = ARRAY_SIZE(max11646_channels), - }, - [max11647] = { - .bits = 10, - .int_vref_mv = 4096, - .mode_list = max11644_mode_list, - .num_modes = ARRAY_SIZE(max11644_mode_list), - .default_mode = s0to1, - .info = &max1238_info, - .channels = max11646_channels, - .num_channels = ARRAY_SIZE(max11646_channels), - }, -}; - - - -static int max1363_initial_setup(struct max1363_state *st) -{ - st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD - | MAX1363_SETUP_POWER_UP_INT_REF - | MAX1363_SETUP_INT_CLOCK - | MAX1363_SETUP_UNIPOLAR - | MAX1363_SETUP_NORESET; - - /* Set scan mode writes the config anyway so wait until then*/ - st->setupbyte = MAX1363_SETUP_BYTE(st->setupbyte); - st->current_mode = &max1363_mode_table[st->chip_info->default_mode]; - st->configbyte = MAX1363_CONFIG_BYTE(st->configbyte); - - return max1363_set_scan_mode(st); -} - -static int __devinit max1363_alloc_scan_masks(struct iio_dev *indio_dev) -{ - struct max1363_state *st = iio_priv(indio_dev); - unsigned long *masks; - int i; - - masks = kzalloc(BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*sizeof(long)* - (st->chip_info->num_modes + 1), GFP_KERNEL); - if (!masks) - return -ENOMEM; - - for (i = 0; i < st->chip_info->num_modes; i++) - bitmap_copy(masks + BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*i, - max1363_mode_table[st->chip_info->mode_list[i]] - .modemask, MAX1363_MAX_CHANNELS); - - indio_dev->available_scan_masks = masks; - - return 0; -} - -static int __devinit max1363_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int ret; - struct max1363_state *st; - struct iio_dev *indio_dev; - struct regulator *reg; - - reg = regulator_get(&client->dev, "vcc"); - if (IS_ERR(reg)) { - ret = PTR_ERR(reg); - goto error_out; - } - - ret = regulator_enable(reg); - if (ret) - goto error_put_reg; - - indio_dev = iio_device_alloc(sizeof(struct max1363_state)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_disable_reg; - } - ret = iio_map_array_register(indio_dev, client->dev.platform_data); - if (ret < 0) - goto error_free_device; - st = iio_priv(indio_dev); - st->reg = reg; - /* this is only used for device removal purposes */ - i2c_set_clientdata(client, indio_dev); - - st->chip_info = &max1363_chip_info_tbl[id->driver_data]; - st->client = client; - - ret = max1363_alloc_scan_masks(indio_dev); - if (ret) - goto error_unregister_map; - - /* Estabilish that the iio_dev is a child of the i2c device */ - indio_dev->dev.parent = &client->dev; - indio_dev->name = id->name; - indio_dev->channels = st->chip_info->channels; - indio_dev->num_channels = st->chip_info->num_channels; - indio_dev->info = st->chip_info->info; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = st->chip_info->channels; - indio_dev->num_channels = st->chip_info->num_channels; - ret = max1363_initial_setup(st); - if (ret < 0) - goto error_free_available_scan_masks; - - ret = max1363_register_ring_funcs_and_init(indio_dev); - if (ret) - goto error_free_available_scan_masks; - - ret = iio_buffer_register(indio_dev, - st->chip_info->channels, - st->chip_info->num_channels); - if (ret) - goto error_cleanup_ring; - - if (client->irq) { - ret = request_threaded_irq(st->client->irq, - NULL, - &max1363_event_handler, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, - "max1363_event", - indio_dev); - - if (ret) - goto error_uninit_ring; - } - - ret = iio_device_register(indio_dev); - if (ret < 0) - goto error_free_irq; - - return 0; -error_free_irq: - free_irq(st->client->irq, indio_dev); -error_uninit_ring: - iio_buffer_unregister(indio_dev); -error_cleanup_ring: - max1363_ring_cleanup(indio_dev); -error_free_available_scan_masks: - kfree(indio_dev->available_scan_masks); -error_unregister_map: - iio_map_array_unregister(indio_dev, client->dev.platform_data); -error_free_device: - iio_device_free(indio_dev); -error_disable_reg: - regulator_disable(reg); -error_put_reg: - regulator_put(reg); -error_out: - return ret; -} - -static int __devexit max1363_remove(struct i2c_client *client) -{ - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct max1363_state *st = iio_priv(indio_dev); - struct regulator *reg = st->reg; - - iio_device_unregister(indio_dev); - if (client->irq) - free_irq(st->client->irq, indio_dev); - iio_buffer_unregister(indio_dev); - max1363_ring_cleanup(indio_dev); - kfree(indio_dev->available_scan_masks); - if (!IS_ERR(reg)) { - regulator_disable(reg); - regulator_put(reg); - } - iio_map_array_unregister(indio_dev, client->dev.platform_data); - iio_device_free(indio_dev); - - return 0; -} - -static const struct i2c_device_id max1363_id[] = { - { "max1361", max1361 }, - { "max1362", max1362 }, - { "max1363", max1363 }, - { "max1364", max1364 }, - { "max1036", max1036 }, - { "max1037", max1037 }, - { "max1038", max1038 }, - { "max1039", max1039 }, - { "max1136", max1136 }, - { "max1137", max1137 }, - { "max1138", max1138 }, - { "max1139", max1139 }, - { "max1236", max1236 }, - { "max1237", max1237 }, - { "max1238", max1238 }, - { "max1239", max1239 }, - { "max11600", max11600 }, - { "max11601", max11601 }, - { "max11602", max11602 }, - { "max11603", max11603 }, - { "max11604", max11604 }, - { "max11605", max11605 }, - { "max11606", max11606 }, - { "max11607", max11607 }, - { "max11608", max11608 }, - { "max11609", max11609 }, - { "max11610", max11610 }, - { "max11611", max11611 }, - { "max11612", max11612 }, - { "max11613", max11613 }, - { "max11614", max11614 }, - { "max11615", max11615 }, - { "max11616", max11616 }, - { "max11617", max11617 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, max1363_id); - -static struct i2c_driver max1363_driver = { - .driver = { - .name = "max1363", - }, - .probe = max1363_probe, - .remove = __devexit_p(max1363_remove), - .id_table = max1363_id, -}; -module_i2c_driver(max1363_driver); - -MODULE_AUTHOR("Jonathan Cameron "); -MODULE_DESCRIPTION("Maxim 1363 ADC"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c deleted file mode 100644 index 41af17b5e74..00000000000 --- a/drivers/staging/iio/adc/max1363_ring.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2008 Jonathan Cameron - * - * 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. - * - * max1363_ring.c - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "max1363.h" - -int max1363_update_scan_mode(struct iio_dev *indio_dev, - const unsigned long *scan_mask) -{ - struct max1363_state *st = iio_priv(indio_dev); - - /* - * Need to figure out the current mode based upon the requested - * scan mask in iio_dev - */ - st->current_mode = max1363_match_mode(scan_mask, st->chip_info); - if (!st->current_mode) - return -EINVAL; - max1363_set_scan_mode(st); - return 0; -} - -static irqreturn_t max1363_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct max1363_state *st = iio_priv(indio_dev); - s64 time_ns; - __u8 *rxbuf; - int b_sent; - size_t d_size; - unsigned long numvals = bitmap_weight(st->current_mode->modemask, - MAX1363_MAX_CHANNELS); - - /* Ensure the timestamp is 8 byte aligned */ - if (st->chip_info->bits != 8) - d_size = numvals*2; - else - d_size = numvals; - if (indio_dev->scan_timestamp) { - d_size += sizeof(s64); - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); - } - /* Monitor mode prevents reading. Whilst not currently implemented - * might as well have this test in here in the meantime as it does - * no harm. - */ - if (numvals == 0) - goto done; - - rxbuf = kmalloc(d_size, GFP_KERNEL); - if (rxbuf == NULL) - goto done; - if (st->chip_info->bits != 8) - b_sent = i2c_master_recv(st->client, rxbuf, numvals*2); - else - b_sent = i2c_master_recv(st->client, rxbuf, numvals); - if (b_sent < 0) - goto done_free; - - time_ns = iio_get_time_ns(); - - if (indio_dev->scan_timestamp) - memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); - iio_push_to_buffers(indio_dev, rxbuf); - -done_free: - kfree(rxbuf); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -static const struct iio_buffer_setup_ops max1363_ring_setup_ops = { - .postenable = &iio_triggered_buffer_postenable, - .preenable = &iio_sw_buffer_preenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) -{ - struct max1363_state *st = iio_priv(indio_dev); - int ret = 0; - - indio_dev->buffer = iio_kfifo_allocate(indio_dev); - if (!indio_dev->buffer) { - ret = -ENOMEM; - goto error_ret; - } - indio_dev->pollfunc = iio_alloc_pollfunc(NULL, - &max1363_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "%s_consumer%d", - st->client->name, - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_deallocate_sw_rb; - } - /* Ring buffer functions - here trigger setup related */ - indio_dev->setup_ops = &max1363_ring_setup_ops; - - /* Flag that polled ring buffering is possible */ - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - - return 0; - -error_deallocate_sw_rb: - iio_kfifo_free(indio_dev->buffer); -error_ret: - return ret; -} - -void max1363_ring_cleanup(struct iio_dev *indio_dev) -{ - /* ensure that the trigger has been detached */ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_kfifo_free(indio_dev->buffer); -} -- cgit v1.2.3 From ec44372865c0ab9dd7d816ab9734463bdb8c20d1 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 6 Oct 2012 14:19:01 +0100 Subject: staging:iio:adc:max1363 drop references to 'ring' given now using a fifo Seems worth clearing the old naming out to avoid any confusion in the future. Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/max1363.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/iio/adc/max1363.c b/drivers/staging/iio/adc/max1363.c index 72715a4d594..dbfdc393806 100644 --- a/drivers/staging/iio/adc/max1363.c +++ b/drivers/staging/iio/adc/max1363.c @@ -788,7 +788,7 @@ static int max1363_monitor_mode_update(struct max1363_state *st, int enabled) const long *modemask; if (!enabled) { - /* transition to ring capture is not currently supported */ + /* transition to buffered capture is not currently supported */ st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP; st->configbyte &= ~MAX1363_SCAN_MASK; st->monitor_on = false; @@ -1482,13 +1482,13 @@ done: return IRQ_HANDLED; } -static const struct iio_buffer_setup_ops max1363_ring_setup_ops = { +static const struct iio_buffer_setup_ops max1363_buffered_setup_ops = { .postenable = &iio_triggered_buffer_postenable, .preenable = &iio_sw_buffer_preenable, .predisable = &iio_triggered_buffer_predisable, }; -static int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) +static int max1363_register_buffered_funcs_and_init(struct iio_dev *indio_dev) { struct max1363_state *st = iio_priv(indio_dev); int ret = 0; @@ -1509,10 +1509,10 @@ static int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev) ret = -ENOMEM; goto error_deallocate_sw_rb; } - /* Ring buffer functions - here trigger setup related */ - indio_dev->setup_ops = &max1363_ring_setup_ops; + /* Buffer functions - here trigger setup related */ + indio_dev->setup_ops = &max1363_buffered_setup_ops; - /* Flag that polled ring buffering is possible */ + /* Flag that polled buffering is possible */ indio_dev->modes |= INDIO_BUFFER_TRIGGERED; return 0; @@ -1523,7 +1523,7 @@ error_ret: return ret; } -static void max1363_ring_cleanup(struct iio_dev *indio_dev) +static void max1363_buffer_cleanup(struct iio_dev *indio_dev) { /* ensure that the trigger has been detached */ iio_dealloc_pollfunc(indio_dev->pollfunc); @@ -1581,7 +1581,7 @@ static int __devinit max1363_probe(struct i2c_client *client, if (ret < 0) goto error_free_available_scan_masks; - ret = max1363_register_ring_funcs_and_init(indio_dev); + ret = max1363_register_buffered_funcs_and_init(indio_dev); if (ret) goto error_free_available_scan_masks; @@ -1589,7 +1589,7 @@ static int __devinit max1363_probe(struct i2c_client *client, st->chip_info->channels, st->chip_info->num_channels); if (ret) - goto error_cleanup_ring; + goto error_cleanup_buffer; if (client->irq) { ret = request_threaded_irq(st->client->irq, @@ -1600,7 +1600,7 @@ static int __devinit max1363_probe(struct i2c_client *client, indio_dev); if (ret) - goto error_uninit_ring; + goto error_uninit_buffer; } ret = iio_device_register(indio_dev); @@ -1610,10 +1610,10 @@ static int __devinit max1363_probe(struct i2c_client *client, return 0; error_free_irq: free_irq(st->client->irq, indio_dev); -error_uninit_ring: +error_uninit_buffer: iio_buffer_unregister(indio_dev); -error_cleanup_ring: - max1363_ring_cleanup(indio_dev); +error_cleanup_buffer: + max1363_buffer_cleanup(indio_dev); error_free_available_scan_masks: kfree(indio_dev->available_scan_masks); error_unregister_map: @@ -1638,7 +1638,7 @@ static int __devexit max1363_remove(struct i2c_client *client) if (client->irq) free_irq(st->client->irq, indio_dev); iio_buffer_unregister(indio_dev); - max1363_ring_cleanup(indio_dev); + max1363_buffer_cleanup(indio_dev); kfree(indio_dev->available_scan_masks); if (!IS_ERR(reg)) { regulator_disable(reg); -- cgit v1.2.3 From 2593b13a622ae99c2c7d6d8c869b59383ab70697 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 6 Oct 2012 14:37:44 +0100 Subject: staging:iio:adc:max1363 make docs match the contents of max1363_chip_info Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/max1363.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/iio/adc/max1363.c b/drivers/staging/iio/adc/max1363.c index dbfdc393806..321775327b2 100644 --- a/drivers/staging/iio/adc/max1363.c +++ b/drivers/staging/iio/adc/max1363.c @@ -127,20 +127,19 @@ enum max1363_modes { /** * struct max1363_chip_info - chip specifc information - * @name: indentification string for chip - * @bits: accuracy of the adc in bits - * @int_vref_mv: the internal reference voltage * @info: iio core function callbacks structure + * @channels: channel specification + * @num_channels: number of channels * @mode_list: array of available scan modes - * @num_modes: the number of scan modes available * @default_mode: the scan mode in which the chip starts up - * @channel: channel specification + * @int_vref_mv: the internal reference voltage * @num_channels: number of channels + * @bits: accuracy of the adc in bits */ struct max1363_chip_info { const struct iio_info *info; - const struct iio_chan_spec *channels; - int num_channels; + const struct iio_chan_spec *channels; + int num_channels; const enum max1363_modes *mode_list; enum max1363_modes default_mode; u16 int_vref_mv; -- cgit v1.2.3 From 0d9fa2ce939279ac7aab34b50b90196f8208af42 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 6 Oct 2012 14:38:11 +0100 Subject: staging:iio:adc:max1363 white space cleanup Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/max1363.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/iio/adc/max1363.c b/drivers/staging/iio/adc/max1363.c index 321775327b2..2f8d433413d 100644 --- a/drivers/staging/iio/adc/max1363.c +++ b/drivers/staging/iio/adc/max1363.c @@ -765,9 +765,9 @@ static int max1363_read_event_config(struct iio_dev *indio_dev, u64 event_code) { struct max1363_state *st = iio_priv(indio_dev); - int val; int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code); + mutex_lock(&indio_dev->mlock); if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) val = (1 << number) & st->mask_low; @@ -969,8 +969,6 @@ static struct attribute_group max1363_event_attribute_group = { .name = "events", }; -#define MAX1363_EVENT_FUNCS \ - static int max1363_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) { @@ -1388,8 +1386,6 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = { }, }; - - static int max1363_initial_setup(struct max1363_state *st) { st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD -- cgit v1.2.3 From b77b8f8c20c83c111050201cad1eed3a71571c35 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 6 Oct 2012 14:39:19 +0100 Subject: staging:iio:adc:max1363 cleanup regulator handling. For historical reasons the regulator handling was a little clunky. This patch brings it inline with a more standard ordering wrt to allocation of the iio_device. Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/max1363.c | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/staging/iio/adc/max1363.c b/drivers/staging/iio/adc/max1363.c index 2f8d433413d..1e84b5b5509 100644 --- a/drivers/staging/iio/adc/max1363.c +++ b/drivers/staging/iio/adc/max1363.c @@ -1531,28 +1531,29 @@ static int __devinit max1363_probe(struct i2c_client *client, int ret; struct max1363_state *st; struct iio_dev *indio_dev; - struct regulator *reg; - - reg = regulator_get(&client->dev, "vcc"); - if (IS_ERR(reg)) { - ret = PTR_ERR(reg); - goto error_out; - } - - ret = regulator_enable(reg); - if (ret) - goto error_put_reg; indio_dev = iio_device_alloc(sizeof(struct max1363_state)); if (indio_dev == NULL) { ret = -ENOMEM; - goto error_disable_reg; + goto error_out; } + ret = iio_map_array_register(indio_dev, client->dev.platform_data); if (ret < 0) goto error_free_device; + st = iio_priv(indio_dev); - st->reg = reg; + + st->reg = regulator_get(&client->dev, "vcc"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto error_unregister_map; + } + + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + /* this is only used for device removal purposes */ i2c_set_clientdata(client, indio_dev); @@ -1561,7 +1562,7 @@ static int __devinit max1363_probe(struct i2c_client *client, ret = max1363_alloc_scan_masks(indio_dev); if (ret) - goto error_unregister_map; + goto error_disable_reg; /* Estabilish that the iio_dev is a child of the i2c device */ indio_dev->dev.parent = &client->dev; @@ -1613,12 +1614,12 @@ error_free_available_scan_masks: kfree(indio_dev->available_scan_masks); error_unregister_map: iio_map_array_unregister(indio_dev, client->dev.platform_data); -error_free_device: - iio_device_free(indio_dev); error_disable_reg: - regulator_disable(reg); + regulator_disable(st->reg); error_put_reg: - regulator_put(reg); + regulator_put(st->reg); +error_free_device: + iio_device_free(indio_dev); error_out: return ret; } @@ -1627,7 +1628,6 @@ static int __devexit max1363_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); struct max1363_state *st = iio_priv(indio_dev); - struct regulator *reg = st->reg; iio_device_unregister(indio_dev); if (client->irq) @@ -1635,9 +1635,9 @@ static int __devexit max1363_remove(struct i2c_client *client) iio_buffer_unregister(indio_dev); max1363_buffer_cleanup(indio_dev); kfree(indio_dev->available_scan_masks); - if (!IS_ERR(reg)) { - regulator_disable(reg); - regulator_put(reg); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); } iio_map_array_unregister(indio_dev, client->dev.platform_data); iio_device_free(indio_dev); -- cgit v1.2.3 From 168c9d95a94077a42e5bf5a4a660b45ccee4fc63 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Sat, 6 Oct 2012 14:42:27 +0100 Subject: iio:adc:max1363 move from staging. Now this driver is using kfifo we can move it out of staging. Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 18 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/max1363.c | 1700 +++++++++++++++++++++++++++++++++++++ drivers/staging/iio/adc/Kconfig | 18 - drivers/staging/iio/adc/Makefile | 2 - drivers/staging/iio/adc/max1363.c | 1700 ------------------------------------- 6 files changed, 1719 insertions(+), 1720 deletions(-) create mode 100644 drivers/iio/adc/max1363.c delete mode 100644 drivers/staging/iio/adc/max1363.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 706386ba02e..ef5200a6850 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -73,4 +73,22 @@ config LP8788_ADC help Say yes here to build support for TI LP8788 ADC. +config MAX1363 + tristate "Maxim max1363 ADC driver" + depends on I2C + select IIO_TRIGGER + select MAX1363_RING_BUFFER + select IIO_BUFFER + select IIO_KFIFO_BUF + help + Say yes here to build support for many Maxim i2c analog to digital + converters (ADC). (max1361, max1362, max1363, max1364, max1036, + max1037, max1038, max1039, max1136, max1136, max1137, max1138, + max1139, max1236, max1237, max11238, max1239, max11600, max11601, + max11602, max11603, max11604, max11605, max11606, max11607, + max11608, max11609, max11610, max11611, max11612, max11613, + max11614, max11615, max11616, max11617, max11644, max11645, + max11646, max11647) Provides direct access via sysfs and buffered + data via the iio dev interface. + endmenu diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 034eacb8f7c..54ac7bbcd01 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_AD7791) += ad7791.o obj-$(CONFIG_AD7887) += ad7887.o obj-$(CONFIG_AT91_ADC) += at91_adc.o obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o +obj-$(CONFIG_MAX1363) += max1363.o diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c new file mode 100644 index 00000000000..1e84b5b5509 --- /dev/null +++ b/drivers/iio/adc/max1363.c @@ -0,0 +1,1700 @@ + /* + * iio/adc/max1363.c + * Copyright (C) 2008-2010 Jonathan Cameron + * + * based on linux/drivers/i2c/chips/max123x + * Copyright (C) 2002-2004 Stefan Eletzhofer + * + * based on linux/drivers/acron/char/pcf8583.c + * Copyright (C) 2000 Russell King + * + * 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. + * + * max1363.c + * + * Partial support for max1363 and similar chips. + * + * Not currently implemented. + * + * - Control of internal reference. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MAX1363_SETUP_BYTE(a) ((a) | 0x80) + +/* There is a fair bit more defined here than currently + * used, but the intention is to support everything these + * chips do in the long run */ + +/* see data sheets */ +/* max1363 and max1236, max1237, max1238, max1239 */ +#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD 0x00 +#define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF 0x20 +#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT 0x40 +#define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT 0x60 +#define MAX1363_SETUP_POWER_UP_INT_REF 0x10 +#define MAX1363_SETUP_POWER_DOWN_INT_REF 0x00 + +/* think about includeing max11600 etc - more settings */ +#define MAX1363_SETUP_EXT_CLOCK 0x08 +#define MAX1363_SETUP_INT_CLOCK 0x00 +#define MAX1363_SETUP_UNIPOLAR 0x00 +#define MAX1363_SETUP_BIPOLAR 0x04 +#define MAX1363_SETUP_RESET 0x00 +#define MAX1363_SETUP_NORESET 0x02 +/* max1363 only - though don't care on others. + * For now monitor modes are not implemented as the relevant + * line is not connected on my test board. + * The definitions are here as I intend to add this soon. + */ +#define MAX1363_SETUP_MONITOR_SETUP 0x01 + +/* Specific to the max1363 */ +#define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4)) +#define MAX1363_MON_INT_ENABLE 0x01 + +/* defined for readability reasons */ +/* All chips */ +#define MAX1363_CONFIG_BYTE(a) ((a)) + +#define MAX1363_CONFIG_SE 0x01 +#define MAX1363_CONFIG_DE 0x00 +#define MAX1363_CONFIG_SCAN_TO_CS 0x00 +#define MAX1363_CONFIG_SCAN_SINGLE_8 0x20 +#define MAX1363_CONFIG_SCAN_MONITOR_MODE 0x40 +#define MAX1363_CONFIG_SCAN_SINGLE_1 0x60 +/* max123{6-9} only */ +#define MAX1236_SCAN_MID_TO_CHANNEL 0x40 + +/* max1363 only - merely part of channel selects or don't care for others*/ +#define MAX1363_CONFIG_EN_MON_MODE_READ 0x18 + +#define MAX1363_CHANNEL_SEL(a) ((a) << 1) + +/* max1363 strictly 0x06 - but doesn't matter */ +#define MAX1363_CHANNEL_SEL_MASK 0x1E +#define MAX1363_SCAN_MASK 0x60 +#define MAX1363_SE_DE_MASK 0x01 + +#define MAX1363_MAX_CHANNELS 25 +/** + * struct max1363_mode - scan mode information + * @conf: The corresponding value of the configuration register + * @modemask: Bit mask corresponding to channels enabled in this mode + */ +struct max1363_mode { + int8_t conf; + DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS); +}; + +/* This must be maintained along side the max1363_mode_table in max1363_core */ +enum max1363_modes { + /* Single read of a single channel */ + _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, + /* Differential single read */ + d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, + d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, + /* Scan to channel and mid to channel where overlapping */ + s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6, + s6to7, s0to7, s6to8, s0to8, s6to9, + s0to9, s6to10, s0to10, s6to11, s0to11, + /* Differential scan to channel and mid to channel where overlapping */ + d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9, + d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2, + d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8, + d7m6to11m10, d1m0to11m10, +}; + +/** + * struct max1363_chip_info - chip specifc information + * @info: iio core function callbacks structure + * @channels: channel specification + * @num_channels: number of channels + * @mode_list: array of available scan modes + * @default_mode: the scan mode in which the chip starts up + * @int_vref_mv: the internal reference voltage + * @num_channels: number of channels + * @bits: accuracy of the adc in bits + */ +struct max1363_chip_info { + const struct iio_info *info; + const struct iio_chan_spec *channels; + int num_channels; + const enum max1363_modes *mode_list; + enum max1363_modes default_mode; + u16 int_vref_mv; + u8 num_modes; + u8 bits; +}; + +/** + * struct max1363_state - driver instance specific data + * @client: i2c_client + * @setupbyte: cache of current device setup byte + * @configbyte: cache of current device config byte + * @chip_info: chip model specific constants, available modes etc + * @current_mode: the scan mode of this chip + * @requestedmask: a valid requested set of channels + * @reg: supply regulator + * @monitor_on: whether monitor mode is enabled + * @monitor_speed: parameter corresponding to device monitor speed setting + * @mask_high: bitmask for enabled high thresholds + * @mask_low: bitmask for enabled low thresholds + * @thresh_high: high threshold values + * @thresh_low: low threshold values + */ +struct max1363_state { + struct i2c_client *client; + u8 setupbyte; + u8 configbyte; + const struct max1363_chip_info *chip_info; + const struct max1363_mode *current_mode; + u32 requestedmask; + struct regulator *reg; + + /* Using monitor modes and buffer at the same time is + currently not supported */ + bool monitor_on; + unsigned int monitor_speed:3; + u8 mask_high; + u8 mask_low; + /* 4x unipolar first then the fours bipolar ones */ + s16 thresh_high[8]; + s16 thresh_low[8]; +}; + +#define MAX1363_MODE_SINGLE(_num, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ + | MAX1363_CONFIG_SCAN_SINGLE_1 \ + | MAX1363_CONFIG_SE, \ + .modemask[0] = _mask, \ + } + +#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ + | MAX1363_CONFIG_SCAN_TO_CS \ + | MAX1363_CONFIG_SE, \ + .modemask[0] = _mask, \ + } + +/* note not available for max1363 hence naming */ +#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ + | MAX1236_SCAN_MID_TO_CHANNEL \ + | MAX1363_CONFIG_SE, \ + .modemask[0] = _mask \ +} + +#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_nump) \ + | MAX1363_CONFIG_SCAN_SINGLE_1 \ + | MAX1363_CONFIG_DE, \ + .modemask[0] = _mask \ + } + +/* Can't think how to automate naming so specify for now */ +#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ + | MAX1363_CONFIG_SCAN_TO_CS \ + | MAX1363_CONFIG_DE, \ + .modemask[0] = _mask \ + } + +/* note only available for max1363 hence naming */ +#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) { \ + .conf = MAX1363_CHANNEL_SEL(_num) \ + | MAX1236_SCAN_MID_TO_CHANNEL \ + | MAX1363_CONFIG_SE, \ + .modemask[0] = _mask \ +} + +static const struct max1363_mode max1363_mode_table[] = { + /* All of the single channel options first */ + MAX1363_MODE_SINGLE(0, 1 << 0), + MAX1363_MODE_SINGLE(1, 1 << 1), + MAX1363_MODE_SINGLE(2, 1 << 2), + MAX1363_MODE_SINGLE(3, 1 << 3), + MAX1363_MODE_SINGLE(4, 1 << 4), + MAX1363_MODE_SINGLE(5, 1 << 5), + MAX1363_MODE_SINGLE(6, 1 << 6), + MAX1363_MODE_SINGLE(7, 1 << 7), + MAX1363_MODE_SINGLE(8, 1 << 8), + MAX1363_MODE_SINGLE(9, 1 << 9), + MAX1363_MODE_SINGLE(10, 1 << 10), + MAX1363_MODE_SINGLE(11, 1 << 11), + + MAX1363_MODE_DIFF_SINGLE(0, 1, 1 << 12), + MAX1363_MODE_DIFF_SINGLE(2, 3, 1 << 13), + MAX1363_MODE_DIFF_SINGLE(4, 5, 1 << 14), + MAX1363_MODE_DIFF_SINGLE(6, 7, 1 << 15), + MAX1363_MODE_DIFF_SINGLE(8, 9, 1 << 16), + MAX1363_MODE_DIFF_SINGLE(10, 11, 1 << 17), + MAX1363_MODE_DIFF_SINGLE(1, 0, 1 << 18), + MAX1363_MODE_DIFF_SINGLE(3, 2, 1 << 19), + MAX1363_MODE_DIFF_SINGLE(5, 4, 1 << 20), + MAX1363_MODE_DIFF_SINGLE(7, 6, 1 << 21), + MAX1363_MODE_DIFF_SINGLE(9, 8, 1 << 22), + MAX1363_MODE_DIFF_SINGLE(11, 10, 1 << 23), + + /* The multichannel scans next */ + MAX1363_MODE_SCAN_TO_CHANNEL(1, 0x003), + MAX1363_MODE_SCAN_TO_CHANNEL(2, 0x007), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(2, 3, 0x00C), + MAX1363_MODE_SCAN_TO_CHANNEL(3, 0x00F), + MAX1363_MODE_SCAN_TO_CHANNEL(4, 0x01F), + MAX1363_MODE_SCAN_TO_CHANNEL(5, 0x03F), + MAX1363_MODE_SCAN_TO_CHANNEL(6, 0x07F), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 7, 0x0C0), + MAX1363_MODE_SCAN_TO_CHANNEL(7, 0x0FF), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 8, 0x1C0), + MAX1363_MODE_SCAN_TO_CHANNEL(8, 0x1FF), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 9, 0x3C0), + MAX1363_MODE_SCAN_TO_CHANNEL(9, 0x3FF), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 10, 0x7C0), + MAX1363_MODE_SCAN_TO_CHANNEL(10, 0x7FF), + MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 11, 0xFC0), + MAX1363_MODE_SCAN_TO_CHANNEL(11, 0xFFF), + + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(2, 2, 0x003000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(4, 3, 0x007000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(6, 4, 0x00F000), + MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(8, 2, 0x018000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(8, 5, 0x01F000), + MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(10, 3, 0x038000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(10, 6, 0x3F000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(3, 2, 0x0C0000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(5, 3, 0x1C0000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(7, 4, 0x3C0000), + MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(9, 2, 0x600000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(9, 5, 0x7C0000), + MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(11, 3, 0xE00000), + MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(11, 6, 0xFC0000), +}; + +static const struct max1363_mode +*max1363_match_mode(const unsigned long *mask, +const struct max1363_chip_info *ci) +{ + int i; + if (mask) + for (i = 0; i < ci->num_modes; i++) + if (bitmap_subset(mask, + max1363_mode_table[ci->mode_list[i]]. + modemask, + MAX1363_MAX_CHANNELS)) + return &max1363_mode_table[ci->mode_list[i]]; + return NULL; +} + +static int max1363_write_basic_config(struct i2c_client *client, + unsigned char d1, + unsigned char d2) +{ + u8 tx_buf[2] = {d1, d2}; + + return i2c_master_send(client, tx_buf, 2); +} + +static int max1363_set_scan_mode(struct max1363_state *st) +{ + st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK + | MAX1363_SCAN_MASK + | MAX1363_SE_DE_MASK); + st->configbyte |= st->current_mode->conf; + + return max1363_write_basic_config(st->client, + st->setupbyte, + st->configbyte); +} + +static int max1363_read_single_chan(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + long m) +{ + int ret = 0; + s32 data; + char rxbuf[2]; + struct max1363_state *st = iio_priv(indio_dev); + struct i2c_client *client = st->client; + + mutex_lock(&indio_dev->mlock); + /* + * If monitor mode is enabled, the method for reading a single + * channel will have to be rather different and has not yet + * been implemented. + * + * Also, cannot read directly if buffered capture enabled. + */ + if (st->monitor_on || iio_buffer_enabled(indio_dev)) { + ret = -EBUSY; + goto error_ret; + } + + /* Check to see if current scan mode is correct */ + if (st->current_mode != &max1363_mode_table[chan->address]) { + /* Update scan mode if needed */ + st->current_mode = &max1363_mode_table[chan->address]; + ret = max1363_set_scan_mode(st); + if (ret < 0) + goto error_ret; + } + if (st->chip_info->bits != 8) { + /* Get reading */ + data = i2c_master_recv(client, rxbuf, 2); + if (data < 0) { + ret = data; + goto error_ret; + } + data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8; + } else { + /* Get reading */ + data = i2c_master_recv(client, rxbuf, 1); + if (data < 0) { + ret = data; + goto error_ret; + } + data = rxbuf[0]; + } + *val = data; +error_ret: + mutex_unlock(&indio_dev->mlock); + return ret; + +} + +static int max1363_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct max1363_state *st = iio_priv(indio_dev); + int ret; + switch (m) { + case IIO_CHAN_INFO_RAW: + ret = max1363_read_single_chan(indio_dev, chan, val, m); + if (ret < 0) + return ret; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + if ((1 << (st->chip_info->bits + 1)) > + st->chip_info->int_vref_mv) { + *val = 0; + *val2 = 500000; + return IIO_VAL_INT_PLUS_MICRO; + } else { + *val = (st->chip_info->int_vref_mv) + >> st->chip_info->bits; + return IIO_VAL_INT; + } + default: + return -EINVAL; + } + return 0; +} + +/* Applies to max1363 */ +static const enum max1363_modes max1363_mode_list[] = { + _s0, _s1, _s2, _s3, + s0to1, s0to2, s0to3, + d0m1, d2m3, d1m0, d3m2, + d0m1to2m3, d1m0to3m2, +}; + +#define MAX1363_EV_M \ + (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) \ + | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)) +#define MAX1363_INFO_MASK (IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT) +#define MAX1363_CHAN_U(num, addr, si, bits, evmask) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = num, \ + .address = addr, \ + .info_mask = MAX1363_INFO_MASK, \ + .datasheet_name = "AIN"#num, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = bits, \ + .storagebits = (bits > 8) ? 16 : 8, \ + .endianness = IIO_BE, \ + }, \ + .scan_index = si, \ + .event_mask = evmask, \ + } + +/* bipolar channel */ +#define MAX1363_CHAN_B(num, num2, addr, si, bits, evmask) \ + { \ + .type = IIO_VOLTAGE, \ + .differential = 1, \ + .indexed = 1, \ + .channel = num, \ + .channel2 = num2, \ + .address = addr, \ + .info_mask = MAX1363_INFO_MASK, \ + .datasheet_name = "AIN"#num"-AIN"#num2, \ + .scan_type = { \ + .sign = 's', \ + .realbits = bits, \ + .storagebits = (bits > 8) ? 16 : 8, \ + .endianness = IIO_BE, \ + }, \ + .scan_index = si, \ + .event_mask = evmask, \ + } + +#define MAX1363_4X_CHANS(bits, em) { \ + MAX1363_CHAN_U(0, _s0, 0, bits, em), \ + MAX1363_CHAN_U(1, _s1, 1, bits, em), \ + MAX1363_CHAN_U(2, _s2, 2, bits, em), \ + MAX1363_CHAN_U(3, _s3, 3, bits, em), \ + MAX1363_CHAN_B(0, 1, d0m1, 4, bits, em), \ + MAX1363_CHAN_B(2, 3, d2m3, 5, bits, em), \ + MAX1363_CHAN_B(1, 0, d1m0, 6, bits, em), \ + MAX1363_CHAN_B(3, 2, d3m2, 7, bits, em), \ + IIO_CHAN_SOFT_TIMESTAMP(8) \ + } + +static const struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8, 0); +static const struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10, 0); +static const struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12, 0); +static const struct iio_chan_spec max1361_channels[] = + MAX1363_4X_CHANS(10, MAX1363_EV_M); +static const struct iio_chan_spec max1363_channels[] = + MAX1363_4X_CHANS(12, MAX1363_EV_M); + +/* Applies to max1236, max1237 */ +static const enum max1363_modes max1236_mode_list[] = { + _s0, _s1, _s2, _s3, + s0to1, s0to2, s0to3, + d0m1, d2m3, d1m0, d3m2, + d0m1to2m3, d1m0to3m2, + s2to3, +}; + +/* Applies to max1238, max1239 */ +static const enum max1363_modes max1238_mode_list[] = { + _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, + s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, + s0to7, s0to8, s0to9, s0to10, s0to11, + d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, + d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, + d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11, + d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10, + s6to7, s6to8, s6to9, s6to10, s6to11, + d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10, +}; + +#define MAX1363_12X_CHANS(bits) { \ + MAX1363_CHAN_U(0, _s0, 0, bits, 0), \ + MAX1363_CHAN_U(1, _s1, 1, bits, 0), \ + MAX1363_CHAN_U(2, _s2, 2, bits, 0), \ + MAX1363_CHAN_U(3, _s3, 3, bits, 0), \ + MAX1363_CHAN_U(4, _s4, 4, bits, 0), \ + MAX1363_CHAN_U(5, _s5, 5, bits, 0), \ + MAX1363_CHAN_U(6, _s6, 6, bits, 0), \ + MAX1363_CHAN_U(7, _s7, 7, bits, 0), \ + MAX1363_CHAN_U(8, _s8, 8, bits, 0), \ + MAX1363_CHAN_U(9, _s9, 9, bits, 0), \ + MAX1363_CHAN_U(10, _s10, 10, bits, 0), \ + MAX1363_CHAN_U(11, _s11, 11, bits, 0), \ + MAX1363_CHAN_B(0, 1, d0m1, 12, bits, 0), \ + MAX1363_CHAN_B(2, 3, d2m3, 13, bits, 0), \ + MAX1363_CHAN_B(4, 5, d4m5, 14, bits, 0), \ + MAX1363_CHAN_B(6, 7, d6m7, 15, bits, 0), \ + MAX1363_CHAN_B(8, 9, d8m9, 16, bits, 0), \ + MAX1363_CHAN_B(10, 11, d10m11, 17, bits, 0), \ + MAX1363_CHAN_B(1, 0, d1m0, 18, bits, 0), \ + MAX1363_CHAN_B(3, 2, d3m2, 19, bits, 0), \ + MAX1363_CHAN_B(5, 4, d5m4, 20, bits, 0), \ + MAX1363_CHAN_B(7, 6, d7m6, 21, bits, 0), \ + MAX1363_CHAN_B(9, 8, d9m8, 22, bits, 0), \ + MAX1363_CHAN_B(11, 10, d11m10, 23, bits, 0), \ + IIO_CHAN_SOFT_TIMESTAMP(24) \ + } +static const struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8); +static const struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10); +static const struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12); + +static const enum max1363_modes max11607_mode_list[] = { + _s0, _s1, _s2, _s3, + s0to1, s0to2, s0to3, + s2to3, + d0m1, d2m3, d1m0, d3m2, + d0m1to2m3, d1m0to3m2, +}; + +static const enum max1363_modes max11608_mode_list[] = { + _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, + s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s0to7, + s6to7, + d0m1, d2m3, d4m5, d6m7, + d1m0, d3m2, d5m4, d7m6, + d0m1to2m3, d0m1to4m5, d0m1to6m7, + d1m0to3m2, d1m0to5m4, d1m0to7m6, +}; + +#define MAX1363_8X_CHANS(bits) { \ + MAX1363_CHAN_U(0, _s0, 0, bits, 0), \ + MAX1363_CHAN_U(1, _s1, 1, bits, 0), \ + MAX1363_CHAN_U(2, _s2, 2, bits, 0), \ + MAX1363_CHAN_U(3, _s3, 3, bits, 0), \ + MAX1363_CHAN_U(4, _s4, 4, bits, 0), \ + MAX1363_CHAN_U(5, _s5, 5, bits, 0), \ + MAX1363_CHAN_U(6, _s6, 6, bits, 0), \ + MAX1363_CHAN_U(7, _s7, 7, bits, 0), \ + MAX1363_CHAN_B(0, 1, d0m1, 8, bits, 0), \ + MAX1363_CHAN_B(2, 3, d2m3, 9, bits, 0), \ + MAX1363_CHAN_B(4, 5, d4m5, 10, bits, 0), \ + MAX1363_CHAN_B(6, 7, d6m7, 11, bits, 0), \ + MAX1363_CHAN_B(1, 0, d1m0, 12, bits, 0), \ + MAX1363_CHAN_B(3, 2, d3m2, 13, bits, 0), \ + MAX1363_CHAN_B(5, 4, d5m4, 14, bits, 0), \ + MAX1363_CHAN_B(7, 6, d7m6, 15, bits, 0), \ + IIO_CHAN_SOFT_TIMESTAMP(16) \ +} +static const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8); +static const struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10); +static const struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12); + +static const enum max1363_modes max11644_mode_list[] = { + _s0, _s1, s0to1, d0m1, d1m0, +}; + +#define MAX1363_2X_CHANS(bits) { \ + MAX1363_CHAN_U(0, _s0, 0, bits, 0), \ + MAX1363_CHAN_U(1, _s1, 1, bits, 0), \ + MAX1363_CHAN_B(0, 1, d0m1, 2, bits, 0), \ + MAX1363_CHAN_B(1, 0, d1m0, 3, bits, 0), \ + IIO_CHAN_SOFT_TIMESTAMP(4) \ + } + +static const struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10); +static const struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12); + +enum { max1361, + max1362, + max1363, + max1364, + max1036, + max1037, + max1038, + max1039, + max1136, + max1137, + max1138, + max1139, + max1236, + max1237, + max1238, + max1239, + max11600, + max11601, + max11602, + max11603, + max11604, + max11605, + max11606, + max11607, + max11608, + max11609, + max11610, + max11611, + max11612, + max11613, + max11614, + max11615, + max11616, + max11617, + max11644, + max11645, + max11646, + max11647 +}; + +static const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600, + 8300, 4200, 2000, 1000 }; + +static ssize_t max1363_monitor_show_freq(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct max1363_state *st = iio_priv(dev_to_iio_dev(dev)); + return sprintf(buf, "%d\n", max1363_monitor_speeds[st->monitor_speed]); +} + +static ssize_t max1363_monitor_store_freq(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct max1363_state *st = iio_priv(indio_dev); + int i, ret; + unsigned long val; + bool found = false; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + return -EINVAL; + for (i = 0; i < ARRAY_SIZE(max1363_monitor_speeds); i++) + if (val == max1363_monitor_speeds[i]) { + found = true; + break; + } + if (!found) + return -EINVAL; + + mutex_lock(&indio_dev->mlock); + st->monitor_speed = i; + mutex_unlock(&indio_dev->mlock); + + return 0; +} + +static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, + max1363_monitor_show_freq, + max1363_monitor_store_freq); + +static IIO_CONST_ATTR(sampling_frequency_available, + "133000 665000 33300 16600 8300 4200 2000 1000"); + +static int max1363_read_thresh(struct iio_dev *indio_dev, + u64 event_code, + int *val) +{ + struct max1363_state *st = iio_priv(indio_dev); + if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) + *val = st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)]; + else + *val = st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)]; + return 0; +} + +static int max1363_write_thresh(struct iio_dev *indio_dev, + u64 event_code, + int val) +{ + struct max1363_state *st = iio_priv(indio_dev); + /* make it handle signed correctly as well */ + switch (st->chip_info->bits) { + case 10: + if (val > 0x3FF) + return -EINVAL; + break; + case 12: + if (val > 0xFFF) + return -EINVAL; + break; + } + + switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { + case IIO_EV_DIR_FALLING: + st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val; + break; + case IIO_EV_DIR_RISING: + st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val; + break; + } + + return 0; +} + +static const u64 max1363_event_codes[] = { + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3, + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), +}; + +static irqreturn_t max1363_event_handler(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct max1363_state *st = iio_priv(indio_dev); + s64 timestamp = iio_get_time_ns(); + unsigned long mask, loc; + u8 rx; + u8 tx[2] = { st->setupbyte, + MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 }; + + i2c_master_recv(st->client, &rx, 1); + mask = rx; + for_each_set_bit(loc, &mask, 8) + iio_push_event(indio_dev, max1363_event_codes[loc], timestamp); + i2c_master_send(st->client, tx, 2); + + return IRQ_HANDLED; +} + +static int max1363_read_event_config(struct iio_dev *indio_dev, + u64 event_code) +{ + struct max1363_state *st = iio_priv(indio_dev); + int val; + int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code); + + mutex_lock(&indio_dev->mlock); + if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) + val = (1 << number) & st->mask_low; + else + val = (1 << number) & st->mask_high; + mutex_unlock(&indio_dev->mlock); + + return val; +} + +static int max1363_monitor_mode_update(struct max1363_state *st, int enabled) +{ + u8 *tx_buf; + int ret, i = 3, j; + unsigned long numelements; + int len; + const long *modemask; + + if (!enabled) { + /* transition to buffered capture is not currently supported */ + st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP; + st->configbyte &= ~MAX1363_SCAN_MASK; + st->monitor_on = false; + return max1363_write_basic_config(st->client, + st->setupbyte, + st->configbyte); + } + + /* Ensure we are in the relevant mode */ + st->setupbyte |= MAX1363_SETUP_MONITOR_SETUP; + st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK + | MAX1363_SCAN_MASK + | MAX1363_SE_DE_MASK); + st->configbyte |= MAX1363_CONFIG_SCAN_MONITOR_MODE; + if ((st->mask_low | st->mask_high) & 0x0F) { + st->configbyte |= max1363_mode_table[s0to3].conf; + modemask = max1363_mode_table[s0to3].modemask; + } else if ((st->mask_low | st->mask_high) & 0x30) { + st->configbyte |= max1363_mode_table[d0m1to2m3].conf; + modemask = max1363_mode_table[d0m1to2m3].modemask; + } else { + st->configbyte |= max1363_mode_table[d1m0to3m2].conf; + modemask = max1363_mode_table[d1m0to3m2].modemask; + } + numelements = bitmap_weight(modemask, MAX1363_MAX_CHANNELS); + len = 3 * numelements + 3; + tx_buf = kmalloc(len, GFP_KERNEL); + if (!tx_buf) { + ret = -ENOMEM; + goto error_ret; + } + tx_buf[0] = st->configbyte; + tx_buf[1] = st->setupbyte; + tx_buf[2] = (st->monitor_speed << 1); + + /* + * So we need to do yet another bit of nefarious scan mode + * setup to match what we need. + */ + for (j = 0; j < 8; j++) + if (test_bit(j, modemask)) { + /* Establish the mode is in the scan */ + if (st->mask_low & (1 << j)) { + tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF; + tx_buf[i + 1] = (st->thresh_low[j] << 4) & 0xF0; + } else if (j < 4) { + tx_buf[i] = 0; + tx_buf[i + 1] = 0; + } else { + tx_buf[i] = 0x80; + tx_buf[i + 1] = 0; + } + if (st->mask_high & (1 << j)) { + tx_buf[i + 1] |= + (st->thresh_high[j] >> 8) & 0x0F; + tx_buf[i + 2] = st->thresh_high[j] & 0xFF; + } else if (j < 4) { + tx_buf[i + 1] |= 0x0F; + tx_buf[i + 2] = 0xFF; + } else { + tx_buf[i + 1] |= 0x07; + tx_buf[i + 2] = 0xFF; + } + i += 3; + } + + + ret = i2c_master_send(st->client, tx_buf, len); + if (ret < 0) + goto error_ret; + if (ret != len) { + ret = -EIO; + goto error_ret; + } + + /* + * Now that we hopefully have sensible thresholds in place it is + * time to turn the interrupts on. + * It is unclear from the data sheet if this should be necessary + * (i.e. whether monitor mode setup is atomic) but it appears to + * be in practice. + */ + tx_buf[0] = st->setupbyte; + tx_buf[1] = MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0; + ret = i2c_master_send(st->client, tx_buf, 2); + if (ret < 0) + goto error_ret; + if (ret != 2) { + ret = -EIO; + goto error_ret; + } + ret = 0; + st->monitor_on = true; +error_ret: + + kfree(tx_buf); + + return ret; +} + +/* + * To keep this manageable we always use one of 3 scan modes. + * Scan 0...3, 0-1,2-3 and 1-0,3-2 + */ + +static inline int __max1363_check_event_mask(int thismask, int checkmask) +{ + int ret = 0; + /* Is it unipolar */ + if (thismask < 4) { + if (checkmask & ~0x0F) { + ret = -EBUSY; + goto error_ret; + } + } else if (thismask < 6) { + if (checkmask & ~0x30) { + ret = -EBUSY; + goto error_ret; + } + } else if (checkmask & ~0xC0) + ret = -EBUSY; +error_ret: + return ret; +} + +static int max1363_write_event_config(struct iio_dev *indio_dev, + u64 event_code, + int state) +{ + int ret = 0; + struct max1363_state *st = iio_priv(indio_dev); + u16 unifiedmask; + int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code); + + mutex_lock(&indio_dev->mlock); + unifiedmask = st->mask_low | st->mask_high; + if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) { + + if (state == 0) + st->mask_low &= ~(1 << number); + else { + ret = __max1363_check_event_mask((1 << number), + unifiedmask); + if (ret) + goto error_ret; + st->mask_low |= (1 << number); + } + } else { + if (state == 0) + st->mask_high &= ~(1 << number); + else { + ret = __max1363_check_event_mask((1 << number), + unifiedmask); + if (ret) + goto error_ret; + st->mask_high |= (1 << number); + } + } + + max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low)); +error_ret: + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +/* + * As with scan_elements, only certain sets of these can + * be combined. + */ +static struct attribute *max1363_event_attributes[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + NULL, +}; + +static struct attribute_group max1363_event_attribute_group = { + .attrs = max1363_event_attributes, + .name = "events", +}; + +static int max1363_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct max1363_state *st = iio_priv(indio_dev); + + /* + * Need to figure out the current mode based upon the requested + * scan mask in iio_dev + */ + st->current_mode = max1363_match_mode(scan_mask, st->chip_info); + if (!st->current_mode) + return -EINVAL; + max1363_set_scan_mode(st); + return 0; +} + +static const struct iio_info max1238_info = { + .read_raw = &max1363_read_raw, + .driver_module = THIS_MODULE, + .update_scan_mode = &max1363_update_scan_mode, +}; + +static const struct iio_info max1363_info = { + .read_event_value = &max1363_read_thresh, + .write_event_value = &max1363_write_thresh, + .read_event_config = &max1363_read_event_config, + .write_event_config = &max1363_write_event_config, + .read_raw = &max1363_read_raw, + .update_scan_mode = &max1363_update_scan_mode, + .driver_module = THIS_MODULE, + .event_attrs = &max1363_event_attribute_group, +}; + +/* max1363 and max1368 tested - rest from data sheet */ +static const struct max1363_chip_info max1363_chip_info_tbl[] = { + [max1361] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max1363_mode_list, + .num_modes = ARRAY_SIZE(max1363_mode_list), + .default_mode = s0to3, + .channels = max1361_channels, + .num_channels = ARRAY_SIZE(max1361_channels), + .info = &max1363_info, + }, + [max1362] = { + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max1363_mode_list, + .num_modes = ARRAY_SIZE(max1363_mode_list), + .default_mode = s0to3, + .channels = max1361_channels, + .num_channels = ARRAY_SIZE(max1361_channels), + .info = &max1363_info, + }, + [max1363] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max1363_mode_list, + .num_modes = ARRAY_SIZE(max1363_mode_list), + .default_mode = s0to3, + .channels = max1363_channels, + .num_channels = ARRAY_SIZE(max1363_channels), + .info = &max1363_info, + }, + [max1364] = { + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max1363_mode_list, + .num_modes = ARRAY_SIZE(max1363_mode_list), + .default_mode = s0to3, + .channels = max1363_channels, + .num_channels = ARRAY_SIZE(max1363_channels), + .info = &max1363_info, + }, + [max1036] = { + .bits = 8, + .int_vref_mv = 4096, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1036_channels, + .num_channels = ARRAY_SIZE(max1036_channels), + }, + [max1037] = { + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1036_channels, + .num_channels = ARRAY_SIZE(max1036_channels), + }, + [max1038] = { + .bits = 8, + .int_vref_mv = 4096, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1038_channels, + .num_channels = ARRAY_SIZE(max1038_channels), + }, + [max1039] = { + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1038_channels, + .num_channels = ARRAY_SIZE(max1038_channels), + }, + [max1136] = { + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1136_channels, + .num_channels = ARRAY_SIZE(max1136_channels), + }, + [max1137] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1136_channels, + .num_channels = ARRAY_SIZE(max1136_channels), + }, + [max1138] = { + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1138_channels, + .num_channels = ARRAY_SIZE(max1138_channels), + }, + [max1139] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1138_channels, + .num_channels = ARRAY_SIZE(max1138_channels), + }, + [max1236] = { + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1236_channels, + .num_channels = ARRAY_SIZE(max1236_channels), + }, + [max1237] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max1236_mode_list, + .num_modes = ARRAY_SIZE(max1236_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1236_channels, + .num_channels = ARRAY_SIZE(max1236_channels), + }, + [max1238] = { + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max1239] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11600] = { + .bits = 8, + .int_vref_mv = 4096, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1036_channels, + .num_channels = ARRAY_SIZE(max1036_channels), + }, + [max11601] = { + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1036_channels, + .num_channels = ARRAY_SIZE(max1036_channels), + }, + [max11602] = { + .bits = 8, + .int_vref_mv = 4096, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .info = &max1238_info, + .channels = max11602_channels, + .num_channels = ARRAY_SIZE(max11602_channels), + }, + [max11603] = { + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .info = &max1238_info, + .channels = max11602_channels, + .num_channels = ARRAY_SIZE(max11602_channels), + }, + [max11604] = { + .bits = 8, + .int_vref_mv = 4098, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11605] = { + .bits = 8, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11606] = { + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1136_channels, + .num_channels = ARRAY_SIZE(max1136_channels), + }, + [max11607] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1136_channels, + .num_channels = ARRAY_SIZE(max1136_channels), + }, + [max11608] = { + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .info = &max1238_info, + .channels = max11608_channels, + .num_channels = ARRAY_SIZE(max11608_channels), + }, + [max11609] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .info = &max1238_info, + .channels = max11608_channels, + .num_channels = ARRAY_SIZE(max11608_channels), + }, + [max11610] = { + .bits = 10, + .int_vref_mv = 4098, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11611] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11612] = { + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1363_channels, + .num_channels = ARRAY_SIZE(max1363_channels), + }, + [max11613] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max11607_mode_list, + .num_modes = ARRAY_SIZE(max11607_mode_list), + .default_mode = s0to3, + .info = &max1238_info, + .channels = max1363_channels, + .num_channels = ARRAY_SIZE(max1363_channels), + }, + [max11614] = { + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .info = &max1238_info, + .channels = max11614_channels, + .num_channels = ARRAY_SIZE(max11614_channels), + }, + [max11615] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max11608_mode_list, + .num_modes = ARRAY_SIZE(max11608_mode_list), + .default_mode = s0to7, + .info = &max1238_info, + .channels = max11614_channels, + .num_channels = ARRAY_SIZE(max11614_channels), + }, + [max11616] = { + .bits = 12, + .int_vref_mv = 4098, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11617] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max1238_mode_list, + .num_modes = ARRAY_SIZE(max1238_mode_list), + .default_mode = s0to11, + .info = &max1238_info, + .channels = max1238_channels, + .num_channels = ARRAY_SIZE(max1238_channels), + }, + [max11644] = { + .bits = 12, + .int_vref_mv = 2048, + .mode_list = max11644_mode_list, + .num_modes = ARRAY_SIZE(max11644_mode_list), + .default_mode = s0to1, + .info = &max1238_info, + .channels = max11644_channels, + .num_channels = ARRAY_SIZE(max11644_channels), + }, + [max11645] = { + .bits = 12, + .int_vref_mv = 4096, + .mode_list = max11644_mode_list, + .num_modes = ARRAY_SIZE(max11644_mode_list), + .default_mode = s0to1, + .info = &max1238_info, + .channels = max11644_channels, + .num_channels = ARRAY_SIZE(max11644_channels), + }, + [max11646] = { + .bits = 10, + .int_vref_mv = 2048, + .mode_list = max11644_mode_list, + .num_modes = ARRAY_SIZE(max11644_mode_list), + .default_mode = s0to1, + .info = &max1238_info, + .channels = max11646_channels, + .num_channels = ARRAY_SIZE(max11646_channels), + }, + [max11647] = { + .bits = 10, + .int_vref_mv = 4096, + .mode_list = max11644_mode_list, + .num_modes = ARRAY_SIZE(max11644_mode_list), + .default_mode = s0to1, + .info = &max1238_info, + .channels = max11646_channels, + .num_channels = ARRAY_SIZE(max11646_channels), + }, +}; + +static int max1363_initial_setup(struct max1363_state *st) +{ + st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD + | MAX1363_SETUP_POWER_UP_INT_REF + | MAX1363_SETUP_INT_CLOCK + | MAX1363_SETUP_UNIPOLAR + | MAX1363_SETUP_NORESET; + + /* Set scan mode writes the config anyway so wait until then*/ + st->setupbyte = MAX1363_SETUP_BYTE(st->setupbyte); + st->current_mode = &max1363_mode_table[st->chip_info->default_mode]; + st->configbyte = MAX1363_CONFIG_BYTE(st->configbyte); + + return max1363_set_scan_mode(st); +} + +static int __devinit max1363_alloc_scan_masks(struct iio_dev *indio_dev) +{ + struct max1363_state *st = iio_priv(indio_dev); + unsigned long *masks; + int i; + + masks = kzalloc(BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*sizeof(long)* + (st->chip_info->num_modes + 1), GFP_KERNEL); + if (!masks) + return -ENOMEM; + + for (i = 0; i < st->chip_info->num_modes; i++) + bitmap_copy(masks + BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*i, + max1363_mode_table[st->chip_info->mode_list[i]] + .modemask, MAX1363_MAX_CHANNELS); + + indio_dev->available_scan_masks = masks; + + return 0; +} + + +static irqreturn_t max1363_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct max1363_state *st = iio_priv(indio_dev); + s64 time_ns; + __u8 *rxbuf; + int b_sent; + size_t d_size; + unsigned long numvals = bitmap_weight(st->current_mode->modemask, + MAX1363_MAX_CHANNELS); + + /* Ensure the timestamp is 8 byte aligned */ + if (st->chip_info->bits != 8) + d_size = numvals*2; + else + d_size = numvals; + if (indio_dev->scan_timestamp) { + d_size += sizeof(s64); + if (d_size % sizeof(s64)) + d_size += sizeof(s64) - (d_size % sizeof(s64)); + } + /* Monitor mode prevents reading. Whilst not currently implemented + * might as well have this test in here in the meantime as it does + * no harm. + */ + if (numvals == 0) + goto done; + + rxbuf = kmalloc(d_size, GFP_KERNEL); + if (rxbuf == NULL) + goto done; + if (st->chip_info->bits != 8) + b_sent = i2c_master_recv(st->client, rxbuf, numvals*2); + else + b_sent = i2c_master_recv(st->client, rxbuf, numvals); + if (b_sent < 0) + goto done_free; + + time_ns = iio_get_time_ns(); + + if (indio_dev->scan_timestamp) + memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); + iio_push_to_buffers(indio_dev, rxbuf); + +done_free: + kfree(rxbuf); +done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static const struct iio_buffer_setup_ops max1363_buffered_setup_ops = { + .postenable = &iio_triggered_buffer_postenable, + .preenable = &iio_sw_buffer_preenable, + .predisable = &iio_triggered_buffer_predisable, +}; + +static int max1363_register_buffered_funcs_and_init(struct iio_dev *indio_dev) +{ + struct max1363_state *st = iio_priv(indio_dev); + int ret = 0; + + indio_dev->buffer = iio_kfifo_allocate(indio_dev); + if (!indio_dev->buffer) { + ret = -ENOMEM; + goto error_ret; + } + indio_dev->pollfunc = iio_alloc_pollfunc(NULL, + &max1363_trigger_handler, + IRQF_ONESHOT, + indio_dev, + "%s_consumer%d", + st->client->name, + indio_dev->id); + if (indio_dev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_deallocate_sw_rb; + } + /* Buffer functions - here trigger setup related */ + indio_dev->setup_ops = &max1363_buffered_setup_ops; + + /* Flag that polled buffering is possible */ + indio_dev->modes |= INDIO_BUFFER_TRIGGERED; + + return 0; + +error_deallocate_sw_rb: + iio_kfifo_free(indio_dev->buffer); +error_ret: + return ret; +} + +static void max1363_buffer_cleanup(struct iio_dev *indio_dev) +{ + /* ensure that the trigger has been detached */ + iio_dealloc_pollfunc(indio_dev->pollfunc); + iio_kfifo_free(indio_dev->buffer); +} + +static int __devinit max1363_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + struct max1363_state *st; + struct iio_dev *indio_dev; + + indio_dev = iio_device_alloc(sizeof(struct max1363_state)); + if (indio_dev == NULL) { + ret = -ENOMEM; + goto error_out; + } + + ret = iio_map_array_register(indio_dev, client->dev.platform_data); + if (ret < 0) + goto error_free_device; + + st = iio_priv(indio_dev); + + st->reg = regulator_get(&client->dev, "vcc"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto error_unregister_map; + } + + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + /* this is only used for device removal purposes */ + i2c_set_clientdata(client, indio_dev); + + st->chip_info = &max1363_chip_info_tbl[id->driver_data]; + st->client = client; + + ret = max1363_alloc_scan_masks(indio_dev); + if (ret) + goto error_disable_reg; + + /* Estabilish that the iio_dev is a child of the i2c device */ + indio_dev->dev.parent = &client->dev; + indio_dev->name = id->name; + indio_dev->channels = st->chip_info->channels; + indio_dev->num_channels = st->chip_info->num_channels; + indio_dev->info = st->chip_info->info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->chip_info->channels; + indio_dev->num_channels = st->chip_info->num_channels; + ret = max1363_initial_setup(st); + if (ret < 0) + goto error_free_available_scan_masks; + + ret = max1363_register_buffered_funcs_and_init(indio_dev); + if (ret) + goto error_free_available_scan_masks; + + ret = iio_buffer_register(indio_dev, + st->chip_info->channels, + st->chip_info->num_channels); + if (ret) + goto error_cleanup_buffer; + + if (client->irq) { + ret = request_threaded_irq(st->client->irq, + NULL, + &max1363_event_handler, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "max1363_event", + indio_dev); + + if (ret) + goto error_uninit_buffer; + } + + ret = iio_device_register(indio_dev); + if (ret < 0) + goto error_free_irq; + + return 0; +error_free_irq: + free_irq(st->client->irq, indio_dev); +error_uninit_buffer: + iio_buffer_unregister(indio_dev); +error_cleanup_buffer: + max1363_buffer_cleanup(indio_dev); +error_free_available_scan_masks: + kfree(indio_dev->available_scan_masks); +error_unregister_map: + iio_map_array_unregister(indio_dev, client->dev.platform_data); +error_disable_reg: + regulator_disable(st->reg); +error_put_reg: + regulator_put(st->reg); +error_free_device: + iio_device_free(indio_dev); +error_out: + return ret; +} + +static int __devexit max1363_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct max1363_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + if (client->irq) + free_irq(st->client->irq, indio_dev); + iio_buffer_unregister(indio_dev); + max1363_buffer_cleanup(indio_dev); + kfree(indio_dev->available_scan_masks); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + iio_map_array_unregister(indio_dev, client->dev.platform_data); + iio_device_free(indio_dev); + + return 0; +} + +static const struct i2c_device_id max1363_id[] = { + { "max1361", max1361 }, + { "max1362", max1362 }, + { "max1363", max1363 }, + { "max1364", max1364 }, + { "max1036", max1036 }, + { "max1037", max1037 }, + { "max1038", max1038 }, + { "max1039", max1039 }, + { "max1136", max1136 }, + { "max1137", max1137 }, + { "max1138", max1138 }, + { "max1139", max1139 }, + { "max1236", max1236 }, + { "max1237", max1237 }, + { "max1238", max1238 }, + { "max1239", max1239 }, + { "max11600", max11600 }, + { "max11601", max11601 }, + { "max11602", max11602 }, + { "max11603", max11603 }, + { "max11604", max11604 }, + { "max11605", max11605 }, + { "max11606", max11606 }, + { "max11607", max11607 }, + { "max11608", max11608 }, + { "max11609", max11609 }, + { "max11610", max11610 }, + { "max11611", max11611 }, + { "max11612", max11612 }, + { "max11613", max11613 }, + { "max11614", max11614 }, + { "max11615", max11615 }, + { "max11616", max11616 }, + { "max11617", max11617 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, max1363_id); + +static struct i2c_driver max1363_driver = { + .driver = { + .name = "max1363", + }, + .probe = max1363_probe, + .remove = __devexit_p(max1363_remove), + .id_table = max1363_id, +}; +module_i2c_driver(max1363_driver); + +MODULE_AUTHOR("Jonathan Cameron "); +MODULE_DESCRIPTION("Maxim 1363 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 4d348048b39..0177f1e0230 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -130,24 +130,6 @@ config AD7280 To compile this driver as a module, choose M here: the module will be called ad7280a -config MAX1363 - tristate "Maxim max1363 ADC driver" - depends on I2C - select IIO_TRIGGER - select MAX1363_RING_BUFFER - select IIO_BUFFER - select IIO_KFIFO_BUF - help - Say yes here to build support for many Maxim i2c analog to digital - converters (ADC). (max1361, max1362, max1363, max1364, max1036, - max1037, max1038, max1039, max1136, max1136, max1137, max1138, - max1139, max1236, max1237, max11238, max1239, max11600, max11601, - max11602, max11603, max11604, max11605, max11606, max11607, - max11608, max11609, max11610, max11611, max11612, max11613, - max11614, max11615, max11616, max11617, max11644, max11645, - max11646, max11647) Provides direct access via sysfs and buffered - data via the iio dev interface. - config LPC32XX_ADC tristate "NXP LPC32XX ADC" depends on ARCH_LPC32XX diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 33979e62871..12b4bd32437 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -2,8 +2,6 @@ # Makefile for industrial I/O ADC drivers # -obj-$(CONFIG_MAX1363) += max1363.o - ad7606-y := ad7606_core.o ad7606-$(CONFIG_IIO_BUFFER) += ad7606_ring.o ad7606-$(CONFIG_AD7606_IFACE_PARALLEL) += ad7606_par.o diff --git a/drivers/staging/iio/adc/max1363.c b/drivers/staging/iio/adc/max1363.c deleted file mode 100644 index 1e84b5b5509..00000000000 --- a/drivers/staging/iio/adc/max1363.c +++ /dev/null @@ -1,1700 +0,0 @@ - /* - * iio/adc/max1363.c - * Copyright (C) 2008-2010 Jonathan Cameron - * - * based on linux/drivers/i2c/chips/max123x - * Copyright (C) 2002-2004 Stefan Eletzhofer - * - * based on linux/drivers/acron/char/pcf8583.c - * Copyright (C) 2000 Russell King - * - * 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. - * - * max1363.c - * - * Partial support for max1363 and similar chips. - * - * Not currently implemented. - * - * - Control of internal reference. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define MAX1363_SETUP_BYTE(a) ((a) | 0x80) - -/* There is a fair bit more defined here than currently - * used, but the intention is to support everything these - * chips do in the long run */ - -/* see data sheets */ -/* max1363 and max1236, max1237, max1238, max1239 */ -#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD 0x00 -#define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF 0x20 -#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT 0x40 -#define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT 0x60 -#define MAX1363_SETUP_POWER_UP_INT_REF 0x10 -#define MAX1363_SETUP_POWER_DOWN_INT_REF 0x00 - -/* think about includeing max11600 etc - more settings */ -#define MAX1363_SETUP_EXT_CLOCK 0x08 -#define MAX1363_SETUP_INT_CLOCK 0x00 -#define MAX1363_SETUP_UNIPOLAR 0x00 -#define MAX1363_SETUP_BIPOLAR 0x04 -#define MAX1363_SETUP_RESET 0x00 -#define MAX1363_SETUP_NORESET 0x02 -/* max1363 only - though don't care on others. - * For now monitor modes are not implemented as the relevant - * line is not connected on my test board. - * The definitions are here as I intend to add this soon. - */ -#define MAX1363_SETUP_MONITOR_SETUP 0x01 - -/* Specific to the max1363 */ -#define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4)) -#define MAX1363_MON_INT_ENABLE 0x01 - -/* defined for readability reasons */ -/* All chips */ -#define MAX1363_CONFIG_BYTE(a) ((a)) - -#define MAX1363_CONFIG_SE 0x01 -#define MAX1363_CONFIG_DE 0x00 -#define MAX1363_CONFIG_SCAN_TO_CS 0x00 -#define MAX1363_CONFIG_SCAN_SINGLE_8 0x20 -#define MAX1363_CONFIG_SCAN_MONITOR_MODE 0x40 -#define MAX1363_CONFIG_SCAN_SINGLE_1 0x60 -/* max123{6-9} only */ -#define MAX1236_SCAN_MID_TO_CHANNEL 0x40 - -/* max1363 only - merely part of channel selects or don't care for others*/ -#define MAX1363_CONFIG_EN_MON_MODE_READ 0x18 - -#define MAX1363_CHANNEL_SEL(a) ((a) << 1) - -/* max1363 strictly 0x06 - but doesn't matter */ -#define MAX1363_CHANNEL_SEL_MASK 0x1E -#define MAX1363_SCAN_MASK 0x60 -#define MAX1363_SE_DE_MASK 0x01 - -#define MAX1363_MAX_CHANNELS 25 -/** - * struct max1363_mode - scan mode information - * @conf: The corresponding value of the configuration register - * @modemask: Bit mask corresponding to channels enabled in this mode - */ -struct max1363_mode { - int8_t conf; - DECLARE_BITMAP(modemask, MAX1363_MAX_CHANNELS); -}; - -/* This must be maintained along side the max1363_mode_table in max1363_core */ -enum max1363_modes { - /* Single read of a single channel */ - _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, - /* Differential single read */ - d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, - d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, - /* Scan to channel and mid to channel where overlapping */ - s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6, - s6to7, s0to7, s6to8, s0to8, s6to9, - s0to9, s6to10, s0to10, s6to11, s0to11, - /* Differential scan to channel and mid to channel where overlapping */ - d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9, - d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2, - d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8, - d7m6to11m10, d1m0to11m10, -}; - -/** - * struct max1363_chip_info - chip specifc information - * @info: iio core function callbacks structure - * @channels: channel specification - * @num_channels: number of channels - * @mode_list: array of available scan modes - * @default_mode: the scan mode in which the chip starts up - * @int_vref_mv: the internal reference voltage - * @num_channels: number of channels - * @bits: accuracy of the adc in bits - */ -struct max1363_chip_info { - const struct iio_info *info; - const struct iio_chan_spec *channels; - int num_channels; - const enum max1363_modes *mode_list; - enum max1363_modes default_mode; - u16 int_vref_mv; - u8 num_modes; - u8 bits; -}; - -/** - * struct max1363_state - driver instance specific data - * @client: i2c_client - * @setupbyte: cache of current device setup byte - * @configbyte: cache of current device config byte - * @chip_info: chip model specific constants, available modes etc - * @current_mode: the scan mode of this chip - * @requestedmask: a valid requested set of channels - * @reg: supply regulator - * @monitor_on: whether monitor mode is enabled - * @monitor_speed: parameter corresponding to device monitor speed setting - * @mask_high: bitmask for enabled high thresholds - * @mask_low: bitmask for enabled low thresholds - * @thresh_high: high threshold values - * @thresh_low: low threshold values - */ -struct max1363_state { - struct i2c_client *client; - u8 setupbyte; - u8 configbyte; - const struct max1363_chip_info *chip_info; - const struct max1363_mode *current_mode; - u32 requestedmask; - struct regulator *reg; - - /* Using monitor modes and buffer at the same time is - currently not supported */ - bool monitor_on; - unsigned int monitor_speed:3; - u8 mask_high; - u8 mask_low; - /* 4x unipolar first then the fours bipolar ones */ - s16 thresh_high[8]; - s16 thresh_low[8]; -}; - -#define MAX1363_MODE_SINGLE(_num, _mask) { \ - .conf = MAX1363_CHANNEL_SEL(_num) \ - | MAX1363_CONFIG_SCAN_SINGLE_1 \ - | MAX1363_CONFIG_SE, \ - .modemask[0] = _mask, \ - } - -#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) { \ - .conf = MAX1363_CHANNEL_SEL(_num) \ - | MAX1363_CONFIG_SCAN_TO_CS \ - | MAX1363_CONFIG_SE, \ - .modemask[0] = _mask, \ - } - -/* note not available for max1363 hence naming */ -#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) { \ - .conf = MAX1363_CHANNEL_SEL(_num) \ - | MAX1236_SCAN_MID_TO_CHANNEL \ - | MAX1363_CONFIG_SE, \ - .modemask[0] = _mask \ -} - -#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) { \ - .conf = MAX1363_CHANNEL_SEL(_nump) \ - | MAX1363_CONFIG_SCAN_SINGLE_1 \ - | MAX1363_CONFIG_DE, \ - .modemask[0] = _mask \ - } - -/* Can't think how to automate naming so specify for now */ -#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) { \ - .conf = MAX1363_CHANNEL_SEL(_num) \ - | MAX1363_CONFIG_SCAN_TO_CS \ - | MAX1363_CONFIG_DE, \ - .modemask[0] = _mask \ - } - -/* note only available for max1363 hence naming */ -#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) { \ - .conf = MAX1363_CHANNEL_SEL(_num) \ - | MAX1236_SCAN_MID_TO_CHANNEL \ - | MAX1363_CONFIG_SE, \ - .modemask[0] = _mask \ -} - -static const struct max1363_mode max1363_mode_table[] = { - /* All of the single channel options first */ - MAX1363_MODE_SINGLE(0, 1 << 0), - MAX1363_MODE_SINGLE(1, 1 << 1), - MAX1363_MODE_SINGLE(2, 1 << 2), - MAX1363_MODE_SINGLE(3, 1 << 3), - MAX1363_MODE_SINGLE(4, 1 << 4), - MAX1363_MODE_SINGLE(5, 1 << 5), - MAX1363_MODE_SINGLE(6, 1 << 6), - MAX1363_MODE_SINGLE(7, 1 << 7), - MAX1363_MODE_SINGLE(8, 1 << 8), - MAX1363_MODE_SINGLE(9, 1 << 9), - MAX1363_MODE_SINGLE(10, 1 << 10), - MAX1363_MODE_SINGLE(11, 1 << 11), - - MAX1363_MODE_DIFF_SINGLE(0, 1, 1 << 12), - MAX1363_MODE_DIFF_SINGLE(2, 3, 1 << 13), - MAX1363_MODE_DIFF_SINGLE(4, 5, 1 << 14), - MAX1363_MODE_DIFF_SINGLE(6, 7, 1 << 15), - MAX1363_MODE_DIFF_SINGLE(8, 9, 1 << 16), - MAX1363_MODE_DIFF_SINGLE(10, 11, 1 << 17), - MAX1363_MODE_DIFF_SINGLE(1, 0, 1 << 18), - MAX1363_MODE_DIFF_SINGLE(3, 2, 1 << 19), - MAX1363_MODE_DIFF_SINGLE(5, 4, 1 << 20), - MAX1363_MODE_DIFF_SINGLE(7, 6, 1 << 21), - MAX1363_MODE_DIFF_SINGLE(9, 8, 1 << 22), - MAX1363_MODE_DIFF_SINGLE(11, 10, 1 << 23), - - /* The multichannel scans next */ - MAX1363_MODE_SCAN_TO_CHANNEL(1, 0x003), - MAX1363_MODE_SCAN_TO_CHANNEL(2, 0x007), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(2, 3, 0x00C), - MAX1363_MODE_SCAN_TO_CHANNEL(3, 0x00F), - MAX1363_MODE_SCAN_TO_CHANNEL(4, 0x01F), - MAX1363_MODE_SCAN_TO_CHANNEL(5, 0x03F), - MAX1363_MODE_SCAN_TO_CHANNEL(6, 0x07F), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 7, 0x0C0), - MAX1363_MODE_SCAN_TO_CHANNEL(7, 0x0FF), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 8, 0x1C0), - MAX1363_MODE_SCAN_TO_CHANNEL(8, 0x1FF), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 9, 0x3C0), - MAX1363_MODE_SCAN_TO_CHANNEL(9, 0x3FF), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 10, 0x7C0), - MAX1363_MODE_SCAN_TO_CHANNEL(10, 0x7FF), - MAX1236_MODE_SCAN_MID_TO_CHANNEL(6, 11, 0xFC0), - MAX1363_MODE_SCAN_TO_CHANNEL(11, 0xFFF), - - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(2, 2, 0x003000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(4, 3, 0x007000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(6, 4, 0x00F000), - MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(8, 2, 0x018000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(8, 5, 0x01F000), - MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(10, 3, 0x038000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(10, 6, 0x3F000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(3, 2, 0x0C0000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(5, 3, 0x1C0000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(7, 4, 0x3C0000), - MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(9, 2, 0x600000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(9, 5, 0x7C0000), - MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(11, 3, 0xE00000), - MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(11, 6, 0xFC0000), -}; - -static const struct max1363_mode -*max1363_match_mode(const unsigned long *mask, -const struct max1363_chip_info *ci) -{ - int i; - if (mask) - for (i = 0; i < ci->num_modes; i++) - if (bitmap_subset(mask, - max1363_mode_table[ci->mode_list[i]]. - modemask, - MAX1363_MAX_CHANNELS)) - return &max1363_mode_table[ci->mode_list[i]]; - return NULL; -} - -static int max1363_write_basic_config(struct i2c_client *client, - unsigned char d1, - unsigned char d2) -{ - u8 tx_buf[2] = {d1, d2}; - - return i2c_master_send(client, tx_buf, 2); -} - -static int max1363_set_scan_mode(struct max1363_state *st) -{ - st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK - | MAX1363_SCAN_MASK - | MAX1363_SE_DE_MASK); - st->configbyte |= st->current_mode->conf; - - return max1363_write_basic_config(st->client, - st->setupbyte, - st->configbyte); -} - -static int max1363_read_single_chan(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - long m) -{ - int ret = 0; - s32 data; - char rxbuf[2]; - struct max1363_state *st = iio_priv(indio_dev); - struct i2c_client *client = st->client; - - mutex_lock(&indio_dev->mlock); - /* - * If monitor mode is enabled, the method for reading a single - * channel will have to be rather different and has not yet - * been implemented. - * - * Also, cannot read directly if buffered capture enabled. - */ - if (st->monitor_on || iio_buffer_enabled(indio_dev)) { - ret = -EBUSY; - goto error_ret; - } - - /* Check to see if current scan mode is correct */ - if (st->current_mode != &max1363_mode_table[chan->address]) { - /* Update scan mode if needed */ - st->current_mode = &max1363_mode_table[chan->address]; - ret = max1363_set_scan_mode(st); - if (ret < 0) - goto error_ret; - } - if (st->chip_info->bits != 8) { - /* Get reading */ - data = i2c_master_recv(client, rxbuf, 2); - if (data < 0) { - ret = data; - goto error_ret; - } - data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8; - } else { - /* Get reading */ - data = i2c_master_recv(client, rxbuf, 1); - if (data < 0) { - ret = data; - goto error_ret; - } - data = rxbuf[0]; - } - *val = data; -error_ret: - mutex_unlock(&indio_dev->mlock); - return ret; - -} - -static int max1363_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long m) -{ - struct max1363_state *st = iio_priv(indio_dev); - int ret; - switch (m) { - case IIO_CHAN_INFO_RAW: - ret = max1363_read_single_chan(indio_dev, chan, val, m); - if (ret < 0) - return ret; - return IIO_VAL_INT; - case IIO_CHAN_INFO_SCALE: - if ((1 << (st->chip_info->bits + 1)) > - st->chip_info->int_vref_mv) { - *val = 0; - *val2 = 500000; - return IIO_VAL_INT_PLUS_MICRO; - } else { - *val = (st->chip_info->int_vref_mv) - >> st->chip_info->bits; - return IIO_VAL_INT; - } - default: - return -EINVAL; - } - return 0; -} - -/* Applies to max1363 */ -static const enum max1363_modes max1363_mode_list[] = { - _s0, _s1, _s2, _s3, - s0to1, s0to2, s0to3, - d0m1, d2m3, d1m0, d3m2, - d0m1to2m3, d1m0to3m2, -}; - -#define MAX1363_EV_M \ - (IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) \ - | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)) -#define MAX1363_INFO_MASK (IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT) -#define MAX1363_CHAN_U(num, addr, si, bits, evmask) \ - { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = num, \ - .address = addr, \ - .info_mask = MAX1363_INFO_MASK, \ - .datasheet_name = "AIN"#num, \ - .scan_type = { \ - .sign = 'u', \ - .realbits = bits, \ - .storagebits = (bits > 8) ? 16 : 8, \ - .endianness = IIO_BE, \ - }, \ - .scan_index = si, \ - .event_mask = evmask, \ - } - -/* bipolar channel */ -#define MAX1363_CHAN_B(num, num2, addr, si, bits, evmask) \ - { \ - .type = IIO_VOLTAGE, \ - .differential = 1, \ - .indexed = 1, \ - .channel = num, \ - .channel2 = num2, \ - .address = addr, \ - .info_mask = MAX1363_INFO_MASK, \ - .datasheet_name = "AIN"#num"-AIN"#num2, \ - .scan_type = { \ - .sign = 's', \ - .realbits = bits, \ - .storagebits = (bits > 8) ? 16 : 8, \ - .endianness = IIO_BE, \ - }, \ - .scan_index = si, \ - .event_mask = evmask, \ - } - -#define MAX1363_4X_CHANS(bits, em) { \ - MAX1363_CHAN_U(0, _s0, 0, bits, em), \ - MAX1363_CHAN_U(1, _s1, 1, bits, em), \ - MAX1363_CHAN_U(2, _s2, 2, bits, em), \ - MAX1363_CHAN_U(3, _s3, 3, bits, em), \ - MAX1363_CHAN_B(0, 1, d0m1, 4, bits, em), \ - MAX1363_CHAN_B(2, 3, d2m3, 5, bits, em), \ - MAX1363_CHAN_B(1, 0, d1m0, 6, bits, em), \ - MAX1363_CHAN_B(3, 2, d3m2, 7, bits, em), \ - IIO_CHAN_SOFT_TIMESTAMP(8) \ - } - -static const struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8, 0); -static const struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10, 0); -static const struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12, 0); -static const struct iio_chan_spec max1361_channels[] = - MAX1363_4X_CHANS(10, MAX1363_EV_M); -static const struct iio_chan_spec max1363_channels[] = - MAX1363_4X_CHANS(12, MAX1363_EV_M); - -/* Applies to max1236, max1237 */ -static const enum max1363_modes max1236_mode_list[] = { - _s0, _s1, _s2, _s3, - s0to1, s0to2, s0to3, - d0m1, d2m3, d1m0, d3m2, - d0m1to2m3, d1m0to3m2, - s2to3, -}; - -/* Applies to max1238, max1239 */ -static const enum max1363_modes max1238_mode_list[] = { - _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11, - s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, - s0to7, s0to8, s0to9, s0to10, s0to11, - d0m1, d2m3, d4m5, d6m7, d8m9, d10m11, - d1m0, d3m2, d5m4, d7m6, d9m8, d11m10, - d0m1to2m3, d0m1to4m5, d0m1to6m7, d0m1to8m9, d0m1to10m11, - d1m0to3m2, d1m0to5m4, d1m0to7m6, d1m0to9m8, d1m0to11m10, - s6to7, s6to8, s6to9, s6to10, s6to11, - d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10, -}; - -#define MAX1363_12X_CHANS(bits) { \ - MAX1363_CHAN_U(0, _s0, 0, bits, 0), \ - MAX1363_CHAN_U(1, _s1, 1, bits, 0), \ - MAX1363_CHAN_U(2, _s2, 2, bits, 0), \ - MAX1363_CHAN_U(3, _s3, 3, bits, 0), \ - MAX1363_CHAN_U(4, _s4, 4, bits, 0), \ - MAX1363_CHAN_U(5, _s5, 5, bits, 0), \ - MAX1363_CHAN_U(6, _s6, 6, bits, 0), \ - MAX1363_CHAN_U(7, _s7, 7, bits, 0), \ - MAX1363_CHAN_U(8, _s8, 8, bits, 0), \ - MAX1363_CHAN_U(9, _s9, 9, bits, 0), \ - MAX1363_CHAN_U(10, _s10, 10, bits, 0), \ - MAX1363_CHAN_U(11, _s11, 11, bits, 0), \ - MAX1363_CHAN_B(0, 1, d0m1, 12, bits, 0), \ - MAX1363_CHAN_B(2, 3, d2m3, 13, bits, 0), \ - MAX1363_CHAN_B(4, 5, d4m5, 14, bits, 0), \ - MAX1363_CHAN_B(6, 7, d6m7, 15, bits, 0), \ - MAX1363_CHAN_B(8, 9, d8m9, 16, bits, 0), \ - MAX1363_CHAN_B(10, 11, d10m11, 17, bits, 0), \ - MAX1363_CHAN_B(1, 0, d1m0, 18, bits, 0), \ - MAX1363_CHAN_B(3, 2, d3m2, 19, bits, 0), \ - MAX1363_CHAN_B(5, 4, d5m4, 20, bits, 0), \ - MAX1363_CHAN_B(7, 6, d7m6, 21, bits, 0), \ - MAX1363_CHAN_B(9, 8, d9m8, 22, bits, 0), \ - MAX1363_CHAN_B(11, 10, d11m10, 23, bits, 0), \ - IIO_CHAN_SOFT_TIMESTAMP(24) \ - } -static const struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8); -static const struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10); -static const struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12); - -static const enum max1363_modes max11607_mode_list[] = { - _s0, _s1, _s2, _s3, - s0to1, s0to2, s0to3, - s2to3, - d0m1, d2m3, d1m0, d3m2, - d0m1to2m3, d1m0to3m2, -}; - -static const enum max1363_modes max11608_mode_list[] = { - _s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, - s0to1, s0to2, s0to3, s0to4, s0to5, s0to6, s0to7, - s6to7, - d0m1, d2m3, d4m5, d6m7, - d1m0, d3m2, d5m4, d7m6, - d0m1to2m3, d0m1to4m5, d0m1to6m7, - d1m0to3m2, d1m0to5m4, d1m0to7m6, -}; - -#define MAX1363_8X_CHANS(bits) { \ - MAX1363_CHAN_U(0, _s0, 0, bits, 0), \ - MAX1363_CHAN_U(1, _s1, 1, bits, 0), \ - MAX1363_CHAN_U(2, _s2, 2, bits, 0), \ - MAX1363_CHAN_U(3, _s3, 3, bits, 0), \ - MAX1363_CHAN_U(4, _s4, 4, bits, 0), \ - MAX1363_CHAN_U(5, _s5, 5, bits, 0), \ - MAX1363_CHAN_U(6, _s6, 6, bits, 0), \ - MAX1363_CHAN_U(7, _s7, 7, bits, 0), \ - MAX1363_CHAN_B(0, 1, d0m1, 8, bits, 0), \ - MAX1363_CHAN_B(2, 3, d2m3, 9, bits, 0), \ - MAX1363_CHAN_B(4, 5, d4m5, 10, bits, 0), \ - MAX1363_CHAN_B(6, 7, d6m7, 11, bits, 0), \ - MAX1363_CHAN_B(1, 0, d1m0, 12, bits, 0), \ - MAX1363_CHAN_B(3, 2, d3m2, 13, bits, 0), \ - MAX1363_CHAN_B(5, 4, d5m4, 14, bits, 0), \ - MAX1363_CHAN_B(7, 6, d7m6, 15, bits, 0), \ - IIO_CHAN_SOFT_TIMESTAMP(16) \ -} -static const struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8); -static const struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10); -static const struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12); - -static const enum max1363_modes max11644_mode_list[] = { - _s0, _s1, s0to1, d0m1, d1m0, -}; - -#define MAX1363_2X_CHANS(bits) { \ - MAX1363_CHAN_U(0, _s0, 0, bits, 0), \ - MAX1363_CHAN_U(1, _s1, 1, bits, 0), \ - MAX1363_CHAN_B(0, 1, d0m1, 2, bits, 0), \ - MAX1363_CHAN_B(1, 0, d1m0, 3, bits, 0), \ - IIO_CHAN_SOFT_TIMESTAMP(4) \ - } - -static const struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10); -static const struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12); - -enum { max1361, - max1362, - max1363, - max1364, - max1036, - max1037, - max1038, - max1039, - max1136, - max1137, - max1138, - max1139, - max1236, - max1237, - max1238, - max1239, - max11600, - max11601, - max11602, - max11603, - max11604, - max11605, - max11606, - max11607, - max11608, - max11609, - max11610, - max11611, - max11612, - max11613, - max11614, - max11615, - max11616, - max11617, - max11644, - max11645, - max11646, - max11647 -}; - -static const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600, - 8300, 4200, 2000, 1000 }; - -static ssize_t max1363_monitor_show_freq(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct max1363_state *st = iio_priv(dev_to_iio_dev(dev)); - return sprintf(buf, "%d\n", max1363_monitor_speeds[st->monitor_speed]); -} - -static ssize_t max1363_monitor_store_freq(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct max1363_state *st = iio_priv(indio_dev); - int i, ret; - unsigned long val; - bool found = false; - - ret = strict_strtoul(buf, 10, &val); - if (ret) - return -EINVAL; - for (i = 0; i < ARRAY_SIZE(max1363_monitor_speeds); i++) - if (val == max1363_monitor_speeds[i]) { - found = true; - break; - } - if (!found) - return -EINVAL; - - mutex_lock(&indio_dev->mlock); - st->monitor_speed = i; - mutex_unlock(&indio_dev->mlock); - - return 0; -} - -static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, - max1363_monitor_show_freq, - max1363_monitor_store_freq); - -static IIO_CONST_ATTR(sampling_frequency_available, - "133000 665000 33300 16600 8300 4200 2000 1000"); - -static int max1363_read_thresh(struct iio_dev *indio_dev, - u64 event_code, - int *val) -{ - struct max1363_state *st = iio_priv(indio_dev); - if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) - *val = st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)]; - else - *val = st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)]; - return 0; -} - -static int max1363_write_thresh(struct iio_dev *indio_dev, - u64 event_code, - int val) -{ - struct max1363_state *st = iio_priv(indio_dev); - /* make it handle signed correctly as well */ - switch (st->chip_info->bits) { - case 10: - if (val > 0x3FF) - return -EINVAL; - break; - case 12: - if (val > 0xFFF) - return -EINVAL; - break; - } - - switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) { - case IIO_EV_DIR_FALLING: - st->thresh_low[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val; - break; - case IIO_EV_DIR_RISING: - st->thresh_high[IIO_EVENT_CODE_EXTRACT_CHAN(event_code)] = val; - break; - } - - return 0; -} - -static const u64 max1363_event_codes[] = { - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 1, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 2, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), - IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 3, - IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), -}; - -static irqreturn_t max1363_event_handler(int irq, void *private) -{ - struct iio_dev *indio_dev = private; - struct max1363_state *st = iio_priv(indio_dev); - s64 timestamp = iio_get_time_ns(); - unsigned long mask, loc; - u8 rx; - u8 tx[2] = { st->setupbyte, - MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 }; - - i2c_master_recv(st->client, &rx, 1); - mask = rx; - for_each_set_bit(loc, &mask, 8) - iio_push_event(indio_dev, max1363_event_codes[loc], timestamp); - i2c_master_send(st->client, tx, 2); - - return IRQ_HANDLED; -} - -static int max1363_read_event_config(struct iio_dev *indio_dev, - u64 event_code) -{ - struct max1363_state *st = iio_priv(indio_dev); - int val; - int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code); - - mutex_lock(&indio_dev->mlock); - if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) - val = (1 << number) & st->mask_low; - else - val = (1 << number) & st->mask_high; - mutex_unlock(&indio_dev->mlock); - - return val; -} - -static int max1363_monitor_mode_update(struct max1363_state *st, int enabled) -{ - u8 *tx_buf; - int ret, i = 3, j; - unsigned long numelements; - int len; - const long *modemask; - - if (!enabled) { - /* transition to buffered capture is not currently supported */ - st->setupbyte &= ~MAX1363_SETUP_MONITOR_SETUP; - st->configbyte &= ~MAX1363_SCAN_MASK; - st->monitor_on = false; - return max1363_write_basic_config(st->client, - st->setupbyte, - st->configbyte); - } - - /* Ensure we are in the relevant mode */ - st->setupbyte |= MAX1363_SETUP_MONITOR_SETUP; - st->configbyte &= ~(MAX1363_CHANNEL_SEL_MASK - | MAX1363_SCAN_MASK - | MAX1363_SE_DE_MASK); - st->configbyte |= MAX1363_CONFIG_SCAN_MONITOR_MODE; - if ((st->mask_low | st->mask_high) & 0x0F) { - st->configbyte |= max1363_mode_table[s0to3].conf; - modemask = max1363_mode_table[s0to3].modemask; - } else if ((st->mask_low | st->mask_high) & 0x30) { - st->configbyte |= max1363_mode_table[d0m1to2m3].conf; - modemask = max1363_mode_table[d0m1to2m3].modemask; - } else { - st->configbyte |= max1363_mode_table[d1m0to3m2].conf; - modemask = max1363_mode_table[d1m0to3m2].modemask; - } - numelements = bitmap_weight(modemask, MAX1363_MAX_CHANNELS); - len = 3 * numelements + 3; - tx_buf = kmalloc(len, GFP_KERNEL); - if (!tx_buf) { - ret = -ENOMEM; - goto error_ret; - } - tx_buf[0] = st->configbyte; - tx_buf[1] = st->setupbyte; - tx_buf[2] = (st->monitor_speed << 1); - - /* - * So we need to do yet another bit of nefarious scan mode - * setup to match what we need. - */ - for (j = 0; j < 8; j++) - if (test_bit(j, modemask)) { - /* Establish the mode is in the scan */ - if (st->mask_low & (1 << j)) { - tx_buf[i] = (st->thresh_low[j] >> 4) & 0xFF; - tx_buf[i + 1] = (st->thresh_low[j] << 4) & 0xF0; - } else if (j < 4) { - tx_buf[i] = 0; - tx_buf[i + 1] = 0; - } else { - tx_buf[i] = 0x80; - tx_buf[i + 1] = 0; - } - if (st->mask_high & (1 << j)) { - tx_buf[i + 1] |= - (st->thresh_high[j] >> 8) & 0x0F; - tx_buf[i + 2] = st->thresh_high[j] & 0xFF; - } else if (j < 4) { - tx_buf[i + 1] |= 0x0F; - tx_buf[i + 2] = 0xFF; - } else { - tx_buf[i + 1] |= 0x07; - tx_buf[i + 2] = 0xFF; - } - i += 3; - } - - - ret = i2c_master_send(st->client, tx_buf, len); - if (ret < 0) - goto error_ret; - if (ret != len) { - ret = -EIO; - goto error_ret; - } - - /* - * Now that we hopefully have sensible thresholds in place it is - * time to turn the interrupts on. - * It is unclear from the data sheet if this should be necessary - * (i.e. whether monitor mode setup is atomic) but it appears to - * be in practice. - */ - tx_buf[0] = st->setupbyte; - tx_buf[1] = MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0; - ret = i2c_master_send(st->client, tx_buf, 2); - if (ret < 0) - goto error_ret; - if (ret != 2) { - ret = -EIO; - goto error_ret; - } - ret = 0; - st->monitor_on = true; -error_ret: - - kfree(tx_buf); - - return ret; -} - -/* - * To keep this manageable we always use one of 3 scan modes. - * Scan 0...3, 0-1,2-3 and 1-0,3-2 - */ - -static inline int __max1363_check_event_mask(int thismask, int checkmask) -{ - int ret = 0; - /* Is it unipolar */ - if (thismask < 4) { - if (checkmask & ~0x0F) { - ret = -EBUSY; - goto error_ret; - } - } else if (thismask < 6) { - if (checkmask & ~0x30) { - ret = -EBUSY; - goto error_ret; - } - } else if (checkmask & ~0xC0) - ret = -EBUSY; -error_ret: - return ret; -} - -static int max1363_write_event_config(struct iio_dev *indio_dev, - u64 event_code, - int state) -{ - int ret = 0; - struct max1363_state *st = iio_priv(indio_dev); - u16 unifiedmask; - int number = IIO_EVENT_CODE_EXTRACT_CHAN(event_code); - - mutex_lock(&indio_dev->mlock); - unifiedmask = st->mask_low | st->mask_high; - if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) { - - if (state == 0) - st->mask_low &= ~(1 << number); - else { - ret = __max1363_check_event_mask((1 << number), - unifiedmask); - if (ret) - goto error_ret; - st->mask_low |= (1 << number); - } - } else { - if (state == 0) - st->mask_high &= ~(1 << number); - else { - ret = __max1363_check_event_mask((1 << number), - unifiedmask); - if (ret) - goto error_ret; - st->mask_high |= (1 << number); - } - } - - max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low)); -error_ret: - mutex_unlock(&indio_dev->mlock); - - return ret; -} - -/* - * As with scan_elements, only certain sets of these can - * be combined. - */ -static struct attribute *max1363_event_attributes[] = { - &iio_dev_attr_sampling_frequency.dev_attr.attr, - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - NULL, -}; - -static struct attribute_group max1363_event_attribute_group = { - .attrs = max1363_event_attributes, - .name = "events", -}; - -static int max1363_update_scan_mode(struct iio_dev *indio_dev, - const unsigned long *scan_mask) -{ - struct max1363_state *st = iio_priv(indio_dev); - - /* - * Need to figure out the current mode based upon the requested - * scan mask in iio_dev - */ - st->current_mode = max1363_match_mode(scan_mask, st->chip_info); - if (!st->current_mode) - return -EINVAL; - max1363_set_scan_mode(st); - return 0; -} - -static const struct iio_info max1238_info = { - .read_raw = &max1363_read_raw, - .driver_module = THIS_MODULE, - .update_scan_mode = &max1363_update_scan_mode, -}; - -static const struct iio_info max1363_info = { - .read_event_value = &max1363_read_thresh, - .write_event_value = &max1363_write_thresh, - .read_event_config = &max1363_read_event_config, - .write_event_config = &max1363_write_event_config, - .read_raw = &max1363_read_raw, - .update_scan_mode = &max1363_update_scan_mode, - .driver_module = THIS_MODULE, - .event_attrs = &max1363_event_attribute_group, -}; - -/* max1363 and max1368 tested - rest from data sheet */ -static const struct max1363_chip_info max1363_chip_info_tbl[] = { - [max1361] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max1363_mode_list, - .num_modes = ARRAY_SIZE(max1363_mode_list), - .default_mode = s0to3, - .channels = max1361_channels, - .num_channels = ARRAY_SIZE(max1361_channels), - .info = &max1363_info, - }, - [max1362] = { - .bits = 10, - .int_vref_mv = 4096, - .mode_list = max1363_mode_list, - .num_modes = ARRAY_SIZE(max1363_mode_list), - .default_mode = s0to3, - .channels = max1361_channels, - .num_channels = ARRAY_SIZE(max1361_channels), - .info = &max1363_info, - }, - [max1363] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max1363_mode_list, - .num_modes = ARRAY_SIZE(max1363_mode_list), - .default_mode = s0to3, - .channels = max1363_channels, - .num_channels = ARRAY_SIZE(max1363_channels), - .info = &max1363_info, - }, - [max1364] = { - .bits = 12, - .int_vref_mv = 4096, - .mode_list = max1363_mode_list, - .num_modes = ARRAY_SIZE(max1363_mode_list), - .default_mode = s0to3, - .channels = max1363_channels, - .num_channels = ARRAY_SIZE(max1363_channels), - .info = &max1363_info, - }, - [max1036] = { - .bits = 8, - .int_vref_mv = 4096, - .mode_list = max1236_mode_list, - .num_modes = ARRAY_SIZE(max1236_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1036_channels, - .num_channels = ARRAY_SIZE(max1036_channels), - }, - [max1037] = { - .bits = 8, - .int_vref_mv = 2048, - .mode_list = max1236_mode_list, - .num_modes = ARRAY_SIZE(max1236_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1036_channels, - .num_channels = ARRAY_SIZE(max1036_channels), - }, - [max1038] = { - .bits = 8, - .int_vref_mv = 4096, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1038_channels, - .num_channels = ARRAY_SIZE(max1038_channels), - }, - [max1039] = { - .bits = 8, - .int_vref_mv = 2048, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1038_channels, - .num_channels = ARRAY_SIZE(max1038_channels), - }, - [max1136] = { - .bits = 10, - .int_vref_mv = 4096, - .mode_list = max1236_mode_list, - .num_modes = ARRAY_SIZE(max1236_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1136_channels, - .num_channels = ARRAY_SIZE(max1136_channels), - }, - [max1137] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max1236_mode_list, - .num_modes = ARRAY_SIZE(max1236_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1136_channels, - .num_channels = ARRAY_SIZE(max1136_channels), - }, - [max1138] = { - .bits = 10, - .int_vref_mv = 4096, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1138_channels, - .num_channels = ARRAY_SIZE(max1138_channels), - }, - [max1139] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1138_channels, - .num_channels = ARRAY_SIZE(max1138_channels), - }, - [max1236] = { - .bits = 12, - .int_vref_mv = 4096, - .mode_list = max1236_mode_list, - .num_modes = ARRAY_SIZE(max1236_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1236_channels, - .num_channels = ARRAY_SIZE(max1236_channels), - }, - [max1237] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max1236_mode_list, - .num_modes = ARRAY_SIZE(max1236_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1236_channels, - .num_channels = ARRAY_SIZE(max1236_channels), - }, - [max1238] = { - .bits = 12, - .int_vref_mv = 4096, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max1239] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11600] = { - .bits = 8, - .int_vref_mv = 4096, - .mode_list = max11607_mode_list, - .num_modes = ARRAY_SIZE(max11607_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1036_channels, - .num_channels = ARRAY_SIZE(max1036_channels), - }, - [max11601] = { - .bits = 8, - .int_vref_mv = 2048, - .mode_list = max11607_mode_list, - .num_modes = ARRAY_SIZE(max11607_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1036_channels, - .num_channels = ARRAY_SIZE(max1036_channels), - }, - [max11602] = { - .bits = 8, - .int_vref_mv = 4096, - .mode_list = max11608_mode_list, - .num_modes = ARRAY_SIZE(max11608_mode_list), - .default_mode = s0to7, - .info = &max1238_info, - .channels = max11602_channels, - .num_channels = ARRAY_SIZE(max11602_channels), - }, - [max11603] = { - .bits = 8, - .int_vref_mv = 2048, - .mode_list = max11608_mode_list, - .num_modes = ARRAY_SIZE(max11608_mode_list), - .default_mode = s0to7, - .info = &max1238_info, - .channels = max11602_channels, - .num_channels = ARRAY_SIZE(max11602_channels), - }, - [max11604] = { - .bits = 8, - .int_vref_mv = 4098, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11605] = { - .bits = 8, - .int_vref_mv = 2048, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11606] = { - .bits = 10, - .int_vref_mv = 4096, - .mode_list = max11607_mode_list, - .num_modes = ARRAY_SIZE(max11607_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1136_channels, - .num_channels = ARRAY_SIZE(max1136_channels), - }, - [max11607] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max11607_mode_list, - .num_modes = ARRAY_SIZE(max11607_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1136_channels, - .num_channels = ARRAY_SIZE(max1136_channels), - }, - [max11608] = { - .bits = 10, - .int_vref_mv = 4096, - .mode_list = max11608_mode_list, - .num_modes = ARRAY_SIZE(max11608_mode_list), - .default_mode = s0to7, - .info = &max1238_info, - .channels = max11608_channels, - .num_channels = ARRAY_SIZE(max11608_channels), - }, - [max11609] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max11608_mode_list, - .num_modes = ARRAY_SIZE(max11608_mode_list), - .default_mode = s0to7, - .info = &max1238_info, - .channels = max11608_channels, - .num_channels = ARRAY_SIZE(max11608_channels), - }, - [max11610] = { - .bits = 10, - .int_vref_mv = 4098, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11611] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11612] = { - .bits = 12, - .int_vref_mv = 4096, - .mode_list = max11607_mode_list, - .num_modes = ARRAY_SIZE(max11607_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1363_channels, - .num_channels = ARRAY_SIZE(max1363_channels), - }, - [max11613] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max11607_mode_list, - .num_modes = ARRAY_SIZE(max11607_mode_list), - .default_mode = s0to3, - .info = &max1238_info, - .channels = max1363_channels, - .num_channels = ARRAY_SIZE(max1363_channels), - }, - [max11614] = { - .bits = 12, - .int_vref_mv = 4096, - .mode_list = max11608_mode_list, - .num_modes = ARRAY_SIZE(max11608_mode_list), - .default_mode = s0to7, - .info = &max1238_info, - .channels = max11614_channels, - .num_channels = ARRAY_SIZE(max11614_channels), - }, - [max11615] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max11608_mode_list, - .num_modes = ARRAY_SIZE(max11608_mode_list), - .default_mode = s0to7, - .info = &max1238_info, - .channels = max11614_channels, - .num_channels = ARRAY_SIZE(max11614_channels), - }, - [max11616] = { - .bits = 12, - .int_vref_mv = 4098, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11617] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max1238_mode_list, - .num_modes = ARRAY_SIZE(max1238_mode_list), - .default_mode = s0to11, - .info = &max1238_info, - .channels = max1238_channels, - .num_channels = ARRAY_SIZE(max1238_channels), - }, - [max11644] = { - .bits = 12, - .int_vref_mv = 2048, - .mode_list = max11644_mode_list, - .num_modes = ARRAY_SIZE(max11644_mode_list), - .default_mode = s0to1, - .info = &max1238_info, - .channels = max11644_channels, - .num_channels = ARRAY_SIZE(max11644_channels), - }, - [max11645] = { - .bits = 12, - .int_vref_mv = 4096, - .mode_list = max11644_mode_list, - .num_modes = ARRAY_SIZE(max11644_mode_list), - .default_mode = s0to1, - .info = &max1238_info, - .channels = max11644_channels, - .num_channels = ARRAY_SIZE(max11644_channels), - }, - [max11646] = { - .bits = 10, - .int_vref_mv = 2048, - .mode_list = max11644_mode_list, - .num_modes = ARRAY_SIZE(max11644_mode_list), - .default_mode = s0to1, - .info = &max1238_info, - .channels = max11646_channels, - .num_channels = ARRAY_SIZE(max11646_channels), - }, - [max11647] = { - .bits = 10, - .int_vref_mv = 4096, - .mode_list = max11644_mode_list, - .num_modes = ARRAY_SIZE(max11644_mode_list), - .default_mode = s0to1, - .info = &max1238_info, - .channels = max11646_channels, - .num_channels = ARRAY_SIZE(max11646_channels), - }, -}; - -static int max1363_initial_setup(struct max1363_state *st) -{ - st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD - | MAX1363_SETUP_POWER_UP_INT_REF - | MAX1363_SETUP_INT_CLOCK - | MAX1363_SETUP_UNIPOLAR - | MAX1363_SETUP_NORESET; - - /* Set scan mode writes the config anyway so wait until then*/ - st->setupbyte = MAX1363_SETUP_BYTE(st->setupbyte); - st->current_mode = &max1363_mode_table[st->chip_info->default_mode]; - st->configbyte = MAX1363_CONFIG_BYTE(st->configbyte); - - return max1363_set_scan_mode(st); -} - -static int __devinit max1363_alloc_scan_masks(struct iio_dev *indio_dev) -{ - struct max1363_state *st = iio_priv(indio_dev); - unsigned long *masks; - int i; - - masks = kzalloc(BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*sizeof(long)* - (st->chip_info->num_modes + 1), GFP_KERNEL); - if (!masks) - return -ENOMEM; - - for (i = 0; i < st->chip_info->num_modes; i++) - bitmap_copy(masks + BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*i, - max1363_mode_table[st->chip_info->mode_list[i]] - .modemask, MAX1363_MAX_CHANNELS); - - indio_dev->available_scan_masks = masks; - - return 0; -} - - -static irqreturn_t max1363_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct max1363_state *st = iio_priv(indio_dev); - s64 time_ns; - __u8 *rxbuf; - int b_sent; - size_t d_size; - unsigned long numvals = bitmap_weight(st->current_mode->modemask, - MAX1363_MAX_CHANNELS); - - /* Ensure the timestamp is 8 byte aligned */ - if (st->chip_info->bits != 8) - d_size = numvals*2; - else - d_size = numvals; - if (indio_dev->scan_timestamp) { - d_size += sizeof(s64); - if (d_size % sizeof(s64)) - d_size += sizeof(s64) - (d_size % sizeof(s64)); - } - /* Monitor mode prevents reading. Whilst not currently implemented - * might as well have this test in here in the meantime as it does - * no harm. - */ - if (numvals == 0) - goto done; - - rxbuf = kmalloc(d_size, GFP_KERNEL); - if (rxbuf == NULL) - goto done; - if (st->chip_info->bits != 8) - b_sent = i2c_master_recv(st->client, rxbuf, numvals*2); - else - b_sent = i2c_master_recv(st->client, rxbuf, numvals); - if (b_sent < 0) - goto done_free; - - time_ns = iio_get_time_ns(); - - if (indio_dev->scan_timestamp) - memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); - iio_push_to_buffers(indio_dev, rxbuf); - -done_free: - kfree(rxbuf); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -static const struct iio_buffer_setup_ops max1363_buffered_setup_ops = { - .postenable = &iio_triggered_buffer_postenable, - .preenable = &iio_sw_buffer_preenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -static int max1363_register_buffered_funcs_and_init(struct iio_dev *indio_dev) -{ - struct max1363_state *st = iio_priv(indio_dev); - int ret = 0; - - indio_dev->buffer = iio_kfifo_allocate(indio_dev); - if (!indio_dev->buffer) { - ret = -ENOMEM; - goto error_ret; - } - indio_dev->pollfunc = iio_alloc_pollfunc(NULL, - &max1363_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "%s_consumer%d", - st->client->name, - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_deallocate_sw_rb; - } - /* Buffer functions - here trigger setup related */ - indio_dev->setup_ops = &max1363_buffered_setup_ops; - - /* Flag that polled buffering is possible */ - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - - return 0; - -error_deallocate_sw_rb: - iio_kfifo_free(indio_dev->buffer); -error_ret: - return ret; -} - -static void max1363_buffer_cleanup(struct iio_dev *indio_dev) -{ - /* ensure that the trigger has been detached */ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_kfifo_free(indio_dev->buffer); -} - -static int __devinit max1363_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - int ret; - struct max1363_state *st; - struct iio_dev *indio_dev; - - indio_dev = iio_device_alloc(sizeof(struct max1363_state)); - if (indio_dev == NULL) { - ret = -ENOMEM; - goto error_out; - } - - ret = iio_map_array_register(indio_dev, client->dev.platform_data); - if (ret < 0) - goto error_free_device; - - st = iio_priv(indio_dev); - - st->reg = regulator_get(&client->dev, "vcc"); - if (IS_ERR(st->reg)) { - ret = PTR_ERR(st->reg); - goto error_unregister_map; - } - - ret = regulator_enable(st->reg); - if (ret) - goto error_put_reg; - - /* this is only used for device removal purposes */ - i2c_set_clientdata(client, indio_dev); - - st->chip_info = &max1363_chip_info_tbl[id->driver_data]; - st->client = client; - - ret = max1363_alloc_scan_masks(indio_dev); - if (ret) - goto error_disable_reg; - - /* Estabilish that the iio_dev is a child of the i2c device */ - indio_dev->dev.parent = &client->dev; - indio_dev->name = id->name; - indio_dev->channels = st->chip_info->channels; - indio_dev->num_channels = st->chip_info->num_channels; - indio_dev->info = st->chip_info->info; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = st->chip_info->channels; - indio_dev->num_channels = st->chip_info->num_channels; - ret = max1363_initial_setup(st); - if (ret < 0) - goto error_free_available_scan_masks; - - ret = max1363_register_buffered_funcs_and_init(indio_dev); - if (ret) - goto error_free_available_scan_masks; - - ret = iio_buffer_register(indio_dev, - st->chip_info->channels, - st->chip_info->num_channels); - if (ret) - goto error_cleanup_buffer; - - if (client->irq) { - ret = request_threaded_irq(st->client->irq, - NULL, - &max1363_event_handler, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, - "max1363_event", - indio_dev); - - if (ret) - goto error_uninit_buffer; - } - - ret = iio_device_register(indio_dev); - if (ret < 0) - goto error_free_irq; - - return 0; -error_free_irq: - free_irq(st->client->irq, indio_dev); -error_uninit_buffer: - iio_buffer_unregister(indio_dev); -error_cleanup_buffer: - max1363_buffer_cleanup(indio_dev); -error_free_available_scan_masks: - kfree(indio_dev->available_scan_masks); -error_unregister_map: - iio_map_array_unregister(indio_dev, client->dev.platform_data); -error_disable_reg: - regulator_disable(st->reg); -error_put_reg: - regulator_put(st->reg); -error_free_device: - iio_device_free(indio_dev); -error_out: - return ret; -} - -static int __devexit max1363_remove(struct i2c_client *client) -{ - struct iio_dev *indio_dev = i2c_get_clientdata(client); - struct max1363_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - if (client->irq) - free_irq(st->client->irq, indio_dev); - iio_buffer_unregister(indio_dev); - max1363_buffer_cleanup(indio_dev); - kfree(indio_dev->available_scan_masks); - if (!IS_ERR(st->reg)) { - regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_map_array_unregister(indio_dev, client->dev.platform_data); - iio_device_free(indio_dev); - - return 0; -} - -static const struct i2c_device_id max1363_id[] = { - { "max1361", max1361 }, - { "max1362", max1362 }, - { "max1363", max1363 }, - { "max1364", max1364 }, - { "max1036", max1036 }, - { "max1037", max1037 }, - { "max1038", max1038 }, - { "max1039", max1039 }, - { "max1136", max1136 }, - { "max1137", max1137 }, - { "max1138", max1138 }, - { "max1139", max1139 }, - { "max1236", max1236 }, - { "max1237", max1237 }, - { "max1238", max1238 }, - { "max1239", max1239 }, - { "max11600", max11600 }, - { "max11601", max11601 }, - { "max11602", max11602 }, - { "max11603", max11603 }, - { "max11604", max11604 }, - { "max11605", max11605 }, - { "max11606", max11606 }, - { "max11607", max11607 }, - { "max11608", max11608 }, - { "max11609", max11609 }, - { "max11610", max11610 }, - { "max11611", max11611 }, - { "max11612", max11612 }, - { "max11613", max11613 }, - { "max11614", max11614 }, - { "max11615", max11615 }, - { "max11616", max11616 }, - { "max11617", max11617 }, - {} -}; - -MODULE_DEVICE_TABLE(i2c, max1363_id); - -static struct i2c_driver max1363_driver = { - .driver = { - .name = "max1363", - }, - .probe = max1363_probe, - .remove = __devexit_p(max1363_remove), - .id_table = max1363_id, -}; -module_i2c_driver(max1363_driver); - -MODULE_AUTHOR("Jonathan Cameron "); -MODULE_DESCRIPTION("Maxim 1363 ADC"); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 1f98ab7fef48a2968f37f422c256c9fbd978c3f0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 10 Nov 2012 03:44:14 +0100 Subject: mac80211: call skb_dequeue/ieee80211_free_txskb instead of __skb_queue_purge Fixes more wifi status skb leaks, leading to hostapd/wpa_supplicant hangs. Signed-off-by: Felix Fietkau Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/sta_info.c | 6 +++--- net/mac80211/status.c | 9 +++++++++ net/mac80211/tx.c | 9 ++++++--- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 8c804550465..156e5835e37 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1314,6 +1314,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); +void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, + struct sk_buff_head *skbs); /* HT */ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 89ccd3ec7eb..3b5911ed431 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -117,8 +117,8 @@ static void free_sta_work(struct work_struct *wk) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]); - __skb_queue_purge(&sta->ps_tx_buf[ac]); - __skb_queue_purge(&sta->tx_filtered[ac]); + ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]); + ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]); } #ifdef CONFIG_MAC80211_MESH @@ -141,7 +141,7 @@ static void free_sta_work(struct work_struct *wk) tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); if (!tid_tx) continue; - __skb_queue_purge(&tid_tx->pending); + ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); kfree(tid_tx); } diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 3af0cc4130f..101eb88a2b7 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -668,3 +668,12 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb) dev_kfree_skb_any(skb); } EXPORT_SYMBOL(ieee80211_free_txskb); + +void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, + struct sk_buff_head *skbs) +{ + struct sk_buff *skb; + + while ((skb = __skb_dequeue(skbs))) + ieee80211_free_txskb(hw, skb); +} diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c9bf83f3665..b858ebe41fd 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1358,7 +1358,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) if (tx->skb) ieee80211_free_txskb(&tx->local->hw, tx->skb); else - __skb_queue_purge(&tx->skbs); + ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs); return -1; } else if (unlikely(res == TX_QUEUED)) { I802_DEBUG_INC(tx->local->tx_handlers_queued); @@ -2120,10 +2120,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, */ void ieee80211_clear_tx_pending(struct ieee80211_local *local) { + struct sk_buff *skb; int i; - for (i = 0; i < local->hw.queues; i++) - skb_queue_purge(&local->pending[i]); + for (i = 0; i < local->hw.queues; i++) { + while ((skb = skb_dequeue(&local->pending[i])) != NULL) + ieee80211_free_txskb(&local->hw, skb); + } } /* -- cgit v1.2.3 From 7e4d68443a80574392d1027ff34992ab945934a6 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Thu, 8 Nov 2012 11:14:08 +0800 Subject: PM / QoS: Resume device before exposing/hiding PM QoS flags Since dev_pm_qos_add_request(), dev_pm_qos_update_request() and dev_pm_qos_remove_request() for PM QoS flags should not be invoked when device in RPM_SUSPENDED, add pm_runtime_get_sync() and pm_runtime_put() around these functions in dev_pm_qos_expose_flags() and dev_pm_qos_hide_flags(). [rjw: Modified the subject and changelog to better reflect the code changes made.] Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/base/power/qos.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 081db2d25da..fdc3894bc33 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -633,15 +633,18 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val) if (!req) return -ENOMEM; + pm_runtime_get_sync(dev); ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_FLAGS, val); if (ret < 0) - return ret; + goto fail; dev->power.qos->flags_req = req; ret = pm_qos_sysfs_add_flags(dev); if (ret) __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); +fail: + pm_runtime_put(dev); return ret; } EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags); @@ -654,7 +657,9 @@ void dev_pm_qos_hide_flags(struct device *dev) { if (dev->power.qos && dev->power.qos->flags_req) { pm_qos_sysfs_remove_flags(dev); + pm_runtime_get_sync(dev); __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); + pm_runtime_put(dev); } } EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags); -- cgit v1.2.3 From 509b7455ef87e1447670c51037cabbf93d772d6f Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 22 Oct 2012 11:32:30 +1100 Subject: of/fdt: Don't copy garbage after "/" in root node path The root node path must be internally converted to "/", or various pieces of code looking for it that way will fail. The code to do that however had a bug where we might incorrectly append pieces of the original path from the fdt to the "/". We should probably add a proper dedicated accessor for the root node but in the meantime this patch should fix it. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Rob Herring --- drivers/of/fdt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 91a375fb6ae..c2b08dcdbc5 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -186,6 +186,7 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, */ fpsize = 1; allocl = 2; + l = 0; } else { /* account for '/' and path size minus terminal 0 * already in 'l' -- cgit v1.2.3 From 55020c8056a83ef2181e4cddd39cb2b9f4b88c5a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 9 Nov 2012 14:07:01 +0100 Subject: of: Add vendor prefix for ON Semiconductor Corp. The used vendor prefix corresponds to the stock symbol (ONNN) for ON Semiconductor Corp. Signed-off-by: Thierry Reding Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 9de2b9ff9d6..ff41e401901 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -34,6 +34,7 @@ national National Semiconductor nintendo Nintendo nvidia NVIDIA nxp NXP Semiconductors +onnn ON Semiconductor Corp. picochip Picochip Ltd powervr Imagination Technologies qcom Qualcomm, Inc. -- cgit v1.2.3 From 1a78958dc212f3698fdc543857af80155cb30f7f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 17 Oct 2012 20:51:54 +0200 Subject: pinctrl: reserve pins when states are activated This switches the way that pins are reserved for multiplexing: We used to do this when the map was parsed, at the creation of the settings inside the pinctrl handle, in pinmux_map_to_setting(). However this does not work for us, because we want to use the same set of pins with different devices at different times: the current code assumes that the pin groups in a pinmux state will only be used with one single device, albeit different groups can be active at different times. For example if a single I2C driver block is used to drive two different busses located on two pin groups A and B, then the pins for all possible states of a function are reserved when fetching the pinctrl handle: the I2C bus can choose either set A or set B by a mux state at runtime, but all pins in both group A and B (the superset) are effectively reserved for that I2C function and mapped to the device. Another device can never get in and use the pins in group A, even if the device/function is using group B at the moment. Instead: let use reserve the pins when the state is activated and drop them when the state is disabled, i.e. when we move to another state. This way different devices/functions can use the same pins at different times. We know that this is an odd way of doing things, but we really need to switch e.g. an SD-card slot to become a tracing output sink at runtime: we plug in a special "tracing card" then mux the pins that used to be an SD slot around to the tracing unit and push out tracing data there instead of SD-card traffic. As a side effect pinmux_free_setting() is unused but the stubs are kept for future additions of code. Cc: Patrice Chotard Cc: Loic Pallardy Acked-by: Stephen Warren Tested-by: Jean Nicolas Graux Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 4 ++- drivers/pinctrl/core.c | 2 ++ drivers/pinctrl/core.h | 2 ++ drivers/pinctrl/pinmux.c | 67 ++++++++++++++++------------------------------- 4 files changed, 29 insertions(+), 46 deletions(-) diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 3b4ee532886..a1cd2f9428d 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -1193,4 +1193,6 @@ foo_switch() ... } -The above has to be done from process context. +The above has to be done from process context. The reservation of the pins +will be done when the state is activated, so in effect one specific pin +can be used by different functions at different times on a running system. diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 2e39c04fc16..cec6072cd7c 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -563,6 +563,8 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) return -EPROBE_DEFER; } + setting->dev_name = map->dev_name; + switch (map->type) { case PIN_MAP_TYPE_MUX_GROUP: ret = pinmux_map_to_setting(map, setting); diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 1f40ff68a8c..12f5694f3d5 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -105,12 +105,14 @@ struct pinctrl_setting_configs { * @type: the type of setting * @pctldev: pin control device handling to be programmed. Not used for * PIN_MAP_TYPE_DUMMY_STATE. + * @dev_name: the name of the device using this state * @data: Data specific to the setting type */ struct pinctrl_setting { struct list_head node; enum pinctrl_map_type type; struct pinctrl_dev *pctldev; + const char *dev_name; union { struct pinctrl_setting_mux mux; struct pinctrl_setting_configs configs; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 9301a7a95ef..0ef01ee2835 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -314,14 +314,11 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, { struct pinctrl_dev *pctldev = setting->pctldev; const struct pinmux_ops *pmxops = pctldev->desc->pmxops; - const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; char const * const *groups; unsigned num_groups; int ret; const char *group; int i; - const unsigned *pins; - unsigned num_pins; if (!pmxops) { dev_err(pctldev->dev, "does not support mux function\n"); @@ -376,53 +373,12 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, } setting->data.mux.group = ret; - ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins, - &num_pins); - if (ret) { - dev_err(pctldev->dev, - "could not get pins for device %s group selector %d\n", - pinctrl_dev_get_name(pctldev), setting->data.mux.group); - return -ENODEV; - } - - /* Try to allocate all pins in this group, one by one */ - for (i = 0; i < num_pins; i++) { - ret = pin_request(pctldev, pins[i], map->dev_name, NULL); - if (ret) { - dev_err(pctldev->dev, - "could not request pin %d on device %s\n", - pins[i], pinctrl_dev_get_name(pctldev)); - /* On error release all taken pins */ - i--; /* this pin just failed */ - for (; i >= 0; i--) - pin_free(pctldev, pins[i], NULL); - return -ENODEV; - } - } - return 0; } void pinmux_free_setting(struct pinctrl_setting const *setting) { - struct pinctrl_dev *pctldev = setting->pctldev; - const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - const unsigned *pins; - unsigned num_pins; - int ret; - int i; - - ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, - &pins, &num_pins); - if (ret) { - dev_err(pctldev->dev, - "could not get pins for device %s group selector %d\n", - pinctrl_dev_get_name(pctldev), setting->data.mux.group); - return; - } - - for (i = 0; i < num_pins; i++) - pin_free(pctldev, pins[i], NULL); + /* This function is currently unused */ } int pinmux_enable_setting(struct pinctrl_setting const *setting) @@ -446,6 +402,22 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) num_pins = 0; } + /* Try to allocate all pins in this group, one by one */ + for (i = 0; i < num_pins; i++) { + ret = pin_request(pctldev, pins[i], setting->dev_name, NULL); + if (ret) { + dev_err(pctldev->dev, + "could not request pin %d on device %s\n", + pins[i], pinctrl_dev_get_name(pctldev)); + /* On error release all taken pins */ + i--; /* this pin just failed */ + for (; i >= 0; i--) + pin_free(pctldev, pins[i], NULL); + return -ENODEV; + } + } + + /* Now that we have acquired the pins, encode the mux setting */ for (i = 0; i < num_pins; i++) { desc = pin_desc_get(pctldev, pins[i]); if (desc == NULL) { @@ -482,6 +454,7 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) num_pins = 0; } + /* Flag the descs that no setting is active */ for (i = 0; i < num_pins; i++) { desc = pin_desc_get(pctldev, pins[i]); if (desc == NULL) { @@ -493,6 +466,10 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) desc->mux_setting = NULL; } + /* And release the pins */ + for (i = 0; i < num_pins; i++) + pin_free(pctldev, pins[i], NULL); + if (ops->disable) ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); } -- cgit v1.2.3 From 55d2e40d4acf9081daee5a95d0eb474511408968 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 24 Oct 2012 23:38:56 +0200 Subject: pinctrl: mvebu: allow plat-orion architectures to use pinctrl-mvebu The mach-kirkwood and mach-dove architectures have not yet been integrated into the mach-mvebu directory, which should ultimately contain the support for all Marvell SoCs from the Engineering Business Unit. However, before this can happen, we need to let mach-kirkwood and mach-dove use the pinctrl-mvebu driver, which supports the kirkwood and dove SoC families. In order to do that, we make this driver available as soon as PLAT_ORION is selected, instead of using ARCH_MVEBU as a condition. In the long term, PLAT_ORION should disappear and be fully replaced by ARCH_MVEBU, but the plan is to make the migration step by step, by first having the existing mach-* directories for Marvell SoCs converge on several infrastructures, including the pinctrl one. Also, like the spear pinctrl driver, we put all pinctrl-mvebu Kconfig options under a if, in order to avoid having certain options (PINCTRL_DOVE, PINCTRL_KIRKWOOD, etc.) selecting an option (PINCTLR_MVEBU) which itself has a dependency (on ARCH_MVEBU). In this a construct, the dependency is in fact ignored due to the selects. Signed-off-by: Thomas Petazzoni Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index d96caefd914..2cc8fd929d9 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -188,9 +188,10 @@ config PINCTRL_EXYNOS4 depends on OF && GPIOLIB select PINCTRL_SAMSUNG +if PLAT_ORION + config PINCTRL_MVEBU bool - depends on ARCH_MVEBU select PINMUX select PINCONF @@ -210,6 +211,8 @@ config PINCTRL_ARMADA_XP bool select PINCTRL_MVEBU +endif + source "drivers/pinctrl/spear/Kconfig" config PINCTRL_XWAY -- cgit v1.2.3 From de1d76258f438414633cb92cb1a195ba3835972c Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 24 Oct 2012 23:38:57 +0200 Subject: pinctrl: mvebu: remove useless include Including the core.h header for the pinctrl subsystem is not necessary, and it is actually causing problems when moving the pinctrl-mvebu drivers into a separate subdirectory. Signed-off-by: Thomas Petazzoni Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-mvebu.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-mvebu.c b/drivers/pinctrl/pinctrl-mvebu.c index 8e6266c6249..6c44b7e8964 100644 --- a/drivers/pinctrl/pinctrl-mvebu.c +++ b/drivers/pinctrl/pinctrl-mvebu.c @@ -24,7 +24,6 @@ #include #include -#include "core.h" #include "pinctrl-mvebu.h" #define MPPS_PER_REG 8 -- cgit v1.2.3 From 06763c741b0a19160482c9b34e5bbc3e50dba79a Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 24 Oct 2012 23:38:58 +0200 Subject: pinctrl: mvebu: move to its own directory Like the spear platform, the mvebu platform has multiple files: one core file, and then one file per SoC family. More files will be added later, as support for mach-orion5x and mach-mv78xx0 SoCs is added to pinctrl-mvebu. For those reasons, having a separate subdirectory, drivers/pinctrl/mvebu/ makes sense, and it had already been suggested by Linus Wallej when the driver was originally submitted. Signed-off-by: Thomas Petazzoni Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 25 +- drivers/pinctrl/Makefile | 6 +- drivers/pinctrl/mvebu/Kconfig | 24 + drivers/pinctrl/mvebu/Makefile | 5 + drivers/pinctrl/mvebu/pinctrl-armada-370.c | 421 ++++++++++++++++ drivers/pinctrl/mvebu/pinctrl-armada-xp.c | 468 ++++++++++++++++++ drivers/pinctrl/mvebu/pinctrl-dove.c | 620 ++++++++++++++++++++++++ drivers/pinctrl/mvebu/pinctrl-kirkwood.c | 472 ++++++++++++++++++ drivers/pinctrl/mvebu/pinctrl-mvebu.c | 753 +++++++++++++++++++++++++++++ drivers/pinctrl/mvebu/pinctrl-mvebu.h | 192 ++++++++ drivers/pinctrl/pinctrl-armada-370.c | 421 ---------------- drivers/pinctrl/pinctrl-armada-xp.c | 468 ------------------ drivers/pinctrl/pinctrl-dove.c | 620 ------------------------ drivers/pinctrl/pinctrl-kirkwood.c | 472 ------------------ drivers/pinctrl/pinctrl-mvebu.c | 753 ----------------------------- drivers/pinctrl/pinctrl-mvebu.h | 192 -------- 16 files changed, 2957 insertions(+), 2955 deletions(-) create mode 100644 drivers/pinctrl/mvebu/Kconfig create mode 100644 drivers/pinctrl/mvebu/Makefile create mode 100644 drivers/pinctrl/mvebu/pinctrl-armada-370.c create mode 100644 drivers/pinctrl/mvebu/pinctrl-armada-xp.c create mode 100644 drivers/pinctrl/mvebu/pinctrl-dove.c create mode 100644 drivers/pinctrl/mvebu/pinctrl-kirkwood.c create mode 100644 drivers/pinctrl/mvebu/pinctrl-mvebu.c create mode 100644 drivers/pinctrl/mvebu/pinctrl-mvebu.h delete mode 100644 drivers/pinctrl/pinctrl-armada-370.c delete mode 100644 drivers/pinctrl/pinctrl-armada-xp.c delete mode 100644 drivers/pinctrl/pinctrl-dove.c delete mode 100644 drivers/pinctrl/pinctrl-kirkwood.c delete mode 100644 drivers/pinctrl/pinctrl-mvebu.c delete mode 100644 drivers/pinctrl/pinctrl-mvebu.h diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 2cc8fd929d9..011133772d2 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -188,30 +188,7 @@ config PINCTRL_EXYNOS4 depends on OF && GPIOLIB select PINCTRL_SAMSUNG -if PLAT_ORION - -config PINCTRL_MVEBU - bool - select PINMUX - select PINCONF - -config PINCTRL_DOVE - bool - select PINCTRL_MVEBU - -config PINCTRL_KIRKWOOD - bool - select PINCTRL_MVEBU - -config PINCTRL_ARMADA_370 - bool - select PINCTRL_MVEBU - -config PINCTRL_ARMADA_XP - bool - select PINCTRL_MVEBU - -endif +source "drivers/pinctrl/mvebu/Kconfig" source "drivers/pinctrl/spear/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index f395ba5cec2..3cb6a0a668a 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -36,12 +36,8 @@ obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o obj-$(CONFIG_PINCTRL_EXYNOS4) += pinctrl-exynos.o -obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o -obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o -obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o -obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o -obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o +obj-$(CONFIG_PLAT_ORION) += mvebu/ obj-$(CONFIG_PLAT_SPEAR) += spear/ diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig new file mode 100644 index 00000000000..366fa541ee9 --- /dev/null +++ b/drivers/pinctrl/mvebu/Kconfig @@ -0,0 +1,24 @@ +if PLAT_ORION + +config PINCTRL_MVEBU + bool + select PINMUX + select PINCONF + +config PINCTRL_DOVE + bool + select PINCTRL_MVEBU + +config PINCTRL_KIRKWOOD + bool + select PINCTRL_MVEBU + +config PINCTRL_ARMADA_370 + bool + select PINCTRL_MVEBU + +config PINCTRL_ARMADA_XP + bool + select PINCTRL_MVEBU + +endif diff --git a/drivers/pinctrl/mvebu/Makefile b/drivers/pinctrl/mvebu/Makefile new file mode 100644 index 00000000000..37c253297af --- /dev/null +++ b/drivers/pinctrl/mvebu/Makefile @@ -0,0 +1,5 @@ +obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o +obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o +obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o +obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o +obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-370.c b/drivers/pinctrl/mvebu/pinctrl-armada-370.c new file mode 100644 index 00000000000..c907647de6a --- /dev/null +++ b/drivers/pinctrl/mvebu/pinctrl-armada-370.c @@ -0,0 +1,421 @@ +/* + * Marvell Armada 370 pinctrl driver based on mvebu pinctrl core + * + * Copyright (C) 2012 Marvell + * + * Thomas Petazzoni + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pinctrl-mvebu.h" + +static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = { + MPP_MODE(0, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "uart0", "rxd")), + MPP_MODE(1, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "uart0", "txd")), + MPP_MODE(2, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "i2c0", "sck"), + MPP_FUNCTION(0x2, "uart0", "txd")), + MPP_MODE(3, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "i2c0", "sda"), + MPP_FUNCTION(0x2, "uart0", "rxd")), + MPP_MODE(4, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "cpu_pd", "vdd")), + MPP_MODE(5, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "ge0", "txclko"), + MPP_FUNCTION(0x2, "uart1", "txd"), + MPP_FUNCTION(0x4, "spi1", "clk"), + MPP_FUNCTION(0x5, "audio", "mclk")), + MPP_MODE(6, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "txd0"), + MPP_FUNCTION(0x2, "sata0", "prsnt"), + MPP_FUNCTION(0x4, "tdm", "rst"), + MPP_FUNCTION(0x5, "audio", "sdo")), + MPP_MODE(7, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "ge0", "txd1"), + MPP_FUNCTION(0x4, "tdm", "tdx"), + MPP_FUNCTION(0x5, "audio", "lrclk")), + MPP_MODE(8, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "txd2"), + MPP_FUNCTION(0x2, "uart0", "rts"), + MPP_FUNCTION(0x4, "tdm", "drx"), + MPP_FUNCTION(0x5, "audio", "bclk")), + MPP_MODE(9, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "ge0", "txd3"), + MPP_FUNCTION(0x2, "uart1", "txd"), + MPP_FUNCTION(0x3, "sd0", "clk"), + MPP_FUNCTION(0x5, "audio", "spdifo")), + MPP_MODE(10, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "txctl"), + MPP_FUNCTION(0x2, "uart0", "cts"), + MPP_FUNCTION(0x4, "tdm", "fsync"), + MPP_FUNCTION(0x5, "audio", "sdi")), + MPP_MODE(11, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "rxd0"), + MPP_FUNCTION(0x2, "uart1", "rxd"), + MPP_FUNCTION(0x3, "sd0", "cmd"), + MPP_FUNCTION(0x4, "spi0", "cs1"), + MPP_FUNCTION(0x5, "sata1", "prsnt"), + MPP_FUNCTION(0x6, "spi1", "cs1")), + MPP_MODE(12, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "rxd1"), + MPP_FUNCTION(0x2, "i2c1", "sda"), + MPP_FUNCTION(0x3, "sd0", "d0"), + MPP_FUNCTION(0x4, "spi1", "cs0"), + MPP_FUNCTION(0x5, "audio", "spdifi")), + MPP_MODE(13, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "rxd2"), + MPP_FUNCTION(0x2, "i2c1", "sck"), + MPP_FUNCTION(0x3, "sd0", "d1"), + MPP_FUNCTION(0x4, "tdm", "pclk"), + MPP_FUNCTION(0x5, "audio", "rmclk")), + MPP_MODE(14, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "rxd3"), + MPP_FUNCTION(0x2, "pcie", "clkreq0"), + MPP_FUNCTION(0x3, "sd0", "d2"), + MPP_FUNCTION(0x4, "spi1", "mosi"), + MPP_FUNCTION(0x5, "spi0", "cs2")), + MPP_MODE(15, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "rxctl"), + MPP_FUNCTION(0x2, "pcie", "clkreq1"), + MPP_FUNCTION(0x3, "sd0", "d3"), + MPP_FUNCTION(0x4, "spi1", "miso"), + MPP_FUNCTION(0x5, "spi0", "cs3")), + MPP_MODE(16, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "rxclk"), + MPP_FUNCTION(0x2, "uart1", "rxd"), + MPP_FUNCTION(0x4, "tdm", "int"), + MPP_FUNCTION(0x5, "audio", "extclk")), + MPP_MODE(17, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "ge", "mdc")), + MPP_MODE(18, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge", "mdio")), + MPP_MODE(19, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "txclk"), + MPP_FUNCTION(0x2, "ge1", "txclkout"), + MPP_FUNCTION(0x4, "tdm", "pclk")), + MPP_MODE(20, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "ge0", "txd4"), + MPP_FUNCTION(0x2, "ge1", "txd0")), + MPP_MODE(21, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "ge0", "txd5"), + MPP_FUNCTION(0x2, "ge1", "txd1"), + MPP_FUNCTION(0x4, "uart1", "txd")), + MPP_MODE(22, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "ge0", "txd6"), + MPP_FUNCTION(0x2, "ge1", "txd2"), + MPP_FUNCTION(0x4, "uart0", "rts")), + MPP_MODE(23, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "ge0", "txd7"), + MPP_FUNCTION(0x2, "ge1", "txd3"), + MPP_FUNCTION(0x4, "spi1", "mosi")), + MPP_MODE(24, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "col"), + MPP_FUNCTION(0x2, "ge1", "txctl"), + MPP_FUNCTION(0x4, "spi1", "cs0")), + MPP_MODE(25, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "rxerr"), + MPP_FUNCTION(0x2, "ge1", "rxd0"), + MPP_FUNCTION(0x4, "uart1", "rxd")), + MPP_MODE(26, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "crs"), + MPP_FUNCTION(0x2, "ge1", "rxd1"), + MPP_FUNCTION(0x4, "spi1", "miso")), + MPP_MODE(27, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "rxd4"), + MPP_FUNCTION(0x2, "ge1", "rxd2"), + MPP_FUNCTION(0x4, "uart0", "cts")), + MPP_MODE(28, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "rxd5"), + MPP_FUNCTION(0x2, "ge1", "rxd3")), + MPP_MODE(29, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "rxd6"), + MPP_FUNCTION(0x2, "ge1", "rxctl"), + MPP_FUNCTION(0x4, "i2c1", "sda")), + MPP_MODE(30, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "ge0", "rxd7"), + MPP_FUNCTION(0x2, "ge1", "rxclk"), + MPP_FUNCTION(0x4, "i2c1", "sck")), + MPP_MODE(31, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x3, "tclk", NULL), + MPP_FUNCTION(0x4, "ge0", "txerr")), + MPP_MODE(32, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "spi0", "cs0")), + MPP_MODE(33, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "bootcs"), + MPP_FUNCTION(0x2, "spi0", "cs0")), + MPP_MODE(34, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "wen0"), + MPP_FUNCTION(0x2, "spi0", "mosi")), + MPP_MODE(35, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "oen"), + MPP_FUNCTION(0x2, "spi0", "sck")), + MPP_MODE(36, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "a1"), + MPP_FUNCTION(0x2, "spi0", "miso")), + MPP_MODE(37, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "a0"), + MPP_FUNCTION(0x2, "sata0", "prsnt")), + MPP_MODE(38, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "ready"), + MPP_FUNCTION(0x2, "uart1", "cts"), + MPP_FUNCTION(0x3, "uart0", "cts")), + MPP_MODE(39, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "ad0"), + MPP_FUNCTION(0x2, "audio", "spdifo")), + MPP_MODE(40, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "ad1"), + MPP_FUNCTION(0x2, "uart1", "rts"), + MPP_FUNCTION(0x3, "uart0", "rts")), + MPP_MODE(41, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "ad2"), + MPP_FUNCTION(0x2, "uart1", "rxd")), + MPP_MODE(42, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "ad3"), + MPP_FUNCTION(0x2, "uart1", "txd")), + MPP_MODE(43, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "ad4"), + MPP_FUNCTION(0x2, "audio", "bclk")), + MPP_MODE(44, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "ad5"), + MPP_FUNCTION(0x2, "audio", "mclk")), + MPP_MODE(45, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "ad6"), + MPP_FUNCTION(0x2, "audio", "lrclk")), + MPP_MODE(46, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "ad7"), + MPP_FUNCTION(0x2, "audio", "sdo")), + MPP_MODE(47, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "ad8"), + MPP_FUNCTION(0x3, "sd0", "clk"), + MPP_FUNCTION(0x5, "audio", "spdifo")), + MPP_MODE(48, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "ad9"), + MPP_FUNCTION(0x2, "uart0", "rts"), + MPP_FUNCTION(0x3, "sd0", "cmd"), + MPP_FUNCTION(0x4, "sata1", "prsnt"), + MPP_FUNCTION(0x5, "spi0", "cs1")), + MPP_MODE(49, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "ad10"), + MPP_FUNCTION(0x2, "pcie", "clkreq1"), + MPP_FUNCTION(0x3, "sd0", "d0"), + MPP_FUNCTION(0x4, "spi1", "cs0"), + MPP_FUNCTION(0x5, "audio", "spdifi")), + MPP_MODE(50, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "ad11"), + MPP_FUNCTION(0x2, "uart0", "cts"), + MPP_FUNCTION(0x3, "sd0", "d1"), + MPP_FUNCTION(0x4, "spi1", "miso"), + MPP_FUNCTION(0x5, "audio", "rmclk")), + MPP_MODE(51, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "ad12"), + MPP_FUNCTION(0x2, "i2c1", "sda"), + MPP_FUNCTION(0x3, "sd0", "d2"), + MPP_FUNCTION(0x4, "spi1", "mosi")), + MPP_MODE(52, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "ad13"), + MPP_FUNCTION(0x2, "i2c1", "sck"), + MPP_FUNCTION(0x3, "sd0", "d3"), + MPP_FUNCTION(0x4, "spi1", "sck")), + MPP_MODE(53, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "ad14"), + MPP_FUNCTION(0x2, "sd0", "clk"), + MPP_FUNCTION(0x3, "tdm", "pclk"), + MPP_FUNCTION(0x4, "spi0", "cs2"), + MPP_FUNCTION(0x5, "pcie", "clkreq1")), + MPP_MODE(54, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "ad15"), + MPP_FUNCTION(0x3, "tdm", "dtx")), + MPP_MODE(55, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "cs1"), + MPP_FUNCTION(0x2, "uart1", "txd"), + MPP_FUNCTION(0x3, "tdm", "rst"), + MPP_FUNCTION(0x4, "sata1", "prsnt"), + MPP_FUNCTION(0x5, "sata0", "prsnt")), + MPP_MODE(56, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "cs2"), + MPP_FUNCTION(0x2, "uart1", "cts"), + MPP_FUNCTION(0x3, "uart0", "cts"), + MPP_FUNCTION(0x4, "spi0", "cs3"), + MPP_FUNCTION(0x5, "pcie", "clkreq0"), + MPP_FUNCTION(0x6, "spi1", "cs1")), + MPP_MODE(57, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "cs3"), + MPP_FUNCTION(0x2, "uart1", "rxd"), + MPP_FUNCTION(0x3, "tdm", "fsync"), + MPP_FUNCTION(0x4, "sata0", "prsnt"), + MPP_FUNCTION(0x5, "audio", "sdo")), + MPP_MODE(58, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "cs0"), + MPP_FUNCTION(0x2, "uart1", "rts"), + MPP_FUNCTION(0x3, "tdm", "int"), + MPP_FUNCTION(0x5, "audio", "extclk"), + MPP_FUNCTION(0x6, "uart0", "rts")), + MPP_MODE(59, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "ale0"), + MPP_FUNCTION(0x2, "uart1", "rts"), + MPP_FUNCTION(0x3, "uart0", "rts"), + MPP_FUNCTION(0x5, "audio", "bclk")), + MPP_MODE(60, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "ale1"), + MPP_FUNCTION(0x2, "uart1", "rxd"), + MPP_FUNCTION(0x3, "sata0", "prsnt"), + MPP_FUNCTION(0x4, "pcie", "rst-out"), + MPP_FUNCTION(0x5, "audio", "sdi")), + MPP_MODE(61, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "dev", "wen1"), + MPP_FUNCTION(0x2, "uart1", "txd"), + MPP_FUNCTION(0x5, "audio", "rclk")), + MPP_MODE(62, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "dev", "a2"), + MPP_FUNCTION(0x2, "uart1", "cts"), + MPP_FUNCTION(0x3, "tdm", "drx"), + MPP_FUNCTION(0x4, "pcie", "clkreq0"), + MPP_FUNCTION(0x5, "audio", "mclk"), + MPP_FUNCTION(0x6, "uart0", "cts")), + MPP_MODE(63, + MPP_FUNCTION(0x0, "gpo", NULL), + MPP_FUNCTION(0x1, "spi0", "sck"), + MPP_FUNCTION(0x2, "tclk", NULL)), + MPP_MODE(64, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "spi0", "miso"), + MPP_FUNCTION(0x2, "spi0-1", "cs1")), + MPP_MODE(65, + MPP_FUNCTION(0x0, "gpio", NULL), + MPP_FUNCTION(0x1, "spi0", "mosi"), + MPP_FUNCTION(0x2, "spi0-1", "cs2")), +}; + +static struct mvebu_pinctrl_soc_info armada_370_pinctrl_info; + +static struct of_device_id armada_370_pinctrl_of_match[] __devinitdata = { + { .compatible = "marvell,mv88f6710-pinctrl" }, + { }, +}; + +static struct mvebu_mpp_ctrl mv88f6710_mpp_controls[] = { + MPP_REG_CTRL(0, 65), +}; + +static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = { + MPP_GPIO_RANGE(0, 0, 0, 32), + MPP_GPIO_RANGE(1, 32, 32, 32), + MPP_GPIO_RANGE(2, 64, 64, 2), +}; + +static int __devinit armada_370_pinctrl_probe(struct platform_device *pdev) +{ + struct mvebu_pinctrl_soc_info *soc = &armada_370_pinctrl_info; + + soc->variant = 0; /* no variants for Armada 370 */ + soc->controls = mv88f6710_mpp_controls; + soc->ncontrols = ARRAY_SIZE(mv88f6710_mpp_controls); + soc->modes = mv88f6710_mpp_modes; + soc->nmodes = ARRAY_SIZE(mv88f6710_mpp_modes); + soc->gpioranges = mv88f6710_mpp_gpio_ranges; + soc->ngpioranges = ARRAY_SIZE(mv88f6710_mpp_gpio_ranges); + + pdev->dev.platform_data = soc; + + return mvebu_pinctrl_probe(pdev); +} + +static int __devexit armada_370_pinctrl_remove(struct platform_device *pdev) +{ + return mvebu_pinctrl_remove(pdev); +} + +static struct platform_driver armada_370_pinctrl_driver = { + .driver = { + .name = "armada-370-pinctrl", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(armada_370_pinctrl_of_match), + }, + .probe = armada_370_pinctrl_probe, + .remove = __devexit_p(armada_370_pinctrl_remove), +}; + +module_platform_driver(armada_370_pinctrl_driver); + +MODULE_AUTHOR("Thomas Petazzoni "); +MODULE_DESCRIPTION("Marvell Armada 370 pinctrl driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c new file mode 100644 index 00000000000..40bd52a46b4 --- /dev/null +++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c @@ -0,0 +1,468 @@ +/* + * Marvell Armada XP pinctrl driver based on mvebu pinctrl core + * + * Copyright (C) 2012 Marvell + * + * Thomas Petazzoni + * + * 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. + * + * This file supports the three variants of Armada XP SoCs that are + * available: mv78230, mv78260 and mv78460. From a pin muxing + * perspective, the mv78230 has 49 MPP pins. The mv78260 and mv78460 + * both have 67 MPP pins (more GPIOs and address lines for the memory + * bus mainly). The only difference between the mv78260 and the + * mv78460 in terms of pin muxing is the addition of two functions on + * pins 43 and 56 to access the VDD of the CPU2 and 3 (mv78260 has two + * cores, mv78460 has four cores). + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pinctrl-mvebu.h" + +enum armada_xp_variant { + V_MV78230 = BIT(0), + V_MV78260 = BIT(1), + V_MV78460 = BIT(2), + V_MV78230_PLUS = (V_MV78230 | V_MV78260 | V_MV78460), + V_MV78260_PLUS = (V_MV78260 | V_MV78460), +}; + +static struct mvebu_mpp_mode armada_xp_mpp_modes[] = { + MPP_MODE(0, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "txclko", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d0", V_MV78230_PLUS)), + MPP_MODE(1, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "txd0", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d1", V_MV78230_PLUS)), + MPP_MODE(2, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "txd1", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d2", V_MV78230_PLUS)), + MPP_MODE(3, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "txd2", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d3", V_MV78230_PLUS)), + MPP_MODE(4, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "txd3", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d4", V_MV78230_PLUS)), + MPP_MODE(5, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "txctl", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d5", V_MV78230_PLUS)), + MPP_MODE(6, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "rxd0", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d6", V_MV78230_PLUS)), + MPP_MODE(7, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "rxd1", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d7", V_MV78230_PLUS)), + MPP_MODE(8, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "rxd2", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d8", V_MV78230_PLUS)), + MPP_MODE(9, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "rxd3", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d9", V_MV78230_PLUS)), + MPP_MODE(10, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "rxctl", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d10", V_MV78230_PLUS)), + MPP_MODE(11, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "rxclk", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d11", V_MV78230_PLUS)), + MPP_MODE(12, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "txd4", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "ge1", "clkout", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d12", V_MV78230_PLUS)), + MPP_MODE(13, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "txd5", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "ge1", "txd0", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d13", V_MV78230_PLUS)), + MPP_MODE(14, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "txd6", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "ge1", "txd1", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d14", V_MV78230_PLUS)), + MPP_MODE(15, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "txd7", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "ge1", "txd2", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d15", V_MV78230_PLUS)), + MPP_MODE(16, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "txclk", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "ge1", "txd3", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d16", V_MV78230_PLUS)), + MPP_MODE(17, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "col", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "ge1", "txctl", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d17", V_MV78230_PLUS)), + MPP_MODE(18, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "rxerr", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "ge1", "rxd0", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "ptp", "trig", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d18", V_MV78230_PLUS)), + MPP_MODE(19, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "crs", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "ge1", "rxd1", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "ptp", "evreq", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d19", V_MV78230_PLUS)), + MPP_MODE(20, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "rxd4", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "ge1", "rxd2", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "ptp", "clk", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d20", V_MV78230_PLUS)), + MPP_MODE(21, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "rxd5", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "ge1", "rxd3", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "mem", "bat", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d21", V_MV78230_PLUS)), + MPP_MODE(22, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "rxd6", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "ge1", "rxctl", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "sata0", "prsnt", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d22", V_MV78230_PLUS)), + MPP_MODE(23, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ge0", "rxd7", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "ge1", "rxclk", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "sata1", "prsnt", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "d23", V_MV78230_PLUS)), + MPP_MODE(24, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "sata1", "prsnt", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "nf", "bootcs-re", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "rst", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "hsync", V_MV78230_PLUS)), + MPP_MODE(25, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "sata0", "prsnt", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "nf", "bootcs-we", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "pclk", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "vsync", V_MV78230_PLUS)), + MPP_MODE(26, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "fsync", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "clk", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)), + MPP_MODE(27, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ptp", "trig", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "dtx", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "e", V_MV78230_PLUS)), + MPP_MODE(28, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ptp", "evreq", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "drx", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "pwm", V_MV78230_PLUS)), + MPP_MODE(29, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "ptp", "clk", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "int0", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "ref-clk", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)), + MPP_MODE(30, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "sd0", "clk", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "int1", V_MV78230_PLUS)), + MPP_MODE(31, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "sd0", "cmd", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "int2", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)), + MPP_MODE(32, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "sd0", "d0", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "int3", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)), + MPP_MODE(33, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "sd0", "d1", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "int4", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "mem", "bat", V_MV78230_PLUS)), + MPP_MODE(34, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "sd0", "d2", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "sata0", "prsnt", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "int5", V_MV78230_PLUS)), + MPP_MODE(35, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "sd0", "d3", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "sata1", "prsnt", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "int6", V_MV78230_PLUS)), + MPP_MODE(36, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "spi", "mosi", V_MV78230_PLUS)), + MPP_MODE(37, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "spi", "miso", V_MV78230_PLUS)), + MPP_MODE(38, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "spi", "sck", V_MV78230_PLUS)), + MPP_MODE(39, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "spi", "cs0", V_MV78230_PLUS)), + MPP_MODE(40, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "spi", "cs1", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "uart2", "cts", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "vdd", "cpu1-pd", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "vga-hsync", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x5, "pcie", "clkreq0", V_MV78230_PLUS)), + MPP_MODE(41, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "spi", "cs2", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "uart2", "rts", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "sata1", "prsnt", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "lcd", "vga-vsync", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x5, "pcie", "clkreq1", V_MV78230_PLUS)), + MPP_MODE(42, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "uart2", "rxd", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "uart0", "cts", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "tdm", "int7", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "tdm-1", "timer", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)), + MPP_MODE(43, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "uart2", "txd", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "uart0", "rts", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "spi", "cs3", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "pcie", "rstout", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x5, "vdd", "cpu2-3-pd", V_MV78460)), + MPP_MODE(44, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "uart2", "cts", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "uart3", "rxd", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "spi", "cs4", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "mem", "bat", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x5, "pcie", "clkreq2", V_MV78230_PLUS)), + MPP_MODE(45, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "uart2", "rts", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "uart3", "txd", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "spi", "cs5", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V_MV78230_PLUS)), + MPP_MODE(46, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "uart3", "rts", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "uart1", "rts", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "spi", "cs6", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V_MV78230_PLUS)), + MPP_MODE(47, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "uart3", "cts", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "uart1", "cts", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x3, "spi", "cs7", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x4, "ref", "clkout", V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x5, "pcie", "clkreq3", V_MV78230_PLUS)), + MPP_MODE(48, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x1, "tclk", NULL, V_MV78230_PLUS), + MPP_VAR_FUNCTION(0x2, "dev", "burst/last", V_MV78230_PLUS)), + MPP_MODE(49, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "we3", V_MV78260_PLUS)), + MPP_MODE(50, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "we2", V_MV78260_PLUS)), + MPP_MODE(51, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad16", V_MV78260_PLUS)), + MPP_MODE(52, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad17", V_MV78260_PLUS)), + MPP_MODE(53, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad18", V_MV78260_PLUS)), + MPP_MODE(54, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad19", V_MV78260_PLUS)), + MPP_MODE(55, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad20", V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x2, "vdd", "cpu0-pd", V_MV78260_PLUS)), + MPP_MODE(56, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad21", V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x2, "vdd", "cpu1-pd", V_MV78260_PLUS)), + MPP_MODE(57, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad22", V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x2, "vdd", "cpu2-3-pd", V_MV78460)), + MPP_MODE(58, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad23", V_MV78260_PLUS)), + MPP_MODE(59, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad24", V_MV78260_PLUS)), + MPP_MODE(60, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad25", V_MV78260_PLUS)), + MPP_MODE(61, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad26", V_MV78260_PLUS)), + MPP_MODE(62, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad27", V_MV78260_PLUS)), + MPP_MODE(63, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad28", V_MV78260_PLUS)), + MPP_MODE(64, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad29", V_MV78260_PLUS)), + MPP_MODE(65, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad30", V_MV78260_PLUS)), + MPP_MODE(66, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), + MPP_VAR_FUNCTION(0x1, "dev", "ad31", V_MV78260_PLUS)), +}; + +static struct mvebu_pinctrl_soc_info armada_xp_pinctrl_info; + +static struct of_device_id armada_xp_pinctrl_of_match[] __devinitdata = { + { + .compatible = "marvell,mv78230-pinctrl", + .data = (void *) V_MV78230, + }, + { + .compatible = "marvell,mv78260-pinctrl", + .data = (void *) V_MV78260, + }, + { + .compatible = "marvell,mv78460-pinctrl", + .data = (void *) V_MV78460, + }, + { }, +}; + +static struct mvebu_mpp_ctrl mv78230_mpp_controls[] = { + MPP_REG_CTRL(0, 48), +}; + +static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = { + MPP_GPIO_RANGE(0, 0, 0, 32), + MPP_GPIO_RANGE(1, 32, 32, 17), +}; + +static struct mvebu_mpp_ctrl mv78260_mpp_controls[] = { + MPP_REG_CTRL(0, 66), +}; + +static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = { + MPP_GPIO_RANGE(0, 0, 0, 32), + MPP_GPIO_RANGE(1, 32, 32, 32), + MPP_GPIO_RANGE(2, 64, 64, 3), +}; + +static struct mvebu_mpp_ctrl mv78460_mpp_controls[] = { + MPP_REG_CTRL(0, 66), +}; + +static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = { + MPP_GPIO_RANGE(0, 0, 0, 32), + MPP_GPIO_RANGE(1, 32, 32, 32), + MPP_GPIO_RANGE(2, 64, 64, 3), +}; + +static int __devinit armada_xp_pinctrl_probe(struct platform_device *pdev) +{ + struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info; + const struct of_device_id *match = + of_match_device(armada_xp_pinctrl_of_match, &pdev->dev); + + if (!match) + return -ENODEV; + + soc->variant = (unsigned) match->data & 0xff; + + switch (soc->variant) { + case V_MV78230: + soc->controls = mv78230_mpp_controls; + soc->ncontrols = ARRAY_SIZE(mv78230_mpp_controls); + soc->modes = armada_xp_mpp_modes; + /* We don't necessarily want the full list of the + * armada_xp_mpp_modes, but only the first 'n' ones + * that are available on this SoC */ + soc->nmodes = mv78230_mpp_controls[0].npins; + soc->gpioranges = mv78230_mpp_gpio_ranges; + soc->ngpioranges = ARRAY_SIZE(mv78230_mpp_gpio_ranges); + break; + case V_MV78260: + soc->controls = mv78260_mpp_controls; + soc->ncontrols = ARRAY_SIZE(mv78260_mpp_controls); + soc->modes = armada_xp_mpp_modes; + /* We don't necessarily want the full list of the + * armada_xp_mpp_modes, but only the first 'n' ones + * that are available on this SoC */ + soc->nmodes = mv78260_mpp_controls[0].npins; + soc->gpioranges = mv78260_mpp_gpio_ranges; + soc->ngpioranges = ARRAY_SIZE(mv78260_mpp_gpio_ranges); + break; + case V_MV78460: + soc->controls = mv78460_mpp_controls; + soc->ncontrols = ARRAY_SIZE(mv78460_mpp_controls); + soc->modes = armada_xp_mpp_modes; + /* We don't necessarily want the full list of the + * armada_xp_mpp_modes, but only the first 'n' ones + * that are available on this SoC */ + soc->nmodes = mv78460_mpp_controls[0].npins; + soc->gpioranges = mv78460_mpp_gpio_ranges; + soc->ngpioranges = ARRAY_SIZE(mv78460_mpp_gpio_ranges); + break; + } + + pdev->dev.platform_data = soc; + + return mvebu_pinctrl_probe(pdev); +} + +static int __devexit armada_xp_pinctrl_remove(struct platform_device *pdev) +{ + return mvebu_pinctrl_remove(pdev); +} + +static struct platform_driver armada_xp_pinctrl_driver = { + .driver = { + .name = "armada-xp-pinctrl", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(armada_xp_pinctrl_of_match), + }, + .probe = armada_xp_pinctrl_probe, + .remove = __devexit_p(armada_xp_pinctrl_remove), +}; + +module_platform_driver(armada_xp_pinctrl_driver); + +MODULE_AUTHOR("Thomas Petazzoni "); +MODULE_DESCRIPTION("Marvell Armada XP pinctrl driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/mvebu/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c new file mode 100644 index 00000000000..ffe74b27d66 --- /dev/null +++ b/drivers/pinctrl/mvebu/pinctrl-dove.c @@ -0,0 +1,620 @@ +/* + * Marvell Dove pinctrl driver based on mvebu pinctrl core + * + * Author: Sebastian Hesselbarth + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pinctrl-mvebu.h" + +#define DOVE_SB_REGS_VIRT_BASE 0xfde00000 +#define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0200) +#define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10) +#define DOVE_AU0_AC97_SEL BIT(16) +#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE | 0xe802C) +#define DOVE_TWSI_ENABLE_OPTION1 BIT(7) +#define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE | 0xe8030) +#define DOVE_TWSI_ENABLE_OPTION2 BIT(20) +#define DOVE_TWSI_ENABLE_OPTION3 BIT(21) +#define DOVE_TWSI_OPTION3_GPIO BIT(22) +#define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE | 0xe8034) +#define DOVE_SSP_ON_AU1 BIT(0) +#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c) +#define DOVE_AU1_SPDIFO_GPIO_EN BIT(1) +#define DOVE_NAND_GPIO_EN BIT(0) +#define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0400) +#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40) +#define DOVE_SPI_GPIO_SEL BIT(5) +#define DOVE_UART1_GPIO_SEL BIT(4) +#define DOVE_AU1_GPIO_SEL BIT(3) +#define DOVE_CAM_GPIO_SEL BIT(2) +#define DOVE_SD1_GPIO_SEL BIT(1) +#define DOVE_SD0_GPIO_SEL BIT(0) + +#define MPPS_PER_REG 8 +#define MPP_BITS 4 +#define MPP_MASK 0xf + +#define CONFIG_PMU BIT(4) + +static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl *ctrl, + unsigned long *config) +{ + unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS; + unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS; + unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); + unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off); + + if (pmu & (1 << ctrl->pid)) + *config = CONFIG_PMU; + else + *config = (mpp >> shift) & MPP_MASK; + return 0; +} + +static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl, + unsigned long config) +{ + unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS; + unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS; + unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); + unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off); + + if (config == CONFIG_PMU) + writel(pmu | (1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL); + else { + writel(pmu & ~(1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL); + mpp &= ~(MPP_MASK << shift); + mpp |= config << shift; + writel(mpp, DOVE_MPP_VIRT_BASE + off); + } + return 0; +} + +static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl, + unsigned long *config) +{ + unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); + unsigned long mask; + + switch (ctrl->pid) { + case 24: /* mpp_camera */ + mask = DOVE_CAM_GPIO_SEL; + break; + case 40: /* mpp_sdio0 */ + mask = DOVE_SD0_GPIO_SEL; + break; + case 46: /* mpp_sdio1 */ + mask = DOVE_SD1_GPIO_SEL; + break; + case 58: /* mpp_spi0 */ + mask = DOVE_SPI_GPIO_SEL; + break; + case 62: /* mpp_uart1 */ + mask = DOVE_UART1_GPIO_SEL; + break; + default: + return -EINVAL; + } + + *config = ((mpp4 & mask) != 0); + + return 0; +} + +static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl, + unsigned long config) +{ + unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); + unsigned long mask; + + switch (ctrl->pid) { + case 24: /* mpp_camera */ + mask = DOVE_CAM_GPIO_SEL; + break; + case 40: /* mpp_sdio0 */ + mask = DOVE_SD0_GPIO_SEL; + break; + case 46: /* mpp_sdio1 */ + mask = DOVE_SD1_GPIO_SEL; + break; + case 58: /* mpp_spi0 */ + mask = DOVE_SPI_GPIO_SEL; + break; + case 62: /* mpp_uart1 */ + mask = DOVE_UART1_GPIO_SEL; + break; + default: + return -EINVAL; + } + + mpp4 &= ~mask; + if (config) + mpp4 |= mask; + + writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE); + + return 0; +} + +static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl, + unsigned long *config) +{ + unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); + + *config = ((gmpp & DOVE_NAND_GPIO_EN) != 0); + + return 0; +} + +static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl, + unsigned long config) +{ + unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); + + gmpp &= ~DOVE_NAND_GPIO_EN; + if (config) + gmpp |= DOVE_NAND_GPIO_EN; + + writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE); + + return 0; +} + +static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl, + unsigned long *config) +{ + unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); + + *config = ((pmu & DOVE_AU0_AC97_SEL) != 0); + + return 0; +} + +static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl, + unsigned long config) +{ + unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); + + pmu &= ~DOVE_AU0_AC97_SEL; + if (config) + pmu |= DOVE_AU0_AC97_SEL; + writel(pmu, DOVE_PMU_MPP_GENERAL_CTRL); + + return 0; +} + +static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl, + unsigned long *config) +{ + unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); + unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1); + unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); + unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); + + *config = 0; + if (mpp4 & DOVE_AU1_GPIO_SEL) + *config |= BIT(3); + if (sspc1 & DOVE_SSP_ON_AU1) + *config |= BIT(2); + if (gmpp & DOVE_AU1_SPDIFO_GPIO_EN) + *config |= BIT(1); + if (gcfg2 & DOVE_TWSI_OPTION3_GPIO) + *config |= BIT(0); + + /* SSP/TWSI only if I2S1 not set*/ + if ((*config & BIT(3)) == 0) + *config &= ~(BIT(2) | BIT(0)); + /* TWSI only if SPDIFO not set*/ + if ((*config & BIT(1)) == 0) + *config &= ~BIT(0); + return 0; +} + +static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl, + unsigned long config) +{ + unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); + unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1); + unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); + unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); + + if (config & BIT(0)) + gcfg2 |= DOVE_TWSI_OPTION3_GPIO; + if (config & BIT(1)) + gmpp |= DOVE_AU1_SPDIFO_GPIO_EN; + if (config & BIT(2)) + sspc1 |= DOVE_SSP_ON_AU1; + if (config & BIT(3)) + mpp4 |= DOVE_AU1_GPIO_SEL; + + writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE); + writel(sspc1, DOVE_SSP_CTRL_STATUS_1); + writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE); + writel(gcfg2, DOVE_GLOBAL_CONFIG_2); + + return 0; +} + +/* mpp[52:57] gpio pins depend heavily on current config; + * gpio_req does not try to mux in gpio capabilities to not + * break other functions. If you require all mpps as gpio + * enforce gpio setting by pinctrl mapping. + */ +static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid) +{ + unsigned long config; + + dove_audio1_ctrl_get(ctrl, &config); + + switch (config) { + case 0x02: /* i2s1 : gpio[56:57] */ + case 0x0e: /* ssp : gpio[56:57] */ + if (pid >= 56) + return 0; + return -ENOTSUPP; + case 0x08: /* spdifo : gpio[52:55] */ + case 0x0b: /* twsi : gpio[52:55] */ + if (pid <= 55) + return 0; + return -ENOTSUPP; + case 0x0a: /* all gpio */ + return 0; + /* 0x00 : i2s1/spdifo : no gpio */ + /* 0x0c : ssp/spdifo : no gpio */ + /* 0x0f : ssp/twsi : no gpio */ + } + return -ENOTSUPP; +} + +/* mpp[52:57] has gpio pins capable of in and out */ +static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl *ctrl, u8 pid, + bool input) +{ + if (pid < 52 || pid > 57) + return -ENOTSUPP; + return 0; +} + +static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl, + unsigned long *config) +{ + unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1); + unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); + + *config = 0; + if (gcfg1 & DOVE_TWSI_ENABLE_OPTION1) + *config = 1; + else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION2) + *config = 2; + else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION3) + *config = 3; + + return 0; +} + +static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl, + unsigned long config) +{ + unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1); + unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); + + gcfg1 &= ~DOVE_TWSI_ENABLE_OPTION1; + gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION2); + + switch (config) { + case 1: + gcfg1 |= DOVE_TWSI_ENABLE_OPTION1; + break; + case 2: + gcfg2 |= DOVE_TWSI_ENABLE_OPTION2; + break; + case 3: + gcfg2 |= DOVE_TWSI_ENABLE_OPTION3; + break; + } + + writel(gcfg1, DOVE_GLOBAL_CONFIG_1); + writel(gcfg2, DOVE_GLOBAL_CONFIG_2); + + return 0; +} + +static struct mvebu_mpp_ctrl dove_mpp_controls[] = { + MPP_FUNC_CTRL(0, 0, "mpp0", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(1, 1, "mpp1", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(2, 2, "mpp2", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(3, 3, "mpp3", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(4, 4, "mpp4", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(5, 5, "mpp5", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(6, 6, "mpp6", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(7, 7, "mpp7", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(8, 8, "mpp8", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(9, 9, "mpp9", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(10, 10, "mpp10", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(11, 11, "mpp11", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(12, 12, "mpp12", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(13, 13, "mpp13", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(14, 14, "mpp14", dove_pmu_mpp_ctrl), + MPP_FUNC_CTRL(15, 15, "mpp15", dove_pmu_mpp_ctrl), + MPP_REG_CTRL(16, 23), + MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl), + MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl), + MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl), + MPP_FUNC_GPIO_CTRL(52, 57, "mpp_audio1", dove_audio1_ctrl), + MPP_FUNC_CTRL(58, 61, "mpp_spi0", dove_mpp4_ctrl), + MPP_FUNC_CTRL(62, 63, "mpp_uart1", dove_mpp4_ctrl), + MPP_FUNC_CTRL(64, 71, "mpp_nand", dove_nand_ctrl), + MPP_FUNC_CTRL(72, 72, "audio0", dove_audio0_ctrl), + MPP_FUNC_CTRL(73, 73, "twsi", dove_twsi_ctrl), +}; + +static struct mvebu_mpp_mode dove_mpp_modes[] = { + MPP_MODE(0, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "uart2", "rts"), + MPP_FUNCTION(0x03, "sdio0", "cd"), + MPP_FUNCTION(0x0f, "lcd0", "pwm"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(1, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "uart2", "cts"), + MPP_FUNCTION(0x03, "sdio0", "wp"), + MPP_FUNCTION(0x0f, "lcd1", "pwm"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(2, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x01, "sata", "prsnt"), + MPP_FUNCTION(0x02, "uart2", "txd"), + MPP_FUNCTION(0x03, "sdio0", "buspwr"), + MPP_FUNCTION(0x04, "uart1", "rts"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(3, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x01, "sata", "act"), + MPP_FUNCTION(0x02, "uart2", "rxd"), + MPP_FUNCTION(0x03, "sdio0", "ledctrl"), + MPP_FUNCTION(0x04, "uart1", "cts"), + MPP_FUNCTION(0x0f, "lcd-spi", "cs1"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(4, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "uart3", "rts"), + MPP_FUNCTION(0x03, "sdio1", "cd"), + MPP_FUNCTION(0x04, "spi1", "miso"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(5, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "uart3", "cts"), + MPP_FUNCTION(0x03, "sdio1", "wp"), + MPP_FUNCTION(0x04, "spi1", "cs"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(6, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "uart3", "txd"), + MPP_FUNCTION(0x03, "sdio1", "buspwr"), + MPP_FUNCTION(0x04, "spi1", "mosi"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(7, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "uart3", "rxd"), + MPP_FUNCTION(0x03, "sdio1", "ledctrl"), + MPP_FUNCTION(0x04, "spi1", "sck"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(8, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x01, "watchdog", "rstout"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(9, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x05, "pex1", "clkreq"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(10, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x05, "ssp", "sclk"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(11, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x01, "sata", "prsnt"), + MPP_FUNCTION(0x02, "sata-1", "act"), + MPP_FUNCTION(0x03, "sdio0", "ledctrl"), + MPP_FUNCTION(0x04, "sdio1", "ledctrl"), + MPP_FUNCTION(0x05, "pex0", "clkreq"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(12, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x01, "sata", "act"), + MPP_FUNCTION(0x02, "uart2", "rts"), + MPP_FUNCTION(0x03, "audio0", "extclk"), + MPP_FUNCTION(0x04, "sdio1", "cd"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(13, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "uart2", "cts"), + MPP_FUNCTION(0x03, "audio1", "extclk"), + MPP_FUNCTION(0x04, "sdio1", "wp"), + MPP_FUNCTION(0x05, "ssp", "extclk"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(14, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "uart2", "txd"), + MPP_FUNCTION(0x04, "sdio1", "buspwr"), + MPP_FUNCTION(0x05, "ssp", "rxd"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(15, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "uart2", "rxd"), + MPP_FUNCTION(0x04, "sdio1", "ledctrl"), + MPP_FUNCTION(0x05, "ssp", "sfrm"), + MPP_FUNCTION(0x10, "pmu", NULL)), + MPP_MODE(16, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "uart3", "rts"), + MPP_FUNCTION(0x03, "sdio0", "cd"), + MPP_FUNCTION(0x04, "lcd-spi", "cs1"), + MPP_FUNCTION(0x05, "ac97", "sdi1")), + MPP_MODE(17, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x01, "ac97-1", "sysclko"), + MPP_FUNCTION(0x02, "uart3", "cts"), + MPP_FUNCTION(0x03, "sdio0", "wp"), + MPP_FUNCTION(0x04, "twsi", "sda"), + MPP_FUNCTION(0x05, "ac97", "sdi2")), + MPP_MODE(18, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "uart3", "txd"), + MPP_FUNCTION(0x03, "sdio0", "buspwr"), + MPP_FUNCTION(0x04, "lcd0", "pwm"), + MPP_FUNCTION(0x05, "ac97", "sdi3")), + MPP_MODE(19, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "uart3", "rxd"), + MPP_FUNCTION(0x03, "sdio0", "ledctrl"), + MPP_FUNCTION(0x04, "twsi", "sck")), + MPP_MODE(20, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x01, "ac97", "sysclko"), + MPP_FUNCTION(0x02, "lcd-spi", "miso"), + MPP_FUNCTION(0x03, "sdio1", "cd"), + MPP_FUNCTION(0x05, "sdio0", "cd"), + MPP_FUNCTION(0x06, "spi1", "miso")), + MPP_MODE(21, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x01, "uart1", "rts"), + MPP_FUNCTION(0x02, "lcd-spi", "cs0"), + MPP_FUNCTION(0x03, "sdio1", "wp"), + MPP_FUNCTION(0x04, "ssp", "sfrm"), + MPP_FUNCTION(0x05, "sdio0", "wp"), + MPP_FUNCTION(0x06, "spi1", "cs")), + MPP_MODE(22, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x01, "uart1", "cts"), + MPP_FUNCTION(0x02, "lcd-spi", "mosi"), + MPP_FUNCTION(0x03, "sdio1", "buspwr"), + MPP_FUNCTION(0x04, "ssp", "txd"), + MPP_FUNCTION(0x05, "sdio0", "buspwr"), + MPP_FUNCTION(0x06, "spi1", "mosi")), + MPP_MODE(23, + MPP_FUNCTION(0x00, "gpio", NULL), + MPP_FUNCTION(0x02, "lcd-spi", "sck"), + MPP_FUNCTION(0x03, "sdio1", "ledctrl"), + MPP_FUNCTION(0x04, "ssp", "sclk"), + MPP_FUNCTION(0x05, "sdio0", "ledctrl"), + MPP_FUNCTION(0x06, "spi1", "sck")), + MPP_MODE(24, + MPP_FUNCTION(0x00, "camera", NULL), + MPP_FUNCTION(0x01, "gpio", NULL)), + MPP_MODE(40, + MPP_FUNCTION(0x00, "sdio0", NULL), + MPP_FUNCTION(0x01, "gpio", NULL)), + MPP_MODE(46, + MPP_FUNCTION(0x00, "sdio1", NULL), + MPP_FUNCTION(0x01, "gpio", NULL)), + MPP_MODE(52, + MPP_FUNCTION(0x00, "i2s1/spdifo", NULL), + MPP_FUNCTION(0x02, "i2s1", NULL), + MPP_FUNCTION(0x08, "spdifo", NULL), + MPP_FUNCTION(0x0a, "gpio", NULL), + MPP_FUNCTION(0x0b, "twsi", NULL), + MPP_FUNCTION(0x0c, "ssp/spdifo", NULL), + MPP_FUNCTION(0x0e, "ssp", NULL), + MPP_FUNCTION(0x0f, "ssp/twsi", NULL)), + MPP_MODE(58, + MPP_FUNCTION(0x00, "spi0", NULL), + MPP_FUNCTION(0x01, "gpio", NULL)), + MPP_MODE(62, + MPP_FUNCTION(0x00, "uart1", NULL), + MPP_FUNCTION(0x01, "gpio", NULL)), + MPP_MODE(64, + MPP_FUNCTION(0x00, "nand", NULL), + MPP_FUNCTION(0x01, "gpo", NULL)), + MPP_MODE(72, + MPP_FUNCTION(0x00, "i2s", NULL), + MPP_FUNCTION(0x01, "ac97", NULL)), + MPP_MODE(73, + MPP_FUNCTION(0x00, "twsi-none", NULL), + MPP_FUNCTION(0x01, "twsi-opt1", NULL), + MPP_FUNCTION(0x02, "twsi-opt2", NULL), + MPP_FUNCTION(0x03, "twsi-opt3", NULL)), +}; + +static struct pinctrl_gpio_range dove_mpp_gpio_ranges[] = { + MPP_GPIO_RANGE(0, 0, 0, 32), + MPP_GPIO_RANGE(1, 32, 32, 32), + MPP_GPIO_RANGE(2, 64, 64, 8), +}; + +static struct mvebu_pinctrl_soc_info dove_pinctrl_info = { + .controls = dove_mpp_controls, + .ncontrols = ARRAY_SIZE(dove_mpp_controls), + .modes = dove_mpp_modes, + .nmodes = ARRAY_SIZE(dove_mpp_modes), + .gpioranges = dove_mpp_gpio_ranges, + .ngpioranges = ARRAY_SIZE(dove_mpp_gpio_ranges), + .variant = 0, +}; + +static struct clk *clk; + +static struct of_device_id dove_pinctrl_of_match[] __devinitdata = { + { .compatible = "marvell,dove-pinctrl", .data = &dove_pinctrl_info }, + { } +}; + +static int __devinit dove_pinctrl_probe(struct platform_device *pdev) +{ + const struct of_device_id *match = + of_match_device(dove_pinctrl_of_match, &pdev->dev); + pdev->dev.platform_data = match->data; + + /* + * General MPP Configuration Register is part of pdma registers. + * grab clk to make sure it is ticking. + */ + clk = devm_clk_get(&pdev->dev, NULL); + if (!IS_ERR(clk)) + clk_prepare_enable(clk); + + return mvebu_pinctrl_probe(pdev); +} + +static int __devexit dove_pinctrl_remove(struct platform_device *pdev) +{ + int ret; + + ret = mvebu_pinctrl_remove(pdev); + if (!IS_ERR(clk)) + clk_disable_unprepare(clk); + return ret; +} + +static struct platform_driver dove_pinctrl_driver = { + .driver = { + .name = "dove-pinctrl", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(dove_pinctrl_of_match), + }, + .probe = dove_pinctrl_probe, + .remove = __devexit_p(dove_pinctrl_remove), +}; + +module_platform_driver(dove_pinctrl_driver); + +MODULE_AUTHOR("Sebastian Hesselbarth "); +MODULE_DESCRIPTION("Marvell Dove pinctrl driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/mvebu/pinctrl-kirkwood.c b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c new file mode 100644 index 00000000000..9a74ef674a0 --- /dev/null +++ b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c @@ -0,0 +1,472 @@ +/* + * Marvell Kirkwood pinctrl driver based on mvebu pinctrl core + * + * Author: Sebastian Hesselbarth + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pinctrl-mvebu.h" + +#define V(f6180, f6190, f6192, f6281, f6282) \ + ((f6180 << 0) | (f6190 << 1) | (f6192 << 2) | \ + (f6281 << 3) | (f6282 << 4)) + +enum kirkwood_variant { + VARIANT_MV88F6180 = V(1, 0, 0, 0, 0), + VARIANT_MV88F6190 = V(0, 1, 0, 0, 0), + VARIANT_MV88F6192 = V(0, 0, 1, 0, 0), + VARIANT_MV88F6281 = V(0, 0, 0, 1, 0), + VARIANT_MV88F6282 = V(0, 0, 0, 0, 1), +}; + +static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = { + MPP_MODE(0, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "nand", "io2", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1))), + MPP_MODE(1, + MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "nand", "io3", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "spi", "mosi", V(1, 1, 1, 1, 1))), + MPP_MODE(2, + MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "nand", "io4", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1))), + MPP_MODE(3, + MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "nand", "io5", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1))), + MPP_MODE(4, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "nand", "io6", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "uart0", "rxd", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1)), + MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0))), + MPP_MODE(5, + MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "nand", "io7", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "uart0", "txd", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "ptp", "trig", V(1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1))), + MPP_MODE(6, + MPP_VAR_FUNCTION(0x0, "sysrst", "out", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "spi", "mosi", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "ptp", "trig", V(1, 1, 1, 1, 0))), + MPP_MODE(7, + MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "pex", "rsto", V(1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ptp", "trig", V(1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1))), + MPP_MODE(8, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "twsi0", "sda", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "uart1", "rts", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "mii-1", "rxerr", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0xc, "ptp", "clk", V(1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1))), + MPP_MODE(9, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "twsi0", "sck", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "uart1", "cts", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xc, "ptp", "evreq", V(1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1))), + MPP_MODE(10, + MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0X3, "uart0", "txd", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0xc, "ptp", "trig", V(1, 1, 1, 1, 0))), + MPP_MODE(11, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "uart0", "rxd", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "ptp-1", "evreq", V(1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0xc, "ptp-2", "trig", V(1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1))), + MPP_MODE(12, + MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 0, 1)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0)), + MPP_VAR_FUNCTION(0x1, "sdio", "clk", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xa, "audio", "spdifo", V(0, 0, 0, 0, 1)), + MPP_VAR_FUNCTION(0xb, "spi", "mosi", V(0, 0, 0, 0, 1)), + MPP_VAR_FUNCTION(0xd, "twsi1", "sda", V(0, 0, 0, 0, 1))), + MPP_MODE(13, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "sdio", "cmd", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xa, "audio", "rmclk", V(0, 0, 0, 0, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1))), + MPP_MODE(14, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "sdio", "d0", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0xa, "audio", "spdifi", V(0, 0, 0, 0, 1)), + MPP_VAR_FUNCTION(0xb, "audio-1", "sdi", V(0, 0, 0, 0, 1)), + MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1))), + MPP_MODE(15, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "sdio", "d1", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "sata0", "act", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "spi", "cs", V(0, 0, 0, 0, 1))), + MPP_MODE(16, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "sdio", "d2", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "sata1", "act", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "extclk", V(0, 0, 0, 0, 1)), + MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1))), + MPP_MODE(17, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "sdio", "d3", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xa, "sata1", "act", V(0, 0, 0, 0, 1)), + MPP_VAR_FUNCTION(0xd, "twsi1", "sck", V(0, 0, 0, 0, 1))), + MPP_MODE(18, + MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "nand", "io0", V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "pex", "clkreq", V(0, 0, 0, 0, 1))), + MPP_MODE(19, + MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "nand", "io1", V(1, 1, 1, 1, 1))), + MPP_MODE(20, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "txd0", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d0", V(0, 0, 0, 0, 1)), + MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 0, 0, 0, 0))), + MPP_MODE(21, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "txd1", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d1", V(0, 0, 0, 0, 1))), + MPP_MODE(22, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "txd2", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d2", V(0, 0, 0, 0, 1))), + MPP_MODE(23, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "txd3", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d3", V(0, 0, 0, 0, 1))), + MPP_MODE(24, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "rxd0", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d4", V(0, 0, 0, 0, 1))), + MPP_MODE(25, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "rxd1", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d5", V(0, 0, 0, 0, 1))), + MPP_MODE(26, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "rxd2", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d6", V(0, 0, 0, 0, 1))), + MPP_MODE(27, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "rxd3", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d7", V(0, 0, 0, 0, 1))), + MPP_MODE(28, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "col", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d8", V(0, 0, 0, 0, 1))), + MPP_MODE(29, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "txclk", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0xb, "lcd", "d9", V(0, 0, 0, 0, 1))), + MPP_MODE(30, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "rxctl", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d10", V(0, 0, 0, 0, 1))), + MPP_MODE(31, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "rxclk", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d11", V(0, 0, 0, 0, 1))), + MPP_MODE(32, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "txclko", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d12", V(0, 0, 0, 0, 1))), + MPP_MODE(33, + MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "txctl", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d13", V(0, 0, 0, 0, 1))), + MPP_MODE(34, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "txen", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d14", V(0, 0, 0, 0, 1))), + MPP_MODE(35, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x3, "ge1", "rxerr", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d15", V(0, 0, 0, 0, 1)), + MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 1, 1, 1, 1))), + MPP_MODE(36, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "twsi1", "sda", V(0, 0, 0, 0, 1))), + MPP_MODE(37, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "twsi1", "sck", V(0, 0, 0, 0, 1))), + MPP_MODE(38, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d18", V(0, 0, 0, 0, 1))), + MPP_MODE(39, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d19", V(0, 0, 0, 0, 1))), + MPP_MODE(40, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d20", V(0, 0, 0, 0, 1))), + MPP_MODE(41, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d21", V(0, 0, 0, 0, 1))), + MPP_MODE(42, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d22", V(0, 0, 0, 0, 1))), + MPP_MODE(43, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d23", V(0, 0, 0, 0, 1))), + MPP_MODE(44, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "clk", V(0, 0, 0, 0, 1))), + MPP_MODE(45, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "e", V(0, 0, 0, 0, 1))), + MPP_MODE(46, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1))), + MPP_MODE(47, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1))), + MPP_MODE(48, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d16", V(0, 0, 0, 0, 1))), + MPP_MODE(49, + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0)), + MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 0, 0, 0, 1)), + MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 0)), + MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 0, 1, 1)), + MPP_VAR_FUNCTION(0x5, "ptp", "clk", V(0, 0, 0, 1, 0)), + MPP_VAR_FUNCTION(0xa, "pex", "clkreq", V(0, 0, 0, 0, 1)), + MPP_VAR_FUNCTION(0xb, "lcd", "d17", V(0, 0, 0, 0, 1))), +}; + +static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = { + MPP_REG_CTRL(0, 29), +}; + +static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = { + MPP_GPIO_RANGE(0, 0, 0, 30), +}; + +static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = { + MPP_REG_CTRL(0, 35), +}; + +static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = { + MPP_GPIO_RANGE(0, 0, 0, 32), + MPP_GPIO_RANGE(1, 32, 32, 4), +}; + +static struct mvebu_mpp_ctrl mv88f628x_mpp_controls[] = { + MPP_REG_CTRL(0, 49), +}; + +static struct pinctrl_gpio_range mv88f628x_gpio_ranges[] = { + MPP_GPIO_RANGE(0, 0, 0, 32), + MPP_GPIO_RANGE(1, 32, 32, 18), +}; + +static struct mvebu_pinctrl_soc_info mv88f6180_info = { + .variant = VARIANT_MV88F6180, + .controls = mv88f6180_mpp_controls, + .ncontrols = ARRAY_SIZE(mv88f6180_mpp_controls), + .modes = mv88f6xxx_mpp_modes, + .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), + .gpioranges = mv88f6180_gpio_ranges, + .ngpioranges = ARRAY_SIZE(mv88f6180_gpio_ranges), +}; + +static struct mvebu_pinctrl_soc_info mv88f6190_info = { + .variant = VARIANT_MV88F6190, + .controls = mv88f619x_mpp_controls, + .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls), + .modes = mv88f6xxx_mpp_modes, + .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), + .gpioranges = mv88f619x_gpio_ranges, + .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges), +}; + +static struct mvebu_pinctrl_soc_info mv88f6192_info = { + .variant = VARIANT_MV88F6192, + .controls = mv88f619x_mpp_controls, + .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls), + .modes = mv88f6xxx_mpp_modes, + .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), + .gpioranges = mv88f619x_gpio_ranges, + .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges), +}; + +static struct mvebu_pinctrl_soc_info mv88f6281_info = { + .variant = VARIANT_MV88F6281, + .controls = mv88f628x_mpp_controls, + .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls), + .modes = mv88f6xxx_mpp_modes, + .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), + .gpioranges = mv88f628x_gpio_ranges, + .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges), +}; + +static struct mvebu_pinctrl_soc_info mv88f6282_info = { + .variant = VARIANT_MV88F6282, + .controls = mv88f628x_mpp_controls, + .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls), + .modes = mv88f6xxx_mpp_modes, + .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), + .gpioranges = mv88f628x_gpio_ranges, + .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges), +}; + +static struct of_device_id kirkwood_pinctrl_of_match[] __devinitdata = { + { .compatible = "marvell,88f6180-pinctrl", .data = &mv88f6180_info }, + { .compatible = "marvell,88f6190-pinctrl", .data = &mv88f6190_info }, + { .compatible = "marvell,88f6192-pinctrl", .data = &mv88f6192_info }, + { .compatible = "marvell,88f6281-pinctrl", .data = &mv88f6281_info }, + { .compatible = "marvell,88f6282-pinctrl", .data = &mv88f6282_info }, + { } +}; + +static int __devinit kirkwood_pinctrl_probe(struct platform_device *pdev) +{ + const struct of_device_id *match = + of_match_device(kirkwood_pinctrl_of_match, &pdev->dev); + pdev->dev.platform_data = match->data; + return mvebu_pinctrl_probe(pdev); +} + +static int __devexit kirkwood_pinctrl_remove(struct platform_device *pdev) +{ + return mvebu_pinctrl_remove(pdev); +} + +static struct platform_driver kirkwood_pinctrl_driver = { + .driver = { + .name = "kirkwood-pinctrl", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(kirkwood_pinctrl_of_match), + }, + .probe = kirkwood_pinctrl_probe, + .remove = __devexit_p(kirkwood_pinctrl_remove), +}; + +module_platform_driver(kirkwood_pinctrl_driver); + +MODULE_AUTHOR("Sebastian Hesselbarth "); +MODULE_DESCRIPTION("Marvell Kirkwood pinctrl driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c new file mode 100644 index 00000000000..6c44b7e8964 --- /dev/null +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c @@ -0,0 +1,753 @@ +/* + * Marvell MVEBU pinctrl core driver + * + * Authors: Sebastian Hesselbarth + * Thomas Petazzoni + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pinctrl-mvebu.h" + +#define MPPS_PER_REG 8 +#define MPP_BITS 4 +#define MPP_MASK 0xf + +struct mvebu_pinctrl_function { + const char *name; + const char **groups; + unsigned num_groups; +}; + +struct mvebu_pinctrl_group { + const char *name; + struct mvebu_mpp_ctrl *ctrl; + struct mvebu_mpp_ctrl_setting *settings; + unsigned num_settings; + unsigned gid; + unsigned *pins; + unsigned npins; +}; + +struct mvebu_pinctrl { + struct device *dev; + struct pinctrl_dev *pctldev; + struct pinctrl_desc desc; + void __iomem *base; + struct mvebu_pinctrl_group *groups; + unsigned num_groups; + struct mvebu_pinctrl_function *functions; + unsigned num_functions; + u8 variant; +}; + +static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_pid( + struct mvebu_pinctrl *pctl, unsigned pid) +{ + unsigned n; + for (n = 0; n < pctl->num_groups; n++) { + if (pid >= pctl->groups[n].pins[0] && + pid < pctl->groups[n].pins[0] + + pctl->groups[n].npins) + return &pctl->groups[n]; + } + return NULL; +} + +static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_name( + struct mvebu_pinctrl *pctl, const char *name) +{ + unsigned n; + for (n = 0; n < pctl->num_groups; n++) { + if (strcmp(name, pctl->groups[n].name) == 0) + return &pctl->groups[n]; + } + return NULL; +} + +static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_val( + struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp, + unsigned long config) +{ + unsigned n; + for (n = 0; n < grp->num_settings; n++) { + if (config == grp->settings[n].val) { + if (!pctl->variant || (pctl->variant & + grp->settings[n].variant)) + return &grp->settings[n]; + } + } + return NULL; +} + +static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_name( + struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp, + const char *name) +{ + unsigned n; + for (n = 0; n < grp->num_settings; n++) { + if (strcmp(name, grp->settings[n].name) == 0) { + if (!pctl->variant || (pctl->variant & + grp->settings[n].variant)) + return &grp->settings[n]; + } + } + return NULL; +} + +static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_gpio_setting( + struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp) +{ + unsigned n; + for (n = 0; n < grp->num_settings; n++) { + if (grp->settings[n].flags & + (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) { + if (!pctl->variant || (pctl->variant & + grp->settings[n].variant)) + return &grp->settings[n]; + } + } + return NULL; +} + +static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name( + struct mvebu_pinctrl *pctl, const char *name) +{ + unsigned n; + for (n = 0; n < pctl->num_functions; n++) { + if (strcmp(name, pctl->functions[n].name) == 0) + return &pctl->functions[n]; + } + return NULL; +} + +/* + * Common mpp pin configuration registers on MVEBU are + * registers of eight 4-bit values for each mpp setting. + * Register offset and bit mask are calculated accordingly below. + */ +static int mvebu_common_mpp_get(struct mvebu_pinctrl *pctl, + struct mvebu_pinctrl_group *grp, + unsigned long *config) +{ + unsigned pin = grp->gid; + unsigned off = (pin / MPPS_PER_REG) * MPP_BITS; + unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS; + + *config = readl(pctl->base + off); + *config >>= shift; + *config &= MPP_MASK; + + return 0; +} + +static int mvebu_common_mpp_set(struct mvebu_pinctrl *pctl, + struct mvebu_pinctrl_group *grp, + unsigned long config) +{ + unsigned pin = grp->gid; + unsigned off = (pin / MPPS_PER_REG) * MPP_BITS; + unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS; + unsigned long reg; + + reg = readl(pctl->base + off); + reg &= ~(MPP_MASK << shift); + reg |= (config << shift); + writel(reg, pctl->base + off); + + return 0; +} + +static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev, + unsigned gid, unsigned long *config) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; + + if (!grp->ctrl) + return -EINVAL; + + if (grp->ctrl->mpp_get) + return grp->ctrl->mpp_get(grp->ctrl, config); + + return mvebu_common_mpp_get(pctl, grp, config); +} + +static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev, + unsigned gid, unsigned long config) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; + + if (!grp->ctrl) + return -EINVAL; + + if (grp->ctrl->mpp_set) + return grp->ctrl->mpp_set(grp->ctrl, config); + + return mvebu_common_mpp_set(pctl, grp, config); +} + +static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, unsigned gid) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; + struct mvebu_mpp_ctrl_setting *curr; + unsigned long config; + unsigned n; + + if (mvebu_pinconf_group_get(pctldev, gid, &config)) + return; + + curr = mvebu_pinctrl_find_setting_by_val(pctl, grp, config); + + if (curr) { + seq_printf(s, "current: %s", curr->name); + if (curr->subname) + seq_printf(s, "(%s)", curr->subname); + if (curr->flags & (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) { + seq_printf(s, "("); + if (curr->flags & MVEBU_SETTING_GPI) + seq_printf(s, "i"); + if (curr->flags & MVEBU_SETTING_GPO) + seq_printf(s, "o"); + seq_printf(s, ")"); + } + } else + seq_printf(s, "current: UNKNOWN"); + + if (grp->num_settings > 1) { + seq_printf(s, ", available = ["); + for (n = 0; n < grp->num_settings; n++) { + if (curr == &grp->settings[n]) + continue; + + /* skip unsupported settings for this variant */ + if (pctl->variant && + !(pctl->variant & grp->settings[n].variant)) + continue; + + seq_printf(s, " %s", grp->settings[n].name); + if (grp->settings[n].subname) + seq_printf(s, "(%s)", grp->settings[n].subname); + if (grp->settings[n].flags & + (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) { + seq_printf(s, "("); + if (grp->settings[n].flags & MVEBU_SETTING_GPI) + seq_printf(s, "i"); + if (grp->settings[n].flags & MVEBU_SETTING_GPO) + seq_printf(s, "o"); + seq_printf(s, ")"); + } + } + seq_printf(s, " ]"); + } + return; +} + +static struct pinconf_ops mvebu_pinconf_ops = { + .pin_config_group_get = mvebu_pinconf_group_get, + .pin_config_group_set = mvebu_pinconf_group_set, + .pin_config_group_dbg_show = mvebu_pinconf_group_dbg_show, +}; + +static int mvebu_pinmux_get_funcs_count(struct pinctrl_dev *pctldev) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + + return pctl->num_functions; +} + +static const char *mvebu_pinmux_get_func_name(struct pinctrl_dev *pctldev, + unsigned fid) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + + return pctl->functions[fid].name; +} + +static int mvebu_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned fid, + const char * const **groups, + unsigned * const num_groups) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + + *groups = pctl->functions[fid].groups; + *num_groups = pctl->functions[fid].num_groups; + return 0; +} + +static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid, + unsigned gid) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct mvebu_pinctrl_function *func = &pctl->functions[fid]; + struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; + struct mvebu_mpp_ctrl_setting *setting; + int ret; + + setting = mvebu_pinctrl_find_setting_by_name(pctl, grp, + func->name); + if (!setting) { + dev_err(pctl->dev, + "unable to find setting %s in group %s\n", + func->name, func->groups[gid]); + return -EINVAL; + } + + ret = mvebu_pinconf_group_set(pctldev, grp->gid, setting->val); + if (ret) { + dev_err(pctl->dev, "cannot set group %s to %s\n", + func->groups[gid], func->name); + return ret; + } + + return 0; +} + +static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, unsigned offset) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct mvebu_pinctrl_group *grp; + struct mvebu_mpp_ctrl_setting *setting; + + grp = mvebu_pinctrl_find_group_by_pid(pctl, offset); + if (!grp) + return -EINVAL; + + if (grp->ctrl->mpp_gpio_req) + return grp->ctrl->mpp_gpio_req(grp->ctrl, offset); + + setting = mvebu_pinctrl_find_gpio_setting(pctl, grp); + if (!setting) + return -ENOTSUPP; + + return mvebu_pinconf_group_set(pctldev, grp->gid, setting->val); +} + +static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, unsigned offset, bool input) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct mvebu_pinctrl_group *grp; + struct mvebu_mpp_ctrl_setting *setting; + + grp = mvebu_pinctrl_find_group_by_pid(pctl, offset); + if (!grp) + return -EINVAL; + + if (grp->ctrl->mpp_gpio_dir) + return grp->ctrl->mpp_gpio_dir(grp->ctrl, offset, input); + + setting = mvebu_pinctrl_find_gpio_setting(pctl, grp); + if (!setting) + return -ENOTSUPP; + + if ((input && (setting->flags & MVEBU_SETTING_GPI)) || + (!input && (setting->flags & MVEBU_SETTING_GPO))) + return 0; + + return -ENOTSUPP; +} + +static struct pinmux_ops mvebu_pinmux_ops = { + .get_functions_count = mvebu_pinmux_get_funcs_count, + .get_function_name = mvebu_pinmux_get_func_name, + .get_function_groups = mvebu_pinmux_get_groups, + .gpio_request_enable = mvebu_pinmux_gpio_request_enable, + .gpio_set_direction = mvebu_pinmux_gpio_set_direction, + .enable = mvebu_pinmux_enable, +}; + +static int mvebu_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + return pctl->num_groups; +} + +static const char *mvebu_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned gid) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + return pctl->groups[gid].name; +} + +static int mvebu_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned gid, const unsigned **pins, + unsigned *num_pins) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + *pins = pctl->groups[gid].pins; + *num_pins = pctl->groups[gid].npins; + return 0; +} + +static int mvebu_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np, + struct pinctrl_map **map, + unsigned *num_maps) +{ + struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct property *prop; + const char *function; + const char *group; + int ret, nmaps, n; + + *map = NULL; + *num_maps = 0; + + ret = of_property_read_string(np, "marvell,function", &function); + if (ret) { + dev_err(pctl->dev, + "missing marvell,function in node %s\n", np->name); + return 0; + } + + nmaps = of_property_count_strings(np, "marvell,pins"); + if (nmaps < 0) { + dev_err(pctl->dev, + "missing marvell,pins in node %s\n", np->name); + return 0; + } + + *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL); + if (map == NULL) { + dev_err(pctl->dev, + "cannot allocate pinctrl_map memory for %s\n", + np->name); + return -ENOMEM; + } + + n = 0; + of_property_for_each_string(np, "marvell,pins", prop, group) { + struct mvebu_pinctrl_group *grp = + mvebu_pinctrl_find_group_by_name(pctl, group); + + if (!grp) { + dev_err(pctl->dev, "unknown pin %s", group); + continue; + } + + if (!mvebu_pinctrl_find_setting_by_name(pctl, grp, function)) { + dev_err(pctl->dev, "unsupported function %s on pin %s", + function, group); + continue; + } + + (*map)[n].type = PIN_MAP_TYPE_MUX_GROUP; + (*map)[n].data.mux.group = group; + (*map)[n].data.mux.function = function; + n++; + } + + *num_maps = nmaps; + + return 0; +} + +static void mvebu_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, + struct pinctrl_map *map, unsigned num_maps) +{ + kfree(map); +} + +static struct pinctrl_ops mvebu_pinctrl_ops = { + .get_groups_count = mvebu_pinctrl_get_groups_count, + .get_group_name = mvebu_pinctrl_get_group_name, + .get_group_pins = mvebu_pinctrl_get_group_pins, + .dt_node_to_map = mvebu_pinctrl_dt_node_to_map, + .dt_free_map = mvebu_pinctrl_dt_free_map, +}; + +static int __devinit _add_function(struct mvebu_pinctrl_function *funcs, + const char *name) +{ + while (funcs->num_groups) { + /* function already there */ + if (strcmp(funcs->name, name) == 0) { + funcs->num_groups++; + return -EEXIST; + } + funcs++; + } + funcs->name = name; + funcs->num_groups = 1; + return 0; +} + +static int __devinit mvebu_pinctrl_build_functions(struct platform_device *pdev, + struct mvebu_pinctrl *pctl) +{ + struct mvebu_pinctrl_function *funcs; + int num = 0; + int n, s; + + /* we allocate functions for number of pins and hope + * there are less unique functions than pins available */ + funcs = devm_kzalloc(&pdev->dev, pctl->desc.npins * + sizeof(struct mvebu_pinctrl_function), GFP_KERNEL); + if (!funcs) + return -ENOMEM; + + for (n = 0; n < pctl->num_groups; n++) { + struct mvebu_pinctrl_group *grp = &pctl->groups[n]; + for (s = 0; s < grp->num_settings; s++) { + /* skip unsupported settings on this variant */ + if (pctl->variant && + !(pctl->variant & grp->settings[s].variant)) + continue; + + /* check for unique functions and count groups */ + if (_add_function(funcs, grp->settings[s].name)) + continue; + + num++; + } + } + + /* with the number of unique functions and it's groups known, + reallocate functions and assign group names */ + funcs = krealloc(funcs, num * sizeof(struct mvebu_pinctrl_function), + GFP_KERNEL); + if (!funcs) + return -ENOMEM; + + pctl->num_functions = num; + pctl->functions = funcs; + + for (n = 0; n < pctl->num_groups; n++) { + struct mvebu_pinctrl_group *grp = &pctl->groups[n]; + for (s = 0; s < grp->num_settings; s++) { + struct mvebu_pinctrl_function *f; + const char **groups; + + /* skip unsupported settings on this variant */ + if (pctl->variant && + !(pctl->variant & grp->settings[s].variant)) + continue; + + f = mvebu_pinctrl_find_function_by_name(pctl, + grp->settings[s].name); + + /* allocate group name array if not done already */ + if (!f->groups) { + f->groups = devm_kzalloc(&pdev->dev, + f->num_groups * sizeof(char *), + GFP_KERNEL); + if (!f->groups) + return -ENOMEM; + } + + /* find next free group name and assign current name */ + groups = f->groups; + while (*groups) + groups++; + *groups = grp->name; + } + } + + return 0; +} + +int __devinit mvebu_pinctrl_probe(struct platform_device *pdev) +{ + struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev); + struct device_node *np = pdev->dev.of_node; + struct mvebu_pinctrl *pctl; + void __iomem *base; + struct pinctrl_pin_desc *pdesc; + unsigned gid, n, k; + int ret; + + if (!soc || !soc->controls || !soc->modes) { + dev_err(&pdev->dev, "wrong pinctrl soc info\n"); + return -EINVAL; + } + + base = of_iomap(np, 0); + if (!base) { + dev_err(&pdev->dev, "unable to get base address\n"); + return -ENODEV; + } + + pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl), + GFP_KERNEL); + if (!pctl) { + dev_err(&pdev->dev, "unable to alloc driver\n"); + return -ENOMEM; + } + + pctl->desc.name = dev_name(&pdev->dev); + pctl->desc.owner = THIS_MODULE; + pctl->desc.pctlops = &mvebu_pinctrl_ops; + pctl->desc.pmxops = &mvebu_pinmux_ops; + pctl->desc.confops = &mvebu_pinconf_ops; + pctl->variant = soc->variant; + pctl->base = base; + pctl->dev = &pdev->dev; + platform_set_drvdata(pdev, pctl); + + /* count controls and create names for mvebu generic + register controls; also does sanity checks */ + pctl->num_groups = 0; + pctl->desc.npins = 0; + for (n = 0; n < soc->ncontrols; n++) { + struct mvebu_mpp_ctrl *ctrl = &soc->controls[n]; + char *names; + + pctl->desc.npins += ctrl->npins; + /* initial control pins */ + for (k = 0; k < ctrl->npins; k++) + ctrl->pins[k] = ctrl->pid + k; + + /* special soc specific control */ + if (ctrl->mpp_get || ctrl->mpp_set) { + if (!ctrl->name || !ctrl->mpp_set || !ctrl->mpp_set) { + dev_err(&pdev->dev, "wrong soc control info\n"); + return -EINVAL; + } + pctl->num_groups += 1; + continue; + } + + /* generic mvebu register control */ + names = devm_kzalloc(&pdev->dev, ctrl->npins * 8, GFP_KERNEL); + if (!names) { + dev_err(&pdev->dev, "failed to alloc mpp names\n"); + return -ENOMEM; + } + for (k = 0; k < ctrl->npins; k++) + sprintf(names + 8*k, "mpp%d", ctrl->pid+k); + ctrl->name = names; + pctl->num_groups += ctrl->npins; + } + + pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins * + sizeof(struct pinctrl_pin_desc), GFP_KERNEL); + if (!pdesc) { + dev_err(&pdev->dev, "failed to alloc pinctrl pins\n"); + return -ENOMEM; + } + + for (n = 0; n < pctl->desc.npins; n++) + pdesc[n].number = n; + pctl->desc.pins = pdesc; + + pctl->groups = devm_kzalloc(&pdev->dev, pctl->num_groups * + sizeof(struct mvebu_pinctrl_group), GFP_KERNEL); + if (!pctl->groups) { + dev_err(&pdev->dev, "failed to alloc pinctrl groups\n"); + return -ENOMEM; + } + + /* assign mpp controls to groups */ + gid = 0; + for (n = 0; n < soc->ncontrols; n++) { + struct mvebu_mpp_ctrl *ctrl = &soc->controls[n]; + pctl->groups[gid].gid = gid; + pctl->groups[gid].ctrl = ctrl; + pctl->groups[gid].name = ctrl->name; + pctl->groups[gid].pins = ctrl->pins; + pctl->groups[gid].npins = ctrl->npins; + + /* generic mvebu register control maps to a number of groups */ + if (!ctrl->mpp_get && !ctrl->mpp_set) { + pctl->groups[gid].npins = 1; + + for (k = 1; k < ctrl->npins; k++) { + gid++; + pctl->groups[gid].gid = gid; + pctl->groups[gid].ctrl = ctrl; + pctl->groups[gid].name = &ctrl->name[8*k]; + pctl->groups[gid].pins = &ctrl->pins[k]; + pctl->groups[gid].npins = 1; + } + } + gid++; + } + + /* assign mpp modes to groups */ + for (n = 0; n < soc->nmodes; n++) { + struct mvebu_mpp_mode *mode = &soc->modes[n]; + struct mvebu_pinctrl_group *grp = + mvebu_pinctrl_find_group_by_pid(pctl, mode->pid); + unsigned num_settings; + + if (!grp) { + dev_warn(&pdev->dev, "unknown pinctrl group %d\n", + mode->pid); + continue; + } + + for (num_settings = 0; ;) { + struct mvebu_mpp_ctrl_setting *set = + &mode->settings[num_settings]; + + if (!set->name) + break; + num_settings++; + + /* skip unsupported settings for this variant */ + if (pctl->variant && !(pctl->variant & set->variant)) + continue; + + /* find gpio/gpo/gpi settings */ + if (strcmp(set->name, "gpio") == 0) + set->flags = MVEBU_SETTING_GPI | + MVEBU_SETTING_GPO; + else if (strcmp(set->name, "gpo") == 0) + set->flags = MVEBU_SETTING_GPO; + else if (strcmp(set->name, "gpi") == 0) + set->flags = MVEBU_SETTING_GPI; + } + + grp->settings = mode->settings; + grp->num_settings = num_settings; + } + + ret = mvebu_pinctrl_build_functions(pdev, pctl); + if (ret) { + dev_err(&pdev->dev, "unable to build functions\n"); + return ret; + } + + pctl->pctldev = pinctrl_register(&pctl->desc, &pdev->dev, pctl); + if (!pctl->pctldev) { + dev_err(&pdev->dev, "unable to register pinctrl driver\n"); + return -EINVAL; + } + + dev_info(&pdev->dev, "registered pinctrl driver\n"); + + /* register gpio ranges */ + for (n = 0; n < soc->ngpioranges; n++) + pinctrl_add_gpio_range(pctl->pctldev, &soc->gpioranges[n]); + + return 0; +} + +int __devexit mvebu_pinctrl_remove(struct platform_device *pdev) +{ + struct mvebu_pinctrl *pctl = platform_get_drvdata(pdev); + pinctrl_unregister(pctl->pctldev); + return 0; +} diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.h b/drivers/pinctrl/mvebu/pinctrl-mvebu.h new file mode 100644 index 00000000000..90bd3beee86 --- /dev/null +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.h @@ -0,0 +1,192 @@ +/* + * Marvell MVEBU pinctrl driver + * + * Authors: Sebastian Hesselbarth + * Thomas Petazzoni + * + * 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. + */ + +#ifndef __PINCTRL_MVEBU_H__ +#define __PINCTRL_MVEBU_H__ + +/** + * struct mvebu_mpp_ctrl - describe a mpp control + * @name: name of the control group + * @pid: first pin id handled by this control + * @npins: number of pins controlled by this control + * @mpp_get: (optional) special function to get mpp setting + * @mpp_set: (optional) special function to set mpp setting + * @mpp_gpio_req: (optional) special function to request gpio + * @mpp_gpio_dir: (optional) special function to set gpio direction + * + * A mpp_ctrl describes a muxable unit, e.g. pin, group of pins, or + * internal function, inside the SoC. Each muxable unit can be switched + * between two or more different settings, e.g. assign mpp pin 13 to + * uart1 or sata. + * + * If optional mpp_get/_set functions are set these are used to get/set + * a specific mode. Otherwise it is assumed that the mpp control is based + * on 4-bit groups in subsequent registers. The optional mpp_gpio_req/_dir + * functions can be used to allow pin settings with varying gpio pins. + */ +struct mvebu_mpp_ctrl { + const char *name; + u8 pid; + u8 npins; + unsigned *pins; + int (*mpp_get)(struct mvebu_mpp_ctrl *ctrl, unsigned long *config); + int (*mpp_set)(struct mvebu_mpp_ctrl *ctrl, unsigned long config); + int (*mpp_gpio_req)(struct mvebu_mpp_ctrl *ctrl, u8 pid); + int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl *ctrl, u8 pid, bool input); +}; + +/** + * struct mvebu_mpp_ctrl_setting - describe a mpp ctrl setting + * @val: ctrl setting value + * @name: ctrl setting name, e.g. uart2, spi0 - unique per mpp_mode + * @subname: (optional) additional ctrl setting name, e.g. rts, cts + * @variant: (optional) variant identifier mask + * @flags: (private) flags to store gpi/gpo/gpio capabilities + * + * A ctrl_setting describes a specific internal mux function that a mpp pin + * can be switched to. The value (val) will be written in the corresponding + * register for common mpp pin configuration registers on MVEBU. SoC specific + * mpp_get/_set function may use val to distinguish between different settings. + * + * The name will be used to switch to this setting in DT description, e.g. + * marvell,function = "uart2". subname is only for debugging purposes. + * + * If name is one of "gpi", "gpo", "gpio" gpio capabilities are + * parsed during initialization and stored in flags. + * + * The variant can be used to combine different revisions of one SoC to a + * common pinctrl driver. It is matched (AND) with variant of soc_info to + * determine if a setting is available on the current SoC revision. + */ +struct mvebu_mpp_ctrl_setting { + u8 val; + const char *name; + const char *subname; + u8 variant; + u8 flags; +#define MVEBU_SETTING_GPO (1 << 0) +#define MVEBU_SETTING_GPI (1 << 1) +}; + +/** + * struct mvebu_mpp_mode - link ctrl and settings + * @pid: first pin id handled by this mode + * @settings: list of settings available for this mode + * + * A mode connects all available settings with the corresponding mpp_ctrl + * given by pid. + */ +struct mvebu_mpp_mode { + u8 pid; + struct mvebu_mpp_ctrl_setting *settings; +}; + +/** + * struct mvebu_pinctrl_soc_info - SoC specific info passed to pinctrl-mvebu + * @variant: variant mask of soc_info + * @controls: list of available mvebu_mpp_ctrls + * @ncontrols: number of available mvebu_mpp_ctrls + * @modes: list of available mvebu_mpp_modes + * @nmodes: number of available mvebu_mpp_modes + * @gpioranges: list of pinctrl_gpio_ranges + * @ngpioranges: number of available pinctrl_gpio_ranges + * + * This struct describes all pinctrl related information for a specific SoC. + * If variant is unequal 0 it will be matched (AND) with variant of each + * setting and allows to distinguish between different revisions of one SoC. + */ +struct mvebu_pinctrl_soc_info { + u8 variant; + struct mvebu_mpp_ctrl *controls; + int ncontrols; + struct mvebu_mpp_mode *modes; + int nmodes; + struct pinctrl_gpio_range *gpioranges; + int ngpioranges; +}; + +#define MPP_REG_CTRL(_idl, _idh) \ + { \ + .name = NULL, \ + .pid = _idl, \ + .npins = _idh - _idl + 1, \ + .pins = (unsigned[_idh - _idl + 1]) { }, \ + .mpp_get = NULL, \ + .mpp_set = NULL, \ + .mpp_gpio_req = NULL, \ + .mpp_gpio_dir = NULL, \ + } + +#define MPP_FUNC_CTRL(_idl, _idh, _name, _func) \ + { \ + .name = _name, \ + .pid = _idl, \ + .npins = _idh - _idl + 1, \ + .pins = (unsigned[_idh - _idl + 1]) { }, \ + .mpp_get = _func ## _get, \ + .mpp_set = _func ## _set, \ + .mpp_gpio_req = NULL, \ + .mpp_gpio_dir = NULL, \ + } + +#define MPP_FUNC_GPIO_CTRL(_idl, _idh, _name, _func) \ + { \ + .name = _name, \ + .pid = _idl, \ + .npins = _idh - _idl + 1, \ + .pins = (unsigned[_idh - _idl + 1]) { }, \ + .mpp_get = _func ## _get, \ + .mpp_set = _func ## _set, \ + .mpp_gpio_req = _func ## _gpio_req, \ + .mpp_gpio_dir = _func ## _gpio_dir, \ + } + +#define _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ + { \ + .val = _val, \ + .name = _name, \ + .subname = _subname, \ + .variant = _mask, \ + .flags = 0, \ + } + +#if defined(CONFIG_DEBUG_FS) +#define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ + _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) +#else +#define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ + _MPP_VAR_FUNCTION(_val, _name, NULL, _mask) +#endif + +#define MPP_FUNCTION(_val, _name, _subname) \ + MPP_VAR_FUNCTION(_val, _name, _subname, (u8)-1) + +#define MPP_MODE(_id, ...) \ + { \ + .pid = _id, \ + .settings = (struct mvebu_mpp_ctrl_setting[]){ \ + __VA_ARGS__, { } }, \ + } + +#define MPP_GPIO_RANGE(_id, _pinbase, _gpiobase, _npins) \ + { \ + .name = "mvebu-gpio", \ + .id = _id, \ + .pin_base = _pinbase, \ + .base = _gpiobase, \ + .npins = _npins, \ + } + +int mvebu_pinctrl_probe(struct platform_device *pdev); +int mvebu_pinctrl_remove(struct platform_device *pdev); + +#endif diff --git a/drivers/pinctrl/pinctrl-armada-370.c b/drivers/pinctrl/pinctrl-armada-370.c deleted file mode 100644 index c907647de6a..00000000000 --- a/drivers/pinctrl/pinctrl-armada-370.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Marvell Armada 370 pinctrl driver based on mvebu pinctrl core - * - * Copyright (C) 2012 Marvell - * - * Thomas Petazzoni - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pinctrl-mvebu.h" - -static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = { - MPP_MODE(0, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "uart0", "rxd")), - MPP_MODE(1, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "uart0", "txd")), - MPP_MODE(2, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "i2c0", "sck"), - MPP_FUNCTION(0x2, "uart0", "txd")), - MPP_MODE(3, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "i2c0", "sda"), - MPP_FUNCTION(0x2, "uart0", "rxd")), - MPP_MODE(4, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "cpu_pd", "vdd")), - MPP_MODE(5, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "ge0", "txclko"), - MPP_FUNCTION(0x2, "uart1", "txd"), - MPP_FUNCTION(0x4, "spi1", "clk"), - MPP_FUNCTION(0x5, "audio", "mclk")), - MPP_MODE(6, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "txd0"), - MPP_FUNCTION(0x2, "sata0", "prsnt"), - MPP_FUNCTION(0x4, "tdm", "rst"), - MPP_FUNCTION(0x5, "audio", "sdo")), - MPP_MODE(7, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "ge0", "txd1"), - MPP_FUNCTION(0x4, "tdm", "tdx"), - MPP_FUNCTION(0x5, "audio", "lrclk")), - MPP_MODE(8, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "txd2"), - MPP_FUNCTION(0x2, "uart0", "rts"), - MPP_FUNCTION(0x4, "tdm", "drx"), - MPP_FUNCTION(0x5, "audio", "bclk")), - MPP_MODE(9, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "ge0", "txd3"), - MPP_FUNCTION(0x2, "uart1", "txd"), - MPP_FUNCTION(0x3, "sd0", "clk"), - MPP_FUNCTION(0x5, "audio", "spdifo")), - MPP_MODE(10, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "txctl"), - MPP_FUNCTION(0x2, "uart0", "cts"), - MPP_FUNCTION(0x4, "tdm", "fsync"), - MPP_FUNCTION(0x5, "audio", "sdi")), - MPP_MODE(11, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "rxd0"), - MPP_FUNCTION(0x2, "uart1", "rxd"), - MPP_FUNCTION(0x3, "sd0", "cmd"), - MPP_FUNCTION(0x4, "spi0", "cs1"), - MPP_FUNCTION(0x5, "sata1", "prsnt"), - MPP_FUNCTION(0x6, "spi1", "cs1")), - MPP_MODE(12, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "rxd1"), - MPP_FUNCTION(0x2, "i2c1", "sda"), - MPP_FUNCTION(0x3, "sd0", "d0"), - MPP_FUNCTION(0x4, "spi1", "cs0"), - MPP_FUNCTION(0x5, "audio", "spdifi")), - MPP_MODE(13, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "rxd2"), - MPP_FUNCTION(0x2, "i2c1", "sck"), - MPP_FUNCTION(0x3, "sd0", "d1"), - MPP_FUNCTION(0x4, "tdm", "pclk"), - MPP_FUNCTION(0x5, "audio", "rmclk")), - MPP_MODE(14, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "rxd3"), - MPP_FUNCTION(0x2, "pcie", "clkreq0"), - MPP_FUNCTION(0x3, "sd0", "d2"), - MPP_FUNCTION(0x4, "spi1", "mosi"), - MPP_FUNCTION(0x5, "spi0", "cs2")), - MPP_MODE(15, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "rxctl"), - MPP_FUNCTION(0x2, "pcie", "clkreq1"), - MPP_FUNCTION(0x3, "sd0", "d3"), - MPP_FUNCTION(0x4, "spi1", "miso"), - MPP_FUNCTION(0x5, "spi0", "cs3")), - MPP_MODE(16, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "rxclk"), - MPP_FUNCTION(0x2, "uart1", "rxd"), - MPP_FUNCTION(0x4, "tdm", "int"), - MPP_FUNCTION(0x5, "audio", "extclk")), - MPP_MODE(17, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "ge", "mdc")), - MPP_MODE(18, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge", "mdio")), - MPP_MODE(19, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "txclk"), - MPP_FUNCTION(0x2, "ge1", "txclkout"), - MPP_FUNCTION(0x4, "tdm", "pclk")), - MPP_MODE(20, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "ge0", "txd4"), - MPP_FUNCTION(0x2, "ge1", "txd0")), - MPP_MODE(21, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "ge0", "txd5"), - MPP_FUNCTION(0x2, "ge1", "txd1"), - MPP_FUNCTION(0x4, "uart1", "txd")), - MPP_MODE(22, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "ge0", "txd6"), - MPP_FUNCTION(0x2, "ge1", "txd2"), - MPP_FUNCTION(0x4, "uart0", "rts")), - MPP_MODE(23, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "ge0", "txd7"), - MPP_FUNCTION(0x2, "ge1", "txd3"), - MPP_FUNCTION(0x4, "spi1", "mosi")), - MPP_MODE(24, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "col"), - MPP_FUNCTION(0x2, "ge1", "txctl"), - MPP_FUNCTION(0x4, "spi1", "cs0")), - MPP_MODE(25, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "rxerr"), - MPP_FUNCTION(0x2, "ge1", "rxd0"), - MPP_FUNCTION(0x4, "uart1", "rxd")), - MPP_MODE(26, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "crs"), - MPP_FUNCTION(0x2, "ge1", "rxd1"), - MPP_FUNCTION(0x4, "spi1", "miso")), - MPP_MODE(27, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "rxd4"), - MPP_FUNCTION(0x2, "ge1", "rxd2"), - MPP_FUNCTION(0x4, "uart0", "cts")), - MPP_MODE(28, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "rxd5"), - MPP_FUNCTION(0x2, "ge1", "rxd3")), - MPP_MODE(29, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "rxd6"), - MPP_FUNCTION(0x2, "ge1", "rxctl"), - MPP_FUNCTION(0x4, "i2c1", "sda")), - MPP_MODE(30, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "ge0", "rxd7"), - MPP_FUNCTION(0x2, "ge1", "rxclk"), - MPP_FUNCTION(0x4, "i2c1", "sck")), - MPP_MODE(31, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x3, "tclk", NULL), - MPP_FUNCTION(0x4, "ge0", "txerr")), - MPP_MODE(32, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "spi0", "cs0")), - MPP_MODE(33, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "bootcs"), - MPP_FUNCTION(0x2, "spi0", "cs0")), - MPP_MODE(34, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "wen0"), - MPP_FUNCTION(0x2, "spi0", "mosi")), - MPP_MODE(35, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "oen"), - MPP_FUNCTION(0x2, "spi0", "sck")), - MPP_MODE(36, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "a1"), - MPP_FUNCTION(0x2, "spi0", "miso")), - MPP_MODE(37, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "a0"), - MPP_FUNCTION(0x2, "sata0", "prsnt")), - MPP_MODE(38, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "ready"), - MPP_FUNCTION(0x2, "uart1", "cts"), - MPP_FUNCTION(0x3, "uart0", "cts")), - MPP_MODE(39, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "ad0"), - MPP_FUNCTION(0x2, "audio", "spdifo")), - MPP_MODE(40, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "ad1"), - MPP_FUNCTION(0x2, "uart1", "rts"), - MPP_FUNCTION(0x3, "uart0", "rts")), - MPP_MODE(41, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "ad2"), - MPP_FUNCTION(0x2, "uart1", "rxd")), - MPP_MODE(42, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "ad3"), - MPP_FUNCTION(0x2, "uart1", "txd")), - MPP_MODE(43, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "ad4"), - MPP_FUNCTION(0x2, "audio", "bclk")), - MPP_MODE(44, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "ad5"), - MPP_FUNCTION(0x2, "audio", "mclk")), - MPP_MODE(45, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "ad6"), - MPP_FUNCTION(0x2, "audio", "lrclk")), - MPP_MODE(46, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "ad7"), - MPP_FUNCTION(0x2, "audio", "sdo")), - MPP_MODE(47, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "ad8"), - MPP_FUNCTION(0x3, "sd0", "clk"), - MPP_FUNCTION(0x5, "audio", "spdifo")), - MPP_MODE(48, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "ad9"), - MPP_FUNCTION(0x2, "uart0", "rts"), - MPP_FUNCTION(0x3, "sd0", "cmd"), - MPP_FUNCTION(0x4, "sata1", "prsnt"), - MPP_FUNCTION(0x5, "spi0", "cs1")), - MPP_MODE(49, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "ad10"), - MPP_FUNCTION(0x2, "pcie", "clkreq1"), - MPP_FUNCTION(0x3, "sd0", "d0"), - MPP_FUNCTION(0x4, "spi1", "cs0"), - MPP_FUNCTION(0x5, "audio", "spdifi")), - MPP_MODE(50, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "ad11"), - MPP_FUNCTION(0x2, "uart0", "cts"), - MPP_FUNCTION(0x3, "sd0", "d1"), - MPP_FUNCTION(0x4, "spi1", "miso"), - MPP_FUNCTION(0x5, "audio", "rmclk")), - MPP_MODE(51, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "ad12"), - MPP_FUNCTION(0x2, "i2c1", "sda"), - MPP_FUNCTION(0x3, "sd0", "d2"), - MPP_FUNCTION(0x4, "spi1", "mosi")), - MPP_MODE(52, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "ad13"), - MPP_FUNCTION(0x2, "i2c1", "sck"), - MPP_FUNCTION(0x3, "sd0", "d3"), - MPP_FUNCTION(0x4, "spi1", "sck")), - MPP_MODE(53, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "ad14"), - MPP_FUNCTION(0x2, "sd0", "clk"), - MPP_FUNCTION(0x3, "tdm", "pclk"), - MPP_FUNCTION(0x4, "spi0", "cs2"), - MPP_FUNCTION(0x5, "pcie", "clkreq1")), - MPP_MODE(54, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "ad15"), - MPP_FUNCTION(0x3, "tdm", "dtx")), - MPP_MODE(55, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "cs1"), - MPP_FUNCTION(0x2, "uart1", "txd"), - MPP_FUNCTION(0x3, "tdm", "rst"), - MPP_FUNCTION(0x4, "sata1", "prsnt"), - MPP_FUNCTION(0x5, "sata0", "prsnt")), - MPP_MODE(56, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "cs2"), - MPP_FUNCTION(0x2, "uart1", "cts"), - MPP_FUNCTION(0x3, "uart0", "cts"), - MPP_FUNCTION(0x4, "spi0", "cs3"), - MPP_FUNCTION(0x5, "pcie", "clkreq0"), - MPP_FUNCTION(0x6, "spi1", "cs1")), - MPP_MODE(57, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "cs3"), - MPP_FUNCTION(0x2, "uart1", "rxd"), - MPP_FUNCTION(0x3, "tdm", "fsync"), - MPP_FUNCTION(0x4, "sata0", "prsnt"), - MPP_FUNCTION(0x5, "audio", "sdo")), - MPP_MODE(58, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "cs0"), - MPP_FUNCTION(0x2, "uart1", "rts"), - MPP_FUNCTION(0x3, "tdm", "int"), - MPP_FUNCTION(0x5, "audio", "extclk"), - MPP_FUNCTION(0x6, "uart0", "rts")), - MPP_MODE(59, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "ale0"), - MPP_FUNCTION(0x2, "uart1", "rts"), - MPP_FUNCTION(0x3, "uart0", "rts"), - MPP_FUNCTION(0x5, "audio", "bclk")), - MPP_MODE(60, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "ale1"), - MPP_FUNCTION(0x2, "uart1", "rxd"), - MPP_FUNCTION(0x3, "sata0", "prsnt"), - MPP_FUNCTION(0x4, "pcie", "rst-out"), - MPP_FUNCTION(0x5, "audio", "sdi")), - MPP_MODE(61, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "dev", "wen1"), - MPP_FUNCTION(0x2, "uart1", "txd"), - MPP_FUNCTION(0x5, "audio", "rclk")), - MPP_MODE(62, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "dev", "a2"), - MPP_FUNCTION(0x2, "uart1", "cts"), - MPP_FUNCTION(0x3, "tdm", "drx"), - MPP_FUNCTION(0x4, "pcie", "clkreq0"), - MPP_FUNCTION(0x5, "audio", "mclk"), - MPP_FUNCTION(0x6, "uart0", "cts")), - MPP_MODE(63, - MPP_FUNCTION(0x0, "gpo", NULL), - MPP_FUNCTION(0x1, "spi0", "sck"), - MPP_FUNCTION(0x2, "tclk", NULL)), - MPP_MODE(64, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "spi0", "miso"), - MPP_FUNCTION(0x2, "spi0-1", "cs1")), - MPP_MODE(65, - MPP_FUNCTION(0x0, "gpio", NULL), - MPP_FUNCTION(0x1, "spi0", "mosi"), - MPP_FUNCTION(0x2, "spi0-1", "cs2")), -}; - -static struct mvebu_pinctrl_soc_info armada_370_pinctrl_info; - -static struct of_device_id armada_370_pinctrl_of_match[] __devinitdata = { - { .compatible = "marvell,mv88f6710-pinctrl" }, - { }, -}; - -static struct mvebu_mpp_ctrl mv88f6710_mpp_controls[] = { - MPP_REG_CTRL(0, 65), -}; - -static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = { - MPP_GPIO_RANGE(0, 0, 0, 32), - MPP_GPIO_RANGE(1, 32, 32, 32), - MPP_GPIO_RANGE(2, 64, 64, 2), -}; - -static int __devinit armada_370_pinctrl_probe(struct platform_device *pdev) -{ - struct mvebu_pinctrl_soc_info *soc = &armada_370_pinctrl_info; - - soc->variant = 0; /* no variants for Armada 370 */ - soc->controls = mv88f6710_mpp_controls; - soc->ncontrols = ARRAY_SIZE(mv88f6710_mpp_controls); - soc->modes = mv88f6710_mpp_modes; - soc->nmodes = ARRAY_SIZE(mv88f6710_mpp_modes); - soc->gpioranges = mv88f6710_mpp_gpio_ranges; - soc->ngpioranges = ARRAY_SIZE(mv88f6710_mpp_gpio_ranges); - - pdev->dev.platform_data = soc; - - return mvebu_pinctrl_probe(pdev); -} - -static int __devexit armada_370_pinctrl_remove(struct platform_device *pdev) -{ - return mvebu_pinctrl_remove(pdev); -} - -static struct platform_driver armada_370_pinctrl_driver = { - .driver = { - .name = "armada-370-pinctrl", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(armada_370_pinctrl_of_match), - }, - .probe = armada_370_pinctrl_probe, - .remove = __devexit_p(armada_370_pinctrl_remove), -}; - -module_platform_driver(armada_370_pinctrl_driver); - -MODULE_AUTHOR("Thomas Petazzoni "); -MODULE_DESCRIPTION("Marvell Armada 370 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-armada-xp.c b/drivers/pinctrl/pinctrl-armada-xp.c deleted file mode 100644 index 40bd52a46b4..00000000000 --- a/drivers/pinctrl/pinctrl-armada-xp.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Marvell Armada XP pinctrl driver based on mvebu pinctrl core - * - * Copyright (C) 2012 Marvell - * - * Thomas Petazzoni - * - * 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. - * - * This file supports the three variants of Armada XP SoCs that are - * available: mv78230, mv78260 and mv78460. From a pin muxing - * perspective, the mv78230 has 49 MPP pins. The mv78260 and mv78460 - * both have 67 MPP pins (more GPIOs and address lines for the memory - * bus mainly). The only difference between the mv78260 and the - * mv78460 in terms of pin muxing is the addition of two functions on - * pins 43 and 56 to access the VDD of the CPU2 and 3 (mv78260 has two - * cores, mv78460 has four cores). - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pinctrl-mvebu.h" - -enum armada_xp_variant { - V_MV78230 = BIT(0), - V_MV78260 = BIT(1), - V_MV78460 = BIT(2), - V_MV78230_PLUS = (V_MV78230 | V_MV78260 | V_MV78460), - V_MV78260_PLUS = (V_MV78260 | V_MV78460), -}; - -static struct mvebu_mpp_mode armada_xp_mpp_modes[] = { - MPP_MODE(0, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "txclko", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d0", V_MV78230_PLUS)), - MPP_MODE(1, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "txd0", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d1", V_MV78230_PLUS)), - MPP_MODE(2, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "txd1", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d2", V_MV78230_PLUS)), - MPP_MODE(3, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "txd2", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d3", V_MV78230_PLUS)), - MPP_MODE(4, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "txd3", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d4", V_MV78230_PLUS)), - MPP_MODE(5, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "txctl", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d5", V_MV78230_PLUS)), - MPP_MODE(6, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "rxd0", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d6", V_MV78230_PLUS)), - MPP_MODE(7, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "rxd1", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d7", V_MV78230_PLUS)), - MPP_MODE(8, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "rxd2", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d8", V_MV78230_PLUS)), - MPP_MODE(9, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "rxd3", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d9", V_MV78230_PLUS)), - MPP_MODE(10, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "rxctl", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d10", V_MV78230_PLUS)), - MPP_MODE(11, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "rxclk", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d11", V_MV78230_PLUS)), - MPP_MODE(12, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "txd4", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "ge1", "clkout", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d12", V_MV78230_PLUS)), - MPP_MODE(13, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "txd5", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "ge1", "txd0", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d13", V_MV78230_PLUS)), - MPP_MODE(14, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "txd6", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "ge1", "txd1", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d14", V_MV78230_PLUS)), - MPP_MODE(15, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "txd7", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "ge1", "txd2", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d15", V_MV78230_PLUS)), - MPP_MODE(16, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "txclk", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "ge1", "txd3", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d16", V_MV78230_PLUS)), - MPP_MODE(17, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "col", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "ge1", "txctl", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d17", V_MV78230_PLUS)), - MPP_MODE(18, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "rxerr", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "ge1", "rxd0", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "ptp", "trig", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d18", V_MV78230_PLUS)), - MPP_MODE(19, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "crs", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "ge1", "rxd1", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "ptp", "evreq", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d19", V_MV78230_PLUS)), - MPP_MODE(20, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "rxd4", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "ge1", "rxd2", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "ptp", "clk", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d20", V_MV78230_PLUS)), - MPP_MODE(21, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "rxd5", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "ge1", "rxd3", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "mem", "bat", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d21", V_MV78230_PLUS)), - MPP_MODE(22, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "rxd6", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "ge1", "rxctl", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "sata0", "prsnt", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d22", V_MV78230_PLUS)), - MPP_MODE(23, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ge0", "rxd7", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "ge1", "rxclk", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "sata1", "prsnt", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "d23", V_MV78230_PLUS)), - MPP_MODE(24, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "sata1", "prsnt", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "nf", "bootcs-re", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "rst", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "hsync", V_MV78230_PLUS)), - MPP_MODE(25, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "sata0", "prsnt", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "nf", "bootcs-we", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "pclk", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "vsync", V_MV78230_PLUS)), - MPP_MODE(26, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "fsync", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "clk", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)), - MPP_MODE(27, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ptp", "trig", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "dtx", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "e", V_MV78230_PLUS)), - MPP_MODE(28, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ptp", "evreq", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "drx", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "pwm", V_MV78230_PLUS)), - MPP_MODE(29, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "ptp", "clk", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "int0", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "ref-clk", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)), - MPP_MODE(30, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "sd0", "clk", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "int1", V_MV78230_PLUS)), - MPP_MODE(31, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "sd0", "cmd", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "int2", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)), - MPP_MODE(32, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "sd0", "d0", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "int3", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)), - MPP_MODE(33, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "sd0", "d1", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "int4", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "mem", "bat", V_MV78230_PLUS)), - MPP_MODE(34, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "sd0", "d2", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "sata0", "prsnt", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "int5", V_MV78230_PLUS)), - MPP_MODE(35, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "sd0", "d3", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "sata1", "prsnt", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "int6", V_MV78230_PLUS)), - MPP_MODE(36, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "spi", "mosi", V_MV78230_PLUS)), - MPP_MODE(37, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "spi", "miso", V_MV78230_PLUS)), - MPP_MODE(38, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "spi", "sck", V_MV78230_PLUS)), - MPP_MODE(39, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "spi", "cs0", V_MV78230_PLUS)), - MPP_MODE(40, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "spi", "cs1", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "uart2", "cts", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "vdd", "cpu1-pd", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "vga-hsync", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "pcie", "clkreq0", V_MV78230_PLUS)), - MPP_MODE(41, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "spi", "cs2", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "uart2", "rts", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "sata1", "prsnt", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "lcd", "vga-vsync", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "pcie", "clkreq1", V_MV78230_PLUS)), - MPP_MODE(42, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "uart2", "rxd", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "uart0", "cts", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "tdm", "int7", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "tdm-1", "timer", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)), - MPP_MODE(43, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "uart2", "txd", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "uart0", "rts", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "spi", "cs3", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "pcie", "rstout", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "vdd", "cpu2-3-pd", V_MV78460)), - MPP_MODE(44, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "uart2", "cts", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "uart3", "rxd", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "spi", "cs4", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "mem", "bat", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "pcie", "clkreq2", V_MV78230_PLUS)), - MPP_MODE(45, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "uart2", "rts", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "uart3", "txd", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "spi", "cs5", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V_MV78230_PLUS)), - MPP_MODE(46, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "uart3", "rts", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "uart1", "rts", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "spi", "cs6", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V_MV78230_PLUS)), - MPP_MODE(47, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "uart3", "cts", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "uart1", "cts", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x3, "spi", "cs7", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x4, "ref", "clkout", V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x5, "pcie", "clkreq3", V_MV78230_PLUS)), - MPP_MODE(48, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x1, "tclk", NULL, V_MV78230_PLUS), - MPP_VAR_FUNCTION(0x2, "dev", "burst/last", V_MV78230_PLUS)), - MPP_MODE(49, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "we3", V_MV78260_PLUS)), - MPP_MODE(50, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "we2", V_MV78260_PLUS)), - MPP_MODE(51, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad16", V_MV78260_PLUS)), - MPP_MODE(52, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad17", V_MV78260_PLUS)), - MPP_MODE(53, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad18", V_MV78260_PLUS)), - MPP_MODE(54, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad19", V_MV78260_PLUS)), - MPP_MODE(55, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad20", V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x2, "vdd", "cpu0-pd", V_MV78260_PLUS)), - MPP_MODE(56, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad21", V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x2, "vdd", "cpu1-pd", V_MV78260_PLUS)), - MPP_MODE(57, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad22", V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x2, "vdd", "cpu2-3-pd", V_MV78460)), - MPP_MODE(58, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad23", V_MV78260_PLUS)), - MPP_MODE(59, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad24", V_MV78260_PLUS)), - MPP_MODE(60, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad25", V_MV78260_PLUS)), - MPP_MODE(61, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad26", V_MV78260_PLUS)), - MPP_MODE(62, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad27", V_MV78260_PLUS)), - MPP_MODE(63, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad28", V_MV78260_PLUS)), - MPP_MODE(64, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad29", V_MV78260_PLUS)), - MPP_MODE(65, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad30", V_MV78260_PLUS)), - MPP_MODE(66, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), - MPP_VAR_FUNCTION(0x1, "dev", "ad31", V_MV78260_PLUS)), -}; - -static struct mvebu_pinctrl_soc_info armada_xp_pinctrl_info; - -static struct of_device_id armada_xp_pinctrl_of_match[] __devinitdata = { - { - .compatible = "marvell,mv78230-pinctrl", - .data = (void *) V_MV78230, - }, - { - .compatible = "marvell,mv78260-pinctrl", - .data = (void *) V_MV78260, - }, - { - .compatible = "marvell,mv78460-pinctrl", - .data = (void *) V_MV78460, - }, - { }, -}; - -static struct mvebu_mpp_ctrl mv78230_mpp_controls[] = { - MPP_REG_CTRL(0, 48), -}; - -static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = { - MPP_GPIO_RANGE(0, 0, 0, 32), - MPP_GPIO_RANGE(1, 32, 32, 17), -}; - -static struct mvebu_mpp_ctrl mv78260_mpp_controls[] = { - MPP_REG_CTRL(0, 66), -}; - -static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = { - MPP_GPIO_RANGE(0, 0, 0, 32), - MPP_GPIO_RANGE(1, 32, 32, 32), - MPP_GPIO_RANGE(2, 64, 64, 3), -}; - -static struct mvebu_mpp_ctrl mv78460_mpp_controls[] = { - MPP_REG_CTRL(0, 66), -}; - -static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = { - MPP_GPIO_RANGE(0, 0, 0, 32), - MPP_GPIO_RANGE(1, 32, 32, 32), - MPP_GPIO_RANGE(2, 64, 64, 3), -}; - -static int __devinit armada_xp_pinctrl_probe(struct platform_device *pdev) -{ - struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info; - const struct of_device_id *match = - of_match_device(armada_xp_pinctrl_of_match, &pdev->dev); - - if (!match) - return -ENODEV; - - soc->variant = (unsigned) match->data & 0xff; - - switch (soc->variant) { - case V_MV78230: - soc->controls = mv78230_mpp_controls; - soc->ncontrols = ARRAY_SIZE(mv78230_mpp_controls); - soc->modes = armada_xp_mpp_modes; - /* We don't necessarily want the full list of the - * armada_xp_mpp_modes, but only the first 'n' ones - * that are available on this SoC */ - soc->nmodes = mv78230_mpp_controls[0].npins; - soc->gpioranges = mv78230_mpp_gpio_ranges; - soc->ngpioranges = ARRAY_SIZE(mv78230_mpp_gpio_ranges); - break; - case V_MV78260: - soc->controls = mv78260_mpp_controls; - soc->ncontrols = ARRAY_SIZE(mv78260_mpp_controls); - soc->modes = armada_xp_mpp_modes; - /* We don't necessarily want the full list of the - * armada_xp_mpp_modes, but only the first 'n' ones - * that are available on this SoC */ - soc->nmodes = mv78260_mpp_controls[0].npins; - soc->gpioranges = mv78260_mpp_gpio_ranges; - soc->ngpioranges = ARRAY_SIZE(mv78260_mpp_gpio_ranges); - break; - case V_MV78460: - soc->controls = mv78460_mpp_controls; - soc->ncontrols = ARRAY_SIZE(mv78460_mpp_controls); - soc->modes = armada_xp_mpp_modes; - /* We don't necessarily want the full list of the - * armada_xp_mpp_modes, but only the first 'n' ones - * that are available on this SoC */ - soc->nmodes = mv78460_mpp_controls[0].npins; - soc->gpioranges = mv78460_mpp_gpio_ranges; - soc->ngpioranges = ARRAY_SIZE(mv78460_mpp_gpio_ranges); - break; - } - - pdev->dev.platform_data = soc; - - return mvebu_pinctrl_probe(pdev); -} - -static int __devexit armada_xp_pinctrl_remove(struct platform_device *pdev) -{ - return mvebu_pinctrl_remove(pdev); -} - -static struct platform_driver armada_xp_pinctrl_driver = { - .driver = { - .name = "armada-xp-pinctrl", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(armada_xp_pinctrl_of_match), - }, - .probe = armada_xp_pinctrl_probe, - .remove = __devexit_p(armada_xp_pinctrl_remove), -}; - -module_platform_driver(armada_xp_pinctrl_driver); - -MODULE_AUTHOR("Thomas Petazzoni "); -MODULE_DESCRIPTION("Marvell Armada XP pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-dove.c b/drivers/pinctrl/pinctrl-dove.c deleted file mode 100644 index ffe74b27d66..00000000000 --- a/drivers/pinctrl/pinctrl-dove.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - * Marvell Dove pinctrl driver based on mvebu pinctrl core - * - * Author: Sebastian Hesselbarth - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pinctrl-mvebu.h" - -#define DOVE_SB_REGS_VIRT_BASE 0xfde00000 -#define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0200) -#define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10) -#define DOVE_AU0_AC97_SEL BIT(16) -#define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE | 0xe802C) -#define DOVE_TWSI_ENABLE_OPTION1 BIT(7) -#define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE | 0xe8030) -#define DOVE_TWSI_ENABLE_OPTION2 BIT(20) -#define DOVE_TWSI_ENABLE_OPTION3 BIT(21) -#define DOVE_TWSI_OPTION3_GPIO BIT(22) -#define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE | 0xe8034) -#define DOVE_SSP_ON_AU1 BIT(0) -#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c) -#define DOVE_AU1_SPDIFO_GPIO_EN BIT(1) -#define DOVE_NAND_GPIO_EN BIT(0) -#define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0400) -#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40) -#define DOVE_SPI_GPIO_SEL BIT(5) -#define DOVE_UART1_GPIO_SEL BIT(4) -#define DOVE_AU1_GPIO_SEL BIT(3) -#define DOVE_CAM_GPIO_SEL BIT(2) -#define DOVE_SD1_GPIO_SEL BIT(1) -#define DOVE_SD0_GPIO_SEL BIT(0) - -#define MPPS_PER_REG 8 -#define MPP_BITS 4 -#define MPP_MASK 0xf - -#define CONFIG_PMU BIT(4) - -static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl *ctrl, - unsigned long *config) -{ - unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS; - unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS; - unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); - unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off); - - if (pmu & (1 << ctrl->pid)) - *config = CONFIG_PMU; - else - *config = (mpp >> shift) & MPP_MASK; - return 0; -} - -static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl, - unsigned long config) -{ - unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS; - unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS; - unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); - unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off); - - if (config == CONFIG_PMU) - writel(pmu | (1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL); - else { - writel(pmu & ~(1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL); - mpp &= ~(MPP_MASK << shift); - mpp |= config << shift; - writel(mpp, DOVE_MPP_VIRT_BASE + off); - } - return 0; -} - -static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl, - unsigned long *config) -{ - unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); - unsigned long mask; - - switch (ctrl->pid) { - case 24: /* mpp_camera */ - mask = DOVE_CAM_GPIO_SEL; - break; - case 40: /* mpp_sdio0 */ - mask = DOVE_SD0_GPIO_SEL; - break; - case 46: /* mpp_sdio1 */ - mask = DOVE_SD1_GPIO_SEL; - break; - case 58: /* mpp_spi0 */ - mask = DOVE_SPI_GPIO_SEL; - break; - case 62: /* mpp_uart1 */ - mask = DOVE_UART1_GPIO_SEL; - break; - default: - return -EINVAL; - } - - *config = ((mpp4 & mask) != 0); - - return 0; -} - -static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl, - unsigned long config) -{ - unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); - unsigned long mask; - - switch (ctrl->pid) { - case 24: /* mpp_camera */ - mask = DOVE_CAM_GPIO_SEL; - break; - case 40: /* mpp_sdio0 */ - mask = DOVE_SD0_GPIO_SEL; - break; - case 46: /* mpp_sdio1 */ - mask = DOVE_SD1_GPIO_SEL; - break; - case 58: /* mpp_spi0 */ - mask = DOVE_SPI_GPIO_SEL; - break; - case 62: /* mpp_uart1 */ - mask = DOVE_UART1_GPIO_SEL; - break; - default: - return -EINVAL; - } - - mpp4 &= ~mask; - if (config) - mpp4 |= mask; - - writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE); - - return 0; -} - -static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl, - unsigned long *config) -{ - unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); - - *config = ((gmpp & DOVE_NAND_GPIO_EN) != 0); - - return 0; -} - -static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl, - unsigned long config) -{ - unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); - - gmpp &= ~DOVE_NAND_GPIO_EN; - if (config) - gmpp |= DOVE_NAND_GPIO_EN; - - writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE); - - return 0; -} - -static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl, - unsigned long *config) -{ - unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); - - *config = ((pmu & DOVE_AU0_AC97_SEL) != 0); - - return 0; -} - -static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl, - unsigned long config) -{ - unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); - - pmu &= ~DOVE_AU0_AC97_SEL; - if (config) - pmu |= DOVE_AU0_AC97_SEL; - writel(pmu, DOVE_PMU_MPP_GENERAL_CTRL); - - return 0; -} - -static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl, - unsigned long *config) -{ - unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); - unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1); - unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); - unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); - - *config = 0; - if (mpp4 & DOVE_AU1_GPIO_SEL) - *config |= BIT(3); - if (sspc1 & DOVE_SSP_ON_AU1) - *config |= BIT(2); - if (gmpp & DOVE_AU1_SPDIFO_GPIO_EN) - *config |= BIT(1); - if (gcfg2 & DOVE_TWSI_OPTION3_GPIO) - *config |= BIT(0); - - /* SSP/TWSI only if I2S1 not set*/ - if ((*config & BIT(3)) == 0) - *config &= ~(BIT(2) | BIT(0)); - /* TWSI only if SPDIFO not set*/ - if ((*config & BIT(1)) == 0) - *config &= ~BIT(0); - return 0; -} - -static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl, - unsigned long config) -{ - unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); - unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1); - unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); - unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); - - if (config & BIT(0)) - gcfg2 |= DOVE_TWSI_OPTION3_GPIO; - if (config & BIT(1)) - gmpp |= DOVE_AU1_SPDIFO_GPIO_EN; - if (config & BIT(2)) - sspc1 |= DOVE_SSP_ON_AU1; - if (config & BIT(3)) - mpp4 |= DOVE_AU1_GPIO_SEL; - - writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE); - writel(sspc1, DOVE_SSP_CTRL_STATUS_1); - writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE); - writel(gcfg2, DOVE_GLOBAL_CONFIG_2); - - return 0; -} - -/* mpp[52:57] gpio pins depend heavily on current config; - * gpio_req does not try to mux in gpio capabilities to not - * break other functions. If you require all mpps as gpio - * enforce gpio setting by pinctrl mapping. - */ -static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid) -{ - unsigned long config; - - dove_audio1_ctrl_get(ctrl, &config); - - switch (config) { - case 0x02: /* i2s1 : gpio[56:57] */ - case 0x0e: /* ssp : gpio[56:57] */ - if (pid >= 56) - return 0; - return -ENOTSUPP; - case 0x08: /* spdifo : gpio[52:55] */ - case 0x0b: /* twsi : gpio[52:55] */ - if (pid <= 55) - return 0; - return -ENOTSUPP; - case 0x0a: /* all gpio */ - return 0; - /* 0x00 : i2s1/spdifo : no gpio */ - /* 0x0c : ssp/spdifo : no gpio */ - /* 0x0f : ssp/twsi : no gpio */ - } - return -ENOTSUPP; -} - -/* mpp[52:57] has gpio pins capable of in and out */ -static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl *ctrl, u8 pid, - bool input) -{ - if (pid < 52 || pid > 57) - return -ENOTSUPP; - return 0; -} - -static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl, - unsigned long *config) -{ - unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1); - unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); - - *config = 0; - if (gcfg1 & DOVE_TWSI_ENABLE_OPTION1) - *config = 1; - else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION2) - *config = 2; - else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION3) - *config = 3; - - return 0; -} - -static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl, - unsigned long config) -{ - unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1); - unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); - - gcfg1 &= ~DOVE_TWSI_ENABLE_OPTION1; - gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION2); - - switch (config) { - case 1: - gcfg1 |= DOVE_TWSI_ENABLE_OPTION1; - break; - case 2: - gcfg2 |= DOVE_TWSI_ENABLE_OPTION2; - break; - case 3: - gcfg2 |= DOVE_TWSI_ENABLE_OPTION3; - break; - } - - writel(gcfg1, DOVE_GLOBAL_CONFIG_1); - writel(gcfg2, DOVE_GLOBAL_CONFIG_2); - - return 0; -} - -static struct mvebu_mpp_ctrl dove_mpp_controls[] = { - MPP_FUNC_CTRL(0, 0, "mpp0", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(1, 1, "mpp1", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(2, 2, "mpp2", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(3, 3, "mpp3", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(4, 4, "mpp4", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(5, 5, "mpp5", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(6, 6, "mpp6", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(7, 7, "mpp7", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(8, 8, "mpp8", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(9, 9, "mpp9", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(10, 10, "mpp10", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(11, 11, "mpp11", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(12, 12, "mpp12", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(13, 13, "mpp13", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(14, 14, "mpp14", dove_pmu_mpp_ctrl), - MPP_FUNC_CTRL(15, 15, "mpp15", dove_pmu_mpp_ctrl), - MPP_REG_CTRL(16, 23), - MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl), - MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl), - MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl), - MPP_FUNC_GPIO_CTRL(52, 57, "mpp_audio1", dove_audio1_ctrl), - MPP_FUNC_CTRL(58, 61, "mpp_spi0", dove_mpp4_ctrl), - MPP_FUNC_CTRL(62, 63, "mpp_uart1", dove_mpp4_ctrl), - MPP_FUNC_CTRL(64, 71, "mpp_nand", dove_nand_ctrl), - MPP_FUNC_CTRL(72, 72, "audio0", dove_audio0_ctrl), - MPP_FUNC_CTRL(73, 73, "twsi", dove_twsi_ctrl), -}; - -static struct mvebu_mpp_mode dove_mpp_modes[] = { - MPP_MODE(0, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "uart2", "rts"), - MPP_FUNCTION(0x03, "sdio0", "cd"), - MPP_FUNCTION(0x0f, "lcd0", "pwm"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(1, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "uart2", "cts"), - MPP_FUNCTION(0x03, "sdio0", "wp"), - MPP_FUNCTION(0x0f, "lcd1", "pwm"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(2, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x01, "sata", "prsnt"), - MPP_FUNCTION(0x02, "uart2", "txd"), - MPP_FUNCTION(0x03, "sdio0", "buspwr"), - MPP_FUNCTION(0x04, "uart1", "rts"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(3, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x01, "sata", "act"), - MPP_FUNCTION(0x02, "uart2", "rxd"), - MPP_FUNCTION(0x03, "sdio0", "ledctrl"), - MPP_FUNCTION(0x04, "uart1", "cts"), - MPP_FUNCTION(0x0f, "lcd-spi", "cs1"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(4, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "uart3", "rts"), - MPP_FUNCTION(0x03, "sdio1", "cd"), - MPP_FUNCTION(0x04, "spi1", "miso"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(5, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "uart3", "cts"), - MPP_FUNCTION(0x03, "sdio1", "wp"), - MPP_FUNCTION(0x04, "spi1", "cs"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(6, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "uart3", "txd"), - MPP_FUNCTION(0x03, "sdio1", "buspwr"), - MPP_FUNCTION(0x04, "spi1", "mosi"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(7, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "uart3", "rxd"), - MPP_FUNCTION(0x03, "sdio1", "ledctrl"), - MPP_FUNCTION(0x04, "spi1", "sck"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(8, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x01, "watchdog", "rstout"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(9, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x05, "pex1", "clkreq"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(10, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x05, "ssp", "sclk"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(11, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x01, "sata", "prsnt"), - MPP_FUNCTION(0x02, "sata-1", "act"), - MPP_FUNCTION(0x03, "sdio0", "ledctrl"), - MPP_FUNCTION(0x04, "sdio1", "ledctrl"), - MPP_FUNCTION(0x05, "pex0", "clkreq"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(12, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x01, "sata", "act"), - MPP_FUNCTION(0x02, "uart2", "rts"), - MPP_FUNCTION(0x03, "audio0", "extclk"), - MPP_FUNCTION(0x04, "sdio1", "cd"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(13, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "uart2", "cts"), - MPP_FUNCTION(0x03, "audio1", "extclk"), - MPP_FUNCTION(0x04, "sdio1", "wp"), - MPP_FUNCTION(0x05, "ssp", "extclk"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(14, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "uart2", "txd"), - MPP_FUNCTION(0x04, "sdio1", "buspwr"), - MPP_FUNCTION(0x05, "ssp", "rxd"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(15, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "uart2", "rxd"), - MPP_FUNCTION(0x04, "sdio1", "ledctrl"), - MPP_FUNCTION(0x05, "ssp", "sfrm"), - MPP_FUNCTION(0x10, "pmu", NULL)), - MPP_MODE(16, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "uart3", "rts"), - MPP_FUNCTION(0x03, "sdio0", "cd"), - MPP_FUNCTION(0x04, "lcd-spi", "cs1"), - MPP_FUNCTION(0x05, "ac97", "sdi1")), - MPP_MODE(17, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x01, "ac97-1", "sysclko"), - MPP_FUNCTION(0x02, "uart3", "cts"), - MPP_FUNCTION(0x03, "sdio0", "wp"), - MPP_FUNCTION(0x04, "twsi", "sda"), - MPP_FUNCTION(0x05, "ac97", "sdi2")), - MPP_MODE(18, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "uart3", "txd"), - MPP_FUNCTION(0x03, "sdio0", "buspwr"), - MPP_FUNCTION(0x04, "lcd0", "pwm"), - MPP_FUNCTION(0x05, "ac97", "sdi3")), - MPP_MODE(19, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "uart3", "rxd"), - MPP_FUNCTION(0x03, "sdio0", "ledctrl"), - MPP_FUNCTION(0x04, "twsi", "sck")), - MPP_MODE(20, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x01, "ac97", "sysclko"), - MPP_FUNCTION(0x02, "lcd-spi", "miso"), - MPP_FUNCTION(0x03, "sdio1", "cd"), - MPP_FUNCTION(0x05, "sdio0", "cd"), - MPP_FUNCTION(0x06, "spi1", "miso")), - MPP_MODE(21, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x01, "uart1", "rts"), - MPP_FUNCTION(0x02, "lcd-spi", "cs0"), - MPP_FUNCTION(0x03, "sdio1", "wp"), - MPP_FUNCTION(0x04, "ssp", "sfrm"), - MPP_FUNCTION(0x05, "sdio0", "wp"), - MPP_FUNCTION(0x06, "spi1", "cs")), - MPP_MODE(22, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x01, "uart1", "cts"), - MPP_FUNCTION(0x02, "lcd-spi", "mosi"), - MPP_FUNCTION(0x03, "sdio1", "buspwr"), - MPP_FUNCTION(0x04, "ssp", "txd"), - MPP_FUNCTION(0x05, "sdio0", "buspwr"), - MPP_FUNCTION(0x06, "spi1", "mosi")), - MPP_MODE(23, - MPP_FUNCTION(0x00, "gpio", NULL), - MPP_FUNCTION(0x02, "lcd-spi", "sck"), - MPP_FUNCTION(0x03, "sdio1", "ledctrl"), - MPP_FUNCTION(0x04, "ssp", "sclk"), - MPP_FUNCTION(0x05, "sdio0", "ledctrl"), - MPP_FUNCTION(0x06, "spi1", "sck")), - MPP_MODE(24, - MPP_FUNCTION(0x00, "camera", NULL), - MPP_FUNCTION(0x01, "gpio", NULL)), - MPP_MODE(40, - MPP_FUNCTION(0x00, "sdio0", NULL), - MPP_FUNCTION(0x01, "gpio", NULL)), - MPP_MODE(46, - MPP_FUNCTION(0x00, "sdio1", NULL), - MPP_FUNCTION(0x01, "gpio", NULL)), - MPP_MODE(52, - MPP_FUNCTION(0x00, "i2s1/spdifo", NULL), - MPP_FUNCTION(0x02, "i2s1", NULL), - MPP_FUNCTION(0x08, "spdifo", NULL), - MPP_FUNCTION(0x0a, "gpio", NULL), - MPP_FUNCTION(0x0b, "twsi", NULL), - MPP_FUNCTION(0x0c, "ssp/spdifo", NULL), - MPP_FUNCTION(0x0e, "ssp", NULL), - MPP_FUNCTION(0x0f, "ssp/twsi", NULL)), - MPP_MODE(58, - MPP_FUNCTION(0x00, "spi0", NULL), - MPP_FUNCTION(0x01, "gpio", NULL)), - MPP_MODE(62, - MPP_FUNCTION(0x00, "uart1", NULL), - MPP_FUNCTION(0x01, "gpio", NULL)), - MPP_MODE(64, - MPP_FUNCTION(0x00, "nand", NULL), - MPP_FUNCTION(0x01, "gpo", NULL)), - MPP_MODE(72, - MPP_FUNCTION(0x00, "i2s", NULL), - MPP_FUNCTION(0x01, "ac97", NULL)), - MPP_MODE(73, - MPP_FUNCTION(0x00, "twsi-none", NULL), - MPP_FUNCTION(0x01, "twsi-opt1", NULL), - MPP_FUNCTION(0x02, "twsi-opt2", NULL), - MPP_FUNCTION(0x03, "twsi-opt3", NULL)), -}; - -static struct pinctrl_gpio_range dove_mpp_gpio_ranges[] = { - MPP_GPIO_RANGE(0, 0, 0, 32), - MPP_GPIO_RANGE(1, 32, 32, 32), - MPP_GPIO_RANGE(2, 64, 64, 8), -}; - -static struct mvebu_pinctrl_soc_info dove_pinctrl_info = { - .controls = dove_mpp_controls, - .ncontrols = ARRAY_SIZE(dove_mpp_controls), - .modes = dove_mpp_modes, - .nmodes = ARRAY_SIZE(dove_mpp_modes), - .gpioranges = dove_mpp_gpio_ranges, - .ngpioranges = ARRAY_SIZE(dove_mpp_gpio_ranges), - .variant = 0, -}; - -static struct clk *clk; - -static struct of_device_id dove_pinctrl_of_match[] __devinitdata = { - { .compatible = "marvell,dove-pinctrl", .data = &dove_pinctrl_info }, - { } -}; - -static int __devinit dove_pinctrl_probe(struct platform_device *pdev) -{ - const struct of_device_id *match = - of_match_device(dove_pinctrl_of_match, &pdev->dev); - pdev->dev.platform_data = match->data; - - /* - * General MPP Configuration Register is part of pdma registers. - * grab clk to make sure it is ticking. - */ - clk = devm_clk_get(&pdev->dev, NULL); - if (!IS_ERR(clk)) - clk_prepare_enable(clk); - - return mvebu_pinctrl_probe(pdev); -} - -static int __devexit dove_pinctrl_remove(struct platform_device *pdev) -{ - int ret; - - ret = mvebu_pinctrl_remove(pdev); - if (!IS_ERR(clk)) - clk_disable_unprepare(clk); - return ret; -} - -static struct platform_driver dove_pinctrl_driver = { - .driver = { - .name = "dove-pinctrl", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(dove_pinctrl_of_match), - }, - .probe = dove_pinctrl_probe, - .remove = __devexit_p(dove_pinctrl_remove), -}; - -module_platform_driver(dove_pinctrl_driver); - -MODULE_AUTHOR("Sebastian Hesselbarth "); -MODULE_DESCRIPTION("Marvell Dove pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-kirkwood.c b/drivers/pinctrl/pinctrl-kirkwood.c deleted file mode 100644 index 9a74ef674a0..00000000000 --- a/drivers/pinctrl/pinctrl-kirkwood.c +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Marvell Kirkwood pinctrl driver based on mvebu pinctrl core - * - * Author: Sebastian Hesselbarth - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pinctrl-mvebu.h" - -#define V(f6180, f6190, f6192, f6281, f6282) \ - ((f6180 << 0) | (f6190 << 1) | (f6192 << 2) | \ - (f6281 << 3) | (f6282 << 4)) - -enum kirkwood_variant { - VARIANT_MV88F6180 = V(1, 0, 0, 0, 0), - VARIANT_MV88F6190 = V(0, 1, 0, 0, 0), - VARIANT_MV88F6192 = V(0, 0, 1, 0, 0), - VARIANT_MV88F6281 = V(0, 0, 0, 1, 0), - VARIANT_MV88F6282 = V(0, 0, 0, 0, 1), -}; - -static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = { - MPP_MODE(0, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "nand", "io2", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1))), - MPP_MODE(1, - MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "nand", "io3", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "spi", "mosi", V(1, 1, 1, 1, 1))), - MPP_MODE(2, - MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "nand", "io4", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1))), - MPP_MODE(3, - MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "nand", "io5", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1))), - MPP_MODE(4, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "nand", "io6", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "uart0", "rxd", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1)), - MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0))), - MPP_MODE(5, - MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "nand", "io7", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "uart0", "txd", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "ptp", "trig", V(1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1))), - MPP_MODE(6, - MPP_VAR_FUNCTION(0x0, "sysrst", "out", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "spi", "mosi", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "ptp", "trig", V(1, 1, 1, 1, 0))), - MPP_MODE(7, - MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "pex", "rsto", V(1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ptp", "trig", V(1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1))), - MPP_MODE(8, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "twsi0", "sda", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "uart1", "rts", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "mii-1", "rxerr", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0xc, "ptp", "clk", V(1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1))), - MPP_MODE(9, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "twsi0", "sck", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "uart1", "cts", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xc, "ptp", "evreq", V(1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1))), - MPP_MODE(10, - MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0X3, "uart0", "txd", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0xc, "ptp", "trig", V(1, 1, 1, 1, 0))), - MPP_MODE(11, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "uart0", "rxd", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "ptp-1", "evreq", V(1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0xc, "ptp-2", "trig", V(1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1))), - MPP_MODE(12, - MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 0, 1)), - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0)), - MPP_VAR_FUNCTION(0x1, "sdio", "clk", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xa, "audio", "spdifo", V(0, 0, 0, 0, 1)), - MPP_VAR_FUNCTION(0xb, "spi", "mosi", V(0, 0, 0, 0, 1)), - MPP_VAR_FUNCTION(0xd, "twsi1", "sda", V(0, 0, 0, 0, 1))), - MPP_MODE(13, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "sdio", "cmd", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xa, "audio", "rmclk", V(0, 0, 0, 0, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1))), - MPP_MODE(14, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "sdio", "d0", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0xa, "audio", "spdifi", V(0, 0, 0, 0, 1)), - MPP_VAR_FUNCTION(0xb, "audio-1", "sdi", V(0, 0, 0, 0, 1)), - MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1))), - MPP_MODE(15, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "sdio", "d1", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "sata0", "act", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "spi", "cs", V(0, 0, 0, 0, 1))), - MPP_MODE(16, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "sdio", "d2", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "sata1", "act", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "extclk", V(0, 0, 0, 0, 1)), - MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1))), - MPP_MODE(17, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "sdio", "d3", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xa, "sata1", "act", V(0, 0, 0, 0, 1)), - MPP_VAR_FUNCTION(0xd, "twsi1", "sck", V(0, 0, 0, 0, 1))), - MPP_MODE(18, - MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "nand", "io0", V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "pex", "clkreq", V(0, 0, 0, 0, 1))), - MPP_MODE(19, - MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "nand", "io1", V(1, 1, 1, 1, 1))), - MPP_MODE(20, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "txd0", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d0", V(0, 0, 0, 0, 1)), - MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 0, 0, 0, 0))), - MPP_MODE(21, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "txd1", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 0, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d1", V(0, 0, 0, 0, 1))), - MPP_MODE(22, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "txd2", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 0, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d2", V(0, 0, 0, 0, 1))), - MPP_MODE(23, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "txd3", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 0, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d3", V(0, 0, 0, 0, 1))), - MPP_MODE(24, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "rxd0", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 0, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d4", V(0, 0, 0, 0, 1))), - MPP_MODE(25, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "rxd1", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 0, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d5", V(0, 0, 0, 0, 1))), - MPP_MODE(26, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "rxd2", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 0, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d6", V(0, 0, 0, 0, 1))), - MPP_MODE(27, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "rxd3", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 0, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d7", V(0, 0, 0, 0, 1))), - MPP_MODE(28, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "col", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 0, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d8", V(0, 0, 0, 0, 1))), - MPP_MODE(29, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "txclk", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 0, 0)), - MPP_VAR_FUNCTION(0xb, "lcd", "d9", V(0, 0, 0, 0, 1))), - MPP_MODE(30, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "rxctl", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d10", V(0, 0, 0, 0, 1))), - MPP_MODE(31, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "rxclk", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d11", V(0, 0, 0, 0, 1))), - MPP_MODE(32, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "txclko", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d12", V(0, 0, 0, 0, 1))), - MPP_MODE(33, - MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "txctl", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d13", V(0, 0, 0, 0, 1))), - MPP_MODE(34, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "txen", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d14", V(0, 0, 0, 0, 1))), - MPP_MODE(35, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1)), - MPP_VAR_FUNCTION(0x3, "ge1", "rxerr", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d15", V(0, 0, 0, 0, 1)), - MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 1, 1, 1, 1))), - MPP_MODE(36, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "twsi1", "sda", V(0, 0, 0, 0, 1))), - MPP_MODE(37, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "twsi1", "sck", V(0, 0, 0, 0, 1))), - MPP_MODE(38, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d18", V(0, 0, 0, 0, 1))), - MPP_MODE(39, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d19", V(0, 0, 0, 0, 1))), - MPP_MODE(40, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d20", V(0, 0, 0, 0, 1))), - MPP_MODE(41, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d21", V(0, 0, 0, 0, 1))), - MPP_MODE(42, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d22", V(0, 0, 0, 0, 1))), - MPP_MODE(43, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d23", V(0, 0, 0, 0, 1))), - MPP_MODE(44, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "clk", V(0, 0, 0, 0, 1))), - MPP_MODE(45, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "e", V(0, 0, 0, 0, 1))), - MPP_MODE(46, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1))), - MPP_MODE(47, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1))), - MPP_MODE(48, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d16", V(0, 0, 0, 0, 1))), - MPP_MODE(49, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0)), - MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 0, 0, 0, 1)), - MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 0)), - MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 0, 1, 1)), - MPP_VAR_FUNCTION(0x5, "ptp", "clk", V(0, 0, 0, 1, 0)), - MPP_VAR_FUNCTION(0xa, "pex", "clkreq", V(0, 0, 0, 0, 1)), - MPP_VAR_FUNCTION(0xb, "lcd", "d17", V(0, 0, 0, 0, 1))), -}; - -static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = { - MPP_REG_CTRL(0, 29), -}; - -static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = { - MPP_GPIO_RANGE(0, 0, 0, 30), -}; - -static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = { - MPP_REG_CTRL(0, 35), -}; - -static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = { - MPP_GPIO_RANGE(0, 0, 0, 32), - MPP_GPIO_RANGE(1, 32, 32, 4), -}; - -static struct mvebu_mpp_ctrl mv88f628x_mpp_controls[] = { - MPP_REG_CTRL(0, 49), -}; - -static struct pinctrl_gpio_range mv88f628x_gpio_ranges[] = { - MPP_GPIO_RANGE(0, 0, 0, 32), - MPP_GPIO_RANGE(1, 32, 32, 18), -}; - -static struct mvebu_pinctrl_soc_info mv88f6180_info = { - .variant = VARIANT_MV88F6180, - .controls = mv88f6180_mpp_controls, - .ncontrols = ARRAY_SIZE(mv88f6180_mpp_controls), - .modes = mv88f6xxx_mpp_modes, - .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), - .gpioranges = mv88f6180_gpio_ranges, - .ngpioranges = ARRAY_SIZE(mv88f6180_gpio_ranges), -}; - -static struct mvebu_pinctrl_soc_info mv88f6190_info = { - .variant = VARIANT_MV88F6190, - .controls = mv88f619x_mpp_controls, - .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls), - .modes = mv88f6xxx_mpp_modes, - .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), - .gpioranges = mv88f619x_gpio_ranges, - .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges), -}; - -static struct mvebu_pinctrl_soc_info mv88f6192_info = { - .variant = VARIANT_MV88F6192, - .controls = mv88f619x_mpp_controls, - .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls), - .modes = mv88f6xxx_mpp_modes, - .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), - .gpioranges = mv88f619x_gpio_ranges, - .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges), -}; - -static struct mvebu_pinctrl_soc_info mv88f6281_info = { - .variant = VARIANT_MV88F6281, - .controls = mv88f628x_mpp_controls, - .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls), - .modes = mv88f6xxx_mpp_modes, - .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), - .gpioranges = mv88f628x_gpio_ranges, - .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges), -}; - -static struct mvebu_pinctrl_soc_info mv88f6282_info = { - .variant = VARIANT_MV88F6282, - .controls = mv88f628x_mpp_controls, - .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls), - .modes = mv88f6xxx_mpp_modes, - .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), - .gpioranges = mv88f628x_gpio_ranges, - .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges), -}; - -static struct of_device_id kirkwood_pinctrl_of_match[] __devinitdata = { - { .compatible = "marvell,88f6180-pinctrl", .data = &mv88f6180_info }, - { .compatible = "marvell,88f6190-pinctrl", .data = &mv88f6190_info }, - { .compatible = "marvell,88f6192-pinctrl", .data = &mv88f6192_info }, - { .compatible = "marvell,88f6281-pinctrl", .data = &mv88f6281_info }, - { .compatible = "marvell,88f6282-pinctrl", .data = &mv88f6282_info }, - { } -}; - -static int __devinit kirkwood_pinctrl_probe(struct platform_device *pdev) -{ - const struct of_device_id *match = - of_match_device(kirkwood_pinctrl_of_match, &pdev->dev); - pdev->dev.platform_data = match->data; - return mvebu_pinctrl_probe(pdev); -} - -static int __devexit kirkwood_pinctrl_remove(struct platform_device *pdev) -{ - return mvebu_pinctrl_remove(pdev); -} - -static struct platform_driver kirkwood_pinctrl_driver = { - .driver = { - .name = "kirkwood-pinctrl", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(kirkwood_pinctrl_of_match), - }, - .probe = kirkwood_pinctrl_probe, - .remove = __devexit_p(kirkwood_pinctrl_remove), -}; - -module_platform_driver(kirkwood_pinctrl_driver); - -MODULE_AUTHOR("Sebastian Hesselbarth "); -MODULE_DESCRIPTION("Marvell Kirkwood pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-mvebu.c b/drivers/pinctrl/pinctrl-mvebu.c deleted file mode 100644 index 6c44b7e8964..00000000000 --- a/drivers/pinctrl/pinctrl-mvebu.c +++ /dev/null @@ -1,753 +0,0 @@ -/* - * Marvell MVEBU pinctrl core driver - * - * Authors: Sebastian Hesselbarth - * Thomas Petazzoni - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pinctrl-mvebu.h" - -#define MPPS_PER_REG 8 -#define MPP_BITS 4 -#define MPP_MASK 0xf - -struct mvebu_pinctrl_function { - const char *name; - const char **groups; - unsigned num_groups; -}; - -struct mvebu_pinctrl_group { - const char *name; - struct mvebu_mpp_ctrl *ctrl; - struct mvebu_mpp_ctrl_setting *settings; - unsigned num_settings; - unsigned gid; - unsigned *pins; - unsigned npins; -}; - -struct mvebu_pinctrl { - struct device *dev; - struct pinctrl_dev *pctldev; - struct pinctrl_desc desc; - void __iomem *base; - struct mvebu_pinctrl_group *groups; - unsigned num_groups; - struct mvebu_pinctrl_function *functions; - unsigned num_functions; - u8 variant; -}; - -static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_pid( - struct mvebu_pinctrl *pctl, unsigned pid) -{ - unsigned n; - for (n = 0; n < pctl->num_groups; n++) { - if (pid >= pctl->groups[n].pins[0] && - pid < pctl->groups[n].pins[0] + - pctl->groups[n].npins) - return &pctl->groups[n]; - } - return NULL; -} - -static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_name( - struct mvebu_pinctrl *pctl, const char *name) -{ - unsigned n; - for (n = 0; n < pctl->num_groups; n++) { - if (strcmp(name, pctl->groups[n].name) == 0) - return &pctl->groups[n]; - } - return NULL; -} - -static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_val( - struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp, - unsigned long config) -{ - unsigned n; - for (n = 0; n < grp->num_settings; n++) { - if (config == grp->settings[n].val) { - if (!pctl->variant || (pctl->variant & - grp->settings[n].variant)) - return &grp->settings[n]; - } - } - return NULL; -} - -static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_name( - struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp, - const char *name) -{ - unsigned n; - for (n = 0; n < grp->num_settings; n++) { - if (strcmp(name, grp->settings[n].name) == 0) { - if (!pctl->variant || (pctl->variant & - grp->settings[n].variant)) - return &grp->settings[n]; - } - } - return NULL; -} - -static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_gpio_setting( - struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp) -{ - unsigned n; - for (n = 0; n < grp->num_settings; n++) { - if (grp->settings[n].flags & - (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) { - if (!pctl->variant || (pctl->variant & - grp->settings[n].variant)) - return &grp->settings[n]; - } - } - return NULL; -} - -static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name( - struct mvebu_pinctrl *pctl, const char *name) -{ - unsigned n; - for (n = 0; n < pctl->num_functions; n++) { - if (strcmp(name, pctl->functions[n].name) == 0) - return &pctl->functions[n]; - } - return NULL; -} - -/* - * Common mpp pin configuration registers on MVEBU are - * registers of eight 4-bit values for each mpp setting. - * Register offset and bit mask are calculated accordingly below. - */ -static int mvebu_common_mpp_get(struct mvebu_pinctrl *pctl, - struct mvebu_pinctrl_group *grp, - unsigned long *config) -{ - unsigned pin = grp->gid; - unsigned off = (pin / MPPS_PER_REG) * MPP_BITS; - unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS; - - *config = readl(pctl->base + off); - *config >>= shift; - *config &= MPP_MASK; - - return 0; -} - -static int mvebu_common_mpp_set(struct mvebu_pinctrl *pctl, - struct mvebu_pinctrl_group *grp, - unsigned long config) -{ - unsigned pin = grp->gid; - unsigned off = (pin / MPPS_PER_REG) * MPP_BITS; - unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS; - unsigned long reg; - - reg = readl(pctl->base + off); - reg &= ~(MPP_MASK << shift); - reg |= (config << shift); - writel(reg, pctl->base + off); - - return 0; -} - -static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev, - unsigned gid, unsigned long *config) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; - - if (!grp->ctrl) - return -EINVAL; - - if (grp->ctrl->mpp_get) - return grp->ctrl->mpp_get(grp->ctrl, config); - - return mvebu_common_mpp_get(pctl, grp, config); -} - -static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev, - unsigned gid, unsigned long config) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; - - if (!grp->ctrl) - return -EINVAL; - - if (grp->ctrl->mpp_set) - return grp->ctrl->mpp_set(grp->ctrl, config); - - return mvebu_common_mpp_set(pctl, grp, config); -} - -static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, unsigned gid) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; - struct mvebu_mpp_ctrl_setting *curr; - unsigned long config; - unsigned n; - - if (mvebu_pinconf_group_get(pctldev, gid, &config)) - return; - - curr = mvebu_pinctrl_find_setting_by_val(pctl, grp, config); - - if (curr) { - seq_printf(s, "current: %s", curr->name); - if (curr->subname) - seq_printf(s, "(%s)", curr->subname); - if (curr->flags & (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) { - seq_printf(s, "("); - if (curr->flags & MVEBU_SETTING_GPI) - seq_printf(s, "i"); - if (curr->flags & MVEBU_SETTING_GPO) - seq_printf(s, "o"); - seq_printf(s, ")"); - } - } else - seq_printf(s, "current: UNKNOWN"); - - if (grp->num_settings > 1) { - seq_printf(s, ", available = ["); - for (n = 0; n < grp->num_settings; n++) { - if (curr == &grp->settings[n]) - continue; - - /* skip unsupported settings for this variant */ - if (pctl->variant && - !(pctl->variant & grp->settings[n].variant)) - continue; - - seq_printf(s, " %s", grp->settings[n].name); - if (grp->settings[n].subname) - seq_printf(s, "(%s)", grp->settings[n].subname); - if (grp->settings[n].flags & - (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) { - seq_printf(s, "("); - if (grp->settings[n].flags & MVEBU_SETTING_GPI) - seq_printf(s, "i"); - if (grp->settings[n].flags & MVEBU_SETTING_GPO) - seq_printf(s, "o"); - seq_printf(s, ")"); - } - } - seq_printf(s, " ]"); - } - return; -} - -static struct pinconf_ops mvebu_pinconf_ops = { - .pin_config_group_get = mvebu_pinconf_group_get, - .pin_config_group_set = mvebu_pinconf_group_set, - .pin_config_group_dbg_show = mvebu_pinconf_group_dbg_show, -}; - -static int mvebu_pinmux_get_funcs_count(struct pinctrl_dev *pctldev) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - - return pctl->num_functions; -} - -static const char *mvebu_pinmux_get_func_name(struct pinctrl_dev *pctldev, - unsigned fid) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - - return pctl->functions[fid].name; -} - -static int mvebu_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned fid, - const char * const **groups, - unsigned * const num_groups) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - - *groups = pctl->functions[fid].groups; - *num_groups = pctl->functions[fid].num_groups; - return 0; -} - -static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid, - unsigned gid) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct mvebu_pinctrl_function *func = &pctl->functions[fid]; - struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; - struct mvebu_mpp_ctrl_setting *setting; - int ret; - - setting = mvebu_pinctrl_find_setting_by_name(pctl, grp, - func->name); - if (!setting) { - dev_err(pctl->dev, - "unable to find setting %s in group %s\n", - func->name, func->groups[gid]); - return -EINVAL; - } - - ret = mvebu_pinconf_group_set(pctldev, grp->gid, setting->val); - if (ret) { - dev_err(pctl->dev, "cannot set group %s to %s\n", - func->groups[gid], func->name); - return ret; - } - - return 0; -} - -static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, unsigned offset) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct mvebu_pinctrl_group *grp; - struct mvebu_mpp_ctrl_setting *setting; - - grp = mvebu_pinctrl_find_group_by_pid(pctl, offset); - if (!grp) - return -EINVAL; - - if (grp->ctrl->mpp_gpio_req) - return grp->ctrl->mpp_gpio_req(grp->ctrl, offset); - - setting = mvebu_pinctrl_find_gpio_setting(pctl, grp); - if (!setting) - return -ENOTSUPP; - - return mvebu_pinconf_group_set(pctldev, grp->gid, setting->val); -} - -static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, unsigned offset, bool input) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct mvebu_pinctrl_group *grp; - struct mvebu_mpp_ctrl_setting *setting; - - grp = mvebu_pinctrl_find_group_by_pid(pctl, offset); - if (!grp) - return -EINVAL; - - if (grp->ctrl->mpp_gpio_dir) - return grp->ctrl->mpp_gpio_dir(grp->ctrl, offset, input); - - setting = mvebu_pinctrl_find_gpio_setting(pctl, grp); - if (!setting) - return -ENOTSUPP; - - if ((input && (setting->flags & MVEBU_SETTING_GPI)) || - (!input && (setting->flags & MVEBU_SETTING_GPO))) - return 0; - - return -ENOTSUPP; -} - -static struct pinmux_ops mvebu_pinmux_ops = { - .get_functions_count = mvebu_pinmux_get_funcs_count, - .get_function_name = mvebu_pinmux_get_func_name, - .get_function_groups = mvebu_pinmux_get_groups, - .gpio_request_enable = mvebu_pinmux_gpio_request_enable, - .gpio_set_direction = mvebu_pinmux_gpio_set_direction, - .enable = mvebu_pinmux_enable, -}; - -static int mvebu_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - return pctl->num_groups; -} - -static const char *mvebu_pinctrl_get_group_name(struct pinctrl_dev *pctldev, - unsigned gid) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - return pctl->groups[gid].name; -} - -static int mvebu_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, - unsigned gid, const unsigned **pins, - unsigned *num_pins) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - *pins = pctl->groups[gid].pins; - *num_pins = pctl->groups[gid].npins; - return 0; -} - -static int mvebu_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np, - struct pinctrl_map **map, - unsigned *num_maps) -{ - struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); - struct property *prop; - const char *function; - const char *group; - int ret, nmaps, n; - - *map = NULL; - *num_maps = 0; - - ret = of_property_read_string(np, "marvell,function", &function); - if (ret) { - dev_err(pctl->dev, - "missing marvell,function in node %s\n", np->name); - return 0; - } - - nmaps = of_property_count_strings(np, "marvell,pins"); - if (nmaps < 0) { - dev_err(pctl->dev, - "missing marvell,pins in node %s\n", np->name); - return 0; - } - - *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL); - if (map == NULL) { - dev_err(pctl->dev, - "cannot allocate pinctrl_map memory for %s\n", - np->name); - return -ENOMEM; - } - - n = 0; - of_property_for_each_string(np, "marvell,pins", prop, group) { - struct mvebu_pinctrl_group *grp = - mvebu_pinctrl_find_group_by_name(pctl, group); - - if (!grp) { - dev_err(pctl->dev, "unknown pin %s", group); - continue; - } - - if (!mvebu_pinctrl_find_setting_by_name(pctl, grp, function)) { - dev_err(pctl->dev, "unsupported function %s on pin %s", - function, group); - continue; - } - - (*map)[n].type = PIN_MAP_TYPE_MUX_GROUP; - (*map)[n].data.mux.group = group; - (*map)[n].data.mux.function = function; - n++; - } - - *num_maps = nmaps; - - return 0; -} - -static void mvebu_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) -{ - kfree(map); -} - -static struct pinctrl_ops mvebu_pinctrl_ops = { - .get_groups_count = mvebu_pinctrl_get_groups_count, - .get_group_name = mvebu_pinctrl_get_group_name, - .get_group_pins = mvebu_pinctrl_get_group_pins, - .dt_node_to_map = mvebu_pinctrl_dt_node_to_map, - .dt_free_map = mvebu_pinctrl_dt_free_map, -}; - -static int __devinit _add_function(struct mvebu_pinctrl_function *funcs, - const char *name) -{ - while (funcs->num_groups) { - /* function already there */ - if (strcmp(funcs->name, name) == 0) { - funcs->num_groups++; - return -EEXIST; - } - funcs++; - } - funcs->name = name; - funcs->num_groups = 1; - return 0; -} - -static int __devinit mvebu_pinctrl_build_functions(struct platform_device *pdev, - struct mvebu_pinctrl *pctl) -{ - struct mvebu_pinctrl_function *funcs; - int num = 0; - int n, s; - - /* we allocate functions for number of pins and hope - * there are less unique functions than pins available */ - funcs = devm_kzalloc(&pdev->dev, pctl->desc.npins * - sizeof(struct mvebu_pinctrl_function), GFP_KERNEL); - if (!funcs) - return -ENOMEM; - - for (n = 0; n < pctl->num_groups; n++) { - struct mvebu_pinctrl_group *grp = &pctl->groups[n]; - for (s = 0; s < grp->num_settings; s++) { - /* skip unsupported settings on this variant */ - if (pctl->variant && - !(pctl->variant & grp->settings[s].variant)) - continue; - - /* check for unique functions and count groups */ - if (_add_function(funcs, grp->settings[s].name)) - continue; - - num++; - } - } - - /* with the number of unique functions and it's groups known, - reallocate functions and assign group names */ - funcs = krealloc(funcs, num * sizeof(struct mvebu_pinctrl_function), - GFP_KERNEL); - if (!funcs) - return -ENOMEM; - - pctl->num_functions = num; - pctl->functions = funcs; - - for (n = 0; n < pctl->num_groups; n++) { - struct mvebu_pinctrl_group *grp = &pctl->groups[n]; - for (s = 0; s < grp->num_settings; s++) { - struct mvebu_pinctrl_function *f; - const char **groups; - - /* skip unsupported settings on this variant */ - if (pctl->variant && - !(pctl->variant & grp->settings[s].variant)) - continue; - - f = mvebu_pinctrl_find_function_by_name(pctl, - grp->settings[s].name); - - /* allocate group name array if not done already */ - if (!f->groups) { - f->groups = devm_kzalloc(&pdev->dev, - f->num_groups * sizeof(char *), - GFP_KERNEL); - if (!f->groups) - return -ENOMEM; - } - - /* find next free group name and assign current name */ - groups = f->groups; - while (*groups) - groups++; - *groups = grp->name; - } - } - - return 0; -} - -int __devinit mvebu_pinctrl_probe(struct platform_device *pdev) -{ - struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev); - struct device_node *np = pdev->dev.of_node; - struct mvebu_pinctrl *pctl; - void __iomem *base; - struct pinctrl_pin_desc *pdesc; - unsigned gid, n, k; - int ret; - - if (!soc || !soc->controls || !soc->modes) { - dev_err(&pdev->dev, "wrong pinctrl soc info\n"); - return -EINVAL; - } - - base = of_iomap(np, 0); - if (!base) { - dev_err(&pdev->dev, "unable to get base address\n"); - return -ENODEV; - } - - pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl), - GFP_KERNEL); - if (!pctl) { - dev_err(&pdev->dev, "unable to alloc driver\n"); - return -ENOMEM; - } - - pctl->desc.name = dev_name(&pdev->dev); - pctl->desc.owner = THIS_MODULE; - pctl->desc.pctlops = &mvebu_pinctrl_ops; - pctl->desc.pmxops = &mvebu_pinmux_ops; - pctl->desc.confops = &mvebu_pinconf_ops; - pctl->variant = soc->variant; - pctl->base = base; - pctl->dev = &pdev->dev; - platform_set_drvdata(pdev, pctl); - - /* count controls and create names for mvebu generic - register controls; also does sanity checks */ - pctl->num_groups = 0; - pctl->desc.npins = 0; - for (n = 0; n < soc->ncontrols; n++) { - struct mvebu_mpp_ctrl *ctrl = &soc->controls[n]; - char *names; - - pctl->desc.npins += ctrl->npins; - /* initial control pins */ - for (k = 0; k < ctrl->npins; k++) - ctrl->pins[k] = ctrl->pid + k; - - /* special soc specific control */ - if (ctrl->mpp_get || ctrl->mpp_set) { - if (!ctrl->name || !ctrl->mpp_set || !ctrl->mpp_set) { - dev_err(&pdev->dev, "wrong soc control info\n"); - return -EINVAL; - } - pctl->num_groups += 1; - continue; - } - - /* generic mvebu register control */ - names = devm_kzalloc(&pdev->dev, ctrl->npins * 8, GFP_KERNEL); - if (!names) { - dev_err(&pdev->dev, "failed to alloc mpp names\n"); - return -ENOMEM; - } - for (k = 0; k < ctrl->npins; k++) - sprintf(names + 8*k, "mpp%d", ctrl->pid+k); - ctrl->name = names; - pctl->num_groups += ctrl->npins; - } - - pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins * - sizeof(struct pinctrl_pin_desc), GFP_KERNEL); - if (!pdesc) { - dev_err(&pdev->dev, "failed to alloc pinctrl pins\n"); - return -ENOMEM; - } - - for (n = 0; n < pctl->desc.npins; n++) - pdesc[n].number = n; - pctl->desc.pins = pdesc; - - pctl->groups = devm_kzalloc(&pdev->dev, pctl->num_groups * - sizeof(struct mvebu_pinctrl_group), GFP_KERNEL); - if (!pctl->groups) { - dev_err(&pdev->dev, "failed to alloc pinctrl groups\n"); - return -ENOMEM; - } - - /* assign mpp controls to groups */ - gid = 0; - for (n = 0; n < soc->ncontrols; n++) { - struct mvebu_mpp_ctrl *ctrl = &soc->controls[n]; - pctl->groups[gid].gid = gid; - pctl->groups[gid].ctrl = ctrl; - pctl->groups[gid].name = ctrl->name; - pctl->groups[gid].pins = ctrl->pins; - pctl->groups[gid].npins = ctrl->npins; - - /* generic mvebu register control maps to a number of groups */ - if (!ctrl->mpp_get && !ctrl->mpp_set) { - pctl->groups[gid].npins = 1; - - for (k = 1; k < ctrl->npins; k++) { - gid++; - pctl->groups[gid].gid = gid; - pctl->groups[gid].ctrl = ctrl; - pctl->groups[gid].name = &ctrl->name[8*k]; - pctl->groups[gid].pins = &ctrl->pins[k]; - pctl->groups[gid].npins = 1; - } - } - gid++; - } - - /* assign mpp modes to groups */ - for (n = 0; n < soc->nmodes; n++) { - struct mvebu_mpp_mode *mode = &soc->modes[n]; - struct mvebu_pinctrl_group *grp = - mvebu_pinctrl_find_group_by_pid(pctl, mode->pid); - unsigned num_settings; - - if (!grp) { - dev_warn(&pdev->dev, "unknown pinctrl group %d\n", - mode->pid); - continue; - } - - for (num_settings = 0; ;) { - struct mvebu_mpp_ctrl_setting *set = - &mode->settings[num_settings]; - - if (!set->name) - break; - num_settings++; - - /* skip unsupported settings for this variant */ - if (pctl->variant && !(pctl->variant & set->variant)) - continue; - - /* find gpio/gpo/gpi settings */ - if (strcmp(set->name, "gpio") == 0) - set->flags = MVEBU_SETTING_GPI | - MVEBU_SETTING_GPO; - else if (strcmp(set->name, "gpo") == 0) - set->flags = MVEBU_SETTING_GPO; - else if (strcmp(set->name, "gpi") == 0) - set->flags = MVEBU_SETTING_GPI; - } - - grp->settings = mode->settings; - grp->num_settings = num_settings; - } - - ret = mvebu_pinctrl_build_functions(pdev, pctl); - if (ret) { - dev_err(&pdev->dev, "unable to build functions\n"); - return ret; - } - - pctl->pctldev = pinctrl_register(&pctl->desc, &pdev->dev, pctl); - if (!pctl->pctldev) { - dev_err(&pdev->dev, "unable to register pinctrl driver\n"); - return -EINVAL; - } - - dev_info(&pdev->dev, "registered pinctrl driver\n"); - - /* register gpio ranges */ - for (n = 0; n < soc->ngpioranges; n++) - pinctrl_add_gpio_range(pctl->pctldev, &soc->gpioranges[n]); - - return 0; -} - -int __devexit mvebu_pinctrl_remove(struct platform_device *pdev) -{ - struct mvebu_pinctrl *pctl = platform_get_drvdata(pdev); - pinctrl_unregister(pctl->pctldev); - return 0; -} diff --git a/drivers/pinctrl/pinctrl-mvebu.h b/drivers/pinctrl/pinctrl-mvebu.h deleted file mode 100644 index 90bd3beee86..00000000000 --- a/drivers/pinctrl/pinctrl-mvebu.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Marvell MVEBU pinctrl driver - * - * Authors: Sebastian Hesselbarth - * Thomas Petazzoni - * - * 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. - */ - -#ifndef __PINCTRL_MVEBU_H__ -#define __PINCTRL_MVEBU_H__ - -/** - * struct mvebu_mpp_ctrl - describe a mpp control - * @name: name of the control group - * @pid: first pin id handled by this control - * @npins: number of pins controlled by this control - * @mpp_get: (optional) special function to get mpp setting - * @mpp_set: (optional) special function to set mpp setting - * @mpp_gpio_req: (optional) special function to request gpio - * @mpp_gpio_dir: (optional) special function to set gpio direction - * - * A mpp_ctrl describes a muxable unit, e.g. pin, group of pins, or - * internal function, inside the SoC. Each muxable unit can be switched - * between two or more different settings, e.g. assign mpp pin 13 to - * uart1 or sata. - * - * If optional mpp_get/_set functions are set these are used to get/set - * a specific mode. Otherwise it is assumed that the mpp control is based - * on 4-bit groups in subsequent registers. The optional mpp_gpio_req/_dir - * functions can be used to allow pin settings with varying gpio pins. - */ -struct mvebu_mpp_ctrl { - const char *name; - u8 pid; - u8 npins; - unsigned *pins; - int (*mpp_get)(struct mvebu_mpp_ctrl *ctrl, unsigned long *config); - int (*mpp_set)(struct mvebu_mpp_ctrl *ctrl, unsigned long config); - int (*mpp_gpio_req)(struct mvebu_mpp_ctrl *ctrl, u8 pid); - int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl *ctrl, u8 pid, bool input); -}; - -/** - * struct mvebu_mpp_ctrl_setting - describe a mpp ctrl setting - * @val: ctrl setting value - * @name: ctrl setting name, e.g. uart2, spi0 - unique per mpp_mode - * @subname: (optional) additional ctrl setting name, e.g. rts, cts - * @variant: (optional) variant identifier mask - * @flags: (private) flags to store gpi/gpo/gpio capabilities - * - * A ctrl_setting describes a specific internal mux function that a mpp pin - * can be switched to. The value (val) will be written in the corresponding - * register for common mpp pin configuration registers on MVEBU. SoC specific - * mpp_get/_set function may use val to distinguish between different settings. - * - * The name will be used to switch to this setting in DT description, e.g. - * marvell,function = "uart2". subname is only for debugging purposes. - * - * If name is one of "gpi", "gpo", "gpio" gpio capabilities are - * parsed during initialization and stored in flags. - * - * The variant can be used to combine different revisions of one SoC to a - * common pinctrl driver. It is matched (AND) with variant of soc_info to - * determine if a setting is available on the current SoC revision. - */ -struct mvebu_mpp_ctrl_setting { - u8 val; - const char *name; - const char *subname; - u8 variant; - u8 flags; -#define MVEBU_SETTING_GPO (1 << 0) -#define MVEBU_SETTING_GPI (1 << 1) -}; - -/** - * struct mvebu_mpp_mode - link ctrl and settings - * @pid: first pin id handled by this mode - * @settings: list of settings available for this mode - * - * A mode connects all available settings with the corresponding mpp_ctrl - * given by pid. - */ -struct mvebu_mpp_mode { - u8 pid; - struct mvebu_mpp_ctrl_setting *settings; -}; - -/** - * struct mvebu_pinctrl_soc_info - SoC specific info passed to pinctrl-mvebu - * @variant: variant mask of soc_info - * @controls: list of available mvebu_mpp_ctrls - * @ncontrols: number of available mvebu_mpp_ctrls - * @modes: list of available mvebu_mpp_modes - * @nmodes: number of available mvebu_mpp_modes - * @gpioranges: list of pinctrl_gpio_ranges - * @ngpioranges: number of available pinctrl_gpio_ranges - * - * This struct describes all pinctrl related information for a specific SoC. - * If variant is unequal 0 it will be matched (AND) with variant of each - * setting and allows to distinguish between different revisions of one SoC. - */ -struct mvebu_pinctrl_soc_info { - u8 variant; - struct mvebu_mpp_ctrl *controls; - int ncontrols; - struct mvebu_mpp_mode *modes; - int nmodes; - struct pinctrl_gpio_range *gpioranges; - int ngpioranges; -}; - -#define MPP_REG_CTRL(_idl, _idh) \ - { \ - .name = NULL, \ - .pid = _idl, \ - .npins = _idh - _idl + 1, \ - .pins = (unsigned[_idh - _idl + 1]) { }, \ - .mpp_get = NULL, \ - .mpp_set = NULL, \ - .mpp_gpio_req = NULL, \ - .mpp_gpio_dir = NULL, \ - } - -#define MPP_FUNC_CTRL(_idl, _idh, _name, _func) \ - { \ - .name = _name, \ - .pid = _idl, \ - .npins = _idh - _idl + 1, \ - .pins = (unsigned[_idh - _idl + 1]) { }, \ - .mpp_get = _func ## _get, \ - .mpp_set = _func ## _set, \ - .mpp_gpio_req = NULL, \ - .mpp_gpio_dir = NULL, \ - } - -#define MPP_FUNC_GPIO_CTRL(_idl, _idh, _name, _func) \ - { \ - .name = _name, \ - .pid = _idl, \ - .npins = _idh - _idl + 1, \ - .pins = (unsigned[_idh - _idl + 1]) { }, \ - .mpp_get = _func ## _get, \ - .mpp_set = _func ## _set, \ - .mpp_gpio_req = _func ## _gpio_req, \ - .mpp_gpio_dir = _func ## _gpio_dir, \ - } - -#define _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ - { \ - .val = _val, \ - .name = _name, \ - .subname = _subname, \ - .variant = _mask, \ - .flags = 0, \ - } - -#if defined(CONFIG_DEBUG_FS) -#define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ - _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) -#else -#define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ - _MPP_VAR_FUNCTION(_val, _name, NULL, _mask) -#endif - -#define MPP_FUNCTION(_val, _name, _subname) \ - MPP_VAR_FUNCTION(_val, _name, _subname, (u8)-1) - -#define MPP_MODE(_id, ...) \ - { \ - .pid = _id, \ - .settings = (struct mvebu_mpp_ctrl_setting[]){ \ - __VA_ARGS__, { } }, \ - } - -#define MPP_GPIO_RANGE(_id, _pinbase, _gpiobase, _npins) \ - { \ - .name = "mvebu-gpio", \ - .id = _id, \ - .pin_base = _pinbase, \ - .base = _gpiobase, \ - .npins = _npins, \ - } - -int mvebu_pinctrl_probe(struct platform_device *pdev); -int mvebu_pinctrl_remove(struct platform_device *pdev); - -#endif -- cgit v1.2.3 From d3e26f2fe993b5dbc8b4b2275d77f9ad3e08c81a Mon Sep 17 00:00:00 2001 From: Barry Song Date: Thu, 27 Sep 2012 17:56:30 +0800 Subject: pinctrl: sirf: enable the driver support new SiRFmarco SoC The driver supports old up SiRFprimaII SoCs, this patch makes it support the new SiRFmarco as well. SiRFmarco, as a SMP SoC, adds new SIRFSOC_GPIO_PAD_EN_CLR registers, to disable GPIO pad, we should write 1 to the corresponding bit in the new CLEAR register instead of writing 0 to SIRFSOC_GPIO_PAD_EN. Signed-off-by: Barry Song Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 4 ++-- drivers/pinctrl/pinctrl-sirf.c | 48 ++++++++++++++++++++++++++++++++---------- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 011133772d2..5f2f9dc43e3 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -143,8 +143,8 @@ config PINCTRL_SINGLE This selects the device tree based generic pinctrl driver. config PINCTRL_SIRF - bool "CSR SiRFprimaII pin controller driver" - depends on ARCH_PRIMA2 + bool "CSR SiRFprimaII/SiRFmarco pin controller driver" + depends on ARCH_SIRF select PINMUX config PINCTRL_TEGRA diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index 9ecacf3d0a7..16ec7d4d81e 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c @@ -32,10 +32,10 @@ #define SIRFSOC_NUM_PADS 622 #define SIRFSOC_RSC_PIN_MUX 0x4 -#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) +#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) +#define SIRFSOC_GPIO_PAD_EN_CLR(g) ((g)*0x100 + 0x90) #define SIRFSOC_GPIO_CTRL(g, i) ((g)*0x100 + (i)*4) #define SIRFSOC_GPIO_DSP_EN0 (0x80) -#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) #define SIRFSOC_GPIO_INT_STATUS(g) ((g)*0x100 + 0x8C) #define SIRFSOC_GPIO_CTL_INTR_LOW_MASK 0x1 @@ -60,6 +60,7 @@ struct sirfsoc_gpio_bank { int id; int parent_irq; spinlock_t lock; + bool is_marco; /* for marco, some registers are different with prima2 */ }; static struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; @@ -191,6 +192,7 @@ struct sirfsoc_pmx { struct pinctrl_dev *pmx; void __iomem *gpio_virtbase; void __iomem *rsc_virtbase; + bool is_marco; }; /* SIRFSOC_GPIO_PAD_EN set */ @@ -1088,12 +1090,21 @@ static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector for (i = 0; i < mux->muxmask_counts; i++) { u32 muxval; - muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); - if (enable) - muxval = muxval & ~mask[i].mask; - else - muxval = muxval | mask[i].mask; - writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); + if (!spmx->is_marco) { + muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); + if (enable) + muxval = muxval & ~mask[i].mask; + else + muxval = muxval | mask[i].mask; + writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); + } else { + if (enable) + writel(mask[i].mask, spmx->gpio_virtbase + + SIRFSOC_GPIO_PAD_EN_CLR(mask[i].group)); + else + writel(mask[i].mask, spmx->gpio_virtbase + + SIRFSOC_GPIO_PAD_EN(mask[i].group)); + } } if (mux->funcmask && enable) { @@ -1158,9 +1169,14 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, spmx = pinctrl_dev_get_drvdata(pmxdev); - muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); - muxval = muxval | (1 << (offset - range->pin_base)); - writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); + if (!spmx->is_marco) { + muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); + muxval = muxval | (1 << (offset - range->pin_base)); + writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); + } else { + writel(1 << (offset - range->pin_base), spmx->gpio_virtbase + + SIRFSOC_GPIO_PAD_EN(group)); + } return 0; } @@ -1218,6 +1234,7 @@ static void __iomem *sirfsoc_rsc_of_iomap(void) { const struct of_device_id rsc_ids[] = { { .compatible = "sirf,prima2-rsc" }, + { .compatible = "sirf,marco-rsc" }, {} }; struct device_node *np; @@ -1259,6 +1276,9 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev) goto out_no_rsc_remap; } + if (of_device_is_compatible(np, "sirf,marco-pinctrl")) + spmx->is_marco = 1; + /* Now register the pin controller and all pins it handles */ spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx); if (!spmx->pmx) { @@ -1287,6 +1307,7 @@ out_no_gpio_remap: static const struct of_device_id pinmux_ids[] __devinitconst = { { .compatible = "sirf,prima2-pinctrl" }, + { .compatible = "sirf,marco-pinctrl" }, {} }; @@ -1648,6 +1669,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) struct sirfsoc_gpio_bank *bank; void *regs; struct platform_device *pdev; + bool is_marco = false; pdev = of_find_device_by_node(np); if (!pdev) @@ -1657,6 +1679,9 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) if (!regs) return -ENOMEM; + if (of_device_is_compatible(np, "sirf,marco-pinctrl")) + is_marco = 1; + for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { bank = &sgpio_bank[i]; spin_lock_init(&bank->lock); @@ -1673,6 +1698,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) bank->chip.gc.of_node = np; bank->chip.regs = regs; bank->id = i; + bank->is_marco = is_marco; bank->parent_irq = platform_get_irq(pdev, i); if (bank->parent_irq < 0) { err = bank->parent_irq; -- cgit v1.2.3 From afa538c2bf00cf6cd28fc6b5fcea1a75894228a0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 2 Nov 2012 21:46:13 +0800 Subject: pinctrl: exynos: Add terminating entry for of_device_id table The of_device_id table is supposed to be zero-terminated. Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-exynos.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c index 21362f48d37..6ff665209a4 100644 --- a/drivers/pinctrl/pinctrl-exynos.c +++ b/drivers/pinctrl/pinctrl-exynos.c @@ -36,6 +36,7 @@ /* list of external wakeup controllers supported */ static const struct of_device_id exynos_wkup_irq_ids[] = { { .compatible = "samsung,exynos4210-wakeup-eint", }, + { } }; static void exynos_gpio_irq_unmask(struct irq_data *irqd) -- cgit v1.2.3 From 7e10ee68f8ccc62e0934ff02f39ce541f3879844 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Sat, 27 Oct 2012 15:21:35 +0530 Subject: Revert "pinctrl: remove pinctrl_remove_gpio_range" This reverts earlier commit which removed pinctrl_remove_gpio_range(), because at that time there weren't any more users of that routine. It was removed as the removal of ranges was done in unregister of pinctrl. But as we are now registering stuff from gpiolib, we may remove and insert a gpio module multiple times. So, we need this routine again. Signed-off-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 14 ++++++++++++++ include/linux/pinctrl/pinctrl.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index cec6072cd7c..b1086dcde15 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -345,6 +345,20 @@ void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, } EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges); +/** + * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller + * @pctldev: pin controller device to remove the range from + * @range: the GPIO range to remove + */ +void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range) +{ + mutex_lock(&pinctrl_mutex); + list_del(&range->node); + mutex_unlock(&pinctrl_mutex); +} +EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range); + /** * pinctrl_get_group_selector() - returns the group selector for a group * @pctldev: the pin controller handling the group diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 7d087f03e91..eda04674633 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -134,6 +134,8 @@ extern void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev, extern void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *ranges, unsigned nranges); +extern void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range); extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev); extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev); #else -- cgit v1.2.3 From f23f1516b6757c326cc638bed8c402c77e2a596e Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Sat, 27 Oct 2012 15:21:36 +0530 Subject: gpiolib: provide provision to register pin ranges pinctrl subsystem needs gpio chip base to prepare set of gpio pin ranges, which a given pinctrl driver can handle. This is important to handle pinctrl gpio request calls in order to program a given pin properly for gpio operation. As gpio base is allocated dynamically during gpiochip registration, presently there exists no clean way to pass this information to the pinctrl subsystem. After few discussions from [1], it was concluded that may be gpio controller reporting the pin range it supports, is a better way than pinctrl subsystem directly registering it. [1] http://comments.gmane.org/gmane.linux.ports.arm.kernel/184816 Cc: Grant Likely Signed-off-by: Viresh Kumar Signed-off-by: Shiraz Hashim [Edited documentation a bit] Signed-off-by: Linus Walleij --- Documentation/devicetree/bindings/gpio/gpio.txt | 36 ++++++++++++++++ Documentation/gpio.txt | 42 +++++++++++++++++++ Documentation/pinctrl.txt | 3 ++ drivers/gpio/gpiolib-of.c | 56 +++++++++++++++++++++++++ drivers/gpio/gpiolib.c | 43 +++++++++++++++++++ drivers/pinctrl/core.c | 13 ++++++ drivers/pinctrl/devicetree.c | 13 ++++++ include/asm-generic/gpio.h | 25 +++++++++++ include/linux/gpio.h | 3 ++ include/linux/pinctrl/pinctrl.h | 17 ++++++++ 10 files changed, 251 insertions(+) diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt index 4e16ba4feab..a33628759d3 100644 --- a/Documentation/devicetree/bindings/gpio/gpio.txt +++ b/Documentation/devicetree/bindings/gpio/gpio.txt @@ -75,4 +75,40 @@ Example of two SOC GPIO banks defined as gpio-controller nodes: gpio-controller; }; +2.1) gpio-controller and pinctrl subsystem +------------------------------------------ +gpio-controller on a SOC might be tightly coupled with the pinctrl +subsystem, in the sense that the pins can be used by other functions +together with optional gpio feature. + +While the pin allocation is totally managed by the pin ctrl subsystem, +gpio (under gpiolib) is still maintained by gpio drivers. It may happen +that different pin ranges in a SoC is managed by different gpio drivers. + +This makes it logical to let gpio drivers announce their pin ranges to +the pin ctrl subsystem and call 'pinctrl_request_gpio' in order to +request the corresponding pin before any gpio usage. + +For this, the gpio controller can use a pinctrl phandle and pins to +announce the pinrange to the pin ctrl subsystem. For example, + + qe_pio_e: gpio-controller@1460 { + #gpio-cells = <2>; + compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; + reg = <0x1460 0x18>; + gpio-controller; + gpio-ranges = <&pinctrl1 20 10>, <&pinctrl2 50 20>; + + } + +where, + &pinctrl1 and &pinctrl2 is the phandle to the pinctrl DT node. + + Next values specify the base pin and number of pins for the range + handled by 'qe_pio_e' gpio. In the given example from base pin 20 to + pin 29 under pinctrl1 and pin 50 to pin 69 under pinctrl2 is handled + by this gpio controller. + +The pinctrl node must have "#gpio-range-cells" property to show number of +arguments to pass with phandle from gpio controllers node. diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index e08a883de36..77a1d11af72 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt @@ -439,6 +439,48 @@ slower clock delays the rising edge of SCK, and the I2C master adjusts its signaling rate accordingly. +GPIO controllers and the pinctrl subsystem +------------------------------------------ + +A GPIO controller on a SOC might be tightly coupled with the pinctrl +subsystem, in the sense that the pins can be used by other functions +together with an optional gpio feature. We have already covered the +case where e.g. a GPIO controller need to reserve a pin or set the +direction of a pin by calling any of: + +pinctrl_request_gpio() +pinctrl_free_gpio() +pinctrl_gpio_direction_input() +pinctrl_gpio_direction_output() + +But how does the pin control subsystem cross-correlate the GPIO +numbers (which are a global business) to a certain pin on a certain +pin controller? + +This is done by registering "ranges" of pins, which are essentially +cross-reference tables. These are described in +Documentation/pinctrl.txt + +While the pin allocation is totally managed by the pinctrl subsystem, +gpio (under gpiolib) is still maintained by gpio drivers. It may happen +that different pin ranges in a SoC is managed by different gpio drivers. + +This makes it logical to let gpio drivers announce their pin ranges to +the pin ctrl subsystem before it will call 'pinctrl_request_gpio' in order +to request the corresponding pin to be prepared by the pinctrl subsystem +before any gpio usage. + +For this, the gpio controller can register its pin range with pinctrl +subsystem. There are two ways of doing it currently: with or without DT. + +For with DT support refer to Documentation/devicetree/bindings/gpio/gpio.txt. + +For non-DT support, user can call gpiochip_add_pin_range() with appropriate +parameters to register a range of gpio pins with a pinctrl driver. For this +exact name string of pinctrl device has to be passed as one of the +argument to this routine. + + What do these conventions omit? =============================== One of the biggest things these conventions omit is pin multiplexing, since diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index a1cd2f9428d..da40efbef6e 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -364,6 +364,9 @@ will get an pin number into its handled number range. Further it is also passed the range ID value, so that the pin controller knows which range it should deal with. +Calling pinctrl_add_gpio_range from pinctrl driver is DEPRECATED. Please see +section 2.1 of Documentation/devicetree/bindings/gpio/gpio.txt on how to bind +pinctrl and gpio drivers. PINMUX interfaces ================= diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index f1a45997aea..a5b90c8e984 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -19,6 +19,7 @@ #include #include #include +#include #include /* Private data structure for of_gpiochip_find_and_xlate */ @@ -216,6 +217,58 @@ err0: } EXPORT_SYMBOL(of_mm_gpiochip_add); +#ifdef CONFIG_PINCTRL +void of_gpiochip_add_pin_range(struct gpio_chip *chip) +{ + struct device_node *np = chip->of_node; + struct gpio_pin_range *pin_range; + struct of_phandle_args pinspec; + int index = 0, ret; + + if (!np) + return; + + do { + ret = of_parse_phandle_with_args(np, "gpio-ranges", + "#gpio-range-cells", index, &pinspec); + if (ret) + break; + + pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), + GFP_KERNEL); + if (!pin_range) { + pr_err("%s: GPIO chip: failed to allocate pin ranges\n", + chip->label); + break; + } + + pin_range->range.name = chip->label; + pin_range->range.base = chip->base; + pin_range->range.pin_base = pinspec.args[0]; + pin_range->range.npins = pinspec.args[1]; + pin_range->pctldev = of_pinctrl_add_gpio_range(pinspec.np, + &pin_range->range); + + list_add_tail(&pin_range->node, &chip->pin_ranges); + + } while (index++); +} + +void of_gpiochip_remove_pin_range(struct gpio_chip *chip) +{ + struct gpio_pin_range *pin_range, *tmp; + + list_for_each_entry_safe(pin_range, tmp, &chip->pin_ranges, node) { + list_del(&pin_range->node); + pinctrl_remove_gpio_range(pin_range->pctldev, + &pin_range->range); + } +} +#else +void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} +void of_gpiochip_remove_pin_range(struct gpio_chip *chip) {} +#endif + void of_gpiochip_add(struct gpio_chip *chip) { if ((!chip->of_node) && (chip->dev)) @@ -229,11 +282,14 @@ void of_gpiochip_add(struct gpio_chip *chip) chip->of_xlate = of_gpio_simple_xlate; } + of_gpiochip_add_pin_range(chip); of_node_get(chip->of_node); } void of_gpiochip_remove(struct gpio_chip *chip) { + of_gpiochip_remove_pin_range(chip); + if (chip->of_node) of_node_put(chip->of_node); } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 1c8d9e3380e..f0b07bbfcc9 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1083,6 +1083,10 @@ int gpiochip_add(struct gpio_chip *chip) } } +#ifdef CONFIG_PINCTRL + INIT_LIST_HEAD(&chip->pin_ranges); +#endif + of_gpiochip_add(chip); unlock: @@ -1180,6 +1184,45 @@ struct gpio_chip *gpiochip_find(void *data, } EXPORT_SYMBOL_GPL(gpiochip_find); +#ifdef CONFIG_PINCTRL +void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins) +{ + struct gpio_pin_range *pin_range; + + pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), GFP_KERNEL); + if (!pin_range) { + pr_err("%s: GPIO chip: failed to allocate pin ranges\n", + chip->label); + return; + } + + pin_range->range.name = chip->label; + pin_range->range.base = chip->base; + pin_range->range.pin_base = pin_base; + pin_range->range.npins = npins; + pin_range->pctldev = find_pinctrl_and_add_gpio_range(pinctl_name, + &pin_range->range); + + list_add_tail(&pin_range->node, &chip->pin_ranges); +} + +void gpiochip_remove_pin_ranges(struct gpio_chip *chip) +{ + struct gpio_pin_range *pin_range, *tmp; + + list_for_each_entry_safe(pin_range, tmp, &chip->pin_ranges, node) { + list_del(&pin_range->node); + pinctrl_remove_gpio_range(pin_range->pctldev, + &pin_range->range); + } +} +#else +void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins) {} +void gpiochip_remove_pin_ranges(struct gpio_chip *chip) {} +#endif + /* These "optional" allocation calls help prevent drivers from stomping * on each other, and help provide better diagnostics in debugfs. * They're called even less than the "set direction" calls. diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index b1086dcde15..71db586b2af 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -345,6 +345,19 @@ void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, } EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges); +struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname, + struct pinctrl_gpio_range *range) +{ + struct pinctrl_dev *pctldev = get_pinctrl_dev_from_devname(devname); + + if (!pctldev) + return NULL; + + pinctrl_add_gpio_range(pctldev, range); + return pctldev; +} +EXPORT_SYMBOL_GPL(find_pinctrl_and_add_gpio_range); + /** * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller * @pctldev: pin controller device to remove the range from diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index fcb1de45473..6728ec71cb6 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -106,6 +106,19 @@ static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np) return NULL; } +struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, + struct pinctrl_gpio_range *range) +{ + struct pinctrl_dev *pctldev; + + pctldev = find_pinctrl_by_of_node(np); + if (!pctldev) + return NULL; + + pinctrl_add_gpio_range(pctldev, range); + return pctldev; +} + static int dt_to_map_one_config(struct pinctrl *p, const char *statename, struct device_node *np_config) { diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index a9432fc6b8b..92e5c432421 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -5,6 +5,7 @@ #include #include #include +#include #ifdef CONFIG_GPIOLIB @@ -47,6 +48,21 @@ struct seq_file; struct module; struct device_node; +#ifdef CONFIG_PINCTRL +/** + * struct gpio_pin_range - pin range controlled by a gpio chip + * @head: list for maintaining set of pin ranges, used internally + * @pctldev: pinctrl device which handles corresponding pins + * @range: actual range of pins controlled by a gpio controller + */ + +struct gpio_pin_range { + struct list_head node; + struct pinctrl_dev *pctldev; + struct pinctrl_gpio_range range; +}; +#endif + /** * struct gpio_chip - abstract a GPIO controller * @label: for diagnostics @@ -134,6 +150,15 @@ struct gpio_chip { int (*of_xlate)(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags); #endif +#ifdef CONFIG_PINCTRL + /* + * If CONFIG_PINCTRL is enabled, then gpio controllers can optionally + * describe the actual pin range which they serve in an SoC. This + * information would be used by pinctrl subsystem to configure + * corresponding pins for gpio usage. + */ + struct list_head pin_ranges; +#endif }; extern const char *gpiochip_is_requested(struct gpio_chip *chip, diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 2e31e8b3a19..a28445992b7 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -231,6 +231,9 @@ static inline int irq_to_gpio(unsigned irq) return -EINVAL; } +void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins); +void gpiochip_remove_pin_ranges(struct gpio_chip *chip); #endif #endif /* __LINUX_GPIO_H */ diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index eda04674633..434e5a94e13 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -136,6 +136,23 @@ extern void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, unsigned nranges); extern void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range); + +extern struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname, + struct pinctrl_gpio_range *range); + +#ifdef CONFIG_OF +extern struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, + struct pinctrl_gpio_range *range); +#else +static inline +struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, + struct pinctrl_gpio_range *range) +{ + return NULL; +} + +#endif /* CONFIG_OF */ + extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev); extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev); #else -- cgit v1.2.3 From 604bb7da77803cc01366c85fd5bcbc88b6dbe33a Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Sat, 27 Oct 2012 15:21:37 +0530 Subject: pinctrl: SPEAr: Add plgpio driver Most of SPEAr SoCs, which support pinctrl, can configure & use pads as gpio. This patch adds plgpio driver for configuring these pads as gpio. Signed-off-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/pinctrl/spear/Kconfig | 7 + drivers/pinctrl/spear/Makefile | 1 + drivers/pinctrl/spear/pinctrl-plgpio.c | 746 +++++++++++++++++++++++++++++++++ 3 files changed, 754 insertions(+) create mode 100644 drivers/pinctrl/spear/pinctrl-plgpio.c diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig index 91558791e76..6f9a1e8bf57 100644 --- a/drivers/pinctrl/spear/Kconfig +++ b/drivers/pinctrl/spear/Kconfig @@ -41,4 +41,11 @@ config PINCTRL_SPEAR1340 depends on MACH_SPEAR1340 select PINCTRL_SPEAR +config PINCTRL_SPEAR_PLGPIO + bool "SPEAr SoC PLGPIO Controller" + depends on GPIOLIB && PINCTRL_SPEAR + help + Say yes here to support PLGPIO controller on ST Microelectronics SPEAr + SoCs. + endif diff --git a/drivers/pinctrl/spear/Makefile b/drivers/pinctrl/spear/Makefile index b28a7ba2244..0e400ebeb8f 100644 --- a/drivers/pinctrl/spear/Makefile +++ b/drivers/pinctrl/spear/Makefile @@ -1,5 +1,6 @@ # SPEAr pinmux support +obj-$(CONFIG_PINCTRL_SPEAR_PLGPIO) += pinctrl-plgpio.o obj-$(CONFIG_PINCTRL_SPEAR) += pinctrl-spear.o obj-$(CONFIG_PINCTRL_SPEAR3XX) += pinctrl-spear3xx.o obj-$(CONFIG_PINCTRL_SPEAR300) += pinctrl-spear300.o diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c new file mode 100644 index 00000000000..1044ad3f3c8 --- /dev/null +++ b/drivers/pinctrl/spear/pinctrl-plgpio.c @@ -0,0 +1,746 @@ +/* + * SPEAr platform PLGPIO driver + * + * Copyright (C) 2012 ST Microelectronics + * Viresh Kumar + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_GPIO_PER_REG 32 +#define PIN_OFFSET(pin) (pin % MAX_GPIO_PER_REG) +#define REG_OFFSET(base, reg, pin) (base + reg + (pin / MAX_GPIO_PER_REG) \ + * sizeof(int *)) + +/* + * plgpio pins in all machines are not one to one mapped, bitwise with registers + * bits. These set of macros define register masks for which below functions + * (pin_to_offset and offset_to_pin) are required to be called. + */ +#define PTO_ENB_REG 0x001 +#define PTO_WDATA_REG 0x002 +#define PTO_DIR_REG 0x004 +#define PTO_IE_REG 0x008 +#define PTO_RDATA_REG 0x010 +#define PTO_MIS_REG 0x020 + +struct plgpio_regs { + u32 enb; /* enable register */ + u32 wdata; /* write data register */ + u32 dir; /* direction set register */ + u32 rdata; /* read data register */ + u32 ie; /* interrupt enable register */ + u32 mis; /* mask interrupt status register */ + u32 eit; /* edge interrupt type */ +}; + +/* + * struct plgpio: plgpio driver specific structure + * + * lock: lock for guarding gpio registers + * base: base address of plgpio block + * irq_base: irq number of plgpio0 + * chip: gpio framework specific chip information structure + * p2o: function ptr for pin to offset conversion. This is required only for + * machines where mapping b/w pin and offset is not 1-to-1. + * o2p: function ptr for offset to pin conversion. This is required only for + * machines where mapping b/w pin and offset is not 1-to-1. + * p2o_regs: mask of registers for which p2o and o2p are applicable + * regs: register offsets + * csave_regs: context save registers for standby/sleep/hibernate cases + */ +struct plgpio { + spinlock_t lock; + void __iomem *base; + struct clk *clk; + unsigned irq_base; + struct irq_domain *irq_domain; + struct gpio_chip chip; + int (*p2o)(int pin); /* pin_to_offset */ + int (*o2p)(int offset); /* offset_to_pin */ + u32 p2o_regs; + struct plgpio_regs regs; +#ifdef CONFIG_PM + struct plgpio_regs *csave_regs; +#endif +}; + +/* register manipulation inline functions */ +static inline u32 is_plgpio_set(void __iomem *base, u32 pin, u32 reg) +{ + u32 offset = PIN_OFFSET(pin); + void __iomem *reg_off = REG_OFFSET(base, reg, pin); + u32 val = readl_relaxed(reg_off); + + return !!(val & (1 << offset)); +} + +static inline void plgpio_reg_set(void __iomem *base, u32 pin, u32 reg) +{ + u32 offset = PIN_OFFSET(pin); + void __iomem *reg_off = REG_OFFSET(base, reg, pin); + u32 val = readl_relaxed(reg_off); + + writel_relaxed(val | (1 << offset), reg_off); +} + +static inline void plgpio_reg_reset(void __iomem *base, u32 pin, u32 reg) +{ + u32 offset = PIN_OFFSET(pin); + void __iomem *reg_off = REG_OFFSET(base, reg, pin); + u32 val = readl_relaxed(reg_off); + + writel_relaxed(val & ~(1 << offset), reg_off); +} + +/* gpio framework specific routines */ +static int plgpio_direction_input(struct gpio_chip *chip, unsigned offset) +{ + struct plgpio *plgpio = container_of(chip, struct plgpio, chip); + unsigned long flags; + + /* get correct offset for "offset" pin */ + if (plgpio->p2o && (plgpio->p2o_regs & PTO_DIR_REG)) { + offset = plgpio->p2o(offset); + if (offset == -1) + return -EINVAL; + } + + spin_lock_irqsave(&plgpio->lock, flags); + plgpio_reg_set(plgpio->base, offset, plgpio->regs.dir); + spin_unlock_irqrestore(&plgpio->lock, flags); + + return 0; +} + +static int plgpio_direction_output(struct gpio_chip *chip, unsigned offset, + int value) +{ + struct plgpio *plgpio = container_of(chip, struct plgpio, chip); + unsigned long flags; + unsigned dir_offset = offset, wdata_offset = offset, tmp; + + /* get correct offset for "offset" pin */ + if (plgpio->p2o && (plgpio->p2o_regs & (PTO_DIR_REG | PTO_WDATA_REG))) { + tmp = plgpio->p2o(offset); + if (tmp == -1) + return -EINVAL; + + if (plgpio->p2o_regs & PTO_DIR_REG) + dir_offset = tmp; + if (plgpio->p2o_regs & PTO_WDATA_REG) + wdata_offset = tmp; + } + + spin_lock_irqsave(&plgpio->lock, flags); + if (value) + plgpio_reg_set(plgpio->base, wdata_offset, + plgpio->regs.wdata); + else + plgpio_reg_reset(plgpio->base, wdata_offset, + plgpio->regs.wdata); + + plgpio_reg_reset(plgpio->base, dir_offset, plgpio->regs.dir); + spin_unlock_irqrestore(&plgpio->lock, flags); + + return 0; +} + +static int plgpio_get_value(struct gpio_chip *chip, unsigned offset) +{ + struct plgpio *plgpio = container_of(chip, struct plgpio, chip); + + if (offset >= chip->ngpio) + return -EINVAL; + + /* get correct offset for "offset" pin */ + if (plgpio->p2o && (plgpio->p2o_regs & PTO_RDATA_REG)) { + offset = plgpio->p2o(offset); + if (offset == -1) + return -EINVAL; + } + + return is_plgpio_set(plgpio->base, offset, plgpio->regs.rdata); +} + +static void plgpio_set_value(struct gpio_chip *chip, unsigned offset, int value) +{ + struct plgpio *plgpio = container_of(chip, struct plgpio, chip); + + if (offset >= chip->ngpio) + return; + + /* get correct offset for "offset" pin */ + if (plgpio->p2o && (plgpio->p2o_regs & PTO_WDATA_REG)) { + offset = plgpio->p2o(offset); + if (offset == -1) + return; + } + + if (value) + plgpio_reg_set(plgpio->base, offset, plgpio->regs.wdata); + else + plgpio_reg_reset(plgpio->base, offset, plgpio->regs.wdata); +} + +static int plgpio_request(struct gpio_chip *chip, unsigned offset) +{ + struct plgpio *plgpio = container_of(chip, struct plgpio, chip); + int gpio = chip->base + offset; + unsigned long flags; + int ret = 0; + + if (offset >= chip->ngpio) + return -EINVAL; + + ret = pinctrl_request_gpio(gpio); + if (ret) + return ret; + + if (!IS_ERR(plgpio->clk)) { + ret = clk_prepare_enable(plgpio->clk); + if (ret) + goto err0; + } + + if (plgpio->regs.enb == -1) + return 0; + + /* + * put gpio in IN mode before enabling it. This make enabling gpio safe + */ + ret = plgpio_direction_input(chip, offset); + if (ret) + goto err1; + + /* get correct offset for "offset" pin */ + if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) { + offset = plgpio->p2o(offset); + if (offset == -1) { + ret = -EINVAL; + goto err1; + } + } + + spin_lock_irqsave(&plgpio->lock, flags); + plgpio_reg_set(plgpio->base, offset, plgpio->regs.enb); + spin_unlock_irqrestore(&plgpio->lock, flags); + return 0; + +err1: + clk_disable_unprepare(plgpio->clk); +err0: + pinctrl_free_gpio(gpio); + return ret; +} + +static void plgpio_free(struct gpio_chip *chip, unsigned offset) +{ + struct plgpio *plgpio = container_of(chip, struct plgpio, chip); + int gpio = chip->base + offset; + unsigned long flags; + + if (offset >= chip->ngpio) + return; + + if (plgpio->regs.enb == -1) + goto disable_clk; + + /* get correct offset for "offset" pin */ + if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) { + offset = plgpio->p2o(offset); + if (offset == -1) + return; + } + + spin_lock_irqsave(&plgpio->lock, flags); + plgpio_reg_reset(plgpio->base, offset, plgpio->regs.enb); + spin_unlock_irqrestore(&plgpio->lock, flags); + +disable_clk: + if (!IS_ERR(plgpio->clk)) + clk_disable_unprepare(plgpio->clk); + + pinctrl_free_gpio(gpio); +} + +static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct plgpio *plgpio = container_of(chip, struct plgpio, chip); + + if (plgpio->irq_base < 0) + return -EINVAL; + + return irq_find_mapping(plgpio->irq_domain, offset); +} + +/* PLGPIO IRQ */ +static void plgpio_irq_disable(struct irq_data *d) +{ + struct plgpio *plgpio = irq_data_get_irq_chip_data(d); + int offset = d->irq - plgpio->irq_base; + unsigned long flags; + + /* get correct offset for "offset" pin */ + if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) { + offset = plgpio->p2o(offset); + if (offset == -1) + return; + } + + spin_lock_irqsave(&plgpio->lock, flags); + plgpio_reg_set(plgpio->base, offset, plgpio->regs.ie); + spin_unlock_irqrestore(&plgpio->lock, flags); +} + +static void plgpio_irq_enable(struct irq_data *d) +{ + struct plgpio *plgpio = irq_data_get_irq_chip_data(d); + int offset = d->irq - plgpio->irq_base; + unsigned long flags; + + /* get correct offset for "offset" pin */ + if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) { + offset = plgpio->p2o(offset); + if (offset == -1) + return; + } + + spin_lock_irqsave(&plgpio->lock, flags); + plgpio_reg_reset(plgpio->base, offset, plgpio->regs.ie); + spin_unlock_irqrestore(&plgpio->lock, flags); +} + +static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger) +{ + struct plgpio *plgpio = irq_data_get_irq_chip_data(d); + int offset = d->irq - plgpio->irq_base; + void __iomem *reg_off; + unsigned int supported_type = 0, val; + + if (offset >= plgpio->chip.ngpio) + return -EINVAL; + + if (plgpio->regs.eit == -1) + supported_type = IRQ_TYPE_LEVEL_HIGH; + else + supported_type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; + + if (!(trigger & supported_type)) + return -EINVAL; + + if (plgpio->regs.eit == -1) + return 0; + + reg_off = REG_OFFSET(plgpio->base, plgpio->regs.eit, offset); + val = readl_relaxed(reg_off); + + offset = PIN_OFFSET(offset); + if (trigger & IRQ_TYPE_EDGE_RISING) + writel_relaxed(val | (1 << offset), reg_off); + else + writel_relaxed(val & ~(1 << offset), reg_off); + + return 0; +} + +static struct irq_chip plgpio_irqchip = { + .name = "PLGPIO", + .irq_enable = plgpio_irq_enable, + .irq_disable = plgpio_irq_disable, + .irq_set_type = plgpio_irq_set_type, +}; + +static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc) +{ + struct plgpio *plgpio = irq_get_handler_data(irq); + struct irq_chip *irqchip = irq_desc_get_chip(desc); + int regs_count, count, pin, offset, i = 0; + unsigned long pending; + + count = plgpio->chip.ngpio; + regs_count = DIV_ROUND_UP(count, MAX_GPIO_PER_REG); + + chained_irq_enter(irqchip, desc); + /* check all plgpio MIS registers for a possible interrupt */ + for (; i < regs_count; i++) { + pending = readl_relaxed(plgpio->base + plgpio->regs.mis + + i * sizeof(int *)); + if (!pending) + continue; + + /* clear interrupts */ + writel_relaxed(~pending, plgpio->base + plgpio->regs.mis + + i * sizeof(int *)); + /* + * clear extra bits in last register having gpios < MAX/REG + * ex: Suppose there are max 102 plgpios. then last register + * must have only (102 - MAX_GPIO_PER_REG * 3) = 6 relevant bits + * so, we must not take other 28 bits into consideration for + * checking interrupt. so clear those bits. + */ + count = count - i * MAX_GPIO_PER_REG; + if (count < MAX_GPIO_PER_REG) + pending &= (1 << count) - 1; + + for_each_set_bit(offset, &pending, MAX_GPIO_PER_REG) { + /* get correct pin for "offset" */ + if (plgpio->o2p && (plgpio->p2o_regs & PTO_MIS_REG)) { + pin = plgpio->o2p(offset); + if (pin == -1) + continue; + } else + pin = offset; + + /* get correct irq line number */ + pin = i * MAX_GPIO_PER_REG + pin; + generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin)); + } + } + chained_irq_exit(irqchip, desc); +} + +/* + * pin to offset and offset to pin converter functions + * + * In spear310 there is inconsistency among bit positions in plgpio regiseters, + * for different plgpio pins. For example: for pin 27, bit offset is 23, pin + * 28-33 are not supported, pin 95 has offset bit 95, bit 100 has offset bit 1 + */ +static int spear310_p2o(int pin) +{ + int offset = pin; + + if (pin <= 27) + offset += 4; + else if (pin <= 33) + offset = -1; + else if (pin <= 97) + offset -= 2; + else if (pin <= 101) + offset = 101 - pin; + else + offset = -1; + + return offset; +} + +int spear310_o2p(int offset) +{ + if (offset <= 3) + return 101 - offset; + else if (offset <= 31) + return offset - 4; + else + return offset + 2; +} + +static int __devinit plgpio_probe_dt(struct platform_device *pdev, + struct plgpio *plgpio) +{ + struct device_node *np = pdev->dev.of_node; + int ret = -EINVAL; + u32 val; + + if (of_machine_is_compatible("st,spear310")) { + plgpio->p2o = spear310_p2o; + plgpio->o2p = spear310_o2p; + plgpio->p2o_regs = PTO_WDATA_REG | PTO_DIR_REG | PTO_IE_REG | + PTO_RDATA_REG | PTO_MIS_REG; + } + + if (!of_property_read_u32(np, "st-plgpio,ngpio", &val)) { + plgpio->chip.ngpio = val; + } else { + dev_err(&pdev->dev, "DT: Invalid ngpio field\n"); + goto end; + } + + if (!of_property_read_u32(np, "st-plgpio,enb-reg", &val)) + plgpio->regs.enb = val; + else + plgpio->regs.enb = -1; + + if (!of_property_read_u32(np, "st-plgpio,wdata-reg", &val)) { + plgpio->regs.wdata = val; + } else { + dev_err(&pdev->dev, "DT: Invalid wdata reg\n"); + goto end; + } + + if (!of_property_read_u32(np, "st-plgpio,dir-reg", &val)) { + plgpio->regs.dir = val; + } else { + dev_err(&pdev->dev, "DT: Invalid dir reg\n"); + goto end; + } + + if (!of_property_read_u32(np, "st-plgpio,ie-reg", &val)) { + plgpio->regs.ie = val; + } else { + dev_err(&pdev->dev, "DT: Invalid ie reg\n"); + goto end; + } + + if (!of_property_read_u32(np, "st-plgpio,rdata-reg", &val)) { + plgpio->regs.rdata = val; + } else { + dev_err(&pdev->dev, "DT: Invalid rdata reg\n"); + goto end; + } + + if (!of_property_read_u32(np, "st-plgpio,mis-reg", &val)) { + plgpio->regs.mis = val; + } else { + dev_err(&pdev->dev, "DT: Invalid mis reg\n"); + goto end; + } + + if (!of_property_read_u32(np, "st-plgpio,eit-reg", &val)) + plgpio->regs.eit = val; + else + plgpio->regs.eit = -1; + + return 0; + +end: + return ret; +} +static int __devinit plgpio_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct plgpio *plgpio; + struct resource *res; + int ret, irq, i; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n"); + return -EBUSY; + } + + plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL); + if (!plgpio) { + dev_err(&pdev->dev, "memory allocation fail\n"); + return -ENOMEM; + } + + plgpio->base = devm_request_and_ioremap(&pdev->dev, res); + if (!plgpio->base) { + dev_err(&pdev->dev, "request and ioremap fail\n"); + return -ENOMEM; + } + + ret = plgpio_probe_dt(pdev, plgpio); + if (ret) { + dev_err(&pdev->dev, "DT probe failed\n"); + return ret; + } + + plgpio->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(plgpio->clk)) + dev_warn(&pdev->dev, "clk_get() failed, work without it\n"); + +#ifdef CONFIG_PM + plgpio->csave_regs = devm_kzalloc(&pdev->dev, + sizeof(*plgpio->csave_regs) * + DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG), + GFP_KERNEL); + if (!plgpio->csave_regs) { + dev_err(&pdev->dev, "csave registers memory allocation fail\n"); + return -ENOMEM; + } +#endif + + platform_set_drvdata(pdev, plgpio); + spin_lock_init(&plgpio->lock); + + plgpio->irq_base = -1; + plgpio->chip.base = -1; + plgpio->chip.request = plgpio_request; + plgpio->chip.free = plgpio_free; + plgpio->chip.direction_input = plgpio_direction_input; + plgpio->chip.direction_output = plgpio_direction_output; + plgpio->chip.get = plgpio_get_value; + plgpio->chip.set = plgpio_set_value; + plgpio->chip.to_irq = plgpio_to_irq; + plgpio->chip.label = dev_name(&pdev->dev); + plgpio->chip.dev = &pdev->dev; + plgpio->chip.owner = THIS_MODULE; + + ret = gpiochip_add(&plgpio->chip); + if (ret) { + dev_err(&pdev->dev, "unable to add gpio chip\n"); + return ret; + } + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_info(&pdev->dev, "irqs not supported\n"); + return 0; + } + + plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0); + if (IS_ERR_VALUE(plgpio->irq_base)) { + /* we would not support irq for gpio */ + dev_warn(&pdev->dev, "couldn't allocate irq base\n"); + return 0; + } + + plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio, + plgpio->irq_base, 0, &irq_domain_simple_ops, NULL); + if (WARN_ON(!plgpio->irq_domain)) { + dev_err(&pdev->dev, "irq domain init failed\n"); + irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio); + ret = -ENXIO; + goto remove_gpiochip; + } + + irq_set_chained_handler(irq, plgpio_irq_handler); + for (i = 0; i < plgpio->chip.ngpio; i++) { + irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip, + handle_simple_irq); + set_irq_flags(i + plgpio->irq_base, IRQF_VALID); + irq_set_chip_data(i + plgpio->irq_base, plgpio); + } + + irq_set_handler_data(irq, plgpio); + dev_info(&pdev->dev, "PLGPIO registered with IRQs\n"); + + return 0; + +remove_gpiochip: + dev_info(&pdev->dev, "Remove gpiochip\n"); + if (gpiochip_remove(&plgpio->chip)) + dev_err(&pdev->dev, "unable to remove gpiochip\n"); + + return ret; +} + +#ifdef CONFIG_PM +static int plgpio_suspend(struct device *dev) +{ + struct plgpio *plgpio = dev_get_drvdata(dev); + int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG); + void __iomem *off; + + for (i = 0; i < reg_count; i++) { + off = plgpio->base + i * sizeof(int *); + + if (plgpio->regs.enb != -1) + plgpio->csave_regs[i].enb = + readl_relaxed(plgpio->regs.enb + off); + if (plgpio->regs.eit != -1) + plgpio->csave_regs[i].eit = + readl_relaxed(plgpio->regs.eit + off); + plgpio->csave_regs[i].wdata = readl_relaxed(plgpio->regs.wdata + + off); + plgpio->csave_regs[i].dir = readl_relaxed(plgpio->regs.dir + + off); + plgpio->csave_regs[i].ie = readl_relaxed(plgpio->regs.ie + off); + } + + return 0; +} + +/* + * This is used to correct the values in end registers. End registers contain + * extra bits that might be used for other purpose in platform. So, we shouldn't + * overwrite these bits. This macro, reads given register again, preserves other + * bit values (non-plgpio bits), and retain captured value (plgpio bits). + */ +#define plgpio_prepare_reg(__reg, _off, _mask, _tmp) \ +{ \ + _tmp = readl_relaxed(plgpio->regs.__reg + _off); \ + _tmp &= ~_mask; \ + plgpio->csave_regs[i].__reg = \ + _tmp | (plgpio->csave_regs[i].__reg & _mask); \ +} + +static int plgpio_resume(struct device *dev) +{ + struct plgpio *plgpio = dev_get_drvdata(dev); + int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG); + void __iomem *off; + u32 mask, tmp; + + for (i = 0; i < reg_count; i++) { + off = plgpio->base + i * sizeof(int *); + + if (i == reg_count - 1) { + mask = (1 << (plgpio->chip.ngpio - i * + MAX_GPIO_PER_REG)) - 1; + + if (plgpio->regs.enb != -1) + plgpio_prepare_reg(enb, off, mask, tmp); + + if (plgpio->regs.eit != -1) + plgpio_prepare_reg(eit, off, mask, tmp); + + plgpio_prepare_reg(wdata, off, mask, tmp); + plgpio_prepare_reg(dir, off, mask, tmp); + plgpio_prepare_reg(ie, off, mask, tmp); + } + + writel_relaxed(plgpio->csave_regs[i].wdata, plgpio->regs.wdata + + off); + writel_relaxed(plgpio->csave_regs[i].dir, plgpio->regs.dir + + off); + + if (plgpio->regs.eit != -1) + writel_relaxed(plgpio->csave_regs[i].eit, + plgpio->regs.eit + off); + + writel_relaxed(plgpio->csave_regs[i].ie, plgpio->regs.ie + off); + + if (plgpio->regs.enb != -1) + writel_relaxed(plgpio->csave_regs[i].enb, + plgpio->regs.enb + off); + } + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(plgpio_dev_pm_ops, plgpio_suspend, plgpio_resume); + +static const struct of_device_id plgpio_of_match[] = { + { .compatible = "st,spear-plgpio" }, + {} +}; +MODULE_DEVICE_TABLE(of, plgpio_of_match); + +static struct platform_driver plgpio_driver = { + .probe = plgpio_probe, + .driver = { + .owner = THIS_MODULE, + .name = "spear-plgpio", + .pm = &plgpio_dev_pm_ops, + .of_match_table = of_match_ptr(plgpio_of_match), + }, +}; + +static int __init plgpio_init(void) +{ + return platform_driver_register(&plgpio_driver); +} +subsys_initcall(plgpio_init); + +MODULE_AUTHOR("Viresh Kumar "); +MODULE_DESCRIPTION("ST Microlectronics SPEAr PLGPIO driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From d4a31ee8997b2fbd82837182363cf8fa84abf347 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 17 Oct 2012 13:16:46 +0200 Subject: ARM: U300: bump IRQs to offset 32 The U300 IRQs were bumped once to offset to 1 (in order to avoid using IRQ 0 which is now NO_IRQ). This was OK as we were still passing the number of irqs in the .nr_irqs field of the machine, with descriptors allocated at boot time. However .nr_irqs should be 0, leading the system to reserve the first 16 IRQs. Then the VIC driver will complain that IRQs 1 thru 15 are pre-allocated, so to avoid this and use free descriptors, move all IRQs up to offset 32. This will all be done away with as we migrate to device tree, so it is an interim solution. Acked-by: Olof Johansson Signed-off-by: Linus Walleij --- arch/arm/mach-u300/core.c | 2 +- arch/arm/mach-u300/include/mach/irqs.h | 116 ++++++++++++++++----------------- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index b8efac4daed..603c08ec878 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1804,7 +1804,7 @@ MACHINE_START(U300, "Ericsson AB U335 S335/B335 Prototype Board") /* Maintainer: Linus Walleij */ .atag_offset = 0x100, .map_io = u300_map_io, - .nr_irqs = NR_IRQS_U300, + .nr_irqs = 0, .init_irq = u300_init_irq, .handle_irq = vic_handle_irq, .timer = &u300_timer, diff --git a/arch/arm/mach-u300/include/mach/irqs.h b/arch/arm/mach-u300/include/mach/irqs.h index e27425a63fa..e85ec3868d0 100644 --- a/arch/arm/mach-u300/include/mach/irqs.h +++ b/arch/arm/mach-u300/include/mach/irqs.h @@ -12,70 +12,70 @@ #ifndef __MACH_IRQS_H #define __MACH_IRQS_H -#define IRQ_U300_INTCON0_START 1 -#define IRQ_U300_INTCON1_START 33 +#define IRQ_U300_INTCON0_START 32 +#define IRQ_U300_INTCON1_START 64 /* These are on INTCON0 - 30 lines */ -#define IRQ_U300_IRQ0_EXT 1 -#define IRQ_U300_IRQ1_EXT 2 -#define IRQ_U300_DMA 3 -#define IRQ_U300_VIDEO_ENC_0 4 -#define IRQ_U300_VIDEO_ENC_1 5 -#define IRQ_U300_AAIF_RX 6 -#define IRQ_U300_AAIF_TX 7 -#define IRQ_U300_AAIF_VGPIO 8 -#define IRQ_U300_AAIF_WAKEUP 9 -#define IRQ_U300_PCM_I2S0_FRAME 10 -#define IRQ_U300_PCM_I2S0_FIFO 11 -#define IRQ_U300_PCM_I2S1_FRAME 12 -#define IRQ_U300_PCM_I2S1_FIFO 13 -#define IRQ_U300_XGAM_GAMCON 14 -#define IRQ_U300_XGAM_CDI 15 -#define IRQ_U300_XGAM_CDICON 16 -#define IRQ_U300_XGAM_PDI 18 -#define IRQ_U300_XGAM_PDICON 19 -#define IRQ_U300_XGAM_GAMEACC 20 -#define IRQ_U300_XGAM_MCIDCT 21 -#define IRQ_U300_APEX 22 -#define IRQ_U300_UART0 23 -#define IRQ_U300_SPI 24 -#define IRQ_U300_TIMER_APP_OS 25 -#define IRQ_U300_TIMER_APP_DD 26 -#define IRQ_U300_TIMER_APP_GP1 27 -#define IRQ_U300_TIMER_APP_GP2 28 -#define IRQ_U300_TIMER_OS 29 -#define IRQ_U300_TIMER_MS 30 -#define IRQ_U300_KEYPAD_KEYBF 31 -#define IRQ_U300_KEYPAD_KEYBR 32 +#define IRQ_U300_IRQ0_EXT 32 +#define IRQ_U300_IRQ1_EXT 33 +#define IRQ_U300_DMA 34 +#define IRQ_U300_VIDEO_ENC_0 35 +#define IRQ_U300_VIDEO_ENC_1 36 +#define IRQ_U300_AAIF_RX 37 +#define IRQ_U300_AAIF_TX 38 +#define IRQ_U300_AAIF_VGPIO 39 +#define IRQ_U300_AAIF_WAKEUP 40 +#define IRQ_U300_PCM_I2S0_FRAME 41 +#define IRQ_U300_PCM_I2S0_FIFO 42 +#define IRQ_U300_PCM_I2S1_FRAME 43 +#define IRQ_U300_PCM_I2S1_FIFO 44 +#define IRQ_U300_XGAM_GAMCON 45 +#define IRQ_U300_XGAM_CDI 46 +#define IRQ_U300_XGAM_CDICON 47 +#define IRQ_U300_XGAM_PDI 49 +#define IRQ_U300_XGAM_PDICON 50 +#define IRQ_U300_XGAM_GAMEACC 51 +#define IRQ_U300_XGAM_MCIDCT 52 +#define IRQ_U300_APEX 53 +#define IRQ_U300_UART0 54 +#define IRQ_U300_SPI 55 +#define IRQ_U300_TIMER_APP_OS 56 +#define IRQ_U300_TIMER_APP_DD 57 +#define IRQ_U300_TIMER_APP_GP1 58 +#define IRQ_U300_TIMER_APP_GP2 59 +#define IRQ_U300_TIMER_OS 60 +#define IRQ_U300_TIMER_MS 61 +#define IRQ_U300_KEYPAD_KEYBF 62 +#define IRQ_U300_KEYPAD_KEYBR 63 /* These are on INTCON1 - 32 lines */ -#define IRQ_U300_GPIO_PORT0 33 -#define IRQ_U300_GPIO_PORT1 34 -#define IRQ_U300_GPIO_PORT2 35 +#define IRQ_U300_GPIO_PORT0 64 +#define IRQ_U300_GPIO_PORT1 65 +#define IRQ_U300_GPIO_PORT2 66 /* These are for DB3150, DB3200 and DB3350 */ -#define IRQ_U300_WDOG 36 -#define IRQ_U300_EVHIST 37 -#define IRQ_U300_MSPRO 38 -#define IRQ_U300_MMCSD_MCIINTR0 39 -#define IRQ_U300_MMCSD_MCIINTR1 40 -#define IRQ_U300_I2C0 41 -#define IRQ_U300_I2C1 42 -#define IRQ_U300_RTC 43 -#define IRQ_U300_NFIF 44 -#define IRQ_U300_NFIF2 45 +#define IRQ_U300_WDOG 67 +#define IRQ_U300_EVHIST 68 +#define IRQ_U300_MSPRO 69 +#define IRQ_U300_MMCSD_MCIINTR0 70 +#define IRQ_U300_MMCSD_MCIINTR1 71 +#define IRQ_U300_I2C0 72 +#define IRQ_U300_I2C1 73 +#define IRQ_U300_RTC 74 +#define IRQ_U300_NFIF 75 +#define IRQ_U300_NFIF2 76 /* The DB3350-specific interrupt lines */ -#define IRQ_U300_ISP_F0 46 -#define IRQ_U300_ISP_F1 47 -#define IRQ_U300_ISP_F2 48 -#define IRQ_U300_ISP_F3 49 -#define IRQ_U300_ISP_F4 50 -#define IRQ_U300_GPIO_PORT3 51 -#define IRQ_U300_SYSCON_PLL_LOCK 52 -#define IRQ_U300_UART1 53 -#define IRQ_U300_GPIO_PORT4 54 -#define IRQ_U300_GPIO_PORT5 55 -#define IRQ_U300_GPIO_PORT6 56 -#define U300_VIC_IRQS_END 57 +#define IRQ_U300_ISP_F0 77 +#define IRQ_U300_ISP_F1 78 +#define IRQ_U300_ISP_F2 79 +#define IRQ_U300_ISP_F3 80 +#define IRQ_U300_ISP_F4 81 +#define IRQ_U300_GPIO_PORT3 82 +#define IRQ_U300_SYSCON_PLL_LOCK 83 +#define IRQ_U300_UART1 84 +#define IRQ_U300_GPIO_PORT4 85 +#define IRQ_U300_GPIO_PORT5 86 +#define IRQ_U300_GPIO_PORT6 87 +#define U300_VIC_IRQS_END 88 /* Maximum 8*7 GPIO lines */ #ifdef CONFIG_PINCTRL_COH901 -- cgit v1.2.3 From a6c45b99a658521291cfb66ecf035cc58b38f206 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 17 Oct 2012 18:31:20 +0200 Subject: pinctrl/coh901: use irqdomain, allocate irqdescs This switches the COH 901 pinctrl driver to allocate its GPIO IRQs dynamically, and start to use a linear irqdomain to map from the hardware IRQs. This way we can cut away the complex allocation of IRQ numbers from the file. Signed-off-by: Linus Walleij --- arch/arm/mach-u300/core.c | 1 - arch/arm/mach-u300/include/mach/irqs.h | 10 ----- drivers/pinctrl/pinctrl-coh901.c | 60 +++++++++++++++++++++------- include/linux/platform_data/pinctrl-coh901.h | 2 - 4 files changed, 46 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 603c08ec878..ce2de0d6f2e 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1445,7 +1445,6 @@ static struct platform_device pinctrl_device = { static struct u300_gpio_platform u300_gpio_plat = { .ports = 7, .gpio_base = 0, - .gpio_irq_base = IRQ_U300_GPIO_BASE, .pinctrl_device = &pinctrl_device, }; diff --git a/arch/arm/mach-u300/include/mach/irqs.h b/arch/arm/mach-u300/include/mach/irqs.h index e85ec3868d0..21d5e76a6cd 100644 --- a/arch/arm/mach-u300/include/mach/irqs.h +++ b/arch/arm/mach-u300/include/mach/irqs.h @@ -77,14 +77,4 @@ #define IRQ_U300_GPIO_PORT6 87 #define U300_VIC_IRQS_END 88 -/* Maximum 8*7 GPIO lines */ -#ifdef CONFIG_PINCTRL_COH901 -#define IRQ_U300_GPIO_BASE (U300_VIC_IRQS_END) -#define IRQ_U300_GPIO_END (IRQ_U300_GPIO_BASE + 56) -#else -#define IRQ_U300_GPIO_END (U300_VIC_IRQS_END) -#endif - -#define NR_IRQS_U300 (IRQ_U300_GPIO_END - IRQ_U300_INTCON0_START) - #endif diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index b446c964121..152efae3df8 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -67,7 +68,6 @@ struct u300_gpio { struct resource *memres; void __iomem *base; struct device *dev; - int irq_base; u32 stride; /* Register offsets */ u32 pcr; @@ -83,6 +83,7 @@ struct u300_gpio_port { struct list_head node; struct u300_gpio *gpio; char name[8]; + struct irq_domain *domain; int irq; int number; u8 toggle_edge_mode; @@ -314,10 +315,30 @@ static int u300_gpio_direction_output(struct gpio_chip *chip, unsigned offset, static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { struct u300_gpio *gpio = to_u300_gpio(chip); - int retirq = gpio->irq_base + offset; + int portno = offset >> 3; + struct u300_gpio_port *port = NULL; + struct list_head *p; + int retirq; - dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d\n", offset, - retirq); + list_for_each(p, &gpio->port_list) { + port = list_entry(p, struct u300_gpio_port, node); + if (port->number == portno) + break; + } + if (port == NULL) { + dev_err(gpio->dev, "could not locate port for GPIO %d IRQ\n", + offset); + return -EINVAL; + } + + /* + * The local hwirqs on the port are the lower three bits, there + * are exactly 8 IRQs per port since they are 8-bit + */ + retirq = irq_find_mapping(port->domain, (offset & 0x7)); + + dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d from port %d\n", + offset, retirq, port->number); return retirq; } @@ -467,7 +488,7 @@ static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger) { struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); struct u300_gpio *gpio = port->gpio; - int offset = d->irq - gpio->irq_base; + int offset = (port->number << 3) + d->hwirq; u32 val; if ((trigger & IRQF_TRIGGER_RISING) && @@ -503,10 +524,12 @@ static void u300_gpio_irq_enable(struct irq_data *d) { struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); struct u300_gpio *gpio = port->gpio; - int offset = d->irq - gpio->irq_base; + int offset = (port->number << 3) + d->hwirq; u32 val; unsigned long flags; + dev_dbg(gpio->dev, "enable IRQ for hwirq %lu on port %s, offset %d\n", + d->hwirq, port->name, offset); local_irq_save(flags); val = readl(U300_PIN_REG(offset, ien)); writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); @@ -517,7 +540,7 @@ static void u300_gpio_irq_disable(struct irq_data *d) { struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); struct u300_gpio *gpio = port->gpio; - int offset = d->irq - gpio->irq_base; + int offset = (port->number << 3) + d->hwirq; u32 val; unsigned long flags; @@ -555,8 +578,7 @@ static void u300_gpio_irq_handler(unsigned irq, struct irq_desc *desc) int irqoffset; for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { - int pin_irq = gpio->irq_base + (port->number << 3) - + irqoffset; + int pin_irq = irq_find_mapping(port->domain, irqoffset); int offset = pinoffset + irqoffset; dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", @@ -631,6 +653,8 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio) list_for_each_safe(p, n, &gpio->port_list) { port = list_entry(p, struct u300_gpio_port, node); list_del(&port->node); + if (port->domain) + irq_domain_remove(port->domain); kfree(port); } } @@ -653,7 +677,6 @@ static int __init u300_gpio_probe(struct platform_device *pdev) gpio->chip = u300_gpio_chip; gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT; - gpio->irq_base = plat->gpio_irq_base; gpio->chip.dev = &pdev->dev; gpio->chip.base = plat->gpio_base; gpio->dev = &pdev->dev; @@ -732,18 +755,26 @@ static int __init u300_gpio_probe(struct platform_device *pdev) port->irq = platform_get_irq_byname(pdev, port->name); - dev_dbg(gpio->dev, "register IRQ %d for %s\n", port->irq, + dev_dbg(gpio->dev, "register IRQ %d for port %s\n", port->irq, port->name); + port->domain = irq_domain_add_linear(pdev->dev.of_node, + U300_GPIO_PINS_PER_PORT, + &irq_domain_simple_ops, + port); + if (!port->domain) + goto err_no_domain; + irq_set_chained_handler(port->irq, u300_gpio_irq_handler); irq_set_handler_data(port->irq, port); /* For each GPIO pin set the unique IRQ handler */ for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) { - int irqno = gpio->irq_base + (portno << 3) + i; + int irqno = irq_create_mapping(port->domain, i); - dev_dbg(gpio->dev, "handler for IRQ %d on %s\n", - irqno, port->name); + dev_dbg(gpio->dev, "GPIO%d on port %s gets IRQ %d\n", + gpio->chip.base + (port->number << 3) + i, + port->name, irqno); irq_set_chip_and_handler(irqno, &u300_gpio_irqchip, handle_simple_irq); set_irq_flags(irqno, IRQF_VALID); @@ -776,6 +807,7 @@ static int __init u300_gpio_probe(struct platform_device *pdev) err_no_pinctrl: err = gpiochip_remove(&gpio->chip); err_no_chip: +err_no_domain: err_no_port: u300_gpio_free_ports(gpio); iounmap(gpio->base); diff --git a/include/linux/platform_data/pinctrl-coh901.h b/include/linux/platform_data/pinctrl-coh901.h index 30dea251b83..27a23b318ce 100644 --- a/include/linux/platform_data/pinctrl-coh901.h +++ b/include/linux/platform_data/pinctrl-coh901.h @@ -13,13 +13,11 @@ * struct u300_gpio_platform - U300 GPIO platform data * @ports: number of GPIO block ports * @gpio_base: first GPIO number for this block (use a free range) - * @gpio_irq_base: first GPIO IRQ number for this block (use a free range) * @pinctrl_device: pin control device to spawn as child */ struct u300_gpio_platform { u8 ports; int gpio_base; - int gpio_irq_base; struct platform_device *pinctrl_device; }; -- cgit v1.2.3 From 585583f54f577d7fd93247101b9f61c8bbbd21f1 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 17 Oct 2012 18:49:05 +0200 Subject: pinctrl/coh901: convert to use managed resources This switches the COH 901 pin controller to use managed resources (devm_*) for memory remaps, clocks, etc. Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-coh901.c | 62 ++++++++++++---------------------------- 1 file changed, 19 insertions(+), 43 deletions(-) diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index 152efae3df8..5c7daf9169e 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -65,7 +65,6 @@ struct u300_gpio { struct gpio_chip chip; struct list_head port_list; struct clk *clk; - struct resource *memres; void __iomem *base; struct device *dev; u32 stride; @@ -663,17 +662,16 @@ static int __init u300_gpio_probe(struct platform_device *pdev) { struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); struct u300_gpio *gpio; + struct resource *memres; int err = 0; int portno; u32 val; u32 ifr; int i; - gpio = kzalloc(sizeof(struct u300_gpio), GFP_KERNEL); - if (gpio == NULL) { - dev_err(&pdev->dev, "failed to allocate memory\n"); + gpio = devm_kzalloc(&pdev->dev, sizeof(struct u300_gpio), GFP_KERNEL); + if (gpio == NULL) return -ENOMEM; - } gpio->chip = u300_gpio_chip; gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT; @@ -681,37 +679,29 @@ static int __init u300_gpio_probe(struct platform_device *pdev) gpio->chip.base = plat->gpio_base; gpio->dev = &pdev->dev; - /* Get GPIO clock */ - gpio->clk = clk_get(gpio->dev, NULL); + memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!memres) { + dev_err(gpio->dev, "could not get GPIO memory resource\n"); + return -ENODEV; + } + + gpio->base = devm_request_and_ioremap(&pdev->dev, memres); + if (!gpio->base) { + dev_err(gpio->dev, "could not get remap memory\n"); + return -ENOMEM; + } + + gpio->clk = devm_clk_get(gpio->dev, NULL); if (IS_ERR(gpio->clk)) { err = PTR_ERR(gpio->clk); dev_err(gpio->dev, "could not get GPIO clock\n"); - goto err_no_clk; + return err; } + err = clk_prepare_enable(gpio->clk); if (err) { dev_err(gpio->dev, "could not enable GPIO clock\n"); - goto err_no_clk_enable; - } - - gpio->memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!gpio->memres) { - dev_err(gpio->dev, "could not get GPIO memory resource\n"); - err = -ENODEV; - goto err_no_resource; - } - - if (!request_mem_region(gpio->memres->start, - resource_size(gpio->memres), - "GPIO Controller")) { - err = -ENODEV; - goto err_no_ioregion; - } - - gpio->base = ioremap(gpio->memres->start, resource_size(gpio->memres)); - if (!gpio->base) { - err = -ENOMEM; - goto err_no_ioremap; + return err; } dev_info(gpio->dev, @@ -810,16 +800,7 @@ err_no_chip: err_no_domain: err_no_port: u300_gpio_free_ports(gpio); - iounmap(gpio->base); -err_no_ioremap: - release_mem_region(gpio->memres->start, resource_size(gpio->memres)); -err_no_ioregion: -err_no_resource: clk_disable_unprepare(gpio->clk); -err_no_clk_enable: - clk_put(gpio->clk); -err_no_clk: - kfree(gpio); dev_info(&pdev->dev, "module ERROR:%d\n", err); return err; } @@ -838,13 +819,8 @@ static int __exit u300_gpio_remove(struct platform_device *pdev) return err; } u300_gpio_free_ports(gpio); - iounmap(gpio->base); - release_mem_region(gpio->memres->start, - resource_size(gpio->memres)); clk_disable_unprepare(gpio->clk); - clk_put(gpio->clk); platform_set_drvdata(pdev, NULL); - kfree(gpio); return 0; } -- cgit v1.2.3 From b36bdc5911effe819e415b144388853bf07a543b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 17 Oct 2012 19:17:56 +0200 Subject: pinctrl/u300: use managed resources This converts the U300 pin controller to use managed resources (devm_*) for it's memory region. Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-u300.c | 32 ++++---------------------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index 309f5b9a70e..2e9825e304a 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c @@ -663,8 +663,6 @@ static const struct pinctrl_pin_desc u300_pads[] = { struct u300_pmx { struct device *dev; struct pinctrl_dev *pctl; - u32 phybase; - u32 physize; void __iomem *virtbase; }; @@ -1110,7 +1108,6 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) struct u300_pmx *upmx; struct resource *res; struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev); - int ret; int i; /* Create state holders etc for this driver */ @@ -1123,26 +1120,15 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENOENT; - upmx->phybase = res->start; - upmx->physize = resource_size(res); - - if (request_mem_region(upmx->phybase, upmx->physize, - DRIVER_NAME) == NULL) { - ret = -ENOMEM; - goto out_no_memregion; - } - upmx->virtbase = ioremap(upmx->phybase, upmx->physize); - if (!upmx->virtbase) { - ret = -ENOMEM; - goto out_no_remap; - } + upmx->virtbase = devm_request_and_ioremap(&pdev->dev, res); + if (!upmx->virtbase) + return -ENOMEM; upmx->pctl = pinctrl_register(&u300_pmx_desc, &pdev->dev, upmx); if (!upmx->pctl) { dev_err(&pdev->dev, "could not register U300 pinmux driver\n"); - ret = -EINVAL; - goto out_no_pmx; + return -EINVAL; } /* We will handle a range of GPIO pins */ @@ -1156,14 +1142,6 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) dev_info(&pdev->dev, "initialized U300 pin control driver\n"); return 0; - -out_no_pmx: - iounmap(upmx->virtbase); -out_no_remap: - platform_set_drvdata(pdev, NULL); -out_no_memregion: - release_mem_region(upmx->phybase, upmx->physize); - return ret; } static int __devexit u300_pmx_remove(struct platform_device *pdev) @@ -1171,8 +1149,6 @@ static int __devexit u300_pmx_remove(struct platform_device *pdev) struct u300_pmx *upmx = platform_get_drvdata(pdev); pinctrl_unregister(upmx->pctl); - iounmap(upmx->virtbase); - release_mem_region(upmx->phybase, upmx->physize); platform_set_drvdata(pdev, NULL); return 0; -- cgit v1.2.3 From e1b29abef69e34a42169cd65d7249b18574c94e8 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 5 Nov 2012 21:42:16 +0800 Subject: pinctrl: u300: Staticize non-exported symbols Staticize u300_pin_config_get() and u300_pin_config_set() functions. Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-u300.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index 2e9825e304a..d756cce588f 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c @@ -1052,9 +1052,8 @@ static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin) return NULL; } -int u300_pin_config_get(struct pinctrl_dev *pctldev, - unsigned pin, - unsigned long *config) +static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long *config) { struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); @@ -1067,9 +1066,8 @@ int u300_pin_config_get(struct pinctrl_dev *pctldev, config); } -int u300_pin_config_set(struct pinctrl_dev *pctldev, - unsigned pin, - unsigned long config) +static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long config) { struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); int ret; -- cgit v1.2.3 From 33dfc41461b77e2b38673ec1b5622b1d9340324d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 5 Nov 2012 21:44:28 +0800 Subject: pinctrl: sirf: Staticize non-exported symbol Staticize sirfsoc_gpio_irq_map() function. Signed-off-by: Axel Lin Acked-by: Barry Song Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-sirf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index 16ec7d4d81e..a3905e58d1b 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c @@ -1642,8 +1642,8 @@ static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset, spin_unlock_irqrestore(&bank->lock, flags); } -int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) +static int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq) { struct sirfsoc_gpio_bank *bank = d->host_data; -- cgit v1.2.3 From 165adc9c1734a3f3bdbc6dc7c7a29bbefb424006 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Nov 2012 14:49:39 +0100 Subject: gpiolib: fix up function prototypes etc Commit 69e1601bca88809dc118abd1becb02c15a02ec71 "gpiolib: provide provision to register pin ranges" Got most of it's function prototypes wrong, so fix this up by: - Moving the void declarations into static inlines in (previously the actual prototypes were declared here...) - Declare the gpiochip_add_pin_range() and gpiochip_remove_pin_ranges() functions in together with the pin range struct declaration itself. - Actually only implement these very functions in gpiolib.c if CONFIG_PINCTRL is set. - Additionally export the symbols since modules will need to be able to do this. Reviewed-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 10 +++++----- include/asm-generic/gpio.h | 6 ++++++ include/linux/gpio.h | 24 ++++++++++++++++++------ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f0b07bbfcc9..1e1a7cabc57 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1185,6 +1185,7 @@ struct gpio_chip *gpiochip_find(void *data, EXPORT_SYMBOL_GPL(gpiochip_find); #ifdef CONFIG_PINCTRL + void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, unsigned int pin_base, unsigned int npins) { @@ -1206,6 +1207,7 @@ void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, list_add_tail(&pin_range->node, &chip->pin_ranges); } +EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); void gpiochip_remove_pin_ranges(struct gpio_chip *chip) { @@ -1217,11 +1219,9 @@ void gpiochip_remove_pin_ranges(struct gpio_chip *chip) &pin_range->range); } } -#else -void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins) {} -void gpiochip_remove_pin_ranges(struct gpio_chip *chip) {} -#endif +EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges); + +#endif /* CONFIG_PINCTRL */ /* These "optional" allocation calls help prevent drivers from stomping * on each other, and help provide better diagnostics in debugfs. diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 92e5c432421..2e60de4265a 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -49,6 +49,7 @@ struct module; struct device_node; #ifdef CONFIG_PINCTRL + /** * struct gpio_pin_range - pin range controlled by a gpio chip * @head: list for maintaining set of pin ranges, used internally @@ -61,6 +62,11 @@ struct gpio_pin_range { struct pinctrl_dev *pctldev; struct pinctrl_gpio_range range; }; + +void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins); +void gpiochip_remove_pin_ranges(struct gpio_chip *chip); + #endif /** diff --git a/include/linux/gpio.h b/include/linux/gpio.h index a28445992b7..21d28b930dc 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -72,9 +72,9 @@ static inline int irq_to_gpio(unsigned int irq) return -EINVAL; } -#endif +#endif /* ! CONFIG_ARCH_HAVE_CUSTOM_GPIO_H */ -#else +#else /* ! CONFIG_GENERIC_GPIO */ #include #include @@ -231,9 +231,21 @@ static inline int irq_to_gpio(unsigned irq) return -EINVAL; } -void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins); -void gpiochip_remove_pin_ranges(struct gpio_chip *chip); -#endif +#ifdef CONFIG_PINCTRL + +static inline void +gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins) +{ +} + +static inline void +gpiochip_remove_pin_ranges(struct gpio_chip *chip) +{ +} + +#endif /* CONFIG_PINCTRL */ + +#endif /* ! CONFIG_GENERIC_GPIO */ #endif /* __LINUX_GPIO_H */ -- cgit v1.2.3 From 167c1af9443757bb9d27ceff8ba4304302cb0651 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Nov 2012 14:58:55 +0100 Subject: gpiolib-of: staticize the pin range calls Commit 69e1601bca88809dc118abd1becb02c15a02ec71 "gpiolib: provide provision to register pin ranges" Declared the of_gpiochip_[add|remove]_pin_range() global while they should be static as they are only ever used in this file. Let's convert them to static. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index a5b90c8e984..220caa5978f 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -218,7 +218,7 @@ err0: EXPORT_SYMBOL(of_mm_gpiochip_add); #ifdef CONFIG_PINCTRL -void of_gpiochip_add_pin_range(struct gpio_chip *chip) +static void of_gpiochip_add_pin_range(struct gpio_chip *chip) { struct device_node *np = chip->of_node; struct gpio_pin_range *pin_range; @@ -254,7 +254,7 @@ void of_gpiochip_add_pin_range(struct gpio_chip *chip) } while (index++); } -void of_gpiochip_remove_pin_range(struct gpio_chip *chip) +static void of_gpiochip_remove_pin_range(struct gpio_chip *chip) { struct gpio_pin_range *pin_range, *tmp; @@ -265,8 +265,8 @@ void of_gpiochip_remove_pin_range(struct gpio_chip *chip) } } #else -void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} -void of_gpiochip_remove_pin_range(struct gpio_chip *chip) {} +static void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} +static void of_gpiochip_remove_pin_range(struct gpio_chip *chip) {} #endif void of_gpiochip_add(struct gpio_chip *chip) -- cgit v1.2.3 From e93fa3f24353e45b189bae656ba000d0533777a3 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Nov 2012 15:03:47 +0100 Subject: gpiolib: remove duplicate pin range code Commit 69e1601bca88809dc118abd1becb02c15a02ec71 "gpiolib: provide provision to register pin ranges" Introduced both of_gpiochip_remove_pin_range() and gpiochip_remove_pin_ranges(). But the contents are exactly the same so remove the OF one and rely on the range deletion in the core. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 220caa5978f..67403e47e4d 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -254,19 +254,8 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) } while (index++); } -static void of_gpiochip_remove_pin_range(struct gpio_chip *chip) -{ - struct gpio_pin_range *pin_range, *tmp; - - list_for_each_entry_safe(pin_range, tmp, &chip->pin_ranges, node) { - list_del(&pin_range->node); - pinctrl_remove_gpio_range(pin_range->pctldev, - &pin_range->range); - } -} #else static void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} -static void of_gpiochip_remove_pin_range(struct gpio_chip *chip) {} #endif void of_gpiochip_add(struct gpio_chip *chip) @@ -288,7 +277,7 @@ void of_gpiochip_add(struct gpio_chip *chip) void of_gpiochip_remove(struct gpio_chip *chip) { - of_gpiochip_remove_pin_range(chip); + gpiochip_remove_pin_ranges(chip); if (chip->of_node) of_node_put(chip->of_node); -- cgit v1.2.3 From 9ef0d6f7628bdcb5cc3c11623930f2527a3881a0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Nov 2012 15:15:44 +0100 Subject: gpiolib: call pin removal in chip removal function This makes us call gpiochio_remove_pin_ranges() in the gpiochip_remove() function, so we get rid of ranges when freeing the chip. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 1e1a7cabc57..bcf9b9914fb 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1127,6 +1127,7 @@ int gpiochip_remove(struct gpio_chip *chip) spin_lock_irqsave(&gpio_lock, flags); + gpiochip_remove_pin_ranges(chip); of_gpiochip_remove(chip); for (id = chip->base; id < chip->base + chip->ngpio; id++) { -- cgit v1.2.3 From 1e63d7b9363f0c57d00991f9f2e0af374dfc591a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Nov 2012 16:03:35 +0100 Subject: gpiolib: separation of pin concerns The fact that of_gpiochip_add_pin_range() and gpiochip_add_pin_range() share too much code is fragile and will invariably mean that bugs need to be fixed in two places instead of one. So separate the concerns of gpiolib.c and gpiolib-of.c and have the latter call the former as back-end. This is necessary also when going forward with other device descriptions such as ACPI. This is done by: - Adding a return code to gpiochip_add_pin_range() so we can reliably check whether this succeeds. - Get rid of the custom of_pinctrl_add_gpio_range() from pinctrl. Instead create of_pinctrl_get() to just retrive the pin controller per se from an OF node. This composite function was just begging to be deleted, it was way to purpose-specific. - Use pinctrl_dev_get_name() to get the name of the retrieved pin controller and use that to call back into the generic gpiochip_add_pin_range(). Now the pin range is only allocated and tied to a pin controller from the core implementation in gpiolib.c. Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 23 +++++++++-------------- drivers/gpio/gpiolib.c | 8 +++++--- drivers/pinctrl/devicetree.c | 4 +--- include/asm-generic/gpio.h | 4 ++-- include/linux/gpio.h | 2 +- include/linux/pinctrl/pinctrl.h | 7 ++----- 6 files changed, 20 insertions(+), 28 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 67403e47e4d..a40cd84c5c1 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -221,8 +221,8 @@ EXPORT_SYMBOL(of_mm_gpiochip_add); static void of_gpiochip_add_pin_range(struct gpio_chip *chip) { struct device_node *np = chip->of_node; - struct gpio_pin_range *pin_range; struct of_phandle_args pinspec; + struct pinctrl_dev *pctldev; int index = 0, ret; if (!np) @@ -234,22 +234,17 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) if (ret) break; - pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), - GFP_KERNEL); - if (!pin_range) { - pr_err("%s: GPIO chip: failed to allocate pin ranges\n", - chip->label); + pctldev = of_pinctrl_get(pinspec.np); + if (!pctldev) break; - } - pin_range->range.name = chip->label; - pin_range->range.base = chip->base; - pin_range->range.pin_base = pinspec.args[0]; - pin_range->range.npins = pinspec.args[1]; - pin_range->pctldev = of_pinctrl_add_gpio_range(pinspec.np, - &pin_range->range); + ret = gpiochip_add_pin_range(chip, + pinctrl_dev_get_name(pctldev), + pinspec.args[0], + pinspec.args[1]); - list_add_tail(&pin_range->node, &chip->pin_ranges); + if (ret) + break; } while (index++); } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index bcf9b9914fb..c5f650095fa 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1187,8 +1187,8 @@ EXPORT_SYMBOL_GPL(gpiochip_find); #ifdef CONFIG_PINCTRL -void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins) +int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins) { struct gpio_pin_range *pin_range; @@ -1196,7 +1196,7 @@ void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, if (!pin_range) { pr_err("%s: GPIO chip: failed to allocate pin ranges\n", chip->label); - return; + return -ENOMEM; } pin_range->range.name = chip->label; @@ -1207,6 +1207,8 @@ void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, &pin_range->range); list_add_tail(&pin_range->node, &chip->pin_ranges); + + return 0; } EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index 6728ec71cb6..fe2d1af7cfa 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -106,8 +106,7 @@ static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np) return NULL; } -struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, - struct pinctrl_gpio_range *range) +struct pinctrl_dev *of_pinctrl_get(struct device_node *np) { struct pinctrl_dev *pctldev; @@ -115,7 +114,6 @@ struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, if (!pctldev) return NULL; - pinctrl_add_gpio_range(pctldev, range); return pctldev; } diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 2e60de4265a..50d995e7e44 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -63,8 +63,8 @@ struct gpio_pin_range { struct pinctrl_gpio_range range; }; -void gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins); +int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins); void gpiochip_remove_pin_ranges(struct gpio_chip *chip); #endif diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 21d28b930dc..81bbfe5b5de 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -233,7 +233,7 @@ static inline int irq_to_gpio(unsigned irq) #ifdef CONFIG_PINCTRL -static inline void +static inline int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, unsigned int pin_base, unsigned int npins) { diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 434e5a94e13..4a58428bc79 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -141,16 +141,13 @@ extern struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname, struct pinctrl_gpio_range *range); #ifdef CONFIG_OF -extern struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, - struct pinctrl_gpio_range *range); +extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np); #else static inline -struct pinctrl_dev *of_pinctrl_add_gpio_range(struct device_node *np, - struct pinctrl_gpio_range *range) +struct pinctrl_dev *of_pinctrl_get(struct device_node *np) { return NULL; } - #endif /* CONFIG_OF */ extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev); -- cgit v1.2.3 From 50309a9c2e576ac4ad29e30f5854acb87bdc2ac4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Nov 2012 17:16:39 +0100 Subject: gpiolib: iron out include ladder mistakes The <*/gpio.h> includes are updated again: now we need to account for the problem introduced by commit: 595679a8038584df7b9398bf34f61db3c038bfea "gpiolib: fix up function prototypes etc" Actually we need static inlines in include/asm-generic/gpio.h as well since we may have GPIOLIB but not PINCTRL. Make sure to move all the CONFIG_PINCTRL business to the end of the file so we are sure we have declared struct gpio_chip. And we need to keep the static inlines in but here for the !CONFIG_GENERIC_GPIO case, and then we may as well throw in a few warnings like the other prototypes there, if someone would have the bad taste of compiling without GENERIC_GPIO even. Signed-off-by: Linus Walleij --- include/asm-generic/gpio.h | 56 +++++++++++++++++++++++++++++----------------- include/linux/gpio.h | 7 +++--- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 50d995e7e44..2b84fc32fae 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -48,27 +48,6 @@ struct seq_file; struct module; struct device_node; -#ifdef CONFIG_PINCTRL - -/** - * struct gpio_pin_range - pin range controlled by a gpio chip - * @head: list for maintaining set of pin ranges, used internally - * @pctldev: pinctrl device which handles corresponding pins - * @range: actual range of pins controlled by a gpio controller - */ - -struct gpio_pin_range { - struct list_head node; - struct pinctrl_dev *pctldev; - struct pinctrl_gpio_range range; -}; - -int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins); -void gpiochip_remove_pin_ranges(struct gpio_chip *chip); - -#endif - /** * struct gpio_chip - abstract a GPIO controller * @label: for diagnostics @@ -288,4 +267,39 @@ static inline void gpio_unexport(unsigned gpio) } #endif /* CONFIG_GPIO_SYSFS */ +#ifdef CONFIG_PINCTRL + +/** + * struct gpio_pin_range - pin range controlled by a gpio chip + * @head: list for maintaining set of pin ranges, used internally + * @pctldev: pinctrl device which handles corresponding pins + * @range: actual range of pins controlled by a gpio controller + */ + +struct gpio_pin_range { + struct list_head node; + struct pinctrl_dev *pctldev; + struct pinctrl_gpio_range range; +}; + +int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins); +void gpiochip_remove_pin_ranges(struct gpio_chip *chip); + +#else + +static inline int +gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, + unsigned int pin_base, unsigned int npins) +{ + return 0; +} + +static inline void +gpiochip_remove_pin_ranges(struct gpio_chip *chip) +{ +} + +#endif /* CONFIG_PINCTRL */ + #endif /* _ASM_GENERIC_GPIO_H */ diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 81bbfe5b5de..7ba2762abbc 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -231,21 +231,20 @@ static inline int irq_to_gpio(unsigned irq) return -EINVAL; } -#ifdef CONFIG_PINCTRL - static inline int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, unsigned int pin_base, unsigned int npins) { + WARN_ON(1); + return -EINVAL; } static inline void gpiochip_remove_pin_ranges(struct gpio_chip *chip) { + WARN_ON(1); } -#endif /* CONFIG_PINCTRL */ - #endif /* ! CONFIG_GENERIC_GPIO */ #endif /* __LINUX_GPIO_H */ -- cgit v1.2.3 From f4f8e5635f398645d614dff5a07598651faf3ead Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Sat, 27 Oct 2012 15:21:38 +0530 Subject: pinctrl: SPEAr: Add gpio ranges support Most of SPEAr SoCs, which support pinctrl, can configure & use pads as gpio. This patch gpio enable support for SPEAr pinctrl drivers. Signed-off-by: Viresh Kumar Acked-by: Linus Walleij Signed-off-by: Linus Walleij --- drivers/pinctrl/spear/Kconfig | 4 + drivers/pinctrl/spear/pinctrl-spear.c | 107 ++++++++++-- drivers/pinctrl/spear/pinctrl-spear.h | 46 ++++++ drivers/pinctrl/spear/pinctrl-spear1310.c | 264 ++++++++++++++++++++++++++++++ drivers/pinctrl/spear/pinctrl-spear300.c | 2 + drivers/pinctrl/spear/pinctrl-spear310.c | 2 + drivers/pinctrl/spear/pinctrl-spear320.c | 2 + drivers/pinctrl/spear/pinctrl-spear3xx.c | 37 +++++ 8 files changed, 447 insertions(+), 17 deletions(-) diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig index 6f9a1e8bf57..04d93e60267 100644 --- a/drivers/pinctrl/spear/Kconfig +++ b/drivers/pinctrl/spear/Kconfig @@ -25,21 +25,25 @@ config PINCTRL_SPEAR310 bool "ST Microelectronics SPEAr310 SoC pin controller driver" depends on MACH_SPEAR310 select PINCTRL_SPEAR3XX + select PINCTRL_SPEAR_PLGPIO config PINCTRL_SPEAR320 bool "ST Microelectronics SPEAr320 SoC pin controller driver" depends on MACH_SPEAR320 select PINCTRL_SPEAR3XX + select PINCTRL_SPEAR_PLGPIO config PINCTRL_SPEAR1310 bool "ST Microelectronics SPEAr1310 SoC pin controller driver" depends on MACH_SPEAR1310 select PINCTRL_SPEAR + select PINCTRL_SPEAR_PLGPIO config PINCTRL_SPEAR1340 bool "ST Microelectronics SPEAr1340 SoC pin controller driver" depends on MACH_SPEAR1340 select PINCTRL_SPEAR + select PINCTRL_SPEAR_PLGPIO config PINCTRL_SPEAR_PLGPIO bool "SPEAr SoC PLGPIO Controller" diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index b1fd6ee33c6..cbca6dc66eb 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,28 @@ static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg) writel_relaxed(val, pmx->vbase + reg); } +static void muxregs_endisable(struct spear_pmx *pmx, + struct spear_muxreg *muxregs, u8 count, bool enable) +{ + struct spear_muxreg *muxreg; + u32 val, temp, j; + + for (j = 0; j < count; j++) { + muxreg = &muxregs[j]; + + val = pmx_readl(pmx, muxreg->reg); + val &= ~muxreg->mask; + + if (enable) + temp = muxreg->val; + else + temp = ~muxreg->val; + + val |= muxreg->mask & temp; + pmx_writel(pmx, val, muxreg->reg); + } +} + static int set_mode(struct spear_pmx *pmx, int mode) { struct spear_pmx_mode *pmx_mode = NULL; @@ -70,6 +93,17 @@ static int set_mode(struct spear_pmx *pmx, int mode) return 0; } +void __devinit +pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup, + unsigned count, u16 reg) +{ + int i = 0, j = 0; + + for (; i < count; i++) + for (; j < gpio_pingroup[i].nmuxregs; j++) + gpio_pingroup[i].muxregs[j].reg = reg; +} + void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg) { struct spear_pingroup *pgroup; @@ -216,9 +250,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); const struct spear_pingroup *pgroup; const struct spear_modemux *modemux; - struct spear_muxreg *muxreg; - u32 val, temp; - int i, j; + int i; bool found = false; pgroup = pmx->machdata->groups[group]; @@ -233,20 +265,8 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, } found = true; - for (j = 0; j < modemux->nmuxregs; j++) { - muxreg = &modemux->muxregs[j]; - - val = pmx_readl(pmx, muxreg->reg); - val &= ~muxreg->mask; - - if (enable) - temp = muxreg->val; - else - temp = ~muxreg->val; - - val |= muxreg->mask & temp; - pmx_writel(pmx, val, muxreg->reg); - } + muxregs_endisable(pmx, modemux->muxregs, modemux->nmuxregs, + enable); } if (!found) { @@ -270,12 +290,65 @@ static void spear_pinctrl_disable(struct pinctrl_dev *pctldev, spear_pinctrl_endisable(pctldev, function, group, false); } +/* gpio with pinmux */ +static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx, + unsigned pin) +{ + struct spear_gpio_pingroup *gpio_pingroup; + int i = 0, j; + + if (!pmx->machdata->gpio_pingroups) + return NULL; + + for (; i < pmx->machdata->ngpio_pingroups; i++) { + gpio_pingroup = &pmx->machdata->gpio_pingroups[i]; + + for (j = 0; j < gpio_pingroup->npins; j++) { + if (gpio_pingroup->pins[j] == pin) + return gpio_pingroup; + } + } + + return ERR_PTR(-EINVAL); +} + +static int gpio_request_endisable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, unsigned offset, bool enable) +{ + struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); + struct spear_gpio_pingroup *gpio_pingroup; + + gpio_pingroup = get_gpio_pingroup(pmx, offset); + if (IS_ERR(gpio_pingroup)) + return PTR_ERR(gpio_pingroup); + + if (gpio_pingroup) + muxregs_endisable(pmx, gpio_pingroup->muxregs, + gpio_pingroup->nmuxregs, enable); + + return 0; +} + +static int gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, unsigned offset) +{ + return gpio_request_endisable(pctldev, range, offset, true); +} + +static void gpio_disable_free(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, unsigned offset) +{ + gpio_request_endisable(pctldev, range, offset, false); +} + static struct pinmux_ops spear_pinmux_ops = { .get_functions_count = spear_pinctrl_get_funcs_count, .get_function_name = spear_pinctrl_get_func_name, .get_function_groups = spear_pinctrl_get_func_groups, .enable = spear_pinctrl_enable, .disable = spear_pinctrl_disable, + .gpio_request_enable = gpio_request_enable, + .gpio_disable_free = gpio_disable_free, }; static struct pinctrl_desc spear_pinctrl_desc = { diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h index d950eb78d93..94f142c10c1 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.h +++ b/drivers/pinctrl/spear/pinctrl-spear.h @@ -12,6 +12,7 @@ #ifndef __PINMUX_SPEAR_H__ #define __PINMUX_SPEAR_H__ +#include #include #include @@ -46,6 +47,44 @@ struct spear_muxreg { u32 val; }; +struct spear_gpio_pingroup { + const unsigned *pins; + unsigned npins; + struct spear_muxreg *muxregs; + u8 nmuxregs; +}; + +/* ste: set to enable */ +#define DEFINE_MUXREG(__pins, __muxreg, __mask, __ste) \ +static struct spear_muxreg __pins##_muxregs[] = { \ + { \ + .reg = __muxreg, \ + .mask = __mask, \ + .val = __ste ? __mask : 0, \ + }, \ +} + +#define DEFINE_2_MUXREG(__pins, __muxreg1, __muxreg2, __mask, __ste1, __ste2) \ +static struct spear_muxreg __pins##_muxregs[] = { \ + { \ + .reg = __muxreg1, \ + .mask = __mask, \ + .val = __ste1 ? __mask : 0, \ + }, { \ + .reg = __muxreg2, \ + .mask = __mask, \ + .val = __ste2 ? __mask : 0, \ + }, \ +} + +#define GPIO_PINGROUP(__pins) \ + { \ + .pins = __pins, \ + .npins = ARRAY_SIZE(__pins), \ + .muxregs = __pins##_muxregs, \ + .nmuxregs = ARRAY_SIZE(__pins##_muxregs), \ + } + /** * struct spear_modemux - SPEAr mode mux configuration * @modes: mode ids supported by this group of muxregs @@ -100,6 +139,8 @@ struct spear_function { * @nfunctions: The numbmer of entries in @functions. * @groups: An array describing all pin groups the pin SoC supports. * @ngroups: The numbmer of entries in @groups. + * @gpio_pingroups: gpio pingroups + * @ngpio_pingroups: gpio pingroups count * * @modes_supported: Does SoC support modes * @mode: mode configured from probe @@ -113,6 +154,8 @@ struct spear_pinctrl_machdata { unsigned nfunctions; struct spear_pingroup **groups; unsigned ngroups; + struct spear_gpio_pingroup *gpio_pingroups; + unsigned ngpio_pingroups; bool modes_supported; u16 mode; @@ -136,6 +179,9 @@ struct spear_pmx { /* exported routines */ void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg); +void __devinit +pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup, + unsigned count, u16 reg); int __devinit spear_pinctrl_probe(struct platform_device *pdev, struct spear_pinctrl_machdata *machdata); int __devexit spear_pinctrl_remove(struct platform_device *pdev); diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c index 0436fc7895d..30134f72745 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/drivers/pinctrl/spear/pinctrl-spear1310.c @@ -2418,6 +2418,268 @@ static struct spear_function *spear1310_functions[] = { &gpt64_function, }; +static const unsigned pin18[] = { 18, }; +static const unsigned pin19[] = { 19, }; +static const unsigned pin20[] = { 20, }; +static const unsigned pin21[] = { 21, }; +static const unsigned pin22[] = { 22, }; +static const unsigned pin23[] = { 23, }; +static const unsigned pin54[] = { 54, }; +static const unsigned pin55[] = { 55, }; +static const unsigned pin56[] = { 56, }; +static const unsigned pin57[] = { 57, }; +static const unsigned pin58[] = { 58, }; +static const unsigned pin59[] = { 59, }; +static const unsigned pin60[] = { 60, }; +static const unsigned pin61[] = { 61, }; +static const unsigned pin62[] = { 62, }; +static const unsigned pin63[] = { 63, }; +static const unsigned pin143[] = { 143, }; +static const unsigned pin144[] = { 144, }; +static const unsigned pin145[] = { 145, }; +static const unsigned pin146[] = { 146, }; +static const unsigned pin147[] = { 147, }; +static const unsigned pin148[] = { 148, }; +static const unsigned pin149[] = { 149, }; +static const unsigned pin150[] = { 150, }; +static const unsigned pin151[] = { 151, }; +static const unsigned pin152[] = { 152, }; +static const unsigned pin205[] = { 205, }; +static const unsigned pin206[] = { 206, }; +static const unsigned pin211[] = { 211, }; +static const unsigned pin212[] = { 212, }; +static const unsigned pin213[] = { 213, }; +static const unsigned pin214[] = { 214, }; +static const unsigned pin215[] = { 215, }; +static const unsigned pin216[] = { 216, }; +static const unsigned pin217[] = { 217, }; +static const unsigned pin218[] = { 218, }; +static const unsigned pin219[] = { 219, }; +static const unsigned pin220[] = { 220, }; +static const unsigned pin221[] = { 221, }; +static const unsigned pin222[] = { 222, }; +static const unsigned pin223[] = { 223, }; +static const unsigned pin224[] = { 224, }; +static const unsigned pin225[] = { 225, }; +static const unsigned pin226[] = { 226, }; +static const unsigned pin227[] = { 227, }; +static const unsigned pin228[] = { 228, }; +static const unsigned pin229[] = { 229, }; +static const unsigned pin230[] = { 230, }; +static const unsigned pin231[] = { 231, }; +static const unsigned pin232[] = { 232, }; +static const unsigned pin233[] = { 233, }; +static const unsigned pin234[] = { 234, }; +static const unsigned pin235[] = { 235, }; +static const unsigned pin236[] = { 236, }; +static const unsigned pin237[] = { 237, }; +static const unsigned pin238[] = { 238, }; +static const unsigned pin239[] = { 239, }; +static const unsigned pin240[] = { 240, }; +static const unsigned pin241[] = { 241, }; +static const unsigned pin242[] = { 242, }; +static const unsigned pin243[] = { 243, }; +static const unsigned pin244[] = { 244, }; +static const unsigned pin245[] = { 245, }; + +static const unsigned pin_grp0[] = { 173, 174, }; +static const unsigned pin_grp1[] = { 175, 185, 188, 197, 198, }; +static const unsigned pin_grp2[] = { 176, 177, 178, 179, 184, 186, 187, 189, + 190, 191, 192, }; +static const unsigned pin_grp3[] = { 180, 181, 182, 183, 193, 194, 195, 196, }; +static const unsigned pin_grp4[] = { 199, 200, }; +static const unsigned pin_grp5[] = { 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, }; +static const unsigned pin_grp6[] = { 86, 87, 88, 89, 90, 91, 92, 93, }; +static const unsigned pin_grp7[] = { 98, 99, }; +static const unsigned pin_grp8[] = { 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 172, }; + +/* Define muxreg arrays */ +DEFINE_2_MUXREG(i2c0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_I2C0_MASK, 0, 1); +DEFINE_2_MUXREG(ssp0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_SSP0_MASK, 0, 1); +DEFINE_2_MUXREG(ssp0_cs0_pins, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_SSP0_CS0_MASK, 0, 1); +DEFINE_2_MUXREG(ssp0_cs1_2_pins, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_SSP0_CS1_2_MASK, 0, 1); +DEFINE_2_MUXREG(i2s0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_I2S0_MASK, 0, 1); +DEFINE_2_MUXREG(i2s1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_I2S1_MASK, 0, 1); +DEFINE_2_MUXREG(clcd_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_CLCD1_MASK, 0, 1); +DEFINE_2_MUXREG(clcd_high_res_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_CLCD2_MASK, 0, 1); +DEFINE_2_MUXREG(pin18, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO15_MASK, 0, 1); +DEFINE_2_MUXREG(pin19, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO14_MASK, 0, 1); +DEFINE_2_MUXREG(pin20, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO13_MASK, 0, 1); +DEFINE_2_MUXREG(pin21, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO12_MASK, 0, 1); +DEFINE_2_MUXREG(pin22, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO11_MASK, 0, 1); +DEFINE_2_MUXREG(pin23, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO10_MASK, 0, 1); +DEFINE_2_MUXREG(pin143, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO00_MASK, 0, 1); +DEFINE_2_MUXREG(pin144, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO01_MASK, 0, 1); +DEFINE_2_MUXREG(pin145, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO02_MASK, 0, 1); +DEFINE_2_MUXREG(pin146, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO03_MASK, 0, 1); +DEFINE_2_MUXREG(pin147, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO04_MASK, 0, 1); +DEFINE_2_MUXREG(pin148, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO05_MASK, 0, 1); +DEFINE_2_MUXREG(pin149, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO06_MASK, 0, 1); +DEFINE_2_MUXREG(pin150, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO07_MASK, 0, 1); +DEFINE_2_MUXREG(pin151, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO08_MASK, 0, 1); +DEFINE_2_MUXREG(pin152, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO09_MASK, 0, 1); +DEFINE_2_MUXREG(smi_2_chips_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_SMI_MASK, 0, 1); +DEFINE_2_MUXREG(pin54, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_SMINCS3_MASK, 0, 1); +DEFINE_2_MUXREG(pin55, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_SMINCS2_MASK, 0, 1); +DEFINE_2_MUXREG(pin56, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NFRSTPWDWN3_MASK, 0, 1); +DEFINE_2_MUXREG(pin57, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN2_MASK, 0, 1); +DEFINE_2_MUXREG(pin58, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN1_MASK, 0, 1); +DEFINE_2_MUXREG(pin59, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN0_MASK, 0, 1); +DEFINE_2_MUXREG(pin60, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFWPRT3_MASK, 0, 1); +DEFINE_2_MUXREG(pin61, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFCE3_MASK, 0, 1); +DEFINE_2_MUXREG(pin62, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD25_MASK, 0, 1); +DEFINE_2_MUXREG(pin63, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD24_MASK, 0, 1); +DEFINE_2_MUXREG(pin_grp0, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIICLK_MASK, 0, 1); +DEFINE_2_MUXREG(pin_grp1, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK, 0, 1); +DEFINE_2_MUXREG(pin_grp2, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_RXCLK_RDV_TXEN_D03_MASK, 0, 1); +DEFINE_2_MUXREG(pin_grp3, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIID47_MASK, 0, 1); +DEFINE_2_MUXREG(pin_grp4, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_MDC_MDIO_MASK, 0, 1); +DEFINE_2_MUXREG(pin_grp5, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD23_MASK, 0, 1); +DEFINE_2_MUXREG(pin_grp6, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_MCI_DATA8_15_MASK, 0, 1); +DEFINE_2_MUXREG(pin_grp7, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NFCE2_MASK, 0, 1); +DEFINE_2_MUXREG(pin_grp8, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NAND8_MASK, 0, 1); +DEFINE_2_MUXREG(nand_16bit_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NAND16BIT_1_MASK, 0, 1); +DEFINE_2_MUXREG(pin205, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_COL1_MASK | PMX_NFCE1_MASK, 0, 1); +DEFINE_2_MUXREG(pin206, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_COL0_MASK | PMX_NFCE2_MASK, 0, 1); +DEFINE_2_MUXREG(pin211, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROW1_MASK | PMX_NFWPRT1_MASK, 0, 1); +DEFINE_2_MUXREG(pin212, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROW0_MASK | PMX_NFWPRT2_MASK, 0, 1); +DEFINE_2_MUXREG(pin213, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA0_MASK, 0, 1); +DEFINE_2_MUXREG(pin214, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA1_MASK, 0, 1); +DEFINE_2_MUXREG(pin215, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA2_MASK, 0, 1); +DEFINE_2_MUXREG(pin216, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA3_MASK, 0, 1); +DEFINE_2_MUXREG(pin217, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA4_MASK, 0, 1); +DEFINE_2_MUXREG(pin218, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA5_MASK, 0, 1); +DEFINE_2_MUXREG(pin219, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA6_MASK, 0, 1); +DEFINE_2_MUXREG(pin220, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA7_MASK, 0, 1); +DEFINE_2_MUXREG(pin221, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA1SD_MASK, 0, 1); +DEFINE_2_MUXREG(pin222, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA2SD_MASK, 0, 1); +DEFINE_2_MUXREG(pin223, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA3SD_MASK, 0, 1); +DEFINE_2_MUXREG(pin224, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR0ALE_MASK, 0, 1); +DEFINE_2_MUXREG(pin225, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR1CLECLK_MASK, 0, 1); +DEFINE_2_MUXREG(pin226, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR2_MASK, 0, 1); +DEFINE_2_MUXREG(pin227, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICECF_MASK, 0, 1); +DEFINE_2_MUXREG(pin228, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICEXD_MASK, 0, 1); +DEFINE_2_MUXREG(pin229, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICESDMMC_MASK, 0, 1); +DEFINE_2_MUXREG(pin230, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDCF1_MASK, 0, 1); +DEFINE_2_MUXREG(pin231, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDCF2_MASK, 0, 1); +DEFINE_2_MUXREG(pin232, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDXD_MASK, 0, 1); +DEFINE_2_MUXREG(pin233, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDSDMMC_MASK, 0, 1); +DEFINE_2_MUXREG(pin234, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATADIR_MASK, 0, 1); +DEFINE_2_MUXREG(pin235, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDMARQWP_MASK, 0, 1); +DEFINE_2_MUXREG(pin236, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIORDRE_MASK, 0, 1); +DEFINE_2_MUXREG(pin237, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIOWRWE_MASK, 0, 1); +DEFINE_2_MUXREG(pin238, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIRESETCF_MASK, 0, 1); +DEFINE_2_MUXREG(pin239, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICS0CE_MASK, 0, 1); +DEFINE_2_MUXREG(pin240, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICFINTR_MASK, 0, 1); +DEFINE_2_MUXREG(pin241, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIORDY_MASK, 0, 1); +DEFINE_2_MUXREG(pin242, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICS1_MASK, 0, 1); +DEFINE_2_MUXREG(pin243, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDMAACK_MASK, 0, 1); +DEFINE_2_MUXREG(pin244, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCISDCMD_MASK, 0, 1); +DEFINE_2_MUXREG(pin245, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCILEDS_MASK, 0, 1); +DEFINE_2_MUXREG(keyboard_rowcol6_8_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROWCOL68_MASK, 0, 1); +DEFINE_2_MUXREG(uart0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_UART0_MASK, 0, 1); +DEFINE_2_MUXREG(uart0_modem_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_UART0_MODEM_MASK, 0, 1); +DEFINE_2_MUXREG(gpt0_tmr0_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT0_TMR0_MASK, 0, 1); +DEFINE_2_MUXREG(gpt0_tmr1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT0_TMR1_MASK, 0, 1); +DEFINE_2_MUXREG(gpt1_tmr0_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT1_TMR0_MASK, 0, 1); +DEFINE_2_MUXREG(gpt1_tmr1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT1_TMR1_MASK, 0, 1); +DEFINE_2_MUXREG(touch_xy_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_TOUCH_XY_MASK, 0, 1); + +static struct spear_gpio_pingroup spear1310_gpio_pingroup[] = { + GPIO_PINGROUP(i2c0_pins), + GPIO_PINGROUP(ssp0_pins), + GPIO_PINGROUP(ssp0_cs0_pins), + GPIO_PINGROUP(ssp0_cs1_2_pins), + GPIO_PINGROUP(i2s0_pins), + GPIO_PINGROUP(i2s1_pins), + GPIO_PINGROUP(clcd_pins), + GPIO_PINGROUP(clcd_high_res_pins), + GPIO_PINGROUP(pin18), + GPIO_PINGROUP(pin19), + GPIO_PINGROUP(pin20), + GPIO_PINGROUP(pin21), + GPIO_PINGROUP(pin22), + GPIO_PINGROUP(pin23), + GPIO_PINGROUP(pin143), + GPIO_PINGROUP(pin144), + GPIO_PINGROUP(pin145), + GPIO_PINGROUP(pin146), + GPIO_PINGROUP(pin147), + GPIO_PINGROUP(pin148), + GPIO_PINGROUP(pin149), + GPIO_PINGROUP(pin150), + GPIO_PINGROUP(pin151), + GPIO_PINGROUP(pin152), + GPIO_PINGROUP(smi_2_chips_pins), + GPIO_PINGROUP(pin54), + GPIO_PINGROUP(pin55), + GPIO_PINGROUP(pin56), + GPIO_PINGROUP(pin57), + GPIO_PINGROUP(pin58), + GPIO_PINGROUP(pin59), + GPIO_PINGROUP(pin60), + GPIO_PINGROUP(pin61), + GPIO_PINGROUP(pin62), + GPIO_PINGROUP(pin63), + GPIO_PINGROUP(pin_grp0), + GPIO_PINGROUP(pin_grp1), + GPIO_PINGROUP(pin_grp2), + GPIO_PINGROUP(pin_grp3), + GPIO_PINGROUP(pin_grp4), + GPIO_PINGROUP(pin_grp5), + GPIO_PINGROUP(pin_grp6), + GPIO_PINGROUP(pin_grp7), + GPIO_PINGROUP(pin_grp8), + GPIO_PINGROUP(nand_16bit_pins), + GPIO_PINGROUP(pin205), + GPIO_PINGROUP(pin206), + GPIO_PINGROUP(pin211), + GPIO_PINGROUP(pin212), + GPIO_PINGROUP(pin213), + GPIO_PINGROUP(pin214), + GPIO_PINGROUP(pin215), + GPIO_PINGROUP(pin216), + GPIO_PINGROUP(pin217), + GPIO_PINGROUP(pin218), + GPIO_PINGROUP(pin219), + GPIO_PINGROUP(pin220), + GPIO_PINGROUP(pin221), + GPIO_PINGROUP(pin222), + GPIO_PINGROUP(pin223), + GPIO_PINGROUP(pin224), + GPIO_PINGROUP(pin225), + GPIO_PINGROUP(pin226), + GPIO_PINGROUP(pin227), + GPIO_PINGROUP(pin228), + GPIO_PINGROUP(pin229), + GPIO_PINGROUP(pin230), + GPIO_PINGROUP(pin231), + GPIO_PINGROUP(pin232), + GPIO_PINGROUP(pin233), + GPIO_PINGROUP(pin234), + GPIO_PINGROUP(pin235), + GPIO_PINGROUP(pin236), + GPIO_PINGROUP(pin237), + GPIO_PINGROUP(pin238), + GPIO_PINGROUP(pin239), + GPIO_PINGROUP(pin240), + GPIO_PINGROUP(pin241), + GPIO_PINGROUP(pin242), + GPIO_PINGROUP(pin243), + GPIO_PINGROUP(pin244), + GPIO_PINGROUP(pin245), + GPIO_PINGROUP(keyboard_rowcol6_8_pins), + GPIO_PINGROUP(uart0_pins), + GPIO_PINGROUP(uart0_modem_pins), + GPIO_PINGROUP(gpt0_tmr0_pins), + GPIO_PINGROUP(gpt0_tmr1_pins), + GPIO_PINGROUP(gpt1_tmr0_pins), + GPIO_PINGROUP(gpt1_tmr1_pins), + GPIO_PINGROUP(touch_xy_pins), +}; + static struct spear_pinctrl_machdata spear1310_machdata = { .pins = spear1310_pins, .npins = ARRAY_SIZE(spear1310_pins), @@ -2425,6 +2687,8 @@ static struct spear_pinctrl_machdata spear1310_machdata = { .ngroups = ARRAY_SIZE(spear1310_pingroups), .functions = spear1310_functions, .nfunctions = ARRAY_SIZE(spear1310_functions), + .gpio_pingroups = spear1310_gpio_pingroup, + .ngpio_pingroups = ARRAY_SIZE(spear1310_gpio_pingroup), .modes_supported = false, }; diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c index 4dfc2849b17..9a491007f42 100644 --- a/drivers/pinctrl/spear/pinctrl-spear300.c +++ b/drivers/pinctrl/spear/pinctrl-spear300.c @@ -661,6 +661,8 @@ static int __devinit spear300_pinctrl_probe(struct platform_device *pdev) spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups); spear3xx_machdata.functions = spear300_functions; spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions); + spear3xx_machdata.gpio_pingroups = NULL; + spear3xx_machdata.ngpio_pingroups = 0; spear3xx_machdata.modes_supported = true; spear3xx_machdata.pmx_modes = spear300_pmx_modes; diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c index 96883693fb7..4d5dfe9c760 100644 --- a/drivers/pinctrl/spear/pinctrl-spear310.c +++ b/drivers/pinctrl/spear/pinctrl-spear310.c @@ -388,6 +388,8 @@ static int __devinit spear310_pinctrl_probe(struct platform_device *pdev) spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions); pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); + pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups, + spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG); spear3xx_machdata.modes_supported = false; diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c index ca47b0e5078..c996e26e3b6 100644 --- a/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/drivers/pinctrl/spear/pinctrl-spear320.c @@ -3431,6 +3431,8 @@ static int __devinit spear320_pinctrl_probe(struct platform_device *pdev) spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear320_pmx_modes); pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); + pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups, + spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG); ret = spear_pinctrl_probe(pdev, &spear3xx_machdata); if (ret) diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c index 0242378f7cb..12ee21af766 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.c +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c @@ -481,7 +481,44 @@ struct spear_function spear3xx_timer_2_3_function = { .ngroups = ARRAY_SIZE(timer_2_3_grps), }; +/* Define muxreg arrays */ +DEFINE_MUXREG(firda_pins, 0, PMX_FIRDA_MASK, 0); +DEFINE_MUXREG(i2c_pins, 0, PMX_I2C_MASK, 0); +DEFINE_MUXREG(ssp_cs_pins, 0, PMX_SSP_CS_MASK, 0); +DEFINE_MUXREG(ssp_pins, 0, PMX_SSP_MASK, 0); +DEFINE_MUXREG(mii_pins, 0, PMX_MII_MASK, 0); +DEFINE_MUXREG(gpio0_pin0_pins, 0, PMX_GPIO_PIN0_MASK, 0); +DEFINE_MUXREG(gpio0_pin1_pins, 0, PMX_GPIO_PIN1_MASK, 0); +DEFINE_MUXREG(gpio0_pin2_pins, 0, PMX_GPIO_PIN2_MASK, 0); +DEFINE_MUXREG(gpio0_pin3_pins, 0, PMX_GPIO_PIN3_MASK, 0); +DEFINE_MUXREG(gpio0_pin4_pins, 0, PMX_GPIO_PIN4_MASK, 0); +DEFINE_MUXREG(gpio0_pin5_pins, 0, PMX_GPIO_PIN5_MASK, 0); +DEFINE_MUXREG(uart0_ext_pins, 0, PMX_UART0_MODEM_MASK, 0); +DEFINE_MUXREG(uart0_pins, 0, PMX_UART0_MASK, 0); +DEFINE_MUXREG(timer_0_1_pins, 0, PMX_TIMER_0_1_MASK, 0); +DEFINE_MUXREG(timer_2_3_pins, 0, PMX_TIMER_2_3_MASK, 0); + +static struct spear_gpio_pingroup spear3xx_gpio_pingroup[] = { + GPIO_PINGROUP(firda_pins), + GPIO_PINGROUP(i2c_pins), + GPIO_PINGROUP(ssp_cs_pins), + GPIO_PINGROUP(ssp_pins), + GPIO_PINGROUP(mii_pins), + GPIO_PINGROUP(gpio0_pin0_pins), + GPIO_PINGROUP(gpio0_pin1_pins), + GPIO_PINGROUP(gpio0_pin2_pins), + GPIO_PINGROUP(gpio0_pin3_pins), + GPIO_PINGROUP(gpio0_pin4_pins), + GPIO_PINGROUP(gpio0_pin5_pins), + GPIO_PINGROUP(uart0_ext_pins), + GPIO_PINGROUP(uart0_pins), + GPIO_PINGROUP(timer_0_1_pins), + GPIO_PINGROUP(timer_2_3_pins), +}; + struct spear_pinctrl_machdata spear3xx_machdata = { .pins = spear3xx_pins, .npins = ARRAY_SIZE(spear3xx_pins), + .gpio_pingroups = spear3xx_gpio_pingroup, + .ngpio_pingroups = ARRAY_SIZE(spear3xx_gpio_pingroup), }; -- cgit v1.2.3 From 4ddb1c295752252f61670e35c791bf16e58bbce6 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Sat, 27 Oct 2012 15:21:39 +0530 Subject: ARM: SPEAr: Add plgpio node in device tree dtsi files This patch adds plgpio nodes in SPEAr DT files. Signed-off-by: Viresh Kumar Signed-off-by: Linus Walleij --- arch/arm/boot/dts/spear1310-evb.dts | 4 ++++ arch/arm/boot/dts/spear1310.dtsi | 27 +++++++++++++++++++++++++++ arch/arm/boot/dts/spear1340-evb.dts | 4 ++++ arch/arm/boot/dts/spear1340.dtsi | 26 ++++++++++++++++++++++++++ arch/arm/boot/dts/spear310.dtsi | 22 +++++++++++++++++++++- arch/arm/boot/dts/spear320-evb.dts | 4 ++++ arch/arm/boot/dts/spear320.dtsi | 23 ++++++++++++++++++++++- 7 files changed, 108 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts index dd4358bc26e..2e4c5727468 100644 --- a/arch/arm/boot/dts/spear1310-evb.dts +++ b/arch/arm/boot/dts/spear1310-evb.dts @@ -181,6 +181,10 @@ status = "okay"; }; + gpio@d8400000 { + status = "okay"; + }; + i2c0: i2c@e0280000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi index 419ea7413d2..7cd25eb4f8e 100644 --- a/arch/arm/boot/dts/spear1310.dtsi +++ b/arch/arm/boot/dts/spear1310.dtsi @@ -70,6 +70,12 @@ status = "disabled"; }; + pinmux: pinmux@e0700000 { + compatible = "st,spear1310-pinmux"; + reg = <0xe0700000 0x1000>; + #gpio-range-cells = <2>; + }; + spi1: spi@5d400000 { compatible = "arm,pl022", "arm,primecell"; reg = <0x5d400000 0x1000>; @@ -179,6 +185,27 @@ thermal@e07008c4 { st,thermal-flags = <0x7000>; }; + + gpiopinctrl: gpio@d8400000 { + compatible = "st,spear-plgpio"; + reg = <0xd8400000 0x1000>; + interrupts = <0 100 0x4>; + #interrupt-cells = <1>; + interrupt-controller; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinmux 0 246>; + status = "disabled"; + + st-plgpio,ngpio = <246>; + st-plgpio,enb-reg = <0xd0>; + st-plgpio,wdata-reg = <0x90>; + st-plgpio,dir-reg = <0xb0>; + st-plgpio,ie-reg = <0x30>; + st-plgpio,rdata-reg = <0x70>; + st-plgpio,mis-reg = <0x10>; + st-plgpio,eit-reg = <0x50>; + }; }; }; }; diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts index c9a54e06fb6..045f7123ffa 100644 --- a/arch/arm/boot/dts/spear1340-evb.dts +++ b/arch/arm/boot/dts/spear1340-evb.dts @@ -193,6 +193,10 @@ status = "okay"; }; + gpio@e2800000 { + status = "okay"; + }; + i2c0: i2c@e0280000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi index d71fe2a68f0..6c09eb0a1b2 100644 --- a/arch/arm/boot/dts/spear1340.dtsi +++ b/arch/arm/boot/dts/spear1340.dtsi @@ -24,6 +24,12 @@ status = "disabled"; }; + pinmux: pinmux@e0700000 { + compatible = "st,spear1340-pinmux"; + reg = <0xe0700000 0x1000>; + #gpio-range-cells = <2>; + }; + spi1: spi@5d400000 { compatible = "arm,pl022", "arm,primecell"; reg = <0x5d400000 0x1000>; @@ -51,6 +57,26 @@ thermal@e07008c4 { st,thermal-flags = <0x2a00>; }; + + gpiopinctrl: gpio@e2800000 { + compatible = "st,spear-plgpio"; + reg = <0xe2800000 0x1000>; + interrupts = <0 107 0x4>; + #interrupt-cells = <1>; + interrupt-controller; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinmux 0 252>; + status = "disabled"; + + st-plgpio,ngpio = <250>; + st-plgpio,wdata-reg = <0x40>; + st-plgpio,dir-reg = <0x00>; + st-plgpio,ie-reg = <0x80>; + st-plgpio,rdata-reg = <0x20>; + st-plgpio,mis-reg = <0xa0>; + st-plgpio,eit-reg = <0x60>; + }; }; }; }; diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi index 62fc4fb3e5f..930303e48df 100644 --- a/arch/arm/boot/dts/spear310.dtsi +++ b/arch/arm/boot/dts/spear310.dtsi @@ -22,9 +22,10 @@ 0xb0000000 0xb0000000 0x10000000 0xd0000000 0xd0000000 0x30000000>; - pinmux@b4000000 { + pinmux: pinmux@b4000000 { compatible = "st,spear310-pinmux"; reg = <0xb4000000 0x1000>; + #gpio-range-cells = <2>; }; fsmc: flash@44000000 { @@ -75,6 +76,25 @@ reg = <0xb2200000 0x1000>; status = "disabled"; }; + + gpiopinctrl: gpio@b4000000 { + compatible = "st,spear-plgpio"; + reg = <0xb4000000 0x1000>; + #interrupt-cells = <1>; + interrupt-controller; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinmux 0 102>; + status = "disabled"; + + st-plgpio,ngpio = <102>; + st-plgpio,enb-reg = <0x10>; + st-plgpio,wdata-reg = <0x20>; + st-plgpio,dir-reg = <0x30>; + st-plgpio,ie-reg = <0x50>; + st-plgpio,rdata-reg = <0x40>; + st-plgpio,mis-reg = <0x60>; + }; }; }; }; diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts index 082328bd64a..ad4bfc68ee0 100644 --- a/arch/arm/boot/dts/spear320-evb.dts +++ b/arch/arm/boot/dts/spear320-evb.dts @@ -164,6 +164,10 @@ status = "okay"; }; + gpio@b3000000 { + status = "okay"; + }; + i2c0: i2c@d0180000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi index 1f49d69595a..67d7ada7127 100644 --- a/arch/arm/boot/dts/spear320.dtsi +++ b/arch/arm/boot/dts/spear320.dtsi @@ -21,9 +21,10 @@ ranges = <0x40000000 0x40000000 0x80000000 0xd0000000 0xd0000000 0x30000000>; - pinmux@b3000000 { + pinmux: pinmux@b3000000 { compatible = "st,spear320-pinmux"; reg = <0xb3000000 0x1000>; + #gpio-range-cells = <2>; }; clcd@90000000 { @@ -90,6 +91,26 @@ reg = <0xa4000000 0x1000>; status = "disabled"; }; + + gpiopinctrl: gpio@b3000000 { + compatible = "st,spear-plgpio"; + reg = <0xb3000000 0x1000>; + #interrupt-cells = <1>; + interrupt-controller; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinmux 0 102>; + status = "disabled"; + + st-plgpio,ngpio = <102>; + st-plgpio,enb-reg = <0x24>; + st-plgpio,wdata-reg = <0x34>; + st-plgpio,dir-reg = <0x44>; + st-plgpio,ie-reg = <0x64>; + st-plgpio,rdata-reg = <0x54>; + st-plgpio,mis-reg = <0x84>; + st-plgpio,eit-reg = <0x94>; + }; }; }; }; -- cgit v1.2.3 From 6bb0700bfe124f3ee245da24b5bb35152d2e6bfc Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 7 Nov 2012 13:37:08 +0800 Subject: pinctrl: Staticize pinconf_ops They are not referenced outside respective driver. Signed-off-by: Axel Lin Cc: Jean-Christophe PLAGNIOL-VILLARD Cc: Simon Arlott Cc: John Crispin Cc: Shawn Guo Cc: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-at91.c | 2 +- drivers/pinctrl/pinctrl-bcm2835.c | 2 +- drivers/pinctrl/pinctrl-falcon.c | 2 +- drivers/pinctrl/pinctrl-imx.c | 2 +- drivers/pinctrl/pinctrl-mxs.c | 2 +- drivers/pinctrl/pinctrl-tegra.c | 2 +- drivers/pinctrl/pinctrl-xway.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index b9e2cbd2ea7..8490a5553ec 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -665,7 +665,7 @@ static void at91_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, { } -struct pinconf_ops at91_pinconf_ops = { +static struct pinconf_ops at91_pinconf_ops = { .pin_config_get = at91_pinconf_get, .pin_config_set = at91_pinconf_set, .pin_config_dbg_show = at91_pinconf_dbg_show, diff --git a/drivers/pinctrl/pinctrl-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c index 7e9be18ec2d..9a963edd66d 100644 --- a/drivers/pinctrl/pinctrl-bcm2835.c +++ b/drivers/pinctrl/pinctrl-bcm2835.c @@ -916,7 +916,7 @@ static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev, return 0; } -struct pinconf_ops bcm2835_pinconf_ops = { +static struct pinconf_ops bcm2835_pinconf_ops = { .pin_config_get = bcm2835_pinconf_get, .pin_config_set = bcm2835_pinconf_set, }; diff --git a/drivers/pinctrl/pinctrl-falcon.c b/drivers/pinctrl/pinctrl-falcon.c index ee730590347..8ed20e84cb0 100644 --- a/drivers/pinctrl/pinctrl-falcon.c +++ b/drivers/pinctrl/pinctrl-falcon.c @@ -322,7 +322,7 @@ static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev, { } -struct pinconf_ops falcon_pinconf_ops = { +static struct pinconf_ops falcon_pinconf_ops = { .pin_config_get = falcon_pinconf_get, .pin_config_set = falcon_pinconf_set, .pin_config_group_get = falcon_pinconf_group_get, diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c index 63866d95357..f3d2384b34b 100644 --- a/drivers/pinctrl/pinctrl-imx.c +++ b/drivers/pinctrl/pinctrl-imx.c @@ -397,7 +397,7 @@ static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, } } -struct pinconf_ops imx_pinconf_ops = { +static struct pinconf_ops imx_pinconf_ops = { .pin_config_get = imx_pinconf_get, .pin_config_set = imx_pinconf_set, .pin_config_dbg_show = imx_pinconf_dbg_show, diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c index 4ba4636b6a4..3e7d4d63f8b 100644 --- a/drivers/pinctrl/pinctrl-mxs.c +++ b/drivers/pinctrl/pinctrl-mxs.c @@ -319,7 +319,7 @@ static void mxs_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, seq_printf(s, "0x%lx", config); } -struct pinconf_ops mxs_pinconf_ops = { +static struct pinconf_ops mxs_pinconf_ops = { .pin_config_get = mxs_pinconf_get, .pin_config_set = mxs_pinconf_set, .pin_config_group_get = mxs_pinconf_group_get, diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c index 7da0b371fd6..f7fe91ebd8d 100644 --- a/drivers/pinctrl/pinctrl-tegra.c +++ b/drivers/pinctrl/pinctrl-tegra.c @@ -660,7 +660,7 @@ static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev, } #endif -struct pinconf_ops tegra_pinconf_ops = { +static struct pinconf_ops tegra_pinconf_ops = { .pin_config_get = tegra_pinconf_get, .pin_config_set = tegra_pinconf_set, .pin_config_group_get = tegra_pinconf_group_get, diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c index b9bcaec6622..ad90984ec50 100644 --- a/drivers/pinctrl/pinctrl-xway.c +++ b/drivers/pinctrl/pinctrl-xway.c @@ -522,7 +522,7 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev, return 0; } -struct pinconf_ops xway_pinconf_ops = { +static struct pinconf_ops xway_pinconf_ops = { .pin_config_get = xway_pinconf_get, .pin_config_set = xway_pinconf_set, }; -- cgit v1.2.3 From 826d6ca8f955c7a902e775acef3bdbfc93695b04 Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Wed, 7 Nov 2012 20:07:25 +0530 Subject: pinctrl: SPEAr: Add SoC specific gpio configuration routines Different SPEAr SoCs have different approach to configure pins as gpios. Some configure a group of gpios with single register bit and others have one bit per gpio pin. Only earlier one is implemented till now, this patch adds support for later one. Here we add callbacks to SoC specific code to configure gpios in gpio_request_enable(). That will do additional SoC specific configuration to enable gpio pins. We also implement this callback for SPEAr1340 in this patch. Signed-off-by: Shiraz Hashim Signed-off-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/pinctrl/spear/pinctrl-spear.c | 26 ++++++++++++-------------- drivers/pinctrl/spear/pinctrl-spear.h | 14 ++++++++++++++ drivers/pinctrl/spear/pinctrl-spear1340.c | 27 +++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index cbca6dc66eb..f9483ae4272 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include @@ -29,16 +28,6 @@ #define DRIVER_NAME "spear-pinmux" -static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg) -{ - return readl_relaxed(pmx->vbase + reg); -} - -static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg) -{ - writel_relaxed(val, pmx->vbase + reg); -} - static void muxregs_endisable(struct spear_pmx *pmx, struct spear_muxreg *muxregs, u8 count, bool enable) { @@ -316,16 +305,25 @@ static int gpio_request_endisable(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset, bool enable) { struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); + struct spear_pinctrl_machdata *machdata = pmx->machdata; struct spear_gpio_pingroup *gpio_pingroup; + /* + * Some SoC have configuration options applicable to group of pins, + * rather than a single pin. + */ gpio_pingroup = get_gpio_pingroup(pmx, offset); - if (IS_ERR(gpio_pingroup)) - return PTR_ERR(gpio_pingroup); - if (gpio_pingroup) muxregs_endisable(pmx, gpio_pingroup->muxregs, gpio_pingroup->nmuxregs, enable); + /* + * SoC may need some extra configurations, or configurations for single + * pin + */ + if (machdata->gpio_request_endisable) + machdata->gpio_request_endisable(pmx, offset, enable); + return 0; } diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h index 94f142c10c1..b06332719b2 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.h +++ b/drivers/pinctrl/spear/pinctrl-spear.h @@ -13,11 +13,13 @@ #define __PINMUX_SPEAR_H__ #include +#include #include #include struct platform_device; struct device; +struct spear_pmx; /** * struct spear_pmx_mode - SPEAr pmx mode @@ -155,6 +157,8 @@ struct spear_pinctrl_machdata { struct spear_pingroup **groups; unsigned ngroups; struct spear_gpio_pingroup *gpio_pingroups; + void (*gpio_request_endisable)(struct spear_pmx *pmx, int offset, + bool enable); unsigned ngpio_pingroups; bool modes_supported; @@ -178,6 +182,16 @@ struct spear_pmx { }; /* exported routines */ +static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg) +{ + return readl_relaxed(pmx->vbase + reg); +} + +static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg) +{ + writel_relaxed(val, pmx->vbase + reg); +} + void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg); void __devinit pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup, diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c index 0606b8cf3f2..0b4af0e5cdc 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/drivers/pinctrl/spear/pinctrl-spear1340.c @@ -1971,6 +1971,32 @@ static struct spear_function *spear1340_functions[] = { &sata_function, }; +static void gpio_request_endisable(struct spear_pmx *pmx, int pin, + bool enable) +{ + unsigned int regoffset, regindex, bitoffset; + unsigned int val; + + /* pin++ as gpio configuration starts from 2nd bit of base register */ + pin++; + + regindex = pin / 32; + bitoffset = pin % 32; + + if (regindex <= 3) + regoffset = PAD_FUNCTION_EN_1 + regindex * sizeof(int *); + else + regoffset = PAD_FUNCTION_EN_5 + (regindex - 4) * sizeof(int *); + + val = pmx_readl(pmx, regoffset); + if (enable) + val &= ~(0x1 << bitoffset); + else + val |= 0x1 << bitoffset; + + pmx_writel(pmx, val, regoffset); +} + static struct spear_pinctrl_machdata spear1340_machdata = { .pins = spear1340_pins, .npins = ARRAY_SIZE(spear1340_pins), @@ -1978,6 +2004,7 @@ static struct spear_pinctrl_machdata spear1340_machdata = { .ngroups = ARRAY_SIZE(spear1340_pingroups), .functions = spear1340_functions, .nfunctions = ARRAY_SIZE(spear1340_functions), + .gpio_request_endisable = gpio_request_endisable, .modes_supported = false, }; -- cgit v1.2.3 From 5c084ec82015553ab8972cd251fc2e5757e4a379 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 7 Nov 2012 23:57:59 +0800 Subject: pinctrl: lantiq: Remove ltq_pmx_disable() function Current code adds empty ltq_pmx_disable() because pinmux_check_ops() requires this callback to be defined. This is not required since commit 02b50ce4cb1 "pinctrl: make pinmux disable function optional". Thus remove ltq_pmx_disable() function. Signed-off-by: Axel Lin Acked-by: John Crispin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-lantiq.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c index 07ba7682cf2..d670ad6e6e4 100644 --- a/drivers/pinctrl/pinctrl-lantiq.c +++ b/drivers/pinctrl/pinctrl-lantiq.c @@ -275,16 +275,6 @@ static int ltq_pmx_enable(struct pinctrl_dev *pctrldev, return 0; } -static void ltq_pmx_disable(struct pinctrl_dev *pctrldev, - unsigned func, - unsigned group) -{ - /* - * Nothing to do here. However, pinconf_check_ops() requires this - * callback to be defined. - */ -} - static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev, struct pinctrl_gpio_range *range, unsigned pin) @@ -312,7 +302,6 @@ static struct pinmux_ops ltq_pmx_ops = { .get_function_name = ltq_pmx_func_name, .get_function_groups = ltq_pmx_get_groups, .enable = ltq_pmx_enable, - .disable = ltq_pmx_disable, .gpio_request_enable = ltq_pmx_gpio_request_enable, }; -- cgit v1.2.3 From 89377aa5156a93e73a3f7c7ccdc0d0fecf65e0d2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 8 Nov 2012 00:10:17 +0800 Subject: pinctrl: lantiq: Staticize non-exported symbols Both ltq_pinctrl_dt_node_to_map() and ltq_pinctrl_dt_free_map() are not referenced outside of this file. Make them static. Signed-off-by: Axel Lin Acked-by: John Crispin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-lantiq.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c index d670ad6e6e4..15f501d8902 100644 --- a/drivers/pinctrl/pinctrl-lantiq.c +++ b/drivers/pinctrl/pinctrl-lantiq.c @@ -46,8 +46,8 @@ static int ltq_get_group_pins(struct pinctrl_dev *pctrldev, return 0; } -void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) +static void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, + struct pinctrl_map *map, unsigned num_maps) { int i; @@ -128,10 +128,10 @@ static int ltq_pinctrl_dt_subnode_size(struct device_node *np) return ret; } -int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, - unsigned *num_maps) +static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np_config, + struct pinctrl_map **map, + unsigned *num_maps) { struct pinctrl_map *tmp; struct device_node *np; -- cgit v1.2.3 From e38d457de7be63e6ced1ea254aa51466deb1fef0 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 10 Nov 2012 21:53:20 +0800 Subject: pinctrl: pinmux: Release all taken pins in pinmux_enable_setting error paths Currently pinmux_enable_setting does not release all taken pins if ops->enable() returns error. This patch ensures all taken pins are released in any error paths. Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 0ef01ee2835..1a00658b3ea 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -409,11 +409,7 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) dev_err(pctldev->dev, "could not request pin %d on device %s\n", pins[i], pinctrl_dev_get_name(pctldev)); - /* On error release all taken pins */ - i--; /* this pin just failed */ - for (; i >= 0; i--) - pin_free(pctldev, pins[i], NULL); - return -ENODEV; + goto err_pin_request; } } @@ -429,8 +425,26 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) desc->mux_setting = &(setting->data.mux); } - return ops->enable(pctldev, setting->data.mux.func, - setting->data.mux.group); + ret = ops->enable(pctldev, setting->data.mux.func, + setting->data.mux.group); + + if (ret) + goto err_enable; + + return 0; + +err_enable: + for (i = 0; i < num_pins; i++) { + desc = pin_desc_get(pctldev, pins[i]); + if (desc) + desc->mux_setting = NULL; + } +err_pin_request: + /* On error release all taken pins */ + while (--i >= 0) + pin_free(pctldev, pins[i], NULL); + + return ret; } void pinmux_disable_setting(struct pinctrl_setting const *setting) -- cgit v1.2.3 From 0b8728d6f140dc20690384286ade47c956edc999 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Mon, 5 Nov 2012 06:20:31 -0800 Subject: ledtrig-cpu: kill useless mutex to fix sleep in atomic context Seeing the following every time the CPU enters or leaves idle on a Beagleboard: BUG: sleeping function called from invalid context at kernel/mutex.c:269 in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0 no locks held by swapper/0/0. [] (unwind_backtrace+0x0/0xf8) from [] (mutex_lock_nested+0x24/0x380) [] (mutex_lock_nested+0x24/0x380) from [] (ledtrig_cpu+0x38/0x88) [] (ledtrig_cpu+0x38/0x88) from [] (cpu_idle+0xf4/0x120) [] (cpu_idle+0xf4/0x120) from [] (start_kernel+0x2bc/0x30c) Miles Lane has reported seeing similar splats during system suspend. The mutex in struct led_trigger_cpu appears to have no function: it resides in a per-cpu data structure which never changes after the trigger is registered. So just remove it. Reported-by: Miles Lane Signed-off-by: Nathan Lynch Signed-off-by: Bryan Wu --- drivers/leds/ledtrig-cpu.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/drivers/leds/ledtrig-cpu.c b/drivers/leds/ledtrig-cpu.c index b312056da14..4239b3955ff 100644 --- a/drivers/leds/ledtrig-cpu.c +++ b/drivers/leds/ledtrig-cpu.c @@ -33,8 +33,6 @@ struct led_trigger_cpu { char name[MAX_NAME_LEN]; struct led_trigger *_trig; - struct mutex lock; - int lock_is_inited; }; static DEFINE_PER_CPU(struct led_trigger_cpu, cpu_trig); @@ -50,12 +48,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt) { struct led_trigger_cpu *trig = &__get_cpu_var(cpu_trig); - /* mutex lock should be initialized before calling mutex_call() */ - if (!trig->lock_is_inited) - return; - - mutex_lock(&trig->lock); - /* Locate the correct CPU LED */ switch (ledevt) { case CPU_LED_IDLE_END: @@ -75,8 +67,6 @@ void ledtrig_cpu(enum cpu_led_event ledevt) /* Will leave the LED as it is */ break; } - - mutex_unlock(&trig->lock); } EXPORT_SYMBOL(ledtrig_cpu); @@ -117,14 +107,9 @@ static int __init ledtrig_cpu_init(void) for_each_possible_cpu(cpu) { struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); - mutex_init(&trig->lock); - snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); - mutex_lock(&trig->lock); led_trigger_register_simple(trig->name, &trig->_trig); - trig->lock_is_inited = 1; - mutex_unlock(&trig->lock); } register_syscore_ops(&ledtrig_cpu_syscore_ops); @@ -142,15 +127,9 @@ static void __exit ledtrig_cpu_exit(void) for_each_possible_cpu(cpu) { struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); - mutex_lock(&trig->lock); - led_trigger_unregister_simple(trig->_trig); trig->_trig = NULL; memset(trig->name, 0, MAX_NAME_LEN); - trig->lock_is_inited = 0; - - mutex_unlock(&trig->lock); - mutex_destroy(&trig->lock); } unregister_syscore_ops(&ledtrig_cpu_syscore_ops); -- cgit v1.2.3 From 0c9f79be295c99ac7e4b569ca493d75fdcc19e4e Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Sun, 11 Nov 2012 11:20:01 +0000 Subject: ipv4: avoid undefined behavior in do_ip_setsockopt() (1< Signed-off-by: David S. Miller --- net/ipv4/ip_sockglue.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 5eea4a81104..14bbfcf717a 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -457,19 +457,28 @@ static int do_ip_setsockopt(struct sock *sk, int level, struct inet_sock *inet = inet_sk(sk); int val = 0, err; - if (((1<= sizeof(int)) { if (get_user(val, (int __user *) optval)) return -EFAULT; -- cgit v1.2.3 From 36caff5d795429c572443894e8789c2150dd796b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 7 Nov 2012 10:31:30 -0500 Subject: USB: fix endpoint-disabling for failed config changes This patch (as1631) fixes a bug that shows up when a config change fails for a device under an xHCI controller. The controller needs to be told to disable the endpoints that have been enabled for the new config. The existing code does this, but before storing the information about which endpoints were enabled! As a result, any second attempt to install the new config is doomed to fail because xhci-hcd will refuse to enable an endpoint that is already enabled. The patch optimistically initializes the new endpoints' device structures before asking the device to switch to the new config. If the request fails then the endpoint information is already stored, so we can use usb_hcd_alloc_bandwidth() to disable the endpoints with no trouble. The rest of the error path is slightly more complex now; we have to disable the new interfaces and call put_device() rather than simply deallocating them. Signed-off-by: Alan Stern Reported-and-tested-by: Matthias Schniedermeyer CC: Sarah Sharp CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 54 ++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 1ed5afd91e6..a557658f322 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1806,29 +1806,8 @@ free_interfaces: goto free_interfaces; } - ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - USB_REQ_SET_CONFIGURATION, 0, configuration, 0, - NULL, 0, USB_CTRL_SET_TIMEOUT); - if (ret < 0) { - /* All the old state is gone, so what else can we do? - * The device is probably useless now anyway. - */ - cp = NULL; - } - - dev->actconfig = cp; - if (!cp) { - usb_set_device_state(dev, USB_STATE_ADDRESS); - usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); - /* Leave LPM disabled while the device is unconfigured. */ - mutex_unlock(hcd->bandwidth_mutex); - usb_autosuspend_device(dev); - goto free_interfaces; - } - mutex_unlock(hcd->bandwidth_mutex); - usb_set_device_state(dev, USB_STATE_CONFIGURED); - - /* Initialize the new interface structures and the + /* + * Initialize the new interface structures and the * hc/hcd/usbcore interface/endpoint state. */ for (i = 0; i < nintf; ++i) { @@ -1872,6 +1851,35 @@ free_interfaces: } kfree(new_interfaces); + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + USB_REQ_SET_CONFIGURATION, 0, configuration, 0, + NULL, 0, USB_CTRL_SET_TIMEOUT); + if (ret < 0 && cp) { + /* + * All the old state is gone, so what else can we do? + * The device is probably useless now anyway. + */ + usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); + for (i = 0; i < nintf; ++i) { + usb_disable_interface(dev, cp->interface[i], true); + put_device(&cp->interface[i]->dev); + cp->interface[i] = NULL; + } + cp = NULL; + } + + dev->actconfig = cp; + mutex_unlock(hcd->bandwidth_mutex); + + if (!cp) { + usb_set_device_state(dev, USB_STATE_ADDRESS); + + /* Leave LPM disabled while the device is unconfigured. */ + usb_autosuspend_device(dev); + return ret; + } + usb_set_device_state(dev, USB_STATE_CONFIGURED); + if (cp->string == NULL && !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) cp->string = usb_cache_string(dev, cp->desc.iConfiguration); -- cgit v1.2.3 From 1b36810e27a9791878e4694357ab6d4c06acc22d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 7 Nov 2012 16:12:47 -0500 Subject: USB: EHCI: miscellaneous cleanups for the library conversion This patch (as1630) cleans up a few minor items resulting from the split-up of the ehci-hcd driver: Remove the product_desc string from the ehci_driver_overrides structure. All drivers will use the generic "EHCI Host Controller" string. (This was requested by Felipe Balbi.) Allow drivers to pass a NULL pointer to ehci_init_driver() if they don't have to override any settings. Remove a #define symbol that is no longer used from the ChipIdea host driver. Rename overrides to pci_overrides in ehci-pci.c, for consistency with ehci-platform.c. Mark the *_overrides structures as __initdata. Signed-off-by: Alan Stern Reviewed-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/host.c | 7 +------ drivers/usb/host/ehci-hcd.c | 9 +++++---- drivers/usb/host/ehci-pci.c | 5 ++--- drivers/usb/host/ehci-platform.c | 3 +-- drivers/usb/host/ehci.h | 1 - 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c index fed97d32389..caecad9213f 100644 --- a/drivers/usb/chipidea/host.c +++ b/drivers/usb/chipidea/host.c @@ -25,17 +25,12 @@ #include #include -#define CHIPIDEA_EHCI #include "../host/ehci.h" #include "ci.h" #include "bits.h" #include "host.h" -static const struct ehci_driver_overrides ci_overrides = { - .product_desc = "ChipIdea HDRC EHCI host controller", -}; - static struct hc_driver __read_mostly ci_ehci_hc_driver; static irqreturn_t host_irq(struct ci13xxx *ci) @@ -103,7 +98,7 @@ int ci_hdrc_host_init(struct ci13xxx *ci) rdrv->name = "host"; ci->roles[CI_ROLE_HOST] = rdrv; - ehci_init_driver(&ci_ehci_hc_driver, &ci_overrides); + ehci_init_driver(&ci_ehci_hc_driver, NULL); return 0; } diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 28f694eb624..c97503bb0b0 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1231,10 +1231,11 @@ void ehci_init_driver(struct hc_driver *drv, /* Copy the generic table to drv and then apply the overrides */ *drv = ehci_hc_driver; - drv->product_desc = over->product_desc; - drv->hcd_priv_size += over->extra_priv_size; - if (over->reset) - drv->reset = over->reset; + if (over) { + drv->hcd_priv_size += over->extra_priv_size; + if (over->reset) + drv->reset = over->reset; + } } EXPORT_SYMBOL_GPL(ehci_init_driver); diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 46018e97524..3fb76ca6184 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -383,8 +383,7 @@ static int ehci_pci_resume(struct usb_hcd *hcd, bool hibernated) static struct hc_driver __read_mostly ehci_pci_hc_driver; -static const struct ehci_driver_overrides overrides = { - .product_desc = "EHCI PCI host controller", +static const struct ehci_driver_overrides pci_overrides __initdata = { .reset = ehci_pci_setup, }; @@ -426,7 +425,7 @@ static int __init ehci_pci_init(void) pr_info("%s: " DRIVER_DESC "\n", hcd_name); - ehci_init_driver(&ehci_pci_hc_driver, &overrides); + ehci_init_driver(&ehci_pci_hc_driver, &pci_overrides); /* Entries for the PCI suspend/resume callbacks are special */ ehci_pci_hc_driver.pci_suspend = ehci_suspend; diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index feeedf84011..f14c542b142 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -57,8 +57,7 @@ static int ehci_platform_reset(struct usb_hcd *hcd) static struct hc_driver __read_mostly ehci_platform_hc_driver; -static const struct ehci_driver_overrides platform_overrides = { - .product_desc = "Generic Platform EHCI controller", +static const struct ehci_driver_overrides platform_overrides __initdata = { .reset = ehci_platform_reset, }; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 24a8ada4701..9dadc7118d6 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -784,7 +784,6 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) /* Declarations of things exported for use by ehci platform drivers */ struct ehci_driver_overrides { - const char *product_desc; size_t extra_priv_size; int (*reset)(struct usb_hcd *hcd); }; -- cgit v1.2.3 From 2656a9abcf1ec8dd5fee6a75d6997a0f2fa0094e Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 8 Nov 2012 10:17:01 -0500 Subject: USB: EHCI: bugfix: urb->hcpriv should not be NULL This patch (as1632b) fixes a bug in ehci-hcd. The USB core uses urb->hcpriv to determine whether or not an URB is active; host controller drivers are supposed to set this pointer to a non-NULL value when an URB is queued. However ehci-hcd sets it to NULL for isochronous URBs, which defeats the check in usbcore. In itself this isn't a big deal. But people have recently found that certain sequences of actions will cause the snd-usb-audio driver to reuse URBs without waiting for them to complete. In the absence of proper checking by usbcore, the URBs get added to their endpoint list twice. This leads to list corruption and a system freeze. The patch makes ehci-hcd assign a meaningful value to urb->hcpriv for isochronous URBs. Improving robustness always helps. Signed-off-by: Alan Stern Reported-by: Artem S. Tashkinov Reported-by: Christof Meerwald CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-q.c | 12 +++--------- drivers/usb/host/ehci-sched.c | 4 ++-- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 4b66374bdc8..3d989028c83 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -264,15 +264,9 @@ ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status) __releases(ehci->lock) __acquires(ehci->lock) { - if (likely (urb->hcpriv != NULL)) { - struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; - - /* S-mask in a QH means it's an interrupt urb */ - if ((qh->hw->hw_info2 & cpu_to_hc32(ehci, QH_SMASK)) != 0) { - - /* ... update hc-wide periodic stats (for usbfs) */ - ehci_to_hcd(ehci)->self.bandwidth_int_reqs--; - } + if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { + /* ... update hc-wide periodic stats */ + ehci_to_hcd(ehci)->self.bandwidth_int_reqs--; } if (unlikely(urb->unlinked)) { diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 2e14714b359..69ebee73c0c 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1630,7 +1630,7 @@ static void itd_link_urb( /* don't need that schedule data any more */ iso_sched_free (stream, iso_sched); - urb->hcpriv = NULL; + urb->hcpriv = stream; ++ehci->isoc_count; enable_periodic(ehci); @@ -2029,7 +2029,7 @@ static void sitd_link_urb( /* don't need that schedule data any more */ iso_sched_free (stream, sched); - urb->hcpriv = NULL; + urb->hcpriv = stream; ++ehci->isoc_count; enable_periodic(ehci); -- cgit v1.2.3 From 2f02bc8af3abb846823811af65ec6cc46a4d525d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 7 Nov 2012 16:35:00 -0500 Subject: USB: report submission of active URBs This patch (as1633) changes slightly the way usbcore handled submissions of URBs that are already active. It will now return -EBUSY rather than -EINVAL, and it will call WARN_ONCE to draw people's attention to the bug. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/error-codes.txt | 2 ++ drivers/usb/core/urb.c | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt index 8d1e2a9ebbb..9c3eb845ebe 100644 --- a/Documentation/usb/error-codes.txt +++ b/Documentation/usb/error-codes.txt @@ -21,6 +21,8 @@ Non-USB-specific: USB-specific: +-EBUSY The URB is already active. + -ENODEV specified USB-device or bus doesn't exist -ENOENT specified interface or endpoint does not exist or diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 3662287e2f4..e0d9d948218 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -321,8 +321,13 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) struct usb_host_endpoint *ep; int is_out; - if (!urb || urb->hcpriv || !urb->complete) + if (!urb || !urb->complete) return -EINVAL; + if (urb->hcpriv) { + WARN_ONCE(1, "URB %p submitted while active\n", urb); + return -EBUSY; + } + dev = urb->dev; if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED)) return -ENODEV; -- cgit v1.2.3 From 5a8477660d9ddc090203736d7271137265cb25bb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 12 Nov 2012 01:19:02 -0500 Subject: kill bogus BUG_ON() in do_close_on_exec() It can be legitimately triggered via procfs access. Now, at least 2 of 3 of get_files_struct() callers in procfs are useless, but when and if we get rid of those we can always add WARN_ON() here. BUG_ON() at that spot is simply wrong. Signed-off-by: Al Viro --- fs/file.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/file.c b/fs/file.c index d3b5fa80b71..331e7d24d9d 100644 --- a/fs/file.c +++ b/fs/file.c @@ -685,7 +685,6 @@ void do_close_on_exec(struct files_struct *files) struct fdtable *fdt; /* exec unshares first */ - BUG_ON(atomic_read(&files->count) != 1); spin_lock(&files->file_lock); for (i = 0; ; i++) { unsigned long set; -- cgit v1.2.3 From 05193639ca977cc889668718adb38db6d585045b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 12 Nov 2012 10:07:36 +0100 Subject: ALSA: hda - Add a missing quirk entry for iMac 9,1 This is another variant of iMac 9,1 with a different codec SSID. Reported-and-tested-by: Everaldo Canuto Cc: [v3.3+] Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c0ce3b1f04b..68fd49294b2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5407,6 +5407,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), + SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), -- cgit v1.2.3 From 6722df86ba92cce09fd5348ca23e7042b51d6013 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Sun, 4 Nov 2012 22:03:02 +0100 Subject: ARM: 7570/1: quiet down the non make -s output Commit edc88ceb0c7d285b9f58bc29a638cd8163b59989 silenced the make -s build, but inadvertently made louder the non-silent build. Fix by prepending '@' to each of the added $(kecho) statements. Build with edc88ceb0c7d285b9f58bc29a638cd8163b59989: CHK include/generated/compile.h echo ' Kernel: arch/arm/boot/Image is ready' Kernel: arch/arm/boot/Image is ready LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage echo ' Kernel: arch/arm/boot/zImage is ready' Kernel: arch/arm/boot/zImage is ready Build with this fix: CHK include/generated/compile.h Kernel: arch/arm/boot/Image is ready LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready Signed-off-by: Josh Cartwright Signed-off-by: Russell King --- arch/arm/boot/Makefile | 10 +++++----- arch/arm/tools/Makefile | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index f2aa09eb658..9137df539b6 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -33,7 +33,7 @@ ifeq ($(CONFIG_XIP_KERNEL),y) $(obj)/xipImage: vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' + @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' $(obj)/Image $(obj)/zImage: FORCE @echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)' @@ -48,14 +48,14 @@ $(obj)/xipImage: FORCE $(obj)/Image: vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' $(obj)/compressed/vmlinux: $(obj)/Image FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' endif @@ -90,7 +90,7 @@ fi $(obj)/uImage: $(obj)/zImage FORCE @$(check_for_multiple_loadaddr) $(call if_changed,uimage) - $(kecho) ' Image $@ is ready' + @$(kecho) ' Image $@ is ready' $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(Q)$(MAKE) $(build)=$(obj)/bootp $@ @@ -98,7 +98,7 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(obj)/bootpImage: $(obj)/bootp/bootp FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' PHONY += initrd FORCE initrd: diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile index cd60a81163e..32d05c8219d 100644 --- a/arch/arm/tools/Makefile +++ b/arch/arm/tools/Makefile @@ -5,6 +5,6 @@ # include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types - $(kecho) ' Generating $@' + @$(kecho) ' Generating $@' @mkdir -p $(dir $@) $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } -- cgit v1.2.3 From 2b6e204f84cc8e324c5425ea98e378a2aeba3be0 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 7 Nov 2012 21:22:08 +0100 Subject: ARM: 7572/1: proc-v6.S: fix comment Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mm/proc-v6.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 86b8b480634..09c5233f4df 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -89,7 +89,7 @@ ENTRY(cpu_v6_dcache_clean_area) mov pc, lr /* - * cpu_arm926_switch_mm(pgd_phys, tsk) + * cpu_v6_switch_mm(pgd_phys, tsk) * * Set the translation table base pointer to be pgd_phys * -- cgit v1.2.3 From 6b90466cfec2a2fe027187d675d8d14217c12d82 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 12 Nov 2012 10:16:09 +0100 Subject: HID: microsoft: do not use compound literal - fix build In patch "HID: microsoft: fix invalid rdesc for 3k kbd" I fixed support for MS 3k keyboards. However the added check using memcmp and a compound statement breaks build on architectures where memcmp is a macro with parameters. hid-microsoft.c:51:18: error: macro "memcmp" passed 6 arguments, but takes just 3 On x86_64, memcmp is a function, so I did not see the error. Signed-off-by: Jiri Slaby Reported-by: Geert Uytterhoeven Signed-off-by: Jiri Kosina --- drivers/hid/hid-microsoft.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index f676c01bb47..6fcd466d082 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c @@ -46,9 +46,9 @@ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, rdesc[559] = 0x45; } /* the same as above (s/usage/physical/) */ - if ((quirks & MS_RDESC_3K) && *rsize == 106 && - !memcmp((char []){ 0x19, 0x00, 0x29, 0xff }, - &rdesc[94], 4)) { + if ((quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 && + rdesc[95] == 0x00 && rdesc[96] == 0x29 && + rdesc[97] == 0xff) { rdesc[94] = 0x35; rdesc[96] = 0x45; } -- cgit v1.2.3 From fa968ee215c0ca91e4a9c3a69ac2405aae6e5d2f Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 7 Nov 2012 10:44:08 +0100 Subject: s390/signal: set correct address space control If user space is running in primary mode it can switch to secondary or access register mode, this is used e.g. in the clock_gettime code of the vdso. If a signal is delivered to the user space process while it has been running in access register mode the signal handler is executed in access register mode as well which will result in a crash most of the time. Set the address space control bits in the PSW to the default for the execution of the signal handler and make sure that the previous address space control is restored on signal return. Take care that user space can not switch to the kernel address space by modifying the registers in the signal frame. Cc: stable@vger.kernel.org Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/compat.h | 2 +- arch/s390/include/uapi/asm/ptrace.h | 4 ++-- arch/s390/kernel/compat_signal.c | 14 ++++++++++++-- arch/s390/kernel/signal.c | 14 ++++++++++++-- 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index a34a9d612fc..18cd6b59265 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h @@ -20,7 +20,7 @@ #define PSW32_MASK_CC 0x00003000UL #define PSW32_MASK_PM 0x00000f00UL -#define PSW32_MASK_USER 0x00003F00UL +#define PSW32_MASK_USER 0x0000FF00UL #define PSW32_ADDR_AMODE 0x80000000UL #define PSW32_ADDR_INSN 0x7FFFFFFFUL diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h index 705588a16d7..a5ca214b34f 100644 --- a/arch/s390/include/uapi/asm/ptrace.h +++ b/arch/s390/include/uapi/asm/ptrace.h @@ -239,7 +239,7 @@ typedef struct #define PSW_MASK_EA 0x00000000UL #define PSW_MASK_BA 0x00000000UL -#define PSW_MASK_USER 0x00003F00UL +#define PSW_MASK_USER 0x0000FF00UL #define PSW_ADDR_AMODE 0x80000000UL #define PSW_ADDR_INSN 0x7FFFFFFFUL @@ -269,7 +269,7 @@ typedef struct #define PSW_MASK_EA 0x0000000100000000UL #define PSW_MASK_BA 0x0000000080000000UL -#define PSW_MASK_USER 0x00003F8180000000UL +#define PSW_MASK_USER 0x0000FF8180000000UL #define PSW_ADDR_AMODE 0x0000000000000000UL #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index a1e8a8694bb..593fcc9253f 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -309,6 +309,10 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs) regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | (__u64)(regs32.psw.mask & PSW32_MASK_USER) << 32 | (__u64)(regs32.psw.addr & PSW32_ADDR_AMODE); + /* Check for invalid user address space control. */ + if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) + regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN); for (i = 0; i < NUM_GPRS; i++) regs->gprs[i] = (__u64) regs32.gprs[i]; @@ -481,7 +485,10 @@ static int setup_frame32(int sig, struct k_sigaction *ka, /* Set up registers for signal handler */ regs->gprs[15] = (__force __u64) frame; - regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ + /* Force 31 bit amode and default user address space control. */ + regs->psw.mask = PSW_MASK_BA | + (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (__force __u64) ka->sa.sa_handler; regs->gprs[2] = map_signal(sig); @@ -549,7 +556,10 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up registers for signal handler */ regs->gprs[15] = (__force __u64) frame; - regs->psw.mask |= PSW_MASK_BA; /* force amode 31 */ + /* Force 31 bit amode and default user address space control. */ + regs->psw.mask = PSW_MASK_BA | + (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (__u64) ka->sa.sa_handler; regs->gprs[2] = map_signal(sig); diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index c13a2a37ef0..d1259d87507 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -136,6 +136,10 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs) /* Use regs->psw.mask instead of psw_user_bits to preserve PER bit. */ regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) | (user_sregs.regs.psw.mask & PSW_MASK_USER); + /* Check for invalid user address space control. */ + if ((regs->psw.mask & PSW_MASK_ASC) >= (psw_kernel_bits & PSW_MASK_ASC)) + regs->psw.mask = (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); /* Check for invalid amode */ if (regs->psw.mask & PSW_MASK_EA) regs->psw.mask |= PSW_MASK_BA; @@ -273,7 +277,10 @@ static int setup_frame(int sig, struct k_sigaction *ka, /* Set up registers for signal handler */ regs->gprs[15] = (unsigned long) frame; - regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ + /* Force default amode and default user address space control. */ + regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | + (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; regs->gprs[2] = map_signal(sig); @@ -346,7 +353,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up registers for signal handler */ regs->gprs[15] = (unsigned long) frame; - regs->psw.mask |= PSW_MASK_EA | PSW_MASK_BA; /* 64 bit amode */ + /* Force default amode and default user address space control. */ + regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA | + (psw_user_bits & PSW_MASK_ASC) | + (regs->psw.mask & ~PSW_MASK_ASC); regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE; regs->gprs[2] = map_signal(sig); -- cgit v1.2.3 From 658e5ce705f2a09ab681eb61ca7c8619bb7a783d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 10 Nov 2012 11:04:27 +0100 Subject: s390/topology: fix core id vs physical package id mix-up The current topology code confuses core id vs physical package id. In other words /sys/devices/system/cpu/cpuX/topology/core_id displays the physical_package_id (aka socket id) instead of the core id. The physical_package_id sysfs attribute always displays "-1" instead of the socket id. Fix this mix-up with a small patch which defines and initializes topology_physical_package_id correctly and fixes the broken core id handling. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/topology.h | 3 +++ arch/s390/kernel/topology.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index 9ca30538376..9935cbd6a46 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h @@ -8,6 +8,9 @@ struct cpu; #ifdef CONFIG_SCHED_BOOK +extern unsigned char cpu_socket_id[NR_CPUS]; +#define topology_physical_package_id(cpu) (cpu_socket_id[cpu]) + extern unsigned char cpu_core_id[NR_CPUS]; extern cpumask_t cpu_core_map[NR_CPUS]; diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 54d93f4b681..dd55f7c2010 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -40,6 +40,7 @@ static DEFINE_SPINLOCK(topology_lock); static struct mask_info core_info; cpumask_t cpu_core_map[NR_CPUS]; unsigned char cpu_core_id[NR_CPUS]; +unsigned char cpu_socket_id[NR_CPUS]; static struct mask_info book_info; cpumask_t cpu_book_map[NR_CPUS]; @@ -83,11 +84,12 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, cpumask_set_cpu(lcpu, &book->mask); cpu_book_id[lcpu] = book->id; cpumask_set_cpu(lcpu, &core->mask); + cpu_core_id[lcpu] = rcpu; if (one_core_per_cpu) { - cpu_core_id[lcpu] = rcpu; + cpu_socket_id[lcpu] = rcpu; core = core->next; } else { - cpu_core_id[lcpu] = core->id; + cpu_socket_id[lcpu] = core->id; } smp_cpu_set_polarization(lcpu, tl_cpu->pp); } -- cgit v1.2.3 From 43c771a1963ab461a2f194e3c97fded1d5fe262f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 12 Nov 2012 10:51:34 +0100 Subject: wireless: allow 40 MHz on world roaming channels 12/13 When in world roaming mode, allow 40 MHz to be used on channels 12 and 13 so that an AP that is, e.g., using HT40+ on channel 9 (in the UK) can be used. Cc: stable@vger.kernel.org Reported-by: Eddie Chapman Tested-by: Eddie Chapman Acked-by: Luis R. Rodriguez Signed-off-by: Johannes Berg --- net/wireless/reg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index bcc7d7ee5a5..b75756b05af 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -141,9 +141,8 @@ static const struct ieee80211_regdomain world_regdom = { .reg_rules = { /* IEEE 802.11b/g, channels 1..11 */ REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), - /* IEEE 802.11b/g, channels 12..13. No HT40 - * channel fits here. */ - REG_RULE(2467-10, 2472+10, 20, 6, 20, + /* IEEE 802.11b/g, channels 12..13. */ + REG_RULE(2467-10, 2472+10, 40, 6, 20, NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), /* IEEE 802.11 channel 14 - Only JP enables -- cgit v1.2.3 From 4cf2d3b1b6ff9b7b6af1d2dbf1b63aa465250bc2 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:57:57 +0200 Subject: clk: ux500: Register i2c clock lookups for u8500 Cc: Ben Dooks Cc: Wolfram Sang Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Ulf Hansson Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index ca4a25ed844..7ad01aa30ef 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -228,6 +228,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, BIT(2), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.1"); + clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, BIT(3), 0); clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, @@ -239,6 +241,7 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, BIT(6), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.2"); clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, BIT(7), 0); @@ -255,11 +258,14 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, BIT(10), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.4"); + clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, BIT(11), 0); clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, BIT(0), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.3"); clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, BIT(1), 0); @@ -284,7 +290,6 @@ void u8500_clk_init(void) BIT(6), 0); clk_register_clkdev(clk, "apb_pclk", "sdi1"); - clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, BIT(7), 0); clk_register_clkdev(clk, "apb_pclk", "sdi3"); @@ -318,8 +323,10 @@ void u8500_clk_init(void) BIT(1), 0); clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, BIT(2), 0); + clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, BIT(3), 0); + clk_register_clkdev(clk, "apb_pclk", "nmk-i2c.0"); clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, BIT(4), 0); @@ -401,6 +408,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.1"); + clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", @@ -412,17 +421,23 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.2"); + clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); /* FIXME: Redefinition of BIT(3). */ + clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.4"); + clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); /* Periph2 */ clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.3"); clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); @@ -452,8 +467,10 @@ void u8500_clk_init(void) U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); + clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "nmk-i2c.0"); clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); -- cgit v1.2.3 From 08b1f1c7b9bf0f6fe9e2ce3369928955554a958b Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:57:58 +0200 Subject: clk: ux500: Register ssp clock lookups for u8500 Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 7ad01aa30ef..36ef41d90d6 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -321,8 +321,11 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, BIT(1), 0); + clk_register_clkdev(clk, "apb_pclk", "ssp0"); + clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, BIT(2), 0); + clk_register_clkdev(clk, "apb_pclk", "ssp1"); clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, BIT(3), 0); @@ -465,8 +468,11 @@ void u8500_clk_init(void) /* Periph3 */ clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "ssp0"); + clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "ssp1"); clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); -- cgit v1.2.3 From 15e66cd8d029de8055822a98c5a72a4414ffc0a6 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:57:59 +0200 Subject: clk: ux500: Register msp clock lookups for u8500 Cc: Mark Brown Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 36ef41d90d6..be843ba1f49 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -232,8 +232,13 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, BIT(3), 0); + clk_register_clkdev(clk, "apb_pclk", "msp0"); + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.0"); + clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, BIT(4), 0); + clk_register_clkdev(clk, "apb_pclk", "msp1"); + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.1"); clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE, BIT(5), 0); @@ -262,6 +267,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, BIT(11), 0); + clk_register_clkdev(clk, "apb_pclk", "msp3"); + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.3"); clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, BIT(0), 0); @@ -285,6 +292,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE, BIT(5), 0); + clk_register_clkdev(clk, "apb_pclk", "msp2"); + clk_register_clkdev(clk, "apb_pclk", "ux500-msp-i2s.2"); clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE, BIT(6), 0); @@ -415,8 +424,13 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "msp0"); + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.0"); + clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "msp1"); + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.1"); clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk", U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE); @@ -436,6 +450,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "msp3"); + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.3"); /* Periph2 */ clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", @@ -448,6 +464,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "msp2"); + clk_register_clkdev(clk, NULL, "ux500-msp-i2s.2"); clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk", U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE); -- cgit v1.2.3 From d4915cf5f6190b94411c3102078ac4b86149fe59 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:58:00 +0200 Subject: clk: ux500: Update rtc clock lookup for u8500 Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index be843ba1f49..0aae9295684 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -40,7 +40,7 @@ void u8500_clk_init(void) CLK_IS_ROOT|CLK_IGNORE_UNUSED, 32768); clk_register_clkdev(clk, "clk32k", NULL); - clk_register_clkdev(clk, NULL, "rtc-pl031"); + clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); /* PRCMU clocks */ fw_version = prcmu_get_fw_version(); -- cgit v1.2.3 From 3d930678034e756d0960d214412d344772b21109 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 22 Oct 2012 15:58:01 +0200 Subject: clk: ux500: Register slimbus clock lookups for u8500 At the same time the prcc bit for the kclk is corrected to bit 8 instead of 3. Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Acked-by: Lee Jones Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 0aae9295684..e2c17d187d9 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -254,6 +254,7 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE, BIT(8), 0); + clk_register_clkdev(clk, "apb_pclk", "slimbus0"); clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE, BIT(9), 0); @@ -441,8 +442,8 @@ void u8500_clk_init(void) clk_register_clkdev(clk, NULL, "nmk-i2c.2"); clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", - U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); - /* FIXME: Redefinition of BIT(3). */ + U8500_CLKRST1_BASE, BIT(8), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "slimbus0"); clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); -- cgit v1.2.3 From 04aa530ec04f61875b99c12721162e2964e3318c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 3 Nov 2012 11:52:09 +0100 Subject: genirq: Always force thread affinity Sankara reported that the genirq core code fails to adjust the affinity of an interrupt thread in several cases: 1) On request/setup_irq() the call to setup_affinity() happens before the new action is registered, so the new thread is not notified. 2) For secondary shared interrupts nothing notifies the new thread to change its affinity. 3) Interrupts which have the IRQ_NO_BALANCE flag set are not moving the thread either. Fix this by setting the thread affinity flag right on thread creation time. This ensures that under all circumstances the thread moves to the right place. Requires a check in irq_thread_check_affinity for an existing affinity mask (CONFIG_CPU_MASK_OFFSTACK=y) Reported-and-tested-by: Sankara Muthukrishnan Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/alpine.LFD.2.02.1209041738200.2754@ionos Signed-off-by: Thomas Gleixner --- kernel/irq/manage.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 1cbd572f6ad..35c70c9e24d 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -732,6 +732,7 @@ static void irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) { cpumask_var_t mask; + bool valid = true; if (!test_and_clear_bit(IRQTF_AFFINITY, &action->thread_flags)) return; @@ -746,10 +747,18 @@ irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *action) } raw_spin_lock_irq(&desc->lock); - cpumask_copy(mask, desc->irq_data.affinity); + /* + * This code is triggered unconditionally. Check the affinity + * mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out. + */ + if (desc->irq_data.affinity) + cpumask_copy(mask, desc->irq_data.affinity); + else + valid = false; raw_spin_unlock_irq(&desc->lock); - set_cpus_allowed_ptr(current, mask); + if (valid) + set_cpus_allowed_ptr(current, mask); free_cpumask_var(mask); } #else @@ -954,6 +963,16 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) */ get_task_struct(t); new->thread = t; + /* + * Tell the thread to set its affinity. This is + * important for shared interrupt handlers as we do + * not invoke setup_affinity() for the secondary + * handlers as everything is already set up. Even for + * interrupts marked with IRQF_NO_BALANCE this is + * correct as we want the thread to move to the cpu(s) + * on which the requesting code placed the interrupt. + */ + set_bit(IRQTF_AFFINITY, &new->thread_flags); } if (!alloc_cpumask_var(&mask, GFP_KERNEL)) { -- cgit v1.2.3 From d0ddfbd3d1346c1f481ec2289eef350cdba64b42 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 12 Nov 2012 18:31:35 +0200 Subject: drm/i915/sdvo: clean up connectors on intel_sdvo_init() failures Any failures in intel_sdvo_init() after the intel_sdvo_setup_output() call left behind ghost connectors, attached (with a dangling pointer) to the sdvo that has been cleaned up and freed. Properly destroy any connectors attached to the encoder. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=46381 CC: Chris Wilson Signed-off-by: Jani Nikula Cc: stable@vger.kernel.org Tested-by: bjo@nord-west.org [danvet: added a comment to explain why we need to clean up connectors even when sdvo_output_setup fails.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sdvo.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 79d308da29f..c600fb06e25 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2382,6 +2382,18 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) return true; } +static void intel_sdvo_output_cleanup(struct intel_sdvo *intel_sdvo) +{ + struct drm_device *dev = intel_sdvo->base.base.dev; + struct drm_connector *connector, *tmp; + + list_for_each_entry_safe(connector, tmp, + &dev->mode_config.connector_list, head) { + if (intel_attached_encoder(connector) == &intel_sdvo->base) + intel_sdvo_destroy(connector); + } +} + static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, struct intel_sdvo_connector *intel_sdvo_connector, int type) @@ -2705,7 +2717,8 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) intel_sdvo->caps.output_flags) != true) { DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", SDVO_NAME(intel_sdvo)); - goto err; + /* Output_setup can leave behind connectors! */ + goto err_output; } /* Only enable the hotplug irq if we need it, to work around noisy @@ -2718,12 +2731,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) /* Set the input timing to the screen. Assume always input 0. */ if (!intel_sdvo_set_target_input(intel_sdvo)) - goto err; + goto err_output; if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, &intel_sdvo->pixel_clock_min, &intel_sdvo->pixel_clock_max)) - goto err; + goto err_output; DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " "clock range %dMHz - %dMHz, " @@ -2743,6 +2756,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); return true; +err_output: + intel_sdvo_output_cleanup(intel_sdvo); + err: drm_encoder_cleanup(&intel_encoder->base); i2c_del_adapter(&intel_sdvo->ddc); -- cgit v1.2.3 From 2611bd189ee8cb6761393aec90d699015d9c5e9f Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 25 Oct 2012 13:27:51 -0700 Subject: xhci: Avoid global symbol pollution with handshake. Non-static xHCI driver symbols should start with the "xhci_" prefix, in order to avoid namespace pollution. Rename the "handshake" function to "xhci_handshake". Signed-off-by: Sarah Sharp Reported-by: Ben Hutchings --- drivers/usb/host/xhci-ring.c | 2 +- drivers/usb/host/xhci.c | 24 +++++++++++++----------- drivers/usb/host/xhci.h | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 4e1a8946b8d..77f1ace87ed 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -318,7 +318,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) * seconds), then it should assume that the there are * larger problems with the xHC and assert HCRST. */ - ret = handshake(xhci, &xhci->op_regs->cmd_ring, + ret = xhci_handshake(xhci, &xhci->op_regs->cmd_ring, CMD_RING_RUNNING, 0, 5 * 1000 * 1000); if (ret < 0) { xhci_err(xhci, "Stopped the command ring failed, " diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index c9e419f29b7..1ca0f3a2832 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -40,7 +40,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); /* TODO: copied from ehci-hcd.c - can this be refactored? */ /* - * handshake - spin reading hc until handshake completes or fails + * xhci_handshake - spin reading hc until handshake completes or fails * @ptr: address of hc register to be read * @mask: bits to look at in result of read * @done: value of those bits when handshake succeeds @@ -52,7 +52,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); * handshake done). There are two failure modes: "usec" have passed (major * hardware flakeout), or the register reads as all-ones (hardware removed). */ -int handshake(struct xhci_hcd *xhci, void __iomem *ptr, +int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr, u32 mask, u32 done, int usec) { u32 result; @@ -103,7 +103,7 @@ int xhci_halt(struct xhci_hcd *xhci) xhci_dbg(xhci, "// Halt the HC\n"); xhci_quiesce(xhci); - ret = handshake(xhci, &xhci->op_regs->status, + ret = xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); if (!ret) { xhci->xhc_state |= XHCI_STATE_HALTED; @@ -132,7 +132,7 @@ static int xhci_start(struct xhci_hcd *xhci) * Wait for the HCHalted Status bit to be 0 to indicate the host is * running. */ - ret = handshake(xhci, &xhci->op_regs->status, + ret = xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, 0, XHCI_MAX_HALT_USEC); if (ret == -ETIMEDOUT) xhci_err(xhci, "Host took too long to start, " @@ -167,7 +167,7 @@ int xhci_reset(struct xhci_hcd *xhci) command |= CMD_RESET; xhci_writel(xhci, command, &xhci->op_regs->command); - ret = handshake(xhci, &xhci->op_regs->command, + ret = xhci_handshake(xhci, &xhci->op_regs->command, CMD_RESET, 0, 10 * 1000 * 1000); if (ret) return ret; @@ -177,7 +177,7 @@ int xhci_reset(struct xhci_hcd *xhci) * xHCI cannot write to any doorbells or operational registers other * than status until the "Controller Not Ready" flag is cleared. */ - ret = handshake(xhci, &xhci->op_regs->status, + ret = xhci_handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 10 * 1000 * 1000); for (i = 0; i < 2; ++i) { @@ -890,7 +890,7 @@ int xhci_suspend(struct xhci_hcd *xhci) command = xhci_readl(xhci, &xhci->op_regs->command); command &= ~CMD_RUN; xhci_writel(xhci, command, &xhci->op_regs->command); - if (handshake(xhci, &xhci->op_regs->status, + if (xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) { xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); spin_unlock_irq(&xhci->lock); @@ -905,7 +905,8 @@ int xhci_suspend(struct xhci_hcd *xhci) command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_CSS; xhci_writel(xhci, command, &xhci->op_regs->command); - if (handshake(xhci, &xhci->op_regs->status, STS_SAVE, 0, 10 * 1000)) { + if (xhci_handshake(xhci, &xhci->op_regs->status, + STS_SAVE, 0, 10 * 1000)) { xhci_warn(xhci, "WARN: xHC save state timeout\n"); spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; @@ -967,7 +968,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_CRS; xhci_writel(xhci, command, &xhci->op_regs->command); - if (handshake(xhci, &xhci->op_regs->status, + if (xhci_handshake(xhci, &xhci->op_regs->status, STS_RESTORE, 0, 10 * 1000)) { xhci_warn(xhci, "WARN: xHC restore state timeout\n"); spin_unlock_irq(&xhci->lock); @@ -1035,7 +1036,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_RUN; xhci_writel(xhci, command, &xhci->op_regs->command); - handshake(xhci, &xhci->op_regs->status, STS_HALT, + xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, 0, 250 * 1000); /* step 5: walk topology and initialize portsc, @@ -3874,7 +3875,8 @@ static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, spin_lock_irqsave(&xhci->lock, flags); /* Check L1 Status */ - ret = handshake(xhci, pm_addr, PORT_L1S_MASK, PORT_L1S_SUCCESS, 125); + ret = xhci_handshake(xhci, pm_addr, + PORT_L1S_MASK, PORT_L1S_SUCCESS, 125); if (ret != -ETIMEDOUT) { /* enter L1 successfully */ temp = xhci_readl(xhci, addr); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 53df4e70ca0..f791bd0aee6 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1720,7 +1720,7 @@ static inline void xhci_unregister_plat(void) /* xHCI host controller glue */ typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); -int handshake(struct xhci_hcd *xhci, void __iomem *ptr, +int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr, u32 mask, u32 done, int usec); void xhci_quiesce(struct xhci_hcd *xhci); int xhci_halt(struct xhci_hcd *xhci); -- cgit v1.2.3 From 392a07ae3316f2b90b39ce41e66d6f6b5c95de90 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 25 Oct 2012 13:44:12 -0700 Subject: xhci: Fix conditional check in bandwidth calculation. David reports that at drivers/usb/host/xhci.c:2257: static bool xhci_is_sync_in_ep(unsigned int ep_type) { return (ep_type == ISOC_IN_EP || ep_type != INT_IN_EP); } The static analyser cppcheck says [linux-3.7-rc2/drivers/usb/host/xhci.c:2257]: (style) Redundant condition: If ep_type == 5, the comparison ep_type != 7 is always true. Maybe the original programmer intention was something like static bool xhci_is_sync_in_ep(unsigned int ep_type) { return (ep_type == ISOC_IN_EP || ep_type == INT_IN_EP); } Fix this. This patch should be backported to stable kernels as old as 3.2, that contain the commit 2b69899934c63b7b9432568584fb4c4a2924f40c "xhci: USB 3.0 BW checking." Signed-off-by: Sarah Sharp Reported-by: David Binderman Cc: stable@vger.kernel.org --- drivers/usb/host/xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1ca0f3a2832..2e29f2f884c 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -2255,7 +2255,7 @@ static bool xhci_is_async_ep(unsigned int ep_type) static bool xhci_is_sync_in_ep(unsigned int ep_type) { - return (ep_type == ISOC_IN_EP || ep_type != INT_IN_EP); + return (ep_type == ISOC_IN_EP || ep_type == INT_IN_EP); } static unsigned int xhci_get_ss_bw_consumed(struct xhci_bw_info *ep_bw) -- cgit v1.2.3 From 4525c0a10dff7ad3669763c28016c7daffc3900e Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 25 Oct 2012 15:56:40 -0700 Subject: xHCI: Fix TD Size calculation on 1.0 hosts. The xHCI 1.0 specification made a change to the TD Size field in TRBs. The value is now the number of packets that remain to be sent in the TD, not including this TRB. The TD Size value for the last TRB in a TD must always be zero. The xHCI function xhci_v1_0_td_remainder() attempts to calculate this, but it gets it wrong. First, it erroneously reuses the old xhci_td_remainder function, which will right shift the value by 10. The xHCI 1.0 spec as of June 2011 says nothing about right shifting by 10. Second, it does not set the TD size for the last TRB in a TD to zero. Third, it uses roundup instead of DIV_ROUND_UP. The total packet count is supposed to be the total number of bytes in this TD, divided by the max packet size, rounded up. DIV_ROUND_UP is the right function to use in that case. With the old code, a TD on an endpoint with max packet size 1024 would be set up like so: TRB 1, TRB length = 600 bytes, TD size = 0 TRB 1, TRB length = 200 bytes, TD size = 0 TRB 1, TRB length = 100 bytes, TD size = 0 With the new code, the TD would be set up like this: TRB 1, TRB length = 600 bytes, TD size = 1 TRB 1, TRB length = 200 bytes, TD size = 1 TRB 1, TRB length = 100 bytes, TD size = 0 This commit should be backported to kernels as old as 3.0, that contain the commit 4da6e6f247a2601ab9f1e63424e4d944ed4124f3 "xhci 1.0: Update TD size field format." Signed-off-by: Sarah Sharp Reported-by: Chintan Mehta Reported-by: Shimmer Huang Tested-by: Bhavik Kothari Tested-by: Shimmer Huang Cc: stable@vger.kernel.org --- drivers/usb/host/xhci-ring.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 77f1ace87ed..cbb44b7b9d6 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3071,11 +3071,11 @@ static u32 xhci_td_remainder(unsigned int remainder) } /* - * For xHCI 1.0 host controllers, TD size is the number of packets remaining in - * the TD (*not* including this TRB). + * For xHCI 1.0 host controllers, TD size is the number of max packet sized + * packets remaining in the TD (*not* including this TRB). * * Total TD packet count = total_packet_count = - * roundup(TD size in bytes / wMaxPacketSize) + * DIV_ROUND_UP(TD size in bytes / wMaxPacketSize) * * Packets transferred up to and including this TRB = packets_transferred = * rounddown(total bytes transferred including this TRB / wMaxPacketSize) @@ -3083,15 +3083,16 @@ static u32 xhci_td_remainder(unsigned int remainder) * TD size = total_packet_count - packets_transferred * * It must fit in bits 21:17, so it can't be bigger than 31. + * The last TRB in a TD must have the TD size set to zero. */ - static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len, - unsigned int total_packet_count, struct urb *urb) + unsigned int total_packet_count, struct urb *urb, + unsigned int num_trbs_left) { int packets_transferred; /* One TRB with a zero-length data packet. */ - if (running_total == 0 && trb_buff_len == 0) + if (num_trbs_left == 0 || (running_total == 0 && trb_buff_len == 0)) return 0; /* All the TRB queueing functions don't count the current TRB in @@ -3100,7 +3101,9 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len, packets_transferred = (running_total + trb_buff_len) / usb_endpoint_maxp(&urb->ep->desc); - return xhci_td_remainder(total_packet_count - packets_transferred); + if ((total_packet_count - packets_transferred) > 31) + return 31 << 17; + return (total_packet_count - packets_transferred) << 17; } static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, @@ -3127,7 +3130,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, num_trbs = count_sg_trbs_needed(xhci, urb); num_sgs = urb->num_mapped_sgs; - total_packet_count = roundup(urb->transfer_buffer_length, + total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length, usb_endpoint_maxp(&urb->ep->desc)); trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id], @@ -3210,7 +3213,8 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, running_total); } else { remainder = xhci_v1_0_td_remainder(running_total, - trb_buff_len, total_packet_count, urb); + trb_buff_len, total_packet_count, urb, + num_trbs - 1); } length_field = TRB_LEN(trb_buff_len) | remainder | @@ -3318,7 +3322,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, start_cycle = ep_ring->cycle_state; running_total = 0; - total_packet_count = roundup(urb->transfer_buffer_length, + total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length, usb_endpoint_maxp(&urb->ep->desc)); /* How much data is in the first TRB? */ addr = (u64) urb->transfer_dma; @@ -3364,7 +3368,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, running_total); } else { remainder = xhci_v1_0_td_remainder(running_total, - trb_buff_len, total_packet_count, urb); + trb_buff_len, total_packet_count, urb, + num_trbs - 1); } length_field = TRB_LEN(trb_buff_len) | remainder | @@ -3627,7 +3632,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, addr = start_addr + urb->iso_frame_desc[i].offset; td_len = urb->iso_frame_desc[i].length; td_remain_len = td_len; - total_packet_count = roundup(td_len, + total_packet_count = DIV_ROUND_UP(td_len, usb_endpoint_maxp(&urb->ep->desc)); /* A zero-length transfer still involves at least one packet. */ if (total_packet_count == 0) @@ -3706,7 +3711,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, } else { remainder = xhci_v1_0_td_remainder( running_total, trb_buff_len, - total_packet_count, urb); + total_packet_count, urb, + (trbs_per_td - j - 1)); } length_field = TRB_LEN(trb_buff_len) | remainder | -- cgit v1.2.3 From 68e5254adb88bede68285f11fb442a4d34fb550c Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Thu, 1 Nov 2012 12:47:59 -0700 Subject: xhci: fix null-pointer dereference when destroying half-built segment rings xhci_alloc_segments_for_ring() builds a list of xhci_segments and links the tail to head at the end (forming a ring). When it bails out for OOM reasons half-way through, it tries to destroy its half-built list with xhci_free_segments_for_ring(), even though it is not a ring yet. This causes a null-pointer dereference upon hitting the last element. Furthermore, one of its callers (xhci_ring_alloc()) mistakenly believes the output parameters to be valid upon this kind of OOM failure, and calls xhci_ring_free() on them. Since the (incomplete) list/ring should already be destroyed in that case, this would lead to a use after free. This patch fixes those issues by having xhci_alloc_segments_for_ring() destroy its half-built, non-circular list manually and destroying the invalid struct xhci_ring in xhci_ring_alloc() with a plain kfree(). This patch should be backported to kernels as old as 2.6.31, that contains the commit 0ebbab37422315a5d0cb29792271085bafdf38c0 "USB: xhci: Ring allocation and initialization." A separate patch will need to be developed for kernels older than 3.4, since the ring allocation code was refactored in that kernel. Signed-off-by: Julius Werner Signed-off-by: Sarah Sharp Cc: stable@vger.kernel.org --- drivers/usb/host/xhci-mem.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 487bc083dea..fb51c7085ad 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -205,7 +205,12 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci, next = xhci_segment_alloc(xhci, cycle_state, flags); if (!next) { - xhci_free_segments_for_ring(xhci, *first); + prev = *first; + while (prev) { + next = prev->next; + xhci_segment_free(xhci, prev); + prev = next; + } return -ENOMEM; } xhci_link_segments(xhci, prev, next, type); @@ -258,7 +263,7 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, return ring; fail: - xhci_ring_free(xhci, ring); + kfree(ring); return NULL; } -- cgit v1.2.3 From bba18e33f25072ebf70fd8f7f0cdbf8cdb59a746 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 17 Oct 2012 13:44:06 -0700 Subject: xhci: Extend Fresco Logic MSI quirk. Ali reports that plugging a device into the Fresco Logic xHCI host with PCI device ID 1400 produces an IRQ error: do_IRQ: 3.176 No irq handler for vector (irq -1) Other early Fresco Logic host revisions don't support MSI, even though their PCI config space claims they do. Extend the quirk to disabling MSI to this chipset revision. Also enable the short transfer quirk, since it's likely this revision also has that quirk, and it should be harmless to enable. 04:00.0 0c03: 1b73:1400 (rev 01) (prog-if 30 [XHCI]) Subsystem: 1d5c:1000 Physical Slot: 3 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- SERR- Reported-by: A Sh Tested-by: A Sh Cc: stable@vger.kernel.org --- drivers/usb/host/xhci-pci.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 8345d7c2306..dcb72f724d0 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -29,6 +29,7 @@ /* Device for a quirk */ #define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73 #define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000 +#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400 0x1400 #define PCI_VENDOR_ID_ETRON 0x1b6f #define PCI_DEVICE_ID_ASROCK_P67 0x7023 @@ -58,8 +59,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) /* Look for vendor-specific quirks */ if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && - pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) { - if (pdev->revision == 0x0) { + (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK || + pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1400)) { + if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK && + pdev->revision == 0x0) { xhci->quirks |= XHCI_RESET_EP_QUIRK; xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure" " endpoint cmd after reset endpoint\n"); -- cgit v1.2.3 From b0e4e606ff6ff26da0f60826e75577b56ba4e463 Mon Sep 17 00:00:00 2001 From: "Alexis R. Cortes" Date: Thu, 8 Nov 2012 16:59:27 -0600 Subject: usb: host: xhci: Stricter conditional for Z1 system models for Compliance Mode Patch This minor patch creates a more stricter conditional for the Z1 sytems for applying the Compliance Mode Patch, this to avoid the quirk to be applied to models that contain a "Z1" in their dmi product string but are different from Z1 systems. This patch should be backported to stable kernels as old as 3.2, that contain the commit 71c731a296f1b08a3724bd1b514b64f1bda87a23 "usb: host: xhci: Fix Compliance Mode on SN65LVPE502CP Hardware" Signed-off-by: Alexis R. Cortes Signed-off-by: Sarah Sharp Cc: stable@vger.kernel.org --- drivers/usb/host/xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 2e29f2f884c..09987d57934 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -480,7 +480,7 @@ static bool compliance_mode_recovery_timer_quirk_check(void) if (strstr(dmi_product_name, "Z420") || strstr(dmi_product_name, "Z620") || strstr(dmi_product_name, "Z820") || - strstr(dmi_product_name, "Z1")) + strstr(dmi_product_name, "Z1 Workstation")) return true; return false; -- cgit v1.2.3 From 77b847677e7cb633627a9ddaa7efbc3fa8586427 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 19 Oct 2012 10:55:16 +0300 Subject: usb: host: xhci: move HC_STATE_SUSPENDED check to xhci_suspend() that check will have to be done by all users of xhci_suspend() so it sounds a lot better to move the check to xhci_suspend() in order to avoid code duplication. Signed-off-by: Felipe Balbi Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-pci.c | 9 +-------- drivers/usb/host/xhci.c | 4 ++++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index dcb72f724d0..af259e0ec17 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -221,15 +221,8 @@ static void xhci_pci_remove(struct pci_dev *dev) static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); - int retval = 0; - if (hcd->state != HC_STATE_SUSPENDED || - xhci->shared_hcd->state != HC_STATE_SUSPENDED) - return -EINVAL; - - retval = xhci_suspend(xhci); - - return retval; + return xhci_suspend(xhci); } static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 09987d57934..5c72c431bab 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -880,6 +880,10 @@ int xhci_suspend(struct xhci_hcd *xhci) struct usb_hcd *hcd = xhci_to_hcd(xhci); u32 command; + if (hcd->state != HC_STATE_SUSPENDED || + xhci->shared_hcd->state != HC_STATE_SUSPENDED) + return -EINVAL; + spin_lock_irq(&xhci->lock); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); -- cgit v1.2.3 From 1ef43369c681bf30a980a4ba42df20514b15fdda Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 8 Nov 2012 11:08:50 -0800 Subject: ARM: OMAP4: TWL: mux sys_drm_msecure as output for PMIC On OMAP4 boards using the TWL6030 PMIC, the sys_drm_msecure is connected to the MSECURE input of the TWL6030 PMIC. This signal controls the secure-mode operation of the PMIC. If its not mux'd correctly, some functionality of the PMIC will not be accessible since the PMIC will be in secure mode. For example, if the TWL RTC is in secure mode, most of its registers are read-only, meaning (re)programming the RTC (e.g. for wakeup from suspend) will fail. To fix, ensure the signal is properly mux'd as output when TWL is intialized. This fix is required when using recent versions of u-boot (>= v2012.04.01) since u-boot is no longer setting the default mux for this pin. Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/twl-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 635e109f5ad..96cae8bdfc2 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -73,6 +73,7 @@ void __init omap4_pmic_init(const char *pmic_type, { /* PMIC part*/ omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE); + omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT); omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data); /* Register additional devices on i2c1 bus if needed */ -- cgit v1.2.3 From 2d4d07b97c0b774ea9ce2a2105818208d3df7241 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 24 Oct 2012 16:37:28 -0200 Subject: ARM: boot: Fix usage of kecho Since commit edc88ceb0 (ARM: be really quiet when building with 'make -s') the following output is generated when building a kernel for ARM: echo ' Kernel: arch/arm/boot/Image is ready' Kernel: arch/arm/boot/Image is ready Building modules, stage 2. echo ' Kernel: arch/arm/boot/zImage is ready' Kernel: arch/arm/boot/zImage is ready As per Documentation/kbuild/makefiles.txt the correct way of using kecho is '@$(kecho)'. Make this change so no more unwanted 'echo' messages are displayed. Signed-off-by: Fabio Estevam Signed-off-by: Arnd Bergmann --- arch/arm/boot/Makefile | 10 +++++----- arch/arm/tools/Makefile | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index f2aa09eb658..9137df539b6 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -33,7 +33,7 @@ ifeq ($(CONFIG_XIP_KERNEL),y) $(obj)/xipImage: vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' + @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' $(obj)/Image $(obj)/zImage: FORCE @echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)' @@ -48,14 +48,14 @@ $(obj)/xipImage: FORCE $(obj)/Image: vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' $(obj)/compressed/vmlinux: $(obj)/Image FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' endif @@ -90,7 +90,7 @@ fi $(obj)/uImage: $(obj)/zImage FORCE @$(check_for_multiple_loadaddr) $(call if_changed,uimage) - $(kecho) ' Image $@ is ready' + @$(kecho) ' Image $@ is ready' $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(Q)$(MAKE) $(build)=$(obj)/bootp $@ @@ -98,7 +98,7 @@ $(obj)/bootp/bootp: $(obj)/zImage initrd FORCE $(obj)/bootpImage: $(obj)/bootp/bootp FORCE $(call if_changed,objcopy) - $(kecho) ' Kernel: $@ is ready' + @$(kecho) ' Kernel: $@ is ready' PHONY += initrd FORCE initrd: diff --git a/arch/arm/tools/Makefile b/arch/arm/tools/Makefile index cd60a81163e..32d05c8219d 100644 --- a/arch/arm/tools/Makefile +++ b/arch/arm/tools/Makefile @@ -5,6 +5,6 @@ # include/generated/mach-types.h: $(src)/gen-mach-types $(src)/mach-types - $(kecho) ' Generating $@' + @$(kecho) ' Generating $@' @mkdir -p $(dir $@) $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; } -- cgit v1.2.3 From 6d1068b3a98519247d8ba4ec85cd40ac136dbdf9 Mon Sep 17 00:00:00 2001 From: Petr Matousek Date: Tue, 6 Nov 2012 19:24:07 +0100 Subject: KVM: x86: invalid opcode oops on SET_SREGS with OSXSAVE bit set (CVE-2012-4461) On hosts without the XSAVE support unprivileged local user can trigger oops similar to the one below by setting X86_CR4_OSXSAVE bit in guest cr4 register using KVM_SET_SREGS ioctl and later issuing KVM_RUN ioctl. invalid opcode: 0000 [#2] SMP Modules linked in: tun ip6table_filter ip6_tables ebtable_nat ebtables ... Pid: 24935, comm: zoog_kvm_monito Tainted: G D 3.2.0-3-686-pae EIP: 0060:[] EFLAGS: 00210246 CPU: 0 EIP is at kvm_arch_vcpu_ioctl_run+0x92a/0xd13 [kvm] EAX: 00000001 EBX: 000f387e ECX: 00000000 EDX: 00000000 ESI: 00000000 EDI: 00000000 EBP: ef5a0060 ESP: d7c63e70 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 Process zoog_kvm_monito (pid: 24935, ti=d7c62000 task=ed84a0c0 task.ti=d7c62000) Stack: 00000001 f70a1200 f8b940a9 ef5a0060 00000000 00200202 f8769009 00000000 ef5a0060 000f387e eda5c020 8722f9c8 00015bae 00000000 ed84a0c0 ed84a0c0 c12bf02d 0000ae80 ef7f8740 fffffffb f359b740 ef5a0060 f8b85dc1 0000ae80 Call Trace: [] ? kvm_arch_vcpu_ioctl_set_sregs+0x2fe/0x308 [kvm] ... [] ? syscall_call+0x7/0xb Code: 89 e8 e8 14 ee ff ff ba 00 00 04 00 89 e8 e8 98 48 ff ff 85 c0 74 1e 83 7d 48 00 75 18 8b 85 08 07 00 00 31 c9 8b 95 0c 07 00 00 <0f> 01 d1 c7 45 48 01 00 00 00 c7 45 1c 01 00 00 00 0f ae f0 89 EIP: [] kvm_arch_vcpu_ioctl_run+0x92a/0xd13 [kvm] SS:ESP 0068:d7c63e70 QEMU first retrieves the supported features via KVM_GET_SUPPORTED_CPUID and then sets them later. So guest's X86_FEATURE_XSAVE should be masked out on hosts without X86_FEATURE_XSAVE, making kvm_set_cr4 with X86_CR4_OSXSAVE fail. Userspaces that allow specifying guest cpuid with X86_FEATURE_XSAVE even on hosts that do not support it, might be susceptible to this attack from inside the guest as well. Allow setting X86_CR4_OSXSAVE bit only if host has XSAVE support. Signed-off-by: Petr Matousek Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/cpuid.h | 3 +++ arch/x86/kvm/x86.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index a10e4601685..58fc5148882 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -24,6 +24,9 @@ static inline bool guest_cpuid_has_xsave(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; + if (!static_cpu_has(X86_FEATURE_XSAVE)) + return 0; + best = kvm_find_cpuid_entry(vcpu, 1, 0); return best && (best->ecx & bit(X86_FEATURE_XSAVE)); } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 224a7e78cb6..4f7641756be 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5781,6 +5781,9 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, int pending_vec, max_bits, idx; struct desc_ptr dt; + if (!guest_cpuid_has_xsave(vcpu) && (sregs->cr4 & X86_CR4_OSXSAVE)) + return -EINVAL; + dt.size = sregs->idt.limit; dt.address = sregs->idt.base; kvm_x86_ops->set_idt(vcpu, &dt); -- cgit v1.2.3 From 5574f7745436d2014fcba1163f820d132e816c85 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sat, 10 Nov 2012 19:52:50 +0100 Subject: ASoC: cs4271: free allocated GPIO In case of probe deferral, the allocated GPIO line is not freed, which prevents it from being claimed and properly asserted in later attempts. Fix this by using devm_gpio_request(). Signed-off-by: Daniel Mack Reported-by: Michael Hirsch Cc: Alexander Sverdlin Signed-off-by: Mark Brown --- sound/soc/codecs/cs4271.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index f994af34f55..e3f0a7f3131 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -485,7 +485,7 @@ static int cs4271_probe(struct snd_soc_codec *codec) gpio_nreset = cs4271plat->gpio_nreset; if (gpio_nreset >= 0) - if (gpio_request(gpio_nreset, "CS4271 Reset")) + if (devm_gpio_request(codec->dev, gpio_nreset, "CS4271 Reset")) gpio_nreset = -EINVAL; if (gpio_nreset >= 0) { /* Reset codec */ @@ -535,15 +535,10 @@ static int cs4271_probe(struct snd_soc_codec *codec) static int cs4271_remove(struct snd_soc_codec *codec) { struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); - int gpio_nreset; - gpio_nreset = cs4271->gpio_nreset; - - if (gpio_is_valid(gpio_nreset)) { + if (gpio_is_valid(cs4271->gpio_nreset)) /* Set codec to the reset state */ - gpio_set_value(gpio_nreset, 0); - gpio_free(gpio_nreset); - } + gpio_set_value(cs4271->gpio_nreset, 0); return 0; }; -- cgit v1.2.3 From d2153a1595ee8235ecf9f9e2d1ac18eee373cbb5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 13 Nov 2012 10:44:54 +0300 Subject: ALSA: es1968: precedence bug in snd_es1968_tea575x_get_pins() I don't think this works as intended. '|' higher precedence than ?: so the bitwize OR "0 | (val & STR_MOST)" is a no-op. I have re-written it to be more clear. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/pci/es1968.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 50169bcfd90..7266020c16c 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -2581,9 +2581,14 @@ static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea) struct es1968 *chip = tea->private_data; unsigned long io = chip->io_port + GPIO_DATA; u16 val = inw(io); - - return (val & STR_DATA) ? TEA575X_DATA : 0 | - (val & STR_MOST) ? TEA575X_MOST : 0; + u8 ret; + + ret = 0; + if (val & STR_DATA) + ret |= TEA575X_DATA; + if (val & STR_MOST) + ret |= TEA575X_MOST; + return ret; } static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output) -- cgit v1.2.3 From 703fb94ec58e0e8769380c2877a8a34aeb5b6c97 Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Tue, 13 Nov 2012 08:52:24 +0100 Subject: xfrm: Fix the gc threshold value for ipv4 The xfrm gc threshold value depends on ip_rt_max_size. This value was set to INT_MAX with the routing cache removal patch, so we start doing garbage collecting when we have INT_MAX/2 IPsec routes cached. Fix this by going back to the static threshold of 1024 routes. Signed-off-by: Steffen Klassert --- include/net/xfrm.h | 2 +- net/ipv4/route.c | 2 +- net/ipv4/xfrm4_policy.c | 13 +------------ 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 6f0ba01afe7..63445ede48b 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1351,7 +1351,7 @@ struct xfrm6_tunnel { }; extern void xfrm_init(void); -extern void xfrm4_init(int rt_hash_size); +extern void xfrm4_init(void); extern int xfrm_state_init(struct net *net); extern void xfrm_state_fini(struct net *net); extern void xfrm4_state_init(void); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a8c651216fa..200d287e49f 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2597,7 +2597,7 @@ int __init ip_rt_init(void) pr_err("Unable to create route proc files\n"); #ifdef CONFIG_XFRM xfrm_init(); - xfrm4_init(ip_rt_max_size); + xfrm4_init(); #endif rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, NULL); diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 05c5ab8d983..3be0ac2c192 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -279,19 +279,8 @@ static void __exit xfrm4_policy_fini(void) xfrm_policy_unregister_afinfo(&xfrm4_policy_afinfo); } -void __init xfrm4_init(int rt_max_size) +void __init xfrm4_init(void) { - /* - * Select a default value for the gc_thresh based on the main route - * table hash size. It seems to me the worst case scenario is when - * we have ipsec operating in transport mode, in which we create a - * dst_entry per socket. The xfrm gc algorithm starts trying to remove - * entries at gc_thresh, and prevents new allocations as 2*gc_thresh - * so lets set an initial xfrm gc_thresh value at the rt_max_size/2. - * That will let us store an ipsec connection per route table entry, - * and start cleaning when were 1/2 full - */ - xfrm4_dst_ops.gc_thresh = rt_max_size/2; dst_entries_init(&xfrm4_dst_ops); xfrm4_state_init(); -- cgit v1.2.3 From d55c4c613fc4d4ad2ba0fc6fa2b57176d420f7e4 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 22 Oct 2012 15:49:02 +0200 Subject: s390/gup: add missing TASK_SIZE check to get_user_pages_fast() When walking page tables we need to make sure that everything is within bounds of the ASCE limit of the task's address space. Otherwise we might calculate e.g. a pud pointer which is not within a pud and dereference it. So check against TASK_SIZE (which is the ASCE limit) before walking page tables. Reviewed-by: Gerald Schaefer Cc: stable@vger.kernel.org Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/mm/gup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 8b8285310b5..16fb3c1615d 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -229,7 +229,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, addr = start; len = (unsigned long) nr_pages << PAGE_SHIFT; end = start + len; - if (end < start) + if ((end < start) || (end > TASK_SIZE)) goto slow_irqon; /* -- cgit v1.2.3 From 516bad44b9f3bdcb0be6be0252b7557bf7a149e4 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 22 Oct 2012 15:58:26 +0200 Subject: s390/gup: fix access_ok() usage in __get_user_pages_fast() access_ok() returns always "true" on s390. Therefore all access_ok() invocations are rather pointless. However when walking page tables we need to make sure that everything is within bounds of the ASCE limit of the task's address space. So remove the access_ok() call and add the same check we have in get_user_pages_fast(). Reviewed-by: Gerald Schaefer Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/mm/gup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 16fb3c1615d..1f5315d1215 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -180,8 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, addr = start; len = (unsigned long) nr_pages << PAGE_SHIFT; end = start + len; - if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, - (void __user *)start, len))) + if ((end < start) || (end > TASK_SIZE)) return 0; local_irq_save(flags); -- cgit v1.2.3 From 4bffbb3455372a26816e364fb4448810f7014452 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 8 Nov 2012 14:18:47 +0100 Subject: s390/mm: have 16 byte aligned struct pages Select HAVE_ALIGNED_STRUCT_PAGE on s390, so that the slub allocator can make use of compare and swap double for lockless updates. This increases the size of struct page to 64 bytes (instead of 56 bytes), however the performance gain justifies the increased size: - now excactly four struct pages fit into a single cache line; the case that accessing a struct page causes two cache line loads does not exist anymore. - calculating the offset of a struct page within the memmap array is only a simple shift instead of a more expensive multiplication. A "hackbench 200 process 200" run on a 32 cpu system did show an 8% runtime improvement. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 5dba755a43e..d385f396dfe 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -96,6 +96,7 @@ config S390 select HAVE_MEMBLOCK_NODE_MAP select HAVE_CMPXCHG_LOCAL select HAVE_CMPXCHG_DOUBLE + select HAVE_ALIGNED_STRUCT_PAGE if SLUB select HAVE_VIRT_CPU_ACCOUNTING select VIRT_CPU_ACCOUNTING select ARCH_DISCARD_MEMBLOCK -- cgit v1.2.3 From 2f4f649a69a9eb51f6e98130e19dd90a260a4145 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 12 Nov 2012 14:33:44 +0200 Subject: drm/i915: do not ignore eDP bpc settings from vbt There are laptops out there that need the eDP bpc from VBT. This is effectively a revert of commit 4344b813f105a19f793f1fd93ad775b784648b95 Author: Daniel Vetter Date: Fri Aug 10 11:10:20 2012 +0200 drm/i915: ignore eDP bpc settings from vbt but putting the VBT check after the EDID check to see them both in dmesg if this clamps more than the EDID. We have enough history with bpc clamping to warrant the extra debug info. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=47641 Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=56401 Signed-off-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 461a637f1ef..4154bcd7a07 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3841,6 +3841,17 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, } } + if (intel_encoder->type == INTEL_OUTPUT_EDP) { + /* Use VBT settings if we have an eDP panel */ + unsigned int edp_bpc = dev_priv->edp.bpp / 3; + + if (edp_bpc < display_bpc) { + DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); + display_bpc = edp_bpc; + } + continue; + } + /* * HDMI is either 12 or 8, so if the display lets 10bpc sneak * through, clamp it down. (Note: >12bpc will be caught below.) -- cgit v1.2.3 From 49bd665c5407a453736d3232ee58f2906b42e83c Mon Sep 17 00:00:00 2001 From: Maciej Patelczyk Date: Mon, 15 Oct 2012 14:29:03 +0200 Subject: [SCSI] isci: copy fis 0x34 response into proper buffer SATA MICROCODE DOWNALOAD fails on isci driver. After receiving Register Device to Host (FIS 0x34) frame Initiator resets phy. In the frame handler routine response (FIS 0x34) was copied into wrong buffer and upper layer did not receive any answer which resulted in timeout and reset. This patch corrects this bug. Signed-off-by: Maciej Patelczyk Signed-off-by: Lukasz Dorau Cc: Signed-off-by: James Bottomley --- drivers/scsi/isci/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index c1bafc3f3fb..9594ab62702 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -1972,7 +1972,7 @@ sci_io_request_frame_handler(struct isci_request *ireq, frame_index, (void **)&frame_buffer); - sci_controller_copy_sata_response(&ireq->stp.req, + sci_controller_copy_sata_response(&ireq->stp.rsp, frame_header, frame_buffer); -- cgit v1.2.3 From 225ae5fd9a320e22841410049c3bdb6cf14a5841 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 13 Nov 2012 10:41:50 +0100 Subject: MIPS: Malta: Fix interupt number of CBUS UART. The CBUS UART's interrupt number was wrong conflicting with the interrupt being tied to the Intel PIIX4. Since the PIIX4's interrupt is registered before the CBUS UART which is not being used on most systems this would not be noticed. Attempts to open the ttyS2 CBUS UART would result in: genirq: Flags mismatch irq 18. 00000000 (serial) vs. 00010000 (XT-PIC cascade) serial_link_irq_chain: request failed: -16 for irq: 18 Qemu was written to match the kernel so will need to be fixed also. Signed-off-by: Ralf Baechle --- arch/mips/mti-malta/malta-platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c index 80562b81f0f..74732177851 100644 --- a/arch/mips/mti-malta/malta-platform.c +++ b/arch/mips/mti-malta/malta-platform.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #define SMC_PORT(base, int) \ @@ -48,7 +49,7 @@ static struct plat_serial8250_port uart8250_data[] = { SMC_PORT(0x2F8, 3), { .mapbase = 0x1f000900, /* The CBUS UART */ - .irq = MIPS_CPU_IRQ_BASE + 2, + .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2, .uartclk = 3686400, /* Twice the usual clk! */ .iotype = UPIO_MEM32, .flags = CBUS_UART_FLAGS, -- cgit v1.2.3 From 9b2b1740e316a3e114974ffeb73b0ff630061b94 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 11 Nov 2012 10:29:40 +0800 Subject: pinctrl: spear: Staticize non-exported symbols They are not referenced outside of this file, make them static. Signed-off-by: Axel Lin Acked-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/pinctrl/spear/pinctrl-spear.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index f9483ae4272..11bd8722a00 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -144,9 +144,10 @@ static void spear_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, seq_printf(s, " " DRIVER_NAME); } -int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, unsigned *num_maps) +static int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np_config, + struct pinctrl_map **map, + unsigned *num_maps) { struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); struct device_node *np; @@ -191,8 +192,9 @@ int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, return 0; } -void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) +static void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, + struct pinctrl_map *map, + unsigned num_maps) { kfree(map); } -- cgit v1.2.3 From 90db8a145c3aa5a14fda6c587e53d7f15070b4ab Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 12 Nov 2012 10:01:56 +0800 Subject: pinctrl: mxs: Make PINCTRL_MXS select PINMUX && PINCONF Then we can remove "select PINMUX && PINCONF" from PINCTRL_IMX{23,28}. This simplifies the dependency. Signed-off-by: Axel Lin Acked-by: Shawn Guo Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 6d5a50bcabe..a274f073abd 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -100,17 +100,15 @@ config PINCTRL_MMP2 config PINCTRL_MXS bool + select PINMUX + select PINCONF config PINCTRL_IMX23 bool - select PINMUX - select PINCONF select PINCTRL_MXS config PINCTRL_IMX28 bool - select PINMUX - select PINCONF select PINCTRL_MXS config PINCTRL_NOMADIK -- cgit v1.2.3 From f0e3e35c9049087172c65302b42da8fe7ebb63a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Sat, 10 Nov 2012 10:13:42 +0100 Subject: USB: keyspan: fix typo causing GPF on open MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit f79b2d0f (USB: keyspan: fix NULL-pointer dereferences and memory leaks) had a small typo which made the driver use wrong offsets when mapping serial port private data. This results in in a GPF when the port is opened. Reported-by: Richard Cc: stable Signed-off-by: Bjørn Mork Acked-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/keyspan.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 7179b0c5f81..cff8dd5b462 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -2430,7 +2430,7 @@ static void keyspan_release(struct usb_serial *serial) static int keyspan_port_probe(struct usb_serial_port *port) { struct usb_serial *serial = port->serial; - struct keyspan_port_private *s_priv; + struct keyspan_serial_private *s_priv; struct keyspan_port_private *p_priv; const struct keyspan_device_details *d_details; struct callbacks *cback; @@ -2445,7 +2445,6 @@ static int keyspan_port_probe(struct usb_serial_port *port) if (!p_priv) return -ENOMEM; - s_priv = usb_get_serial_data(port->serial); p_priv->device_details = d_details; /* Setup values for the various callback routines */ -- cgit v1.2.3 From fcb21645f1bd86d2be29baf48aa1b298de52ccc7 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 8 Nov 2012 11:56:42 -0600 Subject: USB: option: add Novatel E362 and Dell Wireless 5800 USB IDs The Dell 5800 appears to be a simple rebrand of the Novatel E362. Signed-off-by: Dan Williams Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 5dee7d61241..c25d3fdf462 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -158,6 +158,7 @@ static void option_instat_callback(struct urb *urb); #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 +#define NOVATELWIRELESS_PRODUCT_E362 0x9010 #define NOVATELWIRELESS_PRODUCT_G1 0xA001 #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 #define NOVATELWIRELESS_PRODUCT_G2 0xA010 @@ -193,6 +194,9 @@ static void option_instat_callback(struct urb *urb); #define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 #define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 +#define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */ +#define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */ + #define KYOCERA_VENDOR_ID 0x0c88 #define KYOCERA_PRODUCT_KPC650 0x17da #define KYOCERA_PRODUCT_KPC680 0x180a @@ -706,6 +710,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, @@ -728,6 +733,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ + { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, -- cgit v1.2.3 From c0bc3098871dd9b964f6b45ec1e4d70d87811744 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 8 Nov 2012 11:56:53 -0600 Subject: USB: option: add Alcatel X220/X500D USB IDs Signed-off-by: Dan Williams Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index c25d3fdf462..edc64bb6f45 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -287,6 +287,7 @@ static void option_instat_callback(struct urb *urb); /* ALCATEL PRODUCTS */ #define ALCATEL_VENDOR_ID 0x1bbb #define ALCATEL_PRODUCT_X060S_X200 0x0000 +#define ALCATEL_PRODUCT_X220_X500D 0x0017 #define PIRELLI_VENDOR_ID 0x1266 #define PIRELLI_PRODUCT_C100_1 0x1002 @@ -1164,6 +1165,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), -- cgit v1.2.3 From 9f488ba8633fe77910ea0ba80ec762d9c34af1b6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 13 Nov 2012 10:46:33 -0800 Subject: IIO: fix build error in lp8788-charger.c Turns out that consumer.h needs to include types.h on some platforms to build properly (like powerpc). Reported-by: Stephen Rothwell Cc: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- include/linux/iio/consumer.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index 126c0a9375f..16c35ac045b 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -9,6 +9,8 @@ */ #ifndef _IIO_INKERN_CONSUMER_H_ #define _IIO_INKERN_CONSUMER_H_ + +#include #include struct iio_dev; -- cgit v1.2.3 From e592c5d0b7db94b485b4a2342db041a1882b7f75 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 13 Nov 2012 10:52:52 -0800 Subject: Revert "USB/host: Cleanup unneccessary irq disable code" This reverts commit 73d4066055e0e2830533041f4b91df8e6e5976ff. Martin Steigerwald reported that this change caused a hard lockup when using USB if threadirqs are enabled. Thomas pointed out that this patch is incorrect, and can cause problems. So revert it to get the previously working functionality back. Reported-by: Martin Steigerwald Cc: Thomas Gleixner Cc: Chuansheng Liu Cc: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 16 ++++++++++++++++ drivers/usb/host/ehci-ls1x.c | 2 +- drivers/usb/host/ohci-xls.c | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 1e741bca026..f034716190f 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2151,8 +2151,15 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum); irqreturn_t usb_hcd_irq (int irq, void *__hcd) { struct usb_hcd *hcd = __hcd; + unsigned long flags; irqreturn_t rc; + /* IRQF_DISABLED doesn't work correctly with shared IRQs + * when the first handler doesn't use it. So let's just + * assume it's never used. + */ + local_irq_save(flags); + if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) rc = IRQ_NONE; else if (hcd->driver->irq(hcd) == IRQ_NONE) @@ -2160,6 +2167,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) else rc = IRQ_HANDLED; + local_irq_restore(flags); return rc; } EXPORT_SYMBOL_GPL(usb_hcd_irq); @@ -2347,6 +2355,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd, int retval; if (hcd->driver->irq) { + + /* IRQF_DISABLED doesn't work as advertised when used together + * with IRQF_SHARED. As usb_hcd_irq() will always disable + * interrupts we can remove it here. + */ + if (irqflags & IRQF_SHARED) + irqflags &= ~IRQF_DISABLED; + snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", hcd->driver->description, hcd->self.busnum); retval = request_irq(irqnum, &usb_hcd_irq, irqflags, diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c index ca759652626..aa0f328922d 100644 --- a/drivers/usb/host/ehci-ls1x.c +++ b/drivers/usb/host/ehci-ls1x.c @@ -113,7 +113,7 @@ static int ehci_hcd_ls1x_probe(struct platform_device *pdev) goto err_put_hcd; } - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (ret) goto err_put_hcd; diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c index 84201cd1a47..41e378f17c6 100644 --- a/drivers/usb/host/ohci-xls.c +++ b/drivers/usb/host/ohci-xls.c @@ -56,7 +56,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver, goto err3; } - retval = usb_add_hcd(hcd, irq, IRQF_SHARED); + retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); if (retval != 0) goto err4; return retval; -- cgit v1.2.3 From 60e3bf14d4e2a9fcc11c2fc33f572bfafa8ece92 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 20 Oct 2012 07:46:02 +0300 Subject: clocksource: clean up parse_pmtmr() I changed the strict_strtoul() to kstrtouint(). That has the check for UINT_MAX built in to it so the ifdefs can be removed. Also I changed a printk() to pr_info(). Signed-off-by: Dan Carpenter Signed-off-by: John Stultz --- drivers/clocksource/acpi_pm.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 6b5cf02c35c..5d1b9268bca 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -233,16 +233,15 @@ fs_initcall(init_acpi_pm_clocksource); */ static int __init parse_pmtmr(char *arg) { - unsigned long base; + unsigned int base; + int ret; - if (strict_strtoul(arg, 16, &base)) - return -EINVAL; -#ifdef CONFIG_X86_64 - if (base > UINT_MAX) - return -ERANGE; -#endif - printk(KERN_INFO "PMTMR IOPort override: 0x%04x -> 0x%04lx\n", - pmtmr_ioport, base); + ret = kstrtouint(arg, 16, &base); + if (ret) + return ret; + + pr_info("PMTMR IOPort override: 0x%04x -> 0x%04x\n", pmtmr_ioport, + base); pmtmr_ioport = base; return 1; -- cgit v1.2.3 From f95a985781e9e986992351c971af7f7e46e06ed5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 18 Oct 2012 11:34:41 +0200 Subject: time/jiffies: Make clocksource_jiffies static Commit f1b8274 ("clocksource: Cleanup clocksource selection") removed all external references to clocksource_jiffies so there is no need to have the symbol globally visible. Fixes the following sparse warning: CHECK kernel/time/jiffies.c kernel/time/jiffies.c:61:20: warning: symbol 'clocksource_jiffies' was not declared. Should it be static? Signed-off-by: Lars-Peter Clausen Signed-off-by: John Stultz --- kernel/time/jiffies.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c index 6629bf7b528..25f5b2699d3 100644 --- a/kernel/time/jiffies.c +++ b/kernel/time/jiffies.c @@ -58,7 +58,7 @@ static cycle_t jiffies_read(struct clocksource *cs) return (cycle_t) jiffies; } -struct clocksource clocksource_jiffies = { +static struct clocksource clocksource_jiffies = { .name = "jiffies", .rating = 1, /* lowest valid rating*/ .read = jiffies_read, -- cgit v1.2.3 From 980097b36074596c76c1367a9e7b70ec8583d55b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 29 Oct 2012 15:24:18 +0100 Subject: clocksource: arm_generic: use integer math helpers This will make the two crucial integer divisions in the generic ARM arch timer used for ARMv8 use the kernel DIV_ROUND_CLOSEST() helper inline from so they get more precise. Cc: Marc Zyngier Cc: Catalin Marinas Signed-off-by: Linus Walleij Signed-off-by: John Stultz --- drivers/clocksource/arm_generic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/arm_generic.c b/drivers/clocksource/arm_generic.c index c4d9f9566c6..6cd1b30e01a 100644 --- a/drivers/clocksource/arm_generic.c +++ b/drivers/clocksource/arm_generic.c @@ -127,7 +127,7 @@ static void __init arch_timer_calibrate(void) /* Cache the sched_clock multiplier to save a divide in the hot path. */ - sched_clock_mult = NSEC_PER_SEC / arch_timer_rate; + sched_clock_mult = DIV_ROUND_CLOSEST(NSEC_PER_SEC, arch_timer_rate); pr_info("Architected local timer running at %u.%02uMHz.\n", arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100); @@ -221,7 +221,7 @@ int __init arm_generic_timer_init(void) clocksource_register_hz(&clocksource_counter, arch_timer_rate); /* Calibrate the delay loop directly */ - lpj_fine = arch_timer_rate / HZ; + lpj_fine = DIV_ROUND_CLOSEST(arch_timer_rate, HZ); /* Immediately configure the timer on the boot CPU */ arch_timer_setup(per_cpu_ptr(&arch_timer_evt, smp_processor_id())); -- cgit v1.2.3 From 47c8c91b2d60006df22146effe79ac4cdafd9205 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Tue, 13 Nov 2012 09:53:14 +0800 Subject: clocksource: arm_generic: use this_cpu_ptr per-cpu helper Utilize this_cpu_ptr() instead of per_cpu_ptr(...,smp_processor_id()) Signed-off-by: Shan Wei Reviewed-by: Christoph Lameter Signed-off-by: John Stultz --- drivers/clocksource/arm_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clocksource/arm_generic.c b/drivers/clocksource/arm_generic.c index 6cd1b30e01a..c210f4f1ecf 100644 --- a/drivers/clocksource/arm_generic.c +++ b/drivers/clocksource/arm_generic.c @@ -224,7 +224,7 @@ int __init arm_generic_timer_init(void) lpj_fine = DIV_ROUND_CLOSEST(arch_timer_rate, HZ); /* Immediately configure the timer on the boot CPU */ - arch_timer_setup(per_cpu_ptr(&arch_timer_evt, smp_processor_id())); + arch_timer_setup(this_cpu_ptr(&arch_timer_evt)); register_cpu_notifier(&arch_timer_cpu_nb); -- cgit v1.2.3 From d6ad418763888f617ac5b4849823e4cd670df1dd Mon Sep 17 00:00:00 2001 From: John Stultz Date: Tue, 28 Feb 2012 16:50:11 -0800 Subject: time: Kill xtime_lock, replacing it with jiffies_lock Now that timekeeping is protected by its own locks, rename the xtime_lock to jifffies_lock to better describe what it protects. CC: Thomas Gleixner CC: Eric Dumazet CC: Richard Cochran Signed-off-by: John Stultz --- drivers/clocksource/i8253.c | 2 +- include/linux/jiffies.h | 3 ++- kernel/time/jiffies.c | 6 ++++-- kernel/time/tick-common.c | 8 ++++---- kernel/time/tick-internal.h | 1 - kernel/time/tick-sched.c | 22 +++++++++++----------- kernel/time/timekeeping.c | 14 +++----------- 7 files changed, 25 insertions(+), 31 deletions(-) diff --git a/drivers/clocksource/i8253.c b/drivers/clocksource/i8253.c index e7cab2da910..14ee3efcc40 100644 --- a/drivers/clocksource/i8253.c +++ b/drivers/clocksource/i8253.c @@ -35,7 +35,7 @@ static cycle_t i8253_read(struct clocksource *cs) raw_spin_lock_irqsave(&i8253_lock, flags); /* - * Although our caller may have the read side of xtime_lock, + * Although our caller may have the read side of jiffies_lock, * this is now a seqlock, and we are cheating in this routine * by having side effects on state that we cannot undo if * there is a collision on the seqlock and our caller has to diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index 6b87413da9d..82ed068b1eb 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h @@ -70,11 +70,12 @@ extern int register_refined_jiffies(long clock_tick_rate); /* * The 64-bit value is not atomic - you MUST NOT read it - * without sampling the sequence number in xtime_lock. + * without sampling the sequence number in jiffies_lock. * get_jiffies_64() will do this for you as appropriate. */ extern u64 __jiffy_data jiffies_64; extern unsigned long volatile __jiffy_data jiffies; +extern seqlock_t jiffies_lock; #if (BITS_PER_LONG < 64) u64 get_jiffies_64(void); diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c index 25f5b2699d3..7a925ba456f 100644 --- a/kernel/time/jiffies.c +++ b/kernel/time/jiffies.c @@ -67,6 +67,8 @@ static struct clocksource clocksource_jiffies = { .shift = JIFFIES_SHIFT, }; +__cacheline_aligned_in_smp DEFINE_SEQLOCK(jiffies_lock); + #if (BITS_PER_LONG < 64) u64 get_jiffies_64(void) { @@ -74,9 +76,9 @@ u64 get_jiffies_64(void) u64 ret; do { - seq = read_seqbegin(&xtime_lock); + seq = read_seqbegin(&jiffies_lock); ret = jiffies_64; - } while (read_seqretry(&xtime_lock, seq)); + } while (read_seqretry(&jiffies_lock, seq)); return ret; } EXPORT_SYMBOL(get_jiffies_64); diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index da6c9ecad4e..b1600a6973f 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -63,13 +63,13 @@ int tick_is_oneshot_available(void) static void tick_periodic(int cpu) { if (tick_do_timer_cpu == cpu) { - write_seqlock(&xtime_lock); + write_seqlock(&jiffies_lock); /* Keep track of the next tick event */ tick_next_period = ktime_add(tick_next_period, tick_period); do_timer(1); - write_sequnlock(&xtime_lock); + write_sequnlock(&jiffies_lock); } update_process_times(user_mode(get_irq_regs())); @@ -130,9 +130,9 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast) ktime_t next; do { - seq = read_seqbegin(&xtime_lock); + seq = read_seqbegin(&jiffies_lock); next = tick_next_period; - } while (read_seqretry(&xtime_lock, seq)); + } while (read_seqretry(&jiffies_lock, seq)); clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT); diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index 4e265b901fe..cf3e59ed6dc 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h @@ -141,4 +141,3 @@ static inline int tick_device_is_functional(struct clock_event_device *dev) #endif extern void do_timer(unsigned long ticks); -extern seqlock_t xtime_lock; diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index a4026088526..a678046c3e5 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -31,7 +31,7 @@ static DEFINE_PER_CPU(struct tick_sched, tick_cpu_sched); /* - * The time, when the last jiffy update happened. Protected by xtime_lock. + * The time, when the last jiffy update happened. Protected by jiffies_lock. */ static ktime_t last_jiffies_update; @@ -49,14 +49,14 @@ static void tick_do_update_jiffies64(ktime_t now) ktime_t delta; /* - * Do a quick check without holding xtime_lock: + * Do a quick check without holding jiffies_lock: */ delta = ktime_sub(now, last_jiffies_update); if (delta.tv64 < tick_period.tv64) return; - /* Reevalute with xtime_lock held */ - write_seqlock(&xtime_lock); + /* Reevalute with jiffies_lock held */ + write_seqlock(&jiffies_lock); delta = ktime_sub(now, last_jiffies_update); if (delta.tv64 >= tick_period.tv64) { @@ -79,7 +79,7 @@ static void tick_do_update_jiffies64(ktime_t now) /* Keep the tick_next_period variable up to date */ tick_next_period = ktime_add(last_jiffies_update, tick_period); } - write_sequnlock(&xtime_lock); + write_sequnlock(&jiffies_lock); } /* @@ -89,12 +89,12 @@ static ktime_t tick_init_jiffy_update(void) { ktime_t period; - write_seqlock(&xtime_lock); + write_seqlock(&jiffies_lock); /* Did we start the jiffies update yet ? */ if (last_jiffies_update.tv64 == 0) last_jiffies_update = tick_next_period; period = last_jiffies_update; - write_sequnlock(&xtime_lock); + write_sequnlock(&jiffies_lock); return period; } @@ -282,11 +282,11 @@ static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts, /* Read jiffies and the time when jiffies were updated last */ do { - seq = read_seqbegin(&xtime_lock); + seq = read_seqbegin(&jiffies_lock); last_update = last_jiffies_update; last_jiffies = jiffies; time_delta = timekeeping_max_deferment(); - } while (read_seqretry(&xtime_lock, seq)); + } while (read_seqretry(&jiffies_lock, seq)); if (rcu_needs_cpu(cpu, &rcu_delta_jiffies) || printk_needs_cpu(cpu) || arch_needs_cpu(cpu)) { @@ -658,7 +658,7 @@ static void tick_nohz_handler(struct clock_event_device *dev) * concurrency: This happens only when the cpu in charge went * into a long sleep. If two cpus happen to assign themself to * this duty, then the jiffies update is still serialized by - * xtime_lock. + * jiffies_lock. */ if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) tick_do_timer_cpu = cpu; @@ -810,7 +810,7 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer) * concurrency: This happens only when the cpu in charge went * into a long sleep. If two cpus happen to assign themself to * this duty, then the jiffies update is still serialized by - * xtime_lock. + * jiffies_lock. */ if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE)) tick_do_timer_cpu = cpu; diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index e424970bb56..4c7de02eacd 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -25,12 +25,6 @@ static struct timekeeper timekeeper; -/* - * This read-write spinlock protects us from races in SMP while - * playing with xtime. - */ -__cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); - /* flag for if timekeeping is suspended */ int __read_mostly timekeeping_suspended; @@ -1299,9 +1293,7 @@ struct timespec get_monotonic_coarse(void) } /* - * The 64-bit jiffies value is not atomic - you MUST NOT read it - * without sampling the sequence number in xtime_lock. - * jiffies is defined in the linker script... + * Must hold jiffies_lock */ void do_timer(unsigned long ticks) { @@ -1389,7 +1381,7 @@ EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset); */ void xtime_update(unsigned long ticks) { - write_seqlock(&xtime_lock); + write_seqlock(&jiffies_lock); do_timer(ticks); - write_sequnlock(&xtime_lock); + write_sequnlock(&jiffies_lock); } -- cgit v1.2.3 From 4ecd6228acc8c3bb5c7d18bae57ce13685936e6d Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Mon, 5 Nov 2012 13:19:40 +0800 Subject: staging: comedi: jr3_pci: return 'result' from comedi_pci_enable instead of -EIO Fix a smatch warning: drivers/staging/comedi/drivers/jr3_pci.c:793 jr3_pci_auto_attach() info: why not propagate 'result' from comedi_pci_enable() instead of -5? CC: Fengguang Wu Signed-off-by: Yuanhan Liu Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/jr3_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 364541d0f47..69f151d62f3 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -703,7 +703,7 @@ static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, result = comedi_pci_enable(pcidev, "jr3_pci"); if (result < 0) - return -EIO; + return result; dev->iobase = 1; /* the "detach" needs this */ devpriv->iobase = ioremap(pci_resource_start(pcidev, 0), -- cgit v1.2.3 From 9e4edd5794c94463bc0dfb0552cf6bba11b19bcc Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sat, 3 Nov 2012 22:38:34 +0900 Subject: staging/comedi: fix the spaces issue around that '=' in drivers/ni_670x.c fixed below checkpatch error. - ERROR: spaces required around that '=' (ctx:WxV) Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_670x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 36462d582e4..7a72131b935 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -322,7 +322,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = { MODULE_DEVICE_TABLE(pci, ni_670x_pci_table); static struct pci_driver ni_670x_pci_driver = { - .name ="ni_670x", + .name = "ni_670x", .id_table = ni_670x_pci_table, .probe = ni_670x_pci_probe, .remove = __devexit_p(ni_670x_pci_remove), -- cgit v1.2.3 From e45244b73f09b2b13044603c6647d14b15e692f2 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sat, 3 Nov 2012 22:40:13 +0900 Subject: staging/comedi: Use dev_ printks in drivers/comedi_fc.c fixed below checkpatch warning. - WARNING: Prefer netdev_warn(netdev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_fc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/comedi_fc.c b/drivers/staging/comedi/drivers/comedi_fc.c index 63be619dd60..83728298eef 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.c +++ b/drivers/staging/comedi/drivers/comedi_fc.c @@ -53,7 +53,7 @@ unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd, retval = comedi_buf_write_alloc(async, num_bytes); if (retval != num_bytes) { - printk(KERN_WARNING "comedi: buffer overrun\n"); + dev_warn(subd->device->class_dev, "comedi: buffer overrun\n"); async->events |= COMEDI_CB_OVERFLOW; return 0; } -- cgit v1.2.3 From 3b8e2de347e5d52cc005c5becc2a13c38115c8ad Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 09:56:55 -0700 Subject: staging: comedi: addi_apci_3501: remove i_APCI3501_ConfigDigitalOutput() This function is the digital output subdevice 'insn_config' operation. It does not follow the comedi API and the digital output channels on this board are not configurable. Just remove this broken function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3501.c | 46 ---------------------- drivers/staging/comedi/drivers/addi_apci_3501.c | 1 - 2 files changed, 47 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c index c92ec8fc932..0f03c6e9ffb 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c @@ -131,52 +131,6 @@ static int i_APCI3501_ReadDigitalInput(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI3501_ConfigDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Configures The Digital Output Subdevice. | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| | -| data[1] : 1 Enable VCC Interrupt | -| 0 Disable VCC Interrupt | -| data[2] : 1 Enable CC Interrupt | -| 0 Disable CC Interrupt | -| | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Not a valid Data !!! ,Data should be 1 or 0\n"); - return -EINVAL; - } /* if ( (data[0]!=0) && (data[0]!=1) ) */ - if (data[0]) { - devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; - } /* if (data[0]) */ - else { - devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; - } /* else if (data[0]) */ - return insn->n; -} - /* +----------------------------------------------------------------------------+ | Function Name : int i_APCI3501_WriteDigitalOutput | diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 14ee4e0c5a9..c86f31e5859 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -28,7 +28,6 @@ static const struct addi_board apci3501_boardtypes[] = { .ao_config = i_APCI3501_ConfigAnalogOutput, .ao_write = i_APCI3501_WriteAnalogOutput, .di_bits = i_APCI3501_ReadDigitalInput, - .do_config = i_APCI3501_ConfigDigitalOutput, .do_write = i_APCI3501_WriteDigitalOutput, .do_bits = i_APCI3501_ReadDigitalOutput, .timer_config = i_APCI3501_ConfigTimerCounterWatchdog, -- cgit v1.2.3 From 272b6b04e7fcc3b045050ffc595a4655425b0c24 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 09:58:02 -0700 Subject: staging: comedi: addi_apci_3501: fix digital input 'insn_bits' function This driver does not follow the comedi API. The digital input 'insn_bits' function is supposed to return the status of all the input channels in data[1]. Currently this driver uses the data[0] value passed to the function to determine if a single input channel status is requested or the status of all the input channels. Fix the function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' function for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3501.c | 45 +++------------------- drivers/staging/comedi/drivers/addi_apci_3501.c | 2 +- 2 files changed, 6 insertions(+), 41 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c index 0f03c6e9ffb..5408f0720c9 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c @@ -84,50 +84,15 @@ static struct comedi_lrange range_apci3501_ao = { } }; -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI3501_ReadDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI3501_ReadDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci3501_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_Temp; - unsigned int ui_NoOfChannel; - ui_NoOfChannel = CR_CHAN(insn->chanspec); - ui_Temp = data[0]; - *data = inl(devpriv->iobase + APCI3501_DIGITAL_IP); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { + data[1] = inl(devpriv->iobase + APCI3501_DIGITAL_IP) & 0x3; - *data = *data & 0x3; - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* elseif (ui_Temp==1) */ - } /* elseif (ui_Temp==0) */ return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index c86f31e5859..6477416ff51 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -27,7 +27,7 @@ static const struct addi_board apci3501_boardtypes[] = { .reset = i_APCI3501_Reset, .ao_config = i_APCI3501_ConfigAnalogOutput, .ao_write = i_APCI3501_WriteAnalogOutput, - .di_bits = i_APCI3501_ReadDigitalInput, + .di_bits = apci3501_di_insn_bits, .do_write = i_APCI3501_WriteDigitalOutput, .do_bits = i_APCI3501_ReadDigitalOutput, .timer_config = i_APCI3501_ConfigTimerCounterWatchdog, -- cgit v1.2.3 From 141dcc33c037b7e520ba305caaafbbb39db9e962 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 09:59:32 -0700 Subject: staging: comedi: addi_apci_3501: fix digital output 'insn_bits' function This driver does not follow the comedi API. The digital output 'insn_bits' function is passed a mask value in data[0] indicating which output bits in data[1] are changing. The function is then supposed to update the outputs accordingly and then return the current state of the outputs in data[1]. Currently this driver uses the 'insn_write' function to update either a single output channel or all the channels and the 'insn_bits' function to read the state of either a single channel or all the channels. Fix the 'insn_bits' function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' and 'insn_write' functions for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3501.c | 148 +++------------------ drivers/staging/comedi/drivers/addi_apci_3501.c | 3 +- 2 files changed, 16 insertions(+), 135 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c index 5408f0720c9..7a18ce704ba 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c @@ -96,143 +96,25 @@ static int apci3501_di_insn_bits(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI3501_WriteDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : writes To the digital Output Subdevice | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s : Subdevice Pointer | -| struct comedi_insn *insn : Insn Structure Pointer | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci3501_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_Temp, ui_Temp1; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ + unsigned int mask = data[0]; + unsigned int bits = data[1]; - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = inl(devpriv->iobase + APCI3501_DIGITAL_OP); - } /* if(devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* if(devpriv->b_OutputMemoryStatus ) */ - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outl(data[0], devpriv->iobase + APCI3501_DIGITAL_OP); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - data[0] = (data[0] << (2 * data[2])) | ui_Temp; - outl(data[0], - devpriv->iobase + APCI3501_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - (data[0] << ui_NoOfChannel) ^ - 0xffffffff; - data[0] = data[0] & ui_Temp; - outl(data[0], - devpriv->iobase + APCI3501_DIGITAL_OP); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data[2])) ^ - 0xffffffff) & ui_Temp; - outl(data[0], - devpriv->iobase + - APCI3501_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* if else data[3]==1) */ - } /* if else data[3]==0) */ - return insn->n; -} + s->state = inl(devpriv->iobase + APCI3501_DIGITAL_OP); + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); + + outl(s->state, devpriv->iobase + APCI3501_DIGITAL_OP); + } + + data[1] = s->state; -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI3501_ReadDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Temp; - unsigned int ui_NoOfChannel; - - ui_NoOfChannel = CR_CHAN(insn->chanspec); - ui_Temp = data[0]; - *data = inl(devpriv->iobase + APCI3501_DIGITAL_OP); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - *data = *data & 0x3; - - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* else if (ui_Temp==1) */ - } /* else if (ui_Temp==0) */ return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 6477416ff51..b7899488df0 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -28,8 +28,7 @@ static const struct addi_board apci3501_boardtypes[] = { .ao_config = i_APCI3501_ConfigAnalogOutput, .ao_write = i_APCI3501_WriteAnalogOutput, .di_bits = apci3501_di_insn_bits, - .do_write = i_APCI3501_WriteDigitalOutput, - .do_bits = i_APCI3501_ReadDigitalOutput, + .do_bits = apci3501_do_insn_bits, .timer_config = i_APCI3501_ConfigTimerCounterWatchdog, .timer_write = i_APCI3501_StartStopWriteTimerCounterWatchdog, .timer_read = i_APCI3501_ReadTimerCounterWatchdog, -- cgit v1.2.3 From 10f71c7845686b7f93113f1fe6dbc3718d8a8673 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:01:26 -0700 Subject: staging: comedi: addi_apci_3xxx: fix digital input 'insn_bits' function This driver does not follow the comedi API. The digital input 'insn_bits' function is supposed to return the status of all the input channels in data[1]. Currently this function is returning the status in data[0]. It is also unnecessarily testing the size of the return buffer. Fix the function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' function for individual channels. This allows removing the i_APCI3XXX_InsnReadDigitalInput() function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3xxx.c | 115 ++------------------- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 42 +++----- 2 files changed, 20 insertions(+), 137 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c index d1b0ee6b628..5d3570c8a1c 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c @@ -1276,119 +1276,16 @@ static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev, return i_ReturnValue; } -/* -+----------------------------------------------------------------------------+ -| DIGITAL INPUT SUBDEVICE | -+----------------------------------------------------------------------------+ -*/ - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3XXX_InsnReadDigitalInput | -| (struct comedi_device *dev, | -| struct comedi_subdevice *s, | -| struct comedi_insn *insn, | -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Reads the value of the specified Digital input channel | -+----------------------------------------------------------------------------+ -| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) | -+----------------------------------------------------------------------------+ -| Output Parameters : data[0] : Channel value | -+----------------------------------------------------------------------------+ -| Return Value : 0 : No error | -| -3 : Channel selection error | -| -101 : Data size error | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - int i_ReturnValue = insn->n; - unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec); - unsigned int dw_Temp = 0; - - /***************************/ - /* Test the channel number */ - /***************************/ - - if (b_Channel <= devpriv->s_EeParameters.i_NbrDiChannel) { - /************************/ - /* Test the buffer size */ - /************************/ - - if (insn->n >= 1) { - dw_Temp = inl(devpriv->iobase + 32); - *data = (dw_Temp >> b_Channel) & 1; - } else { - /*******************/ - /* Data size error */ - /*******************/ - - printk("Buffer size error\n"); - i_ReturnValue = -101; - } - } else { - /***************************/ - /* Channel selection error */ - /***************************/ - - printk("Channel selection error\n"); - i_ReturnValue = -3; - } - - return i_ReturnValue; -} - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3XXX_InsnBitsDigitalInput | -| (struct comedi_device *dev, | -| struct comedi_subdevice *s, | -| struct comedi_insn *insn, | -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Reads the value of the Digital input Port i.e.4channels| -+----------------------------------------------------------------------------+ -| Input Parameters : - | -+----------------------------------------------------------------------------+ -| Output Parameters : data[0] : Port value | -+----------------------------------------------------------------------------+ -| Return Value :>0: No error | -| .... | -| -101 : Data size error | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci3xxx_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - int i_ReturnValue = insn->n; - unsigned int dw_Temp = 0; - /************************/ - /* Test the buffer size */ - /************************/ + data[1] = inl(devpriv->iobase + 32) & 0xf; - if (insn->n >= 1) { - dw_Temp = inl(devpriv->iobase + 32); - *data = dw_Temp & 0xf; - } else { - /*******************/ - /* Data size error */ - /*******************/ - - printk("Buffer size error\n"); - i_ReturnValue = -101; - } - - return i_ReturnValue; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index 00c972e140f..d0cd2e8544b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -190,8 +190,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .reset = i_APCI3XXX_Reset, .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -224,8 +223,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .reset = i_APCI3XXX_Reset, .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -258,8 +256,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .reset = i_APCI3XXX_Reset, .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -292,8 +289,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .reset = i_APCI3XXX_Reset, .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -326,8 +322,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .reset = i_APCI3XXX_Reset, .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -360,8 +355,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .reset = i_APCI3XXX_Reset, .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -518,8 +512,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -556,8 +549,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -594,8 +586,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -632,8 +623,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -664,8 +654,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .reset = i_APCI3XXX_Reset, .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -692,8 +681,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .reset = i_APCI3XXX_Reset, .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -720,8 +708,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .reset = i_APCI3XXX_Reset, .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, @@ -748,8 +735,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .reset = i_APCI3XXX_Reset, .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, - .di_read = i_APCI3XXX_InsnReadDigitalInput, - .di_bits = i_APCI3XXX_InsnBitsDigitalInput, + .di_bits = apci3xxx_di_insn_bits, .do_write = i_APCI3XXX_InsnWriteDigitalOutput, .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, .do_read = i_APCI3XXX_InsnReadDigitalOutput, -- cgit v1.2.3 From 2b70a4f4f97b70e8cd9d8a16983758aa4fc3450b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:02:16 -0700 Subject: staging: comedi: addi_apci_3xxx: fix digital output 'insn_bits' function This driver does not follow the comedi API. The digital output 'insn_bits' function is passed a mask value in data[0] indicating which output bits in data[1] are changing. The function is then supposed to update the outputs accordingly and then return the current state of the outputs in data[1]. Fix the 'insn_bits' function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' and 'insn_write' functions for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3xxx.c | 257 ++------------------- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 56 ++--- 2 files changed, 27 insertions(+), 286 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c index 5d3570c8a1c..a45a2a26e0d 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c @@ -1288,257 +1288,26 @@ static int apci3xxx_di_insn_bits(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| DIGITAL OUTPUT SUBDEVICE | -+----------------------------------------------------------------------------+ - -*/ - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3XXX_InsnBitsDigitalOutput | -| (struct comedi_device *dev, | -| struct comedi_subdevice *s, | -| struct comedi_insn *insn, | -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Write the selected output mask and read the status from| -| all digital output channles | -+----------------------------------------------------------------------------+ -| Input Parameters : dw_ChannelMask = data [0]; | -| dw_BitMask = data [1]; | -+----------------------------------------------------------------------------+ -| Output Parameters : data[1] : All digital output channles states | -+----------------------------------------------------------------------------+ -| Return Value : >0 : No error | -| -4 : Channel mask error | -| -101 : Data size error | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - int i_ReturnValue = insn->n; - unsigned char b_ChannelCpt = 0; - unsigned int dw_ChannelMask = 0; - unsigned int dw_BitMask = 0; - unsigned int dw_Status = 0; - - /************************/ - /* Test the buffer size */ - /************************/ - - if (insn->n >= 2) { - /*******************************/ - /* Get the channe and bit mask */ - /*******************************/ - - dw_ChannelMask = data[0]; - dw_BitMask = data[1]; - - /*************************/ - /* Test the channel mask */ - /*************************/ - - if ((dw_ChannelMask & 0XFFFFFFF0) == 0) { - /*********************************/ - /* Test if set/reset any channel */ - /*********************************/ - - if (dw_ChannelMask & 0xF) { - /********************************/ - /* Read the digital output port */ - /********************************/ - - dw_Status = inl(devpriv->iobase + 48); - - for (b_ChannelCpt = 0; b_ChannelCpt < 4; - b_ChannelCpt++) { - if ((dw_ChannelMask >> b_ChannelCpt) & - 1) { - dw_Status = - (dw_Status & (0xF - - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt)); - } - } - - outl(dw_Status, devpriv->iobase + 48); - } - - /********************************/ - /* Read the digital output port */ - /********************************/ - - data[1] = inl(devpriv->iobase + 48); - } else { - /************************/ - /* Config command error */ - /************************/ - - printk("Channel mask error\n"); - i_ReturnValue = -4; - } - } else { - /*******************/ - /* Data size error */ - /*******************/ - - printk("Buffer size error\n"); - i_ReturnValue = -101; - } - - return i_ReturnValue; -} - -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3XXX_InsnWriteDigitalOutput | -| (struct comedi_device *dev, | -| struct comedi_subdevice *s, | -| struct comedi_insn *insn, | -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Set the state from digital output channel | -+----------------------------------------------------------------------------+ -| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) | -| b_State = data [0] | -+----------------------------------------------------------------------------+ -| Output Parameters : - | -+----------------------------------------------------------------------------+ -| Return Value : >0 : No error | -| -3 : Channel selection error | -| -101 : Data size error | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci3xxx_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - int i_ReturnValue = insn->n; - unsigned char b_Channel = CR_CHAN(insn->chanspec); - unsigned char b_State = 0; - unsigned int dw_Status = 0; - - /************************/ - /* Test the buffer size */ - /************************/ + unsigned int mask = data[0]; + unsigned int bits = data[1]; - if (insn->n >= 1) { - /***************************/ - /* Test the channel number */ - /***************************/ - - if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) { - /*******************/ - /* Get the command */ - /*******************/ - - b_State = (unsigned char) data[0]; + s->state = inl(devpriv->iobase + 48) & 0xf; + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); - /********************************/ - /* Read the digital output port */ - /********************************/ - - dw_Status = inl(devpriv->iobase + 48); - - dw_Status = - (dw_Status & (0xF - - (1 << b_Channel))) | ((b_State & 1) << - b_Channel); - outl(dw_Status, devpriv->iobase + 48); - } else { - /***************************/ - /* Channel selection error */ - /***************************/ - - printk("Channel selection error\n"); - i_ReturnValue = -3; - } - } else { - /*******************/ - /* Data size error */ - /*******************/ - - printk("Buffer size error\n"); - i_ReturnValue = -101; + outl(s->state, devpriv->iobase + 48); } - return i_ReturnValue; -} + data[1] = s->state; -/* -+----------------------------------------------------------------------------+ -| Function name :int i_APCI3XXX_InsnReadDigitalOutput | -| (struct comedi_device *dev, | -| struct comedi_subdevice *s, | -| struct comedi_insn *insn, | -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read the state from digital output channel | -+----------------------------------------------------------------------------+ -| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) | -+----------------------------------------------------------------------------+ -| Output Parameters : b_State = data [0] | -+----------------------------------------------------------------------------+ -| Return Value : >0 : No error | -| -3 : Channel selection error | -| -101 : Data size error | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - int i_ReturnValue = insn->n; - unsigned char b_Channel = CR_CHAN(insn->chanspec); - unsigned int dw_Status = 0; - - /************************/ - /* Test the buffer size */ - /************************/ - - if (insn->n >= 1) { - /***************************/ - /* Test the channel number */ - /***************************/ - - if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) { - /********************************/ - /* Read the digital output port */ - /********************************/ - - dw_Status = inl(devpriv->iobase + 48); - - dw_Status = (dw_Status >> b_Channel) & 1; - *data = dw_Status; - } else { - /***************************/ - /* Channel selection error */ - /***************************/ - - printk("Channel selection error\n"); - i_ReturnValue = -3; - } - } else { - /*******************/ - /* Data size error */ - /*******************/ - - printk("Buffer size error\n"); - i_ReturnValue = -101; - } - - return i_ReturnValue; + return insn->n; } /* diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index d0cd2e8544b..ae2967a027e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -191,9 +191,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, @@ -224,9 +222,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, @@ -257,9 +253,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, @@ -290,9 +284,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, @@ -323,9 +315,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, @@ -356,9 +346,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, @@ -513,9 +501,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_read = i_APCI3XXX_InsnReadAnalogInput, .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, @@ -550,9 +536,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_read = i_APCI3XXX_InsnReadAnalogInput, .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, @@ -587,9 +571,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_read = i_APCI3XXX_InsnReadAnalogInput, .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, @@ -624,9 +606,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_read = i_APCI3XXX_InsnReadAnalogInput, .ao_write = i_APCI3XXX_InsnWriteAnalogOutput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, .ttl_config = i_APCI3XXX_InsnConfigInitTTLIO, .ttl_bits = i_APCI3XXX_InsnBitsTTLIO, .ttl_read = i_APCI3XXX_InsnReadTTLIO, @@ -655,9 +635,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, }, { .pc_DriverName = "apci3002-16", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -682,9 +660,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, }, { .pc_DriverName = "apci3002-8", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -709,9 +685,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, }, { .pc_DriverName = "apci3002-4", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -736,9 +710,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { .ai_config = i_APCI3XXX_InsnConfigAnalogInput, .ai_read = i_APCI3XXX_InsnReadAnalogInput, .di_bits = apci3xxx_di_insn_bits, - .do_write = i_APCI3XXX_InsnWriteDigitalOutput, - .do_bits = i_APCI3XXX_InsnBitsDigitalOutput, - .do_read = i_APCI3XXX_InsnReadDigitalOutput, + .do_bits = apci3xxx_do_insn_bits, }, { .pc_DriverName = "apci3500", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, -- cgit v1.2.3 From 9741b0ac620211d86d04c83400b08622d84347cf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:02:36 -0700 Subject: staging: comedi: addi_apci_3200: merge addi_apci_3300 support The addi_apci_3200 and addi_apci_3300 board share the same low-level hardware code. Merge the drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_3200.c | 32 +++++++++ drivers/staging/comedi/drivers/addi_apci_3300.c | 91 ------------------------- 2 files changed, 32 insertions(+), 91 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi_apci_3300.c diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 926fd79c11b..2b7157cb950 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -53,11 +53,43 @@ static const struct addi_board apci3200_boardtypes[] = { .do_config = i_APCI3200_ConfigDigitalOutput, .do_write = i_APCI3200_WriteDigitalOutput, .do_bits = i_APCI3200_ReadDigitalOutput, + }, { + .pc_DriverName = "apci3300", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x3007, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = 256, + .i_IorangeBase2 = 4, + .i_IorangeBase3 = 4, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrAiChannelDiff = 8, + .i_AiChannelList = 8, + .i_AiMaxdata = 0x3ffff, + .pr_AiRangelist = &range_apci3300_ai, + .i_NbrDiChannel = 4, + .i_NbrDoChannel = 4, + .ui_MinAcquisitiontimeNs = 10000, + .ui_MinDelaytimeNs = 100000, + .interrupt = v_APCI3200_Interrupt, + .reset = i_APCI3200_Reset, + .ai_config = i_APCI3200_ConfigAnalogInput, + .ai_read = i_APCI3200_ReadAnalogInput, + .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput, + .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test, + .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, + .ai_cmd = i_APCI3200_CommandAnalogInput, + .ai_cancel = i_APCI3200_StopCyclicAcquisition, + .di_bits = i_APCI3200_ReadDigitalInput, + .do_config = i_APCI3200_ConfigDigitalOutput, + .do_write = i_APCI3200_WriteDigitalOutput, + .do_bits = i_APCI3200_ReadDigitalOutput, }, }; static DEFINE_PCI_DEVICE_TABLE(apci3200_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3000) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3007) }, { 0 } }; MODULE_DEVICE_TABLE(pci, apci3200_pci_table); diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c deleted file mode 100644 index e57ef667c8b..00000000000 --- a/drivers/staging/comedi/drivers/addi_apci_3300.c +++ /dev/null @@ -1,91 +0,0 @@ -#include - -#include "../comedidev.h" -#include "comedi_fc.h" -#include "amcc_s5933.h" - -#include "addi-data/addi_common.h" - -static void fpu_begin(void) -{ - kernel_fpu_begin(); -} - -static void fpu_end(void) -{ - kernel_fpu_end(); -} - -#include "addi-data/addi_eeprom.c" -#include "addi-data/hwdrv_apci3200.c" -#include "addi-data/addi_common.c" - -static const struct addi_board apci3300_boardtypes[] = { - { - .pc_DriverName = "apci3300", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x3007, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = 256, - .i_IorangeBase2 = 4, - .i_IorangeBase3 = 4, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, - .i_NbrAiChannelDiff = 8, - .i_AiChannelList = 8, - .i_AiMaxdata = 0x3ffff, - .pr_AiRangelist = &range_apci3300_ai, - .i_NbrDiChannel = 4, - .i_NbrDoChannel = 4, - .ui_MinAcquisitiontimeNs = 10000, - .ui_MinDelaytimeNs = 100000, - .interrupt = v_APCI3200_Interrupt, - .reset = i_APCI3200_Reset, - .ai_config = i_APCI3200_ConfigAnalogInput, - .ai_read = i_APCI3200_ReadAnalogInput, - .ai_write = i_APCI3200_InsnWriteReleaseAnalogInput, - .ai_bits = i_APCI3200_InsnBits_AnalogInput_Test, - .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, - .ai_cmd = i_APCI3200_CommandAnalogInput, - .ai_cancel = i_APCI3200_StopCyclicAcquisition, - .di_bits = i_APCI3200_ReadDigitalInput, - .do_config = i_APCI3200_ConfigDigitalOutput, - .do_write = i_APCI3200_WriteDigitalOutput, - .do_bits = i_APCI3200_ReadDigitalOutput, - }, -}; - -static struct comedi_driver apci3300_driver = { - .driver_name = "addi_apci_3300", - .module = THIS_MODULE, - .attach_pci = addi_attach_pci, - .detach = i_ADDI_Detach, - .num_names = ARRAY_SIZE(apci3300_boardtypes), - .board_name = &apci3300_boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), -}; - -static int __devinit apci3300_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &apci3300_driver); -} - -static void __devexit apci3300_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static DEFINE_PCI_DEVICE_TABLE(apci3300_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3007) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, apci3300_pci_table); - -static struct pci_driver apci3300_pci_driver = { - .name = "addi_apci_3300", - .id_table = apci3300_pci_table, - .probe = apci3300_pci_probe, - .remove = __devexit_p(apci3300_pci_remove), -}; -module_comedi_pci_driver(apci3300_driver, apci3300_pci_driver); -- cgit v1.2.3 From 7395ab3f0ad68507f59bf626017fd6ea0041bea4 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:03:08 -0700 Subject: staging: comedi: addi_apci_3200: fix digital input 'insn_bits' function This driver does not follow the comedi API. The digital input 'insn_bits' function is supposed to return the status of all the input channels in data[1]. Currently this function uses the data[0] parameter to determine if a single channel or all thei nput channels are being read. The status is then being returned in data[0]. Fix the function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' function for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3200.c | 50 +++------------------- drivers/staging/comedi/drivers/addi_apci_3200.c | 4 +- 2 files changed, 7 insertions(+), 47 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index f2330774a6f..2f23ec9cef8 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -609,55 +609,15 @@ static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev, return 0; } -/* - * Read value of the selected channel or port - * - * data[0] = 0: Read single channel - * = 1 Read port value - * data[1] = Port number - * - * data[0] : Read status value - */ -static int i_APCI3200_ReadDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci3200_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_Temp = 0; - unsigned int ui_NoOfChannel = 0; - ui_NoOfChannel = CR_CHAN(insn->chanspec); - ui_Temp = data[0]; - *data = inl(devpriv->i_IobaseReserved); + data[1] = inl(devpriv->i_IobaseReserved) & 0xf; - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - if (data[1] < 0 || data[1] > 1) { - printk("\nThe port number is in error\n"); - return -EINVAL; - } /* if(data[1] < 0 || data[1] >1) */ - switch (ui_NoOfChannel) { - - case 2: - *data = (*data >> (2 * data[1])) & 0x3; - break; - case 3: - *data = (*data & 15); - break; - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* elseif (ui_Temp==1) */ - } return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 2b7157cb950..432caccdd32 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -49,7 +49,7 @@ static const struct addi_board apci3200_boardtypes[] = { .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, .ai_cmd = i_APCI3200_CommandAnalogInput, .ai_cancel = i_APCI3200_StopCyclicAcquisition, - .di_bits = i_APCI3200_ReadDigitalInput, + .di_bits = apci3200_di_insn_bits, .do_config = i_APCI3200_ConfigDigitalOutput, .do_write = i_APCI3200_WriteDigitalOutput, .do_bits = i_APCI3200_ReadDigitalOutput, @@ -80,7 +80,7 @@ static const struct addi_board apci3200_boardtypes[] = { .ai_cmdtest = i_APCI3200_CommandTestAnalogInput, .ai_cmd = i_APCI3200_CommandAnalogInput, .ai_cancel = i_APCI3200_StopCyclicAcquisition, - .di_bits = i_APCI3200_ReadDigitalInput, + .di_bits = apci3200_di_insn_bits, .do_config = i_APCI3200_ConfigDigitalOutput, .do_write = i_APCI3200_WriteDigitalOutput, .do_bits = i_APCI3200_ReadDigitalOutput, -- cgit v1.2.3 From 2e7be560b7d42413b94d46a5ada25fb0a8f732fc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:03:23 -0700 Subject: staging: comedi: addi_apci_3200: fix digital output 'insn_bits' function This driver does not follow the comedi API. The digital output 'insn_bits' function is passed a mask value in data[0] indicating which output bits in data[1] are changing. The function is then supposed to update the outputs accordingly and then return the current state of the outputs in data[1]. Currently this driver uses the 'insn_write' function to update either a single or all the output channels. And it uses the 'insn_bits' function to read either a single or all the output channel states. Fix the 'insn_bits' function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' and 'insn_write' functions for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3200.c | 157 ++------------------- drivers/staging/comedi/drivers/addi_apci_3200.c | 6 +- 2 files changed, 15 insertions(+), 148 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index 2f23ec9cef8..1c2f26d66b4 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -648,156 +648,25 @@ static int i_APCI3200_ConfigDigitalOutput(struct comedi_device *dev, return insn->n; } -/* - * Writes To the digital Output Subdevice - * - * data[0] = Value to output - * data[1] = 0 o/p single channel - * = 1 o/p port - * data[2] = port no - * data[3] = 0 set the digital o/p on - * = 1 set the digital o/p off - */ -static int i_APCI3200_WriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci3200_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_Temp = 0, ui_Temp1 = 0; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ + unsigned int mask = data[0]; + unsigned int bits = data[1]; - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = inl(devpriv->i_IobaseAddon); - - } /* if(devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* if(devpriv->b_OutputMemoryStatus ) */ - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outl(data[0], devpriv->i_IobaseAddon); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = - (data[0] << (2 * - data[2])) | ui_Temp; - break; - case 3: - data[0] = (data[0] | ui_Temp); - break; - } /* switch(ui_NoOfChannels) */ - - outl(data[0], devpriv->i_IobaseAddon); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = (data[0] << ui_NoOfChannel) ^ 0xf; - data[0] = data[0] & ui_Temp; - outl(data[0], devpriv->i_IobaseAddon); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = - ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data - [2])) ^ - 0xf) & ui_Temp; - - break; - case 3: - break; - - default: - comedi_error(dev, - " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* switch(ui_NoOfChannels) */ - - outl(data[0], devpriv->i_IobaseAddon); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* if else data[3]==1) */ - } /* if else data[3]==0) */ - return insn->n; -} + s->state = inl(devpriv->i_IobaseAddon) & 0xf; + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask) -/* - * Read value of the selected channel or port - * - * data[0] = 0 read single channel - * = 1 read port value - * data[1] = port no - */ -static int i_APCI3200_ReadDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Temp; - unsigned int ui_NoOfChannel; - - ui_NoOfChannel = CR_CHAN(insn->chanspec); - ui_Temp = data[0]; - *data = inl(devpriv->i_IobaseAddon); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - if (data[1] < 0 || data[1] > 1) { - printk("\nThe port selection is in error\n"); - return -EINVAL; - } /* if(data[1] <0 ||data[1] >1) */ - switch (ui_NoOfChannel) { - case 2: - *data = (*data >> (2 * data[1])) & 3; - break; + outl(s->state, devpriv->i_IobaseAddon); + } - case 3: - break; + data[1] = s->state; - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch(ui_NoOfChannels) */ - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* else if (ui_Temp==1) */ - } /* else if (ui_Temp==0) */ return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 432caccdd32..890877febac 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -51,8 +51,7 @@ static const struct addi_board apci3200_boardtypes[] = { .ai_cancel = i_APCI3200_StopCyclicAcquisition, .di_bits = apci3200_di_insn_bits, .do_config = i_APCI3200_ConfigDigitalOutput, - .do_write = i_APCI3200_WriteDigitalOutput, - .do_bits = i_APCI3200_ReadDigitalOutput, + .do_bits = apci3200_do_insn_bits, }, { .pc_DriverName = "apci3300", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -82,8 +81,7 @@ static const struct addi_board apci3200_boardtypes[] = { .ai_cancel = i_APCI3200_StopCyclicAcquisition, .di_bits = apci3200_di_insn_bits, .do_config = i_APCI3200_ConfigDigitalOutput, - .do_write = i_APCI3200_WriteDigitalOutput, - .do_bits = i_APCI3200_ReadDigitalOutput, + .do_bits = apci3200_do_insn_bits, }, }; -- cgit v1.2.3 From e9840e632a2fd22b3af4a2593df49dcc94923e50 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:04:09 -0700 Subject: staging: comedi: addi_apci_3200: remove i_APCI3200_ConfigDigitalOutput() The digital outputs of the board supported by this driver are not configurable. This driver abuses the comedi API and uses the 'insn_config' function of the digital output subdevice to enable/disable writing to the eeprom on the board. Remove this function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3200.c | 27 ---------------------- drivers/staging/comedi/drivers/addi_apci_3200.c | 2 -- 2 files changed, 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index 1c2f26d66b4..829af187b24 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -621,33 +621,6 @@ static int apci3200_di_insn_bits(struct comedi_device *dev, return insn->n; } -/* - * Configures The Digital Output Subdevice. - * - * data[0] = 1 Memory enable - * = 0 Memory Disable - */ -static int i_APCI3200_ConfigDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Not a valid Data !!! ,Data should be 1 or 0\n"); - return -EINVAL; - } /* if ( (data[0]!=0) && (data[0]!=1) ) */ - if (data[0]) { - devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; - } /* if (data[0]) */ - else { - devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; - } /* else if (data[0]) */ - return insn->n; -} - static int apci3200_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 890877febac..ee527a71701 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -50,7 +50,6 @@ static const struct addi_board apci3200_boardtypes[] = { .ai_cmd = i_APCI3200_CommandAnalogInput, .ai_cancel = i_APCI3200_StopCyclicAcquisition, .di_bits = apci3200_di_insn_bits, - .do_config = i_APCI3200_ConfigDigitalOutput, .do_bits = apci3200_do_insn_bits, }, { .pc_DriverName = "apci3300", @@ -80,7 +79,6 @@ static const struct addi_board apci3200_boardtypes[] = { .ai_cmd = i_APCI3200_CommandAnalogInput, .ai_cancel = i_APCI3200_StopCyclicAcquisition, .di_bits = apci3200_di_insn_bits, - .do_config = i_APCI3200_ConfigDigitalOutput, .do_bits = apci3200_do_insn_bits, }, }; -- cgit v1.2.3 From a7f4b3ca602c1918c84b0ff2a8ddcb65aa998a82 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:04:26 -0700 Subject: staging: comedi: addi_apci_3120: fix digital input 'insn_bits' function This driver does not follow the comedi API. The digital input 'insn_bits' function is supposed to return the status of all the input channels in data[1]. Currently this function returns the status in data[0]. Fix the function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' function for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 55 ++++------------------ drivers/staging/comedi/drivers/addi_apci_3120.c | 3 +- 2 files changed, 9 insertions(+), 49 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 094691769bd..d5dea349f10 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -2186,57 +2186,18 @@ static int i_APCI3120_InsnReadTimer(struct comedi_device *dev, return insn->n; } -/* - * Reads the value of the specified Digital input channel - */ -static int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Chan, ui_TmpValue; - - ui_Chan = CR_CHAN(insn->chanspec); /* channel specified */ - - /* this_board->di_read(dev,ui_Chan,data); */ - if (ui_Chan <= 3) { - ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI3120_RD_STATUS); - -/* - * since only 1 channel reqd to bring it to last bit it is rotated 8 - * +(chan - 1) times then ANDed with 1 for last bit. - */ - *data = (ui_TmpValue >> (ui_Chan + 8)) & 1; - /* return 0; */ - } else { - /* comedi_error(dev," chan spec wrong"); */ - return -EINVAL; /* "sorry channel spec wrong " */ - } - return insn->n; - -} - -/* - * Reads the value of the Digital input Port i.e.4channels - * value is returned in data[0] - */ -static int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci3120_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_TmpValue; + unsigned int val; - ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI3120_RD_STATUS); - /***** state of 4 channels in the 11, 10, 9, 8 bits of status reg - rotated right 8 times to bring them to last four bits - ANDed with oxf for value. - *****/ + /* the input channels are bits 11:8 of the status reg */ + val = inw(devpriv->iobase + APCI3120_RD_STATUS); + data[1] = (val >> 8) & 0xf; - *data = (ui_TmpValue >> 8) & 0xf; - /* this_board->di_bits(dev,data); */ return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index da3112624b7..bd53a0cb61c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -179,8 +179,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, s->len_chanlist = this_board->i_NbrDiChannel; s->range_table = &range_digital; s->io_bits = 0; /* all bits input */ - s->insn_read = i_APCI3120_InsnReadDigitalInput; - s->insn_bits = i_APCI3120_InsnBitsDigitalInput; + s->insn_bits = apci3120_di_insn_bits; /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[3]; -- cgit v1.2.3 From 66511843c55b1124a8527b041cdde4bd1ae75422 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:04:56 -0700 Subject: staging: comedi: addi_apci_3120: fix digital output 'insn_bits' function This driver does not follow the comedi API. The digital output 'insn_bits' function is passed a mask value in data[0] indicating which output bits in data[1] are changing. The function is then supposed to update the outputs accordingly and then return the current state of the outputs in data[1]. Currently this driver uses the 'insn_write' function to update either a single or all the output channels. And it uses the 'insn_bits' function to read either a single or all the output channel states. Fix the 'insn_bits' function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' and 'insn_write' functions for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 107 +++------------------ drivers/staging/comedi/drivers/addi_apci_3120.c | 3 +- 2 files changed, 16 insertions(+), 94 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index d5dea349f10..106b286724f 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -2230,106 +2230,29 @@ static int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev, return insn->n; } -/* - * Write diatal output port - * - * data[0] = Value to be written - * data[1] = 1 Set digital o/p ON - * = 2 Set digital o/p OFF with memory ON - */ -static int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci3120_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; + unsigned int mask = data[0]; + unsigned int bits = data[1]; + unsigned int val; - if ((data[0] > this_board->i_DoMaxdata) || (data[0] < 0)) { - - comedi_error(dev, "Data is not valid !!! \n"); - return -EINVAL; - } - - switch (data[1]) { - case 1: - data[0] = (data[0] << 4) | devpriv->b_DigitalOutputRegister; - break; - - case 2: - data[0] = data[0]; - break; - default: - printk("\nThe parameter passed is in error \n"); - return -EINVAL; - } /* switch(data[1]) */ - outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT); - - devpriv->b_DigitalOutputRegister = data[0] & 0xF0; - - return insn->n; - -} + /* The do channels are bits 7:4 of the do register */ + val = devpriv->b_DigitalOutputRegister >> 4; + if (mask) { + val &= ~mask; + val |= (bits & mask); + devpriv->b_DigitalOutputRegister = val << 4; -/* - * Write digital output - * - * data[0] = Value to be written - * data[1] = 1 Set digital o/p ON - * = 2 Set digital o/p OFF with memory ON - */ -static int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = comedi_board(dev); - struct addi_private *devpriv = dev->private; - unsigned int ui_Temp1; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ - - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Not a valid Data !!! ,Data should be 1 or 0\n"); - return -EINVAL; - } - if (ui_NoOfChannel > this_board->i_NbrDoChannel - 1) { - comedi_error(dev, - "This board doesn't have specified channel !!! \n"); - return -EINVAL; + outb(val << 4, devpriv->iobase + APCI3120_DIGITAL_OUTPUT); } - switch (data[1]) { - case 1: - data[0] = (data[0] << ui_NoOfChannel); -/* ES05 data[0]=(data[0]<<4)|ui_Temp; */ - data[0] = (data[0] << 4) | devpriv->b_DigitalOutputRegister; - break; - - case 2: - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp1 = ui_Temp1 << 4; -/* ES05 ui_Temp=ui_Temp|ui_Temp1; */ - devpriv->b_DigitalOutputRegister = - devpriv->b_DigitalOutputRegister | ui_Temp1; - - data[0] = (data[0] << ui_NoOfChannel) ^ 0xf; - data[0] = data[0] << 4; -/* ES05 data[0]=data[0]& ui_Temp; */ - data[0] = data[0] & devpriv->b_DigitalOutputRegister; - break; - default: - printk("\nThe parameter passed is in error \n"); - return -EINVAL; - } /* switch(data[1]) */ - outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT); + data[1] = val; -/* ES05 ui_Temp=data[0] & 0xf0; */ - devpriv->b_DigitalOutputRegister = data[0] & 0xf0; return insn->n; - } static int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index bd53a0cb61c..1326a2ec42b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -194,8 +194,7 @@ static int apci3120_attach_pci(struct comedi_device *dev, /* insn_config - for digital output memory */ s->insn_config = i_APCI3120_InsnConfigDigitalOutput; - s->insn_write = i_APCI3120_InsnWriteDigitalOutput; - s->insn_bits = i_APCI3120_InsnBitsDigitalOutput; + s->insn_bits = apci3120_do_insn_bits; /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[4]; -- cgit v1.2.3 From b96450712fe3c67b1a4660425c581691ac888612 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:06:07 -0700 Subject: staging: comedi: addi_apci_3120: remove i_APCI3120_InsnConfigDigitalOutput() The digital outputs of the board supported by this driver are not configurable. This driver abuses the comedi API and uses the 'insn_config' function of the digital output subdevice to enable/disable writing to the eeprom on the board. Remove this function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 31 ---------------------- drivers/staging/comedi/drivers/addi_apci_3120.c | 3 --- 2 files changed, 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 106b286724f..0bc4eda1f74 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -242,8 +242,6 @@ static const struct comedi_lrange range_apci3120_ao = { }; -static unsigned int ui_Temp; - /* FUNCTION DEFINITIONS */ /* @@ -2201,35 +2199,6 @@ static int apci3120_di_insn_bits(struct comedi_device *dev, return insn->n; } -/* - * Configure the output memory ON or OFF - */ -static int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Not a valid Data !!! ,Data should be 1 or 0\n"); - return -EINVAL; - } - if (data[0]) { - devpriv->b_OutputMemoryStatus = APCI3120_ENABLE; - - } else { - devpriv->b_OutputMemoryStatus = APCI3120_DISABLE; - devpriv->b_DigitalOutputRegister = 0; - } - if (!devpriv->b_OutputMemoryStatus) - ui_Temp = 0; - /* if(!devpriv->b_OutputMemoryStatus ) */ - - return insn->n; -} - static int apci3120_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 1326a2ec42b..f65f8271807 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -191,9 +191,6 @@ static int apci3120_attach_pci(struct comedi_device *dev, s->len_chanlist = this_board->i_NbrDoChannel; s->range_table = &range_digital; s->io_bits = 0xf; /* all bits output */ - - /* insn_config - for digital output memory */ - s->insn_config = i_APCI3120_InsnConfigDigitalOutput; s->insn_bits = apci3120_do_insn_bits; /* Allocate and Initialise Timer Subdevice Structures */ -- cgit v1.2.3 From bf83f6d85ef94bbecdc3453a0302ac46693aa917 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:06:24 -0700 Subject: staging: comedi: addi_apci_2200: fix digital input 'insn_bits' function This driver does not follow the comedi API. The digital input 'insn_bits' function is supposed to return the status of all the input channels in data[1]. Currently this function returns the status in data[0]. Fix the function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' function for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci2200.c | 95 ++-------------------- drivers/staging/comedi/drivers/addi_apci_2200.c | 3 +- 2 files changed, 6 insertions(+), 92 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c index 94c884d31b1..7baccf7a9de 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c @@ -63,99 +63,14 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define APCI2200_WATCHDOG_RELOAD_VALUE 4 #define APCI2200_WATCHDOG_STATUS 16 -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2200_Read1DigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the digital input | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI2200_Read1DigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_TmpValue = 0; - unsigned int ui_Channel; - - ui_Channel = CR_CHAN(insn->chanspec); - if (ui_Channel <= 7) { - ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP); - *data = (ui_TmpValue >> ui_Channel) & 0x1; - } /* if(ui_Channel >= 0 && ui_Channel <=7) */ - else { - printk("\nThe specified channel does not exist\n"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* else if(ui_Channel >= 0 && ui_Channel <=7) */ - - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2200_ReadMoreDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the Requested digital inputs | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci2200_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_PortValue = data[0]; - unsigned int ui_Mask = 0; - unsigned int ui_NoOfChannels; - - ui_NoOfChannels = CR_CHAN(insn->chanspec); - *data = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP); - switch (ui_NoOfChannels) { - case 2: - ui_Mask = 3; - *data = (*data >> (2 * ui_PortValue)) & ui_Mask; - break; - case 4: - ui_Mask = 15; - *data = (*data >> (4 * ui_PortValue)) & ui_Mask; - break; - case 7: - break; - - default: - printk("\nWrong parameters\n"); - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch(ui_NoOfChannels) */ + data[1] = inw(devpriv->iobase + APCI2200_DIGITAL_IP); return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index becb2b4d11c..99ce93cca39 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -21,8 +21,7 @@ static const struct addi_board apci2200_boardtypes[] = { .i_NbrDoChannel = 16, .i_Timer = 1, .reset = i_APCI2200_Reset, - .di_read = i_APCI2200_Read1DigitalInput, - .di_bits = i_APCI2200_ReadMoreDigitalInput, + .di_bits = apci2200_di_insn_bits, .do_config = i_APCI2200_ConfigDigitalOutput, .do_write = i_APCI2200_WriteDigitalOutput, .do_bits = i_APCI2200_ReadDigitalOutput, -- cgit v1.2.3 From 8ded30de45e1ea5979396eaa8241e7ee1e57ff3e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:07:04 -0700 Subject: staging: comedi: addi_apci_2200: fix digital output 'insn_bits' function This driver does not follow the comedi API. The digital output 'insn_bits' function is passed a mask value in data[0] indicating which output bits in data[1] are changing. The function is then supposed to update the outputs accordingly and then return the current state of the outputs in data[1]. Currently this driver uses the 'insn_write' function to update either a single or all the output channels. And it uses the 'insn_bits' function to read either a single or all the output channel states. Fix the 'insn_bits' function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' and 'insn_write' functions for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci2200.c | 232 ++------------------- drivers/staging/comedi/drivers/addi_apci_2200.c | 3 +- 2 files changed, 14 insertions(+), 221 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c index 7baccf7a9de..1396696a305 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c @@ -111,231 +111,25 @@ static int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2200_WriteDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Writes port value To the selected port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci2200_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_Temp, ui_Temp1; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ + unsigned int mask = data[0]; + unsigned int bits = data[1]; - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = inw(devpriv->iobase + APCI2200_DIGITAL_OP); + s->state = inw(devpriv->iobase + APCI2200_DIGITAL_OP); + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); - } /* if(devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* if(devpriv->b_OutputMemoryStatus ) */ - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outw(data[0], devpriv->iobase + APCI2200_DIGITAL_OP); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = - (data[0] << (2 * - data[2])) | ui_Temp; - break; - - case 4: - data[0] = - (data[0] << (4 * - data[2])) | ui_Temp; - break; - - case 8: - data[0] = - (data[0] << (8 * - data[2])) | ui_Temp; - break; - case 15: - data[0] = data[0] | ui_Temp; - break; - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - - outw(data[0], - devpriv->iobase + APCI2200_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff; - data[0] = data[0] & ui_Temp; - outw(data[0], - devpriv->iobase + APCI2200_DIGITAL_OP); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = - ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data - [2])) ^ - 0xffff) & ui_Temp; - break; - - case 4: - data[0] = ~data[0] & 0xf; - ui_Temp1 = 15; - ui_Temp1 = - ui_Temp1 << 4 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (4 * - data - [2])) ^ - 0xffff) & ui_Temp; - break; - - case 8: - data[0] = ~data[0] & 0xff; - ui_Temp1 = 255; - ui_Temp1 = - ui_Temp1 << 8 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (8 * - data - [2])) ^ - 0xffff) & ui_Temp; - break; - case 15: - break; - - default: - comedi_error(dev, - " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - - outw(data[0], - devpriv->iobase + - APCI2200_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* if else data[3]==1) */ - } /* if else data[3]==0) */ - return insn->n; -} + outw(s->state, devpriv->iobase + APCI2200_DIGITAL_OP); + } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2200_ReadDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ + data[1] = s->state; -static int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Temp; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ - - ui_Temp = data[0]; - *data = inw(devpriv->iobase + APCI2200_DIGITAL_OP); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if(ui_Temp==0) */ - else { - if (ui_Temp == 1) { - switch (ui_NoOfChannel) { - - case 2: - *data = (*data >> (2 * data[1])) & 3; - break; - - case 4: - *data = (*data >> (4 * data[1])) & 15; - break; - - case 8: - *data = (*data >> (8 * data[1])) & 255; - break; - - case 15: - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - } /* if(ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* elseif(ui_Temp==1) */ - } /* elseif(ui_Temp==0) */ return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 99ce93cca39..cf406595c73 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -23,8 +23,7 @@ static const struct addi_board apci2200_boardtypes[] = { .reset = i_APCI2200_Reset, .di_bits = apci2200_di_insn_bits, .do_config = i_APCI2200_ConfigDigitalOutput, - .do_write = i_APCI2200_WriteDigitalOutput, - .do_bits = i_APCI2200_ReadDigitalOutput, + .do_bits = apci2200_do_insn_bits, .timer_config = i_APCI2200_ConfigWatchdog, .timer_write = i_APCI2200_StartStopWriteWatchdog, .timer_read = i_APCI2200_ReadWatchdog, -- cgit v1.2.3 From 80230c26d26b0ae82f7d9b7786cd22189d7ccf9d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:07:22 -0700 Subject: staging: comedi: addi_apci_2200: remove i_APCI2200_ConfigDigitalOutput() The digital outputs of the board supported by this driver are not configurable. This driver abuses the comedi API and uses the 'insn_config' function of the digital output subdevice to enable/disable writing to the eeprom on the board. Remove this function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci2200.c | 36 ---------------------- drivers/staging/comedi/drivers/addi_apci_2200.c | 1 - 2 files changed, 37 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c index 1396696a305..9d4a117aad4 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c @@ -75,42 +75,6 @@ static int apci2200_di_insn_bits(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2200_ConfigDigitalOutput (struct comedi_device *dev, -| struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Configures The Digital Output Subdevice. | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| data[0] :1:Memory on | -| 0:Memory off | -| | -| | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - devpriv->b_OutputMemoryStatus = data[0]; - return insn->n; -} - static int apci2200_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index cf406595c73..69503b47845 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -22,7 +22,6 @@ static const struct addi_board apci2200_boardtypes[] = { .i_Timer = 1, .reset = i_APCI2200_Reset, .di_bits = apci2200_di_insn_bits, - .do_config = i_APCI2200_ConfigDigitalOutput, .do_bits = apci2200_do_insn_bits, .timer_config = i_APCI2200_ConfigWatchdog, .timer_write = i_APCI2200_StartStopWriteWatchdog, -- cgit v1.2.3 From 06bd743ff823e47da504a4a322e7a0dd02a11197 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:08:07 -0700 Subject: staging: comedi: addi_apci_2032: fix digital output 'insn_bits' function This driver does not follow the comedi API. The digital output 'insn_bits' function is passed a mask value in data[0] indicating which output bits in data[1] are changing. The function is then supposed to update the outputs accordingly and then return the current state of the outputs in data[1]. Currently this driver uses the 'insn_write' function to update either a single or all the output channels. And it uses the 'insn_bits' function to read either a single or all the output channel states. Fix the 'insn_bits' function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' and 'insn_write' functions for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci2032.c | 258 ++------------------- drivers/staging/comedi/drivers/addi_apci_2032.c | 3 +- 2 files changed, 14 insertions(+), 247 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c index ebe6d1d4fe6..8422b682ad9 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c @@ -143,257 +143,25 @@ static int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2032_WriteDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Writes port value To the selected port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To Write | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci2032_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_Temp, ui_Temp1; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ + unsigned int mask = data[0]; + unsigned int bits = data[1]; - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = inl(devpriv->iobase + APCI2032_DIGITAL_OP); + s->state = inl(devpriv->iobase + APCI2032_DIGITAL_OP_RW); + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); - } /* if(devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* if(devpriv->b_OutputMemoryStatus ) */ - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = - (data[0] << (2 * - data[2])) | ui_Temp; - break; - - case 4: - data[0] = - (data[0] << (4 * - data[2])) | ui_Temp; - break; - - case 8: - data[0] = - (data[0] << (8 * - data[2])) | ui_Temp; - break; - - case 16: - data[0] = - (data[0] << (16 * - data[2])) | ui_Temp; - break; - case 31: - data[0] = data[0] | ui_Temp; - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - - outl(data[0], - devpriv->iobase + APCI2032_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - (data[0] << ui_NoOfChannel) ^ - 0xffffffff; - data[0] = data[0] & ui_Temp; - outl(data[0], - devpriv->iobase + APCI2032_DIGITAL_OP); - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = - ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - - case 4: - data[0] = ~data[0] & 0xf; - ui_Temp1 = 15; - ui_Temp1 = - ui_Temp1 << 4 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (4 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - - case 8: - data[0] = ~data[0] & 0xff; - ui_Temp1 = 255; - ui_Temp1 = - ui_Temp1 << 8 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (8 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - - case 16: - data[0] = ~data[0] & 0xffff; - ui_Temp1 = 65535; - ui_Temp1 = - ui_Temp1 << 16 * - data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (16 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - - case 31: - break; - default: - comedi_error(dev, - " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - - outl(data[0], - devpriv->iobase + - APCI2032_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* if else data[3]==1) */ - } /* if else data[3]==0) */ - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2032_ReadDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Temp; - unsigned int ui_NoOfChannel; - - ui_NoOfChannel = CR_CHAN(insn->chanspec); - ui_Temp = data[0]; - *data = inl(devpriv->iobase + APCI2032_DIGITAL_OP_RW); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - switch (ui_NoOfChannel) { - - case 2: - *data = (*data >> (2 * data[1])) & 3; - break; - - case 4: - *data = (*data >> (4 * data[1])) & 15; - break; - - case 8: - *data = (*data >> (8 * data[1])) & 255; - break; - - case 16: - *data = (*data >> (16 * data[1])) & 65535; - break; - - case 31: - break; + outl(s->state, devpriv->iobase + APCI2032_DIGITAL_OP); + } - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ + data[1] = s->state; - } /* switch(ui_NoOfChannels) */ - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* elseif (ui_Temp==1) */ - } return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 92650480cd3..9766c240d80 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -23,8 +23,7 @@ static const struct addi_board apci2032_boardtypes[] = { .interrupt = v_APCI2032_Interrupt, .reset = i_APCI2032_Reset, .do_config = i_APCI2032_ConfigDigitalOutput, - .do_write = i_APCI2032_WriteDigitalOutput, - .do_bits = i_APCI2032_ReadDigitalOutput, + .do_bits = apci2032_do_insn_bits, .do_read = i_APCI2032_ReadInterruptStatus, .timer_config = i_APCI2032_ConfigWatchdog, .timer_write = i_APCI2032_StartStopWriteWatchdog, -- cgit v1.2.3 From 1bf448e27814a5caa8ab0ad8ba2a54af7469cee6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:08:34 -0700 Subject: staging: comedi: addi_apci_2016: fix digital output 'insn_bits' function This driver does not follow the comedi API. The digital output 'insn_bits' function is passed a mask value in data[0] indicating which output bits in data[1] are changing. The function is then supposed to update the outputs accordingly and then return the current state of the outputs in data[1]. Currently this driver uses the 'insn_write' function to update either a single or all the output channels. And it uses the 'insn_bits' function to read either a single or all the output channel states. Fix the 'insn_bits' function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' and 'insn_write' functions for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci2016.c | 239 ++------------------- drivers/staging/comedi/drivers/addi_apci_2016.c | 3 +- 2 files changed, 15 insertions(+), 227 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c index b7192875b00..14c6a3096aa 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c @@ -106,236 +106,25 @@ static int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_WriteDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Writes port value To the selected port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To Write | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci2016_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_NoOfChannel; - unsigned int ui_Temp, ui_Temp1; + unsigned int mask = data[0]; + unsigned int bits = data[1]; - ui_NoOfChannel = CR_CHAN(insn->chanspec); - if (ui_NoOfChannel > 15) { - comedi_error(dev, - "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n"); - return -EINVAL; - } /* if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15)) */ - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = inw(devpriv->iobase + APCI2016_DIGITAL_OP); - } /* if (devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* else if (devpriv->b_OutputMemoryStatus ) */ - if ((data[1] != 0) && (data[1] != 1)) { - comedi_error(dev, - "Invalid Data[1] value !!!, Data[1] should be 0 or 1\n"); - return -EINVAL; - } /* if ((data[1]!=0) && (data[1]!=1)) */ - - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP); - } /* if (data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - case 2: - data[0] = - (data[0] << (2 * - data[2])) | ui_Temp; - break; - case 4: - data[0] = - (data[0] << (4 * - data[2])) | ui_Temp; - break; - case 8: - data[0] = - (data[0] << (8 * - data[2])) | ui_Temp; - break; - case 15: - data[0] = data[0] | ui_Temp; - break; - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* switch(ui_NoOfChannels) */ - outw(data[0], - devpriv->iobase + APCI2016_DIGITAL_OP); - } /* if (data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if (data[1]==1) */ - } /* else if (data[1]==0) */ - } /* if (data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff; - data[0] = data[0] & ui_Temp; - outw(data[0], - devpriv->iobase + APCI2016_DIGITAL_OP); - } /* if (data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - case 2: - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = - ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data - [2])) ^ - 0xffff) & ui_Temp; - break; - case 4: - data[0] = ~data[0] & 0xf; - ui_Temp1 = 15; - ui_Temp1 = - ui_Temp1 << 4 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (4 * - data - [2])) ^ - 0xffff) & ui_Temp; - break; - case 8: - data[0] = ~data[0] & 0xff; - ui_Temp1 = 255; - ui_Temp1 = - ui_Temp1 << 8 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (8 * - data - [2])) ^ - 0xffff) & ui_Temp; - break; - case 15: - break; - default: - comedi_error(dev, - " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* switch(ui_NoOfChannels) */ - outw(data[0], - devpriv->iobase + - APCI2016_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* if else data[3]==1) */ - } /* if else data[3]==0) */ - return insn->n; -} + s->state = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW); + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_BitsDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Temp; - unsigned int ui_NoOfChannel; + outw(s->state, devpriv->iobase + APCI2016_DIGITAL_OP); + } + + data[1] = s->state; - ui_NoOfChannel = CR_CHAN(insn->chanspec); - if (ui_NoOfChannel > 15) { - comedi_error(dev, - "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n"); - return -EINVAL; - } /* if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15)) */ - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Invalid Data[0] value !!!, Data[0] should be 0 or 1\n"); - return -EINVAL; - } /* if ((data[0]!=0) && (data[0]!=1)) */ - ui_Temp = data[0]; - *data = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - switch (ui_NoOfChannel) { - case 2: - *data = (*data >> (2 * data[1])) & 3; - break; - - case 4: - *data = (*data >> (4 * data[1])) & 15; - break; - - case 8: - *data = (*data >> (8 * data[1])) & 255; - break; - - case 15: - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* switch(ui_NoOfChannel) */ - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* else if (ui_Temp==1) */ - } /* if (ui_Temp==0) */ return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c index 7c71981de7d..a792012bfe9 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ b/drivers/staging/comedi/drivers/addi_apci_2016.c @@ -22,8 +22,7 @@ static const struct addi_board apci2016_boardtypes[] = { .i_Timer = 1, .reset = i_APCI2016_Reset, .do_config = i_APCI2016_ConfigDigitalOutput, - .do_write = i_APCI2016_WriteDigitalOutput, - .do_bits = i_APCI2016_BitsDigitalOutput, + .do_bits = apci2016_do_insn_bits, .timer_config = i_APCI2016_ConfigWatchdog, .timer_write = i_APCI2016_StartStopWriteWatchdog, .timer_read = i_APCI2016_ReadWatchdog, -- cgit v1.2.3 From 95e417aea4c954846f0f07e1b1b2e22267255aa5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:09:04 -0700 Subject: staging: comedi: addi_apci_2016: remove i_APCI2016_ConfigDigitalOutput() The digital outputs of the board supported by this driver are not configurable. This driver abuses the comedi API and uses the 'insn_config' function of the digital output subdevice to enable/disable writing to the eeprom on the board. Remove this function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci2016.c | 43 ---------------------- drivers/staging/comedi/drivers/addi_apci_2016.c | 1 - 2 files changed, 44 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c index 14c6a3096aa..c1a58398266 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c @@ -63,49 +63,6 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define APCI2016_WATCHDOG_RELOAD_VALUE 4 #define APCI2016_WATCHDOG_STATUS 16 -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_ConfigDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Configures The Digital Output Subdevice. | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| | -| data[0] : 1 Digital Memory On | -| 0 Digital Memory Off | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - if ((data[0] != 0) && (data[0] != 1)) { - comedi_error(dev, - "Not a valid Data !!! ,Data should be 1 or 0\n"); - return -EINVAL; - } /* if ((data[0]!=0) && (data[0]!=1)) */ - if (data[0]) { - devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; - } /* if (data[0] */ - else { - devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; - } /* else if (data[0] */ - return insn->n; -} - static int apci2016_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c index a792012bfe9..e9431f8ceba 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ b/drivers/staging/comedi/drivers/addi_apci_2016.c @@ -21,7 +21,6 @@ static const struct addi_board apci2016_boardtypes[] = { .i_NbrDoChannel = 16, .i_Timer = 1, .reset = i_APCI2016_Reset, - .do_config = i_APCI2016_ConfigDigitalOutput, .do_bits = apci2016_do_insn_bits, .timer_config = i_APCI2016_ConfigWatchdog, .timer_write = i_APCI2016_StartStopWriteWatchdog, -- cgit v1.2.3 From 6b5d432852d030320cdd41571ab37df0d6f6e823 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:09:37 -0700 Subject: staging: comedi: addi_apci_1564: fix digital input 'insn_bits' function This driver does not follow the comedi API. The digital input 'insn_bits' function is supposed to return the status of all the input channels in data[1]. Currently this function returns the status in data[0]. Fix the function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' function for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1564.c | 108 +-------------------- drivers/staging/comedi/drivers/addi_apci_1564.c | 3 +- 2 files changed, 6 insertions(+), 105 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 0f734d5be4c..68623d93fb2 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -180,113 +180,15 @@ static int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1564_Read1DigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the digital input | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_Channel : Channel number to read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI1564_Read1DigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci1564_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_TmpValue = 0; - unsigned int ui_Channel; - ui_Channel = CR_CHAN(insn->chanspec); - if (ui_Channel <= 31) { - ui_TmpValue = - (unsigned int) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP); -/* -* since only 1 channel reqd to bring it to last bit it is rotated 8 -* +(chan - 1) times then ANDed with 1 for last bit. -*/ - *data = (ui_TmpValue >> ui_Channel) & 0x1; - } /* if (ui_Channel >= 0 && ui_Channel <=31) */ - else { - comedi_error(dev, "Not a valid channel number !!! \n"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* else if (ui_Channel >= 0 && ui_Channel <=31) */ - return insn->n; -} + data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP); -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1564_ReadMoreDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the Requested digital inputs | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To be Read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_PortValue = data[0]; - unsigned int ui_Mask = 0; - unsigned int ui_NoOfChannels; - - ui_NoOfChannels = CR_CHAN(insn->chanspec); - if (data[1] == 0) { - *data = (unsigned int) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP); - switch (ui_NoOfChannels) { - case 2: - ui_Mask = 3; - *data = (*data >> (2 * ui_PortValue)) & ui_Mask; - break; - case 4: - ui_Mask = 15; - *data = (*data >> (4 * ui_PortValue)) & ui_Mask; - break; - case 8: - ui_Mask = 255; - *data = (*data >> (8 * ui_PortValue)) & ui_Mask; - break; - case 16: - ui_Mask = 65535; - *data = (*data >> (16 * ui_PortValue)) & ui_Mask; - break; - case 31: - break; - default: - comedi_error(dev, "Not a valid Channel number !!!\n"); - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch (ui_NoOfChannels) */ - } /* if (data[1]==0) */ - else { - if (data[1] == 1) { - *data = ui_InterruptStatus_1564; - } /* if (data[1]==1) */ - } /* else if (data[1]==0) */ return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 1dcaadade21..42aea51f461 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -24,8 +24,7 @@ static const struct addi_board apci1564_boardtypes[] = { .interrupt = v_APCI1564_Interrupt, .reset = i_APCI1564_Reset, .di_config = i_APCI1564_ConfigDigitalInput, - .di_read = i_APCI1564_Read1DigitalInput, - .di_bits = i_APCI1564_ReadMoreDigitalInput, + .di_bits = apci1564_di_insn_bits, .do_config = i_APCI1564_ConfigDigitalOutput, .do_write = i_APCI1564_WriteDigitalOutput, .do_bits = i_APCI1564_ReadDigitalOutput, -- cgit v1.2.3 From a4a257039fb580142a30872537a03f4d7d7627e3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:11:02 -0700 Subject: staging: comedi: addi_apci_1564: fix digital output 'insn_bits' function This driver does not follow the comedi API. The digital output 'insn_bits' function is passed a mask value in data[0] indicating which output bits in data[1] are changing. The function is then supposed to update the outputs accordingly and then return the current state of the outputs in data[1]. Currently this driver uses the 'insn_write' function to update either a single or all the output channels. And it uses the 'insn_bits' function to read either a single or all the output channel states. Fix the 'insn_bits' function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' and 'insn_write' functions for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1564.c | 255 ++------------------- drivers/staging/comedi/drivers/addi_apci_1564.c | 3 +- 2 files changed, 17 insertions(+), 241 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 68623d93fb2..fc31c4b9340 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -258,250 +258,27 @@ static int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1564_WriteDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Writes port value To the selected port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To Write | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci1564_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_Temp, ui_Temp1; - unsigned int ui_NoOfChannel; + unsigned int mask = data[0]; + unsigned int bits = data[1]; - ui_NoOfChannel = CR_CHAN(insn->chanspec); - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = - inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + + s->state = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + APCI1564_DIGITAL_OP_RW); - } /* if (devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* else if (devpriv->b_OutputMemoryStatus ) */ - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outl(data[0], - devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + - APCI1564_DIGITAL_OP_RW); - } /* if (data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - case 2: - data[0] = - (data[0] << (2 * - data[2])) | ui_Temp; - break; - case 4: - data[0] = - (data[0] << (4 * - data[2])) | ui_Temp; - break; - case 8: - data[0] = - (data[0] << (8 * - data[2])) | ui_Temp; - break; - case 16: - data[0] = - (data[0] << (16 * - data[2])) | ui_Temp; - break; - case 31: - data[0] = data[0] | ui_Temp; - break; - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* switch (ui_NoOfChannels) */ - outl(data[0], - devpriv->i_IobaseAmcc + - APCI1564_DIGITAL_OP + - APCI1564_DIGITAL_OP_RW); - } /* if (data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if (data[1]==1) */ - } /* else if (data[1]==0) */ - } /* if(data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - (data[0] << ui_NoOfChannel) ^ - 0xffffffff; - data[0] = data[0] & ui_Temp; - outl(data[0], - devpriv->i_IobaseAmcc + - APCI1564_DIGITAL_OP + - APCI1564_DIGITAL_OP_RW); - } /* if (data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - case 2: - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = - ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - case 4: - data[0] = ~data[0] & 0xf; - ui_Temp1 = 15; - ui_Temp1 = - ui_Temp1 << 4 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (4 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - case 8: - data[0] = ~data[0] & 0xff; - ui_Temp1 = 255; - ui_Temp1 = - ui_Temp1 << 8 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (8 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - case 16: - data[0] = ~data[0] & 0xffff; - ui_Temp1 = 65535; - ui_Temp1 = - ui_Temp1 << 16 * - data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (16 * - data - [2])) ^ - 0xffffffff) & ui_Temp; - break; - case 31: - break; - default: - comedi_error(dev, - " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* switch(ui_NoOfChannels) */ - outl(data[0], - devpriv->i_IobaseAmcc + - APCI1564_DIGITAL_OP + - APCI1564_DIGITAL_OP_RW); - } /* if (data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if (data[1]==1) */ - } /* else if (data[1]==0) */ - } /* if (data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* else if (data[3]==1) */ - } /* else if (data[3]==0) */ - return insn->n; -} + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); + + outl(s->state, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + + APCI1564_DIGITAL_OP_RW); + } + + data[1] = s->state; -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1564_ReadDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To read | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_Temp; - unsigned int ui_NoOfChannel; - - ui_NoOfChannel = CR_CHAN(insn->chanspec); - ui_Temp = data[0]; - *data = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP + - APCI1564_DIGITAL_OP_RW); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if (ui_Temp==0) */ - else { - if (ui_Temp == 1) { - switch (ui_NoOfChannel) { - case 2: - *data = (*data >> (2 * data[1])) & 3; - break; - - case 4: - *data = (*data >> (4 * data[1])) & 15; - break; - - case 8: - *data = (*data >> (8 * data[1])) & 255; - break; - - case 16: - *data = (*data >> (16 * data[1])) & 65535; - break; - - case 31: - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch(ui_NoOfChannels) */ - } /* if (ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* else if (ui_Temp==1) */ - } /* else if (ui_Temp==0) */ return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 42aea51f461..2fd335b2aad 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -26,8 +26,7 @@ static const struct addi_board apci1564_boardtypes[] = { .di_config = i_APCI1564_ConfigDigitalInput, .di_bits = apci1564_di_insn_bits, .do_config = i_APCI1564_ConfigDigitalOutput, - .do_write = i_APCI1564_WriteDigitalOutput, - .do_bits = i_APCI1564_ReadDigitalOutput, + .do_bits = apci1564_do_insn_bits, .do_read = i_APCI1564_ReadInterruptStatus, .timer_config = i_APCI1564_ConfigTimerCounterWatchdog, .timer_write = i_APCI1564_StartStopWriteTimerCounterWatchdog, -- cgit v1.2.3 From 2942ab926b8a64ef48db92fa5d161db4fcf8ed24 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:11:21 -0700 Subject: staging: comedi: addi_apci_1516: fix digital input 'insn_bits' function This driver does not follow the comedi API. The digital input 'insn_bits' function is supposed to return the status of all the input channels in data[1]. Currently this function returns the status in data[0]. Fix the function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' function for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1516.c | 97 ++-------------------- drivers/staging/comedi/drivers/addi_apci_1516.c | 3 +- 2 files changed, 6 insertions(+), 94 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index 7504c520600..a384c943bb0 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -65,101 +65,14 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define APCI1516_WATCHDOG_RELOAD_VALUE 4 #define APCI1516_WATCHDOG_STATUS 16 -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_Read1DigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the digital input | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI1516_Read1DigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int ui_TmpValue = 0; - unsigned int ui_Channel; - - ui_Channel = CR_CHAN(insn->chanspec); - if (ui_Channel <= 7) { - ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI1516_DIGITAL_IP); - /* since only 1 channel reqd to bring it to last bit it is rotated */ - /* 8 +(chan - 1) times then ANDed with 1 for last bit. */ - *data = (ui_TmpValue >> ui_Channel) & 0x1; - } /* if(ui_Channel >= 0 && ui_Channel <=7) */ - else { - /* comedi_error(dev," \n chan spec wrong\n"); */ - return -EINVAL; /* "sorry channel spec wrong " */ - } /* else if(ui_Channel >= 0 && ui_Channel <=7) */ - - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_ReadMoreDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the Requested digital inputs | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci1516_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_PortValue = data[0]; - unsigned int ui_Mask = 0; - unsigned int ui_NoOfChannels; - - ui_NoOfChannels = CR_CHAN(insn->chanspec); - *data = (unsigned int) inw(devpriv->iobase + APCI1516_DIGITAL_IP); - switch (ui_NoOfChannels) { - case 2: - ui_Mask = 3; - *data = (*data >> (2 * ui_PortValue)) & ui_Mask; - break; - case 4: - ui_Mask = 15; - *data = (*data >> (4 * ui_PortValue)) & ui_Mask; - break; - case 7: - break; - - default: - printk("\nWrong parameters\n"); - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch(ui_NoOfChannels) */ + data[1] = inw(devpriv->iobase + APCI1516_DIGITAL_IP); return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 59c0c65ac18..4662ef056e8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -22,8 +22,7 @@ static const struct addi_board apci1516_boardtypes[] = { .i_NbrDoChannel = 8, .i_Timer = 1, .reset = i_APCI1516_Reset, - .di_read = i_APCI1516_Read1DigitalInput, - .di_bits = i_APCI1516_ReadMoreDigitalInput, + .di_bits = apci1516_di_insn_bits, .do_config = i_APCI1516_ConfigDigitalOutput, .do_write = i_APCI1516_WriteDigitalOutput, .do_bits = i_APCI1516_ReadDigitalOutput, -- cgit v1.2.3 From 5e4116e8f669cda2ada9c3fafb992fbcd66cf4a5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:12:11 -0700 Subject: staging: comedi: addi_apci_1516: fix digital output 'insn_bits' function This driver does not follow the comedi API. The digital output 'insn_bits' function is passed a mask value in data[0] indicating which output bits in data[1] are changing. The function is then supposed to update the outputs accordingly and then return the current state of the outputs in data[1]. Currently this driver uses the 'insn_write' function to update either a single or all the output channels. And it uses the 'insn_bits' function to read either a single or all the output channel states. Fix the 'insn_bits' function so it works like the comedi core expects. The core can then use the function to emulate the 'insn_read' and 'insn_write' functions for individual channels. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1516.c | 232 ++------------------- drivers/staging/comedi/drivers/addi_apci_1516.c | 3 +- 2 files changed, 15 insertions(+), 220 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index a384c943bb0..d9edaaf8ccd 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -113,230 +113,26 @@ static int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_WriteDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Writes port value To the selected port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci1516_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - struct addi_private *devpriv = dev->private; - unsigned int ui_Temp, ui_Temp1; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ - printk("EL311003 : @=%x\n", devpriv->iobase + APCI1516_DIGITAL_OP); - - if (devpriv->b_OutputMemoryStatus) { - ui_Temp = inw(devpriv->iobase + APCI1516_DIGITAL_OP); + struct addi_private *devpriv = dev->private; + unsigned int mask = data[0]; + unsigned int bits = data[1]; - } /* if(devpriv->b_OutputMemoryStatus ) */ - else { - ui_Temp = 0; - } /* if(devpriv->b_OutputMemoryStatus ) */ - if (data[3] == 0) { - if (data[1] == 0) { - data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; - outw(data[0], devpriv->iobase + APCI1516_DIGITAL_OP); - - printk("EL311003 : d=%d @=%x\n", data[0], - devpriv->iobase + APCI1516_DIGITAL_OP); - - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = - (data[0] << (2 * - data[2])) | ui_Temp; - break; - - case 4: - data[0] = - (data[0] << (4 * - data[2])) | ui_Temp; - break; - - case 7: - data[0] = data[0] | ui_Temp; - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - - outw(data[0], - devpriv->iobase + APCI1516_DIGITAL_OP); - - printk("EL311003 : d=%d @=%x\n", data[0], - devpriv->iobase + APCI1516_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==0) */ - else { - if (data[3] == 1) { - if (data[1] == 0) { - data[0] = ~data[0] & 0x1; - ui_Temp1 = 1; - ui_Temp1 = ui_Temp1 << ui_NoOfChannel; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = (data[0] << ui_NoOfChannel) ^ 0xff; - data[0] = data[0] & ui_Temp; - outw(data[0], - devpriv->iobase + APCI1516_DIGITAL_OP); - - printk("EL311003 : d=%d @=%x\n", data[0], - devpriv->iobase + APCI1516_DIGITAL_OP); - - } /* if(data[1]==0) */ - else { - if (data[1] == 1) { - switch (ui_NoOfChannel) { - - case 2: - data[0] = ~data[0] & 0x3; - ui_Temp1 = 3; - ui_Temp1 = - ui_Temp1 << 2 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (2 * - data - [2])) ^ - 0xff) & ui_Temp; - break; - - case 4: - data[0] = ~data[0] & 0xf; - ui_Temp1 = 15; - ui_Temp1 = - ui_Temp1 << 4 * data[2]; - ui_Temp = ui_Temp | ui_Temp1; - data[0] = - ((data[0] << (4 * - data - [2])) ^ - 0xff) & ui_Temp; - break; - - case 7: - break; - - default: - comedi_error(dev, - " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - - outw(data[0], - devpriv->iobase + - APCI1516_DIGITAL_OP); - - printk("EL311003 : d=%d @=%x\n", - data[0], - devpriv->iobase + - APCI1516_DIGITAL_OP); - } /* if(data[1]==1) */ - else { - printk("\nSpecified channel not supported\n"); - } /* else if(data[1]==1) */ - } /* elseif(data[1]==0) */ - } /* if(data[3]==1); */ - else { - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* if else data[3]==1) */ - } /* if else data[3]==0) */ - return (insn->n); -} + s->state = inw(devpriv->iobase + APCI1516_DIGITAL_OP_RW); + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_ReadDigitalOutput | -| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, -| unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read value of the selected channel or port | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ + outw(s->state, devpriv->iobase + APCI1516_DIGITAL_OP); + } -static int i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ + data[1] = s->state; - struct addi_private *devpriv = dev->private; - unsigned int ui_Temp; - unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ - - ui_Temp = data[0]; - *data = inw(devpriv->iobase + APCI1516_DIGITAL_OP_RW); - if (ui_Temp == 0) { - *data = (*data >> ui_NoOfChannel) & 0x1; - } /* if(ui_Temp==0) */ - else { - if (ui_Temp == 1) { - switch (ui_NoOfChannel) { - - case 2: - *data = (*data >> (2 * data[1])) & 3; - break; - - case 4: - *data = (*data >> (4 * data[1])) & 15; - break; - - case 7: - break; - - default: - comedi_error(dev, " chan spec wrong"); - return -EINVAL; /* "sorry channel spec wrong " */ - - } /* switch(ui_NoOfChannels) */ - } /* if(ui_Temp==1) */ - else { - printk("\nSpecified channel not supported \n"); - } /* elseif(ui_Temp==1) */ - } /* elseif(ui_Temp==0) */ return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 4662ef056e8..395e99cd193 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -24,8 +24,7 @@ static const struct addi_board apci1516_boardtypes[] = { .reset = i_APCI1516_Reset, .di_bits = apci1516_di_insn_bits, .do_config = i_APCI1516_ConfigDigitalOutput, - .do_write = i_APCI1516_WriteDigitalOutput, - .do_bits = i_APCI1516_ReadDigitalOutput, + .do_bits = apci1516_do_insn_bits, .timer_config = i_APCI1516_ConfigWatchdog, .timer_write = i_APCI1516_StartStopWriteWatchdog, .timer_read = i_APCI1516_ReadWatchdog, -- cgit v1.2.3 From 7cfa1af0deb1d9c64eb7668355f18dd26788b81d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:12:47 -0700 Subject: staging: comedi: addi_apci_1516: remove i_APCI1516_ConfigDigitalOutput() The digital outputs of the board supported by this driver are not configurable. This driver abuses the comedi API and uses the 'insn_config' function of the digital output subdevice to enable/disable writing to the eeprom on the board. Remove this function. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1516.c | 36 ---------------------- drivers/staging/comedi/drivers/addi_apci_1516.c | 1 - 2 files changed, 37 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index d9edaaf8ccd..48e58a3154e 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -77,42 +77,6 @@ static int apci1516_di_insn_bits(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_ConfigDigitalOutput (struct comedi_device *dev, -| struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Configures The Digital Output Subdevice. | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int *data : Data Pointer contains | -| configuration parameters as below | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| data[0] :1:Memory on | -| 0:Memory off | -| | -| | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - devpriv->b_OutputMemoryStatus = data[0]; - return insn->n; -} - static int apci1516_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 395e99cd193..e5b8c11cb7b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -23,7 +23,6 @@ static const struct addi_board apci1516_boardtypes[] = { .i_Timer = 1, .reset = i_APCI1516_Reset, .di_bits = apci1516_di_insn_bits, - .do_config = i_APCI1516_ConfigDigitalOutput, .do_bits = apci1516_do_insn_bits, .timer_config = i_APCI1516_ConfigWatchdog, .timer_write = i_APCI1516_StartStopWriteWatchdog, -- cgit v1.2.3 From a9c2ba17be3d6c954b2eae9f9820da9c7bb9938f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 10:13:06 -0700 Subject: staging: comedi: addi_apci_1500: fix digital input 'insn_bits' function This driver does not follow the comedi API. The digital input 'insn_bits' function is supposed to return the status of all the input channels in data[1]. Currently this function returns the status in data[0]. Fix the function so it works like the comedi core expects. The 'insn_read' and 'insn_Write' functions for the digital input subdevice cannot be removed yet. This driver is again abusing the API and uses these functions to initialize the board and start/stop "events" generated by the board. These will be addressed later. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1500.c | 78 ++-------------------- drivers/staging/comedi/drivers/addi_apci_1500.c | 2 +- 2 files changed, 6 insertions(+), 74 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c index 771a3054f92..24c4c983db3 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c @@ -1042,83 +1042,15 @@ static int i_APCI1500_Initialisation(struct comedi_device *dev, return insn->n; } -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1500_ReadMoreDigitalInput | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Return the status of the Requested digital inputs | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| unsigned int ui_NoOfChannels : No Of Channels To be Read | -| unsigned int *data : Data Pointer -| data[0] : 0 Read a single channel -| 1 read a port value -| data[1] : port value -+----------------------------------------------------------------------------+ -| Output Parameters : -- data[0] :The read status value -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci1500_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct addi_private *devpriv = dev->private; - unsigned int ui_PortValue = data[1]; - unsigned int ui_Mask = 0; - unsigned int ui_Channel; - unsigned int ui_TmpValue = 0; - ui_Channel = CR_CHAN(insn->chanspec); - switch (data[0]) { - case 0: - if (ui_Channel <= 15) { - ui_TmpValue = - (unsigned int) inw(devpriv->i_IobaseAddon + - APCI1500_DIGITAL_IP); - *data = (ui_TmpValue >> ui_Channel) & 0x1; - } /* if(ui_Channel >= 0 && ui_Channel <=15) */ - else { - printk("\nThe channel specification are in error\n"); - return -EINVAL; /* "sorry channel spec wrong " */ - } /* else if(ui_Channel >= 0 && ui_Channel <=15) */ - break; - case 1: + data[1] = inw(devpriv->i_IobaseAddon + APCI1500_DIGITAL_IP); - *data = (unsigned int) inw(devpriv->i_IobaseAddon + - APCI1500_DIGITAL_IP); - switch (ui_Channel) { - case 2: - ui_Mask = 3; - *data = (*data >> (2 * ui_PortValue)) & ui_Mask; - break; - case 4: - ui_Mask = 15; - *data = (*data >> (4 * ui_PortValue)) & ui_Mask; - break; - case 8: - ui_Mask = 255; - *data = (*data >> (8 * ui_PortValue)) & ui_Mask; - break; - case 15: - break; - - default: - printk("\nSpecified channel cannot be read \n"); - return -EINVAL; /* "sorry channel spec wrong " */ - break; - } /* switch(ui_Channel) */ - break; - default: - printk("\nThe specified functionality does not exist\n"); - return -EINVAL; - } /* switch(data[0]) */ return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 4fe98e5ce75..8d390a4fba8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -26,7 +26,7 @@ static const struct addi_board apci1500_boardtypes[] = { .di_config = i_APCI1500_ConfigDigitalInputEvent, .di_read = i_APCI1500_Initialisation, .di_write = i_APCI1500_StartStopInputEvent, - .di_bits = i_APCI1500_ReadMoreDigitalInput, + .di_bits = apci1500_di_insn_bits, .do_config = i_APCI1500_ConfigDigitalOutputErrorInterrupt, .do_write = i_APCI1500_WriteDigitalOutput, .do_bits = i_APCI1500_ConfigureInterrupt, -- cgit v1.2.3 From 193f3fcb3ab769bab4a2b9fa181eef3e5699a352 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 19 Oct 2012 10:58:13 +0200 Subject: x86: Add cpu_has_topoext Introduce cpu_has_topoext to check for AMD's CPUID topology extensions support. It indicates support for CPUID Fn8000_001D_EAX_x[N:0]-CPUID Fn8000_001E_EDX See AMD's CPUID Specification, Publication # 25481 (as of Rev. 2.34 September 2010) Signed-off-by: Andreas Herrmann Link: http://lkml.kernel.org/r/20121019085813.GD26718@alberich Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/cpufeature.h | 1 + arch/x86/kernel/cpu/amd.c | 2 +- arch/x86/kernel/smpboot.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 8c297aa53ee..c22a492daf5 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -311,6 +311,7 @@ extern const char * const x86_power_flags[32]; #define cpu_has_cx8 boot_cpu_has(X86_FEATURE_CX8) #define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16) #define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU) +#define cpu_has_topoext boot_cpu_has(X86_FEATURE_TOPOEXT) #if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64) # define cpu_has_invlpg 1 diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index f7e98a2c0d1..64e9ad4e49a 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -304,7 +304,7 @@ static void __cpuinit amd_get_topology(struct cpuinfo_x86 *c) int cpu = smp_processor_id(); /* get information required for multi-node processors */ - if (cpu_has(c, X86_FEATURE_TOPOEXT)) { + if (cpu_has_topoext) { u32 eax, ebx, ecx, edx; cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index c80a33bc528..732bf5cff64 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -313,7 +313,7 @@ do { \ static bool __cpuinit match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) { - if (cpu_has(c, X86_FEATURE_TOPOEXT)) { + if (cpu_has_topoext) { int cpu1 = c->cpu_index, cpu2 = o->cpu_index; if (c->phys_proc_id == o->phys_proc_id && -- cgit v1.2.3 From 04a1541828ea223169eb44a336bfad8ec0dfb46a Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 19 Oct 2012 10:59:33 +0200 Subject: x86, cacheinfo: Determine number of cache leafs using CPUID 0x8000001d on AMD CPUID 0x8000001d works quite similar to Intels' CPUID function 4. Use it to determine number of cache leafs. Signed-off-by: Andreas Herrmann Link: http://lkml.kernel.org/r/20121019085933.GE26718@alberich Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/processor.h | 2 +- arch/x86/kernel/cpu/amd.c | 7 +------ arch/x86/kernel/cpu/intel_cacheinfo.c | 28 +++++++++++++++++++++++----- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index ad1fc851167..db0d8c32090 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -187,7 +187,7 @@ extern void print_cpu_info(struct cpuinfo_x86 *); void print_cpu_msr(struct cpuinfo_x86 *); extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); -extern unsigned short num_cache_leaves; +extern void init_amd_cacheinfo(struct cpuinfo_x86 *c); extern void detect_extended_topology(struct cpuinfo_x86 *c); extern void detect_ht(struct cpuinfo_x86 *c); diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 64e9ad4e49a..a8538e6d2ff 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -643,12 +643,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) detect_ht(c); #endif - if (c->extended_cpuid_level >= 0x80000006) { - if (cpuid_edx(0x80000006) & 0xf000) - num_cache_leaves = 4; - else - num_cache_leaves = 3; - } + init_amd_cacheinfo(c); if (c->x86 >= 0xf) set_cpu_cap(c, X86_FEATURE_K8); diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 93c5451bdd5..8ce7a83252f 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -557,21 +557,39 @@ __cpuinit cpuid4_cache_lookup_regs(int index, return 0; } -static int __cpuinit find_num_cache_leaves(void) +static int __cpuinit find_num_cache_leaves(struct cpuinfo_x86 *c) { - unsigned int eax, ebx, ecx, edx; + unsigned int eax, ebx, ecx, edx, op; union _cpuid4_leaf_eax cache_eax; int i = -1; + if (c->x86_vendor == X86_VENDOR_AMD) + op = 0x8000001d; + else + op = 4; + do { ++i; - /* Do cpuid(4) loop to find out num_cache_leaves */ - cpuid_count(4, i, &eax, &ebx, &ecx, &edx); + /* Do cpuid(op) loop to find out num_cache_leaves */ + cpuid_count(op, i, &eax, &ebx, &ecx, &edx); cache_eax.full = eax; } while (cache_eax.split.type != CACHE_TYPE_NULL); return i; } +void __cpuinit init_amd_cacheinfo(struct cpuinfo_x86 *c) +{ + + if (cpu_has_topoext) { + num_cache_leaves = find_num_cache_leaves(c); + } else if (c->extended_cpuid_level >= 0x80000006) { + if (cpuid_edx(0x80000006) & 0xf000) + num_cache_leaves = 4; + else + num_cache_leaves = 3; + } +} + unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) { /* Cache sizes */ @@ -588,7 +606,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) if (is_initialized == 0) { /* Init num_cache_leaves from boot CPU */ - num_cache_leaves = find_num_cache_leaves(); + num_cache_leaves = find_num_cache_leaves(c); is_initialized++; } -- cgit v1.2.3 From 2e8458dfe4202df75543402c7343b8f94de4101e Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 19 Oct 2012 11:00:49 +0200 Subject: x86, cacheinfo: Make use of CPUID 0x8000001d for cache information on AMD Rely on CPUID 0x8000001d for cache information when AMD CPUID topology extensions are available. Signed-off-by: Andreas Herrmann Link: http://lkml.kernel.org/r/20121019090049.GF26718@alberich Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/intel_cacheinfo.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 8ce7a83252f..cd2e1ccce59 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -538,7 +538,11 @@ __cpuinit cpuid4_cache_lookup_regs(int index, unsigned edx; if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { - amd_cpuid4(index, &eax, &ebx, &ecx); + if (cpu_has_topoext) + cpuid_count(0x8000001d, index, &eax.full, + &ebx.full, &ecx.full, &edx); + else + amd_cpuid4(index, &eax, &ebx, &ecx); amd_init_l3_cache(this_leaf, index); } else { cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); -- cgit v1.2.3 From 27d3a8a26ada7660116fdd6830096008c063ee96 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 19 Oct 2012 11:02:09 +0200 Subject: x86, cacheinfo: Base cache sharing info on CPUID 0x8000001d on AMD The patch is based on a patch submitted by Hans Rosenfeld. See http://marc.info/?l=linux-kernel&m=133908777200931 Note that CPUID Fn8000_001D_EAX slightly differs to Intel's CPUID function 4. Bits 14-25 contain NumSharingCache. Actual number of cores sharing this cache. SW to add value of one to get result. The corresponding bits on Intel are defined as "maximum number of threads sharing this cache" (with a "plus 1" encoding). Thus a different method to determine which cores are sharing a cache level has to be used. Signed-off-by: Andreas Herrmann Link: http://lkml.kernel.org/r/20121019090209.GG26718@alberich Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/intel_cacheinfo.c | 41 +++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index cd2e1ccce59..fe9edec6698 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -750,37 +750,50 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info); static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index) { struct _cpuid4_info *this_leaf; - int ret, i, sibling; - struct cpuinfo_x86 *c = &cpu_data(cpu); + int i, sibling; - ret = 0; - if (index == 3) { - ret = 1; - for_each_cpu(i, cpu_llc_shared_mask(cpu)) { + if (cpu_has_topoext) { + unsigned int apicid, nshared, first, last; + + if (!per_cpu(ici_cpuid4_info, cpu)) + return 0; + + this_leaf = CPUID4_INFO_IDX(cpu, index); + nshared = this_leaf->base.eax.split.num_threads_sharing + 1; + apicid = cpu_data(cpu).apicid; + first = apicid - (apicid % nshared); + last = first + nshared - 1; + + for_each_online_cpu(i) { + apicid = cpu_data(i).apicid; + if ((apicid < first) || (apicid > last)) + continue; if (!per_cpu(ici_cpuid4_info, i)) continue; this_leaf = CPUID4_INFO_IDX(i, index); - for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) { - if (!cpu_online(sibling)) + + for_each_online_cpu(sibling) { + apicid = cpu_data(sibling).apicid; + if ((apicid < first) || (apicid > last)) continue; set_bit(sibling, this_leaf->shared_cpu_map); } } - } else if ((c->x86 == 0x15) && ((index == 1) || (index == 2))) { - ret = 1; - for_each_cpu(i, cpu_sibling_mask(cpu)) { + } else if (index == 3) { + for_each_cpu(i, cpu_llc_shared_mask(cpu)) { if (!per_cpu(ici_cpuid4_info, i)) continue; this_leaf = CPUID4_INFO_IDX(i, index); - for_each_cpu(sibling, cpu_sibling_mask(cpu)) { + for_each_cpu(sibling, cpu_llc_shared_mask(cpu)) { if (!cpu_online(sibling)) continue; set_bit(sibling, this_leaf->shared_cpu_map); } } - } + } else + return 0; - return ret; + return 1; } static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) -- cgit v1.2.3 From 80928805babfd97b6f1721dd942a55dd2e7813ea Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Tue, 6 Nov 2012 00:08:53 +0000 Subject: smsc95xx: set MII_BUSY bit to read/write PHY regs The device datasheet specifies the BUSY bit must be set when reading or writing phy registers. This patch ensures we do that. Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/usb/smsc95xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 3286166415b..362cb8cfeb9 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -184,7 +184,7 @@ static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx) /* set the address, index & direction (read from PHY) */ phy_id &= dev->mii.phy_id_mask; idx &= dev->mii.reg_num_mask; - addr = (phy_id << 11) | (idx << 6) | MII_READ_; + addr = (phy_id << 11) | (idx << 6) | MII_READ_ | MII_BUSY_; ret = smsc95xx_write_reg(dev, MII_ADDR, addr); check_warn_goto_done(ret, "Error writing MII_ADDR"); @@ -221,7 +221,7 @@ static void smsc95xx_mdio_write(struct net_device *netdev, int phy_id, int idx, /* set the address, index & direction (write to PHY) */ phy_id &= dev->mii.phy_id_mask; idx &= dev->mii.reg_num_mask; - addr = (phy_id << 11) | (idx << 6) | MII_WRITE_; + addr = (phy_id << 11) | (idx << 6) | MII_WRITE_ | MII_BUSY_; ret = smsc95xx_write_reg(dev, MII_ADDR, addr); check_warn_goto_done(ret, "Error writing MII_ADDR"); -- cgit v1.2.3 From a134884ac0e9fa48786560d49ed49c5f5f686410 Mon Sep 17 00:00:00 2001 From: Stefan Raspl Date: Mon, 12 Nov 2012 23:05:16 +0000 Subject: qeth: Fix IPA_CMD_QIPASSIST return code handling Return codes of IPA_CMD_QIPASSIST are not checked, especially the ones which indicate that the command is not supported. As a result, the device driver would not enable all available features on older card generations. This patch adds proper checking and sets the bare minimum in the supported functions flags to avoid follow-on errors. Signed-off-by: Stefan Raspl Signed-off-by: Frank Blaschka Reviewed-by: Ursula Braun Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core_main.c | 24 ++++++++++++++++++++++-- drivers/s390/net/qeth_l2_main.c | 11 +++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3e25d315045..4d6ba00d004 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2942,13 +2942,33 @@ static int qeth_query_ipassists_cb(struct qeth_card *card, QETH_DBF_TEXT(SETUP, 2, "qipasscb"); cmd = (struct qeth_ipa_cmd *) data; + + switch (cmd->hdr.return_code) { + case IPA_RC_NOTSUPP: + case IPA_RC_L2_UNSUPPORTED_CMD: + QETH_DBF_TEXT(SETUP, 2, "ipaunsup"); + card->options.ipa4.supported_funcs |= IPA_SETADAPTERPARMS; + card->options.ipa6.supported_funcs |= IPA_SETADAPTERPARMS; + return -0; + default: + if (cmd->hdr.return_code) { + QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Unhandled " + "rc=%d\n", + dev_name(&card->gdev->dev), + cmd->hdr.return_code); + return 0; + } + } + if (cmd->hdr.prot_version == QETH_PROT_IPV4) { card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported; card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled; - } else { + } else if (cmd->hdr.prot_version == QETH_PROT_IPV6) { card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported; card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled; - } + } else + QETH_DBF_MESSAGE(1, "%s IPA_CMD_QIPASSIST: Flawed LIC detected" + "\n", dev_name(&card->gdev->dev)); QETH_DBF_TEXT(SETUP, 2, "suppenbl"); QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_supported); QETH_DBF_TEXT_(SETUP, 2, "%08x", (__u32)cmd->hdr.ipa_enabled); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index e67e0258aec..84e8f1d4d21 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -626,10 +626,13 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) QETH_DBF_TEXT(SETUP, 2, "doL2init"); QETH_DBF_TEXT_(SETUP, 2, "doL2%s", CARD_BUS_ID(card)); - rc = qeth_query_setadapterparms(card); - if (rc) { - QETH_DBF_MESSAGE(2, "could not query adapter parameters on " - "device %s: x%x\n", CARD_BUS_ID(card), rc); + if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) { + rc = qeth_query_setadapterparms(card); + if (rc) { + QETH_DBF_MESSAGE(2, "could not query adapter " + "parameters on device %s: x%x\n", + CARD_BUS_ID(card), rc); + } } if (card->info.type == QETH_CARD_TYPE_IQD || -- cgit v1.2.3 From 7702745b15128e5f0659693736a864e35be1c807 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Mon, 12 Nov 2012 23:05:17 +0000 Subject: qeth: set new mac even if old mac is gone If the set_mac_address() function of qeth is invoked, qeth deletes the old mac address first on OSA. Only if deletion returns successfully the new mac address is set on OSA. Deletion may return with a return value "MAC not found on OSA". In this case qeth should continue setting the new mac address. When the OSA cable is pulled, OSA forgets any set mac address. If the OSA network interface acts as a slave to a bonding master interface, bonding can invoke the set_mac_address function for failover purposes and depends on successful setting of the new mac address even though the old mac address could no longer be deleted. Signed-off-by: Ursula Braun Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l2_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 84e8f1d4d21..fddb62654b6 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -679,7 +679,7 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) return -ERESTARTSYS; } rc = qeth_l2_send_delmac(card, &card->dev->dev_addr[0]); - if (!rc) + if (!rc || (rc == IPA_RC_L2_MAC_NOT_FOUND)) rc = qeth_l2_send_setmac(card, addr->sa_data); return rc ? -EINVAL : 0; } -- cgit v1.2.3 From bbc8d9228ea8e37ce29fa96150d10b85a2c7be60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 13 Nov 2012 03:19:43 +0000 Subject: net: cdc_ncm: add Huawei devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A number of Huawei 3G and LTE modems implement a CDC NCM function, including the necessary functional descriptors, but using a non standard interface layout and class/subclass/protocol codes. These devices can be handled by this driver with only a minor change to the probing logic, allowing a single combined control and data interface. This works because the devices - include a CDC Union descriptor labelling the combined interface as both master and slave, and - have an alternate setting #1 for the bulk endpoints on the combined interface. The 3G/LTE network connection is managed by vendor specific AT commands on a serial function in the same composite device. Handling the managment function is out of the scope of this driver. It will be handled by an appropriate USB serial driver. Reported-and-Tested-by: Olof Ermis Reported-and-Tested-by: Tommy Cheng Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ncm.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 4cd582a4f62..74fab1a4015 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -540,10 +540,12 @@ advance: (ctx->ether_desc == NULL) || (ctx->control != intf)) goto error; - /* claim interfaces, if any */ - temp = usb_driver_claim_interface(driver, ctx->data, dev); - if (temp) - goto error; + /* claim data interface, if different from control */ + if (ctx->data != ctx->control) { + temp = usb_driver_claim_interface(driver, ctx->data, dev); + if (temp) + goto error; + } iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber; @@ -623,6 +625,10 @@ static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) tasklet_kill(&ctx->bh); + /* handle devices with combined control and data interface */ + if (ctx->control == ctx->data) + ctx->data = NULL; + /* disconnect master --> disconnect slave */ if (intf == ctx->control && ctx->data) { usb_set_intfdata(ctx->data, NULL); @@ -1245,6 +1251,14 @@ static const struct usb_device_id cdc_devs[] = { .driver_info = (unsigned long) &wwan_info, }, + /* Huawei NCM devices disguised as vendor specific */ + { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16), + .driver_info = (unsigned long)&wwan_info, + }, + { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x46), + .driver_info = (unsigned long)&wwan_info, + }, + /* Generic CDC-NCM devices */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_NCM, USB_CDC_PROTO_NONE), -- cgit v1.2.3 From bd090dfc634ddd711a5fbd0cadc6e0ab4977bcaf Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 13 Nov 2012 05:37:18 +0000 Subject: tcp: tcp_replace_ts_recent() should not be called from tcp_validate_incoming() We added support for RFC 5961 in latest kernels but TCP fails to perform exhaustive check of ACK sequence. We can update our view of peer tsval from a frame that is later discarded by tcp_ack() This makes timestamps enabled sessions vulnerable to injection of a high tsval : peers start an ACK storm, since the victim sends a dupack each time it receives an ACK from the other peer. As tcp_validate_incoming() is called before tcp_ack(), we should not peform tcp_replace_ts_recent() from it, and let callers do it at the right time. Signed-off-by: Eric Dumazet Cc: Neal Cardwell Cc: Yuchung Cheng Cc: Nandita Dukkipati Cc: H.K. Jerry Chu Cc: Romain Francoise Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2c2b13a999e..609ff98aeb4 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5313,11 +5313,6 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, goto discard; } - /* ts_recent update must be made after we are sure that the packet - * is in window. - */ - tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); - /* step 3: check security and precedence [ignored] */ /* step 4: Check for a SYN @@ -5552,6 +5547,11 @@ step5: if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) goto discard; + /* ts_recent update must be made after we are sure that the packet + * is in window. + */ + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); + tcp_rcv_rtt_measure_ts(sk, skb); /* Process urgent data. */ @@ -6130,6 +6130,11 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, } else goto discard; + /* ts_recent update must be made after we are sure that the packet + * is in window. + */ + tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); + /* step 6: check the URG bit */ tcp_urg(sk, skb, th); -- cgit v1.2.3 From 52b702ffa509595c5d04a1a1d0f63acf92b4789b Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 9 Nov 2012 13:35:24 +0000 Subject: vxlan: Fix error that was resulting in VXLAN MTU size being 10 bytes too large This change fixes an issue I found where VXLAN frames were fragmented when they were up to the VXLAN MTU size. I root caused the issue to the fact that the headroom was 4 + 20 + 8 + 8. This math doesn't appear to be correct because we are not inserting a VLAN header, but instead a 2nd Ethernet header. As such the math for the overhead should be 20 + 8 + 8 + 14 to account for the extra headers that are inserted for VXLAN. Signed-off-by: Alexander Duyck Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 7b4adde93c0..0c4d0f49ab4 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -50,8 +50,8 @@ #define VXLAN_N_VID (1u << 24) #define VXLAN_VID_MASK (VXLAN_N_VID - 1) -/* VLAN + IP header + UDP + VXLAN */ -#define VXLAN_HEADROOM (4 + 20 + 8 + 8) +/* IP header + UDP + VXLAN + Ethernet header */ +#define VXLAN_HEADROOM (20 + 8 + 8 + 14) #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */ -- cgit v1.2.3 From 73e212fc48890b552e4ae65b65c0e709f478879b Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sat, 10 Nov 2012 07:12:36 +0000 Subject: doc/net: Fix typo in netdev-features.txt Signed-off-by: Kirill Smelkov Signed-off-by: David S. Miller --- Documentation/networking/netdev-features.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/networking/netdev-features.txt b/Documentation/networking/netdev-features.txt index 4164f5c02e4..f310edec8a7 100644 --- a/Documentation/networking/netdev-features.txt +++ b/Documentation/networking/netdev-features.txt @@ -164,4 +164,4 @@ read the CRC recorded by the NIC on receipt of the packet. This requests that the NIC receive all possible frames, including errored frames (such as bad FCS, etc). This can be helpful when sniffing a link with bad packets on it. Some NICs may receive more packets if also put into normal -PROMISC mdoe. +PROMISC mode. -- cgit v1.2.3 From d4596bad2a713fcd0def492b1960e6d899d5baa8 Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Sat, 10 Nov 2012 19:52:34 +0000 Subject: ipv6: setsockopt(IPIPPROTO_IPV6, IPV6_MINHOPCOUNT) forgot to set return value Cc: Stephen Hemminger Signed-off-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- net/ipv6/ipv6_sockglue.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index ba6d13d1f1e..e02faed6d17 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -827,6 +827,7 @@ pref_skip_coa: if (val < 0 || val > 255) goto e_inval; np->min_hopcount = val; + retv = 0; break; case IPV6_DONTFRAG: np->dontfrag = valbool; -- cgit v1.2.3 From 92cba8f3b42e1cb8211b64e91618102ecc8f0a6d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 11:16:42 -0700 Subject: staging: comedi: addi-data: use auto_attach instead of attach_pci Change the addi-data drivers that use the "common" code so they attach using the generic 'auto_attach' method instead the pci specific 'attach_pci' method. The 'attach_pci' is deprecated and is going to be removed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 5 +++-- drivers/staging/comedi/drivers/addi_apci_035.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1500.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1516.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1564.c | 2 +- drivers/staging/comedi/drivers/addi_apci_16xx.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2016.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3501.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 2 +- 12 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index d2d57e5862e..2500d53a6a3 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -93,9 +93,10 @@ static const void *addi_find_boardinfo(struct comedi_device *dev, return NULL; } -static int addi_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit addi_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct addi_board *this_board; struct addi_private *devpriv; struct comedi_subdevice *s; diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 43b83cf4810..3055fc2e0a7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -40,7 +40,7 @@ static const struct addi_board apci035_boardtypes[] = { static struct comedi_driver apci035_driver = { .driver_name = "addi_apci_035", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, + .auto_attach = addi_auto_attach, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci035_boardtypes), .board_name = &apci035_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 8d390a4fba8..8528b27f77e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -40,7 +40,7 @@ static const struct addi_board apci1500_boardtypes[] = { static struct comedi_driver apci1500_driver = { .driver_name = "addi_apci_1500", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, + .auto_attach = addi_auto_attach, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci1500_boardtypes), .board_name = &apci1500_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index e5b8c11cb7b..0382844fdc0 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -33,7 +33,7 @@ static const struct addi_board apci1516_boardtypes[] = { static struct comedi_driver apci1516_driver = { .driver_name = "addi_apci_1516", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, + .auto_attach = addi_auto_attach, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci1516_boardtypes), .board_name = &apci1516_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 2fd335b2aad..926fa088392 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -37,7 +37,7 @@ static const struct addi_board apci1564_boardtypes[] = { static struct comedi_driver apci1564_driver = { .driver_name = "addi_apci_1564", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, + .auto_attach = addi_auto_attach, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci1564_boardtypes), .board_name = &apci1564_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 14283aad0e4..170d576761a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -39,7 +39,7 @@ static const struct addi_board apci16xx_boardtypes[] = { static struct comedi_driver apci16xx_driver = { .driver_name = "addi_apci_16xx", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, + .auto_attach = addi_auto_attach, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci16xx_boardtypes), .board_name = &apci16xx_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c index e9431f8ceba..54b05d3fa1b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ b/drivers/staging/comedi/drivers/addi_apci_2016.c @@ -31,7 +31,7 @@ static const struct addi_board apci2016_boardtypes[] = { static struct comedi_driver apci2016_driver = { .driver_name = "addi_apci_2016", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, + .auto_attach = addi_auto_attach, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci2016_boardtypes), .board_name = &apci2016_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 9766c240d80..7758de3146e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -34,7 +34,7 @@ static const struct addi_board apci2032_boardtypes[] = { static struct comedi_driver apci2032_driver = { .driver_name = "addi_apci_2032", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, + .auto_attach = addi_auto_attach, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci2032_boardtypes), .board_name = &apci2032_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 69503b47845..3041009915f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -32,7 +32,7 @@ static const struct addi_board apci2200_boardtypes[] = { static struct comedi_driver apci2200_driver = { .driver_name = "addi_apci_2200", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, + .auto_attach = addi_auto_attach, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci2200_boardtypes), .board_name = &apci2200_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index ee527a71701..e95141dabbd 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -93,7 +93,7 @@ MODULE_DEVICE_TABLE(pci, apci3200_pci_table); static struct comedi_driver apci3200_driver = { .driver_name = "addi_apci_3200", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, + .auto_attach = addi_auto_attach, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci3200_boardtypes), .board_name = &apci3200_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index b7899488df0..4c60167be2f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -44,7 +44,7 @@ MODULE_DEVICE_TABLE(pci, apci3501_pci_table); static struct comedi_driver apci3501_driver = { .driver_name = "addi_apci_3501", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, + .auto_attach = addi_auto_attach, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci3501_boardtypes), .board_name = &apci3501_boardtypes[0].pc_DriverName, diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index ae2967a027e..cc3938124cd 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -738,7 +738,7 @@ static const struct addi_board apci3xxx_boardtypes[] = { static struct comedi_driver apci3xxx_driver = { .driver_name = "addi_apci_3xxx", .module = THIS_MODULE, - .attach_pci = addi_attach_pci, + .auto_attach = addi_auto_attach, .detach = i_ADDI_Detach, .num_names = ARRAY_SIZE(apci3xxx_boardtypes), .board_name = &apci3xxx_boardtypes[0].pc_DriverName, -- cgit v1.2.3 From 891e62c33d9cdbcdb8adfaddd111e91a39d0f5fe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 11:16:59 -0700 Subject: staging: comedi: addi_apci_*: use auto_attach instead of attach_pci Change the remaining addi-data drivers so they attach using the generic 'auto_attach' method instead the pci specific 'attach_pci' method. The 'attach_pci' is deprecated and is going to be removed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 7 ++++--- drivers/staging/comedi/drivers/addi_apci_1710.c | 7 ++++--- drivers/staging/comedi/drivers/addi_apci_3120.c | 7 ++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 2f23a173064..14b5989e41a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -246,9 +246,10 @@ static int apci1032_di_insn_bits(struct comedi_device *dev, return insn->n; } -static int apci1032_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit apci1032_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct apci1032_private *devpriv; struct comedi_subdevice *s; int ret; @@ -325,7 +326,7 @@ static void apci1032_detach(struct comedi_device *dev) static struct comedi_driver apci1032_driver = { .driver_name = "addi_apci_1032", .module = THIS_MODULE, - .attach_pci = apci1032_attach_pci, + .auto_attach = apci1032_auto_attach, .detach = apci1032_detach, }; diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 66dd94c2690..485f8214516 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -52,9 +52,10 @@ static const void *apci1710_find_boardinfo(struct comedi_device *dev, return NULL; } -static int apci1710_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit apci1710_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct addi_board *this_board; struct addi_private *devpriv; struct comedi_subdevice *s; @@ -117,7 +118,7 @@ static void apci1710_detach(struct comedi_device *dev) static struct comedi_driver apci1710_driver = { .driver_name = "addi_apci_1710", .module = THIS_MODULE, - .attach_pci = apci1710_attach_pci, + .auto_attach = apci1710_auto_attach, .detach = apci1710_detach, }; diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index f65f8271807..34aab504d35 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -60,9 +60,10 @@ static const void *apci3120_find_boardinfo(struct comedi_device *dev, return NULL; } -static int apci3120_attach_pci(struct comedi_device *dev, - struct pci_dev *pcidev) +static int __devinit apci3120_auto_attach(struct comedi_device *dev, + unsigned long context_unused) { + struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct addi_board *this_board; struct addi_private *devpriv; struct comedi_subdevice *s; @@ -240,7 +241,7 @@ static void apci3120_detach(struct comedi_device *dev) static struct comedi_driver apci3120_driver = { .driver_name = "addi_apci_3120", .module = THIS_MODULE, - .attach_pci = apci3120_attach_pci, + .auto_attach = apci3120_auto_attach, .detach = apci3120_detach, }; -- cgit v1.2.3 From c965c8b7d2538d10d77a320e84ddbe51d221f373 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 6 Nov 2012 17:34:24 -0700 Subject: staging: comedi: addi_common.c: fix the test for the PCI bars Commit: 0fcdafb83b9b4e5c48410b3ca91b1f237ad60dbc staging: comedi: addi-data: cleanup reading of the PCI bars Changed this test before reading the PCI bars: if ((this_board->pc_EepromChip == NULL) || (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) { to this: if (!this_board->pc_EepromChip || !strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { I just noticed that the strcmp test is wrong. This fixes the test and adds a comment for it. This error "broke" the addi-data drivers but they are broken anyway since they don't follow the comedi core API. The addi_apci_1032 driver has been converted to follow the comedi core API. This error effects that driver since the iobase for it should be found in PCI bar 1 not 2. This fixes that also. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 4 +++- drivers/staging/comedi/drivers/addi_apci_1032.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 2500d53a6a3..8c0fbf43a7e 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -119,7 +119,8 @@ static int __devinit addi_auto_attach(struct comedi_device *dev, return ret; if (!this_board->pc_EepromChip || - !strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { + strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { + /* board does not have an eeprom or is not ADDIDATA_9054 */ if (this_board->i_IorangeBase1) dev->iobase = pci_resource_start(pcidev, 1); else @@ -129,6 +130,7 @@ static int __devinit addi_auto_attach(struct comedi_device *dev, devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); } else { + /* board has an ADDIDATA_9054 eeprom */ dev->iobase = pci_resource_start(pcidev, 2); devpriv->iobase = pci_resource_start(pcidev, 2); devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 14b5989e41a..060516b7d19 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -265,7 +265,7 @@ static int __devinit apci1032_auto_attach(struct comedi_device *dev, if (ret) return ret; - dev->iobase = pci_resource_start(pcidev, 2); + dev->iobase = pci_resource_start(pcidev, 1); if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, apci1032_interrupt, IRQF_SHARED, -- cgit v1.2.3 From 7803d8e05d63d743e938233eb49fd8f112dfb07e Mon Sep 17 00:00:00 2001 From: Kumar Amit Mehta Date: Wed, 7 Nov 2012 04:08:09 -0800 Subject: staging: comedi: drivers: jr3_pci.c: fix for coding style issue fixed few error and warning messages as reported by checkpatch.pl Signed-off-by: Kumar Amit Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/jr3_pci.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 69f151d62f3..65d65fe23d6 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -360,7 +360,7 @@ static int read_idm_word(const u8 *data, size_t size, int *pos, return result; } -static int jr3_download_firmware(struct comedi_device *dev, const u8 * data, +static int jr3_download_firmware(struct comedi_device *dev, const u8 *data, size_t size) { /* @@ -470,14 +470,13 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s) struct jr3_channel __iomem *channel = p->channel; int errors = get_u16(&channel->errors); - if (errors != p->errors) { + if (errors != p->errors) p->errors = errors; - } - if (errors & (watch_dog | watch_dog2 | sensor_change)) { + + if (errors & (watch_dog | watch_dog2 | sensor_change)) /* Sensor communication lost, force poll mode */ p->state = state_jr3_poll; - } switch (p->state) { case state_jr3_poll: { u16 model_no = get_u16(&channel->model_no); -- cgit v1.2.3 From 54327dd75ea2258d6fe5201382fad2254c008f9e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 8 Nov 2012 17:11:09 +0800 Subject: staging: comedi: usbduxfast: remove unused variable in usbduxfastsub_ai_Irq() The variable 'p' is initialized but never used otherwise, so remove the unused variable. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 845f240304e..5adc3b31a27 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -312,7 +312,6 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) struct usbduxfastsub_s *udfs; struct comedi_device *this_comedidev; struct comedi_subdevice *s; - uint16_t *p; /* sanity checks - is the urb there? */ if (!urb) { @@ -379,7 +378,6 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) return; } - p = urb->transfer_buffer; if (!udfs->ignore) { if (!udfs->ai_continous) { /* not continuous, fixed number of samples */ -- cgit v1.2.3 From 792660d534f284ebe730c21bc05a94fbf9c62fbd Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 9 Nov 2012 10:04:51 +0000 Subject: staging: comedi: addi_apci_1032: check shared interrupt In the interrupt service routine, check the device is asserting the shared interrupt line and check that interrupts have been enabled. When attaching the device, disable interrupts before setting up the interrupt handler to avoid handling spurious interrupts before the device is ready. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 060516b7d19..dc285307a63 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -31,6 +31,7 @@ #include "../comedidev.h" #include "comedi_fc.h" +#include "amcc_s5933.h" /* * I/O Register Map @@ -45,6 +46,7 @@ #define APCI1032_CTRL_INT_ENA (1 << 2) struct apci1032_private { + unsigned long amcc_iobase; /* base of AMCC I/O registers */ unsigned int mode1; /* rising-edge/high level channels */ unsigned int mode2; /* falling-edge/low level channels */ unsigned int ctrl; /* interrupt mode OR (edge) . AND (level) */ @@ -218,11 +220,21 @@ static int apci1032_cos_cancel(struct comedi_device *dev, static irqreturn_t apci1032_interrupt(int irq, void *d) { struct comedi_device *dev = d; + struct apci1032_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; unsigned int ctrl; - /* disable the interrupt */ + /* check interrupt is from this device */ + if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) & + INTCSR_INTR_ASSERTED) == 0) + return IRQ_NONE; + + /* check interrupt is enabled */ ctrl = inl(dev->iobase + APCI1032_CTRL_REG); + if ((ctrl & APCI1032_CTRL_INT_ENA) == 0) + return IRQ_HANDLED; + + /* disable the interrupt */ outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG); s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff; @@ -265,8 +277,9 @@ static int __devinit apci1032_auto_attach(struct comedi_device *dev, if (ret) return ret; + devpriv->amcc_iobase = pci_resource_start(pcidev, 0); dev->iobase = pci_resource_start(pcidev, 1); - + apci1032_reset(dev); if (pcidev->irq > 0) { ret = request_irq(pcidev->irq, apci1032_interrupt, IRQF_SHARED, dev->board_name, dev); @@ -305,7 +318,6 @@ static int __devinit apci1032_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - apci1032_reset(dev); return 0; } -- cgit v1.2.3 From e5711071ad94794cab0c321c8526183a74f11db2 Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Fri, 2 Nov 2012 08:16:33 -0400 Subject: staging: fwserial: Add TTY-over-Firewire serial driver This patch provides the kernel driver for high-speed TTY communication over the IEEE 1394 bus. Signed-off-by: Peter Hurley Acked-by: Stefan Richter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/fwserial/Kconfig | 9 + drivers/staging/fwserial/Makefile | 2 + drivers/staging/fwserial/TODO | 37 + drivers/staging/fwserial/dma_fifo.c | 310 ++++ drivers/staging/fwserial/dma_fifo.h | 130 ++ drivers/staging/fwserial/fwserial.c | 2946 +++++++++++++++++++++++++++++++++++ drivers/staging/fwserial/fwserial.h | 387 +++++ 9 files changed, 3824 insertions(+) create mode 100644 drivers/staging/fwserial/Kconfig create mode 100644 drivers/staging/fwserial/Makefile create mode 100644 drivers/staging/fwserial/TODO create mode 100644 drivers/staging/fwserial/dma_fifo.c create mode 100644 drivers/staging/fwserial/dma_fifo.h create mode 100644 drivers/staging/fwserial/fwserial.c create mode 100644 drivers/staging/fwserial/fwserial.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 231a2729d34..12a6f2e0aee 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -140,4 +140,6 @@ source "drivers/staging/imx-drm/Kconfig" source "drivers/staging/dgrp/Kconfig" +source "drivers/staging/fwserial/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 2b291c01c51..6d16f822e27 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -62,3 +62,4 @@ obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/ obj-$(CONFIG_CED1401) += ced1401/ obj-$(CONFIG_DRM_IMX) += imx-drm/ obj-$(CONFIG_DGRP) += dgrp/ +obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/ diff --git a/drivers/staging/fwserial/Kconfig b/drivers/staging/fwserial/Kconfig new file mode 100644 index 00000000000..580406cb180 --- /dev/null +++ b/drivers/staging/fwserial/Kconfig @@ -0,0 +1,9 @@ +config FIREWIRE_SERIAL + tristate "TTY over Firewire" + depends on FIREWIRE + help + This enables TTY over IEEE 1394, providing high-speed serial + connectivity to cabled peers. + + To compile this driver as a module, say M here: the module will + be called firewire-serial. diff --git a/drivers/staging/fwserial/Makefile b/drivers/staging/fwserial/Makefile new file mode 100644 index 00000000000..2170869a19b --- /dev/null +++ b/drivers/staging/fwserial/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_FIREWIRE_SERIAL) += firewire-serial.o +firewire-serial-objs := fwserial.o dma_fifo.o diff --git a/drivers/staging/fwserial/TODO b/drivers/staging/fwserial/TODO new file mode 100644 index 00000000000..726900548ea --- /dev/null +++ b/drivers/staging/fwserial/TODO @@ -0,0 +1,37 @@ +TODOs +----- +1. Implement retries for RCODE_BUSY, RCODE_NO_ACK and RCODE_SEND_ERROR + - I/O is handled asynchronously which presents some issues when error + conditions occur. +2. Implement _robust_ console on top of this. The existing prototype console + driver is not ready for the big leagues yet. +3. Expose means of controlling attach/detach of peers via sysfs. Include + GUID-to-port matching/whitelist/blacklist. + +-- Issues with firewire stack -- +1. This driver uses the same unregistered vendor id that the firewire core does + (0xd00d1e). Perhaps this could be exposed as a define in + firewire-constants.h? +2. MAX_ASYNC_PAYLOAD needs to be publicly exposed by core/ohci + - otherwise how will this driver know the max size of address window to + open for one packet write? +3. Maybe device_max_receive() and link_speed_to_max_payload() should be + taken up by the firewire core? +4. To avoid dropping rx data while still limiting the maximum buffering, + the size of the AR context must be known. How to expose this to drivers? +5. Explore if bigger AR context will reduce RCODE_BUSY responses + (or auto-grow to certain max size -- but this would require major surgery + as the current AR is contiguously mapped) + +-- Issues with TTY core -- + 1. Hack for alternate device name scheme + - because udev no longer allows device renaming, devices should have + their proper names on creation. This is an issue for creating the + fwloop device with the fwtty devices because although duplicating + roughly the same operations as tty_port_register_device() isn't difficult, + access to the tty_class & tty_fops is restricted in scope. + + This is currently being worked around in create_loop_device() by + extracting the tty_class ptr and tty_fops ptr from the previously created + tty devices. Perhaps an add'l api can be added -- eg., + tty_{port_}register_named_device(). diff --git a/drivers/staging/fwserial/dma_fifo.c b/drivers/staging/fwserial/dma_fifo.c new file mode 100644 index 00000000000..72aa0533f01 --- /dev/null +++ b/drivers/staging/fwserial/dma_fifo.c @@ -0,0 +1,310 @@ +/* + * DMA-able FIFO implementation + * + * Copyright (C) 2012 Peter Hurley + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include + +#include "dma_fifo.h" + +#ifdef DEBUG_TRACING +#define df_trace(s, args...) pr_debug(s, ##args) +#else +#define df_trace(s, args...) +#endif + +#define FAIL(fifo, condition, format...) ({ \ + fifo->corrupt = !!(condition); \ + if (unlikely(fifo->corrupt)) { \ + __WARN_printf(format); \ + } \ + unlikely(fifo->corrupt); \ +}) + +/* + * private helper fn to determine if check is in open interval (lo,hi) + */ +static bool addr_check(unsigned check, unsigned lo, unsigned hi) +{ + return check - (lo + 1) < (hi - 1) - lo; +} + +/** + * dma_fifo_init: initialize the fifo to a valid but inoperative state + * @fifo: address of in-place "struct dma_fifo" object + */ +void dma_fifo_init(struct dma_fifo *fifo) +{ + memset(fifo, 0, sizeof(*fifo)); + INIT_LIST_HEAD(&fifo->pending); +} + +/** + * dma_fifo_alloc - initialize and allocate dma_fifo + * @fifo: address of in-place "struct dma_fifo" object + * @size: 'apparent' size, in bytes, of fifo + * @align: dma alignment to maintain (should be at least cpu cache alignment), + * must be power of 2 + * @tx_limit: maximum # of bytes transmissable per dma (rounded down to + * multiple of alignment, but at least align size) + * @open_limit: maximum # of outstanding dma transactions allowed + * @gfp_mask: get_free_pages mask, passed to kmalloc() + * + * The 'apparent' size will be rounded up to next greater aligned size. + * Returns 0 if no error, otherwise an error code + */ +int dma_fifo_alloc(struct dma_fifo *fifo, int size, unsigned align, + int tx_limit, int open_limit, gfp_t gfp_mask) +{ + int capacity; + + if (!is_power_of_2(align) || size < 0) + return -EINVAL; + + size = round_up(size, align); + capacity = size + align * open_limit + align * DMA_FIFO_GUARD; + fifo->data = kmalloc(capacity, gfp_mask); + if (!fifo->data) + return -ENOMEM; + + fifo->in = 0; + fifo->out = 0; + fifo->done = 0; + fifo->size = size; + fifo->avail = size; + fifo->align = align; + fifo->tx_limit = max_t(int, round_down(tx_limit, align), align); + fifo->open = 0; + fifo->open_limit = open_limit; + fifo->guard = size + align * open_limit; + fifo->capacity = capacity; + fifo->corrupt = 0; + + return 0; +} + +/** + * dma_fifo_free - frees the fifo + * @fifo: address of in-place "struct dma_fifo" to free + * + * Also reinits the fifo to a valid but inoperative state. This + * allows the fifo to be reused with a different target requiring + * different fifo parameters. + */ +void dma_fifo_free(struct dma_fifo *fifo) +{ + struct dma_pending *pending, *next; + + if (fifo->data == NULL) + return; + + list_for_each_entry_safe(pending, next, &fifo->pending, link) + list_del_init(&pending->link); + kfree(fifo->data); + fifo->data = NULL; +} + +/** + * dma_fifo_reset - dumps the fifo contents and reinits for reuse + * @fifo: address of in-place "struct dma_fifo" to reset + */ +void dma_fifo_reset(struct dma_fifo *fifo) +{ + struct dma_pending *pending, *next; + + if (fifo->data == NULL) + return; + + list_for_each_entry_safe(pending, next, &fifo->pending, link) + list_del_init(&pending->link); + fifo->in = 0; + fifo->out = 0; + fifo->done = 0; + fifo->avail = fifo->size; + fifo->open = 0; + fifo->corrupt = 0; +} + +/** + * dma_fifo_in - copies data into the fifo + * @fifo: address of in-place "struct dma_fifo" to write to + * @src: buffer to copy from + * @n: # of bytes to copy + * + * Returns the # of bytes actually copied, which can be less than requested if + * the fifo becomes full. If < 0, return is error code. + */ +int dma_fifo_in(struct dma_fifo *fifo, const void *src, int n) +{ + int ofs, l; + + if (fifo->data == NULL) + return -ENOENT; + if (fifo->corrupt) + return -ENXIO; + + if (n > fifo->avail) + n = fifo->avail; + if (n <= 0) + return 0; + + ofs = fifo->in % fifo->capacity; + l = min(n, fifo->capacity - ofs); + memcpy(fifo->data + ofs, src, l); + memcpy(fifo->data, src + l, n - l); + + if (FAIL(fifo, addr_check(fifo->done, fifo->in, fifo->in + n) || + fifo->avail < n, + "fifo corrupt: in:%u out:%u done:%u n:%d avail:%d", + fifo->in, fifo->out, fifo->done, n, fifo->avail)) + return -ENXIO; + + fifo->in += n; + fifo->avail -= n; + + df_trace("in:%u out:%u done:%u n:%d avail:%d", fifo->in, fifo->out, + fifo->done, n, fifo->avail); + + return n; +} + +/** + * dma_fifo_out_pend - gets address/len of next avail read and marks as pended + * @fifo: address of in-place "struct dma_fifo" to read from + * @pended: address of structure to fill with read address/len + * The data/len fields will be NULL/0 if no dma is pended. + * + * Returns the # of used bytes remaining in fifo (ie, if > 0, more data + * remains in the fifo that was not pended). If < 0, return is error code. + */ +int dma_fifo_out_pend(struct dma_fifo *fifo, struct dma_pending *pended) +{ + unsigned len, n, ofs, l, limit; + + if (fifo->data == NULL) + return -ENOENT; + if (fifo->corrupt) + return -ENXIO; + + pended->len = 0; + pended->data = NULL; + pended->out = fifo->out; + + len = fifo->in - fifo->out; + if (!len) + return -ENODATA; + if (fifo->open == fifo->open_limit) + return -EAGAIN; + + n = len; + ofs = fifo->out % fifo->capacity; + l = fifo->capacity - ofs; + limit = min_t(unsigned, l, fifo->tx_limit); + if (n > limit) { + n = limit; + fifo->out += limit; + } else if (ofs + n > fifo->guard) { + fifo->out += l; + fifo->in = fifo->out; + } else { + fifo->out += round_up(n, fifo->align); + fifo->in = fifo->out; + } + + df_trace("in: %u out: %u done: %u n: %d len: %u avail: %d", fifo->in, + fifo->out, fifo->done, n, len, fifo->avail); + + pended->len = n; + pended->data = fifo->data + ofs; + pended->next = fifo->out; + list_add_tail(&pended->link, &fifo->pending); + ++fifo->open; + + if (FAIL(fifo, fifo->open > fifo->open_limit, + "past open limit:%d (limit:%d)", + fifo->open, fifo->open_limit)) + return -ENXIO; + if (FAIL(fifo, fifo->out & (fifo->align - 1), + "fifo out unaligned:%u (align:%u)", + fifo->out, fifo->align)) + return -ENXIO; + + return len - n; +} + +/** + * dma_fifo_out_complete - marks pended dma as completed + * @fifo: address of in-place "struct dma_fifo" which was read from + * @complete: address of structure for previously pended dma to mark completed + */ +int dma_fifo_out_complete(struct dma_fifo *fifo, struct dma_pending *complete) +{ + struct dma_pending *pending, *next, *tmp; + + if (fifo->data == NULL) + return -ENOENT; + if (fifo->corrupt) + return -ENXIO; + if (list_empty(&fifo->pending) && fifo->open == 0) + return -EINVAL; + + if (FAIL(fifo, list_empty(&fifo->pending) != (fifo->open == 0), + "pending list disagrees with open count:%d", + fifo->open)) + return -ENXIO; + + tmp = complete->data; + *tmp = *complete; + list_replace(&complete->link, &tmp->link); + dp_mark_completed(tmp); + + /* Only update the fifo in the original pended order */ + list_for_each_entry_safe(pending, next, &fifo->pending, link) { + if (!dp_is_completed(pending)) { + df_trace("still pending: saved out: %u len: %d", + pending->out, pending->len); + break; + } + + if (FAIL(fifo, pending->out != fifo->done || + addr_check(fifo->in, fifo->done, pending->next), + "in:%u out:%u done:%u saved:%u next:%u", + fifo->in, fifo->out, fifo->done, pending->out, + pending->next)) + return -ENXIO; + + list_del_init(&pending->link); + fifo->done = pending->next; + fifo->avail += pending->len; + --fifo->open; + + df_trace("in: %u out: %u done: %u len: %u avail: %d", fifo->in, + fifo->out, fifo->done, pending->len, fifo->avail); + } + + if (FAIL(fifo, fifo->open < 0, "open dma:%d < 0", fifo->open)) + return -ENXIO; + if (FAIL(fifo, fifo->avail > fifo->size, "fifo avail:%d > size:%d", + fifo->avail, fifo->size)) + return -ENXIO; + + return 0; +} diff --git a/drivers/staging/fwserial/dma_fifo.h b/drivers/staging/fwserial/dma_fifo.h new file mode 100644 index 00000000000..a113fe1e6f1 --- /dev/null +++ b/drivers/staging/fwserial/dma_fifo.h @@ -0,0 +1,130 @@ +/* + * DMA-able FIFO interface + * + * Copyright (C) 2012 Peter Hurley + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _DMA_FIFO_H_ +#define _DMA_FIFO_H_ + +/** + * The design basis for the DMA FIFO is to provide an output side that + * complies with the streaming DMA API design that can be DMA'd from directly + * (without additional copying), coupled with an input side that maintains a + * logically consistent 'apparent' size (ie, bytes in + bytes avail is static + * for the lifetime of the FIFO). + * + * DMA output transactions originate on a cache line boundary and can be + * variably-sized. DMA output transactions can be retired out-of-order but + * the FIFO will only advance the output in the original input sequence. + * This means the FIFO will eventually stall if a transaction is never retired. + * + * Chunking the output side into cache line multiples means that some FIFO + * memory is unused. For example, if all the avail input has been pended out, + * then the in and out markers are re-aligned to the next cache line. + * The maximum possible waste is + * (cache line alignment - 1) * (max outstanding dma transactions) + * This potential waste requires additional hidden capacity within the FIFO + * to be able to accept input while the 'apparent' size has not been reached. + * + * Additional cache lines (ie, guard area) are used to minimize DMA + * fragmentation when wrapping at the end of the FIFO. Input is allowed into the + * guard area, but the in and out FIFO markers are wrapped when DMA is pended. + */ + +#define DMA_FIFO_GUARD 3 /* # of cache lines to reserve for the guard area */ + +struct dma_fifo { + unsigned in; + unsigned out; /* updated when dma is pended */ + unsigned done; /* updated upon dma completion */ + struct { + unsigned corrupt:1; + }; + int size; /* 'apparent' size of fifo */ + int guard; /* ofs of guard area */ + int capacity; /* size + reserved */ + int avail; /* # of unused bytes in fifo */ + unsigned align; /* must be power of 2 */ + int tx_limit; /* max # of bytes per dma transaction */ + int open_limit; /* max # of outstanding allowed */ + int open; /* # of outstanding dma transactions */ + struct list_head pending; /* fifo markers for outstanding dma */ + void *data; +}; + +struct dma_pending { + struct list_head link; + void *data; + unsigned len; + unsigned next; + unsigned out; +}; + +static inline void dp_mark_completed(struct dma_pending *dp) +{ + dp->data += 1; +} + +static inline bool dp_is_completed(struct dma_pending *dp) +{ + return (unsigned long)dp->data & 1UL; +} + +extern void dma_fifo_init(struct dma_fifo *fifo); +extern int dma_fifo_alloc(struct dma_fifo *fifo, int size, unsigned align, + int tx_limit, int open_limit, gfp_t gfp_mask); +extern void dma_fifo_free(struct dma_fifo *fifo); +extern void dma_fifo_reset(struct dma_fifo *fifo); +extern int dma_fifo_in(struct dma_fifo *fifo, const void *src, int n); +extern int dma_fifo_out_pend(struct dma_fifo *fifo, struct dma_pending *pended); +extern int dma_fifo_out_complete(struct dma_fifo *fifo, + struct dma_pending *complete); + +/* returns the # of used bytes in the fifo */ +static inline int dma_fifo_level(struct dma_fifo *fifo) +{ + return fifo->size - fifo->avail; +} + +/* returns the # of bytes ready for output in the fifo */ +static inline int dma_fifo_out_level(struct dma_fifo *fifo) +{ + return fifo->in - fifo->out; +} + +/* returns the # of unused bytes in the fifo */ +static inline int dma_fifo_avail(struct dma_fifo *fifo) +{ + return fifo->avail; +} + +/* returns true if fifo has max # of outstanding dmas */ +static inline bool dma_fifo_busy(struct dma_fifo *fifo) +{ + return fifo->open == fifo->open_limit; +} + +/* changes the max size of dma returned from dma_fifo_out_pend() */ +static inline int dma_fifo_change_tx_limit(struct dma_fifo *fifo, int tx_limit) +{ + tx_limit = round_down(tx_limit, fifo->align); + fifo->tx_limit = max_t(int, tx_limit, fifo->align); + return 0; +} + +#endif /* _DMA_FIFO_H_ */ diff --git a/drivers/staging/fwserial/fwserial.c b/drivers/staging/fwserial/fwserial.c new file mode 100644 index 00000000000..5d4d64a3ea8 --- /dev/null +++ b/drivers/staging/fwserial/fwserial.c @@ -0,0 +1,2946 @@ +/* + * FireWire Serial driver + * + * Copyright (C) 2012 Peter Hurley + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fwserial.h" + +#define be32_to_u64(hi, lo) ((u64)be32_to_cpu(hi) << 32 | be32_to_cpu(lo)) + +#define LINUX_VENDOR_ID 0xd00d1eU /* same id used in card root directory */ +#define FWSERIAL_VERSION 0x00e81cU /* must be unique within LINUX_VENDOR_ID */ + +/* configurable options */ +static int num_ttys = 4; /* # of std ttys to create per fw_card */ + /* - doubles as loopback port index */ +static bool auto_connect = true; /* try to VIRT_CABLE to every peer */ +static bool create_loop_dev = true; /* create a loopback device for each card */ +bool limit_bw; /* limit async bandwidth to 20% of max */ + +module_param_named(ttys, num_ttys, int, S_IRUGO | S_IWUSR); +module_param_named(auto, auto_connect, bool, S_IRUGO | S_IWUSR); +module_param_named(loop, create_loop_dev, bool, S_IRUGO | S_IWUSR); +module_param(limit_bw, bool, S_IRUGO | S_IWUSR); + +/* + * Threshold below which the tty is woken for writing + * - should be equal to WAKEUP_CHARS in drivers/tty/n_tty.c because + * even if the writer is woken, n_tty_poll() won't set POLLOUT until + * our fifo is below this level + */ +#define WAKEUP_CHARS 256 + +/** + * fwserial_list: list of every fw_serial created for each fw_card + * See discussion in fwserial_probe. + */ +static LIST_HEAD(fwserial_list); +static DEFINE_MUTEX(fwserial_list_mutex); + +/** + * port_table: array of tty ports allocated to each fw_card + * + * tty ports are allocated during probe when an fw_serial is first + * created for a given fw_card. Ports are allocated in a contiguous block, + * each block consisting of 'num_ports' ports. + */ +static struct fwtty_port *port_table[MAX_TOTAL_PORTS]; +static DEFINE_MUTEX(port_table_lock); +static bool port_table_corrupt; +#define FWTTY_INVALID_INDEX MAX_TOTAL_PORTS + +/* total # of tty ports created per fw_card */ +static int num_ports; + +/* slab used as pool for struct fwtty_transactions */ +static struct kmem_cache *fwtty_txn_cache; + +struct fwtty_transaction; +typedef void (*fwtty_transaction_cb)(struct fw_card *card, int rcode, + void *data, size_t length, + struct fwtty_transaction *txn); + +struct fwtty_transaction { + struct fw_transaction fw_txn; + fwtty_transaction_cb callback; + struct fwtty_port *port; + union { + struct dma_pending dma_pended; + }; +}; + +#define to_device(a, b) (a->b) +#define fwtty_err(p, s, v...) dev_err(to_device(p, device), s, ##v) +#define fwtty_info(p, s, v...) dev_info(to_device(p, device), s, ##v) +#define fwtty_notice(p, s, v...) dev_notice(to_device(p, device), s, ##v) +#define fwtty_dbg(p, s, v...) \ + dev_dbg(to_device(p, device), "%s: " s, __func__, ##v) +#define fwtty_err_ratelimited(p, s, v...) \ + dev_err_ratelimited(to_device(p, device), s, ##v) + +#ifdef DEBUG +static inline void debug_short_write(struct fwtty_port *port, int c, int n) +{ + int avail; + + if (n < c) { + spin_lock_bh(&port->lock); + avail = dma_fifo_avail(&port->tx_fifo); + spin_unlock_bh(&port->lock); + fwtty_dbg(port, "short write: avail:%d req:%d wrote:%d", + avail, c, n); + } +} +#else +#define debug_short_write(port, c, n) +#endif + +static struct fwtty_peer *__fwserial_peer_by_node_id(struct fw_card *card, + int generation, int id); + +#ifdef FWTTY_PROFILING + +static void profile_fifo_avail(struct fwtty_port *port, unsigned *stat) +{ + spin_lock_bh(&port->lock); + profile_size_distrib(stat, dma_fifo_avail(&port->tx_fifo)); + spin_unlock_bh(&port->lock); +} + +static void dump_profile(struct seq_file *m, struct stats *stats) +{ + /* for each stat, print sum of 0 to 2^k, then individually */ + int k = 4; + unsigned sum; + int j; + char t[10]; + + snprintf(t, 10, "< %d", 1 << k); + seq_printf(m, "\n%14s %6s", " ", t); + for (j = k + 1; j < DISTRIBUTION_MAX_INDEX; ++j) + seq_printf(m, "%6d", 1 << j); + + ++k; + for (j = 0, sum = 0; j <= k; ++j) + sum += stats->reads[j]; + seq_printf(m, "\n%14s: %6d", "reads", sum); + for (j = k + 1; j <= DISTRIBUTION_MAX_INDEX; ++j) + seq_printf(m, "%6d", stats->reads[j]); + + for (j = 0, sum = 0; j <= k; ++j) + sum += stats->writes[j]; + seq_printf(m, "\n%14s: %6d", "writes", sum); + for (j = k + 1; j <= DISTRIBUTION_MAX_INDEX; ++j) + seq_printf(m, "%6d", stats->writes[j]); + + for (j = 0, sum = 0; j <= k; ++j) + sum += stats->txns[j]; + seq_printf(m, "\n%14s: %6d", "txns", sum); + for (j = k + 1; j <= DISTRIBUTION_MAX_INDEX; ++j) + seq_printf(m, "%6d", stats->txns[j]); + + for (j = 0, sum = 0; j <= k; ++j) + sum += stats->unthrottle[j]; + seq_printf(m, "\n%14s: %6d", "avail @ unthr", sum); + for (j = k + 1; j <= DISTRIBUTION_MAX_INDEX; ++j) + seq_printf(m, "%6d", stats->unthrottle[j]); +} + +#else +#define profile_fifo_avail(port, stat) +#define dump_profile(m, stats) +#endif + +/* Returns the max receive packet size for the given card */ +static inline int device_max_receive(struct fw_device *fw_device) +{ + return 1 << (clamp_t(int, fw_device->max_rec, 8U, 13U) + 1); +} + +static void fwtty_log_tx_error(struct fwtty_port *port, int rcode) +{ + switch (rcode) { + case RCODE_SEND_ERROR: + fwtty_err_ratelimited(port, "card busy"); + break; + case RCODE_ADDRESS_ERROR: + fwtty_err_ratelimited(port, "bad unit addr or write length"); + break; + case RCODE_DATA_ERROR: + fwtty_err_ratelimited(port, "failed rx"); + break; + case RCODE_NO_ACK: + fwtty_err_ratelimited(port, "missing ack"); + break; + case RCODE_BUSY: + fwtty_err_ratelimited(port, "remote busy"); + break; + default: + fwtty_err_ratelimited(port, "failed tx: %d", rcode); + } +} + +static void fwtty_txn_constructor(void *this) +{ + struct fwtty_transaction *txn = this; + + init_timer(&txn->fw_txn.split_timeout_timer); +} + +static void fwtty_common_callback(struct fw_card *card, int rcode, + void *payload, size_t len, void *cb_data) +{ + struct fwtty_transaction *txn = cb_data; + struct fwtty_port *port = txn->port; + + if (port && rcode != RCODE_COMPLETE) + fwtty_log_tx_error(port, rcode); + if (txn->callback) + txn->callback(card, rcode, payload, len, txn); + kmem_cache_free(fwtty_txn_cache, txn); +} + +static int fwtty_send_data_async(struct fwtty_peer *peer, int tcode, + unsigned long long addr, void *payload, + size_t len, fwtty_transaction_cb callback, + struct fwtty_port *port) +{ + struct fwtty_transaction *txn; + int generation; + + txn = kmem_cache_alloc(fwtty_txn_cache, GFP_ATOMIC); + if (!txn) + return -ENOMEM; + + txn->callback = callback; + txn->port = port; + + generation = peer->generation; + smp_rmb(); + fw_send_request(peer->serial->card, &txn->fw_txn, tcode, + peer->node_id, generation, peer->speed, addr, payload, + len, fwtty_common_callback, txn); + return 0; +} + +static void fwtty_send_txn_async(struct fwtty_peer *peer, + struct fwtty_transaction *txn, int tcode, + unsigned long long addr, void *payload, + size_t len, fwtty_transaction_cb callback, + struct fwtty_port *port) +{ + int generation; + + txn->callback = callback; + txn->port = port; + + generation = peer->generation; + smp_rmb(); + fw_send_request(peer->serial->card, &txn->fw_txn, tcode, + peer->node_id, generation, peer->speed, addr, payload, + len, fwtty_common_callback, txn); +} + + +static void __fwtty_restart_tx(struct fwtty_port *port) +{ + int len, avail; + + len = dma_fifo_out_level(&port->tx_fifo); + if (len) + schedule_delayed_work(&port->drain, 0); + avail = dma_fifo_avail(&port->tx_fifo); + + fwtty_dbg(port, "fifo len: %d avail: %d", len, avail); +} + +static void fwtty_restart_tx(struct fwtty_port *port) +{ + spin_lock_bh(&port->lock); + __fwtty_restart_tx(port); + spin_unlock_bh(&port->lock); +} + +/** + * fwtty_update_port_status - decodes & dispatches line status changes + * + * Note: in loopback, the port->lock is being held. Only use functions that + * don't attempt to reclaim the port->lock. + */ +static void fwtty_update_port_status(struct fwtty_port *port, unsigned status) +{ + unsigned delta; + struct tty_struct *tty; + + /* simulated LSR/MSR status from remote */ + status &= ~MCTRL_MASK; + delta = (port->mstatus ^ status) & ~MCTRL_MASK; + delta &= ~(status & TIOCM_RNG); + port->mstatus = status; + + if (delta & TIOCM_RNG) + ++port->icount.rng; + if (delta & TIOCM_DSR) + ++port->icount.dsr; + if (delta & TIOCM_CAR) + ++port->icount.dcd; + if (delta & TIOCM_CTS) + ++port->icount.cts; + + fwtty_dbg(port, "status: %x delta: %x", status, delta); + + if (delta & TIOCM_CAR) { + tty = tty_port_tty_get(&port->port); + if (tty && !C_CLOCAL(tty)) { + if (status & TIOCM_CAR) + wake_up_interruptible(&port->port.open_wait); + else + schedule_work(&port->hangup); + } + tty_kref_put(tty); + } + + if (delta & TIOCM_CTS) { + tty = tty_port_tty_get(&port->port); + if (tty && C_CRTSCTS(tty)) { + if (tty->hw_stopped) { + if (status & TIOCM_CTS) { + tty->hw_stopped = 0; + if (port->loopback) + __fwtty_restart_tx(port); + else + fwtty_restart_tx(port); + } + } else { + if (~status & TIOCM_CTS) + tty->hw_stopped = 1; + } + } + tty_kref_put(tty); + + } else if (delta & OOB_TX_THROTTLE) { + tty = tty_port_tty_get(&port->port); + if (tty) { + if (tty->hw_stopped) { + if (~status & OOB_TX_THROTTLE) { + tty->hw_stopped = 0; + if (port->loopback) + __fwtty_restart_tx(port); + else + fwtty_restart_tx(port); + } + } else { + if (status & OOB_TX_THROTTLE) + tty->hw_stopped = 1; + } + } + tty_kref_put(tty); + } + + if (delta & (UART_LSR_BI << 24)) { + if (status & (UART_LSR_BI << 24)) { + port->break_last = jiffies; + schedule_delayed_work(&port->emit_breaks, 0); + } else { + /* run emit_breaks one last time (if pending) */ + mod_delayed_work(system_wq, &port->emit_breaks, 0); + } + } + + if (delta & (TIOCM_DSR | TIOCM_CAR | TIOCM_CTS | TIOCM_RNG)) + wake_up_interruptible(&port->port.delta_msr_wait); +} + +/** + * __fwtty_port_line_status - generate 'line status' for indicated port + * + * This function returns a remote 'MSR' state based on the local 'MCR' state, + * as if a null modem cable was attached. The actual status is a mangling + * of TIOCM_* bits suitable for sending to a peer's status_addr. + * + * Note: caller must be holding port lock + */ +static unsigned __fwtty_port_line_status(struct fwtty_port *port) +{ + unsigned status = 0; + + /* TODO: add module param to tie RNG to DTR as well */ + + if (port->mctrl & TIOCM_DTR) + status |= TIOCM_DSR | TIOCM_CAR; + if (port->mctrl & TIOCM_RTS) + status |= TIOCM_CTS; + if (port->mctrl & OOB_RX_THROTTLE) + status |= OOB_TX_THROTTLE; + /* emulate BRK as add'l line status */ + if (port->break_ctl) + status |= UART_LSR_BI << 24; + + return status; +} + +/** + * __fwtty_write_port_status - send the port line status to peer + * + * Note: caller must be holding the port lock. + */ +static int __fwtty_write_port_status(struct fwtty_port *port) +{ + struct fwtty_peer *peer; + int err = -ENOENT; + unsigned status = __fwtty_port_line_status(port); + + rcu_read_lock(); + peer = rcu_dereference(port->peer); + if (peer) { + err = fwtty_send_data_async(peer, TCODE_WRITE_QUADLET_REQUEST, + peer->status_addr, &status, + sizeof(status), NULL, port); + } + rcu_read_unlock(); + + return err; +} + +/** + * fwtty_write_port_status - same as above but locked by port lock + */ +static int fwtty_write_port_status(struct fwtty_port *port) +{ + int err; + + spin_lock_bh(&port->lock); + err = __fwtty_write_port_status(port); + spin_unlock_bh(&port->lock); + return err; +} + +static void __fwtty_throttle(struct fwtty_port *port, struct tty_struct *tty) +{ + unsigned old; + + old = port->mctrl; + port->mctrl |= OOB_RX_THROTTLE; + if (C_CRTSCTS(tty)) + port->mctrl &= ~TIOCM_RTS; + if (~old & OOB_RX_THROTTLE) + __fwtty_write_port_status(port); +} + +/** + * fwtty_do_hangup - wait for ldisc to deliver all pending rx; only then hangup + * + * When the remote has finished tx, and all in-flight rx has been received and + * and pushed to the flip buffer, the remote may close its device. This will + * drop DTR on the remote which will drop carrier here. Typically, the tty is + * hung up when carrier is dropped or lost. + * + * However, there is a race between the hang up and the line discipline + * delivering its data to the reader. A hangup will cause the ldisc to flush + * (ie., clear) the read buffer and flip buffer. Because of firewire's + * relatively high throughput, the ldisc frequently lags well behind the driver, + * resulting in lost data (which has already been received and written to + * the flip buffer) when the remote closes its end. + * + * Unfortunately, since the flip buffer offers no direct method for determining + * if it holds data, ensuring the ldisc has delivered all data is problematic. + */ + +/* FIXME: drop this workaround when __tty_hangup waits for ldisc completion */ +static void fwtty_do_hangup(struct work_struct *work) +{ + struct fwtty_port *port = to_port(work, hangup); + struct tty_struct *tty; + + schedule_timeout_uninterruptible(msecs_to_jiffies(50)); + + tty = tty_port_tty_get(&port->port); + if (tty) + tty_vhangup(tty); + tty_kref_put(tty); +} + + +static void fwtty_emit_breaks(struct work_struct *work) +{ + struct fwtty_port *port = to_port(to_delayed_work(work), emit_breaks); + struct tty_struct *tty; + static const char buf[16]; + unsigned long now = jiffies; + unsigned long elapsed = now - port->break_last; + int n, t, c, brk = 0; + + tty = tty_port_tty_get(&port->port); + if (!tty) + return; + + /* generate breaks at the line rate (but at least 1) */ + n = (elapsed * port->cps) / HZ + 1; + port->break_last = now; + + fwtty_dbg(port, "sending %d brks", n); + + while (n) { + t = min(n, 16); + c = tty_insert_flip_string_fixed_flag(tty, buf, TTY_BREAK, t); + n -= c; + brk += c; + if (c < t) + break; + } + tty_flip_buffer_push(tty); + + tty_kref_put(tty); + + if (port->mstatus & (UART_LSR_BI << 24)) + schedule_delayed_work(&port->emit_breaks, FREQ_BREAKS); + port->icount.brk += brk; +} + +static void fwtty_pushrx(struct work_struct *work) +{ + struct fwtty_port *port = to_port(work, push); + struct tty_struct *tty; + struct buffered_rx *buf, *next; + int n, c = 0; + + tty = tty_port_tty_get(&port->port); + if (!tty) + return; + + spin_lock_bh(&port->lock); + list_for_each_entry_safe(buf, next, &port->buf_list, list) { + n = tty_insert_flip_string_fixed_flag(tty, buf->data, + TTY_NORMAL, buf->n); + c += n; + port->buffered -= n; + if (n < buf->n) { + if (n > 0) { + memmove(buf->data, buf->data + n, buf->n - n); + buf->n -= n; + } + __fwtty_throttle(port, tty); + break; + } else { + list_del(&buf->list); + kfree(buf); + } + } + if (c > 0) + tty_flip_buffer_push(tty); + + if (list_empty(&port->buf_list)) + clear_bit(BUFFERING_RX, &port->flags); + spin_unlock_bh(&port->lock); + + tty_kref_put(tty); +} + +static int fwtty_buffer_rx(struct fwtty_port *port, unsigned char *d, size_t n) +{ + struct buffered_rx *buf; + size_t size = (n + sizeof(struct buffered_rx) + 0xFF) & ~0xFF; + + if (port->buffered + n > HIGH_WATERMARK) + return 0; + buf = kmalloc(size, GFP_ATOMIC); + if (!buf) + return 0; + INIT_LIST_HEAD(&buf->list); + buf->n = n; + memcpy(buf->data, d, n); + + spin_lock_bh(&port->lock); + list_add_tail(&buf->list, &port->buf_list); + port->buffered += n; + if (port->buffered > port->stats.watermark) + port->stats.watermark = port->buffered; + set_bit(BUFFERING_RX, &port->flags); + spin_unlock_bh(&port->lock); + + return n; +} + +static int fwtty_rx(struct fwtty_port *port, unsigned char *data, size_t len) +{ + struct tty_struct *tty; + int c, n = len; + unsigned lsr; + int err = 0; + + tty = tty_port_tty_get(&port->port); + if (!tty) + return -ENOENT; + + fwtty_dbg(port, "%d", n); + profile_size_distrib(port->stats.reads, n); + + if (port->write_only) { + n = 0; + goto out; + } + + /* disregard break status; breaks are generated by emit_breaks work */ + lsr = (port->mstatus >> 24) & ~UART_LSR_BI; + + if (port->overrun) + lsr |= UART_LSR_OE; + + if (lsr & UART_LSR_OE) + ++port->icount.overrun; + + lsr &= port->status_mask; + if (lsr & ~port->ignore_mask & UART_LSR_OE) { + if (!tty_insert_flip_char(tty, 0, TTY_OVERRUN)) { + err = -EIO; + goto out; + } + } + port->overrun = false; + + if (lsr & port->ignore_mask & ~UART_LSR_OE) { + /* TODO: don't drop SAK and Magic SysRq here */ + n = 0; + goto out; + } + + if (!test_bit(BUFFERING_RX, &port->flags)) { + c = tty_insert_flip_string_fixed_flag(tty, data, TTY_NORMAL, n); + if (c > 0) + tty_flip_buffer_push(tty); + n -= c; + + if (n) { + /* start buffering and throttling */ + n -= fwtty_buffer_rx(port, &data[c], n); + + spin_lock_bh(&port->lock); + __fwtty_throttle(port, tty); + spin_unlock_bh(&port->lock); + } + } else + n -= fwtty_buffer_rx(port, data, n); + + if (n) { + port->overrun = true; + err = -EIO; + } + +out: + tty_kref_put(tty); + + port->icount.rx += len; + port->stats.lost += n; + return err; +} + +/** + * fwtty_port_handler - bus address handler for port reads/writes + * @parameters: fw_address_callback_t as specified by firewire core interface + * + * This handler is responsible for handling inbound read/write dma from remotes. + */ +static void fwtty_port_handler(struct fw_card *card, + struct fw_request *request, + int tcode, int destination, int source, + int generation, + unsigned long long addr, + void *data, size_t len, + void *callback_data) +{ + struct fwtty_port *port = callback_data; + struct fwtty_peer *peer; + int err; + int rcode; + + /* Only accept rx from the peer virtual-cabled to this port */ + rcu_read_lock(); + peer = __fwserial_peer_by_node_id(card, generation, source); + rcu_read_unlock(); + if (!peer || peer != rcu_access_pointer(port->peer)) { + rcode = RCODE_ADDRESS_ERROR; + fwtty_err_ratelimited(port, "ignoring unauthenticated data"); + goto respond; + } + + switch (tcode) { + case TCODE_WRITE_QUADLET_REQUEST: + if (addr != port->rx_handler.offset || len != 4) + rcode = RCODE_ADDRESS_ERROR; + else { + fwtty_update_port_status(port, *(unsigned *)data); + rcode = RCODE_COMPLETE; + } + break; + + case TCODE_WRITE_BLOCK_REQUEST: + if (addr != port->rx_handler.offset + 4 || + len > port->rx_handler.length - 4) { + rcode = RCODE_ADDRESS_ERROR; + } else { + err = fwtty_rx(port, data, len); + switch (err) { + case 0: + rcode = RCODE_COMPLETE; + break; + case -EIO: + rcode = RCODE_DATA_ERROR; + break; + default: + rcode = RCODE_CONFLICT_ERROR; + break; + } + } + break; + + default: + rcode = RCODE_TYPE_ERROR; + } + +respond: + fw_send_response(card, request, rcode); +} + +/** + * fwtty_tx_complete - callback for tx dma + * @data: ignored, has no meaning for write txns + * @length: ignored, has no meaning for write txns + * + * The writer must be woken here if the fifo has been emptied because it + * may have slept if chars_in_buffer was != 0 + */ +static void fwtty_tx_complete(struct fw_card *card, int rcode, + void *data, size_t length, + struct fwtty_transaction *txn) +{ + struct fwtty_port *port = txn->port; + struct tty_struct *tty; + int len; + + fwtty_dbg(port, "rcode: %d", rcode); + + switch (rcode) { + case RCODE_COMPLETE: + spin_lock_bh(&port->lock); + dma_fifo_out_complete(&port->tx_fifo, &txn->dma_pended); + len = dma_fifo_level(&port->tx_fifo); + spin_unlock_bh(&port->lock); + + port->icount.tx += txn->dma_pended.len; + break; + + default: + /* TODO: implement retries */ + spin_lock_bh(&port->lock); + dma_fifo_out_complete(&port->tx_fifo, &txn->dma_pended); + len = dma_fifo_level(&port->tx_fifo); + spin_unlock_bh(&port->lock); + + port->stats.dropped += txn->dma_pended.len; + } + + if (len < WAKEUP_CHARS) { + tty = tty_port_tty_get(&port->port); + if (tty) { + tty_wakeup(tty); + tty_kref_put(tty); + } + } +} + +static int fwtty_tx(struct fwtty_port *port, bool drain) +{ + struct fwtty_peer *peer; + struct fwtty_transaction *txn; + struct tty_struct *tty; + int n, len; + + tty = tty_port_tty_get(&port->port); + if (!tty) + return -ENOENT; + + rcu_read_lock(); + peer = rcu_dereference(port->peer); + if (!peer) { + n = -EIO; + goto out; + } + + if (test_and_set_bit(IN_TX, &port->flags)) { + n = -EALREADY; + goto out; + } + + /* try to write as many dma transactions out as possible */ + n = -EAGAIN; + while (!tty->stopped && !tty->hw_stopped && + !test_bit(STOP_TX, &port->flags)) { + txn = kmem_cache_alloc(fwtty_txn_cache, GFP_ATOMIC); + if (!txn) { + n = -ENOMEM; + break; + } + + spin_lock_bh(&port->lock); + n = dma_fifo_out_pend(&port->tx_fifo, &txn->dma_pended); + spin_unlock_bh(&port->lock); + + fwtty_dbg(port, "out: %u rem: %d", txn->dma_pended.len, n); + + if (n < 0) { + kmem_cache_free(fwtty_txn_cache, txn); + if (n == -EAGAIN) + ++port->stats.tx_stall; + else if (n == -ENODATA) + profile_size_distrib(port->stats.txns, 0); + else { + ++port->stats.fifo_errs; + fwtty_err_ratelimited(port, "fifo err: %d", n); + } + break; + } + + profile_size_distrib(port->stats.txns, txn->dma_pended.len); + + fwtty_send_txn_async(peer, txn, TCODE_WRITE_BLOCK_REQUEST, + peer->fifo_addr, txn->dma_pended.data, + txn->dma_pended.len, fwtty_tx_complete, + port); + ++port->stats.sent; + + /* + * Stop tx if the 'last view' of the fifo is empty or if + * this is the writer and there's not enough data to bother + */ + if (n == 0 || (!drain && n < WRITER_MINIMUM)) + break; + } + + if (n >= 0 || n == -EAGAIN || n == -ENOMEM || n == -ENODATA) { + spin_lock_bh(&port->lock); + len = dma_fifo_out_level(&port->tx_fifo); + if (len) { + unsigned long delay = (n == -ENOMEM) ? HZ : 1; + schedule_delayed_work(&port->drain, delay); + } + len = dma_fifo_level(&port->tx_fifo); + spin_unlock_bh(&port->lock); + + /* wakeup the writer */ + if (drain && len < WAKEUP_CHARS) + tty_wakeup(tty); + } + + clear_bit(IN_TX, &port->flags); + wake_up_interruptible(&port->wait_tx); + +out: + rcu_read_unlock(); + tty_kref_put(tty); + return n; +} + +static void fwtty_drain_tx(struct work_struct *work) +{ + struct fwtty_port *port = to_port(to_delayed_work(work), drain); + + fwtty_tx(port, true); +} + +static void fwtty_write_xchar(struct fwtty_port *port, char ch) +{ + struct fwtty_peer *peer; + + ++port->stats.xchars; + + fwtty_dbg(port, "%02x", ch); + + rcu_read_lock(); + peer = rcu_dereference(port->peer); + if (peer) { + fwtty_send_data_async(peer, TCODE_WRITE_BLOCK_REQUEST, + peer->fifo_addr, &ch, sizeof(ch), + NULL, port); + } + rcu_read_unlock(); +} + +struct fwtty_port *fwtty_port_get(unsigned index) +{ + struct fwtty_port *port; + + if (index >= MAX_TOTAL_PORTS) + return NULL; + + mutex_lock(&port_table_lock); + port = port_table[index]; + if (port) + kref_get(&port->serial->kref); + mutex_unlock(&port_table_lock); + return port; +} +EXPORT_SYMBOL(fwtty_port_get); + +static int fwtty_ports_add(struct fw_serial *serial) +{ + int err = -EBUSY; + int i, j; + + if (port_table_corrupt) + return err; + + mutex_lock(&port_table_lock); + for (i = 0; i + num_ports <= MAX_TOTAL_PORTS; i += num_ports) { + if (!port_table[i]) { + for (j = 0; j < num_ports; ++i, ++j) { + serial->ports[j]->index = i; + port_table[i] = serial->ports[j]; + } + err = 0; + break; + } + } + mutex_unlock(&port_table_lock); + return err; +} + +static void fwserial_destroy(struct kref *kref) +{ + struct fw_serial *serial = to_serial(kref, kref); + struct fwtty_port **ports = serial->ports; + int j, i = ports[0]->index; + + synchronize_rcu(); + + mutex_lock(&port_table_lock); + for (j = 0; j < num_ports; ++i, ++j) { + static bool once; + int corrupt = port_table[i] != ports[j]; + if (corrupt && !once) { + WARN(corrupt, "port_table[%d]: %p != ports[%d]: %p", + i, port_table[i], j, ports[j]); + once = true; + port_table_corrupt = true; + } + + port_table[i] = NULL; + } + mutex_unlock(&port_table_lock); + + for (j = 0; j < num_ports; ++j) { + fw_core_remove_address_handler(&ports[j]->rx_handler); + dma_fifo_free(&ports[j]->tx_fifo); + kfree(ports[j]); + } + kfree(serial); +} + +void fwtty_port_put(struct fwtty_port *port) +{ + kref_put(&port->serial->kref, fwserial_destroy); +} +EXPORT_SYMBOL(fwtty_port_put); + +static void fwtty_port_dtr_rts(struct tty_port *tty_port, int on) +{ + struct fwtty_port *port = to_port(tty_port, port); + + fwtty_dbg(port, "on/off: %d", on); + + spin_lock_bh(&port->lock); + /* Don't change carrier state if this is a console */ + if (!port->port.console) { + if (on) + port->mctrl |= TIOCM_DTR | TIOCM_RTS; + else + port->mctrl &= ~(TIOCM_DTR | TIOCM_RTS); + } + + __fwtty_write_port_status(port); + spin_unlock_bh(&port->lock); +} + +/** + * fwtty_port_carrier_raised: required tty_port operation + * + * This port operation is polled after a tty has been opened and is waiting for + * carrier detect -- see drivers/tty/tty_port:tty_port_block_til_ready(). + */ +static int fwtty_port_carrier_raised(struct tty_port *tty_port) +{ + struct fwtty_port *port = to_port(tty_port, port); + int rc; + + rc = (port->mstatus & TIOCM_CAR); + + fwtty_dbg(port, "%d", rc); + + return rc; +} + +static unsigned set_termios(struct fwtty_port *port, struct tty_struct *tty) +{ + unsigned baud, frame; + + baud = tty_termios_baud_rate(&tty->termios); + tty_termios_encode_baud_rate(&tty->termios, baud, baud); + + /* compute bit count of 2 frames */ + frame = 12 + ((C_CSTOPB(tty)) ? 4 : 2) + ((C_PARENB(tty)) ? 2 : 0); + + switch (C_CSIZE(tty)) { + case CS5: + frame -= (C_CSTOPB(tty)) ? 1 : 0; + break; + case CS6: + frame += 2; + break; + case CS7: + frame += 4; + break; + case CS8: + frame += 6; + break; + } + + port->cps = (baud << 1) / frame; + + port->status_mask = UART_LSR_OE; + if (_I_FLAG(tty, BRKINT | PARMRK)) + port->status_mask |= UART_LSR_BI; + + port->ignore_mask = 0; + if (I_IGNBRK(tty)) { + port->ignore_mask |= UART_LSR_BI; + if (I_IGNPAR(tty)) + port->ignore_mask |= UART_LSR_OE; + } + + port->write_only = !C_CREAD(tty); + + /* turn off echo and newline xlat if loopback */ + if (port->loopback) { + tty->termios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHOKE | + ECHONL | ECHOPRT | ECHOCTL); + tty->termios.c_oflag &= ~ONLCR; + } + + return baud; +} + +static int fwtty_port_activate(struct tty_port *tty_port, + struct tty_struct *tty) +{ + struct fwtty_port *port = to_port(tty_port, port); + unsigned baud; + int err; + + set_bit(TTY_IO_ERROR, &tty->flags); + + err = dma_fifo_alloc(&port->tx_fifo, FWTTY_PORT_TXFIFO_LEN, + cache_line_size(), + port->max_payload, + FWTTY_PORT_MAX_PEND_DMA, + GFP_KERNEL); + if (err) + return err; + + spin_lock_bh(&port->lock); + + baud = set_termios(port, tty); + + /* if console, don't change carrier state */ + if (!port->port.console) { + port->mctrl = 0; + if (baud != 0) + port->mctrl = TIOCM_DTR | TIOCM_RTS; + } + + if (C_CRTSCTS(tty) && ~port->mstatus & TIOCM_CTS) + tty->hw_stopped = 1; + + __fwtty_write_port_status(port); + spin_unlock_bh(&port->lock); + + clear_bit(TTY_IO_ERROR, &tty->flags); + + return 0; +} + +/** + * fwtty_port_shutdown + * + * Note: the tty port core ensures this is not the console and + * manages TTY_IO_ERROR properly + */ +static void fwtty_port_shutdown(struct tty_port *tty_port) +{ + struct fwtty_port *port = to_port(tty_port, port); + struct buffered_rx *buf, *next; + + /* TODO: cancel outstanding transactions */ + + cancel_delayed_work_sync(&port->emit_breaks); + cancel_delayed_work_sync(&port->drain); + cancel_work_sync(&port->push); + + spin_lock_bh(&port->lock); + list_for_each_entry_safe(buf, next, &port->buf_list, list) { + list_del(&buf->list); + kfree(buf); + } + port->buffered = 0; + port->flags = 0; + port->break_ctl = 0; + port->overrun = 0; + __fwtty_write_port_status(port); + dma_fifo_free(&port->tx_fifo); + spin_unlock_bh(&port->lock); +} + +static int fwtty_open(struct tty_struct *tty, struct file *fp) +{ + struct fwtty_port *port = tty->driver_data; + + return tty_port_open(&port->port, tty, fp); +} + +static void fwtty_close(struct tty_struct *tty, struct file *fp) +{ + struct fwtty_port *port = tty->driver_data; + + tty_port_close(&port->port, tty, fp); +} + +static void fwtty_hangup(struct tty_struct *tty) +{ + struct fwtty_port *port = tty->driver_data; + + tty_port_hangup(&port->port); +} + +static void fwtty_cleanup(struct tty_struct *tty) +{ + struct fwtty_port *port = tty->driver_data; + + tty->driver_data = NULL; + fwtty_port_put(port); +} + +static int fwtty_install(struct tty_driver *driver, struct tty_struct *tty) +{ + struct fwtty_port *port = fwtty_port_get(tty->index); + int err; + + err = tty_standard_install(driver, tty); + if (!err) + tty->driver_data = port; + else + fwtty_port_put(port); + return err; +} + +static int fwtty_write(struct tty_struct *tty, const unsigned char *buf, int c) +{ + struct fwtty_port *port = tty->driver_data; + int n, len; + + fwtty_dbg(port, "%d", c); + profile_size_distrib(port->stats.writes, c); + + spin_lock_bh(&port->lock); + n = dma_fifo_in(&port->tx_fifo, buf, c); + len = dma_fifo_out_level(&port->tx_fifo); + if (len < DRAIN_THRESHOLD) + schedule_delayed_work(&port->drain, 1); + spin_unlock_bh(&port->lock); + + if (len >= DRAIN_THRESHOLD) + fwtty_tx(port, false); + + debug_short_write(port, c, n); + + return (n < 0) ? 0 : n; +} + +static int fwtty_write_room(struct tty_struct *tty) +{ + struct fwtty_port *port = tty->driver_data; + int n; + + spin_lock_bh(&port->lock); + n = dma_fifo_avail(&port->tx_fifo); + spin_unlock_bh(&port->lock); + + fwtty_dbg(port, "%d", n); + + return n; +} + +static int fwtty_chars_in_buffer(struct tty_struct *tty) +{ + struct fwtty_port *port = tty->driver_data; + int n; + + spin_lock_bh(&port->lock); + n = dma_fifo_level(&port->tx_fifo); + spin_unlock_bh(&port->lock); + + fwtty_dbg(port, "%d", n); + + return n; +} + +static void fwtty_send_xchar(struct tty_struct *tty, char ch) +{ + struct fwtty_port *port = tty->driver_data; + + fwtty_dbg(port, "%02x", ch); + + fwtty_write_xchar(port, ch); +} + +static void fwtty_throttle(struct tty_struct *tty) +{ + struct fwtty_port *port = tty->driver_data; + + /* + * Ignore throttling (but not unthrottling). + * It only makes sense to throttle when data will no longer be + * accepted by the tty flip buffer. For example, it is + * possible for received data to overflow the tty buffer long + * before the line discipline ever has a chance to throttle the driver. + * Additionally, the driver may have already completed the I/O + * but the tty buffer is still emptying, so the line discipline is + * throttling and unthrottling nothing. + */ + + ++port->stats.throttled; +} + +static void fwtty_unthrottle(struct tty_struct *tty) +{ + struct fwtty_port *port = tty->driver_data; + + fwtty_dbg(port, "CRTSCTS: %d", (C_CRTSCTS(tty) != 0)); + + profile_fifo_avail(port, port->stats.unthrottle); + + schedule_work(&port->push); + + spin_lock_bh(&port->lock); + port->mctrl &= ~OOB_RX_THROTTLE; + if (C_CRTSCTS(tty)) + port->mctrl |= TIOCM_RTS; + __fwtty_write_port_status(port); + spin_unlock_bh(&port->lock); +} + +static int check_msr_delta(struct fwtty_port *port, unsigned long mask, + struct async_icount *prev) +{ + struct async_icount now; + int delta; + + now = port->icount; + + delta = ((mask & TIOCM_RNG && prev->rng != now.rng) || + (mask & TIOCM_DSR && prev->dsr != now.dsr) || + (mask & TIOCM_CAR && prev->dcd != now.dcd) || + (mask & TIOCM_CTS && prev->cts != now.cts)); + + *prev = now; + + return delta; +} + +static int wait_msr_change(struct fwtty_port *port, unsigned long mask) +{ + struct async_icount prev; + + prev = port->icount; + + return wait_event_interruptible(port->port.delta_msr_wait, + check_msr_delta(port, mask, &prev)); +} + +static int get_serial_info(struct fwtty_port *port, + struct serial_struct __user *info) +{ + struct serial_struct tmp; + + memset(&tmp, 0, sizeof(tmp)); + + tmp.type = PORT_UNKNOWN; + tmp.line = port->port.tty->index; + tmp.flags = port->port.flags; + tmp.xmit_fifo_size = FWTTY_PORT_TXFIFO_LEN; + tmp.baud_base = 400000000; + tmp.close_delay = port->port.close_delay; + + return (copy_to_user(info, &tmp, sizeof(*info))) ? -EFAULT : 0; +} + +static int set_serial_info(struct fwtty_port *port, + struct serial_struct __user *info) +{ + struct serial_struct tmp; + + if (copy_from_user(&tmp, info, sizeof(tmp))) + return -EFAULT; + + if (tmp.irq != 0 || tmp.port != 0 || tmp.custom_divisor != 0 || + tmp.baud_base != 400000000) + return -EPERM; + + if (!capable(CAP_SYS_ADMIN)) { + if (((tmp.flags & ~ASYNC_USR_MASK) != + (port->port.flags & ~ASYNC_USR_MASK))) + return -EPERM; + } else + port->port.close_delay = tmp.close_delay * HZ / 100; + + return 0; +} + +static int fwtty_ioctl(struct tty_struct *tty, unsigned cmd, + unsigned long arg) +{ + struct fwtty_port *port = tty->driver_data; + int err; + + switch (cmd) { + case TIOCGSERIAL: + mutex_lock(&port->port.mutex); + err = get_serial_info(port, (void __user *)arg); + mutex_unlock(&port->port.mutex); + break; + + case TIOCSSERIAL: + mutex_lock(&port->port.mutex); + err = set_serial_info(port, (void __user *)arg); + mutex_unlock(&port->port.mutex); + break; + + case TIOCMIWAIT: + err = wait_msr_change(port, arg); + break; + + default: + err = -ENOIOCTLCMD; + } + + return err; +} + +static void fwtty_set_termios(struct tty_struct *tty, struct ktermios *old) +{ + struct fwtty_port *port = tty->driver_data; + unsigned baud; + + spin_lock_bh(&port->lock); + baud = set_termios(port, tty); + + if ((baud == 0) && (old->c_cflag & CBAUD)) + port->mctrl &= ~(TIOCM_DTR | TIOCM_RTS); + else if ((baud != 0) && !(old->c_cflag & CBAUD)) { + if (C_CRTSCTS(tty) || !test_bit(TTY_THROTTLED, &tty->flags)) + port->mctrl |= TIOCM_DTR | TIOCM_RTS; + else + port->mctrl |= TIOCM_DTR; + } + __fwtty_write_port_status(port); + spin_unlock_bh(&port->lock); + + if (old->c_cflag & CRTSCTS) { + if (!C_CRTSCTS(tty)) { + tty->hw_stopped = 0; + fwtty_restart_tx(port); + } + } else if (C_CRTSCTS(tty) && ~port->mstatus & TIOCM_CTS) { + tty->hw_stopped = 1; + } +} + +/** + * fwtty_break_ctl - start/stop sending breaks + * + * Signals the remote to start or stop generating simulated breaks. + * First, stop dequeueing from the fifo and wait for writer/drain to leave tx + * before signalling the break line status. This guarantees any pending rx will + * be queued to the line discipline before break is simulated on the remote. + * Conversely, turning off break_ctl requires signalling the line status change, + * then enabling tx. + */ +static int fwtty_break_ctl(struct tty_struct *tty, int state) +{ + struct fwtty_port *port = tty->driver_data; + long ret; + + fwtty_dbg(port, "%d", state); + + if (state == -1) { + set_bit(STOP_TX, &port->flags); + ret = wait_event_interruptible_timeout(port->wait_tx, + !test_bit(IN_TX, &port->flags), + 10); + if (ret == 0 || ret == -ERESTARTSYS) { + clear_bit(STOP_TX, &port->flags); + fwtty_restart_tx(port); + return -EINTR; + } + } + + spin_lock_bh(&port->lock); + port->break_ctl = (state == -1); + __fwtty_write_port_status(port); + spin_unlock_bh(&port->lock); + + if (state == 0) { + spin_lock_bh(&port->lock); + dma_fifo_reset(&port->tx_fifo); + clear_bit(STOP_TX, &port->flags); + spin_unlock_bh(&port->lock); + } + return 0; +} + +static int fwtty_tiocmget(struct tty_struct *tty) +{ + struct fwtty_port *port = tty->driver_data; + unsigned tiocm; + + spin_lock_bh(&port->lock); + tiocm = (port->mctrl & MCTRL_MASK) | (port->mstatus & ~MCTRL_MASK); + spin_unlock_bh(&port->lock); + + fwtty_dbg(port, "%x", tiocm); + + return tiocm; +} + +static int fwtty_tiocmset(struct tty_struct *tty, unsigned set, unsigned clear) +{ + struct fwtty_port *port = tty->driver_data; + + fwtty_dbg(port, "set: %x clear: %x", set, clear); + + /* TODO: simulate loopback if TIOCM_LOOP set */ + + spin_lock_bh(&port->lock); + port->mctrl &= ~(clear & MCTRL_MASK & 0xffff); + port->mctrl |= set & MCTRL_MASK & 0xffff; + __fwtty_write_port_status(port); + spin_unlock_bh(&port->lock); + return 0; +} + +static int fwtty_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount) +{ + struct fwtty_port *port = tty->driver_data; + struct stats stats; + + memcpy(&stats, &port->stats, sizeof(stats)); + if (port->port.console) + (*port->fwcon_ops->stats)(&stats, port->con_data); + + icount->cts = port->icount.cts; + icount->dsr = port->icount.dsr; + icount->rng = port->icount.rng; + icount->dcd = port->icount.dcd; + icount->rx = port->icount.rx; + icount->tx = port->icount.tx + stats.xchars; + icount->frame = port->icount.frame; + icount->overrun = port->icount.overrun; + icount->parity = port->icount.parity; + icount->brk = port->icount.brk; + icount->buf_overrun = port->icount.overrun; + return 0; +} + +static void fwtty_proc_show_port(struct seq_file *m, struct fwtty_port *port) +{ + struct stats stats; + + memcpy(&stats, &port->stats, sizeof(stats)); + if (port->port.console) + (*port->fwcon_ops->stats)(&stats, port->con_data); + + seq_printf(m, " tx:%d rx:%d", port->icount.tx + stats.xchars, + port->icount.rx); + seq_printf(m, " cts:%d dsr:%d rng:%d dcd:%d", port->icount.cts, + port->icount.dsr, port->icount.rng, port->icount.dcd); + seq_printf(m, " fe:%d oe:%d pe:%d brk:%d", port->icount.frame, + port->icount.overrun, port->icount.parity, port->icount.brk); + seq_printf(m, " dr:%d st:%d err:%d lost:%d", stats.dropped, + stats.tx_stall, stats.fifo_errs, stats.lost); + seq_printf(m, " pkts:%d thr:%d wtrmk:%d", stats.sent, stats.throttled, + stats.watermark); + seq_printf(m, " addr:%012llx", port->rx_handler.offset); + + if (port->port.console) { + seq_printf(m, "\n "); + (*port->fwcon_ops->proc_show)(m, port->con_data); + } + + dump_profile(m, &port->stats); +} + +static void fwtty_proc_show_peer(struct seq_file *m, struct fwtty_peer *peer) +{ + int generation = peer->generation; + + smp_rmb(); + seq_printf(m, " %s:", dev_name(&peer->unit->device)); + seq_printf(m, " node:%04x gen:%d", peer->node_id, generation); + seq_printf(m, " sp:%d max:%d guid:%016llx", peer->speed, + peer->max_payload, (unsigned long long) peer->guid); + + if (capable(CAP_SYS_ADMIN)) { + seq_printf(m, " mgmt:%012llx", + (unsigned long long) peer->mgmt_addr); + seq_printf(m, " addr:%012llx", + (unsigned long long) peer->status_addr); + } + seq_putc(m, '\n'); +} + +static int fwtty_proc_show(struct seq_file *m, void *v) +{ + struct fwtty_port *port; + struct fw_serial *serial; + struct fwtty_peer *peer; + int i; + + seq_puts(m, "fwserinfo: 1.0 driver: 1.0\n"); + for (i = 0; i < MAX_TOTAL_PORTS && (port = fwtty_port_get(i)); ++i) { + seq_printf(m, "%2d:", i); + if (capable(CAP_SYS_ADMIN)) + fwtty_proc_show_port(m, port); + fwtty_port_put(port); + seq_printf(m, "\n"); + } + seq_putc(m, '\n'); + + rcu_read_lock(); + list_for_each_entry_rcu(serial, &fwserial_list, list) { + seq_printf(m, "card: %s guid: %016llx\n", + dev_name(serial->card->device), + (unsigned long long) serial->card->guid); + list_for_each_entry_rcu(peer, &serial->peer_list, list) + fwtty_proc_show_peer(m, peer); + } + rcu_read_unlock(); + return 0; +} + +static int fwtty_proc_open(struct inode *inode, struct file *fp) +{ + return single_open(fp, fwtty_proc_show, NULL); +} + +static const struct file_operations fwtty_proc_fops = { + .owner = THIS_MODULE, + .open = fwtty_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static const struct tty_port_operations fwtty_port_ops = { + .dtr_rts = fwtty_port_dtr_rts, + .carrier_raised = fwtty_port_carrier_raised, + .shutdown = fwtty_port_shutdown, + .activate = fwtty_port_activate, +}; + +static const struct tty_operations fwtty_ops = { + .open = fwtty_open, + .close = fwtty_close, + .hangup = fwtty_hangup, + .cleanup = fwtty_cleanup, + .install = fwtty_install, + .write = fwtty_write, + .write_room = fwtty_write_room, + .chars_in_buffer = fwtty_chars_in_buffer, + .send_xchar = fwtty_send_xchar, + .throttle = fwtty_throttle, + .unthrottle = fwtty_unthrottle, + .ioctl = fwtty_ioctl, + .set_termios = fwtty_set_termios, + .break_ctl = fwtty_break_ctl, + .tiocmget = fwtty_tiocmget, + .tiocmset = fwtty_tiocmset, + .get_icount = fwtty_get_icount, + .proc_fops = &fwtty_proc_fops, +}; + +static inline int mgmt_pkt_expected_len(__be16 code) +{ + static const struct fwserial_mgmt_pkt pkt; + + switch (be16_to_cpu(code)) { + case FWSC_VIRT_CABLE_PLUG: + return sizeof(pkt.hdr) + sizeof(pkt.plug_req); + + case FWSC_VIRT_CABLE_PLUG_RSP: /* | FWSC_RSP_OK */ + return sizeof(pkt.hdr) + sizeof(pkt.plug_rsp); + + + case FWSC_VIRT_CABLE_UNPLUG: + case FWSC_VIRT_CABLE_UNPLUG_RSP: + case FWSC_VIRT_CABLE_PLUG_RSP | FWSC_RSP_NACK: + case FWSC_VIRT_CABLE_UNPLUG_RSP | FWSC_RSP_NACK: + return sizeof(pkt.hdr); + + default: + return -1; + } +} + +static inline void fill_plug_params(struct virt_plug_params *params, + struct fwtty_port *port) +{ + u64 status_addr = port->rx_handler.offset; + u64 fifo_addr = port->rx_handler.offset + 4; + size_t fifo_len = port->rx_handler.length - 4; + + params->status_hi = cpu_to_be32(status_addr >> 32); + params->status_lo = cpu_to_be32(status_addr); + params->fifo_hi = cpu_to_be32(fifo_addr >> 32); + params->fifo_lo = cpu_to_be32(fifo_addr); + params->fifo_len = cpu_to_be32(fifo_len); +} + +static inline void fill_plug_req(struct fwserial_mgmt_pkt *pkt, + struct fwtty_port *port) +{ + pkt->hdr.code = cpu_to_be16(FWSC_VIRT_CABLE_PLUG); + pkt->hdr.len = cpu_to_be16(mgmt_pkt_expected_len(pkt->hdr.code)); + fill_plug_params(&pkt->plug_req, port); +} + +static inline void fill_plug_rsp_ok(struct fwserial_mgmt_pkt *pkt, + struct fwtty_port *port) +{ + pkt->hdr.code = cpu_to_be16(FWSC_VIRT_CABLE_PLUG_RSP); + pkt->hdr.len = cpu_to_be16(mgmt_pkt_expected_len(pkt->hdr.code)); + fill_plug_params(&pkt->plug_rsp, port); +} + +static inline void fill_plug_rsp_nack(struct fwserial_mgmt_pkt *pkt) +{ + pkt->hdr.code = cpu_to_be16(FWSC_VIRT_CABLE_PLUG_RSP | FWSC_RSP_NACK); + pkt->hdr.len = cpu_to_be16(mgmt_pkt_expected_len(pkt->hdr.code)); +} + +static inline void fill_unplug_req(struct fwserial_mgmt_pkt *pkt) +{ + pkt->hdr.code = cpu_to_be16(FWSC_VIRT_CABLE_UNPLUG); + pkt->hdr.len = cpu_to_be16(mgmt_pkt_expected_len(pkt->hdr.code)); +} + +static inline void fill_unplug_rsp_nack(struct fwserial_mgmt_pkt *pkt) +{ + pkt->hdr.code = cpu_to_be16(FWSC_VIRT_CABLE_UNPLUG_RSP | FWSC_RSP_NACK); + pkt->hdr.len = cpu_to_be16(mgmt_pkt_expected_len(pkt->hdr.code)); +} + +static inline void fill_unplug_rsp_ok(struct fwserial_mgmt_pkt *pkt) +{ + pkt->hdr.code = cpu_to_be16(FWSC_VIRT_CABLE_UNPLUG_RSP); + pkt->hdr.len = cpu_to_be16(mgmt_pkt_expected_len(pkt->hdr.code)); +} + +static void fwserial_virt_plug_complete(struct fwtty_peer *peer, + struct virt_plug_params *params) +{ + struct fwtty_port *port = peer->port; + + peer->status_addr = be32_to_u64(params->status_hi, params->status_lo); + peer->fifo_addr = be32_to_u64(params->fifo_hi, params->fifo_lo); + peer->fifo_len = be32_to_cpu(params->fifo_len); + peer_set_state(peer, FWPS_ATTACHED); + + /* reconfigure tx_fifo optimally for this peer */ + spin_lock_bh(&port->lock); + port->max_payload = min3(peer->max_payload, peer->fifo_len, + MAX_ASYNC_PAYLOAD); + dma_fifo_change_tx_limit(&port->tx_fifo, port->max_payload); + spin_unlock_bh(&peer->port->lock); + + if (port->port.console && port->fwcon_ops->notify != NULL) + (*port->fwcon_ops->notify)(FWCON_NOTIFY_ATTACH, port->con_data); + + fwtty_info(&peer->unit, "peer (guid:%016llx) connected on %s", + (unsigned long long)peer->guid, dev_name(port->device)); +} + +static inline int fwserial_send_mgmt_sync(struct fwtty_peer *peer, + struct fwserial_mgmt_pkt *pkt) +{ + int generation; + int rcode, tries = 5; + + do { + generation = peer->generation; + smp_rmb(); + + rcode = fw_run_transaction(peer->serial->card, + TCODE_WRITE_BLOCK_REQUEST, + peer->node_id, + generation, peer->speed, + peer->mgmt_addr, + pkt, be16_to_cpu(pkt->hdr.len)); + if (rcode == RCODE_BUSY || rcode == RCODE_SEND_ERROR || + rcode == RCODE_GENERATION) { + fwtty_dbg(&peer->unit, "mgmt write error: %d", rcode); + continue; + } else + break; + } while (--tries > 0); + return rcode; +} + +/** + * fwserial_claim_port - attempt to claim port @ index for peer + * + * Returns ptr to claimed port or error code (as ERR_PTR()) + * Can sleep - must be called from process context + */ +static struct fwtty_port *fwserial_claim_port(struct fwtty_peer *peer, + int index) +{ + struct fwtty_port *port; + + if (index < 0 || index >= num_ports) + return ERR_PTR(-EINVAL); + + /* must guarantee that previous port releases have completed */ + synchronize_rcu(); + + port = peer->serial->ports[index]; + spin_lock_bh(&port->lock); + if (!rcu_access_pointer(port->peer)) + rcu_assign_pointer(port->peer, peer); + else + port = ERR_PTR(-EBUSY); + spin_unlock_bh(&port->lock); + + return port; +} + +/** + * fwserial_find_port - find avail port and claim for peer + * + * Returns ptr to claimed port or NULL if none avail + * Can sleep - must be called from process context + */ +static struct fwtty_port *fwserial_find_port(struct fwtty_peer *peer) +{ + struct fwtty_port **ports = peer->serial->ports; + int i; + + /* must guarantee that previous port releases have completed */ + synchronize_rcu(); + + /* TODO: implement optional GUID-to-specific port # matching */ + + /* find an unattached port (but not the loopback port, if present) */ + for (i = 0; i < num_ttys; ++i) { + spin_lock_bh(&ports[i]->lock); + if (!ports[i]->peer) { + /* claim port */ + rcu_assign_pointer(ports[i]->peer, peer); + spin_unlock_bh(&ports[i]->lock); + return ports[i]; + } + spin_unlock_bh(&ports[i]->lock); + } + return NULL; +} + +static void fwserial_release_port(struct fwtty_port *port) +{ + /* drop carrier (and all other line status) */ + fwtty_update_port_status(port, 0); + + spin_lock_bh(&port->lock); + + /* reset dma fifo max transmission size back to S100 */ + port->max_payload = link_speed_to_max_payload(SCODE_100); + dma_fifo_change_tx_limit(&port->tx_fifo, port->max_payload); + + rcu_assign_pointer(port->peer, NULL); + spin_unlock_bh(&port->lock); + + if (port->port.console && port->fwcon_ops->notify != NULL) + (*port->fwcon_ops->notify)(FWCON_NOTIFY_DETACH, port->con_data); +} + +static void fwserial_plug_timeout(unsigned long data) +{ + struct fwtty_peer *peer = (struct fwtty_peer *) data; + struct fwtty_port *port; + + spin_lock_bh(&peer->lock); + if (peer->state != FWPS_PLUG_PENDING) { + spin_unlock_bh(&peer->lock); + return; + } + + port = peer_revert_state(peer); + spin_unlock_bh(&peer->lock); + + if (port) + fwserial_release_port(port); +} + +/** + * fwserial_connect_peer - initiate virtual cable with peer + * + * Returns 0 if VIRT_CABLE_PLUG request was successfully sent, + * otherwise error code. Must be called from process context. + */ +static int fwserial_connect_peer(struct fwtty_peer *peer) +{ + struct fwtty_port *port; + struct fwserial_mgmt_pkt *pkt; + int err, rcode; + + pkt = kmalloc(sizeof(*pkt), GFP_KERNEL); + if (!pkt) + return -ENOMEM; + + port = fwserial_find_port(peer); + if (!port) { + fwtty_err(&peer->unit, "avail ports in use"); + err = -EBUSY; + goto free_pkt; + } + + spin_lock_bh(&peer->lock); + + /* only initiate VIRT_CABLE_PLUG if peer is currently not attached */ + if (peer->state != FWPS_NOT_ATTACHED) { + err = -EBUSY; + goto release_port; + } + + peer->port = port; + peer_set_state(peer, FWPS_PLUG_PENDING); + + fill_plug_req(pkt, peer->port); + + setup_timer(&peer->timer, fwserial_plug_timeout, (unsigned long)peer); + mod_timer(&peer->timer, jiffies + VIRT_CABLE_PLUG_TIMEOUT); + spin_unlock_bh(&peer->lock); + + rcode = fwserial_send_mgmt_sync(peer, pkt); + + spin_lock_bh(&peer->lock); + if (peer->state == FWPS_PLUG_PENDING && rcode != RCODE_COMPLETE) { + if (rcode == RCODE_CONFLICT_ERROR) + err = -EAGAIN; + else + err = -EIO; + goto cancel_timer; + } + spin_unlock_bh(&peer->lock); + + kfree(pkt); + return 0; + +cancel_timer: + del_timer(&peer->timer); + peer_revert_state(peer); +release_port: + spin_unlock_bh(&peer->lock); + fwserial_release_port(port); +free_pkt: + kfree(pkt); + return err; +} + +/** + * fwserial_close_port - + * HUP the tty (if the tty exists) and unregister the tty device. + * Only used by the unit driver upon unit removal to disconnect and + * cleanup all attached ports + * + * The port reference is put by fwtty_cleanup (if a reference was + * ever taken). + */ +static void fwserial_close_port(struct fwtty_port *port) +{ + struct tty_struct *tty; + + mutex_lock(&port->port.mutex); + tty = tty_port_tty_get(&port->port); + if (tty) { + tty_vhangup(tty); + tty_kref_put(tty); + } + mutex_unlock(&port->port.mutex); + + tty_unregister_device(fwtty_driver, port->index); +} + +/** + * fwserial_lookup - finds first fw_serial associated with card + * @card: fw_card to match + * + * NB: caller must be holding fwserial_list_mutex + */ +static struct fw_serial *fwserial_lookup(struct fw_card *card) +{ + struct fw_serial *serial; + + list_for_each_entry(serial, &fwserial_list, list) { + if (card == serial->card) + return serial; + } + + return NULL; +} + +/** + * __fwserial_lookup_rcu - finds first fw_serial associated with card + * @card: fw_card to match + * + * NB: caller must be inside rcu_read_lock() section + */ +static struct fw_serial *__fwserial_lookup_rcu(struct fw_card *card) +{ + struct fw_serial *serial; + + list_for_each_entry_rcu(serial, &fwserial_list, list) { + if (card == serial->card) + return serial; + } + + return NULL; +} + +/** + * __fwserial_peer_by_node_id - finds a peer matching the given generation + id + * + * If a matching peer could not be found for the specified generation/node id, + * this could be because: + * a) the generation has changed and one of the nodes hasn't updated yet + * b) the remote node has created its remote unit device before this + * local node has created its corresponding remote unit device + * In either case, the remote node should retry + * + * Note: caller must be in rcu_read_lock() section + */ +static struct fwtty_peer *__fwserial_peer_by_node_id(struct fw_card *card, + int generation, int id) +{ + struct fw_serial *serial; + struct fwtty_peer *peer; + + serial = __fwserial_lookup_rcu(card); + if (!serial) { + /* + * Something is very wrong - there should be a matching + * fw_serial structure for every fw_card. Maybe the remote node + * has created its remote unit device before this driver has + * been probed for any unit devices... + */ + fwtty_err(card, "unknown card (guid %016llx)", + (unsigned long long) card->guid); + return NULL; + } + + list_for_each_entry_rcu(peer, &serial->peer_list, list) { + int g = peer->generation; + smp_rmb(); + if (generation == g && id == peer->node_id) + return peer; + } + + return NULL; +} + +#ifdef DEBUG +static void __dump_peer_list(struct fw_card *card) +{ + struct fw_serial *serial; + struct fwtty_peer *peer; + + serial = __fwserial_lookup_rcu(card); + if (!serial) + return; + + list_for_each_entry_rcu(peer, &serial->peer_list, list) { + int g = peer->generation; + smp_rmb(); + fwtty_dbg(card, "peer(%d:%x) guid: %016llx\n", g, + peer->node_id, (unsigned long long) peer->guid); + } +} +#else +#define __dump_peer_list(s) +#endif + +static void fwserial_auto_connect(struct work_struct *work) +{ + struct fwtty_peer *peer = to_peer(to_delayed_work(work), connect); + int err; + + err = fwserial_connect_peer(peer); + if (err == -EAGAIN && ++peer->connect_retries < MAX_CONNECT_RETRIES) + schedule_delayed_work(&peer->connect, CONNECT_RETRY_DELAY); +} + +/** + * fwserial_add_peer - add a newly probed 'serial' unit device as a 'peer' + * @serial: aggregate representing the specific fw_card to add the peer to + * @unit: 'peer' to create and add to peer_list of serial + * + * Adds a 'peer' (ie, a local or remote 'serial' unit device) to the list of + * peers for a specific fw_card. Optionally, auto-attach this peer to an + * available tty port. This function is called either directly or indirectly + * as a result of a 'serial' unit device being created & probed. + * + * Note: this function is serialized with fwserial_remove_peer() by the + * fwserial_list_mutex held in fwserial_probe(). + * + * A 1:1 correspondence between an fw_unit and an fwtty_peer is maintained + * via the dev_set_drvdata() for the device of the fw_unit. + */ +static int fwserial_add_peer(struct fw_serial *serial, struct fw_unit *unit) +{ + struct device *dev = &unit->device; + struct fw_device *parent = fw_parent_device(unit); + struct fwtty_peer *peer; + struct fw_csr_iterator ci; + int key, val; + int generation; + + peer = kzalloc(sizeof(*peer), GFP_KERNEL); + if (!peer) + return -ENOMEM; + + peer_set_state(peer, FWPS_NOT_ATTACHED); + + dev_set_drvdata(dev, peer); + peer->unit = unit; + peer->guid = (u64)parent->config_rom[3] << 32 | parent->config_rom[4]; + peer->speed = parent->max_speed; + peer->max_payload = min(device_max_receive(parent), + link_speed_to_max_payload(peer->speed)); + + generation = parent->generation; + smp_rmb(); + peer->node_id = parent->node_id; + smp_wmb(); + peer->generation = generation; + + /* retrieve the mgmt bus addr from the unit directory */ + fw_csr_iterator_init(&ci, unit->directory); + while (fw_csr_iterator_next(&ci, &key, &val)) { + if (key == (CSR_OFFSET | CSR_DEPENDENT_INFO)) { + peer->mgmt_addr = CSR_REGISTER_BASE + 4 * val; + break; + } + } + if (peer->mgmt_addr == 0ULL) { + /* + * No mgmt address effectively disables VIRT_CABLE_PLUG - + * this peer will not be able to attach to a remote + */ + peer_set_state(peer, FWPS_NO_MGMT_ADDR); + } + + spin_lock_init(&peer->lock); + peer->port = NULL; + + init_timer(&peer->timer); + INIT_WORK(&peer->work, NULL); + INIT_DELAYED_WORK(&peer->connect, fwserial_auto_connect); + + /* associate peer with specific fw_card */ + peer->serial = serial; + list_add_rcu(&peer->list, &serial->peer_list); + + fwtty_info(&peer->unit, "peer added (guid:%016llx)", + (unsigned long long)peer->guid); + + /* identify the local unit & virt cable to loopback port */ + if (parent->is_local) { + serial->self = peer; + if (create_loop_dev) { + struct fwtty_port *port; + port = fwserial_claim_port(peer, num_ttys); + if (!IS_ERR(port)) { + struct virt_plug_params params; + + spin_lock_bh(&peer->lock); + peer->port = port; + fill_plug_params(¶ms, port); + fwserial_virt_plug_complete(peer, ¶ms); + spin_unlock_bh(&peer->lock); + + fwtty_write_port_status(port); + } + } + + } else if (auto_connect) { + /* auto-attach to remote units only (if policy allows) */ + schedule_delayed_work(&peer->connect, 1); + } + + return 0; +} + +/** + * fwserial_remove_peer - remove a 'serial' unit device as a 'peer' + * + * Remove a 'peer' from its list of peers. This function is only + * called by fwserial_remove() on bus removal of the unit device. + * + * Note: this function is serialized with fwserial_add_peer() by the + * fwserial_list_mutex held in fwserial_remove(). + */ +static void fwserial_remove_peer(struct fwtty_peer *peer) +{ + struct fwtty_port *port; + + spin_lock_bh(&peer->lock); + peer_set_state(peer, FWPS_GONE); + spin_unlock_bh(&peer->lock); + + cancel_delayed_work_sync(&peer->connect); + cancel_work_sync(&peer->work); + + spin_lock_bh(&peer->lock); + /* if this unit is the local unit, clear link */ + if (peer == peer->serial->self) + peer->serial->self = NULL; + + /* cancel the request timeout timer (if running) */ + del_timer(&peer->timer); + + port = peer->port; + peer->port = NULL; + + list_del_rcu(&peer->list); + + fwtty_info(&peer->unit, "peer removed (guid:%016llx)", + (unsigned long long)peer->guid); + + spin_unlock_bh(&peer->lock); + + if (port) + fwserial_release_port(port); + + synchronize_rcu(); + kfree(peer); +} + +/** + * create_loop_device - create a loopback tty device + * @tty_driver: tty_driver to own loopback device + * @prototype: ptr to already-assigned 'prototype' tty port + * @index: index to associate this device with the tty port + * @parent: device to child to + * + * HACK - this is basically tty_port_register_device() with an + * alternate naming scheme. Suggest tty_port_register_named_device() + * helper api. + * + * Creates a loopback tty device named 'fwloop' which is attached to + * the local unit in fwserial_add_peer(). Note that in the device + * name advances in increments of port allocation blocks, ie., for port + * indices 0..3, the device name will be 'fwloop0'; for 4..7, 'fwloop1', + * and so on. + * + * Only one loopback device should be created per fw_card. + */ +static void release_loop_device(struct device *dev) +{ + kfree(dev); +} + +static struct device *create_loop_device(struct tty_driver *driver, + struct fwtty_port *prototype, + struct fwtty_port *port, + struct device *parent) +{ + char name[64]; + int index = port->index; + dev_t devt = MKDEV(driver->major, driver->minor_start) + index; + struct device *dev = NULL; + int err; + + if (index >= fwtty_driver->num) + return ERR_PTR(-EINVAL); + + snprintf(name, 64, "%s%d", loop_dev_name, index / num_ports); + + tty_port_link_device(&port->port, driver, index); + + cdev_init(&driver->cdevs[index], driver->cdevs[prototype->index].ops); + driver->cdevs[index].owner = driver->owner; + err = cdev_add(&driver->cdevs[index], devt, 1); + if (err) + return ERR_PTR(err); + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + cdev_del(&driver->cdevs[index]); + return ERR_PTR(-ENOMEM); + } + + dev->devt = devt; + dev->class = prototype->device->class; + dev->parent = parent; + dev->release = release_loop_device; + dev_set_name(dev, "%s", name); + dev->groups = NULL; + dev_set_drvdata(dev, NULL); + + err = device_register(dev); + if (err) { + put_device(dev); + cdev_del(&driver->cdevs[index]); + return ERR_PTR(err); + } + + return dev; +} + +/** + * fwserial_create - init everything to create TTYs for a specific fw_card + * @unit: fw_unit for first 'serial' unit device probed for this fw_card + * + * This function inits the aggregate structure (an fw_serial instance) + * used to manage the TTY ports registered by a specific fw_card. Also, the + * unit device is added as the first 'peer'. + * + * This unit device may represent a local unit device (as specified by the + * config ROM unit directory) or it may represent a remote unit device + * (as specified by the reading of the remote node's config ROM). + * + * Returns 0 to indicate "ownership" of the unit device, or a negative errno + * value to indicate which error. + */ +static int fwserial_create(struct fw_unit *unit) +{ + struct fw_device *parent = fw_parent_device(unit); + struct fw_card *card = parent->card; + struct fw_serial *serial; + struct fwtty_port *port; + struct device *tty_dev; + int i, j; + int err; + + serial = kzalloc(sizeof(*serial), GFP_KERNEL); + if (!serial) + return -ENOMEM; + + kref_init(&serial->kref); + serial->card = card; + INIT_LIST_HEAD(&serial->peer_list); + + for (i = 0; i < num_ports; ++i) { + port = kzalloc(sizeof(*port), GFP_KERNEL); + if (!port) { + err = -ENOMEM; + goto free_ports; + } + tty_port_init(&port->port); + port->index = FWTTY_INVALID_INDEX; + port->port.ops = &fwtty_port_ops; + port->serial = serial; + + spin_lock_init(&port->lock); + INIT_DELAYED_WORK(&port->drain, fwtty_drain_tx); + INIT_DELAYED_WORK(&port->emit_breaks, fwtty_emit_breaks); + INIT_WORK(&port->hangup, fwtty_do_hangup); + INIT_WORK(&port->push, fwtty_pushrx); + INIT_LIST_HEAD(&port->buf_list); + init_waitqueue_head(&port->wait_tx); + port->max_payload = link_speed_to_max_payload(SCODE_100); + dma_fifo_init(&port->tx_fifo); + + rcu_assign_pointer(port->peer, NULL); + serial->ports[i] = port; + + /* get unique bus addr region for port's status & recv fifo */ + port->rx_handler.length = FWTTY_PORT_RXFIFO_LEN + 4; + port->rx_handler.address_callback = fwtty_port_handler; + port->rx_handler.callback_data = port; + /* + * XXX: use custom memory region above cpu physical memory addrs + * this will ease porting to 64-bit firewire adapters + */ + err = fw_core_add_address_handler(&port->rx_handler, + &fw_high_memory_region); + if (err) { + kfree(port); + goto free_ports; + } + } + /* preserve i for error cleanup */ + + err = fwtty_ports_add(serial); + if (err) { + fwtty_err(&unit, "no space in port table"); + goto free_ports; + } + + for (j = 0; j < num_ttys; ++j) { + tty_dev = tty_port_register_device(&serial->ports[j]->port, + fwtty_driver, + serial->ports[j]->index, + card->device); + if (IS_ERR(tty_dev)) { + err = PTR_ERR(tty_dev); + fwtty_err(&unit, "register tty device error (%d)", err); + goto unregister_ttys; + } + + serial->ports[j]->device = tty_dev; + } + /* preserve j for error cleanup */ + + if (create_loop_dev) { + struct device *loop_dev; + + loop_dev = create_loop_device(fwtty_driver, + serial->ports[0], + serial->ports[num_ttys], + card->device); + if (IS_ERR(loop_dev)) { + err = PTR_ERR(loop_dev); + fwtty_err(&unit, "create loop device failed (%d)", err); + goto unregister_ttys; + } + serial->ports[num_ttys]->device = loop_dev; + serial->ports[num_ttys]->loopback = true; + } + + list_add_rcu(&serial->list, &fwserial_list); + + fwtty_notice(&unit, "TTY over FireWire on device %s (guid %016llx)", + dev_name(card->device), (unsigned long long) card->guid); + + err = fwserial_add_peer(serial, unit); + if (!err) + return 0; + + fwtty_err(&unit, "unable to add peer unit device (%d)", err); + + /* fall-through to error processing */ + list_del_rcu(&serial->list); +unregister_ttys: + for (--j; j >= 0; --j) + tty_unregister_device(fwtty_driver, serial->ports[j]->index); + kref_put(&serial->kref, fwserial_destroy); + return err; + +free_ports: + for (--i; i >= 0; --i) + kfree(serial->ports[i]); + kfree(serial); + return err; +} + +/** + * fwserial_probe: bus probe function for firewire 'serial' unit devices + * + * A 'serial' unit device is created and probed as a result of: + * - declaring a ieee1394 bus id table for 'devices' matching a fabricated + * 'serial' unit specifier id + * - adding a unit directory to the config ROM(s) for a 'serial' unit + * + * The firewire core registers unit devices by enumerating unit directories + * of a node's config ROM after reading the config ROM when a new node is + * added to the bus topology after a bus reset. + * + * The practical implications of this are: + * - this probe is called for both local and remote nodes that have a 'serial' + * unit directory in their config ROM (that matches the specifiers in + * fwserial_id_table). + * - no specific order is enforced for local vs. remote unit devices + * + * This unit driver copes with the lack of specific order in the same way the + * firewire net driver does -- each probe, for either a local or remote unit + * device, is treated as a 'peer' (has a struct fwtty_peer instance) and the + * first peer created for a given fw_card (tracked by the global fwserial_list) + * creates the underlying TTYs (aggregated in a fw_serial instance). + * + * NB: an early attempt to differentiate local & remote unit devices by creating + * peers only for remote units and fw_serial instances (with their + * associated TTY devices) only for local units was discarded. Managing + * the peer lifetimes on device removal proved too complicated. + * + * fwserial_probe/fwserial_remove are effectively serialized by the + * fwserial_list_mutex. This is necessary because the addition of the first peer + * for a given fw_card will trigger the creation of the fw_serial for that + * fw_card, which must not simultaneously contend with the removal of the + * last peer for a given fw_card triggering the destruction of the same + * fw_serial for the same fw_card. + */ +static int fwserial_probe(struct device *dev) +{ + struct fw_unit *unit = fw_unit(dev); + struct fw_serial *serial; + int err; + + mutex_lock(&fwserial_list_mutex); + serial = fwserial_lookup(fw_parent_device(unit)->card); + if (!serial) + err = fwserial_create(unit); + else + err = fwserial_add_peer(serial, unit); + mutex_unlock(&fwserial_list_mutex); + return err; +} + +/** + * fwserial_remove: bus removal function for firewire 'serial' unit devices + * + * The corresponding 'peer' for this unit device is removed from the list of + * peers for the associated fw_serial (which has a 1:1 correspondence with a + * specific fw_card). If this is the last peer being removed, then trigger + * the destruction of the underlying TTYs. + */ +static int fwserial_remove(struct device *dev) +{ + struct fwtty_peer *peer = dev_get_drvdata(dev); + struct fw_serial *serial = peer->serial; + int i; + + mutex_lock(&fwserial_list_mutex); + fwserial_remove_peer(peer); + + if (list_empty(&serial->peer_list)) { + /* unlink from the fwserial_list here */ + list_del_rcu(&serial->list); + + for (i = 0; i < num_ports; ++i) + fwserial_close_port(serial->ports[i]); + kref_put(&serial->kref, fwserial_destroy); + } + mutex_unlock(&fwserial_list_mutex); + + return 0; +} + +/** + * fwserial_update: bus update function for 'firewire' serial unit devices + * + * Updates the new node_id and bus generation for this peer. Note that locking + * is unnecessary; but careful memory barrier usage is important to enforce the + * load and store order of generation & node_id. + * + * The fw-core orders the write of node_id before generation in the parent + * fw_device to ensure that a stale node_id cannot be used with a current + * bus generation. So the generation value must be read before the node_id. + * + * In turn, this orders the write of node_id before generation in the peer to + * also ensure a stale node_id cannot be used with a current bus generation. + */ +static void fwserial_update(struct fw_unit *unit) +{ + struct fw_device *parent = fw_parent_device(unit); + struct fwtty_peer *peer = dev_get_drvdata(&unit->device); + int generation; + + generation = parent->generation; + smp_rmb(); + peer->node_id = parent->node_id; + smp_wmb(); + peer->generation = generation; +} + +static const struct ieee1394_device_id fwserial_id_table[] = { + { + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | + IEEE1394_MATCH_VERSION, + .specifier_id = LINUX_VENDOR_ID, + .version = FWSERIAL_VERSION, + }, + { } +}; + +static struct fw_driver fwserial_driver = { + .driver = { + .owner = THIS_MODULE, + .name = KBUILD_MODNAME, + .bus = &fw_bus_type, + .probe = fwserial_probe, + .remove = fwserial_remove, + }, + .update = fwserial_update, + .id_table = fwserial_id_table, +}; + +#define FW_UNIT_SPECIFIER(id) ((CSR_SPECIFIER_ID << 24) | (id)) +#define FW_UNIT_VERSION(ver) ((CSR_VERSION << 24) | (ver)) +#define FW_UNIT_ADDRESS(ofs) (((CSR_OFFSET | CSR_DEPENDENT_INFO) << 24) \ + | (((ofs) - CSR_REGISTER_BASE) >> 2)) +/* XXX: config ROM definitons could be improved with semi-automated offset + * and length calculation + */ +#define FW_ROM_DESCRIPTOR(ofs) (((CSR_LEAF | CSR_DESCRIPTOR) << 24) | (ofs)) + +struct fwserial_unit_directory_data { + u16 crc; + u16 len; + u32 unit_specifier; + u32 unit_sw_version; + u32 unit_addr_offset; + u32 desc1_ofs; + u16 desc1_crc; + u16 desc1_len; + u32 desc1_data[5]; +} __packed; + +static struct fwserial_unit_directory_data fwserial_unit_directory_data = { + .len = 4, + .unit_specifier = FW_UNIT_SPECIFIER(LINUX_VENDOR_ID), + .unit_sw_version = FW_UNIT_VERSION(FWSERIAL_VERSION), + .desc1_ofs = FW_ROM_DESCRIPTOR(1), + .desc1_len = 5, + .desc1_data = { + 0x00000000, /* type = text */ + 0x00000000, /* enc = ASCII, lang EN */ + 0x4c696e75, /* 'Linux TTY' */ + 0x78205454, + 0x59000000, + }, +}; + +static struct fw_descriptor fwserial_unit_directory = { + .length = sizeof(fwserial_unit_directory_data) / sizeof(u32), + .key = (CSR_DIRECTORY | CSR_UNIT) << 24, + .data = (u32 *)&fwserial_unit_directory_data, +}; + +/* + * The management address is in the unit space region but above other known + * address users (to keep wild writes from causing havoc) + */ +const struct fw_address_region fwserial_mgmt_addr_region = { + .start = CSR_REGISTER_BASE + 0x1e0000ULL, + .end = 0x1000000000000ULL, +}; + +static struct fw_address_handler fwserial_mgmt_addr_handler; + +/** + * fwserial_handle_plug_req - handle VIRT_CABLE_PLUG request work + * @work: ptr to peer->work + * + * Attempts to complete the VIRT_CABLE_PLUG handshake sequence for this peer. + * + * This checks for a collided request-- ie, that a VIRT_CABLE_PLUG request was + * already sent to this peer. If so, the collision is resolved by comparing + * guid values; the loser sends the plug response. + * + * Note: if an error prevents a response, don't do anything -- the + * remote will timeout its request. + */ +static void fwserial_handle_plug_req(struct work_struct *work) +{ + struct fwtty_peer *peer = to_peer(work, work); + struct virt_plug_params *plug_req = &peer->work_params.plug_req; + struct fwtty_port *port; + struct fwserial_mgmt_pkt *pkt; + int rcode; + + pkt = kmalloc(sizeof(*pkt), GFP_KERNEL); + if (!pkt) + return; + + port = fwserial_find_port(peer); + + spin_lock_bh(&peer->lock); + + switch (peer->state) { + case FWPS_NOT_ATTACHED: + if (!port) { + fwtty_err(&peer->unit, "no more ports avail"); + fill_plug_rsp_nack(pkt); + } else { + peer->port = port; + fill_plug_rsp_ok(pkt, peer->port); + peer_set_state(peer, FWPS_PLUG_RESPONDING); + /* don't release claimed port */ + port = NULL; + } + break; + + case FWPS_PLUG_PENDING: + if (peer->serial->card->guid > peer->guid) + goto cleanup; + + /* We lost - hijack the already-claimed port and send ok */ + del_timer(&peer->timer); + fill_plug_rsp_ok(pkt, peer->port); + peer_set_state(peer, FWPS_PLUG_RESPONDING); + break; + + default: + fill_plug_rsp_nack(pkt); + } + + spin_unlock_bh(&peer->lock); + if (port) + fwserial_release_port(port); + + rcode = fwserial_send_mgmt_sync(peer, pkt); + + spin_lock_bh(&peer->lock); + if (peer->state == FWPS_PLUG_RESPONDING) { + if (rcode == RCODE_COMPLETE) { + struct fwtty_port *tmp = peer->port; + + fwserial_virt_plug_complete(peer, plug_req); + spin_unlock_bh(&peer->lock); + + fwtty_write_port_status(tmp); + spin_lock_bh(&peer->lock); + } else { + fwtty_err(&peer->unit, "PLUG_RSP error (%d)", rcode); + port = peer_revert_state(peer); + } + } +cleanup: + spin_unlock_bh(&peer->lock); + if (port) + fwserial_release_port(port); + kfree(pkt); + return; +} + +static void fwserial_handle_unplug_req(struct work_struct *work) +{ + struct fwtty_peer *peer = to_peer(work, work); + struct fwtty_port *port = NULL; + struct fwserial_mgmt_pkt *pkt; + int rcode; + + pkt = kmalloc(sizeof(*pkt), GFP_KERNEL); + if (!pkt) + return; + + spin_lock_bh(&peer->lock); + + switch (peer->state) { + case FWPS_ATTACHED: + fill_unplug_rsp_ok(pkt); + peer_set_state(peer, FWPS_UNPLUG_RESPONDING); + break; + + case FWPS_UNPLUG_PENDING: + if (peer->serial->card->guid > peer->guid) + goto cleanup; + + /* We lost - send unplug rsp */ + del_timer(&peer->timer); + fill_unplug_rsp_ok(pkt); + peer_set_state(peer, FWPS_UNPLUG_RESPONDING); + break; + + default: + fill_unplug_rsp_nack(pkt); + } + + spin_unlock_bh(&peer->lock); + + rcode = fwserial_send_mgmt_sync(peer, pkt); + + spin_lock_bh(&peer->lock); + if (peer->state == FWPS_UNPLUG_RESPONDING) { + if (rcode == RCODE_COMPLETE) + port = peer_revert_state(peer); + else + fwtty_err(&peer->unit, "UNPLUG_RSP error (%d)", rcode); + } +cleanup: + spin_unlock_bh(&peer->lock); + if (port) + fwserial_release_port(port); + kfree(pkt); + return; +} + +static int fwserial_parse_mgmt_write(struct fwtty_peer *peer, + struct fwserial_mgmt_pkt *pkt, + unsigned long long addr, + size_t len) +{ + struct fwtty_port *port = NULL; + int rcode; + + if (addr != fwserial_mgmt_addr_handler.offset || len < sizeof(pkt->hdr)) + return RCODE_ADDRESS_ERROR; + + if (len != be16_to_cpu(pkt->hdr.len) || + len != mgmt_pkt_expected_len(pkt->hdr.code)) + return RCODE_DATA_ERROR; + + spin_lock_bh(&peer->lock); + if (peer->state == FWPS_GONE) { + /* + * This should never happen - it would mean that the + * remote unit that just wrote this transaction was + * already removed from the bus -- and the removal was + * processed before we rec'd this transaction + */ + fwtty_err(&peer->unit, "peer already removed"); + spin_unlock_bh(&peer->lock); + return RCODE_ADDRESS_ERROR; + } + + rcode = RCODE_COMPLETE; + + fwtty_dbg(&peer->unit, "mgmt: hdr.code: %04hx", pkt->hdr.code); + + switch (be16_to_cpu(pkt->hdr.code) & FWSC_CODE_MASK) { + case FWSC_VIRT_CABLE_PLUG: + if (work_pending(&peer->work)) { + fwtty_err(&peer->unit, "plug req: busy"); + rcode = RCODE_CONFLICT_ERROR; + + } else { + peer->work_params.plug_req = pkt->plug_req; + PREPARE_WORK(&peer->work, fwserial_handle_plug_req); + queue_work(system_unbound_wq, &peer->work); + } + break; + + case FWSC_VIRT_CABLE_PLUG_RSP: + if (peer->state != FWPS_PLUG_PENDING) { + rcode = RCODE_CONFLICT_ERROR; + + } else if (be16_to_cpu(pkt->hdr.code) & FWSC_RSP_NACK) { + fwtty_notice(&peer->unit, "NACK plug rsp"); + port = peer_revert_state(peer); + + } else { + struct fwtty_port *tmp = peer->port; + + fwserial_virt_plug_complete(peer, &pkt->plug_rsp); + spin_unlock_bh(&peer->lock); + + fwtty_write_port_status(tmp); + spin_lock_bh(&peer->lock); + } + break; + + case FWSC_VIRT_CABLE_UNPLUG: + if (work_pending(&peer->work)) { + fwtty_err(&peer->unit, "unplug req: busy"); + rcode = RCODE_CONFLICT_ERROR; + } else { + PREPARE_WORK(&peer->work, fwserial_handle_unplug_req); + queue_work(system_unbound_wq, &peer->work); + } + break; + + case FWSC_VIRT_CABLE_UNPLUG_RSP: + if (peer->state != FWPS_UNPLUG_PENDING) + rcode = RCODE_CONFLICT_ERROR; + else { + if (be16_to_cpu(pkt->hdr.code) & FWSC_RSP_NACK) + fwtty_notice(&peer->unit, "NACK unplug?"); + port = peer_revert_state(peer); + } + break; + + default: + fwtty_err(&peer->unit, "unknown mgmt code %d", + be16_to_cpu(pkt->hdr.code)); + rcode = RCODE_DATA_ERROR; + } + spin_unlock_bh(&peer->lock); + + if (port) + fwserial_release_port(port); + + return rcode; +} + +/** + * fwserial_mgmt_handler: bus address handler for mgmt requests + * @parameters: fw_address_callback_t as specified by firewire core interface + * + * This handler is responsible for handling virtual cable requests from remotes + * for all cards. + */ +static void fwserial_mgmt_handler(struct fw_card *card, + struct fw_request *request, + int tcode, int destination, int source, + int generation, + unsigned long long addr, + void *data, size_t len, + void *callback_data) +{ + struct fwserial_mgmt_pkt *pkt = data; + struct fwtty_peer *peer; + int rcode; + + rcu_read_lock(); + peer = __fwserial_peer_by_node_id(card, generation, source); + if (!peer) { + fwtty_dbg(card, "peer(%d:%x) not found", generation, source); + __dump_peer_list(card); + rcode = RCODE_CONFLICT_ERROR; + + } else { + switch (tcode) { + case TCODE_WRITE_BLOCK_REQUEST: + rcode = fwserial_parse_mgmt_write(peer, pkt, addr, len); + break; + + default: + rcode = RCODE_TYPE_ERROR; + } + } + + rcu_read_unlock(); + fw_send_response(card, request, rcode); +} + +static int __init fwserial_init(void) +{ + int err, num_loops = !!(create_loop_dev); + + /* num_ttys/num_ports must not be set above the static alloc avail */ + if (num_ttys + num_loops > MAX_CARD_PORTS) + num_ttys = MAX_CARD_PORTS - num_loops; + num_ports = num_ttys + num_loops; + + fwtty_driver = alloc_tty_driver(MAX_TOTAL_PORTS); + if (!fwtty_driver) { + err = -ENOMEM; + return err; + } + + fwtty_driver->driver_name = KBUILD_MODNAME; + fwtty_driver->name = tty_dev_name; + fwtty_driver->major = 0; + fwtty_driver->minor_start = 0; + fwtty_driver->type = TTY_DRIVER_TYPE_SERIAL; + fwtty_driver->subtype = SERIAL_TYPE_NORMAL; + fwtty_driver->flags = TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV; + + fwtty_driver->init_termios = tty_std_termios; + fwtty_driver->init_termios.c_cflag |= CLOCAL; + tty_set_operations(fwtty_driver, &fwtty_ops); + + err = tty_register_driver(fwtty_driver); + if (err) { + driver_err("register tty driver failed (%d)", err); + goto put_tty; + } + + fwtty_txn_cache = kmem_cache_create("fwtty_txn_cache", + sizeof(struct fwtty_transaction), + 0, 0, fwtty_txn_constructor); + if (!fwtty_txn_cache) { + err = -ENOMEM; + goto unregister_driver; + } + + /* + * Ideally, this address handler would be registered per local node + * (rather than the same handler for all local nodes). However, + * since the firewire core requires the config rom descriptor *before* + * the local unit device(s) are created, a single management handler + * must suffice for all local serial units. + */ + fwserial_mgmt_addr_handler.length = sizeof(struct fwserial_mgmt_pkt); + fwserial_mgmt_addr_handler.address_callback = fwserial_mgmt_handler; + + err = fw_core_add_address_handler(&fwserial_mgmt_addr_handler, + &fwserial_mgmt_addr_region); + if (err) { + driver_err("add management handler failed (%d)", err); + goto destroy_cache; + } + + fwserial_unit_directory_data.unit_addr_offset = + FW_UNIT_ADDRESS(fwserial_mgmt_addr_handler.offset); + err = fw_core_add_descriptor(&fwserial_unit_directory); + if (err) { + driver_err("add unit descriptor failed (%d)", err); + goto remove_handler; + } + + err = driver_register(&fwserial_driver.driver); + if (err) { + driver_err("register fwserial driver failed (%d)", err); + goto remove_descriptor; + } + + return 0; + +remove_descriptor: + fw_core_remove_descriptor(&fwserial_unit_directory); +remove_handler: + fw_core_remove_address_handler(&fwserial_mgmt_addr_handler); +destroy_cache: + kmem_cache_destroy(fwtty_txn_cache); +unregister_driver: + tty_unregister_driver(fwtty_driver); +put_tty: + put_tty_driver(fwtty_driver); + return err; +} + +static void __exit fwserial_exit(void) +{ + driver_unregister(&fwserial_driver.driver); + fw_core_remove_descriptor(&fwserial_unit_directory); + fw_core_remove_address_handler(&fwserial_mgmt_addr_handler); + kmem_cache_destroy(fwtty_txn_cache); + tty_unregister_driver(fwtty_driver); + put_tty_driver(fwtty_driver); +} + +module_init(fwserial_init); +module_exit(fwserial_exit); + +MODULE_AUTHOR("Peter Hurley (peter@hurleysoftware.com)"); +MODULE_DESCRIPTION("FireWire Serial TTY Driver"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(ieee1394, fwserial_id_table); +MODULE_PARM_DESC(ttys, "Number of ttys to create for each local firewire node"); +MODULE_PARM_DESC(auto, "Auto-connect a tty to each firewire node discovered"); +MODULE_PARM_DESC(loop, "Create a loopback device, fwloop, with ttys"); +MODULE_PARM_DESC(limit_bw, "Limit bandwidth utilization to 20%."); diff --git a/drivers/staging/fwserial/fwserial.h b/drivers/staging/fwserial/fwserial.h new file mode 100644 index 00000000000..8b572edf956 --- /dev/null +++ b/drivers/staging/fwserial/fwserial.h @@ -0,0 +1,387 @@ +#ifndef _FIREWIRE_FWSERIAL_H +#define _FIREWIRE_FWSERIAL_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dma_fifo.h" + +#ifdef FWTTY_PROFILING +#define DISTRIBUTION_MAX_SIZE 8192 +#define DISTRIBUTION_MAX_INDEX (ilog2(DISTRIBUTION_MAX_SIZE) + 1) +static inline void profile_size_distrib(unsigned stat[], unsigned val) +{ + int n = (val) ? min(ilog2(val) + 1, DISTRIBUTION_MAX_INDEX) : 0; + ++stat[n]; +} +#else +#define DISTRIBUTION_MAX_INDEX 0 +#define profile_size_distrib(st, n) +#endif + +/* Parameters for both VIRT_CABLE_PLUG & VIRT_CABLE_PLUG_RSP mgmt codes */ +struct virt_plug_params { + __be32 status_hi; + __be32 status_lo; + __be32 fifo_hi; + __be32 fifo_lo; + __be32 fifo_len; +}; + +struct peer_work_params { + union { + struct virt_plug_params plug_req; + }; +}; + +/** + * fwtty_peer: structure representing local & remote unit devices + * @unit: unit child device of fw_device node + * @serial: back pointer to associated fw_serial aggregate + * @guid: unique 64-bit guid for this unit device + * @generation: most recent bus generation + * @node_id: most recent node_id + * @speed: link speed of peer (0 = S100, 2 = S400, ... 5 = S3200) + * @mgmt_addr: bus addr region to write mgmt packets to + * @status_addr: bus addr register to write line status to + * @fifo_addr: bus addr region to write serial output to + * @fifo_len: max length for single write to fifo_addr + * @list: link for insertion into fw_serial's peer_list + * @rcu: for deferring peer reclamation + * @lock: spinlock to synchonize changes to state & port fields + * @work: only one work item can be queued at any one time + * Note: pending work is canceled prior to removal, so this + * peer is valid for at least the lifetime of the work function + * @work_params: parameter block for work functions + * @timer: timer for resetting peer state if remote request times out + * @state: current state + * @connect: work item for auto-connecting + * @connect_retries: # of connections already attempted + * @port: associated tty_port (usable if state == FWSC_ATTACHED) + */ +struct fwtty_peer { + struct fw_unit *unit; + struct fw_serial *serial; + u64 guid; + int generation; + int node_id; + unsigned speed; + int max_payload; + u64 mgmt_addr; + + /* these are usable only if state == FWSC_ATTACHED */ + u64 status_addr; + u64 fifo_addr; + int fifo_len; + + struct list_head list; + struct rcu_head rcu; + + spinlock_t lock; + struct work_struct work; + struct peer_work_params work_params; + struct timer_list timer; + int state; + struct delayed_work connect; + int connect_retries; + + struct fwtty_port *port; +}; + +#define to_peer(ptr, field) (container_of(ptr, struct fwtty_peer, field)) + +/* state values for fwtty_peer.state field */ +enum fwtty_peer_state { + FWPS_GONE, + FWPS_NOT_ATTACHED, + FWPS_ATTACHED, + FWPS_PLUG_PENDING, + FWPS_PLUG_RESPONDING, + FWPS_UNPLUG_PENDING, + FWPS_UNPLUG_RESPONDING, + + FWPS_NO_MGMT_ADDR = -1, +}; + +#define CONNECT_RETRY_DELAY HZ +#define MAX_CONNECT_RETRIES 10 + +/* must be holding peer lock for these state funclets */ +static inline void peer_set_state(struct fwtty_peer *peer, int new) +{ + peer->state = new; +} + +static inline struct fwtty_port *peer_revert_state(struct fwtty_peer *peer) +{ + struct fwtty_port *port = peer->port; + + peer->port = NULL; + peer_set_state(peer, FWPS_NOT_ATTACHED); + return port; +} + +struct fwserial_mgmt_pkt { + struct { + __be16 len; + __be16 code; + } hdr; + union { + struct virt_plug_params plug_req; + struct virt_plug_params plug_rsp; + }; +} __packed; + +/* fwserial_mgmt_packet codes */ +#define FWSC_RSP_OK 0x0000 +#define FWSC_RSP_NACK 0x8000 +#define FWSC_CODE_MASK 0x0fff + +#define FWSC_VIRT_CABLE_PLUG 1 +#define FWSC_VIRT_CABLE_UNPLUG 2 +#define FWSC_VIRT_CABLE_PLUG_RSP 3 +#define FWSC_VIRT_CABLE_UNPLUG_RSP 4 + +/* 1 min. plug timeout -- suitable for userland authorization */ +#define VIRT_CABLE_PLUG_TIMEOUT (60 * HZ) + +struct stats { + unsigned xchars; + unsigned dropped; + unsigned tx_stall; + unsigned fifo_errs; + unsigned sent; + unsigned lost; + unsigned throttled; + unsigned watermark; + unsigned reads[DISTRIBUTION_MAX_INDEX + 1]; + unsigned writes[DISTRIBUTION_MAX_INDEX + 1]; + unsigned txns[DISTRIBUTION_MAX_INDEX + 1]; + unsigned unthrottle[DISTRIBUTION_MAX_INDEX + 1]; +}; + +struct fwconsole_ops { + void (*notify)(int code, void *data); + void (*stats)(struct stats *stats, void *data); + void (*proc_show)(struct seq_file *m, void *data); +}; + +/* codes for console ops notify */ +#define FWCON_NOTIFY_ATTACH 1 +#define FWCON_NOTIFY_DETACH 2 + +struct buffered_rx { + struct list_head list; + size_t n; + unsigned char data[0]; +}; + +/** + * fwtty_port: structure used to track/represent underlying tty_port + * @port: underlying tty_port + * @device: tty device + * @index: index into port_table for this particular port + * note: minor = index + FWSERIAL_TTY_START_MINOR + * @serial: back pointer to the containing fw_serial + * @rx_handler: bus address handler for unique addr region used by remotes + * to communicate with this port. Every port uses + * fwtty_port_handler() for per port transactions. + * @fwcon_ops: ops for attached fw_console (if any) + * @con_data: private data for fw_console + * @wait_tx: waitqueue for sleeping until writer/drain completes tx + * @emit_breaks: delayed work responsible for generating breaks when the + * break line status is active + * @cps : characters per second computed from the termios settings + * @break_last: timestamp in jiffies from last emit_breaks + * @hangup: work responsible for HUPing when carrier is dropped/lost + * @mstatus: loose virtualization of LSR/MSR + * bits 15..0 correspond to TIOCM_* bits + * bits 19..16 reserved for mctrl + * bit 20 OOB_TX_THROTTLE + * bits 23..21 reserved + * bits 31..24 correspond to UART_LSR_* bits + * @lock: spinlock for protecting concurrent access to fields below it + * @mctrl: loose virtualization of MCR + * bits 15..0 correspond to TIOCM_* bits + * bit 16 OOB_RX_THROTTLE + * bits 19..17 reserved + * bits 31..20 reserved for mstatus + * @drain: delayed work scheduled to ensure that writes are flushed. + * The work can race with the writer but concurrent sending is + * prevented with the IN_TX flag. Scheduled under lock to + * limit scheduling when fifo has just been drained. + * @push: work responsible for pushing buffered rx to the ldisc. + * rx can become buffered if the tty buffer is filled before the + * ldisc throttles the sender. + * @buf_list: list of buffered rx yet to be sent to ldisc + * @buffered: byte count of buffered rx + * @tx_fifo: fifo used to store & block-up writes for dma to remote + * @max_payload: max bytes transmissable per dma (based on peer's max_payload) + * @status_mask: UART_LSR_* bitmask significant to rx (based on termios) + * @ignore_mask: UART_LSR_* bitmask of states to ignore (also based on termios) + * @break_ctl: if set, port is 'sending break' to remote + * @write_only: self-explanatory + * @overrun: previous rx was lost (partially or completely) + * @loopback: if set, port is in loopback mode + * @flags: atomic bit flags + * bit 0: IN_TX - gate to allow only one cpu to send from the dma fifo + * at a time. + * bit 1: STOP_TX - force tx to exit while sending + * @peer: rcu-pointer to associated fwtty_peer (if attached) + * NULL if no peer attached + * @icount: predefined statistics reported by the TIOCGICOUNT ioctl + * @stats: additional statistics reported in /proc/tty/driver/firewire_serial + */ +struct fwtty_port { + struct tty_port port; + struct device *device; + unsigned index; + struct fw_serial *serial; + struct fw_address_handler rx_handler; + + struct fwconsole_ops *fwcon_ops; + void *con_data; + + wait_queue_head_t wait_tx; + struct delayed_work emit_breaks; + unsigned cps; + unsigned long break_last; + + struct work_struct hangup; + + unsigned mstatus; + + spinlock_t lock; + unsigned mctrl; + struct delayed_work drain; + struct work_struct push; + struct list_head buf_list; + int buffered; + struct dma_fifo tx_fifo; + int max_payload; + unsigned status_mask; + unsigned ignore_mask; + unsigned break_ctl:1, + write_only:1, + overrun:1, + loopback:1; + unsigned long flags; + + struct fwtty_peer *peer; + + struct async_icount icount; + struct stats stats; +}; + +#define to_port(ptr, field) (container_of(ptr, struct fwtty_port, field)) + +/* bit #s for flags field */ +#define IN_TX 0 +#define STOP_TX 1 +#define BUFFERING_RX 2 + +/* bitmasks for special mctrl/mstatus bits */ +#define OOB_RX_THROTTLE 0x00010000 +#define MCTRL_RSRVD 0x000e0000 +#define OOB_TX_THROTTLE 0x00100000 +#define MSTATUS_RSRVD 0x00e00000 + +#define MCTRL_MASK (TIOCM_DTR | TIOCM_RTS | TIOCM_OUT1 | TIOCM_OUT2 | \ + TIOCM_LOOP | OOB_RX_THROTTLE | MCTRL_RSRVD) + +/* XXX even every 1/50th secs. may be unnecessarily accurate */ +/* delay in jiffies between brk emits */ +#define FREQ_BREAKS (HZ / 50) + +/* Ports are allocated in blocks of num_ports for each fw_card */ +#define MAX_CARD_PORTS 32 /* max # of ports per card */ +#define MAX_TOTAL_PORTS 64 /* max # of ports total */ + +/* tuning parameters */ +#define FWTTY_PORT_TXFIFO_LEN 4096 +#define FWTTY_PORT_MAX_PEND_DMA 8 /* costs a cache line per pend */ +#define DRAIN_THRESHOLD 1024 +#define MAX_ASYNC_PAYLOAD 4096 /* ohci-defined limit */ +#define WRITER_MINIMUM 128 +/* TODO: how to set watermark to AR context size? see fwtty_rx() */ +#define HIGH_WATERMARK 32768 /* AR context is 32K */ + +/* + * Size of bus addr region above 4GB used per port as the recv addr + * - must be at least as big as the MAX_ASYNC_PAYLOAD + */ +#define FWTTY_PORT_RXFIFO_LEN MAX_ASYNC_PAYLOAD + +/** + * fw_serial: aggregate used to associate tty ports with specific fw_card + * @card: fw_card associated with this fw_serial device (1:1 association) + * @kref: reference-counted multi-port management allows delayed destroy + * @self: local unit device as 'peer'. Not valid until local unit device + * is enumerated. + * @list: link for insertion into fwserial_list + * @peer_list: list of local & remote unit devices attached to this card + * @ports: fixed array of tty_ports provided by this serial device + */ +struct fw_serial { + struct fw_card *card; + struct kref kref; + + struct fwtty_peer *self; + + struct list_head list; + struct list_head peer_list; + + struct fwtty_port *ports[MAX_CARD_PORTS]; +}; + +#define to_serial(ptr, field) (container_of(ptr, struct fw_serial, field)) + +#define TTY_DEV_NAME "fwtty" /* ttyFW was taken */ +static const char tty_dev_name[] = TTY_DEV_NAME; +static const char loop_dev_name[] = "fwloop"; +extern bool limit_bw; + +struct tty_driver *fwtty_driver; + +#define driver_err(s, v...) pr_err(KBUILD_MODNAME ": " s, ##v) + +struct fwtty_port *fwtty_port_get(unsigned index); +void fwtty_port_put(struct fwtty_port *port); + +static inline void fwtty_bind_console(struct fwtty_port *port, + struct fwconsole_ops *fwcon_ops, + void *data) +{ + port->con_data = data; + port->fwcon_ops = fwcon_ops; +} + +/* + * Returns the max send async payload size in bytes based on the unit device + * link speed - if set to limit bandwidth to max 20%, use lookup table + */ +static inline int link_speed_to_max_payload(unsigned speed) +{ + static const int max_async[] = { 307, 614, 1229, 2458, 4916, 9832, }; + BUILD_BUG_ON(ARRAY_SIZE(max_async) - 1 != SCODE_3200); + + speed = clamp(speed, (unsigned) SCODE_100, (unsigned) SCODE_3200); + if (limit_bw) + return max_async[speed]; + else + return 1 << (speed + 9); +} + +#endif /* _FIREWIRE_FWSERIAL_H */ -- cgit v1.2.3 From b78a4932f5fb11fadf41e69c606a33fa6787574c Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Tue, 13 Nov 2012 18:43:03 +0100 Subject: mac80211: deinitialize ibss-internals after emptiness check The check whether the IBSS is active and can be removed should be performed before deinitializing the fields used for the check/search. Otherwise, the configured BSS will not be found and removed properly. To make it more clear for the future, rename sdata->u.ibss to the local pointer ifibss which is used within the checks. This behaviour was introduced by f3209bea110cade12e2b133da8b8499689cb0e2e ("mac80211: fix IBSS teardown race") Cc: stable@vger.kernel.org Cc: Ignacy Gawedzki Signed-off-by: Simon Wunderlich Signed-off-by: Johannes Berg --- net/mac80211/ibss.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index bf87c70ac6c..c21e33d1abd 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -1151,10 +1151,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) mutex_lock(&sdata->u.ibss.mtx); - sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; - memset(sdata->u.ibss.bssid, 0, ETH_ALEN); - sdata->u.ibss.ssid_len = 0; - active_ibss = ieee80211_sta_active_ibss(sdata); if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { @@ -1175,6 +1171,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) } } + ifibss->state = IEEE80211_IBSS_MLME_SEARCH; + memset(ifibss->bssid, 0, ETH_ALEN); + ifibss->ssid_len = 0; + sta_info_flush(sdata->local, sdata); spin_lock_bh(&ifibss->incomplete_lock); -- cgit v1.2.3 From 4f29ef050848245f7c180b95ccf67dfcd76b1fd8 Mon Sep 17 00:00:00 2001 From: Kevin McKinney Date: Mon, 12 Nov 2012 22:20:30 -0500 Subject: Staging: bcm: Add two products and remove an existing product. This patch adds two new products and modifies the device id table to include them. In addition, product of 0xbccd - BCM_USB_PRODUCT_ID_SM250 is removed because Beceem, ZTE, Sprint use this id for block devices. Reported-by: Muhammad Minhazul Haque Signed-off-by: Kevin McKinney Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceInit.c | 3 ++- drivers/staging/bcm/InterfaceInit.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index bf5c9826752..eb246430b32 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -4,11 +4,12 @@ static struct usb_device_id InterfaceUsbtable[] = { { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) }, { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) }, { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_SM250) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_SYM) }, { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) }, { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) }, { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) }, { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_226) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_326) }, { } }; MODULE_DEVICE_TABLE(usb, InterfaceUsbtable); diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h index 71e80f3bd4c..ffa6e9667ec 100644 --- a/drivers/staging/bcm/InterfaceInit.h +++ b/drivers/staging/bcm/InterfaceInit.h @@ -8,11 +8,11 @@ #define BCM_USB_PRODUCT_ID_T3 0x0300 #define BCM_USB_PRODUCT_ID_T3B 0x0210 #define BCM_USB_PRODUCT_ID_T3L 0x0220 -#define BCM_USB_PRODUCT_ID_SM250 0xbccd #define BCM_USB_PRODUCT_ID_SYM 0x15E #define BCM_USB_PRODUCT_ID_1901 0xe017 #define BCM_USB_PRODUCT_ID_226 0x0132 /* not sure if this is valid */ #define BCM_USB_PRODUCT_ID_ZTE_226 0x172 +#define BCM_USB_PRODUCT_ID_ZTE_326 0x173 /* ZTE AX326 */ #define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007 #define BCM_USB_MINOR_BASE 192 -- cgit v1.2.3 From 5c0ec2497fa2dcfc97907b92094cecab1af8943f Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:07 +0200 Subject: staging: rtl8187se: Removed dead functions Removed stale functions that are never called Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 185 ---------------------------- drivers/staging/rtl8187se/r8180_rtl8225z2.c | 16 --- 2 files changed, 201 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 20e5fb58f52..8ed94d12f5e 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -695,14 +695,6 @@ void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual) return; } -void rtl8180_irq_enable(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - priv->irq_enabled = 1; - write_nic_word(dev, INTA_MASK, priv->irq_mask); -} - void rtl8180_irq_disable(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -724,7 +716,6 @@ void rtl8180_set_mode(struct net_device *dev, int mode) write_nic_byte(dev, EPROM_CMD, ecmd); } -void rtl8180_adapter_start(struct net_device *dev); void rtl8180_beacon_tx_enable(struct net_device *dev); void rtl8180_update_msr(struct net_device *dev) @@ -771,57 +762,6 @@ void rtl8180_set_chan(struct net_device *dev, short ch) priv->rf_set_chan(dev, priv->chan); } -void rtl8180_rx_enable(struct net_device *dev) -{ - u8 cmd; - u32 rxconf; - /* for now we accept data, management & ctl frame*/ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - rxconf = read_nic_dword(dev, RX_CONF); - rxconf = rxconf & ~MAC_FILTER_MASK; - rxconf = rxconf | (1<flags & IFF_PROMISC) - DMESG("NIC in promisc mode"); - - if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || \ - dev->flags & IFF_PROMISC) { - rxconf = rxconf | (1<ieee80211->iw_mode == IW_MODE_MONITOR) { - rxconf = rxconf | (1<crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR) - rxconf = rxconf | (1<retry_data<retry_rts<hw_plcp_len) - txconf = txconf & ~TCR_PLCP_LEN; - else - txconf = txconf | TCR_PLCP_LEN; - - txconf = txconf & ~TCR_MXDMA_MASK; - txconf = txconf | (TCR_MXDMA_2048<irq_mask = 0x6fcf; - - priv->dma_poll_mask = 0; - - rtl8180_beacon_tx_disable(dev); - - rtl8180_set_mode(dev, EPROM_CMD_CONFIG); - write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]); - write_nic_word(dev, MAC4, ((u32 *)dev->dev_addr)[1] & 0xffff); - rtl8180_set_mode(dev, EPROM_CMD_NORMAL); - - rtl8180_update_msr(dev); - - /* These might be unnecessary since we do in rx_enable / tx_enable */ - fix_rx_fifo(dev); - fix_tx_fifo(dev); - - rtl8180_set_mode(dev, EPROM_CMD_CONFIG); - - /* - * The following is very strange. seems to be that 1 means test mode, - * but we need to acknowledges the nic when a packet is ready - * although we set it to 0 - */ - - write_nic_byte(dev, - CONFIG2, read_nic_byte(dev, CONFIG2) & ~\ - (1<rf_init(dev); - - if (priv->rf_set_sens != NULL) - priv->rf_set_sens(dev, priv->sens); - rtl8180_irq_enable(dev); - - netif_start_queue(dev); -} - /* * This configures registers for beacon tx and enables it via * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c index d28c1d99608..a369a3d2b7f 100644 --- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c +++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c @@ -412,22 +412,6 @@ static u32 read_rtl8225(struct net_device *dev, u8 adr) return dataRead; } -short rtl8225_is_V_z2(struct net_device *dev) -{ - short vz2 = 1; - - if (read_rtl8225(dev, 8) != 0x588) - vz2 = 0; - else /* reg 9 pg 1 = 24 */ - if (read_rtl8225(dev, 9) != 0x700) - vz2 = 0; - - /* sw back to pg 0 */ - write_rtl8225(dev, 0, 0xb7); - - return vz2; -} - void rtl8225z2_rf_close(struct net_device *dev) { RF_WriteReg(dev, 0x4, 0x1f); -- cgit v1.2.3 From 51150d27377324441a10d74f7ef7905a440f98ef Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:08 +0200 Subject: staging: rtl8187se: Removed legacy rtl8225_rf_set_chan() Removed rtl8225_rf_set_chan() and corresponding arrays, changed its usage to rtl8225z2_rf_set_chan() Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 41 ------- drivers/staging/rtl8187se/r8180_rtl8225z2.c | 160 +--------------------------- 2 files changed, 3 insertions(+), 198 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 8ed94d12f5e..1a76cc956ea 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -444,24 +444,6 @@ void buffer_free(struct net_device *dev, struct buffer **buffer, int len, short *buffer = NULL; } -void print_buffer(u32 *buffer, int len) -{ - int i; - u8 *buf = (u8 *)buffer; - - printk("ASCII BUFFER DUMP (len: %x):\n", len); - - for (i = 0; i < len; i++) - printk("%c", buf[i]); - - printk("\nBINARY BUFFER DUMP (len: %x):\n", len); - - for (i = 0; i < len; i++) - printk("%02x", buf[i]); - - printk("\n"); -} - int get_curr_tx_free_desc(struct net_device *dev, int priority) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -2970,29 +2952,6 @@ void write_phy_cck(struct net_device *dev, u8 adr, u32 data) rtl8185_write_phy(dev, adr, data | 0x10000); } -void rtl8185_set_rate(struct net_device *dev) -{ - int i; - u16 word; - int basic_rate, min_rr_rate, max_rr_rate; - - basic_rate = ieeerate2rtlrate(240); - min_rr_rate = ieeerate2rtlrate(60); - max_rr_rate = ieeerate2rtlrate(240); - - write_nic_byte(dev, RESP_RATE, - max_rr_rate<chtxpwr[ch]; - u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch]; - - max_cck_power_level = 35; - max_ofdm_power_level = 35; - min_ofdm_power_level = 0; - - if (cck_power_level > max_cck_power_level) - cck_power_level = max_cck_power_level; - - GainIdx = cck_power_level % 6; - GainSetting = cck_power_level / 6; - - if (ch == 14) - cck_power_table = rtl8225_tx_power_cck_ch14; - else - cck_power_table = rtl8225_tx_power_cck; - - write_nic_byte(dev, TX_GAIN_CCK, - rtl8225_tx_gain_cck_ofdm[GainSetting] >> 1); - - for (i = 0; i < 8; i++) { - power = cck_power_table[GainIdx * 8 + i]; - write_phy_cck(dev, 0x44 + i, power); - } - - /* FIXME Is this delay really needed ? */ - force_pci_posting(dev); - mdelay(1); - - if (ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level)) - ofdm_power_level = max_ofdm_power_level; - else - ofdm_power_level += min_ofdm_power_level; - - if (ofdm_power_level > 35) - ofdm_power_level = 35; - - GainIdx = ofdm_power_level % 6; - GainSetting = ofdm_power_level / 6; - - rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON); - - write_phy_ofdm(dev, 2, 0x42); - write_phy_ofdm(dev, 6, 0x00); - write_phy_ofdm(dev, 8, 0x00); - - write_nic_byte(dev, TX_GAIN_OFDM, - rtl8225_tx_gain_cck_ofdm[GainSetting] >> 1); - - power = rtl8225_tx_power_ofdm[GainIdx]; - - write_phy_ofdm(dev, 5, power); - write_phy_ofdm(dev, 7, power); - - force_pci_posting(dev); - mdelay(1); -} - static const u8 rtl8225z2_threshold[] = { 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd, }; @@ -263,15 +157,6 @@ static const u16 rtl8225z2_rxgain[] = { }; -static const u8 ZEBRA2_CCK_OFDM_GAIN_SETTING[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, - 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, -}; - static const u8 rtl8225z2_tx_power_ofdm[] = { 0x42, 0x00, 0x40, 0x00, 0x40 }; @@ -508,8 +393,7 @@ void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch) if (cck_power_level > 35) cck_power_level = 35; - write_nic_byte(dev, CCK_TXAGC, - (ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)cck_power_level])); + write_nic_byte(dev, CCK_TXAGC, cck_power_level); force_pci_posting(dev); mdelay(1); @@ -524,8 +408,7 @@ void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch) write_phy_ofdm(dev, 8, 0x40); } - write_nic_byte(dev, OFDM_TXAGC, - ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)ofdm_power_level]); + write_nic_byte(dev, OFDM_TXAGC, ofdm_power_level); if (ofdm_power_level <= 11) { write_phy_ofdm(dev, 0x07, 0x5c); @@ -576,43 +459,6 @@ static void rtl8225_host_pci_init(struct net_device *dev) write_nic_word(dev, GP_ENABLE, 0xff & (~(1 << 6))); } -static void rtl8225_rf_set_chan(struct net_device *dev, short ch) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - short gset = (priv->ieee80211->state == IEEE80211_LINKED && - ieee80211_is_54g(&priv->ieee80211->current_network)) || - priv->ieee80211->iw_mode == IW_MODE_MONITOR; - - rtl8225_SetTXPowerLevel(dev, ch); - - write_rtl8225(dev, 0x7, rtl8225_chan[ch]); - - force_pci_posting(dev); - mdelay(10); - - if (gset) { - write_nic_byte(dev, SIFS, 0x22); - write_nic_byte(dev, DIFS, 0x14); - } else { - write_nic_byte(dev, SIFS, 0x44); - write_nic_byte(dev, DIFS, 0x24); - } - - if (priv->ieee80211->state == IEEE80211_LINKED && - ieee80211_is_shortslot(&priv->ieee80211->current_network)) - write_nic_byte(dev, SLOT, 0x9); - else - write_nic_byte(dev, SLOT, 0x14); - - if (gset) { - write_nic_byte(dev, EIFS, 81); - write_nic_byte(dev, CW_VAL, 0x73); - } else { - write_nic_byte(dev, EIFS, 81); - write_nic_byte(dev, CW_VAL, 0xa5); - } -} - void rtl8225z2_rf_init(struct net_device *dev) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -792,7 +638,7 @@ void rtl8225z2_rf_init(struct net_device *dev) write_nic_dword(dev, 0x94, 0x15c00002); rtl8185_rf_pins_enable(dev); - rtl8225_rf_set_chan(dev, priv->chan); + rtl8225z2_rf_set_chan(dev, priv->chan); } void rtl8225z2_rf_set_mode(struct net_device *dev) -- cgit v1.2.3 From bf5bff4779efb6e5a64a9848f04b90abd225c10f Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:09 +0200 Subject: staging: rtl8187se: Removed empty functions and one-iteration loop Removed empty functions, their calls and 'do {} while (0)' loop condition Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8185b_init.c | 210 ++++++++++++++------------------ 1 file changed, 89 insertions(+), 121 deletions(-) diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index bf343199bd2..8fa42de4fca 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -217,118 +217,115 @@ static int HwHSSIThreeWire(struct net_device *dev, u8 TryCnt; u8 u1bTmp; - do { - /* Check if WE and RE are cleared. */ - for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { - u1bTmp = read_nic_byte(dev, SW_3W_CMD1); - if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0) - break; + /* Check if WE and RE are cleared. */ + for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { + u1bTmp = read_nic_byte(dev, SW_3W_CMD1); + if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0) + break; - udelay(10); - } - if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) { - printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:" - " %#X RE|WE bits are not clear!!\n", u1bTmp); - dump_stack(); - return 0; - } + udelay(10); + } + if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) { + printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:" + " %#X RE|WE bits are not clear!!\n", u1bTmp); + dump_stack(); + return 0; + } - /* RTL8187S HSSI Read/Write Function */ - u1bTmp = read_nic_byte(dev, RF_SW_CONFIG); + /* RTL8187S HSSI Read/Write Function */ + u1bTmp = read_nic_byte(dev, RF_SW_CONFIG); - if (bSI) - u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */ + if (bSI) + u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */ - else - u1bTmp &= ~RF_SW_CFG_SI; /* reg08[1]=0 Parallel Interface(PI) */ + else + u1bTmp &= ~RF_SW_CFG_SI; /* reg08[1]=0 Parallel Interface(PI) */ - write_nic_byte(dev, RF_SW_CONFIG, u1bTmp); + write_nic_byte(dev, RF_SW_CONFIG, u1bTmp); - if (bSI) { - /* jong: HW SI read must set reg84[3]=0. */ - u1bTmp = read_nic_byte(dev, RFPinsSelect); - u1bTmp &= ~BIT3; - write_nic_byte(dev, RFPinsSelect, u1bTmp); - } - /* Fill up data buffer for write operation. */ - - if (bWrite) { - if (nDataBufBitCnt == 16) { - write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); - } else if (nDataBufBitCnt == 64) { - /* RTL8187S shouldn't enter this case */ - write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf)); - write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4))); - } else { - int idx; - int ByteCnt = nDataBufBitCnt / 8; - /* printk("%d\n",nDataBufBitCnt); */ - if ((nDataBufBitCnt % 8) != 0) { - printk(KERN_ERR "rtl8187se: " - "HwThreeWire(): nDataBufBitCnt(%d)" - " should be multiple of 8!!!\n", - nDataBufBitCnt); - dump_stack(); - nDataBufBitCnt += 8; - nDataBufBitCnt &= ~7; - } + if (bSI) { + /* jong: HW SI read must set reg84[3]=0. */ + u1bTmp = read_nic_byte(dev, RFPinsSelect); + u1bTmp &= ~BIT3; + write_nic_byte(dev, RFPinsSelect, u1bTmp); + } + /* Fill up data buffer for write operation. */ + + if (bWrite) { + if (nDataBufBitCnt == 16) { + write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); + } else if (nDataBufBitCnt == 64) { + /* RTL8187S shouldn't enter this case */ + write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf)); + write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4))); + } else { + int idx; + int ByteCnt = nDataBufBitCnt / 8; + /* printk("%d\n",nDataBufBitCnt); */ + if ((nDataBufBitCnt % 8) != 0) { + printk(KERN_ERR "rtl8187se: " + "HwThreeWire(): nDataBufBitCnt(%d)" + " should be multiple of 8!!!\n", + nDataBufBitCnt); + dump_stack(); + nDataBufBitCnt += 8; + nDataBufBitCnt &= ~7; + } - if (nDataBufBitCnt > 64) { - printk(KERN_ERR "rtl8187se: HwThreeWire():" - " nDataBufBitCnt(%d) should <= 64!!!\n", - nDataBufBitCnt); - dump_stack(); - nDataBufBitCnt = 64; - } + if (nDataBufBitCnt > 64) { + printk(KERN_ERR "rtl8187se: HwThreeWire():" + " nDataBufBitCnt(%d) should <= 64!!!\n", + nDataBufBitCnt); + dump_stack(); + nDataBufBitCnt = 64; + } - for (idx = 0; idx < ByteCnt; idx++) - write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx)); + for (idx = 0; idx < ByteCnt; idx++) + write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx)); - } - } else { /* read */ - if (bSI) { - /* SI - reg274[3:0] : RF register's Address */ - write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); - } else { - /* PI - reg274[15:12] : RF register's Address */ - write_nic_word(dev, SW_3W_DB0, (*((u16 *)pDataBuf)) << 12); - } } + } else { /* read */ + if (bSI) { + /* SI - reg274[3:0] : RF register's Address */ + write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); + } else { + /* PI - reg274[15:12] : RF register's Address */ + write_nic_word(dev, SW_3W_DB0, (*((u16 *)pDataBuf)) << 12); + } + } - /* Set up command: WE or RE. */ - if (bWrite) - write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE); + /* Set up command: WE or RE. */ + if (bWrite) + write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE); - else - write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE); + else + write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE); - /* Check if DONE is set. */ - for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { - u1bTmp = read_nic_byte(dev, SW_3W_CMD1); - if ((u1bTmp & SW_3W_CMD1_DONE) != 0) - break; - - udelay(10); - } + /* Check if DONE is set. */ + for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { + u1bTmp = read_nic_byte(dev, SW_3W_CMD1); + if ((u1bTmp & SW_3W_CMD1_DONE) != 0) + break; - write_nic_byte(dev, SW_3W_CMD1, 0); + udelay(10); + } - /* Read back data for read operation. */ - if (bWrite == 0) { - if (bSI) { - /* Serial Interface : reg363_362[11:0] */ - *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ) ; - } else { - /* Parallel Interface : reg361_360[11:0] */ - *((u16 *)pDataBuf) = read_nic_word(dev, PI_DATA_READ); - } + write_nic_byte(dev, SW_3W_CMD1, 0); - *((u16 *)pDataBuf) &= 0x0FFF; + /* Read back data for read operation. */ + if (bWrite == 0) { + if (bSI) { + /* Serial Interface : reg363_362[11:0] */ + *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ) ; + } else { + /* Parallel Interface : reg361_360[11:0] */ + *((u16 *)pDataBuf) = read_nic_word(dev, PI_DATA_READ); } - } while (0); + *((u16 *)pDataBuf) &= 0x0FFF; + } return bResult; } @@ -1148,18 +1145,11 @@ void rtl8185b_irq_enable(struct net_device *dev) write_nic_dword(dev, IMR, priv->IntrMask); } -void DrvIFIndicateDisassociation(struct net_device *dev, u16 reason) -{ - /* nothing is needed after disassociation request. */ -} - void MgntDisconnectIBSS(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); u8 i; - DrvIFIndicateDisassociation(dev, unspec_reason); - for (i = 0; i < 6 ; i++) priv->ieee80211->current_network.bssid[i] = 0x55; @@ -1190,8 +1180,6 @@ void MlmeDisassociateRequest(struct net_device *dev, u8 *asSta, u8 asRsn) if (memcmp(priv->ieee80211->current_network.bssid, asSta, 6) == 0) { /* ShuChen TODO: change media status. */ - /* ShuChen TODO: What to do when disassociate. */ - DrvIFIndicateDisassociation(dev, unspec_reason); for (i = 0; i < 6; i++) priv->ieee80211->current_network.bssid[i] = 0x22; @@ -1267,14 +1255,6 @@ bool SetRFPowerState(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState) return bResult; } -void HalEnableRx8185Dummy(struct net_device *dev) -{ -} - -void HalDisableRx8185Dummy(struct net_device *dev) -{ -} - bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u32 ChangeSource) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -1359,18 +1339,6 @@ bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u if (bActionAllowed) { /* Config HW to the specified mode. */ SetRFPowerState(dev, StateToSet); - - /* Turn on RF. */ - if (StateToSet == eRfOn) { - HalEnableRx8185Dummy(dev); - if (bConnectBySSID) { - /* by amy not supported */ - } - } - /* Turn off RF. */ - else if (StateToSet == eRfOff) - HalDisableRx8185Dummy(dev); - } /* Release RF spinlock */ -- cgit v1.2.3 From ddedb78aac0fe3fd59263a50c213ca07a4d16dec Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:10 +0200 Subject: staging: rtl8187se: Fixed bugs in interrupt handler Fixed typo in rtl8180_interrupt() and added missing line Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 1a76cc956ea..6ec3a93803f 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -3787,7 +3787,7 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) priv->stats.txbkperr++; priv->ieee80211->stats.tx_errors++; rtl8180_tx_isr(dev, BK_PRIORITY, 1); - rtl8180_try_wake_queue(dev, BE_PRIORITY); + rtl8180_try_wake_queue(dev, BK_PRIORITY); } if (inta & ISR_TBEDER) { /* corresponding to BE_PRIORITY */ @@ -3841,6 +3841,7 @@ irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) priv->link_detect.NumTxOkInPeriod++; /* YJ,add,080828 */ priv->stats.txnpokint++; rtl8180_tx_isr(dev, NORM_PRIORITY, 0); + rtl8180_try_wake_queue(dev, NORM_PRIORITY); } if (inta & ISR_TLPDOK) { /* Low priority tx ok */ -- cgit v1.2.3 From d4457a8e42a3cd71c06032e5ab05175f31d589ec Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:11 +0200 Subject: staging: rtl8187se: Simplified function GetSupportedWirelessMode8185() Removed unnecessary variable in GetSupportedWirelessMode8185() and shortened its code Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8185b_init.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 8fa42de4fca..cf9bcd588c1 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -927,10 +927,7 @@ static void MacConfig_85BASIC(struct net_device *dev) u8 GetSupportedWirelessMode8185(struct net_device *dev) { - u8 btSupportedWirelessMode = 0; - - btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G); - return btSupportedWirelessMode; + return WIRELESS_MODE_B | WIRELESS_MODE_G; } void ActUpdateChannelAccessSetting(struct net_device *dev, -- cgit v1.2.3 From 17e81bd3d3afe8b1791d96c34e3f2c5b3b7ed1df Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:12 +0200 Subject: staging: rtl8187se: Fixed oops when rmmoding Don't remove procfs entry that is never created Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 6ec3a93803f..8139f266d72 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -323,7 +323,6 @@ void rtl8180_proc_remove_one(struct net_device *dev) remove_proc_entry("stats-tx", priv->dir_dev); remove_proc_entry("stats-rx", priv->dir_dev); remove_proc_entry("registers", priv->dir_dev); - remove_proc_entry(dev->name, rtl8180_proc); priv->dir_dev = NULL; } } -- cgit v1.2.3 From 5faca16ad76e3f3bef2866ccabce8d30c8e47c68 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:13 +0200 Subject: staging: rtl8187se: Removed unused module parameters and fixed module description Removed confusing and unimplemented module parameters and fix NIC name in module description Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 8139f266d72..e7419548521 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -61,28 +61,18 @@ static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = { } }; - static char ifname[IFNAMSIZ] = "wlan%d"; -static int hwseqnum = 0; static int hwwep = 0; -static int channels = 0x3fff; MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl); MODULE_AUTHOR("Andrea Merello "); -MODULE_DESCRIPTION("Linux driver for Realtek RTL8180 / RTL8185 WiFi cards"); - +MODULE_DESCRIPTION("Linux driver for Realtek RTL8187SE WiFi cards"); module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR); -module_param(hwseqnum, int, S_IRUGO|S_IWUSR); module_param(hwwep, int, S_IRUGO|S_IWUSR); -module_param(channels, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(devname, " Net interface name, wlan%d=default"); -MODULE_PARM_DESC(hwseqnum, " Try to use hardware 802.11 header sequence numbers. Zero=default"); MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support. Still broken and not available on all cards"); -MODULE_PARM_DESC(channels, " Channel bitmask for specific locales. NYI"); - static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); -- cgit v1.2.3 From b9ce05eef9b35cc80a55954ed8d7dcd8812b5b08 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:14 +0200 Subject: staging: rtl8187se: Removed dead code Removed some unused functions, arrays and #define in r8180_core.c Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 82 ---------------------------------- 1 file changed, 82 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index e7419548521..be2344df260 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -606,66 +606,6 @@ void fix_rx_fifo(struct net_device *dev) set_nic_rxring(dev); } -unsigned char QUALITY_MAP[] = { - 0x64, 0x64, 0x64, 0x63, 0x63, 0x62, 0x62, 0x61, - 0x61, 0x60, 0x60, 0x5f, 0x5f, 0x5e, 0x5d, 0x5c, - 0x5b, 0x5a, 0x59, 0x57, 0x56, 0x54, 0x52, 0x4f, - 0x4c, 0x49, 0x45, 0x41, 0x3c, 0x37, 0x31, 0x29, - 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, - 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20, - 0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e, - 0x1d, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a, 0x19, 0x19, - 0x18, 0x17, 0x16, 0x15, 0x14, 0x12, 0x11, 0x0f, - 0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x01, 0x00 -}; - -unsigned char STRENGTH_MAP[] = { - 0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e, - 0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50, - 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f, - 0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b, - 0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, - 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, - 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f, - 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b, - 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07, - 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, 0x00 -}; - -void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual) -{ - u32 temp; - u32 temp2; - u32 q; - u32 orig_qual; - u8 _rssi; - - q = *qual; - orig_qual = *qual; - _rssi = 0; /* avoid gcc complains.. */ - - if (q <= 0x4e) { - temp = QUALITY_MAP[q]; - } else { - if (q & 0x80) - temp = 0x32; - else - temp = 1; - } - - *qual = temp; - temp2 = *rssi; - - if (_rssi < 0x64) { - if (_rssi == 0) - *rssi = 1; - } else { - *rssi = 0x64; - } - - return; -} - void rtl8180_irq_disable(struct net_device *dev) { struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); @@ -746,26 +686,6 @@ void set_nic_txring(struct net_device *dev) write_nic_dword(dev, TX_BEACON_RING_ADDR, priv->txbeaconringdma); } -void rtl8180_conttx_enable(struct net_device *dev) -{ - u32 txconf; - - txconf = read_nic_dword(dev, TX_CONF); - txconf = txconf & ~TX_LOOPBACK_MASK; - txconf = txconf | (TX_LOOPBACK_CONTINUE< Date: Tue, 13 Nov 2012 19:28:15 +0200 Subject: staging: rtl8187se: Removed unused parameters of HwHSSIThreeWire() Removed two parameters of HwHSSIThreeWire() that are equal in all function calls, fixed return type, fixed register width and simplified code Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_rtl8225.h | 4 +- drivers/staging/rtl8187se/r8185b_init.c | 127 +++++++----------------------- 2 files changed, 31 insertions(+), 100 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_rtl8225.h b/drivers/staging/rtl8187se/r8180_rtl8225.h index 494ea8619e7..c6f2128e755 100644 --- a/drivers/staging/rtl8187se/r8180_rtl8225.h +++ b/drivers/staging/rtl8187se/r8180_rtl8225.h @@ -23,8 +23,8 @@ void rtl8225z2_rf_init(struct net_device *dev); void rtl8225z2_rf_set_chan(struct net_device *dev, short ch); void rtl8225z2_rf_close(struct net_device *dev); -void RF_WriteReg(struct net_device *dev, u8 offset, u32 data); -u32 RF_ReadReg(struct net_device *dev, u8 offset); +void RF_WriteReg(struct net_device *dev, u8 offset, u16 data); +u16 RF_ReadReg(struct net_device *dev, u8 offset); void rtl8180_set_mode(struct net_device *dev, int mode); void rtl8180_set_mode(struct net_device *dev, int mode); diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index cf9bcd588c1..06a1c0b31dc 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -207,13 +207,10 @@ void SetOutputEnableOfRfPins(struct net_device *dev) write_nic_word(dev, RFPinsEnable, 0x1bff); } -static int HwHSSIThreeWire(struct net_device *dev, - u8 *pDataBuf, - u8 nDataBufBitCnt, - int bSI, - int bWrite) +static bool HwHSSIThreeWire(struct net_device *dev, + u8 *pDataBuf, + bool write) { - int bResult = 1; u8 TryCnt; u8 u1bTmp; @@ -228,77 +225,29 @@ static int HwHSSIThreeWire(struct net_device *dev, if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) { printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:" " %#X RE|WE bits are not clear!!\n", u1bTmp); - dump_stack(); - return 0; + return false; } /* RTL8187S HSSI Read/Write Function */ u1bTmp = read_nic_byte(dev, RF_SW_CONFIG); - - if (bSI) - u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */ - - else - u1bTmp &= ~RF_SW_CFG_SI; /* reg08[1]=0 Parallel Interface(PI) */ - - + u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */ write_nic_byte(dev, RF_SW_CONFIG, u1bTmp); - if (bSI) { - /* jong: HW SI read must set reg84[3]=0. */ - u1bTmp = read_nic_byte(dev, RFPinsSelect); - u1bTmp &= ~BIT3; - write_nic_byte(dev, RFPinsSelect, u1bTmp); - } + /* jong: HW SI read must set reg84[3]=0. */ + u1bTmp = read_nic_byte(dev, RFPinsSelect); + u1bTmp &= ~BIT3; + write_nic_byte(dev, RFPinsSelect, u1bTmp); /* Fill up data buffer for write operation. */ - if (bWrite) { - if (nDataBufBitCnt == 16) { - write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); - } else if (nDataBufBitCnt == 64) { - /* RTL8187S shouldn't enter this case */ - write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf)); - write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4))); - } else { - int idx; - int ByteCnt = nDataBufBitCnt / 8; - /* printk("%d\n",nDataBufBitCnt); */ - if ((nDataBufBitCnt % 8) != 0) { - printk(KERN_ERR "rtl8187se: " - "HwThreeWire(): nDataBufBitCnt(%d)" - " should be multiple of 8!!!\n", - nDataBufBitCnt); - dump_stack(); - nDataBufBitCnt += 8; - nDataBufBitCnt &= ~7; - } - - if (nDataBufBitCnt > 64) { - printk(KERN_ERR "rtl8187se: HwThreeWire():" - " nDataBufBitCnt(%d) should <= 64!!!\n", - nDataBufBitCnt); - dump_stack(); - nDataBufBitCnt = 64; - } - - for (idx = 0; idx < ByteCnt; idx++) - write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx)); - - } - } else { /* read */ - if (bSI) { - /* SI - reg274[3:0] : RF register's Address */ - write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); - } else { - /* PI - reg274[15:12] : RF register's Address */ - write_nic_word(dev, SW_3W_DB0, (*((u16 *)pDataBuf)) << 12); - } - } + /* SI - reg274[3:0] : RF register's Address */ + if (write) + write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); + else + write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); /* Set up command: WE or RE. */ - if (bWrite) + if (write) write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE); - else write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE); @@ -306,7 +255,7 @@ static int HwHSSIThreeWire(struct net_device *dev, /* Check if DONE is set. */ for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { u1bTmp = read_nic_byte(dev, SW_3W_CMD1); - if ((u1bTmp & SW_3W_CMD1_DONE) != 0) + if (u1bTmp & SW_3W_CMD1_DONE) break; udelay(10); @@ -315,45 +264,26 @@ static int HwHSSIThreeWire(struct net_device *dev, write_nic_byte(dev, SW_3W_CMD1, 0); /* Read back data for read operation. */ - if (bWrite == 0) { - if (bSI) { - /* Serial Interface : reg363_362[11:0] */ - *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ) ; - } else { - /* Parallel Interface : reg361_360[11:0] */ - *((u16 *)pDataBuf) = read_nic_word(dev, PI_DATA_READ); - } - + if (!write) { + /* Serial Interface : reg363_362[11:0] */ + *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ); *((u16 *)pDataBuf) &= 0x0FFF; } - return bResult; + return true; } -void RF_WriteReg(struct net_device *dev, u8 offset, u32 data) +void RF_WriteReg(struct net_device *dev, u8 offset, u16 data) { - u32 data2Write; - u8 len; - - /* Pure HW 3-wire. */ - data2Write = (data << 4) | (u32)(offset & 0x0f); - len = 16; - - HwHSSIThreeWire(dev, (u8 *)(&data2Write), len, 1, 1); + u16 reg = (data << 4) | (offset & 0x0f); + HwHSSIThreeWire(dev, (u8 *)®, true); } -u32 RF_ReadReg(struct net_device *dev, u8 offset) +u16 RF_ReadReg(struct net_device *dev, u8 offset) { - u32 data2Write; - u8 wlen; - u32 dataRead; - - data2Write = ((u32)(offset & 0x0f)); - wlen = 16; - HwHSSIThreeWire(dev, (u8 *)(&data2Write), wlen, 1, 0); - dataRead = data2Write; - - return dataRead; + u16 reg = offset & 0x0f; + HwHSSIThreeWire(dev, (u8 *)®, false); + return reg; } @@ -469,7 +399,8 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); u32 i; u32 addr, data; - u32 u4bRegOffset, u4bRegValue, u4bRF23, u4bRF24; + u32 u4bRegOffset, u4bRegValue; + u16 u4bRF23, u4bRF24; u8 u1b24E; int d_cut = 0; -- cgit v1.2.3 From 42af49901a02ee935873c3a1e5b2e161148c6160 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:16 +0200 Subject: staging: rtl8187se: Fixed typo in TransmitConfig Fixed typo in TransmitConfig and removed always false condition Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index be2344df260..642508e598b 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -2581,11 +2581,10 @@ short rtl8180_init(struct net_device *dev) priv->CSMethod = (0x01 << 29); - priv->TransmitConfig = TCR_DurProcMode_OFFSET | + priv->TransmitConfig = (1<ShortRetryLimit<LongRetryLimit<LongRetryLimit<ReceiveConfig = RCR_AMF | RCR_ADF | RCR_ACF | RCR_AB | RCR_AM | RCR_APM | -- cgit v1.2.3 From 2296beb0348d40f40f041259186042e504c35433 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:17 +0200 Subject: staging: rtl8187se: Removed non-existent function headers from r8180.h Cleaned up r8180.h header file by removing headers of functions that don't exist Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h index 2682afbac4f..db7974a6426 100644 --- a/drivers/staging/rtl8187se/r8180.h +++ b/drivers/staging/rtl8187se/r8180.h @@ -667,35 +667,22 @@ void write_nic_dword(struct net_device *dev, int x,u32 y); void force_pci_posting(struct net_device *dev); void rtl8180_rtx_disable(struct net_device *); -void rtl8180_rx_enable(struct net_device *); -void rtl8180_tx_enable(struct net_device *); -void rtl8180_start_scanning(struct net_device *dev); -void rtl8180_start_scanning_s(struct net_device *dev); -void rtl8180_stop_scanning(struct net_device *dev); -void rtl8180_disassociate(struct net_device *dev); -//void fix_rx_fifo(struct net_device *dev); void rtl8180_set_anaparam(struct net_device *dev,u32 a); void rtl8185_set_anaparam2(struct net_device *dev,u32 a); void rtl8180_set_hw_wep(struct net_device *dev); void rtl8180_no_hw_wep(struct net_device *dev); void rtl8180_update_msr(struct net_device *dev); -//void rtl8180_BSS_create(struct net_device *dev); void rtl8180_beacon_tx_disable(struct net_device *dev); void rtl8180_beacon_rx_disable(struct net_device *dev); -void rtl8180_conttx_enable(struct net_device *dev); -void rtl8180_conttx_disable(struct net_device *dev); int rtl8180_down(struct net_device *dev); int rtl8180_up(struct net_device *dev); void rtl8180_commit(struct net_device *dev); void rtl8180_set_chan(struct net_device *dev,short ch); -void rtl8180_set_master_essid(struct net_device *dev,char *essid); -void rtl8180_update_beacon_security(struct net_device *dev); void write_phy(struct net_device *dev, u8 adr, u8 data); void write_phy_cck(struct net_device *dev, u8 adr, u32 data); void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data); void rtl8185_tx_antenna(struct net_device *dev, u8 ant); void rtl8185_rf_pins_enable(struct net_device *dev); -void IBSS_randomize_cell(struct net_device *dev); void IPSEnter(struct net_device *dev); void IPSLeave(struct net_device *dev); int get_curr_tx_free_desc(struct net_device *dev, int priority); -- cgit v1.2.3 From 4dffbc3d28db29ae1e75a9988e61b3718fa5bea6 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:18 +0200 Subject: staging: rtl8187se: Removed unused arrays in r8180_rtl8225z2.c Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_rtl8225z2.c | 33 ----------------------------- 1 file changed, 33 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c index 315eece3b78..eba97867b68 100644 --- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c +++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c @@ -15,7 +15,6 @@ #include "ieee80211/dot11d.h" - static void write_rtl8225(struct net_device *dev, u8 adr, u16 data) { int i; @@ -76,22 +75,6 @@ static void write_rtl8225(struct net_device *dev, u8 adr, u16 data) rtl8185_rf_pins_enable(dev); } -static const u16 rtl8225bcd_rxgain[] = { - 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, - 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, - 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, - 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, - 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, - 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, - 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, - 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, - 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, - 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, - 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3, - 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb - -}; - static const u8 rtl8225_agc[] = { 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, @@ -117,10 +100,6 @@ static const u32 rtl8225_chan[] = { 0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x074A, }; -static const u8 rtl8225z2_threshold[] = { - 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd, -}; - static const u8 rtl8225z2_gain_bg[] = { 0x23, 0x15, 0xa5, /* -82-1dBm */ 0x23, 0x15, 0xb5, /* -82-2dBm */ @@ -157,18 +136,6 @@ static const u16 rtl8225z2_rxgain[] = { }; -static const u8 rtl8225z2_tx_power_ofdm[] = { - 0x42, 0x00, 0x40, 0x00, 0x40 -}; - -static const u8 rtl8225z2_tx_power_cck_ch14[] = { - 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 -}; - -static const u8 rtl8225z2_tx_power_cck[] = { - 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 -}; - void rtl8225z2_set_gain(struct net_device *dev, short gain) { const u8 *rtl8225_gain; -- cgit v1.2.3 From dfd6aefb89d1e78765fb54da1ee9cb2bff5e4b50 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:19 +0200 Subject: staging: rtl8187se: Use ARRAY_SIZE instead of in-code constants Use ARRAY_SIZE macro instead of hardcoding array size into loop condition and remove unused last item of rtl8225z2_rxgain[] Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_rtl8225z2.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c index eba97867b68..c592f7936dd 100644 --- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c +++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c @@ -132,7 +132,7 @@ static const u16 rtl8225z2_rxgain[] = { 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, - 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb }; @@ -431,8 +431,8 @@ void rtl8225z2_rf_init(struct net_device *dev) struct r8180_priv *priv = ieee80211_priv(dev); int i; short channel = 1; - u16 brsr; - u32 data, addr; + u16 brsr; + u32 data; priv->chan = channel; @@ -473,8 +473,8 @@ void rtl8225z2_rf_init(struct net_device *dev) write_rtl8225(dev, 0x0, 0x1b7); - for (i = 0; i < 95; i++) { - write_rtl8225(dev, 0x1, (u8)(i + 1)); + for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { + write_rtl8225(dev, 0x1, i + 1); write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]); } @@ -504,14 +504,12 @@ void rtl8225z2_rf_init(struct net_device *dev) write_rtl8225(dev, 0x0, 0x2bf); - for (i = 0; i < 128; i++) { - data = rtl8225_agc[i]; - - addr = i + 0x80; /* enable writing AGC table */ - write_phy_ofdm(dev, 0xb, data); + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { + write_phy_ofdm(dev, 0xb, rtl8225_agc[i]); mdelay(1); - write_phy_ofdm(dev, 0xa, addr); + /* enable writing AGC table */ + write_phy_ofdm(dev, 0xa, i + 0x80); mdelay(1); } -- cgit v1.2.3 From 3044e4576223a08e8e27cb68129ebf79653fde7d Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:20 +0200 Subject: staging: rtl8187se: Removed unneeded reads from EEPROM Removed unneeded reads from EEPROM and some unnecessary conditions Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180.h | 4 ---- drivers/staging/rtl8187se/r8180_core.c | 36 +++++++++------------------------- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h index db7974a6426..a819b01fcd8 100644 --- a/drivers/staging/rtl8187se/r8180.h +++ b/drivers/staging/rtl8187se/r8180.h @@ -365,8 +365,6 @@ typedef struct r8180_priv short digphy; short antb; short diversity; - u8 cs_treshold; - short rcr_csense; u32 key0[4]; short (*rf_set_sens)(struct net_device *dev,short sens); void (*rf_set_chan)(struct net_device *dev,short ch); @@ -623,8 +621,6 @@ typedef struct r8180_priv u8 PowerProfile; u32 CSMethod; - u8 cck_txpwr_base; - u8 ofdm_txpwr_base; u8 dma_poll_stop_mask; //u8 RegThreeWireMode; diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 642508e598b..e55b93c44f4 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -2376,8 +2376,7 @@ short rtl8180_init(struct net_device *dev) { struct r8180_priv *priv = ieee80211_priv(dev); u16 word; - u16 version; - u32 usValue; + u16 usValue; u16 tmpu16; int i, j; struct eeprom_93cx6 eeprom; @@ -2614,36 +2613,31 @@ short rtl8180_init(struct net_device *dev) /* just for sync 85 */ priv->enable_gpio0 = 0; - eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &eeprom_val); - usValue = eeprom_val; - DMESG("usValue is 0x%x\n", usValue); + eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &usValue); + DMESG("usValue is %#hx\n", usValue); /* 3Read AntennaDiversity */ /* SW Antenna Diversity. */ - if ((usValue & EEPROM_SW_AD_MASK) != EEPROM_SW_AD_ENABLE) - priv->EEPROMSwAntennaDiversity = false; - else - priv->EEPROMSwAntennaDiversity = true; + priv->EEPROMSwAntennaDiversity = (usValue & EEPROM_SW_AD_MASK) == + EEPROM_SW_AD_ENABLE; /* Default Antenna to use. */ - if ((usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1) - priv->EEPROMDefaultAntenna1 = false; - else - priv->EEPROMDefaultAntenna1 = true; + priv->EEPROMDefaultAntenna1 = (usValue & EEPROM_DEF_ANT_MASK) == + EEPROM_DEF_ANT_1; if (priv->RegSwAntennaDiversityMechanism == 0) /* Auto */ /* 0: default from EEPROM. */ priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity; else /* 1:disable antenna diversity, 2: enable antenna diversity. */ - priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1) ? false : true); + priv->bSwAntennaDiverity = priv->RegSwAntennaDiversityMechanism == 2; if (priv->RegDefaultAntenna == 0) /* 0: default from EEPROM. */ priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1; else /* 1: main, 2: aux. */ - priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna == 2) ? true : false); + priv->bDefaultAntenna1 = priv->RegDefaultAntenna == 2; /* rtl8185 can calc plcp len in HW. */ priv->hw_plcp_len = 1; @@ -2683,18 +2677,6 @@ short rtl8180_init(struct net_device *dev) if ((tmpu16 & EEPROM_THERMAL_METER_ENABLE) >> 13) priv->bTxPowerTrack = true; - eeprom_93cx6_read(&eeprom, EPROM_TXPW_BASE, &word); - priv->cck_txpwr_base = word & 0xf; - priv->ofdm_txpwr_base = (word>>4) & 0xf; - - eeprom_93cx6_read(&eeprom, EPROM_VERSION, &version); - DMESG("EEPROM version %x", version); - priv->rcr_csense = 3; - - eeprom_93cx6_read(&eeprom, ENERGY_TRESHOLD, &eeprom_val); - priv->cs_treshold = (eeprom_val & 0xff00) >> 8; - - eeprom_93cx6_read(&eeprom, RFCHIPID, &eeprom_val); priv->rf_sleep = rtl8225z4_rf_sleep; priv->rf_wakeup = rtl8225z4_rf_wakeup; DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!"); -- cgit v1.2.3 From 861437d2be466c107a7438bb7eede42c988e9137 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:21 +0200 Subject: staging: rtl8187se: Removed unused fields in r8180_priv Removed unused fields in r8180_priv and dead code that appeared after field removal Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180.h | 10 ------- drivers/staging/rtl8187se/r8180_core.c | 49 ++------------------------------- drivers/staging/rtl8187se/r8185b_init.c | 6 ++-- 3 files changed, 5 insertions(+), 60 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h index a819b01fcd8..1db8257a2d5 100644 --- a/drivers/staging/rtl8187se/r8180.h +++ b/drivers/staging/rtl8187se/r8180.h @@ -327,12 +327,8 @@ typedef struct r8180_priv int irq; struct ieee80211_device *ieee80211; - short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */ - short enable_gpio0; - short hw_plcp_len; short plcp_preamble_mode; // 0:auto 1:short 2:long - spinlock_t irq_lock; spinlock_t irq_th_lock; spinlock_t tx_lock; spinlock_t ps_lock; @@ -350,7 +346,6 @@ typedef struct r8180_priv u8 channel_plan; // it's the channel plan index short up; short crcmon; //if 1 allow bad crc frame reception in monitor mode - short prism_hdr; struct timer_list scan_timer; /*short scanpending; @@ -359,7 +354,6 @@ typedef struct r8180_priv u8 active_probe; //u8 active_scan_num; struct semaphore wx_sem; - struct semaphore rf_state; short hw_wep; short digphy; @@ -489,7 +483,6 @@ typedef struct r8180_priv RT_RF_POWER_STATE eRFPowerState; u32 RfOffReason; bool RFChangeInProgress; - bool bInHctTest; bool SetRFPowerStateInProgress; u8 RFProgType; bool bLeisurePs; @@ -616,15 +609,12 @@ typedef struct r8180_priv // struct workqueue_struct *workqueue; struct work_struct reset_wq; struct work_struct watch_dog_wq; - struct work_struct tx_irq_wq; short ack_tx_to_ieee; u8 PowerProfile; - u32 CSMethod; u8 dma_poll_stop_mask; //u8 RegThreeWireMode; - u8 MWIEnable; u16 ShortRetryLimit; u16 LongRetryLimit; u16 EarlyRxThreshold; diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index e55b93c44f4..744ac8dcbd7 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -1437,14 +1437,9 @@ void rtl8180_rx(struct net_device *dev) dev_kfree_skb_any(priv->rx_skb); priv->stats.rxnolast++; } - /* support for prism header has been originally added by Christian */ - if (priv->prism_hdr && priv->ieee80211->iw_mode == IW_MODE_MONITOR) { - - } else { - priv->rx_skb = dev_alloc_skb(len+2); - if (!priv->rx_skb) - goto drop; - } + priv->rx_skb = dev_alloc_skb(len+2); + if (!priv->rx_skb) + goto drop; priv->rx_skb_complete = 0; priv->rx_skb->dev = dev; @@ -1717,8 +1712,6 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, int remain; int buflen; int count; - u16 duration; - short ext; struct buffer *buflist; struct ieee80211_hdr_3addr *frag_hdr = (struct ieee80211_hdr_3addr *)txbuf; u8 dest[ETH_ALEN]; @@ -1914,15 +1907,6 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority, *tail = *tail | ((rate&0xf) << 24); - /* hw_plcp_len is not used for rtl8180 chip */ - /* FIXME */ - if (!priv->hw_plcp_len) { - duration = rtl8180_len2duration(len, rate, &ext); - *(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16); - if (ext) - *(tail+1) = *(tail+1) | (1<<31); /* plcp length extension */ - } - if (morefrag) *tail = (*tail) | (1<<17); /* more fragment */ if (!remain) @@ -2219,7 +2203,6 @@ void rtl8180_wmm_param_update(struct work_struct *work) } } -void rtl8180_tx_irq_wq(struct work_struct *work); void rtl8180_restart_wq(struct work_struct *work); /* void rtl8180_rq_tx_ack(struct work_struct *work); */ void rtl8180_watch_dog_wq(struct work_struct *work); @@ -2408,7 +2391,6 @@ short rtl8180_init(struct net_device *dev) priv->RFChangeInProgress = false; priv->SetRFPowerStateInProgress = false; priv->RFProgType = 0; - priv->bInHctTest = false; priv->irq_enabled = 0; @@ -2432,14 +2414,12 @@ short rtl8180_init(struct net_device *dev) priv->ieee80211->ps_is_queue_empty = rtl8180_is_tx_queue_empty; priv->hw_wep = hwwep; - priv->prism_hdr = 0; priv->dev = dev; priv->retry_rts = DEFAULT_RETRY_RTS; priv->retry_data = DEFAULT_RETRY_DATA; priv->RFChangeInProgress = false; priv->SetRFPowerStateInProgress = false; priv->RFProgType = 0; - priv->bInHctTest = false; priv->bInactivePs = true; /* false; */ priv->ieee80211->bInactivePs = priv->bInactivePs; priv->bSwRfProcessing = false; @@ -2522,15 +2502,12 @@ short rtl8180_init(struct net_device *dev) priv->RegBModeGainStage = 1; priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; - spin_lock_init(&priv->irq_lock); spin_lock_init(&priv->irq_th_lock); spin_lock_init(&priv->tx_lock); spin_lock_init(&priv->ps_lock); spin_lock_init(&priv->rf_ps_lock); sema_init(&priv->wx_sem, 1); - sema_init(&priv->rf_state, 1); INIT_WORK(&priv->reset_wq, (void *)rtl8180_restart_wq); - INIT_WORK(&priv->tx_irq_wq, (void *)rtl8180_tx_irq_wq); INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq, (void *)rtl8180_hw_wakeup_wq); INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq, @@ -2572,14 +2549,10 @@ short rtl8180_init(struct net_device *dev) priv->ieee80211->stop_send_beacons = rtl8180_beacon_tx_disable; priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; - priv->MWIEnable = 0; - priv->ShortRetryLimit = 7; priv->LongRetryLimit = 7; priv->EarlyRxThreshold = 7; - priv->CSMethod = (0x01 << 29); - priv->TransmitConfig = (1<ShortRetryLimit<InitialGain = 6; DMESG("MAC controller is a RTL8187SE b/g"); - priv->phy_ver = 2; priv->ieee80211->modulation |= IEEE80211_OFDM_MODULATION; priv->ieee80211->short_slot = 1; - /* just for sync 85 */ - priv->enable_gpio0 = 0; - eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &usValue); DMESG("usValue is %#hx\n", usValue); /* 3Read AntennaDiversity */ @@ -2639,9 +2608,6 @@ short rtl8180_init(struct net_device *dev) /* 1: main, 2: aux. */ priv->bDefaultAntenna1 = priv->RegDefaultAntenna == 2; - /* rtl8185 can calc plcp len in HW. */ - priv->hw_plcp_len = 1; - priv->plcp_preamble_mode = 2; /* the eeprom type is stored in RCR register bit #6 */ if (RCR_9356SEL & read_nic_dword(dev, RCR)) @@ -3594,15 +3560,6 @@ void rtl8180_tx_isr(struct net_device *dev, int pri, short error) spin_unlock_irqrestore(&priv->tx_lock, flag); } -void rtl8180_tx_irq_wq(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device * ieee = (struct ieee80211_device *) - container_of(dwork, struct ieee80211_device, watch_dog_wq); - struct net_device *dev = ieee->dev; - - rtl8180_tx_isr(dev, MANAGE_PRIORITY, 0); -} irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) netdev; diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 06a1c0b31dc..5c454fa861c 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -1231,11 +1231,9 @@ bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u priv->RfOffReason = 0; bActionAllowed = true; - if (rtState == eRfOff && ChangeSource >= RF_CHANGE_BY_HW && !priv->bInHctTest) + if (rtState == eRfOff && ChangeSource >= RF_CHANGE_BY_HW) bConnectBySSID = true; - - } else - ; + } break; case eRfOff: -- cgit v1.2.3 From 53094af120e326cd7e092e7d0e479181ca82ad13 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:23 +0200 Subject: staging: rtl8187se: Removed empty stub read_acadapter_file() Removed empty read_acadapter_file() and priv->PowerProfile that never changes its value Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180.h | 1 - drivers/staging/rtl8187se/r8180_core.c | 18 +----------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h index 1db8257a2d5..70ea4145b4c 100644 --- a/drivers/staging/rtl8187se/r8180.h +++ b/drivers/staging/rtl8187se/r8180.h @@ -611,7 +611,6 @@ typedef struct r8180_priv struct work_struct watch_dog_wq; short ack_tx_to_ieee; - u8 PowerProfile; u8 dma_poll_stop_mask; //u8 RegThreeWireMode; diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 744ac8dcbd7..73a6994746f 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -2480,7 +2480,6 @@ short rtl8180_init(struct net_device *dev) priv->NumTxOkTotal = 0; priv->NumTxUnicast = 0; priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL; - priv->PowerProfile = POWER_PROFILE_AC; priv->CurrRetryCnt = 0; priv->LastRetryCnt = 0; priv->LastTxokCnt = 0; @@ -2927,8 +2926,6 @@ static void MgntLinkKeepAlive(struct r8180_priv *priv) } } -static u8 read_acadapter_file(char *filename); - void rtl8180_watch_dog(struct net_device *dev) { struct r8180_priv *priv = ieee80211_priv(dev); @@ -2961,12 +2958,7 @@ void rtl8180_watch_dog(struct net_device *dev) MgntLinkKeepAlive(priv); /* YJ,add,080828,for LPS */ - if (priv->PowerProfile == POWER_PROFILE_BATTERY) - priv->bLeisurePs = true; - else if (priv->PowerProfile == POWER_PROFILE_AC) { - LeisurePSLeave(priv); - priv->bLeisurePs = false; - } + LeisurePSLeave(priv); if (priv->ieee80211->state == IEEE80211_LINKED) { priv->link_detect.NumRxOkInPeriod = priv->ieee80211->NumRxDataInPeriod; @@ -3735,9 +3727,6 @@ void GPIOChangeRFWorkItemCallBack(struct work_struct *work) static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL}; static int readf_count = 0; - if (readf_count % 10 == 0) - priv->PowerProfile = read_acadapter_file("/proc/acpi/ac_adapter/AC0/state"); - readf_count = (readf_count+1)%0xffff; /* We should turn off LED before polling FF51[4]. */ @@ -3782,10 +3771,5 @@ void GPIOChangeRFWorkItemCallBack(struct work_struct *work) } } -static u8 read_acadapter_file(char *filename) -{ - return 0; -} - module_init(rtl8180_pci_module_init); module_exit(rtl8180_pci_module_exit); -- cgit v1.2.3 From fbce428a077f52e33714dabc639a79cfd4ec6af3 Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Tue, 13 Nov 2012 19:28:22 +0200 Subject: staging: rtl8187se: Fixed size of BEACON_INTERVAL register BEACON_INTERVAL register is 16-bit, not 32-bit Signed-off-by: Maxim Mikityanskiy Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 73a6994746f..ea04eec3095 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -1984,10 +1984,10 @@ void rtl8180_link_change(struct net_device *dev) write_nic_dword(dev, BSSID, ((u32 *)net->bssid)[0]); write_nic_word(dev, BSSID+4, ((u16 *)net->bssid)[2]); - beacon_interval = read_nic_dword(dev, BEACON_INTERVAL); + beacon_interval = read_nic_word(dev, BEACON_INTERVAL); beacon_interval &= ~BEACON_INTERVAL_MASK; beacon_interval |= net->beacon_interval; - write_nic_dword(dev, BEACON_INTERVAL, beacon_interval); + write_nic_word(dev, BEACON_INTERVAL, beacon_interval); rtl8180_set_mode(dev, EPROM_CMD_NORMAL); -- cgit v1.2.3 From 87c629853e9b901f9756a628aa088d8d6a1ebf00 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 4 Nov 2012 16:18:56 +0000 Subject: staging: vt6656: no need to bIndicateReceive when no bytes to read. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/usbpipe.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index b5259db6e36..fc68518526e 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -575,7 +575,8 @@ s_nsBulkInUsbIoCompleteRead( // MP_SET_FLAG(pDevice, fMP_DISCONNECTED); // } } else { - bIndicateReceive = TRUE; + if (bytesRead) + bIndicateReceive = TRUE; pDevice->ulBulkInContCRCError = 0; pDevice->ulBulkInBytesRead += bytesRead; -- cgit v1.2.3 From 28044e0193f2d642a4981dd296b2583b30cf36ef Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 4 Nov 2012 17:20:06 +0000 Subject: staging: vt6656: free skbuff and relocate on bReAllocSkb == FALSE. bReAllocSkb == FALSE is when data is not fed to user land. Free and relocate skbuff. Where data is not sent return = FALSE from RXbBulkInProcessData. This appears to reduce false errors when a reused skbuff has old data. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/dpc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 28edf9e7efc..5ad7abb869a 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -617,7 +617,7 @@ RXbBulkInProcessData ( //Discard beacon packet which channel is 0 if ( (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_BEACON) || (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) == WLAN_FSTYPE_PROBERESP) ) { - return TRUE; + return FALSE; } } pRxPacket->byRxChannel = (*pbyRxSts) >> 2; @@ -912,7 +912,7 @@ RXbBulkInProcessData ( pDevice->skb->protocol = htons(ETH_P_802_2); memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb)); netif_rx(pDevice->skb); - pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); + return TRUE; } return FALSE; @@ -1534,6 +1534,11 @@ RXvFreeRCB( ASSERT(!pRCB->Ref); // should be 0 ASSERT(pRCB->pDevice); // shouldn't be NULL + if (bReAllocSkb == FALSE) { + kfree_skb(pRCB->skb); + bReAllocSkb = TRUE; + } + if (bReAllocSkb == TRUE) { pRCB->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); // todo error handling -- cgit v1.2.3 From 95e40c7a169b41796b6998b28b8cadb075359968 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 4 Nov 2012 17:39:02 +0000 Subject: staging: vt6656: dead code remove upc.h Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/mib.c | 1 - drivers/staging/vt6656/upc.h | 162 ------------------------------------------- 2 files changed, 163 deletions(-) delete mode 100644 drivers/staging/vt6656/upc.h diff --git a/drivers/staging/vt6656/mib.c b/drivers/staging/vt6656/mib.c index 8a6ee72f440..d4c7b0cc7ec 100644 --- a/drivers/staging/vt6656/mib.c +++ b/drivers/staging/vt6656/mib.c @@ -37,7 +37,6 @@ * */ -#include "upc.h" #include "mac.h" #include "tether.h" #include "mib.h" diff --git a/drivers/staging/vt6656/upc.h b/drivers/staging/vt6656/upc.h deleted file mode 100644 index b33aba4b12c..00000000000 --- a/drivers/staging/vt6656/upc.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. - * All rights reserved. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * File: upc.h - * - * Purpose: Macros to access device - * - * Author: Tevin Chen - * - * Date: Mar 17, 1997 - * - */ - -#ifndef __UPC_H__ -#define __UPC_H__ - -#include "device.h" -#include "ttype.h" - -/*--------------------- Export Definitions -------------------------*/ - - -// -// For IO mapped -// - -#ifdef IO_MAP - -#define VNSvInPortB(dwIOAddress, pbyData) { \ - *(pbyData) = inb(dwIOAddress); \ -} - - -#define VNSvInPortW(dwIOAddress, pwData) { \ - *(pwData) = inw(dwIOAddress); \ -} - -#define VNSvInPortD(dwIOAddress, pdwData) { \ - *(pdwData) = inl(dwIOAddress); \ -} - - -#define VNSvOutPortB(dwIOAddress, byData) { \ - outb(byData, dwIOAddress); \ -} - - -#define VNSvOutPortW(dwIOAddress, wData) { \ - outw(wData, dwIOAddress); \ -} - -#define VNSvOutPortD(dwIOAddress, dwData) { \ - outl(dwData, dwIOAddress); \ -} - -#else - -// -// For memory mapped IO -// - - -#define VNSvInPortB(dwIOAddress, pbyData) { \ - volatile BYTE* pbyAddr = ((PBYTE)(dwIOAddress)); \ - *(pbyData) = readb(pbyAddr); \ -} - - -#define VNSvInPortW(dwIOAddress, pwData) { \ - volatile WORD* pwAddr = ((PWORD)(dwIOAddress)); \ - *(pwData) = readw(pwAddr); \ -} - -#define VNSvInPortD(dwIOAddress, pdwData) { \ - volatile DWORD* pdwAddr = ((PDWORD)(dwIOAddress)); \ - *(pdwData) = readl(pdwAddr); \ -} - - -#define VNSvOutPortB(dwIOAddress, byData) { \ - volatile BYTE* pbyAddr = ((PBYTE)(dwIOAddress)); \ - writeb((BYTE)byData, pbyAddr); \ -} - - -#define VNSvOutPortW(dwIOAddress, wData) { \ - volatile WORD* pwAddr = ((PWORD)(dwIOAddress)); \ - writew((WORD)wData, pwAddr); \ -} - -#define VNSvOutPortD(dwIOAddress, dwData) { \ - volatile DWORD* pdwAddr = ((PDWORD)(dwIOAddress)); \ - writel((DWORD)dwData, pdwAddr); \ -} - -#endif - - -// -// ALWAYS IO-Mapped IO when in 16-bit/32-bit environment -// -#define PCBvInPortB(dwIOAddress, pbyData) { \ - *(pbyData) = inb(dwIOAddress); \ -} - -#define PCBvInPortW(dwIOAddress, pwData) { \ - *(pwData) = inw(dwIOAddress); \ -} - -#define PCBvInPortD(dwIOAddress, pdwData) { \ - *(pdwData) = inl(dwIOAddress); \ -} - -#define PCBvOutPortB(dwIOAddress, byData) { \ - outb(byData, dwIOAddress); \ -} - -#define PCBvOutPortW(dwIOAddress, wData) { \ - outw(wData, dwIOAddress); \ -} - -#define PCBvOutPortD(dwIOAddress, dwData) { \ - outl(dwData, dwIOAddress); \ -} - - -#define PCAvDelayByIO(uDelayUnit) { \ - BYTE byData; \ - unsigned long ii; \ - \ - if (uDelayUnit <= 50) { \ - udelay(uDelayUnit); \ - } \ - else { \ - for (ii = 0; ii < (uDelayUnit); ii++) \ - byData = inb(0x61); \ - } \ -} - - -/*--------------------- Export Classes ----------------------------*/ - -/*--------------------- Export Variables --------------------------*/ - -/*--------------------- Export Functions --------------------------*/ - -#endif /* __UPC_H__ */ -- cgit v1.2.3 From bebbb29c96a9fcc78a1644cbbb3db688488dc129 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 4 Nov 2012 17:59:05 +0000 Subject: staging: vt6656: dead code byCntMeasure/TKIPCounterMeasuresInvoked remove TKIPCounterMeasuresInvoked and byCntMeasure Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/device.h | 1 - drivers/staging/vt6656/mib.h | 1 - drivers/staging/vt6656/rxtx.c | 5 ----- 3 files changed, 7 deletions(-) diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index 8d9b9c1a2d5..f334e64ca19 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -733,7 +733,6 @@ typedef struct __device_info { BYTE byKeyIndex; BOOL bAES; - BYTE byCntMeasure; unsigned int uKeyLength; BYTE abyKey[WLAN_WEP232_KEYLEN]; diff --git a/drivers/staging/vt6656/mib.h b/drivers/staging/vt6656/mib.h index 82d69a9cc20..85c28e92366 100644 --- a/drivers/staging/vt6656/mib.h +++ b/drivers/staging/vt6656/mib.h @@ -68,7 +68,6 @@ typedef struct tagSDot11Counters { unsigned long long TKIPLocalMICFailures; unsigned long long TKIPRemoteMICFailures; unsigned long long TKIPICVErrors; - unsigned long long TKIPCounterMeasuresInvoked; unsigned long long TKIPReplays; unsigned long long CCMPFormatErrors; unsigned long long CCMPReplays; diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index a54c0c1de2e..3a4933ecb63 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -3033,11 +3033,6 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) } } - if (pDevice->byCntMeasure == 2) { - bNeedDeAuth = TRUE; - pDevice->s802_11Counter.TKIPCounterMeasuresInvoked++; - } - if (pDevice->bEnableHostWEP) { if ((uNodeIndex != 0) && (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) { -- cgit v1.2.3 From d77fb7f7567ef94112ee8aed3960fab0092cd534 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 4 Nov 2012 22:41:33 +0000 Subject: staging: vt6656: nsDMA_tx_packet: free tx context bBoolInUse This reduces the number of free TX urbs when key is not found. Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/rxtx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 3a4933ecb63..0f35a9ae3fc 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -3045,6 +3045,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) if (pTransmitKey == NULL) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"return no tx key\n"); + pContext->bBoolInUse = FALSE; dev_kfree_skb_irq(skb); pStats->tx_dropped++; return STATUS_FAILURE; -- cgit v1.2.3 From 04212268286249b65e589c4d3bbf3760c2ac504d Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 14:23:31 +0000 Subject: staging: vt6656: fix viawget_wpa_param size Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 8f198749ca5..e58049b8a27 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -1488,17 +1488,15 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, size_t seq_len = 0; size_t key_len = 0; u8 *buf; - size_t blen; u8 key_array[64]; int ret = 0; - PRINT_K("SIOCSIWENCODEEXT...... \n"); + PRINT_K("SIOCSIWENCODEEXT......\n"); - blen = sizeof(*param); - buf = kmalloc((int)blen, (int)GFP_KERNEL); + buf = kzalloc(sizeof(struct viawget_wpa_param), GFP_KERNEL); if (buf == NULL) return -ENOMEM; - memset(buf, 0, blen); + param = (struct viawget_wpa_param *)buf; // recover alg_name @@ -1592,7 +1590,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_request_info *info, spin_unlock_irq(&pDevice->lock); error: - kfree(param); + kfree(buf); return ret; } -- cgit v1.2.3 From 8cbd9cc6254065c97c4bac42daa55ba1abe73a8e Mon Sep 17 00:00:00 2001 From: David Sharp Date: Tue, 13 Nov 2012 12:18:21 -0800 Subject: tracing,x86: Add a TSC trace_clock In order to promote interoperability between userspace tracers and ftrace, add a trace_clock that reports raw TSC values which will then be recorded in the ring buffer. Userspace tracers that also record TSCs are then on exactly the same time base as the kernel and events can be unambiguously interlaced. Tested: Enabled a tracepoint and the "tsc" trace_clock and saw very large timestamp values. v2: Move arch-specific bits out of generic code. v3: Rename "x86-tsc", cleanups v7: Generic arch bits in Kbuild. Google-Bug-Id: 6980623 Link: http://lkml.kernel.org/r/1352837903-32191-1-git-send-email-dhsharp@google.com Acked-by: Ingo Molnar Cc: Masami Hiramatsu Cc: Ingo Molnar Cc: Thomas Gleixner Cc: "H. Peter Anvin" Signed-off-by: David Sharp Signed-off-by: Steven Rostedt --- arch/alpha/include/asm/Kbuild | 1 + arch/arm/include/asm/Kbuild | 1 + arch/arm64/include/asm/Kbuild | 1 + arch/avr32/include/asm/Kbuild | 1 + arch/blackfin/include/asm/Kbuild | 1 + arch/c6x/include/asm/Kbuild | 1 + arch/cris/include/asm/Kbuild | 1 + arch/frv/include/asm/Kbuild | 1 + arch/h8300/include/asm/Kbuild | 1 + arch/hexagon/include/asm/Kbuild | 1 + arch/ia64/include/asm/Kbuild | 1 + arch/m32r/include/asm/Kbuild | 1 + arch/m68k/include/asm/Kbuild | 1 + arch/microblaze/include/asm/Kbuild | 1 + arch/mips/include/asm/Kbuild | 1 + arch/mn10300/include/asm/Kbuild | 1 + arch/openrisc/include/asm/Kbuild | 1 + arch/parisc/include/asm/Kbuild | 1 + arch/powerpc/include/asm/Kbuild | 1 + arch/s390/include/asm/Kbuild | 1 + arch/score/include/asm/Kbuild | 1 + arch/sh/include/asm/Kbuild | 1 + arch/sparc/include/asm/Kbuild | 1 + arch/tile/include/asm/Kbuild | 1 + arch/um/include/asm/Kbuild | 1 + arch/unicore32/include/asm/Kbuild | 1 + arch/x86/include/asm/trace_clock.h | 20 ++++++++++++++++++++ arch/x86/kernel/Makefile | 1 + arch/x86/kernel/trace_clock.c | 21 +++++++++++++++++++++ arch/xtensa/include/asm/Kbuild | 1 + include/asm-generic/trace_clock.h | 16 ++++++++++++++++ include/linux/trace_clock.h | 2 ++ kernel/trace/trace.c | 1 + 33 files changed, 88 insertions(+) create mode 100644 arch/x86/include/asm/trace_clock.h create mode 100644 arch/x86/kernel/trace_clock.c create mode 100644 include/asm-generic/trace_clock.h diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index 64ffc9e9e54..dcfabb9f05a 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild @@ -11,3 +11,4 @@ header-y += reg.h header-y += regdef.h header-y += sysinfo.h generic-y += exec.h +generic-y += trace_clock.h diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index f70ae175a3d..514e398f1a0 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -31,5 +31,6 @@ generic-y += sockios.h generic-y += termbits.h generic-y += termios.h generic-y += timex.h +generic-y += trace_clock.h generic-y += types.h generic-y += unaligned.h diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index a581a220593..6e9ca462127 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -43,6 +43,7 @@ generic-y += swab.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += unaligned.h generic-y += user.h diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild index 4807ded352c..4dd4f78d3dc 100644 --- a/arch/avr32/include/asm/Kbuild +++ b/arch/avr32/include/asm/Kbuild @@ -1,3 +1,4 @@ generic-y += clkdev.h generic-y += exec.h +generic-y += trace_clock.h diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild index 5a0625aad6a..27d70759474 100644 --- a/arch/blackfin/include/asm/Kbuild +++ b/arch/blackfin/include/asm/Kbuild @@ -38,6 +38,7 @@ generic-y += statfs.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += ucontext.h generic-y += unaligned.h diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild index 112a496d835..eae7b5963e8 100644 --- a/arch/c6x/include/asm/Kbuild +++ b/arch/c6x/include/asm/Kbuild @@ -49,6 +49,7 @@ generic-y += termbits.h generic-y += termios.h generic-y += tlbflush.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += ucontext.h generic-y += user.h diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild index 6d43a951b5e..15a122c3767 100644 --- a/arch/cris/include/asm/Kbuild +++ b/arch/cris/include/asm/Kbuild @@ -11,3 +11,4 @@ header-y += sync_serial.h generic-y += clkdev.h generic-y += exec.h generic-y += module.h +generic-y += trace_clock.h diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild index 4a159da2363..c5d76702830 100644 --- a/arch/frv/include/asm/Kbuild +++ b/arch/frv/include/asm/Kbuild @@ -1,3 +1,4 @@ generic-y += clkdev.h generic-y += exec.h +generic-y += trace_clock.h diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild index 50bbf387b2f..4bc8ae73e08 100644 --- a/arch/h8300/include/asm/Kbuild +++ b/arch/h8300/include/asm/Kbuild @@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm generic-y += clkdev.h generic-y += exec.h generic-y += module.h +generic-y += trace_clock.h diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild index 3bfa9b30f44..bdb54ceb53b 100644 --- a/arch/hexagon/include/asm/Kbuild +++ b/arch/hexagon/include/asm/Kbuild @@ -48,6 +48,7 @@ generic-y += stat.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += ucontext.h generic-y += unaligned.h diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild index dd02f09b6ed..05b03ecd793 100644 --- a/arch/ia64/include/asm/Kbuild +++ b/arch/ia64/include/asm/Kbuild @@ -2,3 +2,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += kvm_para.h +generic-y += trace_clock.h diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild index 50bbf387b2f..4bc8ae73e08 100644 --- a/arch/m32r/include/asm/Kbuild +++ b/arch/m32r/include/asm/Kbuild @@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm generic-y += clkdev.h generic-y += exec.h generic-y += module.h +generic-y += trace_clock.h diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index 88fa3ac86fa..7f1949c0e08 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild @@ -24,6 +24,7 @@ generic-y += sections.h generic-y += siginfo.h generic-y += statfs.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += word-at-a-time.h generic-y += xor.h diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild index 8653072d7e9..2957fcc7176 100644 --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild @@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm header-y += elf.h generic-y += clkdev.h generic-y += exec.h +generic-y += trace_clock.h diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index 533053d12ce..9b54b7a403d 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild @@ -1 +1,2 @@ # MIPS headers +generic-y += trace_clock.h diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild index 4a159da2363..c5d76702830 100644 --- a/arch/mn10300/include/asm/Kbuild +++ b/arch/mn10300/include/asm/Kbuild @@ -1,3 +1,4 @@ generic-y += clkdev.h generic-y += exec.h +generic-y += trace_clock.h diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild index 78de6805268..8971026e1c6 100644 --- a/arch/openrisc/include/asm/Kbuild +++ b/arch/openrisc/include/asm/Kbuild @@ -60,6 +60,7 @@ generic-y += swab.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += ucontext.h generic-y += user.h diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild index bac8debecff..ff4c9faed54 100644 --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild @@ -3,3 +3,4 @@ generic-y += word-at-a-time.h auxvec.h user.h cputime.h emergency-restart.h \ segment.h topology.h vga.h device.h percpu.h hw_irq.h mutex.h \ div64.h irq_regs.h kdebug.h kvm_para.h local64.h local.h param.h \ poll.h xor.h clkdev.h exec.h +generic-y += trace_clock.h diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild index a4fe15e33c6..2d62b484b3f 100644 --- a/arch/powerpc/include/asm/Kbuild +++ b/arch/powerpc/include/asm/Kbuild @@ -2,3 +2,4 @@ generic-y += clkdev.h generic-y += rwsem.h +generic-y += trace_clock.h diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild index 0633dc6d254..f313f9cbcf4 100644 --- a/arch/s390/include/asm/Kbuild +++ b/arch/s390/include/asm/Kbuild @@ -1,3 +1,4 @@ generic-y += clkdev.h +generic-y += trace_clock.h diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild index ec697aeefd0..16e41fe1a41 100644 --- a/arch/score/include/asm/Kbuild +++ b/arch/score/include/asm/Kbuild @@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm header-y += generic-y += clkdev.h +generic-y += trace_clock.h diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild index 29f83beeef7..280bea9e5e2 100644 --- a/arch/sh/include/asm/Kbuild +++ b/arch/sh/include/asm/Kbuild @@ -31,5 +31,6 @@ generic-y += socket.h generic-y += statfs.h generic-y += termbits.h generic-y += termios.h +generic-y += trace_clock.h generic-y += ucontext.h generic-y += xor.h diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index 645a58da0e8..e26d430ce2f 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild @@ -8,4 +8,5 @@ generic-y += local64.h generic-y += irq_regs.h generic-y += local.h generic-y += module.h +generic-y += trace_clock.h generic-y += word-at-a-time.h diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild index 6948015e08a..b17b9b8e53c 100644 --- a/arch/tile/include/asm/Kbuild +++ b/arch/tile/include/asm/Kbuild @@ -34,5 +34,6 @@ generic-y += sockios.h generic-y += statfs.h generic-y += termbits.h generic-y += termios.h +generic-y += trace_clock.h generic-y += types.h generic-y += xor.h diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild index 0f6e7b32826..b30f34a7988 100644 --- a/arch/um/include/asm/Kbuild +++ b/arch/um/include/asm/Kbuild @@ -2,3 +2,4 @@ generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h generic-y += switch_to.h clkdev.h +generic-y += trace_clock.h diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild index c910c9857e1..7be503e4569 100644 --- a/arch/unicore32/include/asm/Kbuild +++ b/arch/unicore32/include/asm/Kbuild @@ -54,6 +54,7 @@ generic-y += syscalls.h generic-y += termbits.h generic-y += termios.h generic-y += topology.h +generic-y += trace_clock.h generic-y += types.h generic-y += ucontext.h generic-y += unaligned.h diff --git a/arch/x86/include/asm/trace_clock.h b/arch/x86/include/asm/trace_clock.h new file mode 100644 index 00000000000..5c1652728b6 --- /dev/null +++ b/arch/x86/include/asm/trace_clock.h @@ -0,0 +1,20 @@ +#ifndef _ASM_X86_TRACE_CLOCK_H +#define _ASM_X86_TRACE_CLOCK_H + +#include +#include + +#ifdef CONFIG_X86_TSC + +extern u64 notrace trace_clock_x86_tsc(void); + +# define ARCH_TRACE_CLOCKS \ + { trace_clock_x86_tsc, "x86-tsc" }, + +#else /* !CONFIG_X86_TSC */ + +#define ARCH_TRACE_CLOCKS + +#endif + +#endif /* _ASM_X86_TRACE_CLOCK_H */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 9fd5eed3f8f..34e923a5376 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o +obj-$(CONFIG_X86_TSC) += trace_clock.o obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o diff --git a/arch/x86/kernel/trace_clock.c b/arch/x86/kernel/trace_clock.c new file mode 100644 index 00000000000..25b993729f9 --- /dev/null +++ b/arch/x86/kernel/trace_clock.c @@ -0,0 +1,21 @@ +/* + * X86 trace clocks + */ +#include +#include +#include + +/* + * trace_clock_x86_tsc(): A clock that is just the cycle counter. + * + * Unlike the other clocks, this is not in nanoseconds. + */ +u64 notrace trace_clock_x86_tsc(void) +{ + u64 ret; + + rdtsc_barrier(); + rdtscll(ret); + + return ret; +} diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild index 6d130278999..095f0a2244f 100644 --- a/arch/xtensa/include/asm/Kbuild +++ b/arch/xtensa/include/asm/Kbuild @@ -25,4 +25,5 @@ generic-y += siginfo.h generic-y += statfs.h generic-y += termios.h generic-y += topology.h +generic-y += trace_clock.h generic-y += xor.h diff --git a/include/asm-generic/trace_clock.h b/include/asm-generic/trace_clock.h new file mode 100644 index 00000000000..6726f1bafb5 --- /dev/null +++ b/include/asm-generic/trace_clock.h @@ -0,0 +1,16 @@ +#ifndef _ASM_GENERIC_TRACE_CLOCK_H +#define _ASM_GENERIC_TRACE_CLOCK_H +/* + * Arch-specific trace clocks. + */ + +/* + * Additional trace clocks added to the trace_clocks + * array in kernel/trace/trace.c + * None if the architecture has not defined it. + */ +#ifndef ARCH_TRACE_CLOCKS +# define ARCH_TRACE_CLOCKS +#endif + +#endif /* _ASM_GENERIC_TRACE_CLOCK_H */ diff --git a/include/linux/trace_clock.h b/include/linux/trace_clock.h index 4eb490237d4..d563f37e1a1 100644 --- a/include/linux/trace_clock.h +++ b/include/linux/trace_clock.h @@ -12,6 +12,8 @@ #include #include +#include + extern u64 notrace trace_clock_local(void); extern u64 notrace trace_clock(void); extern u64 notrace trace_clock_global(void); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c1434b5ce4d..0d20620c0d2 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -488,6 +488,7 @@ static struct { { trace_clock_local, "local" }, { trace_clock_global, "global" }, { trace_clock_counter, "counter" }, + ARCH_TRACE_CLOCKS }; int trace_clock_id; -- cgit v1.2.3 From 8be0709f10e3dd5d7d07933ad61a9f18c4b93ca5 Mon Sep 17 00:00:00 2001 From: David Sharp Date: Tue, 13 Nov 2012 12:18:22 -0800 Subject: tracing: Format non-nanosec times from tsc clock without a decimal point. With the addition of the "tsc" clock, formatting timestamps to look like fractional seconds is misleading. Mark clocks as either in nanoseconds or not, and format non-nanosecond timestamps as decimal integers. Tested: $ cd /sys/kernel/debug/tracing/ $ cat trace_clock [local] global tsc $ echo sched_switch > set_event $ echo 1 > tracing_on ; sleep 0.0005 ; echo 0 > tracing_on $ cat trace -0 [000] 6330.555552: sched_switch: prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=bash next_pid=29964 next_prio=120 sleep-29964 [000] 6330.555628: sched_switch: prev_comm=bash prev_pid=29964 prev_prio=120 prev_state=S ==> next_comm=swapper next_pid=0 next_prio=120 ... $ echo 1 > options/latency-format $ cat trace -0 0 4104553247us+: sched_switch: prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=bash next_pid=29964 next_prio=120 sleep-29964 0 4104553322us+: sched_switch: prev_comm=bash prev_pid=29964 prev_prio=120 prev_state=S ==> next_comm=swapper next_pid=0 next_prio=120 ... $ echo tsc > trace_clock $ cat trace $ echo 1 > tracing_on ; sleep 0.0005 ; echo 0 > tracing_on $ echo 0 > options/latency-format $ cat trace -0 [000] 16490053398357: sched_switch: prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=bash next_pid=31128 next_prio=120 sleep-31128 [000] 16490053588518: sched_switch: prev_comm=bash prev_pid=31128 prev_prio=120 prev_state=S ==> next_comm=swapper next_pid=0 next_prio=120 ... echo 1 > options/latency-format $ cat trace -0 0 91557653238+: sched_switch: prev_comm=swapper prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=bash next_pid=31128 next_prio=120 sleep-31128 0 91557843399+: sched_switch: prev_comm=bash prev_pid=31128 prev_prio=120 prev_state=S ==> next_comm=swapper next_pid=0 next_prio=120 ... v2: Move arch-specific bits out of generic code. v4: Fix x86_32 build due to 64-bit division. Google-Bug-Id: 6980623 Link: http://lkml.kernel.org/r/1352837903-32191-2-git-send-email-dhsharp@google.com Cc: Masami Hiramatsu Signed-off-by: David Sharp Signed-off-by: Steven Rostedt --- arch/x86/include/asm/trace_clock.h | 2 +- include/linux/ftrace_event.h | 6 +++ kernel/trace/trace.c | 15 ++++++-- kernel/trace/trace.h | 4 -- kernel/trace/trace_output.c | 78 ++++++++++++++++++++++++++------------ 5 files changed, 72 insertions(+), 33 deletions(-) diff --git a/arch/x86/include/asm/trace_clock.h b/arch/x86/include/asm/trace_clock.h index 5c1652728b6..beab86cc282 100644 --- a/arch/x86/include/asm/trace_clock.h +++ b/arch/x86/include/asm/trace_clock.h @@ -9,7 +9,7 @@ extern u64 notrace trace_clock_x86_tsc(void); # define ARCH_TRACE_CLOCKS \ - { trace_clock_x86_tsc, "x86-tsc" }, + { trace_clock_x86_tsc, "x86-tsc", .in_ns = 0 }, #else /* !CONFIG_X86_TSC */ diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index b80c8ddfbbd..a3d489531d8 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -86,6 +86,12 @@ struct trace_iterator { cpumask_var_t started; }; +enum trace_iter_flags { + TRACE_FILE_LAT_FMT = 1, + TRACE_FILE_ANNOTATE = 2, + TRACE_FILE_TIME_IN_NS = 4, +}; + struct trace_event; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0d20620c0d2..d943e69569c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -484,10 +484,11 @@ static const char *trace_options[] = { static struct { u64 (*func)(void); const char *name; + int in_ns; /* is this clock in nanoseconds? */ } trace_clocks[] = { - { trace_clock_local, "local" }, - { trace_clock_global, "global" }, - { trace_clock_counter, "counter" }, + { trace_clock_local, "local", 1 }, + { trace_clock_global, "global", 1 }, + { trace_clock_counter, "counter", 0 }, ARCH_TRACE_CLOCKS }; @@ -2478,6 +2479,10 @@ __tracing_open(struct inode *inode, struct file *file) if (ring_buffer_overruns(iter->tr->buffer)) iter->iter_flags |= TRACE_FILE_ANNOTATE; + /* Output in nanoseconds only if we are using a clock in nanoseconds. */ + if (trace_clocks[trace_clock_id].in_ns) + iter->iter_flags |= TRACE_FILE_TIME_IN_NS; + /* stop the trace while dumping */ tracing_stop(); @@ -3339,6 +3344,10 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) if (trace_flags & TRACE_ITER_LATENCY_FMT) iter->iter_flags |= TRACE_FILE_LAT_FMT; + /* Output in nanoseconds only if we are using a clock in nanoseconds. */ + if (trace_clocks[trace_clock_id].in_ns) + iter->iter_flags |= TRACE_FILE_TIME_IN_NS; + iter->cpu_file = cpu_file; iter->tr = &global_trace; mutex_init(&iter->mutex); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 55010ed175f..c75d7988902 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -406,10 +406,6 @@ void tracing_stop_sched_switch_record(void); void tracing_start_sched_switch_record(void); int register_tracer(struct tracer *type); int is_tracing_stopped(void); -enum trace_file_type { - TRACE_FILE_LAT_FMT = 1, - TRACE_FILE_ANNOTATE = 2, -}; extern cpumask_var_t __read_mostly tracing_buffer_mask; diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 123b189c732..194d79602dc 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -610,24 +610,54 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) return trace_print_lat_fmt(s, entry); } -static unsigned long preempt_mark_thresh = 100; +static unsigned long preempt_mark_thresh_us = 100; static int -lat_print_timestamp(struct trace_seq *s, u64 abs_usecs, - unsigned long rel_usecs) +lat_print_timestamp(struct trace_iterator *iter, u64 next_ts) { - return trace_seq_printf(s, " %4lldus%c: ", abs_usecs, - rel_usecs > preempt_mark_thresh ? '!' : - rel_usecs > 1 ? '+' : ' '); + unsigned long verbose = trace_flags & TRACE_ITER_VERBOSE; + unsigned long in_ns = iter->iter_flags & TRACE_FILE_TIME_IN_NS; + unsigned long long abs_ts = iter->ts - iter->tr->time_start; + unsigned long long rel_ts = next_ts - iter->ts; + struct trace_seq *s = &iter->seq; + + if (in_ns) { + abs_ts = ns2usecs(abs_ts); + rel_ts = ns2usecs(rel_ts); + } + + if (verbose && in_ns) { + unsigned long abs_usec = do_div(abs_ts, USEC_PER_MSEC); + unsigned long abs_msec = (unsigned long)abs_ts; + unsigned long rel_usec = do_div(rel_ts, USEC_PER_MSEC); + unsigned long rel_msec = (unsigned long)rel_ts; + + return trace_seq_printf( + s, "[%08llx] %ld.%03ldms (+%ld.%03ldms): ", + ns2usecs(iter->ts), + abs_msec, abs_usec, + rel_msec, rel_usec); + } else if (verbose && !in_ns) { + return trace_seq_printf( + s, "[%016llx] %lld (+%lld): ", + iter->ts, abs_ts, rel_ts); + } else if (!verbose && in_ns) { + return trace_seq_printf( + s, " %4lldus%c: ", + abs_ts, + rel_ts > preempt_mark_thresh_us ? '!' : + rel_ts > 1 ? '+' : ' '); + } else { /* !verbose && !in_ns */ + return trace_seq_printf(s, " %4lld: ", abs_ts); + } } int trace_print_context(struct trace_iterator *iter) { struct trace_seq *s = &iter->seq; struct trace_entry *entry = iter->ent; - unsigned long long t = ns2usecs(iter->ts); - unsigned long usec_rem = do_div(t, USEC_PER_SEC); - unsigned long secs = (unsigned long)t; + unsigned long long t; + unsigned long secs, usec_rem; char comm[TASK_COMM_LEN]; int ret; @@ -644,8 +674,13 @@ int trace_print_context(struct trace_iterator *iter) return 0; } - return trace_seq_printf(s, " %5lu.%06lu: ", - secs, usec_rem); + if (iter->iter_flags & TRACE_FILE_TIME_IN_NS) { + t = ns2usecs(iter->ts); + usec_rem = do_div(t, USEC_PER_SEC); + secs = (unsigned long)t; + return trace_seq_printf(s, " %5lu.%06lu: ", secs, usec_rem); + } else + return trace_seq_printf(s, " %12llu: ", iter->ts); } int trace_print_lat_context(struct trace_iterator *iter) @@ -659,36 +694,29 @@ int trace_print_lat_context(struct trace_iterator *iter) *next_entry = trace_find_next_entry(iter, NULL, &next_ts); unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE); - unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start); - unsigned long rel_usecs; /* Restore the original ent_size */ iter->ent_size = ent_size; if (!next_entry) next_ts = iter->ts; - rel_usecs = ns2usecs(next_ts - iter->ts); if (verbose) { char comm[TASK_COMM_LEN]; trace_find_cmdline(entry->pid, comm); - ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08llx]" - " %ld.%03ldms (+%ld.%03ldms): ", comm, - entry->pid, iter->cpu, entry->flags, - entry->preempt_count, iter->idx, - ns2usecs(iter->ts), - abs_usecs / USEC_PER_MSEC, - abs_usecs % USEC_PER_MSEC, - rel_usecs / USEC_PER_MSEC, - rel_usecs % USEC_PER_MSEC); + ret = trace_seq_printf( + s, "%16s %5d %3d %d %08x %08lx ", + comm, entry->pid, iter->cpu, entry->flags, + entry->preempt_count, iter->idx); } else { ret = lat_print_generic(s, entry, iter->cpu); - if (ret) - ret = lat_print_timestamp(s, abs_usecs, rel_usecs); } + if (ret) + ret = lat_print_timestamp(iter, next_ts); + return ret; } -- cgit v1.2.3 From 11043d8b125671a32253cddb0b05177be0e976f6 Mon Sep 17 00:00:00 2001 From: Yoshihiro YUNOMAE Date: Tue, 13 Nov 2012 12:18:23 -0800 Subject: tracing: Show raw time stamp on stats per cpu using counter or tsc mode for trace_clock Show raw time stamp values for stats per cpu if you choose counter or tsc mode for trace_clock. Although a unit of tracing time stamp is nsec in local or global mode, the units in counter and TSC mode are tracing counter and cycles respectively. Link: http://lkml.kernel.org/r/1352837903-32191-3-git-send-email-dhsharp@google.com Cc: Frederic Weisbecker Cc: Ingo Molnar Signed-off-by: Yoshihiro YUNOMAE Signed-off-by: David Sharp Signed-off-by: Steven Rostedt --- kernel/trace/trace.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index d943e69569c..b69cc380322 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4388,13 +4388,24 @@ tracing_stats_read(struct file *filp, char __user *ubuf, cnt = ring_buffer_bytes_cpu(tr->buffer, cpu); trace_seq_printf(s, "bytes: %ld\n", cnt); - t = ns2usecs(ring_buffer_oldest_event_ts(tr->buffer, cpu)); - usec_rem = do_div(t, USEC_PER_SEC); - trace_seq_printf(s, "oldest event ts: %5llu.%06lu\n", t, usec_rem); + if (trace_clocks[trace_clock_id].in_ns) { + /* local or global for trace_clock */ + t = ns2usecs(ring_buffer_oldest_event_ts(tr->buffer, cpu)); + usec_rem = do_div(t, USEC_PER_SEC); + trace_seq_printf(s, "oldest event ts: %5llu.%06lu\n", + t, usec_rem); + + t = ns2usecs(ring_buffer_time_stamp(tr->buffer, cpu)); + usec_rem = do_div(t, USEC_PER_SEC); + trace_seq_printf(s, "now ts: %5llu.%06lu\n", t, usec_rem); + } else { + /* counter or tsc mode for trace_clock */ + trace_seq_printf(s, "oldest event ts: %llu\n", + ring_buffer_oldest_event_ts(tr->buffer, cpu)); - t = ns2usecs(ring_buffer_time_stamp(tr->buffer, cpu)); - usec_rem = do_div(t, USEC_PER_SEC); - trace_seq_printf(s, "now ts: %5llu.%06lu\n", t, usec_rem); + trace_seq_printf(s, "now ts: %llu\n", + ring_buffer_time_stamp(tr->buffer, cpu)); + } cnt = ring_buffer_dropped_events_cpu(tr->buffer, cpu); trace_seq_printf(s, "dropped events: %ld\n", cnt); -- cgit v1.2.3 From 1c7d66732458dc187008e3f5b2f71e019e320fc2 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Sat, 3 Nov 2012 12:38:33 +0800 Subject: tracing: Kill unused and puzzled sample code in ftrace.h When doing per-cpu helper optimizing work, find that this code is so puzzled. 1. It's mark as comment text, maybe a sample function for guidelines or a todo work. 2. But, this sample code is odd where struct perf_trace_buf is nonexistent. commit ce71b9 delete struct perf_trace_buf definition. Author: Frederic Weisbecker Date: Sun Nov 22 05:26:55 2009 +0100 tracing: Use the perf recursion protection from trace event Is it necessary to keep there? just compile test. Link: http://lkml.kernel.org/r/50949FC9.6050202@gmail.com Signed-off-by: Shan Wei Signed-off-by: Steven Rostedt --- include/trace/ftrace.h | 73 -------------------------------------------------- 1 file changed, 73 deletions(-) diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 698f2a89032..40dc5e8fe34 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -619,79 +619,6 @@ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) -/* - * Define the insertion callback to perf events - * - * The job is very similar to ftrace_raw_event_ except that we don't - * insert in the ring buffer but in a perf counter. - * - * static void ftrace_perf_(proto) - * { - * struct ftrace_data_offsets_ __maybe_unused __data_offsets; - * struct ftrace_event_call *event_call = &event_; - * extern void perf_tp_event(int, u64, u64, void *, int); - * struct ftrace_raw_##call *entry; - * struct perf_trace_buf *trace_buf; - * u64 __addr = 0, __count = 1; - * unsigned long irq_flags; - * struct trace_entry *ent; - * int __entry_size; - * int __data_size; - * int __cpu - * int pc; - * - * pc = preempt_count(); - * - * __data_size = ftrace_get_offsets_(&__data_offsets, args); - * - * // Below we want to get the aligned size by taking into account - * // the u32 field that will later store the buffer size - * __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32), - * sizeof(u64)); - * __entry_size -= sizeof(u32); - * - * // Protect the non nmi buffer - * // This also protects the rcu read side - * local_irq_save(irq_flags); - * __cpu = smp_processor_id(); - * - * if (in_nmi()) - * trace_buf = rcu_dereference_sched(perf_trace_buf_nmi); - * else - * trace_buf = rcu_dereference_sched(perf_trace_buf); - * - * if (!trace_buf) - * goto end; - * - * trace_buf = per_cpu_ptr(trace_buf, __cpu); - * - * // Avoid recursion from perf that could mess up the buffer - * if (trace_buf->recursion++) - * goto end_recursion; - * - * raw_data = trace_buf->buf; - * - * // Make recursion update visible before entering perf_tp_event - * // so that we protect from perf recursions. - * - * barrier(); - * - * //zero dead bytes from alignment to avoid stack leak to userspace: - * *(u64 *)(&raw_data[__entry_size - sizeof(u64)]) = 0ULL; - * entry = (struct ftrace_raw_ *)raw_data; - * ent = &entry->ent; - * tracing_generic_entry_update(ent, irq_flags, pc); - * ent->type = event_call->id; - * - * <- do some jobs with dynamic arrays - * - * <- affect our values - * - * perf_tp_event(event_call->id, __addr, __count, entry, - * __entry_size); <- submit them to perf counter - * - * } - */ #ifdef CONFIG_PERF_EVENTS -- cgit v1.2.3 From e2efba763b472835fdface597fe2216b3403967e Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:20:52 +0000 Subject: staging: vt6656: 64 bit- Correctly address void structure. Fixes 64 bit deadlock on successful association. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/rxtx.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 0f35a9ae3fc..1f87213e77e 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -1452,12 +1452,10 @@ s_bPacketToWirelessUsb( pvRrvTime = pMICHDR = pvRTS = pvCTS = pvTxDataHd = NULL; - if ((bNeedEncryption) && (pTransmitKey != NULL)) { - if (((PSKeyTable) (pTransmitKey->pvKeyTable))->bSoftWEP == TRUE) { - // WEP 256 - bSoftWEP = TRUE; - } - } + if (bNeedEncryption && pTransmitKey->pvKeyTable) { + if (((PSKeyTable)&pTransmitKey->pvKeyTable)->bSoftWEP == TRUE) + bSoftWEP = TRUE; /* WEP 256 */ + } pTxBufHead = (PTX_BUFFER) usbPacketBuf; memset(pTxBufHead, 0, sizeof(TX_BUFFER)); -- cgit v1.2.3 From eb304bddc47b59927b650d43c3f35b9266c807a9 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:23:00 +0000 Subject: staging: vt6656: 64bit fixes: dpc.c incorrect addressing of void structure. Fixes the deadlock on 64 bit. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/dpc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 5ad7abb869a..e1b088161d1 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -1217,7 +1217,7 @@ static BOOL s_bHandleRxEncryption ( if (byDecMode == KEY_CTL_WEP) { // handle WEP if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || - (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE)) { + (((PSKeyTable)(&pKey->pvKeyTable))->bSoftWEP == TRUE)) { // Software WEP // 1. 3253A // 2. WEP 256 @@ -1324,9 +1324,9 @@ static BOOL s_bHostWepRxEncryption ( if (byDecMode == KEY_CTL_WEP) { // handle WEP - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP \n"); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"byDecMode == KEY_CTL_WEP\n"); if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || - (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == TRUE) || + (((PSKeyTable)(&pKey->pvKeyTable))->bSoftWEP == TRUE) || (bOnFly == FALSE)) { // Software WEP // 1. 3253A -- cgit v1.2.3 From d3b6f870ee5c5d9e15cdcbc38ea711575a2827bc Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:25:31 +0000 Subject: staging: vt6656: 64bit fixes: desh.h fix size. replace DWORD with u32. Fixes size of long issues replace DWORD with u32. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/desc.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/vt6656/desc.h b/drivers/staging/vt6656/desc.h index b68b2ec96ea..5007e98d1b0 100644 --- a/drivers/staging/vt6656/desc.h +++ b/drivers/staging/vt6656/desc.h @@ -298,7 +298,7 @@ typedef const SCTS_FB *PCSCTS_FB; // Tx FIFO header // typedef struct tagSTxBufHead { - DWORD adwTxKey[4]; + u32 adwTxKey[4]; WORD wFIFOCtl; WORD wTimeStamp; WORD wFragCtl; @@ -376,24 +376,24 @@ typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB; // MICHDR data header // typedef struct tagSMICHDRHead { - DWORD adwHDR0[4]; - DWORD adwHDR1[4]; - DWORD adwHDR2[4]; + u32 adwHDR0[4]; + u32 adwHDR1[4]; + u32 adwHDR2[4]; } __attribute__ ((__packed__)) SMICHDRHead, *PSMICHDRHead; typedef const SMICHDRHead *PCSMICHDRHead; typedef struct tagSBEACONCtl { - DWORD BufReady : 1; - DWORD TSF : 15; - DWORD BufLen : 11; - DWORD Reserved : 5; + u32 BufReady:1; + u32 TSF:15; + u32 BufLen:11; + u32 Reserved:5; } __attribute__ ((__packed__)) SBEACONCtl; typedef struct tagSSecretKey { - DWORD dwLowDword; + u32 dwLowDword; BYTE byHighByte; } __attribute__ ((__packed__)) SSecretKey; @@ -402,11 +402,11 @@ typedef struct tagSKeyEntry { BYTE abyAddrHi[2]; WORD wKCTL; BYTE abyAddrLo[4]; - DWORD dwKey0[4]; - DWORD dwKey1[4]; - DWORD dwKey2[4]; - DWORD dwKey3[4]; - DWORD dwKey4[4]; + u32 dwKey0[4]; + u32 dwKey1[4]; + u32 dwKey2[4]; + u32 dwKey3[4]; + u32 dwKey4[4]; } __attribute__ ((__packed__)) SKeyEntry; -- cgit v1.2.3 From cf5d170e02005d43ad95ca38dfa484299574f872 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:28:08 +0000 Subject: staging: vt6656: 64 bit fixes: RXbBulkInProcessData Framesize Size of long issues. Framesize correction replace DWORD with u32. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/dpc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index e1b088161d1..1ff6ea3b3a2 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -332,7 +332,7 @@ RXbBulkInProcessData ( PBYTE pbyFrame; BOOL bDeFragRx = FALSE; unsigned int cbHeaderOffset; - unsigned int FrameSize; + u32 FrameSize; WORD wEtherType = 0; signed int iSANodeIndex = -1; signed int iDANodeIndex = -1; @@ -351,7 +351,7 @@ RXbBulkInProcessData ( /* signed long ldBm = 0; */ BOOL bIsWEP = FALSE; BOOL bExtIV = FALSE; - DWORD dwWbkStatus; + u32 dwWbkStatus; PRCB pRCBIndicate = pRCB; PBYTE pbyDAddress; PWORD pwPLCP_Length; @@ -366,15 +366,15 @@ RXbBulkInProcessData ( skb = pRCB->skb; - //[31:16]RcvByteCount ( not include 4-byte Status ) - dwWbkStatus = *( (PDWORD)(skb->data) ); - FrameSize = (unsigned int)(dwWbkStatus >> 16); - FrameSize += 4; + /* [31:16]RcvByteCount ( not include 4-byte Status ) */ + dwWbkStatus = *((u32 *)(skb->data)); + FrameSize = dwWbkStatus >> 16; + FrameSize += 4; - if (BytesToIndicate != FrameSize) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---------- WRONG Length 1 \n"); - return FALSE; - } + if (BytesToIndicate != FrameSize) { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"------- WRONG Length 1\n"); + return FALSE; + } if ((BytesToIndicate > 2372) || (BytesToIndicate <= 40)) { // Frame Size error drop this packet. -- cgit v1.2.3 From a552397d5e4ef0cc0bd3e9595d6acc9a3b381171 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:32:05 +0000 Subject: staging: vt6656: 64 bit fixes: use u32 for QWORD definition. Size of long issues replace with u32. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/ttype.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index 8e9450ef399..0f70562c056 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -29,6 +29,8 @@ #ifndef __TTYPE_H__ #define __TTYPE_H__ +#include + /******* Common definitions and typedefs ***********************************/ typedef int BOOL; @@ -51,8 +53,8 @@ typedef unsigned long DWORD; // 32-bit // which is NOT really a floating point number. typedef union tagUQuadWord { struct { - DWORD dwLowDword; - DWORD dwHighDword; + u32 dwLowDword; + u32 dwHighDword; } u; double DoNotUseThisField; } UQuadWord; -- cgit v1.2.3 From ed74395ca491265bf26b56e31d6ba3f654a0b690 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:34:51 +0000 Subject: staging: vt6656: 64 bit fixes: rxtx.h Replace DWORD with u32. Size of long issues. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/rxtx.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/vt6656/rxtx.h b/drivers/staging/vt6656/rxtx.h index f99acf1d8eb..dd2198acc63 100644 --- a/drivers/staging/vt6656/rxtx.h +++ b/drivers/staging/vt6656/rxtx.h @@ -61,9 +61,9 @@ typedef struct tagSCTSDataF { // MICHDR data header // typedef struct tagSMICHDR { - DWORD adwHDR0[4]; - DWORD adwHDR1[4]; - DWORD adwHDR2[4]; + u32 adwHDR0[4]; + u32 adwHDR1[4]; + u32 adwHDR2[4]; } SMICHDR, *PSMICHDR; @@ -630,7 +630,7 @@ typedef struct tagSTX_BUFFER BYTE byPKTNO; WORD wTxByteCount; - DWORD adwTxKey[4]; + u32 adwTxKey[4]; WORD wFIFOCtl; WORD wTimeStamp; WORD wFragCtl; -- cgit v1.2.3 From 21814d6c455c7bc112dd0b0ca32756aa2ad81733 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:37:14 +0000 Subject: staging: vt6656: 64 bit fixes: int.h replaced DWORD with u32 Fixes size of long issues. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/int.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6656/int.h b/drivers/staging/vt6656/int.h index 3734e2c953d..5d8faf9f96e 100644 --- a/drivers/staging/vt6656/int.h +++ b/drivers/staging/vt6656/int.h @@ -48,8 +48,8 @@ typedef struct tagSINTData { BYTE byTSR3; BYTE byPkt3; WORD wTime3; - DWORD dwLoTSF; - DWORD dwHiTSF; + u32 dwLoTSF; + u32 dwHiTSF; BYTE byISR0; BYTE byISR1; BYTE byRTSSuccess; -- cgit v1.2.3 From 7730492855a2f9c828599bcd8d62760f96d319e4 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:41:25 +0000 Subject: staging: vt6656: 64 bit fixes : correct all type sizes After this patch all BYTE/WORD/DWORD types can be replaced with the appropriate u sizes. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/ttype.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/vt6656/ttype.h b/drivers/staging/vt6656/ttype.h index 0f70562c056..dfbf74713a8 100644 --- a/drivers/staging/vt6656/ttype.h +++ b/drivers/staging/vt6656/ttype.h @@ -44,9 +44,9 @@ typedef int BOOL; /****** Simple typedefs ***************************************************/ -typedef unsigned char BYTE; // 8-bit -typedef unsigned short WORD; // 16-bit -typedef unsigned long DWORD; // 32-bit +typedef u8 BYTE; +typedef u16 WORD; +typedef u32 DWORD; // QWORD is for those situation that we want // an 8-byte-aligned 8 byte long structure @@ -62,8 +62,8 @@ typedef UQuadWord QWORD; // 64-bit /****** Common pointer types ***********************************************/ -typedef unsigned long ULONG_PTR; // 32-bit -typedef unsigned long DWORD_PTR; // 32-bit +typedef u32 ULONG_PTR; +typedef u32 DWORD_PTR; // boolean pointer -- cgit v1.2.3 From b4dc03af5513774277c9c36b12a25cd3f25f4404 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:45:52 +0000 Subject: staging: vt6656: 64 bit fixes: fix long warning messages. Fixes long warning messages from patch [PATCH 08/14] staging: vt6656: 64 bit fixes : correct all type sizes Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/dpc.c | 4 ++-- drivers/staging/vt6656/key.c | 47 ++++++++++++++++++++++++++++++------------- drivers/staging/vt6656/mac.c | 6 ++++-- drivers/staging/vt6656/rxtx.c | 18 +++++++++++------ 4 files changed, 51 insertions(+), 24 deletions(-) diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 1ff6ea3b3a2..6f9b2b4b4fe 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -1238,7 +1238,7 @@ static BOOL s_bHandleRxEncryption ( PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16); if (byDecMode == KEY_CTL_TKIP) { *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); } else { @@ -1349,7 +1349,7 @@ static BOOL s_bHostWepRxEncryption ( PayloadLen -= (WLAN_HDR_ADDR3_LEN + 8 + 4); // 24 is 802.11 header, 8 is IV&ExtIV, 4 is crc *pdwRxTSC47_16 = cpu_to_le32(*(PDWORD)(pbyIV + 4)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %lx\n",*pdwRxTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ExtIV: %x\n", *pdwRxTSC47_16); if (byDecMode == KEY_CTL_TKIP) { *pwRxTSC15_0 = cpu_to_le16(MAKEWORD(*(pbyIV+2), *pbyIV)); diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index a61fcb9591a..617fda16064 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -235,7 +235,8 @@ BOOL KeybSetKey( PSKeyItem pKey; unsigned int uKeyIdx; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetKey: %lX\n", dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + "Enter KeybSetKey: %X\n", dwKeyIndex); j = (MAX_KEY_TABLE-1); for (i=0;i<(MAX_KEY_TABLE-1);i++) { @@ -261,7 +262,9 @@ BOOL KeybSetKey( if ((dwKeyIndex & TRANSMIT_KEY) != 0) { // Group transmit key pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + "Group transmit key(R)[%X]: %d\n", + pTable->KeyTable[i].dwGTKeyIndex, i); } pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed pTable->KeyTable[i].wKeyCtl |= (byKeyDecMode << 4); @@ -302,9 +305,12 @@ BOOL KeybSetKey( } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ", + pKey->dwTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", + pKey->wTSC15_0); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ", + pKey->dwKeyIndex); return (TRUE); } @@ -326,7 +332,9 @@ BOOL KeybSetKey( if ((dwKeyIndex & TRANSMIT_KEY) != 0) { // Group transmit key pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + "Group transmit key(N)[%X]: %d\n", + pTable->KeyTable[j].dwGTKeyIndex, j); } pTable->KeyTable[j].wKeyCtl &= 0xFF0F; // clear group key control filed pTable->KeyTable[j].wKeyCtl |= (byKeyDecMode << 4); @@ -367,9 +375,11 @@ BOOL KeybSetKey( } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n ", + pKey->dwTSC47_16); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n ", + pKey->dwKeyIndex); return (TRUE); } @@ -597,7 +607,8 @@ BOOL KeybGetTransmitKey(PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyType, DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%x ", pTable->KeyTable[i].abyBSSID[ii]); } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"dwGTKeyIndex: %X\n", + pTable->KeyTable[i].dwGTKeyIndex); return (TRUE); } @@ -696,7 +707,10 @@ BOOL KeybSetDefaultKey( if ((dwKeyIndex & TRANSMIT_KEY) != 0) { // Group transmit key pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, MAX_KEY_TABLE-1); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + "Group transmit key(R)[%X]: %d\n", + pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, + MAX_KEY_TABLE-1); } pTable->KeyTable[MAX_KEY_TABLE-1].wKeyCtl &= 0x7F00; // clear all key control filed @@ -747,9 +761,11 @@ BOOL KeybSetDefaultKey( } DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwTSC47_16: %x\n", + pKey->dwTSC47_16); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->wTSC15_0: %x\n", pKey->wTSC15_0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"pKey->dwKeyIndex: %x\n", + pKey->dwKeyIndex); return (TRUE); } @@ -787,7 +803,8 @@ BOOL KeybSetAllGroupKey( PSKeyItem pKey; unsigned int uKeyIdx; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Enter KeybSetAllGroupKey: %X\n", + dwKeyIndex); if ((dwKeyIndex & PAIRWISE_KEY) != 0) { // Pairwise key @@ -804,7 +821,9 @@ BOOL KeybSetAllGroupKey( if ((dwKeyIndex & TRANSMIT_KEY) != 0) { // Group transmit key pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + "Group transmit key(R)[%X]: %d\n", + pTable->KeyTable[i].dwGTKeyIndex, i); } pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed diff --git a/drivers/staging/vt6656/mac.c b/drivers/staging/vt6656/mac.c index af4a29d1477..8fddc7b3930 100644 --- a/drivers/staging/vt6656/mac.c +++ b/drivers/staging/vt6656/mac.c @@ -260,7 +260,8 @@ BYTE pbyData[24]; dwData1 <<= 16; dwData1 |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData1, wKeyCtl); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"1. wOffset: %d, Data: %X,"\ + " KeyCtl:%X\n", wOffset, dwData1, wKeyCtl); //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); @@ -277,7 +278,8 @@ BYTE pbyData[24]; dwData2 <<= 8; dwData2 |= *(pbyAddr+0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %lX\n", wOffset, dwData2); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"2. wOffset: %d, Data: %X\n", + wOffset, dwData2); //VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); //VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 1f87213e77e..cd9debc2078 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -375,7 +375,8 @@ s_vFillTxKey ( *(pbyIVHead+3) = (BYTE)(((pDevice->byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV // Append IV&ExtIV after Mac Header *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"vFillTxKey()---- pdwExtIV: %x\n", + *pdwExtIV); } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { pTransmitKey->wTSC15_0++; @@ -1749,7 +1750,8 @@ s_bPacketToWirelessUsb( MIC_vAppend((PBYTE)&(psEthHeader->abyDstAddr[0]), 12); dwMIC_Priority = 0; MIC_vAppend((PBYTE)&dwMIC_Priority, 4); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC KEY: %X, %X\n", + dwMICKey0, dwMICKey1); /////////////////////////////////////////////////////////////////// @@ -2631,7 +2633,8 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { MIC_vAppend((PBYTE)&(sEthHeader.abyDstAddr[0]), 12); dwMIC_Priority = 0; MIC_vAppend((PBYTE)&dwMIC_Priority, 4); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY: %lX, %lX\n", dwMICKey0, dwMICKey1); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"DMA0_tx_8021:MIC KEY:"\ + " %X, %X\n", dwMICKey0, dwMICKey1); uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen; @@ -2651,7 +2654,8 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"uLength: %d, %d\n", uLength, cbFrameBodySize); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%lx, %lx\n", *pdwMIC_L, *pdwMIC_R); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"MIC:%x, %x\n", + *pdwMIC_L, *pdwMIC_R); } @@ -3025,7 +3029,8 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"error: KEY is GTK!!~~\n"); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n", + pTransmitKey->dwKeyIndex); bNeedEncryption = TRUE; } } @@ -3034,7 +3039,8 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) if (pDevice->bEnableHostWEP) { if ((uNodeIndex != 0) && (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%lX]\n", pTransmitKey->dwKeyIndex); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Find PTK [%X]\n", + pTransmitKey->dwKeyIndex); bNeedEncryption = TRUE; } } -- cgit v1.2.3 From c0d05b305b00c698b0a8c1b3d46c9380bce9db45 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:49:59 +0000 Subject: staging: vt6656: 64bit fixes: key.c/h change unsigned long to u32 Fixes long issues. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/key.c | 6 +++--- drivers/staging/vt6656/key.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/vt6656/key.c b/drivers/staging/vt6656/key.c index 617fda16064..bf24adb7f29 100644 --- a/drivers/staging/vt6656/key.c +++ b/drivers/staging/vt6656/key.c @@ -223,7 +223,7 @@ BOOL KeybSetKey( PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex, - unsigned long uKeyLength, + u32 uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -675,7 +675,7 @@ BOOL KeybSetDefaultKey( void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, - unsigned long uKeyLength, + u32 uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -791,7 +791,7 @@ BOOL KeybSetAllGroupKey( void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, - unsigned long uKeyLength, + u32 uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode diff --git a/drivers/staging/vt6656/key.h b/drivers/staging/vt6656/key.h index f749c7a027d..bd35d39621a 100644 --- a/drivers/staging/vt6656/key.h +++ b/drivers/staging/vt6656/key.h @@ -58,7 +58,7 @@ typedef struct tagSKeyItem { BOOL bKeyValid; - unsigned long uKeyLength; + u32 uKeyLength; BYTE abyKey[MAX_KEY_LEN]; QWORD KeyRSC; DWORD dwTSC47_16; @@ -107,7 +107,7 @@ BOOL KeybSetKey( PSKeyManagement pTable, PBYTE pbyBSSID, DWORD dwKeyIndex, - unsigned long uKeyLength, + u32 uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -146,7 +146,7 @@ BOOL KeybSetDefaultKey( void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, - unsigned long uKeyLength, + u32 uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode @@ -156,7 +156,7 @@ BOOL KeybSetAllGroupKey( void *pDeviceHandler, PSKeyManagement pTable, DWORD dwKeyIndex, - unsigned long uKeyLength, + u32 uKeyLength, PQWORD pKeyRSC, PBYTE pbyKey, BYTE byKeyDecMode -- cgit v1.2.3 From d5bbef7c94d1f29aeef4cfcd801245a156a67e95 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:53:14 +0000 Subject: staging: vt6656: 64 bit fixes pdwIV is now u32 Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/rxtx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index cd9debc2078..83c04e12093 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -355,7 +355,7 @@ s_vFillTxKey ( } // Append IV after Mac Header *pdwIV &= WEP_IV_MASK;//00000000 11111111 11111111 11111111 - *pdwIV |= (unsigned long)pDevice->byKeyIndex << 30; + *pdwIV |= (u32)pDevice->byKeyIndex << 30; *pdwIV = cpu_to_le32(*pdwIV); pDevice->dwIVCounter++; if (pDevice->dwIVCounter > WEP_IV_MASK) { -- cgit v1.2.3 From 2f8896428181da38cd72aca43c35007d8f0a1ad8 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:56:02 +0000 Subject: staging: vt6656: 64 bit fixes TKIPvMixKey remove unsigned long Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/tkip.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c index 003123e550f..282c08d6576 100644 --- a/drivers/staging/vt6656/tkip.c +++ b/drivers/staging/vt6656/tkip.c @@ -189,27 +189,25 @@ void TKIPvMixKey( PBYTE pbyRC4Key ) { - unsigned int p1k[5]; -// unsigned int ttak0, ttak1, ttak2, ttak3, ttak4; - unsigned int tsc0, tsc1, tsc2; - unsigned int ppk0, ppk1, ppk2, ppk3, ppk4, ppk5; - unsigned long int pnl,pnh; - - int i, j; - - pnl = wTSC15_0; - pnh = dwTSC47_16; - - tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */ - tsc1 = (unsigned int)(pnh % 65536); - tsc2 = (unsigned int)(pnl % 65536); /* lsb */ - - /* Phase 1, step 1 */ - p1k[0] = tsc1; - p1k[1] = tsc0; - p1k[2] = (unsigned int)(pbyTA[0] + (pbyTA[1]*256)); - p1k[3] = (unsigned int)(pbyTA[2] + (pbyTA[3]*256)); - p1k[4] = (unsigned int)(pbyTA[4] + (pbyTA[5]*256)); + u32 p1k[5]; + u32 tsc0, tsc1, tsc2; + u32 ppk0, ppk1, ppk2, ppk3, ppk4, ppk5; + u32 pnl, pnh; + int i, j; + + pnl = (u32)wTSC15_0; + pnh = (u32)(dwTSC47_16 & 0xffffffff); + + tsc0 = (u32)((pnh >> 16) % 65536); /* msb */ + tsc1 = (u32)(pnh % 65536); + tsc2 = (u32)(pnl % 65536); /* lsb */ + + /* Phase 1, step 1 */ + p1k[0] = tsc1; + p1k[1] = tsc0; + p1k[2] = (u32)(pbyTA[0] + (pbyTA[1]*256)); + p1k[3] = (u32)(pbyTA[2] + (pbyTA[3]*256)); + p1k[4] = (u32)(pbyTA[4] + (pbyTA[5]*256)); /* Phase 1, step 2 */ for (i=0; i<8; i++) { -- cgit v1.2.3 From 1d651be13f59ddf706283eb61f2590aedd44cd2d Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 15:59:11 +0000 Subject: staging: vt6656: 64 bit fixes correct sizes of NDIS_802_11_ASSOCIATION_INFORMATION Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/wmgr.h | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/staging/vt6656/wmgr.h b/drivers/staging/vt6656/wmgr.h index 13dfb3bf832..52b1b562b14 100644 --- a/drivers/staging/vt6656/wmgr.h +++ b/drivers/staging/vt6656/wmgr.h @@ -89,44 +89,44 @@ typedef void (*TimerFunction)(unsigned long); //+++ NDIS related -typedef unsigned char NDIS_802_11_MAC_ADDRESS[ETH_ALEN]; +typedef u8 NDIS_802_11_MAC_ADDRESS[ETH_ALEN]; typedef struct _NDIS_802_11_AI_REQFI { - unsigned short Capabilities; - unsigned short ListenInterval; + u16 Capabilities; + u16 ListenInterval; NDIS_802_11_MAC_ADDRESS CurrentAPAddress; } NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI; typedef struct _NDIS_802_11_AI_RESFI { - unsigned short Capabilities; - unsigned short StatusCode; - unsigned short AssociationId; + u16 Capabilities; + u16 StatusCode; + u16 AssociationId; } NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI; typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION { - unsigned long Length; - unsigned short AvailableRequestFixedIEs; - NDIS_802_11_AI_REQFI RequestFixedIEs; - unsigned long RequestIELength; - unsigned long OffsetRequestIEs; - unsigned short AvailableResponseFixedIEs; - NDIS_802_11_AI_RESFI ResponseFixedIEs; - unsigned long ResponseIELength; - unsigned long OffsetResponseIEs; + u32 Length; + u16 AvailableRequestFixedIEs; + NDIS_802_11_AI_REQFI RequestFixedIEs; + u32 RequestIELength; + u32 OffsetRequestIEs; + u16 AvailableResponseFixedIEs; + NDIS_802_11_AI_RESFI ResponseFixedIEs; + u32 ResponseIELength; + u32 OffsetResponseIEs; } NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION; typedef struct tagSAssocInfo { - NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo; - BYTE abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN]; - // store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION - unsigned long RequestIELength; - BYTE abyReqIEs[WLAN_BEACON_FR_MAXLEN]; + NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo; + u8 abyIEs[WLAN_BEACON_FR_MAXLEN+WLAN_BEACON_FR_MAXLEN]; + /* store ReqIEs set by OID_802_11_ASSOCIATION_INFORMATION */ + u32 RequestIELength; + u8 abyReqIEs[WLAN_BEACON_FR_MAXLEN]; } SAssocInfo, *PSAssocInfo; -//--- + -- cgit v1.2.3 From 70e227790d4ee4590023d8041a3485f8053593fc Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 11 Nov 2012 16:07:57 +0000 Subject: staging: vt6656: 64bit fixes: vCommandTimerWait change calculation of timer. The timer appears to run too fast/race on 64 bit systems. Using msecs_to_jiffies seems to cause a deadlock on 64 bit. A calculation of (MSecond * HZ) / 1000 appears to run satisfactory. Change BSSIDInfoCount to u32. After this patch the driver can be successfully connect on little endian 64/32 bit systems. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/wcmd.c | 20 +++++++++++--------- drivers/staging/vt6656/wpa2.h | 4 ++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index 586fbe1627f..b854d7ef97d 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -316,17 +316,19 @@ s_MgrMakeProbeRequest( return pTxPacket; } -void vCommandTimerWait(void *hDeviceContext, unsigned int MSecond) +void vCommandTimerWait(void *hDeviceContext, unsigned long MSecond) { - PSDevice pDevice = (PSDevice)hDeviceContext; + PSDevice pDevice = (PSDevice)hDeviceContext; - init_timer(&pDevice->sTimerCommand); - pDevice->sTimerCommand.data = (unsigned long)pDevice; - pDevice->sTimerCommand.function = (TimerFunction)vRunCommand; - // RUN_AT :1 msec ~= (HZ/1024) - pDevice->sTimerCommand.expires = (unsigned int)RUN_AT((MSecond * HZ) >> 10); - add_timer(&pDevice->sTimerCommand); - return; + init_timer(&pDevice->sTimerCommand); + + pDevice->sTimerCommand.data = (unsigned long)pDevice; + pDevice->sTimerCommand.function = (TimerFunction)vRunCommand; + pDevice->sTimerCommand.expires = RUN_AT((MSecond * HZ) / 1000); + + add_timer(&pDevice->sTimerCommand); + + return; } void vRunCommand(void *hDeviceContext) diff --git a/drivers/staging/vt6656/wpa2.h b/drivers/staging/vt6656/wpa2.h index 46c295905b4..c359252a6b0 100644 --- a/drivers/staging/vt6656/wpa2.h +++ b/drivers/staging/vt6656/wpa2.h @@ -45,8 +45,8 @@ typedef struct tagsPMKIDInfo { } PMKIDInfo, *PPMKIDInfo; typedef struct tagSPMKIDCache { - unsigned long BSSIDInfoCount; - PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE]; + u32 BSSIDInfoCount; + PMKIDInfo BSSIDInfo[MAX_PMKID_CACHE]; } SPMKIDCache, *PSPMKIDCache; -- cgit v1.2.3 From f1426fd7ccff8f0a2c7cb7a5127baa73b7207db9 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Mon, 12 Nov 2012 20:43:34 +0000 Subject: staging: vt6656: Remove WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT macro Already removed in parts of driver. Removed in remainder. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/bssdb.c | 6 ------ drivers/staging/vt6656/device.h | 6 ------ drivers/staging/vt6656/dpc.c | 2 -- drivers/staging/vt6656/iwctl.c | 18 +----------------- drivers/staging/vt6656/iwctl.h | 2 -- drivers/staging/vt6656/main_usb.c | 6 ------ drivers/staging/vt6656/wcmd.c | 10 ---------- drivers/staging/vt6656/wmgr.c | 10 ---------- drivers/staging/vt6656/wpactl.h | 2 -- 9 files changed, 1 insertion(+), 61 deletions(-) diff --git a/drivers/staging/vt6656/bssdb.c b/drivers/staging/vt6656/bssdb.c index 2ac066df834..f1d852b2a9a 100644 --- a/drivers/staging/vt6656/bssdb.c +++ b/drivers/staging/vt6656/bssdb.c @@ -913,7 +913,6 @@ if(pDevice->byReAssocCount > 0) { if((pDevice->byReAssocCount > 10) && (pDevice->bLinkPass != TRUE)) { //10 sec timeout printk("Re-association timeout!!!\n"); pDevice->byReAssocCount = 0; - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT // if(pDevice->bWPASuppWextEnabled == TRUE) { union iwreq_data wrqu; @@ -922,7 +921,6 @@ if(pDevice->byReAssocCount > 0) { PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); } - #endif } else if(pDevice->bLinkPass == TRUE) pDevice->byReAssocCount = 0; @@ -1116,7 +1114,6 @@ if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) && netif_rx(pDevice->skb); pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); } - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT { union iwreq_data wrqu; memset(&wrqu, 0, sizeof (wrqu)); @@ -1124,7 +1121,6 @@ if((pMgmt->eCurrState!=WMAC_STATE_ASSOC) && PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); } - #endif } } else if (pItemSSID->len != 0) { @@ -1169,11 +1165,9 @@ DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bIsRoaming %d, !\n", pDevice->bIsRoaming ); else { if (pDevice->uAutoReConnectTime < 10) { pDevice->uAutoReConnectTime++; - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT //network manager support need not do Roaming scan??? if(pDevice->bWPASuppWextEnabled ==TRUE) pDevice->uAutoReConnectTime = 0; - #endif } else { //mike use old encryption status for wpa reauthen diff --git a/drivers/staging/vt6656/device.h b/drivers/staging/vt6656/device.h index f334e64ca19..2595ac51b20 100644 --- a/drivers/staging/vt6656/device.h +++ b/drivers/staging/vt6656/device.h @@ -68,10 +68,6 @@ #include #include // New driver API -#ifndef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -#define WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT -#endif - //please copy below macro to driver_event.c for API #define RT_INSMOD_EVENT_FLAG 0x0101 #define RT_UPDEV_EVENT_FLAG 0x0102 @@ -815,13 +811,11 @@ typedef struct __device_info { struct sk_buff *skb; //-- -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT BOOL bwextstep0; BOOL bwextstep1; BOOL bwextstep2; BOOL bwextstep3; BOOL bWPASuppWextEnabled; -#endif #ifdef HOSTAP // user space daemon: hostapd, is used for HOSTAP diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 6f9b2b4b4fe..c6f539587f9 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -864,7 +864,6 @@ RXbBulkInProcessData ( pDevice->dev->name); } } - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT //send event to wpa_supplicant //if(pDevice->bWPASuppWextEnabled == TRUE) { @@ -889,7 +888,6 @@ RXbBulkInProcessData ( wireless_send_event(pDevice->dev, IWEVMICHAELMICFAILURE, &wrqu, (char *)&ev); } - #endif if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index e58049b8a27..706e2a6c4e7 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -38,19 +38,12 @@ #include "hostap.h" #include "power.h" #include "rf.h" - -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT #include "iowpa.h" #include "wpactl.h" -#endif #include -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT #define SUPPORTED_WIRELESS_EXT 18 -#else -#define SUPPORTED_WIRELESS_EXT 17 -#endif static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, 2472, 2484, @@ -704,10 +697,8 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); memset(pMgmt->abyDesireBSSID, 0xFF,6); PRINT_K("set essid to 'any' \n"); -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT // Unknown desired AP, so here need not associate?? return 0; -#endif } else { // Set the SSID memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); @@ -729,7 +720,6 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, return 0; } -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT // Wext wil order another command of siwap to link // with desired AP, so here need not associate?? if (pDevice->bWPASuppWextEnabled == TRUE) { @@ -778,7 +768,6 @@ int iwctl_siwessid(struct net_device *dev, struct iw_request_info *info, } return 0; } -#endif DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s \n", pItemSSID->abySSID); } @@ -1155,9 +1144,8 @@ int iwctl_siwencode(struct net_device *dev, struct iw_request_info *info, pMgmt->bShareKeyAlgorithm = FALSE; } -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT memset(pMgmt->abyDesireBSSID, 0xFF, 6); -#endif + return rc; } @@ -1311,8 +1299,6 @@ int iwctl_giwsens(struct net_device *dev, struct iw_request_info *info, return 0; } -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT - int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra) { @@ -1627,8 +1613,6 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, return ret; } -#endif - static const iw_handler iwctl_handler[] = { (iw_handler)NULL, // SIOCSIWCOMMIT (iw_handler)NULL, // SIOCGIWNAME diff --git a/drivers/staging/vt6656/iwctl.h b/drivers/staging/vt6656/iwctl.h index d056f83a915..9cf48ab49de 100644 --- a/drivers/staging/vt6656/iwctl.h +++ b/drivers/staging/vt6656/iwctl.h @@ -118,7 +118,6 @@ int iwctl_giwscan(struct net_device *dev, struct iw_request_info *info, int iwctl_siwscan(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra); -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT int iwctl_siwauth(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra); @@ -139,7 +138,6 @@ int iwctl_giwencodeext(struct net_device *dev, struct iw_request_info *info, int iwctl_siwmlme(struct net_device *dev, struct iw_request_info *info, struct iw_point *wrq, char *extra); -#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT extern const struct iw_handler_def iwctl_handler_def; extern const struct iw_priv_args iwctl_private_args; diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index d402df9161e..d8cb0934148 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1056,13 +1056,11 @@ static int device_open(struct net_device *dev) { pDevice->bEventAvailable = FALSE; pDevice->bWPADEVUp = FALSE; -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT pDevice->bwextstep0 = FALSE; pDevice->bwextstep1 = FALSE; pDevice->bwextstep2 = FALSE; pDevice->bwextstep3 = FALSE; pDevice->bWPASuppWextEnabled = FALSE; -#endif pDevice->byReAssocCount = 0; RXvWorkItem(pDevice); @@ -1848,7 +1846,6 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { */ break; -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT case SIOCSIWAUTH: DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n"); rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL); @@ -1901,7 +1898,6 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer); break; -#endif // #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT case IOCTL_CMD_TEST: @@ -1995,10 +1991,8 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW); //End Modify netif_stop_queue(pDevice->dev); -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT pMgmt->eScanType = WMAC_SCAN_ACTIVE; if (!pDevice->bWPASuppWextEnabled) -#endif bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); diff --git a/drivers/staging/vt6656/wcmd.c b/drivers/staging/vt6656/wcmd.c index b854d7ef97d..99bced79376 100644 --- a/drivers/staging/vt6656/wcmd.c +++ b/drivers/staging/vt6656/wcmd.c @@ -503,7 +503,6 @@ void vRunCommand(void *hDeviceContext) pMgmt->eScanState = WMAC_NO_SCANNING; pDevice->bStopDataPkt = FALSE; -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT if(pMgmt->eScanType == WMAC_SCAN_PASSIVE) { //send scan event to wpa_Supplicant @@ -512,7 +511,6 @@ void vRunCommand(void *hDeviceContext) memset(&wrqu, 0, sizeof(wrqu)); wireless_send_event(pDevice->dev, SIOCGIWSCAN, &wrqu, NULL); } -#endif s_bCommandComplete(pDevice); break; @@ -525,13 +523,11 @@ void vRunCommand(void *hDeviceContext) return; } else { - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT pDevice->bwextstep0 = FALSE; pDevice->bwextstep1 = FALSE; pDevice->bwextstep2 = FALSE; pDevice->bwextstep3 = FALSE; pDevice->bWPASuppWextEnabled = FALSE; - #endif pDevice->fWPA_Authened = FALSE; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Send Disassociation Packet..\n"); @@ -674,7 +670,6 @@ void vRunCommand(void *hDeviceContext) } else { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n"); - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT // if(pDevice->bWPASuppWextEnabled == TRUE) { union iwreq_data wrqu; @@ -683,7 +678,6 @@ void vRunCommand(void *hDeviceContext) PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated:vMgrJoinBSSBegin Fail !!)\n"); wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); } - #endif } } s_bCommandComplete(pDevice); @@ -926,7 +920,6 @@ void vRunCommand(void *hDeviceContext) // unlock command busy pMgmt->eCurrState = WMAC_STATE_IDLE; pMgmt->sNodeDBTable[0].bActive = FALSE; - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT // if(pDevice->bWPASuppWextEnabled == TRUE) { union iwreq_data wrqu; @@ -935,15 +928,12 @@ void vRunCommand(void *hDeviceContext) PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); } - #endif } - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT pDevice->bwextstep0 = FALSE; pDevice->bwextstep1 = FALSE; pDevice->bwextstep2 = FALSE; pDevice->bwextstep3 = FALSE; pDevice->bWPASuppWextEnabled = FALSE; - #endif //clear current SSID pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; pItemSSID->len = 0; diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index 7db6a8d3508..20b3618c6dd 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -998,7 +998,6 @@ s_vMgrRxAssocResponse( pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); } -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT //if(pDevice->bWPASuppWextEnabled == TRUE) { BYTE buf[512]; @@ -1037,7 +1036,6 @@ s_vMgrRxAssocResponse( wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); } -#endif //#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT } else { @@ -1053,14 +1051,12 @@ s_vMgrRxAssocResponse( } -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT //need clear flags related to Networkmanager pDevice->bwextstep0 = FALSE; pDevice->bwextstep1 = FALSE; pDevice->bwextstep2 = FALSE; pDevice->bwextstep3 = FALSE; pDevice->bWPASuppWextEnabled = FALSE; -#endif if(pMgmt->eCurrState == WMAC_STATE_ASSOC) timer_expire(pDevice->sTimerCommand, 0); @@ -1638,7 +1634,6 @@ s_vMgrRxDisassociation( } } - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT // if(pDevice->bWPASuppWextEnabled == TRUE) { union iwreq_data wrqu; @@ -1647,7 +1642,6 @@ s_vMgrRxDisassociation( PRINT_K("wireless_send_event--->SIOCGIWAP(disassociated)\n"); wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); } - #endif } /* else, ignore it */ @@ -1727,7 +1721,6 @@ s_vMgrRxDeauthentication( pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); } - #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT // if(pDevice->bWPASuppWextEnabled == TRUE) { union iwreq_data wrqu; @@ -1736,7 +1729,6 @@ s_vMgrRxDeauthentication( PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n"); wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL); } - #endif } /* else, ignore it. TODO: IBSS authentication service @@ -2645,10 +2637,8 @@ void vMgrJoinBSSBegin(void *hDeviceContext, PCMD_STATUS pStatus) */ } -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT //if(pDevice->bWPASuppWextEnabled == TRUE) Encyption_Rebuild(pDevice, pCurr); -#endif // Infrastructure BSS s_vMgrSynchBSS(pDevice, diff --git a/drivers/staging/vt6656/wpactl.h b/drivers/staging/vt6656/wpactl.h index 00c8451ab50..19ab8b6f7fc 100644 --- a/drivers/staging/vt6656/wpactl.h +++ b/drivers/staging/vt6656/wpactl.h @@ -30,9 +30,7 @@ #define __WPACTL_H__ #include "device.h" -#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT #include "iowpa.h" -#endif /*--------------------- Export Definitions -------------------------*/ -- cgit v1.2.3 From 3e779fc9491f717379343bdc15c3a20d7ff7d77f Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:42 +0200 Subject: staging: xgifb: XGI_GetLcdPtr: add separate table for VB_SIS301LV/VB_SIS302LV Add a separate data table for VB_SIS301LV/VB_SIS302LV to avoid branching and to make further cleanups easier. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 78 ++++++++++++++++++-------------------- drivers/staging/xgifb/vb_table.h | 24 ++++++++++++ 2 files changed, 61 insertions(+), 41 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index c8561a0b386..7686e42c9a0 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1350,7 +1350,11 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, tempdi = XGI_LCDDataTable; break; case 5: - tempdi = XGI_LCDDesDataTable; + if ((pVBInfo->VBType & VB_SIS301LV) || + (pVBInfo->VBType & VB_SIS302LV)) + tempdi = xgifb_lcddldes; + else + tempdi = XGI_LCDDesDataTable; break; default: break; @@ -1614,6 +1618,30 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, default: break; } + } else if (table == 5 && ((pVBInfo->VBType & VB_SIS301LV) || + (pVBInfo->VBType & VB_SIS302LV))) { + switch (tempdi[i].DATAPTR) { + case 0: return &XGI_ExtLCDDes1024x768Data[tempal]; + case 1: return &XGI_StLCDDes1024x768Data[tempal]; + case 2: return &XGI_CetLCDDes1024x768Data[tempal]; + case 3: return &XGI_ExtLCDDLDes1280x1024Data[tempal]; + case 4: return &XGI_StLCDDLDes1280x1024Data[tempal]; + case 5: return &XGI_CetLCDDLDes1280x1024Data[tempal]; + case 6: + case 7: return &xgifb_lcddldes_1400x1050[tempal]; + case 8: return &XGI_CetLCDDes1400x1050Data[tempal]; + case 9: return &XGI_CetLCDDes1400x1050Data2[tempal]; + case 10: return &XGI_ExtLCDDLDes1600x1200Data[tempal]; + case 11: return &XGI_StLCDDLDes1600x1200Data[tempal]; + case 12: return &XGI_NoScalingDesData[tempal]; + case 13: + case 14: return &xgifb_lcddes_1024x768x75[tempal]; + case 15: return &XGI_CetLCDDes1024x768x75Data[tempal]; + case 16: + case 17: return &xgifb_lcddldes_1280x1024x75[tempal]; + case 18: return &XGI_CetLCDDLDes1280x1024x75Data[tempal]; + case 19: return &XGI_NoScalingDesDatax75[tempal]; + } } else if (table == 5) { switch (tempdi[i].DATAPTR) { case 0: @@ -1626,33 +1654,17 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, return &XGI_CetLCDDes1024x768Data[tempal]; break; case 3: - if ((pVBInfo->VBType & VB_SIS301LV) || - (pVBInfo->VBType & VB_SIS302LV)) - return &XGI_ExtLCDDLDes1280x1024Data[tempal]; - else - return &XGI_ExtLCDDes1280x1024Data[tempal]; + return &XGI_ExtLCDDes1280x1024Data[tempal]; break; case 4: - if ((pVBInfo->VBType & VB_SIS301LV) || - (pVBInfo->VBType & VB_SIS302LV)) - return &XGI_StLCDDLDes1280x1024Data[tempal]; - else - return &XGI_StLCDDes1280x1024Data[tempal]; + return &XGI_StLCDDes1280x1024Data[tempal]; break; case 5: - if ((pVBInfo->VBType & VB_SIS301LV) || - (pVBInfo->VBType & VB_SIS302LV)) - return &XGI_CetLCDDLDes1280x1024Data[tempal]; - else - return &XGI_CetLCDDes1280x1024Data[tempal]; + return &XGI_CetLCDDes1280x1024Data[tempal]; break; case 6: case 7: - if ((pVBInfo->VBType & VB_SIS301LV) || - (pVBInfo->VBType & VB_SIS302LV)) - return &xgifb_lcddldes_1400x1050[tempal]; - else - return &xgifb_lcddes_1400x1050[tempal]; + return &xgifb_lcddes_1400x1050[tempal]; break; case 8: return &XGI_CetLCDDes1400x1050Data[tempal]; @@ -1661,18 +1673,10 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, return &XGI_CetLCDDes1400x1050Data2[tempal]; break; case 10: - if ((pVBInfo->VBType & VB_SIS301LV) || - (pVBInfo->VBType & VB_SIS302LV)) - return &XGI_ExtLCDDLDes1600x1200Data[tempal]; - else - return &XGI_ExtLCDDes1600x1200Data[tempal]; + return &XGI_ExtLCDDes1600x1200Data[tempal]; break; case 11: - if ((pVBInfo->VBType & VB_SIS301LV) || - (pVBInfo->VBType & VB_SIS302LV)) - return &XGI_StLCDDLDes1600x1200Data[tempal]; - else - return &XGI_StLCDDes1600x1200Data[tempal]; + return &XGI_StLCDDes1600x1200Data[tempal]; break; case 12: return &XGI_NoScalingDesData[tempal]; @@ -1686,18 +1690,10 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, break; case 16: case 17: - if ((pVBInfo->VBType & VB_SIS301LV) || - (pVBInfo->VBType & VB_SIS302LV)) - return &xgifb_lcddldes_1280x1024x75[tempal]; - else - return &xgifb_lcddes_1280x1024x75[tempal]; + return &xgifb_lcddes_1280x1024x75[tempal]; break; case 18: - if ((pVBInfo->VBType & VB_SIS301LV) || - (pVBInfo->VBType & VB_SIS302LV)) - return &XGI_CetLCDDLDes1280x1024x75Data[tempal]; - else - return &XGI_CetLCDDes1280x1024x75Data[tempal]; + return &XGI_CetLCDDes1280x1024x75Data[tempal]; break; case 19: return &XGI_NoScalingDesDatax75[tempal]; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 180aae042ce..ace8ac4bb14 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1804,6 +1804,30 @@ static struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = { {0xFF, 0x0000, 0x0000, 0} }; +static struct XGI330_LCDDataTablStruct xgifb_lcddldes[] = { + {Panel_1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCDDes1024x768Data */ + {Panel_1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCDDes1024x768Data */ + {Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCDDes1024x768Data */ + {Panel_1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCDDLDes1280x1024Data */ + {Panel_1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCDDLDes1280x1024Data */ + {Panel_1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCDDLDes1280x1024Data */ + {Panel_1400x1050, 0x0019, 0x0001, 6}, /* xgifb_lcddldes_1400x1050 */ + {Panel_1400x1050, 0x0019, 0x0000, 7}, /* xgifb_lcddldes_1400x1050 */ + {Panel_1400x1050, 0x0418, 0x0010, 8}, /* XGI_CetLCDDes1400x1050Data */ + {Panel_1400x1050, 0x0418, 0x0410, 9}, /* XGI_CetLCDDes1400x1050Data2 */ + {Panel_1600x1200, 0x0019, 0x0001, 10}, /* XGI_ExtLCDDLDes1600x1200Data */ + {Panel_1600x1200, 0x0019, 0x0000, 11}, /* XGI_StLCDDes1600x1200Data */ + {PanelRef60Hz, 0x0008, 0x0008, 12}, /* XGI_NoScalingDesData */ + {Panel_1024x768x75, 0x0019, 0x0001, 13}, /* xgifb_lcddes_1024x768x75 */ + {Panel_1024x768x75, 0x0019, 0x0000, 14}, /* xgifb_lcddes_1024x768x75 */ + {Panel_1024x768x75, 0x0018, 0x0010, 15}, /* XGI_CetLCDDes1024x768x75Data */ + {Panel_1280x1024x75, 0x0019, 0x0001, 16}, /* xgifb_lcddldes_1280x1024x75 */ + {Panel_1280x1024x75, 0x0019, 0x0000, 17}, /* xgifb_lcddldes_1280x1024x75 */ + {Panel_1280x1024x75, 0x0018, 0x0010, 18}, /* XGI_CetLCDDes1280x1024x75Data */ + {PanelRef75Hz, 0x0008, 0x0008, 19}, /* XGI_NoScalingDesDatax75 */ + {0xFF, 0x0000, 0x0000, 0} +}; + static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1[] = { {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1 */ {Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2 */ -- cgit v1.2.3 From 515e9a603f3e43b56f1516b8212219d893186d45 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:43 +0200 Subject: staging: xgifb: XGI_GetLcdPtr: replace xgifb_epllcd_crt1 Replace xgifb_epllcd_crt1 with two different tables to make further cleanups easier. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 4 +++- drivers/staging/xgifb/vb_table.h | 39 ++++++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 7686e42c9a0..bc341946788 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1337,8 +1337,10 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, switch (tempbx) { case 0: + tempdi = xgifb_epllcd_crt1_h; + break; case 1: - tempdi = xgifb_epllcd_crt1; + tempdi = xgifb_epllcd_crt1_v; break; case 2: tempdi = XGI_EPLLCDDataPtr; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index ace8ac4bb14..419288e1f64 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1828,18 +1828,33 @@ static struct XGI330_LCDDataTablStruct xgifb_lcddldes[] = { {0xFF, 0x0000, 0x0000, 0} }; -static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1[] = { - {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1 */ - {Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2 */ - {Panel_1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDSCRT11280x1024_1 */ - {Panel_1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDSCRT11280x1024_2 */ - {Panel_1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDSCRT11400x1050_1 */ - {Panel_1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDSCRT11400x1050_2 */ - {Panel_1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDSCRT11600x1200_1 */ - {Panel_1024x768x75, 0x0018, 0x0000, 7}, /* XGI_LVDSCRT11024x768_1x75 */ - {Panel_1024x768x75, 0x0018, 0x0010, 8}, /* XGI_LVDSCRT11024x768_2x75 */ - {Panel_1280x1024x75, 0x0018, 0x0000, 9}, /*XGI_LVDSCRT11280x1024_1x75*/ - {Panel_1280x1024x75, 0x0018, 0x0010, 10},/*XGI_LVDSCRT11280x1024_2x75*/ +static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_h[] = { + {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1_H */ + {Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2_H */ + {Panel_1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDSCRT11280x1024_1_H */ + {Panel_1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDSCRT11280x1024_2_H */ + {Panel_1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDSCRT11400x1050_1_H */ + {Panel_1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDSCRT11400x1050_2_H */ + {Panel_1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDSCRT11600x1200_1_H */ + {Panel_1024x768x75, 0x0018, 0x0000, 7}, /* XGI_LVDSCRT11024x768_1_Hx75 */ + {Panel_1024x768x75, 0x0018, 0x0010, 8}, /* XGI_LVDSCRT11024x768_2_Hx75 */ + {Panel_1280x1024x75, 0x0018, 0x0000, 9}, /*XGI_LVDSCRT11280x1024_1_Hx75 */ + {Panel_1280x1024x75, 0x0018, 0x0010, 10},/*XGI_LVDSCRT11280x1024_2_Hx75 */ + {0xFF, 0x0000, 0x0000, 0} +}; + +static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_v[] = { + {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1_V */ + {Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2_V */ + {Panel_1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDSCRT11280x1024_1_V */ + {Panel_1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDSCRT11280x1024_2_V */ + {Panel_1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDSCRT11400x1050_1_V */ + {Panel_1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDSCRT11400x1050_2_V */ + {Panel_1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDSCRT11600x1200_1_V */ + {Panel_1024x768x75, 0x0018, 0x0000, 7}, /* XGI_LVDSCRT11024x768_1_Vx75 */ + {Panel_1024x768x75, 0x0018, 0x0010, 8}, /* XGI_LVDSCRT11024x768_2_Vx75 */ + {Panel_1280x1024x75, 0x0018, 0x0000, 9}, /*XGI_LVDSCRT11280x1024_1_Vx75 */ + {Panel_1280x1024x75, 0x0018, 0x0010, 10},/*XGI_LVDSCRT11280x1024_2_Vx75 */ {0xFF, 0x0000, 0x0000, 0} }; -- cgit v1.2.3 From 4736783cca01e22f767e402bd2ed237b527f1c6b Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:44 +0200 Subject: staging: xgifb: XGI_GetLcdPtr: use real pointers for data tables Use real pointers for LCD data tables to simplify the code. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 317 +------------------------------------ drivers/staging/xgifb/vb_struct.h | 2 +- drivers/staging/xgifb/vb_table.h | 245 ++++++++++++++-------------- 3 files changed, 119 insertions(+), 445 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index bc341946788..276cd1537e0 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1310,7 +1310,7 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short i, tempdx, tempbx, tempal, modeflag, table; + unsigned short i, tempdx, tempbx, tempal, modeflag; struct XGI330_LCDDataTablStruct *tempdi = NULL; @@ -1365,7 +1365,6 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, if (tempdi == NULL) /* OEMUtil */ return NULL; - table = tempbx; i = 0; while (tempdi[i].PANELID != 0xff) { @@ -1392,319 +1391,7 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, i++; } - if (table == 0) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_LVDSCRT11024x768_1_H[tempal]; - break; - case 1: - return &XGI_LVDSCRT11024x768_2_H[tempal]; - break; - case 2: - return &XGI_LVDSCRT11280x1024_1_H[tempal]; - break; - case 3: - return &XGI_LVDSCRT11280x1024_2_H[tempal]; - break; - case 4: - return &XGI_LVDSCRT11400x1050_1_H[tempal]; - break; - case 5: - return &XGI_LVDSCRT11400x1050_2_H[tempal]; - break; - case 6: - return &XGI_LVDSCRT11600x1200_1_H[tempal]; - break; - case 7: - return &XGI_LVDSCRT11024x768_1_Hx75[tempal]; - break; - case 8: - return &XGI_LVDSCRT11024x768_2_Hx75[tempal]; - break; - case 9: - return &XGI_LVDSCRT11280x1024_1_Hx75[tempal]; - break; - case 10: - return &XGI_LVDSCRT11280x1024_2_Hx75[tempal]; - break; - default: - break; - } - } else if (table == 1) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_LVDSCRT11024x768_1_V[tempal]; - break; - case 1: - return &XGI_LVDSCRT11024x768_2_V[tempal]; - break; - case 2: - return &XGI_LVDSCRT11280x1024_1_V[tempal]; - break; - case 3: - return &XGI_LVDSCRT11280x1024_2_V[tempal]; - break; - case 4: - return &XGI_LVDSCRT11400x1050_1_V[tempal]; - break; - case 5: - return &XGI_LVDSCRT11400x1050_2_V[tempal]; - break; - case 6: - return &XGI_LVDSCRT11600x1200_1_V[tempal]; - break; - case 7: - return &XGI_LVDSCRT11024x768_1_Vx75[tempal]; - break; - case 8: - return &XGI_LVDSCRT11024x768_2_Vx75[tempal]; - break; - case 9: - return &XGI_LVDSCRT11280x1024_1_Vx75[tempal]; - break; - case 10: - return &XGI_LVDSCRT11280x1024_2_Vx75[tempal]; - break; - default: - break; - } - } else if (table == 2) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_LVDS1024x768Data_1[tempal]; - break; - case 1: - return &XGI_LVDS1024x768Data_2[tempal]; - break; - case 2: - return &XGI_LVDS1280x1024Data_1[tempal]; - break; - case 3: - return &XGI_LVDS1280x1024Data_2[tempal]; - break; - case 4: - return &XGI_LVDS1400x1050Data_1[tempal]; - break; - case 5: - return &XGI_LVDS1400x1050Data_2[tempal]; - break; - case 6: - return &XGI_LVDS1600x1200Data_1[tempal]; - break; - case 7: - return &XGI_LVDSNoScalingData[tempal]; - break; - case 8: - return &XGI_LVDS1024x768Data_1x75[tempal]; - break; - case 9: - return &XGI_LVDS1024x768Data_2x75[tempal]; - break; - case 10: - return &XGI_LVDS1280x1024Data_1x75[tempal]; - break; - case 11: - return &XGI_LVDS1280x1024Data_2x75[tempal]; - break; - case 12: - return &XGI_LVDSNoScalingDatax75[tempal]; - break; - default: - break; - } - } else if (table == 3) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_LVDS1024x768Des_1[tempal]; - break; - case 1: - return &XGI_LVDS1024x768Des_3[tempal]; - break; - case 2: - return &XGI_LVDS1024x768Des_2[tempal]; - break; - case 3: - return &XGI_LVDS1280x1024Des_1[tempal]; - break; - case 4: - return &XGI_LVDS1280x1024Des_2[tempal]; - break; - case 5: - return &XGI_LVDS1400x1050Des_1[tempal]; - break; - case 6: - return &XGI_LVDS1400x1050Des_2[tempal]; - break; - case 7: - return &XGI_LVDS1600x1200Des_1[tempal]; - break; - case 8: - return &XGI_LVDSNoScalingDesData[tempal]; - break; - case 9: - return &XGI_LVDS1024x768Des_1x75[tempal]; - break; - case 10: - return &XGI_LVDS1024x768Des_3x75[tempal]; - break; - case 11: - return &XGI_LVDS1024x768Des_2x75[tempal]; - break; - case 12: - return &XGI_LVDS1280x1024Des_1x75[tempal]; - break; - case 13: - return &XGI_LVDS1280x1024Des_2x75[tempal]; - break; - case 14: - return &XGI_LVDSNoScalingDesDatax75[tempal]; - break; - default: - break; - } - } else if (table == 4) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_ExtLCD1024x768Data[tempal]; - break; - case 1: - return &XGI_StLCD1024x768Data[tempal]; - break; - case 2: - return &XGI_CetLCD1024x768Data[tempal]; - break; - case 3: - return &XGI_ExtLCD1280x1024Data[tempal]; - break; - case 4: - return &XGI_StLCD1280x1024Data[tempal]; - break; - case 5: - return &XGI_CetLCD1280x1024Data[tempal]; - break; - case 6: - case 7: - return &xgifb_lcd_1400x1050[tempal]; - break; - case 8: - return &XGI_CetLCD1400x1050Data[tempal]; - break; - case 9: - return &XGI_ExtLCD1600x1200Data[tempal]; - break; - case 10: - return &XGI_StLCD1600x1200Data[tempal]; - break; - case 11: - return &XGI_NoScalingData[tempal]; - break; - case 12: - return &XGI_ExtLCD1024x768x75Data[tempal]; - break; - case 13: - return &XGI_ExtLCD1024x768x75Data[tempal]; - break; - case 14: - return &XGI_CetLCD1024x768x75Data[tempal]; - break; - case 15: - case 16: - return &xgifb_lcd_1280x1024x75[tempal]; - break; - case 17: - return &XGI_CetLCD1280x1024x75Data[tempal]; - break; - case 18: - return &XGI_NoScalingDatax75[tempal]; - break; - default: - break; - } - } else if (table == 5 && ((pVBInfo->VBType & VB_SIS301LV) || - (pVBInfo->VBType & VB_SIS302LV))) { - switch (tempdi[i].DATAPTR) { - case 0: return &XGI_ExtLCDDes1024x768Data[tempal]; - case 1: return &XGI_StLCDDes1024x768Data[tempal]; - case 2: return &XGI_CetLCDDes1024x768Data[tempal]; - case 3: return &XGI_ExtLCDDLDes1280x1024Data[tempal]; - case 4: return &XGI_StLCDDLDes1280x1024Data[tempal]; - case 5: return &XGI_CetLCDDLDes1280x1024Data[tempal]; - case 6: - case 7: return &xgifb_lcddldes_1400x1050[tempal]; - case 8: return &XGI_CetLCDDes1400x1050Data[tempal]; - case 9: return &XGI_CetLCDDes1400x1050Data2[tempal]; - case 10: return &XGI_ExtLCDDLDes1600x1200Data[tempal]; - case 11: return &XGI_StLCDDLDes1600x1200Data[tempal]; - case 12: return &XGI_NoScalingDesData[tempal]; - case 13: - case 14: return &xgifb_lcddes_1024x768x75[tempal]; - case 15: return &XGI_CetLCDDes1024x768x75Data[tempal]; - case 16: - case 17: return &xgifb_lcddldes_1280x1024x75[tempal]; - case 18: return &XGI_CetLCDDLDes1280x1024x75Data[tempal]; - case 19: return &XGI_NoScalingDesDatax75[tempal]; - } - } else if (table == 5) { - switch (tempdi[i].DATAPTR) { - case 0: - return &XGI_ExtLCDDes1024x768Data[tempal]; - break; - case 1: - return &XGI_StLCDDes1024x768Data[tempal]; - break; - case 2: - return &XGI_CetLCDDes1024x768Data[tempal]; - break; - case 3: - return &XGI_ExtLCDDes1280x1024Data[tempal]; - break; - case 4: - return &XGI_StLCDDes1280x1024Data[tempal]; - break; - case 5: - return &XGI_CetLCDDes1280x1024Data[tempal]; - break; - case 6: - case 7: - return &xgifb_lcddes_1400x1050[tempal]; - break; - case 8: - return &XGI_CetLCDDes1400x1050Data[tempal]; - break; - case 9: - return &XGI_CetLCDDes1400x1050Data2[tempal]; - break; - case 10: - return &XGI_ExtLCDDes1600x1200Data[tempal]; - break; - case 11: - return &XGI_StLCDDes1600x1200Data[tempal]; - break; - case 12: - return &XGI_NoScalingDesData[tempal]; - break; - case 13: - case 14: - return &xgifb_lcddes_1024x768x75[tempal]; - break; - case 15: - return &XGI_CetLCDDes1024x768x75Data[tempal]; - break; - case 16: - case 17: - return &xgifb_lcddes_1280x1024x75[tempal]; - break; - case 18: - return &XGI_CetLCDDes1280x1024x75Data[tempal]; - break; - case 19: - return &XGI_NoScalingDesDatax75[tempal]; - break; - default: - break; - } - } - return NULL; + return tempdi[i].DATAPTR; } static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeNo, diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 70158c2c68a..c6f032bc662 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -56,7 +56,7 @@ struct XGI330_LCDDataTablStruct { unsigned char PANELID; unsigned short MASK; unsigned short CAP; - unsigned short DATAPTR; + void *DATAPTR; }; struct XGI330_TVDataTablStruct { diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 419288e1f64..d3fadf7f551 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1749,153 +1749,140 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = { /*add for new UNIVGABIOS*/ static struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = { - {Panel_1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCD1024x768Data */ - {Panel_1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCD1024x768Data */ - {Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCD1024x768Data */ - {Panel_1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCD1280x1024Data */ - {Panel_1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCD1280x1024Data */ - {Panel_1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCD1280x1024Data */ - {Panel_1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCD1400x1050Data */ - {Panel_1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCD1400x1050Data */ - {Panel_1400x1050, 0x0018, 0x0010, 8}, /* XGI_CetLCD1400x1050Data */ - {Panel_1600x1200, 0x0019, 0x0001, 9}, /* XGI_ExtLCD1600x1200Data */ - {Panel_1600x1200, 0x0019, 0x0000, 10}, /* XGI_StLCD1600x1200Data */ - {PanelRef60Hz, 0x0008, 0x0008, 11}, /* XGI_NoScalingData */ - {Panel_1024x768x75, 0x0019, 0x0001, 12}, /* XGI_ExtLCD1024x768x75Data */ - {Panel_1024x768x75, 0x0019, 0x0000, 13}, /* XGI_StLCD1024x768x75Data */ - {Panel_1024x768x75, 0x0018, 0x0010, 14}, /* XGI_CetLCD1024x768x75Data */ - /* XGI_ExtLCD1280x1024x75Data */ - {Panel_1280x1024x75, 0x0019, 0x0001, 15}, - /* XGI_StLCD1280x1024x75Data */ - {Panel_1280x1024x75, 0x0019, 0x0000, 16}, - /* XGI_CetLCD1280x1024x75Data */ - {Panel_1280x1024x75, 0x0018, 0x0010, 17}, - {PanelRef75Hz, 0x0008, 0x0008, 18}, /* XGI_NoScalingDatax75 */ - {0xFF, 0x0000, 0x0000, 0} /* End of table */ + {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCD1024x768Data }, + {Panel_1024x768, 0x0019, 0x0000, XGI_StLCD1024x768Data }, + {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCD1024x768Data }, + {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCD1280x1024Data }, + {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCD1280x1024Data }, + {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCD1280x1024Data }, + {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcd_1400x1050 }, + {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcd_1400x1050 }, + {Panel_1400x1050, 0x0018, 0x0010, XGI_CetLCD1400x1050Data }, + {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCD1600x1200Data }, + {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCD1600x1200Data }, + {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingData }, + {Panel_1024x768x75, 0x0019, 0x0001, XGI_ExtLCD1024x768x75Data }, + {Panel_1024x768x75, 0x0019, 0x0000, XGI_ExtLCD1024x768x75Data }, + {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCD1024x768x75Data }, + {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcd_1280x1024x75 }, + {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcd_1280x1024x75 }, + {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCD1280x1024x75Data }, + {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDatax75 }, + {0xFF, 0x0000, 0x0000, NULL } /* End of table */ }; static struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = { - {Panel_1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCDDes1024x768Data */ - {Panel_1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCDDes1024x768Data */ - {Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCDDes1024x768Data */ - {Panel_1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCDDes1280x1024Data */ - {Panel_1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCDDes1280x1024Data */ - {Panel_1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCDDes1280x1024Data */ - {Panel_1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCDDes1400x1050Data */ - {Panel_1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCDDes1400x1050Data */ - {Panel_1400x1050, 0x0418, 0x0010, 8}, /* XGI_CetLCDDes1400x1050Data */ - {Panel_1400x1050, 0x0418, 0x0410, 9}, /* XGI_CetLCDDes1400x1050Data2 */ - {Panel_1600x1200, 0x0019, 0x0001, 10}, /* XGI_ExtLCDDes1600x1200Data */ - {Panel_1600x1200, 0x0019, 0x0000, 11}, /* XGI_StLCDDes1600x1200Data */ - {PanelRef60Hz, 0x0008, 0x0008, 12}, /* XGI_NoScalingDesData */ - /* XGI_ExtLCDDes1024x768x75Data */ - {Panel_1024x768x75, 0x0019, 0x0001, 13}, - /* XGI_StLCDDes1024x768x75Data */ - {Panel_1024x768x75, 0x0019, 0x0000, 14}, - /* XGI_CetLCDDes1024x768x75Data */ - {Panel_1024x768x75, 0x0018, 0x0010, 15}, - /* XGI_ExtLCDDes1280x1024x75Data */ - {Panel_1280x1024x75, 0x0019, 0x0001, 16}, - /* XGI_StLCDDes1280x1024x75Data */ - {Panel_1280x1024x75, 0x0019, 0x0000, 17}, - /* XGI_CetLCDDes1280x1024x75Data */ - {Panel_1280x1024x75, 0x0018, 0x0010, 18}, - {PanelRef75Hz, 0x0008, 0x0008, 19}, /* XGI_NoScalingDesDatax75 */ - {0xFF, 0x0000, 0x0000, 0} + {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCDDes1024x768Data }, + {Panel_1024x768, 0x0019, 0x0000, XGI_StLCDDes1024x768Data }, + {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCDDes1024x768Data }, + {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCDDes1280x1024Data }, + {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCDDes1280x1024Data }, + {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCDDes1280x1024Data }, + {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcddes_1400x1050 }, + {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcddes_1400x1050 }, + {Panel_1400x1050, 0x0418, 0x0010, XGI_CetLCDDes1400x1050Data }, + {Panel_1400x1050, 0x0418, 0x0410, XGI_CetLCDDes1400x1050Data2 }, + {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCDDes1600x1200Data }, + {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCDDes1600x1200Data }, + {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingDesData }, + {Panel_1024x768x75, 0x0019, 0x0001, xgifb_lcddes_1024x768x75 }, + {Panel_1024x768x75, 0x0019, 0x0000, xgifb_lcddes_1024x768x75 }, + {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCDDes1024x768x75Data }, + {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcddes_1280x1024x75 }, + {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcddes_1280x1024x75 }, + {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCDDes1280x1024x75Data }, + {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDesDatax75 }, + {0xFF, 0x0000, 0x0000, NULL } }; static struct XGI330_LCDDataTablStruct xgifb_lcddldes[] = { - {Panel_1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCDDes1024x768Data */ - {Panel_1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCDDes1024x768Data */ - {Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCDDes1024x768Data */ - {Panel_1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCDDLDes1280x1024Data */ - {Panel_1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCDDLDes1280x1024Data */ - {Panel_1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCDDLDes1280x1024Data */ - {Panel_1400x1050, 0x0019, 0x0001, 6}, /* xgifb_lcddldes_1400x1050 */ - {Panel_1400x1050, 0x0019, 0x0000, 7}, /* xgifb_lcddldes_1400x1050 */ - {Panel_1400x1050, 0x0418, 0x0010, 8}, /* XGI_CetLCDDes1400x1050Data */ - {Panel_1400x1050, 0x0418, 0x0410, 9}, /* XGI_CetLCDDes1400x1050Data2 */ - {Panel_1600x1200, 0x0019, 0x0001, 10}, /* XGI_ExtLCDDLDes1600x1200Data */ - {Panel_1600x1200, 0x0019, 0x0000, 11}, /* XGI_StLCDDes1600x1200Data */ - {PanelRef60Hz, 0x0008, 0x0008, 12}, /* XGI_NoScalingDesData */ - {Panel_1024x768x75, 0x0019, 0x0001, 13}, /* xgifb_lcddes_1024x768x75 */ - {Panel_1024x768x75, 0x0019, 0x0000, 14}, /* xgifb_lcddes_1024x768x75 */ - {Panel_1024x768x75, 0x0018, 0x0010, 15}, /* XGI_CetLCDDes1024x768x75Data */ - {Panel_1280x1024x75, 0x0019, 0x0001, 16}, /* xgifb_lcddldes_1280x1024x75 */ - {Panel_1280x1024x75, 0x0019, 0x0000, 17}, /* xgifb_lcddldes_1280x1024x75 */ - {Panel_1280x1024x75, 0x0018, 0x0010, 18}, /* XGI_CetLCDDes1280x1024x75Data */ - {PanelRef75Hz, 0x0008, 0x0008, 19}, /* XGI_NoScalingDesDatax75 */ - {0xFF, 0x0000, 0x0000, 0} + {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCDDes1024x768Data }, + {Panel_1024x768, 0x0019, 0x0000, XGI_StLCDDes1024x768Data }, + {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCDDes1024x768Data }, + {Panel_1280x1024, 0x0019, 0x0001, XGI_ExtLCDDLDes1280x1024Data }, + {Panel_1280x1024, 0x0019, 0x0000, XGI_StLCDDLDes1280x1024Data }, + {Panel_1280x1024, 0x0018, 0x0010, XGI_CetLCDDLDes1280x1024Data }, + {Panel_1400x1050, 0x0019, 0x0001, xgifb_lcddldes_1400x1050 }, + {Panel_1400x1050, 0x0019, 0x0000, xgifb_lcddldes_1400x1050 }, + {Panel_1400x1050, 0x0418, 0x0010, XGI_CetLCDDes1400x1050Data }, + {Panel_1400x1050, 0x0418, 0x0410, XGI_CetLCDDes1400x1050Data2 }, + {Panel_1600x1200, 0x0019, 0x0001, XGI_ExtLCDDLDes1600x1200Data }, + {Panel_1600x1200, 0x0019, 0x0000, XGI_StLCDDLDes1600x1200Data }, + {PanelRef60Hz, 0x0008, 0x0008, XGI_NoScalingDesData }, + {Panel_1024x768x75, 0x0019, 0x0001, xgifb_lcddes_1024x768x75 }, + {Panel_1024x768x75, 0x0019, 0x0000, xgifb_lcddes_1024x768x75 }, + {Panel_1024x768x75, 0x0018, 0x0010, XGI_CetLCDDes1024x768x75Data }, + {Panel_1280x1024x75, 0x0019, 0x0001, xgifb_lcddldes_1280x1024x75 }, + {Panel_1280x1024x75, 0x0019, 0x0000, xgifb_lcddldes_1280x1024x75 }, + {Panel_1280x1024x75, 0x0018, 0x0010, XGI_CetLCDDLDes1280x1024x75Data }, + {PanelRef75Hz, 0x0008, 0x0008, XGI_NoScalingDesDatax75 }, + {0xFF, 0x0000, 0x0000, NULL } }; static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_h[] = { - {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1_H */ - {Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2_H */ - {Panel_1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDSCRT11280x1024_1_H */ - {Panel_1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDSCRT11280x1024_2_H */ - {Panel_1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDSCRT11400x1050_1_H */ - {Panel_1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDSCRT11400x1050_2_H */ - {Panel_1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDSCRT11600x1200_1_H */ - {Panel_1024x768x75, 0x0018, 0x0000, 7}, /* XGI_LVDSCRT11024x768_1_Hx75 */ - {Panel_1024x768x75, 0x0018, 0x0010, 8}, /* XGI_LVDSCRT11024x768_2_Hx75 */ - {Panel_1280x1024x75, 0x0018, 0x0000, 9}, /*XGI_LVDSCRT11280x1024_1_Hx75 */ - {Panel_1280x1024x75, 0x0018, 0x0010, 10},/*XGI_LVDSCRT11280x1024_2_Hx75 */ - {0xFF, 0x0000, 0x0000, 0} + {Panel_1024x768, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_H }, + {Panel_1024x768, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_H }, + {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_H }, + {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_H }, + {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDSCRT11400x1050_1_H }, + {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDSCRT11400x1050_2_H }, + {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDSCRT11600x1200_1_H }, + {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_Hx75 }, + {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_Hx75 }, + {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_Hx75 }, + {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_Hx75 }, + {0xFF, 0x0000, 0x0000, NULL } }; static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_v[] = { - {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1_V */ - {Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2_V */ - {Panel_1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDSCRT11280x1024_1_V */ - {Panel_1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDSCRT11280x1024_2_V */ - {Panel_1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDSCRT11400x1050_1_V */ - {Panel_1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDSCRT11400x1050_2_V */ - {Panel_1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDSCRT11600x1200_1_V */ - {Panel_1024x768x75, 0x0018, 0x0000, 7}, /* XGI_LVDSCRT11024x768_1_Vx75 */ - {Panel_1024x768x75, 0x0018, 0x0010, 8}, /* XGI_LVDSCRT11024x768_2_Vx75 */ - {Panel_1280x1024x75, 0x0018, 0x0000, 9}, /*XGI_LVDSCRT11280x1024_1_Vx75 */ - {Panel_1280x1024x75, 0x0018, 0x0010, 10},/*XGI_LVDSCRT11280x1024_2_Vx75 */ - {0xFF, 0x0000, 0x0000, 0} + {Panel_1024x768, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_V }, + {Panel_1024x768, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_V }, + {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_V }, + {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_V }, + {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDSCRT11400x1050_1_V }, + {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDSCRT11400x1050_2_V }, + {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDSCRT11600x1200_1_V }, + {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_Vx75 }, + {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_Vx75 }, + {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_Vx75 }, + {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDSCRT11280x1024_2_Vx75 }, + {0xFF, 0x0000, 0x0000, NULL } }; static struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] = { - {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Data_1 */ - {Panel_1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDS1024x768Data_2 */ - {Panel_1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDS1280x1024Data_1 */ - {Panel_1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDS1280x1024Data_2 */ - {Panel_1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDS1400x1050Data_1 */ - {Panel_1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDS1400x1050Data_2 */ - {Panel_1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDS1600x1200Data_1 */ - {PanelRef60Hz, 0x0008, 0x0008, 7}, /* XGI_LVDSNoScalingData */ - {Panel_1024x768x75, 0x0018, 0x0000, 8}, /* XGI_LVDS1024x768Data_1x75 */ - {Panel_1024x768x75, 0x0018, 0x0010, 9}, /* XGI_LVDS1024x768Data_2x75 */ - /* XGI_LVDS1280x1024Data_1x75 */ - {Panel_1280x1024x75, 0x0018, 0x0000, 10}, - /* XGI_LVDS1280x1024Data_2x75 */ - {Panel_1280x1024x75, 0x0018, 0x0010, 11}, - {PanelRef75Hz, 0x0008, 0x0008, 12}, /* XGI_LVDSNoScalingDatax75 */ - {0xFF, 0x0000, 0x0000, 0} + {Panel_1024x768, 0x0018, 0x0000, XGI_LVDS1024x768Data_1 }, + {Panel_1024x768, 0x0018, 0x0010, XGI_LVDS1024x768Data_2 }, + {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDS1280x1024Data_1 }, + {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDS1280x1024Data_2 }, + {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDS1400x1050Data_1 }, + {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDS1400x1050Data_2 }, + {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDS1600x1200Data_1 }, + {PanelRef60Hz, 0x0008, 0x0008, XGI_LVDSNoScalingData }, + {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDS1024x768Data_1x75 }, + {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDS1024x768Data_2x75 }, + {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDS1280x1024Data_1x75 }, + {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDS1280x1024Data_2x75 }, + {PanelRef75Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDatax75 }, + {0xFF, 0x0000, 0x0000, NULL } }; static struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] = { - {Panel_1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Des_1 */ - {Panel_1024x768, 0x0618, 0x0410, 1}, /* XGI_LVDS1024x768Des_3 */ - {Panel_1024x768, 0x0018, 0x0010, 2}, /* XGI_LVDS1024x768Des_2 */ - {Panel_1280x1024, 0x0018, 0x0000, 3}, /* XGI_LVDS1280x1024Des_1 */ - {Panel_1280x1024, 0x0018, 0x0010, 4}, /* XGI_LVDS1280x1024Des_2 */ - {Panel_1400x1050, 0x0018, 0x0000, 5}, /* XGI_LVDS1400x1050Des_1 */ - {Panel_1400x1050, 0x0018, 0x0010, 6}, /* XGI_LVDS1400x1050Des_2 */ - {Panel_1600x1200, 0x0018, 0x0000, 7}, /* XGI_LVDS1600x1200Des_1 */ - {PanelRef60Hz, 0x0008, 0x0008, 8}, /* XGI_LVDSNoScalingDesData */ - {Panel_1024x768x75, 0x0018, 0x0000, 9}, /* XGI_LVDS1024x768Des_1x75 */ - {Panel_1024x768x75, 0x0618, 0x0410, 10}, /* XGI_LVDS1024x768Des_3x75 */ - {Panel_1024x768x75, 0x0018, 0x0010, 11}, /* XGI_LVDS1024x768Des_2x75 */ - /* XGI_LVDS1280x1024Des_1x75 */ - {Panel_1280x1024x75, 0x0018, 0x0000, 12}, - /* XGI_LVDS1280x1024Des_2x75 */ - {Panel_1280x1024x75, 0x0018, 0x0010, 13}, - {PanelRef75Hz, 0x0008, 0x0008, 14}, /* XGI_LVDSNoScalingDesDatax75 */ - {0xFF, 0x0000, 0x0000, 0} + {Panel_1024x768, 0x0018, 0x0000, XGI_LVDS1024x768Des_1 }, + {Panel_1024x768, 0x0618, 0x0410, XGI_LVDS1024x768Des_3 }, + {Panel_1024x768, 0x0018, 0x0010, XGI_LVDS1024x768Des_2 }, + {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDS1280x1024Des_1 }, + {Panel_1280x1024, 0x0018, 0x0010, XGI_LVDS1280x1024Des_2 }, + {Panel_1400x1050, 0x0018, 0x0000, XGI_LVDS1400x1050Des_1 }, + {Panel_1400x1050, 0x0018, 0x0010, XGI_LVDS1400x1050Des_2 }, + {Panel_1600x1200, 0x0018, 0x0000, XGI_LVDS1600x1200Des_1 }, + {PanelRef60Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDesData }, + {Panel_1024x768x75, 0x0018, 0x0000, XGI_LVDS1024x768Des_1x75 }, + {Panel_1024x768x75, 0x0618, 0x0410, XGI_LVDS1024x768Des_3x75 }, + {Panel_1024x768x75, 0x0018, 0x0010, XGI_LVDS1024x768Des_2x75 }, + {Panel_1280x1024x75, 0x0018, 0x0000, XGI_LVDS1280x1024Des_1x75 }, + {Panel_1280x1024x75, 0x0018, 0x0010, XGI_LVDS1280x1024Des_2x75 }, + {PanelRef75Hz, 0x0008, 0x0008, XGI_LVDSNoScalingDesDatax75 }, + {0xFF, 0x0000, 0x0000, NULL } }; static const struct XGI330_TVDataTablStruct XGI_TVDataTable[] = { -- cgit v1.2.3 From 6c27b37091f655815d8cfee340f0f7c16b718400 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:45 +0200 Subject: staging: xgifb: XGI_GetLcdPtr: delete redundant code tempal is a write-only stack variable, and code touching it can be deleted. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 276cd1537e0..9aa923cfdfd 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1310,30 +1310,13 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short i, tempdx, tempbx, tempal, modeflag; + unsigned short i, tempdx, tempbx, modeflag; struct XGI330_LCDDataTablStruct *tempdi = NULL; tempbx = BX; modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - - tempal = tempal & 0x0f; - - if (tempbx <= 1) { /* ExpLink */ - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; - - if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { - tempal = pVBInfo->RefIndex[RefreshRateTableIndex]. - Ext_CRT2CRTC2; - } - - if (tempbx & 0x01) - tempal = (tempal >> 4); - - tempal = (tempal & 0x0f); - } switch (tempbx) { case 0: -- cgit v1.2.3 From 9d1c6299251c0489d6103eaf149c48492ae3e26f Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:46 +0200 Subject: staging: xgifb: XGI_GetLcdPtr: pass the table pointer directly Let the caller pass the table pointer directly instead of using a magic number to indicate which table to use. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 93 ++++++++++++-------------------------- 1 file changed, 30 insertions(+), 63 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 9aa923cfdfd..3a99a92316f 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1305,52 +1305,21 @@ static void XGI_GetLVDSResInfo(unsigned short ModeNo, pVBInfo->VDE = yres; } -static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, +static void *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table, + unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { unsigned short i, tempdx, tempbx, modeflag; - struct XGI330_LCDDataTablStruct *tempdi = NULL; - - tempbx = BX; + tempbx = 0; modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - switch (tempbx) { - case 0: - tempdi = xgifb_epllcd_crt1_h; - break; - case 1: - tempdi = xgifb_epllcd_crt1_v; - break; - case 2: - tempdi = XGI_EPLLCDDataPtr; - break; - case 3: - tempdi = XGI_EPLLCDDesDataPtr; - break; - case 4: - tempdi = XGI_LCDDataTable; - break; - case 5: - if ((pVBInfo->VBType & VB_SIS301LV) || - (pVBInfo->VBType & VB_SIS302LV)) - tempdi = xgifb_lcddldes; - else - tempdi = XGI_LCDDesDataTable; - break; - default: - break; - } - - if (tempdi == NULL) /* OEMUtil */ - return NULL; - i = 0; - while (tempdi[i].PANELID != 0xff) { + while (table[i].PANELID != 0xff) { tempdx = pVBInfo->LCDResInfo; if (tempbx & 0x0080) { /* OEMUtil */ tempbx &= (~0x0080); @@ -1360,21 +1329,21 @@ static void *XGI_GetLcdPtr(unsigned short BX, unsigned short ModeNo, if (pVBInfo->LCDInfo & EnableScalingLCD) tempdx &= (~PanelResInfo); - if (tempdi[i].PANELID == tempdx) { - tempbx = tempdi[i].MASK; + if (table[i].PANELID == tempdx) { + tempbx = table[i].MASK; tempdx = pVBInfo->LCDInfo; if (modeflag & HalfDCLK) tempdx |= SetLCDLowResolution; tempbx &= tempdx; - if (tempbx == tempdi[i].CAP) + if (tempbx == table[i].CAP) break; } i++; } - return tempdi[i].DATAPTR; + return table[i].DATAPTR; } static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeNo, @@ -1411,13 +1380,10 @@ static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short tempbx; struct SiS_LVDSData *LCDPtr = NULL; - tempbx = 2; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, + LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDataPtr, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); pVBInfo->VGAHT = LCDPtr->VGAHT; pVBInfo->VGAVT = LCDPtr->VGAVT; @@ -1454,17 +1420,15 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned char index; - unsigned short tempbx, i; + unsigned short i; struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL; struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL; index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; index = index & IndexMask; - tempbx = 0; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, + LCDPtr = XGI_GetLcdPtr(xgifb_epllcd_crt1_h, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); for (i = 0; i < 8; i++) @@ -1473,11 +1437,10 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); - tempbx = 1; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr1 = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); + LCDPtr1 = XGI_GetLcdPtr(xgifb_epllcd_crt1_v, ModeNo, + ModeIdIndex, RefreshRateTableIndex, + pVBInfo); for (i = 0; i < 7; i++) pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i]; } @@ -1567,13 +1530,14 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL; modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempbx = 3; if (pVBInfo->LCDInfo & EnableScalingLCD) - LCDPtr1 = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); + LCDPtr1 = XGI_GetLcdPtr(XGI_EPLLCDDesDataPtr, ModeNo, + ModeIdIndex, RefreshRateTableIndex, + pVBInfo); else - LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); + LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDesDataPtr, ModeNo, + ModeIdIndex, RefreshRateTableIndex, + pVBInfo); XGI_GetLCDSync(&tempax, &tempbx, pVBInfo); push1 = tempbx; @@ -2804,7 +2768,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - unsigned short tempax = 0, tempbx, modeflag, resinfo; + unsigned short tempax = 0, tempbx = 0, modeflag, resinfo; struct SiS_LCDData *LCDPtr = NULL; @@ -2820,10 +2784,8 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, return; } - tempbx = 4; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, + LCDPtr = XGI_GetLcdPtr(XGI_LCDDataTable, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo); pVBInfo->RVBHCMAX = LCDPtr->RVBHCMAX; @@ -4059,9 +4021,14 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_and_or(pVBInfo->Part2Port, 0x18, 0xDF, 0x00); /* Customized LCDB Does not add */ - tempbx = 5; - LCDBDesPtr = XGI_GetLcdPtr(tempbx, ModeNo, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); + if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) + LCDBDesPtr = XGI_GetLcdPtr(xgifb_lcddldes, ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); + else + LCDBDesPtr = XGI_GetLcdPtr(XGI_LCDDesDataTable, ModeNo, + ModeIdIndex, RefreshRateTableIndex, + pVBInfo); + tempah = pVBInfo->LCDResInfo; tempah &= PanelResInfo; -- cgit v1.2.3 From bdc9eb142cedda1dad47cea8b4112d5f03913ed2 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:47 +0200 Subject: staging: xgifb: constify LCD data Make read-only LCD data tables const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 16 +-- drivers/staging/xgifb/vb_struct.h | 4 +- drivers/staging/xgifb/vb_table.h | 194 ++++++++++++++++++------------------- 3 files changed, 107 insertions(+), 107 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 3a99a92316f..33d5aa0ab58 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1305,7 +1305,7 @@ static void XGI_GetLVDSResInfo(unsigned short ModeNo, pVBInfo->VDE = yres; } -static void *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table, +static void const *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, @@ -1380,7 +1380,7 @@ static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - struct SiS_LVDSData *LCDPtr = NULL; + struct SiS_LVDSData const *LCDPtr = NULL; if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDataPtr, ModeNo, ModeIdIndex, @@ -1421,8 +1421,8 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned char index; unsigned short i; - struct XGI_LVDSCRT1HDataStruct *LCDPtr = NULL; - struct XGI_LVDSCRT1VDataStruct *LCDPtr1 = NULL; + struct XGI_LVDSCRT1HDataStruct const *LCDPtr = NULL; + struct XGI_LVDSCRT1VDataStruct const *LCDPtr1 = NULL; index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; index = index & IndexMask; @@ -1526,8 +1526,8 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned short tempbx, tempax, tempcx, tempdx, push1, push2, modeflag; unsigned long temp, temp1, temp2, temp3, push3; - struct XGI_LCDDesStruct *LCDPtr = NULL; - struct XGI330_LCDDataDesStruct2 *LCDPtr1 = NULL; + struct XGI_LCDDesStruct const *LCDPtr = NULL; + struct XGI330_LCDDataDesStruct2 const *LCDPtr1 = NULL; modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; if (pVBInfo->LCDInfo & EnableScalingLCD) @@ -2770,7 +2770,7 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned short tempax = 0, tempbx = 0, modeflag, resinfo; - struct SiS_LCDData *LCDPtr = NULL; + struct SiS_LCDData const *LCDPtr = NULL; /* si+Ext_ResInfo */ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; @@ -3975,7 +3975,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short push1, push2, pushbx, tempax, tempbx, tempcx, temp, tempah, tempbh, tempch, resinfo, modeflag, CRT1Index; - struct XGI_LCDDesStruct *LCDBDesPtr = NULL; + struct XGI_LCDDesStruct const *LCDBDesPtr = NULL; /* si+Ext_ResInfo */ modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index c6f032bc662..642141994e4 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -56,7 +56,7 @@ struct XGI330_LCDDataTablStruct { unsigned char PANELID; unsigned short MASK; unsigned short CAP; - void *DATAPTR; + void const *DATAPTR; }; struct XGI330_TVDataTablStruct { @@ -178,7 +178,7 @@ struct vb_device_info { unsigned char *pXGINew_DRAMTypeDefinition; unsigned char XGINew_CR97; - struct XGI330_LCDCapStruct *LCDCapList; + struct XGI330_LCDCapStruct const *LCDCapList; struct XGI_TimingHStruct *TimingH; struct XGI_TimingVStruct *TimingV; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index d3fadf7f551..89638c743ed 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -404,7 +404,7 @@ static struct XGI_CRT1TableStruct XGI_CRT1Table[] = { }; /*add for new UNIVGABIOS*/ -static struct SiS_LCDData XGI_StLCD1024x768Data[] = { +static const struct SiS_LCDData XGI_StLCD1024x768Data[] = { {62, 25, 800, 546, 1344, 806}, {32, 15, 930, 546, 1344, 806}, {62, 25, 800, 546, 1344, 806}, /*chiawenfordot9->dot8*/ @@ -414,7 +414,7 @@ static struct SiS_LCDData XGI_StLCD1024x768Data[] = { {1, 1, 1344, 806, 1344, 806} }; -static struct SiS_LCDData XGI_ExtLCD1024x768Data[] = { +static const struct SiS_LCDData XGI_ExtLCD1024x768Data[] = { {42, 25, 1536, 419, 1344, 806}, {48, 25, 1536, 369, 1344, 806}, {42, 25, 1536, 419, 1344, 806}, @@ -430,7 +430,7 @@ static struct SiS_LCDData XGI_ExtLCD1024x768Data[] = { {1, 1, 1344, 806, 1344, 806} }; -static struct SiS_LCDData XGI_CetLCD1024x768Data[] = { +static const struct SiS_LCDData XGI_CetLCD1024x768Data[] = { {1, 1, 1344, 806, 1344, 806}, /* ; 00 (320x200,320x400, 640x200,640x400) */ {1, 1, 1344, 806, 1344, 806}, /* 01 (320x350,640x350) */ @@ -441,7 +441,7 @@ static struct SiS_LCDData XGI_CetLCD1024x768Data[] = { {1, 1, 1344, 806, 1344, 806} /* 06 (1024x768x60Hz) */ }; -static struct SiS_LCDData XGI_StLCD1280x1024Data[] = { +static const struct SiS_LCDData XGI_StLCD1280x1024Data[] = { {22, 5, 800, 510, 1650, 1088}, {22, 5, 800, 510, 1650, 1088}, {176, 45, 900, 510, 1650, 1088}, @@ -452,7 +452,7 @@ static struct SiS_LCDData XGI_StLCD1280x1024Data[] = { {1, 1, 1688, 1066, 1688, 1066} }; -static struct SiS_LCDData XGI_ExtLCD1280x1024Data[] = { +static const struct SiS_LCDData XGI_ExtLCD1280x1024Data[] = { {211, 60, 1024, 501, 1688, 1066}, {211, 60, 1024, 508, 1688, 1066}, {211, 60, 1024, 501, 1688, 1066}, @@ -463,7 +463,7 @@ static struct SiS_LCDData XGI_ExtLCD1280x1024Data[] = { {1, 1, 1688, 1066, 1688, 1066} }; -static struct SiS_LCDData XGI_CetLCD1280x1024Data[] = { +static const struct SiS_LCDData XGI_CetLCD1280x1024Data[] = { {1, 1, 1688, 1066, 1688, 1066}, /* 00 (320x200,320x400, 640x200,640x400) */ {1, 1, 1688, 1066, 1688, 1066}, /* 01 (320x350,640x350) */ @@ -476,7 +476,7 @@ static struct SiS_LCDData XGI_CetLCD1280x1024Data[] = { {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */ }; -static struct SiS_LCDData xgifb_lcd_1400x1050[] = { +static const struct SiS_LCDData xgifb_lcd_1400x1050[] = { {211, 100, 2100, 408, 1688, 1066}, /* 00 (320x200,320x400, 640x200,640x400) */ {211, 64, 1536, 358, 1688, 1066}, /* 01 (320x350,640x350) */ @@ -490,7 +490,7 @@ static struct SiS_LCDData xgifb_lcd_1400x1050[] = { {1, 1, 1688, 1066, 1688, 1066} /* 08 (1400x1050x60Hz) */ }; -static struct SiS_LCDData XGI_ExtLCD1600x1200Data[] = { +static const struct SiS_LCDData XGI_ExtLCD1600x1200Data[] = { {4, 1, 1620, 420, 2160, 1250}, /* 00 (320x200,320x400, 640x200,640x400)*/ {27, 7, 1920, 375, 2160, 1250}, /* 01 (320x350,640x350) */ @@ -504,7 +504,7 @@ static struct SiS_LCDData XGI_ExtLCD1600x1200Data[] = { {1, 1, 2160, 1250, 2160, 1250} /* 09 (1600x1200x60Hz) ;302lv */ }; -static struct SiS_LCDData XGI_StLCD1600x1200Data[] = { +static const struct SiS_LCDData XGI_StLCD1600x1200Data[] = { {27, 4, 800, 500, 2160, 1250}, /* 00 (320x200,320x400, 640x200,640x400) */ {27, 4, 800, 500, 2160, 1250}, /* 01 (320x350,640x350) */ @@ -520,7 +520,7 @@ static struct SiS_LCDData XGI_StLCD1600x1200Data[] = { #define XGI_CetLCD1400x1050Data XGI_CetLCD1280x1024Data -static struct SiS_LCDData XGI_NoScalingData[] = { +static const struct SiS_LCDData XGI_NoScalingData[] = { {1, 1, 800, 449, 800, 449}, {1, 1, 800, 449, 800, 449}, {1, 1, 900, 449, 900, 449}, @@ -531,7 +531,7 @@ static struct SiS_LCDData XGI_NoScalingData[] = { {1, 1, 1688, 1066, 1688, 1066} }; -static struct SiS_LCDData XGI_ExtLCD1024x768x75Data[] = { +static const struct SiS_LCDData XGI_ExtLCD1024x768x75Data[] = { {42, 25, 1536, 419, 1344, 806}, /* ; 00 (320x200,320x400, 640x200,640x400) */ {48, 25, 1536, 369, 1344, 806}, /* ; 01 (320x350,640x350) */ @@ -542,7 +542,7 @@ static struct SiS_LCDData XGI_ExtLCD1024x768x75Data[] = { {1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */ }; -static struct SiS_LCDData XGI_CetLCD1024x768x75Data[] = { +static const struct SiS_LCDData XGI_CetLCD1024x768x75Data[] = { {1, 1, 1312, 800, 1312, 800}, /* ; 00 (320x200,320x400, 640x200,640x400) */ {1, 1, 1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */ @@ -553,7 +553,7 @@ static struct SiS_LCDData XGI_CetLCD1024x768x75Data[] = { {1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */ }; -static struct SiS_LCDData xgifb_lcd_1280x1024x75[] = { +static const struct SiS_LCDData xgifb_lcd_1280x1024x75[] = { {211, 60, 1024, 501, 1688, 1066}, /* ; 00 (320x200,320x400, 640x200,640x400) */ {211, 60, 1024, 508, 1688, 1066}, /* ; 01 (320x350,640x350) */ @@ -567,7 +567,7 @@ static struct SiS_LCDData xgifb_lcd_1280x1024x75[] = { #define XGI_CetLCD1280x1024x75Data XGI_CetLCD1280x1024Data -static struct SiS_LCDData XGI_NoScalingDatax75[] = { +static const struct SiS_LCDData XGI_NoScalingDatax75[] = { {1, 1, 800, 449, 800, 449}, /* ; 00 (320x200, 320x400, 640x200, 640x400) */ {1, 1, 800, 449, 800, 449}, /* ; 01 (320x350, 640x350) */ @@ -582,7 +582,7 @@ static struct SiS_LCDData XGI_NoScalingDatax75[] = { {1, 1, 1688, 806, 1688, 806} /* ; 0A (1280x768x75Hz) */ }; -static struct XGI_LCDDesStruct XGI_ExtLCDDes1024x768Data[] = { +static const struct XGI_LCDDesStruct XGI_ExtLCDDes1024x768Data[] = { {9, 1057, 0, 771}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1057, 0, 771}, /* ; 01 (320x350,640x350) */ {9, 1057, 0, 771}, /* ; 02 (360x400,720x400) */ @@ -592,7 +592,7 @@ static struct XGI_LCDDesStruct XGI_ExtLCDDes1024x768Data[] = { {9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_StLCDDes1024x768Data[] = { +static const struct XGI_LCDDesStruct XGI_StLCDDes1024x768Data[] = { {9, 1057, 737, 703}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1057, 686, 651}, /* ; 01 (320x350,640x350) */ {9, 1057, 737, 703}, /* ; 02 (360x400,720x400) */ @@ -602,7 +602,7 @@ static struct XGI_LCDDesStruct XGI_StLCDDes1024x768Data[] = { {9, 1057, 805, 770} /* ; 06 (1024x768x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_CetLCDDes1024x768Data[] = { +static const struct XGI_LCDDesStruct XGI_CetLCDDes1024x768Data[] = { {1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */ {1152, 856, 622, 587}, /* ; 02 (360x400,720x400) */ @@ -612,7 +612,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDes1024x768Data[] = { {0, 1048, 805, 770} /* ; 06 (1024x768x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_ExtLCDDLDes1280x1024Data[] = { +static const struct XGI_LCDDesStruct XGI_ExtLCDDLDes1280x1024Data[] = { {18, 1346, 981, 940}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1346, 926, 865}, /* 01 (320x350,640x350) */ {18, 1346, 981, 940}, /* 02 (360x400,720x400) */ @@ -623,7 +623,7 @@ static struct XGI_LCDDesStruct XGI_ExtLCDDLDes1280x1024Data[] = { {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_StLCDDLDes1280x1024Data[] = { +static const struct XGI_LCDDesStruct XGI_StLCDDLDes1280x1024Data[] = { {18, 1346, 970, 907}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1346, 917, 854}, /* 01 (320x350,640x350) */ {18, 1346, 970, 907}, /* 02 (360x400,720x400) */ @@ -634,7 +634,7 @@ static struct XGI_LCDDesStruct XGI_StLCDDLDes1280x1024Data[] = { {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024Data[] = { +static const struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024Data[] = { {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ {1368, 1008, 752, 711}, /* 02 (360x400,720x400) */ @@ -645,7 +645,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024Data[] = { {18, 1346, 1065, 1024} /* 07 (1280x1024x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_ExtLCDDes1280x1024Data[] = { +static const struct XGI_LCDDesStruct XGI_ExtLCDDes1280x1024Data[] = { {9, 1337, 981, 940}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1337, 926, 884}, /* ; 01 (320x350,640x350) alan, 2003/09/30 */ {9, 1337, 981, 940}, /* ; 02 (360x400,720x400) */ @@ -656,7 +656,7 @@ static struct XGI_LCDDesStruct XGI_ExtLCDDes1280x1024Data[] = { {9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_StLCDDes1280x1024Data[] = { +static const struct XGI_LCDDesStruct XGI_StLCDDes1280x1024Data[] = { {9, 1337, 970, 907}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1337, 917, 854}, /* ; 01 (320x350,640x350) */ {9, 1337, 970, 907}, /* ; 02 (360x400,720x400) */ @@ -667,7 +667,7 @@ static struct XGI_LCDDesStruct XGI_StLCDDes1280x1024Data[] = { {9, 1337, 1065, 1024} /* ; 07 (1280x1024x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024Data[] = { +static const struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024Data[] = { {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ {1368, 1008, 752, 711}, /* 02 (360x400,720x400) */ @@ -678,7 +678,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024Data[] = { {9, 1337, 1065, 1024} /* 07 (1280x1024x60Hz) */ }; -static struct XGI_LCDDesStruct xgifb_lcddldes_1400x1050[] = { +static const struct XGI_LCDDesStruct xgifb_lcddldes_1400x1050[] = { {18, 1464, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1464, 0, 1051}, /* 01 (320x350,640x350) */ {18, 1464, 0, 1051}, /* 02 (360x400,720x400) */ @@ -690,7 +690,7 @@ static struct XGI_LCDDesStruct xgifb_lcddldes_1400x1050[] = { {18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct XGI_LCDDesStruct xgifb_lcddes_1400x1050[] = { +static const struct XGI_LCDDesStruct xgifb_lcddes_1400x1050[] = { {9, 1455, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ {9, 1455, 0, 1051}, /* 01 (320x350,640x350) */ {9, 1455, 0, 1051}, /* 02 (360x400,720x400) */ @@ -702,7 +702,7 @@ static struct XGI_LCDDesStruct xgifb_lcddes_1400x1050[] = { {9, 1455, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data[] = { +static const struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data[] = { {1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */ {1308, 1068, 781, 766}, /* 01 (320x350,640x350) */ {1308, 1068, 781, 766}, /* 02 (360x400,720x400) */ @@ -714,7 +714,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data[] = { {18, 1464, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data2[] = { +static const struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data2[] = { {0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ {0, 1448, 0, 1051}, /* 01 (320x350,640x350) */ {0, 1448, 0, 1051}, /* 02 (360x400,720x400) */ @@ -722,7 +722,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDes1400x1050Data2[] = { {0, 1448, 0, 1051} /* 04 (640x480x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_ExtLCDDLDes1600x1200Data[] = { +static const struct XGI_LCDDesStruct XGI_ExtLCDDLDes1600x1200Data[] = { {18, 1682, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1682, 0, 1201}, /* 01 (320x350,640x350) */ {18, 1682, 0, 1201}, /* 02 (360x400,720x400) */ @@ -735,7 +735,7 @@ static struct XGI_LCDDesStruct XGI_ExtLCDDLDes1600x1200Data[] = { {18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_StLCDDLDes1600x1200Data[] = { +static const struct XGI_LCDDesStruct XGI_StLCDDLDes1600x1200Data[] = { {18, 1682, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */ {18, 1682, 1083, 1034}, /* 01 (320x350,640x350) */ {18, 1682, 1150, 1101}, /* 02 (360x400,720x400) */ @@ -748,7 +748,7 @@ static struct XGI_LCDDesStruct XGI_StLCDDLDes1600x1200Data[] = { {18, 1682, 0, 1201} /* 09 (1600x1200x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_ExtLCDDes1600x1200Data[] = { +static const struct XGI_LCDDesStruct XGI_ExtLCDDes1600x1200Data[] = { {9, 1673, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ {9, 1673, 0, 1201}, /* 01 (320x350,640x350) */ {9, 1673, 0, 1201}, /* 02 (360x400,720x400) */ @@ -761,7 +761,7 @@ static struct XGI_LCDDesStruct XGI_ExtLCDDes1600x1200Data[] = { {9, 1673, 0, 1201} /* 09 (1600x1200x60Hz) */ }; -static struct XGI_LCDDesStruct XGI_StLCDDes1600x1200Data[] = { +static const struct XGI_LCDDesStruct XGI_StLCDDes1600x1200Data[] = { {9, 1673, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */ {9, 1673, 1083, 1034}, /* 01 (320x350,640x350) */ {9, 1673, 1150, 1101}, /* 02 (360x400,720x400) */ @@ -774,7 +774,7 @@ static struct XGI_LCDDesStruct XGI_StLCDDes1600x1200Data[] = { {9, 1673, 0, 1201} /* 09 (1600x1200x60Hz) */ }; -static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] = { +static const struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] = { {9, 657, 448, 405, 96, 2}, /* 00 (320x200,320x400, 640x200,640x400) */ {9, 657, 448, 355, 96, 2}, /* 01 (320x350,640x350) */ @@ -790,7 +790,7 @@ static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesData[] = { }; /* ;;1024x768x75Hz */ -static struct XGI_LCDDesStruct xgifb_lcddes_1024x768x75[] = { +static const struct XGI_LCDDesStruct xgifb_lcddes_1024x768x75[] = { {9, 1049, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1049, 0, 769}, /* ; 01 (320x350,640x350) */ {9, 1049, 0, 769}, /* ; 02 (360x400,720x400) */ @@ -801,7 +801,7 @@ static struct XGI_LCDDesStruct xgifb_lcddes_1024x768x75[] = { }; /* ;;1024x768x75Hz */ -static struct XGI_LCDDesStruct XGI_CetLCDDes1024x768x75Data[] = { +static const struct XGI_LCDDesStruct XGI_CetLCDDes1024x768x75Data[] = { {1152, 856, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1152, 856, 597, 562}, /* ; 01 (320x350,640x350) */ {1192, 896, 622, 587}, /* ; 02 (360x400,720x400) */ @@ -812,7 +812,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDes1024x768x75Data[] = { }; /* ;;1280x1024x75Hz */ -static struct XGI_LCDDesStruct xgifb_lcddldes_1280x1024x75[] = { +static const struct XGI_LCDDesStruct xgifb_lcddldes_1280x1024x75[] = { {18, 1314, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ {18, 1314, 0, 1025}, /* ; 01 (320x350,640x350) */ {18, 1314, 0, 1025}, /* ; 02 (360x400,720x400) */ @@ -824,7 +824,7 @@ static struct XGI_LCDDesStruct xgifb_lcddldes_1280x1024x75[] = { }; /* 1280x1024x75Hz */ -static struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = { +static const struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = { {1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */ {1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */ @@ -836,7 +836,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDLDes1280x1024x75Data[] = { }; /* ;;1280x1024x75Hz */ -static struct XGI_LCDDesStruct xgifb_lcddes_1280x1024x75[] = { +static const struct XGI_LCDDesStruct xgifb_lcddes_1280x1024x75[] = { {9, 1305, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ {9, 1305, 0, 1025}, /* ; 01 (320x350,640x350) */ {9, 1305, 0, 1025}, /* ; 02 (360x400,720x400) */ @@ -848,7 +848,7 @@ static struct XGI_LCDDesStruct xgifb_lcddes_1280x1024x75[] = { }; /* 1280x1024x75Hz */ -static struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024x75Data[] = { +static const struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024x75Data[] = { {1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */ {1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */ @@ -860,7 +860,7 @@ static struct XGI_LCDDesStruct XGI_CetLCDDes1280x1024x75Data[] = { }; /* Scaling LCD 75Hz */ -static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = { +static const struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = { {9, 657, 448, 405, 96, 2}, /* ; 00 (320x200,320x400, 640x200,640x400) */ {9, 657, 448, 355, 96, 2}, /* ; 01 (320x350,640x350) */ @@ -1174,7 +1174,7 @@ static const unsigned char XGI330_Ren750pGroup3[] = { 0x18, 0x1D, 0x23, 0x28, 0x4C, 0xAA, 0x01 }; -static struct SiS_LVDSData XGI_LVDS1024x768Data_1[] = { +static const struct SiS_LVDSData XGI_LVDS1024x768Data_1[] = { { 960, 438, 1344, 806}, /* 00 (320x200,320x400,640x200,640x400) */ { 960, 388, 1344, 806}, /* 01 (320x350,640x350) */ {1040, 438, 1344, 806}, /* 02 (360x400,720x400) */ @@ -1185,7 +1185,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Data_1[] = { }; -static struct SiS_LVDSData XGI_LVDS1024x768Data_2[] = { +static const struct SiS_LVDSData XGI_LVDS1024x768Data_2[] = { {1344, 806, 1344, 806}, {1344, 806, 1344, 806}, {1344, 806, 1344, 806}, @@ -1197,7 +1197,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Data_2[] = { {800, 525, 1280, 813} }; -static struct SiS_LVDSData XGI_LVDS1280x1024Data_1[] = { +static const struct SiS_LVDSData XGI_LVDS1280x1024Data_1[] = { {1048, 442, 1688, 1066}, {1048, 392, 1688, 1066}, {1048, 442, 1688, 1066}, @@ -1210,7 +1210,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Data_1[] = { #define XGI_LVDS1280x1024Data_2 XGI_LVDS1024x768Data_2 -static struct SiS_LVDSData XGI_LVDS1400x1050Data_1[] = { +static const struct SiS_LVDSData XGI_LVDS1400x1050Data_1[] = { {928, 416, 1688, 1066}, {928, 366, 1688, 1066}, {928, 416, 1688, 1066}, @@ -1222,7 +1222,7 @@ static struct SiS_LVDSData XGI_LVDS1400x1050Data_1[] = { {1688, 1066, 1688, 1066} }; -static struct SiS_LVDSData XGI_LVDS1400x1050Data_2[] = { +static const struct SiS_LVDSData XGI_LVDS1400x1050Data_2[] = { {1688, 1066, 1688, 1066}, {1688, 1066, 1688, 1066}, {1688, 1066, 1688, 1066}, @@ -1235,7 +1235,7 @@ static struct SiS_LVDSData XGI_LVDS1400x1050Data_2[] = { }; /* ;;[ycchen] 12/05/02 LCDHTxLCDVT=2048x1320 */ -static struct SiS_LVDSData XGI_LVDS1600x1200Data_1[] = { +static const struct SiS_LVDSData XGI_LVDS1600x1200Data_1[] = { {1088, 520, 2048, 1320}, /* 00 (320x200,320x400,640x200,640x400) */ {1088, 470, 2048, 1320}, /* 01 (320x350,640x350) */ {1088, 520, 2048, 1320}, /* 02 (360x400,720x400) */ @@ -1248,7 +1248,7 @@ static struct SiS_LVDSData XGI_LVDS1600x1200Data_1[] = { {2048, 1320, 2048, 1320} /* 09 (1600x1200) */ }; -static struct SiS_LVDSData XGI_LVDSNoScalingData[] = { +static const struct SiS_LVDSData XGI_LVDSNoScalingData[] = { { 800, 449, 800, 449}, /* 00 (320x200,320x400,640x200,640x400) */ { 800, 449, 800, 449}, /* 01 (320x350,640x350) */ { 800, 449, 800, 449}, /* 02 (360x400,720x400) */ @@ -1262,7 +1262,7 @@ static struct SiS_LVDSData XGI_LVDSNoScalingData[] = { {1688, 806, 1688, 806} /* 0A (1280x768x60Hz) */ }; -static struct SiS_LVDSData XGI_LVDS1024x768Data_1x75[] = { +static const struct SiS_LVDSData XGI_LVDS1024x768Data_1x75[] = { { 960, 438, 1312, 800}, /* 00 (320x200,320x400,640x200,640x400) */ { 960, 388, 1312, 800}, /* 01 (320x350,640x350) */ {1040, 438, 1312, 800}, /* 02 (360x400,720x400) */ @@ -1273,7 +1273,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Data_1x75[] = { }; -static struct SiS_LVDSData XGI_LVDS1024x768Data_2x75[] = { +static const struct SiS_LVDSData XGI_LVDS1024x768Data_2x75[] = { {1312, 800, 1312, 800}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */ {1312, 800, 1312, 800}, /* ; 02 (360x400,720x400) */ @@ -1283,7 +1283,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Data_2x75[] = { {1312, 800, 1312, 800}, /* ; 06 (512x384,1024x768) */ }; -static struct SiS_LVDSData XGI_LVDS1280x1024Data_1x75[] = { +static const struct SiS_LVDSData XGI_LVDS1280x1024Data_1x75[] = { {1048, 442, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */ {1048, 392, 1688, 1066 }, /* ; 01 (320x350,640x350) */ {1128, 442, 1688, 1066 }, /* ; 02 (360x400,720x400) */ @@ -1294,7 +1294,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Data_1x75[] = { {1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */ }; -static struct SiS_LVDSData XGI_LVDS1280x1024Data_2x75[] = { +static const struct SiS_LVDSData XGI_LVDS1280x1024Data_2x75[] = { {1688, 1066, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */ {1688, 1066, 1688, 1066 }, /* ; 01 (320x350,640x350) */ {1688, 1066, 1688, 1066 }, /* ; 02 (360x400,720x400) */ @@ -1305,7 +1305,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Data_2x75[] = { {1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */ }; -static struct SiS_LVDSData XGI_LVDSNoScalingDatax75[] = { +static const struct SiS_LVDSData XGI_LVDSNoScalingDatax75[] = { { 800, 449, 800, 449}, /* ; 00 (320x200,320x400,640x200,640x400) */ { 800, 449, 800, 449}, /* ; 01 (320x350,640x350) */ { 900, 449, 900, 449}, /* ; 02 (360x400,720x400) */ @@ -1320,7 +1320,7 @@ static struct SiS_LVDSData XGI_LVDSNoScalingDatax75[] = { {1688, 806, 1688, 806}, /* ; 0A (1280x768x75Hz) */ }; -static struct SiS_LVDSData XGI_LVDS1024x768Des_1[] = { +static const struct SiS_LVDSData XGI_LVDS1024x768Des_1[] = { {0, 1048, 0, 771}, /* 00 (320x200,320x400,640x200,640x400) */ {0, 1048, 0, 771}, /* 01 (320x350,640x350) */ {0, 1048, 0, 771}, /* 02 (360x400,720x400) */ @@ -1330,7 +1330,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Des_1[] = { {0, 1048, 805, 770} /* 06 (1024x768x60Hz) */ } ; -static struct SiS_LVDSData XGI_LVDS1024x768Des_2[] = { +static const struct SiS_LVDSData XGI_LVDS1024x768Des_2[] = { {1142, 856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */ {1142, 856, 597, 562}, /* 01 (320x350,640x350) */ {1142, 856, 622, 587}, /* 02 (360x400,720x400) */ @@ -1340,7 +1340,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Des_2[] = { { 0, 1048, 805, 771} /* 06 (1024x768x60Hz) */ }; -static struct SiS_LVDSData XGI_LVDS1024x768Des_3[] = { +static const struct SiS_LVDSData XGI_LVDS1024x768Des_3[] = { {320, 24, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */ {320, 24, 597, 562}, /* 01 (320x350,640x350) */ {320, 24, 622, 587}, /* 02 (360x400,720x400) */ @@ -1348,7 +1348,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Des_3[] = { {320, 24, 722, 687} /* 04 (640x480x60Hz) */ }; -static struct SiS_LVDSData XGI_LVDS1280x1024Des_1[] = { +static const struct SiS_LVDSData XGI_LVDS1280x1024Des_1[] = { {0, 1328, 0, 1025}, /* 00 (320x200,320x400,640x200,640x400) */ {0, 1328, 0, 1025}, /* 01 (320x350,640x350) */ {0, 1328, 0, 1025}, /* 02 (360x400,720x400) */ @@ -1360,7 +1360,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Des_1[] = { }; /* The Display setting for DE Mode Panel */ -static struct SiS_LVDSData XGI_LVDS1280x1024Des_2[] = { +static const struct SiS_LVDSData XGI_LVDS1280x1024Des_2[] = { {1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */ {1368, 1008, 729, 688}, /* 01 (320x350,640x350) */ {1408, 1048, 752, 711}, /* 02 (360x400,720x400) */ @@ -1371,7 +1371,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Des_2[] = { {0000, 1328, 0, 1025} /* 07 (1280x1024x60Hz) */ }; -static struct SiS_LVDSData XGI_LVDS1400x1050Des_1[] = { +static const struct SiS_LVDSData XGI_LVDS1400x1050Des_1[] = { {0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */ {0, 1448, 0, 1051}, /* 01 (320x350,640x350) */ {0, 1448, 0, 1051}, /* 02 (360x400,720x400) */ @@ -1383,7 +1383,7 @@ static struct SiS_LVDSData XGI_LVDS1400x1050Des_1[] = { {0, 1448, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct SiS_LVDSData XGI_LVDS1400x1050Des_2[] = { +static const struct SiS_LVDSData XGI_LVDS1400x1050Des_2[] = { {1308, 1068, 781, 766}, /* 00 (320x200,320x400,640x200,640x400) */ {1308, 1068, 781, 766}, /* 01 (320x350,640x350) */ {1308, 1068, 781, 766}, /* 02 (360x400,720x400) */ @@ -1395,7 +1395,7 @@ static struct SiS_LVDSData XGI_LVDS1400x1050Des_2[] = { { 0, 1448, 0, 1051} /* 08 (1400x1050x60Hz) */ }; -static struct SiS_LVDSData XGI_LVDS1600x1200Des_1[] = { +static const struct SiS_LVDSData XGI_LVDS1600x1200Des_1[] = { {0, 1664, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */ {0, 1664, 0, 1201}, /* 01 (320x350,640x350) */ {0, 1664, 0, 1201}, /* 02 (360x400,720x400) */ @@ -1408,7 +1408,7 @@ static struct SiS_LVDSData XGI_LVDS1600x1200Des_1[] = { {0, 1664, 0, 1201} /* 09 (1600x1200x60Hz) */ }; -static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] = { +static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] = { {0, 648, 448, 405, 96, 2}, /* 00 (320x200,320x400, 640x200,640x400) */ {0, 648, 448, 355, 96, 2}, /* 01 (320x350,640x350) */ @@ -1424,7 +1424,7 @@ static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesData[] = { }; /* ; 1024x768 Full-screen */ -static struct SiS_LVDSData XGI_LVDS1024x768Des_1x75[] = { +static const struct SiS_LVDSData XGI_LVDS1024x768Des_1x75[] = { {0, 1040, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */ {0, 1040, 0, 769}, /* ; 01 (320x350,640x350) */ {0, 1040, 0, 769}, /* ; 02 (360x400,720x400) */ @@ -1435,7 +1435,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Des_1x75[] = { }; /* ; 1024x768 center-screen (Enh. Mode) */ -static struct SiS_LVDSData XGI_LVDS1024x768Des_2x75[] = { +static const struct SiS_LVDSData XGI_LVDS1024x768Des_2x75[] = { {1142, 856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */ {1142, 856, 597, 562}, /* 01 (320x350,640x350) */ {1142, 856, 622, 587}, /* 02 (360x400,720x400) */ @@ -1446,7 +1446,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Des_2x75[] = { }; /* ; 1024x768 center-screen (St.Mode) */ -static struct SiS_LVDSData XGI_LVDS1024x768Des_3x75[] = { +static const struct SiS_LVDSData XGI_LVDS1024x768Des_3x75[] = { {320, 24, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */ {320, 24, 597, 562}, /* ; 01 (320x350,640x350) */ {320, 24, 622, 587}, /* ; 02 (360x400,720x400) */ @@ -1454,7 +1454,7 @@ static struct SiS_LVDSData XGI_LVDS1024x768Des_3x75[] = { {320, 24, 722, 687} /* ; 04 (640x480x60Hz) */ }; -static struct SiS_LVDSData XGI_LVDS1280x1024Des_1x75[] = { +static const struct SiS_LVDSData XGI_LVDS1280x1024Des_1x75[] = { {0, 1296, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */ {0, 1296, 0, 1025}, /* ; 01 (320x350,640x350) */ {0, 1296, 0, 1025}, /* ; 02 (360x400,720x400) */ @@ -1467,7 +1467,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Des_1x75[] = { /* The Display setting for DE Mode Panel */ /* Set DE as default */ -static struct SiS_LVDSData XGI_LVDS1280x1024Des_2x75[] = { +static const struct SiS_LVDSData XGI_LVDS1280x1024Des_2x75[] = { {1368, 976, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */ {1368, 976, 729, 688}, /* ; 01 (320x350,640x350) */ {1408, 976, 752, 711}, /* ; 02 (360x400,720x400) */ @@ -1479,7 +1479,7 @@ static struct SiS_LVDSData XGI_LVDS1280x1024Des_2x75[] = { }; /* Scaling LCD 75Hz */ -static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = { +static const struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = { {0, 648, 448, 405, 96, 2}, /* ; 00 (320x200,320x400, 640x200,640x400) */ {0, 648, 448, 355, 96, 2}, /* ; 01 (320x350,640x350) */ @@ -1495,7 +1495,7 @@ static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = { }; /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] = { +static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] = { { {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} }, /* 00 (320x) */ { {0x4B, 0x27, 0x8F, 0x2B, 0x03, 0x00, 0x44, 0x00} }, /* 01 (360x) */ { {0x55, 0x31, 0x99, 0x46, 0x1D, 0x00, 0x55, 0x00} }, /* 02 (400x) */ @@ -1507,7 +1507,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_H[] = { }; /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[] = { +static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[] = { { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00 } }, /* 00 (320x) */ { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00 } }, /* 01 (360x) */ { {0x60, 0x31, 0x84, 0x3A, 0x88, 0x00, 0x01, 0x00 } }, /* 02 (400x) */ @@ -1520,7 +1520,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_H[] = { }; /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[] = { +static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[] = { { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} }, /* 00 (320x) */ { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} }, /* 01 (360x) */ { {0x63, 0x31, 0x87, 0x3D, 0x8E, 0x00, 0x01, 0x00} }, /* 02 (400x) */ @@ -1532,7 +1532,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_H[] = { }; /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[] = { +static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[] = { { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} }, /* 00 (320x) */ { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} }, /* 01 (360x) */ { {0x7E, 0x40, 0x84, 0x49, 0x91, 0x00, 0x01, 0x00} }, /* 02 (400x) */ @@ -1545,7 +1545,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_H[] = { }; /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] = { +static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] = { { {0x47, 0x27, 0x8B, 0x2C, 0x1A, 0x00, 0x05, 0x00} }, /* 00 (320x) */ { {0x47, 0x27, 0x8B, 0x30, 0x1E, 0x00, 0x05, 0x00} }, /* 01 (360x) */ { {0x51, 0x31, 0x95, 0x36, 0x04, 0x00, 0x01, 0x00} }, /* 02 (400x) */ @@ -1559,7 +1559,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] = { }; /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] = { +static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] = { { {0x76, 0x3F, 0x83, 0x45, 0x8C, 0x00, 0x41, 0x00} }, /* 00 (320x) */ { {0x76, 0x3F, 0x83, 0x45, 0x8C, 0x00, 0x41, 0x00} }, /* 01 (360x) */ { {0x76, 0x31, 0x9A, 0x48, 0x9F, 0x00, 0x41, 0x00} }, /* 02 (400x) */ @@ -1574,7 +1574,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] = { /* ;302lv channelA [ycchen] 12/05/02 LCDHT=2048 */ /* ; CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] = { +static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] = { { {0x5B, 0x27, 0x9F, 0x32, 0x0A, 0x00, 0x01, 0x00} }, /* 00 (320x) */ { {0x5B, 0x27, 0x9F, 0x32, 0x0A, 0x00, 0x01, 0x00} }, /* 01 (360x) */ { {0x65, 0x31, 0x89, 0x3C, 0x94, 0x00, 0x01, 0x00} }, /* 02 (400x) */ @@ -1589,7 +1589,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] = { }; /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */ -static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] = { +static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] = { { {0x97, 0x1F, 0x60, 0x87, 0x5D, 0x83, 0x10} }, /* 00 (x350) */ { {0xB4, 0x1F, 0x92, 0x89, 0x8F, 0xB5, 0x30} }, /* 01 (x400) */ { {0x04, 0x3E, 0xE2, 0x89, 0xDF, 0x05, 0x00} }, /* 02 (x480) */ @@ -1598,7 +1598,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] = { }; /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] = { +static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] = { { {0x24, 0xBB, 0x31, 0x87, 0x5D, 0x25, 0x30} }, /* 00 (x350) */ { {0x24, 0xBB, 0x4A, 0x80, 0x8F, 0x25, 0x30} }, /* 01 (x400) */ { {0x24, 0xBB, 0x72, 0x88, 0xDF, 0x25, 0x30} }, /* 02 (x480) */ @@ -1607,7 +1607,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] = { }; /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] = { +static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] = { { {0x86, 0x1F, 0x5E, 0x82, 0x5D, 0x87, 0x00} }, /* 00 (x350) */ { {0xB8, 0x1F, 0x90, 0x84, 0x8F, 0xB9, 0x30} }, /* 01 (x400) */ { {0x08, 0x3E, 0xE0, 0x84, 0xDF, 0x09, 0x00} }, /* 02 (x480) */ @@ -1617,7 +1617,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] = { }; /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] = { +static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] = { { {0x28, 0xD2, 0xAF, 0x83, 0xAE, 0xD8, 0xA1} }, /* 00 (x350) */ { {0x28, 0xD2, 0xC8, 0x8C, 0xC7, 0xF2, 0x81} }, /* 01 (x400) */ { {0x28, 0xD2, 0xF0, 0x84, 0xEF, 0x1A, 0xB1} }, /* 02 (x480) */ @@ -1627,7 +1627,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] = { }; /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] = { +static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] = { { {0x6C, 0x1F, 0x60, 0x84, 0x5D, 0x6D, 0x10} }, /* 00 (x350) */ { {0x9E, 0x1F, 0x93, 0x86, 0x8F, 0x9F, 0x30} }, /* 01 (x400) */ { {0xEE, 0x1F, 0xE2, 0x86, 0xDF, 0xEF, 0x10} }, /* 02 (x480) */ @@ -1638,7 +1638,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] = { }; /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] = { +static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] = { { {0x28, 0x92, 0xB6, 0x83, 0xB5, 0xCF, 0x81} }, /* 00 (x350) */ { {0x28, 0x92, 0xD5, 0x82, 0xD4, 0xEE, 0x81} }, /* 01 (x400) */ { {0x28, 0x92, 0xFD, 0x8A, 0xFC, 0x16, 0xB1} }, /* 02 (x480) */ @@ -1649,7 +1649,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] = { }; /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */ -static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] = { +static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] = { { {0xd4, 0x1F, 0x81, 0x84, 0x5D, 0xd5, 0x10} }, /* 00 (x350) */ { {0x06, 0x3e, 0xb3, 0x86, 0x8F, 0x07, 0x20} }, /* 01 (x400) */ { {0x56, 0xba, 0x03, 0x86, 0xDF, 0x57, 0x00} }, /* 02 (x480) */ @@ -1661,7 +1661,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] = { }; /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] = { +static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] = { { {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} },/* ; 00 (320x) */ { {0x4B, 0x27, 0x8F, 0x2B, 0x03, 0x00, 0x44, 0x00} },/* ; 01 (360x) */ { {0x55, 0x31, 0x99, 0x46, 0x1D, 0x00, 0x55, 0x00} },/* ; 02 (400x) */ @@ -1673,7 +1673,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] = { }; /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */ -static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] = { +static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] = { { {0x97, 0x1F, 0x60, 0x87, 0x5D, 0x83, 0x10} },/* ; 00 (x350) */ { {0xB4, 0x1F, 0x92, 0x89, 0x8F, 0xB5, 0x30} },/* ; 01 (x400) */ { {0xFE, 0x1F, 0xE0, 0x84, 0xDF, 0xFF, 0x10} },/* ; 02 (x480) */ @@ -1682,7 +1682,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] = { }; /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] = { +static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] = { { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} },/* ; 00 (320x) */ { {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} },/* ; 01 (360x) */ { {0x63, 0x31, 0x87, 0x3D, 0x8E, 0x00, 0x01, 0x00} },/* ; 02 (400x) */ @@ -1694,7 +1694,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] = { }; /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] = { +static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] = { { {0x24, 0xBB, 0x31, 0x87, 0x5D, 0x25, 0x30} },/* ; 00 (x350) */ { {0x24, 0xBB, 0x4A, 0x80, 0x8F, 0x25, 0x30} },/* ; 01 (x400) */ { {0x24, 0xBB, 0x72, 0x88, 0xDF, 0x25, 0x30} },/* ; 02 (x480) */ @@ -1703,7 +1703,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] = { }; /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] = { +static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] = { { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00} },/* ; 00 (320x) */ { {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00} },/* ; 01 (360x) */ { {0x60, 0x31, 0x84, 0x3A, 0x88, 0x00, 0x01, 0x00} },/* ; 02 (400x) */ @@ -1716,7 +1716,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] = { }; /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] = { +static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] = { { {0x86, 0xD1, 0xBC, 0x80, 0xBB, 0xE5, 0x00} },/* ; 00 (x350) */ { {0xB8, 0x1F, 0x90, 0x84, 0x8F, 0xB9, 0x30} },/* ; 01 (x400) */ { {0x08, 0x3E, 0xE0, 0x84, 0xDF, 0x09, 0x00} },/* ; 02 (x480) */ @@ -1725,7 +1725,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] = { { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* ; 05 (x1024) */ }; /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */ -static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] = { +static const struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] = { { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} },/* ; 00 (320x) */ { {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} },/* ; 01 (360x) */ { {0x7E, 0x40, 0x84, 0x49, 0x91, 0x00, 0x01, 0x00} },/* ; 02 (400x) */ @@ -1738,7 +1738,7 @@ static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] = { }; /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */ -static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = { +static const struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = { { {0x28, 0xD2, 0xAF, 0x83, 0xAE, 0xD8, 0xA1} },/* ; 00 (x350) */ { {0x28, 0xD2, 0xC8, 0x8C, 0xC7, 0xF2, 0x81} },/* ; 01 (x400) */ { {0x28, 0xD2, 0xF0, 0x84, 0xEF, 0x1A, 0xB1} },/* ; 02 (x480) */ @@ -1748,7 +1748,7 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = { }; /*add for new UNIVGABIOS*/ -static struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = { +static const struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = { {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCD1024x768Data }, {Panel_1024x768, 0x0019, 0x0000, XGI_StLCD1024x768Data }, {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCD1024x768Data }, @@ -1771,7 +1771,7 @@ static struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = { {0xFF, 0x0000, 0x0000, NULL } /* End of table */ }; -static struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = { +static const struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = { {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCDDes1024x768Data }, {Panel_1024x768, 0x0019, 0x0000, XGI_StLCDDes1024x768Data }, {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCDDes1024x768Data }, @@ -1795,7 +1795,7 @@ static struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = { {0xFF, 0x0000, 0x0000, NULL } }; -static struct XGI330_LCDDataTablStruct xgifb_lcddldes[] = { +static const struct XGI330_LCDDataTablStruct xgifb_lcddldes[] = { {Panel_1024x768, 0x0019, 0x0001, XGI_ExtLCDDes1024x768Data }, {Panel_1024x768, 0x0019, 0x0000, XGI_StLCDDes1024x768Data }, {Panel_1024x768, 0x0018, 0x0010, XGI_CetLCDDes1024x768Data }, @@ -1819,7 +1819,7 @@ static struct XGI330_LCDDataTablStruct xgifb_lcddldes[] = { {0xFF, 0x0000, 0x0000, NULL } }; -static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_h[] = { +static const struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_h[] = { {Panel_1024x768, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_H }, {Panel_1024x768, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_H }, {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_H }, @@ -1834,7 +1834,7 @@ static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_h[] = { {0xFF, 0x0000, 0x0000, NULL } }; -static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_v[] = { +static const struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_v[] = { {Panel_1024x768, 0x0018, 0x0000, XGI_LVDSCRT11024x768_1_V }, {Panel_1024x768, 0x0018, 0x0010, XGI_LVDSCRT11024x768_2_V }, {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDSCRT11280x1024_1_V }, @@ -1849,7 +1849,7 @@ static struct XGI330_LCDDataTablStruct xgifb_epllcd_crt1_v[] = { {0xFF, 0x0000, 0x0000, NULL } }; -static struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] = { +static const struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] = { {Panel_1024x768, 0x0018, 0x0000, XGI_LVDS1024x768Data_1 }, {Panel_1024x768, 0x0018, 0x0010, XGI_LVDS1024x768Data_2 }, {Panel_1280x1024, 0x0018, 0x0000, XGI_LVDS1280x1024Data_1 }, @@ -1866,7 +1866,7 @@ static struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] = { {0xFF, 0x0000, 0x0000, NULL } }; -static struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] = { +static const struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] = { {Panel_1024x768, 0x0018, 0x0000, XGI_LVDS1024x768Des_1 }, {Panel_1024x768, 0x0618, 0x0410, XGI_LVDS1024x768Des_3 }, {Panel_1024x768, 0x0018, 0x0010, XGI_LVDS1024x768Des_2 }, @@ -1903,7 +1903,7 @@ static const struct XGI330_TVDataTablStruct XGI_TVDataTable[] = { }; /* Dual link only */ -static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { +static const struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { /* LCDCap1024x768 */ {Panel_1024x768, DefaultLCDCap, 0, 0x88, 0x06, VCLK65_315, 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, @@ -1938,7 +1938,7 @@ static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10} }; -static struct XGI330_LCDCapStruct XGI_LCDCapList[] = { +static const struct XGI330_LCDCapStruct XGI_LCDCapList[] = { /* LCDCap1024x768 */ {Panel_1024x768, DefaultLCDCap, 0, 0x88, 0x06, VCLK65_315, 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, -- cgit v1.2.3 From bdb381ec74de49cf4d3f391d2680616a80410fce Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:48 +0200 Subject: staging: xgifb: vb_init.h: delete redundant declaration XGI21_LCDCapList does not exist. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/xgifb/vb_init.h b/drivers/staging/xgifb/vb_init.h index a27b4fe0bb7..d5489832254 100644 --- a/drivers/staging/xgifb/vb_init.h +++ b/drivers/staging/xgifb/vb_init.h @@ -1,6 +1,5 @@ #ifndef _VBINIT_ #define _VBINIT_ extern unsigned char XGIInitNew(struct pci_dev *pdev); -extern struct XGI21_LVDSCapStruct XGI21_LCDCapList[13]; #endif -- cgit v1.2.3 From 6008f87765174fa6addd95b97a6b7154629a2206 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:49 +0200 Subject: staging: xgifb: refactor XGI_GetLVDSData() Refactor XGI_GetLVDSData() to avoid nesting and redundant ifs. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 56 ++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 33d5aa0ab58..3faa1dab600 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -1380,37 +1380,35 @@ static void XGI_GetLVDSData(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short RefreshRateTableIndex, struct vb_device_info *pVBInfo) { - struct SiS_LVDSData const *LCDPtr = NULL; + struct SiS_LVDSData const *LCDPtr; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDataPtr, ModeNo, ModeIdIndex, - RefreshRateTableIndex, pVBInfo); - pVBInfo->VGAHT = LCDPtr->VGAHT; - pVBInfo->VGAVT = LCDPtr->VGAVT; - pVBInfo->HT = LCDPtr->LCDHT; - pVBInfo->VT = LCDPtr->LCDVT; - } + if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA))) + return; - if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { - if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding - | EnableScalingLCD))) { - if ((pVBInfo->LCDResInfo == Panel_1024x768) || - (pVBInfo->LCDResInfo == Panel_1024x768x75)) { - pVBInfo->HDE = 1024; - pVBInfo->VDE = 768; - } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) || - (pVBInfo->LCDResInfo == - Panel_1280x1024x75)) { - pVBInfo->HDE = 1280; - pVBInfo->VDE = 1024; - } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { - pVBInfo->HDE = 1400; - pVBInfo->VDE = 1050; - } else { - pVBInfo->HDE = 1600; - pVBInfo->VDE = 1200; - } - } + LCDPtr = XGI_GetLcdPtr(XGI_EPLLCDDataPtr, ModeNo, ModeIdIndex, + RefreshRateTableIndex, pVBInfo); + pVBInfo->VGAHT = LCDPtr->VGAHT; + pVBInfo->VGAVT = LCDPtr->VGAVT; + pVBInfo->HT = LCDPtr->LCDHT; + pVBInfo->VT = LCDPtr->LCDVT; + + if (pVBInfo->LCDInfo & (SetLCDtoNonExpanding | EnableScalingLCD)) + return; + + if ((pVBInfo->LCDResInfo == Panel_1024x768) || + (pVBInfo->LCDResInfo == Panel_1024x768x75)) { + pVBInfo->HDE = 1024; + pVBInfo->VDE = 768; + } else if ((pVBInfo->LCDResInfo == Panel_1280x1024) || + (pVBInfo->LCDResInfo == Panel_1280x1024x75)) { + pVBInfo->HDE = 1280; + pVBInfo->VDE = 1024; + } else if (pVBInfo->LCDResInfo == Panel_1400x1050) { + pVBInfo->HDE = 1400; + pVBInfo->VDE = 1050; + } else { + pVBInfo->HDE = 1600; + pVBInfo->VDE = 1200; } } -- cgit v1.2.3 From 6154e7f48a69fe26a6f084c941bdc39a9fff2f13 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:50 +0200 Subject: staging: xgifb: eliminate global TimingV/TimingH data Use private data instead of global variables for timing data. Also, get rid of the single element arrays. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 28 +++++++++++++--------------- drivers/staging/xgifb/vb_struct.h | 4 ++-- drivers/staging/xgifb/vb_table.h | 4 ---- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 3faa1dab600..0874722cd94 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -54,8 +54,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->SR21 = 0xa3; pVBInfo->SR22 = 0xfb; - pVBInfo->TimingH = XGI_TimingH; - pVBInfo->TimingV = XGI_TimingV; pVBInfo->UpdateCRT1 = XGI_UpdateCRT1Table; /* 310 customization related */ @@ -328,22 +326,22 @@ static void XGI_SetCRT1Timing_H(struct vb_device_info *pVBInfo, data &= 0x7F; xgifb_reg_set(pVBInfo->P3d4, 0x11, data); - data = pVBInfo->TimingH[0].data[0]; + data = pVBInfo->TimingH.data[0]; xgifb_reg_set(pVBInfo->P3d4, 0, data); for (i = 0x01; i <= 0x04; i++) { - data = pVBInfo->TimingH[0].data[i]; + data = pVBInfo->TimingH.data[i]; xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 1), data); } for (i = 0x05; i <= 0x06; i++) { - data = pVBInfo->TimingH[0].data[i]; + data = pVBInfo->TimingH.data[i]; xgifb_reg_set(pVBInfo->P3c4, (unsigned short) (i + 6), data); } j = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0e); j &= 0x1F; - data = pVBInfo->TimingH[0].data[7]; + data = pVBInfo->TimingH.data[7]; data &= 0xE0; data |= j; xgifb_reg_set(pVBInfo->P3c4, 0x0e, data); @@ -385,28 +383,28 @@ static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short i, j; for (i = 0x00; i <= 0x01; i++) { - data = pVBInfo->TimingV[0].data[i]; + data = pVBInfo->TimingV.data[i]; xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 6), data); } for (i = 0x02; i <= 0x03; i++) { - data = pVBInfo->TimingV[0].data[i]; + data = pVBInfo->TimingV.data[i]; xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x0e), data); } for (i = 0x04; i <= 0x05; i++) { - data = pVBInfo->TimingV[0].data[i]; + data = pVBInfo->TimingV.data[i]; xgifb_reg_set(pVBInfo->P3d4, (unsigned short) (i + 0x11), data); } j = (unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x0a); j &= 0xC0; - data = pVBInfo->TimingV[0].data[6]; + data = pVBInfo->TimingV.data[6]; data &= 0x3F; data |= j; xgifb_reg_set(pVBInfo->P3c4, 0x0a, data); - data = pVBInfo->TimingV[0].data[6]; + data = pVBInfo->TimingV.data[6]; data &= 0x80; data = data >> 2; @@ -438,11 +436,11 @@ static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_set(pVBInfo->P3d4, 0x11, data); /* Unlock CRTC */ for (i = 0; i < 8; i++) - pVBInfo->TimingH[0].data[i] + pVBInfo->TimingH.data[i] = pVBInfo->XGINEWUB_CRT1Table[index].CR[i]; for (i = 0; i < 7; i++) - pVBInfo->TimingV[0].data[i] + pVBInfo->TimingV.data[i] = pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8]; XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); @@ -1430,7 +1428,7 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, RefreshRateTableIndex, pVBInfo); for (i = 0; i < 8; i++) - pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i]; + pVBInfo->TimingH.data[i] = LCDPtr[0].Reg[i]; } XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); @@ -1440,7 +1438,7 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, ModeIdIndex, RefreshRateTableIndex, pVBInfo); for (i = 0; i < 7; i++) - pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i]; + pVBInfo->TimingV.data[i] = LCDPtr1[0].Reg[i]; } XGI_SetCRT1Timing_V(ModeIdIndex, ModeNo, pVBInfo); diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 642141994e4..b4898025fd0 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -180,8 +180,8 @@ struct vb_device_info { struct XGI330_LCDCapStruct const *LCDCapList; - struct XGI_TimingHStruct *TimingH; - struct XGI_TimingVStruct *TimingV; + struct XGI_TimingHStruct TimingH; + struct XGI_TimingVStruct TimingV; struct SiS_StandTable_S *StandTable; struct XGI_ExtStruct *EModeIDTable; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 89638c743ed..5a53a7cd030 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -216,10 +216,6 @@ static struct SiS_StandTable_S XGI330_StandTable = { 0xff} }; -static struct XGI_TimingHStruct XGI_TimingH[1]; - -static struct XGI_TimingVStruct XGI_TimingV[1]; - static struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] = { {0x01, 0x27, 0x91, 0x8f, 0xc0}, /* 00 */ {0x03, 0x4f, 0x83, 0x8f, 0xc0}, /* 01 */ -- cgit v1.2.3 From 3625c9a782a09c68379d2749dc9a56ea367f9047 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:51 +0200 Subject: staging: xgifb: eliminate pVBInfo->StandTable Access XGI330_StandTable directly and make it const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 13 ++++++------- drivers/staging/xgifb/vb_struct.h | 1 - drivers/staging/xgifb/vb_table.h | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 0874722cd94..c505799b569 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -23,7 +23,6 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { - pVBInfo->StandTable = &XGI330_StandTable; pVBInfo->EModeIDTable = XGI330_EModeIDTable; pVBInfo->RefIndex = XGI330_RefIndex; pVBInfo->XGINEWUB_CRT1Table = XGI_CRT1Table; @@ -91,7 +90,7 @@ static void XGI_SetSeqRegs(unsigned short ModeNo, modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ - tempah = pVBInfo->StandTable->SR[0]; + tempah = XGI330_StandTable.SR[0]; i = XGI_SetCRT2ToLCDA; if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { @@ -106,7 +105,7 @@ static void XGI_SetSeqRegs(unsigned short ModeNo, for (i = 02; i <= 04; i++) { /* Get SR2,3,4 from file */ - SRdata = pVBInfo->StandTable->SR[i - 1]; + SRdata = XGI330_StandTable.SR[i - 1]; xgifb_reg_set(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */ } } @@ -123,7 +122,7 @@ static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension, for (i = 0; i <= 0x18; i++) { /* Get CRTC from file */ - CRTCdata = pVBInfo->StandTable->CRTC[i]; + CRTCdata = XGI330_StandTable.CRTC[i]; xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */ } } @@ -138,7 +137,7 @@ static void XGI_SetATTRegs(unsigned short ModeNo, modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; for (i = 0; i <= 0x13; i++) { - ARdata = pVBInfo->StandTable->ATTR[i]; + ARdata = XGI330_StandTable.ATTR[i]; if ((modeflag & Charx8Dot) && i == 0x13) { /* ifndef Dot9 */ if (pVBInfo->VBInfo & XGI_SetCRT2ToLCDA) { @@ -169,7 +168,7 @@ static void XGI_SetGRCRegs(struct vb_device_info *pVBInfo) for (i = 0; i <= 0x08; i++) { /* Get GR from file */ - GRdata = pVBInfo->StandTable->GRC[i]; + GRdata = XGI330_StandTable.GRC[i]; xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */ } @@ -5903,7 +5902,7 @@ static void XGI_SetCRT1Group(struct xgifb_video_info *xgifb_info, unsigned short RefreshRateTableIndex, temp; XGI_SetSeqRegs(ModeNo, ModeIdIndex, pVBInfo); - outb(pVBInfo->StandTable->MISC, pVBInfo->P3c2); + outb(XGI330_StandTable.MISC, pVBInfo->P3c2); XGI_SetCRTCRegs(HwDeviceExtension, pVBInfo); XGI_SetATTRegs(ModeNo, ModeIdIndex, pVBInfo); XGI_SetGRCRegs(pVBInfo); diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index b4898025fd0..7ec1afdd91d 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -183,7 +183,6 @@ struct vb_device_info { struct XGI_TimingHStruct TimingH; struct XGI_TimingVStruct TimingV; - struct SiS_StandTable_S *StandTable; struct XGI_ExtStruct *EModeIDTable; struct XGI_Ext2Struct *RefIndex; struct XGI_CRT1TableStruct *XGINEWUB_CRT1Table; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 5a53a7cd030..c2cc91591a4 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -200,7 +200,7 @@ static struct XGI_ExtStruct XGI330_EModeIDTable[] = { {0xff, 0x0000, 0x0000, 0x00, 0x00, 0x00} }; -static struct SiS_StandTable_S XGI330_StandTable = { +static const struct SiS_StandTable_S XGI330_StandTable = { /* ExtVGATable */ 0x00, 0x00, 0x00, 0x0000, {0x01, 0x0f, 0x00, 0x0e}, -- cgit v1.2.3 From b397992e883de4e38fec06abd19e654d319d817a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:52 +0200 Subject: staging: xgifb: eliminate pVBInfo->EModeIDTable Access XGI330_EModeIDTable directly and make it const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 6 +-- drivers/staging/xgifb/vb_def.h | 2 + drivers/staging/xgifb/vb_setmode.c | 105 ++++++++++++++++++------------------ drivers/staging/xgifb/vb_struct.h | 1 - drivers/staging/xgifb/vb_table.h | 2 +- 5 files changed, 58 insertions(+), 58 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index f775c545384..4b88f97edab 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -217,10 +217,10 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, *vmode = FB_VMODE_INTERLACED; else { j = 0; - while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) { - if (XGI_Pr->EModeIDTable[j].Ext_ModeID == + while (XGI330_EModeIDTable[j].Ext_ModeID != 0xff) { + if (XGI330_EModeIDTable[j].Ext_ModeID == XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) { - if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag & + if (XGI330_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) { *vmode = FB_VMODE_DOUBLE; } diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 77137e4452a..260354ca07d 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -259,4 +259,6 @@ #define XGI330_SR32 0x11 #define XGI330_SR33 0 +extern const struct XGI_ExtStruct XGI330_EModeIDTable[]; + #endif diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index c505799b569..4057d2768c3 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -23,7 +23,6 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { - pVBInfo->EModeIDTable = XGI330_EModeIDTable; pVBInfo->RefIndex = XGI330_RefIndex; pVBInfo->XGINEWUB_CRT1Table = XGI_CRT1Table; @@ -87,7 +86,7 @@ static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned char tempah, SRdata; unsigned short i, modeflag; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; xgifb_reg_set(pVBInfo->P3c4, 0x00, 0x03); /* Set SR0 */ tempah = XGI330_StandTable.SR[0]; @@ -134,7 +133,7 @@ static void XGI_SetATTRegs(unsigned short ModeNo, unsigned char ARdata; unsigned short i, modeflag; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; for (i = 0; i <= 0x13; i++) { ARdata = XGI330_StandTable.ATTR[i]; @@ -209,8 +208,8 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, { unsigned short tempax, tempbx, resinfo, modeflag, infoflag; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID; tempax = 0; @@ -407,7 +406,7 @@ static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, data &= 0x80; data = data >> 2; - i = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + i = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; i &= DoubleScanMode; if (i) data |= 0x80; @@ -752,9 +751,9 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, unsigned char data; - resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; tempax = pVBInfo->ModeResInfo[resindex].HTotal; tempbx = pVBInfo->ModeResInfo[resindex].VTotal; @@ -816,7 +815,7 @@ static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short temp, ah, al, temp2, i, DisplayUnit; /* GetOffset */ - temp = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo; + temp = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo; temp = temp >> 8; temp = pVBInfo->ScreenOffset[temp]; @@ -901,8 +900,8 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, unsigned short modeflag, resinfo; /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; CRT2Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; if (pVBInfo->IF_DEF_LVDS == 0) { @@ -1001,7 +1000,7 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, } if (HwDeviceExtension->jChipType >= XG20) { - if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag & + if (XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag & HalfDCLK) { data = xgifb_reg_get(pVBInfo->P3c4, 0x2B); xgifb_reg_set(pVBInfo->P3c4, 0x2B, data); @@ -1099,7 +1098,7 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, unsigned short data, data2, data3, infoflag = 0, modeflag, resindex, xres; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01) @@ -1117,7 +1116,7 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, data2 |= 0x20; xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2); - resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ data = 0x0000; @@ -1279,10 +1278,10 @@ static void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short resindex, xres, yres, modeflag; /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */ - resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; xres = pVBInfo->ModeResInfo[resindex].HTotal; yres = pVBInfo->ModeResInfo[resindex].VTotal; @@ -1312,7 +1311,7 @@ static void const *XGI_GetLcdPtr(struct XGI330_LCDDataTablStruct const *table, tempbx = 0; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; i = 0; @@ -1350,7 +1349,7 @@ static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeNo, { unsigned short i, tempdx, tempal, modeflag; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; tempal = tempal & 0x3f; tempdx = pVBInfo->TVInfo; @@ -1524,7 +1523,7 @@ static void XGI_SetLVDSRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct XGI_LCDDesStruct const *LCDPtr = NULL; struct XGI330_LCDDataDesStruct2 const *LCDPtr1 = NULL; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; if (pVBInfo->LCDInfo & EnableScalingLCD) LCDPtr1 = XGI_GetLcdPtr(XGI_EPLLCDDesDataPtr, ModeNo, ModeIdIndex, RefreshRateTableIndex, @@ -1806,7 +1805,7 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, unsigned char tempal; /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; if ((pVBInfo->SetFlag & ProgrammingCRT2) && (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */ @@ -2052,7 +2051,7 @@ static void XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned short tempax, push, tempbx, temp, modeflag; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; pVBInfo->SetFlag = 0; pVBInfo->ModeType = modeflag & ModeTypeMask; tempbx = 0; @@ -2238,8 +2237,8 @@ static void XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, resinfo = 0; if (pVBInfo->VBInfo & SetCRT2ToTV) { - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; if (pVBInfo->VBInfo & SetCRT2ToTV) { temp = xgifb_reg_get(pVBInfo->P3d4, 0x35); @@ -2324,9 +2323,9 @@ static unsigned char XGI_GetLCDInfo(unsigned short ModeNo, pVBInfo->LCDTypeInfo = 0; pVBInfo->LCDInfo = 0; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo // */ - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */ tempbx = temp & 0x0F; @@ -2405,9 +2404,9 @@ unsigned char XGI_SearchModeID(unsigned short ModeNo, unsigned short *ModeIdIndex, struct vb_device_info *pVBInfo) { for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { - if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo) + if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo) break; - if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) + if (XGI330_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) return 0; } @@ -2647,11 +2646,11 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo, { unsigned short xres, yres, modeflag, resindex; - resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ /* si+St_ModeFlag */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; if (modeflag & HalfDCLK) xres *= 2; @@ -2726,7 +2725,7 @@ static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, pVBInfo->RVBHCMAX = 1; pVBInfo->RVBHCFACT = 1; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; CRT1Index &= IndexMask; temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0]; @@ -2768,8 +2767,8 @@ static void XGI_GetCRT2Data(unsigned short ModeNo, unsigned short ModeIdIndex, struct SiS_LCDData const *LCDPtr = NULL; /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; pVBInfo->NewFlickerMode = 0; pVBInfo->RVBHRS = 50; @@ -2970,7 +2969,7 @@ static unsigned short XGI_GetColorDepth(unsigned short ModeNo, short index; unsigned short modeflag; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; index = (modeflag & ModeTypeMask) - ModeEGA; if (index < 0) @@ -2988,7 +2987,7 @@ static unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short temp, colordepth, modeinfo, index, infoflag, ColorDepth[] = { 0x01, 0x02, 0x04 }; - modeinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeInfo; + modeinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo; infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; index = (modeinfo >> 8) & 0xFF; @@ -3051,7 +3050,7 @@ static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; CRT1Index &= IndexMask; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; XGI_SetCRT2Offset(ModeNo, ModeIdIndex, RefreshRateTableIndex, HwDeviceExtension, pVBInfo); @@ -3074,8 +3073,8 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; CRT1Index &= IndexMask; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* bainy change table name */ if (modeflag & HalfDCLK) { @@ -3234,8 +3233,8 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, modeflag, CRT1Index; /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; CRT1Index &= IndexMask; @@ -3534,8 +3533,8 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned long longtemp, tempeax, tempebx, temp2, tempecx; /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; tempax = 0; @@ -3973,8 +3972,8 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, struct XGI_LCDDesStruct const *LCDBDesPtr = NULL; /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; - resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; + resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; CRT1Index &= IndexMask; @@ -4258,7 +4257,7 @@ static void XGI_SetGroup3(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short modeflag; /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00); if (pVBInfo->TVInfo & TVSetPAL) { @@ -4317,7 +4316,7 @@ static void XGI_SetGroup4(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned long tempebx, tempeax, templong; /* si+Ext_ResInfo */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; temp = pVBInfo->RVBHCFACT; xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp); @@ -4520,11 +4519,11 @@ static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info, { unsigned short xres, yres, colordepth, modeflag, resindex; - resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ /* si+St_ModeFlag */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; if (!(modeflag & Charx8Dot)) { xres /= 9; @@ -4582,11 +4581,11 @@ static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info, else XGI_SetXG21FPBits(pVBInfo); - resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; + resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ /* si+St_ModeFlag */ - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; if (!(modeflag & Charx8Dot)) xres = xres * 8 / 9; @@ -5283,7 +5282,7 @@ static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, return; } - tempal = pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; + tempal = XGI330_EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex; if (tempcl == 0) index = tempal * 4; else @@ -5545,7 +5544,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, unsigned short RefreshRateTableIndex, i, modeflag, index, temp; - modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; + modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; index = xgifb_reg_get(pVBInfo->P3d4, 0x33); index = index >> pVBInfo->SelectCRT2Rate; @@ -5578,7 +5577,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, } } - RefreshRateTableIndex = pVBInfo->EModeIDTable[ModeIdIndex].REFindex; + RefreshRateTableIndex = XGI330_EModeIDTable[ModeIdIndex].REFindex; ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID; if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */ if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800) && @@ -6088,7 +6087,7 @@ unsigned char XGISetModeNew(struct xgifb_video_info *xgifb_info, pVBInfo)) return 0; - pVBInfo->ModeType = pVBInfo->EModeIDTable[ModeIdIndex]. + pVBInfo->ModeType = XGI330_EModeIDTable[ModeIdIndex]. Ext_ModeFlag & ModeTypeMask; pVBInfo->SetFlag = 0; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 7ec1afdd91d..1150ccc398c 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -183,7 +183,6 @@ struct vb_device_info { struct XGI_TimingHStruct TimingH; struct XGI_TimingVStruct TimingV; - struct XGI_ExtStruct *EModeIDTable; struct XGI_Ext2Struct *RefIndex; struct XGI_CRT1TableStruct *XGINEWUB_CRT1Table; struct SiS_VCLKData *VCLKData; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index c2cc91591a4..6065436c313 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -128,7 +128,7 @@ static unsigned char XGI340_AGPReg[12] = { static unsigned char XGI340_SR16[4] = {0x03, 0x83, 0x03, 0x83}; -static struct XGI_ExtStruct XGI330_EModeIDTable[] = { +const struct XGI_ExtStruct XGI330_EModeIDTable[] = { {0x2e, 0x0a1b, 0x0306, 0x06, 0x05, 0x06}, {0x2f, 0x0a1b, 0x0305, 0x05, 0x05, 0x05}, {0x30, 0x2a1b, 0x0407, 0x07, 0x07, 0x0e}, -- cgit v1.2.3 From a39325d24fec6f13a3c60afcca8e728b6aeda24e Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:53 +0200 Subject: staging: xgifb: eliminate pVBInfo->RefIndex Access XGI330_RefIndex directly and make it const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 16 +++---- drivers/staging/xgifb/vb_def.h | 1 + drivers/staging/xgifb/vb_setmode.c | 84 ++++++++++++++++++------------------- drivers/staging/xgifb/vb_struct.h | 1 - drivers/staging/xgifb/vb_table.h | 2 +- 5 files changed, 51 insertions(+), 53 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 4b88f97edab..263b1dc903b 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -73,7 +73,7 @@ static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr, RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, XGI_Pr); - ClockIndex = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + ClockIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000; @@ -101,7 +101,7 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, return 0; RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo, ModeIdIndex, XGI_Pr); - index = XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5]; @@ -111,7 +111,7 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8); A = HT + 5; - HDE = (XGI_Pr->RefIndex[RefreshRateTableIndex].XRes >> 3) - 1; + HDE = (XGI330_RefIndex[RefreshRateTableIndex].XRes >> 3) - 1; E = HDE + 1; cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3]; @@ -162,7 +162,7 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, | ((unsigned short) (sr_data & 0x01) << 10); A = VT + 2; - VDE = XGI_Pr->RefIndex[RefreshRateTableIndex].YRes - 1; + VDE = XGI330_RefIndex[RefreshRateTableIndex].YRes - 1; E = VDE + 1; cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; @@ -202,24 +202,24 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, *lower_margin = F; *vsync_len = C; - if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000) + if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000) *sync &= ~FB_SYNC_VERT_HIGH_ACT; else *sync |= FB_SYNC_VERT_HIGH_ACT; - if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000) + if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000) *sync &= ~FB_SYNC_HOR_HIGH_ACT; else *sync |= FB_SYNC_HOR_HIGH_ACT; *vmode = FB_VMODE_NONINTERLACED; - if (XGI_Pr->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080) + if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080) *vmode = FB_VMODE_INTERLACED; else { j = 0; while (XGI330_EModeIDTable[j].Ext_ModeID != 0xff) { if (XGI330_EModeIDTable[j].Ext_ModeID == - XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) { + XGI330_RefIndex[RefreshRateTableIndex].ModeID) { if (XGI330_EModeIDTable[j].Ext_ModeFlag & DoubleScanMode) { *vmode = FB_VMODE_DOUBLE; diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 260354ca07d..f7e966f4faa 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -260,5 +260,6 @@ #define XGI330_SR33 0 extern const struct XGI_ExtStruct XGI330_EModeIDTable[]; +extern const struct XGI_Ext2Struct XGI330_RefIndex[]; #endif diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 4057d2768c3..06e541d191e 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -23,7 +23,6 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { - pVBInfo->RefIndex = XGI330_RefIndex; pVBInfo->XGINEWUB_CRT1Table = XGI_CRT1Table; pVBInfo->MCLKData = XGI340New_MCLKData; @@ -210,7 +209,7 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - tempbx = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID; + tempbx = XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID; tempax = 0; if (pVBInfo->IF_DEF_LVDS == 0) { @@ -275,9 +274,9 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, } } - for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID == + for (; XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx; (*i)--) { - infoflag = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)]. + infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)]. Ext_InfoFlag; if (infoflag & tempax) return 1; @@ -287,9 +286,9 @@ static unsigned char XGI_AjustCRT2Rate(unsigned short ModeNo, } for ((*i) = 0;; (*i)++) { - infoflag = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)]. + infoflag = XGI330_RefIndex[RefreshRateTableIndex + (*i)]. Ext_InfoFlag; - if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID + if (XGI330_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) { return 0; } @@ -306,7 +305,7 @@ static void XGI_SetSync(unsigned short RefreshRateTableIndex, unsigned short sync, temp; /* di+0x00 */ - sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; + sync = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; sync &= 0xC0; temp = 0x2F; temp |= sync; @@ -426,7 +425,7 @@ static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short i; /* Get index */ - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; index = index & IndexMask; data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11); @@ -462,7 +461,7 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char index, Tempax, Tempbx, Tempcx, Tempdx; unsigned short Temp1, Temp2, Temp3; - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Tempax: CR4 HRS */ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; Tempcx = Tempax; /* Tempcx: HRS */ @@ -559,7 +558,7 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, { unsigned short index, Tempax, Tempbx, Tempcx; - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Tempax: CR4 HRS */ Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; Tempbx = Tempax; /* Tempbx: HRS[7:0] */ @@ -694,7 +693,7 @@ static void xgifb_set_lcd(int chip_id, xgifb_reg_and(pVBInfo->P3c4, 0x30, ~0x20); /* Hsync polarity */ xgifb_reg_and(pVBInfo->P3c4, 0x35, ~0x80); /* Vsync polarity */ - Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + Data = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; if (Data & 0x4000) /* Hsync polarity */ xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); @@ -717,10 +716,10 @@ static void XGI_UpdateXG21CRTC(unsigned short ModeNo, xgifb_reg_and(pVBInfo->P3d4, 0x11, 0x7F); /* Unlock CR0~7 */ if (ModeNo == 0x2E && - (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC == + (XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC == RES640x480x60)) index = 12; - else if (ModeNo == 0x2E && (pVBInfo->RefIndex[RefreshRateTableIndex]. + else if (ModeNo == 0x2E && (XGI330_RefIndex[RefreshRateTableIndex]. Ext_CRT1CRTC == RES640x480x72)) index = 13; else if (ModeNo == 0x2F) @@ -763,7 +762,7 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, if (modeflag & HalfDCLK) tempax = tempax << 1; - temp = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + temp = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; if (temp & InterlaceMode) tempbx = tempbx >> 1; @@ -819,7 +818,7 @@ static void XGI_SetCRT1Offset(unsigned short ModeNo, temp = temp >> 8; temp = pVBInfo->ScreenOffset[temp]; - temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; temp2 &= InterlaceMode; if (temp2) @@ -870,7 +869,7 @@ static void XGI_SetCRT1Offset(unsigned short ModeNo, xgifb_reg_set(pVBInfo->P3d4, 0x13, temp); /* SetDisplayUnit */ - temp2 = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; temp2 &= InterlaceMode; if (temp2) DisplayUnit >>= 1; @@ -902,7 +901,7 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, /* si+Ext_ResInfo */ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - CRT2Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + CRT2Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; if (pVBInfo->IF_DEF_LVDS == 0) { CRT2Index = CRT2Index >> 6; /* for LCD */ @@ -943,7 +942,7 @@ static unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, VCLKIndex = TVCLKBASE_315_25 + TVVCLK; } else { /* for CRT2 */ /* di+Ext_CRTVCLK */ - VCLKIndex = pVBInfo->RefIndex[RefreshRateTableIndex]. + VCLKIndex = XGI330_RefIndex[RefreshRateTableIndex]. Ext_CRTVCLK; VCLKIndex &= IndexMask; } @@ -967,7 +966,7 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short vclkindex; if (pVBInfo->IF_DEF_LVDS == 1) { - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; xgifb_reg_set(pVBInfo->P3c4, 0x31, data); xgifb_reg_set(pVBInfo->P3c4, 0x2B, @@ -989,7 +988,7 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, xgifb_reg_set(pVBInfo->P3c4, 0x2C, data); xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); } else { - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; xgifb_reg_set(pVBInfo->P3c4, 0x31, data); xgifb_reg_set(pVBInfo->P3c4, 0x2B, @@ -1060,7 +1059,7 @@ static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, unsigned char index; - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; index &= IndexMask; VCLK = pVBInfo->VCLKData[index].CLOCK; @@ -1099,7 +1098,7 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, xres; modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01) xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00); @@ -1350,7 +1349,7 @@ static struct SiS_TVData const *XGI_GetTVPtr(unsigned short ModeNo, unsigned short i, tempdx, tempal, modeflag; modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; tempal = tempal & 0x3f; tempdx = pVBInfo->TVInfo; @@ -1418,7 +1417,7 @@ static void XGI_ModCRT1Regs(unsigned short ModeNo, unsigned short ModeIdIndex, struct XGI_LVDSCRT1HDataStruct const *LCDPtr = NULL; struct XGI_LVDSCRT1VDataStruct const *LCDPtr1 = NULL; - index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; index = index & IndexMask; if (pVBInfo->VBInfo & (SetCRT2ToLCD | XGI_SetCRT2ToLCDA)) { @@ -1867,7 +1866,7 @@ static unsigned char XGI_GetVCLKPtr(unsigned short RefreshRateTableIndex, if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot)) tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */ - tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; + tempal = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; return tempal; } @@ -2726,7 +2725,7 @@ static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, pVBInfo->RVBHCMAX = 1; pVBInfo->RVBHCFACT = 1; modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; CRT1Index &= IndexMask; temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0]; temp2 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]; @@ -2988,7 +2987,7 @@ static unsigned short XGI_GetOffset(unsigned short ModeNo, ColorDepth[] = { 0x01, 0x02, 0x04 }; modeinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo; - infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag; + infoflag = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; index = (modeinfo >> 8) & 0xFF; @@ -3048,7 +3047,7 @@ static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, { unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0; - CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; CRT1Index &= IndexMask; resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; @@ -3071,7 +3070,7 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short temp = 0, tempax = 0, tempbx = 0, tempcx = 0, pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0; - CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; CRT1Index &= IndexMask; resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; @@ -3235,7 +3234,7 @@ static void XGI_SetLockRegs(unsigned short ModeNo, unsigned short ModeIdIndex, /* si+Ext_ResInfo */ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; CRT1Index &= IndexMask; if (!(pVBInfo->VBInfo & SetInSlaveMode)) @@ -3535,7 +3534,7 @@ static void XGI_SetGroup2(unsigned short ModeNo, unsigned short ModeIdIndex, /* si+Ext_ResInfo */ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; + crt2crtc = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC; tempax = 0; @@ -3974,7 +3973,7 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, /* si+Ext_ResInfo */ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; resinfo = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; + CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; CRT1Index &= IndexMask; if (!(pVBInfo->VBInfo & SetCRT2ToLCD)) @@ -5578,30 +5577,29 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, } RefreshRateTableIndex = XGI330_EModeIDTable[ModeIdIndex].REFindex; - ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID; + ModeNo = XGI330_RefIndex[RefreshRateTableIndex].ModeID; if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */ - if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800) && - (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 600)) { + if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 800) && + (XGI330_RefIndex[RefreshRateTableIndex].YRes == 600)) { index++; } /* do the similar adjustment like XGISearchCRT1Rate() */ - if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024) && - (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 768)) { + if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1024) && + (XGI330_RefIndex[RefreshRateTableIndex].YRes == 768)) { index++; } - if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1280) && - (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 1024)) { + if ((XGI330_RefIndex[RefreshRateTableIndex].XRes == 1280) && + (XGI330_RefIndex[RefreshRateTableIndex].YRes == 1024)) { index++; } } i = 0; do { - if (pVBInfo->RefIndex[RefreshRateTableIndex + i]. + if (XGI330_RefIndex[RefreshRateTableIndex + i]. ModeID != ModeNo) break; - temp = pVBInfo->RefIndex[RefreshRateTableIndex + i]. - Ext_InfoFlag; + temp = XGI330_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag; temp &= ModeTypeMask; if (temp < pVBInfo->ModeType) break; @@ -5611,7 +5609,7 @@ unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, } while (index != 0xFFFF); if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) { if (pVBInfo->VBInfo & SetInSlaveMode) { - temp = pVBInfo->RefIndex[RefreshRateTableIndex + i - 1]. + temp = XGI330_RefIndex[RefreshRateTableIndex + i - 1]. Ext_InfoFlag; if (temp & InterlaceMode) i++; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 1150ccc398c..d007e004f10 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -183,7 +183,6 @@ struct vb_device_info { struct XGI_TimingHStruct TimingH; struct XGI_TimingVStruct TimingV; - struct XGI_Ext2Struct *RefIndex; struct XGI_CRT1TableStruct *XGINEWUB_CRT1Table; struct SiS_VCLKData *VCLKData; struct SiS_VBVCLKData *VBVCLKData; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 6065436c313..e0bba7ded73 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1969,7 +1969,7 @@ static const struct XGI330_LCDCapStruct XGI_LCDCapList[] = { 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10} }; -static struct XGI_Ext2Struct XGI330_RefIndex[] = { +const struct XGI_Ext2Struct XGI330_RefIndex[] = { {Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, 0x00, 0x10, 0x59, 320, 200},/* 00 */ {Mode32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175, -- cgit v1.2.3 From 7853bced96ff8026a779f7acfad9fcadcd080f66 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:54 +0200 Subject: staging: xgifb: eliminate pVBInfo->XGINEWUB_CRT1Table Access XGI_CRT1Table directly and make it const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 30 +++++++------- drivers/staging/xgifb/vb_def.h | 1 + drivers/staging/xgifb/vb_setmode.c | 82 ++++++++++++++++++------------------- drivers/staging/xgifb/vb_struct.h | 1 - drivers/staging/xgifb/vb_table.h | 2 +- 5 files changed, 56 insertions(+), 60 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 263b1dc903b..725fba15347 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -103,9 +103,9 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, ModeIdIndex, XGI_Pr); index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; - sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[5]; + sr_data = XGI_CRT1Table[index].CR[5]; - cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[0]; + cr_data = XGI_CRT1Table[index].CR[0]; /* Horizontal total */ HT = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8); @@ -114,22 +114,22 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, HDE = (XGI330_RefIndex[RefreshRateTableIndex].XRes >> 3) - 1; E = HDE + 1; - cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[3]; + cr_data = XGI_CRT1Table[index].CR[3]; /* Horizontal retrace (=sync) start */ HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2); F = HRS - E - 3; - cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[1]; + cr_data = XGI_CRT1Table[index].CR[1]; /* Horizontal blank start */ HBS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x30) << 4); - sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[6]; + sr_data = XGI_CRT1Table[index].CR[6]; - cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[2]; + cr_data = XGI_CRT1Table[index].CR[2]; - cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[4]; + cr_data2 = XGI_CRT1Table[index].CR[4]; /* Horizontal blank end */ HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2) @@ -150,11 +150,11 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, *right_margin = F * 8; *hsync_len = C * 8; - sr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[14]; + sr_data = XGI_CRT1Table[index].CR[14]; - cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[8]; + cr_data = XGI_CRT1Table[index].CR[8]; - cr_data2 = XGI_Pr->XGINEWUB_CRT1Table[index].CR[9]; + cr_data2 = XGI_CRT1Table[index].CR[9]; /* Vertical total */ VT = (cr_data & 0xFF) | ((unsigned short) (cr_data2 & 0x01) << 8) @@ -165,7 +165,7 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, VDE = XGI330_RefIndex[RefreshRateTableIndex].YRes - 1; E = VDE + 1; - cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[10]; + cr_data = XGI_CRT1Table[index].CR[10]; /* Vertical retrace (=sync) start */ VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6) @@ -173,23 +173,23 @@ static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr, | ((unsigned short) (sr_data & 0x08) << 7); F = VRS + 1 - E; - cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[12]; + cr_data = XGI_CRT1Table[index].CR[12]; - cr_data3 = (XGI_Pr->XGINEWUB_CRT1Table[index].CR[14] & 0x80) << 5; + cr_data3 = (XGI_CRT1Table[index].CR[14] & 0x80) << 5; /* Vertical blank start */ VBS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x08) << 5) | ((unsigned short) (cr_data3 & 0x20) << 4) | ((unsigned short) (sr_data & 0x04) << 8); - cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[13]; + cr_data = XGI_CRT1Table[index].CR[13]; /* Vertical blank end */ VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4); temp = VBE - ((E - 1) & 511); B = (temp > 0) ? temp : (temp + 512); - cr_data = XGI_Pr->XGINEWUB_CRT1Table[index].CR[11]; + cr_data = XGI_CRT1Table[index].CR[11]; /* Vertical retrace (=sync) end */ VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1); diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index f7e966f4faa..0fd56fbcef0 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -261,5 +261,6 @@ extern const struct XGI_ExtStruct XGI330_EModeIDTable[]; extern const struct XGI_Ext2Struct XGI330_RefIndex[]; +extern const struct XGI_CRT1TableStruct XGI_CRT1Table[]; #endif diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 06e541d191e..7ee42ac8e3a 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -23,8 +23,6 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { - pVBInfo->XGINEWUB_CRT1Table = XGI_CRT1Table; - pVBInfo->MCLKData = XGI340New_MCLKData; pVBInfo->ECLKData = XGI340_ECLKData; pVBInfo->VCLKData = XGI_VCLKData; @@ -434,11 +432,11 @@ static void XGI_SetCRT1CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, for (i = 0; i < 8; i++) pVBInfo->TimingH.data[i] - = pVBInfo->XGINEWUB_CRT1Table[index].CR[i]; + = XGI_CRT1Table[index].CR[i]; for (i = 0; i < 7; i++) pVBInfo->TimingV.data[i] - = pVBInfo->XGINEWUB_CRT1Table[index].CR[i + 8]; + = XGI_CRT1Table[index].CR[i + 8]; XGI_SetCRT1Timing_H(pVBInfo, HwDeviceExtension); @@ -463,21 +461,21 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Tempax: CR4 HRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; + Tempax = XGI_CRT1Table[index].CR[3]; Tempcx = Tempax; /* Tempcx: HRS */ /* SR2E[7:0]->HRS */ xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); - Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */ + Tempdx = XGI_CRT1Table[index].CR[5]; /* SRB */ Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */ Temp1 = Tempdx; /* Temp1[7:6]: HRS[9:8] */ Temp1 <<= 2; /* Temp1[9:8]: HRS[9:8] */ Temp1 |= Tempax; /* Temp1[9:0]: HRS[9:0] */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ + Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */ Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ - Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ + Tempbx = XGI_CRT1Table[index].CR[6]; /* SRC */ Tempbx &= 0x04; /* Tempbx[2]: HRE[5] */ Tempbx <<= 3; /* Tempbx[5]: HRE[5] */ Tempax |= Tempbx; /* Tempax[5:0]: HRE[5:0] */ @@ -499,12 +497,12 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); /* CR10 VRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; + Tempax = XGI_CRT1Table[index].CR[10]; Tempbx = Tempax; /* Tempbx: VRS */ Tempax &= 0x01; /* Tempax[0]: VRS[0] */ xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */ /* CR7[2][7] VRE */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; + Tempax = XGI_CRT1Table[index].CR[9]; Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */ Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */ Tempdx <<= 5; /* Tempdx[7]: VRS[8] */ @@ -518,17 +516,17 @@ static void XGI_SetXG21CRTC(unsigned short ModeNo, unsigned short ModeIdIndex, Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */ Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */ /* Tempax: SRA */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; + Tempax = XGI_CRT1Table[index].CR[14]; Tempax &= 0x08; /* Tempax[3]: VRS[3] */ Temp2 = Tempax; Temp2 <<= 7; /* Temp2[10]: VRS[10] */ Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */ /* Tempax: CR11 VRE */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; + Tempax = XGI_CRT1Table[index].CR[11]; Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ /* Tempbx: SRA */ - Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; + Tempbx = XGI_CRT1Table[index].CR[14]; Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */ Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ @@ -560,21 +558,21 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Tempax: CR4 HRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; + Tempax = XGI_CRT1Table[index].CR[3]; Tempbx = Tempax; /* Tempbx: HRS[7:0] */ /* SR2E[7:0]->HRS */ xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); /* SR0B */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; + Tempax = XGI_CRT1Table[index].CR[5]; Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[4]; /* CR5 HRE */ + Tempax = XGI_CRT1Table[index].CR[4]; /* CR5 HRE */ Tempax &= 0x1F; /* Tempax[4:0]: HRE[4:0] */ Tempcx = Tempax; /* Tempcx: HRE[4:0] */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[6]; /* SRC */ + Tempax = XGI_CRT1Table[index].CR[6]; /* SRC */ Tempax &= 0x04; /* Tempax[2]: HRE[5] */ Tempax <<= 3; /* Tempax[5]: HRE[5] */ Tempcx |= Tempax; /* Tempcx[5:0]: HRE[5:0] */ @@ -583,12 +581,12 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */ /* Tempax: CR4 HRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; + Tempax = XGI_CRT1Table[index].CR[3]; Tempax &= 0x3F; /* Tempax: HRS[5:0] */ if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */ Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */ + Tempax = XGI_CRT1Table[index].CR[5]; /* SR0B */ Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/ Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/ Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */ @@ -597,13 +595,13 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00); /* CR10 VRS */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; + Tempax = XGI_CRT1Table[index].CR[10]; /* SR34[7:0]->VRS[7:0] */ xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); Tempcx = Tempax; /* Tempcx <= VRS[7:0] */ /* CR7[7][2] VRS[9][8] */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; + Tempax = XGI_CRT1Table[index].CR[9]; Tempbx = Tempax; /* Tempbx <= CR07[7:0] */ Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */ Tempax >>= 2; /* Tempax[0]: VRS[8] */ @@ -612,15 +610,15 @@ static void XGI_SetXG27CRTC(unsigned short ModeNo, Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */ Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */ /* Tempax: SR0A */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; + Tempax = XGI_CRT1Table[index].CR[14]; Tempax &= 0x08; /* SR0A[3] VRS[10] */ Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */ /* Tempax: CR11 VRE */ - Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; + Tempax = XGI_CRT1Table[index].CR[11]; Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */ /* Tempbx: SR0A */ - Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; + Tempbx = XGI_CRT1Table[index].CR[14]; Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */ Tempbx >>= 1; /* Tempbx[4]: VRE[4] */ Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */ @@ -2727,16 +2725,16 @@ static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; CRT1Index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; CRT1Index &= IndexMask; - temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0]; - temp2 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]; + temp1 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[0]; + temp2 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[5]; tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8); - tempbx = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8]; + tempbx = (unsigned short) XGI_CRT1Table[CRT1Index].CR[8]; tempcx = (unsigned short) - pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8; + XGI_CRT1Table[CRT1Index].CR[14] << 8; tempcx &= 0x0100; tempcx = tempcx << 2; tempbx |= tempcx; - temp1 = (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9]; + temp1 = (unsigned short) XGI_CRT1Table[CRT1Index].CR[9]; if (temp1 & 0x01) tempbx |= 0x0100; @@ -3092,14 +3090,13 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx += tempbx; if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4]; - tempbx |= ((pVBInfo-> - XGINEWUB_CRT1Table[CRT1Index].CR[14] & + tempbx = XGI_CRT1Table[CRT1Index].CR[4]; + tempbx |= ((XGI_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2); tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */ - tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]; + tempcx = XGI_CRT1Table[CRT1Index].CR[5]; tempcx &= 0x1F; - temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[15]; + temp = XGI_CRT1Table[CRT1Index].CR[15]; temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */ tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */ } @@ -3128,14 +3125,13 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx += tempbx; if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3]; - tempbx |= ((pVBInfo-> - XGINEWUB_CRT1Table[CRT1Index].CR[5] & + tempbx = XGI_CRT1Table[CRT1Index].CR[3]; + tempbx |= ((XGI_CRT1Table[CRT1Index].CR[5] & 0xC0) << 2); tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */ - tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4]; + tempcx = XGI_CRT1Table[CRT1Index].CR[4]; tempcx &= 0x1F; - temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[6]; + temp = XGI_CRT1Table[CRT1Index].CR[6]; temp = (temp & 0x04) << (5 - 2); /* VGAHRE D[5] */ tempcx = ((tempcx | temp) - 3) << 3; /* (VGAHRE-3)*8 */ tempbx += 16; @@ -3177,8 +3173,8 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) { - tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10]; - temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9]; + tempbx = XGI_CRT1Table[CRT1Index].CR[10]; + temp = XGI_CRT1Table[CRT1Index].CR[9]; if (temp & 0x04) tempbx |= 0x0100; @@ -3186,12 +3182,12 @@ static void XGI_SetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex, if (temp & 0x080) tempbx |= 0x0200; - temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]; + temp = XGI_CRT1Table[CRT1Index].CR[14]; if (temp & 0x08) tempbx |= 0x0400; - temp = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[11]; + temp = XGI_CRT1Table[CRT1Index].CR[11]; tempcx = (tempcx & 0xFF00) | (temp & 0x00FF); } diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index d007e004f10..8bfbfab0464 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -183,7 +183,6 @@ struct vb_device_info { struct XGI_TimingHStruct TimingH; struct XGI_TimingVStruct TimingV; - struct XGI_CRT1TableStruct *XGINEWUB_CRT1Table; struct SiS_VCLKData *VCLKData; struct SiS_VBVCLKData *VBVCLKData; struct SiS_StResInfo_S *StResInfo; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index e0bba7ded73..e83c4259ce2 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -236,7 +236,7 @@ static struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] = { {0x59, 0x27, 0x91, 0x8f, 0xc0} /* 16 */ }; -static struct XGI_CRT1TableStruct XGI_CRT1Table[] = { +const struct XGI_CRT1TableStruct XGI_CRT1Table[] = { { {0x2d, 0x28, 0x90, 0x2c, 0x90, 0x00, 0x04, 0x00, 0xbf, 0x1f, 0x9c, 0x8e, 0x96, 0xb9, 0x30} }, /* 0x0 */ { {0x2d, 0x28, 0x90, 0x2c, 0x90, 0x00, 0x04, 0x00, -- cgit v1.2.3 From 7c5c07a611069a97aafc316d701da7bd08de14ee Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:55 +0200 Subject: staging: xgifb: eliminate pVBInfo->UpdateCRT1 Access XGI_UpdateCRT1Table directly and make it const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 10 ++++------ drivers/staging/xgifb/vb_struct.h | 1 - drivers/staging/xgifb/vb_table.h | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 7ee42ac8e3a..59423addd2c 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -49,8 +49,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->SR21 = 0xa3; pVBInfo->SR22 = 0xfb; - pVBInfo->UpdateCRT1 = XGI_UpdateCRT1Table; - /* 310 customization related */ if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) pVBInfo->LCDCapList = XGI_LCDDLCapList; @@ -729,13 +727,13 @@ static void XGI_UpdateXG21CRTC(unsigned short ModeNo, if (index != -1) { xgifb_reg_set(pVBInfo->P3d4, 0x02, - pVBInfo->UpdateCRT1[index].CR02); + XGI_UpdateCRT1Table[index].CR02); xgifb_reg_set(pVBInfo->P3d4, 0x03, - pVBInfo->UpdateCRT1[index].CR03); + XGI_UpdateCRT1Table[index].CR03); xgifb_reg_set(pVBInfo->P3d4, 0x15, - pVBInfo->UpdateCRT1[index].CR15); + XGI_UpdateCRT1Table[index].CR15); xgifb_reg_set(pVBInfo->P3d4, 0x16, - pVBInfo->UpdateCRT1[index].CR16); + XGI_UpdateCRT1Table[index].CR16); } } diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 8bfbfab0464..e73ccd57e24 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -187,7 +187,6 @@ struct vb_device_info { struct SiS_VBVCLKData *VBVCLKData; struct SiS_StResInfo_S *StResInfo; struct SiS_ModeResInfo_S *ModeResInfo; - struct XGI_XG21CRT1Struct *UpdateCRT1; int ram_type; int ram_channel; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index e83c4259ce2..c08c04eaad0 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -216,7 +216,7 @@ static const struct SiS_StandTable_S XGI330_StandTable = { 0xff} }; -static struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] = { +static const struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] = { {0x01, 0x27, 0x91, 0x8f, 0xc0}, /* 00 */ {0x03, 0x4f, 0x83, 0x8f, 0xc0}, /* 01 */ {0x05, 0x27, 0x91, 0x8f, 0xc0}, /* 02 */ -- cgit v1.2.3 From 7e29d632f3e8ac2c4607e869f1601ac590d6e5f4 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:56 +0200 Subject: staging: xgifb: eliminate pVBInfo->CR6E/6F/89 Eliminate dummy zero read-only global data. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 8 ++++---- drivers/staging/xgifb/vb_setmode.c | 3 --- drivers/staging/xgifb/vb_struct.h | 3 --- drivers/staging/xgifb/vb_table.h | 6 ------ 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 7739dbd9f02..72a09601aef 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -444,7 +444,7 @@ static void XGINew_SetDRAMDefaultRegister340( temp2 = 0; for (i = 0; i < 4; i++) { /* CR6E DQM fine tune delay */ - temp = pVBInfo->CR6E[pVBInfo->ram_type][i]; + temp = 0; for (j = 0; j < 4; j++) { temp1 = ((temp >> (2 * j)) & 0x03) << 2; temp2 |= temp1; @@ -463,7 +463,7 @@ static void XGINew_SetDRAMDefaultRegister340( temp2 = 0; for (i = 0; i < 8; i++) { /* CR6F DQ fine tune delay */ - temp = pVBInfo->CR6F[pVBInfo->ram_type][8 * k + i]; + temp = 0; for (j = 0; j < 4; j++) { temp1 = (temp >> (2 * j)) & 0x03; temp2 |= temp1; @@ -486,7 +486,7 @@ static void XGINew_SetDRAMDefaultRegister340( temp2 = 0x80; /* CR89 terminator type select */ - temp = pVBInfo->CR89[pVBInfo->ram_type][0]; + temp = 0; for (j = 0; j < 4; j++) { temp1 = (temp >> (2 * j)) & 0x03; temp2 |= temp1; @@ -496,7 +496,7 @@ static void XGINew_SetDRAMDefaultRegister340( temp2 += 0x10; } - temp = pVBInfo->CR89[pVBInfo->ram_type][1]; + temp = 0; temp1 = temp & 0x03; temp2 |= temp1; xgifb_reg_set(P3d4, 0x89, temp2); diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 59423addd2c..ba5ea68c35b 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -40,9 +40,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->SR15 = XGI340_SR13; pVBInfo->CR40 = XGI340_cr41; pVBInfo->CR6B = XGI340_CR6B; - pVBInfo->CR6E = XGI340_CR6E; - pVBInfo->CR6F = XGI340_CR6F; - pVBInfo->CR89 = XGI340_CR89; pVBInfo->AGPReg = XGI340_AGPReg; pVBInfo->SR16 = XGI340_SR16; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index e73ccd57e24..5926f74861a 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -159,9 +159,6 @@ struct vb_device_info { unsigned long BaseAddr; unsigned char (*CR6B)[4]; - unsigned char (*CR6E)[4]; - unsigned char (*CR6F)[32]; - unsigned char (*CR89)[2]; unsigned char (*SR15)[8]; unsigned char (*CR40)[8]; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index c08c04eaad0..6291a112893 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -114,12 +114,6 @@ static unsigned char XGI340_CR6B[8][4] = { {0x00, 0x00, 0x00, 0x00} }; -static unsigned char XGI340_CR6E[8][4]; - -static unsigned char XGI340_CR6F[8][32]; - -static unsigned char XGI340_CR89[8][2]; - /* CR47,CR48,CR49,CR4A,CR4B,CR4C,CR70,CR71,CR74,CR75,CR76,CR77 */ static unsigned char XGI340_AGPReg[12] = { 0x28, 0x23, 0x00, 0x20, 0x00, 0x20, -- cgit v1.2.3 From 9b0474581640a47678659900262607bd0fe8a2e4 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:57 +0200 Subject: staging: xgifb: eliminate pVBInfo->ECLKData Access XGI340_ECLKData directly and make it const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_def.h | 1 + drivers/staging/xgifb/vb_init.c | 14 +++++++------- drivers/staging/xgifb/vb_setmode.c | 1 - drivers/staging/xgifb/vb_struct.h | 1 - drivers/staging/xgifb/vb_table.h | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 0fd56fbcef0..274f8cc68a0 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -262,5 +262,6 @@ extern const struct XGI_ExtStruct XGI330_EModeIDTable[]; extern const struct XGI_Ext2Struct XGI330_RefIndex[]; extern const struct XGI_CRT1TableStruct XGI_CRT1Table[]; +extern const struct XGI_ECLKDataStruct XGI340_ECLKData[]; #endif diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 72a09601aef..1be740cda81 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -124,13 +124,13 @@ static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, xgifb_reg_set(pVBInfo->P3c4, 0x2E, - pVBInfo->ECLKData[pVBInfo->ram_type].SR2E); + XGI340_ECLKData[pVBInfo->ram_type].SR2E); xgifb_reg_set(pVBInfo->P3c4, 0x2F, - pVBInfo->ECLKData[pVBInfo->ram_type].SR2F); + XGI340_ECLKData[pVBInfo->ram_type].SR2F); xgifb_reg_set(pVBInfo->P3c4, 0x30, - pVBInfo->ECLKData[pVBInfo->ram_type].SR30); + XGI340_ECLKData[pVBInfo->ram_type].SR30); /* When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */ /* Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, @@ -138,10 +138,10 @@ static void XGINew_SetMemoryClock(struct xgi_hw_device_info *HwDeviceExtension, if (HwDeviceExtension->jChipType == XG42) { if ((pVBInfo->MCLKData[pVBInfo->ram_type].SR28 == 0x1C) && (pVBInfo->MCLKData[pVBInfo->ram_type].SR29 == 0x01) && - (((pVBInfo->ECLKData[pVBInfo->ram_type].SR2E == 0x1C) && - (pVBInfo->ECLKData[pVBInfo->ram_type].SR2F == 0x01)) || - ((pVBInfo->ECLKData[pVBInfo->ram_type].SR2E == 0x22) && - (pVBInfo->ECLKData[pVBInfo->ram_type].SR2F == 0x01)))) + (((XGI340_ECLKData[pVBInfo->ram_type].SR2E == 0x1C) && + (XGI340_ECLKData[pVBInfo->ram_type].SR2F == 0x01)) || + ((XGI340_ECLKData[pVBInfo->ram_type].SR2E == 0x22) && + (XGI340_ECLKData[pVBInfo->ram_type].SR2F == 0x01)))) xgifb_reg_set(pVBInfo->P3c4, 0x32, ((unsigned char) xgifb_reg_get( diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index ba5ea68c35b..832b254281a 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -24,7 +24,6 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { pVBInfo->MCLKData = XGI340New_MCLKData; - pVBInfo->ECLKData = XGI340_ECLKData; pVBInfo->VCLKData = XGI_VCLKData; pVBInfo->VBVCLKData = XGI_VBVCLKData; pVBInfo->ScreenOffset = XGI330_ScreenOffset; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 5926f74861a..f7c5ec150da 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -169,7 +169,6 @@ struct vb_device_info { unsigned char SR22; unsigned char SR25; struct SiS_MCLKData *MCLKData; - struct XGI_ECLKDataStruct *ECLKData; unsigned char *ScreenOffset; unsigned char *pXGINew_DRAMTypeDefinition; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 6291a112893..d295eea63a5 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -22,7 +22,7 @@ static struct SiS_MCLKData XGI27New_MCLKData[] = { {0x5c, 0x23, 0x01, 166} }; -static struct XGI_ECLKDataStruct XGI340_ECLKData[] = { +const struct XGI_ECLKDataStruct XGI340_ECLKData[] = { {0x5c, 0x23, 0x01, 166}, {0x55, 0x84, 0x01, 123}, {0x7C, 0x08, 0x01, 200}, -- cgit v1.2.3 From acfe093e8227213f62e86b492b01adc9190f0546 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:58 +0200 Subject: staging: xgifb: eliminate pVBInfo->VCLKData/VBVCLKData Access XGI_VCLKData and XGI_VBVCLKData directly and make them const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 2 +- drivers/staging/xgifb/vb_def.h | 1 + drivers/staging/xgifb/vb_setmode.c | 28 +++++++++++----------------- drivers/staging/xgifb/vb_struct.h | 2 -- drivers/staging/xgifb/vb_table.h | 4 ++-- 5 files changed, 15 insertions(+), 22 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 725fba15347..4b213a318f3 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -75,7 +75,7 @@ static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr, ClockIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; - Clock = XGI_Pr->VCLKData[ClockIndex].CLOCK * 1000; + Clock = XGI_VCLKData[ClockIndex].CLOCK * 1000; return Clock; } diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 274f8cc68a0..46f9aa58bba 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -263,5 +263,6 @@ extern const struct XGI_ExtStruct XGI330_EModeIDTable[]; extern const struct XGI_Ext2Struct XGI330_RefIndex[]; extern const struct XGI_CRT1TableStruct XGI_CRT1Table[]; extern const struct XGI_ECLKDataStruct XGI340_ECLKData[]; +extern const struct SiS_VCLKData XGI_VCLKData[]; #endif diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 832b254281a..137725cbfd2 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -24,8 +24,6 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { pVBInfo->MCLKData = XGI340New_MCLKData; - pVBInfo->VCLKData = XGI_VCLKData; - pVBInfo->VBVCLKData = XGI_VBVCLKData; pVBInfo->ScreenOffset = XGI330_ScreenOffset; pVBInfo->StResInfo = XGI330_StResInfo; pVBInfo->ModeResInfo = XGI330_ModeResInfo; @@ -181,12 +179,12 @@ static unsigned char XGI_SetDefaultVCLK(struct vb_device_info *pVBInfo) { xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x20); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[0].SR2B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[0].SR2C); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[0].SR2B); + xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[0].SR2C); xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, 0x10); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, pVBInfo->VCLKData[1].SR2B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, pVBInfo->VCLKData[1].SR2C); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[1].SR2B); + xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[1].SR2C); xgifb_reg_and(pVBInfo->P3c4, 0x31, ~0x30); return 0; @@ -961,10 +959,8 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; xgifb_reg_set(pVBInfo->P3c4, 0x31, data); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, - pVBInfo->VCLKData[index].SR2B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, - pVBInfo->VCLKData[index].SR2C); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[index].SR2B); + xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[index].SR2C); xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); } else if ((pVBInfo->VBType & (VB_SIS301B | VB_SIS302B | VB_SIS301LV | VB_SIS302LV | VB_XGI301C)) && (pVBInfo->VBInfo @@ -974,19 +970,17 @@ static void XGI_SetCRT1VCLK(unsigned short ModeNo, pVBInfo); data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; xgifb_reg_set(pVBInfo->P3c4, 0x31, data); - data = pVBInfo->VBVCLKData[vclkindex].Part4_A; + data = XGI_VBVCLKData[vclkindex].Part4_A; xgifb_reg_set(pVBInfo->P3c4, 0x2B, data); - data = pVBInfo->VBVCLKData[vclkindex].Part4_B; + data = XGI_VBVCLKData[vclkindex].Part4_B; xgifb_reg_set(pVBInfo->P3c4, 0x2C, data); xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); } else { index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; data = xgifb_reg_get(pVBInfo->P3c4, 0x31) & 0xCF; xgifb_reg_set(pVBInfo->P3c4, 0x31, data); - xgifb_reg_set(pVBInfo->P3c4, 0x2B, - pVBInfo->VCLKData[index].SR2B); - xgifb_reg_set(pVBInfo->P3c4, 0x2C, - pVBInfo->VCLKData[index].SR2C); + xgifb_reg_set(pVBInfo->P3c4, 0x2B, XGI_VCLKData[index].SR2B); + xgifb_reg_set(pVBInfo->P3c4, 0x2C, XGI_VCLKData[index].SR2C); xgifb_reg_set(pVBInfo->P3c4, 0x2D, 0x01); } @@ -1053,7 +1047,7 @@ static void XGI_SetVCLKState(struct xgi_hw_device_info *HwDeviceExtension, index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; index &= IndexMask; - VCLK = pVBInfo->VCLKData[index].CLOCK; + VCLK = XGI_VCLKData[index].CLOCK; data = xgifb_reg_get(pVBInfo->P3c4, 0x32); data &= 0xf3; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index f7c5ec150da..9d1a0c724ce 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -179,8 +179,6 @@ struct vb_device_info { struct XGI_TimingHStruct TimingH; struct XGI_TimingVStruct TimingV; - struct SiS_VCLKData *VCLKData; - struct SiS_VBVCLKData *VBVCLKData; struct SiS_StResInfo_S *StResInfo; struct SiS_ModeResInfo_S *ModeResInfo; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index d295eea63a5..ea133adb0eb 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -2157,7 +2157,7 @@ static struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = { {1152, 864, 8, 16} }; -static struct SiS_VCLKData XGI_VCLKData[] = { +const struct SiS_VCLKData XGI_VCLKData[] = { /* SR2B,SR2C,SR2D */ {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ {0x4E, 0xE4, 28}, /* 01 (28.322MHz) */ @@ -2250,7 +2250,7 @@ static struct SiS_VCLKData XGI_VCLKData[] = { {0xFF, 0x00, 0} /* End mark */ }; -static struct SiS_VBVCLKData XGI_VBVCLKData[] = { +static const struct SiS_VBVCLKData XGI_VBVCLKData[] = { {0x1B, 0xE1, 25}, /* 00 (25.175MHz) */ {0x4E, 0xE4, 28}, /* 01 (28.322MHz) */ {0x57, 0xE4, 31}, /* 02 (31.500MHz) */ -- cgit v1.2.3 From 224114c788c7445aa90245ada7baa46296a06701 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:14:59 +0200 Subject: staging: xgifb: eliminate pVBInfo->ScreenOffset Access XGI330_ScreenOffset directly and make it const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 5 ++--- drivers/staging/xgifb/vb_struct.h | 1 - drivers/staging/xgifb/vb_table.h | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 137725cbfd2..137c3df9d69 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -24,7 +24,6 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { pVBInfo->MCLKData = XGI340New_MCLKData; - pVBInfo->ScreenOffset = XGI330_ScreenOffset; pVBInfo->StResInfo = XGI330_StResInfo; pVBInfo->ModeResInfo = XGI330_ModeResInfo; @@ -806,7 +805,7 @@ static void XGI_SetCRT1Offset(unsigned short ModeNo, /* GetOffset */ temp = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeInfo; temp = temp >> 8; - temp = pVBInfo->ScreenOffset[temp]; + temp = XGI330_ScreenOffset[temp]; temp2 = XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag; temp2 &= InterlaceMode; @@ -2977,7 +2976,7 @@ static unsigned short XGI_GetOffset(unsigned short ModeNo, index = (modeinfo >> 8) & 0xFF; - temp = pVBInfo->ScreenOffset[index]; + temp = XGI330_ScreenOffset[index]; if (infoflag & InterlaceMode) temp = temp << 1; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 9d1a0c724ce..d0ca193ccf1 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -170,7 +170,6 @@ struct vb_device_info { unsigned char SR25; struct SiS_MCLKData *MCLKData; - unsigned char *ScreenOffset; unsigned char *pXGINew_DRAMTypeDefinition; unsigned char XGINew_CR97; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index ea133adb0eb..453c5286104 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -2117,7 +2117,7 @@ const struct XGI_Ext2Struct XGI330_RefIndex[] = { 0x30, 0x47, 0x37, 1024, 768},/* 48 1024x768x160Hz */ }; -static unsigned char XGI330_ScreenOffset[] = { +static const unsigned char XGI330_ScreenOffset[] = { 0x14, 0x19, 0x20, 0x28, 0x32, 0x40, 0x50, 0x64, 0x78, 0x80, 0x2d, 0x35, 0x57, 0x48 -- cgit v1.2.3 From e8e6c754e50fd05f8e44cd88fddb948d9c1e6740 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:15:00 +0200 Subject: staging: xgifb: eliminate pVBInfo->ModeResInfo Access XGI330_ModeResInfo directly and make it const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 23 +++++++++++------------ drivers/staging/xgifb/vb_struct.h | 1 - drivers/staging/xgifb/vb_table.h | 2 +- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 137c3df9d69..3bc1ad21697 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -25,7 +25,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { pVBInfo->MCLKData = XGI340New_MCLKData; pVBInfo->StResInfo = XGI330_StResInfo; - pVBInfo->ModeResInfo = XGI330_ModeResInfo; pVBInfo->LCDResInfo = 0; pVBInfo->LCDTypeInfo = 0; @@ -742,8 +741,8 @@ static void XGI_SetCRT1DE(struct xgi_hw_device_info *HwDeviceExtension, resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; - tempax = pVBInfo->ModeResInfo[resindex].HTotal; - tempbx = pVBInfo->ModeResInfo[resindex].VTotal; + tempax = XGI330_ModeResInfo[resindex].HTotal; + tempbx = XGI330_ModeResInfo[resindex].VTotal; if (modeflag & HalfDCLK) tempax = tempax >> 1; @@ -1101,7 +1100,7 @@ static void XGI_SetCRT1ModeRegs(struct xgi_hw_device_info *HwDeviceExtension, xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x3F, data2); resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ + xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ data = 0x0000; if (infoflag & InterlaceMode) { @@ -1267,8 +1266,8 @@ static void XGI_GetLVDSResInfo(unsigned short ModeNo, /* si+Ext_ResInfo */ resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = pVBInfo->ModeResInfo[resindex].HTotal; - yres = pVBInfo->ModeResInfo[resindex].VTotal; + xres = XGI330_ModeResInfo[resindex].HTotal; + yres = XGI330_ModeResInfo[resindex].VTotal; if (modeflag & HalfDCLK) xres = xres << 1; @@ -2631,8 +2630,8 @@ static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short xres, yres, modeflag, resindex; resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ + xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ + yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */ /* si+St_ModeFlag */ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; @@ -4502,8 +4501,8 @@ static unsigned char XGI_XG21CheckLVDSMode(struct xgifb_video_info *xgifb_info, unsigned short xres, yres, colordepth, modeflag, resindex; resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ + xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ + yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */ /* si+St_ModeFlag */ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; @@ -4564,8 +4563,8 @@ static void xgifb_set_lvds(struct xgifb_video_info *xgifb_info, XGI_SetXG21FPBits(pVBInfo); resindex = XGI330_EModeIDTable[ModeIdIndex].Ext_RESINFO; - xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */ - yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */ + xres = XGI330_ModeResInfo[resindex].HTotal; /* xres->ax */ + yres = XGI330_ModeResInfo[resindex].VTotal; /* yres->bx */ /* si+St_ModeFlag */ modeflag = XGI330_EModeIDTable[ModeIdIndex].Ext_ModeFlag; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index d0ca193ccf1..b670213b4da 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -179,7 +179,6 @@ struct vb_device_info { struct XGI_TimingVStruct TimingV; struct SiS_StResInfo_S *StResInfo; - struct SiS_ModeResInfo_S *ModeResInfo; int ram_type; int ram_channel; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 453c5286104..9c8b460786f 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -2131,7 +2131,7 @@ static struct SiS_StResInfo_S XGI330_StResInfo[] = { {640, 480} }; -static struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = { +static const struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = { { 320, 200, 8, 8}, { 320, 240, 8, 8}, { 320, 400, 8, 8}, -- cgit v1.2.3 From c705ea816585867d70903d9dbe3ecf64e368505a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:15:01 +0200 Subject: staging: xgifb: eliminate pVBInfo->StResInfo Delete unused data. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 1 - drivers/staging/xgifb/vb_struct.h | 2 -- drivers/staging/xgifb/vb_table.h | 8 -------- 3 files changed, 11 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 3bc1ad21697..2ffa35e1e9d 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -24,7 +24,6 @@ static const unsigned short XGINew_VGA_DAC[] = { void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) { pVBInfo->MCLKData = XGI340New_MCLKData; - pVBInfo->StResInfo = XGI330_StResInfo; pVBInfo->LCDResInfo = 0; pVBInfo->LCDTypeInfo = 0; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index b670213b4da..8353f169254 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -178,8 +178,6 @@ struct vb_device_info { struct XGI_TimingHStruct TimingH; struct XGI_TimingVStruct TimingV; - struct SiS_StResInfo_S *StResInfo; - int ram_type; int ram_channel; int ram_bus; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 9c8b460786f..381d07f7671 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -2123,14 +2123,6 @@ static const unsigned char XGI330_ScreenOffset[] = { 0x57, 0x48 }; -static struct SiS_StResInfo_S XGI330_StResInfo[] = { - {640, 400}, - {640, 350}, - {720, 400}, - {720, 350}, - {640, 480} -}; - static const struct SiS_ModeResInfo_S XGI330_ModeResInfo[] = { { 320, 200, 8, 8}, { 320, 240, 8, 8}, -- cgit v1.2.3 From 38c09652a0620095b545d91c5806544e99f5effc Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:15:02 +0200 Subject: staging: xgifb: eliminate pVBInfo->SR21/22/25 In-line constants that are used only once. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_def.h | 1 - drivers/staging/xgifb/vb_init.c | 9 +++------ drivers/staging/xgifb/vb_setmode.c | 3 --- drivers/staging/xgifb/vb_struct.h | 3 --- 4 files changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 46f9aa58bba..a519d3005a4 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -254,7 +254,6 @@ #define XGI330_SR1F 0 #define XGI330_SR23 0xf6 #define XGI330_SR24 0x0d -#define XGI330_SR25 0 #define XGI330_SR31 0xc0 #define XGI330_SR32 0x11 #define XGI330_SR33 0 diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 1be740cda81..8f6090b6ffd 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1401,7 +1401,7 @@ unsigned char XGIInitNew(struct pci_dev *pdev) /* Set PCI */ xgifb_reg_set(pVBInfo->P3c4, 0x23, XGI330_SR23); xgifb_reg_set(pVBInfo->P3c4, 0x24, XGI330_SR24); - xgifb_reg_set(pVBInfo->P3c4, 0x25, XGI330_SR25); + xgifb_reg_set(pVBInfo->P3c4, 0x25, 0); if (HwDeviceExtension->jChipType < XG20) { /* Set VB */ @@ -1482,11 +1482,8 @@ unsigned char XGIInitNew(struct pci_dev *pdev) XGINew_SetDRAMSize_340(xgifb_info, HwDeviceExtension, pVBInfo); - xgifb_reg_set(pVBInfo->P3c4, - 0x22, - (unsigned char) ((pVBInfo->SR22) & 0xFE)); - - xgifb_reg_set(pVBInfo->P3c4, 0x21, pVBInfo->SR21); + xgifb_reg_set(pVBInfo->P3c4, 0x22, 0xfa); + xgifb_reg_set(pVBInfo->P3c4, 0x21, 0xa3); XGINew_ChkSenseStatus(HwDeviceExtension, pVBInfo); XGINew_SetModeScratch(HwDeviceExtension, pVBInfo); diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 2ffa35e1e9d..70912dc10c4 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -37,9 +37,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->AGPReg = XGI340_AGPReg; pVBInfo->SR16 = XGI340_SR16; - pVBInfo->SR21 = 0xa3; - pVBInfo->SR22 = 0xfb; - /* 310 customization related */ if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) pVBInfo->LCDCapList = XGI_LCDDLCapList; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 8353f169254..201fcc5b58f 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -165,9 +165,6 @@ struct vb_device_info { unsigned char *AGPReg; unsigned char *SR16; - unsigned char SR21; - unsigned char SR22; - unsigned char SR25; struct SiS_MCLKData *MCLKData; unsigned char *pXGINew_DRAMTypeDefinition; -- cgit v1.2.3 From 5ce24760f6cab10b3138d9b2b959f2944827fa50 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:15:03 +0200 Subject: staging: xgifb: eliminate pVBInfo->CR6B Access XGI340_CR6B directly and make it const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_def.h | 1 + drivers/staging/xgifb/vb_init.c | 2 +- drivers/staging/xgifb/vb_setmode.c | 1 - drivers/staging/xgifb/vb_struct.h | 2 -- drivers/staging/xgifb/vb_table.h | 2 +- 5 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index a519d3005a4..ee13b848dce 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -263,5 +263,6 @@ extern const struct XGI_Ext2Struct XGI330_RefIndex[]; extern const struct XGI_CRT1TableStruct XGI_CRT1Table[]; extern const struct XGI_ECLKDataStruct XGI340_ECLKData[]; extern const struct SiS_VCLKData XGI_VCLKData[]; +extern const unsigned char XGI340_CR6B[][4]; #endif diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 8f6090b6ffd..ce419d4c950 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -429,7 +429,7 @@ static void XGINew_SetDRAMDefaultRegister340( temp2 = 0; for (i = 0; i < 4; i++) { /* CR6B DQS fine tune delay */ - temp = pVBInfo->CR6B[pVBInfo->ram_type][i]; + temp = XGI340_CR6B[pVBInfo->ram_type][i]; for (j = 0; j < 4; j++) { temp1 = ((temp >> (2 * j)) & 0x03) << 2; temp2 |= temp1; diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 70912dc10c4..e863ec9f4e0 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -33,7 +33,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->SR15 = XGI340_SR13; pVBInfo->CR40 = XGI340_cr41; - pVBInfo->CR6B = XGI340_CR6B; pVBInfo->AGPReg = XGI340_AGPReg; pVBInfo->SR16 = XGI340_SR16; diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 201fcc5b58f..2edd0896cf0 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -158,8 +158,6 @@ struct vb_device_info { void __iomem *FBAddr; unsigned long BaseAddr; - unsigned char (*CR6B)[4]; - unsigned char (*SR15)[8]; unsigned char (*CR40)[8]; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 381d07f7671..18200eb5fba 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -103,7 +103,7 @@ static unsigned char XGI27_cr41[24][8] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 23 CRC5 */ }; -static unsigned char XGI340_CR6B[8][4] = { +const unsigned char XGI340_CR6B[8][4] = { {0xaa, 0xaa, 0xaa, 0xaa}, {0xaa, 0xaa, 0xaa, 0xaa}, {0xaa, 0xaa, 0xaa, 0xaa}, -- cgit v1.2.3 From 0904f7f315cc1a3c643b49751147bc5f3c8a22d4 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:15:04 +0200 Subject: staging: xgifb: eliminate pVBInfo->SR16 Inline constant values that are used only once. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_init.c | 8 ++++---- drivers/staging/xgifb/vb_setmode.c | 1 - drivers/staging/xgifb/vb_struct.h | 1 - drivers/staging/xgifb/vb_table.h | 2 -- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index ce419d4c950..213ec1366a9 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -94,8 +94,8 @@ static void XGINew_DDR1x_MRS_340(unsigned long P3c4, 0x18, pVBInfo->SR15[2][pVBInfo->ram_type]); /* SR18 */ xgifb_reg_set(P3c4, 0x19, 0x01); - xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[0]); - xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[1]); + xgifb_reg_set(P3c4, 0x16, 0x03); + xgifb_reg_set(P3c4, 0x16, 0x83); mdelay(1); xgifb_reg_set(P3c4, 0x1B, 0x03); udelay(500); @@ -103,8 +103,8 @@ static void XGINew_DDR1x_MRS_340(unsigned long P3c4, 0x18, pVBInfo->SR15[2][pVBInfo->ram_type]); /* SR18 */ xgifb_reg_set(P3c4, 0x19, 0x00); - xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[2]); - xgifb_reg_set(P3c4, 0x16, pVBInfo->SR16[3]); + xgifb_reg_set(P3c4, 0x16, 0x03); + xgifb_reg_set(P3c4, 0x16, 0x83); xgifb_reg_set(P3c4, 0x1B, 0x00); } diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index e863ec9f4e0..4d50940899c 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -34,7 +34,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->SR15 = XGI340_SR13; pVBInfo->CR40 = XGI340_cr41; pVBInfo->AGPReg = XGI340_AGPReg; - pVBInfo->SR16 = XGI340_SR16; /* 310 customization related */ if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 2edd0896cf0..407b4a7c100 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -162,7 +162,6 @@ struct vb_device_info { unsigned char (*CR40)[8]; unsigned char *AGPReg; - unsigned char *SR16; struct SiS_MCLKData *MCLKData; unsigned char *pXGINew_DRAMTypeDefinition; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 18200eb5fba..f0fd0ecba15 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -120,8 +120,6 @@ static unsigned char XGI340_AGPReg[12] = { 0x00, 0x05, 0xd0, 0x10, 0x10, 0x00 }; -static unsigned char XGI340_SR16[4] = {0x03, 0x83, 0x03, 0x83}; - const struct XGI_ExtStruct XGI330_EModeIDTable[] = { {0x2e, 0x0a1b, 0x0306, 0x06, 0x05, 0x06}, {0x2f, 0x0a1b, 0x0305, 0x05, 0x05, 0x05}, -- cgit v1.2.3 From ea12b4e077b86998f73740be7eadb7b08481ea36 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:15:05 +0200 Subject: staging: xgifb: eliminate pVBInfo->AGPReg Access XGI340_AGPReg directly and make it const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_def.h | 1 + drivers/staging/xgifb/vb_init.c | 6 +++--- drivers/staging/xgifb/vb_setmode.c | 1 - drivers/staging/xgifb/vb_struct.h | 1 - drivers/staging/xgifb/vb_table.h | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index ee13b848dce..148f6373c9a 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -264,5 +264,6 @@ extern const struct XGI_CRT1TableStruct XGI_CRT1Table[]; extern const struct XGI_ECLKDataStruct XGI340_ECLKData[]; extern const struct SiS_VCLKData XGI_VCLKData[]; extern const unsigned char XGI340_CR6B[][4]; +extern const unsigned char XGI340_AGPReg[]; #endif diff --git a/drivers/staging/xgifb/vb_init.c b/drivers/staging/xgifb/vb_init.c index 213ec1366a9..2b791c10eb1 100644 --- a/drivers/staging/xgifb/vb_init.c +++ b/drivers/staging/xgifb/vb_init.c @@ -1378,17 +1378,17 @@ unsigned char XGIInitNew(struct pci_dev *pdev) for (i = 0x47; i <= 0x4C; i++) xgifb_reg_set(pVBInfo->P3d4, i, - pVBInfo->AGPReg[i - 0x47]); + XGI340_AGPReg[i - 0x47]); for (i = 0x70; i <= 0x71; i++) xgifb_reg_set(pVBInfo->P3d4, i, - pVBInfo->AGPReg[6 + i - 0x70]); + XGI340_AGPReg[6 + i - 0x70]); for (i = 0x74; i <= 0x77; i++) xgifb_reg_set(pVBInfo->P3d4, i, - pVBInfo->AGPReg[8 + i - 0x74]); + XGI340_AGPReg[8 + i - 0x74]); pci_read_config_dword(pdev, 0x50, &Temp); Temp >>= 20; diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index 4d50940899c..eaa5686a5fc 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -33,7 +33,6 @@ void InitTo330Pointer(unsigned char ChipType, struct vb_device_info *pVBInfo) pVBInfo->SR15 = XGI340_SR13; pVBInfo->CR40 = XGI340_cr41; - pVBInfo->AGPReg = XGI340_AGPReg; /* 310 customization related */ if ((pVBInfo->VBType & VB_SIS301LV) || (pVBInfo->VBType & VB_SIS302LV)) diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 407b4a7c100..60aecb4af26 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -161,7 +161,6 @@ struct vb_device_info { unsigned char (*SR15)[8]; unsigned char (*CR40)[8]; - unsigned char *AGPReg; struct SiS_MCLKData *MCLKData; unsigned char *pXGINew_DRAMTypeDefinition; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index f0fd0ecba15..4d7a70e7bdf 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -115,7 +115,7 @@ const unsigned char XGI340_CR6B[8][4] = { }; /* CR47,CR48,CR49,CR4A,CR4B,CR4C,CR70,CR71,CR74,CR75,CR76,CR77 */ -static unsigned char XGI340_AGPReg[12] = { +const unsigned char XGI340_AGPReg[12] = { 0x28, 0x23, 0x00, 0x20, 0x00, 0x20, 0x00, 0x05, 0xd0, 0x10, 0x10, 0x00 }; -- cgit v1.2.3 From 1cccd9e41db141b04b919085b1447f6997786fc4 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:15:06 +0200 Subject: staging: xgifb: constify Tap4 data Make Tap4 data const and adjust functions accordingly. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 10 ++++------ drivers/staging/xgifb/vb_table.h | 8 ++++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index eaa5686a5fc..e469a8e7906 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -4148,12 +4148,11 @@ static void XGI_SetLCDRegs(unsigned short ModeNo, unsigned short ModeIdIndex, /* Output : di -> Tap4 Reg. Setting Pointer */ /* Description : */ /* --------------------------------------------------------------------- */ -static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, - struct vb_device_info *pVBInfo) +static struct XGI301C_Tap4TimingStruct const +*XGI_GetTap4Ptr(unsigned short tempcx, struct vb_device_info *pVBInfo) { unsigned short tempax, tempbx, i; - - struct XGI301C_Tap4TimingStruct *Tap4TimingPtr; + struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr; if (tempcx == 0) { tempax = pVBInfo->VGAHDE; @@ -4194,8 +4193,7 @@ static struct XGI301C_Tap4TimingStruct *XGI_GetTap4Ptr(unsigned short tempcx, static void XGI_SetTap4Regs(struct vb_device_info *pVBInfo) { unsigned short i, j; - - struct XGI301C_Tap4TimingStruct *Tap4TimingPtr; + struct XGI301C_Tap4TimingStruct const *Tap4TimingPtr; if (!(pVBInfo->VBType & VB_XGI301C)) return; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 4d7a70e7bdf..9104d4ada27 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -2421,7 +2421,7 @@ static unsigned char XGI_NTSC1024AdjTime[] = { 0x58, 0xe4, 0x73, 0xd0, 0x13 }; -static struct XGI301C_Tap4TimingStruct xgifb_tap4_timing[] = { +static const struct XGI301C_Tap4TimingStruct xgifb_tap4_timing[] = { {0, { 0x00, 0x20, 0x00, 0x00, 0x7F, 0x20, 0x02, 0x7F, /* ; C0-C7 */ 0x7D, 0x20, 0x04, 0x7F, 0x7D, 0x1F, 0x06, 0x7E, /* ; C8-CF */ @@ -2435,7 +2435,7 @@ static struct XGI301C_Tap4TimingStruct xgifb_tap4_timing[] = { } }; -static struct XGI301C_Tap4TimingStruct PALTap4Timing[] = { +static const struct XGI301C_Tap4TimingStruct PALTap4Timing[] = { {600, { 0x05, 0x19, 0x05, 0x7D, 0x03, 0x19, 0x06, 0x7E, /* ; C0-C7 */ 0x02, 0x19, 0x08, 0x7D, 0x01, 0x18, 0x0A, 0x7D, /* ; C8-CF */ @@ -2471,7 +2471,7 @@ static struct XGI301C_Tap4TimingStruct PALTap4Timing[] = { } }; -static struct XGI301C_Tap4TimingStruct xgifb_ntsc_525_tap4_timing[] = { +static const struct XGI301C_Tap4TimingStruct xgifb_ntsc_525_tap4_timing[] = { {480, { 0x04, 0x1A, 0x04, 0x7E, 0x03, 0x1A, 0x06, 0x7D, /* ; C0-C7 */ 0x01, 0x1A, 0x08, 0x7D, 0x00, 0x19, 0x0A, 0x7D, /* ; C8-CF */ @@ -2507,7 +2507,7 @@ static struct XGI301C_Tap4TimingStruct xgifb_ntsc_525_tap4_timing[] = { } }; -static struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] = { +static const struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] = { {0xFFFF, { 0x05, 0x19, 0x05, 0x7D, 0x03, 0x19, 0x06, 0x7E, /* ; C0-C7 */ 0x02, 0x19, 0x08, 0x7D, 0x01, 0x18, 0x0A, 0x7D, /* ; C8-CF */ -- cgit v1.2.3 From a68292fce139f88bb85b8a53ac9df376063172c3 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sun, 4 Nov 2012 21:15:07 +0200 Subject: staging: xgifb: make remaining data tables const Remaining vb_table.h data can be trivially made const. Signed-off-by: Aaro Koskinen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/vb_setmode.c | 4 ++-- drivers/staging/xgifb/vb_struct.h | 6 +++--- drivers/staging/xgifb/vb_table.h | 28 ++++++++++++++-------------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index e469a8e7906..d723a257199 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -5220,8 +5220,8 @@ static void XGI_SetYFilter(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo) { unsigned short tempbx, index; - - unsigned char tempcl, tempch, tempal, *filterPtr; + unsigned char const *filterPtr; + unsigned char tempcl, tempch, tempal; XGI_GetTVPtrIndex2(&tempbx, &tempcl, &tempch, pVBInfo); /* bx, cl, ch */ diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 60aecb4af26..acf6e7fbbae 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -158,10 +158,10 @@ struct vb_device_info { void __iomem *FBAddr; unsigned long BaseAddr; - unsigned char (*SR15)[8]; - unsigned char (*CR40)[8]; + unsigned char const (*SR15)[8]; + unsigned char const (*CR40)[8]; - struct SiS_MCLKData *MCLKData; + struct SiS_MCLKData const *MCLKData; unsigned char *pXGINew_DRAMTypeDefinition; unsigned char XGINew_CR97; diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index 9104d4ada27..39f528b14f0 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -1,6 +1,6 @@ #ifndef _VB_TABLE_ #define _VB_TABLE_ -static struct SiS_MCLKData XGI340New_MCLKData[] = { +static const struct SiS_MCLKData XGI340New_MCLKData[] = { {0x16, 0x01, 0x01, 166}, {0x19, 0x02, 0x01, 124}, {0x7C, 0x08, 0x01, 200}, @@ -11,7 +11,7 @@ static struct SiS_MCLKData XGI340New_MCLKData[] = { {0x5c, 0x23, 0x01, 166} }; -static struct SiS_MCLKData XGI27New_MCLKData[] = { +static const struct SiS_MCLKData XGI27New_MCLKData[] = { {0x5c, 0x23, 0x01, 166}, {0x19, 0x02, 0x01, 124}, {0x7C, 0x08, 0x80, 200}, @@ -33,21 +33,21 @@ const struct XGI_ECLKDataStruct XGI340_ECLKData[] = { {0x5c, 0x23, 0x01, 166} }; -static unsigned char XG27_SR13[4][8] = { +static const unsigned char XG27_SR13[4][8] = { {0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */ {0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */ {0x32, 0x32, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR18 */ {0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00} /* SR1B */ }; -static unsigned char XGI340_SR13[4][8] = { +static const unsigned char XGI340_SR13[4][8] = { {0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */ {0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */ {0x31, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR18 */ {0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00} /* SR1B */ }; -static unsigned char XGI340_cr41[24][8] = { +static const unsigned char XGI340_cr41[24][8] = { {0x20, 0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0 CR41 */ {0xc4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1 CR8A */ {0xc4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2 CR8B */ @@ -74,7 +74,7 @@ static unsigned char XGI340_cr41[24][8] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 23 CRC5 */ }; -static unsigned char XGI27_cr41[24][8] = { +static const unsigned char XGI27_cr41[24][8] = { {0x20, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0 CR41 */ {0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1 CR8A */ {0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2 CR8B */ @@ -2335,7 +2335,7 @@ static const struct SiS_VBVCLKData XGI_VBVCLKData[] = { #define XGI301TVDelay 0x22 #define XGI301LCDDelay 0x12 -static unsigned char TVAntiFlickList[] = {/* NTSCAntiFlicker */ +static const unsigned char TVAntiFlickList[] = {/* NTSCAntiFlicker */ 0x04, /* ; 0 Adaptive */ 0x00, /* ; 1 new anti-flicker ? */ @@ -2347,7 +2347,7 @@ static unsigned char TVAntiFlickList[] = {/* NTSCAntiFlicker */ }; -static unsigned char TVEdgeList[] = { +static const unsigned char TVEdgeList[] = { 0x00, /* ; 0 NTSC No Edge enhance */ 0x04, /* ; 1 NTSC Adaptive Edge enhance */ 0x00, /* ; 0 PAL No Edge enhance */ @@ -2356,7 +2356,7 @@ static unsigned char TVEdgeList[] = { 0x00 /* ; 1 HiTV */ }; -static unsigned long TVPhaseList[] = { +static const unsigned long TVPhaseList[] = { 0x08BAED21, /* ; 0 NTSC phase */ 0x00E3052A, /* ; 1 PAL phase */ 0x9B2EE421, /* ; 2 PAL-M phase */ @@ -2373,7 +2373,7 @@ static unsigned long TVPhaseList[] = { 0xE00A831E /* ; D PAL-M 1024x768 */ }; -static unsigned char NTSCYFilter1[] = { +static const unsigned char NTSCYFilter1[] = { 0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */ 0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */ 0xEB, 0x04, 0x25, 0x18, /* 2 : 640x text mode */ @@ -2383,7 +2383,7 @@ static unsigned char NTSCYFilter1[] = { 0xEB, 0x15, 0x25, 0xF6 /* 6 : 800x gra. mode */ }; -static unsigned char PALYFilter1[] = { +static const unsigned char PALYFilter1[] = { 0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */ 0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */ 0xF1, 0xF7, 0x1F, 0x32, /* 2 : 640x text mode */ @@ -2393,7 +2393,7 @@ static unsigned char PALYFilter1[] = { 0xFC, 0xFB, 0x14, 0x2A /* 6 : 800x gra. mode */ }; -static unsigned char xgifb_palmn_yfilter1[] = { +static const unsigned char xgifb_palmn_yfilter1[] = { 0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */ 0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */ 0xEB, 0x04, 0x10, 0x18, /* 2 : 640x text mode */ @@ -2404,7 +2404,7 @@ static unsigned char xgifb_palmn_yfilter1[] = { 0xFF, 0xFF, 0xFF, 0xFF /* End of Table */ }; -static unsigned char xgifb_yfilter2[] = { +static const unsigned char xgifb_yfilter2[] = { 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 0 : 320x text mode */ 0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 1 : 360x text mode */ 0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 2 : 640x text mode */ @@ -2415,7 +2415,7 @@ static unsigned char xgifb_yfilter2[] = { 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28 /* 7 : 1024xgra. mode */ }; -static unsigned char XGI_NTSC1024AdjTime[] = { +static const unsigned char XGI_NTSC1024AdjTime[] = { 0xa7, 0x07, 0xf2, 0x6e, 0x17, 0x8b, 0x73, 0x53, 0x13, 0x40, 0x34, 0xF4, 0x63, 0xBB, 0xCC, 0x7A, 0x58, 0xe4, 0x73, 0xd0, 0x13 -- cgit v1.2.3 From d38e0e3fed4f58bcddef4dc93a591dfe2f651cb0 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 7 Nov 2012 18:21:51 -0800 Subject: Revert "Staging: Android alarm: IOCTL command encoding fix" Commit 6bd4a5d96c08dc2380f8053b1bd4f879f55cd3c9 changed the ANDROID_ALARM_GET_TIME ioctls from IOW to IOR. While technically correct, the _IOC_DIR bits are ignored by alarm_ioctl, so the commit breaks a userspace ABI used by all existing Android devices for a purely cosmetic reason. Revert it. Cc: stable Cc: Dae S. Kim Signed-off-by: Colin Cross Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/android_alarm.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index f2ffd963f1c..d0cafd63719 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h @@ -51,12 +51,10 @@ enum android_alarm_return_flags { #define ANDROID_ALARM_WAIT _IO('a', 1) #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) -#define ALARM_IOR(c, type, size) _IOR('a', (c) | ((type) << 4), size) - /* Set alarm */ #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) -#define ANDROID_ALARM_GET_TIME(type) ALARM_IOR(4, type, struct timespec) +#define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) -- cgit v1.2.3 From 695bcb1c0a50e8fe04f0ab868cac849130788bc0 Mon Sep 17 00:00:00 2001 From: Harvey Yang Date: Tue, 6 Nov 2012 16:10:29 +0800 Subject: staging: usbip: put usb_device and kill event handler thread in error cleanups. If probe returns with error, the kthread is still alive even when all usbip modules unloaded. So do cleanups in error handler. Signed-off-by: harvey.yang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/stub_dev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c index 79298d06863..ee36415eb26 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@ -433,6 +433,8 @@ static int stub_probe(struct usb_interface *interface, dev_err(&interface->dev, "stub_add_files for %s\n", udev_busid); usb_set_intfdata(interface, NULL); usb_put_intf(interface); + usb_put_dev(udev); + kthread_stop_put(sdev->ud.eh); busid_priv->interf_count = 0; busid_priv->sdev = NULL; -- cgit v1.2.3 From 8ee271f63ab41312a998a602fd9c8c965f325487 Mon Sep 17 00:00:00 2001 From: Kumar Amit Mehta Date: Tue, 6 Nov 2012 22:38:37 -0800 Subject: staging: tidspbridge: dynload: dload_internal.h: fix for coding style issue fixed few error messages as reported by checkpatch.pl Signed-off-by: Kumar Amit Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/dynload/dload_internal.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/tidspbridge/dynload/dload_internal.h b/drivers/staging/tidspbridge/dynload/dload_internal.h index 7b77573fba5..b9d079b9619 100644 --- a/drivers/staging/tidspbridge/dynload/dload_internal.h +++ b/drivers/staging/tidspbridge/dynload/dload_internal.h @@ -313,14 +313,14 @@ extern uint32_t dload_reverse_checksum16(void *data, unsigned siz); /* * exported by reloc.c */ -extern void dload_relocate(struct dload_state *dlthis, tgt_au_t * data, - struct reloc_record_t *rp, bool * tramps_generated, +extern void dload_relocate(struct dload_state *dlthis, tgt_au_t *data, + struct reloc_record_t *rp, bool *tramps_generated, bool second_pass); -extern rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t * data, +extern rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t *data, int fieldsz, int offset, unsigned sgn); -extern int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t * data, +extern int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t *data, int fieldsz, int offset, unsigned sgn); /* -- cgit v1.2.3 From 466cd9f53016b1cfd7812bf1f95b40697c48ff06 Mon Sep 17 00:00:00 2001 From: Kumar Amit Mehta Date: Tue, 6 Nov 2012 22:52:55 -0800 Subject: staging: tidspbridge: dynload: reloc.c: checkpatch.pl cleanup fix for few error messages as reported by checkpatch.pl Signed-off-by: Kumar Amit Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/tidspbridge/dynload/reloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/tidspbridge/dynload/reloc.c b/drivers/staging/tidspbridge/dynload/reloc.c index 7b28c07ed7c..463abdb6392 100644 --- a/drivers/staging/tidspbridge/dynload/reloc.c +++ b/drivers/staging/tidspbridge/dynload/reloc.c @@ -45,7 +45,7 @@ static const char bsssymbol[] = { ".bss" }; * Effect: * Extracts the specified field and returns it. ************************************************************************* */ -rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t * data, int fieldsz, +rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t *data, int fieldsz, int offset, unsigned sgn) { register rvalue objval; @@ -98,7 +98,7 @@ rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t * data, int fieldsz, ************************************************************************* */ static const unsigned char ovf_limit[] = { 1, 2, 2 }; -int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t * data, +int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t *data, int fieldsz, int offset, unsigned sgn) { register urvalue objval, mask; @@ -161,7 +161,7 @@ static const u8 c60_scale[SCALE_MASK + 1] = { * Effect: * Performs the specified relocation operation ************************************************************************* */ -void dload_relocate(struct dload_state *dlthis, tgt_au_t * data, +void dload_relocate(struct dload_state *dlthis, tgt_au_t *data, struct reloc_record_t *rp, bool *tramps_generated, bool second_pass) { -- cgit v1.2.3 From c299647f0c045a82e0790332433d2df82da6115a Mon Sep 17 00:00:00 2001 From: Adil Mujeeb Date: Thu, 8 Nov 2012 00:20:00 +0530 Subject: Staging: winbond: wbusb: Fixed coding style issue Removed unnecessary printk and pr_debug tracing calls Signed-off-by: Adil Mujeeb Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wbusb.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 48aa1361903..3fa1ae4d3d7 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -79,18 +79,15 @@ static int wbsoft_add_interface(struct ieee80211_hw *dev, static void wbsoft_remove_interface(struct ieee80211_hw *dev, struct ieee80211_vif *vif) { - printk("wbsoft_remove interface called\n"); } static void wbsoft_stop(struct ieee80211_hw *hw) { - printk(KERN_INFO "%s called\n", __func__); } static int wbsoft_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) { - printk(KERN_INFO "%s called\n", __func__); return 0; } @@ -179,12 +176,9 @@ static void hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info if (pHwData->SurpriseRemove) return; - printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo); - RFSynthesizer_SwitchingChannel(pHwData, channel); /* Switch channel */ pHwData->Channel = channel.ChanNo; pHwData->band = channel.band; - pr_debug("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band); reg->M28_MacControl &= ~0xff; /* Clean channel information field */ reg->M28_MacControl |= channel.ChanNo; Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl, @@ -264,8 +258,6 @@ static int wbsoft_config(struct ieee80211_hw *dev, u32 changed) struct wbsoft_priv *priv = dev->priv; struct chan_info ch; - printk("wbsoft_config called\n"); - /* Should use channel_num, or something, as that is already pre-translated */ ch.band = 1; ch.ChanNo = 1; @@ -282,7 +274,6 @@ static int wbsoft_config(struct ieee80211_hw *dev, u32 changed) static u64 wbsoft_get_tsf(struct ieee80211_hw *dev, struct ieee80211_vif *vif) { - printk("wbsoft_get_tsf called\n"); return 0; } @@ -716,7 +707,6 @@ static int wb35_hw_init(struct ieee80211_hw *hw) } priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData); - pr_debug("Driver init, antenna no = %d\n", priv->sLocalPara.bAntennaNo); hal_get_hw_radio_off(pHwData); /* Waiting for HAL setting OK */ @@ -782,9 +772,6 @@ static int wb35_probe(struct usb_interface *intf, interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; - if (endpoint[2].wMaxPacketSize == 512) - printk("[w35und] Working on USB 2.0\n"); - err = wb35_hw_init(dev); if (err) goto error_free_hw; @@ -836,7 +823,6 @@ static void wb35_hw_halt(struct wbsoft_priv *adapter) { /* Turn off Rx and Tx hardware ability */ hal_stop(&adapter->sHwData); - pr_debug("[w35und] Hal_stop O.K.\n"); /* Waiting Irp completed */ msleep(100); -- cgit v1.2.3 From 746f0c5a3ee43ff0628334a7f40fd41df8d87b24 Mon Sep 17 00:00:00 2001 From: Adil Mujeeb Date: Thu, 8 Nov 2012 00:20:02 +0530 Subject: Staging: winbond: wb35rx_f: Fixed coding style issues Fixed checkpatch.pl reported ERRORs Signed-off-by: Adil Mujeeb Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wb35rx_f.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/winbond/wb35rx_f.h b/drivers/staging/winbond/wb35rx_f.h index 1fdf65ea604..559bdca12e1 100644 --- a/drivers/staging/winbond/wb35rx_f.h +++ b/drivers/staging/winbond/wb35rx_f.h @@ -4,12 +4,12 @@ #include #include "wbhal.h" -//==================================== -// Interface function declare -//==================================== -unsigned char Wb35Rx_initial( struct hw_data * pHwData ); -void Wb35Rx_destroy( struct hw_data * pHwData ); -void Wb35Rx_stop( struct hw_data * pHwData ); +/* + * Interface function declaration + */ +unsigned char Wb35Rx_initial(struct hw_data *pHwData); +void Wb35Rx_destroy(struct hw_data *pHwData); +void Wb35Rx_stop(struct hw_data *pHwData); void Wb35Rx_start(struct ieee80211_hw *hw); #endif -- cgit v1.2.3 From 2820663c6f08f838398b0727773fb44e08876969 Mon Sep 17 00:00:00 2001 From: Adil Mujeeb Date: Thu, 8 Nov 2012 00:20:01 +0530 Subject: Staging: winbond: mds: Fixed coding style issues Removed printk tracing call Signed-off-by: Adil Mujeeb Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index 43990e87d64..faa93f0ee10 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -476,11 +476,8 @@ Mds_Tx(struct wbsoft_priv *adapter) /* 931130.5.b */ FragmentCount = PacketSize/FragmentThreshold + 1; stmp = PacketSize + FragmentCount*32 + 8; /* 931130.5.c 8:MIC */ - if ((XmitBufSize + stmp) >= MAX_USB_TX_BUFFER) { - printk("[Mds_Tx] Excess max tx buffer.\n"); + if ((XmitBufSize + stmp) >= MAX_USB_TX_BUFFER) break; /* buffer is not enough */ - } - /* * Start transmitting -- cgit v1.2.3 From 3d20e8e8f94b3b5924ff7a018aa73496089aca8b Mon Sep 17 00:00:00 2001 From: Adil Mujeeb Date: Thu, 8 Nov 2012 00:20:03 +0530 Subject: Staging: winbond: wb35rx_s: Fixed coding style issue Fixed checpatch.pl reported ERRORs (excluding WARNING of line over 80 characters) Signed-off-by: Adil Mujeeb Acked-by: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wb35rx_s.h | 62 +++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/staging/winbond/wb35rx_s.h b/drivers/staging/winbond/wb35rx_s.h index 4b03274a7d2..545bc950072 100644 --- a/drivers/staging/winbond/wb35rx_s.h +++ b/drivers/staging/winbond/wb35rx_s.h @@ -1,44 +1,44 @@ -//============================================================================ -// wb35rx.h -- -//============================================================================ +#ifndef __WINBOND_35RX_S_H +#define __WINBOND_35RX_S_H -// Definition for this module used -#define MAX_USB_RX_BUFFER 4096 // This parameter must be 4096 931130.4.f +/* Definition for this module used */ +#define MAX_USB_RX_BUFFER 4096 /* This parameter must be 4096 931130.4.f */ +#define MAX_USB_RX_BUFFER_NUMBER ETHERNET_RX_DESCRIPTORS /* Maximum 254, 255 is RESERVED ID */ +#define RX_INTERFACE 0 /* Interface 1 */ +#define RX_PIPE 2 /* Pipe 3 */ +#define MAX_PACKET_SIZE 1600 /* 1568 = 8 + 1532 + 4 + 24(IV EIV MIC ICV CRC) for check DMA data 931130.4.g */ +#define RX_END_TAG 0x0badbeef -#define MAX_USB_RX_BUFFER_NUMBER ETHERNET_RX_DESCRIPTORS // Maximum 254, 255 is RESERVED ID -#define RX_INTERFACE 0 // Interface 1 -#define RX_PIPE 2 // Pipe 3 -#define MAX_PACKET_SIZE 1600 //1568 // 8 + 1532 + 4 + 24(IV EIV MIC ICV CRC) for check DMA data 931130.4.g -#define RX_END_TAG 0x0badbeef - -//==================================== -// Internal variable for module -//==================================== +/* + * Internal variable for module + */ struct wb35_rx { - u32 ByteReceived;// For calculating throughput of BulkIn - atomic_t RxFireCounter;// Does Wb35Rx module fire? + u32 ByteReceived; /* For calculating throughput of BulkIn */ + atomic_t RxFireCounter;/* Does Wb35Rx module fire? */ - u8 RxBuffer[ MAX_USB_RX_BUFFER_NUMBER ][ ((MAX_USB_RX_BUFFER+3) & ~0x03 ) ]; - u16 RxBufferSize[ ((MAX_USB_RX_BUFFER_NUMBER+1) & ~0x01) ]; - u8 RxOwner[ ((MAX_USB_RX_BUFFER_NUMBER+3) & ~0x03 ) ];//Ownership of buffer 0: SW 1:HW + u8 RxBuffer[MAX_USB_RX_BUFFER_NUMBER][((MAX_USB_RX_BUFFER+3) & ~0x03)]; + u16 RxBufferSize[((MAX_USB_RX_BUFFER_NUMBER+1) & ~0x01)]; + u8 RxOwner[((MAX_USB_RX_BUFFER_NUMBER+3) & ~0x03)]; /* Ownership of buffer 0:SW 1:HW */ - u32 RxProcessIndex;//The next index to process - u32 RxBufferId; - u32 EP3vm_state; + u32 RxProcessIndex; /* The next index to process */ + u32 RxBufferId; + u32 EP3vm_state; - u32 rx_halt; // For VM stopping + u32 rx_halt; /* For VM stopping */ - u16 MoreDataSize; - u16 PacketSize; + u16 MoreDataSize; + u16 PacketSize; - u32 CurrentRxBufferId; // For complete routine usage - u32 Rx3UrbCancel; + u32 CurrentRxBufferId; /* For complete routine usage */ + u32 Rx3UrbCancel; - u32 LastR1; // For RSSI reporting - struct urb * RxUrb; - u32 Ep3ErrorCount2; // 20060625.1 Usbd for Rx DMA error count + u32 LastR1; /* For RSSI reporting */ + struct urb *RxUrb; + u32 Ep3ErrorCount2; /* 20060625.1 Usbd for Rx DMA error count */ int EP3VM_status; - u8 * pDRx; + u8 *pDRx; }; + +#endif /* __WINBOND_35RX_S_H */ -- cgit v1.2.3 From 0093e5f8b3959aec933ff3d3334fc880d7600b22 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Fri, 9 Nov 2012 12:23:14 +0900 Subject: staging/vme: Use dev_ or pr_ printks in devices/vme_user.c fixed below checkpatch warnings. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... - WARNING: Prefer netdev_dbg(netdev, ... then dev_dbg(dev, ... then pr_debug(... to printk(KERN_DEBUG ... - WARNING: Prefer netdev_warn(netdev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ... and add pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 73 ++++++++++++++++------------------ 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index c3f94f311ca..e3731eb2bab 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -15,6 +15,8 @@ * option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -170,7 +172,7 @@ static int vme_user_open(struct inode *inode, struct file *file) mutex_lock(&image[minor].mutex); /* Allow device to be opened if a resource is needed and allocated. */ if (minor < CONTROL_MINOR && image[minor].resource == NULL) { - printk(KERN_ERR "No resources allocated for device\n"); + pr_err("No resources allocated for device\n"); err = -EINVAL; goto err_res; } @@ -225,13 +227,13 @@ static ssize_t resource_to_user(int minor, char __user *buf, size_t count, (unsigned long)copied); if (retval != 0) { copied = (copied - retval); - printk(KERN_INFO "User copy failed\n"); + pr_info("User copy failed\n"); return -EINVAL; } } else { /* XXX Need to write this */ - printk(KERN_INFO "Currently don't support large transfers\n"); + pr_info("Currently don't support large transfers\n"); /* Map in pages from userspace */ /* Call vme_master_read to do the transfer */ @@ -265,7 +267,7 @@ static ssize_t resource_from_user(unsigned int minor, const char __user *buf, image[minor].kern_buf, copied, *ppos); } else { /* XXX Need to write this */ - printk(KERN_INFO "Currently don't support large transfers\n"); + pr_info("Currently don't support large transfers\n"); /* Map in pages from userspace */ /* Call vme_master_write to do the transfer */ @@ -286,7 +288,7 @@ static ssize_t buffer_to_user(unsigned int minor, char __user *buf, retval = __copy_to_user(buf, image_ptr, (unsigned long)count); if (retval != 0) { retval = (count - retval); - printk(KERN_WARNING "Partial copy to userspace\n"); + pr_warn("Partial copy to userspace\n"); } else retval = count; @@ -305,7 +307,7 @@ static ssize_t buffer_from_user(unsigned int minor, const char __user *buf, retval = __copy_from_user(image_ptr, buf, (unsigned long)count); if (retval != 0) { retval = (count - retval); - printk(KERN_WARNING "Partial copy to userspace\n"); + pr_warn("Partial copy to userspace\n"); } else retval = count; @@ -476,7 +478,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, copied = copy_from_user(&irq_req, argp, sizeof(struct vme_irq_id)); if (copied != 0) { - printk(KERN_WARNING "Partial copy from userspace\n"); + pr_warn("Partial copy from userspace\n"); return -EFAULT; } @@ -503,8 +505,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, copied = copy_to_user(argp, &master, sizeof(struct vme_master)); if (copied != 0) { - printk(KERN_WARNING "Partial copy to " - "userspace\n"); + pr_warn("Partial copy to userspace\n"); return -EFAULT; } @@ -515,8 +516,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, copied = copy_from_user(&master, argp, sizeof(master)); if (copied != 0) { - printk(KERN_WARNING "Partial copy from " - "userspace\n"); + pr_warn("Partial copy from userspace\n"); return -EFAULT; } @@ -546,8 +546,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, copied = copy_to_user(argp, &slave, sizeof(struct vme_slave)); if (copied != 0) { - printk(KERN_WARNING "Partial copy to " - "userspace\n"); + pr_warn("Partial copy to userspace\n"); return -EFAULT; } @@ -558,8 +557,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, copied = copy_from_user(&slave, argp, sizeof(slave)); if (copied != 0) { - printk(KERN_WARNING "Partial copy from " - "userspace\n"); + pr_warn("Partial copy from userspace\n"); return -EFAULT; } @@ -599,8 +597,8 @@ static void buf_unalloc(int num) { if (image[num].kern_buf) { #ifdef VME_DEBUG - printk(KERN_DEBUG "UniverseII:Releasing buffer at %p\n", - image[num].pci_buf); + pr_debug("UniverseII:Releasing buffer at %p\n", + image[num].pci_buf); #endif vme_free_consistent(image[num].resource, image[num].size_buf, @@ -612,7 +610,7 @@ static void buf_unalloc(int num) #ifdef VME_DEBUG } else { - printk(KERN_DEBUG "UniverseII: Buffer not allocated\n"); + pr_debug("UniverseII: Buffer not allocated\n"); #endif } } @@ -629,11 +627,10 @@ static int __init vme_user_init(void) { int retval = 0; - printk(KERN_INFO "VME User Space Access Driver\n"); + pr_info("VME User Space Access Driver\n"); if (bus_num == 0) { - printk(KERN_ERR "%s: No cards, skipping registration\n", - driver_name); + pr_err("No cards, skipping registration\n"); retval = -ENODEV; goto err_nocard; } @@ -642,8 +639,8 @@ static int __init vme_user_init(void) * in future revisions if that ever becomes necessary. */ if (bus_num > VME_USER_BUS_MAX) { - printk(KERN_ERR "%s: Driver only able to handle %d buses\n", - driver_name, VME_USER_BUS_MAX); + pr_err("Driver only able to handle %d buses\n", + VME_USER_BUS_MAX); bus_num = VME_USER_BUS_MAX; } @@ -683,8 +680,7 @@ static int __devinit vme_user_probe(struct vme_dev *vdev) /* Save pointer to the bridge device */ if (vme_user_bridge != NULL) { - printk(KERN_ERR "%s: Driver can only be loaded for 1 device\n", - driver_name); + dev_err(&vdev->dev, "Driver can only be loaded for 1 device\n"); err = -EINVAL; goto err_dev; } @@ -707,8 +703,8 @@ static int __devinit vme_user_probe(struct vme_dev *vdev) err = register_chrdev_region(MKDEV(VME_MAJOR, 0), VME_DEVS, driver_name); if (err) { - printk(KERN_WARNING "%s: Error getting Major Number %d for " - "driver.\n", driver_name, VME_MAJOR); + dev_warn(&vdev->dev, "Error getting Major Number %d for driver.\n", + VME_MAJOR); goto err_region; } @@ -718,7 +714,7 @@ static int __devinit vme_user_probe(struct vme_dev *vdev) vme_user_cdev->owner = THIS_MODULE; err = cdev_add(vme_user_cdev, MKDEV(VME_MAJOR, 0), VME_DEVS); if (err) { - printk(KERN_WARNING "%s: cdev_all failed\n", driver_name); + dev_warn(&vdev->dev, "cdev_all failed\n"); goto err_char; } @@ -732,16 +728,16 @@ static int __devinit vme_user_probe(struct vme_dev *vdev) image[i].resource = vme_slave_request(vme_user_bridge, VME_A24, VME_SCT); if (image[i].resource == NULL) { - printk(KERN_WARNING "Unable to allocate slave " - "resource\n"); + dev_warn(&vdev->dev, + "Unable to allocate slave resource\n"); goto err_slave; } image[i].size_buf = PCI_BUF_SIZE; image[i].kern_buf = vme_alloc_consistent(image[i].resource, image[i].size_buf, &image[i].pci_buf); if (image[i].kern_buf == NULL) { - printk(KERN_WARNING "Unable to allocate memory for " - "buffer\n"); + dev_warn(&vdev->dev, + "Unable to allocate memory for buffer\n"); image[i].pci_buf = 0; vme_slave_free(image[i].resource); err = -ENOMEM; @@ -758,15 +754,15 @@ static int __devinit vme_user_probe(struct vme_dev *vdev) image[i].resource = vme_master_request(vme_user_bridge, VME_A32, VME_SCT, VME_D32); if (image[i].resource == NULL) { - printk(KERN_WARNING "Unable to allocate master " - "resource\n"); + dev_warn(&vdev->dev, + "Unable to allocate master resource\n"); goto err_master; } image[i].size_buf = PCI_BUF_SIZE; image[i].kern_buf = kmalloc(image[i].size_buf, GFP_KERNEL); if (image[i].kern_buf == NULL) { - printk(KERN_WARNING "Unable to allocate memory for " - "master window buffers\n"); + dev_warn(&vdev->dev, + "Unable to allocate memory for master window buffers\n"); err = -ENOMEM; goto err_master_buf; } @@ -775,7 +771,7 @@ static int __devinit vme_user_probe(struct vme_dev *vdev) /* Create sysfs entries - on udev systems this creates the dev files */ vme_user_sysfs_class = class_create(THIS_MODULE, driver_name); if (IS_ERR(vme_user_sysfs_class)) { - printk(KERN_ERR "Error creating vme_user class.\n"); + dev_err(&vdev->dev, "Error creating vme_user class.\n"); err = PTR_ERR(vme_user_sysfs_class); goto err_class; } @@ -803,8 +799,7 @@ static int __devinit vme_user_probe(struct vme_dev *vdev) image[i].device = device_create(vme_user_sysfs_class, NULL, MKDEV(VME_MAJOR, i), NULL, name, num); if (IS_ERR(image[i].device)) { - printk(KERN_INFO "%s: Error creating sysfs device\n", - driver_name); + dev_info(&vdev->dev, "Error creating sysfs device\n"); err = PTR_ERR(image[i].device); goto err_sysfs; } -- cgit v1.2.3 From 0129544891de73f7d86f175a6285af404c676c83 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sat, 10 Nov 2012 06:33:02 +0900 Subject: staging/serqt_usb2: fixed line over issue in serqt_usb2.c Fixed a description of the procedure call dev_dbg(). Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/serqt_usb2/serqt_usb2.c | 59 ++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 099bc69ca00..9bc8923f795 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -272,7 +272,8 @@ static void qt_write_bulk_callback(struct urb *urb) status = urb->status; if (status) { - dev_dbg(&urb->dev->dev, "nonzero write bulk status received:%d\n", status); + dev_dbg(&urb->dev->dev, + "nonzero write bulk status received:%d\n", status); return; } @@ -321,7 +322,8 @@ static void qt_read_bulk_callback(struct urb *urb) /* index = MINOR(port->tty->device) - serial->minor; */ index = tty->index - serial->minor; - dev_dbg(&port->dev, "%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding); + dev_dbg(&port->dev, + "%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding); if (port_paranoia_check(port, __func__) != 0) { qt_port->ReadBulkStopped = 1; @@ -333,7 +335,8 @@ static void qt_read_bulk_callback(struct urb *urb) if (qt_port->closePending == 1) { /* Were closing , stop reading */ - dev_dbg(&port->dev, "%s - (qt_port->closepending == 1\n", __func__); + dev_dbg(&port->dev, + "%s - (qt_port->closepending == 1\n", __func__); qt_port->ReadBulkStopped = 1; goto exit; } @@ -912,10 +915,14 @@ static int qt_open(struct tty_struct *tty, dev_dbg(&port->dev, "port number is %d\n", port->number); dev_dbg(&port->dev, "serial number is %d\n", port->serial->minor); - dev_dbg(&port->dev, "Bulkin endpoint is %d\n", port->bulk_in_endpointAddress); - dev_dbg(&port->dev, "BulkOut endpoint is %d\n", port->bulk_out_endpointAddress); - dev_dbg(&port->dev, "Interrupt endpoint is %d\n", port->interrupt_in_endpointAddress); - dev_dbg(&port->dev, "port's number in the device is %d\n", quatech_port->port_num); + dev_dbg(&port->dev, + "Bulkin endpoint is %d\n", port->bulk_in_endpointAddress); + dev_dbg(&port->dev, + "BulkOut endpoint is %d\n", port->bulk_out_endpointAddress); + dev_dbg(&port->dev, "Interrupt endpoint is %d\n", + port->interrupt_in_endpointAddress); + dev_dbg(&port->dev, "port's number in the device is %d\n", + quatech_port->port_num); quatech_port->read_urb = port->read_urb; /* set up our bulk in urb */ @@ -928,7 +935,8 @@ static int qt_open(struct tty_struct *tty, quatech_port->read_urb->transfer_buffer_length, qt_read_bulk_callback, quatech_port); - dev_dbg(&port->dev, "qt_open: bulkin endpoint is %d\n", port->bulk_in_endpointAddress); + dev_dbg(&port->dev, "qt_open: bulkin endpoint is %d\n", + port->bulk_in_endpointAddress); quatech_port->read_urb_busy = true; result = usb_submit_urb(quatech_port->read_urb, GFP_KERNEL); if (result) { @@ -1021,15 +1029,18 @@ static void qt_close(struct usb_serial_port *port) /* Close uart channel */ status = qt_close_channel(serial, index); if (status < 0) - dev_dbg(&port->dev, "%s - port %d qt_close_channel failed.\n", __func__, port->number); + dev_dbg(&port->dev, + "%s - port %d qt_close_channel failed.\n", + __func__, port->number); port0->open_ports--; - dev_dbg(&port->dev, "qt_num_open_ports in close%d:in port%d\n", port0->open_ports, port->number); + dev_dbg(&port->dev, "qt_num_open_ports in close%d:in port%d\n", + port0->open_ports, port->number); if (port0->open_ports == 0) { if (serial->port[0]->interrupt_in_urb) { - dev_dbg(&port->dev, "%s", "Shutdown interrupt_in_urb\n"); + dev_dbg(&port->dev, "Shutdown interrupt_in_urb\n"); usb_kill_urb(serial->port[0]->interrupt_in_urb); } @@ -1053,7 +1064,8 @@ static int qt_write(struct tty_struct *tty, struct usb_serial_port *port, return -ENODEV; if (count == 0) { - dev_dbg(&port->dev, "%s - write request of 0 bytes\n", __func__); + dev_dbg(&port->dev, + "%s - write request of 0 bytes\n", __func__); return 0; } @@ -1080,7 +1092,8 @@ static int qt_write(struct tty_struct *tty, struct usb_serial_port *port, /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb, GFP_ATOMIC); if (result) - dev_dbg(&port->dev, "%s - failed submitting write urb, error %d\n", + dev_dbg(&port->dev, + "%s - failed submitting write urb, error %d\n", __func__, result); else result = count; @@ -1163,7 +1176,8 @@ static int qt_ioctl(struct tty_struct *tty, return 0; } - dev_dbg(&port->dev, "%s -No ioctl for that one. port = %d\n", __func__, port->number); + dev_dbg(&port->dev, "%s -No ioctl for that one. port = %d\n", + __func__, port->number); return -ENOIOCTLCMD; } @@ -1238,7 +1252,8 @@ static void qt_set_termios(struct tty_struct *tty, /* Now determine flow control */ if (cflag & CRTSCTS) { - dev_dbg(&port->dev, "%s - Enabling HW flow control port %d\n", __func__, port->number); + dev_dbg(&port->dev, "%s - Enabling HW flow control port %d\n", + __func__, port->number); /* Enable RTS/CTS flow control */ status = BoxSetHW_FlowCtrl(port->serial, index, 1); @@ -1249,7 +1264,9 @@ static void qt_set_termios(struct tty_struct *tty, } } else { /* Disable RTS/CTS flow control */ - dev_dbg(&port->dev, "%s - disabling HW flow control port %d\n", __func__, port->number); + dev_dbg(&port->dev, + "%s - disabling HW flow control port %d\n", + __func__, port->number); status = BoxSetHW_FlowCtrl(port->serial, index, 0); if (status < 0) { @@ -1268,17 +1285,21 @@ static void qt_set_termios(struct tty_struct *tty, BoxSetSW_FlowCtrl(port->serial, index, stop_char, start_char); if (status < 0) - dev_dbg(&port->dev, "BoxSetSW_FlowCtrl (enabled) failed\n"); + dev_dbg(&port->dev, + "BoxSetSW_FlowCtrl (enabled) failed\n"); } else { /* disable SW flow control */ status = BoxDisable_SW_FlowCtrl(port->serial, index); if (status < 0) - dev_dbg(&port->dev, "BoxSetSW_FlowCtrl (diabling) failed\n"); + dev_dbg(&port->dev, + "BoxSetSW_FlowCtrl (diabling) failed\n"); } termios->c_cflag &= ~CMSPAR; - /* FIXME: Error cases should be returning the actual bits changed only */ + /* FIXME: + Error cases should be returning the actual bits changed only + */ } static void qt_break(struct tty_struct *tty, int break_state) -- cgit v1.2.3 From bbbd527b4f828a92c12ce619180820f1721d32ab Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sat, 10 Nov 2012 06:33:56 +0900 Subject: staging/serqt_usb2: refactor qt_read_bulk_callback() in serqt_usb2.c Modified to eliminate the deep nesting and redundant description. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/serqt_usb2/serqt_usb2.c | 147 +++++++++++++++++--------------- 1 file changed, 80 insertions(+), 67 deletions(-) diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 9bc8923f795..0395bdfeab1 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -291,22 +291,89 @@ static void qt_interrupt_callback(struct urb *urb) /* FIXME */ } +static int qt_status_change(unsigned int limit, + unsigned char *data, + int i, + struct quatech_port *qt_port, + struct usb_serial_port *port) +{ + void (*fn)(struct quatech_port *, unsigned char); + + if (0x00 == data[i + 2]) { + dev_dbg(&port->dev, "Line status status.\n"); + fn = ProcessLineStatus; + } else { + dev_dbg(&port->dev, "Modem status status.\n"); + fn = ProcessModemStatus; + } + + if (i > limit) { + dev_dbg(&port->dev, + "Illegal escape seuences in received data\n"); + return 0; + } + + (*fn)(qt_port, data[i + 3]); + + return 1; +} + +static void qt_status_change_check(struct tty_struct *tty, + struct urb *urb, + struct quatech_port *qt_port, + struct usb_serial_port *port) +{ + int flag, i; + unsigned char *data = urb->transfer_buffer; + unsigned int RxCount = urb->actual_length; + + for (i = 0; i < RxCount; ++i) { + /* Look ahead code here */ + if ((i <= (RxCount - 3)) && (data[i] == 0x1b) + && (data[i + 1] == 0x1b)) { + flag = 0; + switch (data[i + 2]) { + case 0x00: + case 0x01: + flag = qt_status_change((RxCount - 4), data, i, + qt_port, port); + if (flag == 1) + i += 3; + break; + + case 0xff: + dev_dbg(&port->dev, "No status sequence.\n"); + + ProcessRxChar(tty, port, data[i]); + ProcessRxChar(tty, port, data[i + 1]); + + i += 2; + break; + } + if (flag == 1) + continue; + } + + if (tty && urb->actual_length) + tty_insert_flip_char(tty, data[i], TTY_NORMAL); + + } + tty_flip_buffer_push(tty); +} + static void qt_read_bulk_callback(struct urb *urb) { struct usb_serial_port *port = urb->context; struct usb_serial *serial = get_usb_serial(port, __func__); struct quatech_port *qt_port = qt_get_port_private(port); - unsigned char *data; struct tty_struct *tty; - unsigned int index; - unsigned int RxCount; - int i, result; - int flag, flag_data; + int result; if (urb->status) { qt_port->ReadBulkStopped = 1; - dev_dbg(&urb->dev->dev, "%s - nonzero write bulk status received: %d\n", + dev_dbg(&urb->dev->dev, + "%s - nonzero write bulk status received: %d\n", __func__, urb->status); return; } @@ -315,13 +382,6 @@ static void qt_read_bulk_callback(struct urb *urb) if (!tty) return; - data = urb->transfer_buffer; - - RxCount = urb->actual_length; - - /* index = MINOR(port->tty->device) - serial->minor; */ - index = tty->index - serial->minor; - dev_dbg(&port->dev, "%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding); @@ -354,62 +414,14 @@ static void qt_read_bulk_callback(struct urb *urb) if (urb->status) { qt_port->ReadBulkStopped = 1; - dev_dbg(&port->dev, "%s - nonzero read bulk status received: %d\n", + dev_dbg(&port->dev, + "%s - nonzero read bulk status received: %d\n", __func__, urb->status); goto exit; } - if (RxCount) { - flag_data = 0; - for (i = 0; i < RxCount; ++i) { - /* Look ahead code here */ - if ((i <= (RxCount - 3)) && (data[i] == 0x1b) - && (data[i + 1] == 0x1b)) { - flag = 0; - switch (data[i + 2]) { - case 0x00: - /* line status change 4th byte must follow */ - if (i > (RxCount - 4)) { - dev_dbg(&port->dev, "Illegal escape seuences in received data\n"); - break; - } - ProcessLineStatus(qt_port, data[i + 3]); - i += 3; - flag = 1; - break; - - case 0x01: - /* Modem status status change 4th byte must follow */ - dev_dbg(&port->dev, "Modem status status.\n"); - if (i > (RxCount - 4)) { - dev_dbg(&port->dev, "Illegal escape sequences in received data\n"); - break; - } - ProcessModemStatus(qt_port, - data[i + 3]); - i += 3; - flag = 1; - break; - case 0xff: - dev_dbg(&port->dev, "No status sequence.\n"); - - if (tty) { - ProcessRxChar(tty, port, data[i]); - ProcessRxChar(tty, port, data[i + 1]); - } - i += 2; - break; - } - if (flag == 1) - continue; - } - - if (tty && urb->actual_length) - tty_insert_flip_char(tty, data[i], TTY_NORMAL); - - } - tty_flip_buffer_push(tty); - } + if (urb->actual_length) + qt_status_change_check(tty, urb, qt_port, port); /* Continue trying to always read */ usb_fill_bulk_urb(port->read_urb, serial->dev, @@ -420,10 +432,11 @@ static void qt_read_bulk_callback(struct urb *urb) qt_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_ATOMIC); if (result) - dev_dbg(&port->dev, "%s - failed resubmitting read urb, error %d", + dev_dbg(&port->dev, + "%s - failed resubmitting read urb, error %d", __func__, result); else { - if (RxCount) { + if (urb->actual_length) { tty_flip_buffer_push(tty); tty_schedule_flip(tty); } -- cgit v1.2.3 From 04e9d11beb49538458af005f703cb666fc1d3ccf Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sat, 10 Nov 2012 06:34:11 +0900 Subject: staging/serqt_usb2: refactor qt_open() in serqt_usb2.c Modified to eliminate the deep nesting. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/serqt_usb2/serqt_usb2.c | 51 +++++++++++++++++---------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 0395bdfeab1..4c475edebc6 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -840,6 +840,31 @@ static void qt_release(struct usb_serial *serial) } +static void qt_submit_urb_from_open(struct usb_serial *serial, + struct usb_serial_port *port) +{ + int result; + struct usb_serial_port *port0 = serial->port[0]; + + /* set up interrupt urb */ + usb_fill_int_urb(port0->interrupt_in_urb, + serial->dev, + usb_rcvintpipe(serial->dev, + port0->interrupt_in_endpointAddress), + port0->interrupt_in_buffer, + port0->interrupt_in_urb->transfer_buffer_length, + qt_interrupt_callback, serial, + port0->interrupt_in_urb->interval); + + result = usb_submit_urb(port0->interrupt_in_urb, + GFP_KERNEL); + if (result) { + dev_err(&port->dev, + "%s - Error %d submitting interrupt urb\n", + __func__, result); + } +} + static int qt_open(struct tty_struct *tty, struct usb_serial_port *port) { @@ -900,30 +925,8 @@ static int qt_open(struct tty_struct *tty, /* Check to see if we've set up our endpoint info yet */ if (port0->open_ports == 1) { - if (serial->port[0]->interrupt_in_buffer == NULL) { - /* set up interrupt urb */ - usb_fill_int_urb(serial->port[0]->interrupt_in_urb, - serial->dev, - usb_rcvintpipe(serial->dev, - serial->port[0]->interrupt_in_endpointAddress), - serial->port[0]->interrupt_in_buffer, - serial->port[0]-> - interrupt_in_urb->transfer_buffer_length, - qt_interrupt_callback, serial, - serial->port[0]-> - interrupt_in_urb->interval); - - result = - usb_submit_urb(serial->port[0]->interrupt_in_urb, - GFP_KERNEL); - if (result) { - dev_err(&port->dev, - "%s - Error %d submitting " - "interrupt urb\n", __func__, result); - } - - } - + if (serial->port[0]->interrupt_in_buffer == NULL) + qt_submit_urb_from_open(serial, port); } dev_dbg(&port->dev, "port number is %d\n", port->number); -- cgit v1.2.3 From 7028035d513ea7c1cc532c0f2b0e0808ebe5ccf6 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sat, 10 Nov 2012 06:34:27 +0900 Subject: staging/serqt_usb2: refactor qt_unthrottle() in serqt_usb2.c Modified to eliminate the deep nesting. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/serqt_usb2/serqt_usb2.c | 39 +++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 4c475edebc6..f68a855199f 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -1473,12 +1473,32 @@ static void qt_throttle(struct tty_struct *tty) mutex_unlock(&qt_port->lock); } +static void qt_submit_urb_from_unthrottle(struct usb_serial_port *port, + struct usb_serial *serial) +{ + int result; + + /* Start reading from the device */ + usb_fill_bulk_urb(port->read_urb, serial->dev, + usb_rcvbulkpipe(serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + qt_read_bulk_callback, port); + + result = usb_submit_urb(port->read_urb, GFP_ATOMIC); + + if (result) + dev_err(&port->dev, + "%s - failed restarting read urb, error %d\n", + __func__, result); +} + static void qt_unthrottle(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = get_usb_serial(port, __func__); struct quatech_port *qt_port; - unsigned int result; if (!serial) return; @@ -1494,21 +1514,8 @@ static void qt_unthrottle(struct tty_struct *tty) dev_dbg(&port->dev, "%s - qt_port->RxHolding = 0\n", __func__); /* if we have a bulk endpoint, start it up */ - if ((serial->num_bulk_in) && (qt_port->ReadBulkStopped == 1)) { - /* Start reading from the device */ - usb_fill_bulk_urb(port->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, - port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, - port->read_urb-> - transfer_buffer_length, - qt_read_bulk_callback, port); - result = usb_submit_urb(port->read_urb, GFP_ATOMIC); - if (result) - dev_err(&port->dev, - "%s - failed restarting read urb, error %d\n", - __func__, result); - } + if ((serial->num_bulk_in) && (qt_port->ReadBulkStopped == 1)) + qt_submit_urb_from_unthrottle(port, serial); } mutex_unlock(&qt_port->lock); } -- cgit v1.2.3 From a71cac2a4c502b2ef6715b1576681834f9dbe693 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Sun, 11 Nov 2012 13:24:39 +0100 Subject: staging: line6: wrap >80 char lines in capture.c Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/capture.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c index c85c5b6bffb..389c41fd1b7 100644 --- a/drivers/staging/line6/capture.c +++ b/drivers/staging/line6/capture.c @@ -256,8 +256,8 @@ static void audio_in_callback(struct urb *urb) #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE)) #endif - if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, &line6pcm->flags) - && (fsize > 0)) + if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, + &line6pcm->flags) && (fsize > 0)) line6_capture_copy(line6pcm, fbuf, fsize); } @@ -274,7 +274,8 @@ static void audio_in_callback(struct urb *urb) #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE if (!(line6pcm->flags & LINE6_BITS_PCM_IMPULSE)) #endif - if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, &line6pcm->flags)) + if (test_bit(LINE6_INDEX_PCM_ALSA_CAPTURE_STREAM, + &line6pcm->flags)) line6_capture_check_period(line6pcm, length); } } @@ -356,7 +357,8 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd) #ifdef CONFIG_PM case SNDRV_PCM_TRIGGER_RESUME: #endif - err = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_STREAM); + err = line6_pcm_acquire(line6pcm, + LINE6_BIT_PCM_ALSA_CAPTURE_STREAM); if (err < 0) return err; @@ -367,7 +369,8 @@ int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd) #ifdef CONFIG_PM case SNDRV_PCM_TRIGGER_SUSPEND: #endif - err = line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_CAPTURE_STREAM); + err = line6_pcm_release(line6pcm, + LINE6_BIT_PCM_ALSA_CAPTURE_STREAM); if (err < 0) return err; -- cgit v1.2.3 From b3a24fc4e2ded4f28d5f4c69ea01fea721608658 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Sun, 11 Nov 2012 13:24:40 +0100 Subject: staging: line6: fix quoted string across lines in midibuf.c Checkpatch warns when quoted strings are split across lines. The rationale is that quoted strings should be left on a single line so that grep works. (The 80 character line limit does not apply to quoted strings.) Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/midibuf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/line6/midibuf.c b/drivers/staging/line6/midibuf.c index 836e8c847c5..968e0de83da 100644 --- a/drivers/staging/line6/midibuf.c +++ b/drivers/staging/line6/midibuf.c @@ -64,9 +64,9 @@ int line6_midibuf_init(struct MidiBuffer *this, int size, int split) void line6_midibuf_status(struct MidiBuffer *this) { - pr_debug("midibuf size=%d split=%d pos_read=%d pos_write=%d " - "full=%d command_prev=%02x\n", this->size, this->split, - this->pos_read, this->pos_write, this->full, this->command_prev); + pr_debug("midibuf size=%d split=%d pos_read=%d pos_write=%d full=%d command_prev=%02x\n", + this->size, this->split, this->pos_read, this->pos_write, + this->full, this->command_prev); } int line6_midibuf_bytes_free(struct MidiBuffer *this) -- cgit v1.2.3 From 928f25ee4393a94d80ab829427e1047a64702187 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Sun, 11 Nov 2012 13:24:41 +0100 Subject: staging: line6: shorten comment below 80 chars in pcm.c Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index 7fe44a6fd0e..6c1e31335d1 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -109,7 +109,7 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) line6pcm->prev_fbuf = NULL; if (test_flags(flags_old, flags_new, LINE6_BITS_CAPTURE_BUFFER)) { - /* We may be invoked multiple times in a row so allocate once only */ + /* Invoked multiple times in a row so allocate once only */ if (!line6pcm->buffer_in) { line6pcm->buffer_in = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * @@ -148,7 +148,7 @@ int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) } if (test_flags(flags_old, flags_new, LINE6_BITS_PLAYBACK_BUFFER)) { - /* We may be invoked multiple times in a row so allocate once only */ + /* Invoked multiple times in a row so allocate once only */ if (!line6pcm->buffer_out) { line6pcm->buffer_out = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * -- cgit v1.2.3 From b957e0ceb667fe4f2a18275b5187b2813b983baf Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Sun, 11 Nov 2012 13:24:42 +0100 Subject: staging: line6: drop trailing whitespace in pcm.h Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/pcm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h index 5210ec8dbe1..6aa0d46a289 100644 --- a/drivers/staging/line6/pcm.h +++ b/drivers/staging/line6/pcm.h @@ -167,7 +167,7 @@ enum { #endif LINE6_BIT_PCM_ALSA_CAPTURE_STREAM | LINE6_BIT_PCM_MONITOR_CAPTURE_STREAM, - + LINE6_BITS_STREAM = LINE6_BITS_PLAYBACK_STREAM | LINE6_BITS_CAPTURE_STREAM -- cgit v1.2.3 From 6a8ec8769d4613a5fbd981bfb3e5925b29d4140d Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Sun, 11 Nov 2012 13:24:43 +0100 Subject: staging: line6: wrap lines to 80 chars in playback.c There are a few instances of 80+ character lines in playback.c. Two instances are just because of a useless comment "this is somewhat paranoid", so drop the comment. Other instances are straightforward line wrapping. Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/playback.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c index a0ab9d0493f..4cf23af9c62 100644 --- a/drivers/staging/line6/playback.c +++ b/drivers/staging/line6/playback.c @@ -185,7 +185,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) if (urb_size == 0) { /* can't determine URB size */ spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags); - dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n"); /* this is somewhat paranoid */ + dev_err(line6pcm->line6->ifcdev, "driver bug: urb_size = 0\n"); return -EINVAL; } @@ -218,7 +218,8 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) len * bytes_per_frame, runtime->dma_area, (urb_frames - len) * bytes_per_frame); } else - dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", len); /* this is somewhat paranoid */ + dev_err(line6pcm->line6->ifcdev, "driver bug: len = %d\n", + len); } else { memcpy(urb_out->transfer_buffer, runtime->dma_area + @@ -319,7 +320,8 @@ void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm) } /* - Wait until unlinking of all currently active playback URBs has been finished. + Wait until unlinking of all currently active playback URBs has been + finished. */ void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm) { @@ -413,7 +415,8 @@ static void audio_out_callback(struct urb *urb) if (!shutdown) { submit_audio_out_urb(line6pcm); - if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, &line6pcm->flags)) { + if (test_bit(LINE6_INDEX_PCM_ALSA_PLAYBACK_STREAM, + &line6pcm->flags)) { line6pcm->bytes_out += length; if (line6pcm->bytes_out >= line6pcm->period_out) { line6pcm->bytes_out %= line6pcm->period_out; @@ -499,7 +502,8 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd) #ifdef CONFIG_PM case SNDRV_PCM_TRIGGER_RESUME: #endif - err = line6_pcm_acquire(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM); + err = line6_pcm_acquire(line6pcm, + LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM); if (err < 0) return err; @@ -510,7 +514,8 @@ int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd) #ifdef CONFIG_PM case SNDRV_PCM_TRIGGER_SUSPEND: #endif - err = line6_pcm_release(line6pcm, LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM); + err = line6_pcm_release(line6pcm, + LINE6_BIT_PCM_ALSA_PLAYBACK_STREAM); if (err < 0) return err; -- cgit v1.2.3 From b07d945227e4e62d93e26c694bf0e7b70978a7d6 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Sun, 11 Nov 2012 13:24:44 +0100 Subject: staging: line6: replace deprecated strict_strtol() in toneport.c The LED value is an int, so replace strict_strtol() with kstrtoint(). It's safe to pass in the actual variable instead of a local temporary because strto*() doesn't write to the result unless the function returns success. Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/toneport.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c index 31b624b6342..a529dd3d604 100644 --- a/drivers/staging/line6/toneport.c +++ b/drivers/staging/line6/toneport.c @@ -127,13 +127,11 @@ static ssize_t toneport_set_led_red(struct device *dev, const char *buf, size_t count) { int retval; - long value; - retval = strict_strtol(buf, 10, &value); + retval = kstrtoint(buf, 10, &led_red); if (retval) return retval; - led_red = value; toneport_update_led(dev); return count; } @@ -143,13 +141,11 @@ static ssize_t toneport_set_led_green(struct device *dev, const char *buf, size_t count) { int retval; - long value; - retval = strict_strtol(buf, 10, &value); + retval = kstrtoint(buf, 10, &led_green); if (retval) return retval; - led_green = value; toneport_update_led(dev); return count; } -- cgit v1.2.3 From 4391bb982b9d0ccbae724dd8f8d95c1ddb725ae3 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Sun, 11 Nov 2012 13:24:45 +0100 Subject: staging: line6: wrap lines to 80 chars in usbdefs.h Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/usbdefs.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h index 353d59d77b0..43eb54008a2 100644 --- a/drivers/staging/line6/usbdefs.h +++ b/drivers/staging/line6/usbdefs.h @@ -83,11 +83,15 @@ enum { LINE6_BIT(VARIAX), LINE6_BITS_PRO = LINE6_BIT_BASSPODXTPRO | LINE6_BIT_PODXTPRO, - LINE6_BITS_LIVE = LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_PODXTLIVE | LINE6_BIT_PODX3LIVE, - LINE6_BITS_PODXTALL = LINE6_BIT_PODXT | LINE6_BIT_PODXTLIVE | LINE6_BIT_PODXTPRO, + LINE6_BITS_LIVE = LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_PODXTLIVE | + LINE6_BIT_PODX3LIVE, + LINE6_BITS_PODXTALL = LINE6_BIT_PODXT | LINE6_BIT_PODXTLIVE | + LINE6_BIT_PODXTPRO, LINE6_BITS_PODX3ALL = LINE6_BIT_PODX3 | LINE6_BIT_PODX3LIVE, LINE6_BITS_PODHDALL = LINE6_BIT_PODHD300 | LINE6_BIT_PODHD500, - LINE6_BITS_BASSPODXTALL = LINE6_BIT_BASSPODXT | LINE6_BIT_BASSPODXTLIVE | LINE6_BIT_BASSPODXTPRO + LINE6_BITS_BASSPODXTALL = LINE6_BIT_BASSPODXT | + LINE6_BIT_BASSPODXTLIVE | + LINE6_BIT_BASSPODXTPRO }; /* device supports settings parameter via USB */ -- cgit v1.2.3 From e5603cbd7f6b8d8ec6a59d3ce11c3fa28ef2a733 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Sun, 11 Nov 2012 13:24:46 +0100 Subject: staging: line6: wrap comment to 80 chars in variax.c Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/variax.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index f97416b1de5..1b85eccd92b 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -160,7 +160,9 @@ static void variax_startup5(unsigned long data) /* current model dump: */ line6_dump_request_async(&variax->dumpreq, &variax->line6, 0, VARIAX_DUMP_PASS1); - /* passes 2 and 3 are performed implicitly before entering variax_startup6 */ + /* passes 2 and 3 are performed implicitly before entering + * variax_startup6. + */ } static void variax_startup6(struct usb_line6_variax *variax) -- cgit v1.2.3 From d85c8a6ab2bb0ba067a2a72c63c3bd20e6788996 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 13 Nov 2012 22:27:19 +0100 Subject: MAINTAINERS: i2c: 7 years, this is it I have been maintaining the i2c subsystem for 7 years now, it's about time to let someone else take over. Just before I leave, I would like to thank several individuals who made this possible at all: * Greg Kroah-Hartman, for his faith in my potential subsystem maintainer skills. Greg, I hope I met your expectations. * Late David Brownell, for helping me convert the i2c subsystem to the standard device driver model. Rest in peace David, we're missing you. * Ben Dooks, for stepping in when I asked for someone to take care of the huge flow of new i2c adapter drivers for embedded systems. * Wolfram Sang, for joining the crew when it became clear that there was more review work than Ben and myself could deal with. I hope I did not forget anyone, please forgive me if I did. Another big thank is due to Wolfram again, who quickly proposed to take over as the main i2c subsystem maintainer. This will allow for a smooth and fast transition. Note that I will keep maintaining all I2C/SMBus controller drivers for PC systems as well as a few others. I am hereby updating MAINTAINERS accordingly. I'll also keep maintaining user-space i2c-tools. Signed-off-by: Jean Delvare Cc: Greg Kroah-Hartman Cc: Ben Dooks Acked-by: Wolfram Sang --- MAINTAINERS | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 59203e77ce9..ff8e763eaa5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3598,6 +3598,49 @@ F: drivers/hid/hid-hyperv.c F: drivers/net/hyperv/ F: drivers/staging/hv/ +I2C OVER PARALLEL PORT +M: Jean Delvare +L: linux-i2c@vger.kernel.org +S: Maintained +F: Documentation/i2c/busses/i2c-parport +F: Documentation/i2c/busses/i2c-parport-light +F: drivers/i2c/busses/i2c-parport.c +F: drivers/i2c/busses/i2c-parport-light.c + +I2C/SMBUS CONTROLLER DRIVERS FOR PC +M: Jean Delvare +L: linux-i2c@vger.kernel.org +S: Maintained +F: Documentation/i2c/busses/i2c-ali1535 +F: Documentation/i2c/busses/i2c-ali1563 +F: Documentation/i2c/busses/i2c-ali15x3 +F: Documentation/i2c/busses/i2c-amd756 +F: Documentation/i2c/busses/i2c-amd8111 +F: Documentation/i2c/busses/i2c-i801 +F: Documentation/i2c/busses/i2c-nforce2 +F: Documentation/i2c/busses/i2c-piix4 +F: Documentation/i2c/busses/i2c-sis5595 +F: Documentation/i2c/busses/i2c-sis630 +F: Documentation/i2c/busses/i2c-sis96x +F: Documentation/i2c/busses/i2c-via +F: Documentation/i2c/busses/i2c-viapro +F: drivers/i2c/busses/i2c-ali1535.c +F: drivers/i2c/busses/i2c-ali1563.c +F: drivers/i2c/busses/i2c-ali15x3.c +F: drivers/i2c/busses/i2c-amd756.c +F: drivers/i2c/busses/i2c-amd756-s4882.c +F: drivers/i2c/busses/i2c-amd8111.c +F: drivers/i2c/busses/i2c-i801.c +F: drivers/i2c/busses/i2c-isch.c +F: drivers/i2c/busses/i2c-nforce2.c +F: drivers/i2c/busses/i2c-nforce2-s4985.c +F: drivers/i2c/busses/i2c-piix4.c +F: drivers/i2c/busses/i2c-sis5595.c +F: drivers/i2c/busses/i2c-sis630.c +F: drivers/i2c/busses/i2c-sis96x.c +F: drivers/i2c/busses/i2c-via.c +F: drivers/i2c/busses/i2c-viapro.c + I2C/SMBUS STUB DRIVER M: "Mark M. Hoffman" L: linux-i2c@vger.kernel.org @@ -3605,9 +3648,8 @@ S: Maintained F: drivers/i2c/busses/i2c-stub.c I2C SUBSYSTEM -M: "Jean Delvare (PC drivers, core)" +M: Wolfram Sang M: "Ben Dooks (embedded platforms)" -M: "Wolfram Sang (embedded platforms)" L: linux-i2c@vger.kernel.org W: http://i2c.wiki.kernel.org/ T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/ @@ -3618,6 +3660,13 @@ F: drivers/i2c/ F: include/linux/i2c.h F: include/linux/i2c-*.h +I2C-TAOS-EVM DRIVER +M: Jean Delvare +L: linux-i2c@vger.kernel.org +S: Maintained +F: Documentation/i2c/busses/i2c-taos-evm +F: drivers/i2c/busses/i2c-taos-evm.c + I2C-TINY-USB DRIVER M: Till Harbaum L: linux-i2c@vger.kernel.org @@ -7887,13 +7936,6 @@ M: Roger Luethi S: Maintained F: drivers/net/ethernet/via/via-rhine.c -VIAPRO SMBUS DRIVER -M: Jean Delvare -L: linux-i2c@vger.kernel.org -S: Maintained -F: Documentation/i2c/busses/i2c-viapro -F: drivers/i2c/busses/i2c-viapro.c - VIA SD/MMC CARD CONTROLLER DRIVER M: Bruce Chang M: Harald Welte -- cgit v1.2.3 From aa1e3e81e75ceb3d977c3292cefafcd5179eb8b8 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 13 Nov 2012 22:27:19 +0100 Subject: i2c-mux-pinctrl: Fix probe error path When allocating the memory for i2c busses, the code checked the wrong variable and thus never detected if there was a memory error. Signed-off-by: Guenter Roeck Cc: stable@vger.kernel.org Signed-off-by: Jean Delvare --- drivers/i2c/muxes/i2c-mux-pinctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c index 5f097f309b9..7fa5b24b16d 100644 --- a/drivers/i2c/muxes/i2c-mux-pinctrl.c +++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c @@ -169,7 +169,7 @@ static int __devinit i2c_mux_pinctrl_probe(struct platform_device *pdev) mux->busses = devm_kzalloc(&pdev->dev, sizeof(mux->busses) * mux->pdata->bus_count, GFP_KERNEL); - if (!mux->states) { + if (!mux->busses) { dev_err(&pdev->dev, "Cannot allocate busses\n"); ret = -ENOMEM; goto err; -- cgit v1.2.3 From 878d7439d0f45a95869e417576774673d1fa243f Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 18 Oct 2012 04:55:36 -0700 Subject: rcu: Fix batch-limit size problem Commit 29c00b4a1d9e27 (rcu: Add event-tracing for RCU callback invocation) added a regression in rcu_do_batch() Under stress, RCU is supposed to allow to process all items in queue, instead of a batch of 10 items (blimit), but an integer overflow makes the effective limit being 1. So, unless there is frequent idle periods (during which RCU ignores batch limits), RCU can be forced into a state where it cannot keep up with the callback-generation rate, eventually resulting in OOM. This commit therefore converts a few variables in rcu_do_batch() from int to long to fix this problem, along with the module parameters controlling the batch limits. Signed-off-by: Eric Dumazet Signed-off-by: Paul E. McKenney Cc: # 3.2 + --- kernel/rcutree.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 93d6871bf7f..e4c2192b47c 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -212,13 +212,13 @@ DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = { #endif }; -static int blimit = 10; /* Maximum callbacks per rcu_do_batch. */ -static int qhimark = 10000; /* If this many pending, ignore blimit. */ -static int qlowmark = 100; /* Once only this many pending, use blimit. */ +static long blimit = 10; /* Maximum callbacks per rcu_do_batch. */ +static long qhimark = 10000; /* If this many pending, ignore blimit. */ +static long qlowmark = 100; /* Once only this many pending, use blimit. */ -module_param(blimit, int, 0444); -module_param(qhimark, int, 0444); -module_param(qlowmark, int, 0444); +module_param(blimit, long, 0444); +module_param(qhimark, long, 0444); +module_param(qlowmark, long, 0444); int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */ int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT; @@ -1791,7 +1791,8 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp) { unsigned long flags; struct rcu_head *next, *list, **tail; - int bl, count, count_lazy, i; + long bl, count, count_lazy; + int i; /* If no callbacks are ready, just return.*/ if (!cpu_has_callbacks_ready_to_invoke(rdp)) { -- cgit v1.2.3 From bb08f76d8419a163b7a4212a0e4ea6bd25acacd1 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sat, 20 Oct 2012 12:33:37 -0700 Subject: rcu: Remove list_for_each_continue_rcu() The list_for_each_continue_rcu() macro is no longer used, so this commit removes it. The list_for_each_entry_continue_rcu() macro should be used instead. Signed-off-by: Paul E. McKenney --- Documentation/RCU/checklist.txt | 17 ++++++++--------- Documentation/RCU/whatisRCU.txt | 4 +--- include/linux/rculist.h | 17 ----------------- 3 files changed, 9 insertions(+), 29 deletions(-) diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt index cdb20d41a44..31ef8fe07f8 100644 --- a/Documentation/RCU/checklist.txt +++ b/Documentation/RCU/checklist.txt @@ -271,15 +271,14 @@ over a rather long period of time, but improvements are always welcome! The same cautions apply to call_rcu_bh() and call_rcu_sched(). 9. All RCU list-traversal primitives, which include - rcu_dereference(), list_for_each_entry_rcu(), - list_for_each_continue_rcu(), and list_for_each_safe_rcu(), - must be either within an RCU read-side critical section or - must be protected by appropriate update-side locks. RCU - read-side critical sections are delimited by rcu_read_lock() - and rcu_read_unlock(), or by similar primitives such as - rcu_read_lock_bh() and rcu_read_unlock_bh(), in which case - the matching rcu_dereference() primitive must be used in order - to keep lockdep happy, in this case, rcu_dereference_bh(). + rcu_dereference(), list_for_each_entry_rcu(), and + list_for_each_safe_rcu(), must be either within an RCU read-side + critical section or must be protected by appropriate update-side + locks. RCU read-side critical sections are delimited by + rcu_read_lock() and rcu_read_unlock(), or by similar primitives + such as rcu_read_lock_bh() and rcu_read_unlock_bh(), in which + case the matching rcu_dereference() primitive must be used in + order to keep lockdep happy, in this case, rcu_dereference_bh(). The reason that it is permissible to use RCU list-traversal primitives when the update-side lock is held is that doing so diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt index bf0f6de2aa0..9d30de00d73 100644 --- a/Documentation/RCU/whatisRCU.txt +++ b/Documentation/RCU/whatisRCU.txt @@ -789,9 +789,7 @@ RCU list traversal: list_for_each_entry_rcu hlist_for_each_entry_rcu hlist_nulls_for_each_entry_rcu - - list_for_each_continue_rcu (to be deprecated in favor of new - list_for_each_entry_continue_rcu) + list_for_each_entry_continue_rcu RCU pointer/list update: diff --git a/include/linux/rculist.h b/include/linux/rculist.h index e0f0fab2041..c92dd28eaa6 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -286,23 +286,6 @@ static inline void list_splice_init_rcu(struct list_head *list, &pos->member != (head); \ pos = list_entry_rcu(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_continue_rcu - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - * - * Iterate over an rcu-protected list, continuing after current point. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as list_add_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define list_for_each_continue_rcu(pos, head) \ - for ((pos) = rcu_dereference_raw(list_next_rcu(pos)); \ - (pos) != (head); \ - (pos) = rcu_dereference_raw(list_next_rcu(pos))) - /** * list_for_each_entry_continue_rcu - continue iteration over list of given type * @pos: the type * to use as a loop cursor. -- cgit v1.2.3 From 67afeed2cab0e59712b4ebf1aef9a2e555a188ce Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sat, 20 Oct 2012 12:56:06 -0700 Subject: rcu: Add new rcutorture module parameters to start/end test messages Several new rcutorture module parameters have been added, but are not printed to the console at the beginning and end of tests, which makes it difficult to reproduce a prior test. This commit therefore adds these new module parameters to the list printed at the beginning and the end of the tests. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutorture.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index aaa7b9f3532..7fa184f6a48 100644 --- a/kernel/rcutorture.c +++ b/kernel/rcutorture.c @@ -1396,12 +1396,16 @@ rcu_torture_print_module_parms(struct rcu_torture_ops *cur_ops, char *tag) "fqs_duration=%d fqs_holdoff=%d fqs_stutter=%d " "test_boost=%d/%d test_boost_interval=%d " "test_boost_duration=%d shutdown_secs=%d " + "stall_cpu=%d stall_cpu_holdoff=%d " + "n_barrier_cbs=%d " "onoff_interval=%d onoff_holdoff=%d\n", torture_type, tag, nrealreaders, nfakewriters, stat_interval, verbose, test_no_idle_hz, shuffle_interval, stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter, test_boost, cur_ops->can_boost, test_boost_interval, test_boost_duration, shutdown_secs, + stall_cpu, stall_cpu_holdoff, + n_barrier_cbs, onoff_interval, onoff_holdoff); } -- cgit v1.2.3 From f0a0e6f282c72247e7c8ec17c68d528c1bb4d49e Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Tue, 23 Oct 2012 13:47:01 -0700 Subject: rcu: Clarify memory-ordering properties of grace-period primitives This commit explicitly states the memory-ordering properties of the RCU grace-period primitives. Although these properties were in some sense implied by the fundmental property of RCU ("a grace period must wait for all pre-existing RCU read-side critical sections to complete"), stating it explicitly will be a great labor-saving device. Reported-by: Oleg Nesterov Signed-off-by: Paul E. McKenney Reviewed-by: Oleg Nesterov --- include/linux/rcupdate.h | 25 +++++++++++++++++++++++++ kernel/rcutree.c | 29 +++++++++++++++++++++++++---- kernel/rcutree_plugin.h | 8 ++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 7c968e4f929..6256759fb81 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -90,6 +90,25 @@ extern void do_trace_rcu_torture_read(char *rcutorturename, * that started after call_rcu() was invoked. RCU read-side critical * sections are delimited by rcu_read_lock() and rcu_read_unlock(), * and may be nested. + * + * Note that all CPUs must agree that the grace period extended beyond + * all pre-existing RCU read-side critical section. On systems with more + * than one CPU, this means that when "func()" is invoked, each CPU is + * guaranteed to have executed a full memory barrier since the end of its + * last RCU read-side critical section whose beginning preceded the call + * to call_rcu(). It also means that each CPU executing an RCU read-side + * critical section that continues beyond the start of "func()" must have + * executed a memory barrier after the call_rcu() but before the beginning + * of that RCU read-side critical section. Note that these guarantees + * include CPUs that are offline, idle, or executing in user mode, as + * well as CPUs that are executing in the kernel. + * + * Furthermore, if CPU A invoked call_rcu() and CPU B invoked the + * resulting RCU callback function "func()", then both CPU A and CPU B are + * guaranteed to execute a full memory barrier during the time interval + * between the call to call_rcu() and the invocation of "func()" -- even + * if CPU A and CPU B are the same CPU (but again only if the system has + * more than one CPU). */ extern void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *head)); @@ -118,6 +137,9 @@ extern void call_rcu(struct rcu_head *head, * OR * - rcu_read_lock_bh() and rcu_read_unlock_bh(), if in process context. * These may be nested. + * + * See the description of call_rcu() for more detailed information on + * memory ordering guarantees. */ extern void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *head)); @@ -137,6 +159,9 @@ extern void call_rcu_bh(struct rcu_head *head, * OR * anything that disables preemption. * These may be nested. + * + * See the description of call_rcu() for more detailed information on + * memory ordering guarantees. */ extern void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu)); diff --git a/kernel/rcutree.c b/kernel/rcutree.c index e4c2192b47c..15a2beec320 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -2228,10 +2228,28 @@ static inline int rcu_blocking_is_gp(void) * rcu_read_lock_sched(). * * This means that all preempt_disable code sequences, including NMI and - * hardware-interrupt handlers, in progress on entry will have completed - * before this primitive returns. However, this does not guarantee that - * softirq handlers will have completed, since in some kernels, these - * handlers can run in process context, and can block. + * non-threaded hardware-interrupt handlers, in progress on entry will + * have completed before this primitive returns. However, this does not + * guarantee that softirq handlers will have completed, since in some + * kernels, these handlers can run in process context, and can block. + * + * Note that this guarantee implies further memory-ordering guarantees. + * On systems with more than one CPU, when synchronize_sched() returns, + * each CPU is guaranteed to have executed a full memory barrier since the + * end of its last RCU-sched read-side critical section whose beginning + * preceded the call to synchronize_sched(). In addition, each CPU having + * an RCU read-side critical section that extends beyond the return from + * synchronize_sched() is guaranteed to have executed a full memory barrier + * after the beginning of synchronize_sched() and before the beginning of + * that RCU read-side critical section. Note that these guarantees include + * CPUs that are offline, idle, or executing in user mode, as well as CPUs + * that are executing in the kernel. + * + * Furthermore, if CPU A invoked synchronize_sched(), which returned + * to its caller on CPU B, then both CPU A and CPU B are guaranteed + * to have executed a full memory barrier during the execution of + * synchronize_sched() -- even if CPU A and CPU B are the same CPU (but + * again only if the system has more than one CPU). * * This primitive provides the guarantees made by the (now removed) * synchronize_kernel() API. In contrast, synchronize_rcu() only @@ -2259,6 +2277,9 @@ EXPORT_SYMBOL_GPL(synchronize_sched); * read-side critical sections have completed. RCU read-side critical * sections are delimited by rcu_read_lock_bh() and rcu_read_unlock_bh(), * and may be nested. + * + * See the description of synchronize_sched() for more detailed information + * on memory ordering guarantees. */ void synchronize_rcu_bh(void) { diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index f9211548818..57e0ef8ed72 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h @@ -670,6 +670,9 @@ EXPORT_SYMBOL_GPL(kfree_call_rcu); * concurrently with new RCU read-side critical sections that began while * synchronize_rcu() was waiting. RCU read-side critical sections are * delimited by rcu_read_lock() and rcu_read_unlock(), and may be nested. + * + * See the description of synchronize_sched() for more detailed information + * on memory ordering guarantees. */ void synchronize_rcu(void) { @@ -875,6 +878,11 @@ EXPORT_SYMBOL_GPL(synchronize_rcu_expedited); /** * rcu_barrier - Wait until all in-flight call_rcu() callbacks complete. + * + * Note that this primitive does not necessarily wait for an RCU grace period + * to complete. For example, if there are no RCU callbacks queued anywhere + * in the system, then rcu_barrier() is within its rights to return + * immediately, without waiting for anything, much less an RCU grace period. */ void rcu_barrier(void) { -- cgit v1.2.3 From 351573a86d0ef17cbba1c5436706602692781bfe Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 29 Oct 2012 04:52:56 -0700 Subject: rcu: Fix TINY_RCU rcu_is_cpu_rrupt_from_idle check The rcu_is_cpu_rrupt_from_idle() needs to allow for one interrupt level from the idle loop, but TINY_RCU checks for a call from the idle loop itself. This commit fixes this issue. Reported-by: Josh Triplett Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutiny.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c index e4c6a598d6f..e7dce58f9c2 100644 --- a/kernel/rcutiny.c +++ b/kernel/rcutiny.c @@ -195,7 +195,7 @@ EXPORT_SYMBOL(rcu_is_cpu_idle); */ int rcu_is_cpu_rrupt_from_idle(void) { - return rcu_dynticks_nesting <= 0; + return rcu_dynticks_nesting <= 1; } /* -- cgit v1.2.3 From c896054f75f9a720ecf2ab3e688f4da79a55fe05 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 25 Oct 2012 17:59:23 -0700 Subject: rcu: Reduce default RCU CPU stall warning timeout The RCU CPU stall warning timeout has defaulted to 60 seconds for some years, with almost no false positives. This commit therefore reduces the default to 21 seconds, slightly shorter than the new soft-lockup timeout. Signed-off-by: Paul E. McKenney --- lib/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 28e9d6c9894..41faf0b8df1 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -972,7 +972,7 @@ config RCU_CPU_STALL_TIMEOUT int "RCU CPU stall timeout in seconds" depends on TREE_RCU || TREE_PREEMPT_RCU range 3 300 - default 60 + default 21 help If a given RCU grace period extends more than the specified number of seconds, a CPU stall warning is printed. If the -- cgit v1.2.3 From eb5ce43997b10dd07a63befeb26778d996c5a356 Mon Sep 17 00:00:00 2001 From: Rami Rosen Date: Tue, 13 Nov 2012 13:29:15 +0000 Subject: vxlan: fix a typo. Use eXtensible and not eXtensiable in the comment on top. Signed-off-by: Rami Rosen Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 0c4d0f49ab4..3d0bf664ea3 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1,5 +1,5 @@ /* - * VXLAN: Virtual eXtensiable Local Area Network + * VXLAN: Virtual eXtensible Local Area Network * * Copyright (c) 2012 Vyatta Inc. * -- cgit v1.2.3 From e00d33cb5de0c68ed95513d3b4f42f9e3697f8ee Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Sun, 11 Nov 2012 13:52:24 +0100 Subject: staging: line6: replace DEBUG_MESSAGES() with dev_dbg() The dyndbg feature allows dev_dbg() calls to be enabled/disabled at runtime and is therefore more convenient than static debug log messages. Use dev_dbg() instead of the line6-specific DEBUG_MESSAGES() macro. Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 6 ++--- drivers/staging/line6/pod.c | 57 ++++++++++++++++-------------------------- drivers/staging/line6/variax.c | 12 ++++----- 3 files changed, 28 insertions(+), 47 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index ac11a3bd1bb..571f2ceceed 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -412,10 +412,8 @@ static void line6_data_received(struct urb *urb) if (done < urb->actual_length) { line6_midibuf_ignore(mb, done); - DEBUG_MESSAGES(dev_err - (line6->ifcdev, - "%d %d buffer overflow - message skipped\n", - done, urb->actual_length)); + dev_dbg(line6->ifcdev, "%d %d buffer overflow - message skipped\n", + done, urb->actual_length); } for (;;) { diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c index 9edd053fb9a..4a86f7a1585 100644 --- a/drivers/staging/line6/pod.c +++ b/drivers/staging/line6/pod.c @@ -252,25 +252,19 @@ void line6_pod_process_message(struct usb_line6_pod *pod) break; default: - DEBUG_MESSAGES(dev_err - (pod-> - line6.ifcdev, - "unknown dump code %02X\n", - pod-> - dumpreq.in_progress)); + dev_dbg(pod->line6.ifcdev, + "unknown dump code %02X\n", + pod->dumpreq.in_progress); } line6_dump_finished(&pod->dumpreq); pod_startup3(pod); } else - DEBUG_MESSAGES(dev_err - (pod->line6.ifcdev, - "wrong size of channel dump message (%d instead of %d)\n", - pod-> - line6.message_length, - (int) - sizeof(pod->prog_data) + - 7)); + dev_dbg(pod->line6.ifcdev, + "wrong size of channel dump message (%d instead of %d)\n", + pod->line6.message_length, + (int)sizeof(pod->prog_data) + + 7); break; @@ -302,11 +296,9 @@ void line6_pod_process_message(struct usb_line6_pod *pod) #undef PROCESS_SYSTEM_PARAM default: - DEBUG_MESSAGES(dev_err - (pod-> - line6.ifcdev, - "unknown tuner/system response %02X\n", - buf[6])); + dev_dbg(pod->line6.ifcdev, + "unknown tuner/system response %02X\n", + buf[6]); } break; @@ -321,25 +313,21 @@ void line6_pod_process_message(struct usb_line6_pod *pod) break; case POD_SYSEX_CLIP: - DEBUG_MESSAGES(dev_err - (pod->line6.ifcdev, - "audio clipped\n")); + dev_dbg(pod->line6.ifcdev, "audio clipped\n"); pod->clipping.value = 1; wake_up(&pod->clipping.wait); break; case POD_SYSEX_STORE: - DEBUG_MESSAGES(dev_err - (pod->line6.ifcdev, - "message %02X not yet implemented\n", - buf[5])); + dev_dbg(pod->line6.ifcdev, + "message %02X not yet implemented\n", + buf[5]); break; default: - DEBUG_MESSAGES(dev_err - (pod->line6.ifcdev, - "unknown sysex message %02X\n", - buf[5])); + dev_dbg(pod->line6.ifcdev, + "unknown sysex message %02X\n", + buf[5]); } } else if (memcmp @@ -352,9 +340,7 @@ void line6_pod_process_message(struct usb_line6_pod *pod) buf[10]; pod_startup4(pod); } else - DEBUG_MESSAGES(dev_err - (pod->line6.ifcdev, - "unknown sysex header\n")); + dev_dbg(pod->line6.ifcdev, "unknown sysex header\n"); break; @@ -362,9 +348,8 @@ void line6_pod_process_message(struct usb_line6_pod *pod) break; default: - DEBUG_MESSAGES(dev_err - (pod->line6.ifcdev, - "POD: unknown message %02X\n", buf[0])); + dev_dbg(pod->line6.ifcdev, "POD: unknown message %02X\n", + buf[0]); } } diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c index 1b85eccd92b..8df529f2638 100644 --- a/drivers/staging/line6/variax.c +++ b/drivers/staging/line6/variax.c @@ -262,10 +262,9 @@ void line6_variax_process_message(struct usb_line6_variax *variax) 2, VARIAX_DUMP_PASS3); } } else { - DEBUG_MESSAGES(dev_err - (variax->line6.ifcdev, - "illegal length %d of model data\n", - variax->line6.message_length)); + dev_dbg(variax->line6.ifcdev, + "illegal length %d of model data\n", + variax->line6.message_length); line6_dump_finished(&variax->dumpreq); } } else if (memcmp(buf + 1, variax_request_bank + 1, @@ -295,9 +294,8 @@ void line6_variax_process_message(struct usb_line6_variax *variax) break; default: - DEBUG_MESSAGES(dev_err - (variax->line6.ifcdev, - "Variax: unknown message %02X\n", buf[0])); + dev_dbg(variax->line6.ifcdev, + "Variax: unknown message %02X\n", buf[0]); } } -- cgit v1.2.3 From 60fb08b38eb1c9ffdde52817417f4b87f52be7b3 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Sun, 11 Nov 2012 13:52:25 +0100 Subject: staging: line6: drop unused DEBUG_MESSAGES() macro The DEBUG_MESSAGES() macro is no longer needed since dev_dbg() is now used for debug messages. Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h index 35246cfcd91..9dd8ff475f5 100644 --- a/drivers/staging/line6/driver.h +++ b/drivers/staging/line6/driver.h @@ -52,12 +52,6 @@ #define LINE6_CHANNEL_MASK 0x0f -#ifdef CONFIG_LINE6_USB_DEBUG -#define DEBUG_MESSAGES(x) (x) -#else -#define DEBUG_MESSAGES(x) -#endif - #define MISSING_CASE \ printk(KERN_ERR "line6usb driver bug: missing case in %s:%d\n", \ __FILE__, __LINE__) -- cgit v1.2.3 From bf83e30ec654e3a6d79e89ae70d1c9811a2387df Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Sun, 11 Nov 2012 13:52:26 +0100 Subject: staging: line6: drop unused CONFIG_LINE6_USB_DEBUG The CONFIG_LINE6_USB_DEBUG option is no longer relevant since dyndbg dev_dbg() is now used instead of a compile-time decision whether to enable debug messages or not. Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/Kconfig | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/line6/Kconfig b/drivers/staging/line6/Kconfig index 43120ff2ab7..a5ded1233fe 100644 --- a/drivers/staging/line6/Kconfig +++ b/drivers/staging/line6/Kconfig @@ -23,14 +23,6 @@ menuconfig LINE6_USB if LINE6_USB -config LINE6_USB_DEBUG - bool "print debug messages" - default n - help - Say Y here to write debug messages to the syslog. - - If unsure, say N. - config LINE6_USB_DUMP_CTRL bool "dump control messages" default n -- cgit v1.2.3 From 0a8f4a07e668ea9500df83bbe1d73cd06145cdb8 Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Sun, 11 Nov 2012 22:41:12 +0200 Subject: Staging: ipack: ipack: fix coding style issues This uses linux/io.h instead of asm/io.h and cleans up an 80+ character issue. Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/ipack.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index 75bfecfe362..f713ab3e83b 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "ipack.h" #define to_ipack_dev(device) container_of(device, struct ipack_device, dev) @@ -242,7 +242,8 @@ static int ipack_unregister_bus_member(struct device *dev, void *data) int ipack_bus_unregister(struct ipack_bus_device *bus) { - bus_for_each_dev(&ipack_bus_type, NULL, bus, ipack_unregister_bus_member); + bus_for_each_dev(&ipack_bus_type, NULL, bus, + ipack_unregister_bus_member); ida_simple_remove(&ipack_ida, bus->bus_nr); kfree(bus); return 0; -- cgit v1.2.3 From 9d10b221264b9383fcf8e8628f89e9859c05599d Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Sun, 11 Nov 2012 22:41:13 +0200 Subject: staging: ipack: tpci200: fixes 80 character line length issue This fixes one of the two instances of an 80+ char line in the file. Fixing the other instance would have decreased the readability of the code, in my opinion. Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/carriers/tpci200.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/ipack/carriers/tpci200.c b/drivers/staging/ipack/carriers/tpci200.c index 24e8e6d63f2..31cafffb8e7 100644 --- a/drivers/staging/ipack/carriers/tpci200.c +++ b/drivers/staging/ipack/carriers/tpci200.c @@ -209,7 +209,8 @@ static int tpci200_request_irq(struct ipack_device *dev, if (tpci200->slots[dev->slot].irq != NULL) { dev_err(&dev->dev, - "Slot [%d:%d] IRQ already registered !\n", dev->bus->bus_nr, + "Slot [%d:%d] IRQ already registered !\n", + dev->bus->bus_nr, dev->slot); res = -EINVAL; goto out_unlock; -- cgit v1.2.3 From 87648933116f528b3cda64c4d80d9577277fe4f0 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Mon, 12 Nov 2012 21:16:28 +0000 Subject: staging: et131x: Avoid unnecessary calculations in for loop In et131x_rx_dma_memory_alloc(), we loop over fbr_entries - the values of fbr_align and fbr_chunksize calculated in the loop do not depend on the loop counter and are the same for all loop iterations. Take the calculations of these values out of the loop, as we only need to calculate them once per loop, not once per loop iteration. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 69a07299b74..4f68646f66b 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -2266,7 +2266,9 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) u8 id; u32 i, j; u32 bufsize; - u32 pktstat_ringsize, fbr_chunksize; + u32 pktstat_ringsize; + u32 fbr_chunksize; + u32 fbr_align; struct rx_ring *rx_ring; /* Setup some convenience pointers */ @@ -2341,10 +2343,17 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) } for (id = 0; id < NUM_FBRS; id++) { + if (id == 0 && rx_ring->fbr[id]->buffsize > 4096) + fbr_align = 4096; + else + fbr_align = rx_ring->fbr[id]->buffsize; + + fbr_chunksize = (FBR_CHUNKS * + rx_ring->fbr[id]->buffsize) + fbr_align - 1; + for (i = 0; i < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); i++) { dma_addr_t fbr_tmp_physaddr; dma_addr_t fbr_offset; - u32 fbr_align; /* This code allocates an area of memory big enough for * N free buffers + (buffer_size - 1) so that the @@ -2353,13 +2362,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) * effect would be to double the size of FBR0. By * allocating N buffers at once, we reduce this overhead */ - if (id == 0 && rx_ring->fbr[id]->buffsize > 4096) - fbr_align = 4096; - else - fbr_align = rx_ring->fbr[id]->buffsize; - - fbr_chunksize = (FBR_CHUNKS * - rx_ring->fbr[id]->buffsize) + fbr_align - 1; rx_ring->fbr[id]->mem_virtaddrs[i] = dma_alloc_coherent( &adapter->pdev->dev, fbr_chunksize, &rx_ring->fbr[id]->mem_physaddrs[i], -- cgit v1.2.3 From d3c75e8dc81b6482ea230d03bbddddd38db9ab35 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Mon, 12 Nov 2012 21:16:29 +0000 Subject: staging: et131x: Remove unnecessary DMA address alignment code "The cpu return address and the DMA bus master address are both guaranteed to be aligned to the smallest PAGE_SIZE order which is greater than or equal to the requested size." There are several places in the et131x.c code where these addresses are aligned to a 4k boundary after a call to dma_alloc_coherent(), needlessly. Remove these alignment offset calculations, and the et131x_align_allocated_memory() call which is only used for 4k alignments. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 72 +++-------------------------------------- 1 file changed, 5 insertions(+), 67 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 4f68646f66b..5f15a2e175b 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -290,7 +290,6 @@ struct fbr_lookup { dma_addr_t ring_physaddr; void *mem_virtaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; dma_addr_t mem_physaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; - dma_addr_t offset; u32 local_full; u32 num_entries; dma_addr_t buffsize; @@ -2226,32 +2225,6 @@ static inline u32 bump_free_buff_ring(u32 *free_buff_ring, u32 limit) return tmp_free_buff_ring; } -/** - * et131x_align_allocated_memory - Align allocated memory on a given boundary - * @adapter: pointer to our adapter structure - * @phys_addr: pointer to Physical address - * @offset: pointer to the offset variable - * @mask: correct mask - */ -static void et131x_align_allocated_memory(struct et131x_adapter *adapter, - dma_addr_t *phys_addr, - dma_addr_t *offset, - u64 mask) -{ - u64 new_addr = *phys_addr & ~mask; - - *offset = 0; - - if (new_addr != *phys_addr) { - /* Move to next aligned block */ - new_addr += mask + 1; - /* Return offset for adjusting virt addr */ - *offset = new_addr - *phys_addr; - /* Return new physical address */ - *phys_addr = new_addr; - } -} - /** * et131x_rx_dma_memory_alloc * @adapter: pointer to our private adapter structure @@ -2268,7 +2241,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) u32 bufsize; u32 pktstat_ringsize; u32 fbr_chunksize; - u32 fbr_align; struct rx_ring *rx_ring; /* Setup some convenience pointers */ @@ -2331,29 +2303,13 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) "Cannot alloc memory for Free Buffer Ring %d\n", id); return -ENOMEM; } - - /* Align Free Buffer Ring on a 4K boundary */ - et131x_align_allocated_memory(adapter, - &rx_ring->fbr[id]->ring_physaddr, - &rx_ring->fbr[id]->offset, 0x0FFF); - - rx_ring->fbr[id]->ring_virtaddr = - (void *)((u8 *) rx_ring->fbr[id]->ring_virtaddr + - rx_ring->fbr[id]->offset); } for (id = 0; id < NUM_FBRS; id++) { - if (id == 0 && rx_ring->fbr[id]->buffsize > 4096) - fbr_align = 4096; - else - fbr_align = rx_ring->fbr[id]->buffsize; - - fbr_chunksize = (FBR_CHUNKS * - rx_ring->fbr[id]->buffsize) + fbr_align - 1; + fbr_chunksize = (FBR_CHUNKS * rx_ring->fbr[id]->buffsize); for (i = 0; i < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); i++) { dma_addr_t fbr_tmp_physaddr; - dma_addr_t fbr_offset; /* This code allocates an area of memory big enough for * N free buffers + (buffer_size - 1) so that the @@ -2376,11 +2332,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) /* See NOTE in "Save Physical Address" comment above */ fbr_tmp_physaddr = rx_ring->fbr[id]->mem_physaddrs[i]; - et131x_align_allocated_memory(adapter, - &fbr_tmp_physaddr, - &fbr_offset, - (fbr_align - 1)); - for (j = 0; j < FBR_CHUNKS; j++) { u32 index = (i * FBR_CHUNKS) + j; @@ -2389,7 +2340,7 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) */ rx_ring->fbr[id]->virt[index] = (u8 *) rx_ring->fbr[id]->mem_virtaddrs[i] + - (j * rx_ring->fbr[id]->buffsize) + fbr_offset; + (j * rx_ring->fbr[id]->buffsize); /* now store the physical address in the * descriptor so the device can access it @@ -2499,16 +2450,8 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); index++) { if (rx_ring->fbr[id]->mem_virtaddrs[index]) { - u32 fbr_align; - if (rx_ring->fbr[id]->buffsize > 4096) - fbr_align = 4096; - else - fbr_align = rx_ring->fbr[id]->buffsize; - - bufsize = - (rx_ring->fbr[id]->buffsize * FBR_CHUNKS) + - fbr_align - 1; + bufsize = (rx_ring->fbr[id]->buffsize * FBR_CHUNKS); dma_free_coherent(&adapter->pdev->dev, bufsize, @@ -2519,10 +2462,6 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) } } - /* Now the FIFO itself */ - rx_ring->fbr[id]->ring_virtaddr = (void *)((u8 *) - rx_ring->fbr[id]->ring_virtaddr - rx_ring->fbr[id]->offset); - bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries) + 0xfff; @@ -2967,7 +2906,7 @@ static int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) /* Allocate enough memory for the Tx descriptor ring, and allocate * some extra so that the ring can be aligned on a 4k boundary. */ - desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX) + 4096 - 1; + desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX); tx_ring->tx_desc_ring = (struct tx_desc *) dma_alloc_coherent(&adapter->pdev->dev, desc_size, @@ -3011,8 +2950,7 @@ static void et131x_tx_dma_memory_free(struct et131x_adapter *adapter) if (adapter->tx_ring.tx_desc_ring) { /* Free memory relating to Tx rings here */ - desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX) - + 4096 - 1; + desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX); dma_free_coherent(&adapter->pdev->dev, desc_size, adapter->tx_ring.tx_desc_ring, -- cgit v1.2.3 From c096ae130e97ffb45a902dba3c4ab07a37006091 Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Mon, 12 Nov 2012 16:28:59 +0100 Subject: staging: drm/imx: Fix YUYV support in i.MX IPUv3 base driver YVYU is not supported by the IPU, so remove partial handling of this format and replace it with YUYV which is supported. Signed-off-by: Michael Olbrich Signed-off-by: Philipp Zabel Signed-off-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/ipu-v3/ipu-common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c index 27e77c72c9c..41fe1164270 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c @@ -380,6 +380,7 @@ int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem, ipu_cpmem_set_buffer(cpmem, 0, image->phys + y_offset); break; case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUYV: ipu_cpmem_set_buffer(cpmem, 0, image->phys + image->rect.left * 2 + image->rect.top * image->pix.bytesperline); @@ -414,7 +415,7 @@ enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat) switch (pixelformat) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_YUYV: return IPUV3_COLORSPACE_YUV; case V4L2_PIX_FMT_RGB32: case V4L2_PIX_FMT_BGR32: -- cgit v1.2.3 From d3e4e610a1a65e77599d6dc2e2bed793da965f41 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 12 Nov 2012 16:29:00 +0100 Subject: staging: drm/imx: Add YVU420 support to i.MX IPUv3 base driver Signed-off-by: Philipp Zabel Signed-off-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/ipu-v3/ipu-common.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c index 41fe1164270..7f3a3aeb88a 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c @@ -234,6 +234,11 @@ void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem *p, ipu_ch_param_write_field(p, IPU_FIELD_UBO, u_offset / 8); ipu_ch_param_write_field(p, IPU_FIELD_VBO, v_offset / 8); break; + case V4L2_PIX_FMT_YVU420: + ipu_ch_param_write_field(p, IPU_FIELD_SLUV, (stride / 2) - 1); + ipu_ch_param_write_field(p, IPU_FIELD_UBO, v_offset / 8); + ipu_ch_param_write_field(p, IPU_FIELD_VBO, u_offset / 8); + break; } } EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full); @@ -246,10 +251,11 @@ void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format, switch (pixel_format) { case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: uv_stride = stride / 2; u_offset = stride * height; v_offset = u_offset + (uv_stride * height / 2); - ipu_cpmem_set_yuv_planar_full(p, V4L2_PIX_FMT_YUV420, stride, + ipu_cpmem_set_yuv_planar_full(p, pixel_format, stride, u_offset, v_offset); break; } @@ -307,6 +313,7 @@ int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat) { switch (pixelformat) { case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: /* pix format */ ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 2); /* burst size */ @@ -369,6 +376,7 @@ int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem, switch (pix->pixelformat) { case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: y_offset = Y_OFFSET(pix, image->rect.left, image->rect.top); u_offset = U_OFFSET(pix, image->rect.left, image->rect.top) - y_offset; @@ -414,6 +422,7 @@ enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat) { switch (pixelformat) { case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_YUYV: return IPUV3_COLORSPACE_YUV; -- cgit v1.2.3 From a8e4e232bab3387af5f9ee92713d1a511e249107 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 12 Nov 2012 16:29:01 +0100 Subject: staging: drm/imx: silence ipu_crtc_dpms debug message It's for debugging only, so use dev_dbg. Signed-off-by: Philipp Zabel Signed-off-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/ipuv3-crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c index 78d3edac75c..7e85c5972ae 100644 --- a/drivers/staging/imx-drm/ipuv3-crtc.c +++ b/drivers/staging/imx-drm/ipuv3-crtc.c @@ -116,7 +116,7 @@ static void ipu_crtc_dpms(struct drm_crtc *crtc, int mode) { struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); - dev_info(ipu_crtc->dev, "%s mode: %d\n", __func__, mode); + dev_dbg(ipu_crtc->dev, "%s mode: %d\n", __func__, mode); switch (mode) { case DRM_MODE_DPMS_ON: -- cgit v1.2.3 From 0125f21b2bafde5e8dc34a31c20d2db6f3645bdc Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 12 Nov 2012 16:29:02 +0100 Subject: staging: drm/imx: Add ipu_cpmem_set_yuv_interleaved() For configuring interleaved formats. Signed-off-by: Philipp Zabel Signed-off-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h | 1 + drivers/staging/imx-drm/ipu-v3/ipu-common.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h index 74158dd7375..22c1196579b 100644 --- a/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h +++ b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h @@ -293,6 +293,7 @@ static inline void ipu_cpmem_interlaced_scan(struct ipu_ch_param *p, void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format, int stride, int height); +void ipu_cpmem_set_yuv_interleaved(struct ipu_ch_param *p, u32 pixel_format); void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem *p, u32 pixel_format, int stride, int u_offset, int v_offset); int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat); diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c index 7f3a3aeb88a..eaa6f62a9e3 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c @@ -225,6 +225,23 @@ int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem *p, } EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_passthrough); +void ipu_cpmem_set_yuv_interleaved(struct ipu_ch_param *p, u32 pixel_format) +{ + switch (pixel_format) { + case V4L2_PIX_FMT_UYVY: + ipu_ch_param_write_field(p, IPU_FIELD_BPP, 3); /* bits/pixel */ + ipu_ch_param_write_field(p, IPU_FIELD_PFS, 0xA); /* pix format */ + ipu_ch_param_write_field(p, IPU_FIELD_NPB, 31); /* burst size */ + break; + case V4L2_PIX_FMT_YUYV: + ipu_ch_param_write_field(p, IPU_FIELD_BPP, 3); /* bits/pixel */ + ipu_ch_param_write_field(p, IPU_FIELD_PFS, 0x8); /* pix format */ + ipu_ch_param_write_field(p, IPU_FIELD_NPB, 31); /* burst size */ + break; + } +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved); + void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem *p, u32 pixel_format, int stride, int u_offset, int v_offset) { -- cgit v1.2.3 From 87e31a0795059315576cccce1205aed663c6502d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 12 Nov 2012 16:29:03 +0100 Subject: staging: drm/imx: Add pinctrl support to parallel display driver To allow the iomux to be configured for the display. Signed-off-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/parallel-display.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c index 9b51d732eef..324283c9553 100644 --- a/drivers/staging/imx-drm/parallel-display.c +++ b/drivers/staging/imx-drm/parallel-display.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "imx-drm.h" @@ -195,11 +196,20 @@ static int __devinit imx_pd_probe(struct platform_device *pdev) struct imx_parallel_display *imxpd; int ret; const char *fmt; + struct pinctrl *pinctrl; imxpd = devm_kzalloc(&pdev->dev, sizeof(*imxpd), GFP_KERNEL); if (!imxpd) return -ENOMEM; + pinctrl = devm_pinctrl_get_select_default(&pdev->dev); + if (IS_ERR(pinctrl)) { + ret = PTR_ERR(pinctrl); + dev_warn(&pdev->dev, "pinctrl_get_select_default failed with %d", + ret); + return ret; + } + edidp = of_get_property(np, "edid", &imxpd->edid_len); if (edidp) imxpd->edid = kmemdup(edidp, imxpd->edid_len, GFP_KERNEL); -- cgit v1.2.3 From 2d8f46f286a80255d8c684fb12fd40feb37ad258 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 12 Nov 2012 16:29:04 +0100 Subject: staging: drm/imx: Remove 300ms delay after memory reset This has been added once, but does not seem to be necessary. Tested on i.MX51 and i.MX6. Signed-off-by: Philipp Zabel Signed-off-by: Sascha Hauer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/ipu-v3/ipu-common.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c index eaa6f62a9e3..cd05718b704 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c @@ -673,8 +673,6 @@ static int ipu_reset(struct ipu_soc *ipu) cpu_relax(); } - mdelay(300); - return 0; } -- cgit v1.2.3 From 2aeeb8acfc19f8a9f283081bbf77919b61b92042 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 13 Nov 2012 14:10:00 -0400 Subject: staging: omap-thermal: fix compilation Because we are not including linux/io.h, the driver is not compiling. This patch adds the missing header. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 368a2e19b2d..1cae5ed944e 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "omap-bandgap.h" -- cgit v1.2.3 From 5041949117e3c1a0b7c21c3b176ca18b202d4027 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 13 Nov 2012 14:10:01 -0400 Subject: staging: omap-thermal: remove platform data nomenclature Because the driver is not really using platform data, this patch removes the pdata nomenclature from this driver. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-thermal-common.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c b/drivers/staging/omap-thermal/omap-thermal-common.c index 5c0c203b887..5be66d7f5d2 100644 --- a/drivers/staging/omap-thermal/omap-thermal-common.c +++ b/drivers/staging/omap-thermal/omap-thermal-common.c @@ -256,12 +256,12 @@ static struct omap_thermal_data int omap_thermal_expose_sensor(struct omap_bandgap *bg_ptr, int id, char *domain) { - struct omap_thermal_pdata pdata; + struct omap_thermal_data *data; data = omap_bandgap_get_sensor_data(bg_ptr, id); if (!data) - data = omap_thermal_build_pdata(bg_ptr, id); + data = omap_thermal_build_data(bg_ptr, id); if (!data) return -EINVAL; @@ -359,7 +359,7 @@ int omap_thermal_register_cpu_cooling(struct omap_bandgap *bg_ptr, int id) data = omap_bandgap_get_sensor_data(bg_ptr, id); if (!data) - data = omap_thermal_build_pdata(bg_ptr, id); + data = omap_thermal_build_data(bg_ptr, id); if (!data) return -EINVAL; -- cgit v1.2.3 From 5035d48dd02f982b3034ba755d5c4d153b2fc6df Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 13 Nov 2012 14:10:02 -0400 Subject: staging: omap-thermal: remove freq_clip table The API exposed by cpu cooling does not need any freq clip table anymore. Now the cpu cooling device is smart enough to build its own table. For this reason, this patch removes all the code that is generating a freq clip table and also removes all references in data structures regarding freq clip table. Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.h | 9 ---- drivers/staging/omap-thermal/omap-thermal-common.c | 63 ++-------------------- 2 files changed, 3 insertions(+), 69 deletions(-) diff --git a/drivers/staging/omap-thermal/omap-bandgap.h b/drivers/staging/omap-thermal/omap-bandgap.h index 78aed7535f4..2bb14bd7c6d 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.h +++ b/drivers/staging/omap-thermal/omap-bandgap.h @@ -335,14 +335,6 @@ struct temp_sensor_regval { u32 tshut_threshold; }; -/** - * struct thermal_cooling_conf - description on how to cool a thermal zone - * @freq_clip_count: size of freq_data - */ -struct thermal_cooling_conf { - int freq_clip_count; -}; - /** * struct omap_temp_sensor - bandgap temperature sensor platform data * @ts_data: pointer to struct with thresholds, limits of temperature sensor @@ -365,7 +357,6 @@ struct omap_temp_sensor { struct temp_sensor_registers *registers; struct temp_sensor_regval regval; char *domain; - struct thermal_cooling_conf cooling_data; /* for hotspot extrapolation */ const int slope; const int constant; diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c b/drivers/staging/omap-thermal/omap-thermal-common.c index 5be66d7f5d2..15e9723ba4d 100644 --- a/drivers/staging/omap-thermal/omap-thermal-common.c +++ b/drivers/staging/omap-thermal/omap-thermal-common.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "omap-thermal.h" @@ -112,7 +113,7 @@ static int omap_thermal_bind(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev) { struct omap_thermal_data *data = thermal->devdata; - int max, id; + int id; if (IS_ERR_OR_NULL(data)) return -ENODEV; @@ -122,7 +123,6 @@ static int omap_thermal_bind(struct thermal_zone_device *thermal, return 0; id = data->sensor_id; - max = data->bg_ptr->conf->sensors[id].cooling_data.freq_clip_count; /* TODO: bind with min and max states */ /* Simple thing, two trips, one passive another critical */ @@ -304,58 +304,9 @@ int omap_thermal_report_sensor_temperature(struct omap_bandgap *bg_ptr, int id) return 0; } -static int omap_thermal_build_cpufreq_clip(struct omap_bandgap *bg_ptr, - struct freq_clip_table **tab_ptr, - int *tab_size) -{ - struct cpufreq_frequency_table *freq_table; - struct freq_clip_table *tab; - int i, count = 0; - - freq_table = cpufreq_frequency_get_table(0); - if (IS_ERR_OR_NULL(freq_table)) { - dev_err(bg_ptr->dev, - "%s: failed to get cpufreq table (%p)\n", - __func__, freq_table); - return -EINVAL; - } - - for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { - unsigned int freq = freq_table[i].frequency; - if (freq == CPUFREQ_ENTRY_INVALID) - continue; - count++; - } - - tab = devm_kzalloc(bg_ptr->dev, sizeof(*tab) * count, GFP_KERNEL); - if (!tab) { - dev_err(bg_ptr->dev, - "%s: no memory available\n", __func__); - return -ENOMEM; - } - - for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) { - unsigned int freq = freq_table[i].frequency; - - if (freq == CPUFREQ_ENTRY_INVALID) - continue; - - tab[count - i - 1].freq_clip_max = freq; - tab[count - i - 1].temp_level = OMAP_TRIP_HOT; - tab[count - i - 1].mask_val = cpumask_of(0); - } - - *tab_ptr = tab; - *tab_size = count; - - return 0; -} - int omap_thermal_register_cpu_cooling(struct omap_bandgap *bg_ptr, int id) { struct omap_thermal_data *data; - struct freq_clip_table *tab_ptr; - int tab_size, ret; data = omap_bandgap_get_sensor_data(bg_ptr, id); if (!data) @@ -364,21 +315,13 @@ int omap_thermal_register_cpu_cooling(struct omap_bandgap *bg_ptr, int id) if (!data) return -EINVAL; - ret = omap_thermal_build_cpufreq_clip(bg_ptr, &tab_ptr, &tab_size); - if (ret < 0) { - dev_err(bg_ptr->dev, - "%s: failed to build cpufreq clip table\n", __func__); - return ret; - } - /* Register cooling device */ - data->cool_dev = cpufreq_cooling_register(tab_ptr, tab_size); + data->cool_dev = cpufreq_cooling_register(cpu_present_mask); if (IS_ERR_OR_NULL(data->cool_dev)) { dev_err(bg_ptr->dev, "Failed to register cpufreq cooling device\n"); return PTR_ERR(data->cool_dev); } - bg_ptr->conf->sensors[id].cooling_data.freq_clip_count = tab_size; omap_bandgap_set_sensor_data(bg_ptr, id, data); return 0; -- cgit v1.2.3 From 71e303f5b87e821a702e5a17b26f61ab329737e4 Mon Sep 17 00:00:00 2001 From: Eduardo Valentin Date: Tue, 13 Nov 2012 14:10:03 -0400 Subject: staging: omap-thermal: add IRQ debugging messaging For debugging purposes, print the IRQ event for the domain being processed. Signed-off-by: Enric Balletbo i Serra Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 1cae5ed944e..3eb726f29d1 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -113,6 +113,11 @@ static irqreturn_t talert_irq_handler(int irq, void *data) omap_bandgap_writel(bg_ptr, ctrl, tsr->bgap_mask_ctrl); + dev_dbg(bg_ptr->dev, + "%s: IRQ from %s sensor: hotevent %d coldevent %d\n", + __func__, bg_ptr->conf->sensors[i].domain, + t_hot, t_cold); + /* read temperature */ temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl); temp &= tsr->bgap_dtemp_mask; -- cgit v1.2.3 From b87ea759a4cc2cae359288f003aae6a027330860 Mon Sep 17 00:00:00 2001 From: Radhesh Fadnis Date: Tue, 13 Nov 2012 14:10:04 -0400 Subject: staging: omap-thermal: fix context restore function In the context restore function, if the context is lost or not is being checked by the contents of the counter register. But this is logic hold good as long as counter reset value is zero, if the reset value is non-zero then above logic doesn't hold good. Hence removed checking of the register value and restoring the context. Signed-off-by: Radhesh Fadnis Signed-off-by: Enric Balletbo i Serra Signed-off-by: Eduardo Valentin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omap-thermal/omap-bandgap.c | 57 +++++++++++------------------ 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/drivers/staging/omap-thermal/omap-bandgap.c b/drivers/staging/omap-thermal/omap-bandgap.c index 3eb726f29d1..c17bc955c55 100644 --- a/drivers/staging/omap-thermal/omap-bandgap.c +++ b/drivers/staging/omap-thermal/omap-bandgap.c @@ -1065,7 +1065,6 @@ static int omap_bandgap_save_ctxt(struct omap_bandgap *bg_ptr) static int omap_bandgap_restore_ctxt(struct omap_bandgap *bg_ptr) { int i; - u32 temp = 0; for (i = 0; i < bg_ptr->conf->sensor_count; i++) { struct temp_sensor_registers *tsr; @@ -1078,41 +1077,27 @@ static int omap_bandgap_restore_ctxt(struct omap_bandgap *bg_ptr) if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER)) val = omap_bandgap_readl(bg_ptr, tsr->bgap_counter); - if (val == 0) { - if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG)) - omap_bandgap_writel(bg_ptr, - rval->tshut_threshold, - tsr->tshut_threshold); - /* Force immediate temperature measurement and update - * of the DTEMP field - */ - omap_bandgap_force_single_read(bg_ptr, i); - - if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER)) - omap_bandgap_writel(bg_ptr, rval->bg_counter, - tsr->bgap_counter); - if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG)) - omap_bandgap_writel(bg_ptr, rval->bg_mode_ctrl, - tsr->bgap_mode_ctrl); - if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) { - omap_bandgap_writel(bg_ptr, - rval->bg_threshold, - tsr->bgap_threshold); - omap_bandgap_writel(bg_ptr, rval->bg_ctrl, - tsr->bgap_mask_ctrl); - } - } else { - temp = omap_bandgap_readl(bg_ptr, - tsr->temp_sensor_ctrl); - temp &= (tsr->bgap_dtemp_mask); - omap_bandgap_force_single_read(bg_ptr, i); - if (temp == 0 && OMAP_BANDGAP_HAS(bg_ptr, TALERT)) { - temp = omap_bandgap_readl(bg_ptr, - tsr->bgap_mask_ctrl); - temp |= 1 << __ffs(tsr->mode_ctrl_mask); - omap_bandgap_writel(bg_ptr, temp, - tsr->bgap_mask_ctrl); - } + if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG)) + omap_bandgap_writel(bg_ptr, + rval->tshut_threshold, + tsr->tshut_threshold); + /* Force immediate temperature measurement and update + * of the DTEMP field + */ + omap_bandgap_force_single_read(bg_ptr, i); + + if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER)) + omap_bandgap_writel(bg_ptr, rval->bg_counter, + tsr->bgap_counter); + if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG)) + omap_bandgap_writel(bg_ptr, rval->bg_mode_ctrl, + tsr->bgap_mode_ctrl); + if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) { + omap_bandgap_writel(bg_ptr, + rval->bg_threshold, + tsr->bgap_threshold); + omap_bandgap_writel(bg_ptr, rval->bg_ctrl, + tsr->bgap_mask_ctrl); } } -- cgit v1.2.3 From 848ce5112e7fcb38aaafff28253314da330b681e Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Tue, 13 Nov 2012 21:04:36 +0000 Subject: staging: vt6656: iwctl_giwaplist/device_ioctl : use off stack buffers. Calls ioctl SIOCGIWAPLIST use off stack buffers. clears up warning messages. main_usb.c:2015:1: warning: the frame size of 1888 bytes is larger than 1024 bytes [-Wframe-larger-than=] iwctl.c:683:1: warning: the frame size of 1280 bytes is larger than 1024 bytes [-Wframe-larger-than=] Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 73 ++++++++++++++++++++++----------------- drivers/staging/vt6656/main_usb.c | 46 ++++++++++++++---------- 2 files changed, 68 insertions(+), 51 deletions(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 706e2a6c4e7..a914d20cc0e 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -632,47 +632,56 @@ int iwctl_giwap(struct net_device *dev, struct iw_request_info *info, * Wireless Handler: get ap list */ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, - struct iw_point *wrq, char *extra) + struct iw_point *wrq, u8 *extra) { + struct sockaddr *sock; + struct iw_quality *qual; + PSDevice pDevice = netdev_priv(dev); + PSMgmtObject pMgmt = &pDevice->sMgmtObj; + PKnownBSS pBSS = &pMgmt->sBSSList[0]; int ii; int jj; - int rc = 0; - struct sockaddr sock[IW_MAX_AP]; - struct iw_quality qual[IW_MAX_AP]; - PSDevice pDevice = netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST \n"); - // Only super-user can see AP list + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST\n"); + /* Only super-user can see AP list */ - if (!capable(CAP_NET_ADMIN)) { - rc = -EPERM; - return rc; - } + if (pBSS == NULL) + return -ENODEV; - if (wrq->pointer) { - PKnownBSS pBSS = &(pMgmt->sBSSList[0]); + if (!capable(CAP_NET_ADMIN)) + return -EPERM; - for (ii = 0, jj= 0; ii < MAX_BSS_NUM; ii++) { - pBSS = &(pMgmt->sBSSList[ii]); - if (!pBSS->bActive) - continue; - if (jj >= IW_MAX_AP) - break; - memcpy(sock[jj].sa_data, pBSS->abyBSSID, 6); - sock[jj].sa_family = ARPHRD_ETHER; - qual[jj].level = pBSS->uRSSI; - qual[jj].qual = qual[jj].noise = 0; - qual[jj].updated = 2; - jj++; - } + if (!wrq->pointer) + return -EINVAL; + + sock = kzalloc(sizeof(struct sockaddr) * IW_MAX_AP, GFP_KERNEL); + qual = kzalloc(sizeof(struct iw_quality) * IW_MAX_AP, GFP_KERNEL); + if (sock == NULL || qual == NULL) + return -ENOMEM; - wrq->flags = 1; // Should be defined - wrq->length = jj; - memcpy(extra, sock, sizeof(struct sockaddr) * jj); - memcpy(extra + sizeof(struct sockaddr) * jj, qual, sizeof(struct iw_quality) * jj); + for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) { + if (!pBSS[ii].bActive) + continue; + if (jj >= IW_MAX_AP) + break; + memcpy(sock[jj].sa_data, pBSS[ii].abyBSSID, 6); + sock[jj].sa_family = ARPHRD_ETHER; + qual[jj].level = pBSS[ii].uRSSI; + qual[jj].qual = qual[jj].noise = 0; + qual[jj].updated = 2; + jj++; } - return rc; + + wrq->flags = 1; /* Should be defined */ + wrq->length = jj; + memcpy(extra, sock, sizeof(struct sockaddr) * jj); + memcpy(extra + sizeof(struct sockaddr) * jj, qual, + sizeof(struct iw_quality) * jj); + + kfree(sock); + kfree(qual); + + return 0; } /* diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index d8cb0934148..f3c44aefa41 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1555,12 +1555,12 @@ static struct net_device_stats *device_get_stats(struct net_device *dev) { static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - PSCmdRequest pReq; - //BOOL bCommit = FALSE; + PSDevice pDevice = (PSDevice)netdev_priv(dev); + PSMgmtObject pMgmt = &pDevice->sMgmtObj; + PSCmdRequest pReq; + u8 *buffer; struct iwreq *wrq = (struct iwreq *) rq; - int rc =0; + int rc = 0; if (pMgmt == NULL) { rc = -EFAULT; @@ -1797,20 +1797,28 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { break; case SIOCGIWAPLIST: - { - char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))]; - - if (wrq->u.data.pointer) { - rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer); - if (rc == 0) { - if (copy_to_user(wrq->u.data.pointer, - buffer, - (wrq->u.data.length * (sizeof(struct sockaddr) + sizeof(struct iw_quality))) - )) - rc = -EFAULT; - } - } - } + if (wrq->u.data.pointer) { + buffer = kzalloc((sizeof(struct sockaddr) + + sizeof(struct iw_quality)) * IW_MAX_AP, + GFP_KERNEL); + if (buffer == NULL) { + rc = -ENOMEM; + break; + } + + rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer); + if (rc < 0) { + kfree(buffer); + break; + } + + if (copy_to_user(wrq->u.data.pointer, buffer, + wrq->u.data.length * (sizeof(struct sockaddr) + + sizeof(struct iw_quality)))) + rc = -EFAULT; + + kfree(buffer); + } break; -- cgit v1.2.3 From 2a366e7b9d7118e657980399bcf41b353894ab92 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:36:19 -0700 Subject: staging: comedi: addi_apci_1516: merge in addi_apci_2016 driver The low-level hardware support code for these drivers, hwdrv_apci1516.c and hwdrv_apci2016.c, is identical. Both of these boards are 16 channel dio boards. The 1516 board has 8 input/8 output channels and the 2016 has 16 output channels. To ease maintainability, merge the boardinfo and pci device information from the addi_apci_2016 driver into the addi_apci_1516 driver and modify the Kconfig and Makefile appropriately. This allows deleting the addi_apci_2016.c and hwdrv_apci2016.c files. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 13 +- drivers/staging/comedi/drivers/Makefile | 1 - .../comedi/drivers/addi-data/hwdrv_apci2016.c | 240 --------------------- drivers/staging/comedi/drivers/addi_apci_1516.c | 17 ++ drivers/staging/comedi/drivers/addi_apci_2016.c | 68 ------ 5 files changed, 19 insertions(+), 320 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c delete mode 100644 drivers/staging/comedi/drivers/addi_apci_2016.c diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 6246bed00ef..bede5736532 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -594,10 +594,10 @@ config COMEDI_ADDI_APCI_1500 called addi_apci_1500. config COMEDI_ADDI_APCI_1516 - tristate "ADDI-DATA APCI_1516 support" + tristate "ADDI-DATA APCI-1516/2016 support" depends on VIRT_TO_BUS ---help--- - Enable support for ADDI-DATA APCI_1516 cards + Enable support for ADDI-DATA APCI-1516 and APCI-2016 boards. To compile this driver as a module, choose M here: the module will be called addi_apci_1516. @@ -620,15 +620,6 @@ config COMEDI_ADDI_APCI_16XX To compile this driver as a module, choose M here: the module will be called addi_apci_16xx. -config COMEDI_ADDI_APCI_2016 - tristate "ADDI-DATA APCI_2016 support" - depends on VIRT_TO_BUS - ---help--- - Enable support for ADDI-DATA APCI_2016 cards - - To compile this driver as a module, choose M here: the module will be - called addi_apci_2016. - config COMEDI_ADDI_APCI_2032 tristate "ADDI-DATA APCI_2032 support" depends on VIRT_TO_BUS diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index c784bedb911..0de4d2eb76f 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -62,7 +62,6 @@ obj-$(CONFIG_COMEDI_ADDI_APCI_1500) += addi_apci_1500.o obj-$(CONFIG_COMEDI_ADDI_APCI_1516) += addi_apci_1516.o obj-$(CONFIG_COMEDI_ADDI_APCI_1564) += addi_apci_1564.o obj-$(CONFIG_COMEDI_ADDI_APCI_16XX) += addi_apci_16xx.o -obj-$(CONFIG_COMEDI_ADDI_APCI_2016) += addi_apci_2016.o obj-$(CONFIG_COMEDI_ADDI_APCI_2032) += addi_apci_2032.o obj-$(CONFIG_COMEDI_ADDI_APCI_2200) += addi_apci_2200.o obj-$(CONFIG_COMEDI_ADDI_APCI_3120) += addi_apci_3120.o diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c deleted file mode 100644 index c1a58398266..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c +++ /dev/null @@ -1,240 +0,0 @@ -/** -@verbatim - -Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - - ADDI-DATA GmbH - Dieselstrasse 3 - D-77833 Ottersweier - Tel: +19(0)7223/9493-0 - Fax: +49(0)7223/9493-92 - http://www.addi-data.com - info@addi-data.com - -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. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -You should also find the complete GPL in the COPYING file accompanying this source code. - -@endverbatim -*/ -/* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-------------------------------+---------------------------------------+ - | Project : APCI-2016 | Compiler : GCC | - | Module name : hwdrv_apci2016.c| Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-------------------------------+---------------------------------------+ - | Description : Hardware Layer Access For APCI-2016 | - +-----------------------------------------------------------------------+ - | UPDATES | - +----------+-----------+------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | | | | - | | | | - | | | | - +----------+-----------+------------------------------------------------+ -*/ - -/********* Definitions for APCI-2016 card *****/ - -#define APCI2016_ADDRESS_RANGE 8 - -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI2016_DIGITAL_OP 0x04 -#define APCI2016_DIGITAL_OP_RW 4 - -/* TIMER COUNTER WATCHDOG DEFINES */ - -#define ADDIDATA_WATCHDOG 2 -#define APCI2016_DIGITAL_OP_WATCHDOG 0 -#define APCI2016_WATCHDOG_ENABLEDISABLE 12 -#define APCI2016_WATCHDOG_RELOAD_VALUE 4 -#define APCI2016_WATCHDOG_STATUS 16 - -static int apci2016_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - unsigned int mask = data[0]; - unsigned int bits = data[1]; - - s->state = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW); - if (mask) { - s->state &= ~mask; - s->state |= (bits & mask); - - outw(s->state, devpriv->iobase + APCI2016_DIGITAL_OP); - } - - data[1] = s->state; - - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_ConfigWatchdog | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Configures The Watchdog | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure | -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - if (data[0] == 0) { - /* Disable the watchdog */ - outw(0x0, - devpriv->i_IobaseAddon + - APCI2016_WATCHDOG_ENABLEDISABLE); - /* Loading the Reload value */ - outw(data[1], - devpriv->i_IobaseAddon + - APCI2016_WATCHDOG_RELOAD_VALUE); - data[1] = data[1] >> 16; - outw(data[1], - devpriv->i_IobaseAddon + - APCI2016_WATCHDOG_RELOAD_VALUE + 2); - } else { - printk("\nThe input parameters are wrong\n"); - } - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_StartStopWriteWatchdog | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Start / Stop The Watchdog | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure | -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ -static int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - switch (data[0]) { - case 0: /* stop the watchdog */ - outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */ - break; - case 1: /* start the watchdog */ - outw(0x0001, - devpriv->i_IobaseAddon + - APCI2016_WATCHDOG_ENABLEDISABLE); - break; - case 2: /* Software trigger */ - outw(0x0201, - devpriv->i_IobaseAddon + - APCI2016_WATCHDOG_ENABLEDISABLE); - break; - default: - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* switch(data[0]) */ - - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_ReadWatchdog | -| (struct comedi_device *dev,struct comedi_subdevice *s, | -| struct comedi_insn *insn,unsigned int *data) | -+----------------------------------------------------------------------------+ -| Task : Read The Watchdog | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure | -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI2016_ReadWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct addi_private *devpriv = dev->private; - - udelay(5); - data[0] = inw(devpriv->i_IobaseAddon + APCI2016_WATCHDOG_STATUS) & 0x1; - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI2016_Reset(struct comedi_device *dev) | | -+----------------------------------------------------------------------------+ -| Task :resets all the registers | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI2016_Reset(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - - outw(0x0, devpriv->iobase + APCI2016_DIGITAL_OP); /* Resets the digital output channels */ - outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE); - outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE); - outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE + 2); - return 0; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 0382844fdc0..cada79ce026 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -27,6 +27,22 @@ static const struct addi_board apci1516_boardtypes[] = { .timer_config = i_APCI1516_ConfigWatchdog, .timer_write = i_APCI1516_StartStopWriteWatchdog, .timer_read = i_APCI1516_ReadWatchdog, + }, { + .pc_DriverName = "apci2016", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1002, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = APCI1516_ADDRESS_RANGE, + .i_IorangeBase2 = 32, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrDoChannel = 16, + .i_Timer = 1, + .reset = i_APCI1516_Reset, + .do_bits = apci1516_do_insn_bits, + .timer_config = i_APCI1516_ConfigWatchdog, + .timer_write = i_APCI1516_StartStopWriteWatchdog, + .timer_read = i_APCI1516_ReadWatchdog, }, }; @@ -53,6 +69,7 @@ static void __devexit apci1516_pci_remove(struct pci_dev *dev) static DEFINE_PCI_DEVICE_TABLE(apci1516_pci_table) = { { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1001) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1002) }, { 0 } }; MODULE_DEVICE_TABLE(pci, apci1516_pci_table); diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c deleted file mode 100644 index 54b05d3fa1b..00000000000 --- a/drivers/staging/comedi/drivers/addi_apci_2016.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "../comedidev.h" -#include "comedi_fc.h" -#include "amcc_s5933.h" - -#include "addi-data/addi_common.h" - -#include "addi-data/addi_eeprom.c" -#include "addi-data/hwdrv_apci2016.c" -#include "addi-data/addi_common.c" - -static const struct addi_board apci2016_boardtypes[] = { - { - .pc_DriverName = "apci2016", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1002, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = APCI2016_ADDRESS_RANGE, - .i_IorangeBase2 = 32, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, - .i_NbrDoChannel = 16, - .i_Timer = 1, - .reset = i_APCI2016_Reset, - .do_bits = apci2016_do_insn_bits, - .timer_config = i_APCI2016_ConfigWatchdog, - .timer_write = i_APCI2016_StartStopWriteWatchdog, - .timer_read = i_APCI2016_ReadWatchdog, - }, -}; - -static struct comedi_driver apci2016_driver = { - .driver_name = "addi_apci_2016", - .module = THIS_MODULE, - .auto_attach = addi_auto_attach, - .detach = i_ADDI_Detach, - .num_names = ARRAY_SIZE(apci2016_boardtypes), - .board_name = &apci2016_boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), -}; - -static int __devinit apci2016_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - return comedi_pci_auto_config(dev, &apci2016_driver); -} - -static void __devexit apci2016_pci_remove(struct pci_dev *dev) -{ - comedi_pci_auto_unconfig(dev); -} - -static DEFINE_PCI_DEVICE_TABLE(apci2016_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1002) }, - { 0 } -}; -MODULE_DEVICE_TABLE(pci, apci2016_pci_table); - -static struct pci_driver apci2016_pci_driver = { - .name = "addi_apci_2016", - .id_table = apci2016_pci_table, - .probe = apci2016_pci_probe, - .remove = __devexit_p(apci2016_pci_remove), -}; -module_comedi_pci_driver(apci2016_driver, apci2016_pci_driver); - -MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From ecc073057330b739920bda32d57ae97f16b14c43 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:36:44 -0700 Subject: staging: comedi: addi_apci_1516: add support for apci1016 board The apci1016 board can also be supported by this driver. This board is also a 16 channel dio board with 16 input channels. The apci1016 does not have the watchdog timer feature of the apci1516 and apci2016. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index cada79ce026..c885833bcdc 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -10,6 +10,18 @@ static const struct addi_board apci1516_boardtypes[] = { { + .pc_DriverName = "apci1016", + .i_VendorId = PCI_VENDOR_ID_ADDIDATA, + .i_DeviceId = 0x1000, + .i_IorangeBase0 = 128, + .i_IorangeBase1 = APCI1516_ADDRESS_RANGE, + .i_IorangeBase2 = 32, + .i_PCIEeprom = ADDIDATA_EEPROM, + .pc_EepromChip = ADDIDATA_S5920, + .i_NbrDiChannel = 16, + .reset = i_APCI1516_Reset, + .di_bits = apci1516_di_insn_bits, + }, { .pc_DriverName = "apci1516", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x1001, @@ -68,6 +80,7 @@ static void __devexit apci1516_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(apci1516_pci_table) = { + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1000) }, { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1001) }, { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1002) }, { 0 } -- cgit v1.2.3 From f57f797a6cc1d5ad101f90244b936480079c6dab Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:37:01 -0700 Subject: staging: comedi: addi_apci_1516: cleanup the register map defines For aesthetic reasons, rename the defines used for the register map and convert them from decimal to hex values. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1516.c | 63 ++++++++++------------ 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index 48e58a3154e..f1b209df0fd 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -51,19 +51,22 @@ You should also find the complete GPL in the COPYING file accompanying this sour /* Card Specific information */ #define APCI1516_ADDRESS_RANGE 8 -/* DIGITAL INPUT-OUTPUT DEFINE */ - -#define APCI1516_DIGITAL_OP 4 -#define APCI1516_DIGITAL_OP_RW 4 -#define APCI1516_DIGITAL_IP 0 +/* + * PCI bar 1 I/O Register map + */ +#define APCI1516_DI_REG 0x00 +#define APCI1516_DO_REG 0x04 -/* TIMER COUNTER WATCHDOG DEFINES */ +/* + * PCI bar 2 I/O Register map + */ +#define APCI1516_WDOG_REG 0x00 +#define APCI1516_WDOG_RELOAD_LSB_REG 0x04 +#define APCI1516_WDOG_RELOAD_MSB_REG 0x06 +#define APCI1516_WDOG_CTRL_REG 0x0c +#define APCI1516_WDOG_STATUS_REG 0x10 #define ADDIDATA_WATCHDOG 2 -#define APCI1516_DIGITAL_OP_WATCHDOG 0 -#define APCI1516_WATCHDOG_ENABLEDISABLE 12 -#define APCI1516_WATCHDOG_RELOAD_VALUE 4 -#define APCI1516_WATCHDOG_STATUS 16 static int apci1516_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, @@ -72,7 +75,7 @@ static int apci1516_di_insn_bits(struct comedi_device *dev, { struct addi_private *devpriv = dev->private; - data[1] = inw(devpriv->iobase + APCI1516_DIGITAL_IP); + data[1] = inw(devpriv->iobase + APCI1516_DI_REG); return insn->n; } @@ -87,12 +90,12 @@ static int apci1516_do_insn_bits(struct comedi_device *dev, unsigned int mask = data[0]; unsigned int bits = data[1]; - s->state = inw(devpriv->iobase + APCI1516_DIGITAL_OP_RW); + s->state = inw(devpriv->iobase + APCI1516_DO_REG); if (mask) { s->state &= ~mask; s->state |= (bits & mask); - outw(s->state, devpriv->iobase + APCI1516_DIGITAL_OP); + outw(s->state, devpriv->iobase + APCI1516_DO_REG); } data[1] = s->state; @@ -130,17 +133,13 @@ static int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, if (data[0] == 0) { /* Disable the watchdog */ - outw(0x0, - devpriv->i_IobaseAddon + - APCI1516_WATCHDOG_ENABLEDISABLE); + outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); /* Loading the Reload value */ - outw(data[1], - devpriv->i_IobaseAddon + - APCI1516_WATCHDOG_RELOAD_VALUE); + outw(data[1], devpriv->i_IobaseAddon + + APCI1516_WDOG_RELOAD_LSB_REG); data[1] = data[1] >> 16; - outw(data[1], - devpriv->i_IobaseAddon + - APCI1516_WATCHDOG_RELOAD_VALUE + 2); + outw(data[1], devpriv->i_IobaseAddon + + APCI1516_WDOG_RELOAD_MSB_REG); } /* if(data[0]==0) */ else { printk("\nThe input parameters are wrong\n"); @@ -180,17 +179,13 @@ static int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, switch (data[0]) { case 0: /* stop the watchdog */ - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */ + outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); break; case 1: /* start the watchdog */ - outw(0x0001, - devpriv->i_IobaseAddon + - APCI1516_WATCHDOG_ENABLEDISABLE); + outw(0x0001, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); break; case 2: /* Software trigger */ - outw(0x0201, - devpriv->i_IobaseAddon + - APCI1516_WATCHDOG_ENABLEDISABLE); + outw(0x0201, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); break; default: printk("\nSpecified functionality does not exist\n"); @@ -227,7 +222,7 @@ static int i_APCI1516_ReadWatchdog(struct comedi_device *dev, { struct addi_private *devpriv = dev->private; - data[0] = inw(devpriv->i_IobaseAddon + APCI1516_WATCHDOG_STATUS) & 0x1; + data[0] = inw(devpriv->i_IobaseAddon + APCI1516_WDOG_STATUS_REG) & 0x1; return insn->n; } @@ -250,9 +245,9 @@ static int i_APCI1516_Reset(struct comedi_device *dev) { struct addi_private *devpriv = dev->private; - outw(0x0, devpriv->iobase + APCI1516_DIGITAL_OP); /* RESETS THE DIGITAL OUTPUTS */ - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE); - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE); - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE + 2); + outw(0x0, devpriv->iobase + APCI1516_DO_REG); + outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); + outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_RELOAD_LSB_REG); + outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_RELOAD_MSB_REG); return 0; } -- cgit v1.2.3 From 393cc220bda3f16d497d9a5192a52fc08db18a89 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:37:31 -0700 Subject: staging: comedi: addi_apci_1516: define the watchdog control register Add defines for the bits in the watchdog control register and use them to remove the "magic" numbers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index f1b209df0fd..a0d29be6726 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -64,6 +64,8 @@ You should also find the complete GPL in the COPYING file accompanying this sour #define APCI1516_WDOG_RELOAD_LSB_REG 0x04 #define APCI1516_WDOG_RELOAD_MSB_REG 0x06 #define APCI1516_WDOG_CTRL_REG 0x0c +#define APCI1516_WDOG_CTRL_ENABLE (1 << 0) +#define APCI1516_WDOG_CTRL_SOFT_TRIG (1 << 9) #define APCI1516_WDOG_STATUS_REG 0x10 #define ADDIDATA_WATCHDOG 2 @@ -182,10 +184,12 @@ static int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); break; case 1: /* start the watchdog */ - outw(0x0001, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); + outw(APCI1516_WDOG_CTRL_ENABLE, + devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); break; case 2: /* Software trigger */ - outw(0x0201, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); + outw(APCI1516_WDOG_CTRL_ENABLE | APCI1516_WDOG_CTRL_SOFT_TRIG, + devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); break; default: printk("\nSpecified functionality does not exist\n"); -- cgit v1.2.3 From 049ff74ca0f831d08b5895bebf40fe064117e2b3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:38:39 -0700 Subject: staging: comedi: addi_apci_1516: separate from addi_common.c This driver is for simple 16 channel dio boards. Using the addi-data "common" code introduces a lot of bloat. Copy the code in addi_common.c to this driver and remove the #include that caused addi_common.c to be compiled with this driver. This will allow removing the bloat. Rename the attach_pci and detach functions so they have namespace associated with this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 314 +++++++++++++++++++++++- 1 file changed, 311 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index c885833bcdc..4cf1f034917 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -4,9 +4,12 @@ #include "addi-data/addi_common.h" +#ifndef COMEDI_SUBD_TTLIO +#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ +#endif + #include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1516.c" -#include "addi-data/addi_common.c" static const struct addi_board apci1516_boardtypes[] = { { @@ -58,11 +61,316 @@ static const struct addi_board apci1516_boardtypes[] = { }, }; +static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; + unsigned short w_Address = CR_CHAN(insn->chanspec); + unsigned short w_Data; + + w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, + this_board->pc_EepromChip, 2 * w_Address); + data[0] = w_Data; + + return insn->n; +} + +static irqreturn_t v_ADDI_Interrupt(int irq, void *d) +{ + struct comedi_device *dev = d; + const struct addi_board *this_board = comedi_board(dev); + + this_board->interrupt(irq, d); + return IRQ_RETVAL(1); +} + +static int i_ADDI_Reset(struct comedi_device *dev) +{ + const struct addi_board *this_board = comedi_board(dev); + + this_board->reset(dev); + return 0; +} + +static const void *addi_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) +{ + const void *p = dev->driver->board_name; + const struct addi_board *this_board; + int i; + + for (i = 0; i < dev->driver->num_names; i++) { + this_board = p; + if (this_board->i_VendorId == pcidev->vendor && + this_board->i_DeviceId == pcidev->device) + return this_board; + p += dev->driver->offset; + } + return NULL; +} + +static int __devinit apci1516_auto_attach(struct comedi_device *dev, + unsigned long context_unused) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + const struct addi_board *this_board; + struct addi_private *devpriv; + struct comedi_subdevice *s; + int ret, n_subdevices; + unsigned int dw_Dummy; + + this_board = addi_find_boardinfo(dev, pcidev); + if (!this_board) + return -ENODEV; + dev->board_ptr = this_board; + dev->board_name = this_board->pc_DriverName; + + devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); + if (!devpriv) + return -ENOMEM; + dev->private = devpriv; + + ret = comedi_pci_enable(pcidev, dev->board_name); + if (ret) + return ret; + + if (!this_board->pc_EepromChip || + strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { + /* board does not have an eeprom or is not ADDIDATA_9054 */ + if (this_board->i_IorangeBase1) + dev->iobase = pci_resource_start(pcidev, 1); + else + dev->iobase = pci_resource_start(pcidev, 0); + + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); + } else { + /* board has an ADDIDATA_9054 eeprom */ + dev->iobase = pci_resource_start(pcidev, 2); + devpriv->iobase = pci_resource_start(pcidev, 2); + devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), + this_board->i_IorangeBase3); + } + devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); + + /* Initialize parameters that can be overridden in EEPROM */ + devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; + devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; + devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; + devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; + devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; + devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; + devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; + devpriv->s_EeParameters.i_Dma = this_board->i_Dma; + devpriv->s_EeParameters.i_Timer = this_board->i_Timer; + devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = + this_board->ui_MinAcquisitiontimeNs; + devpriv->s_EeParameters.ui_MinDelaytimeNs = + this_board->ui_MinDelaytimeNs; + + /* ## */ + + if (pcidev->irq > 0) { + ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, + dev->board_name, dev); + if (ret == 0) + dev->irq = pcidev->irq; + } + + /* Read eepeom and fill addi_board Structure */ + + if (this_board->i_PCIEeprom) { + if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { + /* Set 3 wait stait */ + if (!(strcmp(dev->board_name, "apci035"))) { + outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); + } else { + outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); + } + /* Enable the interrupt for the controller */ + dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); + outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); + } + addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); + } + + n_subdevices = 7; + ret = comedi_alloc_subdevices(dev, n_subdevices); + if (ret) + return ret; + + /* Allocate and Initialise AI Subdevice Structures */ + s = &dev->subdevices[0]; + if ((devpriv->s_EeParameters.i_NbrAiChannel) + || (this_board->i_NbrAiChannelDiff)) { + dev->read_subdev = s; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = + SDF_READABLE | SDF_COMMON | SDF_GROUND + | SDF_DIFF; + if (devpriv->s_EeParameters.i_NbrAiChannel) { + s->n_chan = + devpriv->s_EeParameters.i_NbrAiChannel; + devpriv->b_SingelDiff = 0; + } else { + s->n_chan = this_board->i_NbrAiChannelDiff; + devpriv->b_SingelDiff = 1; + } + s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; + s->len_chanlist = this_board->i_AiChannelList; + s->range_table = this_board->pr_AiRangelist; + + /* Set the initialisation flag */ + devpriv->b_AiInitialisation = 1; + + s->insn_config = this_board->ai_config; + s->insn_read = this_board->ai_read; + s->insn_write = this_board->ai_write; + s->insn_bits = this_board->ai_bits; + s->do_cmdtest = this_board->ai_cmdtest; + s->do_cmd = this_board->ai_cmd; + s->cancel = this_board->ai_cancel; + + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise AO Subdevice Structures */ + s = &dev->subdevices[1]; + if (devpriv->s_EeParameters.i_NbrAoChannel) { + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; + s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrAoChannel; + s->range_table = this_board->pr_AoRangelist; + s->insn_config = this_board->ao_config; + s->insn_write = this_board->ao_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DI Subdevice Structures */ + s = &dev->subdevices[2]; + if (devpriv->s_EeParameters.i_NbrDiChannel) { + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; + s->maxdata = 1; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDiChannel; + s->range_table = &range_digital; + s->io_bits = 0; /* all bits input */ + s->insn_config = this_board->di_config; + s->insn_read = this_board->di_read; + s->insn_write = this_board->di_write; + s->insn_bits = this_board->di_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + /* Allocate and Initialise DO Subdevice Structures */ + s = &dev->subdevices[3]; + if (devpriv->s_EeParameters.i_NbrDoChannel) { + s->type = COMEDI_SUBD_DO; + s->subdev_flags = + SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; + s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; + s->len_chanlist = + devpriv->s_EeParameters.i_NbrDoChannel; + s->range_table = &range_digital; + s->io_bits = 0xf; /* all bits output */ + + /* insn_config - for digital output memory */ + s->insn_config = this_board->do_config; + s->insn_write = this_board->do_write; + s->insn_bits = this_board->do_bits; + s->insn_read = this_board->do_read; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise Timer Subdevice Structures */ + s = &dev->subdevices[4]; + if (devpriv->s_EeParameters.i_Timer) { + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = 1; + s->maxdata = 0; + s->len_chanlist = 1; + s->range_table = &range_digital; + + s->insn_write = this_board->timer_write; + s->insn_read = this_board->timer_read; + s->insn_config = this_board->timer_config; + s->insn_bits = this_board->timer_bits; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* Allocate and Initialise TTL */ + s = &dev->subdevices[5]; + if (this_board->i_NbrTTLChannel) { + s->type = COMEDI_SUBD_TTLIO; + s->subdev_flags = + SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->n_chan = this_board->i_NbrTTLChannel; + s->maxdata = 1; + s->io_bits = 0; /* all bits input */ + s->len_chanlist = this_board->i_NbrTTLChannel; + s->range_table = &range_digital; + s->insn_config = this_board->ttl_config; + s->insn_bits = this_board->ttl_bits; + s->insn_read = this_board->ttl_read; + s->insn_write = this_board->ttl_write; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + /* EEPROM */ + s = &dev->subdevices[6]; + if (this_board->i_PCIEeprom) { + s->type = COMEDI_SUBD_MEMORY; + s->subdev_flags = SDF_READABLE | SDF_INTERNAL; + s->n_chan = 256; + s->maxdata = 0xffff; + s->insn_read = i_ADDIDATA_InsnReadEeprom; + } else { + s->type = COMEDI_SUBD_UNUSED; + } + + i_ADDI_Reset(dev); + return 0; +} + +static void apci1516_detach(struct comedi_device *dev) +{ + struct pci_dev *pcidev = comedi_to_pci_dev(dev); + struct addi_private *devpriv = dev->private; + + if (devpriv) { + if (dev->iobase) + i_ADDI_Reset(dev); + if (dev->irq) + free_irq(dev->irq, dev); + if (devpriv->dw_AiBase) + iounmap(devpriv->dw_AiBase); + } + if (pcidev) { + if (dev->iobase) + comedi_pci_disable(pcidev); + } +} + static struct comedi_driver apci1516_driver = { .driver_name = "addi_apci_1516", .module = THIS_MODULE, - .auto_attach = addi_auto_attach, - .detach = i_ADDI_Detach, + .auto_attach = apci1516_auto_attach, + .detach = apci1516_detach, .num_names = ARRAY_SIZE(apci1516_boardtypes), .board_name = &apci1516_boardtypes[0].pc_DriverName, .offset = sizeof(struct addi_board), -- cgit v1.2.3 From c605605e84aa13d332b87b19eed6b38f52f49036 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:38:57 -0700 Subject: staging: comedi: addi_apci_1516: board does not have ttl i/o The boards supported by this driver do not have ttl i/o. Remove the subdevice init for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 4cf1f034917..cce0e64b364 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -314,22 +314,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, /* Allocate and Initialise TTL */ s = &dev->subdevices[5]; - if (this_board->i_NbrTTLChannel) { - s->type = COMEDI_SUBD_TTLIO; - s->subdev_flags = - SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrTTLChannel; - s->maxdata = 1; - s->io_bits = 0; /* all bits input */ - s->len_chanlist = this_board->i_NbrTTLChannel; - s->range_table = &range_digital; - s->insn_config = this_board->ttl_config; - s->insn_bits = this_board->ttl_bits; - s->insn_read = this_board->ttl_read; - s->insn_write = this_board->ttl_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; /* EEPROM */ s = &dev->subdevices[6]; -- cgit v1.2.3 From b0bfc2ad865d6adccec728a9dba398faeaba7679 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:39:14 -0700 Subject: staging: comedi: addi_apci_1516: board does not have analog inputs The boards supported by this driver do not have analog inputs. Remove the subdevice init for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 34 +------------------------ 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index cce0e64b364..b5f738947a1 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -205,39 +205,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, /* Allocate and Initialise AI Subdevice Structures */ s = &dev->subdevices[0]; - if ((devpriv->s_EeParameters.i_NbrAiChannel) - || (this_board->i_NbrAiChannelDiff)) { - dev->read_subdev = s; - s->type = COMEDI_SUBD_AI; - s->subdev_flags = - SDF_READABLE | SDF_COMMON | SDF_GROUND - | SDF_DIFF; - if (devpriv->s_EeParameters.i_NbrAiChannel) { - s->n_chan = - devpriv->s_EeParameters.i_NbrAiChannel; - devpriv->b_SingelDiff = 0; - } else { - s->n_chan = this_board->i_NbrAiChannelDiff; - devpriv->b_SingelDiff = 1; - } - s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; - s->len_chanlist = this_board->i_AiChannelList; - s->range_table = this_board->pr_AiRangelist; - - /* Set the initialisation flag */ - devpriv->b_AiInitialisation = 1; - - s->insn_config = this_board->ai_config; - s->insn_read = this_board->ai_read; - s->insn_write = this_board->ai_write; - s->insn_bits = this_board->ai_bits; - s->do_cmdtest = this_board->ai_cmdtest; - s->do_cmd = this_board->ai_cmd; - s->cancel = this_board->ai_cancel; - - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; /* Allocate and Initialise AO Subdevice Structures */ s = &dev->subdevices[1]; -- cgit v1.2.3 From aa459d0ccccb176da6028182115dd5f652dcca2f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:39:29 -0700 Subject: staging: comedi: addi_apci_1516: board does not have analog outputs The boards supported by this driver do not have analog outputs. Remove the subdevice init for it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index b5f738947a1..0c45a5b09e7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -209,19 +209,8 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, /* Allocate and Initialise AO Subdevice Structures */ s = &dev->subdevices[1]; - if (devpriv->s_EeParameters.i_NbrAoChannel) { - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; - s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrAoChannel; - s->range_table = this_board->pr_AoRangelist; - s->insn_config = this_board->ao_config; - s->insn_write = this_board->ao_write; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; + /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[2]; if (devpriv->s_EeParameters.i_NbrDiChannel) { -- cgit v1.2.3 From a899e56567f1d0e3eb1ceebd7233f1a5929e7b17 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:39:47 -0700 Subject: staging: comedi: addi_apci_1516: remove eeprom support code Reading the eeprom on the boards supported by this driver is not necessary. All the information required is in the boardinfo. Remove the eeprom support code since it's not really interesting or useful. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 46 +------------------------ 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 0c45a5b09e7..2be6c858c68 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -8,7 +8,6 @@ #define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ #endif -#include "addi-data/addi_eeprom.c" #include "addi-data/hwdrv_apci1516.c" static const struct addi_board apci1516_boardtypes[] = { @@ -61,23 +60,6 @@ static const struct addi_board apci1516_boardtypes[] = { }, }; -static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - const struct addi_board *this_board = comedi_board(dev); - struct addi_private *devpriv = dev->private; - unsigned short w_Address = CR_CHAN(insn->chanspec); - unsigned short w_Data; - - w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, - this_board->pc_EepromChip, 2 * w_Address); - data[0] = w_Data; - - return insn->n; -} - static irqreturn_t v_ADDI_Interrupt(int irq, void *d) { struct comedi_device *dev = d; @@ -120,7 +102,6 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, struct addi_private *devpriv; struct comedi_subdevice *s; int ret, n_subdevices; - unsigned int dw_Dummy; this_board = addi_find_boardinfo(dev, pcidev); if (!this_board) @@ -181,23 +162,6 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, dev->irq = pcidev->irq; } - /* Read eepeom and fill addi_board Structure */ - - if (this_board->i_PCIEeprom) { - if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { - /* Set 3 wait stait */ - if (!(strcmp(dev->board_name, "apci035"))) { - outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); - } else { - outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); - } - /* Enable the interrupt for the controller */ - dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); - outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - } - addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); - } - n_subdevices = 7; ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret) @@ -275,15 +239,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, /* EEPROM */ s = &dev->subdevices[6]; - if (this_board->i_PCIEeprom) { - s->type = COMEDI_SUBD_MEMORY; - s->subdev_flags = SDF_READABLE | SDF_INTERNAL; - s->n_chan = 256; - s->maxdata = 0xffff; - s->insn_read = i_ADDIDATA_InsnReadEeprom; - } else { - s->type = COMEDI_SUBD_UNUSED; - } + s->type = COMEDI_SUBD_UNUSED; i_ADDI_Reset(dev); return 0; -- cgit v1.2.3 From 485267c47db9449faea5785b6b34397ee82bc45b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:40:02 -0700 Subject: staging: comedi: addi_apci_1516: remove unused define The COMEDI_SUBD_TTLIO define is not used by this driver. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 2be6c858c68..b6e95f3ee7b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -4,10 +4,6 @@ #include "addi-data/addi_common.h" -#ifndef COMEDI_SUBD_TTLIO -#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */ -#endif - #include "addi-data/hwdrv_apci1516.c" static const struct addi_board apci1516_boardtypes[] = { -- cgit v1.2.3 From ece790f6cfd366536e39ac9446fc53c235ff96bf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:40:18 -0700 Subject: staging: comedi: addi_apci_1516: remove unnecessary include This include is not needed. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index b6e95f3ee7b..da60d144ba9 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -1,6 +1,5 @@ #include "../comedidev.h" #include "comedi_fc.h" -#include "amcc_s5933.h" #include "addi-data/addi_common.h" -- cgit v1.2.3 From 3b9323b43d0c0914a852be6ed991f2fb421cb1f2 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:40:34 -0700 Subject: staging: comedi: addi_apci_1516: absorb i_APCI1516_Reset() The same low-level reset function is used by all the boards supported by this driver. Remove it from the boardinfo and absorb the function from hwdrv_apci1516.c directly into the driver. Rename the CamelCase function i_ADDI_Reset() to apci1516_reset(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1516.c | 26 ---------------------- drivers/staging/comedi/drivers/addi_apci_1516.c | 17 +++++++------- 2 files changed, 9 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index a0d29be6726..9aa8298f5e5 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -229,29 +229,3 @@ static int i_APCI1516_ReadWatchdog(struct comedi_device *dev, data[0] = inw(devpriv->i_IobaseAddon + APCI1516_WDOG_STATUS_REG) & 0x1; return insn->n; } - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_Reset(struct comedi_device *dev) | | -+----------------------------------------------------------------------------+ -| Task :resets all the registers | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI1516_Reset(struct comedi_device *dev) -{ - struct addi_private *devpriv = dev->private; - - outw(0x0, devpriv->iobase + APCI1516_DO_REG); - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_RELOAD_LSB_REG); - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_RELOAD_MSB_REG); - return 0; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index da60d144ba9..c3e167d0430 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -16,7 +16,6 @@ static const struct addi_board apci1516_boardtypes[] = { .i_PCIEeprom = ADDIDATA_EEPROM, .pc_EepromChip = ADDIDATA_S5920, .i_NbrDiChannel = 16, - .reset = i_APCI1516_Reset, .di_bits = apci1516_di_insn_bits, }, { .pc_DriverName = "apci1516", @@ -30,7 +29,6 @@ static const struct addi_board apci1516_boardtypes[] = { .i_NbrDiChannel = 8, .i_NbrDoChannel = 8, .i_Timer = 1, - .reset = i_APCI1516_Reset, .di_bits = apci1516_di_insn_bits, .do_bits = apci1516_do_insn_bits, .timer_config = i_APCI1516_ConfigWatchdog, @@ -47,7 +45,6 @@ static const struct addi_board apci1516_boardtypes[] = { .pc_EepromChip = ADDIDATA_S5920, .i_NbrDoChannel = 16, .i_Timer = 1, - .reset = i_APCI1516_Reset, .do_bits = apci1516_do_insn_bits, .timer_config = i_APCI1516_ConfigWatchdog, .timer_write = i_APCI1516_StartStopWriteWatchdog, @@ -64,11 +61,15 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) return IRQ_RETVAL(1); } -static int i_ADDI_Reset(struct comedi_device *dev) +static int apci1516_reset(struct comedi_device *dev) { - const struct addi_board *this_board = comedi_board(dev); + struct addi_private *devpriv = dev->private; + + outw(0x0, devpriv->iobase + APCI1516_DO_REG); + outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); + outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_RELOAD_LSB_REG); + outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_RELOAD_MSB_REG); - this_board->reset(dev); return 0; } @@ -236,7 +237,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s = &dev->subdevices[6]; s->type = COMEDI_SUBD_UNUSED; - i_ADDI_Reset(dev); + apci1516_reset(dev); return 0; } @@ -247,7 +248,7 @@ static void apci1516_detach(struct comedi_device *dev) if (devpriv) { if (dev->iobase) - i_ADDI_Reset(dev); + apci1516_reset(dev); if (dev->irq) free_irq(dev->irq, dev); if (devpriv->dw_AiBase) -- cgit v1.2.3 From 722bf0f09f0931aab537400bee29f097ca218ba3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:40:50 -0700 Subject: staging: comedi: addi_apci_1516: don't reset the apci1016 board The apci1016 board only has digital inputs. There is no reason to reset the digital outputs and watchdog timer on that board. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index c3e167d0430..c1caeb1e525 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -63,8 +63,12 @@ static irqreturn_t v_ADDI_Interrupt(int irq, void *d) static int apci1516_reset(struct comedi_device *dev) { + const struct addi_board *this_board = comedi_board(dev); struct addi_private *devpriv = dev->private; + if (!this_board->i_Timer) + return 0; + outw(0x0, devpriv->iobase + APCI1516_DO_REG); outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_RELOAD_LSB_REG); -- cgit v1.2.3 From 8451a63216d6cfefa5f9fb89ab7eefd03fc57e33 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:41:06 -0700 Subject: staging: comedi: addi_apci_1516: boards do not have interrupts The boards supported by this driver do not have interrupt capabiltiy. Remove the interrupt support code. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index c1caeb1e525..d78174afdf2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -52,15 +52,6 @@ static const struct addi_board apci1516_boardtypes[] = { }, }; -static irqreturn_t v_ADDI_Interrupt(int irq, void *d) -{ - struct comedi_device *dev = d; - const struct addi_board *this_board = comedi_board(dev); - - this_board->interrupt(irq, d); - return IRQ_RETVAL(1); -} - static int apci1516_reset(struct comedi_device *dev) { const struct addi_board *this_board = comedi_board(dev); @@ -153,15 +144,6 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, devpriv->s_EeParameters.ui_MinDelaytimeNs = this_board->ui_MinDelaytimeNs; - /* ## */ - - if (pcidev->irq > 0) { - ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, - dev->board_name, dev); - if (ret == 0) - dev->irq = pcidev->irq; - } - n_subdevices = 7; ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret) @@ -253,8 +235,6 @@ static void apci1516_detach(struct comedi_device *dev) if (devpriv) { if (dev->iobase) apci1516_reset(dev); - if (dev->irq) - free_irq(dev->irq, dev); if (devpriv->dw_AiBase) iounmap(devpriv->dw_AiBase); } -- cgit v1.2.3 From 56587a06ade1f95f1425cc5fb2230fb54e82428f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:41:22 -0700 Subject: staging: comedi: addi_apci_1516: cleanup subdevice ops pointers The same subdevice operations are used, as needed, for all the boards supported by this driver. Remove the function pointers from the boardinfo and set the subdevice operations directly in the attach. Remove all the subdevice operations that would be set to NULL. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 30 +++++-------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index d78174afdf2..8fc848b021b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -16,7 +16,6 @@ static const struct addi_board apci1516_boardtypes[] = { .i_PCIEeprom = ADDIDATA_EEPROM, .pc_EepromChip = ADDIDATA_S5920, .i_NbrDiChannel = 16, - .di_bits = apci1516_di_insn_bits, }, { .pc_DriverName = "apci1516", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -29,11 +28,6 @@ static const struct addi_board apci1516_boardtypes[] = { .i_NbrDiChannel = 8, .i_NbrDoChannel = 8, .i_Timer = 1, - .di_bits = apci1516_di_insn_bits, - .do_bits = apci1516_do_insn_bits, - .timer_config = i_APCI1516_ConfigWatchdog, - .timer_write = i_APCI1516_StartStopWriteWatchdog, - .timer_read = i_APCI1516_ReadWatchdog, }, { .pc_DriverName = "apci2016", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, @@ -45,10 +39,6 @@ static const struct addi_board apci1516_boardtypes[] = { .pc_EepromChip = ADDIDATA_S5920, .i_NbrDoChannel = 16, .i_Timer = 1, - .do_bits = apci1516_do_insn_bits, - .timer_config = i_APCI1516_ConfigWatchdog, - .timer_write = i_APCI1516_StartStopWriteWatchdog, - .timer_read = i_APCI1516_ReadWatchdog, }, }; @@ -168,10 +158,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, devpriv->s_EeParameters.i_NbrDiChannel; s->range_table = &range_digital; s->io_bits = 0; /* all bits input */ - s->insn_config = this_board->di_config; - s->insn_read = this_board->di_read; - s->insn_write = this_board->di_write; - s->insn_bits = this_board->di_bits; + s->insn_bits = apci1516_di_insn_bits; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -187,12 +174,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, devpriv->s_EeParameters.i_NbrDoChannel; s->range_table = &range_digital; s->io_bits = 0xf; /* all bits output */ - - /* insn_config - for digital output memory */ - s->insn_config = this_board->do_config; - s->insn_write = this_board->do_write; - s->insn_bits = this_board->do_bits; - s->insn_read = this_board->do_read; + s->insn_bits = apci1516_do_insn_bits; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -206,11 +188,9 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s->maxdata = 0; s->len_chanlist = 1; s->range_table = &range_digital; - - s->insn_write = this_board->timer_write; - s->insn_read = this_board->timer_read; - s->insn_config = this_board->timer_config; - s->insn_bits = this_board->timer_bits; + s->insn_write = i_APCI1516_StartStopWriteWatchdog; + s->insn_read = i_APCI1516_ReadWatchdog; + s->insn_config = i_APCI1516_ConfigWatchdog; } else { s->type = COMEDI_SUBD_UNUSED; } -- cgit v1.2.3 From a3003b41331c83b0be7c46126ed4f03cc22bee05 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:41:41 -0700 Subject: staging: comedi: addi_apci_1516: simplify the PCI bar reading The boards supported by this driver have an eeprom attached to a S5920 PCI controller chip. Knowing this information allows simplifying the code that reads the PCI bars to get the iobase address. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 8fc848b021b..5d114864b85 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -99,24 +99,10 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, if (ret) return ret; - if (!this_board->pc_EepromChip || - strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) { - /* board does not have an eeprom or is not ADDIDATA_9054 */ - if (this_board->i_IorangeBase1) - dev->iobase = pci_resource_start(pcidev, 1); - else - dev->iobase = pci_resource_start(pcidev, 0); - - devpriv->iobase = dev->iobase; - devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); - devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - } else { - /* board has an ADDIDATA_9054 eeprom */ - dev->iobase = pci_resource_start(pcidev, 2); - devpriv->iobase = pci_resource_start(pcidev, 2); - devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3), - this_board->i_IorangeBase3); - } + dev->iobase = pci_resource_start(pcidev, 1); + devpriv->iobase = dev->iobase; + devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); + devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); /* Initialize parameters that can be overridden in EEPROM */ -- cgit v1.2.3 From 82c2bc7f50cf587da788c5c90891f5028f6aae9f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:41:57 -0700 Subject: staging: comedi: addi_apci_1516: remove unnecessary info from boardinfo The i_IorangeBase[012], i_PCIEeprom, and pc_EepromChip data in the boardinfo was only needed to work out the usage of the PCI bars. This is no longer needed so remove the data. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 5d114864b85..6c61f3dc5cb 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -10,21 +10,11 @@ static const struct addi_board apci1516_boardtypes[] = { .pc_DriverName = "apci1016", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x1000, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = APCI1516_ADDRESS_RANGE, - .i_IorangeBase2 = 32, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, .i_NbrDiChannel = 16, }, { .pc_DriverName = "apci1516", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x1001, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = APCI1516_ADDRESS_RANGE, - .i_IorangeBase2 = 32, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, .i_NbrDiChannel = 8, .i_NbrDoChannel = 8, .i_Timer = 1, @@ -32,11 +22,6 @@ static const struct addi_board apci1516_boardtypes[] = { .pc_DriverName = "apci2016", .i_VendorId = PCI_VENDOR_ID_ADDIDATA, .i_DeviceId = 0x1002, - .i_IorangeBase0 = 128, - .i_IorangeBase1 = APCI1516_ADDRESS_RANGE, - .i_IorangeBase2 = 32, - .i_PCIEeprom = ADDIDATA_EEPROM, - .pc_EepromChip = ADDIDATA_S5920, .i_NbrDoChannel = 16, .i_Timer = 1, }, -- cgit v1.2.3 From d330b1da10a2bd0f71c2aa7f9e209b8d06d45901 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:42:15 -0700 Subject: staging: comedi: addi_apci_1516: remove devpriv->iobase usage The iobase address stored in devpriv->iobase is also stored in dev->iobase. Use that instead. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c | 10 +++------- drivers/staging/comedi/drivers/addi_apci_1516.c | 3 +-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index 9aa8298f5e5..0658fe9b45e 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -75,9 +75,7 @@ static int apci1516_di_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; - - data[1] = inw(devpriv->iobase + APCI1516_DI_REG); + data[1] = inw(dev->iobase + APCI1516_DI_REG); return insn->n; } @@ -87,17 +85,15 @@ static int apci1516_do_insn_bits(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - - struct addi_private *devpriv = dev->private; unsigned int mask = data[0]; unsigned int bits = data[1]; - s->state = inw(devpriv->iobase + APCI1516_DO_REG); + s->state = inw(dev->iobase + APCI1516_DO_REG); if (mask) { s->state &= ~mask; s->state |= (bits & mask); - outw(s->state, devpriv->iobase + APCI1516_DO_REG); + outw(s->state, dev->iobase + APCI1516_DO_REG); } data[1] = s->state; diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 6c61f3dc5cb..dabf44c7360 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -35,7 +35,7 @@ static int apci1516_reset(struct comedi_device *dev) if (!this_board->i_Timer) return 0; - outw(0x0, devpriv->iobase + APCI1516_DO_REG); + outw(0x0, dev->iobase + APCI1516_DO_REG); outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_RELOAD_LSB_REG); outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_RELOAD_MSB_REG); @@ -85,7 +85,6 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, return ret; dev->iobase = pci_resource_start(pcidev, 1); - devpriv->iobase = dev->iobase; devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); -- cgit v1.2.3 From 4bcf9593b46c1fe3b952ae541dec45a810d0debd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:42:38 -0700 Subject: staging: comedi: addi_apci_1516: remove devpriv->dw_AiBase This driver does not ioremap the PCI bar stored in devpriv->dw_AiBase. Remove the iounmap. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index dabf44c7360..941ed608cc6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -180,14 +180,9 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, static void apci1516_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - struct addi_private *devpriv = dev->private; - if (devpriv) { - if (dev->iobase) - apci1516_reset(dev); - if (devpriv->dw_AiBase) - iounmap(devpriv->dw_AiBase); - } + if (dev->iobase) + apci1516_reset(dev); if (pcidev) { if (dev->iobase) comedi_pci_disable(pcidev); -- cgit v1.2.3 From 308632e8490e97b98f6a7ba0aa15e10ba4224e68 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:42:54 -0700 Subject: staging: comedi: addi_apci_1516: don't read the unused PCI bars This driver does use devpriv->i_IobaseAmcc or devpriv->i_IobaseReserved. Don't bother reading these PCI bars. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 941ed608cc6..f4ccfc6f19f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -85,9 +85,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, return ret; dev->iobase = pci_resource_start(pcidev, 1); - devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); /* Initialize parameters that can be overridden in EEPROM */ devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; -- cgit v1.2.3 From 321ab8a09fc08aac07286707071bdbd614d37bfc Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:43:10 -0700 Subject: staging: comedi: addi_apci_1516: remove use of devpriv->s_EeParameters This driver no longer reads the eeprom to find the board specific data, all the necessary data is in the boardinfo. Use the boardinfo directly instead of passing through devpriv->s_EeParameters. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 33 ++++++------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index f4ccfc6f19f..1bb059fe025 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -87,21 +87,6 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, dev->iobase = pci_resource_start(pcidev, 1); devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - /* Initialize parameters that can be overridden in EEPROM */ - devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; - devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; - devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; - devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; - devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; - devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; - devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; - devpriv->s_EeParameters.i_Dma = this_board->i_Dma; - devpriv->s_EeParameters.i_Timer = this_board->i_Timer; - devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = - this_board->ui_MinAcquisitiontimeNs; - devpriv->s_EeParameters.ui_MinDelaytimeNs = - this_board->ui_MinDelaytimeNs; - n_subdevices = 7; ret = comedi_alloc_subdevices(dev, n_subdevices); if (ret) @@ -117,13 +102,12 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[2]; - if (devpriv->s_EeParameters.i_NbrDiChannel) { + if (this_board->i_NbrDiChannel) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; + s->n_chan = this_board->i_NbrDiChannel; s->maxdata = 1; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDiChannel; + s->len_chanlist = this_board->i_NbrDiChannel; s->range_table = &range_digital; s->io_bits = 0; /* all bits input */ s->insn_bits = apci1516_di_insn_bits; @@ -132,14 +116,13 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, } /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[3]; - if (devpriv->s_EeParameters.i_NbrDoChannel) { + if (this_board->i_NbrDoChannel) { s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; - s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; - s->len_chanlist = - devpriv->s_EeParameters.i_NbrDoChannel; + s->n_chan = this_board->i_NbrDoChannel; + s->maxdata = 1; + s->len_chanlist = this_board->i_NbrDoChannel; s->range_table = &range_digital; s->io_bits = 0xf; /* all bits output */ s->insn_bits = apci1516_do_insn_bits; @@ -149,7 +132,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[4]; - if (devpriv->s_EeParameters.i_Timer) { + if (this_board->i_Timer) { s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 1; -- cgit v1.2.3 From 005ce48e86f610b1a41e3ed527e42b0788e0639c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:43:27 -0700 Subject: staging: comedi: addi_apci_1516: only allocate needed subdevices The addi-data "common" code always allocated 7 subdevices. This driver only requires 3. Change the allocation and remove the unused subdevices. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 27 +++++-------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 1bb059fe025..1423e1345c7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -67,7 +67,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, const struct addi_board *this_board; struct addi_private *devpriv; struct comedi_subdevice *s; - int ret, n_subdevices; + int ret; this_board = addi_find_boardinfo(dev, pcidev); if (!this_board) @@ -87,21 +87,12 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, dev->iobase = pci_resource_start(pcidev, 1); devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); - n_subdevices = 7; - ret = comedi_alloc_subdevices(dev, n_subdevices); + ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; - /* Allocate and Initialise AI Subdevice Structures */ - s = &dev->subdevices[0]; - s->type = COMEDI_SUBD_UNUSED; - - /* Allocate and Initialise AO Subdevice Structures */ - s = &dev->subdevices[1]; - s->type = COMEDI_SUBD_UNUSED; - /* Allocate and Initialise DI Subdevice Structures */ - s = &dev->subdevices[2]; + s = &dev->subdevices[0]; if (this_board->i_NbrDiChannel) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; @@ -115,7 +106,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } /* Allocate and Initialise DO Subdevice Structures */ - s = &dev->subdevices[3]; + s = &dev->subdevices[1]; if (this_board->i_NbrDoChannel) { s->type = COMEDI_SUBD_DO; s->subdev_flags = @@ -131,7 +122,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, } /* Allocate and Initialise Timer Subdevice Structures */ - s = &dev->subdevices[4]; + s = &dev->subdevices[2]; if (this_board->i_Timer) { s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; @@ -146,14 +137,6 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - /* Allocate and Initialise TTL */ - s = &dev->subdevices[5]; - s->type = COMEDI_SUBD_UNUSED; - - /* EEPROM */ - s = &dev->subdevices[6]; - s->type = COMEDI_SUBD_UNUSED; - apci1516_reset(dev); return 0; } -- cgit v1.2.3 From a29cd0eedf30779675d6a1a678da1ff55d681494 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:43:44 -0700 Subject: staging: comedi: addi_apci_1516: remove use of struct addi_private The only private data this driver has is the iobase address for the watchdog. Create a local struct to hold this information in dev->private and remove the need for struct addi_private from the "common" code. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1516.c | 20 ++++++++++---------- drivers/staging/comedi/drivers/addi_apci_1516.c | 16 ++++++++++------ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index 0658fe9b45e..1aa0be3271d 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -127,16 +127,16 @@ static int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1516_private *devpriv = dev->private; if (data[0] == 0) { /* Disable the watchdog */ - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); + outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); /* Loading the Reload value */ - outw(data[1], devpriv->i_IobaseAddon + + outw(data[1], devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_LSB_REG); data[1] = data[1] >> 16; - outw(data[1], devpriv->i_IobaseAddon + + outw(data[1], devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_MSB_REG); } /* if(data[0]==0) */ else { @@ -173,19 +173,19 @@ static int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1516_private *devpriv = dev->private; switch (data[0]) { case 0: /* stop the watchdog */ - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); + outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); break; case 1: /* start the watchdog */ outw(APCI1516_WDOG_CTRL_ENABLE, - devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); + devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); break; case 2: /* Software trigger */ outw(APCI1516_WDOG_CTRL_ENABLE | APCI1516_WDOG_CTRL_SOFT_TRIG, - devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); + devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); break; default: printk("\nSpecified functionality does not exist\n"); @@ -220,8 +220,8 @@ static int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - struct addi_private *devpriv = dev->private; + struct apci1516_private *devpriv = dev->private; - data[0] = inw(devpriv->i_IobaseAddon + APCI1516_WDOG_STATUS_REG) & 0x1; + data[0] = inw(devpriv->wdog_iobase + APCI1516_WDOG_STATUS_REG) & 0x1; return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 1423e1345c7..b56fa6ecb28 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -3,6 +3,10 @@ #include "addi-data/addi_common.h" +struct apci1516_private { + unsigned long wdog_iobase; +}; + #include "addi-data/hwdrv_apci1516.c" static const struct addi_board apci1516_boardtypes[] = { @@ -30,15 +34,15 @@ static const struct addi_board apci1516_boardtypes[] = { static int apci1516_reset(struct comedi_device *dev) { const struct addi_board *this_board = comedi_board(dev); - struct addi_private *devpriv = dev->private; + struct apci1516_private *devpriv = dev->private; if (!this_board->i_Timer) return 0; outw(0x0, dev->iobase + APCI1516_DO_REG); - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_CTRL_REG); - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_RELOAD_LSB_REG); - outw(0x0, devpriv->i_IobaseAddon + APCI1516_WDOG_RELOAD_MSB_REG); + outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); + outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_LSB_REG); + outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_MSB_REG); return 0; } @@ -65,7 +69,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, { struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct addi_board *this_board; - struct addi_private *devpriv; + struct apci1516_private *devpriv; struct comedi_subdevice *s; int ret; @@ -85,7 +89,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, return ret; dev->iobase = pci_resource_start(pcidev, 1); - devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); + devpriv->wdog_iobase = pci_resource_start(pcidev, 2); ret = comedi_alloc_subdevices(dev, 3); if (ret) -- cgit v1.2.3 From e195bf803f8964ab19826e90a0b61a25e543d874 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:44:02 -0700 Subject: staging: comedi: addi_apci_1516: remove use of struct addi_board The only boardinfo needed in this driver only consists of 6 data values. The "common" addi_board has a lot of unnecessary bloat. Create a local struct for this drivers boardinfo and remove the need for struct addi_board in the "common" code. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 73 ++++++++++++++----------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index b56fa6ecb28..c2e4b3a9e99 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -9,34 +9,43 @@ struct apci1516_private { #include "addi-data/hwdrv_apci1516.c" -static const struct addi_board apci1516_boardtypes[] = { +struct apci1516_boardinfo { + const char *name; + unsigned short vendor; + unsigned short device; + int di_nchan; + int do_nchan; + int has_timer; +}; + +static const struct apci1516_boardinfo apci1516_boardtypes[] = { { - .pc_DriverName = "apci1016", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1000, - .i_NbrDiChannel = 16, + .name = "apci1016", + .vendor = PCI_VENDOR_ID_ADDIDATA, + .device = 0x1000, + .di_nchan = 16, }, { - .pc_DriverName = "apci1516", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1001, - .i_NbrDiChannel = 8, - .i_NbrDoChannel = 8, - .i_Timer = 1, + .name = "apci1516", + .vendor = PCI_VENDOR_ID_ADDIDATA, + .device = 0x1001, + .di_nchan = 8, + .do_nchan = 8, + .has_timer = 1, }, { - .pc_DriverName = "apci2016", - .i_VendorId = PCI_VENDOR_ID_ADDIDATA, - .i_DeviceId = 0x1002, - .i_NbrDoChannel = 16, - .i_Timer = 1, + .name = "apci2016", + .vendor = PCI_VENDOR_ID_ADDIDATA, + .device = 0x1002, + .do_nchan = 16, + .has_timer = 1, }, }; static int apci1516_reset(struct comedi_device *dev) { - const struct addi_board *this_board = comedi_board(dev); + const struct apci1516_boardinfo *this_board = comedi_board(dev); struct apci1516_private *devpriv = dev->private; - if (!this_board->i_Timer) + if (!this_board->has_timer) return 0; outw(0x0, dev->iobase + APCI1516_DO_REG); @@ -51,13 +60,13 @@ static const void *addi_find_boardinfo(struct comedi_device *dev, struct pci_dev *pcidev) { const void *p = dev->driver->board_name; - const struct addi_board *this_board; + const struct apci1516_boardinfo *this_board; int i; for (i = 0; i < dev->driver->num_names; i++) { this_board = p; - if (this_board->i_VendorId == pcidev->vendor && - this_board->i_DeviceId == pcidev->device) + if (this_board->vendor == pcidev->vendor && + this_board->device == pcidev->device) return this_board; p += dev->driver->offset; } @@ -68,7 +77,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - const struct addi_board *this_board; + const struct apci1516_boardinfo *this_board; struct apci1516_private *devpriv; struct comedi_subdevice *s; int ret; @@ -77,7 +86,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, if (!this_board) return -ENODEV; dev->board_ptr = this_board; - dev->board_name = this_board->pc_DriverName; + dev->board_name = this_board->name; devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) @@ -97,12 +106,12 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[0]; - if (this_board->i_NbrDiChannel) { + if (this_board->di_nchan) { s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrDiChannel; + s->n_chan = this_board->di_nchan; s->maxdata = 1; - s->len_chanlist = this_board->i_NbrDiChannel; + s->len_chanlist = this_board->di_nchan; s->range_table = &range_digital; s->io_bits = 0; /* all bits input */ s->insn_bits = apci1516_di_insn_bits; @@ -111,13 +120,13 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, } /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[1]; - if (this_board->i_NbrDoChannel) { + if (this_board->do_nchan) { s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; - s->n_chan = this_board->i_NbrDoChannel; + s->n_chan = this_board->do_nchan; s->maxdata = 1; - s->len_chanlist = this_board->i_NbrDoChannel; + s->len_chanlist = this_board->do_nchan; s->range_table = &range_digital; s->io_bits = 0xf; /* all bits output */ s->insn_bits = apci1516_do_insn_bits; @@ -127,7 +136,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[2]; - if (this_board->i_Timer) { + if (this_board->has_timer) { s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 1; @@ -163,8 +172,8 @@ static struct comedi_driver apci1516_driver = { .auto_attach = apci1516_auto_attach, .detach = apci1516_detach, .num_names = ARRAY_SIZE(apci1516_boardtypes), - .board_name = &apci1516_boardtypes[0].pc_DriverName, - .offset = sizeof(struct addi_board), + .board_name = &apci1516_boardtypes[0].name, + .offset = sizeof(struct apci1516_boardinfo), }; static int __devinit apci1516_pci_probe(struct pci_dev *dev, -- cgit v1.2.3 From ed168d0a20f4b8e666e188ff43b2663099cd4b01 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:44:19 -0700 Subject: staging: comedi: addi_apci_1516: remove unnecessary include This driver no longer depends on the addi-data "common" code. Remove the include. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index c2e4b3a9e99..36ae5cda389 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -1,8 +1,6 @@ #include "../comedidev.h" #include "comedi_fc.h" -#include "addi-data/addi_common.h" - struct apci1516_private { unsigned long wdog_iobase; }; -- cgit v1.2.3 From e32a32c9098c745048e28c2851ac356763d3bbba Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:44:36 -0700 Subject: staging: comedi: addi_apci_1516: cleanup addi_find_boardinfo() This driver uses the comedi auto_config mechanism to attach to the PCI board. This mechanism does not require passing the boardinfo data in the comedi_driver. Remove it and modify the code to directly access the boardinfo data instead of messing with the dev->driver->board_name pointer. All the boards supported by this driver have the same PCI vendor id. Remove this extra info from the boardinfo and the test for it. Rename the function so it has namespace associated with this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 36ae5cda389..e2d79c3b2d9 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -9,7 +9,6 @@ struct apci1516_private { struct apci1516_boardinfo { const char *name; - unsigned short vendor; unsigned short device; int di_nchan; int do_nchan; @@ -19,19 +18,16 @@ struct apci1516_boardinfo { static const struct apci1516_boardinfo apci1516_boardtypes[] = { { .name = "apci1016", - .vendor = PCI_VENDOR_ID_ADDIDATA, .device = 0x1000, .di_nchan = 16, }, { .name = "apci1516", - .vendor = PCI_VENDOR_ID_ADDIDATA, .device = 0x1001, .di_nchan = 8, .do_nchan = 8, .has_timer = 1, }, { .name = "apci2016", - .vendor = PCI_VENDOR_ID_ADDIDATA, .device = 0x1002, .do_nchan = 16, .has_timer = 1, @@ -54,19 +50,16 @@ static int apci1516_reset(struct comedi_device *dev) return 0; } -static const void *addi_find_boardinfo(struct comedi_device *dev, - struct pci_dev *pcidev) +static const void *apci1516_find_boardinfo(struct comedi_device *dev, + struct pci_dev *pcidev) { - const void *p = dev->driver->board_name; const struct apci1516_boardinfo *this_board; int i; for (i = 0; i < dev->driver->num_names; i++) { - this_board = p; - if (this_board->vendor == pcidev->vendor && - this_board->device == pcidev->device) + this_board = &apci1516_boardtypes[i]; + if (this_board->device == pcidev->device) return this_board; - p += dev->driver->offset; } return NULL; } @@ -80,7 +73,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - this_board = addi_find_boardinfo(dev, pcidev); + this_board = apci1516_find_boardinfo(dev, pcidev); if (!this_board) return -ENODEV; dev->board_ptr = this_board; @@ -169,9 +162,6 @@ static struct comedi_driver apci1516_driver = { .module = THIS_MODULE, .auto_attach = apci1516_auto_attach, .detach = apci1516_detach, - .num_names = ARRAY_SIZE(apci1516_boardtypes), - .board_name = &apci1516_boardtypes[0].name, - .offset = sizeof(struct apci1516_boardinfo), }; static int __devinit apci1516_pci_probe(struct pci_dev *dev, -- cgit v1.2.3 From 87450c0271dd9da9242b13fa3ecade3af3d31eb9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:44:53 -0700 Subject: staging: comedi: addi_apci_1516: merge in hwdrv_apci1516.c Merge the code from hwdrv_apci1516.c into the driver and delete the now unused file. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1516.c | 227 --------------------- drivers/staging/comedi/drivers/addi_apci_1516.c | 147 ++++++++++++- 2 files changed, 143 insertions(+), 231 deletions(-) delete mode 100644 drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c deleted file mode 100644 index 1aa0be3271d..00000000000 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ /dev/null @@ -1,227 +0,0 @@ -/** -@verbatim - -Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. - - ADDI-DATA GmbH - Dieselstrasse 3 - D-77833 Ottersweier - Tel: +19(0)7223/9493-0 - Fax: +49(0)7223/9493-92 - http://www.addi-data.com - info@addi-data.com - -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. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -You should also find the complete GPL in the COPYING file accompanying this source code. - -@endverbatim -*/ -/* - - +-----------------------------------------------------------------------+ - | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | - +-----------------------------------------------------------------------+ - | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | - | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | - +-------------------------------+---------------------------------------+ - | Project : APCI-1516 | Compiler : GCC | - | Module name : hwdrv_apci1516.c| Version : 2.96 | - +-------------------------------+---------------------------------------+ - | Project manager: Eric Stolz | Date : 02/12/2002 | - +-------------------------------+---------------------------------------+ - | Description : Hardware Layer Access For APCI-1516 | - +-----------------------------------------------------------------------+ - | UPDATES | - +----------+-----------+------------------------------------------------+ - | Date | Author | Description of updates | - +----------+-----------+------------------------------------------------+ - | | | | - | | | | - | | | | - +----------+-----------+------------------------------------------------+ -*/ - -/********* Definitions for APCI-1516 card *****/ - -/* Card Specific information */ -#define APCI1516_ADDRESS_RANGE 8 - -/* - * PCI bar 1 I/O Register map - */ -#define APCI1516_DI_REG 0x00 -#define APCI1516_DO_REG 0x04 - -/* - * PCI bar 2 I/O Register map - */ -#define APCI1516_WDOG_REG 0x00 -#define APCI1516_WDOG_RELOAD_LSB_REG 0x04 -#define APCI1516_WDOG_RELOAD_MSB_REG 0x06 -#define APCI1516_WDOG_CTRL_REG 0x0c -#define APCI1516_WDOG_CTRL_ENABLE (1 << 0) -#define APCI1516_WDOG_CTRL_SOFT_TRIG (1 << 9) -#define APCI1516_WDOG_STATUS_REG 0x10 - -#define ADDIDATA_WATCHDOG 2 - -static int apci1516_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - data[1] = inw(dev->iobase + APCI1516_DI_REG); - - return insn->n; -} - -static int apci1516_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - unsigned int mask = data[0]; - unsigned int bits = data[1]; - - s->state = inw(dev->iobase + APCI1516_DO_REG); - if (mask) { - s->state &= ~mask; - s->state |= (bits & mask); - - outw(s->state, dev->iobase + APCI1516_DO_REG); - } - - data[1] = s->state; - - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, -| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) | -| | -+----------------------------------------------------------------------------+ -| Task : Configures The Watchdog | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure -| struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci1516_private *devpriv = dev->private; - - if (data[0] == 0) { - /* Disable the watchdog */ - outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); - /* Loading the Reload value */ - outw(data[1], devpriv->wdog_iobase + - APCI1516_WDOG_RELOAD_LSB_REG); - data[1] = data[1] >> 16; - outw(data[1], devpriv->wdog_iobase + - APCI1516_WDOG_RELOAD_MSB_REG); - } /* if(data[0]==0) */ - else { - printk("\nThe input parameters are wrong\n"); - return -EINVAL; - } /* elseif(data[0]==0) */ - - return insn->n; -} - - /* - +----------------------------------------------------------------------------+ - | Function Name : int i_APCI1516_StartStopWriteWatchdog | - | (struct comedi_device *dev,struct comedi_subdevice *s, - struct comedi_insn *insn,unsigned int *data); | - +----------------------------------------------------------------------------+ - | Task : Start / Stop The Watchdog | - +----------------------------------------------------------------------------+ - | Input Parameters : struct comedi_device *dev : Driver handle | - | struct comedi_subdevice *s, :pointer to subdevice structure - struct comedi_insn *insn :pointer to insn structure | - | unsigned int *data : Data Pointer to read status | - +----------------------------------------------------------------------------+ - | Output Parameters : -- | - +----------------------------------------------------------------------------+ - | Return Value : TRUE : No error occur | - | : FALSE : Error occur. Return the error | - | | - +----------------------------------------------------------------------------+ - */ - -static int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci1516_private *devpriv = dev->private; - - switch (data[0]) { - case 0: /* stop the watchdog */ - outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); - break; - case 1: /* start the watchdog */ - outw(APCI1516_WDOG_CTRL_ENABLE, - devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); - break; - case 2: /* Software trigger */ - outw(APCI1516_WDOG_CTRL_ENABLE | APCI1516_WDOG_CTRL_SOFT_TRIG, - devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); - break; - default: - printk("\nSpecified functionality does not exist\n"); - return -EINVAL; - } /* switch(data[0]) */ - return insn->n; -} - -/* -+----------------------------------------------------------------------------+ -| Function Name : int i_APCI1516_ReadWatchdog | -| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, - unsigned int *data); | -+----------------------------------------------------------------------------+ -| Task : Read The Watchdog | -+----------------------------------------------------------------------------+ -| Input Parameters : struct comedi_device *dev : Driver handle | -| struct comedi_subdevice *s, :pointer to subdevice structure - struct comedi_insn *insn :pointer to insn structure | -| unsigned int *data : Data Pointer to read status | -+----------------------------------------------------------------------------+ -| Output Parameters : -- | -+----------------------------------------------------------------------------+ -| Return Value : TRUE : No error occur | -| : FALSE : Error occur. Return the error | -| | -+----------------------------------------------------------------------------+ -*/ - -static int i_APCI1516_ReadWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci1516_private *devpriv = dev->private; - - data[0] = inw(devpriv->wdog_iobase + APCI1516_WDOG_STATUS_REG) & 0x1; - return insn->n; -} diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index e2d79c3b2d9..d39278dac5a 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -1,11 +1,53 @@ +/* + * addi_apci_1516.c + * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. + * Project manager: Eric Stolz + * + * ADDI-DATA GmbH + * Dieselstrasse 3 + * D-77833 Ottersweier + * Tel: +19(0)7223/9493-0 + * Fax: +49(0)7223/9493-92 + * http://www.addi-data.com + * info@addi-data.com + * + * 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. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * You should also find the complete GPL in the COPYING file accompanying + * this source code. + */ + #include "../comedidev.h" #include "comedi_fc.h" -struct apci1516_private { - unsigned long wdog_iobase; -}; +/* + * PCI bar 1 I/O Register map + */ +#define APCI1516_DI_REG 0x00 +#define APCI1516_DO_REG 0x04 -#include "addi-data/hwdrv_apci1516.c" +/* + * PCI bar 2 I/O Register map + */ +#define APCI1516_WDOG_REG 0x00 +#define APCI1516_WDOG_RELOAD_LSB_REG 0x04 +#define APCI1516_WDOG_RELOAD_MSB_REG 0x06 +#define APCI1516_WDOG_CTRL_REG 0x0c +#define APCI1516_WDOG_CTRL_ENABLE (1 << 0) +#define APCI1516_WDOG_CTRL_SOFT_TRIG (1 << 9) +#define APCI1516_WDOG_STATUS_REG 0x10 struct apci1516_boardinfo { const char *name; @@ -34,6 +76,103 @@ static const struct apci1516_boardinfo apci1516_boardtypes[] = { }, }; +struct apci1516_private { + unsigned long wdog_iobase; +}; + +static int apci1516_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + data[1] = inw(dev->iobase + APCI1516_DI_REG); + + return insn->n; +} + +static int apci1516_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int mask = data[0]; + unsigned int bits = data[1]; + + s->state = inw(dev->iobase + APCI1516_DO_REG); + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); + + outw(s->state, dev->iobase + APCI1516_DO_REG); + } + + data[1] = s->state; + + return insn->n; +} + +static int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci1516_private *devpriv = dev->private; + + if (data[0] == 0) { + /* Disable the watchdog */ + outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); + /* Loading the Reload value */ + outw(data[1], devpriv->wdog_iobase + + APCI1516_WDOG_RELOAD_LSB_REG); + data[1] = data[1] >> 16; + outw(data[1], devpriv->wdog_iobase + + APCI1516_WDOG_RELOAD_MSB_REG); + } /* if(data[0]==0) */ + else { + printk("\nThe input parameters are wrong\n"); + return -EINVAL; + } /* elseif(data[0]==0) */ + + return insn->n; +} + +static int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci1516_private *devpriv = dev->private; + + switch (data[0]) { + case 0: /* stop the watchdog */ + outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); + break; + case 1: /* start the watchdog */ + outw(APCI1516_WDOG_CTRL_ENABLE, + devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); + break; + case 2: /* Software trigger */ + outw(APCI1516_WDOG_CTRL_ENABLE | APCI1516_WDOG_CTRL_SOFT_TRIG, + devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); + break; + default: + printk("\nSpecified functionality does not exist\n"); + return -EINVAL; + } /* switch(data[0]) */ + return insn->n; +} + +static int i_APCI1516_ReadWatchdog(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + struct apci1516_private *devpriv = dev->private; + + data[0] = inw(devpriv->wdog_iobase + APCI1516_WDOG_STATUS_REG) & 0x1; + return insn->n; +} + static int apci1516_reset(struct comedi_device *dev) { const struct apci1516_boardinfo *this_board = comedi_board(dev); -- cgit v1.2.3 From 308d703ba48ab7f2e16d744d3b8751ab5998ab9e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:45:08 -0700 Subject: staging: comedi: addi_apci_1516: remove setting of s->len_chanlist This value only has meaning for subdevices that support async commands. Since this driver does not support async commands on any of its subdevices, don't bother setting it . The comedi core will detect this and set the value appropriately. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index d39278dac5a..415b347ac7e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -241,7 +241,6 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; s->n_chan = this_board->di_nchan; s->maxdata = 1; - s->len_chanlist = this_board->di_nchan; s->range_table = &range_digital; s->io_bits = 0; /* all bits input */ s->insn_bits = apci1516_di_insn_bits; @@ -256,7 +255,6 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; s->n_chan = this_board->do_nchan; s->maxdata = 1; - s->len_chanlist = this_board->do_nchan; s->range_table = &range_digital; s->io_bits = 0xf; /* all bits output */ s->insn_bits = apci1516_do_insn_bits; @@ -271,7 +269,6 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; s->n_chan = 1; s->maxdata = 0; - s->len_chanlist = 1; s->range_table = &range_digital; s->insn_write = i_APCI1516_StartStopWriteWatchdog; s->insn_read = i_APCI1516_ReadWatchdog; -- cgit v1.2.3 From 5aaa8bc35b4fc9cb720cf31ce7bd23ac7c1803f7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:45:23 -0700 Subject: staging: comedi: addi_apci_1516: remove setting of s->io_bits This value only has meaning for dio subdevices. Don't bother setting it for the di and do subdevices in this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 415b347ac7e..978b3cdc97b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -242,7 +242,6 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s->n_chan = this_board->di_nchan; s->maxdata = 1; s->range_table = &range_digital; - s->io_bits = 0; /* all bits input */ s->insn_bits = apci1516_di_insn_bits; } else { s->type = COMEDI_SUBD_UNUSED; @@ -256,7 +255,6 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s->n_chan = this_board->do_nchan; s->maxdata = 1; s->range_table = &range_digital; - s->io_bits = 0xf; /* all bits output */ s->insn_bits = apci1516_do_insn_bits; } else { s->type = COMEDI_SUBD_UNUSED; -- cgit v1.2.3 From 42e07ce63e181c9a6bd7166f55c5dbb9a984a776 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:45:39 -0700 Subject: staging: comedi: addi_apci_1516: cleanup the s->subdev_flags The flags SDF_GROUND and SDF_COMMON only have meaning for analog input/output subdevices. Remove these flags from the digital input/output and timer subdevices in this driver. The digital output subdevice does not need the SDF_READABLE flags. Remove it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 978b3cdc97b..c8156e1354b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -238,7 +238,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s = &dev->subdevices[0]; if (this_board->di_nchan) { s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_READABLE; s->n_chan = this_board->di_nchan; s->maxdata = 1; s->range_table = &range_digital; @@ -250,8 +250,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s = &dev->subdevices[1]; if (this_board->do_nchan) { s->type = COMEDI_SUBD_DO; - s->subdev_flags = - SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITEABLE; s->n_chan = this_board->do_nchan; s->maxdata = 1; s->range_table = &range_digital; @@ -264,7 +263,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s = &dev->subdevices[2]; if (this_board->has_timer) { s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; + s->subdev_flags = SDF_WRITEABLE; s->n_chan = 1; s->maxdata = 0; s->range_table = &range_digital; -- cgit v1.2.3 From 9138de6b6befaae36b1074ce01c37517aceda061 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:46:04 -0700 Subject: staging: comedi: addi_apci_1516: add defines for the PCI device ids The PCI device ids supported by this driver are used multiple places in the code. To improve maintainability, create #define's for them. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index c8156e1354b..85ecd1a5229 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -32,6 +32,13 @@ #include "../comedidev.h" #include "comedi_fc.h" +/* + * PCI device ids supported by this driver + */ +#define PCI_DEVICE_ID_APCI1016 0x1000 +#define PCI_DEVICE_ID_APCI1516 0x1001 +#define PCI_DEVICE_ID_APCI2016 0x1002 + /* * PCI bar 1 I/O Register map */ @@ -60,17 +67,17 @@ struct apci1516_boardinfo { static const struct apci1516_boardinfo apci1516_boardtypes[] = { { .name = "apci1016", - .device = 0x1000, + .device = PCI_DEVICE_ID_APCI1016, .di_nchan = 16, }, { .name = "apci1516", - .device = 0x1001, + .device = PCI_DEVICE_ID_APCI1516, .di_nchan = 8, .do_nchan = 8, .has_timer = 1, }, { .name = "apci2016", - .device = 0x1002, + .device = PCI_DEVICE_ID_APCI2016, .do_nchan = 16, .has_timer = 1, }, @@ -309,9 +316,9 @@ static void __devexit apci1516_pci_remove(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(apci1516_pci_table) = { - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1000) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1001) }, - { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1002) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1016) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI1516) }, + { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, PCI_DEVICE_ID_APCI2016) }, { 0 } }; MODULE_DEVICE_TABLE(pci, apci1516_pci_table); -- cgit v1.2.3 From 87722a7ab74f2f9d89dcd45955a1c1d304e5e1c6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:46:19 -0700 Subject: staging: comedi: addi_apci_1516: cleanup apci1516_detach() This driver uses the comedi auto_config mechanism to attach to the comedi subsystem. The dev->hw_dev is set by the core so comedi_to_pci_dev() will always return a valid pcidev. Remove the unnecessary test. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 85ecd1a5229..ac99774a7cb 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -289,11 +289,9 @@ static void apci1516_detach(struct comedi_device *dev) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); - if (dev->iobase) + if (dev->iobase) { apci1516_reset(dev); - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); + comedi_pci_disable(pcidev); } } -- cgit v1.2.3 From 5c7c83230c1b0f490fa98402ea666609527d6558 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:46:35 -0700 Subject: staging: comedi: addi_apci_1516: cleanup the subdevice init For aesthetic reasons. add some whitespace to the subdevice init. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 46 ++++++++++++------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index ac99774a7cb..66207a197a4 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -244,41 +244,41 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, /* Allocate and Initialise DI Subdevice Structures */ s = &dev->subdevices[0]; if (this_board->di_nchan) { - s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; - s->n_chan = this_board->di_nchan; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = apci1516_di_insn_bits; + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->n_chan = this_board->di_nchan; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = apci1516_di_insn_bits; } else { - s->type = COMEDI_SUBD_UNUSED; + s->type = COMEDI_SUBD_UNUSED; } /* Allocate and Initialise DO Subdevice Structures */ s = &dev->subdevices[1]; if (this_board->do_nchan) { - s->type = COMEDI_SUBD_DO; - s->subdev_flags = SDF_WRITEABLE; - s->n_chan = this_board->do_nchan; - s->maxdata = 1; - s->range_table = &range_digital; - s->insn_bits = apci1516_do_insn_bits; + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITEABLE; + s->n_chan = this_board->do_nchan; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = apci1516_do_insn_bits; } else { - s->type = COMEDI_SUBD_UNUSED; + s->type = COMEDI_SUBD_UNUSED; } /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[2]; if (this_board->has_timer) { - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_WRITEABLE; - s->n_chan = 1; - s->maxdata = 0; - s->range_table = &range_digital; - s->insn_write = i_APCI1516_StartStopWriteWatchdog; - s->insn_read = i_APCI1516_ReadWatchdog; - s->insn_config = i_APCI1516_ConfigWatchdog; + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_WRITEABLE; + s->n_chan = 1; + s->maxdata = 0; + s->range_table = &range_digital; + s->insn_write = i_APCI1516_StartStopWriteWatchdog; + s->insn_read = i_APCI1516_ReadWatchdog; + s->insn_config = i_APCI1516_ConfigWatchdog; } else { - s->type = COMEDI_SUBD_UNUSED; + s->type = COMEDI_SUBD_UNUSED; } apci1516_reset(dev); -- cgit v1.2.3 From 9151b01f3c5155d67d4dbd1c294694d57859dbec Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:46:52 -0700 Subject: staging: comedi: addi_apci_1516: fix i_APCI1516_ReadWatchdog() This function is used by the watchdog subdevice to read the status of the watchdog. Rename the CamelCase function to apci1516_wdog_insn_read and fix the function to return the status value insn->n times like the comedi core expects. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 66207a197a4..49b2f5c996c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -169,14 +169,17 @@ static int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, return insn->n; } -static int i_APCI1516_ReadWatchdog(struct comedi_device *dev, +static int apci1516_wdog_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { struct apci1516_private *devpriv = dev->private; + int i; + + for (i = 0; i < insn->n; i++) + data[i] = inw(devpriv->wdog_iobase + APCI1516_WDOG_STATUS_REG); - data[0] = inw(devpriv->wdog_iobase + APCI1516_WDOG_STATUS_REG) & 0x1; return insn->n; } @@ -275,7 +278,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s->maxdata = 0; s->range_table = &range_digital; s->insn_write = i_APCI1516_StartStopWriteWatchdog; - s->insn_read = i_APCI1516_ReadWatchdog; + s->insn_read = apci1516_wdog_insn_read; s->insn_config = i_APCI1516_ConfigWatchdog; } else { s->type = COMEDI_SUBD_UNUSED; -- cgit v1.2.3 From 158b64973e7854cddefb1f56c3758ed8382f2bc8 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:47:09 -0700 Subject: staging: comedi: addi_apci_1516: fix i_APCI1516_ConfigWatchdog() This function is used by the watchdog subdevice to enable/disable and set the timeout for the watchdog. Rename the CamelCase function to apci1516_wdog_insn_config. Currently this function does not follow the comed API. Recode it so it works like the core expects. data[0] is the configuration id code (INSN_CONFIG_*) for the configuration instruction. Two instructions are supported: INSN_CONFIG_ARM: enables the watchdog and sets the timeout value INSN_CONFIG_DISARM: disables the watchdog Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 55 +++++++++++++++---------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 49b2f5c996c..856bb192ca0 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -49,8 +49,7 @@ * PCI bar 2 I/O Register map */ #define APCI1516_WDOG_REG 0x00 -#define APCI1516_WDOG_RELOAD_LSB_REG 0x04 -#define APCI1516_WDOG_RELOAD_MSB_REG 0x06 +#define APCI1516_WDOG_RELOAD_REG 0x04 #define APCI1516_WDOG_CTRL_REG 0x0c #define APCI1516_WDOG_CTRL_ENABLE (1 << 0) #define APCI1516_WDOG_CTRL_SOFT_TRIG (1 << 9) @@ -85,6 +84,7 @@ static const struct apci1516_boardinfo apci1516_boardtypes[] = { struct apci1516_private { unsigned long wdog_iobase; + unsigned int ctrl; }; static int apci1516_di_insn_bits(struct comedi_device *dev, @@ -118,27 +118,42 @@ static int apci1516_do_insn_bits(struct comedi_device *dev, return insn->n; } -static int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, +/* + * The watchdog subdevice is configured with two INSN_CONFIG instructions: + * + * Enable the watchdog and set the reload timeout: + * data[0] = INSN_CONFIG_ARM + * data[1] = timeout reload value + * + * Disable the watchdog: + * data[0] = INSN_CONFIG_DISARM + */ +static int apci1516_wdog_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { struct apci1516_private *devpriv = dev->private; + unsigned int reload; - if (data[0] == 0) { - /* Disable the watchdog */ - outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); - /* Loading the Reload value */ - outw(data[1], devpriv->wdog_iobase + - APCI1516_WDOG_RELOAD_LSB_REG); - data[1] = data[1] >> 16; - outw(data[1], devpriv->wdog_iobase + - APCI1516_WDOG_RELOAD_MSB_REG); - } /* if(data[0]==0) */ - else { - printk("\nThe input parameters are wrong\n"); + switch (data[0]) { + case INSN_CONFIG_ARM: + devpriv->ctrl = APCI1516_WDOG_CTRL_ENABLE; + reload = data[1] & s->maxdata; + outw(reload, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_REG); + + /* Time base is 20ms, let the user know the timeout */ + dev_info(dev->class_dev, "watchdog enabled, timeout:%dms\n", + 20 * reload + 20); + break; + case INSN_CONFIG_DISARM: + devpriv->ctrl = 0; + break; + default: return -EINVAL; - } /* elseif(data[0]==0) */ + } + + outw(devpriv->ctrl, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); return insn->n; } @@ -193,8 +208,7 @@ static int apci1516_reset(struct comedi_device *dev) outw(0x0, dev->iobase + APCI1516_DO_REG); outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); - outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_LSB_REG); - outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_MSB_REG); + outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_RELOAD_REG); return 0; } @@ -275,11 +289,10 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITEABLE; s->n_chan = 1; - s->maxdata = 0; - s->range_table = &range_digital; + s->maxdata = 0xff; s->insn_write = i_APCI1516_StartStopWriteWatchdog; s->insn_read = apci1516_wdog_insn_read; - s->insn_config = i_APCI1516_ConfigWatchdog; + s->insn_config = apci1516_wdog_insn_config; } else { s->type = COMEDI_SUBD_UNUSED; } -- cgit v1.2.3 From 0ff1fa77687052ff36aa141317c45f737057ce5d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:47:27 -0700 Subject: staging: comedi: addi_apci_1516: fix i_APCI1516_StartStopWriteWatchdog() This function is used by the watchdog subdevice to "ping" the watchdog. Rename the CamelCase function to apci1516_wdog_insn_write. Currently this function does not follow the comed API. INSN_WRITE functions are supposed to write insn->n values. Also, starting and stopping the watchdog is handled by the INSN_CONFIG function. Fix this function so it works like the comedi core expects. Also, since the watchdog needs to be enabled in order to "ping" it, make sure it is enabled before writing to it. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 38 +++++++++++-------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 856bb192ca0..e3e4b0f0f5b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -52,7 +52,7 @@ #define APCI1516_WDOG_RELOAD_REG 0x04 #define APCI1516_WDOG_CTRL_REG 0x0c #define APCI1516_WDOG_CTRL_ENABLE (1 << 0) -#define APCI1516_WDOG_CTRL_SOFT_TRIG (1 << 9) +#define APCI1516_WDOG_CTRL_SW_TRIG (1 << 9) #define APCI1516_WDOG_STATUS_REG 0x10 struct apci1516_boardinfo { @@ -158,29 +158,25 @@ static int apci1516_wdog_insn_config(struct comedi_device *dev, return insn->n; } -static int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) +static int apci1516_wdog_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct apci1516_private *devpriv = dev->private; + int i; - switch (data[0]) { - case 0: /* stop the watchdog */ - outw(0x0, devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); - break; - case 1: /* start the watchdog */ - outw(APCI1516_WDOG_CTRL_ENABLE, - devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); - break; - case 2: /* Software trigger */ - outw(APCI1516_WDOG_CTRL_ENABLE | APCI1516_WDOG_CTRL_SOFT_TRIG, - devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); - break; - default: - printk("\nSpecified functionality does not exist\n"); + if (devpriv->ctrl == 0) { + dev_warn(dev->class_dev, "watchdog is disabled\n"); return -EINVAL; - } /* switch(data[0]) */ + } + + /* "ping" the watchdog */ + for (i = 0; i < insn->n; i++) { + outw(devpriv->ctrl | APCI1516_WDOG_CTRL_SW_TRIG, + devpriv->wdog_iobase + APCI1516_WDOG_CTRL_REG); + } + return insn->n; } @@ -290,7 +286,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s->subdev_flags = SDF_WRITEABLE; s->n_chan = 1; s->maxdata = 0xff; - s->insn_write = i_APCI1516_StartStopWriteWatchdog; + s->insn_write = apci1516_wdog_insn_write; s->insn_read = apci1516_wdog_insn_read; s->insn_config = apci1516_wdog_insn_config; } else { -- cgit v1.2.3 From 1567ceaa3f0e4207fcce46e5116752c9e2d8e294 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:47:48 -0700 Subject: staging: comedi: addi_apci_1516: final cleanup of the register map defines I finally got hold of the i/o mapping from ADDI-DATA. Cleanup the defines a bit and add the missing information. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index e3e4b0f0f5b..5f8d802fa78 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -40,20 +40,22 @@ #define PCI_DEVICE_ID_APCI2016 0x1002 /* - * PCI bar 1 I/O Register map + * PCI bar 1 I/O Register map - Digital input/output */ -#define APCI1516_DI_REG 0x00 -#define APCI1516_DO_REG 0x04 +#define APCI1516_DI_REG 0x00 +#define APCI1516_DO_REG 0x04 /* - * PCI bar 2 I/O Register map + * PCI bar 2 I/O Register map - Watchdog (APCI-1516 and APCI-2016) */ -#define APCI1516_WDOG_REG 0x00 -#define APCI1516_WDOG_RELOAD_REG 0x04 -#define APCI1516_WDOG_CTRL_REG 0x0c -#define APCI1516_WDOG_CTRL_ENABLE (1 << 0) -#define APCI1516_WDOG_CTRL_SW_TRIG (1 << 9) -#define APCI1516_WDOG_STATUS_REG 0x10 +#define APCI1516_WDOG_REG 0x00 +#define APCI1516_WDOG_RELOAD_REG 0x04 +#define APCI1516_WDOG_CTRL_REG 0x0c +#define APCI1516_WDOG_CTRL_ENABLE (1 << 0) +#define APCI1516_WDOG_CTRL_SW_TRIG (1 << 9) +#define APCI1516_WDOG_STATUS_REG 0x10 +#define APCI1516_WDOG_STATUS_ENABLED (1 << 0) +#define APCI1516_WDOG_STATUS_SW_TRIG (1 << 1) struct apci1516_boardinfo { const char *name; -- cgit v1.2.3 From 07e957120d79f41463023c302274ba26c994d789 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:48:03 -0700 Subject: staging: comedi: addi_apci_1516: rename has_timer The "timer" on these boards is actually a watchdog. Rename the boardinfo value "has_timer" to "has_wdog". Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 5f8d802fa78..952142aca88 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -62,7 +62,7 @@ struct apci1516_boardinfo { unsigned short device; int di_nchan; int do_nchan; - int has_timer; + int has_wdog; }; static const struct apci1516_boardinfo apci1516_boardtypes[] = { @@ -75,12 +75,12 @@ static const struct apci1516_boardinfo apci1516_boardtypes[] = { .device = PCI_DEVICE_ID_APCI1516, .di_nchan = 8, .do_nchan = 8, - .has_timer = 1, + .has_wdog = 1, }, { .name = "apci2016", .device = PCI_DEVICE_ID_APCI2016, .do_nchan = 16, - .has_timer = 1, + .has_wdog = 1, }, }; @@ -201,7 +201,7 @@ static int apci1516_reset(struct comedi_device *dev) const struct apci1516_boardinfo *this_board = comedi_board(dev); struct apci1516_private *devpriv = dev->private; - if (!this_board->has_timer) + if (!this_board->has_wdog) return 0; outw(0x0, dev->iobase + APCI1516_DO_REG); @@ -283,7 +283,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, /* Allocate and Initialise Timer Subdevice Structures */ s = &dev->subdevices[2]; - if (this_board->has_timer) { + if (this_board->has_wdog) { s->type = COMEDI_SUBD_TIMER; s->subdev_flags = SDF_WRITEABLE; s->n_chan = 1; -- cgit v1.2.3 From 3f0732a724d3d454a264a7ac2313313cf95a52bf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:48:18 -0700 Subject: staging: comedi: addi_apci_1516: reword the initialization comments The subdevice init does not do any allocation, this was already done by comedi_alloc_subdevices(). Reword the comments a bit. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 952142aca88..af2291252fc 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -256,7 +256,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, if (ret) return ret; - /* Allocate and Initialise DI Subdevice Structures */ + /* Initialize the digital input subdevice */ s = &dev->subdevices[0]; if (this_board->di_nchan) { s->type = COMEDI_SUBD_DI; @@ -268,7 +268,8 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, } else { s->type = COMEDI_SUBD_UNUSED; } - /* Allocate and Initialise DO Subdevice Structures */ + + /* Initialize the digital output subdevice */ s = &dev->subdevices[1]; if (this_board->do_nchan) { s->type = COMEDI_SUBD_DO; @@ -281,7 +282,7 @@ static int __devinit apci1516_auto_attach(struct comedi_device *dev, s->type = COMEDI_SUBD_UNUSED; } - /* Allocate and Initialise Timer Subdevice Structures */ + /* Initialize the watchdog subdevice */ s = &dev->subdevices[2]; if (this_board->has_wdog) { s->type = COMEDI_SUBD_TIMER; -- cgit v1.2.3 From 98071b6773d39e8714edafe9ac7a6a99b7f04b4d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:48:34 -0700 Subject: staging: comedi: addi_apci_1516: update the Kconfig This driver does not use virt_to_bus(), remove the depends on for it. Update the Kconfig entry to list all the boards supported by this driver. Also, expand the help text a bit. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index bede5736532..77de0301191 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -594,10 +594,11 @@ config COMEDI_ADDI_APCI_1500 called addi_apci_1500. config COMEDI_ADDI_APCI_1516 - tristate "ADDI-DATA APCI-1516/2016 support" - depends on VIRT_TO_BUS + tristate "ADDI-DATA APCI-1016/1516/2016 support" ---help--- - Enable support for ADDI-DATA APCI-1516 and APCI-2016 boards. + Enable support for ADDI-DATA APCI-1016, APCI-1516 and APCI-2016 boards. + These are 16 channel, optically isolated, digital I/O boards. The 1516 + and 2016 boards also have a watchdog for resetting the outputs to "0". To compile this driver as a module, choose M here: the module will be called addi_apci_1516. -- cgit v1.2.3 From be3c5126b553cc807d112a5010a10f8e5bee5427 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 13:48:50 -0700 Subject: staging: comedi: addi_apci_1516: update the MODULE_DESCRIPTION Change the generic MODULE_DESCRIPTION text to something more specific for this driver. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1516.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index af2291252fc..e6aa5226014 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -344,6 +344,6 @@ static struct pci_driver apci1516_pci_driver = { }; module_comedi_pci_driver(apci1516_driver, apci1516_pci_driver); +MODULE_DESCRIPTION("ADDI-DATA APCI-1016/1516/2016, 16 channel DIO boards"); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 743815ae1bbd2790321a3ab1f23abb82c1fdd45b Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Tue, 13 Nov 2012 15:41:32 -0600 Subject: staging: drm/omap: Fix usage of IS_ERR_OR_NULL and PTR_ERR Return PTR_ERR(-ENOMEM) if dmm_txn_init cannot allocate a refill engine. Signed-off-by: Andy Gross Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_dmm_tiler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index 4d138df369b..5c809c05685 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -296,7 +296,7 @@ static int fill(struct tcm_area *area, struct page **pages, txn = dmm_txn_init(omap_dmm, area->tcm); if (IS_ERR_OR_NULL(txn)) - return PTR_ERR(txn); + return PTR_ERR(-ENOMEM); tcm_for_each_slice(slice, *area, area_s) { struct pat_area p_area = { -- cgit v1.2.3 From 1ba56fb45a927d083f655302e75a1911a75b5da6 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 13 Nov 2012 13:10:59 +0000 Subject: vxlan: Update hard_header_len based on lowerdev when instantiating VXLAN In the event of a VXLAN device being linked to a device that has a hard_header_len greater than that of standard ethernet we could end up with the hard_header_len not being large enough for outgoing frames. In order to prevent this we should update the length when a lowerdev is provided. Signed-off-by: Alexander Duyck Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 3d0bf664ea3..8b5c6191707 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1102,6 +1102,10 @@ static int vxlan_newlink(struct net *net, struct net_device *dev, if (!tb[IFLA_MTU]) dev->mtu = lowerdev->mtu - VXLAN_HEADROOM; + + /* update header length based on lower device */ + dev->hard_header_len = lowerdev->hard_header_len + + VXLAN_HEADROOM; } if (data[IFLA_VXLAN_TOS]) -- cgit v1.2.3 From 1f168dbdf731dea301a297e2409adc4a54ed6612 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 16:21:17 -0700 Subject: staging: comedi: Kconfig: remove VIRT_TO_BUS depends on The only addi-data driver that uses virt_to_bus is addi_apci_3120. Remove the depends on for the other addi-data drivers. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 77de0301191..7de2a10213b 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -568,7 +568,6 @@ config COMEDI_8255_PCI config COMEDI_ADDI_APCI_035 tristate "ADDI-DATA APCI_035 support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_035 cards @@ -577,7 +576,6 @@ config COMEDI_ADDI_APCI_035 config COMEDI_ADDI_APCI_1032 tristate "ADDI-DATA APCI_1032 support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_1032 cards @@ -586,7 +584,6 @@ config COMEDI_ADDI_APCI_1032 config COMEDI_ADDI_APCI_1500 tristate "ADDI-DATA APCI_1500 support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_1500 cards @@ -605,7 +602,6 @@ config COMEDI_ADDI_APCI_1516 config COMEDI_ADDI_APCI_1564 tristate "ADDI-DATA APCI_1564 support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_1564 cards @@ -614,7 +610,6 @@ config COMEDI_ADDI_APCI_1564 config COMEDI_ADDI_APCI_16XX tristate "ADDI-DATA APCI_16xx support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_16xx cards @@ -623,7 +618,6 @@ config COMEDI_ADDI_APCI_16XX config COMEDI_ADDI_APCI_2032 tristate "ADDI-DATA APCI_2032 support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_2032 cards @@ -632,7 +626,6 @@ config COMEDI_ADDI_APCI_2032 config COMEDI_ADDI_APCI_2200 tristate "ADDI-DATA APCI_2200 support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_2200 cards @@ -651,7 +644,6 @@ config COMEDI_ADDI_APCI_3120 config COMEDI_ADDI_APCI_3501 tristate "ADDI-DATA APCI_3501 support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_3501 cards @@ -660,7 +652,6 @@ config COMEDI_ADDI_APCI_3501 config COMEDI_ADDI_APCI_3XXX tristate "ADDI-DATA APCI_3xxx support" - depends on VIRT_TO_BUS ---help--- Enable support for ADDI-DATA APCI_3xxx cards -- cgit v1.2.3 From 3c6bdaeab4fda6c9fdd5f3f5c610dea97bddf7d6 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 18 Sep 2012 12:19:30 -0400 Subject: [SCSI] Add a report opcode helper The REPORT SUPPORTED OPERATION CODES command can be used to query whether a given opcode is supported by a device. Add a helper function that allows us to look up commands. We only issue RSOC if the device reports compliance with SPC-3 or later. But to err on the side of caution we disable the command for ATA, FireWire and USB. Signed-off-by: Martin K. Petersen Acked-by: Mike Snitzer Signed-off-by: James Bottomley --- drivers/ata/libata-scsi.c | 1 + drivers/firewire/sbp2.c | 1 + drivers/scsi/scsi.c | 45 ++++++++++++++++++++++++++++++++++++++++++ drivers/usb/storage/scsiglue.c | 3 +++ include/scsi/scsi_device.h | 3 +++ 5 files changed, 53 insertions(+) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e3bda074fa1..7c2dead6051 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1052,6 +1052,7 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) { sdev->use_10_for_rw = 1; sdev->use_10_for_ms = 1; + sdev->no_report_opcodes = 1; /* Schedule policy is determined by ->qc_defer() callback and * it needs to see every deferred qc. Set dev_blocked to 1 to diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 1162d6b3bf8..f82e9d4295d 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -1546,6 +1546,7 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) struct sbp2_logical_unit *lu = sdev->hostdata; sdev->use_10_for_rw = 1; + sdev->no_report_opcodes = 1; if (sbp2_param_exclusive_login) sdev->manage_start_stop = 1; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 2936b447cae..2c0d0ec8150 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -1061,6 +1062,50 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf, } EXPORT_SYMBOL_GPL(scsi_get_vpd_page); +/** + * scsi_report_opcode - Find out if a given command opcode is supported + * @sdev: scsi device to query + * @buffer: scratch buffer (must be at least 20 bytes long) + * @len: length of buffer + * @opcode: opcode for command to look up + * + * Uses the REPORT SUPPORTED OPERATION CODES to look up the given + * opcode. Returns 0 if RSOC fails or if the command opcode is + * unsupported. Returns 1 if the device claims to support the command. + */ +int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, + unsigned int len, unsigned char opcode) +{ + unsigned char cmd[16]; + struct scsi_sense_hdr sshdr; + int result; + + if (sdev->no_report_opcodes || sdev->scsi_level < SCSI_SPC_3) + return 0; + + memset(cmd, 0, 16); + cmd[0] = MAINTENANCE_IN; + cmd[1] = MI_REPORT_SUPPORTED_OPERATION_CODES; + cmd[2] = 1; /* One command format */ + cmd[3] = opcode; + put_unaligned_be32(len, &cmd[6]); + memset(buffer, 0, len); + + result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, + &sshdr, 30 * HZ, 3, NULL); + + if (result && scsi_sense_valid(&sshdr) && + sshdr.sense_key == ILLEGAL_REQUEST && + (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00) + return 0; + + if ((buffer[1] & 3) == 3) /* Command supported */ + return 1; + + return 0; +} +EXPORT_SYMBOL(scsi_report_opcode); + /** * scsi_device_get - get an additional reference to a scsi_device * @sdev: device to get a reference to diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index a3d54366afc..6ab376a7c50 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -186,6 +186,9 @@ static int slave_configure(struct scsi_device *sdev) /* Some devices don't handle VPD pages correctly */ sdev->skip_vpd_pages = 1; + /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */ + sdev->no_report_opcodes = 1; + /* Some disks return the total number of blocks in response * to READ CAPACITY rather than the highest block number. * If this device makes that mistake, tell the sd driver. */ diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 88fae8d2015..379d465e807 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -135,6 +135,7 @@ struct scsi_device { * because we did a bus reset. */ unsigned use_10_for_rw:1; /* first try 10-byte read / write */ unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ + unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ unsigned skip_vpd_pages:1; /* do not read VPD pages */ @@ -362,6 +363,8 @@ extern int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries, struct scsi_sense_hdr *sshdr); extern int scsi_get_vpd_page(struct scsi_device *, u8 page, unsigned char *buf, int buf_len); +extern int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, + unsigned int len, unsigned char opcode); extern int scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state); extern struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, -- cgit v1.2.3 From 26e85fcd15f68b57d9ba645cd3591117a8ac0e05 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 18 Sep 2012 12:19:31 -0400 Subject: [SCSI] sd: Permit merged discard requests Support requests with more than one bio payload for discards. The total number of bytes to be discarded is stored in req->__data_len and used in sd_done() to complete the I/O. Signed-off-by: Martin K. Petersen Reviewed-by: Mike Snitzer Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 12f6fdfc114..c6af4c1a9ca 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -583,29 +583,26 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) } /** - * scsi_setup_discard_cmnd - unmap blocks on thinly provisioned device + * sd_setup_discard_cmnd - unmap blocks on thinly provisioned device * @sdp: scsi device to operate one * @rq: Request to prepare * * Will issue either UNMAP or WRITE SAME(16) depending on preference * indicated by target device. **/ -static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) +static int sd_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) { struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); - struct bio *bio = rq->bio; - sector_t sector = bio->bi_sector; - unsigned int nr_sectors = bio_sectors(bio); + sector_t sector = blk_rq_pos(rq); + unsigned int nr_sectors = blk_rq_sectors(rq); + unsigned int nr_bytes = blk_rq_bytes(rq); unsigned int len; int ret; char *buf; struct page *page; - if (sdkp->device->sector_size == 4096) { - sector >>= 3; - nr_sectors >>= 3; - } - + sector >>= ilog2(sdp->sector_size) - 9; + nr_sectors >>= ilog2(sdp->sector_size) - 9; rq->timeout = SD_TIMEOUT; memset(rq->cmd, 0, rq->cmd_len); @@ -660,6 +657,7 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq) blk_add_request_payload(rq, page, len); ret = scsi_setup_blk_pc_cmnd(sdp, rq); rq->buffer = page_address(page); + rq->__data_len = nr_bytes; out: if (ret != BLKPREP_OK) { @@ -712,7 +710,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) * block PC requests to make life easier. */ if (rq->cmd_flags & REQ_DISCARD) { - ret = scsi_setup_discard_cmnd(sdp, rq); + ret = sd_setup_discard_cmnd(sdp, rq); goto out; } else if (rq->cmd_flags & REQ_FLUSH) { ret = scsi_setup_flush_cmnd(sdp, rq); @@ -1482,12 +1480,20 @@ static int sd_done(struct scsi_cmnd *SCpnt) unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); struct scsi_sense_hdr sshdr; struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk); + struct request *req = SCpnt->request; int sense_valid = 0; int sense_deferred = 0; unsigned char op = SCpnt->cmnd[0]; - if ((SCpnt->request->cmd_flags & REQ_DISCARD) && !result) - scsi_set_resid(SCpnt, 0); + if (req->cmd_flags & REQ_DISCARD) { + if (!result) { + good_bytes = blk_rq_bytes(req); + scsi_set_resid(SCpnt, 0); + } else { + good_bytes = 0; + scsi_set_resid(SCpnt, blk_rq_bytes(req)); + } + } if (result) { sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); -- cgit v1.2.3 From 5db44863b6ebbb400c5e61d56ebe8f21ef48b1bd Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 18 Sep 2012 12:19:32 -0400 Subject: [SCSI] sd: Implement support for WRITE SAME Implement support for WRITE SAME(10) and WRITE SAME(16) in the SCSI disk driver. - We set the default maximum to 0xFFFF because there are several devices out there that only support two-byte block counts even with WRITE SAME(16). We only enable transfers bigger than 0xFFFF if the device explicitly reports MAXIMUM WRITE SAME LENGTH in the BLOCK LIMITS VPD. - max_write_same_blocks can be overriden per-device basis in sysfs. - The UNMAP discovery heuristics remain unchanged but the discard limits are tweaked to match the "real" WRITE SAME commands. - In the error handling logic we now distinguish between WRITE SAME with and without UNMAP set. The discovery process heuristics are: - If the device reports a SCSI level of SPC-3 or greater we'll issue READ SUPPORTED OPERATION CODES to find out whether WRITE SAME(16) is supported. If that's the case we will use it. - If the device supports the block limits VPD and reports a MAXIMUM WRITE SAME LENGTH bigger than 0xFFFF we will use WRITE SAME(16). - Otherwise we will use WRITE SAME(10) unless the target LBA is beyond 0xFFFFFFFF or the block count exceeds 0xFFFF. - no_write_same is set for ATA, FireWire and USB. Signed-off-by: Martin K. Petersen Reviewed-by: Mike Snitzer Reviewed-by: Jeff Garzik Signed-off-by: James Bottomley --- drivers/ata/libata-scsi.c | 1 + drivers/firewire/sbp2.c | 1 + drivers/scsi/scsi_lib.c | 22 ++++-- drivers/scsi/sd.c | 172 ++++++++++++++++++++++++++++++++++++++--- drivers/scsi/sd.h | 7 ++ drivers/usb/storage/scsiglue.c | 3 + include/scsi/scsi_device.h | 1 + 7 files changed, 191 insertions(+), 16 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 7c2dead6051..a6df6a351d6 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1053,6 +1053,7 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) sdev->use_10_for_rw = 1; sdev->use_10_for_ms = 1; sdev->no_report_opcodes = 1; + sdev->no_write_same = 1; /* Schedule policy is determined by ->qc_defer() callback and * it needs to see every deferred qc. Set dev_blocked to 1 to diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index f82e9d4295d..bb1b392f5cd 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -1547,6 +1547,7 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) sdev->use_10_for_rw = 1; sdev->no_report_opcodes = 1; + sdev->no_write_same = 1; if (sbp2_param_exclusive_login) sdev->manage_start_stop = 1; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index da36a3a81a9..9032e910bca 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -900,11 +900,23 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) action = ACTION_FAIL; error = -EILSEQ; /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ - } else if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && - (cmd->cmnd[0] == UNMAP || - cmd->cmnd[0] == WRITE_SAME_16 || - cmd->cmnd[0] == WRITE_SAME)) { - description = "Discard failure"; + } else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { + switch (cmd->cmnd[0]) { + case UNMAP: + description = "Discard failure"; + break; + case WRITE_SAME: + case WRITE_SAME_16: + if (cmd->cmnd[1] & 0x8) + description = "Discard failure"; + else + description = + "Write same failure"; + break; + default: + description = "Invalid command failure"; + break; + } action = ACTION_FAIL; error = -EREMOTEIO; } else diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index c6af4c1a9ca..352bc77b7c8 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -99,6 +99,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); #endif static void sd_config_discard(struct scsi_disk *, unsigned int); +static void sd_config_write_same(struct scsi_disk *); static int sd_revalidate_disk(struct gendisk *); static void sd_unlock_native_capacity(struct gendisk *disk); static int sd_probe(struct device *); @@ -395,6 +396,45 @@ sd_store_max_medium_access_timeouts(struct device *dev, return err ? err : count; } +static ssize_t +sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + + return snprintf(buf, 20, "%u\n", sdkp->max_ws_blocks); +} + +static ssize_t +sd_store_write_same_blocks(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + struct scsi_device *sdp = sdkp->device; + unsigned long max; + int err; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (sdp->type != TYPE_DISK) + return -EINVAL; + + err = kstrtoul(buf, 10, &max); + + if (err) + return err; + + if (max == 0) + sdp->no_write_same = 1; + else if (max <= SD_MAX_WS16_BLOCKS) + sdkp->max_ws_blocks = max; + + sd_config_write_same(sdkp); + + return count; +} + static struct device_attribute sd_disk_attrs[] = { __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, sd_store_cache_type), @@ -410,6 +450,8 @@ static struct device_attribute sd_disk_attrs[] = { __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, sd_store_provisioning_mode), + __ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR, + sd_show_write_same_blocks, sd_store_write_same_blocks), __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, sd_show_max_medium_access_timeouts, sd_store_max_medium_access_timeouts), @@ -561,19 +603,23 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode) return; case SD_LBP_UNMAP: - max_blocks = min_not_zero(sdkp->max_unmap_blocks, 0xffffffff); + max_blocks = min_not_zero(sdkp->max_unmap_blocks, + (u32)SD_MAX_WS16_BLOCKS); break; case SD_LBP_WS16: - max_blocks = min_not_zero(sdkp->max_ws_blocks, 0xffffffff); + max_blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS16_BLOCKS); break; case SD_LBP_WS10: - max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); + max_blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS10_BLOCKS); break; case SD_LBP_ZERO: - max_blocks = min_not_zero(sdkp->max_ws_blocks, (u32)0xffff); + max_blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS10_BLOCKS); q->limits.discard_zeroes_data = 1; break; } @@ -667,6 +713,83 @@ out: return ret; } +static void sd_config_write_same(struct scsi_disk *sdkp) +{ + struct request_queue *q = sdkp->disk->queue; + unsigned int logical_block_size = sdkp->device->sector_size; + unsigned int blocks = 0; + + if (sdkp->device->no_write_same) { + sdkp->max_ws_blocks = 0; + goto out; + } + + /* Some devices can not handle block counts above 0xffff despite + * supporting WRITE SAME(16). Consequently we default to 64k + * blocks per I/O unless the device explicitly advertises a + * bigger limit. + */ + if (sdkp->max_ws_blocks == 0) + sdkp->max_ws_blocks = SD_MAX_WS10_BLOCKS; + + if (sdkp->ws16 || sdkp->max_ws_blocks > SD_MAX_WS10_BLOCKS) + blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS16_BLOCKS); + else + blocks = min_not_zero(sdkp->max_ws_blocks, + (u32)SD_MAX_WS10_BLOCKS); + +out: + blk_queue_max_write_same_sectors(q, blocks * (logical_block_size >> 9)); +} + +/** + * sd_setup_write_same_cmnd - write the same data to multiple blocks + * @sdp: scsi device to operate one + * @rq: Request to prepare + * + * Will issue either WRITE SAME(10) or WRITE SAME(16) depending on + * preference indicated by target device. + **/ +static int sd_setup_write_same_cmnd(struct scsi_device *sdp, struct request *rq) +{ + struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); + struct bio *bio = rq->bio; + sector_t sector = blk_rq_pos(rq); + unsigned int nr_sectors = blk_rq_sectors(rq); + unsigned int nr_bytes = blk_rq_bytes(rq); + int ret; + + if (sdkp->device->no_write_same) + return BLKPREP_KILL; + + BUG_ON(bio_offset(bio) || bio_iovec(bio)->bv_len != sdp->sector_size); + + sector >>= ilog2(sdp->sector_size) - 9; + nr_sectors >>= ilog2(sdp->sector_size) - 9; + + rq->__data_len = sdp->sector_size; + rq->timeout = SD_WRITE_SAME_TIMEOUT; + memset(rq->cmd, 0, rq->cmd_len); + + if (sdkp->ws16 || sector > 0xffffffff || nr_sectors > 0xffff) { + rq->cmd_len = 16; + rq->cmd[0] = WRITE_SAME_16; + put_unaligned_be64(sector, &rq->cmd[2]); + put_unaligned_be32(nr_sectors, &rq->cmd[10]); + } else { + rq->cmd_len = 10; + rq->cmd[0] = WRITE_SAME; + put_unaligned_be32(sector, &rq->cmd[2]); + put_unaligned_be16(nr_sectors, &rq->cmd[7]); + } + + ret = scsi_setup_blk_pc_cmnd(sdp, rq); + rq->__data_len = nr_bytes; + + return ret; +} + static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) { rq->timeout = SD_FLUSH_TIMEOUT; @@ -712,6 +835,9 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) if (rq->cmd_flags & REQ_DISCARD) { ret = sd_setup_discard_cmnd(sdp, rq); goto out; + } else if (rq->cmd_flags & REQ_WRITE_SAME) { + ret = sd_setup_write_same_cmnd(sdp, rq); + goto out; } else if (rq->cmd_flags & REQ_FLUSH) { ret = scsi_setup_flush_cmnd(sdp, rq); goto out; @@ -1484,8 +1610,9 @@ static int sd_done(struct scsi_cmnd *SCpnt) int sense_valid = 0; int sense_deferred = 0; unsigned char op = SCpnt->cmnd[0]; + unsigned char unmap = SCpnt->cmnd[1] & 8; - if (req->cmd_flags & REQ_DISCARD) { + if (req->cmd_flags & REQ_DISCARD || req->cmd_flags & REQ_WRITE_SAME) { if (!result) { good_bytes = blk_rq_bytes(req); scsi_set_resid(SCpnt, 0); @@ -1542,9 +1669,25 @@ static int sd_done(struct scsi_cmnd *SCpnt) if (sshdr.asc == 0x10) /* DIX: Host detected corruption */ good_bytes = sd_completed_bytes(SCpnt); /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ - if ((sshdr.asc == 0x20 || sshdr.asc == 0x24) && - (op == UNMAP || op == WRITE_SAME_16 || op == WRITE_SAME)) - sd_config_discard(sdkp, SD_LBP_DISABLE); + if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { + switch (op) { + case UNMAP: + sd_config_discard(sdkp, SD_LBP_DISABLE); + break; + case WRITE_SAME_16: + case WRITE_SAME: + if (unmap) + sd_config_discard(sdkp, SD_LBP_DISABLE); + else { + sdkp->device->no_write_same = 1; + sd_config_write_same(sdkp); + + good_bytes = 0; + req->__data_len = blk_rq_bytes(req); + req->cmd_flags |= REQ_QUIET; + } + } + } break; default: break; @@ -2380,9 +2523,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) if (buffer[3] == 0x3c) { unsigned int lba_count, desc_count; - sdkp->max_ws_blocks = - (u32) min_not_zero(get_unaligned_be64(&buffer[36]), - (u64)0xffffffff); + sdkp->max_ws_blocks = (u32)get_unaligned_be64(&buffer[36]); if (!sdkp->lbpme) goto out; @@ -2475,6 +2616,13 @@ static void sd_read_block_provisioning(struct scsi_disk *sdkp) kfree(buffer); } +static void sd_read_write_same(struct scsi_disk *sdkp, unsigned char *buffer) +{ + if (scsi_report_opcode(sdkp->device, buffer, SD_BUF_SIZE, + WRITE_SAME_16)) + sdkp->ws16 = 1; +} + static int sd_try_extended_inquiry(struct scsi_device *sdp) { /* @@ -2534,6 +2682,7 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_read_write_protect_flag(sdkp, buffer); sd_read_cache_type(sdkp, buffer); sd_read_app_tag_own(sdkp, buffer); + sd_read_write_same(sdkp, buffer); } sdkp->first_scan = 0; @@ -2551,6 +2700,7 @@ static int sd_revalidate_disk(struct gendisk *disk) blk_queue_flush(sdkp->disk->queue, flush); set_capacity(disk, sdkp->capacity); + sd_config_write_same(sdkp); kfree(buffer); out: diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 47c52a6d733..74a1e4ca540 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -14,6 +14,7 @@ #define SD_TIMEOUT (30 * HZ) #define SD_MOD_TIMEOUT (75 * HZ) #define SD_FLUSH_TIMEOUT (60 * HZ) +#define SD_WRITE_SAME_TIMEOUT (120 * HZ) /* * Number of allowed retries @@ -38,6 +39,11 @@ enum { SD_MEMPOOL_SIZE = 2, /* CDB pool size */ }; +enum { + SD_MAX_WS10_BLOCKS = 0xffff, + SD_MAX_WS16_BLOCKS = 0x7fffff, +}; + enum { SD_LBP_FULL = 0, /* Full logical block provisioning */ SD_LBP_UNMAP, /* Use UNMAP command */ @@ -77,6 +83,7 @@ struct scsi_disk { unsigned lbpws : 1; unsigned lbpws10 : 1; unsigned lbpvpd : 1; + unsigned ws16 : 1; }; #define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 6ab376a7c50..92f35abee92 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -189,6 +189,9 @@ static int slave_configure(struct scsi_device *sdev) /* Do not attempt to use REPORT SUPPORTED OPERATION CODES */ sdev->no_report_opcodes = 1; + /* Do not attempt to use WRITE SAME */ + sdev->no_write_same = 1; + /* Some disks return the total number of blocks in response * to READ CAPACITY rather than the highest block number. * If this device makes that mistake, tell the sd driver. */ diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 379d465e807..55367b04dc9 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -136,6 +136,7 @@ struct scsi_device { unsigned use_10_for_rw:1; /* first try 10-byte read / write */ unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ + unsigned no_write_same:1; /* no WRITE SAME command */ unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */ unsigned skip_vpd_pages:1; /* do not read VPD pages */ -- cgit v1.2.3 From effded75e24c7941961d473e4f4babed4c52af3c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 14 Nov 2012 11:23:54 +0300 Subject: ALSA: fm801: precedence bug in snd_fm801_tea575x_get_pins() There is a precedence bug because | has higher precedence than ?:. This code was cut and pasted and I fixed a similar bug a few days ago. Signed-off-by: Dan Carpenter Signed-off-by: Takashi Iwai --- sound/pci/fm801.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index cc2e91d1553..c5806f89be1 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -767,9 +767,14 @@ static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea) struct fm801 *chip = tea->private_data; unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); - - return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 | - (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0; + u8 ret; + + ret = 0; + if (reg & FM801_GPIO_GP(gpio.data)) + ret |= TEA575X_DATA; + if (reg & FM801_GPIO_GP(gpio.most)) + ret |= TEA575X_MOST; + return ret; } static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output) -- cgit v1.2.3 From 0d852fe4d27fa82de9fdcbda9a5ac634800b1fd1 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Tue, 13 Nov 2012 16:43:21 +0100 Subject: i2c: at91: fix SMBus quick command The driver claims to support SMBus quick command but it was not the case. This patch fixes this issue. Without it, i2cdetect finds imaginary devices. And with some IP versions, trying to send 0 byte can cause issue when writing data to an EEPROM. Signed-off-by: Ludovic Desroches Acked-by: Jean-Christophe PLAGNIOL-VILLARD [wsa: improved the commit message] Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-at91.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index aa59a254be2..c02bf208084 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -39,6 +39,7 @@ #define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */ #define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */ #define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */ +#define AT91_TWI_QUICK 0x0040 /* SMBus quick command */ #define AT91_TWI_SWRST 0x0080 /* Software Reset */ #define AT91_TWI_MMR 0x0004 /* Master Mode Register */ @@ -212,7 +213,11 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev) INIT_COMPLETION(dev->cmd_complete); dev->transfer_status = 0; - if (dev->msg->flags & I2C_M_RD) { + + if (!dev->buf_len) { + at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK); + at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP); + } else if (dev->msg->flags & I2C_M_RD) { unsigned start_flags = AT91_TWI_START; if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) { -- cgit v1.2.3 From 23ff2f0f6128b4c310fbb274dbb91cc2f9b6ab06 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 14 Nov 2012 09:39:31 +0000 Subject: regulator: core: Avoid deadlock when regulator_register fails When regulator_register fails and exits through the scrub path the regulator_put function was called whilst holding the regulator_list_mutex, causing deadlock. This patch adds a private version of the regulator_put function which can be safely called whilst holding the mutex, replacing the aforementioned call. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- drivers/regulator/core.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5c4829cba6a..3ebc06b280a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1381,22 +1381,14 @@ struct regulator *regulator_get_exclusive(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(regulator_get_exclusive); -/** - * regulator_put - "free" the regulator source - * @regulator: regulator source - * - * Note: drivers must ensure that all regulator_enable calls made on this - * regulator source are balanced by regulator_disable calls prior to calling - * this function. - */ -void regulator_put(struct regulator *regulator) +/* Locks held by regulator_put() */ +static void _regulator_put(struct regulator *regulator) { struct regulator_dev *rdev; if (regulator == NULL || IS_ERR(regulator)) return; - mutex_lock(®ulator_list_mutex); rdev = regulator->rdev; debugfs_remove_recursive(regulator->debugfs); @@ -1412,6 +1404,20 @@ void regulator_put(struct regulator *regulator) rdev->exclusive = 0; module_put(rdev->owner); +} + +/** + * regulator_put - "free" the regulator source + * @regulator: regulator source + * + * Note: drivers must ensure that all regulator_enable calls made on this + * regulator source are balanced by regulator_disable calls prior to calling + * this function. + */ +void regulator_put(struct regulator *regulator) +{ + mutex_lock(®ulator_list_mutex); + _regulator_put(regulator); mutex_unlock(®ulator_list_mutex); } EXPORT_SYMBOL_GPL(regulator_put); @@ -3445,7 +3451,7 @@ unset_supplies: scrub: if (rdev->supply) - regulator_put(rdev->supply); + _regulator_put(rdev->supply); if (rdev->ena_gpio) gpio_free(rdev->ena_gpio); kfree(rdev->constraints); -- cgit v1.2.3 From 04baaa27b43d389879237b32f8bd194a94cf1ca7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 13 Nov 2012 21:28:44 +0100 Subject: iwlwifi: fix monitor mode FCS flag When the firmware is in SNIFFER mode, it leaves the FCS at the end of frame. Not telling mac80211 means it won't add the right flag to the radiotap header and that confuses wireshark. Since mac80211 doesn't have a per-packet flag, set the HW flag dynamically. This works as the monitor vif can only be present in the driver by itself. This fixes a regression introduced by my commit 578977264199de9815ace51ade87cec4894cf010 Author: Johannes Berg Date: Fri May 11 10:53:18 2012 +0200 iwlwifi: support explicit monitor interface Cc: stable@vger.kernel.org [3.5+] Reported-by: MARK PHILLIPS Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/mac80211.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index fa4d1b8cd9f..2d9eee93c74 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -1354,6 +1354,20 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, vif_priv->ctx = ctx; ctx->vif = vif; + /* + * In SNIFFER device type, the firmware reports the FCS to + * the host, rather than snipping it off. Unfortunately, + * mac80211 doesn't (yet) provide a per-packet flag for + * this, so that we have to set the hardware flag based + * on the interfaces added. As the monitor interface can + * only be present by itself, and will be removed before + * other interfaces are added, this is safe. + */ + if (vif->type == NL80211_IFTYPE_MONITOR) + priv->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS; + else + priv->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; + err = iwl_setup_interface(priv, ctx); if (!err || reset) goto out; -- cgit v1.2.3 From 9aadd70aed60b47e367e7a1a6b9068daba04fe05 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 6 Nov 2012 16:31:32 +0000 Subject: Revert "ARM: OMAP: convert I2C driver to PM QoS for MPU latency constraints" This reverts commit 3db11feffc1ad2ab9dea27789e6b5b3032827adc (ARM: OMAP: convert I2C driver to PM QoS for MPU latency constraints). This commit causes I2C timeouts to appear on several OMAP3430/3530-based boards: http://marc.info/?l=linux-arm-kernel&m=135071372426971&w=2 http://marc.info/?l=linux-arm-kernel&m=135067558415214&w=2 http://marc.info/?l=linux-arm-kernel&m=135216013608196&w=2 and appears to have been sent for merging before one of its prerequisites was merged: http://marc.info/?l=linux-arm-kernel&m=135219411617621&w=2 Signed-off-by: Paul Walmsley Acked-by: Jean Pihet Signed-off-by: Wolfram Sang --- arch/arm/plat-omap/i2c.c | 21 +++++++++++++++++++++ drivers/i2c/busses/i2c-omap.c | 32 ++++++++++++++------------------ include/linux/i2c-omap.h | 1 + 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index a5683a84c6e..6013831a043 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -26,12 +26,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include #define OMAP_I2C_SIZE 0x3f @@ -127,6 +129,16 @@ static inline int omap1_i2c_add_bus(int bus_id) #ifdef CONFIG_ARCH_OMAP2PLUS +/* + * XXX This function is a temporary compatibility wrapper - only + * needed until the I2C driver can be converted to call + * omap_pm_set_max_dev_wakeup_lat() and handle a return code. + */ +static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) +{ + omap_pm_set_max_mpu_wakeup_lat(dev, t); +} + static inline int omap2_i2c_add_bus(int bus_id) { int l; @@ -158,6 +170,15 @@ static inline int omap2_i2c_add_bus(int bus_id) dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr; pdata->flags = dev_attr->flags; + /* + * When waiting for completion of a i2c transfer, we need to + * set a wake up latency constraint for the MPU. This is to + * ensure quick enough wakeup from idle, when transfer + * completes. + * Only omap3 has support for constraints + */ + if (cpu_is_omap34xx()) + pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(struct omap_i2c_bus_platform_data), NULL, 0, 0); diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index db31eaed6ea..0b0254312d2 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -43,7 +43,6 @@ #include #include #include -#include /* I2C controller revisions */ #define OMAP_I2C_OMAP1_REV_2 0x20 @@ -187,8 +186,9 @@ struct omap_i2c_dev { int reg_shift; /* bit shift for I2C register addresses */ struct completion cmd_complete; struct resource *ioarea; - u32 latency; /* maximum MPU wkup latency */ - struct pm_qos_request pm_qos_request; + u32 latency; /* maximum mpu wkup latency */ + void (*set_mpu_wkup_lat)(struct device *dev, + long latency); u32 speed; /* Speed of bus in kHz */ u32 dtrev; /* extra revision from DT */ u32 flags; @@ -494,7 +494,9 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) dev->b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ - dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8); + if (dev->set_mpu_wkup_lat != NULL) + dev->latency = (1000000 * dev->threshold) / + (1000 * dev->speed / 8); } /* @@ -629,16 +631,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) if (r < 0) goto out; - /* - * When waiting for completion of a i2c transfer, we need to - * set a wake up latency constraint for the MPU. This is to - * ensure quick enough wakeup from idle, when transfer - * completes. - */ - if (dev->latency) - pm_qos_add_request(&dev->pm_qos_request, - PM_QOS_CPU_DMA_LATENCY, - dev->latency); + if (dev->set_mpu_wkup_lat != NULL) + dev->set_mpu_wkup_lat(dev->dev, dev->latency); for (i = 0; i < num; i++) { r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1))); @@ -646,8 +640,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) break; } - if (dev->latency) - pm_qos_remove_request(&dev->pm_qos_request); + if (dev->set_mpu_wkup_lat != NULL) + dev->set_mpu_wkup_lat(dev->dev, -1); if (r == 0) r = num; @@ -1104,6 +1098,7 @@ omap_i2c_probe(struct platform_device *pdev) } else if (pdata != NULL) { dev->speed = pdata->clkrate; dev->flags = pdata->flags; + dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat; dev->dtrev = pdata->rev; } @@ -1159,8 +1154,9 @@ omap_i2c_probe(struct platform_device *pdev) dev->b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ - dev->latency = (1000000 * dev->fifo_size) / - (1000 * dev->speed / 8); + if (dev->set_mpu_wkup_lat != NULL) + dev->latency = (1000000 * dev->fifo_size) / + (1000 * dev->speed / 8); } /* reset ASAP, clearing any IRQs */ diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index df804ba73e0..92a0dc75bc7 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -34,6 +34,7 @@ struct omap_i2c_bus_platform_data { u32 clkrate; u32 rev; u32 flags; + void (*set_mpu_wkup_lat)(struct device *dev, long set); }; #endif -- cgit v1.2.3 From 10e44239f67d0b6fb74006e61a7e883b8075247a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 13 Nov 2012 11:22:48 +0100 Subject: ALSA: usb-audio: Fix mutex deadlock at disconnection The recent change for USB-audio disconnection race fixes introduced a mutex deadlock again. There is a circular dependency between chip->shutdown_rwsem and pcm->open_mutex, depicted like below, when a device is opened during the disconnection operation: A. snd_usb_audio_disconnect() -> card.c::register_mutex -> chip->shutdown_rwsem (write) -> snd_card_disconnect() -> pcm.c::register_mutex -> pcm->open_mutex B. snd_pcm_open() -> pcm->open_mutex -> snd_usb_pcm_open() -> chip->shutdown_rwsem (read) Since the chip->shutdown_rwsem protection in the case A is required only for turning on the chip->shutdown flag and it doesn't have to be taken for the whole operation, we can reduce its window in snd_usb_audio_disconnect(). Reported-by: Jiri Slaby Cc: Signed-off-by: Takashi Iwai --- sound/usb/card.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/usb/card.c b/sound/usb/card.c index 282f0fc9fed..dbf7999d18b 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -559,9 +559,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, return; card = chip->card; - mutex_lock(®ister_mutex); down_write(&chip->shutdown_rwsem); chip->shutdown = 1; + up_write(&chip->shutdown_rwsem); + + mutex_lock(®ister_mutex); chip->num_interfaces--; if (chip->num_interfaces <= 0) { snd_card_disconnect(card); @@ -582,11 +584,9 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, snd_usb_mixer_disconnect(p); } usb_chip[chip->index] = NULL; - up_write(&chip->shutdown_rwsem); mutex_unlock(®ister_mutex); snd_card_free_when_closed(card); } else { - up_write(&chip->shutdown_rwsem); mutex_unlock(®ister_mutex); } } -- cgit v1.2.3 From aedc256dd032fe9b0691fdd0f67b5e65e3e7bc0d Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 14 Nov 2012 16:22:45 +0200 Subject: i2c: omap: ensure writes to dev->buf_len are ordered if we allow compiler reorder our writes, we could fall into a situation where dev->buf_len is reset for no apparent reason. This bug was found with a simple script which would transfer data to an i2c client from 1 to 1024 bytes (a simple for loop), when we got to transfer sizes bigger than the fifo size, dev->buf_len was reset to zero before we had an oportunity to handle XDR Interrupt. Because dev->buf_len was zero, we entered omap_i2c_transmit_data() to transfer zero bytes, which would mean we would just silently exit omap_i2c_transmit_data() without actually writing anything to DATA register. That would cause XDR IRQ to trigger forever and we would never transfer the remaining bytes. After adding the memory barrier, we also drop resetting dev->buf_len to zero in omap_i2c_xfer_msg() because both omap_i2c_transmit_data() and omap_i2c_receive_data() will act until dev->buf_len reaches zero, rendering the other write in omap_i2c_xfer_msg() redundant. This patch has been tested with pandaboard for a few iterations of the script mentioned above. Signed-off-by: Felipe Balbi Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-omap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 0b0254312d2..3525c9e62cb 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -524,6 +524,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, dev->buf = msg->buf; dev->buf_len = msg->len; + /* make sure writes to dev->buf_len are ordered */ + barrier(); + omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len); /* Clear the FIFO Buffers */ @@ -581,7 +584,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, */ timeout = wait_for_completion_timeout(&dev->cmd_complete, OMAP_I2C_TIMEOUT); - dev->buf_len = 0; if (timeout == 0) { dev_err(dev->dev, "controller timed out\n"); omap_i2c_init(dev); -- cgit v1.2.3 From 65b6ecc03838fd263cf7fafdfa6cf13012b91d56 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 14 Nov 2012 18:27:07 +0100 Subject: uprobes: Flush cache after xol write Flush the cache so that the instructions written to the XOL area are visible. Signed-off-by: Rabin Vincent Acked-by: Ananth N Mavinakayanahalli Signed-off-by: Oleg Nesterov --- kernel/events/uprobes.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 39c75cc51ef..5ce99cfd2e6 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1199,6 +1199,11 @@ static unsigned long xol_get_insn_slot(struct uprobe *uprobe, unsigned long slot vaddr = kmap_atomic(area->page); memcpy(vaddr + offset, uprobe->arch.insn, MAX_UINSN_BYTES); kunmap_atomic(vaddr); + /* + * We probably need flush_icache_user_range() but it needs vma. + * This should work on supported architectures too. + */ + flush_dcache_page(area->page); return current->utask->xol_vaddr; } -- cgit v1.2.3 From f78cff48c3d13636705851b0a9e733db117d58ee Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:38 -0800 Subject: doc: Add x86 CPU0 online/offline feature If CONFIG_BOOTPARAM_HOTPLUG_CPU0 is turned on, CPU0 is hotpluggable. Otherwise, by default CPU0 is not hotpluggable and kernel parameter cpu0_hotplug enables CPU0 online/offline feature. The documentations point out two known CPU0 dependencies. First, resume from hibernate or suspend always starts from CPU0. So hibernate and suspend are prevented if CPU0 is offline. Another dependency is PIC interrupts always go to CPU0. It's said that some machines may depend on CPU0 to poweroff/reboot. But I haven't seen such dependency on a few tested machines. Please let me know if you see any CPU0 dependencies on your machine. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-2-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- Documentation/cpu-hotplug.txt | 24 ++++++++++++++++++++++++ Documentation/kernel-parameters.txt | 14 ++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index 66ef8f35613..9f401350f50 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt @@ -207,6 +207,30 @@ by making it not-removable. In such cases you will also notice that the online file is missing under cpu0. +Q: Is CPU0 removable on X86? +A: Yes. If kernel is compiled with CONFIG_BOOTPARAM_HOTPLUG_CPU0=y, CPU0 is +removable by default. Otherwise, CPU0 is also removable by kernel option +cpu0_hotplug. + +But some features depend on CPU0. Two known dependencies are: + +1. Resume from hibernate/suspend depends on CPU0. Hibernate/suspend will fail if +CPU0 is offline and you need to online CPU0 before hibernate/suspend can +continue. +2. PIC interrupts also depend on CPU0. CPU0 can't be removed if a PIC interrupt +is detected. + +It's said poweroff/reboot may depend on CPU0 on some machines although I haven't +seen any poweroff/reboot failure so far after CPU0 is offline on a few tested +machines. + +Please let me know if you know or see any other dependencies of CPU0. + +If the dependencies are under your control, you can turn on CPU0 hotplug feature +either by CONFIG_BOOTPARAM_HOTPLUG_CPU0 or by kernel parameter cpu0_hotplug. + +--Fenghua Yu + Q: How do i find out if a particular CPU is not removable? A: Depending on the implementation, some architectures may show this by the absence of the "online" file. This is done if it can be determined ahead of diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 9776f068306..f7cbe1d98cb 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1984,6 +1984,20 @@ bytes respectively. Such letter suffixes can also be entirely omitted. nox2apic [X86-64,APIC] Do not enable x2APIC mode. + cpu0_hotplug [X86] Turn on CPU0 hotplug feature when + CONFIG_BOOTPARAM_HOTPLUG_CPU0 is off. + Some features depend on CPU0. Known dependencies are: + 1. Resume from suspend/hibernate depends on CPU0. + Suspend/hibernate will fail if CPU0 is offline and you + need to online CPU0 before suspend/hibernate. + 2. PIC interrupts also depend on CPU0. CPU0 can't be + removed if a PIC interrupt is detected. + It's said poweroff/reboot may depend on CPU0 on some + machines although I haven't seen such issues so far + after CPU0 is offline on a few tested machines. + If the dependencies are under your control, you can + turn on cpu0_hotplug. + nptcg= [IA-64] Override max number of concurrent global TLB purges which is reported from either PAL_VM_SUMMARY or SAL PALO. -- cgit v1.2.3 From 80aa1dff65717e7518647d4e27d1d3dcea5818e6 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:39 -0800 Subject: x86, Kconfig: Add config switch for CPU0 hotplug New config switch CONFIG_BOOTPARAM_HOTPLUG_CPU0 sets default state of whether the CPU0 hotplug is on or off. If the switch is off, CPU0 is not hotpluggable by default. But the CPU0 hotplug feature can still be turned on by kernel parameter cpu0_hotplug at boot. If the switch is on, CPU0 is always hotpluggable. The default value of the switch is off. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-3-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/Kconfig | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 46c3bff3ced..036e89ab470 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1698,6 +1698,35 @@ config HOTPLUG_CPU automatically on SMP systems. ) Say N if you want to disable CPU hotplug. +config BOOTPARAM_HOTPLUG_CPU0 + bool "Set default setting of cpu0_hotpluggable" + default n + depends on HOTPLUG_CPU && EXPERIMENTAL + ---help--- + Set whether default state of cpu0_hotpluggable is on or off. + + Say Y here to enable CPU0 hotplug by default. If this switch + is turned on, there is no need to give cpu0_hotplug kernel + parameter and the CPU0 hotplug feature is enabled by default. + + Please note: there are two known CPU0 dependencies if you want + to enable the CPU0 hotplug feature either by this switch or by + cpu0_hotplug kernel parameter. + + First, resume from hibernate or suspend always starts from CPU0. + So hibernate and suspend are prevented if CPU0 is offline. + + Second dependency is PIC interrupts always go to CPU0. CPU0 can not + offline if any interrupt can not migrate out of CPU0. There may + be other CPU0 dependencies. + + Please make sure the dependencies are under your control before + you enable this feature. + + Say N if you don't want to enable CPU0 hotplug feature by default. + You still can enable the CPU0 hotplug feature at boot by kernel + parameter cpu0_hotplug. + config COMPAT_VDSO def_bool y prompt "Compat VDSO support" -- cgit v1.2.3 From 4d25031a81d3cd32edc00de6596db76cc4010685 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:40 -0800 Subject: x86, topology: Don't offline CPU0 if any PIC irq can not be migrated out of it If CONFIG_BOOTPARAM_HOTPLUG_CPU is turned on, CPU0 hotplug feature is enabled by default. If CONFIG_BOOTPARAM_HOTPLUG_CPU is not turned on, CPU0 hotplug feature is not enabled by default. The kernel parameter cpu0_hotplug can enable CPU0 hotplug feature at boot. Currently the feature is supported on Intel platforms only. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-4-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/topology.c | 50 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c index 76ee97709a0..0e7b4a7a7fb 100644 --- a/arch/x86/kernel/topology.c +++ b/arch/x86/kernel/topology.c @@ -30,23 +30,59 @@ #include #include #include +#include #include static DEFINE_PER_CPU(struct x86_cpu, cpu_devices); #ifdef CONFIG_HOTPLUG_CPU + +#ifdef CONFIG_BOOTPARAM_HOTPLUG_CPU0 +static int cpu0_hotpluggable = 1; +#else +static int cpu0_hotpluggable; +static int __init enable_cpu0_hotplug(char *str) +{ + cpu0_hotpluggable = 1; + return 1; +} + +__setup("cpu0_hotplug", enable_cpu0_hotplug); +#endif + int __ref arch_register_cpu(int num) { + struct cpuinfo_x86 *c = &cpu_data(num); + + /* + * Currently CPU0 is only hotpluggable on Intel platforms. Other + * vendors can add hotplug support later. + */ + if (c->x86_vendor != X86_VENDOR_INTEL) + cpu0_hotpluggable = 0; + /* - * CPU0 cannot be offlined due to several - * restrictions and assumptions in kernel. This basically - * doesn't add a control file, one cannot attempt to offline - * BSP. + * Two known BSP/CPU0 dependencies: Resume from suspend/hibernate + * depends on BSP. PIC interrupts depend on BSP. * - * Also certain PCI quirks require not to enable hotplug control - * for all CPU's. + * If the BSP depencies are under control, one can tell kernel to + * enable BSP hotplug. This basically adds a control file and + * one can attempt to offline BSP. */ - if (num) + if (num == 0 && cpu0_hotpluggable) { + unsigned int irq; + /* + * We won't take down the boot processor on i386 if some + * interrupts only are able to be serviced by the BSP in PIC. + */ + for_each_active_irq(irq) { + if (!IO_APIC_IRQ(irq) && irq_has_action(irq)) { + cpu0_hotpluggable = 0; + break; + } + } + } + if (num || cpu0_hotpluggable) per_cpu(cpu_devices, num).cpu.hotpluggable = 1; return register_cpu(&per_cpu(cpu_devices, num).cpu, num); -- cgit v1.2.3 From 30106c174311b8cfaaa3186c7f6f9c36c62d17da Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:41 -0800 Subject: x86, hotplug: Support functions for CPU0 online/offline Add smp_store_boot_cpu_info() to store cpu info for BSP during boot time. Now smp_store_cpu_info() stores cpu info for bringing up BSP or AP after it's offline. Continue to online CPU0 in native_cpu_up(). Continue to offline CPU0 in native_cpu_disable(). Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-5-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/smp.h | 1 + arch/x86/kernel/smpboot.c | 38 ++++++++++++++++++-------------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 4f19a152603..b073aaea747 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -166,6 +166,7 @@ void native_send_call_func_ipi(const struct cpumask *mask); void native_send_call_func_single_ipi(int cpu); void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle); +void smp_store_boot_cpu_info(void); void smp_store_cpu_info(int id); #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index c80a33bc528..c297907f3c7 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -125,8 +125,8 @@ EXPORT_PER_CPU_SYMBOL(cpu_info); atomic_t init_deasserted; /* - * Report back to the Boot Processor. - * Running on AP. + * Report back to the Boot Processor during boot time or to the caller processor + * during CPU online. */ static void __cpuinit smp_callin(void) { @@ -279,19 +279,30 @@ notrace static void __cpuinit start_secondary(void *unused) cpu_idle(); } +void __init smp_store_boot_cpu_info(void) +{ + int id = 0; /* CPU 0 */ + struct cpuinfo_x86 *c = &cpu_data(id); + + *c = boot_cpu_data; + c->cpu_index = id; +} + /* * The bootstrap kernel entry code has set these up. Save them for * a given CPU */ - void __cpuinit smp_store_cpu_info(int id) { struct cpuinfo_x86 *c = &cpu_data(id); *c = boot_cpu_data; c->cpu_index = id; - if (id != 0) - identify_secondary_cpu(c); + /* + * During boot time, CPU0 has this setup already. Save the info when + * bringing up AP or offlined CPU0. + */ + identify_secondary_cpu(c); } static bool __cpuinit @@ -795,7 +806,7 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle) pr_debug("++++++++++++++++++++=_---CPU UP %u\n", cpu); - if (apicid == BAD_APICID || apicid == boot_cpu_physical_apicid || + if (apicid == BAD_APICID || !physid_isset(apicid, phys_cpu_present_map) || !apic->apic_id_valid(apicid)) { pr_err("%s: bad cpu %d\n", __func__, cpu); @@ -990,7 +1001,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) /* * Setup boot CPU information */ - smp_store_cpu_info(0); /* Final full version of the data */ + smp_store_boot_cpu_info(); /* Final full version of the data */ cpumask_copy(cpu_callin_mask, cpumask_of(0)); mb(); @@ -1214,19 +1225,6 @@ void cpu_disable_common(void) int native_cpu_disable(void) { - int cpu = smp_processor_id(); - - /* - * Perhaps use cpufreq to drop frequency, but that could go - * into generic code. - * - * We won't take down the boot processor on i386 due to some - * interrupts only being able to be serviced by the BSP. - * Especially so if we're not using an IOAPIC -zwane - */ - if (cpu == 0) - return -EBUSY; - clear_local_APIC(); cpu_disable_common(); -- cgit v1.2.3 From 209efae12981f3d2d694499b761def10895c078c Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:42 -0800 Subject: x86, hotplug, suspend: Online CPU0 for suspend or hibernate Because x86 BIOS requires CPU0 to resume from sleep, suspend or hibernate can't be executed if CPU0 is detected offline. To make suspend or hibernate and further resume succeed, CPU0 must be online. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-6-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/power/cpu.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index 218cdb16163..adde77588e2 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -237,3 +237,47 @@ void restore_processor_state(void) #ifdef CONFIG_X86_32 EXPORT_SYMBOL(restore_processor_state); #endif + +/* + * When bsp_check() is called in hibernate and suspend, cpu hotplug + * is disabled already. So it's unnessary to handle race condition between + * cpumask query and cpu hotplug. + */ +static int bsp_check(void) +{ + if (cpumask_first(cpu_online_mask) != 0) { + pr_warn("CPU0 is offline.\n"); + return -ENODEV; + } + + return 0; +} + +static int bsp_pm_callback(struct notifier_block *nb, unsigned long action, + void *ptr) +{ + int ret = 0; + + switch (action) { + case PM_SUSPEND_PREPARE: + case PM_HIBERNATION_PREPARE: + ret = bsp_check(); + break; + default: + break; + } + return notifier_from_errno(ret); +} + +static int __init bsp_pm_check_init(void) +{ + /* + * Set this bsp_pm_callback as lower priority than + * cpu_hotplug_pm_callback. So cpu_hotplug_pm_callback will be called + * earlier to disable cpu hotplug before bsp online check. + */ + pm_notifier(bsp_pm_callback, -INT_MAX); + return 0; +} + +core_initcall(bsp_pm_check_init); -- cgit v1.2.3 From 6e32d479db6079dd5d4309aa66aecbcf2664a5fe Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:43 -0800 Subject: kernel/cpu.c: Add comment for priority in cpu_hotplug_pm_callback cpu_hotplug_pm_callback should have higher priority than bsp_pm_callback which depends on cpu_hotplug_pm_callback to disable cpu hotplug to avoid race during bsp online checking. This is to hightlight the priorities between the two callbacks in case people may overlook the order. Ideally the priorities should be defined in macro/enum instead of fixed values. To do that, a seperate patchset may be pushed which will touch serveral other generic files and is out of scope of this patchset. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-7-git-send-email-fenghua.yu@intel.com Reviewed-by: Srivatsa S. Bhat Acked-by: Rafael J. Wysocki Signed-off-by: H. Peter Anvin --- kernel/cpu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/cpu.c b/kernel/cpu.c index 42bd331ee0a..a2491a2d62b 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -601,6 +601,11 @@ cpu_hotplug_pm_callback(struct notifier_block *nb, static int __init cpu_hotplug_pm_sync_init(void) { + /* + * cpu_hotplug_pm_callback has higher priority than x86 + * bsp_pm_callback which depends on cpu_hotplug_pm_callback + * to disable cpu hotplug to avoid cpu hotplug race. + */ pm_notifier(cpu_hotplug_pm_callback, 0); return 0; } -- cgit v1.2.3 From 42e78e9719aa0c76711e2731b19c90fe5ae05278 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:44 -0800 Subject: x86-64, hotplug: Add start_cpu0() entry point to head_64.S start_cpu0() is defined in head_64.S for 64-bit. The function sets up stack and jumps to start_secondary() for CPU0 wake up. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-8-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/head_64.S | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 94bf9cc2c7e..980053c4b9c 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -252,6 +252,22 @@ ENTRY(secondary_startup_64) pushq %rax # target address in negative space lretq +#ifdef CONFIG_HOTPLUG_CPU +/* + * Boot CPU0 entry point. It's called from play_dead(). Everything has been set + * up already except stack. We just set up stack here. Then call + * start_secondary(). + */ +ENTRY(start_cpu0) + movq stack_start(%rip),%rsp + movq initial_code(%rip),%rax + pushq $0 # fake return address to stop unwinder + pushq $__KERNEL_CS # set correct cs + pushq %rax # target address in negative space + lretq +ENDPROC(start_cpu0) +#endif + /* SMP bootup changes these two */ __REFDATA .align 8 -- cgit v1.2.3 From 3e2a0cc3cdc19e0518ae87583add40ea1bf55b67 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:45 -0800 Subject: x86-32, hotplug: Add start_cpu0() entry point to head_32.S start_cpu0() is defined in head_32.S for 32-bit. The function sets up stack and jumps to start_secondary() for CPU0 wake up. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-9-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/head_32.S | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 957a47aec64..a013e7390ab 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -266,6 +266,19 @@ num_subarch_entries = (. - subarch_entries) / 4 jmp default_entry #endif /* CONFIG_PARAVIRT */ +#ifdef CONFIG_HOTPLUG_CPU +/* + * Boot CPU0 entry point. It's called from play_dead(). Everything has been set + * up already except stack. We just set up stack here. Then call + * start_secondary(). + */ +ENTRY(start_cpu0) + movl stack_start, %ecx + movl %ecx, %esp + jmp *(initial_code) +ENDPROC(start_cpu0) +#endif + /* * Non-boot CPU entry point; entered from trampoline.S * We can't lgdt here, because lgdt itself uses a data segment, but -- cgit v1.2.3 From d61f978b8f26d2392c88249f877e46e2c2b5561d Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sun, 4 Nov 2012 23:13:09 +0100 Subject: brcmfmac: fix typo in CONFIG_BRCMISCAN The old ifdef CONFIG_BRCMFISCAN looks wrong to me and it makes more sense when CONFIG_BRCMISCAN is used. This patch was just compile tested by me, but not runtime tested. Signed-off-by: Hauke Mehrtens Acked-by: Franky Lin Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index a6f1e816600..481345c23de 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -4401,7 +4401,7 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode) static void brcmf_wiphy_pno_params(struct wiphy *wiphy) { -#ifndef CONFIG_BRCMFISCAN +#ifndef CONFIG_BRCMISCAN /* scheduled scan settings */ wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; -- cgit v1.2.3 From 0a4e1ae6808a28a92573550603121b146b11312e Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Nov 2012 01:46:41 +0100 Subject: perf tests: Move test__vmlinux_matches_kallsyms into separate object Separating test__vmlinux_matches_kallsyms test from the builtin-test into vmlinux-kallsyms object. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352508412-16914-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 + tools/perf/tests/builtin-test.c | 223 +--------------------------------- tools/perf/tests/tests.h | 6 + tools/perf/tests/vmlinux-kallsyms.c | 230 ++++++++++++++++++++++++++++++++++++ 4 files changed, 239 insertions(+), 221 deletions(-) create mode 100644 tools/perf/tests/tests.h create mode 100644 tools/perf/tests/vmlinux-kallsyms.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index cca5bb8334a..7c7ba4d6daf 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -431,6 +431,7 @@ LIB_OBJS += $(OUTPUT)arch/common.o LIB_OBJS += $(OUTPUT)tests/parse-events.o LIB_OBJS += $(OUTPUT)tests/dso-data.o LIB_OBJS += $(OUTPUT)tests/attr.o +LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o BUILTIN_OBJS += $(OUTPUT)builtin-bench.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 5d4354e2445..5bc9063bf30 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -21,231 +21,12 @@ #include -static int vmlinux_matches_kallsyms_filter(struct map *map __maybe_unused, - struct symbol *sym) -{ - bool *visited = symbol__priv(sym); - *visited = true; - return 0; -} - -static int test__vmlinux_matches_kallsyms(void) -{ - int err = -1; - struct rb_node *nd; - struct symbol *sym; - struct map *kallsyms_map, *vmlinux_map; - struct machine kallsyms, vmlinux; - enum map_type type = MAP__FUNCTION; - struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", }; - - /* - * Step 1: - * - * Init the machines that will hold kernel, modules obtained from - * both vmlinux + .ko files and from /proc/kallsyms split by modules. - */ - machine__init(&kallsyms, "", HOST_KERNEL_ID); - machine__init(&vmlinux, "", HOST_KERNEL_ID); - - /* - * Step 2: - * - * Create the kernel maps for kallsyms and the DSO where we will then - * load /proc/kallsyms. Also create the modules maps from /proc/modules - * and find the .ko files that match them in /lib/modules/`uname -r`/. - */ - if (machine__create_kernel_maps(&kallsyms) < 0) { - pr_debug("machine__create_kernel_maps "); - return -1; - } - - /* - * Step 3: - * - * Load and split /proc/kallsyms into multiple maps, one per module. - */ - if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type, NULL) <= 0) { - pr_debug("dso__load_kallsyms "); - goto out; - } - - /* - * Step 4: - * - * kallsyms will be internally on demand sorted by name so that we can - * find the reference relocation * symbol, i.e. the symbol we will use - * to see if the running kernel was relocated by checking if it has the - * same value in the vmlinux file we load. - */ - kallsyms_map = machine__kernel_map(&kallsyms, type); - - sym = map__find_symbol_by_name(kallsyms_map, ref_reloc_sym.name, NULL); - if (sym == NULL) { - pr_debug("dso__find_symbol_by_name "); - goto out; - } - - ref_reloc_sym.addr = sym->start; - - /* - * Step 5: - * - * Now repeat step 2, this time for the vmlinux file we'll auto-locate. - */ - if (machine__create_kernel_maps(&vmlinux) < 0) { - pr_debug("machine__create_kernel_maps "); - goto out; - } - - vmlinux_map = machine__kernel_map(&vmlinux, type); - map__kmap(vmlinux_map)->ref_reloc_sym = &ref_reloc_sym; - - /* - * Step 6: - * - * Locate a vmlinux file in the vmlinux path that has a buildid that - * matches the one of the running kernel. - * - * While doing that look if we find the ref reloc symbol, if we find it - * we'll have its ref_reloc_symbol.unrelocated_addr and then - * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines - * to fixup the symbols. - */ - if (machine__load_vmlinux_path(&vmlinux, type, - vmlinux_matches_kallsyms_filter) <= 0) { - pr_debug("machine__load_vmlinux_path "); - goto out; - } - - err = 0; - /* - * Step 7: - * - * Now look at the symbols in the vmlinux DSO and check if we find all of them - * in the kallsyms dso. For the ones that are in both, check its names and - * end addresses too. - */ - for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) { - struct symbol *pair, *first_pair; - bool backwards = true; - - sym = rb_entry(nd, struct symbol, rb_node); - - if (sym->start == sym->end) - continue; - - first_pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL); - pair = first_pair; - - if (pair && pair->start == sym->start) { -next_pair: - if (strcmp(sym->name, pair->name) == 0) { - /* - * kallsyms don't have the symbol end, so we - * set that by using the next symbol start - 1, - * in some cases we get this up to a page - * wrong, trace_kmalloc when I was developing - * this code was one such example, 2106 bytes - * off the real size. More than that and we - * _really_ have a problem. - */ - s64 skew = sym->end - pair->end; - if (llabs(skew) < page_size) - continue; - - pr_debug("%#" PRIx64 ": diff end addr for %s v: %#" PRIx64 " k: %#" PRIx64 "\n", - sym->start, sym->name, sym->end, pair->end); - } else { - struct rb_node *nnd; -detour: - nnd = backwards ? rb_prev(&pair->rb_node) : - rb_next(&pair->rb_node); - if (nnd) { - struct symbol *next = rb_entry(nnd, struct symbol, rb_node); - - if (next->start == sym->start) { - pair = next; - goto next_pair; - } - } - - if (backwards) { - backwards = false; - pair = first_pair; - goto detour; - } - - pr_debug("%#" PRIx64 ": diff name v: %s k: %s\n", - sym->start, sym->name, pair->name); - } - } else - pr_debug("%#" PRIx64 ": %s not on kallsyms\n", sym->start, sym->name); - - err = -1; - } - - if (!verbose) - goto out; - - pr_info("Maps only in vmlinux:\n"); - - for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) { - struct map *pos = rb_entry(nd, struct map, rb_node), *pair; - /* - * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while - * the kernel will have the path for the vmlinux file being used, - * so use the short name, less descriptive but the same ("[kernel]" in - * both cases. - */ - pair = map_groups__find_by_name(&kallsyms.kmaps, type, - (pos->dso->kernel ? - pos->dso->short_name : - pos->dso->name)); - if (pair) - pair->priv = 1; - else - map__fprintf(pos, stderr); - } - - pr_info("Maps in vmlinux with a different name in kallsyms:\n"); - - for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) { - struct map *pos = rb_entry(nd, struct map, rb_node), *pair; - - pair = map_groups__find(&kallsyms.kmaps, type, pos->start); - if (pair == NULL || pair->priv) - continue; - - if (pair->start == pos->start) { - pair->priv = 1; - pr_info(" %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as", - pos->start, pos->end, pos->pgoff, pos->dso->name); - if (pos->pgoff != pair->pgoff || pos->end != pair->end) - pr_info(": \n*%" PRIx64 "-%" PRIx64 " %" PRIx64 "", - pair->start, pair->end, pair->pgoff); - pr_info(" %s\n", pair->dso->name); - pair->priv = 1; - } - } - - pr_info("Maps only in kallsyms:\n"); - - for (nd = rb_first(&kallsyms.kmaps.maps[type]); - nd; nd = rb_next(nd)) { - struct map *pos = rb_entry(nd, struct map, rb_node); - - if (!pos->priv) - map__fprintf(pos, stderr); - } -out: - return err; -} - #include "util/cpumap.h" #include "util/evsel.h" #include +#include "tests.h" + static int trace_event__id(const char *evname) { char *filename; diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h new file mode 100644 index 00000000000..2223de5ad29 --- /dev/null +++ b/tools/perf/tests/tests.h @@ -0,0 +1,6 @@ +#ifndef TESTS_H +#define TESTS_H + +int test__vmlinux_matches_kallsyms(void); + +#endif /* TESTS_H */ diff --git a/tools/perf/tests/vmlinux-kallsyms.c b/tools/perf/tests/vmlinux-kallsyms.c new file mode 100644 index 00000000000..0d1cdbee2f5 --- /dev/null +++ b/tools/perf/tests/vmlinux-kallsyms.c @@ -0,0 +1,230 @@ +#include +#include +#include +#include "map.h" +#include "symbol.h" +#include "util.h" +#include "tests.h" +#include "debug.h" +#include "machine.h" + +static int vmlinux_matches_kallsyms_filter(struct map *map __maybe_unused, + struct symbol *sym) +{ + bool *visited = symbol__priv(sym); + *visited = true; + return 0; +} + +int test__vmlinux_matches_kallsyms(void) +{ + int err = -1; + struct rb_node *nd; + struct symbol *sym; + struct map *kallsyms_map, *vmlinux_map; + struct machine kallsyms, vmlinux; + enum map_type type = MAP__FUNCTION; + struct ref_reloc_sym ref_reloc_sym = { .name = "_stext", }; + + /* + * Step 1: + * + * Init the machines that will hold kernel, modules obtained from + * both vmlinux + .ko files and from /proc/kallsyms split by modules. + */ + machine__init(&kallsyms, "", HOST_KERNEL_ID); + machine__init(&vmlinux, "", HOST_KERNEL_ID); + + /* + * Step 2: + * + * Create the kernel maps for kallsyms and the DSO where we will then + * load /proc/kallsyms. Also create the modules maps from /proc/modules + * and find the .ko files that match them in /lib/modules/`uname -r`/. + */ + if (machine__create_kernel_maps(&kallsyms) < 0) { + pr_debug("machine__create_kernel_maps "); + return -1; + } + + /* + * Step 3: + * + * Load and split /proc/kallsyms into multiple maps, one per module. + */ + if (machine__load_kallsyms(&kallsyms, "/proc/kallsyms", type, NULL) <= 0) { + pr_debug("dso__load_kallsyms "); + goto out; + } + + /* + * Step 4: + * + * kallsyms will be internally on demand sorted by name so that we can + * find the reference relocation * symbol, i.e. the symbol we will use + * to see if the running kernel was relocated by checking if it has the + * same value in the vmlinux file we load. + */ + kallsyms_map = machine__kernel_map(&kallsyms, type); + + sym = map__find_symbol_by_name(kallsyms_map, ref_reloc_sym.name, NULL); + if (sym == NULL) { + pr_debug("dso__find_symbol_by_name "); + goto out; + } + + ref_reloc_sym.addr = sym->start; + + /* + * Step 5: + * + * Now repeat step 2, this time for the vmlinux file we'll auto-locate. + */ + if (machine__create_kernel_maps(&vmlinux) < 0) { + pr_debug("machine__create_kernel_maps "); + goto out; + } + + vmlinux_map = machine__kernel_map(&vmlinux, type); + map__kmap(vmlinux_map)->ref_reloc_sym = &ref_reloc_sym; + + /* + * Step 6: + * + * Locate a vmlinux file in the vmlinux path that has a buildid that + * matches the one of the running kernel. + * + * While doing that look if we find the ref reloc symbol, if we find it + * we'll have its ref_reloc_symbol.unrelocated_addr and then + * maps__reloc_vmlinux will notice and set proper ->[un]map_ip routines + * to fixup the symbols. + */ + if (machine__load_vmlinux_path(&vmlinux, type, + vmlinux_matches_kallsyms_filter) <= 0) { + pr_debug("machine__load_vmlinux_path "); + goto out; + } + + err = 0; + /* + * Step 7: + * + * Now look at the symbols in the vmlinux DSO and check if we find all of them + * in the kallsyms dso. For the ones that are in both, check its names and + * end addresses too. + */ + for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) { + struct symbol *pair, *first_pair; + bool backwards = true; + + sym = rb_entry(nd, struct symbol, rb_node); + + if (sym->start == sym->end) + continue; + + first_pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL); + pair = first_pair; + + if (pair && pair->start == sym->start) { +next_pair: + if (strcmp(sym->name, pair->name) == 0) { + /* + * kallsyms don't have the symbol end, so we + * set that by using the next symbol start - 1, + * in some cases we get this up to a page + * wrong, trace_kmalloc when I was developing + * this code was one such example, 2106 bytes + * off the real size. More than that and we + * _really_ have a problem. + */ + s64 skew = sym->end - pair->end; + if (llabs(skew) < page_size) + continue; + + pr_debug("%#" PRIx64 ": diff end addr for %s v: %#" PRIx64 " k: %#" PRIx64 "\n", + sym->start, sym->name, sym->end, pair->end); + } else { + struct rb_node *nnd; +detour: + nnd = backwards ? rb_prev(&pair->rb_node) : + rb_next(&pair->rb_node); + if (nnd) { + struct symbol *next = rb_entry(nnd, struct symbol, rb_node); + + if (next->start == sym->start) { + pair = next; + goto next_pair; + } + } + + if (backwards) { + backwards = false; + pair = first_pair; + goto detour; + } + + pr_debug("%#" PRIx64 ": diff name v: %s k: %s\n", + sym->start, sym->name, pair->name); + } + } else + pr_debug("%#" PRIx64 ": %s not on kallsyms\n", sym->start, sym->name); + + err = -1; + } + + if (!verbose) + goto out; + + pr_info("Maps only in vmlinux:\n"); + + for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) { + struct map *pos = rb_entry(nd, struct map, rb_node), *pair; + /* + * If it is the kernel, kallsyms is always "[kernel.kallsyms]", while + * the kernel will have the path for the vmlinux file being used, + * so use the short name, less descriptive but the same ("[kernel]" in + * both cases. + */ + pair = map_groups__find_by_name(&kallsyms.kmaps, type, + (pos->dso->kernel ? + pos->dso->short_name : + pos->dso->name)); + if (pair) + pair->priv = 1; + else + map__fprintf(pos, stderr); + } + + pr_info("Maps in vmlinux with a different name in kallsyms:\n"); + + for (nd = rb_first(&vmlinux.kmaps.maps[type]); nd; nd = rb_next(nd)) { + struct map *pos = rb_entry(nd, struct map, rb_node), *pair; + + pair = map_groups__find(&kallsyms.kmaps, type, pos->start); + if (pair == NULL || pair->priv) + continue; + + if (pair->start == pos->start) { + pair->priv = 1; + pr_info(" %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as", + pos->start, pos->end, pos->pgoff, pos->dso->name); + if (pos->pgoff != pair->pgoff || pos->end != pair->end) + pr_info(": \n*%" PRIx64 "-%" PRIx64 " %" PRIx64 "", + pair->start, pair->end, pair->pgoff); + pr_info(" %s\n", pair->dso->name); + pair->priv = 1; + } + } + + pr_info("Maps only in kallsyms:\n"); + + for (nd = rb_first(&kallsyms.kmaps.maps[type]); + nd; nd = rb_next(nd)) { + struct map *pos = rb_entry(nd, struct map, rb_node); + + if (!pos->priv) + map__fprintf(pos, stderr); + } +out: + return err; +} -- cgit v1.2.3 From d3b59a38bcdab4248134023c2c5dfabee5a4878e Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Nov 2012 01:46:42 +0100 Subject: perf tests: Move test__open_syscall_event into separate object Separating test__open_syscall_event test from the builtin-test into open-syscall object. Adding util object under tests directory to gather help functions common to more tests. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352508412-16914-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 2 + tools/perf/tests/builtin-test.c | 84 ----------------------------------------- tools/perf/tests/open-syscall.c | 66 ++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 5 +++ tools/perf/tests/util.c | 30 +++++++++++++++ 5 files changed, 103 insertions(+), 84 deletions(-) create mode 100644 tools/perf/tests/open-syscall.c create mode 100644 tools/perf/tests/util.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 7c7ba4d6daf..69f582c53cb 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -432,6 +432,8 @@ LIB_OBJS += $(OUTPUT)tests/parse-events.o LIB_OBJS += $(OUTPUT)tests/dso-data.o LIB_OBJS += $(OUTPUT)tests/attr.o LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o +LIB_OBJS += $(OUTPUT)tests/open-syscall.o +LIB_OBJS += $(OUTPUT)tests/util.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o BUILTIN_OBJS += $(OUTPUT)builtin-bench.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 5bc9063bf30..b6b1e46a51c 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -27,90 +27,6 @@ #include "tests.h" -static int trace_event__id(const char *evname) -{ - char *filename; - int err = -1, fd; - - if (asprintf(&filename, - "%s/syscalls/%s/id", - tracing_events_path, evname) < 0) - return -1; - - fd = open(filename, O_RDONLY); - if (fd >= 0) { - char id[16]; - if (read(fd, id, sizeof(id)) > 0) - err = atoi(id); - close(fd); - } - - free(filename); - return err; -} - -static int test__open_syscall_event(void) -{ - int err = -1, fd; - struct thread_map *threads; - struct perf_evsel *evsel; - struct perf_event_attr attr; - unsigned int nr_open_calls = 111, i; - int id = trace_event__id("sys_enter_open"); - - if (id < 0) { - pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); - return -1; - } - - threads = thread_map__new(-1, getpid(), UINT_MAX); - if (threads == NULL) { - pr_debug("thread_map__new\n"); - return -1; - } - - memset(&attr, 0, sizeof(attr)); - attr.type = PERF_TYPE_TRACEPOINT; - attr.config = id; - evsel = perf_evsel__new(&attr, 0); - if (evsel == NULL) { - pr_debug("perf_evsel__new\n"); - goto out_thread_map_delete; - } - - if (perf_evsel__open_per_thread(evsel, threads) < 0) { - pr_debug("failed to open counter: %s, " - "tweak /proc/sys/kernel/perf_event_paranoid?\n", - strerror(errno)); - goto out_evsel_delete; - } - - for (i = 0; i < nr_open_calls; ++i) { - fd = open("/etc/passwd", O_RDONLY); - close(fd); - } - - if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) { - pr_debug("perf_evsel__read_on_cpu\n"); - goto out_close_fd; - } - - if (evsel->counts->cpu[0].val != nr_open_calls) { - pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n", - nr_open_calls, evsel->counts->cpu[0].val); - goto out_close_fd; - } - - err = 0; -out_close_fd: - perf_evsel__close_fd(evsel, 1, threads->nr); -out_evsel_delete: - perf_evsel__delete(evsel); -out_thread_map_delete: - thread_map__delete(threads); - return err; -} - #include static int test__open_syscall_event_on_all_cpus(void) diff --git a/tools/perf/tests/open-syscall.c b/tools/perf/tests/open-syscall.c new file mode 100644 index 00000000000..98be8b518b4 --- /dev/null +++ b/tools/perf/tests/open-syscall.c @@ -0,0 +1,66 @@ +#include "thread_map.h" +#include "evsel.h" +#include "debug.h" +#include "tests.h" + +int test__open_syscall_event(void) +{ + int err = -1, fd; + struct thread_map *threads; + struct perf_evsel *evsel; + struct perf_event_attr attr; + unsigned int nr_open_calls = 111, i; + int id = trace_event__id("sys_enter_open"); + + if (id < 0) { + pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); + return -1; + } + + threads = thread_map__new(-1, getpid(), UINT_MAX); + if (threads == NULL) { + pr_debug("thread_map__new\n"); + return -1; + } + + memset(&attr, 0, sizeof(attr)); + attr.type = PERF_TYPE_TRACEPOINT; + attr.config = id; + evsel = perf_evsel__new(&attr, 0); + if (evsel == NULL) { + pr_debug("perf_evsel__new\n"); + goto out_thread_map_delete; + } + + if (perf_evsel__open_per_thread(evsel, threads) < 0) { + pr_debug("failed to open counter: %s, " + "tweak /proc/sys/kernel/perf_event_paranoid?\n", + strerror(errno)); + goto out_evsel_delete; + } + + for (i = 0; i < nr_open_calls; ++i) { + fd = open("/etc/passwd", O_RDONLY); + close(fd); + } + + if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) { + pr_debug("perf_evsel__read_on_cpu\n"); + goto out_close_fd; + } + + if (evsel->counts->cpu[0].val != nr_open_calls) { + pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n", + nr_open_calls, evsel->counts->cpu[0].val); + goto out_close_fd; + } + + err = 0; +out_close_fd: + perf_evsel__close_fd(evsel, 1, threads->nr); +out_evsel_delete: + perf_evsel__delete(evsel); +out_thread_map_delete: + thread_map__delete(threads); + return err; +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 2223de5ad29..bac133e15bb 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -1,6 +1,11 @@ #ifndef TESTS_H #define TESTS_H +/* Tests */ int test__vmlinux_matches_kallsyms(void); +int test__open_syscall_event(void); + +/* Util */ +int trace_event__id(const char *evname); #endif /* TESTS_H */ diff --git a/tools/perf/tests/util.c b/tools/perf/tests/util.c new file mode 100644 index 00000000000..748f2e8f696 --- /dev/null +++ b/tools/perf/tests/util.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#include +#include "tests.h" +#include "debugfs.h" + +int trace_event__id(const char *evname) +{ + char *filename; + int err = -1, fd; + + if (asprintf(&filename, + "%s/syscalls/%s/id", + tracing_events_path, evname) < 0) + return -1; + + fd = open(filename, O_RDONLY); + if (fd >= 0) { + char id[16]; + if (read(fd, id, sizeof(id)) > 0) + err = atoi(id); + close(fd); + } + + free(filename); + return err; +} -- cgit v1.2.3 From bd90517b374b1d6381a5509f55df1a9b7c33a6b1 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Nov 2012 01:46:43 +0100 Subject: perf tests: Move test__open_syscall_event_on_all_cpus into separate object Separating test__open_syscall_event_on_all_cpus test from the builtin-test into open-syscall-all-cpus object. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352508412-16914-4-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 + tools/perf/tests/builtin-test.c | 114 ----------------------------- tools/perf/tests/open-syscall-all-cpus.c | 120 +++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + 4 files changed, 122 insertions(+), 114 deletions(-) create mode 100644 tools/perf/tests/open-syscall-all-cpus.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 69f582c53cb..d413e89c38e 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -433,6 +433,7 @@ LIB_OBJS += $(OUTPUT)tests/dso-data.o LIB_OBJS += $(OUTPUT)tests/attr.o LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o LIB_OBJS += $(OUTPUT)tests/open-syscall.o +LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o LIB_OBJS += $(OUTPUT)tests/util.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index b6b1e46a51c..98e883bc330 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -29,120 +29,6 @@ #include -static int test__open_syscall_event_on_all_cpus(void) -{ - int err = -1, fd, cpu; - struct thread_map *threads; - struct cpu_map *cpus; - struct perf_evsel *evsel; - struct perf_event_attr attr; - unsigned int nr_open_calls = 111, i; - cpu_set_t cpu_set; - int id = trace_event__id("sys_enter_open"); - - if (id < 0) { - pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); - return -1; - } - - threads = thread_map__new(-1, getpid(), UINT_MAX); - if (threads == NULL) { - pr_debug("thread_map__new\n"); - return -1; - } - - cpus = cpu_map__new(NULL); - if (cpus == NULL) { - pr_debug("cpu_map__new\n"); - goto out_thread_map_delete; - } - - - CPU_ZERO(&cpu_set); - - memset(&attr, 0, sizeof(attr)); - attr.type = PERF_TYPE_TRACEPOINT; - attr.config = id; - evsel = perf_evsel__new(&attr, 0); - if (evsel == NULL) { - pr_debug("perf_evsel__new\n"); - goto out_thread_map_delete; - } - - if (perf_evsel__open(evsel, cpus, threads) < 0) { - pr_debug("failed to open counter: %s, " - "tweak /proc/sys/kernel/perf_event_paranoid?\n", - strerror(errno)); - goto out_evsel_delete; - } - - for (cpu = 0; cpu < cpus->nr; ++cpu) { - unsigned int ncalls = nr_open_calls + cpu; - /* - * XXX eventually lift this restriction in a way that - * keeps perf building on older glibc installations - * without CPU_ALLOC. 1024 cpus in 2010 still seems - * a reasonable upper limit tho :-) - */ - if (cpus->map[cpu] >= CPU_SETSIZE) { - pr_debug("Ignoring CPU %d\n", cpus->map[cpu]); - continue; - } - - CPU_SET(cpus->map[cpu], &cpu_set); - if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { - pr_debug("sched_setaffinity() failed on CPU %d: %s ", - cpus->map[cpu], - strerror(errno)); - goto out_close_fd; - } - for (i = 0; i < ncalls; ++i) { - fd = open("/etc/passwd", O_RDONLY); - close(fd); - } - CPU_CLR(cpus->map[cpu], &cpu_set); - } - - /* - * Here we need to explicitely preallocate the counts, as if - * we use the auto allocation it will allocate just for 1 cpu, - * as we start by cpu 0. - */ - if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) { - pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr); - goto out_close_fd; - } - - err = 0; - - for (cpu = 0; cpu < cpus->nr; ++cpu) { - unsigned int expected; - - if (cpus->map[cpu] >= CPU_SETSIZE) - continue; - - if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) { - pr_debug("perf_evsel__read_on_cpu\n"); - err = -1; - break; - } - - expected = nr_open_calls + cpu; - if (evsel->counts->cpu[cpu].val != expected) { - pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n", - expected, cpus->map[cpu], evsel->counts->cpu[cpu].val); - err = -1; - } - } - -out_close_fd: - perf_evsel__close_fd(evsel, 1, threads->nr); -out_evsel_delete: - perf_evsel__delete(evsel); -out_thread_map_delete: - thread_map__delete(threads); - return err; -} /* * This test will generate random numbers of calls to some getpid syscalls, diff --git a/tools/perf/tests/open-syscall-all-cpus.c b/tools/perf/tests/open-syscall-all-cpus.c new file mode 100644 index 00000000000..31072aba0d5 --- /dev/null +++ b/tools/perf/tests/open-syscall-all-cpus.c @@ -0,0 +1,120 @@ +#include "evsel.h" +#include "tests.h" +#include "thread_map.h" +#include "cpumap.h" +#include "debug.h" + +int test__open_syscall_event_on_all_cpus(void) +{ + int err = -1, fd, cpu; + struct thread_map *threads; + struct cpu_map *cpus; + struct perf_evsel *evsel; + struct perf_event_attr attr; + unsigned int nr_open_calls = 111, i; + cpu_set_t cpu_set; + int id = trace_event__id("sys_enter_open"); + + if (id < 0) { + pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); + return -1; + } + + threads = thread_map__new(-1, getpid(), UINT_MAX); + if (threads == NULL) { + pr_debug("thread_map__new\n"); + return -1; + } + + cpus = cpu_map__new(NULL); + if (cpus == NULL) { + pr_debug("cpu_map__new\n"); + goto out_thread_map_delete; + } + + + CPU_ZERO(&cpu_set); + + memset(&attr, 0, sizeof(attr)); + attr.type = PERF_TYPE_TRACEPOINT; + attr.config = id; + evsel = perf_evsel__new(&attr, 0); + if (evsel == NULL) { + pr_debug("perf_evsel__new\n"); + goto out_thread_map_delete; + } + + if (perf_evsel__open(evsel, cpus, threads) < 0) { + pr_debug("failed to open counter: %s, " + "tweak /proc/sys/kernel/perf_event_paranoid?\n", + strerror(errno)); + goto out_evsel_delete; + } + + for (cpu = 0; cpu < cpus->nr; ++cpu) { + unsigned int ncalls = nr_open_calls + cpu; + /* + * XXX eventually lift this restriction in a way that + * keeps perf building on older glibc installations + * without CPU_ALLOC. 1024 cpus in 2010 still seems + * a reasonable upper limit tho :-) + */ + if (cpus->map[cpu] >= CPU_SETSIZE) { + pr_debug("Ignoring CPU %d\n", cpus->map[cpu]); + continue; + } + + CPU_SET(cpus->map[cpu], &cpu_set); + if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { + pr_debug("sched_setaffinity() failed on CPU %d: %s ", + cpus->map[cpu], + strerror(errno)); + goto out_close_fd; + } + for (i = 0; i < ncalls; ++i) { + fd = open("/etc/passwd", O_RDONLY); + close(fd); + } + CPU_CLR(cpus->map[cpu], &cpu_set); + } + + /* + * Here we need to explicitely preallocate the counts, as if + * we use the auto allocation it will allocate just for 1 cpu, + * as we start by cpu 0. + */ + if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) { + pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr); + goto out_close_fd; + } + + err = 0; + + for (cpu = 0; cpu < cpus->nr; ++cpu) { + unsigned int expected; + + if (cpus->map[cpu] >= CPU_SETSIZE) + continue; + + if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) { + pr_debug("perf_evsel__read_on_cpu\n"); + err = -1; + break; + } + + expected = nr_open_calls + cpu; + if (evsel->counts->cpu[cpu].val != expected) { + pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n", + expected, cpus->map[cpu], evsel->counts->cpu[cpu].val); + err = -1; + } + } + +out_close_fd: + perf_evsel__close_fd(evsel, 1, threads->nr); +out_evsel_delete: + perf_evsel__delete(evsel); +out_thread_map_delete: + thread_map__delete(threads); + return err; +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index bac133e15bb..c2887f226db 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -4,6 +4,7 @@ /* Tests */ int test__vmlinux_matches_kallsyms(void); int test__open_syscall_event(void); +int test__open_syscall_event_on_all_cpus(void); /* Util */ int trace_event__id(const char *evname); -- cgit v1.2.3 From a65b9c62be044b7956022e2823c5f079cf35b069 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Nov 2012 01:46:44 +0100 Subject: perf tests: Move test__basic_mmap into separate object Separating test__basic_mmap test from the builtin-test into mmap-basic object. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352508412-16914-5-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 + tools/perf/tests/builtin-test.c | 157 -------------------------------------- tools/perf/tests/mmap-basic.c | 162 ++++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + 4 files changed, 164 insertions(+), 157 deletions(-) create mode 100644 tools/perf/tests/mmap-basic.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index d413e89c38e..337489e827c 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -434,6 +434,7 @@ LIB_OBJS += $(OUTPUT)tests/attr.o LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o LIB_OBJS += $(OUTPUT)tests/open-syscall.o LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o +LIB_OBJS += $(OUTPUT)tests/mmap-basic.o LIB_OBJS += $(OUTPUT)tests/util.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 98e883bc330..609f5929532 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -30,163 +30,6 @@ #include -/* - * This test will generate random numbers of calls to some getpid syscalls, - * then establish an mmap for a group of events that are created to monitor - * the syscalls. - * - * It will receive the events, using mmap, use its PERF_SAMPLE_ID generated - * sample.id field to map back to its respective perf_evsel instance. - * - * Then it checks if the number of syscalls reported as perf events by - * the kernel corresponds to the number of syscalls made. - */ -static int test__basic_mmap(void) -{ - int err = -1; - union perf_event *event; - struct thread_map *threads; - struct cpu_map *cpus; - struct perf_evlist *evlist; - struct perf_event_attr attr = { - .type = PERF_TYPE_TRACEPOINT, - .read_format = PERF_FORMAT_ID, - .sample_type = PERF_SAMPLE_ID, - .watermark = 0, - }; - cpu_set_t cpu_set; - const char *syscall_names[] = { "getsid", "getppid", "getpgrp", - "getpgid", }; - pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp, - (void*)getpgid }; -#define nsyscalls ARRAY_SIZE(syscall_names) - int ids[nsyscalls]; - unsigned int nr_events[nsyscalls], - expected_nr_events[nsyscalls], i, j; - struct perf_evsel *evsels[nsyscalls], *evsel; - - for (i = 0; i < nsyscalls; ++i) { - char name[64]; - - snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]); - ids[i] = trace_event__id(name); - if (ids[i] < 0) { - pr_debug("Is debugfs mounted on /sys/kernel/debug?\n"); - return -1; - } - nr_events[i] = 0; - expected_nr_events[i] = random() % 257; - } - - threads = thread_map__new(-1, getpid(), UINT_MAX); - if (threads == NULL) { - pr_debug("thread_map__new\n"); - return -1; - } - - cpus = cpu_map__new(NULL); - if (cpus == NULL) { - pr_debug("cpu_map__new\n"); - goto out_free_threads; - } - - CPU_ZERO(&cpu_set); - CPU_SET(cpus->map[0], &cpu_set); - sched_setaffinity(0, sizeof(cpu_set), &cpu_set); - if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { - pr_debug("sched_setaffinity() failed on CPU %d: %s ", - cpus->map[0], strerror(errno)); - goto out_free_cpus; - } - - evlist = perf_evlist__new(cpus, threads); - if (evlist == NULL) { - pr_debug("perf_evlist__new\n"); - goto out_free_cpus; - } - - /* anonymous union fields, can't be initialized above */ - attr.wakeup_events = 1; - attr.sample_period = 1; - - for (i = 0; i < nsyscalls; ++i) { - attr.config = ids[i]; - evsels[i] = perf_evsel__new(&attr, i); - if (evsels[i] == NULL) { - pr_debug("perf_evsel__new\n"); - goto out_free_evlist; - } - - perf_evlist__add(evlist, evsels[i]); - - if (perf_evsel__open(evsels[i], cpus, threads) < 0) { - pr_debug("failed to open counter: %s, " - "tweak /proc/sys/kernel/perf_event_paranoid?\n", - strerror(errno)); - goto out_close_fd; - } - } - - if (perf_evlist__mmap(evlist, 128, true) < 0) { - pr_debug("failed to mmap events: %d (%s)\n", errno, - strerror(errno)); - goto out_close_fd; - } - - for (i = 0; i < nsyscalls; ++i) - for (j = 0; j < expected_nr_events[i]; ++j) { - int foo = syscalls[i](); - ++foo; - } - - while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) { - struct perf_sample sample; - - if (event->header.type != PERF_RECORD_SAMPLE) { - pr_debug("unexpected %s event\n", - perf_event__name(event->header.type)); - goto out_munmap; - } - - err = perf_evlist__parse_sample(evlist, event, &sample); - if (err) { - pr_err("Can't parse sample, err = %d\n", err); - goto out_munmap; - } - - evsel = perf_evlist__id2evsel(evlist, sample.id); - if (evsel == NULL) { - pr_debug("event with id %" PRIu64 - " doesn't map to an evsel\n", sample.id); - goto out_munmap; - } - nr_events[evsel->idx]++; - } - - list_for_each_entry(evsel, &evlist->entries, node) { - if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) { - pr_debug("expected %d %s events, got %d\n", - expected_nr_events[evsel->idx], - perf_evsel__name(evsel), nr_events[evsel->idx]); - goto out_munmap; - } - } - - err = 0; -out_munmap: - perf_evlist__munmap(evlist); -out_close_fd: - for (i = 0; i < nsyscalls; ++i) - perf_evsel__close_fd(evsels[i], 1, threads->nr); -out_free_evlist: - perf_evlist__delete(evlist); -out_free_cpus: - cpu_map__delete(cpus); -out_free_threads: - thread_map__delete(threads); - return err; -#undef nsyscalls -} static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp) { diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c new file mode 100644 index 00000000000..e1746811e14 --- /dev/null +++ b/tools/perf/tests/mmap-basic.c @@ -0,0 +1,162 @@ +#include "evlist.h" +#include "evsel.h" +#include "thread_map.h" +#include "cpumap.h" +#include "tests.h" + +/* + * This test will generate random numbers of calls to some getpid syscalls, + * then establish an mmap for a group of events that are created to monitor + * the syscalls. + * + * It will receive the events, using mmap, use its PERF_SAMPLE_ID generated + * sample.id field to map back to its respective perf_evsel instance. + * + * Then it checks if the number of syscalls reported as perf events by + * the kernel corresponds to the number of syscalls made. + */ +int test__basic_mmap(void) +{ + int err = -1; + union perf_event *event; + struct thread_map *threads; + struct cpu_map *cpus; + struct perf_evlist *evlist; + struct perf_event_attr attr = { + .type = PERF_TYPE_TRACEPOINT, + .read_format = PERF_FORMAT_ID, + .sample_type = PERF_SAMPLE_ID, + .watermark = 0, + }; + cpu_set_t cpu_set; + const char *syscall_names[] = { "getsid", "getppid", "getpgrp", + "getpgid", }; + pid_t (*syscalls[])(void) = { (void *)getsid, getppid, getpgrp, + (void*)getpgid }; +#define nsyscalls ARRAY_SIZE(syscall_names) + int ids[nsyscalls]; + unsigned int nr_events[nsyscalls], + expected_nr_events[nsyscalls], i, j; + struct perf_evsel *evsels[nsyscalls], *evsel; + + for (i = 0; i < nsyscalls; ++i) { + char name[64]; + + snprintf(name, sizeof(name), "sys_enter_%s", syscall_names[i]); + ids[i] = trace_event__id(name); + if (ids[i] < 0) { + pr_debug("Is debugfs mounted on /sys/kernel/debug?\n"); + return -1; + } + nr_events[i] = 0; + expected_nr_events[i] = random() % 257; + } + + threads = thread_map__new(-1, getpid(), UINT_MAX); + if (threads == NULL) { + pr_debug("thread_map__new\n"); + return -1; + } + + cpus = cpu_map__new(NULL); + if (cpus == NULL) { + pr_debug("cpu_map__new\n"); + goto out_free_threads; + } + + CPU_ZERO(&cpu_set); + CPU_SET(cpus->map[0], &cpu_set); + sched_setaffinity(0, sizeof(cpu_set), &cpu_set); + if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { + pr_debug("sched_setaffinity() failed on CPU %d: %s ", + cpus->map[0], strerror(errno)); + goto out_free_cpus; + } + + evlist = perf_evlist__new(cpus, threads); + if (evlist == NULL) { + pr_debug("perf_evlist__new\n"); + goto out_free_cpus; + } + + /* anonymous union fields, can't be initialized above */ + attr.wakeup_events = 1; + attr.sample_period = 1; + + for (i = 0; i < nsyscalls; ++i) { + attr.config = ids[i]; + evsels[i] = perf_evsel__new(&attr, i); + if (evsels[i] == NULL) { + pr_debug("perf_evsel__new\n"); + goto out_free_evlist; + } + + perf_evlist__add(evlist, evsels[i]); + + if (perf_evsel__open(evsels[i], cpus, threads) < 0) { + pr_debug("failed to open counter: %s, " + "tweak /proc/sys/kernel/perf_event_paranoid?\n", + strerror(errno)); + goto out_close_fd; + } + } + + if (perf_evlist__mmap(evlist, 128, true) < 0) { + pr_debug("failed to mmap events: %d (%s)\n", errno, + strerror(errno)); + goto out_close_fd; + } + + for (i = 0; i < nsyscalls; ++i) + for (j = 0; j < expected_nr_events[i]; ++j) { + int foo = syscalls[i](); + ++foo; + } + + while ((event = perf_evlist__mmap_read(evlist, 0)) != NULL) { + struct perf_sample sample; + + if (event->header.type != PERF_RECORD_SAMPLE) { + pr_debug("unexpected %s event\n", + perf_event__name(event->header.type)); + goto out_munmap; + } + + err = perf_evlist__parse_sample(evlist, event, &sample); + if (err) { + pr_err("Can't parse sample, err = %d\n", err); + goto out_munmap; + } + + evsel = perf_evlist__id2evsel(evlist, sample.id); + if (evsel == NULL) { + pr_debug("event with id %" PRIu64 + " doesn't map to an evsel\n", sample.id); + goto out_munmap; + } + nr_events[evsel->idx]++; + } + + list_for_each_entry(evsel, &evlist->entries, node) { + if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) { + pr_debug("expected %d %s events, got %d\n", + expected_nr_events[evsel->idx], + perf_evsel__name(evsel), nr_events[evsel->idx]); + goto out_munmap; + } + } + + err = 0; +out_munmap: + perf_evlist__munmap(evlist); +out_close_fd: + for (i = 0; i < nsyscalls; ++i) + perf_evsel__close_fd(evsels[i], 1, threads->nr); +out_free_evlist: + perf_evlist__delete(evlist); +out_free_cpus: + cpu_map__delete(cpus); +out_free_threads: + thread_map__delete(threads); + return err; +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index c2887f226db..1a925ddeae7 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -5,6 +5,7 @@ int test__vmlinux_matches_kallsyms(void); int test__open_syscall_event(void); int test__open_syscall_event_on_all_cpus(void); +int test__basic_mmap(void); /* Util */ int trace_event__id(const char *evname); -- cgit v1.2.3 From 16d00fee703866c61c9006eff097952289335479 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Nov 2012 01:46:45 +0100 Subject: perf tests: Move test__PERF_RECORD into separate object Separating test__PERF_RECORD test from the builtin-test into perf-record object. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352508412-16914-6-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 + tools/perf/tests/builtin-test.c | 307 --------------------------------------- tools/perf/tests/perf-record.c | 312 ++++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + 4 files changed, 314 insertions(+), 307 deletions(-) create mode 100644 tools/perf/tests/perf-record.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 337489e827c..a2d6153a6d0 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -435,6 +435,7 @@ LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o LIB_OBJS += $(OUTPUT)tests/open-syscall.o LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o LIB_OBJS += $(OUTPUT)tests/mmap-basic.o +LIB_OBJS += $(OUTPUT)tests/perf-record.o LIB_OBJS += $(OUTPUT)tests/util.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 609f5929532..7cb3928d896 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -31,313 +31,6 @@ -static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp) -{ - int i, cpu = -1, nrcpus = 1024; -realloc: - CPU_ZERO(maskp); - - if (sched_getaffinity(pid, sizeof(*maskp), maskp) == -1) { - if (errno == EINVAL && nrcpus < (1024 << 8)) { - nrcpus = nrcpus << 2; - goto realloc; - } - perror("sched_getaffinity"); - return -1; - } - - for (i = 0; i < nrcpus; i++) { - if (CPU_ISSET(i, maskp)) { - if (cpu == -1) - cpu = i; - else - CPU_CLR(i, maskp); - } - } - - return cpu; -} - -static int test__PERF_RECORD(void) -{ - struct perf_record_opts opts = { - .target = { - .uid = UINT_MAX, - .uses_mmap = true, - }, - .no_delay = true, - .freq = 10, - .mmap_pages = 256, - }; - cpu_set_t cpu_mask; - size_t cpu_mask_size = sizeof(cpu_mask); - struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); - struct perf_evsel *evsel; - struct perf_sample sample; - const char *cmd = "sleep"; - const char *argv[] = { cmd, "1", NULL, }; - char *bname; - u64 prev_time = 0; - bool found_cmd_mmap = false, - found_libc_mmap = false, - found_vdso_mmap = false, - found_ld_mmap = false; - int err = -1, errs = 0, i, wakeups = 0; - u32 cpu; - int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, }; - - if (evlist == NULL || argv == NULL) { - pr_debug("Not enough memory to create evlist\n"); - goto out; - } - - /* - * We need at least one evsel in the evlist, use the default - * one: "cycles". - */ - err = perf_evlist__add_default(evlist); - if (err < 0) { - pr_debug("Not enough memory to create evsel\n"); - goto out_delete_evlist; - } - - /* - * Create maps of threads and cpus to monitor. In this case - * we start with all threads and cpus (-1, -1) but then in - * perf_evlist__prepare_workload we'll fill in the only thread - * we're monitoring, the one forked there. - */ - err = perf_evlist__create_maps(evlist, &opts.target); - if (err < 0) { - pr_debug("Not enough memory to create thread/cpu maps\n"); - goto out_delete_evlist; - } - - /* - * Prepare the workload in argv[] to run, it'll fork it, and then wait - * for perf_evlist__start_workload() to exec it. This is done this way - * so that we have time to open the evlist (calling sys_perf_event_open - * on all the fds) and then mmap them. - */ - err = perf_evlist__prepare_workload(evlist, &opts, argv); - if (err < 0) { - pr_debug("Couldn't run the workload!\n"); - goto out_delete_evlist; - } - - /* - * Config the evsels, setting attr->comm on the first one, etc. - */ - evsel = perf_evlist__first(evlist); - evsel->attr.sample_type |= PERF_SAMPLE_CPU; - evsel->attr.sample_type |= PERF_SAMPLE_TID; - evsel->attr.sample_type |= PERF_SAMPLE_TIME; - perf_evlist__config_attrs(evlist, &opts); - - err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask); - if (err < 0) { - pr_debug("sched__get_first_possible_cpu: %s\n", strerror(errno)); - goto out_delete_evlist; - } - - cpu = err; - - /* - * So that we can check perf_sample.cpu on all the samples. - */ - if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) { - pr_debug("sched_setaffinity: %s\n", strerror(errno)); - goto out_delete_evlist; - } - - /* - * Call sys_perf_event_open on all the fds on all the evsels, - * grouping them if asked to. - */ - err = perf_evlist__open(evlist); - if (err < 0) { - pr_debug("perf_evlist__open: %s\n", strerror(errno)); - goto out_delete_evlist; - } - - /* - * mmap the first fd on a given CPU and ask for events for the other - * fds in the same CPU to be injected in the same mmap ring buffer - * (using ioctl(PERF_EVENT_IOC_SET_OUTPUT)). - */ - err = perf_evlist__mmap(evlist, opts.mmap_pages, false); - if (err < 0) { - pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); - goto out_delete_evlist; - } - - /* - * Now that all is properly set up, enable the events, they will - * count just on workload.pid, which will start... - */ - perf_evlist__enable(evlist); - - /* - * Now! - */ - perf_evlist__start_workload(evlist); - - while (1) { - int before = total_events; - - for (i = 0; i < evlist->nr_mmaps; i++) { - union perf_event *event; - - while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { - const u32 type = event->header.type; - const char *name = perf_event__name(type); - - ++total_events; - if (type < PERF_RECORD_MAX) - nr_events[type]++; - - err = perf_evlist__parse_sample(evlist, event, &sample); - if (err < 0) { - if (verbose) - perf_event__fprintf(event, stderr); - pr_debug("Couldn't parse sample\n"); - goto out_err; - } - - if (verbose) { - pr_info("%" PRIu64" %d ", sample.time, sample.cpu); - perf_event__fprintf(event, stderr); - } - - if (prev_time > sample.time) { - pr_debug("%s going backwards in time, prev=%" PRIu64 ", curr=%" PRIu64 "\n", - name, prev_time, sample.time); - ++errs; - } - - prev_time = sample.time; - - if (sample.cpu != cpu) { - pr_debug("%s with unexpected cpu, expected %d, got %d\n", - name, cpu, sample.cpu); - ++errs; - } - - if ((pid_t)sample.pid != evlist->workload.pid) { - pr_debug("%s with unexpected pid, expected %d, got %d\n", - name, evlist->workload.pid, sample.pid); - ++errs; - } - - if ((pid_t)sample.tid != evlist->workload.pid) { - pr_debug("%s with unexpected tid, expected %d, got %d\n", - name, evlist->workload.pid, sample.tid); - ++errs; - } - - if ((type == PERF_RECORD_COMM || - type == PERF_RECORD_MMAP || - type == PERF_RECORD_FORK || - type == PERF_RECORD_EXIT) && - (pid_t)event->comm.pid != evlist->workload.pid) { - pr_debug("%s with unexpected pid/tid\n", name); - ++errs; - } - - if ((type == PERF_RECORD_COMM || - type == PERF_RECORD_MMAP) && - event->comm.pid != event->comm.tid) { - pr_debug("%s with different pid/tid!\n", name); - ++errs; - } - - switch (type) { - case PERF_RECORD_COMM: - if (strcmp(event->comm.comm, cmd)) { - pr_debug("%s with unexpected comm!\n", name); - ++errs; - } - break; - case PERF_RECORD_EXIT: - goto found_exit; - case PERF_RECORD_MMAP: - bname = strrchr(event->mmap.filename, '/'); - if (bname != NULL) { - if (!found_cmd_mmap) - found_cmd_mmap = !strcmp(bname + 1, cmd); - if (!found_libc_mmap) - found_libc_mmap = !strncmp(bname + 1, "libc", 4); - if (!found_ld_mmap) - found_ld_mmap = !strncmp(bname + 1, "ld", 2); - } else if (!found_vdso_mmap) - found_vdso_mmap = !strcmp(event->mmap.filename, "[vdso]"); - break; - - case PERF_RECORD_SAMPLE: - /* Just ignore samples for now */ - break; - default: - pr_debug("Unexpected perf_event->header.type %d!\n", - type); - ++errs; - } - } - } - - /* - * We don't use poll here because at least at 3.1 times the - * PERF_RECORD_{!SAMPLE} events don't honour - * perf_event_attr.wakeup_events, just PERF_EVENT_SAMPLE does. - */ - if (total_events == before && false) - poll(evlist->pollfd, evlist->nr_fds, -1); - - sleep(1); - if (++wakeups > 5) { - pr_debug("No PERF_RECORD_EXIT event!\n"); - break; - } - } - -found_exit: - if (nr_events[PERF_RECORD_COMM] > 1) { - pr_debug("Excessive number of PERF_RECORD_COMM events!\n"); - ++errs; - } - - if (nr_events[PERF_RECORD_COMM] == 0) { - pr_debug("Missing PERF_RECORD_COMM for %s!\n", cmd); - ++errs; - } - - if (!found_cmd_mmap) { - pr_debug("PERF_RECORD_MMAP for %s missing!\n", cmd); - ++errs; - } - - if (!found_libc_mmap) { - pr_debug("PERF_RECORD_MMAP for %s missing!\n", "libc"); - ++errs; - } - - if (!found_ld_mmap) { - pr_debug("PERF_RECORD_MMAP for %s missing!\n", "ld"); - ++errs; - } - - if (!found_vdso_mmap) { - pr_debug("PERF_RECORD_MMAP for %s missing!\n", "[vdso]"); - ++errs; - } -out_err: - perf_evlist__munmap(evlist); -out_delete_evlist: - perf_evlist__delete(evlist); -out: - return (err < 0 || errs > 0) ? -1 : 0; -} - - #if defined(__x86_64__) || defined(__i386__) #define barrier() asm volatile("" ::: "memory") diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c new file mode 100644 index 00000000000..70e0d4421df --- /dev/null +++ b/tools/perf/tests/perf-record.c @@ -0,0 +1,312 @@ +#include +#include "evlist.h" +#include "evsel.h" +#include "perf.h" +#include "debug.h" +#include "tests.h" + +static int sched__get_first_possible_cpu(pid_t pid, cpu_set_t *maskp) +{ + int i, cpu = -1, nrcpus = 1024; +realloc: + CPU_ZERO(maskp); + + if (sched_getaffinity(pid, sizeof(*maskp), maskp) == -1) { + if (errno == EINVAL && nrcpus < (1024 << 8)) { + nrcpus = nrcpus << 2; + goto realloc; + } + perror("sched_getaffinity"); + return -1; + } + + for (i = 0; i < nrcpus; i++) { + if (CPU_ISSET(i, maskp)) { + if (cpu == -1) + cpu = i; + else + CPU_CLR(i, maskp); + } + } + + return cpu; +} + +int test__PERF_RECORD(void) +{ + struct perf_record_opts opts = { + .target = { + .uid = UINT_MAX, + .uses_mmap = true, + }, + .no_delay = true, + .freq = 10, + .mmap_pages = 256, + }; + cpu_set_t cpu_mask; + size_t cpu_mask_size = sizeof(cpu_mask); + struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); + struct perf_evsel *evsel; + struct perf_sample sample; + const char *cmd = "sleep"; + const char *argv[] = { cmd, "1", NULL, }; + char *bname; + u64 prev_time = 0; + bool found_cmd_mmap = false, + found_libc_mmap = false, + found_vdso_mmap = false, + found_ld_mmap = false; + int err = -1, errs = 0, i, wakeups = 0; + u32 cpu; + int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, }; + + if (evlist == NULL || argv == NULL) { + pr_debug("Not enough memory to create evlist\n"); + goto out; + } + + /* + * We need at least one evsel in the evlist, use the default + * one: "cycles". + */ + err = perf_evlist__add_default(evlist); + if (err < 0) { + pr_debug("Not enough memory to create evsel\n"); + goto out_delete_evlist; + } + + /* + * Create maps of threads and cpus to monitor. In this case + * we start with all threads and cpus (-1, -1) but then in + * perf_evlist__prepare_workload we'll fill in the only thread + * we're monitoring, the one forked there. + */ + err = perf_evlist__create_maps(evlist, &opts.target); + if (err < 0) { + pr_debug("Not enough memory to create thread/cpu maps\n"); + goto out_delete_evlist; + } + + /* + * Prepare the workload in argv[] to run, it'll fork it, and then wait + * for perf_evlist__start_workload() to exec it. This is done this way + * so that we have time to open the evlist (calling sys_perf_event_open + * on all the fds) and then mmap them. + */ + err = perf_evlist__prepare_workload(evlist, &opts, argv); + if (err < 0) { + pr_debug("Couldn't run the workload!\n"); + goto out_delete_evlist; + } + + /* + * Config the evsels, setting attr->comm on the first one, etc. + */ + evsel = perf_evlist__first(evlist); + evsel->attr.sample_type |= PERF_SAMPLE_CPU; + evsel->attr.sample_type |= PERF_SAMPLE_TID; + evsel->attr.sample_type |= PERF_SAMPLE_TIME; + perf_evlist__config_attrs(evlist, &opts); + + err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask); + if (err < 0) { + pr_debug("sched__get_first_possible_cpu: %s\n", strerror(errno)); + goto out_delete_evlist; + } + + cpu = err; + + /* + * So that we can check perf_sample.cpu on all the samples. + */ + if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) { + pr_debug("sched_setaffinity: %s\n", strerror(errno)); + goto out_delete_evlist; + } + + /* + * Call sys_perf_event_open on all the fds on all the evsels, + * grouping them if asked to. + */ + err = perf_evlist__open(evlist); + if (err < 0) { + pr_debug("perf_evlist__open: %s\n", strerror(errno)); + goto out_delete_evlist; + } + + /* + * mmap the first fd on a given CPU and ask for events for the other + * fds in the same CPU to be injected in the same mmap ring buffer + * (using ioctl(PERF_EVENT_IOC_SET_OUTPUT)). + */ + err = perf_evlist__mmap(evlist, opts.mmap_pages, false); + if (err < 0) { + pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); + goto out_delete_evlist; + } + + /* + * Now that all is properly set up, enable the events, they will + * count just on workload.pid, which will start... + */ + perf_evlist__enable(evlist); + + /* + * Now! + */ + perf_evlist__start_workload(evlist); + + while (1) { + int before = total_events; + + for (i = 0; i < evlist->nr_mmaps; i++) { + union perf_event *event; + + while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { + const u32 type = event->header.type; + const char *name = perf_event__name(type); + + ++total_events; + if (type < PERF_RECORD_MAX) + nr_events[type]++; + + err = perf_evlist__parse_sample(evlist, event, &sample); + if (err < 0) { + if (verbose) + perf_event__fprintf(event, stderr); + pr_debug("Couldn't parse sample\n"); + goto out_err; + } + + if (verbose) { + pr_info("%" PRIu64" %d ", sample.time, sample.cpu); + perf_event__fprintf(event, stderr); + } + + if (prev_time > sample.time) { + pr_debug("%s going backwards in time, prev=%" PRIu64 ", curr=%" PRIu64 "\n", + name, prev_time, sample.time); + ++errs; + } + + prev_time = sample.time; + + if (sample.cpu != cpu) { + pr_debug("%s with unexpected cpu, expected %d, got %d\n", + name, cpu, sample.cpu); + ++errs; + } + + if ((pid_t)sample.pid != evlist->workload.pid) { + pr_debug("%s with unexpected pid, expected %d, got %d\n", + name, evlist->workload.pid, sample.pid); + ++errs; + } + + if ((pid_t)sample.tid != evlist->workload.pid) { + pr_debug("%s with unexpected tid, expected %d, got %d\n", + name, evlist->workload.pid, sample.tid); + ++errs; + } + + if ((type == PERF_RECORD_COMM || + type == PERF_RECORD_MMAP || + type == PERF_RECORD_FORK || + type == PERF_RECORD_EXIT) && + (pid_t)event->comm.pid != evlist->workload.pid) { + pr_debug("%s with unexpected pid/tid\n", name); + ++errs; + } + + if ((type == PERF_RECORD_COMM || + type == PERF_RECORD_MMAP) && + event->comm.pid != event->comm.tid) { + pr_debug("%s with different pid/tid!\n", name); + ++errs; + } + + switch (type) { + case PERF_RECORD_COMM: + if (strcmp(event->comm.comm, cmd)) { + pr_debug("%s with unexpected comm!\n", name); + ++errs; + } + break; + case PERF_RECORD_EXIT: + goto found_exit; + case PERF_RECORD_MMAP: + bname = strrchr(event->mmap.filename, '/'); + if (bname != NULL) { + if (!found_cmd_mmap) + found_cmd_mmap = !strcmp(bname + 1, cmd); + if (!found_libc_mmap) + found_libc_mmap = !strncmp(bname + 1, "libc", 4); + if (!found_ld_mmap) + found_ld_mmap = !strncmp(bname + 1, "ld", 2); + } else if (!found_vdso_mmap) + found_vdso_mmap = !strcmp(event->mmap.filename, "[vdso]"); + break; + + case PERF_RECORD_SAMPLE: + /* Just ignore samples for now */ + break; + default: + pr_debug("Unexpected perf_event->header.type %d!\n", + type); + ++errs; + } + } + } + + /* + * We don't use poll here because at least at 3.1 times the + * PERF_RECORD_{!SAMPLE} events don't honour + * perf_event_attr.wakeup_events, just PERF_EVENT_SAMPLE does. + */ + if (total_events == before && false) + poll(evlist->pollfd, evlist->nr_fds, -1); + + sleep(1); + if (++wakeups > 5) { + pr_debug("No PERF_RECORD_EXIT event!\n"); + break; + } + } + +found_exit: + if (nr_events[PERF_RECORD_COMM] > 1) { + pr_debug("Excessive number of PERF_RECORD_COMM events!\n"); + ++errs; + } + + if (nr_events[PERF_RECORD_COMM] == 0) { + pr_debug("Missing PERF_RECORD_COMM for %s!\n", cmd); + ++errs; + } + + if (!found_cmd_mmap) { + pr_debug("PERF_RECORD_MMAP for %s missing!\n", cmd); + ++errs; + } + + if (!found_libc_mmap) { + pr_debug("PERF_RECORD_MMAP for %s missing!\n", "libc"); + ++errs; + } + + if (!found_ld_mmap) { + pr_debug("PERF_RECORD_MMAP for %s missing!\n", "ld"); + ++errs; + } + + if (!found_vdso_mmap) { + pr_debug("PERF_RECORD_MMAP for %s missing!\n", "[vdso]"); + ++errs; + } +out_err: + perf_evlist__munmap(evlist); +out_delete_evlist: + perf_evlist__delete(evlist); +out: + return (err < 0 || errs > 0) ? -1 : 0; +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 1a925ddeae7..374b039dd22 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -6,6 +6,7 @@ int test__vmlinux_matches_kallsyms(void); int test__open_syscall_event(void); int test__open_syscall_event_on_all_cpus(void); int test__basic_mmap(void); +int test__PERF_RECORD(void); /* Util */ int trace_event__id(const char *evname); -- cgit v1.2.3 From bacf7e5d4055b65506292cf6412ec71e7948a9cf Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Nov 2012 01:46:46 +0100 Subject: perf tests: Move test__rdpmc into separate object Separating test__rdpmc test from the builtin-test into rdpmc object. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352508412-16914-7-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 + tools/perf/tests/builtin-test.c | 168 -------------------------------------- tools/perf/tests/rdpmc.c | 175 ++++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + 4 files changed, 177 insertions(+), 168 deletions(-) create mode 100644 tools/perf/tests/rdpmc.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index a2d6153a6d0..2e5197a0ad6 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -436,6 +436,7 @@ LIB_OBJS += $(OUTPUT)tests/open-syscall.o LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o LIB_OBJS += $(OUTPUT)tests/mmap-basic.o LIB_OBJS += $(OUTPUT)tests/perf-record.o +LIB_OBJS += $(OUTPUT)tests/rdpmc.o LIB_OBJS += $(OUTPUT)tests/util.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 7cb3928d896..1e9a0ea68fb 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -30,174 +30,6 @@ #include - -#if defined(__x86_64__) || defined(__i386__) - -#define barrier() asm volatile("" ::: "memory") - -static u64 rdpmc(unsigned int counter) -{ - unsigned int low, high; - - asm volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (counter)); - - return low | ((u64)high) << 32; -} - -static u64 rdtsc(void) -{ - unsigned int low, high; - - asm volatile("rdtsc" : "=a" (low), "=d" (high)); - - return low | ((u64)high) << 32; -} - -static u64 mmap_read_self(void *addr) -{ - struct perf_event_mmap_page *pc = addr; - u32 seq, idx, time_mult = 0, time_shift = 0; - u64 count, cyc = 0, time_offset = 0, enabled, running, delta; - - do { - seq = pc->lock; - barrier(); - - enabled = pc->time_enabled; - running = pc->time_running; - - if (enabled != running) { - cyc = rdtsc(); - time_mult = pc->time_mult; - time_shift = pc->time_shift; - time_offset = pc->time_offset; - } - - idx = pc->index; - count = pc->offset; - if (idx) - count += rdpmc(idx - 1); - - barrier(); - } while (pc->lock != seq); - - if (enabled != running) { - u64 quot, rem; - - quot = (cyc >> time_shift); - rem = cyc & ((1 << time_shift) - 1); - delta = time_offset + quot * time_mult + - ((rem * time_mult) >> time_shift); - - enabled += delta; - if (idx) - running += delta; - - quot = count / running; - rem = count % running; - count = quot * enabled + (rem * enabled) / running; - } - - return count; -} - -/* - * If the RDPMC instruction faults then signal this back to the test parent task: - */ -static void segfault_handler(int sig __maybe_unused, - siginfo_t *info __maybe_unused, - void *uc __maybe_unused) -{ - exit(-1); -} - -static int __test__rdpmc(void) -{ - volatile int tmp = 0; - u64 i, loops = 1000; - int n; - int fd; - void *addr; - struct perf_event_attr attr = { - .type = PERF_TYPE_HARDWARE, - .config = PERF_COUNT_HW_INSTRUCTIONS, - .exclude_kernel = 1, - }; - u64 delta_sum = 0; - struct sigaction sa; - - sigfillset(&sa.sa_mask); - sa.sa_sigaction = segfault_handler; - sigaction(SIGSEGV, &sa, NULL); - - fd = sys_perf_event_open(&attr, 0, -1, -1, 0); - if (fd < 0) { - pr_err("Error: sys_perf_event_open() syscall returned " - "with %d (%s)\n", fd, strerror(errno)); - return -1; - } - - addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0); - if (addr == (void *)(-1)) { - pr_err("Error: mmap() syscall returned with (%s)\n", - strerror(errno)); - goto out_close; - } - - for (n = 0; n < 6; n++) { - u64 stamp, now, delta; - - stamp = mmap_read_self(addr); - - for (i = 0; i < loops; i++) - tmp++; - - now = mmap_read_self(addr); - loops *= 10; - - delta = now - stamp; - pr_debug("%14d: %14Lu\n", n, (long long)delta); - - delta_sum += delta; - } - - munmap(addr, page_size); - pr_debug(" "); -out_close: - close(fd); - - if (!delta_sum) - return -1; - - return 0; -} - -static int test__rdpmc(void) -{ - int status = 0; - int wret = 0; - int ret; - int pid; - - pid = fork(); - if (pid < 0) - return -1; - - if (!pid) { - ret = __test__rdpmc(); - - exit(ret); - } - - wret = waitpid(pid, &status, 0); - if (wret < 0 || status) - return -1; - - return 0; -} - -#endif - static int test__perf_pmu(void) { return perf_pmu__test(); diff --git a/tools/perf/tests/rdpmc.c b/tools/perf/tests/rdpmc.c new file mode 100644 index 00000000000..ff94886aad9 --- /dev/null +++ b/tools/perf/tests/rdpmc.c @@ -0,0 +1,175 @@ +#include +#include +#include +#include +#include "types.h" +#include "perf.h" +#include "debug.h" +#include "tests.h" + +#if defined(__x86_64__) || defined(__i386__) + +#define barrier() asm volatile("" ::: "memory") + +static u64 rdpmc(unsigned int counter) +{ + unsigned int low, high; + + asm volatile("rdpmc" : "=a" (low), "=d" (high) : "c" (counter)); + + return low | ((u64)high) << 32; +} + +static u64 rdtsc(void) +{ + unsigned int low, high; + + asm volatile("rdtsc" : "=a" (low), "=d" (high)); + + return low | ((u64)high) << 32; +} + +static u64 mmap_read_self(void *addr) +{ + struct perf_event_mmap_page *pc = addr; + u32 seq, idx, time_mult = 0, time_shift = 0; + u64 count, cyc = 0, time_offset = 0, enabled, running, delta; + + do { + seq = pc->lock; + barrier(); + + enabled = pc->time_enabled; + running = pc->time_running; + + if (enabled != running) { + cyc = rdtsc(); + time_mult = pc->time_mult; + time_shift = pc->time_shift; + time_offset = pc->time_offset; + } + + idx = pc->index; + count = pc->offset; + if (idx) + count += rdpmc(idx - 1); + + barrier(); + } while (pc->lock != seq); + + if (enabled != running) { + u64 quot, rem; + + quot = (cyc >> time_shift); + rem = cyc & ((1 << time_shift) - 1); + delta = time_offset + quot * time_mult + + ((rem * time_mult) >> time_shift); + + enabled += delta; + if (idx) + running += delta; + + quot = count / running; + rem = count % running; + count = quot * enabled + (rem * enabled) / running; + } + + return count; +} + +/* + * If the RDPMC instruction faults then signal this back to the test parent task: + */ +static void segfault_handler(int sig __maybe_unused, + siginfo_t *info __maybe_unused, + void *uc __maybe_unused) +{ + exit(-1); +} + +static int __test__rdpmc(void) +{ + volatile int tmp = 0; + u64 i, loops = 1000; + int n; + int fd; + void *addr; + struct perf_event_attr attr = { + .type = PERF_TYPE_HARDWARE, + .config = PERF_COUNT_HW_INSTRUCTIONS, + .exclude_kernel = 1, + }; + u64 delta_sum = 0; + struct sigaction sa; + + sigfillset(&sa.sa_mask); + sa.sa_sigaction = segfault_handler; + sigaction(SIGSEGV, &sa, NULL); + + fd = sys_perf_event_open(&attr, 0, -1, -1, 0); + if (fd < 0) { + pr_err("Error: sys_perf_event_open() syscall returned " + "with %d (%s)\n", fd, strerror(errno)); + return -1; + } + + addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0); + if (addr == (void *)(-1)) { + pr_err("Error: mmap() syscall returned with (%s)\n", + strerror(errno)); + goto out_close; + } + + for (n = 0; n < 6; n++) { + u64 stamp, now, delta; + + stamp = mmap_read_self(addr); + + for (i = 0; i < loops; i++) + tmp++; + + now = mmap_read_self(addr); + loops *= 10; + + delta = now - stamp; + pr_debug("%14d: %14Lu\n", n, (long long)delta); + + delta_sum += delta; + } + + munmap(addr, page_size); + pr_debug(" "); +out_close: + close(fd); + + if (!delta_sum) + return -1; + + return 0; +} + +int test__rdpmc(void) +{ + int status = 0; + int wret = 0; + int ret; + int pid; + + pid = fork(); + if (pid < 0) + return -1; + + if (!pid) { + ret = __test__rdpmc(); + + exit(ret); + } + + wret = waitpid(pid, &status, 0); + if (wret < 0 || status) + return -1; + + return 0; +} + +#endif diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 374b039dd22..03d428d7243 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -7,6 +7,7 @@ int test__open_syscall_event(void); int test__open_syscall_event_on_all_cpus(void); int test__basic_mmap(void); int test__PERF_RECORD(void); +int test__rdpmc(void); /* Util */ int trace_event__id(const char *evname); -- cgit v1.2.3 From cfffae2ef7029d38e71d337fbc2a9c6cf1fa5aaf Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Nov 2012 01:46:47 +0100 Subject: perf tests: Move perf_evsel__roundtrip_name_test into separate object Separating perf_evsel__roundtrip_name_test test from the builtin-test into evsel-roundtrip-name object. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352508412-16914-8-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 + tools/perf/tests/builtin-test.c | 112 +------------------------------ tools/perf/tests/evsel-roundtrip-name.c | 114 ++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + 4 files changed, 117 insertions(+), 111 deletions(-) create mode 100644 tools/perf/tests/evsel-roundtrip-name.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 2e5197a0ad6..ad6fcb5f582 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -437,6 +437,7 @@ LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o LIB_OBJS += $(OUTPUT)tests/mmap-basic.o LIB_OBJS += $(OUTPUT)tests/perf-record.o LIB_OBJS += $(OUTPUT)tests/rdpmc.o +LIB_OBJS += $(OUTPUT)tests/evsel-roundtrip-name.o LIB_OBJS += $(OUTPUT)tests/util.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 1e9a0ea68fb..93f5e9176e6 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -35,116 +35,6 @@ static int test__perf_pmu(void) return perf_pmu__test(); } -static int perf_evsel__roundtrip_cache_name_test(void) -{ - char name[128]; - int type, op, err = 0, ret = 0, i, idx; - struct perf_evsel *evsel; - struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); - - if (evlist == NULL) - return -ENOMEM; - - for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { - for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { - /* skip invalid cache type */ - if (!perf_evsel__is_cache_op_valid(type, op)) - continue; - - for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { - __perf_evsel__hw_cache_type_op_res_name(type, op, i, - name, sizeof(name)); - err = parse_events(evlist, name, 0); - if (err) - ret = err; - } - } - } - - idx = 0; - evsel = perf_evlist__first(evlist); - - for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { - for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { - /* skip invalid cache type */ - if (!perf_evsel__is_cache_op_valid(type, op)) - continue; - - for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { - __perf_evsel__hw_cache_type_op_res_name(type, op, i, - name, sizeof(name)); - if (evsel->idx != idx) - continue; - - ++idx; - - if (strcmp(perf_evsel__name(evsel), name)) { - pr_debug("%s != %s\n", perf_evsel__name(evsel), name); - ret = -1; - } - - evsel = perf_evsel__next(evsel); - } - } - } - - perf_evlist__delete(evlist); - return ret; -} - -static int __perf_evsel__name_array_test(const char *names[], int nr_names) -{ - int i, err; - struct perf_evsel *evsel; - struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); - - if (evlist == NULL) - return -ENOMEM; - - for (i = 0; i < nr_names; ++i) { - err = parse_events(evlist, names[i], 0); - if (err) { - pr_debug("failed to parse event '%s', err %d\n", - names[i], err); - goto out_delete_evlist; - } - } - - err = 0; - list_for_each_entry(evsel, &evlist->entries, node) { - if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) { - --err; - pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]); - } - } - -out_delete_evlist: - perf_evlist__delete(evlist); - return err; -} - -#define perf_evsel__name_array_test(names) \ - __perf_evsel__name_array_test(names, ARRAY_SIZE(names)) - -static int perf_evsel__roundtrip_name_test(void) -{ - int err = 0, ret = 0; - - err = perf_evsel__name_array_test(perf_evsel__hw_names); - if (err) - ret = err; - - err = perf_evsel__name_array_test(perf_evsel__sw_names); - if (err) - ret = err; - - err = perf_evsel__roundtrip_cache_name_test(); - if (err) - ret = err; - - return ret; -} - static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name, int size, bool should_be_signed) { @@ -382,7 +272,7 @@ static struct test { }, { .desc = "roundtrip evsel->name check", - .func = perf_evsel__roundtrip_name_test, + .func = test__perf_evsel__roundtrip_name_test, }, { .desc = "Check parsing of sched tracepoints fields", diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c new file mode 100644 index 00000000000..e61fc828a15 --- /dev/null +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -0,0 +1,114 @@ +#include "evlist.h" +#include "evsel.h" +#include "parse-events.h" +#include "tests.h" + +static int perf_evsel__roundtrip_cache_name_test(void) +{ + char name[128]; + int type, op, err = 0, ret = 0, i, idx; + struct perf_evsel *evsel; + struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); + + if (evlist == NULL) + return -ENOMEM; + + for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { + for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { + /* skip invalid cache type */ + if (!perf_evsel__is_cache_op_valid(type, op)) + continue; + + for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { + __perf_evsel__hw_cache_type_op_res_name(type, op, i, + name, sizeof(name)); + err = parse_events(evlist, name, 0); + if (err) + ret = err; + } + } + } + + idx = 0; + evsel = perf_evlist__first(evlist); + + for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { + for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { + /* skip invalid cache type */ + if (!perf_evsel__is_cache_op_valid(type, op)) + continue; + + for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { + __perf_evsel__hw_cache_type_op_res_name(type, op, i, + name, sizeof(name)); + if (evsel->idx != idx) + continue; + + ++idx; + + if (strcmp(perf_evsel__name(evsel), name)) { + pr_debug("%s != %s\n", perf_evsel__name(evsel), name); + ret = -1; + } + + evsel = perf_evsel__next(evsel); + } + } + } + + perf_evlist__delete(evlist); + return ret; +} + +static int __perf_evsel__name_array_test(const char *names[], int nr_names) +{ + int i, err; + struct perf_evsel *evsel; + struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); + + if (evlist == NULL) + return -ENOMEM; + + for (i = 0; i < nr_names; ++i) { + err = parse_events(evlist, names[i], 0); + if (err) { + pr_debug("failed to parse event '%s', err %d\n", + names[i], err); + goto out_delete_evlist; + } + } + + err = 0; + list_for_each_entry(evsel, &evlist->entries, node) { + if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) { + --err; + pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]); + } + } + +out_delete_evlist: + perf_evlist__delete(evlist); + return err; +} + +#define perf_evsel__name_array_test(names) \ + __perf_evsel__name_array_test(names, ARRAY_SIZE(names)) + +int test__perf_evsel__roundtrip_name_test(void) +{ + int err = 0, ret = 0; + + err = perf_evsel__name_array_test(perf_evsel__hw_names); + if (err) + ret = err; + + err = perf_evsel__name_array_test(perf_evsel__sw_names); + if (err) + ret = err; + + err = perf_evsel__roundtrip_cache_name_test(); + if (err) + ret = err; + + return ret; +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 03d428d7243..5897dd13efa 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -8,6 +8,7 @@ int test__open_syscall_event_on_all_cpus(void); int test__basic_mmap(void); int test__PERF_RECORD(void); int test__rdpmc(void); +int test__perf_evsel__roundtrip_name_test(void); /* Util */ int trace_event__id(const char *evname); -- cgit v1.2.3 From 5e24a0904ed4029f6778a214b6fe41b9265fd620 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Nov 2012 01:46:48 +0100 Subject: perf tests: Move perf_evsel__tp_sched_test into separate object Separating perf_evsel__tp_sched_test test from the builtin-test into evsel-tp-sched object. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352508412-16914-9-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 + tools/perf/tests/builtin-test.c | 83 +------------------------------------- tools/perf/tests/evsel-tp-sched.c | 84 +++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + 4 files changed, 87 insertions(+), 82 deletions(-) create mode 100644 tools/perf/tests/evsel-tp-sched.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index ad6fcb5f582..e510b53eb8d 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -438,6 +438,7 @@ LIB_OBJS += $(OUTPUT)tests/mmap-basic.o LIB_OBJS += $(OUTPUT)tests/perf-record.o LIB_OBJS += $(OUTPUT)tests/rdpmc.o LIB_OBJS += $(OUTPUT)tests/evsel-roundtrip-name.o +LIB_OBJS += $(OUTPUT)tests/evsel-tp-sched.o LIB_OBJS += $(OUTPUT)tests/util.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 93f5e9176e6..c66caa79c62 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -35,87 +35,6 @@ static int test__perf_pmu(void) return perf_pmu__test(); } -static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name, - int size, bool should_be_signed) -{ - struct format_field *field = perf_evsel__field(evsel, name); - int is_signed; - int ret = 0; - - if (field == NULL) { - pr_debug("%s: \"%s\" field not found!\n", evsel->name, name); - return -1; - } - - is_signed = !!(field->flags | FIELD_IS_SIGNED); - if (should_be_signed && !is_signed) { - pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n", - evsel->name, name, is_signed, should_be_signed); - ret = -1; - } - - if (field->size != size) { - pr_debug("%s: \"%s\" size (%d) should be %d!\n", - evsel->name, name, field->size, size); - ret = -1; - } - - return ret; -} - -static int perf_evsel__tp_sched_test(void) -{ - struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch", 0); - int ret = 0; - - if (evsel == NULL) { - pr_debug("perf_evsel__new\n"); - return -1; - } - - if (perf_evsel__test_field(evsel, "prev_comm", 16, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "prev_pid", 4, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "prev_prio", 4, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "prev_state", 8, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "next_comm", 16, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "next_pid", 4, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "next_prio", 4, true)) - ret = -1; - - perf_evsel__delete(evsel); - - evsel = perf_evsel__newtp("sched", "sched_wakeup", 0); - - if (perf_evsel__test_field(evsel, "comm", 16, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "pid", 4, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "prio", 4, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "success", 4, true)) - ret = -1; - - if (perf_evsel__test_field(evsel, "target_cpu", 4, true)) - ret = -1; - - return ret; -} - static int test__syscall_open_tp_fields(void) { struct perf_record_opts opts = { @@ -276,7 +195,7 @@ static struct test { }, { .desc = "Check parsing of sched tracepoints fields", - .func = perf_evsel__tp_sched_test, + .func = test__perf_evsel__tp_sched_test, }, { .desc = "Generate and check syscalls:sys_enter_open event fields", diff --git a/tools/perf/tests/evsel-tp-sched.c b/tools/perf/tests/evsel-tp-sched.c new file mode 100644 index 00000000000..a5d2fcc5ae3 --- /dev/null +++ b/tools/perf/tests/evsel-tp-sched.c @@ -0,0 +1,84 @@ +#include "evsel.h" +#include "tests.h" +#include "event-parse.h" + +static int perf_evsel__test_field(struct perf_evsel *evsel, const char *name, + int size, bool should_be_signed) +{ + struct format_field *field = perf_evsel__field(evsel, name); + int is_signed; + int ret = 0; + + if (field == NULL) { + pr_debug("%s: \"%s\" field not found!\n", evsel->name, name); + return -1; + } + + is_signed = !!(field->flags | FIELD_IS_SIGNED); + if (should_be_signed && !is_signed) { + pr_debug("%s: \"%s\" signedness(%d) is wrong, should be %d\n", + evsel->name, name, is_signed, should_be_signed); + ret = -1; + } + + if (field->size != size) { + pr_debug("%s: \"%s\" size (%d) should be %d!\n", + evsel->name, name, field->size, size); + ret = -1; + } + + return ret; +} + +int test__perf_evsel__tp_sched_test(void) +{ + struct perf_evsel *evsel = perf_evsel__newtp("sched", "sched_switch", 0); + int ret = 0; + + if (evsel == NULL) { + pr_debug("perf_evsel__new\n"); + return -1; + } + + if (perf_evsel__test_field(evsel, "prev_comm", 16, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "prev_pid", 4, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "prev_prio", 4, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "prev_state", 8, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "next_comm", 16, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "next_pid", 4, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "next_prio", 4, true)) + ret = -1; + + perf_evsel__delete(evsel); + + evsel = perf_evsel__newtp("sched", "sched_wakeup", 0); + + if (perf_evsel__test_field(evsel, "comm", 16, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "pid", 4, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "prio", 4, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "success", 4, true)) + ret = -1; + + if (perf_evsel__test_field(evsel, "target_cpu", 4, true)) + ret = -1; + + return ret; +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 5897dd13efa..1ef265d84a6 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -9,6 +9,7 @@ int test__basic_mmap(void); int test__PERF_RECORD(void); int test__rdpmc(void); int test__perf_evsel__roundtrip_name_test(void); +int test__perf_evsel__tp_sched_test(void); /* Util */ int trace_event__id(const char *evname); -- cgit v1.2.3 From dc447eed59037c1c65feab9c72d372b6249af978 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Nov 2012 01:46:49 +0100 Subject: perf tests: Move test__syscall_open_tp_fields into separate object Separating test__syscall_open_tp_fields test from the builtin-test into open-syscall-tp-fields object. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352508412-16914-10-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 + tools/perf/tests/builtin-test.c | 112 ---------------------------- tools/perf/tests/open-syscall-tp-fields.c | 117 ++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + 4 files changed, 119 insertions(+), 112 deletions(-) create mode 100644 tools/perf/tests/open-syscall-tp-fields.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index e510b53eb8d..1e505591554 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -434,6 +434,7 @@ LIB_OBJS += $(OUTPUT)tests/attr.o LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o LIB_OBJS += $(OUTPUT)tests/open-syscall.o LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o +LIB_OBJS += $(OUTPUT)tests/open-syscall-tp-fields.o LIB_OBJS += $(OUTPUT)tests/mmap-basic.o LIB_OBJS += $(OUTPUT)tests/perf-record.o LIB_OBJS += $(OUTPUT)tests/rdpmc.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index c66caa79c62..bab84903985 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -35,118 +35,6 @@ static int test__perf_pmu(void) return perf_pmu__test(); } -static int test__syscall_open_tp_fields(void) -{ - struct perf_record_opts opts = { - .target = { - .uid = UINT_MAX, - .uses_mmap = true, - }, - .no_delay = true, - .freq = 1, - .mmap_pages = 256, - .raw_samples = true, - }; - const char *filename = "/etc/passwd"; - int flags = O_RDONLY | O_DIRECTORY; - struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); - struct perf_evsel *evsel; - int err = -1, i, nr_events = 0, nr_polls = 0; - - if (evlist == NULL) { - pr_debug("%s: perf_evlist__new\n", __func__); - goto out; - } - - evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0); - if (evsel == NULL) { - pr_debug("%s: perf_evsel__newtp\n", __func__); - goto out_delete_evlist; - } - - perf_evlist__add(evlist, evsel); - - err = perf_evlist__create_maps(evlist, &opts.target); - if (err < 0) { - pr_debug("%s: perf_evlist__create_maps\n", __func__); - goto out_delete_evlist; - } - - perf_evsel__config(evsel, &opts, evsel); - - evlist->threads->map[0] = getpid(); - - err = perf_evlist__open(evlist); - if (err < 0) { - pr_debug("perf_evlist__open: %s\n", strerror(errno)); - goto out_delete_evlist; - } - - err = perf_evlist__mmap(evlist, UINT_MAX, false); - if (err < 0) { - pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); - goto out_delete_evlist; - } - - perf_evlist__enable(evlist); - - /* - * Generate the event: - */ - open(filename, flags); - - while (1) { - int before = nr_events; - - for (i = 0; i < evlist->nr_mmaps; i++) { - union perf_event *event; - - while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { - const u32 type = event->header.type; - int tp_flags; - struct perf_sample sample; - - ++nr_events; - - if (type != PERF_RECORD_SAMPLE) - continue; - - err = perf_evsel__parse_sample(evsel, event, &sample); - if (err) { - pr_err("Can't parse sample, err = %d\n", err); - goto out_munmap; - } - - tp_flags = perf_evsel__intval(evsel, &sample, "flags"); - - if (flags != tp_flags) { - pr_debug("%s: Expected flags=%#x, got %#x\n", - __func__, flags, tp_flags); - goto out_munmap; - } - - goto out_ok; - } - } - - if (nr_events == before) - poll(evlist->pollfd, evlist->nr_fds, 10); - - if (++nr_polls > 5) { - pr_debug("%s: no events!\n", __func__); - goto out_munmap; - } - } -out_ok: - err = 0; -out_munmap: - perf_evlist__munmap(evlist); -out_delete_evlist: - perf_evlist__delete(evlist); -out: - return err; -} - static struct test { const char *desc; int (*func)(void); diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c new file mode 100644 index 00000000000..b05b6a6f01a --- /dev/null +++ b/tools/perf/tests/open-syscall-tp-fields.c @@ -0,0 +1,117 @@ +#include "perf.h" +#include "evlist.h" +#include "evsel.h" +#include "thread_map.h" +#include "tests.h" + +int test__syscall_open_tp_fields(void) +{ + struct perf_record_opts opts = { + .target = { + .uid = UINT_MAX, + .uses_mmap = true, + }, + .no_delay = true, + .freq = 1, + .mmap_pages = 256, + .raw_samples = true, + }; + const char *filename = "/etc/passwd"; + int flags = O_RDONLY | O_DIRECTORY; + struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); + struct perf_evsel *evsel; + int err = -1, i, nr_events = 0, nr_polls = 0; + + if (evlist == NULL) { + pr_debug("%s: perf_evlist__new\n", __func__); + goto out; + } + + evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0); + if (evsel == NULL) { + pr_debug("%s: perf_evsel__newtp\n", __func__); + goto out_delete_evlist; + } + + perf_evlist__add(evlist, evsel); + + err = perf_evlist__create_maps(evlist, &opts.target); + if (err < 0) { + pr_debug("%s: perf_evlist__create_maps\n", __func__); + goto out_delete_evlist; + } + + perf_evsel__config(evsel, &opts, evsel); + + evlist->threads->map[0] = getpid(); + + err = perf_evlist__open(evlist); + if (err < 0) { + pr_debug("perf_evlist__open: %s\n", strerror(errno)); + goto out_delete_evlist; + } + + err = perf_evlist__mmap(evlist, UINT_MAX, false); + if (err < 0) { + pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); + goto out_delete_evlist; + } + + perf_evlist__enable(evlist); + + /* + * Generate the event: + */ + open(filename, flags); + + while (1) { + int before = nr_events; + + for (i = 0; i < evlist->nr_mmaps; i++) { + union perf_event *event; + + while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { + const u32 type = event->header.type; + int tp_flags; + struct perf_sample sample; + + ++nr_events; + + if (type != PERF_RECORD_SAMPLE) + continue; + + err = perf_evsel__parse_sample(evsel, event, &sample); + if (err) { + pr_err("Can't parse sample, err = %d\n", err); + goto out_munmap; + } + + tp_flags = perf_evsel__intval(evsel, &sample, "flags"); + + if (flags != tp_flags) { + pr_debug("%s: Expected flags=%#x, got %#x\n", + __func__, flags, tp_flags); + goto out_munmap; + } + + goto out_ok; + } + } + + if (nr_events == before) + poll(evlist->pollfd, evlist->nr_fds, 10); + + if (++nr_polls > 5) { + pr_debug("%s: no events!\n", __func__); + goto out_munmap; + } + } +out_ok: + err = 0; +out_munmap: + perf_evlist__munmap(evlist); +out_delete_evlist: + perf_evlist__delete(evlist); +out: + return err; +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 1ef265d84a6..f70f99848a2 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -10,6 +10,7 @@ int test__PERF_RECORD(void); int test__rdpmc(void); int test__perf_evsel__roundtrip_name_test(void); int test__perf_evsel__tp_sched_test(void); +int test__syscall_open_tp_fields(void); /* Util */ int trace_event__id(const char *evname); -- cgit v1.2.3 From cff7f956ec4a1ede9b752cfae3c12f588292ad80 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Nov 2012 01:46:50 +0100 Subject: perf tests: Move pmu tests into separate object Separating pmu's object tests into pmu object under tests directory. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352508412-16914-11-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 + tools/perf/tests/builtin-test.c | 7 +- tools/perf/tests/pmu.c | 178 ++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/util/pmu.c | 185 ++-------------------------------------- tools/perf/util/pmu.h | 4 + 6 files changed, 191 insertions(+), 185 deletions(-) create mode 100644 tools/perf/tests/pmu.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 1e505591554..9af012f3771 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -440,6 +440,7 @@ LIB_OBJS += $(OUTPUT)tests/perf-record.o LIB_OBJS += $(OUTPUT)tests/rdpmc.o LIB_OBJS += $(OUTPUT)tests/evsel-roundtrip-name.o LIB_OBJS += $(OUTPUT)tests/evsel-tp-sched.o +LIB_OBJS += $(OUTPUT)tests/pmu.o LIB_OBJS += $(OUTPUT)tests/util.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index bab84903985..d3b95e04b7a 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -30,11 +30,6 @@ #include -static int test__perf_pmu(void) -{ - return perf_pmu__test(); -} - static struct test { const char *desc; int (*func)(void); @@ -71,7 +66,7 @@ static struct test { }, { .desc = "Test perf pmu format parsing", - .func = test__perf_pmu, + .func = test__pmu, }, { .desc = "Test dso data interface", diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c new file mode 100644 index 00000000000..a5f379863b8 --- /dev/null +++ b/tools/perf/tests/pmu.c @@ -0,0 +1,178 @@ +#include "parse-events.h" +#include "pmu.h" +#include "util.h" +#include "tests.h" + +/* Simulated format definitions. */ +static struct test_format { + const char *name; + const char *value; +} test_formats[] = { + { "krava01", "config:0-1,62-63\n", }, + { "krava02", "config:10-17\n", }, + { "krava03", "config:5\n", }, + { "krava11", "config1:0,2,4,6,8,20-28\n", }, + { "krava12", "config1:63\n", }, + { "krava13", "config1:45-47\n", }, + { "krava21", "config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", }, + { "krava22", "config2:8,18,48,58\n", }, + { "krava23", "config2:28-29,38\n", }, +}; + +#define TEST_FORMATS_CNT (sizeof(test_formats) / sizeof(struct test_format)) + +/* Simulated users input. */ +static struct parse_events__term test_terms[] = { + { + .config = (char *) "krava01", + .val.num = 15, + .type_val = PARSE_EVENTS__TERM_TYPE_NUM, + .type_term = PARSE_EVENTS__TERM_TYPE_USER, + }, + { + .config = (char *) "krava02", + .val.num = 170, + .type_val = PARSE_EVENTS__TERM_TYPE_NUM, + .type_term = PARSE_EVENTS__TERM_TYPE_USER, + }, + { + .config = (char *) "krava03", + .val.num = 1, + .type_val = PARSE_EVENTS__TERM_TYPE_NUM, + .type_term = PARSE_EVENTS__TERM_TYPE_USER, + }, + { + .config = (char *) "krava11", + .val.num = 27, + .type_val = PARSE_EVENTS__TERM_TYPE_NUM, + .type_term = PARSE_EVENTS__TERM_TYPE_USER, + }, + { + .config = (char *) "krava12", + .val.num = 1, + .type_val = PARSE_EVENTS__TERM_TYPE_NUM, + .type_term = PARSE_EVENTS__TERM_TYPE_USER, + }, + { + .config = (char *) "krava13", + .val.num = 2, + .type_val = PARSE_EVENTS__TERM_TYPE_NUM, + .type_term = PARSE_EVENTS__TERM_TYPE_USER, + }, + { + .config = (char *) "krava21", + .val.num = 119, + .type_val = PARSE_EVENTS__TERM_TYPE_NUM, + .type_term = PARSE_EVENTS__TERM_TYPE_USER, + }, + { + .config = (char *) "krava22", + .val.num = 11, + .type_val = PARSE_EVENTS__TERM_TYPE_NUM, + .type_term = PARSE_EVENTS__TERM_TYPE_USER, + }, + { + .config = (char *) "krava23", + .val.num = 2, + .type_val = PARSE_EVENTS__TERM_TYPE_NUM, + .type_term = PARSE_EVENTS__TERM_TYPE_USER, + }, +}; +#define TERMS_CNT (sizeof(test_terms) / sizeof(struct parse_events__term)) + +/* + * Prepare format directory data, exported by kernel + * at /sys/bus/event_source/devices//format. + */ +static char *test_format_dir_get(void) +{ + static char dir[PATH_MAX]; + unsigned int i; + + snprintf(dir, PATH_MAX, "/tmp/perf-pmu-test-format-XXXXXX"); + if (!mkdtemp(dir)) + return NULL; + + for (i = 0; i < TEST_FORMATS_CNT; i++) { + static char name[PATH_MAX]; + struct test_format *format = &test_formats[i]; + FILE *file; + + snprintf(name, PATH_MAX, "%s/%s", dir, format->name); + + file = fopen(name, "w"); + if (!file) + return NULL; + + if (1 != fwrite(format->value, strlen(format->value), 1, file)) + break; + + fclose(file); + } + + return dir; +} + +/* Cleanup format directory. */ +static int test_format_dir_put(char *dir) +{ + char buf[PATH_MAX]; + snprintf(buf, PATH_MAX, "rm -f %s/*\n", dir); + if (system(buf)) + return -1; + + snprintf(buf, PATH_MAX, "rmdir %s\n", dir); + return system(buf); +} + +static struct list_head *test_terms_list(void) +{ + static LIST_HEAD(terms); + unsigned int i; + + for (i = 0; i < TERMS_CNT; i++) + list_add_tail(&test_terms[i].list, &terms); + + return &terms; +} + +#undef TERMS_CNT + +int test__pmu(void) +{ + char *format = test_format_dir_get(); + LIST_HEAD(formats); + struct list_head *terms = test_terms_list(); + int ret; + + if (!format) + return -EINVAL; + + do { + struct perf_event_attr attr; + + memset(&attr, 0, sizeof(attr)); + + ret = perf_pmu__format_parse(format, &formats); + if (ret) + break; + + ret = perf_pmu__config_terms(&formats, &attr, terms); + if (ret) + break; + + ret = -EINVAL; + + if (attr.config != 0xc00000000002a823) + break; + if (attr.config1 != 0x8000400000000145) + break; + if (attr.config2 != 0x0400000020041d07) + break; + + ret = 0; + } while (0); + + test_format_dir_put(format); + return ret; +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index f70f99848a2..88a55dfa99d 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -11,6 +11,7 @@ int test__rdpmc(void); int test__perf_evsel__roundtrip_name_test(void); int test__perf_evsel__tp_sched_test(void); int test__syscall_open_tp_fields(void); +int test__pmu(void); /* Util */ int trace_event__id(const char *evname); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 18e84801d4d..9bdc60c6f13 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -22,7 +22,7 @@ static LIST_HEAD(pmus); * Parse & process all the sysfs attributes located under * the directory specified in 'dir' parameter. */ -static int pmu_format_parse(char *dir, struct list_head *head) +int perf_pmu__format_parse(char *dir, struct list_head *head) { struct dirent *evt_ent; DIR *format_dir; @@ -77,7 +77,7 @@ static int pmu_format(char *name, struct list_head *format) if (stat(path, &st) < 0) return 0; /* no error if format does not exist */ - if (pmu_format_parse(path, format)) + if (perf_pmu__format_parse(path, format)) return -1; return 0; @@ -446,8 +446,9 @@ static int pmu_config_term(struct list_head *formats, return 0; } -static int pmu_config(struct list_head *formats, struct perf_event_attr *attr, - struct list_head *head_terms) +int perf_pmu__config_terms(struct list_head *formats, + struct perf_event_attr *attr, + struct list_head *head_terms) { struct parse_events__term *term; @@ -467,7 +468,7 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, struct list_head *head_terms) { attr->type = pmu->type; - return pmu_config(&pmu->format, attr, head_terms); + return perf_pmu__config_terms(&pmu->format, attr, head_terms); } static struct perf_pmu__alias *pmu_find_alias(struct perf_pmu *pmu, @@ -551,177 +552,3 @@ void perf_pmu__set_format(unsigned long *bits, long from, long to) for (b = from; b <= to; b++) set_bit(b, bits); } - -/* Simulated format definitions. */ -static struct test_format { - const char *name; - const char *value; -} test_formats[] = { - { "krava01", "config:0-1,62-63\n", }, - { "krava02", "config:10-17\n", }, - { "krava03", "config:5\n", }, - { "krava11", "config1:0,2,4,6,8,20-28\n", }, - { "krava12", "config1:63\n", }, - { "krava13", "config1:45-47\n", }, - { "krava21", "config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", }, - { "krava22", "config2:8,18,48,58\n", }, - { "krava23", "config2:28-29,38\n", }, -}; - -#define TEST_FORMATS_CNT (sizeof(test_formats) / sizeof(struct test_format)) - -/* Simulated users input. */ -static struct parse_events__term test_terms[] = { - { - .config = (char *) "krava01", - .val.num = 15, - .type_val = PARSE_EVENTS__TERM_TYPE_NUM, - .type_term = PARSE_EVENTS__TERM_TYPE_USER, - }, - { - .config = (char *) "krava02", - .val.num = 170, - .type_val = PARSE_EVENTS__TERM_TYPE_NUM, - .type_term = PARSE_EVENTS__TERM_TYPE_USER, - }, - { - .config = (char *) "krava03", - .val.num = 1, - .type_val = PARSE_EVENTS__TERM_TYPE_NUM, - .type_term = PARSE_EVENTS__TERM_TYPE_USER, - }, - { - .config = (char *) "krava11", - .val.num = 27, - .type_val = PARSE_EVENTS__TERM_TYPE_NUM, - .type_term = PARSE_EVENTS__TERM_TYPE_USER, - }, - { - .config = (char *) "krava12", - .val.num = 1, - .type_val = PARSE_EVENTS__TERM_TYPE_NUM, - .type_term = PARSE_EVENTS__TERM_TYPE_USER, - }, - { - .config = (char *) "krava13", - .val.num = 2, - .type_val = PARSE_EVENTS__TERM_TYPE_NUM, - .type_term = PARSE_EVENTS__TERM_TYPE_USER, - }, - { - .config = (char *) "krava21", - .val.num = 119, - .type_val = PARSE_EVENTS__TERM_TYPE_NUM, - .type_term = PARSE_EVENTS__TERM_TYPE_USER, - }, - { - .config = (char *) "krava22", - .val.num = 11, - .type_val = PARSE_EVENTS__TERM_TYPE_NUM, - .type_term = PARSE_EVENTS__TERM_TYPE_USER, - }, - { - .config = (char *) "krava23", - .val.num = 2, - .type_val = PARSE_EVENTS__TERM_TYPE_NUM, - .type_term = PARSE_EVENTS__TERM_TYPE_USER, - }, -}; -#define TERMS_CNT (sizeof(test_terms) / sizeof(struct parse_events__term)) - -/* - * Prepare format directory data, exported by kernel - * at /sys/bus/event_source/devices//format. - */ -static char *test_format_dir_get(void) -{ - static char dir[PATH_MAX]; - unsigned int i; - - snprintf(dir, PATH_MAX, "/tmp/perf-pmu-test-format-XXXXXX"); - if (!mkdtemp(dir)) - return NULL; - - for (i = 0; i < TEST_FORMATS_CNT; i++) { - static char name[PATH_MAX]; - struct test_format *format = &test_formats[i]; - FILE *file; - - snprintf(name, PATH_MAX, "%s/%s", dir, format->name); - - file = fopen(name, "w"); - if (!file) - return NULL; - - if (1 != fwrite(format->value, strlen(format->value), 1, file)) - break; - - fclose(file); - } - - return dir; -} - -/* Cleanup format directory. */ -static int test_format_dir_put(char *dir) -{ - char buf[PATH_MAX]; - snprintf(buf, PATH_MAX, "rm -f %s/*\n", dir); - if (system(buf)) - return -1; - - snprintf(buf, PATH_MAX, "rmdir %s\n", dir); - return system(buf); -} - -static struct list_head *test_terms_list(void) -{ - static LIST_HEAD(terms); - unsigned int i; - - for (i = 0; i < TERMS_CNT; i++) - list_add_tail(&test_terms[i].list, &terms); - - return &terms; -} - -#undef TERMS_CNT - -int perf_pmu__test(void) -{ - char *format = test_format_dir_get(); - LIST_HEAD(formats); - struct list_head *terms = test_terms_list(); - int ret; - - if (!format) - return -EINVAL; - - do { - struct perf_event_attr attr; - - memset(&attr, 0, sizeof(attr)); - - ret = pmu_format_parse(format, &formats); - if (ret) - break; - - ret = pmu_config(&formats, &attr, terms); - if (ret) - break; - - ret = -EINVAL; - - if (attr.config != 0xc00000000002a823) - break; - if (attr.config1 != 0x8000400000000145) - break; - if (attr.config2 != 0x0400000020041d07) - break; - - ret = 0; - } while (0); - - test_format_dir_put(format); - return ret; -} diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 39f3abac774..07d553fe8d8 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -37,6 +37,9 @@ struct perf_pmu { struct perf_pmu *perf_pmu__find(char *name); int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, struct list_head *head_terms); +int perf_pmu__config_terms(struct list_head *formats, + struct perf_event_attr *attr, + struct list_head *head_terms); int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms); struct list_head *perf_pmu__alias(struct perf_pmu *pmu, struct list_head *head_terms); @@ -46,6 +49,7 @@ void perf_pmu_error(struct list_head *list, char *name, char const *msg); int perf_pmu__new_format(struct list_head *list, char *name, int config, unsigned long *bits); void perf_pmu__set_format(unsigned long *bits, long from, long to); +int perf_pmu__format_parse(char *dir, struct list_head *head); struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu); -- cgit v1.2.3 From c81251e808fe2386e71990ecd49c408bb7cb4666 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Nov 2012 01:46:51 +0100 Subject: perf tests: Final cleanup for builtin-test move Final function renames to match test__* style and include cleanup. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352508412-16914-12-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/perf.h | 1 - tools/perf/tests/attr.c | 3 ++- tools/perf/tests/builtin-test.c | 34 +++++++--------------------------- tools/perf/tests/dso-data.c | 3 ++- tools/perf/tests/parse-events.c | 3 ++- tools/perf/tests/tests.h | 3 +++ tools/perf/util/parse-events.h | 1 - tools/perf/util/symbol.h | 1 - 8 files changed, 16 insertions(+), 33 deletions(-) diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 054182e41dc..00472646b3b 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -178,7 +178,6 @@ extern bool test_attr__enabled; void test_attr__init(void); void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, int fd, int group_fd, unsigned long flags); -int test_attr__run(void); static inline int sys_perf_event_open(struct perf_event_attr *attr, diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index 6e2feee8db2..25638a98625 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -27,6 +27,7 @@ #include "../perf.h" #include "util.h" #include "exec_cmd.h" +#include "tests.h" #define ENV "PERF_TEST_ATTR" @@ -151,7 +152,7 @@ static int run_dir(const char *d, const char *perf) return system(cmd); } -int test_attr__run(void) +int test__attr(void) { struct stat st; char path_perf[PATH_MAX]; diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index d3b95e04b7a..186f6753549 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -4,31 +4,11 @@ * Builtin regression testing command: ever growing number of sanity tests */ #include "builtin.h" - -#include "util/cache.h" -#include "util/color.h" -#include "util/debug.h" -#include "util/debugfs.h" -#include "util/evlist.h" -#include "util/machine.h" -#include "util/parse-options.h" -#include "util/parse-events.h" -#include "util/symbol.h" -#include "util/thread_map.h" -#include "util/pmu.h" -#include "event-parse.h" -#include "../../include/linux/hw_breakpoint.h" - -#include - -#include "util/cpumap.h" -#include "util/evsel.h" -#include - #include "tests.h" - -#include - +#include "debug.h" +#include "color.h" +#include "parse-options.h" +#include "symbol.h" static struct test { const char *desc; @@ -52,7 +32,7 @@ static struct test { }, { .desc = "parse events tests", - .func = parse_events__test, + .func = test__parse_events, }, #if defined(__x86_64__) || defined(__i386__) { @@ -70,7 +50,7 @@ static struct test { }, { .desc = "Test dso data interface", - .func = dso__test_data, + .func = test__dso_data, }, { .desc = "roundtrip evsel->name check", @@ -86,7 +66,7 @@ static struct test { }, { .desc = "struct perf_event_attr setup", - .func = test_attr__run, + .func = test__attr, }, { .func = NULL, diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index 0cd42fc9bc1..b5198f52c24 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -8,6 +8,7 @@ #include "machine.h" #include "symbol.h" +#include "tests.h" #define TEST_ASSERT_VAL(text, cond) \ do { \ @@ -95,7 +96,7 @@ struct test_data_offset offsets[] = { }, }; -int dso__test_data(void) +int test__dso_data(void) { struct machine machine; struct dso *dso; diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index b49c2eebff3..f2a82d0158c 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -4,6 +4,7 @@ #include "evlist.h" #include "sysfs.h" #include "../../../include/linux/hw_breakpoint.h" +#include "tests.h" #define TEST_ASSERT_VAL(text, cond) \ do { \ @@ -1086,7 +1087,7 @@ static int test_pmu_events(void) return ret; } -int parse_events__test(void) +int test__parse_events(void) { int ret1, ret2 = 0; diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 88a55dfa99d..fc121edab01 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -12,6 +12,9 @@ int test__perf_evsel__roundtrip_name_test(void); int test__perf_evsel__tp_sched_test(void); int test__syscall_open_tp_fields(void); int test__pmu(void); +int test__attr(void); +int test__dso_data(void); +int test__parse_events(void); /* Util */ int trace_event__id(const char *evname); diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index ac9a6aacf2f..f6399373d67 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -99,7 +99,6 @@ void parse_events__set_leader(char *name, struct list_head *list); void parse_events_update_lists(struct list_head *list_event, struct list_head *list_all); void parse_events_error(void *data, void *scanner, char const *msg); -int parse_events__test(void); void print_events(const char *event_glob, bool name_only); void print_events_type(u8 type); diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 04ccf296208..de68f98b236 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -224,7 +224,6 @@ size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp); size_t symbol__fprintf(struct symbol *sym, FILE *fp); bool symbol_type__is_a(char symbol_type, enum map_type map_type); -int dso__test_data(void); int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, struct symsrc *runtime_ss, symbol_filter_t filter, int kmodule); -- cgit v1.2.3 From f95e0818cbd026a8f2277895c65fcc9cc5b28cf6 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sat, 10 Nov 2012 01:46:52 +0100 Subject: perf tests: Check for mkstemp return value in dso-data test Adding check for mkstemp return error value in dso-data test. Reported-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352508412-16914-13-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/dso-data.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index b5198f52c24..5eaffa2de9c 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -26,6 +26,10 @@ static char *test_file(int size) unsigned char *buf; fd = mkstemp(templ); + if (fd < 0) { + perror("mkstemp failed"); + return NULL; + } buf = malloc(size); if (!buf) { -- cgit v1.2.3 From 61e945150fe0ec4c20b7a3663b90c7ab705a88b4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 10 Nov 2012 19:41:15 -0300 Subject: perf tools: Stop using 'self' in pstack As suggested by tglx long ago. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-zgcldbjno41jn02b15760k4p@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/pstack.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/tools/perf/util/pstack.c b/tools/perf/util/pstack.c index 13d36faf64e..daa17aeb6c6 100644 --- a/tools/perf/util/pstack.c +++ b/tools/perf/util/pstack.c @@ -17,59 +17,59 @@ struct pstack { struct pstack *pstack__new(unsigned short max_nr_entries) { - struct pstack *self = zalloc((sizeof(*self) + - max_nr_entries * sizeof(void *))); - if (self != NULL) - self->max_nr_entries = max_nr_entries; - return self; + struct pstack *pstack = zalloc((sizeof(*pstack) + + max_nr_entries * sizeof(void *))); + if (pstack != NULL) + pstack->max_nr_entries = max_nr_entries; + return pstack; } -void pstack__delete(struct pstack *self) +void pstack__delete(struct pstack *pstack) { - free(self); + free(pstack); } -bool pstack__empty(const struct pstack *self) +bool pstack__empty(const struct pstack *pstack) { - return self->top == 0; + return pstack->top == 0; } -void pstack__remove(struct pstack *self, void *key) +void pstack__remove(struct pstack *pstack, void *key) { - unsigned short i = self->top, last_index = self->top - 1; + unsigned short i = pstack->top, last_index = pstack->top - 1; while (i-- != 0) { - if (self->entries[i] == key) { + if (pstack->entries[i] == key) { if (i < last_index) - memmove(self->entries + i, - self->entries + i + 1, + memmove(pstack->entries + i, + pstack->entries + i + 1, (last_index - i) * sizeof(void *)); - --self->top; + --pstack->top; return; } } pr_err("%s: %p not on the pstack!\n", __func__, key); } -void pstack__push(struct pstack *self, void *key) +void pstack__push(struct pstack *pstack, void *key) { - if (self->top == self->max_nr_entries) { - pr_err("%s: top=%d, overflow!\n", __func__, self->top); + if (pstack->top == pstack->max_nr_entries) { + pr_err("%s: top=%d, overflow!\n", __func__, pstack->top); return; } - self->entries[self->top++] = key; + pstack->entries[pstack->top++] = key; } -void *pstack__pop(struct pstack *self) +void *pstack__pop(struct pstack *pstack) { void *ret; - if (self->top == 0) { + if (pstack->top == 0) { pr_err("%s: underflow!\n", __func__); return NULL; } - ret = self->entries[--self->top]; - self->entries[self->top] = NULL; + ret = pstack->entries[--pstack->top]; + pstack->entries[pstack->top] = NULL; return ret; } -- cgit v1.2.3 From 30193d78d82a68247aa628a2414dc0f76c5b8093 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 12 Nov 2012 13:20:03 -0300 Subject: perf hists: Initialize all of he->stat with zeroes Not just nr_events and period. Reported-by: Namhyung Kim Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-8nodd6b4bytyf1snf96oy531@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 7c6e73b1b7e..cb17e2a8c6e 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -742,9 +742,8 @@ static struct hist_entry *hists__add_dummy_entry(struct hists *hists, he = hist_entry__new(pair); if (he) { - he->stat.nr_events = 0; - he->stat.period = 0; - he->hists = hists; + memset(&he->stat, 0, sizeof(he->stat)); + he->hists = hists; rb_link_node(&he->rb_node, parent, p); rb_insert_color(&he->rb_node, &hists->entries); hists__inc_nr_entries(hists, he); -- cgit v1.2.3 From 4f746c95f18ad4d85599d9c157da7e6da766c3d9 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 12 Nov 2012 14:14:00 +0900 Subject: perf tools: Fix compile error on NO_NEWT=1 build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC builtin-annotate.o In file included from util/evsel.h:10:0, from util/evlist.h:8, from builtin-annotate.c:20: util/hist.h: In function ‘script_browse’: util/hist.h:198:45: error: unused parameter ‘script_opt’ [-Werror=unused-parameter] cc1: all warnings being treated as errors make: *** [builtin-annotate.o] Error 1 make: *** Waiting for unfinished jobs.... Signed-off-by: Namhyung Kim Cc: Feng Tang Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352697240-422-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 1278c2c72a9..8b091a51e4a 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -195,7 +195,7 @@ static inline int hist_entry__tui_annotate(struct hist_entry *self return 0; } -static inline int script_browse(const char *script_opt) +static inline int script_browse(const char *script_opt __maybe_unused) { return 0; } -- cgit v1.2.3 From 0020ce23864d16f66e5667013b8b43d1df3e142e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 12 Nov 2012 11:50:17 +0900 Subject: perf tools: Add gtk. config option for launching GTK browser Add config option for launching GTK browser for the specified command by default. Currently only 'report' command is supported. Adding following line to the perfconfig file will have a same effect of specifying --gtk option on command line (unless other related options are not given). $ cat ~/.perfconfig [gtk] report = true Signed-off-by: Namhyung Kim Acked-by: Pekka Enberg Cc: Ingo Molnar Cc: Paul Mackerras Cc: Pekka Enberg Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352688617-25570-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/perf.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/perf/perf.c b/tools/perf/perf.c index a0ae2902f9c..0f661fbce6a 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -85,21 +85,26 @@ int check_pager_config(const char *cmd) return c.val; } -static int tui_command_config(const char *var, const char *value, void *data) +static int browser_command_config(const char *var, const char *value, void *data) { struct pager_config *c = data; if (!prefixcmp(var, "tui.") && !strcmp(var + 4, c->cmd)) c->val = perf_config_bool(var, value); + if (!prefixcmp(var, "gtk.") && !strcmp(var + 4, c->cmd)) + c->val = perf_config_bool(var, value) ? 2 : 0; return 0; } -/* returns 0 for "no tui", 1 for "use tui", and -1 for "not specified" */ -static int check_tui_config(const char *cmd) +/* + * returns 0 for "no tui", 1 for "use tui", 2 for "use gtk", + * and -1 for "not specified" + */ +static int check_browser_config(const char *cmd) { struct pager_config c; c.cmd = cmd; c.val = -1; - perf_config(tui_command_config, &c); + perf_config(browser_command_config, &c); return c.val; } @@ -302,7 +307,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) prefix = NULL; /* setup_perf_directory(); */ if (use_browser == -1) - use_browser = check_tui_config(p->cmd); + use_browser = check_browser_config(p->cmd); if (use_pager == -1 && p->option & RUN_SETUP) use_pager = check_pager_config(p->cmd); -- cgit v1.2.3 From 6064803313bad9ae4cae233a9d56678adb2b6e7c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Sun, 11 Nov 2012 23:20:50 +0900 Subject: perf tools: Use sscanf for parsing /proc/pid/maps When reading those files to synthesize MMAP events. It makes the code shorter and cleaner. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1352643651-13891-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.c | 74 +++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 43 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index ca9ca285406..3cf2c3e0605 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -193,55 +193,43 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, event->header.misc = PERF_RECORD_MISC_USER; while (1) { - char bf[BUFSIZ], *pbf = bf; - int n; + char bf[BUFSIZ]; + char prot[5]; + char execname[PATH_MAX]; + char anonstr[] = "//anon"; size_t size; + if (fgets(bf, sizeof(bf), fp) == NULL) break; + /* ensure null termination since stack will be reused. */ + strcpy(execname, ""); + /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ - n = hex2u64(pbf, &event->mmap.start); - if (n < 0) - continue; - pbf += n + 1; - n = hex2u64(pbf, &event->mmap.len); - if (n < 0) + sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %*x:%*x %*u %s\n", + &event->mmap.start, &event->mmap.len, prot, + &event->mmap.pgoff, execname); + + if (prot[2] != 'x') continue; - pbf += n + 3; - if (*pbf == 'x') { /* vm_exec */ - char anonstr[] = "//anon\n"; - char *execname = strchr(bf, '/'); - - /* Catch VDSO */ - if (execname == NULL) - execname = strstr(bf, "[vdso]"); - - /* Catch anonymous mmaps */ - if ((execname == NULL) && !strstr(bf, "[")) - execname = anonstr; - - if (execname == NULL) - continue; - - pbf += 3; - n = hex2u64(pbf, &event->mmap.pgoff); - - size = strlen(execname); - execname[size - 1] = '\0'; /* Remove \n */ - memcpy(event->mmap.filename, execname, size); - size = PERF_ALIGN(size, sizeof(u64)); - event->mmap.len -= event->mmap.start; - event->mmap.header.size = (sizeof(event->mmap) - - (sizeof(event->mmap.filename) - size)); - memset(event->mmap.filename + size, 0, machine->id_hdr_size); - event->mmap.header.size += machine->id_hdr_size; - event->mmap.pid = tgid; - event->mmap.tid = pid; - - if (process(tool, event, &synth_sample, machine) != 0) { - rc = -1; - break; - } + + if (!strcmp(execname, "")) + strcpy(execname, anonstr); + + size = strlen(execname) + 1; + memcpy(event->mmap.filename, execname, size); + size = PERF_ALIGN(size, sizeof(u64)); + event->mmap.len -= event->mmap.start; + event->mmap.header.size = (sizeof(event->mmap) - + (sizeof(event->mmap.filename) - size)); + memset(event->mmap.filename + size, 0, machine->id_hdr_size); + event->mmap.header.size += machine->id_hdr_size; + event->mmap.pid = tgid; + event->mmap.tid = pid; + + if (process(tool, event, &synth_sample, machine) != 0) { + rc = -1; + break; } } -- cgit v1.2.3 From cac21425578abddc4e9f529845832a57ba27ce0f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 12 Nov 2012 18:34:00 +0100 Subject: perf tools: Fix attributes for '{}' defined event groups Fixing events attributes for groups defined via '{}'. Currently 'enable_on_exec' attribute in record command and both 'disabled ' and 'enable_on_exec' attributes in stat command are set based on the 'group' option. This eliminates proper setup for '{}' defined groups as they don't set 'group' option. Making above attributes values based on the 'evsel->leader' as this is common to both group definition. Moving perf_evlist__set_leader call within builtin-record ahead perf_evlist__config_attrs call, because the latter needs possible group leader links in place. Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352741644-16809-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 8 ++++++-- tools/perf/builtin-stat.c | 11 ++++------- tools/perf/tests/attr/test-record-group1 | 4 +--- tools/perf/tests/attr/test-stat-group1 | 6 ++---- tools/perf/tests/open-syscall-tp-fields.c | 2 +- tools/perf/util/evlist.c | 6 ++---- tools/perf/util/evsel.c | 8 +++----- tools/perf/util/evsel.h | 3 +-- 8 files changed, 20 insertions(+), 28 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 5783c322511..371702785d6 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -230,11 +230,15 @@ static int perf_record__open(struct perf_record *rec) struct perf_record_opts *opts = &rec->opts; int rc = 0; - perf_evlist__config_attrs(evlist, opts); - + /* + * Set the evsel leader links before we configure attributes, + * since some might depend on this info. + */ if (opts->group) perf_evlist__set_leader(evlist); + perf_evlist__config_attrs(evlist, opts); + list_for_each_entry(pos, &evlist->entries, node) { struct perf_event_attr *attr = &pos->attr; /* diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 6888960ef8b..557081e0c6d 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -129,8 +129,7 @@ static struct stats runtime_itlb_cache_stats[MAX_NR_CPUS]; static struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS]; static struct stats walltime_nsecs_stats; -static int create_perf_stat_counter(struct perf_evsel *evsel, - struct perf_evsel *first) +static int create_perf_stat_counter(struct perf_evsel *evsel) { struct perf_event_attr *attr = &evsel->attr; bool exclude_guest_missing = false; @@ -153,7 +152,7 @@ retry: return 0; } - if (!perf_target__has_task(&target) && (!group || evsel == first)) { + if (!perf_target__has_task(&target) && (!evsel->leader)) { attr->disabled = 1; attr->enable_on_exec = 1; } @@ -272,7 +271,7 @@ static int read_counter(struct perf_evsel *counter) static int __run_perf_stat(int argc __maybe_unused, const char **argv) { unsigned long long t0, t1; - struct perf_evsel *counter, *first; + struct perf_evsel *counter; int status = 0; int child_ready_pipe[2], go_pipe[2]; const bool forks = (argc > 0); @@ -332,10 +331,8 @@ static int __run_perf_stat(int argc __maybe_unused, const char **argv) if (group) perf_evlist__set_leader(evsel_list); - first = perf_evlist__first(evsel_list); - list_for_each_entry(counter, &evsel_list->entries, node) { - if (create_perf_stat_counter(counter, first) < 0) { + if (create_perf_stat_counter(counter) < 0) { /* * PPC returns ENXIO for HW counters until 2.6.37 * (behavior changed with commit b0a873e). diff --git a/tools/perf/tests/attr/test-record-group1 b/tools/perf/tests/attr/test-record-group1 index 39bf8609538..013572f2360 100644 --- a/tools/perf/tests/attr/test-record-group1 +++ b/tools/perf/tests/attr/test-record-group1 @@ -15,6 +15,4 @@ config=1 sample_type=327 mmap=0 comm=0 -# TODO this is disabled for --group option, enabled otherwise -# check why.. -enable_on_exec=1 +enable_on_exec=0 diff --git a/tools/perf/tests/attr/test-stat-group1 b/tools/perf/tests/attr/test-stat-group1 index 5ae2718de86..2a1f86e4a90 100644 --- a/tools/perf/tests/attr/test-stat-group1 +++ b/tools/perf/tests/attr/test-stat-group1 @@ -11,7 +11,5 @@ group_fd=-1 fd=2 group_fd=1 config=1 -# TODO both disabled and enable_on_exec are disabled for --group option, -# enabled otherwise, check why.. -disabled=1 -enable_on_exec=1 +disabled=0 +enable_on_exec=0 diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c index b05b6a6f01a..1c52fdc1164 100644 --- a/tools/perf/tests/open-syscall-tp-fields.c +++ b/tools/perf/tests/open-syscall-tp-fields.c @@ -41,7 +41,7 @@ int test__syscall_open_tp_fields(void) goto out_delete_evlist; } - perf_evsel__config(evsel, &opts, evsel); + perf_evsel__config(evsel, &opts); evlist->threads->map[0] = getpid(); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index a41dc4a5c2d..04acae0ce69 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -52,15 +52,13 @@ struct perf_evlist *perf_evlist__new(struct cpu_map *cpus, void perf_evlist__config_attrs(struct perf_evlist *evlist, struct perf_record_opts *opts) { - struct perf_evsel *evsel, *first; + struct perf_evsel *evsel; if (evlist->cpus->map[0] < 0) opts->no_inherit = true; - first = perf_evlist__first(evlist); - list_for_each_entry(evsel, &evlist->entries, node) { - perf_evsel__config(evsel, opts, first); + perf_evsel__config(evsel, opts); if (evlist->nr_entries > 1) evsel->attr.sample_type |= PERF_SAMPLE_ID; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 618d41140ab..6d4a5f6ed75 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -404,8 +404,8 @@ const char *perf_evsel__name(struct perf_evsel *evsel) return evsel->name ?: "unknown"; } -void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, - struct perf_evsel *first) +void perf_evsel__config(struct perf_evsel *evsel, + struct perf_record_opts *opts) { struct perf_event_attr *attr = &evsel->attr; int track = !evsel->idx; /* only the first counter needs these */ @@ -486,10 +486,8 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, attr->mmap = track; attr->comm = track; - if (perf_target__none(&opts->target) && - (!opts->group || evsel == first)) { + if (perf_target__none(&opts->target) && (!evsel->leader)) attr->enable_on_exec = 1; - } } int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 6f94d6dea00..32d7ec78ded 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -92,8 +92,7 @@ void perf_evsel__exit(struct perf_evsel *evsel); void perf_evsel__delete(struct perf_evsel *evsel); void perf_evsel__config(struct perf_evsel *evsel, - struct perf_record_opts *opts, - struct perf_evsel *first); + struct perf_record_opts *opts); bool perf_evsel__is_cache_op_valid(u8 type, u8 op); -- cgit v1.2.3 From 774cb499ca9ab0e5950a149d1fe102b125da1cee Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 12 Nov 2012 18:34:01 +0100 Subject: perf tools: Fix 'disabled' attribute config for record command Currently the record command sets all events initially as disabled. There's non conditional perf_evlist__enable call, that enables all events before we exec tracee program. That actually screws whole enable_on_exec logic, because the event is enabled before the traced program got executed. What we actually want is: 1) For any type of traced program: - all independent events and group leaders are disabled - all group members are enabled Group members are ruled by group leaders. They need to be enabled, because the group scheduling relies on that. 2) For traced programs executed by perf: - all independent events and group leaders have enable_on_exec set - we don't specifically enable or disable any event during the record command Independent events and group leaders are initially disabled and get enabled by exec. Group members are ruled by group leaders as stated in 1). 3) For traced programs attached by perf (pid/tid): - we specifically enable or disable all events during the record command When attaching events to already running traced we enable/disable events specifically, as there's no initial traced exec call. Fixing appropriate perf_event_attr test case to cover this change. Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352741644-16809-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 15 ++++++++++-- tools/perf/tests/attr/test-record-group | 1 + tools/perf/tests/attr/test-record-group1 | 1 + tools/perf/util/evsel.c | 42 +++++++++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 371702785d6..268b356391f 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -701,7 +701,13 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) } } - perf_evlist__enable(evsel_list); + /* + * When perf is starting the traced process, all the events + * (apart from group members) have enable_on_exec=1 set, + * so don't spoil it by prematurely enabling them. + */ + if (!perf_target__none(&opts->target)) + perf_evlist__enable(evsel_list); /* * Let the child rip @@ -724,7 +730,12 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) waking++; } - if (done) + /* + * When perf is starting the traced process, at the end events + * die with the process and we wait for that. Thus no need to + * disable events in this case. + */ + if (done && !perf_target__none(&opts->target)) perf_evlist__disable(evsel_list); } diff --git a/tools/perf/tests/attr/test-record-group b/tools/perf/tests/attr/test-record-group index b945f770dc9..a6599e9a19d 100644 --- a/tools/perf/tests/attr/test-record-group +++ b/tools/perf/tests/attr/test-record-group @@ -15,3 +15,4 @@ sample_type=327 mmap=0 comm=0 enable_on_exec=0 +disabled=0 diff --git a/tools/perf/tests/attr/test-record-group1 b/tools/perf/tests/attr/test-record-group1 index 013572f2360..5a8359da38a 100644 --- a/tools/perf/tests/attr/test-record-group1 +++ b/tools/perf/tests/attr/test-record-group1 @@ -16,3 +16,4 @@ sample_type=327 mmap=0 comm=0 enable_on_exec=0 +disabled=0 diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 6d4a5f6ed75..fc4faaa7afb 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -404,13 +404,40 @@ const char *perf_evsel__name(struct perf_evsel *evsel) return evsel->name ?: "unknown"; } +/* + * The enable_on_exec/disabled value strategy: + * + * 1) For any type of traced program: + * - all independent events and group leaders are disabled + * - all group members are enabled + * + * Group members are ruled by group leaders. They need to + * be enabled, because the group scheduling relies on that. + * + * 2) For traced programs executed by perf: + * - all independent events and group leaders have + * enable_on_exec set + * - we don't specifically enable or disable any event during + * the record command + * + * Independent events and group leaders are initially disabled + * and get enabled by exec. Group members are ruled by group + * leaders as stated in 1). + * + * 3) For traced programs attached by perf (pid/tid): + * - we specifically enable or disable all events during + * the record command + * + * When attaching events to already running traced we + * enable/disable events specifically, as there's no + * initial traced exec call. + */ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts) { struct perf_event_attr *attr = &evsel->attr; int track = !evsel->idx; /* only the first counter needs these */ - attr->disabled = 1; attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1; attr->inherit = !opts->no_inherit; attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | @@ -486,6 +513,19 @@ void perf_evsel__config(struct perf_evsel *evsel, attr->mmap = track; attr->comm = track; + /* + * XXX see the function comment above + * + * Disabling only independent events or group leaders, + * keeping group members enabled. + */ + if (!evsel->leader) + attr->disabled = 1; + + /* + * Setting enable_on_exec for independent events and + * group leaders for traced executed by perf. + */ if (perf_target__none(&opts->target) && (!evsel->leader)) attr->enable_on_exec = 1; } -- cgit v1.2.3 From 2711926a416733b853977a0e014c713955ad0d8a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 12 Nov 2012 18:34:02 +0100 Subject: perf tools: Ensure single disable call per event in record comand It's possible we issue the event disable ioctl multiple times until we read the final portion of the mmap buffer. Ensuring just single disable ioctl call for event, because there's no need to do that more than once. Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352741644-16809-4-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 268b356391f..f3151d3c70c 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -502,6 +502,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) struct perf_evlist *evsel_list = rec->evlist; const char *output_name = rec->output_name; struct perf_session *session; + bool disabled = false; rec->progname = argv[0]; @@ -735,8 +736,10 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) * die with the process and we wait for that. Thus no need to * disable events in this case. */ - if (done && !perf_target__none(&opts->target)) + if (done && !disabled && !perf_target__none(&opts->target)) { perf_evlist__disable(evsel_list); + disabled = true; + } } if (quiet || signr == SIGUSR1) -- cgit v1.2.3 From 3fe4430dd66837d8fcdb63c167e908655fc842e3 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 12 Nov 2012 18:34:03 +0100 Subject: perf tools: Omit group members from perf_evlist__disable/enable There's no need to disable/enable ordinary group member events, because they are initialy enabled and get scheduled by the leader. Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352741644-16809-5-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 04acae0ce69..e9d2d5da2fb 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -222,6 +222,8 @@ void perf_evlist__disable(struct perf_evlist *evlist) for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { list_for_each_entry(pos, &evlist->entries, node) { + if (pos->leader) + continue; for (thread = 0; thread < evlist->threads->nr; thread++) ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_DISABLE, 0); @@ -236,6 +238,8 @@ void perf_evlist__enable(struct perf_evlist *evlist) for (cpu = 0; cpu < cpu_map__nr(evlist->cpus); cpu++) { list_for_each_entry(pos, &evlist->entries, node) { + if (pos->leader) + continue; for (thread = 0; thread < evlist->threads->nr; thread++) ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_ENABLE, 0); -- cgit v1.2.3 From 534123f458f196bcc269f97d20ccf125925c2e7b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 13 Nov 2012 15:32:58 +0100 Subject: perf tools: Add basic event modifier sanity check Updating event parser to allow any non zero string containing [ukhpGH] characters for event modifier. The modifier sanity is checked later in parse-event object logic. The check validates modifier to contain only one instance of any modifier (apart from 'p') present. v2: - added length check suggested Namhyung Kim Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20121113143258.GA2481@krava.brq.redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/parse-events.c | 24 ++++++++++++++++++++++++ tools/perf/util/parse-events.l | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index c0b785b5084..020323af336 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -722,6 +722,27 @@ static int get_event_modifier(struct event_modifier *mod, char *str, return 0; } +/* + * Basic modifier sanity check to validate it contains only one + * instance of any modifier (apart from 'p') present. + */ +static int check_modifier(char *str) +{ + char *p = str; + + /* The sizeof includes 0 byte as well. */ + if (strlen(str) > (sizeof("ukhGHppp") - 1)) + return -1; + + while (*p) { + if (*p != 'p' && strchr(p + 1, *p)) + return -1; + p++; + } + + return 0; +} + int parse_events__modifier_event(struct list_head *list, char *str, bool add) { struct perf_evsel *evsel; @@ -730,6 +751,9 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add) if (str == NULL) return 0; + if (check_modifier(str)) + return -EINVAL; + if (!add && get_event_modifier(&mod, str, NULL)) return -EINVAL; diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 66959fab663..e9d1134c2c6 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -82,7 +82,7 @@ num_hex 0x[a-fA-F0-9]+ num_raw_hex [a-fA-F0-9]+ name [a-zA-Z_*?][a-zA-Z0-9_*?]* name_minus [a-zA-Z_*?][a-zA-Z0-9\-_*?]* -modifier_event [ukhpGH]{1,8} +modifier_event [ukhpGH]+ modifier_bp [rwx]{1,3} %% -- cgit v1.2.3 From 7da5c85dd34dd67846fec965e4bf1f761eecca05 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 13 Nov 2012 22:30:31 +0900 Subject: perf ui tui: Move progress.c under ui/tui directory Current ui_progress functions are implemented for TUI only. So move the file under the tui directory. This is needed for providing an UI- agnostic wrapper. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Pekka Enberg Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352813436-14173-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 2 +- tools/perf/ui/progress.c | 32 -------------------------------- tools/perf/ui/tui/progress.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 33 deletions(-) delete mode 100644 tools/perf/ui/progress.c create mode 100644 tools/perf/ui/tui/progress.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 9af012f3771..50e85c85265 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -617,11 +617,11 @@ ifndef NO_NEWT LIB_OBJS += $(OUTPUT)ui/browsers/hists.o LIB_OBJS += $(OUTPUT)ui/browsers/map.o LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o - LIB_OBJS += $(OUTPUT)ui/progress.o LIB_OBJS += $(OUTPUT)ui/util.o LIB_OBJS += $(OUTPUT)ui/tui/setup.o LIB_OBJS += $(OUTPUT)ui/tui/util.o LIB_OBJS += $(OUTPUT)ui/tui/helpline.o + LIB_OBJS += $(OUTPUT)ui/tui/progress.o LIB_H += ui/browser.h LIB_H += ui/browsers/map.h LIB_H += ui/keysyms.h diff --git a/tools/perf/ui/progress.c b/tools/perf/ui/progress.c deleted file mode 100644 index 13aa64e50e1..00000000000 --- a/tools/perf/ui/progress.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "../cache.h" -#include "progress.h" -#include "libslang.h" -#include "ui.h" -#include "browser.h" - -void ui_progress__update(u64 curr, u64 total, const char *title) -{ - int bar, y; - /* - * FIXME: We should have a per UI backend way of showing progress, - * stdio will just show a percentage as NN%, etc. - */ - if (use_browser <= 0) - return; - - if (total == 0) - return; - - ui__refresh_dimensions(true); - pthread_mutex_lock(&ui__lock); - y = SLtt_Screen_Rows / 2 - 2; - SLsmg_set_color(0); - SLsmg_draw_box(y, 0, 3, SLtt_Screen_Cols); - SLsmg_gotorc(y++, 1); - SLsmg_write_string((char *)title); - SLsmg_set_color(HE_COLORSET_SELECTED); - bar = ((SLtt_Screen_Cols - 2) * curr) / total; - SLsmg_fill_region(y, 1, 1, bar, ' '); - SLsmg_refresh(); - pthread_mutex_unlock(&ui__lock); -} diff --git a/tools/perf/ui/tui/progress.c b/tools/perf/ui/tui/progress.c new file mode 100644 index 00000000000..f8dc986e427 --- /dev/null +++ b/tools/perf/ui/tui/progress.c @@ -0,0 +1,32 @@ +#include "../cache.h" +#include "../progress.h" +#include "../libslang.h" +#include "../ui.h" +#include "../browser.h" + +void ui_progress__update(u64 curr, u64 total, const char *title) +{ + int bar, y; + /* + * FIXME: We should have a per UI backend way of showing progress, + * stdio will just show a percentage as NN%, etc. + */ + if (use_browser <= 0) + return; + + if (total == 0) + return; + + ui__refresh_dimensions(true); + pthread_mutex_lock(&ui__lock); + y = SLtt_Screen_Rows / 2 - 2; + SLsmg_set_color(0); + SLsmg_draw_box(y, 0, 3, SLtt_Screen_Cols); + SLsmg_gotorc(y++, 1); + SLsmg_write_string((char *)title); + SLsmg_set_color(HE_COLORSET_SELECTED); + bar = ((SLtt_Screen_Cols - 2) * curr) / total; + SLsmg_fill_region(y, 1, 1, bar, ' '); + SLsmg_refresh(); + pthread_mutex_unlock(&ui__lock); +} -- cgit v1.2.3 From 688f2f5b99311b127ea43efdbf47bb2e3c7a2e32 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 13 Nov 2012 22:30:32 +0900 Subject: perf ui: Introduce generic ui_progress helper Make ui_progress functions generic so that UI frontend code will add its callbacks. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Pekka Enberg Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352813436-14173-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 + tools/perf/ui/gtk/util.c | 11 ----------- tools/perf/ui/progress.c | 20 ++++++++++++++++++++ tools/perf/ui/progress.h | 8 ++++++++ tools/perf/ui/tui/progress.c | 12 +++++++++++- tools/perf/ui/tui/setup.c | 1 + 6 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 tools/perf/ui/progress.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 50e85c85265..f8466b49b92 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -423,6 +423,7 @@ LIB_OBJS += $(OUTPUT)util/vdso.o LIB_OBJS += $(OUTPUT)util/stat.o LIB_OBJS += $(OUTPUT)ui/helpline.o +LIB_OBJS += $(OUTPUT)ui/progress.o LIB_OBJS += $(OUTPUT)ui/hist.o LIB_OBJS += $(OUTPUT)ui/stdio/hist.o diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c index ccb046aac98..c06942a41c7 100644 --- a/tools/perf/ui/gtk/util.c +++ b/tools/perf/ui/gtk/util.c @@ -111,14 +111,3 @@ struct perf_error_ops perf_gtk_eops = { .warning = perf_gtk__warning_statusbar, #endif }; - -/* - * FIXME: Functions below should be implemented properly. - * For now, just add stubs for NO_NEWT=1 build. - */ -#ifndef NEWT_SUPPORT -void ui_progress__update(u64 curr __maybe_unused, u64 total __maybe_unused, - const char *title __maybe_unused) -{ -} -#endif diff --git a/tools/perf/ui/progress.c b/tools/perf/ui/progress.c new file mode 100644 index 00000000000..f5e4d1b95c7 --- /dev/null +++ b/tools/perf/ui/progress.c @@ -0,0 +1,20 @@ +#include "../cache.h" +#include "progress.h" + +static void nop_progress_update(u64 curr __maybe_unused, + u64 total __maybe_unused, + const char *title __maybe_unused) +{ +} + +static struct ui_progress default_progress_fns = +{ + .update = nop_progress_update, +}; + +struct ui_progress *progress_fns = &default_progress_fns; + +void ui_progress__update(u64 curr, u64 total, const char *title) +{ + return progress_fns->update(curr, total, title); +} diff --git a/tools/perf/ui/progress.h b/tools/perf/ui/progress.h index d9c205b59aa..717814b3216 100644 --- a/tools/perf/ui/progress.h +++ b/tools/perf/ui/progress.h @@ -3,6 +3,14 @@ #include <../types.h> +struct ui_progress { + void (*update)(u64, u64, const char *); +}; + +extern struct ui_progress *progress_fns; + +void ui_progress__init(void); + void ui_progress__update(u64 curr, u64 total, const char *title); #endif diff --git a/tools/perf/ui/tui/progress.c b/tools/perf/ui/tui/progress.c index f8dc986e427..6c2184d53cb 100644 --- a/tools/perf/ui/tui/progress.c +++ b/tools/perf/ui/tui/progress.c @@ -4,7 +4,7 @@ #include "../ui.h" #include "../browser.h" -void ui_progress__update(u64 curr, u64 total, const char *title) +static void tui_progress__update(u64 curr, u64 total, const char *title) { int bar, y; /* @@ -30,3 +30,13 @@ void ui_progress__update(u64 curr, u64 total, const char *title) SLsmg_refresh(); pthread_mutex_unlock(&ui__lock); } + +static struct ui_progress tui_progress_fns = +{ + .update = tui_progress__update, +}; + +void ui_progress__init(void) +{ + progress_fns = &tui_progress_fns; +} diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index 60debb81537..81efa192e86 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c @@ -118,6 +118,7 @@ int ui__init(void) newtSetSuspendCallback(newt_suspend, NULL); ui_helpline__init(); ui_browser__init(); + ui_progress__init(); signal(SIGSEGV, ui__signal); signal(SIGFPE, ui__signal); -- cgit v1.2.3 From a753579c3ec096bba9d24e1594a07dbb25aca8e4 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 13 Nov 2012 22:30:33 +0900 Subject: perf ui gtk: Implement ui_progress functions Implement progress update function for GTK2 front end. Note that since it will be called before gtk main loop so that we should call gtk event loop handler directly. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Pekka Enberg Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352813436-14173-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 1 + tools/perf/ui/gtk/gtk.h | 1 + tools/perf/ui/gtk/progress.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ tools/perf/ui/gtk/setup.c | 2 ++ 4 files changed, 54 insertions(+) create mode 100644 tools/perf/ui/gtk/progress.c diff --git a/tools/perf/Makefile b/tools/perf/Makefile index f8466b49b92..5a9075ea218 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -648,6 +648,7 @@ ifndef NO_GTK2 LIB_OBJS += $(OUTPUT)ui/gtk/setup.o LIB_OBJS += $(OUTPUT)ui/gtk/util.o LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o + LIB_OBJS += $(OUTPUT)ui/gtk/progress.o # Make sure that it'd be included only once. ifeq ($(findstring -DNEWT_SUPPORT,$(BASIC_CFLAGS)),) LIB_OBJS += $(OUTPUT)ui/setup.o diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h index 687af0bba18..856320e2cc0 100644 --- a/tools/perf/ui/gtk/gtk.h +++ b/tools/perf/ui/gtk/gtk.h @@ -30,6 +30,7 @@ struct perf_gtk_context *perf_gtk__activate_context(GtkWidget *window); int perf_gtk__deactivate_context(struct perf_gtk_context **ctx); void perf_gtk__init_helpline(void); +void perf_gtk__init_progress(void); void perf_gtk__init_hpp(void); #ifndef HAVE_GTK_INFO_BAR diff --git a/tools/perf/ui/gtk/progress.c b/tools/perf/ui/gtk/progress.c new file mode 100644 index 00000000000..903426fe27c --- /dev/null +++ b/tools/perf/ui/gtk/progress.c @@ -0,0 +1,50 @@ +#include + +#include "gtk.h" +#include "../progress.h" +#include "util.h" + +static GtkWidget *dialog; +static GtkWidget *progress; + +static void gtk_progress_update(u64 curr, u64 total, const char *title) +{ + double fraction = total ? 1.0 * curr / total : 0.0; + char buf[1024]; + + if (dialog == NULL) { + GtkWidget *vbox = gtk_vbox_new(TRUE, 5); + GtkWidget *label = gtk_label_new(title); + + dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); + progress = gtk_progress_bar_new(); + + gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, FALSE, 3); + gtk_box_pack_start(GTK_BOX(vbox), progress, TRUE, TRUE, 3); + + gtk_container_add(GTK_CONTAINER(dialog), vbox); + + gtk_window_set_title(GTK_WINDOW(dialog), "perf"); + gtk_window_resize(GTK_WINDOW(dialog), 300, 80); + gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); + + gtk_widget_show_all(dialog); + } + + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), fraction); + snprintf(buf, sizeof(buf), "%"PRIu64" / %"PRIu64, curr, total); + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), buf); + + /* we didn't call gtk_main yet, so do it manually */ + while (gtk_events_pending()) + gtk_main_iteration(); +} + +static struct ui_progress gtk_progress_fns = { + .update = gtk_progress_update, +}; + +void perf_gtk__init_progress(void) +{ + progress_fns = >k_progress_fns; +} diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c index 3c4c6ef7828..6c2dd2e423f 100644 --- a/tools/perf/ui/gtk/setup.c +++ b/tools/perf/ui/gtk/setup.c @@ -8,7 +8,9 @@ int perf_gtk__init(void) { perf_error__register(&perf_gtk_eops); perf_gtk__init_helpline(); + perf_gtk__init_progress(); perf_gtk__init_hpp(); + return gtk_init_check(NULL, NULL) ? 0 : -1; } -- cgit v1.2.3 From a5580f3ecb295a514f9522daf0ef7158f73ec2d6 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 13 Nov 2012 22:30:34 +0900 Subject: perf ui: Add ui_progress__finish() Sometimes we need to know when the progress bar should disappear. Checking curr >= total wasn't enough since there're cases not met that condition for the last call. So add a new ->finish callback to identify this explicitly. Currently only GTK frontend needs it. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Pekka Enberg Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352813436-14173-4-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/gtk/progress.c | 9 +++++++++ tools/perf/ui/progress.c | 6 ++++++ tools/perf/ui/progress.h | 2 ++ tools/perf/util/debug.h | 1 + tools/perf/util/session.c | 1 + 5 files changed, 19 insertions(+) diff --git a/tools/perf/ui/gtk/progress.c b/tools/perf/ui/gtk/progress.c index 903426fe27c..482bcf3df9b 100644 --- a/tools/perf/ui/gtk/progress.c +++ b/tools/perf/ui/gtk/progress.c @@ -40,8 +40,17 @@ static void gtk_progress_update(u64 curr, u64 total, const char *title) gtk_main_iteration(); } +static void gtk_progress_finish(void) +{ + /* this will also destroy all of its children */ + gtk_widget_destroy(dialog); + + dialog = NULL; +} + static struct ui_progress gtk_progress_fns = { .update = gtk_progress_update, + .finish = gtk_progress_finish, }; void perf_gtk__init_progress(void) diff --git a/tools/perf/ui/progress.c b/tools/perf/ui/progress.c index f5e4d1b95c7..3ec695607a4 100644 --- a/tools/perf/ui/progress.c +++ b/tools/perf/ui/progress.c @@ -18,3 +18,9 @@ void ui_progress__update(u64 curr, u64 total, const char *title) { return progress_fns->update(curr, total, title); } + +void ui_progress__finish(void) +{ + if (progress_fns->finish) + progress_fns->finish(); +} diff --git a/tools/perf/ui/progress.h b/tools/perf/ui/progress.h index 717814b3216..257cc224f9c 100644 --- a/tools/perf/ui/progress.h +++ b/tools/perf/ui/progress.h @@ -5,6 +5,7 @@ struct ui_progress { void (*update)(u64, u64, const char *); + void (*finish)(void); }; extern struct ui_progress *progress_fns; @@ -12,5 +13,6 @@ extern struct ui_progress *progress_fns; void ui_progress__init(void); void ui_progress__update(u64 curr, u64 total, const char *title); +void ui_progress__finish(void); #endif diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index dec98750b48..83e8d234af6 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -26,6 +26,7 @@ int ui__error(const char *format, ...) __attribute__((format(printf, 1, 2))); static inline void ui_progress__update(u64 curr __maybe_unused, u64 total __maybe_unused, const char *title __maybe_unused) {} +static inline void ui_progress__finish(void) {} #define ui__error(format, arg...) ui__warning(format, ##arg) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 15abe40dc70..ce6f5116238 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1458,6 +1458,7 @@ more: session->ordered_samples.next_flush = ULLONG_MAX; err = flush_sample_queue(session, tool); out_err: + ui_progress__finish(); perf_session__warn_about_errors(session, tool); perf_session_free_sample_buffers(session); return err; -- cgit v1.2.3 From 59ed16b315681a08cf8aa13ee949e9405801f442 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 13 Nov 2012 22:30:35 +0900 Subject: perf ui: Always compile browser setup code We now have proper fallback logic, so always build it regardless of TUI or GTK setting. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Pekka Enberg Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1352813436-14173-5-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 3 +-- tools/perf/ui/ui.h | 28 ++++++++++++++++++++++++++++ tools/perf/util/cache.h | 39 +-------------------------------------- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 5a9075ea218..a7c6aa8d4a8 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -422,6 +422,7 @@ LIB_OBJS += $(OUTPUT)util/intlist.o LIB_OBJS += $(OUTPUT)util/vdso.o LIB_OBJS += $(OUTPUT)util/stat.o +LIB_OBJS += $(OUTPUT)ui/setup.o LIB_OBJS += $(OUTPUT)ui/helpline.o LIB_OBJS += $(OUTPUT)ui/progress.o LIB_OBJS += $(OUTPUT)ui/hist.o @@ -612,7 +613,6 @@ ifndef NO_NEWT BASIC_CFLAGS += -I/usr/include/slang BASIC_CFLAGS += -DNEWT_SUPPORT EXTLIBS += -lnewt -lslang - LIB_OBJS += $(OUTPUT)ui/setup.o LIB_OBJS += $(OUTPUT)ui/browser.o LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o LIB_OBJS += $(OUTPUT)ui/browsers/hists.o @@ -651,7 +651,6 @@ ifndef NO_GTK2 LIB_OBJS += $(OUTPUT)ui/gtk/progress.o # Make sure that it'd be included only once. ifeq ($(findstring -DNEWT_SUPPORT,$(BASIC_CFLAGS)),) - LIB_OBJS += $(OUTPUT)ui/setup.o LIB_OBJS += $(OUTPUT)ui/util.o endif endif diff --git a/tools/perf/ui/ui.h b/tools/perf/ui/ui.h index 7b67045479f..d86359c9990 100644 --- a/tools/perf/ui/ui.h +++ b/tools/perf/ui/ui.h @@ -3,9 +3,37 @@ #include #include +#include extern pthread_mutex_t ui__lock; +extern int use_browser; + +void setup_browser(bool fallback_to_pager); +void exit_browser(bool wait_for_ok); + +#ifdef NEWT_SUPPORT +int ui__init(void); +void ui__exit(bool wait_for_ok); +#else +static inline int ui__init(void) +{ + return -1; +} +static inline void ui__exit(bool wait_for_ok __maybe_unused) {} +#endif + +#ifdef GTK2_SUPPORT +int perf_gtk__init(void); +void perf_gtk__exit(bool wait_for_ok); +#else +static inline int perf_gtk__init(void) +{ + return -1; +} +static inline void perf_gtk__exit(bool wait_for_ok __maybe_unused) {} +#endif + void ui__refresh_dimensions(bool force); #endif /* _PERF_UI_H_ */ diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 2bd51370ad2..26e36723987 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -5,6 +5,7 @@ #include "util.h" #include "strbuf.h" #include "../perf.h" +#include "../ui/ui.h" #define CMD_EXEC_PATH "--exec-path" #define CMD_PERF_DIR "--perf-dir=" @@ -31,44 +32,6 @@ extern const char *pager_program; extern int pager_in_use(void); extern int pager_use_color; -extern int use_browser; - -#if defined(NEWT_SUPPORT) || defined(GTK2_SUPPORT) -void setup_browser(bool fallback_to_pager); -void exit_browser(bool wait_for_ok); - -#ifdef NEWT_SUPPORT -int ui__init(void); -void ui__exit(bool wait_for_ok); -#else -static inline int ui__init(void) -{ - return -1; -} -static inline void ui__exit(bool wait_for_ok __maybe_unused) {} -#endif - -#ifdef GTK2_SUPPORT -int perf_gtk__init(void); -void perf_gtk__exit(bool wait_for_ok); -#else -static inline int perf_gtk__init(void) -{ - return -1; -} -static inline void perf_gtk__exit(bool wait_for_ok __maybe_unused) {} -#endif - -#else /* NEWT_SUPPORT || GTK2_SUPPORT */ - -static inline void setup_browser(bool fallback_to_pager) -{ - if (fallback_to_pager) - setup_pager(); -} -static inline void exit_browser(bool wait_for_ok __maybe_unused) {} -#endif /* NEWT_SUPPORT || GTK2_SUPPORT */ - char *alias_lookup(const char *alias); int split_cmdline(char *cmdline, const char ***argv); -- cgit v1.2.3 From 0bca6cff89c6e7d1e383993cccf0f59146874a34 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 5 Nov 2012 15:15:24 +0000 Subject: tools: Define a Makefile function to do subdir processing Define a Makefile function that can be called with $(call ...) to wrap the subdir make invocations in tools/Makefile. This will allow us in the next patch to insert bits in there to honour O= flags when called from the top-level Makefile. Signed-off-by: David Howells Cc: Borislav Petkov Cc: Ingo Molnar Cc: Linus Torvalds Cc: Namhyung Kim Cc: Paul Mackerras Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1378.1352379110@warthog.procyon.org.uk Signed-off-by: Arnaldo Carvalho de Melo --- tools/Makefile | 24 ++++++++++++------------ tools/scripts/Makefile.include | 8 ++++++++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/tools/Makefile b/tools/Makefile index 3ae43947a17..1f9a529fe54 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -31,44 +31,44 @@ help: @echo ' clean: a summary clean target to clean _all_ folders' cpupower: FORCE - $(QUIET_SUBDIR0)power/$@/ $(QUIET_SUBDIR1) + $(call descend,power/$@) firewire lguest perf usb virtio vm: FORCE - $(QUIET_SUBDIR0)$@/ $(QUIET_SUBDIR1) + $(call descend,$@) selftests: FORCE - $(QUIET_SUBDIR0)testing/$@/ $(QUIET_SUBDIR1) + $(call descend,testing/$@) turbostat x86_energy_perf_policy: FORCE - $(QUIET_SUBDIR0)power/x86/$@/ $(QUIET_SUBDIR1) + $(call descend,power/x86/$@) cpupower_install: - $(QUIET_SUBDIR0)power/$(@:_install=)/ $(QUIET_SUBDIR1) install + $(call descend,power/$(@:_install=),install) firewire_install lguest_install perf_install usb_install virtio_install vm_install: - $(QUIET_SUBDIR0)$(@:_install=)/ $(QUIET_SUBDIR1) install + $(call descend,$(@:_install=),install) selftests_install: - $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) install + $(call descend,testing/$(@:_clean=),install) turbostat_install x86_energy_perf_policy_install: - $(QUIET_SUBDIR0)power/x86/$(@:_install=)/ $(QUIET_SUBDIR1) install + $(call descend,power/x86/$(@:_install=),install) install: cpupower_install firewire_install lguest_install perf_install \ selftests_install turbostat_install usb_install virtio_install \ vm_install x86_energy_perf_policy_install cpupower_clean: - $(QUIET_SUBDIR0)power/cpupower/ $(QUIET_SUBDIR1) clean + $(call descend,power/cpupower,clean) firewire_clean lguest_clean perf_clean usb_clean virtio_clean vm_clean: - $(QUIET_SUBDIR0)$(@:_clean=)/ $(QUIET_SUBDIR1) clean + $(call descend,$(@:_clean=),clean) selftests_clean: - $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) clean + $(call descend,testing/$(@:_clean=),clean) turbostat_clean x86_energy_perf_policy_clean: - $(QUIET_SUBDIR0)power/x86/$(@:_clean=)/ $(QUIET_SUBDIR1) clean + $(call descend,power/x86/$(@:_clean=),clean) clean: cpupower_clean firewire_clean lguest_clean perf_clean selftests_clean \ turbostat_clean usb_clean virtio_clean vm_clean \ diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include index 96ce80a3743..4a9e3176f74 100644 --- a/tools/scripts/Makefile.include +++ b/tools/scripts/Makefile.include @@ -41,6 +41,14 @@ else NO_SUBDIR = : endif +# +# Define a callable command for descending to a new directory +# +# Call by doing: $(call descend,directory[,target]) +# +descend = \ + $(QUIET_SUBDIR0)$(1) $(QUIET_SUBDIR1) $(2) + QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir QUIET_SUBDIR1 = -- cgit v1.2.3 From 9db48cd5ccd0d127e991c15509a0241a18043e91 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 5 Nov 2012 21:02:08 +0000 Subject: tools: Honour the O= flag when tool build called from a higher Makefile Honour the O= flag that was passed to a higher level Makefile and then passed down as part of a tool build. To make this work, the top-level Makefile passes the original O= flag and subdir=tools to the tools/Makefile, and that in turn passes subdir=$(O)/$(subdir)/foodir when building tool foo in directory $(O)/$(subdir)/foodir (where the intervening slashes aren't added if an element is missing). For example, take perf. This is found in tools/perf/. Assume we're building into directory ~/zebra/, so we pass O=~/zebra to make. Dependening on where we run the build from, we see: make run in dir $(OUTPUT) dir ======================= ================== linux ~/zebra/tools/perf/ linux/tools ~/zebra/perf/ linux/tools/perf ~/zebra/ and if O= is not set, we get: make run in dir $(OUTPUT) dir ======================= ================== linux linux/tools/perf/ linux/tools linux/tools/perf/ linux/tools/perf linux/tools/perf/ The output directories are created by the descend function if they don't already exist. Signed-off-by: David Howells Cc: Borislav Petkov Cc: Ingo Molnar Cc: Linus Torvalds Cc: Namhyung Kim Cc: Paul Mackerras Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1378.1352379110@warthog.procyon.org.uk Signed-off-by: Arnaldo Carvalho de Melo --- Makefile | 6 ++++-- tools/scripts/Makefile.include | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 14c93b39b92..08a31d8b7e3 100644 --- a/Makefile +++ b/Makefile @@ -1321,10 +1321,12 @@ kernelversion: # Clear a bunch of variables before executing the submake tools/: FORCE - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/ + $(Q)mkdir -p $(objtree)/tools + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/ tools/%: FORCE - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/ $* + $(Q)mkdir -p $(objtree)/tools + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/ $* # Single targets # --------------------------------------------------------------------------- diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include index 4a9e3176f74..87467b17e05 100644 --- a/tools/scripts/Makefile.include +++ b/tools/scripts/Makefile.include @@ -1,8 +1,11 @@ -ifeq ("$(origin O)", "command line") +ifeq ($(origin O), command line) dummy := $(if $(shell test -d $(O) || echo $(O)),$(error O=$(O) does not exist),) ABSOLUTE_O := $(shell cd $(O) ; pwd) - OUTPUT := $(ABSOLUTE_O)/ + OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/) COMMAND_O := O=$(ABSOLUTE_O) +ifeq ($(objtree),) + objtree := $(O) +endif endif ifneq ($(OUTPUT),) @@ -47,9 +50,10 @@ endif # Call by doing: $(call descend,directory[,target]) # descend = \ - $(QUIET_SUBDIR0)$(1) $(QUIET_SUBDIR1) $(2) + +mkdir -p $(OUTPUT)$(1) && \ + $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) -QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir +QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir QUIET_SUBDIR1 = ifneq ($(findstring $(MAKEFLAGS),s),s) @@ -64,5 +68,10 @@ ifndef V $(MAKE) $(PRINT_DIR) -C $$subdir QUIET_FLEX = @echo ' ' FLEX $@; QUIET_BISON = @echo ' ' BISON $@; + + descend = \ + @echo ' ' DESCEND $(1); \ + mkdir -p $(OUTPUT)$(1) && \ + $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) endif endif -- cgit v1.2.3 From 1668fc6505bd0796e34ee7f65eee69e81daaabe9 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 13 Nov 2012 14:14:38 -0300 Subject: tools: Pass the target in descend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing: [acme@sandy linux]$ cd tools [acme@sandy tools]$ make clean DESCEND power/cpupower CC lib/cpufreq.o CC lib/sysfs.o LD libcpupower.so.0.0.0 CC utils/helpers/amd.o utils/helpers/amd.c:7:21: error: pci/pci.h: No such file or directory In file included from utils/helpers/amd.c:9: ./utils/helpers/helpers.h:137: warning: ‘struct pci_access’ declared inside parameter list ./utils/helpers/helpers.h:137: warning: its scope is only this definition or declaration, which is probably not what you want ./utils/helpers/helpers.h:139: warning: ‘struct pci_access’ declared inside parameter list utils/helpers/amd.c: In function ‘amd_pci_get_num_boost_states’: utils/helpers/amd.c:120: warning: passing argument 1 of ‘pci_slot_func_init’ from incompatible pointer type ./utils/helpers/helpers.h:138: note: expected ‘struct pci_access **’ but argument is of type ‘struct pci_access **’ utils/helpers/amd.c:125: warning: implicit declaration of function ‘pci_read_byte’ utils/helpers/amd.c:132: warning: implicit declaration of function ‘pci_cleanup’ make[1]: *** [utils/helpers/amd.o] Error 1 make: *** [cpupower_clean] Error 2 [acme@sandy tools]$ Reported-by: Arnaldo Carvalho de Melo Signed-off-by: David Howells Cc: Borislav Petkov Cc: Ingo Molnar Cc: Linus Torvalds Cc: Namhyung Kim Cc: Paul Mackerras Cc: Thomas Gleixner Link: http://lkml.kernel.org/n/tip-tviyimq6x6nm77sj5lt4t19f@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/scripts/Makefile.include | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include index 87467b17e05..2964b96aa55 100644 --- a/tools/scripts/Makefile.include +++ b/tools/scripts/Makefile.include @@ -51,7 +51,7 @@ endif # descend = \ +mkdir -p $(OUTPUT)$(1) && \ - $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) + $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2) QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir QUIET_SUBDIR1 = @@ -72,6 +72,6 @@ ifndef V descend = \ @echo ' ' DESCEND $(1); \ mkdir -p $(OUTPUT)$(1) && \ - $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) + $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2) endif endif -- cgit v1.2.3 From 1483c2ae90738e7453bfe446a3bbcdd0ba9abf36 Mon Sep 17 00:00:00 2001 From: Sukadev Bhattiprolu Date: Wed, 31 Oct 2012 11:21:28 -0700 Subject: perf powerpc: Use uapi/unistd.h to fix build error Use the 'unistd.h' from arch/powerpc/include/uapi to build the perf tool. Signed-off-by: Sukadev Bhattiprolu Acked-by: David Howells Cc: Anton Blanchard Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Robert Richter Cc: linuxppc-dev@ozlabs.org Link: http://lkml.kernel.org/r/20121107191818.GA16211@us.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/perf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 00472646b3b..f53ee0bbee8 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -26,7 +26,7 @@ void get_term_dimensions(struct winsize *ws); #endif #ifdef __powerpc__ -#include "../../arch/powerpc/include/asm/unistd.h" +#include "../../arch/powerpc/include/uapi/asm/unistd.h" #define rmb() asm volatile ("sync" ::: "memory") #define cpu_relax() asm volatile ("" ::: "memory"); #define CPUINFO_PROC "cpu" -- cgit v1.2.3 From 07ac002f2fcc74c5be47b656d9201d5de84dc53d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 13 Nov 2012 17:27:28 -0300 Subject: perf evsel: Introduce is_group_member method To clarify what is being tested, instead of assuming that evsel->leader == NULL means either an 'isolated' evsel or a 'group leader'. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-lvdbvimaxw9nc5een5vmem0c@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 3 ++- tools/perf/tests/parse-events.c | 20 ++++++++++---------- tools/perf/util/evlist.c | 4 ++-- tools/perf/util/evsel.c | 6 +++--- tools/perf/util/evsel.h | 6 ++++++ 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 557081e0c6d..c247faca712 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -152,7 +152,8 @@ retry: return 0; } - if (!perf_target__has_task(&target) && (!evsel->leader)) { + if (!perf_target__has_task(&target) && + !perf_evsel__is_group_member(evsel)) { attr->disabled = 1; attr->enable_on_exec = 1; } diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index f2a82d0158c..42a0c8cd3cd 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -521,7 +521,7 @@ static int test__group1(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel)); /* cycles:upp */ evsel = perf_evsel__next(evsel); @@ -557,7 +557,7 @@ static int test__group2(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel)); /* cache-references + :u modifier */ evsel = perf_evsel__next(evsel); @@ -583,7 +583,7 @@ static int test__group2(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel)); return 0; } @@ -606,7 +606,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel)); TEST_ASSERT_VAL("wrong group name", !strcmp(leader->group_name, "group1")); @@ -636,7 +636,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel)); TEST_ASSERT_VAL("wrong group name", !strcmp(leader->group_name, "group2")); @@ -663,7 +663,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel)); return 0; } @@ -687,7 +687,7 @@ static int test__group4(struct perf_evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 1); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel)); /* instructions:kp + p */ evsel = perf_evsel__next(evsel); @@ -724,7 +724,7 @@ static int test__group5(struct perf_evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel)); /* instructions + G */ evsel = perf_evsel__next(evsel); @@ -751,7 +751,7 @@ static int test__group5(struct perf_evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); TEST_ASSERT_VAL("wrong group name", !evsel->group_name); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel)); /* instructions:G */ evsel = perf_evsel__next(evsel); @@ -777,7 +777,7 @@ static int test__group5(struct perf_evlist *evlist __maybe_unused) TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip); - TEST_ASSERT_VAL("wrong leader", evsel->leader == NULL); + TEST_ASSERT_VAL("wrong leader", !perf_evsel__is_group_member(evsel)); return 0; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index e9d2d5da2fb..705293489e3 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -222,7 +222,7 @@ void perf_evlist__disable(struct perf_evlist *evlist) for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { list_for_each_entry(pos, &evlist->entries, node) { - if (pos->leader) + if (perf_evsel__is_group_member(pos)) continue; for (thread = 0; thread < evlist->threads->nr; thread++) ioctl(FD(pos, cpu, thread), @@ -238,7 +238,7 @@ void perf_evlist__enable(struct perf_evlist *evlist) for (cpu = 0; cpu < cpu_map__nr(evlist->cpus); cpu++) { list_for_each_entry(pos, &evlist->entries, node) { - if (pos->leader) + if (perf_evsel__is_group_member(pos)) continue; for (thread = 0; thread < evlist->threads->nr; thread++) ioctl(FD(pos, cpu, thread), diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index fc4faaa7afb..1fb636c550a 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -519,14 +519,14 @@ void perf_evsel__config(struct perf_evsel *evsel, * Disabling only independent events or group leaders, * keeping group members enabled. */ - if (!evsel->leader) + if (!perf_evsel__is_group_member(evsel)) attr->disabled = 1; /* * Setting enable_on_exec for independent events and * group leaders for traced executed by perf. */ - if (perf_target__none(&opts->target) && (!evsel->leader)) + if (perf_target__none(&opts->target) && !perf_evsel__is_group_member(evsel)) attr->enable_on_exec = 1; } @@ -707,7 +707,7 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread) struct perf_evsel *leader = evsel->leader; int fd; - if (!leader) + if (!perf_evsel__is_group_member(evsel)) return -1; /* diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 32d7ec78ded..a4c1dd4e149 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -3,6 +3,7 @@ #include #include +#include #include "../../../include/uapi/linux/perf_event.h" #include "types.h" #include "xyarray.h" @@ -224,4 +225,9 @@ static inline struct perf_evsel *perf_evsel__next(struct perf_evsel *evsel) { return list_entry(evsel->node.next, struct perf_evsel, node); } + +static inline bool perf_evsel__is_group_member(const struct perf_evsel *evsel) +{ + return evsel->leader != NULL; +} #endif /* __PERF_EVSEL_H */ -- cgit v1.2.3 From 70847780dca19f3707d9fa433f68edf8cbaf91f2 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 8 Nov 2012 16:27:33 +0800 Subject: usb: host: tegra: remove pointless NULL check in tegra_ehci_remove() Test for tegra and hcd in tegra_ehci_remove() look like potential NULL pointer dereference, but in fact those tests are not needed, so remove these pointless tests entirely. Signed-off-by: Wei Yongjun Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-tegra.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 94ee3212094..ef0a6ef7875 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -775,9 +775,6 @@ static int tegra_ehci_remove(struct platform_device *pdev) struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - if (tegra == NULL || hcd == NULL) - return -EINVAL; - pm_runtime_get_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); -- cgit v1.2.3 From bc13364b3413a3815740c4a2f087e06f1b7ed850 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 8 Nov 2012 09:56:13 -0200 Subject: usb: ehci-mxc: Remove unused 'echi' variable Since commit c73cee7 (USB: EHCI: remove ehci_port_power() routine), the 'ehci' variable is no longer used, so remove it and fix the following build warning: drivers/usb/host/ehci-mxc.c:41:19: warning: unused variable 'ehci' [-Wunused-variable] Signed-off-by: Fabio Estevam Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-mxc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index a37224a4a49..8804f74689d 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -39,8 +39,6 @@ struct ehci_mxc_priv { /* called during probe() after chip reset completes */ static int ehci_mxc_setup(struct usb_hcd *hcd) { - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - hcd->has_tt = 1; return ehci_setup(hcd); -- cgit v1.2.3 From d8fd7d5ae3e0561920b38647793b1947e07c7acf Mon Sep 17 00:00:00 2001 From: Amardeep Rai Date: Thu, 8 Nov 2012 20:37:58 +0530 Subject: usb: spear-ehci/ohci: Do clk_get using dev-id We used to get clk using con-id, but now we have device struct available for these devices as they are probed using DT. And so must get clk using dev-id. Signed-off-by: Amardeep Rai Signed-off-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-spear.c | 13 +------------ drivers/usb/host/ohci-spear.c | 13 +------------ 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c index 719ca48a471..d08506af41c 100644 --- a/drivers/usb/host/ehci-spear.c +++ b/drivers/usb/host/ehci-spear.c @@ -109,8 +109,6 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) struct clk *usbh_clk; const struct hc_driver *driver = &ehci_spear_hc_driver; int irq, retval; - char clk_name[20] = "usbh_clk"; - static int instance = -1; if (usb_disabled()) return -ENODEV; @@ -129,16 +127,7 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &spear_ehci_dma_mask; - /* - * Increment the device instance, when probing via device-tree - */ - if (pdev->id < 0) - instance++; - else - instance = pdev->id; - sprintf(clk_name, "usbh.%01d_clk", instance); - - usbh_clk = clk_get(NULL, clk_name); + usbh_clk = clk_get(&pdev->dev, NULL); if (IS_ERR(usbh_clk)) { dev_err(&pdev->dev, "Error getting interface clock\n"); retval = PTR_ERR(usbh_clk); diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index d607be33c03..97477083365 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -101,8 +101,6 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) struct spear_ohci *ohci_p; struct resource *res; int retval, irq; - char clk_name[20] = "usbh_clk"; - static int instance = -1; irq = platform_get_irq(pdev, 0); if (irq < 0) { @@ -118,16 +116,7 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &spear_ohci_dma_mask; - /* - * Increment the device instance, when probing via device-tree - */ - if (pdev->id < 0) - instance++; - else - instance = pdev->id; - sprintf(clk_name, "usbh.%01d_clk", instance); - - usbh_clk = clk_get(NULL, clk_name); + usbh_clk = clk_get(&pdev->dev, NULL); if (IS_ERR(usbh_clk)) { dev_err(&pdev->dev, "Error getting interface clock\n"); retval = PTR_ERR(usbh_clk); -- cgit v1.2.3 From 98515e5923b1c8f982511eeec9d27014b05efebf Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 8 Nov 2012 20:37:59 +0530 Subject: usb: spear-ehci/ohci: Use devm_*() routines This patch frees SPEAr ehci/ohci drivers from tension of freeing resources :) devm_* derivatives of multiple routines are used while allocating resources, which would be freed automatically by kernel. Signed-off-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-spear.c | 37 +++++++++++++------------------------ drivers/usb/host/ohci-spear.c | 33 ++++++++++++--------------------- 2 files changed, 25 insertions(+), 45 deletions(-) diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c index d08506af41c..3fadff8f8d3 100644 --- a/drivers/usb/host/ehci-spear.c +++ b/drivers/usb/host/ehci-spear.c @@ -116,7 +116,7 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { retval = irq; - goto fail_irq_get; + goto fail; } /* @@ -127,38 +127,38 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &spear_ehci_dma_mask; - usbh_clk = clk_get(&pdev->dev, NULL); + usbh_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(usbh_clk)) { dev_err(&pdev->dev, "Error getting interface clock\n"); retval = PTR_ERR(usbh_clk); - goto fail_get_usbh_clk; + goto fail; } hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { retval = -ENOMEM; - goto fail_create_hcd; + goto fail; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { retval = -ENODEV; - goto fail_request_resource; + goto err_put_hcd; } hcd->rsrc_start = res->start; hcd->rsrc_len = resource_size(res); - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, + if (!devm_request_mem_region(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len, driver->description)) { retval = -EBUSY; - goto fail_request_resource; + goto err_put_hcd; } - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len); if (hcd->regs == NULL) { dev_dbg(&pdev->dev, "error mapping memory\n"); retval = -ENOMEM; - goto fail_ioremap; + goto err_put_hcd; } ehci = (struct spear_ehci *)hcd_to_ehci(hcd); @@ -167,21 +167,15 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev) spear_start_ehci(ehci); retval = usb_add_hcd(hcd, irq, IRQF_SHARED); if (retval) - goto fail_add_hcd; + goto err_stop_ehci; return retval; -fail_add_hcd: +err_stop_ehci: spear_stop_ehci(ehci); - iounmap(hcd->regs); -fail_ioremap: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -fail_request_resource: +err_put_hcd: usb_put_hcd(hcd); -fail_create_hcd: - clk_put(usbh_clk); -fail_get_usbh_clk: -fail_irq_get: +fail: dev_err(&pdev->dev, "init fail, %d\n", retval); return retval ; @@ -200,13 +194,8 @@ static int spear_ehci_hcd_drv_remove(struct platform_device *pdev) if (ehci_p->clk) spear_stop_ehci(ehci_p); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); - if (ehci_p->clk) - clk_put(ehci_p->clk); - return 0; } diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index 97477083365..c69725d9f0c 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -105,7 +105,7 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { retval = irq; - goto fail_irq_get; + goto fail; } /* @@ -116,38 +116,39 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) if (!pdev->dev.dma_mask) pdev->dev.dma_mask = &spear_ohci_dma_mask; - usbh_clk = clk_get(&pdev->dev, NULL); + usbh_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(usbh_clk)) { dev_err(&pdev->dev, "Error getting interface clock\n"); retval = PTR_ERR(usbh_clk); - goto fail_get_usbh_clk; + goto fail; } hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { retval = -ENOMEM; - goto fail_create_hcd; + goto fail; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { retval = -ENODEV; - goto fail_request_resource; + goto err_put_hcd; } hcd->rsrc_start = pdev->resource[0].start; hcd->rsrc_len = resource_size(res); - if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { + if (!devm_request_mem_region(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len, + hcd_name)) { dev_dbg(&pdev->dev, "request_mem_region failed\n"); retval = -EBUSY; - goto fail_request_resource; + goto err_put_hcd; } - hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len); if (!hcd->regs) { dev_dbg(&pdev->dev, "ioremap failed\n"); retval = -ENOMEM; - goto fail_ioremap; + goto err_put_hcd; } ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd); @@ -160,15 +161,9 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev) return retval; spear_stop_ohci(ohci_p); - iounmap(hcd->regs); -fail_ioremap: - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -fail_request_resource: +err_put_hcd: usb_put_hcd(hcd); -fail_create_hcd: - clk_put(usbh_clk); -fail_get_usbh_clk: -fail_irq_get: +fail: dev_err(&pdev->dev, "init fail, %d\n", retval); return retval; @@ -183,12 +178,8 @@ static int spear_ohci_hcd_drv_remove(struct platform_device *pdev) if (ohci_p->clk) spear_stop_ohci(ohci_p); - iounmap(hcd->regs); - release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); - if (ohci_p->clk) - clk_put(ohci_p->clk); platform_set_drvdata(pdev, NULL); return 0; } -- cgit v1.2.3 From 4b85c62411f7a95db33025b3aba29f7525c214d5 Mon Sep 17 00:00:00 2001 From: Boyan Nedeltchev Date: Mon, 12 Nov 2012 13:06:06 +0200 Subject: usb: misc: usbtest: send ISO packets for g_zero since commit b4036cc (usb: gadget: add isochronous support to gadget zero), g_zero has learned about isochronous transfers, which allows us to use usbtest.ko to exercise isochronous pipes. All we need to do to enable that functionality on usbtest.ko, is set the "iso" to 1 on struct usbtest_info Signed-off-by: Boyan Nedeltchev Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 055b84adeda..f10bd970d50 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -2386,6 +2386,7 @@ static struct usbtest_info gz_info = { .name = "Linux gadget zero", .autoconf = 1, .ctrl_out = 1, + .iso = 1, .alt = 0, }; -- cgit v1.2.3 From 9d94e16be70d34d139ec3c7882ed0283b5ac074d Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 13 Nov 2012 10:43:38 +0100 Subject: usb: otg: twl4030: Change TWL4030_MODULE_* ids to TWL_MODULE_* To facilitate upcoming cleanup in twl stack. No functional changes. Signed-off-by: Peter Ujfalusi Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/twl4030-usb.c | 46 ++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index f0d2e7530cf..11b2a1203d4 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -123,10 +123,10 @@ #define PHY_CLK_CTRL_STS 0xFF #define PHY_DPLL_CLK (1 << 0) -/* In module TWL4030_MODULE_PM_MASTER */ +/* In module TWL_MODULE_PM_MASTER */ #define STS_HW_CONDITIONS 0x0F -/* In module TWL4030_MODULE_PM_RECEIVER */ +/* In module TWL_MODULE_PM_RECEIVER */ #define VUSB_DEDICATED1 0x7D #define VUSB_DEDICATED2 0x7E #define VUSB1V5_DEV_GRP 0x71 @@ -195,14 +195,14 @@ static int twl4030_i2c_write_u8_verify(struct twl4030_usb *twl, } #define twl4030_usb_write_verify(twl, address, data) \ - twl4030_i2c_write_u8_verify(twl, TWL4030_MODULE_USB, (data), (address)) + twl4030_i2c_write_u8_verify(twl, TWL_MODULE_USB, (data), (address)) static inline int twl4030_usb_write(struct twl4030_usb *twl, u8 address, u8 data) { int ret = 0; - ret = twl_i2c_write_u8(TWL4030_MODULE_USB, data, address); + ret = twl_i2c_write_u8(TWL_MODULE_USB, data, address); if (ret < 0) dev_dbg(twl->dev, "TWL4030:USB:Write[0x%x] Error %d\n", address, ret); @@ -227,7 +227,7 @@ static inline int twl4030_readb(struct twl4030_usb *twl, u8 module, u8 address) static inline int twl4030_usb_read(struct twl4030_usb *twl, u8 address) { - return twl4030_readb(twl, TWL4030_MODULE_USB, address); + return twl4030_readb(twl, TWL_MODULE_USB, address); } /*-------------------------------------------------------------------------*/ @@ -264,8 +264,7 @@ static enum omap_musb_vbus_id_status * signal is active, the OTG module is activated, and * its interrupt may be raised (may wake the system). */ - status = twl4030_readb(twl, TWL4030_MODULE_PM_MASTER, - STS_HW_CONDITIONS); + status = twl4030_readb(twl, TWL_MODULE_PM_MASTER, STS_HW_CONDITIONS); if (status < 0) dev_err(twl->dev, "USB link status err %d\n", status); else if (status & (BIT(7) | BIT(2))) { @@ -372,8 +371,7 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on) * SLEEP. We work around this by clearing the bit after usv3v1 * is re-activated. This ensures that VUSB3V1 is really active. */ - twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, - VUSB_DEDICATED2); + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2); regulator_enable(twl->usb1v5); __twl4030_phy_power(twl, 1); twl4030_usb_write(twl, PHY_CLK_CTRL, @@ -419,50 +417,48 @@ static void twl4030_phy_resume(struct twl4030_usb *twl) static int twl4030_usb_ldo_init(struct twl4030_usb *twl) { /* Enable writing to power configuration registers */ - twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, - TWL4030_PM_MASTER_KEY_CFG1, - TWL4030_PM_MASTER_PROTECT_KEY); + twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG1, + TWL4030_PM_MASTER_PROTECT_KEY); - twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, - TWL4030_PM_MASTER_KEY_CFG2, - TWL4030_PM_MASTER_PROTECT_KEY); + twl_i2c_write_u8(TWL_MODULE_PM_MASTER, TWL4030_PM_MASTER_KEY_CFG2, + TWL4030_PM_MASTER_PROTECT_KEY); /* Keep VUSB3V1 LDO in sleep state until VBUS/ID change detected*/ - /*twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/ + /*twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB_DEDICATED2);*/ /* input to VUSB3V1 LDO is from VBAT, not VBUS */ - twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); /* Initialize 3.1V regulator */ - twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); twl->usb3v1 = regulator_get(twl->dev, "usb3v1"); if (IS_ERR(twl->usb3v1)) return -ENODEV; - twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); /* Initialize 1.5V regulator */ - twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); twl->usb1v5 = regulator_get(twl->dev, "usb1v5"); if (IS_ERR(twl->usb1v5)) goto fail1; - twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); /* Initialize 1.8V regulator */ - twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); twl->usb1v8 = regulator_get(twl->dev, "usb1v8"); if (IS_ERR(twl->usb1v8)) goto fail2; - twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); /* disable access to power configuration registers */ - twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, - TWL4030_PM_MASTER_PROTECT_KEY); + twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0, + TWL4030_PM_MASTER_PROTECT_KEY); return 0; -- cgit v1.2.3 From c019bc119a97aa20372c5a2cf210d209380d397d Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 14 Nov 2012 19:15:47 +1100 Subject: TTY: hvc_console, fix port reference count going to zero prematurely Commit bdb498c20040 "TTY: hvc_console, add tty install" took the port refcounting out of hvc_open()/hvc_close(), but failed to remove the kref_put() and tty_kref_put() calls in hvc_hangup() that were there to remove the extra references that hvc_open() had taken. The result was that doing a vhangup() when the current terminal was a hvc_console, then closing the current terminal, would end up calling destroy_hvc_struct() and making the port disappear entirely. This meant that Fedora 17 systems would boot up but then not display the login prompt on the console, and attempts to open /dev/hvc0 would give a "No such device" error. This fixes it by removing the extra kref_put() and tty_kref_put() calls. Signed-off-by: Paul Mackerras Acked-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_console.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index a5dec1ca1b8..13ee53bd0bf 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -424,7 +424,6 @@ static void hvc_hangup(struct tty_struct *tty) { struct hvc_struct *hp = tty->driver_data; unsigned long flags; - int temp_open_count; if (!hp) return; @@ -444,7 +443,6 @@ static void hvc_hangup(struct tty_struct *tty) return; } - temp_open_count = hp->port.count; hp->port.count = 0; spin_unlock_irqrestore(&hp->port.lock, flags); tty_port_tty_set(&hp->port, NULL); @@ -453,11 +451,6 @@ static void hvc_hangup(struct tty_struct *tty) if (hp->ops->notifier_hangup) hp->ops->notifier_hangup(hp, hp->data); - - while(temp_open_count) { - --temp_open_count; - tty_port_put(&hp->port); - } } /* -- cgit v1.2.3 From 1838b8c487378c6c576029d9e0e07b5a73036bac Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 4 Nov 2012 23:34:18 +0800 Subject: tty: serial: max310x: Add terminating entry for spi_device_id table The spi_device_id table is supposed to be zero-terminated. Signed-off-by: Axel Lin Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/max310x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c index 2bc28a59d38..1ab1d2c66de 100644 --- a/drivers/tty/serial/max310x.c +++ b/drivers/tty/serial/max310x.c @@ -1239,6 +1239,7 @@ static int __devexit max310x_remove(struct spi_device *spi) static const struct spi_device_id max310x_id_table[] = { { "max3107", MAX310X_TYPE_MAX3107 }, { "max3108", MAX310X_TYPE_MAX3108 }, + { } }; MODULE_DEVICE_TABLE(spi, max310x_id_table); -- cgit v1.2.3 From ddd32b4289a6feda9ad9e68b0d85641c389a72ba Mon Sep 17 00:00:00 2001 From: Joonsoo Kim Date: Tue, 13 Nov 2012 02:17:36 +0900 Subject: x86, mm: Correct vmflag test for checking VM_HUGETLB commit 611ae8e3f5204f7480b3b405993b3352cfa16662('enable tlb flush range support for x86') change flush_tlb_mm_range() considerably. After this, we test whether vmflag equal to VM_HUGETLB and it may be always failed, because vmflag usually has other flags simultaneously. Our intention is to check whether this vma is for hughtlb, so correct it according to this purpose. Signed-off-by: Joonsoo Kim Acked-by: Alex Shi Link: http://lkml.kernel.org/r/1352740656-19417-1-git-send-email-js1304@gmail.com Signed-off-by: H. Peter Anvin --- arch/x86/mm/tlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 0777f042e40..60f926cd8b0 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -197,7 +197,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, } if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1 - || vmflag == VM_HUGETLB) { + || vmflag & VM_HUGETLB) { local_flush_tlb(); goto flush_all; } -- cgit v1.2.3 From ce2fcbd99cef580623116bb33531dbc3e6f690b0 Mon Sep 17 00:00:00 2001 From: Chuansheng Liu Date: Thu, 8 Nov 2012 19:14:40 +0800 Subject: firmware loader: Fix the race FW_STATUS_DONE is followed by class_timeout There is a race as below when calling request_firmware(): CPU1 CPU2 write 0 > loading mutex_lock(&fw_lock) ... set_bit FW_STATUS_DONE class_timeout is coming set_bit FW_STATUS_ABORT complete_all &completion ... mutex_unlock(&fw_lock) In this time, the bit FW_STATUS_DONE and FW_STATUS_ABORT are set, and request_firmware() will return failure due to condition in _request_firmware_load(): if (!buf->size || test_bit(FW_STATUS_ABORT, &buf->status)) retval = -ENOENT; But from the above scenerio, it should be a successful requesting. So we need judge if the bit FW_STATUS_DONE is already set before calling fw_load_abort() in timeout function. As Ming's proposal, we need change the timer into sched_work to benefit from using &fw_lock mutex also. Signed-off-by: liu chuansheng Acked-by: Ming Lei Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 8945f4e489e..b44ed35ac38 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -143,7 +143,7 @@ struct fw_cache_entry { }; struct firmware_priv { - struct timer_list timeout; + struct delayed_work timeout_work; bool nowait; struct device dev; struct firmware_buf *buf; @@ -667,11 +667,18 @@ static struct bin_attribute firmware_attr_data = { .write = firmware_data_write, }; -static void firmware_class_timeout(u_long data) +static void firmware_class_timeout_work(struct work_struct *work) { - struct firmware_priv *fw_priv = (struct firmware_priv *) data; + struct firmware_priv *fw_priv = container_of(work, + struct firmware_priv, timeout_work.work); + mutex_lock(&fw_lock); + if (test_bit(FW_STATUS_DONE, &(fw_priv->buf->status))) { + mutex_unlock(&fw_lock); + return; + } fw_load_abort(fw_priv); + mutex_unlock(&fw_lock); } static struct firmware_priv * @@ -690,8 +697,8 @@ fw_create_instance(struct firmware *firmware, const char *fw_name, fw_priv->nowait = nowait; fw_priv->fw = firmware; - setup_timer(&fw_priv->timeout, - firmware_class_timeout, (u_long) fw_priv); + INIT_DELAYED_WORK(&fw_priv->timeout_work, + firmware_class_timeout_work); f_dev = &fw_priv->dev; @@ -858,7 +865,9 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, dev_dbg(f_dev->parent, "firmware: direct-loading" " firmware %s\n", buf->fw_id); + mutex_lock(&fw_lock); set_bit(FW_STATUS_DONE, &buf->status); + mutex_unlock(&fw_lock); complete_all(&buf->completion); direct_load = 1; goto handle_fw; @@ -894,15 +903,14 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, dev_set_uevent_suppress(f_dev, false); dev_dbg(f_dev, "firmware: requesting %s\n", buf->fw_id); if (timeout != MAX_SCHEDULE_TIMEOUT) - mod_timer(&fw_priv->timeout, - round_jiffies_up(jiffies + timeout)); + schedule_delayed_work(&fw_priv->timeout_work, timeout); kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); } wait_for_completion(&buf->completion); - del_timer_sync(&fw_priv->timeout); + cancel_delayed_work_sync(&fw_priv->timeout_work); handle_fw: mutex_lock(&fw_lock); -- cgit v1.2.3 From bd9eb7fbe69111ea0ff1f999ef4a5f26d223d1d5 Mon Sep 17 00:00:00 2001 From: Chuansheng Liu Date: Sat, 10 Nov 2012 01:27:22 +0800 Subject: firmware loader: Fix the concurrent request_firmware() race for kref_get/put There is one race that both request_firmware() with the same firmware name. The race scenerio is as below: CPU1 CPU2 request_firmware() --> _request_firmware_load() return err another request_firmware() is coming --> _request_firmware_cleanup is called --> _request_firmware_prepare --> release_firmware ---> fw_lookup_and_allocate_buf --> spin_lock(&fwc->lock) ... __fw_lookup_buf() return true fw_free_buf() will be called --> ... kref_put --> decrease the refcount to 0 kref_get(&tmp->ref) ==> it will trigger warning due to refcount == 0 __fw_free_buf() --> ... spin_unlock(&fwc->lock) spin_lock(&fwc->lock) list_del(&buf->list) spin_unlock(&fwc->lock) kfree(buf) After that, the freed buf will be used. The key race is decreasing refcount to 0 and list_del is not protected together by fwc->lock, and it is possible another thread try to get it between refcount==0 and list_del. Fix it here to protect it together. Acked-by: Ming Lei Signed-off-by: liu chuansheng Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index b44ed35ac38..be5f7aae75f 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -246,7 +246,6 @@ static void __fw_free_buf(struct kref *ref) __func__, buf->fw_id, buf, buf->data, (unsigned int)buf->size); - spin_lock(&fwc->lock); list_del(&buf->list); spin_unlock(&fwc->lock); @@ -263,7 +262,10 @@ static void __fw_free_buf(struct kref *ref) static void fw_free_buf(struct firmware_buf *buf) { - kref_put(&buf->ref, __fw_free_buf); + struct firmware_cache *fwc = buf->fwc; + spin_lock(&fwc->lock); + if (!kref_put(&buf->ref, __fw_free_buf)) + spin_unlock(&fwc->lock); } /* direct firmware loading support */ -- cgit v1.2.3 From 60dac5e284fe99751e3beefe1a9cc7a0771ad73c Mon Sep 17 00:00:00 2001 From: Cesar Eduardo Barros Date: Sat, 27 Oct 2012 20:37:10 -0200 Subject: firmware: use noinline_for_stack The comment above fw_file_size() suggests it is noinline for stack size reasons. Use noinline_for_stack to make this more clear. Signed-off-by: Cesar Eduardo Barros Acked-by: Ming Lei Signed-off-by: Greg Kroah-Hartman --- drivers/base/firmware_class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index be5f7aae75f..4b04ec4bd2f 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -277,7 +277,7 @@ static const char *fw_path[] = { }; /* Don't inline this: 'struct kstat' is biggish */ -static noinline long fw_file_size(struct file *file) +static noinline_for_stack long fw_file_size(struct file *file) { struct kstat st; if (vfs_getattr(file->f_path.mnt, file->f_path.dentry, &st)) -- cgit v1.2.3 From 27602842060484b564cd725241b402b0bddfb830 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Sat, 3 Nov 2012 17:47:58 +0800 Subject: firmware loader: introduce module parameter to customize(v4) fw search path This patch introduces one module parameter of 'path' in firmware_class to support customizing firmware image search path, so that people can use its own firmware path if the default built-in paths can't meet their demand[1], and the typical usage is passing the below from kernel command parameter when 'firmware_class' is built in kernel: firmware_class.path=$CUSTOMIZED_PATH [1], https://lkml.org/lkml/2012/10/11/337 Cc: Linus Torvalds Signed-off-by: Ming Lei Signed-off-by: Greg Kroah-Hartman --- Documentation/firmware_class/README | 5 +++++ drivers/base/firmware_class.c | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Documentation/firmware_class/README b/Documentation/firmware_class/README index 815b711bcd8..e9fce78c413 100644 --- a/Documentation/firmware_class/README +++ b/Documentation/firmware_class/README @@ -22,12 +22,17 @@ - calls request_firmware(&fw_entry, $FIRMWARE, device) - kernel searchs the fimware image with name $FIRMWARE directly in the below search path of root filesystem: + User customized search path by module parameter 'path'[1] "/lib/firmware/updates/" UTS_RELEASE, "/lib/firmware/updates", "/lib/firmware/" UTS_RELEASE, "/lib/firmware" - If found, goto 7), else goto 2) + [1], the 'path' is a string parameter which length should be less + than 256, user should pass 'firmware_class.path=$CUSTOMIZED_PATH' + if firmware_class is built in kernel(the general situation) + 2), userspace: - /sys/class/firmware/xxx/{loading,data} appear. - hotplug gets called with a firmware identifier in $FIRMWARE diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 4b04ec4bd2f..7888af7941a 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -269,13 +269,23 @@ static void fw_free_buf(struct firmware_buf *buf) } /* direct firmware loading support */ -static const char *fw_path[] = { +static char fw_path_para[256]; +static const char * const fw_path[] = { + fw_path_para, "/lib/firmware/updates/" UTS_RELEASE, "/lib/firmware/updates", "/lib/firmware/" UTS_RELEASE, "/lib/firmware" }; +/* + * Typical usage is that passing 'firmware_class.path=$CUSTOMIZED_PATH' + * from kernel command line because firmware_class is generally built in + * kernel instead of module. + */ +module_param_string(path, fw_path_para, sizeof(fw_path_para), 0644); +MODULE_PARM_DESC(path, "customized firmware image search path with a higher priority than default path"); + /* Don't inline this: 'struct kstat' is biggish */ static noinline_for_stack long fw_file_size(struct file *file) { @@ -317,6 +327,11 @@ static bool fw_get_filesystem_firmware(struct firmware_buf *buf) for (i = 0; i < ARRAY_SIZE(fw_path); i++) { struct file *file; + + /* skip the unset customized path */ + if (!fw_path[i][0]) + continue; + snprintf(path, PATH_MAX, "%s/%s", fw_path[i], buf->fw_id); file = filp_open(path, O_RDONLY, 0); -- cgit v1.2.3 From 6a927857d890658789e6e54b058ef8527de8200a Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Sat, 3 Nov 2012 17:48:16 +0800 Subject: firmware loader: document firmware cache mechanism This patch documents the firmware cache mechanism so that users of request_firmware() know that it can be called safely inside device's suspend and resume callback, and the device's firmware needn't be cached any more by individual driver itself to deal with firmware loss during system resume. Signed-off-by: Ming Lei Signed-off-by: Greg Kroah-Hartman --- Documentation/firmware_class/README | 7 +++++++ drivers/base/firmware_class.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/Documentation/firmware_class/README b/Documentation/firmware_class/README index e9fce78c413..43fada989e6 100644 --- a/Documentation/firmware_class/README +++ b/Documentation/firmware_class/README @@ -119,3 +119,10 @@ on the setup, so I think that the choice on what firmware to make persistent should be left to userspace. + about firmware cache: + -------------------- + After firmware cache mechanism is introduced during system sleep, + request_firmware can be called safely inside device's suspend and + resume callback, and callers need't cache the firmware by + themselves any more for dealing with firmware loss during system + resume. diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 7888af7941a..d8146030918 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -988,6 +988,9 @@ err_put_dev: * firmware image for this or any other device. * * Caller must hold the reference count of @device. + * + * The function can be called safely inside device's suspend and + * resume callback. **/ int request_firmware(const struct firmware **firmware_p, const char *name, -- cgit v1.2.3 From bdda27fb98463244f056852f800bbce7db67dc4a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 26 Oct 2012 13:40:04 +0200 Subject: ACPI / PM: Fix device PM kernedoc comments and #ifdefs The kerneldoc comments for acpi_pm_device_sleep_state(), acpi_pm_device_run_wake(), and acpi_pm_device_sleep_wake() are outdated or otherwise inaccurate and/or don't follow the common kerneldoc patterns, so fix them. Additionally, notice that acpi_pm_device_run_wake() should be under CONFIG_PM_RUNTIME rather than under CONFIG_PM_SLEEP, so fix that too. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sleep.c | 53 ++++++++++++++++++++++--------------------------- include/acpi/acpi_bus.h | 8 ++++++-- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 69134653909..4defa0297ee 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -684,28 +684,21 @@ int acpi_suspend(u32 acpi_state) #ifdef CONFIG_PM /** - * acpi_pm_device_sleep_state - return preferred power state of ACPI device - * in the system sleep state given by %acpi_target_sleep_state - * @dev: device to examine; its driver model wakeup flags control - * whether it should be able to wake up the system - * @d_min_p: used to store the upper limit of allowed states range - * @d_max_in: specify the lowest allowed states - * Return value: preferred power state of the device on success, -ENODEV - * (ie. if there's no 'struct acpi_device' for @dev) or -EINVAL on failure + * acpi_pm_device_sleep_state - Get preferred power state of ACPI device. + * @dev: Device whose preferred target power state to return. + * @d_min_p: Location to store the upper limit of the allowed states range. + * @d_max_in: Deepest low-power state to take into consideration. + * Return value: Preferred power state of the device on success, -ENODEV + * (if there's no 'struct acpi_device' for @dev) or -EINVAL on failure * - * Find the lowest power (highest number) ACPI device power state that - * device @dev can be in while the system is in the sleep state represented - * by %acpi_target_sleep_state. If @wake is nonzero, the device should be - * able to wake up the system from this sleep state. If @d_min_p is set, - * the highest power (lowest number) device power state of @dev allowed - * in this system sleep state is stored at the location pointed to by it. + * Find the lowest power (highest number) ACPI device power state that the + * device can be in while the system is in the sleep state represented + * by %acpi_target_sleep_state. If @d_min_p is set, the highest power (lowest + * number) device power state that @dev can be in for the given system sleep + * state is stored at the location pointed to by it. * - * The caller must ensure that @dev is valid before using this function. - * The caller is also responsible for figuring out if the device is - * supposed to be able to wake up the system and passing this information - * via @wake. + * The caller must ensure that @dev is valid before using this function. */ - int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) { acpi_handle handle = DEVICE_ACPI_HANDLE(dev); @@ -797,14 +790,15 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) EXPORT_SYMBOL(acpi_pm_device_sleep_state); #endif /* CONFIG_PM */ -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM_RUNTIME /** - * acpi_pm_device_run_wake - Enable/disable wake-up for given device. - * @phys_dev: Device to enable/disable the platform to wake-up the system for. - * @enable: Whether enable or disable the wake-up functionality. + * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. + * @phys_dev: Device to enable/disable the platform to wake up. + * @enable: Whether to enable or disable the wakeup functionality. * - * Find the ACPI device object corresponding to @pci_dev and try to - * enable/disable the GPE associated with it. + * Find the ACPI device object corresponding to @phys_dev and try to + * enable/disable the GPE associated with it, so that it can generate + * wakeup signals for the device in response to external (remote) events. */ int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) { @@ -832,12 +826,13 @@ int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) return 0; } EXPORT_SYMBOL(acpi_pm_device_run_wake); +#endif /* CONFIG_PM_RUNTIME */ +#ifdef CONFIG_PM_SLEEP /** - * acpi_pm_device_sleep_wake - enable or disable the system wake-up - * capability of given device - * @dev: device to handle - * @enable: 'true' - enable, 'false' - disable the wake-up capability + * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system. + * @dev: Device to enable/desible to wake up the system from sleep states. + * @enable: Whether to enable or disable @dev to wake up the system. */ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) { diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 0daa0fbd865..72053db9c2e 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -426,14 +426,18 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m) } #endif -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM_RUNTIME int acpi_pm_device_run_wake(struct device *, bool); -int acpi_pm_device_sleep_wake(struct device *, bool); #else static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) { return -ENODEV; } +#endif + +#ifdef CONFIG_PM_SLEEP +int acpi_pm_device_sleep_wake(struct device *, bool); +#else static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) { return -ENODEV; -- cgit v1.2.3 From ec2cd81ccfc055155ef4ca673f207168f516d287 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Nov 2012 01:40:09 +0100 Subject: ACPI / PM: Move routines for adding/removing device wakeup notifiers ACPI routines for adding and removing device wakeup notifiers are currently defined in a PCI-specific file, but they will be necessary for non-PCI devices too, so move them to a separate file under drivers/acpi and rename them to indicate their ACPI origins. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/Makefile | 3 +- drivers/acpi/device_pm.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/pci/pci-acpi.c | 71 +++---------------------------------- include/acpi/acpi_bus.h | 15 ++++++++ 4 files changed, 112 insertions(+), 68 deletions(-) create mode 100644 drivers/acpi/device_pm.c diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 82422fe90f8..a2711fae62d 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -21,9 +21,10 @@ obj-y += acpi.o \ acpi-y += osl.o utils.o reboot.o acpi-y += nvs.o -# sleep related files +# Power management related files acpi-y += wakeup.o acpi-y += sleep.o +acpi-$(CONFIG_PM) += device_pm.o acpi-$(CONFIG_ACPI_SLEEP) += proc.o diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c new file mode 100644 index 00000000000..2d2e0bc8891 --- /dev/null +++ b/drivers/acpi/device_pm.c @@ -0,0 +1,91 @@ +/* + * drivers/acpi/device_pm.c - ACPI device power management routines. + * + * Copyright (C) 2012, Intel Corp. + * Author: Rafael J. Wysocki + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include + +#include +#include + +static DEFINE_MUTEX(acpi_pm_notifier_lock); + +/** + * acpi_add_pm_notifier - Register PM notifier for given ACPI device. + * @adev: ACPI device to add the notifier for. + * @context: Context information to pass to the notifier routine. + * + * NOTE: @adev need not be a run-wake or wakeup device to be a valid source of + * PM wakeup events. For example, wakeup events may be generated for bridges + * if one of the devices below the bridge is signaling wakeup, even if the + * bridge itself doesn't have a wakeup GPE associated with it. + */ +acpi_status acpi_add_pm_notifier(struct acpi_device *adev, + acpi_notify_handler handler, void *context) +{ + acpi_status status = AE_ALREADY_EXISTS; + + mutex_lock(&acpi_pm_notifier_lock); + + if (adev->wakeup.flags.notifier_present) + goto out; + + status = acpi_install_notify_handler(adev->handle, + ACPI_SYSTEM_NOTIFY, + handler, context); + if (ACPI_FAILURE(status)) + goto out; + + adev->wakeup.flags.notifier_present = true; + + out: + mutex_unlock(&acpi_pm_notifier_lock); + return status; +} + +/** + * acpi_remove_pm_notifier - Unregister PM notifier from given ACPI device. + * @adev: ACPI device to remove the notifier from. + */ +acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, + acpi_notify_handler handler) +{ + acpi_status status = AE_BAD_PARAMETER; + + mutex_lock(&acpi_pm_notifier_lock); + + if (!adev->wakeup.flags.notifier_present) + goto out; + + status = acpi_remove_notify_handler(adev->handle, + ACPI_SYSTEM_NOTIFY, + handler); + if (ACPI_FAILURE(status)) + goto out; + + adev->wakeup.flags.notifier_present = false; + + out: + mutex_unlock(&acpi_pm_notifier_lock); + return status; +} diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 63d6618a480..1af4008182f 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -20,8 +20,6 @@ #include #include "pci.h" -static DEFINE_MUTEX(pci_acpi_pm_notify_mtx); - /** * pci_acpi_wake_bus - Wake-up notification handler for root buses. * @handle: ACPI handle of a device the notification is for. @@ -68,67 +66,6 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) pci_pme_wakeup_bus(pci_dev->subordinate); } -/** - * add_pm_notifier - Register PM notifier for given ACPI device. - * @dev: ACPI device to add the notifier for. - * @context: PCI device or bus to check for PME status if an event is signaled. - * - * NOTE: @dev need not be a run-wake or wake-up device to be a valid source of - * PM wake-up events. For example, wake-up events may be generated for bridges - * if one of the devices below the bridge is signaling PME, even if the bridge - * itself doesn't have a wake-up GPE associated with it. - */ -static acpi_status add_pm_notifier(struct acpi_device *dev, - acpi_notify_handler handler, - void *context) -{ - acpi_status status = AE_ALREADY_EXISTS; - - mutex_lock(&pci_acpi_pm_notify_mtx); - - if (dev->wakeup.flags.notifier_present) - goto out; - - status = acpi_install_notify_handler(dev->handle, - ACPI_SYSTEM_NOTIFY, - handler, context); - if (ACPI_FAILURE(status)) - goto out; - - dev->wakeup.flags.notifier_present = true; - - out: - mutex_unlock(&pci_acpi_pm_notify_mtx); - return status; -} - -/** - * remove_pm_notifier - Unregister PM notifier from given ACPI device. - * @dev: ACPI device to remove the notifier from. - */ -static acpi_status remove_pm_notifier(struct acpi_device *dev, - acpi_notify_handler handler) -{ - acpi_status status = AE_BAD_PARAMETER; - - mutex_lock(&pci_acpi_pm_notify_mtx); - - if (!dev->wakeup.flags.notifier_present) - goto out; - - status = acpi_remove_notify_handler(dev->handle, - ACPI_SYSTEM_NOTIFY, - handler); - if (ACPI_FAILURE(status)) - goto out; - - dev->wakeup.flags.notifier_present = false; - - out: - mutex_unlock(&pci_acpi_pm_notify_mtx); - return status; -} - /** * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus. * @dev: ACPI device to add the notifier for. @@ -137,7 +74,7 @@ static acpi_status remove_pm_notifier(struct acpi_device *dev, acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, struct pci_bus *pci_bus) { - return add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus); + return acpi_add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus); } /** @@ -146,7 +83,7 @@ acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev, */ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) { - return remove_pm_notifier(dev, pci_acpi_wake_bus); + return acpi_remove_pm_notifier(dev, pci_acpi_wake_bus); } /** @@ -157,7 +94,7 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, struct pci_dev *pci_dev) { - return add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev); + return acpi_add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev); } /** @@ -166,7 +103,7 @@ acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, */ acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) { - return remove_pm_notifier(dev, pci_acpi_wake_dev); + return acpi_remove_pm_notifier(dev, pci_acpi_wake_dev); } phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 72053db9c2e..6983272f9d0 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -416,8 +416,23 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state); int acpi_disable_wakeup_device_power(struct acpi_device *dev); #ifdef CONFIG_PM +acpi_status acpi_add_pm_notifier(struct acpi_device *adev, + acpi_notify_handler handler, void *context); +acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, + acpi_notify_handler handler); int acpi_pm_device_sleep_state(struct device *, int *, int); #else +static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev, + acpi_notify_handler handler, + void *context) +{ + return AE_SUPPORT; +} +static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, + acpi_notify_handler handler) +{ + return AE_SUPPORT; +} static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m) { if (p) -- cgit v1.2.3 From 86b3832c64b6d01092216d84dc6a6b300875d0bb Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Nov 2012 01:40:18 +0100 Subject: ACPI / PM: Move device power state selection routine to device_pm.c The ACPI function for choosing device power state is now located in drivers/acpi/sleep.c, but drivers/acpi/device_pm.c is a more logical place for it, so move it there. However, instead of moving the function entirely, move its core only under a different name and with a different list of arguments, so that it is more flexible, and leave a wrapper around it in the original location. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/sleep.c | 88 ++------------------------------------ include/acpi/acpi_bus.h | 15 ++++++- 3 files changed, 124 insertions(+), 86 deletions(-) diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 2d2e0bc8891..c017b801171 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -23,7 +23,9 @@ */ #include +#include #include +#include #include #include @@ -89,3 +91,108 @@ acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, mutex_unlock(&acpi_pm_notifier_lock); return status; } + +/** + * acpi_device_power_state - Get preferred power state of ACPI device. + * @dev: Device whose preferred target power state to return. + * @adev: ACPI device node corresponding to @dev. + * @target_state: System state to match the resultant device state. + * @d_max_in: Deepest low-power state to take into consideration. + * @d_min_p: Location to store the upper limit of the allowed states range. + * Return value: Preferred power state of the device on success, -ENODEV + * (if there's no 'struct acpi_device' for @dev) or -EINVAL on failure + * + * Find the lowest power (highest number) ACPI device power state that the + * device can be in while the system is in the state represented by + * @target_state. If @d_min_p is set, the highest power (lowest number) device + * power state that @dev can be in for the given system sleep state is stored + * at the location pointed to by it. + * + * Callers must ensure that @dev and @adev are valid pointers and that @adev + * actually corresponds to @dev before using this function. + */ +int acpi_device_power_state(struct device *dev, struct acpi_device *adev, + u32 target_state, int d_max_in, int *d_min_p) +{ + char acpi_method[] = "_SxD"; + unsigned long long d_min, d_max; + bool wakeup = false; + + if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3) + return -EINVAL; + + if (d_max_in > ACPI_STATE_D3_HOT) { + enum pm_qos_flags_status stat; + + stat = dev_pm_qos_flags(dev, PM_QOS_FLAG_NO_POWER_OFF); + if (stat == PM_QOS_FLAGS_ALL) + d_max_in = ACPI_STATE_D3_HOT; + } + + acpi_method[2] = '0' + target_state; + /* + * If the sleep state is S0, the lowest limit from ACPI is D3, + * but if the device has _S0W, we will use the value from _S0W + * as the lowest limit from ACPI. Finally, we will constrain + * the lowest limit with the specified one. + */ + d_min = ACPI_STATE_D0; + d_max = ACPI_STATE_D3; + + /* + * If present, _SxD methods return the minimum D-state (highest power + * state) we can use for the corresponding S-states. Otherwise, the + * minimum D-state is D0 (ACPI 3.x). + * + * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer + * provided -- that's our fault recovery, we ignore retval. + */ + if (target_state > ACPI_STATE_S0) { + acpi_evaluate_integer(adev->handle, acpi_method, NULL, &d_min); + wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid + && adev->wakeup.sleep_state >= target_state; + } else if (dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) != + PM_QOS_FLAGS_NONE) { + wakeup = adev->wakeup.flags.valid; + } + + /* + * If _PRW says we can wake up the system from the target sleep state, + * the D-state returned by _SxD is sufficient for that (we assume a + * wakeup-aware driver if wake is set). Still, if _SxW exists + * (ACPI 3.x), it should return the maximum (lowest power) D-state that + * can wake the system. _S0W may be valid, too. + */ + if (wakeup) { + acpi_status status; + + acpi_method[3] = 'W'; + status = acpi_evaluate_integer(adev->handle, acpi_method, NULL, + &d_max); + if (ACPI_FAILURE(status)) { + if (target_state != ACPI_STATE_S0 || + status != AE_NOT_FOUND) + d_max = d_min; + } else if (d_max < d_min) { + /* Warn the user of the broken DSDT */ + printk(KERN_WARNING "ACPI: Wrong value from %s\n", + acpi_method); + /* Sanitize it */ + d_min = d_max; + } + } + + if (d_max_in < d_min) + return -EINVAL; + if (d_min_p) + *d_min_p = d_min; + /* constrain d_max with specified lowest limit (max number) */ + if (d_max > d_max_in) { + for (d_max = d_max_in; d_max > d_min; d_max--) { + if (adev->power.states[d_max].flags.valid) + break; + } + } + return d_max; +} +EXPORT_SYMBOL_GPL(acpi_device_power_state); diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 4defa0297ee..fa20d017188 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -19,7 +19,6 @@ #include #include #include -#include #include @@ -691,101 +690,20 @@ int acpi_suspend(u32 acpi_state) * Return value: Preferred power state of the device on success, -ENODEV * (if there's no 'struct acpi_device' for @dev) or -EINVAL on failure * - * Find the lowest power (highest number) ACPI device power state that the - * device can be in while the system is in the sleep state represented - * by %acpi_target_sleep_state. If @d_min_p is set, the highest power (lowest - * number) device power state that @dev can be in for the given system sleep - * state is stored at the location pointed to by it. - * * The caller must ensure that @dev is valid before using this function. */ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) { acpi_handle handle = DEVICE_ACPI_HANDLE(dev); struct acpi_device *adev; - char acpi_method[] = "_SxD"; - unsigned long long d_min, d_max; - bool wakeup = false; - if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3) - return -EINVAL; if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { - printk(KERN_DEBUG "ACPI handle has no context!\n"); + dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); return -ENODEV; } - if (d_max_in > ACPI_STATE_D3_HOT) { - enum pm_qos_flags_status stat; - - stat = dev_pm_qos_flags(dev, PM_QOS_FLAG_NO_POWER_OFF); - if (stat == PM_QOS_FLAGS_ALL) - d_max_in = ACPI_STATE_D3_HOT; - } - - acpi_method[2] = '0' + acpi_target_sleep_state; - /* - * If the sleep state is S0, the lowest limit from ACPI is D3, - * but if the device has _S0W, we will use the value from _S0W - * as the lowest limit from ACPI. Finally, we will constrain - * the lowest limit with the specified one. - */ - d_min = ACPI_STATE_D0; - d_max = ACPI_STATE_D3; - - /* - * If present, _SxD methods return the minimum D-state (highest power - * state) we can use for the corresponding S-states. Otherwise, the - * minimum D-state is D0 (ACPI 3.x). - * - * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer - * provided -- that's our fault recovery, we ignore retval. - */ - if (acpi_target_sleep_state > ACPI_STATE_S0) { - acpi_evaluate_integer(handle, acpi_method, NULL, &d_min); - wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid - && adev->wakeup.sleep_state >= acpi_target_sleep_state; - } else if (dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) != - PM_QOS_FLAGS_NONE) { - wakeup = adev->wakeup.flags.valid; - } - - /* - * If _PRW says we can wake up the system from the target sleep state, - * the D-state returned by _SxD is sufficient for that (we assume a - * wakeup-aware driver if wake is set). Still, if _SxW exists - * (ACPI 3.x), it should return the maximum (lowest power) D-state that - * can wake the system. _S0W may be valid, too. - */ - if (wakeup) { - acpi_status status; - - acpi_method[3] = 'W'; - status = acpi_evaluate_integer(handle, acpi_method, NULL, - &d_max); - if (ACPI_FAILURE(status)) { - if (acpi_target_sleep_state != ACPI_STATE_S0 || - status != AE_NOT_FOUND) - d_max = d_min; - } else if (d_max < d_min) { - /* Warn the user of the broken DSDT */ - printk(KERN_WARNING "ACPI: Wrong value from %s\n", - acpi_method); - /* Sanitize it */ - d_min = d_max; - } - } - if (d_max_in < d_min) - return -EINVAL; - if (d_min_p) - *d_min_p = d_min; - /* constrain d_max with specified lowest limit (max number) */ - if (d_max > d_max_in) { - for (d_max = d_max_in; d_max > d_min; d_max--) { - if (adev->power.states[d_max].flags.valid) - break; - } - } - return d_max; + return acpi_device_power_state(dev, adev, acpi_target_sleep_state, + d_max_in, d_min_p); } EXPORT_SYMBOL(acpi_pm_device_sleep_state); #endif /* CONFIG_PM */ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 6983272f9d0..a8080dfe718 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -420,6 +420,8 @@ acpi_status acpi_add_pm_notifier(struct acpi_device *adev, acpi_notify_handler handler, void *context); acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, acpi_notify_handler handler); +int acpi_device_power_state(struct device *dev, struct acpi_device *adev, + u32 target_state, int d_max_in, int *d_min_p); int acpi_pm_device_sleep_state(struct device *, int *, int); #else static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev, @@ -433,12 +435,23 @@ static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev, { return AE_SUPPORT; } -static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m) +static inline int __acpi_device_power_state(int m, int *p) { if (p) *p = ACPI_STATE_D0; return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3) ? m : ACPI_STATE_D0; } +static inline int acpi_device_power_state(struct device *dev, + struct acpi_device *adev, + u32 target_state, int d_max_in, + int *d_min_p) +{ + return __acpi_device_power_state(d_max_in, d_min_p); +} +static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m) +{ + return __acpi_device_power_state(m, p); +} #endif #ifdef CONFIG_PM_RUNTIME -- cgit v1.2.3 From cd7bd02d319eb34fa33d1705cf63f64928643708 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Nov 2012 01:40:28 +0100 Subject: ACPI / PM: Move runtime remote wakeup setup routine to device_pm.c The ACPI function for setting up devices to do runtime remote wakeup is now located in drivers/acpi/sleep.c, but drivers/acpi/device_pm.c is a more logical place for it, so move it there. No functional changes should result from this modification. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 39 +++++++++++++++++++++++++++++++++++++++ drivers/acpi/sleep.c | 39 --------------------------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index c017b801171..81052981045 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -196,3 +197,41 @@ int acpi_device_power_state(struct device *dev, struct acpi_device *adev, return d_max; } EXPORT_SYMBOL_GPL(acpi_device_power_state); + +#ifdef CONFIG_PM_RUNTIME +/** + * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. + * @phys_dev: Device to enable/disable the platform to wake up. + * @enable: Whether to enable or disable the wakeup functionality. + * + * Find the ACPI device object corresponding to @phys_dev and try to + * enable/disable the GPE associated with it, so that it can generate + * wakeup signals for the device in response to external (remote) events. + */ +int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) +{ + struct acpi_device *dev; + acpi_handle handle; + + if (!device_run_wake(phys_dev)) + return -EINVAL; + + handle = DEVICE_ACPI_HANDLE(phys_dev); + if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { + dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", + __func__); + return -ENODEV; + } + + if (enable) { + acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); + acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); + } else { + acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); + acpi_disable_wakeup_device_power(dev); + } + + return 0; +} +EXPORT_SYMBOL(acpi_pm_device_run_wake); +#endif /* CONFIG_PM_RUNTIME */ diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index fa20d017188..241304ee406 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -18,7 +18,6 @@ #include #include #include -#include #include @@ -708,44 +707,6 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) EXPORT_SYMBOL(acpi_pm_device_sleep_state); #endif /* CONFIG_PM */ -#ifdef CONFIG_PM_RUNTIME -/** - * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. - * @phys_dev: Device to enable/disable the platform to wake up. - * @enable: Whether to enable or disable the wakeup functionality. - * - * Find the ACPI device object corresponding to @phys_dev and try to - * enable/disable the GPE associated with it, so that it can generate - * wakeup signals for the device in response to external (remote) events. - */ -int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) -{ - struct acpi_device *dev; - acpi_handle handle; - - if (!device_run_wake(phys_dev)) - return -EINVAL; - - handle = DEVICE_ACPI_HANDLE(phys_dev); - if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { - dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", - __func__); - return -ENODEV; - } - - if (enable) { - acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); - acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); - } else { - acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); - acpi_disable_wakeup_device_power(dev); - } - - return 0; -} -EXPORT_SYMBOL(acpi_pm_device_run_wake); -#endif /* CONFIG_PM_RUNTIME */ - #ifdef CONFIG_PM_SLEEP /** * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system. -- cgit v1.2.3 From dee8370cc87e505ef39567f0974e73d59e75d76b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Nov 2012 01:40:36 +0100 Subject: ACPI / PM: Split device wakeup management routines Two device wakeup management routines in device_pm.c and sleep.c, acpi_pm_device_run_wake() and acpi_pm_device_sleep_wake(), take a device pointer argument and use it to obtain the ACPI handle of the corresponding ACPI namespace node. That handle is then used to get the address of the struct acpi_device object corresponding to the struct device passed as the argument. Unfortunately, that last operation may be costly, because it involves taking the global ACPI namespace mutex, so it shouldn't be carried out too often. However, the callers of those routines usually call them in a row with acpi_pm_device_sleep_state() which also takes that mutex for the same reason, so it would be more efficient if they ran acpi_bus_get_device() themselves to obtain a pointer to the struct acpi_device object in question and then passed that pointer to the appropriate PM routines. To make that possible, split each of the PM routines mentioned above in two parts, one taking a struct acpi_device pointer argument and the other implementing the current interface for compatibility. Additionally, change acpi_pm_device_run_wake() to actually return an error code if there is an error while setting up runtime remote wakeup for the device. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 74 +++++++++++++++++++++++++++++++++++++----------- drivers/acpi/sleep.c | 8 ++---- include/acpi/acpi_bus.h | 11 +++++++ 3 files changed, 71 insertions(+), 22 deletions(-) diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 81052981045..b4f03f91b0b 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -200,38 +200,78 @@ EXPORT_SYMBOL_GPL(acpi_device_power_state); #ifdef CONFIG_PM_RUNTIME /** - * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. - * @phys_dev: Device to enable/disable the platform to wake up. + * __acpi_device_run_wake - Enable/disable runtime remote wakeup for device. + * @adev: ACPI device to enable/disable the remote wakeup for. * @enable: Whether to enable or disable the wakeup functionality. * - * Find the ACPI device object corresponding to @phys_dev and try to - * enable/disable the GPE associated with it, so that it can generate - * wakeup signals for the device in response to external (remote) events. + * Enable/disable the GPE associated with @adev so that it can generate + * wakeup signals for the device in response to external (remote) events and + * enable/disable device wakeup power. + * + * Callers must ensure that @adev is a valid ACPI device node before executing + * this function. + */ +int __acpi_device_run_wake(struct acpi_device *adev, bool enable) +{ + struct acpi_device_wakeup *wakeup = &adev->wakeup; + + if (enable) { + acpi_status res; + int error; + + error = acpi_enable_wakeup_device_power(adev, ACPI_STATE_S0); + if (error) + return error; + + res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); + if (ACPI_FAILURE(res)) { + acpi_disable_wakeup_device_power(adev); + return -EIO; + } + } else { + acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); + acpi_disable_wakeup_device_power(adev); + } + return 0; +} + +/** + * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device. + * @dev: Device to enable/disable the platform to wake up. + * @enable: Whether to enable or disable the wakeup functionality. */ int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) { - struct acpi_device *dev; + struct acpi_device *adev; acpi_handle handle; if (!device_run_wake(phys_dev)) return -EINVAL; handle = DEVICE_ACPI_HANDLE(phys_dev); - if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { - dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", + if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { + dev_dbg(phys_dev, "ACPI handle without context in %s!\n", __func__); return -ENODEV; } - if (enable) { - acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); - acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); - } else { - acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); - acpi_disable_wakeup_device_power(dev); - } - - return 0; + return __acpi_device_run_wake(adev, enable); } EXPORT_SYMBOL(acpi_pm_device_run_wake); #endif /* CONFIG_PM_RUNTIME */ + + #ifdef CONFIG_PM_SLEEP +/** + * __acpi_device_sleep_wake - Enable or disable device to wake up the system. + * @dev: Device to enable/desible to wake up the system. + * @target_state: System state the device is supposed to wake up from. + * @enable: Whether to enable or disable @dev to wake up the system. + */ +int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state, + bool enable) +{ + return enable ? + acpi_enable_wakeup_device_power(adev, target_state) : + acpi_disable_wakeup_device_power(adev); +} +#endif /* CONFIG_PM_SLEEP */ diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 241304ee406..77c517f6f6d 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -724,15 +724,13 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) handle = DEVICE_ACPI_HANDLE(dev); if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { - dev_dbg(dev, "ACPI handle has no context in %s!\n", __func__); + dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); return -ENODEV; } - error = enable ? - acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : - acpi_disable_wakeup_device_power(adev); + error = __acpi_device_sleep_wake(adev, acpi_target_sleep_state, enable); if (!error) - dev_info(dev, "wake-up capability %s by ACPI\n", + dev_info(dev, "System wakeup %s by ACPI\n", enable ? "enabled" : "disabled"); return error; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index a8080dfe718..a635942bcd5 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -455,8 +455,13 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m) #endif #ifdef CONFIG_PM_RUNTIME +int __acpi_device_run_wake(struct acpi_device *, bool); int acpi_pm_device_run_wake(struct device *, bool); #else +static inline int __acpi_device_run_wake(struct acpi_device *adev, bool en) +{ + return -ENODEV; +} static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) { return -ENODEV; @@ -464,8 +469,14 @@ static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) #endif #ifdef CONFIG_PM_SLEEP +int __acpi_device_sleep_wake(struct acpi_device *, u32, bool); int acpi_pm_device_sleep_wake(struct device *, bool); #else +static inline int __acpi_device_sleep_wake(struct acpi_device *adev, + u32 target_state, bool enable) +{ + return -ENODEV; +} static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) { return -ENODEV; -- cgit v1.2.3 From 078eb12648c2f8bba48921f60ec2cec3e1bbc051 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Nov 2012 01:40:45 +0100 Subject: ACPI / PM: Provide device PM functions operating on struct acpi_device If the caller of acpi_bus_set_power() already has a pointer to the struct acpi_device object corresponding to the device in question, it doesn't make sense for it to go through acpi_bus_get_device(), which may be costly, because it involves acquiring the global ACPI namespace mutex. For this reason, export the function operating on struct acpi_device objects used internally by acpi_bus_set_power(), so that it may be called instead of acpi_bus_set_power() in the above case, and change its name to acpi_device_set_power(). Additionally, introduce two inline wrappers for checking ACPI PM capabilities of devices represented by struct acpi_device objects. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/bus.c | 15 ++++++++++++--- include/acpi/acpi_bus.h | 11 +++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index d59175efc42..07a20ee3e69 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -257,7 +257,15 @@ static int __acpi_bus_get_power(struct acpi_device *device, int *state) } -static int __acpi_bus_set_power(struct acpi_device *device, int state) +/** + * acpi_device_set_power - Set power state of an ACPI device. + * @device: Device to set the power state of. + * @state: New power state to set. + * + * Callers must ensure that the device is power manageable before using this + * function. + */ +int acpi_device_set_power(struct acpi_device *device, int state) { int result = 0; acpi_status status = AE_OK; @@ -341,6 +349,7 @@ static int __acpi_bus_set_power(struct acpi_device *device, int state) return result; } +EXPORT_SYMBOL(acpi_device_set_power); int acpi_bus_set_power(acpi_handle handle, int state) @@ -359,7 +368,7 @@ int acpi_bus_set_power(acpi_handle handle, int state) return -ENODEV; } - return __acpi_bus_set_power(device, state); + return acpi_device_set_power(device, state); } EXPORT_SYMBOL(acpi_bus_set_power); @@ -402,7 +411,7 @@ int acpi_bus_update_power(acpi_handle handle, int *state_p) if (result) return result; - result = __acpi_bus_set_power(device, state); + result = acpi_device_set_power(device, state); if (!result && state_p) *state_p = state; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index a635942bcd5..35812b6e042 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -339,6 +339,7 @@ acpi_status acpi_bus_get_status_handle(acpi_handle handle, unsigned long long *sta); int acpi_bus_get_status(struct acpi_device *device); int acpi_bus_set_power(acpi_handle handle, int state); +int acpi_device_set_power(struct acpi_device *device, int state); int acpi_bus_update_power(acpi_handle handle, int *state_p); bool acpi_bus_power_manageable(acpi_handle handle); bool acpi_bus_can_wakeup(acpi_handle handle); @@ -483,6 +484,16 @@ static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) } #endif +static inline bool acpi_device_power_manageable(struct acpi_device *adev) +{ + return adev->flags.power_manageable; +} + +static inline bool acpi_device_can_wakeup(struct acpi_device *adev) +{ + return adev->wakeup.flags.valid; +} + #else /* CONFIG_ACPI */ static inline int register_acpi_bus_type(void *bus) { return 0; } -- cgit v1.2.3 From a6ae7594b1b157e0e7976ed105a7be27d69a5361 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Nov 2012 01:40:53 +0100 Subject: ACPI / PM: Move device PM functions related to sleep states Introduce helper function returning the target sleep state of the system and use it to move the remaining device power management functions from sleep.c to device_pm.c. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 54 +++++++++++++++++++++++++++++++++++++++++ drivers/acpi/sleep.c | 63 +++++------------------------------------------- include/acpi/acpi_bus.h | 2 ++ 3 files changed, 62 insertions(+), 57 deletions(-) diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index b4f03f91b0b..7ddd93463a2 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -198,6 +198,31 @@ int acpi_device_power_state(struct device *dev, struct acpi_device *adev, } EXPORT_SYMBOL_GPL(acpi_device_power_state); +/** + * acpi_pm_device_sleep_state - Get preferred power state of ACPI device. + * @dev: Device whose preferred target power state to return. + * @d_min_p: Location to store the upper limit of the allowed states range. + * @d_max_in: Deepest low-power state to take into consideration. + * Return value: Preferred power state of the device on success, -ENODEV + * (if there's no 'struct acpi_device' for @dev) or -EINVAL on failure + * + * The caller must ensure that @dev is valid before using this function. + */ +int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) +{ + acpi_handle handle = DEVICE_ACPI_HANDLE(dev); + struct acpi_device *adev; + + if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { + dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); + return -ENODEV; + } + + return acpi_device_power_state(dev, adev, acpi_target_system_state(), + d_max_in, d_min_p); +} +EXPORT_SYMBOL(acpi_pm_device_sleep_state); + #ifdef CONFIG_PM_RUNTIME /** * __acpi_device_run_wake - Enable/disable runtime remote wakeup for device. @@ -274,4 +299,33 @@ int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state, acpi_enable_wakeup_device_power(adev, target_state) : acpi_disable_wakeup_device_power(adev); } + +/** + * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system. + * @dev: Device to enable/desible to wake up the system from sleep states. + * @enable: Whether to enable or disable @dev to wake up the system. + */ +int acpi_pm_device_sleep_wake(struct device *dev, bool enable) +{ + acpi_handle handle; + struct acpi_device *adev; + int error; + + if (!device_can_wakeup(dev)) + return -EINVAL; + + handle = DEVICE_ACPI_HANDLE(dev); + if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { + dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); + return -ENODEV; + } + + error = __acpi_device_sleep_wake(adev, acpi_target_system_state(), + enable); + if (!error) + dev_info(dev, "System wakeup %s by ACPI\n", + enable ? "enabled" : "disabled"); + + return error; +} #endif /* CONFIG_PM_SLEEP */ diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 77c517f6f6d..13a285dffac 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -80,6 +80,12 @@ static int acpi_sleep_prepare(u32 acpi_state) #ifdef CONFIG_ACPI_SLEEP static u32 acpi_target_sleep_state = ACPI_STATE_S0; + +u32 acpi_target_system_state(void) +{ + return acpi_target_sleep_state; +} + static bool pwr_btn_event_pending; /* @@ -680,63 +686,6 @@ int acpi_suspend(u32 acpi_state) return -EINVAL; } -#ifdef CONFIG_PM -/** - * acpi_pm_device_sleep_state - Get preferred power state of ACPI device. - * @dev: Device whose preferred target power state to return. - * @d_min_p: Location to store the upper limit of the allowed states range. - * @d_max_in: Deepest low-power state to take into consideration. - * Return value: Preferred power state of the device on success, -ENODEV - * (if there's no 'struct acpi_device' for @dev) or -EINVAL on failure - * - * The caller must ensure that @dev is valid before using this function. - */ -int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) -{ - acpi_handle handle = DEVICE_ACPI_HANDLE(dev); - struct acpi_device *adev; - - if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { - dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); - return -ENODEV; - } - - return acpi_device_power_state(dev, adev, acpi_target_sleep_state, - d_max_in, d_min_p); -} -EXPORT_SYMBOL(acpi_pm_device_sleep_state); -#endif /* CONFIG_PM */ - -#ifdef CONFIG_PM_SLEEP -/** - * acpi_pm_device_sleep_wake - Enable or disable device to wake up the system. - * @dev: Device to enable/desible to wake up the system from sleep states. - * @enable: Whether to enable or disable @dev to wake up the system. - */ -int acpi_pm_device_sleep_wake(struct device *dev, bool enable) -{ - acpi_handle handle; - struct acpi_device *adev; - int error; - - if (!device_can_wakeup(dev)) - return -EINVAL; - - handle = DEVICE_ACPI_HANDLE(dev); - if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { - dev_dbg(dev, "ACPI handle without context in %s!\n", __func__); - return -ENODEV; - } - - error = __acpi_device_sleep_wake(adev, acpi_target_sleep_state, enable); - if (!error) - dev_info(dev, "System wakeup %s by ACPI\n", - enable ? "enabled" : "disabled"); - - return error; -} -#endif /* CONFIG_PM_SLEEP */ - static void acpi_power_off_prepare(void) { /* Prepare to power off the system */ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 35812b6e042..bf8709a1844 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -470,9 +470,11 @@ static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) #endif #ifdef CONFIG_PM_SLEEP +u32 acpi_target_system_state(void); int __acpi_device_sleep_wake(struct acpi_device *, u32, bool); int acpi_pm_device_sleep_wake(struct device *, bool); #else +static inline u32 acpi_target_system_state(void) { return ACPI_STATE_S0; } static inline int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state, bool enable) { -- cgit v1.2.3 From e5cc8ef31267317f3e177415c84e3f3602e5bfc9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Nov 2012 01:41:01 +0100 Subject: ACPI / PM: Provide ACPI PM callback routines for subsystems Some bus types don't support power management natively, but generally there may be device nodes in ACPI tables corresponding to the devices whose bus types they are (under ACPI 5 those bus types may be SPI, I2C and platform). If that is the case, standard ACPI power management may be applied to those devices, although currently the kernel has no means for that. For this reason, provide a set of routines that may be used as power management callbacks for such devices. This may be done in three different ways. (1) Device drivers handling the devices in question may run acpi_dev_pm_attach() in their .probe() routines, which (on success) will cause the devices to be added to the general ACPI PM domain and ACPI power management will be used for them going forward. Then, acpi_dev_pm_detach() may be used to remove the devices from the general ACPI PM domain if ACPI power management is not necessary for them any more. (2) The devices' subsystems may use acpi_subsys_runtime_suspend(), acpi_subsys_runtime_resume(), acpi_subsys_prepare(), acpi_subsys_suspend_late(), acpi_subsys_resume_early() as their power management callbacks in the same way as the general ACPI PM domain does that. (3) The devices' drivers may execute acpi_dev_suspend_late(), acpi_dev_resume_early(), acpi_dev_runtime_suspend(), acpi_dev_runtime_resume() from their power management callbacks as appropriate, if that's absolutely necessary, but it is not recommended to do that, because such drivers may not work without ACPI support as a result. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 317 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 34 +++++ 2 files changed, 351 insertions(+) diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 7ddd93463a2..a8e059f69d5 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -224,6 +224,22 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in) EXPORT_SYMBOL(acpi_pm_device_sleep_state); #ifdef CONFIG_PM_RUNTIME +/** + * acpi_wakeup_device - Wakeup notification handler for ACPI devices. + * @handle: ACPI handle of the device the notification is for. + * @event: Type of the signaled event. + * @context: Device corresponding to @handle. + */ +static void acpi_wakeup_device(acpi_handle handle, u32 event, void *context) +{ + struct device *dev = context; + + if (event == ACPI_NOTIFY_DEVICE_WAKE && dev) { + pm_wakeup_event(dev, 0); + pm_runtime_resume(dev); + } +} + /** * __acpi_device_run_wake - Enable/disable runtime remote wakeup for device. * @adev: ACPI device to enable/disable the remote wakeup for. @@ -283,6 +299,9 @@ int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) return __acpi_device_run_wake(adev, enable); } EXPORT_SYMBOL(acpi_pm_device_run_wake); +#else +static inline void acpi_wakeup_device(acpi_handle handle, u32 event, + void *context) {} #endif /* CONFIG_PM_RUNTIME */ #ifdef CONFIG_PM_SLEEP @@ -329,3 +348,301 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) return error; } #endif /* CONFIG_PM_SLEEP */ + +/** + * acpi_dev_pm_get_node - Get ACPI device node for the given physical device. + * @dev: Device to get the ACPI node for. + */ +static struct acpi_device *acpi_dev_pm_get_node(struct device *dev) +{ + acpi_handle handle = DEVICE_ACPI_HANDLE(dev); + struct acpi_device *adev; + + return handle && ACPI_SUCCESS(acpi_bus_get_device(handle, &adev)) ? + adev : NULL; +} + +/** + * acpi_dev_pm_low_power - Put ACPI device into a low-power state. + * @dev: Device to put into a low-power state. + * @adev: ACPI device node corresponding to @dev. + * @system_state: System state to choose the device state for. + */ +static int acpi_dev_pm_low_power(struct device *dev, struct acpi_device *adev, + u32 system_state) +{ + int power_state; + + if (!acpi_device_power_manageable(adev)) + return 0; + + power_state = acpi_device_power_state(dev, adev, system_state, + ACPI_STATE_D3, NULL); + if (power_state < ACPI_STATE_D0 || power_state > ACPI_STATE_D3) + return -EIO; + + return acpi_device_set_power(adev, power_state); +} + +/** + * acpi_dev_pm_full_power - Put ACPI device into the full-power state. + * @adev: ACPI device node to put into the full-power state. + */ +static int acpi_dev_pm_full_power(struct acpi_device *adev) +{ + return acpi_device_power_manageable(adev) ? + acpi_device_set_power(adev, ACPI_STATE_D0) : 0; +} + +#ifdef CONFIG_PM_RUNTIME +/** + * acpi_dev_runtime_suspend - Put device into a low-power state using ACPI. + * @dev: Device to put into a low-power state. + * + * Put the given device into a runtime low-power state using the standard ACPI + * mechanism. Set up remote wakeup if desired, choose the state to put the + * device into (this checks if remote wakeup is expected to work too), and set + * the power state of the device. + */ +int acpi_dev_runtime_suspend(struct device *dev) +{ + struct acpi_device *adev = acpi_dev_pm_get_node(dev); + bool remote_wakeup; + int error; + + if (!adev) + return 0; + + remote_wakeup = dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) > + PM_QOS_FLAGS_NONE; + error = __acpi_device_run_wake(adev, remote_wakeup); + if (remote_wakeup && error) + return -EAGAIN; + + error = acpi_dev_pm_low_power(dev, adev, ACPI_STATE_S0); + if (error) + __acpi_device_run_wake(adev, false); + + return error; +} +EXPORT_SYMBOL_GPL(acpi_dev_runtime_suspend); + +/** + * acpi_dev_runtime_resume - Put device into the full-power state using ACPI. + * @dev: Device to put into the full-power state. + * + * Put the given device into the full-power state using the standard ACPI + * mechanism at run time. Set the power state of the device to ACPI D0 and + * disable remote wakeup. + */ +int acpi_dev_runtime_resume(struct device *dev) +{ + struct acpi_device *adev = acpi_dev_pm_get_node(dev); + int error; + + if (!adev) + return 0; + + error = acpi_dev_pm_full_power(adev); + __acpi_device_run_wake(adev, false); + return error; +} +EXPORT_SYMBOL_GPL(acpi_dev_runtime_resume); + +/** + * acpi_subsys_runtime_suspend - Suspend device using ACPI. + * @dev: Device to suspend. + * + * Carry out the generic runtime suspend procedure for @dev and use ACPI to put + * it into a runtime low-power state. + */ +int acpi_subsys_runtime_suspend(struct device *dev) +{ + int ret = pm_generic_runtime_suspend(dev); + return ret ? ret : acpi_dev_runtime_suspend(dev); +} +EXPORT_SYMBOL_GPL(acpi_subsys_runtime_suspend); + +/** + * acpi_subsys_runtime_resume - Resume device using ACPI. + * @dev: Device to Resume. + * + * Use ACPI to put the given device into the full-power state and carry out the + * generic runtime resume procedure for it. + */ +int acpi_subsys_runtime_resume(struct device *dev) +{ + int ret = acpi_dev_runtime_resume(dev); + return ret ? ret : pm_generic_runtime_resume(dev); +} +EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume); +#endif /* CONFIG_PM_RUNTIME */ + +#ifdef CONFIG_PM_SLEEP +/** + * acpi_dev_suspend_late - Put device into a low-power state using ACPI. + * @dev: Device to put into a low-power state. + * + * Put the given device into a low-power state during system transition to a + * sleep state using the standard ACPI mechanism. Set up system wakeup if + * desired, choose the state to put the device into (this checks if system + * wakeup is expected to work too), and set the power state of the device. + */ +int acpi_dev_suspend_late(struct device *dev) +{ + struct acpi_device *adev = acpi_dev_pm_get_node(dev); + u32 target_state; + bool wakeup; + int error; + + if (!adev) + return 0; + + target_state = acpi_target_system_state(); + wakeup = device_may_wakeup(dev); + error = __acpi_device_sleep_wake(adev, target_state, wakeup); + if (wakeup && error) + return error; + + error = acpi_dev_pm_low_power(dev, adev, target_state); + if (error) + __acpi_device_sleep_wake(adev, ACPI_STATE_UNKNOWN, false); + + return error; +} +EXPORT_SYMBOL_GPL(acpi_dev_suspend_late); + +/** + * acpi_dev_resume_early - Put device into the full-power state using ACPI. + * @dev: Device to put into the full-power state. + * + * Put the given device into the full-power state using the standard ACPI + * mechanism during system transition to the working state. Set the power + * state of the device to ACPI D0 and disable remote wakeup. + */ +int acpi_dev_resume_early(struct device *dev) +{ + struct acpi_device *adev = acpi_dev_pm_get_node(dev); + int error; + + if (!adev) + return 0; + + error = acpi_dev_pm_full_power(adev); + __acpi_device_sleep_wake(adev, ACPI_STATE_UNKNOWN, false); + return error; +} +EXPORT_SYMBOL_GPL(acpi_dev_resume_early); + +/** + * acpi_subsys_prepare - Prepare device for system transition to a sleep state. + * @dev: Device to prepare. + */ +int acpi_subsys_prepare(struct device *dev) +{ + /* + * Follow PCI and resume devices suspended at run time before running + * their system suspend callbacks. + */ + pm_runtime_resume(dev); + return pm_generic_prepare(dev); +} +EXPORT_SYMBOL_GPL(acpi_subsys_prepare); + +/** + * acpi_subsys_suspend_late - Suspend device using ACPI. + * @dev: Device to suspend. + * + * Carry out the generic late suspend procedure for @dev and use ACPI to put + * it into a low-power state during system transition into a sleep state. + */ +int acpi_subsys_suspend_late(struct device *dev) +{ + int ret = pm_generic_suspend_late(dev); + return ret ? ret : acpi_dev_suspend_late(dev); +} +EXPORT_SYMBOL_GPL(acpi_subsys_suspend_late); + +/** + * acpi_subsys_resume_early - Resume device using ACPI. + * @dev: Device to Resume. + * + * Use ACPI to put the given device into the full-power state and carry out the + * generic early resume procedure for it during system transition into the + * working state. + */ +int acpi_subsys_resume_early(struct device *dev) +{ + int ret = acpi_dev_resume_early(dev); + return ret ? ret : pm_generic_resume_early(dev); +} +EXPORT_SYMBOL_GPL(acpi_subsys_resume_early); +#endif /* CONFIG_PM_SLEEP */ + +static struct dev_pm_domain acpi_general_pm_domain = { + .ops = { +#ifdef CONFIG_PM_RUNTIME + .runtime_suspend = acpi_subsys_runtime_suspend, + .runtime_resume = acpi_subsys_runtime_resume, + .runtime_idle = pm_generic_runtime_idle, +#endif +#ifdef CONFIG_PM_SLEEP + .prepare = acpi_subsys_prepare, + .suspend_late = acpi_subsys_suspend_late, + .resume_early = acpi_subsys_resume_early, + .poweroff_late = acpi_subsys_suspend_late, + .restore_early = acpi_subsys_resume_early, +#endif + }, +}; + +/** + * acpi_dev_pm_attach - Prepare device for ACPI power management. + * @dev: Device to prepare. + * + * If @dev has a valid ACPI handle that has a valid struct acpi_device object + * attached to it, install a wakeup notification handler for the device and + * add it to the general ACPI PM domain. + * + * This assumes that the @dev's bus type uses generic power management callbacks + * (or doesn't use any power management callbacks at all). + * + * Callers must ensure proper synchronization of this function with power + * management callbacks. + */ +int acpi_dev_pm_attach(struct device *dev) +{ + struct acpi_device *adev = acpi_dev_pm_get_node(dev); + + if (!adev) + return -ENODEV; + + if (dev->pm_domain) + return -EEXIST; + + acpi_add_pm_notifier(adev, acpi_wakeup_device, dev); + dev->pm_domain = &acpi_general_pm_domain; + return 0; +} +EXPORT_SYMBOL_GPL(acpi_dev_pm_attach); + +/** + * acpi_dev_pm_detach - Remove ACPI power management from the device. + * @dev: Device to take care of. + * + * Remove the device from the general ACPI PM domain and remove its wakeup + * notifier. + * + * Callers must ensure proper synchronization of this function with power + * management callbacks. + */ +void acpi_dev_pm_detach(struct device *dev) +{ + struct acpi_device *adev = acpi_dev_pm_get_node(dev); + + if (adev && dev->pm_domain == &acpi_general_pm_domain) { + dev->pm_domain = NULL; + acpi_remove_pm_notifier(adev, acpi_wakeup_device); + } +} +EXPORT_SYMBOL_GPL(acpi_dev_pm_detach); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 90be9898110..0676b6ac57f 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -430,4 +430,38 @@ acpi_status acpi_os_prepare_sleep(u8 sleep_state, #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0) #endif +#if defined(CONFIG_ACPI) && defined(CONFIG_PM_RUNTIME) +int acpi_dev_runtime_suspend(struct device *dev); +int acpi_dev_runtime_resume(struct device *dev); +int acpi_subsys_runtime_suspend(struct device *dev); +int acpi_subsys_runtime_resume(struct device *dev); +#else +static inline int acpi_dev_runtime_suspend(struct device *dev) { return 0; } +static inline int acpi_dev_runtime_resume(struct device *dev) { return 0; } +static inline int acpi_subsys_runtime_suspend(struct device *dev) { return 0; } +static inline int acpi_subsys_runtime_resume(struct device *dev) { return 0; } +#endif + +#ifdef CONFIG_ACPI_SLEEP +int acpi_dev_suspend_late(struct device *dev); +int acpi_dev_resume_early(struct device *dev); +int acpi_subsys_prepare(struct device *dev); +int acpi_subsys_suspend_late(struct device *dev); +int acpi_subsys_resume_early(struct device *dev); +#else +static inline int acpi_dev_suspend_late(struct device *dev) { return 0; } +static inline int acpi_dev_resume_early(struct device *dev) { return 0; } +static inline int acpi_subsys_prepare(struct device *dev) { return 0; } +static inline int acpi_subsys_suspend_late(struct device *dev) { return 0; } +static inline int acpi_subsys_resume_early(struct device *dev) { return 0; } +#endif + +#if defined(CONFIG_ACPI) && defined(CONFIG_PM) +int acpi_dev_pm_attach(struct device *dev); +int acpi_dev_pm_detach(struct device *dev); +#else +static inline int acpi_dev_pm_attach(struct device *dev) { return -ENODEV; } +static inline void acpi_dev_pm_detach(struct device *dev) {} +#endif + #endif /*_LINUX_ACPI_H*/ -- cgit v1.2.3 From 99926a8cd36b6088448fec41aed4a3b5b05b3679 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Sat, 10 Nov 2012 22:48:33 +0100 Subject: ACPI / PM: Fix build problem related to acpi_target_system_state() Commit b87b49cd0efd ("ACPI / PM: Move device PM functions related to sleep states") declared acpi_target_system_state() for CONFIG_PM_SLEEP whereas it is only defined for CONFIG_ACPI_SLEEP, resulting in the following link error: drivers/built-in.o: In function `acpi_pm_device_sleep_wake': drivers/acpi/device_pm.c:342: undefined reference to `acpi_target_system_state' drivers/built-in.o: In function `acpi_dev_suspend_late': drivers/acpi/device_pm.c:501: undefined reference to `acpi_target_system_state' drivers/built-in.o: In function `acpi_pm_device_sleep_state': drivers/acpi/device_pm.c:221: undefined reference to `acpi_target_system_state' Define it only for CONFIG_ACPI_SLEEP and fallback to a dummy definition for other configs. [rjw: The problem only occurs for exotic .configs in which HIBERNATE_CALLBACKS is selected by XEN_SAVE_RESTORE and neither SUSPEND nor HIBERNATION is set.] Signed-off-by: David Rientjes Signed-off-by: Rafael J. Wysocki --- include/acpi/acpi_bus.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index bf8709a1844..80155fda517 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -470,11 +470,9 @@ static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) #endif #ifdef CONFIG_PM_SLEEP -u32 acpi_target_system_state(void); int __acpi_device_sleep_wake(struct acpi_device *, u32, bool); int acpi_pm_device_sleep_wake(struct device *, bool); #else -static inline u32 acpi_target_system_state(void) { return ACPI_STATE_S0; } static inline int __acpi_device_sleep_wake(struct acpi_device *adev, u32 target_state, bool enable) { @@ -486,6 +484,12 @@ static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) } #endif +#ifdef CONFIG_ACPI_SLEEP +u32 acpi_target_system_state(void); +#else +static inline u32 acpi_target_system_state(void) { return ACPI_STATE_S0; } +#endif + static inline bool acpi_device_power_manageable(struct acpi_device *adev) { return adev->flags.power_manageable; -- cgit v1.2.3 From f351d027eea545a7996af54fce99f5668a67fec5 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 23 Oct 2012 01:29:27 +0200 Subject: ACPI / EC: Cleanup the member name for spinlock/mutex in struct Current member names for mutex/spinlock are a little confusing. Change the { struct mutex lock; spinlock_t curr_lock; } to { struct mutex mutex; spinlock_t lock; } So that the code is cleaner and easier to read. Signed-off-by: Feng Tang Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 52 ++++++++++++++++++++++++------------------------- drivers/acpi/internal.h | 4 ++-- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a51df968131..29f349ccf62 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -158,10 +158,10 @@ static int ec_transaction_done(struct acpi_ec *ec) { unsigned long flags; int ret = 0; - spin_lock_irqsave(&ec->curr_lock, flags); + spin_lock_irqsave(&ec->lock, flags); if (!ec->curr || ec->curr->done) ret = 1; - spin_unlock_irqrestore(&ec->curr_lock, flags); + spin_unlock_irqrestore(&ec->lock, flags); return ret; } @@ -175,7 +175,7 @@ static void start_transaction(struct acpi_ec *ec) static void advance_transaction(struct acpi_ec *ec, u8 status) { unsigned long flags; - spin_lock_irqsave(&ec->curr_lock, flags); + spin_lock_irqsave(&ec->lock, flags); if (!ec->curr) goto unlock; if (ec->curr->wlen > ec->curr->wi) { @@ -200,7 +200,7 @@ err: if (in_interrupt()) ++ec->curr->irq_count; unlock: - spin_unlock_irqrestore(&ec->curr_lock, flags); + spin_unlock_irqrestore(&ec->lock, flags); } static int acpi_ec_sync_query(struct acpi_ec *ec); @@ -238,9 +238,9 @@ static int ec_poll(struct acpi_ec *ec) if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) break; pr_debug(PREFIX "controller reset, restart transaction\n"); - spin_lock_irqsave(&ec->curr_lock, flags); + spin_lock_irqsave(&ec->lock, flags); start_transaction(ec); - spin_unlock_irqrestore(&ec->curr_lock, flags); + spin_unlock_irqrestore(&ec->lock, flags); } return -ETIME; } @@ -253,17 +253,17 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, if (EC_FLAGS_MSI) udelay(ACPI_EC_MSI_UDELAY); /* start transaction */ - spin_lock_irqsave(&ec->curr_lock, tmp); + spin_lock_irqsave(&ec->lock, tmp); /* following two actions should be kept atomic */ ec->curr = t; start_transaction(ec); if (ec->curr->command == ACPI_EC_COMMAND_QUERY) clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); - spin_unlock_irqrestore(&ec->curr_lock, tmp); + spin_unlock_irqrestore(&ec->lock, tmp); ret = ec_poll(ec); - spin_lock_irqsave(&ec->curr_lock, tmp); + spin_lock_irqsave(&ec->lock, tmp); ec->curr = NULL; - spin_unlock_irqrestore(&ec->curr_lock, tmp); + spin_unlock_irqrestore(&ec->lock, tmp); return ret; } @@ -292,7 +292,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) return -EINVAL; if (t->rdata) memset(t->rdata, 0, t->rlen); - mutex_lock(&ec->lock); + mutex_lock(&ec->mutex); if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) { status = -EINVAL; goto unlock; @@ -335,7 +335,7 @@ end: if (ec->global_lock) acpi_release_global_lock(glk); unlock: - mutex_unlock(&ec->lock); + mutex_unlock(&ec->mutex); return status; } @@ -468,10 +468,10 @@ void acpi_ec_block_transactions(void) if (!ec) return; - mutex_lock(&ec->lock); + mutex_lock(&ec->mutex); /* Prevent transactions from being carried out */ set_bit(EC_FLAGS_BLOCKED, &ec->flags); - mutex_unlock(&ec->lock); + mutex_unlock(&ec->mutex); } void acpi_ec_unblock_transactions(void) @@ -481,10 +481,10 @@ void acpi_ec_unblock_transactions(void) if (!ec) return; - mutex_lock(&ec->lock); + mutex_lock(&ec->mutex); /* Allow transactions to be carried out again */ clear_bit(EC_FLAGS_BLOCKED, &ec->flags); - mutex_unlock(&ec->lock); + mutex_unlock(&ec->mutex); } void acpi_ec_unblock_transactions_early(void) @@ -536,9 +536,9 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, handler->handle = handle; handler->func = func; handler->data = data; - mutex_lock(&ec->lock); + mutex_lock(&ec->mutex); list_add(&handler->node, &ec->list); - mutex_unlock(&ec->lock); + mutex_unlock(&ec->mutex); return 0; } @@ -547,14 +547,14 @@ EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler); void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) { struct acpi_ec_query_handler *handler, *tmp; - mutex_lock(&ec->lock); + mutex_lock(&ec->mutex); list_for_each_entry_safe(handler, tmp, &ec->list, node) { if (query_bit == handler->query_bit) { list_del(&handler->node); kfree(handler); } } - mutex_unlock(&ec->lock); + mutex_unlock(&ec->mutex); } EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); @@ -601,9 +601,9 @@ static void acpi_ec_gpe_query(void *ec_cxt) struct acpi_ec *ec = ec_cxt; if (!ec) return; - mutex_lock(&ec->lock); + mutex_lock(&ec->mutex); acpi_ec_sync_query(ec); - mutex_unlock(&ec->lock); + mutex_unlock(&ec->mutex); } static int ec_check_sci(struct acpi_ec *ec, u8 state) @@ -691,10 +691,10 @@ static struct acpi_ec *make_acpi_ec(void) if (!ec) return NULL; ec->flags = 1 << EC_FLAGS_QUERY_PENDING; - mutex_init(&ec->lock); + mutex_init(&ec->mutex); init_waitqueue_head(&ec->wait); INIT_LIST_HEAD(&ec->list); - spin_lock_init(&ec->curr_lock); + spin_lock_init(&ec->lock); return ec; } @@ -853,12 +853,12 @@ static int acpi_ec_remove(struct acpi_device *device, int type) ec = acpi_driver_data(device); ec_remove_handlers(ec); - mutex_lock(&ec->lock); + mutex_lock(&ec->mutex); list_for_each_entry_safe(handler, tmp, &ec->list, node) { list_del(&handler->node); kfree(handler); } - mutex_unlock(&ec->lock); + mutex_unlock(&ec->mutex); release_region(ec->data_addr, 1); release_region(ec->command_addr, 1); device->driver_data = NULL; diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index ca75b9ce048..509dcaa1755 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -58,11 +58,11 @@ struct acpi_ec { unsigned long data_addr; unsigned long global_lock; unsigned long flags; - struct mutex lock; + struct mutex mutex; wait_queue_head_t wait; struct list_head list; struct transaction *curr; - spinlock_t curr_lock; + spinlock_t lock; }; extern struct acpi_ec *first_ec; -- cgit v1.2.3 From b76b51ba0cef13980813373a548a12206e3cd3c9 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 23 Oct 2012 01:29:38 +0200 Subject: ACPI / EC: Add more debug info and trivial code cleanup Add more debug info for EC transaction debugging, like the interrupt status register value, the detail info of a EC transaction. Signed-off-by: Feng Tang Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 29f349ccf62..8f8b644bba8 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -175,30 +175,32 @@ static void start_transaction(struct acpi_ec *ec) static void advance_transaction(struct acpi_ec *ec, u8 status) { unsigned long flags; + struct transaction *t = ec->curr; + spin_lock_irqsave(&ec->lock, flags); - if (!ec->curr) + if (!t) goto unlock; - if (ec->curr->wlen > ec->curr->wi) { + if (t->wlen > t->wi) { if ((status & ACPI_EC_FLAG_IBF) == 0) acpi_ec_write_data(ec, - ec->curr->wdata[ec->curr->wi++]); + t->wdata[t->wi++]); else goto err; - } else if (ec->curr->rlen > ec->curr->ri) { + } else if (t->rlen > t->ri) { if ((status & ACPI_EC_FLAG_OBF) == 1) { - ec->curr->rdata[ec->curr->ri++] = acpi_ec_read_data(ec); - if (ec->curr->rlen == ec->curr->ri) - ec->curr->done = true; + t->rdata[t->ri++] = acpi_ec_read_data(ec); + if (t->rlen == t->ri) + t->done = true; } else goto err; - } else if (ec->curr->wlen == ec->curr->wi && + } else if (t->wlen == t->wi && (status & ACPI_EC_FLAG_IBF) == 0) - ec->curr->done = true; + t->done = true; goto unlock; err: /* false interrupt, state didn't change */ if (in_interrupt()) - ++ec->curr->irq_count; + ++t->irq_count; unlock: spin_unlock_irqrestore(&ec->lock, flags); } @@ -310,7 +312,8 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) status = -ETIME; goto end; } - pr_debug(PREFIX "transaction start\n"); + pr_debug(PREFIX "transaction start (cmd=0x%02x, addr=0x%02x)\n", + t->command, t->wdata ? t->wdata[0] : 0); /* disable GPE during transaction if storm is detected */ if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { /* It has to be disabled, so that it doesn't trigger. */ @@ -326,8 +329,9 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) /* It is safe to enable the GPE outside of the transaction. */ acpi_enable_gpe(NULL, ec->gpe); } else if (t->irq_count > ec_storm_threshold) { - pr_info(PREFIX "GPE storm detected, " - "transactions will use polling mode\n"); + pr_info(PREFIX "GPE storm detected(%d GPEs), " + "transactions will use polling mode\n", + t->irq_count); set_bit(EC_FLAGS_GPE_STORM, &ec->flags); } pr_debug(PREFIX "transaction end\n"); @@ -403,7 +407,7 @@ int ec_burst_disable(void) EXPORT_SYMBOL(ec_burst_disable); -int ec_read(u8 addr, u8 * val) +int ec_read(u8 addr, u8 *val) { int err; u8 temp_data; @@ -622,10 +626,11 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, u32 gpe_number, void *data) { struct acpi_ec *ec = data; + u8 status = acpi_ec_read_status(ec); - pr_debug(PREFIX "~~~> interrupt\n"); + pr_debug(PREFIX "~~~> interrupt, status:0x%02x\n", status); - advance_transaction(ec, acpi_ec_read_status(ec)); + advance_transaction(ec, status); if (ec_transaction_done(ec) && (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { wake_up(&ec->wait); -- cgit v1.2.3 From a3cd8d2789c2e265e09377f260e7d2ac9cec81bb Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 23 Oct 2012 01:30:12 +0200 Subject: ACPI / EC: Don't count a SCI interrupt as a false one Currently when advance_transaction() is called in EC interrupt handler, if there is nothing driver can do with the interrupt, it will be taken as a false one. But this is not always true, as there may be a SCI EC interrupt fired during normal read/write operation, which should not be counted as a false one. This patch fixes the problem. Signed-off-by: Feng Tang Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 8f8b644bba8..354007d490d 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -198,9 +198,13 @@ static void advance_transaction(struct acpi_ec *ec, u8 status) t->done = true; goto unlock; err: - /* false interrupt, state didn't change */ - if (in_interrupt()) + /* + * If SCI bit is set, then don't think it's a false IRQ + * otherwise will take a not handled IRQ as a false one. + */ + if (in_interrupt() && !(status & ACPI_EC_FLAG_SCI)) ++t->irq_count; + unlock: spin_unlock_irqrestore(&ec->lock, flags); } -- cgit v1.2.3 From 8ab0ab2570cfc48303e545944f53690a6983a898 Mon Sep 17 00:00:00 2001 From: Toshi Kani Date: Tue, 23 Oct 2012 01:30:26 +0200 Subject: ACPI: dock: Remove redundant ACPI NS walk Combined two ACPI namespace walks, which look for dock stations and then bays separately, into a single walk. Signed-off-by: Toshi Kani Reviewed-by: Yasuaki Ishimatsu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/dock.c | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 88eb1430466..ae4ebf2d4cd 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -1016,44 +1016,32 @@ static int dock_remove(struct dock_station *ds) } /** - * find_dock - look for a dock station + * find_dock_and_bay - look for dock stations and bays * @handle: acpi handle of a device * @lvl: unused - * @context: counter of dock stations found + * @context: unused * @rv: unused * - * This is called by acpi_walk_namespace to look for dock stations. + * This is called by acpi_walk_namespace to look for dock stations and bays. */ static __init acpi_status -find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) +find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv) { - if (is_dock(handle)) + if (is_dock(handle) || is_ejectable_bay(handle)) dock_add(handle); return AE_OK; } -static __init acpi_status -find_bay(acpi_handle handle, u32 lvl, void *context, void **rv) -{ - /* If bay is a dock, it's already handled */ - if (is_ejectable_bay(handle) && !is_dock(handle)) - dock_add(handle); - return AE_OK; -} - static int __init dock_init(void) { if (acpi_disabled) return 0; - /* look for a dock station */ + /* look for dock stations and bays */ acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, find_dock, NULL, NULL, NULL); + ACPI_UINT32_MAX, find_dock_and_bay, NULL, NULL, NULL); - /* look for bay */ - acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, find_bay, NULL, NULL, NULL); if (!dock_station_count) { printk(KERN_INFO PREFIX "No dock devices found.\n"); return 0; -- cgit v1.2.3 From 73d4511a5f1e208399b2f7a058b73578c1977611 Mon Sep 17 00:00:00 2001 From: Josh Date: Tue, 23 Oct 2012 01:30:40 +0200 Subject: ACPI: strict_strtoul() and printk() cleanup in acpi_pad Replace a few calls to strict_strtoul() in acpi_pad.c with kstrtoul() and use pr_warn() instead of printk() in the same file. [rjw: Modified the subject and changelog.] Signed-off-by: Josh Taylor Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_pad.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index af4aad6ee2e..16fa979f718 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -286,7 +286,7 @@ static ssize_t acpi_pad_rrtime_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long num; - if (strict_strtoul(buf, 0, &num)) + if (kstrtoul(buf, 0, &num)) return -EINVAL; if (num < 1 || num >= 100) return -EINVAL; @@ -309,7 +309,7 @@ static ssize_t acpi_pad_idlepct_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long num; - if (strict_strtoul(buf, 0, &num)) + if (kstrtoul(buf, 0, &num)) return -EINVAL; if (num < 1 || num >= 100) return -EINVAL; @@ -332,7 +332,7 @@ static ssize_t acpi_pad_idlecpus_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long num; - if (strict_strtoul(buf, 0, &num)) + if (kstrtoul(buf, 0, &num)) return -EINVAL; mutex_lock(&isolated_cpus_lock); acpi_pad_idle_cpus(num); @@ -457,7 +457,7 @@ static void acpi_pad_notify(acpi_handle handle, u32 event, dev_name(&device->dev), event, 0); break; default: - printk(KERN_WARNING "Unsupported event [0x%x]\n", event); + pr_warn("Unsupported event [0x%x]\n", event); break; } } -- cgit v1.2.3 From 5e5041f3527b36b58e864886ba34c179ad40ff92 Mon Sep 17 00:00:00 2001 From: Yasuaki Ishimatsu Date: Tue, 23 Oct 2012 01:30:54 +0200 Subject: ACPI / processor: prevent cpu from becoming online Even if acpi_processor_handle_eject() offlines cpu, there is a chance to online the cpu after that. So the patch closes the window by using get/put_online_cpus(). Why does the patch change _cpu_up() logic? The patch cares the race of hot-remove cpu and _cpu_up(). If the patch does not change it, there is the following race. hot-remove cpu | _cpu_up() ------------------------------------- ------------------------------------ call acpi_processor_handle_eject() | call cpu_down() | call get_online_cpus() | | call cpu_hotplug_begin() and stop here call arch_unregister_cpu() | call acpi_unmap_lsapic() | call put_online_cpus() | | start and continue _cpu_up() return acpi_processor_remove() | continue hot-remove the cpu | So _cpu_up() can continue to itself. And hot-remove cpu can also continue itself. If the patch changes _cpu_up() logic, the race disappears as below: hot-remove cpu | _cpu_up() ----------------------------------------------------------------------- call acpi_processor_handle_eject() | call cpu_down() | call get_online_cpus() | | call cpu_hotplug_begin() and stop here call arch_unregister_cpu() | call acpi_unmap_lsapic() | cpu's cpu_present is set | to false by set_cpu_present()| call put_online_cpus() | | start _cpu_up() | check cpu_present() and return -EINVAL return acpi_processor_remove() | continue hot-remove the cpu | Signed-off-by: Yasuaki Ishimatsu Reviewed-by: Srivatsa S. Bhat Reviewed-by: Toshi Kani Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_driver.c | 14 ++++++++++++++ kernel/cpu.c | 8 +++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index bd4e5dca3ff..a4352b88a33 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -852,8 +852,22 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr) if (cpu_online(pr->id)) cpu_down(pr->id); + get_online_cpus(); + /* + * The cpu might become online again at this point. So we check whether + * the cpu has been onlined or not. If the cpu became online, it means + * that someone wants to use the cpu. So acpi_processor_handle_eject() + * returns -EAGAIN. + */ + if (unlikely(cpu_online(pr->id))) { + put_online_cpus(); + pr_warn("Failed to remove CPU %d, because other task " + "brought the CPU back online\n", pr->id); + return -EAGAIN; + } arch_unregister_cpu(pr->id); acpi_unmap_lsapic(pr->id); + put_online_cpus(); return (0); } #else diff --git a/kernel/cpu.c b/kernel/cpu.c index 42bd331ee0a..f45657f1eb8 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -348,11 +348,13 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen) unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; struct task_struct *idle; - if (cpu_online(cpu) || !cpu_present(cpu)) - return -EINVAL; - cpu_hotplug_begin(); + if (cpu_online(cpu) || !cpu_present(cpu)) { + ret = -EINVAL; + goto out; + } + idle = idle_thread_get(cpu); if (IS_ERR(idle)) { ret = PTR_ERR(idle); -- cgit v1.2.3 From 0a290ac4252c85205cb924ff7f6da10cfd20fb01 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Tue, 23 Oct 2012 01:31:14 +0200 Subject: ACPI / x86: Add quirk for "CheckPoint P-20-00" to not use bridge _CRS_ info This is to fix a regression https://bugzilla.kernel.org/show_bug.cgi?id=47981 The CheckPoint P-20-00 works ok before new machines (2008 and later) are forced to use the bridge _CRS info by default in 2.6.34. Add this quirk to restore its old way of working: not using bridge _CRS info. Signed-off-by: Feng Tang Signed-off-by: Rafael J. Wysocki --- arch/x86/pci/acpi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 192397c9860..7010c199b4f 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -98,6 +98,16 @@ static const struct dmi_system_id pci_use_crs_table[] __initconst = { DMI_MATCH(DMI_BIOS_VERSION, "6JET85WW (1.43 )"), }, }, + /* https://bugzilla.kernel.org/show_bug.cgi?id=47981 */ + { + .callback = set_nouse_crs, + .ident = "CheckPoint P-20-00", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "CheckPoint"), + DMI_MATCH(DMI_PRODUCT_NAME, "P-20-00"), + DMI_MATCH(DMI_BOARD_NAME, "Bridgeport"), + }, + }, {} }; -- cgit v1.2.3 From 594df89a59cf2a2afc22fe27f508dd864d1edb5f Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Fri, 26 Oct 2012 13:38:16 +0200 Subject: ACPI: Fix a hard coding style when determining if a device is a container, v3 "ACPI0004","PNP0A05" and "PNP0A06" are all defined in array container_device_ids[], so use it, but not the hard coding style. Also, introduce a new API is_container_device() to determine if a device is a container device. Signed-off-by: Tang Chen Signed-off-by: Yasuaki Ishimatsu Reviewed-by: Bjorn Helgaas Signed-off-by: Rafael J. Wysocki --- drivers/acpi/container.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 1f9f7d7d7bc..69e2d6be910 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -92,6 +92,19 @@ static int is_device_present(acpi_handle handle) return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT); } +static bool is_container_device(const char *hid) +{ + const struct acpi_device_id *container_id; + + for (container_id = container_device_ids; + container_id->id[0]; container_id++) { + if (!strcmp((char *)container_id->id, hid)) + return true; + } + + return false; +} + /*******************************************************************/ static int acpi_container_add(struct acpi_device *device) { @@ -232,10 +245,8 @@ container_walk_namespace_cb(acpi_handle handle, goto end; } - if (strcmp(hid, "ACPI0004") && strcmp(hid, "PNP0A05") && - strcmp(hid, "PNP0A06")) { + if (!is_container_device(hid)) goto end; - } switch (*action) { case INSTALL_NOTIFY_HANDLER: -- cgit v1.2.3 From b3c450c38075f414077e58439cff6bdce9e47df8 Mon Sep 17 00:00:00 2001 From: Toshi Kani Date: Fri, 26 Oct 2012 13:38:57 +0200 Subject: ACPI: Fix stale pointer access to flags.lockable During hot-remove, acpi_bus_hot_remove_device() calls ACPI _LCK method when device->flags.lockable is set. However, this device pointer is stale since the target acpi_device object has been already kfree'd by acpi_bus_trim(). The flags.lockable indicates whether or not this ACPI object implements _LCK method. Fix the stable pointer access by replacing it with acpi_get_handle() to check if _LCK is implemented. Signed-off-by: Toshi Kani Reviewed-by: Yasuaki Ishimatsu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 1fcb8678665..ed87f433cec 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -97,6 +97,7 @@ void acpi_bus_hot_remove_device(void *context) struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context; struct acpi_device *device; acpi_handle handle = ej_event->handle; + acpi_handle temp; struct acpi_object_list arg_list; union acpi_object arg; acpi_status status = AE_OK; @@ -117,13 +118,16 @@ void acpi_bus_hot_remove_device(void *context) goto err_out; } + /* device has been freed */ + device = NULL; + /* power off device */ status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) printk(KERN_WARNING PREFIX "Power-off device failed\n"); - if (device->flags.lockable) { + if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) { arg_list.count = 1; arg_list.pointer = &arg; arg.type = ACPI_TYPE_INTEGER; -- cgit v1.2.3 From f4fa0e018a175ea92a3187ade8f678599dc5980a Mon Sep 17 00:00:00 2001 From: Toshi Kani Date: Fri, 26 Oct 2012 13:39:06 +0200 Subject: ACPI: Remove unused lockable in acpi_device_flags Removed lockable in struct acpi_device_flags since it is no longer used by any code. acpi_bus_hot_remove_device() cannot use this flag because acpi_bus_trim() frees up its acpi_device object. Furthermore, the dock driver calls _LCK method without using this lockable flag. Signed-off-by: Toshi Kani Reviewed-by: Yasuaki Ishimatsu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 5 ----- include/acpi/acpi_bus.h | 3 +-- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ed87f433cec..19d3d4a1274 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1017,11 +1017,6 @@ static int acpi_bus_get_flags(struct acpi_device *device) device->flags.ejectable = 1; } - /* Presence of _LCK indicates 'lockable' */ - status = acpi_get_handle(device->handle, "_LCK", &temp); - if (ACPI_SUCCESS(status)) - device->flags.lockable = 1; - /* Power resources cannot be power manageable. */ if (device->device_type == ACPI_BUS_TYPE_POWER) return 0; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 0daa0fbd865..e8b2877aea3 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -144,12 +144,11 @@ struct acpi_device_flags { u32 bus_address:1; u32 removable:1; u32 ejectable:1; - u32 lockable:1; u32 suprise_removal_ok:1; u32 power_manageable:1; u32 performance_manageable:1; u32 eject_pending:1; - u32 reserved:23; + u32 reserved:24; }; /* File System */ -- cgit v1.2.3 From 1bad2f19f7f79d1ec9e6c48168fd7ce8dc1c305f Mon Sep 17 00:00:00 2001 From: Kristen Carlson Accardi Date: Fri, 26 Oct 2012 13:39:15 +0200 Subject: ACPI / Sleep: add acpi_sleep=nonvs_s3 parameter The ACPI specificiation would like us to save NVS at hibernation time, but makes no mention of saving NVS over S3. Not all versions of Windows do this either, and it is clear that not all machines need NVS saved/restored over S3. Allow the user to improve their suspend/resume time by disabling the NVS save/restore at S3 time, but continue to do the NVS save/restore for S4 as specified. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Rafael J. Wysocki --- arch/x86/kernel/acpi/sleep.c | 2 ++ drivers/acpi/sleep.c | 17 ++++++++++++++++- include/linux/acpi.h | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 11676cf65ae..d5e0d717005 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -101,6 +101,8 @@ static int __init acpi_sleep_setup(char *str) #endif if (strncmp(str, "nonvs", 5) == 0) acpi_nvs_nosave(); + if (strncmp(str, "nonvs_s3", 8) == 0) + acpi_nvs_nosave_s3(); if (strncmp(str, "old_ordering", 12) == 0) acpi_old_suspend_ordering(); str = strchr(str, ','); diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index fdcdbb65291..8640782944c 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -97,6 +97,21 @@ void __init acpi_nvs_nosave(void) nvs_nosave = true; } +/* + * The ACPI specification wants us to save NVS memory regions during hibernation + * but says nothing about saving NVS during S3. Not all versions of Windows + * save NVS on S3 suspend either, and it is clear that not all systems need + * NVS to be saved at S3 time. To improve suspend/resume time, allow the + * user to disable saving NVS on S3 if their system does not require it, but + * continue to save/restore NVS for S4 as specified. + */ +static bool nvs_nosave_s3; + +void __init acpi_nvs_nosave_s3(void) +{ + nvs_nosave_s3 = true; +} + /* * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the * user to request that behavior by using the 'acpi_old_suspend_ordering' @@ -243,7 +258,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state) u32 acpi_state = acpi_suspend_states[pm_state]; int error = 0; - error = nvs_nosave ? 0 : suspend_nvs_alloc(); + error = (nvs_nosave || nvs_nosave_s3) ? 0 : suspend_nvs_alloc(); if (error) return error; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 90be9898110..3cf93491125 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -261,6 +261,7 @@ int acpi_resources_are_enforced(void); void __init acpi_no_s4_hw_signature(void); void __init acpi_old_suspend_ordering(void); void __init acpi_nvs_nosave(void); +void __init acpi_nvs_nosave_s3(void); #endif /* CONFIG_PM_SLEEP */ struct acpi_osc_context { -- cgit v1.2.3 From 9743fdea9f9473cd2440741342a5ed8e19eb51bd Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Fri, 26 Oct 2012 13:39:24 +0200 Subject: ACPI: move acpi_no_s4_hw_signature() declaration into #ifdef CONFIG_HIBERNATION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit acpi_no_s4_hw_signature is defined in #ifdef CONFIG_HIBERNATION block, but the current code put the declaration in #ifdef CONFIG_PM_SLEEP block. I happened to meet this issue when I turned off PM_SLEEP config manually: arch/x86/kernel/acpi/sleep.c:100:4: error: implicit declaration of function ‘acpi_no_s4_hw_signature’ [-Werror=implicit-function-declaration] Signed-off-by: Yuanhan Liu Reviewed-by: Fengguang Wu Signed-off-by: Rafael J. Wysocki --- include/linux/acpi.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 3cf93491125..87edfcc0ab6 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -257,8 +257,11 @@ int acpi_check_region(resource_size_t start, resource_size_t n, int acpi_resources_are_enforced(void); -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_HIBERNATION void __init acpi_no_s4_hw_signature(void); +#endif + +#ifdef CONFIG_PM_SLEEP void __init acpi_old_suspend_ordering(void); void __init acpi_nvs_nosave(void); void __init acpi_nvs_nosave_s3(void); -- cgit v1.2.3 From ccf78040265bfce2aac5766e1ddf4fc3dde36899 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 30 Oct 2012 14:41:07 +0100 Subject: ACPI: Add _UID support for ACPI devices. The _UID object is optional, but is required when the device has no other way to report a persistent unique device ID. This patch is required for ACPI 5.0 ACPI enumerated IP cores. Signed-off-by: Lv Zheng Signed-off-by: Rui Zhang Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 19d3d4a1274..daa88d527e8 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -381,6 +381,7 @@ static void acpi_device_release(struct device *dev) struct acpi_device *acpi_dev = to_acpi_device(dev); acpi_free_ids(acpi_dev); + kfree(acpi_dev->pnp.unique_id); kfree(acpi_dev); } @@ -1211,6 +1212,9 @@ static void acpi_device_set_id(struct acpi_device *device) device->pnp.bus_address = info->address; device->flags.bus_address = 1; } + if (info->valid & ACPI_VALID_UID) + device->pnp.unique_id = kstrdup(info->unique_id.string, + GFP_KERNEL); kfree(info); -- cgit v1.2.3 From 923d4a45a9d2e350c27b7b7e1c724c19eb921c92 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Tue, 30 Oct 2012 14:43:26 +0100 Subject: ACPI: Add user space interface for identification objects ACPI devices are glued with physical devices through _ADR object, ACPI enumerated devices are identified with _UID object. Currently we can observe _HID/_CID through sysfs interfaces (hid/modalias), but there's no way for us to check _ADR/_UID from user space. This patch closes this gap for ACPI developers and users. [rjw: Modified the subject and changelog slightly.] Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index daa88d527e8..86bfa690bc6 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -220,6 +220,25 @@ acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *bu } static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); +static ssize_t acpi_device_uid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct acpi_device *acpi_dev = to_acpi_device(dev); + + return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id); +} +static DEVICE_ATTR(uid, 0444, acpi_device_uid_show, NULL); + +static ssize_t acpi_device_adr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct acpi_device *acpi_dev = to_acpi_device(dev); + + return sprintf(buf, "0x%08x\n", + (unsigned int)(acpi_dev->pnp.bus_address)); +} +static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL); + static ssize_t acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); @@ -304,6 +323,11 @@ static int acpi_device_setup_files(struct acpi_device *dev) goto end; } + if (dev->flags.bus_address) + result = device_create_file(&dev->dev, &dev_attr_adr); + if (dev->pnp.unique_id) + result = device_create_file(&dev->dev, &dev_attr_uid); + /* * If device has _EJ0, 'eject' file is created that is used to trigger * hot-removal function from userland. @@ -335,6 +359,10 @@ static void acpi_device_remove_files(struct acpi_device *dev) if (ACPI_SUCCESS(status)) device_remove_file(&dev->dev, &dev_attr_eject); + if (dev->pnp.unique_id) + device_remove_file(&dev->dev, &dev_attr_uid); + if (dev->flags.bus_address) + device_remove_file(&dev->dev, &dev_attr_adr); device_remove_file(&dev->dev, &dev_attr_modalias); device_remove_file(&dev->dev, &dev_attr_hid); if (dev->handle) -- cgit v1.2.3 From 61622accd05b158d05f967b627e72da23d64f2ed Mon Sep 17 00:00:00 2001 From: Toshi Kani Date: Thu, 1 Nov 2012 14:42:12 +0000 Subject: ACPI: Export functions for hot-remove Exported acpi_os_hotplug_execute() and acpi_bus_hot_remove_device() so that they can be called from modules for hot-remove operations. Signed-off-by: Toshi Kani Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 1 + drivers/acpi/scan.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 9eaf708f588..7dfe91d0173 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -986,6 +986,7 @@ acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function, { return __acpi_os_execute(0, function, context, 1); } +EXPORT_SYMBOL(acpi_os_hotplug_execute); void acpi_os_wait_events_complete(void) { diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 86bfa690bc6..9d43532d69b 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -161,6 +161,7 @@ err_out: kfree(context); return; } +EXPORT_SYMBOL(acpi_bus_hot_remove_device); static ssize_t acpi_eject_store(struct device *d, struct device_attribute *attr, -- cgit v1.2.3 From c5b18e22e74dc7dbd3f7729997a3a553ce761d2b Mon Sep 17 00:00:00 2001 From: Toshi Kani Date: Thu, 1 Nov 2012 14:42:13 +0000 Subject: ACPI: Add ACPI CPU hot-remove support Added support of CPU hot-remove via an ACPI eject notification. It calls acpi_bus_hot_remove_device(), which shares the same code path with the sysfs eject operation. acpi_os_hotplug_execute() runs the hot-remove operation in kacpi_hotplug_wq and serializes it between ACPI hot-remove and sysfs eject requests. Signed-off-by: Toshi Kani Reviewed-by: Yasuaki Ishimatsu Tested-by: IgorMammedov Tested-by: Vijay Mohan Pandarathil Tested-by: Prarit Bhargava Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_driver.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index a4352b88a33..8cc33d0e5d8 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -695,8 +695,8 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) static void acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data) { - struct acpi_processor *pr; struct acpi_device *device = NULL; + struct acpi_eject_event *ej_event = NULL; u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ int result; @@ -728,20 +728,27 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, "received ACPI_NOTIFY_EJECT_REQUEST\n")); if (acpi_bus_get_device(handle, &device)) { - printk(KERN_ERR PREFIX - "Device don't exist, dropping EJECT\n"); + pr_err(PREFIX "Device don't exist, dropping EJECT\n"); break; } - pr = acpi_driver_data(device); - if (!pr) { - printk(KERN_ERR PREFIX - "Driver data is NULL, dropping EJECT\n"); + if (!acpi_driver_data(device)) { + pr_err(PREFIX "Driver data is NULL, dropping EJECT\n"); break; } - /* REVISIT: update when eject is supported */ - ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; - break; + ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); + if (!ej_event) { + pr_err(PREFIX "No memory, dropping EJECT\n"); + break; + } + + ej_event->handle = handle; + ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; + acpi_os_hotplug_execute(acpi_bus_hot_remove_device, + (void *)ej_event); + + /* eject is performed asynchronously */ + return; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, -- cgit v1.2.3 From 3ae45a27df74358b4bcd3d5a67e47ad734a48945 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 2 Nov 2012 13:09:08 +0100 Subject: ACPI: Make seemingly useless check in osl.c more understandable There is a seemingly useless check in drivers/acpi/osl.c added by commit bc73675 (ACPI: fixes a false alarm from lockdep), which really is necessary to avoid false positive lockdep complaints. Document this and rearrange the code related to it so that it makes fewer checks. Signed-off-by: Rafael J. Wysocki Acked-by: Yinghai Lu --- drivers/acpi/osl.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 7dfe91d0173..6dc4a2b1e95 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -932,7 +932,7 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, * having a static work_struct. */ - dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC); + dpc = kzalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC); if (!dpc) return AE_NO_MEMORY; @@ -944,17 +944,22 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, * because the hotplug code may call driver .remove() functions, * which invoke flush_scheduled_work/acpi_os_wait_events_complete * to flush these workqueues. + * + * To prevent lockdep from complaining unnecessarily, make sure that + * there is a different static lockdep key for each workqueue by using + * INIT_WORK() for each of them separately. */ - queue = hp ? kacpi_hotplug_wq : - (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); - dpc->wait = hp ? 1 : 0; - - if (queue == kacpi_hotplug_wq) + if (hp) { + queue = kacpi_hotplug_wq; + dpc->wait = 1; INIT_WORK(&dpc->work, acpi_os_execute_deferred); - else if (queue == kacpi_notify_wq) + } else if (type == OSL_NOTIFY_HANDLER) { + queue = kacpi_notify_wq; INIT_WORK(&dpc->work, acpi_os_execute_deferred); - else + } else { + queue = kacpid_wq; INIT_WORK(&dpc->work, acpi_os_execute_deferred); + } /* * On some machines, a software-initiated SMI causes corruption unless -- cgit v1.2.3 From acacb5f211e99fa2c98cf4ef4c632ab43724adb6 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 29 Oct 2012 17:25:19 +0000 Subject: ACPI: add newline in power.c message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add newline to printk so that the message is on a line by itself and not merged with something unrelated to it. Reported-by: Toralf Förster Signed-off-by: Randy Dunlap Signed-off-by: Rafael J. Wysocki --- drivers/acpi/power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 40e38a06ba8..7db61b8fa11 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -473,7 +473,7 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle) return ret; no_power_resource: - printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!"); + printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!\n"); return -ENODEV; } EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); -- cgit v1.2.3 From 54c4c7db6cb94d7d1217df6d7fca6847c61744ab Mon Sep 17 00:00:00 2001 From: Wen Congyang Date: Thu, 15 Nov 2012 00:22:27 +0100 Subject: ACPI / memory-hotplug: call acpi_bus_trim() to remove memory device The memory device has been ejected and powoffed, so we can call acpi_bus_trim() to remove the memory device from acpi bus. Signed-off-by: Wen Congyang Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_memhotplug.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 24c807f9663..1e90e8f0100 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -401,8 +401,9 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) } /* - * TBD: Invoke acpi_bus_remove to cleanup data structures + * Invoke acpi_bus_trim() to remove memory device */ + acpi_bus_trim(device, 1); /* _EJ0 succeeded; _OST is not necessary */ return; -- cgit v1.2.3 From 06f64c8f239a47b359c60301914c783b56b32c13 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Wed, 31 Oct 2012 22:44:33 +0100 Subject: driver core / ACPI: Move ACPI support to core device and driver types With ACPI 5 we are starting to see devices that don't natively support discovery but can be enumerated with the help of the ACPI namespace. Typically, these devices can be represented in the Linux device driver model as platform devices or some serial bus devices, like SPI or I2C devices. Since we want to re-use existing drivers for those devices, we need a way for drivers to specify the ACPI IDs of supported devices, so that they can be matched against device nodes in the ACPI namespace. To this end, it is sufficient to add a pointer to an array of supported ACPI device IDs, that can be provided by the driver, to struct device. Moreover, things like ACPI power management need to have access to the ACPI handle of each supported device, because that handle is used to invoke AML methods associated with the corresponding ACPI device node. The ACPI handles of devices are now stored in the archdata member structure of struct device whose definition depends on the architecture and includes the ACPI handle only on x86 and ia64. Since the pointer to an array of supported ACPI IDs is added to struct device_driver in an architecture-independent way, it is logical to move the ACPI handle from archdata to struct device itself at the same time. This also makes code more straightforward in some places and follows the example of Device Trees that have a poiter to struct device_node in there too. This changeset is based on Mika Westerberg's work. Signed-off-by: Mika Westerberg Acked-by: Greg Kroah-Hartman Acked-by: H. Peter Anvin Acked-by: Tony Luck Signed-off-by: Rafael J. Wysocki --- arch/ia64/include/asm/device.h | 3 --- arch/x86/include/asm/device.h | 3 --- drivers/acpi/glue.c | 14 ++++++-------- include/acpi/acpi_bus.h | 2 +- include/linux/device.h | 4 ++++ 5 files changed, 11 insertions(+), 15 deletions(-) diff --git a/arch/ia64/include/asm/device.h b/arch/ia64/include/asm/device.h index d05e78f6db9..f69c32ffbe6 100644 --- a/arch/ia64/include/asm/device.h +++ b/arch/ia64/include/asm/device.h @@ -7,9 +7,6 @@ #define _ASM_IA64_DEVICE_H struct dev_archdata { -#ifdef CONFIG_ACPI - void *acpi_handle; -#endif #ifdef CONFIG_INTEL_IOMMU void *iommu; /* hook for IOMMU specific extension */ #endif diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h index 93e1c55f14a..03dd72957d2 100644 --- a/arch/x86/include/asm/device.h +++ b/arch/x86/include/asm/device.h @@ -2,9 +2,6 @@ #define _ASM_X86_DEVICE_H struct dev_archdata { -#ifdef CONFIG_ACPI - void *acpi_handle; -#endif #ifdef CONFIG_X86_DEV_DMA_OPS struct dma_map_ops *dma_ops; #endif diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 08373086cd7..2f3849aedc9 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -134,7 +134,7 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2]; int retval = -EINVAL; - if (dev->archdata.acpi_handle) { + if (dev->acpi_handle) { dev_warn(dev, "Drivers changed 'acpi_handle'\n"); return -EINVAL; } @@ -169,7 +169,7 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) acpi_dev->physical_node_count++; mutex_unlock(&acpi_dev->physical_node_lock); - dev->archdata.acpi_handle = handle; + dev->acpi_handle = handle; if (!physical_node->node_id) strcpy(physical_node_name, PHYSICAL_NODE_STRING); @@ -198,11 +198,10 @@ static int acpi_unbind_one(struct device *dev) acpi_status status; struct list_head *node, *next; - if (!dev->archdata.acpi_handle) + if (!dev->acpi_handle) return 0; - status = acpi_bus_get_device(dev->archdata.acpi_handle, - &acpi_dev); + status = acpi_bus_get_device(dev->acpi_handle, &acpi_dev); if (ACPI_FAILURE(status)) goto err; @@ -228,7 +227,7 @@ static int acpi_unbind_one(struct device *dev) sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name); sysfs_remove_link(&dev->kobj, "firmware_node"); - dev->archdata.acpi_handle = NULL; + dev->acpi_handle = NULL; /* acpi_bind_one increase refcnt by one */ put_device(dev); kfree(entry); @@ -269,8 +268,7 @@ static int acpi_platform_notify(struct device *dev) if (!ret) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - acpi_get_name(dev->archdata.acpi_handle, - ACPI_FULL_PATHNAME, &buffer); + acpi_get_name(dev->acpi_handle, ACPI_FULL_PATHNAME, &buffer); DBG("Device %s -> %s\n", dev_name(dev), (char *)buffer.pointer); kfree(buffer.pointer); } else diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 0daa0fbd865..bb1537c5e67 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -410,7 +410,7 @@ acpi_handle acpi_get_child(acpi_handle, u64); int acpi_is_root_bridge(acpi_handle); acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); -#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle)) +#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->acpi_handle)) int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state); int acpi_disable_wakeup_device_power(struct acpi_device *dev); diff --git a/include/linux/device.h b/include/linux/device.h index 86ef6ab553b..cc3aee57a46 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -190,6 +190,7 @@ extern struct klist *bus_get_device_klist(struct bus_type *bus); * @mod_name: Used for built-in modules. * @suppress_bind_attrs: Disables bind/unbind via sysfs. * @of_match_table: The open firmware table. + * @acpi_match_table: The ACPI match table. * @probe: Called to query the existence of a specific device, * whether this driver can work with it, and bind the driver * to a specific device. @@ -223,6 +224,7 @@ struct device_driver { bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ const struct of_device_id *of_match_table; + const struct acpi_device_id *acpi_match_table; int (*probe) (struct device *dev); int (*remove) (struct device *dev); @@ -616,6 +618,7 @@ struct device_dma_parameters { * @dma_mem: Internal for coherent mem override. * @archdata: For arch-specific additions. * @of_node: Associated device tree node. + * @acpi_handle: Associated ACPI device node's namespace handle. * @devt: For creating the sysfs "dev". * @id: device instance * @devres_lock: Spinlock to protect the resource of the device. @@ -680,6 +683,7 @@ struct device { struct dev_archdata archdata; struct device_node *of_node; /* associated device tree node */ + void *acpi_handle; /* associated ACPI device node */ dev_t devt; /* dev_t, creates the sysfs "dev" */ u32 id; /* device instance */ -- cgit v1.2.3 From cf761af9ee0f2c172710ad2b7ca029016b5d4c45 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Wed, 31 Oct 2012 22:44:41 +0100 Subject: ACPI: Provide generic functions for matching ACPI device nodes Introduce function acpi_match_device() allowing callers to match struct device objects with populated acpi_handle fields against arrays of ACPI device IDs. Also introduce function acpi_driver_match_device() using acpi_match_device() internally and allowing callers to match a struct device object against an array of ACPI device IDs provided by a device driver. Additionally, introduce macro ACPI_PTR() that may be used by device drivers to escape pointers to data structures whose definitions depend on CONFIG_ACPI. Signed-off-by: Mika Westerberg Acked-by: Greg Kroah-Hartman Acked-by: H. Peter Anvin Acked-by: Tony Luck Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 40 +++++++++++++++++++++++++++++++++++----- include/linux/acpi.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 1fcb8678665..a0dfdffe54d 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -340,8 +340,8 @@ static void acpi_device_remove_files(struct acpi_device *dev) ACPI Bus operations -------------------------------------------------------------------------- */ -int acpi_match_device_ids(struct acpi_device *device, - const struct acpi_device_id *ids) +static const struct acpi_device_id *__acpi_match_device( + struct acpi_device *device, const struct acpi_device_id *ids) { const struct acpi_device_id *id; struct acpi_hardware_id *hwid; @@ -351,14 +351,44 @@ int acpi_match_device_ids(struct acpi_device *device, * driver for it. */ if (!device->status.present) - return -ENODEV; + return NULL; for (id = ids; id->id[0]; id++) list_for_each_entry(hwid, &device->pnp.ids, list) if (!strcmp((char *) id->id, hwid->id)) - return 0; + return id; + + return NULL; +} - return -ENOENT; +/** + * acpi_match_device - Match a struct device against a given list of ACPI IDs + * @ids: Array of struct acpi_device_id object to match against. + * @dev: The device structure to match. + * + * Check if @dev has a valid ACPI handle and if there is a struct acpi_device + * object for that handle and use that object to match against a given list of + * device IDs. + * + * Return a pointer to the first matching ID on success or %NULL on failure. + */ +const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, + const struct device *dev) +{ + struct acpi_device *adev; + + if (!ids || !dev->acpi_handle + || ACPI_FAILURE(acpi_bus_get_device(dev->acpi_handle, &adev))) + return NULL; + + return __acpi_match_device(adev, ids); +} +EXPORT_SYMBOL_GPL(acpi_match_device); + +int acpi_match_device_ids(struct acpi_device *device, + const struct acpi_device_id *ids) +{ + return __acpi_match_device(device, ids) ? 0 : -ENOENT; } EXPORT_SYMBOL(acpi_match_device_ids); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 90be9898110..48761cb481d 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -26,6 +26,7 @@ #define _LINUX_ACPI_H #include /* for struct resource */ +#include #ifdef CONFIG_ACPI @@ -364,6 +365,17 @@ extern int acpi_nvs_register(__u64 start, __u64 size); extern int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *), void *data); +const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, + const struct device *dev); + +static inline bool acpi_driver_match_device(struct device *dev, + const struct device_driver *drv) +{ + return !!acpi_match_device(drv->acpi_match_table, dev); +} + +#define ACPI_PTR(_ptr) (_ptr) + #else /* !CONFIG_ACPI */ #define acpi_disabled 1 @@ -418,6 +430,22 @@ static inline int acpi_nvs_for_each_region(int (*func)(__u64, __u64, void *), return 0; } +struct acpi_device_id; + +static inline const struct acpi_device_id *acpi_match_device( + const struct acpi_device_id *ids, const struct device *dev) +{ + return NULL; +} + +static inline bool acpi_driver_match_device(struct device *dev, + const struct device_driver *drv) +{ + return false; +} + +#define ACPI_PTR(_ptr) (NULL) + #endif /* !CONFIG_ACPI */ #ifdef CONFIG_ACPI -- cgit v1.2.3 From 35e92b78c1d327b1624e94d1c9c65ea7065d6b95 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 31 Oct 2012 22:44:48 +0100 Subject: ACPI / x86: Export acpi_[un]register_gsi() These functions might be called from modules as well so make sure they are exported. In addition, implement empty version of acpi_unregister_gsi() and remove the one from pci_irq.c. Signed-off-by: Andy Shevchenko Signed-off-by: Mika Westerberg Acked-by: Greg Kroah-Hartman Acked-by: H. Peter Anvin Acked-by: Tony Luck Signed-off-by: Rafael J. Wysocki --- arch/x86/kernel/acpi/boot.c | 6 ++++++ drivers/acpi/pci_irq.c | 5 ----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index e651f7a589a..e48cafcf92a 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -574,6 +574,12 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity) return irq; } +EXPORT_SYMBOL_GPL(acpi_register_gsi); + +void acpi_unregister_gsi(u32 gsi) +{ +} +EXPORT_SYMBOL_GPL(acpi_unregister_gsi); void __init acpi_set_irq_model_pic(void) { diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 0eefa12e648..1be25a590dc 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -495,11 +495,6 @@ int acpi_pci_irq_enable(struct pci_dev *dev) return 0; } -/* FIXME: implement x86/x86_64 version */ -void __attribute__ ((weak)) acpi_unregister_gsi(u32 i) -{ -} - void acpi_pci_irq_disable(struct pci_dev *dev) { struct acpi_prt_entry *entry; -- cgit v1.2.3 From a42b9bfe959519772fd8d97557c760f7cda4d325 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Wed, 31 Oct 2012 22:44:55 +0100 Subject: ACPI / ia64: Export acpi_[un]register_gsi() These functions might be called from modules as well so make sure they are exported. Signed-off-by: Mika Westerberg Acked-by: Greg Kroah-Hartman Acked-by: H. Peter Anvin Acked-by: Tony Luck Signed-off-by: Rafael J. Wysocki --- arch/ia64/kernel/acpi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 440578850ae..e9682f5be34 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -633,6 +633,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int triggering, int polarity) ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); } +EXPORT_SYMBOL_GPL(acpi_register_gsi); void acpi_unregister_gsi(u32 gsi) { @@ -644,6 +645,7 @@ void acpi_unregister_gsi(u32 gsi) iosapic_unregister_intr(gsi); } +EXPORT_SYMBOL_GPL(acpi_unregister_gsi); static int __init acpi_parse_fadt(struct acpi_table_header *table) { -- cgit v1.2.3 From 91e5687805885f9fceb60b95e950a3d3bdcf4764 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Wed, 31 Oct 2012 22:45:02 +0100 Subject: ACPI: Add support for platform bus type With ACPI 5 it is now possible to enumerate traditional SoC peripherals, like serial bus controllers and slave devices behind them. These devices are typically based on IP-blocks used in many existing SoC platforms and platform drivers for them may already be present in the kernel tree. To make driver "porting" more straightforward, add ACPI support to the platform bus type. Instead of writing ACPI "glue" drivers for the existing platform drivers, register the platform bus type with ACPI to create platform device objects for the drivers and bind the corresponding ACPI handles to those platform devices. This should allow us to reuse the existing platform drivers for the devices in question with the minimum amount of modifications. This changeset is based on Mika Westerberg's and Mathias Nyman's work. Signed-off-by: Mathias Nyman Signed-off-by: Mika Westerberg Acked-by: Greg Kroah-Hartman Acked-by: H. Peter Anvin Acked-by: Tony Luck Signed-off-by: Rafael J. Wysocki --- drivers/acpi/Makefile | 1 + drivers/acpi/acpi_platform.c | 285 +++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/internal.h | 7 ++ drivers/acpi/scan.c | 16 ++- drivers/base/platform.c | 5 + 5 files changed, 313 insertions(+), 1 deletion(-) create mode 100644 drivers/acpi/acpi_platform.c diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 82422fe90f8..227c82bbe9a 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -36,6 +36,7 @@ acpi-y += processor_core.o acpi-y += ec.o acpi-$(CONFIG_ACPI_DOCK) += dock.o acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o +acpi-y += acpi_platform.o acpi-y += power.o acpi-y += event.o acpi-y += sysfs.o diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c new file mode 100644 index 00000000000..a5a23462287 --- /dev/null +++ b/drivers/acpi/acpi_platform.c @@ -0,0 +1,285 @@ +/* + * ACPI support for platform bus type. + * + * Copyright (C) 2012, Intel Corporation + * Authors: Mika Westerberg + * Mathias Nyman + * Rafael J. Wysocki + * + * 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. + */ + +#include +#include +#include +#include +#include + +ACPI_MODULE_NAME("platform"); + +struct resource_info { + struct device *dev; + struct resource *res; + size_t n, cur; +}; + +static acpi_status acpi_platform_count_resources(struct acpi_resource *res, + void *data) +{ + struct acpi_resource_extended_irq *acpi_xirq; + struct resource_info *ri = data; + + switch (res->type) { + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + case ACPI_RESOURCE_TYPE_IRQ: + ri->n++; + break; + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + acpi_xirq = &res->data.extended_irq; + ri->n += acpi_xirq->interrupt_count; + break; + case ACPI_RESOURCE_TYPE_ADDRESS32: + if (res->data.address32.resource_type == ACPI_IO_RANGE) + ri->n++; + break; + } + + return AE_OK; +} + +static acpi_status acpi_platform_add_resources(struct acpi_resource *res, + void *data) +{ + struct acpi_resource_fixed_memory32 *acpi_mem; + struct acpi_resource_address32 *acpi_add32; + struct acpi_resource_extended_irq *acpi_xirq; + struct acpi_resource_irq *acpi_irq; + struct resource_info *ri = data; + struct resource *r; + int irq, i; + + switch (res->type) { + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + acpi_mem = &res->data.fixed_memory32; + r = &ri->res[ri->cur++]; + + r->start = acpi_mem->address; + r->end = r->start + acpi_mem->address_length - 1; + r->flags = IORESOURCE_MEM; + + dev_dbg(ri->dev, "Memory32Fixed %pR\n", r); + break; + + case ACPI_RESOURCE_TYPE_ADDRESS32: + acpi_add32 = &res->data.address32; + + if (acpi_add32->resource_type == ACPI_IO_RANGE) { + r = &ri->res[ri->cur++]; + r->start = acpi_add32->minimum; + r->end = r->start + acpi_add32->address_length - 1; + r->flags = IORESOURCE_IO; + dev_dbg(ri->dev, "Address32 %pR\n", r); + } + break; + + case ACPI_RESOURCE_TYPE_IRQ: + acpi_irq = &res->data.irq; + r = &ri->res[ri->cur++]; + + irq = acpi_register_gsi(ri->dev, + acpi_irq->interrupts[0], + acpi_irq->triggering, + acpi_irq->polarity); + + r->start = r->end = irq; + r->flags = IORESOURCE_IRQ; + + dev_dbg(ri->dev, "IRQ %pR\n", r); + break; + + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + acpi_xirq = &res->data.extended_irq; + + for (i = 0; i < acpi_xirq->interrupt_count; i++, ri->cur++) { + r = &ri->res[ri->cur]; + irq = acpi_register_gsi(ri->dev, + acpi_xirq->interrupts[i], + acpi_xirq->triggering, + acpi_xirq->polarity); + + r->start = r->end = irq; + r->flags = IORESOURCE_IRQ; + + dev_dbg(ri->dev, "Interrupt %pR\n", r); + } + break; + } + + return AE_OK; +} + +static acpi_status acpi_platform_get_device_uid(struct acpi_device *adev, + int *uid) +{ + struct acpi_device_info *info; + acpi_status status; + + status = acpi_get_object_info(adev->handle, &info); + if (ACPI_FAILURE(status)) + return status; + + status = AE_NOT_EXIST; + if ((info->valid & ACPI_VALID_UID) && + !kstrtoint(info->unique_id.string, 0, uid)) + status = AE_OK; + + kfree(info); + return status; +} + +/** + * acpi_create_platform_device - Create platform device for ACPI device node + * @adev: ACPI device node to create a platform device for. + * + * Check if the given @adev can be represented as a platform device and, if + * that's the case, create and register a platform device, populate its common + * resources and returns a pointer to it. Otherwise, return %NULL. + * + * The platform device's name will be taken from the @adev's _HID and _UID. + */ +struct platform_device *acpi_create_platform_device(struct acpi_device *adev) +{ + struct platform_device *pdev = NULL; + struct acpi_device *acpi_parent; + struct device *parent = NULL; + struct resource_info ri; + acpi_status status; + int devid; + + /* If the ACPI node already has a physical device attached, skip it. */ + if (adev->physical_node_count) + return NULL; + + /* Use the UID of the device as the new platform device id if found. */ + status = acpi_platform_get_device_uid(adev, &devid); + if (ACPI_FAILURE(status)) + devid = -1; + + memset(&ri, 0, sizeof(ri)); + + /* First, count the resources. */ + status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, + acpi_platform_count_resources, &ri); + if (ACPI_FAILURE(status) || !ri.n) + return NULL; + + /* Next, allocate memory for all the resources and populate it. */ + ri.dev = &adev->dev; + ri.res = kzalloc(ri.n * sizeof(struct resource), GFP_KERNEL); + if (!ri.res) { + dev_err(&adev->dev, + "failed to allocate memory for resources\n"); + return NULL; + } + + status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, + acpi_platform_add_resources, &ri); + if (ACPI_FAILURE(status)) { + dev_err(&adev->dev, "failed to walk resources\n"); + goto out; + } + + if (WARN_ON(ri.n != ri.cur)) + goto out; + + /* + * If the ACPI node has a parent and that parent has a physical device + * attached to it, that physical device should be the parent of the + * platform device we are about to create. + */ + acpi_parent = adev->parent; + if (acpi_parent) { + struct acpi_device_physical_node *entry; + struct list_head *list; + + mutex_lock(&acpi_parent->physical_node_lock); + list = &acpi_parent->physical_node_list; + if (!list_empty(list)) { + entry = list_first_entry(list, + struct acpi_device_physical_node, + node); + parent = entry->dev; + } + mutex_unlock(&acpi_parent->physical_node_lock); + } + pdev = platform_device_register_resndata(parent, acpi_device_hid(adev), + devid, ri.res, ri.n, NULL, 0); + if (IS_ERR(pdev)) { + dev_err(&adev->dev, "platform device creation failed: %ld\n", + PTR_ERR(pdev)); + pdev = NULL; + } else { + dev_dbg(&adev->dev, "created platform device %s\n", + dev_name(&pdev->dev)); + } + + out: + kfree(ri.res); + return pdev; +} + +static acpi_status acpi_platform_match(acpi_handle handle, u32 depth, + void *data, void **return_value) +{ + struct platform_device *pdev = data; + struct acpi_device *adev; + acpi_status status; + + status = acpi_bus_get_device(handle, &adev); + if (ACPI_FAILURE(status)) + return status; + + /* Skip ACPI devices that have physical device attached */ + if (adev->physical_node_count) + return AE_OK; + + if (!strcmp(pdev->name, acpi_device_hid(adev))) { + int devid; + + /* Check that both name and UID match if it exists */ + status = acpi_platform_get_device_uid(adev, &devid); + if (ACPI_FAILURE(status)) + devid = -1; + + if (pdev->id != devid) + return AE_OK; + + *(acpi_handle *)return_value = handle; + return AE_CTRL_TERMINATE; + } + + return AE_OK; +} + +static int acpi_platform_find_device(struct device *dev, acpi_handle *handle) +{ + struct platform_device *pdev = to_platform_device(dev); + + *handle = NULL; + acpi_get_devices(pdev->name, acpi_platform_match, pdev, handle); + + return *handle ? 0 : -ENODEV; +} + +static struct acpi_bus_type acpi_platform_bus = { + .bus = &platform_bus_type, + .find_device = acpi_platform_find_device, +}; + +static int __init acpi_platform_init(void) +{ + return register_acpi_bus_type(&acpi_platform_bus); +} +arch_initcall(acpi_platform_init); diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index ca75b9ce048..57d41f6e144 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -93,4 +93,11 @@ static inline int suspend_nvs_save(void) { return 0; } static inline void suspend_nvs_restore(void) {} #endif +/*-------------------------------------------------------------------------- + Platform bus support + -------------------------------------------------------------------------- */ +struct platform_device; + +struct platform_device *acpi_create_platform_device(struct acpi_device *adev); + #endif /* _ACPI_INTERNAL_H_ */ diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index a0dfdffe54d..d842569395a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -29,6 +29,15 @@ extern struct acpi_device *acpi_root; static const char *dummy_hid = "device"; +/* + * The following ACPI IDs are known to be suitable for representing as + * platform devices. + */ +static const struct acpi_device_id acpi_platform_device_ids[] = { + + { } +}; + static LIST_HEAD(acpi_device_list); static LIST_HEAD(acpi_bus_id_list); DEFINE_MUTEX(acpi_device_lock); @@ -1513,8 +1522,13 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, */ device = NULL; acpi_bus_get_device(handle, &device); - if (ops->acpi_op_add && !device) + if (ops->acpi_op_add && !device) { acpi_add_single_object(&device, handle, type, sta, ops); + /* Is the device a known good platform device? */ + if (device + && !acpi_match_device_ids(device, acpi_platform_device_ids)) + acpi_create_platform_device(device); + } if (!device) return AE_CTRL_DEPTH; diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 72c776f2a1f..7de29ebfce7 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "base.h" #include "power/power.h" @@ -709,6 +710,10 @@ static int platform_match(struct device *dev, struct device_driver *drv) if (of_driver_match_device(dev, drv)) return 1; + /* Then try ACPI style match */ + if (acpi_driver_match_device(dev, drv)) + return 1; + /* Then try to match against the id table */ if (pdrv->id_table) return platform_match_id(pdrv->id_table, pdev) != NULL; -- cgit v1.2.3 From b4b6cae2f36d92b31788f10816709d5290a1119a Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Sat, 10 Nov 2012 23:16:02 +0100 Subject: ACPI / platform: use ACPI device name instead of _HID._UID Using _UID makes the ACPI platform bus code depend on BIOS to get it right. If it doesn't we fail to create the platform device as the name should be unique. The ACPI core already makes a unique name when it first creates the ACPI device so we can use that same name as the platform device name instead of trusting that the BIOS sets the _UIDs correctly. Signed-off-by: Mika Westerberg Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_platform.c | 62 ++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 40 deletions(-) diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index a5a23462287..dbb31d61e31 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -120,25 +120,6 @@ static acpi_status acpi_platform_add_resources(struct acpi_resource *res, return AE_OK; } -static acpi_status acpi_platform_get_device_uid(struct acpi_device *adev, - int *uid) -{ - struct acpi_device_info *info; - acpi_status status; - - status = acpi_get_object_info(adev->handle, &info); - if (ACPI_FAILURE(status)) - return status; - - status = AE_NOT_EXIST; - if ((info->valid & ACPI_VALID_UID) && - !kstrtoint(info->unique_id.string, 0, uid)) - status = AE_OK; - - kfree(info); - return status; -} - /** * acpi_create_platform_device - Create platform device for ACPI device node * @adev: ACPI device node to create a platform device for. @@ -156,19 +137,12 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) struct device *parent = NULL; struct resource_info ri; acpi_status status; - int devid; /* If the ACPI node already has a physical device attached, skip it. */ if (adev->physical_node_count) return NULL; - /* Use the UID of the device as the new platform device id if found. */ - status = acpi_platform_get_device_uid(adev, &devid); - if (ACPI_FAILURE(status)) - devid = -1; - memset(&ri, 0, sizeof(ri)); - /* First, count the resources. */ status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, acpi_platform_count_resources, &ri); @@ -214,8 +188,8 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) } mutex_unlock(&acpi_parent->physical_node_lock); } - pdev = platform_device_register_resndata(parent, acpi_device_hid(adev), - devid, ri.res, ri.n, NULL, 0); + pdev = platform_device_register_resndata(parent, dev_name(&adev->dev), + -1, ri.res, ri.n, NULL, 0); if (IS_ERR(pdev)) { dev_err(&adev->dev, "platform device creation failed: %ld\n", PTR_ERR(pdev)); @@ -245,17 +219,7 @@ static acpi_status acpi_platform_match(acpi_handle handle, u32 depth, if (adev->physical_node_count) return AE_OK; - if (!strcmp(pdev->name, acpi_device_hid(adev))) { - int devid; - - /* Check that both name and UID match if it exists */ - status = acpi_platform_get_device_uid(adev, &devid); - if (ACPI_FAILURE(status)) - devid = -1; - - if (pdev->id != devid) - return AE_OK; - + if (!strcmp(dev_name(&pdev->dev), dev_name(&adev->dev))) { *(acpi_handle *)return_value = handle; return AE_CTRL_TERMINATE; } @@ -266,10 +230,28 @@ static acpi_status acpi_platform_match(acpi_handle handle, u32 depth, static int acpi_platform_find_device(struct device *dev, acpi_handle *handle) { struct platform_device *pdev = to_platform_device(dev); + char *name, *tmp, *hid; + + /* + * The platform device is named using the ACPI device name + * _HID:INSTANCE so we strip the INSTANCE out in order to find the + * correct device using its _HID. + */ + name = kstrdup(dev_name(dev), GFP_KERNEL); + if (!name) + return -ENOMEM; + + tmp = name; + hid = strsep(&tmp, ":"); + if (!hid) { + kfree(name); + return -ENODEV; + } *handle = NULL; - acpi_get_devices(pdev->name, acpi_platform_match, pdev, handle); + acpi_get_devices(hid, acpi_platform_match, pdev, handle); + kfree(name); return *handle ? 0 : -ENODEV; } -- cgit v1.2.3 From e1c467e69040c3be68959332959c07fb3d818e87 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Wed, 14 Nov 2012 04:36:53 -0800 Subject: x86, hotplug: Wake up CPU0 via NMI instead of INIT, SIPI, SIPI Instead of waiting for STARTUP after INITs, BSP will execute the BIOS boot-strap code which is not a desired behavior for waking up BSP. To avoid the boot-strap code, wake up CPU0 by NMI instead. This works to wake up soft offlined CPU0 only. If CPU0 is hard offlined (i.e. physically hot removed and then hot added), NMI won't wake it up. We'll change this code in the future to wake up hard offlined CPU0 if real platform and request are available. AP is still waken up as before by INIT, SIPI, SIPI sequence. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352896613-25957-1-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/cpu.h | 1 + arch/x86/kernel/smpboot.c | 111 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 105 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index 4564c8e28a3..a1195726e8c 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -28,6 +28,7 @@ struct x86_cpu { #ifdef CONFIG_HOTPLUG_CPU extern int arch_register_cpu(int num); extern void arch_unregister_cpu(int); +extern void __cpuinit start_cpu0(void); #endif DECLARE_PER_CPU(int, cpu_state); diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index c297907f3c7..ef53e667e05 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -138,15 +138,17 @@ static void __cpuinit smp_callin(void) * we may get here before an INIT-deassert IPI reaches * our local APIC. We have to wait for the IPI or we'll * lock up on an APIC access. + * + * Since CPU0 is not wakened up by INIT, it doesn't wait for the IPI. */ - if (apic->wait_for_init_deassert) + cpuid = smp_processor_id(); + if (apic->wait_for_init_deassert && cpuid != 0) apic->wait_for_init_deassert(&init_deasserted); /* * (This works even if the APIC is not enabled.) */ phys_id = read_apic_id(); - cpuid = smp_processor_id(); if (cpumask_test_cpu(cpuid, cpu_callin_mask)) { panic("%s: phys CPU#%d, CPU#%d already present??\n", __func__, phys_id, cpuid); @@ -228,6 +230,8 @@ static void __cpuinit smp_callin(void) cpumask_set_cpu(cpuid, cpu_callin_mask); } +static int cpu0_logical_apicid; +static int enable_start_cpu0; /* * Activate a secondary processor. */ @@ -243,6 +247,8 @@ notrace static void __cpuinit start_secondary(void *unused) preempt_disable(); smp_callin(); + enable_start_cpu0 = 0; + #ifdef CONFIG_X86_32 /* switch away from the initial page table */ load_cr3(swapper_pg_dir); @@ -492,7 +498,7 @@ void __inquire_remote_apic(int apicid) * won't ... remember to clear down the APIC, etc later. */ int __cpuinit -wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip) +wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip) { unsigned long send_status, accept_status = 0; int maxlvt; @@ -500,7 +506,7 @@ wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip) /* Target chip */ /* Boot on the stack */ /* Kick the second */ - apic_icr_write(APIC_DM_NMI | apic->dest_logical, logical_apicid); + apic_icr_write(APIC_DM_NMI | apic->dest_logical, apicid); pr_debug("Waiting for send to finish...\n"); send_status = safe_apic_wait_icr_idle(); @@ -660,6 +666,63 @@ static void __cpuinit announce_cpu(int cpu, int apicid) node, cpu, apicid); } +static int wakeup_cpu0_nmi(unsigned int cmd, struct pt_regs *regs) +{ + int cpu; + + cpu = smp_processor_id(); + if (cpu == 0 && !cpu_online(cpu) && enable_start_cpu0) + return NMI_HANDLED; + + return NMI_DONE; +} + +/* + * Wake up AP by INIT, INIT, STARTUP sequence. + * + * Instead of waiting for STARTUP after INITs, BSP will execute the BIOS + * boot-strap code which is not a desired behavior for waking up BSP. To + * void the boot-strap code, wake up CPU0 by NMI instead. + * + * This works to wake up soft offlined CPU0 only. If CPU0 is hard offlined + * (i.e. physically hot removed and then hot added), NMI won't wake it up. + * We'll change this code in the future to wake up hard offlined CPU0 if + * real platform and request are available. + */ +static int __cpuinit +wakeup_cpu_via_init_nmi(int cpu, unsigned long start_ip, int apicid, + int *cpu0_nmi_registered) +{ + int id; + int boot_error; + + /* + * Wake up AP by INIT, INIT, STARTUP sequence. + */ + if (cpu) + return wakeup_secondary_cpu_via_init(apicid, start_ip); + + /* + * Wake up BSP by nmi. + * + * Register a NMI handler to help wake up CPU0. + */ + boot_error = register_nmi_handler(NMI_LOCAL, + wakeup_cpu0_nmi, 0, "wake_cpu0"); + + if (!boot_error) { + enable_start_cpu0 = 1; + *cpu0_nmi_registered = 1; + if (apic->dest_logical == APIC_DEST_LOGICAL) + id = cpu0_logical_apicid; + else + id = apicid; + boot_error = wakeup_secondary_cpu_via_nmi(id, start_ip); + } + + return boot_error; +} + /* * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad * (ie clustered apic addressing mode), this is a LOGICAL apic ID. @@ -675,6 +738,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle) unsigned long boot_error = 0; int timeout; + int cpu0_nmi_registered = 0; /* Just in case we booted with a single CPU. */ alternatives_enable_smp(); @@ -722,13 +786,16 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle) } /* - * Kick the secondary CPU. Use the method in the APIC driver - * if it's defined - or use an INIT boot APIC message otherwise: + * Wake up a CPU in difference cases: + * - Use the method in the APIC driver if it's defined + * Otherwise, + * - Use an INIT boot APIC message for APs or NMI for BSP. */ if (apic->wakeup_secondary_cpu) boot_error = apic->wakeup_secondary_cpu(apicid, start_ip); else - boot_error = wakeup_secondary_cpu_via_init(apicid, start_ip); + boot_error = wakeup_cpu_via_init_nmi(cpu, start_ip, apicid, + &cpu0_nmi_registered); if (!boot_error) { /* @@ -793,6 +860,13 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu, struct task_struct *idle) */ smpboot_restore_warm_reset_vector(); } + /* + * Clean up the nmi handler. Do this after the callin and callout sync + * to avoid impact of possible long unregister time. + */ + if (cpu0_nmi_registered) + unregister_nmi_handler(NMI_LOCAL, "wake_cpu0"); + return boot_error; } @@ -1037,6 +1111,11 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) */ setup_local_APIC(); + if (x2apic_mode) + cpu0_logical_apicid = apic_read(APIC_LDR); + else + cpu0_logical_apicid = GET_APIC_LOGICAL_ID(apic_read(APIC_LDR)); + /* * Enable IO APIC before setting up error vector */ @@ -1264,6 +1343,14 @@ void play_dead_common(void) local_irq_disable(); } +static bool wakeup_cpu0(void) +{ + if (smp_processor_id() == 0 && enable_start_cpu0) + return true; + + return false; +} + /* * We need to flush the caches before going to sleep, lest we have * dirty data in our caches when we come back up. @@ -1327,6 +1414,11 @@ static inline void mwait_play_dead(void) __monitor(mwait_ptr, 0, 0); mb(); __mwait(eax, 0); + /* + * If NMI wants to wake up CPU0, start CPU0. + */ + if (wakeup_cpu0()) + start_cpu0(); } } @@ -1337,6 +1429,11 @@ static inline void hlt_play_dead(void) while (1) { native_halt(); + /* + * If NMI wants to wake up CPU0, start CPU0. + */ + if (wakeup_cpu0()) + start_cpu0(); } } -- cgit v1.2.3 From 27fd185f3d9e83c64b7a596881d7751a638c9683 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:47 -0800 Subject: x86, hotplug: During CPU0 online, enable x2apic, set_numa_node. Previously these functions were not run on the BSP (CPU 0, the boot processor) since the boot processor init would only be executed before this functionality was initialized. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-11-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/common.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 7505f7b13e7..ca165ac6793 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -1237,7 +1237,7 @@ void __cpuinit cpu_init(void) oist = &per_cpu(orig_ist, cpu); #ifdef CONFIG_NUMA - if (cpu != 0 && this_cpu_read(numa_node) == 0 && + if (this_cpu_read(numa_node) == 0 && early_cpu_to_node(cpu) != NUMA_NO_NODE) set_numa_node(early_cpu_to_node(cpu)); #endif @@ -1269,8 +1269,7 @@ void __cpuinit cpu_init(void) barrier(); x86_configure_nx(); - if (cpu != 0) - enable_x2apic(); + enable_x2apic(); /* * set up and load the per-CPU TSS -- cgit v1.2.3 From 30242aa6023b71325c6b8addac06faf544a85fd0 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:48 -0800 Subject: x86, hotplug: The first online processor saves the MTRR state Ask the first online CPU to save mtrr instead of asking BSP. BSP could be offline when mtrr_save_state() is called. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-12-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/cpu/mtrr/main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 6b96110bb0c..e4c1a418453 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -695,11 +695,16 @@ void mtrr_ap_init(void) } /** - * Save current fixed-range MTRR state of the BSP + * Save current fixed-range MTRR state of the first cpu in cpu_online_mask. */ void mtrr_save_state(void) { - smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1); + int first_cpu; + + get_online_cpus(); + first_cpu = cpumask_first(cpu_online_mask); + smp_call_function_single(first_cpu, mtrr_save_fixed_ranges, NULL, 1); + put_online_cpus(); } void set_mtrr_aps_delayed_init(void) -- cgit v1.2.3 From 8d966a04107e56993a051cd41ead0b4f23ba2414 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:49 -0800 Subject: x86, hotplug: Handle retrigger irq by the first available CPU The first cpu in irq cfg->domain is likely to be CPU 0 and may not be available when CPU 0 is offline. Instead of using CPU 0 to handle retriggered irq, we use first available CPU which is online and in this irq's domain. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-13-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/apic/io_apic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 1817fa91102..f78fc2b4deb 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2199,9 +2199,11 @@ static int ioapic_retrigger_irq(struct irq_data *data) { struct irq_cfg *cfg = data->chip_data; unsigned long flags; + int cpu; raw_spin_lock_irqsave(&vector_lock, flags); - apic->send_IPI_mask(cpumask_of(cpumask_first(cfg->domain)), cfg->vector); + cpu = cpumask_first_and(cfg->domain, cpu_online_mask); + apic->send_IPI_mask(cpumask_of(cpu), cfg->vector); raw_spin_unlock_irqrestore(&vector_lock, flags); return 1; -- cgit v1.2.3 From 6f5298c2139b06925037490367906f3d73955b86 Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:50 -0800 Subject: x86/i387.c: Initialize thread xstate only on CPU0 only once init_thread_xstate() is only called once to avoid overriding xstate_size during boot time or during CPU hotplug. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-14-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/i387.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 675a0501244..245a71db401 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -175,7 +175,11 @@ void __cpuinit fpu_init(void) cr0 |= X86_CR0_EM; write_cr0(cr0); - if (!smp_processor_id()) + /* + * init_thread_xstate is only called once to avoid overriding + * xstate_size during boot time or during CPU hotplug. + */ + if (xstate_size == 0) init_thread_xstate(); mxcsr_feature_mask_init(); -- cgit v1.2.3 From a71c8bc5dfefbbf80ef90739791554ef7ea4401b Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Tue, 13 Nov 2012 11:32:51 -0800 Subject: x86, topology: Debug CPU0 hotplug CONFIG_DEBUG_HOTPLUG_CPU0 is for debugging the CPU0 hotplug feature. The switch offlines CPU0 as soon as possible and boots userspace up with CPU0 offlined. User can online CPU0 back after boot time. The default value of the switch is off. To debug CPU0 hotplug, you need to enable CPU0 offline/online feature by either turning on CONFIG_BOOTPARAM_HOTPLUG_CPU0 during compilation or giving cpu0_hotplug kernel parameter at boot. It's safe and early place to take down CPU0 after all hotplug notifiers are installed and SMP is booted. Please note that some applications or drivers, e.g. some versions of udevd, during boot time may put CPU0 online again in this CPU0 hotplug debug mode. In this debug mode, setup_local_APIC() may report a warning on max_loops<=0 when CPU0 is onlined back after boot time. This is because pending interrupt in IRR can not move to ISR. The warning is not CPU0 specfic and it can happen on other CPUs as well. It is harmless except the first CPU0 online takes a bit longer time. And so this debug mode is useful to expose this issue. I'll send a seperate patch to fix this generic warning issue. Signed-off-by: Fenghua Yu Link: http://lkml.kernel.org/r/1352835171-3958-15-git-send-email-fenghua.yu@intel.com Signed-off-by: H. Peter Anvin --- arch/x86/Kconfig | 15 ++++++++++++++ arch/x86/include/asm/cpu.h | 3 +++ arch/x86/kernel/topology.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++ arch/x86/power/cpu.c | 38 ++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 036e89ab470..b6cfa5f6252 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1727,6 +1727,21 @@ config BOOTPARAM_HOTPLUG_CPU0 You still can enable the CPU0 hotplug feature at boot by kernel parameter cpu0_hotplug. +config DEBUG_HOTPLUG_CPU0 + def_bool n + prompt "Debug CPU0 hotplug" + depends on HOTPLUG_CPU && EXPERIMENTAL + ---help--- + Enabling this option offlines CPU0 (if CPU0 can be offlined) as + soon as possible and boots up userspace with CPU0 offlined. User + can online CPU0 back after boot time. + + To debug CPU0 hotplug, you need to enable CPU0 offline/online + feature by either turning on CONFIG_BOOTPARAM_HOTPLUG_CPU0 during + compilation or giving cpu0_hotplug kernel parameter at boot. + + If unsure, say N. + config COMPAT_VDSO def_bool y prompt "Compat VDSO support" diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index a1195726e8c..5f9a1243190 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -29,6 +29,9 @@ struct x86_cpu { extern int arch_register_cpu(int num); extern void arch_unregister_cpu(int); extern void __cpuinit start_cpu0(void); +#ifdef CONFIG_DEBUG_HOTPLUG_CPU0 +extern int _debug_hotplug_cpu(int cpu, int action); +#endif #endif DECLARE_PER_CPU(int, cpu_state); diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c index 0e7b4a7a7fb..6e60b5fe224 100644 --- a/arch/x86/kernel/topology.c +++ b/arch/x86/kernel/topology.c @@ -50,6 +50,57 @@ static int __init enable_cpu0_hotplug(char *str) __setup("cpu0_hotplug", enable_cpu0_hotplug); #endif +#ifdef CONFIG_DEBUG_HOTPLUG_CPU0 +/* + * This function offlines a CPU as early as possible and allows userspace to + * boot up without the CPU. The CPU can be onlined back by user after boot. + * + * This is only called for debugging CPU offline/online feature. + */ +int __ref _debug_hotplug_cpu(int cpu, int action) +{ + struct device *dev = get_cpu_device(cpu); + int ret; + + if (!cpu_is_hotpluggable(cpu)) + return -EINVAL; + + cpu_hotplug_driver_lock(); + + switch (action) { + case 0: + ret = cpu_down(cpu); + if (!ret) { + pr_info("CPU %u is now offline\n", cpu); + kobject_uevent(&dev->kobj, KOBJ_OFFLINE); + } else + pr_debug("Can't offline CPU%d.\n", cpu); + break; + case 1: + ret = cpu_up(cpu); + if (!ret) + kobject_uevent(&dev->kobj, KOBJ_ONLINE); + else + pr_debug("Can't online CPU%d.\n", cpu); + break; + default: + ret = -EINVAL; + } + + cpu_hotplug_driver_unlock(); + + return ret; +} + +static int __init debug_hotplug_cpu(void) +{ + _debug_hotplug_cpu(0, 0); + return 0; +} + +late_initcall_sync(debug_hotplug_cpu); +#endif /* CONFIG_DEBUG_HOTPLUG_CPU0 */ + int __ref arch_register_cpu(int num) { struct cpuinfo_x86 *c = &cpu_data(num); diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index adde77588e2..120cee1c3f8 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -21,6 +21,7 @@ #include #include #include /* pcntxt_mask */ +#include #ifdef CONFIG_X86_32 static struct saved_context saved_context; @@ -263,6 +264,43 @@ static int bsp_pm_callback(struct notifier_block *nb, unsigned long action, case PM_HIBERNATION_PREPARE: ret = bsp_check(); break; +#ifdef CONFIG_DEBUG_HOTPLUG_CPU0 + case PM_RESTORE_PREPARE: + /* + * When system resumes from hibernation, online CPU0 because + * 1. it's required for resume and + * 2. the CPU was online before hibernation + */ + if (!cpu_online(0)) + _debug_hotplug_cpu(0, 1); + break; + case PM_POST_RESTORE: + /* + * When a resume really happens, this code won't be called. + * + * This code is called only when user space hibernation software + * prepares for snapshot device during boot time. So we just + * call _debug_hotplug_cpu() to restore to CPU0's state prior to + * preparing the snapshot device. + * + * This works for normal boot case in our CPU0 hotplug debug + * mode, i.e. CPU0 is offline and user mode hibernation + * software initializes during boot time. + * + * If CPU0 is online and user application accesses snapshot + * device after boot time, this will offline CPU0 and user may + * see different CPU0 state before and after accessing + * the snapshot device. But hopefully this is not a case when + * user debugging CPU0 hotplug. Even if users hit this case, + * they can easily online CPU0 back. + * + * To simplify this debug code, we only consider normal boot + * case. Otherwise we need to remember CPU0's state and restore + * to that state and resolve racy conditions etc. + */ + _debug_hotplug_cpu(0, 0); + break; +#endif default: break; } -- cgit v1.2.3 From 046d9ce6820e99087e81511284045eada94950e8 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 15 Nov 2012 00:30:01 +0100 Subject: ACPI: Move device resources interpretation code from PNP to ACPI core Move some code used for parsing ACPI device resources from the PNP subsystem to the ACPI core, so that other bus types (platform, SPI, I2C) can use the same routines for parsing resources in a consistent way, without duplicating code. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg Tested-by: Mika Westerberg --- drivers/acpi/Makefile | 1 + drivers/acpi/resource.c | 393 +++++++++++++++++++++++++++++++++++++++++ drivers/pnp/base.h | 2 + drivers/pnp/pnpacpi/rsparser.c | 296 ++++--------------------------- drivers/pnp/resource.c | 16 ++ include/linux/acpi.h | 10 ++ 6 files changed, 454 insertions(+), 264 deletions(-) create mode 100644 drivers/acpi/resource.c diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 227c82bbe9a..3223edfb23b 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -32,6 +32,7 @@ acpi-$(CONFIG_ACPI_SLEEP) += proc.o # acpi-y += bus.o glue.o acpi-y += scan.o +acpi-y += resource.o acpi-y += processor_core.o acpi-y += ec.o acpi-$(CONFIG_ACPI_DOCK) += dock.o diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c new file mode 100644 index 00000000000..3e7fd349e29 --- /dev/null +++ b/drivers/acpi/resource.c @@ -0,0 +1,393 @@ +/* + * drivers/acpi/resource.c - ACPI device resources interpretation. + * + * Copyright (C) 2012, Intel Corp. + * Author: Rafael J. Wysocki + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include + +#ifdef CONFIG_X86 +#define valid_IRQ(i) (((i) != 0) && ((i) != 2)) +#else +#define valid_IRQ(i) (true) +#endif + +static unsigned long acpi_dev_memresource_flags(u64 len, u8 write_protect, + bool window) +{ + unsigned long flags = IORESOURCE_MEM; + + if (len == 0) + flags |= IORESOURCE_DISABLED; + + if (write_protect == ACPI_READ_WRITE_MEMORY) + flags |= IORESOURCE_MEM_WRITEABLE; + + if (window) + flags |= IORESOURCE_WINDOW; + + return flags; +} + +static void acpi_dev_get_memresource(struct resource *res, u64 start, u64 len, + u8 write_protect) +{ + res->start = start; + res->end = start + len - 1; + res->flags = acpi_dev_memresource_flags(len, write_protect, false); +} + +/** + * acpi_dev_resource_memory - Extract ACPI memory resource information. + * @ares: Input ACPI resource object. + * @res: Output generic resource object. + * + * Check if the given ACPI resource object represents a memory resource and + * if that's the case, use the information in it to populate the generic + * resource object pointed to by @res. + */ +bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res) +{ + struct acpi_resource_memory24 *memory24; + struct acpi_resource_memory32 *memory32; + struct acpi_resource_fixed_memory32 *fixed_memory32; + + switch (ares->type) { + case ACPI_RESOURCE_TYPE_MEMORY24: + memory24 = &ares->data.memory24; + acpi_dev_get_memresource(res, memory24->minimum, + memory24->address_length, + memory24->write_protect); + break; + case ACPI_RESOURCE_TYPE_MEMORY32: + memory32 = &ares->data.memory32; + acpi_dev_get_memresource(res, memory32->minimum, + memory32->address_length, + memory32->write_protect); + break; + case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: + fixed_memory32 = &ares->data.fixed_memory32; + acpi_dev_get_memresource(res, fixed_memory32->address, + fixed_memory32->address_length, + fixed_memory32->write_protect); + break; + default: + return false; + } + return true; +} +EXPORT_SYMBOL_GPL(acpi_dev_resource_memory); + +static unsigned int acpi_dev_ioresource_flags(u64 start, u64 end, u8 io_decode, + bool window) +{ + int flags = IORESOURCE_IO; + + if (io_decode == ACPI_DECODE_16) + flags |= IORESOURCE_IO_16BIT_ADDR; + + if (start > end || end >= 0x10003) + flags |= IORESOURCE_DISABLED; + + if (window) + flags |= IORESOURCE_WINDOW; + + return flags; +} + +static void acpi_dev_get_ioresource(struct resource *res, u64 start, u64 len, + u8 io_decode) +{ + u64 end = start + len - 1; + + res->start = start; + res->end = end; + res->flags = acpi_dev_ioresource_flags(start, end, io_decode, false); +} + +/** + * acpi_dev_resource_io - Extract ACPI I/O resource information. + * @ares: Input ACPI resource object. + * @res: Output generic resource object. + * + * Check if the given ACPI resource object represents an I/O resource and + * if that's the case, use the information in it to populate the generic + * resource object pointed to by @res. + */ +bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res) +{ + struct acpi_resource_io *io; + struct acpi_resource_fixed_io *fixed_io; + + switch (ares->type) { + case ACPI_RESOURCE_TYPE_IO: + io = &ares->data.io; + acpi_dev_get_ioresource(res, io->minimum, + io->address_length, + io->io_decode); + break; + case ACPI_RESOURCE_TYPE_FIXED_IO: + fixed_io = &ares->data.fixed_io; + acpi_dev_get_ioresource(res, fixed_io->address, + fixed_io->address_length, + ACPI_DECODE_10); + break; + default: + return false; + } + return true; +} +EXPORT_SYMBOL_GPL(acpi_dev_resource_io); + +/** + * acpi_dev_resource_address_space - Extract ACPI address space information. + * @ares: Input ACPI resource object. + * @res: Output generic resource object. + * + * Check if the given ACPI resource object represents an address space resource + * and if that's the case, use the information in it to populate the generic + * resource object pointed to by @res. + */ +bool acpi_dev_resource_address_space(struct acpi_resource *ares, + struct resource *res) +{ + acpi_status status; + struct acpi_resource_address64 addr; + bool window; + u64 len; + u8 io_decode; + + switch (ares->type) { + case ACPI_RESOURCE_TYPE_ADDRESS16: + case ACPI_RESOURCE_TYPE_ADDRESS32: + case ACPI_RESOURCE_TYPE_ADDRESS64: + break; + default: + return false; + } + + status = acpi_resource_to_address64(ares, &addr); + if (ACPI_FAILURE(status)) + return true; + + res->start = addr.minimum; + res->end = addr.maximum; + window = addr.producer_consumer == ACPI_PRODUCER; + + switch(addr.resource_type) { + case ACPI_MEMORY_RANGE: + len = addr.maximum - addr.minimum + 1; + res->flags = acpi_dev_memresource_flags(len, + addr.info.mem.write_protect, + window); + break; + case ACPI_IO_RANGE: + io_decode = addr.granularity == 0xfff ? + ACPI_DECODE_10 : ACPI_DECODE_16; + res->flags = acpi_dev_ioresource_flags(addr.minimum, + addr.maximum, + io_decode, window); + break; + case ACPI_BUS_NUMBER_RANGE: + res->flags = IORESOURCE_BUS; + break; + default: + res->flags = 0; + } + + return true; +} +EXPORT_SYMBOL_GPL(acpi_dev_resource_address_space); + +/** + * acpi_dev_resource_ext_address_space - Extract ACPI address space information. + * @ares: Input ACPI resource object. + * @res: Output generic resource object. + * + * Check if the given ACPI resource object represents an extended address space + * resource and if that's the case, use the information in it to populate the + * generic resource object pointed to by @res. + */ +bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, + struct resource *res) +{ + struct acpi_resource_extended_address64 *ext_addr; + bool window; + u64 len; + u8 io_decode; + + if (ares->type != ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64) + return false; + + ext_addr = &ares->data.ext_address64; + + res->start = ext_addr->minimum; + res->end = ext_addr->maximum; + window = ext_addr->producer_consumer == ACPI_PRODUCER; + + switch(ext_addr->resource_type) { + case ACPI_MEMORY_RANGE: + len = ext_addr->maximum - ext_addr->minimum + 1; + res->flags = acpi_dev_memresource_flags(len, + ext_addr->info.mem.write_protect, + window); + break; + case ACPI_IO_RANGE: + io_decode = ext_addr->granularity == 0xfff ? + ACPI_DECODE_10 : ACPI_DECODE_16; + res->flags = acpi_dev_ioresource_flags(ext_addr->minimum, + ext_addr->maximum, + io_decode, window); + break; + case ACPI_BUS_NUMBER_RANGE: + res->flags = IORESOURCE_BUS; + break; + default: + res->flags = 0; + } + + return true; +} +EXPORT_SYMBOL_GPL(acpi_dev_resource_ext_address_space); + +/** + * acpi_dev_irq_flags - Determine IRQ resource flags. + * @triggering: Triggering type as provided by ACPI. + * @polarity: Interrupt polarity as provided by ACPI. + * @shareable: Whether or not the interrupt is shareable. + */ +unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable) +{ + unsigned long flags; + + if (triggering == ACPI_LEVEL_SENSITIVE) + flags = polarity == ACPI_ACTIVE_LOW ? + IORESOURCE_IRQ_LOWLEVEL : IORESOURCE_IRQ_HIGHLEVEL; + else + flags = polarity == ACPI_ACTIVE_LOW ? + IORESOURCE_IRQ_LOWEDGE : IORESOURCE_IRQ_HIGHEDGE; + + if (shareable == ACPI_SHARED) + flags |= IORESOURCE_IRQ_SHAREABLE; + + return flags | IORESOURCE_IRQ; +} +EXPORT_SYMBOL_GPL(acpi_dev_irq_flags); + +static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi) +{ + res->start = gsi; + res->end = gsi; + res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED; +} + +static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, + u8 triggering, u8 polarity, u8 shareable) +{ + int irq, p, t; + + if (!valid_IRQ(gsi)) { + acpi_dev_irqresource_disabled(res, gsi); + return; + } + + /* + * In IO-APIC mode, use overrided attribute. Two reasons: + * 1. BIOS bug in DSDT + * 2. BIOS uses IO-APIC mode Interrupt Source Override + */ + if (!acpi_get_override_irq(gsi, &t, &p)) { + u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; + u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; + + if (triggering != trig || polarity != pol) { + pr_warning("ACPI: IRQ %d override to %s, %s\n", gsi, + t ? "edge" : "level", p ? "low" : "high"); + triggering = trig; + polarity = pol; + } + } + + res->flags = acpi_dev_irq_flags(triggering, polarity, shareable); + irq = acpi_register_gsi(NULL, gsi, triggering, polarity); + if (irq >= 0) { + res->start = irq; + res->end = irq; + } else { + acpi_dev_irqresource_disabled(res, gsi); + } +} + +/** + * acpi_dev_resource_interrupt - Extract ACPI interrupt resource information. + * @ares: Input ACPI resource object. + * @index: Index into the array of GSIs represented by the resource. + * @res: Output generic resource object. + * + * Check if the given ACPI resource object represents an interrupt resource + * and @index does not exceed the resource's interrupt count (true is returned + * in that case regardless of the results of the other checks)). If that's the + * case, register the GSI corresponding to @index from the array of interrupts + * represented by the resource and populate the generic resource object pointed + * to by @res accordingly. If the registration of the GSI is not successful, + * IORESOURCE_DISABLED will be set it that object's flags. + */ +bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, + struct resource *res) +{ + struct acpi_resource_irq *irq; + struct acpi_resource_extended_irq *ext_irq; + + switch (ares->type) { + case ACPI_RESOURCE_TYPE_IRQ: + /* + * Per spec, only one interrupt per descriptor is allowed in + * _CRS, but some firmware violates this, so parse them all. + */ + irq = &ares->data.irq; + if (index >= irq->interrupt_count) { + acpi_dev_irqresource_disabled(res, 0); + return false; + } + acpi_dev_get_irqresource(res, irq->interrupts[index], + irq->triggering, irq->polarity, + irq->sharable); + break; + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + ext_irq = &ares->data.extended_irq; + if (index >= ext_irq->interrupt_count) { + acpi_dev_irqresource_disabled(res, 0); + return false; + } + acpi_dev_get_irqresource(res, ext_irq->interrupts[index], + ext_irq->triggering, ext_irq->polarity, + ext_irq->sharable); + break; + default: + return false; + } + + return true; +} +EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt); diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h index fa4e0a5db3f..ffd53e3eb92 100644 --- a/drivers/pnp/base.h +++ b/drivers/pnp/base.h @@ -159,6 +159,8 @@ struct pnp_resource { void pnp_free_resource(struct pnp_resource *pnp_res); +struct pnp_resource *pnp_add_resource(struct pnp_dev *dev, + struct resource *res); struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, int flags); struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 5be4a392a3a..b8f4ea7b27f 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -28,37 +28,6 @@ #include "../base.h" #include "pnpacpi.h" -#ifdef CONFIG_IA64 -#define valid_IRQ(i) (1) -#else -#define valid_IRQ(i) (((i) != 0) && ((i) != 2)) -#endif - -/* - * Allocated Resources - */ -static int irq_flags(int triggering, int polarity, int shareable) -{ - int flags; - - if (triggering == ACPI_LEVEL_SENSITIVE) { - if (polarity == ACPI_ACTIVE_LOW) - flags = IORESOURCE_IRQ_LOWLEVEL; - else - flags = IORESOURCE_IRQ_HIGHLEVEL; - } else { - if (polarity == ACPI_ACTIVE_LOW) - flags = IORESOURCE_IRQ_LOWEDGE; - else - flags = IORESOURCE_IRQ_HIGHEDGE; - } - - if (shareable == ACPI_SHARED) - flags |= IORESOURCE_IRQ_SHAREABLE; - - return flags; -} - static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering, int *polarity, int *shareable) { @@ -94,45 +63,6 @@ static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering, *shareable = ACPI_EXCLUSIVE; } -static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, - u32 gsi, int triggering, - int polarity, int shareable) -{ - int irq, flags; - int p, t; - - if (!valid_IRQ(gsi)) { - pnp_add_irq_resource(dev, gsi, IORESOURCE_DISABLED); - return; - } - - /* - * in IO-APIC mode, use overrided attribute. Two reasons: - * 1. BIOS bug in DSDT - * 2. BIOS uses IO-APIC mode Interrupt Source Override - */ - if (!acpi_get_override_irq(gsi, &t, &p)) { - t = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; - p = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; - - if (triggering != t || polarity != p) { - dev_warn(&dev->dev, "IRQ %d override to %s, %s\n", - gsi, t ? "edge":"level", p ? "low":"high"); - triggering = t; - polarity = p; - } - } - - flags = irq_flags(triggering, polarity, shareable); - irq = acpi_register_gsi(&dev->dev, gsi, triggering, polarity); - if (irq >= 0) - pcibios_penalize_isa_irq(irq, 1); - else - flags |= IORESOURCE_DISABLED; - - pnp_add_irq_resource(dev, irq, flags); -} - static int dma_flags(struct pnp_dev *dev, int type, int bus_master, int transfer) { @@ -177,21 +107,16 @@ static int dma_flags(struct pnp_dev *dev, int type, int bus_master, return flags; } -static void pnpacpi_parse_allocated_ioresource(struct pnp_dev *dev, u64 start, - u64 len, int io_decode, - int window) -{ - int flags = 0; - u64 end = start + len - 1; +/* + * Allocated Resources + */ - if (io_decode == ACPI_DECODE_16) - flags |= IORESOURCE_IO_16BIT_ADDR; - if (len == 0 || end >= 0x10003) - flags |= IORESOURCE_DISABLED; - if (window) - flags |= IORESOURCE_WINDOW; +static void pnpacpi_add_irqresource(struct pnp_dev *dev, struct resource *r) +{ + if (!(r->flags & IORESOURCE_DISABLED)) + pcibios_penalize_isa_irq(r->start, 1); - pnp_add_io_resource(dev, start, end, flags); + pnp_add_resource(dev, r); } /* @@ -249,130 +174,49 @@ static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev, } } -static void pnpacpi_parse_allocated_memresource(struct pnp_dev *dev, - u64 start, u64 len, - int write_protect, int window) -{ - int flags = 0; - u64 end = start + len - 1; - - if (len == 0) - flags |= IORESOURCE_DISABLED; - if (write_protect == ACPI_READ_WRITE_MEMORY) - flags |= IORESOURCE_MEM_WRITEABLE; - if (window) - flags |= IORESOURCE_WINDOW; - - pnp_add_mem_resource(dev, start, end, flags); -} - -static void pnpacpi_parse_allocated_busresource(struct pnp_dev *dev, - u64 start, u64 len) -{ - u64 end = start + len - 1; - - pnp_add_bus_resource(dev, start, end); -} - -static void pnpacpi_parse_allocated_address_space(struct pnp_dev *dev, - struct acpi_resource *res) -{ - struct acpi_resource_address64 addr, *p = &addr; - acpi_status status; - int window; - u64 len; - - status = acpi_resource_to_address64(res, p); - if (!ACPI_SUCCESS(status)) { - dev_warn(&dev->dev, "failed to convert resource type %d\n", - res->type); - return; - } - - /* Windows apparently computes length rather than using _LEN */ - len = p->maximum - p->minimum + 1; - window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; - - if (p->resource_type == ACPI_MEMORY_RANGE) - pnpacpi_parse_allocated_memresource(dev, p->minimum, len, - p->info.mem.write_protect, window); - else if (p->resource_type == ACPI_IO_RANGE) - pnpacpi_parse_allocated_ioresource(dev, p->minimum, len, - p->granularity == 0xfff ? ACPI_DECODE_10 : - ACPI_DECODE_16, window); - else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) - pnpacpi_parse_allocated_busresource(dev, p->minimum, len); -} - -static void pnpacpi_parse_allocated_ext_address_space(struct pnp_dev *dev, - struct acpi_resource *res) -{ - struct acpi_resource_extended_address64 *p = &res->data.ext_address64; - int window; - u64 len; - - /* Windows apparently computes length rather than using _LEN */ - len = p->maximum - p->minimum + 1; - window = (p->producer_consumer == ACPI_PRODUCER) ? 1 : 0; - - if (p->resource_type == ACPI_MEMORY_RANGE) - pnpacpi_parse_allocated_memresource(dev, p->minimum, len, - p->info.mem.write_protect, window); - else if (p->resource_type == ACPI_IO_RANGE) - pnpacpi_parse_allocated_ioresource(dev, p->minimum, len, - p->granularity == 0xfff ? ACPI_DECODE_10 : - ACPI_DECODE_16, window); - else if (p->resource_type == ACPI_BUS_NUMBER_RANGE) - pnpacpi_parse_allocated_busresource(dev, p->minimum, len); -} - static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, void *data) { struct pnp_dev *dev = data; - struct acpi_resource_irq *irq; struct acpi_resource_dma *dma; - struct acpi_resource_io *io; - struct acpi_resource_fixed_io *fixed_io; struct acpi_resource_vendor_typed *vendor_typed; - struct acpi_resource_memory24 *memory24; - struct acpi_resource_memory32 *memory32; - struct acpi_resource_fixed_memory32 *fixed_memory32; - struct acpi_resource_extended_irq *extended_irq; + struct resource r; int i, flags; - switch (res->type) { - case ACPI_RESOURCE_TYPE_IRQ: - /* - * Per spec, only one interrupt per descriptor is allowed in - * _CRS, but some firmware violates this, so parse them all. - */ - irq = &res->data.irq; - if (irq->interrupt_count == 0) - pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); - else { - for (i = 0; i < irq->interrupt_count; i++) { - pnpacpi_parse_allocated_irqresource(dev, - irq->interrupts[i], - irq->triggering, - irq->polarity, - irq->sharable); - } + if (acpi_dev_resource_memory(res, &r) + || acpi_dev_resource_io(res, &r) + || acpi_dev_resource_address_space(res, &r) + || acpi_dev_resource_ext_address_space(res, &r)) { + pnp_add_resource(dev, &r); + return AE_OK; + } + r.flags = 0; + if (acpi_dev_resource_interrupt(res, 0, &r)) { + pnpacpi_add_irqresource(dev, &r); + for (i = 1; acpi_dev_resource_interrupt(res, i, &r); i++) + pnpacpi_add_irqresource(dev, &r); + + if (i > 1) { /* * The IRQ encoder puts a single interrupt in each * descriptor, so if a _CRS descriptor has more than * one interrupt, we won't be able to re-encode it. */ - if (pnp_can_write(dev) && irq->interrupt_count > 1) { + if (pnp_can_write(dev)) { dev_warn(&dev->dev, "multiple interrupts in " "_CRS descriptor; configuration can't " "be changed\n"); dev->capabilities &= ~PNP_WRITE; } } - break; + return AE_OK; + } else if (r.flags & IORESOURCE_DISABLED) { + pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); + return AE_OK; + } + switch (res->type) { case ACPI_RESOURCE_TYPE_DMA: dma = &res->data.dma; if (dma->channel_count > 0 && dma->channels[0] != (u8) -1) @@ -383,26 +227,10 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, pnp_add_dma_resource(dev, dma->channels[0], flags); break; - case ACPI_RESOURCE_TYPE_IO: - io = &res->data.io; - pnpacpi_parse_allocated_ioresource(dev, - io->minimum, - io->address_length, - io->io_decode, 0); - break; - case ACPI_RESOURCE_TYPE_START_DEPENDENT: case ACPI_RESOURCE_TYPE_END_DEPENDENT: break; - case ACPI_RESOURCE_TYPE_FIXED_IO: - fixed_io = &res->data.fixed_io; - pnpacpi_parse_allocated_ioresource(dev, - fixed_io->address, - fixed_io->address_length, - ACPI_DECODE_10, 0); - break; - case ACPI_RESOURCE_TYPE_VENDOR: vendor_typed = &res->data.vendor_typed; pnpacpi_parse_allocated_vendor(dev, vendor_typed); @@ -411,66 +239,6 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, case ACPI_RESOURCE_TYPE_END_TAG: break; - case ACPI_RESOURCE_TYPE_MEMORY24: - memory24 = &res->data.memory24; - pnpacpi_parse_allocated_memresource(dev, - memory24->minimum, - memory24->address_length, - memory24->write_protect, 0); - break; - case ACPI_RESOURCE_TYPE_MEMORY32: - memory32 = &res->data.memory32; - pnpacpi_parse_allocated_memresource(dev, - memory32->minimum, - memory32->address_length, - memory32->write_protect, 0); - break; - case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: - fixed_memory32 = &res->data.fixed_memory32; - pnpacpi_parse_allocated_memresource(dev, - fixed_memory32->address, - fixed_memory32->address_length, - fixed_memory32->write_protect, 0); - break; - case ACPI_RESOURCE_TYPE_ADDRESS16: - case ACPI_RESOURCE_TYPE_ADDRESS32: - case ACPI_RESOURCE_TYPE_ADDRESS64: - pnpacpi_parse_allocated_address_space(dev, res); - break; - - case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: - pnpacpi_parse_allocated_ext_address_space(dev, res); - break; - - case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: - extended_irq = &res->data.extended_irq; - - if (extended_irq->interrupt_count == 0) - pnp_add_irq_resource(dev, 0, IORESOURCE_DISABLED); - else { - for (i = 0; i < extended_irq->interrupt_count; i++) { - pnpacpi_parse_allocated_irqresource(dev, - extended_irq->interrupts[i], - extended_irq->triggering, - extended_irq->polarity, - extended_irq->sharable); - } - - /* - * The IRQ encoder puts a single interrupt in each - * descriptor, so if a _CRS descriptor has more than - * one interrupt, we won't be able to re-encode it. - */ - if (pnp_can_write(dev) && - extended_irq->interrupt_count > 1) { - dev_warn(&dev->dev, "multiple interrupts in " - "_CRS descriptor; configuration can't " - "be changed\n"); - dev->capabilities &= ~PNP_WRITE; - } - } - break; - case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: break; @@ -531,7 +299,7 @@ static __init void pnpacpi_parse_irq_option(struct pnp_dev *dev, if (p->interrupts[i]) __set_bit(p->interrupts[i], map.bits); - flags = irq_flags(p->triggering, p->polarity, p->sharable); + flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable); pnp_register_irq_resource(dev, option_flags, &map, flags); } @@ -555,7 +323,7 @@ static __init void pnpacpi_parse_ext_irq_option(struct pnp_dev *dev, } } - flags = irq_flags(p->triggering, p->polarity, p->sharable); + flags = acpi_dev_irq_flags(p->triggering, p->polarity, p->sharable); pnp_register_irq_resource(dev, option_flags, &map, flags); } diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index b0ecacbe53b..3e6db1c1dc2 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -503,6 +503,22 @@ static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev) return pnp_res; } +struct pnp_resource *pnp_add_resource(struct pnp_dev *dev, + struct resource *res) +{ + struct pnp_resource *pnp_res; + + pnp_res = pnp_new_resource(dev); + if (!pnp_res) { + dev_err(&dev->dev, "can't add resource %pR\n", res); + return NULL; + } + + pnp_res->res = *res; + dev_dbg(&dev->dev, "%pR\n", res); + return pnp_res; +} + struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, int flags) { diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 48761cb481d..16fcaf8dad3 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -251,6 +251,16 @@ extern int pnpacpi_disabled; #define PXM_INVAL (-1) +bool acpi_dev_resource_memory(struct acpi_resource *ares, struct resource *res); +bool acpi_dev_resource_io(struct acpi_resource *ares, struct resource *res); +bool acpi_dev_resource_address_space(struct acpi_resource *ares, + struct resource *res); +bool acpi_dev_resource_ext_address_space(struct acpi_resource *ares, + struct resource *res); +unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable); +bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, + struct resource *res); + int acpi_check_resource_conflict(const struct resource *res); int acpi_check_region(resource_size_t start, resource_size_t n, -- cgit v1.2.3 From 97d69dc061e968b5e9e56f48bb223b9ab7764b48 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 15 Nov 2012 00:30:12 +0100 Subject: ACPI / platform: Use common ACPI device resource parsing routines Use common routines in drivers/acpi/resource.c to parse ACPI device resources while creating platform device objects. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg Tested-by: Mika Westerberg --- drivers/acpi/acpi_platform.c | 89 ++++++++++---------------------------------- 1 file changed, 20 insertions(+), 69 deletions(-) diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index dbb31d61e31..bcbb00ce6d9 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -29,21 +29,20 @@ static acpi_status acpi_platform_count_resources(struct acpi_resource *res, void *data) { struct acpi_resource_extended_irq *acpi_xirq; + struct acpi_resource_irq *acpi_irq; struct resource_info *ri = data; switch (res->type) { - case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: case ACPI_RESOURCE_TYPE_IRQ: - ri->n++; + acpi_irq = &res->data.irq; + ri->n += acpi_irq->interrupt_count; break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: acpi_xirq = &res->data.extended_irq; ri->n += acpi_xirq->interrupt_count; break; - case ACPI_RESOURCE_TYPE_ADDRESS32: - if (res->data.address32.resource_type == ACPI_IO_RANGE) - ri->n++; - break; + default: + ri->n++; } return AE_OK; @@ -52,71 +51,26 @@ static acpi_status acpi_platform_count_resources(struct acpi_resource *res, static acpi_status acpi_platform_add_resources(struct acpi_resource *res, void *data) { - struct acpi_resource_fixed_memory32 *acpi_mem; - struct acpi_resource_address32 *acpi_add32; - struct acpi_resource_extended_irq *acpi_xirq; - struct acpi_resource_irq *acpi_irq; struct resource_info *ri = data; struct resource *r; - int irq, i; - - switch (res->type) { - case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: - acpi_mem = &res->data.fixed_memory32; - r = &ri->res[ri->cur++]; - r->start = acpi_mem->address; - r->end = r->start + acpi_mem->address_length - 1; - r->flags = IORESOURCE_MEM; - - dev_dbg(ri->dev, "Memory32Fixed %pR\n", r); - break; - - case ACPI_RESOURCE_TYPE_ADDRESS32: - acpi_add32 = &res->data.address32; - - if (acpi_add32->resource_type == ACPI_IO_RANGE) { - r = &ri->res[ri->cur++]; - r->start = acpi_add32->minimum; - r->end = r->start + acpi_add32->address_length - 1; - r->flags = IORESOURCE_IO; - dev_dbg(ri->dev, "Address32 %pR\n", r); - } - break; - - case ACPI_RESOURCE_TYPE_IRQ: - acpi_irq = &res->data.irq; - r = &ri->res[ri->cur++]; - - irq = acpi_register_gsi(ri->dev, - acpi_irq->interrupts[0], - acpi_irq->triggering, - acpi_irq->polarity); - - r->start = r->end = irq; - r->flags = IORESOURCE_IRQ; - - dev_dbg(ri->dev, "IRQ %pR\n", r); - break; - - case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: - acpi_xirq = &res->data.extended_irq; - - for (i = 0; i < acpi_xirq->interrupt_count; i++, ri->cur++) { - r = &ri->res[ri->cur]; - irq = acpi_register_gsi(ri->dev, - acpi_xirq->interrupts[i], - acpi_xirq->triggering, - acpi_xirq->polarity); + r = ri->res + ri->cur; + if (acpi_dev_resource_memory(res, r) + || acpi_dev_resource_io(res, r) + || acpi_dev_resource_address_space(res, r) + || acpi_dev_resource_ext_address_space(res, r)) { + ri->cur++; + return AE_OK; + } + if (acpi_dev_resource_interrupt(res, 0, r)) { + int i; - r->start = r->end = irq; - r->flags = IORESOURCE_IRQ; + r++; + for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++) + r++; - dev_dbg(ri->dev, "Interrupt %pR\n", r); - } - break; + ri->cur += i; } - return AE_OK; } @@ -165,9 +119,6 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) goto out; } - if (WARN_ON(ri.n != ri.cur)) - goto out; - /* * If the ACPI node has a parent and that parent has a physical device * attached to it, that physical device should be the parent of the @@ -189,7 +140,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) mutex_unlock(&acpi_parent->physical_node_lock); } pdev = platform_device_register_resndata(parent, dev_name(&adev->dev), - -1, ri.res, ri.n, NULL, 0); + -1, ri.res, ri.cur, NULL, 0); if (IS_ERR(pdev)) { dev_err(&adev->dev, "platform device creation failed: %ld\n", PTR_ERR(pdev)); -- cgit v1.2.3 From 8e345c991c8c7a3c081199ef77deada79e37618a Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 15 Nov 2012 00:30:21 +0100 Subject: ACPI: Centralized processing of ACPI device resources Currently, whoever wants to use ACPI device resources has to call acpi_walk_resources() to browse the buffer returned by the _CRS method for the given device and create filters passed to that routine to apply to the individual resource items. This generally is cumbersome, time-consuming and inefficient. Moreover, it may be problematic if resource conflicts need to be resolved, because the different users of _CRS will need to do that in a consistent way. However, if there are resource conflicts, the ACPI core should be able to resolve them centrally instead of relying on various users of acpi_walk_resources() to handle them correctly together. For this reason, introduce a new function, acpi_dev_get_resources(), that can be used by subsystems to obtain a list of struct resource objects corresponding to the ACPI device resources returned by _CRS and, if necessary, to apply additional preprocessing routine to the ACPI resources before converting them to the struct resource format. Make the ACPI code that creates platform device objects use acpi_dev_get_resources() for resource processing instead of executing acpi_walk_resources() twice by itself, which causes it to be much more straightforward and easier to follow. In the future, acpi_dev_get_resources() can be extended to meet the needs of the ACPI PNP subsystem and other users of _CRS in the kernel. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg Tested-by: Mika Westerberg --- drivers/acpi/acpi_platform.c | 94 ++++++------------------------ drivers/acpi/resource.c | 134 +++++++++++++++++++++++++++++++++++++++++++ include/linux/acpi.h | 10 ++++ 3 files changed, 161 insertions(+), 77 deletions(-) diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index bcbb00ce6d9..7ac20d8b8f0 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -19,61 +19,6 @@ ACPI_MODULE_NAME("platform"); -struct resource_info { - struct device *dev; - struct resource *res; - size_t n, cur; -}; - -static acpi_status acpi_platform_count_resources(struct acpi_resource *res, - void *data) -{ - struct acpi_resource_extended_irq *acpi_xirq; - struct acpi_resource_irq *acpi_irq; - struct resource_info *ri = data; - - switch (res->type) { - case ACPI_RESOURCE_TYPE_IRQ: - acpi_irq = &res->data.irq; - ri->n += acpi_irq->interrupt_count; - break; - case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: - acpi_xirq = &res->data.extended_irq; - ri->n += acpi_xirq->interrupt_count; - break; - default: - ri->n++; - } - - return AE_OK; -} - -static acpi_status acpi_platform_add_resources(struct acpi_resource *res, - void *data) -{ - struct resource_info *ri = data; - struct resource *r; - - r = ri->res + ri->cur; - if (acpi_dev_resource_memory(res, r) - || acpi_dev_resource_io(res, r) - || acpi_dev_resource_address_space(res, r) - || acpi_dev_resource_ext_address_space(res, r)) { - ri->cur++; - return AE_OK; - } - if (acpi_dev_resource_interrupt(res, 0, r)) { - int i; - - r++; - for (i = 1; acpi_dev_resource_interrupt(res, i, r); i++) - r++; - - ri->cur += i; - } - return AE_OK; -} - /** * acpi_create_platform_device - Create platform device for ACPI device node * @adev: ACPI device node to create a platform device for. @@ -89,35 +34,31 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) struct platform_device *pdev = NULL; struct acpi_device *acpi_parent; struct device *parent = NULL; - struct resource_info ri; - acpi_status status; + struct resource_list_entry *rentry; + struct list_head resource_list; + struct resource *resources; + int count; /* If the ACPI node already has a physical device attached, skip it. */ if (adev->physical_node_count) return NULL; - memset(&ri, 0, sizeof(ri)); - /* First, count the resources. */ - status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, - acpi_platform_count_resources, &ri); - if (ACPI_FAILURE(status) || !ri.n) + INIT_LIST_HEAD(&resource_list); + count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); + if (count <= 0) return NULL; - /* Next, allocate memory for all the resources and populate it. */ - ri.dev = &adev->dev; - ri.res = kzalloc(ri.n * sizeof(struct resource), GFP_KERNEL); - if (!ri.res) { - dev_err(&adev->dev, - "failed to allocate memory for resources\n"); + resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL); + if (!resources) { + dev_err(&adev->dev, "No memory for resources\n"); + acpi_dev_free_resource_list(&resource_list); return NULL; } + count = 0; + list_for_each_entry(rentry, &resource_list, node) + resources[count++] = rentry->res; - status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, - acpi_platform_add_resources, &ri); - if (ACPI_FAILURE(status)) { - dev_err(&adev->dev, "failed to walk resources\n"); - goto out; - } + acpi_dev_free_resource_list(&resource_list); /* * If the ACPI node has a parent and that parent has a physical device @@ -140,7 +81,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) mutex_unlock(&acpi_parent->physical_node_lock); } pdev = platform_device_register_resndata(parent, dev_name(&adev->dev), - -1, ri.res, ri.cur, NULL, 0); + -1, resources, count, NULL, 0); if (IS_ERR(pdev)) { dev_err(&adev->dev, "platform device creation failed: %ld\n", PTR_ERR(pdev)); @@ -150,8 +91,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) dev_name(&pdev->dev)); } - out: - kfree(ri.res); + kfree(resources); return pdev; } diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 3e7fd349e29..2bafc25482b 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef CONFIG_X86 #define valid_IRQ(i) (((i) != 0) && ((i) != 2)) @@ -391,3 +392,136 @@ bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, return true; } EXPORT_SYMBOL_GPL(acpi_dev_resource_interrupt); + +/** + * acpi_dev_free_resource_list - Free resource from %acpi_dev_get_resources(). + * @list: The head of the resource list to free. + */ +void acpi_dev_free_resource_list(struct list_head *list) +{ + struct resource_list_entry *rentry, *re; + + list_for_each_entry_safe(rentry, re, list, node) { + list_del(&rentry->node); + kfree(rentry); + } +} +EXPORT_SYMBOL_GPL(acpi_dev_free_resource_list); + +struct res_proc_context { + struct list_head *list; + int (*preproc)(struct acpi_resource *, void *); + void *preproc_data; + int count; + int error; +}; + +static acpi_status acpi_dev_new_resource_entry(struct resource *r, + struct res_proc_context *c) +{ + struct resource_list_entry *rentry; + + rentry = kmalloc(sizeof(*rentry), GFP_KERNEL); + if (!rentry) { + c->error = -ENOMEM; + return AE_NO_MEMORY; + } + INIT_LIST_HEAD(&rentry->node); + rentry->res = *r; + list_add_tail(&rentry->node, c->list); + c->count++; + return AE_OK; +} + +static acpi_status acpi_dev_process_resource(struct acpi_resource *ares, + void *context) +{ + struct res_proc_context *c = context; + struct resource r; + int i; + + if (c->preproc) { + int ret; + + ret = c->preproc(ares, c->preproc_data); + if (ret < 0) { + c->error = ret; + return AE_ABORT_METHOD; + } else if (ret > 0) { + return AE_OK; + } + } + + memset(&r, 0, sizeof(r)); + + if (acpi_dev_resource_memory(ares, &r) + || acpi_dev_resource_io(ares, &r) + || acpi_dev_resource_address_space(ares, &r) + || acpi_dev_resource_ext_address_space(ares, &r)) + return acpi_dev_new_resource_entry(&r, c); + + for (i = 0; acpi_dev_resource_interrupt(ares, i, &r); i++) { + acpi_status status; + + status = acpi_dev_new_resource_entry(&r, c); + if (ACPI_FAILURE(status)) + return status; + } + + return AE_OK; +} + +/** + * acpi_dev_get_resources - Get current resources of a device. + * @adev: ACPI device node to get the resources for. + * @list: Head of the resultant list of resources (must be empty). + * @preproc: The caller's preprocessing routine. + * @preproc_data: Pointer passed to the caller's preprocessing routine. + * + * Evaluate the _CRS method for the given device node and process its output by + * (1) executing the @preproc() rountine provided by the caller, passing the + * resource pointer and @preproc_data to it as arguments, for each ACPI resource + * returned and (2) converting all of the returned ACPI resources into struct + * resource objects if possible. If the return value of @preproc() in step (1) + * is different from 0, step (2) is not applied to the given ACPI resource and + * if that value is negative, the whole processing is aborted and that value is + * returned as the final error code. + * + * The resultant struct resource objects are put on the list pointed to by + * @list, that must be empty initially, as members of struct resource_list_entry + * objects. Callers of this routine should use %acpi_dev_free_resource_list() to + * free that list. + * + * The number of resources in the output list is returned on success, an error + * code reflecting the error condition is returned otherwise. + */ +int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list, + int (*preproc)(struct acpi_resource *, void *), + void *preproc_data) +{ + struct res_proc_context c; + acpi_handle not_used; + acpi_status status; + + if (!adev || !adev->handle || !list_empty(list)) + return -EINVAL; + + status = acpi_get_handle(adev->handle, METHOD_NAME__CRS, ¬_used); + if (ACPI_FAILURE(status)) + return 0; + + c.list = list; + c.preproc = preproc; + c.preproc_data = preproc_data; + c.count = 0; + c.error = 0; + status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, + acpi_dev_process_resource, &c); + if (ACPI_FAILURE(status)) { + acpi_dev_free_resource_list(list); + return c.error ? c.error : -EIO; + } + + return c.count; +} +EXPORT_SYMBOL_GPL(acpi_dev_get_resources); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 16fcaf8dad3..32fbc4e73a5 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -261,6 +261,16 @@ unsigned long acpi_dev_irq_flags(u8 triggering, u8 polarity, u8 shareable); bool acpi_dev_resource_interrupt(struct acpi_resource *ares, int index, struct resource *res); +struct resource_list_entry { + struct list_head node; + struct resource res; +}; + +void acpi_dev_free_resource_list(struct list_head *list); +int acpi_dev_get_resources(struct acpi_device *adev, struct list_head *list, + int (*preproc)(struct acpi_resource *, void *), + void *preproc_data); + int acpi_check_resource_conflict(const struct resource *res); int acpi_check_region(resource_size_t start, resource_size_t n, -- cgit v1.2.3 From 45dcd31547fcd58273423799b12efe0e8371127e Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:24:51 +0000 Subject: Cleanup of invalid ACPI name handling and repair Implemented a change/cleanup for the handling of invalid ACPI names. Names are now validated and repaired only when 1) entering a new name into the namespace and 2) disassembling a named AML opcode. A warning is only displayed in debug mode or when the interpreter is in "strict" mode, since some working machines do in fact contain invalid ACPI names. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acutils.h | 2 +- drivers/acpi/acpica/nsdump.c | 8 -------- drivers/acpi/acpica/nssearch.c | 17 +---------------- drivers/acpi/acpica/utmisc.c | 34 ++++++++++++++++++++++++++-------- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 5035327ebcc..68cb6de26d1 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -483,7 +483,7 @@ void acpi_ut_print_string(char *string, u8 max_length); u8 acpi_ut_valid_acpi_name(u32 name); -acpi_name acpi_ut_repair_name(char *name); +void acpi_ut_repair_name(char *name); u8 acpi_ut_valid_acpi_char(char character, u32 position); diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index 2526aaf945e..993b12417e7 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c @@ -209,14 +209,6 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, "Invalid ACPI Object Type 0x%08X", type)); } - if (!acpi_ut_valid_acpi_name(this_node->name.integer)) { - this_node->name.integer = - acpi_ut_repair_name(this_node->name.ascii); - - ACPI_WARNING((AE_INFO, "Invalid ACPI Name %08X", - this_node->name.integer)); - } - acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node)); } diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index 456cc859f86..1d2d8ffc1bc 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c @@ -314,22 +314,7 @@ acpi_ns_search_and_enter(u32 target_name, * this problem, and we want to be able to enable ACPI support for them, * even though there are a few bad names. */ - if (!acpi_ut_valid_acpi_name(target_name)) { - target_name = - acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name)); - - /* Report warning only if in strict mode or debug mode */ - - if (!acpi_gbl_enable_interpreter_slack) { - ACPI_WARNING((AE_INFO, - "Found bad character(s) in name, repaired: [%4.4s]\n", - ACPI_CAST_PTR(char, &target_name))); - } else { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Found bad character(s) in name, repaired: [%4.4s]\n", - ACPI_CAST_PTR(char, &target_name))); - } - } + acpi_ut_repair_name(ACPI_CAST_PTR(char, &target_name)); /* Try to find the name in the namespace level specified by the caller */ diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 33c6cf7ff46..d91d88df2a9 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -642,25 +642,43 @@ u8 acpi_ut_valid_acpi_name(u32 name) * ******************************************************************************/ -acpi_name acpi_ut_repair_name(char *name) +void acpi_ut_repair_name(char *name) { - u32 i; - char new_name[ACPI_NAME_SIZE]; + u32 i; + u8 found_bad_char = FALSE; + + ACPI_FUNCTION_NAME(ut_repair_name); + + /* Check each character in the name */ for (i = 0; i < ACPI_NAME_SIZE; i++) { - new_name[i] = name[i]; + if (acpi_ut_valid_acpi_char(name[i], i)) { + continue; + } /* * Replace a bad character with something printable, yet technically * still invalid. This prevents any collisions with existing "good" * names in the namespace. */ - if (!acpi_ut_valid_acpi_char(name[i], i)) { - new_name[i] = '*'; - } + name[i] = '*'; + found_bad_char = TRUE; } - return (*(u32 *) new_name); + if (found_bad_char) { + + /* Report warning only if in strict mode or debug mode */ + + if (!acpi_gbl_enable_interpreter_slack) { + ACPI_WARNING((AE_INFO, + "Found bad character(s) in name, repaired: [%4.4s]\n", + name)); + } else { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Found bad character(s) in name, repaired: [%4.4s]\n", + name)); + } + } } /******************************************************************************* -- cgit v1.2.3 From 6d33b6be17dd6a0934396704f969ceb7f3206347 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 31 Oct 2012 02:25:05 +0000 Subject: ACPICA: Fix unmerged utility divergences. Utility improvements in ACPICA are partial ignored by ACPICA Linux release. This will lead to divergences between Linux and ACPICA. This patch ports the entire "utility" into Linux and makes them igored in the compilation stage by "ACPI_FUTURE_USAGE". The following "Utility" files have been ported into the Linux: drivers/acpi/uttrack.c drivers/acpi/utcache.c drivers/acpi/utids.c This patch will not affect the generated vmlinx binary. This will decrease 274 lines of 20120913 divergence.diff. Signed-off-by: Robert Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/Makefile | 3 + drivers/acpi/acpica/acutils.h | 51 ++- drivers/acpi/acpica/utcache.c | 323 ++++++++++++++++++ drivers/acpi/acpica/utclib.c | 748 ++++++++++++++++++++++++++++++++++++++++++ drivers/acpi/acpica/utdebug.c | 9 +- drivers/acpi/acpica/utmisc.c | 99 +++++- drivers/acpi/acpica/uttrack.c | 650 ++++++++++++++++++++++++++++++++++++ 7 files changed, 1852 insertions(+), 31 deletions(-) create mode 100644 drivers/acpi/acpica/utcache.c create mode 100644 drivers/acpi/acpica/utclib.c create mode 100644 drivers/acpi/acpica/uttrack.c diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 7f1d40797e8..c8bc24bd1f7 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -161,3 +161,6 @@ acpi-y += \ utxfinit.o \ utxferror.o \ utxfmutex.o + +acpi-$(ACPI_FUTURE_USAGE) += uttrack.o utcache.o utclib.o + diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 68cb6de26d1..82d6025332e 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -69,6 +69,22 @@ extern const char *acpi_gbl_siz_decode[]; extern const char *acpi_gbl_trs_decode[]; extern const char *acpi_gbl_ttp_decode[]; extern const char *acpi_gbl_typ_decode[]; +extern const char *acpi_gbl_ppc_decode[]; +extern const char *acpi_gbl_ior_decode[]; +extern const char *acpi_gbl_dts_decode[]; +extern const char *acpi_gbl_ct_decode[]; +extern const char *acpi_gbl_sbt_decode[]; +extern const char *acpi_gbl_am_decode[]; +extern const char *acpi_gbl_sm_decode[]; +extern const char *acpi_gbl_wm_decode[]; +extern const char *acpi_gbl_cph_decode[]; +extern const char *acpi_gbl_cpo_decode[]; +extern const char *acpi_gbl_dp_decode[]; +extern const char *acpi_gbl_ed_decode[]; +extern const char *acpi_gbl_bpb_decode[]; +extern const char *acpi_gbl_sb_decode[]; +extern const char *acpi_gbl_fc_decode[]; +extern const char *acpi_gbl_pt_decode[]; #endif /* Types for Resource descriptor entries */ @@ -79,14 +95,14 @@ extern const char *acpi_gbl_typ_decode[]; #define ACPI_SMALL_VARIABLE_LENGTH 3 typedef -acpi_status(*acpi_walk_aml_callback) (u8 * aml, +acpi_status(*acpi_walk_aml_callback) (u8 *aml, u32 length, u32 offset, u8 resource_index, void **context); typedef acpi_status(*acpi_pkg_callback) (u8 object_type, - union acpi_operand_object * source_object, + union acpi_operand_object *source_object, union acpi_generic_state * state, void *context); @@ -202,7 +218,9 @@ extern const u8 _acpi_ctype[]; #define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU)) #define ACPI_IS_ALPHA(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP)) -#endif /* ACPI_USE_SYSTEM_CLIBRARY */ +#endif /* !ACPI_USE_SYSTEM_CLIBRARY */ + +#define ACPI_IS_ASCII(c) ((c) < 0x80) /* * utcopy - Object construction and conversion interfaces @@ -210,11 +228,11 @@ extern const u8 _acpi_ctype[]; acpi_status acpi_ut_build_simple_object(union acpi_operand_object *obj, union acpi_object *user_obj, - u8 * data_space, u32 * buffer_space_used); + u8 *data_space, u32 *buffer_space_used); acpi_status acpi_ut_build_package_object(union acpi_operand_object *obj, - u8 * buffer, u32 * space_used); + u8 *buffer, u32 *space_used); acpi_status acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *obj, @@ -287,9 +305,9 @@ acpi_ut_ptr_exit(u32 line_number, const char *function_name, const char *module_name, u32 component_id, u8 *ptr); -void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id); +void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id); -void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display); +void acpi_ut_dump_buffer2(u8 *buffer, u32 count, u32 display); void acpi_ut_report_error(char *module_name, u32 line_number); @@ -337,15 +355,15 @@ acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, */ acpi_status acpi_ut_execute_HID(struct acpi_namespace_node *device_node, - struct acpica_device_id **return_id); + struct acpica_device_id ** return_id); acpi_status acpi_ut_execute_UID(struct acpi_namespace_node *device_node, - struct acpica_device_id **return_id); + struct acpica_device_id ** return_id); acpi_status acpi_ut_execute_CID(struct acpi_namespace_node *device_node, - struct acpica_device_id_list **return_cid_list); + struct acpica_device_id_list ** return_cid_list); /* * utlock - reader/writer locks @@ -479,6 +497,10 @@ acpi_ut_walk_package_tree(union acpi_operand_object *source_object, void acpi_ut_strupr(char *src_string); +void acpi_ut_strlwr(char *src_string); + +int acpi_ut_stricmp(char *string1, char *string2); + void acpi_ut_print_string(char *string, u8 max_length); u8 acpi_ut_valid_acpi_name(u32 name); @@ -487,7 +509,7 @@ void acpi_ut_repair_name(char *name); u8 acpi_ut_valid_acpi_char(char character, u32 position); -acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer); +acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer); /* Values for Base above (16=Hex, 10=Decimal) */ @@ -508,12 +530,12 @@ acpi_ut_display_init_pathname(u8 type, * utresrc */ acpi_status -acpi_ut_walk_aml_resources(u8 * aml, +acpi_ut_walk_aml_resources(u8 *aml, acpi_size aml_length, acpi_walk_aml_callback user_function, void **context); -acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index); +acpi_status acpi_ut_validate_resource(void *aml, u8 *return_index); u32 acpi_ut_get_descriptor_length(void *aml); @@ -524,8 +546,7 @@ u8 acpi_ut_get_resource_header_length(void *aml); u8 acpi_ut_get_resource_type(void *aml); acpi_status -acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, - u8 ** end_tag); +acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, u8 **end_tag); /* * utmutex - mutex support diff --git a/drivers/acpi/acpica/utcache.c b/drivers/acpi/acpica/utcache.c new file mode 100644 index 00000000000..eacb9ba2b9e --- /dev/null +++ b/drivers/acpi/acpica/utcache.c @@ -0,0 +1,323 @@ +/****************************************************************************** + * + * Module Name: utcache - local cache allocation routines + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME("utcache") + +#ifdef ACPI_USE_LOCAL_CACHE +/******************************************************************************* + * + * FUNCTION: acpi_os_create_cache + * + * PARAMETERS: cache_name - Ascii name for the cache + * object_size - Size of each cached object + * max_depth - Maximum depth of the cache (in objects) + * return_cache - Where the new cache object is returned + * + * RETURN: Status + * + * DESCRIPTION: Create a cache object + * + ******************************************************************************/ +acpi_status +acpi_os_create_cache(char *cache_name, + u16 object_size, + u16 max_depth, struct acpi_memory_list ** return_cache) +{ + struct acpi_memory_list *cache; + + ACPI_FUNCTION_ENTRY(); + + if (!cache_name || !return_cache || (object_size < 16)) { + return (AE_BAD_PARAMETER); + } + + /* Create the cache object */ + + cache = acpi_os_allocate(sizeof(struct acpi_memory_list)); + if (!cache) { + return (AE_NO_MEMORY); + } + + /* Populate the cache object and return it */ + + ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list)); + cache->link_offset = 8; + cache->list_name = cache_name; + cache->object_size = object_size; + cache->max_depth = max_depth; + + *return_cache = cache; + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_os_purge_cache + * + * PARAMETERS: cache - Handle to cache object + * + * RETURN: Status + * + * DESCRIPTION: Free all objects within the requested cache. + * + ******************************************************************************/ + +acpi_status acpi_os_purge_cache(struct acpi_memory_list * cache) +{ + char *next; + acpi_status status; + + ACPI_FUNCTION_ENTRY(); + + if (!cache) { + return (AE_BAD_PARAMETER); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Walk the list of objects in this cache */ + + while (cache->list_head) { + + /* Delete and unlink one cached state object */ + + next = *(ACPI_CAST_INDIRECT_PTR(char, + &(((char *)cache-> + list_head)[cache-> + link_offset]))); + ACPI_FREE(cache->list_head); + + cache->list_head = next; + cache->current_depth--; + } + + (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_os_delete_cache + * + * PARAMETERS: cache - Handle to cache object + * + * RETURN: Status + * + * DESCRIPTION: Free all objects within the requested cache and delete the + * cache object. + * + ******************************************************************************/ + +acpi_status acpi_os_delete_cache(struct acpi_memory_list * cache) +{ + acpi_status status; + + ACPI_FUNCTION_ENTRY(); + + /* Purge all objects in the cache */ + + status = acpi_os_purge_cache(cache); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Now we can delete the cache object */ + + acpi_os_free(cache); + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_os_release_object + * + * PARAMETERS: cache - Handle to cache object + * object - The object to be released + * + * RETURN: None + * + * DESCRIPTION: Release an object to the specified cache. If cache is full, + * the object is deleted. + * + ******************************************************************************/ + +acpi_status +acpi_os_release_object(struct acpi_memory_list * cache, void *object) +{ + acpi_status status; + + ACPI_FUNCTION_ENTRY(); + + if (!cache || !object) { + return (AE_BAD_PARAMETER); + } + + /* If cache is full, just free this object */ + + if (cache->current_depth >= cache->max_depth) { + ACPI_FREE(object); + ACPI_MEM_TRACKING(cache->total_freed++); + } + + /* Otherwise put this object back into the cache */ + + else { + status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Mark the object as cached */ + + ACPI_MEMSET(object, 0xCA, cache->object_size); + ACPI_SET_DESCRIPTOR_TYPE(object, ACPI_DESC_TYPE_CACHED); + + /* Put the object at the head of the cache list */ + + *(ACPI_CAST_INDIRECT_PTR(char, + &(((char *)object)[cache-> + link_offset]))) = + cache->list_head; + cache->list_head = object; + cache->current_depth++; + + (void)acpi_ut_release_mutex(ACPI_MTX_CACHES); + } + + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_os_acquire_object + * + * PARAMETERS: cache - Handle to cache object + * + * RETURN: the acquired object. NULL on error + * + * DESCRIPTION: Get an object from the specified cache. If cache is empty, + * the object is allocated. + * + ******************************************************************************/ + +void *acpi_os_acquire_object(struct acpi_memory_list *cache) +{ + acpi_status status; + void *object; + + ACPI_FUNCTION_NAME(os_acquire_object); + + if (!cache) { + return (NULL); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_CACHES); + if (ACPI_FAILURE(status)) { + return (NULL); + } + + ACPI_MEM_TRACKING(cache->requests++); + + /* Check the cache first */ + + if (cache->list_head) { + + /* There is an object available, use it */ + + object = cache->list_head; + cache->list_head = *(ACPI_CAST_INDIRECT_PTR(char, + &(((char *) + object)[cache-> + link_offset]))); + + cache->current_depth--; + + ACPI_MEM_TRACKING(cache->hits++); + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, + "Object %p from %s cache\n", object, + cache->list_name)); + + status = acpi_ut_release_mutex(ACPI_MTX_CACHES); + if (ACPI_FAILURE(status)) { + return (NULL); + } + + /* Clear (zero) the previously used Object */ + + ACPI_MEMSET(object, 0, cache->object_size); + } else { + /* The cache is empty, create a new object */ + + ACPI_MEM_TRACKING(cache->total_allocated++); + +#ifdef ACPI_DBG_TRACK_ALLOCATIONS + if ((cache->total_allocated - cache->total_freed) > + cache->max_occupied) { + cache->max_occupied = + cache->total_allocated - cache->total_freed; + } +#endif + + /* Avoid deadlock with ACPI_ALLOCATE_ZEROED */ + + status = acpi_ut_release_mutex(ACPI_MTX_CACHES); + if (ACPI_FAILURE(status)) { + return (NULL); + } + + object = ACPI_ALLOCATE_ZEROED(cache->object_size); + if (!object) { + return (NULL); + } + } + + return (object); +} +#endif /* ACPI_USE_LOCAL_CACHE */ diff --git a/drivers/acpi/acpica/utclib.c b/drivers/acpi/acpica/utclib.c new file mode 100644 index 00000000000..f887f93e56a --- /dev/null +++ b/drivers/acpi/acpica/utclib.c @@ -0,0 +1,748 @@ +/****************************************************************************** + * + * Module Name: cmclib - Local implementation of C library functions + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" + +/* + * These implementations of standard C Library routines can optionally be + * used if a C library is not available. In general, they are less efficient + * than an inline or assembly implementation + */ + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME("cmclib") + +#ifndef ACPI_USE_SYSTEM_CLIBRARY +#define NEGATIVE 1 +#define POSITIVE 0 +/******************************************************************************* + * + * FUNCTION: acpi_ut_memcmp (memcmp) + * + * PARAMETERS: buffer1 - First Buffer + * buffer2 - Second Buffer + * count - Maximum # of bytes to compare + * + * RETURN: Index where Buffers mismatched, or 0 if Buffers matched + * + * DESCRIPTION: Compare two Buffers, with a maximum length + * + ******************************************************************************/ +int acpi_ut_memcmp(const char *buffer1, const char *buffer2, acpi_size count) +{ + + return ((count == ACPI_SIZE_MAX) ? 0 : ((unsigned char)*buffer1 - + (unsigned char)*buffer2)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_memcpy (memcpy) + * + * PARAMETERS: dest - Target of the copy + * src - Source buffer to copy + * count - Number of bytes to copy + * + * RETURN: Dest + * + * DESCRIPTION: Copy arbitrary bytes of memory + * + ******************************************************************************/ + +void *acpi_ut_memcpy(void *dest, const void *src, acpi_size count) +{ + char *new = (char *)dest; + char *old = (char *)src; + + while (count) { + *new = *old; + new++; + old++; + count--; + } + + return (dest); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_memset (memset) + * + * PARAMETERS: dest - Buffer to set + * value - Value to set each byte of memory + * count - Number of bytes to set + * + * RETURN: Dest + * + * DESCRIPTION: Initialize a buffer to a known value. + * + ******************************************************************************/ + +void *acpi_ut_memset(void *dest, u8 value, acpi_size count) +{ + char *new = (char *)dest; + + while (count) { + *new = (char)value; + new++; + count--; + } + + return (dest); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strlen (strlen) + * + * PARAMETERS: string - Null terminated string + * + * RETURN: Length + * + * DESCRIPTION: Returns the length of the input string + * + ******************************************************************************/ + +acpi_size acpi_ut_strlen(const char *string) +{ + u32 length = 0; + + /* Count the string until a null is encountered */ + + while (*string) { + length++; + string++; + } + + return (length); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strcpy (strcpy) + * + * PARAMETERS: dst_string - Target of the copy + * src_string - The source string to copy + * + * RETURN: dst_string + * + * DESCRIPTION: Copy a null terminated string + * + ******************************************************************************/ + +char *acpi_ut_strcpy(char *dst_string, const char *src_string) +{ + char *string = dst_string; + + /* Move bytes brute force */ + + while (*src_string) { + *string = *src_string; + + string++; + src_string++; + } + + /* Null terminate */ + + *string = 0; + return (dst_string); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strncpy (strncpy) + * + * PARAMETERS: dst_string - Target of the copy + * src_string - The source string to copy + * count - Maximum # of bytes to copy + * + * RETURN: dst_string + * + * DESCRIPTION: Copy a null terminated string, with a maximum length + * + ******************************************************************************/ + +char *acpi_ut_strncpy(char *dst_string, const char *src_string, acpi_size count) +{ + char *string = dst_string; + + /* Copy the string */ + + for (string = dst_string; + count && (count--, (*string++ = *src_string++));) {; + } + + /* Pad with nulls if necessary */ + + while (count--) { + *string = 0; + string++; + } + + /* Return original pointer */ + + return (dst_string); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strcmp (strcmp) + * + * PARAMETERS: string1 - First string + * string2 - Second string + * + * RETURN: Index where strings mismatched, or 0 if strings matched + * + * DESCRIPTION: Compare two null terminated strings + * + ******************************************************************************/ + +int acpi_ut_strcmp(const char *string1, const char *string2) +{ + + for (; (*string1 == *string2); string2++) { + if (!*string1++) { + return (0); + } + } + + return ((unsigned char)*string1 - (unsigned char)*string2); +} + +#ifdef ACPI_FUTURE_IMPLEMENTATION +/* Not used at this time */ +/******************************************************************************* + * + * FUNCTION: acpi_ut_strchr (strchr) + * + * PARAMETERS: string - Search string + * ch - character to search for + * + * RETURN: Ptr to char or NULL if not found + * + * DESCRIPTION: Search a string for a character + * + ******************************************************************************/ + +char *acpi_ut_strchr(const char *string, int ch) +{ + + for (; (*string); string++) { + if ((*string) == (char)ch) { + return ((char *)string); + } + } + + return (NULL); +} +#endif + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strncmp (strncmp) + * + * PARAMETERS: string1 - First string + * string2 - Second string + * count - Maximum # of bytes to compare + * + * RETURN: Index where strings mismatched, or 0 if strings matched + * + * DESCRIPTION: Compare two null terminated strings, with a maximum length + * + ******************************************************************************/ + +int acpi_ut_strncmp(const char *string1, const char *string2, acpi_size count) +{ + + for (; count-- && (*string1 == *string2); string2++) { + if (!*string1++) { + return (0); + } + } + + return ((count == ACPI_SIZE_MAX) ? 0 : ((unsigned char)*string1 - + (unsigned char)*string2)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strcat (Strcat) + * + * PARAMETERS: dst_string - Target of the copy + * src_string - The source string to copy + * + * RETURN: dst_string + * + * DESCRIPTION: Append a null terminated string to a null terminated string + * + ******************************************************************************/ + +char *acpi_ut_strcat(char *dst_string, const char *src_string) +{ + char *string; + + /* Find end of the destination string */ + + for (string = dst_string; *string++;) {; + } + + /* Concatenate the string */ + + for (--string; (*string++ = *src_string++);) {; + } + + return (dst_string); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strncat (strncat) + * + * PARAMETERS: dst_string - Target of the copy + * src_string - The source string to copy + * count - Maximum # of bytes to copy + * + * RETURN: dst_string + * + * DESCRIPTION: Append a null terminated string to a null terminated string, + * with a maximum count. + * + ******************************************************************************/ + +char *acpi_ut_strncat(char *dst_string, const char *src_string, acpi_size count) +{ + char *string; + + if (count) { + + /* Find end of the destination string */ + + for (string = dst_string; *string++;) {; + } + + /* Concatenate the string */ + + for (--string; (*string++ = *src_string++) && --count;) {; + } + + /* Null terminate if necessary */ + + if (!count) { + *string = 0; + } + } + + return (dst_string); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strstr (strstr) + * + * PARAMETERS: string1 - Target string + * string2 - Substring to search for + * + * RETURN: Where substring match starts, Null if no match found + * + * DESCRIPTION: Checks if String2 occurs in String1. This is not really a + * full implementation of strstr, only sufficient for command + * matching + * + ******************************************************************************/ + +char *acpi_ut_strstr(char *string1, char *string2) +{ + char *string; + + if (acpi_ut_strlen(string2) > acpi_ut_strlen(string1)) { + return (NULL); + } + + /* Walk entire string, comparing the letters */ + + for (string = string1; *string2;) { + if (*string2 != *string) { + return (NULL); + } + + string2++; + string++; + } + + return (string1); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_strtoul (strtoul) + * + * PARAMETERS: string - Null terminated string + * terminater - Where a pointer to the terminating byte is + * returned + * base - Radix of the string + * + * RETURN: Converted value + * + * DESCRIPTION: Convert a string into a 32-bit unsigned value. + * Note: use acpi_ut_strtoul64 for 64-bit integers. + * + ******************************************************************************/ + +u32 acpi_ut_strtoul(const char *string, char **terminator, u32 base) +{ + u32 converted = 0; + u32 index; + u32 sign; + const char *string_start; + u32 return_value = 0; + acpi_status status = AE_OK; + + /* + * Save the value of the pointer to the buffer's first + * character, save the current errno value, and then + * skip over any white space in the buffer: + */ + string_start = string; + while (ACPI_IS_SPACE(*string) || *string == '\t') { + ++string; + } + + /* + * The buffer may contain an optional plus or minus sign. + * If it does, then skip over it but remember what is was: + */ + if (*string == '-') { + sign = NEGATIVE; + ++string; + } else if (*string == '+') { + ++string; + sign = POSITIVE; + } else { + sign = POSITIVE; + } + + /* + * If the input parameter Base is zero, then we need to + * determine if it is octal, decimal, or hexadecimal: + */ + if (base == 0) { + if (*string == '0') { + if (acpi_ut_to_lower(*(++string)) == 'x') { + base = 16; + ++string; + } else { + base = 8; + } + } else { + base = 10; + } + } else if (base < 2 || base > 36) { + /* + * The specified Base parameter is not in the domain of + * this function: + */ + goto done; + } + + /* + * For octal and hexadecimal bases, skip over the leading + * 0 or 0x, if they are present. + */ + if (base == 8 && *string == '0') { + string++; + } + + if (base == 16 && + *string == '0' && acpi_ut_to_lower(*(++string)) == 'x') { + string++; + } + + /* + * Main loop: convert the string to an unsigned long: + */ + while (*string) { + if (ACPI_IS_DIGIT(*string)) { + index = (u32)((u8)*string - '0'); + } else { + index = (u32)acpi_ut_to_upper(*string); + if (ACPI_IS_UPPER(index)) { + index = index - 'A' + 10; + } else { + goto done; + } + } + + if (index >= base) { + goto done; + } + + /* + * Check to see if value is out of range: + */ + + if (return_value > ((ACPI_UINT32_MAX - (u32)index) / (u32)base)) { + status = AE_ERROR; + return_value = 0; /* reset */ + } else { + return_value *= base; + return_value += index; + converted = 1; + } + + ++string; + } + + done: + /* + * If appropriate, update the caller's pointer to the next + * unconverted character in the buffer. + */ + if (terminator) { + if (converted == 0 && return_value == 0 && string != NULL) { + *terminator = (char *)string_start; + } else { + *terminator = (char *)string; + } + } + + if (status == AE_ERROR) { + return_value = ACPI_UINT32_MAX; + } + + /* + * If a minus sign was present, then "the conversion is negated": + */ + if (sign == NEGATIVE) { + return_value = (ACPI_UINT32_MAX - return_value) + 1; + } + + return (return_value); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_to_upper (TOUPPER) + * + * PARAMETERS: c - Character to convert + * + * RETURN: Converted character as an int + * + * DESCRIPTION: Convert character to uppercase + * + ******************************************************************************/ + +int acpi_ut_to_upper(int c) +{ + + return (ACPI_IS_LOWER(c) ? ((c) - 0x20) : (c)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_to_lower (TOLOWER) + * + * PARAMETERS: c - Character to convert + * + * RETURN: Converted character as an int + * + * DESCRIPTION: Convert character to lowercase + * + ******************************************************************************/ + +int acpi_ut_to_lower(int c) +{ + + return (ACPI_IS_UPPER(c) ? ((c) + 0x20) : (c)); +} + +/******************************************************************************* + * + * FUNCTION: is* functions + * + * DESCRIPTION: is* functions use the ctype table below + * + ******************************************************************************/ + +const u8 _acpi_ctype[257] = { + _ACPI_CN, /* 0x0 0. */ + _ACPI_CN, /* 0x1 1. */ + _ACPI_CN, /* 0x2 2. */ + _ACPI_CN, /* 0x3 3. */ + _ACPI_CN, /* 0x4 4. */ + _ACPI_CN, /* 0x5 5. */ + _ACPI_CN, /* 0x6 6. */ + _ACPI_CN, /* 0x7 7. */ + _ACPI_CN, /* 0x8 8. */ + _ACPI_CN | _ACPI_SP, /* 0x9 9. */ + _ACPI_CN | _ACPI_SP, /* 0xA 10. */ + _ACPI_CN | _ACPI_SP, /* 0xB 11. */ + _ACPI_CN | _ACPI_SP, /* 0xC 12. */ + _ACPI_CN | _ACPI_SP, /* 0xD 13. */ + _ACPI_CN, /* 0xE 14. */ + _ACPI_CN, /* 0xF 15. */ + _ACPI_CN, /* 0x10 16. */ + _ACPI_CN, /* 0x11 17. */ + _ACPI_CN, /* 0x12 18. */ + _ACPI_CN, /* 0x13 19. */ + _ACPI_CN, /* 0x14 20. */ + _ACPI_CN, /* 0x15 21. */ + _ACPI_CN, /* 0x16 22. */ + _ACPI_CN, /* 0x17 23. */ + _ACPI_CN, /* 0x18 24. */ + _ACPI_CN, /* 0x19 25. */ + _ACPI_CN, /* 0x1A 26. */ + _ACPI_CN, /* 0x1B 27. */ + _ACPI_CN, /* 0x1C 28. */ + _ACPI_CN, /* 0x1D 29. */ + _ACPI_CN, /* 0x1E 30. */ + _ACPI_CN, /* 0x1F 31. */ + _ACPI_XS | _ACPI_SP, /* 0x20 32. ' ' */ + _ACPI_PU, /* 0x21 33. '!' */ + _ACPI_PU, /* 0x22 34. '"' */ + _ACPI_PU, /* 0x23 35. '#' */ + _ACPI_PU, /* 0x24 36. '$' */ + _ACPI_PU, /* 0x25 37. '%' */ + _ACPI_PU, /* 0x26 38. '&' */ + _ACPI_PU, /* 0x27 39. ''' */ + _ACPI_PU, /* 0x28 40. '(' */ + _ACPI_PU, /* 0x29 41. ')' */ + _ACPI_PU, /* 0x2A 42. '*' */ + _ACPI_PU, /* 0x2B 43. '+' */ + _ACPI_PU, /* 0x2C 44. ',' */ + _ACPI_PU, /* 0x2D 45. '-' */ + _ACPI_PU, /* 0x2E 46. '.' */ + _ACPI_PU, /* 0x2F 47. '/' */ + _ACPI_XD | _ACPI_DI, /* 0x30 48. '0' */ + _ACPI_XD | _ACPI_DI, /* 0x31 49. '1' */ + _ACPI_XD | _ACPI_DI, /* 0x32 50. '2' */ + _ACPI_XD | _ACPI_DI, /* 0x33 51. '3' */ + _ACPI_XD | _ACPI_DI, /* 0x34 52. '4' */ + _ACPI_XD | _ACPI_DI, /* 0x35 53. '5' */ + _ACPI_XD | _ACPI_DI, /* 0x36 54. '6' */ + _ACPI_XD | _ACPI_DI, /* 0x37 55. '7' */ + _ACPI_XD | _ACPI_DI, /* 0x38 56. '8' */ + _ACPI_XD | _ACPI_DI, /* 0x39 57. '9' */ + _ACPI_PU, /* 0x3A 58. ':' */ + _ACPI_PU, /* 0x3B 59. ';' */ + _ACPI_PU, /* 0x3C 60. '<' */ + _ACPI_PU, /* 0x3D 61. '=' */ + _ACPI_PU, /* 0x3E 62. '>' */ + _ACPI_PU, /* 0x3F 63. '?' */ + _ACPI_PU, /* 0x40 64. '@' */ + _ACPI_XD | _ACPI_UP, /* 0x41 65. 'A' */ + _ACPI_XD | _ACPI_UP, /* 0x42 66. 'B' */ + _ACPI_XD | _ACPI_UP, /* 0x43 67. 'C' */ + _ACPI_XD | _ACPI_UP, /* 0x44 68. 'D' */ + _ACPI_XD | _ACPI_UP, /* 0x45 69. 'E' */ + _ACPI_XD | _ACPI_UP, /* 0x46 70. 'F' */ + _ACPI_UP, /* 0x47 71. 'G' */ + _ACPI_UP, /* 0x48 72. 'H' */ + _ACPI_UP, /* 0x49 73. 'I' */ + _ACPI_UP, /* 0x4A 74. 'J' */ + _ACPI_UP, /* 0x4B 75. 'K' */ + _ACPI_UP, /* 0x4C 76. 'L' */ + _ACPI_UP, /* 0x4D 77. 'M' */ + _ACPI_UP, /* 0x4E 78. 'N' */ + _ACPI_UP, /* 0x4F 79. 'O' */ + _ACPI_UP, /* 0x50 80. 'P' */ + _ACPI_UP, /* 0x51 81. 'Q' */ + _ACPI_UP, /* 0x52 82. 'R' */ + _ACPI_UP, /* 0x53 83. 'S' */ + _ACPI_UP, /* 0x54 84. 'T' */ + _ACPI_UP, /* 0x55 85. 'U' */ + _ACPI_UP, /* 0x56 86. 'V' */ + _ACPI_UP, /* 0x57 87. 'W' */ + _ACPI_UP, /* 0x58 88. 'X' */ + _ACPI_UP, /* 0x59 89. 'Y' */ + _ACPI_UP, /* 0x5A 90. 'Z' */ + _ACPI_PU, /* 0x5B 91. '[' */ + _ACPI_PU, /* 0x5C 92. '\' */ + _ACPI_PU, /* 0x5D 93. ']' */ + _ACPI_PU, /* 0x5E 94. '^' */ + _ACPI_PU, /* 0x5F 95. '_' */ + _ACPI_PU, /* 0x60 96. '`' */ + _ACPI_XD | _ACPI_LO, /* 0x61 97. 'a' */ + _ACPI_XD | _ACPI_LO, /* 0x62 98. 'b' */ + _ACPI_XD | _ACPI_LO, /* 0x63 99. 'c' */ + _ACPI_XD | _ACPI_LO, /* 0x64 100. 'd' */ + _ACPI_XD | _ACPI_LO, /* 0x65 101. 'e' */ + _ACPI_XD | _ACPI_LO, /* 0x66 102. 'f' */ + _ACPI_LO, /* 0x67 103. 'g' */ + _ACPI_LO, /* 0x68 104. 'h' */ + _ACPI_LO, /* 0x69 105. 'i' */ + _ACPI_LO, /* 0x6A 106. 'j' */ + _ACPI_LO, /* 0x6B 107. 'k' */ + _ACPI_LO, /* 0x6C 108. 'l' */ + _ACPI_LO, /* 0x6D 109. 'm' */ + _ACPI_LO, /* 0x6E 110. 'n' */ + _ACPI_LO, /* 0x6F 111. 'o' */ + _ACPI_LO, /* 0x70 112. 'p' */ + _ACPI_LO, /* 0x71 113. 'q' */ + _ACPI_LO, /* 0x72 114. 'r' */ + _ACPI_LO, /* 0x73 115. 's' */ + _ACPI_LO, /* 0x74 116. 't' */ + _ACPI_LO, /* 0x75 117. 'u' */ + _ACPI_LO, /* 0x76 118. 'v' */ + _ACPI_LO, /* 0x77 119. 'w' */ + _ACPI_LO, /* 0x78 120. 'x' */ + _ACPI_LO, /* 0x79 121. 'y' */ + _ACPI_LO, /* 0x7A 122. 'z' */ + _ACPI_PU, /* 0x7B 123. '{' */ + _ACPI_PU, /* 0x7C 124. '|' */ + _ACPI_PU, /* 0x7D 125. '}' */ + _ACPI_PU, /* 0x7E 126. '~' */ + _ACPI_CN, /* 0x7F 127. */ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 to 0x8F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 to 0x9F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 to 0xAF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0 to 0xBF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 to 0xCF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 to 0xDF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0 to 0xEF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0 to 0x100 */ +}; + +#endif /* ACPI_USE_SYSTEM_CLIBRARY */ diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index e810894149a..6e3ae6a23f0 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -47,8 +47,9 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utdebug") + #ifdef ACPI_DEBUG_OUTPUT -static acpi_thread_id acpi_gbl_prev_thread_id; +static acpi_thread_id acpi_gbl_prev_thread_id = (acpi_thread_id) 0xFFFFFFFF; static char *acpi_gbl_fn_entry_str = "----Entry"; static char *acpi_gbl_fn_exit_str = "----Exit-"; @@ -109,7 +110,7 @@ void acpi_ut_track_stack_ptr(void) * RETURN: Updated pointer to the function name * * DESCRIPTION: Remove the "Acpi" prefix from the function name, if present. - * This allows compiler macros such as __func__ to be used + * This allows compiler macros such as __FUNCTION__ to be used * with no change to the debug output. * ******************************************************************************/ @@ -519,7 +520,7 @@ acpi_ut_ptr_exit(u32 line_number, * ******************************************************************************/ -void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) +void acpi_ut_dump_buffer2(u8 *buffer, u32 count, u32 display) { u32 i = 0; u32 j; @@ -636,7 +637,7 @@ void acpi_ut_dump_buffer2(u8 * buffer, u32 count, u32 display) * ******************************************************************************/ -void acpi_ut_dump_buffer(u8 * buffer, u32 count, u32 display, u32 component_id) +void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id) { /* Only dump the buffer if tracing is enabled */ diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index d91d88df2a9..0fed4bcc84b 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -41,8 +41,6 @@ * POSSIBILITY OF SUCH DAMAGES. */ -#include - #include #include "accommon.h" #include "acnamesp.h" @@ -201,8 +199,8 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) */ acpi_gbl_owner_id_mask[j] |= (1 << k); - acpi_gbl_last_owner_id_index = (u8) j; - acpi_gbl_next_owner_id_offset = (u8) (k + 1); + acpi_gbl_last_owner_id_index = (u8)j; + acpi_gbl_next_owner_id_offset = (u8)(k + 1); /* * Construct encoded ID from the index and bit position @@ -339,6 +337,73 @@ void acpi_ut_strupr(char *src_string) return; } +#ifdef ACPI_ASL_COMPILER +/******************************************************************************* + * + * FUNCTION: acpi_ut_strlwr (strlwr) + * + * PARAMETERS: src_string - The source string to convert + * + * RETURN: None + * + * DESCRIPTION: Convert string to lowercase + * + * NOTE: This is not a POSIX function, so it appears here, not in utclib.c + * + ******************************************************************************/ + +void acpi_ut_strlwr(char *src_string) +{ + char *string; + + ACPI_FUNCTION_ENTRY(); + + if (!src_string) { + return; + } + + /* Walk entire string, lowercasing the letters */ + + for (string = src_string; *string; string++) { + *string = (char)ACPI_TOLOWER(*string); + } + + return; +} + +/****************************************************************************** + * + * FUNCTION: acpi_ut_stricmp + * + * PARAMETERS: string1 - first string to compare + * string2 - second string to compare + * + * RETURN: int that signifies string relationship. Zero means strings + * are equal. + * + * DESCRIPTION: Implementation of the non-ANSI stricmp function (compare + * strings with no case sensitivity) + * + ******************************************************************************/ + +int acpi_ut_stricmp(char *string1, char *string2) +{ + int c1; + int c2; + + do { + c1 = tolower((int)*string1); + c2 = tolower((int)*string2); + + string1++; + string2++; + } + while ((c1 == c2) && (c1)); + + return (c1 - c2); +} +#endif + /******************************************************************************* * * FUNCTION: acpi_ut_print_string @@ -638,7 +703,16 @@ u8 acpi_ut_valid_acpi_name(u32 name) * RETURN: Repaired version of the name * * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and - * return the new name. + * return the new name. NOTE: the Name parameter must reside in + * read/write memory, cannot be a const. + * + * An ACPI Name must consist of valid ACPI characters. We will repair the name + * if necessary because we don't want to abort because of this, but we want + * all namespace names to be printable. A warning message is appropriate. + * + * This issue came up because there are in fact machines that exhibit + * this problem, and we want to be able to enable ACPI support for them, + * even though there are a few bad names. * ******************************************************************************/ @@ -699,7 +773,7 @@ void acpi_ut_repair_name(char *name) * ******************************************************************************/ -acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer) +acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer) { u32 this_digit = 0; u64 return_value = 0; @@ -772,14 +846,14 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer) /* Convert ASCII 0-9 to Decimal value */ - this_digit = ((u8) * string) - '0'; + this_digit = ((u8)*string) - '0'; } else if (base == 10) { /* Digit is out of range; possible in to_integer case only */ term = 1; } else { - this_digit = (u8) ACPI_TOUPPER(*string); + this_digit = (u8)ACPI_TOUPPER(*string); if (ACPI_IS_XDIGIT((char)this_digit)) { /* Convert ASCII Hex char to value */ @@ -806,8 +880,9 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer) valid_digits++; - if (sign_of0x && ((valid_digits > 16) - || ((valid_digits > 8) && mode32))) { + if (sign_of0x + && ((valid_digits > 16) + || ((valid_digits > 8) && mode32))) { /* * This is to_integer operation case. * No any restrictions for string-to-integer conversion, @@ -818,7 +893,7 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 * ret_integer) /* Divide the digit into the correct position */ - (void)acpi_ut_short_divide((dividend - (u64) this_digit), + (void)acpi_ut_short_divide((dividend - (u64)this_digit), base, "ient, NULL); if (return_value > quotient) { @@ -908,7 +983,7 @@ acpi_ut_create_update_state_and_push(union acpi_operand_object *object, ******************************************************************************/ acpi_status -acpi_ut_walk_package_tree(union acpi_operand_object * source_object, +acpi_ut_walk_package_tree(union acpi_operand_object *source_object, void *target_object, acpi_pkg_callback walk_callback, void *context) { diff --git a/drivers/acpi/acpica/uttrack.c b/drivers/acpi/acpica/uttrack.c new file mode 100644 index 00000000000..73ca27d40f9 --- /dev/null +++ b/drivers/acpi/acpica/uttrack.c @@ -0,0 +1,650 @@ +/****************************************************************************** + * + * Module Name: uttrack - Memory allocation tracking routines (debug only) + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2012, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +/* + * These procedures are used for tracking memory leaks in the subsystem, and + * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set. + * + * Each memory allocation is tracked via a doubly linked list. Each + * element contains the caller's component, module name, function name, and + * line number. acpi_ut_allocate and acpi_ut_allocate_zeroed call + * acpi_ut_track_allocation to add an element to the list; deletion + * occurs in the body of acpi_ut_free. + */ + +#include +#include "accommon.h" + +#ifdef ACPI_DBG_TRACK_ALLOCATIONS + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME("uttrack") + +/* Local prototypes */ +static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation); + +static acpi_status +acpi_ut_track_allocation(struct acpi_debug_mem_block *address, + acpi_size size, + u8 alloc_type, + u32 component, const char *module, u32 line); + +static acpi_status +acpi_ut_remove_allocation(struct acpi_debug_mem_block *address, + u32 component, const char *module, u32 line); + +/******************************************************************************* + * + * FUNCTION: acpi_ut_create_list + * + * PARAMETERS: cache_name - Ascii name for the cache + * object_size - Size of each cached object + * return_cache - Where the new cache object is returned + * + * RETURN: Status + * + * DESCRIPTION: Create a local memory list for tracking purposed + * + ******************************************************************************/ + +acpi_status +acpi_ut_create_list(char *list_name, + u16 object_size, struct acpi_memory_list **return_cache) +{ + struct acpi_memory_list *cache; + + cache = acpi_os_allocate(sizeof(struct acpi_memory_list)); + if (!cache) { + return (AE_NO_MEMORY); + } + + ACPI_MEMSET(cache, 0, sizeof(struct acpi_memory_list)); + + cache->list_name = list_name; + cache->object_size = object_size; + + *return_cache = cache; + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_allocate_and_track + * + * PARAMETERS: size - Size of the allocation + * component - Component type of caller + * module - Source file name of caller + * line - Line number of caller + * + * RETURN: Address of the allocated memory on success, NULL on failure. + * + * DESCRIPTION: The subsystem's equivalent of malloc. + * + ******************************************************************************/ + +void *acpi_ut_allocate_and_track(acpi_size size, + u32 component, const char *module, u32 line) +{ + struct acpi_debug_mem_block *allocation; + acpi_status status; + + allocation = + acpi_ut_allocate(size + sizeof(struct acpi_debug_mem_header), + component, module, line); + if (!allocation) { + return (NULL); + } + + status = acpi_ut_track_allocation(allocation, size, + ACPI_MEM_MALLOC, component, module, + line); + if (ACPI_FAILURE(status)) { + acpi_os_free(allocation); + return (NULL); + } + + acpi_gbl_global_list->total_allocated++; + acpi_gbl_global_list->total_size += (u32)size; + acpi_gbl_global_list->current_total_size += (u32)size; + if (acpi_gbl_global_list->current_total_size > + acpi_gbl_global_list->max_occupied) { + acpi_gbl_global_list->max_occupied = + acpi_gbl_global_list->current_total_size; + } + + return ((void *)&allocation->user_space); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_allocate_zeroed_and_track + * + * PARAMETERS: size - Size of the allocation + * component - Component type of caller + * module - Source file name of caller + * line - Line number of caller + * + * RETURN: Address of the allocated memory on success, NULL on failure. + * + * DESCRIPTION: Subsystem equivalent of calloc. + * + ******************************************************************************/ + +void *acpi_ut_allocate_zeroed_and_track(acpi_size size, + u32 component, + const char *module, u32 line) +{ + struct acpi_debug_mem_block *allocation; + acpi_status status; + + allocation = + acpi_ut_allocate_zeroed(size + sizeof(struct acpi_debug_mem_header), + component, module, line); + if (!allocation) { + + /* Report allocation error */ + + ACPI_ERROR((module, line, + "Could not allocate size %u", (u32)size)); + return (NULL); + } + + status = acpi_ut_track_allocation(allocation, size, + ACPI_MEM_CALLOC, component, module, + line); + if (ACPI_FAILURE(status)) { + acpi_os_free(allocation); + return (NULL); + } + + acpi_gbl_global_list->total_allocated++; + acpi_gbl_global_list->total_size += (u32)size; + acpi_gbl_global_list->current_total_size += (u32)size; + if (acpi_gbl_global_list->current_total_size > + acpi_gbl_global_list->max_occupied) { + acpi_gbl_global_list->max_occupied = + acpi_gbl_global_list->current_total_size; + } + + return ((void *)&allocation->user_space); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_free_and_track + * + * PARAMETERS: allocation - Address of the memory to deallocate + * component - Component type of caller + * module - Source file name of caller + * line - Line number of caller + * + * RETURN: None + * + * DESCRIPTION: Frees the memory at Allocation + * + ******************************************************************************/ + +void +acpi_ut_free_and_track(void *allocation, + u32 component, const char *module, u32 line) +{ + struct acpi_debug_mem_block *debug_block; + acpi_status status; + + ACPI_FUNCTION_TRACE_PTR(ut_free, allocation); + + if (NULL == allocation) { + ACPI_ERROR((module, line, "Attempt to delete a NULL address")); + + return_VOID; + } + + debug_block = ACPI_CAST_PTR(struct acpi_debug_mem_block, + (((char *)allocation) - + sizeof(struct acpi_debug_mem_header))); + + acpi_gbl_global_list->total_freed++; + acpi_gbl_global_list->current_total_size -= debug_block->size; + + status = acpi_ut_remove_allocation(debug_block, + component, module, line); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Could not free memory")); + } + + acpi_os_free(debug_block); + ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "%p freed\n", allocation)); + return_VOID; +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_find_allocation + * + * PARAMETERS: allocation - Address of allocated memory + * + * RETURN: A list element if found; NULL otherwise. + * + * DESCRIPTION: Searches for an element in the global allocation tracking list. + * + ******************************************************************************/ + +static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation) +{ + struct acpi_debug_mem_block *element; + + ACPI_FUNCTION_ENTRY(); + + element = acpi_gbl_global_list->list_head; + + /* Search for the address. */ + + while (element) { + if (element == allocation) { + return (element); + } + + element = element->next; + } + + return (NULL); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_track_allocation + * + * PARAMETERS: allocation - Address of allocated memory + * size - Size of the allocation + * alloc_type - MEM_MALLOC or MEM_CALLOC + * component - Component type of caller + * module - Source file name of caller + * line - Line number of caller + * + * RETURN: None. + * + * DESCRIPTION: Inserts an element into the global allocation tracking list. + * + ******************************************************************************/ + +static acpi_status +acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation, + acpi_size size, + u8 alloc_type, + u32 component, const char *module, u32 line) +{ + struct acpi_memory_list *mem_list; + struct acpi_debug_mem_block *element; + acpi_status status = AE_OK; + + ACPI_FUNCTION_TRACE_PTR(ut_track_allocation, allocation); + + if (acpi_gbl_disable_mem_tracking) { + return_ACPI_STATUS(AE_OK); + } + + mem_list = acpi_gbl_global_list; + status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* + * Search list for this address to make sure it is not already on the list. + * This will catch several kinds of problems. + */ + element = acpi_ut_find_allocation(allocation); + if (element) { + ACPI_ERROR((AE_INFO, + "UtTrackAllocation: Allocation already present in list! (%p)", + allocation)); + + ACPI_ERROR((AE_INFO, "Element %p Address %p", + element, allocation)); + + goto unlock_and_exit; + } + + /* Fill in the instance data. */ + + allocation->size = (u32)size; + allocation->alloc_type = alloc_type; + allocation->component = component; + allocation->line = line; + + ACPI_STRNCPY(allocation->module, module, ACPI_MAX_MODULE_NAME); + allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0; + + /* Insert at list head */ + + if (mem_list->list_head) { + ((struct acpi_debug_mem_block *)(mem_list->list_head))-> + previous = allocation; + } + + allocation->next = mem_list->list_head; + allocation->previous = NULL; + + mem_list->list_head = allocation; + + unlock_and_exit: + status = acpi_ut_release_mutex(ACPI_MTX_MEMORY); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_remove_allocation + * + * PARAMETERS: allocation - Address of allocated memory + * component - Component type of caller + * module - Source file name of caller + * line - Line number of caller + * + * RETURN: + * + * DESCRIPTION: Deletes an element from the global allocation tracking list. + * + ******************************************************************************/ + +static acpi_status +acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation, + u32 component, const char *module, u32 line) +{ + struct acpi_memory_list *mem_list; + acpi_status status; + + ACPI_FUNCTION_TRACE(ut_remove_allocation); + + if (acpi_gbl_disable_mem_tracking) { + return_ACPI_STATUS(AE_OK); + } + + mem_list = acpi_gbl_global_list; + if (NULL == mem_list->list_head) { + + /* No allocations! */ + + ACPI_ERROR((module, line, + "Empty allocation list, nothing to free!")); + + return_ACPI_STATUS(AE_OK); + } + + status = acpi_ut_acquire_mutex(ACPI_MTX_MEMORY); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Unlink */ + + if (allocation->previous) { + (allocation->previous)->next = allocation->next; + } else { + mem_list->list_head = allocation->next; + } + + if (allocation->next) { + (allocation->next)->previous = allocation->previous; + } + + /* Mark the segment as deleted */ + + ACPI_MEMSET(&allocation->user_space, 0xEA, allocation->size); + + ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Freeing size 0%X\n", + allocation->size)); + + status = acpi_ut_release_mutex(ACPI_MTX_MEMORY); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_dump_allocation_info + * + * PARAMETERS: + * + * RETURN: None + * + * DESCRIPTION: Print some info about the outstanding allocations. + * + ******************************************************************************/ + +void acpi_ut_dump_allocation_info(void) +{ +/* + struct acpi_memory_list *mem_list; +*/ + + ACPI_FUNCTION_TRACE(ut_dump_allocation_info); + +/* + ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, + ("%30s: %4d (%3d Kb)\n", "Current allocations", + mem_list->current_count, + ROUND_UP_TO_1K (mem_list->current_size))); + + ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, + ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations", + mem_list->max_concurrent_count, + ROUND_UP_TO_1K (mem_list->max_concurrent_size))); + + ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, + ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects", + running_object_count, + ROUND_UP_TO_1K (running_object_size))); + + ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, + ("%30s: %4d (%3d Kb)\n", "Total (all) allocations", + running_alloc_count, + ROUND_UP_TO_1K (running_alloc_size))); + + ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, + ("%30s: %4d (%3d Kb)\n", "Current Nodes", + acpi_gbl_current_node_count, + ROUND_UP_TO_1K (acpi_gbl_current_node_size))); + + ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES, + ("%30s: %4d (%3d Kb)\n", "Max Nodes", + acpi_gbl_max_concurrent_node_count, + ROUND_UP_TO_1K ((acpi_gbl_max_concurrent_node_count * + sizeof (struct acpi_namespace_node))))); +*/ + return_VOID; +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_dump_allocations + * + * PARAMETERS: component - Component(s) to dump info for. + * module - Module to dump info for. NULL means all. + * + * RETURN: None + * + * DESCRIPTION: Print a list of all outstanding allocations. + * + ******************************************************************************/ + +void acpi_ut_dump_allocations(u32 component, const char *module) +{ + struct acpi_debug_mem_block *element; + union acpi_descriptor *descriptor; + u32 num_outstanding = 0; + u8 descriptor_type; + + ACPI_FUNCTION_TRACE(ut_dump_allocations); + + if (acpi_gbl_disable_mem_tracking) { + return; + } + + /* + * Walk the allocation list. + */ + if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) { + return; + } + + element = acpi_gbl_global_list->list_head; + while (element) { + if ((element->component & component) && + ((module == NULL) + || (0 == ACPI_STRCMP(module, element->module)))) { + descriptor = + ACPI_CAST_PTR(union acpi_descriptor, + &element->user_space); + + if (element->size < + sizeof(struct acpi_common_descriptor)) { + acpi_os_printf("%p Length 0x%04X %9.9s-%u " + "[Not a Descriptor - too small]\n", + descriptor, element->size, + element->module, element->line); + } else { + /* Ignore allocated objects that are in a cache */ + + if (ACPI_GET_DESCRIPTOR_TYPE(descriptor) != + ACPI_DESC_TYPE_CACHED) { + acpi_os_printf + ("%p Length 0x%04X %9.9s-%u [%s] ", + descriptor, element->size, + element->module, element->line, + acpi_ut_get_descriptor_name + (descriptor)); + + /* Validate the descriptor type using Type field and length */ + + descriptor_type = 0; /* Not a valid descriptor type */ + + switch (ACPI_GET_DESCRIPTOR_TYPE + (descriptor)) { + case ACPI_DESC_TYPE_OPERAND: + if (element->size == + sizeof(union + acpi_operand_object)) + { + descriptor_type = + ACPI_DESC_TYPE_OPERAND; + } + break; + + case ACPI_DESC_TYPE_PARSER: + if (element->size == + sizeof(union + acpi_parse_object)) { + descriptor_type = + ACPI_DESC_TYPE_PARSER; + } + break; + + case ACPI_DESC_TYPE_NAMED: + if (element->size == + sizeof(struct + acpi_namespace_node)) + { + descriptor_type = + ACPI_DESC_TYPE_NAMED; + } + break; + + default: + break; + } + + /* Display additional info for the major descriptor types */ + + switch (descriptor_type) { + case ACPI_DESC_TYPE_OPERAND: + acpi_os_printf + ("%12.12s RefCount 0x%04X\n", + acpi_ut_get_type_name + (descriptor->object.common. + type), + descriptor->object.common. + reference_count); + break; + + case ACPI_DESC_TYPE_PARSER: + acpi_os_printf + ("AmlOpcode 0x%04hX\n", + descriptor->op.asl. + aml_opcode); + break; + + case ACPI_DESC_TYPE_NAMED: + acpi_os_printf("%4.4s\n", + acpi_ut_get_node_name + (&descriptor-> + node)); + break; + + default: + acpi_os_printf("\n"); + break; + } + } + } + + num_outstanding++; + } + + element = element->next; + } + + (void)acpi_ut_release_mutex(ACPI_MTX_MEMORY); + + /* Print summary */ + + if (!num_outstanding) { + ACPI_INFO((AE_INFO, "No outstanding allocations")); + } else { + ACPI_ERROR((AE_INFO, "%u(0x%X) Outstanding allocations", + num_outstanding, num_outstanding)); + } + + return_VOID; +} + +#endif /* ACPI_DBG_TRACK_ALLOCATIONS */ -- cgit v1.2.3 From f540fadf29a6987efbfa7daf10976935fd59ae7c Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 31 Oct 2012 02:25:15 +0000 Subject: ACPICA: Fix unmerged debugger divergences. Debugger improvements in ACPICA are always ignored by ACPICA Linux release. This will lead to divergences between Linux and ACPICA. This patch fixes such unmerged debugger updates. Following patches are included: 1. Fixed a couple compiler warnings for extra extern Wed, 14 Mar 2007 21:12:19 +0000 2. Cleanup for internal Reference Object. Wed, 27 Aug 2008 10:11:30 -0700 3. Debugger: Lock method args for multithread command. Fri, 24 Apr 2009 12:28:49 -0700 4. Debugger: Add max count argument for Batch command. Tue, 29 Sep 2009 12:31:58 -0700 5. Add new host interfaces for _OSI support. Thu, 5 Aug 2010 14:18:28 -0700 6. Increase debugger buffer size for method return objects. Wed, 17 Nov 2010 13:48:30 -0800 7. Debugger: Add command to display status of global handlers. Tue, 25 Jan 2011 13:47:58 -0800 8. Debugger: Split large dbcmds.c file. Wed, 26 Jan 2011 13:03:41 -0800 9. Debugger/AcpiExec: Add support to pass complex args to methods. Tue, 17 May 2011 13:33:39 -0700 10.Debugger: Add Template command to dump resource templates. Fri, 28 Oct 2011 14:18:51 -0700 11.Support for custom ACPICA build for ACPI 5.0 reduced hardware. Wed, 1 Feb 2012 13:18:17 -0800 12.Debugger: Improve command help support. Wed, 15 Feb 2012 07:59:26 -0800 13.Update ACPI_HW_DEPENDENT* macro invocations. Wed, 15 Feb 2012 08:14:08 -0800 14.Debugger: Rename function to simplify source code conversion. Wed, 13 Jun 2012 14:23:06 -0700 15.Debugger: Enhance "Tables" and "Unload" commands. Fri, 29 Jun 2012 13:10:58 -0700 16.Debugger: update prototype for AcpiDbSleep function. Fri, 17 Aug 2012 13:43:02 -0700 This patch will not affect the generated vmlinx binary. This will decrease 264 lines of 20120913 divergence.diff. Signed-off-by: Robert Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acdebug.h | 94 ++++++++++++++++++++++++++++-------------- drivers/acpi/acpica/acglobal.h | 69 ++++++++++++++++--------------- drivers/acpi/acpica/aclocal.h | 2 + include/acpi/acconfig.h | 1 + 4 files changed, 101 insertions(+), 65 deletions(-) diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 5e8abb07724..432a318c9ed 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -44,17 +44,28 @@ #ifndef __ACDEBUG_H__ #define __ACDEBUG_H__ -#define ACPI_DEBUG_BUFFER_SIZE 4196 +#define ACPI_DEBUG_BUFFER_SIZE 0x4000 /* 16K buffer for return objects */ -struct command_info { +struct acpi_db_command_info { char *name; /* Command Name */ u8 min_args; /* Minimum arguments required */ }; -struct argument_info { +struct acpi_db_command_help { + u8 line_count; /* Number of help lines */ + char *invocation; /* Command Invocation */ + char *description; /* Command Description */ +}; + +struct acpi_db_argument_info { char *name; /* Argument Name */ }; +struct acpi_db_execute_walk { + u32 count; + u32 max_count; +}; + #define PARAM_LIST(pl) pl #define DBTEST_OUTPUT_LEVEL(lvl) if (acpi_gbl_db_opt_verbose) #define VERBOSE_PRINT(fp) DBTEST_OUTPUT_LEVEL(lvl) {\ @@ -77,59 +88,71 @@ acpi_db_single_step(struct acpi_walk_state *walk_state, /* * dbcmds - debug commands and output routines */ -acpi_status acpi_db_disassemble_method(char *name); +struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string); void acpi_db_display_table_info(char *table_arg); -void acpi_db_unload_acpi_table(char *table_arg, char *instance_arg); +void acpi_db_display_template(char *buffer_arg); -void -acpi_db_set_method_breakpoint(char *location, - struct acpi_walk_state *walk_state, - union acpi_parse_object *op); +void acpi_db_unload_acpi_table(char *name); -void acpi_db_set_method_call_breakpoint(union acpi_parse_object *op); +void acpi_db_send_notify(char *name, u32 value); -void acpi_db_get_bus_info(void); +void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg); -void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op); +acpi_status acpi_db_sleep(char *object_arg); -void acpi_db_dump_namespace(char *start_arg, char *depth_arg); +void acpi_db_display_locks(void); -void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg); +void acpi_db_display_resources(char *object_arg); -void acpi_db_send_notify(char *name, u32 value); +ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_db_display_gpes(void)) + +void acpi_db_display_handlers(void); + +ACPI_HW_DEPENDENT_RETURN_VOID(void + acpi_db_generate_gpe(char *gpe_arg, + char *block_arg)) + +/* + * dbmethod - control method commands + */ +void +acpi_db_set_method_breakpoint(char *location, + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + +void acpi_db_set_method_call_breakpoint(union acpi_parse_object *op); void acpi_db_set_method_data(char *type_arg, char *index_arg, char *value_arg); -acpi_status -acpi_db_display_objects(char *obj_type_arg, char *display_count_arg); +acpi_status acpi_db_disassemble_method(char *name); -void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg); +void acpi_db_disassemble_aml(char *statements, union acpi_parse_object *op); -acpi_status acpi_db_find_name_in_namespace(char *name_arg); +void acpi_db_batch_execute(char *count_arg); +/* + * dbnames - namespace commands + */ void acpi_db_set_scope(char *name); -ACPI_HW_DEPENDENT_RETURN_OK(acpi_status acpi_db_sleep(char *object_arg)) +void acpi_db_dump_namespace(char *start_arg, char *depth_arg); -void acpi_db_find_references(char *object_arg); +void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg); -void acpi_db_display_locks(void); +acpi_status acpi_db_find_name_in_namespace(char *name_arg); -void acpi_db_display_resources(char *object_arg); +void acpi_db_check_predefined_names(void); -ACPI_HW_DEPENDENT_RETURN_VOID(void acpi_db_display_gpes(void)) +acpi_status +acpi_db_display_objects(char *obj_type_arg, char *display_count_arg); void acpi_db_check_integrity(void); -ACPI_HW_DEPENDENT_RETURN_VOID(void - acpi_db_generate_gpe(char *gpe_arg, - char *block_arg)) - -void acpi_db_check_predefined_names(void); +void acpi_db_find_references(char *object_arg); -void acpi_db_batch_execute(void); +void acpi_db_get_bus_info(void); /* * dbdisply - debug display commands @@ -161,7 +184,8 @@ acpi_db_display_argument_object(union acpi_operand_object *obj_desc, /* * dbexec - debugger control method execution */ -void acpi_db_execute(char *name, char **args, u32 flags); +void +acpi_db_execute(char *name, char **args, acpi_object_type * types, u32 flags); void acpi_db_create_execution_threads(char *num_threads_arg, @@ -175,7 +199,8 @@ u32 acpi_db_get_cache_info(struct acpi_memory_list *cache); * dbfileio - Debugger file I/O commands */ acpi_object_type -acpi_db_match_argument(char *user_argument, struct argument_info *arguments); +acpi_db_match_argument(char *user_argument, + struct acpi_db_argument_info *arguments); void acpi_db_close_debug_file(void); @@ -208,6 +233,11 @@ acpi_db_command_dispatch(char *input_buffer, void ACPI_SYSTEM_XFACE acpi_db_execute_thread(void *context); +acpi_status acpi_db_user_commands(char prompt, union acpi_parse_object *op); + +char *acpi_db_get_next_token(char *string, + char **next, acpi_object_type * return_type); + /* * dbstats - Generation and display of ACPI table statistics */ diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index ce79100fb5e..fe20e186ca1 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -153,26 +153,6 @@ u8 acpi_gbl_reduced_hardware; ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_no_resource_disassembly, FALSE); -/***************************************************************************** - * - * Debug support - * - ****************************************************************************/ - -/* Procedure nesting level for debug output */ - -extern u32 acpi_gbl_nesting_level; - -ACPI_EXTERN u32 acpi_gpe_count; -ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS]; - -/* Support for dynamic control method tracing mechanism */ - -ACPI_EXTERN u32 acpi_gbl_original_dbg_level; -ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; -ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; -ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; - /***************************************************************************** * * ACPI Table globals @@ -259,15 +239,6 @@ ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE reg * ****************************************************************************/ -#ifdef ACPI_DBG_TRACK_ALLOCATIONS - -/* Lists for tracking memory allocations */ - -ACPI_EXTERN struct acpi_memory_list *acpi_gbl_global_list; -ACPI_EXTERN struct acpi_memory_list *acpi_gbl_ns_node_list; -ACPI_EXTERN u8 acpi_gbl_display_final_mem_stats; -#endif - /* Object caches */ ACPI_EXTERN acpi_cache_t *acpi_gbl_namespace_cache; @@ -326,6 +297,15 @@ extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; #endif +#ifdef ACPI_DBG_TRACK_ALLOCATIONS + +/* Lists for tracking memory allocations */ + +ACPI_EXTERN struct acpi_memory_list *acpi_gbl_global_list; +ACPI_EXTERN struct acpi_memory_list *acpi_gbl_ns_node_list; +ACPI_EXTERN u8 acpi_gbl_display_final_mem_stats; +#endif + /***************************************************************************** * * Namespace globals @@ -401,6 +381,28 @@ ACPI_EXTERN void *acpi_gbl_global_event_handler_context; #endif /* !ACPI_REDUCED_HARDWARE */ +/***************************************************************************** + * + * Debug support + * + ****************************************************************************/ + +/* Procedure nesting level for debug output */ + +extern u32 acpi_gbl_nesting_level; + +/* Event counters */ + +ACPI_EXTERN u32 acpi_gpe_count; +ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS]; + +/* Support for dynamic control method tracing mechanism */ + +ACPI_EXTERN u32 acpi_gbl_original_dbg_level; +ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; +ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; +ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; + /***************************************************************************** * * Debugger globals @@ -426,10 +428,11 @@ ACPI_EXTERN u8 acpi_gbl_db_opt_stats; ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; ACPI_EXTERN char *acpi_gbl_db_args[ACPI_DEBUGGER_MAX_ARGS]; -ACPI_EXTERN char acpi_gbl_db_line_buf[80]; -ACPI_EXTERN char acpi_gbl_db_parsed_buf[80]; -ACPI_EXTERN char acpi_gbl_db_scope_buf[40]; -ACPI_EXTERN char acpi_gbl_db_debug_filename[40]; +ACPI_EXTERN acpi_object_type acpi_gbl_db_arg_types[ACPI_DEBUGGER_MAX_ARGS]; +ACPI_EXTERN char acpi_gbl_db_line_buf[ACPI_DB_LINE_BUFFER_SIZE]; +ACPI_EXTERN char acpi_gbl_db_parsed_buf[ACPI_DB_LINE_BUFFER_SIZE]; +ACPI_EXTERN char acpi_gbl_db_scope_buf[80]; +ACPI_EXTERN char acpi_gbl_db_debug_filename[80]; ACPI_EXTERN u8 acpi_gbl_db_output_to_file; ACPI_EXTERN char *acpi_gbl_db_buffer; ACPI_EXTERN char *acpi_gbl_db_filename; diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index c816ee67509..b5a4651cf2b 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -1031,6 +1031,7 @@ struct acpi_db_method_info { acpi_handle method; acpi_handle main_thread_gate; acpi_handle thread_complete_gate; + acpi_handle info_gate; acpi_thread_id *threads; u32 num_threads; u32 num_created; @@ -1041,6 +1042,7 @@ struct acpi_db_method_info { u32 num_loops; char pathname[128]; char **args; + acpi_object_type *types; /* * Arguments to be passed to method for the command diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index 03f14856bd0..0943457e0fa 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -241,6 +241,7 @@ *****************************************************************************/ #define ACPI_DEBUGGER_MAX_ARGS 8 /* Must be max method args + 1 */ +#define ACPI_DB_LINE_BUFFER_SIZE 512 #define ACPI_DEBUGGER_COMMAND_PROMPT '-' #define ACPI_DEBUGGER_EXECUTE_PROMPT '%' -- cgit v1.2.3 From 78e25fef2751434f38c7f711ecbf8762f79f7318 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 31 Oct 2012 02:25:24 +0000 Subject: ACPICA: Fix divergences of definition conflicts. There are conflicts in the "acpi_device_id*" definitions between the Linux and the ACPICA. The definitions of acpi_device_id* in ACPICA have been changed to the "acpi_pnp_device_id*". This patch changes the corresponding "acpica_device_id*" definitiions in the Linux. This patch will not affect the generated vmlinx binary. This will decrease 298 lines of 20120913 divergence.diff. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acutils.h | 6 +++--- drivers/acpi/acpica/evrgnini.c | 4 ++-- drivers/acpi/acpica/nsxfeval.c | 4 ++-- drivers/acpi/acpica/nsxfname.c | 28 ++++++++++++++-------------- drivers/acpi/acpica/utids.c | 37 ++++++++++++++++++++----------------- drivers/acpi/scan.c | 2 +- include/acpi/actypes.h | 12 ++++++------ 7 files changed, 48 insertions(+), 45 deletions(-) diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 82d6025332e..d94b4177657 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -355,15 +355,15 @@ acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, */ acpi_status acpi_ut_execute_HID(struct acpi_namespace_node *device_node, - struct acpica_device_id ** return_id); + struct acpi_pnp_device_id ** return_id); acpi_status acpi_ut_execute_UID(struct acpi_namespace_node *device_node, - struct acpica_device_id ** return_id); + struct acpi_pnp_device_id ** return_id); acpi_status acpi_ut_execute_CID(struct acpi_namespace_node *device_node, - struct acpica_device_id_list ** return_cid_list); + struct acpi_pnp_device_id_list ** return_cid_list); /* * utlock - reader/writer locks diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 4c1c8261166..6786f00042c 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -350,8 +350,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) { acpi_status status; - struct acpica_device_id *hid; - struct acpica_device_id_list *cid; + struct acpi_pnp_device_id *hid; + struct acpi_pnp_device_id_list *cid; u32 i; u8 match; diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index 9692e670233..494f2ebd623 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -542,8 +542,8 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, acpi_status status; struct acpi_namespace_node *node; u32 flags; - struct acpica_device_id *hid; - struct acpica_device_id_list *cid; + struct acpi_pnp_device_id *hid; + struct acpi_pnp_device_id_list *cid; u32 i; u8 found; int no_match; diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 08e9610b34c..7bc4985146f 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -53,8 +53,8 @@ ACPI_MODULE_NAME("nsxfname") /* Local prototypes */ -static char *acpi_ns_copy_device_id(struct acpica_device_id *dest, - struct acpica_device_id *source, +static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest, + struct acpi_pnp_device_id *source, char *string_area); /****************************************************************************** @@ -219,20 +219,20 @@ ACPI_EXPORT_SYMBOL(acpi_get_name) * * FUNCTION: acpi_ns_copy_device_id * - * PARAMETERS: dest - Pointer to the destination DEVICE_ID - * source - Pointer to the source DEVICE_ID + * PARAMETERS: dest - Pointer to the destination PNP_DEVICE_ID + * source - Pointer to the source PNP_DEVICE_ID * string_area - Pointer to where to copy the dest string * * RETURN: Pointer to the next string area * - * DESCRIPTION: Copy a single DEVICE_ID, including the string data. + * DESCRIPTION: Copy a single PNP_DEVICE_ID, including the string data. * ******************************************************************************/ -static char *acpi_ns_copy_device_id(struct acpica_device_id *dest, - struct acpica_device_id *source, +static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest, + struct acpi_pnp_device_id *source, char *string_area) { - /* Create the destination DEVICE_ID */ + /* Create the destination PNP_DEVICE_ID */ dest->string = string_area; dest->length = source->length; @@ -269,9 +269,9 @@ acpi_get_object_info(acpi_handle handle, { struct acpi_namespace_node *node; struct acpi_device_info *info; - struct acpica_device_id_list *cid_list = NULL; - struct acpica_device_id *hid = NULL; - struct acpica_device_id *uid = NULL; + struct acpi_pnp_device_id_list *cid_list = NULL; + struct acpi_pnp_device_id *hid = NULL; + struct acpi_pnp_device_id *uid = NULL; char *next_id_string; acpi_object_type type; acpi_name name; @@ -348,7 +348,7 @@ acpi_get_object_info(acpi_handle handle, info_size += (cid_list->list_size - - sizeof(struct acpica_device_id_list)); + sizeof(struct acpi_pnp_device_id_list)); valid |= ACPI_VALID_CID; } } @@ -418,11 +418,11 @@ acpi_get_object_info(acpi_handle handle, next_id_string = ACPI_CAST_PTR(char, info->compatible_id_list.ids); if (cid_list) { - /* Point past the CID DEVICE_ID array */ + /* Point past the CID PNP_DEVICE_ID array */ next_id_string += ((acpi_size) cid_list->count * - sizeof(struct acpica_device_id)); + sizeof(struct acpi_pnp_device_id)); } /* diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index 5d84e195457..f18ac81c839 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c @@ -67,10 +67,10 @@ ACPI_MODULE_NAME("utids") ******************************************************************************/ acpi_status acpi_ut_execute_HID(struct acpi_namespace_node *device_node, - struct acpica_device_id **return_id) + struct acpi_pnp_device_id **return_id) { union acpi_operand_object *obj_desc; - struct acpica_device_id *hid; + struct acpi_pnp_device_id *hid; u32 length; acpi_status status; @@ -94,16 +94,17 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node, /* Allocate a buffer for the HID */ hid = - ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) + + ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) + (acpi_size) length); if (!hid) { status = AE_NO_MEMORY; goto cleanup; } - /* Area for the string starts after DEVICE_ID struct */ + /* Area for the string starts after PNP_DEVICE_ID struct */ - hid->string = ACPI_ADD_PTR(char, hid, sizeof(struct acpica_device_id)); + hid->string = + ACPI_ADD_PTR(char, hid, sizeof(struct acpi_pnp_device_id)); /* Convert EISAID to a string or simply copy existing string */ @@ -144,10 +145,10 @@ cleanup: acpi_status acpi_ut_execute_UID(struct acpi_namespace_node *device_node, - struct acpica_device_id **return_id) + struct acpi_pnp_device_id **return_id) { union acpi_operand_object *obj_desc; - struct acpica_device_id *uid; + struct acpi_pnp_device_id *uid; u32 length; acpi_status status; @@ -171,16 +172,17 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node, /* Allocate a buffer for the UID */ uid = - ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) + + ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) + (acpi_size) length); if (!uid) { status = AE_NO_MEMORY; goto cleanup; } - /* Area for the string starts after DEVICE_ID struct */ + /* Area for the string starts after PNP_DEVICE_ID struct */ - uid->string = ACPI_ADD_PTR(char, uid, sizeof(struct acpica_device_id)); + uid->string = + ACPI_ADD_PTR(char, uid, sizeof(struct acpi_pnp_device_id)); /* Convert an Integer to string, or just copy an existing string */ @@ -226,11 +228,11 @@ cleanup: acpi_status acpi_ut_execute_CID(struct acpi_namespace_node *device_node, - struct acpica_device_id_list **return_cid_list) + struct acpi_pnp_device_id_list **return_cid_list) { union acpi_operand_object **cid_objects; union acpi_operand_object *obj_desc; - struct acpica_device_id_list *cid_list; + struct acpi_pnp_device_id_list *cid_list; char *next_id_string; u32 string_area_size; u32 length; @@ -288,11 +290,12 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node, /* * Now that we know the length of the CIDs, allocate return buffer: * 1) Size of the base structure + - * 2) Size of the CID DEVICE_ID array + + * 2) Size of the CID PNP_DEVICE_ID array + * 3) Size of the actual CID strings */ - cid_list_size = sizeof(struct acpica_device_id_list) + - ((count - 1) * sizeof(struct acpica_device_id)) + string_area_size; + cid_list_size = sizeof(struct acpi_pnp_device_id_list) + + ((count - 1) * sizeof(struct acpi_pnp_device_id)) + + string_area_size; cid_list = ACPI_ALLOCATE_ZEROED(cid_list_size); if (!cid_list) { @@ -300,10 +303,10 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node, goto cleanup; } - /* Area for CID strings starts after the CID DEVICE_ID array */ + /* Area for CID strings starts after the CID PNP_DEVICE_ID array */ next_id_string = ACPI_CAST_PTR(char, cid_list->ids) + - ((acpi_size) count * sizeof(struct acpica_device_id)); + ((acpi_size) count * sizeof(struct acpi_pnp_device_id)); /* Copy/convert the CIDs to the return buffer */ diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 1fcb8678665..db127100bd9 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1185,7 +1185,7 @@ static void acpi_device_set_id(struct acpi_device *device) { acpi_status status; struct acpi_device_info *info; - struct acpica_device_id_list *cid_list; + struct acpi_pnp_device_id_list *cid_list; int i; switch (device->device_type) { diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index a85bae96826..7520f420e4e 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -1020,15 +1020,15 @@ u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported); /* Structures used for device/processor HID, UID, CID */ -struct acpica_device_id { +struct acpi_pnp_device_id { u32 length; /* Length of string + null */ char *string; }; -struct acpica_device_id_list { +struct acpi_pnp_device_id_list { u32 count; /* Number of IDs in Ids array */ u32 list_size; /* Size of list, including ID strings */ - struct acpica_device_id ids[1]; /* ID array */ + struct acpi_pnp_device_id ids[1]; /* ID array */ }; /* @@ -1046,9 +1046,9 @@ struct acpi_device_info { u8 lowest_dstates[5]; /* _sx_w values: 0xFF indicates not valid */ u32 current_status; /* _STA value */ u64 address; /* _ADR value */ - struct acpica_device_id hardware_id; /* _HID value */ - struct acpica_device_id unique_id; /* _UID value */ - struct acpica_device_id_list compatible_id_list; /* _CID list */ + struct acpi_pnp_device_id hardware_id; /* _HID value */ + struct acpi_pnp_device_id unique_id; /* _UID value */ + struct acpi_pnp_device_id_list compatible_id_list; /* _CID list */ }; /* Values for Flags field above (acpi_get_object_info) */ -- cgit v1.2.3 From 644ef74e6d187ca2e8a23ff41a513964de36f93e Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 31 Oct 2012 02:25:36 +0000 Subject: ACPICA: Fix AcpiSrc caused divergences. There are definitions that can been converted into new styles by the recent AcpiSrc while they remain the old styles in the Linux. This patch fixes those definitions that will be converted by the AcpiSrc. This patch will not affect the generated vmlinux binary. This will decrease 97 lines of 20120913 divergence.diff. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 2 +- drivers/acpi/acpica/aclocal.h | 4 ++-- drivers/acpi/acpica/acobject.h | 2 +- drivers/acpi/acpica/dswexec.c | 2 +- drivers/acpi/acpica/evxface.c | 2 +- drivers/acpi/sysfs.c | 4 ++-- include/acpi/acpixf.h | 2 +- include/acpi/actypes.h | 8 ++++---- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index fe20e186ca1..35006d193d5 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -376,7 +376,7 @@ ACPI_EXTERN struct acpi_gpe_block_info #if (!ACPI_REDUCED_HARDWARE) ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized; -ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler; +ACPI_EXTERN acpi_gbl_event_handler acpi_gbl_global_event_handler; ACPI_EXTERN void *acpi_gbl_global_event_handler_context; #endif /* !ACPI_REDUCED_HARDWARE */ diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index b5a4651cf2b..564f2abf590 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -262,7 +262,7 @@ struct acpi_create_field_info { }; typedef -acpi_status(*ACPI_INTERNAL_METHOD) (struct acpi_walk_state * walk_state); +acpi_status(*acpi_internal_method) (struct acpi_walk_state * walk_state); /* * Bitmapped ACPI types. Used internally only @@ -645,7 +645,7 @@ union acpi_generic_state { * ****************************************************************************/ -typedef acpi_status(*ACPI_EXECUTE_OP) (struct acpi_walk_state * walk_state); +typedef acpi_status(*acpi_execute_op) (struct acpi_walk_state * walk_state); /* Address Range info block */ diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 364a1303fb8..ac4269fb1a3 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -179,7 +179,7 @@ struct acpi_object_method { union acpi_operand_object *mutex; u8 *aml_start; union { - ACPI_INTERNAL_METHOD implementation; + acpi_internal_method implementation; union acpi_operand_object *handler; } dispatch; diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index 642f3c053e8..fa44609aba3 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c @@ -57,7 +57,7 @@ ACPI_MODULE_NAME("dswexec") /* * Dispatch table for opcode classes */ -static ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch[] = { +static acpi_execute_op acpi_gbl_op_type_dispatch[] = { acpi_ex_opcode_0A_0T_1R, acpi_ex_opcode_1A_0T_0R, acpi_ex_opcode_1A_0T_1R, diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 7587eb6c958..ae668f32cf1 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -398,7 +398,7 @@ ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) * ******************************************************************************/ acpi_status -acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context) +acpi_install_global_event_handler(acpi_gbl_event_handler handler, void *context) { acpi_status status; diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 7c3f98ba4af..ea61ca9129c 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -476,7 +476,7 @@ static void fixed_event_count(u32 event_number) return; } -static void acpi_gbl_event_handler(u32 event_type, acpi_handle device, +static void acpi_global_event_handler(u32 event_type, acpi_handle device, u32 event_number, void *context) { if (event_type == ACPI_EVENT_TYPE_GPE) @@ -638,7 +638,7 @@ void acpi_irq_stats_init(void) if (all_counters == NULL) goto fail; - status = acpi_install_global_event_handler(acpi_gbl_event_handler, NULL); + status = acpi_install_global_event_handler(acpi_global_event_handler, NULL); if (ACPI_FAILURE(status)) goto fail; diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 8b891dbead6..352fd1a3832 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -274,7 +274,7 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function); ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_install_global_event_handler - (ACPI_GBL_EVENT_HANDLER handler, void *context)) + (acpi_gbl_event_handler handler, void *context)) ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status acpi_install_fixed_event_handler(u32 diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 7520f420e4e..ea50a314e55 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -796,11 +796,11 @@ typedef u8 acpi_adr_space_type; /* Sleep function dispatch */ -typedef acpi_status(*ACPI_SLEEP_FUNCTION) (u8 sleep_state); +typedef acpi_status(*acpi_sleep_function) (u8 sleep_state); struct acpi_sleep_functions { - ACPI_SLEEP_FUNCTION legacy_function; - ACPI_SLEEP_FUNCTION extended_function; + acpi_sleep_function legacy_function; + acpi_sleep_function extended_function; }; /* @@ -931,7 +931,7 @@ typedef void * Various handlers and callback procedures */ typedef -void (*ACPI_GBL_EVENT_HANDLER) (u32 event_type, +void (*acpi_gbl_event_handler) (u32 event_type, acpi_handle device, u32 event_number, void *context); -- cgit v1.2.3 From 1f86e8c1c9f129d450fd75e42d25ddba69a522ac Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 31 Oct 2012 02:25:45 +0000 Subject: ACPICA: Fix indent caused divergences. New version of "indent" program will generate different outputs that will lead to the divergences between the Linux and the ACPICA. This patch fixes such divergences caused by the "indent" program. The version of the "indent" used for this patch is "GNU indent 2.2.11". This patch will not affect the generated vmlinux binary. This will decrease 581 lines of 20120913 divergence.diff. Signed-off-by: Robert Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acdispat.h | 11 +++++++---- drivers/acpi/acpica/acevents.h | 6 ++++-- drivers/acpi/acpica/aclocal.h | 6 ++++-- drivers/acpi/acpica/acparser.h | 3 +-- drivers/acpi/acpica/acpredef.h | 11 ++++++----- drivers/acpi/acpica/dsopcode.c | 3 ++- drivers/acpi/acpica/dsutils.c | 3 ++- drivers/acpi/acpica/dswstate.c | 14 +++++++++----- drivers/acpi/acpica/evgpe.c | 20 ++++++++++++-------- drivers/acpi/acpica/evgpeblk.c | 3 ++- drivers/acpi/acpica/evgpeutil.c | 3 ++- drivers/acpi/acpica/evrgnini.c | 3 +-- drivers/acpi/acpica/evxfgpe.c | 9 +++++---- drivers/acpi/acpica/exconvrt.c | 4 ++-- drivers/acpi/acpica/excreate.c | 3 +-- drivers/acpi/acpica/exdump.c | 9 ++++++--- drivers/acpi/acpica/exfldio.c | 3 +-- drivers/acpi/acpica/exnames.c | 6 +++--- drivers/acpi/acpica/exresop.c | 3 ++- drivers/acpi/acpica/hwgpe.c | 3 ++- drivers/acpi/acpica/hwtimer.c | 3 +-- drivers/acpi/acpica/hwxfsleep.c | 12 ++++-------- drivers/acpi/acpica/nsaccess.c | 3 +-- drivers/acpi/acpica/nsinit.c | 4 ++-- drivers/acpi/acpica/psopcode.c | 23 ++++++++++++++--------- drivers/acpi/acpica/psparse.c | 5 +++-- drivers/acpi/acpica/rscalc.c | 3 +-- include/acpi/acpixf.h | 13 +++++-------- include/acpi/actypes.h | 6 ++++-- 29 files changed, 109 insertions(+), 89 deletions(-) diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h index 5935ba6707e..ed33ebcdaeb 100644 --- a/drivers/acpi/acpica/acdispat.h +++ b/drivers/acpi/acpica/acdispat.h @@ -309,10 +309,13 @@ acpi_ds_obj_stack_push(void *object, struct acpi_walk_state *walk_state); acpi_status acpi_ds_obj_stack_pop(u32 pop_count, struct acpi_walk_state *walk_state); -struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union acpi_parse_object - *origin, union acpi_operand_object - *mth_desc, struct acpi_thread_state - *thread); +struct acpi_walk_state * acpi_ds_create_walk_state(acpi_owner_id owner_id, + union acpi_parse_object + *origin, + union acpi_operand_object + *mth_desc, + struct acpi_thread_state + *thread); acpi_status acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state, diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index c0a43b38c6a..e975c672044 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -84,9 +84,11 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info); acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); -acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info); +acpi_status +acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info); -acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info); +acpi_status +acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info); struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, u32 gpe_number); diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 564f2abf590..5b5be40a199 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -486,8 +486,10 @@ struct acpi_gpe_device_info { struct acpi_namespace_node *gpe_device; }; -typedef acpi_status(*acpi_gpe_callback) (struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block, void *context); +typedef acpi_status(*acpi_gpe_callback) (struct acpi_gpe_xrupt_info * + gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block, + void *context); /* Information about each particular fixed event */ diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index b725d780d34..eefcf47a61a 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h @@ -150,8 +150,7 @@ u8 acpi_ps_has_completed_scope(struct acpi_parse_state *parser_state); void acpi_ps_pop_scope(struct acpi_parse_state *parser_state, - union acpi_parse_object **op, - u32 * arg_list, u32 * arg_count); + union acpi_parse_object **op, u32 *arg_list, u32 *arg_count); acpi_status acpi_ps_push_scope(struct acpi_parse_state *parser_state, diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 3080c017f5b..9dfa1c83bd4 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -150,8 +150,7 @@ enum acpi_return_package_types { * is saved here (rather than in a separate table) in order to minimize the * overall size of the stored data. */ -static const union acpi_predefined_info predefined_names[] = -{ +static const union acpi_predefined_info predefined_names[] = { {{"_AC0", 0, ACPI_RTYPE_INTEGER}}, {{"_AC1", 0, ACPI_RTYPE_INTEGER}}, {{"_AC2", 0, ACPI_RTYPE_INTEGER}}, @@ -538,7 +537,8 @@ static const union acpi_predefined_info predefined_names[] = /* Acpi 1.0 defined _WAK with no return value. Later, it was changed to return a package */ - {{"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}}, + {{"_WAK", 1, + ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}}, {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, /* Fixed-length (2 Int), but is optional */ /* _WDG/_WED are MS extensions defined by "Windows Instrumentation" */ @@ -551,11 +551,12 @@ static const union acpi_predefined_info predefined_names[] = }; #if 0 + /* This is an internally implemented control method, no need to check */ - {{"_OSI", 1, ACPI_RTYPE_INTEGER}}, +{ { +"_OSI", 1, ACPI_RTYPE_INTEGER}}, /* TBD: */ - _PRT - currently ignore reversed entries. attempt to fix here? think about possibly fixing package elements like _BIF, etc. #endif diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index aa34d8984d3..0df024e5fb6 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -649,7 +649,8 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) && (op->common.parent->common.aml_opcode != AML_VAR_PACKAGE_OP) - && (op->common.parent->common.aml_opcode != AML_NAME_OP))) { + && (op->common.parent->common.aml_opcode != + AML_NAME_OP))) { walk_state->result_obj = obj_desc; } } diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index 73a5447475f..4bbdd6c7a3d 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c @@ -560,7 +560,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, * indicate this to the interpreter, set the * object to the root */ - obj_desc = ACPI_CAST_PTR(union + obj_desc = + ACPI_CAST_PTR(union acpi_operand_object, acpi_gbl_root_node); status = AE_OK; diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index d0e6555061e..9bb7fa45e24 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c @@ -51,8 +51,9 @@ ACPI_MODULE_NAME("dswstate") /* Local prototypes */ -static acpi_status acpi_ds_result_stack_push(struct acpi_walk_state *ws); -static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *ws); +static acpi_status +acpi_ds_result_stack_push(struct acpi_walk_state *walk_state); +static acpi_status acpi_ds_result_stack_pop(struct acpi_walk_state *walk_state); /******************************************************************************* * @@ -536,9 +537,12 @@ struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state *thread) * ******************************************************************************/ -struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, union acpi_parse_object - *origin, union acpi_operand_object - *method_desc, struct acpi_thread_state +struct acpi_walk_state *acpi_ds_create_walk_state(acpi_owner_id owner_id, + union acpi_parse_object + *origin, + union acpi_operand_object + *method_desc, + struct acpi_thread_state *thread) { struct acpi_walk_state *walk_state; diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index ef0193d74b5..36d12057442 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -89,7 +89,8 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info) /* Set the mask bit only if there are references to this GPE */ if (gpe_event_info->runtime_count) { - ACPI_SET_BIT(gpe_register_info->enable_for_run, (u8)register_bit); + ACPI_SET_BIT(gpe_register_info->enable_for_run, + (u8)register_bit); } return_ACPI_STATUS(AE_OK); @@ -106,8 +107,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info) * DESCRIPTION: Clear a GPE of stale events and enable it. * ******************************************************************************/ -acpi_status -acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) +acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) { acpi_status status; @@ -131,8 +131,8 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) } /* Enable the requested GPE */ - status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); return_ACPI_STATUS(status); } @@ -150,7 +150,8 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) * ******************************************************************************/ -acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info) +acpi_status +acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info) { acpi_status status = AE_OK; @@ -191,7 +192,8 @@ acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info * ******************************************************************************/ -acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info) +acpi_status +acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info) { acpi_status status = AE_OK; @@ -208,7 +210,8 @@ acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_i status = acpi_ev_update_gpe_enable_mask(gpe_event_info); if (ACPI_SUCCESS(status)) { - status = acpi_hw_low_set_gpe(gpe_event_info, + status = + acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); } @@ -306,7 +309,8 @@ struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, /* A Non-NULL gpe_device means this is a GPE Block Device */ - obj_desc = acpi_ns_get_attached_object((struct acpi_namespace_node *) + obj_desc = + acpi_ns_get_attached_object((struct acpi_namespace_node *) gpe_device); if (!obj_desc || !obj_desc->device.gpe_block) { return (NULL); diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 8cf4c104c7b..1571a61a783 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -486,7 +486,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Could not enable GPE 0x%02X", - gpe_index + gpe_block->block_base_number)); + gpe_index + + gpe_block->block_base_number)); continue; } diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c index cb50dd91bc1..228a0c3b1d4 100644 --- a/drivers/acpi/acpica/evgpeutil.c +++ b/drivers/acpi/acpica/evgpeutil.c @@ -374,7 +374,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info, gpe_event_info->dispatch.handler = NULL; gpe_event_info->flags &= ~ACPI_GPE_DISPATCH_MASK; - } else if ((gpe_event_info-> + } else + if ((gpe_event_info-> flags & ACPI_GPE_DISPATCH_MASK) == ACPI_GPE_DISPATCH_NOTIFY) { diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 6786f00042c..1474241bfc7 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -227,8 +227,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, /* Install a handler for this PCI root bridge */ - status = - acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); + status = acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); if (ACPI_FAILURE(status)) { if (status == AE_SAME_HANDLER) { /* diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 87c5f233226..d36f9973937 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -221,7 +221,8 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, if (wake_device == ACPI_ROOT_OBJECT) { device_node = acpi_gbl_root_node; } else { - device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); + device_node = + ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); } /* Validate WakeDevice is of type Device */ @@ -324,7 +325,8 @@ ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake) * ******************************************************************************/ -acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action) +acpi_status +acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action) { acpi_status status = AE_OK; struct acpi_gpe_event_info *gpe_event_info; @@ -694,8 +696,7 @@ ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) * the FADT-defined gpe blocks. Otherwise, the GPE block device. * ******************************************************************************/ -acpi_status -acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) +acpi_status acpi_get_gpe_device(u32 index, acpi_handle * gpe_device) { struct acpi_gpe_device_info info; acpi_status status; diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index bfb062e4c4b..4492a4e0302 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c @@ -516,8 +516,8 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc, string_length--; } - return_desc = acpi_ut_create_string_object((acpi_size) - string_length); + return_desc = + acpi_ut_create_string_object((acpi_size) string_length); if (!return_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index 691d4763102..9f152701bc0 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c @@ -243,8 +243,7 @@ acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state) /* Init object and attach to NS node */ - obj_desc->mutex.sync_level = - (u8) walk_state->operands[1]->integer.value; + obj_desc->mutex.sync_level = (u8)walk_state->operands[1]->integer.value; obj_desc->mutex.node = (struct acpi_namespace_node *)walk_state->operands[0]; diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 213c081776f..40608b3e28f 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -464,7 +464,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) ACPI_FUNCTION_NAME(ex_dump_operand) - if (!((ACPI_LV_EXEC & acpi_dbg_level) + if (! + ((ACPI_LV_EXEC & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) { return; } @@ -810,7 +811,8 @@ void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags) ACPI_FUNCTION_ENTRY(); if (!flags) { - if (!((ACPI_LV_OBJECTS & acpi_dbg_level) + if (! + ((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) { return; } @@ -996,7 +998,8 @@ acpi_ex_dump_object_descriptor(union acpi_operand_object *obj_desc, u32 flags) } if (!flags) { - if (!((ACPI_LV_OBJECTS & acpi_dbg_level) + if (! + ((ACPI_LV_OBJECTS & acpi_dbg_level) && (_COMPONENT & acpi_dbg_layer))) { return_VOID; } diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index a7784152ed3..419148a66e7 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -54,8 +54,7 @@ ACPI_MODULE_NAME("exfldio") /* Local prototypes */ static acpi_status acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, - u32 field_datum_byte_offset, - u64 *value, u32 read_write); + u32 field_datum_byte_offset, u64 *value, u32 read_write); static u8 acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value); diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c index fcc75fa27d3..6d19bd42d29 100644 --- a/drivers/acpi/acpica/exnames.c +++ b/drivers/acpi/acpica/exnames.c @@ -53,8 +53,7 @@ ACPI_MODULE_NAME("exnames") /* Local prototypes */ static char *acpi_ex_allocate_name_string(u32 prefix_count, u32 num_name_segs); -static acpi_status -acpi_ex_name_segment(u8 ** in_aml_address, char *name_string); +static acpi_status acpi_ex_name_segment(u8 **in_aml_address, char *name_string); /******************************************************************************* * @@ -178,7 +177,8 @@ static acpi_status acpi_ex_name_segment(u8 ** in_aml_address, char *name_string) ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "Bytes from stream:\n")); - for (index = 0; (index < ACPI_NAME_SIZE) + for (index = 0; + (index < ACPI_NAME_SIZE) && (acpi_ut_valid_acpi_char(*aml_address, 0)); index++) { char_buf[index] = *aml_address++; ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "%c\n", char_buf[index])); diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index f232fbabdea..17dc218cd39 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c @@ -337,7 +337,8 @@ acpi_ex_resolve_operands(u16 opcode, if ((opcode == AML_STORE_OP) && ((*stack_ptr)->common.type == ACPI_TYPE_LOCAL_REFERENCE) - && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) { + && ((*stack_ptr)->reference.class == + ACPI_REFCLASS_INDEX)) { goto next_operand; } break; diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index db4076580e2..3b3b5e45847 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -339,7 +339,8 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, acpi_status acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, - struct acpi_gpe_block_info *gpe_block, void *context) + struct acpi_gpe_block_info * gpe_block, + void *context) { u32 i; acpi_status status; diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index b6411f16832..438004a1dd8 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -101,8 +101,7 @@ acpi_status acpi_get_timer(u32 * ticks) return_ACPI_STATUS(AE_BAD_PARAMETER); } - status = - acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block); + status = acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c index 0ff1ecea5c3..ae443fe2ebf 100644 --- a/drivers/acpi/acpica/hwxfsleep.c +++ b/drivers/acpi/acpica/hwxfsleep.c @@ -49,8 +49,7 @@ ACPI_MODULE_NAME("hwxfsleep") /* Local prototypes */ -static acpi_status -acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id); +static acpi_status acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id); /* * Dispatch table used to efficiently branch to the various sleep @@ -234,8 +233,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) * function. * ******************************************************************************/ -static acpi_status -acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id) +static acpi_status acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id) { acpi_status status; struct acpi_sleep_functions *sleep_functions = @@ -369,8 +367,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) return_ACPI_STATUS(AE_AML_OPERAND_VALUE); } - status = - acpi_hw_sleep_dispatch(sleep_state, ACPI_SLEEP_FUNCTION_ID); + status = acpi_hw_sleep_dispatch(sleep_state, ACPI_SLEEP_FUNCTION_ID); return_ACPI_STATUS(status); } @@ -396,8 +393,7 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); status = - acpi_hw_sleep_dispatch(sleep_state, - ACPI_WAKE_PREP_FUNCTION_ID); + acpi_hw_sleep_dispatch(sleep_state, ACPI_WAKE_PREP_FUNCTION_ID); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index 23db53ce229..fc168e62c1c 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c @@ -179,8 +179,7 @@ acpi_status acpi_ns_root_initialize(void) /* Build an object around the static string */ - obj_desc->string.length = - (u32) ACPI_STRLEN(val); + obj_desc->string.length = (u32)ACPI_STRLEN(val); obj_desc->string.pointer = val; obj_desc->common.flags |= AOPOBJ_STATIC_POINTER; break; diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 95ffe8dfa1f..4328e2adfeb 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -96,8 +96,8 @@ acpi_status acpi_ns_initialize_objects(void) /* Walk entire namespace from the supplied root */ status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, - ACPI_UINT32_MAX, acpi_ns_init_one_object, NULL, - &info, NULL); + ACPI_UINT32_MAX, acpi_ns_init_one_object, + NULL, &info, NULL); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace")); } diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c index ed1d457bd5c..e5572a78bdb 100644 --- a/drivers/acpi/acpica/psopcode.c +++ b/drivers/acpi/acpica/psopcode.c @@ -392,10 +392,12 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = { AML_FLAGS_EXEC_1A_0T_1R | AML_NO_OPERAND_RESOLVE), /* 38 */ ACPI_OP("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, - AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT), + AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | + AML_CONSTANT), /* 39 */ ACPI_OP("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, - AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT), + AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | + AML_CONSTANT), /* 3A */ ACPI_OP("LNot", ARGP_LNOT_OP, ARGI_LNOT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT), @@ -495,7 +497,8 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = { AML_NSNODE | AML_NAMED | AML_DEFER), /* 59 */ ACPI_OP("Field", ARGP_FIELD_OP, ARGI_FIELD_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, - AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), + AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | + AML_FIELD), /* 5A */ ACPI_OP("Device", ARGP_DEVICE_OP, ARGI_DEVICE_OP, ACPI_TYPE_DEVICE, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, @@ -519,12 +522,13 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = { /* 5E */ ACPI_OP("IndexField", ARGP_INDEX_FIELD_OP, ARGI_INDEX_FIELD_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, - AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD), + AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | + AML_FIELD), /* 5F */ ACPI_OP("BankField", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP, - ACPI_TYPE_LOCAL_BANK_FIELD, AML_CLASS_NAMED_OBJECT, - AML_TYPE_NAMED_FIELD, - AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_FIELD | - AML_DEFER), + ACPI_TYPE_LOCAL_BANK_FIELD, + AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_FIELD, + AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | + AML_FIELD | AML_DEFER), /* Internal opcodes that map to invalid AML opcodes */ @@ -632,7 +636,8 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = { /* 7D */ ACPI_OP("[EvalSubTree]", ARGP_SCOPE_OP, ARGI_SCOPE_OP, ACPI_TYPE_ANY, AML_CLASS_NAMED_OBJECT, AML_TYPE_NAMED_NO_OBJ, - AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | AML_NSNODE), + AML_HAS_ARGS | AML_NSOBJECT | AML_NSOPCODE | + AML_NSNODE), /* ACPI 3.0 opcodes */ diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index 01985703bb9..dfdda00c6ff 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c @@ -459,8 +459,9 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) /* Executing a control method - additional cleanup */ - acpi_ds_terminate_control_method( - walk_state->method_desc, walk_state); + acpi_ds_terminate_control_method(walk_state-> + method_desc, + walk_state); } acpi_ds_delete_walk_state(walk_state); diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index de12469d1c9..42745676ecd 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -664,8 +664,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, (*sub_object_list)->string. length + 1); } else { - temp_size_needed += - acpi_ns_get_pathname_length((*sub_object_list)->reference.node); + temp_size_needed += acpi_ns_get_pathname_length((*sub_object_list)->reference.node); } } else { /* diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 352fd1a3832..fe84aee5df4 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -178,8 +178,7 @@ acpi_status acpi_unload_table_id(acpi_owner_id id); acpi_status acpi_get_table_header(acpi_string signature, - u32 instance, - struct acpi_table_header *out_table_header); + u32 instance, struct acpi_table_header *out_table_header); acpi_status acpi_get_table_with_size(acpi_string signature, @@ -190,8 +189,7 @@ acpi_get_table(acpi_string signature, u32 instance, struct acpi_table_header **out_table); acpi_status -acpi_get_table_by_index(u32 table_index, - struct acpi_table_header **out_table); +acpi_get_table_by_index(u32 table_index, struct acpi_table_header **out_table); acpi_status acpi_install_table_handler(acpi_tbl_handler handler, void *context); @@ -300,10 +298,9 @@ ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status u32 gpe_number, acpi_gpe_handler address)) -acpi_status -acpi_install_notify_handler(acpi_handle device, - u32 handler_type, - acpi_notify_handler handler, void *context); +acpi_status acpi_install_notify_handler(acpi_handle device, u32 handler_type, + acpi_notify_handler handler, + void *context); acpi_status acpi_remove_notify_handler(acpi_handle device, diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index ea50a314e55..1fa6ba12307 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -922,7 +922,8 @@ struct acpi_system_info { /* * Types specific to the OS service interfaces */ -typedef u32(ACPI_SYSTEM_XFACE * acpi_osd_handler) (void *context); +typedef u32 + (ACPI_SYSTEM_XFACE * acpi_osd_handler) (void *context); typedef void (ACPI_SYSTEM_XFACE * acpi_osd_exec_callback) (void *context); @@ -938,7 +939,8 @@ void (*acpi_gbl_event_handler) (u32 event_type, #define ACPI_EVENT_TYPE_GPE 0 #define ACPI_EVENT_TYPE_FIXED 1 -typedef u32(*acpi_event_handler) (void *context); +typedef +u32(*acpi_event_handler) (void *context); typedef u32 (*acpi_gpe_handler) (acpi_handle gpe_device, u32 gpe_number, void *context); -- cgit v1.2.3 From 86ff0e508f88eda6e479a897476026055831d2d8 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 31 Oct 2012 02:25:52 +0000 Subject: ACPICA: Fix unmerged acmacros.h divergences. The 20121018 release depends on some unmerged acmaros.h fixes. This patch includes the fixes made on acmaros.h that will not affect the generated vmlinux binary. This patch will not affect the generated vmlinux binary. This will decrease 157 lines of 20120913 divergence.diff. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acmacros.h | 161 +++++++++++++++-------------------------- drivers/acpi/acpica/psloop.c | 2 - 2 files changed, 57 insertions(+), 106 deletions(-) diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index a7f68c47f51..da8062d91ee 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -84,29 +84,29 @@ /* These macros reverse the bytes during the move, converting little-endian to big endian */ - /* Big Endian <== Little Endian */ - /* Hi...Lo Lo...Hi */ + /* Big Endian <== Little Endian */ + /* Hi...Lo Lo...Hi */ /* 16-bit source, 16/32/64 destination */ #define ACPI_MOVE_16_TO_16(d, s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[1];\ - (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[0];} + (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[0];} #define ACPI_MOVE_16_TO_32(d, s) {(*(u32 *)(void *)(d))=0;\ - ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\ - ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];} + ((u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\ + ((u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];} #define ACPI_MOVE_16_TO_64(d, s) {(*(u64 *)(void *)(d))=0;\ - ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[1];\ - ((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[0];} + ((u8 *)(void *)(d))[6] = ((u8 *)(void *)(s))[1];\ + ((u8 *)(void *)(d))[7] = ((u8 *)(void *)(s))[0];} /* 32-bit source, 16/32/64 destination */ #define ACPI_MOVE_32_TO_16(d, s) ACPI_MOVE_16_TO_16(d, s) /* Truncate to 16 */ #define ACPI_MOVE_32_TO_32(d, s) {(( u8 *)(void *)(d))[0] = ((u8 *)(void *)(s))[3];\ - (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[2];\ - (( u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\ - (( u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];} + (( u8 *)(void *)(d))[1] = ((u8 *)(void *)(s))[2];\ + (( u8 *)(void *)(d))[2] = ((u8 *)(void *)(s))[1];\ + (( u8 *)(void *)(d))[3] = ((u8 *)(void *)(s))[0];} #define ACPI_MOVE_32_TO_64(d, s) {(*(u64 *)(void *)(d))=0;\ ((u8 *)(void *)(d))[4] = ((u8 *)(void *)(s))[3];\ @@ -196,24 +196,12 @@ #endif #endif -/* Macros based on machine integer width */ - -#if ACPI_MACHINE_WIDTH == 32 -#define ACPI_MOVE_SIZE_TO_16(d, s) ACPI_MOVE_32_TO_16(d, s) - -#elif ACPI_MACHINE_WIDTH == 64 -#define ACPI_MOVE_SIZE_TO_16(d, s) ACPI_MOVE_64_TO_16(d, s) - -#else -#error unknown ACPI_MACHINE_WIDTH -#endif - /* * Fast power-of-two math macros for non-optimized compilers */ -#define _ACPI_DIV(value, power_of2) ((u32) ((value) >> (power_of2))) -#define _ACPI_MUL(value, power_of2) ((u32) ((value) << (power_of2))) -#define _ACPI_MOD(value, divisor) ((u32) ((value) & ((divisor) -1))) +#define _ACPI_DIV(value, power_of2) ((u32) ((value) >> (power_of2))) +#define _ACPI_MUL(value, power_of2) ((u32) ((value) << (power_of2))) +#define _ACPI_MOD(value, divisor) ((u32) ((value) & ((divisor) -1))) #define ACPI_DIV_2(a) _ACPI_DIV(a, 1) #define ACPI_MUL_2(a) _ACPI_MUL(a, 1) @@ -238,12 +226,12 @@ /* * Rounding macros (Power of two boundaries only) */ -#define ACPI_ROUND_DOWN(value, boundary) (((acpi_size)(value)) & \ - (~(((acpi_size) boundary)-1))) +#define ACPI_ROUND_DOWN(value, boundary) (((acpi_size)(value)) & \ + (~(((acpi_size) boundary)-1))) -#define ACPI_ROUND_UP(value, boundary) ((((acpi_size)(value)) + \ - (((acpi_size) boundary)-1)) & \ - (~(((acpi_size) boundary)-1))) +#define ACPI_ROUND_UP(value, boundary) ((((acpi_size)(value)) + \ + (((acpi_size) boundary)-1)) & \ + (~(((acpi_size) boundary)-1))) /* Note: sizeof(acpi_size) evaluates to either 4 or 8 (32- vs 64-bit mode) */ @@ -264,7 +252,7 @@ #define ACPI_ROUND_UP_TO(value, boundary) (((value) + ((boundary)-1)) / (boundary)) -#define ACPI_IS_MISALIGNED(value) (((acpi_size) value) & (sizeof(acpi_size)-1)) +#define ACPI_IS_MISALIGNED(value) (((acpi_size) value) & (sizeof(acpi_size)-1)) /* * Bitmask creation @@ -355,7 +343,6 @@ * Ascii error messages can be configured out */ #ifndef ACPI_NO_ERROR_MESSAGES - /* * Error reporting. Callers module and line number are inserted by AE_INFO, * the plist contains a set of parens to allow variable-length lists. @@ -375,18 +362,15 @@ #define ACPI_WARN_PREDEFINED(plist) #define ACPI_INFO_PREDEFINED(plist) -#endif /* ACPI_NO_ERROR_MESSAGES */ +#endif /* ACPI_NO_ERROR_MESSAGES */ /* * Debug macros that are conditionally compiled */ #ifdef ACPI_DEBUG_OUTPUT - /* * Function entry tracing */ -#ifdef CONFIG_ACPI_DEBUG_FUNC_TRACE - #define ACPI_FUNCTION_TRACE(a) ACPI_FUNCTION_NAME(a) \ acpi_ut_trace(ACPI_DEBUG_PARAMETERS) #define ACPI_FUNCTION_TRACE_PTR(a, b) ACPI_FUNCTION_NAME(a) \ @@ -464,44 +448,18 @@ #endif /* ACPI_SIMPLE_RETURN_MACROS */ -#else /* !CONFIG_ACPI_DEBUG_FUNC_TRACE */ - -#define ACPI_FUNCTION_TRACE(a) -#define ACPI_FUNCTION_TRACE_PTR(a,b) -#define ACPI_FUNCTION_TRACE_U32(a,b) -#define ACPI_FUNCTION_TRACE_STR(a,b) -#define ACPI_FUNCTION_EXIT -#define ACPI_FUNCTION_STATUS_EXIT(s) -#define ACPI_FUNCTION_VALUE_EXIT(s) -#define ACPI_FUNCTION_TRACE(a) -#define ACPI_FUNCTION_ENTRY() - -#define return_VOID return -#define return_ACPI_STATUS(s) return(s) -#define return_VALUE(s) return(s) -#define return_UINT8(s) return(s) -#define return_UINT32(s) return(s) -#define return_PTR(s) return(s) - -#endif /* CONFIG_ACPI_DEBUG_FUNC_TRACE */ - /* Conditional execution */ #define ACPI_DEBUG_EXEC(a) a -#define ACPI_NORMAL_EXEC(a) - -#define ACPI_DEBUG_DEFINE(a) a; #define ACPI_DEBUG_ONLY_MEMBERS(a) a; #define _VERBOSE_STRUCTURES -/* Stack and buffer dumping */ +/* Various object display routines for debug */ #define ACPI_DUMP_STACK_ENTRY(a) acpi_ex_dump_operand((a), 0) -#define ACPI_DUMP_OPERANDS(a, b, c) acpi_ex_dump_operands(a, b, c) - +#define ACPI_DUMP_OPERANDS(a, b ,c) acpi_ex_dump_operands(a, b, c) #define ACPI_DUMP_ENTRY(a, b) acpi_ns_dump_entry (a, b) #define ACPI_DUMP_PATHNAME(a, b, c, d) acpi_ns_dump_pathname(a, b, c, d) -#define ACPI_DUMP_RESOURCE_LIST(a) acpi_rs_dump_resource_list(a) #define ACPI_DUMP_BUFFER(a, b) acpi_ut_dump_buffer((u8 *) a, b, DB_BYTE_DISPLAY, _COMPONENT) #else @@ -510,25 +468,23 @@ * leaving no executable debug code! */ #define ACPI_DEBUG_EXEC(a) -#define ACPI_NORMAL_EXEC(a) a; - -#define ACPI_DEBUG_DEFINE(a) do { } while(0) -#define ACPI_DEBUG_ONLY_MEMBERS(a) do { } while(0) -#define ACPI_FUNCTION_TRACE(a) do { } while(0) -#define ACPI_FUNCTION_TRACE_PTR(a, b) do { } while(0) -#define ACPI_FUNCTION_TRACE_U32(a, b) do { } while(0) -#define ACPI_FUNCTION_TRACE_STR(a, b) do { } while(0) -#define ACPI_FUNCTION_EXIT do { } while(0) -#define ACPI_FUNCTION_STATUS_EXIT(s) do { } while(0) -#define ACPI_FUNCTION_VALUE_EXIT(s) do { } while(0) -#define ACPI_FUNCTION_ENTRY() do { } while(0) -#define ACPI_DUMP_STACK_ENTRY(a) do { } while(0) -#define ACPI_DUMP_OPERANDS(a, b, c) do { } while(0) -#define ACPI_DUMP_ENTRY(a, b) do { } while(0) -#define ACPI_DUMP_TABLES(a, b) do { } while(0) -#define ACPI_DUMP_PATHNAME(a, b, c, d) do { } while(0) -#define ACPI_DUMP_RESOURCE_LIST(a) do { } while(0) -#define ACPI_DUMP_BUFFER(a, b) do { } while(0) +#define ACPI_DEBUG_ONLY_MEMBERS(a) +#define ACPI_FUNCTION_TRACE(a) +#define ACPI_FUNCTION_TRACE_PTR(a, b) +#define ACPI_FUNCTION_TRACE_U32(a, b) +#define ACPI_FUNCTION_TRACE_STR(a, b) +#define ACPI_FUNCTION_EXIT +#define ACPI_FUNCTION_STATUS_EXIT(s) +#define ACPI_FUNCTION_VALUE_EXIT(s) +#define ACPI_FUNCTION_ENTRY() +#define ACPI_DUMP_STACK_ENTRY(a) +#define ACPI_DUMP_OPERANDS(a, b, c) +#define ACPI_DUMP_ENTRY(a, b) +#define ACPI_DUMP_TABLES(a, b) +#define ACPI_DUMP_PATHNAME(a, b, c, d) +#define ACPI_DUMP_BUFFER(a, b) +#define ACPI_DEBUG_PRINT(pl) +#define ACPI_DEBUG_PRINT_RAW(pl) #define return_VOID return #define return_ACPI_STATUS(s) return(s) @@ -556,18 +512,6 @@ #define ACPI_DEBUGGER_EXEC(a) #endif -#ifdef ACPI_DEBUG_OUTPUT -/* - * 1) Set name to blanks - * 2) Copy the object name - */ -#define ACPI_ADD_OBJECT_NAME(a,b) ACPI_MEMSET (a->common.name, ' ', sizeof (a->common.name));\ - ACPI_STRNCPY (a->common.name, acpi_gbl_ns_type_names[b], sizeof (a->common.name)) -#else - -#define ACPI_ADD_OBJECT_NAME(a,b) -#endif - /* * Memory allocation tracking (DEBUG ONLY) */ @@ -578,13 +522,13 @@ /* Memory allocation */ #ifndef ACPI_ALLOCATE -#define ACPI_ALLOCATE(a) acpi_ut_allocate((acpi_size)(a), ACPI_MEM_PARAMETERS) +#define ACPI_ALLOCATE(a) acpi_ut_allocate((acpi_size) (a), ACPI_MEM_PARAMETERS) #endif #ifndef ACPI_ALLOCATE_ZEROED -#define ACPI_ALLOCATE_ZEROED(a) acpi_ut_allocate_zeroed((acpi_size)(a), ACPI_MEM_PARAMETERS) +#define ACPI_ALLOCATE_ZEROED(a) acpi_ut_allocate_zeroed((acpi_size) (a), ACPI_MEM_PARAMETERS) #endif #ifndef ACPI_FREE -#define ACPI_FREE(a) acpio_os_free(a) +#define ACPI_FREE(a) acpi_os_free(a) #endif #define ACPI_MEM_TRACKING(a) @@ -592,16 +536,25 @@ /* Memory allocation */ -#define ACPI_ALLOCATE(a) acpi_ut_allocate_and_track((acpi_size)(a), ACPI_MEM_PARAMETERS) -#define ACPI_ALLOCATE_ZEROED(a) acpi_ut_allocate_zeroed_and_track((acpi_size)(a), ACPI_MEM_PARAMETERS) +#define ACPI_ALLOCATE(a) acpi_ut_allocate_and_track((acpi_size) (a), ACPI_MEM_PARAMETERS) +#define ACPI_ALLOCATE_ZEROED(a) acpi_ut_allocate_zeroed_and_track((acpi_size) (a), ACPI_MEM_PARAMETERS) #define ACPI_FREE(a) acpi_ut_free_and_track(a, ACPI_MEM_PARAMETERS) #define ACPI_MEM_TRACKING(a) a #endif /* ACPI_DBG_TRACK_ALLOCATIONS */ -/* Preemption point */ -#ifndef ACPI_PREEMPTION_POINT -#define ACPI_PREEMPTION_POINT() /* no preemption */ -#endif +/* + * Macros used for ACPICA utilities only + */ + +/* Generate a UUID */ + +#define ACPI_INIT_UUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ + (a) & 0xFF, ((a) >> 8) & 0xFF, ((a) >> 16) & 0xFF, ((a) >> 24) & 0xFF, \ + (b) & 0xFF, ((b) >> 8) & 0xFF, \ + (c) & 0xFF, ((c) >> 8) & 0xFF, \ + (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) + +#define ACPI_IS_OCTAL_DIGIT(d) (((char)(d) >= '0') && ((char)(d) <= '7')) #endif /* ACMACROS_H */ diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 799162c1b6d..31e2e9fb2de 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -843,8 +843,6 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state, *op = NULL; } - ACPI_PREEMPTION_POINT(); - return_ACPI_STATUS(AE_OK); } -- cgit v1.2.3 From 68aafc35161dcc9d365a32c2f9f077aedc61754d Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:26:01 +0000 Subject: ACPICA: Audit/update for ACPICA return macros and debug depth counter 1) Ensure that all functions that use the various TRACE macros also use the appropriate ACPICA return macros. 2) Ensure that all normal return statements surround the return expression (value) with parens. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/dswload2.c | 4 ++-- drivers/acpi/acpica/dswstate.c | 4 ++-- drivers/acpi/acpica/evxfgpe.c | 4 ++-- drivers/acpi/acpica/exdebug.c | 2 +- drivers/acpi/acpica/exmutex.c | 2 +- drivers/acpi/acpica/exoparg6.c | 2 +- drivers/acpi/acpica/hwpci.c | 4 ++-- drivers/acpi/acpica/nsnames.c | 2 +- drivers/acpi/acpica/nsxfeval.c | 2 +- drivers/acpi/acpica/rslist.c | 4 ++-- drivers/acpi/acpica/tbinstal.c | 2 ++ drivers/acpi/acpica/tbutils.c | 2 +- drivers/acpi/acpica/tbxface.c | 4 ++-- drivers/acpi/acpica/tbxfroot.c | 1 - drivers/acpi/acpica/utdebug.c | 1 + drivers/acpi/acpica/utmutex.c | 2 ++ drivers/acpi/acpica/uttrack.c | 4 ++-- drivers/acpi/acpica/utxface.c | 3 ++- 18 files changed, 27 insertions(+), 22 deletions(-) diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index 89c0114210c..37983574835 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c @@ -254,7 +254,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, acpi_ut_get_type_name(node->type), acpi_ut_get_node_name(node))); - return (AE_AML_OPERAND_TYPE); + return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } break; @@ -602,7 +602,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) region_space, walk_state); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } acpi_ex_exit_interpreter(); diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index 9bb7fa45e24..8e6267980aa 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c @@ -708,13 +708,13 @@ void acpi_ds_delete_walk_state(struct acpi_walk_state *walk_state) ACPI_FUNCTION_TRACE_PTR(ds_delete_walk_state, walk_state); if (!walk_state) { - return; + return_VOID; } if (walk_state->descriptor_type != ACPI_DESC_TYPE_WALK) { ACPI_ERROR((AE_INFO, "%p is not a valid walk state", walk_state)); - return; + return_VOID; } /* There should not be any open scopes */ diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index d36f9973937..3f30e753b65 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -569,7 +569,7 @@ acpi_install_gpe_block(acpi_handle gpe_device, status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } node = acpi_ns_validate_handle(gpe_device); @@ -652,7 +652,7 @@ acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } node = acpi_ns_validate_handle(gpe_device); diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c index bc5b9a6a131..e0c905095ed 100644 --- a/drivers/acpi/acpica/exdebug.c +++ b/drivers/acpi/acpica/exdebug.c @@ -190,7 +190,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, acpi_os_printf("Table Index 0x%X\n", source_desc->reference.value); - return; + return_VOID; default: break; diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index bcceda5be9e..9099783eb85 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -305,7 +305,7 @@ acpi_status acpi_ex_release_mutex_object(union acpi_operand_object *obj_desc) ACPI_FUNCTION_TRACE(ex_release_mutex_object); if (obj_desc->mutex.acquisition_depth == 0) { - return (AE_NOT_ACQUIRED); + return_ACPI_STATUS(AE_NOT_ACQUIRED); } /* Match multiple Acquires with multiple Releases */ diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index 0786b865906..ab68dc532c7 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c @@ -198,7 +198,7 @@ acpi_ex_do_match(u32 match_op, return (FALSE); } - return logical_result; + return (logical_result); } /******************************************************************************* diff --git a/drivers/acpi/acpica/hwpci.c b/drivers/acpi/acpica/hwpci.c index 1455ddcdc32..65bc3453a29 100644 --- a/drivers/acpi/acpica/hwpci.c +++ b/drivers/acpi/acpica/hwpci.c @@ -259,7 +259,7 @@ acpi_hw_process_pci_list(struct acpi_pci_id *pci_id, status = acpi_hw_get_pci_device_info(pci_id, info->device, &bus_number, &is_bridge); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + return (status); } info = info->next; @@ -271,7 +271,7 @@ acpi_hw_process_pci_list(struct acpi_pci_id *pci_id, pci_id->segment, pci_id->bus, pci_id->device, pci_id->function, status, bus_number, is_bridge)); - return_ACPI_STATUS(AE_OK); + return (AE_OK); } /******************************************************************************* diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index 96e0eb609bb..55a175eadcc 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -195,7 +195,7 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node) ACPI_ERROR((AE_INFO, "Invalid Namespace Node (%p) while traversing namespace", next_node)); - return 0; + return (0); } size += ACPI_PATH_SEGMENT_LENGTH; next_node = next_node->parent; diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index 494f2ebd623..ee4d873f9f0 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -550,7 +550,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { - return (status); + return_ACPI_STATUS(status); } node = acpi_ns_validate_handle(obj_handle); diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c index 46b5324b22d..8b64db9a3fd 100644 --- a/drivers/acpi/acpica/rslist.c +++ b/drivers/acpi/acpica/rslist.c @@ -109,7 +109,7 @@ acpi_rs_convert_aml_to_resources(u8 * aml, ACPI_ERROR((AE_INFO, "Invalid/unsupported resource descriptor: Type 0x%2.2X", resource_index)); - return (AE_AML_INVALID_RESOURCE_TYPE); + return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); } /* Convert the AML byte stream resource to a local resource struct */ @@ -200,7 +200,7 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, ACPI_ERROR((AE_INFO, "Invalid/unsupported resource descriptor: Type 0x%2.2X", resource->type)); - return (AE_AML_INVALID_RESOURCE_TYPE); + return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); } status = acpi_rs_convert_resource_to_aml(resource, diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 70f9d787c82..f540ae46292 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c @@ -526,6 +526,8 @@ void acpi_tb_terminate(void) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + + return_VOID; } /******************************************************************************* diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index b6cea30da63..285e24b9738 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -354,7 +354,7 @@ u8 acpi_tb_checksum(u8 *buffer, u32 length) sum = (u8) (sum + *(buffer++)); } - return sum; + return (sum); } /******************************************************************************* diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index 21101262e47..f5632780421 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -236,7 +236,7 @@ acpi_get_table_header(char *signature, sizeof(struct acpi_table_header)); if (!header) { - return AE_NO_MEMORY; + return (AE_NO_MEMORY); } ACPI_MEMCPY(out_table_header, header, sizeof(struct acpi_table_header)); @@ -244,7 +244,7 @@ acpi_get_table_header(char *signature, sizeof(struct acpi_table_header)); } else { - return AE_NOT_FOUND; + return (AE_NOT_FOUND); } } else { ACPI_MEMCPY(out_table_header, diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index 74e72080003..f8ee9b35b99 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c @@ -67,7 +67,6 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp); static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) { - ACPI_FUNCTION_ENTRY(); /* * The signature and checksum must both be correct diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 6e3ae6a23f0..2c217991764 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -300,6 +300,7 @@ acpi_ut_trace_ptr(u32 line_number, const char *function_name, const char *module_name, u32 component_id, void *pointer) { + acpi_gbl_nesting_level++; acpi_ut_track_stack_ptr(); diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 296baa676bc..93a11919933 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -193,6 +193,8 @@ static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id) acpi_gbl_mutex_info[mutex_id].mutex = NULL; acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED; + + return_VOID; } /******************************************************************************* diff --git a/drivers/acpi/acpica/uttrack.c b/drivers/acpi/acpica/uttrack.c index 73ca27d40f9..e79c49d44d0 100644 --- a/drivers/acpi/acpica/uttrack.c +++ b/drivers/acpi/acpica/uttrack.c @@ -517,14 +517,14 @@ void acpi_ut_dump_allocations(u32 component, const char *module) ACPI_FUNCTION_TRACE(ut_dump_allocations); if (acpi_gbl_disable_mem_tracking) { - return; + return_VOID; } /* * Walk the allocation list. */ if (ACPI_FAILURE(acpi_ut_acquire_mutex(ACPI_MTX_MEMORY))) { - return; + return_VOID; } element = acpi_gbl_global_list->list_head; diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index b09632b4f5b..0c98d42fb2f 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -238,7 +238,7 @@ acpi_install_initialization_handler(acpi_init_handler handler, u32 function) } acpi_gbl_init_handler = handler; - return AE_OK; + return (AE_OK); } ACPI_EXPORT_SYMBOL(acpi_install_initialization_handler) @@ -263,6 +263,7 @@ acpi_status acpi_purge_cached_objects(void) (void)acpi_os_purge_cache(acpi_gbl_operand_cache); (void)acpi_os_purge_cache(acpi_gbl_ps_node_cache); (void)acpi_os_purge_cache(acpi_gbl_ps_node_ext_cache); + return_ACPI_STATUS(AE_OK); } -- cgit v1.2.3 From 4f3ca640e97ba54df42789a7c3085c75630e863c Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:26:11 +0000 Subject: ACPICA: ACPICA core: Cleanup empty lines at file start and end Maintenance for source code consistency. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acobject.h | 1 - drivers/acpi/acpica/amlresrc.h | 1 - drivers/acpi/acpica/exmisc.c | 1 - drivers/acpi/acpica/exmutex.c | 1 - drivers/acpi/acpica/exnames.c | 1 - drivers/acpi/acpica/exoparg1.c | 1 - drivers/acpi/acpica/exoparg3.c | 1 - drivers/acpi/acpica/exoparg6.c | 1 - drivers/acpi/acpica/exprep.c | 1 - drivers/acpi/acpica/exregion.c | 1 - drivers/acpi/acpica/exresnte.c | 1 - drivers/acpi/acpica/exresolv.c | 1 - drivers/acpi/acpica/exresop.c | 1 - drivers/acpi/acpica/exstoren.c | 1 - drivers/acpi/acpica/exstorob.c | 1 - drivers/acpi/acpica/exsystem.c | 1 - drivers/acpi/acpica/exutils.c | 1 - drivers/acpi/acpica/hwacpi.c | 1 - drivers/acpi/acpica/hwgpe.c | 1 - drivers/acpi/acpica/hwregs.c | 1 - drivers/acpi/acpica/hwtimer.c | 1 - drivers/acpi/acpica/hwvalid.c | 1 - drivers/acpi/acpica/hwxface.c | 1 - include/acpi/acpiosxf.h | 1 - include/acpi/acpixf.h | 1 - 25 files changed, 25 deletions(-) diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index ac4269fb1a3..b83e46aebb1 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -1,4 +1,3 @@ - /****************************************************************************** * * Name: acobject.h - Definition of union acpi_operand_object (Internal object only) diff --git a/drivers/acpi/acpica/amlresrc.h b/drivers/acpi/acpica/amlresrc.h index af4947956ec..968449685e0 100644 --- a/drivers/acpi/acpica/amlresrc.h +++ b/drivers/acpi/acpica/amlresrc.h @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: amlresrc.h - AML resource descriptors diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 271c0c57ea1..15e1abd1913 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index 9099783eb85..4723974a4cf 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exmutex - ASL Mutex Acquire/Release functions diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c index 6d19bd42d29..a41c82fe2d3 100644 --- a/drivers/acpi/acpica/exnames.c +++ b/drivers/acpi/acpica/exnames.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exnames - interpreter/scanner name load/execute diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 9ba8c73cea1..c6490d60919 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exoparg1 - AML execution - opcodes with 1 argument diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index 71fcc65c9ff..00b19bfe5b5 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exoparg3 - AML execution - opcodes with 3 arguments diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index ab68dc532c7..98188555e78 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exoparg6 - AML execution - opcodes with 6 arguments diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 81eca60d274..95892480876 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exprep - ACPI AML (p-code) execution - field prep utilities diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index 1f1ce0c3d2f..b41e333eb8f 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exregion - ACPI default op_region (address space) handlers diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c index fa50e77e64a..1cb057fe817 100644 --- a/drivers/acpi/acpica/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exresnte - AML Interpreter object resolution diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index bbf40ac2758..ae199e7cdfb 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exresolv - AML Interpreter object resolution diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index 17dc218cd39..04b70b38ebd 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exresop - AML Interpreter operand/object resolution diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c index b35bed52e06..6fe6eacb372 100644 --- a/drivers/acpi/acpica/exstoren.c +++ b/drivers/acpi/acpica/exstoren.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exstoren - AML Interpreter object store support, diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c index 53c24847354..b9ac30c11b5 100644 --- a/drivers/acpi/acpica/exstorob.c +++ b/drivers/acpi/acpica/exstorob.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exstorob - AML Interpreter object store support, store to object diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index b760641e2fc..2d6d8bc12ed 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exsystem - Interface to OS services diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index d1ab7917eed..ff291e626ec 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: exutils - interpreter/scanner utilities diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index a1e71d0ef57..bcf931ca192 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 3b3b5e45847..64560045052 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: hwgpe - Low level GPE enable/disable/clear functions diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 4af6d20ef07..f4e57503576 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c @@ -1,4 +1,3 @@ - /******************************************************************************* * * Module Name: hwregs - Read/write access functions for the various ACPI diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index 438004a1dd8..19f6cce95f1 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Name: hwtimer.c - ACPI Power Management Timer Interface diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index c99d546b217..b6aae58299d 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: hwvalid - I/O request validation diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 7bfd649d199..05a154c3c9a 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c @@ -1,4 +1,3 @@ - /****************************************************************************** * * Module Name: hwxface - Public ACPICA hardware interfaces diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 1222ba93d80..64e2c8b830a 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -1,4 +1,3 @@ - /****************************************************************************** * * Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL). These diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index fe84aee5df4..2596de109ff 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -1,4 +1,3 @@ - /****************************************************************************** * * Name: acpixf.h - External interfaces to the ACPI subsystem -- cgit v1.2.3 From 691fda505822e46e2a8106e33b408a12e11732bc Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:26:23 +0000 Subject: ACPICA: Fix some typos in comments No functional changes. Some small fixes within commments. Colin Ian King. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/tbxfload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/acpica/tbxfload.c b/drivers/acpi/acpica/tbxfload.c index f87cc63e69a..a5e1e4e4709 100644 --- a/drivers/acpi/acpica/tbxfload.c +++ b/drivers/acpi/acpica/tbxfload.c @@ -211,7 +211,7 @@ static acpi_status acpi_tb_load_namespace(void) * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must * be a valid ACPI table with a valid ACPI table header. * Note1: Mainly intended to support hotplug addition of SSDTs. - * Note2: Does not copy the incoming table. User is reponsible + * Note2: Does not copy the incoming table. User is responsible * to ensure that the table is not deleted or unmapped. * ******************************************************************************/ -- cgit v1.2.3 From 267d672ab3e2b171230b3edb5711794fab0afb02 Mon Sep 17 00:00:00 2001 From: Robert Moore Date: Wed, 31 Oct 2012 02:26:36 +0000 Subject: ACPICA: Fix for predefined name loop during ACPICA initialization If a name cannot be created, simply continue on to the next name. Do not attempt to use the name, do not abort. With assistance from Colin Ian King. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nsaccess.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index fc168e62c1c..d70eaf39dfd 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c @@ -110,11 +110,11 @@ acpi_status acpi_ns_root_initialize(void) status = acpi_ns_lookup(NULL, init_val->name, init_val->type, ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, NULL, &new_node); - - if (ACPI_FAILURE(status) || (!new_node)) { /* Must be on same line for code converter */ + if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Could not create predefined name %s", init_val->name)); + continue; } /* -- cgit v1.2.3 From b9e17693576e4739cd267f59cbdfdd33c5eefe76 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:26:47 +0000 Subject: ACPICA: Update local C library module comments for ASCII table Improve the commenting of the table. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/utclib.c | 261 ++++++++++++++++++++++--------------------- 1 file changed, 131 insertions(+), 130 deletions(-) diff --git a/drivers/acpi/acpica/utclib.c b/drivers/acpi/acpica/utclib.c index f887f93e56a..19ea4755aa7 100644 --- a/drivers/acpi/acpica/utclib.c +++ b/drivers/acpi/acpica/utclib.c @@ -46,7 +46,7 @@ /* * These implementations of standard C Library routines can optionally be - * used if a C library is not available. In general, they are less efficient + * used if a C library is not available. In general, they are less efficient * than an inline or assembly implementation */ @@ -606,134 +606,134 @@ int acpi_ut_to_lower(int c) ******************************************************************************/ const u8 _acpi_ctype[257] = { - _ACPI_CN, /* 0x0 0. */ - _ACPI_CN, /* 0x1 1. */ - _ACPI_CN, /* 0x2 2. */ - _ACPI_CN, /* 0x3 3. */ - _ACPI_CN, /* 0x4 4. */ - _ACPI_CN, /* 0x5 5. */ - _ACPI_CN, /* 0x6 6. */ - _ACPI_CN, /* 0x7 7. */ - _ACPI_CN, /* 0x8 8. */ - _ACPI_CN | _ACPI_SP, /* 0x9 9. */ - _ACPI_CN | _ACPI_SP, /* 0xA 10. */ - _ACPI_CN | _ACPI_SP, /* 0xB 11. */ - _ACPI_CN | _ACPI_SP, /* 0xC 12. */ - _ACPI_CN | _ACPI_SP, /* 0xD 13. */ - _ACPI_CN, /* 0xE 14. */ - _ACPI_CN, /* 0xF 15. */ - _ACPI_CN, /* 0x10 16. */ - _ACPI_CN, /* 0x11 17. */ - _ACPI_CN, /* 0x12 18. */ - _ACPI_CN, /* 0x13 19. */ - _ACPI_CN, /* 0x14 20. */ - _ACPI_CN, /* 0x15 21. */ - _ACPI_CN, /* 0x16 22. */ - _ACPI_CN, /* 0x17 23. */ - _ACPI_CN, /* 0x18 24. */ - _ACPI_CN, /* 0x19 25. */ - _ACPI_CN, /* 0x1A 26. */ - _ACPI_CN, /* 0x1B 27. */ - _ACPI_CN, /* 0x1C 28. */ - _ACPI_CN, /* 0x1D 29. */ - _ACPI_CN, /* 0x1E 30. */ - _ACPI_CN, /* 0x1F 31. */ - _ACPI_XS | _ACPI_SP, /* 0x20 32. ' ' */ - _ACPI_PU, /* 0x21 33. '!' */ - _ACPI_PU, /* 0x22 34. '"' */ - _ACPI_PU, /* 0x23 35. '#' */ - _ACPI_PU, /* 0x24 36. '$' */ - _ACPI_PU, /* 0x25 37. '%' */ - _ACPI_PU, /* 0x26 38. '&' */ - _ACPI_PU, /* 0x27 39. ''' */ - _ACPI_PU, /* 0x28 40. '(' */ - _ACPI_PU, /* 0x29 41. ')' */ - _ACPI_PU, /* 0x2A 42. '*' */ - _ACPI_PU, /* 0x2B 43. '+' */ - _ACPI_PU, /* 0x2C 44. ',' */ - _ACPI_PU, /* 0x2D 45. '-' */ - _ACPI_PU, /* 0x2E 46. '.' */ - _ACPI_PU, /* 0x2F 47. '/' */ - _ACPI_XD | _ACPI_DI, /* 0x30 48. '0' */ - _ACPI_XD | _ACPI_DI, /* 0x31 49. '1' */ - _ACPI_XD | _ACPI_DI, /* 0x32 50. '2' */ - _ACPI_XD | _ACPI_DI, /* 0x33 51. '3' */ - _ACPI_XD | _ACPI_DI, /* 0x34 52. '4' */ - _ACPI_XD | _ACPI_DI, /* 0x35 53. '5' */ - _ACPI_XD | _ACPI_DI, /* 0x36 54. '6' */ - _ACPI_XD | _ACPI_DI, /* 0x37 55. '7' */ - _ACPI_XD | _ACPI_DI, /* 0x38 56. '8' */ - _ACPI_XD | _ACPI_DI, /* 0x39 57. '9' */ - _ACPI_PU, /* 0x3A 58. ':' */ - _ACPI_PU, /* 0x3B 59. ';' */ - _ACPI_PU, /* 0x3C 60. '<' */ - _ACPI_PU, /* 0x3D 61. '=' */ - _ACPI_PU, /* 0x3E 62. '>' */ - _ACPI_PU, /* 0x3F 63. '?' */ - _ACPI_PU, /* 0x40 64. '@' */ - _ACPI_XD | _ACPI_UP, /* 0x41 65. 'A' */ - _ACPI_XD | _ACPI_UP, /* 0x42 66. 'B' */ - _ACPI_XD | _ACPI_UP, /* 0x43 67. 'C' */ - _ACPI_XD | _ACPI_UP, /* 0x44 68. 'D' */ - _ACPI_XD | _ACPI_UP, /* 0x45 69. 'E' */ - _ACPI_XD | _ACPI_UP, /* 0x46 70. 'F' */ - _ACPI_UP, /* 0x47 71. 'G' */ - _ACPI_UP, /* 0x48 72. 'H' */ - _ACPI_UP, /* 0x49 73. 'I' */ - _ACPI_UP, /* 0x4A 74. 'J' */ - _ACPI_UP, /* 0x4B 75. 'K' */ - _ACPI_UP, /* 0x4C 76. 'L' */ - _ACPI_UP, /* 0x4D 77. 'M' */ - _ACPI_UP, /* 0x4E 78. 'N' */ - _ACPI_UP, /* 0x4F 79. 'O' */ - _ACPI_UP, /* 0x50 80. 'P' */ - _ACPI_UP, /* 0x51 81. 'Q' */ - _ACPI_UP, /* 0x52 82. 'R' */ - _ACPI_UP, /* 0x53 83. 'S' */ - _ACPI_UP, /* 0x54 84. 'T' */ - _ACPI_UP, /* 0x55 85. 'U' */ - _ACPI_UP, /* 0x56 86. 'V' */ - _ACPI_UP, /* 0x57 87. 'W' */ - _ACPI_UP, /* 0x58 88. 'X' */ - _ACPI_UP, /* 0x59 89. 'Y' */ - _ACPI_UP, /* 0x5A 90. 'Z' */ - _ACPI_PU, /* 0x5B 91. '[' */ - _ACPI_PU, /* 0x5C 92. '\' */ - _ACPI_PU, /* 0x5D 93. ']' */ - _ACPI_PU, /* 0x5E 94. '^' */ - _ACPI_PU, /* 0x5F 95. '_' */ - _ACPI_PU, /* 0x60 96. '`' */ - _ACPI_XD | _ACPI_LO, /* 0x61 97. 'a' */ - _ACPI_XD | _ACPI_LO, /* 0x62 98. 'b' */ - _ACPI_XD | _ACPI_LO, /* 0x63 99. 'c' */ - _ACPI_XD | _ACPI_LO, /* 0x64 100. 'd' */ - _ACPI_XD | _ACPI_LO, /* 0x65 101. 'e' */ - _ACPI_XD | _ACPI_LO, /* 0x66 102. 'f' */ - _ACPI_LO, /* 0x67 103. 'g' */ - _ACPI_LO, /* 0x68 104. 'h' */ - _ACPI_LO, /* 0x69 105. 'i' */ - _ACPI_LO, /* 0x6A 106. 'j' */ - _ACPI_LO, /* 0x6B 107. 'k' */ - _ACPI_LO, /* 0x6C 108. 'l' */ - _ACPI_LO, /* 0x6D 109. 'm' */ - _ACPI_LO, /* 0x6E 110. 'n' */ - _ACPI_LO, /* 0x6F 111. 'o' */ - _ACPI_LO, /* 0x70 112. 'p' */ - _ACPI_LO, /* 0x71 113. 'q' */ - _ACPI_LO, /* 0x72 114. 'r' */ - _ACPI_LO, /* 0x73 115. 's' */ - _ACPI_LO, /* 0x74 116. 't' */ - _ACPI_LO, /* 0x75 117. 'u' */ - _ACPI_LO, /* 0x76 118. 'v' */ - _ACPI_LO, /* 0x77 119. 'w' */ - _ACPI_LO, /* 0x78 120. 'x' */ - _ACPI_LO, /* 0x79 121. 'y' */ - _ACPI_LO, /* 0x7A 122. 'z' */ - _ACPI_PU, /* 0x7B 123. '{' */ - _ACPI_PU, /* 0x7C 124. '|' */ - _ACPI_PU, /* 0x7D 125. '}' */ - _ACPI_PU, /* 0x7E 126. '~' */ - _ACPI_CN, /* 0x7F 127. */ + _ACPI_CN, /* 0x00 0 NUL */ + _ACPI_CN, /* 0x01 1 SOH */ + _ACPI_CN, /* 0x02 2 STX */ + _ACPI_CN, /* 0x03 3 ETX */ + _ACPI_CN, /* 0x04 4 EOT */ + _ACPI_CN, /* 0x05 5 ENQ */ + _ACPI_CN, /* 0x06 6 ACK */ + _ACPI_CN, /* 0x07 7 BEL */ + _ACPI_CN, /* 0x08 8 BS */ + _ACPI_CN | _ACPI_SP, /* 0x09 9 TAB */ + _ACPI_CN | _ACPI_SP, /* 0x0A 10 LF */ + _ACPI_CN | _ACPI_SP, /* 0x0B 11 VT */ + _ACPI_CN | _ACPI_SP, /* 0x0C 12 FF */ + _ACPI_CN | _ACPI_SP, /* 0x0D 13 CR */ + _ACPI_CN, /* 0x0E 14 SO */ + _ACPI_CN, /* 0x0F 15 SI */ + _ACPI_CN, /* 0x10 16 DLE */ + _ACPI_CN, /* 0x11 17 DC1 */ + _ACPI_CN, /* 0x12 18 DC2 */ + _ACPI_CN, /* 0x13 19 DC3 */ + _ACPI_CN, /* 0x14 20 DC4 */ + _ACPI_CN, /* 0x15 21 NAK */ + _ACPI_CN, /* 0x16 22 SYN */ + _ACPI_CN, /* 0x17 23 ETB */ + _ACPI_CN, /* 0x18 24 CAN */ + _ACPI_CN, /* 0x19 25 EM */ + _ACPI_CN, /* 0x1A 26 SUB */ + _ACPI_CN, /* 0x1B 27 ESC */ + _ACPI_CN, /* 0x1C 28 FS */ + _ACPI_CN, /* 0x1D 29 GS */ + _ACPI_CN, /* 0x1E 30 RS */ + _ACPI_CN, /* 0x1F 31 US */ + _ACPI_XS | _ACPI_SP, /* 0x20 32 ' ' */ + _ACPI_PU, /* 0x21 33 '!' */ + _ACPI_PU, /* 0x22 34 '"' */ + _ACPI_PU, /* 0x23 35 '#' */ + _ACPI_PU, /* 0x24 36 '$' */ + _ACPI_PU, /* 0x25 37 '%' */ + _ACPI_PU, /* 0x26 38 '&' */ + _ACPI_PU, /* 0x27 39 ''' */ + _ACPI_PU, /* 0x28 40 '(' */ + _ACPI_PU, /* 0x29 41 ')' */ + _ACPI_PU, /* 0x2A 42 '*' */ + _ACPI_PU, /* 0x2B 43 '+' */ + _ACPI_PU, /* 0x2C 44 ',' */ + _ACPI_PU, /* 0x2D 45 '-' */ + _ACPI_PU, /* 0x2E 46 '.' */ + _ACPI_PU, /* 0x2F 47 '/' */ + _ACPI_XD | _ACPI_DI, /* 0x30 48 '0' */ + _ACPI_XD | _ACPI_DI, /* 0x31 49 '1' */ + _ACPI_XD | _ACPI_DI, /* 0x32 50 '2' */ + _ACPI_XD | _ACPI_DI, /* 0x33 51 '3' */ + _ACPI_XD | _ACPI_DI, /* 0x34 52 '4' */ + _ACPI_XD | _ACPI_DI, /* 0x35 53 '5' */ + _ACPI_XD | _ACPI_DI, /* 0x36 54 '6' */ + _ACPI_XD | _ACPI_DI, /* 0x37 55 '7' */ + _ACPI_XD | _ACPI_DI, /* 0x38 56 '8' */ + _ACPI_XD | _ACPI_DI, /* 0x39 57 '9' */ + _ACPI_PU, /* 0x3A 58 ':' */ + _ACPI_PU, /* 0x3B 59 ';' */ + _ACPI_PU, /* 0x3C 60 '<' */ + _ACPI_PU, /* 0x3D 61 '=' */ + _ACPI_PU, /* 0x3E 62 '>' */ + _ACPI_PU, /* 0x3F 63 '?' */ + _ACPI_PU, /* 0x40 64 '@' */ + _ACPI_XD | _ACPI_UP, /* 0x41 65 'A' */ + _ACPI_XD | _ACPI_UP, /* 0x42 66 'B' */ + _ACPI_XD | _ACPI_UP, /* 0x43 67 'C' */ + _ACPI_XD | _ACPI_UP, /* 0x44 68 'D' */ + _ACPI_XD | _ACPI_UP, /* 0x45 69 'E' */ + _ACPI_XD | _ACPI_UP, /* 0x46 70 'F' */ + _ACPI_UP, /* 0x47 71 'G' */ + _ACPI_UP, /* 0x48 72 'H' */ + _ACPI_UP, /* 0x49 73 'I' */ + _ACPI_UP, /* 0x4A 74 'J' */ + _ACPI_UP, /* 0x4B 75 'K' */ + _ACPI_UP, /* 0x4C 76 'L' */ + _ACPI_UP, /* 0x4D 77 'M' */ + _ACPI_UP, /* 0x4E 78 'N' */ + _ACPI_UP, /* 0x4F 79 'O' */ + _ACPI_UP, /* 0x50 80 'P' */ + _ACPI_UP, /* 0x51 81 'Q' */ + _ACPI_UP, /* 0x52 82 'R' */ + _ACPI_UP, /* 0x53 83 'S' */ + _ACPI_UP, /* 0x54 84 'T' */ + _ACPI_UP, /* 0x55 85 'U' */ + _ACPI_UP, /* 0x56 86 'V' */ + _ACPI_UP, /* 0x57 87 'W' */ + _ACPI_UP, /* 0x58 88 'X' */ + _ACPI_UP, /* 0x59 89 'Y' */ + _ACPI_UP, /* 0x5A 90 'Z' */ + _ACPI_PU, /* 0x5B 91 '[' */ + _ACPI_PU, /* 0x5C 92 '\' */ + _ACPI_PU, /* 0x5D 93 ']' */ + _ACPI_PU, /* 0x5E 94 '^' */ + _ACPI_PU, /* 0x5F 95 '_' */ + _ACPI_PU, /* 0x60 96 '`' */ + _ACPI_XD | _ACPI_LO, /* 0x61 97 'a' */ + _ACPI_XD | _ACPI_LO, /* 0x62 98 'b' */ + _ACPI_XD | _ACPI_LO, /* 0x63 99 'c' */ + _ACPI_XD | _ACPI_LO, /* 0x64 100 'd' */ + _ACPI_XD | _ACPI_LO, /* 0x65 101 'e' */ + _ACPI_XD | _ACPI_LO, /* 0x66 102 'f' */ + _ACPI_LO, /* 0x67 103 'g' */ + _ACPI_LO, /* 0x68 104 'h' */ + _ACPI_LO, /* 0x69 105 'i' */ + _ACPI_LO, /* 0x6A 106 'j' */ + _ACPI_LO, /* 0x6B 107 'k' */ + _ACPI_LO, /* 0x6C 108 'l' */ + _ACPI_LO, /* 0x6D 109 'm' */ + _ACPI_LO, /* 0x6E 110 'n' */ + _ACPI_LO, /* 0x6F 111 'o' */ + _ACPI_LO, /* 0x70 112 'p' */ + _ACPI_LO, /* 0x71 113 'q' */ + _ACPI_LO, /* 0x72 114 'r' */ + _ACPI_LO, /* 0x73 115 's' */ + _ACPI_LO, /* 0x74 116 't' */ + _ACPI_LO, /* 0x75 117 'u' */ + _ACPI_LO, /* 0x76 118 'v' */ + _ACPI_LO, /* 0x77 119 'w' */ + _ACPI_LO, /* 0x78 120 'x' */ + _ACPI_LO, /* 0x79 121 'y' */ + _ACPI_LO, /* 0x7A 122 'z' */ + _ACPI_PU, /* 0x7B 123 '{' */ + _ACPI_PU, /* 0x7C 124 '|' */ + _ACPI_PU, /* 0x7D 125 '}' */ + _ACPI_PU, /* 0x7E 126 '~' */ + _ACPI_CN, /* 0x7F 127 DEL */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 to 0x8F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 to 0x9F */ @@ -742,7 +742,8 @@ const u8 _acpi_ctype[257] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0 to 0xCF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0 to 0xDF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0 to 0xEF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0 to 0x100 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0 to 0xFF */ + 0 /* 0x100 */ }; #endif /* ACPI_USE_SYSTEM_CLIBRARY */ -- cgit v1.2.3 From 73a3090a2160fb01317f5a44af6ee5a064a29625 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:26:55 +0000 Subject: ACPICA: Remove extra spaces after periods within comments This makes all comments consistent. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acglobal.h | 2 +- drivers/acpi/acpica/aclocal.h | 4 ++-- drivers/acpi/acpica/acobject.h | 4 ++-- drivers/acpi/acpica/acopcode.h | 6 +++--- drivers/acpi/acpica/acstruct.h | 2 +- drivers/acpi/acpica/dscontrol.c | 2 +- drivers/acpi/acpica/dsfield.c | 2 +- drivers/acpi/acpica/dsmethod.c | 6 +++--- drivers/acpi/acpica/dsmthdat.c | 14 +++++++------- drivers/acpi/acpica/dsobject.c | 6 +++--- drivers/acpi/acpica/dsutils.c | 30 +++++++++++++++--------------- drivers/acpi/acpica/dswexec.c | 8 ++++---- drivers/acpi/acpica/dswstate.c | 8 ++++---- drivers/acpi/acpica/excreate.c | 6 +++--- drivers/acpi/acpica/exdump.c | 2 +- drivers/acpi/acpica/exfield.c | 4 ++-- drivers/acpi/acpica/exfldio.c | 12 ++++++------ drivers/acpi/acpica/exmisc.c | 4 ++-- drivers/acpi/acpica/exnames.c | 2 +- drivers/acpi/acpica/exoparg1.c | 10 +++++----- drivers/acpi/acpica/exoparg2.c | 2 +- drivers/acpi/acpica/exoparg3.c | 2 +- drivers/acpi/acpica/exoparg6.c | 2 +- drivers/acpi/acpica/exprep.c | 12 ++++++------ drivers/acpi/acpica/exregion.c | 2 +- drivers/acpi/acpica/exresnte.c | 8 ++++---- drivers/acpi/acpica/exresolv.c | 2 +- drivers/acpi/acpica/exresop.c | 4 ++-- drivers/acpi/acpica/exstore.c | 4 ++-- drivers/acpi/acpica/exstoren.c | 10 +++++----- drivers/acpi/acpica/exstorob.c | 4 ++-- drivers/acpi/acpica/exsystem.c | 8 ++++---- drivers/acpi/acpica/exutils.c | 4 ++-- drivers/acpi/acpica/hwacpi.c | 2 +- drivers/acpi/acpica/hwtimer.c | 2 +- drivers/acpi/acpica/nsalloc.c | 4 ++-- drivers/acpi/acpica/nsdump.c | 2 +- drivers/acpi/acpica/nsload.c | 10 +++++----- drivers/acpi/acpica/nsobject.c | 8 ++++---- drivers/acpi/acpica/nsparse.c | 8 ++++---- drivers/acpi/acpica/nsutils.c | 6 +++--- drivers/acpi/acpica/nswalk.c | 10 +++++----- drivers/acpi/acpica/nsxfeval.c | 14 +++++++------- drivers/acpi/acpica/nsxfname.c | 6 +++--- drivers/acpi/acpica/nsxfobj.c | 4 ++-- drivers/acpi/acpica/psargs.c | 8 ++++---- drivers/acpi/acpica/psopcode.c | 6 +++--- drivers/acpi/acpica/psparse.c | 8 ++++---- drivers/acpi/acpica/psutils.c | 4 ++-- drivers/acpi/acpica/rscalc.c | 2 +- drivers/acpi/acpica/tbxfroot.c | 2 +- drivers/acpi/acpica/utcache.c | 6 +++--- drivers/acpi/acpica/utdebug.c | 18 +++++++++--------- drivers/acpi/acpica/utmath.c | 2 +- drivers/acpi/acpica/utmisc.c | 14 +++++++------- drivers/acpi/acpica/utmutex.c | 12 ++++++------ drivers/acpi/acpica/utobject.c | 8 ++++---- drivers/acpi/acpica/utstate.c | 2 +- drivers/acpi/acpica/uttrack.c | 6 +++--- drivers/acpi/acpica/utxface.c | 2 +- include/acpi/acexcep.h | 2 +- 61 files changed, 188 insertions(+), 188 deletions(-) diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 35006d193d5..64472e4ec32 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -70,7 +70,7 @@ /* * Enable "slack" in the AML interpreter? Default is FALSE, and the - * interpreter strictly follows the ACPI specification. Setting to TRUE + * interpreter strictly follows the ACPI specification. Setting to TRUE * allows the interpreter to ignore certain errors and/or bad AML constructs. * * Currently, these features are enabled by this flag: diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 5b5be40a199..ff8bd0061e8 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -265,7 +265,7 @@ typedef acpi_status(*acpi_internal_method) (struct acpi_walk_state * walk_state); /* - * Bitmapped ACPI types. Used internally only + * Bitmapped ACPI types. Used internally only */ #define ACPI_BTYPE_ANY 0x00000000 #define ACPI_BTYPE_INTEGER 0x00000001 @@ -584,7 +584,7 @@ struct acpi_pscope_state { }; /* - * Thread state - one per thread across multiple walk states. Multiple walk + * Thread state - one per thread across multiple walk states. Multiple walk * states are created when there are nested control methods executing. */ struct acpi_thread_state { diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index b83e46aebb1..24eb9eac951 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -197,7 +197,7 @@ struct acpi_object_method { /****************************************************************************** * - * Objects that can be notified. All share a common notify_info area. + * Objects that can be notified. All share a common notify_info area. * *****************************************************************************/ @@ -234,7 +234,7 @@ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO}; /****************************************************************************** * - * Fields. All share a common header/info field. + * Fields. All share a common header/info field. * *****************************************************************************/ diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h index 9440d053fbb..d786a5128b7 100644 --- a/drivers/acpi/acpica/acopcode.h +++ b/drivers/acpi/acpica/acopcode.h @@ -54,7 +54,7 @@ #define _UNK 0x6B /* - * Reserved ASCII characters. Do not use any of these for + * Reserved ASCII characters. Do not use any of these for * internal opcodes, since they are used to differentiate * name strings from AML opcodes */ @@ -63,7 +63,7 @@ #define _PFX 0x6D /* - * All AML opcodes and the parse-time arguments for each. Used by the AML + * All AML opcodes and the parse-time arguments for each. Used by the AML * parser Each list is compressed into a 32-bit number and stored in the * master opcode table (in psopcode.c). */ @@ -193,7 +193,7 @@ #define ARGP_ZERO_OP ARG_NONE /* - * All AML opcodes and the runtime arguments for each. Used by the AML + * All AML opcodes and the runtime arguments for each. Used by the AML * interpreter Each list is compressed into a 32-bit number and stored * in the master opcode table (in psopcode.c). * diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index f196e2c9a71..937e66c65d1 100644 --- a/drivers/acpi/acpica/acstruct.h +++ b/drivers/acpi/acpica/acstruct.h @@ -53,7 +53,7 @@ ****************************************************************************/ /* - * Walk state - current state of a parse tree walk. Used for both a leisurely + * Walk state - current state of a parse tree walk. Used for both a leisurely * stroll through the tree (for whatever reason), and for control method * execution. */ diff --git a/drivers/acpi/acpica/dscontrol.c b/drivers/acpi/acpica/dscontrol.c index 465f02134b8..57895db3231 100644 --- a/drivers/acpi/acpica/dscontrol.c +++ b/drivers/acpi/acpica/dscontrol.c @@ -280,7 +280,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, /* * Get the return value and save as the last result - * value. This is the only place where walk_state->return_desc + * value. This is the only place where walk_state->return_desc * is set to anything other than zero! */ walk_state->return_desc = walk_state->operands[0]; diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index 3da6fd8530c..b5b904ee815 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c @@ -277,7 +277,7 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, * * RETURN: Status * - * DESCRIPTION: Process all named fields in a field declaration. Names are + * DESCRIPTION: Process all named fields in a field declaration. Names are * entered into the namespace. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index aa9a5d4e405..52eb4e01622 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -170,7 +170,7 @@ acpi_ds_create_method_mutex(union acpi_operand_object *method_desc) * * RETURN: Status * - * DESCRIPTION: Prepare a method for execution. Parses the method if necessary, + * DESCRIPTION: Prepare a method for execution. Parses the method if necessary, * increments the thread count, and waits at the method semaphore * for clearance to execute. * @@ -444,7 +444,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, * RETURN: Status * * DESCRIPTION: Restart a method that was preempted by another (nested) method - * invocation. Handle the return value (if any) from the callee. + * invocation. Handle the return value (if any) from the callee. * ******************************************************************************/ @@ -530,7 +530,7 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state, * * RETURN: None * - * DESCRIPTION: Terminate a control method. Delete everything that the method + * DESCRIPTION: Terminate a control method. Delete everything that the method * created, delete all locals and arguments, and delete the parse * tree if requested. * diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index 8d55cebaa65..9a83b7e0f3b 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c @@ -76,7 +76,7 @@ acpi_ds_method_data_get_type(u16 opcode, * RETURN: Status * * DESCRIPTION: Initialize the data structures that hold the method's arguments - * and locals. The data struct is an array of namespace nodes for + * and locals. The data struct is an array of namespace nodes for * each - this allows ref_of and de_ref_of to work properly for these * special data types. * @@ -129,7 +129,7 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state) * * RETURN: None * - * DESCRIPTION: Delete method locals and arguments. Arguments are only + * DESCRIPTION: Delete method locals and arguments. Arguments are only * deleted if this method was called from another method. * ******************************************************************************/ @@ -183,7 +183,7 @@ void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state) * * RETURN: Status * - * DESCRIPTION: Initialize arguments for a method. The parameter list is a list + * DESCRIPTION: Initialize arguments for a method. The parameter list is a list * of ACPI operand objects, either null terminated or whose length * is defined by max_param_count. * @@ -401,7 +401,7 @@ acpi_ds_method_data_get_value(u8 type, * This means that either 1) The expected argument was * not passed to the method, or 2) A local variable * was referenced by the method (via the ASL) - * before it was initialized. Either case is an error. + * before it was initialized. Either case is an error. */ /* If slack enabled, init the local_x/arg_x to an Integer of value zero */ @@ -465,7 +465,7 @@ acpi_ds_method_data_get_value(u8 type, * * RETURN: None * - * DESCRIPTION: Delete the entry at Opcode:Index. Inserts + * DESCRIPTION: Delete the entry at Opcode:Index. Inserts * a null into the stack slot after the object is deleted. * ******************************************************************************/ @@ -523,7 +523,7 @@ acpi_ds_method_data_delete_value(u8 type, * * RETURN: Status * - * DESCRIPTION: Store a value in an Arg or Local. The obj_desc is installed + * DESCRIPTION: Store a value in an Arg or Local. The obj_desc is installed * as the new value for the Arg or Local and the reference count * for obj_desc is incremented. * @@ -566,7 +566,7 @@ acpi_ds_store_object_to_local(u8 type, /* * If the reference count on the object is more than one, we must - * take a copy of the object before we store. A reference count + * take a copy of the object before we store. A reference count * of exactly 1 means that the object was just created during the * evaluation of an expression, and we can safely use it since it * is not used anywhere else. diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index 68592dd3496..c9f15d3a368 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c @@ -293,7 +293,7 @@ acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state, /* * Second arg is the buffer data (optional) byte_list can be either - * individual bytes or a string initializer. In either case, a + * individual bytes or a string initializer. In either case, a * byte_list appears in the AML. */ arg = op->common.value.arg; /* skip first arg */ @@ -568,7 +568,7 @@ acpi_ds_create_node(struct acpi_walk_state *walk_state, /* * Because of the execution pass through the non-control-method - * parts of the table, we can arrive here twice. Only init + * parts of the table, we can arrive here twice. Only init * the named object node the first time through */ if (acpi_ns_get_attached_object(node)) { @@ -618,7 +618,7 @@ acpi_ds_create_node(struct acpi_walk_state *walk_state, * RETURN: Status * * DESCRIPTION: Initialize a namespace object from a parser Op and its - * associated arguments. The namespace object is a more compact + * associated arguments. The namespace object is a more compact * representation of the Op and its arguments. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index 4bbdd6c7a3d..afeb99f4948 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c @@ -61,7 +61,7 @@ ACPI_MODULE_NAME("dsutils") * * RETURN: None. * - * DESCRIPTION: Clear and remove a reference on an implicit return value. Used + * DESCRIPTION: Clear and remove a reference on an implicit return value. Used * to delete "stale" return values (if enabled, the return value * from every operator is saved at least momentarily, in case the * parent method exits.) @@ -107,7 +107,7 @@ void acpi_ds_clear_implicit_return(struct acpi_walk_state *walk_state) * * DESCRIPTION: Implements the optional "implicit return". We save the result * of every ASL operator and control method invocation in case the - * parent method exit. Before storing a new return value, we + * parent method exit. Before storing a new return value, we * delete the previous return value. * ******************************************************************************/ @@ -198,7 +198,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, * * If there is no parent, or the parent is a scope_op, we are executing * at the method level. An executing method typically has no parent, - * since each method is parsed separately. A method invoked externally + * since each method is parsed separately. A method invoked externally * via execute_control_method has a scope_op as the parent. */ if ((!op->common.parent) || @@ -223,7 +223,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, } /* - * Decide what to do with the result based on the parent. If + * Decide what to do with the result based on the parent. If * the parent opcode will not use the result, delete the object. * Otherwise leave it as is, it will be deleted when it is used * as an operand later. @@ -266,7 +266,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, /* * These opcodes allow term_arg(s) as operands and therefore - * the operands can be method calls. The result is used. + * the operands can be method calls. The result is used. */ goto result_used; @@ -284,7 +284,7 @@ acpi_ds_is_result_used(union acpi_parse_object * op, AML_BANK_FIELD_OP)) { /* * These opcodes allow term_arg(s) as operands and therefore - * the operands can be method calls. The result is used. + * the operands can be method calls. The result is used. */ goto result_used; } @@ -329,9 +329,9 @@ acpi_ds_is_result_used(union acpi_parse_object * op, * * RETURN: Status * - * DESCRIPTION: Used after interpretation of an opcode. If there is an internal + * DESCRIPTION: Used after interpretation of an opcode. If there is an internal * result descriptor, check if the parent opcode will actually use - * this result. If not, delete the result now so that it will + * this result. If not, delete the result now so that it will * not become orphaned. * ******************************************************************************/ @@ -376,7 +376,7 @@ acpi_ds_delete_result_if_not_used(union acpi_parse_object *op, * * RETURN: Status * - * DESCRIPTION: Resolve all operands to their values. Used to prepare + * DESCRIPTION: Resolve all operands to their values. Used to prepare * arguments to a control method invocation (a call from one * method to another.) * @@ -391,7 +391,7 @@ acpi_status acpi_ds_resolve_operands(struct acpi_walk_state *walk_state) /* * Attempt to resolve each of the valid operands - * Method arguments are passed by reference, not by value. This means + * Method arguments are passed by reference, not by value. This means * that the actual objects are passed, not copies of the objects. */ for (i = 0; i < walk_state->num_operands; i++) { @@ -451,7 +451,7 @@ void acpi_ds_clear_operands(struct acpi_walk_state *walk_state) * RETURN: Status * * DESCRIPTION: Translate a parse tree object that is an argument to an AML - * opcode to the equivalent interpreter object. This may include + * opcode to the equivalent interpreter object. This may include * looking up a name or entering a new name into the internal * namespace. * @@ -496,9 +496,9 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, /* * Special handling for buffer_field declarations. This is a deferred * opcode that unfortunately defines the field name as the last - * parameter instead of the first. We get here when we are performing + * parameter instead of the first. We get here when we are performing * the deferred execution, so the actual name of the field is already - * in the namespace. We don't want to attempt to look it up again + * in the namespace. We don't want to attempt to look it up again * because we may be executing in a different scope than where the * actual opcode exists. */ @@ -605,8 +605,8 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, /* * If the name is null, this means that this is an * optional result parameter that was not specified - * in the original ASL. Create a Zero Constant for a - * placeholder. (Store to a constant is a Noop.) + * in the original ASL. Create a Zero Constant for a + * placeholder. (Store to a constant is a Noop.) */ opcode = AML_ZERO_OP; /* Has no arguments! */ diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index fa44609aba3..58593931be9 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c @@ -204,7 +204,7 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, * RETURN: Status * * DESCRIPTION: Descending callback used during the execution of control - * methods. This is where most operators and operands are + * methods. This is where most operators and operands are * dispatched to the interpreter. * ****************************************************************************/ @@ -297,7 +297,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, if (walk_state->walk_type & ACPI_WALK_METHOD) { /* * Found a named object declaration during method execution; - * we must enter this object into the namespace. The created + * we must enter this object into the namespace. The created * object is temporary and will be deleted upon completion of * the execution of this method. * @@ -348,7 +348,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, * RETURN: Status * * DESCRIPTION: Ascending callback used during the execution of control - * methods. The only thing we really need to do here is to + * methods. The only thing we really need to do here is to * notice the beginning of IF, ELSE, and WHILE blocks. * ****************************************************************************/ @@ -432,7 +432,7 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) if (ACPI_SUCCESS(status)) { /* * Dispatch the request to the appropriate interpreter handler - * routine. There is one routine per opcode "type" based upon the + * routine. There is one routine per opcode "type" based upon the * number of opcode arguments and return type. */ status = diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index 8e6267980aa..3e65a15a735 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c @@ -348,7 +348,7 @@ acpi_ds_obj_stack_push(void *object, struct acpi_walk_state * walk_state) * * RETURN: Status * - * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT + * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT * deleted by this routine. * ******************************************************************************/ @@ -492,7 +492,7 @@ acpi_ds_push_walk_state(struct acpi_walk_state *walk_state, * RETURN: A walk_state object popped from the thread's stack * * DESCRIPTION: Remove and return the walkstate object that is at the head of - * the walk stack for the given walk list. NULL indicates that + * the walk stack for the given walk list. NULL indicates that * the list is empty. * ******************************************************************************/ @@ -532,7 +532,7 @@ struct acpi_walk_state *acpi_ds_pop_walk_state(struct acpi_thread_state *thread) * * RETURN: Pointer to the new walk state. * - * DESCRIPTION: Allocate and initialize a new walk state. The current walk + * DESCRIPTION: Allocate and initialize a new walk state. The current walk * state is set to this new state. * ******************************************************************************/ @@ -657,7 +657,7 @@ acpi_ds_init_aml_walk(struct acpi_walk_state *walk_state, /* * Setup the current scope. * Find a Named Op that has a namespace node associated with it. - * search upwards from this Op. Current scope is the first + * search upwards from this Op. Current scope is the first * Op with a namespace node. */ extra_op = parser_state->start_op; diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index 9f152701bc0..66554bc6f9a 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c @@ -78,7 +78,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state) (target_node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) { /* * Dereference an existing alias so that we don't create a chain - * of aliases. With this code, we guarantee that an alias is + * of aliases. With this code, we guarantee that an alias is * always exactly one level of indirection away from the * actual aliased name. */ @@ -90,7 +90,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state) /* * For objects that can never change (i.e., the NS node will * permanently point to the same object), we can simply attach - * the object to the new NS node. For other objects (such as + * the object to the new NS node. For other objects (such as * Integers, buffers, etc.), we have to point the Alias node * to the original Node. */ @@ -139,7 +139,7 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state) /* * The new alias assumes the type of the target, and it points - * to the same object. The reference count of the object has an + * to the same object. The reference count of the object has an * additional reference to prevent deletion out from under either the * target node or the alias Node */ diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 40608b3e28f..3157f3bb8de 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -778,7 +778,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands, * PARAMETERS: title - Descriptive text * value - Value to be displayed * - * DESCRIPTION: Object dump output formatting functions. These functions + * DESCRIPTION: Object dump output formatting functions. These functions * reduce the number of format strings required and keeps them * all in one place for easy modification. * diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index dc092f5b35d..ebc55fbf3ff 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -59,7 +59,7 @@ ACPI_MODULE_NAME("exfield") * * RETURN: Status * - * DESCRIPTION: Read from a named field. Returns either an Integer or a + * DESCRIPTION: Read from a named field. Returns either an Integer or a * Buffer, depending on the size of the field. * ******************************************************************************/ @@ -149,7 +149,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, * Allocate a buffer for the contents of the field. * * If the field is larger than the current integer width, create - * a BUFFER to hold it. Otherwise, use an INTEGER. This allows + * a BUFFER to hold it. Otherwise, use an INTEGER. This allows * the use of arithmetic operators on the returned value if the * field size is equal or smaller than an Integer. * diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 419148a66e7..aa2ccfb7cb6 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -154,7 +154,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, #endif /* - * Validate the request. The entire request from the byte offset for a + * Validate the request. The entire request from the byte offset for a * length of one field datum (access width) must fit within the region. * (Region length is specified in bytes) */ @@ -182,7 +182,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, obj_desc->common_field.access_byte_width) { /* * This is the case where the access_type (acc_word, etc.) is wider - * than the region itself. For example, a region of length one + * than the region itself. For example, a region of length one * byte, and a field with Dword access specified. */ ACPI_ERROR((AE_INFO, @@ -320,7 +320,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, * * DESCRIPTION: Check if a value is out of range of the field being written. * Used to check if the values written to Index and Bank registers - * are out of range. Normally, the value is simply truncated + * are out of range. Normally, the value is simply truncated * to fit the field, but this case is most likely a serious * coding error in the ASL. * @@ -369,7 +369,7 @@ acpi_ex_register_overflow(union acpi_operand_object *obj_desc, u64 value) * * RETURN: Status * - * DESCRIPTION: Read or Write a single datum of a field. The field_type is + * DESCRIPTION: Read or Write a single datum of a field. The field_type is * demultiplexed here to handle the different types of fields * (buffer_field, region_field, index_field, bank_field) * @@ -859,7 +859,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length); /* * We must have a buffer that is at least as long as the field - * we are writing to. This is because individual fields are + * we are writing to. This is because individual fields are * indivisible and partial writes are not supported -- as per * the ACPI specification. */ @@ -874,7 +874,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, /* * Copy the original data to the new buffer, starting - * at Byte zero. All unused (upper) bytes of the + * at Byte zero. All unused (upper) bytes of the * buffer will be 0. */ ACPI_MEMCPY((char *)new_buffer, (char *)buffer, buffer_length); diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 15e1abd1913..84058705ed1 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c @@ -253,7 +253,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, ACPI_FUNCTION_TRACE(ex_do_concatenate); /* - * Convert the second operand if necessary. The first operand + * Convert the second operand if necessary. The first operand * determines the type of the second operand, (See the Data Types * section of the ACPI specification.) Both object types are * guaranteed to be either Integer/String/Buffer by the operand @@ -572,7 +572,7 @@ acpi_ex_do_logical_op(u16 opcode, ACPI_FUNCTION_TRACE(ex_do_logical_op); /* - * Convert the second operand if necessary. The first operand + * Convert the second operand if necessary. The first operand * determines the type of the second operand, (See the Data Types * section of the ACPI 3.0+ specification.) Both object types are * guaranteed to be either Integer/String/Buffer by the operand diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c index a41c82fe2d3..2ff578a16ad 100644 --- a/drivers/acpi/acpica/exnames.c +++ b/drivers/acpi/acpica/exnames.c @@ -62,7 +62,7 @@ static acpi_status acpi_ex_name_segment(u8 **in_aml_address, char *name_string); * (-1)==root, 0==none * num_name_segs - count of 4-character name segments * - * RETURN: A pointer to the allocated string segment. This segment must + * RETURN: A pointer to the allocated string segment. This segment must * be deleted by the caller. * * DESCRIPTION: Allocate a buffer for a name string. Ensure allocated name diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index c6490d60919..bbf01e9bf05 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -605,7 +605,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) } /* - * Set result to ONES (TRUE) if Value == 0. Note: + * Set result to ONES (TRUE) if Value == 0. Note: * return_desc->Integer.Value is initially == 0 (FALSE) from above. */ if (!operand[0]->integer.value) { @@ -617,7 +617,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) case AML_INCREMENT_OP: /* Increment (Operand) */ /* - * Create a new integer. Can't just get the base integer and + * Create a new integer. Can't just get the base integer and * increment it because it may be an Arg or Field. */ return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); @@ -685,7 +685,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) /* * Note: The operand is not resolved at this point because we want to - * get the associated object, not its value. For example, we don't + * get the associated object, not its value. For example, we don't * want to resolve a field_unit to its value, we want the actual * field_unit object. */ @@ -726,7 +726,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) /* * The type of the base object must be integer, buffer, string, or - * package. All others are not supported. + * package. All others are not supported. * * NOTE: Integer is not specifically supported by the ACPI spec, * but is supported implicitly via implicit operand conversion. @@ -964,7 +964,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) case ACPI_TYPE_PACKAGE: /* - * Return the referenced element of the package. We must + * Return the referenced element of the package. We must * add another reference to the referenced object, however. */ return_desc = diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c index 879e8a277b9..ee5634a074c 100644 --- a/drivers/acpi/acpica/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c @@ -123,7 +123,7 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state) /* * Dispatch the notify to the appropriate handler * NOTE: the request is queued for execution after this method - * completes. The notify handlers are NOT invoked synchronously + * completes. The notify handlers are NOT invoked synchronously * from this thread -- because handlers may in turn run other * control methods. */ diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index 00b19bfe5b5..2c89b4651f0 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c @@ -157,7 +157,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state) case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */ /* - * Create the return object. The Source operand is guaranteed to be + * Create the return object. The Source operand is guaranteed to be * either a String or a Buffer, so just use its type. */ return_desc = acpi_ut_create_internal_object((operand[0])-> diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index 98188555e78..3e08695c3b3 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c @@ -268,7 +268,7 @@ acpi_status acpi_ex_opcode_6A_0T_1R(struct acpi_walk_state * walk_state) * and the next should be examined. * * Upon finding a match, the loop will terminate via "break" at - * the bottom. If it terminates "normally", match_value will be + * the bottom. If it terminates "normally", match_value will be * ACPI_UINT64_MAX (Ones) (its initial value) indicating that no * match was found. */ diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 95892480876..ba9db4de7c8 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -77,8 +77,8 @@ acpi_ex_generate_access(u32 field_bit_offset, * any_acc keyword. * * NOTE: Need to have the region_length in order to check for boundary - * conditions (end-of-region). However, the region_length is a deferred - * operation. Therefore, to complete this implementation, the generation + * conditions (end-of-region). However, the region_length is a deferred + * operation. Therefore, to complete this implementation, the generation * of this access width must be deferred until the region length has * been evaluated. * @@ -307,7 +307,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc, * RETURN: Status * * DESCRIPTION: Initialize the areas of the field object that are common - * to the various types of fields. Note: This is very "sensitive" + * to the various types of fields. Note: This is very "sensitive" * code because we are solving the general case for field * alignment. * @@ -335,13 +335,13 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc, obj_desc->common_field.bit_length = field_bit_length; /* - * Decode the access type so we can compute offsets. The access type gives + * Decode the access type so we can compute offsets. The access type gives * two pieces of information - the width of each field access and the * necessary byte_alignment (address granularity) of the access. * * For any_acc, the access_bit_width is the largest width that is both * necessary and possible in an attempt to access the whole field in one - * I/O operation. However, for any_acc, the byte_alignment is always one + * I/O operation. However, for any_acc, the byte_alignment is always one * byte. * * For all Buffer Fields, the byte_alignment is always one byte. @@ -362,7 +362,7 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc, /* * base_byte_offset is the address of the start of the field within the - * region. It is the byte address of the first *datum* (field-width data + * region. It is the byte address of the first *datum* (field-width data * unit) of the field. (i.e., the first datum that contains at least the * first *bit* of the field.) * diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index b41e333eb8f..1db2c0bfde0 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -201,7 +201,7 @@ acpi_ex_system_memory_space_handler(u32 function, * Perform the memory read or write * * Note: For machines that do not support non-aligned transfers, the target - * address was checked for alignment above. We do not attempt to break the + * address was checked for alignment above. We do not attempt to break the * transfer up into smaller (byte-size) chunks because the AML specifically * asked for a transfer width that the hardware may require. */ diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c index 1cb057fe817..6239956786e 100644 --- a/drivers/acpi/acpica/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c @@ -57,8 +57,8 @@ ACPI_MODULE_NAME("exresnte") * PARAMETERS: object_ptr - Pointer to a location that contains * a pointer to a NS node, and will receive a * pointer to the resolved object. - * walk_state - Current state. Valid only if executing AML - * code. NULL if simply resolving an object + * walk_state - Current state. Valid only if executing AML + * code. NULL if simply resolving an object * * RETURN: Status * @@ -66,7 +66,7 @@ ACPI_MODULE_NAME("exresnte") * * Note: for some of the data types, the pointer attached to the Node * can be either a pointer to an actual internal object or a pointer into the - * AML stream itself. These types are currently: + * AML stream itself. These types are currently: * * ACPI_TYPE_INTEGER * ACPI_TYPE_STRING @@ -88,7 +88,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, ACPI_FUNCTION_TRACE(ex_resolve_node_to_value); /* - * The stack pointer points to a struct acpi_namespace_node (Node). Get the + * The stack pointer points to a struct acpi_namespace_node (Node). Get the * object that is attached to the Node. */ node = *object_ptr; diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index ae199e7cdfb..cc176b245e2 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c @@ -326,7 +326,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, * * RETURN: Status * - * DESCRIPTION: Return the base object and type. Traverse a reference list if + * DESCRIPTION: Return the base object and type. Traverse a reference list if * necessary to get to the base object. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index 04b70b38ebd..b9ebff2f6a0 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c @@ -86,7 +86,7 @@ acpi_ex_check_object_type(acpi_object_type type_needed, if (type_needed == ACPI_TYPE_LOCAL_REFERENCE) { /* * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference - * objects and thus allow them to be targets. (As per the ACPI + * objects and thus allow them to be targets. (As per the ACPI * specification, a store to a constant is a noop.) */ if ((this_type == ACPI_TYPE_INTEGER) && @@ -638,7 +638,7 @@ acpi_ex_resolve_operands(u16 opcode, if (acpi_gbl_enable_interpreter_slack) { /* * Enable original behavior of Store(), allowing any and all - * objects as the source operand. The ACPI spec does not + * objects as the source operand. The ACPI spec does not * allow this, however. */ break; diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index 5fffe7ab5ec..90431f12f83 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c @@ -374,7 +374,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, * with the input value. * * When storing into an object the data is converted to the - * target object type then stored in the object. This means + * target object type then stored in the object. This means * that the target object type (for an initialized target) will * not be changed by a store operation. * @@ -491,7 +491,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, acpi_ut_get_object_type_name(source_desc), source_desc, node)); - /* No conversions for all other types. Just attach the source object */ + /* No conversions for all other types. Just attach the source object */ status = acpi_ns_attach_object(node, source_desc, source_desc->common.type); diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c index 6fe6eacb372..87153bbc4b4 100644 --- a/drivers/acpi/acpica/exstoren.c +++ b/drivers/acpi/acpica/exstoren.c @@ -60,7 +60,7 @@ ACPI_MODULE_NAME("exstoren") * * RETURN: Status, resolved object in source_desc_ptr. * - * DESCRIPTION: Resolve an object. If the object is a reference, dereference + * DESCRIPTION: Resolve an object. If the object is a reference, dereference * it and return the actual object in the source_desc_ptr. * ******************************************************************************/ @@ -92,7 +92,7 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, /* * Stores into a Field/Region or into a Integer/Buffer/String - * are all essentially the same. This case handles the + * are all essentially the same. This case handles the * "interchangeable" types Integer, String, and Buffer. */ if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) { @@ -166,7 +166,7 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, * * RETURN: Status * - * DESCRIPTION: "Store" an object to another object. This may include + * DESCRIPTION: "Store" an object to another object. This may include * converting the source type to the target type (implicit * conversion), and a copy of the value of the source to * the target. @@ -177,14 +177,14 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, * with the input value. * * When storing into an object the data is converted to the - * target object type then stored in the object. This means + * target object type then stored in the object. This means * that the target object type (for an initialized target) will * not be changed by a store operation. * * This module allows destination types of Number, String, * Buffer, and Package. * - * Assumes parameters are already validated. NOTE: source_desc + * Assumes parameters are already validated. NOTE: source_desc * resolution (from a reference object) must be performed by * the caller if necessary. * diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c index b9ac30c11b5..b5f339cb130 100644 --- a/drivers/acpi/acpica/exstorob.c +++ b/drivers/acpi/acpica/exstorob.c @@ -107,7 +107,7 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc, #ifdef ACPI_OBSOLETE_BEHAVIOR /* * NOTE: ACPI versions up to 3.0 specified that the buffer must be - * truncated if the string is smaller than the buffer. However, "other" + * truncated if the string is smaller than the buffer. However, "other" * implementations of ACPI never did this and thus became the defacto * standard. ACPI 3.0A changes this behavior such that the buffer * is no longer truncated. @@ -116,7 +116,7 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc, /* * OBSOLETE BEHAVIOR: * If the original source was a string, we must truncate the buffer, - * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer + * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer * copy must not truncate the original buffer. */ if (original_src_type == ACPI_TYPE_STRING) { diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index 2d6d8bc12ed..c8a0ad5c1f5 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -58,7 +58,7 @@ ACPI_MODULE_NAME("exsystem") * RETURN: Status * * DESCRIPTION: Implements a semaphore wait with a check to see if the - * semaphore is available immediately. If it is not, the + * semaphore is available immediately. If it is not, the * interpreter is released before waiting. * ******************************************************************************/ @@ -103,7 +103,7 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) * RETURN: Status * * DESCRIPTION: Implements a mutex wait with a check to see if the - * mutex is available immediately. If it is not, the + * mutex is available immediately. If it is not, the * interpreter is released before waiting. * ******************************************************************************/ @@ -151,7 +151,7 @@ acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) * DESCRIPTION: Suspend running thread for specified amount of time. * Note: ACPI specification requires that Stall() does not * relinquish the processor, and delays longer than 100 usec - * should use Sleep() instead. We allow stalls up to 255 usec + * should use Sleep() instead. We allow stalls up to 255 usec * for compatibility with other interpreters and existing BIOSs. * ******************************************************************************/ @@ -253,7 +253,7 @@ acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc) * RETURN: Status * * DESCRIPTION: Provides an access point to perform synchronization operations - * within the AML. This operation is a request to wait for an + * within the AML. This operation is a request to wait for an * event. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index ff291e626ec..264d22d8018 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -44,12 +44,12 @@ /* * DEFINE_AML_GLOBALS is tested in amlcode.h * to determine whether certain global names should be "defined" or only - * "declared" in the current compilation. This enhances maintainability + * "declared" in the current compilation. This enhances maintainability * by enabling a single header file to embody all knowledge of the names * in question. * * Exactly one module of any executable should #define DEFINE_GLOBALS - * before #including the header files which use this convention. The + * before #including the header files which use this convention. The * names in question will be defined and initialized in that module, * and declared as extern in all other modules which #include those * header files. diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index bcf931ca192..90a9aea1cee 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c @@ -135,7 +135,7 @@ acpi_status acpi_hw_set_mode(u32 mode) * * RETURN: SYS_MODE_ACPI or SYS_MODE_LEGACY * - * DESCRIPTION: Return current operating state of system. Determined by + * DESCRIPTION: Return current operating state of system. Determined by * querying the SCI_EN bit. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index 19f6cce95f1..bfdce22f379 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -127,7 +127,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_timer) * a versatile and accurate timer. * * Note that this function accommodates only a single timer - * rollover. Thus for 24-bit timers, this function should only + * rollover. Thus for 24-bit timers, this function should only * be used for calculating durations less than ~4.6 seconds * (~20 minutes for 32-bit timers) -- calculations below: * diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index ac389e5bb59..15143c44f5e 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -332,7 +332,7 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) * * RETURN: None. * - * DESCRIPTION: Delete a subtree of the namespace. This includes all objects + * DESCRIPTION: Delete a subtree of the namespace. This includes all objects * stored within the subtree. * ******************************************************************************/ @@ -418,7 +418,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) * RETURN: Status * * DESCRIPTION: Delete entries within the namespace that are owned by a - * specific ID. Used to delete entire ACPI tables. All + * specific ID. Used to delete entire ACPI tables. All * reference counts are updated. * * MUTEX: Locks namespace during deletion walk. diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index 993b12417e7..924b3c71473 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c @@ -692,7 +692,7 @@ void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level) * * PARAMETERS: search_base - Root of subtree to be dumped, or * NS_ALL to dump the entire namespace - * max_depth - Maximum depth of dump. Use INT_MAX + * max_depth - Maximum depth of dump. Use INT_MAX * for an effectively unlimited depth. * * RETURN: None diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index 76935ff2928..911f99127b9 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c @@ -80,8 +80,8 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) /* * Parse the table and load the namespace with all named - * objects found within. Control methods are NOT parsed - * at this time. In fact, the control methods cannot be + * objects found within. Control methods are NOT parsed + * at this time. In fact, the control methods cannot be * parsed until the entire namespace is loaded, because * if a control method makes a forward reference (call) * to another control method, we can't continue parsing @@ -122,7 +122,7 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node) } /* - * Now we can parse the control methods. We always parse + * Now we can parse the control methods. We always parse * them here for a sanity check, and if configured for * just-in-time parsing, we delete the control method * parse trees. @@ -166,7 +166,7 @@ acpi_status acpi_ns_load_namespace(void) } /* - * Load the namespace. The DSDT is required, + * Load the namespace. The DSDT is required, * but the SSDT and PSDT tables are optional. */ status = acpi_ns_load_table_by_type(ACPI_TABLE_ID_DSDT); @@ -283,7 +283,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle) * RETURN: Status * * DESCRIPTION: Shrinks the namespace, typically in response to an undocking - * event. Deletes an entire subtree starting from (and + * event. Deletes an entire subtree starting from (and * including) the given handle. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index d6c9a3cc671..e69f7fa2579 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c @@ -61,7 +61,7 @@ ACPI_MODULE_NAME("nsobject") * RETURN: Status * * DESCRIPTION: Record the given object as the value associated with the - * name whose acpi_handle is passed. If Object is NULL + * name whose acpi_handle is passed. If Object is NULL * and Type is ACPI_TYPE_ANY, set the name as having no value. * Note: Future may require that the Node->Flags field be passed * as a parameter. @@ -133,7 +133,7 @@ acpi_ns_attach_object(struct acpi_namespace_node *node, ((struct acpi_namespace_node *)object)->object) { /* * Value passed is a name handle and that name has a - * non-null value. Use that name's value and type. + * non-null value. Use that name's value and type. */ obj_desc = ((struct acpi_namespace_node *)object)->object; object_type = ((struct acpi_namespace_node *)object)->type; @@ -321,7 +321,7 @@ union acpi_operand_object *acpi_ns_get_secondary_object(union * * RETURN: Status * - * DESCRIPTION: Low-level attach data. Create and attach a Data object. + * DESCRIPTION: Low-level attach data. Create and attach a Data object. * ******************************************************************************/ @@ -377,7 +377,7 @@ acpi_ns_attach_data(struct acpi_namespace_node *node, * * RETURN: Status * - * DESCRIPTION: Low-level detach data. Delete the data node, but the caller + * DESCRIPTION: Low-level detach data. Delete the data node, but the caller * is responsible for the actual data. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index ec7ba2d3463..233f756d5cf 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -168,11 +168,11 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node) /* * AML Parse, pass 1 * - * In this pass, we load most of the namespace. Control methods - * are not parsed until later. A parse tree is not created. Instead, - * each Parser Op subtree is deleted when it is finished. This saves + * In this pass, we load most of the namespace. Control methods + * are not parsed until later. A parse tree is not created. Instead, + * each Parser Op subtree is deleted when it is finished. This saves * a great deal of memory, and allows a small cache of parse objects - * to service the entire parse. The second pass of the parse then + * to service the entire parse. The second pass of the parse then * performs another complete parse of the AML. */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n")); diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index ef753a41e08..16b3da80b92 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -530,7 +530,7 @@ acpi_ns_externalize_name(u32 internal_name_length, ((num_segments > 0) ? (num_segments - 1) : 0) + 1; /* - * Check to see if we're still in bounds. If not, there's a problem + * Check to see if we're still in bounds. If not, there's a problem * with internal_name (invalid format). */ if (required_length > internal_name_length) { @@ -681,7 +681,7 @@ u32 acpi_ns_opens_scope(acpi_object_type type) * \ (backslash) and ^ (carat) prefixes, and the * . (period) to separate segments are supported. * prefix_node - Root of subtree to be searched, or NS_ALL for the - * root of the name space. If Name is fully + * root of the name space. If Name is fully * qualified (first s8 is '\'), the passed value * of Scope will not be accessed. * flags - Used to indicate whether to perform upsearch or @@ -689,7 +689,7 @@ u32 acpi_ns_opens_scope(acpi_object_type type) * return_node - Where the Node is returned * * DESCRIPTION: Look up a name relative to a given scope and return the - * corresponding Node. NOTE: Scope can be null. + * corresponding Node. NOTE: Scope can be null. * * MUTEX: Locks namespace * diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index 730bccc5e7f..0483877f26b 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c @@ -60,8 +60,8 @@ ACPI_MODULE_NAME("nswalk") * RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if * none is found. * - * DESCRIPTION: Return the next peer node within the namespace. If Handle - * is valid, Scope is ignored. Otherwise, the first node + * DESCRIPTION: Return the next peer node within the namespace. If Handle + * is valid, Scope is ignored. Otherwise, the first node * within Scope is returned. * ******************************************************************************/ @@ -97,8 +97,8 @@ struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node * RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if * none is found. * - * DESCRIPTION: Return the next peer node within the namespace. If Handle - * is valid, Scope is ignored. Otherwise, the first node + * DESCRIPTION: Return the next peer node within the namespace. If Handle + * is valid, Scope is ignored. Otherwise, the first node * within Scope is returned. * ******************************************************************************/ @@ -305,7 +305,7 @@ acpi_ns_walk_namespace(acpi_object_type type, /* * Depth first search: Attempt to go down another level in the - * namespace if we are allowed to. Don't go any further if we have + * namespace if we are allowed to. Don't go any further if we have * reached the caller specified maximum depth or if the user * function has specified that the maximum depth has been reached. */ diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index ee4d873f9f0..d6a9f77972b 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -61,16 +61,16 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info); * PARAMETERS: handle - Object handle (optional) * pathname - Object pathname (optional) * external_params - List of parameters to pass to method, - * terminated by NULL. May be NULL + * terminated by NULL. May be NULL * if no parameters are being passed. * return_buffer - Where to put method's return value (if - * any). If NULL, no value is returned. + * any). If NULL, no value is returned. * return_type - Expected type of return object * * RETURN: Status * * DESCRIPTION: Find and evaluate the given object, passing the given - * parameters if necessary. One of "Handle" or "Pathname" must + * parameters if necessary. One of "Handle" or "Pathname" must * be valid (non-null) * ******************************************************************************/ @@ -155,15 +155,15 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object_typed) * PARAMETERS: handle - Object handle (optional) * pathname - Object pathname (optional) * external_params - List of parameters to pass to method, - * terminated by NULL. May be NULL + * terminated by NULL. May be NULL * if no parameters are being passed. * return_buffer - Where to put method's return value (if - * any). If NULL, no value is returned. + * any). If NULL, no value is returned. * * RETURN: Status * * DESCRIPTION: Find and evaluate the given object, passing the given - * parameters if necessary. One of "Handle" or "Pathname" must + * parameters if necessary. One of "Handle" or "Pathname" must * be valid (non-null) * ******************************************************************************/ @@ -656,7 +656,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, * starting (and ending) at the object specified by start_handle. * The user_function is called whenever an object of type - * Device is found. If the user function returns + * Device is found. If the user function returns * a non-zero value, the search is terminated immediately and this * value is returned to the caller. * diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 7bc4985146f..ce878977117 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -69,8 +69,8 @@ static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest, * RETURN: Status * * DESCRIPTION: This routine will search for a caller specified name in the - * name space. The caller can restrict the search region by - * specifying a non NULL parent. The parent value is itself a + * name space. The caller can restrict the search region by + * specifying a non NULL parent. The parent value is itself a * namespace handle. * ******************************************************************************/ @@ -149,7 +149,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_handle) * RETURN: Pointer to a string containing the fully qualified Name. * * DESCRIPTION: This routine returns the fully qualified name associated with - * the Handle parameter. This and the acpi_pathname_to_handle are + * the Handle parameter. This and the acpi_pathname_to_handle are * complementary functions. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index 6766fc4f088..9d029dac6b6 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c @@ -220,8 +220,8 @@ ACPI_EXPORT_SYMBOL(acpi_get_parent) * * RETURN: Status * - * DESCRIPTION: Return the next peer object within the namespace. If Handle is - * valid, Scope is ignored. Otherwise, the first object within + * DESCRIPTION: Return the next peer object within the namespace. If Handle is + * valid, Scope is ignored. Otherwise, the first object within * Scope is returned. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index 844464c4f90..cb79e2d4d74 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -120,7 +120,7 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state) * RETURN: Pointer to end-of-package +1 * * DESCRIPTION: Get next package length and return a pointer past the end of - * the package. Consumes the package length field + * the package. Consumes the package length field * ******************************************************************************/ @@ -147,8 +147,8 @@ u8 *acpi_ps_get_next_package_end(struct acpi_parse_state *parser_state) * RETURN: Pointer to the start of the name string (pointer points into * the AML. * - * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name - * prefix characters. Set parser state to point past the string. + * DESCRIPTION: Get next raw namestring within the AML stream. Handles all name + * prefix characters. Set parser state to point past the string. * (Name is consumed from the AML.) * ******************************************************************************/ @@ -220,7 +220,7 @@ char *acpi_ps_get_next_namestring(struct acpi_parse_state *parser_state) * * DESCRIPTION: Get next name (if method call, return # of required args). * Names are looked up in the internal namespace to determine - * if the name represents a control method. If a method + * if the name represents a control method. If a method * is found, the number of arguments to the method is returned. * This information is critical for parsing to continue correctly. * diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c index e5572a78bdb..1793d934aa3 100644 --- a/drivers/acpi/acpica/psopcode.c +++ b/drivers/acpi/acpica/psopcode.c @@ -59,7 +59,7 @@ static const u8 acpi_gbl_argument_count[] = * * DESCRIPTION: Opcode table. Each entry contains * The name is a simple ascii string, the operand specifier is an - * ascii string with one letter per operand. The letter specifies + * ascii string with one letter per operand. The letter specifies * the operand type. * ******************************************************************************/ @@ -183,7 +183,7 @@ static const u8 acpi_gbl_argument_count[] = ******************************************************************************/ /* - * Master Opcode information table. A summary of everything we know about each + * Master Opcode information table. A summary of everything we know about each * opcode, all in one place. */ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = { @@ -700,7 +700,7 @@ static const u8 acpi_gbl_short_op_index[256] = { /* * This table is indexed by the second opcode of the extended opcode - * pair. It returns an index into the opcode table (acpi_gbl_aml_op_info) + * pair. It returns an index into the opcode table (acpi_gbl_aml_op_info) */ static const u8 acpi_gbl_long_op_index[NUM_EXTENDED_OPCODE] = { /* 0 1 2 3 4 5 6 7 */ diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index dfdda00c6ff..2494caf4775 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c @@ -43,9 +43,9 @@ /* * Parse the AML and build an operation tree as most interpreters, - * like Perl, do. Parsing is done by hand rather than with a YACC + * like Perl, do. Parsing is done by hand rather than with a YACC * generated parser to tightly constrain stack and dynamic memory - * usage. At the same time, parsing is kept flexible and the code + * usage. At the same time, parsing is kept flexible and the code * fairly compact by parsing based on a list of AML opcode * templates in aml_op_info[] */ @@ -379,7 +379,7 @@ acpi_ps_next_parse_state(struct acpi_walk_state *walk_state, case AE_CTRL_FALSE: /* * Either an IF/WHILE Predicate was false or we encountered a BREAK - * opcode. In both cases, we do not execute the rest of the + * opcode. In both cases, we do not execute the rest of the * package; We simply close out the parent (finishing the walk of * this branch of the tree) and continue execution at the parent * level. @@ -488,7 +488,7 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) acpi_gbl_current_walk_list = thread; /* - * Execute the walk loop as long as there is a valid Walk State. This + * Execute the walk loop as long as there is a valid Walk State. This * handles nested control method invocations without recursion. */ ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "State=%p\n", walk_state)); diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c index 8736ad5f04d..4137dcb352d 100644 --- a/drivers/acpi/acpica/psutils.c +++ b/drivers/acpi/acpica/psutils.c @@ -108,7 +108,7 @@ void acpi_ps_init_op(union acpi_parse_object *op, u16 opcode) * RETURN: Pointer to the new Op, null on failure * * DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on - * opcode. A cache of opcodes is available for the pure + * opcode. A cache of opcodes is available for the pure * GENERIC_OP, since this is by far the most commonly used. * ******************************************************************************/ @@ -164,7 +164,7 @@ union acpi_parse_object *acpi_ps_alloc_op(u16 opcode) * * RETURN: None. * - * DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list + * DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list * or actually free it. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 42745676ecd..68517798550 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -601,7 +601,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, /* * Calculate the size of the return buffer. * The base size is the number of elements * the sizes of the - * structures. Additional space for the strings is added below. + * structures. Additional space for the strings is added below. * The minus one is to subtract the size of the u8 Source[1] * member because it is added below. * diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index f8ee9b35b99..28f330230f9 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c @@ -107,7 +107,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp) * RETURN: Status, RSDP physical address * * DESCRIPTION: Search lower 1Mbyte of memory for the root system descriptor - * pointer structure. If it is found, set *RSDP to point to it. + * pointer structure. If it is found, set *RSDP to point to it. * * NOTE1: The RSDP must be either in the first 1K of the Extended * BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.) diff --git a/drivers/acpi/acpica/utcache.c b/drivers/acpi/acpica/utcache.c index eacb9ba2b9e..e1d40ed2639 100644 --- a/drivers/acpi/acpica/utcache.c +++ b/drivers/acpi/acpica/utcache.c @@ -183,7 +183,7 @@ acpi_status acpi_os_delete_cache(struct acpi_memory_list * cache) * * RETURN: None * - * DESCRIPTION: Release an object to the specified cache. If cache is full, + * DESCRIPTION: Release an object to the specified cache. If cache is full, * the object is deleted. * ******************************************************************************/ @@ -240,9 +240,9 @@ acpi_os_release_object(struct acpi_memory_list * cache, void *object) * * PARAMETERS: cache - Handle to cache object * - * RETURN: the acquired object. NULL on error + * RETURN: the acquired object. NULL on error * - * DESCRIPTION: Get an object from the specified cache. If cache is empty, + * DESCRIPTION: Get an object from the specified cache. If cache is empty, * the object is allocated. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 2c217991764..7a3327067f2 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -223,7 +223,7 @@ ACPI_EXPORT_SYMBOL(acpi_debug_print) * * RETURN: None * - * DESCRIPTION: Print message with no headers. Has same interface as + * DESCRIPTION: Print message with no headers. Has same interface as * debug_print so that the same macros can be used. * ******************************************************************************/ @@ -259,7 +259,7 @@ ACPI_EXPORT_SYMBOL(acpi_debug_print_raw) * * RETURN: None * - * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is + * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is * set in debug_level * ******************************************************************************/ @@ -291,7 +291,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_trace) * * RETURN: None * - * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is + * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is * set in debug_level * ******************************************************************************/ @@ -321,7 +321,7 @@ acpi_ut_trace_ptr(u32 line_number, * * RETURN: None * - * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is + * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is * set in debug_level * ******************************************************************************/ @@ -352,7 +352,7 @@ acpi_ut_trace_str(u32 line_number, * * RETURN: None * - * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is + * DESCRIPTION: Function entry trace. Prints only if TRACE_FUNCTIONS bit is * set in debug_level * ******************************************************************************/ @@ -382,7 +382,7 @@ acpi_ut_trace_u32(u32 line_number, * * RETURN: None * - * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is + * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is * set in debug_level * ******************************************************************************/ @@ -414,7 +414,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_exit) * * RETURN: None * - * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is + * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is * set in debug_level. Prints exit status also. * ******************************************************************************/ @@ -455,7 +455,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_status_exit) * * RETURN: None * - * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is + * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is * set in debug_level. Prints exit value also. * ******************************************************************************/ @@ -487,7 +487,7 @@ ACPI_EXPORT_SYMBOL(acpi_ut_value_exit) * * RETURN: None * - * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is + * DESCRIPTION: Function exit trace. Prints only if TRACE_FUNCTIONS bit is * set in debug_level. Prints exit value also. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c index d88a8aaab2a..49563674833 100644 --- a/drivers/acpi/acpica/utmath.c +++ b/drivers/acpi/acpica/utmath.c @@ -81,7 +81,7 @@ typedef union uint64_overlay { * RETURN: Status (Checks for divide-by-zero) * * DESCRIPTION: Perform a short (maximum 64 bits divided by 32 bits) - * divide and modulo. The result is a 64-bit quotient and a + * divide and modulo. The result is a 64-bit quotient and a * 32-bit remainder. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 0fed4bcc84b..7ba197298ef 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -250,7 +250,7 @@ acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id) * control method or unloading a table. Either way, we would * ignore any error anyway. * - * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255 + * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255 * ******************************************************************************/ @@ -534,8 +534,8 @@ u32 acpi_ut_dword_byte_swap(u32 value) * RETURN: None * * DESCRIPTION: Set the global integer bit width based upon the revision - * of the DSDT. For Revision 1 and 0, Integers are 32 bits. - * For Revision 2 and above, Integers are 64 bits. Yes, this + * of the DSDT. For Revision 1 and 0, Integers are 32 bits. + * For Revision 2 and above, Integers are 64 bits. Yes, this * makes a difference. * ******************************************************************************/ @@ -671,7 +671,7 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position) * * RETURN: TRUE if the name is valid, FALSE otherwise * - * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: + * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: * 1) Upper case alpha * 2) numeric * 3) underscore @@ -1010,10 +1010,10 @@ acpi_ut_walk_package_tree(union acpi_operand_object *source_object, /* * Check for: - * 1) An uninitialized package element. It is completely + * 1) An uninitialized package element. It is completely * legal to declare a package and leave it uninitialized * 2) Not an internal object - can be a namespace node instead - * 3) Any type other than a package. Packages are handled in else + * 3) Any type other than a package. Packages are handled in else * case below. */ if ((!this_source_obj) || @@ -1032,7 +1032,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object *source_object, state->pkg.source_object->package.count) { /* * We've handled all of the objects at this level, This means - * that we have just completed a package. That package may + * that we have just completed a package. That package may * have contained one or more packages itself. * * Delete this state and pop the previous state (package). diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 93a11919933..5ccf57c0d87 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -228,9 +228,9 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) /* * Mutex debug code, for internal debugging only. * - * Deadlock prevention. Check if this thread owns any mutexes of value - * greater than or equal to this one. If so, the thread has violated - * the mutex ordering rule. This indicates a coding error somewhere in + * Deadlock prevention. Check if this thread owns any mutexes of value + * greater than or equal to this one. If so, the thread has violated + * the mutex ordering rule. This indicates a coding error somewhere in * the ACPI subsystem code. */ for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) { @@ -321,9 +321,9 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id) /* * Mutex debug code, for internal debugging only. * - * Deadlock prevention. Check if this thread owns any mutexes of value - * greater than this one. If so, the thread has violated the mutex - * ordering rule. This indicates a coding error somewhere in + * Deadlock prevention. Check if this thread owns any mutexes of value + * greater than this one. If so, the thread has violated the mutex + * ordering rule. This indicates a coding error somewhere in * the ACPI subsystem code. */ for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) { diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c index 655f0799a39..5c52ca78f6f 100644 --- a/drivers/acpi/acpica/utobject.c +++ b/drivers/acpi/acpica/utobject.c @@ -77,7 +77,7 @@ acpi_ut_get_element_length(u8 object_type, * * NOTE: We always allocate the worst-case object descriptor because * these objects are cached, and we want them to be - * one-size-satisifies-any-request. This in itself may not be + * one-size-satisifies-any-request. This in itself may not be * the most memory efficient, but the efficiency of the object * cache should more than make up for this! * @@ -370,9 +370,9 @@ u8 acpi_ut_valid_internal_object(void *object) * line_number - Caller's line number (for error output) * component_id - Caller's component ID (for error output) * - * RETURN: Pointer to newly allocated object descriptor. Null on error + * RETURN: Pointer to newly allocated object descriptor. Null on error * - * DESCRIPTION: Allocate a new object descriptor. Gracefully handle + * DESCRIPTION: Allocate a new object descriptor. Gracefully handle * error conditions. * ******************************************************************************/ @@ -554,7 +554,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, /* * Account for the space required by the object rounded up to the next - * multiple of the machine word size. This keeps each object aligned + * multiple of the machine word size. This keeps each object aligned * on a machine word boundary. (preventing alignment faults on some * machines.) */ diff --git a/drivers/acpi/acpica/utstate.c b/drivers/acpi/acpica/utstate.c index a1c98826007..cee0473ba81 100644 --- a/drivers/acpi/acpica/utstate.c +++ b/drivers/acpi/acpica/utstate.c @@ -147,7 +147,7 @@ union acpi_generic_state *acpi_ut_pop_generic_state(union acpi_generic_state * * RETURN: The new state object. NULL on failure. * - * DESCRIPTION: Create a generic state object. Attempt to obtain one from + * DESCRIPTION: Create a generic state object. Attempt to obtain one from * the global state cache; If none available, create a new one. * ******************************************************************************/ diff --git a/drivers/acpi/acpica/uttrack.c b/drivers/acpi/acpica/uttrack.c index e79c49d44d0..79f311c3d1c 100644 --- a/drivers/acpi/acpica/uttrack.c +++ b/drivers/acpi/acpica/uttrack.c @@ -45,9 +45,9 @@ * These procedures are used for tracking memory leaks in the subsystem, and * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set. * - * Each memory allocation is tracked via a doubly linked list. Each + * Each memory allocation is tracked via a doubly linked list. Each * element contains the caller's component, module name, function name, and - * line number. acpi_ut_allocate and acpi_ut_allocate_zeroed call + * line number. acpi_ut_allocate and acpi_ut_allocate_zeroed call * acpi_ut_track_allocation to add an element to the list; deletion * occurs in the body of acpi_ut_free. */ @@ -499,7 +499,7 @@ void acpi_ut_dump_allocation_info(void) * FUNCTION: acpi_ut_dump_allocations * * PARAMETERS: component - Component(s) to dump info for. - * module - Module to dump info for. NULL means all. + * module - Module to dump info for. NULL means all. * * RETURN: None * diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 0c98d42fb2f..390db0ca5e2 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -147,7 +147,7 @@ ACPI_EXPORT_SYMBOL(acpi_subsystem_status) * RETURN: status - the status of the call * * DESCRIPTION: This function is called to get information about the current - * state of the ACPI subsystem. It will return system information + * state of the ACPI subsystem. It will return system information * in the out_buffer. * * If the function fails an appropriate status will be returned diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index 19503449814..6c3890e0214 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h @@ -122,7 +122,7 @@ #define AE_CODE_TBL_MAX 0x0005 /* - * AML exceptions. These are caused by problems with + * AML exceptions. These are caused by problems with * the actual AML byte stream */ #define AE_AML_BAD_OPCODE (acpi_status) (0x0001 | AE_CODE_AML) -- cgit v1.2.3 From abf95c362929ce0af7dd413f981597c5386f749d Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:27:04 +0000 Subject: ACPICA: Remove extra spaces after periods in the Intel license For consistency with the rest of the source code. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- include/acpi/acpiosxf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 64e2c8b830a..43152742b46 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL). These + * Name: acpiosxf.h - All interfaces to the OS Services Layer (OSL). These * interfaces must be implemented by OSL to interface the * ACPI components to the host operating system. * -- cgit v1.2.3 From bee6dc39cfa4be083e8c11cee0867eb7dc56895b Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Wed, 31 Oct 2012 02:27:15 +0000 Subject: ACPICA: Resource Mgr: Small fix for buffer size calculation Fixes a one byte error in the output buffer calculation. Feng Tang - ACPICA BZ 849: https://www.acpica.org/bugzilla/show_bug.cgi?id=849 Signed-off-by: Feng Tang Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/rscalc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 68517798550..147feb6aa2a 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -457,6 +457,15 @@ acpi_rs_get_list_length(u8 * aml_buffer, * Get the number of vendor data bytes */ extra_struct_bytes = resource_length; + + /* + * There is already one byte included in the minimum + * descriptor size. If there are extra struct bytes, + * subtract one from the count. + */ + if (extra_struct_bytes) { + extra_struct_bytes--; + } break; case ACPI_RESOURCE_NAME_END_TAG: -- cgit v1.2.3 From 2489ef01849d3d7f62f53b47c245017406f02d32 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:27:24 +0000 Subject: ACPICA: Add debug print message for mutex objects that are force-released At control method termination, any currently acquired mutex objects are force-released. Add a new message for each one that is released. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/exmutex.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index 4723974a4cf..d1f449d93dc 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -461,7 +461,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) union acpi_operand_object *next = thread->acquired_mutex_list; union acpi_operand_object *obj_desc; - ACPI_FUNCTION_ENTRY(); + ACPI_FUNCTION_NAME(ex_release_all_mutexes); /* Traverse the list of owned mutexes, releasing each one */ @@ -473,6 +473,10 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread) obj_desc->mutex.next = NULL; obj_desc->mutex.acquisition_depth = 0; + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, + "Force-releasing held mutex: %p\n", + obj_desc)); + /* Release the mutex, special case for Global Lock */ if (obj_desc == acpi_gbl_global_lock_mutex) { -- cgit v1.2.3 From d8da9151bb7e2d18624fdd8dbb066419186f0ec1 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:27:32 +0000 Subject: ACPICA: AcpiExec: Improve algorithm for tracking memory leaks Add some intelligence to the code that maintains the global list of allocated memory. The list is now ordered by allocated memory address, significantly improving performance. When running AcpiExec on the ASLTS test suite, speed improvements of 3X to 5X are seen, depending on the platform and/or the environment. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/uttrack.c | 100 ++++++++++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 29 deletions(-) diff --git a/drivers/acpi/acpica/uttrack.c b/drivers/acpi/acpica/uttrack.c index 79f311c3d1c..a424a9e3fea 100644 --- a/drivers/acpi/acpica/uttrack.c +++ b/drivers/acpi/acpica/uttrack.c @@ -61,7 +61,9 @@ ACPI_MODULE_NAME("uttrack") /* Local prototypes */ -static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation); +static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct + acpi_debug_mem_block + *allocation); static acpi_status acpi_ut_track_allocation(struct acpi_debug_mem_block *address, @@ -263,31 +265,61 @@ acpi_ut_free_and_track(void *allocation, * * PARAMETERS: allocation - Address of allocated memory * - * RETURN: A list element if found; NULL otherwise. + * RETURN: Three cases: + * 1) List is empty, NULL is returned. + * 2) Element was found. Returns Allocation parameter. + * 3) Element was not found. Returns position where it should be + * inserted into the list. * * DESCRIPTION: Searches for an element in the global allocation tracking list. + * If the element is not found, returns the location within the + * list where the element should be inserted. + * + * Note: The list is ordered by larger-to-smaller addresses. + * + * This global list is used to detect memory leaks in ACPICA as + * well as other issues such as an attempt to release the same + * internal object more than once. Although expensive as far + * as cpu time, this list is much more helpful for finding these + * types of issues than using memory leak detectors outside of + * the ACPICA code. * ******************************************************************************/ -static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation) +static struct acpi_debug_mem_block *acpi_ut_find_allocation(struct + acpi_debug_mem_block + *allocation) { struct acpi_debug_mem_block *element; - ACPI_FUNCTION_ENTRY(); - element = acpi_gbl_global_list->list_head; + if (!element) { + return (NULL); + } + + /* + * Search for the address. + * + * Note: List is ordered by larger-to-smaller addresses, on the + * assumption that a new allocation usually has a larger address + * than previous allocations. + */ + while (element > allocation) { - /* Search for the address. */ + /* Check for end-of-list */ - while (element) { - if (element == allocation) { + if (!element->next) { return (element); } element = element->next; } - return (NULL); + if (element == allocation) { + return (element); + } + + return (element->previous); } /******************************************************************************* @@ -301,7 +333,7 @@ static struct acpi_debug_mem_block *acpi_ut_find_allocation(void *allocation) * module - Source file name of caller * line - Line number of caller * - * RETURN: None. + * RETURN: Status * * DESCRIPTION: Inserts an element into the global allocation tracking list. * @@ -330,22 +362,18 @@ acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation, } /* - * Search list for this address to make sure it is not already on the list. - * This will catch several kinds of problems. + * Search the global list for this address to make sure it is not + * already present. This will catch several kinds of problems. */ element = acpi_ut_find_allocation(allocation); - if (element) { + if (element == allocation) { ACPI_ERROR((AE_INFO, - "UtTrackAllocation: Allocation already present in list! (%p)", + "UtTrackAllocation: Allocation (%p) already present in global list!", allocation)); - - ACPI_ERROR((AE_INFO, "Element %p Address %p", - element, allocation)); - goto unlock_and_exit; } - /* Fill in the instance data. */ + /* Fill in the instance data */ allocation->size = (u32)size; allocation->alloc_type = alloc_type; @@ -355,17 +383,31 @@ acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation, ACPI_STRNCPY(allocation->module, module, ACPI_MAX_MODULE_NAME); allocation->module[ACPI_MAX_MODULE_NAME - 1] = 0; - /* Insert at list head */ + if (!element) { - if (mem_list->list_head) { - ((struct acpi_debug_mem_block *)(mem_list->list_head))-> - previous = allocation; - } + /* Insert at list head */ + + if (mem_list->list_head) { + ((struct acpi_debug_mem_block *)(mem_list->list_head))-> + previous = allocation; + } + + allocation->next = mem_list->list_head; + allocation->previous = NULL; - allocation->next = mem_list->list_head; - allocation->previous = NULL; + mem_list->list_head = allocation; + } else { + /* Insert after element */ + + allocation->next = element->next; + allocation->previous = element; + + if (element->next) { + (element->next)->previous = allocation; + } - mem_list->list_head = allocation; + element->next = allocation; + } unlock_and_exit: status = acpi_ut_release_mutex(ACPI_MTX_MEMORY); @@ -381,7 +423,7 @@ acpi_ut_track_allocation(struct acpi_debug_mem_block *allocation, * module - Source file name of caller * line - Line number of caller * - * RETURN: + * RETURN: Status * * DESCRIPTION: Deletes an element from the global allocation tracking list. * @@ -443,7 +485,7 @@ acpi_ut_remove_allocation(struct acpi_debug_mem_block *allocation, * * FUNCTION: acpi_ut_dump_allocation_info * - * PARAMETERS: + * PARAMETERS: None * * RETURN: None * -- cgit v1.2.3 From ff60027174cf94bab6d4f45ab5c5da1de63b7d1b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:27:40 +0000 Subject: ACPICA: Add ACPI_MOVE_NAME macro to optimize 4-byte ACPI_NAME copies Resolves to a 32-bit move for the normal case, strncpy on machines that do not support misaligned transfers. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- include/acpi/actypes.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 1fa6ba12307..d1fb674fd39 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -453,10 +453,14 @@ typedef u64 acpi_integer; #define ACPI_PHYSADDR_TO_PTR(i) ACPI_TO_POINTER(i) #define ACPI_PTR_TO_PHYSADDR(i) ACPI_TO_INTEGER(i) +/* Optimizations for 4-character (32-bit) acpi_name manipulation */ + #ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED #define ACPI_COMPARE_NAME(a,b) (*ACPI_CAST_PTR (u32, (a)) == *ACPI_CAST_PTR (u32, (b))) +#define ACPI_MOVE_NAME(dest,src) (*ACPI_CAST_PTR (u32, (dest)) = *ACPI_CAST_PTR (u32, (src))) #else #define ACPI_COMPARE_NAME(a,b) (!ACPI_STRNCMP (ACPI_CAST_PTR (char, (a)), ACPI_CAST_PTR (char, (b)), ACPI_NAME_SIZE)) +#define ACPI_MOVE_NAME(dest,src) (ACPI_STRNCPY (ACPI_CAST_PTR (char, (dest)), ACPI_CAST_PTR (char, (src)), ACPI_NAME_SIZE)) #endif /******************************************************************************* -- cgit v1.2.3 From 00eb32550f59a15796e936418b46b5134bd23a55 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:27:48 +0000 Subject: ACPICA: Enhance error reporting for invalid opcodes and bad ACPI_NAMEs For disassembler, dump the 48 bytes surrounding the invalid opcode. Fix incorrect table offset reported for invalid opcodes. Report original 32-bit value for bad ACPI_NAMEs. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nsutils.c | 9 ++++---- drivers/acpi/acpica/psloop.c | 51 ++++++++++++++++++++++++++++++++--------- drivers/acpi/acpica/utmisc.c | 3 +++ drivers/acpi/acpica/utxferror.c | 2 +- 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 16b3da80b92..0d3d481ce58 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -557,10 +557,11 @@ acpi_ns_externalize_name(u32 internal_name_length, (*converted_name)[j++] = '.'; } - (*converted_name)[j++] = internal_name[names_index++]; - (*converted_name)[j++] = internal_name[names_index++]; - (*converted_name)[j++] = internal_name[names_index++]; - (*converted_name)[j++] = internal_name[names_index++]; + ACPI_MOVE_NAME(*converted_name, internal_name); + acpi_ut_repair_name(*converted_name); + + j += ACPI_NAME_SIZE; + names_index += ACPI_NAME_SIZE; } } diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 31e2e9fb2de..e8b6dc0c51c 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -135,16 +135,38 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) /* The opcode is unrecognized. Just skip unknown opcodes */ - ACPI_ERROR((AE_INFO, - "Found unknown opcode 0x%X at AML address %p offset 0x%X, ignoring", - walk_state->opcode, walk_state->parser_state.aml, - walk_state->aml_offset)); + if (walk_state->pass_number == 2) { + ACPI_ERROR((AE_INFO, + "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring", + walk_state->opcode, + walk_state->aml_offset + + sizeof(struct acpi_table_header))); - ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128); + ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128); - /* Assume one-byte bad opcode */ +#ifdef ACPI_ASL_COMPILER + + acpi_os_printf + ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n", + walk_state->opcode, + walk_state->aml_offset + + sizeof(struct acpi_table_header)); + + /* TBD: Pass current offset to dump_buffer */ + + acpi_ut_dump_buffer2(((u8 *)walk_state->parser_state. + aml - 16), 48, DB_BYTE_DISPLAY); + acpi_os_printf(" */\n"); +#endif + } + + /* Increment past one or two-byte opcode */ walk_state->parser_state.aml++; + if (walk_state->opcode > 0xFF) { + walk_state->parser_state.aml++; + } + return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); default: @@ -519,11 +541,18 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, if ((op_info->class == AML_CLASS_EXECUTE) && (!arg)) { ACPI_WARNING((AE_INFO, - "Detected an unsupported executable opcode " - "at module-level: [0x%.4X] at table offset 0x%.4X", - op->common.aml_opcode, - (u32)((aml_op_start - walk_state->parser_state.aml_start) - + sizeof(struct acpi_table_header)))); + "Unsupported module-level executable opcode " + "0x%.2X at table offset 0x%.4X", + op->common. + aml_opcode, + (u32) + (ACPI_PTR_DIFF + (aml_op_start, + walk_state-> + parser_state. + aml_start) + + sizeof(struct + acpi_table_header)))); } } break; diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 7ba197298ef..9286a69eb9a 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -720,9 +720,12 @@ void acpi_ut_repair_name(char *name) { u32 i; u8 found_bad_char = FALSE; + u32 original_name; ACPI_FUNCTION_NAME(ut_repair_name); + ACPI_MOVE_NAME(&original_name, name); + /* Check each character in the name */ for (i = 0; i < ACPI_NAME_SIZE; i++) { diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c index 6d63cc39b9a..d4d3826140d 100644 --- a/drivers/acpi/acpica/utxferror.c +++ b/drivers/acpi/acpica/utxferror.c @@ -408,7 +408,7 @@ acpi_ut_namespace_error(const char *module_name, ACPI_MOVE_32_TO_32(&bad_name, ACPI_CAST_PTR(u32, internal_name)); - acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); + acpi_os_printf("[0x%.8X] (NON-ASCII)", bad_name); } else { /* Convert path to external format */ -- cgit v1.2.3 From 2d2dd50880d018e42076252f9fff16e11c567de0 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:27:56 +0000 Subject: ACPICA: Update support for ACPI 5 MPST table Fixes some problems introduced by late changes to the table as it was added to the ACPI 5.0 specification. Both the table compiler and the disassembler and the main header support for the table. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- include/acpi/actbl3.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/include/acpi/actbl3.h b/include/acpi/actbl3.h index 8c61b5fe42a..6585141e4b9 100644 --- a/include/acpi/actbl3.h +++ b/include/acpi/actbl3.h @@ -277,10 +277,10 @@ struct acpi_table_gtdt { ******************************************************************************/ #define ACPI_MPST_CHANNEL_INFO \ - u16 reserved1; \ u8 channel_id; \ - u8 reserved2; \ - u16 power_node_count; + u8 reserved1[3]; \ + u16 power_node_count; \ + u16 reserved2; /* Main table */ @@ -304,9 +304,8 @@ struct acpi_mpst_power_node { u32 length; u64 range_address; u64 range_length; - u8 num_power_states; - u8 num_physical_components; - u16 reserved2; + u32 num_power_states; + u32 num_physical_components; }; /* Values for Flags field above */ @@ -332,10 +331,11 @@ struct acpi_mpst_component { struct acpi_mpst_data_hdr { u16 characteristics_count; + u16 reserved; }; struct acpi_mpst_power_data { - u8 revision; + u8 structure_id; u8 flags; u16 reserved1; u32 average_power; @@ -356,10 +356,10 @@ struct acpi_mpst_shared { u32 signature; u16 pcc_command; u16 pcc_status; - u16 command_register; - u16 status_register; - u16 power_state_id; - u16 power_node_id; + u32 command_register; + u32 status_register; + u32 power_state_id; + u32 power_node_id; u64 energy_consumed; u64 average_power; }; -- cgit v1.2.3 From eed9525ac445f446a5dabd70d32938044f04fad5 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:28:03 +0000 Subject: ACPICA: Deploy ACPI_MOVE_NAME across ACPICA source base Replaces instances of strncpy(...,4) for ACPI_NAMEs. ACPI_MOVE_NAME optimizes these to a single 32-bit copy on machines that support misaligned transfers. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nsxfname.c | 3 +-- drivers/acpi/acpica/tbfind.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index ce878977117..2d10df2ef66 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -202,8 +202,7 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) /* Just copy the ACPI name from the Node and zero terminate it */ - ACPI_STRNCPY(buffer->pointer, acpi_ut_get_node_name(node), - ACPI_NAME_SIZE); + ACPI_MOVE_NAME(buffer->pointer, acpi_ut_get_node_name(node)); ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0; status = AE_OK; diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index 57deae16657..77d1db29a72 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c @@ -77,7 +77,7 @@ acpi_tb_find_table(char *signature, /* Normalize the input strings */ ACPI_MEMSET(&header, 0, sizeof(struct acpi_table_header)); - ACPI_STRNCPY(header.signature, signature, ACPI_NAME_SIZE); + ACPI_MOVE_NAME(header.signature, signature); ACPI_STRNCPY(header.oem_id, oem_id, ACPI_OEM_ID_SIZE); ACPI_STRNCPY(header.oem_table_id, oem_table_id, ACPI_OEM_TABLE_ID_SIZE); -- cgit v1.2.3 From 97171c6be3088a68b403c7285d34c151f7dbfb18 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:28:11 +0000 Subject: ACPICA: Add starting offset parameter to common dump buffer routine Rename the dump buffer routines. Offset parameter can specify the buffer starting offset that is used when displaying each line of the buffer. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acmacros.h | 2 +- drivers/acpi/acpica/acutils.h | 5 +++-- drivers/acpi/acpica/exdebug.c | 8 ++++---- drivers/acpi/acpica/exdump.c | 9 +++++---- drivers/acpi/acpica/psloop.c | 22 ++++++++++++++-------- drivers/acpi/acpica/utdebug.c | 13 +++++++------ 6 files changed, 34 insertions(+), 25 deletions(-) diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index da8062d91ee..5efad99f216 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -460,7 +460,7 @@ #define ACPI_DUMP_OPERANDS(a, b ,c) acpi_ex_dump_operands(a, b, c) #define ACPI_DUMP_ENTRY(a, b) acpi_ns_dump_entry (a, b) #define ACPI_DUMP_PATHNAME(a, b, c, d) acpi_ns_dump_pathname(a, b, c, d) -#define ACPI_DUMP_BUFFER(a, b) acpi_ut_dump_buffer((u8 *) a, b, DB_BYTE_DISPLAY, _COMPONENT) +#define ACPI_DUMP_BUFFER(a, b) acpi_ut_debug_dump_buffer((u8 *) a, b, DB_BYTE_DISPLAY, _COMPONENT) #else /* diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index d94b4177657..5a6aa581e24 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -305,9 +305,10 @@ acpi_ut_ptr_exit(u32 line_number, const char *function_name, const char *module_name, u32 component_id, u8 *ptr); -void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id); +void +acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id); -void acpi_ut_dump_buffer2(u8 *buffer, u32 count, u32 display); +void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 offset); void acpi_ut_report_error(char *module_name, u32 line_number); diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c index e0c905095ed..d7c9f51608a 100644 --- a/drivers/acpi/acpica/exdebug.c +++ b/drivers/acpi/acpica/exdebug.c @@ -145,10 +145,10 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, case ACPI_TYPE_BUFFER: acpi_os_printf("[0x%.2X]\n", (u32)source_desc->buffer.length); - acpi_ut_dump_buffer2(source_desc->buffer.pointer, - (source_desc->buffer.length < 256) ? - source_desc->buffer.length : 256, - DB_BYTE_DISPLAY); + acpi_ut_dump_buffer(source_desc->buffer.pointer, + (source_desc->buffer.length < 256) ? + source_desc->buffer.length : 256, + DB_BYTE_DISPLAY, 0); break; case ACPI_TYPE_STRING: diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index 3157f3bb8de..858b43a7dcf 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -942,10 +942,11 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, acpi_os_printf("[Buffer] Length %.2X = ", obj_desc->buffer.length); if (obj_desc->buffer.length) { - acpi_ut_dump_buffer(ACPI_CAST_PTR - (u8, obj_desc->buffer.pointer), - obj_desc->buffer.length, - DB_DWORD_DISPLAY, _COMPONENT); + acpi_ut_debug_dump_buffer(ACPI_CAST_PTR + (u8, + obj_desc->buffer.pointer), + obj_desc->buffer.length, + DB_DWORD_DISPLAY, _COMPONENT); } else { acpi_os_printf("\n"); } diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index e8b6dc0c51c..d48c8fc0e72 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -133,7 +133,7 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) case AML_CLASS_UNKNOWN: - /* The opcode is unrecognized. Just skip unknown opcodes */ + /* The opcode is unrecognized. Complain and skip unknown opcodes */ if (walk_state->pass_number == 2) { ACPI_ERROR((AE_INFO, @@ -142,28 +142,34 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) walk_state->aml_offset + sizeof(struct acpi_table_header))); - ACPI_DUMP_BUFFER(walk_state->parser_state.aml, 128); + ACPI_DUMP_BUFFER(walk_state->parser_state.aml - 16, 48); #ifdef ACPI_ASL_COMPILER - + /* + * This is executed for the disassembler only. Output goes + * to the disassembled ASL output file. + */ acpi_os_printf ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n", walk_state->opcode, walk_state->aml_offset + sizeof(struct acpi_table_header)); - /* TBD: Pass current offset to dump_buffer */ + /* Dump the context surrounding the invalid opcode */ - acpi_ut_dump_buffer2(((u8 *)walk_state->parser_state. - aml - 16), 48, DB_BYTE_DISPLAY); + acpi_ut_dump_buffer(((u8 *)walk_state->parser_state. + aml - 16), 48, DB_BYTE_DISPLAY, + walk_state->aml_offset + + sizeof(struct acpi_table_header) - + 16); acpi_os_printf(" */\n"); #endif } - /* Increment past one or two-byte opcode */ + /* Increment past one-byte or two-byte opcode */ walk_state->parser_state.aml++; - if (walk_state->opcode > 0xFF) { + if (walk_state->opcode > 0xFF) { /* Can only happen if first byte is 0x5B */ walk_state->parser_state.aml++; } diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index 7a3327067f2..5d95166245a 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -513,7 +513,7 @@ acpi_ut_ptr_exit(u32 line_number, * PARAMETERS: buffer - Buffer to dump * count - Amount to dump, in bytes * display - BYTE, WORD, DWORD, or QWORD display - * component_ID - Caller's component ID + * offset - Beginning buffer offset (display only) * * RETURN: None * @@ -521,7 +521,7 @@ acpi_ut_ptr_exit(u32 line_number, * ******************************************************************************/ -void acpi_ut_dump_buffer2(u8 *buffer, u32 count, u32 display) +void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 base_offset) { u32 i = 0; u32 j; @@ -543,7 +543,7 @@ void acpi_ut_dump_buffer2(u8 *buffer, u32 count, u32 display) /* Print current offset */ - acpi_os_printf("%6.4X: ", i); + acpi_os_printf("%6.4X: ", (base_offset + i)); /* Print 16 hex chars */ @@ -625,7 +625,7 @@ void acpi_ut_dump_buffer2(u8 *buffer, u32 count, u32 display) /******************************************************************************* * - * FUNCTION: acpi_ut_dump_buffer + * FUNCTION: acpi_ut_debug_dump_buffer * * PARAMETERS: buffer - Buffer to dump * count - Amount to dump, in bytes @@ -638,7 +638,8 @@ void acpi_ut_dump_buffer2(u8 *buffer, u32 count, u32 display) * ******************************************************************************/ -void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id) +void +acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id) { /* Only dump the buffer if tracing is enabled */ @@ -648,5 +649,5 @@ void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id) return; } - acpi_ut_dump_buffer2(buffer, count, display); + acpi_ut_dump_buffer(buffer, count, display, 0); } -- cgit v1.2.3 From 47abd13ccfa140ad34620b343bf0e6eca15ed8e8 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:28:19 +0000 Subject: ACPICA: Fix externalize name to complete migration to ACPI_MOVE_NAME Fix for name segment copy and validation. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/nsutils.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 0d3d481ce58..b5b4cb72a8a 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -557,8 +557,11 @@ acpi_ns_externalize_name(u32 internal_name_length, (*converted_name)[j++] = '.'; } - ACPI_MOVE_NAME(*converted_name, internal_name); - acpi_ut_repair_name(*converted_name); + /* Copy and validate the 4-char name segment */ + + ACPI_MOVE_NAME(&(*converted_name)[j], + &internal_name[names_index]); + acpi_ut_repair_name(&(*converted_name)[j]); j += ACPI_NAME_SIZE; names_index += ACPI_NAME_SIZE; -- cgit v1.2.3 From 17b1f45a68ebd7944904a801d81a5c4206f9f76b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:28:27 +0000 Subject: ACPICA: Update for 64-bit generation of recent error message changes Fix for errors on printf changes on 64-bit platforms and gcc. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/psloop.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index d48c8fc0e72..5607805aab2 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -139,8 +139,8 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) ACPI_ERROR((AE_INFO, "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring", walk_state->opcode, - walk_state->aml_offset + - sizeof(struct acpi_table_header))); + (u32)(walk_state->aml_offset + + sizeof(struct acpi_table_header)))); ACPI_DUMP_BUFFER(walk_state->parser_state.aml - 16, 48); @@ -152,8 +152,8 @@ static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state) acpi_os_printf ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n", walk_state->opcode, - walk_state->aml_offset + - sizeof(struct acpi_table_header)); + (u32)(walk_state->aml_offset + + sizeof(struct acpi_table_header))); /* Dump the context surrounding the invalid opcode */ -- cgit v1.2.3 From 413fc3f592c65977858f8adce2e7af0e82aa1191 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:28:38 +0000 Subject: ACPICA: AcpiGetObjectInfo: Add support for ACPI 5 _SUB method Now calls _SUB in addition to the other ID methods: _HID, _CID, and _UID. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/acutils.h | 4 +++ drivers/acpi/acpica/nsxfname.c | 29 ++++++++++++++---- drivers/acpi/acpica/utids.c | 67 ++++++++++++++++++++++++++++++++++++++++++ include/acpi/acnames.h | 1 + include/acpi/actypes.h | 12 ++++---- 5 files changed, 103 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 5a6aa581e24..b0f5f92b674 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -362,6 +362,10 @@ acpi_status acpi_ut_execute_UID(struct acpi_namespace_node *device_node, struct acpi_pnp_device_id ** return_id); +acpi_status +acpi_ut_execute_SUB(struct acpi_namespace_node *device_node, + struct acpi_pnp_device_id **return_id); + acpi_status acpi_ut_execute_CID(struct acpi_namespace_node *device_node, struct acpi_pnp_device_id_list ** return_cid_list); diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 2d10df2ef66..811c6f13f47 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -231,6 +231,7 @@ static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest, struct acpi_pnp_device_id *source, char *string_area) { + /* Create the destination PNP_DEVICE_ID */ dest->string = string_area; @@ -255,8 +256,8 @@ static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest, * namespace node and possibly by running several standard * control methods (Such as in the case of a device.) * - * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA, - * _ADR, _sx_w, and _sx_d methods. + * For Device and Processor objects, run the Device _HID, _UID, _CID, _SUB, + * _STA, _ADR, _sx_w, and _sx_d methods. * * Note: Allocates the return buffer, must be freed by the caller. * @@ -271,6 +272,7 @@ acpi_get_object_info(acpi_handle handle, struct acpi_pnp_device_id_list *cid_list = NULL; struct acpi_pnp_device_id *hid = NULL; struct acpi_pnp_device_id *uid = NULL; + struct acpi_pnp_device_id *sub = NULL; char *next_id_string; acpi_object_type type; acpi_name name; @@ -315,7 +317,7 @@ acpi_get_object_info(acpi_handle handle, if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { /* * Get extra info for ACPI Device/Processor objects only: - * Run the Device _HID, _UID, and _CID methods. + * Run the Device _HID, _UID, _SUB, and _CID methods. * * Note: none of these methods are required, so they may or may * not be present for this device. The Info->Valid bitfield is used @@ -338,6 +340,14 @@ acpi_get_object_info(acpi_handle handle, valid |= ACPI_VALID_UID; } + /* Execute the Device._SUB method */ + + status = acpi_ut_execute_SUB(node, &sub); + if (ACPI_SUCCESS(status)) { + info_size += sub->length; + valid |= ACPI_VALID_SUB; + } + /* Execute the Device._CID method */ status = acpi_ut_execute_CID(node, &cid_list); @@ -425,8 +435,9 @@ acpi_get_object_info(acpi_handle handle, } /* - * Copy the HID, UID, and CIDs to the return buffer. The variable-length - * strings are copied to the reserved area at the end of the buffer. + * Copy the HID, UID, SUB, and CIDs to the return buffer. + * The variable-length strings are copied to the reserved area + * at the end of the buffer. * * For HID and CID, check if the ID is a PCI Root Bridge. */ @@ -444,6 +455,11 @@ acpi_get_object_info(acpi_handle handle, uid, next_id_string); } + if (sub) { + next_id_string = acpi_ns_copy_device_id(&info->subsystem_id, + sub, next_id_string); + } + if (cid_list) { info->compatible_id_list.count = cid_list->count; info->compatible_id_list.list_size = cid_list->list_size; @@ -480,6 +496,9 @@ acpi_get_object_info(acpi_handle handle, if (uid) { ACPI_FREE(uid); } + if (sub) { + ACPI_FREE(sub); + } if (cid_list) { ACPI_FREE(cid_list); } diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index f18ac81c839..774c3aefbf5 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c @@ -125,6 +125,73 @@ cleanup: return_ACPI_STATUS(status); } +/******************************************************************************* + * + * FUNCTION: acpi_ut_execute_SUB + * + * PARAMETERS: device_node - Node for the device + * return_id - Where the _SUB is returned + * + * RETURN: Status + * + * DESCRIPTION: Executes the _SUB control method that returns the subsystem + * ID of the device. The _SUB value is always a string containing + * either a valid PNP or ACPI ID. + * + * NOTE: Internal function, no parameter validation + * + ******************************************************************************/ + +acpi_status +acpi_ut_execute_SUB(struct acpi_namespace_node *device_node, + struct acpi_pnp_device_id **return_id) +{ + union acpi_operand_object *obj_desc; + struct acpi_pnp_device_id *sub; + u32 length; + acpi_status status; + + ACPI_FUNCTION_TRACE(ut_execute_SUB); + + status = acpi_ut_evaluate_object(device_node, METHOD_NAME__SUB, + ACPI_BTYPE_STRING, &obj_desc); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get the size of the String to be returned, includes null terminator */ + + length = obj_desc->string.length + 1; + + /* Allocate a buffer for the SUB */ + + sub = + ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) + + (acpi_size) length); + if (!sub) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Area for the string starts after PNP_DEVICE_ID struct */ + + sub->string = + ACPI_ADD_PTR(char, sub, sizeof(struct acpi_pnp_device_id)); + + /* Simply copy existing string */ + + ACPI_STRCPY(sub->string, obj_desc->string.pointer); + sub->length = length; + *return_id = sub; + + cleanup: + + /* On exit, we must delete the return object */ + + acpi_ut_remove_reference(obj_desc); + return_ACPI_STATUS(status); +} + /******************************************************************************* * * FUNCTION: acpi_ut_execute_UID diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h index 745dd24e3cb..7665df66328 100644 --- a/include/acpi/acnames.h +++ b/include/acpi/acnames.h @@ -50,6 +50,7 @@ #define METHOD_NAME__HID "_HID" #define METHOD_NAME__CID "_CID" #define METHOD_NAME__UID "_UID" +#define METHOD_NAME__SUB "_SUB" #define METHOD_NAME__ADR "_ADR" #define METHOD_NAME__INI "_INI" #define METHOD_NAME__STA "_STA" diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index d1fb674fd39..4f43f1fba13 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -1024,7 +1024,7 @@ u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported); #define ACPI_UUID_LENGTH 16 -/* Structures used for device/processor HID, UID, CID */ +/* Structures used for device/processor HID, UID, CID, and SUB */ struct acpi_pnp_device_id { u32 length; /* Length of string + null */ @@ -1054,6 +1054,7 @@ struct acpi_device_info { u64 address; /* _ADR value */ struct acpi_pnp_device_id hardware_id; /* _HID value */ struct acpi_pnp_device_id unique_id; /* _UID value */ + struct acpi_pnp_device_id subsystem_id; /* _SUB value */ struct acpi_pnp_device_id_list compatible_id_list; /* _CID list */ }; @@ -1067,11 +1068,12 @@ struct acpi_device_info { #define ACPI_VALID_ADR 0x02 #define ACPI_VALID_HID 0x04 #define ACPI_VALID_UID 0x08 -#define ACPI_VALID_CID 0x10 -#define ACPI_VALID_SXDS 0x20 -#define ACPI_VALID_SXWS 0x40 +#define ACPI_VALID_SUB 0x10 +#define ACPI_VALID_CID 0x20 +#define ACPI_VALID_SXDS 0x40 +#define ACPI_VALID_SXWS 0x80 -/* Flags for _STA method */ +/* Flags for _STA return value (current_status above) */ #define ACPI_STA_DEVICE_PRESENT 0x01 #define ACPI_STA_DEVICE_ENABLED 0x02 -- cgit v1.2.3 From a19ec8a607f82885aa150836a72dec12d3c9aca5 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 31 Oct 2012 02:28:46 +0000 Subject: ACPICA: Update version to 20121018 Version 20121018. Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- include/acpi/acpixf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 2596de109ff..3d88395d4d6 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -46,7 +46,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20120913 +#define ACPI_CA_VERSION 0x20121018 #include #include -- cgit v1.2.3 From 8bf1ac723639c4260f76df0e45ee23aa35a23067 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Tue, 23 Oct 2012 01:23:33 +0200 Subject: cpufreq / core: Fix typo in comment describing show_bios_limit() show_bios_limit is mistakenly written as show_scaling_driver in a comment describing purpose of show_bios_limit() routine. Fix it. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index fb8a5279c5d..021973b7dc5 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -581,7 +581,7 @@ static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf) } /** - * show_scaling_driver - show the current cpufreq HW/BIOS limitation + * show_bios_limit - show the current cpufreq HW/BIOS limitation */ static ssize_t show_bios_limit(struct cpufreq_policy *policy, char *buf) { -- cgit v1.2.3 From 4b972f0b04eaae645b22d99479b9aea43c3d64e7 Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Tue, 23 Oct 2012 01:23:43 +0200 Subject: cpufreq / core: Fix printing of governor and driver name Arrays for governer and driver name are of size CPUFREQ_NAME_LEN or 16. i.e. 15 bytes for name and 1 for trailing '\0'. When cpufreq driver print these names (for sysfs), it includes '\n' or ' ' in the fmt string and still passes length as CPUFREQ_NAME_LEN. If the driver or governor names are using all 15 fields allocated to them, then the trailing '\n' or ' ' will never be printed. And so commands like: root@linaro-developer# cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver will print something like: cpufreq_foodrvroot@linaro-developer# Fix this by increasing print length by one character. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 6 +++--- include/linux/cpufreq.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 021973b7dc5..db6e337ad33 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -445,7 +445,7 @@ static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf) else if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) return sprintf(buf, "performance\n"); else if (policy->governor) - return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", + return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", policy->governor->name); return -EINVAL; } @@ -491,7 +491,7 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy, */ static ssize_t show_scaling_driver(struct cpufreq_policy *policy, char *buf) { - return scnprintf(buf, CPUFREQ_NAME_LEN, "%s\n", cpufreq_driver->name); + return scnprintf(buf, CPUFREQ_NAME_PLEN, "%s\n", cpufreq_driver->name); } /** @@ -512,7 +512,7 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy, if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2))) goto out; - i += scnprintf(&buf[i], CPUFREQ_NAME_LEN, "%s ", t->name); + i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name); } out: i += sprintf(&buf[i], "\n"); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index b60f6ba01d0..fc4b7851015 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -22,6 +22,8 @@ #include #define CPUFREQ_NAME_LEN 16 +/* Print length for names. Extra 1 space for accomodating '\n' in prints */ +#define CPUFREQ_NAME_PLEN (CPUFREQ_NAME_LEN + 1) /********************************************************************* -- cgit v1.2.3 From 2aacdfff9c6958723aa5076003247933cefc32ea Mon Sep 17 00:00:00 2001 From: viresh kumar Date: Tue, 23 Oct 2012 01:28:05 +0200 Subject: cpufreq: Move common part from governors to separate file, v2 Multiple cpufreq governers have defined similar get_cpu_idle_time_***() routines. These routines must be moved to some common place, so that all governors can use them. So moving them to cpufreq_governor.c, which seems to be a better place for keeping these routines. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/Makefile | 4 +-- drivers/cpufreq/cpufreq_conservative.c | 34 ---------------------- drivers/cpufreq/cpufreq_governor.c | 52 ++++++++++++++++++++++++++++++++++ drivers/cpufreq/cpufreq_ondemand.c | 34 ---------------------- include/linux/cpufreq.h | 5 ++++ 5 files changed, 59 insertions(+), 70 deletions(-) create mode 100644 drivers/cpufreq/cpufreq_governor.c diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 1bc90e1306d..5b1413e4721 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -7,8 +7,8 @@ obj-$(CONFIG_CPU_FREQ_STAT) += cpufreq_stats.o obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o -obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o -obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o +obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o cpufreq_governor.o +obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o cpufreq_governor.o # CPUfreq cross-arch helpers obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index a152af7e199..181abad0726 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -95,40 +95,6 @@ static struct dbs_tuners { .freq_step = 5, }; -static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) -{ - u64 idle_time; - u64 cur_wall_time; - u64 busy_time; - - cur_wall_time = jiffies64_to_cputime64(get_jiffies_64()); - - busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE]; - - idle_time = cur_wall_time - busy_time; - if (wall) - *wall = jiffies_to_usecs(cur_wall_time); - - return jiffies_to_usecs(idle_time); -} - -static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) -{ - u64 idle_time = get_cpu_idle_time_us(cpu, NULL); - - if (idle_time == -1ULL) - return get_cpu_idle_time_jiffy(cpu, wall); - else - idle_time += get_cpu_iowait_time_us(cpu, wall); - - return idle_time; -} - /* keep track of frequency transitions */ static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c new file mode 100644 index 00000000000..0001071cdcd --- /dev/null +++ b/drivers/cpufreq/cpufreq_governor.c @@ -0,0 +1,52 @@ +/* + * drivers/cpufreq/cpufreq_governor.c + * + * CPUFREQ governors common code + * + * 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. + */ + +#include +#include +#include +#include +#include +/* + * Code picked from earlier governer implementations + */ +static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) +{ + u64 idle_time; + u64 cur_wall_time; + u64 busy_time; + + cur_wall_time = jiffies64_to_cputime64(get_jiffies_64()); + + busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER]; + busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM]; + busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ]; + busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ]; + busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL]; + busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE]; + + idle_time = cur_wall_time - busy_time; + if (wall) + *wall = jiffies_to_usecs(cur_wall_time); + + return jiffies_to_usecs(idle_time); +} + +cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) +{ + u64 idle_time = get_cpu_idle_time_us(cpu, NULL); + + if (idle_time == -1ULL) + return get_cpu_idle_time_jiffy(cpu, wall); + else + idle_time += get_cpu_iowait_time_us(cpu, wall); + + return idle_time; +} +EXPORT_SYMBOL_GPL(get_cpu_idle_time); diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 396322f2a83..d7f774bb49d 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -119,40 +119,6 @@ static struct dbs_tuners { .powersave_bias = 0, }; -static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) -{ - u64 idle_time; - u64 cur_wall_time; - u64 busy_time; - - cur_wall_time = jiffies64_to_cputime64(get_jiffies_64()); - - busy_time = kcpustat_cpu(cpu).cpustat[CPUTIME_USER]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_IRQ]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_SOFTIRQ]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_STEAL]; - busy_time += kcpustat_cpu(cpu).cpustat[CPUTIME_NICE]; - - idle_time = cur_wall_time - busy_time; - if (wall) - *wall = jiffies_to_usecs(cur_wall_time); - - return jiffies_to_usecs(idle_time); -} - -static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) -{ - u64 idle_time = get_cpu_idle_time_us(cpu, NULL); - - if (idle_time == -1ULL) - return get_cpu_idle_time_jiffy(cpu, wall); - else - idle_time += get_cpu_iowait_time_us(cpu, wall); - - return idle_time; -} - static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wall) { u64 iowait_time = get_cpu_iowait_time_us(cpu, wall); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index fc4b7851015..d03c2199305 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -11,6 +11,7 @@ #ifndef _LINUX_CPUFREQ_H #define _LINUX_CPUFREQ_H +#include #include #include #include @@ -407,5 +408,9 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, void cpufreq_frequency_table_put_attr(unsigned int cpu); +/********************************************************************* + * Governor Helpers * + *********************************************************************/ +cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall); #endif /* _LINUX_CPUFREQ_H */ -- cgit v1.2.3 From db7011516cbfc3d867b77721f77258d36cfbf705 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 23 Oct 2012 01:29:03 +0200 Subject: cpufreq: Improve debug prints With debug options on, it is difficult to locate cpufreq core's debug prints. Fix this by prefixing debug prints with KBUILD_MODNAME. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 2 ++ drivers/cpufreq/cpufreq_performance.c | 2 ++ drivers/cpufreq/cpufreq_powersave.c | 2 ++ drivers/cpufreq/cpufreq_userspace.c | 2 ++ drivers/cpufreq/freq_table.c | 2 ++ 5 files changed, 10 insertions(+) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index db6e337ad33..85df5387bc6 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -15,6 +15,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/cpufreq/cpufreq_performance.c b/drivers/cpufreq/cpufreq_performance.c index f13a8a9af6a..ceee06849b9 100644 --- a/drivers/cpufreq/cpufreq_performance.c +++ b/drivers/cpufreq/cpufreq_performance.c @@ -10,6 +10,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/cpufreq/cpufreq_powersave.c b/drivers/cpufreq/cpufreq_powersave.c index 4c2eb512f2b..2d948a17115 100644 --- a/drivers/cpufreq/cpufreq_powersave.c +++ b/drivers/cpufreq/cpufreq_powersave.c @@ -10,6 +10,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index bedac1aa9be..c8c3d293cc5 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -11,6 +11,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 90431cb9280..49cda256efb 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -9,6 +9,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include -- cgit v1.2.3 From 8636fd280e970696be62c8495a5aacb5f3b6237d Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Wed, 24 Oct 2012 22:16:34 +0200 Subject: cpufreq: fix jiffies/cputime mixup in conservative/ondemand governors The function get_cpu_idle_time_jiffy in both the conservative and ondemand governors use jiffies_to_usecs to convert a cputime value to usecs which gives the wrong value on architectures where cputime and jiffies use different units. Only matters if NO_HZ is disabled, since otherwise get_cpu_idle_time_us should already return a valid value, and get_cpu_idle_time_jiffy isn't actually called. Signed-off-by: Andreas Schwab Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq_governor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 0001071cdcd..679842a8d34 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -33,9 +33,9 @@ static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) idle_time = cur_wall_time - busy_time; if (wall) - *wall = jiffies_to_usecs(cur_wall_time); + *wall = cputime_to_usecs(cur_wall_time); - return jiffies_to_usecs(idle_time); + return cputime_to_usecs(idle_time); } cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) -- cgit v1.2.3 From 0676f7f2e7d2adec11f40320ca43a8897b8ef906 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 24 Oct 2012 23:39:48 +0200 Subject: cpufreq: return early from __cpufreq_driver_getavg() There is no need to do cpufreq_get_cpu() and cpufreq_put_cpu() for drivers that don't support getavg() routine. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 85df5387bc6..f552d5fe0f8 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1511,12 +1511,14 @@ int __cpufreq_driver_getavg(struct cpufreq_policy *policy, unsigned int cpu) { int ret = 0; + if (!(cpu_online(cpu) && cpufreq_driver->getavg)) + return 0; + policy = cpufreq_cpu_get(policy->cpu); if (!policy) return -EINVAL; - if (cpu_online(cpu) && cpufreq_driver->getavg) - ret = cpufreq_driver->getavg(policy, cpu); + ret = cpufreq_driver->getavg(policy, cpu); cpufreq_cpu_put(policy); return ret; -- cgit v1.2.3 From 4471a34f9a1f2da220272e823bdb8e8fa83a7661 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 26 Oct 2012 00:47:42 +0200 Subject: cpufreq: governors: remove redundant code Initially ondemand governor was written and then using its code conservative governor is written. It used a lot of code from ondemand governor, but copy of code was created instead of using the same routines from both governors. Which increased code redundancy, which is difficult to manage. This patch is an attempt to move common part of both the governors to cpufreq_governor.c file to come over above mentioned issues. This shouldn't change anything from functionality point of view. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq_conservative.c | 548 ++++++++------------------ drivers/cpufreq/cpufreq_governor.c | 276 ++++++++++++- drivers/cpufreq/cpufreq_governor.h | 177 +++++++++ drivers/cpufreq/cpufreq_ondemand.c | 698 +++++++++++---------------------- include/linux/cpufreq.h | 6 - 5 files changed, 832 insertions(+), 873 deletions(-) create mode 100644 drivers/cpufreq/cpufreq_governor.h diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 181abad0726..64ef737e7e7 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -11,83 +11,30 @@ * published by the Free Software Foundation. */ -#include -#include -#include #include -#include -#include +#include +#include #include +#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include -/* - * dbs is used in this file as a shortform for demandbased switching - * It helps to keep variable names smaller, simpler - */ +#include "cpufreq_governor.h" +/* Conservative governor macors */ #define DEF_FREQUENCY_UP_THRESHOLD (80) #define DEF_FREQUENCY_DOWN_THRESHOLD (20) - -/* - * The polling frequency of this governor depends on the capability of - * the processor. Default polling frequency is 1000 times the transition - * latency of the processor. The governor will work on any processor with - * transition latency <= 10mS, using appropriate sampling - * rate. - * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL) - * this governor will not work. - * All times here are in uS. - */ -#define MIN_SAMPLING_RATE_RATIO (2) - -static unsigned int min_sampling_rate; - -#define LATENCY_MULTIPLIER (1000) -#define MIN_LATENCY_MULTIPLIER (100) #define DEF_SAMPLING_DOWN_FACTOR (1) #define MAX_SAMPLING_DOWN_FACTOR (10) -#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) - -static void do_dbs_timer(struct work_struct *work); - -struct cpu_dbs_info_s { - cputime64_t prev_cpu_idle; - cputime64_t prev_cpu_wall; - cputime64_t prev_cpu_nice; - struct cpufreq_policy *cur_policy; - struct delayed_work work; - unsigned int down_skip; - unsigned int requested_freq; - int cpu; - unsigned int enable:1; - /* - * percpu mutex that serializes governor limit change with - * do_dbs_timer invocation. We do not want do_dbs_timer to run - * when user is changing the governor or limits. - */ - struct mutex timer_mutex; -}; -static DEFINE_PER_CPU(struct cpu_dbs_info_s, cs_cpu_dbs_info); -static unsigned int dbs_enable; /* number of CPUs using this policy */ +static struct dbs_data cs_dbs_data; +static DEFINE_PER_CPU(struct cs_cpu_dbs_info_s, cs_cpu_dbs_info); -/* - * dbs_mutex protects dbs_enable in governor start/stop. - */ -static DEFINE_MUTEX(dbs_mutex); - -static struct dbs_tuners { - unsigned int sampling_rate; - unsigned int sampling_down_factor; - unsigned int up_threshold; - unsigned int down_threshold; - unsigned int ignore_nice; - unsigned int freq_step; -} dbs_tuners_ins = { +static struct cs_dbs_tuners cs_tuners = { .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, .down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD, .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, @@ -95,61 +42,121 @@ static struct dbs_tuners { .freq_step = 5, }; -/* keep track of frequency transitions */ -static int -dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, - void *data) +/* + * Every sampling_rate, we check, if current idle time is less than 20% + * (default), then we try to increase frequency Every sampling_rate * + * sampling_down_factor, we check, if current idle time is more than 80%, then + * we try to decrease frequency + * + * Any frequency increase takes it to the maximum frequency. Frequency reduction + * happens at minimum steps of 5% (default) of maximum frequency + */ +static void cs_check_cpu(int cpu, unsigned int load) { - struct cpufreq_freqs *freq = data; - struct cpu_dbs_info_s *this_dbs_info = &per_cpu(cs_cpu_dbs_info, - freq->cpu); + struct cs_cpu_dbs_info_s *dbs_info = &per_cpu(cs_cpu_dbs_info, cpu); + struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy; + unsigned int freq_target; + + /* + * break out if we 'cannot' reduce the speed as the user might + * want freq_step to be zero + */ + if (cs_tuners.freq_step == 0) + return; + + /* Check for frequency increase */ + if (load > cs_tuners.up_threshold) { + dbs_info->down_skip = 0; + + /* if we are already at full speed then break out early */ + if (dbs_info->requested_freq == policy->max) + return; + + freq_target = (cs_tuners.freq_step * policy->max) / 100; + + /* max freq cannot be less than 100. But who knows.... */ + if (unlikely(freq_target == 0)) + freq_target = 5; + + dbs_info->requested_freq += freq_target; + if (dbs_info->requested_freq > policy->max) + dbs_info->requested_freq = policy->max; + __cpufreq_driver_target(policy, dbs_info->requested_freq, + CPUFREQ_RELATION_H); + return; + } + + /* + * The optimal frequency is the frequency that is the lowest that can + * support the current CPU usage without triggering the up policy. To be + * safe, we focus 10 points under the threshold. + */ + if (load < (cs_tuners.down_threshold - 10)) { + freq_target = (cs_tuners.freq_step * policy->max) / 100; + + dbs_info->requested_freq -= freq_target; + if (dbs_info->requested_freq < policy->min) + dbs_info->requested_freq = policy->min; + + /* + * if we cannot reduce the frequency anymore, break out early + */ + if (policy->cur == policy->min) + return; + + __cpufreq_driver_target(policy, dbs_info->requested_freq, + CPUFREQ_RELATION_H); + return; + } +} + +static void cs_dbs_timer(struct work_struct *work) +{ + struct cs_cpu_dbs_info_s *dbs_info = container_of(work, + struct cs_cpu_dbs_info_s, cdbs.work.work); + unsigned int cpu = dbs_info->cdbs.cpu; + int delay = delay_for_sampling_rate(cs_tuners.sampling_rate); + + mutex_lock(&dbs_info->cdbs.timer_mutex); + + dbs_check_cpu(&cs_dbs_data, cpu); + + schedule_delayed_work_on(cpu, &dbs_info->cdbs.work, delay); + mutex_unlock(&dbs_info->cdbs.timer_mutex); +} + +static int dbs_cpufreq_notifier(struct notifier_block *nb, unsigned long val, + void *data) +{ + struct cpufreq_freqs *freq = data; + struct cs_cpu_dbs_info_s *dbs_info = + &per_cpu(cs_cpu_dbs_info, freq->cpu); struct cpufreq_policy *policy; - if (!this_dbs_info->enable) + if (!dbs_info->enable) return 0; - policy = this_dbs_info->cur_policy; + policy = dbs_info->cdbs.cur_policy; /* - * we only care if our internally tracked freq moves outside - * the 'valid' ranges of freqency available to us otherwise - * we do not change it + * we only care if our internally tracked freq moves outside the 'valid' + * ranges of freqency available to us otherwise we do not change it */ - if (this_dbs_info->requested_freq > policy->max - || this_dbs_info->requested_freq < policy->min) - this_dbs_info->requested_freq = freq->new; + if (dbs_info->requested_freq > policy->max + || dbs_info->requested_freq < policy->min) + dbs_info->requested_freq = freq->new; return 0; } -static struct notifier_block dbs_cpufreq_notifier_block = { - .notifier_call = dbs_cpufreq_notifier -}; - /************************** sysfs interface ************************/ static ssize_t show_sampling_rate_min(struct kobject *kobj, struct attribute *attr, char *buf) { - return sprintf(buf, "%u\n", min_sampling_rate); + return sprintf(buf, "%u\n", cs_dbs_data.min_sampling_rate); } -define_one_global_ro(sampling_rate_min); - -/* cpufreq_conservative Governor Tunables */ -#define show_one(file_name, object) \ -static ssize_t show_##file_name \ -(struct kobject *kobj, struct attribute *attr, char *buf) \ -{ \ - return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ -} -show_one(sampling_rate, sampling_rate); -show_one(sampling_down_factor, sampling_down_factor); -show_one(up_threshold, up_threshold); -show_one(down_threshold, down_threshold); -show_one(ignore_nice_load, ignore_nice); -show_one(freq_step, freq_step); - static ssize_t store_sampling_down_factor(struct kobject *a, struct attribute *b, const char *buf, size_t count) @@ -161,7 +168,7 @@ static ssize_t store_sampling_down_factor(struct kobject *a, if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1) return -EINVAL; - dbs_tuners_ins.sampling_down_factor = input; + cs_tuners.sampling_down_factor = input; return count; } @@ -175,7 +182,7 @@ static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b, if (ret != 1) return -EINVAL; - dbs_tuners_ins.sampling_rate = max(input, min_sampling_rate); + cs_tuners.sampling_rate = max(input, cs_dbs_data.min_sampling_rate); return count; } @@ -186,11 +193,10 @@ static ssize_t store_up_threshold(struct kobject *a, struct attribute *b, int ret; ret = sscanf(buf, "%u", &input); - if (ret != 1 || input > 100 || - input <= dbs_tuners_ins.down_threshold) + if (ret != 1 || input > 100 || input <= cs_tuners.down_threshold) return -EINVAL; - dbs_tuners_ins.up_threshold = input; + cs_tuners.up_threshold = input; return count; } @@ -203,21 +209,19 @@ static ssize_t store_down_threshold(struct kobject *a, struct attribute *b, /* cannot be lower than 11 otherwise freq will not fall */ if (ret != 1 || input < 11 || input > 100 || - input >= dbs_tuners_ins.up_threshold) + input >= cs_tuners.up_threshold) return -EINVAL; - dbs_tuners_ins.down_threshold = input; + cs_tuners.down_threshold = input; return count; } static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b, const char *buf, size_t count) { - unsigned int input; + unsigned int input, j; int ret; - unsigned int j; - ret = sscanf(buf, "%u", &input); if (ret != 1) return -EINVAL; @@ -225,19 +229,20 @@ static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b, if (input > 1) input = 1; - if (input == dbs_tuners_ins.ignore_nice) /* nothing to do */ + if (input == cs_tuners.ignore_nice) /* nothing to do */ return count; - dbs_tuners_ins.ignore_nice = input; + cs_tuners.ignore_nice = input; /* we need to re-evaluate prev_cpu_idle */ for_each_online_cpu(j) { - struct cpu_dbs_info_s *dbs_info; + struct cs_cpu_dbs_info_s *dbs_info; dbs_info = &per_cpu(cs_cpu_dbs_info, j); - dbs_info->prev_cpu_idle = get_cpu_idle_time(j, - &dbs_info->prev_cpu_wall); - if (dbs_tuners_ins.ignore_nice) - dbs_info->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE]; + dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j, + &dbs_info->cdbs.prev_cpu_wall); + if (cs_tuners.ignore_nice) + dbs_info->cdbs.prev_cpu_nice = + kcpustat_cpu(j).cpustat[CPUTIME_NICE]; } return count; } @@ -255,18 +260,28 @@ static ssize_t store_freq_step(struct kobject *a, struct attribute *b, if (input > 100) input = 100; - /* no need to test here if freq_step is zero as the user might actually - * want this, they would be crazy though :) */ - dbs_tuners_ins.freq_step = input; + /* + * no need to test here if freq_step is zero as the user might actually + * want this, they would be crazy though :) + */ + cs_tuners.freq_step = input; return count; } +show_one(cs, sampling_rate, sampling_rate); +show_one(cs, sampling_down_factor, sampling_down_factor); +show_one(cs, up_threshold, up_threshold); +show_one(cs, down_threshold, down_threshold); +show_one(cs, ignore_nice_load, ignore_nice); +show_one(cs, freq_step, freq_step); + define_one_global_rw(sampling_rate); define_one_global_rw(sampling_down_factor); define_one_global_rw(up_threshold); define_one_global_rw(down_threshold); define_one_global_rw(ignore_nice_load); define_one_global_rw(freq_step); +define_one_global_ro(sampling_rate_min); static struct attribute *dbs_attributes[] = { &sampling_rate_min.attr, @@ -279,283 +294,38 @@ static struct attribute *dbs_attributes[] = { NULL }; -static struct attribute_group dbs_attr_group = { +static struct attribute_group cs_attr_group = { .attrs = dbs_attributes, .name = "conservative", }; /************************** sysfs end ************************/ -static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) -{ - unsigned int load = 0; - unsigned int max_load = 0; - unsigned int freq_target; - - struct cpufreq_policy *policy; - unsigned int j; - - policy = this_dbs_info->cur_policy; - - /* - * Every sampling_rate, we check, if current idle time is less - * than 20% (default), then we try to increase frequency - * Every sampling_rate*sampling_down_factor, we check, if current - * idle time is more than 80%, then we try to decrease frequency - * - * Any frequency increase takes it to the maximum frequency. - * Frequency reduction happens at minimum steps of - * 5% (default) of maximum frequency - */ - - /* Get Absolute Load */ - for_each_cpu(j, policy->cpus) { - struct cpu_dbs_info_s *j_dbs_info; - cputime64_t cur_wall_time, cur_idle_time; - unsigned int idle_time, wall_time; - - j_dbs_info = &per_cpu(cs_cpu_dbs_info, j); - - cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); - - wall_time = (unsigned int) - (cur_wall_time - j_dbs_info->prev_cpu_wall); - j_dbs_info->prev_cpu_wall = cur_wall_time; - - idle_time = (unsigned int) - (cur_idle_time - j_dbs_info->prev_cpu_idle); - j_dbs_info->prev_cpu_idle = cur_idle_time; - - if (dbs_tuners_ins.ignore_nice) { - u64 cur_nice; - unsigned long cur_nice_jiffies; - - cur_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE] - - j_dbs_info->prev_cpu_nice; - /* - * Assumption: nice time between sampling periods will - * be less than 2^32 jiffies for 32 bit sys - */ - cur_nice_jiffies = (unsigned long) - cputime64_to_jiffies64(cur_nice); - - j_dbs_info->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE]; - idle_time += jiffies_to_usecs(cur_nice_jiffies); - } - - if (unlikely(!wall_time || wall_time < idle_time)) - continue; - - load = 100 * (wall_time - idle_time) / wall_time; - - if (load > max_load) - max_load = load; - } +define_get_cpu_dbs_routines(cs_cpu_dbs_info); - /* - * break out if we 'cannot' reduce the speed as the user might - * want freq_step to be zero - */ - if (dbs_tuners_ins.freq_step == 0) - return; - - /* Check for frequency increase */ - if (max_load > dbs_tuners_ins.up_threshold) { - this_dbs_info->down_skip = 0; - - /* if we are already at full speed then break out early */ - if (this_dbs_info->requested_freq == policy->max) - return; - - freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100; - - /* max freq cannot be less than 100. But who knows.... */ - if (unlikely(freq_target == 0)) - freq_target = 5; - - this_dbs_info->requested_freq += freq_target; - if (this_dbs_info->requested_freq > policy->max) - this_dbs_info->requested_freq = policy->max; - - __cpufreq_driver_target(policy, this_dbs_info->requested_freq, - CPUFREQ_RELATION_H); - return; - } - - /* - * The optimal frequency is the frequency that is the lowest that - * can support the current CPU usage without triggering the up - * policy. To be safe, we focus 10 points under the threshold. - */ - if (max_load < (dbs_tuners_ins.down_threshold - 10)) { - freq_target = (dbs_tuners_ins.freq_step * policy->max) / 100; - - this_dbs_info->requested_freq -= freq_target; - if (this_dbs_info->requested_freq < policy->min) - this_dbs_info->requested_freq = policy->min; - - /* - * if we cannot reduce the frequency anymore, break out early - */ - if (policy->cur == policy->min) - return; - - __cpufreq_driver_target(policy, this_dbs_info->requested_freq, - CPUFREQ_RELATION_H); - return; - } -} - -static void do_dbs_timer(struct work_struct *work) -{ - struct cpu_dbs_info_s *dbs_info = - container_of(work, struct cpu_dbs_info_s, work.work); - unsigned int cpu = dbs_info->cpu; - - /* We want all CPUs to do sampling nearly on same jiffy */ - int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); - - delay -= jiffies % delay; - - mutex_lock(&dbs_info->timer_mutex); - - dbs_check_cpu(dbs_info); - - schedule_delayed_work_on(cpu, &dbs_info->work, delay); - mutex_unlock(&dbs_info->timer_mutex); -} - -static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) -{ - /* We want all CPUs to do sampling nearly on same jiffy */ - int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); - delay -= jiffies % delay; +static struct notifier_block cs_cpufreq_notifier_block = { + .notifier_call = dbs_cpufreq_notifier, +}; - dbs_info->enable = 1; - INIT_DEFERRABLE_WORK(&dbs_info->work, do_dbs_timer); - schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay); -} +static struct cs_ops cs_ops = { + .notifier_block = &cs_cpufreq_notifier_block, +}; -static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) -{ - dbs_info->enable = 0; - cancel_delayed_work_sync(&dbs_info->work); -} +static struct dbs_data cs_dbs_data = { + .governor = GOV_CONSERVATIVE, + .attr_group = &cs_attr_group, + .tuners = &cs_tuners, + .get_cpu_cdbs = get_cpu_cdbs, + .get_cpu_dbs_info_s = get_cpu_dbs_info_s, + .gov_dbs_timer = cs_dbs_timer, + .gov_check_cpu = cs_check_cpu, + .gov_ops = &cs_ops, +}; -static int cpufreq_governor_dbs(struct cpufreq_policy *policy, +static int cs_cpufreq_governor_dbs(struct cpufreq_policy *policy, unsigned int event) { - unsigned int cpu = policy->cpu; - struct cpu_dbs_info_s *this_dbs_info; - unsigned int j; - int rc; - - this_dbs_info = &per_cpu(cs_cpu_dbs_info, cpu); - - switch (event) { - case CPUFREQ_GOV_START: - if ((!cpu_online(cpu)) || (!policy->cur)) - return -EINVAL; - - mutex_lock(&dbs_mutex); - - for_each_cpu(j, policy->cpus) { - struct cpu_dbs_info_s *j_dbs_info; - j_dbs_info = &per_cpu(cs_cpu_dbs_info, j); - j_dbs_info->cur_policy = policy; - - j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j, - &j_dbs_info->prev_cpu_wall); - if (dbs_tuners_ins.ignore_nice) - j_dbs_info->prev_cpu_nice = - kcpustat_cpu(j).cpustat[CPUTIME_NICE]; - } - this_dbs_info->cpu = cpu; - this_dbs_info->down_skip = 0; - this_dbs_info->requested_freq = policy->cur; - - mutex_init(&this_dbs_info->timer_mutex); - dbs_enable++; - /* - * Start the timerschedule work, when this governor - * is used for first time - */ - if (dbs_enable == 1) { - unsigned int latency; - /* policy latency is in nS. Convert it to uS first */ - latency = policy->cpuinfo.transition_latency / 1000; - if (latency == 0) - latency = 1; - - rc = sysfs_create_group(cpufreq_global_kobject, - &dbs_attr_group); - if (rc) { - mutex_unlock(&dbs_mutex); - return rc; - } - - /* - * conservative does not implement micro like ondemand - * governor, thus we are bound to jiffes/HZ - */ - min_sampling_rate = - MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10); - /* Bring kernel and HW constraints together */ - min_sampling_rate = max(min_sampling_rate, - MIN_LATENCY_MULTIPLIER * latency); - dbs_tuners_ins.sampling_rate = - max(min_sampling_rate, - latency * LATENCY_MULTIPLIER); - - cpufreq_register_notifier( - &dbs_cpufreq_notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); - } - mutex_unlock(&dbs_mutex); - - dbs_timer_init(this_dbs_info); - - break; - - case CPUFREQ_GOV_STOP: - dbs_timer_exit(this_dbs_info); - - mutex_lock(&dbs_mutex); - dbs_enable--; - mutex_destroy(&this_dbs_info->timer_mutex); - - /* - * Stop the timerschedule work, when this governor - * is used for first time - */ - if (dbs_enable == 0) - cpufreq_unregister_notifier( - &dbs_cpufreq_notifier_block, - CPUFREQ_TRANSITION_NOTIFIER); - - mutex_unlock(&dbs_mutex); - if (!dbs_enable) - sysfs_remove_group(cpufreq_global_kobject, - &dbs_attr_group); - - break; - - case CPUFREQ_GOV_LIMITS: - mutex_lock(&this_dbs_info->timer_mutex); - if (policy->max < this_dbs_info->cur_policy->cur) - __cpufreq_driver_target( - this_dbs_info->cur_policy, - policy->max, CPUFREQ_RELATION_H); - else if (policy->min > this_dbs_info->cur_policy->cur) - __cpufreq_driver_target( - this_dbs_info->cur_policy, - policy->min, CPUFREQ_RELATION_L); - dbs_check_cpu(this_dbs_info); - mutex_unlock(&this_dbs_info->timer_mutex); - - break; - } - return 0; + return cpufreq_governor_dbs(&cs_dbs_data, policy, event); } #ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE @@ -563,13 +333,14 @@ static #endif struct cpufreq_governor cpufreq_gov_conservative = { .name = "conservative", - .governor = cpufreq_governor_dbs, + .governor = cs_cpufreq_governor_dbs, .max_transition_latency = TRANSITION_LATENCY_LIMIT, .owner = THIS_MODULE, }; static int __init cpufreq_gov_dbs_init(void) { + mutex_init(&cs_dbs_data.mutex); return cpufreq_register_governor(&cpufreq_gov_conservative); } @@ -578,7 +349,6 @@ static void __exit cpufreq_gov_dbs_exit(void) cpufreq_unregister_governor(&cpufreq_gov_conservative); } - MODULE_AUTHOR("Alexander Clouter "); MODULE_DESCRIPTION("'cpufreq_conservative' - A dynamic cpufreq governor for " "Low Latency Frequency Transition capable processors " diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 679842a8d34..5ea2c829a79 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -3,19 +3,31 @@ * * CPUFREQ governors common code * + * Copyright (C) 2001 Russell King + * (C) 2003 Venkatesh Pallipadi . + * (C) 2003 Jun Nakajima + * (C) 2009 Alexander Clouter + * (c) 2012 Viresh Kumar + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include +#include +#include #include #include +#include #include #include -/* - * Code picked from earlier governer implementations - */ +#include + +#include "cpufreq_governor.h" + static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) { u64 idle_time; @@ -33,9 +45,9 @@ static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) idle_time = cur_wall_time - busy_time; if (wall) - *wall = cputime_to_usecs(cur_wall_time); + *wall = jiffies_to_usecs(cur_wall_time); - return cputime_to_usecs(idle_time); + return jiffies_to_usecs(idle_time); } cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) @@ -50,3 +62,257 @@ cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) return idle_time; } EXPORT_SYMBOL_GPL(get_cpu_idle_time); + +void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) +{ + struct cpu_dbs_common_info *cdbs = dbs_data->get_cpu_cdbs(cpu); + struct od_dbs_tuners *od_tuners = dbs_data->tuners; + struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; + struct cpufreq_policy *policy; + unsigned int max_load = 0; + unsigned int ignore_nice; + unsigned int j; + + if (dbs_data->governor == GOV_ONDEMAND) + ignore_nice = od_tuners->ignore_nice; + else + ignore_nice = cs_tuners->ignore_nice; + + policy = cdbs->cur_policy; + + /* Get Absolute Load (in terms of freq for ondemand gov) */ + for_each_cpu(j, policy->cpus) { + struct cpu_dbs_common_info *j_cdbs; + cputime64_t cur_wall_time, cur_idle_time, cur_iowait_time; + unsigned int idle_time, wall_time, iowait_time; + unsigned int load; + + j_cdbs = dbs_data->get_cpu_cdbs(j); + + cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); + + wall_time = (unsigned int) + (cur_wall_time - j_cdbs->prev_cpu_wall); + j_cdbs->prev_cpu_wall = cur_wall_time; + + idle_time = (unsigned int) + (cur_idle_time - j_cdbs->prev_cpu_idle); + j_cdbs->prev_cpu_idle = cur_idle_time; + + if (ignore_nice) { + u64 cur_nice; + unsigned long cur_nice_jiffies; + + cur_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE] - + cdbs->prev_cpu_nice; + /* + * Assumption: nice time between sampling periods will + * be less than 2^32 jiffies for 32 bit sys + */ + cur_nice_jiffies = (unsigned long) + cputime64_to_jiffies64(cur_nice); + + cdbs->prev_cpu_nice = + kcpustat_cpu(j).cpustat[CPUTIME_NICE]; + idle_time += jiffies_to_usecs(cur_nice_jiffies); + } + + if (dbs_data->governor == GOV_ONDEMAND) { + struct od_cpu_dbs_info_s *od_j_dbs_info = + dbs_data->get_cpu_dbs_info_s(cpu); + + cur_iowait_time = get_cpu_iowait_time_us(j, + &cur_wall_time); + if (cur_iowait_time == -1ULL) + cur_iowait_time = 0; + + iowait_time = (unsigned int) (cur_iowait_time - + od_j_dbs_info->prev_cpu_iowait); + od_j_dbs_info->prev_cpu_iowait = cur_iowait_time; + + /* + * For the purpose of ondemand, waiting for disk IO is + * an indication that you're performance critical, and + * not that the system is actually idle. So subtract the + * iowait time from the cpu idle time. + */ + if (od_tuners->io_is_busy && idle_time >= iowait_time) + idle_time -= iowait_time; + } + + if (unlikely(!wall_time || wall_time < idle_time)) + continue; + + load = 100 * (wall_time - idle_time) / wall_time; + + if (dbs_data->governor == GOV_ONDEMAND) { + int freq_avg = __cpufreq_driver_getavg(policy, j); + if (freq_avg <= 0) + freq_avg = policy->cur; + + load *= freq_avg; + } + + if (load > max_load) + max_load = load; + } + + dbs_data->gov_check_cpu(cpu, max_load); +} +EXPORT_SYMBOL_GPL(dbs_check_cpu); + +static inline void dbs_timer_init(struct dbs_data *dbs_data, + struct cpu_dbs_common_info *cdbs, unsigned int sampling_rate) +{ + int delay = delay_for_sampling_rate(sampling_rate); + + INIT_DEFERRABLE_WORK(&cdbs->work, dbs_data->gov_dbs_timer); + schedule_delayed_work_on(cdbs->cpu, &cdbs->work, delay); +} + +static inline void dbs_timer_exit(struct cpu_dbs_common_info *cdbs) +{ + cancel_delayed_work_sync(&cdbs->work); +} + +int cpufreq_governor_dbs(struct dbs_data *dbs_data, + struct cpufreq_policy *policy, unsigned int event) +{ + struct od_cpu_dbs_info_s *od_dbs_info = NULL; + struct cs_cpu_dbs_info_s *cs_dbs_info = NULL; + struct od_dbs_tuners *od_tuners = dbs_data->tuners; + struct cs_dbs_tuners *cs_tuners = dbs_data->tuners; + struct cpu_dbs_common_info *cpu_cdbs; + unsigned int *sampling_rate, latency, ignore_nice, j, cpu = policy->cpu; + int rc; + + cpu_cdbs = dbs_data->get_cpu_cdbs(cpu); + + if (dbs_data->governor == GOV_CONSERVATIVE) { + cs_dbs_info = dbs_data->get_cpu_dbs_info_s(cpu); + sampling_rate = &cs_tuners->sampling_rate; + ignore_nice = cs_tuners->ignore_nice; + } else { + od_dbs_info = dbs_data->get_cpu_dbs_info_s(cpu); + sampling_rate = &od_tuners->sampling_rate; + ignore_nice = od_tuners->ignore_nice; + } + + switch (event) { + case CPUFREQ_GOV_START: + if ((!cpu_online(cpu)) || (!policy->cur)) + return -EINVAL; + + mutex_lock(&dbs_data->mutex); + + dbs_data->enable++; + cpu_cdbs->cpu = cpu; + for_each_cpu(j, policy->cpus) { + struct cpu_dbs_common_info *j_cdbs; + j_cdbs = dbs_data->get_cpu_cdbs(j); + + j_cdbs->cur_policy = policy; + j_cdbs->prev_cpu_idle = get_cpu_idle_time(j, + &j_cdbs->prev_cpu_wall); + if (ignore_nice) + j_cdbs->prev_cpu_nice = + kcpustat_cpu(j).cpustat[CPUTIME_NICE]; + } + + /* + * Start the timerschedule work, when this governor is used for + * first time + */ + if (dbs_data->enable != 1) + goto second_time; + + rc = sysfs_create_group(cpufreq_global_kobject, + dbs_data->attr_group); + if (rc) { + mutex_unlock(&dbs_data->mutex); + return rc; + } + + /* policy latency is in nS. Convert it to uS first */ + latency = policy->cpuinfo.transition_latency / 1000; + if (latency == 0) + latency = 1; + + /* + * conservative does not implement micro like ondemand + * governor, thus we are bound to jiffes/HZ + */ + if (dbs_data->governor == GOV_CONSERVATIVE) { + struct cs_ops *ops = dbs_data->gov_ops; + + cpufreq_register_notifier(ops->notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + + dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * + jiffies_to_usecs(10); + } else { + struct od_ops *ops = dbs_data->gov_ops; + + od_tuners->io_is_busy = ops->io_busy(); + } + + /* Bring kernel and HW constraints together */ + dbs_data->min_sampling_rate = max(dbs_data->min_sampling_rate, + MIN_LATENCY_MULTIPLIER * latency); + *sampling_rate = max(dbs_data->min_sampling_rate, latency * + LATENCY_MULTIPLIER); + +second_time: + if (dbs_data->governor == GOV_CONSERVATIVE) { + cs_dbs_info->down_skip = 0; + cs_dbs_info->enable = 1; + cs_dbs_info->requested_freq = policy->cur; + } else { + struct od_ops *ops = dbs_data->gov_ops; + od_dbs_info->rate_mult = 1; + od_dbs_info->sample_type = OD_NORMAL_SAMPLE; + ops->powersave_bias_init_cpu(cpu); + } + mutex_unlock(&dbs_data->mutex); + + mutex_init(&cpu_cdbs->timer_mutex); + dbs_timer_init(dbs_data, cpu_cdbs, *sampling_rate); + break; + + case CPUFREQ_GOV_STOP: + if (dbs_data->governor == GOV_CONSERVATIVE) + cs_dbs_info->enable = 0; + + dbs_timer_exit(cpu_cdbs); + + mutex_lock(&dbs_data->mutex); + mutex_destroy(&cpu_cdbs->timer_mutex); + dbs_data->enable--; + if (!dbs_data->enable) { + struct cs_ops *ops = dbs_data->gov_ops; + + sysfs_remove_group(cpufreq_global_kobject, + dbs_data->attr_group); + if (dbs_data->governor == GOV_CONSERVATIVE) + cpufreq_unregister_notifier(ops->notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); + } + mutex_unlock(&dbs_data->mutex); + + break; + + case CPUFREQ_GOV_LIMITS: + mutex_lock(&cpu_cdbs->timer_mutex); + if (policy->max < cpu_cdbs->cur_policy->cur) + __cpufreq_driver_target(cpu_cdbs->cur_policy, + policy->max, CPUFREQ_RELATION_H); + else if (policy->min > cpu_cdbs->cur_policy->cur) + __cpufreq_driver_target(cpu_cdbs->cur_policy, + policy->min, CPUFREQ_RELATION_L); + dbs_check_cpu(dbs_data, cpu); + mutex_unlock(&cpu_cdbs->timer_mutex); + break; + } + return 0; +} +EXPORT_SYMBOL_GPL(cpufreq_governor_dbs); diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h new file mode 100644 index 00000000000..34e14adfc3f --- /dev/null +++ b/drivers/cpufreq/cpufreq_governor.h @@ -0,0 +1,177 @@ +/* + * drivers/cpufreq/cpufreq_governor.h + * + * Header file for CPUFreq governors common code + * + * Copyright (C) 2001 Russell King + * (C) 2003 Venkatesh Pallipadi . + * (C) 2003 Jun Nakajima + * (C) 2009 Alexander Clouter + * (c) 2012 Viresh Kumar + * + * 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. + */ + +#ifndef _CPUFREQ_GOVERNER_H +#define _CPUFREQ_GOVERNER_H + +#include +#include +#include +#include +#include +#include + +/* + * The polling frequency depends on the capability of the processor. Default + * polling frequency is 1000 times the transition latency of the processor. The + * governor will work on any processor with transition latency <= 10mS, using + * appropriate sampling rate. + * + * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL) + * this governor will not work. All times here are in uS. + */ +#define MIN_SAMPLING_RATE_RATIO (2) +#define LATENCY_MULTIPLIER (1000) +#define MIN_LATENCY_MULTIPLIER (100) +#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) + +/* Ondemand Sampling types */ +enum {OD_NORMAL_SAMPLE, OD_SUB_SAMPLE}; + +/* Macro creating sysfs show routines */ +#define show_one(_gov, file_name, object) \ +static ssize_t show_##file_name \ +(struct kobject *kobj, struct attribute *attr, char *buf) \ +{ \ + return sprintf(buf, "%u\n", _gov##_tuners.object); \ +} + +#define define_get_cpu_dbs_routines(_dbs_info) \ +static struct cpu_dbs_common_info *get_cpu_cdbs(int cpu) \ +{ \ + return &per_cpu(_dbs_info, cpu).cdbs; \ +} \ + \ +static void *get_cpu_dbs_info_s(int cpu) \ +{ \ + return &per_cpu(_dbs_info, cpu); \ +} + +/* + * Abbreviations: + * dbs: used as a shortform for demand based switching It helps to keep variable + * names smaller, simpler + * cdbs: common dbs + * on_*: On-demand governor + * cs_*: Conservative governor + */ + +/* Per cpu structures */ +struct cpu_dbs_common_info { + int cpu; + cputime64_t prev_cpu_idle; + cputime64_t prev_cpu_wall; + cputime64_t prev_cpu_nice; + struct cpufreq_policy *cur_policy; + struct delayed_work work; + /* + * percpu mutex that serializes governor limit change with gov_dbs_timer + * invocation. We do not want gov_dbs_timer to run when user is changing + * the governor or limits. + */ + struct mutex timer_mutex; +}; + +struct od_cpu_dbs_info_s { + struct cpu_dbs_common_info cdbs; + cputime64_t prev_cpu_iowait; + struct cpufreq_frequency_table *freq_table; + unsigned int freq_lo; + unsigned int freq_lo_jiffies; + unsigned int freq_hi_jiffies; + unsigned int rate_mult; + unsigned int sample_type:1; +}; + +struct cs_cpu_dbs_info_s { + struct cpu_dbs_common_info cdbs; + unsigned int down_skip; + unsigned int requested_freq; + unsigned int enable:1; +}; + +/* Governers sysfs tunables */ +struct od_dbs_tuners { + unsigned int ignore_nice; + unsigned int sampling_rate; + unsigned int sampling_down_factor; + unsigned int up_threshold; + unsigned int down_differential; + unsigned int powersave_bias; + unsigned int io_is_busy; +}; + +struct cs_dbs_tuners { + unsigned int ignore_nice; + unsigned int sampling_rate; + unsigned int sampling_down_factor; + unsigned int up_threshold; + unsigned int down_threshold; + unsigned int freq_step; +}; + +/* Per Governer data */ +struct dbs_data { + /* Common across governors */ + #define GOV_ONDEMAND 0 + #define GOV_CONSERVATIVE 1 + int governor; + unsigned int min_sampling_rate; + unsigned int enable; /* number of CPUs using this policy */ + struct attribute_group *attr_group; + void *tuners; + + /* dbs_mutex protects dbs_enable in governor start/stop */ + struct mutex mutex; + + struct cpu_dbs_common_info *(*get_cpu_cdbs)(int cpu); + void *(*get_cpu_dbs_info_s)(int cpu); + void (*gov_dbs_timer)(struct work_struct *work); + void (*gov_check_cpu)(int cpu, unsigned int load); + + /* Governor specific ops, see below */ + void *gov_ops; +}; + +/* Governor specific ops, will be passed to dbs_data->gov_ops */ +struct od_ops { + int (*io_busy)(void); + void (*powersave_bias_init_cpu)(int cpu); + unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy, + unsigned int freq_next, unsigned int relation); + void (*freq_increase)(struct cpufreq_policy *p, unsigned int freq); +}; + +struct cs_ops { + struct notifier_block *notifier_block; +}; + +static inline int delay_for_sampling_rate(unsigned int sampling_rate) +{ + int delay = usecs_to_jiffies(sampling_rate); + + /* We want all CPUs to do sampling nearly on same jiffy */ + if (num_online_cpus() > 1) + delay -= jiffies % delay; + + return delay; +} + +cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall); +void dbs_check_cpu(struct dbs_data *dbs_data, int cpu); +int cpufreq_governor_dbs(struct dbs_data *dbs_data, + struct cpufreq_policy *policy, unsigned int event); +#endif /* _CPUFREQ_GOVERNER_H */ diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index d7f774bb49d..bdaab920630 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -10,24 +10,23 @@ * published by the Free Software Foundation. */ -#include -#include -#include +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include -#include -#include +#include +#include #include +#include +#include #include -#include +#include +#include #include -#include -#include +#include -/* - * dbs is used in this file as a shortform for demandbased switching - * It helps to keep variable names smaller, simpler - */ +#include "cpufreq_governor.h" +/* On-demand governor macors */ #define DEF_FREQUENCY_DOWN_DIFFERENTIAL (10) #define DEF_FREQUENCY_UP_THRESHOLD (80) #define DEF_SAMPLING_DOWN_FACTOR (1) @@ -38,80 +37,10 @@ #define MIN_FREQUENCY_UP_THRESHOLD (11) #define MAX_FREQUENCY_UP_THRESHOLD (100) -/* - * The polling frequency of this governor depends on the capability of - * the processor. Default polling frequency is 1000 times the transition - * latency of the processor. The governor will work on any processor with - * transition latency <= 10mS, using appropriate sampling - * rate. - * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL) - * this governor will not work. - * All times here are in uS. - */ -#define MIN_SAMPLING_RATE_RATIO (2) - -static unsigned int min_sampling_rate; - -#define LATENCY_MULTIPLIER (1000) -#define MIN_LATENCY_MULTIPLIER (100) -#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000) - -static void do_dbs_timer(struct work_struct *work); -static int cpufreq_governor_dbs(struct cpufreq_policy *policy, - unsigned int event); - -#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND -static -#endif -struct cpufreq_governor cpufreq_gov_ondemand = { - .name = "ondemand", - .governor = cpufreq_governor_dbs, - .max_transition_latency = TRANSITION_LATENCY_LIMIT, - .owner = THIS_MODULE, -}; - -/* Sampling types */ -enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE}; - -struct cpu_dbs_info_s { - cputime64_t prev_cpu_idle; - cputime64_t prev_cpu_iowait; - cputime64_t prev_cpu_wall; - cputime64_t prev_cpu_nice; - struct cpufreq_policy *cur_policy; - struct delayed_work work; - struct cpufreq_frequency_table *freq_table; - unsigned int freq_lo; - unsigned int freq_lo_jiffies; - unsigned int freq_hi_jiffies; - unsigned int rate_mult; - int cpu; - unsigned int sample_type:1; - /* - * percpu mutex that serializes governor limit change with - * do_dbs_timer invocation. We do not want do_dbs_timer to run - * when user is changing the governor or limits. - */ - struct mutex timer_mutex; -}; -static DEFINE_PER_CPU(struct cpu_dbs_info_s, od_cpu_dbs_info); - -static unsigned int dbs_enable; /* number of CPUs using this policy */ +static struct dbs_data od_dbs_data; +static DEFINE_PER_CPU(struct od_cpu_dbs_info_s, od_cpu_dbs_info); -/* - * dbs_mutex protects dbs_enable in governor start/stop. - */ -static DEFINE_MUTEX(dbs_mutex); - -static struct dbs_tuners { - unsigned int sampling_rate; - unsigned int up_threshold; - unsigned int down_differential; - unsigned int ignore_nice; - unsigned int sampling_down_factor; - unsigned int powersave_bias; - unsigned int io_is_busy; -} dbs_tuners_ins = { +static struct od_dbs_tuners od_tuners = { .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, .down_differential = DEF_FREQUENCY_DOWN_DIFFERENTIAL, @@ -119,14 +48,35 @@ static struct dbs_tuners { .powersave_bias = 0, }; -static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wall) +static void ondemand_powersave_bias_init_cpu(int cpu) { - u64 iowait_time = get_cpu_iowait_time_us(cpu, wall); + struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - if (iowait_time == -1ULL) - return 0; + dbs_info->freq_table = cpufreq_frequency_get_table(cpu); + dbs_info->freq_lo = 0; +} - return iowait_time; +/* + * Not all CPUs want IO time to be accounted as busy; this depends on how + * efficient idling at a higher frequency/voltage is. + * Pavel Machek says this is not so for various generations of AMD and old + * Intel systems. + * Mike Chan (androidlcom) calis this is also not true for ARM. + * Because of this, whitelist specific known (series) of CPUs by default, and + * leave all others up to the user. + */ +static int should_io_be_busy(void) +{ +#if defined(CONFIG_X86) + /* + * For Intel, Core 2 (model 15) andl later have an efficient idle. + */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && + boot_cpu_data.x86 == 6 && + boot_cpu_data.x86_model >= 15) + return 1; +#endif + return 0; } /* @@ -135,14 +85,13 @@ static inline cputime64_t get_cpu_iowait_time(unsigned int cpu, cputime64_t *wal * freq_lo, and freq_lo_jiffies in percpu area for averaging freqs. */ static unsigned int powersave_bias_target(struct cpufreq_policy *policy, - unsigned int freq_next, - unsigned int relation) + unsigned int freq_next, unsigned int relation) { unsigned int freq_req, freq_reduc, freq_avg; unsigned int freq_hi, freq_lo; unsigned int index = 0; unsigned int jiffies_total, jiffies_hi, jiffies_lo; - struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, + struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, policy->cpu); if (!dbs_info->freq_table) { @@ -154,7 +103,7 @@ static unsigned int powersave_bias_target(struct cpufreq_policy *policy, cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_next, relation, &index); freq_req = dbs_info->freq_table[index].frequency; - freq_reduc = freq_req * dbs_tuners_ins.powersave_bias / 1000; + freq_reduc = freq_req * od_tuners.powersave_bias / 1000; freq_avg = freq_req - freq_reduc; /* Find freq bounds for freq_avg in freq_table */ @@ -173,7 +122,7 @@ static unsigned int powersave_bias_target(struct cpufreq_policy *policy, dbs_info->freq_lo_jiffies = 0; return freq_lo; } - jiffies_total = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); + jiffies_total = usecs_to_jiffies(od_tuners.sampling_rate); jiffies_hi = (freq_avg - freq_lo) * jiffies_total; jiffies_hi += ((freq_hi - freq_lo) / 2); jiffies_hi /= (freq_hi - freq_lo); @@ -184,13 +133,6 @@ static unsigned int powersave_bias_target(struct cpufreq_policy *policy, return freq_hi; } -static void ondemand_powersave_bias_init_cpu(int cpu) -{ - struct cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - dbs_info->freq_table = cpufreq_frequency_get_table(cpu); - dbs_info->freq_lo = 0; -} - static void ondemand_powersave_bias_init(void) { int i; @@ -199,53 +141,138 @@ static void ondemand_powersave_bias_init(void) } } -/************************** sysfs interface ************************/ +static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq) +{ + if (od_tuners.powersave_bias) + freq = powersave_bias_target(p, freq, CPUFREQ_RELATION_H); + else if (p->cur == p->max) + return; -static ssize_t show_sampling_rate_min(struct kobject *kobj, - struct attribute *attr, char *buf) + __cpufreq_driver_target(p, freq, od_tuners.powersave_bias ? + CPUFREQ_RELATION_L : CPUFREQ_RELATION_H); +} + +/* + * Every sampling_rate, we check, if current idle time is less than 20% + * (default), then we try to increase frequency Every sampling_rate, we look for + * a the lowest frequency which can sustain the load while keeping idle time + * over 30%. If such a frequency exist, we try to decrease to this frequency. + * + * Any frequency increase takes it to the maximum frequency. Frequency reduction + * happens at minimum steps of 5% (default) of current frequency + */ +static void od_check_cpu(int cpu, unsigned int load_freq) { - return sprintf(buf, "%u\n", min_sampling_rate); + struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, cpu); + struct cpufreq_policy *policy = dbs_info->cdbs.cur_policy; + + dbs_info->freq_lo = 0; + + /* Check for frequency increase */ + if (load_freq > od_tuners.up_threshold * policy->cur) { + /* If switching to max speed, apply sampling_down_factor */ + if (policy->cur < policy->max) + dbs_info->rate_mult = + od_tuners.sampling_down_factor; + dbs_freq_increase(policy, policy->max); + return; + } + + /* Check for frequency decrease */ + /* if we cannot reduce the frequency anymore, break out early */ + if (policy->cur == policy->min) + return; + + /* + * The optimal frequency is the frequency that is the lowest that can + * support the current CPU usage without triggering the up policy. To be + * safe, we focus 10 points under the threshold. + */ + if (load_freq < (od_tuners.up_threshold - od_tuners.down_differential) * + policy->cur) { + unsigned int freq_next; + freq_next = load_freq / (od_tuners.up_threshold - + od_tuners.down_differential); + + /* No longer fully busy, reset rate_mult */ + dbs_info->rate_mult = 1; + + if (freq_next < policy->min) + freq_next = policy->min; + + if (!od_tuners.powersave_bias) { + __cpufreq_driver_target(policy, freq_next, + CPUFREQ_RELATION_L); + } else { + int freq = powersave_bias_target(policy, freq_next, + CPUFREQ_RELATION_L); + __cpufreq_driver_target(policy, freq, + CPUFREQ_RELATION_L); + } + } } -define_one_global_ro(sampling_rate_min); +static void od_dbs_timer(struct work_struct *work) +{ + struct od_cpu_dbs_info_s *dbs_info = + container_of(work, struct od_cpu_dbs_info_s, cdbs.work.work); + unsigned int cpu = dbs_info->cdbs.cpu; + int delay, sample_type = dbs_info->sample_type; -/* cpufreq_ondemand Governor Tunables */ -#define show_one(file_name, object) \ -static ssize_t show_##file_name \ -(struct kobject *kobj, struct attribute *attr, char *buf) \ -{ \ - return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ + mutex_lock(&dbs_info->cdbs.timer_mutex); + + /* Common NORMAL_SAMPLE setup */ + dbs_info->sample_type = OD_NORMAL_SAMPLE; + if (sample_type == OD_SUB_SAMPLE) { + delay = dbs_info->freq_lo_jiffies; + __cpufreq_driver_target(dbs_info->cdbs.cur_policy, + dbs_info->freq_lo, CPUFREQ_RELATION_H); + } else { + dbs_check_cpu(&od_dbs_data, cpu); + if (dbs_info->freq_lo) { + /* Setup timer for SUB_SAMPLE */ + dbs_info->sample_type = OD_SUB_SAMPLE; + delay = dbs_info->freq_hi_jiffies; + } else { + delay = delay_for_sampling_rate(dbs_info->rate_mult); + } + } + + schedule_delayed_work_on(cpu, &dbs_info->cdbs.work, delay); + mutex_unlock(&dbs_info->cdbs.timer_mutex); +} + +/************************** sysfs interface ************************/ + +static ssize_t show_sampling_rate_min(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + return sprintf(buf, "%u\n", od_dbs_data.min_sampling_rate); } -show_one(sampling_rate, sampling_rate); -show_one(io_is_busy, io_is_busy); -show_one(up_threshold, up_threshold); -show_one(sampling_down_factor, sampling_down_factor); -show_one(ignore_nice_load, ignore_nice); -show_one(powersave_bias, powersave_bias); /** * update_sampling_rate - update sampling rate effective immediately if needed. * @new_rate: new sampling rate * * If new rate is smaller than the old, simply updaing - * dbs_tuners_int.sampling_rate might not be appropriate. For example, - * if the original sampling_rate was 1 second and the requested new sampling - * rate is 10 ms because the user needs immediate reaction from ondemand - * governor, but not sure if higher frequency will be required or not, - * then, the governor may change the sampling rate too late; up to 1 second - * later. Thus, if we are reducing the sampling rate, we need to make the - * new value effective immediately. + * dbs_tuners_int.sampling_rate might not be appropriate. For example, if the + * original sampling_rate was 1 second and the requested new sampling rate is 10 + * ms because the user needs immediate reaction from ondemand governor, but not + * sure if higher frequency will be required or not, then, the governor may + * change the sampling rate too late; up to 1 second later. Thus, if we are + * reducing the sampling rate, we need to make the new value effective + * immediately. */ static void update_sampling_rate(unsigned int new_rate) { int cpu; - dbs_tuners_ins.sampling_rate = new_rate - = max(new_rate, min_sampling_rate); + od_tuners.sampling_rate = new_rate = max(new_rate, + od_dbs_data.min_sampling_rate); for_each_online_cpu(cpu) { struct cpufreq_policy *policy; - struct cpu_dbs_info_s *dbs_info; + struct od_cpu_dbs_info_s *dbs_info; unsigned long next_sampling, appointed_at; policy = cpufreq_cpu_get(cpu); @@ -254,28 +281,28 @@ static void update_sampling_rate(unsigned int new_rate) dbs_info = &per_cpu(od_cpu_dbs_info, policy->cpu); cpufreq_cpu_put(policy); - mutex_lock(&dbs_info->timer_mutex); + mutex_lock(&dbs_info->cdbs.timer_mutex); - if (!delayed_work_pending(&dbs_info->work)) { - mutex_unlock(&dbs_info->timer_mutex); + if (!delayed_work_pending(&dbs_info->cdbs.work)) { + mutex_unlock(&dbs_info->cdbs.timer_mutex); continue; } - next_sampling = jiffies + usecs_to_jiffies(new_rate); - appointed_at = dbs_info->work.timer.expires; - + next_sampling = jiffies + usecs_to_jiffies(new_rate); + appointed_at = dbs_info->cdbs.work.timer.expires; if (time_before(next_sampling, appointed_at)) { - mutex_unlock(&dbs_info->timer_mutex); - cancel_delayed_work_sync(&dbs_info->work); - mutex_lock(&dbs_info->timer_mutex); + mutex_unlock(&dbs_info->cdbs.timer_mutex); + cancel_delayed_work_sync(&dbs_info->cdbs.work); + mutex_lock(&dbs_info->cdbs.timer_mutex); - schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, - usecs_to_jiffies(new_rate)); + schedule_delayed_work_on(dbs_info->cdbs.cpu, + &dbs_info->cdbs.work, + usecs_to_jiffies(new_rate)); } - mutex_unlock(&dbs_info->timer_mutex); + mutex_unlock(&dbs_info->cdbs.timer_mutex); } } @@ -300,7 +327,7 @@ static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b, ret = sscanf(buf, "%u", &input); if (ret != 1) return -EINVAL; - dbs_tuners_ins.io_is_busy = !!input; + od_tuners.io_is_busy = !!input; return count; } @@ -315,7 +342,7 @@ static ssize_t store_up_threshold(struct kobject *a, struct attribute *b, input < MIN_FREQUENCY_UP_THRESHOLD) { return -EINVAL; } - dbs_tuners_ins.up_threshold = input; + od_tuners.up_threshold = input; return count; } @@ -328,12 +355,12 @@ static ssize_t store_sampling_down_factor(struct kobject *a, if (ret != 1 || input > MAX_SAMPLING_DOWN_FACTOR || input < 1) return -EINVAL; - dbs_tuners_ins.sampling_down_factor = input; + od_tuners.sampling_down_factor = input; /* Reset down sampling multiplier in case it was active */ for_each_online_cpu(j) { - struct cpu_dbs_info_s *dbs_info; - dbs_info = &per_cpu(od_cpu_dbs_info, j); + struct od_cpu_dbs_info_s *dbs_info = &per_cpu(od_cpu_dbs_info, + j); dbs_info->rate_mult = 1; } return count; @@ -354,19 +381,20 @@ static ssize_t store_ignore_nice_load(struct kobject *a, struct attribute *b, if (input > 1) input = 1; - if (input == dbs_tuners_ins.ignore_nice) { /* nothing to do */ + if (input == od_tuners.ignore_nice) { /* nothing to do */ return count; } - dbs_tuners_ins.ignore_nice = input; + od_tuners.ignore_nice = input; /* we need to re-evaluate prev_cpu_idle */ for_each_online_cpu(j) { - struct cpu_dbs_info_s *dbs_info; + struct od_cpu_dbs_info_s *dbs_info; dbs_info = &per_cpu(od_cpu_dbs_info, j); - dbs_info->prev_cpu_idle = get_cpu_idle_time(j, - &dbs_info->prev_cpu_wall); - if (dbs_tuners_ins.ignore_nice) - dbs_info->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE]; + dbs_info->cdbs.prev_cpu_idle = get_cpu_idle_time(j, + &dbs_info->cdbs.prev_cpu_wall); + if (od_tuners.ignore_nice) + dbs_info->cdbs.prev_cpu_nice = + kcpustat_cpu(j).cpustat[CPUTIME_NICE]; } return count; @@ -385,17 +413,25 @@ static ssize_t store_powersave_bias(struct kobject *a, struct attribute *b, if (input > 1000) input = 1000; - dbs_tuners_ins.powersave_bias = input; + od_tuners.powersave_bias = input; ondemand_powersave_bias_init(); return count; } +show_one(od, sampling_rate, sampling_rate); +show_one(od, io_is_busy, io_is_busy); +show_one(od, up_threshold, up_threshold); +show_one(od, sampling_down_factor, sampling_down_factor); +show_one(od, ignore_nice_load, ignore_nice); +show_one(od, powersave_bias, powersave_bias); + define_one_global_rw(sampling_rate); define_one_global_rw(io_is_busy); define_one_global_rw(up_threshold); define_one_global_rw(sampling_down_factor); define_one_global_rw(ignore_nice_load); define_one_global_rw(powersave_bias); +define_one_global_ro(sampling_rate_min); static struct attribute *dbs_attributes[] = { &sampling_rate_min.attr, @@ -408,354 +444,71 @@ static struct attribute *dbs_attributes[] = { NULL }; -static struct attribute_group dbs_attr_group = { +static struct attribute_group od_attr_group = { .attrs = dbs_attributes, .name = "ondemand", }; /************************** sysfs end ************************/ -static void dbs_freq_increase(struct cpufreq_policy *p, unsigned int freq) -{ - if (dbs_tuners_ins.powersave_bias) - freq = powersave_bias_target(p, freq, CPUFREQ_RELATION_H); - else if (p->cur == p->max) - return; - - __cpufreq_driver_target(p, freq, dbs_tuners_ins.powersave_bias ? - CPUFREQ_RELATION_L : CPUFREQ_RELATION_H); -} - -static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) -{ - unsigned int max_load_freq; - - struct cpufreq_policy *policy; - unsigned int j; - - this_dbs_info->freq_lo = 0; - policy = this_dbs_info->cur_policy; - - /* - * Every sampling_rate, we check, if current idle time is less - * than 20% (default), then we try to increase frequency - * Every sampling_rate, we look for a the lowest - * frequency which can sustain the load while keeping idle time over - * 30%. If such a frequency exist, we try to decrease to this frequency. - * - * Any frequency increase takes it to the maximum frequency. - * Frequency reduction happens at minimum steps of - * 5% (default) of current frequency - */ - - /* Get Absolute Load - in terms of freq */ - max_load_freq = 0; - - for_each_cpu(j, policy->cpus) { - struct cpu_dbs_info_s *j_dbs_info; - cputime64_t cur_wall_time, cur_idle_time, cur_iowait_time; - unsigned int idle_time, wall_time, iowait_time; - unsigned int load, load_freq; - int freq_avg; - - j_dbs_info = &per_cpu(od_cpu_dbs_info, j); - - cur_idle_time = get_cpu_idle_time(j, &cur_wall_time); - cur_iowait_time = get_cpu_iowait_time(j, &cur_wall_time); - - wall_time = (unsigned int) - (cur_wall_time - j_dbs_info->prev_cpu_wall); - j_dbs_info->prev_cpu_wall = cur_wall_time; - - idle_time = (unsigned int) - (cur_idle_time - j_dbs_info->prev_cpu_idle); - j_dbs_info->prev_cpu_idle = cur_idle_time; - - iowait_time = (unsigned int) - (cur_iowait_time - j_dbs_info->prev_cpu_iowait); - j_dbs_info->prev_cpu_iowait = cur_iowait_time; - - if (dbs_tuners_ins.ignore_nice) { - u64 cur_nice; - unsigned long cur_nice_jiffies; - - cur_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE] - - j_dbs_info->prev_cpu_nice; - /* - * Assumption: nice time between sampling periods will - * be less than 2^32 jiffies for 32 bit sys - */ - cur_nice_jiffies = (unsigned long) - cputime64_to_jiffies64(cur_nice); - - j_dbs_info->prev_cpu_nice = kcpustat_cpu(j).cpustat[CPUTIME_NICE]; - idle_time += jiffies_to_usecs(cur_nice_jiffies); - } - - /* - * For the purpose of ondemand, waiting for disk IO is an - * indication that you're performance critical, and not that - * the system is actually idle. So subtract the iowait time - * from the cpu idle time. - */ - - if (dbs_tuners_ins.io_is_busy && idle_time >= iowait_time) - idle_time -= iowait_time; +define_get_cpu_dbs_routines(od_cpu_dbs_info); - if (unlikely(!wall_time || wall_time < idle_time)) - continue; - - load = 100 * (wall_time - idle_time) / wall_time; - - freq_avg = __cpufreq_driver_getavg(policy, j); - if (freq_avg <= 0) - freq_avg = policy->cur; - - load_freq = load * freq_avg; - if (load_freq > max_load_freq) - max_load_freq = load_freq; - } - - /* Check for frequency increase */ - if (max_load_freq > dbs_tuners_ins.up_threshold * policy->cur) { - /* If switching to max speed, apply sampling_down_factor */ - if (policy->cur < policy->max) - this_dbs_info->rate_mult = - dbs_tuners_ins.sampling_down_factor; - dbs_freq_increase(policy, policy->max); - return; - } - - /* Check for frequency decrease */ - /* if we cannot reduce the frequency anymore, break out early */ - if (policy->cur == policy->min) - return; - - /* - * The optimal frequency is the frequency that is the lowest that - * can support the current CPU usage without triggering the up - * policy. To be safe, we focus 10 points under the threshold. - */ - if (max_load_freq < - (dbs_tuners_ins.up_threshold - dbs_tuners_ins.down_differential) * - policy->cur) { - unsigned int freq_next; - freq_next = max_load_freq / - (dbs_tuners_ins.up_threshold - - dbs_tuners_ins.down_differential); - - /* No longer fully busy, reset rate_mult */ - this_dbs_info->rate_mult = 1; - - if (freq_next < policy->min) - freq_next = policy->min; - - if (!dbs_tuners_ins.powersave_bias) { - __cpufreq_driver_target(policy, freq_next, - CPUFREQ_RELATION_L); - } else { - int freq = powersave_bias_target(policy, freq_next, - CPUFREQ_RELATION_L); - __cpufreq_driver_target(policy, freq, - CPUFREQ_RELATION_L); - } - } -} - -static void do_dbs_timer(struct work_struct *work) -{ - struct cpu_dbs_info_s *dbs_info = - container_of(work, struct cpu_dbs_info_s, work.work); - unsigned int cpu = dbs_info->cpu; - int sample_type = dbs_info->sample_type; - - int delay; - - mutex_lock(&dbs_info->timer_mutex); - - /* Common NORMAL_SAMPLE setup */ - dbs_info->sample_type = DBS_NORMAL_SAMPLE; - if (!dbs_tuners_ins.powersave_bias || - sample_type == DBS_NORMAL_SAMPLE) { - dbs_check_cpu(dbs_info); - if (dbs_info->freq_lo) { - /* Setup timer for SUB_SAMPLE */ - dbs_info->sample_type = DBS_SUB_SAMPLE; - delay = dbs_info->freq_hi_jiffies; - } else { - /* We want all CPUs to do sampling nearly on - * same jiffy - */ - delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate - * dbs_info->rate_mult); - - if (num_online_cpus() > 1) - delay -= jiffies % delay; - } - } else { - __cpufreq_driver_target(dbs_info->cur_policy, - dbs_info->freq_lo, CPUFREQ_RELATION_H); - delay = dbs_info->freq_lo_jiffies; - } - schedule_delayed_work_on(cpu, &dbs_info->work, delay); - mutex_unlock(&dbs_info->timer_mutex); -} - -static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) -{ - /* We want all CPUs to do sampling nearly on same jiffy */ - int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); - - if (num_online_cpus() > 1) - delay -= jiffies % delay; +static struct od_ops od_ops = { + .io_busy = should_io_be_busy, + .powersave_bias_init_cpu = ondemand_powersave_bias_init_cpu, + .powersave_bias_target = powersave_bias_target, + .freq_increase = dbs_freq_increase, +}; - dbs_info->sample_type = DBS_NORMAL_SAMPLE; - INIT_DEFERRABLE_WORK(&dbs_info->work, do_dbs_timer); - schedule_delayed_work_on(dbs_info->cpu, &dbs_info->work, delay); -} +static struct dbs_data od_dbs_data = { + .governor = GOV_ONDEMAND, + .attr_group = &od_attr_group, + .tuners = &od_tuners, + .get_cpu_cdbs = get_cpu_cdbs, + .get_cpu_dbs_info_s = get_cpu_dbs_info_s, + .gov_dbs_timer = od_dbs_timer, + .gov_check_cpu = od_check_cpu, + .gov_ops = &od_ops, +}; -static inline void dbs_timer_exit(struct cpu_dbs_info_s *dbs_info) +static int od_cpufreq_governor_dbs(struct cpufreq_policy *policy, + unsigned int event) { - cancel_delayed_work_sync(&dbs_info->work); + return cpufreq_governor_dbs(&od_dbs_data, policy, event); } -/* - * Not all CPUs want IO time to be accounted as busy; this dependson how - * efficient idling at a higher frequency/voltage is. - * Pavel Machek says this is not so for various generations of AMD and old - * Intel systems. - * Mike Chan (androidlcom) calis this is also not true for ARM. - * Because of this, whitelist specific known (series) of CPUs by default, and - * leave all others up to the user. - */ -static int should_io_be_busy(void) -{ -#if defined(CONFIG_X86) - /* - * For Intel, Core 2 (model 15) andl later have an efficient idle. - */ - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && - boot_cpu_data.x86 == 6 && - boot_cpu_data.x86_model >= 15) - return 1; +#ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND +static #endif - return 0; -} - -static int cpufreq_governor_dbs(struct cpufreq_policy *policy, - unsigned int event) -{ - unsigned int cpu = policy->cpu; - struct cpu_dbs_info_s *this_dbs_info; - unsigned int j; - int rc; - - this_dbs_info = &per_cpu(od_cpu_dbs_info, cpu); - - switch (event) { - case CPUFREQ_GOV_START: - if ((!cpu_online(cpu)) || (!policy->cur)) - return -EINVAL; - - mutex_lock(&dbs_mutex); - - dbs_enable++; - for_each_cpu(j, policy->cpus) { - struct cpu_dbs_info_s *j_dbs_info; - j_dbs_info = &per_cpu(od_cpu_dbs_info, j); - j_dbs_info->cur_policy = policy; - - j_dbs_info->prev_cpu_idle = get_cpu_idle_time(j, - &j_dbs_info->prev_cpu_wall); - if (dbs_tuners_ins.ignore_nice) - j_dbs_info->prev_cpu_nice = - kcpustat_cpu(j).cpustat[CPUTIME_NICE]; - } - this_dbs_info->cpu = cpu; - this_dbs_info->rate_mult = 1; - ondemand_powersave_bias_init_cpu(cpu); - /* - * Start the timerschedule work, when this governor - * is used for first time - */ - if (dbs_enable == 1) { - unsigned int latency; - - rc = sysfs_create_group(cpufreq_global_kobject, - &dbs_attr_group); - if (rc) { - mutex_unlock(&dbs_mutex); - return rc; - } - - /* policy latency is in nS. Convert it to uS first */ - latency = policy->cpuinfo.transition_latency / 1000; - if (latency == 0) - latency = 1; - /* Bring kernel and HW constraints together */ - min_sampling_rate = max(min_sampling_rate, - MIN_LATENCY_MULTIPLIER * latency); - dbs_tuners_ins.sampling_rate = - max(min_sampling_rate, - latency * LATENCY_MULTIPLIER); - dbs_tuners_ins.io_is_busy = should_io_be_busy(); - } - mutex_unlock(&dbs_mutex); - - mutex_init(&this_dbs_info->timer_mutex); - dbs_timer_init(this_dbs_info); - break; - - case CPUFREQ_GOV_STOP: - dbs_timer_exit(this_dbs_info); - - mutex_lock(&dbs_mutex); - mutex_destroy(&this_dbs_info->timer_mutex); - dbs_enable--; - mutex_unlock(&dbs_mutex); - if (!dbs_enable) - sysfs_remove_group(cpufreq_global_kobject, - &dbs_attr_group); - - break; - - case CPUFREQ_GOV_LIMITS: - mutex_lock(&this_dbs_info->timer_mutex); - if (policy->max < this_dbs_info->cur_policy->cur) - __cpufreq_driver_target(this_dbs_info->cur_policy, - policy->max, CPUFREQ_RELATION_H); - else if (policy->min > this_dbs_info->cur_policy->cur) - __cpufreq_driver_target(this_dbs_info->cur_policy, - policy->min, CPUFREQ_RELATION_L); - dbs_check_cpu(this_dbs_info); - mutex_unlock(&this_dbs_info->timer_mutex); - break; - } - return 0; -} +struct cpufreq_governor cpufreq_gov_ondemand = { + .name = "ondemand", + .governor = od_cpufreq_governor_dbs, + .max_transition_latency = TRANSITION_LATENCY_LIMIT, + .owner = THIS_MODULE, +}; static int __init cpufreq_gov_dbs_init(void) { u64 idle_time; int cpu = get_cpu(); + mutex_init(&od_dbs_data.mutex); idle_time = get_cpu_idle_time_us(cpu, NULL); put_cpu(); if (idle_time != -1ULL) { /* Idle micro accounting is supported. Use finer thresholds */ - dbs_tuners_ins.up_threshold = MICRO_FREQUENCY_UP_THRESHOLD; - dbs_tuners_ins.down_differential = - MICRO_FREQUENCY_DOWN_DIFFERENTIAL; + od_tuners.up_threshold = MICRO_FREQUENCY_UP_THRESHOLD; + od_tuners.down_differential = MICRO_FREQUENCY_DOWN_DIFFERENTIAL; /* * In nohz/micro accounting case we set the minimum frequency * not depending on HZ, but fixed (very low). The deferred * timer might skip some samples if idle/sleeping as needed. */ - min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE; + od_dbs_data.min_sampling_rate = MICRO_FREQUENCY_MIN_SAMPLE_RATE; } else { /* For correct statistics, we need 10 ticks for each measure */ - min_sampling_rate = - MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10); + od_dbs_data.min_sampling_rate = MIN_SAMPLING_RATE_RATIO * + jiffies_to_usecs(10); } return cpufreq_register_governor(&cpufreq_gov_ondemand); @@ -766,7 +519,6 @@ static void __exit cpufreq_gov_dbs_exit(void) cpufreq_unregister_governor(&cpufreq_gov_ondemand); } - MODULE_AUTHOR("Venkatesh Pallipadi "); MODULE_AUTHOR("Alexey Starikovskiy "); MODULE_DESCRIPTION("'cpufreq_ondemand' - A dynamic cpufreq governor for " diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index d03c2199305..a55b88eaf96 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -407,10 +407,4 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table, unsigned int cpu); void cpufreq_frequency_table_put_attr(unsigned int cpu); - -/********************************************************************* - * Governor Helpers * - *********************************************************************/ -cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall); - #endif /* _LINUX_CPUFREQ_H */ -- cgit v1.2.3 From 1e7586a18a2ab69a160837c0a4be31f7147cfb5e Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 26 Oct 2012 00:51:21 +0200 Subject: cpufreq: Fix sparse warnings by updating cputime64_t to u64 There were few sparse warnings due to mismatch of type on function arguments. Two types were used u64 and cputime64_t. Both are actually u64, so use u64 only. Reported-by: Fengguang Wu Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq_governor.c | 4 ++-- drivers/cpufreq/cpufreq_governor.h | 11 +++++------ drivers/cpufreq/cpufreq_stats.c | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 5ea2c829a79..be9d255e292 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -50,7 +50,7 @@ static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall) return jiffies_to_usecs(idle_time); } -cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall) +u64 get_cpu_idle_time(unsigned int cpu, u64 *wall) { u64 idle_time = get_cpu_idle_time_us(cpu, NULL); @@ -83,7 +83,7 @@ void dbs_check_cpu(struct dbs_data *dbs_data, int cpu) /* Get Absolute Load (in terms of freq for ondemand gov) */ for_each_cpu(j, policy->cpus) { struct cpu_dbs_common_info *j_cdbs; - cputime64_t cur_wall_time, cur_idle_time, cur_iowait_time; + u64 cur_wall_time, cur_idle_time, cur_iowait_time; unsigned int idle_time, wall_time, iowait_time; unsigned int load; diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index 34e14adfc3f..f6616540c53 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h @@ -17,7 +17,6 @@ #ifndef _CPUFREQ_GOVERNER_H #define _CPUFREQ_GOVERNER_H -#include #include #include #include @@ -72,9 +71,9 @@ static void *get_cpu_dbs_info_s(int cpu) \ /* Per cpu structures */ struct cpu_dbs_common_info { int cpu; - cputime64_t prev_cpu_idle; - cputime64_t prev_cpu_wall; - cputime64_t prev_cpu_nice; + u64 prev_cpu_idle; + u64 prev_cpu_wall; + u64 prev_cpu_nice; struct cpufreq_policy *cur_policy; struct delayed_work work; /* @@ -87,7 +86,7 @@ struct cpu_dbs_common_info { struct od_cpu_dbs_info_s { struct cpu_dbs_common_info cdbs; - cputime64_t prev_cpu_iowait; + u64 prev_cpu_iowait; struct cpufreq_frequency_table *freq_table; unsigned int freq_lo; unsigned int freq_lo_jiffies; @@ -170,7 +169,7 @@ static inline int delay_for_sampling_rate(unsigned int sampling_rate) return delay; } -cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall); +u64 get_cpu_idle_time(unsigned int cpu, u64 *wall); void dbs_check_cpu(struct dbs_data *dbs_data, int cpu); int cpufreq_governor_dbs(struct dbs_data *dbs_data, struct cpufreq_policy *policy, unsigned int event); diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 399831690fe..e40e5080964 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -37,7 +37,7 @@ struct cpufreq_stats { unsigned int max_state; unsigned int state_num; unsigned int last_index; - cputime64_t *time_in_state; + u64 *time_in_state; unsigned int *freq_table; #ifdef CONFIG_CPU_FREQ_STAT_DETAILS unsigned int *trans_table; @@ -223,7 +223,7 @@ static int cpufreq_stats_create_table(struct cpufreq_policy *policy, count++; } - alloc_size = count * sizeof(int) + count * sizeof(cputime64_t); + alloc_size = count * sizeof(int) + count * sizeof(u64); #ifdef CONFIG_CPU_FREQ_STAT_DETAILS alloc_size += count * count * sizeof(int); -- cgit v1.2.3 From da58445570326ac2a342770a9c9a2646276e1721 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 26 Oct 2012 00:51:32 +0200 Subject: cpufreq: Fix sparse warning by making local function static cpufreq_disabled() is a local function, so should be marked static. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index f552d5fe0f8..261ef654a35 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -129,7 +129,7 @@ static int __init init_cpufreq_transition_notifier_list(void) pure_initcall(init_cpufreq_transition_notifier_list); static int off __read_mostly; -int cpufreq_disabled(void) +static int cpufreq_disabled(void) { return off; } -- cgit v1.2.3 From 5a1c022850ea5d64c2997bf9b89f5ae112d5ee4d Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 31 Oct 2012 01:28:15 +0100 Subject: cpufreq: Avoid calling cpufreq driver's target() routine if target_freq == policy->cur Avoid calling cpufreq driver's target() routine if new frequency is same as policies current frequency. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 261ef654a35..28dc134cec3 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1476,6 +1476,10 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu, target_freq, relation); + + if (target_freq == policy->cur) + return 0; + if (cpu_online(policy->cpu) && cpufreq_driver->target) retval = cpufreq_driver->target(policy, target_freq, relation); -- cgit v1.2.3 From 7249924e537816368c4a35afd97ab311f75a6368 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 31 Oct 2012 01:28:21 +0100 Subject: cpufreq: Make sure target freq is within limits __cpufreq_driver_target() must not pass target frequency beyond the limits of current policy. Today most of cpufreq platform drivers are doing this check in their target routines. Why not move it to __cpufreq_driver_target()? Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 28dc134cec3..2f5ac2dcfda 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1470,12 +1470,19 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int relation) { int retval = -EINVAL; + unsigned int old_target_freq = target_freq; if (cpufreq_disabled()) return -ENODEV; - pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu, - target_freq, relation); + /* Make sure that target_freq is within supported range */ + if (target_freq > policy->max) + target_freq = policy->max; + if (target_freq < policy->min) + target_freq = policy->min; + + pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n", + policy->cpu, target_freq, relation, old_target_freq); if (target_freq == policy->cur) return 0; -- cgit v1.2.3 From f55c9c26278b0fcfa3336eccbba3d8a782da8aed Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 31 Oct 2012 05:49:13 +0000 Subject: cpufreq: Remove unnecessary initialization of a local variable Remove an unnecessary initializer for the 'ret' variable in __cpufreq_set_policy(). [rjw: Modified the subject and changelog slightly.] Signed-off-by: Jingoo Han Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 2f5ac2dcfda..1f93dbd7235 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -404,7 +404,7 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, static ssize_t store_##file_name \ (struct cpufreq_policy *policy, const char *buf, size_t count) \ { \ - unsigned int ret = -EINVAL; \ + unsigned int ret; \ struct cpufreq_policy new_policy; \ \ ret = cpufreq_get_policy(&new_policy, policy->cpu); \ @@ -459,7 +459,7 @@ static ssize_t show_scaling_governor(struct cpufreq_policy *policy, char *buf) static ssize_t store_scaling_governor(struct cpufreq_policy *policy, const char *buf, size_t count) { - unsigned int ret = -EINVAL; + unsigned int ret; char str_governor[16]; struct cpufreq_policy new_policy; -- cgit v1.2.3 From 1aef40e288acfb3cc28ff77528b34ef66683bed6 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Fri, 26 Oct 2012 12:26:24 +0200 Subject: cpuidle / sysfs: change function parameter The function needs the cpuidle_device which is initially passed to the caller. The current code gets the struct device from the struct cpuidle_device, pass it the cpuidle_add_sysfs function. This function calls per_cpu(cpuidle_devices, cpu) to get the cpuidle_device. This patch pass the cpuidle_device instead and simplify the code. Signed-off-by: Daniel Lezcano Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/cpuidle.c | 8 +++----- drivers/cpuidle/cpuidle.h | 4 ++-- drivers/cpuidle/sysfs.c | 12 +++--------- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 7f15b8514a1..b511ac39cc8 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -394,7 +394,6 @@ EXPORT_SYMBOL_GPL(cpuidle_disable_device); static int __cpuidle_register_device(struct cpuidle_device *dev) { int ret; - struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu); struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); if (!try_module_get(cpuidle_driver->owner)) @@ -404,7 +403,7 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) per_cpu(cpuidle_devices, dev->cpu) = dev; list_add(&dev->device_list, &cpuidle_detected_devices); - ret = cpuidle_add_sysfs(cpu_dev); + ret = cpuidle_add_sysfs(dev); if (ret) goto err_sysfs; @@ -416,7 +415,7 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) return 0; err_coupled: - cpuidle_remove_sysfs(cpu_dev); + cpuidle_remove_sysfs(dev); wait_for_completion(&dev->kobj_unregister); err_sysfs: list_del(&dev->device_list); @@ -460,7 +459,6 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device); */ void cpuidle_unregister_device(struct cpuidle_device *dev) { - struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu); struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); if (dev->registered == 0) @@ -470,7 +468,7 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) cpuidle_disable_device(dev); - cpuidle_remove_sysfs(cpu_dev); + cpuidle_remove_sysfs(dev); list_del(&dev->device_list); wait_for_completion(&dev->kobj_unregister); per_cpu(cpuidle_devices, dev->cpu) = NULL; diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h index 76e7f696ad8..2120d9e937c 100644 --- a/drivers/cpuidle/cpuidle.h +++ b/drivers/cpuidle/cpuidle.h @@ -29,8 +29,8 @@ extern int cpuidle_add_interface(struct device *dev); extern void cpuidle_remove_interface(struct device *dev); extern int cpuidle_add_state_sysfs(struct cpuidle_device *device); extern void cpuidle_remove_state_sysfs(struct cpuidle_device *device); -extern int cpuidle_add_sysfs(struct device *dev); -extern void cpuidle_remove_sysfs(struct device *dev); +extern int cpuidle_add_sysfs(struct cpuidle_device *dev); +extern void cpuidle_remove_sysfs(struct cpuidle_device *dev); #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED bool cpuidle_state_is_coupled(struct cpuidle_device *dev, diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 5f809e337b8..84e62852e50 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -408,13 +408,11 @@ void cpuidle_remove_state_sysfs(struct cpuidle_device *device) * cpuidle_add_sysfs - creates a sysfs instance for the target device * @dev: the target device */ -int cpuidle_add_sysfs(struct device *cpu_dev) +int cpuidle_add_sysfs(struct cpuidle_device *dev) { - int cpu = cpu_dev->id; - struct cpuidle_device *dev; + struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu); int error; - dev = per_cpu(cpuidle_devices, cpu); error = kobject_init_and_add(&dev->kobj, &ktype_cpuidle, &cpu_dev->kobj, "cpuidle"); if (!error) @@ -426,11 +424,7 @@ int cpuidle_add_sysfs(struct device *cpu_dev) * cpuidle_remove_sysfs - deletes a sysfs instance on the target device * @dev: the target device */ -void cpuidle_remove_sysfs(struct device *cpu_dev) +void cpuidle_remove_sysfs(struct cpuidle_device *dev) { - int cpu = cpu_dev->id; - struct cpuidle_device *dev; - - dev = per_cpu(cpuidle_devices, cpu); kobject_put(&dev->kobj); } -- cgit v1.2.3 From e45a00d679a788217f35ee4214a32d6d1924160b Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Fri, 26 Oct 2012 12:26:32 +0200 Subject: cpuidle / sysfs: move kobj initialization in the syfs file Move the kobj initialization and completion in the sysfs.c and encapsulate the code more. Signed-off-by: Daniel Lezcano Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/cpuidle.c | 4 ---- drivers/cpuidle/sysfs.c | 7 +++++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index b511ac39cc8..f4b8fc50c0f 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -399,8 +399,6 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) if (!try_module_get(cpuidle_driver->owner)) return -EINVAL; - init_completion(&dev->kobj_unregister); - per_cpu(cpuidle_devices, dev->cpu) = dev; list_add(&dev->device_list, &cpuidle_detected_devices); ret = cpuidle_add_sysfs(dev); @@ -416,7 +414,6 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) err_coupled: cpuidle_remove_sysfs(dev); - wait_for_completion(&dev->kobj_unregister); err_sysfs: list_del(&dev->device_list); per_cpu(cpuidle_devices, dev->cpu) = NULL; @@ -470,7 +467,6 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) cpuidle_remove_sysfs(dev); list_del(&dev->device_list); - wait_for_completion(&dev->kobj_unregister); per_cpu(cpuidle_devices, dev->cpu) = NULL; cpuidle_coupled_unregister_device(dev); diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 84e62852e50..ed87399bb02 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -374,8 +374,8 @@ int cpuidle_add_state_sysfs(struct cpuidle_device *device) kobj->state_usage = &device->states_usage[i]; init_completion(&kobj->kobj_unregister); - ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle, &device->kobj, - "state%d", i); + ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle, + &device->kobj, "state%d", i); if (ret) { kfree(kobj); goto error_state; @@ -413,6 +413,8 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev) struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu); int error; + init_completion(&dev->kobj_unregister); + error = kobject_init_and_add(&dev->kobj, &ktype_cpuidle, &cpu_dev->kobj, "cpuidle"); if (!error) @@ -427,4 +429,5 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev) void cpuidle_remove_sysfs(struct cpuidle_device *dev) { kobject_put(&dev->kobj); + wait_for_completion(&dev->kobj_unregister); } -- cgit v1.2.3 From 69a37beabf1f0a6705c08e879bdd5d82ff6486c4 Mon Sep 17 00:00:00 2001 From: Youquan Song Date: Fri, 26 Oct 2012 12:26:41 +0200 Subject: cpuidle: Quickly notice prediction failure for repeat mode The prediction for future is difficult and when the cpuidle governor prediction fails and govenor possibly choose the shallower C-state than it should. How to quickly notice and find the failure becomes important for power saving. cpuidle menu governor has a method to predict the repeat pattern if there are 8 C-states residency which are continuous and the same or very close, so it will predict the next C-states residency will keep same residency time. There is a real case that turbostat utility (tools/power/x86/turbostat) at kernel 3.3 or early. turbostat utility will read 10 registers one by one at Sandybridge, so it will generate 10 IPIs to wake up idle CPUs. So cpuidle menu governor will predict it is repeat mode and there is another IPI wake up idle CPU soon, so it keeps idle CPU stay at C1 state even though CPU is totally idle. However, in the turbostat, following 10 registers reading is sleep 5 seconds by default, so the idle CPU will keep at C1 for a long time though it is idle until break event occurs. In a idle Sandybridge system, run "./turbostat -v", we will notice that deep C-state dangles between "70% ~ 99%". After patched the kernel, we will notice deep C-state stays at >99.98%. In the patch, a timer is added when menu governor detects a repeat mode and choose a shallow C-state. The timer is set to a time out value that greater than predicted time, and we conclude repeat mode prediction failure if timer is triggered. When repeat mode happens as expected, the timer is not triggered and CPU waken up from C-states and it will cancel the timer initiatively. When repeat mode does not happen, the timer will be time out and menu governor will quickly notice that the repeat mode prediction fails and then re-evaluates deeper C-states possibility. Below is another case which will clearly show the patch much benefit: #include #include #include #include #include #include #include volatile int * shutdown; volatile long * count; int delay = 20; int loop = 8; void usage(void) { fprintf(stderr, "Usage: idle_predict [options]\n" " --help -h Print this help\n" " --thread -n Thread number\n" " --loop -l Loop times in shallow Cstate\n" " --delay -t Sleep time (uS)in shallow Cstate\n"); } void *simple_loop() { int idle_num = 1; while (!(*shutdown)) { *count = *count + 1; if (idle_num % loop) usleep(delay); else { /* sleep 1 second */ usleep(1000000); idle_num = 0; } idle_num++; } } static void sighand(int sig) { *shutdown = 1; } int main(int argc, char *argv[]) { sigset_t sigset; int signum = SIGALRM; int i, c, er = 0, thread_num = 8; pthread_t pt[1024]; static char optstr[] = "n:l:t:h:"; while ((c = getopt(argc, argv, optstr)) != EOF) switch (c) { case 'n': thread_num = atoi(optarg); break; case 'l': loop = atoi(optarg); break; case 't': delay = atoi(optarg); break; case 'h': default: usage(); exit(1); } printf("thread=%d,loop=%d,delay=%d\n",thread_num,loop,delay); count = malloc(sizeof(long)); shutdown = malloc(sizeof(int)); *count = 0; *shutdown = 0; sigemptyset(&sigset); sigaddset(&sigset, signum); sigprocmask (SIG_BLOCK, &sigset, NULL); signal(SIGINT, sighand); signal(SIGTERM, sighand); for(i = 0; i < thread_num ; i++) pthread_create(&pt[i], NULL, simple_loop, NULL); for (i = 0; i < thread_num; i++) pthread_join(pt[i], NULL); exit(0); } Get powertop V2 from git://github.com/fenrus75/powertop, build powertop. After build the above test application, then run it. Test plaform can be Intel Sandybridge or other recent platforms. #./idle_predict -l 10 & #./powertop We will find that deep C-state will dangle between 40%~100% and much time spent on C1 state. It is because menu governor wrongly predict that repeat mode is kept, so it will choose the C1 shallow C-state even though it has chance to sleep 1 second in deep C-state. While after patched the kernel, we find that deep C-state will keep >99.6%. Signed-off-by: Rik van Riel Signed-off-by: Youquan Song Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/governors/menu.c | 75 +++++++++++++++++++++++++++++++++++++--- include/linux/tick.h | 6 ++++ kernel/time/tick-sched.c | 4 +++ 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 5b1f2c372c1..37c0ff6c805 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -28,6 +28,13 @@ #define MAX_INTERESTING 50000 #define STDDEV_THRESH 400 +/* 60 * 60 > STDDEV_THRESH * INTERVALS = 400 * 8 */ +#define MAX_DEVIATION 60 + +static DEFINE_PER_CPU(struct hrtimer, menu_hrtimer); +static DEFINE_PER_CPU(int, hrtimer_status); +/* menu hrtimer mode */ +enum {MENU_HRTIMER_STOP, MENU_HRTIMER_REPEAT}; /* * Concepts and ideas behind the menu governor @@ -191,17 +198,42 @@ static u64 div_round64(u64 dividend, u32 divisor) return div_u64(dividend + (divisor / 2), divisor); } +/* Cancel the hrtimer if it is not triggered yet */ +void menu_hrtimer_cancel(void) +{ + int cpu = smp_processor_id(); + struct hrtimer *hrtmr = &per_cpu(menu_hrtimer, cpu); + + /* The timer is still not time out*/ + if (per_cpu(hrtimer_status, cpu)) { + hrtimer_cancel(hrtmr); + per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_STOP; + } +} +EXPORT_SYMBOL_GPL(menu_hrtimer_cancel); + +/* Call back for hrtimer is triggered */ +static enum hrtimer_restart menu_hrtimer_notify(struct hrtimer *hrtimer) +{ + int cpu = smp_processor_id(); + + per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_STOP; + + return HRTIMER_NORESTART; +} + /* * Try detecting repeating patterns by keeping track of the last 8 * intervals, and checking if the standard deviation of that set * of points is below a threshold. If it is... then use the * average of these 8 points as the estimated value. */ -static void detect_repeating_patterns(struct menu_device *data) +static int detect_repeating_patterns(struct menu_device *data) { int i; uint64_t avg = 0; uint64_t stddev = 0; /* contains the square of the std deviation */ + int ret = 0; /* first calculate average and standard deviation of the past */ for (i = 0; i < INTERVALS; i++) @@ -210,7 +242,7 @@ static void detect_repeating_patterns(struct menu_device *data) /* if the avg is beyond the known next tick, it's worthless */ if (avg > data->expected_us) - return; + return 0; for (i = 0; i < INTERVALS; i++) stddev += (data->intervals[i] - avg) * @@ -223,8 +255,12 @@ static void detect_repeating_patterns(struct menu_device *data) * repeating pattern and predict we keep doing this. */ - if (avg && stddev < STDDEV_THRESH) + if (avg && stddev < STDDEV_THRESH) { data->predicted_us = avg; + ret = 1; + } + + return ret; } /** @@ -240,6 +276,9 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) int i; int multiplier; struct timespec t; + int repeat = 0, low_predicted = 0; + int cpu = smp_processor_id(); + struct hrtimer *hrtmr = &per_cpu(menu_hrtimer, cpu); if (data->needs_update) { menu_update(drv, dev); @@ -274,7 +313,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket], RESOLUTION * DECAY); - detect_repeating_patterns(data); + repeat = detect_repeating_patterns(data); /* * We want to default to C1 (hlt), not to busy polling @@ -295,8 +334,10 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) if (s->disabled || su->disable) continue; - if (s->target_residency > data->predicted_us) + if (s->target_residency > data->predicted_us) { + low_predicted = 1; continue; + } if (s->exit_latency > latency_req) continue; if (s->exit_latency * multiplier > data->predicted_us) @@ -309,6 +350,27 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) } } + /* not deepest C-state chosen for low predicted residency */ + if (low_predicted) { + unsigned int timer_us = 0; + + /* + * Set a timer to detect whether this sleep is much + * longer than repeat mode predicted. If the timer + * triggers, the code will evaluate whether to put + * the CPU into a deeper C-state. + * The timer is cancelled on CPU wakeup. + */ + timer_us = 2 * (data->predicted_us + MAX_DEVIATION); + + if (repeat && (4 * timer_us < data->expected_us)) { + hrtimer_start(hrtmr, ns_to_ktime(1000 * timer_us), + HRTIMER_MODE_REL_PINNED); + /* In repeat case, menu hrtimer is started */ + per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_REPEAT; + } + } + return data->last_state_idx; } @@ -399,6 +461,9 @@ static int menu_enable_device(struct cpuidle_driver *drv, struct cpuidle_device *dev) { struct menu_device *data = &per_cpu(menu_devices, dev->cpu); + struct hrtimer *t = &per_cpu(menu_hrtimer, dev->cpu); + hrtimer_init(t, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + t->function = menu_hrtimer_notify; memset(data, 0, sizeof(struct menu_device)); diff --git a/include/linux/tick.h b/include/linux/tick.h index f37fceb69b7..1a6567b4849 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -142,4 +142,10 @@ static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; } static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; } # endif /* !NO_HZ */ +# ifdef CONFIG_CPU_IDLE_GOV_MENU +extern void menu_hrtimer_cancel(void); +# else +static inline void menu_hrtimer_cancel(void) {} +# endif /* CONFIG_CPU_IDLE_GOV_MENU */ + #endif diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index a4026088526..6f337068dc4 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -526,6 +526,8 @@ void tick_nohz_irq_exit(void) if (!ts->inidle) return; + /* Cancel the timer because CPU already waken up from the C-states*/ + menu_hrtimer_cancel(); __tick_nohz_idle_enter(ts); } @@ -621,6 +623,8 @@ void tick_nohz_idle_exit(void) ts->inidle = 0; + /* Cancel the timer because CPU already waken up from the C-states*/ + menu_hrtimer_cancel(); if (ts->idle_active || ts->tick_stopped) now = ktime_get(); -- cgit v1.2.3 From e11538d1f03914eb92af5a1a378375c05ae8520c Mon Sep 17 00:00:00 2001 From: Youquan Song Date: Fri, 26 Oct 2012 12:26:50 +0200 Subject: cpuidle: Quickly notice prediction failure in general case The prediction for future is difficult and when the cpuidle governor prediction fails and govenor possibly choose the shallower C-state than it should. How to quickly notice and find the failure becomes important for power saving. The patch extends to general case that prediction logic get a small predicted residency, so it choose a shallow C-state though the expected residency is large . Once the prediction will be fail, the CPU will keep staying at shallow C-state for a long time. Acutally, the CPU has change enter into deep C-state. So when the expected residency is long enough but governor choose a shallow C-state, an timer will be added in order to monitor if the prediction failure. When C-state is waken up prior to the adding timer, the timer will be cancelled initiatively. When the timer is triggered and menu governor will quickly notice prediction failure and re-evaluates deeper C-states possibility. Signed-off-by: Rik van Riel Signed-off-by: Youquan Song Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/governors/menu.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 37c0ff6c805..43a54fd6bfa 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -34,7 +34,7 @@ static DEFINE_PER_CPU(struct hrtimer, menu_hrtimer); static DEFINE_PER_CPU(int, hrtimer_status); /* menu hrtimer mode */ -enum {MENU_HRTIMER_STOP, MENU_HRTIMER_REPEAT}; +enum {MENU_HRTIMER_STOP, MENU_HRTIMER_REPEAT, MENU_HRTIMER_GENERAL}; /* * Concepts and ideas behind the menu governor @@ -116,6 +116,13 @@ enum {MENU_HRTIMER_STOP, MENU_HRTIMER_REPEAT}; * */ +/* + * The C-state residency is so long that is is worthwhile to exit + * from the shallow C-state and re-enter into a deeper C-state. + */ +static unsigned int perfect_cstate_ms __read_mostly = 30; +module_param(perfect_cstate_ms, uint, 0000); + struct menu_device { int last_state_idx; int needs_update; @@ -216,6 +223,16 @@ EXPORT_SYMBOL_GPL(menu_hrtimer_cancel); static enum hrtimer_restart menu_hrtimer_notify(struct hrtimer *hrtimer) { int cpu = smp_processor_id(); + struct menu_device *data = &per_cpu(menu_devices, cpu); + + /* In general case, the expected residency is much larger than + * deepest C-state target residency, but prediction logic still + * predicts a small predicted residency, so the prediction + * history is totally broken if the timer is triggered. + * So reset the correction factor. + */ + if (per_cpu(hrtimer_status, cpu) == MENU_HRTIMER_GENERAL) + data->correction_factor[data->bucket] = RESOLUTION * DECAY; per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_STOP; @@ -353,6 +370,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) /* not deepest C-state chosen for low predicted residency */ if (low_predicted) { unsigned int timer_us = 0; + unsigned int perfect_us = 0; /* * Set a timer to detect whether this sleep is much @@ -363,12 +381,26 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) */ timer_us = 2 * (data->predicted_us + MAX_DEVIATION); + perfect_us = perfect_cstate_ms * 1000; + if (repeat && (4 * timer_us < data->expected_us)) { hrtimer_start(hrtmr, ns_to_ktime(1000 * timer_us), HRTIMER_MODE_REL_PINNED); /* In repeat case, menu hrtimer is started */ per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_REPEAT; + } else if (perfect_us < data->expected_us) { + /* + * The next timer is long. This could be because + * we did not make a useful prediction. + * In that case, it makes sense to re-enter + * into a deeper C-state after some time. + */ + hrtimer_start(hrtmr, ns_to_ktime(1000 * timer_us), + HRTIMER_MODE_REL_PINNED); + /* In general case, menu hrtimer is started */ + per_cpu(hrtimer_status, cpu) = MENU_HRTIMER_GENERAL; } + } return data->last_state_idx; -- cgit v1.2.3 From d73d68dc49e09143e8e3bef10670a021c26ec4a5 Mon Sep 17 00:00:00 2001 From: Youquan Song Date: Fri, 26 Oct 2012 12:26:59 +0200 Subject: cpuidle: Set residency to 0 if target Cstate not enter When cpuidle governor choose a C-state to enter for idle CPU, but it notice that there is tasks request to be executed. So the idle CPU will not really enter the target C-state and go to run task. In this situation, it will use the residency of previous really entered target C-states. Obviously, it is not reasonable. So, this patch fix it by set the target C-state residency to 0. Signed-off-by: Rik van Riel Signed-off-by: Youquan Song Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/cpuidle.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index f4b8fc50c0f..ce4cac706dd 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -144,6 +144,10 @@ int cpuidle_idle_call(void) /* ask the governor for the next state */ next_state = cpuidle_curr_governor->select(drv, dev); if (need_resched()) { + dev->last_residency = 0; + /* give the governor an opportunity to reflect on the outcome */ + if (cpuidle_curr_governor->reflect) + cpuidle_curr_governor->reflect(dev, next_state); local_irq_enable(); return 0; } -- cgit v1.2.3 From c96ca4fb76b711279be063da083f09b8d65af5c5 Mon Sep 17 00:00:00 2001 From: Youquan Song Date: Fri, 26 Oct 2012 12:27:07 +0200 Subject: cpuidle: Get typical recent sleep interval The function detect_repeating_patterns was not very useful for workloads with alternating long and short pauses, for example virtual machines handling network requests for each other (say a web and database server). Instead, try to find a recent sleep interval that is somewhere between the median and the mode sleep time, by discarding outliers to the up side and recalculating the average and standard deviation until that is no longer required. This should do something sane with a sleep interval series like: 200 180 210 10000 30 1000 170 200 The current code would simply discard such a series, while the new code will guess a typical sleep interval just shy of 200. The original patch come from Rik van Riel . Signed-off-by: Rik van Riel Signed-off-by: Youquan Song Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/governors/menu.c | 69 ++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 43a54fd6bfa..2efee27714a 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -245,36 +245,59 @@ static enum hrtimer_restart menu_hrtimer_notify(struct hrtimer *hrtimer) * of points is below a threshold. If it is... then use the * average of these 8 points as the estimated value. */ -static int detect_repeating_patterns(struct menu_device *data) +static u32 get_typical_interval(struct menu_device *data) { - int i; - uint64_t avg = 0; - uint64_t stddev = 0; /* contains the square of the std deviation */ - int ret = 0; - - /* first calculate average and standard deviation of the past */ - for (i = 0; i < INTERVALS; i++) - avg += data->intervals[i]; - avg = avg / INTERVALS; + int i = 0, divisor = 0; + uint64_t max = 0, avg = 0, stddev = 0; + int64_t thresh = LLONG_MAX; /* Discard outliers above this value. */ + unsigned int ret = 0; - /* if the avg is beyond the known next tick, it's worthless */ - if (avg > data->expected_us) - return 0; - - for (i = 0; i < INTERVALS; i++) - stddev += (data->intervals[i] - avg) * - (data->intervals[i] - avg); +again: - stddev = stddev / INTERVALS; + /* first calculate average and standard deviation of the past */ + max = avg = divisor = stddev = 0; + for (i = 0; i < INTERVALS; i++) { + int64_t value = data->intervals[i]; + if (value <= thresh) { + avg += value; + divisor++; + if (value > max) + max = value; + } + } + do_div(avg, divisor); + for (i = 0; i < INTERVALS; i++) { + int64_t value = data->intervals[i]; + if (value <= thresh) { + int64_t diff = value - avg; + stddev += diff * diff; + } + } + do_div(stddev, divisor); + stddev = int_sqrt(stddev); /* - * now.. if stddev is small.. then assume we have a - * repeating pattern and predict we keep doing this. + * If we have outliers to the upside in our distribution, discard + * those by setting the threshold to exclude these outliers, then + * calculate the average and standard deviation again. Once we get + * down to the bottom 3/4 of our samples, stop excluding samples. + * + * This can deal with workloads that have long pauses interspersed + * with sporadic activity with a bunch of short pauses. + * + * The typical interval is obtained when standard deviation is small + * or standard deviation is small compared to the average interval. */ - - if (avg && stddev < STDDEV_THRESH) { + if (((avg > stddev * 6) && (divisor * 4 >= INTERVALS * 3)) + || stddev <= 20) { data->predicted_us = avg; ret = 1; + return ret; + + } else if ((divisor * 4) > INTERVALS * 3) { + /* Exclude the max interval */ + thresh = max - 1; + goto again; } return ret; @@ -330,7 +353,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) data->predicted_us = div_round64(data->expected_us * data->correction_factor[data->bucket], RESOLUTION * DECAY); - repeat = detect_repeating_patterns(data); + repeat = get_typical_interval(data); /* * We want to default to C1 (hlt), not to busy polling -- cgit v1.2.3 From 349631e0e411fefa2fed7e0a30b97704562dbd6b Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Wed, 31 Oct 2012 01:05:16 +0100 Subject: cpuidle / sysfs: move structure declaration into the sysfs.c file The structure cpuidle_state_kobj is not used anywhere except in the sysfs.c file. The definition of this structure is not needed in the cpuidle header file. This patch moves it to the sysfs.c file in order to encapsulate the code a bit more. Signed-off-by: Daniel Lezcano Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/sysfs.c | 7 +++++++ include/linux/cpuidle.h | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index ed87399bb02..f15c1e56e16 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -297,6 +297,13 @@ static struct attribute *cpuidle_state_default_attrs[] = { NULL }; +struct cpuidle_state_kobj { + struct cpuidle_state *state; + struct cpuidle_state_usage *state_usage; + struct completion kobj_unregister; + struct kobject kobj; +}; + #define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj) #define kobj_to_state(k) (kobj_to_state_obj(k)->state) #define kobj_to_state_usage(k) (kobj_to_state_obj(k)->state_usage) diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 279b1eaa8b7..7daf0e3b93b 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -82,13 +82,6 @@ cpuidle_set_statedata(struct cpuidle_state_usage *st_usage, void *data) st_usage->driver_data = data; } -struct cpuidle_state_kobj { - struct cpuidle_state *state; - struct cpuidle_state_usage *state_usage; - struct completion kobj_unregister; - struct kobject kobj; -}; - struct cpuidle_device { unsigned int registered:1; unsigned int enabled:1; -- cgit v1.2.3 From 8f3e9953e1e4ae5c11e2e880e7d85c03c0180613 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Wed, 31 Oct 2012 01:09:02 +0100 Subject: cpuidle: fixup device.h header in cpuidle.h The "struct device" is only used in sysfs.c. The other .c files including the private header "cpuidle.h" do not need to pull the entire headers tree from there as they don't manipulate the "struct device". This patch fixes this by moving the header inclusion to sysfs.c and adding a forward declaration for the struct device. The number of lines generated by the preprocesor: Without this patch : 17269 loc With this patch : 16446 loc Signed-off-by: Daniel Lezcano Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/cpuidle.h | 5 +++-- drivers/cpuidle/sysfs.c | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h index 2120d9e937c..f6b0923c225 100644 --- a/drivers/cpuidle/cpuidle.h +++ b/drivers/cpuidle/cpuidle.h @@ -5,8 +5,6 @@ #ifndef __DRIVER_CPUIDLE_H #define __DRIVER_CPUIDLE_H -#include - /* For internal use only */ extern struct cpuidle_governor *cpuidle_curr_governor; extern struct list_head cpuidle_governors; @@ -25,6 +23,9 @@ extern void cpuidle_uninstall_idle_handler(void); extern int cpuidle_switch_governor(struct cpuidle_governor *gov); /* sysfs */ + +struct device; + extern int cpuidle_add_interface(struct device *dev); extern void cpuidle_remove_interface(struct device *dev); extern int cpuidle_add_state_sysfs(struct cpuidle_device *device); diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index f15c1e56e16..49b1f4bcc1b 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "cpuidle.h" -- cgit v1.2.3 From 42f67f2acab2b7179c0d1ab234869e391448dfa6 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Wed, 31 Oct 2012 16:44:45 +0000 Subject: cpuidle: move driver's refcount to cpuidle We want to support different cpuidle drivers co-existing together. In this case we should move the refcount to the cpuidle_driver structure to handle several drivers at a time. Signed-off-by: Daniel Lezcano Acked-by: Peter De Schrijver Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/driver.c | 13 ++++++++----- include/linux/cpuidle.h | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 87db3877fea..39ba8e181e9 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c @@ -16,7 +16,6 @@ static struct cpuidle_driver *cpuidle_curr_driver; DEFINE_SPINLOCK(cpuidle_driver_lock); -int cpuidle_driver_refcount; static void set_power_states(struct cpuidle_driver *drv) { @@ -61,6 +60,8 @@ int cpuidle_register_driver(struct cpuidle_driver *drv) if (!drv->power_specified) set_power_states(drv); + drv->refcnt = 0; + cpuidle_curr_driver = drv; spin_unlock(&cpuidle_driver_lock); @@ -92,7 +93,7 @@ void cpuidle_unregister_driver(struct cpuidle_driver *drv) spin_lock(&cpuidle_driver_lock); - if (!WARN_ON(cpuidle_driver_refcount > 0)) + if (!WARN_ON(drv->refcnt > 0)) cpuidle_curr_driver = NULL; spin_unlock(&cpuidle_driver_lock); @@ -106,7 +107,7 @@ struct cpuidle_driver *cpuidle_driver_ref(void) spin_lock(&cpuidle_driver_lock); drv = cpuidle_curr_driver; - cpuidle_driver_refcount++; + drv->refcnt++; spin_unlock(&cpuidle_driver_lock); return drv; @@ -114,10 +115,12 @@ struct cpuidle_driver *cpuidle_driver_ref(void) void cpuidle_driver_unref(void) { + struct cpuidle_driver *drv = cpuidle_curr_driver; + spin_lock(&cpuidle_driver_lock); - if (!WARN_ON(cpuidle_driver_refcount <= 0)) - cpuidle_driver_refcount--; + if (drv && !WARN_ON(drv->refcnt <= 0)) + drv->refcnt--; spin_unlock(&cpuidle_driver_lock); } diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 7daf0e3b93b..d08e1afa491 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -124,6 +124,7 @@ static inline int cpuidle_get_last_residency(struct cpuidle_device *dev) struct cpuidle_driver { const char *name; struct module *owner; + int refcnt; unsigned int power_specified:1; /* set to 1 to use the core cpuidle time keeping (for all states). */ -- cgit v1.2.3 From 41682032715c2c969357c81391a442a24dd1c2c2 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Wed, 31 Oct 2012 16:44:46 +0000 Subject: cpuidle: move driver checking within the lock section The code is racy and the check with cpuidle_curr_driver should be done under the lock. I don't find a path in the different drivers where that could happen because the arch specific drivers are written in such way it is not possible to register a driver while it is unregistered, except maybe in a very improbable case when "intel_idle" and "processor_idle" are competing. One could unregister a driver, while the other one is registering. Signed-off-by: Daniel Lezcano Acked-by: Peter De Schrijver Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/driver.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 39ba8e181e9..3e590756923 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c @@ -85,17 +85,9 @@ EXPORT_SYMBOL_GPL(cpuidle_get_driver); */ void cpuidle_unregister_driver(struct cpuidle_driver *drv) { - if (drv != cpuidle_curr_driver) { - WARN(1, "invalid cpuidle_unregister_driver(%s)\n", - drv->name); - return; - } - spin_lock(&cpuidle_driver_lock); - - if (!WARN_ON(drv->refcnt > 0)) + if (drv == cpuidle_curr_driver && !WARN_ON(drv->refcnt > 0)) cpuidle_curr_driver = NULL; - spin_unlock(&cpuidle_driver_lock); } EXPORT_SYMBOL_GPL(cpuidle_unregister_driver); -- cgit v1.2.3 From 13dd52f11a04e616900f565d6a1e5138e58d579f Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Wed, 31 Oct 2012 16:44:47 +0000 Subject: cpuidle: prepare the cpuidle core to handle multiple drivers This patch is a preparation for the multiple cpuidle drivers support. As the next patch will introduce the multiple drivers with the Kconfig option and we want to keep the code clean and understandable, this patch defines a set of functions for encapsulating some common parts and splits what should be done under a lock from the rest. [rjw: Modified the subject and changelog slightly.] Signed-off-by: Daniel Lezcano Acked-by: Peter De Schrijver Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/driver.c | 60 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 3e590756923..8246662f594 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c @@ -39,11 +39,20 @@ static void set_power_states(struct cpuidle_driver *drv) drv->states[i].power_usage = -1 - i; } -/** - * cpuidle_register_driver - registers a driver - * @drv: the driver - */ -int cpuidle_register_driver(struct cpuidle_driver *drv) +static void __cpuidle_driver_init(struct cpuidle_driver *drv) +{ + drv->refcnt = 0; + + if (!drv->power_specified) + set_power_states(drv); +} + +static void cpuidle_set_driver(struct cpuidle_driver *drv) +{ + cpuidle_curr_driver = drv; +} + +static int __cpuidle_register_driver(struct cpuidle_driver *drv) { if (!drv || !drv->state_count) return -EINVAL; @@ -51,22 +60,38 @@ int cpuidle_register_driver(struct cpuidle_driver *drv) if (cpuidle_disabled()) return -ENODEV; - spin_lock(&cpuidle_driver_lock); - if (cpuidle_curr_driver) { - spin_unlock(&cpuidle_driver_lock); + if (cpuidle_get_driver()) return -EBUSY; - } - if (!drv->power_specified) - set_power_states(drv); + __cpuidle_driver_init(drv); - drv->refcnt = 0; + cpuidle_set_driver(drv); - cpuidle_curr_driver = drv; + return 0; +} + +static void __cpuidle_unregister_driver(struct cpuidle_driver *drv) +{ + if (drv != cpuidle_get_driver()) + return; + + if (!WARN_ON(drv->refcnt > 0)) + cpuidle_set_driver(NULL); +} +/** + * cpuidle_register_driver - registers a driver + * @drv: the driver + */ +int cpuidle_register_driver(struct cpuidle_driver *drv) +{ + int ret; + + spin_lock(&cpuidle_driver_lock); + ret = __cpuidle_register_driver(drv); spin_unlock(&cpuidle_driver_lock); - return 0; + return ret; } EXPORT_SYMBOL_GPL(cpuidle_register_driver); @@ -86,8 +111,7 @@ EXPORT_SYMBOL_GPL(cpuidle_get_driver); void cpuidle_unregister_driver(struct cpuidle_driver *drv) { spin_lock(&cpuidle_driver_lock); - if (drv == cpuidle_curr_driver && !WARN_ON(drv->refcnt > 0)) - cpuidle_curr_driver = NULL; + __cpuidle_unregister_driver(drv); spin_unlock(&cpuidle_driver_lock); } EXPORT_SYMBOL_GPL(cpuidle_unregister_driver); @@ -98,7 +122,7 @@ struct cpuidle_driver *cpuidle_driver_ref(void) spin_lock(&cpuidle_driver_lock); - drv = cpuidle_curr_driver; + drv = cpuidle_get_driver(); drv->refcnt++; spin_unlock(&cpuidle_driver_lock); @@ -107,7 +131,7 @@ struct cpuidle_driver *cpuidle_driver_ref(void) void cpuidle_driver_unref(void) { - struct cpuidle_driver *drv = cpuidle_curr_driver; + struct cpuidle_driver *drv = cpuidle_get_driver(); spin_lock(&cpuidle_driver_lock); -- cgit v1.2.3 From bf4d1b5ddb78f86078ac6ae0415802d5f0c68f92 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Wed, 31 Oct 2012 16:44:48 +0000 Subject: cpuidle: support multiple drivers With the tegra3 and the big.LITTLE [1] new architectures, several cpus with different characteristics (latencies and states) can co-exists on the system. The cpuidle framework has the limitation of handling only identical cpus. This patch removes this limitation by introducing the multiple driver support for cpuidle. This option is configurable at compile time and should be enabled for the architectures mentioned above. So there is no impact for the other platforms if the option is disabled. The option defaults to 'n'. Note the multiple drivers support is also compatible with the existing drivers, even if just one driver is needed, all the cpu will be tied to this driver using an extra small chunk of processor memory. The multiple driver support use a per-cpu driver pointer instead of a global variable and the accessor to this variable are done from a cpu context. In order to keep the compatibility with the existing drivers, the function 'cpuidle_register_driver' and 'cpuidle_unregister_driver' will register the specified driver for all the cpus. The semantic for the output of /sys/devices/system/cpu/cpuidle/current_driver remains the same except the driver name will be related to the current cpu. The /sys/devices/system/cpu/cpu[0-9]/cpuidle/driver/name files are added allowing to read the per cpu driver name. [1] http://lwn.net/Articles/481055/ Signed-off-by: Daniel Lezcano Acked-by: Peter De Schrijver Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/Kconfig | 9 +++ drivers/cpuidle/cpuidle.c | 36 ++++++---- drivers/cpuidle/cpuidle.h | 4 +- drivers/cpuidle/driver.c | 166 ++++++++++++++++++++++++++++++++++++++----- drivers/cpuidle/sysfs.c | 174 ++++++++++++++++++++++++++++++++++++++++++++-- include/linux/cpuidle.h | 7 +- 6 files changed, 356 insertions(+), 40 deletions(-) diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig index a76b689e553..234ae651b38 100644 --- a/drivers/cpuidle/Kconfig +++ b/drivers/cpuidle/Kconfig @@ -9,6 +9,15 @@ config CPU_IDLE If you're using an ACPI-enabled platform, you should say Y here. +config CPU_IDLE_MULTIPLE_DRIVERS + bool "Support multiple cpuidle drivers" + depends on CPU_IDLE + default n + help + Allows the cpuidle framework to use different drivers for each CPU. + This is useful if you have a system with different CPU latencies and + states. If unsure say N. + config CPU_IDLE_GOV_LADDER bool depends on CPU_IDLE diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index ce4cac706dd..711dd83fd3b 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -68,7 +68,7 @@ static cpuidle_enter_t cpuidle_enter_ops; int cpuidle_play_dead(void) { struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); - struct cpuidle_driver *drv = cpuidle_get_driver(); + struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); int i, dead_state = -1; int power_usage = -1; @@ -128,7 +128,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, int cpuidle_idle_call(void) { struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); - struct cpuidle_driver *drv = cpuidle_get_driver(); + struct cpuidle_driver *drv; int next_state, entered_state; if (off) @@ -141,6 +141,8 @@ int cpuidle_idle_call(void) if (!dev || !dev->enabled) return -EBUSY; + drv = cpuidle_get_cpu_driver(dev); + /* ask the governor for the next state */ next_state = cpuidle_curr_governor->select(drv, dev); if (need_resched()) { @@ -312,15 +314,19 @@ static void poll_idle_init(struct cpuidle_driver *drv) {} int cpuidle_enable_device(struct cpuidle_device *dev) { int ret, i; - struct cpuidle_driver *drv = cpuidle_get_driver(); + struct cpuidle_driver *drv; if (!dev) return -EINVAL; if (dev->enabled) return 0; + + drv = cpuidle_get_cpu_driver(dev); + if (!drv || !cpuidle_curr_governor) return -EIO; + if (!dev->state_count) dev->state_count = drv->state_count; @@ -335,7 +341,8 @@ int cpuidle_enable_device(struct cpuidle_device *dev) poll_idle_init(drv); - if ((ret = cpuidle_add_state_sysfs(dev))) + ret = cpuidle_add_device_sysfs(dev); + if (ret) return ret; if (cpuidle_curr_governor->enable && @@ -356,7 +363,7 @@ int cpuidle_enable_device(struct cpuidle_device *dev) return 0; fail_sysfs: - cpuidle_remove_state_sysfs(dev); + cpuidle_remove_device_sysfs(dev); return ret; } @@ -372,17 +379,20 @@ EXPORT_SYMBOL_GPL(cpuidle_enable_device); */ void cpuidle_disable_device(struct cpuidle_device *dev) { + struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); + if (!dev || !dev->enabled) return; - if (!cpuidle_get_driver() || !cpuidle_curr_governor) + + if (!drv || !cpuidle_curr_governor) return; dev->enabled = 0; if (cpuidle_curr_governor->disable) - cpuidle_curr_governor->disable(cpuidle_get_driver(), dev); + cpuidle_curr_governor->disable(drv, dev); - cpuidle_remove_state_sysfs(dev); + cpuidle_remove_device_sysfs(dev); enabled_devices--; } @@ -398,9 +408,9 @@ EXPORT_SYMBOL_GPL(cpuidle_disable_device); static int __cpuidle_register_device(struct cpuidle_device *dev) { int ret; - struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); + struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); - if (!try_module_get(cpuidle_driver->owner)) + if (!try_module_get(drv->owner)) return -EINVAL; per_cpu(cpuidle_devices, dev->cpu) = dev; @@ -421,7 +431,7 @@ err_coupled: err_sysfs: list_del(&dev->device_list); per_cpu(cpuidle_devices, dev->cpu) = NULL; - module_put(cpuidle_driver->owner); + module_put(drv->owner); return ret; } @@ -460,7 +470,7 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device); */ void cpuidle_unregister_device(struct cpuidle_device *dev) { - struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); + struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); if (dev->registered == 0) return; @@ -477,7 +487,7 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) cpuidle_resume_and_unlock(); - module_put(cpuidle_driver->owner); + module_put(drv->owner); } EXPORT_SYMBOL_GPL(cpuidle_unregister_device); diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h index f6b0923c225..ee97e9672ec 100644 --- a/drivers/cpuidle/cpuidle.h +++ b/drivers/cpuidle/cpuidle.h @@ -28,8 +28,8 @@ struct device; extern int cpuidle_add_interface(struct device *dev); extern void cpuidle_remove_interface(struct device *dev); -extern int cpuidle_add_state_sysfs(struct cpuidle_device *device); -extern void cpuidle_remove_state_sysfs(struct cpuidle_device *device); +extern int cpuidle_add_device_sysfs(struct cpuidle_device *device); +extern void cpuidle_remove_device_sysfs(struct cpuidle_device *device); extern int cpuidle_add_sysfs(struct cpuidle_device *dev); extern void cpuidle_remove_sysfs(struct cpuidle_device *dev); diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 8246662f594..3af841fb397 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c @@ -14,9 +14,11 @@ #include "cpuidle.h" -static struct cpuidle_driver *cpuidle_curr_driver; DEFINE_SPINLOCK(cpuidle_driver_lock); +static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu); +static struct cpuidle_driver * __cpuidle_get_cpu_driver(int cpu); + static void set_power_states(struct cpuidle_driver *drv) { int i; @@ -47,12 +49,7 @@ static void __cpuidle_driver_init(struct cpuidle_driver *drv) set_power_states(drv); } -static void cpuidle_set_driver(struct cpuidle_driver *drv) -{ - cpuidle_curr_driver = drv; -} - -static int __cpuidle_register_driver(struct cpuidle_driver *drv) +static int __cpuidle_register_driver(struct cpuidle_driver *drv, int cpu) { if (!drv || !drv->state_count) return -EINVAL; @@ -60,23 +57,84 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv) if (cpuidle_disabled()) return -ENODEV; - if (cpuidle_get_driver()) + if (__cpuidle_get_cpu_driver(cpu)) return -EBUSY; __cpuidle_driver_init(drv); - cpuidle_set_driver(drv); + __cpuidle_set_cpu_driver(drv, cpu); return 0; } -static void __cpuidle_unregister_driver(struct cpuidle_driver *drv) +static void __cpuidle_unregister_driver(struct cpuidle_driver *drv, int cpu) { - if (drv != cpuidle_get_driver()) + if (drv != __cpuidle_get_cpu_driver(cpu)) return; if (!WARN_ON(drv->refcnt > 0)) - cpuidle_set_driver(NULL); + __cpuidle_set_cpu_driver(NULL, cpu); +} + +#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS + +static DEFINE_PER_CPU(struct cpuidle_driver *, cpuidle_drivers); + +static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu) +{ + per_cpu(cpuidle_drivers, cpu) = drv; +} + +static struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu) +{ + return per_cpu(cpuidle_drivers, cpu); +} + +static void __cpuidle_unregister_all_cpu_driver(struct cpuidle_driver *drv) +{ + int cpu; + for_each_present_cpu(cpu) + __cpuidle_unregister_driver(drv, cpu); +} + +static int __cpuidle_register_all_cpu_driver(struct cpuidle_driver *drv) +{ + int ret = 0; + int i, cpu; + + for_each_present_cpu(cpu) { + ret = __cpuidle_register_driver(drv, cpu); + if (ret) + break; + } + + if (ret) + for_each_present_cpu(i) { + if (i == cpu) + break; + __cpuidle_unregister_driver(drv, i); + } + + + return ret; +} + +int cpuidle_register_cpu_driver(struct cpuidle_driver *drv, int cpu) +{ + int ret; + + spin_lock(&cpuidle_driver_lock); + ret = __cpuidle_register_driver(drv, cpu); + spin_unlock(&cpuidle_driver_lock); + + return ret; +} + +void cpuidle_unregister_cpu_driver(struct cpuidle_driver *drv, int cpu) +{ + spin_lock(&cpuidle_driver_lock); + __cpuidle_unregister_driver(drv, cpu); + spin_unlock(&cpuidle_driver_lock); } /** @@ -88,7 +146,7 @@ int cpuidle_register_driver(struct cpuidle_driver *drv) int ret; spin_lock(&cpuidle_driver_lock); - ret = __cpuidle_register_driver(drv); + ret = __cpuidle_register_all_cpu_driver(drv); spin_unlock(&cpuidle_driver_lock); return ret; @@ -96,13 +154,48 @@ int cpuidle_register_driver(struct cpuidle_driver *drv) EXPORT_SYMBOL_GPL(cpuidle_register_driver); /** - * cpuidle_get_driver - return the current driver + * cpuidle_unregister_driver - unregisters a driver + * @drv: the driver */ -struct cpuidle_driver *cpuidle_get_driver(void) +void cpuidle_unregister_driver(struct cpuidle_driver *drv) +{ + spin_lock(&cpuidle_driver_lock); + __cpuidle_unregister_all_cpu_driver(drv); + spin_unlock(&cpuidle_driver_lock); +} +EXPORT_SYMBOL_GPL(cpuidle_unregister_driver); + +#else + +static struct cpuidle_driver *cpuidle_curr_driver; + +static inline void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu) +{ + cpuidle_curr_driver = drv; +} + +static inline struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu) { return cpuidle_curr_driver; } -EXPORT_SYMBOL_GPL(cpuidle_get_driver); + +/** + * cpuidle_register_driver - registers a driver + * @drv: the driver + */ +int cpuidle_register_driver(struct cpuidle_driver *drv) +{ + int ret, cpu; + + cpu = get_cpu(); + spin_lock(&cpuidle_driver_lock); + ret = __cpuidle_register_driver(drv, cpu); + spin_unlock(&cpuidle_driver_lock); + put_cpu(); + + return ret; +} +EXPORT_SYMBOL_GPL(cpuidle_register_driver); /** * cpuidle_unregister_driver - unregisters a driver @@ -110,11 +203,50 @@ EXPORT_SYMBOL_GPL(cpuidle_get_driver); */ void cpuidle_unregister_driver(struct cpuidle_driver *drv) { + int cpu; + + cpu = get_cpu(); spin_lock(&cpuidle_driver_lock); - __cpuidle_unregister_driver(drv); + __cpuidle_unregister_driver(drv, cpu); spin_unlock(&cpuidle_driver_lock); + put_cpu(); } EXPORT_SYMBOL_GPL(cpuidle_unregister_driver); +#endif + +/** + * cpuidle_get_driver - return the current driver + */ +struct cpuidle_driver *cpuidle_get_driver(void) +{ + struct cpuidle_driver *drv; + int cpu; + + cpu = get_cpu(); + drv = __cpuidle_get_cpu_driver(cpu); + put_cpu(); + + return drv; +} +EXPORT_SYMBOL_GPL(cpuidle_get_driver); + +/** + * cpuidle_get_cpu_driver - return the driver tied with a cpu + */ +struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev) +{ + struct cpuidle_driver *drv; + + if (!dev) + return NULL; + + spin_lock(&cpuidle_driver_lock); + drv = __cpuidle_get_cpu_driver(dev->cpu); + spin_unlock(&cpuidle_driver_lock); + + return drv; +} +EXPORT_SYMBOL_GPL(cpuidle_get_cpu_driver); struct cpuidle_driver *cpuidle_driver_ref(void) { diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 49b1f4bcc1b..34094294610 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -364,17 +364,17 @@ static inline void cpuidle_free_state_kobj(struct cpuidle_device *device, int i) } /** - * cpuidle_add_driver_sysfs - adds driver-specific sysfs attributes + * cpuidle_add_state_sysfs - adds cpuidle states sysfs attributes * @device: the target device */ -int cpuidle_add_state_sysfs(struct cpuidle_device *device) +static int cpuidle_add_state_sysfs(struct cpuidle_device *device) { int i, ret = -ENOMEM; struct cpuidle_state_kobj *kobj; - struct cpuidle_driver *drv = cpuidle_get_driver(); + struct cpuidle_driver *drv = cpuidle_get_cpu_driver(device); /* state statistics */ - for (i = 0; i < device->state_count; i++) { + for (i = 0; i < drv->state_count; i++) { kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL); if (!kobj) goto error_state; @@ -401,10 +401,10 @@ error_state: } /** - * cpuidle_remove_driver_sysfs - removes driver-specific sysfs attributes + * cpuidle_remove_driver_sysfs - removes the cpuidle states sysfs attributes * @device: the target device */ -void cpuidle_remove_state_sysfs(struct cpuidle_device *device) +static void cpuidle_remove_state_sysfs(struct cpuidle_device *device) { int i; @@ -412,6 +412,168 @@ void cpuidle_remove_state_sysfs(struct cpuidle_device *device) cpuidle_free_state_kobj(device, i); } +#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS +#define kobj_to_driver_kobj(k) container_of(k, struct cpuidle_driver_kobj, kobj) +#define attr_to_driver_attr(a) container_of(a, struct cpuidle_driver_attr, attr) + +#define define_one_driver_ro(_name, show) \ + static struct cpuidle_driver_attr attr_driver_##_name = \ + __ATTR(_name, 0644, show, NULL) + +struct cpuidle_driver_kobj { + struct cpuidle_driver *drv; + struct completion kobj_unregister; + struct kobject kobj; +}; + +struct cpuidle_driver_attr { + struct attribute attr; + ssize_t (*show)(struct cpuidle_driver *, char *); + ssize_t (*store)(struct cpuidle_driver *, const char *, size_t); +}; + +static ssize_t show_driver_name(struct cpuidle_driver *drv, char *buf) +{ + ssize_t ret; + + spin_lock(&cpuidle_driver_lock); + ret = sprintf(buf, "%s\n", drv ? drv->name : "none"); + spin_unlock(&cpuidle_driver_lock); + + return ret; +} + +static void cpuidle_driver_sysfs_release(struct kobject *kobj) +{ + struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj); + complete(&driver_kobj->kobj_unregister); +} + +static ssize_t cpuidle_driver_show(struct kobject *kobj, struct attribute * attr, + char * buf) +{ + int ret = -EIO; + struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj); + struct cpuidle_driver_attr *dattr = attr_to_driver_attr(attr); + + if (dattr->show) + ret = dattr->show(driver_kobj->drv, buf); + + return ret; +} + +static ssize_t cpuidle_driver_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t size) +{ + int ret = -EIO; + struct cpuidle_driver_kobj *driver_kobj = kobj_to_driver_kobj(kobj); + struct cpuidle_driver_attr *dattr = attr_to_driver_attr(attr); + + if (dattr->store) + ret = dattr->store(driver_kobj->drv, buf, size); + + return ret; +} + +define_one_driver_ro(name, show_driver_name); + +static const struct sysfs_ops cpuidle_driver_sysfs_ops = { + .show = cpuidle_driver_show, + .store = cpuidle_driver_store, +}; + +static struct attribute *cpuidle_driver_default_attrs[] = { + &attr_driver_name.attr, + NULL +}; + +static struct kobj_type ktype_driver_cpuidle = { + .sysfs_ops = &cpuidle_driver_sysfs_ops, + .default_attrs = cpuidle_driver_default_attrs, + .release = cpuidle_driver_sysfs_release, +}; + +/** + * cpuidle_add_driver_sysfs - adds the driver name sysfs attribute + * @device: the target device + */ +static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev) +{ + struct cpuidle_driver_kobj *kdrv; + struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); + int ret; + + kdrv = kzalloc(sizeof(*kdrv), GFP_KERNEL); + if (!kdrv) + return -ENOMEM; + + kdrv->drv = drv; + init_completion(&kdrv->kobj_unregister); + + ret = kobject_init_and_add(&kdrv->kobj, &ktype_driver_cpuidle, + &dev->kobj, "driver"); + if (ret) { + kfree(kdrv); + return ret; + } + + kobject_uevent(&kdrv->kobj, KOBJ_ADD); + dev->kobj_driver = kdrv; + + return ret; +} + +/** + * cpuidle_remove_driver_sysfs - removes the driver name sysfs attribute + * @device: the target device + */ +static void cpuidle_remove_driver_sysfs(struct cpuidle_device *dev) +{ + struct cpuidle_driver_kobj *kdrv = dev->kobj_driver; + kobject_put(&kdrv->kobj); + wait_for_completion(&kdrv->kobj_unregister); + kfree(kdrv); +} +#else +static inline int cpuidle_add_driver_sysfs(struct cpuidle_device *dev) +{ + return 0; +} + +static inline void cpuidle_remove_driver_sysfs(struct cpuidle_device *dev) +{ + ; +} +#endif + +/** + * cpuidle_add_device_sysfs - adds device specific sysfs attributes + * @device: the target device + */ +int cpuidle_add_device_sysfs(struct cpuidle_device *device) +{ + int ret; + + ret = cpuidle_add_state_sysfs(device); + if (ret) + return ret; + + ret = cpuidle_add_driver_sysfs(device); + if (ret) + cpuidle_remove_state_sysfs(device); + return ret; +} + +/** + * cpuidle_remove_device_sysfs : removes device specific sysfs attributes + * @device : the target device + */ +void cpuidle_remove_device_sysfs(struct cpuidle_device *device) +{ + cpuidle_remove_driver_sysfs(device); + cpuidle_remove_state_sysfs(device); +} + /** * cpuidle_add_sysfs - creates a sysfs instance for the target device * @dev: the target device diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index d08e1afa491..3711b34dc4f 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -91,7 +91,7 @@ struct cpuidle_device { int state_count; struct cpuidle_state_usage states_usage[CPUIDLE_STATE_MAX]; struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; - + struct cpuidle_driver_kobj *kobj_driver; struct list_head device_list; struct kobject kobj; struct completion kobj_unregister; @@ -157,6 +157,10 @@ extern int cpuidle_wrap_enter(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index)); extern int cpuidle_play_dead(void); +extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev); +extern int cpuidle_register_cpu_driver(struct cpuidle_driver *drv, int cpu); +extern void cpuidle_unregister_cpu_driver(struct cpuidle_driver *drv, int cpu); + #else static inline void disable_cpuidle(void) { } static inline int cpuidle_idle_call(void) { return -ENODEV; } @@ -183,7 +187,6 @@ static inline int cpuidle_wrap_enter(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index)) { return -ENODEV; } static inline int cpuidle_play_dead(void) {return -ENODEV; } - #endif #ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED -- cgit v1.2.3 From 7e6fdd4bad033fa2d73716377b184fa975b0d985 Mon Sep 17 00:00:00 2001 From: Rajagopal Venkat Date: Fri, 26 Oct 2012 01:50:09 +0200 Subject: PM / devfreq: Core updates to support devices which can idle Prepare devfreq core framework to support devices which can idle. When device idleness is detected perhaps through runtime-pm, need some mechanism to suspend devfreq load monitoring and resume back when device is online. Present code continues monitoring unless device is removed from devfreq core. This patch introduces following design changes, - use per device work instead of global work to monitor device load. This enables suspend/resume of device devfreq and reduces monitoring code complexity. - decouple delayed work based load monitoring logic from core by introducing helpers functions to be used by governors. This provides flexibility for governors either to use delayed work based monitoring functions or to implement their own mechanism. - devfreq core interacts with governors via events to perform specific actions. These events include start/stop devfreq. This sets ground for adding suspend/resume events. The devfreq apis are not modified and are kept intact. Signed-off-by: Rajagopal Venkat Acked-by: MyungJoo Ham Signed-off-by: Rafael J. Wysocki --- Documentation/ABI/testing/sysfs-class-devfreq | 8 - drivers/devfreq/devfreq.c | 442 +++++++++++--------------- drivers/devfreq/governor.h | 11 + drivers/devfreq/governor_performance.c | 16 +- drivers/devfreq/governor_powersave.c | 16 +- drivers/devfreq/governor_simpleondemand.c | 24 ++ drivers/devfreq/governor_userspace.c | 23 +- include/linux/devfreq.h | 34 +- 8 files changed, 278 insertions(+), 296 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 23d78b5aab1..89283b1b024 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -21,14 +21,6 @@ Description: The /sys/class/devfreq/.../cur_freq shows the current frequency of the corresponding devfreq object. -What: /sys/class/devfreq/.../central_polling -Date: September 2011 -Contact: MyungJoo Ham -Description: - The /sys/class/devfreq/.../central_polling shows whether - the devfreq ojbect is using devfreq-provided central - polling mechanism or not. - What: /sys/class/devfreq/.../polling_interval Date: September 2011 Contact: MyungJoo Ham diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index b146d76f04c..1aaf1aeb1f1 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -30,17 +30,11 @@ struct class *devfreq_class; /* - * devfreq_work periodically monitors every registered device. - * The minimum polling interval is one jiffy. The polling interval is - * determined by the minimum polling period among all polling devfreq - * devices. The resolution of polling interval is one jiffy. + * devfreq core provides delayed work based load monitoring helper + * functions. Governors can use these or can implement their own + * monitoring mechanism. */ -static bool polling; static struct workqueue_struct *devfreq_wq; -static struct delayed_work devfreq_work; - -/* wait removing if this is to be removed */ -static struct devfreq *wait_remove_device; /* The list of all device-devfreq */ static LIST_HEAD(devfreq_list); @@ -72,6 +66,8 @@ static struct devfreq *find_device_devfreq(struct device *dev) return ERR_PTR(-ENODEV); } +/* Load monitoring helper functions for governors use */ + /** * update_devfreq() - Reevaluate the device and configure frequency. * @devfreq: the devfreq instance. @@ -120,6 +116,152 @@ int update_devfreq(struct devfreq *devfreq) return err; } +/** + * devfreq_monitor() - Periodically poll devfreq objects. + * @work: the work struct used to run devfreq_monitor periodically. + * + */ +static void devfreq_monitor(struct work_struct *work) +{ + int err; + struct devfreq *devfreq = container_of(work, + struct devfreq, work.work); + + mutex_lock(&devfreq->lock); + err = update_devfreq(devfreq); + if (err) + dev_err(&devfreq->dev, "dvfs failed with (%d) error\n", err); + + queue_delayed_work(devfreq_wq, &devfreq->work, + msecs_to_jiffies(devfreq->profile->polling_ms)); + mutex_unlock(&devfreq->lock); +} + +/** + * devfreq_monitor_start() - Start load monitoring of devfreq instance + * @devfreq: the devfreq instance. + * + * Helper function for starting devfreq device load monitoing. By + * default delayed work based monitoring is supported. Function + * to be called from governor in response to DEVFREQ_GOV_START + * event when device is added to devfreq framework. + */ +void devfreq_monitor_start(struct devfreq *devfreq) +{ + INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor); + if (devfreq->profile->polling_ms) + queue_delayed_work(devfreq_wq, &devfreq->work, + msecs_to_jiffies(devfreq->profile->polling_ms)); +} + +/** + * devfreq_monitor_stop() - Stop load monitoring of a devfreq instance + * @devfreq: the devfreq instance. + * + * Helper function to stop devfreq device load monitoing. Function + * to be called from governor in response to DEVFREQ_GOV_STOP + * event when device is removed from devfreq framework. + */ +void devfreq_monitor_stop(struct devfreq *devfreq) +{ + cancel_delayed_work_sync(&devfreq->work); +} + +/** + * devfreq_monitor_suspend() - Suspend load monitoring of a devfreq instance + * @devfreq: the devfreq instance. + * + * Helper function to suspend devfreq device load monitoing. Function + * to be called from governor in response to DEVFREQ_GOV_SUSPEND + * event or when polling interval is set to zero. + * + * Note: Though this function is same as devfreq_monitor_stop(), + * intentionally kept separate to provide hooks for collecting + * transition statistics. + */ +void devfreq_monitor_suspend(struct devfreq *devfreq) +{ + mutex_lock(&devfreq->lock); + if (devfreq->stop_polling) { + mutex_unlock(&devfreq->lock); + return; + } + + devfreq->stop_polling = true; + mutex_unlock(&devfreq->lock); + cancel_delayed_work_sync(&devfreq->work); +} + +/** + * devfreq_monitor_resume() - Resume load monitoring of a devfreq instance + * @devfreq: the devfreq instance. + * + * Helper function to resume devfreq device load monitoing. Function + * to be called from governor in response to DEVFREQ_GOV_RESUME + * event or when polling interval is set to non-zero. + */ +void devfreq_monitor_resume(struct devfreq *devfreq) +{ + mutex_lock(&devfreq->lock); + if (!devfreq->stop_polling) + goto out; + + if (!delayed_work_pending(&devfreq->work) && + devfreq->profile->polling_ms) + queue_delayed_work(devfreq_wq, &devfreq->work, + msecs_to_jiffies(devfreq->profile->polling_ms)); + devfreq->stop_polling = false; + +out: + mutex_unlock(&devfreq->lock); +} + +/** + * devfreq_interval_update() - Update device devfreq monitoring interval + * @devfreq: the devfreq instance. + * @delay: new polling interval to be set. + * + * Helper function to set new load monitoring polling interval. Function + * to be called from governor in response to DEVFREQ_GOV_INTERVAL event. + */ +void devfreq_interval_update(struct devfreq *devfreq, unsigned int *delay) +{ + unsigned int cur_delay = devfreq->profile->polling_ms; + unsigned int new_delay = *delay; + + mutex_lock(&devfreq->lock); + devfreq->profile->polling_ms = new_delay; + + if (devfreq->stop_polling) + goto out; + + /* if new delay is zero, stop polling */ + if (!new_delay) { + mutex_unlock(&devfreq->lock); + cancel_delayed_work_sync(&devfreq->work); + return; + } + + /* if current delay is zero, start polling with new delay */ + if (!cur_delay) { + queue_delayed_work(devfreq_wq, &devfreq->work, + msecs_to_jiffies(devfreq->profile->polling_ms)); + goto out; + } + + /* if current delay is greater than new delay, restart polling */ + if (cur_delay > new_delay) { + mutex_unlock(&devfreq->lock); + cancel_delayed_work_sync(&devfreq->work); + mutex_lock(&devfreq->lock); + if (!devfreq->stop_polling) + queue_delayed_work(devfreq_wq, &devfreq->work, + msecs_to_jiffies(devfreq->profile->polling_ms)); + } +out: + mutex_unlock(&devfreq->lock); +} + /** * devfreq_notifier_call() - Notify that the device frequency requirements * has been changed out of devfreq framework. @@ -143,59 +285,32 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type, } /** - * _remove_devfreq() - Remove devfreq from the device. + * _remove_devfreq() - Remove devfreq from the list and release its resources. * @devfreq: the devfreq struct * @skip: skip calling device_unregister(). - * - * Note that the caller should lock devfreq->lock before calling - * this. _remove_devfreq() will unlock it and free devfreq - * internally. devfreq_list_lock should be locked by the caller - * as well (not relased at return) - * - * Lock usage: - * devfreq->lock: locked before call. - * unlocked at return (and freed) - * devfreq_list_lock: locked before call. - * kept locked at return. - * if devfreq is centrally polled. - * - * Freed memory: - * devfreq */ static void _remove_devfreq(struct devfreq *devfreq, bool skip) { - if (!mutex_is_locked(&devfreq->lock)) { - WARN(true, "devfreq->lock must be locked by the caller.\n"); - return; - } - if (!devfreq->governor->no_central_polling && - !mutex_is_locked(&devfreq_list_lock)) { - WARN(true, "devfreq_list_lock must be locked by the caller.\n"); + mutex_lock(&devfreq_list_lock); + if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) { + mutex_unlock(&devfreq_list_lock); + dev_warn(&devfreq->dev, "releasing devfreq which doesn't exist\n"); return; } + list_del(&devfreq->node); + mutex_unlock(&devfreq_list_lock); - if (devfreq->being_removed) - return; - - devfreq->being_removed = true; + devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_STOP, NULL); if (devfreq->profile->exit) devfreq->profile->exit(devfreq->dev.parent); - if (devfreq->governor->exit) - devfreq->governor->exit(devfreq); - if (!skip && get_device(&devfreq->dev)) { device_unregister(&devfreq->dev); put_device(&devfreq->dev); } - if (!devfreq->governor->no_central_polling) - list_del(&devfreq->node); - - mutex_unlock(&devfreq->lock); mutex_destroy(&devfreq->lock); - kfree(devfreq); } @@ -210,130 +325,8 @@ static void _remove_devfreq(struct devfreq *devfreq, bool skip) static void devfreq_dev_release(struct device *dev) { struct devfreq *devfreq = to_devfreq(dev); - bool central_polling = !devfreq->governor->no_central_polling; - - /* - * If devfreq_dev_release() was called by device_unregister() of - * _remove_devfreq(), we cannot mutex_lock(&devfreq->lock) and - * being_removed is already set. This also partially checks the case - * where devfreq_dev_release() is called from a thread other than - * the one called _remove_devfreq(); however, this case is - * dealt completely with another following being_removed check. - * - * Because being_removed is never being - * unset, we do not need to worry about race conditions on - * being_removed. - */ - if (devfreq->being_removed) - return; - if (central_polling) - mutex_lock(&devfreq_list_lock); - - mutex_lock(&devfreq->lock); - - /* - * Check being_removed flag again for the case where - * devfreq_dev_release() was called in a thread other than the one - * possibly called _remove_devfreq(). - */ - if (devfreq->being_removed) { - mutex_unlock(&devfreq->lock); - goto out; - } - - /* devfreq->lock is unlocked and removed in _removed_devfreq() */ _remove_devfreq(devfreq, true); - -out: - if (central_polling) - mutex_unlock(&devfreq_list_lock); -} - -/** - * devfreq_monitor() - Periodically poll devfreq objects. - * @work: the work struct used to run devfreq_monitor periodically. - * - */ -static void devfreq_monitor(struct work_struct *work) -{ - static unsigned long last_polled_at; - struct devfreq *devfreq, *tmp; - int error; - unsigned long jiffies_passed; - unsigned long next_jiffies = ULONG_MAX, now = jiffies; - struct device *dev; - - /* Initially last_polled_at = 0, polling every device at bootup */ - jiffies_passed = now - last_polled_at; - last_polled_at = now; - if (jiffies_passed == 0) - jiffies_passed = 1; - - mutex_lock(&devfreq_list_lock); - list_for_each_entry_safe(devfreq, tmp, &devfreq_list, node) { - mutex_lock(&devfreq->lock); - dev = devfreq->dev.parent; - - /* Do not remove tmp for a while */ - wait_remove_device = tmp; - - if (devfreq->governor->no_central_polling || - devfreq->next_polling == 0) { - mutex_unlock(&devfreq->lock); - continue; - } - mutex_unlock(&devfreq_list_lock); - - /* - * Reduce more next_polling if devfreq_wq took an extra - * delay. (i.e., CPU has been idled.) - */ - if (devfreq->next_polling <= jiffies_passed) { - error = update_devfreq(devfreq); - - /* Remove a devfreq with an error. */ - if (error && error != -EAGAIN) { - - dev_err(dev, "Due to update_devfreq error(%d), devfreq(%s) is removed from the device\n", - error, devfreq->governor->name); - - /* - * Unlock devfreq before locking the list - * in order to avoid deadlock with - * find_device_devfreq or others - */ - mutex_unlock(&devfreq->lock); - mutex_lock(&devfreq_list_lock); - /* Check if devfreq is already removed */ - if (IS_ERR(find_device_devfreq(dev))) - continue; - mutex_lock(&devfreq->lock); - /* This unlocks devfreq->lock and free it */ - _remove_devfreq(devfreq, false); - continue; - } - devfreq->next_polling = devfreq->polling_jiffies; - } else { - devfreq->next_polling -= jiffies_passed; - } - - if (devfreq->next_polling) - next_jiffies = (next_jiffies > devfreq->next_polling) ? - devfreq->next_polling : next_jiffies; - - mutex_unlock(&devfreq->lock); - mutex_lock(&devfreq_list_lock); - } - wait_remove_device = NULL; - mutex_unlock(&devfreq_list_lock); - - if (next_jiffies > 0 && next_jiffies < ULONG_MAX) { - polling = true; - queue_delayed_work(devfreq_wq, &devfreq_work, next_jiffies); - } else { - polling = false; - } } /** @@ -357,16 +350,13 @@ struct devfreq *devfreq_add_device(struct device *dev, return ERR_PTR(-EINVAL); } - - if (!governor->no_central_polling) { - mutex_lock(&devfreq_list_lock); - devfreq = find_device_devfreq(dev); - mutex_unlock(&devfreq_list_lock); - if (!IS_ERR(devfreq)) { - dev_err(dev, "%s: Unable to create devfreq for the device. It already has one.\n", __func__); - err = -EINVAL; - goto err_out; - } + mutex_lock(&devfreq_list_lock); + devfreq = find_device_devfreq(dev); + mutex_unlock(&devfreq_list_lock); + if (!IS_ERR(devfreq)) { + dev_err(dev, "%s: Unable to create devfreq for the device. It already has one.\n", __func__); + err = -EINVAL; + goto err_out; } devfreq = kzalloc(sizeof(struct devfreq), GFP_KERNEL); @@ -386,48 +376,41 @@ struct devfreq *devfreq_add_device(struct device *dev, devfreq->governor = governor; devfreq->previous_freq = profile->initial_freq; devfreq->data = data; - devfreq->next_polling = devfreq->polling_jiffies - = msecs_to_jiffies(devfreq->profile->polling_ms); devfreq->nb.notifier_call = devfreq_notifier_call; dev_set_name(&devfreq->dev, dev_name(dev)); err = device_register(&devfreq->dev); if (err) { put_device(&devfreq->dev); + mutex_unlock(&devfreq->lock); goto err_dev; } - if (governor->init) - err = governor->init(devfreq); - if (err) - goto err_init; - mutex_unlock(&devfreq->lock); - if (governor->no_central_polling) - goto out; - mutex_lock(&devfreq_list_lock); - list_add(&devfreq->node, &devfreq_list); + mutex_unlock(&devfreq_list_lock); - if (devfreq_wq && devfreq->next_polling && !polling) { - polling = true; - queue_delayed_work(devfreq_wq, &devfreq_work, - devfreq->next_polling); + err = devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_START, NULL); + if (err) { + dev_err(dev, "%s: Unable to start governor for the device\n", + __func__); + goto err_init; } - mutex_unlock(&devfreq_list_lock); -out: + return devfreq; err_init: + list_del(&devfreq->node); device_unregister(&devfreq->dev); err_dev: - mutex_unlock(&devfreq->lock); kfree(devfreq); err_out: return ERR_PTR(err); } +EXPORT_SYMBOL(devfreq_add_device); /** * devfreq_remove_device() - Remove devfreq feature from a device. @@ -435,30 +418,14 @@ err_out: */ int devfreq_remove_device(struct devfreq *devfreq) { - bool central_polling; - if (!devfreq) return -EINVAL; - central_polling = !devfreq->governor->no_central_polling; - - if (central_polling) { - mutex_lock(&devfreq_list_lock); - while (wait_remove_device == devfreq) { - mutex_unlock(&devfreq_list_lock); - schedule(); - mutex_lock(&devfreq_list_lock); - } - } - - mutex_lock(&devfreq->lock); - _remove_devfreq(devfreq, false); /* it unlocks devfreq->lock */ - - if (central_polling) - mutex_unlock(&devfreq_list_lock); + _remove_devfreq(devfreq, false); return 0; } +EXPORT_SYMBOL(devfreq_remove_device); static ssize_t show_governor(struct device *dev, struct device_attribute *attr, char *buf) @@ -490,35 +457,13 @@ static ssize_t store_polling_interval(struct device *dev, if (ret != 1) goto out; - mutex_lock(&df->lock); - df->profile->polling_ms = value; - df->next_polling = df->polling_jiffies - = msecs_to_jiffies(value); - mutex_unlock(&df->lock); - + df->governor->event_handler(df, DEVFREQ_GOV_INTERVAL, &value); ret = count; - if (df->governor->no_central_polling) - goto out; - - mutex_lock(&devfreq_list_lock); - if (df->next_polling > 0 && !polling) { - polling = true; - queue_delayed_work(devfreq_wq, &devfreq_work, - df->next_polling); - } - mutex_unlock(&devfreq_list_lock); out: return ret; } -static ssize_t show_central_polling(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", - !to_devfreq(dev)->governor->no_central_polling); -} - static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -590,7 +535,6 @@ static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr, static struct device_attribute devfreq_attrs[] = { __ATTR(governor, S_IRUGO, show_governor, NULL), __ATTR(cur_freq, S_IRUGO, show_freq, NULL), - __ATTR(central_polling, S_IRUGO, show_central_polling, NULL), __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, store_polling_interval), __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq), @@ -598,23 +542,6 @@ static struct device_attribute devfreq_attrs[] = { { }, }; -/** - * devfreq_start_polling() - Initialize data structure for devfreq framework and - * start polling registered devfreq devices. - */ -static int __init devfreq_start_polling(void) -{ - mutex_lock(&devfreq_list_lock); - polling = false; - devfreq_wq = create_freezable_workqueue("devfreq_wq"); - INIT_DEFERRABLE_WORK(&devfreq_work, devfreq_monitor); - mutex_unlock(&devfreq_list_lock); - - devfreq_monitor(&devfreq_work.work); - return 0; -} -late_initcall(devfreq_start_polling); - static int __init devfreq_init(void) { devfreq_class = class_create(THIS_MODULE, "devfreq"); @@ -622,7 +549,15 @@ static int __init devfreq_init(void) pr_err("%s: couldn't create class\n", __FILE__); return PTR_ERR(devfreq_class); } + + devfreq_wq = create_freezable_workqueue("devfreq_wq"); + if (IS_ERR(devfreq_wq)) { + class_destroy(devfreq_class); + pr_err("%s: couldn't create workqueue\n", __FILE__); + return PTR_ERR(devfreq_wq); + } devfreq_class->dev_attrs = devfreq_attrs; + return 0; } subsys_initcall(devfreq_init); @@ -630,6 +565,7 @@ subsys_initcall(devfreq_init); static void __exit devfreq_exit(void) { class_destroy(devfreq_class); + destroy_workqueue(devfreq_wq); } module_exit(devfreq_exit); diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index ea7f13c58de..bb3aff32d62 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -18,7 +18,18 @@ #define to_devfreq(DEV) container_of((DEV), struct devfreq, dev) +/* Devfreq events */ +#define DEVFREQ_GOV_START 0x1 +#define DEVFREQ_GOV_STOP 0x2 +#define DEVFREQ_GOV_INTERVAL 0x3 + /* Caution: devfreq->lock must be locked before calling update_devfreq */ extern int update_devfreq(struct devfreq *devfreq); +extern void devfreq_monitor_start(struct devfreq *devfreq); +extern void devfreq_monitor_stop(struct devfreq *devfreq); +extern void devfreq_monitor_suspend(struct devfreq *devfreq); +extern void devfreq_monitor_resume(struct devfreq *devfreq); +extern void devfreq_interval_update(struct devfreq *devfreq, + unsigned int *delay); #endif /* _GOVERNOR_H */ diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c index af75ddd4f15..eea3f9bd789 100644 --- a/drivers/devfreq/governor_performance.c +++ b/drivers/devfreq/governor_performance.c @@ -26,14 +26,22 @@ static int devfreq_performance_func(struct devfreq *df, return 0; } -static int performance_init(struct devfreq *devfreq) +static int devfreq_performance_handler(struct devfreq *devfreq, + unsigned int event, void *data) { - return update_devfreq(devfreq); + int ret = 0; + + if (event == DEVFREQ_GOV_START) { + mutex_lock(&devfreq->lock); + ret = update_devfreq(devfreq); + mutex_unlock(&devfreq->lock); + } + + return ret; } const struct devfreq_governor devfreq_performance = { .name = "performance", - .init = performance_init, .get_target_freq = devfreq_performance_func, - .no_central_polling = true, + .event_handler = devfreq_performance_handler, }; diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c index fec0cdbd247..2868d98ed3e 100644 --- a/drivers/devfreq/governor_powersave.c +++ b/drivers/devfreq/governor_powersave.c @@ -23,14 +23,22 @@ static int devfreq_powersave_func(struct devfreq *df, return 0; } -static int powersave_init(struct devfreq *devfreq) +static int devfreq_powersave_handler(struct devfreq *devfreq, + unsigned int event, void *data) { - return update_devfreq(devfreq); + int ret = 0; + + if (event == DEVFREQ_GOV_START) { + mutex_lock(&devfreq->lock); + ret = update_devfreq(devfreq); + mutex_unlock(&devfreq->lock); + } + + return ret; } const struct devfreq_governor devfreq_powersave = { .name = "powersave", - .init = powersave_init, .get_target_freq = devfreq_powersave_func, - .no_central_polling = true, + .event_handler = devfreq_powersave_handler, }; diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index a2e3eae7901..3716a659122 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -12,6 +12,7 @@ #include #include #include +#include "governor.h" /* Default constants for DevFreq-Simple-Ondemand (DFSO) */ #define DFSO_UPTHRESHOLD (90) @@ -88,7 +89,30 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, return 0; } +static int devfreq_simple_ondemand_handler(struct devfreq *devfreq, + unsigned int event, void *data) +{ + switch (event) { + case DEVFREQ_GOV_START: + devfreq_monitor_start(devfreq); + break; + + case DEVFREQ_GOV_STOP: + devfreq_monitor_stop(devfreq); + break; + + case DEVFREQ_GOV_INTERVAL: + devfreq_interval_update(devfreq, (unsigned int *)data); + break; + default: + break; + } + + return 0; +} + const struct devfreq_governor devfreq_simple_ondemand = { .name = "simple_ondemand", .get_target_freq = devfreq_simple_ondemand_func, + .event_handler = devfreq_simple_ondemand_handler, }; diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c index 0681246fc89..7067555bd44 100644 --- a/drivers/devfreq/governor_userspace.c +++ b/drivers/devfreq/governor_userspace.c @@ -116,10 +116,27 @@ static void userspace_exit(struct devfreq *devfreq) devfreq->data = NULL; } +static int devfreq_userspace_handler(struct devfreq *devfreq, + unsigned int event, void *data) +{ + int ret = 0; + + switch (event) { + case DEVFREQ_GOV_START: + ret = userspace_init(devfreq); + break; + case DEVFREQ_GOV_STOP: + userspace_exit(devfreq); + break; + default: + break; + } + + return ret; +} + const struct devfreq_governor devfreq_userspace = { .name = "userspace", .get_target_freq = devfreq_userspace_func, - .init = userspace_init, - .exit = userspace_exit, - .no_central_polling = true, + .event_handler = devfreq_userspace_handler, }; diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 281c72a3b9d..9cdffde74bb 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -91,25 +91,18 @@ struct devfreq_dev_profile { * status of the device (load = busy_time / total_time). * If no_central_polling is set, this callback is called * only with update_devfreq() notified by OPP. - * @init Called when the devfreq is being attached to a device - * @exit Called when the devfreq is being removed from a - * device. Governor should stop any internal routines - * before return because related data may be - * freed after exit(). - * @no_central_polling Do not use devfreq's central polling mechanism. - * When this is set, devfreq will not call - * get_target_freq with devfreq_monitor(). However, - * devfreq will call get_target_freq with - * devfreq_update() notified by OPP framework. + * @event_handler Callback for devfreq core framework to notify events + * to governors. Events include per device governor + * init and exit, opp changes out of devfreq, suspend + * and resume of per device devfreq during device idle. * * Note that the callbacks are called with devfreq->lock locked by devfreq. */ struct devfreq_governor { const char name[DEVFREQ_NAME_LEN]; int (*get_target_freq)(struct devfreq *this, unsigned long *freq); - int (*init)(struct devfreq *this); - void (*exit)(struct devfreq *this); - const bool no_central_polling; + int (*event_handler)(struct devfreq *devfreq, + unsigned int event, void *data); }; /** @@ -124,18 +117,13 @@ struct devfreq_governor { * @nb notifier block used to notify devfreq object that it should * reevaluate operable frequencies. Devfreq users may use * devfreq.nb to the corresponding register notifier call chain. - * @polling_jiffies interval in jiffies. + * @work delayed work for load monitoring. * @previous_freq previously configured frequency value. - * @next_polling the number of remaining jiffies to poll with - * "devfreq_monitor" executions to reevaluate - * frequency/voltage of the device. Set by - * profile's polling_ms interval. * @data Private data of the governor. The devfreq framework does not * touch this. - * @being_removed a flag to mark that this object is being removed in - * order to prevent trying to remove the object multiple times. * @min_freq Limit minimum frequency requested by user (0: none) * @max_freq Limit maximum frequency requested by user (0: none) + * @stop_polling devfreq polling status of a device. * * This structure stores the devfreq information for a give device. * @@ -153,17 +141,15 @@ struct devfreq { struct devfreq_dev_profile *profile; const struct devfreq_governor *governor; struct notifier_block nb; + struct delayed_work work; - unsigned long polling_jiffies; unsigned long previous_freq; - unsigned int next_polling; void *data; /* private data for governors */ - bool being_removed; - unsigned long min_freq; unsigned long max_freq; + bool stop_polling; }; #if defined(CONFIG_PM_DEVFREQ) -- cgit v1.2.3 From 206c30cfeb7c05dfb9fdfd81b1deb933627e43c1 Mon Sep 17 00:00:00 2001 From: Rajagopal Venkat Date: Fri, 26 Oct 2012 01:50:18 +0200 Subject: PM / devfreq: Add suspend and resume apis Add devfreq suspend/resume apis for devfreq users. This patch supports suspend and resume of devfreq load monitoring, required for devices which can idle. Signed-off-by: Rajagopal Venkat Acked-by: MyungJoo Ham Signed-off-by: Rafael J. Wysocki --- drivers/devfreq/devfreq.c | 28 ++++++++++++++++++++++++++++ drivers/devfreq/governor.h | 2 ++ drivers/devfreq/governor_simpleondemand.c | 9 +++++++++ include/linux/devfreq.h | 12 ++++++++++++ 4 files changed, 51 insertions(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 1aaf1aeb1f1..999600da21c 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -427,6 +427,34 @@ int devfreq_remove_device(struct devfreq *devfreq) } EXPORT_SYMBOL(devfreq_remove_device); +/** + * devfreq_suspend_device() - Suspend devfreq of a device. + * @devfreq: the devfreq instance to be suspended + */ +int devfreq_suspend_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + return devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_SUSPEND, NULL); +} +EXPORT_SYMBOL(devfreq_suspend_device); + +/** + * devfreq_resume_device() - Resume devfreq of a device. + * @devfreq: the devfreq instance to be resumed + */ +int devfreq_resume_device(struct devfreq *devfreq) +{ + if (!devfreq) + return -EINVAL; + + return devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_RESUME, NULL); +} +EXPORT_SYMBOL(devfreq_resume_device); + static ssize_t show_governor(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index bb3aff32d62..26432ac0a39 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -22,6 +22,8 @@ #define DEVFREQ_GOV_START 0x1 #define DEVFREQ_GOV_STOP 0x2 #define DEVFREQ_GOV_INTERVAL 0x3 +#define DEVFREQ_GOV_SUSPEND 0x4 +#define DEVFREQ_GOV_RESUME 0x5 /* Caution: devfreq->lock must be locked before calling update_devfreq */ extern int update_devfreq(struct devfreq *devfreq); diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index 3716a659122..b5cf0fb24ef 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -104,6 +104,15 @@ static int devfreq_simple_ondemand_handler(struct devfreq *devfreq, case DEVFREQ_GOV_INTERVAL: devfreq_interval_update(devfreq, (unsigned int *)data); break; + + case DEVFREQ_GOV_SUSPEND: + devfreq_monitor_suspend(devfreq); + break; + + case DEVFREQ_GOV_RESUME: + devfreq_monitor_resume(devfreq); + break; + default: break; } diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 9cdffde74bb..ee243a3229b 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -158,6 +158,8 @@ extern struct devfreq *devfreq_add_device(struct device *dev, const struct devfreq_governor *governor, void *data); extern int devfreq_remove_device(struct devfreq *devfreq); +extern int devfreq_suspend_device(struct devfreq *devfreq); +extern int devfreq_resume_device(struct devfreq *devfreq); /* Helper functions for devfreq user device driver with OPP. */ extern struct opp *devfreq_recommended_opp(struct device *dev, @@ -211,6 +213,16 @@ static int devfreq_remove_device(struct devfreq *devfreq) return 0; } +static int devfreq_suspend_device(struct devfreq *devfreq) +{ + return 0; +} + +static int devfreq_resume_device(struct devfreq *devfreq) +{ + return 0; +} + static struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags) { -- cgit v1.2.3 From 7f98a905dca6e4f144cdd4462edeac00c2bdc379 Mon Sep 17 00:00:00 2001 From: Rajagopal Venkat Date: Fri, 26 Oct 2012 01:50:26 +0200 Subject: PM / devfreq: Add current freq callback in device profile Devfreq returns governor predicted frequency as current frequency via sysfs interface. But device may not support all frequencies that governor predicts. So add a callback in device profile to get current freq from driver. Also add a new sysfs node to expose governor predicted next target frequency. Signed-off-by: Rajagopal Venkat Acked-by: MyungJoo Ham Signed-off-by: Rafael J. Wysocki --- Documentation/ABI/testing/sysfs-class-devfreq | 11 ++++++++++- drivers/devfreq/devfreq.c | 14 ++++++++++++++ include/linux/devfreq.h | 3 +++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 89283b1b024..e6cf08e6734 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -19,7 +19,16 @@ Date: September 2011 Contact: MyungJoo Ham Description: The /sys/class/devfreq/.../cur_freq shows the current - frequency of the corresponding devfreq object. + frequency of the corresponding devfreq object. Same as + target_freq when get_cur_freq() is not implemented by + devfreq driver. + +What: /sys/class/devfreq/.../target_freq +Date: September 2012 +Contact: Rajagopal Venkat +Description: + The /sys/class/devfreq/.../target_freq shows the next governor + predicted target frequency of the corresponding devfreq object. What: /sys/class/devfreq/.../polling_interval Date: September 2011 diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 999600da21c..f2f8a976c46 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -463,6 +463,19 @@ static ssize_t show_governor(struct device *dev, static ssize_t show_freq(struct device *dev, struct device_attribute *attr, char *buf) +{ + unsigned long freq; + struct devfreq *devfreq = to_devfreq(dev); + + if (devfreq->profile->get_cur_freq && + !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq)) + return sprintf(buf, "%lu\n", freq); + + return sprintf(buf, "%lu\n", devfreq->previous_freq); +} + +static ssize_t show_target_freq(struct device *dev, + struct device_attribute *attr, char *buf) { return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq); } @@ -563,6 +576,7 @@ static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr, static struct device_attribute devfreq_attrs[] = { __ATTR(governor, S_IRUGO, show_governor, NULL), __ATTR(cur_freq, S_IRUGO, show_freq, NULL), + __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, store_polling_interval), __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq), diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index ee243a3229b..7e2e2ea4a70 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -66,6 +66,8 @@ struct devfreq_dev_status { * explained above with "DEVFREQ_FLAG_*" macros. * @get_dev_status The device should provide the current performance * status to devfreq, which is used by governors. + * @get_cur_freq The device should provide the current frequency + * at which it is operating. * @exit An optional callback that is called when devfreq * is removing the devfreq object due to error or * from devfreq_remove_device() call. If the user @@ -79,6 +81,7 @@ struct devfreq_dev_profile { int (*target)(struct device *dev, unsigned long *freq, u32 flags); int (*get_dev_status)(struct device *dev, struct devfreq_dev_status *stat); + int (*get_cur_freq)(struct device *dev, unsigned long *freq); void (*exit)(struct device *dev); }; -- cgit v1.2.3 From c5b4a1c15da3e6f472c6ff1a085a1134d18a1464 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 26 Oct 2012 01:50:35 +0200 Subject: PM / devfreq: kernel-doc typo corrections Parameter documentation needs a ':' for scripts/kernel-doc to parse properly. Minor fixes for ones warned by: ./scripts/kernel-doc -text drivers/devfreq/devfreq.c>/dev/null Signed-off-by: Nishanth Menon Acked-by: Randy Dunlap Acked-by: MyungJoo Ham Signed-off-by: Rafael J. Wysocki --- drivers/devfreq/devfreq.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index f2f8a976c46..a42f69b34eb 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -265,9 +265,9 @@ out: /** * devfreq_notifier_call() - Notify that the device frequency requirements * has been changed out of devfreq framework. - * @nb the notifier_block (supposed to be devfreq->nb) - * @type not used - * @devp not used + * @nb: the notifier_block (supposed to be devfreq->nb) + * @type: not used + * @devp: not used * * Called by a notifier that uses devfreq->nb. */ @@ -414,7 +414,7 @@ EXPORT_SYMBOL(devfreq_add_device); /** * devfreq_remove_device() - Remove devfreq feature from a device. - * @devfreq the devfreq instance to be removed + * @devfreq: the devfreq instance to be removed */ int devfreq_remove_device(struct devfreq *devfreq) { @@ -619,9 +619,9 @@ module_exit(devfreq_exit); /** * devfreq_recommended_opp() - Helper function to get proper OPP for the * freq value given to target callback. - * @dev The devfreq user device. (parent of devfreq) - * @freq The frequency given to target function - * @flags Flags handed from devfreq framework. + * @dev: The devfreq user device. (parent of devfreq) + * @freq: The frequency given to target function + * @flags: Flags handed from devfreq framework. * */ struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, @@ -652,8 +652,8 @@ struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, * devfreq_register_opp_notifier() - Helper function to get devfreq notified * for any changes in the OPP availability * changes - * @dev The devfreq user device. (parent of devfreq) - * @devfreq The devfreq object. + * @dev: The devfreq user device. (parent of devfreq) + * @devfreq: The devfreq object. */ int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq) { @@ -668,8 +668,8 @@ int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq) * devfreq_unregister_opp_notifier() - Helper function to stop getting devfreq * notified for any changes in the OPP * availability changes anymore. - * @dev The devfreq user device. (parent of devfreq) - * @devfreq The devfreq object. + * @dev: The devfreq user device. (parent of devfreq) + * @devfreq: The devfreq object. * * At exit() callback of devfreq_dev_profile, this must be included if * devfreq_recommended_opp is used. -- cgit v1.2.3 From 12e26265e6225bf93b2fdc70399774b31e2dd980 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 26 Oct 2012 01:50:43 +0200 Subject: PM / devfreq: fix sscanf handling for writable sysfs entries sscanf returns 0 when an invalid parameter like: echo -n "a">min_freq is attempted. Returning back the return result(0) will cause the command not to return back to command prompt. Instead, just return -EINVAL when sscanf does not return 1. This is done for min_freq, max_freq and polling_interval Signed-off-by: Nishanth Menon Acked-by: MyungJoo Ham Signed-off-by: Rafael J. Wysocki --- drivers/devfreq/devfreq.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index a42f69b34eb..79a7343c28a 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -496,12 +496,11 @@ static ssize_t store_polling_interval(struct device *dev, ret = sscanf(buf, "%u", &value); if (ret != 1) - goto out; + return -EINVAL; df->governor->event_handler(df, DEVFREQ_GOV_INTERVAL, &value); ret = count; -out: return ret; } @@ -515,7 +514,7 @@ static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr, ret = sscanf(buf, "%lu", &value); if (ret != 1) - goto out; + return -EINVAL; mutex_lock(&df->lock); max = df->max_freq; @@ -529,7 +528,6 @@ static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr, ret = count; unlock: mutex_unlock(&df->lock); -out: return ret; } @@ -549,7 +547,7 @@ static ssize_t store_max_freq(struct device *dev, struct device_attribute *attr, ret = sscanf(buf, "%lu", &value); if (ret != 1) - goto out; + return -EINVAL; mutex_lock(&df->lock); min = df->min_freq; @@ -563,7 +561,6 @@ static ssize_t store_max_freq(struct device *dev, struct device_attribute *attr, ret = count; unlock: mutex_unlock(&df->lock); -out: return ret; } -- cgit v1.2.3 From 1a1357ea176670867f347419c3345e2becc07338 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 26 Oct 2012 01:50:53 +0200 Subject: PM / devfreq: make devfreq_class static devfreq_class is used internally by devfreq and has no need to be globally available. This also fixes the following sparse warning: drivers/devfreq/devfreq.c:30:14: warning: symbol 'devfreq_class' was not declared. Should it be static? Signed-off-by: Nishanth Menon Signed-off-by: Rafael J. Wysocki --- drivers/devfreq/devfreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 79a7343c28a..789af4ff5c9 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -27,7 +27,7 @@ #include #include "governor.h" -struct class *devfreq_class; +static struct class *devfreq_class; /* * devfreq core provides delayed work based load monitoring helper -- cgit v1.2.3 From dde8437d06560366d8988c92b5774039ec703864 Mon Sep 17 00:00:00 2001 From: Vincent Guittot Date: Tue, 23 Oct 2012 01:21:49 +0200 Subject: PM / OPP: RCU reclaim synchronize_rcu() blocks the caller of opp_enable/disbale for a complete grace period. This blocking duration prevents any intensive use of the functions. Replace synchronize_rcu() by call_rcu() which will call our function for freeing the old opp element. The duration of opp_enable() and opp_disable() will be no more dependant of the grace period. Signed-off-by: Vincent Guittot Reviewed-by: Paul E. McKenney Signed-off-by: Rafael J. Wysocki --- drivers/base/power/opp.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index d9468642fc4..1211210b15b 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -65,6 +65,7 @@ struct opp { unsigned long u_volt; struct device_opp *dev_opp; + struct rcu_head head; }; /** @@ -441,6 +442,17 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) return 0; } +/** + * opp_free_rcu() - helper to clear the struct opp when grace period has + * elapsed without blocking the the caller of opp_set_availability + */ +static void opp_free_rcu(struct rcu_head *head) +{ + struct opp *opp = container_of(head, struct opp, head); + + kfree(opp); +} + /** * opp_set_availability() - helper to set the availability of an opp * @dev: device for which we do this operation @@ -512,7 +524,7 @@ static int opp_set_availability(struct device *dev, unsigned long freq, list_replace_rcu(&opp->node, &new_opp->node); mutex_unlock(&dev_opp_list_lock); - synchronize_rcu(); + call_rcu(&opp->head, opp_free_rcu); /* Notify the change of the OPP availability */ if (availability_req) @@ -522,13 +534,10 @@ static int opp_set_availability(struct device *dev, unsigned long freq, srcu_notifier_call_chain(&dev_opp->head, OPP_EVENT_DISABLE, new_opp); - /* clean up old opp */ - new_opp = opp; - goto out; + return 0; unlock: mutex_unlock(&dev_opp_list_lock); -out: kfree(new_opp); return r; } -- cgit v1.2.3 From 80126ce7aeb4e187429681ef8a7785b7dcd7a348 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Tue, 23 Oct 2012 01:27:44 +0200 Subject: PM / OPP: Export symbols for module usage. Export the OPP functions for use by driver modules. Cc: "Rafael J. Wysocki" Cc: Kevin Hilman Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org [nm@ti.com: expansion of functions exported] Signed-off-by: Nishanth Menon Signed-off-by: Liam Girdwood Acked-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- drivers/base/power/opp.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 1211210b15b..66888861f9e 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -23,6 +23,7 @@ #include #include #include +#include /* * Internal data structure organization with the OPP layer library is as @@ -161,6 +162,7 @@ unsigned long opp_get_voltage(struct opp *opp) return v; } +EXPORT_SYMBOL(opp_get_voltage); /** * opp_get_freq() - Gets the frequency corresponding to an available opp @@ -190,6 +192,7 @@ unsigned long opp_get_freq(struct opp *opp) return f; } +EXPORT_SYMBOL(opp_get_freq); /** * opp_get_opp_count() - Get number of opps available in the opp list @@ -222,6 +225,7 @@ int opp_get_opp_count(struct device *dev) return count; } +EXPORT_SYMBOL(opp_get_opp_count); /** * opp_find_freq_exact() - search for an exact frequency @@ -269,6 +273,7 @@ struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq, return opp; } +EXPORT_SYMBOL(opp_find_freq_exact); /** * opp_find_freq_ceil() - Search for an rounded ceil freq @@ -311,6 +316,7 @@ struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq) return opp; } +EXPORT_SYMBOL(opp_find_freq_ceil); /** * opp_find_freq_floor() - Search for a rounded floor freq @@ -357,6 +363,7 @@ struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq) return opp; } +EXPORT_SYMBOL(opp_find_freq_floor); /** * opp_add() - Add an OPP table from a table definitions @@ -561,6 +568,7 @@ int opp_enable(struct device *dev, unsigned long freq) { return opp_set_availability(dev, freq, true); } +EXPORT_SYMBOL(opp_enable); /** * opp_disable() - Disable a specific OPP @@ -582,6 +590,7 @@ int opp_disable(struct device *dev, unsigned long freq) { return opp_set_availability(dev, freq, false); } +EXPORT_SYMBOL(opp_disable); #ifdef CONFIG_CPU_FREQ /** -- cgit v1.2.3 From 0779726cc265805d0f7c7dd1d791fa4076b31a9a Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Wed, 24 Oct 2012 22:00:12 +0200 Subject: PM / OPP: predictable fail results for opp_find* functions, v2 Currently the opp_find* functions return -ENODEV when: a) it cant find a device (e.g. request for an OPP search on device which was not registered) b) When it cant find a match for the search strategy used This makes life a little in-efficient for users such as devfreq to make reasonable judgement before switching search strategies. So, standardize the return results as following: -EINVAL for bad pointer parameters -ENODEV when device cannot be found -ERANGE when search fails This has the following benefit for devfreq implementation: The search fails when an unregistered device pointer is provided. This is a trigger to change the search direction and search for a better fit, however, if we cannot differentiate between a valid search range failure Vs an unregistered device, second search goes through the same fail return condition. This can be avoided by appropriate handling of error return code. With this change, we also fix devfreq for the improved search strategy with updated error code. Signed-off-by: Nishanth Menon Reviewed-by: Kevin Hilman Acked-by: MyungJoo Ham Signed-off-by: Rafael J. Wysocki --- drivers/base/power/opp.c | 27 +++++++++++++++++++-------- drivers/devfreq/devfreq.c | 4 ++-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 66888861f9e..c8a908b099c 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -235,7 +235,10 @@ EXPORT_SYMBOL(opp_get_opp_count); * * Searches for exact match in the opp list and returns pointer to the matching * opp if found, else returns ERR_PTR in case of error and should be handled - * using IS_ERR. + * using IS_ERR. Error return values can be: + * EINVAL: for bad pointer + * ERANGE: no match found for search + * ENODEV: if device not found in list of registered devices * * Note: available is a modifier for the search. if available=true, then the * match is for exact matching frequency and is available in the stored OPP @@ -254,7 +257,7 @@ struct opp *opp_find_freq_exact(struct device *dev, unsigned long freq, bool available) { struct device_opp *dev_opp; - struct opp *temp_opp, *opp = ERR_PTR(-ENODEV); + struct opp *temp_opp, *opp = ERR_PTR(-ERANGE); dev_opp = find_device_opp(dev); if (IS_ERR(dev_opp)) { @@ -284,7 +287,11 @@ EXPORT_SYMBOL(opp_find_freq_exact); * for a device. * * Returns matching *opp and refreshes *freq accordingly, else returns - * ERR_PTR in case of error and should be handled using IS_ERR. + * ERR_PTR in case of error and should be handled using IS_ERR. Error return + * values can be: + * EINVAL: for bad pointer + * ERANGE: no match found for search + * ENODEV: if device not found in list of registered devices * * Locking: This function must be called under rcu_read_lock(). opp is a rcu * protected pointer. The reason for the same is that the opp pointer which is @@ -295,7 +302,7 @@ EXPORT_SYMBOL(opp_find_freq_exact); struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq) { struct device_opp *dev_opp; - struct opp *temp_opp, *opp = ERR_PTR(-ENODEV); + struct opp *temp_opp, *opp = ERR_PTR(-ERANGE); if (!dev || !freq) { dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); @@ -304,7 +311,7 @@ struct opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq) dev_opp = find_device_opp(dev); if (IS_ERR(dev_opp)) - return opp; + return ERR_CAST(dev_opp); list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) { if (temp_opp->available && temp_opp->rate >= *freq) { @@ -327,7 +334,11 @@ EXPORT_SYMBOL(opp_find_freq_ceil); * for a device. * * Returns matching *opp and refreshes *freq accordingly, else returns - * ERR_PTR in case of error and should be handled using IS_ERR. + * ERR_PTR in case of error and should be handled using IS_ERR. Error return + * values can be: + * EINVAL: for bad pointer + * ERANGE: no match found for search + * ENODEV: if device not found in list of registered devices * * Locking: This function must be called under rcu_read_lock(). opp is a rcu * protected pointer. The reason for the same is that the opp pointer which is @@ -338,7 +349,7 @@ EXPORT_SYMBOL(opp_find_freq_ceil); struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq) { struct device_opp *dev_opp; - struct opp *temp_opp, *opp = ERR_PTR(-ENODEV); + struct opp *temp_opp, *opp = ERR_PTR(-ERANGE); if (!dev || !freq) { dev_err(dev, "%s: Invalid argument freq=%p\n", __func__, freq); @@ -347,7 +358,7 @@ struct opp *opp_find_freq_floor(struct device *dev, unsigned long *freq) dev_opp = find_device_opp(dev); if (IS_ERR(dev_opp)) - return opp; + return ERR_CAST(dev_opp); list_for_each_entry_rcu(temp_opp, &dev_opp->opp_list, node) { if (temp_opp->available) { diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index b146d76f04c..4fa1a22c55e 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -656,14 +656,14 @@ struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, opp = opp_find_freq_floor(dev, freq); /* If not available, use the closest opp */ - if (opp == ERR_PTR(-ENODEV)) + if (opp == ERR_PTR(-ERANGE)) opp = opp_find_freq_ceil(dev, freq); } else { /* The freq is an lower bound. opp should be higher */ opp = opp_find_freq_ceil(dev, freq); /* If not available, use the closest opp */ - if (opp == ERR_PTR(-ENODEV)) + if (opp == ERR_PTR(-ERANGE)) opp = opp_find_freq_floor(dev, freq); } -- cgit v1.2.3 From ea83f81b489be3be268ed7fabfe8dd94bdc45a29 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 31 Oct 2012 01:29:17 +0100 Subject: PM / OPP: using kfree_rcu() to simplify the code The callback function of call_rcu() just calls a kfree(), so we can use kfree_rcu() instead of call_rcu() + callback function. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Rafael J. Wysocki --- drivers/base/power/opp.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index c8a908b099c..50b2831e027 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -460,17 +460,6 @@ int opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) return 0; } -/** - * opp_free_rcu() - helper to clear the struct opp when grace period has - * elapsed without blocking the the caller of opp_set_availability - */ -static void opp_free_rcu(struct rcu_head *head) -{ - struct opp *opp = container_of(head, struct opp, head); - - kfree(opp); -} - /** * opp_set_availability() - helper to set the availability of an opp * @dev: device for which we do this operation @@ -542,7 +531,7 @@ static int opp_set_availability(struct device *dev, unsigned long freq, list_replace_rcu(&opp->node, &new_opp->node); mutex_unlock(&dev_opp_list_lock); - call_rcu(&opp->head, opp_free_rcu); + kfree_rcu(opp, head); /* Notify the change of the OPP availability */ if (availability_req) -- cgit v1.2.3 From c122f27e1c1bada4cdf19669afed5a00a69bc5a5 Mon Sep 17 00:00:00 2001 From: Murali Karicheri Date: Tue, 23 Oct 2012 01:18:40 +0200 Subject: base: power - use clk_prepare_enable and clk_prepare_disable When PM runtime is enabled in DaVinci and the machine migrates to common clk framework, the clk_enable() gets called without clk_prepare(). This patch is to fix this issue so that PM run time can inter work with common clk framework. Signed-off-by: Murali Karicheri Signed-off-by: Rafael J. Wysocki --- drivers/base/power/clock_ops.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index eb78e9640c4..9d8fde70939 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -99,7 +99,7 @@ static void __pm_clk_remove(struct pm_clock_entry *ce) if (ce->status < PCE_STATUS_ERROR) { if (ce->status == PCE_STATUS_ENABLED) - clk_disable(ce->clk); + clk_disable_unprepare(ce->clk); if (ce->status >= PCE_STATUS_ACQUIRED) clk_put(ce->clk); @@ -396,7 +396,7 @@ static void enable_clock(struct device *dev, const char *con_id) clk = clk_get(dev, con_id); if (!IS_ERR(clk)) { - clk_enable(clk); + clk_prepare_enable(clk); clk_put(clk); dev_info(dev, "Runtime PM disabled, clock forced on.\n"); } @@ -413,7 +413,7 @@ static void disable_clock(struct device *dev, const char *con_id) clk = clk_get(dev, con_id); if (!IS_ERR(clk)) { - clk_disable(clk); + clk_disable_unprepare(clk); clk_put(clk); dev_info(dev, "Runtime PM disabled, clock forced off.\n"); } -- cgit v1.2.3 From 883ee4f79d636d13f24c2479c66d42cb652b0239 Mon Sep 17 00:00:00 2001 From: Daniel Walter Date: Tue, 23 Oct 2012 01:20:35 +0200 Subject: PM / sysfs: replace strict_str* with kstrto* Replace strict_strtoul() with kstrtoul() in pm_async_store() and pm_qos_power_write(). [rjw: Modified subject and changelog.] Signed-off-by: Daniel Walter Acked-by: Pavel Machek Signed-off-by: Rafael J. Wysocki --- kernel/power/main.c | 2 +- kernel/power/qos.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/power/main.c b/kernel/power/main.c index f458238109c..1c16f9167de 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -59,7 +59,7 @@ static ssize_t pm_async_store(struct kobject *kobj, struct kobj_attribute *attr, { unsigned long val; - if (strict_strtoul(buf, 10, &val)) + if (kstrtoul(buf, 10, &val)) return -EINVAL; if (val > 1) diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 846bd42c7ed..4da05cee81b 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -500,7 +500,7 @@ static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf, } else { ascii_value[count] = '\0'; } - ret = strict_strtoul(ascii_value, 16, &ulval); + ret = kstrtoul(ascii_value, 16, &ulval); if (ret) { pr_debug("%s, 0x%lx, 0x%x\n", ascii_value, ulval, ret); return -EINVAL; -- cgit v1.2.3 From 8316bd72c0248adbb9572abf2dd045a95f682bcd Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Tue, 23 Oct 2012 01:21:09 +0200 Subject: PM / Hibernate: use rb_entry Since the software suspend extents are organized in an rbtree, use rb_entry instead of container_of, as it is semantically more appropriate in order to get a node as it is iterated. Signed-off-by: Davidlohr Bueso Signed-off-by: Rafael J. Wysocki --- kernel/power/swap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 3c9d764eb0d..7c33ed20041 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -126,7 +126,7 @@ static int swsusp_extents_insert(unsigned long swap_offset) /* Figure out where to put the new node */ while (*new) { - ext = container_of(*new, struct swsusp_extent, node); + ext = rb_entry(*new, struct swsusp_extent, node); parent = *new; if (swap_offset < ext->start) { /* Try to merge */ -- cgit v1.2.3 From 4b6d1f12f9c4e0e420d5747d3ae285d8f66d627f Mon Sep 17 00:00:00 2001 From: LongX Zhang Date: Thu, 25 Oct 2012 00:21:28 +0200 Subject: driver core / PM: move the calling to device_pm_remove behind the calling to bus_remove_device We hit an hang issue when removing a mmc device on Medfield Android phone by sysfs interface. device_pm_remove will call pm_runtime_remove which would disable runtime PM of the device. After that pm_runtime_get* or pm_runtime_put* will be ignored. So if we disable the runtime PM before device really be removed, drivers' _remove callback may access HW even pm_runtime_get* fails. That is bad. Consider below call sequence when removing a device: device_del => device_pm_remove => class_intf->remove_dev(dev, class_intf) => pm_runtime_get_sync/put_sync => bus_remove_device => device_release_driver => pm_runtime_get_sync/put_sync remove_dev might call pm_runtime_get_sync/put_sync. Then, generic device_release_driver also calls pm_runtime_get_sync/put_sync. Since device_del => device_pm_remove firstly, later _get_sync wouldn't really wake up the device. I git log -p to find the patch which moves the calling to device_pm_remove ahead. It's below patch: commit 775b64d2b6ca37697de925f70799c710aab5849a Author: Rafael J. Wysocki Date: Sat Jan 12 20:40:46 2008 +0100 PM: Acquire device locks on suspend This patch reorganizes the way suspend and resume notifications are sent to drivers. The major changes are that now the PM core acquires every device semaphore before calling the methods, and calls to device_add() during suspends will fail, while calls to device_del() during suspends will block. It also provides a way to safely remove a suspended device with the help of the PM core, by using the device_pm_schedule_removal() callback introduced specifically for this purpose, and updates two drivers (msr and cpuid) that need to use it. As device_pm_schedule_removal is deleted by another patch, we need also revert other parts of the patch, i.e. move the calling of device_pm_remove after the calling to bus_remove_device. Signed-off-by: LongX Zhang Acked-by: Greg Kroah-Hartman Signed-off-by: Rafael J. Wysocki --- drivers/base/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index abea76c36a4..150a41580fa 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1180,7 +1180,6 @@ void device_del(struct device *dev) if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_DEL_DEVICE, dev); - device_pm_remove(dev); dpm_sysfs_remove(dev); if (parent) klist_del(&dev->p->knode_parent); @@ -1205,6 +1204,7 @@ void device_del(struct device *dev) device_remove_file(dev, &uevent_attr); device_remove_attrs(dev); bus_remove_device(dev); + device_pm_remove(dev); driver_deferred_probe_del(dev); /* Notify the platform of the removal, in case they -- cgit v1.2.3 From 61ca8bac45ea2fb263b3a7229e00f040df166501 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:48:03 -0700 Subject: staging: comedi: comedi_fc.h: introduce new helpers for do_cmdtest step 3 Step 3 of the do_cmdtest functions validates the arguments for the command to be executed. Most of these are simple tests to see if the argument "is" a value, a "min" value, or a "max" value. Each of these tests then clamps the argument to the value if it fails the test. Introduce three new helper functions in comedi_fc.h to handle these tests and remove the boilerplate code from the drivers. The new helper functions are: cfc_check_trigger_arg_is() - argument must be == the value cfc_check_trigger_arg_min() - argument must be >= the value cfc_check_trigger_arg_max() - argument must be <= the value All of these helpers set the argument to the value and return -EINVAL if the validation fails. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_fc.h | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h index 94481c637a0..31afab79f39 100644 --- a/drivers/staging/comedi/drivers/comedi_fc.h +++ b/drivers/staging/comedi/drivers/comedi_fc.h @@ -105,4 +105,48 @@ static inline int cfc_check_trigger_is_unique(unsigned int src) return 0; } +/** + * cfc_check_trigger_arg_is() - trivially validate a trigger argument + * @arg: pointer to the trigger arg to validate + * @val: the value the argument should be + */ +static inline int cfc_check_trigger_arg_is(unsigned int *arg, unsigned int val) +{ + if (*arg != val) { + *arg = val; + return -EINVAL; + } + return 0; +} + +/** + * cfc_check_trigger_arg_min() - trivially validate a trigger argument + * @arg: pointer to the trigger arg to validate + * @val: the minimum value the argument should be + */ +static inline int cfc_check_trigger_arg_min(unsigned int *arg, + unsigned int val) +{ + if (*arg < val) { + *arg = val; + return -EINVAL; + } + return 0; +} + +/** + * cfc_check_trigger_arg_max() - trivially validate a trigger argument + * @arg: pointer to the trigger arg to validate + * @val: the maximum value the argument should be + */ +static inline int cfc_check_trigger_arg_max(unsigned int *arg, + unsigned int val) +{ + if (*arg > val) { + *arg = val; + return -EINVAL; + } + return 0; +} + #endif /* _COMEDI_FC_H */ -- cgit v1.2.3 From 851eef809c50d79e13e44fbd2b35b58fab0d4932 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:48:23 -0700 Subject: staging: comedi: 8255: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of subdev_8255_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index a256622e2dd..c7aa41ad842 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -249,28 +249,13 @@ static int subdev_8255_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3 */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From 2404271050e9cda4243876c9e3e8ff51e1fc1c09 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:48:41 -0700 Subject: staging: comedi: comedi_parport: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of parport_intr_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_parport.c | 27 ++++++------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c index 6d3b56a70aa..76d59dcbea0 100644 --- a/drivers/staging/comedi/drivers/comedi_parport.c +++ b/drivers/staging/comedi/drivers/comedi_parport.c @@ -196,28 +196,13 @@ static int parport_intr_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From 58bed93eebeea7708f42da8f2bcb40a035004713 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:49:05 -0700 Subject: staging: comedi: addi_apci_1032: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of apci1032_cos_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 27 ++++++------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index dc285307a63..eb31375e72e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -154,28 +154,13 @@ static int apci1032_cos_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From a1d6de5a9807ae45e5fbd167c8568c0e9fca71f0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:49:22 -0700 Subject: staging: comedi: amplc_dio200: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of dio200_subdev_intr_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 34 +++++---------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index cb75a177c9a..57c618b4e98 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1020,41 +1020,19 @@ dio200_subdev_intr_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - - /* cmd->scan_begin_src == TRIG_EXT */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - - /* cmd->convert_src == TRIG_NOW */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - - /* cmd->scan_end_src == TRIG_COUNT */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); switch (cmd->stop_src) { case TRIG_COUNT: /* any count allowed */ break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; default: break; -- cgit v1.2.3 From 7efbbc37db3ced8bde7ed68b04a17fd716deb586 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:49:38 -0700 Subject: staging: comedi: amplc_pc236: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of pc236_intr_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pc236.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index ae75754dd77..d460b243f37 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -331,28 +331,13 @@ static int pc236_intr_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: */ + /* Step 3: check it arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From effa7a282e2bce17cdabc631de4c9905dc570498 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:49:55 -0700 Subject: staging: comedi: ni_6527: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of ni6527_intr_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_6527.c | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 112742ebad9..24102d1aa82 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -247,29 +247,13 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From 5f93c88fe74d554b63d30707043ee16d8f65eef3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:50:14 -0700 Subject: staging: comedi: ni_65xx: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of ni_65xx_intr_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_65xx.c | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index df7a3df83ba..8318081c89b 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -504,29 +504,13 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - - if (cmd->scan_end_arg != 1) { - cmd->scan_end_arg = 1; - err++; - } - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From c563065bb15177f88b346837331cbe77dbe43b40 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:50:32 -0700 Subject: staging: comedi: pcm_common: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of comedi_pcm_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcm_common.c | 34 +++++------------------------ 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcm_common.c b/drivers/staging/comedi/drivers/pcm_common.c index 85ee05ece9c..8a718aea6f3 100644 --- a/drivers/staging/comedi/drivers/pcm_common.c +++ b/drivers/staging/comedi/drivers/pcm_common.c @@ -29,41 +29,19 @@ int comedi_pcm_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - - /* cmd->scan_begin_src == TRIG_EXT */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - - /* cmd->convert_src == TRIG_NOW */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - - /* cmd->scan_end_src == TRIG_COUNT */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); switch (cmd->stop_src) { case TRIG_COUNT: /* any count allowed */ break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; default: break; -- cgit v1.2.3 From 50b825ffa3f3c16d273e396f8a2977d2a76da2fd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:50:51 -0700 Subject: staging: comedi: das800: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of das800_ai_do_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das800.c | 44 +++++++++++---------------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c index 85ab24c4556..38f625be812 100644 --- a/drivers/staging/comedi/drivers/das800.c +++ b/drivers/staging/comedi/drivers/das800.c @@ -622,37 +622,21 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; - err++; - } - } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + thisboard->ai_speed); + + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From df5daff81f81599cfb88471d149f26480bc08d92 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:51:13 -0700 Subject: staging: comedi: comedi_test: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of waveform_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_test.c | 63 ++++++++-------------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 1be345518b6..fb3d09323ba 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -252,55 +252,28 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->convert_src == TRIG_NOW) + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->convert_src == TRIG_NOW) { - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - } if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < nano_per_micro) { - cmd->scan_begin_arg = nano_per_micro; - err++; - } - if (cmd->convert_src == TRIG_TIMER && - cmd->scan_begin_arg < - cmd->convert_arg * cmd->chanlist_len) { - cmd->scan_begin_arg = - cmd->convert_arg * cmd->chanlist_len; - err++; - } - } - /* - * XXX these checks are generic and should go in core if not there - * already - */ - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + nano_per_micro); + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + cmd->convert_arg * cmd->chanlist_len); } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From fa567598f0294cbca84928201709fa26ecbe549a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:51:28 -0700 Subject: staging: comedi: hwdrv_apci3120: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of i_APCI3120_CommandTestAnalogInput(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 56 +++++++--------------- 1 file changed, 17 insertions(+), 39 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index 0bc4eda1f74..74065baa3c0 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -767,54 +767,32 @@ static int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->scan_begin_src == TRIG_TIMER) { /* Test Delay timing */ - if (cmd->scan_begin_arg < 100000) { - cmd->scan_begin_arg = 100000; - err++; - } - } + if (cmd->scan_begin_src == TRIG_TIMER) /* Test Delay timing */ + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 100000); if (cmd->convert_src == TRIG_TIMER) { /* Test Acquisition timing */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->convert_arg && - (cmd->convert_arg < 10000)) { - cmd->convert_arg = 10000; - err++; - } + if (cmd->convert_arg) + err |= cfc_check_trigger_arg_min( + &cmd->convert_arg, 10000); } else { - if (cmd->convert_arg < 10000) { - cmd->convert_arg = 10000; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + 10000); } } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->chanlist_len > this_board->i_AiChannelList) { - cmd->chanlist_len = this_board->i_AiChannelList; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_max(&cmd->chanlist_len, + this_board->i_AiChannelList); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From 430f87dad7b3d751846651e5928138689f0c7c83 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:51:45 -0700 Subject: staging: comedi: adl_pci9111: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of pci9111_ai_do_cmd_test(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9111.c | 59 +++++++++------------------- 1 file changed, 18 insertions(+), 41 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 45f85f64eff..570ccc676cc 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -366,52 +366,29 @@ static int pci9111_ai_do_cmd_test(struct comedi_device *dev, if (error) return 2; - /* Step 3 : make sure arguments are trivialy compatible */ + /* Step 3: check if arguments are trivially valid */ - if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) { - cmd->start_arg = 0; - error++; - } + error |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if ((cmd->convert_src == TRIG_TIMER) && - (cmd->convert_arg < PCI9111_AI_ACQUISITION_PERIOD_MIN_NS)) { - cmd->convert_arg = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS; - error++; - } - if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) { - cmd->convert_arg = 0; - error++; - } + if (cmd->convert_src == TRIG_TIMER) + error |= cfc_check_trigger_arg_min(&cmd->convert_arg, + PCI9111_AI_ACQUISITION_PERIOD_MIN_NS); + else /* TRIG_EXT */ + error |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if ((cmd->scan_begin_src == TRIG_TIMER) && - (cmd->scan_begin_arg < PCI9111_AI_ACQUISITION_PERIOD_MIN_NS)) { - cmd->scan_begin_arg = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS; - error++; - } - if ((cmd->scan_begin_src == TRIG_FOLLOW) - && (cmd->scan_begin_arg != 0)) { - cmd->scan_begin_arg = 0; - error++; - } - if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) { - cmd->scan_begin_arg = 0; - error++; - } + if (cmd->scan_begin_src == TRIG_TIMER) + error |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + PCI9111_AI_ACQUISITION_PERIOD_MIN_NS); + else /* TRIG_FOLLOW || TRIG_EXT */ + error |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - if ((cmd->scan_end_src == TRIG_COUNT) && - (cmd->scan_end_arg != cmd->chanlist_len)) { - cmd->scan_end_arg = cmd->chanlist_len; - error++; - } + error |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, + cmd->chanlist_len); - if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) { - cmd->stop_arg = 1; - error++; - } - if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) { - cmd->stop_arg = 0; - error++; - } + if (cmd->stop_src == TRIG_COUNT) + error |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + error |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (error) return 3; -- cgit v1.2.3 From 1b44331348ddda4d0194036b647bd46f436b1d08 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:52:04 -0700 Subject: staging: comedi: adl_pci9118: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of pci9118_ai_do_cmd_test(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 72 ++++++++-------------------- 1 file changed, 21 insertions(+), 51 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index 2b1d21bd324..a6b21cb61da 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -1216,19 +1216,13 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (cmd->start_src & (TRIG_NOW | TRIG_EXT)) - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT)) - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); if ((cmd->scan_begin_src == TRIG_TIMER) && (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) { @@ -1238,64 +1232,40 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev, } if (cmd->scan_begin_src == TRIG_TIMER) - if (cmd->scan_begin_arg < this_board->ai_ns_min) { - cmd->scan_begin_arg = this_board->ai_ns_min; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + this_board->ai_ns_min); if (cmd->scan_begin_src == TRIG_EXT) if (cmd->scan_begin_arg) { cmd->scan_begin_arg = 0; - err++; - if (cmd->scan_end_arg > 65535) { - cmd->scan_end_arg = 65535; - err++; - } + err |= -EINVAL; + err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg, + 65535); } if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) - if (cmd->convert_arg < this_board->ai_ns_min) { - cmd->convert_arg = this_board->ai_ns_min; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + this_board->ai_ns_min); if (cmd->convert_src == TRIG_EXT) - if (cmd->convert_arg) { - cmd->convert_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } - - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); - if (cmd->chanlist_len > this_board->n_aichanlist) { - cmd->chanlist_len = this_board->n_aichanlist; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_max(&cmd->chanlist_len, + this_board->n_aichanlist); - if (cmd->scan_end_arg < cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_end_arg, + cmd->chanlist_len); if ((cmd->scan_end_arg % cmd->chanlist_len)) { cmd->scan_end_arg = cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len); - err++; + err |= -EINVAL; } if (err) -- cgit v1.2.3 From ad23feaa1e265e5a9dbba3a4eb13b822aa2ba7c6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:52:23 -0700 Subject: staging: comedi: adv_pci1710: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of pci171x_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adv_pci1710.c | 48 ++++++++-------------------- 1 file changed, 13 insertions(+), 35 deletions(-) diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index d1f800aa2d3..bdfa9051f4f 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1066,45 +1066,23 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + this_board->ai_ns_min); + else /* TRIG_FOLLOW */ + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < this_board->ai_ns_min) { - cmd->convert_arg = this_board->ai_ns_min; - err++; - } - } else { /* TRIG_FOLLOW */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From 0427c4847ef2d9f6babbc9167687a606e7533c19 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:52:40 -0700 Subject: staging: comedi: amplc_pci224: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of pci224_ao_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 53 ++++++++------------------- 1 file changed, 16 insertions(+), 37 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index e997f6e446d..0b901d5d269 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -757,76 +757,58 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* Step 3: make sure arguments are trivially compatible. */ + /* Step 3: check if arguments are trivially valid */ switch (cmd->start_src) { case TRIG_INT: - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); break; case TRIG_EXT: /* Force to external trigger 0. */ if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) { cmd->start_arg = COMBINE(cmd->start_arg, 0, ~CR_FLAGS_MASK); - err++; + err |= -EINVAL; } /* The only flag allowed is CR_EDGE, which is ignored. */ if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) { cmd->start_arg = COMBINE(cmd->start_arg, 0, CR_FLAGS_MASK & ~CR_EDGE); - err++; + err |= -EINVAL; } break; } switch (cmd->scan_begin_src) { case TRIG_TIMER: - if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) { - cmd->scan_begin_arg = MAX_SCAN_PERIOD; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + MAX_SCAN_PERIOD); + tmp = cmd->chanlist_len * CONVERT_PERIOD; if (tmp < MIN_SCAN_PERIOD) tmp = MIN_SCAN_PERIOD; - - if (cmd->scan_begin_arg < tmp) { - cmd->scan_begin_arg = tmp; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, tmp); break; case TRIG_EXT: /* Force to external trigger 0. */ if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) { cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, ~CR_FLAGS_MASK); - err++; + err |= -EINVAL; } /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */ if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT)) != 0) { cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, - CR_FLAGS_MASK & ~(CR_EDGE - | - CR_INVERT)); - err++; + CR_FLAGS_MASK & + ~(CR_EDGE | CR_INVERT)); + err |= -EINVAL; } break; } - /* cmd->convert_src == TRIG_NOW */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - - /* cmd->scan_end_arg == TRIG_COUNT */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); switch (cmd->stop_src) { case TRIG_COUNT: @@ -837,7 +819,7 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) { cmd->stop_arg = COMBINE(cmd->stop_arg, 0, ~CR_FLAGS_MASK); - err++; + err |= -EINVAL; } /* The only flag allowed is CR_EDGE, which is ignored. */ if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) { @@ -846,10 +828,7 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, } break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; } -- cgit v1.2.3 From 670c475cf02d1fe715c61a605eadb1a8776a8c4c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:53:08 -0700 Subject: staging: comedi: amplc_pci230: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of pci230_{ao,ai}_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 120 +++++++++----------------- 1 file changed, 39 insertions(+), 81 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index ef87946e642..7cc48ec1d5f 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -999,14 +999,10 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, if (err) return 2; - /* Step 3: make sure arguments are trivially compatible. - * "invalid argument" returned by comedilib to user mode process - * if this fails. */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } #define MAX_SPEED_AO 8000 /* 8000 ns => 125 kHz */ #define MIN_SPEED_AO 4294967295u /* 4294967295ns = 4.29s */ /*- Comedi limit due to unsigned int cmd. Driver limit @@ -1015,14 +1011,10 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, switch (cmd->scan_begin_src) { case TRIG_TIMER: - if (cmd->scan_begin_arg < MAX_SPEED_AO) { - cmd->scan_begin_arg = MAX_SPEED_AO; - err++; - } - if (cmd->scan_begin_arg > MIN_SPEED_AO) { - cmd->scan_begin_arg = MIN_SPEED_AO; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED_AO); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + MIN_SPEED_AO); break; case TRIG_EXT: /* External trigger - for PCI230+ hardware version 2 onwards. */ @@ -1030,37 +1022,27 @@ static int pci230_ao_cmdtest(struct comedi_device *dev, if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) { cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, ~CR_FLAGS_MASK); - err++; + err |= -EINVAL; } /* The only flags allowed are CR_EDGE and CR_INVERT. The * CR_EDGE flag is ignored. */ if ((cmd->scan_begin_arg & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) { - cmd->scan_begin_arg = - COMBINE(cmd->scan_begin_arg, 0, - CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT)); - err++; + cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, + CR_FLAGS_MASK & + ~(CR_EDGE | CR_INVERT)); + err |= -EINVAL; } break; default: - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); break; } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_NONE) { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_NONE) + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -1618,14 +1600,10 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* Step 3: make sure arguments are trivially compatible. - * "invalid argument" returned by comedilib to user mode process - * if this fails. */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } #define MAX_SPEED_AI_SE 3200 /* PCI230 SE: 3200 ns => 312.5 kHz */ #define MAX_SPEED_AI_DIFF 8000 /* PCI230 DIFF: 8000 ns => 125 kHz */ #define MAX_SPEED_AI_PLUS 4000 /* PCI230+: 4000 ns => 250 kHz */ @@ -1656,14 +1634,10 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, max_speed_ai = MAX_SPEED_AI_PLUS; } - if (cmd->convert_arg < max_speed_ai) { - cmd->convert_arg = max_speed_ai; - err++; - } - if (cmd->convert_arg > MIN_SPEED_AI) { - cmd->convert_arg = MIN_SPEED_AI; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + max_speed_ai); + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, + MIN_SPEED_AI); } else if (cmd->convert_src == TRIG_EXT) { /* * external trigger @@ -1678,46 +1652,33 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) { cmd->convert_arg = COMBINE(cmd->convert_arg, 0, ~CR_FLAGS_MASK); - err++; + err |= -EINVAL; } /* The only flags allowed are CR_INVERT and CR_EDGE. * CR_EDGE is required. */ if ((cmd->convert_arg & (CR_FLAGS_MASK & ~CR_INVERT)) != CR_EDGE) { /* Set CR_EDGE, preserve CR_INVERT. */ - cmd->convert_arg = - COMBINE(cmd->start_arg, (CR_EDGE | 0), - CR_FLAGS_MASK & ~CR_INVERT); - err++; + cmd->convert_arg = COMBINE(cmd->start_arg, + (CR_EDGE | 0), + CR_FLAGS_MASK & + ~CR_INVERT); + err |= -EINVAL; } } else { /* Backwards compatibility with previous versions. */ /* convert_arg == 0 => trigger on -ve edge. */ /* convert_arg == 1 => trigger on +ve edge. */ - if (cmd->convert_arg > 1) { - /* Default to trigger on +ve edge. */ - cmd->convert_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 1); } } else { - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - if (cmd->stop_src == TRIG_NONE) { - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->stop_src == TRIG_NONE) + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (cmd->scan_begin_src == TRIG_EXT) { /* external "trigger" to begin each scan @@ -1726,24 +1687,21 @@ static int pci230_ai_cmdtest(struct comedi_device *dev, if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) { cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, ~CR_FLAGS_MASK); - err++; + err |= -EINVAL; } /* The only flag allowed is CR_EDGE, which is ignored. */ if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) { cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, CR_FLAGS_MASK & ~CR_EDGE); - err++; + err |= -EINVAL; } } else if (cmd->scan_begin_src == TRIG_TIMER) { /* N.B. cmd->convert_arg is also TRIG_TIMER */ if (!pci230_ai_check_scan_period(cmd)) - err++; + err |= -EINVAL; } else { - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); } if (err) -- cgit v1.2.3 From 7d4adbe4f146b3fde9ddb6273e2e4f5fd97c4391 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:53:24 -0700 Subject: staging: comedi: cb_das16_cs: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of das16cs_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_das16_cs.c | 64 +++++++++------------------- 1 file changed, 19 insertions(+), 45 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 8b091c61cbc..93731de1f2b 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -194,67 +194,41 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } #define MAX_SPEED 10000 /* in nanoseconds */ #define MIN_SPEED 1000000000 /* in nanoseconds */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } - if (cmd->scan_begin_arg > MIN_SPEED) { - cmd->scan_begin_arg = MIN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + MIN_SPEED); } else { /* external trigger */ /* should be level/edge, hi/lo specification here */ /* should specify multiple external triggers */ - if (cmd->scan_begin_arg > 9) { - cmd->scan_begin_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); } if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < MAX_SPEED) { - cmd->convert_arg = MAX_SPEED; - err++; - } - if (cmd->convert_arg > MIN_SPEED) { - cmd->convert_arg = MIN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + MAX_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, + MIN_SPEED); } else { /* external trigger */ /* see above */ - if (cmd->convert_arg > 9) { - cmd->convert_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9); } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From 00d9c8cb5f88cc4dd059511a57f25160c7af0a83 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:53:40 -0700 Subject: staging: comedi: cb_pcidas: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of cb_pcidas_{ai,ao}_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas.c | 80 ++++++++++-------------------- 1 file changed, 25 insertions(+), 55 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index e7314e5f726..9c45e85ec30 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -840,49 +840,32 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, /* External trigger, only CR_EDGE and CR_INVERT flags allowed */ if ((cmd->start_arg & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) { - cmd->start_arg &= - ~(CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT)); - err++; + cmd->start_arg &= ~(CR_FLAGS_MASK & + ~(CR_EDGE | CR_INVERT)); + err |= -EINVAL; } if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) { cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT); - err++; + err |= -EINVAL; } break; default: - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); break; } - if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < - thisboard->ai_speed * cmd->chanlist_len) { - cmd->scan_begin_arg = - thisboard->ai_speed * cmd->chanlist_len; - err++; - } - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; - err++; - } - } + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + thisboard->ai_speed * cmd->chanlist_len); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_NONE) { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + thisboard->ai_speed); + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_NONE) + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; @@ -1075,31 +1058,18 @@ static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < thisboard->ao_scan_speed) { - cmd->scan_begin_arg = thisboard->ao_scan_speed; - err++; - } - } + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + thisboard->ao_scan_speed); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_NONE) { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_NONE) + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From a48e1258b43fcd00ba0c273cd75c27003191e05e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:54:11 -0700 Subject: staging: comedi: das16: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of das16_cmd_test(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16.c | 55 +++++++++++----------------------- 1 file changed, 18 insertions(+), 37 deletions(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 2ceadcb9740..b159f44d694 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -442,46 +442,27 @@ static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - /* check against maximum frequency */ - if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < - board->ai_speed * cmd->chanlist_len) { - cmd->scan_begin_arg = - board->ai_speed * cmd->chanlist_len; - err++; - } - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < board->ai_speed) { - cmd->convert_arg = board->ai_speed; - err++; - } - } + if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + /* check against maximum frequency */ + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + board->ai_speed * cmd->chanlist_len); + + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + board->ai_speed); + + if (cmd->stop_src == TRIG_NONE) + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); - if (cmd->stop_src == TRIG_NONE) { - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } if (err) return 3; -- cgit v1.2.3 From 050b3b1830386e5c8884804b841d4e83c57cf0de Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:54:26 -0700 Subject: staging: comedi: das16m1: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of das16m1_cmd_test(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das16m1.c | 35 ++++++++------------------------ 1 file changed, 9 insertions(+), 26 deletions(-) diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index d93d95102af..b0a861a779b 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -186,40 +186,23 @@ static int das16m1_cmd_test(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < 1000) { - cmd->convert_arg = 1000; - err++; - } - } + if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 1000); + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) -- cgit v1.2.3 From 35402007dd9ad3a05350a0815aa2e1ca7dba77d5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:54:41 -0700 Subject: staging: comedi: das1800: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of das1800_ai_do_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/das1800.c | 38 +++++++++----------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 2495cd91479..7900f959555 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -824,39 +824,23 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; - err++; - } - } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + thisboard->ai_speed); + + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); switch (cmd->stop_src) { case TRIG_COUNT: - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; default: break; -- cgit v1.2.3 From e43ed5fa1435e3ae8a2a5727ea30581640f9e18d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:54:56 -0700 Subject: staging: comedi: dmm32at: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of dmm32at_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dmm32at.c | 53 +++++++++----------------------- 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c index a526c6770bb..9e2124179a0 100644 --- a/drivers/staging/comedi/drivers/dmm32at.c +++ b/drivers/staging/comedi/drivers/dmm32at.c @@ -280,33 +280,25 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } #define MAX_SCAN_SPEED 1000000 /* in nanoseconds */ #define MIN_SCAN_SPEED 1000000000 /* in nanoseconds */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SCAN_SPEED) { - cmd->scan_begin_arg = MAX_SCAN_SPEED; - err++; - } - if (cmd->scan_begin_arg > MIN_SCAN_SPEED) { - cmd->scan_begin_arg = MIN_SCAN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SCAN_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + MIN_SCAN_SPEED); } else { /* external trigger */ /* should be level/edge, hi/lo specification here */ /* should specify multiple external triggers */ - if (cmd->scan_begin_arg > 9) { - cmd->scan_begin_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); } + if (cmd->convert_src == TRIG_TIMER) { if (cmd->convert_arg >= 17500) cmd->convert_arg = 20000; @@ -316,35 +308,20 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, cmd->convert_arg = 10000; else cmd->convert_arg = 5000; - } else { /* external trigger */ /* see above */ - if (cmd->convert_arg > 9) { - cmd->convert_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9); } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0xfffffff0) { - cmd->stop_arg = 0xfffffff0; - err++; - } - if (cmd->stop_arg == 0) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0xfffffff0); + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) -- cgit v1.2.3 From 2345dc8b0c2d3759e91e300d8480c5788aea720d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:55:11 -0700 Subject: staging: comedi: dt2814: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of dt2814_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt2814.c | 42 ++++++++++----------------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c index 35cb2b55236..e520dbaaa19 100644 --- a/drivers/staging/comedi/drivers/dt2814.c +++ b/drivers/staging/comedi/drivers/dt2814.c @@ -149,36 +149,20 @@ static int dt2814_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg > 1000000000) { - cmd->scan_begin_arg = 1000000000; - err++; - } - if (cmd->scan_begin_arg < DT2814_MAX_SPEED) { - cmd->scan_begin_arg = DT2814_MAX_SPEED; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg < 2) { - cmd->stop_arg = 2; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 1000000000); + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + DT2814_MAX_SPEED); + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 2); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From 61e55b88fd19331e33fb09e6b423ac0975aaa26d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:55:27 -0700 Subject: staging: comedi: dt282x: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of dt282x_{ai,ao}_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 82 +++++++++------------------------ 1 file changed, 22 insertions(+), 60 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 9746294efc9..122d980a95a 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -611,52 +611,30 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } if (cmd->scan_begin_src == TRIG_FOLLOW) { /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); } else { /* external trigger */ /* should be level/edge, hi/lo specification here */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } - if (cmd->convert_arg < 4000) { - /* XXX board dependent */ - cmd->convert_arg = 4000; - err++; + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); } + + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 4000); + #define SLOWEST_TIMER (250*(1<<15)*255) - if (cmd->convert_arg > SLOWEST_TIMER) { - cmd->convert_arg = SLOWEST_TIMER; - err++; - } - if (cmd->convert_arg < board->ai_speed) { - cmd->convert_arg = board->ai_speed; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, SLOWEST_TIMER); + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, board->ai_speed); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + } else { /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -874,33 +852,17 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 5000); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg, 2); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->scan_begin_arg < 5000 /* XXX unknown */) { - cmd->scan_begin_arg = 5000; - err++; - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg > 2) { - /* XXX chanlist stuff? */ - cmd->scan_end_arg = 2; - err++; - } if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + } else { /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) -- cgit v1.2.3 From 39c7bba8ccaee3bec441cb3de7763b96b1b76d94 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:55:42 -0700 Subject: staging: comedi: dt3000: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of dt3k_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt3000.c | 53 ++++++++++----------------------- 1 file changed, 16 insertions(+), 37 deletions(-) diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 71c24954640..f6d4ebd6cb5 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -468,51 +468,30 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < this_board->ai_speed) { - cmd->scan_begin_arg = this_board->ai_speed; - err++; - } - if (cmd->scan_begin_arg > 100 * 16 * 65535) { - cmd->scan_begin_arg = 100 * 16 * 65535; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + this_board->ai_speed); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + 100 * 16 * 65535); } if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < this_board->ai_speed) { - cmd->convert_arg = this_board->ai_speed; - err++; - } - if (cmd->convert_arg > 50 * 16 * 65535) { - cmd->convert_arg = 50 * 16 * 65535; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + this_board->ai_speed); + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, + 50 * 16 * 65535); } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From bf1b2022ef4052953b7f8e04ee3259c061561261 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:55:56 -0700 Subject: staging: comedi: gsc_hpdi: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of di_cmd_test(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/gsc_hpdi.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 77b86820d7b..eb3cb80ff2a 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -641,29 +641,20 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (!cmd->chanlist_len) { cmd->chanlist_len = 32; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; + err |= -EINVAL; } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); switch (cmd->stop_src) { case TRIG_COUNT: - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; default: break; -- cgit v1.2.3 From 8c6c5a692d46a2f2fc589952a1f38ac1c690d3a7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:56:11 -0700 Subject: staging: comedi: gsc_hpdi: cleanup step 3 of me4000_ai_do_cmd_test() Remove the dev_err() noise and convert the error handling to the normal form (err |= -EINVAL) used in the do_cmdtest functions. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me4000.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index c85e5e5420b..a489a6548e7 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -969,28 +969,23 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, if (err) return 2; - /* - * Stage 3. Check if arguments are generally valid. - */ + /* Step 3: check if arguments are trivially valid */ + if (cmd->chanlist_len < 1) { - dev_err(dev->class_dev, "No channel list\n"); cmd->chanlist_len = 1; - err++; + err |= -EINVAL; } if (init_ticks < 66) { - dev_err(dev->class_dev, "Start arg to low\n"); cmd->start_arg = 2000; - err++; + err |= -EINVAL; } if (scan_ticks && scan_ticks < 67) { - dev_err(dev->class_dev, "Scan begin arg to low\n"); cmd->scan_begin_arg = 2031; - err++; + err |= -EINVAL; } if (chan_ticks < 66) { - dev_err(dev->class_dev, "Convert arg to low\n"); cmd->convert_arg = 2000; - err++; + err |= -EINVAL; } if (err) -- cgit v1.2.3 From dd254844f1dff6ee1b3be499b2730a4ff1d9ca51 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:56:26 -0700 Subject: staging: comedi: ni_at_a2150: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of a2150_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_at_a2150.c | 44 +++++++++------------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c index 0222def373c..06de25bb2f5 100644 --- a/drivers/staging/comedi/drivers/ni_at_a2150.c +++ b/drivers/staging/comedi/drivers/ni_at_a2150.c @@ -345,37 +345,21 @@ static int a2150_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; - err++; - } - } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + thisboard->ai_speed); + + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From ec3ffe6d423d7b05527371815f9d5530a4c895fd Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:56:41 -0700 Subject: staging: comedi: ni_atmio16d: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of atmio16d_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_atmio16d.c | 43 ++++++++-------------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index a3884b4d90c..4a17494f55e 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -271,51 +271,32 @@ static int atmio16d_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } if (cmd->scan_begin_src == TRIG_FOLLOW) { /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); } else { #if 0 /* external trigger */ /* should be level/edge, hi/lo specification here */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); #endif } - if (cmd->convert_arg < 10000) { - cmd->convert_arg = 10000; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 10000); #if 0 - if (cmd->convert_arg > SLOWEST_TIMER) { - cmd->convert_arg = SLOWEST_TIMER; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, SLOWEST_TIMER); #endif - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + } else { /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) -- cgit v1.2.3 From 88c793010bdeace47d6fc19f42bce00544280205 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:56:56 -0700 Subject: staging: comedi: ni_labpc: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of labpc_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc.c | 54 +++++++++---------------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index f4a0377486e..b56039bea6a 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -1026,56 +1026,34 @@ static int labpc_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg == TRIG_NOW && cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + if (cmd->start_arg == TRIG_NOW) + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); if (!cmd->chanlist_len) - err++; + err |= -EINVAL; + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + thisboard->ai_speed); - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; - err++; - } - } /* make sure scan timing is not too fast */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->convert_src == TRIG_TIMER && - cmd->scan_begin_arg < - cmd->convert_arg * cmd->chanlist_len) { - cmd->scan_begin_arg = - cmd->convert_arg * cmd->chanlist_len; - err++; - } - if (cmd->scan_begin_arg < - thisboard->ai_speed * cmd->chanlist_len) { - cmd->scan_begin_arg = - thisboard->ai_speed * cmd->chanlist_len; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + cmd->convert_arg * cmd->chanlist_len); + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + thisboard->ai_speed * cmd->chanlist_len); } - /* stop source */ + switch (cmd->stop_src) { case TRIG_COUNT: - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; /* * TRIG_EXT doesn't care since it doesn't -- cgit v1.2.3 From 616a14d7adfb2ee9bec6209500be6399771a2816 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:57:10 -0700 Subject: staging: comedi: ni_pcidio: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of ni_pcidio_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_pcidio.c | 36 +++++++++--------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 20e7545204b..5d442b09c67 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -715,46 +715,32 @@ static int ni_pcidio_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - /* same for both TRIG_INT and TRIG_NOW */ - cmd->start_arg = 0; - err++; - } #define MAX_SPEED (TIMER_BASE) /* in nanoseconds */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED); /* no minimum speed */ } else { /* TRIG_EXT */ /* should be level/edge, hi/lo specification here */ if ((cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) != 0) { cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT); - err++; + err |= -EINVAL; } } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_COUNT) { /* no limit */ - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + } else { /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) -- cgit v1.2.3 From aadd0132c5ac794415690b5ef95fd4da986fec78 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:57:27 -0700 Subject: staging: comedi: ni_tiocmd: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of ni_tio_cmdtest(). Note that cmd->stop_src only has one trigger source so the extra test is not required. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tiocmd.c | 40 ++++++++---------------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index 11a377a6c27..0c991b99da1 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -275,37 +275,19 @@ int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd *cmd) if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_src != TRIG_EXT) { - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - } - if (cmd->scan_begin_src != TRIG_EXT) { - if (cmd->scan_begin_arg) { - cmd->scan_begin_arg = 0; - err++; - } - } - if (cmd->convert_src != TRIG_EXT) { - if (cmd->convert_arg) { - cmd->convert_arg = 0; - err++; - } - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + if (cmd->start_src != TRIG_EXT) + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->stop_src == TRIG_NONE) { - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->scan_begin_src != TRIG_EXT) + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + + if (cmd->convert_src != TRIG_EXT) + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From d1e27594ed307e96637dc26c9c7f643ab86aff88 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:57:42 -0700 Subject: staging: comedi: pcl711: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of pcl711_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl711.c | 36 ++++++++++----------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c index f9c15aa45fe..6ee5da24a96 100644 --- a/drivers/staging/comedi/drivers/pcl711.c +++ b/drivers/staging/comedi/drivers/pcl711.c @@ -289,38 +289,24 @@ static int pcl711_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3 */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } if (cmd->scan_begin_src == TRIG_EXT) { - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); } else { #define MAX_SPEED 1000 #define TIMER_BASE 100 - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED); } + + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_NONE) { - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } else { /* ignore */ } -- cgit v1.2.3 From 4cd8672ab3dbf26a3143136625ab41b8be3841c7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:57:56 -0700 Subject: staging: comedi: pcl812: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of pcl812_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl812.c | 58 +++++++++------------------------ 1 file changed, 15 insertions(+), 43 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c index d94c9dc7832..560930e6a8e 100644 --- a/drivers/staging/comedi/drivers/pcl812.c +++ b/drivers/staging/comedi/drivers/pcl812.c @@ -565,53 +565,25 @@ static int pcl812_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + board->ai_ns_min); + else /* TRIG_EXT */ + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < board->ai_ns_min) { - cmd->convert_arg = board->ai_ns_min; - err++; - } - } else { /* TRIG_EXT */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_max(&cmd->chanlist_len, MAX_CHANLIST_LEN); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->chanlist_len > MAX_CHANLIST_LEN) { - cmd->chanlist_len = board->n_aichan; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From b93e56ade2395dd0320a262e8d4741ce1fc582e0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:58:16 -0700 Subject: staging: comedi: pcl816: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of pcl816_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl816.c | 50 ++++++++++----------------------- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c index 858600a753b..f625fdab335 100644 --- a/drivers/staging/comedi/drivers/pcl816.c +++ b/drivers/staging/comedi/drivers/pcl816.c @@ -484,43 +484,23 @@ static int pcl816_ai_cmdtest(struct comedi_device *dev, return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < board->ai_ns_min) { - cmd->convert_arg = board->ai_ns_min; - err++; - } - } else { /* TRIG_EXT */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + board->ai_ns_min); + else /* TRIG_EXT */ + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From 8efdc1bf560338b3d40f9eb9985576d35c6eeec7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:58:32 -0700 Subject: staging: comedi: pcl818: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl818.c | 48 +++++++++------------------------ 1 file changed, 13 insertions(+), 35 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index c94f289e3f3..06127a5f62a 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -1294,45 +1294,23 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + board->ns_min); + else /* TRIG_EXT */ + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < board->ns_min) { - cmd->convert_arg = board->ns_min; - err++; - } - } else { /* TRIG_EXT */ - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From 42cae4a1c030403883277aecc53a726e329f64cf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:58:47 -0700 Subject: staging: comedi: quatech_daqp_cs: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of daqp_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/quatech_daqp_cs.c | 46 ++++++++---------------- 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c index ee9158b203c..ef0cdaa7f02 100644 --- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c +++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c @@ -482,19 +482,15 @@ static int daqp_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } #define MAX_SPEED 10000 /* 100 kHz - in nanoseconds */ - if (cmd->scan_begin_src == TRIG_TIMER - && cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED); /* If both scan_begin and convert are both timer values, the only * way that can make sense is if the scan time is the number of @@ -503,30 +499,18 @@ static int daqp_ai_cmdtest(struct comedi_device *dev, if (cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER && cmd->scan_begin_arg != cmd->convert_arg * cmd->scan_end_arg) { - err++; + err |= -EINVAL; } - if (cmd->convert_src == TRIG_TIMER && cmd->convert_arg < MAX_SPEED) { - cmd->convert_arg = MAX_SPEED; - err++; - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED); - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From 8a2b08ec90c5bde08c1cacfdcfd709aeeed95826 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:59:02 -0700 Subject: staging: comedi: rtd520: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of rtd_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 72 ++++++++++++++------------------- 1 file changed, 30 insertions(+), 42 deletions(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 23b76d0b1a5..5b31e60ffb5 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -745,97 +745,85 @@ static int rtd_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); if (cmd->scan_begin_src == TRIG_TIMER) { /* Note: these are time periods, not actual rates */ if (1 == cmd->chanlist_len) { /* no scanning */ - if (cmd->scan_begin_arg < RTD_MAX_SPEED_1) { - cmd->scan_begin_arg = RTD_MAX_SPEED_1; + if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + RTD_MAX_SPEED_1)) { rtd_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_UP); - err++; + err |= -EINVAL; } - if (cmd->scan_begin_arg > RTD_MIN_SPEED_1) { - cmd->scan_begin_arg = RTD_MIN_SPEED_1; + if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + RTD_MIN_SPEED_1)) { rtd_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_DOWN); - err++; + err |= -EINVAL; } } else { - if (cmd->scan_begin_arg < RTD_MAX_SPEED) { - cmd->scan_begin_arg = RTD_MAX_SPEED; + if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + RTD_MAX_SPEED)) { rtd_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_UP); - err++; + err |= -EINVAL; } - if (cmd->scan_begin_arg > RTD_MIN_SPEED) { - cmd->scan_begin_arg = RTD_MIN_SPEED; + if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + RTD_MIN_SPEED)) { rtd_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_DOWN); - err++; + err |= -EINVAL; } } } else { /* external trigger */ /* should be level/edge, hi/lo specification here */ /* should specify multiple external triggers */ - if (cmd->scan_begin_arg > 9) { - cmd->scan_begin_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); } + if (cmd->convert_src == TRIG_TIMER) { if (1 == cmd->chanlist_len) { /* no scanning */ - if (cmd->convert_arg < RTD_MAX_SPEED_1) { - cmd->convert_arg = RTD_MAX_SPEED_1; + if (cfc_check_trigger_arg_min(&cmd->convert_arg, + RTD_MAX_SPEED_1)) { rtd_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_UP); - err++; + err |= -EINVAL; } - if (cmd->convert_arg > RTD_MIN_SPEED_1) { - cmd->convert_arg = RTD_MIN_SPEED_1; + if (cfc_check_trigger_arg_max(&cmd->convert_arg, + RTD_MIN_SPEED_1)) { rtd_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_DOWN); - err++; + err |= -EINVAL; } } else { - if (cmd->convert_arg < RTD_MAX_SPEED) { - cmd->convert_arg = RTD_MAX_SPEED; + if (cfc_check_trigger_arg_min(&cmd->convert_arg, + RTD_MAX_SPEED)) { rtd_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_UP); - err++; + err |= -EINVAL; } - if (cmd->convert_arg > RTD_MIN_SPEED) { - cmd->convert_arg = RTD_MIN_SPEED; + if (cfc_check_trigger_arg_max(&cmd->convert_arg, + RTD_MIN_SPEED)) { rtd_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_DOWN); - err++; + err |= -EINVAL; } } } else { /* external trigger */ /* see above */ - if (cmd->convert_arg > 9) { - cmd->convert_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9); } if (cmd->stop_src == TRIG_COUNT) { /* TODO check for rounding error due to counter wrap */ - } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) -- cgit v1.2.3 From 53a254b92cad920941cf8225dbe805bf9b57ca11 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:59:18 -0700 Subject: staging: comedi: s626: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of s626_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 78 ++++++++++------------------------- 1 file changed, 22 insertions(+), 56 deletions(-) diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 686ee0e8713..e32b54f4bfc 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1549,80 +1549,46 @@ static int s626_ai_cmdtest(struct comedi_device *dev, /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_src != TRIG_EXT && cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + if (cmd->start_src != TRIG_EXT) + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + if (cmd->start_src == TRIG_EXT) + err |= cfc_check_trigger_arg_max(&cmd->start_arg, 39); - if (cmd->start_src == TRIG_EXT && cmd->start_arg > 39) { - cmd->start_arg = 39; - err++; - } + if (cmd->scan_begin_src == TRIG_EXT) + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 39); - if (cmd->scan_begin_src == TRIG_EXT && cmd->scan_begin_arg > 39) { - cmd->scan_begin_arg = 39; - err++; - } + if (cmd->convert_src == TRIG_EXT) + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 39); - if (cmd->convert_src == TRIG_EXT && cmd->convert_arg > 39) { - cmd->convert_arg = 39; - err++; - } #define MAX_SPEED 200000 /* in nanoseconds */ #define MIN_SPEED 2000000000 /* in nanoseconds */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } - if (cmd->scan_begin_arg > MIN_SPEED) { - cmd->scan_begin_arg = MIN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + MIN_SPEED); } else { /* external trigger */ /* should be level/edge, hi/lo specification here */ /* should specify multiple external triggers */ -/* if(cmd->scan_begin_arg>9){ */ -/* cmd->scan_begin_arg=9; */ -/* err++; */ -/* } */ +/* err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */ } if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < MAX_SPEED) { - cmd->convert_arg = MAX_SPEED; - err++; - } - if (cmd->convert_arg > MIN_SPEED) { - cmd->convert_arg = MIN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, MIN_SPEED); } else { /* external trigger */ /* see above */ -/* if(cmd->convert_arg>9){ */ -/* cmd->convert_arg=9; */ -/* err++; */ -/* } */ +/* err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); */ } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From 0cd0b8fde1ec3fa31e37ab6c83cc53f7d87d1f1d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:59:32 -0700 Subject: staging: comedi: skel: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of skel_ai_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/skel.c | 63 ++++++++++------------------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 162bf266f76..deb0bfaf0a3 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -233,67 +233,40 @@ static int skel_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } #define MAX_SPEED 10000 /* in nanoseconds */ #define MIN_SPEED 1000000000 /* in nanoseconds */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < MAX_SPEED) { - cmd->scan_begin_arg = MAX_SPEED; - err++; - } - if (cmd->scan_begin_arg > MIN_SPEED) { - cmd->scan_begin_arg = MIN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + MAX_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + MIN_SPEED); } else { /* external trigger */ /* should be level/edge, hi/lo specification here */ /* should specify multiple external triggers */ - if (cmd->scan_begin_arg > 9) { - cmd->scan_begin_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); } + if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < MAX_SPEED) { - cmd->convert_arg = MAX_SPEED; - err++; - } - if (cmd->convert_arg > MIN_SPEED) { - cmd->convert_arg = MIN_SPEED; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED); + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, MIN_SPEED); } else { /* external trigger */ /* see above */ - if (cmd->convert_arg > 9) { - cmd->convert_arg = 9; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9); } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From f4d36c7a424647aa07a1bb5facd226cdf2f03151 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 17:59:48 -0700 Subject: staging: comedi: usbdux: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of usbdux_{ai,ao}_cmdtest(). Also, remove some dev_dbg() noise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 108 ++++++++------------------------ 1 file changed, 26 insertions(+), 82 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 9629b4f469c..78f3a2e013c 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -938,9 +938,6 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, if (!(this_usbduxsub->probed)) return -ENODEV; - dev_dbg(&this_usbduxsub->interface->dev, - "comedi%d: usbdux_ai_cmdtest\n", dev->minor); - /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); @@ -962,19 +959,12 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); if (cmd->scan_begin_src == TRIG_TIMER) { if (this_usbduxsub->high_speed) { @@ -989,51 +979,35 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, while (i < (cmd->chanlist_len)) i = i * 2; - if (cmd->scan_begin_arg < (1000000 / 8 * i)) { - cmd->scan_begin_arg = 1000000 / 8 * i; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + 1000000 / 8 * i); /* now calc the real sampling rate with all the * rounding errors */ tmpTimer = ((unsigned int)(cmd->scan_begin_arg / 125000)) * 125000; - if (cmd->scan_begin_arg != tmpTimer) { - cmd->scan_begin_arg = tmpTimer; - err++; - } } else { /* full speed */ /* 1kHz scans every USB frame */ - if (cmd->scan_begin_arg < 1000000) { - cmd->scan_begin_arg = 1000000; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + 1000000); /* * calc the real sampling rate with the rounding errors */ tmpTimer = ((unsigned int)(cmd->scan_begin_arg / 1000000)) * 1000000; - if (cmd->scan_begin_arg != tmpTimer) { - cmd->scan_begin_arg = tmpTimer; - err++; - } } - } - /* the same argument */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, + tmpTimer); } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -1472,9 +1446,6 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev, if (!(this_usbduxsub->probed)) return -ENODEV; - dev_dbg(&this_usbduxsub->interface->dev, - "comedi%d: usbdux_ao_cmdtest\n", dev->minor); - /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); @@ -1519,57 +1490,30 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } + if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + 1000000); - if (cmd->scan_begin_src == TRIG_TIMER) { - /* timer */ - if (cmd->scan_begin_arg < 1000000) { - cmd->scan_begin_arg = 1000000; - err++; - } - } /* not used now, is for later use */ - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < 125000) { - cmd->convert_arg = 125000; - err++; - } - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000); - /* the same argument */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } - dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: err=%d, " - "scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, " - "convert_arg=%d\n", dev->minor, err, cmd->scan_begin_src, - cmd->scan_begin_arg, cmd->convert_src, cmd->convert_arg); - if (err) return 3; -- cgit v1.2.3 From 9309c4772e9bbe6e9c27d96c333ecb2755d725fe Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 18:00:06 -0700 Subject: staging: comedi: usbduxfast: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of usbduxfast_ai_cmdtest(). Also, remove some debug noise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 38 +++++++---------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 5adc3b31a27..4e19f6186f2 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -555,12 +555,6 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev, if (!udfs->probed) return -ENODEV; -#ifdef CONFIG_COMEDI_DEBUG - printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmdtest\n", dev->minor); - printk(KERN_DEBUG "comedi%d: usbduxfast: convert_arg=%u " - "scan_begin_arg=%u\n", - dev->minor, cmd->convert_arg, cmd->scan_begin_arg); -#endif /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, @@ -590,20 +584,15 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_src == TRIG_NOW && cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + if (cmd->start_src == TRIG_NOW) + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); if (!cmd->chanlist_len) - err++; + err |= -EINVAL; - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (cmd->chanlist_len == 1) minSamplPer = 1; @@ -620,28 +609,19 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev, /* calc arg again */ tmp = steps / 30; - if (cmd->convert_arg != tmp) { - cmd->convert_arg = tmp; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, tmp); } if (cmd->scan_begin_src == TRIG_TIMER) - err++; + err |= -EINVAL; /* stop source */ switch (cmd->stop_src) { case TRIG_COUNT: - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; /* * TRIG_EXT doesn't care since it doesn't trigger -- cgit v1.2.3 From 7ec265905acdc6b24ce3b604a99dec690c7ab46a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 18:00:21 -0700 Subject: staging: comedi: usbduxsigma: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of usbdux_{ai,ao}_cmdtest(). Also, remove some debug noise. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxsigma.c | 105 +++++++-------------------- 1 file changed, 26 insertions(+), 79 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 972017069e5..cdd279b1f61 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -904,9 +904,6 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, if (!(this_usbduxsub->probed)) return -ENODEV; - dev_dbg(&this_usbduxsub->interface->dev, - "comedi%d: usbdux_ai_cmdtest\n", dev->minor); - /* Step 1 : check if triggers are trivially valid */ err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); @@ -928,19 +925,12 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + + if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); if (cmd->scan_begin_src == TRIG_TIMER) { if (this_usbduxsub->high_speed) { @@ -951,51 +941,35 @@ static int usbdux_ai_cmdtest(struct comedi_device *dev, * are in the channel list the more time we need. */ i = chanToInterval(cmd->chanlist_len); - if (cmd->scan_begin_arg < (1000000 / 8 * i)) { - cmd->scan_begin_arg = 1000000 / 8 * i; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + (1000000 / 8 * i)); /* now calc the real sampling rate with all the * rounding errors */ tmpTimer = ((unsigned int)(cmd->scan_begin_arg / 125000)) * 125000; - if (cmd->scan_begin_arg != tmpTimer) { - cmd->scan_begin_arg = tmpTimer; - err++; - } } else { /* full speed */ /* 1kHz scans every USB frame */ - if (cmd->scan_begin_arg < 1000000) { - cmd->scan_begin_arg = 1000000; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + 1000000); /* * calc the real sampling rate with the rounding errors */ tmpTimer = ((unsigned int)(cmd->scan_begin_arg / 1000000)) * 1000000; - if (cmd->scan_begin_arg != tmpTimer) { - cmd->scan_begin_arg = tmpTimer; - err++; - } } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, + tmpTimer); } - /* the same argument */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -1576,57 +1550,30 @@ static int usbdux_ao_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->scan_begin_src == TRIG_FOLLOW) { - /* internal trigger */ - if (cmd->scan_begin_arg != 0) { - cmd->scan_begin_arg = 0; - err++; - } - } + if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + 1000000); - if (cmd->scan_begin_src == TRIG_TIMER) { - /* timer */ - if (cmd->scan_begin_arg < 1000000) { - cmd->scan_begin_arg = 1000000; - err++; - } - } /* not used now, is for later use */ - if (cmd->convert_src == TRIG_TIMER) { - if (cmd->convert_arg < 125000) { - cmd->convert_arg = 125000; - err++; - } - } + if (cmd->convert_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 125000); - /* the same argument */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (cmd->stop_src == TRIG_COUNT) { /* any count is allowed */ } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } - dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: err=%d, " - "scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, " - "convert_arg=%d\n", dev->minor, err, cmd->scan_begin_src, - cmd->scan_begin_arg, cmd->convert_src, cmd->convert_arg); - if (err) return 3; -- cgit v1.2.3 From c3be5c7f1e124a415453c45508c95bff3a6b2308 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 13 Nov 2012 18:00:36 -0700 Subject: staging: comedi: ni_mio_common: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of ni_{ai,ao,cdio}_cmdtest(). Note that all the command triggers in ni_cdio_cmdtest are single source so the extra tests are not required. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_mio_common.c | 186 +++++++------------------ 1 file changed, 51 insertions(+), 135 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 743a9016e07..56dc59908d3 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -2256,7 +2256,7 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (cmd->start_src == TRIG_EXT) { /* external trigger */ @@ -2265,30 +2265,17 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (tmp > 16) tmp = 16; tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE)); - if (cmd->start_arg != tmp) { - cmd->start_arg = tmp; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, tmp); } else { - if (cmd->start_arg != 0) { - /* true for both TRIG_NOW and TRIG_INT */ - cmd->start_arg = 0; - err++; - } + /* true for both TRIG_NOW and TRIG_INT */ + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); } + if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < ni_min_ai_scan_period_ns(dev, - cmd-> - chanlist_len)) - { - cmd->scan_begin_arg = - ni_min_ai_scan_period_ns(dev, cmd->chanlist_len); - err++; - } - if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) { - cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + ni_min_ai_scan_period_ns(dev, cmd->chanlist_len)); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + devpriv->clock_ns * 0xffffff); } else if (cmd->scan_begin_src == TRIG_EXT) { /* external trigger */ unsigned int tmp = CR_CHAN(cmd->scan_begin_arg); @@ -2296,32 +2283,20 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (tmp > 16) tmp = 16; tmp |= (cmd->scan_begin_arg & (CR_INVERT | CR_EDGE)); - if (cmd->scan_begin_arg != tmp) { - cmd->scan_begin_arg = tmp; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, tmp); } else { /* TRIG_OTHER */ - if (cmd->scan_begin_arg) { - cmd->scan_begin_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); } + if (cmd->convert_src == TRIG_TIMER) { if ((boardtype.reg_type == ni_reg_611x) || (boardtype.reg_type == ni_reg_6143)) { - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); } else { - if (cmd->convert_arg < boardtype.ai_speed) { - cmd->convert_arg = boardtype.ai_speed; - err++; - } - if (cmd->convert_arg > devpriv->clock_ns * 0xffff) { - cmd->convert_arg = devpriv->clock_ns * 0xffff; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + boardtype.ai_speed); + err |= cfc_check_trigger_arg_max(&cmd->convert_arg, + devpriv->clock_ns * 0xffff); } } else if (cmd->convert_src == TRIG_EXT) { /* external trigger */ @@ -2330,40 +2305,23 @@ static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (tmp > 16) tmp = 16; tmp |= (cmd->convert_arg & (CR_ALT_FILTER | CR_INVERT)); - if (cmd->convert_arg != tmp) { - cmd->convert_arg = tmp; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, tmp); } else if (cmd->convert_src == TRIG_NOW) { - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + if (cmd->stop_src == TRIG_COUNT) { unsigned int max_count = 0x01000000; if (boardtype.reg_type == ni_reg_611x) max_count -= num_adc_stages_611x; - if (cmd->stop_arg > max_count) { - cmd->stop_arg = max_count; - err++; - } - if (cmd->stop_arg < 1) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, max_count); + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); } else { /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); } if (err) @@ -3432,7 +3390,7 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (cmd->start_src == TRIG_EXT) { /* external trigger */ @@ -3441,48 +3399,27 @@ static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (tmp > 18) tmp = 18; tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE)); - if (cmd->start_arg != tmp) { - cmd->start_arg = tmp; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, tmp); } else { - if (cmd->start_arg != 0) { - /* true for both TRIG_NOW and TRIG_INT */ - cmd->start_arg = 0; - err++; - } + /* true for both TRIG_NOW and TRIG_INT */ + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); } + if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < boardtype.ao_speed) { - cmd->scan_begin_arg = boardtype.ao_speed; - err++; - } - if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) { /* XXX check */ - cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff; - err++; - } - } - if (cmd->convert_arg != 0) { - cmd->convert_arg = 0; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } - if (cmd->stop_src == TRIG_COUNT) { /* XXX check */ - if (cmd->stop_arg > 0x00ffffff) { - cmd->stop_arg = 0x00ffffff; - err++; - } - } else { - /* TRIG_NONE */ - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + boardtype.ao_speed); + err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, + devpriv->clock_ns * 0xffffff); } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); + if (err) return 3; @@ -3706,39 +3643,18 @@ static int ni_cdio_cmdtest(struct comedi_device *dev, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ - if (cmd->start_src == TRIG_INT) { - if (cmd->start_arg != 0) { - cmd->start_arg = 0; - err++; - } - } - if (cmd->scan_begin_src == TRIG_EXT) { - tmp = cmd->scan_begin_arg; - tmp &= CR_PACK_FLAGS(CDO_Sample_Source_Select_Mask, 0, 0, - CR_INVERT); - if (tmp != cmd->scan_begin_arg) { - err++; - } - } - if (cmd->convert_src == TRIG_NOW) { - if (cmd->convert_arg) { - cmd->convert_arg = 0; - err++; - } - } + /* Step 3: check if arguments are trivially valid */ - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); - if (cmd->stop_src == TRIG_NONE) { - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } - } + tmp = cmd->scan_begin_arg; + tmp &= CR_PACK_FLAGS(CDO_Sample_Source_Select_Mask, 0, 0, CR_INVERT); + if (tmp != cmd->scan_begin_arg) + err |= -EINVAL; + + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); if (err) return 3; -- cgit v1.2.3 From 33cdce6293dcc0b10dcaa8bb5e6fdc8e56b5968f Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 14 Nov 2012 11:22:56 +0000 Subject: staging: comedi: addi_apci_1032: conform to new INSN_CONFIG_DIGITAL_TRIG Conform to the new definition of the `INSN_CONFIG_DIGITAL_TRIG` configuration instruction. Return an error if the 'trigger number' in `data[1]` is non-zero or if the configuration operation in `data[2]` is not supported. Deal with the 'left-shift' amount in `data[3]`. The trigger's input channels can only be configured as a set of rising and falling edges ('OR' mode) or as a set of high and low levels ('AND' mode). Preserve the old input channels to the right of the 'left-shift' value except when switching modes. (The 'left-shift' support is a bit of an overkill for this driver since the trigger only has 16 input channels.) Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi_apci_1032.c | 70 ++++++++++++++++++++----- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index eb31375e72e..0f47113ee0b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -86,10 +86,14 @@ static int apci1032_reset(struct comedi_device *dev) * The COS interrupt must be configured before it can be enabled. * * data[0] : INSN_CONFIG_DIGITAL_TRIG - * data[1] : 0 = OR (edge) interrupts - * 1 = AND (level) interrupts - * data[2] : rising-edge/high level channels - * data[3] : falling-edge/low level channels + * data[1] : trigger number (= 0) + * data[2] : configuration operation: + * COMEDI_DIGITAL_TRIG_DISABLE = no interrupts + * COMEDI_DIGITAL_TRIG_ENABLE_EDGES = OR (edge) interrupts + * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = AND (level) interrupts + * data[3] : left-shift for data[4] and data[5] + * data[4] : rising-edge/high level channels + * data[5] : falling-edge/low level channels */ static int apci1032_cos_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, @@ -97,21 +101,59 @@ static int apci1032_cos_insn_config(struct comedi_device *dev, unsigned int *data) { struct apci1032_private *devpriv = dev->private; + unsigned int shift, oldmask; switch (data[0]) { case INSN_CONFIG_DIGITAL_TRIG: - devpriv->mode1 = data[2]; - devpriv->mode2 = data[3]; - - if (devpriv->mode1 || devpriv->mode2) { - devpriv->ctrl = APCI1032_CTRL_INT_ENA; - if (data[1] == 1) - devpriv->ctrl = APCI1032_CTRL_INT_AND; - else - devpriv->ctrl = APCI1032_CTRL_INT_OR; - } else { + if (data[1] != 0) + return -EINVAL; + shift = data[3]; + oldmask = (1U << shift) - 1; + switch (data[2]) { + case COMEDI_DIGITAL_TRIG_DISABLE: devpriv->ctrl = 0; + devpriv->mode1 = 0; + devpriv->mode2 = 0; apci1032_reset(dev); + break; + case COMEDI_DIGITAL_TRIG_ENABLE_EDGES: + if (devpriv->ctrl != (APCI1032_CTRL_INT_ENA | + APCI1032_CTRL_INT_OR)) { + /* switching to 'OR' mode */ + devpriv->ctrl = APCI1032_CTRL_INT_ENA | + APCI1032_CTRL_INT_OR; + /* wipe old channels */ + devpriv->mode1 = 0; + devpriv->mode2 = 0; + } else { + /* preserve unspecified channels */ + devpriv->mode1 &= oldmask; + devpriv->mode2 &= oldmask; + } + /* configure specified channels */ + devpriv->mode1 |= data[4] << shift; + devpriv->mode2 |= data[5] << shift; + break; + case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS: + if (devpriv->ctrl != (APCI1032_CTRL_INT_ENA | + APCI1032_CTRL_INT_AND)) { + /* switching to 'AND' mode */ + devpriv->ctrl = APCI1032_CTRL_INT_ENA | + APCI1032_CTRL_INT_AND; + /* wipe old channels */ + devpriv->mode1 = 0; + devpriv->mode2 = 0; + } else { + /* preserve unspecified channels */ + devpriv->mode1 &= oldmask; + devpriv->mode2 &= oldmask; + } + /* configure specified channels */ + devpriv->mode1 |= data[4] << shift; + devpriv->mode2 |= data[5] << shift; + break; + default: + return -EINVAL; } break; default: -- cgit v1.2.3 From b0a2b6d8ac9ce5d27c9086a196d8f44194561979 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 14 Nov 2012 11:22:57 +0000 Subject: staging: comedi: check data length for INSN_CONFIG_DIGITAL_TRIG The newly defined format for the `INSN_CONFIG_DIGITAL_TRIG` configuration instruction expects 6 data values. Check the length in `check_insn_config_length()` before calling the comedi subdevice's `insn_config` handler. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index c2a32cf95a8..06906f6f7f4 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -880,6 +880,10 @@ static int check_insn_config_length(struct comedi_insn *insn, if (insn->n == 5) return 0; break; + case INSN_CONFIG_DIGITAL_TRIG: + if (insn->n == 6) + return 0; + break; /* by default we allow the insn since we don't have checks for * all possible cases yet */ default: -- cgit v1.2.3 From 206cb10816d3b1ee38761b387106973df52c4315 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 14 Nov 2012 11:22:55 +0000 Subject: staging: comedi: define operations for INSN_CONFIG_DIGITAL_TRIG The 'addi_apci_1032' driver recently started supporting the `INSN_CONFIG_DIGITAL_TRIG` configuration instruction, but as no other drivers were using it before, there was no existing practice of how the instruction should look. Define the format to be something a bit more configurable. In particular, a subdevice might have more than one trigger requiring an ID and/or `COMEDI_EV_...` flags to disambiguate them, a trigger might have more than 32 inputs, and a trigger might need several `INSN_CONFIG_DIGITAL_TRIG` configuration instructions to configure completely (if there are more than 32 inputs or if it uses a combination of edge-triggered and level-triggered inputs). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h index 3cbd2cda1f7..c8a8ca12612 100644 --- a/drivers/staging/comedi/comedi.h +++ b/drivers/staging/comedi/comedi.h @@ -283,6 +283,44 @@ enum configuration_ids { INSN_CONFIG_PWM_GET_H_BRIDGE = 5004 }; +/* + * Settings for INSN_CONFIG_DIGITAL_TRIG: + * data[0] = INSN_CONFIG_DIGITAL_TRIG + * data[1] = trigger ID + * data[2] = configuration operation + * data[3] = configuration parameter 1 + * data[4] = configuration parameter 2 + * data[5] = configuration parameter 3 + * + * operation parameter 1 parameter 2 parameter 3 + * --------------------------------- ----------- ----------- ----------- + * COMEDI_DIGITAL_TRIG_DISABLE + * COMEDI_DIGITAL_TRIG_ENABLE_EDGES left-shift rising-edges falling-edges + * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS left-shift high-levels low-levels + * + * COMEDI_DIGITAL_TRIG_DISABLE returns the trigger to its default, inactive, + * unconfigured state. + * + * COMEDI_DIGITAL_TRIG_ENABLE_EDGES sets the rising and/or falling edge inputs + * that each can fire the trigger. + * + * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS sets a combination of high and/or low + * level inputs that can fire the trigger. + * + * "left-shift" is useful if the trigger has more than 32 inputs to specify the + * first input for this configuration. + * + * Some sequences of INSN_CONFIG_DIGITAL_TRIG instructions may have a (partly) + * accumulative effect, depending on the low-level driver. This is useful + * when setting up a trigger that has more than 32 inputs or has a combination + * of edge and level triggered inputs. + */ +enum comedi_digital_trig_op { + COMEDI_DIGITAL_TRIG_DISABLE = 0, + COMEDI_DIGITAL_TRIG_ENABLE_EDGES = 1, + COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = 2 +}; + enum comedi_io_direction { COMEDI_INPUT = 0, COMEDI_OUTPUT = 1, -- cgit v1.2.3 From 847d74a26010e9bae51299b7c1008c5ec9a349f4 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 14 Nov 2012 13:10:34 +0000 Subject: staging: comedi: remove old auto-config All the Comedi drivers that call `comedi_pci_auto_config()` or `comedi_usb_auto_config()` define a `auto_attach()` handler in their `struct comedi_driver`. There is no need to fall back to abusing the `attach()` handler any more, so remove the code that supports that. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 67 ++-------------------------------------- 1 file changed, 2 insertions(+), 65 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index adae25643b1..d8c3cd32f45 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -879,49 +879,6 @@ comedi_auto_config_helper(struct device *hardware_device, return ret; } -static int comedi_old_auto_config_wrapper(struct comedi_device *dev, - unsigned long context) -{ - struct comedi_devconfig *it = (struct comedi_devconfig *)context; - struct comedi_driver *driv = dev->driver; - - if (driv->num_names) { - /* look for generic board entry matching driver name, which - * has already been copied to it->board_name */ - dev->board_ptr = comedi_recognize(driv, it->board_name); - if (dev->board_ptr == NULL) { - dev_warn(dev->class_dev, - "auto config failed to find board entry '%s' for driver '%s'\n", - it->board_name, driv->driver_name); - comedi_report_boards(driv); - return -EINVAL; - } - } - if (!driv->attach) { - dev_warn(dev->class_dev, - "BUG! driver '%s' using old-style auto config but has no attach handler\n", - driv->driver_name); - return -EINVAL; - } - return driv->attach(dev, it); -} - -static int comedi_old_auto_config(struct device *hardware_device, - struct comedi_driver *driver, - const int *options, unsigned num_options) -{ - struct comedi_devconfig it; - - memset(&it, 0, sizeof(it)); - strncpy(it.board_name, driver->driver_name, COMEDI_NAMELEN); - it.board_name[COMEDI_NAMELEN - 1] = '\0'; - BUG_ON(num_options > COMEDI_NDEVCONFOPTS); - memcpy(it.options, options, num_options * sizeof(int)); - return comedi_auto_config_helper(hardware_device, driver, - comedi_old_auto_config_wrapper, - (unsigned long)&it); -} - static int comedi_auto_config_wrapper(struct comedi_device *dev, unsigned long context) { @@ -990,20 +947,6 @@ void comedi_pci_disable(struct pci_dev *pdev) } EXPORT_SYMBOL_GPL(comedi_pci_disable); -static int comedi_old_pci_auto_config(struct pci_dev *pcidev, - struct comedi_driver *driver) -{ - int options[2]; - - /* pci bus */ - options[0] = pcidev->bus->number; - /* pci slot */ - options[1] = PCI_SLOT(pcidev->devfn); - - return comedi_old_auto_config(&pcidev->dev, driver, - options, ARRAY_SIZE(options)); -} - static int comedi_pci_attach_wrapper(struct comedi_device *dev, unsigned long context) { @@ -1026,7 +969,7 @@ int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) else if (driver->auto_attach) return comedi_auto_config(&pcidev->dev, driver, 0); else - return comedi_old_pci_auto_config(pcidev, driver); + return -EINVAL; } EXPORT_SYMBOL_GPL(comedi_pci_auto_config); @@ -1069,12 +1012,6 @@ EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); #if IS_ENABLED(CONFIG_USB) -static int comedi_old_usb_auto_config(struct usb_interface *intf, - struct comedi_driver *driver) -{ - return comedi_old_auto_config(&intf->dev, driver, NULL, 0); -} - static int comedi_usb_attach_wrapper(struct comedi_device *dev, unsigned long context) { @@ -1098,7 +1035,7 @@ int comedi_usb_auto_config(struct usb_interface *intf, else if (driver->auto_attach) return comedi_auto_config(&intf->dev, driver, 0); else - return comedi_old_usb_auto_config(intf, driver); + return -EINVAL; } EXPORT_SYMBOL_GPL(comedi_usb_auto_config); -- cgit v1.2.3 From a692e9743a7b2085afbca2f7e50a449c3e205cc0 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 14 Nov 2012 13:10:35 +0000 Subject: staging: comedi: don't call attach_pci handler All the Comedi drivers that call `comedi_pci_auto_config()` have replaced the `attach_pci()` handler in their `struct comedi_driver` with a `auto_attach()` handler, so there is no need to check for the existence of the `attach_pci()` handler any more. Remove this check and the code that calls it. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index d8c3cd32f45..f780d38d6da 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -947,26 +947,10 @@ void comedi_pci_disable(struct pci_dev *pdev) } EXPORT_SYMBOL_GPL(comedi_pci_disable); -static int comedi_pci_attach_wrapper(struct comedi_device *dev, - unsigned long context) -{ - return dev->driver->attach_pci(dev, (struct pci_dev *)context); -} - -static int comedi_new_pci_auto_config(struct pci_dev *pcidev, - struct comedi_driver *driver) -{ - return comedi_auto_config_helper(&pcidev->dev, driver, - comedi_pci_attach_wrapper, - (unsigned long)pcidev); -} - int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) { - if (driver->attach_pci) - return comedi_new_pci_auto_config(pcidev, driver); - else if (driver->auto_attach) + if (driver->auto_attach) return comedi_auto_config(&pcidev->dev, driver, 0); else return -EINVAL; -- cgit v1.2.3 From 45d6f1965e9a8b830dd69b98cf8d45de53394ee5 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 14 Nov 2012 13:10:36 +0000 Subject: staging: comedi: don't call attach_usb handler All the Comedi drivers that call `comedi_usb_auto_config()` have replaced the `attach_usb()` handler in their `struct comedi_driver` with a `auto_attach()` handler, so there is no need to check for the existence of the `attach_usb()` handler any more. Remove this check and the code that calls it. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index f780d38d6da..047c1d911c8 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -996,27 +996,11 @@ EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); #if IS_ENABLED(CONFIG_USB) -static int comedi_usb_attach_wrapper(struct comedi_device *dev, - unsigned long context) -{ - return dev->driver->attach_usb(dev, (struct usb_interface *)context); -} - -static int comedi_new_usb_auto_config(struct usb_interface *intf, - struct comedi_driver *driver) -{ - return comedi_auto_config_helper(&intf->dev, driver, - comedi_usb_attach_wrapper, - (unsigned long)intf); -} - int comedi_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { BUG_ON(intf == NULL); - if (driver->attach_usb) - return comedi_new_usb_auto_config(intf, driver); - else if (driver->auto_attach) + if (driver->auto_attach) return comedi_auto_config(&intf->dev, driver, 0); else return -EINVAL; -- cgit v1.2.3 From af448aca8fa41789aec8a968a56ed0868c803a2b Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 14 Nov 2012 13:10:37 +0000 Subject: staging: comedi: don't check driver->auto_attach There is no need for `comedi_pci_auto_config()` and `comedi_usb_auto_config()` to check that `driver->auto_attach` is non-null before calling `comedi_auto_attach()` as this check is done by `comedi_auto_config()` itself (actually by `comedi_auto_config_wrapper()`). Remove the unnecessary checks. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 047c1d911c8..d27425eb977 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -949,11 +949,7 @@ EXPORT_SYMBOL_GPL(comedi_pci_disable); int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) { - - if (driver->auto_attach) - return comedi_auto_config(&pcidev->dev, driver, 0); - else - return -EINVAL; + return comedi_auto_config(&pcidev->dev, driver, 0); } EXPORT_SYMBOL_GPL(comedi_pci_auto_config); @@ -1000,10 +996,7 @@ int comedi_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { BUG_ON(intf == NULL); - if (driver->auto_attach) - return comedi_auto_config(&intf->dev, driver, 0); - else - return -EINVAL; + return comedi_auto_config(&intf->dev, driver, 0); } EXPORT_SYMBOL_GPL(comedi_usb_auto_config); -- cgit v1.2.3 From a588da1d5aac72801df0c83075225a6074c81ac5 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 14 Nov 2012 13:10:38 +0000 Subject: staging: comedi: simplify comedi_auto_attach() `comedi_auto_config()` just calls internal function `comedi_auto_config_helper()`, passing it a wrapper function `comedi_auto_config_wrapper()` to handle the specifics of checking and calling the low-level comedi driver's `auto_attach()` handler. Since there are no other callers of `comedi_auto_config_helper()` or `comedi_auto_config_wrapper()`, combine everything into the single exported function `comedi_auto_config()`. Change the ordering of the check for existence of the low-level comedi driver's `auto_attach()` handler and the allocation of the comedi minor device number. This means the log message warning of the absence of the handler now has to be refer to the hardware device instead of the not-yet-allocated comedi device. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index d27425eb977..8de9a24d9ad 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -833,12 +833,8 @@ void comedi_reset_async_buf(struct comedi_async *async) async->events = 0; } -static int -comedi_auto_config_helper(struct device *hardware_device, - struct comedi_driver *driver, - int (*attach_wrapper) (struct comedi_device *, - unsigned long), - unsigned long context) +int comedi_auto_config(struct device *hardware_device, + struct comedi_driver *driver, unsigned long context) { int minor; struct comedi_device_file_info *dev_file_info; @@ -848,6 +844,13 @@ comedi_auto_config_helper(struct device *hardware_device, if (!comedi_autoconfig) return 0; + if (!driver->auto_attach) { + dev_warn(hardware_device, + "BUG! comedi driver '%s' has no auto_attach handler\n", + driver->driver_name); + return -EINVAL; + } + minor = comedi_alloc_board_minor(hardware_device); if (minor < 0) return minor; @@ -862,9 +865,8 @@ comedi_auto_config_helper(struct device *hardware_device, ret = -EIO; else { comedi_set_hw_dev(comedi_dev, hardware_device); - /* set comedi_dev->driver here for attach wrapper */ comedi_dev->driver = driver; - ret = (*attach_wrapper)(comedi_dev, context); + ret = driver->auto_attach(comedi_dev, context); if (ret < 0) { module_put(driver->module); __comedi_device_detach(comedi_dev); @@ -878,25 +880,6 @@ comedi_auto_config_helper(struct device *hardware_device, comedi_free_board_minor(minor); return ret; } - -static int comedi_auto_config_wrapper(struct comedi_device *dev, - unsigned long context) -{ - if (!dev->driver->auto_attach) { - dev_warn(dev->class_dev, - "BUG! driver '%s' has no auto_attach handler\n", - dev->driver->driver_name); - return -EINVAL; - } - return dev->driver->auto_attach(dev, context); -} - -int comedi_auto_config(struct device *hardware_device, - struct comedi_driver *driver, unsigned long context) -{ - return comedi_auto_config_helper(hardware_device, driver, - comedi_auto_config_wrapper, context); -} EXPORT_SYMBOL_GPL(comedi_auto_config); void comedi_auto_unconfig(struct device *hardware_device) -- cgit v1.2.3 From ddbd029903d29ec9a5aceb82d4b0c4a7468d1984 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 14 Nov 2012 13:10:39 +0000 Subject: staging: comedi: remove attach_pci and attach_usb handlers No comedi drivers set the `attach_pci()` or `attach_usb()` handlers in their `struct comedi_driver` any longer as they have all been replaced with an `auto_attach()` handler. Also, no code calls the `attach_pci()` or `attach_usb()` handlers any longer. Remove them from `struct comedi_driver`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 5af3579337e..ce6ab93b754 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -201,8 +201,6 @@ struct comedi_driver { struct module *module; int (*attach) (struct comedi_device *, struct comedi_devconfig *); void (*detach) (struct comedi_device *); - int (*attach_pci) (struct comedi_device *, struct pci_dev *); - int (*attach_usb) (struct comedi_device *, struct usb_interface *); int (*auto_attach) (struct comedi_device *, unsigned long); /* number of elements in board_name and board_id arrays */ -- cgit v1.2.3 From 581a7ddec13d8f08b308c4764090bf57b0254f6f Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 14 Nov 2012 13:10:40 +0000 Subject: staging: comedi: use inlines for PCI/USB auto config Apart from the somewhat unnecessary `BUG_ON()` calls, `comedi_pci_auto_config()` and `comedi_usb_auto_config()` are just one-line wrappers around `comedi_auto_config()`, and `comedi_pci_auto_unconfig()` and `comedi_usb_auto_unconfig()` are just one-line wrappers around `comedi_auto_unconfig()`. Convert them to inline functions and remove the `BUG_ON()` calls. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedidev.h | 28 ++++++++++++++++++++++------ drivers/staging/comedi/drivers.c | 27 --------------------------- 2 files changed, 22 insertions(+), 33 deletions(-) diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index ce6ab93b754..692e1e615d4 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -517,11 +517,27 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s); int comedi_auto_config(struct device *hardware_device, struct comedi_driver *driver, unsigned long context); void comedi_auto_unconfig(struct device *hardware_device); -int comedi_pci_auto_config(struct pci_dev *pcidev, - struct comedi_driver *driver); -void comedi_pci_auto_unconfig(struct pci_dev *pcidev); -int comedi_usb_auto_config(struct usb_interface *intf, - struct comedi_driver *driver); -void comedi_usb_auto_unconfig(struct usb_interface *intf); + +static inline int comedi_pci_auto_config(struct pci_dev *pcidev, + struct comedi_driver *driver) +{ + return comedi_auto_config(&pcidev->dev, driver, 0); +} + +static inline void comedi_pci_auto_unconfig(struct pci_dev *pcidev) +{ + comedi_auto_unconfig(&pcidev->dev); +} + +static inline int comedi_usb_auto_config(struct usb_interface *intf, + struct comedi_driver *driver) +{ + return comedi_auto_config(&intf->dev, driver, 0); +} + +static inline void comedi_usb_auto_unconfig(struct usb_interface *intf) +{ + comedi_auto_unconfig(&intf->dev); +} #endif /* _COMEDIDEV_H */ diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 8de9a24d9ad..7175c302b0c 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -930,18 +930,6 @@ void comedi_pci_disable(struct pci_dev *pdev) } EXPORT_SYMBOL_GPL(comedi_pci_disable); -int comedi_pci_auto_config(struct pci_dev *pcidev, struct comedi_driver *driver) -{ - return comedi_auto_config(&pcidev->dev, driver, 0); -} -EXPORT_SYMBOL_GPL(comedi_pci_auto_config); - -void comedi_pci_auto_unconfig(struct pci_dev *pcidev) -{ - comedi_auto_unconfig(&pcidev->dev); -} -EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig); - int comedi_pci_driver_register(struct comedi_driver *comedi_driver, struct pci_driver *pci_driver) { @@ -975,21 +963,6 @@ EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); #if IS_ENABLED(CONFIG_USB) -int comedi_usb_auto_config(struct usb_interface *intf, - struct comedi_driver *driver) -{ - BUG_ON(intf == NULL); - return comedi_auto_config(&intf->dev, driver, 0); -} -EXPORT_SYMBOL_GPL(comedi_usb_auto_config); - -void comedi_usb_auto_unconfig(struct usb_interface *intf) -{ - BUG_ON(intf == NULL); - comedi_auto_unconfig(&intf->dev); -} -EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig); - int comedi_usb_driver_register(struct comedi_driver *comedi_driver, struct usb_driver *usb_driver) { -- cgit v1.2.3 From 8fdefcb0ab74eff3273a6c3039c4e80ef5f56bdc Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 14 Nov 2012 09:13:54 -0500 Subject: staging: dgrp: remove TIOCGSOFTCAR and TIOCSSOFTCAR handling The TIOCGSOFTCAR and TIOCSSOFTCAR ioctls are handled by the tty layer so the dgrp driver shouldn't try to deal with them itself. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgrp/dgrp_tty.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c index e125b03598d..efa62ced7c8 100644 --- a/drivers/staging/dgrp/dgrp_tty.c +++ b/drivers/staging/dgrp/dgrp_tty.c @@ -2615,21 +2615,6 @@ static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd, */ return 0; - case TIOCGSOFTCAR: - rc = access_ok(VERIFY_WRITE, (void __user *) arg, - sizeof(long)); - if (rc == 0) - return -EFAULT; - put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) arg); - return 0; - - case TIOCSSOFTCAR: - get_user(arg, (unsigned long __user *) arg); - tty->termios.c_cflag = - ((tty->termios.c_cflag & ~CLOCAL) | - (arg ? CLOCAL : 0)); - return 0; - case TIOCMGET: rc = access_ok(VERIFY_WRITE, (void __user *) arg, sizeof(unsigned int)); -- cgit v1.2.3 From 70ce93954f571eb913ee52529fa87fd1a315b2d1 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 14 Nov 2012 08:50:41 +0100 Subject: staging: line6: drop control URB dumping code The usbmon feature should be used instead of manually dumping control URBs. There are a few advantages to using usbmon: * Can be turned on/off at runtime * Provides full USB-level traffic * tcpdump and wireshark support for powerful analysis * No driver-specific code is required Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 36 ------------------------------------ drivers/staging/line6/midi.c | 3 --- 2 files changed, 39 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index 571f2ceceed..fda92d1e92b 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -177,22 +177,6 @@ void line6_write_hexdump(struct usb_line6 *line6, char dir, } #endif -#ifdef CONFIG_LINE6_USB_DUMP_CTRL -/* - Dump URB data to syslog. -*/ -static void line6_dump_urb(struct urb *urb) -{ - struct usb_line6 *line6 = (struct usb_line6 *)urb->context; - - if (urb->status < 0) - return; - - line6_write_hexdump(line6, 'R', (unsigned char *)urb->transfer_buffer, - urb->actual_length); -} -#endif - /* Send raw message in pieces of wMaxPacketSize bytes. */ @@ -201,10 +185,6 @@ int line6_send_raw_message(struct usb_line6 *line6, const char *buffer, { int i, done = 0; -#ifdef CONFIG_LINE6_USB_DUMP_CTRL - line6_write_hexdump(line6, 'S', buffer, size); -#endif - for (i = 0; i < size; i += line6->max_packet_size) { int partial; const char *frag_buf = buffer + i; @@ -259,10 +239,6 @@ static int line6_send_raw_message_async_part(struct message *msg, (char *)msg->buffer + done, bytes, line6_async_request_sent, msg, line6->interval); -#ifdef CONFIG_LINE6_USB_DUMP_CTRL - line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes); -#endif - msg->done += bytes; retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -403,10 +379,6 @@ static void line6_data_received(struct urb *urb) if (urb->status == -ESHUTDOWN) return; -#ifdef CONFIG_LINE6_USB_DUMP_CTRL - line6_dump_urb(urb); -#endif - done = line6_midibuf_write(mb, urb->transfer_buffer, urb->actual_length); @@ -502,10 +474,6 @@ int line6_send_program(struct usb_line6 *line6, u8 value) buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST; buffer[1] = value; -#ifdef CONFIG_LINE6_USB_DUMP_CTRL - line6_write_hexdump(line6, 'S', buffer, 2); -#endif - retval = usb_interrupt_msg(line6->usbdev, usb_sndintpipe(line6->usbdev, line6->ep_control_write), @@ -539,10 +507,6 @@ int line6_transmit_parameter(struct usb_line6 *line6, int param, u8 value) buffer[1] = param; buffer[2] = value; -#ifdef CONFIG_LINE6_USB_DUMP_CTRL - line6_write_hexdump(line6, 'S', buffer, 3); -#endif - retval = usb_interrupt_msg(line6->usbdev, usb_sndintpipe(line6->usbdev, line6->ep_control_write), diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c index 50407294fbd..348d42549b0 100644 --- a/drivers/staging/line6/midi.c +++ b/drivers/staging/line6/midi.c @@ -131,9 +131,6 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data, dev_err(line6->ifcdev, "Out of memory\n"); return -ENOMEM; } -#ifdef CONFIG_LINE6_USB_DUMP_CTRL - line6_write_hexdump(line6, 'S', data, length); -#endif transfer_buffer = kmemdup(data, length, GFP_ATOMIC); -- cgit v1.2.3 From 19ae77935e45d60bf64144e2d67074a2886db245 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 14 Nov 2012 08:50:42 +0100 Subject: staging: line6: drop CONTROL from CONFIG_LINE6_USB_DUMP_ANY CONFIG_LINE6_USB_DUMP_CTRL is no longer used by the code and therefore no longer plays a role in CONFIG_LINE6_USB_DUMP_ANY. Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h index 9dd8ff475f5..7770635028b 100644 --- a/drivers/staging/line6/driver.h +++ b/drivers/staging/line6/driver.h @@ -20,7 +20,7 @@ #define DRIVER_NAME "line6usb" -#if defined(CONFIG_LINE6_USB_DUMP_CTRL) || defined(CONFIG_LINE6_USB_DUMP_MIDI) || defined(CONFIG_LINE6_USB_DUMP_PCM) +#if defined(CONFIG_LINE6_USB_DUMP_MIDI) || defined(CONFIG_LINE6_USB_DUMP_PCM) #define CONFIG_LINE6_USB_DUMP_ANY #endif -- cgit v1.2.3 From 4aea449ac8c4955f18c49ecb6fd3e0417a2073c0 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 14 Nov 2012 08:50:43 +0100 Subject: staging: line6: drop unused CONFIG_LINE6_USB_DUMP_CTRL Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/Kconfig | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/staging/line6/Kconfig b/drivers/staging/line6/Kconfig index a5ded1233fe..2101799344c 100644 --- a/drivers/staging/line6/Kconfig +++ b/drivers/staging/line6/Kconfig @@ -23,15 +23,6 @@ menuconfig LINE6_USB if LINE6_USB -config LINE6_USB_DUMP_CTRL - bool "dump control messages" - default n - help - Say Y here to write control messages sent to and received from - Line6 devices to the syslog. - - If unsure, say N. - config LINE6_USB_DUMP_MIDI bool "dump MIDI messages" default n -- cgit v1.2.3 From 36a01f4d971c4d2d9923a94ca21ccd3f2d579563 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 14 Nov 2012 08:50:44 +0100 Subject: staging: line6: drop MIDI dumping code ALSA amidi(1) and aseqdump(1) can be used to dump MIDI instead of manually dumping MIDI messages in the driver. The advantage of using these existing tools is that can be used at run-time rather than compile-time. Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.c | 3 --- drivers/staging/line6/midi.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c index fda92d1e92b..0bc838d9251 100644 --- a/drivers/staging/line6/driver.c +++ b/drivers/staging/line6/driver.c @@ -402,9 +402,6 @@ static void line6_data_received(struct urb *urb) continue; line6->message_length = done; -#ifdef CONFIG_LINE6_USB_DUMP_MIDI - line6_write_hexdump(line6, 'r', line6->buffer_message, done); -#endif line6_midi_receive(line6, line6->buffer_message, done); switch (line6->usbdev->descriptor.idProduct) { diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c index 348d42549b0..c8e099bd0a4 100644 --- a/drivers/staging/line6/midi.c +++ b/drivers/staging/line6/midi.c @@ -59,9 +59,6 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream) if (done == 0) break; -#ifdef CONFIG_LINE6_USB_DUMP_MIDI - line6_write_hexdump(line6, 's', chunk, done); -#endif line6_midibuf_write(mb, chunk, done); snd_rawmidi_transmit_ack(substream, done); } -- cgit v1.2.3 From 10c39f1d717d3e5e8bcb2998f7dee4362edda26a Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 14 Nov 2012 08:50:45 +0100 Subject: staging: line6: drop MIDI from CONFIG_LINE6_USB_DUMP_ANY CONFIG_LINE6_USB_DUMP_MIDI is no longer used by the code and therefore no longer plays a role in CONFIG_LINE6_USB_DUMP_ANY. Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/driver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h index 7770635028b..f0be5a2adab 100644 --- a/drivers/staging/line6/driver.h +++ b/drivers/staging/line6/driver.h @@ -20,7 +20,7 @@ #define DRIVER_NAME "line6usb" -#if defined(CONFIG_LINE6_USB_DUMP_MIDI) || defined(CONFIG_LINE6_USB_DUMP_PCM) +#if defined(CONFIG_LINE6_USB_DUMP_PCM) #define CONFIG_LINE6_USB_DUMP_ANY #endif -- cgit v1.2.3 From c6c2f47f30c44f3fdae9362f811f95109f81303e Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Wed, 14 Nov 2012 08:50:46 +0100 Subject: staging: line6: drop unused CONFIG_LINE6_USB_DUMP_MIDI Signed-off-by: Stefan Hajnoczi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/Kconfig | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/staging/line6/Kconfig b/drivers/staging/line6/Kconfig index 2101799344c..80a7202a75a 100644 --- a/drivers/staging/line6/Kconfig +++ b/drivers/staging/line6/Kconfig @@ -23,15 +23,6 @@ menuconfig LINE6_USB if LINE6_USB -config LINE6_USB_DUMP_MIDI - bool "dump MIDI messages" - default n - help - Say Y here to write MIDI messages sent to and received from - Line6 devices to the syslog. - - If unsure, say N. - config LINE6_USB_DUMP_PCM bool "dump PCM data" default n -- cgit v1.2.3 From fdbf20b3b0a58c3ed115dfba4fe8b87385ad4cbc Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:28:54 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_connector.c The following warnings fixed. - WARNING: braces {} are not necessary for any arm of this statement - WARNING: braces {} are not necessary for single statement blocks Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_connector.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/omapdrm/omap_connector.c b/drivers/staging/omapdrm/omap_connector.c index 38be186c249..91edb3f9697 100644 --- a/drivers/staging/omapdrm/omap_connector.c +++ b/drivers/staging/omapdrm/omap_connector.c @@ -146,11 +146,10 @@ enum drm_connector_status omap_connector_detect( enum drm_connector_status ret; if (dssdrv->detect) { - if (dssdrv->detect(dssdev)) { + if (dssdrv->detect(dssdev)) ret = connector_status_connected; - } else { + else ret = connector_status_disconnected; - } } else { ret = connector_status_unknown; } @@ -383,9 +382,8 @@ struct drm_connector *omap_connector_init(struct drm_device *dev, return connector; fail: - if (connector) { + if (connector) omap_connector_destroy(connector); - } return NULL; } -- cgit v1.2.3 From bd690dece9467a0178ebe8db0ddaaefdc180f0dd Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:30:08 +0900 Subject: staging/omapdrm: remove the unnecessary initialization of a local variable in omap_crtc.c The following error fixed. - ERROR: do not initialise statics to 0 or NULL Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/omapdrm/omap_crtc.c b/drivers/staging/omapdrm/omap_crtc.c index 52492232903..cbda7e02733 100644 --- a/drivers/staging/omapdrm/omap_crtc.c +++ b/drivers/staging/omapdrm/omap_crtc.c @@ -114,7 +114,7 @@ static void omap_crtc_load_lut(struct drm_crtc *crtc) static void vblank_cb(void *arg) { - static uint32_t sequence = 0; + static uint32_t sequence; struct drm_crtc *crtc = arg; struct drm_device *dev = crtc->dev; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); -- cgit v1.2.3 From d21a9d3ba52ae07662cc7832009b1502eda41072 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:30:23 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_crtc.c The following warning fixed. - WARNING: braces {} are not necessary for single statement blocks Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_crtc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/omapdrm/omap_crtc.c b/drivers/staging/omapdrm/omap_crtc.c index cbda7e02733..d87bd84257b 100644 --- a/drivers/staging/omapdrm/omap_crtc.c +++ b/drivers/staging/omapdrm/omap_crtc.c @@ -263,8 +263,8 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, return crtc; fail: - if (crtc) { + if (crtc) omap_crtc_destroy(crtc); - } + return NULL; } -- cgit v1.2.3 From c7f904b33422b477e5708330bd40cdc63bbbd227 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:30:38 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_drv.c The following warnings fixed. - WARNING: braces {} are not necessary for single statement blocks Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_drv.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c index 6ae2f763b27..d4823fd6776 100644 --- a/drivers/staging/omapdrm/omap_drv.c +++ b/drivers/staging/omapdrm/omap_drv.c @@ -51,9 +51,8 @@ static void omap_fb_output_poll_changed(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; DBG("dev=%p", dev); - if (priv->fbdev) { + if (priv->fbdev) drm_fb_helper_hotplug_event(priv->fbdev); - } } static const struct drm_mode_config_funcs omap_mode_config_funcs = { @@ -85,9 +84,9 @@ static int omap_drm_notifier(struct notifier_block *nb, case OMAP_DSS_HOTPLUG_DISCONNECT: { struct drm_device *dev = drm_device; DBG("hotplug event: evt=%d, dev=%p", evt, dev); - if (dev) { + if (dev) drm_sysfs_hotplug_event(dev); - } + return NOTIFY_OK; } default: /* don't care about other events for now */ @@ -211,9 +210,9 @@ static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl, struct drm_encoder *encoder = omap_connector_attached_encoder( priv->connectors[*j]); - if (encoder) { + if (encoder) mgr = omap_encoder_get_manager(encoder); - } + } (*j)++; } @@ -232,9 +231,9 @@ static int create_crtc(struct drm_device *dev, struct omap_overlay *ovl, struct drm_encoder *encoder = omap_connector_attached_encoder( priv->connectors[idx]); - if (encoder) { + if (encoder) mgr = omap_encoder_get_manager(encoder); - } + } (*j)++; } @@ -353,9 +352,8 @@ static int omap_modeset_init(struct drm_device *dev) */ int max_overlays = min(omap_dss_get_num_overlays(), num_crtc); - for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) { + for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) create_encoder(dev, omap_dss_get_overlay_manager(i)); - } for_each_dss_dev(dssdev) { create_connector(dev, dssdev); @@ -468,15 +466,13 @@ static int ioctl_gem_cpu_prep(struct drm_device *dev, void *data, VERB("%p:%p: handle=%d, op=%x", dev, file_priv, args->handle, args->op); obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (!obj) { + if (!obj) return -ENOENT; - } ret = omap_gem_op_sync(obj, args->op); - if (!ret) { + if (!ret) ret = omap_gem_op_start(obj, args->op); - } drm_gem_object_unreference_unlocked(obj); @@ -493,16 +489,14 @@ static int ioctl_gem_cpu_fini(struct drm_device *dev, void *data, VERB("%p:%p: handle=%d", dev, file_priv, args->handle); obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (!obj) { + if (!obj) return -ENOENT; - } /* XXX flushy, flushy */ ret = 0; - if (!ret) { + if (!ret) ret = omap_gem_op_finish(obj, args->op); - } drm_gem_object_unreference_unlocked(obj); @@ -519,9 +513,8 @@ static int ioctl_gem_info(struct drm_device *dev, void *data, DBG("%p:%p: handle=%d", dev, file_priv, args->handle); obj = drm_gem_object_lookup(dev, file_priv, args->handle); - if (!obj) { + if (!obj) return -ENOENT; - } args->size = omap_gem_mmap_size(obj); args->offset = omap_gem_mmap_offset(obj); @@ -595,9 +588,8 @@ static int dev_load(struct drm_device *dev, unsigned long flags) drm_kms_helper_poll_init(dev); ret = drm_vblank_init(dev, priv->num_crtcs); - if (ret) { + if (ret) dev_warn(dev->dev, "could not init vblank\n"); - } return 0; } -- cgit v1.2.3 From 7ced63cf7ecfa572d7890a2112997dd75837d153 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:30:52 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_drv.h The following errors fixed. - ERROR: "foo * bar" should be "foo *bar" Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_drv.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h index 8f7c447930f..8f41098fd84 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/staging/omapdrm/omap_drv.h @@ -191,9 +191,9 @@ size_t omap_gem_mmap_size(struct drm_gem_object *obj); int omap_gem_tiled_size(struct drm_gem_object *obj, uint16_t *w, uint16_t *h); int omap_gem_tiled_stride(struct drm_gem_object *obj, uint32_t orient); -struct dma_buf * omap_gem_prime_export(struct drm_device *dev, +struct dma_buf *omap_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags); -struct drm_gem_object * omap_gem_prime_import(struct drm_device *dev, +struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev, struct dma_buf *buffer); static inline int align_pitch(int pitch, int width, int bpp) -- cgit v1.2.3 From bc1e1581763de164c79e76669f754b3608680153 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:31:09 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_drv.h The following warnings fixed. - WARNING: braces {} are not necessary for single statement blocks Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_drv.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/omapdrm/omap_drv.h b/drivers/staging/omapdrm/omap_drv.h index 8f41098fd84..1d4aea53b75 100644 --- a/drivers/staging/omapdrm/omap_drv.h +++ b/drivers/staging/omapdrm/omap_drv.h @@ -218,17 +218,17 @@ static inline int objects_lookup(struct drm_device *dev, for (i = 0; i < n; i++) { bos[i] = drm_gem_object_lookup(dev, filp, handles[i]); - if (!bos[i]) { + if (!bos[i]) goto fail; - } + } return 0; fail: - while (--i > 0) { + while (--i > 0) drm_gem_object_unreference_unlocked(bos[i]); - } + return -ENOENT; } -- cgit v1.2.3 From 582bc28c2d1c0fe45ba797c48b46a8dda537c4b4 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:31:27 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_encoder.c The following warnings fixed. - WARNING: braces {} are not necessary for single statement blocks Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_encoder.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/omapdrm/omap_encoder.c b/drivers/staging/omapdrm/omap_encoder.c index 31c735d3921..5341d5e3e31 100644 --- a/drivers/staging/omapdrm/omap_encoder.c +++ b/drivers/staging/omapdrm/omap_encoder.c @@ -72,9 +72,9 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, for (i = 0; i < priv->num_connectors; i++) { struct drm_connector *connector = priv->connectors[i]; - if (connector->encoder == encoder) { + if (connector->encoder == encoder) omap_connector_mode_set(connector, mode); - } + } } @@ -163,9 +163,8 @@ struct drm_encoder *omap_encoder_init(struct drm_device *dev, return encoder; fail: - if (encoder) { + if (encoder) omap_encoder_destroy(encoder); - } return NULL; } -- cgit v1.2.3 From ddcd49ed6e74f98a643532ec4ccac8841099785c Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:32:17 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_fb.c The following warnings fixed. - WARNING: braces {} are not necessary for single statement blocks Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_fb.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/staging/omapdrm/omap_fb.c b/drivers/staging/omapdrm/omap_fb.c index 75d2ff1bf8a..09028e9c109 100644 --- a/drivers/staging/omapdrm/omap_fb.c +++ b/drivers/staging/omapdrm/omap_fb.c @@ -307,17 +307,16 @@ struct drm_connector *omap_framebuffer_get_next_connector( struct list_head *connector_list = &dev->mode_config.connector_list; struct drm_connector *connector = from; - if (!from) { + if (!from) return list_first_entry(connector_list, typeof(*from), head); - } list_for_each_entry_from(connector, connector_list, head) { if (connector != from) { struct drm_encoder *encoder = connector->encoder; struct drm_crtc *crtc = encoder ? encoder->crtc : NULL; - if (crtc && crtc->fb == fb) { + if (crtc && crtc->fb == fb) return connector; - } + } } @@ -466,8 +465,8 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev, return fb; fail: - if (fb) { + if (fb) omap_framebuffer_destroy(fb); - } + return ERR_PTR(ret); } -- cgit v1.2.3 From 801d5bc6013cfd9d01ec168285972e969521a562 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:32:56 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_gem.c The following error fixed. - ERROR: "foo ** bar" should be "foo **bar" Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c index 8a9b1cee0f7..94c04a5200d 100644 --- a/drivers/staging/omapdrm/omap_gem.c +++ b/drivers/staging/omapdrm/omap_gem.c @@ -25,7 +25,7 @@ #include "omap_dmm_tiler.h" /* remove these once drm core helpers are merged */ -struct page ** _drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask); +struct page **_drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask); void _drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, bool dirty, bool accessed); int _drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size); -- cgit v1.2.3 From ae053039553349f625945f65b211b50f4587117d Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:33:17 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_gem.c The following warnings fixed. - WARNING: braces {} are not necessary for single statement blocks Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_gem.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c index 94c04a5200d..e615871ea9e 100644 --- a/drivers/staging/omapdrm/omap_gem.c +++ b/drivers/staging/omapdrm/omap_gem.c @@ -521,9 +521,8 @@ int omap_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) /* if a shmem backed object, make sure we have pages attached now */ ret = get_pages(obj, &pages); - if (ret) { + if (ret) goto fail; - } /* where should we do corresponding put_pages().. we are mapping * the original page, rather than thru a GART, so we can't rely @@ -1146,9 +1145,8 @@ int omap_gem_op_sync(struct drm_gem_object *obj, enum omap_gem_op op) struct omap_gem_sync_waiter *waiter = kzalloc(sizeof(*waiter), GFP_KERNEL); - if (!waiter) { + if (!waiter) return -ENOMEM; - } waiter->omap_obj = omap_obj; waiter->op = op; @@ -1177,9 +1175,8 @@ int omap_gem_op_sync(struct drm_gem_object *obj, enum omap_gem_op op) } spin_unlock(&sync_lock); - if (waiter) { + if (waiter) kfree(waiter); - } } return ret; } @@ -1201,9 +1198,8 @@ int omap_gem_op_async(struct drm_gem_object *obj, enum omap_gem_op op, struct omap_gem_sync_waiter *waiter = kzalloc(sizeof(*waiter), GFP_ATOMIC); - if (!waiter) { + if (!waiter) return -ENOMEM; - } waiter->omap_obj = omap_obj; waiter->op = op; @@ -1285,9 +1281,8 @@ void omap_gem_free_object(struct drm_gem_object *obj) list_del(&omap_obj->mm_list); - if (obj->map_list.map) { + if (obj->map_list.map) drm_gem_free_mmap_offset(obj); - } /* this means the object is still pinned.. which really should * not happen. I think.. @@ -1296,9 +1291,9 @@ void omap_gem_free_object(struct drm_gem_object *obj) /* don't free externally allocated backing memory */ if (!(omap_obj->flags & OMAP_BO_EXT_MEM)) { - if (omap_obj->pages) { + if (omap_obj->pages) omap_gem_detach_pages(obj); - } + if (!is_shmem(obj)) { dma_free_writecombine(dev->dev, obj->size, omap_obj->vaddr, omap_obj->paddr); @@ -1308,9 +1303,8 @@ void omap_gem_free_object(struct drm_gem_object *obj) } /* don't free externally allocated syncobj */ - if (!(omap_obj->flags & OMAP_BO_EXT_SYNC)) { + if (!(omap_obj->flags & OMAP_BO_EXT_SYNC)) kfree(omap_obj->sync); - } drm_gem_object_release(obj); @@ -1395,9 +1389,9 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, */ omap_obj->vaddr = dma_alloc_writecombine(dev->dev, size, &omap_obj->paddr, GFP_KERNEL); - if (omap_obj->vaddr) { + if (omap_obj->vaddr) flags |= OMAP_BO_DMA; - } + } omap_obj->flags = flags; @@ -1407,22 +1401,20 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, omap_obj->height = gsize.tiled.height; } - if (flags & (OMAP_BO_DMA|OMAP_BO_EXT_MEM)) { + if (flags & (OMAP_BO_DMA|OMAP_BO_EXT_MEM)) ret = drm_gem_private_object_init(dev, obj, size); - } else { + else ret = drm_gem_object_init(dev, obj, size); - } - if (ret) { + if (ret) goto fail; - } return obj; fail: - if (obj) { + if (obj) omap_gem_free_object(obj); - } + return NULL; } -- cgit v1.2.3 From 696e3ca30aedcb11726050504b8e3c56bdc8285b Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:33:43 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_gem.c The following errors fixed. - ERROR: space prohibited after that '!' (ctx:BxW) Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/omapdrm/omap_gem.c b/drivers/staging/omapdrm/omap_gem.c index e615871ea9e..c38992b76fc 100644 --- a/drivers/staging/omapdrm/omap_gem.c +++ b/drivers/staging/omapdrm/omap_gem.c @@ -952,7 +952,7 @@ int omap_gem_put_pages(struct drm_gem_object *obj) void *omap_gem_vaddr(struct drm_gem_object *obj) { struct omap_gem_object *omap_obj = to_omap_bo(obj); - WARN_ON(! mutex_is_locked(&obj->dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex)); if (!omap_obj->vaddr) { struct page **pages; int ret = get_pages(obj, &pages); @@ -971,7 +971,7 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m) struct omap_gem_object *omap_obj = to_omap_bo(obj); uint64_t off = 0; - WARN_ON(! mutex_is_locked(&dev->struct_mutex)); + WARN_ON(!mutex_is_locked(&dev->struct_mutex)); if (obj->map_list.map) off = (uint64_t)obj->map_list.hash.key; -- cgit v1.2.3 From 11d3d27b69207348a8552ec4139a2c461905e2b2 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:40:14 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_gem_dmabuf.c The following errors fixed. - ERROR: "foo * bar" should be "foo *bar" Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_gem_dmabuf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/omapdrm/omap_gem_dmabuf.c b/drivers/staging/omapdrm/omap_gem_dmabuf.c index c6f3ef6f57b..9a302062b03 100644 --- a/drivers/staging/omapdrm/omap_gem_dmabuf.c +++ b/drivers/staging/omapdrm/omap_gem_dmabuf.c @@ -191,13 +191,13 @@ struct dma_buf_ops omap_dmabuf_ops = { .mmap = omap_gem_dmabuf_mmap, }; -struct dma_buf * omap_gem_prime_export(struct drm_device *dev, +struct dma_buf *omap_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj, int flags) { return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, 0600); } -struct drm_gem_object * omap_gem_prime_import(struct drm_device *dev, +struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev, struct dma_buf *buffer) { struct drm_gem_object *obj; -- cgit v1.2.3 From b1ca079e7eb6ca862247fe694f320367bd962a24 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:40:29 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_gem_helper.c The following error fixed. - ERROR: "foo ** bar" should be "foo **bar" Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_gem_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/omapdrm/omap_gem_helpers.c b/drivers/staging/omapdrm/omap_gem_helpers.c index f895363a5e5..1b541104753 100644 --- a/drivers/staging/omapdrm/omap_gem_helpers.c +++ b/drivers/staging/omapdrm/omap_gem_helpers.c @@ -32,7 +32,7 @@ * @obj: obj in question * @gfpmask: gfp mask of requested pages */ -struct page ** _drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask) +struct page **_drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask) { struct inode *inode; struct address_space *mapping; -- cgit v1.2.3 From 4a19313c9d09967db35833982de2c6565ee5e7e9 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:40:43 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_gem_helper.c The following warning fixed. - WARNING: braces {} are not necessary for single statement blocks Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_gem_helpers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/omapdrm/omap_gem_helpers.c b/drivers/staging/omapdrm/omap_gem_helpers.c index 1b541104753..ffb8cceaeb4 100644 --- a/drivers/staging/omapdrm/omap_gem_helpers.c +++ b/drivers/staging/omapdrm/omap_gem_helpers.c @@ -80,9 +80,9 @@ struct page **_drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask) return pages; fail: - while (i--) { + while (i--) page_cache_release(pages[i]); - } + drm_free_large(pages); return ERR_CAST(p); } -- cgit v1.2.3 From 373de7f4f7a52d3d18cbe78087325f98e3b7cded Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:40:57 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_plane.c The following warning fixed. - WARNING: braces {} are not necessary for single statement blocks Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_plane.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/staging/omapdrm/omap_plane.c index 1b3a9febd40..25d78ca6fdb 100644 --- a/drivers/staging/omapdrm/omap_plane.c +++ b/drivers/staging/omapdrm/omap_plane.c @@ -551,8 +551,8 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, return plane; fail: - if (plane) { + if (plane) omap_plane_destroy(plane); - } + return NULL; } -- cgit v1.2.3 From c17d37df984b0eaf67d422b2698755fe71d6d1e0 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 14 Nov 2012 19:41:13 +0900 Subject: staging/omapdrm: Fix spacing coding style in omap_plane.c The following errors and warnings fixed. - ERROR: code indent should use tabs where possible - WARNING: please, no spaces at the start of a line Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_plane.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/staging/omapdrm/omap_plane.c index 25d78ca6fdb..2a8e5bab49c 100644 --- a/drivers/staging/omapdrm/omap_plane.c +++ b/drivers/staging/omapdrm/omap_plane.c @@ -436,8 +436,8 @@ void omap_plane_install_properties(struct drm_plane *plane, drm_object_attach_property(obj, prop, 0); } - prop = priv->zorder_prop; - if (!prop) { + prop = priv->zorder_prop; + if (!prop) { prop = drm_property_create_range(dev, 0, "zorder", 0, 3); if (prop == NULL) return; -- cgit v1.2.3 From 36e97a5714073a1f95c70cbb925928ca7315fb66 Mon Sep 17 00:00:00 2001 From: Kumar Amit Mehta Date: Wed, 14 Nov 2012 15:30:57 +0530 Subject: staging: rtl8187se: r8180_core.c: Inspect the return value of register_netdev() Inspect the return value of register_netdev() in the driver probe routine and return -ENODEV in case of error. Signed-off-by: Kumar Amit Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index ea04eec3095..6a27836f989 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -3258,7 +3258,8 @@ static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, netif_carrier_off(dev); - register_netdev(dev); + if (register_netdev(dev)) + goto fail1; rtl8180_proc_init_one(dev); -- cgit v1.2.3 From f0f98b19e23d4426ca185e3d4ca80e6aff5ef51b Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 13 Nov 2012 09:48:51 +0100 Subject: regulator: fix voltage check in regulator_is_supported_voltage() regulator_is_supported_voltage() should return true only if the voltage of fixed/constant regulator is between min_uV and max_uV. Signed-off-by: Marek Szyprowski Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 5c4829cba6a..27eb9d66f06 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1974,7 +1974,7 @@ int regulator_is_supported_voltage(struct regulator *regulator, if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { ret = regulator_get_voltage(regulator); if (ret >= 0) - return (min_uV >= ret && ret <= max_uV); + return (min_uV <= ret && ret <= max_uV); else return ret; } -- cgit v1.2.3 From 70a6f46d7b0ec03653b9ab3f8063a9717a4a53ef Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 14 Nov 2012 11:49:53 +0000 Subject: pstore: Fix NULL pointer dereference in console writes Passing a NULL id causes a NULL pointer deference in writers such as erst_writer and efi_pstore_write because they expect to update this id. Pass a dummy id instead. This avoids a cascade of oopses caused when the initial pstore_console_write passes a null which in turn causes writes to the console causing further oopses in subsequent pstore_console_write calls. Signed-off-by: Colin Ian King Acked-by: Kees Cook Cc: stable@vger.kernel.org Signed-off-by: Anton Vorontsov --- fs/pstore/platform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index a40da07e93d..947fbe06c3b 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -161,6 +161,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) while (s < e) { unsigned long flags; + u64 id; if (c > psinfo->bufsize) c = psinfo->bufsize; @@ -172,7 +173,7 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c) spin_lock_irqsave(&psinfo->buf_lock, flags); } memcpy(psinfo->buf, s, c); - psinfo->write(PSTORE_TYPE_CONSOLE, 0, NULL, 0, c, psinfo); + psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, c, psinfo); spin_unlock_irqrestore(&psinfo->buf_lock, flags); s += c; c = e - s; -- cgit v1.2.3 From b2942004fb5c9f3304b77e187b8a1977b3626c9b Mon Sep 17 00:00:00 2001 From: Saurabh Mohan Date: Wed, 14 Nov 2012 18:08:15 -0800 Subject: ipv4/ip_vti.c: VTI fix post-decryption forwarding With the latest kernel there are two things that must be done post decryption so that the packet are forwarded. 1. Remove the mark from the packet. This will cause the packet to not match the ipsec-policy again. However doing this causes the post-decryption check to fail also and the packet will get dropped. (cat /proc/net/xfrm_stat). 2. Remove the sp association in the skbuff so that no policy check is done on the packet for VTI tunnels. Due to #2 above we must now do a security-policy check in the vti rcv path prior to resetting the mark in the skbuff. Signed-off-by: Saurabh Mohan Reported-by: Ruben Herold Signed-off-by: David S. Miller --- net/ipv4/ip_vti.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 1831092f999..858fddf6482 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c @@ -338,12 +338,17 @@ static int vti_rcv(struct sk_buff *skb) if (tunnel != NULL) { struct pcpu_tstats *tstats; + if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) + return -1; + tstats = this_cpu_ptr(tunnel->dev->tstats); u64_stats_update_begin(&tstats->syncp); tstats->rx_packets++; tstats->rx_bytes += skb->len; u64_stats_update_end(&tstats->syncp); + skb->mark = 0; + secpath_reset(skb); skb->dev = tunnel->dev; return 1; } -- cgit v1.2.3 From 71c6c837a0fe9d291e0764503f09dac0fec59ce1 Mon Sep 17 00:00:00 2001 From: Xiaotian Feng Date: Tue, 13 Nov 2012 19:47:36 +0000 Subject: drivers/net: fix tasklet misuse issue In commit 175c0dff, drivers uses tasklet_kill to avoid put disabled tasklet on the tasklet vec. But some of the drivers uses tasklet_init & tasklet_disable in the driver init code, then tasklet_enable when it is opened. This makes tasklet_enable on a killed tasklet and make ksoftirqd crazy then. Normally, drivers should use tasklet_init/tasklet_kill on device open/remove, and use tasklet_disable/tasklet_enable on device suspend/resume. Reported-by: Peter Wu Tested-by: Peter Wu Signed-off-by: Xiaotian Feng Cc: "David S. Miller" Cc: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: David S. Miller --- drivers/net/ethernet/jme.c | 28 +++++++---------------- drivers/net/ethernet/micrel/ksz884x.c | 16 ++++--------- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 12 +++++----- 3 files changed, 18 insertions(+), 38 deletions(-) diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 92317e9c0f7..60ac46f4ac0 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -1860,10 +1860,14 @@ jme_open(struct net_device *netdev) jme_clear_pm(jme); JME_NAPI_ENABLE(jme); - tasklet_enable(&jme->linkch_task); - tasklet_enable(&jme->txclean_task); - tasklet_hi_enable(&jme->rxclean_task); - tasklet_hi_enable(&jme->rxempty_task); + tasklet_init(&jme->linkch_task, jme_link_change_tasklet, + (unsigned long) jme); + tasklet_init(&jme->txclean_task, jme_tx_clean_tasklet, + (unsigned long) jme); + tasklet_init(&jme->rxclean_task, jme_rx_clean_tasklet, + (unsigned long) jme); + tasklet_init(&jme->rxempty_task, jme_rx_empty_tasklet, + (unsigned long) jme); rc = jme_request_irq(jme); if (rc) @@ -3079,22 +3083,6 @@ jme_init_one(struct pci_dev *pdev, tasklet_init(&jme->pcc_task, jme_pcc_tasklet, (unsigned long) jme); - tasklet_init(&jme->linkch_task, - jme_link_change_tasklet, - (unsigned long) jme); - tasklet_init(&jme->txclean_task, - jme_tx_clean_tasklet, - (unsigned long) jme); - tasklet_init(&jme->rxclean_task, - jme_rx_clean_tasklet, - (unsigned long) jme); - tasklet_init(&jme->rxempty_task, - jme_rx_empty_tasklet, - (unsigned long) jme); - tasklet_disable_nosync(&jme->linkch_task); - tasklet_disable_nosync(&jme->txclean_task); - tasklet_disable_nosync(&jme->rxclean_task); - tasklet_disable_nosync(&jme->rxempty_task); jme->dpi.cur = PCC_P1; jme->reg_ghc = 0; diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index e558edd1cb6..69e01977a1d 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -5459,8 +5459,10 @@ static int prepare_hardware(struct net_device *dev) rc = request_irq(dev->irq, netdev_intr, IRQF_SHARED, dev->name, dev); if (rc) return rc; - tasklet_enable(&hw_priv->rx_tasklet); - tasklet_enable(&hw_priv->tx_tasklet); + tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, + (unsigned long) hw_priv); + tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, + (unsigned long) hw_priv); hw->promiscuous = 0; hw->all_multi = 0; @@ -7033,16 +7035,6 @@ static int __devinit pcidev_init(struct pci_dev *pdev, spin_lock_init(&hw_priv->hwlock); mutex_init(&hw_priv->lock); - /* tasklet is enabled. */ - tasklet_init(&hw_priv->rx_tasklet, rx_proc_task, - (unsigned long) hw_priv); - tasklet_init(&hw_priv->tx_tasklet, tx_proc_task, - (unsigned long) hw_priv); - - /* tasklet_enable will decrement the atomic counter. */ - tasklet_disable(&hw_priv->rx_tasklet); - tasklet_disable(&hw_priv->tx_tasklet); - for (i = 0; i < TOTAL_PORT_NUM; i++) init_waitqueue_head(&hw_priv->counter[i].counter); diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 1d04754a663..77e6db9dcfe 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -942,6 +942,10 @@ static int axienet_open(struct net_device *ndev) phy_start(lp->phy_dev); } + /* Enable tasklets for Axi DMA error handling */ + tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, + (unsigned long) lp); + /* Enable interrupts for Axi DMA Tx */ ret = request_irq(lp->tx_irq, axienet_tx_irq, 0, ndev->name, ndev); if (ret) @@ -950,8 +954,7 @@ static int axienet_open(struct net_device *ndev) ret = request_irq(lp->rx_irq, axienet_rx_irq, 0, ndev->name, ndev); if (ret) goto err_rx_irq; - /* Enable tasklets for Axi DMA error handling */ - tasklet_enable(&lp->dma_err_tasklet); + return 0; err_rx_irq: @@ -960,6 +963,7 @@ err_tx_irq: if (lp->phy_dev) phy_disconnect(lp->phy_dev); lp->phy_dev = NULL; + tasklet_kill(&lp->dma_err_tasklet); dev_err(lp->dev, "request_irq() failed\n"); return ret; } @@ -1613,10 +1617,6 @@ static int __devinit axienet_of_probe(struct platform_device *op) goto err_iounmap_2; } - tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, - (unsigned long) lp); - tasklet_disable(&lp->dma_err_tasklet); - return 0; err_iounmap_2: -- cgit v1.2.3 From 769ce4c95e8f77c1d5df82194e54df49d28830c5 Mon Sep 17 00:00:00 2001 From: Kamlakant Patel Date: Wed, 14 Nov 2012 01:41:38 +0000 Subject: net/smsc911x: Fix ready check in cases where WORD_SWAP is needed The chip ready check added by the commit 3ac3546e [Always wait for the chip to be ready] does not work when the register read/write is word swapped. This check has been added before the WORD_SWAP register is programmed, so we need to check for swapped register value as well. Bit 16 is marked as RESERVED in SMSC datasheet, Steve Glendinning checked with SMSC and wrote: The chip architects have concluded we should be reading PMT_CTRL until we see any of bits 0, 8, 16 or 24 set. Then we should read BYTE_TEST to check the byte order is correct (as we already do). The rationale behind this is that some of the chip variants have word order swapping features too, so the READY bit could actually be in any of the 4 possible locations. The architects have confirmed that if any of these 4 positions is set the chip is ready. The other 3 locations will either never be set or can only go high after READY does (so also indicate the device is ready). This change will check for the READY bit at the 16th position. We do not check the other two cases (bit 8 and 24) since the driver does not support byte-swapped register read/write. Signed-off-by: Kamlakant Patel Signed-off-by: David S. Miller --- drivers/net/ethernet/smsc/smsc911x.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 62d1baf111e..c53c0f4e2ce 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2110,7 +2110,7 @@ static void __devinit smsc911x_read_mac_address(struct net_device *dev) static int __devinit smsc911x_init(struct net_device *dev) { struct smsc911x_data *pdata = netdev_priv(dev); - unsigned int byte_test; + unsigned int byte_test, mask; unsigned int to = 100; SMSC_TRACE(pdata, probe, "Driver Parameters:"); @@ -2130,9 +2130,22 @@ static int __devinit smsc911x_init(struct net_device *dev) /* * poll the READY bit in PMT_CTRL. Any other access to the device is * forbidden while this bit isn't set. Try for 100ms + * + * Note that this test is done before the WORD_SWAP register is + * programmed. So in some configurations the READY bit is at 16 before + * WORD_SWAP is written to. This issue is worked around by waiting + * until either bit 0 or bit 16 gets set in PMT_CTRL. + * + * SMSC has confirmed that checking bit 16 (marked as reserved in + * the datasheet) is fine since these bits "will either never be set + * or can only go high after READY does (so also indicate the device + * is ready)". */ - while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to) + + mask = PMT_CTRL_READY_ | swahw32(PMT_CTRL_READY_); + while (!(smsc911x_reg_read(pdata, PMT_CTRL) & mask) && --to) udelay(1000); + if (to == 0) { pr_err("Device not READY in 100ms aborting\n"); return -ENODEV; -- cgit v1.2.3 From 80d11788fb8f4d9fcfae5ad508c7f1b65e8b28a3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 14 Nov 2012 22:32:15 -0500 Subject: Revert "drivers/net/phy/mdio-bitbang.c: Call mdiobus_unregister before mdiobus_free" This reverts commit aa731872f7d33dcb8b54dad0cfb82d4e4d195d7e. As pointed out by Ben Hutchings, this change is not correct. mdiobus_unregister() can't be called if the bus isn't registered yet, however this change can result in situations which cause that to happen. Part of the confusion here revolves around the fact that the callers of this module control registration/unregistration, rather than the module itself. Signed-off-by: David S. Miller --- drivers/net/phy/mdio-bitbang.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c index 6428fcbbdd4..daec9b05d16 100644 --- a/drivers/net/phy/mdio-bitbang.c +++ b/drivers/net/phy/mdio-bitbang.c @@ -234,7 +234,6 @@ void free_mdio_bitbang(struct mii_bus *bus) struct mdiobb_ctrl *ctrl = bus->priv; module_put(ctrl->ops->owner); - mdiobus_unregister(bus); mdiobus_free(bus); } EXPORT_SYMBOL(free_mdio_bitbang); -- cgit v1.2.3 From dba2939c8d4128664ddfddc169b32ae4b39aebc1 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Wed, 14 Nov 2012 17:47:47 -0700 Subject: staging: comedi: cb_pcidas64: use cfc_check_trigger_arg_*() helpers Use the new helpers in the step 3 tests of {ai,ao}_cmdtest(). Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Cc: Greg Kroah-Hartman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 72 ++++++++-------------------- 1 file changed, 21 insertions(+), 51 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 68a12890322..17813aa6bb2 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -2120,56 +2120,34 @@ static int ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (cmd->convert_src == TRIG_TIMER) { if (thisboard->layout == LAYOUT_4020) { - if (cmd->convert_arg) { - cmd->convert_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); } else { - if (cmd->convert_arg < thisboard->ai_speed) { - cmd->convert_arg = thisboard->ai_speed; - err++; - } - if (cmd->scan_begin_src == TRIG_TIMER) { - /* if scans are timed faster than - * conversion rate allows */ - if (cmd->convert_arg * cmd->chanlist_len > - cmd->scan_begin_arg) { - cmd->scan_begin_arg = + err |= cfc_check_trigger_arg_min(&cmd->convert_arg, + thisboard->ai_speed); + /* if scans are timed faster than conversion rate allows */ + if (cmd->scan_begin_src == TRIG_TIMER) + err |= cfc_check_trigger_arg_min( + &cmd->scan_begin_arg, cmd->convert_arg * - cmd->chanlist_len; - err++; - } - } + cmd->chanlist_len); } } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); switch (cmd->stop_src) { case TRIG_EXT: break; case TRIG_COUNT: - if (!cmd->stop_arg) { - cmd->stop_arg = 1; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); break; case TRIG_NONE: - if (cmd->stop_arg != 0) { - cmd->stop_arg = 0; - err++; - } + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); break; default: break; @@ -3428,29 +3406,21 @@ static int ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, if (err) return 2; - /* step 3: make sure arguments are trivially compatible */ + /* Step 3: check if arguments are trivially valid */ if (cmd->scan_begin_src == TRIG_TIMER) { - if (cmd->scan_begin_arg < thisboard->ao_scan_speed) { - cmd->scan_begin_arg = thisboard->ao_scan_speed; - err++; - } - if (get_ao_divisor(cmd->scan_begin_arg, - cmd->flags) > max_counter_value) { + err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, + thisboard->ao_scan_speed); + if (get_ao_divisor(cmd->scan_begin_arg, cmd->flags) > + max_counter_value) { cmd->scan_begin_arg = (max_counter_value + 2) * TIMER_BASE; - err++; + err |= -EINVAL; } } - if (!cmd->chanlist_len) { - cmd->chanlist_len = 1; - err++; - } - if (cmd->scan_end_arg != cmd->chanlist_len) { - cmd->scan_end_arg = cmd->chanlist_len; - err++; - } + err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); if (err) return 3; -- cgit v1.2.3 From 507ccdbfd80020c402cbbf65ceeb3235edb79021 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 12 Nov 2012 10:00:22 +0800 Subject: pinctrl: tegra: Make PINCTRL_TEGRA select PINMUX && PINCONF Then we can remove "select PINMUX && PINCONF" from PINCTRL_TEGRA{20,30}. This simplifies the dependency. Signed-off-by: Axel Lin Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index a274f073abd..0074873561d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -156,17 +156,15 @@ config PINCTRL_SIRF config PINCTRL_TEGRA bool + select PINMUX + select PINCONF config PINCTRL_TEGRA20 bool - select PINMUX - select PINCONF select PINCTRL_TEGRA config PINCTRL_TEGRA30 bool - select PINMUX - select PINCONF select PINCTRL_TEGRA config PINCTRL_U300 -- cgit v1.2.3 From 9387760db221420f56a9f43a7d079c9fb209e32e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 12 Nov 2012 14:45:50 +0800 Subject: pinctrl: pxa3xx: Use devm_request_and_ioremap Use managed resources API to simplify the code. Also ensure we do request mem_region before ioremap. Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-pxa3xx.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/pinctrl/pinctrl-pxa3xx.c b/drivers/pinctrl/pinctrl-pxa3xx.c index f14cd6ba4c0..43e3dd058dd 100644 --- a/drivers/pinctrl/pinctrl-pxa3xx.c +++ b/drivers/pinctrl/pinctrl-pxa3xx.c @@ -173,7 +173,6 @@ int pxa3xx_pinctrl_register(struct platform_device *pdev, { struct pinctrl_desc *desc; struct resource *res; - int ret = 0; if (!info || !info->cputype) return -EINVAL; @@ -190,21 +189,17 @@ int pxa3xx_pinctrl_register(struct platform_device *pdev, return -ENOENT; info->phy_base = res->start; info->phy_size = resource_size(res); - info->virt_base = ioremap(info->phy_base, info->phy_size); + info->virt_base = devm_request_and_ioremap(&pdev->dev, res); if (!info->virt_base) return -ENOMEM; info->pctrl = pinctrl_register(desc, &pdev->dev, info); if (!info->pctrl) { dev_err(&pdev->dev, "failed to register PXA pinmux driver\n"); - ret = -EINVAL; - goto err; + return -EINVAL; } pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range); platform_set_drvdata(pdev, info); return 0; -err: - iounmap(info->virt_base); - return ret; } int pxa3xx_pinctrl_unregister(struct platform_device *pdev) @@ -212,7 +207,6 @@ int pxa3xx_pinctrl_unregister(struct platform_device *pdev) struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev); pinctrl_unregister(info->pctrl); - iounmap(info->virt_base); platform_set_drvdata(pdev, NULL); return 0; } -- cgit v1.2.3 From 72facfea710afc7165e8f2fedd2e048098960b7e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 12 Nov 2012 14:46:48 +0800 Subject: pinctrl: pxa3xx: Remove phy_base and phy_size from struct pxa3xx_pinmux_info They are not used, remove them. Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-pxa3xx.c | 2 -- drivers/pinctrl/pinctrl-pxa3xx.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/pinctrl/pinctrl-pxa3xx.c b/drivers/pinctrl/pinctrl-pxa3xx.c index 43e3dd058dd..51f8a388b91 100644 --- a/drivers/pinctrl/pinctrl-pxa3xx.c +++ b/drivers/pinctrl/pinctrl-pxa3xx.c @@ -187,8 +187,6 @@ int pxa3xx_pinctrl_register(struct platform_device *pdev, res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENOENT; - info->phy_base = res->start; - info->phy_size = resource_size(res); info->virt_base = devm_request_and_ioremap(&pdev->dev, res); if (!info->virt_base) return -ENOMEM; diff --git a/drivers/pinctrl/pinctrl-pxa3xx.h b/drivers/pinctrl/pinctrl-pxa3xx.h index 8135744d659..92fad088083 100644 --- a/drivers/pinctrl/pinctrl-pxa3xx.h +++ b/drivers/pinctrl/pinctrl-pxa3xx.h @@ -60,8 +60,6 @@ struct pxa3xx_pinmux_info { struct device *dev; struct pinctrl_dev *pctrl; enum pxa_cpu_type cputype; - unsigned int phy_base; - unsigned int phy_size; void __iomem *virt_base; struct pxa3xx_mfp_pin *mfp; -- cgit v1.2.3 From edbdfa8df038a2ac83a919041327a900e2e12a25 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 14 Nov 2012 11:20:09 +0100 Subject: pinctrl/nomadik: db8500: split clkout group The clkout group is split into groups clkout1 and clkout2 which allows pins cklkout1 and clkout2 to be muxed separately. Signed-off-by: Patrice Chotard Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik-db8500.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/pinctrl-nomadik-db8500.c index 6de52e7c57f..7d88ae35211 100644 --- a/drivers/pinctrl/pinctrl-nomadik-db8500.c +++ b/drivers/pinctrl/pinctrl-nomadik-db8500.c @@ -475,8 +475,10 @@ static const unsigned hsit_a_1_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9, DB8500_PIN_AG9, DB8500_PIN_AG8, DB8500_PIN_AF8 }; static const unsigned hsit_a_2_pins[] = { DB8500_PIN_AJ9, DB8500_PIN_AH9, DB8500_PIN_AG9, DB8500_PIN_AG8 }; -static const unsigned clkout_a_1_pins[] = { DB8500_PIN_AH7, DB8500_PIN_AJ6 }; -static const unsigned clkout_a_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 }; +static const unsigned clkout1_a_1_pins[] = { DB8500_PIN_AH7 }; +static const unsigned clkout1_a_2_pins[] = { DB8500_PIN_AG7 }; +static const unsigned clkout2_a_1_pins[] = { DB8500_PIN_AJ6 }; +static const unsigned clkout2_a_2_pins[] = { DB8500_PIN_AF7 }; static const unsigned usb_a_1_pins[] = { DB8500_PIN_AF28, DB8500_PIN_AE29, DB8500_PIN_AD29, DB8500_PIN_AC29, DB8500_PIN_AD28, DB8500_PIN_AD26, DB8500_PIN_AE26, DB8500_PIN_AG29, DB8500_PIN_AE27, DB8500_PIN_AD27, @@ -592,7 +594,8 @@ static const unsigned stmmod_c_1_pins[] = { DB8500_PIN_C20, DB8500_PIN_B21, DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24 }; static const unsigned usbsim_c_1_pins[] = { DB8500_PIN_D22 }; static const unsigned mc4rstn_c_1_pins[] = { DB8500_PIN_AF25 }; -static const unsigned clkout_c_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AH12 }; +static const unsigned clkout1_c_1_pins[] = { DB8500_PIN_AH13 }; +static const unsigned clkout2_c_1_pins[] = { DB8500_PIN_AH12 }; static const unsigned i2c3_c_1_pins[] = { DB8500_PIN_AG12, DB8500_PIN_AH11 }; static const unsigned spi0_c_1_pins[] = { DB8500_PIN_AH10, DB8500_PIN_AH9, DB8500_PIN_AG9, DB8500_PIN_AG8 }; @@ -700,8 +703,10 @@ static const struct nmk_pingroup nmk_db8500_groups[] = { DB8500_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(clkout_a_1, NMK_GPIO_ALT_A), - DB8500_PIN_GROUP(clkout_a_2, NMK_GPIO_ALT_A), + DB8500_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A), + DB8500_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A), + DB8500_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A), + DB8500_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A), DB8500_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A), /* Altfunction B column */ DB8500_PIN_GROUP(trig_b_1, NMK_GPIO_ALT_B), @@ -773,7 +778,8 @@ static const struct nmk_pingroup nmk_db8500_groups[] = { DB8500_PIN_GROUP(stmmod_c_1, NMK_GPIO_ALT_C), DB8500_PIN_GROUP(usbsim_c_1, NMK_GPIO_ALT_C), DB8500_PIN_GROUP(mc4rstn_c_1, NMK_GPIO_ALT_C), - DB8500_PIN_GROUP(clkout_c_1, NMK_GPIO_ALT_C), + DB8500_PIN_GROUP(clkout1_c_1, NMK_GPIO_ALT_C), + DB8500_PIN_GROUP(clkout2_c_1, NMK_GPIO_ALT_C), DB8500_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C), DB8500_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C), DB8500_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C), @@ -851,7 +857,8 @@ DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1"); DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1"); DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1_a_2", "mc1dir_a_1"); DB8500_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2"); -DB8500_FUNC_GROUPS(clkout, "clkout_a_1", "clkout_a_2", "clkout_c_1"); +DB8500_FUNC_GROUPS(clkout, "clkout1_a_1", "clkout1_a_2", "clkout1_c_1", + "clkout2_a_1", "clkout2_a_2", "clkout2_c_1"); DB8500_FUNC_GROUPS(usb, "usb_a_1"); DB8500_FUNC_GROUPS(trig, "trig_b_1"); DB8500_FUNC_GROUPS(i2c4, "i2c4_b_1"); -- cgit v1.2.3 From 896a95ba13879ad6a595822893a8993254757c0a Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Wed, 14 Nov 2012 11:26:27 +0100 Subject: pinctrl/nomadik: db8540: split clkout group The clkout group is split into groups clkout1 and clkout2 which allows pins cklkout1 and clkout2 to be muxed separately. Signed-off-by: Patrice Chotard Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik-db8540.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/pinctrl-nomadik-db8540.c b/drivers/pinctrl/pinctrl-nomadik-db8540.c index bce0583738e..bb6a4016322 100644 --- a/drivers/pinctrl/pinctrl-nomadik-db8540.c +++ b/drivers/pinctrl/pinctrl-nomadik-db8540.c @@ -460,8 +460,10 @@ static const unsigned hsit_a_1_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10, DB8540_PIN_E10, DB8540_PIN_B12, DB8540_PIN_D10 }; static const unsigned hsit_a_2_pins[] = { DB8540_PIN_B11, DB8540_PIN_B10, DB8540_PIN_E10, DB8540_PIN_B12 }; -static const unsigned clkout_a_1_pins[] = { DB8540_PIN_D11, DB8540_PIN_AJ6 }; -static const unsigned clkout_a_2_pins[] = { DB8540_PIN_B13, DB8540_PIN_C12 }; +static const unsigned clkout1_a_1_pins[] = { DB8540_PIN_D11 }; +static const unsigned clkout1_a_2_pins[] = { DB8540_PIN_B13 }; +static const unsigned clkout2_a_1_pins[] = { DB8540_PIN_AJ6 }; +static const unsigned clkout2_a_2_pins[] = { DB8540_PIN_C12 }; static const unsigned msp4_a_1_pins[] = { DB8540_PIN_B14, DB8540_PIN_E11 }; static const unsigned usb_a_1_pins[] = { DB8540_PIN_D12, DB8540_PIN_D15, DB8540_PIN_C13, DB8540_PIN_C14, DB8540_PIN_C18, DB8540_PIN_C16, @@ -698,8 +700,10 @@ static const struct nmk_pingroup nmk_db8540_groups[] = { DB8540_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A), DB8540_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A), DB8540_PIN_GROUP(hsit_a_2, NMK_GPIO_ALT_A), - DB8540_PIN_GROUP(clkout_a_1, NMK_GPIO_ALT_A), - DB8540_PIN_GROUP(clkout_a_2, NMK_GPIO_ALT_A), + DB8540_PIN_GROUP(clkout1_a_1, NMK_GPIO_ALT_A), + DB8540_PIN_GROUP(clkout1_a_2, NMK_GPIO_ALT_A), + DB8540_PIN_GROUP(clkout2_a_1, NMK_GPIO_ALT_A), + DB8540_PIN_GROUP(clkout2_a_2, NMK_GPIO_ALT_A), DB8540_PIN_GROUP(msp4_a_1, NMK_GPIO_ALT_A), DB8540_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A), /* Altfunction B column */ @@ -831,7 +835,8 @@ static const struct nmk_pingroup nmk_db8540_groups[] = { static const char * const a##_groups[] = { b }; DB8540_FUNC_GROUPS(apetrig, "apetrig_b_1"); -DB8540_FUNC_GROUPS(clkout, "clkoutreq_a_1", "clkout_a_1", "clkout_a_2"); +DB8540_FUNC_GROUPS(clkout, "clkoutreq_a_1", "clkout1_a_1", "clkout1_a_2", + "clkout2_a_1", "clkout2_a_2"); DB8540_FUNC_GROUPS(ddrtrig, "ddrtrig_b_1"); DB8540_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2"); DB8540_FUNC_GROUPS(hwobs, "hwobs_oc4_1"); -- cgit v1.2.3 From 102caad905d919cc981f8ce799e5a63b6889b979 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 11 Nov 2012 10:31:31 +0800 Subject: pinctrl: tegra: Staticize non-exported symbols They are not referenced outside of this file, make them static. Signed-off-by: Axel Lin Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-tegra.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c index f7fe91ebd8d..e9f80a54b3d 100644 --- a/drivers/pinctrl/pinctrl-tegra.c +++ b/drivers/pinctrl/pinctrl-tegra.c @@ -178,8 +178,9 @@ static int add_config(struct device *dev, unsigned long **configs, return 0; } -void tegra_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, - struct pinctrl_map *map, unsigned num_maps) +static void tegra_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, + struct pinctrl_map *map, + unsigned num_maps) { int i; @@ -209,11 +210,11 @@ static const struct cfg_param { {"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING}, }; -int tegra_pinctrl_dt_subnode_to_map(struct device *dev, - struct device_node *np, - struct pinctrl_map **map, - unsigned *reserved_maps, - unsigned *num_maps) +static int tegra_pinctrl_dt_subnode_to_map(struct device *dev, + struct device_node *np, + struct pinctrl_map **map, + unsigned *reserved_maps, + unsigned *num_maps) { int ret, i; const char *function; @@ -288,9 +289,10 @@ exit: return ret; } -int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, - struct device_node *np_config, - struct pinctrl_map **map, unsigned *num_maps) +static int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np_config, + struct pinctrl_map **map, + unsigned *num_maps) { unsigned reserved_maps; struct device_node *np; -- cgit v1.2.3 From cbc351abe3c9bcec11c712dd41bb212748fd46d3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 15 Nov 2012 11:58:24 +0100 Subject: pinctrl/samsung: don't allow enabling pinctrl-samsung standalone The main samsung pinctrl module references the specific exynos4210 pinctrl driver, which selects the main driver in Kconfig. Making the main driver a silent "bool" option avoid this potential build error if CONFIG_PINCTRL_SAMSUNG=y && CONFIG_PINCTRL_EXYNOS4=n: drivers/built-in.o:(.rodata+0x4e4): undefined reference to `exynos4210_pin_ctrl' Signed-off-by: Arnd Bergmann Cc: Tomasz Figa Cc: Kyungmin Park Cc: Linus Walleij Acked-by: Kukjin Kim Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index d96caefd914..aeecf0f72ca 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -178,7 +178,7 @@ config PINCTRL_COH901 ports of 8 GPIO pins each. config PINCTRL_SAMSUNG - bool "Samsung pinctrl driver" + bool depends on OF && GPIOLIB select PINMUX select PINCONF -- cgit v1.2.3 From 8d1c6ef67a4530ee5dbd5038d2959a54593013b1 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 13 Nov 2012 09:00:07 +0800 Subject: pinctrl: imx: Fix the logic checking if not able to find pin reg map Current code sets "pin_reg = &info->pin_regs[i];" in each loop iteration, so in the case of no-match, pin_reg is not NULL. Signed-off-by: Axel Lin Acked-by: Dong Aisheng Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-imx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-imx.c b/drivers/pinctrl/pinctrl-imx.c index f3d2384b34b..525a2c8644f 100644 --- a/drivers/pinctrl/pinctrl-imx.c +++ b/drivers/pinctrl/pinctrl-imx.c @@ -71,7 +71,7 @@ static const struct imx_pin_reg *imx_find_pin_reg( break; } - if (!pin_reg) { + if (i == info->npin_regs) { dev_err(info->dev, "Pin(%s): unable to find pin reg map\n", info->pins[pin].name); return NULL; -- cgit v1.2.3 From 4484d0b17982af8d7af2c21bcc67e47f4237ce70 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 13 Nov 2012 15:31:41 +0800 Subject: pinctrl: spear: Fix the logic of setting reg in pmx_init_gpio_pingroup_addr Current code does not work if count > 1, fix it. Signed-off-by: Axel Lin Acked-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/pinctrl/spear/pinctrl-spear.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index 11bd8722a00..add933286e9 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -86,10 +86,10 @@ void __devinit pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup, unsigned count, u16 reg) { - int i = 0, j = 0; + int i, j; - for (; i < count; i++) - for (; j < gpio_pingroup[i].nmuxregs; j++) + for (i = 0; i < count; i++) + for (j = 0; j < gpio_pingroup[i].nmuxregs; j++) gpio_pingroup[i].muxregs[j].reg = reg; } -- cgit v1.2.3 From 80357203ec68a2c8ebcb61d2cebdf02d10369af1 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 14 Nov 2012 00:16:14 +0800 Subject: pinctrl: coh901: Return proper error if irq_domain_add_linear() fails Return -ENOMEM instead of 0 if irq_domain_add_linear fails. Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-coh901.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index 5c7daf9169e..1144dcdf2da 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -752,8 +752,10 @@ static int __init u300_gpio_probe(struct platform_device *pdev) U300_GPIO_PINS_PER_PORT, &irq_domain_simple_ops, port); - if (!port->domain) + if (!port->domain) { + err = -ENOMEM; goto err_no_domain; + } irq_set_chained_handler(port->irq, u300_gpio_irq_handler); irq_set_handler_data(port->irq, port); @@ -801,7 +803,7 @@ err_no_domain: err_no_port: u300_gpio_free_ports(gpio); clk_disable_unprepare(gpio->clk); - dev_info(&pdev->dev, "module ERROR:%d\n", err); + dev_err(&pdev->dev, "module ERROR:%d\n", err); return err; } -- cgit v1.2.3 From 6f37b1b4d407d6abcd24c4519cd892903229cd95 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 13 Nov 2012 20:20:50 +0800 Subject: pinctrl: spear: Make get_gpio_pingroup return NULL when no gpio_pingroup found Currently get_gpio_pingroup() may return NULL or ERR_PTR(-EINVAL) when no gpio_pingroup found. The caller in gpio_request_endisable() only checks if the return value is NULL. Return ERR_PTR(-EINVAL) for get_gpio_pingroup() causes problem and seems not necessary. Signed-off-by: Axel Lin Acked-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/pinctrl/spear/pinctrl-spear.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index add933286e9..bf78eb7f85c 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -286,12 +286,12 @@ static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx, unsigned pin) { struct spear_gpio_pingroup *gpio_pingroup; - int i = 0, j; + int i, j; if (!pmx->machdata->gpio_pingroups) return NULL; - for (; i < pmx->machdata->ngpio_pingroups; i++) { + for (i = 0; i < pmx->machdata->ngpio_pingroups; i++) { gpio_pingroup = &pmx->machdata->gpio_pingroups[i]; for (j = 0; j < gpio_pingroup->npins; j++) { @@ -300,7 +300,7 @@ static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx, } } - return ERR_PTR(-EINVAL); + return NULL; } static int gpio_request_endisable(struct pinctrl_dev *pctldev, -- cgit v1.2.3 From 9804049097af11b4f64a82b0e8c8078b3f2cbada Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 14 Nov 2012 16:37:45 +0800 Subject: pinctrl: plgpio: Call clk_disable_unprepare only if clk_prepare_enable is called This driver allows clk_get() failure, and still work without it. This patch adds !IS_ERR(plgpio->clk) checking in plgpio_request() error path so we only call clk_disable_unprepare() if clk_prepare_enable() is called. Signed-off-by: Axel Lin Acked-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/pinctrl/spear/pinctrl-plgpio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c index 1044ad3f3c8..cf6d9c20493 100644 --- a/drivers/pinctrl/spear/pinctrl-plgpio.c +++ b/drivers/pinctrl/spear/pinctrl-plgpio.c @@ -243,7 +243,8 @@ static int plgpio_request(struct gpio_chip *chip, unsigned offset) return 0; err1: - clk_disable_unprepare(plgpio->clk); + if (!IS_ERR(plgpio->clk)) + clk_disable_unprepare(plgpio->clk); err0: pinctrl_free_gpio(gpio); return ret; -- cgit v1.2.3 From f92bc45ffdcd28c41bb6861753deb1a68d857922 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 14 Nov 2012 14:44:07 +0530 Subject: Pinctrl/spear: plgpio: don't call prepare/unprepare SPEAr SoC's don't do anything in clk_prepare() of plgpio driver, so there is no need to call this routine multiple times. Just call it once at probe. Signed-off-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/pinctrl/spear/pinctrl-plgpio.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c index cf6d9c20493..5aebbf780fb 100644 --- a/drivers/pinctrl/spear/pinctrl-plgpio.c +++ b/drivers/pinctrl/spear/pinctrl-plgpio.c @@ -213,7 +213,7 @@ static int plgpio_request(struct gpio_chip *chip, unsigned offset) return ret; if (!IS_ERR(plgpio->clk)) { - ret = clk_prepare_enable(plgpio->clk); + ret = clk_enable(plgpio->clk); if (ret) goto err0; } @@ -244,7 +244,7 @@ static int plgpio_request(struct gpio_chip *chip, unsigned offset) err1: if (!IS_ERR(plgpio->clk)) - clk_disable_unprepare(plgpio->clk); + clk_disable(plgpio->clk); err0: pinctrl_free_gpio(gpio); return ret; @@ -275,7 +275,7 @@ static void plgpio_free(struct gpio_chip *chip, unsigned offset) disable_clk: if (!IS_ERR(plgpio->clk)) - clk_disable_unprepare(plgpio->clk); + clk_disable(plgpio->clk); pinctrl_free_gpio(gpio); } @@ -584,10 +584,18 @@ static int __devinit plgpio_probe(struct platform_device *pdev) plgpio->chip.dev = &pdev->dev; plgpio->chip.owner = THIS_MODULE; + if (!IS_ERR(plgpio->clk)) { + ret = clk_prepare(plgpio->clk); + if (ret) { + dev_err(&pdev->dev, "clk prepare failed\n"); + return ret; + } + } + ret = gpiochip_add(&plgpio->chip); if (ret) { dev_err(&pdev->dev, "unable to add gpio chip\n"); - return ret; + goto unprepare_clk; } irq = platform_get_irq(pdev, 0); @@ -629,6 +637,9 @@ remove_gpiochip: dev_info(&pdev->dev, "Remove gpiochip\n"); if (gpiochip_remove(&plgpio->chip)) dev_err(&pdev->dev, "unable to remove gpiochip\n"); +unprepare_clk: + if (!IS_ERR(plgpio->clk)) + clk_unprepare(plgpio->clk); return ret; } -- cgit v1.2.3 From 5133375bb46a0d6c3fba07097caed7aa5e629ccd Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 15 Nov 2012 13:15:37 +0100 Subject: ACPI / PM: Fix build problem when CONFIG_ACPI or CONFIG_PM is not set Commit e5cc8ef (ACPI / PM: Provide ACPI PM callback routines for subsystems) introduced a build problem occuring if CONFIG_ACPI is unset or CONFIG_PM is unset and errno.h is not included before acpi.h, because in that case ENODEV used in acpi.h is undefined. Fix the issue by making acpi.h include errno.h. Signed-off-by: Rafael J. Wysocki --- include/linux/acpi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 0676b6ac57f..5fdd8727151 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -25,6 +25,7 @@ #ifndef _LINUX_ACPI_H #define _LINUX_ACPI_H +#include #include /* for struct resource */ #ifdef CONFIG_ACPI -- cgit v1.2.3 From af451af4e0a3a4cd7536843f585c96a9b095a4e8 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Tue, 9 Oct 2012 23:26:06 -0700 Subject: mtd: nand: fix Samsung SLC NAND identification regression A combination of the following two commits caused a regression in 3.7-rc1 when identifying some Samsung NAND, so that some previously working NAND were no longer detected properly: commit e3b88bd604283ef83ae6e8f53622d5b1ffe9d43a mtd: nand: add generic READ ID length calculation functions commit e2d3a35ee427aaba99b6c68a56609ce276c51270 mtd: nand: detect Samsung K9GBG08U0A, K9GAG08U0F ID Particularly, a regression was seen on Samsung K9F2G08U0B, with the following full 8-byte READ ID string: ec da 10 95 44 00 ec da The basic problem is that Samsung manufactures both SLC and MLC NAND that use a non-standard decoding table for deriving information from their IDs. I have heuristically determined that all the chips that use the new table have ID strings which wrap around after the 6th byte. Unfortunately, I overlooked the fact that some older Samsung SLC (which use a different decoding table) have "5 byte ID strings" which also wrap around after the 6th byte. This patch re-introduces a distinction between these old and new Samsung NAND by checking that the 6th byte is non-zero, allowing both old and new Samsung NAND to be detected properly. Signed-off-by: Brian Norris Tested-by: Brian Norris Reported-by: Marek Vasut Tested-by: Marek Vasut Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ec6841d8e95..d5ece6ea6f9 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2983,13 +2983,14 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, /* * Field definitions are in the following datasheets: * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32) - * New style (6 byte ID): Samsung K9GAG08U0F (p.44) + * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) * Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22) * - * Check for ID length, cell type, and Hynix/Samsung ID to decide what - * to do. + * Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung + * ID to decide what to do. */ - if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) { + if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && + id_data[5] != 0x00) { /* Calc pagesize */ mtd->writesize = 2048 << (extid & 0x03); extid >>= 2; -- cgit v1.2.3 From 6924d99fcdf1a688538a3cdebd1f135c22eec191 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 14 Nov 2012 21:46:30 -0800 Subject: mtd: nand: fix Samsung SLC detection regression This patch fixes errors seen in identifying old Samsung SLC, due to the following commits: commit e2d3a35ee427aaba99b6c68a56609ce276c51270 mtd: nand: detect Samsung K9GBG08U0A, K9GAG08U0F ID commit e3b88bd604283ef83ae6e8f53622d5b1ffe9d43a mtd: nand: add generic READ ID length calculation functions Some Samsung NAND with "5-byte" ID really appear to have 6-byte IDs, with wraparound like: Samsung K9K8G08U0D ec d3 51 95 58 ec ec d3 Samsung K9F1G08U0C ec f1 00 95 40 ec ec f1 Samsung K9F2G08U0B ec da 10 95 44 00 ec da This bad wraparound makes it hard to reliably detect the difference between Samsung SLC with 5-byte ID and Samsung SLC with 6-byte ID. The fix is to, for now, only use the new Samsung table for MLC. We cannot support the new SLC (K9FAG08U0M) until Samsung gives better ID decode information. Note that this applies in addition to the previous regression fix: commit bc86cf7af2ebda88056538e8edff852ee627f76a mtd: nand: fix Samsung SLC NAND identification regression Together, these patches completely restore the previous detection behavior so that we cannot see any more regressions in Samsung SLC NAND (finger crossed). With luck, I can get a hold of a Samsung representative and stop having to cross my fingers eventually. Reported-by: Sylwester Nawrocki Tested-by: Sylwester Nawrocki Signed-off-by: Brian Norris Signed-off-by: Artem Bityutskiy --- drivers/mtd/nand/nand_base.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index d5ece6ea6f9..1a03b7f673c 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2990,6 +2990,7 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, * ID to decide what to do. */ if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG && + (chip->cellinfo & NAND_CI_CELLTYPE_MSK) && id_data[5] != 0x00) { /* Calc pagesize */ mtd->writesize = 2048 << (extid & 0x03); -- cgit v1.2.3 From 949a05d03490e39e773e8652ccab9157e6f595b4 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 2 Nov 2012 12:30:53 +0000 Subject: [PARISC] fix virtual aliasing issue in get_shared_area() On Thu, 2012-11-01 at 16:45 -0700, Michel Lespinasse wrote: > Looking at the arch/parisc/kernel/sys_parisc.c implementation of > get_shared_area(), I do have a concern though. The function basically > ignores the pgoff argument, so that if one creates a shared mapping of > pages 0-N of a file, and then a separate shared mapping of pages 1-N > of that same file, both will have the same cache offset for their > starting address. > > This looks like this would create obvious aliasing issues. Am I > misreading this ? I can't understand how this could work good enough > to be undetected, so there must be something I'm missing here ??? This turns out to be correct and we need to pay attention to the pgoff as well as the address when creating the virtual address for the area. Fortunately, the bug is rarely triggered as most applications which use pgoff tend to use large values (git being the primary one, and it uses pgoff in multiples of 16MB) which are larger than our cache coherency modulus, so the problem isn't often seen in practise. Reported-by: Michel Lespinasse Cc: Signed-off-by: James Bottomley --- arch/parisc/kernel/sys_parisc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 7426e40699b..f76c10863c6 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -73,6 +73,8 @@ static unsigned long get_shared_area(struct address_space *mapping, struct vm_area_struct *vma; int offset = mapping ? get_offset(mapping) : 0; + offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000; + addr = DCACHE_ALIGN(addr - offset) + offset; for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { -- cgit v1.2.3 From e7ed671825d7d8ee7225a9e1de997d643e6d5d69 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 7 Nov 2012 23:19:42 +0800 Subject: pinctrl: single: dump pinmux register value Dump pinmux register value, not only function part in the pinmux register. Also fix the issue on caluclating pin offset. The last parameter should be pin number, not register offset. Signed-off-by: Haojian Zhuang Acked-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 726a729a2ec..145025f5008 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -244,15 +244,15 @@ static int pcs_get_group_pins(struct pinctrl_dev *pctldev, static void pcs_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, - unsigned offset) + unsigned pin) { struct pcs_device *pcs; - unsigned val; + unsigned val, mux_bytes; pcs = pinctrl_dev_get_drvdata(pctldev); - val = pcs->read(pcs->base + offset); - val &= pcs->fmask; + mux_bytes = pcs->width / BITS_PER_BYTE; + val = pcs->read(pcs->base + pin * mux_bytes); seq_printf(s, "%08x %s " , val, DRIVER_NAME); } -- cgit v1.2.3 From b9196395c905edec512dfd6690428084228c16ec Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 14 Nov 2012 09:10:39 -0500 Subject: drm/radeon: fix logic error in atombios_encoders.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=50431 Reported-by: David Binderman Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Reviewed-by: Michel Dänzer --- drivers/gpu/drm/radeon/atombios_encoders.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index ba498f8e47a..010bae19554 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1625,7 +1625,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); /* some early dce3.2 boards have a bug in their transmitter control table */ - if ((rdev->family != CHIP_RV710) || (rdev->family != CHIP_RV730)) + if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730)) atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); } if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { -- cgit v1.2.3 From ae289dc1f474ff380e9d7601f02e4d766cbba408 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 15 Nov 2012 09:22:40 +0100 Subject: s390/3215: fix tty close handling The 3215 console always has the RAW3215_FIXED flag set, which causes raw3215_shutdown() not to wait for outstanding I/O requests if an attached tty gets closed. The flag however can be simply removed, so we can guarantee that all requests belonging to the tty have been processed when the tty is closed. However the tasklet that belongs to the 3215 device may be scheduled even if there is no tty attached anymore, since we have a race between console and tty processing. Thefore unconditional tty_wakekup() in raw3215_wakeup() can cause the following NULL pointer dereference: 3.465368 Unable to handle kernel pointer dereference at virtual kernel address (null) 3.465448 Oops: 0004 #1 SMP 3.465454 Modules linked in: 3.465459 CPU: 1 Not tainted 3.6.0 #1 3.465462 Process swapper/1 (pid: 0, task: 000000003ffa4428, ksp: 000000003ffb7ce0) 3.465466 Krnl PSW : 0404100180000000 0000000000162f86 (__wake_up+0x46/0xb8) 3.465480 R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:0 CC:1 PM:0 EA:3 Krnl GPRS: fffffffffffffffe 0000000000000000 0000000000000160 0000000000000001 3.465492 0000000000000001 0000000000000004 0000000000000004 000000000096b490 3.465499 0000000000000001 0000000000000100 0000000000000001 0000000000000001 3.465506 070000003fc87d60 0000000000000160 000000003fc87d68 000000003fc87d00 3.465526 Krnl Code: 0000000000162f76: e3c0f0a80004 lg %r12,168(%r15) 0000000000162f7c: 58000370 l %r0,880 #0000000000162f80: c007ffffffff00 xilf %r0,4294967295 >0000000000162f86: ba102000 cs %r1,%r0,0(%r2) 0000000000162f8a: 1211 ltr %r1,%r1 0000000000162f8c: a774002f brc 7,162fea 0000000000162f90: b904002d lgr %r2,%r13 0000000000162f94: b904003a lgr %r3,%r10 3.465597 Call Trace: 3.465599 (<0400000000000000> 0x400000000000000) 3.465602 <000000000048c77e> raw3215_wakeup+0x2e/0x40 3.465607 <0000000000134d66> tasklet_action+0x96/0x168 3.465612 <000000000013423c> __do_softirq+0xd8/0x21c 3.465615 <0000000000134678> irq_exit+0xa8/0xac 3.465617 <000000000046c232> do_IRQ+0x182/0x248 3.465621 <00000000005c8296> io_return+0x0/0x8 3.465625 <00000000005c7cac> vtime_stop_cpu+0x4c/0xb8 3.465629 (<0000000000194e06> tick_nohz_idle_enter+0x4e/0x74) 3.465633 <0000000000104760> cpu_idle+0x170/0x184 3.465636 <00000000005b5182> smp_start_secondary+0xd6/0xe0 3.465641 <00000000005c86be> restart_int_handler+0x56/0x6c 3.465643 <0000000000000000> 0x0 3.465645 Last Breaking-Event-Address: 3.465647 <0000000000403136> tty_wakeup+0x46/0x98 3.465652 3.465654 Kernel panic - not syncing: Fatal exception in interrupt 01: HCPGIR450W CP entered; disabled wait PSW 00020001 80000000 00000000 0010F63C The easiest solution is simply to check if tty is NULL in the tasklet. If it is NULL nothing is to do (no tty attached), otherwise tty_wakeup() can be called, since we hold a reference to the tty. This is not nice... but it is a small patch and it works. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/s390/char/con3215.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 9ffb6d5f17a..4ed343e4eb4 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -44,7 +44,6 @@ #define RAW3215_NR_CCWS 3 #define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ -#define RAW3215_FIXED 1 /* 3215 console device is not be freed */ #define RAW3215_WORKING 4 /* set if a request is being worked on */ #define RAW3215_THROTTLED 8 /* set if reading is disabled */ #define RAW3215_STOPPED 16 /* set if writing is disabled */ @@ -339,8 +338,10 @@ static void raw3215_wakeup(unsigned long data) struct tty_struct *tty; tty = tty_port_tty_get(&raw->port); - tty_wakeup(tty); - tty_kref_put(tty); + if (tty) { + tty_wakeup(tty); + tty_kref_put(tty); + } } /* @@ -629,8 +630,7 @@ static void raw3215_shutdown(struct raw3215_info *raw) DECLARE_WAITQUEUE(wait, current); unsigned long flags; - if (!(raw->port.flags & ASYNC_INITIALIZED) || - (raw->flags & RAW3215_FIXED)) + if (!(raw->port.flags & ASYNC_INITIALIZED)) return; /* Wait for outstanding requests, then free irq */ spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); @@ -926,8 +926,6 @@ static int __init con3215_init(void) dev_set_drvdata(&cdev->dev, raw); cdev->handler = raw3215_irq; - raw->flags |= RAW3215_FIXED; - /* Request the console irq */ if (raw3215_startup(raw) != 0) { raw3215_free_info(raw); -- cgit v1.2.3 From 953e9e93862871e005bdcde3b98db822d12185a8 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 15 Nov 2012 12:56:05 +0800 Subject: pinctrl: nomadik: Prevent NULL dereference if of_match_device returns NULL of_match_device() may return NULL. Signed-off-by: Axel Lin Acked-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 6a95d0438b6..98c088ae7f4 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -1864,9 +1864,14 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) if (platid) version = platid->driver_data; - else if (np) - version = (unsigned int) - of_match_device(nmk_pinctrl_match, &pdev->dev)->data; + else if (np) { + const struct of_device_id *match; + + match = of_match_device(nmk_pinctrl_match, &pdev->dev); + if (!match) + return -ENODEV; + version = (unsigned int) match->data; + } /* Poke in other ASIC variants here */ if (version == PINCTRL_NMK_STN8815) -- cgit v1.2.3 From 16c4c52435cf8bb6e5986c14d36d93a0dd4c98df Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 13 Nov 2012 18:16:43 +0100 Subject: bindings: i2c: use consistent naming for i2c binding descriptions Filenames of devictree binding documentation seems to be arbitrary and for me it is unneeded hazzle to find the corresponding documentation for a specific driver. Naming the description the same as the driver is a lot easier and makes sense to me since the driver defines the binding it understands. Also, remove a reference in one source to the binding documentation, since path information easily gets stale. Signed-off-by: Wolfram Sang Cc: Rob Herring Cc: Grant Likely Signed-off-by: Grant Likely --- .../devicetree/bindings/i2c/arm-versatile.txt | 10 --- .../devicetree/bindings/i2c/atmel-i2c.txt | 30 ------- .../devicetree/bindings/i2c/cavium-i2c.txt | 34 -------- .../devicetree/bindings/i2c/ce4100-i2c.txt | 93 ---------------------- Documentation/devicetree/bindings/i2c/davinci.txt | 28 ------- Documentation/devicetree/bindings/i2c/fsl-i2c.txt | 64 --------------- .../devicetree/bindings/i2c/fsl-imx-i2c.txt | 25 ------ Documentation/devicetree/bindings/i2c/gpio-i2c.txt | 32 -------- Documentation/devicetree/bindings/i2c/i2c-at91.txt | 30 +++++++ .../devicetree/bindings/i2c/i2c-davinci.txt | 28 +++++++ Documentation/devicetree/bindings/i2c/i2c-gpio.txt | 32 ++++++++ Documentation/devicetree/bindings/i2c/i2c-imx.txt | 25 ++++++ Documentation/devicetree/bindings/i2c/i2c-mpc.txt | 64 +++++++++++++++ Documentation/devicetree/bindings/i2c/i2c-mux.txt | 60 ++++++++++++++ .../devicetree/bindings/i2c/i2c-mv64xxx.txt | 18 +++++ .../devicetree/bindings/i2c/i2c-nomadik.txt | 23 ++++++ .../devicetree/bindings/i2c/i2c-octeon.txt | 34 ++++++++ Documentation/devicetree/bindings/i2c/i2c-omap.txt | 30 +++++++ Documentation/devicetree/bindings/i2c/i2c-pnx.txt | 36 +++++++++ .../devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt | 93 ++++++++++++++++++++++ Documentation/devicetree/bindings/i2c/i2c-pxa.txt | 33 ++++++++ .../devicetree/bindings/i2c/i2c-s3c2410.txt | 43 ++++++++++ Documentation/devicetree/bindings/i2c/i2c-sirf.txt | 19 +++++ .../devicetree/bindings/i2c/i2c-versatile.txt | 10 +++ Documentation/devicetree/bindings/i2c/i2c-xiic.txt | 22 +++++ Documentation/devicetree/bindings/i2c/mrvl-i2c.txt | 51 ------------ Documentation/devicetree/bindings/i2c/mux.txt | 60 -------------- Documentation/devicetree/bindings/i2c/nomadik.txt | 23 ------ Documentation/devicetree/bindings/i2c/omap-i2c.txt | 30 ------- Documentation/devicetree/bindings/i2c/pnx.txt | 36 --------- .../devicetree/bindings/i2c/samsung-i2c.txt | 43 ---------- Documentation/devicetree/bindings/i2c/sirf-i2c.txt | 19 ----- Documentation/devicetree/bindings/i2c/xiic.txt | 22 ----- drivers/i2c/busses/i2c-ocores.c | 4 - 34 files changed, 600 insertions(+), 604 deletions(-) delete mode 100644 Documentation/devicetree/bindings/i2c/arm-versatile.txt delete mode 100644 Documentation/devicetree/bindings/i2c/atmel-i2c.txt delete mode 100644 Documentation/devicetree/bindings/i2c/cavium-i2c.txt delete mode 100644 Documentation/devicetree/bindings/i2c/ce4100-i2c.txt delete mode 100644 Documentation/devicetree/bindings/i2c/davinci.txt delete mode 100644 Documentation/devicetree/bindings/i2c/fsl-i2c.txt delete mode 100644 Documentation/devicetree/bindings/i2c/fsl-imx-i2c.txt delete mode 100644 Documentation/devicetree/bindings/i2c/gpio-i2c.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-at91.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-davinci.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-gpio.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-imx.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mpc.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mux.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-nomadik.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-octeon.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-omap.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-pnx.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-pxa.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-sirf.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-versatile.txt create mode 100644 Documentation/devicetree/bindings/i2c/i2c-xiic.txt delete mode 100644 Documentation/devicetree/bindings/i2c/mrvl-i2c.txt delete mode 100644 Documentation/devicetree/bindings/i2c/mux.txt delete mode 100644 Documentation/devicetree/bindings/i2c/nomadik.txt delete mode 100644 Documentation/devicetree/bindings/i2c/omap-i2c.txt delete mode 100644 Documentation/devicetree/bindings/i2c/pnx.txt delete mode 100644 Documentation/devicetree/bindings/i2c/samsung-i2c.txt delete mode 100644 Documentation/devicetree/bindings/i2c/sirf-i2c.txt delete mode 100644 Documentation/devicetree/bindings/i2c/xiic.txt diff --git a/Documentation/devicetree/bindings/i2c/arm-versatile.txt b/Documentation/devicetree/bindings/i2c/arm-versatile.txt deleted file mode 100644 index 361d31c51b6..00000000000 --- a/Documentation/devicetree/bindings/i2c/arm-versatile.txt +++ /dev/null @@ -1,10 +0,0 @@ -i2c Controller on ARM Versatile platform: - -Required properties: -- compatible : Must be "arm,versatile-i2c"; -- reg -- #address-cells = <1>; -- #size-cells = <0>; - -Optional properties: -- Child nodes conforming to i2c bus binding diff --git a/Documentation/devicetree/bindings/i2c/atmel-i2c.txt b/Documentation/devicetree/bindings/i2c/atmel-i2c.txt deleted file mode 100644 index b689a0d9441..00000000000 --- a/Documentation/devicetree/bindings/i2c/atmel-i2c.txt +++ /dev/null @@ -1,30 +0,0 @@ -I2C for Atmel platforms - -Required properties : -- compatible : Must be "atmel,at91rm9200-i2c", "atmel,at91sam9261-i2c", - "atmel,at91sam9260-i2c", "atmel,at91sam9g20-i2c", "atmel,at91sam9g10-i2c" - or "atmel,at91sam9x5-i2c" -- reg: physical base address of the controller and length of memory mapped - region. -- interrupts: interrupt number to the cpu. -- #address-cells = <1>; -- #size-cells = <0>; - -Optional properties: -- Child nodes conforming to i2c bus binding - -Examples : - -i2c0: i2c@fff84000 { - compatible = "atmel,at91sam9g20-i2c"; - reg = <0xfff84000 0x100>; - interrupts = <12 4 6>; - #address-cells = <1>; - #size-cells = <0>; - - 24c512@50 { - compatible = "24c512"; - reg = <0x50>; - pagesize = <128>; - } -} diff --git a/Documentation/devicetree/bindings/i2c/cavium-i2c.txt b/Documentation/devicetree/bindings/i2c/cavium-i2c.txt deleted file mode 100644 index dced82ebe31..00000000000 --- a/Documentation/devicetree/bindings/i2c/cavium-i2c.txt +++ /dev/null @@ -1,34 +0,0 @@ -* Two Wire Serial Interface (TWSI) / I2C - -- compatible: "cavium,octeon-3860-twsi" - - Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs. - -- reg: The base address of the TWSI/I2C bus controller register bank. - -- #address-cells: Must be <1>. - -- #size-cells: Must be <0>. I2C addresses have no size component. - -- interrupts: A single interrupt specifier. - -- clock-frequency: The I2C bus clock rate in Hz. - -Example: - twsi0: i2c@1180000001000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "cavium,octeon-3860-twsi"; - reg = <0x11800 0x00001000 0x0 0x200>; - interrupts = <0 45>; - clock-frequency = <100000>; - - rtc@68 { - compatible = "dallas,ds1337"; - reg = <0x68>; - }; - tmp@4c { - compatible = "ti,tmp421"; - reg = <0x4c>; - }; - }; diff --git a/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt b/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt deleted file mode 100644 index 569b1624851..00000000000 --- a/Documentation/devicetree/bindings/i2c/ce4100-i2c.txt +++ /dev/null @@ -1,93 +0,0 @@ -CE4100 I2C ----------- - -CE4100 has one PCI device which is described as the I2C-Controller. This -PCI device has three PCI-bars, each bar contains a complete I2C -controller. So we have a total of three independent I2C-Controllers -which share only an interrupt line. -The driver is probed via the PCI-ID and is gathering the information of -attached devices from the devices tree. -Grant Likely recommended to use the ranges property to map the PCI-Bar -number to its physical address and to use this to find the child nodes -of the specific I2C controller. This were his exact words: - - Here's where the magic happens. Each entry in - ranges describes how the parent pci address space - (middle group of 3) is translated to the local - address space (first group of 2) and the size of - each range (last cell). In this particular case, - the first cell of the local address is chosen to be - 1:1 mapped to the BARs, and the second is the - offset from be base of the BAR (which would be - non-zero if you had 2 or more devices mapped off - the same BAR) - - ranges allows the address mapping to be described - in a way that the OS can interpret without - requiring custom device driver code. - -This is an example which is used on FalconFalls: ------------------------------------------------- - i2c-controller@b,2 { - #address-cells = <2>; - #size-cells = <1>; - compatible = "pci8086,2e68.2", - "pci8086,2e68", - "pciclass,ff0000", - "pciclass,ff00"; - - reg = <0x15a00 0x0 0x0 0x0 0x0>; - interrupts = <16 1>; - - /* as described by Grant, the first number in the group of - * three is the bar number followed by the 64bit bar address - * followed by size of the mapping. The bar address - * requires also a valid translation in parents ranges - * property. - */ - ranges = <0 0 0x02000000 0 0xdffe0500 0x100 - 1 0 0x02000000 0 0xdffe0600 0x100 - 2 0 0x02000000 0 0xdffe0700 0x100>; - - i2c@0 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "intel,ce4100-i2c-controller"; - - /* The first number in the reg property is the - * number of the bar - */ - reg = <0 0 0x100>; - - /* This I2C controller has no devices */ - }; - - i2c@1 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "intel,ce4100-i2c-controller"; - reg = <1 0 0x100>; - - /* This I2C controller has one gpio controller */ - gpio@26 { - #gpio-cells = <2>; - compatible = "ti,pcf8575"; - reg = <0x26>; - gpio-controller; - }; - }; - - i2c@2 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "intel,ce4100-i2c-controller"; - reg = <2 0 0x100>; - - gpio@26 { - #gpio-cells = <2>; - compatible = "ti,pcf8575"; - reg = <0x26>; - gpio-controller; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/i2c/davinci.txt b/Documentation/devicetree/bindings/i2c/davinci.txt deleted file mode 100644 index 2dc935b4113..00000000000 --- a/Documentation/devicetree/bindings/i2c/davinci.txt +++ /dev/null @@ -1,28 +0,0 @@ -* Texas Instruments Davinci I2C - -This file provides information, what the device node for the -davinci i2c interface contain. - -Required properties: -- compatible: "ti,davinci-i2c"; -- reg : Offset and length of the register set for the device - -Recommended properties : -- interrupts : standard interrupt property. -- clock-frequency : desired I2C bus clock frequency in Hz. - -Example (enbw_cmc board): - i2c@1c22000 { - compatible = "ti,davinci-i2c"; - reg = <0x22000 0x1000>; - clock-frequency = <100000>; - interrupts = <15>; - interrupt-parent = <&intc>; - #address-cells = <1>; - #size-cells = <0>; - - dtt@48 { - compatible = "national,lm75"; - reg = <0x48>; - }; - }; diff --git a/Documentation/devicetree/bindings/i2c/fsl-i2c.txt b/Documentation/devicetree/bindings/i2c/fsl-i2c.txt deleted file mode 100644 index 1eacd6b20ed..00000000000 --- a/Documentation/devicetree/bindings/i2c/fsl-i2c.txt +++ /dev/null @@ -1,64 +0,0 @@ -* I2C - -Required properties : - - - reg : Offset and length of the register set for the device - - compatible : should be "fsl,CHIP-i2c" where CHIP is the name of a - compatible processor, e.g. mpc8313, mpc8543, mpc8544, mpc5121, - mpc5200 or mpc5200b. For the mpc5121, an additional node - "fsl,mpc5121-i2c-ctrl" is required as shown in the example below. - -Recommended properties : - - - interrupts : where a is the interrupt number and b is a - field that represents an encoding of the sense and level - information for the interrupt. This should be encoded based on - the information in section 2) depending on the type of interrupt - controller you have. - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - fsl,preserve-clocking : boolean; if defined, the clock settings - from the bootloader are preserved (not touched). - - clock-frequency : desired I2C bus clock frequency in Hz. - - fsl,timeout : I2C bus timeout in microseconds. - -Examples : - - /* MPC5121 based board */ - i2c@1740 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5121-i2c", "fsl-i2c"; - reg = <0x1740 0x20>; - interrupts = <11 0x8>; - interrupt-parent = <&ipic>; - clock-frequency = <100000>; - }; - - i2ccontrol@1760 { - compatible = "fsl,mpc5121-i2c-ctrl"; - reg = <0x1760 0x8>; - }; - - /* MPC5200B based board */ - i2c@3d00 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; - reg = <0x3d00 0x40>; - interrupts = <2 15 0>; - interrupt-parent = <&mpc5200_pic>; - fsl,preserve-clocking; - }; - - /* MPC8544 base board */ - i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,mpc8544-i2c", "fsl-i2c"; - reg = <0x3100 0x100>; - interrupts = <43 2>; - interrupt-parent = <&mpic>; - clock-frequency = <400000>; - fsl,timeout = <10000>; - }; diff --git a/Documentation/devicetree/bindings/i2c/fsl-imx-i2c.txt b/Documentation/devicetree/bindings/i2c/fsl-imx-i2c.txt deleted file mode 100644 index f3cf43b66f7..00000000000 --- a/Documentation/devicetree/bindings/i2c/fsl-imx-i2c.txt +++ /dev/null @@ -1,25 +0,0 @@ -* Freescale Inter IC (I2C) and High Speed Inter IC (HS-I2C) for i.MX - -Required properties: -- compatible : Should be "fsl,-i2c" -- reg : Should contain I2C/HS-I2C registers location and length -- interrupts : Should contain I2C/HS-I2C interrupt - -Optional properties: -- clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz. - The absence of the propoerty indicates the default frequency 100 kHz. - -Examples: - -i2c@83fc4000 { /* I2C2 on i.MX51 */ - compatible = "fsl,imx51-i2c", "fsl,imx1-i2c"; - reg = <0x83fc4000 0x4000>; - interrupts = <63>; -}; - -i2c@70038000 { /* HS-I2C on i.MX51 */ - compatible = "fsl,imx51-i2c", "fsl,imx1-i2c"; - reg = <0x70038000 0x4000>; - interrupts = <64>; - clock-frequency = <400000>; -}; diff --git a/Documentation/devicetree/bindings/i2c/gpio-i2c.txt b/Documentation/devicetree/bindings/i2c/gpio-i2c.txt deleted file mode 100644 index 4f8ec947c6b..00000000000 --- a/Documentation/devicetree/bindings/i2c/gpio-i2c.txt +++ /dev/null @@ -1,32 +0,0 @@ -Device-Tree bindings for i2c gpio driver - -Required properties: - - compatible = "i2c-gpio"; - - gpios: sda and scl gpio - - -Optional properties: - - i2c-gpio,sda-open-drain: sda as open drain - - i2c-gpio,scl-open-drain: scl as open drain - - i2c-gpio,scl-output-only: scl as output only - - i2c-gpio,delay-us: delay between GPIO operations (may depend on each platform) - - i2c-gpio,timeout-ms: timeout to get data - -Example nodes: - -i2c@0 { - compatible = "i2c-gpio"; - gpios = <&pioA 23 0 /* sda */ - &pioA 24 0 /* scl */ - >; - i2c-gpio,sda-open-drain; - i2c-gpio,scl-open-drain; - i2c-gpio,delay-us = <2>; /* ~100 kHz */ - #address-cells = <1>; - #size-cells = <0>; - - rv3029c2@56 { - compatible = "rv3029c2"; - reg = <0x56>; - }; -}; diff --git a/Documentation/devicetree/bindings/i2c/i2c-at91.txt b/Documentation/devicetree/bindings/i2c/i2c-at91.txt new file mode 100644 index 00000000000..b689a0d9441 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-at91.txt @@ -0,0 +1,30 @@ +I2C for Atmel platforms + +Required properties : +- compatible : Must be "atmel,at91rm9200-i2c", "atmel,at91sam9261-i2c", + "atmel,at91sam9260-i2c", "atmel,at91sam9g20-i2c", "atmel,at91sam9g10-i2c" + or "atmel,at91sam9x5-i2c" +- reg: physical base address of the controller and length of memory mapped + region. +- interrupts: interrupt number to the cpu. +- #address-cells = <1>; +- #size-cells = <0>; + +Optional properties: +- Child nodes conforming to i2c bus binding + +Examples : + +i2c0: i2c@fff84000 { + compatible = "atmel,at91sam9g20-i2c"; + reg = <0xfff84000 0x100>; + interrupts = <12 4 6>; + #address-cells = <1>; + #size-cells = <0>; + + 24c512@50 { + compatible = "24c512"; + reg = <0x50>; + pagesize = <128>; + } +} diff --git a/Documentation/devicetree/bindings/i2c/i2c-davinci.txt b/Documentation/devicetree/bindings/i2c/i2c-davinci.txt new file mode 100644 index 00000000000..2dc935b4113 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-davinci.txt @@ -0,0 +1,28 @@ +* Texas Instruments Davinci I2C + +This file provides information, what the device node for the +davinci i2c interface contain. + +Required properties: +- compatible: "ti,davinci-i2c"; +- reg : Offset and length of the register set for the device + +Recommended properties : +- interrupts : standard interrupt property. +- clock-frequency : desired I2C bus clock frequency in Hz. + +Example (enbw_cmc board): + i2c@1c22000 { + compatible = "ti,davinci-i2c"; + reg = <0x22000 0x1000>; + clock-frequency = <100000>; + interrupts = <15>; + interrupt-parent = <&intc>; + #address-cells = <1>; + #size-cells = <0>; + + dtt@48 { + compatible = "national,lm75"; + reg = <0x48>; + }; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt new file mode 100644 index 00000000000..4f8ec947c6b --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-gpio.txt @@ -0,0 +1,32 @@ +Device-Tree bindings for i2c gpio driver + +Required properties: + - compatible = "i2c-gpio"; + - gpios: sda and scl gpio + + +Optional properties: + - i2c-gpio,sda-open-drain: sda as open drain + - i2c-gpio,scl-open-drain: scl as open drain + - i2c-gpio,scl-output-only: scl as output only + - i2c-gpio,delay-us: delay between GPIO operations (may depend on each platform) + - i2c-gpio,timeout-ms: timeout to get data + +Example nodes: + +i2c@0 { + compatible = "i2c-gpio"; + gpios = <&pioA 23 0 /* sda */ + &pioA 24 0 /* scl */ + >; + i2c-gpio,sda-open-drain; + i2c-gpio,scl-open-drain; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; + #size-cells = <0>; + + rv3029c2@56 { + compatible = "rv3029c2"; + reg = <0x56>; + }; +}; diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.txt b/Documentation/devicetree/bindings/i2c/i2c-imx.txt new file mode 100644 index 00000000000..f3cf43b66f7 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-imx.txt @@ -0,0 +1,25 @@ +* Freescale Inter IC (I2C) and High Speed Inter IC (HS-I2C) for i.MX + +Required properties: +- compatible : Should be "fsl,-i2c" +- reg : Should contain I2C/HS-I2C registers location and length +- interrupts : Should contain I2C/HS-I2C interrupt + +Optional properties: +- clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz. + The absence of the propoerty indicates the default frequency 100 kHz. + +Examples: + +i2c@83fc4000 { /* I2C2 on i.MX51 */ + compatible = "fsl,imx51-i2c", "fsl,imx1-i2c"; + reg = <0x83fc4000 0x4000>; + interrupts = <63>; +}; + +i2c@70038000 { /* HS-I2C on i.MX51 */ + compatible = "fsl,imx51-i2c", "fsl,imx1-i2c"; + reg = <0x70038000 0x4000>; + interrupts = <64>; + clock-frequency = <400000>; +}; diff --git a/Documentation/devicetree/bindings/i2c/i2c-mpc.txt b/Documentation/devicetree/bindings/i2c/i2c-mpc.txt new file mode 100644 index 00000000000..1eacd6b20ed --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-mpc.txt @@ -0,0 +1,64 @@ +* I2C + +Required properties : + + - reg : Offset and length of the register set for the device + - compatible : should be "fsl,CHIP-i2c" where CHIP is the name of a + compatible processor, e.g. mpc8313, mpc8543, mpc8544, mpc5121, + mpc5200 or mpc5200b. For the mpc5121, an additional node + "fsl,mpc5121-i2c-ctrl" is required as shown in the example below. + +Recommended properties : + + - interrupts : where a is the interrupt number and b is a + field that represents an encoding of the sense and level + information for the interrupt. This should be encoded based on + the information in section 2) depending on the type of interrupt + controller you have. + - interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. + - fsl,preserve-clocking : boolean; if defined, the clock settings + from the bootloader are preserved (not touched). + - clock-frequency : desired I2C bus clock frequency in Hz. + - fsl,timeout : I2C bus timeout in microseconds. + +Examples : + + /* MPC5121 based board */ + i2c@1740 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5121-i2c", "fsl-i2c"; + reg = <0x1740 0x20>; + interrupts = <11 0x8>; + interrupt-parent = <&ipic>; + clock-frequency = <100000>; + }; + + i2ccontrol@1760 { + compatible = "fsl,mpc5121-i2c-ctrl"; + reg = <0x1760 0x8>; + }; + + /* MPC5200B based board */ + i2c@3d00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; + reg = <0x3d00 0x40>; + interrupts = <2 15 0>; + interrupt-parent = <&mpc5200_pic>; + fsl,preserve-clocking; + }; + + /* MPC8544 base board */ + i2c@3100 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,mpc8544-i2c", "fsl-i2c"; + reg = <0x3100 0x100>; + interrupts = <43 2>; + interrupt-parent = <&mpic>; + clock-frequency = <400000>; + fsl,timeout = <10000>; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-mux.txt b/Documentation/devicetree/bindings/i2c/i2c-mux.txt new file mode 100644 index 00000000000..af84cce5cd7 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-mux.txt @@ -0,0 +1,60 @@ +Common i2c bus multiplexer/switch properties. + +An i2c bus multiplexer/switch will have several child busses that are +numbered uniquely in a device dependent manner. The nodes for an i2c bus +multiplexer/switch will have one child node for each child +bus. + +Required properties: +- #address-cells = <1>; +- #size-cells = <0>; + +Required properties for child nodes: +- #address-cells = <1>; +- #size-cells = <0>; +- reg : The sub-bus number. + +Optional properties for child nodes: +- Other properties specific to the multiplexer/switch hardware. +- Child nodes conforming to i2c bus binding + + +Example : + + /* + An NXP pca9548 8 channel I2C multiplexer at address 0x70 + with two NXP pca8574 GPIO expanders attached, one each to + ports 3 and 4. + */ + + mux@70 { + compatible = "nxp,pca9548"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + gpio1: gpio@38 { + compatible = "nxp,pca8574"; + reg = <0x38>; + #gpio-cells = <2>; + gpio-controller; + }; + }; + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + + gpio2: gpio@38 { + compatible = "nxp,pca8574"; + reg = <0x38>; + #gpio-cells = <2>; + gpio-controller; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt new file mode 100644 index 00000000000..f46d928aa73 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt @@ -0,0 +1,18 @@ + +* Marvell MV64XXX I2C controller + +Required properties : + + - reg : Offset and length of the register set for the device + - compatible : Should be "marvell,mv64xxx-i2c" + - interrupts : The interrupt number + - clock-frequency : Desired I2C bus clock frequency in Hz. + +Examples: + + i2c@11000 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x11000 0x20>; + interrupts = <29>; + clock-frequency = <100000>; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-nomadik.txt b/Documentation/devicetree/bindings/i2c/i2c-nomadik.txt new file mode 100644 index 00000000000..72065b0ff68 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-nomadik.txt @@ -0,0 +1,23 @@ +I2C for Nomadik based systems + +Required (non-standard) properties: + - Nil + +Recommended (non-standard) properties: + - clock-frequency : Maximum bus clock frequency for the device + +Optional (non-standard) properties: + - Nil + +Example : + +i2c@80004000 { + compatible = "stericsson,db8500-i2c", "st,nomadik-i2c"; + reg = <0x80004000 0x1000>; + interrupts = <0 21 0x4>; + #address-cells = <1>; + #size-cells = <0>; + v-i2c-supply = <&db8500_vape_reg>; + + clock-frequency = <400000>; +}; diff --git a/Documentation/devicetree/bindings/i2c/i2c-octeon.txt b/Documentation/devicetree/bindings/i2c/i2c-octeon.txt new file mode 100644 index 00000000000..dced82ebe31 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-octeon.txt @@ -0,0 +1,34 @@ +* Two Wire Serial Interface (TWSI) / I2C + +- compatible: "cavium,octeon-3860-twsi" + + Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs. + +- reg: The base address of the TWSI/I2C bus controller register bank. + +- #address-cells: Must be <1>. + +- #size-cells: Must be <0>. I2C addresses have no size component. + +- interrupts: A single interrupt specifier. + +- clock-frequency: The I2C bus clock rate in Hz. + +Example: + twsi0: i2c@1180000001000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cavium,octeon-3860-twsi"; + reg = <0x11800 0x00001000 0x0 0x200>; + interrupts = <0 45>; + clock-frequency = <100000>; + + rtc@68 { + compatible = "dallas,ds1337"; + reg = <0x68>; + }; + tmp@4c { + compatible = "ti,tmp421"; + reg = <0x4c>; + }; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-omap.txt b/Documentation/devicetree/bindings/i2c/i2c-omap.txt new file mode 100644 index 00000000000..56564aa4b44 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-omap.txt @@ -0,0 +1,30 @@ +I2C for OMAP platforms + +Required properties : +- compatible : Must be "ti,omap3-i2c" or "ti,omap4-i2c" +- ti,hwmods : Must be "i2c", n being the instance number (1-based) +- #address-cells = <1>; +- #size-cells = <0>; + +Recommended properties : +- clock-frequency : Desired I2C bus clock frequency in Hz. Otherwise + the default 100 kHz frequency will be used. + +Optional properties: +- Child nodes conforming to i2c bus binding + +Note: Current implementation will fetch base address, irq and dma +from omap hwmod data base during device registration. +Future plan is to migrate hwmod data base contents into device tree +blob so that, all the required data will be used from device tree dts +file. + +Examples : + +i2c1: i2c@0 { + compatible = "ti,omap3-i2c"; + #address-cells = <1>; + #size-cells = <0>; + ti,hwmods = "i2c1"; + clock-frequency = <400000>; +}; diff --git a/Documentation/devicetree/bindings/i2c/i2c-pnx.txt b/Documentation/devicetree/bindings/i2c/i2c-pnx.txt new file mode 100644 index 00000000000..fe98ada33ee --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-pnx.txt @@ -0,0 +1,36 @@ +* NXP PNX I2C Controller + +Required properties: + + - reg: Offset and length of the register set for the device + - compatible: should be "nxp,pnx-i2c" + - interrupts: configure one interrupt line + - #address-cells: always 1 (for i2c addresses) + - #size-cells: always 0 + - interrupt-parent: the phandle for the interrupt controller that + services interrupts for this device. + +Optional properties: + + - clock-frequency: desired I2C bus clock frequency in Hz, Default: 100000 Hz + +Examples: + + i2c1: i2c@400a0000 { + compatible = "nxp,pnx-i2c"; + reg = <0x400a0000 0x100>; + interrupt-parent = <&mic>; + interrupts = <51 0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c2: i2c@400a8000 { + compatible = "nxp,pnx-i2c"; + reg = <0x400a8000 0x100>; + interrupt-parent = <&mic>; + interrupts = <50 0>; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt b/Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt new file mode 100644 index 00000000000..569b1624851 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-pxa-pci-ce4100.txt @@ -0,0 +1,93 @@ +CE4100 I2C +---------- + +CE4100 has one PCI device which is described as the I2C-Controller. This +PCI device has three PCI-bars, each bar contains a complete I2C +controller. So we have a total of three independent I2C-Controllers +which share only an interrupt line. +The driver is probed via the PCI-ID and is gathering the information of +attached devices from the devices tree. +Grant Likely recommended to use the ranges property to map the PCI-Bar +number to its physical address and to use this to find the child nodes +of the specific I2C controller. This were his exact words: + + Here's where the magic happens. Each entry in + ranges describes how the parent pci address space + (middle group of 3) is translated to the local + address space (first group of 2) and the size of + each range (last cell). In this particular case, + the first cell of the local address is chosen to be + 1:1 mapped to the BARs, and the second is the + offset from be base of the BAR (which would be + non-zero if you had 2 or more devices mapped off + the same BAR) + + ranges allows the address mapping to be described + in a way that the OS can interpret without + requiring custom device driver code. + +This is an example which is used on FalconFalls: +------------------------------------------------ + i2c-controller@b,2 { + #address-cells = <2>; + #size-cells = <1>; + compatible = "pci8086,2e68.2", + "pci8086,2e68", + "pciclass,ff0000", + "pciclass,ff00"; + + reg = <0x15a00 0x0 0x0 0x0 0x0>; + interrupts = <16 1>; + + /* as described by Grant, the first number in the group of + * three is the bar number followed by the 64bit bar address + * followed by size of the mapping. The bar address + * requires also a valid translation in parents ranges + * property. + */ + ranges = <0 0 0x02000000 0 0xdffe0500 0x100 + 1 0 0x02000000 0 0xdffe0600 0x100 + 2 0 0x02000000 0 0xdffe0700 0x100>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,ce4100-i2c-controller"; + + /* The first number in the reg property is the + * number of the bar + */ + reg = <0 0 0x100>; + + /* This I2C controller has no devices */ + }; + + i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,ce4100-i2c-controller"; + reg = <1 0 0x100>; + + /* This I2C controller has one gpio controller */ + gpio@26 { + #gpio-cells = <2>; + compatible = "ti,pcf8575"; + reg = <0x26>; + gpio-controller; + }; + }; + + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "intel,ce4100-i2c-controller"; + reg = <2 0 0x100>; + + gpio@26 { + #gpio-cells = <2>; + compatible = "ti,pcf8575"; + reg = <0x26>; + gpio-controller; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-pxa.txt b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt new file mode 100644 index 00000000000..12b78ac507e --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-pxa.txt @@ -0,0 +1,33 @@ +* Marvell MMP I2C controller + +Required properties : + + - reg : Offset and length of the register set for the device + - compatible : should be "mrvl,mmp-twsi" where mmp is the name of a + compatible processor, e.g. pxa168, pxa910, mmp2, mmp3. + For the pxa2xx/pxa3xx, an additional node "mrvl,pxa-i2c" is required + as shown in the example below. + +Recommended properties : + + - interrupts : the interrupt number + - interrupt-parent : the phandle for the interrupt controller that + services interrupts for this device. If the parent is the default + interrupt controller in device tree, it could be ignored. + - mrvl,i2c-polling : Disable interrupt of i2c controller. Polling + status register of i2c controller instead. + - mrvl,i2c-fast-mode : Enable fast mode of i2c controller. + +Examples: + twsi1: i2c@d4011000 { + compatible = "mrvl,mmp-twsi"; + reg = <0xd4011000 0x1000>; + interrupts = <7>; + mrvl,i2c-fast-mode; + }; + + twsi2: i2c@d4025000 { + compatible = "mrvl,mmp-twsi"; + reg = <0xd4025000 0x1000>; + interrupts = <58>; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt b/Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt new file mode 100644 index 00000000000..b6cb5a12c67 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-s3c2410.txt @@ -0,0 +1,43 @@ +* Samsung's I2C controller + +The Samsung's I2C controller is used to interface with I2C devices. + +Required properties: + - compatible: value should be either of the following. + (a) "samsung, s3c2410-i2c", for i2c compatible with s3c2410 i2c. + (b) "samsung, s3c2440-i2c", for i2c compatible with s3c2440 i2c. + (c) "samsung, s3c2440-hdmiphy-i2c", for s3c2440-like i2c used + inside HDMIPHY block found on several samsung SoCs + - reg: physical base address of the controller and length of memory mapped + region. + - interrupts: interrupt number to the cpu. + - samsung,i2c-sda-delay: Delay (in ns) applied to data line (SDA) edges. + +Optional properties: + - gpios: The order of the gpios should be the following: . + The gpio specifier depends on the gpio controller. Required in all + cases except for "samsung,s3c2440-hdmiphy-i2c" whose input/output + lines are permanently wired to the respective client + - samsung,i2c-slave-addr: Slave address in multi-master enviroment. If not + specified, default value is 0. + - samsung,i2c-max-bus-freq: Desired frequency in Hz of the bus. If not + specified, the default value in Hz is 100000. + +Example: + + i2c@13870000 { + compatible = "samsung,s3c2440-i2c"; + reg = <0x13870000 0x100>; + interrupts = <345>; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <100000>; + gpios = <&gpd1 2 0 /* SDA */ + &gpd1 3 0 /* SCL */>; + #address-cells = <1>; + #size-cells = <0>; + + wm8994@1a { + compatible = "wlf,wm8994"; + reg = <0x1a>; + }; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-sirf.txt b/Documentation/devicetree/bindings/i2c/i2c-sirf.txt new file mode 100644 index 00000000000..7baf9e133fa --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-sirf.txt @@ -0,0 +1,19 @@ +I2C for SiRFprimaII platforms + +Required properties : +- compatible : Must be "sirf,prima2-i2c" +- reg: physical base address of the controller and length of memory mapped + region. +- interrupts: interrupt number to the cpu. + +Optional properties: +- clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz. + The absence of the propoerty indicates the default frequency 100 kHz. + +Examples : + +i2c0: i2c@b00e0000 { + compatible = "sirf,prima2-i2c"; + reg = <0xb00e0000 0x10000>; + interrupts = <24>; +}; diff --git a/Documentation/devicetree/bindings/i2c/i2c-versatile.txt b/Documentation/devicetree/bindings/i2c/i2c-versatile.txt new file mode 100644 index 00000000000..361d31c51b6 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-versatile.txt @@ -0,0 +1,10 @@ +i2c Controller on ARM Versatile platform: + +Required properties: +- compatible : Must be "arm,versatile-i2c"; +- reg +- #address-cells = <1>; +- #size-cells = <0>; + +Optional properties: +- Child nodes conforming to i2c bus binding diff --git a/Documentation/devicetree/bindings/i2c/i2c-xiic.txt b/Documentation/devicetree/bindings/i2c/i2c-xiic.txt new file mode 100644 index 00000000000..ceabbe91ae4 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-xiic.txt @@ -0,0 +1,22 @@ +Xilinx IIC controller: + +Required properties: +- compatible : Must be "xlnx,xps-iic-2.00.a" +- reg : IIC register location and length +- interrupts : IIC controller unterrupt +- #address-cells = <1> +- #size-cells = <0> + +Optional properties: +- Child nodes conforming to i2c bus binding + +Example: + + axi_iic_0: i2c@40800000 { + compatible = "xlnx,xps-iic-2.00.a"; + interrupts = < 1 2 >; + reg = < 0x40800000 0x10000 >; + + #size-cells = <0>; + #address-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/i2c/mrvl-i2c.txt b/Documentation/devicetree/bindings/i2c/mrvl-i2c.txt deleted file mode 100644 index 0f7945019f6..00000000000 --- a/Documentation/devicetree/bindings/i2c/mrvl-i2c.txt +++ /dev/null @@ -1,51 +0,0 @@ -* Marvell MMP I2C controller - -Required properties : - - - reg : Offset and length of the register set for the device - - compatible : should be "mrvl,mmp-twsi" where mmp is the name of a - compatible processor, e.g. pxa168, pxa910, mmp2, mmp3. - For the pxa2xx/pxa3xx, an additional node "mrvl,pxa-i2c" is required - as shown in the example below. - -Recommended properties : - - - interrupts : the interrupt number - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. If the parent is the default - interrupt controller in device tree, it could be ignored. - - mrvl,i2c-polling : Disable interrupt of i2c controller. Polling - status register of i2c controller instead. - - mrvl,i2c-fast-mode : Enable fast mode of i2c controller. - -Examples: - twsi1: i2c@d4011000 { - compatible = "mrvl,mmp-twsi"; - reg = <0xd4011000 0x1000>; - interrupts = <7>; - mrvl,i2c-fast-mode; - }; - - twsi2: i2c@d4025000 { - compatible = "mrvl,mmp-twsi"; - reg = <0xd4025000 0x1000>; - interrupts = <58>; - }; - -* Marvell MV64XXX I2C controller - -Required properties : - - - reg : Offset and length of the register set for the device - - compatible : Should be "marvell,mv64xxx-i2c" - - interrupts : The interrupt number - - clock-frequency : Desired I2C bus clock frequency in Hz. - -Examples: - - i2c@11000 { - compatible = "marvell,mv64xxx-i2c"; - reg = <0x11000 0x20>; - interrupts = <29>; - clock-frequency = <100000>; - }; diff --git a/Documentation/devicetree/bindings/i2c/mux.txt b/Documentation/devicetree/bindings/i2c/mux.txt deleted file mode 100644 index af84cce5cd7..00000000000 --- a/Documentation/devicetree/bindings/i2c/mux.txt +++ /dev/null @@ -1,60 +0,0 @@ -Common i2c bus multiplexer/switch properties. - -An i2c bus multiplexer/switch will have several child busses that are -numbered uniquely in a device dependent manner. The nodes for an i2c bus -multiplexer/switch will have one child node for each child -bus. - -Required properties: -- #address-cells = <1>; -- #size-cells = <0>; - -Required properties for child nodes: -- #address-cells = <1>; -- #size-cells = <0>; -- reg : The sub-bus number. - -Optional properties for child nodes: -- Other properties specific to the multiplexer/switch hardware. -- Child nodes conforming to i2c bus binding - - -Example : - - /* - An NXP pca9548 8 channel I2C multiplexer at address 0x70 - with two NXP pca8574 GPIO expanders attached, one each to - ports 3 and 4. - */ - - mux@70 { - compatible = "nxp,pca9548"; - reg = <0x70>; - #address-cells = <1>; - #size-cells = <0>; - - i2c@3 { - #address-cells = <1>; - #size-cells = <0>; - reg = <3>; - - gpio1: gpio@38 { - compatible = "nxp,pca8574"; - reg = <0x38>; - #gpio-cells = <2>; - gpio-controller; - }; - }; - i2c@4 { - #address-cells = <1>; - #size-cells = <0>; - reg = <4>; - - gpio2: gpio@38 { - compatible = "nxp,pca8574"; - reg = <0x38>; - #gpio-cells = <2>; - gpio-controller; - }; - }; - }; diff --git a/Documentation/devicetree/bindings/i2c/nomadik.txt b/Documentation/devicetree/bindings/i2c/nomadik.txt deleted file mode 100644 index 72065b0ff68..00000000000 --- a/Documentation/devicetree/bindings/i2c/nomadik.txt +++ /dev/null @@ -1,23 +0,0 @@ -I2C for Nomadik based systems - -Required (non-standard) properties: - - Nil - -Recommended (non-standard) properties: - - clock-frequency : Maximum bus clock frequency for the device - -Optional (non-standard) properties: - - Nil - -Example : - -i2c@80004000 { - compatible = "stericsson,db8500-i2c", "st,nomadik-i2c"; - reg = <0x80004000 0x1000>; - interrupts = <0 21 0x4>; - #address-cells = <1>; - #size-cells = <0>; - v-i2c-supply = <&db8500_vape_reg>; - - clock-frequency = <400000>; -}; diff --git a/Documentation/devicetree/bindings/i2c/omap-i2c.txt b/Documentation/devicetree/bindings/i2c/omap-i2c.txt deleted file mode 100644 index 56564aa4b44..00000000000 --- a/Documentation/devicetree/bindings/i2c/omap-i2c.txt +++ /dev/null @@ -1,30 +0,0 @@ -I2C for OMAP platforms - -Required properties : -- compatible : Must be "ti,omap3-i2c" or "ti,omap4-i2c" -- ti,hwmods : Must be "i2c", n being the instance number (1-based) -- #address-cells = <1>; -- #size-cells = <0>; - -Recommended properties : -- clock-frequency : Desired I2C bus clock frequency in Hz. Otherwise - the default 100 kHz frequency will be used. - -Optional properties: -- Child nodes conforming to i2c bus binding - -Note: Current implementation will fetch base address, irq and dma -from omap hwmod data base during device registration. -Future plan is to migrate hwmod data base contents into device tree -blob so that, all the required data will be used from device tree dts -file. - -Examples : - -i2c1: i2c@0 { - compatible = "ti,omap3-i2c"; - #address-cells = <1>; - #size-cells = <0>; - ti,hwmods = "i2c1"; - clock-frequency = <400000>; -}; diff --git a/Documentation/devicetree/bindings/i2c/pnx.txt b/Documentation/devicetree/bindings/i2c/pnx.txt deleted file mode 100644 index fe98ada33ee..00000000000 --- a/Documentation/devicetree/bindings/i2c/pnx.txt +++ /dev/null @@ -1,36 +0,0 @@ -* NXP PNX I2C Controller - -Required properties: - - - reg: Offset and length of the register set for the device - - compatible: should be "nxp,pnx-i2c" - - interrupts: configure one interrupt line - - #address-cells: always 1 (for i2c addresses) - - #size-cells: always 0 - - interrupt-parent: the phandle for the interrupt controller that - services interrupts for this device. - -Optional properties: - - - clock-frequency: desired I2C bus clock frequency in Hz, Default: 100000 Hz - -Examples: - - i2c1: i2c@400a0000 { - compatible = "nxp,pnx-i2c"; - reg = <0x400a0000 0x100>; - interrupt-parent = <&mic>; - interrupts = <51 0>; - #address-cells = <1>; - #size-cells = <0>; - }; - - i2c2: i2c@400a8000 { - compatible = "nxp,pnx-i2c"; - reg = <0x400a8000 0x100>; - interrupt-parent = <&mic>; - interrupts = <50 0>; - #address-cells = <1>; - #size-cells = <0>; - clock-frequency = <100000>; - }; diff --git a/Documentation/devicetree/bindings/i2c/samsung-i2c.txt b/Documentation/devicetree/bindings/i2c/samsung-i2c.txt deleted file mode 100644 index b6cb5a12c67..00000000000 --- a/Documentation/devicetree/bindings/i2c/samsung-i2c.txt +++ /dev/null @@ -1,43 +0,0 @@ -* Samsung's I2C controller - -The Samsung's I2C controller is used to interface with I2C devices. - -Required properties: - - compatible: value should be either of the following. - (a) "samsung, s3c2410-i2c", for i2c compatible with s3c2410 i2c. - (b) "samsung, s3c2440-i2c", for i2c compatible with s3c2440 i2c. - (c) "samsung, s3c2440-hdmiphy-i2c", for s3c2440-like i2c used - inside HDMIPHY block found on several samsung SoCs - - reg: physical base address of the controller and length of memory mapped - region. - - interrupts: interrupt number to the cpu. - - samsung,i2c-sda-delay: Delay (in ns) applied to data line (SDA) edges. - -Optional properties: - - gpios: The order of the gpios should be the following: . - The gpio specifier depends on the gpio controller. Required in all - cases except for "samsung,s3c2440-hdmiphy-i2c" whose input/output - lines are permanently wired to the respective client - - samsung,i2c-slave-addr: Slave address in multi-master enviroment. If not - specified, default value is 0. - - samsung,i2c-max-bus-freq: Desired frequency in Hz of the bus. If not - specified, the default value in Hz is 100000. - -Example: - - i2c@13870000 { - compatible = "samsung,s3c2440-i2c"; - reg = <0x13870000 0x100>; - interrupts = <345>; - samsung,i2c-sda-delay = <100>; - samsung,i2c-max-bus-freq = <100000>; - gpios = <&gpd1 2 0 /* SDA */ - &gpd1 3 0 /* SCL */>; - #address-cells = <1>; - #size-cells = <0>; - - wm8994@1a { - compatible = "wlf,wm8994"; - reg = <0x1a>; - }; - }; diff --git a/Documentation/devicetree/bindings/i2c/sirf-i2c.txt b/Documentation/devicetree/bindings/i2c/sirf-i2c.txt deleted file mode 100644 index 7baf9e133fa..00000000000 --- a/Documentation/devicetree/bindings/i2c/sirf-i2c.txt +++ /dev/null @@ -1,19 +0,0 @@ -I2C for SiRFprimaII platforms - -Required properties : -- compatible : Must be "sirf,prima2-i2c" -- reg: physical base address of the controller and length of memory mapped - region. -- interrupts: interrupt number to the cpu. - -Optional properties: -- clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz. - The absence of the propoerty indicates the default frequency 100 kHz. - -Examples : - -i2c0: i2c@b00e0000 { - compatible = "sirf,prima2-i2c"; - reg = <0xb00e0000 0x10000>; - interrupts = <24>; -}; diff --git a/Documentation/devicetree/bindings/i2c/xiic.txt b/Documentation/devicetree/bindings/i2c/xiic.txt deleted file mode 100644 index ceabbe91ae4..00000000000 --- a/Documentation/devicetree/bindings/i2c/xiic.txt +++ /dev/null @@ -1,22 +0,0 @@ -Xilinx IIC controller: - -Required properties: -- compatible : Must be "xlnx,xps-iic-2.00.a" -- reg : IIC register location and length -- interrupts : IIC controller unterrupt -- #address-cells = <1> -- #size-cells = <0> - -Optional properties: -- Child nodes conforming to i2c bus binding - -Example: - - axi_iic_0: i2c@40800000 { - compatible = "xlnx,xps-iic-2.00.a"; - interrupts = < 1 2 >; - reg = < 0x40800000 0x10000 >; - - #size-cells = <0>; - #address-cells = <1>; - }; diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index bffd5501ac2..15da1ac7cf9 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -9,10 +9,6 @@ * kind, whether express or implied. */ -/* - * This driver can be used from the device tree, see - * Documentation/devicetree/bindings/i2c/ocore-i2c.txt - */ #include #include #include -- cgit v1.2.3 From 31982e52f0f5d6d51e69d5c4c4a7be5d52307c6e Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Wed, 31 Oct 2012 17:57:49 +0200 Subject: arm-dt: Enable DT proc updates. This simple patch enables dynamic changes of the DT tree on runtime to be visible to the device-tree proc interface. Signed-off-by: Pantelis Antoniou Acked-by: Rob Herring Signed-off-by: Grant Likely --- arch/arm/include/asm/prom.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h index aeae9c609df..6d65ba222db 100644 --- a/arch/arm/include/asm/prom.h +++ b/arch/arm/include/asm/prom.h @@ -11,6 +11,8 @@ #ifndef __ASMARM_PROM_H #define __ASMARM_PROM_H +#define HAVE_ARCH_DEVTREE_FIXUPS + #ifdef CONFIG_OF extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); -- cgit v1.2.3 From 5212d096cbed2eae1e442b3f8bf448e6a577af6f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 16 Nov 2012 00:01:35 +0800 Subject: pinctrl: nomadik: Staticize non-exported symbols They are not referenced outside of this file, make them static. Signed-off-by: Axel Lin Acked-by: Lee Jones Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 98c088ae7f4..8ef3e85cb01 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -1286,8 +1286,8 @@ void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up) } } -int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) +static int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq) { struct nmk_gpio_chip *nmk_chip = d->host_data; @@ -1671,9 +1671,9 @@ static void nmk_pmx_disable(struct pinctrl_dev *pctldev, dev_dbg(npct->dev, "disable group %s, %u pins\n", g->name, g->npins); } -int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned offset) +static int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); struct nmk_gpio_chip *nmk_chip; @@ -1702,9 +1702,9 @@ int nmk_gpio_request_enable(struct pinctrl_dev *pctldev, return 0; } -void nmk_gpio_disable_free(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, - unsigned offset) +static void nmk_gpio_disable_free(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned offset) { struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev); @@ -1722,17 +1722,15 @@ static struct pinmux_ops nmk_pinmux_ops = { .gpio_disable_free = nmk_gpio_disable_free, }; -int nmk_pin_config_get(struct pinctrl_dev *pctldev, - unsigned pin, - unsigned long *config) +static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long *config) { /* Not implemented */ return -EINVAL; } -int nmk_pin_config_set(struct pinctrl_dev *pctldev, - unsigned pin, - unsigned long config) +static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long config) { static const char *pullnames[] = { [NMK_GPIO_PULL_NONE] = "none", -- cgit v1.2.3 From 0da9a0c2638c8476b4a5021841912f249e3187dc Mon Sep 17 00:00:00 2001 From: Tommi Rantala Date: Thu, 15 Nov 2012 03:49:05 +0000 Subject: sctp: fix /proc/net/sctp/ memory leak Commit 13d782f ("sctp: Make the proc files per network namespace.") changed the /proc/net/sctp/ struct file_operations opener functions to use single_open_net() and seq_open_net(). Avoid leaking memory by using single_release_net() and seq_release_net() as the release functions. Discovered with Trinity (the syscall fuzzer). Signed-off-by: Tommi Rantala Acked-by: Neil Horman Cc: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/sctp/proc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/sctp/proc.c b/net/sctp/proc.c index c3bea269faf..9966e7b1645 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -102,7 +102,7 @@ static const struct file_operations sctp_snmp_seq_fops = { .open = sctp_snmp_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = single_release_net, }; /* Set up the proc fs entry for 'snmp' object. */ @@ -251,7 +251,7 @@ static const struct file_operations sctp_eps_seq_fops = { .open = sctp_eps_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; /* Set up the proc fs entry for 'eps' object. */ @@ -372,7 +372,7 @@ static const struct file_operations sctp_assocs_seq_fops = { .open = sctp_assocs_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; /* Set up the proc fs entry for 'assocs' object. */ @@ -517,7 +517,7 @@ static const struct file_operations sctp_remaddr_seq_fops = { .open = sctp_remaddr_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = seq_release_net, }; int __net_init sctp_remaddr_proc_init(struct net *net) -- cgit v1.2.3 From 44d6453a8793e5a39c861718f62f91e832694435 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 31 Oct 2012 14:40:52 +0100 Subject: clk: ux500: Register rng clock lookups for u8500 Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 4ec6f60e372..87d625b08fa 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -378,6 +378,7 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p6_pclk0", "per6clk", U8500_CLKRST6_BASE, BIT(0), 0); + clk_register_clkdev(clk, "apb_pclk", "rng"); clk = clk_reg_prcc_pclk("p6_pclk1", "per6clk", U8500_CLKRST6_BASE, BIT(1), 0); @@ -518,5 +519,5 @@ void u8500_clk_init(void) /* Periph6 */ clk = clk_reg_prcc_kclk("p3_rng_kclk", "rngclk", U8500_CLKRST6_BASE, BIT(0), CLK_SET_RATE_GATE); - + clk_register_clkdev(clk, NULL, "rng"); } -- cgit v1.2.3 From 5678596c7628e47e022d1d30fb2a6c9607f42a0e Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 31 Oct 2012 14:40:53 +0100 Subject: clk: ux500: Register nomadik keypad clock lookups for u8500 Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/clk/ux500/u8500_clk.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c index 87d625b08fa..64877e1588e 100644 --- a/drivers/clk/ux500/u8500_clk.c +++ b/drivers/clk/ux500/u8500_clk.c @@ -350,6 +350,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_pclk("p3_pclk5", "per3clk", U8500_CLKRST3_BASE, BIT(5), 0); + clk_register_clkdev(clk, "apb_pclk", "ske"); + clk_register_clkdev(clk, "apb_pclk", "nmk-ske-keypad"); clk = clk_reg_prcc_pclk("p3_pclk6", "per3clk", U8500_CLKRST3_BASE, BIT(6), 0); @@ -507,6 +509,8 @@ void u8500_clk_init(void) clk = clk_reg_prcc_kclk("p3_ske_kclk", "rtc32k", U8500_CLKRST3_BASE, BIT(5), CLK_SET_RATE_GATE); + clk_register_clkdev(clk, NULL, "ske"); + clk_register_clkdev(clk, NULL, "nmk-ske-keypad"); clk = clk_reg_prcc_kclk("p3_uart2_kclk", "uartclk", U8500_CLKRST3_BASE, BIT(6), CLK_SET_RATE_GATE); -- cgit v1.2.3 From ddc07ef9499509200033be7e387feb6c83744a73 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 1 Nov 2012 13:33:55 +0800 Subject: CLK: clk-twl6040: fix return value check in twl6040_clk_probe() In case of error, the function clk_register() returns ERR_PTR() and never returns NULL. The NULL test in the return value check should be replaced with IS_ERR(). dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Mike Turquette --- drivers/clk/clk-twl6040.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-twl6040.c b/drivers/clk/clk-twl6040.c index f4a3389c3d0..bc1e713e7b9 100644 --- a/drivers/clk/clk-twl6040.c +++ b/drivers/clk/clk-twl6040.c @@ -92,8 +92,8 @@ static int __devinit twl6040_clk_probe(struct platform_device *pdev) clkdata->mcpdm_fclk.init = &wm831x_clkout_init; clkdata->clk = clk_register(&pdev->dev, &clkdata->mcpdm_fclk); - if (!clkdata->clk) - return -EINVAL; + if (IS_ERR(clkdata->clk)) + return PTR_ERR(clkdata->clk); dev_set_drvdata(&pdev->dev, clkdata); -- cgit v1.2.3 From 90d4971d3d71a50f2265d97589ef361d1402647a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 6 Nov 2012 10:34:20 +0800 Subject: clk: spear: Add stub functions for spear3[0|1|2]0_clk_init() This fixes compile error if one of SPEAr3xx implementations is not selected. CC drivers/clk/spear/spear3xx_clock.o drivers/clk/spear/spear3xx_clock.c: In function 'spear3xx_clk_init': drivers/clk/spear/spear3xx_clock.c:599:3: error: implicit declaration of function 'spear300_clk_init' [-Werror=implicit-function-declaration] drivers/clk/spear/spear3xx_clock.c:601:3: error: implicit declaration of function 'spear310_clk_init' [-Werror=implicit-function-declaration] drivers/clk/spear/spear3xx_clock.c:603:3: error: implicit declaration of function 'spear320_clk_init' [-Werror=implicit-function-declaration] cc1: some warnings being treated as errors make[3]: *** [drivers/clk/spear/spear3xx_clock.o] Error 1 make[2]: *** [drivers/clk/spear] Error 2 make[1]: *** [drivers/clk] Error 2 make: *** [drivers] Error 2 Signed-off-by: Axel Lin Acked-by: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/spear3xx_clock.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index c3157454bb3..59049cf81a7 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -157,6 +157,8 @@ static void __init spear300_clk_init(void) 1); clk_register_clkdev(clk, NULL, "a0000000.kbd"); } +#else +static inline void spear300_clk_init(void) { } #endif /* array of all spear 310 clock lookups */ @@ -197,6 +199,8 @@ static void __init spear310_clk_init(void) 1); clk_register_clkdev(clk, NULL, "b2200000.serial"); } +#else +static inline void spear310_clk_init(void) { } #endif /* array of all spear 320 clock lookups */ @@ -336,6 +340,8 @@ static void __init spear320_clk_init(void) &_lock); clk_register_clkdev(clk, NULL, "60100000.serial"); } +#else +static inline void spear320_clk_init(void) { } #endif void __init spear3xx_clk_init(void) -- cgit v1.2.3 From 93532c8a4890871aa0d84dd91b80dad9f58542e0 Mon Sep 17 00:00:00 2001 From: Igor Mazanov Date: Thu, 15 Nov 2012 21:07:00 +0400 Subject: clk: remove inline usage from clk-provider.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Users of GCC 4.7 have reported compiler errors due to having inline applied to function declarations in clk-provider.h. The definitions exist in drivers/clk/clk.c. An example error: In file included from arch/arm/mach-omap2/clockdomain.c:25:0: arch/arm/mach-omap2/clockdomain.c: In function ‘clkdm_clk_disable’: include/linux/clk-provider.h:338:12: error: inlining failed in call to always_inline ‘__clk_get_enable_count’: function body not available arch/arm/mach-omap2/clockdomain.c:1001:28: error: called from here make[1]: *** [arch/arm/mach-omap2/clockdomain.o] Error 1 make: *** [arch/arm/mach-omap2] Error 2 This patch removes the use of inline from include/linux/clk-provider.h but keeps the function definitions in drivers/clk/clk.c as inlined since they are one-liners. Signed-off-by: Igor Mazanov Acked-by: Paul Walmsley Signed-off-by: Mike Turquette [mturquette@linaro.org: improved subject, added changelog] --- include/linux/clk-provider.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index c1273158292..f9f5e9eeb9d 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -335,8 +335,8 @@ const char *__clk_get_name(struct clk *clk); struct clk_hw *__clk_get_hw(struct clk *clk); u8 __clk_get_num_parents(struct clk *clk); struct clk *__clk_get_parent(struct clk *clk); -inline int __clk_get_enable_count(struct clk *clk); -inline int __clk_get_prepare_count(struct clk *clk); +int __clk_get_enable_count(struct clk *clk); +int __clk_get_prepare_count(struct clk *clk); unsigned long __clk_get_rate(struct clk *clk); unsigned long __clk_get_flags(struct clk *clk); int __clk_is_enabled(struct clk *clk); -- cgit v1.2.3 From 70f77b3f7ec010ff9624c1f2e39a81babc9e2429 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 9 Jun 2012 19:10:27 +0300 Subject: ftrace: Clear bits properly in reset_iter_read() There is a typo here where '&' is used instead of '|' and it turns the statement into a noop. The original code is equivalent to: iter->flags &= ~((1 << 2) & (1 << 4)); Link: http://lkml.kernel.org/r/20120609161027.GD6488@elgon.mountain Cc: stable@vger.kernel.org # all of them Signed-off-by: Dan Carpenter Signed-off-by: Steven Rostedt --- kernel/trace/ftrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 9dcf15d3838..51b71594f32 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -2437,7 +2437,7 @@ static void reset_iter_read(struct ftrace_iterator *iter) { iter->pos = 0; iter->func_pos = 0; - iter->flags &= ~(FTRACE_ITER_PRINTALL & FTRACE_ITER_HASH); + iter->flags &= ~(FTRACE_ITER_PRINTALL | FTRACE_ITER_HASH); } static void *t_start(struct seq_file *m, loff_t *pos) -- cgit v1.2.3 From ec34232575083fd0f43d3a101e8ebb041b203761 Mon Sep 17 00:00:00 2001 From: Andrew Vagin Date: Thu, 15 Nov 2012 04:03:17 +0000 Subject: tcp: fix retransmission in repair mode Currently if a socket was repaired with a few packet in a write queue, a kernel bug may be triggered: kernel BUG at net/ipv4/tcp_output.c:2330! RIP: 0010:[] tcp_retransmit_skb+0x5ff/0x610 According to the initial realization v3.4-rc2-963-gc0e88ff, all skb-s should look like already posted. This patch fixes code according with this sentence. Here are three points, which were not done in the initial patch: 1. A tcp send head should not be changed 2. Initialize TSO state of a skb 3. Reset the retransmission time This patch moves logic from tcp_sendmsg to tcp_write_xmit. A packet passes the ussual way, but isn't sent to network. This patch solves all described problems and handles tcp_sendpages. Cc: Pavel Emelyanov Cc: "David S. Miller" Cc: Alexey Kuznetsov Cc: James Morris Cc: Hideaki YOSHIFUJI Cc: Patrick McHardy Signed-off-by: Andrey Vagin Acked-by: Pavel Emelyanov Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 4 ++-- net/ipv4/tcp_output.c | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 197c0008503..083092e3aed 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1212,7 +1212,7 @@ new_segment: wait_for_sndbuf: set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); wait_for_memory: - if (copied && likely(!tp->repair)) + if (copied) tcp_push(sk, flags & ~MSG_MORE, mss_now, TCP_NAGLE_PUSH); if ((err = sk_stream_wait_memory(sk, &timeo)) != 0) @@ -1223,7 +1223,7 @@ wait_for_memory: } out: - if (copied && likely(!tp->repair)) + if (copied) tcp_push(sk, flags, mss_now, tp->nonagle); release_sock(sk); return copied + copied_syn; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index cfe6ffe1c17..2798706cb06 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1986,6 +1986,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, tso_segs = tcp_init_tso_segs(sk, skb, mss_now); BUG_ON(!tso_segs); + if (unlikely(tp->repair) && tp->repair_queue == TCP_SEND_QUEUE) + goto repair; /* Skip network transmission */ + cwnd_quota = tcp_cwnd_test(tp, skb); if (!cwnd_quota) break; @@ -2026,6 +2029,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle, if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp))) break; +repair: /* Advance the send_head. This one is sent out. * This call will increment packets_out. */ -- cgit v1.2.3 From a652208e0b52c190e57f2a075ffb5e897fe31c3b Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 14 Nov 2012 02:51:04 +0000 Subject: net: correct check in dev_addr_del() Check (ha->addr == dev->dev_addr) is always true because dev_addr_init() sets this. Correct the check to behave properly on addr removal. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/core/dev_addr_lists.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index 87cc17db2d5..b079c7bbc15 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -319,7 +319,8 @@ int dev_addr_del(struct net_device *dev, const unsigned char *addr, */ ha = list_first_entry(&dev->dev_addrs.list, struct netdev_hw_addr, list); - if (ha->addr == dev->dev_addr && ha->refcount == 1) + if (!memcmp(ha->addr, addr, dev->addr_len) && + ha->type == addr_type && ha->refcount == 1) return -ENOENT; err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, -- cgit v1.2.3 From 4087641b255cb003ce653aac79e3445fcb864552 Mon Sep 17 00:00:00 2001 From: Kumar Amit Mehta Date: Thu, 15 Nov 2012 22:52:13 +0530 Subject: staging: rtl8192e: rtl8192e: rtl_core.c: Audit the return value of register_netdev() Inspect the return value of register_netdev() in the driver probe routine and return -ENODEV in case of error. Signed-off-by: Kumar Amit Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 81134d312ee..f68df241f78 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -2955,7 +2955,8 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, netif_carrier_off(dev); netif_stop_queue(dev); - register_netdev(dev); + if (register_netdev(dev)) + goto err_free_irq; RT_TRACE(COMP_INIT, "dev name: %s\n", dev->name); rtl8192_proc_init_one(dev); -- cgit v1.2.3 From 2a38e6fcf9173ffa8acf827c0b5d69863e012434 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Thu, 15 Nov 2012 16:57:29 +0000 Subject: staging: vt6656: iwctl_giwaplist() re warn: possible memory leak of 'qual' Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/iwctl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index a914d20cc0e..08557fa9f00 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -655,9 +655,13 @@ int iwctl_giwaplist(struct net_device *dev, struct iw_request_info *info, return -EINVAL; sock = kzalloc(sizeof(struct sockaddr) * IW_MAX_AP, GFP_KERNEL); + if (sock == NULL) + return -ENOMEM; qual = kzalloc(sizeof(struct iw_quality) * IW_MAX_AP, GFP_KERNEL); - if (sock == NULL || qual == NULL) + if (qual == NULL) { + kfree(sock); return -ENOMEM; + } for (ii = 0, jj = 0; ii < MAX_BSS_NUM; ii++) { if (!pBSS[ii].bActive) -- cgit v1.2.3 From e773efc405026bb8540c84bf45420bd66d5b34a7 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 11 Nov 2012 17:37:58 +0200 Subject: mei: amthif: prefix cb list with amthif amthif cb list were prefixed with amthi_ instead if amthif. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 10 +++++----- drivers/misc/mei/init.c | 8 ++++---- drivers/misc/mei/interrupt.c | 6 ++---- drivers/misc/mei/main.c | 5 ++--- drivers/misc/mei/mei_dev.h | 9 +++++---- 5 files changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 96db3ad2125..1de28df94da 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -124,7 +124,7 @@ struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, struct mei_cl_cb *next = NULL; list_for_each_entry_safe(pos, next, - &dev->amthi_read_complete_list.list, list) { + &dev->amthif_rd_complete_list.list, list) { cl_temp = (struct mei_cl *)pos->file_private; if (cl_temp && cl_temp == &dev->iamthif_cl && pos->file_object == file) @@ -351,12 +351,12 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) cb->major_file_operations = MEI_IOCTL; - if (!list_empty(&dev->amthi_cmd_list.list) || + if (!list_empty(&dev->amthif_cmd_list.list) || dev->iamthif_state != MEI_IAMTHIF_IDLE) { dev_dbg(&dev->pdev->dev, "amthif state = %d\n", dev->iamthif_state); dev_dbg(&dev->pdev->dev, "AMTHIF: add cb to the wait list\n"); - list_add_tail(&cb->list, &dev->amthi_cmd_list.list); + list_add_tail(&cb->list, &dev->amthif_cmd_list.list); return 0; } return mei_amthif_send_cmd(dev, cb); @@ -388,7 +388,7 @@ void mei_amthif_run_next_cmd(struct mei_device *dev) dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n"); - list_for_each_entry_safe(pos, next, &dev->amthi_cmd_list.list, list) { + list_for_each_entry_safe(pos, next, &dev->amthif_cmd_list.list, list) { list_del(&pos->list); cl_tmp = (struct mei_cl *)pos->file_private; @@ -589,7 +589,7 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb) memcpy(cb->response_buffer.data, dev->iamthif_msg_buf, dev->iamthif_msg_buf_index); - list_add_tail(&cb->list, &dev->amthi_read_complete_list.list); + list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list); dev_dbg(&dev->pdev->dev, "amthi read completed\n"); dev->iamthif_timer = jiffies; dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n", diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 8c3c2689f70..7e6d591fef4 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -80,8 +80,8 @@ int mei_cl_flush_queues(struct mei_cl *cl) mei_io_list_flush(&cl->dev->write_waiting_list, cl); mei_io_list_flush(&cl->dev->ctrl_wr_list, cl); mei_io_list_flush(&cl->dev->ctrl_rd_list, cl); - mei_io_list_flush(&cl->dev->amthi_cmd_list, cl); - mei_io_list_flush(&cl->dev->amthi_read_complete_list, cl); + mei_io_list_flush(&cl->dev->amthif_cmd_list, cl); + mei_io_list_flush(&cl->dev->amthif_rd_complete_list, cl); return 0; } @@ -117,8 +117,8 @@ struct mei_device *mei_device_init(struct pci_dev *pdev) mei_io_list_init(&dev->write_waiting_list); mei_io_list_init(&dev->ctrl_wr_list); mei_io_list_init(&dev->ctrl_rd_list); - mei_io_list_init(&dev->amthi_cmd_list); - mei_io_list_init(&dev->amthi_read_complete_list); + mei_io_list_init(&dev->amthif_cmd_list); + mei_io_list_init(&dev->amthif_rd_complete_list); dev->pdev = pdev; return dev; } diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 62f8b65fd11..7193149678e 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -1127,7 +1127,6 @@ void mei_timer(struct work_struct *work) unsigned long timeout; struct mei_cl *cl_pos = NULL; struct mei_cl *cl_next = NULL; - struct list_head *amthi_complete_list = NULL; struct mei_cl_cb *cb_pos = NULL; struct mei_cl_cb *cb_next = NULL; @@ -1195,9 +1194,8 @@ void mei_timer(struct work_struct *work) dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n"); - amthi_complete_list = &dev->amthi_read_complete_list.list; - - list_for_each_entry_safe(cb_pos, cb_next, amthi_complete_list, list) { + list_for_each_entry_safe(cb_pos, cb_next, + &dev->amthif_rd_complete_list.list, list) { cl_pos = cb_pos->file_object->private_data; diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index ff50cc14cc3..bea545a5ae2 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -146,9 +146,8 @@ static bool mei_clear_lists(struct mei_device *dev, struct file *file) bool removed = false; /* remove callbacks associated with a file */ - mei_clear_list(dev, file, &dev->amthi_cmd_list.list); - if (mei_clear_list(dev, file, - &dev->amthi_read_complete_list.list)) + mei_clear_list(dev, file, &dev->amthif_cmd_list.list); + if (mei_clear_list(dev, file, &dev->amthif_rd_complete_list.list)) removed = true; mei_clear_list(dev, file, &dev->ctrl_rd_list.list); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 8b96d99b857..ce246b0fb2d 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -184,16 +184,13 @@ struct mei_device { /* * lists of queues */ - /* array of pointers to aio lists */ + /* array of pointers to aio lists */ struct mei_cl_cb read_list; /* driver read queue */ struct mei_cl_cb write_list; /* driver write queue */ struct mei_cl_cb write_waiting_list; /* write waiting queue */ struct mei_cl_cb ctrl_wr_list; /* managed write IOCTL list */ struct mei_cl_cb ctrl_rd_list; /* managed read IOCTL list */ - struct mei_cl_cb amthi_cmd_list; /* amthi list for cmd waiting */ - /* driver managed amthi list for reading completed amthi cmd data */ - struct mei_cl_cb amthi_read_complete_list; /* * list of files */ @@ -254,6 +251,10 @@ struct mei_device { unsigned char wd_data[MEI_WD_START_MSG_SIZE]; + /* amthif list for cmd waiting */ + struct mei_cl_cb amthif_cmd_list; + /* driver managed amthif list for reading completed amthif cmd data */ + struct mei_cl_cb amthif_rd_complete_list; struct file *iamthif_file_object; struct mei_cl iamthif_cl; struct mei_cl_cb *iamthif_current_cb; -- cgit v1.2.3 From db3ed43185c6f5d4fd6c5ac963347b849540996e Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 11 Nov 2012 17:37:59 +0200 Subject: mei: use type struct mei_cl *cl instead of void in struct mei_cb We can use correct type 'struct mei_cl' instead of 'void *' for file_private in the struct mei_cb as there is no other type assigned to this member of the structure We rename the member from file_private to cl Remove about 10 lines of declarations of temporary variables used for type casting Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 14 ++++---------- drivers/misc/mei/init.c | 6 ++---- drivers/misc/mei/interrupt.c | 14 +++++++------- drivers/misc/mei/iorw.c | 2 +- drivers/misc/mei/main.c | 8 ++------ drivers/misc/mei/mei_dev.h | 9 ++++++++- 6 files changed, 24 insertions(+), 29 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 1de28df94da..74d593fd6cb 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -119,14 +119,12 @@ void mei_amthif_host_init(struct mei_device *dev) struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, struct file *file) { - struct mei_cl *cl_temp; struct mei_cl_cb *pos = NULL; struct mei_cl_cb *next = NULL; list_for_each_entry_safe(pos, next, &dev->amthif_rd_complete_list.list, list) { - cl_temp = (struct mei_cl *)pos->file_private; - if (cl_temp && cl_temp == &dev->iamthif_cl && + if (pos->cl && pos->cl == &dev->iamthif_cl && pos->file_object == file) return pos; } @@ -370,7 +368,6 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) */ void mei_amthif_run_next_cmd(struct mei_device *dev) { - struct mei_cl *cl_tmp; struct mei_cl_cb *pos = NULL; struct mei_cl_cb *next = NULL; int status; @@ -390,9 +387,8 @@ void mei_amthif_run_next_cmd(struct mei_device *dev) list_for_each_entry_safe(pos, next, &dev->amthif_cmd_list.list, list) { list_del(&pos->list); - cl_tmp = (struct mei_cl *)pos->file_private; - if (cl_tmp && cl_tmp == &dev->iamthif_cl) { + if (pos->cl && pos->cl == &dev->iamthif_cl) { status = mei_amthif_send_cmd(dev, pos); if (status) { dev_dbg(&dev->pdev->dev, @@ -500,7 +496,6 @@ int mei_amthif_irq_process_completed(struct mei_device *dev, s32 *slots, int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list, struct mei_device *dev, struct mei_msg_hdr *mei_hdr) { - struct mei_cl *cl; struct mei_cl_cb *cb; unsigned char *buffer; @@ -528,14 +523,13 @@ int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list, cb = dev->iamthif_current_cb; dev->iamthif_current_cb = NULL; - cl = (struct mei_cl *)cb->file_private; - if (!cl) + if (!cb->cl) return -ENODEV; dev->iamthif_stall_timer = 0; cb->buf_idx = dev->iamthif_msg_buf_index; cb->read_time = jiffies; - if (dev->iamthif_ioctl && cl == &dev->iamthif_cl) { + if (dev->iamthif_ioctl && cb->cl == &dev->iamthif_cl) { /* found the iamthif cb */ dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n "); dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n "); diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 7e6d591fef4..0046ca50548 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -55,10 +55,8 @@ void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl) struct mei_cl_cb *next; list_for_each_entry_safe(pos, next, &list->list, list) { - if (pos->file_private) { - struct mei_cl *cl_tmp; - cl_tmp = (struct mei_cl *)pos->file_private; - if (mei_cl_cmp_id(cl, cl_tmp)) + if (pos->cl) { + if (mei_cl_cmp_id(cl, pos->cl)) list_del(&pos->list); } } diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 7193149678e..acc994e3f20 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -113,7 +113,7 @@ static int mei_irq_thread_read_client_message(struct mei_cl_cb *complete_list, goto quit; list_for_each_entry_safe(cb_pos, cb_next, &dev->read_list.list, list) { - cl = (struct mei_cl *)cb_pos->file_private; + cl = cb_pos->cl; if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) { cl->reading_state = MEI_READING; buffer = cb_pos->response_buffer.data + cb_pos->buf_idx; @@ -263,7 +263,7 @@ static void mei_client_connect_response(struct mei_device *dev, } list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) { - cl = (struct mei_cl *)pos->file_private; + cl = pos->cl; if (!cl) { list_del(&pos->list); return; @@ -301,7 +301,7 @@ static void mei_client_disconnect_response(struct mei_device *dev, rs->status); list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) { - cl = (struct mei_cl *)pos->file_private; + cl = pos->cl; if (!cl) { list_del(&pos->list); @@ -981,7 +981,7 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, list = &dev->write_waiting_list; list_for_each_entry_safe(pos, next, &list->list, list) { - cl = (struct mei_cl *)pos->file_private; + cl = pos->cl; if (cl == NULL) continue; @@ -1039,7 +1039,7 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, /* complete control write list CB */ dev_dbg(&dev->pdev->dev, "complete control write list cb.\n"); list_for_each_entry_safe(pos, next, &dev->ctrl_wr_list.list, list) { - cl = (struct mei_cl *) pos->file_private; + cl = pos->cl; if (!cl) { list_del(&pos->list); return -ENODEV; @@ -1077,7 +1077,7 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, /* complete write list CB */ dev_dbg(&dev->pdev->dev, "complete write list cb.\n"); list_for_each_entry_safe(pos, next, &dev->write_list.list, list) { - cl = (struct mei_cl *)pos->file_private; + cl = pos->cl; if (cl == NULL) continue; @@ -1316,7 +1316,7 @@ end: list_for_each_entry_safe(cb_pos, cb_next, &complete_list.list, list) { - cl = (struct mei_cl *)cb_pos->file_private; + cl = cb_pos->cl; list_del(&cb_pos->list); if (cl) { if (cl != &dev->iamthif_cl) { diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index a1d9ba1a06e..cc53ce766e8 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -71,7 +71,7 @@ struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp) mei_io_list_init(cb); cb->file_object = fp; - cb->file_private = cl; + cb->cl = cl; cb->buf_idx = 0; return cb; } diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index bea545a5ae2..e0e39c498d1 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -189,13 +189,9 @@ static struct mei_cl_cb *find_read_list_entry( struct mei_cl_cb *next = NULL; dev_dbg(&dev->pdev->dev, "remove read_list CB\n"); - list_for_each_entry_safe(pos, next, &dev->read_list.list, list) { - struct mei_cl *cl_temp; - cl_temp = (struct mei_cl *)pos->file_private; - - if (mei_cl_cmp_id(cl, cl_temp)) + list_for_each_entry_safe(pos, next, &dev->read_list.list, list) + if (mei_cl_cmp_id(cl, pos->cl)) return pos; - } return NULL; } diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index ce246b0fb2d..da0c1f5eed9 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -143,10 +143,17 @@ struct mei_message_data { }; +struct mei_cl; + +/* + * struct mei_cl_cb - file operation callback structure + * + * @cl - file client who is running this operation + */ struct mei_cl_cb { struct list_head list; + struct mei_cl *cl; enum mei_cb_major_types major_file_operations; - void *file_private; struct mei_message_data request_buffer; struct mei_message_data response_buffer; unsigned long buf_idx; -- cgit v1.2.3 From 4b8960b492360c115f8214ec116f469338ac2734 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 11 Nov 2012 17:38:00 +0200 Subject: mei: rename enum mei_cb_major_types to enum mei_cb_file_ops 1. Rename mei_cb_major_types to more understandable mei_cb_file_ops 2. Rename member struct mei_cl_cb of this type to simple 'fop_type' 3. Add kernel doc for the type Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 2 +- drivers/misc/mei/init.c | 2 +- drivers/misc/mei/interrupt.c | 18 +++++++++--------- drivers/misc/mei/iorw.c | 4 ++-- drivers/misc/mei/main.c | 2 +- drivers/misc/mei/mei_dev.h | 26 +++++++++++++++++--------- 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 74d593fd6cb..34d37a9c31a 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -347,7 +347,7 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *cb) if (ret) return ret; - cb->major_file_operations = MEI_IOCTL; + cb->fop_type = MEI_FOP_IOCTL; if (!list_empty(&dev->amthif_cmd_list.list) || dev->iamthif_state != MEI_IAMTHIF_IDLE) { diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 0046ca50548..85b6520f39f 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -597,7 +597,7 @@ int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl) if (!cb) return -ENOMEM; - cb->major_file_operations = MEI_CLOSE; + cb->fop_type = MEI_FOP_CLOSE; if (dev->mei_host_buffer_is_empty) { dev->mei_host_buffer_is_empty = false; if (mei_disconnect(dev, cl)) { diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index acc994e3f20..34e20cc5460 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -57,14 +57,14 @@ irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id) */ static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos) { - if (cb_pos->major_file_operations == MEI_WRITE) { + if (cb_pos->fop_type == MEI_FOP_WRITE) { mei_io_cb_free(cb_pos); cb_pos = NULL; cl->writing_state = MEI_WRITE_COMPLETE; if (waitqueue_active(&cl->tx_wait)) wake_up_interruptible(&cl->tx_wait); - } else if (cb_pos->major_file_operations == MEI_READ && + } else if (cb_pos->fop_type == MEI_FOP_READ && MEI_READING == cl->reading_state) { cl->reading_state = MEI_READ_COMPLETE; if (waitqueue_active(&cl->rx_wait)) @@ -268,7 +268,7 @@ static void mei_client_connect_response(struct mei_device *dev, list_del(&pos->list); return; } - if (MEI_IOCTL == pos->major_file_operations) { + if (pos->fop_type == MEI_FOP_IOCTL) { if (is_treat_specially_client(cl, rs)) { list_del(&pos->list); cl->status = 0; @@ -988,8 +988,8 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, cl->status = 0; list_del(&pos->list); if (MEI_WRITING == cl->writing_state && - (pos->major_file_operations == MEI_WRITE) && - (cl != &dev->iamthif_cl)) { + pos->fop_type == MEI_FOP_WRITE && + cl != &dev->iamthif_cl) { dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n"); cl->writing_state = MEI_WRITE_COMPLETE; list_add_tail(&pos->list, &cmpl_list->list); @@ -1044,22 +1044,22 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, list_del(&pos->list); return -ENODEV; } - switch (pos->major_file_operations) { - case MEI_CLOSE: + switch (pos->fop_type) { + case MEI_FOP_CLOSE: /* send disconnect message */ ret = _mei_irq_thread_close(dev, slots, pos, cl, cmpl_list); if (ret) return ret; break; - case MEI_READ: + case MEI_FOP_READ: /* send flow control message */ ret = _mei_irq_thread_read(dev, slots, pos, cl, cmpl_list); if (ret) return ret; break; - case MEI_IOCTL: + case MEI_FOP_IOCTL: /* connect message */ if (mei_other_client_is_connecting(dev, cl)) continue; diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index cc53ce766e8..cf1107658bc 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -193,7 +193,7 @@ int mei_ioctl_connect_client(struct file *file, goto end; } - cb->major_file_operations = MEI_IOCTL; + cb->fop_type = MEI_FOP_IOCTL; if (dev->dev_state != MEI_DEV_ENABLED) { rets = -ENODEV; @@ -360,7 +360,7 @@ int mei_start_read(struct mei_device *dev, struct mei_cl *cl) if (rets) goto err; - cb->major_file_operations = MEI_READ; + cb->fop_type = MEI_FOP_READ; cl->read_cb = cb; if (dev->mei_host_buffer_is_empty) { dev->mei_host_buffer_is_empty = false; diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index e0e39c498d1..57bf96cf7ff 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -626,7 +626,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, return length; } - write_cb->major_file_operations = MEI_WRITE; + write_cb->fop_type = MEI_FOP_WRITE; dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", cl->host_client_id, cl->me_client_id); diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index da0c1f5eed9..59e94c24690 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -125,13 +125,20 @@ enum mei_wd_states { MEI_WD_STOPPING, }; -/* MEI CB */ -enum mei_cb_major_types { - MEI_READ = 0, - MEI_WRITE, - MEI_IOCTL, - MEI_OPEN, - MEI_CLOSE +/** + * enum mei_cb_file_ops - file operation associated with the callback + * @MEI_FOP_READ - read + * @MEI_FOP_WRITE - write + * @MEI_FOP_IOCTL - ioctl + * @MEI_FOP_OPEN - open + * @MEI_FOP_CLOSE - close + */ +enum mei_cb_file_ops { + MEI_FOP_READ = 0, + MEI_FOP_WRITE, + MEI_FOP_IOCTL, + MEI_FOP_OPEN, + MEI_FOP_CLOSE }; /* @@ -145,15 +152,16 @@ struct mei_message_data { struct mei_cl; -/* +/** * struct mei_cl_cb - file operation callback structure * * @cl - file client who is running this operation + * @fop_type - file operation type */ struct mei_cl_cb { struct list_head list; struct mei_cl *cl; - enum mei_cb_major_types major_file_operations; + enum mei_cb_file_ops fop_type; struct mei_message_data request_buffer; struct mei_message_data response_buffer; unsigned long buf_idx; -- cgit v1.2.3 From a562d5c25aa48c23774ab8d60bfd3bbcbca4bf1d Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 11 Nov 2012 17:38:01 +0200 Subject: mei: move amthif specific release code to amithif Move amthif code part into separate function mei_amthif_release. Also helper functions mei_clear_list and mei_clear_lists are moved along Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 114 +++++++++++++++++++++++++++++ drivers/misc/mei/main.c | 176 ++++++++++----------------------------------- drivers/misc/mei/mei_dev.h | 2 + 3 files changed, 154 insertions(+), 138 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 34d37a9c31a..8f4373aa9e2 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -596,4 +596,118 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb) wake_up_interruptible(&dev->iamthif_cl.wait); } +/** + * mei_clear_list - removes all callbacks associated with file + * from mei_cb_list + * + * @dev: device structure. + * @file: file structure + * @mei_cb_list: callbacks list + * + * mei_clear_list is called to clear resources associated with file + * when application calls close function or Ctrl-C was pressed + * + * returns true if callback removed from the list, false otherwise + */ +static bool mei_clear_list(struct mei_device *dev, + const struct file *file, struct list_head *mei_cb_list) +{ + struct mei_cl_cb *cb_pos = NULL; + struct mei_cl_cb *cb_next = NULL; + bool removed = false; + + /* list all list member */ + list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) { + /* check if list member associated with a file */ + if (file == cb_pos->file_object) { + /* remove member from the list */ + list_del(&cb_pos->list); + /* check if cb equal to current iamthif cb */ + if (dev->iamthif_current_cb == cb_pos) { + dev->iamthif_current_cb = NULL; + /* send flow control to iamthif client */ + mei_send_flow_control(dev, &dev->iamthif_cl); + } + /* free all allocated buffers */ + mei_io_cb_free(cb_pos); + cb_pos = NULL; + removed = true; + } + } + return removed; +} + +/** + * mei_clear_lists - removes all callbacks associated with file + * + * @dev: device structure + * @file: file structure + * + * mei_clear_lists is called to clear resources associated with file + * when application calls close function or Ctrl-C was pressed + * + * returns true if callback removed from the list, false otherwise + */ +static bool mei_clear_lists(struct mei_device *dev, struct file *file) +{ + bool removed = false; + + /* remove callbacks associated with a file */ + mei_clear_list(dev, file, &dev->amthif_cmd_list.list); + if (mei_clear_list(dev, file, &dev->amthif_rd_complete_list.list)) + removed = true; + mei_clear_list(dev, file, &dev->ctrl_rd_list.list); + + if (mei_clear_list(dev, file, &dev->ctrl_wr_list.list)) + removed = true; + + if (mei_clear_list(dev, file, &dev->write_waiting_list.list)) + removed = true; + + if (mei_clear_list(dev, file, &dev->write_list.list)) + removed = true; + + /* check if iamthif_current_cb not NULL */ + if (dev->iamthif_current_cb && !removed) { + /* check file and iamthif current cb association */ + if (dev->iamthif_current_cb->file_object == file) { + /* remove cb */ + mei_io_cb_free(dev->iamthif_current_cb); + dev->iamthif_current_cb = NULL; + removed = true; + } + } + return removed; +} + +/** +* mei_amthif_release - the release function +* +* @inode: pointer to inode structure +* @file: pointer to file structure +* +* returns 0 on success, <0 on error +*/ +int mei_amthif_release(struct mei_device *dev, struct file *file) +{ + if (dev->open_handle_count > 0) + dev->open_handle_count--; + + if (dev->iamthif_file_object == file && + dev->iamthif_state != MEI_IAMTHIF_IDLE) { + + dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n", + dev->iamthif_state); + dev->iamthif_canceled = true; + if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) { + dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n"); + mei_amthif_run_next_cmd(dev); + } + } + + if (mei_clear_lists(dev, file)) + dev->iamthif_state = MEI_IAMTHIF_IDLE; + + return 0; +} diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 57bf96cf7ff..43512e51795 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -89,90 +89,6 @@ MODULE_DEVICE_TABLE(pci, mei_pci_tbl); static DEFINE_MUTEX(mei_mutex); -/** - * mei_clear_list - removes all callbacks associated with file - * from mei_cb_list - * - * @dev: device structure. - * @file: file structure - * @mei_cb_list: callbacks list - * - * mei_clear_list is called to clear resources associated with file - * when application calls close function or Ctrl-C was pressed - * - * returns true if callback removed from the list, false otherwise - */ -static bool mei_clear_list(struct mei_device *dev, - const struct file *file, struct list_head *mei_cb_list) -{ - struct mei_cl_cb *cb_pos = NULL; - struct mei_cl_cb *cb_next = NULL; - bool removed = false; - - /* list all list member */ - list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, list) { - /* check if list member associated with a file */ - if (file == cb_pos->file_object) { - /* remove member from the list */ - list_del(&cb_pos->list); - /* check if cb equal to current iamthif cb */ - if (dev->iamthif_current_cb == cb_pos) { - dev->iamthif_current_cb = NULL; - /* send flow control to iamthif client */ - mei_send_flow_control(dev, &dev->iamthif_cl); - } - /* free all allocated buffers */ - mei_io_cb_free(cb_pos); - cb_pos = NULL; - removed = true; - } - } - return removed; -} - -/** - * mei_clear_lists - removes all callbacks associated with file - * - * @dev: device structure - * @file: file structure - * - * mei_clear_lists is called to clear resources associated with file - * when application calls close function or Ctrl-C was pressed - * - * returns true if callback removed from the list, false otherwise - */ -static bool mei_clear_lists(struct mei_device *dev, struct file *file) -{ - bool removed = false; - - /* remove callbacks associated with a file */ - mei_clear_list(dev, file, &dev->amthif_cmd_list.list); - if (mei_clear_list(dev, file, &dev->amthif_rd_complete_list.list)) - removed = true; - - mei_clear_list(dev, file, &dev->ctrl_rd_list.list); - - if (mei_clear_list(dev, file, &dev->ctrl_wr_list.list)) - removed = true; - - if (mei_clear_list(dev, file, &dev->write_waiting_list.list)) - removed = true; - - if (mei_clear_list(dev, file, &dev->write_list.list)) - removed = true; - - /* check if iamthif_current_cb not NULL */ - if (dev->iamthif_current_cb && !removed) { - /* check file and iamthif current cb association */ - if (dev->iamthif_current_cb->file_object == file) { - /* remove cb */ - mei_io_cb_free(dev->iamthif_current_cb); - dev->iamthif_current_cb = NULL; - removed = true; - } - } - return removed; -} /** * find_read_list_entry - find read list entry * @@ -289,67 +205,51 @@ static int mei_release(struct inode *inode, struct file *file) dev = cl->dev; mutex_lock(&dev->device_lock); - if (cl != &dev->iamthif_cl) { - if (cl->state == MEI_FILE_CONNECTED) { - cl->state = MEI_FILE_DISCONNECTING; - dev_dbg(&dev->pdev->dev, - "disconnecting client host client = %d, " - "ME client = %d\n", - cl->host_client_id, - cl->me_client_id); - rets = mei_disconnect_host_client(dev, cl); - } - mei_cl_flush_queues(cl); - dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n", + if (cl == &dev->iamthif_cl) { + rets = mei_amthif_release(dev, file); + goto out; + } + if (cl->state == MEI_FILE_CONNECTED) { + cl->state = MEI_FILE_DISCONNECTING; + dev_dbg(&dev->pdev->dev, + "disconnecting client host client = %d, " + "ME client = %d\n", cl->host_client_id, cl->me_client_id); + rets = mei_disconnect_host_client(dev, cl); + } + mei_cl_flush_queues(cl); + dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n", + cl->host_client_id, + cl->me_client_id); + + if (dev->open_handle_count > 0) { + clear_bit(cl->host_client_id, dev->host_clients_map); + dev->open_handle_count--; + } + mei_remove_client_from_file_list(dev, cl->host_client_id); - if (dev->open_handle_count > 0) { - clear_bit(cl->host_client_id, dev->host_clients_map); - dev->open_handle_count--; - } - mei_remove_client_from_file_list(dev, cl->host_client_id); - - /* free read cb */ - cb = NULL; - if (cl->read_cb) { - cb = find_read_list_entry(dev, cl); - /* Remove entry from read list */ - if (cb) - list_del(&cb->list); - - cb = cl->read_cb; - cl->read_cb = NULL; - } - - file->private_data = NULL; - - if (cb) { - mei_io_cb_free(cb); - cb = NULL; - } + /* free read cb */ + cb = NULL; + if (cl->read_cb) { + cb = find_read_list_entry(dev, cl); + /* Remove entry from read list */ + if (cb) + list_del(&cb->list); - kfree(cl); - } else { - if (dev->open_handle_count > 0) - dev->open_handle_count--; - - if (dev->iamthif_file_object == file && - dev->iamthif_state != MEI_IAMTHIF_IDLE) { - - dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n", - dev->iamthif_state); - dev->iamthif_canceled = true; - if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) { - dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n"); - mei_amthif_run_next_cmd(dev); - } - } + cb = cl->read_cb; + cl->read_cb = NULL; + } - if (mei_clear_lists(dev, file)) - dev->iamthif_state = MEI_IAMTHIF_IDLE; + file->private_data = NULL; + if (cb) { + mei_io_cb_free(cb); + cb = NULL; } + + kfree(cl); +out: mutex_unlock(&dev->device_lock); return rets; } diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 59e94c24690..bdad35e7aa5 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -389,6 +389,8 @@ int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb); int mei_amthif_read(struct mei_device *dev, struct file *file, char __user *ubuf, size_t length, loff_t *offset); +int mei_amthif_release(struct mei_device *dev, struct file *file); + struct mei_cl_cb *mei_amthif_find_read_list_entry(struct mei_device *dev, struct file *file); -- cgit v1.2.3 From 744f0f2f424d374b233cea5f9b34caa851543755 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 11 Nov 2012 17:38:02 +0200 Subject: mei: extract amthif specific code from mei_poll to mei_amthif_poll Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 19 +++++++++++++++++++ drivers/misc/mei/main.c | 10 +--------- drivers/misc/mei/mei_dev.h | 6 +++++- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 8f4373aa9e2..7416241dce8 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -401,6 +401,25 @@ void mei_amthif_run_next_cmd(struct mei_device *dev) } } + +unsigned int mei_amthif_poll(struct mei_device *dev, + struct file *file, poll_table *wait) +{ + unsigned int mask = 0; + mutex_unlock(&dev->device_lock); + poll_wait(file, &dev->iamthif_cl.wait, wait); + mutex_lock(&dev->device_lock); + if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && + dev->iamthif_file_object == file) { + mask |= (POLLIN | POLLRDNORM); + dev_dbg(&dev->pdev->dev, "run next amthi cb\n"); + mei_amthif_run_next_cmd(dev); + } + return mask; +} + + + /** * mei_amthif_irq_process_completed - processes completed iamthif operation. * diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 43512e51795..2cc1ebb131b 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -694,15 +694,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait) if (cl == &dev->iamthif_cl) { - mutex_unlock(&dev->device_lock); - poll_wait(file, &dev->iamthif_cl.wait, wait); - mutex_lock(&dev->device_lock); - if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE && - dev->iamthif_file_object == file) { - mask |= (POLLIN | POLLRDNORM); - dev_dbg(&dev->pdev->dev, "run next amthi cb\n"); - mei_amthif_run_next_cmd(dev); - } + mask = mei_amthif_poll(dev, file, wait); goto out; } diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index bdad35e7aa5..dad85f3fe39 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -19,6 +19,7 @@ #include #include +#include #include #include "hw.h" @@ -387,7 +388,10 @@ void mei_amthif_host_init(struct mei_device *dev); int mei_amthif_write(struct mei_device *dev, struct mei_cl_cb *priv_cb); int mei_amthif_read(struct mei_device *dev, struct file *file, - char __user *ubuf, size_t length, loff_t *offset); + char __user *ubuf, size_t length, loff_t *offset); + +unsigned int mei_amthif_poll(struct mei_device *dev, + struct file *file, poll_table *wait); int mei_amthif_release(struct mei_device *dev, struct file *file); -- cgit v1.2.3 From ff8b2f4e424a489222d3c7d55fb2d04c9639ef98 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 11 Nov 2012 17:38:03 +0200 Subject: mei: use link and unlink terms for connecting ME and HOST client 1. rename mei_me_cl_update_filext to mei_me_cl_link 2. rename mei_remove_client_from_file_list to mei_me_cl_unlink Code style, documenation, and usage of both function is updated Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 4 +-- drivers/misc/mei/init.c | 67 ++++++++++++++++++++++------------------------ drivers/misc/mei/iorw.c | 16 +---------- drivers/misc/mei/main.c | 6 ++--- drivers/misc/mei/mei_dev.h | 4 +-- drivers/misc/mei/wd.c | 8 +++--- 6 files changed, 44 insertions(+), 61 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 7416241dce8..095d0595a49 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -73,10 +73,10 @@ void mei_amthif_host_init(struct mei_device *dev) dev->iamthif_cl.state = MEI_FILE_DISCONNECTED; /* find ME amthi client */ - i = mei_me_cl_update_filext(dev, &dev->iamthif_cl, + i = mei_me_cl_link(dev, &dev->iamthif_cl, &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID); if (i < 0) { - dev_dbg(&dev->pdev->dev, "failed to find iamthif client.\n"); + dev_info(&dev->pdev->dev, "failed to find iamthif client.\n"); return; } diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 85b6520f39f..4fcb0bb2c9f 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -281,12 +281,10 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) cl_pos->timer_count = 0; } /* remove entry if already in list */ - dev_dbg(&dev->pdev->dev, "list del iamthif and wd file list.\n"); - mei_remove_client_from_file_list(dev, - dev->wd_cl.host_client_id); + dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n"); + mei_me_cl_unlink(dev, &dev->wd_cl); - mei_remove_client_from_file_list(dev, - dev->iamthif_cl.host_client_id); + mei_me_cl_unlink(dev, &dev->iamthif_cl); mei_amthif_reset_params(dev); dev->extra_write_index = 0; @@ -520,17 +518,20 @@ int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid) /** - * mei_me_cl_update_filext - searches for ME client guid - * sets client_id in mei_file_private if found + * mei_me_cl_link - create link between host and me clinet and add + * me_cl to the list + * * @dev: the device structure - * @cl: private file structure to set client_id in - * @cuuid: searched uuid of ME client - * @client_id: id of host client to be set in file private structure + * @cl: link between me and host client assocated with opened file descriptor + * @cuuid: uuid of ME client + * @client_id: id of the host client * - * returns ME client index + * returns ME client index if ME client + * -EINVAL on incorrect values + * -ENONET if client not found */ -int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl, - const uuid_le *cuuid, u8 host_cl_id) +int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl, + const uuid_le *cuuid, u8 host_cl_id) { int i; @@ -550,6 +551,24 @@ int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl, return -ENOENT; } +/** + * mei_me_cl_unlink - remove me_cl from the list + * + * @dev: the device structure + * @host_client_id: host client id to be removed + */ +void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl) +{ + struct mei_cl *pos, *next; + list_for_each_entry_safe(pos, next, &dev->file_list, link) { + if (cl->host_client_id == pos->host_client_id) { + dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n", + pos->host_client_id, pos->me_client_id); + list_del_init(&pos->link); + break; + } + } +} /** * mei_alloc_file_private - allocates a private file structure and sets it up. @@ -642,25 +661,3 @@ free: return rets; } -/** - * mei_remove_client_from_file_list - - * removes file private data from device file list - * - * @dev: the device structure - * @host_client_id: host client id to be removed - */ -void mei_remove_client_from_file_list(struct mei_device *dev, - u8 host_client_id) -{ - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if (host_client_id == cl_pos->host_client_id) { - dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n", - cl_pos->host_client_id, - cl_pos->me_client_id); - list_del_init(&cl_pos->link); - break; - } - } -} diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c index cf1107658bc..eb93a1b53b9 100644 --- a/drivers/misc/mei/iorw.c +++ b/drivers/misc/mei/iorw.c @@ -171,8 +171,6 @@ int mei_ioctl_connect_client(struct file *file, struct mei_cl_cb *cb; struct mei_client *client; struct mei_cl *cl; - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; long timeout = mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT); int i; int err; @@ -229,21 +227,9 @@ int mei_ioctl_connect_client(struct file *file, goto end; } clear_bit(cl->host_client_id, dev->host_clients_map); - list_for_each_entry_safe(cl_pos, cl_next, - &dev->file_list, link) { - if (mei_cl_cmp_id(cl, cl_pos)) { - dev_dbg(&dev->pdev->dev, - "remove file private data node host" - " client = %d, ME client = %d.\n", - cl_pos->host_client_id, - cl_pos->me_client_id); - list_del(&cl_pos->link); - } + mei_me_cl_unlink(dev, cl); - } - dev_dbg(&dev->pdev->dev, "free file private data memory.\n"); kfree(cl); - cl = NULL; file->private_data = &dev->iamthif_cl; diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 2cc1ebb131b..251aafff549 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -227,7 +227,7 @@ static int mei_release(struct inode *inode, struct file *file) clear_bit(cl->host_client_id, dev->host_clients_map); dev->open_handle_count--; } - mei_remove_client_from_file_list(dev, cl->host_client_id); + mei_me_cl_unlink(dev, cl); /* free read cb */ cb = NULL; @@ -913,8 +913,8 @@ static void __devexit mei_remove(struct pci_dev *pdev) /* remove entry if already in list */ dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n"); - mei_remove_client_from_file_list(dev, dev->wd_cl.host_client_id); - mei_remove_client_from_file_list(dev, dev->iamthif_cl.host_client_id); + mei_me_cl_unlink(dev, &dev->wd_cl); + mei_me_cl_unlink(dev, &dev->iamthif_cl); dev->iamthif_current_cb = NULL; dev->me_clients_num = 0; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index dad85f3fe39..aaee666577b 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -301,12 +301,12 @@ int mei_hw_init(struct mei_device *dev); int mei_task_initialize_clients(void *data); int mei_initialize_clients(struct mei_device *dev); int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl); -void mei_remove_client_from_file_list(struct mei_device *dev, u8 host_client_id); void mei_allocate_me_clients_storage(struct mei_device *dev); -int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl, +int mei_me_cl_link(struct mei_device *dev, struct mei_cl *cl, const uuid_le *cguid, u8 host_client_id); +void mei_me_cl_unlink(struct mei_device *dev, struct mei_cl *cl); int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid); int mei_me_cl_by_id(struct mei_device *dev, u8 client_id); diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 4fc2b3d4680..636409f9667 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -62,6 +62,7 @@ static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout) */ int mei_wd_host_init(struct mei_device *dev) { + int id; mei_cl_init(&dev->wd_cl, dev); /* look for WD client and connect to it */ @@ -69,12 +70,11 @@ int mei_wd_host_init(struct mei_device *dev) dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT; dev->wd_state = MEI_WD_IDLE; - /* find ME WD client */ - mei_me_cl_update_filext(dev, &dev->wd_cl, + /* Connect WD ME client to the host client */ + id = mei_me_cl_link(dev, &dev->wd_cl, &mei_wd_guid, MEI_WD_HOST_CLIENT_ID); - dev_dbg(&dev->pdev->dev, "wd: check client\n"); - if (MEI_FILE_CONNECTING != dev->wd_cl.state) { + if (id < 0) { dev_info(&dev->pdev->dev, "wd: failed to find the client\n"); return -ENOENT; } -- cgit v1.2.3 From aeba4a06f28fad11b1e61d150bd3cde3008b80c8 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 11 Nov 2012 17:38:04 +0200 Subject: mei: use the same bus msg for connect and disconnect request structs hbm_client_connect_request and hbm_client_disconnect_request have the same layout so we can drop the later Add kdoc for the request and response structure so it is clear they can be used for both purposes Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw.h | 22 ++++++++++++++++------ drivers/misc/mei/interface.c | 22 ++++++++++------------ drivers/misc/mei/interrupt.c | 17 ++++++++--------- 3 files changed, 34 insertions(+), 27 deletions(-) diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h index f21721aa4dc..be8ca6b333c 100644 --- a/drivers/misc/mei/hw.h +++ b/drivers/misc/mei/hw.h @@ -293,6 +293,14 @@ struct hbm_props_response { struct mei_client_properties client_properties; } __packed; +/** + * struct hbm_client_connect_request - connect/disconnect request + * + * @hbm_cmd - bus message command header + * @me_addr - address of the client in ME + * @host_addr - address of the client in the driver + * @reserved + */ struct hbm_client_connect_request { u8 hbm_cmd; u8 me_addr; @@ -300,6 +308,14 @@ struct hbm_client_connect_request { u8 reserved; } __packed; +/** + * struct hbm_client_connect_response - connect/disconnect response + * + * @hbm_cmd - bus message command header + * @me_addr - address of the client in ME + * @host_addr - address of the client in the driver + * @status - status of the request + */ struct hbm_client_connect_response { u8 hbm_cmd; u8 me_addr; @@ -307,12 +323,6 @@ struct hbm_client_connect_response { u8 status; } __packed; -struct hbm_client_disconnect_request { - u8 hbm_cmd; - u8 me_addr; - u8 host_addr; - u8 reserved[1]; -} __packed; #define MEI_FC_MESSAGE_RESERVED_LENGTH 5 diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 509c3957ff4..6b50cf0253e 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c @@ -352,26 +352,24 @@ int mei_other_client_is_connecting(struct mei_device *dev, int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) { struct mei_msg_hdr *mei_hdr; - struct hbm_client_disconnect_request *mei_cli_disconnect; + struct hbm_client_connect_request *req; mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; mei_hdr->host_addr = 0; mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_client_disconnect_request); + mei_hdr->length = sizeof(struct hbm_client_connect_request); mei_hdr->msg_complete = 1; mei_hdr->reserved = 0; - mei_cli_disconnect = - (struct hbm_client_disconnect_request *) &dev->wr_msg_buf[1]; - memset(mei_cli_disconnect, 0, sizeof(*mei_cli_disconnect)); - mei_cli_disconnect->host_addr = cl->host_client_id; - mei_cli_disconnect->me_addr = cl->me_client_id; - mei_cli_disconnect->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD; - mei_cli_disconnect->reserved[0] = 0; + req = (struct hbm_client_connect_request *)&dev->wr_msg_buf[1]; + memset(req, 0, sizeof(*req)); + req->host_addr = cl->host_client_id; + req->me_addr = cl->me_client_id; + req->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD; + req->reserved = 0; - return mei_write_message(dev, mei_hdr, - (unsigned char *) mei_cli_disconnect, - sizeof(struct hbm_client_disconnect_request)); + return mei_write_message(dev, mei_hdr, (unsigned char *)req, + sizeof(struct hbm_client_connect_request)); } /** diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 34e20cc5460..f8821015f3f 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -174,10 +174,10 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots, struct mei_cl_cb *cmpl_list) { if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + - sizeof(struct hbm_client_disconnect_request))) + sizeof(struct hbm_client_connect_request))) return -EBADMSG; - *slots -= mei_data2slots(sizeof(struct hbm_client_disconnect_request)); + *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); if (mei_disconnect(dev, cl)) { cl->status = 0; @@ -414,10 +414,10 @@ static void mei_client_flow_control_response(struct mei_device *dev, * returns !=0, same; 0,not. */ static int same_disconn_addr(struct mei_cl *cl, - struct hbm_client_disconnect_request *disconn) + struct hbm_client_connect_request *req) { - return (cl->host_client_id == disconn->host_addr && - cl->me_client_id == disconn->me_addr); + return (cl->host_client_id == req->host_addr && + cl->me_client_id == req->me_addr); } /** @@ -427,7 +427,7 @@ static int same_disconn_addr(struct mei_cl *cl, * @disconnect_req: disconnect request bus message. */ static void mei_client_disconnect_request(struct mei_device *dev, - struct hbm_client_disconnect_request *disconnect_req) + struct hbm_client_connect_request *disconnect_req) { struct mei_msg_hdr *mei_hdr; struct hbm_client_connect_response *disconnect_res; @@ -484,10 +484,10 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, struct hbm_host_version_response *version_res; struct hbm_client_connect_response *connect_res; struct hbm_client_connect_response *disconnect_res; + struct hbm_client_connect_request *disconnect_req; struct hbm_flow_control *flow_control; struct hbm_props_response *props_res; struct hbm_host_enum_response *enum_res; - struct hbm_client_disconnect_request *disconnect_req; struct hbm_host_stop_request *host_stop_req; int res; @@ -653,8 +653,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, case CLIENT_DISCONNECT_REQ_CMD: /* search for client */ - disconnect_req = - (struct hbm_client_disconnect_request *) mei_msg; + disconnect_req = (struct hbm_client_connect_request *)mei_msg; mei_client_disconnect_request(dev, disconnect_req); break; -- cgit v1.2.3 From 95a69adab9acfc3981c504737a2b6578e4d846ef Mon Sep 17 00:00:00 2001 From: Tomas Hozza Date: Thu, 8 Nov 2012 10:53:29 +0100 Subject: tools: hv: Netlink source address validation allows DoS The source code without this patch caused hypervkvpd to exit when it processed a spoofed Netlink packet which has been sent from an untrusted local user. Now Netlink messages with a non-zero nl_pid source address are ignored and a warning is printed into the syslog. Signed-off-by: Tomas Hozza Acked-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- tools/hv/hv_kvp_daemon.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 13c2a142331..c1d910243d4 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -1486,13 +1486,19 @@ int main(void) len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0, addr_p, &addr_l); - if (len < 0 || addr.nl_pid) { + if (len < 0) { syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s", addr.nl_pid, errno, strerror(errno)); close(fd); return -1; } + if (addr.nl_pid) { + syslog(LOG_WARNING, "Received packet from untrusted pid:%u", + addr.nl_pid); + continue; + } + incoming_msg = (struct nlmsghdr *)kvp_recv_buffer; incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg); hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data; -- cgit v1.2.3 From d892de8d3fb1e807de561289cfb1fed42950440a Mon Sep 17 00:00:00 2001 From: Tomas Hozza Date: Fri, 9 Nov 2012 15:01:20 +0100 Subject: tools/hv: Fix string types Initial patch by Ben Hutchings Standard C strings are arrays of char, not __u8 (unsigned char). Declare variables and parameters accordingly, and add the necessary casts. Signed-off-by: Tomas Hozza Acked-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- tools/hv/hv_kvp_daemon.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index c1d910243d4..d25a46925e6 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -299,7 +299,7 @@ static int kvp_file_init(void) return 0; } -static int kvp_key_delete(int pool, __u8 *key, int key_size) +static int kvp_key_delete(int pool, const char *key, int key_size) { int i; int j, k; @@ -342,7 +342,7 @@ static int kvp_key_delete(int pool, __u8 *key, int key_size) return 1; } -static int kvp_key_add_or_modify(int pool, __u8 *key, int key_size, __u8 *value, +static int kvp_key_add_or_modify(int pool, const char *key, int key_size, const char *value, int value_size) { int i; @@ -396,7 +396,7 @@ static int kvp_key_add_or_modify(int pool, __u8 *key, int key_size, __u8 *value, return 0; } -static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value, +static int kvp_get_value(int pool, const char *key, int key_size, char *value, int value_size) { int i; @@ -428,8 +428,8 @@ static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value, return 1; } -static int kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size, - __u8 *value, int value_size) +static int kvp_pool_enumerate(int pool, int index, char *key, int key_size, + char *value, int value_size) { struct kvp_record *record; -- cgit v1.2.3 From 997071bcb34005f42e0fe5bc7930e895b070f251 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 15 Nov 2012 14:34:42 -0800 Subject: mm: export a function to get vm committed memory It will be useful to be able to access global memory commitment from device drivers. On the Hyper-V platform, the host has a policy engine to balance the available physical memory amongst all competing virtual machines hosted on a given node. This policy engine is driven by a number of metrics including the memory commitment reported by the guests. The balloon driver for Linux on Hyper-V will use this function to retrieve guest memory commitment. This function is also used in Xen self ballooning code. [akpm@linux-foundation.org: coding-style tweak] Signed-off-by: K. Y. Srinivasan Acked-by: David Rientjes Acked-by: Dan Magenheimer Cc: Konrad Rzeszutek Wilk Cc: Jeremy Fitzhardinge Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/xen/xen-selfballoon.c | 2 +- include/linux/mman.h | 2 ++ mm/mmap.c | 14 ++++++++++++++ mm/nommu.c | 15 +++++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c index 7d041cb6da2..2552d3e0a70 100644 --- a/drivers/xen/xen-selfballoon.c +++ b/drivers/xen/xen-selfballoon.c @@ -222,7 +222,7 @@ static void selfballoon_process(struct work_struct *work) if (xen_selfballooning_enabled) { cur_pages = totalram_pages; tgt_pages = cur_pages; /* default is no change */ - goal_pages = percpu_counter_read_positive(&vm_committed_as) + + goal_pages = vm_memory_committed() + totalreserve_pages + MB2PAGES(selfballoon_reserved_mb); #ifdef CONFIG_FRONTSWAP diff --git a/include/linux/mman.h b/include/linux/mman.h index d09dde1e57f..9aa863da287 100644 --- a/include/linux/mman.h +++ b/include/linux/mman.h @@ -11,6 +11,8 @@ extern int sysctl_overcommit_memory; extern int sysctl_overcommit_ratio; extern struct percpu_counter vm_committed_as; +unsigned long vm_memory_committed(void); + static inline void vm_acct_memory(long pages) { percpu_counter_add(&vm_committed_as, pages); diff --git a/mm/mmap.c b/mm/mmap.c index 2d942353d68..b064822be82 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -88,6 +88,20 @@ int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT; */ struct percpu_counter vm_committed_as ____cacheline_aligned_in_smp; +/* + * The global memory commitment made in the system can be a metric + * that can be used to drive ballooning decisions when Linux is hosted + * as a guest. On Hyper-V, the host implements a policy engine for dynamically + * balancing memory across competing virtual machines that are hosted. + * Several metrics drive this policy engine including the guest reported + * memory commitment. + */ +unsigned long vm_memory_committed(void) +{ + return percpu_counter_read_positive(&vm_committed_as); +} +EXPORT_SYMBOL_GPL(vm_memory_committed); + /* * Check that a process has enough memory to allocate a new virtual * mapping. 0 means there is enough memory for the allocation to diff --git a/mm/nommu.c b/mm/nommu.c index 45131b41bcd..79c3cac87af 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -66,6 +66,21 @@ int heap_stack_gap = 0; atomic_long_t mmap_pages_allocated; +/* + * The global memory commitment made in the system can be a metric + * that can be used to drive ballooning decisions when Linux is hosted + * as a guest. On Hyper-V, the host implements a policy engine for dynamically + * balancing memory across competing virtual machines that are hosted. + * Several metrics drive this policy engine including the guest reported + * memory commitment. + */ +unsigned long vm_memory_committed(void) +{ + return percpu_counter_read_positive(&vm_committed_as); +} + +EXPORT_SYMBOL_GPL(vm_memory_committed); + EXPORT_SYMBOL(mem_map); EXPORT_SYMBOL(num_physpages); -- cgit v1.2.3 From 9aa8b50b2b3d3a70728438a15a0fdd03a6794a84 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 14 Nov 2012 01:09:02 -0800 Subject: Drivers: hv: Add Hyper-V balloon driver Add the basic balloon driver. Windows hosts dynamically manage the guest memory allocation via a combination memory hot add and ballooning. Memory hot add is used to grow the guest memory upto the maximum memory that can be allocatted to the guest. Ballooning is used to both shrink as well as expand up to the max memory. Supporting hot add needs additional support from the host. We will support hot add when this support is available. For now, by setting the VM startup memory to the VM max memory, we can use ballooning alone to dynamically manage memory allocation amongst competing guests on a given host. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/Kconfig | 6 + drivers/hv/Makefile | 1 + drivers/hv/hv_balloon.c | 1041 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1048 insertions(+) create mode 100644 drivers/hv/hv_balloon.c diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig index 70f5dde1cc5..b38ef6d8d04 100644 --- a/drivers/hv/Kconfig +++ b/drivers/hv/Kconfig @@ -13,4 +13,10 @@ config HYPERV_UTILS help Select this option to enable the Hyper-V Utilities. +config HYPERV_BALLOON + tristate "Microsoft Hyper-V Balloon driver" + depends on HYPERV + help + Select this option to enable Hyper-V Balloon driver. + endmenu diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile index a23938b991c..e6abfa02d8b 100644 --- a/drivers/hv/Makefile +++ b/drivers/hv/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_HYPERV) += hv_vmbus.o obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o +obj-$(CONFIG_HYPERV_BALLOON) += hv_balloon.o hv_vmbus-y := vmbus_drv.o \ hv.o connection.o channel.o \ diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c new file mode 100644 index 00000000000..bbc497373aa --- /dev/null +++ b/drivers/hv/hv_balloon.c @@ -0,0 +1,1041 @@ +/* + * Copyright (c) 2012, Microsoft Corporation. + * + * Author: + * K. Y. Srinivasan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * We begin with definitions supporting the Dynamic Memory protocol + * with the host. + * + * Begin protocol definitions. + */ + + + +/* + * Protocol versions. The low word is the minor version, the high word the major + * version. + * + * History: + * Initial version 1.0 + * Changed to 0.1 on 2009/03/25 + * Changes to 0.2 on 2009/05/14 + * Changes to 0.3 on 2009/12/03 + * Changed to 1.0 on 2011/04/05 + */ + +#define DYNMEM_MAKE_VERSION(Major, Minor) ((__u32)(((Major) << 16) | (Minor))) +#define DYNMEM_MAJOR_VERSION(Version) ((__u32)(Version) >> 16) +#define DYNMEM_MINOR_VERSION(Version) ((__u32)(Version) & 0xff) + +enum { + DYNMEM_PROTOCOL_VERSION_1 = DYNMEM_MAKE_VERSION(0, 3), + DYNMEM_PROTOCOL_VERSION_2 = DYNMEM_MAKE_VERSION(1, 0), + + DYNMEM_PROTOCOL_VERSION_WIN7 = DYNMEM_PROTOCOL_VERSION_1, + DYNMEM_PROTOCOL_VERSION_WIN8 = DYNMEM_PROTOCOL_VERSION_2, + + DYNMEM_PROTOCOL_VERSION_CURRENT = DYNMEM_PROTOCOL_VERSION_WIN8 +}; + + + +/* + * Message Types + */ + +enum dm_message_type { + /* + * Version 0.3 + */ + DM_ERROR = 0, + DM_VERSION_REQUEST = 1, + DM_VERSION_RESPONSE = 2, + DM_CAPABILITIES_REPORT = 3, + DM_CAPABILITIES_RESPONSE = 4, + DM_STATUS_REPORT = 5, + DM_BALLOON_REQUEST = 6, + DM_BALLOON_RESPONSE = 7, + DM_UNBALLOON_REQUEST = 8, + DM_UNBALLOON_RESPONSE = 9, + DM_MEM_HOT_ADD_REQUEST = 10, + DM_MEM_HOT_ADD_RESPONSE = 11, + DM_VERSION_03_MAX = 11, + /* + * Version 1.0. + */ + DM_INFO_MESSAGE = 12, + DM_VERSION_1_MAX = 12 +}; + + +/* + * Structures defining the dynamic memory management + * protocol. + */ + +union dm_version { + struct { + __u16 minor_version; + __u16 major_version; + }; + __u32 version; +} __packed; + + +union dm_caps { + struct { + __u64 balloon:1; + __u64 hot_add:1; + __u64 reservedz:62; + } cap_bits; + __u64 caps; +} __packed; + +union dm_mem_page_range { + struct { + /* + * The PFN number of the first page in the range. + * 40 bits is the architectural limit of a PFN + * number for AMD64. + */ + __u64 start_page:40; + /* + * The number of pages in the range. + */ + __u64 page_cnt:24; + } finfo; + __u64 page_range; +} __packed; + + + +/* + * The header for all dynamic memory messages: + * + * type: Type of the message. + * size: Size of the message in bytes; including the header. + * trans_id: The guest is responsible for manufacturing this ID. + */ + +struct dm_header { + __u16 type; + __u16 size; + __u32 trans_id; +} __packed; + +/* + * A generic message format for dynamic memory. + * Specific message formats are defined later in the file. + */ + +struct dm_message { + struct dm_header hdr; + __u8 data[]; /* enclosed message */ +} __packed; + + +/* + * Specific message types supporting the dynamic memory protocol. + */ + +/* + * Version negotiation message. Sent from the guest to the host. + * The guest is free to try different versions until the host + * accepts the version. + * + * dm_version: The protocol version requested. + * is_last_attempt: If TRUE, this is the last version guest will request. + * reservedz: Reserved field, set to zero. + */ + +struct dm_version_request { + struct dm_header hdr; + union dm_version version; + __u32 is_last_attempt:1; + __u32 reservedz:31; +} __packed; + +/* + * Version response message; Host to Guest and indicates + * if the host has accepted the version sent by the guest. + * + * is_accepted: If TRUE, host has accepted the version and the guest + * should proceed to the next stage of the protocol. FALSE indicates that + * guest should re-try with a different version. + * + * reservedz: Reserved field, set to zero. + */ + +struct dm_version_response { + struct dm_header hdr; + __u64 is_accepted:1; + __u64 reservedz:63; +} __packed; + +/* + * Message reporting capabilities. This is sent from the guest to the + * host. + */ + +struct dm_capabilities { + struct dm_header hdr; + union dm_caps caps; + __u64 min_page_cnt; + __u64 max_page_number; +} __packed; + +/* + * Response to the capabilities message. This is sent from the host to the + * guest. This message notifies if the host has accepted the guest's + * capabilities. If the host has not accepted, the guest must shutdown + * the service. + * + * is_accepted: Indicates if the host has accepted guest's capabilities. + * reservedz: Must be 0. + */ + +struct dm_capabilities_resp_msg { + struct dm_header hdr; + __u64 is_accepted:1; + __u64 reservedz:63; +} __packed; + +/* + * This message is used to report memory pressure from the guest. + * This message is not part of any transaction and there is no + * response to this message. + * + * num_avail: Available memory in pages. + * num_committed: Committed memory in pages. + * page_file_size: The accumulated size of all page files + * in the system in pages. + * zero_free: The nunber of zero and free pages. + * page_file_writes: The writes to the page file in pages. + * io_diff: An indicator of file cache efficiency or page file activity, + * calculated as File Cache Page Fault Count - Page Read Count. + * This value is in pages. + * + * Some of these metrics are Windows specific and fortunately + * the algorithm on the host side that computes the guest memory + * pressure only uses num_committed value. + */ + +struct dm_status { + struct dm_header hdr; + __u64 num_avail; + __u64 num_committed; + __u64 page_file_size; + __u64 zero_free; + __u32 page_file_writes; + __u32 io_diff; +} __packed; + + +/* + * Message to ask the guest to allocate memory - balloon up message. + * This message is sent from the host to the guest. The guest may not be + * able to allocate as much memory as requested. + * + * num_pages: number of pages to allocate. + */ + +struct dm_balloon { + struct dm_header hdr; + __u32 num_pages; + __u32 reservedz; +} __packed; + + +/* + * Balloon response message; this message is sent from the guest + * to the host in response to the balloon message. + * + * reservedz: Reserved; must be set to zero. + * more_pages: If FALSE, this is the last message of the transaction. + * if TRUE there will atleast one more message from the guest. + * + * range_count: The number of ranges in the range array. + * + * range_array: An array of page ranges returned to the host. + * + */ + +struct dm_balloon_response { + struct dm_header hdr; + __u32 reservedz; + __u32 more_pages:1; + __u32 range_count:31; + union dm_mem_page_range range_array[]; +} __packed; + +/* + * Un-balloon message; this message is sent from the host + * to the guest to give guest more memory. + * + * more_pages: If FALSE, this is the last message of the transaction. + * if TRUE there will atleast one more message from the guest. + * + * reservedz: Reserved; must be set to zero. + * + * range_count: The number of ranges in the range array. + * + * range_array: An array of page ranges returned to the host. + * + */ + +struct dm_unballoon_request { + struct dm_header hdr; + __u32 more_pages:1; + __u32 reservedz:31; + __u32 range_count; + union dm_mem_page_range range_array[]; +} __packed; + +/* + * Un-balloon response message; this message is sent from the guest + * to the host in response to an unballoon request. + * + */ + +struct dm_unballoon_response { + struct dm_header hdr; +} __packed; + + +/* + * Hot add request message. Message sent from the host to the guest. + * + * mem_range: Memory range to hot add. + * + * On Linux we currently don't support this since we cannot hot add + * arbitrary granularity of memory. + */ + +struct dm_hot_add { + struct dm_header hdr; + union dm_mem_page_range range; +} __packed; + +/* + * Hot add response message. + * This message is sent by the guest to report the status of a hot add request. + * If page_count is less than the requested page count, then the host should + * assume all further hot add requests will fail, since this indicates that + * the guest has hit an upper physical memory barrier. + * + * Hot adds may also fail due to low resources; in this case, the guest must + * not complete this message until the hot add can succeed, and the host must + * not send a new hot add request until the response is sent. + * If VSC fails to hot add memory DYNMEM_NUMBER_OF_UNSUCCESSFUL_HOTADD_ATTEMPTS + * times it fails the request. + * + * + * page_count: number of pages that were successfully hot added. + * + * result: result of the operation 1: success, 0: failure. + * + */ + +struct dm_hot_add_response { + struct dm_header hdr; + __u32 page_count; + __u32 result; +} __packed; + +/* + * Types of information sent from host to the guest. + */ + +enum dm_info_type { + INFO_TYPE_MAX_PAGE_CNT = 0, + MAX_INFO_TYPE +}; + + +/* + * Header for the information message. + */ + +struct dm_info_header { + enum dm_info_type type; + __u32 data_size; +} __packed; + +/* + * This message is sent from the host to the guest to pass + * some relevant information (win8 addition). + * + * reserved: no used. + * info_size: size of the information blob. + * info: information blob. + */ + +struct dm_info_msg { + struct dm_info_header header; + __u32 reserved; + __u32 info_size; + __u8 info[]; +}; + +/* + * End protocol definitions. + */ + +static bool hot_add; +static bool do_hot_add; + +module_param(hot_add, bool, (S_IRUGO | S_IWUSR)); +MODULE_PARM_DESC(hot_add, "If set attempt memory hot_add"); + +static atomic_t trans_id = ATOMIC_INIT(0); + +static int dm_ring_size = (5 * PAGE_SIZE); + +/* + * Driver specific state. + */ + +enum hv_dm_state { + DM_INITIALIZING = 0, + DM_INITIALIZED, + DM_BALLOON_UP, + DM_BALLOON_DOWN, + DM_HOT_ADD, + DM_INIT_ERROR +}; + + +static __u8 recv_buffer[PAGE_SIZE]; +static __u8 *send_buffer; +#define PAGES_IN_2M 512 + +struct hv_dynmem_device { + struct hv_device *dev; + enum hv_dm_state state; + struct completion host_event; + struct completion config_event; + + /* + * Number of pages we have currently ballooned out. + */ + unsigned int num_pages_ballooned; + + /* + * This thread handles both balloon/hot-add + * requests from the host as well as notifying + * the host with regards to memory pressure in + * the guest. + */ + struct task_struct *thread; + + /* + * We start with the highest version we can support + * and downgrade based on the host; we save here the + * next version to try. + */ + __u32 next_version; +}; + +static struct hv_dynmem_device dm_device; + +static void hot_add_req(struct hv_dynmem_device *dm, struct dm_hot_add *msg) +{ + + struct dm_hot_add_response resp; + + if (do_hot_add) { + + pr_info("Memory hot add not supported\n"); + + /* + * Currently we do not support hot add. + * Just fail the request. + */ + } + + memset(&resp, 0, sizeof(struct dm_hot_add_response)); + resp.hdr.type = DM_MEM_HOT_ADD_RESPONSE; + resp.hdr.size = sizeof(struct dm_hot_add_response); + resp.hdr.trans_id = atomic_inc_return(&trans_id); + + resp.page_count = 0; + resp.result = 0; + + dm->state = DM_INITIALIZED; + vmbus_sendpacket(dm->dev->channel, &resp, + sizeof(struct dm_hot_add_response), + (unsigned long)NULL, + VM_PKT_DATA_INBAND, 0); + +} + +static void process_info(struct hv_dynmem_device *dm, struct dm_info_msg *msg) +{ + switch (msg->header.type) { + case INFO_TYPE_MAX_PAGE_CNT: + pr_info("Received INFO_TYPE_MAX_PAGE_CNT\n"); + pr_info("Data Size is %d\n", msg->header.data_size); + break; + default: + pr_info("Received Unknown type: %d\n", msg->header.type); + } +} + +/* + * Post our status as it relates memory pressure to the + * host. Host expects the guests to post this status + * periodically at 1 second intervals. + * + * The metrics specified in this protocol are very Windows + * specific and so we cook up numbers here to convey our memory + * pressure. + */ + +static void post_status(struct hv_dynmem_device *dm) +{ + struct dm_status status; + + + memset(&status, 0, sizeof(struct dm_status)); + status.hdr.type = DM_STATUS_REPORT; + status.hdr.size = sizeof(struct dm_status); + status.hdr.trans_id = atomic_inc_return(&trans_id); + + + status.num_committed = vm_memory_committed(); + + vmbus_sendpacket(dm->dev->channel, &status, + sizeof(struct dm_status), + (unsigned long)NULL, + VM_PKT_DATA_INBAND, 0); + +} + + + +void free_balloon_pages(struct hv_dynmem_device *dm, + union dm_mem_page_range *range_array) +{ + int num_pages = range_array->finfo.page_cnt; + __u64 start_frame = range_array->finfo.start_page; + struct page *pg; + int i; + + for (i = 0; i < num_pages; i++) { + pg = pfn_to_page(i + start_frame); + __free_page(pg); + dm->num_pages_ballooned--; + } +} + + + +static int alloc_balloon_pages(struct hv_dynmem_device *dm, int num_pages, + struct dm_balloon_response *bl_resp, int alloc_unit, + bool *alloc_error) +{ + int i = 0; + struct page *pg; + + if (num_pages < alloc_unit) + return 0; + + for (i = 0; (i * alloc_unit) < num_pages; i++) { + if (bl_resp->hdr.size + sizeof(union dm_mem_page_range) > + PAGE_SIZE) + return i * alloc_unit; + + /* + * We execute this code in a thread context. Furthermore, + * we don't want the kernel to try too hard. + */ + pg = alloc_pages(GFP_HIGHUSER | __GFP_NORETRY | + __GFP_NOMEMALLOC | __GFP_NOWARN, + get_order(alloc_unit << PAGE_SHIFT)); + + if (!pg) { + *alloc_error = true; + return i * alloc_unit; + } + + + dm->num_pages_ballooned += alloc_unit; + + bl_resp->range_count++; + bl_resp->range_array[i].finfo.start_page = + page_to_pfn(pg); + bl_resp->range_array[i].finfo.page_cnt = alloc_unit; + bl_resp->hdr.size += sizeof(union dm_mem_page_range); + + } + + return num_pages; +} + + + +static void balloon_up(struct hv_dynmem_device *dm, struct dm_balloon *req) +{ + int num_pages = req->num_pages; + int num_ballooned = 0; + struct dm_balloon_response *bl_resp; + int alloc_unit; + int ret; + bool alloc_error = false; + bool done = false; + int i; + + + /* + * Currently, we only support 4k allocations. + */ + alloc_unit = 1; + + while (!done) { + bl_resp = (struct dm_balloon_response *)send_buffer; + memset(send_buffer, 0, PAGE_SIZE); + bl_resp->hdr.type = DM_BALLOON_RESPONSE; + bl_resp->hdr.trans_id = atomic_inc_return(&trans_id); + bl_resp->hdr.size = sizeof(struct dm_balloon_response); + bl_resp->more_pages = 1; + + + num_pages -= num_ballooned; + num_ballooned = alloc_balloon_pages(dm, num_pages, + bl_resp, alloc_unit, + &alloc_error); + + if ((alloc_error) || (num_ballooned == num_pages)) { + bl_resp->more_pages = 0; + done = true; + dm->state = DM_INITIALIZED; + } + + /* + * We are pushing a lot of data through the channel; + * deal with transient failures caused because of the + * lack of space in the ring buffer. + */ + + do { + ret = vmbus_sendpacket(dm_device.dev->channel, + bl_resp, + bl_resp->hdr.size, + (unsigned long)NULL, + VM_PKT_DATA_INBAND, 0); + + if (ret == -EAGAIN) + msleep(20); + + } while (ret == -EAGAIN); + + if (ret) { + /* + * Free up the memory we allocatted. + */ + pr_info("Balloon response failed\n"); + + for (i = 0; i < bl_resp->range_count; i++) + free_balloon_pages(dm, + &bl_resp->range_array[i]); + + done = true; + } + } + +} + +static void balloon_down(struct hv_dynmem_device *dm, + struct dm_unballoon_request *req) +{ + union dm_mem_page_range *range_array = req->range_array; + int range_count = req->range_count; + struct dm_unballoon_response resp; + int i; + + for (i = 0; i < range_count; i++) + free_balloon_pages(dm, &range_array[i]); + + if (req->more_pages == 1) + return; + + memset(&resp, 0, sizeof(struct dm_unballoon_response)); + resp.hdr.type = DM_UNBALLOON_RESPONSE; + resp.hdr.trans_id = atomic_inc_return(&trans_id); + resp.hdr.size = sizeof(struct dm_unballoon_response); + + vmbus_sendpacket(dm_device.dev->channel, &resp, + sizeof(struct dm_unballoon_response), + (unsigned long)NULL, + VM_PKT_DATA_INBAND, 0); + + dm->state = DM_INITIALIZED; +} + +static void balloon_onchannelcallback(void *context); + +static int dm_thread_func(void *dm_dev) +{ + struct hv_dynmem_device *dm = dm_dev; + int t; + unsigned long scan_start; + + while (!kthread_should_stop()) { + t = wait_for_completion_timeout(&dm_device.config_event, 1*HZ); + /* + * The host expects us to post information on the memory + * pressure every second. + */ + + if (t == 0) + post_status(dm); + + scan_start = jiffies; + switch (dm->state) { + case DM_BALLOON_UP: + balloon_up(dm, (struct dm_balloon *)recv_buffer); + break; + + case DM_HOT_ADD: + hot_add_req(dm, (struct dm_hot_add *)recv_buffer); + break; + default: + break; + } + + if (!time_in_range(jiffies, scan_start, scan_start + HZ)) + post_status(dm); + + } + + return 0; +} + + +static void version_resp(struct hv_dynmem_device *dm, + struct dm_version_response *vresp) +{ + struct dm_version_request version_req; + int ret; + + if (vresp->is_accepted) { + /* + * We are done; wakeup the + * context waiting for version + * negotiation. + */ + complete(&dm->host_event); + return; + } + /* + * If there are more versions to try, continue + * with negotiations; if not + * shutdown the service since we are not able + * to negotiate a suitable version number + * with the host. + */ + if (dm->next_version == 0) + goto version_error; + + dm->next_version = 0; + memset(&version_req, 0, sizeof(struct dm_version_request)); + version_req.hdr.type = DM_VERSION_REQUEST; + version_req.hdr.size = sizeof(struct dm_version_request); + version_req.hdr.trans_id = atomic_inc_return(&trans_id); + version_req.version.version = DYNMEM_PROTOCOL_VERSION_WIN7; + version_req.is_last_attempt = 1; + + ret = vmbus_sendpacket(dm->dev->channel, &version_req, + sizeof(struct dm_version_request), + (unsigned long)NULL, + VM_PKT_DATA_INBAND, 0); + + if (ret) + goto version_error; + + return; + +version_error: + dm->state = DM_INIT_ERROR; + complete(&dm->host_event); +} + +static void cap_resp(struct hv_dynmem_device *dm, + struct dm_capabilities_resp_msg *cap_resp) +{ + if (!cap_resp->is_accepted) { + pr_info("Capabilities not accepted by host\n"); + dm->state = DM_INIT_ERROR; + } + complete(&dm->host_event); +} + +static void balloon_onchannelcallback(void *context) +{ + struct hv_device *dev = context; + u32 recvlen; + u64 requestid; + struct dm_message *dm_msg; + struct dm_header *dm_hdr; + struct hv_dynmem_device *dm = hv_get_drvdata(dev); + + memset(recv_buffer, 0, sizeof(recv_buffer)); + vmbus_recvpacket(dev->channel, recv_buffer, + PAGE_SIZE, &recvlen, &requestid); + + if (recvlen > 0) { + dm_msg = (struct dm_message *)recv_buffer; + dm_hdr = &dm_msg->hdr; + + switch (dm_hdr->type) { + case DM_VERSION_RESPONSE: + version_resp(dm, + (struct dm_version_response *)dm_msg); + break; + + case DM_CAPABILITIES_RESPONSE: + cap_resp(dm, + (struct dm_capabilities_resp_msg *)dm_msg); + break; + + case DM_BALLOON_REQUEST: + dm->state = DM_BALLOON_UP; + complete(&dm->config_event); + break; + + case DM_UNBALLOON_REQUEST: + dm->state = DM_BALLOON_DOWN; + balloon_down(dm, + (struct dm_unballoon_request *)recv_buffer); + break; + + case DM_MEM_HOT_ADD_REQUEST: + dm->state = DM_HOT_ADD; + complete(&dm->config_event); + break; + + case DM_INFO_MESSAGE: + process_info(dm, (struct dm_info_msg *)dm_msg); + break; + + default: + pr_err("Unhandled message: type: %d\n", dm_hdr->type); + + } + } + +} + +static int balloon_probe(struct hv_device *dev, + const struct hv_vmbus_device_id *dev_id) +{ + int ret, t; + struct dm_version_request version_req; + struct dm_capabilities cap_msg; + + do_hot_add = hot_add; + + /* + * First allocate a send buffer. + */ + + send_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!send_buffer) + return -ENOMEM; + + ret = vmbus_open(dev->channel, dm_ring_size, dm_ring_size, NULL, 0, + balloon_onchannelcallback, dev); + + if (ret) + return ret; + + dm_device.dev = dev; + dm_device.state = DM_INITIALIZING; + dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN7; + init_completion(&dm_device.host_event); + init_completion(&dm_device.config_event); + + dm_device.thread = + kthread_run(dm_thread_func, &dm_device, "hv_balloon"); + if (IS_ERR(dm_device.thread)) { + ret = PTR_ERR(dm_device.thread); + goto probe_error0; + } + + hv_set_drvdata(dev, &dm_device); + /* + * Initiate the hand shake with the host and negotiate + * a version that the host can support. We start with the + * highest version number and go down if the host cannot + * support it. + */ + memset(&version_req, 0, sizeof(struct dm_version_request)); + version_req.hdr.type = DM_VERSION_REQUEST; + version_req.hdr.size = sizeof(struct dm_version_request); + version_req.hdr.trans_id = atomic_inc_return(&trans_id); + version_req.version.version = DYNMEM_PROTOCOL_VERSION_WIN8; + version_req.is_last_attempt = 0; + + ret = vmbus_sendpacket(dev->channel, &version_req, + sizeof(struct dm_version_request), + (unsigned long)NULL, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret) + goto probe_error1; + + t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ); + if (t == 0) { + ret = -ETIMEDOUT; + goto probe_error1; + } + + /* + * If we could not negotiate a compatible version with the host + * fail the probe function. + */ + if (dm_device.state == DM_INIT_ERROR) { + ret = -ETIMEDOUT; + goto probe_error1; + } + /* + * Now submit our capabilities to the host. + */ + memset(&cap_msg, 0, sizeof(struct dm_capabilities)); + cap_msg.hdr.type = DM_CAPABILITIES_REPORT; + cap_msg.hdr.size = sizeof(struct dm_capabilities); + cap_msg.hdr.trans_id = atomic_inc_return(&trans_id); + + cap_msg.caps.cap_bits.balloon = 1; + /* + * While we currently don't support hot-add, + * we still advertise this capability since the + * host requires that guests partcipating in the + * dynamic memory protocol support hot add. + */ + cap_msg.caps.cap_bits.hot_add = 1; + + /* + * Currently the host does not use these + * values and we set them to what is done in the + * Windows driver. + */ + cap_msg.min_page_cnt = 0; + cap_msg.max_page_number = -1; + + ret = vmbus_sendpacket(dev->channel, &cap_msg, + sizeof(struct dm_capabilities), + (unsigned long)NULL, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (ret) + goto probe_error1; + + t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ); + if (t == 0) { + ret = -ETIMEDOUT; + goto probe_error1; + } + + /* + * If the host does not like our capabilities, + * fail the probe function. + */ + if (dm_device.state == DM_INIT_ERROR) { + ret = -ETIMEDOUT; + goto probe_error1; + } + + dm_device.state = DM_INITIALIZED; + + return 0; + +probe_error1: + kthread_stop(dm_device.thread); + +probe_error0: + vmbus_close(dev->channel); + return ret; +} + +static int balloon_remove(struct hv_device *dev) +{ + struct hv_dynmem_device *dm = hv_get_drvdata(dev); + + if (dm->num_pages_ballooned != 0) + pr_warn("Ballooned pages: %d\n", dm->num_pages_ballooned); + + vmbus_close(dev->channel); + kthread_stop(dm->thread); + + return 0; +} + +static const struct hv_vmbus_device_id id_table[] = { + /* Dynamic Memory Class ID */ + /* 525074DC-8985-46e2-8057-A307DC18A502 */ + { VMBUS_DEVICE(0xdc, 0x74, 0x50, 0X52, 0x85, 0x89, 0xe2, 0x46, + 0x80, 0x57, 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02) + }, + { }, +}; + +MODULE_DEVICE_TABLE(vmbus, id_table); + +static struct hv_driver balloon_drv = { + .name = "hv_balloon", + .id_table = id_table, + .probe = balloon_probe, + .remove = balloon_remove, +}; + +static int __init init_balloon_drv(void) +{ + + return vmbus_driver_register(&balloon_drv); +} + +static void exit_balloon_drv(void) +{ + + vmbus_driver_unregister(&balloon_drv); +} + +module_init(init_balloon_drv); +module_exit(exit_balloon_drv); + +MODULE_DESCRIPTION("Hyper-V Balloon"); +MODULE_VERSION(HV_DRV_VERSION); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 888155bbf63a5f955d7a45932ff05e848f715bf0 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 12 Nov 2012 11:07:24 +0000 Subject: vmwgfx: return an -EFAULT if copy_to_user() fails copy_to_user() returns the number of bytes remaining to be copied, but we want to return a negative error code here. I fixed a couple of these last year, but I missed this one. Signed-off-by: Dan Carpenter Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index b07ca2e4d04..7290811f89b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -110,6 +110,8 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, memcpy_fromio(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); ret = copy_to_user(buffer, bounce, size); + if (ret) + ret = -EFAULT; vfree(bounce); if (unlikely(ret != 0)) -- cgit v1.2.3 From ac207ed2471150e06af0afc76e4becc701fa2733 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 13 Nov 2012 18:31:55 +0000 Subject: ttm: Clear the ttm page allocated from high memory zone correctly The TTM page can be allocated from high memory. In such case it is wrong to use the page_address(page) as the virtual address for the high memory page. bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=50241 Signed-off-by: Zhao Yakui Cc: stable@vger.kernel.org Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_page_alloc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 860dc4813e9..bd2a3b40cd1 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c @@ -749,7 +749,10 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, /* clear the pages coming from the pool if requested */ if (flags & TTM_PAGE_FLAG_ZERO_ALLOC) { list_for_each_entry(p, &plist, lru) { - clear_page(page_address(p)); + if (PageHighMem(p)) + clear_highpage(p); + else + clear_page(page_address(p)); } } -- cgit v1.2.3 From 55aa914e9274cf1d55397cc04eb926eb055c79f7 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 9 Nov 2012 12:10:43 +0000 Subject: drm/ttm: remove unneeded preempt_disable/enable It is unnecessary to disable preemption explicitly while calling copy_highpage(). Because copy_highpage() will do it again through kmap_atomic/kunmap_atomic. Signed-off-by: Akinobu Mita Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_tt.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index bf8260133ea..7d759a43029 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -308,9 +308,7 @@ int ttm_tt_swapin(struct ttm_tt *ttm) if (unlikely(to_page == NULL)) goto out_err; - preempt_disable(); copy_highpage(to_page, from_page); - preempt_enable(); page_cache_release(from_page); } @@ -358,9 +356,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage) ret = PTR_ERR(to_page); goto out_err; } - preempt_disable(); copy_highpage(to_page, from_page); - preempt_enable(); set_page_dirty(to_page); mark_page_accessed(to_page); page_cache_release(to_page); -- cgit v1.2.3 From c3c9b370ea4fa2566dfb0c3d88d9f02be0533e7a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 16 Nov 2012 09:26:41 +0900 Subject: ASoC: bells: Fix up git patch application failure It seems git has been getting confused by the very similar contexts for the speaker DAIs and has been applying patches to the wrong places causing all sorts of confusion. Fix this up by hand. Reported-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/samsung/bells.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index b56b9a3c616..a2ca1567b9e 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c @@ -212,7 +212,7 @@ static struct snd_soc_dai_link bells_dai_wm5102[] = { { .name = "Sub", .stream_name = "Sub", - .cpu_dai_name = "wm5110-aif3", + .cpu_dai_name = "wm5102-aif3", .codec_dai_name = "wm9081-hifi", .codec_name = "wm9081.1-006c", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF @@ -247,7 +247,7 @@ static struct snd_soc_dai_link bells_dai_wm5110[] = { { .name = "Sub", .stream_name = "Sub", - .cpu_dai_name = "wm5102-aif3", + .cpu_dai_name = "wm5110-aif3", .codec_dai_name = "wm9081-hifi", .codec_name = "wm9081.1-006c", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF -- cgit v1.2.3 From 96e1f18fbb8c146aee9cdad1ebc510b8ccf94b6f Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 15 Nov 2012 11:41:30 +0000 Subject: ASoC: arizona: Fix typo - Swap value in 48k_rates[] and 44k1_rates[] Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/arizona.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c index c03b65af305..054967d8bac 100644 --- a/sound/soc/codecs/arizona.c +++ b/sound/soc/codecs/arizona.c @@ -268,7 +268,7 @@ EXPORT_SYMBOL_GPL(arizona_out_ev); static unsigned int arizona_sysclk_48k_rates[] = { 6144000, 12288000, - 22579200, + 24576000, 49152000, 73728000, 98304000, @@ -278,7 +278,7 @@ static unsigned int arizona_sysclk_48k_rates[] = { static unsigned int arizona_sysclk_44k1_rates[] = { 5644800, 11289600, - 24576000, + 22579200, 45158400, 67737600, 90316800, -- cgit v1.2.3 From 1b2f8a9550f92686fb76f9dd4d0ec7c0c3f1b027 Mon Sep 17 00:00:00 2001 From: chao bi Date: Tue, 6 Nov 2012 11:13:59 +0800 Subject: serial:ifx6x60:SPI header is decoded incorrectly This patch is to correct the bit mapping of "MORE" and "CTS" in SPI frame header. Per SPI protocol, SPI header is encoded with length of 4 byte, which is defined as below: bit 0 ~ 11: current data size; bit 12: "MORE" bit; bit 13: reserve bit 14 ~ 15: reserve bit 16 ~ 27: next data size bit 28: RI bit 29: DCD bit 30: CTS/RTS bit 31: DSR/DTR According to above SPI header structure, the bit mapping of "MORE" and "CTS" is incorrect in function ifx_spi_decode_spi_header(); Cc: Chen Jun Signed-off-by: channing Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index fbda37415f0..21eb70bcb6a 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -64,8 +64,8 @@ #include "ifx6x60.h" #define IFX_SPI_MORE_MASK 0x10 -#define IFX_SPI_MORE_BIT 12 /* bit position in u16 */ -#define IFX_SPI_CTS_BIT 13 /* bit position in u16 */ +#define IFX_SPI_MORE_BIT 4 /* bit position in u8 */ +#define IFX_SPI_CTS_BIT 6 /* bit position in u8 */ #define IFX_SPI_MODE SPI_MODE_1 #define IFX_SPI_TTY_ID 0 #define IFX_SPI_TIMEOUT_SEC 2 -- cgit v1.2.3 From e8823f1ca8d5a0c5d69a8862682ee8bde26990ca Mon Sep 17 00:00:00 2001 From: Jun Chen Date: Wed, 7 Nov 2012 12:04:04 -0500 Subject: serial: ifx6x60: ifx_spi_write don't need to do mrdy_assert when fifo is not empty This patch check whether the fifo lenth is empty before writing new data to fifo.If condition is true,ifx_spi_write need to trigger one mrdy_assert. If condition is false,the mrdy_assert will be trigger by the next ifx_spi_io. Cc: Bi Chao Signed-off-by: Chen Jun Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ifx6x60.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 21eb70bcb6a..1754c147a94 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -508,9 +508,16 @@ static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf, { struct ifx_spi_device *ifx_dev = tty->driver_data; unsigned char *tmp_buf = (unsigned char *)buf; - int tx_count = kfifo_in_locked(&ifx_dev->tx_fifo, tmp_buf, count, - &ifx_dev->fifo_lock); - mrdy_assert(ifx_dev); + unsigned long flags; + bool is_fifo_empty; + + spin_lock_irqsave(&ifx_dev->fifo_lock, flags); + is_fifo_empty = kfifo_is_empty(&ifx_dev->tx_fifo); + int tx_count = kfifo_in(&ifx_dev->tx_fifo, tmp_buf, count); + spin_unlock_irqrestore(&ifx_dev->fifo_lock, flags); + if (is_fifo_empty) + mrdy_assert(ifx_dev); + return tx_count; } -- cgit v1.2.3 From 4bd82136cdf04f3a8d50e20c1b76da750f75f2db Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 1 Nov 2012 16:43:49 +0000 Subject: moxa: dcd handling of CLOCAL is backwards We should do hangup on dcd loss if CLOCAL is false not true. Signed-off-by: Alan Cox Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?id=49911 Signed-off-by: Greg Kroah-Hartman --- drivers/tty/moxa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 56e616b9109..9b57aae139f 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -1370,7 +1370,7 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) p->DCDState = dcd; spin_unlock_irqrestore(&p->port.lock, flags); tty = tty_port_tty_get(&p->port); - if (tty && C_CLOCAL(tty) && !dcd) + if (tty && !C_CLOCAL(tty) && !dcd) tty_hangup(tty); tty_kref_put(tty); } -- cgit v1.2.3 From d1519e23c2b3a518fb41daf3eceae43382433ceb Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 1 Nov 2012 16:45:49 +0000 Subject: ipwireless: don't oops if we run out of space Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?id=49851 Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/ipwireless/network.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/tty/ipwireless/network.c b/drivers/tty/ipwireless/network.c index 57102e66165..c0dfb642383 100644 --- a/drivers/tty/ipwireless/network.c +++ b/drivers/tty/ipwireless/network.c @@ -352,6 +352,8 @@ static struct sk_buff *ipw_packet_received_skb(unsigned char *data, } skb = dev_alloc_skb(length + 4); + if (skb == NULL) + return NULL; skb_reserve(skb, 2); memcpy(skb_put(skb, length), data, length); @@ -397,7 +399,8 @@ void ipwireless_network_packet_received(struct ipw_network *network, /* Send the data to the ppp_generic module. */ skb = ipw_packet_received_skb(data, length); - ppp_input(network->ppp_channel, skb); + if (skb) + ppp_input(network->ppp_channel, skb); } else spin_unlock_irqrestore(&network->lock, flags); -- cgit v1.2.3 From 19387b27e42d5e20a8188cfa15dc902114d98c43 Mon Sep 17 00:00:00 2001 From: Yasuaki Ishimatsu Date: Thu, 15 Nov 2012 06:59:31 +0000 Subject: ACPI / memory-hotplug: add memory offline code to acpi_memory_device_remove() The memory device can be removed by 2 ways: 1. send eject request by SCI 2. echo 1 >/sys/bus/pci/devices/PNP0C80:XX/eject In the 1st case, acpi_memory_disable_device() will be called. In the 2nd case, acpi_memory_device_remove() will be called. acpi_memory_device_remove() will also be called when we unbind the memory device from the driver acpi_memhotplug or a driver initialization fails. acpi_memory_disable_device() has already implemented a code which offlines memory and releases acpi_memory_info struct. But acpi_memory_device_remove() has not implemented it yet. So the patch move offlining memory and releasing acpi_memory_info struct codes to a new function acpi_memory_remove_memory(). And it is used by both acpi_memory_device_remove() and acpi_memory_disable_device(). Signed-off-by: Yasuaki Ishimatsu Signed-off-by: Wen Congyang Acked-by: David Rientjes Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_memhotplug.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 1e90e8f0100..736ec047e0f 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -306,25 +306,37 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) return 0; } -static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) +static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device) { int result; struct acpi_memory_info *info, *n; - - /* - * Ask the VM to offline this memory range. - * Note: Assume that this function returns zero on success - */ list_for_each_entry_safe(info, n, &mem_device->res_list, list) { if (info->enabled) { result = remove_memory(info->start_addr, info->length); if (result) return result; } + + list_del(&info->list); kfree(info); } + return 0; +} + +static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) +{ + int result; + + /* + * Ask the VM to offline this memory range. + * Note: Assume that this function returns zero on success + */ + result = acpi_memory_remove_memory(mem_device); + if (result) + return result; + /* Power-off and eject the device */ result = acpi_memory_powerdown_device(mem_device); if (result) { @@ -474,12 +486,17 @@ static int acpi_memory_device_add(struct acpi_device *device) static int acpi_memory_device_remove(struct acpi_device *device, int type) { struct acpi_memory_device *mem_device = NULL; - + int result; if (!device || !acpi_driver_data(device)) return -EINVAL; mem_device = acpi_driver_data(device); + + result = acpi_memory_remove_memory(mem_device); + if (result) + return result; + kfree(mem_device); return 0; -- cgit v1.2.3 From c13b86a336d089f248293776a853252fbca15c26 Mon Sep 17 00:00:00 2001 From: Hindin Joseph Date: Sun, 4 Nov 2012 22:50:08 +0200 Subject: USB: fix authorization and claimed port logic It looks like I've run into some inconsistency in the USB stack behavior. The USB stack maintains, among others, two states for the attach USB device: authorized and owned. Authorization state is accessible to the user space code through correspondent sysfs files, the ownership can be set by claiming the hub's port with ioctl call. Both state may be set before the device is attached, by access the hub settings. When the new device is attached, both authorization and ownership prevent the kernel USB stack from setting the newly attached device configuration, but when the device is authorized, the ownership state is ignored. It looks like ignoring the ownership state on authorization make the stack behavior inconsistent; it also prevents the user space code from completely overriding configuration selection, important for implementing workarounds for bugs in the device configuration selection. The following patch makes the stack behavior more consistent, by moving ownership test into usb_choose_configuration - the later function is used both by generic_probe and usb_authorize_device Signed-off-by: Joseph Hindin Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/generic.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index 69ecd3c9231..eff2010eb63 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c @@ -47,6 +47,9 @@ int usb_choose_configuration(struct usb_device *udev) int insufficient_power = 0; struct usb_host_config *c, *best; + if (usb_device_is_owned(udev)) + return 0; + best = NULL; c = udev->config; num_configs = udev->descriptor.bNumConfigurations; @@ -160,9 +163,7 @@ static int generic_probe(struct usb_device *udev) /* Choose and set the configuration. This registers the interfaces * with the driver core and lets interface drivers bind to them. */ - if (usb_device_is_owned(udev)) - ; /* Don't configure if the device is owned */ - else if (udev->authorized == 0) + if (udev->authorized == 0) dev_err(&udev->dev, "Device is not authorized for usage\n"); else { c = usb_choose_configuration(udev); -- cgit v1.2.3 From 4bb535d2b6fe1466d89037c95945cc7bf5ba2377 Mon Sep 17 00:00:00 2001 From: Josh Cartwright Date: Mon, 5 Nov 2012 15:24:26 -0600 Subject: serial: xilinx_uartps: kill CONFIG_OF conditional The Zynq platform requires the use of CONFIG_OF. Remove the #ifdef conditionals in the uartps driver. Make dependency explicit in Kconfig. Signed-off-by: Josh Cartwright Tested-by: Michal Simek Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/xilinx_uartps.c | 9 --------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index b1768012ed2..6a69c88c502 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1376,6 +1376,7 @@ config SERIAL_MXS_AUART_CONSOLE config SERIAL_XILINX_PS_UART tristate "Xilinx PS UART support" + depends on OF select SERIAL_CORE help This driver supports the Xilinx PS UART port. diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index b627363352e..23efe17be44 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -946,15 +946,11 @@ static int __devinit xuartps_probe(struct platform_device *pdev) struct resource *res, *res2; int clk = 0; -#ifdef CONFIG_OF const unsigned int *prop; prop = of_get_property(pdev->dev.of_node, "clock", NULL); if (prop) clk = be32_to_cpup(prop); -#else - clk = *((unsigned int *)(pdev->dev.platform_data)); -#endif if (!clk) { dev_err(&pdev->dev, "no clock specified\n"); return -ENODEV; @@ -1044,16 +1040,11 @@ static int xuartps_resume(struct platform_device *pdev) } /* Match table for of_platform binding */ - -#ifdef CONFIG_OF static struct of_device_id xuartps_of_match[] __devinitdata = { { .compatible = "xlnx,xuartps", }, {} }; MODULE_DEVICE_TABLE(of, xuartps_of_match); -#else -#define xuartps_of_match NULL -#endif static struct platform_driver xuartps_platform_driver = { .probe = xuartps_probe, /* Probe method */ -- cgit v1.2.3 From 7a876b39b5bc94f67e8a3a7adfd270b8c21fc762 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 6 Nov 2012 14:30:28 +0000 Subject: serial: cast before shifting on port io Without this we will shift data into oblivion and give wrong results on some configurations Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index d3dd4ad984f..63b33889d51 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2366,7 +2366,7 @@ static ssize_t uart_get_attr_port(struct device *dev, struct tty_port *port = dev_get_drvdata(dev); uart_get_info(port, &tmp); - return snprintf(buf, PAGE_SIZE, "0x%lX\n", (unsigned long)(tmp.port | (tmp.port_high << HIGH_BITS_OFFSET))); + return snprintf(buf, PAGE_SIZE, "0x%lX\n", (unsigned long)(tmp.port | (((unsigned long)tmp.port_high) << HIGH_BITS_OFFSET))); } static ssize_t uart_get_attr_irq(struct device *dev, -- cgit v1.2.3 From 9642dbe73c8a3b55a812253fcb9add9eeed4ca81 Mon Sep 17 00:00:00 2001 From: Steven Miao Date: Wed, 7 Nov 2012 13:27:56 +0800 Subject: serial: bfin-uart: avoid dead lock in rx irq handler in smp kernel Disabing dma irq and lock bottom half in smp kernel doesn't ensure exclusive uart access. Call spin_lock_irqsave() instead. Signed-off-by: Steven Miao Signed-off-by: Sonic Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bfin_uart.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index 9242d56ba26..ca64c4a83ce 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c @@ -477,9 +477,9 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart) void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) { int x_pos, pos; + unsigned long flags; - dma_disable_irq_nosync(uart->rx_dma_channel); - spin_lock_bh(&uart->rx_lock); + spin_lock_irqsave(&uart->rx_lock, flags); /* 2D DMA RX buffer ring is used. Because curr_y_count and * curr_x_count can't be read as an atomic operation, @@ -510,8 +510,7 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) uart->rx_dma_buf.tail = uart->rx_dma_buf.head; } - spin_unlock_bh(&uart->rx_lock); - dma_enable_irq(uart->rx_dma_channel); + spin_unlock_irqrestore(&uart->rx_lock, flags); mod_timer(&(uart->rx_dma_timer), jiffies + DMA_RX_FLUSH_JIFFIES); } -- cgit v1.2.3 From 315bbae9c5cb1f54a6d6fd47b9cf325fbedccf05 Mon Sep 17 00:00:00 2001 From: Wen Congyang Date: Fri, 16 Nov 2012 02:04:05 +0100 Subject: ACPI / memhotplug: deal with eject request in hotplug queue The memory device can be removed by 2 ways: 1. send eject request by SCI 2. echo 1 >/sys/bus/pci/devices/PNP0C80:XX/eject We handle the 1st case in the module acpi_memhotplug, and handle the 2nd case in ACPI eject notification. This 2 events may happen at the same time, so we may touch acpi_memory_device.res_list at the same time. This patch reimplements memory-hotremove support through an ACPI eject notification. Now the memory device is offlined and hotremoved only in the function acpi_memory_device_remove() which is protected by device_lock(). Signed-off-by: Wen Congyang Reviewed-by: Yasuaki Ishimatsu Reviewed-by: Toshi Kani Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_memhotplug.c | 88 +++++------------------------------------- 1 file changed, 9 insertions(+), 79 deletions(-) diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 736ec047e0f..6e12042658b 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -272,40 +272,6 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) return 0; } -static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) -{ - acpi_status status; - struct acpi_object_list arg_list; - union acpi_object arg; - unsigned long long current_status; - - - /* Issue the _EJ0 command */ - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = 1; - status = acpi_evaluate_object(mem_device->device->handle, - "_EJ0", &arg_list, NULL); - /* Return on _EJ0 failure */ - if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "_EJ0 failed")); - return -ENODEV; - } - - /* Evalute _STA to check if the device is disabled */ - status = acpi_evaluate_integer(mem_device->device->handle, "_STA", - NULL, ¤t_status); - if (ACPI_FAILURE(status)) - return -ENODEV; - - /* Check for device status. Device should be disabled */ - if (current_status & ACPI_STA_DEVICE_ENABLED) - return -EINVAL; - - return 0; -} - static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device) { int result; @@ -325,34 +291,11 @@ static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device) return 0; } -static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) -{ - int result; - - /* - * Ask the VM to offline this memory range. - * Note: Assume that this function returns zero on success - */ - result = acpi_memory_remove_memory(mem_device); - if (result) - return result; - - /* Power-off and eject the device */ - result = acpi_memory_powerdown_device(mem_device); - if (result) { - /* Set the status of the device to invalid */ - mem_device->state = MEMORY_INVALID_STATE; - return result; - } - - mem_device->state = MEMORY_POWER_OFF_STATE; - return result; -} - static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) { struct acpi_memory_device *mem_device; struct acpi_device *device; + struct acpi_eject_event *ej_event = NULL; u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ switch (event) { @@ -394,32 +337,19 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) break; } - /* - * Currently disabling memory device from kernel mode - * TBD: Can also be disabled from user mode scripts - * TBD: Can also be disabled by Callback registration - * with generic sysfs driver - */ - if (acpi_memory_disable_device(mem_device)) { - printk(KERN_ERR PREFIX "Disable memory device\n"); - /* - * If _EJ0 was called but failed, _OST is not - * necessary. - */ - if (mem_device->state == MEMORY_INVALID_STATE) - return; - + ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); + if (!ej_event) { + pr_err(PREFIX "No memory, dropping EJECT\n"); break; } - /* - * Invoke acpi_bus_trim() to remove memory device - */ - acpi_bus_trim(device, 1); + ej_event->handle = handle; + ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; + acpi_os_hotplug_execute(acpi_bus_hot_remove_device, + (void *)ej_event); - /* _EJ0 succeeded; _OST is not necessary */ + /* eject is performed asynchronously */ return; - default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); -- cgit v1.2.3 From 386e52b95550db87c93455e3c0efe3cc4543f036 Mon Sep 17 00:00:00 2001 From: Wen Congyang Date: Fri, 16 Nov 2012 02:06:06 +0100 Subject: ACPI / memhotplug: fix memory leak when memory device is unbound from acpi_memhotplug We allocate memory to store acpi_memory_info, so we should free it before freeing mem_device. Signed-off-by: Wen Congyang Reviewed-by: Yasuaki Ishimatsu Acked-by: David Rientjes Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_memhotplug.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 6e12042658b..c5e7b6d08ef 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -125,12 +125,20 @@ acpi_memory_get_resource(struct acpi_resource *resource, void *context) return AE_OK; } +static void +acpi_memory_free_device_resources(struct acpi_memory_device *mem_device) +{ + struct acpi_memory_info *info, *n; + + list_for_each_entry_safe(info, n, &mem_device->res_list, list) + kfree(info); + INIT_LIST_HEAD(&mem_device->res_list); +} + static int acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) { acpi_status status; - struct acpi_memory_info *info, *n; - if (!list_empty(&mem_device->res_list)) return 0; @@ -138,9 +146,7 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS, acpi_memory_get_resource, mem_device); if (ACPI_FAILURE(status)) { - list_for_each_entry_safe(info, n, &mem_device->res_list, list) - kfree(info); - INIT_LIST_HEAD(&mem_device->res_list); + acpi_memory_free_device_resources(mem_device); return -EINVAL; } @@ -363,6 +369,15 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) return; } +static void acpi_memory_device_free(struct acpi_memory_device *mem_device) +{ + if (!mem_device) + return; + + acpi_memory_free_device_resources(mem_device); + kfree(mem_device); +} + static int acpi_memory_device_add(struct acpi_device *device) { int result; @@ -427,7 +442,7 @@ static int acpi_memory_device_remove(struct acpi_device *device, int type) if (result) return result; - kfree(mem_device); + acpi_memory_device_free(mem_device); return 0; } -- cgit v1.2.3 From 50827fbde161a4ccb05a649752dd221b083f5ea5 Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Thu, 15 Nov 2012 16:03:16 +0800 Subject: serial: mfd: Add nmi_touch_watchdog() into the console write function This is following what 8250 driver is doing in console write function, to avoid the hardware lockup case. v2: incldudes the Signed-off-by: Feng Tang Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mfd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c index c4b50af46c4..79fe59b6cc4 100644 --- a/drivers/tty/serial/mfd.c +++ b/drivers/tty/serial/mfd.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -1113,6 +1114,8 @@ serial_hsu_console_write(struct console *co, const char *s, unsigned int count) unsigned int ier; int locked = 1; + touch_nmi_watchdog(); + local_irq_save(flags); if (up->port.sysrq) locked = 0; -- cgit v1.2.3 From e0b7b24dd9559fcda0f8bfd6acbcad81682c4fdd Mon Sep 17 00:00:00 2001 From: Wen Congyang Date: Fri, 16 Nov 2012 02:08:16 +0100 Subject: ACPI / memhotplug: free memory device if acpi_memory_enable_device() failed If acpi_memory_enable_device() fails, acpi_memory_enable_device() will return a non-zero value, which means we fail to bind the memory device to this driver. So we should free memory device before acpi_memory_device_add() returns. Signed-off-by: Wen Congyang Reviewed-by: Yasuaki Ishimatsu Acked-by: David Rientjes Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_memhotplug.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index c5e7b6d08ef..e52ad5d3792 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -421,9 +421,11 @@ static int acpi_memory_device_add(struct acpi_device *device) if (!acpi_memory_check_device(mem_device)) { /* call add_memory func */ result = acpi_memory_enable_device(mem_device); - if (result) + if (result) { printk(KERN_ERR PREFIX "Error in acpi_memory_enable_device\n"); + acpi_memory_device_free(mem_device); + } } return result; } -- cgit v1.2.3 From 65479472571fbf91502b7854be45ec0026b5229e Mon Sep 17 00:00:00 2001 From: Wen Congyang Date: Fri, 16 Nov 2012 02:10:37 +0100 Subject: ACPI / memhotplug: don't allow to eject the memory device if it is being used We eject the memory device even if it is in use. It is very dangerous, and it will cause the kernel to be panicked. Signed-off-by: Wen Congyang Reviewed-by: Yasuaki Ishimatsu Acked-by: David Rientjes Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_memhotplug.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index e52ad5d3792..f7e30076996 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -78,6 +78,7 @@ struct acpi_memory_info { unsigned short caching; /* memory cache attribute */ unsigned short write_protect; /* memory read/write attribute */ unsigned int enabled:1; + unsigned int failed:1; }; struct acpi_memory_device { @@ -257,9 +258,23 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) node = memory_add_physaddr_to_nid(info->start_addr); result = add_memory(node, info->start_addr, info->length); - if (result) + + /* + * If the memory block has been used by the kernel, add_memory() + * returns -EEXIST. If add_memory() returns the other error, it + * means that this memory block is not used by the kernel. + */ + if (result && result != -EEXIST) { + info->failed = 1; continue; - info->enabled = 1; + } + + if (!result) + info->enabled = 1; + /* + * Add num_enable even if add_memory() returns -EEXIST, so the + * device is bound to this driver. + */ num_enabled++; } if (!num_enabled) { @@ -280,21 +295,30 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device) { - int result; + int result = 0; struct acpi_memory_info *info, *n; list_for_each_entry_safe(info, n, &mem_device->res_list, list) { - if (info->enabled) { - result = remove_memory(info->start_addr, info->length); - if (result) - return result; - } + if (info->failed) + /* The kernel does not use this memory block */ + continue; + + if (!info->enabled) + /* + * The kernel uses this memory block, but it may be not + * managed by us. + */ + return -EBUSY; + + result = remove_memory(info->start_addr, info->length); + if (result) + return result; list_del(&info->list); kfree(info); } - return 0; + return result; } static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) -- cgit v1.2.3 From 18e0749aa825b8af12990521536f617d1405c37f Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 11 Nov 2012 10:24:19 +0400 Subject: serial: Unneeded ARCH dependencies are removed This patch performs a small cleanup tty/Serial/Kconfig file by removing unneeded ARCH dependencies. This dependencies already included in board/type symbols. Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 6a69c88c502..59c23d03810 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -93,7 +93,7 @@ config SERIAL_SB1250_DUART_CONSOLE config SERIAL_ATMEL bool "AT91 / AT32 on-chip serial port support" - depends on (ARM && ARCH_AT91) || AVR32 + depends on ARCH_AT91 || AVR32 select SERIAL_CORE help This enables the driver for the on-chip UARTs of the Atmel @@ -198,7 +198,7 @@ config SERIAL_CLPS711X_CONSOLE config SERIAL_SAMSUNG tristate "Samsung SoC serial support" - depends on ARM && PLAT_SAMSUNG + depends on PLAT_SAMSUNG select SERIAL_CORE help Support for the on-chip UARTs on the Samsung S3C24XX series CPUs, @@ -208,14 +208,14 @@ config SERIAL_SAMSUNG config SERIAL_SAMSUNG_UARTS_4 bool - depends on ARM && PLAT_SAMSUNG + depends on PLAT_SAMSUNG default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442) help Internal node for the common case of 4 Samsung compatible UARTs config SERIAL_SAMSUNG_UARTS int - depends on ARM && PLAT_SAMSUNG + depends on PLAT_SAMSUNG default 6 if ARCH_S5P6450 default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416 default 3 @@ -249,7 +249,7 @@ config SERIAL_SAMSUNG_CONSOLE config SERIAL_SIRFSOC tristate "SiRF SoC Platform Serial port support" - depends on ARM && ARCH_PRIMA2 + depends on ARCH_PRIMA2 select SERIAL_CORE help Support for the on-chip UART on the CSR SiRFprimaII series, @@ -347,7 +347,7 @@ config SERIAL_ZS_CONSOLE config SERIAL_21285 tristate "DC21285 serial port support" - depends on ARM && FOOTBRIDGE + depends on FOOTBRIDGE select SERIAL_CORE help If you have a machine based on a 21285 (Footbridge) StrongARM(R)/ @@ -371,7 +371,7 @@ config SERIAL_21285_CONSOLE config SERIAL_MPSC bool "Marvell MPSC serial port support" - depends on PPC32 && MV64X60 + depends on MV64X60 select SERIAL_CORE help Say Y here if you want to use the Marvell MPSC serial controller. @@ -408,7 +408,7 @@ config SERIAL_PXA_CONSOLE config SERIAL_SA1100 bool "SA1100 serial port support" - depends on ARM && ARCH_SA1100 + depends on ARCH_SA1100 select SERIAL_CORE help If you have a machine based on a SA1100/SA1110 StrongARM(R) CPU you @@ -716,7 +716,7 @@ config SERIAL_SH_SCI_DMA config SERIAL_PNX8XXX bool "Enable PNX8XXX SoCs' UART Support" - depends on MIPS && (SOC_PNX8550 || SOC_PNX833X) + depends on SOC_PNX8550 || SOC_PNX833X select SERIAL_CORE help If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330 @@ -1013,7 +1013,7 @@ config SERIAL_SGI_IOC3 config SERIAL_MSM bool "MSM on-chip serial port support" - depends on ARM && ARCH_MSM + depends on ARCH_MSM select SERIAL_CORE config SERIAL_MSM_CONSOLE @@ -1035,7 +1035,7 @@ config SERIAL_MSM_HS config SERIAL_VT8500 bool "VIA VT8500 on-chip serial port support" - depends on ARM && ARCH_VT8500 + depends on ARCH_VT8500 select SERIAL_CORE config SERIAL_VT8500_CONSOLE @@ -1045,7 +1045,7 @@ config SERIAL_VT8500_CONSOLE config SERIAL_NETX tristate "NetX serial port support" - depends on ARM && ARCH_NETX + depends on ARCH_NETX select SERIAL_CORE help If you have a machine based on a Hilscher NetX SoC you -- cgit v1.2.3 From 61d8eff14417fb6d6c5d57e4f0f7925e9e99fce3 Mon Sep 17 00:00:00 2001 From: Wen Congyang Date: Fri, 16 Nov 2012 02:12:38 +0100 Subject: ACPI / memhotplug: bind the memory device when the driver is being loaded We had introduced acpi_hotmem_initialized to avoid strange add_memory fail message. But the memory device may not be used by the kernel, and the device should be bound when the driver is being loaded. Remove acpi_hotmem_initialized to allow that the device can be bound when the driver is being loaded. Signed-off-by: Wen Congyang Reviewed-by: Yasuaki Ishimatsu Acked-by: David Rientjes Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_memhotplug.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index f7e30076996..e0f7425c885 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -87,8 +87,6 @@ struct acpi_memory_device { struct list_head res_list; }; -static int acpi_hotmem_initialized; - static acpi_status acpi_memory_get_resource(struct acpi_resource *resource, void *context) { @@ -433,15 +431,6 @@ static int acpi_memory_device_add(struct acpi_device *device) printk(KERN_DEBUG "%s \n", acpi_device_name(device)); - /* - * Early boot code has recognized memory area by EFI/E820. - * If DSDT shows these memory devices on boot, hotplug is not necessary - * for them. So, it just returns until completion of this driver's - * start up. - */ - if (!acpi_hotmem_initialized) - return 0; - if (!acpi_memory_check_device(mem_device)) { /* call add_memory func */ result = acpi_memory_enable_device(mem_device); @@ -557,7 +546,6 @@ static int __init acpi_memory_device_init(void) return -ENODEV; } - acpi_hotmem_initialized = 1; return 0; } -- cgit v1.2.3 From 5318609519800617323b5fdb17c1d4fe12c3d794 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 14 Nov 2012 01:15:19 -0800 Subject: mm, oom: ensure sysrq+f always passes valid zonelist With hotpluggable and memoryless nodes, it's possible that node 0 will not be online, so use the first online node's zonelist rather than hardcoding node 0 to pass a zonelist with all zones to the oom killer. Signed-off-by: David Rientjes Reviewed-by: Michal Hocko Signed-off-by: Greg Kroah-Hartman --- drivers/tty/sysrq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 16ee6cee07d..b3c4a250ff8 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -346,7 +346,8 @@ static struct sysrq_key_op sysrq_term_op = { static void moom_callback(struct work_struct *ignored) { - out_of_memory(node_zonelist(0, GFP_KERNEL), GFP_KERNEL, 0, NULL, true); + out_of_memory(node_zonelist(first_online_node, GFP_KERNEL), GFP_KERNEL, + 0, NULL, true); } static DECLARE_WORK(moom_work, moom_callback); -- cgit v1.2.3 From 2dff8ad92661b6c99e9ba8b5918e43b522551556 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 14 Nov 2012 10:38:13 +0100 Subject: tty/serial/ar933x_uart: fix baud rate calculation The UART of the AR933x SoC implements a fractional divisor for generating the desired baud rate. The current code uses a fixed value for the fractional part of the divisor, and this leads to improperly calculated baud rates: baud scale step real baud diff 300 5207* 8192 17756 17456 5818.66% 600 2603* 8192 35511 34911 5818.50% 1200 1301* 8192 71023 69823 5818.58% 2400 650* 8192 11241 8841 368.37% 4800 324* 8192 22645 17845 371.77% 9600 161 8192 9645 45 0.46% 14400 107 8192 14468 68 0.47% 19200 80 8192 19290 90 0.46% 28800 53 8192 28935 135 0.46% 38400 39 8192 39063 663 1.72% 57600 26 8192 57870 270 0.46% 115200 12 8192 120192 4992 4.33% 230400 5 8192 260417 30017 13.02% 460800 2 8192 520833 60033 13.02% 921600 0 8192 1562500 640900 69.93% After the patch, the integer and fractional parts of the divisor will be calculated dynamically. This ensures that the UART will use correct baud rates: baud scale step real baud diff 300 6 11 300 0 0.00% 600 54 173 600 0 0.00% 1200 30 195 1200 0 0.00% 2400 30 390 2400 0 0.00% 4800 48 1233 4800 0 0.00% 9600 78 3976 9600 0 0.00% 14400 98 7474 14400 0 0.00% 19200 55 5637 19200 0 0.00% 28800 130 19780 28800 0 0.00% 38400 36 7449 38400 0 0.00% 57600 78 23857 57600 0 0.00% 115200 43 26575 115200 0 0.00% 230400 23 28991 230400 0 0.00% 460800 11 28991 460800 0 0.00% 921600 5 28991 921599 -1 0.00% Signed-off-by: Gabor Juhos Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ar933x_uart.c | 90 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c index e4f60e2b87f..0f5b28afc2a 100644 --- a/drivers/tty/serial/ar933x_uart.c +++ b/drivers/tty/serial/ar933x_uart.c @@ -25,11 +25,19 @@ #include #include +#include + #include #include #define DRIVER_NAME "ar933x-uart" +#define AR933X_UART_MAX_SCALE 0xff +#define AR933X_UART_MAX_STEP 0xffff + +#define AR933X_UART_MIN_BAUD 300 +#define AR933X_UART_MAX_BAUD 3000000 + #define AR933X_DUMMY_STATUS_RD 0x01 static struct uart_driver ar933x_uart_driver; @@ -37,6 +45,8 @@ static struct uart_driver ar933x_uart_driver; struct ar933x_uart_port { struct uart_port port; unsigned int ier; /* shadow Interrupt Enable Register */ + unsigned int min_baud; + unsigned int max_baud; }; static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, @@ -162,6 +172,57 @@ static void ar933x_uart_enable_ms(struct uart_port *port) { } +/* + * baudrate = (clk / (scale + 1)) * (step * (1 / 2^17)) + */ +static unsigned long ar933x_uart_get_baud(unsigned int clk, + unsigned int scale, + unsigned int step) +{ + u64 t; + u32 div; + + div = (2 << 16) * (scale + 1); + t = clk; + t *= step; + t += (div / 2); + do_div(t, div); + + return t; +} + +static void ar933x_uart_get_scale_step(unsigned int clk, + unsigned int baud, + unsigned int *scale, + unsigned int *step) +{ + unsigned int tscale; + long min_diff; + + *scale = 0; + *step = 0; + + min_diff = baud; + for (tscale = 0; tscale < AR933X_UART_MAX_SCALE; tscale++) { + u64 tstep; + int diff; + + tstep = baud * (tscale + 1); + tstep *= (2 << 16); + do_div(tstep, clk); + + if (tstep > AR933X_UART_MAX_STEP) + break; + + diff = abs(ar933x_uart_get_baud(clk, tscale, tstep) - baud); + if (diff < min_diff) { + min_diff = diff; + *scale = tscale; + *step = tstep; + } + } +} + static void ar933x_uart_set_termios(struct uart_port *port, struct ktermios *new, struct ktermios *old) @@ -169,7 +230,7 @@ static void ar933x_uart_set_termios(struct uart_port *port, struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; unsigned int cs; unsigned long flags; - unsigned int baud, scale; + unsigned int baud, scale, step; /* Only CS8 is supported */ new->c_cflag &= ~CSIZE; @@ -191,8 +252,8 @@ static void ar933x_uart_set_termios(struct uart_port *port, /* Mark/space parity is not supported */ new->c_cflag &= ~CMSPAR; - baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); - scale = (port->uartclk / (16 * baud)) - 1; + baud = uart_get_baud_rate(port, new, old, up->min_baud, up->max_baud); + ar933x_uart_get_scale_step(port->uartclk, baud, &scale, &step); /* * Ok, we're now changing the port state. Do it with @@ -200,6 +261,10 @@ static void ar933x_uart_set_termios(struct uart_port *port, */ spin_lock_irqsave(&up->port.lock, flags); + /* disable the UART */ + ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, + AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S); + /* Update the per-port timeout. */ uart_update_timeout(port, new->c_cflag, baud); @@ -210,7 +275,7 @@ static void ar933x_uart_set_termios(struct uart_port *port, up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD; ar933x_uart_write(up, AR933X_UART_CLOCK_REG, - scale << AR933X_UART_CLOCK_SCALE_S | 8192); + scale << AR933X_UART_CLOCK_SCALE_S | step); /* setup configuration register */ ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs); @@ -219,6 +284,11 @@ static void ar933x_uart_set_termios(struct uart_port *port, ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, AR933X_UART_CS_HOST_INT_EN); + /* reenable the UART */ + ar933x_uart_rmw(up, AR933X_UART_CS_REG, + AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S, + AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S); + spin_unlock_irqrestore(&up->port.lock, flags); if (tty_termios_baud_rate(new)) @@ -401,6 +471,8 @@ static void ar933x_uart_config_port(struct uart_port *port, int flags) static int ar933x_uart_verify_port(struct uart_port *port, struct serial_struct *ser) { + struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; + if (ser->type != PORT_UNKNOWN && ser->type != PORT_AR933X) return -EINVAL; @@ -408,7 +480,8 @@ static int ar933x_uart_verify_port(struct uart_port *port, if (ser->irq < 0 || ser->irq >= NR_IRQS) return -EINVAL; - if (ser->baud_base < 28800) + if (ser->baud_base < up->min_baud || + ser->baud_base > up->max_baud) return -EINVAL; return 0; @@ -561,6 +634,7 @@ static int __devinit ar933x_uart_probe(struct platform_device *pdev) struct uart_port *port; struct resource *mem_res; struct resource *irq_res; + unsigned int baud; int id; int ret; @@ -611,6 +685,12 @@ static int __devinit ar933x_uart_probe(struct platform_device *pdev) port->fifosize = AR933X_UART_FIFO_SIZE; port->ops = &ar933x_uart_ops; + baud = ar933x_uart_get_baud(port->uartclk, AR933X_UART_MAX_SCALE, 1); + up->min_baud = max_t(unsigned int, baud, AR933X_UART_MIN_BAUD); + + baud = ar933x_uart_get_baud(port->uartclk, 0, AR933X_UART_MAX_STEP); + up->max_baud = min_t(unsigned int, baud, AR933X_UART_MAX_BAUD); + ar933x_uart_add_console_port(up); ret = uart_add_one_port(&ar933x_uart_driver, &up->port); -- cgit v1.2.3 From 7342c59a44ad9e5f30baaa2de84830f40b9f06c0 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 15 Nov 2012 09:49:48 +0100 Subject: TTY: isicom, stop using port->tty Do not access unsafe port->tty pointer when we have a safe tty already. Use the safe one. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/isicom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index d7492e18360..5f3ecbc2713 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c @@ -603,7 +603,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) if (tty_port_cts_enabled(&port->port)) { if (tty->hw_stopped) { if (header & ISI_CTS) { - port->port.tty->hw_stopped = 0; + tty->hw_stopped = 0; /* start tx ing */ port->status |= (ISI_TXOK | ISI_CTS); -- cgit v1.2.3 From 81c79838ca24f48e0e4bb96502d131d6af758ae0 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 15 Nov 2012 09:49:49 +0100 Subject: TTY: pty, fix tty buffers leak After commit "TTY: move tty buffers to tty_port", the tty buffers are not freed in some drivers. This is because tty_port_destructor is not called whenever a tty_port is freed. This was an assumption I counted with but was unfortunately untrue. So fix the drivers to fulfil this assumption. PTY is one of those, here we just need to use tty_port_put instead of kfree. (Assuming tty_port_destructor does not need port->ops to be set which we change here too.) Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 2 +- drivers/tty/tty_port.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 0ce0b3ec2bb..a541ec87593 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -408,7 +408,7 @@ static void pty_unix98_shutdown(struct tty_struct *tty) static void pty_cleanup(struct tty_struct *tty) { tty->port->itty = NULL; - kfree(tty->port); + tty_port_put(tty->port); } /* Traditional BSD devices */ diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 416b42f7c34..fdc42c2d565 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -128,7 +128,7 @@ static void tty_port_destructor(struct kref *kref) if (port->xmit_buf) free_page((unsigned long)port->xmit_buf); tty_buffer_free_all(port); - if (port->ops->destruct) + if (port->ops && port->ops->destruct) port->ops->destruct(port); else kfree(port); -- cgit v1.2.3 From 55bef83cc68bda76a14a23b1076a9a9a9e43af68 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 15 Nov 2012 09:49:50 +0100 Subject: ISDN: capi, use kref from tty_port After commit "TTY: move tty buffers to tty_port", the tty buffers are not freed in some drivers. This is because tty_port_destructor is not called whenever a tty_port is freed. This was an assumption I counted with but was unfortunately untrue. So fix the drivers to fulfil this assumption. Here it is enough to switch to refcounting in tty_port. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/capi/capi.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index c679867c2cc..89562a845f6 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -77,8 +77,6 @@ struct ackqueue_entry { }; struct capiminor { - struct kref kref; - unsigned int minor; struct capi20_appl *ap; @@ -190,7 +188,20 @@ static void capiminor_del_all_ack(struct capiminor *mp) /* -------- struct capiminor ---------------------------------------- */ -static const struct tty_port_operations capiminor_port_ops; /* we have none */ +static void capiminor_destroy(struct tty_port *port) +{ + struct capiminor *mp = container_of(port, struct capiminor, port); + + kfree_skb(mp->outskb); + skb_queue_purge(&mp->inqueue); + skb_queue_purge(&mp->outqueue); + capiminor_del_all_ack(mp); + kfree(mp); +} + +static const struct tty_port_operations capiminor_port_ops = { + .destruct = capiminor_destroy, +}; static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) { @@ -204,8 +215,6 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) return NULL; } - kref_init(&mp->kref); - mp->ap = ap; mp->ncci = ncci; INIT_LIST_HEAD(&mp->ackqueue); @@ -247,21 +256,10 @@ err_out2: spin_unlock(&capiminors_lock); err_out1: - kfree(mp); + tty_port_put(&mp->port); return NULL; } -static void capiminor_destroy(struct kref *kref) -{ - struct capiminor *mp = container_of(kref, struct capiminor, kref); - - kfree_skb(mp->outskb); - skb_queue_purge(&mp->inqueue); - skb_queue_purge(&mp->outqueue); - capiminor_del_all_ack(mp); - kfree(mp); -} - static struct capiminor *capiminor_get(unsigned int minor) { struct capiminor *mp; @@ -269,7 +267,7 @@ static struct capiminor *capiminor_get(unsigned int minor) spin_lock(&capiminors_lock); mp = capiminors[minor]; if (mp) - kref_get(&mp->kref); + tty_port_get(&mp->port); spin_unlock(&capiminors_lock); return mp; @@ -277,7 +275,7 @@ static struct capiminor *capiminor_get(unsigned int minor) static inline void capiminor_put(struct capiminor *mp) { - kref_put(&mp->kref, capiminor_destroy); + tty_port_put(&mp->port); } static void capiminor_free(struct capiminor *mp) -- cgit v1.2.3 From 9753eb8de8a36de41f3b5e217e995cccfbecdada Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 15 Nov 2012 09:49:51 +0100 Subject: MMC: sdio_uart, remove unused member from sdio_uart_port tty from struct sdio_uart_port is unused. Proper refcounted tty in tty_port->tty is used instead. So remove the member from that structure. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/card/sdio_uart.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index d2339ea3781..369f7ba1d21 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c @@ -67,7 +67,6 @@ struct uart_icount { struct sdio_uart_port { struct tty_port port; struct kref kref; - struct tty_struct *tty; unsigned int index; struct sdio_func *func; struct mutex func_lock; -- cgit v1.2.3 From e70c67713cdabf55e05db7f1c4fc38085da333a5 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 15 Nov 2012 09:49:52 +0100 Subject: MMC: sdio, use kref from tty_port After commit "TTY: move tty buffers to tty_port", the tty buffers are not freed in some drivers. This is because tty_port_destructor is not called whenever a tty_port is freed. This was an assumption I counted with but was unfortunately untrue. So fix the drivers to fulfil this assumption. Here it is enough to switch to refcounting in tty_port. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/card/sdio_uart.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index 369f7ba1d21..bd57a11acc7 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c @@ -66,7 +66,6 @@ struct uart_icount { struct sdio_uart_port { struct tty_port port; - struct kref kref; unsigned int index; struct sdio_func *func; struct mutex func_lock; @@ -92,7 +91,6 @@ static int sdio_uart_add_port(struct sdio_uart_port *port) { int index, ret = -EBUSY; - kref_init(&port->kref); mutex_init(&port->func_lock); spin_lock_init(&port->write_lock); if (kfifo_alloc(&port->xmit_fifo, FIFO_SIZE, GFP_KERNEL)) @@ -122,23 +120,15 @@ static struct sdio_uart_port *sdio_uart_port_get(unsigned index) spin_lock(&sdio_uart_table_lock); port = sdio_uart_table[index]; if (port) - kref_get(&port->kref); + tty_port_get(&port->port); spin_unlock(&sdio_uart_table_lock); return port; } -static void sdio_uart_port_destroy(struct kref *kref) -{ - struct sdio_uart_port *port = - container_of(kref, struct sdio_uart_port, kref); - kfifo_free(&port->xmit_fifo); - kfree(port); -} - static void sdio_uart_port_put(struct sdio_uart_port *port) { - kref_put(&port->kref, sdio_uart_port_destroy); + tty_port_put(&port->port); } static void sdio_uart_port_remove(struct sdio_uart_port *port) @@ -736,6 +726,14 @@ static void sdio_uart_shutdown(struct tty_port *tport) sdio_uart_release_func(port); } +static void sdio_uart_port_destroy(struct tty_port *tport) +{ + struct sdio_uart_port *port = + container_of(tport, struct sdio_uart_port, port); + kfifo_free(&port->xmit_fifo); + kfree(port); +} + /** * sdio_uart_install - install method * @driver: the driver in use (sdio_uart in our case) @@ -1044,6 +1042,7 @@ static const struct tty_port_operations sdio_uart_port_ops = { .carrier_raised = uart_carrier_raised, .shutdown = sdio_uart_shutdown, .activate = sdio_uart_activate, + .destruct = sdio_uart_port_destroy, }; static const struct tty_operations sdio_uart_ops = { -- cgit v1.2.3 From 9a8e62bc68832dc55a5e6868f812b65567fe66b5 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 15 Nov 2012 09:49:53 +0100 Subject: TTY: n_gsm, use kref from tty_port After commit "TTY: move tty buffers to tty_port", the tty buffers are not freed in some drivers. This is because tty_port_destructor is not called whenever a tty_port is freed. This was an assumption I counted with but was unfortunately untrue. So fix the drivers to fulfil this assumption. Here it is enough to switch to refcounting in tty_port. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 1e8e8ce5595..dcc0430a49c 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -134,7 +134,6 @@ struct gsm_dlci { #define DLCI_OPENING 1 /* Sending SABM not seen UA */ #define DLCI_OPEN 2 /* SABM/UA complete */ #define DLCI_CLOSING 3 /* Sending DISC not seen UA/DM */ - struct kref ref; /* freed from port or mux close */ struct mutex mutex; /* Link layer */ @@ -1635,7 +1634,6 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr) if (dlci == NULL) return NULL; spin_lock_init(&dlci->lock); - kref_init(&dlci->ref); mutex_init(&dlci->mutex); dlci->fifo = &dlci->_fifo; if (kfifo_alloc(&dlci->_fifo, 4096, GFP_KERNEL) < 0) { @@ -1669,9 +1667,9 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr) * * Can sleep. */ -static void gsm_dlci_free(struct kref *ref) +static void gsm_dlci_free(struct tty_port *port) { - struct gsm_dlci *dlci = container_of(ref, struct gsm_dlci, ref); + struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port); del_timer_sync(&dlci->t1); dlci->gsm->dlci[dlci->addr] = NULL; @@ -1683,12 +1681,12 @@ static void gsm_dlci_free(struct kref *ref) static inline void dlci_get(struct gsm_dlci *dlci) { - kref_get(&dlci->ref); + tty_port_get(&dlci->port); } static inline void dlci_put(struct gsm_dlci *dlci) { - kref_put(&dlci->ref, gsm_dlci_free); + tty_port_put(&dlci->port); } /** @@ -2874,6 +2872,7 @@ static void gsm_dtr_rts(struct tty_port *port, int onoff) static const struct tty_port_operations gsm_port_ops = { .carrier_raised = gsm_carrier_raised, .dtr_rts = gsm_dtr_rts, + .destruct = gsm_dlci_free, }; static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty) -- cgit v1.2.3 From de274bfe0fc81def6ddb8a17020a9a4b56477cc4 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 15 Nov 2012 09:49:54 +0100 Subject: TTY: introduce tty_port_destroy After commit "TTY: move tty buffers to tty_port", the tty buffers are not freed in some drivers. This is because tty_port_destructor is not called whenever a tty_port is freed. This was an assumption I counted with but was unfortunately untrue. Those using refcounting are safe now, but for those which do not we introduce a function to be called right before the tty_port is freed by the drivers. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_port.c | 16 +++++++++++++++- include/linux/tty.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index fdc42c2d565..b7ff59d3db8 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -122,12 +122,26 @@ void tty_port_free_xmit_buf(struct tty_port *port) } EXPORT_SYMBOL(tty_port_free_xmit_buf); +/** + * tty_port_destroy -- destroy inited port + * @port: tty port to be doestroyed + * + * When a port was initialized using tty_port_init, one has to destroy the + * port by this function. Either indirectly by using tty_port refcounting + * (tty_port_put) or directly if refcounting is not used. + */ +void tty_port_destroy(struct tty_port *port) +{ + tty_buffer_free_all(port); +} +EXPORT_SYMBOL(tty_port_destroy); + static void tty_port_destructor(struct kref *kref) { struct tty_port *port = container_of(kref, struct tty_port, kref); if (port->xmit_buf) free_page((unsigned long)port->xmit_buf); - tty_buffer_free_all(port); + tty_port_destroy(port); if (port->ops && port->ops->destruct) port->ops->destruct(port); else diff --git a/include/linux/tty.h b/include/linux/tty.h index d7ff88fb896..8db1b569c37 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -455,6 +455,7 @@ extern struct device *tty_port_register_device_attr(struct tty_port *port, const struct attribute_group **attr_grp); extern int tty_port_alloc_xmit_buf(struct tty_port *port); extern void tty_port_free_xmit_buf(struct tty_port *port); +extern void tty_port_destroy(struct tty_port *port); extern void tty_port_put(struct tty_port *port); static inline struct tty_port *tty_port_get(struct tty_port *port) -- cgit v1.2.3 From d0f59141ca40159c9d142c0f62e9aea61f846539 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 15 Nov 2012 09:49:55 +0100 Subject: TTY: isicom, fix tty buffers memory leak After commit "TTY: move tty buffers to tty_port", the tty buffers are not freed in some drivers. This is because tty_port_destructor is not called whenever a tty_port is freed. This was an assumption I counted with but was unfortunately untrue. So fix the drivers to fulfil this assumption. This one is special as we need more work to be done. Previously, the tty_port was initialized at module load time, but to be able to destroy the port and init it again, we now do the initialization in probe and destroy in remove. I.e. at more appropriate places for that. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/isicom.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index 5f3ecbc2713..67f288d7e76 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c @@ -1610,10 +1610,15 @@ static int __devinit isicom_probe(struct pci_dev *pdev, if (retval < 0) goto errunri; - for (index = 0; index < board->port_count; index++) - tty_port_register_device(&board->ports[index].port, - isicom_normal, board->index * 16 + index, - &pdev->dev); + for (index = 0; index < board->port_count; index++) { + struct tty_port *tport = &board->ports[index].port; + tty_port_init(tport); + tport->ops = &isicom_port_ops; + tport->close_delay = 50 * HZ/100; + tport->closing_wait = 3000 * HZ/100; + tty_port_register_device(tport, isicom_normal, + board->index * 16 + index, &pdev->dev); + } return 0; @@ -1635,8 +1640,10 @@ static void __devexit isicom_remove(struct pci_dev *pdev) struct isi_board *board = pci_get_drvdata(pdev); unsigned int i; - for (i = 0; i < board->port_count; i++) + for (i = 0; i < board->port_count; i++) { tty_unregister_device(isicom_normal, board->index * 16 + i); + tty_port_destroy(&board->ports[i].port); + } free_irq(board->irq, board); pci_release_region(pdev, 3); @@ -1655,13 +1662,9 @@ static int __init isicom_init(void) isi_card[idx].ports = port; spin_lock_init(&isi_card[idx].card_lock); for (channel = 0; channel < 16; channel++, port++) { - tty_port_init(&port->port); - port->port.ops = &isicom_port_ops; port->magic = ISICOM_MAGIC; port->card = &isi_card[idx]; port->channel = channel; - port->port.close_delay = 50 * HZ/100; - port->port.closing_wait = 3000 * HZ/100; port->status = 0; /* . . . */ } -- cgit v1.2.3 From 191c5f10275cfbb36802edadbdb10c73537327b4 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 15 Nov 2012 09:49:56 +0100 Subject: TTY: call tty_port_destroy in the rest of drivers After commit "TTY: move tty buffers to tty_port", the tty buffers are not freed in some drivers. This is because tty_port_destructor is not called whenever a tty_port is freed. This was an assumption I counted with but was unfortunately untrue. So fix the drivers to fulfil this assumption. To be sure, the TTY buffers (and later some stuff) are gone along with the tty_port, we have to call tty_port_destroy at tear-down places. This is mostly where the structure containing a tty_port is freed. This patch does exactly that -- put tty_port_destroy at those places. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- arch/alpha/kernel/srmcons.c | 5 ++++- arch/ia64/hp/sim/simserial.c | 1 + arch/m68k/emu/nfcon.c | 6 ++++-- arch/parisc/kernel/pdc_cons.c | 5 +++-- arch/um/drivers/line.c | 2 ++ arch/xtensa/platforms/iss/console.c | 1 + drivers/char/pcmcia/synclink_cs.c | 5 ++++- drivers/char/ttyprintk.c | 4 +++- drivers/isdn/gigaset/common.c | 10 ++++++---- drivers/isdn/i4l/isdn_tty.c | 4 ++++ drivers/misc/pti.c | 7 +++++-- drivers/net/usb/hso.c | 5 +++-- drivers/s390/char/con3215.c | 1 + drivers/s390/char/sclp_tty.c | 4 +++- drivers/s390/char/sclp_vt220.c | 2 ++ drivers/s390/char/tty3270.c | 2 ++ drivers/staging/ccg/u_serial.c | 5 ++++- drivers/staging/dgrp/dgrp_specproc.c | 2 ++ drivers/staging/dgrp/dgrp_tty.c | 4 +++- drivers/staging/ipack/devices/ipoctal.c | 2 ++ drivers/tty/amiserial.c | 2 ++ drivers/tty/bfin_jtag_comm.c | 6 ++++-- drivers/tty/cyclades.c | 8 +++++--- drivers/tty/ehv_bytechan.c | 2 ++ drivers/tty/hvc/hvsi.c | 1 + drivers/tty/ipwireless/tty.c | 1 + drivers/tty/moxa.c | 4 ++++ drivers/tty/mxser.c | 25 +++++++++++++++++-------- drivers/tty/nozomi.c | 13 +++++++++---- drivers/tty/rocket.c | 2 ++ drivers/tty/serial/68328serial.c | 2 ++ drivers/tty/serial/ifx6x60.c | 5 ++++- drivers/tty/serial/kgdb_nmi.c | 2 ++ drivers/tty/serial/serial_core.c | 6 ++++++ drivers/tty/synclink.c | 1 + drivers/tty/synclink_gt.c | 5 ++++- drivers/tty/synclinkmp.c | 5 ++++- drivers/tty/vt/vt.c | 5 ++++- drivers/usb/gadget/u_serial.c | 5 ++++- drivers/usb/serial/usb-serial.c | 1 + net/irda/ircomm/ircomm_tty.c | 1 + 41 files changed, 139 insertions(+), 40 deletions(-) diff --git a/arch/alpha/kernel/srmcons.c b/arch/alpha/kernel/srmcons.c index 5d5865204a1..59b7bbad839 100644 --- a/arch/alpha/kernel/srmcons.c +++ b/arch/alpha/kernel/srmcons.c @@ -205,7 +205,6 @@ static const struct tty_operations srmcons_ops = { static int __init srmcons_init(void) { - tty_port_init(&srmcons_singleton.port); setup_timer(&srmcons_singleton.timer, srmcons_receive_chars, (unsigned long)&srmcons_singleton); if (srm_is_registered_console) { @@ -215,6 +214,9 @@ srmcons_init(void) driver = alloc_tty_driver(MAX_SRM_CONSOLE_DEVICES); if (!driver) return -ENOMEM; + + tty_port_init(&srmcons_singleton.port); + driver->driver_name = "srm"; driver->name = "srm"; driver->major = 0; /* dynamic */ @@ -227,6 +229,7 @@ srmcons_init(void) err = tty_register_driver(driver); if (err) { put_tty_driver(driver); + tty_port_destroy(&srmcons_singleton.port); return err; } srmcons_driver = driver; diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index ec536e4e36c..fc3924d18c1 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -555,6 +555,7 @@ static int __init simrs_init(void) return 0; err_free_tty: put_tty_driver(hp_simserial_driver); + tty_port_destroy(&state->port); return retval; } diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c index 16d170f53bf..6685bf45c2c 100644 --- a/arch/m68k/emu/nfcon.c +++ b/arch/m68k/emu/nfcon.c @@ -120,8 +120,6 @@ static int __init nfcon_init(void) { int res; - tty_port_init(&nfcon_tty_port); - stderr_id = nf_get_id("NF_STDERR"); if (!stderr_id) return -ENODEV; @@ -130,6 +128,8 @@ static int __init nfcon_init(void) if (!nfcon_tty_driver) return -ENOMEM; + tty_port_init(&nfcon_tty_port); + nfcon_tty_driver->driver_name = "nfcon"; nfcon_tty_driver->name = "nfcon"; nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; @@ -143,6 +143,7 @@ static int __init nfcon_init(void) if (res) { pr_err("failed to register nfcon tty driver\n"); put_tty_driver(nfcon_tty_driver); + tty_port_destroy(&nfcon_tty_port); return res; } @@ -157,6 +158,7 @@ static void __exit nfcon_exit(void) unregister_console(&nf_console); tty_unregister_driver(nfcon_tty_driver); put_tty_driver(nfcon_tty_driver); + tty_port_destroy(&nfcon_tty_port); } module_init(nfcon_init); diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index 88238638aee..efc5e7d3053 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c @@ -186,13 +186,13 @@ static int __init pdc_console_tty_driver_init(void) printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n"); pdc_cons.flags &= ~CON_BOOT; - tty_port_init(&tty_port); - pdc_console_tty_driver = alloc_tty_driver(1); if (!pdc_console_tty_driver) return -ENOMEM; + tty_port_init(&tty_port); + pdc_console_tty_driver->driver_name = "pdc_cons"; pdc_console_tty_driver->name = "ttyB"; pdc_console_tty_driver->major = MUX_MAJOR; @@ -207,6 +207,7 @@ static int __init pdc_console_tty_driver_init(void) err = tty_register_driver(pdc_console_tty_driver); if (err) { printk(KERN_ERR "Unable to register the PDC console TTY driver\n"); + tty_port_destroy(&tty_port); return err; } diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index fd9a15b318a..9ffc28bd4b7 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -584,6 +584,8 @@ int register_lines(struct line_driver *line_driver, printk(KERN_ERR "register_lines : can't register %s driver\n", line_driver->name); put_tty_driver(driver); + for (i = 0; i < nlines; i++) + tty_port_destroy(&lines[i].port); return err; } diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index 7e74895eee0..8207a119eee 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -221,6 +221,7 @@ static __exit void rs_exit(void) printk("ISS_SERIAL: failed to unregister serial driver (%d)\n", error); put_tty_driver(serial_driver); + tty_port_destroy(&serial_port); } diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 21721d25e38..b66eaa04f8c 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -549,8 +549,10 @@ static int mgslpc_probe(struct pcmcia_device *link) /* Initialize the struct pcmcia_device structure */ ret = mgslpc_config(link); - if (ret) + if (ret) { + tty_port_destroy(&info->port); return ret; + } mgslpc_add_device(info); @@ -2757,6 +2759,7 @@ static void mgslpc_remove_device(MGSLPC_INFO *remove_info) hdlcdev_exit(info); #endif release_resources(info); + tty_port_destroy(&info->port); kfree(info); mgslpc_device_count--; return; diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index af98f6d6509..4945bd3d18d 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -179,7 +179,6 @@ static int __init ttyprintk_init(void) { int ret = -ENOMEM; - tty_port_init(&tpk_port.port); tpk_port.port.ops = &null_ops; mutex_init(&tpk_port.port_write_mutex); @@ -190,6 +189,8 @@ static int __init ttyprintk_init(void) if (IS_ERR(ttyprintk_driver)) return PTR_ERR(ttyprintk_driver); + tty_port_init(&tpk_port.port); + ttyprintk_driver->driver_name = "ttyprintk"; ttyprintk_driver->name = "ttyprintk"; ttyprintk_driver->major = TTYAUX_MAJOR; @@ -211,6 +212,7 @@ static int __init ttyprintk_init(void) error: tty_unregister_driver(ttyprintk_driver); put_tty_driver(ttyprintk_driver); + tty_port_destroy(&tpk_port.port); ttyprintk_driver = NULL; return ret; } diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 30a6b174fbb..bc9d89a8c4f 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -518,6 +518,7 @@ f_bcs: gig_dbg(DEBUG_INIT, "freeing bcs[]"); kfree(cs->bcs); f_cs: gig_dbg(DEBUG_INIT, "freeing cs"); mutex_unlock(&cs->mutex); + tty_port_destroy(&cs->port); free_cs(cs); } EXPORT_SYMBOL_GPL(gigaset_freecs); @@ -751,14 +752,14 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, gig_dbg(DEBUG_INIT, "setting up iif"); if (gigaset_isdn_regdev(cs, modulename) < 0) { pr_err("error registering ISDN device\n"); - goto error; + goto error_port; } make_valid(cs, VALID_ID); ++cs->cs_init; gig_dbg(DEBUG_INIT, "setting up hw"); if (cs->ops->initcshw(cs) < 0) - goto error; + goto error_port; ++cs->cs_init; @@ -773,7 +774,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, gig_dbg(DEBUG_INIT, "setting up bcs[%d]", i); if (gigaset_initbcs(cs->bcs + i, cs, i) < 0) { pr_err("could not allocate channel %d data\n", i); - goto error; + goto error_port; } } @@ -786,7 +787,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, gig_dbg(DEBUG_INIT, "cs initialized"); return cs; - +error_port: + tty_port_destroy(&cs->port); error: gig_dbg(DEBUG_INIT, "failed"); gigaset_freecs(cs); diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index b817809f763..e09dc8a5e74 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -1849,6 +1849,8 @@ err_unregister: kfree(info->fax); #endif kfree(info->port.xmit_buf - 4); + info->port.xmit_buf = NULL; + tty_port_destroy(&info->port); } tty_unregister_driver(m->tty_modem); err: @@ -1870,6 +1872,8 @@ isdn_tty_exit(void) kfree(info->fax); #endif kfree(info->port.xmit_buf - 4); + info->port.xmit_buf = NULL; + tty_port_destroy(&info->port); } tty_unregister_driver(dev->mdm.tty_modem); put_tty_driver(dev->mdm.tty_modem); diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index 4999b34b7a6..a1f0d174e68 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -882,11 +882,14 @@ err: static void __devexit pti_pci_remove(struct pci_dev *pdev) { struct pti_dev *drv_data = pci_get_drvdata(pdev); + unsigned int a; unregister_console(&pti_console); - tty_unregister_device(pti_tty_driver, 0); - tty_unregister_device(pti_tty_driver, 1); + for (a = 0; a < PTITTY_MINOR_NUM; a++) { + tty_unregister_device(pti_tty_driver, a); + tty_port_destroy(&drv_data->port[a]); + } iounmap(drv_data->pti_ioaddr); pci_set_drvdata(pdev, NULL); diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 605a4baa9b7..cd8ccb240f4 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2274,6 +2274,7 @@ static void hso_serial_common_free(struct hso_serial *serial) /* unlink and free TX URB */ usb_free_urb(serial->tx_urb); kfree(serial->tx_data); + tty_port_destroy(&serial->port); } static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, @@ -2283,12 +2284,12 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, int minor; int i; + tty_port_init(&serial->port); + minor = get_free_serial_index(); if (minor < 0) goto exit; - tty_port_init(&serial->port); - /* register our minor number */ serial->parent->dev = tty_port_register_device(&serial->port, tty_drv, minor, &serial->parent->interface->dev); diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 9ffb6d5f17a..8fb014f32e4 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -677,6 +677,7 @@ static void raw3215_free_info(struct raw3215_info *raw) { kfree(raw->inbuf); kfree(raw->buffer); + tty_port_destroy(&raw->port); kfree(raw); } diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 30ec09e3d03..877fbc37c1e 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -547,7 +547,6 @@ sclp_tty_init(void) sclp_tty_tolower = 1; } sclp_tty_chars_count = 0; - tty_port_init(&sclp_port); rc = sclp_register(&sclp_input_event); if (rc) { @@ -555,6 +554,8 @@ sclp_tty_init(void) return rc; } + tty_port_init(&sclp_port); + driver->driver_name = "sclp_line"; driver->name = "sclp_line"; driver->major = TTY_MAJOR; @@ -571,6 +572,7 @@ sclp_tty_init(void) rc = tty_register_driver(driver); if (rc) { put_tty_driver(driver); + tty_port_destroy(&sclp_port); return rc; } sclp_tty_driver = driver; diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 7e60f3d2f3f..effcc8756e0 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -615,6 +615,7 @@ static void __init __sclp_vt220_cleanup(void) return; sclp_unregister(&sclp_vt220_register); __sclp_vt220_free_pages(); + tty_port_destroy(&sclp_vt220_port); } /* Allocate buffer pages and register with sclp core. Controlled by init @@ -650,6 +651,7 @@ out: if (rc) { __sclp_vt220_free_pages(); sclp_vt220_init_count--; + tty_port_destroy(&sclp_vt220_port); } return rc; } diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 482ee028f84..43ea0593bdb 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -722,6 +722,7 @@ out_pages: while (pages--) free_pages((unsigned long) tp->freemem_pages[pages], 0); kfree(tp->freemem_pages); + tty_port_destroy(&tp->port); out_tp: kfree(tp); out_err: @@ -744,6 +745,7 @@ tty3270_free_view(struct tty3270 *tp) for (pages = 0; pages < TTY3270_STRING_PAGES; pages++) free_pages((unsigned long) tp->freemem_pages[pages], 0); kfree(tp->freemem_pages); + tty_port_destroy(&tp->port); kfree(tp); } diff --git a/drivers/staging/ccg/u_serial.c b/drivers/staging/ccg/u_serial.c index 5b3f5fffea9..373c40656b5 100644 --- a/drivers/staging/ccg/u_serial.c +++ b/drivers/staging/ccg/u_serial.c @@ -1140,8 +1140,10 @@ int gserial_setup(struct usb_gadget *g, unsigned count) return status; fail: - while (count--) + while (count--) { + tty_port_destroy(&ports[count].port->port); kfree(ports[count].port); + } put_tty_driver(gs_tty_driver); gs_tty_driver = NULL; return status; @@ -1195,6 +1197,7 @@ void gserial_cleanup(void) WARN_ON(port->port_usb != NULL); + tty_port_destroy(&port->port); kfree(port); } n_ports = 0; diff --git a/drivers/staging/dgrp/dgrp_specproc.c b/drivers/staging/dgrp/dgrp_specproc.c index db91f676508..c214078a89e 100644 --- a/drivers/staging/dgrp/dgrp_specproc.c +++ b/drivers/staging/dgrp/dgrp_specproc.c @@ -752,6 +752,8 @@ static int dgrp_add_id(long id) return 0; + /* FIXME this guy should free the tty driver stored in nd and destroy + * all channel ports */ error_out: kfree(nd); return ret; diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c index e125b03598d..0db4c0514f6 100644 --- a/drivers/staging/dgrp/dgrp_tty.c +++ b/drivers/staging/dgrp/dgrp_tty.c @@ -3119,6 +3119,7 @@ static void dgrp_tty_hangup(struct tty_struct *tty) void dgrp_tty_uninit(struct nd_struct *nd) { + unsigned int i; char id[3]; ID_TO_CHAR(nd->nd_ID, id); @@ -3152,6 +3153,8 @@ dgrp_tty_uninit(struct nd_struct *nd) put_tty_driver(nd->nd_xprint_ttdriver); nd->nd_ttdriver_flags &= ~XPRINT_TTDRV_REG; } + for (i = 0; i < CHAN_MAX; i++) + tty_port_destroy(&nd->nd_chan[i].port); } @@ -3335,7 +3338,6 @@ dgrp_tty_init(struct nd_struct *nd) init_waitqueue_head(&(ch->ch_pun.un_open_wait)); init_waitqueue_head(&(ch->ch_pun.un_close_wait)); tty_port_init(&ch->port); - tty_port_init(&ch->port); } return 0; } diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index d751edfda83..729cb642840 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -446,6 +446,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL); if (IS_ERR(tty_dev)) { dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); + tty_port_destroy(&channel->tty_port); continue; } dev_set_drvdata(tty_dev, channel); @@ -741,6 +742,7 @@ static void __ipoctal_remove(struct ipoctal *ipoctal) struct ipoctal_channel *channel = &ipoctal->channel[i]; tty_unregister_device(ipoctal->tty_drv, i); tty_port_free_xmit_buf(&channel->tty_port); + tty_port_destroy(&channel->tty_port); } tty_unregister_driver(ipoctal->tty_drv); diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 42d0a2581a8..9d7d00cdfec 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1771,6 +1771,7 @@ fail_free_irq: fail_unregister: tty_unregister_driver(serial_driver); fail_put_tty_driver: + tty_port_destroy(&state->tport); put_tty_driver(serial_driver); return error; } @@ -1785,6 +1786,7 @@ static int __exit amiga_serial_remove(struct platform_device *pdev) printk("SERIAL: failed to unregister serial driver (%d)\n", error); put_tty_driver(serial_driver); + tty_port_destroy(&state->tport); free_irq(IRQ_AMIGA_TBE, state); free_irq(IRQ_AMIGA_RBF, state); diff --git a/drivers/tty/bfin_jtag_comm.c b/drivers/tty/bfin_jtag_comm.c index 02b7d3a0969..1cfcdbf1d0c 100644 --- a/drivers/tty/bfin_jtag_comm.c +++ b/drivers/tty/bfin_jtag_comm.c @@ -240,8 +240,6 @@ static int __init bfin_jc_init(void) { int ret; - tty_port_init(&port); - bfin_jc_kthread = kthread_create(bfin_jc_emudat_manager, NULL, DRV_NAME); if (IS_ERR(bfin_jc_kthread)) return PTR_ERR(bfin_jc_kthread); @@ -257,6 +255,8 @@ static int __init bfin_jc_init(void) if (!bfin_jc_driver) goto err_driver; + tty_port_init(&port); + bfin_jc_driver->driver_name = DRV_NAME; bfin_jc_driver->name = DEV_NAME; bfin_jc_driver->type = TTY_DRIVER_TYPE_SERIAL; @@ -274,6 +274,7 @@ static int __init bfin_jc_init(void) return 0; err: + tty_port_destroy(&port); put_tty_driver(bfin_jc_driver); err_driver: kfree(bfin_jc_write_buf.buf); @@ -289,6 +290,7 @@ static void __exit bfin_jc_exit(void) kfree(bfin_jc_write_buf.buf); tty_unregister_driver(bfin_jc_driver); put_tty_driver(bfin_jc_driver); + tty_port_destroy(&port); } module_exit(bfin_jc_exit); diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index 0a6a0bc1b59..de25774b5ec 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c @@ -3934,7 +3934,7 @@ err: static void __devexit cy_pci_remove(struct pci_dev *pdev) { struct cyclades_card *cinfo = pci_get_drvdata(pdev); - unsigned int i; + unsigned int i, channel; /* non-Z with old PLX */ if (!cy_is_Z(cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) == @@ -3960,9 +3960,11 @@ static void __devexit cy_pci_remove(struct pci_dev *pdev) pci_release_regions(pdev); cinfo->base_addr = NULL; - for (i = cinfo->first_line; i < cinfo->first_line + - cinfo->nports; i++) + for (channel = 0, i = cinfo->first_line; i < cinfo->first_line + + cinfo->nports; i++, channel++) { tty_unregister_device(cy_serial_driver, i); + tty_port_destroy(&cinfo->ports[channel].port); + } cinfo->nports = 0; kfree(cinfo->ports); } diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 4ab936b7aac..4193afb74a0 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -757,6 +757,7 @@ static int __devinit ehv_bc_tty_probe(struct platform_device *pdev) return 0; error: + tty_port_destroy(&bc->port); irq_dispose_mapping(bc->tx_irq); irq_dispose_mapping(bc->rx_irq); @@ -770,6 +771,7 @@ static int ehv_bc_tty_remove(struct platform_device *pdev) tty_unregister_device(ehv_bc_driver, bc - bcs); + tty_port_destroy(&bc->port); irq_dispose_mapping(bc->tx_irq); irq_dispose_mapping(bc->rx_irq); diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index 5b95b4f28cf..68357a6e4de 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -1218,6 +1218,7 @@ static int __init hvsi_console_init(void) if (hp->virq == 0) { printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", __func__, irq[0]); + tty_port_destroy(&hp->port); continue; } diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index 160f0ad9589..2cde13ddf9f 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -566,6 +566,7 @@ void ipwireless_tty_free(struct ipw_tty *tty) ipwireless_disassociate_network_ttys(network, ttyj->channel_idx); tty_unregister_device(ipw_tty_driver, j); + tty_port_destroy(&ttyj->port); ttys[j] = NULL; mutex_unlock(&ttyj->ipw_tty_mutex); kfree(ttyj); diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 9b57aae139f..d628176fb6d 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c @@ -895,6 +895,8 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev) return 0; err_free: + for (i = 0; i < MAX_PORTS_PER_BOARD; i++) + tty_port_destroy(&brd->ports[i].port); kfree(brd->ports); err: return ret; @@ -919,6 +921,8 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) tty_kref_put(tty); } } + for (a = 0; a < MAX_PORTS_PER_BOARD; a++) + tty_port_destroy(&brd->ports[a].port); while (1) { opened = 0; for (a = 0; a < brd->numPorts; a++) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index cfda47dabd2..802a248e7ab 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -2411,14 +2411,27 @@ static int __devinit mxser_initbrd(struct mxser_board *brd, retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser", brd); - if (retval) + if (retval) { + for (i = 0; i < brd->info->nports; i++) + tty_port_destroy(&brd->ports[i].port); printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may " "conflict with another device.\n", brd->info->name, brd->irq); + } return retval; } +static void mxser_board_remove(struct mxser_board *brd) +{ + unsigned int i; + + for (i = 0; i < brd->info->nports; i++) { + tty_unregister_device(mxvar_sdriver, brd->idx + i); + tty_port_destroy(&brd->ports[i].port); + } +} + static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) { int id, i, bits, ret; @@ -2649,10 +2662,8 @@ static void __devexit mxser_remove(struct pci_dev *pdev) { #ifdef CONFIG_PCI struct mxser_board *brd = pci_get_drvdata(pdev); - unsigned int i; - for (i = 0; i < brd->info->nports; i++) - tty_unregister_device(mxvar_sdriver, brd->idx + i); + mxser_board_remove(brd); free_irq(pdev->irq, brd); pci_release_region(pdev, 2); @@ -2748,15 +2759,13 @@ err_put: static void __exit mxser_module_exit(void) { - unsigned int i, j; + unsigned int i; pci_unregister_driver(&mxser_driver); for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */ if (mxser_boards[i].info != NULL) - for (j = 0; j < mxser_boards[i].info->nports; j++) - tty_unregister_device(mxvar_sdriver, - mxser_boards[i].idx + j); + mxser_board_remove(&mxser_boards[i]); tty_unregister_driver(mxvar_sdriver); put_tty_driver(mxvar_sdriver); diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index b917c942495..cb764d29775 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1479,6 +1479,7 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, if (IS_ERR(tty_dev)) { ret = PTR_ERR(tty_dev); dev_err(&pdev->dev, "Could not allocate tty?\n"); + tty_port_destroy(&port->port); goto err_free_tty; } } @@ -1486,8 +1487,10 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, return 0; err_free_tty: - for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) - tty_unregister_device(ntty_driver, i); + for (i = 0; i < MAX_PORT; ++i) { + tty_unregister_device(ntty_driver, dc->index_start + i); + tty_port_destroy(&dc->port[i].port); + } err_free_kfifo: for (i = 0; i < MAX_PORT; i++) kfifo_free(&dc->port[i].fifo_ul); @@ -1520,8 +1523,10 @@ static void __devexit tty_exit(struct nozomi *dc) complete off a hangup method ? */ while (dc->open_ttys) msleep(1); - for (i = dc->index_start; i < dc->index_start + MAX_PORT; ++i) - tty_unregister_device(ntty_driver, i); + for (i = 0; i < MAX_PORT; ++i) { + tty_unregister_device(ntty_driver, dc->index_start + i); + tty_port_destroy(&dc->port[i].port); + } } /* Deallocate memory for one device */ diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 9700d34b20a..d9056dac4ea 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c @@ -673,6 +673,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) { printk(KERN_ERR "RocketPort sInitChan(%d, %d, %d) failed!\n", board, aiop, chan); + tty_port_destroy(&info->port); kfree(info); return; } @@ -2357,6 +2358,7 @@ static void rp_cleanup_module(void) for (i = 0; i < MAX_RP_PORTS; i++) if (rp_table[i]) { tty_unregister_device(rocket_driver, i); + tty_port_destroy(&rp_table[i]->port); kfree(rp_table[i]); } diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index 66c38a3f74c..f99a84526f8 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c @@ -1225,6 +1225,8 @@ rs68328_init(void) if (tty_register_driver(serial_driver)) { put_tty_driver(serial_driver); + for (i = 0; i < NR_PORTS; i++) + tty_port_destroy(&m68k_soft[i].tport); printk(KERN_ERR "Couldn't register serial driver\n"); return -ENOMEM; } diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 1754c147a94..91125bb151c 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c @@ -829,6 +829,7 @@ static void ifx_spi_free_port(struct ifx_spi_device *ifx_dev) { if (ifx_dev->tty_dev) tty_unregister_device(tty_drv, ifx_dev->minor); + tty_port_destroy(&ifx_dev->tty_port); kfifo_free(&ifx_dev->tx_fifo); } @@ -862,10 +863,12 @@ static int ifx_spi_create_port(struct ifx_spi_device *ifx_dev) dev_dbg(&ifx_dev->spi_dev->dev, "%s: registering tty device failed", __func__); ret = PTR_ERR(ifx_dev->tty_dev); - goto error_ret; + goto error_port; } return 0; +error_port: + tty_port_destroy(pport); error_ret: ifx_spi_free_port(ifx_dev); return ret; diff --git a/drivers/tty/serial/kgdb_nmi.c b/drivers/tty/serial/kgdb_nmi.c index d185247ba1a..6ac2b797a76 100644 --- a/drivers/tty/serial/kgdb_nmi.c +++ b/drivers/tty/serial/kgdb_nmi.c @@ -266,6 +266,7 @@ static int kgdb_nmi_tty_install(struct tty_driver *drv, struct tty_struct *tty) } return 0; err: + tty_port_destroy(&priv->port); kfree(priv); return ret; } @@ -275,6 +276,7 @@ static void kgdb_nmi_tty_cleanup(struct tty_struct *tty) struct kgdb_nmi_tty_priv *priv = tty->driver_data; tty->driver_data = NULL; + tty_port_destroy(&priv->port); kfree(priv); } diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 63b33889d51..61ba24089ef 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2297,6 +2297,8 @@ int uart_register_driver(struct uart_driver *drv) if (retval >= 0) return retval; + for (i = 0; i < drv->nr; i++) + tty_port_destroy(&drv->state[i].port); put_tty_driver(normal); out_kfree: kfree(drv->state); @@ -2316,8 +2318,12 @@ out: void uart_unregister_driver(struct uart_driver *drv) { struct tty_driver *p = drv->tty_driver; + unsigned int i; + tty_unregister_driver(p); put_tty_driver(p); + for (i = 0; i < drv->nr; i++) + tty_port_destroy(&drv->state[i].port); kfree(drv->state); drv->state = NULL; drv->tty_driver = NULL; diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 70e3a525bc8..e4b5c39fc4e 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c @@ -4425,6 +4425,7 @@ static void synclink_cleanup(void) mgsl_release_resources(info); tmp = info; info = info->next_device; + tty_port_destroy(&tmp->port); kfree(tmp); } diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index b38e954eedd..6e4c34011b7 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -3645,8 +3645,10 @@ static void device_init(int adapter_num, struct pci_dev *pdev) for (i=0; i < port_count; ++i) { port_array[i] = alloc_dev(adapter_num, i, pdev); if (port_array[i] == NULL) { - for (--i; i >= 0; --i) + for (--i; i >= 0; --i) { + tty_port_destroy(&port_array[i]->port); kfree(port_array[i]); + } return; } } @@ -3773,6 +3775,7 @@ static void slgt_cleanup(void) release_resources(info); tmp = info; info = info->next_device; + tty_port_destroy(&tmp->port); kfree(tmp); } diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index f17d9f3d84a..40745beb258 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c @@ -3843,8 +3843,10 @@ static void device_init(int adapter_num, struct pci_dev *pdev) for ( port = 0; port < SCA_MAX_PORTS; ++port ) { port_array[port] = alloc_dev(adapter_num,port,pdev); if( port_array[port] == NULL ) { - for ( --port; port >= 0; --port ) + for (--port; port >= 0; --port) { + tty_port_destroy(&port_array[port]->port); kfree(port_array[port]); + } return; } } @@ -3953,6 +3955,7 @@ static void synclinkmp_cleanup(void) } tmp = info; info = info->next_device; + tty_port_destroy(&tmp->port); kfree(tmp); } diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index f87d7e8964b..607636b4734 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -779,6 +779,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ con_set_default_unimap(vc); vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); if (!vc->vc_screenbuf) { + tty_port_destroy(&vc->port); kfree(vc); vc_cons[currcons].d = NULL; return -ENOMEM; @@ -999,8 +1000,10 @@ void vc_deallocate(unsigned int currcons) put_pid(vc->vt_pid); module_put(vc->vc_sw->owner); kfree(vc->vc_screenbuf); - if (currcons >= MIN_NR_CONSOLES) + if (currcons >= MIN_NR_CONSOLES) { + tty_port_destroy(&vc->port); kfree(vc); + } vc_cons[currcons].d = NULL; } } diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index f1739526820..d0f95482f40 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -1145,8 +1145,10 @@ int gserial_setup(struct usb_gadget *g, unsigned count) return status; fail: - while (count--) + while (count--) { + tty_port_destroy(&ports[count].port->port); kfree(ports[count].port); + } put_tty_driver(gs_tty_driver); gs_tty_driver = NULL; return status; @@ -1200,6 +1202,7 @@ void gserial_cleanup(void) WARN_ON(port->port_usb != NULL); + tty_port_destroy(&port->port); kfree(port); } n_ports = 0; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 73b8e056916..64bda135ba7 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -597,6 +597,7 @@ static void port_release(struct device *dev) kfifo_free(&port->write_fifo); kfree(port->interrupt_in_buffer); kfree(port->interrupt_out_buffer); + tty_port_destroy(&port->port); kfree(port); } diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 496ce2cebcd..a68c88cdec6 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -183,6 +183,7 @@ static void __exit __ircomm_tty_cleanup(struct ircomm_tty_cb *self) ircomm_tty_shutdown(self); self->magic = 0; + tty_port_destroy(&self->port); kfree(self); } -- cgit v1.2.3 From 6e8bd6e727c5ec949194087ac6b593e1e7fe79c4 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 5 Nov 2012 15:04:23 -0800 Subject: drivers/parport: remove depends on CONFIG_EXPERIMENTAL The CONFIG_EXPERIMENTAL config item has not carried much meaning for a while now and is almost always enabled by default. As agreed during the Linux kernel summit, remove it from any "depends on" lines in Kconfigs. Signed-off-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- drivers/parport/Kconfig | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig index 4b6e4e7aca8..0e60438ebe3 100644 --- a/drivers/parport/Kconfig +++ b/drivers/parport/Kconfig @@ -57,8 +57,8 @@ config PARPORT_SERIAL will be called parport_serial. config PARPORT_PC_FIFO - bool "Use FIFO/DMA if available (EXPERIMENTAL)" - depends on PARPORT_PC && EXPERIMENTAL + bool "Use FIFO/DMA if available" + depends on PARPORT_PC help Many parallel port chipsets provide hardware that can speed up printing. Say Y here if you want to take advantage of that. @@ -70,8 +70,8 @@ config PARPORT_PC_FIFO specify which IRQ/DMA to use. config PARPORT_PC_SUPERIO - bool "SuperIO chipset support (EXPERIMENTAL)" - depends on PARPORT_PC && EXPERIMENTAL + bool "SuperIO chipset support" + depends on PARPORT_PC help Saying Y here enables some probes for Super-IO chipsets in order to find out things like base addresses, IRQ lines and DMA channels. It @@ -85,8 +85,8 @@ config PARPORT_PC_PCMCIA ports. If unsure, say N. config PARPORT_IP32 - tristate "SGI IP32 builtin port (EXPERIMENTAL)" - depends on SGI_IP32 && EXPERIMENTAL + tristate "SGI IP32 builtin port" + depends on SGI_IP32 select PARPORT_NOT_PC help Say Y here if you need support for the parallel port on @@ -126,8 +126,8 @@ config PARPORT_GSC select PARPORT_NOT_PC config PARPORT_SUNBPP - tristate "Sparc hardware (EXPERIMENTAL)" - depends on SBUS && EXPERIMENTAL + tristate "Sparc hardware" + depends on SBUS select PARPORT_NOT_PC help This driver provides support for the bidirectional parallel port -- cgit v1.2.3 From ecd43c0d7e504fde69e6e53ac63adfd2feea135a Mon Sep 17 00:00:00 2001 From: Manuel Traut Date: Fri, 9 Nov 2012 07:06:40 +0100 Subject: uio_pdrv: set memory mapping name If uio_pdrv[_genirq] is used, the uio maps have currently no name set. This patch sets the uio_mem name to the name of the memory resource. Signed-off-by: Manuel Traut Reported-by: Stefan Staedtler Tested-by: Stefan Staedtler Signed-off-by: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_pdrv.c | 1 + drivers/uio/uio_pdrv_genirq.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/uio/uio_pdrv.c b/drivers/uio/uio_pdrv.c index 72d3646c736..39be9e06170 100644 --- a/drivers/uio/uio_pdrv.c +++ b/drivers/uio/uio_pdrv.c @@ -60,6 +60,7 @@ static int uio_pdrv_probe(struct platform_device *pdev) uiomem->memtype = UIO_MEM_PHYS; uiomem->addr = r->start; uiomem->size = resource_size(r); + uiomem->name = r->name; ++uiomem; } diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index 42202cd8315..ac988ce62f2 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c @@ -172,6 +172,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev) uiomem->memtype = UIO_MEM_PHYS; uiomem->addr = r->start; uiomem->size = resource_size(r); + uiomem->name = r->name; ++uiomem; } -- cgit v1.2.3 From 67d16a4686c9b94c8f52a66afe7521909aeb75b4 Mon Sep 17 00:00:00 2001 From: Wei WANG Date: Fri, 9 Nov 2012 20:53:33 +0800 Subject: drivers/mfd: Add realtek pcie card reader driver Realtek PCI-E card reader driver adapts requests from upper-level sdmmc/memstick layer to the real physical card reader. Signed-off-by: Wei WANG Reviewed-by: Arnd Bergmann Tested-by: Borislav Petkov Signed-off-by: Greg Kroah-Hartman --- drivers/mfd/Kconfig | 9 + drivers/mfd/Makefile | 3 + drivers/mfd/rtl8411.c | 251 ++++++++ drivers/mfd/rts5209.c | 223 +++++++ drivers/mfd/rts5229.c | 205 +++++++ drivers/mfd/rtsx_pcr.c | 1251 +++++++++++++++++++++++++++++++++++++++ drivers/mfd/rtsx_pcr.h | 32 + include/linux/mfd/rtsx_common.h | 48 ++ include/linux/mfd/rtsx_pci.h | 794 +++++++++++++++++++++++++ 9 files changed, 2816 insertions(+) create mode 100644 drivers/mfd/rtl8411.c create mode 100644 drivers/mfd/rts5209.c create mode 100644 drivers/mfd/rts5229.c create mode 100644 drivers/mfd/rtsx_pcr.c create mode 100644 drivers/mfd/rtsx_pcr.h create mode 100644 include/linux/mfd/rtsx_common.h create mode 100644 include/linux/mfd/rtsx_pci.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index acab3ef8a31..867af072d48 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -63,6 +63,15 @@ config MFD_SM501_GPIO lines on the SM501. The platform data is used to supply the base number for the first GPIO line to register. +config MFD_RTSX_PCI + tristate "Support for Realtek PCI-E card reader" + depends on PCI + help + This supports for Realtek PCI-Express card reader including rts5209, + rts5229, rtl8411, etc. Realtek card reader supports access to many + types of memory cards, such as Memory Stick, Memory Stick Pro, + Secure Digital and MultiMediaCard. + config MFD_ASIC3 bool "Support for Compaq ASIC3" depends on GENERIC_HARDIRQS && GPIOLIB && ARM diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index d8ccb630ddb..b53db06d1b4 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -9,6 +9,9 @@ obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o obj-$(CONFIG_MFD_SM501) += sm501.o obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o +rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o +obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o + obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c new file mode 100644 index 00000000000..89f046ca9e4 --- /dev/null +++ b/drivers/mfd/rtl8411.c @@ -0,0 +1,251 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * 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, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * Wei WANG + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include +#include + +#include "rtsx_pcr.h" + +static u8 rtl8411_get_ic_version(struct rtsx_pcr *pcr) +{ + u8 val; + + rtsx_pci_read_register(pcr, SYS_VER, &val); + return val & 0x0F; +} + +static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, CD_PAD_CTL, + CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE); +} + +static int rtl8411_turn_on_led(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x00); +} + +static int rtl8411_turn_off_led(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x01); +} + +static int rtl8411_enable_auto_blink(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0xFF, 0x0D); +} + +static int rtl8411_disable_auto_blink(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0x08, 0x00); +} + +static int rtl8411_card_power_on(struct rtsx_pcr *pcr, int card) +{ + int err; + + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, + BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CTL, + BPP_LDO_POWB, BPP_LDO_SUSPEND); + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + /* To avoid too large in-rush current */ + udelay(150); + + err = rtsx_pci_write_register(pcr, CARD_PWR_CTL, + BPP_POWER_MASK, BPP_POWER_10_PERCENT_ON); + if (err < 0) + return err; + + udelay(150); + + err = rtsx_pci_write_register(pcr, CARD_PWR_CTL, + BPP_POWER_MASK, BPP_POWER_15_PERCENT_ON); + if (err < 0) + return err; + + udelay(150); + + err = rtsx_pci_write_register(pcr, CARD_PWR_CTL, + BPP_POWER_MASK, BPP_POWER_ON); + if (err < 0) + return err; + + return rtsx_pci_write_register(pcr, LDO_CTL, BPP_LDO_POWB, BPP_LDO_ON); +} + +static int rtl8411_card_power_off(struct rtsx_pcr *pcr, int card) +{ + int err; + + err = rtsx_pci_write_register(pcr, CARD_PWR_CTL, + BPP_POWER_MASK, BPP_POWER_OFF); + if (err < 0) + return err; + + return rtsx_pci_write_register(pcr, LDO_CTL, + BPP_LDO_POWB, BPP_LDO_SUSPEND); +} + +static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr) +{ + unsigned int card_exist; + + card_exist = rtsx_pci_readl(pcr, RTSX_BIPR); + card_exist &= CARD_EXIST; + if (!card_exist) { + /* Enable card CD */ + rtsx_pci_write_register(pcr, CD_PAD_CTL, + CD_DISABLE_MASK, CD_ENABLE); + /* Enable card interrupt */ + rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x00); + return 0; + } + + if (hweight32(card_exist) > 1) { + rtsx_pci_write_register(pcr, CARD_PWR_CTL, + BPP_POWER_MASK, BPP_POWER_5_PERCENT_ON); + msleep(100); + + card_exist = rtsx_pci_readl(pcr, RTSX_BIPR); + if (card_exist & MS_EXIST) + card_exist = MS_EXIST; + else if (card_exist & SD_EXIST) + card_exist = SD_EXIST; + else + card_exist = 0; + + rtsx_pci_write_register(pcr, CARD_PWR_CTL, + BPP_POWER_MASK, BPP_POWER_OFF); + + dev_dbg(&(pcr->pci->dev), + "After CD deglitch, card_exist = 0x%x\n", + card_exist); + } + + if (card_exist & MS_EXIST) { + /* Disable SD interrupt */ + rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x40); + rtsx_pci_write_register(pcr, CD_PAD_CTL, + CD_DISABLE_MASK, MS_CD_EN_ONLY); + } else if (card_exist & SD_EXIST) { + /* Disable MS interrupt */ + rtsx_pci_write_register(pcr, EFUSE_CONTENT, 0xe0, 0x80); + rtsx_pci_write_register(pcr, CD_PAD_CTL, + CD_DISABLE_MASK, SD_CD_EN_ONLY); + } + + return card_exist; +} + +static const struct pcr_ops rtl8411_pcr_ops = { + .extra_init_hw = rtl8411_extra_init_hw, + .optimize_phy = NULL, + .turn_on_led = rtl8411_turn_on_led, + .turn_off_led = rtl8411_turn_off_led, + .enable_auto_blink = rtl8411_enable_auto_blink, + .disable_auto_blink = rtl8411_disable_auto_blink, + .card_power_on = rtl8411_card_power_on, + .card_power_off = rtl8411_card_power_off, + .cd_deglitch = rtl8411_cd_deglitch, +}; + +/* SD Pull Control Enable: + * SD_DAT[3:0] ==> pull up + * SD_CD ==> pull up + * SD_WP ==> pull up + * SD_CMD ==> pull up + * SD_CLK ==> pull down + */ +static const u32 rtl8411_sd_pull_ctl_enable_tbl[] = { + RTSX_REG_PAIR(CARD_PULL_CTL1, 0xAA), + RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA), + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xA9), + RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09), + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x09), + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04), + 0, +}; + +/* SD Pull Control Disable: + * SD_DAT[3:0] ==> pull down + * SD_CD ==> pull up + * SD_WP ==> pull down + * SD_CMD ==> pull down + * SD_CLK ==> pull down + */ +static const u32 rtl8411_sd_pull_ctl_disable_tbl[] = { + RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65), + RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95), + RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09), + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05), + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04), + 0, +}; + +/* MS Pull Control Enable: + * MS CD ==> pull up + * others ==> pull down + */ +static const u32 rtl8411_ms_pull_ctl_enable_tbl[] = { + RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65), + RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95), + RTSX_REG_PAIR(CARD_PULL_CTL4, 0x05), + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05), + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04), + 0, +}; + +/* MS Pull Control Disable: + * MS CD ==> pull up + * others ==> pull down + */ +static const u32 rtl8411_ms_pull_ctl_disable_tbl[] = { + RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65), + RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL3, 0x95), + RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09), + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05), + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04), + 0, +}; + +void rtl8411_init_params(struct rtsx_pcr *pcr) +{ + pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104; + pcr->num_slots = 2; + pcr->ops = &rtl8411_pcr_ops; + + pcr->ic_version = rtl8411_get_ic_version(pcr); + pcr->sd_pull_ctl_enable_tbl = rtl8411_sd_pull_ctl_enable_tbl; + pcr->sd_pull_ctl_disable_tbl = rtl8411_sd_pull_ctl_disable_tbl; + pcr->ms_pull_ctl_enable_tbl = rtl8411_ms_pull_ctl_enable_tbl; + pcr->ms_pull_ctl_disable_tbl = rtl8411_ms_pull_ctl_disable_tbl; +} diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c new file mode 100644 index 00000000000..283a4f14808 --- /dev/null +++ b/drivers/mfd/rts5209.c @@ -0,0 +1,223 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * 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, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * Wei WANG + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include + +#include "rtsx_pcr.h" + +static u8 rts5209_get_ic_version(struct rtsx_pcr *pcr) +{ + u8 val; + + val = rtsx_pci_readb(pcr, 0x1C); + return val & 0x0F; +} + +static void rts5209_init_vendor_cfg(struct rtsx_pcr *pcr) +{ + u32 val; + + rtsx_pci_read_config_dword(pcr, 0x724, &val); + dev_dbg(&(pcr->pci->dev), "Cfg 0x724: 0x%x\n", val); + + if (!(val & 0x80)) { + if (val & 0x08) + pcr->ms_pmos = false; + else + pcr->ms_pmos = true; + } +} + +static int rts5209_extra_init_hw(struct rtsx_pcr *pcr) +{ + rtsx_pci_init_cmd(pcr); + + /* Turn off LED */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO, 0xFF, 0x03); + /* Configure GPIO as output */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO_DIR, 0xFF, 0x03); + + return rtsx_pci_send_cmd(pcr, 100); +} + +static int rts5209_optimize_phy(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_phy_register(pcr, 0x00, 0xB966); +} + +static int rts5209_turn_on_led(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x00); +} + +static int rts5209_turn_off_led(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x01); +} + +static int rts5209_enable_auto_blink(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0xFF, 0x0D); +} + +static int rts5209_disable_auto_blink(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, CARD_AUTO_BLINK, 0x08, 0x00); +} + +static int rts5209_card_power_on(struct rtsx_pcr *pcr, int card) +{ + int err; + u8 pwr_mask, partial_pwr_on, pwr_on; + + pwr_mask = SD_POWER_MASK; + partial_pwr_on = SD_PARTIAL_POWER_ON; + pwr_on = SD_POWER_ON; + + if (pcr->ms_pmos && (card == RTSX_MS_CARD)) { + pwr_mask = MS_POWER_MASK; + partial_pwr_on = MS_PARTIAL_POWER_ON; + pwr_on = MS_POWER_ON; + } + + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, + pwr_mask, partial_pwr_on); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, + LDO3318_PWR_MASK, 0x04); + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + /* To avoid too large in-rush current */ + udelay(150); + + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, pwr_mask, pwr_on); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, + LDO3318_PWR_MASK, 0x00); + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + return 0; +} + +static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card) +{ + u8 pwr_mask, pwr_off; + + pwr_mask = SD_POWER_MASK; + pwr_off = SD_POWER_OFF; + + if (pcr->ms_pmos && (card == RTSX_MS_CARD)) { + pwr_mask = MS_POWER_MASK; + pwr_off = MS_POWER_OFF; + } + + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, + pwr_mask | PMOS_STRG_MASK, pwr_off | PMOS_STRG_400mA); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, + LDO3318_PWR_MASK, 0X06); + return rtsx_pci_send_cmd(pcr, 100); +} + +static const struct pcr_ops rts5209_pcr_ops = { + .extra_init_hw = rts5209_extra_init_hw, + .optimize_phy = rts5209_optimize_phy, + .turn_on_led = rts5209_turn_on_led, + .turn_off_led = rts5209_turn_off_led, + .enable_auto_blink = rts5209_enable_auto_blink, + .disable_auto_blink = rts5209_disable_auto_blink, + .card_power_on = rts5209_card_power_on, + .card_power_off = rts5209_card_power_off, + .cd_deglitch = NULL, +}; + +/* SD Pull Control Enable: + * SD_DAT[3:0] ==> pull up + * SD_CD ==> pull up + * SD_WP ==> pull up + * SD_CMD ==> pull up + * SD_CLK ==> pull down + */ +static const u32 rts5209_sd_pull_ctl_enable_tbl[] = { + RTSX_REG_PAIR(CARD_PULL_CTL1, 0xAA), + RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA), + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9), + 0, +}; + +/* SD Pull Control Disable: + * SD_DAT[3:0] ==> pull down + * SD_CD ==> pull up + * SD_WP ==> pull down + * SD_CMD ==> pull down + * SD_CLK ==> pull down + */ +static const u32 rts5209_sd_pull_ctl_disable_tbl[] = { + RTSX_REG_PAIR(CARD_PULL_CTL1, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5), + 0, +}; + +/* MS Pull Control Enable: + * MS CD ==> pull up + * others ==> pull down + */ +static const u32 rts5209_ms_pull_ctl_enable_tbl[] = { + RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15), + 0, +}; + +/* MS Pull Control Disable: + * MS CD ==> pull up + * others ==> pull down + */ +static const u32 rts5209_ms_pull_ctl_disable_tbl[] = { + RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15), + 0, +}; + +void rts5209_init_params(struct rtsx_pcr *pcr) +{ + pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | + EXTRA_CAPS_SD_SDR104 | EXTRA_CAPS_MMC_8BIT; + pcr->num_slots = 2; + pcr->ops = &rts5209_pcr_ops; + + rts5209_init_vendor_cfg(pcr); + + pcr->ic_version = rts5209_get_ic_version(pcr); + pcr->sd_pull_ctl_enable_tbl = rts5209_sd_pull_ctl_enable_tbl; + pcr->sd_pull_ctl_disable_tbl = rts5209_sd_pull_ctl_disable_tbl; + pcr->ms_pull_ctl_enable_tbl = rts5209_ms_pull_ctl_enable_tbl; + pcr->ms_pull_ctl_disable_tbl = rts5209_ms_pull_ctl_disable_tbl; +} diff --git a/drivers/mfd/rts5229.c b/drivers/mfd/rts5229.c new file mode 100644 index 00000000000..b9dbab266fd --- /dev/null +++ b/drivers/mfd/rts5229.c @@ -0,0 +1,205 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * 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, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * Wei WANG + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include + +#include "rtsx_pcr.h" + +static u8 rts5229_get_ic_version(struct rtsx_pcr *pcr) +{ + u8 val; + + rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val); + return val & 0x0F; +} + +static int rts5229_extra_init_hw(struct rtsx_pcr *pcr) +{ + rtsx_pci_init_cmd(pcr); + + /* Configure GPIO as output */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02); + /* Switch LDO3318 source from DV33 to card_3v3 */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01); + /* LED shine disabled, set initial shine cycle period */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02); + + return rtsx_pci_send_cmd(pcr, 100); +} + +static int rts5229_optimize_phy(struct rtsx_pcr *pcr) +{ + /* Optimize RX sensitivity */ + return rtsx_pci_write_phy_register(pcr, 0x00, 0xBA42); +} + +static int rts5229_turn_on_led(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02); +} + +static int rts5229_turn_off_led(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00); +} + +static int rts5229_enable_auto_blink(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08); +} + +static int rts5229_disable_auto_blink(struct rtsx_pcr *pcr) +{ + return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00); +} + +static int rts5229_card_power_on(struct rtsx_pcr *pcr, int card) +{ + int err; + + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, + SD_POWER_MASK, SD_PARTIAL_POWER_ON); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, + LDO3318_PWR_MASK, 0x02); + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + /* To avoid too large in-rush current */ + udelay(150); + + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, + SD_POWER_MASK, SD_POWER_ON); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, + LDO3318_PWR_MASK, 0x06); + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + return 0; +} + +static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card) +{ + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, + SD_POWER_MASK | PMOS_STRG_MASK, + SD_POWER_OFF | PMOS_STRG_400mA); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, + LDO3318_PWR_MASK, 0X00); + return rtsx_pci_send_cmd(pcr, 100); +} + +static const struct pcr_ops rts5229_pcr_ops = { + .extra_init_hw = rts5229_extra_init_hw, + .optimize_phy = rts5229_optimize_phy, + .turn_on_led = rts5229_turn_on_led, + .turn_off_led = rts5229_turn_off_led, + .enable_auto_blink = rts5229_enable_auto_blink, + .disable_auto_blink = rts5229_disable_auto_blink, + .card_power_on = rts5229_card_power_on, + .card_power_off = rts5229_card_power_off, + .cd_deglitch = NULL, +}; + +/* SD Pull Control Enable: + * SD_DAT[3:0] ==> pull up + * SD_CD ==> pull up + * SD_WP ==> pull up + * SD_CMD ==> pull up + * SD_CLK ==> pull down + */ +static const u32 rts5229_sd_pull_ctl_enable_tbl1[] = { + RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA), + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9), + 0, +}; + +/* For RTS5229 version C */ +static const u32 rts5229_sd_pull_ctl_enable_tbl2[] = { + RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA), + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD9), + 0, +}; + +/* SD Pull Control Disable: + * SD_DAT[3:0] ==> pull down + * SD_CD ==> pull up + * SD_WP ==> pull down + * SD_CMD ==> pull down + * SD_CLK ==> pull down + */ +static const u32 rts5229_sd_pull_ctl_disable_tbl1[] = { + RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5), + 0, +}; + +/* For RTS5229 version C */ +static const u32 rts5229_sd_pull_ctl_disable_tbl2[] = { + RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE5), + 0, +}; + +/* MS Pull Control Enable: + * MS CD ==> pull up + * others ==> pull down + */ +static const u32 rts5229_ms_pull_ctl_enable_tbl[] = { + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15), + 0, +}; + +/* MS Pull Control Disable: + * MS CD ==> pull up + * others ==> pull down + */ +static const u32 rts5229_ms_pull_ctl_disable_tbl[] = { + RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55), + RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15), + 0, +}; + +void rts5229_init_params(struct rtsx_pcr *pcr) +{ + pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104; + pcr->num_slots = 2; + pcr->ops = &rts5229_pcr_ops; + + pcr->ic_version = rts5229_get_ic_version(pcr); + if (pcr->ic_version == IC_VER_C) { + pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl2; + pcr->sd_pull_ctl_disable_tbl = rts5229_sd_pull_ctl_disable_tbl2; + } else { + pcr->sd_pull_ctl_enable_tbl = rts5229_sd_pull_ctl_enable_tbl1; + pcr->sd_pull_ctl_disable_tbl = rts5229_sd_pull_ctl_disable_tbl1; + } + pcr->ms_pull_ctl_enable_tbl = rts5229_ms_pull_ctl_enable_tbl; + pcr->ms_pull_ctl_disable_tbl = rts5229_ms_pull_ctl_disable_tbl; +} diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c new file mode 100644 index 00000000000..56d4377c62c --- /dev/null +++ b/drivers/mfd/rtsx_pcr.c @@ -0,0 +1,1251 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * 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, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * Wei WANG + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rtsx_pcr.h" + +static bool msi_en = true; +module_param(msi_en, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(msi_en, "Enable MSI"); + +static DEFINE_IDR(rtsx_pci_idr); +static DEFINE_SPINLOCK(rtsx_pci_lock); + +static struct mfd_cell rtsx_pcr_cells[] = { + [RTSX_SD_CARD] = { + .name = DRV_NAME_RTSX_PCI_SDMMC, + }, + [RTSX_MS_CARD] = { + .name = DRV_NAME_RTSX_PCI_MS, + }, +}; + +static DEFINE_PCI_DEVICE_TABLE(rtsx_pci_ids) = { + { PCI_DEVICE(0x10EC, 0x5209), PCI_CLASS_OTHERS << 16, 0xFF0000 }, + { PCI_DEVICE(0x10EC, 0x5229), PCI_CLASS_OTHERS << 16, 0xFF0000 }, + { PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, rtsx_pci_ids); + +void rtsx_pci_start_run(struct rtsx_pcr *pcr) +{ + /* If pci device removed, don't queue idle work any more */ + if (pcr->remove_pci) + return; + + if (pcr->state != PDEV_STAT_RUN) { + pcr->state = PDEV_STAT_RUN; + if (pcr->ops->enable_auto_blink) + pcr->ops->enable_auto_blink(pcr); + } + + mod_delayed_work(system_wq, &pcr->idle_work, msecs_to_jiffies(200)); +} +EXPORT_SYMBOL_GPL(rtsx_pci_start_run); + +int rtsx_pci_write_register(struct rtsx_pcr *pcr, u16 addr, u8 mask, u8 data) +{ + int i; + u32 val = HAIMR_WRITE_START; + + val |= (u32)(addr & 0x3FFF) << 16; + val |= (u32)mask << 8; + val |= (u32)data; + + rtsx_pci_writel(pcr, RTSX_HAIMR, val); + + for (i = 0; i < MAX_RW_REG_CNT; i++) { + val = rtsx_pci_readl(pcr, RTSX_HAIMR); + if ((val & HAIMR_TRANS_END) == 0) { + if (data != (u8)val) + return -EIO; + return 0; + } + } + + return -ETIMEDOUT; +} +EXPORT_SYMBOL_GPL(rtsx_pci_write_register); + +int rtsx_pci_read_register(struct rtsx_pcr *pcr, u16 addr, u8 *data) +{ + u32 val = HAIMR_READ_START; + int i; + + val |= (u32)(addr & 0x3FFF) << 16; + rtsx_pci_writel(pcr, RTSX_HAIMR, val); + + for (i = 0; i < MAX_RW_REG_CNT; i++) { + val = rtsx_pci_readl(pcr, RTSX_HAIMR); + if ((val & HAIMR_TRANS_END) == 0) + break; + } + + if (i >= MAX_RW_REG_CNT) + return -ETIMEDOUT; + + if (data) + *data = (u8)(val & 0xFF); + + return 0; +} +EXPORT_SYMBOL_GPL(rtsx_pci_read_register); + +int rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val) +{ + int err, i, finished = 0; + u8 tmp; + + rtsx_pci_init_cmd(pcr); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYDATA0, 0xFF, (u8)val); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYDATA1, 0xFF, (u8)(val >> 8)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYADDR, 0xFF, addr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYRWCTL, 0xFF, 0x81); + + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + for (i = 0; i < 100000; i++) { + err = rtsx_pci_read_register(pcr, PHYRWCTL, &tmp); + if (err < 0) + return err; + + if (!(tmp & 0x80)) { + finished = 1; + break; + } + } + + if (!finished) + return -ETIMEDOUT; + + return 0; +} +EXPORT_SYMBOL_GPL(rtsx_pci_write_phy_register); + +int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val) +{ + int err, i, finished = 0; + u16 data; + u8 *ptr, tmp; + + rtsx_pci_init_cmd(pcr); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYADDR, 0xFF, addr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PHYRWCTL, 0xFF, 0x80); + + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + for (i = 0; i < 100000; i++) { + err = rtsx_pci_read_register(pcr, PHYRWCTL, &tmp); + if (err < 0) + return err; + + if (!(tmp & 0x80)) { + finished = 1; + break; + } + } + + if (!finished) + return -ETIMEDOUT; + + rtsx_pci_init_cmd(pcr); + + rtsx_pci_add_cmd(pcr, READ_REG_CMD, PHYDATA0, 0, 0); + rtsx_pci_add_cmd(pcr, READ_REG_CMD, PHYDATA1, 0, 0); + + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + ptr = rtsx_pci_get_cmd_data(pcr); + data = ((u16)ptr[1] << 8) | ptr[0]; + + if (val) + *val = data; + + return 0; +} +EXPORT_SYMBOL_GPL(rtsx_pci_read_phy_register); + +void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr) +{ + rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD); + rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA); + + rtsx_pci_write_register(pcr, DMACTL, 0x80, 0x80); + rtsx_pci_write_register(pcr, RBCTL, 0x80, 0x80); +} +EXPORT_SYMBOL_GPL(rtsx_pci_stop_cmd); + +void rtsx_pci_add_cmd(struct rtsx_pcr *pcr, + u8 cmd_type, u16 reg_addr, u8 mask, u8 data) +{ + unsigned long flags; + u32 val = 0; + u32 *ptr = (u32 *)(pcr->host_cmds_ptr); + + val |= (u32)(cmd_type & 0x03) << 30; + val |= (u32)(reg_addr & 0x3FFF) << 16; + val |= (u32)mask << 8; + val |= (u32)data; + + spin_lock_irqsave(&pcr->lock, flags); + ptr += pcr->ci; + if (pcr->ci < (HOST_CMDS_BUF_LEN / 4)) { + put_unaligned_le32(val, ptr); + ptr++; + pcr->ci++; + } + spin_unlock_irqrestore(&pcr->lock, flags); +} +EXPORT_SYMBOL_GPL(rtsx_pci_add_cmd); + +void rtsx_pci_send_cmd_no_wait(struct rtsx_pcr *pcr) +{ + u32 val = 1 << 31; + + rtsx_pci_writel(pcr, RTSX_HCBAR, pcr->host_cmds_addr); + + val |= (u32)(pcr->ci * 4) & 0x00FFFFFF; + /* Hardware Auto Response */ + val |= 0x40000000; + rtsx_pci_writel(pcr, RTSX_HCBCTLR, val); +} +EXPORT_SYMBOL_GPL(rtsx_pci_send_cmd_no_wait); + +int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout) +{ + struct completion trans_done; + u32 val = 1 << 31; + long timeleft; + unsigned long flags; + int err = 0; + + spin_lock_irqsave(&pcr->lock, flags); + + /* set up data structures for the wakeup system */ + pcr->done = &trans_done; + pcr->trans_result = TRANS_NOT_READY; + init_completion(&trans_done); + + rtsx_pci_writel(pcr, RTSX_HCBAR, pcr->host_cmds_addr); + + val |= (u32)(pcr->ci * 4) & 0x00FFFFFF; + /* Hardware Auto Response */ + val |= 0x40000000; + rtsx_pci_writel(pcr, RTSX_HCBCTLR, val); + + spin_unlock_irqrestore(&pcr->lock, flags); + + /* Wait for TRANS_OK_INT */ + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, msecs_to_jiffies(timeout)); + if (timeleft <= 0) { + dev_dbg(&(pcr->pci->dev), "Timeout (%s %d)\n", + __func__, __LINE__); + err = -ETIMEDOUT; + goto finish_send_cmd; + } + + spin_lock_irqsave(&pcr->lock, flags); + if (pcr->trans_result == TRANS_RESULT_FAIL) + err = -EINVAL; + else if (pcr->trans_result == TRANS_RESULT_OK) + err = 0; + else if (pcr->trans_result == TRANS_NO_DEVICE) + err = -ENODEV; + spin_unlock_irqrestore(&pcr->lock, flags); + +finish_send_cmd: + spin_lock_irqsave(&pcr->lock, flags); + pcr->done = NULL; + spin_unlock_irqrestore(&pcr->lock, flags); + + if ((err < 0) && (err != -ENODEV)) + rtsx_pci_stop_cmd(pcr); + + if (pcr->finish_me) + complete(pcr->finish_me); + + return err; +} +EXPORT_SYMBOL_GPL(rtsx_pci_send_cmd); + +static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr, + dma_addr_t addr, unsigned int len, int end) +{ + u64 *ptr = (u64 *)(pcr->host_sg_tbl_ptr) + pcr->sgi; + u64 val; + u8 option = SG_VALID | SG_TRANS_DATA; + + dev_dbg(&(pcr->pci->dev), "DMA addr: 0x%x, Len: 0x%x\n", + (unsigned int)addr, len); + + if (end) + option |= SG_END; + val = ((u64)addr << 32) | ((u64)len << 12) | option; + + put_unaligned_le64(val, ptr); + ptr++; + pcr->sgi++; +} + +int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, + int num_sg, bool read, int timeout) +{ + struct completion trans_done; + u8 dir; + int err = 0, i, count; + long timeleft; + unsigned long flags; + struct scatterlist *sg; + enum dma_data_direction dma_dir; + u32 val; + dma_addr_t addr; + unsigned int len; + + dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg); + + /* don't transfer data during abort processing */ + if (pcr->remove_pci) + return -EINVAL; + + if ((sglist == NULL) || (num_sg <= 0)) + return -EINVAL; + + if (read) { + dir = DEVICE_TO_HOST; + dma_dir = DMA_FROM_DEVICE; + } else { + dir = HOST_TO_DEVICE; + dma_dir = DMA_TO_DEVICE; + } + + count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); + if (count < 1) { + dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); + return -EINVAL; + } + dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); + + val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; + pcr->sgi = 0; + for_each_sg(sglist, sg, count, i) { + addr = sg_dma_address(sg); + len = sg_dma_len(sg); + rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1); + } + + spin_lock_irqsave(&pcr->lock, flags); + + pcr->done = &trans_done; + pcr->trans_result = TRANS_NOT_READY; + init_completion(&trans_done); + rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr); + rtsx_pci_writel(pcr, RTSX_HDBCTLR, val); + + spin_unlock_irqrestore(&pcr->lock, flags); + + timeleft = wait_for_completion_interruptible_timeout( + &trans_done, msecs_to_jiffies(timeout)); + if (timeleft <= 0) { + dev_dbg(&(pcr->pci->dev), "Timeout (%s %d)\n", + __func__, __LINE__); + err = -ETIMEDOUT; + goto out; + } + + spin_lock_irqsave(&pcr->lock, flags); + + if (pcr->trans_result == TRANS_RESULT_FAIL) + err = -EINVAL; + else if (pcr->trans_result == TRANS_NO_DEVICE) + err = -ENODEV; + + spin_unlock_irqrestore(&pcr->lock, flags); + +out: + spin_lock_irqsave(&pcr->lock, flags); + pcr->done = NULL; + spin_unlock_irqrestore(&pcr->lock, flags); + + dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); + + if ((err < 0) && (err != -ENODEV)) + rtsx_pci_stop_cmd(pcr); + + if (pcr->finish_me) + complete(pcr->finish_me); + + return err; +} +EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); + +int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) +{ + int err; + int i, j; + u16 reg; + u8 *ptr; + + if (buf_len > 512) + buf_len = 512; + + ptr = buf; + reg = PPBUF_BASE2; + for (i = 0; i < buf_len / 256; i++) { + rtsx_pci_init_cmd(pcr); + + for (j = 0; j < 256; j++) + rtsx_pci_add_cmd(pcr, READ_REG_CMD, reg++, 0, 0); + + err = rtsx_pci_send_cmd(pcr, 250); + if (err < 0) + return err; + + memcpy(ptr, rtsx_pci_get_cmd_data(pcr), 256); + ptr += 256; + } + + if (buf_len % 256) { + rtsx_pci_init_cmd(pcr); + + for (j = 0; j < buf_len % 256; j++) + rtsx_pci_add_cmd(pcr, READ_REG_CMD, reg++, 0, 0); + + err = rtsx_pci_send_cmd(pcr, 250); + if (err < 0) + return err; + } + + memcpy(ptr, rtsx_pci_get_cmd_data(pcr), buf_len % 256); + + return 0; +} +EXPORT_SYMBOL_GPL(rtsx_pci_read_ppbuf); + +int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) +{ + int err; + int i, j; + u16 reg; + u8 *ptr; + + if (buf_len > 512) + buf_len = 512; + + ptr = buf; + reg = PPBUF_BASE2; + for (i = 0; i < buf_len / 256; i++) { + rtsx_pci_init_cmd(pcr); + + for (j = 0; j < 256; j++) { + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, + reg++, 0xFF, *ptr); + ptr++; + } + + err = rtsx_pci_send_cmd(pcr, 250); + if (err < 0) + return err; + } + + if (buf_len % 256) { + rtsx_pci_init_cmd(pcr); + + for (j = 0; j < buf_len % 256; j++) { + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, + reg++, 0xFF, *ptr); + ptr++; + } + + err = rtsx_pci_send_cmd(pcr, 250); + if (err < 0) + return err; + } + + return 0; +} +EXPORT_SYMBOL_GPL(rtsx_pci_write_ppbuf); + +static int rtsx_pci_set_pull_ctl(struct rtsx_pcr *pcr, const u32 *tbl) +{ + int err; + + rtsx_pci_init_cmd(pcr); + + while (*tbl & 0xFFFF0000) { + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, + (u16)(*tbl >> 16), 0xFF, (u8)(*tbl)); + tbl++; + } + + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + return 0; +} + +int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card) +{ + const u32 *tbl; + + if (card == RTSX_SD_CARD) + tbl = pcr->sd_pull_ctl_enable_tbl; + else if (card == RTSX_MS_CARD) + tbl = pcr->ms_pull_ctl_enable_tbl; + else + return -EINVAL; + + return rtsx_pci_set_pull_ctl(pcr, tbl); +} +EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_enable); + +int rtsx_pci_card_pull_ctl_disable(struct rtsx_pcr *pcr, int card) +{ + const u32 *tbl; + + if (card == RTSX_SD_CARD) + tbl = pcr->sd_pull_ctl_disable_tbl; + else if (card == RTSX_MS_CARD) + tbl = pcr->ms_pull_ctl_disable_tbl; + else + return -EINVAL; + + + return rtsx_pci_set_pull_ctl(pcr, tbl); +} +EXPORT_SYMBOL_GPL(rtsx_pci_card_pull_ctl_disable); + +static void rtsx_pci_enable_bus_int(struct rtsx_pcr *pcr) +{ + pcr->bier = TRANS_OK_INT_EN | TRANS_FAIL_INT_EN | SD_INT_EN; + + if (pcr->num_slots > 1) + pcr->bier |= MS_INT_EN; + + /* Enable Bus Interrupt */ + rtsx_pci_writel(pcr, RTSX_BIER, pcr->bier); + + dev_dbg(&(pcr->pci->dev), "RTSX_BIER: 0x%08x\n", pcr->bier); +} + +static inline u8 double_ssc_depth(u8 depth) +{ + return ((depth > 1) ? (depth - 1) : depth); +} + +static u8 revise_ssc_depth(u8 ssc_depth, u8 div) +{ + if (div > CLK_DIV_1) { + if (ssc_depth > (div - 1)) + ssc_depth -= (div - 1); + else + ssc_depth = SSC_DEPTH_4M; + } + + return ssc_depth; +} + +int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, + u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk) +{ + int err, clk; + u8 N, min_N, max_N, clk_divider; + u8 mcu_cnt, div, max_div; + u8 depth[] = { + [RTSX_SSC_DEPTH_4M] = SSC_DEPTH_4M, + [RTSX_SSC_DEPTH_2M] = SSC_DEPTH_2M, + [RTSX_SSC_DEPTH_1M] = SSC_DEPTH_1M, + [RTSX_SSC_DEPTH_500K] = SSC_DEPTH_500K, + [RTSX_SSC_DEPTH_250K] = SSC_DEPTH_250K, + }; + + if (initial_mode) { + /* We use 250k(around) here, in initial stage */ + clk_divider = SD_CLK_DIVIDE_128; + card_clock = 30000000; + } else { + clk_divider = SD_CLK_DIVIDE_0; + } + err = rtsx_pci_write_register(pcr, SD_CFG1, + SD_CLK_DIVIDE_MASK, clk_divider); + if (err < 0) + return err; + + card_clock /= 1000000; + dev_dbg(&(pcr->pci->dev), "Switch card clock to %dMHz\n", card_clock); + + min_N = 80; + max_N = 208; + max_div = CLK_DIV_8; + + clk = card_clock; + if (!initial_mode && double_clk) + clk = card_clock * 2; + dev_dbg(&(pcr->pci->dev), + "Internal SSC clock: %dMHz (cur_clock = %d)\n", + clk, pcr->cur_clock); + + if (clk == pcr->cur_clock) + return 0; + + N = (u8)(clk - 2); + if ((clk <= 2) || (N > max_N)) + return -EINVAL; + + mcu_cnt = (u8)(125/clk + 3); + if (mcu_cnt > 15) + mcu_cnt = 15; + + /* Make sure that the SSC clock div_n is equal or greater than min_N */ + div = CLK_DIV_1; + while ((N < min_N) && (div < max_div)) { + N = (N + 2) * 2 - 2; + div++; + } + dev_dbg(&(pcr->pci->dev), "N = %d, div = %d\n", N, div); + + ssc_depth = depth[ssc_depth]; + if (double_clk) + ssc_depth = double_ssc_depth(ssc_depth); + + ssc_depth = revise_ssc_depth(ssc_depth, div); + dev_dbg(&(pcr->pci->dev), "ssc_depth = %d\n", ssc_depth); + + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, + CLK_LOW_FREQ, CLK_LOW_FREQ); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_DIV, + 0xFF, (div << 4) | mcu_cnt); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, + SSC_DEPTH_MASK, ssc_depth); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); + if (vpclk) { + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, + PHASE_NOT_RESET, 0); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, + PHASE_NOT_RESET, PHASE_NOT_RESET); + } + + err = rtsx_pci_send_cmd(pcr, 2000); + if (err < 0) + return err; + + /* Wait SSC clock stable */ + udelay(10); + err = rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0); + if (err < 0) + return err; + + pcr->cur_clock = clk; + return 0; +} +EXPORT_SYMBOL_GPL(rtsx_pci_switch_clock); + +int rtsx_pci_card_power_on(struct rtsx_pcr *pcr, int card) +{ + if (pcr->ops->card_power_on) + return pcr->ops->card_power_on(pcr, card); + + return 0; +} +EXPORT_SYMBOL_GPL(rtsx_pci_card_power_on); + +int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card) +{ + if (pcr->ops->card_power_off) + return pcr->ops->card_power_off(pcr, card); + + return 0; +} +EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off); + +unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr) +{ + unsigned int val; + + val = rtsx_pci_readl(pcr, RTSX_BIPR); + if (pcr->ops->cd_deglitch) + val = pcr->ops->cd_deglitch(pcr); + + return val; +} +EXPORT_SYMBOL_GPL(rtsx_pci_card_exist); + +void rtsx_pci_complete_unfinished_transfer(struct rtsx_pcr *pcr) +{ + struct completion finish; + + pcr->finish_me = &finish; + init_completion(&finish); + + if (pcr->done) + complete(pcr->done); + + if (!pcr->remove_pci) + rtsx_pci_stop_cmd(pcr); + + wait_for_completion_interruptible_timeout(&finish, + msecs_to_jiffies(2)); + pcr->finish_me = NULL; +} +EXPORT_SYMBOL_GPL(rtsx_pci_complete_unfinished_transfer); + +static void rtsx_pci_card_detect(struct work_struct *work) +{ + struct delayed_work *dwork; + struct rtsx_pcr *pcr; + unsigned long flags; + unsigned int card_detect = 0; + u32 irq_status; + + dwork = to_delayed_work(work); + pcr = container_of(dwork, struct rtsx_pcr, carddet_work); + + dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__); + + spin_lock_irqsave(&pcr->lock, flags); + + irq_status = rtsx_pci_readl(pcr, RTSX_BIPR); + dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status); + + if (pcr->card_inserted || pcr->card_removed) { + dev_dbg(&(pcr->pci->dev), + "card_inserted: 0x%x, card_removed: 0x%x\n", + pcr->card_inserted, pcr->card_removed); + + if (pcr->ops->cd_deglitch) + pcr->card_inserted = pcr->ops->cd_deglitch(pcr); + + card_detect = pcr->card_inserted | pcr->card_removed; + pcr->card_inserted = 0; + pcr->card_removed = 0; + } + + spin_unlock_irqrestore(&pcr->lock, flags); + + if (card_detect & SD_EXIST) + pcr->slots[RTSX_SD_CARD].card_event( + pcr->slots[RTSX_SD_CARD].p_dev); + if (card_detect & MS_EXIST) + pcr->slots[RTSX_MS_CARD].card_event( + pcr->slots[RTSX_MS_CARD].p_dev); +} + +static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) +{ + struct rtsx_pcr *pcr = dev_id; + u32 int_reg; + + if (!pcr) + return IRQ_NONE; + + spin_lock(&pcr->lock); + + int_reg = rtsx_pci_readl(pcr, RTSX_BIPR); + /* Clear interrupt flag */ + rtsx_pci_writel(pcr, RTSX_BIPR, int_reg); + if ((int_reg & pcr->bier) == 0) { + spin_unlock(&pcr->lock); + return IRQ_NONE; + } + if (int_reg == 0xFFFFFFFF) { + spin_unlock(&pcr->lock); + return IRQ_HANDLED; + } + + int_reg &= (pcr->bier | 0x7FFFFF); + + if (int_reg & SD_INT) { + if (int_reg & SD_EXIST) { + pcr->card_inserted |= SD_EXIST; + } else { + pcr->card_removed |= SD_EXIST; + pcr->card_inserted &= ~SD_EXIST; + } + } + + if (int_reg & MS_INT) { + if (int_reg & MS_EXIST) { + pcr->card_inserted |= MS_EXIST; + } else { + pcr->card_removed |= MS_EXIST; + pcr->card_inserted &= ~MS_EXIST; + } + } + + if (pcr->card_inserted || pcr->card_removed) + schedule_delayed_work(&pcr->carddet_work, + msecs_to_jiffies(200)); + + if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { + if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) { + pcr->trans_result = TRANS_RESULT_FAIL; + if (pcr->done) + complete(pcr->done); + } else if (int_reg & TRANS_OK_INT) { + pcr->trans_result = TRANS_RESULT_OK; + if (pcr->done) + complete(pcr->done); + } + } + + spin_unlock(&pcr->lock); + return IRQ_HANDLED; +} + +static int rtsx_pci_acquire_irq(struct rtsx_pcr *pcr) +{ + dev_info(&(pcr->pci->dev), "%s: pcr->msi_en = %d, pci->irq = %d\n", + __func__, pcr->msi_en, pcr->pci->irq); + + if (request_irq(pcr->pci->irq, rtsx_pci_isr, + pcr->msi_en ? 0 : IRQF_SHARED, + DRV_NAME_RTSX_PCI, pcr)) { + dev_err(&(pcr->pci->dev), + "rtsx_sdmmc: unable to grab IRQ %d, disabling device\n", + pcr->pci->irq); + return -1; + } + + pcr->irq = pcr->pci->irq; + pci_intx(pcr->pci, !pcr->msi_en); + + return 0; +} + +static void rtsx_pci_idle_work(struct work_struct *work) +{ + struct delayed_work *dwork = to_delayed_work(work); + struct rtsx_pcr *pcr = container_of(dwork, struct rtsx_pcr, idle_work); + + dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__); + + mutex_lock(&pcr->pcr_mutex); + + pcr->state = PDEV_STAT_IDLE; + + if (pcr->ops->disable_auto_blink) + pcr->ops->disable_auto_blink(pcr); + if (pcr->ops->turn_off_led) + pcr->ops->turn_off_led(pcr); + + mutex_unlock(&pcr->pcr_mutex); +} + +static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) +{ + int err; + + rtsx_pci_writel(pcr, RTSX_HCBAR, pcr->host_cmds_addr); + + rtsx_pci_enable_bus_int(pcr); + + /* Power on SSC */ + err = rtsx_pci_write_register(pcr, FPDCTL, SSC_POWER_DOWN, 0); + if (err < 0) + return err; + + /* Wait SSC power stable */ + udelay(200); + + if (pcr->ops->optimize_phy) { + err = pcr->ops->optimize_phy(pcr); + if (err < 0) + return err; + } + + rtsx_pci_init_cmd(pcr); + + /* Set mcu_cnt to 7 to ensure data can be sampled properly */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_DIV, 0x07, 0x07); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, HOST_SLEEP_STATE, 0x03, 0x00); + /* Disable card clock */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, 0x1E, 0); + /* Reset ASPM state to default value */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0); + /* Reset delink mode */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x0A, 0); + /* Card driving select */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL, + 0x07, DRIVER_TYPE_D); + /* Enable SSC Clock */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL1, + 0xFF, SSC_8X_EN | SSC_SEL_4M); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SSC_CTL2, 0xFF, 0x12); + /* Disable cd_pwr_save */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CHANGE_LINK_STATE, 0x16, 0x10); + /* Clear Link Ready Interrupt */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, + LINK_RDY_INT, LINK_RDY_INT); + /* Enlarge the estimation window of PERST# glitch + * to reduce the chance of invalid card interrupt + */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PERST_GLITCH_WIDTH, 0xFF, 0x80); + /* Update RC oscillator to 400k + * bit[0] F_HIGH: for RC oscillator, Rst_value is 1'b1 + * 1: 2M 0: 400k + */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, RCCTL, 0x01, 0x00); + /* Set interrupt write clear + * bit 1: U_elbi_if_rd_clr_en + * 1: Enable ELBI interrupt[31:22] & [7:0] flag read clear + * 0: ELBI interrupt flag[31:22] & [7:0] only can be write clear + */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, NFTS_TX_CTRL, 0x02, 0); + /* Force CLKREQ# PIN to drive 0 to request clock */ + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x08, 0x08); + + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + /* Enable clk_request_n to enable clock power management */ + rtsx_pci_write_config_byte(pcr, 0x81, 1); + /* Enter L1 when host tx idle */ + rtsx_pci_write_config_byte(pcr, 0x70F, 0x5B); + + if (pcr->ops->extra_init_hw) { + err = pcr->ops->extra_init_hw(pcr); + if (err < 0) + return err; + } + + return 0; +} + +static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) +{ + int err; + + spin_lock_init(&pcr->lock); + mutex_init(&pcr->pcr_mutex); + + switch (PCI_PID(pcr)) { + default: + case 0x5209: + rts5209_init_params(pcr); + break; + + case 0x5229: + rts5229_init_params(pcr); + break; + + case 0x5289: + rtl8411_init_params(pcr); + break; + } + + dev_dbg(&(pcr->pci->dev), "PID: 0x%04x, IC version: 0x%02x\n", + PCI_PID(pcr), pcr->ic_version); + + pcr->slots = kcalloc(pcr->num_slots, sizeof(struct rtsx_slot), + GFP_KERNEL); + if (!pcr->slots) + return -ENOMEM; + + pcr->state = PDEV_STAT_IDLE; + err = rtsx_pci_init_hw(pcr); + if (err < 0) { + kfree(pcr->slots); + return err; + } + + return 0; +} + +static int __devinit rtsx_pci_probe(struct pci_dev *pcidev, + const struct pci_device_id *id) +{ + struct rtsx_pcr *pcr; + struct pcr_handle *handle; + u32 base, len; + int ret, i; + + dev_dbg(&(pcidev->dev), + ": Realtek PCI-E Card Reader found at %s [%04x:%04x] (rev %x)\n", + pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device, + (int)pcidev->revision); + + ret = pci_enable_device(pcidev); + if (ret) + return ret; + + ret = pci_request_regions(pcidev, DRV_NAME_RTSX_PCI); + if (ret) + goto disable; + + pcr = kzalloc(sizeof(*pcr), GFP_KERNEL); + if (!pcr) { + ret = -ENOMEM; + goto release_pci; + } + + handle = kzalloc(sizeof(*handle), GFP_KERNEL); + if (!handle) { + ret = -ENOMEM; + goto free_pcr; + } + handle->pcr = pcr; + + if (!idr_pre_get(&rtsx_pci_idr, GFP_KERNEL)) { + ret = -ENOMEM; + goto free_handle; + } + + spin_lock(&rtsx_pci_lock); + ret = idr_get_new(&rtsx_pci_idr, pcr, &pcr->id); + spin_unlock(&rtsx_pci_lock); + if (ret) + goto free_handle; + + pcr->pci = pcidev; + dev_set_drvdata(&pcidev->dev, handle); + + len = pci_resource_len(pcidev, 0); + base = pci_resource_start(pcidev, 0); + pcr->remap_addr = ioremap_nocache(base, len); + if (!pcr->remap_addr) { + ret = -ENOMEM; + goto free_host; + } + + pcr->rtsx_resv_buf = dma_alloc_coherent(&(pcidev->dev), + RTSX_RESV_BUF_LEN, &(pcr->rtsx_resv_buf_addr), + GFP_KERNEL); + if (pcr->rtsx_resv_buf == NULL) { + ret = -ENXIO; + goto unmap; + } + pcr->host_cmds_ptr = pcr->rtsx_resv_buf; + pcr->host_cmds_addr = pcr->rtsx_resv_buf_addr; + pcr->host_sg_tbl_ptr = pcr->rtsx_resv_buf + HOST_CMDS_BUF_LEN; + pcr->host_sg_tbl_addr = pcr->rtsx_resv_buf_addr + HOST_CMDS_BUF_LEN; + + pcr->card_inserted = 0; + pcr->card_removed = 0; + INIT_DELAYED_WORK(&pcr->carddet_work, rtsx_pci_card_detect); + INIT_DELAYED_WORK(&pcr->idle_work, rtsx_pci_idle_work); + + pcr->msi_en = msi_en; + if (pcr->msi_en) { + ret = pci_enable_msi(pcidev); + if (ret < 0) + pcr->msi_en = false; + } + + ret = rtsx_pci_acquire_irq(pcr); + if (ret < 0) + goto free_dma; + + pci_set_master(pcidev); + synchronize_irq(pcr->irq); + + ret = rtsx_pci_init_chip(pcr); + if (ret < 0) + goto disable_irq; + + for (i = 0; i < ARRAY_SIZE(rtsx_pcr_cells); i++) { + rtsx_pcr_cells[i].platform_data = handle; + rtsx_pcr_cells[i].pdata_size = sizeof(*handle); + } + ret = mfd_add_devices(&pcidev->dev, pcr->id, rtsx_pcr_cells, + ARRAY_SIZE(rtsx_pcr_cells), NULL, 0, NULL); + if (ret < 0) + goto disable_irq; + + schedule_delayed_work(&pcr->idle_work, msecs_to_jiffies(200)); + + return 0; + +disable_irq: + free_irq(pcr->irq, (void *)pcr); +free_dma: + dma_free_coherent(&(pcr->pci->dev), RTSX_RESV_BUF_LEN, + pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr); +unmap: + iounmap(pcr->remap_addr); +free_host: + dev_set_drvdata(&pcidev->dev, NULL); +free_handle: + kfree(handle); +free_pcr: + kfree(pcr); +release_pci: + pci_release_regions(pcidev); +disable: + pci_disable_device(pcidev); + + return ret; +} + +static void __devexit rtsx_pci_remove(struct pci_dev *pcidev) +{ + struct pcr_handle *handle = pci_get_drvdata(pcidev); + struct rtsx_pcr *pcr = handle->pcr; + + pcr->remove_pci = true; + + cancel_delayed_work(&pcr->carddet_work); + cancel_delayed_work(&pcr->idle_work); + + mfd_remove_devices(&pcidev->dev); + + dma_free_coherent(&(pcr->pci->dev), RTSX_RESV_BUF_LEN, + pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr); + free_irq(pcr->irq, (void *)pcr); + if (pcr->msi_en) + pci_disable_msi(pcr->pci); + iounmap(pcr->remap_addr); + + dev_set_drvdata(&pcidev->dev, NULL); + pci_release_regions(pcidev); + pci_disable_device(pcidev); + + spin_lock(&rtsx_pci_lock); + idr_remove(&rtsx_pci_idr, pcr->id); + spin_unlock(&rtsx_pci_lock); + + kfree(pcr->slots); + kfree(pcr); + kfree(handle); + + dev_dbg(&(pcidev->dev), + ": Realtek PCI-E Card Reader at %s [%04x:%04x] has been removed\n", + pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device); +} + +#ifdef CONFIG_PM + +static int rtsx_pci_suspend(struct pci_dev *pcidev, pm_message_t state) +{ + struct pcr_handle *handle; + struct rtsx_pcr *pcr; + int ret = 0; + + dev_dbg(&(pcidev->dev), "--> %s\n", __func__); + + handle = pci_get_drvdata(pcidev); + pcr = handle->pcr; + + cancel_delayed_work(&pcr->carddet_work); + cancel_delayed_work(&pcr->idle_work); + + mutex_lock(&pcr->pcr_mutex); + + if (pcr->ops->turn_off_led) + pcr->ops->turn_off_led(pcr); + + rtsx_pci_writel(pcr, RTSX_BIER, 0); + pcr->bier = 0; + + rtsx_pci_write_register(pcr, PETXCFG, 0x08, 0x08); + rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x02); + + pci_save_state(pcidev); + pci_enable_wake(pcidev, pci_choose_state(pcidev, state), 0); + pci_disable_device(pcidev); + pci_set_power_state(pcidev, pci_choose_state(pcidev, state)); + + mutex_unlock(&pcr->pcr_mutex); + return ret; +} + +static int rtsx_pci_resume(struct pci_dev *pcidev) +{ + struct pcr_handle *handle; + struct rtsx_pcr *pcr; + int ret = 0; + + dev_dbg(&(pcidev->dev), "--> %s\n", __func__); + + handle = pci_get_drvdata(pcidev); + pcr = handle->pcr; + + mutex_lock(&pcr->pcr_mutex); + + pci_set_power_state(pcidev, PCI_D0); + pci_restore_state(pcidev); + ret = pci_enable_device(pcidev); + if (ret) + goto out; + pci_set_master(pcidev); + + ret = rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x00); + if (ret) + goto out; + + ret = rtsx_pci_init_hw(pcr); + if (ret) + goto out; + + schedule_delayed_work(&pcr->idle_work, msecs_to_jiffies(200)); + +out: + mutex_unlock(&pcr->pcr_mutex); + return ret; +} + +#else /* CONFIG_PM */ + +#define rtsx_pci_suspend NULL +#define rtsx_pci_resume NULL + +#endif /* CONFIG_PM */ + +static struct pci_driver rtsx_pci_driver = { + .name = DRV_NAME_RTSX_PCI, + .id_table = rtsx_pci_ids, + .probe = rtsx_pci_probe, + .remove = __devexit_p(rtsx_pci_remove), + .suspend = rtsx_pci_suspend, + .resume = rtsx_pci_resume, +}; +module_pci_driver(rtsx_pci_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Wei WANG "); +MODULE_DESCRIPTION("Realtek PCI-E Card Reader Driver"); diff --git a/drivers/mfd/rtsx_pcr.h b/drivers/mfd/rtsx_pcr.h new file mode 100644 index 00000000000..12462c1df1a --- /dev/null +++ b/drivers/mfd/rtsx_pcr.h @@ -0,0 +1,32 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * 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, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * Wei WANG + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTSX_PCR_H +#define __RTSX_PCR_H + +#include + +void rts5209_init_params(struct rtsx_pcr *pcr); +void rts5229_init_params(struct rtsx_pcr *pcr); +void rtl8411_init_params(struct rtsx_pcr *pcr); + +#endif diff --git a/include/linux/mfd/rtsx_common.h b/include/linux/mfd/rtsx_common.h new file mode 100644 index 00000000000..a8d393e3066 --- /dev/null +++ b/include/linux/mfd/rtsx_common.h @@ -0,0 +1,48 @@ +/* Driver for Realtek driver-based card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * 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, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * Wei WANG + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTSX_COMMON_H +#define __RTSX_COMMON_H + +#define DRV_NAME_RTSX_PCI "rtsx_pci" +#define DRV_NAME_RTSX_PCI_SDMMC "rtsx_pci_sdmmc" +#define DRV_NAME_RTSX_PCI_MS "rtsx_pci_ms" + +#define RTSX_REG_PAIR(addr, val) (((u32)(addr) << 16) | (u8)(val)) + +#define RTSX_SSC_DEPTH_4M 0x01 +#define RTSX_SSC_DEPTH_2M 0x02 +#define RTSX_SSC_DEPTH_1M 0x03 +#define RTSX_SSC_DEPTH_500K 0x04 +#define RTSX_SSC_DEPTH_250K 0x05 + +#define RTSX_SD_CARD 0 +#define RTSX_MS_CARD 1 + +struct platform_device; + +struct rtsx_slot { + struct platform_device *p_dev; + void (*card_event)(struct platform_device *p_dev); +}; + +#endif diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h new file mode 100644 index 00000000000..060b721fcbf --- /dev/null +++ b/include/linux/mfd/rtsx_pci.h @@ -0,0 +1,794 @@ +/* Driver for Realtek PCI-Express card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * 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, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * Wei WANG + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTSX_PCI_H +#define __RTSX_PCI_H + +#include +#include + +#include "rtsx_common.h" + +#define MAX_RW_REG_CNT 1024 + +/* PCI Operation Register Address */ +#define RTSX_HCBAR 0x00 +#define RTSX_HCBCTLR 0x04 +#define RTSX_HDBAR 0x08 +#define RTSX_HDBCTLR 0x0C +#define RTSX_HAIMR 0x10 +#define RTSX_BIPR 0x14 +#define RTSX_BIER 0x18 + +/* Host command buffer control register */ +#define STOP_CMD (0x01 << 28) + +/* Host data buffer control register */ +#define SDMA_MODE 0x00 +#define ADMA_MODE (0x02 << 26) +#define STOP_DMA (0x01 << 28) +#define TRIG_DMA (0x01 << 31) + +/* Host access internal memory register */ +#define HAIMR_TRANS_START (0x01 << 31) +#define HAIMR_READ 0x00 +#define HAIMR_WRITE (0x01 << 30) +#define HAIMR_READ_START (HAIMR_TRANS_START | HAIMR_READ) +#define HAIMR_WRITE_START (HAIMR_TRANS_START | HAIMR_WRITE) +#define HAIMR_TRANS_END (HAIMR_TRANS_START) + +/* Bus interrupt pending register */ +#define CMD_DONE_INT (1 << 31) +#define DATA_DONE_INT (1 << 30) +#define TRANS_OK_INT (1 << 29) +#define TRANS_FAIL_INT (1 << 28) +#define XD_INT (1 << 27) +#define MS_INT (1 << 26) +#define SD_INT (1 << 25) +#define GPIO0_INT (1 << 24) +#define OC_INT (1 << 23) +#define SD_WRITE_PROTECT (1 << 19) +#define XD_EXIST (1 << 18) +#define MS_EXIST (1 << 17) +#define SD_EXIST (1 << 16) +#define DELINK_INT GPIO0_INT +#define MS_OC_INT (1 << 23) +#define SD_OC_INT (1 << 22) + +#define CARD_INT (XD_INT | MS_INT | SD_INT) +#define NEED_COMPLETE_INT (DATA_DONE_INT | TRANS_OK_INT | TRANS_FAIL_INT) +#define RTSX_INT (CMD_DONE_INT | NEED_COMPLETE_INT | \ + CARD_INT | GPIO0_INT | OC_INT) + +#define CARD_EXIST (XD_EXIST | MS_EXIST | SD_EXIST) + +/* Bus interrupt enable register */ +#define CMD_DONE_INT_EN (1 << 31) +#define DATA_DONE_INT_EN (1 << 30) +#define TRANS_OK_INT_EN (1 << 29) +#define TRANS_FAIL_INT_EN (1 << 28) +#define XD_INT_EN (1 << 27) +#define MS_INT_EN (1 << 26) +#define SD_INT_EN (1 << 25) +#define GPIO0_INT_EN (1 << 24) +#define OC_INT_EN (1 << 23) +#define DELINK_INT_EN GPIO0_INT_EN +#define MS_OC_INT_EN (1 << 23) +#define SD_OC_INT_EN (1 << 22) + +#define READ_REG_CMD 0 +#define WRITE_REG_CMD 1 +#define CHECK_REG_CMD 2 + +/* + * macros for easy use + */ +#define rtsx_pci_writel(pcr, reg, value) \ + iowrite32(value, (pcr)->remap_addr + reg) +#define rtsx_pci_readl(pcr, reg) \ + ioread32((pcr)->remap_addr + reg) +#define rtsx_pci_writew(pcr, reg, value) \ + iowrite16(value, (pcr)->remap_addr + reg) +#define rtsx_pci_readw(pcr, reg) \ + ioread16((pcr)->remap_addr + reg) +#define rtsx_pci_writeb(pcr, reg, value) \ + iowrite8(value, (pcr)->remap_addr + reg) +#define rtsx_pci_readb(pcr, reg) \ + ioread8((pcr)->remap_addr + reg) + +#define rtsx_pci_read_config_byte(pcr, where, val) \ + pci_read_config_byte((pcr)->pci, where, val) + +#define rtsx_pci_write_config_byte(pcr, where, val) \ + pci_write_config_byte((pcr)->pci, where, val) + +#define rtsx_pci_read_config_dword(pcr, where, val) \ + pci_read_config_dword((pcr)->pci, where, val) + +#define rtsx_pci_write_config_dword(pcr, where, val) \ + pci_write_config_dword((pcr)->pci, where, val) + +#define STATE_TRANS_NONE 0 +#define STATE_TRANS_CMD 1 +#define STATE_TRANS_BUF 2 +#define STATE_TRANS_SG 3 + +#define TRANS_NOT_READY 0 +#define TRANS_RESULT_OK 1 +#define TRANS_RESULT_FAIL 2 +#define TRANS_NO_DEVICE 3 + +#define RTSX_RESV_BUF_LEN 4096 +#define HOST_CMDS_BUF_LEN 1024 +#define HOST_SG_TBL_BUF_LEN (RTSX_RESV_BUF_LEN - HOST_CMDS_BUF_LEN) +#define HOST_SG_TBL_ITEMS (HOST_SG_TBL_BUF_LEN / 8) +#define MAX_SG_ITEM_LEN 0x80000 + +#define HOST_TO_DEVICE 0 +#define DEVICE_TO_HOST 1 + +#define MAX_PHASE 31 +#define RX_TUNING_CNT 3 + +/* SG descriptor */ +#define SG_INT 0x04 +#define SG_END 0x02 +#define SG_VALID 0x01 + +#define SG_NO_OP 0x00 +#define SG_TRANS_DATA (0x02 << 4) +#define SG_LINK_DESC (0x03 << 4) + +/* SD bank voltage */ +#define SD_IO_3V3 0 +#define SD_IO_1V8 1 + + +/* Card Clock Enable Register */ +#define SD_CLK_EN 0x04 +#define MS_CLK_EN 0x08 + +/* Card Select Register */ +#define SD_MOD_SEL 2 +#define MS_MOD_SEL 3 + +/* Card Output Enable Register */ +#define SD_OUTPUT_EN 0x04 +#define MS_OUTPUT_EN 0x08 + +/* CARD_SHARE_MODE */ +#define CARD_SHARE_MASK 0x0F +#define CARD_SHARE_MULTI_LUN 0x00 +#define CARD_SHARE_NORMAL 0x00 +#define CARD_SHARE_48_SD 0x04 +#define CARD_SHARE_48_MS 0x08 +/* CARD_SHARE_MODE for barossa */ +#define CARD_SHARE_BAROSSA_SD 0x01 +#define CARD_SHARE_BAROSSA_MS 0x02 + +/* SD30_DRIVE_SEL */ +#define DRIVER_TYPE_A 0x05 +#define DRIVER_TYPE_B 0x03 +#define DRIVER_TYPE_C 0x02 +#define DRIVER_TYPE_D 0x01 + +/* FPDCTL */ +#define SSC_POWER_DOWN 0x01 +#define SD_OC_POWER_DOWN 0x02 +#define ALL_POWER_DOWN 0x07 +#define OC_POWER_DOWN 0x06 + +/* CLK_CTL */ +#define CHANGE_CLK 0x01 + +/* LDO_CTL */ +#define BPP_LDO_POWB 0x03 +#define BPP_LDO_ON 0x00 +#define BPP_LDO_SUSPEND 0x02 +#define BPP_LDO_OFF 0x03 + +/* CD_PAD_CTL */ +#define CD_DISABLE_MASK 0x07 +#define MS_CD_DISABLE 0x04 +#define SD_CD_DISABLE 0x02 +#define XD_CD_DISABLE 0x01 +#define CD_DISABLE 0x07 +#define CD_ENABLE 0x00 +#define MS_CD_EN_ONLY 0x03 +#define SD_CD_EN_ONLY 0x05 +#define XD_CD_EN_ONLY 0x06 +#define FORCE_CD_LOW_MASK 0x38 +#define FORCE_CD_XD_LOW 0x08 +#define FORCE_CD_SD_LOW 0x10 +#define FORCE_CD_MS_LOW 0x20 +#define CD_AUTO_DISABLE 0x40 + +/* SD_STAT1 */ +#define SD_CRC7_ERR 0x80 +#define SD_CRC16_ERR 0x40 +#define SD_CRC_WRITE_ERR 0x20 +#define SD_CRC_WRITE_ERR_MASK 0x1C +#define GET_CRC_TIME_OUT 0x02 +#define SD_TUNING_COMPARE_ERR 0x01 + +/* SD_STAT2 */ +#define SD_RSP_80CLK_TIMEOUT 0x01 + +/* SD_BUS_STAT */ +#define SD_CLK_TOGGLE_EN 0x80 +#define SD_CLK_FORCE_STOP 0x40 +#define SD_DAT3_STATUS 0x10 +#define SD_DAT2_STATUS 0x08 +#define SD_DAT1_STATUS 0x04 +#define SD_DAT0_STATUS 0x02 +#define SD_CMD_STATUS 0x01 + +/* SD_PAD_CTL */ +#define SD_IO_USING_1V8 0x80 +#define SD_IO_USING_3V3 0x7F +#define TYPE_A_DRIVING 0x00 +#define TYPE_B_DRIVING 0x01 +#define TYPE_C_DRIVING 0x02 +#define TYPE_D_DRIVING 0x03 + +/* SD_SAMPLE_POINT_CTL */ +#define DDR_FIX_RX_DAT 0x00 +#define DDR_VAR_RX_DAT 0x80 +#define DDR_FIX_RX_DAT_EDGE 0x00 +#define DDR_FIX_RX_DAT_14_DELAY 0x40 +#define DDR_FIX_RX_CMD 0x00 +#define DDR_VAR_RX_CMD 0x20 +#define DDR_FIX_RX_CMD_POS_EDGE 0x00 +#define DDR_FIX_RX_CMD_14_DELAY 0x10 +#define SD20_RX_POS_EDGE 0x00 +#define SD20_RX_14_DELAY 0x08 +#define SD20_RX_SEL_MASK 0x08 + +/* SD_PUSH_POINT_CTL */ +#define DDR_FIX_TX_CMD_DAT 0x00 +#define DDR_VAR_TX_CMD_DAT 0x80 +#define DDR_FIX_TX_DAT_14_TSU 0x00 +#define DDR_FIX_TX_DAT_12_TSU 0x40 +#define DDR_FIX_TX_CMD_NEG_EDGE 0x00 +#define DDR_FIX_TX_CMD_14_AHEAD 0x20 +#define SD20_TX_NEG_EDGE 0x00 +#define SD20_TX_14_AHEAD 0x10 +#define SD20_TX_SEL_MASK 0x10 +#define DDR_VAR_SDCLK_POL_SWAP 0x01 + +/* SD_TRANSFER */ +#define SD_TRANSFER_START 0x80 +#define SD_TRANSFER_END 0x40 +#define SD_STAT_IDLE 0x20 +#define SD_TRANSFER_ERR 0x10 +/* SD Transfer Mode definition */ +#define SD_TM_NORMAL_WRITE 0x00 +#define SD_TM_AUTO_WRITE_3 0x01 +#define SD_TM_AUTO_WRITE_4 0x02 +#define SD_TM_AUTO_READ_3 0x05 +#define SD_TM_AUTO_READ_4 0x06 +#define SD_TM_CMD_RSP 0x08 +#define SD_TM_AUTO_WRITE_1 0x09 +#define SD_TM_AUTO_WRITE_2 0x0A +#define SD_TM_NORMAL_READ 0x0C +#define SD_TM_AUTO_READ_1 0x0D +#define SD_TM_AUTO_READ_2 0x0E +#define SD_TM_AUTO_TUNING 0x0F + +/* SD_VPTX_CTL / SD_VPRX_CTL */ +#define PHASE_CHANGE 0x80 +#define PHASE_NOT_RESET 0x40 + +/* SD_DCMPS_TX_CTL / SD_DCMPS_RX_CTL */ +#define DCMPS_CHANGE 0x80 +#define DCMPS_CHANGE_DONE 0x40 +#define DCMPS_ERROR 0x20 +#define DCMPS_CURRENT_PHASE 0x1F + +/* SD Configure 1 Register */ +#define SD_CLK_DIVIDE_0 0x00 +#define SD_CLK_DIVIDE_256 0xC0 +#define SD_CLK_DIVIDE_128 0x80 +#define SD_BUS_WIDTH_1BIT 0x00 +#define SD_BUS_WIDTH_4BIT 0x01 +#define SD_BUS_WIDTH_8BIT 0x02 +#define SD_ASYNC_FIFO_NOT_RST 0x10 +#define SD_20_MODE 0x00 +#define SD_DDR_MODE 0x04 +#define SD_30_MODE 0x08 + +#define SD_CLK_DIVIDE_MASK 0xC0 + +/* SD_CMD_STATE */ +#define SD_CMD_IDLE 0x80 + +/* SD_DATA_STATE */ +#define SD_DATA_IDLE 0x80 + +/* DCM_DRP_CTL */ +#define DCM_RESET 0x08 +#define DCM_LOCKED 0x04 +#define DCM_208M 0x00 +#define DCM_TX 0x01 +#define DCM_RX 0x02 + +/* DCM_DRP_TRIG */ +#define DRP_START 0x80 +#define DRP_DONE 0x40 + +/* DCM_DRP_CFG */ +#define DRP_WRITE 0x80 +#define DRP_READ 0x00 +#define DCM_WRITE_ADDRESS_50 0x50 +#define DCM_WRITE_ADDRESS_51 0x51 +#define DCM_READ_ADDRESS_00 0x00 +#define DCM_READ_ADDRESS_51 0x51 + +/* IRQSTAT0 */ +#define DMA_DONE_INT 0x80 +#define SUSPEND_INT 0x40 +#define LINK_RDY_INT 0x20 +#define LINK_DOWN_INT 0x10 + +/* DMACTL */ +#define DMA_RST 0x80 +#define DMA_BUSY 0x04 +#define DMA_DIR_TO_CARD 0x00 +#define DMA_DIR_FROM_CARD 0x02 +#define DMA_EN 0x01 +#define DMA_128 (0 << 4) +#define DMA_256 (1 << 4) +#define DMA_512 (2 << 4) +#define DMA_1024 (3 << 4) +#define DMA_PACK_SIZE_MASK 0x30 + +/* SSC_CTL1 */ +#define SSC_RSTB 0x80 +#define SSC_8X_EN 0x40 +#define SSC_FIX_FRAC 0x20 +#define SSC_SEL_1M 0x00 +#define SSC_SEL_2M 0x08 +#define SSC_SEL_4M 0x10 +#define SSC_SEL_8M 0x18 + +/* SSC_CTL2 */ +#define SSC_DEPTH_MASK 0x07 +#define SSC_DEPTH_DISALBE 0x00 +#define SSC_DEPTH_4M 0x01 +#define SSC_DEPTH_2M 0x02 +#define SSC_DEPTH_1M 0x03 +#define SSC_DEPTH_500K 0x04 +#define SSC_DEPTH_250K 0x05 + +/* System Clock Control Register */ +#define CLK_LOW_FREQ 0x01 + +/* System Clock Divider Register */ +#define CLK_DIV_1 0x01 +#define CLK_DIV_2 0x02 +#define CLK_DIV_4 0x03 +#define CLK_DIV_8 0x04 + +/* MS_CFG */ +#define SAMPLE_TIME_RISING 0x00 +#define SAMPLE_TIME_FALLING 0x80 +#define PUSH_TIME_DEFAULT 0x00 +#define PUSH_TIME_ODD 0x40 +#define NO_EXTEND_TOGGLE 0x00 +#define EXTEND_TOGGLE_CHK 0x20 +#define MS_BUS_WIDTH_1 0x00 +#define MS_BUS_WIDTH_4 0x10 +#define MS_BUS_WIDTH_8 0x18 +#define MS_2K_SECTOR_MODE 0x04 +#define MS_512_SECTOR_MODE 0x00 +#define MS_TOGGLE_TIMEOUT_EN 0x00 +#define MS_TOGGLE_TIMEOUT_DISEN 0x01 +#define MS_NO_CHECK_INT 0x02 + +/* MS_TRANS_CFG */ +#define WAIT_INT 0x80 +#define NO_WAIT_INT 0x00 +#define NO_AUTO_READ_INT_REG 0x00 +#define AUTO_READ_INT_REG 0x40 +#define MS_CRC16_ERR 0x20 +#define MS_RDY_TIMEOUT 0x10 +#define MS_INT_CMDNK 0x08 +#define MS_INT_BREQ 0x04 +#define MS_INT_ERR 0x02 +#define MS_INT_CED 0x01 + +/* MS_TRANSFER */ +#define MS_TRANSFER_START 0x80 +#define MS_TRANSFER_END 0x40 +#define MS_TRANSFER_ERR 0x20 +#define MS_BS_STATE 0x10 +#define MS_TM_READ_BYTES 0x00 +#define MS_TM_NORMAL_READ 0x01 +#define MS_TM_WRITE_BYTES 0x04 +#define MS_TM_NORMAL_WRITE 0x05 +#define MS_TM_AUTO_READ 0x08 +#define MS_TM_AUTO_WRITE 0x0C + +/* SD Configure 2 Register */ +#define SD_CALCULATE_CRC7 0x00 +#define SD_NO_CALCULATE_CRC7 0x80 +#define SD_CHECK_CRC16 0x00 +#define SD_NO_CHECK_CRC16 0x40 +#define SD_NO_CHECK_WAIT_CRC_TO 0x20 +#define SD_WAIT_BUSY_END 0x08 +#define SD_NO_WAIT_BUSY_END 0x00 +#define SD_CHECK_CRC7 0x00 +#define SD_NO_CHECK_CRC7 0x04 +#define SD_RSP_LEN_0 0x00 +#define SD_RSP_LEN_6 0x01 +#define SD_RSP_LEN_17 0x02 +/* SD/MMC Response Type Definition */ +#define SD_RSP_TYPE_R0 0x04 +#define SD_RSP_TYPE_R1 0x01 +#define SD_RSP_TYPE_R1b 0x09 +#define SD_RSP_TYPE_R2 0x02 +#define SD_RSP_TYPE_R3 0x05 +#define SD_RSP_TYPE_R4 0x05 +#define SD_RSP_TYPE_R5 0x01 +#define SD_RSP_TYPE_R6 0x01 +#define SD_RSP_TYPE_R7 0x01 + +/* SD_CONFIURE3 */ +#define SD_RSP_80CLK_TIMEOUT_EN 0x01 + +/* Card Transfer Reset Register */ +#define SPI_STOP 0x01 +#define XD_STOP 0x02 +#define SD_STOP 0x04 +#define MS_STOP 0x08 +#define SPI_CLR_ERR 0x10 +#define XD_CLR_ERR 0x20 +#define SD_CLR_ERR 0x40 +#define MS_CLR_ERR 0x80 + +/* Card Data Source Register */ +#define PINGPONG_BUFFER 0x01 +#define RING_BUFFER 0x00 + +/* Card Power Control Register */ +#define PMOS_STRG_MASK 0x10 +#define PMOS_STRG_800mA 0x10 +#define PMOS_STRG_400mA 0x00 +#define SD_POWER_OFF 0x03 +#define SD_PARTIAL_POWER_ON 0x01 +#define SD_POWER_ON 0x00 +#define SD_POWER_MASK 0x03 +#define MS_POWER_OFF 0x0C +#define MS_PARTIAL_POWER_ON 0x04 +#define MS_POWER_ON 0x00 +#define MS_POWER_MASK 0x0C +#define BPP_POWER_OFF 0x0F +#define BPP_POWER_5_PERCENT_ON 0x0E +#define BPP_POWER_10_PERCENT_ON 0x0C +#define BPP_POWER_15_PERCENT_ON 0x08 +#define BPP_POWER_ON 0x00 +#define BPP_POWER_MASK 0x0F + +/* PWR_GATE_CTRL */ +#define PWR_GATE_EN 0x01 +#define LDO3318_PWR_MASK 0x06 +#define LDO_ON 0x00 +#define LDO_SUSPEND 0x04 +#define LDO_OFF 0x06 + +/* CARD_CLK_SOURCE */ +#define CRC_FIX_CLK (0x00 << 0) +#define CRC_VAR_CLK0 (0x01 << 0) +#define CRC_VAR_CLK1 (0x02 << 0) +#define SD30_FIX_CLK (0x00 << 2) +#define SD30_VAR_CLK0 (0x01 << 2) +#define SD30_VAR_CLK1 (0x02 << 2) +#define SAMPLE_FIX_CLK (0x00 << 4) +#define SAMPLE_VAR_CLK0 (0x01 << 4) +#define SAMPLE_VAR_CLK1 (0x02 << 4) + +#define MS_CFG 0xFD40 +#define MS_TPC 0xFD41 +#define MS_TRANS_CFG 0xFD42 +#define MS_TRANSFER 0xFD43 +#define MS_INT_REG 0xFD44 +#define MS_BYTE_CNT 0xFD45 +#define MS_SECTOR_CNT_L 0xFD46 +#define MS_SECTOR_CNT_H 0xFD47 +#define MS_DBUS_H 0xFD48 + +#define SD_CFG1 0xFDA0 +#define SD_CFG2 0xFDA1 +#define SD_CFG3 0xFDA2 +#define SD_STAT1 0xFDA3 +#define SD_STAT2 0xFDA4 +#define SD_BUS_STAT 0xFDA5 +#define SD_PAD_CTL 0xFDA6 +#define SD_SAMPLE_POINT_CTL 0xFDA7 +#define SD_PUSH_POINT_CTL 0xFDA8 +#define SD_CMD0 0xFDA9 +#define SD_CMD1 0xFDAA +#define SD_CMD2 0xFDAB +#define SD_CMD3 0xFDAC +#define SD_CMD4 0xFDAD +#define SD_CMD5 0xFDAE +#define SD_BYTE_CNT_L 0xFDAF +#define SD_BYTE_CNT_H 0xFDB0 +#define SD_BLOCK_CNT_L 0xFDB1 +#define SD_BLOCK_CNT_H 0xFDB2 +#define SD_TRANSFER 0xFDB3 +#define SD_CMD_STATE 0xFDB5 +#define SD_DATA_STATE 0xFDB6 + +#define SRCTL 0xFC13 + +#define DCM_DRP_CTL 0xFC23 +#define DCM_DRP_TRIG 0xFC24 +#define DCM_DRP_CFG 0xFC25 +#define DCM_DRP_WR_DATA_L 0xFC26 +#define DCM_DRP_WR_DATA_H 0xFC27 +#define DCM_DRP_RD_DATA_L 0xFC28 +#define DCM_DRP_RD_DATA_H 0xFC29 +#define SD_VPCLK0_CTL 0xFC2A +#define SD_VPCLK1_CTL 0xFC2B +#define SD_DCMPS0_CTL 0xFC2C +#define SD_DCMPS1_CTL 0xFC2D +#define SD_VPTX_CTL SD_VPCLK0_CTL +#define SD_VPRX_CTL SD_VPCLK1_CTL +#define SD_DCMPS_TX_CTL SD_DCMPS0_CTL +#define SD_DCMPS_RX_CTL SD_DCMPS1_CTL +#define CARD_CLK_SOURCE 0xFC2E + +#define CARD_PWR_CTL 0xFD50 +#define CARD_CLK_SWITCH 0xFD51 +#define CARD_SHARE_MODE 0xFD52 +#define CARD_DRIVE_SEL 0xFD53 +#define CARD_STOP 0xFD54 +#define CARD_OE 0xFD55 +#define CARD_AUTO_BLINK 0xFD56 +#define CARD_GPIO_DIR 0xFD57 +#define CARD_GPIO 0xFD58 +#define CARD_DATA_SOURCE 0xFD5B +#define CARD_SELECT 0xFD5C +#define SD30_DRIVE_SEL 0xFD5E +#define CARD_CLK_EN 0xFD69 +#define SDIO_CTRL 0xFD6B +#define CD_PAD_CTL 0xFD73 + +#define FPDCTL 0xFC00 +#define PDINFO 0xFC01 + +#define CLK_CTL 0xFC02 +#define CLK_DIV 0xFC03 +#define CLK_SEL 0xFC04 + +#define SSC_DIV_N_0 0xFC0F +#define SSC_DIV_N_1 0xFC10 +#define SSC_CTL1 0xFC11 +#define SSC_CTL2 0xFC12 + +#define RCCTL 0xFC14 + +#define FPGA_PULL_CTL 0xFC1D +#define OLT_LED_CTL 0xFC1E +#define GPIO_CTL 0xFC1F + +#define LDO_CTL 0xFC1E +#define SYS_VER 0xFC32 + +#define CARD_PULL_CTL1 0xFD60 +#define CARD_PULL_CTL2 0xFD61 +#define CARD_PULL_CTL3 0xFD62 +#define CARD_PULL_CTL4 0xFD63 +#define CARD_PULL_CTL5 0xFD64 +#define CARD_PULL_CTL6 0xFD65 + +/* PCI Express Related Registers */ +#define IRQEN0 0xFE20 +#define IRQSTAT0 0xFE21 +#define IRQEN1 0xFE22 +#define IRQSTAT1 0xFE23 +#define TLPRIEN 0xFE24 +#define TLPRISTAT 0xFE25 +#define TLPTIEN 0xFE26 +#define TLPTISTAT 0xFE27 +#define DMATC0 0xFE28 +#define DMATC1 0xFE29 +#define DMATC2 0xFE2A +#define DMATC3 0xFE2B +#define DMACTL 0xFE2C +#define BCTL 0xFE2D +#define RBBC0 0xFE2E +#define RBBC1 0xFE2F +#define RBDAT 0xFE30 +#define RBCTL 0xFE34 +#define CFGADDR0 0xFE35 +#define CFGADDR1 0xFE36 +#define CFGDATA0 0xFE37 +#define CFGDATA1 0xFE38 +#define CFGDATA2 0xFE39 +#define CFGDATA3 0xFE3A +#define CFGRWCTL 0xFE3B +#define PHYRWCTL 0xFE3C +#define PHYDATA0 0xFE3D +#define PHYDATA1 0xFE3E +#define PHYADDR 0xFE3F +#define MSGRXDATA0 0xFE40 +#define MSGRXDATA1 0xFE41 +#define MSGRXDATA2 0xFE42 +#define MSGRXDATA3 0xFE43 +#define MSGTXDATA0 0xFE44 +#define MSGTXDATA1 0xFE45 +#define MSGTXDATA2 0xFE46 +#define MSGTXDATA3 0xFE47 +#define MSGTXCTL 0xFE48 +#define PETXCFG 0xFE49 + +#define CDRESUMECTL 0xFE52 +#define WAKE_SEL_CTL 0xFE54 +#define PME_FORCE_CTL 0xFE56 +#define ASPM_FORCE_CTL 0xFE57 +#define PM_CLK_FORCE_CTL 0xFE58 +#define PERST_GLITCH_WIDTH 0xFE5C +#define CHANGE_LINK_STATE 0xFE5B +#define RESET_LOAD_REG 0xFE5E +#define EFUSE_CONTENT 0xFE5F +#define HOST_SLEEP_STATE 0xFE60 +#define SDIO_CFG 0xFE70 + +#define NFTS_TX_CTRL 0xFE72 + +#define PWR_GATE_CTRL 0xFE75 +#define PWD_SUSPEND_EN 0xFE76 +#define LDO_PWR_SEL 0xFE78 + +#define DUMMY_REG_RESET_0 0xFE90 + +/* Memory mapping */ +#define SRAM_BASE 0xE600 +#define RBUF_BASE 0xF400 +#define PPBUF_BASE1 0xF800 +#define PPBUF_BASE2 0xFA00 +#define IMAGE_FLAG_ADDR0 0xCE80 +#define IMAGE_FLAG_ADDR1 0xCE81 + +#define rtsx_pci_init_cmd(pcr) ((pcr)->ci = 0) + +struct rtsx_pcr; + +struct pcr_handle { + struct rtsx_pcr *pcr; +}; + +struct pcr_ops { + int (*extra_init_hw)(struct rtsx_pcr *pcr); + int (*optimize_phy)(struct rtsx_pcr *pcr); + int (*turn_on_led)(struct rtsx_pcr *pcr); + int (*turn_off_led)(struct rtsx_pcr *pcr); + int (*enable_auto_blink)(struct rtsx_pcr *pcr); + int (*disable_auto_blink)(struct rtsx_pcr *pcr); + int (*card_power_on)(struct rtsx_pcr *pcr, int card); + int (*card_power_off)(struct rtsx_pcr *pcr, int card); + unsigned int (*cd_deglitch)(struct rtsx_pcr *pcr); +}; + +enum PDEV_STAT {PDEV_STAT_IDLE, PDEV_STAT_RUN}; + +struct rtsx_pcr { + struct pci_dev *pci; + unsigned int id; + + /* pci resources */ + unsigned long addr; + void __iomem *remap_addr; + int irq; + + /* host reserved buffer */ + void *rtsx_resv_buf; + dma_addr_t rtsx_resv_buf_addr; + + void *host_cmds_ptr; + dma_addr_t host_cmds_addr; + int ci; + + void *host_sg_tbl_ptr; + dma_addr_t host_sg_tbl_addr; + int sgi; + + u32 bier; + char trans_result; + + unsigned int card_inserted; + unsigned int card_removed; + + struct delayed_work carddet_work; + struct delayed_work idle_work; + + spinlock_t lock; + struct mutex pcr_mutex; + struct completion *done; + struct completion *finish_me; + + unsigned int cur_clock; + bool ms_pmos; + bool remove_pci; + bool msi_en; + +#define EXTRA_CAPS_SD_SDR50 (1 << 0) +#define EXTRA_CAPS_SD_SDR104 (1 << 1) +#define EXTRA_CAPS_SD_DDR50 (1 << 2) +#define EXTRA_CAPS_MMC_HSDDR (1 << 3) +#define EXTRA_CAPS_MMC_HS200 (1 << 4) +#define EXTRA_CAPS_MMC_8BIT (1 << 5) + u32 extra_caps; + +#define IC_VER_A 0 +#define IC_VER_B 1 +#define IC_VER_C 2 +#define IC_VER_D 3 + u8 ic_version; + + const u32 *sd_pull_ctl_enable_tbl; + const u32 *sd_pull_ctl_disable_tbl; + const u32 *ms_pull_ctl_enable_tbl; + const u32 *ms_pull_ctl_disable_tbl; + + const struct pcr_ops *ops; + enum PDEV_STAT state; + + int num_slots; + struct rtsx_slot *slots; +}; + +#define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid)) +#define PCI_VID(pcr) ((pcr)->pci->vendor) +#define PCI_PID(pcr) ((pcr)->pci->device) + +void rtsx_pci_start_run(struct rtsx_pcr *pcr); +int rtsx_pci_write_register(struct rtsx_pcr *pcr, u16 addr, u8 mask, u8 data); +int rtsx_pci_read_register(struct rtsx_pcr *pcr, u16 addr, u8 *data); +int rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val); +int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val); +void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr); +void rtsx_pci_add_cmd(struct rtsx_pcr *pcr, + u8 cmd_type, u16 reg_addr, u8 mask, u8 data); +void rtsx_pci_send_cmd_no_wait(struct rtsx_pcr *pcr); +int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout); +int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, + int num_sg, bool read, int timeout); +int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); +int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); +int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card); +int rtsx_pci_card_pull_ctl_disable(struct rtsx_pcr *pcr, int card); +int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, + u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk); +int rtsx_pci_card_power_on(struct rtsx_pcr *pcr, int card); +int rtsx_pci_card_power_off(struct rtsx_pcr *pcr, int card); +unsigned int rtsx_pci_card_exist(struct rtsx_pcr *pcr); +void rtsx_pci_complete_unfinished_transfer(struct rtsx_pcr *pcr); + +static inline u8 *rtsx_pci_get_cmd_data(struct rtsx_pcr *pcr) +{ + return (u8 *)(pcr->host_cmds_ptr); +} + +#endif -- cgit v1.2.3 From 2c94b6452cc6de582584f21066cc5e36d9530c59 Mon Sep 17 00:00:00 2001 From: Wei WANG Date: Fri, 9 Nov 2012 20:53:34 +0800 Subject: drivers/mmc: Add realtek pcie sdmmc host driver Realtek PCI-E SD/MMC card host driver is used to access SD/MMC card, with the help of Realtek PCI-E card reader MFD driver. Signed-off-by: Wei WANG Reviewed-by: Arnd Bergmann Tested-by: Borislav Petkov Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/host/Kconfig | 7 + drivers/mmc/host/Makefile | 2 + drivers/mmc/host/rtsx_pci_sdmmc.c | 1348 +++++++++++++++++++++++++++++++++++++ 3 files changed, 1357 insertions(+) create mode 100644 drivers/mmc/host/rtsx_pci_sdmmc.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 9bf10e7bbfa..dfa6d56ff0f 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -621,3 +621,10 @@ config MMC_USHC Note: These controllers only support SDIO cards and do not support MMC or SD memory cards. + +config MMC_REALTEK_PCI + tristate "Realtek PCI-E SD/MMC Card Interface Driver" + depends on MFD_RTSX_PCI + help + Say Y here to include driver code to support SD/MMC card interface + of Realtek PCI-E card reader diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index 17ad0a7ba40..8aa592d14c4 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -46,6 +46,8 @@ obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o obj-$(CONFIG_MMC_VUB300) += vub300.o obj-$(CONFIG_MMC_USHC) += ushc.o +obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o + obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c new file mode 100644 index 00000000000..12eff6f8cab --- /dev/null +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c @@ -0,0 +1,1348 @@ +/* Realtek PCI-Express SD/MMC Card Interface driver + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * 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, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * Wei WANG + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* SD Tuning Data Structure + * Record continuous timing phase path + */ +struct timing_phase_path { + int start; + int end; + int mid; + int len; +}; + +struct realtek_pci_sdmmc { + struct platform_device *pdev; + struct rtsx_pcr *pcr; + struct mmc_host *mmc; + struct mmc_request *mrq; + + struct mutex host_mutex; + + u8 ssc_depth; + unsigned int clock; + bool vpclk; + bool double_clk; + bool eject; + bool initial_mode; + bool ddr_mode; +}; + +static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host) +{ + return &(host->pdev->dev); +} + +static inline void sd_clear_error(struct realtek_pci_sdmmc *host) +{ + rtsx_pci_write_register(host->pcr, CARD_STOP, + SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR); +} + +#ifdef DEBUG +static void sd_print_debug_regs(struct realtek_pci_sdmmc *host) +{ + struct rtsx_pcr *pcr = host->pcr; + u16 i; + u8 *ptr; + + /* Print SD host internal registers */ + rtsx_pci_init_cmd(pcr); + for (i = 0xFDA0; i <= 0xFDAE; i++) + rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0); + for (i = 0xFD52; i <= 0xFD69; i++) + rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0); + rtsx_pci_send_cmd(pcr, 100); + + ptr = rtsx_pci_get_cmd_data(pcr); + for (i = 0xFDA0; i <= 0xFDAE; i++) + dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); + for (i = 0xFD52; i <= 0xFD69; i++) + dev_dbg(sdmmc_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); +} +#else +#define sd_print_debug_regs(host) +#endif /* DEBUG */ + +static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, + u8 *buf, int buf_len, int timeout) +{ + struct rtsx_pcr *pcr = host->pcr; + int err, i; + u8 trans_mode; + + dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD%d\n", __func__, cmd[0] - 0x40); + + if (!buf) + buf_len = 0; + + if ((cmd[0] & 0x3F) == MMC_SEND_TUNING_BLOCK) + trans_mode = SD_TM_AUTO_TUNING; + else + trans_mode = SD_TM_NORMAL_READ; + + rtsx_pci_init_cmd(pcr); + + for (i = 0; i < 5; i++) + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, cmd[i]); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, + 0xFF, (u8)(byte_cnt >> 8)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | + SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); + if (trans_mode != SD_TM_AUTO_TUNING) + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, + CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, + 0xFF, trans_mode | SD_TRANSFER_START); + rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + err = rtsx_pci_send_cmd(pcr, timeout); + if (err < 0) { + sd_print_debug_regs(host); + dev_dbg(sdmmc_dev(host), + "rtsx_pci_send_cmd fail (err = %d)\n", err); + return err; + } + + if (buf && buf_len) { + err = rtsx_pci_read_ppbuf(pcr, buf, buf_len); + if (err < 0) { + dev_dbg(sdmmc_dev(host), + "rtsx_pci_read_ppbuf fail (err = %d)\n", err); + return err; + } + } + + return 0; +} + +static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, + u8 *buf, int buf_len, int timeout) +{ + struct rtsx_pcr *pcr = host->pcr; + int err, i; + u8 trans_mode; + + if (!buf) + buf_len = 0; + + if (buf && buf_len) { + err = rtsx_pci_write_ppbuf(pcr, buf, buf_len); + if (err < 0) { + dev_dbg(sdmmc_dev(host), + "rtsx_pci_write_ppbuf fail (err = %d)\n", err); + return err; + } + } + + trans_mode = cmd ? SD_TM_AUTO_WRITE_2 : SD_TM_AUTO_WRITE_3; + rtsx_pci_init_cmd(pcr); + + if (cmd) { + dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d\n", __func__, + cmd[0] - 0x40); + + for (i = 0; i < 5; i++) + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, + SD_CMD0 + i, 0xFF, cmd[i]); + } + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8)byte_cnt); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, + 0xFF, (u8)(byte_cnt >> 8)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | + SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + trans_mode | SD_TRANSFER_START); + rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + err = rtsx_pci_send_cmd(pcr, timeout); + if (err < 0) { + sd_print_debug_regs(host); + dev_dbg(sdmmc_dev(host), + "rtsx_pci_send_cmd fail (err = %d)\n", err); + return err; + } + + return 0; +} + +static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, + struct mmc_command *cmd) +{ + struct rtsx_pcr *pcr = host->pcr; + u8 cmd_idx = (u8)cmd->opcode; + u32 arg = cmd->arg; + int err = 0; + int timeout = 100; + int i; + u8 *ptr; + int stat_idx = 0; + u8 rsp_type; + int rsp_len = 5; + + dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", + __func__, cmd_idx, arg); + + /* Response type: + * R0 + * R1, R5, R6, R7 + * R1b + * R2 + * R3, R4 + */ + switch (mmc_resp_type(cmd)) { + case MMC_RSP_NONE: + rsp_type = SD_RSP_TYPE_R0; + rsp_len = 0; + break; + case MMC_RSP_R1: + rsp_type = SD_RSP_TYPE_R1; + break; + case MMC_RSP_R1B: + rsp_type = SD_RSP_TYPE_R1b; + break; + case MMC_RSP_R2: + rsp_type = SD_RSP_TYPE_R2; + rsp_len = 16; + break; + case MMC_RSP_R3: + rsp_type = SD_RSP_TYPE_R3; + break; + default: + dev_dbg(sdmmc_dev(host), "cmd->flag is not valid\n"); + err = -EINVAL; + goto out; + } + + if (rsp_type == SD_RSP_TYPE_R1b) + timeout = 3000; + + if (cmd->opcode == SD_SWITCH_VOLTAGE) { + err = rtsx_pci_write_register(pcr, SD_BUS_STAT, + 0xFF, SD_CLK_TOGGLE_EN); + if (err < 0) + goto out; + } + + rtsx_pci_init_cmd(pcr); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8)(arg >> 24)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8)(arg >> 16)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8)(arg >> 8)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8)arg); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, + 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); + rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, + SD_TRANSFER_END | SD_STAT_IDLE, + SD_TRANSFER_END | SD_STAT_IDLE); + + if (rsp_type == SD_RSP_TYPE_R2) { + /* Read data from ping-pong buffer */ + for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++) + rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); + stat_idx = 16; + } else if (rsp_type != SD_RSP_TYPE_R0) { + /* Read data from SD_CMDx registers */ + for (i = SD_CMD0; i <= SD_CMD4; i++) + rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); + stat_idx = 5; + } + + rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0); + + err = rtsx_pci_send_cmd(pcr, timeout); + if (err < 0) { + sd_print_debug_regs(host); + sd_clear_error(host); + dev_dbg(sdmmc_dev(host), + "rtsx_pci_send_cmd error (err = %d)\n", err); + goto out; + } + + if (rsp_type == SD_RSP_TYPE_R0) { + err = 0; + goto out; + } + + /* Eliminate returned value of CHECK_REG_CMD */ + ptr = rtsx_pci_get_cmd_data(pcr) + 1; + + /* Check (Start,Transmission) bit of Response */ + if ((ptr[0] & 0xC0) != 0) { + err = -EILSEQ; + dev_dbg(sdmmc_dev(host), "Invalid response bit\n"); + goto out; + } + + /* Check CRC7 */ + if (!(rsp_type & SD_NO_CHECK_CRC7)) { + if (ptr[stat_idx] & SD_CRC7_ERR) { + err = -EILSEQ; + dev_dbg(sdmmc_dev(host), "CRC7 error\n"); + goto out; + } + } + + if (rsp_type == SD_RSP_TYPE_R2) { + for (i = 0; i < 4; i++) { + cmd->resp[i] = get_unaligned_be32(ptr + 1 + i * 4); + dev_dbg(sdmmc_dev(host), "cmd->resp[%d] = 0x%08x\n", + i, cmd->resp[i]); + } + } else { + cmd->resp[0] = get_unaligned_be32(ptr + 1); + dev_dbg(sdmmc_dev(host), "cmd->resp[0] = 0x%08x\n", + cmd->resp[0]); + } + +out: + cmd->error = err; +} + +static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) +{ + struct rtsx_pcr *pcr = host->pcr; + struct mmc_host *mmc = host->mmc; + struct mmc_card *card = mmc->card; + struct mmc_data *data = mrq->data; + int uhs = mmc_sd_card_uhs(card); + int read = (data->flags & MMC_DATA_READ) ? 1 : 0; + u8 cfg2, trans_mode; + int err; + size_t data_len = data->blksz * data->blocks; + + if (read) { + cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | + SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0; + trans_mode = SD_TM_AUTO_READ_3; + } else { + cfg2 = SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | + SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | SD_RSP_LEN_0; + trans_mode = SD_TM_AUTO_WRITE_3; + } + + if (!uhs) + cfg2 |= SD_NO_CHECK_WAIT_CRC_TO; + + rtsx_pci_init_cmd(pcr); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, + 0xFF, (u8)data->blocks); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, + 0xFF, (u8)(data->blocks >> 8)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, + CARD_DATA_SOURCE, 0x01, RING_BUFFER); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, + DMA_DONE_INT, DMA_DONE_INT); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, + 0xFF, (u8)(data_len >> 24)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, + 0xFF, (u8)(data_len >> 16)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, + 0xFF, (u8)(data_len >> 8)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)data_len); + if (read) { + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, + 0x03 | DMA_PACK_SIZE_MASK, + DMA_DIR_FROM_CARD | DMA_EN | DMA_512); + } else { + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, + 0x03 | DMA_PACK_SIZE_MASK, + DMA_DIR_TO_CARD | DMA_EN | DMA_512); + } + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, RING_BUFFER); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + trans_mode | SD_TRANSFER_START); + rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + rtsx_pci_send_cmd_no_wait(pcr); + + err = rtsx_pci_transfer_data(pcr, data->sg, data->sg_len, read, 10000); + if (err < 0) { + sd_clear_error(host); + return err; + } + + return 0; +} + +static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) +{ + rtsx_pci_write_register(host->pcr, SD_CFG1, + SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_128); +} + +static inline void sd_disable_initial_mode(struct realtek_pci_sdmmc *host) +{ + rtsx_pci_write_register(host->pcr, SD_CFG1, + SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); +} + +static void sd_normal_rw(struct realtek_pci_sdmmc *host, + struct mmc_request *mrq) +{ + struct mmc_command *cmd = mrq->cmd; + struct mmc_data *data = mrq->data; + u8 _cmd[5], *buf; + + _cmd[0] = 0x40 | (u8)cmd->opcode; + put_unaligned_be32(cmd->arg, (u32 *)(&_cmd[1])); + + buf = kzalloc(data->blksz, GFP_NOIO); + if (!buf) { + cmd->error = -ENOMEM; + return; + } + + if (data->flags & MMC_DATA_READ) { + if (host->initial_mode) + sd_disable_initial_mode(host); + + cmd->error = sd_read_data(host, _cmd, (u16)data->blksz, buf, + data->blksz, 200); + + if (host->initial_mode) + sd_enable_initial_mode(host); + + sg_copy_from_buffer(data->sg, data->sg_len, buf, data->blksz); + } else { + sg_copy_to_buffer(data->sg, data->sg_len, buf, data->blksz); + + cmd->error = sd_write_data(host, _cmd, (u16)data->blksz, buf, + data->blksz, 200); + } + + kfree(buf); +} + +static int sd_change_phase(struct realtek_pci_sdmmc *host, u8 sample_point) +{ + struct rtsx_pcr *pcr = host->pcr; + int err; + + dev_dbg(sdmmc_dev(host), "%s: sample_point = %d\n", + __func__, sample_point); + + rtsx_pci_init_cmd(pcr); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CHANGE_CLK, CHANGE_CLK); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPRX_CTL, 0x1F, sample_point); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_VPCLK0_CTL, + PHASE_NOT_RESET, PHASE_NOT_RESET); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CHANGE_CLK, 0); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); + + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + return 0; +} + +static u8 sd_search_final_phase(struct realtek_pci_sdmmc *host, u32 phase_map) +{ + struct timing_phase_path path[MAX_PHASE + 1]; + int i, j, cont_path_cnt; + int new_block, max_len, final_path_idx; + u8 final_phase = 0xFF; + + /* Parse phase_map, take it as a bit-ring */ + cont_path_cnt = 0; + new_block = 1; + j = 0; + for (i = 0; i < MAX_PHASE + 1; i++) { + if (phase_map & (1 << i)) { + if (new_block) { + new_block = 0; + j = cont_path_cnt++; + path[j].start = i; + path[j].end = i; + } else { + path[j].end = i; + } + } else { + new_block = 1; + if (cont_path_cnt) { + /* Calculate path length and middle point */ + int idx = cont_path_cnt - 1; + path[idx].len = + path[idx].end - path[idx].start + 1; + path[idx].mid = + path[idx].start + path[idx].len / 2; + } + } + } + + if (cont_path_cnt == 0) { + dev_dbg(sdmmc_dev(host), "No continuous phase path\n"); + goto finish; + } else { + /* Calculate last continuous path length and middle point */ + int idx = cont_path_cnt - 1; + path[idx].len = path[idx].end - path[idx].start + 1; + path[idx].mid = path[idx].start + path[idx].len / 2; + } + + /* Connect the first and last continuous paths if they are adjacent */ + if (!path[0].start && (path[cont_path_cnt - 1].end == MAX_PHASE)) { + /* Using negative index */ + path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1; + path[0].len += path[cont_path_cnt - 1].len; + path[0].mid = path[0].start + path[0].len / 2; + /* Convert negative middle point index to positive one */ + if (path[0].mid < 0) + path[0].mid += MAX_PHASE + 1; + cont_path_cnt--; + } + + /* Choose the longest continuous phase path */ + max_len = 0; + final_phase = 0; + final_path_idx = 0; + for (i = 0; i < cont_path_cnt; i++) { + if (path[i].len > max_len) { + max_len = path[i].len; + final_phase = (u8)path[i].mid; + final_path_idx = i; + } + + dev_dbg(sdmmc_dev(host), "path[%d].start = %d\n", + i, path[i].start); + dev_dbg(sdmmc_dev(host), "path[%d].end = %d\n", + i, path[i].end); + dev_dbg(sdmmc_dev(host), "path[%d].len = %d\n", + i, path[i].len); + dev_dbg(sdmmc_dev(host), "path[%d].mid = %d\n", + i, path[i].mid); + } + +finish: + dev_dbg(sdmmc_dev(host), "Final chosen phase: %d\n", final_phase); + return final_phase; +} + +static void sd_wait_data_idle(struct realtek_pci_sdmmc *host) +{ + int err, i; + u8 val = 0; + + for (i = 0; i < 100; i++) { + err = rtsx_pci_read_register(host->pcr, SD_DATA_STATE, &val); + if (val & SD_DATA_IDLE) + return; + + udelay(100); + } +} + +static int sd_tuning_rx_cmd(struct realtek_pci_sdmmc *host, + u8 opcode, u8 sample_point) +{ + int err; + u8 cmd[5] = {0}; + + err = sd_change_phase(host, sample_point); + if (err < 0) + return err; + + cmd[0] = 0x40 | opcode; + err = sd_read_data(host, cmd, 0x40, NULL, 0, 100); + if (err < 0) { + /* Wait till SD DATA IDLE */ + sd_wait_data_idle(host); + sd_clear_error(host); + return err; + } + + return 0; +} + +static int sd_tuning_phase(struct realtek_pci_sdmmc *host, + u8 opcode, u32 *phase_map) +{ + int err, i; + u32 raw_phase_map = 0; + + for (i = MAX_PHASE; i >= 0; i--) { + err = sd_tuning_rx_cmd(host, opcode, (u8)i); + if (err == 0) + raw_phase_map |= 1 << i; + } + + if (phase_map) + *phase_map = raw_phase_map; + + return 0; +} + +static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode) +{ + int err, i; + u32 raw_phase_map[RX_TUNING_CNT] = {0}, phase_map; + u8 final_phase; + + for (i = 0; i < RX_TUNING_CNT; i++) { + err = sd_tuning_phase(host, opcode, &(raw_phase_map[i])); + if (err < 0) + return err; + + if (raw_phase_map[i] == 0) + break; + } + + phase_map = 0xFFFFFFFF; + for (i = 0; i < RX_TUNING_CNT; i++) { + dev_dbg(sdmmc_dev(host), "RX raw_phase_map[%d] = 0x%08x\n", + i, raw_phase_map[i]); + phase_map &= raw_phase_map[i]; + } + dev_dbg(sdmmc_dev(host), "RX phase_map = 0x%08x\n", phase_map); + + if (phase_map) { + final_phase = sd_search_final_phase(host, phase_map); + if (final_phase == 0xFF) + return -EINVAL; + + err = sd_change_phase(host, final_phase); + if (err < 0) + return err; + } else { + return -EINVAL; + } + + return 0; +} + +static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct realtek_pci_sdmmc *host = mmc_priv(mmc); + struct rtsx_pcr *pcr = host->pcr; + struct mmc_command *cmd = mrq->cmd; + struct mmc_data *data = mrq->data; + unsigned int data_size = 0; + + if (host->eject) { + cmd->error = -ENOMEDIUM; + goto finish; + } + + mutex_lock(&pcr->pcr_mutex); + + rtsx_pci_start_run(pcr); + + rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth, + host->initial_mode, host->double_clk, host->vpclk); + rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, SD_MOD_SEL); + rtsx_pci_write_register(pcr, CARD_SHARE_MODE, + CARD_SHARE_MASK, CARD_SHARE_48_SD); + + mutex_lock(&host->host_mutex); + host->mrq = mrq; + mutex_unlock(&host->host_mutex); + + if (mrq->data) + data_size = data->blocks * data->blksz; + + if (!data_size || mmc_op_multi(cmd->opcode) || + (cmd->opcode == MMC_READ_SINGLE_BLOCK) || + (cmd->opcode == MMC_WRITE_BLOCK)) { + sd_send_cmd_get_rsp(host, cmd); + + if (!cmd->error && data_size) { + sd_rw_multi(host, mrq); + + if (mmc_op_multi(cmd->opcode) && mrq->stop) + sd_send_cmd_get_rsp(host, mrq->stop); + } + } else { + sd_normal_rw(host, mrq); + } + + if (mrq->data) { + if (cmd->error || data->error) + data->bytes_xfered = 0; + else + data->bytes_xfered = data->blocks * data->blksz; + } + + mutex_unlock(&pcr->pcr_mutex); + +finish: + if (cmd->error) + dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error); + + mutex_lock(&host->host_mutex); + host->mrq = NULL; + mutex_unlock(&host->host_mutex); + + mmc_request_done(mmc, mrq); +} + +static int sd_set_bus_width(struct realtek_pci_sdmmc *host, + unsigned char bus_width) +{ + int err = 0; + u8 width[] = { + [MMC_BUS_WIDTH_1] = SD_BUS_WIDTH_1BIT, + [MMC_BUS_WIDTH_4] = SD_BUS_WIDTH_4BIT, + [MMC_BUS_WIDTH_8] = SD_BUS_WIDTH_8BIT, + }; + + if (bus_width <= MMC_BUS_WIDTH_8) + err = rtsx_pci_write_register(host->pcr, SD_CFG1, + 0x03, width[bus_width]); + + return err; +} + +static int sd_power_on(struct realtek_pci_sdmmc *host) +{ + struct rtsx_pcr *pcr = host->pcr; + int err; + + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SELECT, 0x07, SD_MOD_SEL); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SHARE_MODE, + CARD_SHARE_MASK, CARD_SHARE_48_SD); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, + SD_CLK_EN, SD_CLK_EN); + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + err = rtsx_pci_card_pull_ctl_enable(pcr, RTSX_SD_CARD); + if (err < 0) + return err; + + err = rtsx_pci_card_power_on(pcr, RTSX_SD_CARD); + if (err < 0) + return err; + + err = rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN); + if (err < 0) + return err; + + return 0; +} + +static int sd_power_off(struct realtek_pci_sdmmc *host) +{ + struct rtsx_pcr *pcr = host->pcr; + int err; + + rtsx_pci_init_cmd(pcr); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, 0); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE, SD_OUTPUT_EN, 0); + + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + err = rtsx_pci_card_power_off(pcr, RTSX_SD_CARD); + if (err < 0) + return err; + + return rtsx_pci_card_pull_ctl_disable(pcr, RTSX_SD_CARD); +} + +static int sd_set_power_mode(struct realtek_pci_sdmmc *host, + unsigned char power_mode) +{ + int err; + + if (power_mode == MMC_POWER_OFF) + err = sd_power_off(host); + else + err = sd_power_on(host); + + return err; +} + +static int sd_set_timing(struct realtek_pci_sdmmc *host, + unsigned char timing, bool *ddr_mode) +{ + struct rtsx_pcr *pcr = host->pcr; + int err = 0; + + *ddr_mode = false; + + rtsx_pci_init_cmd(pcr); + + switch (timing) { + case MMC_TIMING_UHS_SDR104: + case MMC_TIMING_UHS_SDR50: + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1, + 0x0C | SD_ASYNC_FIFO_NOT_RST, + SD_30_MODE | SD_ASYNC_FIFO_NOT_RST); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, + CLK_LOW_FREQ, CLK_LOW_FREQ); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF, + CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, 0); + break; + + case MMC_TIMING_UHS_DDR50: + *ddr_mode = true; + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1, + 0x0C | SD_ASYNC_FIFO_NOT_RST, + SD_DDR_MODE | SD_ASYNC_FIFO_NOT_RST); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, + CLK_LOW_FREQ, CLK_LOW_FREQ); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF, + CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, 0); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_PUSH_POINT_CTL, + DDR_VAR_TX_CMD_DAT, DDR_VAR_TX_CMD_DAT); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL, + DDR_VAR_RX_DAT | DDR_VAR_RX_CMD, + DDR_VAR_RX_DAT | DDR_VAR_RX_CMD); + break; + + case MMC_TIMING_MMC_HS: + case MMC_TIMING_SD_HS: + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CFG1, + 0x0C, SD_20_MODE); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, + CLK_LOW_FREQ, CLK_LOW_FREQ); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF, + CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, 0); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_PUSH_POINT_CTL, + SD20_TX_SEL_MASK, SD20_TX_14_AHEAD); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL, + SD20_RX_SEL_MASK, SD20_RX_14_DELAY); + break; + + default: + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, + SD_CFG1, 0x0C, SD_20_MODE); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, + CLK_LOW_FREQ, CLK_LOW_FREQ); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF, + CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL, CLK_LOW_FREQ, 0); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, + SD_PUSH_POINT_CTL, 0xFF, 0); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL, + SD20_RX_SEL_MASK, SD20_RX_POS_EDGE); + break; + } + + err = rtsx_pci_send_cmd(pcr, 100); + + return err; +} + +static void sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct realtek_pci_sdmmc *host = mmc_priv(mmc); + struct rtsx_pcr *pcr = host->pcr; + + if (host->eject) + return; + + mutex_lock(&pcr->pcr_mutex); + + rtsx_pci_start_run(pcr); + + sd_set_bus_width(host, ios->bus_width); + sd_set_power_mode(host, ios->power_mode); + sd_set_timing(host, ios->timing, &host->ddr_mode); + + host->vpclk = false; + host->double_clk = true; + + switch (ios->timing) { + case MMC_TIMING_UHS_SDR104: + case MMC_TIMING_UHS_SDR50: + host->ssc_depth = RTSX_SSC_DEPTH_2M; + host->vpclk = true; + host->double_clk = false; + break; + case MMC_TIMING_UHS_DDR50: + case MMC_TIMING_UHS_SDR25: + host->ssc_depth = RTSX_SSC_DEPTH_1M; + break; + default: + host->ssc_depth = RTSX_SSC_DEPTH_500K; + break; + } + + host->initial_mode = (ios->clock <= 1000000) ? true : false; + + host->clock = ios->clock; + rtsx_pci_switch_clock(pcr, ios->clock, host->ssc_depth, + host->initial_mode, host->double_clk, host->vpclk); + + mutex_unlock(&pcr->pcr_mutex); +} + +static int sdmmc_get_ro(struct mmc_host *mmc) +{ + struct realtek_pci_sdmmc *host = mmc_priv(mmc); + struct rtsx_pcr *pcr = host->pcr; + int ro = 0; + u32 val; + + if (host->eject) + return -ENOMEDIUM; + + mutex_lock(&pcr->pcr_mutex); + + rtsx_pci_start_run(pcr); + + /* Check SD mechanical write-protect switch */ + val = rtsx_pci_readl(pcr, RTSX_BIPR); + dev_dbg(sdmmc_dev(host), "%s: RTSX_BIPR = 0x%08x\n", __func__, val); + if (val & SD_WRITE_PROTECT) + ro = 1; + + mutex_unlock(&pcr->pcr_mutex); + + return ro; +} + +static int sdmmc_get_cd(struct mmc_host *mmc) +{ + struct realtek_pci_sdmmc *host = mmc_priv(mmc); + struct rtsx_pcr *pcr = host->pcr; + int cd = 0; + u32 val; + + if (host->eject) + return -ENOMEDIUM; + + mutex_lock(&pcr->pcr_mutex); + + rtsx_pci_start_run(pcr); + + /* Check SD card detect */ + val = rtsx_pci_card_exist(pcr); + dev_dbg(sdmmc_dev(host), "%s: RTSX_BIPR = 0x%08x\n", __func__, val); + if (val & SD_EXIST) + cd = 1; + + mutex_unlock(&pcr->pcr_mutex); + + return cd; +} + +static int sd_wait_voltage_stable_1(struct realtek_pci_sdmmc *host) +{ + struct rtsx_pcr *pcr = host->pcr; + int err; + u8 stat; + + /* Reference to Signal Voltage Switch Sequence in SD spec. + * Wait for a period of time so that the card can drive SD_CMD and + * SD_DAT[3:0] to low after sending back CMD11 response. + */ + mdelay(1); + + /* SD_CMD, SD_DAT[3:0] should be driven to low by card; + * If either one of SD_CMD,SD_DAT[3:0] is not low, + * abort the voltage switch sequence; + */ + err = rtsx_pci_read_register(pcr, SD_BUS_STAT, &stat); + if (err < 0) + return err; + + if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | + SD_DAT1_STATUS | SD_DAT0_STATUS)) + return -EINVAL; + + /* Stop toggle SD clock */ + err = rtsx_pci_write_register(pcr, SD_BUS_STAT, + 0xFF, SD_CLK_FORCE_STOP); + if (err < 0) + return err; + + return 0; +} + +static int sd_wait_voltage_stable_2(struct realtek_pci_sdmmc *host) +{ + struct rtsx_pcr *pcr = host->pcr; + int err; + u8 stat, mask, val; + + /* Wait 1.8V output of voltage regulator in card stable */ + msleep(50); + + /* Toggle SD clock again */ + err = rtsx_pci_write_register(pcr, SD_BUS_STAT, 0xFF, SD_CLK_TOGGLE_EN); + if (err < 0) + return err; + + /* Wait for a period of time so that the card can drive + * SD_DAT[3:0] to high at 1.8V + */ + msleep(20); + + /* SD_CMD, SD_DAT[3:0] should be pulled high by host */ + err = rtsx_pci_read_register(pcr, SD_BUS_STAT, &stat); + if (err < 0) + return err; + + mask = SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | + SD_DAT1_STATUS | SD_DAT0_STATUS; + val = SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | + SD_DAT1_STATUS | SD_DAT0_STATUS; + if ((stat & mask) != val) { + dev_dbg(sdmmc_dev(host), + "%s: SD_BUS_STAT = 0x%x\n", __func__, stat); + rtsx_pci_write_register(pcr, SD_BUS_STAT, + SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); + rtsx_pci_write_register(pcr, CARD_CLK_EN, 0xFF, 0); + return -EINVAL; + } + + return 0; +} + +static int sd_change_bank_voltage(struct realtek_pci_sdmmc *host, u8 voltage) +{ + struct rtsx_pcr *pcr = host->pcr; + int err; + + if (voltage == SD_IO_3V3) { + err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4FC0 | 0x24); + if (err < 0) + return err; + } else if (voltage == SD_IO_1V8) { + err = rtsx_pci_write_phy_register(pcr, 0x08, 0x4C40 | 0x24); + if (err < 0) + return err; + } else { + return -EINVAL; + } + + return 0; +} + +static int sdmmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct realtek_pci_sdmmc *host = mmc_priv(mmc); + struct rtsx_pcr *pcr = host->pcr; + int err = 0; + u8 voltage; + + dev_dbg(sdmmc_dev(host), "%s: signal_voltage = %d\n", + __func__, ios->signal_voltage); + + if (host->eject) + return -ENOMEDIUM; + + mutex_lock(&pcr->pcr_mutex); + + rtsx_pci_start_run(pcr); + + if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) + voltage = SD_IO_3V3; + else + voltage = SD_IO_1V8; + + if (voltage == SD_IO_1V8) { + err = rtsx_pci_write_register(pcr, + SD30_DRIVE_SEL, 0x07, DRIVER_TYPE_B); + if (err < 0) + goto out; + + err = sd_wait_voltage_stable_1(host); + if (err < 0) + goto out; + } + + err = sd_change_bank_voltage(host, voltage); + if (err < 0) + goto out; + + if (voltage == SD_IO_1V8) { + err = sd_wait_voltage_stable_2(host); + if (err < 0) + goto out; + } + + /* Stop toggle SD clock in idle */ + err = rtsx_pci_write_register(pcr, SD_BUS_STAT, + SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); + +out: + mutex_unlock(&pcr->pcr_mutex); + + return err; +} + +static int sdmmc_execute_tuning(struct mmc_host *mmc, u32 opcode) +{ + struct realtek_pci_sdmmc *host = mmc_priv(mmc); + struct rtsx_pcr *pcr = host->pcr; + int err = 0; + + if (host->eject) + return -ENOMEDIUM; + + mutex_lock(&pcr->pcr_mutex); + + rtsx_pci_start_run(pcr); + + if (!host->ddr_mode) + err = sd_tuning_rx(host, MMC_SEND_TUNING_BLOCK); + + mutex_unlock(&pcr->pcr_mutex); + + return err; +} + +static const struct mmc_host_ops realtek_pci_sdmmc_ops = { + .request = sdmmc_request, + .set_ios = sdmmc_set_ios, + .get_ro = sdmmc_get_ro, + .get_cd = sdmmc_get_cd, + .start_signal_voltage_switch = sdmmc_switch_voltage, + .execute_tuning = sdmmc_execute_tuning, +}; + +#ifdef CONFIG_PM +static int rtsx_pci_sdmmc_suspend(struct platform_device *pdev, + pm_message_t state) +{ + struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); + struct mmc_host *mmc = host->mmc; + int err; + + dev_dbg(sdmmc_dev(host), "--> %s\n", __func__); + + err = mmc_suspend_host(mmc); + if (err) + return err; + + return 0; +} + +static int rtsx_pci_sdmmc_resume(struct platform_device *pdev) +{ + struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); + struct mmc_host *mmc = host->mmc; + + dev_dbg(sdmmc_dev(host), "--> %s\n", __func__); + + return mmc_resume_host(mmc); +} +#else /* CONFIG_PM */ +#define rtsx_pci_sdmmc_suspend NULL +#define rtsx_pci_sdmmc_resume NULL +#endif /* CONFIG_PM */ + +static void init_extra_caps(struct realtek_pci_sdmmc *host) +{ + struct mmc_host *mmc = host->mmc; + struct rtsx_pcr *pcr = host->pcr; + + dev_dbg(sdmmc_dev(host), "pcr->extra_caps = 0x%x\n", pcr->extra_caps); + + if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50) + mmc->caps |= MMC_CAP_UHS_SDR50; + if (pcr->extra_caps & EXTRA_CAPS_SD_SDR104) + mmc->caps |= MMC_CAP_UHS_SDR104; + if (pcr->extra_caps & EXTRA_CAPS_SD_DDR50) + mmc->caps |= MMC_CAP_UHS_DDR50; + if (pcr->extra_caps & EXTRA_CAPS_MMC_HSDDR) + mmc->caps |= MMC_CAP_1_8V_DDR; + if (pcr->extra_caps & EXTRA_CAPS_MMC_8BIT) + mmc->caps |= MMC_CAP_8_BIT_DATA; +} + +static void realtek_init_host(struct realtek_pci_sdmmc *host) +{ + struct mmc_host *mmc = host->mmc; + + mmc->f_min = 250000; + mmc->f_max = 208000000; + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; + mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_BUS_WIDTH_TEST | + MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25; + mmc->max_current_330 = 400; + mmc->max_current_180 = 800; + mmc->ops = &realtek_pci_sdmmc_ops; + + init_extra_caps(host); + + mmc->max_segs = 256; + mmc->max_seg_size = 65536; + mmc->max_blk_size = 512; + mmc->max_blk_count = 65535; + mmc->max_req_size = 524288; +} + +static void rtsx_pci_sdmmc_card_event(struct platform_device *pdev) +{ + struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); + + mmc_detect_change(host->mmc, 0); +} + +static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev) +{ + struct mmc_host *mmc; + struct realtek_pci_sdmmc *host; + struct rtsx_pcr *pcr; + struct pcr_handle *handle = pdev->dev.platform_data; + + if (!handle) + return -ENXIO; + + pcr = handle->pcr; + if (!pcr) + return -ENXIO; + + dev_dbg(&(pdev->dev), ": Realtek PCI-E SDMMC controller found\n"); + + mmc = mmc_alloc_host(sizeof(*host), &pdev->dev); + if (!mmc) + return -ENOMEM; + + host = mmc_priv(mmc); + host->pcr = pcr; + host->mmc = mmc; + host->pdev = pdev; + platform_set_drvdata(pdev, host); + pcr->slots[RTSX_SD_CARD].p_dev = pdev; + pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event; + + mutex_init(&host->host_mutex); + + realtek_init_host(host); + + mmc_add_host(mmc); + + return 0; +} + +static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev) +{ + struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); + struct rtsx_pcr *pcr; + struct mmc_host *mmc; + + if (!host) + return 0; + + pcr = host->pcr; + pcr->slots[RTSX_SD_CARD].p_dev = NULL; + pcr->slots[RTSX_SD_CARD].card_event = NULL; + mmc = host->mmc; + host->eject = true; + + mutex_lock(&host->host_mutex); + if (host->mrq) { + dev_dbg(&(pdev->dev), + "%s: Controller removed during transfer\n", + mmc_hostname(mmc)); + + rtsx_pci_complete_unfinished_transfer(pcr); + + host->mrq->cmd->error = -ENOMEDIUM; + if (host->mrq->stop) + host->mrq->stop->error = -ENOMEDIUM; + mmc_request_done(mmc, host->mrq); + } + mutex_unlock(&host->host_mutex); + + mmc_remove_host(mmc); + mmc_free_host(mmc); + + platform_set_drvdata(pdev, NULL); + + dev_dbg(&(pdev->dev), + ": Realtek PCI-E SDMMC controller has been removed\n"); + + return 0; +} + +static struct platform_device_id rtsx_pci_sdmmc_ids[] = { + { + .name = DRV_NAME_RTSX_PCI_SDMMC, + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(platform, rtsx_pci_sdmmc_ids); + +static struct platform_driver rtsx_pci_sdmmc_driver = { + .probe = rtsx_pci_sdmmc_drv_probe, + .remove = rtsx_pci_sdmmc_drv_remove, + .id_table = rtsx_pci_sdmmc_ids, + .suspend = rtsx_pci_sdmmc_suspend, + .resume = rtsx_pci_sdmmc_resume, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME_RTSX_PCI_SDMMC, + }, +}; +module_platform_driver(rtsx_pci_sdmmc_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Wei WANG "); +MODULE_DESCRIPTION("Realtek PCI-E SD/MMC Card Host Driver"); -- cgit v1.2.3 From b902dd4ecc2cccdd6c033ba5d959d4d6606e55fb Mon Sep 17 00:00:00 2001 From: Wei WANG Date: Fri, 9 Nov 2012 20:53:35 +0800 Subject: drivers/memstick: Add realtek pcie memstick host driver Realtek PCI-E Memstick card host driver is used to access Memstick card, with the help of Realtek PCI-E card reader MFD driver. Signed-off-by: Wei WANG Acked-by: Alex Dubov Signed-off-by: Greg Kroah-Hartman --- drivers/memstick/host/Kconfig | 10 + drivers/memstick/host/Makefile | 1 + drivers/memstick/host/rtsx_pci_ms.c | 641 ++++++++++++++++++++++++++++++++++++ 3 files changed, 652 insertions(+) create mode 100644 drivers/memstick/host/rtsx_pci_ms.c diff --git a/drivers/memstick/host/Kconfig b/drivers/memstick/host/Kconfig index cc0997a0517..4f7a17fd1aa 100644 --- a/drivers/memstick/host/Kconfig +++ b/drivers/memstick/host/Kconfig @@ -42,3 +42,13 @@ config MEMSTICK_R592 To compile this driver as a module, choose M here: the module will be called r592. + +config MEMSTICK_REALTEK_PCI + tristate "Realtek PCI-E Memstick Card Interface Driver" + depends on MFD_RTSX_PCI + help + Say Y here to include driver code to support Memstick card interface + of Realtek PCI-E card reader + + To compile this driver as a module, choose M here: the module will + be called rtsx_pci_ms. diff --git a/drivers/memstick/host/Makefile b/drivers/memstick/host/Makefile index 31ba8d378e4..af3459d7686 100644 --- a/drivers/memstick/host/Makefile +++ b/drivers/memstick/host/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_MEMSTICK_TIFM_MS) += tifm_ms.o obj-$(CONFIG_MEMSTICK_JMICRON_38X) += jmb38x_ms.o obj-$(CONFIG_MEMSTICK_R592) += r592.o +obj-$(CONFIG_MEMSTICK_REALTEK_PCI) += rtsx_pci_ms.o diff --git a/drivers/memstick/host/rtsx_pci_ms.c b/drivers/memstick/host/rtsx_pci_ms.c new file mode 100644 index 00000000000..f5ddb82dadb --- /dev/null +++ b/drivers/memstick/host/rtsx_pci_ms.c @@ -0,0 +1,641 @@ +/* Realtek PCI-Express Memstick Card Interface driver + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * 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, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + * Author: + * Wei WANG + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include +#include +#include +#include +#include +#include +#include + +struct realtek_pci_ms { + struct platform_device *pdev; + struct rtsx_pcr *pcr; + struct memstick_host *msh; + struct memstick_request *req; + + struct mutex host_mutex; + struct work_struct handle_req; + + u8 ssc_depth; + unsigned int clock; + unsigned char ifmode; + bool eject; +}; + +static inline struct device *ms_dev(struct realtek_pci_ms *host) +{ + return &(host->pdev->dev); +} + +static inline void ms_clear_error(struct realtek_pci_ms *host) +{ + rtsx_pci_write_register(host->pcr, CARD_STOP, + MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR); +} + +#ifdef DEBUG + +static void ms_print_debug_regs(struct realtek_pci_ms *host) +{ + struct rtsx_pcr *pcr = host->pcr; + u16 i; + u8 *ptr; + + /* Print MS host internal registers */ + rtsx_pci_init_cmd(pcr); + for (i = 0xFD40; i <= 0xFD44; i++) + rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0); + for (i = 0xFD52; i <= 0xFD69; i++) + rtsx_pci_add_cmd(pcr, READ_REG_CMD, i, 0, 0); + rtsx_pci_send_cmd(pcr, 100); + + ptr = rtsx_pci_get_cmd_data(pcr); + for (i = 0xFD40; i <= 0xFD44; i++) + dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); + for (i = 0xFD52; i <= 0xFD69; i++) + dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); +} + +#else + +#define ms_print_debug_regs(host) + +#endif + +static int ms_power_on(struct realtek_pci_ms *host) +{ + struct rtsx_pcr *pcr = host->pcr; + int err; + + rtsx_pci_init_cmd(pcr); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SELECT, 0x07, MS_MOD_SEL); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SHARE_MODE, + CARD_SHARE_MASK, CARD_SHARE_48_MS); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, + MS_CLK_EN, MS_CLK_EN); + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + err = rtsx_pci_card_pull_ctl_enable(pcr, RTSX_MS_CARD); + if (err < 0) + return err; + + err = rtsx_pci_card_power_on(pcr, RTSX_MS_CARD); + if (err < 0) + return err; + + /* Wait ms power stable */ + msleep(150); + + err = rtsx_pci_write_register(pcr, CARD_OE, + MS_OUTPUT_EN, MS_OUTPUT_EN); + if (err < 0) + return err; + + return 0; +} + +static int ms_power_off(struct realtek_pci_ms *host) +{ + struct rtsx_pcr *pcr = host->pcr; + int err; + + rtsx_pci_init_cmd(pcr); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, 0); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0); + + err = rtsx_pci_send_cmd(pcr, 100); + if (err < 0) + return err; + + err = rtsx_pci_card_power_off(pcr, RTSX_MS_CARD); + if (err < 0) + return err; + + return rtsx_pci_card_pull_ctl_disable(pcr, RTSX_MS_CARD); +} + +static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir, + u8 tpc, u8 cfg, struct scatterlist *sg) +{ + struct rtsx_pcr *pcr = host->pcr; + int err; + unsigned int length = sg->length; + u16 sec_cnt = (u16)(length / 512); + u8 val, trans_mode, dma_dir; + + dev_dbg(ms_dev(host), "%s: tpc = 0x%02x, data_dir = %s, length = %d\n", + __func__, tpc, (data_dir == READ) ? "READ" : "WRITE", + length); + + if (data_dir == READ) { + dma_dir = DMA_DIR_FROM_CARD; + trans_mode = MS_TM_AUTO_READ; + } else { + dma_dir = DMA_DIR_TO_CARD; + trans_mode = MS_TM_AUTO_WRITE; + } + + rtsx_pci_init_cmd(pcr); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H, + 0xFF, (u8)(sec_cnt >> 8)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_L, + 0xFF, (u8)sec_cnt); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0, + DMA_DONE_INT, DMA_DONE_INT); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(length >> 24)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(length >> 16)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(length >> 8)); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)length); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL, + 0x03 | DMA_PACK_SIZE_MASK, dma_dir | DMA_EN | DMA_512); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, RING_BUFFER); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER, + 0xFF, MS_TRANSFER_START | trans_mode); + rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER, + MS_TRANSFER_END, MS_TRANSFER_END); + + rtsx_pci_send_cmd_no_wait(pcr); + + err = rtsx_pci_transfer_data(pcr, sg, 1, data_dir == READ, 10000); + if (err < 0) { + ms_clear_error(host); + return err; + } + + rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val); + if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) + return -EIO; + + return 0; +} + +static int ms_write_bytes(struct realtek_pci_ms *host, u8 tpc, + u8 cfg, u8 cnt, u8 *data, u8 *int_reg) +{ + struct rtsx_pcr *pcr = host->pcr; + int err, i; + + dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc); + + if (!data) + return -EINVAL; + + rtsx_pci_init_cmd(pcr); + + for (i = 0; i < cnt; i++) + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, + PPBUF_BASE2 + i, 0xFF, data[i]); + if (cnt % 2) + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, + PPBUF_BASE2 + i, 0xFF, 0xFF); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER, + 0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES); + rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER, + MS_TRANSFER_END, MS_TRANSFER_END); + if (int_reg) + rtsx_pci_add_cmd(pcr, READ_REG_CMD, MS_TRANS_CFG, 0, 0); + + err = rtsx_pci_send_cmd(pcr, 5000); + if (err < 0) { + u8 val; + + rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val); + dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val); + + if (int_reg) + *int_reg = val & 0x0F; + + ms_print_debug_regs(host); + + ms_clear_error(host); + + if (!(tpc & 0x08)) { + if (val & MS_CRC16_ERR) + return -EIO; + } else { + if (!(val & 0x80)) { + if (val & (MS_INT_ERR | MS_INT_CMDNK)) + return -EIO; + } + } + + return -ETIMEDOUT; + } + + if (int_reg) { + u8 *ptr = rtsx_pci_get_cmd_data(pcr) + 1; + *int_reg = *ptr & 0x0F; + } + + return 0; +} + +static int ms_read_bytes(struct realtek_pci_ms *host, u8 tpc, + u8 cfg, u8 cnt, u8 *data, u8 *int_reg) +{ + struct rtsx_pcr *pcr = host->pcr; + int err, i; + u8 *ptr; + + dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc); + + if (!data) + return -EINVAL; + + rtsx_pci_init_cmd(pcr); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER, + 0xFF, MS_TRANSFER_START | MS_TM_READ_BYTES); + rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER, + MS_TRANSFER_END, MS_TRANSFER_END); + for (i = 0; i < cnt - 1; i++) + rtsx_pci_add_cmd(pcr, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0); + if (cnt % 2) + rtsx_pci_add_cmd(pcr, READ_REG_CMD, PPBUF_BASE2 + cnt, 0, 0); + else + rtsx_pci_add_cmd(pcr, READ_REG_CMD, + PPBUF_BASE2 + cnt - 1, 0, 0); + if (int_reg) + rtsx_pci_add_cmd(pcr, READ_REG_CMD, MS_TRANS_CFG, 0, 0); + + err = rtsx_pci_send_cmd(pcr, 5000); + if (err < 0) { + u8 val; + + rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val); + dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val); + + if (int_reg) + *int_reg = val & 0x0F; + + ms_print_debug_regs(host); + + ms_clear_error(host); + + if (!(tpc & 0x08)) { + if (val & MS_CRC16_ERR) + return -EIO; + } else { + if (!(val & 0x80)) { + if (val & (MS_INT_ERR | MS_INT_CMDNK)) + return -EIO; + } + } + + return -ETIMEDOUT; + } + + ptr = rtsx_pci_get_cmd_data(pcr) + 1; + for (i = 0; i < cnt; i++) + data[i] = *ptr++; + + if (int_reg) + *int_reg = *ptr & 0x0F; + + return 0; +} + +static int rtsx_pci_ms_issue_cmd(struct realtek_pci_ms *host) +{ + struct memstick_request *req = host->req; + int err = 0; + u8 cfg = 0, int_reg; + + dev_dbg(ms_dev(host), "%s\n", __func__); + + if (req->need_card_int) { + if (host->ifmode != MEMSTICK_SERIAL) + cfg = WAIT_INT; + } + + if (req->long_data) { + err = ms_transfer_data(host, req->data_dir, + req->tpc, cfg, &(req->sg)); + } else { + if (req->data_dir == READ) { + err = ms_read_bytes(host, req->tpc, cfg, + req->data_len, req->data, &int_reg); + } else { + err = ms_write_bytes(host, req->tpc, cfg, + req->data_len, req->data, &int_reg); + } + } + if (err < 0) + return err; + + if (req->need_card_int && (host->ifmode == MEMSTICK_SERIAL)) { + err = ms_read_bytes(host, MS_TPC_GET_INT, + NO_WAIT_INT, 1, &int_reg, NULL); + if (err < 0) + return err; + } + + if (req->need_card_int) { + dev_dbg(ms_dev(host), "int_reg: 0x%02x\n", int_reg); + + if (int_reg & MS_INT_CMDNK) + req->int_reg |= MEMSTICK_INT_CMDNAK; + if (int_reg & MS_INT_BREQ) + req->int_reg |= MEMSTICK_INT_BREQ; + if (int_reg & MS_INT_ERR) + req->int_reg |= MEMSTICK_INT_ERR; + if (int_reg & MS_INT_CED) + req->int_reg |= MEMSTICK_INT_CED; + } + + return 0; +} + +static void rtsx_pci_ms_handle_req(struct work_struct *work) +{ + struct realtek_pci_ms *host = container_of(work, + struct realtek_pci_ms, handle_req); + struct rtsx_pcr *pcr = host->pcr; + struct memstick_host *msh = host->msh; + int rc; + + mutex_lock(&pcr->pcr_mutex); + + rtsx_pci_start_run(pcr); + + rtsx_pci_switch_clock(host->pcr, host->clock, host->ssc_depth, + false, true, false); + rtsx_pci_write_register(pcr, CARD_SELECT, 0x07, MS_MOD_SEL); + rtsx_pci_write_register(pcr, CARD_SHARE_MODE, + CARD_SHARE_MASK, CARD_SHARE_48_MS); + + if (!host->req) { + do { + rc = memstick_next_req(msh, &host->req); + dev_dbg(ms_dev(host), "next req %d\n", rc); + + if (!rc) + host->req->error = rtsx_pci_ms_issue_cmd(host); + } while (!rc); + } + + mutex_unlock(&pcr->pcr_mutex); +} + +static void rtsx_pci_ms_request(struct memstick_host *msh) +{ + struct realtek_pci_ms *host = memstick_priv(msh); + + dev_dbg(ms_dev(host), "--> %s\n", __func__); + + schedule_work(&host->handle_req); +} + +static int rtsx_pci_ms_set_param(struct memstick_host *msh, + enum memstick_param param, int value) +{ + struct realtek_pci_ms *host = memstick_priv(msh); + struct rtsx_pcr *pcr = host->pcr; + unsigned int clock = 0; + u8 ssc_depth = 0; + int err; + + dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n", + __func__, param, value); + + switch (param) { + case MEMSTICK_POWER: + if (value == MEMSTICK_POWER_ON) + err = ms_power_on(host); + else if (value == MEMSTICK_POWER_OFF) + err = ms_power_off(host); + else + return -EINVAL; + break; + + case MEMSTICK_INTERFACE: + if (value == MEMSTICK_SERIAL) { + clock = 19000000; + ssc_depth = RTSX_SSC_DEPTH_500K; + + err = rtsx_pci_write_register(pcr, MS_CFG, + 0x18, MS_BUS_WIDTH_1); + if (err < 0) + return err; + } else if (value == MEMSTICK_PAR4) { + clock = 39000000; + ssc_depth = RTSX_SSC_DEPTH_1M; + + err = rtsx_pci_write_register(pcr, MS_CFG, + 0x58, MS_BUS_WIDTH_4 | PUSH_TIME_ODD); + if (err < 0) + return err; + } else { + return -EINVAL; + } + + err = rtsx_pci_switch_clock(pcr, clock, + ssc_depth, false, true, false); + if (err < 0) + return err; + + host->ssc_depth = ssc_depth; + host->clock = clock; + host->ifmode = value; + break; + } + + return 0; +} + +#ifdef CONFIG_PM + +static int rtsx_pci_ms_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct realtek_pci_ms *host = platform_get_drvdata(pdev); + struct memstick_host *msh = host->msh; + + dev_dbg(ms_dev(host), "--> %s\n", __func__); + + memstick_suspend_host(msh); + return 0; +} + +static int rtsx_pci_ms_resume(struct platform_device *pdev) +{ + struct realtek_pci_ms *host = platform_get_drvdata(pdev); + struct memstick_host *msh = host->msh; + + dev_dbg(ms_dev(host), "--> %s\n", __func__); + + memstick_resume_host(msh); + return 0; +} + +#else /* CONFIG_PM */ + +#define rtsx_pci_ms_suspend NULL +#define rtsx_pci_ms_resume NULL + +#endif /* CONFIG_PM */ + +static void rtsx_pci_ms_card_event(struct platform_device *pdev) +{ + struct realtek_pci_ms *host = platform_get_drvdata(pdev); + + memstick_detect_change(host->msh); +} + +static int rtsx_pci_ms_drv_probe(struct platform_device *pdev) +{ + struct memstick_host *msh; + struct realtek_pci_ms *host; + struct rtsx_pcr *pcr; + struct pcr_handle *handle = pdev->dev.platform_data; + int rc; + + if (!handle) + return -ENXIO; + + pcr = handle->pcr; + if (!pcr) + return -ENXIO; + + dev_dbg(&(pdev->dev), + ": Realtek PCI-E Memstick controller found\n"); + + msh = memstick_alloc_host(sizeof(*host), &pdev->dev); + if (!msh) + return -ENOMEM; + + host = memstick_priv(msh); + host->pcr = pcr; + host->msh = msh; + host->pdev = pdev; + platform_set_drvdata(pdev, host); + pcr->slots[RTSX_MS_CARD].p_dev = pdev; + pcr->slots[RTSX_MS_CARD].card_event = rtsx_pci_ms_card_event; + + mutex_init(&host->host_mutex); + + INIT_WORK(&host->handle_req, rtsx_pci_ms_handle_req); + msh->request = rtsx_pci_ms_request; + msh->set_param = rtsx_pci_ms_set_param; + msh->caps = MEMSTICK_CAP_PAR4; + + rc = memstick_add_host(msh); + if (rc) { + memstick_free_host(msh); + return rc; + } + + return 0; +} + +static int rtsx_pci_ms_drv_remove(struct platform_device *pdev) +{ + struct realtek_pci_ms *host = platform_get_drvdata(pdev); + struct rtsx_pcr *pcr; + struct memstick_host *msh; + int rc; + + if (!host) + return 0; + + pcr = host->pcr; + pcr->slots[RTSX_MS_CARD].p_dev = NULL; + pcr->slots[RTSX_MS_CARD].card_event = NULL; + msh = host->msh; + host->eject = true; + + mutex_lock(&host->host_mutex); + if (host->req) { + dev_dbg(&(pdev->dev), + "%s: Controller removed during transfer\n", + dev_name(&msh->dev)); + + rtsx_pci_complete_unfinished_transfer(pcr); + + host->req->error = -ENOMEDIUM; + do { + rc = memstick_next_req(msh, &host->req); + if (!rc) + host->req->error = -ENOMEDIUM; + } while (!rc); + } + mutex_unlock(&host->host_mutex); + + memstick_remove_host(msh); + memstick_free_host(msh); + + platform_set_drvdata(pdev, NULL); + + dev_dbg(&(pdev->dev), + ": Realtek PCI-E Memstick controller has been removed\n"); + + return 0; +} + +static struct platform_device_id rtsx_pci_ms_ids[] = { + { + .name = DRV_NAME_RTSX_PCI_MS, + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(platform, rtsx_pci_ms_ids); + +static struct platform_driver rtsx_pci_ms_driver = { + .probe = rtsx_pci_ms_drv_probe, + .remove = rtsx_pci_ms_drv_remove, + .id_table = rtsx_pci_ms_ids, + .suspend = rtsx_pci_ms_suspend, + .resume = rtsx_pci_ms_resume, + .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME_RTSX_PCI_MS, + }, +}; +module_platform_driver(rtsx_pci_ms_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Wei WANG "); +MODULE_DESCRIPTION("Realtek PCI-E Memstick Card Host Driver"); -- cgit v1.2.3 From 04bfd1dfb2c0ef236553d205bd95be02792c3396 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 15 Nov 2012 17:32:53 -0800 Subject: drivers: mfd: fix dependencies for MFD_RTSX_PCI We need to include MFD_CORE if this option is enabled, otherwise we get build errors. Cc: Wei WANG Cc: Arnd Bergmann Cc: Borislav Petkov Signed-off-by: Greg Kroah-Hartman --- drivers/mfd/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 867af072d48..2c10938b356 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -66,6 +66,7 @@ config MFD_SM501_GPIO config MFD_RTSX_PCI tristate "Support for Realtek PCI-E card reader" depends on PCI + select MFD_CORE help This supports for Realtek PCI-Express card reader including rts5209, rts5229, rtl8411, etc. Realtek card reader supports access to many -- cgit v1.2.3 From ebf1b764aa5cb3b4bfe2e96674f1b559f7c37e64 Mon Sep 17 00:00:00 2001 From: Mark Rusk Date: Tue, 6 Nov 2012 14:33:13 -0600 Subject: misc: hpilo: ignore auxiliary HP iLO BMC's This patch ignores auxiliary HP Lights-Out (iLO) management controllers. All HP iLO controllers that have had the PCI subsystem device ID set to 0x1979 by the BIOS are ignored. Also changes default number of channels to 16 and bumps the version of the module from 1.3 to 1.4. Signed-off-by: Mark Rusk ---- drivers/misc/hpilo.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) Signed-off-by: Greg Kroah-Hartman --- drivers/misc/hpilo.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 12ccdf94e4f..b362d938e92 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -30,7 +30,7 @@ static struct class *ilo_class; static unsigned int ilo_major; -static unsigned int max_ccb = MIN_CCB; +static unsigned int max_ccb = 16; static char ilo_hwdev[MAX_ILO_DEV]; static inline int get_entry_id(int entry) @@ -725,6 +725,9 @@ static void ilo_remove(struct pci_dev *pdev) int i, minor; struct ilo_hwinfo *ilo_hw = pci_get_drvdata(pdev); + if (!ilo_hw) + return; + clear_device(ilo_hw); minor = MINOR(ilo_hw->cdev.dev); @@ -751,9 +754,13 @@ static void ilo_remove(struct pci_dev *pdev) static int __devinit ilo_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - int devnum, minor, start, error; + int devnum, minor, start, error = 0; struct ilo_hwinfo *ilo_hw; + /* Ignore subsystem_device = 0x1979 (set by BIOS) */ + if (pdev->subsystem_device == 0x1979) + goto out; + if (max_ccb > MAX_CCB) max_ccb = MAX_CCB; else if (max_ccb < MIN_CCB) @@ -892,14 +899,14 @@ static void __exit ilo_exit(void) class_destroy(ilo_class); } -MODULE_VERSION("1.3"); +MODULE_VERSION("1.4"); MODULE_ALIAS(ILO_NAME); MODULE_DESCRIPTION(ILO_NAME); MODULE_AUTHOR("David Altobelli "); MODULE_LICENSE("GPL v2"); module_param(max_ccb, uint, 0444); -MODULE_PARM_DESC(max_ccb, "Maximum number of HP iLO channels to attach (8)"); +MODULE_PARM_DESC(max_ccb, "Maximum number of HP iLO channels to attach (16)"); module_init(ilo_init); module_exit(ilo_exit); -- cgit v1.2.3 From 73050d7144272f2485e22685fb266c9a6c2eb2d6 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 5 Nov 2012 15:04:35 -0800 Subject: drivers/uwb: remove depends on CONFIG_EXPERIMENTAL The CONFIG_EXPERIMENTAL config item has not carried much meaning for a while now and is almost always enabled by default. As agreed during the Linux kernel summit, remove it from any "depends on" lines in Kconfigs. Signed-off-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/uwb/Kconfig b/drivers/uwb/Kconfig index d100f54ed65..2431eedbe6a 100644 --- a/drivers/uwb/Kconfig +++ b/drivers/uwb/Kconfig @@ -3,8 +3,7 @@ # menuconfig UWB - tristate "Ultra Wideband devices (EXPERIMENTAL)" - depends on EXPERIMENTAL + tristate "Ultra Wideband devices" depends on PCI default n help -- cgit v1.2.3 From ba2d8ce9db0a61505362bb17b8899df3d3326146 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 8 Nov 2012 12:47:41 -0600 Subject: cdc-acm: implement TIOCSSERIAL to avoid blocking close(2) Some devices (ex Nokia C7) simply don't respond at all when data is sent to some of their USB interfaces. The data gets stuck in the TTYs queue and sits there until close(2), which them blocks because closing_wait defaults to 30 seconds (even though the fd is O_NONBLOCK). This is rarely desired. Implement the standard mechanism to adjust closing_wait and let applications handle it how they want to. See also 02303f73373aa1da19dbec510ec5a4e2576f9610 for usb_wwan.c. Signed-off-by: Dan Williams Cc: stable Acked-by: Oliver Neukum Tested-by: Aleksander Morgado Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 6e49ec6f3ad..8d809a811e1 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -787,6 +787,10 @@ static int get_serial_info(struct acm *acm, struct serial_struct __user *info) tmp.flags = ASYNC_LOW_LATENCY; tmp.xmit_fifo_size = acm->writesize; tmp.baud_base = le32_to_cpu(acm->line.dwDTERate); + tmp.close_delay = acm->port.close_delay / 10; + tmp.closing_wait = acm->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? + ASYNC_CLOSING_WAIT_NONE : + acm->port.closing_wait / 10; if (copy_to_user(info, &tmp, sizeof(tmp))) return -EFAULT; @@ -794,6 +798,37 @@ static int get_serial_info(struct acm *acm, struct serial_struct __user *info) return 0; } +static int set_serial_info(struct acm *acm, + struct serial_struct __user *newinfo) +{ + struct serial_struct new_serial; + unsigned int closing_wait, close_delay; + int retval = 0; + + if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) + return -EFAULT; + + close_delay = new_serial.close_delay * 10; + closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? + ASYNC_CLOSING_WAIT_NONE : new_serial.closing_wait * 10; + + mutex_lock(&acm->port.mutex); + + if (!capable(CAP_SYS_ADMIN)) { + if ((close_delay != acm->port.close_delay) || + (closing_wait != acm->port.closing_wait)) + retval = -EPERM; + else + retval = -EOPNOTSUPP; + } else { + acm->port.close_delay = close_delay; + acm->port.closing_wait = closing_wait; + } + + mutex_unlock(&acm->port.mutex); + return retval; +} + static int acm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -804,6 +839,9 @@ static int acm_tty_ioctl(struct tty_struct *tty, case TIOCGSERIAL: /* gets serial port data */ rv = get_serial_info(acm, (struct serial_struct __user *) arg); break; + case TIOCSSERIAL: + rv = set_serial_info(acm, (struct serial_struct __user *) arg); + break; } return rv; -- cgit v1.2.3 From ff84f0e9f70cde6de1ba7c7f6156c8c3c98af383 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 9 Nov 2012 09:44:41 +0800 Subject: Revert "usb: otg: mxs-phy: Fix mx23 operation" The real reason causes mx23 fail are: - Calling mxs_phy_hw_init(mxs_phy) again at connection - Error connect/disconnect nodity at hub.c The coming patch will fix above two problems, Mike Thompson tested his hardware works OK after commented out this delay setting. This reverts commit 363366cf61c544ea476f3d220f43a95cb03014f5. Signed-off-by: Peter Chen Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/mxs-phy.c | 38 +++----------------------------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c index 88db976647c..c1a67cb8e24 100644 --- a/drivers/usb/otg/mxs-phy.c +++ b/drivers/usb/otg/mxs-phy.c @@ -20,7 +20,6 @@ #include #include #include -#include #define DRIVER_NAME "mxs_phy" @@ -35,16 +34,9 @@ #define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14) #define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1) -/* - * Amount of delay in miliseconds to safely enable ENHOSTDISCONDETECT bit - * so that connection and reset processing can be completed for the root hub. - */ -#define MXY_PHY_ENHOSTDISCONDETECT_DELAY 250 - struct mxs_phy { struct usb_phy phy; struct clk *clk; - struct delayed_work enhostdiscondetect_work; }; #define to_mxs_phy(p) container_of((p), struct mxs_phy, phy) @@ -70,7 +62,6 @@ static int mxs_phy_init(struct usb_phy *phy) clk_prepare_enable(mxs_phy->clk); mxs_phy_hw_init(mxs_phy); - INIT_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work, NULL); return 0; } @@ -85,34 +76,13 @@ static void mxs_phy_shutdown(struct usb_phy *phy) clk_disable_unprepare(mxs_phy->clk); } -static void mxs_phy_enhostdiscondetect_delay(struct work_struct *ws) -{ - struct mxs_phy *mxs_phy = container_of(ws, struct mxs_phy, - enhostdiscondetect_work.work); - - /* Enable HOSTDISCONDETECT after delay. */ - dev_dbg(mxs_phy->phy.dev, "Setting ENHOSTDISCONDETECT\n"); - writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, - mxs_phy->phy.io_priv + HW_USBPHY_CTRL_SET); -} - static int mxs_phy_on_connect(struct usb_phy *phy, int port) { - struct mxs_phy *mxs_phy = to_mxs_phy(phy); - dev_dbg(phy->dev, "Connect on port %d\n", port); - mxs_phy_hw_init(mxs_phy); - - /* - * Delay enabling ENHOSTDISCONDETECT so that connection and - * reset processing can be completed for the root hub. - */ - dev_dbg(phy->dev, "Delaying setting ENHOSTDISCONDETECT\n"); - PREPARE_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work, - mxs_phy_enhostdiscondetect_delay); - schedule_delayed_work(&mxs_phy->enhostdiscondetect_work, - msecs_to_jiffies(MXY_PHY_ENHOSTDISCONDETECT_DELAY)); + mxs_phy_hw_init(to_mxs_phy(phy)); + writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, + phy->io_priv + HW_USBPHY_CTRL_SET); return 0; } @@ -121,8 +91,6 @@ static int mxs_phy_on_disconnect(struct usb_phy *phy, int port) { dev_dbg(phy->dev, "Disconnect on port %d\n", port); - /* No need to delay before clearing ENHOSTDISCONDETECT. */ - dev_dbg(phy->dev, "Clearing ENHOSTDISCONDETECT\n"); writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, phy->io_priv + HW_USBPHY_CTRL_CLR); -- cgit v1.2.3 From 0e1a024d1a16ae1b3d01495d3bcd34f285724e7e Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 9 Nov 2012 09:44:42 +0800 Subject: usb: mxs-phy: re-init phy during the connection is useless As phy is working, re-init phy may cause unexpected results Signed-off-by: Peter Chen Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/otg/mxs-phy.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c index c1a67cb8e24..5b09f3339de 100644 --- a/drivers/usb/otg/mxs-phy.c +++ b/drivers/usb/otg/mxs-phy.c @@ -80,7 +80,6 @@ static int mxs_phy_on_connect(struct usb_phy *phy, int port) { dev_dbg(phy->dev, "Connect on port %d\n", port); - mxs_phy_hw_init(to_mxs_phy(phy)); writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, phy->io_priv + HW_USBPHY_CTRL_SET); -- cgit v1.2.3 From b76baa8154335a906be85f2b32d6bd1876900133 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 9 Nov 2012 09:44:43 +0800 Subject: usb: refine phy notify operation during connection and disconnection At commit 925aa46ba963a4da6d8ee6ab1d04a02ffa8db62b, Richard Zhao adds the phy notification callback when port change occurs. In fact, this phy notification should be added according to below rules: 1. Only set HW_USBPHY_CTRL.ENHOSTDISCONDETECT during high speed host mode. 2. Do not set HW_USBPHY_CTRL.ENHOSTDISCONDETECT during the reset and speed negotiation period. 3. Do not set HW_USBPHY_CTRL.ENHOSTDISCONDETECT during host suspend/resume sequence. Please refer: i.mx23RM(page: 413) for below rules. http://www.freescale.com/files/dsp/doc/ref_manual/IMX23RM.pdf Freescale i.MX SoC, i.mx23, i.mx28 and i.mx6(i.mx6SL does not need to follow the 3rd rule) need to follow above rules. Current code set connect notification (HW_USBPHY_CTRL.ENHOSTDISCONDETECT) at hub_port_connect_change, it conflicts with above the 2th rule. The correct notification setting method should be: 1. Set connect notify after the second bus reset. 2. Set disconnect notify after disconnection. Signed-off-by: Peter Chen Tested-by: Mike Thompson Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 90accdefdc7..8391538d688 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4038,6 +4038,9 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, if (retval) goto fail; + if (hcd->phy && !hdev->parent) + usb_phy_notify_connect(hcd->phy, port1); + /* * Some superspeed devices have finished the link training process * and attached to a superspeed hub port, but the device descriptor @@ -4232,8 +4235,12 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, } /* Disconnect any existing devices under this port */ - if (udev) + if (udev) { + if (hcd->phy && !hdev->parent && + !(portstatus & USB_PORT_STAT_CONNECTION)) + usb_phy_notify_disconnect(hcd->phy, port1); usb_disconnect(&hub->ports[port1 - 1]->child); + } clear_bit(port1, hub->change_bits); /* We can forget about a "removed" device when there's a physical @@ -4256,13 +4263,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, } } - if (hcd->phy && !hdev->parent) { - if (portstatus & USB_PORT_STAT_CONNECTION) - usb_phy_notify_connect(hcd->phy, port1); - else - usb_phy_notify_disconnect(hcd->phy, port1); - } - /* Return now if debouncing failed or nothing is connected or * the device was "removed". */ -- cgit v1.2.3 From ac96511bb5cf92bad97ffc2249f75e45eb70301d Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 9 Nov 2012 09:44:44 +0800 Subject: usb: phy: change phy notify connect/disconnect API The old parameter "port" is useless for phy notify, as one usb phy is only for one usb port. New parameter "speed" stands for the device's speed which is on the port, this "speed" parameter is needed at some platforms which will do some phy operations according to device's speed. Signed-off-by: Peter Chen Tested-by: Mike Thompson Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 4 ++-- drivers/usb/otg/mxs-phy.c | 22 ++++++++++++++-------- include/linux/usb/phy.h | 15 +++++++++------ 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8391538d688..a815fd2cc5e 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -4039,7 +4039,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, goto fail; if (hcd->phy && !hdev->parent) - usb_phy_notify_connect(hcd->phy, port1); + usb_phy_notify_connect(hcd->phy, udev->speed); /* * Some superspeed devices have finished the link training process @@ -4238,7 +4238,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, if (udev) { if (hcd->phy && !hdev->parent && !(portstatus & USB_PORT_STAT_CONNECTION)) - usb_phy_notify_disconnect(hcd->phy, port1); + usb_phy_notify_disconnect(hcd->phy, udev->speed); usb_disconnect(&hub->ports[port1 - 1]->child); } clear_bit(port1, hub->change_bits); diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c index 5b09f3339de..9a3caeecc50 100644 --- a/drivers/usb/otg/mxs-phy.c +++ b/drivers/usb/otg/mxs-phy.c @@ -76,22 +76,28 @@ static void mxs_phy_shutdown(struct usb_phy *phy) clk_disable_unprepare(mxs_phy->clk); } -static int mxs_phy_on_connect(struct usb_phy *phy, int port) +static int mxs_phy_on_connect(struct usb_phy *phy, + enum usb_device_speed speed) { - dev_dbg(phy->dev, "Connect on port %d\n", port); + dev_dbg(phy->dev, "%s speed device has connected\n", + (speed == USB_SPEED_HIGH) ? "high" : "non-high"); - writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, - phy->io_priv + HW_USBPHY_CTRL_SET); + if (speed == USB_SPEED_HIGH) + writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, + phy->io_priv + HW_USBPHY_CTRL_SET); return 0; } -static int mxs_phy_on_disconnect(struct usb_phy *phy, int port) +static int mxs_phy_on_disconnect(struct usb_phy *phy, + enum usb_device_speed speed) { - dev_dbg(phy->dev, "Disconnect on port %d\n", port); + dev_dbg(phy->dev, "%s speed device has disconnected\n", + (speed == USB_SPEED_HIGH) ? "high" : "non-high"); - writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, - phy->io_priv + HW_USBPHY_CTRL_CLR); + if (speed == USB_SPEED_HIGH) + writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT, + phy->io_priv + HW_USBPHY_CTRL_CLR); return 0; } diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index 06b5bae35b2..a29ae1eb934 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -10,6 +10,7 @@ #define __LINUX_USB_PHY_H #include +#include enum usb_phy_events { USB_EVENT_NONE, /* no events or cable disconnected */ @@ -99,8 +100,10 @@ struct usb_phy { int suspend); /* notify phy connect status change */ - int (*notify_connect)(struct usb_phy *x, int port); - int (*notify_disconnect)(struct usb_phy *x, int port); + int (*notify_connect)(struct usb_phy *x, + enum usb_device_speed speed); + int (*notify_disconnect)(struct usb_phy *x, + enum usb_device_speed speed); }; @@ -189,19 +192,19 @@ usb_phy_set_suspend(struct usb_phy *x, int suspend) } static inline int -usb_phy_notify_connect(struct usb_phy *x, int port) +usb_phy_notify_connect(struct usb_phy *x, enum usb_device_speed speed) { if (x->notify_connect) - return x->notify_connect(x, port); + return x->notify_connect(x, speed); else return 0; } static inline int -usb_phy_notify_disconnect(struct usb_phy *x, int port) +usb_phy_notify_disconnect(struct usb_phy *x, enum usb_device_speed speed) { if (x->notify_disconnect) - return x->notify_disconnect(x, port); + return x->notify_disconnect(x, speed); else return 0; } -- cgit v1.2.3 From ddc150f7a33ae0c9cb16eaac3641abc00f56316f Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Fri, 16 Nov 2012 02:46:28 +0100 Subject: ACPI / PM: Add check preventing transitioning to non-D0 state from D3. No power transitioning from D3 state up to a non-D0 state is allowed so make acpi_device_set_power() fail and complain if such a transition is attempted. Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/bus.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 07a20ee3e69..1f0d457ecbc 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -306,6 +306,12 @@ int acpi_device_set_power(struct acpi_device *device, int state) * a lower-powered state. */ if (state < device->power.state) { + if (device->power.state >= ACPI_STATE_D3_HOT && + state != ACPI_STATE_D0) { + printk(KERN_WARNING PREFIX + "Cannot transition to non-D0 state from D3\n"); + return -ENODEV; + } if (device->power.flags.power_resources) { result = acpi_power_transition(device, state); if (result) -- cgit v1.2.3 From d6ff85513d523551177b1564b62d64c864b97d68 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 13 Nov 2012 17:47:13 +0100 Subject: driver: platform: fix documentation for platform_get_irq_byname Probably due to copy&paste, some stuff was simply forgotten. Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 1e8f65420db..d5e3b45a81f 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -122,7 +122,7 @@ struct resource *platform_get_resource_byname(struct platform_device *dev, EXPORT_SYMBOL_GPL(platform_get_resource_byname); /** - * platform_get_irq - get an IRQ for a device + * platform_get_irq_byname - get an IRQ for a device by name * @dev: platform device * @name: IRQ name */ -- cgit v1.2.3 From 7dd2517c39c1334c9431c0732487e16f752ca09a Mon Sep 17 00:00:00 2001 From: Yan Hong Date: Thu, 8 Nov 2012 16:10:17 -0800 Subject: fs/debugsfs: remove unnecessary inode->i_private initialization inode->i_private is promised to be NULL on allocation, no need to set it explicitly. Signed-off-by: Yan Hong Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- fs/debugfs/inode.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index b607d92cdf2..153bb1e42e6 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -59,7 +59,6 @@ static struct inode *debugfs_get_inode(struct super_block *sb, umode_t mode, dev case S_IFDIR: inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; - inode->i_private = NULL; /* directory inodes start off with i_nlink == 2 * (for "." entry) */ -- cgit v1.2.3 From 83ca897d170919035acfe5c472479941847e93cc Mon Sep 17 00:00:00 2001 From: Fu Wei Date: Fri, 16 Nov 2012 01:01:56 +0800 Subject: Documentation: Chinese translation of Documentation/arm/kernel_user_helpers.txt This is a Chinese translated version of Documentation/arm/kernel_user_helpers.txt Signed-off-by: Fu Wei Signed-off-by: Greg Kroah-Hartman --- Documentation/zh_CN/arm/kernel_user_helpers.txt | 284 ++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 Documentation/zh_CN/arm/kernel_user_helpers.txt diff --git a/Documentation/zh_CN/arm/kernel_user_helpers.txt b/Documentation/zh_CN/arm/kernel_user_helpers.txt new file mode 100644 index 00000000000..cd7fc8f34cf --- /dev/null +++ b/Documentation/zh_CN/arm/kernel_user_helpers.txt @@ -0,0 +1,284 @@ +Chinese translated version of Documentation/arm/kernel_user_helpers.txt + +If you have any comment or update to the content, please contact the +original document maintainer directly. However, if you have a problem +communicating in English you can also ask the Chinese maintainer for +help. Contact the Chinese maintainer if this translation is outdated +or if there is a problem with the translation. + +Maintainer: Nicolas Pitre + Dave Martin +Chinese maintainer: Fu Wei +--------------------------------------------------------------------- +Documentation/arm/kernel_user_helpers.txt 的中文翻译 + +如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 +交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 +译存在问题,请联系中文版维护者。 +英文版维护者: Nicolas Pitre + Dave Martin +中文版维护者: 傅炜 Fu Wei +中文版翻译者: 傅炜 Fu Wei +中文版校译者: 宋冬生 Dongsheng Song + 傅炜 Fu Wei + + +以下为正文 +--------------------------------------------------------------------- +内核提供的用户空间辅助代码 +========================= + +在内核内存空间的固定地址处,有一个由内核提供并可从用户空间访问的代码 +段。它用于向用户空间提供因在许多 ARM CPU 中未实现的特性和/或指令而需 +内核提供帮助的某些操作。这些代码直接在用户模式下执行的想法是为了获得 +最佳效率,但那些与内核计数器联系过于紧密的部分,则被留给了用户库实现。 +事实上,此代码甚至可能因不同的 CPU 而异,这取决于其可用的指令集或它 +是否为 SMP 系统。换句话说,内核保留在不作出警告的情况下根据需要更改 +这些代码的权利。只有本文档描述的入口及其结果是保证稳定的。 + +这与完全成熟的 VDSO 实现不同(但两者并不冲突),尽管如此,VDSO 可阻止 +某些通过常量高效跳转到那些代码段的汇编技巧。且由于那些代码段在返回用户 +代码前仅使用少量的代码周期,则一个 VDSO 间接远程调用将会在这些简单的 +操作上增加一个可测量的开销。 + +在对那些拥有原生支持的新型处理器进行代码优化时,仅在已为其他操作使用 +了类似的新增指令,而导致二进制结果已与早期 ARM 处理器不兼容的情况下, +用户空间才应绕过这些辅助代码,并在内联函数中实现这些操作(无论是通过 +编译器在代码中直接放置,还是作为库函数调用实现的一部分)。也就是说, +如果你编译的代码不会为了其他目的使用新指令,则不要仅为了避免使用这些 +内核辅助代码,导致二进制程序无法在早期处理器上运行。 + +新的辅助代码可能随着时间的推移而增加,所以新内核中的某些辅助代码在旧 +内核中可能不存在。因此,程序必须在对任何辅助代码调用假设是安全之前, +检测 __kuser_helper_version 的值(见下文)。理想情况下,这种检测应该 +只在进程启动时执行一次;如果内核版本不支持所需辅助代码,则该进程可尽早 +中止执行。 + +kuser_helper_version +-------------------- + +位置: 0xffff0ffc + +参考声明: + + extern int32_t __kuser_helper_version; + +定义: + + 这个区域包含了当前运行内核实现的辅助代码版本号。用户空间可以通过读 + 取此版本号以确定特定的辅助代码是否存在。 + +使用范例: + +#define __kuser_helper_version (*(int32_t *)0xffff0ffc) + +void check_kuser_version(void) +{ + if (__kuser_helper_version < 2) { + fprintf(stderr, "can't do atomic operations, kernel too old\n"); + abort(); + } +} + +注意: + + 用户空间可以假设这个域的值不会在任何单个进程的生存期内改变。也就 + 是说,这个域可以仅在库的初始化阶段或进程启动阶段读取一次。 + +kuser_get_tls +------------- + +位置: 0xffff0fe0 + +参考原型: + + void * __kuser_get_tls(void); + +输入: + + lr = 返回地址 + +输出: + + r0 = TLS 值 + +被篡改的寄存器: + + 无 + +定义: + + 获取之前通过 __ARM_NR_set_tls 系统调用设置的 TLS 值。 + +使用范例: + +typedef void * (__kuser_get_tls_t)(void); +#define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0) + +void foo() +{ + void *tls = __kuser_get_tls(); + printf("TLS = %p\n", tls); +} + +注意: + + - 仅在 __kuser_helper_version >= 1 时,此辅助代码存在 + (从内核版本 2.6.12 开始)。 + +kuser_cmpxchg +------------- + +位置: 0xffff0fc0 + +参考原型: + + int __kuser_cmpxchg(int32_t oldval, int32_t newval, volatile int32_t *ptr); + +输入: + + r0 = oldval + r1 = newval + r2 = ptr + lr = 返回地址 + +输出: + + r0 = 成功代码 (零或非零) + C flag = 如果 r0 == 0 则置 1,如果 r0 != 0 则清零。 + +被篡改的寄存器: + + r3, ip, flags + +定义: + + 仅在 *ptr 为 oldval 时原子保存 newval 于 *ptr 中。 + 如果 *ptr 被改变,则返回值为零,否则为非零值。 + 如果 *ptr 被改变,则 C flag 也会被置 1,以实现调用代码中的汇编 + 优化。 + +使用范例: + +typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr); +#define __kuser_cmpxchg (*(__kuser_cmpxchg_t *)0xffff0fc0) + +int atomic_add(volatile int *ptr, int val) +{ + int old, new; + + do { + old = *ptr; + new = old + val; + } while(__kuser_cmpxchg(old, new, ptr)); + + return new; +} + +注意: + + - 这个例程已根据需要包含了内存屏障。 + + - 仅在 __kuser_helper_version >= 2 时,此辅助代码存在 + (从内核版本 2.6.12 开始)。 + +kuser_memory_barrier +-------------------- + +位置: 0xffff0fa0 + +参考原型: + + void __kuser_memory_barrier(void); + +输入: + + lr = 返回地址 + +输出: + + 无 + +被篡改的寄存器: + + 无 + +定义: + + 应用于任何需要内存屏障以防止手动数据修改带来的一致性问题,以及 + __kuser_cmpxchg 中。 + +使用范例: + +typedef void (__kuser_dmb_t)(void); +#define __kuser_dmb (*(__kuser_dmb_t *)0xffff0fa0) + +注意: + + - 仅在 __kuser_helper_version >= 3 时,此辅助代码存在 + (从内核版本 2.6.15 开始)。 + +kuser_cmpxchg64 +--------------- + +位置: 0xffff0f60 + +参考原型: + + int __kuser_cmpxchg64(const int64_t *oldval, + const int64_t *newval, + volatile int64_t *ptr); + +输入: + + r0 = 指向 oldval + r1 = 指向 newval + r2 = 指向目标值 + lr = 返回地址 + +输出: + + r0 = 成功代码 (零或非零) + C flag = 如果 r0 == 0 则置 1,如果 r0 != 0 则清零。 + +被篡改的寄存器: + + r3, lr, flags + +定义: + + 仅在 *ptr 等于 *oldval 指向的 64 位值时,原子保存 *newval + 指向的 64 位值于 *ptr 中。如果 *ptr 被改变,则返回值为零, + 否则为非零值。 + + 如果 *ptr 被改变,则 C flag 也会被置 1,以实现调用代码中的汇编 + 优化。 + +使用范例: + +typedef int (__kuser_cmpxchg64_t)(const int64_t *oldval, + const int64_t *newval, + volatile int64_t *ptr); +#define __kuser_cmpxchg64 (*(__kuser_cmpxchg64_t *)0xffff0f60) + +int64_t atomic_add64(volatile int64_t *ptr, int64_t val) +{ + int64_t old, new; + + do { + old = *ptr; + new = old + val; + } while(__kuser_cmpxchg64(&old, &new, ptr)); + + return new; +} + +注意: + + - 这个例程已根据需要包含了内存屏障。 + + - 由于这个过程的代码长度(此辅助代码跨越 2 个常规的 kuser “槽”), + 因此 0xffff0f80 不被作为有效的入口点。 + + - 仅在 __kuser_helper_version >= 5 时,此辅助代码存在 + (从内核版本 3.1 开始)。 -- cgit v1.2.3 From a6bb87522f42aea056585282a70de7512d297323 Mon Sep 17 00:00:00 2001 From: Harvey Yang Date: Thu, 15 Nov 2012 16:32:49 +0800 Subject: usb: usbip: userspace: remove the port state file when detaching port. with the last detached port state file remaining, usbip reports error on attaching. So clean up the state files on detaching. Signed-off-by: Harvey Yang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/userspace/src/usbip_detach.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/staging/usbip/userspace/src/usbip_detach.c b/drivers/staging/usbip/userspace/src/usbip_detach.c index 89bf3c195c2..dac5f065755 100644 --- a/drivers/staging/usbip/userspace/src/usbip_detach.c +++ b/drivers/staging/usbip/userspace/src/usbip_detach.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -46,6 +47,7 @@ static int detach_port(char *port) { int ret; uint8_t portnum; + char path[PATH_MAX+1]; for (unsigned int i=0; i < strlen(port); i++) if (!isdigit(port[i])) { @@ -57,6 +59,13 @@ static int detach_port(char *port) portnum = atoi(port); + /* remove the port state file */ + + snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", portnum); + + remove(path); + rmdir(VHCI_STATE_PATH); + ret = usbip_vhci_driver_open(); if (ret < 0) { err("open vhci_driver"); -- cgit v1.2.3 From bdbd3b38d3bf664e5c04904bd734ac79660e41b5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 15 Nov 2012 17:50:14 -0800 Subject: Staging: ipack: CONFIG_HOTPLUG is always enabled as CONFIG_HOTPLUG is always enabled now, just remove the #ifdef logic in the ipack core for it if was disabled. Cc:Samuel Iglesias Gonsalvez Cc: Jens Taprogge Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/ipack.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index f713ab3e83b..429696bc544 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -85,8 +85,6 @@ static int ipack_bus_remove(struct device *device) return 0; } -#ifdef CONFIG_HOTPLUG - static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env) { struct ipack_device *idev; @@ -104,12 +102,6 @@ static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } -#else /* !CONFIG_HOTPLUG */ - -#define ipack_uevent NULL - -#endif /* !CONFIG_HOTPLUG */ - #define ipack_device_attr(field, format_string) \ static ssize_t \ field##_show(struct device *dev, struct device_attribute *attr, \ -- cgit v1.2.3 From a369aa0eb7082da3d97c63f7d2265fddc84923d3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 15 Nov 2012 17:55:24 -0800 Subject: Staging: ipack: remove last TODO items The code is checkpatch clean, and the logic and flow looks good to me, so I don't think there's anything left to do here. Cc: Samuel Iglesias Gonsalvez Cc: Jens Taprogge Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/TODO | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/ipack/TODO b/drivers/staging/ipack/TODO index ffafe6911a7..e667acf5d33 100644 --- a/drivers/staging/ipack/TODO +++ b/drivers/staging/ipack/TODO @@ -9,12 +9,6 @@ boards. The ipack driver is just an abstraction of the bus providing the common operations between the two kind of boards. -TODO -==== - -checkpatch.pl warnings -cleanup - Contact ======= -- cgit v1.2.3 From bb74ac23b10820d8722c3e1f4add9ef59e703f63 Mon Sep 17 00:00:00 2001 From: Yasuaki Ishimatsu Date: Fri, 16 Nov 2012 02:56:59 +0100 Subject: ACPI: create _SUN sysfs file _SUN method provides the slot unique-ID in the ACPI namespace. And The value is written in Advanced Configuration and Power Interface Specification as follows: "The _SUN value is required to be unique among the slots ofthe same type. It is also recommended that this number match the slot number printed on the physical slot whenever possible." So if we can know the value, we can identify the physical position of the slot in the system. The patch creates "sun" file in sysfs for identifying physical position of the slot. Signed-off-by: Yasuaki Ishimatsu Reviewed-by: Toshi Kani Signed-off-by: Rafael J. Wysocki --- Documentation/ABI/testing/sysfs-devices-sun | 14 ++++++++++++++ drivers/acpi/scan.c | 24 ++++++++++++++++++++++++ include/acpi/acpi_bus.h | 1 + 3 files changed, 39 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-devices-sun diff --git a/Documentation/ABI/testing/sysfs-devices-sun b/Documentation/ABI/testing/sysfs-devices-sun new file mode 100644 index 00000000000..86be9848a77 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-sun @@ -0,0 +1,14 @@ +Whatt: /sys/devices/.../sun +Date: October 2012 +Contact: Yasuaki Ishimatsu +Description: + The file contains a Slot-unique ID which provided by the _SUN + method in the ACPI namespace. The value is written in Advanced + Configuration and Power Interface Specification as follows: + + "The _SUN value is required to be unique among the slots of + the same type. It is also recommended that this number match + the slot number printed on the physical slot whenever possible." + + So reading the sysfs file, we can identify a physical position + of the slot in the system. diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 9d43532d69b..d0b38ab47ab 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -283,11 +283,21 @@ static ssize_t description_show(struct device *dev, } static DEVICE_ATTR(description, 0444, description_show, NULL); +static ssize_t +acpi_device_sun_show(struct device *dev, struct device_attribute *attr, + char *buf) { + struct acpi_device *acpi_dev = to_acpi_device(dev); + + return sprintf(buf, "%lu\n", acpi_dev->pnp.sun); +} +static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); + static int acpi_device_setup_files(struct acpi_device *dev) { struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; acpi_status status; acpi_handle temp; + unsigned long long sun; int result = 0; /* @@ -329,6 +339,16 @@ static int acpi_device_setup_files(struct acpi_device *dev) if (dev->pnp.unique_id) result = device_create_file(&dev->dev, &dev_attr_uid); + status = acpi_evaluate_integer(dev->handle, "_SUN", NULL, &sun); + if (ACPI_SUCCESS(status)) { + dev->pnp.sun = (unsigned long)sun; + result = device_create_file(&dev->dev, &dev_attr_sun); + if (result) + goto end; + } else { + dev->pnp.sun = (unsigned long)-1; + } + /* * If device has _EJ0, 'eject' file is created that is used to trigger * hot-removal function from userland. @@ -360,6 +380,10 @@ static void acpi_device_remove_files(struct acpi_device *dev) if (ACPI_SUCCESS(status)) device_remove_file(&dev->dev, &dev_attr_eject); + status = acpi_get_handle(dev->handle, "_SUN", &temp); + if (ACPI_SUCCESS(status)) + device_remove_file(&dev->dev, &dev_attr_sun); + if (dev->pnp.unique_id) device_remove_file(&dev->dev, &dev_attr_uid); if (dev->flags.bus_address) diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index e8b2877aea3..6f385e5909d 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -179,6 +179,7 @@ struct acpi_device_pnp { acpi_device_name device_name; /* Driver-determined */ acpi_device_class device_class; /* " */ union acpi_object *str_obj; /* unicode string for _STR method */ + unsigned long sun; /* _SUN */ }; #define acpi_device_bid(d) ((d)->pnp.bus_id) -- cgit v1.2.3 From cee31c52df6263555c11cf51ee6ea30637e0cfd1 Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Fri, 16 Nov 2012 10:50:03 +0900 Subject: Revert "sh-sci / PM: Avoid deadlocking runtime PM" This reverts commit 048be431e4 (sh-sci / PM: Avoid deadlocking runtime PM, from Rafael J. Wysocki , 2012-03-09). In order to get console PM work properly, we should implement uart_ops ->pm() operation, rather than sprinkle band-ading runtime PM calls in the driver. Signed-off-by: Shinya Kuribayashi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 6ee59001d61..3d27f4978dd 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1753,8 +1753,6 @@ static int sci_startup(struct uart_port *port) dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); - pm_runtime_put_noidle(port->dev); - sci_port_enable(s); ret = sci_request_irq(s); @@ -1782,8 +1780,6 @@ static void sci_shutdown(struct uart_port *port) sci_free_irq(s); sci_port_disable(s); - - pm_runtime_get_noresume(port->dev); } static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, @@ -2122,7 +2118,6 @@ static int __devinit sci_init_single(struct platform_device *dev, sci_init_gpios(sci_port); pm_runtime_irq_safe(&dev->dev); - pm_runtime_get_noresume(&dev->dev); pm_runtime_enable(&dev->dev); } -- cgit v1.2.3 From 8807ec6c707802cabadc0fe1b035ffefa27f1719 Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Fri, 16 Nov 2012 10:51:01 +0900 Subject: Revert "sh-sci / PM: Use power.irq_safe" This reverts commit 5a50a01bf0 (sh-sci / PM: Use power.irq_safe, from Rafael J. Wysocki , 2011-08-24). In order to get console PM work properly, we should implement uart_ops ->pm() operation, rather than sprinkle band-ading runtime PM calls in the driver. Signed-off-by: Shinya Kuribayashi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 3d27f4978dd..fcac1360c78 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2117,7 +2117,6 @@ static int __devinit sci_init_single(struct platform_device *dev, sci_init_gpios(sci_port); - pm_runtime_irq_safe(&dev->dev); pm_runtime_enable(&dev->dev); } -- cgit v1.2.3 From 00cadbfd1e73fb9951da7d2358c39b561c017ea3 Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Fri, 16 Nov 2012 10:51:24 +0900 Subject: Partially revert "serial: sh-sci: console Runtime PM support" This partially reverts commit 1ba7622094 (serial: sh-sci: console Runtime PM support, from Magnus Damm , 2011-08-03). The generic 'serial_core' can take care of console PM maintenance, so all (or at least the first thing) we have to do to get console PM work properly, is to implement uart_ops ->pm() operation in the sh-sci serial client driver. This patch partially reverts the commit above, but leaving sci_reset() change in place, because sci_reset() is already part of another commit (73c3d53f38 serial: sh-sci: Avoid FIFO clear for MCE toggle.). A revised version of console PM support follows next. Signed-off-by: Shinya Kuribayashi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 53 +-------------------------------------------- 1 file changed, 1 insertion(+), 52 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index fcac1360c78..602d0781c6c 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -99,12 +99,6 @@ struct sci_port { #endif struct notifier_block freq_transition; - -#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE - unsigned short saved_smr; - unsigned short saved_fcr; - unsigned char saved_brr; -#endif }; /* Function prototypes */ @@ -2248,8 +2242,7 @@ static int __devinit serial_console_setup(struct console *co, char *options) if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); - sci_port_disable(sci_port); - + /* TODO: disable clock */ return uart_set_options(port, co, baud, parity, bits, flow); } @@ -2292,46 +2285,6 @@ static int __devinit sci_probe_earlyprintk(struct platform_device *pdev) return 0; } -#define uart_console(port) ((port)->cons->index == (port)->line) - -static int sci_runtime_suspend(struct device *dev) -{ - struct sci_port *sci_port = dev_get_drvdata(dev); - struct uart_port *port = &sci_port->port; - - if (uart_console(port)) { - struct plat_sci_reg *reg; - - sci_port->saved_smr = serial_port_in(port, SCSMR); - sci_port->saved_brr = serial_port_in(port, SCBRR); - - reg = sci_getreg(port, SCFCR); - if (reg->size) - sci_port->saved_fcr = serial_port_in(port, SCFCR); - else - sci_port->saved_fcr = 0; - } - return 0; -} - -static int sci_runtime_resume(struct device *dev) -{ - struct sci_port *sci_port = dev_get_drvdata(dev); - struct uart_port *port = &sci_port->port; - - if (uart_console(port)) { - sci_reset(port); - serial_port_out(port, SCSMR, sci_port->saved_smr); - serial_port_out(port, SCBRR, sci_port->saved_brr); - - if (sci_port->saved_fcr) - serial_port_out(port, SCFCR, sci_port->saved_fcr); - - serial_port_out(port, SCSCR, sci_port->cfg->scscr); - } - return 0; -} - #define SCI_CONSOLE (&serial_console) #else @@ -2341,8 +2294,6 @@ static inline int __devinit sci_probe_earlyprintk(struct platform_device *pdev) } #define SCI_CONSOLE NULL -#define sci_runtime_suspend NULL -#define sci_runtime_resume NULL #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ @@ -2460,8 +2411,6 @@ static int sci_resume(struct device *dev) } static const struct dev_pm_ops sci_dev_pm_ops = { - .runtime_suspend = sci_runtime_suspend, - .runtime_resume = sci_runtime_resume, .suspend = sci_suspend, .resume = sci_resume, }; -- cgit v1.2.3 From 0174e5ca82ba6bd62ab870e5781b72bd5397f1c3 Mon Sep 17 00:00:00 2001 From: Teppei Kamijou Date: Fri, 16 Nov 2012 10:51:55 +0900 Subject: serial: sh-sci: console runtime PM support (revisit) The commit 1ba7622094 (serial: sh-sci: console Runtime PM support, from Magnus Damm , 2011-08-03), tried to support console runtime PM, but unfortunately it didn't work for us for some reason. We did not investigated further at that time, instead would like to propose a different approach. In Linux tty/serial world, to get console PM work properly, a serial client driver does not have to maintain .runtime_suspend()/..resume() calls itself, but can leave console power power management handling to the serial core driver. This patch moves the sh-sci driver in that direction. Notes: * There is room to optimize console runtime PM more aggressively by maintaining additional local runtime PM calls, but as a first step having .pm() operation would suffice. * We still have a couple of direct calls to sci_port_enable/..disable left in the driver. We have to live with them, because they're out of serial core's help. Signed-off-by: Teppei Kamijou Signed-off-by: Shinya Kuribayashi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 602d0781c6c..8aade611d1a 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1747,8 +1747,6 @@ static int sci_startup(struct uart_port *port) dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); - sci_port_enable(s); - ret = sci_request_irq(s); if (unlikely(ret < 0)) return ret; @@ -1772,8 +1770,6 @@ static void sci_shutdown(struct uart_port *port) sci_free_dma(port); sci_free_irq(s); - - sci_port_disable(s); } static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, @@ -1922,6 +1918,21 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, sci_port_disable(s); } +static void sci_pm(struct uart_port *port, unsigned int state, + unsigned int oldstate) +{ + struct sci_port *sci_port = to_sci_port(port); + + switch (state) { + case 3: + sci_port_disable(sci_port); + break; + default: + sci_port_enable(sci_port); + break; + } +} + static const char *sci_type(struct uart_port *port) { switch (port->type) { @@ -2043,6 +2054,7 @@ static struct uart_ops sci_uart_ops = { .startup = sci_startup, .shutdown = sci_shutdown, .set_termios = sci_set_termios, + .pm = sci_pm, .type = sci_type, .release_port = sci_release_port, .request_port = sci_request_port, @@ -2196,16 +2208,12 @@ static void serial_console_write(struct console *co, const char *s, struct uart_port *port = &sci_port->port; unsigned short bits; - sci_port_enable(sci_port); - uart_console_write(port, s, count, serial_console_putchar); /* wait until fifo is empty and last bit has been transmitted */ bits = SCxSR_TDxE(port) | SCxSR_TEND(port); while ((serial_port_in(port, SCxSR) & bits) != bits) cpu_relax(); - - sci_port_disable(sci_port); } static int __devinit serial_console_setup(struct console *co, char *options) @@ -2237,12 +2245,9 @@ static int __devinit serial_console_setup(struct console *co, char *options) if (unlikely(ret != 0)) return ret; - sci_port_enable(sci_port); - if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); - /* TODO: disable clock */ return uart_set_options(port, co, baud, parity, bits, flow); } -- cgit v1.2.3 From 4ffc3cdb642823ebee84538addac7cde1174e314 Mon Sep 17 00:00:00 2001 From: Takashi Yoshii Date: Fri, 16 Nov 2012 10:52:22 +0900 Subject: serial: sh-sci: fix condition test to set SCBRR SCBRR == 0 is valid value (divide by 1). Signed-off-by: Takashi Yoshii Signed-off-by: Shinya Kuribayashi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 8aade611d1a..6c1fddb0e20 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1854,7 +1854,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t, s->cfg->scscr); - if (t > 0) { + if (t >= 0) { if (t >= 256) { serial_port_out(port, SCSMR, (serial_port_in(port, SCSMR) & ~3) | 1); t >>= 2; -- cgit v1.2.3 From 9d482cc353bd0391730730b26e4c2938dc90e477 Mon Sep 17 00:00:00 2001 From: Takashi Yoshii Date: Fri, 16 Nov 2012 10:52:49 +0900 Subject: serial: sh-sci: support lower baud rate Support prescaler 1/16 and 1/64, in addition to current 1 and 1/4. Supporting below 2400bps was dropped long time ago in mainline. Since then, setting lower rate has been resulting in erroneous register value, without indicating any errors through API. This patch adds more prescaler to support lower rates again. This still doesn't check range, but we won't hit the case because even 50bps at 48MHz clock is now supported. Signed-off-by: Takashi Yoshii Signed-off-by: Shinya Kuribayashi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 6c1fddb0e20..a54c47d0fd6 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1815,7 +1815,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, { struct sci_port *s = to_sci_port(port); struct plat_sci_reg *reg; - unsigned int baud, smr_val, max_baud; + unsigned int baud, smr_val, max_baud, cks; int t = -1; /* @@ -1849,21 +1849,18 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, termios->c_cflag, baud); - serial_port_out(port, SCSMR, smr_val); + for (cks = 0; t >= 256 && cks <= 3; cks++) + t >>= 2; - dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t, - s->cfg->scscr); + dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", + __func__, smr_val, cks, t, s->cfg->scscr); if (t >= 0) { - if (t >= 256) { - serial_port_out(port, SCSMR, (serial_port_in(port, SCSMR) & ~3) | 1); - t >>= 2; - } else - serial_port_out(port, SCSMR, serial_port_in(port, SCSMR) & ~3); - + serial_port_out(port, SCSMR, (smr_val & ~3) | cks); serial_port_out(port, SCBRR, t); udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ - } + } else + serial_port_out(port, SCSMR, smr_val); sci_init_pins(port, termios->c_cflag); -- cgit v1.2.3 From 63f7ad115ef35b711f3ae2b46a07acbf1ca3bdfd Mon Sep 17 00:00:00 2001 From: Takashi Yoshii Date: Fri, 16 Nov 2012 10:53:11 +0900 Subject: serial: sh-sci: mask SCTFDR/RFDR according to fifosize Current mask 0xff to SCTFDR/RFDR damages SCIFB, because the registers on SCIFB have 9-bit data (0 to 256). This patch changes the mask according to port->fifosize. Though I'm not sure if the mask is really needed (I don't know if there are variants which have non-zero upper bits), it is safer. Signed-off-by: Takashi Yoshii Signed-off-by: Shinya Kuribayashi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index a54c47d0fd6..c2d359cba55 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -485,7 +485,7 @@ static int sci_txfill(struct uart_port *port) reg = sci_getreg(port, SCTFDR); if (reg->size) - return serial_port_in(port, SCTFDR) & 0xff; + return serial_port_in(port, SCTFDR) & ((port->fifosize << 1) - 1); reg = sci_getreg(port, SCFDR); if (reg->size) @@ -505,7 +505,7 @@ static int sci_rxfill(struct uart_port *port) reg = sci_getreg(port, SCRFDR); if (reg->size) - return serial_port_in(port, SCRFDR) & 0xff; + return serial_port_in(port, SCRFDR) & ((port->fifosize << 1) - 1); reg = sci_getreg(port, SCFDR); if (reg->size) -- cgit v1.2.3 From 8c66d6d2a1a572768616ddca2c3863384b14d846 Mon Sep 17 00:00:00 2001 From: Takashi Yoshii Date: Fri, 16 Nov 2012 10:53:31 +0900 Subject: serial: sh-sci: fix common SCIFB regmap definition About FIFO count, there are two variants of SCIFs which show a) TX count in upper, RX count in lower byte of FDR register b) TX count in TFDR register, RX count in RFDR register Common SCIFB regmap in current source code is defined as "a". At least 7372 and 73a0 HW manual say their SICFB are "b". This patch alters the definition to "b", considering the current one has come from a mistake. The reason is as follows. The flag SCIFB sh-sci driver means it has 256 byte FIFO. The count is from 0(empty) to 256(full), that makes 9-bit. Because FDR is 16-bit register, it can not hold two 9-bits. That's why, SCIFB can not be "a". Signed-off-by: Takashi Yoshii Signed-off-by: Shinya Kuribayashi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index c2d359cba55..107801b1279 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -196,9 +196,9 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCxSR] = { 0x14, 16 }, [SCxRDR] = { 0x60, 8 }, [SCFCR] = { 0x18, 16 }, - [SCFDR] = { 0x1c, 16 }, - [SCTFDR] = sci_reg_invalid, - [SCRFDR] = sci_reg_invalid, + [SCFDR] = sci_reg_invalid, + [SCTFDR] = { 0x38, 16 }, + [SCRFDR] = { 0x3c, 16 }, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, }, -- cgit v1.2.3 From 40f70c03e33a1eed3f3fcd13418e76abad77d117 Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Fri, 16 Nov 2012 10:54:15 +0900 Subject: serial: sh-sci: add locking to console write function to avoid SMP lockup Symptom: When entering the suspend with Android logcat running, printk() call gets stuck and never returns. The issue can be observed at printk()s on nonboot CPUs when going to offline with their interrupts disabled, and never seen at boot CPU (core0 in our case). Details: serial_console_write() lacks of appropriate spinlock handling. In SMP systems, as long as sci_transmit_chars() is being processed at one CPU core, serial_console_write() can stuck at the other CPU core(s), when it tries to access to the same serial port _without_ a proper locking. serial_console_write() waits for the transmit FIFO getting empty, while sci_transmit_chars() writes data to the FIFO. In general, peripheral interrupts are routed to boot CPU (core0) by Linux ARM standard affinity settings. SCI(F) interrupts are handled by core0, so sci_transmit_chars() is processed on core0 as well. When logcat is running, it writes enormous log data to the kernel at every moment, forever. So core0 can repeatedly continue to process sci_transmit_chars() in its interrupt handler, which eventually makes the other CPU core(s) stuck at serial_console_write(). Looking at serial/8250.c, this is a known console write lockup issue with SMP kernels. Fix the sh-sci driver in the same way 8250.c does. Signed-off-by: Shinya Kuribayashi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 107801b1279..63a23eadd7e 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -2203,7 +2203,21 @@ static void serial_console_write(struct console *co, const char *s, { struct sci_port *sci_port = &sci_ports[co->index]; struct uart_port *port = &sci_port->port; - unsigned short bits; + unsigned short bits, ctrl; + unsigned long flags; + int locked = 1; + + local_irq_save(flags); + if (port->sysrq) + locked = 0; + else if (oops_in_progress) + locked = spin_trylock(&port->lock); + else + spin_lock(&port->lock); + + /* first save the SCSCR then disable the interrupts */ + ctrl = serial_port_in(port, SCSCR); + serial_port_out(port, SCSCR, sci_port->cfg->scscr); uart_console_write(port, s, count, serial_console_putchar); @@ -2211,6 +2225,13 @@ static void serial_console_write(struct console *co, const char *s, bits = SCxSR_TDxE(port) | SCxSR_TEND(port); while ((serial_port_in(port, SCxSR) & bits) != bits) cpu_relax(); + + /* restore the SCSCR */ + serial_port_out(port, SCSCR, ctrl); + + if (locked) + spin_unlock(&port->lock); + local_irq_restore(flags); } static int __devinit serial_console_setup(struct console *co, char *options) -- cgit v1.2.3 From 33b48e1633f738c5ae78234c2dd5e3a9ba115437 Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Fri, 16 Nov 2012 10:54:49 +0900 Subject: serial: sh-sci: fix possible race cases on SCSCR register accesses In the previous commit, console write function (serial_console_write) is changed to disable SCI interrupts while printing console strings. This introduces possible race cases in the serial startup / shutdown functions on SMP systems. This patch fixes the sh-sci in the same way as commit 9ec1882df2 (tty: serial: imx: console write routing is unsafe on SMP, from Xinyu Chen , 2012-08-27) did. There could be several consumers of the console, * the kernel printk * the init process using /dev/kmsg to call printk to show log * shell, which opens /dev/console and writes with sys_write() The shell goes into the normal UART open() and write() system calls, while the other two go into the console operations. The open() call invokes serial startup function (sci_startup), which will write to the SCSCR register (to enable or disable SCI interrupts) without any locking. This will conflict with the console serial function. Add spinlock protections in sci_startup() and sci_shutdown() properly. Signed-off-by: Shinya Kuribayashi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 63a23eadd7e..d38c0f54603 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1743,6 +1743,7 @@ static inline void sci_free_dma(struct uart_port *port) static int sci_startup(struct uart_port *port) { struct sci_port *s = to_sci_port(port); + unsigned long flags; int ret; dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); @@ -1753,8 +1754,10 @@ static int sci_startup(struct uart_port *port) sci_request_dma(port); + spin_lock_irqsave(&port->lock, flags); sci_start_tx(port); sci_start_rx(port); + spin_unlock_irqrestore(&port->lock, flags); return 0; } @@ -1762,11 +1765,14 @@ static int sci_startup(struct uart_port *port) static void sci_shutdown(struct uart_port *port) { struct sci_port *s = to_sci_port(port); + unsigned long flags; dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); + spin_lock_irqsave(&port->lock, flags); sci_stop_rx(port); sci_stop_tx(port); + spin_unlock_irqrestore(&port->lock, flags); sci_free_dma(port); sci_free_irq(s); -- cgit v1.2.3 From 60817a680b1bd3341b6909fab7d8a1fcc3a78369 Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Tue, 9 Oct 2012 15:37:48 +0800 Subject: libata-acpi: Fix NULL ptr derference in ata_acpi_dev_handle commit 6b66d95895c149cbc04d4fac5a2f5477c543a8ae didn't handle SATA PMP case in ata_acpi_bind_device and will cause a NULL ptr dereference when user attached a SATA drive to the PMP port. Fix this by checking PMP support. This bug is reported by Dan van der Ster in the following bugzilla page: https://bugzilla.kernel.org/show_bug.cgi?id=48211 Reported-by: Dan van der Ster Tested-by: Dan van der Ster Signed-off-by: Aaron Lu Cc: Signed-off-by: Jeff Garzik Tested-by: Simon --- drivers/ata/libata-acpi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index fd9ecf74e63..5b0ba3f20ed 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -1105,10 +1105,15 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev, struct acpi_device *acpi_dev; struct acpi_device_power_state *states; - if (ap->flags & ATA_FLAG_ACPI_SATA) - ata_dev = &ap->link.device[sdev->channel]; - else + if (ap->flags & ATA_FLAG_ACPI_SATA) { + if (!sata_pmp_attached(ap)) + ata_dev = &ap->link.device[sdev->id]; + else + ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id]; + } + else { ata_dev = &ap->link.device[sdev->id]; + } *handle = ata_dev_acpi_handle(ata_dev); -- cgit v1.2.3 From 9addf6afeef0f2c9a1fef880e2dbe633d15a89bd Mon Sep 17 00:00:00 2001 From: Vipul Kumar Samar Date: Thu, 8 Nov 2012 20:39:54 +0530 Subject: pata_arasan: Initialize cf clock to 166MHz PATA arasan driver expects the clock to be set to 166 MHz for proper functioning. This patch sets clk to 166 MHz in probe. Signed-off-by: Vipul Kumar Samar Signed-off-by: Viresh Kumar Signed-off-by: Jeff Garzik --- drivers/ata/pata_arasan_cf.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 26201ebef3c..71111f214ea 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -317,6 +317,12 @@ static int cf_init(struct arasan_cf_dev *acdev) return ret; } + ret = clk_set_rate(acdev->clk, 166000000); + if (ret) { + dev_warn(acdev->host->dev, "clock set rate failed"); + return ret; + } + spin_lock_irqsave(&acdev->host->lock, flags); /* configure CF interface clock */ writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk : -- cgit v1.2.3 From c37472d3f4ec6bf98b443490e069f31d18bcd6f5 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 6 Nov 2012 22:55:32 +0100 Subject: sata_highbank: mark ahci_highbank_probe as __devinit The ahci_highbank_probe function is incorrectly marked as __init, which means it can get discarded at boot time, which might be a problem if for some reason the device only becomes operational after loading another module. Using __devinit instead avoids seeing this warning for every build: WARNING: vmlinux.o(.data+0xf7b0): Section mismatch in reference from the variable ahci_highbank_driver to the function .init.text:ahci_highbank_probe() The variable ahci_highbank_driver references the function __init ahci_highbank_probe() If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console Signed-off-by: Arnd Bergmann Cc: Mark Langsdorf Cc: Rob Herring Signed-off-by: Jeff Garzik --- drivers/ata/sata_highbank.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index 0d7c4c2cd26..36a141a2b22 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -260,7 +260,7 @@ static const struct of_device_id ahci_of_match[] = { }; MODULE_DEVICE_TABLE(of, ahci_of_match); -static int __init ahci_highbank_probe(struct platform_device *pdev) +static int __devinit ahci_highbank_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ahci_host_priv *hpriv; -- cgit v1.2.3 From cd705d5ad49bb8894dda2726dcaef8f63ddeba43 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 21 Oct 2012 18:57:56 +0200 Subject: libata debugging: Warn when unable to find timing descriptor based on xfer_mode ata_timing_find_mode could return NULL which is not checked by all low-level ATA drivers using it and cause a NULL ptr deref. Warn at least so that possible issues can get fixed easily. Signed-off-by: Borislav Petkov Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 3cc7096cfda..f46fbd3bd3f 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2942,6 +2942,10 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode) if (xfer_mode == t->mode) return t; + + WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n", + __func__, xfer_mode); + return NULL; } -- cgit v1.2.3 From b03e66a6be91f8389fcd902ab6c1563db1c9c06b Mon Sep 17 00:00:00 2001 From: David Milburn Date: Mon, 29 Oct 2012 18:00:22 -0500 Subject: sata_svw: check DMA start bit before reset If kdump is triggered with pending IO, controller may not respond causing kdump to fail. http://marc.info/?l=linux-ide&m=133032255424658&w=2 During error recovery ata_do_dev_read_id never completes due hang in mmio_insw. ata_do_dev_read_id ata_sff_data_xfer ioread16_rep mmio_insw if DMA start bit is cleared before reset, PIO command is successful and kdump succeeds. Signed-off-by: David Milburn Signed-off-by: Jeff Garzik --- drivers/ata/sata_svw.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index 44a4256533e..08608de87e4 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -142,6 +142,39 @@ static int k2_sata_scr_write(struct ata_link *link, return 0; } +static int k2_sata_softreset(struct ata_link *link, + unsigned int *class, unsigned long deadline) +{ + u8 dmactl; + void __iomem *mmio = link->ap->ioaddr.bmdma_addr; + + dmactl = readb(mmio + ATA_DMA_CMD); + + /* Clear the start bit */ + if (dmactl & ATA_DMA_START) { + dmactl &= ~ATA_DMA_START; + writeb(dmactl, mmio + ATA_DMA_CMD); + } + + return ata_sff_softreset(link, class, deadline); +} + +static int k2_sata_hardreset(struct ata_link *link, + unsigned int *class, unsigned long deadline) +{ + u8 dmactl; + void __iomem *mmio = link->ap->ioaddr.bmdma_addr; + + dmactl = readb(mmio + ATA_DMA_CMD); + + /* Clear the start bit */ + if (dmactl & ATA_DMA_START) { + dmactl &= ~ATA_DMA_START; + writeb(dmactl, mmio + ATA_DMA_CMD); + } + + return sata_sff_hardreset(link, class, deadline); +} static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) { @@ -346,6 +379,8 @@ static struct scsi_host_template k2_sata_sht = { static struct ata_port_operations k2_sata_ops = { .inherits = &ata_bmdma_port_ops, + .softreset = k2_sata_softreset, + .hardreset = k2_sata_hardreset, .sff_tf_load = k2_sata_tf_load, .sff_tf_read = k2_sata_tf_read, .sff_check_status = k2_stat_check_status, -- cgit v1.2.3 From 29448ec129c5c9c7ece2ef28c72a0dafd70c8af2 Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Tue, 16 Oct 2012 22:59:01 +0800 Subject: [libata] PM callbacks should be conditionally compiled on CONFIG_PM_SLEEP This will fix warnings like following when CONFIG_PM_SLEEP is not set: warning: 'xxx_suspend' defined but not used [-Wunused-function] warning: 'xxx_resume' defined but not used [-Wunused-function] Because SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) Only references the callbacks on CONFIG_PM_SLEEP (instead of CONFIG_PM). Cc: Viresh Kumar Cc: linux-ide@vger.kernel.org Signed-off-by: Yuanhan Liu Signed-off-by: Fengguang Wu Signed-off-by: Jeff Garzik --- drivers/ata/ahci_platform.c | 2 +- drivers/ata/pata_arasan_cf.c | 2 +- drivers/ata/sata_highbank.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index b1ae48054dc..b7078afddb7 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -238,7 +238,7 @@ static int __devexit ahci_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int ahci_suspend(struct device *dev) { struct ahci_platform_data *pdata = dev_get_platdata(dev); diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 71111f214ea..371fd2c698b 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -914,7 +914,7 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int arasan_cf_suspend(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index 36a141a2b22..400bf1c3e98 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -378,7 +378,7 @@ static int __devexit ahci_highbank_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int ahci_highbank_suspend(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); -- cgit v1.2.3 From 6fc4adca6ce3e1d57a42707019dddcb883578a91 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Thu, 15 Nov 2012 18:13:19 +0000 Subject: tilegx: request_irq with a non-null device name This patch simply makes the tilegx net driver call request_irq with a non-null name. It makes the output in /proc/interrupts more obvious, but also helps tools that don't expect to find null there. Signed-off-by: Simon Marchi Acked-by: Chris Metcalf Signed-off-by: David S. Miller --- drivers/net/ethernet/tile/tilegx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c index 4e981001385..66e025ad5df 100644 --- a/drivers/net/ethernet/tile/tilegx.c +++ b/drivers/net/ethernet/tile/tilegx.c @@ -917,7 +917,7 @@ static int tile_net_setup_interrupts(struct net_device *dev) ingress_irq = rc; tile_irq_activate(ingress_irq, TILE_IRQ_PERCPU); rc = request_irq(ingress_irq, tile_net_handle_ingress_irq, - 0, NULL, NULL); + 0, "tile_net", NULL); if (rc != 0) { netdev_err(dev, "request_irq failed: %d\n", rc); destroy_irq(ingress_irq); -- cgit v1.2.3 From e9c00136a4754829faf885cf966c9754c7734660 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Wed, 7 Nov 2012 15:05:33 +0100 Subject: batman-adv: fix tt_global_entries flags update Flags carried by a change_entry have to be always copied into the client entry as they may contain important attributes (e.g. TT_CLIENT_WIFI). For instance, a client added by means of the "early detection mechanism" has no flag set at the beginning, so they must be updated once the proper ADD event is received. This was introduced by 30cfd02b60e1cb16f5effb0a01f826c5bb7e4c59 ("batman-adv: detect not yet announced clients") Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/translation-table.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 112edd371b2..64c00120c9f 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -769,6 +769,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv, */ tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP; + /* the change can carry possible "attribute" flags like the + * TT_CLIENT_WIFI, therefore they have to be copied in the + * client entry + */ + tt_global_entry->common.flags |= flags; + /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only * one originator left in the list and we previously received a * delete + roaming change for this originator. -- cgit v1.2.3 From 27b37ebfa2d2a1b6acef6f2d21c497475c9b9709 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Thu, 8 Nov 2012 14:21:11 +0100 Subject: batman-adv: correctly pass the client flag on tt_response When a TT response with the full table is sent, the client flags should be sent as well. This patch fix the flags assignment when populating the tt_response to send back This was introduced by 30cfd02b60e1cb16f5effb0a01f826c5bb7e4c59 ("batman-adv: detect not yet announced clients") Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/translation-table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 64c00120c9f..fec1a00a069 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1502,7 +1502,7 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, memcpy(tt_change->addr, tt_common_entry->addr, ETH_ALEN); - tt_change->flags = BATADV_NO_FLAGS; + tt_change->flags = tt_common_entry->flags; tt_count++; tt_change++; -- cgit v1.2.3 From 1f36aebcc5fa53c5d98f3329186466b5eb76a168 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Thu, 8 Nov 2012 21:55:29 +0100 Subject: batman-adv: don't add TEMP clients belonging to other backbone nodes The "early client detection" mechanism must not add clients belonging to other backbone nodes. Such clients must be reached by directly using the LAN instead of the mesh. This was introduced by 30cfd02b60e1cb16f5effb0a01f826c5bb7e4c59 ("batman-adv: detect not yet announced clients") Reported-by: Glen Page Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/translation-table.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index fec1a00a069..baae7158580 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -2456,6 +2456,13 @@ bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv, { bool ret = false; + /* if the originator is a backbone node (meaning it belongs to the same + * LAN of this node) the temporary client must not be added because to + * reach such destination the node must use the LAN instead of the mesh + */ + if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig)) + goto out; + if (!batadv_tt_global_add(bat_priv, orig_node, addr, BATADV_TT_CLIENT_TEMP, atomic_read(&orig_node->last_ttvn))) -- cgit v1.2.3 From 74490f969155caf1ec945ad2d35d3a8eec6be71d Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Thu, 8 Nov 2012 21:55:30 +0100 Subject: batman-adv: process broadcast packets in BLA earlier The logic in the BLA mechanism may decide to drop broadcast packets because the node may still be in the setup phase. For this reason, further broadcast processing like the early client detection mechanism must be done only after the BLA check. This patches moves the invocation to BLA before any other broadcast processing. This was introduced 30cfd02b60e1cb16f5effb0a01f826c5bb7e4c59 ("batman-adv: detect not yet announced clients") Reported-by: Glen Page Signed-off-by: Simon Wunderlich Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- net/batman-adv/soft-interface.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index b9a28d2dd3e..ce0684a1fc8 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -325,6 +325,12 @@ void batadv_interface_rx(struct net_device *soft_iface, soft_iface->last_rx = jiffies; + /* Let the bridge loop avoidance check the packet. If will + * not handle it, we can safely push it up. + */ + if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) + goto out; + if (orig_node) batadv_tt_add_temporary_global_entry(bat_priv, orig_node, ethhdr->h_source); @@ -332,12 +338,6 @@ void batadv_interface_rx(struct net_device *soft_iface, if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) goto dropped; - /* Let the bridge loop avoidance check the packet. If will - * not handle it, we can safely push it up. - */ - if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) - goto out; - netif_rx(skb); goto out; -- cgit v1.2.3 From 097965ee447e5ccec9776f9b075e64cf7607e5eb Mon Sep 17 00:00:00 2001 From: Nicolas Royer Date: Tue, 6 Nov 2012 17:31:03 +0100 Subject: ARM: at91/AT91SAM9G45: fix crypto peripherals irq issue due to sparse irq support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spare irq support introduced by commit 8fe82a5 (ARM: at91: sparse irq support) involves to add the NR_IRQS_LEGACY offset to irq number. Signed-off-by: Nicolas Royer Acked-by: Nicolas Ferre Acked-by: Eric Bénard Tested-by: Eric Bénard Cc: stable@vger.kernel.org # 3.6 --- arch/arm/mach-at91/at91sam9g45_devices.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index b1596072dcc..fcd233cb33d 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1841,8 +1841,8 @@ static struct resource sha_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91SAM9G45_ID_AESTDESSHA, - .end = AT91SAM9G45_ID_AESTDESSHA, + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, .flags = IORESOURCE_IRQ, }, }; @@ -1874,8 +1874,8 @@ static struct resource tdes_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91SAM9G45_ID_AESTDESSHA, - .end = AT91SAM9G45_ID_AESTDESSHA, + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, .flags = IORESOURCE_IRQ, }, }; @@ -1910,8 +1910,8 @@ static struct resource aes_resources[] = { .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91SAM9G45_ID_AESTDESSHA, - .end = AT91SAM9G45_ID_AESTDESSHA, + .start = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, + .end = NR_IRQS_LEGACY + AT91SAM9G45_ID_AESTDESSHA, .flags = IORESOURCE_IRQ, }, }; -- cgit v1.2.3 From 641f3ce64b050961d454a0716bb6dbf528315aac Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 14 Nov 2012 12:18:17 +0100 Subject: ARM: at91/usbh: fix overcurrent gpio setup Use gpio_is_valid also for overcurrent pins (which are currently negative in many board files). Signed-off-by: Johan Hovold Acked-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/at91rm9200_devices.c | 2 +- arch/arm/mach-at91/at91sam9260_devices.c | 2 +- arch/arm/mach-at91/at91sam9261_devices.c | 2 +- arch/arm/mach-at91/at91sam9263_devices.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c index 1e122bcd784..3cee0e6ea7c 100644 --- a/arch/arm/mach-at91/at91rm9200_devices.c +++ b/arch/arm/mach-at91/at91rm9200_devices.c @@ -68,7 +68,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index aa1e5872988..414bd855fb0 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c index b9487696b7b..cd604aad8e9 100644 --- a/arch/arm/mach-at91/at91sam9261_devices.c +++ b/arch/arm/mach-at91/at91sam9261_devices.c @@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index cb85da2ecce..9c61e59a210 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -78,7 +78,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) /* Enable overcurrent notification */ for (i = 0; i < data->ports; i++) { - if (data->overcurrent_pin[i]) + if (gpio_is_valid(data->overcurrent_pin[i])) at91_set_gpio_input(data->overcurrent_pin[i], 1); } -- cgit v1.2.3 From bacaf7cd092a2c42a904bce437e64690e04aaa10 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 16 Nov 2012 11:08:31 +0100 Subject: Revert "ACPI / x86: Add quirk for "CheckPoint P-20-00" to not use bridge _CRS_ info" This reverts commit 0a290ac4252c85205cb924ff7f6da10cfd20fb01 on the basis of the following comment from Bjorn Helgaas: Here's my reasoning: this is a CheckPoint product, and it looks like an appliance, not really a general-purpose machine. The issue has apparently been there from day one, and the kernel shipped on the machine complains noisily about the issue, but apparently nobody bothered to investigate it. This corruption will clearly break other ACPI-related things. We can sort of work around this one (though the workaround does prevent us from doing any PCI resource reassignment), but we have no idea what the other lurking ACPI issues are (and we have no assurance that *only* ACPI things are broken -- maybe the memory corruption affects other unknown things). It may take significant debugging effort to identify the next problem. The only report I've seen (this one) is apparently from a CheckPoint employee, so it's not clear that anybody else is trying to run upstream Linux on it. Being a CheckPoint employee, [...] is probably in a position to get the BIOS fixed. You might still be able to convince me, but it seems like the benefit to a quirk for this platform is small, and it does cost everybody else something in code size and complexity. References: https://bugzilla.kernel.org/show_bug.cgi?id=47981#c36 Signed-off-by: Rafael J. Wysocki --- arch/x86/pci/acpi.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 7010c199b4f..192397c9860 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -98,16 +98,6 @@ static const struct dmi_system_id pci_use_crs_table[] __initconst = { DMI_MATCH(DMI_BIOS_VERSION, "6JET85WW (1.43 )"), }, }, - /* https://bugzilla.kernel.org/show_bug.cgi?id=47981 */ - { - .callback = set_nouse_crs, - .ident = "CheckPoint P-20-00", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "CheckPoint"), - DMI_MATCH(DMI_PRODUCT_NAME, "P-20-00"), - DMI_MATCH(DMI_BOARD_NAME, "Bridgeport"), - }, - }, {} }; -- cgit v1.2.3 From a13ea24e20fc09c33e5bbd5ab35b24fd69437313 Mon Sep 17 00:00:00 2001 From: Alexandra Chin Date: Fri, 16 Nov 2012 16:31:46 +0800 Subject: staging: ste_rmi4: Convert to Type-B support Convert to MT-B because Synaptics touch devices are capable of tracking identifiable fingers. Signed-off-by: Alexandra Chin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c | 76 ++++++++++++--------------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c index 37d19c696ea..c71366d3dee 100644 --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "synaptics_i2c_rmi4.h" /* TODO: for multiple device support will need a per-device mutex */ @@ -67,7 +68,6 @@ #define PDT_START_SCAN_LOCATION (0x00E9) #define PDT_END_SCAN_LOCATION (0x000A) #define PDT_ENTRY_SIZE (0x0006) -#define RMI4_NUMBER_OF_MAX_FINGERS (8) #define SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM (0x11) #define SYNAPTICS_RMI4_DEVICE_CONTROL_FUNC_NUM (0x01) @@ -164,6 +164,7 @@ struct synaptics_rmi4_device_info { * @regulator: pointer to the regulator structure * @wait: wait queue structure variable * @touch_stopped: flag to stop the thread function + * @fingers_supported: maximum supported fingers * * This structure gives the device data information. */ @@ -184,6 +185,7 @@ struct synaptics_rmi4_data { struct regulator *regulator; wait_queue_head_t wait; bool touch_stopped; + unsigned char fingers_supported; }; /** @@ -303,22 +305,21 @@ static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata, /* number of touch points - fingers down in this case */ int touch_count = 0; int finger; - int fingers_supported; int finger_registers; int reg; int finger_shift; int finger_status; int retval; + int x, y; + int wx, wy; unsigned short data_base_addr; unsigned short data_offset; unsigned char data_reg_blk_size; unsigned char values[2]; unsigned char data[DATA_LEN]; - int x[RMI4_NUMBER_OF_MAX_FINGERS]; - int y[RMI4_NUMBER_OF_MAX_FINGERS]; - int wx[RMI4_NUMBER_OF_MAX_FINGERS]; - int wy[RMI4_NUMBER_OF_MAX_FINGERS]; + unsigned char fingers_supported = pdata->fingers_supported; struct i2c_client *client = pdata->i2c_client; + struct input_dev *input_dev = pdata->input_dev; /* get 2D sensor finger data */ /* @@ -333,7 +334,6 @@ static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata, * 10 = finger present but data may not be accurate, * 11 = reserved for product use. */ - fingers_supported = rfi->num_of_data_points; finger_registers = (fingers_supported + 3)/4; data_base_addr = rfi->fn_desc.data_base_addr; retval = synaptics_rmi4_i2c_block_read(pdata, data_base_addr, values, @@ -358,7 +358,11 @@ static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata, * if finger status indicates a finger is present then * read the finger data and report it */ - if (finger_status == 1 || finger_status == 2) { + input_mt_slot(input_dev, finger); + input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, + finger_status != 0); + + if (finger_status) { /* Read the finger data */ data_offset = data_base_addr + ((finger * data_reg_blk_size) + @@ -367,50 +371,33 @@ static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata, data_offset, data, data_reg_blk_size); if (retval != data_reg_blk_size) { - printk(KERN_ERR "%s:read data failed\n", + dev_err(&client->dev, "%s:read data failed\n", __func__); return 0; - } else { - x[touch_count] = - (data[0] << 4) | (data[2] & MASK_4BIT); - y[touch_count] = - (data[1] << 4) | - ((data[2] >> 4) & MASK_4BIT); - wy[touch_count] = - (data[3] >> 4) & MASK_4BIT; - wx[touch_count] = - (data[3] & MASK_4BIT); - - if (pdata->board->x_flip) - x[touch_count] = - pdata->sensor_max_x - - x[touch_count]; - if (pdata->board->y_flip) - y[touch_count] = - pdata->sensor_max_y - - y[touch_count]; } + x = (data[0] << 4) | (data[2] & MASK_4BIT); + y = (data[1] << 4) | ((data[2] >> 4) & MASK_4BIT); + wy = (data[3] >> 4) & MASK_4BIT; + wx = (data[3] & MASK_4BIT); + + if (pdata->board->x_flip) + x = pdata->sensor_max_x - x; + if (pdata->board->y_flip) + y = pdata->sensor_max_y - y; + + input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, + max(wx, wy)); + input_report_abs(input_dev, ABS_MT_POSITION_X, x); + input_report_abs(input_dev, ABS_MT_POSITION_Y, y); + /* number of active touch points */ touch_count++; } } - /* report to input subsystem */ - if (touch_count) { - for (finger = 0; finger < touch_count; finger++) { - input_report_abs(pdata->input_dev, ABS_MT_TOUCH_MAJOR, - max(wx[finger] , wy[finger])); - input_report_abs(pdata->input_dev, ABS_MT_POSITION_X, - x[finger]); - input_report_abs(pdata->input_dev, ABS_MT_POSITION_Y, - y[finger]); - input_mt_sync(pdata->input_dev); - } - } else - input_mt_sync(pdata->input_dev); - /* sync after groups of events */ - input_sync(pdata->input_dev); + input_mt_sync_frame(input_dev); + input_sync(input_dev); /* return the number of touch points */ return touch_count; } @@ -575,6 +562,7 @@ static int synpatics_rmi4_touchpad_detect(struct synaptics_rmi4_data *pdata, if ((queries[1] & MASK_3BIT) == 5) rfi->num_of_data_points = 10; } + pdata->fingers_supported = rfi->num_of_data_points; /* Need to get interrupt info for handling interrupts */ rfi->index_to_intr_reg = (interruptcount + 7)/8; if (rfi->index_to_intr_reg != 0) @@ -988,6 +976,8 @@ static int __devinit synaptics_rmi4_probe rmi4_data->sensor_max_y, 0, 0); input_set_abs_params(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, 0, MAX_TOUCH_MAJOR, 0, 0); + input_mt_init_slots(rmi4_data->input_dev, + rmi4_data->fingers_supported, 0); /* Clear interrupts */ synaptics_rmi4_i2c_block_read(rmi4_data, -- cgit v1.2.3 From ed71871bed7198ca4aa6a79b7a93b73ad6408e98 Mon Sep 17 00:00:00 2001 From: Noam Camus Date: Fri, 16 Nov 2012 07:03:05 +0200 Subject: tty/8250_early: Turn serial_in/serial_out into weak symbols. Allows overriding default methods serial_in/serial_out. In such platform specific replacement it is possible to use other regshift, biased register offset, any other manipulation that is not covered with common default methods. Overriding default methods may be useful for platforms which got serial peripheral with registers represented in big endian. In this situation and assuming that 32 bit operations / alignment is required then it may be useful to swab words before/after accessing the serial registers. Signed-off-by: Noam Camus Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_early.c | 42 ++++++++++++++++++------------------ include/linux/serial_8250.h | 2 ++ 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c index 843a150ba10..f53a7db4350 100644 --- a/drivers/tty/serial/8250/8250_early.c +++ b/drivers/tty/serial/8250/8250_early.c @@ -48,7 +48,7 @@ struct early_serial8250_device { static struct early_serial8250_device early_device; -static unsigned int __init serial_in(struct uart_port *port, int offset) +unsigned int __weak __init serial8250_early_in(struct uart_port *port, int offset) { switch (port->iotype) { case UPIO_MEM: @@ -62,7 +62,7 @@ static unsigned int __init serial_in(struct uart_port *port, int offset) } } -static void __init serial_out(struct uart_port *port, int offset, int value) +void __weak __init serial8250_early_out(struct uart_port *port, int offset, int value) { switch (port->iotype) { case UPIO_MEM: @@ -84,7 +84,7 @@ static void __init wait_for_xmitr(struct uart_port *port) unsigned int status; for (;;) { - status = serial_in(port, UART_LSR); + status = serial8250_early_in(port, UART_LSR); if ((status & BOTH_EMPTY) == BOTH_EMPTY) return; cpu_relax(); @@ -94,7 +94,7 @@ static void __init wait_for_xmitr(struct uart_port *port) static void __init serial_putc(struct uart_port *port, int c) { wait_for_xmitr(port); - serial_out(port, UART_TX, c); + serial8250_early_out(port, UART_TX, c); } static void __init early_serial8250_write(struct console *console, @@ -104,14 +104,14 @@ static void __init early_serial8250_write(struct console *console, unsigned int ier; /* Save the IER and disable interrupts */ - ier = serial_in(port, UART_IER); - serial_out(port, UART_IER, 0); + ier = serial8250_early_in(port, UART_IER); + serial8250_early_out(port, UART_IER, 0); uart_console_write(port, s, count, serial_putc); /* Wait for transmitter to become empty and restore the IER */ wait_for_xmitr(port); - serial_out(port, UART_IER, ier); + serial8250_early_out(port, UART_IER, ier); } static unsigned int __init probe_baud(struct uart_port *port) @@ -119,11 +119,11 @@ static unsigned int __init probe_baud(struct uart_port *port) unsigned char lcr, dll, dlm; unsigned int quot; - lcr = serial_in(port, UART_LCR); - serial_out(port, UART_LCR, lcr | UART_LCR_DLAB); - dll = serial_in(port, UART_DLL); - dlm = serial_in(port, UART_DLM); - serial_out(port, UART_LCR, lcr); + lcr = serial8250_early_in(port, UART_LCR); + serial8250_early_out(port, UART_LCR, lcr | UART_LCR_DLAB); + dll = serial8250_early_in(port, UART_DLL); + dlm = serial8250_early_in(port, UART_DLM); + serial8250_early_out(port, UART_LCR, lcr); quot = (dlm << 8) | dll; return (port->uartclk / 16) / quot; @@ -135,17 +135,17 @@ static void __init init_port(struct early_serial8250_device *device) unsigned int divisor; unsigned char c; - serial_out(port, UART_LCR, 0x3); /* 8n1 */ - serial_out(port, UART_IER, 0); /* no interrupt */ - serial_out(port, UART_FCR, 0); /* no fifo */ - serial_out(port, UART_MCR, 0x3); /* DTR + RTS */ + serial8250_early_out(port, UART_LCR, 0x3); /* 8n1 */ + serial8250_early_out(port, UART_IER, 0); /* no interrupt */ + serial8250_early_out(port, UART_FCR, 0); /* no fifo */ + serial8250_early_out(port, UART_MCR, 0x3); /* DTR + RTS */ divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * device->baud); - c = serial_in(port, UART_LCR); - serial_out(port, UART_LCR, c | UART_LCR_DLAB); - serial_out(port, UART_DLL, divisor & 0xff); - serial_out(port, UART_DLM, (divisor >> 8) & 0xff); - serial_out(port, UART_LCR, c & ~UART_LCR_DLAB); + c = serial8250_early_in(port, UART_LCR); + serial8250_early_out(port, UART_LCR, c | UART_LCR_DLAB); + serial8250_early_out(port, UART_DLL, divisor & 0xff); + serial8250_early_out(port, UART_DLM, (divisor >> 8) & 0xff); + serial8250_early_out(port, UART_LCR, c & ~UART_LCR_DLAB); } static int __init parse_options(struct early_serial8250_device *device, diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index c174c90fb3f..c490d20b3fb 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -105,6 +105,8 @@ extern int early_serial_setup(struct uart_port *port); extern int serial8250_find_port(struct uart_port *p); extern int serial8250_find_port_for_earlycon(void); +extern unsigned int serial8250_early_in(struct uart_port *port, int offset); +extern void serial8250_early_out(struct uart_port *port, int offset, int value); extern int setup_early_serial8250_console(char *cmdline); extern void serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old); -- cgit v1.2.3 From f4b1f03b826ba22c9835e9e89a1ca03541313e04 Mon Sep 17 00:00:00 2001 From: Huang Shijie Date: Fri, 16 Nov 2012 16:03:52 +0800 Subject: serial: mxs-auart: distinguish the different SOCs The current mxs-auart driver is used for both mx23 and mx28. But in mx23, the DMA has a bug(see errata:2836). We can not add the DMA support in mx23, but we can add DMA support to auart in mx28. So in order to add the DMA support for the auart in mx28, we should distinguish the distinguish SOCs. This patch adds a new platform_device_id table and a inline function is_imx28_auart() to distinguish the mx23 and mx28. Signed-off-by: Huang Shijie Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mxs-auart.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 6db3baa39a9..06d72713fb9 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -114,11 +114,17 @@ static struct uart_driver auart_driver; +enum mxs_auart_type { + IMX23_AUART, + IMX28_AUART, +}; + struct mxs_auart_port { struct uart_port port; unsigned int flags; unsigned int ctrl; + enum mxs_auart_type devtype; unsigned int irq; @@ -126,6 +132,29 @@ struct mxs_auart_port { struct device *dev; }; +static struct platform_device_id mxs_auart_devtype[] = { + { .name = "mxs-auart-imx23", .driver_data = IMX23_AUART }, + { .name = "mxs-auart-imx28", .driver_data = IMX28_AUART }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, mxs_auart_devtype); + +static struct of_device_id mxs_auart_dt_ids[] = { + { + .compatible = "fsl,imx28-auart", + .data = &mxs_auart_devtype[IMX28_AUART] + }, { + .compatible = "fsl,imx23-auart", + .data = &mxs_auart_devtype[IMX23_AUART] + }, { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids); + +static inline int is_imx28_auart(struct mxs_auart_port *s) +{ + return s->devtype == IMX28_AUART; +} + static void mxs_auart_stop_tx(struct uart_port *u); #define to_auart_port(u) container_of(u, struct mxs_auart_port, port) @@ -706,6 +735,8 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, static int __devinit mxs_auart_probe(struct platform_device *pdev) { + const struct of_device_id *of_id = + of_match_device(mxs_auart_dt_ids, &pdev->dev); struct mxs_auart_port *s; u32 version; int ret = 0; @@ -730,6 +761,11 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev) goto out_free; } + if (of_id) { + pdev->id_entry = of_id->data; + s->devtype = pdev->id_entry->driver_data; + } + s->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(s->clk)) { ret = PTR_ERR(s->clk); @@ -805,12 +841,6 @@ static int __devexit mxs_auart_remove(struct platform_device *pdev) return 0; } -static struct of_device_id mxs_auart_dt_ids[] = { - { .compatible = "fsl,imx23-auart", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(of, mxs_auart_dt_ids); - static struct platform_driver mxs_auart_driver = { .probe = mxs_auart_probe, .remove = __devexit_p(mxs_auart_remove), -- cgit v1.2.3 From e8001632816e600ced7d9d4790930fd87935c654 Mon Sep 17 00:00:00 2001 From: Huang Shijie Date: Fri, 16 Nov 2012 16:03:53 +0800 Subject: serial: mxs-auart: add the DMA support for mx28 Only we meet the following conditions, we can enable the DMA support for auart: (1) We enable the DMA support in the dts file, such as arch/arm/boot/dts/imx28.dtsi. (2) We enable the hardware flow control. (3) We use the mx28, not the mx23. Due to hardware bug(see errata: 2836), we can not add the DMA support to mx23. Signed-off-by: Huang Shijie Signed-off-by: Greg Kroah-Hartman --- .../bindings/tty/serial/fsl-mxs-auart.txt | 8 + drivers/tty/serial/mxs-auart.c | 322 ++++++++++++++++++++- 2 files changed, 325 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt b/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt index 2ee903fad25..273a8d5b330 100644 --- a/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt +++ b/Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt @@ -6,11 +6,19 @@ Required properties: - reg : Address and length of the register set for the device - interrupts : Should contain the auart interrupt numbers +Optional properties: +- fsl,auart-dma-channel : The DMA channels, the first is for RX, the other + is for TX. If you add this property, it also means that you + will enable the DMA support for the auart. + Note: due to the hardware bug in imx23(see errata : 2836), + only the imx28 can enable the DMA support for the auart. + Example: auart0: serial@8006a000 { compatible = "fsl,imx28-auart", "fsl,imx23-auart"; reg = <0x8006a000 0x2000>; interrupts = <112 70 71>; + fsl,auart-dma-channel = <8 9>; }; Note: Each auart port should have an alias correctly numbered in "aliases" diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 06d72713fb9..d5b9e303901 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include @@ -71,6 +73,15 @@ #define AUART_CTRL0_SFTRST (1 << 31) #define AUART_CTRL0_CLKGATE (1 << 30) +#define AUART_CTRL0_RXTO_ENABLE (1 << 27) +#define AUART_CTRL0_RXTIMEOUT(v) (((v) & 0x7ff) << 16) +#define AUART_CTRL0_XFER_COUNT(v) ((v) & 0xffff) + +#define AUART_CTRL1_XFER_COUNT(v) ((v) & 0xffff) + +#define AUART_CTRL2_DMAONERR (1 << 26) +#define AUART_CTRL2_TXDMAE (1 << 25) +#define AUART_CTRL2_RXDMAE (1 << 24) #define AUART_CTRL2_CTSEN (1 << 15) #define AUART_CTRL2_RTSEN (1 << 14) @@ -111,6 +122,7 @@ #define AUART_STAT_BERR (1 << 18) #define AUART_STAT_PERR (1 << 17) #define AUART_STAT_FERR (1 << 16) +#define AUART_STAT_RXCOUNT_MASK 0xffff static struct uart_driver auart_driver; @@ -122,7 +134,11 @@ enum mxs_auart_type { struct mxs_auart_port { struct uart_port port; - unsigned int flags; +#define MXS_AUART_DMA_CONFIG 0x1 +#define MXS_AUART_DMA_ENABLED 0x2 +#define MXS_AUART_DMA_TX_SYNC 2 /* bit 2 */ +#define MXS_AUART_DMA_RX_READY 3 /* bit 3 */ + unsigned long flags; unsigned int ctrl; enum mxs_auart_type devtype; @@ -130,6 +146,20 @@ struct mxs_auart_port { struct clk *clk; struct device *dev; + + /* for DMA */ + struct mxs_dma_data dma_data; + int dma_channel_rx, dma_channel_tx; + int dma_irq_rx, dma_irq_tx; + int dma_channel; + + struct scatterlist tx_sgl; + struct dma_chan *tx_dma_chan; + void *tx_dma_buf; + + struct scatterlist rx_sgl; + struct dma_chan *rx_dma_chan; + void *rx_dma_buf; }; static struct platform_device_id mxs_auart_devtype[] = { @@ -155,14 +185,107 @@ static inline int is_imx28_auart(struct mxs_auart_port *s) return s->devtype == IMX28_AUART; } +static inline bool auart_dma_enabled(struct mxs_auart_port *s) +{ + return s->flags & MXS_AUART_DMA_ENABLED; +} + static void mxs_auart_stop_tx(struct uart_port *u); #define to_auart_port(u) container_of(u, struct mxs_auart_port, port) -static inline void mxs_auart_tx_chars(struct mxs_auart_port *s) +static void mxs_auart_tx_chars(struct mxs_auart_port *s); + +static void dma_tx_callback(void *param) { + struct mxs_auart_port *s = param; struct circ_buf *xmit = &s->port.state->xmit; + dma_unmap_sg(s->dev, &s->tx_sgl, 1, DMA_TO_DEVICE); + + /* clear the bit used to serialize the DMA tx. */ + clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags); + smp_mb__after_clear_bit(); + + /* wake up the possible processes. */ + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&s->port); + + mxs_auart_tx_chars(s); +} + +static int mxs_auart_dma_tx(struct mxs_auart_port *s, int size) +{ + struct dma_async_tx_descriptor *desc; + struct scatterlist *sgl = &s->tx_sgl; + struct dma_chan *channel = s->tx_dma_chan; + u32 pio; + + /* [1] : send PIO. Note, the first pio word is CTRL1. */ + pio = AUART_CTRL1_XFER_COUNT(size); + desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)&pio, + 1, DMA_TRANS_NONE, 0); + if (!desc) { + dev_err(s->dev, "step 1 error\n"); + return -EINVAL; + } + + /* [2] : set DMA buffer. */ + sg_init_one(sgl, s->tx_dma_buf, size); + dma_map_sg(s->dev, sgl, 1, DMA_TO_DEVICE); + desc = dmaengine_prep_slave_sg(channel, sgl, + 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc) { + dev_err(s->dev, "step 2 error\n"); + return -EINVAL; + } + + /* [3] : submit the DMA */ + desc->callback = dma_tx_callback; + desc->callback_param = s; + dmaengine_submit(desc); + dma_async_issue_pending(channel); + return 0; +} + +static void mxs_auart_tx_chars(struct mxs_auart_port *s) +{ + struct circ_buf *xmit = &s->port.state->xmit; + + if (auart_dma_enabled(s)) { + int i = 0; + int size; + void *buffer = s->tx_dma_buf; + + if (test_and_set_bit(MXS_AUART_DMA_TX_SYNC, &s->flags)) + return; + + while (!uart_circ_empty(xmit) && !uart_tx_stopped(&s->port)) { + size = min_t(u32, UART_XMIT_SIZE - i, + CIRC_CNT_TO_END(xmit->head, + xmit->tail, + UART_XMIT_SIZE)); + memcpy(buffer + i, xmit->buf + xmit->tail, size); + xmit->tail = (xmit->tail + size) & (UART_XMIT_SIZE - 1); + + i += size; + if (i >= UART_XMIT_SIZE) + break; + } + + if (uart_tx_stopped(&s->port)) + mxs_auart_stop_tx(&s->port); + + if (i) { + mxs_auart_dma_tx(s, i); + } else { + clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags); + smp_mb__after_clear_bit(); + } + return; + } + + while (!(readl(s->port.membase + AUART_STAT) & AUART_STAT_TXFF)) { if (s->port.x_char) { @@ -316,10 +439,157 @@ static u32 mxs_auart_get_mctrl(struct uart_port *u) return mctrl; } +static bool mxs_auart_dma_filter(struct dma_chan *chan, void *param) +{ + struct mxs_auart_port *s = param; + + if (!mxs_dma_is_apbx(chan)) + return false; + + if (s->dma_channel == chan->chan_id) { + chan->private = &s->dma_data; + return true; + } + return false; +} + +static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s); +static void dma_rx_callback(void *arg) +{ + struct mxs_auart_port *s = (struct mxs_auart_port *) arg; + struct tty_struct *tty = s->port.state->port.tty; + int count; + u32 stat; + + stat = readl(s->port.membase + AUART_STAT); + stat &= ~(AUART_STAT_OERR | AUART_STAT_BERR | + AUART_STAT_PERR | AUART_STAT_FERR); + + count = stat & AUART_STAT_RXCOUNT_MASK; + tty_insert_flip_string(tty, s->rx_dma_buf, count); + + writel(stat, s->port.membase + AUART_STAT); + tty_flip_buffer_push(tty); + + /* start the next DMA for RX. */ + mxs_auart_dma_prep_rx(s); +} + +static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s) +{ + struct dma_async_tx_descriptor *desc; + struct scatterlist *sgl = &s->rx_sgl; + struct dma_chan *channel = s->rx_dma_chan; + u32 pio[1]; + + /* [1] : send PIO */ + pio[0] = AUART_CTRL0_RXTO_ENABLE + | AUART_CTRL0_RXTIMEOUT(0x80) + | AUART_CTRL0_XFER_COUNT(UART_XMIT_SIZE); + desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio, + 1, DMA_TRANS_NONE, 0); + if (!desc) { + dev_err(s->dev, "step 1 error\n"); + return -EINVAL; + } + + /* [2] : send DMA request */ + sg_init_one(sgl, s->rx_dma_buf, UART_XMIT_SIZE); + dma_map_sg(s->dev, sgl, 1, DMA_FROM_DEVICE); + desc = dmaengine_prep_slave_sg(channel, sgl, 1, DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + if (!desc) { + dev_err(s->dev, "step 2 error\n"); + return -1; + } + + /* [3] : submit the DMA, but do not issue it. */ + desc->callback = dma_rx_callback; + desc->callback_param = s; + dmaengine_submit(desc); + dma_async_issue_pending(channel); + return 0; +} + +static void mxs_auart_dma_exit_channel(struct mxs_auart_port *s) +{ + if (s->tx_dma_chan) { + dma_release_channel(s->tx_dma_chan); + s->tx_dma_chan = NULL; + } + if (s->rx_dma_chan) { + dma_release_channel(s->rx_dma_chan); + s->rx_dma_chan = NULL; + } + + kfree(s->tx_dma_buf); + kfree(s->rx_dma_buf); + s->tx_dma_buf = NULL; + s->rx_dma_buf = NULL; +} + +static void mxs_auart_dma_exit(struct mxs_auart_port *s) +{ + + writel(AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE | AUART_CTRL2_DMAONERR, + s->port.membase + AUART_CTRL2_CLR); + + mxs_auart_dma_exit_channel(s); + s->flags &= ~MXS_AUART_DMA_ENABLED; + clear_bit(MXS_AUART_DMA_TX_SYNC, &s->flags); + clear_bit(MXS_AUART_DMA_RX_READY, &s->flags); +} + +static int mxs_auart_dma_init(struct mxs_auart_port *s) +{ + dma_cap_mask_t mask; + + if (auart_dma_enabled(s)) + return 0; + + /* We do not get the right DMA channels. */ + if (s->dma_channel_rx == -1 || s->dma_channel_rx == -1) + return -EINVAL; + + /* init for RX */ + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + s->dma_channel = s->dma_channel_rx; + s->dma_data.chan_irq = s->dma_irq_rx; + s->rx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s); + if (!s->rx_dma_chan) + goto err_out; + s->rx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA); + if (!s->rx_dma_buf) + goto err_out; + + /* init for TX */ + s->dma_channel = s->dma_channel_tx; + s->dma_data.chan_irq = s->dma_irq_tx; + s->tx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s); + if (!s->tx_dma_chan) + goto err_out; + s->tx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA); + if (!s->tx_dma_buf) + goto err_out; + + /* set the flags */ + s->flags |= MXS_AUART_DMA_ENABLED; + dev_dbg(s->dev, "enabled the DMA support."); + + return 0; + +err_out: + mxs_auart_dma_exit_channel(s); + return -EINVAL; + +} + static void mxs_auart_settermios(struct uart_port *u, struct ktermios *termios, struct ktermios *old) { + struct mxs_auart_port *s = to_auart_port(u); u32 bm, ctrl, ctrl2, div; unsigned int cflag, baud; @@ -391,10 +661,23 @@ static void mxs_auart_settermios(struct uart_port *u, ctrl |= AUART_LINECTRL_STP2; /* figure out the hardware flow control settings */ - if (cflag & CRTSCTS) + if (cflag & CRTSCTS) { + /* + * The DMA has a bug(see errata:2836) in mx23. + * So we can not implement the DMA for auart in mx23, + * we can only implement the DMA support for auart + * in mx28. + */ + if (is_imx28_auart(s) && (s->flags & MXS_AUART_DMA_CONFIG)) { + if (!mxs_auart_dma_init(s)) + /* enable DMA tranfer */ + ctrl2 |= AUART_CTRL2_TXDMAE | AUART_CTRL2_RXDMAE + | AUART_CTRL2_DMAONERR; + } ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN; - else + } else { ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); + } /* set baud rate */ baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); @@ -406,6 +689,18 @@ static void mxs_auart_settermios(struct uart_port *u, writel(ctrl2, u->membase + AUART_CTRL2); uart_update_timeout(u, termios->c_cflag, baud); + + /* prepare for the DMA RX. */ + if (auart_dma_enabled(s) && + !test_and_set_bit(MXS_AUART_DMA_RX_READY, &s->flags)) { + if (!mxs_auart_dma_prep_rx(s)) { + /* Disable the normal RX interrupt. */ + writel(AUART_INTR_RXIEN, u->membase + AUART_INTR_CLR); + } else { + mxs_auart_dma_exit(s); + dev_err(s->dev, "We can not start up the DMA.\n"); + } + } } static irqreturn_t mxs_auart_irq_handle(int irq, void *context) @@ -484,6 +779,9 @@ static void mxs_auart_shutdown(struct uart_port *u) { struct mxs_auart_port *s = to_auart_port(u); + if (auart_dma_enabled(s)) + mxs_auart_dma_exit(s); + writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, @@ -717,6 +1015,7 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + u32 dma_channel[2]; int ret; if (!np) @@ -730,6 +1029,20 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s, } s->port.line = ret; + s->dma_irq_rx = platform_get_irq(pdev, 1); + s->dma_irq_tx = platform_get_irq(pdev, 2); + + ret = of_property_read_u32_array(np, "fsl,auart-dma-channel", + dma_channel, 2); + if (ret == 0) { + s->dma_channel_rx = dma_channel[0]; + s->dma_channel_tx = dma_channel[1]; + + s->flags |= MXS_AUART_DMA_CONFIG; + } else { + s->dma_channel_rx = -1; + s->dma_channel_tx = -1; + } return 0; } @@ -787,7 +1100,6 @@ static int __devinit mxs_auart_probe(struct platform_device *pdev) s->port.type = PORT_IMX; s->port.dev = s->dev = get_device(&pdev->dev); - s->flags = 0; s->ctrl = 0; s->irq = platform_get_irq(pdev, 0); -- cgit v1.2.3 From 77a807dcebc1be1e96dc8b47db2e598034e8a7c7 Mon Sep 17 00:00:00 2001 From: Huang Shijie Date: Fri, 16 Nov 2012 16:03:54 +0800 Subject: ARM: dts: enable dma support for auart0 in mx28 enable the dma support for auart0 in mx28. Signed-off-by: Huang Shijie Signed-off-by: Greg Kroah-Hartman --- arch/arm/boot/dts/imx28.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi index 55c57ea6169..b4587b27ae4 100644 --- a/arch/arm/boot/dts/imx28.dtsi +++ b/arch/arm/boot/dts/imx28.dtsi @@ -799,6 +799,7 @@ compatible = "fsl,imx28-auart", "fsl,imx23-auart"; reg = <0x8006a000 0x2000>; interrupts = <112 70 71>; + fsl,auart-dma-channel = <8 9>; clocks = <&clks 45>; status = "disabled"; }; -- cgit v1.2.3 From 4fd24483d1de7a3c183fa862fa9ff13b49361966 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 16 Nov 2012 12:07:54 +0530 Subject: usb: dwc3: core: move dwc3_cache_hwparams before dwc3_alloc_event_buffers commit 392142 moved event buffer allocation out of dwc3_core_init() but event buffer allocation uses the cached copy of hwparams to determine the number of event buffers and the caching is done in dwc3_core_init. So moved dwc3_cache_hwparams function before dwc3_alloc_event_buffers so that dwc3_alloc_event_buffers sees the correct number of event buffers. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index e71a62a652d..516d4007dfc 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -315,8 +315,6 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc) dwc3_core_soft_reset(dwc); - dwc3_cache_hwparams(dwc); - reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg &= ~DWC3_GCTL_SCALEDOWN_MASK; reg &= ~DWC3_GCTL_DISSCRAMBLE; @@ -460,6 +458,8 @@ static int __devinit dwc3_probe(struct platform_device *pdev) pm_runtime_get_sync(dev); pm_runtime_forbid(dev); + dwc3_cache_hwparams(dwc); + ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE); if (ret) { dev_err(dwc->dev, "failed to allocate event buffers\n"); -- cgit v1.2.3 From 644a9d3b66e6983c2c1f3b24c3006d49b184c871 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 16 Nov 2012 17:17:50 +0800 Subject: misc: apds9802als: Fix the logic checking timeout in als_wait_for_data_ready() In the case of timeout waiting for data ready, the retry variable is -1. This also fixes a bug: current code returns -ETIMEDOUT if latest retry success ( which means retry is 0 when exiting the while loop ). Signed-off-by: Axel Lin Signed-off-by: Greg Kroah-Hartman --- drivers/misc/apds9802als.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index 0314773f6db..94923d25991 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c @@ -68,7 +68,7 @@ static int als_wait_for_data_ready(struct device *dev) ret = i2c_smbus_read_byte_data(client, 0x86); } while (!(ret & 0x80) && retry--); - if (!retry) { + if (retry < 0) { dev_warn(dev, "timeout waiting for data ready\n"); return -ETIMEDOUT; } -- cgit v1.2.3 From 32cdba1e05418909708a17e52505e8b2ba4381d1 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 14 Nov 2012 19:03:42 +0100 Subject: uprobes: Use percpu_rw_semaphore to fix register/unregister vs dup_mmap() race This was always racy, but 268720903f87e0b84b161626c4447b81671b5d18 "uprobes: Rework register_for_each_vma() to make it O(n)" should be blamed anyway, it made everything worse and I didn't notice. register/unregister call build_map_info() and then do install/remove breakpoint for every mm which mmaps inode/offset. This can obviously race with fork()->dup_mmap() in between and we can miss the child. uprobe_register() could be easily fixed but unregister is much worse, the new mm inherits "int3" from parent and there is no way to detect this if uprobe goes away. So this patch simply adds percpu_down_read/up_read around dup_mmap(), and percpu_down_write/up_write into register_for_each_vma(). This adds 2 new hooks into dup_mmap() but we can kill uprobe_dup_mmap() and fold it into uprobe_end_dup_mmap(). Reported-by: Srikar Dronamraju Acked-by: Srikar Dronamraju Signed-off-by: Oleg Nesterov --- include/linux/uprobes.h | 8 ++++++++ kernel/events/uprobes.c | 26 +++++++++++++++++++++++--- kernel/fork.c | 2 ++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index 2615c4d7788..4f628a6fc5b 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h @@ -97,6 +97,8 @@ extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_con extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc); extern int uprobe_mmap(struct vm_area_struct *vma); extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end); +extern void uprobe_start_dup_mmap(void); +extern void uprobe_end_dup_mmap(void); extern void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm); extern void uprobe_free_utask(struct task_struct *t); extern void uprobe_copy_process(struct task_struct *t); @@ -127,6 +129,12 @@ static inline void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end) { } +static inline void uprobe_start_dup_mmap(void) +{ +} +static inline void uprobe_end_dup_mmap(void) +{ +} static inline void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) { diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 5ce99cfd2e6..dea7acfbb07 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -33,6 +33,7 @@ #include /* user_enable_single_step */ #include /* notifier mechanism */ #include "../../mm/internal.h" /* munlock_vma_page */ +#include #include @@ -71,6 +72,8 @@ static struct mutex uprobes_mutex[UPROBES_HASH_SZ]; static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ]; #define uprobes_mmap_hash(v) (&uprobes_mmap_mutex[((unsigned long)(v)) % UPROBES_HASH_SZ]) +static struct percpu_rw_semaphore dup_mmap_sem; + /* * uprobe_events allows us to skip the uprobe_mmap if there are no uprobe * events active at this time. Probably a fine grained per inode count is @@ -766,10 +769,13 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) struct map_info *info; int err = 0; + percpu_down_write(&dup_mmap_sem); info = build_map_info(uprobe->inode->i_mapping, uprobe->offset, is_register); - if (IS_ERR(info)) - return PTR_ERR(info); + if (IS_ERR(info)) { + err = PTR_ERR(info); + goto out; + } while (info) { struct mm_struct *mm = info->mm; @@ -799,7 +805,8 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) mmput(mm); info = free_map_info(info); } - + out: + percpu_up_write(&dup_mmap_sem); return err; } @@ -1131,6 +1138,16 @@ void uprobe_clear_state(struct mm_struct *mm) kfree(area); } +void uprobe_start_dup_mmap(void) +{ + percpu_down_read(&dup_mmap_sem); +} + +void uprobe_end_dup_mmap(void) +{ + percpu_up_read(&dup_mmap_sem); +} + void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) { newmm->uprobes_state.xol_area = NULL; @@ -1597,6 +1614,9 @@ static int __init init_uprobes(void) mutex_init(&uprobes_mmap_mutex[i]); } + if (percpu_init_rwsem(&dup_mmap_sem)) + return -ENOMEM; + return register_die_notifier(&uprobe_exception_nb); } module_init(init_uprobes); diff --git a/kernel/fork.c b/kernel/fork.c index 8b20ab7d3aa..c497e57aa65 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -352,6 +352,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) unsigned long charge; struct mempolicy *pol; + uprobe_start_dup_mmap(); down_write(&oldmm->mmap_sem); flush_cache_dup_mm(oldmm); uprobe_dup_mmap(oldmm, mm); @@ -469,6 +470,7 @@ out: up_write(&mm->mmap_sem); flush_tlb_mm(oldmm); up_write(&oldmm->mmap_sem); + uprobe_end_dup_mmap(); return retval; fail_nomem_anon_vma_fork: mpol_put(pol); -- cgit v1.2.3 From ecf026dc340f9700ed3c485344913a8a2b10e2e3 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 25 Oct 2012 23:02:18 +0800 Subject: ARM i.MX: fix error-valued pointer dereference in clk_register_gate2() The error-valued pointer clk is used for the arg of kfree, it should be kfree(gate) if clk_register() return ERR_PTR(). dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/clk-gate2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c index 3c1b8ff9a0a..cc49c7ae186 100644 --- a/arch/arm/mach-imx/clk-gate2.c +++ b/arch/arm/mach-imx/clk-gate2.c @@ -112,7 +112,7 @@ struct clk *clk_register_gate2(struct device *dev, const char *name, clk = clk_register(dev, &gate->hw); if (IS_ERR(clk)) - kfree(clk); + kfree(gate); return clk; } -- cgit v1.2.3 From 3d5e2abe6e265acc5e1fda810301243e9bac92b2 Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Fri, 16 Nov 2012 15:39:24 +0100 Subject: ARM: imx: ehci: fix host power mask bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch sets HPM (Host power mask bit) to bit 16 according to i.MX Reference Manual. Falsely it was set to bit 8, but this controls pull-up Impedance. Reported-by: Michael Burkey Cc: Stable Signed-off-by: Christoph Fritz Acked-by: Eric Bénard Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/ehci-imx25.c | 2 +- arch/arm/mach-imx/ehci-imx35.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/ehci-imx25.c b/arch/arm/mach-imx/ehci-imx25.c index 412c583a24b..576af744695 100644 --- a/arch/arm/mach-imx/ehci-imx25.c +++ b/arch/arm/mach-imx/ehci-imx25.c @@ -30,7 +30,7 @@ #define MX25_H1_SIC_SHIFT 21 #define MX25_H1_SIC_MASK (0x3 << MX25_H1_SIC_SHIFT) #define MX25_H1_PP_BIT (1 << 18) -#define MX25_H1_PM_BIT (1 << 8) +#define MX25_H1_PM_BIT (1 << 16) #define MX25_H1_IPPUE_UP_BIT (1 << 7) #define MX25_H1_IPPUE_DOWN_BIT (1 << 6) #define MX25_H1_TLL_BIT (1 << 5) diff --git a/arch/arm/mach-imx/ehci-imx35.c b/arch/arm/mach-imx/ehci-imx35.c index 779e16eb65c..293397852e4 100644 --- a/arch/arm/mach-imx/ehci-imx35.c +++ b/arch/arm/mach-imx/ehci-imx35.c @@ -30,7 +30,7 @@ #define MX35_H1_SIC_SHIFT 21 #define MX35_H1_SIC_MASK (0x3 << MX35_H1_SIC_SHIFT) #define MX35_H1_PP_BIT (1 << 18) -#define MX35_H1_PM_BIT (1 << 8) +#define MX35_H1_PM_BIT (1 << 16) #define MX35_H1_IPPUE_UP_BIT (1 << 7) #define MX35_H1_IPPUE_DOWN_BIT (1 << 6) #define MX35_H1_TLL_BIT (1 << 5) -- cgit v1.2.3 From 68a81291ff6650f3ff409ebfc58ef97dfe85a2e4 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 16 Nov 2012 09:28:49 -0500 Subject: staging: Add SystemBase Multi-2/PCI driver I ported the driver supplied by SystemBase to mainline. As the driver had MODULE_LICENSE("GPL") it is declared as a GPL module and thus I have the right to distribute it upstream. Note, I did the bare minimum to get it working. It still needs a lot of loving. Cc: hjchoi Signed-off-by: Steven Rostedt Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/sb105x/Kconfig | 9 + drivers/staging/sb105x/Makefile | 3 + drivers/staging/sb105x/sb_mp_register.h | 295 +++ drivers/staging/sb105x/sb_pci_mp.c | 3195 +++++++++++++++++++++++++++++++ drivers/staging/sb105x/sb_pci_mp.h | 293 +++ drivers/staging/sb105x/sb_ser_core.h | 368 ++++ 8 files changed, 4166 insertions(+) create mode 100644 drivers/staging/sb105x/Kconfig create mode 100644 drivers/staging/sb105x/Makefile create mode 100644 drivers/staging/sb105x/sb_mp_register.h create mode 100644 drivers/staging/sb105x/sb_pci_mp.c create mode 100644 drivers/staging/sb105x/sb_pci_mp.h create mode 100644 drivers/staging/sb105x/sb_ser_core.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index d805eef1191..f245fd3153d 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -144,4 +144,6 @@ source "drivers/staging/imx-drm/Kconfig" source "drivers/staging/dgrp/Kconfig" +source "drivers/staging/sb105x/Kconfig" + endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 76e2ebd596f..94cc3fa5ef8 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -64,3 +64,4 @@ obj-$(CONFIG_NET_VENDOR_SILICOM) += silicom/ obj-$(CONFIG_CED1401) += ced1401/ obj-$(CONFIG_DRM_IMX) += imx-drm/ obj-$(CONFIG_DGRP) += dgrp/ +obj-$(CONFIG_SB105X) += sb105x/ diff --git a/drivers/staging/sb105x/Kconfig b/drivers/staging/sb105x/Kconfig new file mode 100644 index 00000000000..ac87c5e38de --- /dev/null +++ b/drivers/staging/sb105x/Kconfig @@ -0,0 +1,9 @@ +config SB105X + tristate "SystemBase PCI Multiport UART" + select SERIAL_CORE + depends on PCI + help + A driver for the SystemBase Multi-2/PCI serial card + + To compile this driver a module, choose M here: the module + will be called "sb105x". diff --git a/drivers/staging/sb105x/Makefile b/drivers/staging/sb105x/Makefile new file mode 100644 index 00000000000..b1bf3779aca --- /dev/null +++ b/drivers/staging/sb105x/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_SB105X) += sb105x.o + +sb105x-y := sb_pci_mp.o diff --git a/drivers/staging/sb105x/sb_mp_register.h b/drivers/staging/sb105x/sb_mp_register.h new file mode 100644 index 00000000000..5480ae11368 --- /dev/null +++ b/drivers/staging/sb105x/sb_mp_register.h @@ -0,0 +1,295 @@ + +/* + * SB105X_UART.h + * + * Copyright (C) 2008 systembase + * + * UART registers. + * + * 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. + */ + +#ifndef UART_SB105X_H +#define UART_SB105X_H + +/* + * option register + */ + +/* Device Infomation Register */ +#define MP_OPTR_DIR0 0x04 /* port0 ~ port8 */ +#define MP_OPTR_DIR1 0x05 /* port8 ~ port15 */ +#define MP_OPTR_DIR2 0x06 /* port16 ~ port23 */ +#define MP_OPTR_DIR3 0x07 /* port24 ~ port31 */ + +#define DIR_UART_16C550 0 +#define DIR_UART_16C1050 1 +#define DIR_UART_16C1050A 2 + +#define DIR_CLK_1843200 0x0 /* input clock 1843200 Hz */ +#define DIR_CLK_3686400 0x1 /* input clock 3686400 Hz */ +#define DIR_CLK_7372800 0x2 /* input clock 7372800 Hz */ +#define DIR_CLK_14745600 0x3 /* input clock 14745600 Hz */ +#define DIR_CLK_29491200 0x4 /* input clock 29491200 Hz */ +#define DIR_CLK_58985400 0x5 /* input clock 58985400 Hz */ + +/* Interface Information Register */ +#define MP_OPTR_IIR0 0x08 /* port0 ~ port8 */ +#define MP_OPTR_IIR1 0x09 /* port8 ~ port15 */ +#define MP_OPTR_IIR2 0x0A /* port16 ~ port23 */ +#define MP_OPTR_IIR3 0x0B /* port24 ~ port31 */ + +#define IIR_RS232 0x00 /* RS232 type */ +#define IIR_RS422 0x10 /* RS422 type */ +#define IIR_RS485 0x20 /* RS485 type */ +#define IIR_UNKNOWN 0x30 /* unknown type */ + +/* Interrrupt Mask Register */ +#define MP_OPTR_IMR0 0x0C /* port0 ~ port8 */ +#define MP_OPTR_IMR1 0x0D /* port8 ~ port15 */ +#define MP_OPTR_IMR2 0x0E /* port16 ~ port23 */ +#define MP_OPTR_IMR3 0x0F /* port24 ~ port31 */ + +/* Interrupt Poll Register */ +#define MP_OPTR_IPR0 0x10 /* port0 ~ port8 */ +#define MP_OPTR_IPR1 0x11 /* port8 ~ port15 */ +#define MP_OPTR_IPR2 0x12 /* port16 ~ port23 */ +#define MP_OPTR_IPR3 0x13 /* port24 ~ port31 */ + +/* General Purpose Output Control Register */ +#define MP_OPTR_GPOCR 0x20 + +/* General Purpose Output Data Register */ +#define MP_OPTR_GPODR 0x21 + +/* Parallel Additional Function Register */ +#define MP_OPTR_PAFR 0x23 + +/* + * systembase 16c105x UART register + */ + +#define PAGE_0 0 +#define PAGE_1 1 +#define PAGE_2 2 +#define PAGE_3 3 +#define PAGE_4 4 + +/* + * ****************************************************************** + * * DLAB=0 =============== Page 0 Registers * + * ****************************************************************** + */ + +#define SB105X_RX 0 /* In: Receive buffer */ +#define SB105X_TX 0 /* Out: Transmit buffer */ + +#define SB105X_IER 1 /* Out: Interrupt Enable Register */ + +#define SB105X_IER_CTSI 0x80 /* CTS# Interrupt Enable (Requires EFR[4] = 1) */ +#define SB105X_IER_RTSI 0x40 /* RTS# Interrupt Enable (Requires EFR[4] = 1) */ +#define SB105X_IER_XOI 0x20 /* Xoff Interrupt Enable (Requires EFR[4] = 1) */ +#define SB105X_IER_SME 0x10 /* Sleep Mode Enable (Requires EFR[4] = 1) */ +#define SB105X_IER_MSI 0x08 /* Enable Modem status interrupt */ +#define SB105X_IER_RLSI 0x04 /* Enable receiver line status interrupt */ +#define SB105X_IER_THRI 0x02 /* Enable Transmitter holding register int. */ +#define SB105X_IER_RDI 0x01 /* Enable receiver data interrupt */ + +#define SB105X_ISR 2 /* In: Interrupt ID Register */ + +#define SB105X_ISR_NOINT 0x01 /* No interrupts pending */ +#define SB105X_ISR_RLSI 0x06 /* Receiver line status interrupt (Priority = 1)*/ +#define SB105X_ISR_RDAI 0x0c /* Receive Data Available interrupt */ +#define SB105X_ISR_CTII 0x04 /* Character Timeout Indication interrupt */ +#define SB105X_ISR_THRI 0x02 /* Transmitter holding register empty */ +#define SB105X_ISR_MSI 0x00 /* Modem status interrupt */ +#define SB105X_ISR_RXCI 0x10 /* Receive Xoff or Special Character interrupt */ +#define SB105X_ISR_RCSI 0x20 /* RTS#, CTS# status interrupt during Auto RTS/CTS flow control */ + +#define SB105X_FCR 2 /* Out: FIFO Control Register */ + +#define SB105X_FCR_FEN 0x01 /* FIFO Enable */ +#define SB105X_FCR_RXFR 0x02 /* RX FIFO Reset */ +#define SB105X_FCR_TXFR 0x04 /* TX FIFO Reset */ +#define SB105X_FCR_DMS 0x08 /* DMA Mode Select */ + +#define SB105X_FCR_RTR08 0x00 /* Receice Trigger Level set at 8 */ +#define SB105X_FCR_RTR16 0x40 /* Receice Trigger Level set at 16 */ +#define SB105X_FCR_RTR56 0x80 /* Receice Trigger Level set at 56 */ +#define SB105X_FCR_RTR60 0xc0 /* Receice Trigger Level set at 60 */ +#define SB105X_FCR_TTR08 0x00 /* Transmit Trigger Level set at 8 */ +#define SB105X_FCR_TTR16 0x10 /* Transmit Trigger Level set at 16 */ +#define SB105X_FCR_TTR32 0x20 /* Transmit Trigger Level set at 32 */ +#define SB105X_FCR_TTR56 0x30 /* Transmit Trigger Level set at 56 */ + +#define SB105X_LCR 3 /* Out: Line Control Register */ +/* + * * Note: if the word length is 5 bits (SB105X_LCR_WLEN5), then setting + * * SB105X_LCR_STOP will select 1.5 stop bits, not 2 stop bits. + */ +#define SB105X_LCR_DLAB 0x80 /* Divisor Latch Enable */ +#define SB105X_LCR_SBC 0x40 /* Break Enable*/ +#define SB105X_LCR_SPAR 0x20 /* Set Stick parity */ +#define SB105X_LCR_EPAR 0x10 /* Even parity select */ +#define SB105X_LCR_PAREN 0x08 /* Parity Enable */ +#define SB105X_LCR_STOP 0x04 /* Stop bits: 0->1 bit, 1->2 bits, 1 and SB105X_LCR_WLEN5 -> 1.5 bit */ +#define SB105X_LCR_WLEN5 0x00 /* Wordlength: 5 bits */ +#define SB105X_LCR_WLEN6 0x01 /* Wordlength: 6 bits */ +#define SB105X_LCR_WLEN7 0x02 /* Wordlength: 7 bits */ +#define SB105X_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ + +#define SB105X_LCR_BF 0xBF + +#define SB105X_MCR 4 /* Out: Modem Control Register */ +#define SB105X_MCR_CPS 0x80 /* Clock Prescaler Select */ +#define SB105X_MCR_P2S 0x40 /* Page 2 Select /Xoff Re-Transmit Access Enable */ +#define SB105X_MCR_XOA 0x20 /* Xon Any Enable */ +#define SB105X_MCR_ILB 0x10 /* Internal Loopback Enable */ +#define SB105X_MCR_OUT2 0x08 /* Out2/Interrupt Output Enable*/ +#define SB105X_MCR_OUT1 0x04 /* Out1/Interrupt Output Enable */ +#define SB105X_MCR_RTS 0x02 /* RTS# Output */ +#define SB105X_MCR_DTR 0x01 /* DTR# Output */ + +#define SB105X_LSR 5 /* In: Line Status Register */ +#define SB105X_LSR_RFEI 0x80 /* Receive FIFO data error Indicator */ +#define SB105X_LSR_TEMI 0x40 /* THR and TSR Empty Indicator */ +#define SB105X_LSR_THRE 0x20 /* THR Empty Indicator */ +#define SB105X_LSR_BII 0x10 /* Break interrupt indicator */ +#define SB105X_LSR_FEI 0x08 /* Frame error indicator */ +#define SB105X_LSR_PEI 0x04 /* Parity error indicator */ +#define SB105X_LSR_OEI 0x02 /* Overrun error indicator */ +#define SB105X_LSR_RDRI 0x01 /* Receive data ready Indicator*/ + +#define SB105X_MSR 6 /* In: Modem Status Register */ +#define SB105X_MSR_DCD 0x80 /* Data Carrier Detect */ +#define SB105X_MSR_RI 0x40 /* Ring Indicator */ +#define SB105X_MSR_DSR 0x20 /* Data Set Ready */ +#define SB105X_MSR_CTS 0x10 /* Clear to Send */ +#define SB105X_MSR_DDCD 0x08 /* Delta DCD */ +#define SB105X_MSR_DRI 0x04 /* Delta ring indicator */ +#define SB105X_MSR_DDSR 0x02 /* Delta DSR */ +#define SB105X_MSR_DCTS 0x01 /* Delta CTS */ + +#define SB105XA_MDR 6 /* Out: Multi Drop mode Register */ +#define SB105XA_MDR_NPS 0x08 /* 9th Bit Polarity Select */ +#define SB105XA_MDR_AME 0x02 /* Auto Multi-drop Enable */ +#define SB105XA_MDR_MDE 0x01 /* Multi Drop Enable */ + +#define SB105X_SPR 7 /* I/O: Scratch Register */ + +/* + * DLAB=1 + */ +#define SB105X_DLL 0 /* Out: Divisor Latch Low */ +#define SB105X_DLM 1 /* Out: Divisor Latch High */ + +/* + * ****************************************************************** + * * DLAB(LCR[7]) = 0 , MCR[6] = 1 ============= Page 2 Registers * + * ****************************************************************** + */ +#define SB105X_GICR 1 /* Global Interrupt Control Register */ +#define SB105X_GICR_GIM 0x01 /* Global Interrupt Mask */ + +#define SB105X_GISR 2 /* Global Interrupt Status Register */ +#define SB105X_GISR_MGICR0 0x80 /* Mirror the content of GICR[0] */ +#define SB105X_GISR_CS3IS 0x08 /* SB105X of CS3# Interrupt Status */ +#define SB105X_GISR_CS2IS 0x04 /* SB105X of CS2# Interrupt Status */ +#define SB105X_GISR_CS1IS 0x02 /* SB105X of CS1# Interrupt Status */ +#define SB105X_GISR_CS0IS 0x01 /* SB105X of CS0# Interrupt Status */ + +#define SB105X_TFCR 5 /* Transmit FIFO Count Register */ + +#define SB105X_RFCR 6 /* Receive FIFO Count Register */ + +#define SB105X_FSR 7 /* Flow Control Status Register */ +#define SB105X_FSR_THFS 0x20 /* Transmit Hardware Flow Control Status */ +#define SB105X_FSR_TSFS 0x10 /* Transmit Software Flow Control Status */ +#define SB105X_FSR_RHFS 0x02 /* Receive Hardware Flow Control Status */ +#define SB105X_FSR_RSFS 0x01 /* Receive Software Flow Control Status */ + +/* + * ****************************************************************** + * * LCR = 0xBF, PSR[0] = 0 ============= Page 3 Registers * + * ****************************************************************** + */ + +#define SB105X_PSR 0 /* Page Select Register */ +#define SB105X_PSR_P3KEY 0xA4 /* Page 3 Select Key */ +#define SB105X_PSR_P4KEY 0xA5 /* Page 5 Select Key */ + +#define SB105X_ATR 1 /* Auto Toggle Control Register */ +#define SB105X_ATR_RPS 0x80 /* RXEN Polarity Select */ +#define SB105X_ATR_RCMS 0x40 /* RXEN Control Mode Select */ +#define SB105X_ATR_TPS 0x20 /* TXEN Polarity Select */ +#define SB105X_ATR_TCMS 0x10 /* TXEN Control Mode Select */ +#define SB105X_ATR_ATDIS 0x00 /* Auto Toggle is disabled */ +#define SB105X_ATR_ART 0x01 /* RTS#/TXEN pin operates as TXEN */ +#define SB105X_ATR_ADT 0x02 /* DTR#/TXEN pin operates as TXEN */ +#define SB105X_ATR_A80 0x03 /* only in 80 pin use */ + +#define SB105X_EFR 2 /* (Auto) Enhanced Feature Register */ +#define SB105X_EFR_ACTS 0x80 /* Auto-CTS Flow Control Enable */ +#define SB105X_EFR_ARTS 0x40 /* Auto-RTS Flow Control Enable */ +#define SB105X_EFR_SCD 0x20 /* Special Character Detect */ +#define SB105X_EFR_EFBEN 0x10 /* Enhanced Function Bits Enable */ + +#define SB105X_XON1 4 /* Xon1 Character Register */ +#define SB105X_XON2 5 /* Xon2 Character Register */ +#define SB105X_XOFF1 6 /* Xoff1 Character Register */ +#define SB105X_XOFF2 7 /* Xoff2 Character Register */ + +/* + * ****************************************************************** + * * LCR = 0xBF, PSR[0] = 1 ============ Page 4 Registers * + * ****************************************************************** + */ + +#define SB105X_AFR 1 /* Additional Feature Register */ +#define SB105X_AFR_GIPS 0x20 /* Global Interrupt Polarity Select */ +#define SB105X_AFR_GIEN 0x10 /* Global Interrupt Enable */ +#define SB105X_AFR_AFEN 0x01 /* 256-byte FIFO Enable */ + +#define SB105X_XRCR 2 /* Xoff Re-transmit Count Register */ +#define SB105X_XRCR_NRC1 0x00 /* Transmits Xoff Character whenever the number of received data is 1 during XOFF status */ +#define SB105X_XRCR_NRC4 0x01 /* Transmits Xoff Character whenever the number of received data is 4 during XOFF status */ +#define SB105X_XRCR_NRC8 0x02 /* Transmits Xoff Character whenever the number of received data is 8 during XOFF status */ +#define SB105X_XRCR_NRC16 0x03 /* Transmits Xoff Character whenever the number of received data is 16 during XOFF status */ + +#define SB105X_TTR 4 /* Transmit FIFO Trigger Level Register */ +#define SB105X_RTR 5 /* Receive FIFO Trigger Level Register */ +#define SB105X_FUR 6 /* Flow Control Upper Threshold Register */ +#define SB105X_FLR 7 /* Flow Control Lower Threshold Register */ + + +/* page 0 */ + +#define SB105X_GET_CHAR(port) inb((port)->iobase + SB105X_RX) +#define SB105X_GET_IER(port) inb((port)->iobase + SB105X_IER) +#define SB105X_GET_ISR(port) inb((port)->iobase + SB105X_ISR) +#define SB105X_GET_LCR(port) inb((port)->iobase + SB105X_LCR) +#define SB105X_GET_MCR(port) inb((port)->iobase + SB105X_MCR) +#define SB105X_GET_LSR(port) inb((port)->iobase + SB105X_LSR) +#define SB105X_GET_MSR(port) inb((port)->iobase + SB105X_MSR) +#define SB105X_GET_SPR(port) inb((port)->iobase + SB105X_SPR) + +#define SB105X_PUT_CHAR(port,v) outb((v),(port)->iobase + SB105X_TX ) +#define SB105X_PUT_IER(port,v) outb((v),(port)->iobase + SB105X_IER ) +#define SB105X_PUT_FCR(port,v) outb((v),(port)->iobase + SB105X_FCR ) +#define SB105X_PUT_LCR(port,v) outb((v),(port)->iobase + SB105X_LCR ) +#define SB105X_PUT_MCR(port,v) outb((v),(port)->iobase + SB105X_MCR ) +#define SB105X_PUT_SPR(port,v) outb((v),(port)->iobase + SB105X_SPR ) + + +/* page 1 */ +#define SB105X_GET_REG(port,reg) inb((port)->iobase + (reg)) +#define SB105X_PUT_REG(port,reg,v) outb((v),(port)->iobase + (reg)) + +/* page 2 */ + +#define SB105X_PUT_PSR(port,v) outb((v),(port)->iobase + SB105X_PSR ) + +#endif diff --git a/drivers/staging/sb105x/sb_pci_mp.c b/drivers/staging/sb105x/sb_pci_mp.c new file mode 100644 index 00000000000..fbebf88226d --- /dev/null +++ b/drivers/staging/sb105x/sb_pci_mp.c @@ -0,0 +1,3195 @@ +#include "sb_pci_mp.h" +#include +#include + +extern struct parport *parport_pc_probe_port(unsigned long base_lo, + unsigned long base_hi, + int irq, int dma, + struct device *dev, + int irqflags); + +static struct mp_device_t mp_devs[MAX_MP_DEV]; +static int mp_nrpcibrds = sizeof(mp_pciboards)/sizeof(mppcibrd_t); +static int NR_BOARD=0; +static int NR_PORTS=0; +static struct mp_port multi_ports[MAX_MP_PORT]; +static struct irq_info irq_lists[NR_IRQS]; + +static _INLINE_ unsigned int serial_in(struct mp_port *mtpt, int offset); +static _INLINE_ void serial_out(struct mp_port *mtpt, int offset, int value); +static _INLINE_ unsigned int read_option_register(struct mp_port *mtpt, int offset); +static int sb1054_get_register(struct sb_uart_port * port, int page, int reg); +static int sb1054_set_register(struct sb_uart_port * port, int page, int reg, int value); +static void SendATCommand(struct mp_port * mtpt); +static int set_deep_fifo(struct sb_uart_port * port, int status); +static int get_deep_fifo(struct sb_uart_port * port); +static int get_device_type(int arg); +static int set_auto_rts(struct sb_uart_port *port, int status); +static void mp_stop(struct tty_struct *tty); +static void __mp_start(struct tty_struct *tty); +static void mp_start(struct tty_struct *tty); +static void mp_tasklet_action(unsigned long data); +static inline void mp_update_mctrl(struct sb_uart_port *port, unsigned int set, unsigned int clear); +static int mp_startup(struct sb_uart_state *state, int init_hw); +static void mp_shutdown(struct sb_uart_state *state); +static void mp_change_speed(struct sb_uart_state *state, struct MP_TERMIOS *old_termios); + +static inline int __mp_put_char(struct sb_uart_port *port, struct circ_buf *circ, unsigned char c); +static int mp_put_char(struct tty_struct *tty, unsigned char ch); + +static void mp_put_chars(struct tty_struct *tty); +static int mp_write(struct tty_struct *tty, const unsigned char * buf, int count); +static int mp_write_room(struct tty_struct *tty); +static int mp_chars_in_buffer(struct tty_struct *tty); +static void mp_flush_buffer(struct tty_struct *tty); +static void mp_send_xchar(struct tty_struct *tty, char ch); +static void mp_throttle(struct tty_struct *tty); +static void mp_unthrottle(struct tty_struct *tty); +static int mp_get_info(struct sb_uart_state *state, struct serial_struct *retinfo); +static int mp_set_info(struct sb_uart_state *state, struct serial_struct *newinfo); +static int mp_get_lsr_info(struct sb_uart_state *state, unsigned int *value); + +static int mp_tiocmget(struct tty_struct *tty); +static int mp_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); +static int mp_break_ctl(struct tty_struct *tty, int break_state); +static int mp_do_autoconfig(struct sb_uart_state *state); +static int mp_wait_modem_status(struct sb_uart_state *state, unsigned long arg); +static int mp_get_count(struct sb_uart_state *state, struct serial_icounter_struct *icnt); +static int mp_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); +static void mp_set_termios(struct tty_struct *tty, struct MP_TERMIOS *old_termios); +static void mp_close(struct tty_struct *tty, struct file *filp); +static void mp_wait_until_sent(struct tty_struct *tty, int timeout); +static void mp_hangup(struct tty_struct *tty); +static void mp_update_termios(struct sb_uart_state *state); +static int mp_block_til_ready(struct file *filp, struct sb_uart_state *state); +static struct sb_uart_state *uart_get(struct uart_driver *drv, int line); +static int mp_open(struct tty_struct *tty, struct file *filp); +static const char *mp_type(struct sb_uart_port *port); +static void mp_change_pm(struct sb_uart_state *state, int pm_state); +static inline void mp_report_port(struct uart_driver *drv, struct sb_uart_port *port); +static void mp_configure_port(struct uart_driver *drv, struct sb_uart_state *state, struct sb_uart_port *port); +static void mp_unconfigure_port(struct uart_driver *drv, struct sb_uart_state *state); +static int mp_register_driver(struct uart_driver *drv); +static void mp_unregister_driver(struct uart_driver *drv); +static int mp_add_one_port(struct uart_driver *drv, struct sb_uart_port *port); +static int mp_remove_one_port(struct uart_driver *drv, struct sb_uart_port *port); +static void autoconfig(struct mp_port *mtpt, unsigned int probeflags); +static void autoconfig_irq(struct mp_port *mtpt); +static void multi_stop_tx(struct sb_uart_port *port); +static void multi_start_tx(struct sb_uart_port *port); +static void multi_stop_rx(struct sb_uart_port *port); +static void multi_enable_ms(struct sb_uart_port *port); +static _INLINE_ void receive_chars(struct mp_port *mtpt, int *status ); +static _INLINE_ void transmit_chars(struct mp_port *mtpt); +static _INLINE_ void check_modem_status(struct mp_port *mtpt); +static inline void multi_handle_port(struct mp_port *mtpt); +static irqreturn_t multi_interrupt(int irq, void *dev_id); +static void serial_do_unlink(struct irq_info *i, struct mp_port *mtpt); +static int serial_link_irq_chain(struct mp_port *mtpt); +static void serial_unlink_irq_chain(struct mp_port *mtpt); +static void multi_timeout(unsigned long data); +static unsigned int multi_tx_empty(struct sb_uart_port *port); +static unsigned int multi_get_mctrl(struct sb_uart_port *port); +static void multi_set_mctrl(struct sb_uart_port *port, unsigned int mctrl); +static void multi_break_ctl(struct sb_uart_port *port, int break_state); +static int multi_startup(struct sb_uart_port *port); +static void multi_shutdown(struct sb_uart_port *port); +static unsigned int multi_get_divisor(struct sb_uart_port *port, unsigned int baud); +static void multi_set_termios(struct sb_uart_port *port, struct MP_TERMIOS *termios, struct MP_TERMIOS *old); +static void multi_pm(struct sb_uart_port *port, unsigned int state, unsigned int oldstate); +static void multi_release_std_resource(struct mp_port *mtpt); +static void multi_release_port(struct sb_uart_port *port); +static int multi_request_port(struct sb_uart_port *port); +static void multi_config_port(struct sb_uart_port *port, int flags); +static int multi_verify_port(struct sb_uart_port *port, struct serial_struct *ser); +static const char * multi_type(struct sb_uart_port *port); +static void __init multi_init_ports(void); +static void __init multi_register_ports(struct uart_driver *drv); +static int init_mp_dev(struct pci_dev *pcidev, mppcibrd_t brd); + +static int deep[256]; +static int deep_count; +static int fcr_arr[256]; +static int fcr_count; +static int ttr[256]; +static int ttr_count; +static int rtr[256]; +static int rtr_count; + +module_param_array(deep,int,&deep_count,0); +module_param_array(fcr_arr,int,&fcr_count,0); +module_param_array(ttr,int,&ttr_count,0); +module_param_array(rtr,int,&rtr_count,0); + +static _INLINE_ unsigned int serial_in(struct mp_port *mtpt, int offset) +{ + return inb(mtpt->port.iobase + offset); +} + +static _INLINE_ void serial_out(struct mp_port *mtpt, int offset, int value) +{ + outb(value, mtpt->port.iobase + offset); +} + +static _INLINE_ unsigned int read_option_register(struct mp_port *mtpt, int offset) +{ + return inb(mtpt->option_base_addr + offset); +} + +static int sb1053a_get_interface(struct mp_port *mtpt, int port_num) +{ + unsigned long option_base_addr = mtpt->option_base_addr; + unsigned int interface = 0; + + switch (port_num) + { + case 0: + case 1: + /* set GPO[1:0] = 00 */ + outb(0x00, option_base_addr + MP_OPTR_GPODR); + break; + case 2: + case 3: + /* set GPO[1:0] = 01 */ + outb(0x01, option_base_addr + MP_OPTR_GPODR); + break; + case 4: + case 5: + /* set GPO[1:0] = 10 */ + outb(0x02, option_base_addr + MP_OPTR_GPODR); + break; + default: + break; + } + + port_num &= 0x1; + + /* get interface */ + interface = inb(option_base_addr + MP_OPTR_IIR0 + port_num); + + /* set GPO[1:0] = 11 */ + outb(0x03, option_base_addr + MP_OPTR_GPODR); + + return (interface); +} + +static int sb1054_get_register(struct sb_uart_port * port, int page, int reg) +{ + int ret = 0; + unsigned int lcr = 0; + unsigned int mcr = 0; + unsigned int tmp = 0; + + if( page <= 0) + { + printk(" page 0 can not use this fuction\n"); + return -1; + } + + switch(page) + { + case 1: + lcr = SB105X_GET_LCR(port); + tmp = lcr | SB105X_LCR_DLAB; + SB105X_PUT_LCR(port, tmp); + + tmp = SB105X_GET_LCR(port); + + ret = SB105X_GET_REG(port,reg); + SB105X_PUT_LCR(port,lcr); + break; + case 2: + mcr = SB105X_GET_MCR(port); + tmp = mcr | SB105X_MCR_P2S; + SB105X_PUT_MCR(port,tmp); + + ret = SB105X_GET_REG(port,reg); + + SB105X_PUT_MCR(port,mcr); + break; + case 3: + lcr = SB105X_GET_LCR(port); + tmp = lcr | SB105X_LCR_BF; + SB105X_PUT_LCR(port,tmp); + SB105X_PUT_REG(port,SB105X_PSR,SB105X_PSR_P3KEY); + + ret = SB105X_GET_REG(port,reg); + + SB105X_PUT_LCR(port,lcr); + break; + case 4: + lcr = SB105X_GET_LCR(port); + tmp = lcr | SB105X_LCR_BF; + SB105X_PUT_LCR(port,tmp); + SB105X_PUT_REG(port,SB105X_PSR,SB105X_PSR_P4KEY); + + ret = SB105X_GET_REG(port,reg); + + SB105X_PUT_LCR(port,lcr); + break; + default: + printk(" error invalid page number \n"); + return -1; + } + + return ret; +} + +static int sb1054_set_register(struct sb_uart_port * port, int page, int reg, int value) +{ + int lcr = 0; + int mcr = 0; + int ret = 0; + + if( page <= 0) + { + printk(" page 0 can not use this fuction\n"); + return -1; + } + switch(page) + { + case 1: + lcr = SB105X_GET_LCR(port); + SB105X_PUT_LCR(port, lcr | SB105X_LCR_DLAB); + + SB105X_PUT_REG(port,reg,value); + + SB105X_PUT_LCR(port, lcr); + ret = 1; + break; + case 2: + mcr = SB105X_GET_MCR(port); + SB105X_PUT_MCR(port, mcr | SB105X_MCR_P2S); + + SB105X_PUT_REG(port,reg,value); + + SB105X_PUT_MCR(port, mcr); + ret = 1; + break; + case 3: + lcr = SB105X_GET_LCR(port); + SB105X_PUT_LCR(port, lcr | SB105X_LCR_BF); + SB105X_PUT_PSR(port, SB105X_PSR_P3KEY); + + SB105X_PUT_REG(port,reg,value); + + SB105X_PUT_LCR(port, lcr); + ret = 1; + break; + case 4: + lcr = SB105X_GET_LCR(port); + SB105X_PUT_LCR(port, lcr | SB105X_LCR_BF); + SB105X_PUT_PSR(port, SB105X_PSR_P4KEY); + + SB105X_PUT_REG(port,reg,value); + + SB105X_PUT_LCR(port, lcr); + ret = 1; + break; + default: + printk(" error invalid page number \n"); + return -1; + } + + return ret; +} + +static int set_multidrop_mode(struct sb_uart_port *port, unsigned int mode) +{ + int mdr = SB105XA_MDR_NPS; + + if (mode & MDMODE_ENABLE) + { + mdr |= SB105XA_MDR_MDE; + } + + if (1) //(mode & MDMODE_AUTO) + { + int efr = 0; + mdr |= SB105XA_MDR_AME; + efr = sb1054_get_register(port, PAGE_3, SB105X_EFR); + efr |= SB105X_EFR_SCD; + sb1054_set_register(port, PAGE_3, SB105X_EFR, efr); + } + + sb1054_set_register(port, PAGE_1, SB105XA_MDR, mdr); + port->mdmode &= ~0x6; + port->mdmode |= mode; + printk("[%d] multidrop init: %x\n", port->line, port->mdmode); + + return 0; +} + +static int get_multidrop_addr(struct sb_uart_port *port) +{ + return sb1054_get_register(port, PAGE_3, SB105X_XOFF2); +} + +static int set_multidrop_addr(struct sb_uart_port *port, unsigned int addr) +{ + sb1054_set_register(port, PAGE_3, SB105X_XOFF2, addr); + + return 0; +} + +static void SendATCommand(struct mp_port * mtpt) +{ + // a t cr lf + unsigned char ch[] = {0x61,0x74,0x0d,0x0a,0x0}; + unsigned char lineControl; + unsigned char i=0; + unsigned char Divisor = 0xc; + + lineControl = serial_inp(mtpt,UART_LCR); + serial_outp(mtpt,UART_LCR,(lineControl | UART_LCR_DLAB)); + serial_outp(mtpt,UART_DLL,(Divisor & 0xff)); + serial_outp(mtpt,UART_DLM,(Divisor & 0xff00)>>8); //baudrate is 4800 + + + serial_outp(mtpt,UART_LCR,lineControl); + serial_outp(mtpt,UART_LCR,0x03); // N-8-1 + serial_outp(mtpt,UART_FCR,7); + serial_outp(mtpt,UART_MCR,0x3); + while(ch[i]){ + while((serial_inp(mtpt,UART_LSR) & 0x60) !=0x60){ + ; + } + serial_outp(mtpt,0,ch[i++]); + } + + +}// end of SendATCommand() + +static int set_deep_fifo(struct sb_uart_port * port, int status) +{ + int afr_status = 0; + afr_status = sb1054_get_register(port, PAGE_4, SB105X_AFR); + + if(status == ENABLE) + { + afr_status |= SB105X_AFR_AFEN; + } + else + { + afr_status &= ~SB105X_AFR_AFEN; + } + + sb1054_set_register(port,PAGE_4,SB105X_AFR,afr_status); + sb1054_set_register(port,PAGE_4,SB105X_TTR,ttr[port->line]); + sb1054_set_register(port,PAGE_4,SB105X_RTR,rtr[port->line]); + afr_status = sb1054_get_register(port, PAGE_4, SB105X_AFR); + + return afr_status; +} + +static int get_device_type(int arg) +{ + int ret; + ret = inb(mp_devs[arg].option_reg_addr+MP_OPTR_DIR0); + ret = (ret & 0xf0) >> 4; + switch (ret) + { + case DIR_UART_16C550: + return PORT_16C55X; + case DIR_UART_16C1050: + return PORT_16C105X; + case DIR_UART_16C1050A: + /* + if (mtpt->port.line < 2) + { + return PORT_16C105XA; + } + else + { + if (mtpt->device->device_id & 0x50) + { + return PORT_16C55X; + } + else + { + return PORT_16C105X; + } + }*/ + return PORT_16C105XA; + default: + return PORT_UNKNOWN; + } + +} +static int get_deep_fifo(struct sb_uart_port * port) +{ + int afr_status = 0; + afr_status = sb1054_get_register(port, PAGE_4, SB105X_AFR); + return afr_status; +} + +static int set_auto_rts(struct sb_uart_port *port, int status) +{ + int atr_status = 0; + +#if 0 + int efr_status = 0; + + efr_status = sb1054_get_register(port, PAGE_3, SB105X_EFR); + if(status == ENABLE) + efr_status |= SB105X_EFR_ARTS; + else + efr_status &= ~SB105X_EFR_ARTS; + sb1054_set_register(port,PAGE_3,SB105X_EFR,efr_status); + efr_status = sb1054_get_register(port, PAGE_3, SB105X_EFR); +#endif + +//ATR + atr_status = sb1054_get_register(port, PAGE_3, SB105X_ATR); + switch(status) + { + case RS422PTP: + atr_status = (SB105X_ATR_TPS) | (SB105X_ATR_A80); + break; + case RS422MD: + atr_status = (SB105X_ATR_TPS) | (SB105X_ATR_TCMS) | (SB105X_ATR_A80); + break; + case RS485NE: + atr_status = (SB105X_ATR_RCMS) | (SB105X_ATR_TPS) | (SB105X_ATR_TCMS) | (SB105X_ATR_A80); + break; + case RS485ECHO: + atr_status = (SB105X_ATR_TPS) | (SB105X_ATR_TCMS) | (SB105X_ATR_A80); + break; + } + + sb1054_set_register(port,PAGE_3,SB105X_ATR,atr_status); + atr_status = sb1054_get_register(port, PAGE_3, SB105X_ATR); + + return atr_status; +} + +static void mp_stop(struct tty_struct *tty) +{ + struct sb_uart_state *state = tty->driver_data; + struct sb_uart_port *port = state->port; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + port->ops->stop_tx(port); + spin_unlock_irqrestore(&port->lock, flags); +} + +static void __mp_start(struct tty_struct *tty) +{ + struct sb_uart_state *state = tty->driver_data; + struct sb_uart_port *port = state->port; + + if (!uart_circ_empty(&state->info->xmit) && state->info->xmit.buf && + !tty->stopped && !tty->hw_stopped) + port->ops->start_tx(port); +} + +static void mp_start(struct tty_struct *tty) +{ + __mp_start(tty); +} + +static void mp_tasklet_action(unsigned long data) +{ + struct sb_uart_state *state = (struct sb_uart_state *)data; + struct tty_struct *tty; + + printk("tasklet is called!\n"); + tty = state->info->tty; + tty_wakeup(tty); +} + +static inline void mp_update_mctrl(struct sb_uart_port *port, unsigned int set, unsigned int clear) +{ + unsigned int old; + + old = port->mctrl; + port->mctrl = (old & ~clear) | set; + if (old != port->mctrl) + port->ops->set_mctrl(port, port->mctrl); +} + +#define uart_set_mctrl(port,set) mp_update_mctrl(port,set,0) +#define uart_clear_mctrl(port,clear) mp_update_mctrl(port,0,clear) + +static int mp_startup(struct sb_uart_state *state, int init_hw) +{ + struct sb_uart_info *info = state->info; + struct sb_uart_port *port = state->port; + unsigned long page; + int retval = 0; + + if (info->flags & UIF_INITIALIZED) + return 0; + + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + if (port->type == PORT_UNKNOWN) + return 0; + + if (!info->xmit.buf) { + page = get_zeroed_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + info->xmit.buf = (unsigned char *) page; + + uart_circ_clear(&info->xmit); + } + + retval = port->ops->startup(port); + if (retval == 0) { + if (init_hw) { + mp_change_speed(state, NULL); + + if (info->tty->termios.c_cflag & CBAUD) + uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); + } + + info->flags |= UIF_INITIALIZED; + + + clear_bit(TTY_IO_ERROR, &info->tty->flags); + } + + if (retval && capable(CAP_SYS_ADMIN)) + retval = 0; + + return retval; +} + +static void mp_shutdown(struct sb_uart_state *state) +{ + struct sb_uart_info *info = state->info; + struct sb_uart_port *port = state->port; + + if (info->tty) + set_bit(TTY_IO_ERROR, &info->tty->flags); + + if (info->flags & UIF_INITIALIZED) { + info->flags &= ~UIF_INITIALIZED; + + if (!info->tty || (info->tty->termios.c_cflag & HUPCL)) + uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); + + wake_up_interruptible(&info->delta_msr_wait); + + port->ops->shutdown(port); + + synchronize_irq(port->irq); + } + tasklet_kill(&info->tlet); + + if (info->xmit.buf) { + free_page((unsigned long)info->xmit.buf); + info->xmit.buf = NULL; + } +} + +static void mp_change_speed(struct sb_uart_state *state, struct MP_TERMIOS *old_termios) +{ + struct tty_struct *tty = state->info->tty; + struct sb_uart_port *port = state->port; + + if (!tty || port->type == PORT_UNKNOWN) + return; + + if (tty->termios.c_cflag & CRTSCTS) + state->info->flags |= UIF_CTS_FLOW; + else + state->info->flags &= ~UIF_CTS_FLOW; + + if (tty->termios.c_cflag & CLOCAL) + state->info->flags &= ~UIF_CHECK_CD; + else + state->info->flags |= UIF_CHECK_CD; + + port->ops->set_termios(port, &tty->termios, old_termios); +} + +static inline int __mp_put_char(struct sb_uart_port *port, struct circ_buf *circ, unsigned char c) +{ + unsigned long flags; + int ret = 0; + + if (!circ->buf) + return 0; + + spin_lock_irqsave(&port->lock, flags); + if (uart_circ_chars_free(circ) != 0) { + circ->buf[circ->head] = c; + circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1); + ret = 1; + } + spin_unlock_irqrestore(&port->lock, flags); + return ret; +} + +static int mp_put_char(struct tty_struct *tty, unsigned char ch) +{ + struct sb_uart_state *state = tty->driver_data; + + return __mp_put_char(state->port, &state->info->xmit, ch); +} + +static void mp_put_chars(struct tty_struct *tty) +{ + mp_start(tty); +} + +static int mp_write(struct tty_struct *tty, const unsigned char * buf, int count) +{ + struct sb_uart_state *state = tty->driver_data; + struct sb_uart_port *port; + struct circ_buf *circ; + int c, ret = 0; + + if (!state || !state->info) { + return -EL3HLT; + } + + port = state->port; + circ = &state->info->xmit; + + if (!circ->buf) + return 0; + + while (1) { + c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); + if (count < c) + c = count; + if (c <= 0) + break; + memcpy(circ->buf + circ->head, buf, c); + + circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1); + buf += c; + count -= c; + ret += c; + } + mp_start(tty); + return ret; +} + +static int mp_write_room(struct tty_struct *tty) +{ + struct sb_uart_state *state = tty->driver_data; + + return uart_circ_chars_free(&state->info->xmit); +} + +static int mp_chars_in_buffer(struct tty_struct *tty) +{ + struct sb_uart_state *state = tty->driver_data; + + return uart_circ_chars_pending(&state->info->xmit); +} + +static void mp_flush_buffer(struct tty_struct *tty) +{ + struct sb_uart_state *state = tty->driver_data; + struct sb_uart_port *port = state->port; + unsigned long flags; + + if (!state || !state->info) { + return; + } + + spin_lock_irqsave(&port->lock, flags); + uart_circ_clear(&state->info->xmit); + spin_unlock_irqrestore(&port->lock, flags); + wake_up_interruptible(&tty->write_wait); + tty_wakeup(tty); +} + +static void mp_send_xchar(struct tty_struct *tty, char ch) +{ + struct sb_uart_state *state = tty->driver_data; + struct sb_uart_port *port = state->port; + unsigned long flags; + + if (port->ops->send_xchar) + port->ops->send_xchar(port, ch); + else { + port->x_char = ch; + if (ch) { + spin_lock_irqsave(&port->lock, flags); + port->ops->start_tx(port); + spin_unlock_irqrestore(&port->lock, flags); + } + } +} + +static void mp_throttle(struct tty_struct *tty) +{ + struct sb_uart_state *state = tty->driver_data; + + if (I_IXOFF(tty)) + mp_send_xchar(tty, STOP_CHAR(tty)); + + if (tty->termios.c_cflag & CRTSCTS) + uart_clear_mctrl(state->port, TIOCM_RTS); +} + +static void mp_unthrottle(struct tty_struct *tty) +{ + struct sb_uart_state *state = tty->driver_data; + struct sb_uart_port *port = state->port; + + if (I_IXOFF(tty)) { + if (port->x_char) + port->x_char = 0; + else + mp_send_xchar(tty, START_CHAR(tty)); + } + + if (tty->termios.c_cflag & CRTSCTS) + uart_set_mctrl(port, TIOCM_RTS); +} + +static int mp_get_info(struct sb_uart_state *state, struct serial_struct *retinfo) +{ + struct sb_uart_port *port = state->port; + struct serial_struct tmp; + + memset(&tmp, 0, sizeof(tmp)); + tmp.type = port->type; + tmp.line = port->line; + tmp.port = port->iobase; + if (HIGH_BITS_OFFSET) + tmp.port_high = (long) port->iobase >> HIGH_BITS_OFFSET; + tmp.irq = port->irq; + tmp.flags = port->flags; + tmp.xmit_fifo_size = port->fifosize; + tmp.baud_base = port->uartclk / 16; + tmp.close_delay = state->close_delay; + tmp.closing_wait = state->closing_wait == USF_CLOSING_WAIT_NONE ? + ASYNC_CLOSING_WAIT_NONE : + state->closing_wait; + tmp.custom_divisor = port->custom_divisor; + tmp.hub6 = port->hub6; + tmp.io_type = port->iotype; + tmp.iomem_reg_shift = port->regshift; + tmp.iomem_base = (void *)port->mapbase; + + if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) + return -EFAULT; + return 0; +} + +static int mp_set_info(struct sb_uart_state *state, struct serial_struct *newinfo) +{ + struct serial_struct new_serial; + struct sb_uart_port *port = state->port; + unsigned long new_port; + unsigned int change_irq, change_port, closing_wait; + unsigned int old_custom_divisor; + unsigned int old_flags, new_flags; + int retval = 0; + + if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) + return -EFAULT; + + new_port = new_serial.port; + if (HIGH_BITS_OFFSET) + new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; + + new_serial.irq = irq_canonicalize(new_serial.irq); + + closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? + USF_CLOSING_WAIT_NONE : new_serial.closing_wait; + MP_STATE_LOCK(state); + + change_irq = new_serial.irq != port->irq; + change_port = new_port != port->iobase || + (unsigned long)new_serial.iomem_base != port->mapbase || + new_serial.hub6 != port->hub6 || + new_serial.io_type != port->iotype || + new_serial.iomem_reg_shift != port->regshift || + new_serial.type != port->type; + old_flags = port->flags; + new_flags = new_serial.flags; + old_custom_divisor = port->custom_divisor; + + if (!capable(CAP_SYS_ADMIN)) { + retval = -EPERM; + if (change_irq || change_port || + (new_serial.baud_base != port->uartclk / 16) || + (new_serial.close_delay != state->close_delay) || + (closing_wait != state->closing_wait) || + (new_serial.xmit_fifo_size != port->fifosize) || + (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0)) + goto exit; + port->flags = ((port->flags & ~UPF_USR_MASK) | + (new_flags & UPF_USR_MASK)); + port->custom_divisor = new_serial.custom_divisor; + goto check_and_exit; + } + + if (port->ops->verify_port) + retval = port->ops->verify_port(port, &new_serial); + + if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || + (new_serial.baud_base < 9600)) + retval = -EINVAL; + + if (retval) + goto exit; + + if (change_port || change_irq) { + retval = -EBUSY; + + if (uart_users(state) > 1) + goto exit; + + mp_shutdown(state); + } + + if (change_port) { + unsigned long old_iobase, old_mapbase; + unsigned int old_type, old_iotype, old_hub6, old_shift; + + old_iobase = port->iobase; + old_mapbase = port->mapbase; + old_type = port->type; + old_hub6 = port->hub6; + old_iotype = port->iotype; + old_shift = port->regshift; + + if (old_type != PORT_UNKNOWN) + port->ops->release_port(port); + + port->iobase = new_port; + port->type = new_serial.type; + port->hub6 = new_serial.hub6; + port->iotype = new_serial.io_type; + port->regshift = new_serial.iomem_reg_shift; + port->mapbase = (unsigned long)new_serial.iomem_base; + + if (port->type != PORT_UNKNOWN) { + retval = port->ops->request_port(port); + } else { + retval = 0; + } + + if (retval && old_type != PORT_UNKNOWN) { + port->iobase = old_iobase; + port->type = old_type; + port->hub6 = old_hub6; + port->iotype = old_iotype; + port->regshift = old_shift; + port->mapbase = old_mapbase; + retval = port->ops->request_port(port); + if (retval) + port->type = PORT_UNKNOWN; + + retval = -EBUSY; + } + } + + port->irq = new_serial.irq; + port->uartclk = new_serial.baud_base * 16; + port->flags = (port->flags & ~UPF_CHANGE_MASK) | + (new_flags & UPF_CHANGE_MASK); + port->custom_divisor = new_serial.custom_divisor; + state->close_delay = new_serial.close_delay; + state->closing_wait = closing_wait; + port->fifosize = new_serial.xmit_fifo_size; + if (state->info->tty) + state->info->tty->low_latency = + (port->flags & UPF_LOW_LATENCY) ? 1 : 0; + +check_and_exit: + retval = 0; + if (port->type == PORT_UNKNOWN) + goto exit; + if (state->info->flags & UIF_INITIALIZED) { + if (((old_flags ^ port->flags) & UPF_SPD_MASK) || + old_custom_divisor != port->custom_divisor) { + if (port->flags & UPF_SPD_MASK) { + printk(KERN_NOTICE + "%s sets custom speed on ttyMP%d. This " + "is deprecated.\n", current->comm, + port->line); + } + mp_change_speed(state, NULL); + } + } else + retval = mp_startup(state, 1); +exit: + MP_STATE_UNLOCK(state); + return retval; +} + + +static int mp_get_lsr_info(struct sb_uart_state *state, unsigned int *value) +{ + struct sb_uart_port *port = state->port; + unsigned int result; + + result = port->ops->tx_empty(port); + + if (port->x_char || + ((uart_circ_chars_pending(&state->info->xmit) > 0) && + !state->info->tty->stopped && !state->info->tty->hw_stopped)) + result &= ~TIOCSER_TEMT; + + return put_user(result, value); +} + +static int mp_tiocmget(struct tty_struct *tty) +{ + struct sb_uart_state *state = tty->driver_data; + struct sb_uart_port *port = state->port; + int result = -EIO; + + MP_STATE_LOCK(state); + if (!(tty->flags & (1 << TTY_IO_ERROR))) { + result = port->mctrl; + spin_lock_irq(&port->lock); + result |= port->ops->get_mctrl(port); + spin_unlock_irq(&port->lock); + } + MP_STATE_UNLOCK(state); + return result; +} + +static int mp_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) +{ + struct sb_uart_state *state = tty->driver_data; + struct sb_uart_port *port = state->port; + int ret = -EIO; + + + MP_STATE_LOCK(state); + if (!(tty->flags & (1 << TTY_IO_ERROR))) { + mp_update_mctrl(port, set, clear); + ret = 0; + } + MP_STATE_UNLOCK(state); + + return ret; +} + +static int mp_break_ctl(struct tty_struct *tty, int break_state) +{ + struct sb_uart_state *state = tty->driver_data; + struct sb_uart_port *port = state->port; + + MP_STATE_LOCK(state); + + if (port->type != PORT_UNKNOWN) + port->ops->break_ctl(port, break_state); + + MP_STATE_UNLOCK(state); + return 0; +} + +static int mp_do_autoconfig(struct sb_uart_state *state) +{ + struct sb_uart_port *port = state->port; + int flags, ret; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (mutex_lock_interruptible(&state->mutex)) + return -ERESTARTSYS; + ret = -EBUSY; + if (uart_users(state) == 1) { + mp_shutdown(state); + + if (port->type != PORT_UNKNOWN) + port->ops->release_port(port); + + flags = UART_CONFIG_TYPE; + if (port->flags & UPF_AUTO_IRQ) + flags |= UART_CONFIG_IRQ; + + port->ops->config_port(port, flags); + + ret = mp_startup(state, 1); + } + MP_STATE_UNLOCK(state); + return ret; +} + +static int mp_wait_modem_status(struct sb_uart_state *state, unsigned long arg) +{ + struct sb_uart_port *port = state->port; + DECLARE_WAITQUEUE(wait, current); + struct sb_uart_icount cprev, cnow; + int ret; + + spin_lock_irq(&port->lock); + memcpy(&cprev, &port->icount, sizeof(struct sb_uart_icount)); + + port->ops->enable_ms(port); + spin_unlock_irq(&port->lock); + + add_wait_queue(&state->info->delta_msr_wait, &wait); + for (;;) { + spin_lock_irq(&port->lock); + memcpy(&cnow, &port->icount, sizeof(struct sb_uart_icount)); + spin_unlock_irq(&port->lock); + + set_current_state(TASK_INTERRUPTIBLE); + + if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || + ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { + ret = 0; + break; + } + + schedule(); + + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + + cprev = cnow; + } + + current->state = TASK_RUNNING; + remove_wait_queue(&state->info->delta_msr_wait, &wait); + + return ret; +} + +static int mp_get_count(struct sb_uart_state *state, struct serial_icounter_struct *icnt) +{ + struct serial_icounter_struct icount; + struct sb_uart_icount cnow; + struct sb_uart_port *port = state->port; + + spin_lock_irq(&port->lock); + memcpy(&cnow, &port->icount, sizeof(struct sb_uart_icount)); + spin_unlock_irq(&port->lock); + + icount.cts = cnow.cts; + icount.dsr = cnow.dsr; + icount.rng = cnow.rng; + icount.dcd = cnow.dcd; + icount.rx = cnow.rx; + icount.tx = cnow.tx; + icount.frame = cnow.frame; + icount.overrun = cnow.overrun; + icount.parity = cnow.parity; + icount.brk = cnow.brk; + icount.buf_overrun = cnow.buf_overrun; + + return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0; +} + +static int mp_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) +{ + struct sb_uart_state *state = tty->driver_data; + struct mp_port *info = (struct mp_port *)state->port; + int ret = -ENOIOCTLCMD; + + + switch (cmd) { + case TIOCSMULTIDROP: + /* set multi-drop mode enable or disable, and default operation mode is H/W mode */ + if (info->port.type == PORT_16C105XA) + { + //arg &= ~0x6; + //state->port->mdmode = 0; + return set_multidrop_mode((struct sb_uart_port *)info, (unsigned int)arg); + } + ret = -ENOTSUPP; + break; + case GETDEEPFIFO: + ret = get_deep_fifo(state->port); + return ret; + case SETDEEPFIFO: + ret = set_deep_fifo(state->port,arg); + deep[state->port->line] = arg; + return ret; + case SETTTR: + if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){ + ret = sb1054_set_register(state->port,PAGE_4,SB105X_TTR,arg); + ttr[state->port->line] = arg; + } + return ret; + case SETRTR: + if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){ + ret = sb1054_set_register(state->port,PAGE_4,SB105X_RTR,arg); + rtr[state->port->line] = arg; + } + return ret; + case GETTTR: + if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){ + ret = sb1054_get_register(state->port,PAGE_4,SB105X_TTR); + } + return ret; + case GETRTR: + if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){ + ret = sb1054_get_register(state->port,PAGE_4,SB105X_RTR); + } + return ret; + + case SETFCR: + if (info->port.type == PORT_16C105X || info->port.type == PORT_16C105XA){ + ret = sb1054_set_register(state->port,PAGE_1,SB105X_FCR,arg); + } + else{ + serial_out(info,2,arg); + } + + return ret; + case TIOCSMDADDR: + /* set multi-drop address */ + if (info->port.type == PORT_16C105XA) + { + state->port->mdmode |= MDMODE_ADDR; + return set_multidrop_addr((struct sb_uart_port *)info, (unsigned int)arg); + } + ret = -ENOTSUPP; + break; + + case TIOCGMDADDR: + /* set multi-drop address */ + if ((info->port.type == PORT_16C105XA) && (state->port->mdmode & MDMODE_ADDR)) + { + return get_multidrop_addr((struct sb_uart_port *)info); + } + ret = -ENOTSUPP; + break; + + case TIOCSENDADDR: + /* send address in multi-drop mode */ + if ((info->port.type == PORT_16C105XA) + && (state->port->mdmode & (MDMODE_ENABLE))) + { + if (mp_chars_in_buffer(tty) > 0) + { + tty_wait_until_sent(tty, 0); + } + //while ((serial_in(info, UART_LSR) & 0x60) != 0x60); + //while (sb1054_get_register(state->port, PAGE_2, SB105X_TFCR) != 0); + while ((serial_in(info, UART_LSR) & 0x60) != 0x60); + serial_out(info, UART_SCR, (int)arg); + } + break; + + case TIOCGSERIAL: + ret = mp_get_info(state, (struct serial_struct *)arg); + break; + + case TIOCSSERIAL: + ret = mp_set_info(state, (struct serial_struct *)arg); + break; + + case TIOCSERCONFIG: + ret = mp_do_autoconfig(state); + break; + + case TIOCSERGWILD: /* obsolete */ + case TIOCSERSWILD: /* obsolete */ + ret = 0; + break; + /* for Multiport */ + case TIOCGNUMOFPORT: /* Get number of ports */ + return NR_PORTS; + case TIOCGGETDEVID: + return mp_devs[arg].device_id; + case TIOCGGETREV: + return mp_devs[arg].revision; + case TIOCGGETNRPORTS: + return mp_devs[arg].nr_ports; + case TIOCGGETBDNO: + return NR_BOARD; + case TIOCGGETINTERFACE: + if (mp_devs[arg].revision == 0xc0) + { + /* for SB16C1053APCI */ + return (sb1053a_get_interface(info, info->port.line)); + } + else + { + return (inb(mp_devs[arg].option_reg_addr+MP_OPTR_IIR0+(state->port->line/8))); + } + case TIOCGGETPORTTYPE: + ret = get_device_type(arg);; + return ret; + case TIOCSMULTIECHO: /* set to multi-drop mode(RS422) or echo mode(RS485)*/ + outb( ( inb(info->interface_config_addr) & ~0x03 ) | 0x01 , + info->interface_config_addr); + return 0; + case TIOCSPTPNOECHO: /* set to multi-drop mode(RS422) or echo mode(RS485) */ + outb( ( inb(info->interface_config_addr) & ~0x03 ) , + info->interface_config_addr); + return 0; + } + + if (ret != -ENOIOCTLCMD) + goto out; + + if (tty->flags & (1 << TTY_IO_ERROR)) { + ret = -EIO; + goto out; + } + + switch (cmd) { + case TIOCMIWAIT: + ret = mp_wait_modem_status(state, arg); + break; + + case TIOCGICOUNT: + ret = mp_get_count(state, (struct serial_icounter_struct *)arg); + break; + } + + if (ret != -ENOIOCTLCMD) + goto out; + + MP_STATE_LOCK(state); + switch (cmd) { + case TIOCSERGETLSR: /* Get line status register */ + ret = mp_get_lsr_info(state, (unsigned int *)arg); + break; + + default: { + struct sb_uart_port *port = state->port; + if (port->ops->ioctl) + ret = port->ops->ioctl(port, cmd, arg); + break; + } + } + + MP_STATE_UNLOCK(state); +out: + return ret; +} + +static void mp_set_termios(struct tty_struct *tty, struct MP_TERMIOS *old_termios) +{ + struct sb_uart_state *state = tty->driver_data; + unsigned long flags; + unsigned int cflag = tty->termios.c_cflag; + +#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + + if ((cflag ^ old_termios->c_cflag) == 0 && + RELEVANT_IFLAG(tty->termios.c_iflag ^ old_termios->c_iflag) == 0) + return; + + mp_change_speed(state, old_termios); + + if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) + uart_clear_mctrl(state->port, TIOCM_RTS | TIOCM_DTR); + + if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) { + unsigned int mask = TIOCM_DTR; + if (!(cflag & CRTSCTS) || + !test_bit(TTY_THROTTLED, &tty->flags)) + mask |= TIOCM_RTS; + uart_set_mctrl(state->port, mask); + } + + if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) { + spin_lock_irqsave(&state->port->lock, flags); + tty->hw_stopped = 0; + __mp_start(tty); + spin_unlock_irqrestore(&state->port->lock, flags); + } + + if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { + spin_lock_irqsave(&state->port->lock, flags); + if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) { + tty->hw_stopped = 1; + state->port->ops->stop_tx(state->port); + } + spin_unlock_irqrestore(&state->port->lock, flags); + } +} + +static void mp_close(struct tty_struct *tty, struct file *filp) +{ + struct sb_uart_state *state = tty->driver_data; + struct sb_uart_port *port; + + printk("mp_close!\n"); + if (!state || !state->port) + return; + + port = state->port; + + printk("close1 %d\n", __LINE__); + MP_STATE_LOCK(state); + + printk("close2 %d\n", __LINE__); + if (tty_hung_up_p(filp)) + goto done; + + printk("close3 %d\n", __LINE__); + if ((tty->count == 1) && (state->count != 1)) { + printk("mp_close: bad serial port count; tty->count is 1, " + "state->count is %d\n", state->count); + state->count = 1; + } + printk("close4 %d\n", __LINE__); + if (--state->count < 0) { + printk("rs_close: bad serial port count for ttyMP%d: %d\n", + port->line, state->count); + state->count = 0; + } + if (state->count) + goto done; + + tty->closing = 1; + + printk("close5 %d\n", __LINE__); + if (state->closing_wait != USF_CLOSING_WAIT_NONE) + tty_wait_until_sent(tty, state->closing_wait); + + printk("close6 %d\n", __LINE__); + if (state->info->flags & UIF_INITIALIZED) { + unsigned long flags; + spin_lock_irqsave(&port->lock, flags); + port->ops->stop_rx(port); + spin_unlock_irqrestore(&port->lock, flags); + mp_wait_until_sent(tty, port->timeout); + } + printk("close7 %d\n", __LINE__); + + mp_shutdown(state); + printk("close8 %d\n", __LINE__); + mp_flush_buffer(tty); + tty_ldisc_flush(tty); + tty->closing = 0; + state->info->tty = NULL; + if (state->info->blocked_open) + { + if (state->close_delay) + { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(state->close_delay); + } + } + else + { + mp_change_pm(state, 3); + } + printk("close8 %d\n", __LINE__); + + state->info->flags &= ~UIF_NORMAL_ACTIVE; + wake_up_interruptible(&state->info->open_wait); + +done: + printk("close done\n"); + MP_STATE_UNLOCK(state); + module_put(THIS_MODULE); +} + +static void mp_wait_until_sent(struct tty_struct *tty, int timeout) +{ + struct sb_uart_state *state = tty->driver_data; + struct sb_uart_port *port = state->port; + unsigned long char_time, expire; + + if (port->type == PORT_UNKNOWN || port->fifosize == 0) + return; + + char_time = (port->timeout - HZ/50) / port->fifosize; + char_time = char_time / 5; + if (char_time == 0) + char_time = 1; + if (timeout && timeout < char_time) + char_time = timeout; + + if (timeout == 0 || timeout > 2 * port->timeout) + timeout = 2 * port->timeout; + + expire = jiffies + timeout; + + while (!port->ops->tx_empty(port)) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(char_time); + if (signal_pending(current)) + break; + if (time_after(jiffies, expire)) + break; + } + set_current_state(TASK_RUNNING); /* might not be needed */ +} + +static void mp_hangup(struct tty_struct *tty) +{ + struct sb_uart_state *state = tty->driver_data; + + MP_STATE_LOCK(state); + if (state->info && state->info->flags & UIF_NORMAL_ACTIVE) { + mp_flush_buffer(tty); + mp_shutdown(state); + state->count = 0; + state->info->flags &= ~UIF_NORMAL_ACTIVE; + state->info->tty = NULL; + wake_up_interruptible(&state->info->open_wait); + wake_up_interruptible(&state->info->delta_msr_wait); + } + MP_STATE_UNLOCK(state); +} + +static void mp_update_termios(struct sb_uart_state *state) +{ + struct tty_struct *tty = state->info->tty; + struct sb_uart_port *port = state->port; + + if (!(tty->flags & (1 << TTY_IO_ERROR))) { + mp_change_speed(state, NULL); + + if (tty->termios.c_cflag & CBAUD) + uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS); + } +} + +static int mp_block_til_ready(struct file *filp, struct sb_uart_state *state) +{ + DECLARE_WAITQUEUE(wait, current); + struct sb_uart_info *info = state->info; + struct sb_uart_port *port = state->port; + unsigned int mctrl; + + info->blocked_open++; + state->count--; + + add_wait_queue(&info->open_wait, &wait); + while (1) { + set_current_state(TASK_INTERRUPTIBLE); + + if (tty_hung_up_p(filp) || info->tty == NULL) + break; + + if (!(info->flags & UIF_INITIALIZED)) + break; + + if ((filp->f_flags & O_NONBLOCK) || + (info->tty->termios.c_cflag & CLOCAL) || + (info->tty->flags & (1 << TTY_IO_ERROR))) { + break; + } + + if (info->tty->termios.c_cflag & CBAUD) + uart_set_mctrl(port, TIOCM_DTR); + + spin_lock_irq(&port->lock); + port->ops->enable_ms(port); + mctrl = port->ops->get_mctrl(port); + spin_unlock_irq(&port->lock); + if (mctrl & TIOCM_CAR) + break; + + MP_STATE_UNLOCK(state); + schedule(); + MP_STATE_LOCK(state); + + if (signal_pending(current)) + break; + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&info->open_wait, &wait); + + state->count++; + info->blocked_open--; + + if (signal_pending(current)) + return -ERESTARTSYS; + + if (!info->tty || tty_hung_up_p(filp)) + return -EAGAIN; + + return 0; +} + +static struct sb_uart_state *uart_get(struct uart_driver *drv, int line) +{ + struct sb_uart_state *state; + + MP_MUTEX_LOCK(mp_mutex); + state = drv->state + line; + if (mutex_lock_interruptible(&state->mutex)) { + state = ERR_PTR(-ERESTARTSYS); + goto out; + } + state->count++; + if (!state->port) { + state->count--; + MP_STATE_UNLOCK(state); + state = ERR_PTR(-ENXIO); + goto out; + } + + if (!state->info) { + state->info = kmalloc(sizeof(struct sb_uart_info), GFP_KERNEL); + if (state->info) { + memset(state->info, 0, sizeof(struct sb_uart_info)); + init_waitqueue_head(&state->info->open_wait); + init_waitqueue_head(&state->info->delta_msr_wait); + + state->port->info = state->info; + + tasklet_init(&state->info->tlet, mp_tasklet_action, + (unsigned long)state); + } else { + state->count--; + MP_STATE_UNLOCK(state); + state = ERR_PTR(-ENOMEM); + } + } + +out: + MP_MUTEX_UNLOCK(mp_mutex); + return state; +} + +static int mp_open(struct tty_struct *tty, struct file *filp) +{ + struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state; + struct sb_uart_state *state; + int retval; + int line = tty->index; + struct mp_port *mtpt; + + retval = -ENODEV; + if (line >= tty->driver->num) + goto fail; + + state = uart_get(drv, line); + + mtpt = (struct mp_port *)state->port; + + if (IS_ERR(state)) { + retval = PTR_ERR(state); + goto fail; + } + + tty->driver_data = state; + tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0; + tty->alt_speed = 0; + state->info->tty = tty; + + if (tty_hung_up_p(filp)) { + retval = -EAGAIN; + state->count--; + MP_STATE_UNLOCK(state); + goto fail; + } + + if (state->count == 1) + mp_change_pm(state, 0); + + retval = mp_startup(state, 0); + + if (retval == 0) + retval = mp_block_til_ready(filp, state); + MP_STATE_UNLOCK(state); + + if (retval == 0 && !(state->info->flags & UIF_NORMAL_ACTIVE)) { + state->info->flags |= UIF_NORMAL_ACTIVE; + + mp_update_termios(state); + } + + uart_clear_mctrl(state->port, TIOCM_RTS); + try_module_get(THIS_MODULE); +fail: + return retval; +} + + +static const char *mp_type(struct sb_uart_port *port) +{ + const char *str = NULL; + + if (port->ops->type) + str = port->ops->type(port); + + if (!str) + str = "unknown"; + + return str; +} + +static void mp_change_pm(struct sb_uart_state *state, int pm_state) +{ + struct sb_uart_port *port = state->port; + if (port->ops->pm) + port->ops->pm(port, pm_state, state->pm_state); + state->pm_state = pm_state; +} + +static inline void mp_report_port(struct uart_driver *drv, struct sb_uart_port *port) +{ + char address[64]; + + switch (port->iotype) { + case UPIO_PORT: + snprintf(address, sizeof(address),"I/O 0x%x", port->iobase); + break; + case UPIO_HUB6: + snprintf(address, sizeof(address),"I/O 0x%x offset 0x%x", port->iobase, port->hub6); + break; + case UPIO_MEM: + snprintf(address, sizeof(address),"MMIO 0x%lx", port->mapbase); + break; + default: + snprintf(address, sizeof(address),"*unknown*" ); + strlcpy(address, "*unknown*", sizeof(address)); + break; + } + + printk( "%s%d at %s (irq = %d) is a %s\n", + drv->dev_name, port->line, address, port->irq, mp_type(port)); + +} + +static void mp_configure_port(struct uart_driver *drv, struct sb_uart_state *state, struct sb_uart_port *port) +{ + unsigned int flags; + + + if (!port->iobase && !port->mapbase && !port->membase) + { + DPRINTK("%s error \n",__FUNCTION__); + return; + } + flags = UART_CONFIG_TYPE; + if (port->flags & UPF_AUTO_IRQ) + flags |= UART_CONFIG_IRQ; + if (port->flags & UPF_BOOT_AUTOCONF) { + port->type = PORT_UNKNOWN; + port->ops->config_port(port, flags); + } + + if (port->type != PORT_UNKNOWN) { + unsigned long flags; + + mp_report_port(drv, port); + + spin_lock_irqsave(&port->lock, flags); + port->ops->set_mctrl(port, 0); + spin_unlock_irqrestore(&port->lock, flags); + + mp_change_pm(state, 3); + } +} + +static void mp_unconfigure_port(struct uart_driver *drv, struct sb_uart_state *state) +{ + struct sb_uart_port *port = state->port; + struct sb_uart_info *info = state->info; + + if (info && info->tty) + tty_hangup(info->tty); + + MP_STATE_LOCK(state); + + state->info = NULL; + + if (port->type != PORT_UNKNOWN) + port->ops->release_port(port); + + port->type = PORT_UNKNOWN; + + if (info) { + tasklet_kill(&info->tlet); + kfree(info); + } + + MP_STATE_UNLOCK(state); +} +static struct tty_operations mp_ops = { + .open = mp_open, + .close = mp_close, + .write = mp_write, + .put_char = mp_put_char, + .flush_chars = mp_put_chars, + .write_room = mp_write_room, + .chars_in_buffer= mp_chars_in_buffer, + .flush_buffer = mp_flush_buffer, + .ioctl = mp_ioctl, + .throttle = mp_throttle, + .unthrottle = mp_unthrottle, + .send_xchar = mp_send_xchar, + .set_termios = mp_set_termios, + .stop = mp_stop, + .start = mp_start, + .hangup = mp_hangup, + .break_ctl = mp_break_ctl, + .wait_until_sent= mp_wait_until_sent, +#ifdef CONFIG_PROC_FS + .proc_fops = NULL, +#endif + .tiocmget = mp_tiocmget, + .tiocmset = mp_tiocmset, +}; + +static int mp_register_driver(struct uart_driver *drv) +{ + struct tty_driver *normal = NULL; + int i, retval; + + drv->state = kmalloc(sizeof(struct sb_uart_state) * drv->nr, GFP_KERNEL); + retval = -ENOMEM; + if (!drv->state) + { + printk("SB PCI Error: Kernel memory allocation error!\n"); + goto out; + } + memset(drv->state, 0, sizeof(struct sb_uart_state) * drv->nr); + + normal = alloc_tty_driver(drv->nr); + if (!normal) + { + printk("SB PCI Error: tty allocation error!\n"); + goto out; + } + + drv->tty_driver = normal; + + normal->owner = drv->owner; + normal->magic = TTY_DRIVER_MAGIC; + normal->driver_name = drv->driver_name; + normal->name = drv->dev_name; + normal->major = drv->major; + normal->minor_start = drv->minor; + + normal->num = MAX_MP_PORT ; + + normal->type = TTY_DRIVER_TYPE_SERIAL; + normal->subtype = SERIAL_TYPE_NORMAL; + normal->init_termios = tty_std_termios; + normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + normal->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + normal->driver_state = drv; + + tty_set_operations(normal, &mp_ops); + +for (i = 0; i < drv->nr; i++) { + struct sb_uart_state *state = drv->state + i; + + state->close_delay = 500; + state->closing_wait = 30000; + + mutex_init(&state->mutex); + } + + retval = tty_register_driver(normal); +out: + if (retval < 0) { + printk("Register tty driver Fail!\n"); + put_tty_driver(normal); + kfree(drv->state); + } + + return retval; +} + +void mp_unregister_driver(struct uart_driver *drv) +{ + struct tty_driver *normal = NULL; + + normal = drv->tty_driver; + + if (!normal) + { + return; + } + + tty_unregister_driver(normal); + put_tty_driver(normal); + drv->tty_driver = NULL; + + + if (drv->state) + { + kfree(drv->state); + } + +} + +static int mp_add_one_port(struct uart_driver *drv, struct sb_uart_port *port) +{ + struct sb_uart_state *state; + int ret = 0; + + + if (port->line >= drv->nr) + return -EINVAL; + + state = drv->state + port->line; + + MP_MUTEX_LOCK(mp_mutex); + if (state->port) { + ret = -EINVAL; + goto out; + } + + state->port = port; + + spin_lock_init(&port->lock); + port->cons = drv->cons; + port->info = state->info; + + mp_configure_port(drv, state, port); + + tty_register_device(drv->tty_driver, port->line, port->dev); + +out: + MP_MUTEX_UNLOCK(mp_mutex); + + + return ret; +} + +static int mp_remove_one_port(struct uart_driver *drv, struct sb_uart_port *port) +{ + struct sb_uart_state *state = drv->state + port->line; + + if (state->port != port) + printk(KERN_ALERT "Removing wrong port: %p != %p\n", + state->port, port); + + MP_MUTEX_LOCK(mp_mutex); + + tty_unregister_device(drv->tty_driver, port->line); + + mp_unconfigure_port(drv, state); + state->port = NULL; + MP_MUTEX_UNLOCK(mp_mutex); + + return 0; +} + +static void autoconfig(struct mp_port *mtpt, unsigned int probeflags) +{ + unsigned char status1, scratch, scratch2, scratch3; + unsigned char save_lcr, save_mcr; + unsigned long flags; + + unsigned char u_type; + unsigned char b_ret = 0; + + if (!mtpt->port.iobase && !mtpt->port.mapbase && !mtpt->port.membase) + return; + + DEBUG_AUTOCONF("ttyMP%d: autoconf (0x%04x, 0x%p): ", + mtpt->port.line, mtpt->port.iobase, mtpt->port.membase); + + spin_lock_irqsave(&mtpt->port.lock, flags); + + if (!(mtpt->port.flags & UPF_BUGGY_UART)) { + scratch = serial_inp(mtpt, UART_IER); + serial_outp(mtpt, UART_IER, 0); +#ifdef __i386__ + outb(0xff, 0x080); +#endif + scratch2 = serial_inp(mtpt, UART_IER) & 0x0f; + serial_outp(mtpt, UART_IER, 0x0F); +#ifdef __i386__ + outb(0, 0x080); +#endif + scratch3 = serial_inp(mtpt, UART_IER) & 0x0F; + serial_outp(mtpt, UART_IER, scratch); + if (scratch2 != 0 || scratch3 != 0x0F) { + DEBUG_AUTOCONF("IER test failed (%02x, %02x) ", + scratch2, scratch3); + goto out; + } + } + + save_mcr = serial_in(mtpt, UART_MCR); + save_lcr = serial_in(mtpt, UART_LCR); + + if (!(mtpt->port.flags & UPF_SKIP_TEST)) { + serial_outp(mtpt, UART_MCR, UART_MCR_LOOP | 0x0A); + status1 = serial_inp(mtpt, UART_MSR) & 0xF0; + serial_outp(mtpt, UART_MCR, save_mcr); + if (status1 != 0x90) { + DEBUG_AUTOCONF("LOOP test failed (%02x) ", + status1); + goto out; + } + } + + serial_outp(mtpt, UART_LCR, 0xBF); + serial_outp(mtpt, UART_EFR, 0); + serial_outp(mtpt, UART_LCR, 0); + + serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO); + scratch = serial_in(mtpt, UART_IIR) >> 6; + + DEBUG_AUTOCONF("iir=%d ", scratch); + if(mtpt->device->nr_ports >= 8) + b_ret = read_option_register(mtpt,(MP_OPTR_DIR0 + ((mtpt->port.line)/8))); + else + b_ret = read_option_register(mtpt,MP_OPTR_DIR0); + u_type = (b_ret & 0xf0) >> 4; + if(mtpt->port.type == PORT_UNKNOWN ) + { + switch (u_type) + { + case DIR_UART_16C550: + mtpt->port.type = PORT_16C55X; + break; + case DIR_UART_16C1050: + mtpt->port.type = PORT_16C105X; + break; + case DIR_UART_16C1050A: + if (mtpt->port.line < 2) + { + mtpt->port.type = PORT_16C105XA; + } + else + { + if (mtpt->device->device_id & 0x50) + { + mtpt->port.type = PORT_16C55X; + } + else + { + mtpt->port.type = PORT_16C105X; + } + } + break; + default: + mtpt->port.type = PORT_UNKNOWN; + break; + } + } + + if(mtpt->port.type == PORT_UNKNOWN ) + { +printk("unknow2\n"); + switch (scratch) { + case 0: + case 1: + mtpt->port.type = PORT_UNKNOWN; + break; + case 2: + case 3: + mtpt->port.type = PORT_16C55X; + break; + } + } + + serial_outp(mtpt, UART_LCR, save_lcr); + + mtpt->port.fifosize = uart_config[mtpt->port.type].dfl_xmit_fifo_size; + mtpt->capabilities = uart_config[mtpt->port.type].flags; + + if (mtpt->port.type == PORT_UNKNOWN) + goto out; + serial_outp(mtpt, UART_MCR, save_mcr); + serial_outp(mtpt, UART_FCR, (UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT)); + serial_outp(mtpt, UART_FCR, 0); + (void)serial_in(mtpt, UART_RX); + serial_outp(mtpt, UART_IER, 0); + +out: + spin_unlock_irqrestore(&mtpt->port.lock, flags); + DEBUG_AUTOCONF("type=%s\n", uart_config[mtpt->port.type].name); +} + +static void autoconfig_irq(struct mp_port *mtpt) +{ + unsigned char save_mcr, save_ier; + unsigned long irqs; + int irq; + + /* forget possible initially masked and pending IRQ */ + probe_irq_off(probe_irq_on()); + save_mcr = serial_inp(mtpt, UART_MCR); + save_ier = serial_inp(mtpt, UART_IER); + serial_outp(mtpt, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); + + irqs = probe_irq_on(); + serial_outp(mtpt, UART_MCR, 0); + serial_outp(mtpt, UART_MCR, + UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); + + serial_outp(mtpt, UART_IER, 0x0f); /* enable all intrs */ + (void)serial_inp(mtpt, UART_LSR); + (void)serial_inp(mtpt, UART_RX); + (void)serial_inp(mtpt, UART_IIR); + (void)serial_inp(mtpt, UART_MSR); + serial_outp(mtpt, UART_TX, 0xFF); + irq = probe_irq_off(irqs); + + serial_outp(mtpt, UART_MCR, save_mcr); + serial_outp(mtpt, UART_IER, save_ier); + + mtpt->port.irq = (irq > 0) ? irq : 0; +} + +static void multi_stop_tx(struct sb_uart_port *port) +{ + struct mp_port *mtpt = (struct mp_port *)port; + + if (mtpt->ier & UART_IER_THRI) { + mtpt->ier &= ~UART_IER_THRI; + serial_out(mtpt, UART_IER, mtpt->ier); + } + + tasklet_schedule(&port->info->tlet); +} + +static void multi_start_tx(struct sb_uart_port *port) +{ + struct mp_port *mtpt = (struct mp_port *)port; + + if (!(mtpt->ier & UART_IER_THRI)) { + mtpt->ier |= UART_IER_THRI; + serial_out(mtpt, UART_IER, mtpt->ier); + } +} + +static void multi_stop_rx(struct sb_uart_port *port) +{ + struct mp_port *mtpt = (struct mp_port *)port; + + mtpt->ier &= ~UART_IER_RLSI; + mtpt->port.read_status_mask &= ~UART_LSR_DR; + serial_out(mtpt, UART_IER, mtpt->ier); +} + +static void multi_enable_ms(struct sb_uart_port *port) +{ + struct mp_port *mtpt = (struct mp_port *)port; + + mtpt->ier |= UART_IER_MSI; + serial_out(mtpt, UART_IER, mtpt->ier); +} + + +static _INLINE_ void receive_chars(struct mp_port *mtpt, int *status ) +{ + struct tty_struct *tty = mtpt->port.info->tty; + unsigned char lsr = *status; + int max_count = 256; + unsigned char ch; + char flag; + + //lsr &= mtpt->port.read_status_mask; + + do { + if ((lsr & UART_LSR_PE) && (mtpt->port.mdmode & MDMODE_ENABLE)) + { + ch = serial_inp(mtpt, UART_RX); + } + else if (lsr & UART_LSR_SPECIAL) + { + flag = 0; + ch = serial_inp(mtpt, UART_RX); + + if (lsr & UART_LSR_BI) + { + + mtpt->port.icount.brk++; + flag = TTY_BREAK; + + if (sb_uart_handle_break(&mtpt->port)) + goto ignore_char; + } + if (lsr & UART_LSR_PE) + { + mtpt->port.icount.parity++; + flag = TTY_PARITY; + } + if (lsr & UART_LSR_FE) + { + mtpt->port.icount.frame++; + flag = TTY_FRAME; + } + if (lsr & UART_LSR_OE) + { + mtpt->port.icount.overrun++; + flag = TTY_OVERRUN; + } + tty_insert_flip_char(tty, ch, flag); + } + else + { + ch = serial_inp(mtpt, UART_RX); + tty_insert_flip_char(tty, ch, 0); + } +ignore_char: + lsr = serial_inp(mtpt, UART_LSR); + } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); + + tty_flip_buffer_push(tty); +} + + + + +static _INLINE_ void transmit_chars(struct mp_port *mtpt) +{ + struct circ_buf *xmit = &mtpt->port.info->xmit; + int count; + + if (mtpt->port.x_char) { + serial_outp(mtpt, UART_TX, mtpt->port.x_char); + mtpt->port.icount.tx++; + mtpt->port.x_char = 0; + return; + } + if (uart_circ_empty(xmit) || uart_tx_stopped(&mtpt->port)) { + multi_stop_tx(&mtpt->port); + return; + } + + count = uart_circ_chars_pending(xmit); + + if(count > mtpt->port.fifosize) + { + count = mtpt->port.fifosize; + } + + printk("[%d] mdmode: %x\n", mtpt->port.line, mtpt->port.mdmode); + do { +#if 0 + /* check multi-drop mode */ + if ((mtpt->port.mdmode & (MDMODE_ENABLE | MDMODE_ADDR)) == (MDMODE_ENABLE | MDMODE_ADDR)) + { + printk("send address\n"); + /* send multi-drop address */ + serial_out(mtpt, UART_SCR, xmit->buf[xmit->tail]); + } + else +#endif + { + serial_out(mtpt, UART_TX, xmit->buf[xmit->tail]); + } + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + mtpt->port.icount.tx++; + } while (--count > 0); +} + + + +static _INLINE_ void check_modem_status(struct mp_port *mtpt) +{ + int status; + + status = serial_in(mtpt, UART_MSR); + + if ((status & UART_MSR_ANY_DELTA) == 0) + return; + + if (status & UART_MSR_TERI) + mtpt->port.icount.rng++; + if (status & UART_MSR_DDSR) + mtpt->port.icount.dsr++; + if (status & UART_MSR_DDCD) + sb_uart_handle_dcd_change(&mtpt->port, status & UART_MSR_DCD); + if (status & UART_MSR_DCTS) + sb_uart_handle_cts_change(&mtpt->port, status & UART_MSR_CTS); + + wake_up_interruptible(&mtpt->port.info->delta_msr_wait); +} + +static inline void multi_handle_port(struct mp_port *mtpt) +{ + unsigned int status = serial_inp(mtpt, UART_LSR); + + //printk("lsr: %x\n", status); + + if ((status & UART_LSR_DR) || (status & UART_LSR_SPECIAL)) + receive_chars(mtpt, &status); + check_modem_status(mtpt); + if (status & UART_LSR_THRE) + { + if ((mtpt->port.type == PORT_16C105X) + || (mtpt->port.type == PORT_16C105XA)) + transmit_chars(mtpt); + else + { + if (mtpt->interface >= RS485NE) + uart_set_mctrl(&mtpt->port, TIOCM_RTS); + + transmit_chars(mtpt); + + + if (mtpt->interface >= RS485NE) + { + while((status=serial_in(mtpt,UART_LSR) &0x60)!=0x60); + uart_clear_mctrl(&mtpt->port, TIOCM_RTS); + } + } + } +} + + + +static irqreturn_t multi_interrupt(int irq, void *dev_id) +{ + struct irq_info *iinfo = dev_id; + struct list_head *lhead, *end = NULL; + int pass_counter = 0; + + + spin_lock(&iinfo->lock); + + lhead = iinfo->head; + do { + struct mp_port *mtpt; + unsigned int iir; + + mtpt = list_entry(lhead, struct mp_port, list); + + iir = serial_in(mtpt, UART_IIR); + printk("intrrupt! port %d, iir 0x%x\n", mtpt->port.line, iir); //wlee + if (!(iir & UART_IIR_NO_INT)) + { + printk("interrupt handle\n"); + spin_lock(&mtpt->port.lock); + multi_handle_port(mtpt); + spin_unlock(&mtpt->port.lock); + + end = NULL; + } else if (end == NULL) + end = lhead; + + lhead = lhead->next; + if (lhead == iinfo->head && pass_counter++ > PASS_LIMIT) + { + printk(KERN_ERR "multi: too much work for " + "irq%d\n", irq); + printk( "multi: too much work for " + "irq%d\n", irq); + break; + } + } while (lhead != end); + + spin_unlock(&iinfo->lock); + + + return IRQ_HANDLED; +} + +static void serial_do_unlink(struct irq_info *i, struct mp_port *mtpt) +{ + spin_lock_irq(&i->lock); + + if (!list_empty(i->head)) { + if (i->head == &mtpt->list) + i->head = i->head->next; + list_del(&mtpt->list); + } else { + i->head = NULL; + } + + spin_unlock_irq(&i->lock); +} + +static int serial_link_irq_chain(struct mp_port *mtpt) +{ + struct irq_info *i = irq_lists + mtpt->port.irq; + int ret, irq_flags = mtpt->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; + spin_lock_irq(&i->lock); + + if (i->head) { + list_add(&mtpt->list, i->head); + spin_unlock_irq(&i->lock); + + ret = 0; + } else { + INIT_LIST_HEAD(&mtpt->list); + i->head = &mtpt->list; + spin_unlock_irq(&i->lock); + + ret = request_irq(mtpt->port.irq, multi_interrupt, + irq_flags, "serial", i); + if (ret < 0) + serial_do_unlink(i, mtpt); + } + + return ret; +} + + + + +static void serial_unlink_irq_chain(struct mp_port *mtpt) +{ + struct irq_info *i = irq_lists + mtpt->port.irq; + + if (list_empty(i->head)) + { + free_irq(mtpt->port.irq, i); + } + serial_do_unlink(i, mtpt); +} + +static void multi_timeout(unsigned long data) +{ + struct mp_port *mtpt = (struct mp_port *)data; + + + spin_lock(&mtpt->port.lock); + multi_handle_port(mtpt); + spin_unlock(&mtpt->port.lock); + + mod_timer(&mtpt->timer, jiffies+1 ); +} + +static unsigned int multi_tx_empty(struct sb_uart_port *port) +{ + struct mp_port *mtpt = (struct mp_port *)port; + unsigned long flags; + unsigned int ret; + + spin_lock_irqsave(&mtpt->port.lock, flags); + ret = serial_in(mtpt, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; + spin_unlock_irqrestore(&mtpt->port.lock, flags); + + return ret; +} + + +static unsigned int multi_get_mctrl(struct sb_uart_port *port) +{ + struct mp_port *mtpt = (struct mp_port *)port; + unsigned char status; + unsigned int ret; + + status = serial_in(mtpt, UART_MSR); + + ret = 0; + if (status & UART_MSR_DCD) + ret |= TIOCM_CAR; + if (status & UART_MSR_RI) + ret |= TIOCM_RNG; + if (status & UART_MSR_DSR) + ret |= TIOCM_DSR; + if (status & UART_MSR_CTS) + ret |= TIOCM_CTS; + return ret; +} + +static void multi_set_mctrl(struct sb_uart_port *port, unsigned int mctrl) +{ + struct mp_port *mtpt = (struct mp_port *)port; + unsigned char mcr = 0; + + mctrl &= 0xff; + + if (mctrl & TIOCM_RTS) + mcr |= UART_MCR_RTS; + if (mctrl & TIOCM_DTR) + mcr |= UART_MCR_DTR; + if (mctrl & TIOCM_OUT1) + mcr |= UART_MCR_OUT1; + if (mctrl & TIOCM_OUT2) + mcr |= UART_MCR_OUT2; + if (mctrl & TIOCM_LOOP) + mcr |= UART_MCR_LOOP; + + + serial_out(mtpt, UART_MCR, mcr); +} + + +static void multi_break_ctl(struct sb_uart_port *port, int break_state) +{ + struct mp_port *mtpt = (struct mp_port *)port; + unsigned long flags; + + spin_lock_irqsave(&mtpt->port.lock, flags); + if (break_state == -1) + mtpt->lcr |= UART_LCR_SBC; + else + mtpt->lcr &= ~UART_LCR_SBC; + serial_out(mtpt, UART_LCR, mtpt->lcr); + spin_unlock_irqrestore(&mtpt->port.lock, flags); +} + + + +static int multi_startup(struct sb_uart_port *port) +{ + struct mp_port *mtpt = (struct mp_port *)port; + unsigned long flags; + int retval; + + mtpt->capabilities = uart_config[mtpt->port.type].flags; + mtpt->mcr = 0; + + if (mtpt->capabilities & UART_CLEAR_FIFO) { + serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO); + serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); + serial_outp(mtpt, UART_FCR, 0); + } + + (void) serial_inp(mtpt, UART_LSR); + (void) serial_inp(mtpt, UART_RX); + (void) serial_inp(mtpt, UART_IIR); + (void) serial_inp(mtpt, UART_MSR); + //test-wlee 9-bit disable + serial_outp(mtpt, UART_MSR, 0); + + + if (!(mtpt->port.flags & UPF_BUGGY_UART) && + (serial_inp(mtpt, UART_LSR) == 0xff)) { + printk("ttyS%d: LSR safety check engaged!\n", mtpt->port.line); + //return -ENODEV; + } + + if ((!is_real_interrupt(mtpt->port.irq)) || (mtpt->poll_type==TYPE_POLL)) { + unsigned int timeout = mtpt->port.timeout; + + timeout = timeout > 6 ? (timeout / 2 - 2) : 1; + + mtpt->timer.data = (unsigned long)mtpt; + mod_timer(&mtpt->timer, jiffies + timeout); + } + else + { + retval = serial_link_irq_chain(mtpt); + if (retval) + return retval; + } + + serial_outp(mtpt, UART_LCR, UART_LCR_WLEN8); + + spin_lock_irqsave(&mtpt->port.lock, flags); + if ((is_real_interrupt(mtpt->port.irq))||(mtpt->poll_type==TYPE_INTERRUPT)) + mtpt->port.mctrl |= TIOCM_OUT2; + + multi_set_mctrl(&mtpt->port, mtpt->port.mctrl); + spin_unlock_irqrestore(&mtpt->port.lock, flags); + + + mtpt->ier = UART_IER_RLSI | UART_IER_RDI; + serial_outp(mtpt, UART_IER, mtpt->ier); + + (void) serial_inp(mtpt, UART_LSR); + (void) serial_inp(mtpt, UART_RX); + (void) serial_inp(mtpt, UART_IIR); + (void) serial_inp(mtpt, UART_MSR); + + return 0; +} + + + +static void multi_shutdown(struct sb_uart_port *port) +{ + struct mp_port *mtpt = (struct mp_port *)port; + unsigned long flags; + + + mtpt->ier = 0; + serial_outp(mtpt, UART_IER, 0); + + spin_lock_irqsave(&mtpt->port.lock, flags); + mtpt->port.mctrl &= ~TIOCM_OUT2; + + multi_set_mctrl(&mtpt->port, mtpt->port.mctrl); + spin_unlock_irqrestore(&mtpt->port.lock, flags); + + serial_out(mtpt, UART_LCR, serial_inp(mtpt, UART_LCR) & ~UART_LCR_SBC); + serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT); + serial_outp(mtpt, UART_FCR, 0); + + + (void) serial_in(mtpt, UART_RX); + + if ((!is_real_interrupt(mtpt->port.irq))||(mtpt->poll_type==TYPE_POLL)) + { + del_timer_sync(&mtpt->timer); + } + else + { + serial_unlink_irq_chain(mtpt); + } +} + + + +static unsigned int multi_get_divisor(struct sb_uart_port *port, unsigned int baud) +{ + unsigned int quot; + + if ((port->flags & UPF_MAGIC_MULTIPLIER) && + baud == (port->uartclk/4)) + quot = 0x8001; + else if ((port->flags & UPF_MAGIC_MULTIPLIER) && + baud == (port->uartclk/8)) + quot = 0x8002; + else + quot = sb_uart_get_divisor(port, baud); + + return quot; +} + + + + +static void multi_set_termios(struct sb_uart_port *port, struct MP_TERMIOS *termios, struct MP_TERMIOS *old) +{ + struct mp_port *mtpt = (struct mp_port *)port; + unsigned char cval, fcr = 0; + unsigned long flags; + unsigned int baud, quot; + + switch (termios->c_cflag & CSIZE) { + case CS5: + cval = 0x00; + break; + case CS6: + cval = 0x01; + break; + case CS7: + cval = 0x02; + break; + default: + case CS8: + cval = 0x03; + break; + } + + if (termios->c_cflag & CSTOPB) + cval |= 0x04; + if (termios->c_cflag & PARENB) + cval |= UART_LCR_PARITY; + if (!(termios->c_cflag & PARODD)) + cval |= UART_LCR_EPAR; + +#ifdef CMSPAR + if (termios->c_cflag & CMSPAR) + cval |= UART_LCR_SPAR; +#endif + + baud = sb_uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); + quot = multi_get_divisor(port, baud); + + if (mtpt->capabilities & UART_USE_FIFO) { + //if (baud < 2400) + // fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; + //else + // fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8; + + // fcr = UART_FCR_ENABLE_FIFO | 0x90; + fcr = fcr_arr[mtpt->port.line]; + } + + spin_lock_irqsave(&mtpt->port.lock, flags); + + sb_uart_update_timeout(port, termios->c_cflag, baud); + + mtpt->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; + if (termios->c_iflag & INPCK) + mtpt->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; + if (termios->c_iflag & (BRKINT | PARMRK)) + mtpt->port.read_status_mask |= UART_LSR_BI; + + mtpt->port.ignore_status_mask = 0; + if (termios->c_iflag & IGNPAR) + mtpt->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; + if (termios->c_iflag & IGNBRK) { + mtpt->port.ignore_status_mask |= UART_LSR_BI; + if (termios->c_iflag & IGNPAR) + mtpt->port.ignore_status_mask |= UART_LSR_OE; + } + + if ((termios->c_cflag & CREAD) == 0) + mtpt->port.ignore_status_mask |= UART_LSR_DR; + + mtpt->ier &= ~UART_IER_MSI; + if (UART_ENABLE_MS(&mtpt->port, termios->c_cflag)) + mtpt->ier |= UART_IER_MSI; + + serial_out(mtpt, UART_IER, mtpt->ier); + + if (mtpt->capabilities & UART_STARTECH) { + serial_outp(mtpt, UART_LCR, 0xBF); + serial_outp(mtpt, UART_EFR, + termios->c_cflag & CRTSCTS ? UART_EFR_CTS :0); + } + + serial_outp(mtpt, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ + + serial_outp(mtpt, UART_DLL, quot & 0xff); /* LS of divisor */ + serial_outp(mtpt, UART_DLM, quot >> 8); /* MS of divisor */ + + serial_outp(mtpt, UART_LCR, cval); /* reset DLAB */ + mtpt->lcr = cval; /* Save LCR */ + + if (fcr & UART_FCR_ENABLE_FIFO) { + /* emulated UARTs (Lucent Venus 167x) need two steps */ + serial_outp(mtpt, UART_FCR, UART_FCR_ENABLE_FIFO); + } + + serial_outp(mtpt, UART_FCR, fcr); /* set fcr */ + + + if ((mtpt->port.type == PORT_16C105X) + || (mtpt->port.type == PORT_16C105XA)) + { + if(deep[mtpt->port.line]!=0) + set_deep_fifo(port, ENABLE); + + if (mtpt->interface != RS232) + set_auto_rts(port,mtpt->interface); + + } + else + { + if (mtpt->interface >= RS485NE) + { + uart_clear_mctrl(&mtpt->port, TIOCM_RTS); + } + } + + if(mtpt->device->device_id == PCI_DEVICE_ID_MP4M) + { + SendATCommand(mtpt); + printk("SendATCommand\n"); + } + multi_set_mctrl(&mtpt->port, mtpt->port.mctrl); + spin_unlock_irqrestore(&mtpt->port.lock, flags); +} + +static void multi_pm(struct sb_uart_port *port, unsigned int state, unsigned int oldstate) +{ + struct mp_port *mtpt = (struct mp_port *)port; + if (state) { + if (mtpt->capabilities & UART_STARTECH) { + serial_outp(mtpt, UART_LCR, 0xBF); + serial_outp(mtpt, UART_EFR, UART_EFR_ECB); + serial_outp(mtpt, UART_LCR, 0); + serial_outp(mtpt, UART_IER, UART_IERX_SLEEP); + serial_outp(mtpt, UART_LCR, 0xBF); + serial_outp(mtpt, UART_EFR, 0); + serial_outp(mtpt, UART_LCR, 0); + } + + if (mtpt->pm) + mtpt->pm(port, state, oldstate); + } + else + { + if (mtpt->capabilities & UART_STARTECH) { + serial_outp(mtpt, UART_LCR, 0xBF); + serial_outp(mtpt, UART_EFR, UART_EFR_ECB); + serial_outp(mtpt, UART_LCR, 0); + serial_outp(mtpt, UART_IER, 0); + serial_outp(mtpt, UART_LCR, 0xBF); + serial_outp(mtpt, UART_EFR, 0); + serial_outp(mtpt, UART_LCR, 0); + } + + if (mtpt->pm) + mtpt->pm(port, state, oldstate); + } +} + +static void multi_release_std_resource(struct mp_port *mtpt) +{ + unsigned int size = 8 << mtpt->port.regshift; + + switch (mtpt->port.iotype) { + case UPIO_MEM: + if (!mtpt->port.mapbase) + break; + + if (mtpt->port.flags & UPF_IOREMAP) { + iounmap(mtpt->port.membase); + mtpt->port.membase = NULL; + } + + release_mem_region(mtpt->port.mapbase, size); + break; + + case UPIO_HUB6: + case UPIO_PORT: + release_region(mtpt->port.iobase,size); + break; + } +} + +static void multi_release_port(struct sb_uart_port *port) +{ +} + +static int multi_request_port(struct sb_uart_port *port) +{ + return 0; +} + +static void multi_config_port(struct sb_uart_port *port, int flags) +{ + struct mp_port *mtpt = (struct mp_port *)port; + int probeflags = PROBE_ANY; + + if (flags & UART_CONFIG_TYPE) + autoconfig(mtpt, probeflags); + if (mtpt->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) + autoconfig_irq(mtpt); + + if (mtpt->port.type == PORT_UNKNOWN) + multi_release_std_resource(mtpt); +} + +static int multi_verify_port(struct sb_uart_port *port, struct serial_struct *ser) +{ + if (ser->irq >= NR_IRQS || ser->irq < 0 || + ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || + ser->type == PORT_STARTECH) + return -EINVAL; + return 0; +} + +static const char * multi_type(struct sb_uart_port *port) +{ + int type = port->type; + + if (type >= ARRAY_SIZE(uart_config)) + type = 0; + return uart_config[type].name; +} + +static struct sb_uart_ops multi_pops = { + .tx_empty = multi_tx_empty, + .set_mctrl = multi_set_mctrl, + .get_mctrl = multi_get_mctrl, + .stop_tx = multi_stop_tx, + .start_tx = multi_start_tx, + .stop_rx = multi_stop_rx, + .enable_ms = multi_enable_ms, + .break_ctl = multi_break_ctl, + .startup = multi_startup, + .shutdown = multi_shutdown, + .set_termios = multi_set_termios, + .pm = multi_pm, + .type = multi_type, + .release_port = multi_release_port, + .request_port = multi_request_port, + .config_port = multi_config_port, + .verify_port = multi_verify_port, +}; + +static struct uart_driver multi_reg = { + .owner = THIS_MODULE, + .driver_name = "goldel_tulip", + .dev_name = "ttyMP", + .major = SB_TTY_MP_MAJOR, + .minor = 0, + .nr = MAX_MP_PORT, + .cons = NULL, +}; + +static void __init multi_init_ports(void) +{ + struct mp_port *mtpt; + static int first = 1; + int i,j,k; + unsigned char osc; + unsigned char b_ret = 0; + static struct mp_device_t * sbdev; + + if (!first) + return; + first = 0; + + mtpt = multi_ports; + + for (k=0;knr_ports; i++, mtpt++) + { + mtpt->device = sbdev; + mtpt->port.iobase = sbdev->uart_access_addr + 8*i; + mtpt->port.irq = sbdev->irq; + if ( ((sbdev->device_id == PCI_DEVICE_ID_MP4)&&(sbdev->revision==0x91))) + mtpt->interface_config_addr = sbdev->option_reg_addr + 0x08 + i; + else if (sbdev->revision == 0xc0) + mtpt->interface_config_addr = sbdev->option_reg_addr + 0x08 + (i & 0x1); + else + mtpt->interface_config_addr = sbdev->option_reg_addr + 0x08 + i/8; + + mtpt->option_base_addr = sbdev->option_reg_addr; + + mtpt->poll_type = sbdev->poll_type; + + mtpt->port.uartclk = BASE_BAUD * 16; + + /* get input clock infomation */ + osc = inb(sbdev->option_reg_addr + MP_OPTR_DIR0 + i/8) & 0x0F; + if (osc==0x0f) + osc = 0; + for(j=0;jport.uartclk *= 2; + mtpt->port.flags |= STD_COM_FLAGS | UPF_SHARE_IRQ ; + mtpt->port.iotype = UPIO_PORT; + mtpt->port.ops = &multi_pops; + + if (sbdev->revision == 0xc0) + { + /* for SB16C1053APCI */ + b_ret = sb1053a_get_interface(mtpt, i); + } + else + { + b_ret = read_option_register(mtpt,(MP_OPTR_IIR0 + i/8)); + printk("IIR_RET = %x\n",b_ret); + } + + if(IIR_RS232 == (b_ret & IIR_RS232)) + { + mtpt->interface = RS232; + } + if(IIR_RS422 == (b_ret & IIR_RS422)) + { + mtpt->interface = RS422PTP; + } + if(IIR_RS485 == (b_ret & IIR_RS485)) + { + mtpt->interface = RS485NE; + } + } + } +} + +static void __init multi_register_ports(struct uart_driver *drv) +{ + int i; + + multi_init_ports(); + + for (i = 0; i < NR_PORTS; i++) { + struct mp_port *mtpt = &multi_ports[i]; + + mtpt->port.line = i; + mtpt->port.ops = &multi_pops; + init_timer(&mtpt->timer); + mtpt->timer.function = multi_timeout; + mp_add_one_port(drv, &mtpt->port); + } +} + +/** + * pci_remap_base - remap BAR value of pci device + * + * PARAMETERS + * pcidev - pci_dev structure address + * offset - BAR offset PCI_BASE_ADDRESS_0 ~ PCI_BASE_ADDRESS_4 + * address - address to be changed BAR value + * size - size of address space + * + * RETURNS + * If this function performs successful, it returns 0. Otherwise, It returns -1. + */ +static int pci_remap_base(struct pci_dev *pcidev, unsigned int offset, + unsigned int address, unsigned int size) +{ +#if 0 + struct resource *root; + unsigned index = (offset - 0x10) >> 2; +#endif + + pci_write_config_dword(pcidev, offset, address); +#if 0 + root = pcidev->resource[index].parent; + release_resource(&pcidev->resource[index]); + address &= ~0x1; + pcidev->resource[index].start = address; + pcidev->resource[index].end = address + size - 1; + + if (request_resource(root, &pcidev->resource[index]) != NULL) + { + printk(KERN_ERR "pci remap conflict!! 0x%x\n", address); + return (-1); + } +#endif + + return (0); +} + +static int init_mp_dev(struct pci_dev *pcidev, mppcibrd_t brd) +{ + static struct mp_device_t * sbdev = mp_devs; + unsigned long addr = 0; + int j; + struct resource * ret = NULL; + + sbdev->device_id = brd.device_id; + pci_read_config_byte(pcidev, PCI_CLASS_REVISION, &(sbdev->revision)); + sbdev->name = brd.name; + sbdev->uart_access_addr = pcidev->resource[0].start & PCI_BASE_ADDRESS_IO_MASK; + + /* check revision. The SB16C1053APCI's option i/o address is BAR4 */ + if (sbdev->revision == 0xc0) + { + /* SB16C1053APCI */ + sbdev->option_reg_addr = pcidev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK; + } + else + { + sbdev->option_reg_addr = pcidev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK; + } +#if 1 + if (sbdev->revision == 0xc0) + { + outb(0x00, sbdev->option_reg_addr + MP_OPTR_GPOCR); + inb(sbdev->option_reg_addr + MP_OPTR_GPOCR); + outb(0x83, sbdev->option_reg_addr + MP_OPTR_GPOCR); + } +#endif + + sbdev->irq = pcidev->irq; + + if ((brd.device_id & 0x0800) || !(brd.device_id &0xff00)) + { + sbdev->poll_type = TYPE_INTERRUPT; + } + else + { + sbdev->poll_type = TYPE_POLL; + } + + /* codes which is specific to each board*/ + switch(brd.device_id){ + case PCI_DEVICE_ID_MP1 : + case PCIE_DEVICE_ID_MP1 : + case PCIE_DEVICE_ID_MP1E : + case PCIE_DEVICE_ID_GT_MP1 : + sbdev->nr_ports = 1; + break; + case PCI_DEVICE_ID_MP2 : + case PCIE_DEVICE_ID_MP2 : + case PCIE_DEVICE_ID_GT_MP2 : + case PCIE_DEVICE_ID_MP2B : + case PCIE_DEVICE_ID_MP2E : + sbdev->nr_ports = 2; + + /* serial base address remap */ + if (sbdev->revision == 0xc0) + { + int prev_port_addr = 0; + + pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &prev_port_addr); + pci_remap_base(pcidev, PCI_BASE_ADDRESS_1, prev_port_addr + 8, 8); + } + break; + case PCI_DEVICE_ID_MP4 : + case PCI_DEVICE_ID_MP4A : + case PCIE_DEVICE_ID_MP4 : + case PCI_DEVICE_ID_GT_MP4 : + case PCI_DEVICE_ID_GT_MP4A : + case PCIE_DEVICE_ID_GT_MP4 : + case PCI_DEVICE_ID_MP4M : + case PCIE_DEVICE_ID_MP4B : + sbdev->nr_ports = 4; + + if(sbdev->revision == 0x91){ + sbdev->reserved_addr[0] = pcidev->resource[0].start & PCI_BASE_ADDRESS_IO_MASK; + outb(0x03 , sbdev->reserved_addr[0] + 0x01); + outb(0x03 , sbdev->reserved_addr[0] + 0x02); + outb(0x01 , sbdev->reserved_addr[0] + 0x20); + outb(0x00 , sbdev->reserved_addr[0] + 0x21); + request_region(sbdev->reserved_addr[0], 32, sbdev->name); + sbdev->uart_access_addr = pcidev->resource[1].start & PCI_BASE_ADDRESS_IO_MASK; + sbdev->option_reg_addr = pcidev->resource[2].start & PCI_BASE_ADDRESS_IO_MASK; + } + + /* SB16C1053APCI */ + if (sbdev->revision == 0xc0) + { + int prev_port_addr = 0; + + pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &prev_port_addr); + pci_remap_base(pcidev, PCI_BASE_ADDRESS_1, prev_port_addr + 8, 8); + pci_remap_base(pcidev, PCI_BASE_ADDRESS_2, prev_port_addr + 16, 8); + pci_remap_base(pcidev, PCI_BASE_ADDRESS_3, prev_port_addr + 24, 8); + } + break; + case PCI_DEVICE_ID_MP6 : + case PCI_DEVICE_ID_MP6A : + case PCI_DEVICE_ID_GT_MP6 : + case PCI_DEVICE_ID_GT_MP6A : + sbdev->nr_ports = 6; + + /* SB16C1053APCI */ + if (sbdev->revision == 0xc0) + { + int prev_port_addr = 0; + + pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &prev_port_addr); + pci_remap_base(pcidev, PCI_BASE_ADDRESS_1, prev_port_addr + 8, 8); + pci_remap_base(pcidev, PCI_BASE_ADDRESS_2, prev_port_addr + 16, 16); + pci_remap_base(pcidev, PCI_BASE_ADDRESS_3, prev_port_addr + 32, 16); + } + break; + case PCI_DEVICE_ID_MP8 : + case PCIE_DEVICE_ID_MP8 : + case PCI_DEVICE_ID_GT_MP8 : + case PCIE_DEVICE_ID_GT_MP8 : + case PCIE_DEVICE_ID_MP8B : + sbdev->nr_ports = 8; + break; + case PCI_DEVICE_ID_MP32 : + case PCIE_DEVICE_ID_MP32 : + case PCI_DEVICE_ID_GT_MP32 : + case PCIE_DEVICE_ID_GT_MP32 : + { + int portnum_hex=0; + portnum_hex = inb(sbdev->option_reg_addr); + sbdev->nr_ports = ((portnum_hex/16)*10) + (portnum_hex % 16); + } + break; + case PCI_DEVICE_ID_MP2S1P : + sbdev->nr_ports = 2; + + /* SB16C1053APCI */ + if (sbdev->revision == 0xc0) + { + int prev_port_addr = 0; + + pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &prev_port_addr); + pci_remap_base(pcidev, PCI_BASE_ADDRESS_1, prev_port_addr + 8, 8); + } + + /* add PC compatible parallel port */ + parport_pc_probe_port(pcidev->resource[2].start, pcidev->resource[3].start, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &pcidev->dev, 0); + break; + case PCI_DEVICE_ID_MP1P : + /* add PC compatible parallel port */ + parport_pc_probe_port(pcidev->resource[2].start, pcidev->resource[3].start, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &pcidev->dev, 0); + break; + } + + ret = request_region(sbdev->uart_access_addr, (8*sbdev->nr_ports), sbdev->name); + + if (sbdev->revision == 0xc0) + { + ret = request_region(sbdev->option_reg_addr, 0x40, sbdev->name); + } + else + { + ret = request_region(sbdev->option_reg_addr, 0x20, sbdev->name); + } + + + NR_BOARD++; + NR_PORTS += sbdev->nr_ports; + + /* Enable PCI interrupt */ + addr = sbdev->option_reg_addr + MP_OPTR_IMR0; + for(j=0; j < (sbdev->nr_ports/8)+1; j++) + { + if (sbdev->poll_type == TYPE_INTERRUPT) + { + outb(0xff,addr +j); + } + } + sbdev++; + + return 0; +} + +static int __init multi_init(void) +{ + int ret, i; + struct pci_dev *dev = NULL; + + if(fcr_count==0) + { + for(i=0;i<256;i++) + { + fcr_arr[i] = 0x01; + + } + } + if(deep_count==0) + { + for(i=0;i<256;i++) + { + deep[i] = 1; + + } + } + if(rtr_count==0) + { + for(i=0;i<256;i++) + { + rtr[i] = 0x10; + } + } + if(ttr_count==0) + { + for(i=0;i<256;i++) + { + ttr[i] = 0x38; + } + } + + +printk("MULTI INIT\n"); + for( i=0; i< mp_nrpcibrds; i++) + { + + while( (dev = pci_get_device(mp_pciboards[i].vendor_id, mp_pciboards[i].device_id, dev) ) ) + + { +printk("FOUND~~~\n"); +// Cent OS bug fix +// if (mp_pciboards[i].device_id & 0x0800) + { + int status; + pci_disable_device(dev); + status = pci_enable_device(dev); + + if (status != 0) + { + printk("Multiport Board Enable Fail !\n\n"); + status = -ENXIO; + return status; + } + } + + init_mp_dev(dev, mp_pciboards[i]); + } + } + + for (i = 0; i < NR_IRQS; i++) + spin_lock_init(&irq_lists[i].lock); + + ret = mp_register_driver(&multi_reg); + + if (ret >= 0) + multi_register_ports(&multi_reg); + + return ret; +} + +static void __exit multi_exit(void) +{ + int i; + + for (i = 0; i < NR_PORTS; i++) + mp_remove_one_port(&multi_reg, &multi_ports[i].port); + + mp_unregister_driver(&multi_reg); +} + +module_init(multi_init); +module_exit(multi_exit); + +MODULE_DESCRIPTION("SystemBase Multiport PCI/PCIe CORE"); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/sb105x/sb_pci_mp.h b/drivers/staging/sb105x/sb_pci_mp.h new file mode 100644 index 00000000000..f33efde07b9 --- /dev/null +++ b/drivers/staging/sb105x/sb_pci_mp.h @@ -0,0 +1,293 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + + +#define MP_TERMIOS ktermios + +#include "sb_mp_register.h" +#include "sb_ser_core.h" + +#define DRIVER_VERSION "1.1" +#define DRIVER_DATE "2012/01/05" +#define DRIVER_AUTHOR "SYSTEMBASE" +#define DRIVER_DESC "SystemBase PCI/PCIe Multiport Core" + +#define SB_TTY_MP_MAJOR 54 +#define PCI_VENDOR_ID_MULTIPORT 0x14A1 + +#define PCI_DEVICE_ID_MP1 0x4d01 +#define PCI_DEVICE_ID_MP2 0x4d02 +#define PCI_DEVICE_ID_MP4 0x4d04 +#define PCI_DEVICE_ID_MP4A 0x4d54 +#define PCI_DEVICE_ID_MP6 0x4d06 +#define PCI_DEVICE_ID_MP6A 0x4d56 +#define PCI_DEVICE_ID_MP8 0x4d08 +#define PCI_DEVICE_ID_MP32 0x4d32 +/* Parallel port */ +#define PCI_DEVICE_ID_MP1P 0x4301 +#define PCI_DEVICE_ID_MP2S1P 0x4303 + +#define PCIE_DEVICE_ID_MP1 0x4501 +#define PCIE_DEVICE_ID_MP2 0x4502 +#define PCIE_DEVICE_ID_MP4 0x4504 +#define PCIE_DEVICE_ID_MP8 0x4508 +#define PCIE_DEVICE_ID_MP32 0x4532 + +#define PCIE_DEVICE_ID_MP1E 0x4e01 +#define PCIE_DEVICE_ID_MP2E 0x4e02 +#define PCIE_DEVICE_ID_MP2B 0x4b02 +#define PCIE_DEVICE_ID_MP4B 0x4b04 +#define PCIE_DEVICE_ID_MP8B 0x4b08 + +#define PCI_DEVICE_ID_GT_MP4 0x0004 +#define PCI_DEVICE_ID_GT_MP4A 0x0054 +#define PCI_DEVICE_ID_GT_MP6 0x0006 +#define PCI_DEVICE_ID_GT_MP6A 0x0056 +#define PCI_DEVICE_ID_GT_MP8 0x0008 +#define PCI_DEVICE_ID_GT_MP32 0x0032 + +#define PCIE_DEVICE_ID_GT_MP1 0x1501 +#define PCIE_DEVICE_ID_GT_MP2 0x1502 +#define PCIE_DEVICE_ID_GT_MP4 0x1504 +#define PCIE_DEVICE_ID_GT_MP8 0x1508 +#define PCIE_DEVICE_ID_GT_MP32 0x1532 + +#define PCI_DEVICE_ID_MP4M 0x4604 //modem + +#define MAX_MP_DEV 8 +#define BD_MAX_PORT 32 /* Max serial port in one board */ +#define MAX_MP_PORT 256 /* Max serial port in one PC */ + +#define PORT_16C105XA 3 +#define PORT_16C105X 2 +#define PORT_16C55X 1 + +#define ENABLE 1 +#define DISABLE 0 + +/* ioctls */ +#define TIOCGNUMOFPORT 0x545F +#define TIOCSMULTIECHO 0x5440 +#define TIOCSPTPNOECHO 0x5441 + +#define TIOCGOPTIONREG 0x5461 +#define TIOCGDISABLEIRQ 0x5462 +#define TIOCGENABLEIRQ 0x5463 +#define TIOCGSOFTRESET 0x5464 +#define TIOCGSOFTRESETR 0x5465 +#define TIOCGREGINFO 0x5466 +#define TIOCGGETLSR 0x5467 +#define TIOCGGETDEVID 0x5468 +#define TIOCGGETBDNO 0x5469 +#define TIOCGGETINTERFACE 0x546A +#define TIOCGGETREV 0x546B +#define TIOCGGETNRPORTS 0x546C +#define TIOCGGETPORTTYPE 0x546D +#define GETDEEPFIFO 0x54AA +#define SETDEEPFIFO 0x54AB +#define SETFCR 0x54BA +#define SETTTR 0x54B1 +#define SETRTR 0x54B2 +#define GETTTR 0x54B3 +#define GETRTR 0x54B4 + +/* multi-drop mode related ioctl commands */ +#define TIOCSMULTIDROP 0x5470 +#define TIOCSMDADDR 0x5471 +#define TIOCGMDADDR 0x5472 +#define TIOCSENDADDR 0x5473 + + +/* serial interface */ +#define RS232 1 +#define RS422PTP 2 +#define RS422MD 3 +#define RS485NE 4 +#define RS485ECHO 5 + +#define serial_inp(up, offset) serial_in(up, offset) +#define serial_outp(up, offset, value) serial_out(up, offset, value) + +#define PASS_LIMIT 256 +#define is_real_interrupt(irq) ((irq) != 0) + +#define PROBE_ANY (~0) + +static DEFINE_MUTEX(mp_mutex); +#define MP_MUTEX_LOCK(x) mutex_lock(&(x)) +#define MP_MUTEX_UNLOCK(x) mutex_unlock(&(x)) +#define MP_STATE_LOCK(x) mutex_lock(&((x)->mutex)) +#define MP_STATE_UNLOCK(x) mutex_unlock(&((x)->mutex)) + + +#define UART_LSR_SPECIAL 0x1E + +#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) +#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0)) + + +//#define MP_DEBUG 1 +#undef MP_DEBUG + +#ifdef MP_DEBUG +#define DPRINTK(x...) printk(x) +#else +#define DPRINTK(x...) do { } while (0) +#endif + +#ifdef MP_DEBUG +#define DEBUG_AUTOCONF(fmt...) printk(fmt) +#else +#define DEBUG_AUTOCONF(fmt...) do { } while (0) +#endif + +#ifdef MP_DEBUG +#define DEBUG_INTR(fmt...) printk(fmt) +#else +#define DEBUG_INTR(fmt...) do { } while (0) +#endif + +#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486)) +#define SERIAL_INLINE +#endif +#ifdef SERIAL_INLINE +#define _INLINE_ inline +#else +#define _INLINE_ +#endif + +#define TYPE_POLL 1 +#define TYPE_INTERRUPT 2 + + +struct mp_device_t { + unsigned short device_id; + unsigned char revision; + char *name; + unsigned long uart_access_addr; + unsigned long option_reg_addr; + unsigned long reserved_addr[4]; + int irq; + int nr_ports; + int poll_type; +}; + +typedef struct mppcibrd { + char *name; + unsigned short vendor_id; + unsigned short device_id; +} mppcibrd_t; + +static mppcibrd_t mp_pciboards[] = { + + { "Multi-1 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP1} , + { "Multi-2 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP2} , + { "Multi-4 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP4} , + { "Multi-4 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP4A} , + { "Multi-6 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP6} , + { "Multi-6 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP6A} , + { "Multi-8 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP8} , + { "Multi-32 PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP32} , + + { "Multi-1P PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP1P} , + { "Multi-2S1P PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP2S1P} , + + { "Multi-4(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP4} , + { "Multi-4(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP4A} , + { "Multi-6(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP6} , + { "Multi-6(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP6A} , + { "Multi-8(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP8} , + { "Multi-32(GT) PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_GT_MP32} , + + { "Multi-1 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP1} , + { "Multi-2 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP2} , + { "Multi-4 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP4} , + { "Multi-8 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP8} , + { "Multi-32 PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP32} , + + { "Multi-1 PCIe E", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP1E} , + { "Multi-2 PCIe E", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP2E} , + { "Multi-2 PCIe B", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP2B} , + { "Multi-4 PCIe B", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP4B} , + { "Multi-8 PCIe B", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_MP8B} , + + { "Multi-1(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP1} , + { "Multi-2(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP2} , + { "Multi-4(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP4} , + { "Multi-8(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP8} , + { "Multi-32(GT) PCIe", PCI_VENDOR_ID_MULTIPORT , PCIE_DEVICE_ID_GT_MP32} , + + { "Multi-4M PCI", PCI_VENDOR_ID_MULTIPORT , PCI_DEVICE_ID_MP4M} , +}; + +struct mp_port { + struct sb_uart_port port; + + struct timer_list timer; /* "no irq" timer */ + struct list_head list; /* ports on this IRQ */ + unsigned int capabilities; /* port capabilities */ + unsigned short rev; + unsigned char acr; + unsigned char ier; + unsigned char lcr; + unsigned char mcr; + unsigned char mcr_mask; /* mask of user bits */ + unsigned char mcr_force; /* mask of forced bits */ + unsigned char lsr_break_flag; + + void (*pm)(struct sb_uart_port *port, + unsigned int state, unsigned int old); + struct mp_device_t *device; + unsigned long interface_config_addr; + unsigned long option_base_addr; + unsigned char interface; + unsigned char poll_type; +}; + +struct irq_info { + spinlock_t lock; + struct list_head *head; +}; + +struct sb105x_uart_config { + char *name; + int dfl_xmit_fifo_size; + int flags; +}; + +static const struct sb105x_uart_config uart_config[] = { + { "unknown", 1, 0 }, + { "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, + { "SB16C1050", 128, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH }, + { "SB16C1050A", 128, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH }, +}; + + + diff --git a/drivers/staging/sb105x/sb_ser_core.h b/drivers/staging/sb105x/sb_ser_core.h new file mode 100644 index 00000000000..c8fb9917329 --- /dev/null +++ b/drivers/staging/sb105x/sb_ser_core.h @@ -0,0 +1,368 @@ +#include + +#define UART_CONFIG_TYPE (1 << 0) +#define UART_CONFIG_IRQ (1 << 1) +#define UPIO_PORT (0) +#define UPIO_HUB6 (1) +#define UPIO_MEM (2) +#define UPIO_MEM32 (3) +#define UPIO_AU (4) /* Au1x00 type IO */ +#define UPIO_TSI (5) /* Tsi108/109 type IO */ +#define UPF_FOURPORT (1 << 1) +#define UPF_SAK (1 << 2) +#define UPF_SPD_MASK (0x1030) +#define UPF_SPD_HI (0x0010) +#define UPF_SPD_VHI (0x0020) +#define UPF_SPD_CUST (0x0030) +#define UPF_SPD_SHI (0x1000) +#define UPF_SPD_WARP (0x1010) +#define UPF_SKIP_TEST (1 << 6) +#define UPF_AUTO_IRQ (1 << 7) +#define UPF_HARDPPS_CD (1 << 11) +#define UPF_LOW_LATENCY (1 << 13) +#define UPF_BUGGY_UART (1 << 14) +#define UPF_MAGIC_MULTIPLIER (1 << 16) +#define UPF_CONS_FLOW (1 << 23) +#define UPF_SHARE_IRQ (1 << 24) +#define UPF_BOOT_AUTOCONF (1 << 28) +#define UPF_DEAD (1 << 30) +#define UPF_IOREMAP (1 << 31) +#define UPF_CHANGE_MASK (0x17fff) +#define UPF_USR_MASK (UPF_SPD_MASK|UPF_LOW_LATENCY) +#define USF_CLOSING_WAIT_INF (0) +#define USF_CLOSING_WAIT_NONE (~0U) + +#define UART_XMIT_SIZE PAGE_SIZE + +#define UIF_CHECK_CD (1 << 25) +#define UIF_CTS_FLOW (1 << 26) +#define UIF_NORMAL_ACTIVE (1 << 29) +#define UIF_INITIALIZED (1 << 31) +#define UIF_SUSPENDED (1 << 30) + +#define WAKEUP_CHARS 256 + +#define uart_circ_empty(circ) ((circ)->head == (circ)->tail) +#define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0) + +#define uart_circ_chars_pending(circ) \ + (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE)) + +#define uart_circ_chars_free(circ) \ + (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE)) + +#define uart_tx_stopped(port) \ + ((port)->info->tty->stopped || (port)->info->tty->hw_stopped) + +#define UART_ENABLE_MS(port,cflag) ((port)->flags & UPF_HARDPPS_CD || \ + (cflag) & CRTSCTS || \ + !((cflag) & CLOCAL)) + + +struct sb_uart_port; +struct sb_uart_info; +struct serial_struct; +struct device; + +struct sb_uart_ops { + unsigned int (*tx_empty)(struct sb_uart_port *); + void (*set_mctrl)(struct sb_uart_port *, unsigned int mctrl); + unsigned int (*get_mctrl)(struct sb_uart_port *); + void (*stop_tx)(struct sb_uart_port *); + void (*start_tx)(struct sb_uart_port *); + void (*send_xchar)(struct sb_uart_port *, char ch); + void (*stop_rx)(struct sb_uart_port *); + void (*enable_ms)(struct sb_uart_port *); + void (*break_ctl)(struct sb_uart_port *, int ctl); + int (*startup)(struct sb_uart_port *); + void (*shutdown)(struct sb_uart_port *); + void (*set_termios)(struct sb_uart_port *, struct MP_TERMIOS *new, + struct MP_TERMIOS *old); + void (*pm)(struct sb_uart_port *, unsigned int state, + unsigned int oldstate); + int (*set_wake)(struct sb_uart_port *, unsigned int state); + + const char *(*type)(struct sb_uart_port *); + + void (*release_port)(struct sb_uart_port *); + + int (*request_port)(struct sb_uart_port *); + void (*config_port)(struct sb_uart_port *, int); + int (*verify_port)(struct sb_uart_port *, struct serial_struct *); + int (*ioctl)(struct sb_uart_port *, unsigned int, unsigned long); +}; + + +struct sb_uart_icount { + __u32 cts; + __u32 dsr; + __u32 rng; + __u32 dcd; + __u32 rx; + __u32 tx; + __u32 frame; + __u32 overrun; + __u32 parity; + __u32 brk; + __u32 buf_overrun; +}; +typedef unsigned int upf_t; + +struct sb_uart_port { + spinlock_t lock; /* port lock */ + unsigned int iobase; /* in/out[bwl] */ + unsigned char __iomem *membase; /* read/write[bwl] */ + unsigned int irq; /* irq number */ + unsigned int uartclk; /* base uart clock */ + unsigned int fifosize; /* tx fifo size */ + unsigned char x_char; /* xon/xoff char */ + unsigned char regshift; /* reg offset shift */ + unsigned char iotype; /* io access style */ + unsigned char unused1; + + + unsigned int read_status_mask; /* driver specific */ + unsigned int ignore_status_mask; /* driver specific */ + struct sb_uart_info *info; /* pointer to parent info */ + struct sb_uart_icount icount; /* statistics */ + + struct console *cons; /* struct console, if any */ +#ifdef CONFIG_SERIAL_CORE_CONSOLE + unsigned long sysrq; /* sysrq timeout */ +#endif + + upf_t flags; + + unsigned int mctrl; /* current modem ctrl settings */ + unsigned int timeout; /* character-based timeout */ + unsigned int type; /* port type */ + const struct sb_uart_ops *ops; + unsigned int custom_divisor; + unsigned int line; /* port index */ + unsigned long mapbase; /* for ioremap */ + struct device *dev; /* parent device */ + unsigned char hub6; /* this should be in the 8250 driver */ + unsigned char unused[3]; +}; + +#define mdmode unused[2] +#define MDMODE_ADDR 0x1 +#define MDMODE_ENABLE 0x2 +#define MDMODE_AUTO 0x4 +#define MDMODE_ADDRSEND 0x8 + +struct sb_uart_state { + unsigned int close_delay; /* msec */ + unsigned int closing_wait; /* msec */ + + + int count; + int pm_state; + struct sb_uart_info *info; + struct sb_uart_port *port; + + struct mutex mutex; +}; + +typedef unsigned int uif_t; + +struct sb_uart_info { + struct tty_struct *tty; + struct circ_buf xmit; + uif_t flags; + + int blocked_open; + + struct tasklet_struct tlet; + + wait_queue_head_t open_wait; + wait_queue_head_t delta_msr_wait; +}; + + +struct module; +struct tty_driver; + +struct uart_driver { + struct module *owner; + const char *driver_name; + const char *dev_name; + int major; + int minor; + int nr; + struct console *cons; + + struct sb_uart_state *state; + struct tty_driver *tty_driver; +}; + +void sb_uart_write_wakeup(struct sb_uart_port *port) +{ + struct sb_uart_info *info = port->info; + tasklet_schedule(&info->tlet); +} + +void sb_uart_update_timeout(struct sb_uart_port *port, unsigned int cflag, + unsigned int baud) +{ + unsigned int bits; + + switch (cflag & CSIZE) + { + case CS5: + bits = 7; + break; + + case CS6: + bits = 8; + break; + + case CS7: + bits = 9; + break; + + default: + bits = 10; + break; + } + + if (cflag & CSTOPB) + { + bits++; + } + + if (cflag & PARENB) + { + bits++; + } + + bits = bits * port->fifosize; + + port->timeout = (HZ * bits) / baud + HZ/50; +} +unsigned int sb_uart_get_baud_rate(struct sb_uart_port *port, struct MP_TERMIOS *termios, + struct MP_TERMIOS *old, unsigned int min, + unsigned int max) +{ + unsigned int try, baud, altbaud = 38400; + upf_t flags = port->flags & UPF_SPD_MASK; + + if (flags == UPF_SPD_HI) + altbaud = 57600; + if (flags == UPF_SPD_VHI) + altbaud = 115200; + if (flags == UPF_SPD_SHI) + altbaud = 230400; + if (flags == UPF_SPD_WARP) + altbaud = 460800; + + for (try = 0; try < 2; try++) { + + switch (termios->c_cflag & (CBAUD | CBAUDEX)) + { + case B921600 : baud = 921600; break; + case B460800 : baud = 460800; break; + case B230400 : baud = 230400; break; + case B115200 : baud = 115200; break; + case B57600 : baud = 57600; break; + case B38400 : baud = 38400; break; + case B19200 : baud = 19200; break; + case B9600 : baud = 9600; break; + case B4800 : baud = 4800; break; + case B2400 : baud = 2400; break; + case B1800 : baud = 1800; break; + case B1200 : baud = 1200; break; + case B600 : baud = 600; break; + case B300 : baud = 300; break; + case B200 : baud = 200; break; + case B150 : baud = 150; break; + case B134 : baud = 134; break; + case B110 : baud = 110; break; + case B75 : baud = 75; break; + case B50 : baud = 50; break; + default : baud = 9600; break; + } + + if (baud == 38400) + baud = altbaud; + + if (baud == 0) + baud = 9600; + + if (baud >= min && baud <= max) + return baud; + + termios->c_cflag &= ~CBAUD; + if (old) { + termios->c_cflag |= old->c_cflag & CBAUD; + old = NULL; + continue; + } + + termios->c_cflag |= B9600; + } + + return 0; +} +unsigned int sb_uart_get_divisor(struct sb_uart_port *port, unsigned int baud) +{ + unsigned int quot; + + if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) + quot = port->custom_divisor; + else + quot = (port->uartclk + (8 * baud)) / (16 * baud); + + return quot; +} + + + +static inline int sb_uart_handle_break(struct sb_uart_port *port) +{ + struct sb_uart_info *info = port->info; + + if (port->flags & UPF_SAK) + do_SAK(info->tty); + return 0; +} + +static inline void sb_uart_handle_dcd_change(struct sb_uart_port *port, unsigned int status) +{ + struct sb_uart_info *info = port->info; + + port->icount.dcd++; + + if (info->flags & UIF_CHECK_CD) { + if (status) + wake_up_interruptible(&info->open_wait); + else if (info->tty) + tty_hangup(info->tty); + } +} + +static inline void sb_uart_handle_cts_change(struct sb_uart_port *port, unsigned int status) +{ + struct sb_uart_info *info = port->info; + struct tty_struct *tty = info->tty; + + port->icount.cts++; + + if (info->flags & UIF_CTS_FLOW) { + if (tty->hw_stopped) { + if (status) { + tty->hw_stopped = 0; + port->ops->start_tx(port); + sb_uart_write_wakeup(port); + } + } else { + if (!status) { + tty->hw_stopped = 1; + port->ops->stop_tx(port); + } + } + } +} + + + -- cgit v1.2.3 From 8e620b0476696e9428442d3551f3dad47df0e28f Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 15 Nov 2012 17:21:16 +0000 Subject: arm64: Distinguish between user and kernel XN bits On AArch64, the meaning of the XN bit has changed to UXN (user). The PXN (privileged) bit must be set to prevent kernel execution. Without the PXN bit set, the CPU may speculatively access device memory. This patch ensures that all the mappings that the kernel must not execute from (including user mappings) have the PXN bit set. Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/io.h | 2 +- arch/arm64/include/asm/pgtable-hwdef.h | 6 +++-- arch/arm64/include/asm/pgtable.h | 40 +++++++++++++++++----------------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index 54f6116697f..d2f05a60827 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -222,7 +222,7 @@ extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot extern void __iounmap(volatile void __iomem *addr); #define PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_DIRTY) -#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) +#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_PXN | PTE_UXN | PTE_ATTRINDX(MT_DEVICE_nGnRE)) #define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC)) #define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h index 0f3b4581d92..75fd13d289b 100644 --- a/arch/arm64/include/asm/pgtable-hwdef.h +++ b/arch/arm64/include/asm/pgtable-hwdef.h @@ -38,7 +38,8 @@ #define PMD_SECT_S (_AT(pmdval_t, 3) << 8) #define PMD_SECT_AF (_AT(pmdval_t, 1) << 10) #define PMD_SECT_NG (_AT(pmdval_t, 1) << 11) -#define PMD_SECT_XN (_AT(pmdval_t, 1) << 54) +#define PMD_SECT_PXN (_AT(pmdval_t, 1) << 53) +#define PMD_SECT_UXN (_AT(pmdval_t, 1) << 54) /* * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). @@ -57,7 +58,8 @@ #define PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */ #define PTE_AF (_AT(pteval_t, 1) << 10) /* Access Flag */ #define PTE_NG (_AT(pteval_t, 1) << 11) /* nG */ -#define PTE_XN (_AT(pteval_t, 1) << 54) /* XN */ +#define PTE_PXN (_AT(pteval_t, 1) << 53) /* Privileged XN */ +#define PTE_UXN (_AT(pteval_t, 1) << 54) /* User XN */ /* * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 8960239be72..14aba2db677 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -62,23 +62,23 @@ extern pgprot_t pgprot_default; #define _MOD_PROT(p, b) __pgprot(pgprot_val(p) | (b)) -#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_XN | PTE_RDONLY) -#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN) -#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG) -#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) -#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) -#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) -#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_RDONLY) -#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_XN | PTE_DIRTY) -#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_DIRTY) - -#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_XN | PTE_RDONLY) -#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN) -#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG) -#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) -#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) -#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_XN | PTE_RDONLY) -#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_RDONLY) +#define PAGE_NONE _MOD_PROT(pgprot_default, PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define PAGE_SHARED _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) +#define PAGE_SHARED_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN) +#define PAGE_COPY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define PAGE_COPY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) +#define PAGE_READONLY _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define PAGE_READONLY_EXEC _MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) +#define PAGE_KERNEL _MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY) +#define PAGE_KERNEL_EXEC _MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY) + +#define __PAGE_NONE __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define __PAGE_SHARED __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN) +#define __PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN) +#define __PAGE_COPY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define __PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) +#define __PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY) +#define __PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY) #endif /* __ASSEMBLY__ */ @@ -130,10 +130,10 @@ extern struct page *empty_zero_page; #define pte_young(pte) (pte_val(pte) & PTE_AF) #define pte_special(pte) (pte_val(pte) & PTE_SPECIAL) #define pte_write(pte) (!(pte_val(pte) & PTE_RDONLY)) -#define pte_exec(pte) (!(pte_val(pte) & PTE_XN)) +#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN)) #define pte_present_exec_user(pte) \ - ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_XN)) == \ + ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == \ (PTE_VALID | PTE_USER)) #define PTE_BIT_FUNC(fn,op) \ @@ -262,7 +262,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { - const pteval_t mask = PTE_USER | PTE_XN | PTE_RDONLY; + const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY; pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); return pte; } -- cgit v1.2.3 From 76859725ad31ac480d55bf176e5bbe0f9ab6e6cb Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 16 Nov 2012 16:19:58 +0100 Subject: Staging: ipack: adapt copyright to CERN guidelines Adapt the copyright clause to CERN guidelines, as it has the copyright over them. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ipack/carriers/tpci200.c | 7 ++++--- drivers/staging/ipack/carriers/tpci200.h | 7 ++++--- drivers/staging/ipack/devices/ipoctal.c | 7 ++++--- drivers/staging/ipack/devices/ipoctal.h | 7 ++++--- drivers/staging/ipack/devices/scc2698.h | 7 ++++--- drivers/staging/ipack/ipack.c | 4 ++-- drivers/staging/ipack/ipack.h | 4 ++-- 7 files changed, 24 insertions(+), 19 deletions(-) diff --git a/drivers/staging/ipack/carriers/tpci200.c b/drivers/staging/ipack/carriers/tpci200.c index 31cafffb8e7..c1a19b274c2 100644 --- a/drivers/staging/ipack/carriers/tpci200.c +++ b/drivers/staging/ipack/carriers/tpci200.c @@ -2,9 +2,10 @@ * tpci200.c * * driver for the TEWS TPCI-200 device - * Copyright (c) 2009 Nicolas Serafini, EIC2 SA - * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN - * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * Copyright (C) 2009-2012 CERN (www.cern.ch) + * Author: Nicolas Serafini, EIC2 SA + * Author: Samuel Iglesias Gonsalvez * * 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 diff --git a/drivers/staging/ipack/carriers/tpci200.h b/drivers/staging/ipack/carriers/tpci200.h index 982f31920af..8d9be277b34 100644 --- a/drivers/staging/ipack/carriers/tpci200.h +++ b/drivers/staging/ipack/carriers/tpci200.h @@ -2,9 +2,10 @@ * tpci200.h * * driver for the carrier TEWS TPCI-200 - * Copyright (c) 2009 Nicolas Serafini, EIC2 SA - * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN - * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * Copyright (C) 2009-2012 CERN (www.cern.ch) + * Author: Nicolas Serafini, EIC2 SA + * Author: Samuel Iglesias Gonsalvez * * 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 diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index b6a72e6c106..783f120338d 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c @@ -2,9 +2,10 @@ * ipoctal.c * * driver for the GE IP-OCTAL boards - * Copyright (c) 2009 Nicolas Serafini, EIC2 SA - * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN - * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * Copyright (C) 2009-2012 CERN (www.cern.ch) + * Author: Nicolas Serafini, EIC2 SA + * Author: Samuel Iglesias Gonsalvez * * 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 diff --git a/drivers/staging/ipack/devices/ipoctal.h b/drivers/staging/ipack/devices/ipoctal.h index c5b4ed46516..28f1c423315 100644 --- a/drivers/staging/ipack/devices/ipoctal.h +++ b/drivers/staging/ipack/devices/ipoctal.h @@ -2,9 +2,10 @@ * ipoctal.h * * driver for the IPOCTAL boards - * Copyright (c) 2009 Nicolas Serafini, EIC2 SA - * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN - * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia + + * Copyright (C) 2009-2012 CERN (www.cern.ch) + * Author: Nicolas Serafini, EIC2 SA + * Author: Samuel Iglesias Gonsalvez * * 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 diff --git a/drivers/staging/ipack/devices/scc2698.h b/drivers/staging/ipack/devices/scc2698.h index 96e8d8c30e1..2ad6acd513f 100644 --- a/drivers/staging/ipack/devices/scc2698.h +++ b/drivers/staging/ipack/devices/scc2698.h @@ -2,9 +2,10 @@ * scc2698.h * * driver for the IPOCTAL boards - * Copyright (c) 2009 Nicolas Serafini, EIC2 SA - * Copyright (c) 2010,2011 Samuel Iglesias Gonsalvez , CERN - * Copyright (c) 2012 Samuel Iglesias Gonsalvez , Igalia + * + * Copyright (C) 2009-2012 CERN (www.cern.ch) + * Author: Nicolas Serafini, EIC2 SA + * Author: Samuel Iglesias Gonsalvez * * 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 diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c index 429696bc544..6d5079de52b 100644 --- a/drivers/staging/ipack/ipack.c +++ b/drivers/staging/ipack/ipack.c @@ -1,8 +1,8 @@ /* * Industry-pack bus support functions. * - * (C) 2011 Samuel Iglesias Gonsalvez , CERN - * (C) 2012 Samuel Iglesias Gonsalvez , Igalia + * Copyright (C) 2011-2012 CERN (www.cern.ch) + * Author: Samuel Iglesias Gonsalvez * * 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 diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h index 7ca8789459e..6760bfaf0ac 100644 --- a/drivers/staging/ipack/ipack.h +++ b/drivers/staging/ipack/ipack.h @@ -1,8 +1,8 @@ /* * Industry-pack bus. * - * (C) 2011 Samuel Iglesias Gonsalvez , CERN - * (C) 2012 Samuel Iglesias Gonsalvez , Igalia + * Copyright (C) 2011-2012 CERN (www.cern.ch) + * Author: Samuel Iglesias Gonsalvez * * 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 -- cgit v1.2.3 From 05e5027efc9c0bb6d1d04cde279afbafca0a7929 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 16 Nov 2012 08:14:18 -0800 Subject: Staging: ipack: move out of staging The ipack subsystem is cleaned up enough to now move out of the staging tree, and into drivers/ipack. Cc: Samuel Iglesias Gonsalvez Cc: Jens Taprogge Signed-off-by: Greg Kroah-Hartman --- drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/ipack/Kconfig | 24 + drivers/ipack/Makefile | 6 + drivers/ipack/carriers/Kconfig | 7 + drivers/ipack/carriers/Makefile | 1 + drivers/ipack/carriers/tpci200.c | 627 ++++++++++++++++++++++++++ drivers/ipack/carriers/tpci200.h | 168 +++++++ drivers/ipack/devices/Kconfig | 6 + drivers/ipack/devices/Makefile | 1 + drivers/ipack/devices/ipoctal.c | 751 +++++++++++++++++++++++++++++++ drivers/ipack/devices/ipoctal.h | 42 ++ drivers/ipack/devices/scc2698.h | 228 ++++++++++ drivers/ipack/ipack.c | 481 ++++++++++++++++++++ drivers/ipack/ipack.h | 215 +++++++++ drivers/ipack/ipack_ids.h | 32 ++ drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/ipack/Kconfig | 24 - drivers/staging/ipack/Makefile | 6 - drivers/staging/ipack/TODO | 16 - drivers/staging/ipack/carriers/Kconfig | 7 - drivers/staging/ipack/carriers/Makefile | 1 - drivers/staging/ipack/carriers/tpci200.c | 627 -------------------------- drivers/staging/ipack/carriers/tpci200.h | 168 ------- drivers/staging/ipack/devices/Kconfig | 6 - drivers/staging/ipack/devices/Makefile | 1 - drivers/staging/ipack/devices/ipoctal.c | 751 ------------------------------- drivers/staging/ipack/devices/ipoctal.h | 42 -- drivers/staging/ipack/devices/scc2698.h | 228 ---------- drivers/staging/ipack/ipack.c | 481 -------------------- drivers/staging/ipack/ipack.h | 215 --------- drivers/staging/ipack/ipack_ids.h | 32 -- 33 files changed, 2592 insertions(+), 2608 deletions(-) create mode 100644 drivers/ipack/Kconfig create mode 100644 drivers/ipack/Makefile create mode 100644 drivers/ipack/carriers/Kconfig create mode 100644 drivers/ipack/carriers/Makefile create mode 100644 drivers/ipack/carriers/tpci200.c create mode 100644 drivers/ipack/carriers/tpci200.h create mode 100644 drivers/ipack/devices/Kconfig create mode 100644 drivers/ipack/devices/Makefile create mode 100644 drivers/ipack/devices/ipoctal.c create mode 100644 drivers/ipack/devices/ipoctal.h create mode 100644 drivers/ipack/devices/scc2698.h create mode 100644 drivers/ipack/ipack.c create mode 100644 drivers/ipack/ipack.h create mode 100644 drivers/ipack/ipack_ids.h delete mode 100644 drivers/staging/ipack/Kconfig delete mode 100644 drivers/staging/ipack/Makefile delete mode 100644 drivers/staging/ipack/TODO delete mode 100644 drivers/staging/ipack/carriers/Kconfig delete mode 100644 drivers/staging/ipack/carriers/Makefile delete mode 100644 drivers/staging/ipack/carriers/tpci200.c delete mode 100644 drivers/staging/ipack/carriers/tpci200.h delete mode 100644 drivers/staging/ipack/devices/Kconfig delete mode 100644 drivers/staging/ipack/devices/Makefile delete mode 100644 drivers/staging/ipack/devices/ipoctal.c delete mode 100644 drivers/staging/ipack/devices/ipoctal.h delete mode 100644 drivers/staging/ipack/devices/scc2698.h delete mode 100644 drivers/staging/ipack/ipack.c delete mode 100644 drivers/staging/ipack/ipack.h delete mode 100644 drivers/staging/ipack/ipack_ids.h diff --git a/drivers/Kconfig b/drivers/Kconfig index dbdefa3fe77..f5fb0722a63 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -156,4 +156,6 @@ source "drivers/pwm/Kconfig" source "drivers/irqchip/Kconfig" +source "drivers/ipack/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index a16a8d001ae..7863b9fee50 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -145,3 +145,4 @@ obj-$(CONFIG_EXTCON) += extcon/ obj-$(CONFIG_MEMORY) += memory/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_VME_BUS) += vme/ +obj-$(CONFIG_IPACK_BUS) += ipack/ diff --git a/drivers/ipack/Kconfig b/drivers/ipack/Kconfig new file mode 100644 index 00000000000..3949e558956 --- /dev/null +++ b/drivers/ipack/Kconfig @@ -0,0 +1,24 @@ +# +# IPACK configuration. +# + +menuconfig IPACK_BUS + tristate "IndustryPack bus support" + depends on HAS_IOMEM + ---help--- + This option provides support for the IndustryPack framework. There + are IndustryPack carrier boards, which interface another bus (such as + PCI) to an IndustryPack bus, and IndustryPack modules, that are + hosted on these buses. While IndustryPack modules can provide a + large variety of functionality, they are most often found in + industrial control applications. + + Say N if unsure. + +if IPACK_BUS + +source "drivers/ipack/carriers/Kconfig" + +source "drivers/ipack/devices/Kconfig" + +endif # IPACK diff --git a/drivers/ipack/Makefile b/drivers/ipack/Makefile new file mode 100644 index 00000000000..6f14ade0f8f --- /dev/null +++ b/drivers/ipack/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the IPACK bridge device drivers. +# +obj-$(CONFIG_IPACK_BUS) += ipack.o +obj-y += devices/ +obj-y += carriers/ diff --git a/drivers/ipack/carriers/Kconfig b/drivers/ipack/carriers/Kconfig new file mode 100644 index 00000000000..922ff5c35ac --- /dev/null +++ b/drivers/ipack/carriers/Kconfig @@ -0,0 +1,7 @@ +config BOARD_TPCI200 + tristate "Support for the TEWS TPCI-200 IndustryPack carrier board" + depends on IPACK_BUS + depends on PCI + help + This driver adds support for the TEWS TPCI200 IndustryPack carrier board. + default n diff --git a/drivers/ipack/carriers/Makefile b/drivers/ipack/carriers/Makefile new file mode 100644 index 00000000000..d8b76459300 --- /dev/null +++ b/drivers/ipack/carriers/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_BOARD_TPCI200) += tpci200.o diff --git a/drivers/ipack/carriers/tpci200.c b/drivers/ipack/carriers/tpci200.c new file mode 100644 index 00000000000..c1a19b274c2 --- /dev/null +++ b/drivers/ipack/carriers/tpci200.c @@ -0,0 +1,627 @@ +/** + * tpci200.c + * + * driver for the TEWS TPCI-200 device + * + * Copyright (C) 2009-2012 CERN (www.cern.ch) + * Author: Nicolas Serafini, EIC2 SA + * Author: Samuel Iglesias Gonsalvez + * + * 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; version 2 of the License. + */ + +#include +#include +#include "tpci200.h" + +static const u16 tpci200_status_timeout[] = { + TPCI200_A_TIMEOUT, + TPCI200_B_TIMEOUT, + TPCI200_C_TIMEOUT, + TPCI200_D_TIMEOUT, +}; + +static const u16 tpci200_status_error[] = { + TPCI200_A_ERROR, + TPCI200_B_ERROR, + TPCI200_C_ERROR, + TPCI200_D_ERROR, +}; + +static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = { + [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE, + [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE, + [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE, + [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE, + [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE, +}; + +static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = { + [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL, + [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL, + [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL, + [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL, + [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL, +}; + +static struct tpci200_board *check_slot(struct ipack_device *dev) +{ + struct tpci200_board *tpci200; + + if (dev == NULL) + return NULL; + + + tpci200 = dev_get_drvdata(dev->bus->parent); + + if (tpci200 == NULL) { + dev_info(&dev->dev, "carrier board not found\n"); + return NULL; + } + + if (dev->slot >= TPCI200_NB_SLOT) { + dev_info(&dev->dev, + "Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n", + dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1); + return NULL; + } + + return tpci200; +} + +static void tpci200_clear_mask(struct tpci200_board *tpci200, + __le16 __iomem *addr, u16 mask) +{ + unsigned long flags; + spin_lock_irqsave(&tpci200->regs_lock, flags); + iowrite16(ioread16(addr) & (~mask), addr); + spin_unlock_irqrestore(&tpci200->regs_lock, flags); +} + +static void tpci200_set_mask(struct tpci200_board *tpci200, + __le16 __iomem *addr, u16 mask) +{ + unsigned long flags; + spin_lock_irqsave(&tpci200->regs_lock, flags); + iowrite16(ioread16(addr) | mask, addr); + spin_unlock_irqrestore(&tpci200->regs_lock, flags); +} + +static void tpci200_unregister(struct tpci200_board *tpci200) +{ + free_irq(tpci200->info->pdev->irq, (void *) tpci200); + + pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); + pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs); + + pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); + pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR); + + pci_disable_device(tpci200->info->pdev); + pci_dev_put(tpci200->info->pdev); +} + +static void tpci200_enable_irq(struct tpci200_board *tpci200, + int islot) +{ + tpci200_set_mask(tpci200, + &tpci200->info->interface_regs->control[islot], + TPCI200_INT0_EN | TPCI200_INT1_EN); +} + +static void tpci200_disable_irq(struct tpci200_board *tpci200, + int islot) +{ + tpci200_clear_mask(tpci200, + &tpci200->info->interface_regs->control[islot], + TPCI200_INT0_EN | TPCI200_INT1_EN); +} + +static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq) +{ + irqreturn_t ret; + + if (!slot_irq) + return -ENODEV; + ret = slot_irq->handler(slot_irq->arg); + + return ret; +} + +static irqreturn_t tpci200_interrupt(int irq, void *dev_id) +{ + struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; + struct slot_irq *slot_irq; + irqreturn_t ret; + u16 status_reg; + int i; + + /* Read status register */ + status_reg = ioread16(&tpci200->info->interface_regs->status); + + /* Did we cause the interrupt? */ + if (!(status_reg & TPCI200_SLOT_INT_MASK)) + return IRQ_NONE; + + /* callback to the IRQ handler for the corresponding slot */ + rcu_read_lock(); + for (i = 0; i < TPCI200_NB_SLOT; i++) { + if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2 * i)))) + continue; + slot_irq = rcu_dereference(tpci200->slots[i].irq); + ret = tpci200_slot_irq(slot_irq); + if (ret == -ENODEV) { + dev_info(&tpci200->info->pdev->dev, + "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", + tpci200->number, i); + tpci200_disable_irq(tpci200, i); + } + } + rcu_read_unlock(); + + return IRQ_HANDLED; +} + +static int tpci200_free_irq(struct ipack_device *dev) +{ + struct slot_irq *slot_irq; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + if (mutex_lock_interruptible(&tpci200->mutex)) + return -ERESTARTSYS; + + if (tpci200->slots[dev->slot].irq == NULL) { + mutex_unlock(&tpci200->mutex); + return -EINVAL; + } + + tpci200_disable_irq(tpci200, dev->slot); + slot_irq = tpci200->slots[dev->slot].irq; + /* uninstall handler */ + RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL); + synchronize_rcu(); + kfree(slot_irq); + mutex_unlock(&tpci200->mutex); + return 0; +} + +static int tpci200_request_irq(struct ipack_device *dev, + irqreturn_t (*handler)(void *), void *arg) +{ + int res = 0; + struct slot_irq *slot_irq; + struct tpci200_board *tpci200; + + tpci200 = check_slot(dev); + if (tpci200 == NULL) + return -EINVAL; + + if (mutex_lock_interruptible(&tpci200->mutex)) + return -ERESTARTSYS; + + if (tpci200->slots[dev->slot].irq != NULL) { + dev_err(&dev->dev, + "Slot [%d:%d] IRQ already registered !\n", + dev->bus->bus_nr, + dev->slot); + res = -EINVAL; + goto out_unlock; + } + + slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL); + if (slot_irq == NULL) { + dev_err(&dev->dev, + "Slot [%d:%d] unable to allocate memory for IRQ !\n", + dev->bus->bus_nr, dev->slot); + res = -ENOMEM; + goto out_unlock; + } + + /* + * WARNING: Setup Interrupt Vector in the IndustryPack device + * before an IRQ request. + * Read the User Manual of your IndustryPack device to know + * where to write the vector in memory. + */ + slot_irq->handler = handler; + slot_irq->arg = arg; + slot_irq->holder = dev; + + rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq); + tpci200_enable_irq(tpci200, dev->slot); + +out_unlock: + mutex_unlock(&tpci200->mutex); + return res; +} + +static int tpci200_register(struct tpci200_board *tpci200) +{ + int i; + int res; + phys_addr_t ioidint_base; + unsigned short slot_ctrl; + + if (pci_enable_device(tpci200->info->pdev) < 0) + return -ENODEV; + + /* Request IP interface register (Bar 2) */ + res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR, + "Carrier IP interface registers"); + if (res) { + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_disable_pci; + } + + /* Request IO ID INT space (Bar 3) */ + res = pci_request_region(tpci200->info->pdev, + TPCI200_IO_ID_INT_SPACES_BAR, + "Carrier IO ID INT space"); + if (res) { + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_ip_space; + } + + /* Request MEM8 space (Bar 5) */ + res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR, + "Carrier MEM8 space"); + if (res) { + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_ioid_int_space; + } + + /* Request MEM16 space (Bar 4) */ + res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR, + "Carrier MEM16 space"); + if (res) { + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_mem8_space; + } + + /* Map internal tpci200 driver user space */ + tpci200->info->interface_regs = + ioremap_nocache(pci_resource_start(tpci200->info->pdev, + TPCI200_IP_INTERFACE_BAR), + TPCI200_IFACE_SIZE); + + /* Initialize lock that protects interface_regs */ + spin_lock_init(&tpci200->regs_lock); + + ioidint_base = pci_resource_start(tpci200->info->pdev, + TPCI200_IO_ID_INT_SPACES_BAR); + tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF; + tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF; + tpci200->mod_mem[IPACK_INT_SPACE] = + ioidint_base + TPCI200_INT_SPACE_OFF; + tpci200->mod_mem[IPACK_MEM8_SPACE] = + pci_resource_start(tpci200->info->pdev, + TPCI200_MEM8_SPACE_BAR); + tpci200->mod_mem[IPACK_MEM16_SPACE] = + pci_resource_start(tpci200->info->pdev, + TPCI200_MEM16_SPACE_BAR); + + /* Set the default parameters of the slot + * INT0 disabled, level sensitive + * INT1 disabled, level sensitive + * error interrupt disabled + * timeout interrupt disabled + * recover time disabled + * clock rate 8 MHz + */ + slot_ctrl = 0; + for (i = 0; i < TPCI200_NB_SLOT; i++) + writew(slot_ctrl, &tpci200->info->interface_regs->control[i]); + + res = request_irq(tpci200->info->pdev->irq, + tpci200_interrupt, IRQF_SHARED, + KBUILD_MODNAME, (void *) tpci200); + if (res) { + dev_err(&tpci200->info->pdev->dev, + "(bn 0x%X, sn 0x%X) unable to register IRQ !", + tpci200->info->pdev->bus->number, + tpci200->info->pdev->devfn); + goto out_release_ioid_int_space; + } + + return 0; + +out_release_mem8_space: + pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); +out_release_ioid_int_space: + pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); +out_release_ip_space: + pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); +out_disable_pci: + pci_disable_device(tpci200->info->pdev); + return res; +} + +static int tpci200_get_clockrate(struct ipack_device *dev) +{ + struct tpci200_board *tpci200 = check_slot(dev); + __le16 __iomem *addr; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->control[dev->slot]; + return (ioread16(addr) & TPCI200_CLK32) ? 32 : 8; +} + +static int tpci200_set_clockrate(struct ipack_device *dev, int mherz) +{ + struct tpci200_board *tpci200 = check_slot(dev); + __le16 __iomem *addr; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->control[dev->slot]; + + switch (mherz) { + case 8: + tpci200_clear_mask(tpci200, addr, TPCI200_CLK32); + break; + case 32: + tpci200_set_mask(tpci200, addr, TPCI200_CLK32); + break; + default: + return -EINVAL; + } + return 0; +} + +static int tpci200_get_error(struct ipack_device *dev) +{ + struct tpci200_board *tpci200 = check_slot(dev); + __le16 __iomem *addr; + u16 mask; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->status; + mask = tpci200_status_error[dev->slot]; + return (ioread16(addr) & mask) ? 1 : 0; +} + +static int tpci200_get_timeout(struct ipack_device *dev) +{ + struct tpci200_board *tpci200 = check_slot(dev); + __le16 __iomem *addr; + u16 mask; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->status; + mask = tpci200_status_timeout[dev->slot]; + + return (ioread16(addr) & mask) ? 1 : 0; +} + +static int tpci200_reset_timeout(struct ipack_device *dev) +{ + struct tpci200_board *tpci200 = check_slot(dev); + __le16 __iomem *addr; + u16 mask; + + if (!tpci200) + return -ENODEV; + + addr = &tpci200->info->interface_regs->status; + mask = tpci200_status_timeout[dev->slot]; + + iowrite16(mask, addr); + return 0; +} + +static void tpci200_uninstall(struct tpci200_board *tpci200) +{ + tpci200_unregister(tpci200); + kfree(tpci200->slots); +} + +static const struct ipack_bus_ops tpci200_bus_ops = { + .request_irq = tpci200_request_irq, + .free_irq = tpci200_free_irq, + .get_clockrate = tpci200_get_clockrate, + .set_clockrate = tpci200_set_clockrate, + .get_error = tpci200_get_error, + .get_timeout = tpci200_get_timeout, + .reset_timeout = tpci200_reset_timeout, +}; + +static int tpci200_install(struct tpci200_board *tpci200) +{ + int res; + + tpci200->slots = kzalloc( + TPCI200_NB_SLOT * sizeof(struct tpci200_slot), GFP_KERNEL); + if (tpci200->slots == NULL) + return -ENOMEM; + + res = tpci200_register(tpci200); + if (res) { + kfree(tpci200->slots); + tpci200->slots = NULL; + return res; + } + + mutex_init(&tpci200->mutex); + return 0; +} + +static void tpci200_release_device(struct ipack_device *dev) +{ + kfree(dev); +} + +static int tpci200_create_device(struct tpci200_board *tpci200, int i) +{ + enum ipack_space space; + struct ipack_device *dev = + kzalloc(sizeof(struct ipack_device), GFP_KERNEL); + if (!dev) + return -ENOMEM; + dev->slot = i; + dev->bus = tpci200->info->ipack_bus; + dev->release = tpci200_release_device; + + for (space = 0; space < IPACK_SPACE_COUNT; space++) { + dev->region[space].start = + tpci200->mod_mem[space] + + tpci200_space_interval[space] * i; + dev->region[space].size = tpci200_space_size[space]; + } + return ipack_device_register(dev); +} + +static int tpci200_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + int ret, i; + struct tpci200_board *tpci200; + u32 reg32; + + tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL); + if (!tpci200) + return -ENOMEM; + + tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL); + if (!tpci200->info) { + ret = -ENOMEM; + goto out_err_info; + } + + pci_dev_get(pdev); + + /* Obtain a mapping of the carrier's PCI configuration registers */ + ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR, + KBUILD_MODNAME " Configuration Memory"); + if (ret) { + dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory"); + ret = -EBUSY; + goto out_err_pci_request; + } + tpci200->info->cfg_regs = ioremap_nocache( + pci_resource_start(pdev, TPCI200_CFG_MEM_BAR), + pci_resource_len(pdev, TPCI200_CFG_MEM_BAR)); + if (!tpci200->info->cfg_regs) { + dev_err(&pdev->dev, "Failed to map PCI Configuration Memory"); + ret = -EFAULT; + goto out_err_ioremap; + } + + /* Disable byte swapping for 16 bit IP module access. This will ensure + * that the Industrypack big endian byte order is preserved by the + * carrier. */ + reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC); + reg32 |= 1 << LAS_BIT_BIGENDIAN; + iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC); + + reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC); + reg32 |= 1 << LAS_BIT_BIGENDIAN; + iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC); + + /* Save struct pci_dev pointer */ + tpci200->info->pdev = pdev; + tpci200->info->id_table = (struct pci_device_id *)id; + + /* register the device and initialize it */ + ret = tpci200_install(tpci200); + if (ret) { + dev_err(&pdev->dev, "error during tpci200 install\n"); + ret = -ENODEV; + goto out_err_install; + } + + /* Register the carrier in the industry pack bus driver */ + tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev, + TPCI200_NB_SLOT, + &tpci200_bus_ops); + if (!tpci200->info->ipack_bus) { + dev_err(&pdev->dev, + "error registering the carrier on ipack driver\n"); + ret = -EFAULT; + goto out_err_bus_register; + } + + /* save the bus number given by ipack to logging purpose */ + tpci200->number = tpci200->info->ipack_bus->bus_nr; + dev_set_drvdata(&pdev->dev, tpci200); + + for (i = 0; i < TPCI200_NB_SLOT; i++) + tpci200_create_device(tpci200, i); + return 0; + +out_err_bus_register: + tpci200_uninstall(tpci200); +out_err_install: + iounmap(tpci200->info->cfg_regs); +out_err_ioremap: + pci_release_region(pdev, TPCI200_CFG_MEM_BAR); +out_err_pci_request: + pci_dev_put(pdev); + kfree(tpci200->info); +out_err_info: + kfree(tpci200); + return ret; +} + +static void __tpci200_pci_remove(struct tpci200_board *tpci200) +{ + ipack_bus_unregister(tpci200->info->ipack_bus); + tpci200_uninstall(tpci200); + + kfree(tpci200->info); + kfree(tpci200); +} + +static void __devexit tpci200_pci_remove(struct pci_dev *dev) +{ + struct tpci200_board *tpci200 = pci_get_drvdata(dev); + + __tpci200_pci_remove(tpci200); +} + +static DEFINE_PCI_DEVICE_TABLE(tpci200_idtable) = { + { TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID, + TPCI200_SUBDEVICE_ID }, + { 0, }, +}; + +MODULE_DEVICE_TABLE(pci, tpci200_idtable); + +static struct pci_driver tpci200_pci_drv = { + .name = "tpci200", + .id_table = tpci200_idtable, + .probe = tpci200_pci_probe, + .remove = __devexit_p(tpci200_pci_remove), +}; + +module_pci_driver(tpci200_pci_drv); + +MODULE_DESCRIPTION("TEWS TPCI-200 device driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/ipack/carriers/tpci200.h b/drivers/ipack/carriers/tpci200.h new file mode 100644 index 00000000000..8d9be277b34 --- /dev/null +++ b/drivers/ipack/carriers/tpci200.h @@ -0,0 +1,168 @@ +/** + * tpci200.h + * + * driver for the carrier TEWS TPCI-200 + * + * Copyright (C) 2009-2012 CERN (www.cern.ch) + * Author: Nicolas Serafini, EIC2 SA + * Author: Samuel Iglesias Gonsalvez + * + * 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; version 2 of the License. + */ + +#ifndef _TPCI200_H_ +#define _TPCI200_H_ + +#include +#include +#include +#include +#include + +#include "../ipack.h" + +#define TPCI200_NB_SLOT 0x4 +#define TPCI200_NB_BAR 0x6 + +#define TPCI200_VENDOR_ID 0x1498 +#define TPCI200_DEVICE_ID 0x30C8 +#define TPCI200_SUBVENDOR_ID 0x1498 +#define TPCI200_SUBDEVICE_ID 0x300A + +#define TPCI200_CFG_MEM_BAR 0 +#define TPCI200_IP_INTERFACE_BAR 2 +#define TPCI200_IO_ID_INT_SPACES_BAR 3 +#define TPCI200_MEM16_SPACE_BAR 4 +#define TPCI200_MEM8_SPACE_BAR 5 + +struct tpci200_regs { + __le16 revision; + /* writes to control should occur with the mutex held to protect + * read-modify-write operations */ + __le16 control[4]; + __le16 reset; + __le16 status; + u8 reserved[242]; +} __packed; + +#define TPCI200_IFACE_SIZE 0x100 + +#define TPCI200_IO_SPACE_OFF 0x0000 +#define TPCI200_IO_SPACE_INTERVAL 0x0100 +#define TPCI200_IO_SPACE_SIZE 0x0080 +#define TPCI200_ID_SPACE_OFF 0x0080 +#define TPCI200_ID_SPACE_INTERVAL 0x0100 +#define TPCI200_ID_SPACE_SIZE 0x0040 +#define TPCI200_INT_SPACE_OFF 0x00C0 +#define TPCI200_INT_SPACE_INTERVAL 0x0100 +#define TPCI200_INT_SPACE_SIZE 0x0040 +#define TPCI200_IOIDINT_SIZE 0x0400 + +#define TPCI200_MEM8_SPACE_INTERVAL 0x00400000 +#define TPCI200_MEM8_SPACE_SIZE 0x00400000 +#define TPCI200_MEM16_SPACE_INTERVAL 0x00800000 +#define TPCI200_MEM16_SPACE_SIZE 0x00800000 + +/* control field in tpci200_regs */ +#define TPCI200_INT0_EN 0x0040 +#define TPCI200_INT1_EN 0x0080 +#define TPCI200_INT0_EDGE 0x0010 +#define TPCI200_INT1_EDGE 0x0020 +#define TPCI200_ERR_INT_EN 0x0008 +#define TPCI200_TIME_INT_EN 0x0004 +#define TPCI200_RECOVER_EN 0x0002 +#define TPCI200_CLK32 0x0001 + +/* reset field in tpci200_regs */ +#define TPCI200_A_RESET 0x0001 +#define TPCI200_B_RESET 0x0002 +#define TPCI200_C_RESET 0x0004 +#define TPCI200_D_RESET 0x0008 + +/* status field in tpci200_regs */ +#define TPCI200_A_TIMEOUT 0x1000 +#define TPCI200_B_TIMEOUT 0x2000 +#define TPCI200_C_TIMEOUT 0x4000 +#define TPCI200_D_TIMEOUT 0x8000 + +#define TPCI200_A_ERROR 0x0100 +#define TPCI200_B_ERROR 0x0200 +#define TPCI200_C_ERROR 0x0400 +#define TPCI200_D_ERROR 0x0800 + +#define TPCI200_A_INT0 0x0001 +#define TPCI200_A_INT1 0x0002 +#define TPCI200_B_INT0 0x0004 +#define TPCI200_B_INT1 0x0008 +#define TPCI200_C_INT0 0x0010 +#define TPCI200_C_INT1 0x0020 +#define TPCI200_D_INT0 0x0040 +#define TPCI200_D_INT1 0x0080 + +#define TPCI200_SLOT_INT_MASK 0x00FF + +/* PCI Configuration registers. The PCI bridge is a PLX Technology PCI9030. */ +#define LAS1_DESC 0x2C +#define LAS2_DESC 0x30 + +/* Bits in the LAS?_DESC registers */ +#define LAS_BIT_BIGENDIAN 24 + +#define VME_IOID_SPACE "IOID" +#define VME_MEM_SPACE "MEM" + +/** + * struct slot_irq - slot IRQ definition. + * @vector Vector number + * @handler Handler called when IRQ arrives + * @arg Handler argument + * + */ +struct slot_irq { + struct ipack_device *holder; + int vector; + irqreturn_t (*handler)(void *); + void *arg; +}; + +/** + * struct tpci200_slot - data specific to the tpci200 slot. + * @slot_id Slot identification gived to external interface + * @irq Slot IRQ infos + * @io_phys IO physical base address register of the slot + * @id_phys ID physical base address register of the slot + * @int_phys INT physical base address register of the slot + * @mem_phys MEM physical base address register of the slot + * + */ +struct tpci200_slot { + struct slot_irq *irq; +}; + +/** + * struct tpci200_infos - informations specific of the TPCI200 tpci200. + * @pci_dev PCI device + * @interface_regs Pointer to IP interface space (Bar 2) + * @ioidint_space Pointer to IP ID, IO and INT space (Bar 3) + * @mem8_space Pointer to MEM space (Bar 4) + * + */ +struct tpci200_infos { + struct pci_dev *pdev; + struct pci_device_id *id_table; + struct tpci200_regs __iomem *interface_regs; + void __iomem *cfg_regs; + struct ipack_bus_device *ipack_bus; +}; +struct tpci200_board { + unsigned int number; + struct mutex mutex; + spinlock_t regs_lock; + struct tpci200_slot *slots; + struct tpci200_infos *info; + phys_addr_t mod_mem[IPACK_SPACE_COUNT]; +}; + +#endif /* _TPCI200_H_ */ diff --git a/drivers/ipack/devices/Kconfig b/drivers/ipack/devices/Kconfig new file mode 100644 index 00000000000..0b82fdc198c --- /dev/null +++ b/drivers/ipack/devices/Kconfig @@ -0,0 +1,6 @@ +config SERIAL_IPOCTAL + tristate "IndustryPack IP-OCTAL uart support" + depends on IPACK_BUS + help + This driver supports the IPOCTAL serial port device for the IndustryPack bus. + default n diff --git a/drivers/ipack/devices/Makefile b/drivers/ipack/devices/Makefile new file mode 100644 index 00000000000..6de18bda4a9 --- /dev/null +++ b/drivers/ipack/devices/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_SERIAL_IPOCTAL) += ipoctal.o diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c new file mode 100644 index 00000000000..783f120338d --- /dev/null +++ b/drivers/ipack/devices/ipoctal.c @@ -0,0 +1,751 @@ +/** + * ipoctal.c + * + * driver for the GE IP-OCTAL boards + * + * Copyright (C) 2009-2012 CERN (www.cern.ch) + * Author: Nicolas Serafini, EIC2 SA + * Author: Samuel Iglesias Gonsalvez + * + * 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; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../ipack.h" +#include "ipoctal.h" +#include "scc2698.h" + +#define IP_OCTAL_ID_SPACE_VECTOR 0x41 +#define IP_OCTAL_NB_BLOCKS 4 + +static const struct tty_operations ipoctal_fops; + +struct ipoctal_channel { + struct ipoctal_stats stats; + unsigned int nb_bytes; + wait_queue_head_t queue; + spinlock_t lock; + unsigned int pointer_read; + unsigned int pointer_write; + atomic_t open; + struct tty_port tty_port; + union scc2698_channel __iomem *regs; + union scc2698_block __iomem *block_regs; + unsigned int board_id; + unsigned char *board_write; + u8 isr_rx_rdy_mask; + u8 isr_tx_rdy_mask; +}; + +struct ipoctal { + struct ipack_device *dev; + unsigned int board_id; + struct ipoctal_channel channel[NR_CHANNELS]; + unsigned char write; + struct tty_driver *tty_drv; + u8 __iomem *mem8_space; + u8 __iomem *int_space; +}; + +static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) +{ + struct ipoctal_channel *channel; + + channel = dev_get_drvdata(tty->dev); + + iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); + return 0; +} + +static int ipoctal_open(struct tty_struct *tty, struct file *file) +{ + int res; + struct ipoctal_channel *channel; + + channel = dev_get_drvdata(tty->dev); + + if (atomic_read(&channel->open)) + return -EBUSY; + + tty->driver_data = channel; + + res = tty_port_open(&channel->tty_port, tty, file); + if (res) + return res; + + atomic_inc(&channel->open); + return 0; +} + +static void ipoctal_reset_stats(struct ipoctal_stats *stats) +{ + stats->tx = 0; + stats->rx = 0; + stats->rcv_break = 0; + stats->framing_err = 0; + stats->overrun_err = 0; + stats->parity_err = 0; +} + +static void ipoctal_free_channel(struct ipoctal_channel *channel) +{ + ipoctal_reset_stats(&channel->stats); + channel->pointer_read = 0; + channel->pointer_write = 0; + channel->nb_bytes = 0; +} + +static void ipoctal_close(struct tty_struct *tty, struct file *filp) +{ + struct ipoctal_channel *channel = tty->driver_data; + + tty_port_close(&channel->tty_port, tty, filp); + + if (atomic_dec_and_test(&channel->open)) + ipoctal_free_channel(channel); +} + +static int ipoctal_get_icount(struct tty_struct *tty, + struct serial_icounter_struct *icount) +{ + struct ipoctal_channel *channel = tty->driver_data; + + icount->cts = 0; + icount->dsr = 0; + icount->rng = 0; + icount->dcd = 0; + icount->rx = channel->stats.rx; + icount->tx = channel->stats.tx; + icount->frame = channel->stats.framing_err; + icount->parity = channel->stats.parity_err; + icount->brk = channel->stats.rcv_break; + return 0; +} + +static void ipoctal_irq_rx(struct ipoctal_channel *channel, + struct tty_struct *tty, u8 sr) +{ + unsigned char value; + unsigned char flag = TTY_NORMAL; + u8 isr; + + do { + value = ioread8(&channel->regs->r.rhr); + /* Error: count statistics */ + if (sr & SR_ERROR) { + iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); + + if (sr & SR_OVERRUN_ERROR) { + channel->stats.overrun_err++; + /* Overrun doesn't affect the current character*/ + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + if (sr & SR_PARITY_ERROR) { + channel->stats.parity_err++; + flag = TTY_PARITY; + } + if (sr & SR_FRAMING_ERROR) { + channel->stats.framing_err++; + flag = TTY_FRAME; + } + if (sr & SR_RECEIVED_BREAK) { + iowrite8(CR_CMD_RESET_BREAK_CHANGE, &channel->regs->w.cr); + channel->stats.rcv_break++; + flag = TTY_BREAK; + } + } + tty_insert_flip_char(tty, value, flag); + + /* Check if there are more characters in RX FIFO + * If there are more, the isr register for this channel + * has enabled the RxRDY|FFULL bit. + */ + isr = ioread8(&channel->block_regs->r.isr); + sr = ioread8(&channel->regs->r.sr); + } while (isr & channel->isr_rx_rdy_mask); + + tty_flip_buffer_push(tty); +} + +static void ipoctal_irq_tx(struct ipoctal_channel *channel) +{ + unsigned char value; + unsigned int *pointer_write = &channel->pointer_write; + + if (channel->nb_bytes <= 0) { + channel->nb_bytes = 0; + return; + } + + value = channel->tty_port.xmit_buf[*pointer_write]; + iowrite8(value, &channel->regs->w.thr); + channel->stats.tx++; + (*pointer_write)++; + *pointer_write = *pointer_write % PAGE_SIZE; + channel->nb_bytes--; + + if ((channel->nb_bytes == 0) && + (waitqueue_active(&channel->queue))) { + + if (channel->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) { + *channel->board_write = 1; + wake_up_interruptible(&channel->queue); + } + } +} + +static void ipoctal_irq_channel(struct ipoctal_channel *channel) +{ + u8 isr, sr; + struct tty_struct *tty; + + /* If there is no client, skip the check */ + if (!atomic_read(&channel->open)) + return; + + tty = tty_port_tty_get(&channel->tty_port); + if (!tty) + return; + /* The HW is organized in pair of channels. See which register we need + * to read from */ + isr = ioread8(&channel->block_regs->r.isr); + sr = ioread8(&channel->regs->r.sr); + + /* In case of RS-485, change from TX to RX when finishing TX. + * Half-duplex. */ + if ((channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) && + (sr & SR_TX_EMPTY) && (channel->nb_bytes == 0)) { + iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_NEGATE_RTSN, &channel->regs->w.cr); + iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); + *channel->board_write = 1; + wake_up_interruptible(&channel->queue); + } + + /* RX data */ + if ((isr & channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) + ipoctal_irq_rx(channel, tty, sr); + + /* TX of each character */ + if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) + ipoctal_irq_tx(channel); + + tty_flip_buffer_push(tty); + tty_kref_put(tty); +} + +static irqreturn_t ipoctal_irq_handler(void *arg) +{ + unsigned int i; + struct ipoctal *ipoctal = (struct ipoctal *) arg; + + /* Check all channels */ + for (i = 0; i < NR_CHANNELS; i++) + ipoctal_irq_channel(&ipoctal->channel[i]); + + /* Clear the IPack device interrupt */ + readw(ipoctal->int_space + ACK_INT_REQ0); + readw(ipoctal->int_space + ACK_INT_REQ1); + + return IRQ_HANDLED; +} + +static const struct tty_port_operations ipoctal_tty_port_ops = { + .dtr_rts = NULL, + .activate = ipoctal_port_activate, +}; + +static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, + unsigned int slot) +{ + int res; + int i; + struct tty_driver *tty; + char name[20]; + struct ipoctal_channel *channel; + struct ipack_region *region; + void __iomem *addr; + union scc2698_channel __iomem *chan_regs; + union scc2698_block __iomem *block_regs; + + ipoctal->board_id = ipoctal->dev->id_device; + + region = &ipoctal->dev->region[IPACK_IO_SPACE]; + addr = devm_ioremap_nocache(&ipoctal->dev->dev, + region->start, region->size); + if (!addr) { + dev_err(&ipoctal->dev->dev, + "Unable to map slot [%d:%d] IO space!\n", + bus_nr, slot); + return -EADDRNOTAVAIL; + } + /* Save the virtual address to access the registers easily */ + chan_regs = + (union scc2698_channel __iomem *) addr; + block_regs = + (union scc2698_block __iomem *) addr; + + region = &ipoctal->dev->region[IPACK_INT_SPACE]; + ipoctal->int_space = + devm_ioremap_nocache(&ipoctal->dev->dev, + region->start, region->size); + if (!ipoctal->int_space) { + dev_err(&ipoctal->dev->dev, + "Unable to map slot [%d:%d] INT space!\n", + bus_nr, slot); + return -EADDRNOTAVAIL; + } + + region = &ipoctal->dev->region[IPACK_MEM8_SPACE]; + ipoctal->mem8_space = + devm_ioremap_nocache(&ipoctal->dev->dev, + region->start, 0x8000); + if (!addr) { + dev_err(&ipoctal->dev->dev, + "Unable to map slot [%d:%d] MEM8 space!\n", + bus_nr, slot); + return -EADDRNOTAVAIL; + } + + + /* Disable RX and TX before touching anything */ + for (i = 0; i < NR_CHANNELS ; i++) { + struct ipoctal_channel *channel = &ipoctal->channel[i]; + channel->regs = chan_regs + i; + channel->block_regs = block_regs + (i >> 1); + channel->board_write = &ipoctal->write; + channel->board_id = ipoctal->board_id; + if (i & 1) { + channel->isr_tx_rdy_mask = ISR_TxRDY_B; + channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_B; + } else { + channel->isr_tx_rdy_mask = ISR_TxRDY_A; + channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_A; + } + + iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); + iowrite8(MR1_CHRL_8_BITS | MR1_ERROR_CHAR | MR1_RxINT_RxRDY, + &channel->regs->w.mr); /* mr1 */ + iowrite8(0, &channel->regs->w.mr); /* mr2 */ + iowrite8(TX_CLK_9600 | RX_CLK_9600, &channel->regs->w.csr); + } + + for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) { + iowrite8(ACR_BRG_SET2, &block_regs[i].w.acr); + iowrite8(OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | OPCR_MPOb_RTSN, + &block_regs[i].w.opcr); + iowrite8(IMR_TxRDY_A | IMR_RxRDY_FFULL_A | IMR_DELTA_BREAK_A | + IMR_TxRDY_B | IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B, + &block_regs[i].w.imr); + } + + /* + * IP-OCTAL has different addresses to copy its IRQ vector. + * Depending of the carrier these addresses are accesible or not. + * More info in the datasheet. + */ + ipoctal->dev->bus->ops->request_irq(ipoctal->dev, + ipoctal_irq_handler, ipoctal); + /* Dummy write */ + iowrite8(1, ipoctal->mem8_space + 1); + + /* Register the TTY device */ + + /* Each IP-OCTAL channel is a TTY port */ + tty = alloc_tty_driver(NR_CHANNELS); + + if (!tty) + return -ENOMEM; + + /* Fill struct tty_driver with ipoctal data */ + tty->owner = THIS_MODULE; + tty->driver_name = KBUILD_MODNAME; + sprintf(name, KBUILD_MODNAME ".%d.%d.", bus_nr, slot); + tty->name = name; + tty->major = 0; + + tty->minor_start = 0; + tty->type = TTY_DRIVER_TYPE_SERIAL; + tty->subtype = SERIAL_TYPE_NORMAL; + tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + tty->init_termios = tty_std_termios; + tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + tty->init_termios.c_ispeed = 9600; + tty->init_termios.c_ospeed = 9600; + + tty_set_operations(tty, &ipoctal_fops); + res = tty_register_driver(tty); + if (res) { + dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n"); + put_tty_driver(tty); + return res; + } + + /* Save struct tty_driver for use it when uninstalling the device */ + ipoctal->tty_drv = tty; + + for (i = 0; i < NR_CHANNELS; i++) { + struct device *tty_dev; + + channel = &ipoctal->channel[i]; + tty_port_init(&channel->tty_port); + tty_port_alloc_xmit_buf(&channel->tty_port); + channel->tty_port.ops = &ipoctal_tty_port_ops; + + ipoctal_reset_stats(&channel->stats); + channel->nb_bytes = 0; + init_waitqueue_head(&channel->queue); + + spin_lock_init(&channel->lock); + channel->pointer_read = 0; + channel->pointer_write = 0; + tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL); + if (IS_ERR(tty_dev)) { + dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); + continue; + } + dev_set_drvdata(tty_dev, channel); + + /* + * Enable again the RX. TX will be enabled when + * there is something to send + */ + iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); + } + + return 0; +} + +static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, + const unsigned char *buf, + int count) +{ + unsigned long flags; + int i; + unsigned int *pointer_read = &channel->pointer_read; + + /* Copy the bytes from the user buffer to the internal one */ + for (i = 0; i < count; i++) { + if (i <= (PAGE_SIZE - channel->nb_bytes)) { + spin_lock_irqsave(&channel->lock, flags); + channel->tty_port.xmit_buf[*pointer_read] = buf[i]; + *pointer_read = (*pointer_read + 1) % PAGE_SIZE; + channel->nb_bytes++; + spin_unlock_irqrestore(&channel->lock, flags); + } else { + break; + } + } + return i; +} + +static int ipoctal_write_tty(struct tty_struct *tty, + const unsigned char *buf, int count) +{ + struct ipoctal_channel *channel = tty->driver_data; + unsigned int char_copied; + + char_copied = ipoctal_copy_write_buffer(channel, buf, count); + + /* As the IP-OCTAL 485 only supports half duplex, do it manually */ + if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) { + iowrite8(CR_DISABLE_RX, &channel->regs->w.cr); + iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr); + } + + /* + * Send a packet and then disable TX to avoid failure after several send + * operations + */ + iowrite8(CR_ENABLE_TX, &channel->regs->w.cr); + wait_event_interruptible(channel->queue, *channel->board_write); + iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); + + *channel->board_write = 0; + return char_copied; +} + +static int ipoctal_write_room(struct tty_struct *tty) +{ + struct ipoctal_channel *channel = tty->driver_data; + + return PAGE_SIZE - channel->nb_bytes; +} + +static int ipoctal_chars_in_buffer(struct tty_struct *tty) +{ + struct ipoctal_channel *channel = tty->driver_data; + + return channel->nb_bytes; +} + +static void ipoctal_set_termios(struct tty_struct *tty, + struct ktermios *old_termios) +{ + unsigned int cflag; + unsigned char mr1 = 0; + unsigned char mr2 = 0; + unsigned char csr = 0; + struct ipoctal_channel *channel = tty->driver_data; + speed_t baud; + + cflag = tty->termios.c_cflag; + + /* Disable and reset everything before change the setup */ + iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr); + + /* Set Bits per chars */ + switch (cflag & CSIZE) { + case CS6: + mr1 |= MR1_CHRL_6_BITS; + break; + case CS7: + mr1 |= MR1_CHRL_7_BITS; + break; + case CS8: + default: + mr1 |= MR1_CHRL_8_BITS; + /* By default, select CS8 */ + tty->termios.c_cflag = (cflag & ~CSIZE) | CS8; + break; + } + + /* Set Parity */ + if (cflag & PARENB) + if (cflag & PARODD) + mr1 |= MR1_PARITY_ON | MR1_PARITY_ODD; + else + mr1 |= MR1_PARITY_ON | MR1_PARITY_EVEN; + else + mr1 |= MR1_PARITY_OFF; + + /* Mark or space parity is not supported */ + tty->termios.c_cflag &= ~CMSPAR; + + /* Set stop bits */ + if (cflag & CSTOPB) + mr2 |= MR2_STOP_BITS_LENGTH_2; + else + mr2 |= MR2_STOP_BITS_LENGTH_1; + + /* Set the flow control */ + switch (channel->board_id) { + case IPACK1_DEVICE_ID_SBS_OCTAL_232: + if (cflag & CRTSCTS) { + mr1 |= MR1_RxRTS_CONTROL_ON; + mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_ON; + } else { + mr1 |= MR1_RxRTS_CONTROL_OFF; + mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF; + } + break; + case IPACK1_DEVICE_ID_SBS_OCTAL_422: + mr1 |= MR1_RxRTS_CONTROL_OFF; + mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF; + break; + case IPACK1_DEVICE_ID_SBS_OCTAL_485: + mr1 |= MR1_RxRTS_CONTROL_OFF; + mr2 |= MR2_TxRTS_CONTROL_ON | MR2_CTS_ENABLE_TX_OFF; + break; + default: + return; + break; + } + + baud = tty_get_baud_rate(tty); + tty_termios_encode_baud_rate(&tty->termios, baud, baud); + + /* Set baud rate */ + switch (baud) { + case 75: + csr |= TX_CLK_75 | RX_CLK_75; + break; + case 110: + csr |= TX_CLK_110 | RX_CLK_110; + break; + case 150: + csr |= TX_CLK_150 | RX_CLK_150; + break; + case 300: + csr |= TX_CLK_300 | RX_CLK_300; + break; + case 600: + csr |= TX_CLK_600 | RX_CLK_600; + break; + case 1200: + csr |= TX_CLK_1200 | RX_CLK_1200; + break; + case 1800: + csr |= TX_CLK_1800 | RX_CLK_1800; + break; + case 2000: + csr |= TX_CLK_2000 | RX_CLK_2000; + break; + case 2400: + csr |= TX_CLK_2400 | RX_CLK_2400; + break; + case 4800: + csr |= TX_CLK_4800 | RX_CLK_4800; + break; + case 9600: + csr |= TX_CLK_9600 | RX_CLK_9600; + break; + case 19200: + csr |= TX_CLK_19200 | RX_CLK_19200; + break; + case 38400: + default: + csr |= TX_CLK_38400 | RX_CLK_38400; + /* In case of default, we establish 38400 bps */ + tty_termios_encode_baud_rate(&tty->termios, 38400, 38400); + break; + } + + mr1 |= MR1_ERROR_CHAR; + mr1 |= MR1_RxINT_RxRDY; + + /* Write the control registers */ + iowrite8(mr1, &channel->regs->w.mr); + iowrite8(mr2, &channel->regs->w.mr); + iowrite8(csr, &channel->regs->w.csr); + + /* Enable again the RX */ + iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); +} + +static void ipoctal_hangup(struct tty_struct *tty) +{ + unsigned long flags; + struct ipoctal_channel *channel = tty->driver_data; + + if (channel == NULL) + return; + + spin_lock_irqsave(&channel->lock, flags); + channel->nb_bytes = 0; + channel->pointer_read = 0; + channel->pointer_write = 0; + spin_unlock_irqrestore(&channel->lock, flags); + + tty_port_hangup(&channel->tty_port); + + iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); + iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr); + + clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags); + wake_up_interruptible(&channel->tty_port.open_wait); +} + +static const struct tty_operations ipoctal_fops = { + .ioctl = NULL, + .open = ipoctal_open, + .close = ipoctal_close, + .write = ipoctal_write_tty, + .set_termios = ipoctal_set_termios, + .write_room = ipoctal_write_room, + .chars_in_buffer = ipoctal_chars_in_buffer, + .get_icount = ipoctal_get_icount, + .hangup = ipoctal_hangup, +}; + +static int ipoctal_probe(struct ipack_device *dev) +{ + int res; + struct ipoctal *ipoctal; + + ipoctal = kzalloc(sizeof(struct ipoctal), GFP_KERNEL); + if (ipoctal == NULL) + return -ENOMEM; + + ipoctal->dev = dev; + res = ipoctal_inst_slot(ipoctal, dev->bus->bus_nr, dev->slot); + if (res) + goto out_uninst; + + dev_set_drvdata(&dev->dev, ipoctal); + return 0; + +out_uninst: + kfree(ipoctal); + return res; +} + +static void __ipoctal_remove(struct ipoctal *ipoctal) +{ + int i; + + ipoctal->dev->bus->ops->free_irq(ipoctal->dev); + + for (i = 0; i < NR_CHANNELS; i++) { + struct ipoctal_channel *channel = &ipoctal->channel[i]; + tty_unregister_device(ipoctal->tty_drv, i); + tty_port_free_xmit_buf(&channel->tty_port); + } + + tty_unregister_driver(ipoctal->tty_drv); + put_tty_driver(ipoctal->tty_drv); + kfree(ipoctal); +} + +static void ipoctal_remove(struct ipack_device *idev) +{ + __ipoctal_remove(dev_get_drvdata(&idev->dev)); +} + +static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = { + { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS, + IPACK1_DEVICE_ID_SBS_OCTAL_232) }, + { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS, + IPACK1_DEVICE_ID_SBS_OCTAL_422) }, + { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS, + IPACK1_DEVICE_ID_SBS_OCTAL_485) }, + { 0, }, +}; + +MODULE_DEVICE_TABLE(ipack, ipoctal_ids); + +static const struct ipack_driver_ops ipoctal_drv_ops = { + .probe = ipoctal_probe, + .remove = ipoctal_remove, +}; + +static struct ipack_driver driver = { + .ops = &ipoctal_drv_ops, + .id_table = ipoctal_ids, +}; + +static int __init ipoctal_init(void) +{ + return ipack_driver_register(&driver, THIS_MODULE, KBUILD_MODNAME); +} + +static void __exit ipoctal_exit(void) +{ + ipack_driver_unregister(&driver); +} + +MODULE_DESCRIPTION("IP-Octal 232, 422 and 485 device driver"); +MODULE_LICENSE("GPL"); + +module_init(ipoctal_init); +module_exit(ipoctal_exit); diff --git a/drivers/ipack/devices/ipoctal.h b/drivers/ipack/devices/ipoctal.h new file mode 100644 index 00000000000..28f1c423315 --- /dev/null +++ b/drivers/ipack/devices/ipoctal.h @@ -0,0 +1,42 @@ +/** + * ipoctal.h + * + * driver for the IPOCTAL boards + + * Copyright (C) 2009-2012 CERN (www.cern.ch) + * Author: Nicolas Serafini, EIC2 SA + * Author: Samuel Iglesias Gonsalvez + * + * 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; version 2 of the License. + */ + +#ifndef _IPOCTAL_H +#define _IPOCTAL_H_ + +#define NR_CHANNELS 8 +#define IPOCTAL_MAX_BOARDS 16 +#define MAX_DEVICES (NR_CHANNELS * IPOCTAL_MAX_BOARDS) +#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) + +/** + * struct ipoctal_stats -- Stats since last reset + * + * @tx: Number of transmitted bytes + * @rx: Number of received bytes + * @overrun: Number of overrun errors + * @parity_err: Number of parity errors + * @framing_err: Number of framing errors + * @rcv_break: Number of break received + */ +struct ipoctal_stats { + unsigned long tx; + unsigned long rx; + unsigned long overrun_err; + unsigned long parity_err; + unsigned long framing_err; + unsigned long rcv_break; +}; + +#endif /* _IPOCTAL_H_ */ diff --git a/drivers/ipack/devices/scc2698.h b/drivers/ipack/devices/scc2698.h new file mode 100644 index 00000000000..2ad6acd513f --- /dev/null +++ b/drivers/ipack/devices/scc2698.h @@ -0,0 +1,228 @@ +/* + * scc2698.h + * + * driver for the IPOCTAL boards + * + * Copyright (C) 2009-2012 CERN (www.cern.ch) + * Author: Nicolas Serafini, EIC2 SA + * Author: Samuel Iglesias Gonsalvez + * + * 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; version 2 of the License. + */ + +#ifndef SCC2698_H_ +#define SCC2698_H_ + +/* + * union scc2698_channel - Channel access to scc2698 IO + * + * dn value are only spacer. + * + */ +union scc2698_channel { + struct { + u8 d0, mr; /* Mode register 1/2*/ + u8 d1, sr; /* Status register */ + u8 d2, r1; /* reserved */ + u8 d3, rhr; /* Receive holding register (R) */ + u8 junk[8]; /* other crap for block control */ + } __packed r; /* Read access */ + struct { + u8 d0, mr; /* Mode register 1/2 */ + u8 d1, csr; /* Clock select register */ + u8 d2, cr; /* Command register */ + u8 d3, thr; /* Transmit holding register */ + u8 junk[8]; /* other crap for block control */ + } __packed w; /* Write access */ +}; + +/* + * union scc2698_block - Block access to scc2698 IO + * + * The scc2698 contain 4 block. + * Each block containt two channel a and b. + * dn value are only spacer. + * + */ +union scc2698_block { + struct { + u8 d0, mra; /* Mode register 1/2 (a) */ + u8 d1, sra; /* Status register (a) */ + u8 d2, r1; /* reserved */ + u8 d3, rhra; /* Receive holding register (a) */ + u8 d4, ipcr; /* Input port change register of block */ + u8 d5, isr; /* Interrupt status register of block */ + u8 d6, ctur; /* Counter timer upper register of block */ + u8 d7, ctlr; /* Counter timer lower register of block */ + u8 d8, mrb; /* Mode register 1/2 (b) */ + u8 d9, srb; /* Status register (b) */ + u8 da, r2; /* reserved */ + u8 db, rhrb; /* Receive holding register (b) */ + u8 dc, r3; /* reserved */ + u8 dd, ip; /* Input port register of block */ + u8 de, ctg; /* Start counter timer of block */ + u8 df, cts; /* Stop counter timer of block */ + } __packed r; /* Read access */ + struct { + u8 d0, mra; /* Mode register 1/2 (a) */ + u8 d1, csra; /* Clock select register (a) */ + u8 d2, cra; /* Command register (a) */ + u8 d3, thra; /* Transmit holding register (a) */ + u8 d4, acr; /* Auxiliary control register of block */ + u8 d5, imr; /* Interrupt mask register of block */ + u8 d6, ctu; /* Counter timer upper register of block */ + u8 d7, ctl; /* Counter timer lower register of block */ + u8 d8, mrb; /* Mode register 1/2 (b) */ + u8 d9, csrb; /* Clock select register (a) */ + u8 da, crb; /* Command register (b) */ + u8 db, thrb; /* Transmit holding register (b) */ + u8 dc, r1; /* reserved */ + u8 dd, opcr; /* Output port configuration register of block */ + u8 de, r2; /* reserved */ + u8 df, r3; /* reserved */ + } __packed w; /* Write access */ +}; + +#define MR1_CHRL_5_BITS (0x0 << 0) +#define MR1_CHRL_6_BITS (0x1 << 0) +#define MR1_CHRL_7_BITS (0x2 << 0) +#define MR1_CHRL_8_BITS (0x3 << 0) +#define MR1_PARITY_EVEN (0x1 << 2) +#define MR1_PARITY_ODD (0x0 << 2) +#define MR1_PARITY_ON (0x0 << 3) +#define MR1_PARITY_FORCE (0x1 << 3) +#define MR1_PARITY_OFF (0x2 << 3) +#define MR1_PARITY_SPECIAL (0x3 << 3) +#define MR1_ERROR_CHAR (0x0 << 5) +#define MR1_ERROR_BLOCK (0x1 << 5) +#define MR1_RxINT_RxRDY (0x0 << 6) +#define MR1_RxINT_FFULL (0x1 << 6) +#define MR1_RxRTS_CONTROL_ON (0x1 << 7) +#define MR1_RxRTS_CONTROL_OFF (0x0 << 7) + +#define MR2_STOP_BITS_LENGTH_1 (0x7 << 0) +#define MR2_STOP_BITS_LENGTH_2 (0xF << 0) +#define MR2_CTS_ENABLE_TX_ON (0x1 << 4) +#define MR2_CTS_ENABLE_TX_OFF (0x0 << 4) +#define MR2_TxRTS_CONTROL_ON (0x1 << 5) +#define MR2_TxRTS_CONTROL_OFF (0x0 << 5) +#define MR2_CH_MODE_NORMAL (0x0 << 6) +#define MR2_CH_MODE_ECHO (0x1 << 6) +#define MR2_CH_MODE_LOCAL (0x2 << 6) +#define MR2_CH_MODE_REMOTE (0x3 << 6) + +#define CR_ENABLE_RX (0x1 << 0) +#define CR_DISABLE_RX (0x1 << 1) +#define CR_ENABLE_TX (0x1 << 2) +#define CR_DISABLE_TX (0x1 << 3) +#define CR_CMD_RESET_MR (0x1 << 4) +#define CR_CMD_RESET_RX (0x2 << 4) +#define CR_CMD_RESET_TX (0x3 << 4) +#define CR_CMD_RESET_ERR_STATUS (0x4 << 4) +#define CR_CMD_RESET_BREAK_CHANGE (0x5 << 4) +#define CR_CMD_START_BREAK (0x6 << 4) +#define CR_CMD_STOP_BREAK (0x7 << 4) +#define CR_CMD_ASSERT_RTSN (0x8 << 4) +#define CR_CMD_NEGATE_RTSN (0x9 << 4) +#define CR_CMD_SET_TIMEOUT_MODE (0xA << 4) +#define CR_CMD_DISABLE_TIMEOUT_MODE (0xC << 4) + +#define SR_RX_READY (0x1 << 0) +#define SR_FIFO_FULL (0x1 << 1) +#define SR_TX_READY (0x1 << 2) +#define SR_TX_EMPTY (0x1 << 3) +#define SR_OVERRUN_ERROR (0x1 << 4) +#define SR_PARITY_ERROR (0x1 << 5) +#define SR_FRAMING_ERROR (0x1 << 6) +#define SR_RECEIVED_BREAK (0x1 << 7) + +#define SR_ERROR (0xF0) + +#define ACR_DELTA_IP0_IRQ_EN (0x1 << 0) +#define ACR_DELTA_IP1_IRQ_EN (0x1 << 1) +#define ACR_DELTA_IP2_IRQ_EN (0x1 << 2) +#define ACR_DELTA_IP3_IRQ_EN (0x1 << 3) +#define ACR_CT_Mask (0x7 << 4) +#define ACR_CExt (0x0 << 4) +#define ACR_CTxCA (0x1 << 4) +#define ACR_CTxCB (0x2 << 4) +#define ACR_CClk16 (0x3 << 4) +#define ACR_TExt (0x4 << 4) +#define ACR_TExt16 (0x5 << 4) +#define ACR_TClk (0x6 << 4) +#define ACR_TClk16 (0x7 << 4) +#define ACR_BRG_SET1 (0x0 << 7) +#define ACR_BRG_SET2 (0x1 << 7) + +#define TX_CLK_75 (0x0 << 0) +#define TX_CLK_110 (0x1 << 0) +#define TX_CLK_38400 (0x2 << 0) +#define TX_CLK_150 (0x3 << 0) +#define TX_CLK_300 (0x4 << 0) +#define TX_CLK_600 (0x5 << 0) +#define TX_CLK_1200 (0x6 << 0) +#define TX_CLK_2000 (0x7 << 0) +#define TX_CLK_2400 (0x8 << 0) +#define TX_CLK_4800 (0x9 << 0) +#define TX_CLK_1800 (0xA << 0) +#define TX_CLK_9600 (0xB << 0) +#define TX_CLK_19200 (0xC << 0) +#define RX_CLK_75 (0x0 << 4) +#define RX_CLK_110 (0x1 << 4) +#define RX_CLK_38400 (0x2 << 4) +#define RX_CLK_150 (0x3 << 4) +#define RX_CLK_300 (0x4 << 4) +#define RX_CLK_600 (0x5 << 4) +#define RX_CLK_1200 (0x6 << 4) +#define RX_CLK_2000 (0x7 << 4) +#define RX_CLK_2400 (0x8 << 4) +#define RX_CLK_4800 (0x9 << 4) +#define RX_CLK_1800 (0xA << 4) +#define RX_CLK_9600 (0xB << 4) +#define RX_CLK_19200 (0xC << 4) + +#define OPCR_MPOa_RTSN (0x0 << 0) +#define OPCR_MPOa_C_TO (0x1 << 0) +#define OPCR_MPOa_TxC1X (0x2 << 0) +#define OPCR_MPOa_TxC16X (0x3 << 0) +#define OPCR_MPOa_RxC1X (0x4 << 0) +#define OPCR_MPOa_RxC16X (0x5 << 0) +#define OPCR_MPOa_TxRDY (0x6 << 0) +#define OPCR_MPOa_RxRDY_FF (0x7 << 0) + +#define OPCR_MPOb_RTSN (0x0 << 4) +#define OPCR_MPOb_C_TO (0x1 << 4) +#define OPCR_MPOb_TxC1X (0x2 << 4) +#define OPCR_MPOb_TxC16X (0x3 << 4) +#define OPCR_MPOb_RxC1X (0x4 << 4) +#define OPCR_MPOb_RxC16X (0x5 << 4) +#define OPCR_MPOb_TxRDY (0x6 << 4) +#define OPCR_MPOb_RxRDY_FF (0x7 << 4) + +#define OPCR_MPP_INPUT (0x0 << 7) +#define OPCR_MPP_OUTPUT (0x1 << 7) + +#define IMR_TxRDY_A (0x1 << 0) +#define IMR_RxRDY_FFULL_A (0x1 << 1) +#define IMR_DELTA_BREAK_A (0x1 << 2) +#define IMR_COUNTER_READY (0x1 << 3) +#define IMR_TxRDY_B (0x1 << 4) +#define IMR_RxRDY_FFULL_B (0x1 << 5) +#define IMR_DELTA_BREAK_B (0x1 << 6) +#define IMR_INPUT_PORT_CHANGE (0x1 << 7) + +#define ISR_TxRDY_A (0x1 << 0) +#define ISR_RxRDY_FFULL_A (0x1 << 1) +#define ISR_DELTA_BREAK_A (0x1 << 2) +#define ISR_COUNTER_READY (0x1 << 3) +#define ISR_TxRDY_B (0x1 << 4) +#define ISR_RxRDY_FFULL_B (0x1 << 5) +#define ISR_DELTA_BREAK_B (0x1 << 6) +#define ISR_INPUT_PORT_CHANGE (0x1 << 7) + +#define ACK_INT_REQ0 0 +#define ACK_INT_REQ1 2 + +#endif /* SCC2698_H_ */ diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c new file mode 100644 index 00000000000..6d5079de52b --- /dev/null +++ b/drivers/ipack/ipack.c @@ -0,0 +1,481 @@ +/* + * Industry-pack bus support functions. + * + * Copyright (C) 2011-2012 CERN (www.cern.ch) + * Author: Samuel Iglesias Gonsalvez + * + * 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; version 2 of the License. + */ + +#include +#include +#include +#include +#include "ipack.h" + +#define to_ipack_dev(device) container_of(device, struct ipack_device, dev) +#define to_ipack_driver(drv) container_of(drv, struct ipack_driver, driver) + +static DEFINE_IDA(ipack_ida); + +static void ipack_device_release(struct device *dev) +{ + struct ipack_device *device = to_ipack_dev(dev); + kfree(device->id); + device->release(device); +} + +static inline const struct ipack_device_id * +ipack_match_one_device(const struct ipack_device_id *id, + const struct ipack_device *device) +{ + if ((id->format == IPACK_ANY_FORMAT || + id->format == device->id_format) && + (id->vendor == IPACK_ANY_ID || id->vendor == device->id_vendor) && + (id->device == IPACK_ANY_ID || id->device == device->id_device)) + return id; + return NULL; +} + +static const struct ipack_device_id * +ipack_match_id(const struct ipack_device_id *ids, struct ipack_device *idev) +{ + if (ids) { + while (ids->vendor || ids->device) { + if (ipack_match_one_device(ids, idev)) + return ids; + ids++; + } + } + return NULL; +} + +static int ipack_bus_match(struct device *dev, struct device_driver *drv) +{ + struct ipack_device *idev = to_ipack_dev(dev); + struct ipack_driver *idrv = to_ipack_driver(drv); + const struct ipack_device_id *found_id; + + found_id = ipack_match_id(idrv->id_table, idev); + return found_id ? 1 : 0; +} + +static int ipack_bus_probe(struct device *device) +{ + struct ipack_device *dev = to_ipack_dev(device); + struct ipack_driver *drv = to_ipack_driver(device->driver); + + if (!drv->ops->probe) + return -EINVAL; + + return drv->ops->probe(dev); +} + +static int ipack_bus_remove(struct device *device) +{ + struct ipack_device *dev = to_ipack_dev(device); + struct ipack_driver *drv = to_ipack_driver(device->driver); + + if (!drv->ops->remove) + return -EINVAL; + + drv->ops->remove(dev); + return 0; +} + +static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct ipack_device *idev; + + if (!dev) + return -ENODEV; + + idev = to_ipack_dev(dev); + + if (add_uevent_var(env, + "MODALIAS=ipack:f%02Xv%08Xd%08X", idev->id_format, + idev->id_vendor, idev->id_device)) + return -ENOMEM; + + return 0; +} + +#define ipack_device_attr(field, format_string) \ +static ssize_t \ +field##_show(struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + struct ipack_device *idev = to_ipack_dev(dev); \ + return sprintf(buf, format_string, idev->field); \ +} + +static ssize_t id_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned int i, c, l, s; + struct ipack_device *idev = to_ipack_dev(dev); + + + switch (idev->id_format) { + case IPACK_ID_VERSION_1: + l = 0x7; s = 1; break; + case IPACK_ID_VERSION_2: + l = 0xf; s = 2; break; + default: + return -EIO; + } + c = 0; + for (i = 0; i < idev->id_avail; i++) { + if (i > 0) { + if ((i & l) == 0) + buf[c++] = '\n'; + else if ((i & s) == 0) + buf[c++] = ' '; + } + sprintf(&buf[c], "%02x", idev->id[i]); + c += 2; + } + buf[c++] = '\n'; + return c; +} + +static ssize_t +id_vendor_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct ipack_device *idev = to_ipack_dev(dev); + switch (idev->id_format) { + case IPACK_ID_VERSION_1: + return sprintf(buf, "0x%02x\n", idev->id_vendor); + case IPACK_ID_VERSION_2: + return sprintf(buf, "0x%06x\n", idev->id_vendor); + default: + return -EIO; + } +} + +static ssize_t +id_device_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct ipack_device *idev = to_ipack_dev(dev); + switch (idev->id_format) { + case IPACK_ID_VERSION_1: + return sprintf(buf, "0x%02x\n", idev->id_device); + case IPACK_ID_VERSION_2: + return sprintf(buf, "0x%04x\n", idev->id_device); + default: + return -EIO; + } +} + +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct ipack_device *idev = to_ipack_dev(dev); + + return sprintf(buf, "ipac:f%02Xv%08Xd%08X", idev->id_format, + idev->id_vendor, idev->id_device); +} + +ipack_device_attr(id_format, "0x%hhu\n"); + +static struct device_attribute ipack_dev_attrs[] = { + __ATTR_RO(id), + __ATTR_RO(id_device), + __ATTR_RO(id_format), + __ATTR_RO(id_vendor), + __ATTR_RO(modalias), +}; + +static struct bus_type ipack_bus_type = { + .name = "ipack", + .probe = ipack_bus_probe, + .match = ipack_bus_match, + .remove = ipack_bus_remove, + .dev_attrs = ipack_dev_attrs, + .uevent = ipack_uevent, +}; + +struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, + const struct ipack_bus_ops *ops) +{ + int bus_nr; + struct ipack_bus_device *bus; + + bus = kzalloc(sizeof(struct ipack_bus_device), GFP_KERNEL); + if (!bus) + return NULL; + + bus_nr = ida_simple_get(&ipack_ida, 0, 0, GFP_KERNEL); + if (bus_nr < 0) { + kfree(bus); + return NULL; + } + + bus->bus_nr = bus_nr; + bus->parent = parent; + bus->slots = slots; + bus->ops = ops; + return bus; +} +EXPORT_SYMBOL_GPL(ipack_bus_register); + +static int ipack_unregister_bus_member(struct device *dev, void *data) +{ + struct ipack_device *idev = to_ipack_dev(dev); + struct ipack_bus_device *bus = data; + + if (idev->bus == bus) + ipack_device_unregister(idev); + + return 1; +} + +int ipack_bus_unregister(struct ipack_bus_device *bus) +{ + bus_for_each_dev(&ipack_bus_type, NULL, bus, + ipack_unregister_bus_member); + ida_simple_remove(&ipack_ida, bus->bus_nr); + kfree(bus); + return 0; +} +EXPORT_SYMBOL_GPL(ipack_bus_unregister); + +int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, + const char *name) +{ + edrv->driver.owner = owner; + edrv->driver.name = name; + edrv->driver.bus = &ipack_bus_type; + return driver_register(&edrv->driver); +} +EXPORT_SYMBOL_GPL(ipack_driver_register); + +void ipack_driver_unregister(struct ipack_driver *edrv) +{ + driver_unregister(&edrv->driver); +} +EXPORT_SYMBOL_GPL(ipack_driver_unregister); + +static u16 ipack_crc_byte(u16 crc, u8 c) +{ + int i; + + crc ^= c << 8; + for (i = 0; i < 8; i++) + crc = (crc << 1) ^ ((crc & 0x8000) ? 0x1021 : 0); + return crc; +} + +/* + * The algorithm in lib/crc-ccitt.c does not seem to apply since it uses the + * opposite bit ordering. + */ +static u8 ipack_calc_crc1(struct ipack_device *dev) +{ + u8 c; + u16 crc; + unsigned int i; + + crc = 0xffff; + for (i = 0; i < dev->id_avail; i++) { + c = (i != 11) ? dev->id[i] : 0; + crc = ipack_crc_byte(crc, c); + } + crc = ~crc; + return crc & 0xff; +} + +static u16 ipack_calc_crc2(struct ipack_device *dev) +{ + u8 c; + u16 crc; + unsigned int i; + + crc = 0xffff; + for (i = 0; i < dev->id_avail; i++) { + c = ((i != 0x18) && (i != 0x19)) ? dev->id[i] : 0; + crc = ipack_crc_byte(crc, c); + } + crc = ~crc; + return crc; +} + +static void ipack_parse_id1(struct ipack_device *dev) +{ + u8 *id = dev->id; + u8 crc; + + dev->id_vendor = id[4]; + dev->id_device = id[5]; + dev->speed_8mhz = 1; + dev->speed_32mhz = (id[7] == 'H'); + crc = ipack_calc_crc1(dev); + dev->id_crc_correct = (crc == id[11]); + if (!dev->id_crc_correct) { + dev_warn(&dev->dev, "ID CRC invalid found 0x%x, expected 0x%x.\n", + id[11], crc); + } +} + +static void ipack_parse_id2(struct ipack_device *dev) +{ + __be16 *id = (__be16 *) dev->id; + u16 flags, crc; + + dev->id_vendor = ((be16_to_cpu(id[3]) & 0xff) << 16) + + be16_to_cpu(id[4]); + dev->id_device = be16_to_cpu(id[5]); + flags = be16_to_cpu(id[10]); + dev->speed_8mhz = !!(flags & 2); + dev->speed_32mhz = !!(flags & 4); + crc = ipack_calc_crc2(dev); + dev->id_crc_correct = (crc == be16_to_cpu(id[12])); + if (!dev->id_crc_correct) { + dev_warn(&dev->dev, "ID CRC invalid found 0x%x, expected 0x%x.\n", + id[11], crc); + } +} + +static int ipack_device_read_id(struct ipack_device *dev) +{ + u8 __iomem *idmem; + int i; + int ret = 0; + + idmem = ioremap(dev->region[IPACK_ID_SPACE].start, + dev->region[IPACK_ID_SPACE].size); + if (!idmem) { + dev_err(&dev->dev, "error mapping memory\n"); + return -ENOMEM; + } + + /* Determine ID PROM Data Format. If we find the ids "IPAC" or "IPAH" + * we are dealing with a IndustryPack format 1 device. If we detect + * "VITA4 " (16 bit big endian formatted) we are dealing with a + * IndustryPack format 2 device */ + if ((ioread8(idmem + 1) == 'I') && + (ioread8(idmem + 3) == 'P') && + (ioread8(idmem + 5) == 'A') && + ((ioread8(idmem + 7) == 'C') || + (ioread8(idmem + 7) == 'H'))) { + dev->id_format = IPACK_ID_VERSION_1; + dev->id_avail = ioread8(idmem + 0x15); + if ((dev->id_avail < 0x0c) || (dev->id_avail > 0x40)) { + dev_warn(&dev->dev, "invalid id size"); + dev->id_avail = 0x0c; + } + } else if ((ioread8(idmem + 0) == 'I') && + (ioread8(idmem + 1) == 'V') && + (ioread8(idmem + 2) == 'A') && + (ioread8(idmem + 3) == 'T') && + (ioread8(idmem + 4) == ' ') && + (ioread8(idmem + 5) == '4')) { + dev->id_format = IPACK_ID_VERSION_2; + dev->id_avail = ioread16be(idmem + 0x16); + if ((dev->id_avail < 0x1a) || (dev->id_avail > 0x40)) { + dev_warn(&dev->dev, "invalid id size"); + dev->id_avail = 0x1a; + } + } else { + dev->id_format = IPACK_ID_VERSION_INVALID; + dev->id_avail = 0; + } + + if (!dev->id_avail) { + ret = -ENODEV; + goto out; + } + + /* Obtain the amount of memory required to store a copy of the complete + * ID ROM contents */ + dev->id = kmalloc(dev->id_avail, GFP_KERNEL); + if (!dev->id) { + dev_err(&dev->dev, "dev->id alloc failed.\n"); + ret = -ENOMEM; + goto out; + } + for (i = 0; i < dev->id_avail; i++) { + if (dev->id_format == IPACK_ID_VERSION_1) + dev->id[i] = ioread8(idmem + (i << 1) + 1); + else + dev->id[i] = ioread8(idmem + i); + } + + /* now we can finally work with the copy */ + switch (dev->id_format) { + case IPACK_ID_VERSION_1: + ipack_parse_id1(dev); + break; + case IPACK_ID_VERSION_2: + ipack_parse_id2(dev); + break; + } + +out: + iounmap(idmem); + + return ret; +} + +int ipack_device_register(struct ipack_device *dev) +{ + int ret; + + dev->dev.bus = &ipack_bus_type; + dev->dev.release = ipack_device_release; + dev->dev.parent = dev->bus->parent; + dev_set_name(&dev->dev, + "ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot); + + if (dev->bus->ops->set_clockrate(dev, 8)) + dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n"); + if (dev->bus->ops->reset_timeout(dev)) + dev_warn(&dev->dev, "failed to reset potential timeout."); + + ret = ipack_device_read_id(dev); + if (ret < 0) { + dev_err(&dev->dev, "error reading device id section.\n"); + return ret; + } + + /* if the device supports 32 MHz operation, use it. */ + if (dev->speed_32mhz) { + ret = dev->bus->ops->set_clockrate(dev, 32); + if (ret < 0) + dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n"); + } + + ret = device_register(&dev->dev); + if (ret < 0) + kfree(dev->id); + + return ret; +} +EXPORT_SYMBOL_GPL(ipack_device_register); + +void ipack_device_unregister(struct ipack_device *dev) +{ + device_unregister(&dev->dev); +} +EXPORT_SYMBOL_GPL(ipack_device_unregister); + +static int __init ipack_init(void) +{ + ida_init(&ipack_ida); + return bus_register(&ipack_bus_type); +} + +static void __exit ipack_exit(void) +{ + bus_unregister(&ipack_bus_type); + ida_destroy(&ipack_ida); +} + +module_init(ipack_init); +module_exit(ipack_exit); + +MODULE_AUTHOR("Samuel Iglesias Gonsalvez "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Industry-pack bus core"); diff --git a/drivers/ipack/ipack.h b/drivers/ipack/ipack.h new file mode 100644 index 00000000000..6760bfaf0ac --- /dev/null +++ b/drivers/ipack/ipack.h @@ -0,0 +1,215 @@ +/* + * Industry-pack bus. + * + * Copyright (C) 2011-2012 CERN (www.cern.ch) + * Author: Samuel Iglesias Gonsalvez + * + * 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; version 2 of the License. + */ + +#include +#include +#include + +#include "ipack_ids.h" + +#define IPACK_IDPROM_OFFSET_I 0x01 +#define IPACK_IDPROM_OFFSET_P 0x03 +#define IPACK_IDPROM_OFFSET_A 0x05 +#define IPACK_IDPROM_OFFSET_C 0x07 +#define IPACK_IDPROM_OFFSET_MANUFACTURER_ID 0x09 +#define IPACK_IDPROM_OFFSET_MODEL 0x0B +#define IPACK_IDPROM_OFFSET_REVISION 0x0D +#define IPACK_IDPROM_OFFSET_RESERVED 0x0F +#define IPACK_IDPROM_OFFSET_DRIVER_ID_L 0x11 +#define IPACK_IDPROM_OFFSET_DRIVER_ID_H 0x13 +#define IPACK_IDPROM_OFFSET_NUM_BYTES 0x15 +#define IPACK_IDPROM_OFFSET_CRC 0x17 + +struct ipack_bus_ops; +struct ipack_driver; + +enum ipack_space { + IPACK_IO_SPACE = 0, + IPACK_ID_SPACE, + IPACK_INT_SPACE, + IPACK_MEM8_SPACE, + IPACK_MEM16_SPACE, + /* Dummy for counting the number of entries. Must remain the last + * entry */ + IPACK_SPACE_COUNT, +}; + +/** + */ +struct ipack_region { + phys_addr_t start; + size_t size; +}; + +/** + * struct ipack_device + * + * @slot: Slot where the device is plugged in the carrier board + * @bus: ipack_bus_device where the device is plugged to. + * @id_space: Virtual address to ID space. + * @io_space: Virtual address to IO space. + * @mem_space: Virtual address to MEM space. + * @dev: device in kernel representation. + * + * Warning: Direct access to mapped memory is possible but the endianness + * is not the same with PCI carrier or VME carrier. The endianness is managed + * by the carrier board throught bus->ops. + */ +struct ipack_device { + unsigned int slot; + struct ipack_bus_device *bus; + struct device dev; + void (*release) (struct ipack_device *dev); + struct ipack_region region[IPACK_SPACE_COUNT]; + u8 *id; + size_t id_avail; + u32 id_vendor; + u32 id_device; + u8 id_format; + unsigned int id_crc_correct:1; + unsigned int speed_8mhz:1; + unsigned int speed_32mhz:1; +}; + +/** + * struct ipack_driver_ops -- Callbacks to IPack device driver + * + * @probe: Probe function + * @remove: Prepare imminent removal of the device. Services provided by the + * device should be revoked. + */ + +struct ipack_driver_ops { + int (*probe) (struct ipack_device *dev); + void (*remove) (struct ipack_device *dev); +}; + +/** + * struct ipack_driver -- Specific data to each ipack device driver + * + * @driver: Device driver kernel representation + * @ops: Callbacks provided by the IPack device driver + */ +struct ipack_driver { + struct device_driver driver; + const struct ipack_device_id *id_table; + const struct ipack_driver_ops *ops; +}; + +/** + * struct ipack_bus_ops - available operations on a bridge module + * + * @map_space: map IP address space + * @unmap_space: unmap IP address space + * @request_irq: request IRQ + * @free_irq: free IRQ + * @get_clockrate: Returns the clockrate the carrier is currently + * communicating with the device at. + * @set_clockrate: Sets the clock-rate for carrier / module communication. + * Should return -EINVAL if the requested speed is not supported. + * @get_error: Returns the error state for the slot the device is attached + * to. + * @get_timeout: Returns 1 if the communication with the device has + * previously timed out. + * @reset_timeout: Resets the state returned by get_timeout. + */ +struct ipack_bus_ops { + int (*request_irq) (struct ipack_device *dev, + irqreturn_t (*handler)(void *), void *arg); + int (*free_irq) (struct ipack_device *dev); + int (*get_clockrate) (struct ipack_device *dev); + int (*set_clockrate) (struct ipack_device *dev, int mherz); + int (*get_error) (struct ipack_device *dev); + int (*get_timeout) (struct ipack_device *dev); + int (*reset_timeout) (struct ipack_device *dev); +}; + +/** + * struct ipack_bus_device + * + * @dev: pointer to carrier device + * @slots: number of slots available + * @bus_nr: ipack bus number + * @ops: bus operations for the mezzanine drivers + */ +struct ipack_bus_device { + struct device *parent; + int slots; + int bus_nr; + const struct ipack_bus_ops *ops; +}; + +/** + * ipack_bus_register -- register a new ipack bus + * + * @parent: pointer to the parent device, if any. + * @slots: number of slots available in the bus device. + * @ops: bus operations for the mezzanine drivers. + * + * The carrier board device should call this function to register itself as + * available bus device in ipack. + */ +struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, + const struct ipack_bus_ops *ops); + +/** + * ipack_bus_unregister -- unregister an ipack bus + */ +int ipack_bus_unregister(struct ipack_bus_device *bus); + +/** + * ipack_driver_register -- Register a new ipack device driver + * + * Called by a ipack driver to register itself as a driver + * that can manage ipack devices. + */ +int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, + const char *name); +void ipack_driver_unregister(struct ipack_driver *edrv); + +/** + * ipack_device_register -- register an IPack device with the kernel + * @dev: the new device to register. + * + * Register a new IPack device ("module" in IndustryPack jargon). The call + * is done by the carrier driver. The carrier should populate the fields + * bus and slot as well as the region array of @dev prior to calling this + * function. The rest of the fields will be allocated and populated + * during registration. + * + * Return zero on success or error code on failure. + */ +int ipack_device_register(struct ipack_device *dev); +void ipack_device_unregister(struct ipack_device *dev); + +/** + * DEFINE_IPACK_DEVICE_TABLE - macro used to describe a IndustryPack table + * @_table: device table name + * + * This macro is used to create a struct ipack_device_id array (a device table) + * in a generic manner. + */ +#define DEFINE_IPACK_DEVICE_TABLE(_table) \ + const struct ipack_device_id _table[] __devinitconst + +/** + * IPACK_DEVICE - macro used to describe a specific IndustryPack device + * @_format: the format version (currently either 1 or 2, 8 bit value) + * @vend: the 8 or 24 bit IndustryPack Vendor ID + * @dev: the 8 or 16 bit IndustryPack Device ID + * + * This macro is used to create a struct ipack_device_id that matches a specific + * device. + */ +#define IPACK_DEVICE(_format, vend, dev) \ + .format = (_format), \ + .vendor = (vend), \ + .device = (dev) diff --git a/drivers/ipack/ipack_ids.h b/drivers/ipack/ipack_ids.h new file mode 100644 index 00000000000..8153fee3f2f --- /dev/null +++ b/drivers/ipack/ipack_ids.h @@ -0,0 +1,32 @@ +/* + * IndustryPack Fromat, Vendor and Device IDs. + */ + +/* ID section format versions */ +#define IPACK_ID_VERSION_INVALID 0x00 +#define IPACK_ID_VERSION_1 0x01 +#define IPACK_ID_VERSION_2 0x02 + +/* Vendors and devices. Sort key: vendor first, device next. */ +#define IPACK1_VENDOR_ID_RESERVED1 0x00 +#define IPACK1_VENDOR_ID_RESERVED2 0xFF +#define IPACK1_VENDOR_ID_UNREGISTRED01 0x01 +#define IPACK1_VENDOR_ID_UNREGISTRED02 0x02 +#define IPACK1_VENDOR_ID_UNREGISTRED03 0x03 +#define IPACK1_VENDOR_ID_UNREGISTRED04 0x04 +#define IPACK1_VENDOR_ID_UNREGISTRED05 0x05 +#define IPACK1_VENDOR_ID_UNREGISTRED06 0x06 +#define IPACK1_VENDOR_ID_UNREGISTRED07 0x07 +#define IPACK1_VENDOR_ID_UNREGISTRED08 0x08 +#define IPACK1_VENDOR_ID_UNREGISTRED09 0x09 +#define IPACK1_VENDOR_ID_UNREGISTRED10 0x0A +#define IPACK1_VENDOR_ID_UNREGISTRED11 0x0B +#define IPACK1_VENDOR_ID_UNREGISTRED12 0x0C +#define IPACK1_VENDOR_ID_UNREGISTRED13 0x0D +#define IPACK1_VENDOR_ID_UNREGISTRED14 0x0E +#define IPACK1_VENDOR_ID_UNREGISTRED15 0x0F + +#define IPACK1_VENDOR_ID_SBS 0xF0 +#define IPACK1_DEVICE_ID_SBS_OCTAL_232 0x22 +#define IPACK1_DEVICE_ID_SBS_OCTAL_422 0x2A +#define IPACK1_DEVICE_ID_SBS_OCTAL_485 0x48 diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 12a6f2e0aee..943ca607200 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -122,8 +122,6 @@ source "drivers/staging/ozwpan/Kconfig" source "drivers/staging/ccg/Kconfig" -source "drivers/staging/ipack/Kconfig" - source "drivers/staging/gdm72xx/Kconfig" source "drivers/staging/csr/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 6d16f822e27..20c764d7ab3 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -28,7 +28,6 @@ obj-$(CONFIG_OCTEON_ETHERNET) += octeon/ obj-$(CONFIG_VT6655) += vt6655/ obj-$(CONFIG_VT6656) += vt6656/ obj-$(CONFIG_VME_BUS) += vme/ -obj-$(CONFIG_IPACK_BUS) += ipack/ obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_ZRAM) += zram/ diff --git a/drivers/staging/ipack/Kconfig b/drivers/staging/ipack/Kconfig deleted file mode 100644 index 5cf43b3364e..00000000000 --- a/drivers/staging/ipack/Kconfig +++ /dev/null @@ -1,24 +0,0 @@ -# -# IPACK configuration. -# - -menuconfig IPACK_BUS - tristate "IndustryPack bus support" - depends on HAS_IOMEM - ---help--- - This option provides support for the IndustryPack framework. There - are IndustryPack carrier boards, which interface another bus (such as - PCI) to an IndustryPack bus, and IndustryPack modules, that are - hosted on these buses. While IndustryPack modules can provide a - large variety of functionality, they are most often found in - industrial control applications. - - Say N if unsure. - -if IPACK_BUS - -source "drivers/staging/ipack/carriers/Kconfig" - -source "drivers/staging/ipack/devices/Kconfig" - -endif # IPACK diff --git a/drivers/staging/ipack/Makefile b/drivers/staging/ipack/Makefile deleted file mode 100644 index 6f14ade0f8f..00000000000 --- a/drivers/staging/ipack/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for the IPACK bridge device drivers. -# -obj-$(CONFIG_IPACK_BUS) += ipack.o -obj-y += devices/ -obj-y += carriers/ diff --git a/drivers/staging/ipack/TODO b/drivers/staging/ipack/TODO deleted file mode 100644 index e667acf5d33..00000000000 --- a/drivers/staging/ipack/TODO +++ /dev/null @@ -1,16 +0,0 @@ - TODO - ==== -Introduction -============ - -These drivers add support for IndustryPack devices: carrier and IP module -boards. - -The ipack driver is just an abstraction of the bus providing the common -operations between the two kind of boards. - -Contact -======= - -Contact: Samuel Iglesias Gonsalvez -Mailing List: industrypack-devel@lists.sourceforge.net diff --git a/drivers/staging/ipack/carriers/Kconfig b/drivers/staging/ipack/carriers/Kconfig deleted file mode 100644 index 922ff5c35ac..00000000000 --- a/drivers/staging/ipack/carriers/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -config BOARD_TPCI200 - tristate "Support for the TEWS TPCI-200 IndustryPack carrier board" - depends on IPACK_BUS - depends on PCI - help - This driver adds support for the TEWS TPCI200 IndustryPack carrier board. - default n diff --git a/drivers/staging/ipack/carriers/Makefile b/drivers/staging/ipack/carriers/Makefile deleted file mode 100644 index d8b76459300..00000000000 --- a/drivers/staging/ipack/carriers/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_BOARD_TPCI200) += tpci200.o diff --git a/drivers/staging/ipack/carriers/tpci200.c b/drivers/staging/ipack/carriers/tpci200.c deleted file mode 100644 index c1a19b274c2..00000000000 --- a/drivers/staging/ipack/carriers/tpci200.c +++ /dev/null @@ -1,627 +0,0 @@ -/** - * tpci200.c - * - * driver for the TEWS TPCI-200 device - * - * Copyright (C) 2009-2012 CERN (www.cern.ch) - * Author: Nicolas Serafini, EIC2 SA - * Author: Samuel Iglesias Gonsalvez - * - * 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; version 2 of the License. - */ - -#include -#include -#include "tpci200.h" - -static const u16 tpci200_status_timeout[] = { - TPCI200_A_TIMEOUT, - TPCI200_B_TIMEOUT, - TPCI200_C_TIMEOUT, - TPCI200_D_TIMEOUT, -}; - -static const u16 tpci200_status_error[] = { - TPCI200_A_ERROR, - TPCI200_B_ERROR, - TPCI200_C_ERROR, - TPCI200_D_ERROR, -}; - -static const size_t tpci200_space_size[IPACK_SPACE_COUNT] = { - [IPACK_IO_SPACE] = TPCI200_IO_SPACE_SIZE, - [IPACK_ID_SPACE] = TPCI200_ID_SPACE_SIZE, - [IPACK_INT_SPACE] = TPCI200_INT_SPACE_SIZE, - [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_SIZE, - [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_SIZE, -}; - -static const size_t tpci200_space_interval[IPACK_SPACE_COUNT] = { - [IPACK_IO_SPACE] = TPCI200_IO_SPACE_INTERVAL, - [IPACK_ID_SPACE] = TPCI200_ID_SPACE_INTERVAL, - [IPACK_INT_SPACE] = TPCI200_INT_SPACE_INTERVAL, - [IPACK_MEM8_SPACE] = TPCI200_MEM8_SPACE_INTERVAL, - [IPACK_MEM16_SPACE] = TPCI200_MEM16_SPACE_INTERVAL, -}; - -static struct tpci200_board *check_slot(struct ipack_device *dev) -{ - struct tpci200_board *tpci200; - - if (dev == NULL) - return NULL; - - - tpci200 = dev_get_drvdata(dev->bus->parent); - - if (tpci200 == NULL) { - dev_info(&dev->dev, "carrier board not found\n"); - return NULL; - } - - if (dev->slot >= TPCI200_NB_SLOT) { - dev_info(&dev->dev, - "Slot [%d:%d] doesn't exist! Last tpci200 slot is %d.\n", - dev->bus->bus_nr, dev->slot, TPCI200_NB_SLOT-1); - return NULL; - } - - return tpci200; -} - -static void tpci200_clear_mask(struct tpci200_board *tpci200, - __le16 __iomem *addr, u16 mask) -{ - unsigned long flags; - spin_lock_irqsave(&tpci200->regs_lock, flags); - iowrite16(ioread16(addr) & (~mask), addr); - spin_unlock_irqrestore(&tpci200->regs_lock, flags); -} - -static void tpci200_set_mask(struct tpci200_board *tpci200, - __le16 __iomem *addr, u16 mask) -{ - unsigned long flags; - spin_lock_irqsave(&tpci200->regs_lock, flags); - iowrite16(ioread16(addr) | mask, addr); - spin_unlock_irqrestore(&tpci200->regs_lock, flags); -} - -static void tpci200_unregister(struct tpci200_board *tpci200) -{ - free_irq(tpci200->info->pdev->irq, (void *) tpci200); - - pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); - pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs); - - pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); - pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); - pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR); - pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); - pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR); - - pci_disable_device(tpci200->info->pdev); - pci_dev_put(tpci200->info->pdev); -} - -static void tpci200_enable_irq(struct tpci200_board *tpci200, - int islot) -{ - tpci200_set_mask(tpci200, - &tpci200->info->interface_regs->control[islot], - TPCI200_INT0_EN | TPCI200_INT1_EN); -} - -static void tpci200_disable_irq(struct tpci200_board *tpci200, - int islot) -{ - tpci200_clear_mask(tpci200, - &tpci200->info->interface_regs->control[islot], - TPCI200_INT0_EN | TPCI200_INT1_EN); -} - -static irqreturn_t tpci200_slot_irq(struct slot_irq *slot_irq) -{ - irqreturn_t ret; - - if (!slot_irq) - return -ENODEV; - ret = slot_irq->handler(slot_irq->arg); - - return ret; -} - -static irqreturn_t tpci200_interrupt(int irq, void *dev_id) -{ - struct tpci200_board *tpci200 = (struct tpci200_board *) dev_id; - struct slot_irq *slot_irq; - irqreturn_t ret; - u16 status_reg; - int i; - - /* Read status register */ - status_reg = ioread16(&tpci200->info->interface_regs->status); - - /* Did we cause the interrupt? */ - if (!(status_reg & TPCI200_SLOT_INT_MASK)) - return IRQ_NONE; - - /* callback to the IRQ handler for the corresponding slot */ - rcu_read_lock(); - for (i = 0; i < TPCI200_NB_SLOT; i++) { - if (!(status_reg & ((TPCI200_A_INT0 | TPCI200_A_INT1) << (2 * i)))) - continue; - slot_irq = rcu_dereference(tpci200->slots[i].irq); - ret = tpci200_slot_irq(slot_irq); - if (ret == -ENODEV) { - dev_info(&tpci200->info->pdev->dev, - "No registered ISR for slot [%d:%d]!. IRQ will be disabled.\n", - tpci200->number, i); - tpci200_disable_irq(tpci200, i); - } - } - rcu_read_unlock(); - - return IRQ_HANDLED; -} - -static int tpci200_free_irq(struct ipack_device *dev) -{ - struct slot_irq *slot_irq; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - if (mutex_lock_interruptible(&tpci200->mutex)) - return -ERESTARTSYS; - - if (tpci200->slots[dev->slot].irq == NULL) { - mutex_unlock(&tpci200->mutex); - return -EINVAL; - } - - tpci200_disable_irq(tpci200, dev->slot); - slot_irq = tpci200->slots[dev->slot].irq; - /* uninstall handler */ - RCU_INIT_POINTER(tpci200->slots[dev->slot].irq, NULL); - synchronize_rcu(); - kfree(slot_irq); - mutex_unlock(&tpci200->mutex); - return 0; -} - -static int tpci200_request_irq(struct ipack_device *dev, - irqreturn_t (*handler)(void *), void *arg) -{ - int res = 0; - struct slot_irq *slot_irq; - struct tpci200_board *tpci200; - - tpci200 = check_slot(dev); - if (tpci200 == NULL) - return -EINVAL; - - if (mutex_lock_interruptible(&tpci200->mutex)) - return -ERESTARTSYS; - - if (tpci200->slots[dev->slot].irq != NULL) { - dev_err(&dev->dev, - "Slot [%d:%d] IRQ already registered !\n", - dev->bus->bus_nr, - dev->slot); - res = -EINVAL; - goto out_unlock; - } - - slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL); - if (slot_irq == NULL) { - dev_err(&dev->dev, - "Slot [%d:%d] unable to allocate memory for IRQ !\n", - dev->bus->bus_nr, dev->slot); - res = -ENOMEM; - goto out_unlock; - } - - /* - * WARNING: Setup Interrupt Vector in the IndustryPack device - * before an IRQ request. - * Read the User Manual of your IndustryPack device to know - * where to write the vector in memory. - */ - slot_irq->handler = handler; - slot_irq->arg = arg; - slot_irq->holder = dev; - - rcu_assign_pointer(tpci200->slots[dev->slot].irq, slot_irq); - tpci200_enable_irq(tpci200, dev->slot); - -out_unlock: - mutex_unlock(&tpci200->mutex); - return res; -} - -static int tpci200_register(struct tpci200_board *tpci200) -{ - int i; - int res; - phys_addr_t ioidint_base; - unsigned short slot_ctrl; - - if (pci_enable_device(tpci200->info->pdev) < 0) - return -ENODEV; - - /* Request IP interface register (Bar 2) */ - res = pci_request_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR, - "Carrier IP interface registers"); - if (res) { - dev_err(&tpci200->info->pdev->dev, - "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); - goto out_disable_pci; - } - - /* Request IO ID INT space (Bar 3) */ - res = pci_request_region(tpci200->info->pdev, - TPCI200_IO_ID_INT_SPACES_BAR, - "Carrier IO ID INT space"); - if (res) { - dev_err(&tpci200->info->pdev->dev, - "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); - goto out_release_ip_space; - } - - /* Request MEM8 space (Bar 5) */ - res = pci_request_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR, - "Carrier MEM8 space"); - if (res) { - dev_err(&tpci200->info->pdev->dev, - "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); - goto out_release_ioid_int_space; - } - - /* Request MEM16 space (Bar 4) */ - res = pci_request_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR, - "Carrier MEM16 space"); - if (res) { - dev_err(&tpci200->info->pdev->dev, - "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); - goto out_release_mem8_space; - } - - /* Map internal tpci200 driver user space */ - tpci200->info->interface_regs = - ioremap_nocache(pci_resource_start(tpci200->info->pdev, - TPCI200_IP_INTERFACE_BAR), - TPCI200_IFACE_SIZE); - - /* Initialize lock that protects interface_regs */ - spin_lock_init(&tpci200->regs_lock); - - ioidint_base = pci_resource_start(tpci200->info->pdev, - TPCI200_IO_ID_INT_SPACES_BAR); - tpci200->mod_mem[IPACK_IO_SPACE] = ioidint_base + TPCI200_IO_SPACE_OFF; - tpci200->mod_mem[IPACK_ID_SPACE] = ioidint_base + TPCI200_ID_SPACE_OFF; - tpci200->mod_mem[IPACK_INT_SPACE] = - ioidint_base + TPCI200_INT_SPACE_OFF; - tpci200->mod_mem[IPACK_MEM8_SPACE] = - pci_resource_start(tpci200->info->pdev, - TPCI200_MEM8_SPACE_BAR); - tpci200->mod_mem[IPACK_MEM16_SPACE] = - pci_resource_start(tpci200->info->pdev, - TPCI200_MEM16_SPACE_BAR); - - /* Set the default parameters of the slot - * INT0 disabled, level sensitive - * INT1 disabled, level sensitive - * error interrupt disabled - * timeout interrupt disabled - * recover time disabled - * clock rate 8 MHz - */ - slot_ctrl = 0; - for (i = 0; i < TPCI200_NB_SLOT; i++) - writew(slot_ctrl, &tpci200->info->interface_regs->control[i]); - - res = request_irq(tpci200->info->pdev->irq, - tpci200_interrupt, IRQF_SHARED, - KBUILD_MODNAME, (void *) tpci200); - if (res) { - dev_err(&tpci200->info->pdev->dev, - "(bn 0x%X, sn 0x%X) unable to register IRQ !", - tpci200->info->pdev->bus->number, - tpci200->info->pdev->devfn); - goto out_release_ioid_int_space; - } - - return 0; - -out_release_mem8_space: - pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); -out_release_ioid_int_space: - pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); -out_release_ip_space: - pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); -out_disable_pci: - pci_disable_device(tpci200->info->pdev); - return res; -} - -static int tpci200_get_clockrate(struct ipack_device *dev) -{ - struct tpci200_board *tpci200 = check_slot(dev); - __le16 __iomem *addr; - - if (!tpci200) - return -ENODEV; - - addr = &tpci200->info->interface_regs->control[dev->slot]; - return (ioread16(addr) & TPCI200_CLK32) ? 32 : 8; -} - -static int tpci200_set_clockrate(struct ipack_device *dev, int mherz) -{ - struct tpci200_board *tpci200 = check_slot(dev); - __le16 __iomem *addr; - - if (!tpci200) - return -ENODEV; - - addr = &tpci200->info->interface_regs->control[dev->slot]; - - switch (mherz) { - case 8: - tpci200_clear_mask(tpci200, addr, TPCI200_CLK32); - break; - case 32: - tpci200_set_mask(tpci200, addr, TPCI200_CLK32); - break; - default: - return -EINVAL; - } - return 0; -} - -static int tpci200_get_error(struct ipack_device *dev) -{ - struct tpci200_board *tpci200 = check_slot(dev); - __le16 __iomem *addr; - u16 mask; - - if (!tpci200) - return -ENODEV; - - addr = &tpci200->info->interface_regs->status; - mask = tpci200_status_error[dev->slot]; - return (ioread16(addr) & mask) ? 1 : 0; -} - -static int tpci200_get_timeout(struct ipack_device *dev) -{ - struct tpci200_board *tpci200 = check_slot(dev); - __le16 __iomem *addr; - u16 mask; - - if (!tpci200) - return -ENODEV; - - addr = &tpci200->info->interface_regs->status; - mask = tpci200_status_timeout[dev->slot]; - - return (ioread16(addr) & mask) ? 1 : 0; -} - -static int tpci200_reset_timeout(struct ipack_device *dev) -{ - struct tpci200_board *tpci200 = check_slot(dev); - __le16 __iomem *addr; - u16 mask; - - if (!tpci200) - return -ENODEV; - - addr = &tpci200->info->interface_regs->status; - mask = tpci200_status_timeout[dev->slot]; - - iowrite16(mask, addr); - return 0; -} - -static void tpci200_uninstall(struct tpci200_board *tpci200) -{ - tpci200_unregister(tpci200); - kfree(tpci200->slots); -} - -static const struct ipack_bus_ops tpci200_bus_ops = { - .request_irq = tpci200_request_irq, - .free_irq = tpci200_free_irq, - .get_clockrate = tpci200_get_clockrate, - .set_clockrate = tpci200_set_clockrate, - .get_error = tpci200_get_error, - .get_timeout = tpci200_get_timeout, - .reset_timeout = tpci200_reset_timeout, -}; - -static int tpci200_install(struct tpci200_board *tpci200) -{ - int res; - - tpci200->slots = kzalloc( - TPCI200_NB_SLOT * sizeof(struct tpci200_slot), GFP_KERNEL); - if (tpci200->slots == NULL) - return -ENOMEM; - - res = tpci200_register(tpci200); - if (res) { - kfree(tpci200->slots); - tpci200->slots = NULL; - return res; - } - - mutex_init(&tpci200->mutex); - return 0; -} - -static void tpci200_release_device(struct ipack_device *dev) -{ - kfree(dev); -} - -static int tpci200_create_device(struct tpci200_board *tpci200, int i) -{ - enum ipack_space space; - struct ipack_device *dev = - kzalloc(sizeof(struct ipack_device), GFP_KERNEL); - if (!dev) - return -ENOMEM; - dev->slot = i; - dev->bus = tpci200->info->ipack_bus; - dev->release = tpci200_release_device; - - for (space = 0; space < IPACK_SPACE_COUNT; space++) { - dev->region[space].start = - tpci200->mod_mem[space] - + tpci200_space_interval[space] * i; - dev->region[space].size = tpci200_space_size[space]; - } - return ipack_device_register(dev); -} - -static int tpci200_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - int ret, i; - struct tpci200_board *tpci200; - u32 reg32; - - tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL); - if (!tpci200) - return -ENOMEM; - - tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL); - if (!tpci200->info) { - ret = -ENOMEM; - goto out_err_info; - } - - pci_dev_get(pdev); - - /* Obtain a mapping of the carrier's PCI configuration registers */ - ret = pci_request_region(pdev, TPCI200_CFG_MEM_BAR, - KBUILD_MODNAME " Configuration Memory"); - if (ret) { - dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory"); - ret = -EBUSY; - goto out_err_pci_request; - } - tpci200->info->cfg_regs = ioremap_nocache( - pci_resource_start(pdev, TPCI200_CFG_MEM_BAR), - pci_resource_len(pdev, TPCI200_CFG_MEM_BAR)); - if (!tpci200->info->cfg_regs) { - dev_err(&pdev->dev, "Failed to map PCI Configuration Memory"); - ret = -EFAULT; - goto out_err_ioremap; - } - - /* Disable byte swapping for 16 bit IP module access. This will ensure - * that the Industrypack big endian byte order is preserved by the - * carrier. */ - reg32 = ioread32(tpci200->info->cfg_regs + LAS1_DESC); - reg32 |= 1 << LAS_BIT_BIGENDIAN; - iowrite32(reg32, tpci200->info->cfg_regs + LAS1_DESC); - - reg32 = ioread32(tpci200->info->cfg_regs + LAS2_DESC); - reg32 |= 1 << LAS_BIT_BIGENDIAN; - iowrite32(reg32, tpci200->info->cfg_regs + LAS2_DESC); - - /* Save struct pci_dev pointer */ - tpci200->info->pdev = pdev; - tpci200->info->id_table = (struct pci_device_id *)id; - - /* register the device and initialize it */ - ret = tpci200_install(tpci200); - if (ret) { - dev_err(&pdev->dev, "error during tpci200 install\n"); - ret = -ENODEV; - goto out_err_install; - } - - /* Register the carrier in the industry pack bus driver */ - tpci200->info->ipack_bus = ipack_bus_register(&pdev->dev, - TPCI200_NB_SLOT, - &tpci200_bus_ops); - if (!tpci200->info->ipack_bus) { - dev_err(&pdev->dev, - "error registering the carrier on ipack driver\n"); - ret = -EFAULT; - goto out_err_bus_register; - } - - /* save the bus number given by ipack to logging purpose */ - tpci200->number = tpci200->info->ipack_bus->bus_nr; - dev_set_drvdata(&pdev->dev, tpci200); - - for (i = 0; i < TPCI200_NB_SLOT; i++) - tpci200_create_device(tpci200, i); - return 0; - -out_err_bus_register: - tpci200_uninstall(tpci200); -out_err_install: - iounmap(tpci200->info->cfg_regs); -out_err_ioremap: - pci_release_region(pdev, TPCI200_CFG_MEM_BAR); -out_err_pci_request: - pci_dev_put(pdev); - kfree(tpci200->info); -out_err_info: - kfree(tpci200); - return ret; -} - -static void __tpci200_pci_remove(struct tpci200_board *tpci200) -{ - ipack_bus_unregister(tpci200->info->ipack_bus); - tpci200_uninstall(tpci200); - - kfree(tpci200->info); - kfree(tpci200); -} - -static void __devexit tpci200_pci_remove(struct pci_dev *dev) -{ - struct tpci200_board *tpci200 = pci_get_drvdata(dev); - - __tpci200_pci_remove(tpci200); -} - -static DEFINE_PCI_DEVICE_TABLE(tpci200_idtable) = { - { TPCI200_VENDOR_ID, TPCI200_DEVICE_ID, TPCI200_SUBVENDOR_ID, - TPCI200_SUBDEVICE_ID }, - { 0, }, -}; - -MODULE_DEVICE_TABLE(pci, tpci200_idtable); - -static struct pci_driver tpci200_pci_drv = { - .name = "tpci200", - .id_table = tpci200_idtable, - .probe = tpci200_pci_probe, - .remove = __devexit_p(tpci200_pci_remove), -}; - -module_pci_driver(tpci200_pci_drv); - -MODULE_DESCRIPTION("TEWS TPCI-200 device driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/ipack/carriers/tpci200.h b/drivers/staging/ipack/carriers/tpci200.h deleted file mode 100644 index 8d9be277b34..00000000000 --- a/drivers/staging/ipack/carriers/tpci200.h +++ /dev/null @@ -1,168 +0,0 @@ -/** - * tpci200.h - * - * driver for the carrier TEWS TPCI-200 - * - * Copyright (C) 2009-2012 CERN (www.cern.ch) - * Author: Nicolas Serafini, EIC2 SA - * Author: Samuel Iglesias Gonsalvez - * - * 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; version 2 of the License. - */ - -#ifndef _TPCI200_H_ -#define _TPCI200_H_ - -#include -#include -#include -#include -#include - -#include "../ipack.h" - -#define TPCI200_NB_SLOT 0x4 -#define TPCI200_NB_BAR 0x6 - -#define TPCI200_VENDOR_ID 0x1498 -#define TPCI200_DEVICE_ID 0x30C8 -#define TPCI200_SUBVENDOR_ID 0x1498 -#define TPCI200_SUBDEVICE_ID 0x300A - -#define TPCI200_CFG_MEM_BAR 0 -#define TPCI200_IP_INTERFACE_BAR 2 -#define TPCI200_IO_ID_INT_SPACES_BAR 3 -#define TPCI200_MEM16_SPACE_BAR 4 -#define TPCI200_MEM8_SPACE_BAR 5 - -struct tpci200_regs { - __le16 revision; - /* writes to control should occur with the mutex held to protect - * read-modify-write operations */ - __le16 control[4]; - __le16 reset; - __le16 status; - u8 reserved[242]; -} __packed; - -#define TPCI200_IFACE_SIZE 0x100 - -#define TPCI200_IO_SPACE_OFF 0x0000 -#define TPCI200_IO_SPACE_INTERVAL 0x0100 -#define TPCI200_IO_SPACE_SIZE 0x0080 -#define TPCI200_ID_SPACE_OFF 0x0080 -#define TPCI200_ID_SPACE_INTERVAL 0x0100 -#define TPCI200_ID_SPACE_SIZE 0x0040 -#define TPCI200_INT_SPACE_OFF 0x00C0 -#define TPCI200_INT_SPACE_INTERVAL 0x0100 -#define TPCI200_INT_SPACE_SIZE 0x0040 -#define TPCI200_IOIDINT_SIZE 0x0400 - -#define TPCI200_MEM8_SPACE_INTERVAL 0x00400000 -#define TPCI200_MEM8_SPACE_SIZE 0x00400000 -#define TPCI200_MEM16_SPACE_INTERVAL 0x00800000 -#define TPCI200_MEM16_SPACE_SIZE 0x00800000 - -/* control field in tpci200_regs */ -#define TPCI200_INT0_EN 0x0040 -#define TPCI200_INT1_EN 0x0080 -#define TPCI200_INT0_EDGE 0x0010 -#define TPCI200_INT1_EDGE 0x0020 -#define TPCI200_ERR_INT_EN 0x0008 -#define TPCI200_TIME_INT_EN 0x0004 -#define TPCI200_RECOVER_EN 0x0002 -#define TPCI200_CLK32 0x0001 - -/* reset field in tpci200_regs */ -#define TPCI200_A_RESET 0x0001 -#define TPCI200_B_RESET 0x0002 -#define TPCI200_C_RESET 0x0004 -#define TPCI200_D_RESET 0x0008 - -/* status field in tpci200_regs */ -#define TPCI200_A_TIMEOUT 0x1000 -#define TPCI200_B_TIMEOUT 0x2000 -#define TPCI200_C_TIMEOUT 0x4000 -#define TPCI200_D_TIMEOUT 0x8000 - -#define TPCI200_A_ERROR 0x0100 -#define TPCI200_B_ERROR 0x0200 -#define TPCI200_C_ERROR 0x0400 -#define TPCI200_D_ERROR 0x0800 - -#define TPCI200_A_INT0 0x0001 -#define TPCI200_A_INT1 0x0002 -#define TPCI200_B_INT0 0x0004 -#define TPCI200_B_INT1 0x0008 -#define TPCI200_C_INT0 0x0010 -#define TPCI200_C_INT1 0x0020 -#define TPCI200_D_INT0 0x0040 -#define TPCI200_D_INT1 0x0080 - -#define TPCI200_SLOT_INT_MASK 0x00FF - -/* PCI Configuration registers. The PCI bridge is a PLX Technology PCI9030. */ -#define LAS1_DESC 0x2C -#define LAS2_DESC 0x30 - -/* Bits in the LAS?_DESC registers */ -#define LAS_BIT_BIGENDIAN 24 - -#define VME_IOID_SPACE "IOID" -#define VME_MEM_SPACE "MEM" - -/** - * struct slot_irq - slot IRQ definition. - * @vector Vector number - * @handler Handler called when IRQ arrives - * @arg Handler argument - * - */ -struct slot_irq { - struct ipack_device *holder; - int vector; - irqreturn_t (*handler)(void *); - void *arg; -}; - -/** - * struct tpci200_slot - data specific to the tpci200 slot. - * @slot_id Slot identification gived to external interface - * @irq Slot IRQ infos - * @io_phys IO physical base address register of the slot - * @id_phys ID physical base address register of the slot - * @int_phys INT physical base address register of the slot - * @mem_phys MEM physical base address register of the slot - * - */ -struct tpci200_slot { - struct slot_irq *irq; -}; - -/** - * struct tpci200_infos - informations specific of the TPCI200 tpci200. - * @pci_dev PCI device - * @interface_regs Pointer to IP interface space (Bar 2) - * @ioidint_space Pointer to IP ID, IO and INT space (Bar 3) - * @mem8_space Pointer to MEM space (Bar 4) - * - */ -struct tpci200_infos { - struct pci_dev *pdev; - struct pci_device_id *id_table; - struct tpci200_regs __iomem *interface_regs; - void __iomem *cfg_regs; - struct ipack_bus_device *ipack_bus; -}; -struct tpci200_board { - unsigned int number; - struct mutex mutex; - spinlock_t regs_lock; - struct tpci200_slot *slots; - struct tpci200_infos *info; - phys_addr_t mod_mem[IPACK_SPACE_COUNT]; -}; - -#endif /* _TPCI200_H_ */ diff --git a/drivers/staging/ipack/devices/Kconfig b/drivers/staging/ipack/devices/Kconfig deleted file mode 100644 index 0b82fdc198c..00000000000 --- a/drivers/staging/ipack/devices/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config SERIAL_IPOCTAL - tristate "IndustryPack IP-OCTAL uart support" - depends on IPACK_BUS - help - This driver supports the IPOCTAL serial port device for the IndustryPack bus. - default n diff --git a/drivers/staging/ipack/devices/Makefile b/drivers/staging/ipack/devices/Makefile deleted file mode 100644 index 6de18bda4a9..00000000000 --- a/drivers/staging/ipack/devices/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_SERIAL_IPOCTAL) += ipoctal.o diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c deleted file mode 100644 index 783f120338d..00000000000 --- a/drivers/staging/ipack/devices/ipoctal.c +++ /dev/null @@ -1,751 +0,0 @@ -/** - * ipoctal.c - * - * driver for the GE IP-OCTAL boards - * - * Copyright (C) 2009-2012 CERN (www.cern.ch) - * Author: Nicolas Serafini, EIC2 SA - * Author: Samuel Iglesias Gonsalvez - * - * 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; version 2 of the License. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../ipack.h" -#include "ipoctal.h" -#include "scc2698.h" - -#define IP_OCTAL_ID_SPACE_VECTOR 0x41 -#define IP_OCTAL_NB_BLOCKS 4 - -static const struct tty_operations ipoctal_fops; - -struct ipoctal_channel { - struct ipoctal_stats stats; - unsigned int nb_bytes; - wait_queue_head_t queue; - spinlock_t lock; - unsigned int pointer_read; - unsigned int pointer_write; - atomic_t open; - struct tty_port tty_port; - union scc2698_channel __iomem *regs; - union scc2698_block __iomem *block_regs; - unsigned int board_id; - unsigned char *board_write; - u8 isr_rx_rdy_mask; - u8 isr_tx_rdy_mask; -}; - -struct ipoctal { - struct ipack_device *dev; - unsigned int board_id; - struct ipoctal_channel channel[NR_CHANNELS]; - unsigned char write; - struct tty_driver *tty_drv; - u8 __iomem *mem8_space; - u8 __iomem *int_space; -}; - -static int ipoctal_port_activate(struct tty_port *port, struct tty_struct *tty) -{ - struct ipoctal_channel *channel; - - channel = dev_get_drvdata(tty->dev); - - iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); - return 0; -} - -static int ipoctal_open(struct tty_struct *tty, struct file *file) -{ - int res; - struct ipoctal_channel *channel; - - channel = dev_get_drvdata(tty->dev); - - if (atomic_read(&channel->open)) - return -EBUSY; - - tty->driver_data = channel; - - res = tty_port_open(&channel->tty_port, tty, file); - if (res) - return res; - - atomic_inc(&channel->open); - return 0; -} - -static void ipoctal_reset_stats(struct ipoctal_stats *stats) -{ - stats->tx = 0; - stats->rx = 0; - stats->rcv_break = 0; - stats->framing_err = 0; - stats->overrun_err = 0; - stats->parity_err = 0; -} - -static void ipoctal_free_channel(struct ipoctal_channel *channel) -{ - ipoctal_reset_stats(&channel->stats); - channel->pointer_read = 0; - channel->pointer_write = 0; - channel->nb_bytes = 0; -} - -static void ipoctal_close(struct tty_struct *tty, struct file *filp) -{ - struct ipoctal_channel *channel = tty->driver_data; - - tty_port_close(&channel->tty_port, tty, filp); - - if (atomic_dec_and_test(&channel->open)) - ipoctal_free_channel(channel); -} - -static int ipoctal_get_icount(struct tty_struct *tty, - struct serial_icounter_struct *icount) -{ - struct ipoctal_channel *channel = tty->driver_data; - - icount->cts = 0; - icount->dsr = 0; - icount->rng = 0; - icount->dcd = 0; - icount->rx = channel->stats.rx; - icount->tx = channel->stats.tx; - icount->frame = channel->stats.framing_err; - icount->parity = channel->stats.parity_err; - icount->brk = channel->stats.rcv_break; - return 0; -} - -static void ipoctal_irq_rx(struct ipoctal_channel *channel, - struct tty_struct *tty, u8 sr) -{ - unsigned char value; - unsigned char flag = TTY_NORMAL; - u8 isr; - - do { - value = ioread8(&channel->regs->r.rhr); - /* Error: count statistics */ - if (sr & SR_ERROR) { - iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); - - if (sr & SR_OVERRUN_ERROR) { - channel->stats.overrun_err++; - /* Overrun doesn't affect the current character*/ - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } - if (sr & SR_PARITY_ERROR) { - channel->stats.parity_err++; - flag = TTY_PARITY; - } - if (sr & SR_FRAMING_ERROR) { - channel->stats.framing_err++; - flag = TTY_FRAME; - } - if (sr & SR_RECEIVED_BREAK) { - iowrite8(CR_CMD_RESET_BREAK_CHANGE, &channel->regs->w.cr); - channel->stats.rcv_break++; - flag = TTY_BREAK; - } - } - tty_insert_flip_char(tty, value, flag); - - /* Check if there are more characters in RX FIFO - * If there are more, the isr register for this channel - * has enabled the RxRDY|FFULL bit. - */ - isr = ioread8(&channel->block_regs->r.isr); - sr = ioread8(&channel->regs->r.sr); - } while (isr & channel->isr_rx_rdy_mask); - - tty_flip_buffer_push(tty); -} - -static void ipoctal_irq_tx(struct ipoctal_channel *channel) -{ - unsigned char value; - unsigned int *pointer_write = &channel->pointer_write; - - if (channel->nb_bytes <= 0) { - channel->nb_bytes = 0; - return; - } - - value = channel->tty_port.xmit_buf[*pointer_write]; - iowrite8(value, &channel->regs->w.thr); - channel->stats.tx++; - (*pointer_write)++; - *pointer_write = *pointer_write % PAGE_SIZE; - channel->nb_bytes--; - - if ((channel->nb_bytes == 0) && - (waitqueue_active(&channel->queue))) { - - if (channel->board_id != IPACK1_DEVICE_ID_SBS_OCTAL_485) { - *channel->board_write = 1; - wake_up_interruptible(&channel->queue); - } - } -} - -static void ipoctal_irq_channel(struct ipoctal_channel *channel) -{ - u8 isr, sr; - struct tty_struct *tty; - - /* If there is no client, skip the check */ - if (!atomic_read(&channel->open)) - return; - - tty = tty_port_tty_get(&channel->tty_port); - if (!tty) - return; - /* The HW is organized in pair of channels. See which register we need - * to read from */ - isr = ioread8(&channel->block_regs->r.isr); - sr = ioread8(&channel->regs->r.sr); - - /* In case of RS-485, change from TX to RX when finishing TX. - * Half-duplex. */ - if ((channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) && - (sr & SR_TX_EMPTY) && (channel->nb_bytes == 0)) { - iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); - iowrite8(CR_CMD_NEGATE_RTSN, &channel->regs->w.cr); - iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); - *channel->board_write = 1; - wake_up_interruptible(&channel->queue); - } - - /* RX data */ - if ((isr & channel->isr_rx_rdy_mask) && (sr & SR_RX_READY)) - ipoctal_irq_rx(channel, tty, sr); - - /* TX of each character */ - if ((isr & channel->isr_tx_rdy_mask) && (sr & SR_TX_READY)) - ipoctal_irq_tx(channel); - - tty_flip_buffer_push(tty); - tty_kref_put(tty); -} - -static irqreturn_t ipoctal_irq_handler(void *arg) -{ - unsigned int i; - struct ipoctal *ipoctal = (struct ipoctal *) arg; - - /* Check all channels */ - for (i = 0; i < NR_CHANNELS; i++) - ipoctal_irq_channel(&ipoctal->channel[i]); - - /* Clear the IPack device interrupt */ - readw(ipoctal->int_space + ACK_INT_REQ0); - readw(ipoctal->int_space + ACK_INT_REQ1); - - return IRQ_HANDLED; -} - -static const struct tty_port_operations ipoctal_tty_port_ops = { - .dtr_rts = NULL, - .activate = ipoctal_port_activate, -}; - -static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, - unsigned int slot) -{ - int res; - int i; - struct tty_driver *tty; - char name[20]; - struct ipoctal_channel *channel; - struct ipack_region *region; - void __iomem *addr; - union scc2698_channel __iomem *chan_regs; - union scc2698_block __iomem *block_regs; - - ipoctal->board_id = ipoctal->dev->id_device; - - region = &ipoctal->dev->region[IPACK_IO_SPACE]; - addr = devm_ioremap_nocache(&ipoctal->dev->dev, - region->start, region->size); - if (!addr) { - dev_err(&ipoctal->dev->dev, - "Unable to map slot [%d:%d] IO space!\n", - bus_nr, slot); - return -EADDRNOTAVAIL; - } - /* Save the virtual address to access the registers easily */ - chan_regs = - (union scc2698_channel __iomem *) addr; - block_regs = - (union scc2698_block __iomem *) addr; - - region = &ipoctal->dev->region[IPACK_INT_SPACE]; - ipoctal->int_space = - devm_ioremap_nocache(&ipoctal->dev->dev, - region->start, region->size); - if (!ipoctal->int_space) { - dev_err(&ipoctal->dev->dev, - "Unable to map slot [%d:%d] INT space!\n", - bus_nr, slot); - return -EADDRNOTAVAIL; - } - - region = &ipoctal->dev->region[IPACK_MEM8_SPACE]; - ipoctal->mem8_space = - devm_ioremap_nocache(&ipoctal->dev->dev, - region->start, 0x8000); - if (!addr) { - dev_err(&ipoctal->dev->dev, - "Unable to map slot [%d:%d] MEM8 space!\n", - bus_nr, slot); - return -EADDRNOTAVAIL; - } - - - /* Disable RX and TX before touching anything */ - for (i = 0; i < NR_CHANNELS ; i++) { - struct ipoctal_channel *channel = &ipoctal->channel[i]; - channel->regs = chan_regs + i; - channel->block_regs = block_regs + (i >> 1); - channel->board_write = &ipoctal->write; - channel->board_id = ipoctal->board_id; - if (i & 1) { - channel->isr_tx_rdy_mask = ISR_TxRDY_B; - channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_B; - } else { - channel->isr_tx_rdy_mask = ISR_TxRDY_A; - channel->isr_rx_rdy_mask = ISR_RxRDY_FFULL_A; - } - - iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); - iowrite8(MR1_CHRL_8_BITS | MR1_ERROR_CHAR | MR1_RxINT_RxRDY, - &channel->regs->w.mr); /* mr1 */ - iowrite8(0, &channel->regs->w.mr); /* mr2 */ - iowrite8(TX_CLK_9600 | RX_CLK_9600, &channel->regs->w.csr); - } - - for (i = 0; i < IP_OCTAL_NB_BLOCKS; i++) { - iowrite8(ACR_BRG_SET2, &block_regs[i].w.acr); - iowrite8(OPCR_MPP_OUTPUT | OPCR_MPOa_RTSN | OPCR_MPOb_RTSN, - &block_regs[i].w.opcr); - iowrite8(IMR_TxRDY_A | IMR_RxRDY_FFULL_A | IMR_DELTA_BREAK_A | - IMR_TxRDY_B | IMR_RxRDY_FFULL_B | IMR_DELTA_BREAK_B, - &block_regs[i].w.imr); - } - - /* - * IP-OCTAL has different addresses to copy its IRQ vector. - * Depending of the carrier these addresses are accesible or not. - * More info in the datasheet. - */ - ipoctal->dev->bus->ops->request_irq(ipoctal->dev, - ipoctal_irq_handler, ipoctal); - /* Dummy write */ - iowrite8(1, ipoctal->mem8_space + 1); - - /* Register the TTY device */ - - /* Each IP-OCTAL channel is a TTY port */ - tty = alloc_tty_driver(NR_CHANNELS); - - if (!tty) - return -ENOMEM; - - /* Fill struct tty_driver with ipoctal data */ - tty->owner = THIS_MODULE; - tty->driver_name = KBUILD_MODNAME; - sprintf(name, KBUILD_MODNAME ".%d.%d.", bus_nr, slot); - tty->name = name; - tty->major = 0; - - tty->minor_start = 0; - tty->type = TTY_DRIVER_TYPE_SERIAL; - tty->subtype = SERIAL_TYPE_NORMAL; - tty->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - tty->init_termios = tty_std_termios; - tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - tty->init_termios.c_ispeed = 9600; - tty->init_termios.c_ospeed = 9600; - - tty_set_operations(tty, &ipoctal_fops); - res = tty_register_driver(tty); - if (res) { - dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n"); - put_tty_driver(tty); - return res; - } - - /* Save struct tty_driver for use it when uninstalling the device */ - ipoctal->tty_drv = tty; - - for (i = 0; i < NR_CHANNELS; i++) { - struct device *tty_dev; - - channel = &ipoctal->channel[i]; - tty_port_init(&channel->tty_port); - tty_port_alloc_xmit_buf(&channel->tty_port); - channel->tty_port.ops = &ipoctal_tty_port_ops; - - ipoctal_reset_stats(&channel->stats); - channel->nb_bytes = 0; - init_waitqueue_head(&channel->queue); - - spin_lock_init(&channel->lock); - channel->pointer_read = 0; - channel->pointer_write = 0; - tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL); - if (IS_ERR(tty_dev)) { - dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); - continue; - } - dev_set_drvdata(tty_dev, channel); - - /* - * Enable again the RX. TX will be enabled when - * there is something to send - */ - iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); - } - - return 0; -} - -static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, - const unsigned char *buf, - int count) -{ - unsigned long flags; - int i; - unsigned int *pointer_read = &channel->pointer_read; - - /* Copy the bytes from the user buffer to the internal one */ - for (i = 0; i < count; i++) { - if (i <= (PAGE_SIZE - channel->nb_bytes)) { - spin_lock_irqsave(&channel->lock, flags); - channel->tty_port.xmit_buf[*pointer_read] = buf[i]; - *pointer_read = (*pointer_read + 1) % PAGE_SIZE; - channel->nb_bytes++; - spin_unlock_irqrestore(&channel->lock, flags); - } else { - break; - } - } - return i; -} - -static int ipoctal_write_tty(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - struct ipoctal_channel *channel = tty->driver_data; - unsigned int char_copied; - - char_copied = ipoctal_copy_write_buffer(channel, buf, count); - - /* As the IP-OCTAL 485 only supports half duplex, do it manually */ - if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) { - iowrite8(CR_DISABLE_RX, &channel->regs->w.cr); - iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr); - } - - /* - * Send a packet and then disable TX to avoid failure after several send - * operations - */ - iowrite8(CR_ENABLE_TX, &channel->regs->w.cr); - wait_event_interruptible(channel->queue, *channel->board_write); - iowrite8(CR_DISABLE_TX, &channel->regs->w.cr); - - *channel->board_write = 0; - return char_copied; -} - -static int ipoctal_write_room(struct tty_struct *tty) -{ - struct ipoctal_channel *channel = tty->driver_data; - - return PAGE_SIZE - channel->nb_bytes; -} - -static int ipoctal_chars_in_buffer(struct tty_struct *tty) -{ - struct ipoctal_channel *channel = tty->driver_data; - - return channel->nb_bytes; -} - -static void ipoctal_set_termios(struct tty_struct *tty, - struct ktermios *old_termios) -{ - unsigned int cflag; - unsigned char mr1 = 0; - unsigned char mr2 = 0; - unsigned char csr = 0; - struct ipoctal_channel *channel = tty->driver_data; - speed_t baud; - - cflag = tty->termios.c_cflag; - - /* Disable and reset everything before change the setup */ - iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr); - - /* Set Bits per chars */ - switch (cflag & CSIZE) { - case CS6: - mr1 |= MR1_CHRL_6_BITS; - break; - case CS7: - mr1 |= MR1_CHRL_7_BITS; - break; - case CS8: - default: - mr1 |= MR1_CHRL_8_BITS; - /* By default, select CS8 */ - tty->termios.c_cflag = (cflag & ~CSIZE) | CS8; - break; - } - - /* Set Parity */ - if (cflag & PARENB) - if (cflag & PARODD) - mr1 |= MR1_PARITY_ON | MR1_PARITY_ODD; - else - mr1 |= MR1_PARITY_ON | MR1_PARITY_EVEN; - else - mr1 |= MR1_PARITY_OFF; - - /* Mark or space parity is not supported */ - tty->termios.c_cflag &= ~CMSPAR; - - /* Set stop bits */ - if (cflag & CSTOPB) - mr2 |= MR2_STOP_BITS_LENGTH_2; - else - mr2 |= MR2_STOP_BITS_LENGTH_1; - - /* Set the flow control */ - switch (channel->board_id) { - case IPACK1_DEVICE_ID_SBS_OCTAL_232: - if (cflag & CRTSCTS) { - mr1 |= MR1_RxRTS_CONTROL_ON; - mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_ON; - } else { - mr1 |= MR1_RxRTS_CONTROL_OFF; - mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF; - } - break; - case IPACK1_DEVICE_ID_SBS_OCTAL_422: - mr1 |= MR1_RxRTS_CONTROL_OFF; - mr2 |= MR2_TxRTS_CONTROL_OFF | MR2_CTS_ENABLE_TX_OFF; - break; - case IPACK1_DEVICE_ID_SBS_OCTAL_485: - mr1 |= MR1_RxRTS_CONTROL_OFF; - mr2 |= MR2_TxRTS_CONTROL_ON | MR2_CTS_ENABLE_TX_OFF; - break; - default: - return; - break; - } - - baud = tty_get_baud_rate(tty); - tty_termios_encode_baud_rate(&tty->termios, baud, baud); - - /* Set baud rate */ - switch (baud) { - case 75: - csr |= TX_CLK_75 | RX_CLK_75; - break; - case 110: - csr |= TX_CLK_110 | RX_CLK_110; - break; - case 150: - csr |= TX_CLK_150 | RX_CLK_150; - break; - case 300: - csr |= TX_CLK_300 | RX_CLK_300; - break; - case 600: - csr |= TX_CLK_600 | RX_CLK_600; - break; - case 1200: - csr |= TX_CLK_1200 | RX_CLK_1200; - break; - case 1800: - csr |= TX_CLK_1800 | RX_CLK_1800; - break; - case 2000: - csr |= TX_CLK_2000 | RX_CLK_2000; - break; - case 2400: - csr |= TX_CLK_2400 | RX_CLK_2400; - break; - case 4800: - csr |= TX_CLK_4800 | RX_CLK_4800; - break; - case 9600: - csr |= TX_CLK_9600 | RX_CLK_9600; - break; - case 19200: - csr |= TX_CLK_19200 | RX_CLK_19200; - break; - case 38400: - default: - csr |= TX_CLK_38400 | RX_CLK_38400; - /* In case of default, we establish 38400 bps */ - tty_termios_encode_baud_rate(&tty->termios, 38400, 38400); - break; - } - - mr1 |= MR1_ERROR_CHAR; - mr1 |= MR1_RxINT_RxRDY; - - /* Write the control registers */ - iowrite8(mr1, &channel->regs->w.mr); - iowrite8(mr2, &channel->regs->w.mr); - iowrite8(csr, &channel->regs->w.csr); - - /* Enable again the RX */ - iowrite8(CR_ENABLE_RX, &channel->regs->w.cr); -} - -static void ipoctal_hangup(struct tty_struct *tty) -{ - unsigned long flags; - struct ipoctal_channel *channel = tty->driver_data; - - if (channel == NULL) - return; - - spin_lock_irqsave(&channel->lock, flags); - channel->nb_bytes = 0; - channel->pointer_read = 0; - channel->pointer_write = 0; - spin_unlock_irqrestore(&channel->lock, flags); - - tty_port_hangup(&channel->tty_port); - - iowrite8(CR_DISABLE_RX | CR_DISABLE_TX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_RX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_TX, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_ERR_STATUS, &channel->regs->w.cr); - iowrite8(CR_CMD_RESET_MR, &channel->regs->w.cr); - - clear_bit(ASYNCB_INITIALIZED, &channel->tty_port.flags); - wake_up_interruptible(&channel->tty_port.open_wait); -} - -static const struct tty_operations ipoctal_fops = { - .ioctl = NULL, - .open = ipoctal_open, - .close = ipoctal_close, - .write = ipoctal_write_tty, - .set_termios = ipoctal_set_termios, - .write_room = ipoctal_write_room, - .chars_in_buffer = ipoctal_chars_in_buffer, - .get_icount = ipoctal_get_icount, - .hangup = ipoctal_hangup, -}; - -static int ipoctal_probe(struct ipack_device *dev) -{ - int res; - struct ipoctal *ipoctal; - - ipoctal = kzalloc(sizeof(struct ipoctal), GFP_KERNEL); - if (ipoctal == NULL) - return -ENOMEM; - - ipoctal->dev = dev; - res = ipoctal_inst_slot(ipoctal, dev->bus->bus_nr, dev->slot); - if (res) - goto out_uninst; - - dev_set_drvdata(&dev->dev, ipoctal); - return 0; - -out_uninst: - kfree(ipoctal); - return res; -} - -static void __ipoctal_remove(struct ipoctal *ipoctal) -{ - int i; - - ipoctal->dev->bus->ops->free_irq(ipoctal->dev); - - for (i = 0; i < NR_CHANNELS; i++) { - struct ipoctal_channel *channel = &ipoctal->channel[i]; - tty_unregister_device(ipoctal->tty_drv, i); - tty_port_free_xmit_buf(&channel->tty_port); - } - - tty_unregister_driver(ipoctal->tty_drv); - put_tty_driver(ipoctal->tty_drv); - kfree(ipoctal); -} - -static void ipoctal_remove(struct ipack_device *idev) -{ - __ipoctal_remove(dev_get_drvdata(&idev->dev)); -} - -static DEFINE_IPACK_DEVICE_TABLE(ipoctal_ids) = { - { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS, - IPACK1_DEVICE_ID_SBS_OCTAL_232) }, - { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS, - IPACK1_DEVICE_ID_SBS_OCTAL_422) }, - { IPACK_DEVICE(IPACK_ID_VERSION_1, IPACK1_VENDOR_ID_SBS, - IPACK1_DEVICE_ID_SBS_OCTAL_485) }, - { 0, }, -}; - -MODULE_DEVICE_TABLE(ipack, ipoctal_ids); - -static const struct ipack_driver_ops ipoctal_drv_ops = { - .probe = ipoctal_probe, - .remove = ipoctal_remove, -}; - -static struct ipack_driver driver = { - .ops = &ipoctal_drv_ops, - .id_table = ipoctal_ids, -}; - -static int __init ipoctal_init(void) -{ - return ipack_driver_register(&driver, THIS_MODULE, KBUILD_MODNAME); -} - -static void __exit ipoctal_exit(void) -{ - ipack_driver_unregister(&driver); -} - -MODULE_DESCRIPTION("IP-Octal 232, 422 and 485 device driver"); -MODULE_LICENSE("GPL"); - -module_init(ipoctal_init); -module_exit(ipoctal_exit); diff --git a/drivers/staging/ipack/devices/ipoctal.h b/drivers/staging/ipack/devices/ipoctal.h deleted file mode 100644 index 28f1c423315..00000000000 --- a/drivers/staging/ipack/devices/ipoctal.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * ipoctal.h - * - * driver for the IPOCTAL boards - - * Copyright (C) 2009-2012 CERN (www.cern.ch) - * Author: Nicolas Serafini, EIC2 SA - * Author: Samuel Iglesias Gonsalvez - * - * 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; version 2 of the License. - */ - -#ifndef _IPOCTAL_H -#define _IPOCTAL_H_ - -#define NR_CHANNELS 8 -#define IPOCTAL_MAX_BOARDS 16 -#define MAX_DEVICES (NR_CHANNELS * IPOCTAL_MAX_BOARDS) -#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - -/** - * struct ipoctal_stats -- Stats since last reset - * - * @tx: Number of transmitted bytes - * @rx: Number of received bytes - * @overrun: Number of overrun errors - * @parity_err: Number of parity errors - * @framing_err: Number of framing errors - * @rcv_break: Number of break received - */ -struct ipoctal_stats { - unsigned long tx; - unsigned long rx; - unsigned long overrun_err; - unsigned long parity_err; - unsigned long framing_err; - unsigned long rcv_break; -}; - -#endif /* _IPOCTAL_H_ */ diff --git a/drivers/staging/ipack/devices/scc2698.h b/drivers/staging/ipack/devices/scc2698.h deleted file mode 100644 index 2ad6acd513f..00000000000 --- a/drivers/staging/ipack/devices/scc2698.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * scc2698.h - * - * driver for the IPOCTAL boards - * - * Copyright (C) 2009-2012 CERN (www.cern.ch) - * Author: Nicolas Serafini, EIC2 SA - * Author: Samuel Iglesias Gonsalvez - * - * 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; version 2 of the License. - */ - -#ifndef SCC2698_H_ -#define SCC2698_H_ - -/* - * union scc2698_channel - Channel access to scc2698 IO - * - * dn value are only spacer. - * - */ -union scc2698_channel { - struct { - u8 d0, mr; /* Mode register 1/2*/ - u8 d1, sr; /* Status register */ - u8 d2, r1; /* reserved */ - u8 d3, rhr; /* Receive holding register (R) */ - u8 junk[8]; /* other crap for block control */ - } __packed r; /* Read access */ - struct { - u8 d0, mr; /* Mode register 1/2 */ - u8 d1, csr; /* Clock select register */ - u8 d2, cr; /* Command register */ - u8 d3, thr; /* Transmit holding register */ - u8 junk[8]; /* other crap for block control */ - } __packed w; /* Write access */ -}; - -/* - * union scc2698_block - Block access to scc2698 IO - * - * The scc2698 contain 4 block. - * Each block containt two channel a and b. - * dn value are only spacer. - * - */ -union scc2698_block { - struct { - u8 d0, mra; /* Mode register 1/2 (a) */ - u8 d1, sra; /* Status register (a) */ - u8 d2, r1; /* reserved */ - u8 d3, rhra; /* Receive holding register (a) */ - u8 d4, ipcr; /* Input port change register of block */ - u8 d5, isr; /* Interrupt status register of block */ - u8 d6, ctur; /* Counter timer upper register of block */ - u8 d7, ctlr; /* Counter timer lower register of block */ - u8 d8, mrb; /* Mode register 1/2 (b) */ - u8 d9, srb; /* Status register (b) */ - u8 da, r2; /* reserved */ - u8 db, rhrb; /* Receive holding register (b) */ - u8 dc, r3; /* reserved */ - u8 dd, ip; /* Input port register of block */ - u8 de, ctg; /* Start counter timer of block */ - u8 df, cts; /* Stop counter timer of block */ - } __packed r; /* Read access */ - struct { - u8 d0, mra; /* Mode register 1/2 (a) */ - u8 d1, csra; /* Clock select register (a) */ - u8 d2, cra; /* Command register (a) */ - u8 d3, thra; /* Transmit holding register (a) */ - u8 d4, acr; /* Auxiliary control register of block */ - u8 d5, imr; /* Interrupt mask register of block */ - u8 d6, ctu; /* Counter timer upper register of block */ - u8 d7, ctl; /* Counter timer lower register of block */ - u8 d8, mrb; /* Mode register 1/2 (b) */ - u8 d9, csrb; /* Clock select register (a) */ - u8 da, crb; /* Command register (b) */ - u8 db, thrb; /* Transmit holding register (b) */ - u8 dc, r1; /* reserved */ - u8 dd, opcr; /* Output port configuration register of block */ - u8 de, r2; /* reserved */ - u8 df, r3; /* reserved */ - } __packed w; /* Write access */ -}; - -#define MR1_CHRL_5_BITS (0x0 << 0) -#define MR1_CHRL_6_BITS (0x1 << 0) -#define MR1_CHRL_7_BITS (0x2 << 0) -#define MR1_CHRL_8_BITS (0x3 << 0) -#define MR1_PARITY_EVEN (0x1 << 2) -#define MR1_PARITY_ODD (0x0 << 2) -#define MR1_PARITY_ON (0x0 << 3) -#define MR1_PARITY_FORCE (0x1 << 3) -#define MR1_PARITY_OFF (0x2 << 3) -#define MR1_PARITY_SPECIAL (0x3 << 3) -#define MR1_ERROR_CHAR (0x0 << 5) -#define MR1_ERROR_BLOCK (0x1 << 5) -#define MR1_RxINT_RxRDY (0x0 << 6) -#define MR1_RxINT_FFULL (0x1 << 6) -#define MR1_RxRTS_CONTROL_ON (0x1 << 7) -#define MR1_RxRTS_CONTROL_OFF (0x0 << 7) - -#define MR2_STOP_BITS_LENGTH_1 (0x7 << 0) -#define MR2_STOP_BITS_LENGTH_2 (0xF << 0) -#define MR2_CTS_ENABLE_TX_ON (0x1 << 4) -#define MR2_CTS_ENABLE_TX_OFF (0x0 << 4) -#define MR2_TxRTS_CONTROL_ON (0x1 << 5) -#define MR2_TxRTS_CONTROL_OFF (0x0 << 5) -#define MR2_CH_MODE_NORMAL (0x0 << 6) -#define MR2_CH_MODE_ECHO (0x1 << 6) -#define MR2_CH_MODE_LOCAL (0x2 << 6) -#define MR2_CH_MODE_REMOTE (0x3 << 6) - -#define CR_ENABLE_RX (0x1 << 0) -#define CR_DISABLE_RX (0x1 << 1) -#define CR_ENABLE_TX (0x1 << 2) -#define CR_DISABLE_TX (0x1 << 3) -#define CR_CMD_RESET_MR (0x1 << 4) -#define CR_CMD_RESET_RX (0x2 << 4) -#define CR_CMD_RESET_TX (0x3 << 4) -#define CR_CMD_RESET_ERR_STATUS (0x4 << 4) -#define CR_CMD_RESET_BREAK_CHANGE (0x5 << 4) -#define CR_CMD_START_BREAK (0x6 << 4) -#define CR_CMD_STOP_BREAK (0x7 << 4) -#define CR_CMD_ASSERT_RTSN (0x8 << 4) -#define CR_CMD_NEGATE_RTSN (0x9 << 4) -#define CR_CMD_SET_TIMEOUT_MODE (0xA << 4) -#define CR_CMD_DISABLE_TIMEOUT_MODE (0xC << 4) - -#define SR_RX_READY (0x1 << 0) -#define SR_FIFO_FULL (0x1 << 1) -#define SR_TX_READY (0x1 << 2) -#define SR_TX_EMPTY (0x1 << 3) -#define SR_OVERRUN_ERROR (0x1 << 4) -#define SR_PARITY_ERROR (0x1 << 5) -#define SR_FRAMING_ERROR (0x1 << 6) -#define SR_RECEIVED_BREAK (0x1 << 7) - -#define SR_ERROR (0xF0) - -#define ACR_DELTA_IP0_IRQ_EN (0x1 << 0) -#define ACR_DELTA_IP1_IRQ_EN (0x1 << 1) -#define ACR_DELTA_IP2_IRQ_EN (0x1 << 2) -#define ACR_DELTA_IP3_IRQ_EN (0x1 << 3) -#define ACR_CT_Mask (0x7 << 4) -#define ACR_CExt (0x0 << 4) -#define ACR_CTxCA (0x1 << 4) -#define ACR_CTxCB (0x2 << 4) -#define ACR_CClk16 (0x3 << 4) -#define ACR_TExt (0x4 << 4) -#define ACR_TExt16 (0x5 << 4) -#define ACR_TClk (0x6 << 4) -#define ACR_TClk16 (0x7 << 4) -#define ACR_BRG_SET1 (0x0 << 7) -#define ACR_BRG_SET2 (0x1 << 7) - -#define TX_CLK_75 (0x0 << 0) -#define TX_CLK_110 (0x1 << 0) -#define TX_CLK_38400 (0x2 << 0) -#define TX_CLK_150 (0x3 << 0) -#define TX_CLK_300 (0x4 << 0) -#define TX_CLK_600 (0x5 << 0) -#define TX_CLK_1200 (0x6 << 0) -#define TX_CLK_2000 (0x7 << 0) -#define TX_CLK_2400 (0x8 << 0) -#define TX_CLK_4800 (0x9 << 0) -#define TX_CLK_1800 (0xA << 0) -#define TX_CLK_9600 (0xB << 0) -#define TX_CLK_19200 (0xC << 0) -#define RX_CLK_75 (0x0 << 4) -#define RX_CLK_110 (0x1 << 4) -#define RX_CLK_38400 (0x2 << 4) -#define RX_CLK_150 (0x3 << 4) -#define RX_CLK_300 (0x4 << 4) -#define RX_CLK_600 (0x5 << 4) -#define RX_CLK_1200 (0x6 << 4) -#define RX_CLK_2000 (0x7 << 4) -#define RX_CLK_2400 (0x8 << 4) -#define RX_CLK_4800 (0x9 << 4) -#define RX_CLK_1800 (0xA << 4) -#define RX_CLK_9600 (0xB << 4) -#define RX_CLK_19200 (0xC << 4) - -#define OPCR_MPOa_RTSN (0x0 << 0) -#define OPCR_MPOa_C_TO (0x1 << 0) -#define OPCR_MPOa_TxC1X (0x2 << 0) -#define OPCR_MPOa_TxC16X (0x3 << 0) -#define OPCR_MPOa_RxC1X (0x4 << 0) -#define OPCR_MPOa_RxC16X (0x5 << 0) -#define OPCR_MPOa_TxRDY (0x6 << 0) -#define OPCR_MPOa_RxRDY_FF (0x7 << 0) - -#define OPCR_MPOb_RTSN (0x0 << 4) -#define OPCR_MPOb_C_TO (0x1 << 4) -#define OPCR_MPOb_TxC1X (0x2 << 4) -#define OPCR_MPOb_TxC16X (0x3 << 4) -#define OPCR_MPOb_RxC1X (0x4 << 4) -#define OPCR_MPOb_RxC16X (0x5 << 4) -#define OPCR_MPOb_TxRDY (0x6 << 4) -#define OPCR_MPOb_RxRDY_FF (0x7 << 4) - -#define OPCR_MPP_INPUT (0x0 << 7) -#define OPCR_MPP_OUTPUT (0x1 << 7) - -#define IMR_TxRDY_A (0x1 << 0) -#define IMR_RxRDY_FFULL_A (0x1 << 1) -#define IMR_DELTA_BREAK_A (0x1 << 2) -#define IMR_COUNTER_READY (0x1 << 3) -#define IMR_TxRDY_B (0x1 << 4) -#define IMR_RxRDY_FFULL_B (0x1 << 5) -#define IMR_DELTA_BREAK_B (0x1 << 6) -#define IMR_INPUT_PORT_CHANGE (0x1 << 7) - -#define ISR_TxRDY_A (0x1 << 0) -#define ISR_RxRDY_FFULL_A (0x1 << 1) -#define ISR_DELTA_BREAK_A (0x1 << 2) -#define ISR_COUNTER_READY (0x1 << 3) -#define ISR_TxRDY_B (0x1 << 4) -#define ISR_RxRDY_FFULL_B (0x1 << 5) -#define ISR_DELTA_BREAK_B (0x1 << 6) -#define ISR_INPUT_PORT_CHANGE (0x1 << 7) - -#define ACK_INT_REQ0 0 -#define ACK_INT_REQ1 2 - -#endif /* SCC2698_H_ */ diff --git a/drivers/staging/ipack/ipack.c b/drivers/staging/ipack/ipack.c deleted file mode 100644 index 6d5079de52b..00000000000 --- a/drivers/staging/ipack/ipack.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - * Industry-pack bus support functions. - * - * Copyright (C) 2011-2012 CERN (www.cern.ch) - * Author: Samuel Iglesias Gonsalvez - * - * 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; version 2 of the License. - */ - -#include -#include -#include -#include -#include "ipack.h" - -#define to_ipack_dev(device) container_of(device, struct ipack_device, dev) -#define to_ipack_driver(drv) container_of(drv, struct ipack_driver, driver) - -static DEFINE_IDA(ipack_ida); - -static void ipack_device_release(struct device *dev) -{ - struct ipack_device *device = to_ipack_dev(dev); - kfree(device->id); - device->release(device); -} - -static inline const struct ipack_device_id * -ipack_match_one_device(const struct ipack_device_id *id, - const struct ipack_device *device) -{ - if ((id->format == IPACK_ANY_FORMAT || - id->format == device->id_format) && - (id->vendor == IPACK_ANY_ID || id->vendor == device->id_vendor) && - (id->device == IPACK_ANY_ID || id->device == device->id_device)) - return id; - return NULL; -} - -static const struct ipack_device_id * -ipack_match_id(const struct ipack_device_id *ids, struct ipack_device *idev) -{ - if (ids) { - while (ids->vendor || ids->device) { - if (ipack_match_one_device(ids, idev)) - return ids; - ids++; - } - } - return NULL; -} - -static int ipack_bus_match(struct device *dev, struct device_driver *drv) -{ - struct ipack_device *idev = to_ipack_dev(dev); - struct ipack_driver *idrv = to_ipack_driver(drv); - const struct ipack_device_id *found_id; - - found_id = ipack_match_id(idrv->id_table, idev); - return found_id ? 1 : 0; -} - -static int ipack_bus_probe(struct device *device) -{ - struct ipack_device *dev = to_ipack_dev(device); - struct ipack_driver *drv = to_ipack_driver(device->driver); - - if (!drv->ops->probe) - return -EINVAL; - - return drv->ops->probe(dev); -} - -static int ipack_bus_remove(struct device *device) -{ - struct ipack_device *dev = to_ipack_dev(device); - struct ipack_driver *drv = to_ipack_driver(device->driver); - - if (!drv->ops->remove) - return -EINVAL; - - drv->ops->remove(dev); - return 0; -} - -static int ipack_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct ipack_device *idev; - - if (!dev) - return -ENODEV; - - idev = to_ipack_dev(dev); - - if (add_uevent_var(env, - "MODALIAS=ipack:f%02Xv%08Xd%08X", idev->id_format, - idev->id_vendor, idev->id_device)) - return -ENOMEM; - - return 0; -} - -#define ipack_device_attr(field, format_string) \ -static ssize_t \ -field##_show(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct ipack_device *idev = to_ipack_dev(dev); \ - return sprintf(buf, format_string, idev->field); \ -} - -static ssize_t id_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned int i, c, l, s; - struct ipack_device *idev = to_ipack_dev(dev); - - - switch (idev->id_format) { - case IPACK_ID_VERSION_1: - l = 0x7; s = 1; break; - case IPACK_ID_VERSION_2: - l = 0xf; s = 2; break; - default: - return -EIO; - } - c = 0; - for (i = 0; i < idev->id_avail; i++) { - if (i > 0) { - if ((i & l) == 0) - buf[c++] = '\n'; - else if ((i & s) == 0) - buf[c++] = ' '; - } - sprintf(&buf[c], "%02x", idev->id[i]); - c += 2; - } - buf[c++] = '\n'; - return c; -} - -static ssize_t -id_vendor_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct ipack_device *idev = to_ipack_dev(dev); - switch (idev->id_format) { - case IPACK_ID_VERSION_1: - return sprintf(buf, "0x%02x\n", idev->id_vendor); - case IPACK_ID_VERSION_2: - return sprintf(buf, "0x%06x\n", idev->id_vendor); - default: - return -EIO; - } -} - -static ssize_t -id_device_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct ipack_device *idev = to_ipack_dev(dev); - switch (idev->id_format) { - case IPACK_ID_VERSION_1: - return sprintf(buf, "0x%02x\n", idev->id_device); - case IPACK_ID_VERSION_2: - return sprintf(buf, "0x%04x\n", idev->id_device); - default: - return -EIO; - } -} - -static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct ipack_device *idev = to_ipack_dev(dev); - - return sprintf(buf, "ipac:f%02Xv%08Xd%08X", idev->id_format, - idev->id_vendor, idev->id_device); -} - -ipack_device_attr(id_format, "0x%hhu\n"); - -static struct device_attribute ipack_dev_attrs[] = { - __ATTR_RO(id), - __ATTR_RO(id_device), - __ATTR_RO(id_format), - __ATTR_RO(id_vendor), - __ATTR_RO(modalias), -}; - -static struct bus_type ipack_bus_type = { - .name = "ipack", - .probe = ipack_bus_probe, - .match = ipack_bus_match, - .remove = ipack_bus_remove, - .dev_attrs = ipack_dev_attrs, - .uevent = ipack_uevent, -}; - -struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, - const struct ipack_bus_ops *ops) -{ - int bus_nr; - struct ipack_bus_device *bus; - - bus = kzalloc(sizeof(struct ipack_bus_device), GFP_KERNEL); - if (!bus) - return NULL; - - bus_nr = ida_simple_get(&ipack_ida, 0, 0, GFP_KERNEL); - if (bus_nr < 0) { - kfree(bus); - return NULL; - } - - bus->bus_nr = bus_nr; - bus->parent = parent; - bus->slots = slots; - bus->ops = ops; - return bus; -} -EXPORT_SYMBOL_GPL(ipack_bus_register); - -static int ipack_unregister_bus_member(struct device *dev, void *data) -{ - struct ipack_device *idev = to_ipack_dev(dev); - struct ipack_bus_device *bus = data; - - if (idev->bus == bus) - ipack_device_unregister(idev); - - return 1; -} - -int ipack_bus_unregister(struct ipack_bus_device *bus) -{ - bus_for_each_dev(&ipack_bus_type, NULL, bus, - ipack_unregister_bus_member); - ida_simple_remove(&ipack_ida, bus->bus_nr); - kfree(bus); - return 0; -} -EXPORT_SYMBOL_GPL(ipack_bus_unregister); - -int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, - const char *name) -{ - edrv->driver.owner = owner; - edrv->driver.name = name; - edrv->driver.bus = &ipack_bus_type; - return driver_register(&edrv->driver); -} -EXPORT_SYMBOL_GPL(ipack_driver_register); - -void ipack_driver_unregister(struct ipack_driver *edrv) -{ - driver_unregister(&edrv->driver); -} -EXPORT_SYMBOL_GPL(ipack_driver_unregister); - -static u16 ipack_crc_byte(u16 crc, u8 c) -{ - int i; - - crc ^= c << 8; - for (i = 0; i < 8; i++) - crc = (crc << 1) ^ ((crc & 0x8000) ? 0x1021 : 0); - return crc; -} - -/* - * The algorithm in lib/crc-ccitt.c does not seem to apply since it uses the - * opposite bit ordering. - */ -static u8 ipack_calc_crc1(struct ipack_device *dev) -{ - u8 c; - u16 crc; - unsigned int i; - - crc = 0xffff; - for (i = 0; i < dev->id_avail; i++) { - c = (i != 11) ? dev->id[i] : 0; - crc = ipack_crc_byte(crc, c); - } - crc = ~crc; - return crc & 0xff; -} - -static u16 ipack_calc_crc2(struct ipack_device *dev) -{ - u8 c; - u16 crc; - unsigned int i; - - crc = 0xffff; - for (i = 0; i < dev->id_avail; i++) { - c = ((i != 0x18) && (i != 0x19)) ? dev->id[i] : 0; - crc = ipack_crc_byte(crc, c); - } - crc = ~crc; - return crc; -} - -static void ipack_parse_id1(struct ipack_device *dev) -{ - u8 *id = dev->id; - u8 crc; - - dev->id_vendor = id[4]; - dev->id_device = id[5]; - dev->speed_8mhz = 1; - dev->speed_32mhz = (id[7] == 'H'); - crc = ipack_calc_crc1(dev); - dev->id_crc_correct = (crc == id[11]); - if (!dev->id_crc_correct) { - dev_warn(&dev->dev, "ID CRC invalid found 0x%x, expected 0x%x.\n", - id[11], crc); - } -} - -static void ipack_parse_id2(struct ipack_device *dev) -{ - __be16 *id = (__be16 *) dev->id; - u16 flags, crc; - - dev->id_vendor = ((be16_to_cpu(id[3]) & 0xff) << 16) - + be16_to_cpu(id[4]); - dev->id_device = be16_to_cpu(id[5]); - flags = be16_to_cpu(id[10]); - dev->speed_8mhz = !!(flags & 2); - dev->speed_32mhz = !!(flags & 4); - crc = ipack_calc_crc2(dev); - dev->id_crc_correct = (crc == be16_to_cpu(id[12])); - if (!dev->id_crc_correct) { - dev_warn(&dev->dev, "ID CRC invalid found 0x%x, expected 0x%x.\n", - id[11], crc); - } -} - -static int ipack_device_read_id(struct ipack_device *dev) -{ - u8 __iomem *idmem; - int i; - int ret = 0; - - idmem = ioremap(dev->region[IPACK_ID_SPACE].start, - dev->region[IPACK_ID_SPACE].size); - if (!idmem) { - dev_err(&dev->dev, "error mapping memory\n"); - return -ENOMEM; - } - - /* Determine ID PROM Data Format. If we find the ids "IPAC" or "IPAH" - * we are dealing with a IndustryPack format 1 device. If we detect - * "VITA4 " (16 bit big endian formatted) we are dealing with a - * IndustryPack format 2 device */ - if ((ioread8(idmem + 1) == 'I') && - (ioread8(idmem + 3) == 'P') && - (ioread8(idmem + 5) == 'A') && - ((ioread8(idmem + 7) == 'C') || - (ioread8(idmem + 7) == 'H'))) { - dev->id_format = IPACK_ID_VERSION_1; - dev->id_avail = ioread8(idmem + 0x15); - if ((dev->id_avail < 0x0c) || (dev->id_avail > 0x40)) { - dev_warn(&dev->dev, "invalid id size"); - dev->id_avail = 0x0c; - } - } else if ((ioread8(idmem + 0) == 'I') && - (ioread8(idmem + 1) == 'V') && - (ioread8(idmem + 2) == 'A') && - (ioread8(idmem + 3) == 'T') && - (ioread8(idmem + 4) == ' ') && - (ioread8(idmem + 5) == '4')) { - dev->id_format = IPACK_ID_VERSION_2; - dev->id_avail = ioread16be(idmem + 0x16); - if ((dev->id_avail < 0x1a) || (dev->id_avail > 0x40)) { - dev_warn(&dev->dev, "invalid id size"); - dev->id_avail = 0x1a; - } - } else { - dev->id_format = IPACK_ID_VERSION_INVALID; - dev->id_avail = 0; - } - - if (!dev->id_avail) { - ret = -ENODEV; - goto out; - } - - /* Obtain the amount of memory required to store a copy of the complete - * ID ROM contents */ - dev->id = kmalloc(dev->id_avail, GFP_KERNEL); - if (!dev->id) { - dev_err(&dev->dev, "dev->id alloc failed.\n"); - ret = -ENOMEM; - goto out; - } - for (i = 0; i < dev->id_avail; i++) { - if (dev->id_format == IPACK_ID_VERSION_1) - dev->id[i] = ioread8(idmem + (i << 1) + 1); - else - dev->id[i] = ioread8(idmem + i); - } - - /* now we can finally work with the copy */ - switch (dev->id_format) { - case IPACK_ID_VERSION_1: - ipack_parse_id1(dev); - break; - case IPACK_ID_VERSION_2: - ipack_parse_id2(dev); - break; - } - -out: - iounmap(idmem); - - return ret; -} - -int ipack_device_register(struct ipack_device *dev) -{ - int ret; - - dev->dev.bus = &ipack_bus_type; - dev->dev.release = ipack_device_release; - dev->dev.parent = dev->bus->parent; - dev_set_name(&dev->dev, - "ipack-dev.%u.%u", dev->bus->bus_nr, dev->slot); - - if (dev->bus->ops->set_clockrate(dev, 8)) - dev_warn(&dev->dev, "failed to switch to 8 MHz operation for reading of device ID.\n"); - if (dev->bus->ops->reset_timeout(dev)) - dev_warn(&dev->dev, "failed to reset potential timeout."); - - ret = ipack_device_read_id(dev); - if (ret < 0) { - dev_err(&dev->dev, "error reading device id section.\n"); - return ret; - } - - /* if the device supports 32 MHz operation, use it. */ - if (dev->speed_32mhz) { - ret = dev->bus->ops->set_clockrate(dev, 32); - if (ret < 0) - dev_err(&dev->dev, "failed to switch to 32 MHz operation.\n"); - } - - ret = device_register(&dev->dev); - if (ret < 0) - kfree(dev->id); - - return ret; -} -EXPORT_SYMBOL_GPL(ipack_device_register); - -void ipack_device_unregister(struct ipack_device *dev) -{ - device_unregister(&dev->dev); -} -EXPORT_SYMBOL_GPL(ipack_device_unregister); - -static int __init ipack_init(void) -{ - ida_init(&ipack_ida); - return bus_register(&ipack_bus_type); -} - -static void __exit ipack_exit(void) -{ - bus_unregister(&ipack_bus_type); - ida_destroy(&ipack_ida); -} - -module_init(ipack_init); -module_exit(ipack_exit); - -MODULE_AUTHOR("Samuel Iglesias Gonsalvez "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Industry-pack bus core"); diff --git a/drivers/staging/ipack/ipack.h b/drivers/staging/ipack/ipack.h deleted file mode 100644 index 6760bfaf0ac..00000000000 --- a/drivers/staging/ipack/ipack.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Industry-pack bus. - * - * Copyright (C) 2011-2012 CERN (www.cern.ch) - * Author: Samuel Iglesias Gonsalvez - * - * 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; version 2 of the License. - */ - -#include -#include -#include - -#include "ipack_ids.h" - -#define IPACK_IDPROM_OFFSET_I 0x01 -#define IPACK_IDPROM_OFFSET_P 0x03 -#define IPACK_IDPROM_OFFSET_A 0x05 -#define IPACK_IDPROM_OFFSET_C 0x07 -#define IPACK_IDPROM_OFFSET_MANUFACTURER_ID 0x09 -#define IPACK_IDPROM_OFFSET_MODEL 0x0B -#define IPACK_IDPROM_OFFSET_REVISION 0x0D -#define IPACK_IDPROM_OFFSET_RESERVED 0x0F -#define IPACK_IDPROM_OFFSET_DRIVER_ID_L 0x11 -#define IPACK_IDPROM_OFFSET_DRIVER_ID_H 0x13 -#define IPACK_IDPROM_OFFSET_NUM_BYTES 0x15 -#define IPACK_IDPROM_OFFSET_CRC 0x17 - -struct ipack_bus_ops; -struct ipack_driver; - -enum ipack_space { - IPACK_IO_SPACE = 0, - IPACK_ID_SPACE, - IPACK_INT_SPACE, - IPACK_MEM8_SPACE, - IPACK_MEM16_SPACE, - /* Dummy for counting the number of entries. Must remain the last - * entry */ - IPACK_SPACE_COUNT, -}; - -/** - */ -struct ipack_region { - phys_addr_t start; - size_t size; -}; - -/** - * struct ipack_device - * - * @slot: Slot where the device is plugged in the carrier board - * @bus: ipack_bus_device where the device is plugged to. - * @id_space: Virtual address to ID space. - * @io_space: Virtual address to IO space. - * @mem_space: Virtual address to MEM space. - * @dev: device in kernel representation. - * - * Warning: Direct access to mapped memory is possible but the endianness - * is not the same with PCI carrier or VME carrier. The endianness is managed - * by the carrier board throught bus->ops. - */ -struct ipack_device { - unsigned int slot; - struct ipack_bus_device *bus; - struct device dev; - void (*release) (struct ipack_device *dev); - struct ipack_region region[IPACK_SPACE_COUNT]; - u8 *id; - size_t id_avail; - u32 id_vendor; - u32 id_device; - u8 id_format; - unsigned int id_crc_correct:1; - unsigned int speed_8mhz:1; - unsigned int speed_32mhz:1; -}; - -/** - * struct ipack_driver_ops -- Callbacks to IPack device driver - * - * @probe: Probe function - * @remove: Prepare imminent removal of the device. Services provided by the - * device should be revoked. - */ - -struct ipack_driver_ops { - int (*probe) (struct ipack_device *dev); - void (*remove) (struct ipack_device *dev); -}; - -/** - * struct ipack_driver -- Specific data to each ipack device driver - * - * @driver: Device driver kernel representation - * @ops: Callbacks provided by the IPack device driver - */ -struct ipack_driver { - struct device_driver driver; - const struct ipack_device_id *id_table; - const struct ipack_driver_ops *ops; -}; - -/** - * struct ipack_bus_ops - available operations on a bridge module - * - * @map_space: map IP address space - * @unmap_space: unmap IP address space - * @request_irq: request IRQ - * @free_irq: free IRQ - * @get_clockrate: Returns the clockrate the carrier is currently - * communicating with the device at. - * @set_clockrate: Sets the clock-rate for carrier / module communication. - * Should return -EINVAL if the requested speed is not supported. - * @get_error: Returns the error state for the slot the device is attached - * to. - * @get_timeout: Returns 1 if the communication with the device has - * previously timed out. - * @reset_timeout: Resets the state returned by get_timeout. - */ -struct ipack_bus_ops { - int (*request_irq) (struct ipack_device *dev, - irqreturn_t (*handler)(void *), void *arg); - int (*free_irq) (struct ipack_device *dev); - int (*get_clockrate) (struct ipack_device *dev); - int (*set_clockrate) (struct ipack_device *dev, int mherz); - int (*get_error) (struct ipack_device *dev); - int (*get_timeout) (struct ipack_device *dev); - int (*reset_timeout) (struct ipack_device *dev); -}; - -/** - * struct ipack_bus_device - * - * @dev: pointer to carrier device - * @slots: number of slots available - * @bus_nr: ipack bus number - * @ops: bus operations for the mezzanine drivers - */ -struct ipack_bus_device { - struct device *parent; - int slots; - int bus_nr; - const struct ipack_bus_ops *ops; -}; - -/** - * ipack_bus_register -- register a new ipack bus - * - * @parent: pointer to the parent device, if any. - * @slots: number of slots available in the bus device. - * @ops: bus operations for the mezzanine drivers. - * - * The carrier board device should call this function to register itself as - * available bus device in ipack. - */ -struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, - const struct ipack_bus_ops *ops); - -/** - * ipack_bus_unregister -- unregister an ipack bus - */ -int ipack_bus_unregister(struct ipack_bus_device *bus); - -/** - * ipack_driver_register -- Register a new ipack device driver - * - * Called by a ipack driver to register itself as a driver - * that can manage ipack devices. - */ -int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, - const char *name); -void ipack_driver_unregister(struct ipack_driver *edrv); - -/** - * ipack_device_register -- register an IPack device with the kernel - * @dev: the new device to register. - * - * Register a new IPack device ("module" in IndustryPack jargon). The call - * is done by the carrier driver. The carrier should populate the fields - * bus and slot as well as the region array of @dev prior to calling this - * function. The rest of the fields will be allocated and populated - * during registration. - * - * Return zero on success or error code on failure. - */ -int ipack_device_register(struct ipack_device *dev); -void ipack_device_unregister(struct ipack_device *dev); - -/** - * DEFINE_IPACK_DEVICE_TABLE - macro used to describe a IndustryPack table - * @_table: device table name - * - * This macro is used to create a struct ipack_device_id array (a device table) - * in a generic manner. - */ -#define DEFINE_IPACK_DEVICE_TABLE(_table) \ - const struct ipack_device_id _table[] __devinitconst - -/** - * IPACK_DEVICE - macro used to describe a specific IndustryPack device - * @_format: the format version (currently either 1 or 2, 8 bit value) - * @vend: the 8 or 24 bit IndustryPack Vendor ID - * @dev: the 8 or 16 bit IndustryPack Device ID - * - * This macro is used to create a struct ipack_device_id that matches a specific - * device. - */ -#define IPACK_DEVICE(_format, vend, dev) \ - .format = (_format), \ - .vendor = (vend), \ - .device = (dev) diff --git a/drivers/staging/ipack/ipack_ids.h b/drivers/staging/ipack/ipack_ids.h deleted file mode 100644 index 8153fee3f2f..00000000000 --- a/drivers/staging/ipack/ipack_ids.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * IndustryPack Fromat, Vendor and Device IDs. - */ - -/* ID section format versions */ -#define IPACK_ID_VERSION_INVALID 0x00 -#define IPACK_ID_VERSION_1 0x01 -#define IPACK_ID_VERSION_2 0x02 - -/* Vendors and devices. Sort key: vendor first, device next. */ -#define IPACK1_VENDOR_ID_RESERVED1 0x00 -#define IPACK1_VENDOR_ID_RESERVED2 0xFF -#define IPACK1_VENDOR_ID_UNREGISTRED01 0x01 -#define IPACK1_VENDOR_ID_UNREGISTRED02 0x02 -#define IPACK1_VENDOR_ID_UNREGISTRED03 0x03 -#define IPACK1_VENDOR_ID_UNREGISTRED04 0x04 -#define IPACK1_VENDOR_ID_UNREGISTRED05 0x05 -#define IPACK1_VENDOR_ID_UNREGISTRED06 0x06 -#define IPACK1_VENDOR_ID_UNREGISTRED07 0x07 -#define IPACK1_VENDOR_ID_UNREGISTRED08 0x08 -#define IPACK1_VENDOR_ID_UNREGISTRED09 0x09 -#define IPACK1_VENDOR_ID_UNREGISTRED10 0x0A -#define IPACK1_VENDOR_ID_UNREGISTRED11 0x0B -#define IPACK1_VENDOR_ID_UNREGISTRED12 0x0C -#define IPACK1_VENDOR_ID_UNREGISTRED13 0x0D -#define IPACK1_VENDOR_ID_UNREGISTRED14 0x0E -#define IPACK1_VENDOR_ID_UNREGISTRED15 0x0F - -#define IPACK1_VENDOR_ID_SBS 0xF0 -#define IPACK1_DEVICE_ID_SBS_OCTAL_232 0x22 -#define IPACK1_DEVICE_ID_SBS_OCTAL_422 0x2A -#define IPACK1_DEVICE_ID_SBS_OCTAL_485 0x48 -- cgit v1.2.3 From 14dc124f1b2feebe1883bb8b51545d26eaca99b7 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 16 Nov 2012 16:19:59 +0100 Subject: MAINTAINERS: Add maintainers for Industry Pack subsystem Add Samuel Iglesias Gonsalvez, Jens Taprogge and Greg Kroah-Hartman as maintainers for the Industry Pack subsystem. Cc: Jens Taprogge Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 59203e77ce9..b76fa082bee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3740,6 +3740,15 @@ M: Stanislaw Gruszka S: Maintained F: drivers/usb/atm/ueagle-atm.c +INDUSTRY PACK SUBSYSTEM (IPACK) +M: Samuel Iglesias Gonsalvez +M: Jens Taprogge +M: Greg Kroah-Hartman +L: industrypack-devel@lists.sourceforge.net +W: http://industrypack.sourceforge.net +S: Maintained +F: drivers/ipack/ + INTEGRITY MEASUREMENT ARCHITECTURE (IMA) M: Mimi Zohar S: Supported -- cgit v1.2.3 From f58945392aad6a07ede5455ebb584aa729ac1ef0 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sat, 22 Sep 2012 13:54:55 -0300 Subject: clk: mxs: Use a better name for the USB PHY clock Use a better name for the USB PHY clock. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo Signed-off-by: Mike Turquette --- Documentation/devicetree/bindings/clock/imx23-clock.txt | 2 +- Documentation/devicetree/bindings/clock/imx28-clock.txt | 4 ++-- drivers/clk/mxs/clk-imx23.c | 6 +++--- drivers/clk/mxs/clk-imx28.c | 10 +++++----- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/imx23-clock.txt b/Documentation/devicetree/bindings/clock/imx23-clock.txt index a0b867ef8d9..baadbb11fe9 100644 --- a/Documentation/devicetree/bindings/clock/imx23-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx23-clock.txt @@ -52,7 +52,7 @@ clocks and IDs. lcdif 38 etm 39 usb 40 - usb_pwr 41 + usb_phy 41 Examples: diff --git a/Documentation/devicetree/bindings/clock/imx28-clock.txt b/Documentation/devicetree/bindings/clock/imx28-clock.txt index aa2af2866fe..52a49a4a50b 100644 --- a/Documentation/devicetree/bindings/clock/imx28-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx28-clock.txt @@ -73,8 +73,8 @@ clocks and IDs. can1 59 usb0 60 usb1 61 - usb0_pwr 62 - usb1_pwr 63 + usb0_phy 62 + usb1_phy 63 enet_out 64 Examples: diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c index f00dffb9ad6..8dd476e2a9c 100644 --- a/drivers/clk/mxs/clk-imx23.c +++ b/drivers/clk/mxs/clk-imx23.c @@ -85,7 +85,7 @@ enum imx23_clk { cpu_xtal, hbus, xbus, lcdif_div, ssp_div, gpmi_div, emi_pll, emi_xtal, etm_div, saif_div, clk32k_div, rtc, adc, spdif_div, clk32k, dri, pwm, filt, uart, ssp, gpmi, spdif, emi, saif, - lcdif, etm, usb, usb_pwr, + lcdif, etm, usb, usb_phy, clk_max }; @@ -143,8 +143,8 @@ int __init mx23_clocks_init(void) clks[saif] = mxs_clk_gate("saif", "saif_div", SAIF, 31); clks[lcdif] = mxs_clk_gate("lcdif", "lcdif_div", PIX, 31); clks[etm] = mxs_clk_gate("etm", "etm_div", ETM, 31); - clks[usb] = mxs_clk_gate("usb", "usb_pwr", DIGCTRL, 2); - clks[usb_pwr] = clk_register_gate(NULL, "usb_pwr", "pll", 0, PLLCTRL0, 18, 0, &mxs_lock); + clks[usb] = mxs_clk_gate("usb", "usb_phy", DIGCTRL, 2); + clks[usb_phy] = clk_register_gate(NULL, "usb_phy", "pll", 0, PLLCTRL0, 18, 0, &mxs_lock); for (i = 0; i < ARRAY_SIZE(clks); i++) if (IS_ERR(clks[i])) { diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index 42978f1b4bd..db3af087412 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c @@ -140,7 +140,7 @@ enum imx28_clk { emi_xtal, lcdif_div, etm_div, ptp, saif0_div, saif1_div, clk32k_div, rtc, lradc, spdif_div, clk32k, pwm, uart, ssp0, ssp1, ssp2, ssp3, gpmi, spdif, emi, saif0, saif1, lcdif, etm, - fec, can0, can1, usb0, usb1, usb0_pwr, usb1_pwr, enet_out, + fec, can0, can1, usb0, usb1, usb0_phy, usb1_phy, enet_out, clk_max }; @@ -218,10 +218,10 @@ int __init mx28_clocks_init(void) clks[fec] = mxs_clk_gate("fec", "hbus", ENET, 30); clks[can0] = mxs_clk_gate("can0", "ref_xtal", FLEXCAN, 30); clks[can1] = mxs_clk_gate("can1", "ref_xtal", FLEXCAN, 28); - clks[usb0] = mxs_clk_gate("usb0", "usb0_pwr", DIGCTRL, 2); - clks[usb1] = mxs_clk_gate("usb1", "usb1_pwr", DIGCTRL, 16); - clks[usb0_pwr] = clk_register_gate(NULL, "usb0_pwr", "pll0", 0, PLL0CTRL0, 18, 0, &mxs_lock); - clks[usb1_pwr] = clk_register_gate(NULL, "usb1_pwr", "pll1", 0, PLL1CTRL0, 18, 0, &mxs_lock); + clks[usb0] = mxs_clk_gate("usb0", "usb0_phy", DIGCTRL, 2); + clks[usb1] = mxs_clk_gate("usb1", "usb1_phy", DIGCTRL, 16); + clks[usb0_phy] = clk_register_gate(NULL, "usb0_phy", "pll0", 0, PLL0CTRL0, 18, 0, &mxs_lock); + clks[usb1_phy] = clk_register_gate(NULL, "usb1_phy", "pll1", 0, PLL1CTRL0, 18, 0, &mxs_lock); clks[enet_out] = clk_register_gate(NULL, "enet_out", "pll2", 0, ENET, 18, 0, &mxs_lock); for (i = 0; i < ARRAY_SIZE(clks); i++) -- cgit v1.2.3 From 40e80c469f1b52a68e09da3808a1228cf9947fa7 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 31 Oct 2012 13:00:15 -0700 Subject: rcu: Update documentation for TREE_RCU debugfs tracing This commit updates the tracing documentation to reflect the new format that has per-RCU-flavor directories. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- Documentation/RCU/trace.txt | 365 ++++++++++++++++++++++---------------------- 1 file changed, 182 insertions(+), 183 deletions(-) diff --git a/Documentation/RCU/trace.txt b/Documentation/RCU/trace.txt index 672d1908325..79ce9891a8c 100644 --- a/Documentation/RCU/trace.txt +++ b/Documentation/RCU/trace.txt @@ -10,51 +10,61 @@ for rcutree and next for rcutiny. CONFIG_TREE_RCU and CONFIG_TREE_PREEMPT_RCU debugfs Files and Formats -These implementations of RCU provides several debugfs files under the +These implementations of RCU provide several debugfs directories under the top-level directory "rcu": -rcu/rcudata: +rcu/rcu_bh +rcu/rcu_preempt +rcu/rcu_sched + +Each directory contains files for the corresponding flavor of RCU. +Note that rcu/rcu_preempt is only present for CONFIG_TREE_PREEMPT_RCU. +For CONFIG_TREE_RCU, the RCU flavor maps onto the RCU-sched flavor, +so that activity for both appears in rcu/rcu_sched. + +In addition, the following file appears in the top-level directory: +rcu/rcutorture. This file displays rcutorture test progress. The output +of "cat rcu/rcutorture" looks as follows: + +rcutorture test sequence: 0 (test in progress) +rcutorture update version number: 615 + +The first line shows the number of rcutorture tests that have completed +since boot. If a test is currently running, the "(test in progress)" +string will appear as shown above. The second line shows the number of +update cycles that the current test has started, or zero if there is +no test in progress. + + +Within each flavor directory (rcu/rcu_bh, rcu/rcu_sched, and possibly +also rcu/rcu_preempt) the following files will be present: + +rcudata: Displays fields in struct rcu_data. -rcu/rcudata.csv: - Comma-separated values spreadsheet version of rcudata. -rcu/rcugp: +rcugp: Displays grace-period counters. -rcu/rcuhier: +rcuhier: Displays the struct rcu_node hierarchy. -rcu/rcu_pending: +rcu_pending: Displays counts of the reasons rcu_pending() decided that RCU had work to do. -rcu/rcutorture: - Displays rcutorture test progress. -rcu/rcuboost: +rcuboost: Displays RCU boosting statistics. Only present if CONFIG_RCU_BOOST=y. -The output of "cat rcu/rcudata" looks as follows: - -rcu_sched: - 0 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=545/1/0 df=50 of=0 ql=163 qs=NRW. kt=0/W/0 ktl=ebc3 b=10 ci=153737 co=0 ca=0 - 1 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=967/1/0 df=58 of=0 ql=634 qs=NRW. kt=0/W/1 ktl=58c b=10 ci=191037 co=0 ca=0 - 2 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=1081/1/0 df=175 of=0 ql=74 qs=N.W. kt=0/W/2 ktl=da94 b=10 ci=75991 co=0 ca=0 - 3 c=20942 g=20943 pq=1 pgp=20942 qp=1 dt=1846/0/0 df=404 of=0 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=72261 co=0 ca=0 - 4 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=369/1/0 df=83 of=0 ql=48 qs=N.W. kt=0/W/4 ktl=e0e7 b=10 ci=128365 co=0 ca=0 - 5 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=381/1/0 df=64 of=0 ql=169 qs=NRW. kt=0/W/5 ktl=fb2f b=10 ci=164360 co=0 ca=0 - 6 c=20972 g=20973 pq=1 pgp=20973 qp=0 dt=1037/1/0 df=183 of=0 ql=62 qs=N.W. kt=0/W/6 ktl=d2ad b=10 ci=65663 co=0 ca=0 - 7 c=20897 g=20897 pq=1 pgp=20896 qp=0 dt=1572/0/0 df=382 of=0 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=75006 co=0 ca=0 -rcu_bh: - 0 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=545/1/0 df=6 of=0 ql=0 qs=.... kt=0/W/0 ktl=ebc3 b=10 ci=0 co=0 ca=0 - 1 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=967/1/0 df=3 of=0 ql=0 qs=.... kt=0/W/1 ktl=58c b=10 ci=151 co=0 ca=0 - 2 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1081/1/0 df=6 of=0 ql=0 qs=.... kt=0/W/2 ktl=da94 b=10 ci=0 co=0 ca=0 - 3 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1846/0/0 df=8 of=0 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=0 co=0 ca=0 - 4 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=369/1/0 df=6 of=0 ql=0 qs=.... kt=0/W/4 ktl=e0e7 b=10 ci=0 co=0 ca=0 - 5 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=381/1/0 df=4 of=0 ql=0 qs=.... kt=0/W/5 ktl=fb2f b=10 ci=0 co=0 ca=0 - 6 c=1480 g=1480 pq=1 pgp=1480 qp=0 dt=1037/1/0 df=6 of=0 ql=0 qs=.... kt=0/W/6 ktl=d2ad b=10 ci=0 co=0 ca=0 - 7 c=1474 g=1474 pq=1 pgp=1473 qp=0 dt=1572/0/0 df=8 of=0 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=0 co=0 ca=0 - -The first section lists the rcu_data structures for rcu_sched, the second -for rcu_bh. Note that CONFIG_TREE_PREEMPT_RCU kernels will have an -additional section for rcu_preempt. Each section has one line per CPU, -or eight for this 8-CPU system. The fields are as follows: +The output of "cat rcu/rcu_preempt/rcudata" looks as follows: + + 0!c=30455 g=30456 pq=1 qp=1 dt=126535/140000000000000/0 df=2002 of=4 ql=0/0 qs=N... b=10 ci=74572 nci=0 co=1131 ca=716 + 1!c=30719 g=30720 pq=1 qp=0 dt=132007/140000000000000/0 df=1874 of=10 ql=0/0 qs=N... b=10 ci=123209 nci=0 co=685 ca=982 + 2!c=30150 g=30151 pq=1 qp=1 dt=138537/140000000000000/0 df=1707 of=8 ql=0/0 qs=N... b=10 ci=80132 nci=0 co=1328 ca=1458 + 3 c=31249 g=31250 pq=1 qp=0 dt=107255/140000000000000/0 df=1749 of=6 ql=0/450 qs=NRW. b=10 ci=151700 nci=0 co=509 ca=622 + 4!c=29502 g=29503 pq=1 qp=1 dt=83647/140000000000000/0 df=965 of=5 ql=0/0 qs=N... b=10 ci=65643 nci=0 co=1373 ca=1521 + 5 c=31201 g=31202 pq=1 qp=1 dt=70422/0/0 df=535 of=7 ql=0/0 qs=.... b=10 ci=58500 nci=0 co=764 ca=698 + 6!c=30253 g=30254 pq=1 qp=1 dt=95363/140000000000000/0 df=780 of=5 ql=0/0 qs=N... b=10 ci=100607 nci=0 co=1414 ca=1353 + 7 c=31178 g=31178 pq=1 qp=0 dt=91536/0/0 df=547 of=4 ql=0/0 qs=.... b=10 ci=109819 nci=0 co=1115 ca=969 + +This file has one line per CPU, or eight for this 8-CPU system. +The fields are as follows: o The number at the beginning of each line is the CPU number. CPUs numbers followed by an exclamation mark are offline, @@ -64,11 +74,13 @@ o The number at the beginning of each line is the CPU number. substantially larger than the number of actual CPUs. o "c" is the count of grace periods that this CPU believes have - completed. Offlined CPUs and CPUs in dynticks idle mode may - lag quite a ways behind, for example, CPU 6 under "rcu_sched" - above, which has been offline through not quite 40,000 RCU grace - periods. It is not unusual to see CPUs lagging by thousands of - grace periods. + completed. Offlined CPUs and CPUs in dynticks idle mode may lag + quite a ways behind, for example, CPU 4 under "rcu_sched" above, + which has been offline through 16 RCU grace periods. It is not + unusual to see offline CPUs lagging by thousands of grace periods. + Note that although the grace-period number is an unsigned long, + it is printed out as a signed long to allow more human-friendly + representation near boot time. o "g" is the count of grace periods that this CPU believes have started. Again, offlined CPUs and CPUs in dynticks idle mode @@ -84,30 +96,25 @@ o "pq" indicates that this CPU has passed through a quiescent state CPU has not yet reported that fact, (2) some other CPU has not yet reported for this grace period, or (3) both. -o "pgp" indicates which grace period the last-observed quiescent - state for this CPU corresponds to. This is important for handling - the race between CPU 0 reporting an extended dynticks-idle - quiescent state for CPU 1 and CPU 1 suddenly waking up and - reporting its own quiescent state. If CPU 1 was the last CPU - for the current grace period, then the CPU that loses this race - will attempt to incorrectly mark CPU 1 as having checked in for - the next grace period! - o "qp" indicates that RCU still expects a quiescent state from this CPU. Offlined CPUs and CPUs in dyntick idle mode might well have qp=1, which is OK: RCU is still ignoring them. o "dt" is the current value of the dyntick counter that is incremented - when entering or leaving dynticks idle state, either by the - scheduler or by irq. This number is even if the CPU is in - dyntick idle mode and odd otherwise. The number after the first - "/" is the interrupt nesting depth when in dyntick-idle state, - or one greater than the interrupt-nesting depth otherwise. - The number after the second "/" is the NMI nesting depth. + when entering or leaving idle, either due to a context switch or + due to an interrupt. This number is even if the CPU is in idle + from RCU's viewpoint and odd otherwise. The number after the + first "/" is the interrupt nesting depth when in idle state, + or a large number added to the interrupt-nesting depth when + running a non-idle task. Some architectures do not accurately + count interrupt nesting when running in non-idle kernel context, + which can result in interesting anomalies such as negative + interrupt-nesting levels. The number after the second "/" + is the NMI nesting depth. o "df" is the number of times that some other CPU has forced a quiescent state on behalf of this CPU due to this CPU being in - dynticks-idle state. + idle state. o "of" is the number of times that some other CPU has forced a quiescent state on behalf of this CPU due to this CPU being @@ -120,9 +127,13 @@ o "of" is the number of times that some other CPU has forced a error, so it makes sense to err conservatively. o "ql" is the number of RCU callbacks currently residing on - this CPU. This is the total number of callbacks, regardless - of what state they are in (new, waiting for grace period to - start, waiting for grace period to end, ready to invoke). + this CPU. The first number is the number of "lazy" callbacks + that are known to RCU to only be freeing memory, and the number + after the "/" is the total number of callbacks, lazy or not. + These counters count callbacks regardless of what phase of + grace-period processing that they are in (new, waiting for + grace period to start, waiting for grace period to end, ready + to invoke). o "qs" gives an indication of the state of the callback queue with four characters: @@ -150,6 +161,43 @@ o "qs" gives an indication of the state of the callback queue If there are no callbacks in a given one of the above states, the corresponding character is replaced by ".". +o "b" is the batch limit for this CPU. If more than this number + of RCU callbacks is ready to invoke, then the remainder will + be deferred. + +o "ci" is the number of RCU callbacks that have been invoked for + this CPU. Note that ci+nci+ql is the number of callbacks that have + been registered in absence of CPU-hotplug activity. + +o "nci" is the number of RCU callbacks that have been offloaded from + this CPU. This will always be zero unless the kernel was built + with CONFIG_RCU_NOCB_CPU=y and the "rcu_nocbs=" kernel boot + parameter was specified. + +o "co" is the number of RCU callbacks that have been orphaned due to + this CPU going offline. These orphaned callbacks have been moved + to an arbitrarily chosen online CPU. + +o "ca" is the number of RCU callbacks that have been adopted by this + CPU due to other CPUs going offline. Note that ci+co-ca+ql is + the number of RCU callbacks registered on this CPU. + + +Kernels compiled with CONFIG_RCU_BOOST=y display the following from +/debug/rcu/rcu_preempt/rcudata: + + 0!c=12865 g=12866 pq=1 qp=1 dt=83113/140000000000000/0 df=288 of=11 ql=0/0 qs=N... kt=0/O ktl=944 b=10 ci=60709 nci=0 co=748 ca=871 + 1 c=14407 g=14408 pq=1 qp=0 dt=100679/140000000000000/0 df=378 of=7 ql=0/119 qs=NRW. kt=0/W ktl=9b6 b=10 ci=109740 nci=0 co=589 ca=485 + 2 c=14407 g=14408 pq=1 qp=0 dt=105486/0/0 df=90 of=9 ql=0/89 qs=NRW. kt=0/W ktl=c0c b=10 ci=83113 nci=0 co=533 ca=490 + 3 c=14407 g=14408 pq=1 qp=0 dt=107138/0/0 df=142 of=8 ql=0/188 qs=NRW. kt=0/W ktl=b96 b=10 ci=121114 nci=0 co=426 ca=290 + 4 c=14405 g=14406 pq=1 qp=1 dt=50238/0/0 df=706 of=7 ql=0/0 qs=.... kt=0/W ktl=812 b=10 ci=34929 nci=0 co=643 ca=114 + 5!c=14168 g=14169 pq=1 qp=0 dt=45465/140000000000000/0 df=161 of=11 ql=0/0 qs=N... kt=0/O ktl=b4d b=10 ci=47712 nci=0 co=677 ca=722 + 6 c=14404 g=14405 pq=1 qp=0 dt=59454/0/0 df=94 of=6 ql=0/0 qs=.... kt=0/W ktl=e57 b=10 ci=55597 nci=0 co=701 ca=811 + 7 c=14407 g=14408 pq=1 qp=1 dt=68850/0/0 df=31 of=8 ql=0/0 qs=.... kt=0/W ktl=14bd b=10 ci=77475 nci=0 co=508 ca=1042 + +This is similar to the output discussed above, but contains the following +additional fields: + o "kt" is the per-CPU kernel-thread state. The digit preceding the first slash is zero if there is no work pending and 1 otherwise. The character between the first pair of slashes is @@ -184,35 +232,12 @@ o "ktl" is the low-order 16 bits (in hexadecimal) of the count of This field is displayed only for CONFIG_RCU_BOOST kernels. -o "b" is the batch limit for this CPU. If more than this number - of RCU callbacks is ready to invoke, then the remainder will - be deferred. - -o "ci" is the number of RCU callbacks that have been invoked for - this CPU. Note that ci+ql is the number of callbacks that have - been registered in absence of CPU-hotplug activity. - -o "co" is the number of RCU callbacks that have been orphaned due to - this CPU going offline. These orphaned callbacks have been moved - to an arbitrarily chosen online CPU. - -o "ca" is the number of RCU callbacks that have been adopted due to - other CPUs going offline. Note that ci+co-ca+ql is the number of - RCU callbacks registered on this CPU. -There is also an rcu/rcudata.csv file with the same information in -comma-separated-variable spreadsheet format. +The output of "cat rcu/rcu_preempt/rcugp" looks as follows: +completed=31249 gpnum=31250 age=1 max=18 -The output of "cat rcu/rcugp" looks as follows: - -rcu_sched: completed=33062 gpnum=33063 -rcu_bh: completed=464 gpnum=464 - -Again, this output is for both "rcu_sched" and "rcu_bh". Note that -kernels built with CONFIG_TREE_PREEMPT_RCU will have an additional -"rcu_preempt" line. The fields are taken from the rcu_state structure, -and are as follows: +These fields are taken from the rcu_state structure, and are as follows: o "completed" is the number of grace periods that have completed. It is comparable to the "c" field from rcu/rcudata in that a @@ -220,44 +245,42 @@ o "completed" is the number of grace periods that have completed. that the corresponding RCU grace period has completed. o "gpnum" is the number of grace periods that have started. It is - comparable to the "g" field from rcu/rcudata in that a CPU - whose "g" field matches the value of "gpnum" is aware that the - corresponding RCU grace period has started. + similarly comparable to the "g" field from rcu/rcudata in that + a CPU whose "g" field matches the value of "gpnum" is aware that + the corresponding RCU grace period has started. - If these two fields are equal (as they are for "rcu_bh" above), - then there is no grace period in progress, in other words, RCU - is idle. On the other hand, if the two fields differ (as they - do for "rcu_sched" above), then an RCU grace period is in progress. + If these two fields are equal, then there is no grace period + in progress, in other words, RCU is idle. On the other hand, + if the two fields differ (as they are above), then an RCU grace + period is in progress. +o "age" is the number of jiffies that the current grace period + has extended for, or zero if there is no grace period currently + in effect. -The output of "cat rcu/rcuhier" looks as follows, with very long lines: +o "max" is the age in jiffies of the longest-duration grace period + thus far. -c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6 -1/1 ..>. 0:127 ^0 -3/3 ..>. 0:35 ^0 0/0 ..>. 36:71 ^1 0/0 ..>. 72:107 ^2 0/0 ..>. 108:127 ^3 -3/3f ..>. 0:5 ^0 2/3 ..>. 6:11 ^1 0/0 ..>. 12:17 ^2 0/0 ..>. 18:23 ^3 0/0 ..>. 24:29 ^4 0/0 ..>. 30:35 ^5 0/0 ..>. 36:41 ^0 0/0 ..>. 42:47 ^1 0/0 ..>. 48:53 ^2 0/0 ..>. 54:59 ^3 0/0 ..>. 60:65 ^4 0/0 ..>. 66:71 ^5 0/0 ..>. 72:77 ^0 0/0 ..>. 78:83 ^1 0/0 ..>. 84:89 ^2 0/0 ..>. 90:95 ^3 0/0 ..>. 96:101 ^4 0/0 ..>. 102:107 ^5 0/0 ..>. 108:113 ^0 0/0 ..>. 114:119 ^1 0/0 ..>. 120:125 ^2 0/0 ..>. 126:127 ^3 -rcu_bh: -c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0 -0/1 ..>. 0:127 ^0 -0/3 ..>. 0:35 ^0 0/0 ..>. 36:71 ^1 0/0 ..>. 72:107 ^2 0/0 ..>. 108:127 ^3 -0/3f ..>. 0:5 ^0 0/3 ..>. 6:11 ^1 0/0 ..>. 12:17 ^2 0/0 ..>. 18:23 ^3 0/0 ..>. 24:29 ^4 0/0 ..>. 30:35 ^5 0/0 ..>. 36:41 ^0 0/0 ..>. 42:47 ^1 0/0 ..>. 48:53 ^2 0/0 ..>. 54:59 ^3 0/0 ..>. 60:65 ^4 0/0 ..>. 66:71 ^5 0/0 ..>. 72:77 ^0 0/0 ..>. 78:83 ^1 0/0 ..>. 84:89 ^2 0/0 ..>. 90:95 ^3 0/0 ..>. 96:101 ^4 0/0 ..>. 102:107 ^5 0/0 ..>. 108:113 ^0 0/0 ..>. 114:119 ^1 0/0 ..>. 120:125 ^2 0/0 ..>. 126:127 ^3 +The output of "cat rcu/rcu_preempt/rcuhier" looks as follows: -This is once again split into "rcu_sched" and "rcu_bh" portions, -and CONFIG_TREE_PREEMPT_RCU kernels will again have an additional -"rcu_preempt" section. The fields are as follows: +c=14407 g=14408 s=0 jfq=2 j=c863 nfqs=12040/nfqsng=0(12040) fqlh=1051 oqlen=0/0 +3/3 ..>. 0:7 ^0 +e/e ..>. 0:3 ^0 d/d ..>. 4:7 ^1 -o "c" is exactly the same as "completed" under rcu/rcugp. +The fields are as follows: -o "g" is exactly the same as "gpnum" under rcu/rcugp. +o "c" is exactly the same as "completed" under rcu/rcu_preempt/rcugp. -o "s" is the "signaled" state that drives force_quiescent_state()'s +o "g" is exactly the same as "gpnum" under rcu/rcu_preempt/rcugp. + +o "s" is the current state of the force_quiescent_state() state machine. o "jfq" is the number of jiffies remaining for this grace period before force_quiescent_state() is invoked to help push things - along. Note that CPUs in dyntick-idle mode throughout the grace - period will not report on their own, but rather must be check by - some other CPU via force_quiescent_state(). + along. Note that CPUs in idle mode throughout the grace period + will not report on their own, but rather must be check by some + other CPU via force_quiescent_state(). o "j" is the low-order four hex digits of the jiffies counter. Yes, Paul did run into a number of problems that turned out to @@ -268,7 +291,8 @@ o "nfqs" is the number of calls to force_quiescent_state() since o "nfqsng" is the number of useless calls to force_quiescent_state(), where there wasn't actually a grace period active. This can - happen due to races. The number in parentheses is the difference + no longer happen due to grace-period processing being pushed + into a kthread. The number in parentheses is the difference between "nfqs" and "nfqsng", or the number of times that force_quiescent_state() actually did some real work. @@ -276,28 +300,27 @@ o "fqlh" is the number of calls to force_quiescent_state() that exited immediately (without even being counted in nfqs above) due to contention on ->fqslock. -o Each element of the form "1/1 0:127 ^0" represents one struct - rcu_node. Each line represents one level of the hierarchy, from - root to leaves. It is best to think of the rcu_data structures - as forming yet another level after the leaves. Note that there - might be either one, two, or three levels of rcu_node structures, - depending on the relationship between CONFIG_RCU_FANOUT and - CONFIG_NR_CPUS. +o Each element of the form "3/3 ..>. 0:7 ^0" represents one rcu_node + structure. Each line represents one level of the hierarchy, + from root to leaves. It is best to think of the rcu_data + structures as forming yet another level after the leaves. + Note that there might be either one, two, three, or even four + levels of rcu_node structures, depending on the relationship + between CONFIG_RCU_FANOUT, CONFIG_RCU_FANOUT_LEAF (possibly + adjusted using the rcu_fanout_leaf kernel boot parameter), and + CONFIG_NR_CPUS (possibly adjusted using the nr_cpu_ids count of + possible CPUs for the booting hardware). o The numbers separated by the "/" are the qsmask followed by the qsmaskinit. The qsmask will have one bit - set for each entity in the next lower level that - has not yet checked in for the current grace period. + set for each entity in the next lower level that has + not yet checked in for the current grace period ("e" + indicating CPUs 5, 6, and 7 in the example above). The qsmaskinit will have one bit for each entity that is currently expected to check in during each grace period. The value of qsmaskinit is assigned to that of qsmask at the beginning of each grace period. - For example, for "rcu_sched", the qsmask of the first - entry of the lowest level is 0x14, meaning that we - are still waiting for CPUs 2 and 4 to check in for the - current grace period. - o The characters separated by the ">" indicate the state of the blocked-tasks lists. A "G" preceding the ">" indicates that at least one task blocked in an RCU @@ -312,48 +335,39 @@ o Each element of the form "1/1 0:127 ^0" represents one struct A "." character appears if the corresponding condition does not hold, so that "..>." indicates that no tasks are blocked. In contrast, "GE>T" indicates maximal - inconvenience from blocked tasks. + inconvenience from blocked tasks. CONFIG_TREE_RCU + builds of the kernel will always show "..>.". o The numbers separated by the ":" are the range of CPUs served by this struct rcu_node. This can be helpful in working out how the hierarchy is wired together. - For example, the first entry at the lowest level shows - "0:5", indicating that it covers CPUs 0 through 5. + For example, the example rcu_node structure shown above + has "0:7", indicating that it covers CPUs 0 through 7. o The number after the "^" indicates the bit in the - next higher level rcu_node structure that this - rcu_node structure corresponds to. - - For example, the first entry at the lowest level shows - "^0", indicating that it corresponds to bit zero in - the first entry at the middle level. - - -The output of "cat rcu/rcu_pending" looks as follows: - -rcu_sched: - 0 np=255892 qsp=53936 rpq=85 cbr=0 cng=14417 gpc=10033 gps=24320 nn=146741 - 1 np=261224 qsp=54638 rpq=33 cbr=0 cng=25723 gpc=16310 gps=2849 nn=155792 - 2 np=237496 qsp=49664 rpq=23 cbr=0 cng=2762 gpc=45478 gps=1762 nn=136629 - 3 np=236249 qsp=48766 rpq=98 cbr=0 cng=286 gpc=48049 gps=1218 nn=137723 - 4 np=221310 qsp=46850 rpq=7 cbr=0 cng=26 gpc=43161 gps=4634 nn=123110 - 5 np=237332 qsp=48449 rpq=9 cbr=0 cng=54 gpc=47920 gps=3252 nn=137456 - 6 np=219995 qsp=46718 rpq=12 cbr=0 cng=50 gpc=42098 gps=6093 nn=120834 - 7 np=249893 qsp=49390 rpq=42 cbr=0 cng=72 gpc=38400 gps=17102 nn=144888 -rcu_bh: - 0 np=146741 qsp=1419 rpq=6 cbr=0 cng=6 gpc=0 gps=0 nn=145314 - 1 np=155792 qsp=12597 rpq=3 cbr=0 cng=0 gpc=4 gps=8 nn=143180 - 2 np=136629 qsp=18680 rpq=1 cbr=0 cng=0 gpc=7 gps=6 nn=117936 - 3 np=137723 qsp=2843 rpq=0 cbr=0 cng=0 gpc=10 gps=7 nn=134863 - 4 np=123110 qsp=12433 rpq=0 cbr=0 cng=0 gpc=4 gps=2 nn=110671 - 5 np=137456 qsp=4210 rpq=1 cbr=0 cng=0 gpc=6 gps=5 nn=133235 - 6 np=120834 qsp=9902 rpq=2 cbr=0 cng=0 gpc=6 gps=3 nn=110921 - 7 np=144888 qsp=26336 rpq=0 cbr=0 cng=0 gpc=8 gps=2 nn=118542 - -As always, this is once again split into "rcu_sched" and "rcu_bh" -portions, with CONFIG_TREE_PREEMPT_RCU kernels having an additional -"rcu_preempt" section. The fields are as follows: + next higher level rcu_node structure that this rcu_node + structure corresponds to. For example, the "d/d ..>. 4:7 + ^1" has a "1" in this position, indicating that it + corresponds to the "1" bit in the "3" shown in the + "3/3 ..>. 0:7 ^0" entry on the next level up. + + +The output of "cat rcu/rcu_sched/rcu_pending" looks as follows: + + 0!np=26111 qsp=29 rpq=5386 cbr=1 cng=570 gpc=3674 gps=577 nn=15903 + 1!np=28913 qsp=35 rpq=6097 cbr=1 cng=448 gpc=3700 gps=554 nn=18113 + 2!np=32740 qsp=37 rpq=6202 cbr=0 cng=476 gpc=4627 gps=546 nn=20889 + 3 np=23679 qsp=22 rpq=5044 cbr=1 cng=415 gpc=3403 gps=347 nn=14469 + 4!np=30714 qsp=4 rpq=5574 cbr=0 cng=528 gpc=3931 gps=639 nn=20042 + 5 np=28910 qsp=2 rpq=5246 cbr=0 cng=428 gpc=4105 gps=709 nn=18422 + 6!np=38648 qsp=5 rpq=7076 cbr=0 cng=840 gpc=4072 gps=961 nn=25699 + 7 np=37275 qsp=2 rpq=6873 cbr=0 cng=868 gpc=3416 gps=971 nn=25147 + +The fields are as follows: + +o The leading number is the CPU number, with "!" indicating + an offline CPU. o "np" is the number of times that __rcu_pending() has been invoked for the corresponding flavor of RCU. @@ -377,38 +391,23 @@ o "gpc" is the number of times that an old grace period had o "gps" is the number of times that a new grace period had started, but this CPU was not yet aware of it. -o "nn" is the number of times that this CPU needed nothing. Alert - readers will note that the rcu "nn" number for a given CPU very - closely matches the rcu_bh "np" number for that same CPU. This - is due to short-circuit evaluation in rcu_pending(). - - -The output of "cat rcu/rcutorture" looks as follows: - -rcutorture test sequence: 0 (test in progress) -rcutorture update version number: 615 - -The first line shows the number of rcutorture tests that have completed -since boot. If a test is currently running, the "(test in progress)" -string will appear as shown above. The second line shows the number of -update cycles that the current test has started, or zero if there is -no test in progress. +o "nn" is the number of times that this CPU needed nothing. The output of "cat rcu/rcuboost" looks as follows: -0:5 tasks=.... kt=W ntb=0 neb=0 nnb=0 j=2f95 bt=300f - balk: nt=0 egt=989 bt=0 nb=0 ny=0 nos=16 -6:7 tasks=.... kt=W ntb=0 neb=0 nnb=0 j=2f95 bt=300f - balk: nt=0 egt=225 bt=0 nb=0 ny=0 nos=6 +0:3 tasks=.... kt=W ntb=0 neb=0 nnb=0 j=c864 bt=c894 + balk: nt=0 egt=4695 bt=0 nb=0 ny=56 nos=0 +4:7 tasks=.... kt=W ntb=0 neb=0 nnb=0 j=c864 bt=c894 + balk: nt=0 egt=6541 bt=0 nb=0 ny=126 nos=0 This information is output only for rcu_preempt. Each two-line entry corresponds to a leaf rcu_node strcuture. The fields are as follows: o "n:m" is the CPU-number range for the corresponding two-line entry. In the sample output above, the first entry covers - CPUs zero through five and the second entry covers CPUs 6 - and 7. + CPUs zero through three and the second entry covers CPUs four + through seven. o "tasks=TNEB" gives the state of the various segments of the rnp->blocked_tasks list: -- cgit v1.2.3 From d484a215139cf556cb718a7ec7042260b7fc2d28 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 31 Oct 2012 13:22:08 -0700 Subject: rcu: Add documentation for the new rcuexp debugfs trace file This commit adds the documentation of the rcuexp debugfs trace file that records statistics for expedited grace periods. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- Documentation/RCU/trace.txt | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/Documentation/RCU/trace.txt b/Documentation/RCU/trace.txt index 79ce9891a8c..c776968f446 100644 --- a/Documentation/RCU/trace.txt +++ b/Documentation/RCU/trace.txt @@ -41,6 +41,8 @@ also rcu/rcu_preempt) the following files will be present: rcudata: Displays fields in struct rcu_data. +rcuexp: + Displays statistics for expedited grace periods. rcugp: Displays grace-period counters. rcuhier: @@ -233,6 +235,45 @@ o "ktl" is the low-order 16 bits (in hexadecimal) of the count of This field is displayed only for CONFIG_RCU_BOOST kernels. +The output of "cat rcu/rcu_preempt/rcuexp" looks as follows: + +s=21872 d=21872 w=0 tf=0 wd1=0 wd2=0 n=0 sc=21872 dt=21872 dl=0 dx=21872 + +These fields are as follows: + +o "s" is the starting sequence number. + +o "d" is the ending sequence number. When the starting and ending + numbers differ, there is an expedited grace period in progress. + +o "w" is the number of times that the sequence numbers have been + in danger of wrapping. + +o "tf" is the number of times that contention has resulted in a + failure to begin an expedited grace period. + +o "wd1" and "wd2" are the number of times that an attempt to + start an expedited grace period found that someone else had + completed an expedited grace period that satisfies the + attempted request. "Our work is done." + +o "n" is number of times that contention was so great that + the request was demoted from an expedited grace period to + a normal grace period. + +o "sc" is the number of times that the attempt to start a + new expedited grace period succeeded. + +o "dt" is the number of times that we attempted to update + the "d" counter. + +o "dl" is the number of times that we failed to update the "d" + counter. + +o "dx" is the number of times that we succeeded in updating + the "d" counter. + + The output of "cat rcu/rcu_preempt/rcugp" looks as follows: completed=31249 gpnum=31250 age=1 max=18 -- cgit v1.2.3 From 3fbfbf7a3b66ec424042d909f14ba2ddf4372ea8 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sun, 19 Aug 2012 21:35:53 -0700 Subject: rcu: Add callback-free CPUs RCU callback execution can add significant OS jitter and also can degrade both scheduling latency and, in asymmetric multiprocessors, energy efficiency. This commit therefore adds the ability for selected CPUs ("rcu_nocbs=" boot parameter) to have their callbacks offloaded to kthreads. If the "rcu_nocb_poll" boot parameter is also specified, these kthreads will do polling, removing the need for the offloaded CPUs to do wakeups. At least one CPU must be doing normal callback processing: currently CPU 0 cannot be selected as a no-CBs CPU. In addition, attempts to offline the last normal-CBs CPU will fail. This feature was inspired by Jim Houston's and Joe Korty's JRCU, and this commit includes fixes to problems located by Fengguang Wu's kbuild test robot. [ paulmck: Added gfp.h include file as suggested by Fengguang Wu. ] Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- Documentation/kernel-parameters.txt | 21 ++ include/trace/events/rcu.h | 1 + init/Kconfig | 22 ++ kernel/rcutree.c | 63 ++++-- kernel/rcutree.h | 47 +++++ kernel/rcutree_plugin.h | 397 +++++++++++++++++++++++++++++++++++- kernel/rcutree_trace.c | 7 +- 7 files changed, 542 insertions(+), 16 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 9776f068306..9d2e5cb3a95 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2394,6 +2394,27 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ramdisk_size= [RAM] Sizes of RAM disks in kilobytes See Documentation/blockdev/ramdisk.txt. + rcu_nocbs= [KNL,BOOT] + In kernels built with CONFIG_RCU_NOCB_CPU=y, set + the specified list of CPUs to be no-callback CPUs. + Invocation of these CPUs' RCU callbacks will + be offloaded to "rcuoN" kthreads created for + that purpose. This reduces OS jitter on the + offloaded CPUs, which can be useful for HPC and + real-time workloads. It can also improve energy + efficiency for asymmetric multiprocessors. + + rcu_nocbs_poll [KNL,BOOT] + Rather than requiring that offloaded CPUs + (specified by rcu_nocbs= above) explicitly + awaken the corresponding "rcuoN" kthreads, + make these kthreads poll for callbacks. + This improves the real-time response for the + offloaded CPUs by relieving them of the need to + wake up the corresponding kthread, but degrades + energy efficiency by requiring that the kthreads + periodically wake up to do the polling. + rcutree.blimit= [KNL,BOOT] Set maximum number of finished RCU callbacks to process in one batch. diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h index 5bde94d8585..d4f559b1ec3 100644 --- a/include/trace/events/rcu.h +++ b/include/trace/events/rcu.h @@ -549,6 +549,7 @@ TRACE_EVENT(rcu_torture_read, * "EarlyExit": rcu_barrier_callback() piggybacked, thus early exit. * "Inc1": rcu_barrier_callback() piggyback check counter incremented. * "Offline": rcu_barrier_callback() found offline CPU + * "OnlineNoCB": rcu_barrier_callback() found online no-CBs CPU. * "OnlineQ": rcu_barrier_callback() found online CPU with callbacks. * "OnlineNQ": rcu_barrier_callback() found online CPU, no callbacks. * "IRQ": An rcu_barrier_callback() callback posted on remote CPU. diff --git a/init/Kconfig b/init/Kconfig index ec62139207d..5ac6ee09422 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -654,6 +654,28 @@ config RCU_BOOST_DELAY Accept the default if unsure. +config RCU_NOCB_CPU + bool "Offload RCU callback processing from boot-selected CPUs" + depends on TREE_RCU || TREE_PREEMPT_RCU + default n + help + Use this option to reduce OS jitter for aggressive HPC or + real-time workloads. It can also be used to offload RCU + callback invocation to energy-efficient CPUs in battery-powered + asymmetric multiprocessors. + + This option offloads callback invocation from the set of + CPUs specified at boot time by the rcu_nocbs parameter. + For each such CPU, a kthread ("rcuoN") will be created to + invoke callbacks, where the "N" is the CPU being offloaded. + Nothing prevents this kthread from running on the specified + CPUs, but (1) the kthreads may be preempted between each + callback, and (2) affinity or cgroups can be used to force + the kthreads to run on whatever set of CPUs is desired. + + Say Y here if you want reduced OS jitter on selected CPUs. + Say N here if you are unsure. + endmenu # "RCU Subsystem" config IKCONFIG diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 5ffadcc3bb2..7733eb56e15 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c @@ -303,7 +303,8 @@ EXPORT_SYMBOL_GPL(rcu_sched_force_quiescent_state); static int cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp) { - return &rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL]; + return &rdp->nxtlist != rdp->nxttail[RCU_DONE_TAIL] && + rdp->nxttail[RCU_DONE_TAIL] != NULL; } /* @@ -312,8 +313,11 @@ cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp) static int cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp) { - return *rdp->nxttail[RCU_DONE_TAIL + - (ACCESS_ONCE(rsp->completed) != rdp->completed)] && + struct rcu_head **ntp; + + ntp = rdp->nxttail[RCU_DONE_TAIL + + (ACCESS_ONCE(rsp->completed) != rdp->completed)]; + return rdp->nxttail[RCU_DONE_TAIL] && ntp && *ntp && !rcu_gp_in_progress(rsp); } @@ -1123,6 +1127,7 @@ static void init_callback_list(struct rcu_data *rdp) rdp->nxtlist = NULL; for (i = 0; i < RCU_NEXT_SIZE; i++) rdp->nxttail[i] = &rdp->nxtlist; + init_nocb_callback_list(rdp); } /* @@ -1633,6 +1638,10 @@ static void rcu_send_cbs_to_orphanage(int cpu, struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp) { + /* No-CBs CPUs do not have orphanable callbacks. */ + if (is_nocb_cpu(rdp->cpu)) + return; + /* * Orphan the callbacks. First adjust the counts. This is safe * because _rcu_barrier() excludes CPU-hotplug operations, so it @@ -1684,6 +1693,10 @@ static void rcu_adopt_orphan_cbs(struct rcu_state *rsp) int i; struct rcu_data *rdp = __this_cpu_ptr(rsp->rda); + /* No-CBs CPUs are handled specially. */ + if (rcu_nocb_adopt_orphan_cbs(rsp, rdp)) + return; + /* Do the accounting first. */ rdp->qlen_lazy += rsp->qlen_lazy; rdp->qlen += rsp->qlen; @@ -2162,9 +2175,15 @@ static void __call_rcu_core(struct rcu_state *rsp, struct rcu_data *rdp, } } +/* + * Helper function for call_rcu() and friends. The cpu argument will + * normally be -1, indicating "currently running CPU". It may specify + * a CPU only if that CPU is a no-CBs CPU. Currently, only _rcu_barrier() + * is expected to specify a CPU. + */ static void __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), - struct rcu_state *rsp, bool lazy) + struct rcu_state *rsp, int cpu, bool lazy) { unsigned long flags; struct rcu_data *rdp; @@ -2184,9 +2203,14 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), rdp = this_cpu_ptr(rsp->rda); /* Add the callback to our list. */ - if (unlikely(rdp->nxttail[RCU_NEXT_TAIL] == NULL)) { + if (unlikely(rdp->nxttail[RCU_NEXT_TAIL] == NULL) || cpu != -1) { + int offline; + + if (cpu != -1) + rdp = per_cpu_ptr(rsp->rda, cpu); + offline = !__call_rcu_nocb(rdp, head, lazy); + WARN_ON_ONCE(offline); /* _call_rcu() is illegal on offline CPU; leak the callback. */ - WARN_ON_ONCE(1); local_irq_restore(flags); return; } @@ -2215,7 +2239,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), */ void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu)) { - __call_rcu(head, func, &rcu_sched_state, 0); + __call_rcu(head, func, &rcu_sched_state, -1, 0); } EXPORT_SYMBOL_GPL(call_rcu_sched); @@ -2224,7 +2248,7 @@ EXPORT_SYMBOL_GPL(call_rcu_sched); */ void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu)) { - __call_rcu(head, func, &rcu_bh_state, 0); + __call_rcu(head, func, &rcu_bh_state, -1, 0); } EXPORT_SYMBOL_GPL(call_rcu_bh); @@ -2676,9 +2700,17 @@ static void _rcu_barrier(struct rcu_state *rsp) * When that callback is invoked, we will know that all of the * corresponding CPU's preceding callbacks have been invoked. */ - for_each_online_cpu(cpu) { + for_each_possible_cpu(cpu) { + if (!cpu_online(cpu) && !is_nocb_cpu(cpu)) + continue; rdp = per_cpu_ptr(rsp->rda, cpu); - if (ACCESS_ONCE(rdp->qlen)) { + if (is_nocb_cpu(cpu)) { + _rcu_barrier_trace(rsp, "OnlineNoCB", cpu, + rsp->n_barrier_done); + atomic_inc(&rsp->barrier_cpu_count); + __call_rcu(&rdp->barrier_head, rcu_barrier_callback, + rsp, cpu, 0); + } else if (ACCESS_ONCE(rdp->qlen)) { _rcu_barrier_trace(rsp, "OnlineQ", cpu, rsp->n_barrier_done); smp_call_function_single(cpu, rcu_barrier_func, rsp, 1); @@ -2752,6 +2784,7 @@ rcu_boot_init_percpu_data(int cpu, struct rcu_state *rsp) #endif rdp->cpu = cpu; rdp->rsp = rsp; + rcu_boot_init_nocb_percpu_data(rdp); raw_spin_unlock_irqrestore(&rnp->lock, flags); } @@ -2833,6 +2866,7 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self, struct rcu_data *rdp = per_cpu_ptr(rcu_state->rda, cpu); struct rcu_node *rnp = rdp->mynode; struct rcu_state *rsp; + int ret = NOTIFY_OK; trace_rcu_utilization("Start CPU hotplug"); switch (action) { @@ -2846,7 +2880,10 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self, rcu_boost_kthread_setaffinity(rnp, -1); break; case CPU_DOWN_PREPARE: - rcu_boost_kthread_setaffinity(rnp, cpu); + if (nocb_cpu_expendable(cpu)) + rcu_boost_kthread_setaffinity(rnp, cpu); + else + ret = NOTIFY_BAD; break; case CPU_DYING: case CPU_DYING_FROZEN: @@ -2870,7 +2907,7 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self, break; } trace_rcu_utilization("End CPU hotplug"); - return NOTIFY_OK; + return ret; } /* @@ -2890,6 +2927,7 @@ static int __init rcu_spawn_gp_kthread(void) raw_spin_lock_irqsave(&rnp->lock, flags); rsp->gp_kthread = t; raw_spin_unlock_irqrestore(&rnp->lock, flags); + rcu_spawn_nocb_kthreads(rsp); } return 0; } @@ -3085,6 +3123,7 @@ void __init rcu_init(void) rcu_init_one(&rcu_sched_state, &rcu_sched_data); rcu_init_one(&rcu_bh_state, &rcu_bh_data); __rcu_init_preempt(); + rcu_init_nocb(); open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); /* diff --git a/kernel/rcutree.h b/kernel/rcutree.h index d274af35721..488f2ec6b66 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h @@ -317,6 +317,18 @@ struct rcu_data { struct rcu_head oom_head; #endif /* #ifdef CONFIG_RCU_FAST_NO_HZ */ + /* 7) Callback offloading. */ +#ifdef CONFIG_RCU_NOCB_CPU + struct rcu_head *nocb_head; /* CBs waiting for kthread. */ + struct rcu_head **nocb_tail; + atomic_long_t nocb_q_count; /* # CBs waiting for kthread */ + atomic_long_t nocb_q_count_lazy; /* (approximate). */ + int nocb_p_count; /* # CBs being invoked by kthread */ + int nocb_p_count_lazy; /* (approximate). */ + wait_queue_head_t nocb_wq; /* For nocb kthreads to sleep on. */ + struct task_struct *nocb_kthread; +#endif /* #ifdef CONFIG_RCU_NOCB_CPU */ + int cpu; struct rcu_state *rsp; }; @@ -369,6 +381,12 @@ struct rcu_state { struct rcu_data __percpu *rda; /* pointer of percu rcu_data. */ void (*call)(struct rcu_head *head, /* call_rcu() flavor. */ void (*func)(struct rcu_head *head)); +#ifdef CONFIG_RCU_NOCB_CPU + void (*call_remote)(struct rcu_head *head, + void (*func)(struct rcu_head *head)); + /* call_rcu() flavor, but for */ + /* placing on remote CPU. */ +#endif /* #ifdef CONFIG_RCU_NOCB_CPU */ /* The following fields are guarded by the root rcu_node's lock. */ @@ -439,6 +457,8 @@ struct rcu_state { #define RCU_GP_FLAG_FQS 0x2 /* Need grace-period quiescent-state forcing. */ extern struct list_head rcu_struct_flavors; + +/* Sequence through rcu_state structures for each RCU flavor. */ #define for_each_rcu_flavor(rsp) \ list_for_each_entry((rsp), &rcu_struct_flavors, flavors) @@ -515,5 +535,32 @@ static void print_cpu_stall_info(struct rcu_state *rsp, int cpu); static void print_cpu_stall_info_end(void); static void zero_cpu_stall_ticks(struct rcu_data *rdp); static void increment_cpu_stall_ticks(void); +static bool is_nocb_cpu(int cpu); +static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, + bool lazy); +static bool rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, + struct rcu_data *rdp); +static bool nocb_cpu_expendable(int cpu); +static void rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp); +static void rcu_spawn_nocb_kthreads(struct rcu_state *rsp); +static void init_nocb_callback_list(struct rcu_data *rdp); +static void __init rcu_init_nocb(void); #endif /* #ifndef RCU_TREE_NONCORE */ + +#ifdef CONFIG_RCU_TRACE +#ifdef CONFIG_RCU_NOCB_CPU +/* Sum up queue lengths for tracing. */ +static inline void rcu_nocb_q_lengths(struct rcu_data *rdp, long *ql, long *qll) +{ + *ql = atomic_long_read(&rdp->nocb_q_count) + rdp->nocb_p_count; + *qll = atomic_long_read(&rdp->nocb_q_count_lazy) + rdp->nocb_p_count_lazy; +} +#else /* #ifdef CONFIG_RCU_NOCB_CPU */ +static inline void rcu_nocb_q_lengths(struct rcu_data *rdp, long *ql, long *qll) +{ + *ql = 0; + *qll = 0; +} +#endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */ +#endif /* #ifdef CONFIG_RCU_TRACE */ diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 5ce3352505e..6cdc372de34 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h @@ -25,6 +25,7 @@ */ #include +#include #include #include @@ -36,6 +37,14 @@ #define RCU_BOOST_PRIO RCU_KTHREAD_PRIO #endif +#ifdef CONFIG_RCU_NOCB_CPU +static cpumask_var_t rcu_nocb_mask; /* CPUs to have callbacks offloaded. */ +static bool have_rcu_nocb_mask; /* Was rcu_nocb_mask allocated? */ +static bool rcu_nocb_poll; /* Offload kthread are to poll. */ +module_param(rcu_nocb_poll, bool, 0444); +static char __initdata nocb_buf[NR_CPUS * 5]; +#endif /* #ifdef CONFIG_RCU_NOCB_CPU */ + /* * Check the RCU kernel configuration parameters and print informative * messages about anything out of the ordinary. If you like #ifdef, you @@ -76,6 +85,18 @@ static void __init rcu_bootup_announce_oddness(void) printk(KERN_INFO "\tExperimental boot-time adjustment of leaf fanout to %d.\n", rcu_fanout_leaf); if (nr_cpu_ids != NR_CPUS) printk(KERN_INFO "\tRCU restricting CPUs from NR_CPUS=%d to nr_cpu_ids=%d.\n", NR_CPUS, nr_cpu_ids); +#ifdef CONFIG_RCU_NOCB_CPU + if (have_rcu_nocb_mask) { + if (cpumask_test_cpu(0, rcu_nocb_mask)) { + cpumask_clear_cpu(0, rcu_nocb_mask); + pr_info("\tCPU 0: illegal no-CBs CPU (cleared).\n"); + } + cpulist_scnprintf(nocb_buf, sizeof(nocb_buf), rcu_nocb_mask); + pr_info("\tExperimental no-CBs CPUs: %s.\n", nocb_buf); + if (rcu_nocb_poll) + pr_info("\tExperimental polled no-CBs CPUs.\n"); + } +#endif /* #ifdef CONFIG_RCU_NOCB_CPU */ } #ifdef CONFIG_TREE_PREEMPT_RCU @@ -642,7 +663,7 @@ static void rcu_preempt_do_callbacks(void) */ void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu)) { - __call_rcu(head, func, &rcu_preempt_state, 0); + __call_rcu(head, func, &rcu_preempt_state, -1, 0); } EXPORT_SYMBOL_GPL(call_rcu); @@ -656,7 +677,7 @@ EXPORT_SYMBOL_GPL(call_rcu); void kfree_call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu)) { - __call_rcu(head, func, &rcu_preempt_state, 1); + __call_rcu(head, func, &rcu_preempt_state, -1, 1); } EXPORT_SYMBOL_GPL(kfree_call_rcu); @@ -1025,7 +1046,7 @@ static void rcu_preempt_check_callbacks(int cpu) void kfree_call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu)) { - __call_rcu(head, func, &rcu_sched_state, 1); + __call_rcu(head, func, &rcu_sched_state, -1, 1); } EXPORT_SYMBOL_GPL(kfree_call_rcu); @@ -2104,3 +2125,373 @@ static void increment_cpu_stall_ticks(void) } #endif /* #else #ifdef CONFIG_RCU_CPU_STALL_INFO */ + +#ifdef CONFIG_RCU_NOCB_CPU + +/* + * Offload callback processing from the boot-time-specified set of CPUs + * specified by rcu_nocb_mask. For each CPU in the set, there is a + * kthread created that pulls the callbacks from the corresponding CPU, + * waits for a grace period to elapse, and invokes the callbacks. + * The no-CBs CPUs do a wake_up() on their kthread when they insert + * a callback into any empty list, unless the rcu_nocb_poll boot parameter + * has been specified, in which case each kthread actively polls its + * CPU. (Which isn't so great for energy efficiency, but which does + * reduce RCU's overhead on that CPU.) + * + * This is intended to be used in conjunction with Frederic Weisbecker's + * adaptive-idle work, which would seriously reduce OS jitter on CPUs + * running CPU-bound user-mode computations. + * + * Offloading of callback processing could also in theory be used as + * an energy-efficiency measure because CPUs with no RCU callbacks + * queued are more aggressive about entering dyntick-idle mode. + */ + + +/* Parse the boot-time rcu_nocb_mask CPU list from the kernel parameters. */ +static int __init rcu_nocb_setup(char *str) +{ + alloc_bootmem_cpumask_var(&rcu_nocb_mask); + have_rcu_nocb_mask = true; + cpulist_parse(str, rcu_nocb_mask); + return 1; +} +__setup("rcu_nocbs=", rcu_nocb_setup); + +/* Is the specified CPU a no-CPUs CPU? */ +static bool is_nocb_cpu(int cpu) +{ + if (have_rcu_nocb_mask) + return cpumask_test_cpu(cpu, rcu_nocb_mask); + return false; +} + +/* + * Enqueue the specified string of rcu_head structures onto the specified + * CPU's no-CBs lists. The CPU is specified by rdp, the head of the + * string by rhp, and the tail of the string by rhtp. The non-lazy/lazy + * counts are supplied by rhcount and rhcount_lazy. + * + * If warranted, also wake up the kthread servicing this CPUs queues. + */ +static void __call_rcu_nocb_enqueue(struct rcu_data *rdp, + struct rcu_head *rhp, + struct rcu_head **rhtp, + int rhcount, int rhcount_lazy) +{ + int len; + struct rcu_head **old_rhpp; + struct task_struct *t; + + /* Enqueue the callback on the nocb list and update counts. */ + old_rhpp = xchg(&rdp->nocb_tail, rhtp); + ACCESS_ONCE(*old_rhpp) = rhp; + atomic_long_add(rhcount, &rdp->nocb_q_count); + atomic_long_add(rhcount_lazy, &rdp->nocb_q_count_lazy); + + /* If we are not being polled and there is a kthread, awaken it ... */ + t = ACCESS_ONCE(rdp->nocb_kthread); + if (rcu_nocb_poll | !t) + return; + len = atomic_long_read(&rdp->nocb_q_count); + if (old_rhpp == &rdp->nocb_head) { + wake_up(&rdp->nocb_wq); /* ... only if queue was empty ... */ + rdp->qlen_last_fqs_check = 0; + } else if (len > rdp->qlen_last_fqs_check + qhimark) { + wake_up_process(t); /* ... or if many callbacks queued. */ + rdp->qlen_last_fqs_check = LONG_MAX / 2; + } + return; +} + +/* + * This is a helper for __call_rcu(), which invokes this when the normal + * callback queue is inoperable. If this is not a no-CBs CPU, this + * function returns failure back to __call_rcu(), which can complain + * appropriately. + * + * Otherwise, this function queues the callback where the corresponding + * "rcuo" kthread can find it. + */ +static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, + bool lazy) +{ + + if (!is_nocb_cpu(rdp->cpu)) + return 0; + __call_rcu_nocb_enqueue(rdp, rhp, &rhp->next, 1, lazy); + return 1; +} + +/* + * Adopt orphaned callbacks on a no-CBs CPU, or return 0 if this is + * not a no-CBs CPU. + */ +static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, + struct rcu_data *rdp) +{ + long ql = rsp->qlen; + long qll = rsp->qlen_lazy; + + /* If this is not a no-CBs CPU, tell the caller to do it the old way. */ + if (!is_nocb_cpu(smp_processor_id())) + return 0; + rsp->qlen = 0; + rsp->qlen_lazy = 0; + + /* First, enqueue the donelist, if any. This preserves CB ordering. */ + if (rsp->orphan_donelist != NULL) { + __call_rcu_nocb_enqueue(rdp, rsp->orphan_donelist, + rsp->orphan_donetail, ql, qll); + ql = qll = 0; + rsp->orphan_donelist = NULL; + rsp->orphan_donetail = &rsp->orphan_donelist; + } + if (rsp->orphan_nxtlist != NULL) { + __call_rcu_nocb_enqueue(rdp, rsp->orphan_nxtlist, + rsp->orphan_nxttail, ql, qll); + ql = qll = 0; + rsp->orphan_nxtlist = NULL; + rsp->orphan_nxttail = &rsp->orphan_nxtlist; + } + return 1; +} + +/* + * There must be at least one non-no-CBs CPU in operation at any given + * time, because no-CBs CPUs are not capable of initiating grace periods + * independently. This function therefore complains if the specified + * CPU is the last non-no-CBs CPU, allowing the CPU-hotplug system to + * avoid offlining the last such CPU. (Recursion is a wonderful thing, + * but you have to have a base case!) + */ +static bool nocb_cpu_expendable(int cpu) +{ + cpumask_var_t non_nocb_cpus; + int ret; + + /* + * If there are no no-CB CPUs or if this CPU is not a no-CB CPU, + * then offlining this CPU is harmless. Let it happen. + */ + if (!have_rcu_nocb_mask || is_nocb_cpu(cpu)) + return 1; + + /* If no memory, play it safe and keep the CPU around. */ + if (!alloc_cpumask_var(&non_nocb_cpus, GFP_NOIO)) + return 0; + cpumask_andnot(non_nocb_cpus, cpu_online_mask, rcu_nocb_mask); + cpumask_clear_cpu(cpu, non_nocb_cpus); + ret = !cpumask_empty(non_nocb_cpus); + free_cpumask_var(non_nocb_cpus); + return ret; +} + +/* + * Helper structure for remote registry of RCU callbacks. + * This is needed for when a no-CBs CPU needs to start a grace period. + * If it just invokes call_rcu(), the resulting callback will be queued, + * which can result in deadlock. + */ +struct rcu_head_remote { + struct rcu_head *rhp; + call_rcu_func_t *crf; + void (*func)(struct rcu_head *rhp); +}; + +/* + * Register a callback as specified by the rcu_head_remote struct. + * This function is intended to be invoked via smp_call_function_single(). + */ +static void call_rcu_local(void *arg) +{ + struct rcu_head_remote *rhrp = + container_of(arg, struct rcu_head_remote, rhp); + + rhrp->crf(rhrp->rhp, rhrp->func); +} + +/* + * Set up an rcu_head_remote structure and the invoke call_rcu_local() + * on CPU 0 (which is guaranteed to be a non-no-CBs CPU) via + * smp_call_function_single(). + */ +static void invoke_crf_remote(struct rcu_head *rhp, + void (*func)(struct rcu_head *rhp), + call_rcu_func_t crf) +{ + struct rcu_head_remote rhr; + + rhr.rhp = rhp; + rhr.crf = crf; + rhr.func = func; + smp_call_function_single(0, call_rcu_local, &rhr, 1); +} + +/* + * Helper functions to be passed to wait_rcu_gp(), each of which + * invokes invoke_crf_remote() to register a callback appropriately. + */ +static void __maybe_unused +call_rcu_preempt_remote(struct rcu_head *rhp, + void (*func)(struct rcu_head *rhp)) +{ + invoke_crf_remote(rhp, func, call_rcu); +} +static void call_rcu_bh_remote(struct rcu_head *rhp, + void (*func)(struct rcu_head *rhp)) +{ + invoke_crf_remote(rhp, func, call_rcu_bh); +} +static void call_rcu_sched_remote(struct rcu_head *rhp, + void (*func)(struct rcu_head *rhp)) +{ + invoke_crf_remote(rhp, func, call_rcu_sched); +} + +/* + * Per-rcu_data kthread, but only for no-CBs CPUs. Each kthread invokes + * callbacks queued by the corresponding no-CBs CPU. + */ +static int rcu_nocb_kthread(void *arg) +{ + int c, cl; + struct rcu_head *list; + struct rcu_head *next; + struct rcu_head **tail; + struct rcu_data *rdp = arg; + + /* Each pass through this loop invokes one batch of callbacks */ + for (;;) { + /* If not polling, wait for next batch of callbacks. */ + if (!rcu_nocb_poll) + wait_event(rdp->nocb_wq, rdp->nocb_head); + list = ACCESS_ONCE(rdp->nocb_head); + if (!list) { + schedule_timeout_interruptible(1); + continue; + } + + /* + * Extract queued callbacks, update counts, and wait + * for a grace period to elapse. + */ + ACCESS_ONCE(rdp->nocb_head) = NULL; + tail = xchg(&rdp->nocb_tail, &rdp->nocb_head); + c = atomic_long_xchg(&rdp->nocb_q_count, 0); + cl = atomic_long_xchg(&rdp->nocb_q_count_lazy, 0); + ACCESS_ONCE(rdp->nocb_p_count) += c; + ACCESS_ONCE(rdp->nocb_p_count_lazy) += cl; + wait_rcu_gp(rdp->rsp->call_remote); + + /* Each pass through the following loop invokes a callback. */ + trace_rcu_batch_start(rdp->rsp->name, cl, c, -1); + c = cl = 0; + while (list) { + next = list->next; + /* Wait for enqueuing to complete, if needed. */ + while (next == NULL && &list->next != tail) { + schedule_timeout_interruptible(1); + next = list->next; + } + debug_rcu_head_unqueue(list); + local_bh_disable(); + if (__rcu_reclaim(rdp->rsp->name, list)) + cl++; + c++; + local_bh_enable(); + list = next; + } + trace_rcu_batch_end(rdp->rsp->name, c, !!list, 0, 0, 1); + ACCESS_ONCE(rdp->nocb_p_count) -= c; + ACCESS_ONCE(rdp->nocb_p_count_lazy) -= cl; + rdp->n_cbs_invoked += c; + } + return 0; +} + +/* Initialize per-rcu_data variables for no-CBs CPUs. */ +static void __init rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp) +{ + rdp->nocb_tail = &rdp->nocb_head; + init_waitqueue_head(&rdp->nocb_wq); +} + +/* Create a kthread for each RCU flavor for each no-CBs CPU. */ +static void __init rcu_spawn_nocb_kthreads(struct rcu_state *rsp) +{ + int cpu; + struct rcu_data *rdp; + struct task_struct *t; + + if (rcu_nocb_mask == NULL) + return; + for_each_cpu(cpu, rcu_nocb_mask) { + rdp = per_cpu_ptr(rsp->rda, cpu); + t = kthread_run(rcu_nocb_kthread, rdp, "rcuo%d", cpu); + BUG_ON(IS_ERR(t)); + ACCESS_ONCE(rdp->nocb_kthread) = t; + } +} + +/* Prevent __call_rcu() from enqueuing callbacks on no-CBs CPUs */ +static void init_nocb_callback_list(struct rcu_data *rdp) +{ + if (rcu_nocb_mask == NULL || + !cpumask_test_cpu(rdp->cpu, rcu_nocb_mask)) + return; + rdp->nxttail[RCU_NEXT_TAIL] = NULL; +} + +/* Initialize the ->call_remote fields in the rcu_state structures. */ +static void __init rcu_init_nocb(void) +{ +#ifdef CONFIG_PREEMPT_RCU + rcu_preempt_state.call_remote = call_rcu_preempt_remote; +#endif /* #ifdef CONFIG_PREEMPT_RCU */ + rcu_bh_state.call_remote = call_rcu_bh_remote; + rcu_sched_state.call_remote = call_rcu_sched_remote; +} + +#else /* #ifdef CONFIG_RCU_NOCB_CPU */ + +static bool is_nocb_cpu(int cpu) +{ + return false; +} + +static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp, + bool lazy) +{ + return 0; +} + +static bool __maybe_unused rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp, + struct rcu_data *rdp) +{ + return 0; +} + +static bool nocb_cpu_expendable(int cpu) +{ + return 1; +} + +static void __init rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp) +{ +} + +static void __init rcu_spawn_nocb_kthreads(struct rcu_state *rsp) +{ +} + +static void init_nocb_callback_list(struct rcu_data *rdp) +{ +} + +static void __init rcu_init_nocb(void) +{ +} + +#endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */ diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index f9512687a6e..3189f9aa3e8 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -113,6 +113,8 @@ static char convert_kthread_status(unsigned int kthread_status) static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) { + long ql, qll; + if (!rdp->beenonline) return; seq_printf(m, "%3d%cc=%ld g=%ld pq=%d qp=%d", @@ -126,8 +128,11 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) rdp->dynticks->dynticks_nmi_nesting, rdp->dynticks_fqs); seq_printf(m, " of=%lu", rdp->offline_fqs); + rcu_nocb_q_lengths(rdp, &ql, &qll); + qll += rdp->qlen_lazy; + ql += rdp->qlen; seq_printf(m, " ql=%ld/%ld qs=%c%c%c%c", - rdp->qlen_lazy, rdp->qlen, + qll, ql, ".N"[rdp->nxttail[RCU_NEXT_READY_TAIL] != rdp->nxttail[RCU_NEXT_TAIL]], ".R"[rdp->nxttail[RCU_WAIT_TAIL] != -- cgit v1.2.3 From c635a4e1c24e9396db10ed7424b2084908b32252 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 29 Oct 2012 07:29:20 -0700 Subject: rcu: Separate accounting of callbacks from callback-free CPUs Currently, callback invocations from callback-free CPUs are accounted to the CPU that registered the callback, but using the same field that is used for normal callbacks. This makes it impossible to determine from debugfs output whether callbacks are in fact being diverted. This commit therefore adds a separate ->n_nocbs_invoked field in the rcu_data structure in which diverted callback invocations are counted. RCU's debugfs tracing still displays normal callback invocations using ci=, but displayed diverted callbacks with nci=. Signed-off-by: Paul E. McKenney Signed-off-by: Paul E. McKenney --- kernel/rcutree.h | 1 + kernel/rcutree_plugin.h | 2 +- kernel/rcutree_trace.c | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/kernel/rcutree.h b/kernel/rcutree.h index 488f2ec6b66..4b69291b093 100644 --- a/kernel/rcutree.h +++ b/kernel/rcutree.h @@ -287,6 +287,7 @@ struct rcu_data { long qlen_last_fqs_check; /* qlen at last check for QS forcing */ unsigned long n_cbs_invoked; /* count of RCU cbs invoked. */ + unsigned long n_nocbs_invoked; /* count of no-CBs RCU cbs invoked. */ unsigned long n_cbs_orphaned; /* RCU cbs orphaned by dying CPU */ unsigned long n_cbs_adopted; /* RCU cbs adopted from dying CPU */ unsigned long n_force_qs_snap; diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 6cdc372de34..f6e5ec2932b 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h @@ -2406,7 +2406,7 @@ static int rcu_nocb_kthread(void *arg) trace_rcu_batch_end(rdp->rsp->name, c, !!list, 0, 0, 1); ACCESS_ONCE(rdp->nocb_p_count) -= c; ACCESS_ONCE(rdp->nocb_p_count_lazy) -= cl; - rdp->n_cbs_invoked += c; + rdp->n_nocbs_invoked += c; } return 0; } diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c index 3189f9aa3e8..0d095dcaa67 100644 --- a/kernel/rcutree_trace.c +++ b/kernel/rcutree_trace.c @@ -148,8 +148,9 @@ static void print_one_rcu_data(struct seq_file *m, struct rcu_data *rdp) per_cpu(rcu_cpu_kthread_loops, rdp->cpu) & 0xffff); #endif /* #ifdef CONFIG_RCU_BOOST */ seq_printf(m, " b=%ld", rdp->blimit); - seq_printf(m, " ci=%lu co=%lu ca=%lu\n", - rdp->n_cbs_invoked, rdp->n_cbs_orphaned, rdp->n_cbs_adopted); + seq_printf(m, " ci=%lu nci=%lu co=%lu ca=%lu\n", + rdp->n_cbs_invoked, rdp->n_nocbs_invoked, + rdp->n_cbs_orphaned, rdp->n_cbs_adopted); } static int show_rcudata(struct seq_file *m, void *v) -- cgit v1.2.3 From 4e79752c25ec221ac1e28f8875b539ed7631a0db Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Wed, 7 Nov 2012 13:35:32 -0800 Subject: sched: Mark RCU reader in sched_show_task() When sched_show_task() is invoked from try_to_freeze_tasks(), there is no RCU read-side critical section, resulting in the following splat: [ 125.780730] =============================== [ 125.780766] [ INFO: suspicious RCU usage. ] [ 125.780804] 3.7.0-rc3+ #988 Not tainted [ 125.780838] ------------------------------- [ 125.780875] /home/rafael/src/linux/kernel/sched/core.c:4497 suspicious rcu_dereference_check() usage! [ 125.780946] [ 125.780946] other info that might help us debug this: [ 125.780946] [ 125.781031] [ 125.781031] rcu_scheduler_active = 1, debug_locks = 0 [ 125.781087] 4 locks held by s2ram/4211: [ 125.781120] #0: (&buffer->mutex){+.+.+.}, at: [] sysfs_write_file+0x3f/0x160 [ 125.781233] #1: (s_active#94){.+.+.+}, at: [] sysfs_write_file+0xc8/0x160 [ 125.781339] #2: (pm_mutex){+.+.+.}, at: [] pm_suspend+0x81/0x230 [ 125.781439] #3: (tasklist_lock){.?.?..}, at: [] try_to_freeze_tasks+0x2cd/0x3f0 [ 125.781543] [ 125.781543] stack backtrace: [ 125.781584] Pid: 4211, comm: s2ram Not tainted 3.7.0-rc3+ #988 [ 125.781632] Call Trace: [ 125.781662] [] lockdep_rcu_suspicious+0x103/0x140 [ 125.781719] [] sched_show_task+0x121/0x180 [ 125.781770] [] try_to_freeze_tasks+0x394/0x3f0 [ 125.781823] [] freeze_kernel_threads+0x25/0x80 [ 125.781876] [] pm_suspend+0x165/0x230 [ 125.781924] [] state_store+0x99/0x100 [ 125.781975] [] kobj_attr_store+0x17/0x20 [ 125.782038] [] sysfs_write_file+0xe1/0x160 [ 125.782091] [] vfs_write+0xc6/0x180 [ 125.782138] [] sys_write+0x5a/0xa0 [ 125.782185] [] ? trace_hardirqs_on_thunk+0x3a/0x3f [ 125.782242] [] system_call_fastpath+0x16/0x1b This commit therefore adds the needed RCU read-side critical section. Reported-by: "Rafael J. Wysocki" Signed-off-by: Paul E. McKenney --- kernel/sched/core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 6d4569e0924..36f260864f6 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -4474,6 +4474,7 @@ static const char stat_nam[] = TASK_STATE_TO_CHAR_STR; void sched_show_task(struct task_struct *p) { unsigned long free = 0; + int ppid; unsigned state; state = p->state ? __ffs(p->state) + 1 : 0; @@ -4493,8 +4494,11 @@ void sched_show_task(struct task_struct *p) #ifdef CONFIG_DEBUG_STACK_USAGE free = stack_not_used(p); #endif + rcu_read_lock(); + ppid = task_pid_nr(rcu_dereference(p->real_parent)); + rcu_read_unlock(); printk(KERN_CONT "%5lu %5d %6d 0x%08lx\n", free, - task_pid_nr(p), task_pid_nr(rcu_dereference(p->real_parent)), + task_pid_nr(p), ppid, (unsigned long)task_thread_info(p)->flags); show_stack(p, NULL); -- cgit v1.2.3 From fa0cbbf145aabbf29c6f28f8a11935c0b0fd86fc Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Mon, 12 Nov 2012 17:53:04 -0800 Subject: mm, oom: reintroduce /proc/pid/oom_adj This is mostly a revert of 01dc52ebdf47 ("oom: remove deprecated oom_adj") from Davidlohr Bueso. It reintroduces /proc/pid/oom_adj for backwards compatibility with earlier kernels. It simply scales the value linearly when /proc/pid/oom_score_adj is written. The major difference is that its scheduled removal is no longer included in Documentation/feature-removal-schedule.txt. We do warn users with a single printk, though, to suggest the more powerful and supported /proc/pid/oom_score_adj interface. Reported-by: Artem S. Tashkinov Signed-off-by: David Rientjes Signed-off-by: Linus Torvalds --- Documentation/filesystems/proc.txt | 16 ++++-- fs/proc/base.c | 109 +++++++++++++++++++++++++++++++++++++ include/uapi/linux/oom.h | 9 +++ 3 files changed, 130 insertions(+), 4 deletions(-) diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index a1793d670cd..3844d21d6ca 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -33,7 +33,7 @@ Table of Contents 2 Modifying System Parameters 3 Per-Process Parameters - 3.1 /proc//oom_score_adj - Adjust the oom-killer + 3.1 /proc//oom_adj & /proc//oom_score_adj - Adjust the oom-killer score 3.2 /proc//oom_score - Display current oom-killer score 3.3 /proc//io - Display the IO accounting fields @@ -1320,10 +1320,10 @@ of the kernel. CHAPTER 3: PER-PROCESS PARAMETERS ------------------------------------------------------------------------------ -3.1 /proc//oom_score_adj- Adjust the oom-killer score +3.1 /proc//oom_adj & /proc//oom_score_adj- Adjust the oom-killer score -------------------------------------------------------------------------------- -This file can be used to adjust the badness heuristic used to select which +These file can be used to adjust the badness heuristic used to select which process gets killed in out of memory conditions. The badness heuristic assigns a value to each candidate task ranging from 0 @@ -1361,6 +1361,12 @@ same system, cpuset, mempolicy, or memory controller resources to use at least equivalent to discounting 50% of the task's allowed memory from being considered as scoring against the task. +For backwards compatibility with previous kernels, /proc//oom_adj may also +be used to tune the badness score. Its acceptable values range from -16 +(OOM_ADJUST_MIN) to +15 (OOM_ADJUST_MAX) and a special value of -17 +(OOM_DISABLE) to disable oom killing entirely for that task. Its value is +scaled linearly with /proc//oom_score_adj. + The value of /proc//oom_score_adj may be reduced no lower than the last value set by a CAP_SYS_RESOURCE process. To reduce the value any lower requires CAP_SYS_RESOURCE. @@ -1375,7 +1381,9 @@ minimal amount of work. ------------------------------------------------------------- This file can be used to check the current score used by the oom-killer is for -any given . +any given . Use it together with /proc//oom_score_adj to tune which +process should be killed in an out-of-memory situation. + 3.3 /proc//io - Display the IO accounting fields ------------------------------------------------------- diff --git a/fs/proc/base.c b/fs/proc/base.c index 144a96732dd..3c231adf845 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -873,6 +873,113 @@ static const struct file_operations proc_environ_operations = { .release = mem_release, }; +static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count, + loff_t *ppos) +{ + struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode); + char buffer[PROC_NUMBUF]; + int oom_adj = OOM_ADJUST_MIN; + size_t len; + unsigned long flags; + + if (!task) + return -ESRCH; + if (lock_task_sighand(task, &flags)) { + if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MAX) + oom_adj = OOM_ADJUST_MAX; + else + oom_adj = (task->signal->oom_score_adj * -OOM_DISABLE) / + OOM_SCORE_ADJ_MAX; + unlock_task_sighand(task, &flags); + } + put_task_struct(task); + len = snprintf(buffer, sizeof(buffer), "%d\n", oom_adj); + return simple_read_from_buffer(buf, count, ppos, buffer, len); +} + +static ssize_t oom_adj_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct task_struct *task; + char buffer[PROC_NUMBUF]; + int oom_adj; + unsigned long flags; + int err; + + memset(buffer, 0, sizeof(buffer)); + if (count > sizeof(buffer) - 1) + count = sizeof(buffer) - 1; + if (copy_from_user(buffer, buf, count)) { + err = -EFAULT; + goto out; + } + + err = kstrtoint(strstrip(buffer), 0, &oom_adj); + if (err) + goto out; + if ((oom_adj < OOM_ADJUST_MIN || oom_adj > OOM_ADJUST_MAX) && + oom_adj != OOM_DISABLE) { + err = -EINVAL; + goto out; + } + + task = get_proc_task(file->f_path.dentry->d_inode); + if (!task) { + err = -ESRCH; + goto out; + } + + task_lock(task); + if (!task->mm) { + err = -EINVAL; + goto err_task_lock; + } + + if (!lock_task_sighand(task, &flags)) { + err = -ESRCH; + goto err_task_lock; + } + + /* + * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum + * value is always attainable. + */ + if (oom_adj == OOM_ADJUST_MAX) + oom_adj = OOM_SCORE_ADJ_MAX; + else + oom_adj = (oom_adj * OOM_SCORE_ADJ_MAX) / -OOM_DISABLE; + + if (oom_adj < task->signal->oom_score_adj && + !capable(CAP_SYS_RESOURCE)) { + err = -EACCES; + goto err_sighand; + } + + /* + * /proc/pid/oom_adj is provided for legacy purposes, ask users to use + * /proc/pid/oom_score_adj instead. + */ + printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n", + current->comm, task_pid_nr(current), task_pid_nr(task), + task_pid_nr(task)); + + task->signal->oom_score_adj = oom_adj; + trace_oom_score_adj_update(task); +err_sighand: + unlock_task_sighand(task, &flags); +err_task_lock: + task_unlock(task); + put_task_struct(task); +out: + return err < 0 ? err : count; +} + +static const struct file_operations proc_oom_adj_operations = { + .read = oom_adj_read, + .write = oom_adj_write, + .llseek = generic_file_llseek, +}; + static ssize_t oom_score_adj_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -2598,6 +2705,7 @@ static const struct pid_entry tgid_base_stuff[] = { REG("cgroup", S_IRUGO, proc_cgroup_operations), #endif INF("oom_score", S_IRUGO, proc_oom_score), + REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), #ifdef CONFIG_AUDITSYSCALL REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), @@ -2964,6 +3072,7 @@ static const struct pid_entry tid_base_stuff[] = { REG("cgroup", S_IRUGO, proc_cgroup_operations), #endif INF("oom_score", S_IRUGO, proc_oom_score), + REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adj_operations), REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations), #ifdef CONFIG_AUDITSYSCALL REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations), diff --git a/include/uapi/linux/oom.h b/include/uapi/linux/oom.h index a49c4afc706..b29272d621c 100644 --- a/include/uapi/linux/oom.h +++ b/include/uapi/linux/oom.h @@ -8,4 +8,13 @@ #define OOM_SCORE_ADJ_MIN (-1000) #define OOM_SCORE_ADJ_MAX 1000 +/* + * /proc//oom_adj set to -17 protects from the oom killer for legacy + * purposes. + */ +#define OOM_DISABLE (-17) +/* inclusive */ +#define OOM_ADJUST_MIN (-16) +#define OOM_ADJUST_MAX 15 + #endif /* _UAPI__INCLUDE_LINUX_OOM_H */ -- cgit v1.2.3 From d3fb695576fc7f9d045da9e1ef001d94b0eea3cb Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 15 Nov 2012 08:58:27 +0800 Subject: Thermal: Add Linux/Thermal subsystem info in MAINTAINER file All the changes made to the generic thermal layer, or platform thermal drivers that make use of the thermal layer, should be sent to linux-pm@vger.kernel.org for discussion. And as the maintainer, I will only apply the patches that have been sent to linux-pm@vger.kernel.org. Signed-off-by: Zhang Rui Signed-off-by: Linus Torvalds --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index ff8e763eaa5..bb0b27db673 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7259,6 +7259,14 @@ L: linux-xtensa@linux-xtensa.org S: Maintained F: arch/xtensa/ +THERMAL +M: Zhang Rui +L: linux-pm@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git +S: Supported +F: drivers/thermal/ +F: include/linux/thermal.h + THINKPAD ACPI EXTRAS DRIVER M: Henrique de Moraes Holschuh L: ibm-acpi-devel@lists.sourceforge.net -- cgit v1.2.3 From 976a702ac9eeacea09e588456ab165dc06f9ee83 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 16 Nov 2012 05:31:53 +0000 Subject: tcp: handle tcp_net_metrics_init() order-5 memory allocation failures order-5 allocations can fail with current kernels, we should try vmalloc() as well. Reported-by: Julien Tinnes Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp_metrics.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 53bc5847bfa..f696d7c2e9f 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -9,6 +8,7 @@ #include #include #include +#include #include #include @@ -1034,7 +1034,10 @@ static int __net_init tcp_net_metrics_init(struct net *net) net->ipv4.tcp_metrics_hash_log = order_base_2(slots); size = sizeof(struct tcpm_hash_bucket) << net->ipv4.tcp_metrics_hash_log; - net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL); + net->ipv4.tcp_metrics_hash = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); + if (!net->ipv4.tcp_metrics_hash) + net->ipv4.tcp_metrics_hash = vzalloc(size); + if (!net->ipv4.tcp_metrics_hash) return -ENOMEM; @@ -1055,7 +1058,10 @@ static void __net_exit tcp_net_metrics_exit(struct net *net) tm = next; } } - kfree(net->ipv4.tcp_metrics_hash); + if (is_vmalloc_addr(net->ipv4.tcp_metrics_hash)) + vfree(net->ipv4.tcp_metrics_hash); + else + kfree(net->ipv4.tcp_metrics_hash); } static __net_initdata struct pernet_operations tcp_net_metrics_ops = { -- cgit v1.2.3 From 7dbce021a6df9d4812385d11729140829abc3f95 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 16 Nov 2012 19:33:45 +0100 Subject: ipack: move header files to include/linux Move ipack header files to include/linux/ directory where they belong. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/ipack/carriers/tpci200.h | 3 +- drivers/ipack/devices/ipoctal.c | 3 +- drivers/ipack/ipack.c | 3 +- drivers/ipack/ipack.h | 215 --------------------------------------- include/linux/ipack.h | 213 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 218 insertions(+), 219 deletions(-) delete mode 100644 drivers/ipack/ipack.h create mode 100644 include/linux/ipack.h diff --git a/drivers/ipack/carriers/tpci200.h b/drivers/ipack/carriers/tpci200.h index 8d9be277b34..a7a151dab83 100644 --- a/drivers/ipack/carriers/tpci200.h +++ b/drivers/ipack/carriers/tpci200.h @@ -20,8 +20,7 @@ #include #include #include - -#include "../ipack.h" +#include #define TPCI200_NB_SLOT 0x4 #define TPCI200_NB_BAR 0x6 diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index 783f120338d..7f568e268a1 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -22,7 +22,8 @@ #include #include #include -#include "../ipack.h" +#include +#include "../ipack_ids.h" #include "ipoctal.h" #include "scc2698.h" diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c index 6d5079de52b..cc5498347ac 100644 --- a/drivers/ipack/ipack.c +++ b/drivers/ipack/ipack.c @@ -13,7 +13,8 @@ #include #include #include -#include "ipack.h" +#include +#include "ipack_ids.h" #define to_ipack_dev(device) container_of(device, struct ipack_device, dev) #define to_ipack_driver(drv) container_of(drv, struct ipack_driver, driver) diff --git a/drivers/ipack/ipack.h b/drivers/ipack/ipack.h deleted file mode 100644 index 6760bfaf0ac..00000000000 --- a/drivers/ipack/ipack.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Industry-pack bus. - * - * Copyright (C) 2011-2012 CERN (www.cern.ch) - * Author: Samuel Iglesias Gonsalvez - * - * 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; version 2 of the License. - */ - -#include -#include -#include - -#include "ipack_ids.h" - -#define IPACK_IDPROM_OFFSET_I 0x01 -#define IPACK_IDPROM_OFFSET_P 0x03 -#define IPACK_IDPROM_OFFSET_A 0x05 -#define IPACK_IDPROM_OFFSET_C 0x07 -#define IPACK_IDPROM_OFFSET_MANUFACTURER_ID 0x09 -#define IPACK_IDPROM_OFFSET_MODEL 0x0B -#define IPACK_IDPROM_OFFSET_REVISION 0x0D -#define IPACK_IDPROM_OFFSET_RESERVED 0x0F -#define IPACK_IDPROM_OFFSET_DRIVER_ID_L 0x11 -#define IPACK_IDPROM_OFFSET_DRIVER_ID_H 0x13 -#define IPACK_IDPROM_OFFSET_NUM_BYTES 0x15 -#define IPACK_IDPROM_OFFSET_CRC 0x17 - -struct ipack_bus_ops; -struct ipack_driver; - -enum ipack_space { - IPACK_IO_SPACE = 0, - IPACK_ID_SPACE, - IPACK_INT_SPACE, - IPACK_MEM8_SPACE, - IPACK_MEM16_SPACE, - /* Dummy for counting the number of entries. Must remain the last - * entry */ - IPACK_SPACE_COUNT, -}; - -/** - */ -struct ipack_region { - phys_addr_t start; - size_t size; -}; - -/** - * struct ipack_device - * - * @slot: Slot where the device is plugged in the carrier board - * @bus: ipack_bus_device where the device is plugged to. - * @id_space: Virtual address to ID space. - * @io_space: Virtual address to IO space. - * @mem_space: Virtual address to MEM space. - * @dev: device in kernel representation. - * - * Warning: Direct access to mapped memory is possible but the endianness - * is not the same with PCI carrier or VME carrier. The endianness is managed - * by the carrier board throught bus->ops. - */ -struct ipack_device { - unsigned int slot; - struct ipack_bus_device *bus; - struct device dev; - void (*release) (struct ipack_device *dev); - struct ipack_region region[IPACK_SPACE_COUNT]; - u8 *id; - size_t id_avail; - u32 id_vendor; - u32 id_device; - u8 id_format; - unsigned int id_crc_correct:1; - unsigned int speed_8mhz:1; - unsigned int speed_32mhz:1; -}; - -/** - * struct ipack_driver_ops -- Callbacks to IPack device driver - * - * @probe: Probe function - * @remove: Prepare imminent removal of the device. Services provided by the - * device should be revoked. - */ - -struct ipack_driver_ops { - int (*probe) (struct ipack_device *dev); - void (*remove) (struct ipack_device *dev); -}; - -/** - * struct ipack_driver -- Specific data to each ipack device driver - * - * @driver: Device driver kernel representation - * @ops: Callbacks provided by the IPack device driver - */ -struct ipack_driver { - struct device_driver driver; - const struct ipack_device_id *id_table; - const struct ipack_driver_ops *ops; -}; - -/** - * struct ipack_bus_ops - available operations on a bridge module - * - * @map_space: map IP address space - * @unmap_space: unmap IP address space - * @request_irq: request IRQ - * @free_irq: free IRQ - * @get_clockrate: Returns the clockrate the carrier is currently - * communicating with the device at. - * @set_clockrate: Sets the clock-rate for carrier / module communication. - * Should return -EINVAL if the requested speed is not supported. - * @get_error: Returns the error state for the slot the device is attached - * to. - * @get_timeout: Returns 1 if the communication with the device has - * previously timed out. - * @reset_timeout: Resets the state returned by get_timeout. - */ -struct ipack_bus_ops { - int (*request_irq) (struct ipack_device *dev, - irqreturn_t (*handler)(void *), void *arg); - int (*free_irq) (struct ipack_device *dev); - int (*get_clockrate) (struct ipack_device *dev); - int (*set_clockrate) (struct ipack_device *dev, int mherz); - int (*get_error) (struct ipack_device *dev); - int (*get_timeout) (struct ipack_device *dev); - int (*reset_timeout) (struct ipack_device *dev); -}; - -/** - * struct ipack_bus_device - * - * @dev: pointer to carrier device - * @slots: number of slots available - * @bus_nr: ipack bus number - * @ops: bus operations for the mezzanine drivers - */ -struct ipack_bus_device { - struct device *parent; - int slots; - int bus_nr; - const struct ipack_bus_ops *ops; -}; - -/** - * ipack_bus_register -- register a new ipack bus - * - * @parent: pointer to the parent device, if any. - * @slots: number of slots available in the bus device. - * @ops: bus operations for the mezzanine drivers. - * - * The carrier board device should call this function to register itself as - * available bus device in ipack. - */ -struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, - const struct ipack_bus_ops *ops); - -/** - * ipack_bus_unregister -- unregister an ipack bus - */ -int ipack_bus_unregister(struct ipack_bus_device *bus); - -/** - * ipack_driver_register -- Register a new ipack device driver - * - * Called by a ipack driver to register itself as a driver - * that can manage ipack devices. - */ -int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, - const char *name); -void ipack_driver_unregister(struct ipack_driver *edrv); - -/** - * ipack_device_register -- register an IPack device with the kernel - * @dev: the new device to register. - * - * Register a new IPack device ("module" in IndustryPack jargon). The call - * is done by the carrier driver. The carrier should populate the fields - * bus and slot as well as the region array of @dev prior to calling this - * function. The rest of the fields will be allocated and populated - * during registration. - * - * Return zero on success or error code on failure. - */ -int ipack_device_register(struct ipack_device *dev); -void ipack_device_unregister(struct ipack_device *dev); - -/** - * DEFINE_IPACK_DEVICE_TABLE - macro used to describe a IndustryPack table - * @_table: device table name - * - * This macro is used to create a struct ipack_device_id array (a device table) - * in a generic manner. - */ -#define DEFINE_IPACK_DEVICE_TABLE(_table) \ - const struct ipack_device_id _table[] __devinitconst - -/** - * IPACK_DEVICE - macro used to describe a specific IndustryPack device - * @_format: the format version (currently either 1 or 2, 8 bit value) - * @vend: the 8 or 24 bit IndustryPack Vendor ID - * @dev: the 8 or 16 bit IndustryPack Device ID - * - * This macro is used to create a struct ipack_device_id that matches a specific - * device. - */ -#define IPACK_DEVICE(_format, vend, dev) \ - .format = (_format), \ - .vendor = (vend), \ - .device = (dev) diff --git a/include/linux/ipack.h b/include/linux/ipack.h new file mode 100644 index 00000000000..7a0a3085ab5 --- /dev/null +++ b/include/linux/ipack.h @@ -0,0 +1,213 @@ +/* + * Industry-pack bus. + * + * Copyright (C) 2011-2012 CERN (www.cern.ch) + * Author: Samuel Iglesias Gonsalvez + * + * 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; version 2 of the License. + */ + +#include +#include +#include + +#define IPACK_IDPROM_OFFSET_I 0x01 +#define IPACK_IDPROM_OFFSET_P 0x03 +#define IPACK_IDPROM_OFFSET_A 0x05 +#define IPACK_IDPROM_OFFSET_C 0x07 +#define IPACK_IDPROM_OFFSET_MANUFACTURER_ID 0x09 +#define IPACK_IDPROM_OFFSET_MODEL 0x0B +#define IPACK_IDPROM_OFFSET_REVISION 0x0D +#define IPACK_IDPROM_OFFSET_RESERVED 0x0F +#define IPACK_IDPROM_OFFSET_DRIVER_ID_L 0x11 +#define IPACK_IDPROM_OFFSET_DRIVER_ID_H 0x13 +#define IPACK_IDPROM_OFFSET_NUM_BYTES 0x15 +#define IPACK_IDPROM_OFFSET_CRC 0x17 + +struct ipack_bus_ops; +struct ipack_driver; + +enum ipack_space { + IPACK_IO_SPACE = 0, + IPACK_ID_SPACE, + IPACK_INT_SPACE, + IPACK_MEM8_SPACE, + IPACK_MEM16_SPACE, + /* Dummy for counting the number of entries. Must remain the last + * entry */ + IPACK_SPACE_COUNT, +}; + +/** + */ +struct ipack_region { + phys_addr_t start; + size_t size; +}; + +/** + * struct ipack_device + * + * @slot: Slot where the device is plugged in the carrier board + * @bus: ipack_bus_device where the device is plugged to. + * @id_space: Virtual address to ID space. + * @io_space: Virtual address to IO space. + * @mem_space: Virtual address to MEM space. + * @dev: device in kernel representation. + * + * Warning: Direct access to mapped memory is possible but the endianness + * is not the same with PCI carrier or VME carrier. The endianness is managed + * by the carrier board throught bus->ops. + */ +struct ipack_device { + unsigned int slot; + struct ipack_bus_device *bus; + struct device dev; + void (*release) (struct ipack_device *dev); + struct ipack_region region[IPACK_SPACE_COUNT]; + u8 *id; + size_t id_avail; + u32 id_vendor; + u32 id_device; + u8 id_format; + unsigned int id_crc_correct:1; + unsigned int speed_8mhz:1; + unsigned int speed_32mhz:1; +}; + +/** + * struct ipack_driver_ops -- Callbacks to IPack device driver + * + * @probe: Probe function + * @remove: Prepare imminent removal of the device. Services provided by the + * device should be revoked. + */ + +struct ipack_driver_ops { + int (*probe) (struct ipack_device *dev); + void (*remove) (struct ipack_device *dev); +}; + +/** + * struct ipack_driver -- Specific data to each ipack device driver + * + * @driver: Device driver kernel representation + * @ops: Callbacks provided by the IPack device driver + */ +struct ipack_driver { + struct device_driver driver; + const struct ipack_device_id *id_table; + const struct ipack_driver_ops *ops; +}; + +/** + * struct ipack_bus_ops - available operations on a bridge module + * + * @map_space: map IP address space + * @unmap_space: unmap IP address space + * @request_irq: request IRQ + * @free_irq: free IRQ + * @get_clockrate: Returns the clockrate the carrier is currently + * communicating with the device at. + * @set_clockrate: Sets the clock-rate for carrier / module communication. + * Should return -EINVAL if the requested speed is not supported. + * @get_error: Returns the error state for the slot the device is attached + * to. + * @get_timeout: Returns 1 if the communication with the device has + * previously timed out. + * @reset_timeout: Resets the state returned by get_timeout. + */ +struct ipack_bus_ops { + int (*request_irq) (struct ipack_device *dev, + irqreturn_t (*handler)(void *), void *arg); + int (*free_irq) (struct ipack_device *dev); + int (*get_clockrate) (struct ipack_device *dev); + int (*set_clockrate) (struct ipack_device *dev, int mherz); + int (*get_error) (struct ipack_device *dev); + int (*get_timeout) (struct ipack_device *dev); + int (*reset_timeout) (struct ipack_device *dev); +}; + +/** + * struct ipack_bus_device + * + * @dev: pointer to carrier device + * @slots: number of slots available + * @bus_nr: ipack bus number + * @ops: bus operations for the mezzanine drivers + */ +struct ipack_bus_device { + struct device *parent; + int slots; + int bus_nr; + const struct ipack_bus_ops *ops; +}; + +/** + * ipack_bus_register -- register a new ipack bus + * + * @parent: pointer to the parent device, if any. + * @slots: number of slots available in the bus device. + * @ops: bus operations for the mezzanine drivers. + * + * The carrier board device should call this function to register itself as + * available bus device in ipack. + */ +struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, + const struct ipack_bus_ops *ops); + +/** + * ipack_bus_unregister -- unregister an ipack bus + */ +int ipack_bus_unregister(struct ipack_bus_device *bus); + +/** + * ipack_driver_register -- Register a new ipack device driver + * + * Called by a ipack driver to register itself as a driver + * that can manage ipack devices. + */ +int ipack_driver_register(struct ipack_driver *edrv, struct module *owner, + const char *name); +void ipack_driver_unregister(struct ipack_driver *edrv); + +/** + * ipack_device_register -- register an IPack device with the kernel + * @dev: the new device to register. + * + * Register a new IPack device ("module" in IndustryPack jargon). The call + * is done by the carrier driver. The carrier should populate the fields + * bus and slot as well as the region array of @dev prior to calling this + * function. The rest of the fields will be allocated and populated + * during registration. + * + * Return zero on success or error code on failure. + */ +int ipack_device_register(struct ipack_device *dev); +void ipack_device_unregister(struct ipack_device *dev); + +/** + * DEFINE_IPACK_DEVICE_TABLE - macro used to describe a IndustryPack table + * @_table: device table name + * + * This macro is used to create a struct ipack_device_id array (a device table) + * in a generic manner. + */ +#define DEFINE_IPACK_DEVICE_TABLE(_table) \ + const struct ipack_device_id _table[] __devinitconst + +/** + * IPACK_DEVICE - macro used to describe a specific IndustryPack device + * @_format: the format version (currently either 1 or 2, 8 bit value) + * @vend: the 8 or 24 bit IndustryPack Vendor ID + * @dev: the 8 or 16 bit IndustryPack Device ID + * + * This macro is used to create a struct ipack_device_id that matches a specific + * device. + */ +#define IPACK_DEVICE(_format, vend, dev) \ + .format = (_format), \ + .vendor = (vend), \ + .device = (dev) -- cgit v1.2.3 From 27cf2d1b873fc50a2c0388253ec666fa4c61bfd4 Mon Sep 17 00:00:00 2001 From: Samuel Iglesias Gonsalvez Date: Fri, 16 Nov 2012 19:33:46 +0100 Subject: ipack: remove ipack_ids.h file Its contents are merged into ipack.h. So this file is not needed. Doing that, it simplifies the ipack-related driver development. Signed-off-by: Samuel Iglesias Gonsalvez Signed-off-by: Greg Kroah-Hartman --- drivers/ipack/devices/ipoctal.c | 1 - drivers/ipack/ipack.c | 1 - drivers/ipack/ipack_ids.h | 32 -------------------------------- include/linux/ipack.h | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 34 deletions(-) delete mode 100644 drivers/ipack/ipack_ids.h diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index 7f568e268a1..c06ab396e84 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -23,7 +23,6 @@ #include #include #include -#include "../ipack_ids.h" #include "ipoctal.h" #include "scc2698.h" diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c index cc5498347ac..7ec6b208b1c 100644 --- a/drivers/ipack/ipack.c +++ b/drivers/ipack/ipack.c @@ -14,7 +14,6 @@ #include #include #include -#include "ipack_ids.h" #define to_ipack_dev(device) container_of(device, struct ipack_device, dev) #define to_ipack_driver(drv) container_of(drv, struct ipack_driver, driver) diff --git a/drivers/ipack/ipack_ids.h b/drivers/ipack/ipack_ids.h deleted file mode 100644 index 8153fee3f2f..00000000000 --- a/drivers/ipack/ipack_ids.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * IndustryPack Fromat, Vendor and Device IDs. - */ - -/* ID section format versions */ -#define IPACK_ID_VERSION_INVALID 0x00 -#define IPACK_ID_VERSION_1 0x01 -#define IPACK_ID_VERSION_2 0x02 - -/* Vendors and devices. Sort key: vendor first, device next. */ -#define IPACK1_VENDOR_ID_RESERVED1 0x00 -#define IPACK1_VENDOR_ID_RESERVED2 0xFF -#define IPACK1_VENDOR_ID_UNREGISTRED01 0x01 -#define IPACK1_VENDOR_ID_UNREGISTRED02 0x02 -#define IPACK1_VENDOR_ID_UNREGISTRED03 0x03 -#define IPACK1_VENDOR_ID_UNREGISTRED04 0x04 -#define IPACK1_VENDOR_ID_UNREGISTRED05 0x05 -#define IPACK1_VENDOR_ID_UNREGISTRED06 0x06 -#define IPACK1_VENDOR_ID_UNREGISTRED07 0x07 -#define IPACK1_VENDOR_ID_UNREGISTRED08 0x08 -#define IPACK1_VENDOR_ID_UNREGISTRED09 0x09 -#define IPACK1_VENDOR_ID_UNREGISTRED10 0x0A -#define IPACK1_VENDOR_ID_UNREGISTRED11 0x0B -#define IPACK1_VENDOR_ID_UNREGISTRED12 0x0C -#define IPACK1_VENDOR_ID_UNREGISTRED13 0x0D -#define IPACK1_VENDOR_ID_UNREGISTRED14 0x0E -#define IPACK1_VENDOR_ID_UNREGISTRED15 0x0F - -#define IPACK1_VENDOR_ID_SBS 0xF0 -#define IPACK1_DEVICE_ID_SBS_OCTAL_232 0x22 -#define IPACK1_DEVICE_ID_SBS_OCTAL_422 0x2A -#define IPACK1_DEVICE_ID_SBS_OCTAL_485 0x48 diff --git a/include/linux/ipack.h b/include/linux/ipack.h index 7a0a3085ab5..a360c73129a 100644 --- a/include/linux/ipack.h +++ b/include/linux/ipack.h @@ -26,6 +26,39 @@ #define IPACK_IDPROM_OFFSET_NUM_BYTES 0x15 #define IPACK_IDPROM_OFFSET_CRC 0x17 +/* + * IndustryPack Fromat, Vendor and Device IDs. + */ + +/* ID section format versions */ +#define IPACK_ID_VERSION_INVALID 0x00 +#define IPACK_ID_VERSION_1 0x01 +#define IPACK_ID_VERSION_2 0x02 + +/* Vendors and devices. Sort key: vendor first, device next. */ +#define IPACK1_VENDOR_ID_RESERVED1 0x00 +#define IPACK1_VENDOR_ID_RESERVED2 0xFF +#define IPACK1_VENDOR_ID_UNREGISTRED01 0x01 +#define IPACK1_VENDOR_ID_UNREGISTRED02 0x02 +#define IPACK1_VENDOR_ID_UNREGISTRED03 0x03 +#define IPACK1_VENDOR_ID_UNREGISTRED04 0x04 +#define IPACK1_VENDOR_ID_UNREGISTRED05 0x05 +#define IPACK1_VENDOR_ID_UNREGISTRED06 0x06 +#define IPACK1_VENDOR_ID_UNREGISTRED07 0x07 +#define IPACK1_VENDOR_ID_UNREGISTRED08 0x08 +#define IPACK1_VENDOR_ID_UNREGISTRED09 0x09 +#define IPACK1_VENDOR_ID_UNREGISTRED10 0x0A +#define IPACK1_VENDOR_ID_UNREGISTRED11 0x0B +#define IPACK1_VENDOR_ID_UNREGISTRED12 0x0C +#define IPACK1_VENDOR_ID_UNREGISTRED13 0x0D +#define IPACK1_VENDOR_ID_UNREGISTRED14 0x0E +#define IPACK1_VENDOR_ID_UNREGISTRED15 0x0F + +#define IPACK1_VENDOR_ID_SBS 0xF0 +#define IPACK1_DEVICE_ID_SBS_OCTAL_232 0x22 +#define IPACK1_DEVICE_ID_SBS_OCTAL_422 0x2A +#define IPACK1_DEVICE_ID_SBS_OCTAL_485 0x48 + struct ipack_bus_ops; struct ipack_driver; -- cgit v1.2.3 From baefa31db2f2b13a05d1b81bdf2d20d487f58b0a Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Fri, 16 Nov 2012 09:04:15 +0000 Subject: net-rps: Fix brokeness causing OOO packets In commit c445477d74ab3779 which adds aRFS to the kernel, the CPU selected for RFS is not set correctly when CPU is changing. This is causing OOO packets and probably other issues. Signed-off-by: Tom Herbert Acked-by: Eric Dumazet Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- net/core/dev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index bda6d004f9f..c0946cb2b35 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2818,8 +2818,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, if (unlikely(tcpu != next_cpu) && (tcpu == RPS_NO_CPU || !cpu_online(tcpu) || ((int)(per_cpu(softnet_data, tcpu).input_queue_head - - rflow->last_qtail)) >= 0)) + rflow->last_qtail)) >= 0)) { + tcpu = next_cpu; rflow = set_rps_cpu(dev, skb, rflow, next_cpu); + } if (tcpu != RPS_NO_CPU && cpu_online(tcpu)) { *rflowp = rflow; -- cgit v1.2.3 From a485e827f07bfdd0762059386e6e787bed6e81ee Mon Sep 17 00:00:00 2001 From: Albert Pool Date: Tue, 30 Oct 2012 20:58:06 +0100 Subject: rtlwifi: rtl8192cu: Add new USB ID This is an ISY IWL 2000. Probably a clone of Belkin F7D1102 050d:1102. Its FCC ID is the same. Signed-off-by: Albert Pool Cc: stable@vger.kernel.org Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 9970c2b1b19..b7e6607e6b6 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -297,6 +297,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { /*=== Customer ID ===*/ /****** 8188CU ********/ {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ + {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/ {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ -- cgit v1.2.3 From b1a47aa5e1e159e2cb06d7dfcc17ef5149b09299 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Thu, 15 Nov 2012 15:58:47 -0800 Subject: mwifiex: fix system hang issue in cmd timeout error case Reported by Tim Shepard: I was seeing sporadic failures (wedgeups), and the majority of those failures I saw printed the printouts in mwifiex_cmd_timeout_func with cmd = 0xe5 which is CMD_802_11_HS_CFG_ENH. When this happens, two minutes later I get notified that the rtcwake thread is blocked, like this: INFO: task rtcwake:3495 blocked for more than 120 seconds. To get the hung thread unblocked we wake up the cmd wait queue and cancel the ioctl. Cc: "3.4+" Reported-by: Tim Shepard Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cmdevt.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 8d465107f52..ae9010ed58d 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -890,9 +890,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context) return; } cmd_node = adapter->curr_cmd; - if (cmd_node->wait_q_enabled) - adapter->cmd_wait_q.status = -ETIMEDOUT; - if (cmd_node) { adapter->dbg.timeout_cmd_id = adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; @@ -938,6 +935,14 @@ mwifiex_cmd_timeout_func(unsigned long function_context) dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", adapter->ps_mode, adapter->ps_state); + + if (cmd_node->wait_q_enabled) { + adapter->cmd_wait_q.status = -ETIMEDOUT; + wake_up_interruptible(&adapter->cmd_wait_q.wait); + mwifiex_cancel_pending_ioctl(adapter); + /* reset cmd_sent flag to unblock new commands */ + adapter->cmd_sent = false; + } } if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) mwifiex_init_fw_complete(adapter); -- cgit v1.2.3 From dd321acddc3be1371263b8c9e6c6f2af89f63d57 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Thu, 15 Nov 2012 15:58:48 -0800 Subject: mwifiex: report error to MMC core if we cannot suspend When host_sleep_config command fails we should return error to MMC core to indicate the failure for our device. The misspelled variable is also removed as it's redundant. Cc: "3.0+" Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sdio.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index fc8a9bfa124..82cf0fa2d9f 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -161,7 +161,6 @@ static int mwifiex_sdio_suspend(struct device *dev) struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; mmc_pm_flag_t pm_flag = 0; - int hs_actived = 0; int i; int ret = 0; @@ -188,12 +187,14 @@ static int mwifiex_sdio_suspend(struct device *dev) adapter = card->adapter; /* Enable the Host Sleep */ - hs_actived = mwifiex_enable_hs(adapter); - if (hs_actived) { - pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n"); - ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + if (!mwifiex_enable_hs(adapter)) { + dev_err(adapter->dev, "cmd: failed to suspend\n"); + return -EFAULT; } + dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n"); + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + /* Indicate device suspended */ adapter->is_suspended = true; -- cgit v1.2.3 From 38c1a01cf10c6e4049b4ffbd4a6af655df2a46e1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 16 Nov 2012 20:46:19 +0100 Subject: wireless: add back sysfs directory commit 35b2a113cb0298d4f9a1263338b456094a414057 broke (at least) Fedora's networking scripts, they check for the existence of the wireless directory. As the files aren't used, add the directory back and not the files. Also do it for both drivers based on the old wireless extensions and cfg80211, regardless of whether the compat code for wext is built into cfg80211 or not. Cc: stable@vger.kernel.org [3.6] Reported-by: Dave Airlie Reported-by: Bill Nottingham Signed-off-by: Johannes Berg --- net/core/net-sysfs.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index bcf02f608cb..017a8bacfb2 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -429,6 +429,17 @@ static struct attribute_group netstat_group = { .name = "statistics", .attrs = netstat_attrs, }; + +#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) +static struct attribute *wireless_attrs[] = { + NULL +}; + +static struct attribute_group wireless_group = { + .name = "wireless", + .attrs = wireless_attrs, +}; +#endif #endif /* CONFIG_SYSFS */ #ifdef CONFIG_RPS @@ -1409,6 +1420,15 @@ int netdev_register_kobject(struct net_device *net) groups++; *groups++ = &netstat_group; + +#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) + if (net->ieee80211_ptr) + *groups++ = &wireless_group; +#if IS_ENABLED(CONFIG_WIRELESS_EXT) + else if (net->wireless_handlers) + *groups++ = &wireless_group; +#endif +#endif #endif /* CONFIG_SYSFS */ error = device_add(dev); -- cgit v1.2.3 From 8a66790b7850a6669129af078768a1d42076a0ef Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 16 Nov 2012 21:55:48 +0100 Subject: ACPI / resources: Use AE_CTRL_TERMINATE to terminate resources walks Currently acpi_dev_process_resource() returns AE_ABORT_METHOD to terminate the acpi_walk_resources() it is called from if the .preproc() routine provided by the caller of acpi_dev_get_resources() initiating the resources walk returns an error code. It is better to use AE_CTRL_TERMINATE for this purpose, however, so do that. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg --- drivers/acpi/resource.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 2bafc25482b..4107c004467 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -446,7 +446,7 @@ static acpi_status acpi_dev_process_resource(struct acpi_resource *ares, ret = c->preproc(ares, c->preproc_data); if (ret < 0) { c->error = ret; - return AE_ABORT_METHOD; + return AE_CTRL_TERMINATE; } else if (ret > 0) { return AE_OK; } -- cgit v1.2.3 From 4000e626156935dfb626321ce09cae2c833eabbb Mon Sep 17 00:00:00 2001 From: Kamil Iskra Date: Fri, 16 Nov 2012 22:28:58 +0100 Subject: ACPI / battery: Correct battery capacity values on Thinkpads Add a quirk to correctly report battery capacity on 2010 and 2011 Lenovo Thinkpad models. The affected models that I tested (x201, t410, t410s, and x220) exhibit a problem where, when battery capacity reporting unit is mAh, the values being reported are wrong. Pre-2010 and 2012 models appear to always report in mWh and are thus unaffected. Also, in mid-2012 Lenovo issued a BIOS update for the 2011 models that fixes the issue (tested on x220 with a post-1.29 BIOS). No such update is available for the 2010 models, so those still need this patch. Problem description: for some reason, the affected Thinkpads switch the reporting unit between mAh and mWh; generally, mAh is used when a laptop is plugged in and mWh when it's unplugged, although a suspend/resume or rmmod/modprobe is needed for the switch to take effect. The values reported in mAh are *always* wrong. This does not appear to be a kernel regression; I believe that the values were never reported correctly. I tested back to kernel 2.6.34, with multiple machines and BIOS versions. Simply plugging a laptop into mains before turning it on is enough to reproduce the problem. Here's a sample /proc/acpi/battery/BAT0/info from Thinkpad x220 (before a BIOS update) with a 4-cell battery: present: yes design capacity: 2886 mAh last full capacity: 2909 mAh battery technology: rechargeable design voltage: 14800 mV design capacity warning: 145 mAh design capacity low: 13 mAh cycle count: 0 capacity granularity 1: 1 mAh capacity granularity 2: 1 mAh model number: 42T4899 serial number: 21064 battery type: LION OEM info: SANYO Once the laptop switches the unit to mWh (unplug from mains, suspend, resume), the output changes to: present: yes design capacity: 28860 mWh last full capacity: 29090 mWh battery technology: rechargeable design voltage: 14800 mV design capacity warning: 1454 mWh design capacity low: 200 mWh cycle count: 0 capacity granularity 1: 1 mWh capacity granularity 2: 1 mWh model number: 42T4899 serial number: 21064 battery type: LION OEM info: SANYO Can you see how the values for "design capacity", etc., differ by a factor of 10 instead of 14.8 (the design voltage of this battery)? On the battery itself it says: 14.8V, 1.95Ah, 29Wh, so clearly the values reported in mWh are correct and the ones in mAh are not. My guess is that this problem has been around ever since those machines were released, but because the most common Thinkpad batteries are rated at 10.8V, the error (8%) is small enough that it simply hasn't been noticed or at least nobody could be bothered to look into it. My patch works around the problem by adjusting the incorrectly reported mAh values by "10000 / design_voltage". The patch also has code to figure out if it should be activated or not. It only activates on Lenovo Thinkpads, only when the unit is mAh, and, as an extra precaution, only when the battery capacity reported through ACPI does not match what is reported through DMI (I've never encountered a machine where the first two conditions would be true but the last would not, but better safe than sorry). I've been using this patch for close to a year on several systems without any problems. References: https://bugzilla.kernel.org/show_bug.cgi?id=41062 Acked-by: Henrique de Moraes Holschuh Cc: Signed-off-by: Rafael J. Wysocki --- drivers/acpi/battery.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 45e3e1759fb..7efaeaa53b8 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -34,6 +34,7 @@ #include #include #include +#include #ifdef CONFIG_ACPI_PROCFS_POWER #include @@ -95,6 +96,18 @@ enum { ACPI_BATTERY_ALARM_PRESENT, ACPI_BATTERY_XINFO_PRESENT, ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, + /* On Lenovo Thinkpad models from 2010 and 2011, the power unit + switches between mWh and mAh depending on whether the system + is running on battery or not. When mAh is the unit, most + reported values are incorrect and need to be adjusted by + 10000/design_voltage. Verified on x201, t410, t410s, and x220. + Pre-2010 and 2012 models appear to always report in mWh and + are thus unaffected (tested with t42, t61, t500, x200, x300, + and x230). Also, in mid-2012 Lenovo issued a BIOS update for + the 2011 models that fixes the issue (tested on x220 with a + post-1.29 BIOS), but as of Nov. 2012, no such update is + available for the 2010 models. */ + ACPI_BATTERY_QUIRK_THINKPAD_MAH, }; struct acpi_battery { @@ -438,6 +451,21 @@ static int acpi_battery_get_info(struct acpi_battery *battery) kfree(buffer.pointer); if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) battery->full_charge_capacity = battery->design_capacity; + if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) && + battery->power_unit && battery->design_voltage) { + battery->design_capacity = battery->design_capacity * + 10000 / battery->design_voltage; + battery->full_charge_capacity = battery->full_charge_capacity * + 10000 / battery->design_voltage; + battery->design_capacity_warning = + battery->design_capacity_warning * + 10000 / battery->design_voltage; + /* Curiously, design_capacity_low, unlike the rest of them, + is correct. */ + /* capacity_granularity_* equal 1 on the systems tested, so + it's impossible to tell if they would need an adjustment + or not if their values were higher. */ + } return result; } @@ -486,6 +514,11 @@ static int acpi_battery_get_state(struct acpi_battery *battery) && battery->capacity_now >= 0 && battery->capacity_now <= 100) battery->capacity_now = (battery->capacity_now * battery->full_charge_capacity) / 100; + if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) && + battery->power_unit && battery->design_voltage) { + battery->capacity_now = battery->capacity_now * + 10000 / battery->design_voltage; + } return result; } @@ -595,6 +628,24 @@ static void sysfs_remove_battery(struct acpi_battery *battery) mutex_unlock(&battery->sysfs_lock); } +static void find_battery(const struct dmi_header *dm, void *private) +{ + struct acpi_battery *battery = (struct acpi_battery *)private; + /* Note: the hardcoded offsets below have been extracted from + the source code of dmidecode. */ + if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) { + const u8 *dmi_data = (const u8 *)(dm + 1); + int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6)); + if (dm->length >= 18) + dmi_capacity *= dmi_data[17]; + if (battery->design_capacity * battery->design_voltage / 1000 + != dmi_capacity && + battery->design_capacity * 10 == dmi_capacity) + set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, + &battery->flags); + } +} + /* * According to the ACPI spec, some kinds of primary batteries can * report percentage battery remaining capacity directly to OS. @@ -620,6 +671,32 @@ static void acpi_battery_quirks(struct acpi_battery *battery) battery->capacity_now = (battery->capacity_now * battery->full_charge_capacity) / 100; } + + if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags)) + return ; + + if (battery->power_unit && dmi_name_in_vendors("LENOVO")) { + const char *s; + s = dmi_get_system_info(DMI_PRODUCT_VERSION); + if (s && !strnicmp(s, "ThinkPad", 8)) { + dmi_walk(find_battery, battery); + if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, + &battery->flags) && + battery->design_voltage) { + battery->design_capacity = + battery->design_capacity * + 10000 / battery->design_voltage; + battery->full_charge_capacity = + battery->full_charge_capacity * + 10000 / battery->design_voltage; + battery->design_capacity_warning = + battery->design_capacity_warning * + 10000 / battery->design_voltage; + battery->capacity_now = battery->capacity_now * + 10000 / battery->design_voltage; + } + } + } } static int acpi_battery_update(struct acpi_battery *battery) -- cgit v1.2.3 From 29282fde80d44e587f8c152b10049a56e61659f0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 9 Nov 2012 15:20:17 +0100 Subject: KVM: x86: Fix invalid secondary exec controls in vmx_cpuid_update() The commit [ad756a16: KVM: VMX: Implement PCID/INVPCID for guests with EPT] introduced the unconditional access to SECONDARY_VM_EXEC_CONTROL, and this triggers kernel warnings like below on old CPUs: vmwrite error: reg 401e value a0568000 (err 12) Pid: 13649, comm: qemu-kvm Not tainted 3.7.0-rc4-test2+ #154 Call Trace: [] vmwrite_error+0x27/0x29 [kvm_intel] [] vmcs_writel+0x1b/0x20 [kvm_intel] [] vmx_cpuid_update+0x74/0x170 [kvm_intel] [] kvm_vcpu_ioctl_set_cpuid2+0x76/0x90 [kvm] [] kvm_arch_vcpu_ioctl+0xc37/0xed0 [kvm] [] ? __vunmap+0x9c/0x110 [] ? vmx_vcpu_load+0x39/0x1a0 [kvm_intel] [] ? kvm_arch_vcpu_load+0x52/0x1a0 [kvm] [] ? vcpu_load+0x74/0xd0 [kvm] [] kvm_vcpu_ioctl+0x110/0x5e0 [kvm] [] ? kvm_dev_ioctl+0x4d/0x4a0 [kvm] [] do_vfs_ioctl+0x8f/0x530 [] ? remove_vma+0x56/0x60 [] ? do_munmap+0x328/0x400 [] ? fget_light+0x4c/0x100 [] sys_ioctl+0x91/0xb0 [] system_call_fastpath+0x1a/0x1f This patch adds a check for the availability of secondary exec control to avoid these warnings. Cc: [v3.6+] Signed-off-by: Takashi Iwai Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/vmx.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ad6b1dd06f8..f85815945fc 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -6549,19 +6549,22 @@ static void vmx_cpuid_update(struct kvm_vcpu *vcpu) } } - exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); /* Exposing INVPCID only when PCID is exposed */ best = kvm_find_cpuid_entry(vcpu, 0x7, 0); if (vmx_invpcid_supported() && best && (best->ebx & bit(X86_FEATURE_INVPCID)) && guest_cpuid_has_pcid(vcpu)) { + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); exec_control |= SECONDARY_EXEC_ENABLE_INVPCID; vmcs_write32(SECONDARY_VM_EXEC_CONTROL, exec_control); } else { - exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; - vmcs_write32(SECONDARY_VM_EXEC_CONTROL, - exec_control); + if (cpu_has_secondary_exec_ctrls()) { + exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); + exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID; + vmcs_write32(SECONDARY_VM_EXEC_CONTROL, + exec_control); + } if (best) best->ebx &= ~bit(X86_FEATURE_INVPCID); } -- cgit v1.2.3 From 63c3b902e517012b127d6528434b928ceaa10f7b Mon Sep 17 00:00:00 2001 From: Michel Lespinasse Date: Fri, 16 Nov 2012 14:14:47 -0800 Subject: mm: add anon_vma_lock to validate_mm() Iterating over the vma->anon_vma_chain without anon_vma_lock may cause NULL ptr deref in anon_vma_interval_tree_verify(), because the node in the chain might have been removed. BUG: unable to handle kernel paging request at fffffffffffffff0 IP: [] anon_vma_interval_tree_verify+0xc/0xa0 PGD 4e28067 PUD 4e29067 PMD 0 Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC CPU 0 Pid: 9050, comm: trinity-child64 Tainted: G W 3.7.0-rc2-next-20121025-sasha-00001-g673f98e-dirty #77 RIP: 0010: anon_vma_interval_tree_verify+0xc/0xa0 Process trinity-child64 (pid: 9050, threadinfo ffff880045f80000, task ffff880048eb0000) Call Trace: validate_mm+0x58/0x1e0 vma_adjust+0x635/0x6b0 __split_vma.isra.22+0x161/0x220 split_vma+0x24/0x30 sys_madvise+0x5da/0x7b0 tracesys+0xe1/0xe6 RIP anon_vma_interval_tree_verify+0xc/0xa0 CR2: fffffffffffffff0 Figured out by Bob Liu. Reported-by: Sasha Levin Cc: Bob Liu Signed-off-by: Michel Lespinasse Reviewed-by: Rik van Riel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm/mmap.c b/mm/mmap.c index 2d942353d68..9a796c41e7d 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -334,8 +334,10 @@ void validate_mm(struct mm_struct *mm) struct vm_area_struct *vma = mm->mmap; while (vma) { struct anon_vma_chain *avc; + vma_lock_anon_vma(vma); list_for_each_entry(avc, &vma->anon_vma_chain, same_vma) anon_vma_interval_tree_verify(avc); + vma_unlock_anon_vma(vma); vma = vma->vm_next; i++; } -- cgit v1.2.3 From 1756954c61cb5c97c618ccb366482b9c1f891d6d Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Fri, 16 Nov 2012 14:14:48 -0800 Subject: mm: fix build warning for uninitialized value do_wp_page() sets mmun_called if mmun_start and mmun_end were initialized and, if so, may call mmu_notifier_invalidate_range_end() with these values. This doesn't prevent gcc from emitting a build warning though: mm/memory.c: In function `do_wp_page': mm/memory.c:2530: warning: `mmun_start' may be used uninitialized in this function mm/memory.c:2531: warning: `mmun_end' may be used uninitialized in this function It's much easier to initialize the variables to impossible values and do a simple comparison to determine if they were initialized to remove the bool entirely. Signed-off-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index fb135ba4aba..221fc9ffcab 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2527,9 +2527,8 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, int ret = 0; int page_mkwrite = 0; struct page *dirty_page = NULL; - unsigned long mmun_start; /* For mmu_notifiers */ - unsigned long mmun_end; /* For mmu_notifiers */ - bool mmun_called = false; /* For mmu_notifiers */ + unsigned long mmun_start = 0; /* For mmu_notifiers */ + unsigned long mmun_end = 0; /* For mmu_notifiers */ old_page = vm_normal_page(vma, address, orig_pte); if (!old_page) { @@ -2708,8 +2707,7 @@ gotten: goto oom_free_new; mmun_start = address & PAGE_MASK; - mmun_end = (address & PAGE_MASK) + PAGE_SIZE; - mmun_called = true; + mmun_end = mmun_start + PAGE_SIZE; mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end); /* @@ -2778,7 +2776,7 @@ gotten: page_cache_release(new_page); unlock: pte_unmap_unlock(page_table, ptl); - if (mmun_called) + if (mmun_end > mmun_start) mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end); if (old_page) { /* -- cgit v1.2.3 From 9a5a8f19b43430752067ecaee62fc59e11e88fa6 Mon Sep 17 00:00:00 2001 From: Michal Hocko Date: Fri, 16 Nov 2012 14:14:49 -0800 Subject: memcg: oom: fix totalpages calculation for memory.swappiness==0 oom_badness() takes a totalpages argument which says how many pages are available and it uses it as a base for the score calculation. The value is calculated by mem_cgroup_get_limit which considers both limit and total_swap_pages (resp. memsw portion of it). This is usually correct but since fe35004fbf9e ("mm: avoid swapping out with swappiness==0") we do not swap when swappiness is 0 which means that we cannot really use up all the totalpages pages. This in turn confuses oom score calculation if the memcg limit is much smaller than the available swap because the used memory (capped by the limit) is negligible comparing to totalpages so the resulting score is too small if adj!=0 (typically task with CAP_SYS_ADMIN or non zero oom_score_adj). A wrong process might be selected as result. The problem can be worked around by checking mem_cgroup_swappiness==0 and not considering swap at all in such a case. Signed-off-by: Michal Hocko Acked-by: David Rientjes Acked-by: Johannes Weiner Acked-by: KOSAKI Motohiro Acked-by: KAMEZAWA Hiroyuki Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/cgroups/memory.txt | 4 ++++ mm/memcontrol.c | 21 +++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt index c07f7b4fb88..71c4da41344 100644 --- a/Documentation/cgroups/memory.txt +++ b/Documentation/cgroups/memory.txt @@ -466,6 +466,10 @@ Note: 5.3 swappiness Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only. +Please note that unlike the global swappiness, memcg knob set to 0 +really prevents from any swapping even if there is a swap storage +available. This might lead to memcg OOM killer if there are no file +pages to reclaim. Following cgroups' swappiness can't be changed. - root cgroup (uses /proc/sys/vm/swappiness). diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 7acf43bf04a..93a7e36ded8 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1452,17 +1452,26 @@ static int mem_cgroup_count_children(struct mem_cgroup *memcg) static u64 mem_cgroup_get_limit(struct mem_cgroup *memcg) { u64 limit; - u64 memsw; limit = res_counter_read_u64(&memcg->res, RES_LIMIT); - limit += total_swap_pages << PAGE_SHIFT; - memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT); /* - * If memsw is finite and limits the amount of swap space available - * to this memcg, return that limit. + * Do not consider swap space if we cannot swap due to swappiness */ - return min(limit, memsw); + if (mem_cgroup_swappiness(memcg)) { + u64 memsw; + + limit += total_swap_pages << PAGE_SHIFT; + memsw = res_counter_read_u64(&memcg->memsw, RES_LIMIT); + + /* + * If memsw is finite and limits the amount of swap space + * available to this memcg, return that limit. + */ + limit = min(limit, memsw); + } + + return limit; } void mem_cgroup_out_of_memory(struct mem_cgroup *memcg, gfp_t gfp_mask, -- cgit v1.2.3 From 18f694271b86ee279e88208550cc49fee206b544 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Fri, 16 Nov 2012 14:14:52 -0800 Subject: mips, arc: fix build failure Using a cross-compiler to fix another issue, the following build error occurred for mips defconfig: arch/mips/fw/arc/misc.c: In function 'ArcHalt': arch/mips/fw/arc/misc.c:25:2: error: implicit declaration of function 'local_irq_disable' Fix it up by including irqflags.h. Signed-off-by: David Rientjes Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/fw/arc/misc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/mips/fw/arc/misc.c b/arch/mips/fw/arc/misc.c index 7cf80ca2c1d..f9f5307434c 100644 --- a/arch/mips/fw/arc/misc.c +++ b/arch/mips/fw/arc/misc.c @@ -11,6 +11,7 @@ */ #include #include +#include #include -- cgit v1.2.3 From bea8c150a7efbc0f204e709b7274fe273f55e0d3 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Fri, 16 Nov 2012 14:14:54 -0800 Subject: memcg: fix hotplugged memory zone oops When MEMCG is configured on (even when it's disabled by boot option), when adding or removing a page to/from its lru list, the zone pointer used for stats updates is nowadays taken from the struct lruvec. (On many configurations, calculating zone from page is slower.) But we have no code to update all the lruvecs (per zone, per memcg) when a memory node is hotadded. Here's an extract from the oops which results when running numactl to bind a program to a newly onlined node: BUG: unable to handle kernel NULL pointer dereference at 0000000000000f60 IP: __mod_zone_page_state+0x9/0x60 Pid: 1219, comm: numactl Not tainted 3.6.0-rc5+ #180 Bochs Bochs Process numactl (pid: 1219, threadinfo ffff880039abc000, task ffff8800383c4ce0) Call Trace: __pagevec_lru_add_fn+0xdf/0x140 pagevec_lru_move_fn+0xb1/0x100 __pagevec_lru_add+0x1c/0x30 lru_add_drain_cpu+0xa3/0x130 lru_add_drain+0x2f/0x40 ... The natural solution might be to use a memcg callback whenever memory is hotadded; but that solution has not been scoped out, and it happens that we do have an easy location at which to update lruvec->zone. The lruvec pointer is discovered either by mem_cgroup_zone_lruvec() or by mem_cgroup_page_lruvec(), and both of those do know the right zone. So check and set lruvec->zone in those; and remove the inadequate attempt to set lruvec->zone from lruvec_init(), which is called before NODE_DATA(node) has been allocated in such cases. Ah, there was one exceptionr. For no particularly good reason, mem_cgroup_force_empty_list() has its own code for deciding lruvec. Change it to use the standard mem_cgroup_zone_lruvec() and mem_cgroup_get_lru_size() too. In fact it was already safe against such an oops (the lru lists in danger could only be empty), but we're better proofed against future changes this way. I've marked this for stable (3.6) since we introduced the problem in 3.5 (now closed to stable); but I have no idea if this is the only fix needed to get memory hotadd working with memcg in 3.6, and received no answer when I enquired twice before. Reported-by: Tang Chen Signed-off-by: Hugh Dickins Acked-by: Johannes Weiner Acked-by: KAMEZAWA Hiroyuki Cc: Konstantin Khlebnikov Cc: Wen Congyang Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 2 +- mm/memcontrol.c | 46 +++++++++++++++++++++++++++++++++++----------- mm/mmzone.c | 6 +----- mm/page_alloc.c | 2 +- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 50aaca81f63..a23923ba826 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -752,7 +752,7 @@ extern int init_currently_empty_zone(struct zone *zone, unsigned long start_pfn, unsigned long size, enum memmap_context context); -extern void lruvec_init(struct lruvec *lruvec, struct zone *zone); +extern void lruvec_init(struct lruvec *lruvec); static inline struct zone *lruvec_zone(struct lruvec *lruvec) { diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 93a7e36ded8..dd39ba000b3 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1055,12 +1055,24 @@ struct lruvec *mem_cgroup_zone_lruvec(struct zone *zone, struct mem_cgroup *memcg) { struct mem_cgroup_per_zone *mz; + struct lruvec *lruvec; - if (mem_cgroup_disabled()) - return &zone->lruvec; + if (mem_cgroup_disabled()) { + lruvec = &zone->lruvec; + goto out; + } mz = mem_cgroup_zoneinfo(memcg, zone_to_nid(zone), zone_idx(zone)); - return &mz->lruvec; + lruvec = &mz->lruvec; +out: + /* + * Since a node can be onlined after the mem_cgroup was created, + * we have to be prepared to initialize lruvec->zone here; + * and if offlined then reonlined, we need to reinitialize it. + */ + if (unlikely(lruvec->zone != zone)) + lruvec->zone = zone; + return lruvec; } /* @@ -1087,9 +1099,12 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone) struct mem_cgroup_per_zone *mz; struct mem_cgroup *memcg; struct page_cgroup *pc; + struct lruvec *lruvec; - if (mem_cgroup_disabled()) - return &zone->lruvec; + if (mem_cgroup_disabled()) { + lruvec = &zone->lruvec; + goto out; + } pc = lookup_page_cgroup(page); memcg = pc->mem_cgroup; @@ -1107,7 +1122,16 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct zone *zone) pc->mem_cgroup = memcg = root_mem_cgroup; mz = page_cgroup_zoneinfo(memcg, page); - return &mz->lruvec; + lruvec = &mz->lruvec; +out: + /* + * Since a node can be onlined after the mem_cgroup was created, + * we have to be prepared to initialize lruvec->zone here; + * and if offlined then reonlined, we need to reinitialize it. + */ + if (unlikely(lruvec->zone != zone)) + lruvec->zone = zone; + return lruvec; } /** @@ -3697,17 +3721,17 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, static bool mem_cgroup_force_empty_list(struct mem_cgroup *memcg, int node, int zid, enum lru_list lru) { - struct mem_cgroup_per_zone *mz; + struct lruvec *lruvec; unsigned long flags, loop; struct list_head *list; struct page *busy; struct zone *zone; zone = &NODE_DATA(node)->node_zones[zid]; - mz = mem_cgroup_zoneinfo(memcg, node, zid); - list = &mz->lruvec.lists[lru]; + lruvec = mem_cgroup_zone_lruvec(zone, memcg); + list = &lruvec->lists[lru]; - loop = mz->lru_size[lru]; + loop = mem_cgroup_get_lru_size(lruvec, lru); /* give some margin against EBUSY etc...*/ loop += 256; busy = NULL; @@ -4745,7 +4769,7 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node) for (zone = 0; zone < MAX_NR_ZONES; zone++) { mz = &pn->zoneinfo[zone]; - lruvec_init(&mz->lruvec, &NODE_DATA(node)->node_zones[zone]); + lruvec_init(&mz->lruvec); mz->usage_in_excess = 0; mz->on_tree = false; mz->memcg = memcg; diff --git a/mm/mmzone.c b/mm/mmzone.c index 3cef80f6ac7..4596d81b89b 100644 --- a/mm/mmzone.c +++ b/mm/mmzone.c @@ -87,7 +87,7 @@ int memmap_valid_within(unsigned long pfn, } #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */ -void lruvec_init(struct lruvec *lruvec, struct zone *zone) +void lruvec_init(struct lruvec *lruvec) { enum lru_list lru; @@ -95,8 +95,4 @@ void lruvec_init(struct lruvec *lruvec, struct zone *zone) for_each_lru(lru) INIT_LIST_HEAD(&lruvec->lists[lru]); - -#ifdef CONFIG_MEMCG - lruvec->zone = zone; -#endif } diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 5b74de6702e..c91598b1b4c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4505,7 +4505,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat, zone->zone_pgdat = pgdat; zone_pcp_init(zone); - lruvec_init(&zone->lruvec, zone); + lruvec_init(&zone->lruvec); if (!size) continue; -- cgit v1.2.3 From f58b59c1df3cb990d644018e1461cd4acd3c1700 Mon Sep 17 00:00:00 2001 From: Xiaotian Feng Date: Fri, 16 Nov 2012 14:14:55 -0800 Subject: swapfile: fix name leak in swapoff There's a name leak introduced by commit 91a27b2a7567 ("vfs: define struct filename and have getname() return it"). Add the missing putname. [akpm@linux-foundation.org: cleanup] Signed-off-by: Xiaotian Feng Reviewed-by: Jeff Layton Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/swapfile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index 71cd288b200..f91a25547ff 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -1494,9 +1494,8 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) BUG_ON(!current->mm); pathname = getname(specialfile); - err = PTR_ERR(pathname); if (IS_ERR(pathname)) - goto out; + return PTR_ERR(pathname); victim = file_open_name(pathname, O_RDWR|O_LARGEFILE, 0); err = PTR_ERR(victim); @@ -1608,6 +1607,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) out_dput: filp_close(victim, NULL); out: + putname(pathname); return err; } -- cgit v1.2.3 From 2ca3cb50edc351875df13d083524f524cdeb3054 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 16 Nov 2012 14:14:56 -0800 Subject: rapidio: fix kernel-doc warnings Fix rapidio kernel-doc warnings: Warning(drivers/rapidio/rio.c:415): No description found for parameter 'local' Warning(drivers/rapidio/rio.c:415): Excess function parameter 'lstart' description in 'rio_map_inb_region' Warning(include/linux/rio.h:290): No description found for parameter 'switches' Warning(include/linux/rio.h:290): No description found for parameter 'destid_table' Signed-off-by: Randy Dunlap Cc: Matt Porter Acked-by: Alexandre Bounine Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rapidio/rio.c | 2 +- include/linux/rio.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index c17ae22567e..0c6fcb461fa 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -401,7 +401,7 @@ EXPORT_SYMBOL_GPL(rio_release_inb_pwrite); /** * rio_map_inb_region -- Map inbound memory region. * @mport: Master port. - * @lstart: physical address of memory region to be mapped + * @local: physical address of memory region to be mapped * @rbase: RIO base address assigned to this window * @size: Size of the memory region * @rflags: Flags for mapping. diff --git a/include/linux/rio.h b/include/linux/rio.h index 4187da51100..a3e78427866 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -275,9 +275,11 @@ struct rio_id_table { * struct rio_net - RIO network info * @node: Node in global list of RIO networks * @devices: List of devices in this network + * @switches: List of switches in this netowrk * @mports: List of master ports accessing this network * @hport: Default port for accessing this network * @id: RIO network ID + * @destid_table: destID allocation table */ struct rio_net { struct list_head node; /* node in list of networks */ -- cgit v1.2.3 From 96710098ee124951ff2fed7cd8406da92aad011a Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Fri, 16 Nov 2012 14:14:59 -0800 Subject: mm: revert "mm: vmscan: scale number of pages reclaimed by reclaim/compaction based on failures" Jiri Slaby reported the following: (It's an effective revert of "mm: vmscan: scale number of pages reclaimed by reclaim/compaction based on failures".) Given kswapd had hours of runtime in ps/top output yesterday in the morning and after the revert it's now 2 minutes in sum for the last 24h, I would say, it's gone. The intention of the patch in question was to compensate for the loss of lumpy reclaim. Part of the reason lumpy reclaim worked is because it aggressively reclaimed pages and this patch was meant to be a sane compromise. When compaction fails, it gets deferred and both compaction and reclaim/compaction is deferred avoid excessive reclaim. However, since commit c654345924f7 ("mm: remove __GFP_NO_KSWAPD"), kswapd is woken up each time and continues reclaiming which was not taken into account when the patch was developed. Attempts to address the problem ended up just changing the shape of the problem instead of fixing it. The release window gets closer and while a THP allocation failing is not a major problem, kswapd chewing up a lot of CPU is. This patch reverts commit 83fde0f22872 ("mm: vmscan: scale number of pages reclaimed by reclaim/compaction based on failures") and will be revisited in the future. Signed-off-by: Mel Gorman Cc: Zdenek Kabelac Tested-by: Valdis Kletnieks Cc: Jiri Slaby Cc: Rik van Riel Cc: Jiri Slaby Cc: Johannes Hirte Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 8b055e9379b..48550c66f1f 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1760,28 +1760,6 @@ static bool in_reclaim_compaction(struct scan_control *sc) return false; } -#ifdef CONFIG_COMPACTION -/* - * If compaction is deferred for sc->order then scale the number of pages - * reclaimed based on the number of consecutive allocation failures - */ -static unsigned long scale_for_compaction(unsigned long pages_for_compaction, - struct lruvec *lruvec, struct scan_control *sc) -{ - struct zone *zone = lruvec_zone(lruvec); - - if (zone->compact_order_failed <= sc->order) - pages_for_compaction <<= zone->compact_defer_shift; - return pages_for_compaction; -} -#else -static unsigned long scale_for_compaction(unsigned long pages_for_compaction, - struct lruvec *lruvec, struct scan_control *sc) -{ - return pages_for_compaction; -} -#endif - /* * Reclaim/compaction is used for high-order allocation requests. It reclaims * order-0 pages before compacting the zone. should_continue_reclaim() returns @@ -1829,9 +1807,6 @@ static inline bool should_continue_reclaim(struct lruvec *lruvec, * inactive lists are large enough, continue reclaiming */ pages_for_compaction = (2UL << sc->order); - - pages_for_compaction = scale_for_compaction(pages_for_compaction, - lruvec, sc); inactive_lru_pages = get_lru_size(lruvec, LRU_INACTIVE_FILE); if (nr_swap_pages > 0) inactive_lru_pages += get_lru_size(lruvec, LRU_INACTIVE_ANON); -- cgit v1.2.3 From 498c2280212327858e521e9d21345d4cc2637f54 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 16 Nov 2012 14:15:00 -0800 Subject: mm: highmem: don't treat PKMAP_ADDR(LAST_PKMAP) as a highmem address kmap_to_page returns the corresponding struct page for a virtual address of an arbitrary mapping. This works by checking whether the address falls in the pkmap region and using the pkmap page tables instead of the linear mapping if appropriate. Unfortunately, the bounds checking means that PKMAP_ADDR(LAST_PKMAP) is incorrectly treated as a highmem address and we can end up walking off the end of pkmap_page_table and subsequently passing junk to pte_page. This patch fixes the bound check to stay within the pkmap tables. Signed-off-by: Will Deacon Cc: Mel Gorman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/highmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/highmem.c b/mm/highmem.c index d517cd16a6e..2da13a5c50e 100644 --- a/mm/highmem.c +++ b/mm/highmem.c @@ -98,7 +98,7 @@ struct page *kmap_to_page(void *vaddr) { unsigned long addr = (unsigned long)vaddr; - if (addr >= PKMAP_ADDR(0) && addr <= PKMAP_ADDR(LAST_PKMAP)) { + if (addr >= PKMAP_ADDR(0) && addr < PKMAP_ADDR(LAST_PKMAP)) { int i = (addr - PKMAP_ADDR(0)) >> PAGE_SHIFT; return pte_page(pkmap_page_table[i]); } -- cgit v1.2.3 From 215c02bc33bbd5ff4d7379a909462d11f0103218 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Fri, 16 Nov 2012 14:15:03 -0800 Subject: tmpfs: fix shmem_getpage_gfp() VM_BUG_ON Fuzzing with trinity hit the "impossible" VM_BUG_ON(error) (which Fedora has converted to WARNING) in shmem_getpage_gfp(): WARNING: at mm/shmem.c:1151 shmem_getpage_gfp+0xa5c/0xa70() Pid: 29795, comm: trinity-child4 Not tainted 3.7.0-rc2+ #49 Call Trace: warn_slowpath_common+0x7f/0xc0 warn_slowpath_null+0x1a/0x20 shmem_getpage_gfp+0xa5c/0xa70 shmem_fault+0x4f/0xa0 __do_fault+0x71/0x5c0 handle_pte_fault+0x97/0xae0 handle_mm_fault+0x289/0x350 __do_page_fault+0x18e/0x530 do_page_fault+0x2b/0x50 page_fault+0x28/0x30 tracesys+0xe1/0xe6 Thanks to Johannes for pointing to truncation: free_swap_and_cache() only does a trylock on the page, so the page lock we've held since before confirming swap is not enough to protect against truncation. What cleanup is needed in this case? Just delete_from_swap_cache(), which takes care of the memcg uncharge. Signed-off-by: Hugh Dickins Reported-by: Dave Jones Cc: Johannes Weiner Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/shmem.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index 67afba5117f..dc12264f44f 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1145,8 +1145,20 @@ repeat: if (!error) { error = shmem_add_to_page_cache(page, mapping, index, gfp, swp_to_radix_entry(swap)); - /* We already confirmed swap, and make no allocation */ - VM_BUG_ON(error); + /* + * We already confirmed swap under page lock, and make + * no memory allocation here, so usually no possibility + * of error; but free_swap_and_cache() only trylocks a + * page, so it is just possible that the entry has been + * truncated or holepunched since swap was confirmed. + * shmem_undo_range() will have done some of the + * unaccounting, now delete_from_swap_cache() will do + * the rest (including mem_cgroup_uncharge_swapcache). + * Reset swap.val? No, leave it so "failed" goes back to + * "repeat": reading a hole and writing should succeed. + */ + if (error) + delete_from_swap_cache(page); } if (error) goto failed; -- cgit v1.2.3 From 0f3c42f522dc1ad7e27affc0a4aa8c790bce0a66 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Fri, 16 Nov 2012 14:15:04 -0800 Subject: tmpfs: change final i_blocks BUG to WARNING Under a particular load on one machine, I have hit shmem_evict_inode()'s BUG_ON(inode->i_blocks), enough times to narrow it down to a particular race between swapout and eviction. It comes from the "if (freed > 0)" asymmetry in shmem_recalc_inode(), and the lack of coherent locking between mapping's nrpages and shmem's swapped count. There's a window in shmem_writepage(), between lowering nrpages in shmem_delete_from_page_cache() and then raising swapped count, when the freed count appears to be +1 when it should be 0, and then the asymmetry stops it from being corrected with -1 before hitting the BUG. One answer is coherent locking: using tree_lock throughout, without info->lock; reasonable, but the raw_spin_lock in percpu_counter_add() on used_blocks makes that messier than expected. Another answer may be a further effort to eliminate the weird shmem_recalc_inode() altogether, but previous attempts at that failed. So far undecided, but for now change the BUG_ON to WARN_ON: in usual circumstances it remains a useful consistency check. Signed-off-by: Hugh Dickins Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/shmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/shmem.c b/mm/shmem.c index dc12264f44f..89341b658bd 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -643,7 +643,7 @@ static void shmem_evict_inode(struct inode *inode) kfree(info->symlink); simple_xattrs_free(&info->xattrs); - BUG_ON(inode->i_blocks); + WARN_ON(inode->i_blocks); shmem_free_inode(inode->i_sb); clear_inode(inode); } -- cgit v1.2.3 From 5576646f3c1abd60d72d19829de6f5d8c2ca8ecf Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 16 Nov 2012 14:15:06 -0800 Subject: revert "mm: fix-up zone present pages" Revert commit 7f1290f2f2a4 ("mm: fix-up zone present pages") That patch tried to fix a issue when calculating zone->present_pages, but it caused a regression on 32bit systems with HIGHMEM. With that change, reset_zone_present_pages() resets all zone->present_pages to zero, and fixup_zone_present_pages() is called to recalculate zone->present_pages when the boot allocator frees core memory pages into buddy allocator. Because highmem pages are not freed by bootmem allocator, all highmem zones' present_pages becomes zero. Various options for improving the situation are being discussed but for now, let's return to the 3.6 code. Cc: Jianguo Wu Cc: Jiang Liu Cc: Petr Tesarik Cc: "Luck, Tony" Cc: Mel Gorman Cc: Yinghai Lu Cc: Minchan Kim Cc: Johannes Weiner Acked-by: David Rientjes Tested-by: Chris Clayton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/mm/init.c | 1 - include/linux/mm.h | 4 ---- mm/bootmem.c | 10 +--------- mm/memory_hotplug.c | 7 ------- mm/nobootmem.c | 3 --- mm/page_alloc.c | 34 ---------------------------------- 6 files changed, 1 insertion(+), 58 deletions(-) diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index acd5b68e887..082e383c1b6 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -637,7 +637,6 @@ mem_init (void) high_memory = __va(max_low_pfn * PAGE_SIZE); - reset_zone_present_pages(); for_each_online_pgdat(pgdat) if (pgdat->bdata->node_bootmem_map) totalram_pages += free_all_bootmem_node(pgdat); diff --git a/include/linux/mm.h b/include/linux/mm.h index fa068040273..bcaab4e6fe9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1684,9 +1684,5 @@ static inline unsigned int debug_guardpage_minorder(void) { return 0; } static inline bool page_is_guard(struct page *page) { return false; } #endif /* CONFIG_DEBUG_PAGEALLOC */ -extern void reset_zone_present_pages(void); -extern void fixup_zone_present_pages(int nid, unsigned long start_pfn, - unsigned long end_pfn); - #endif /* __KERNEL__ */ #endif /* _LINUX_MM_H */ diff --git a/mm/bootmem.c b/mm/bootmem.c index 434be4ae7a0..f468185b3b2 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -198,8 +198,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) int order = ilog2(BITS_PER_LONG); __free_pages_bootmem(pfn_to_page(start), order); - fixup_zone_present_pages(page_to_nid(pfn_to_page(start)), - start, start + BITS_PER_LONG); count += BITS_PER_LONG; start += BITS_PER_LONG; } else { @@ -210,9 +208,6 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) if (vec & 1) { page = pfn_to_page(start + off); __free_pages_bootmem(page, 0); - fixup_zone_present_pages( - page_to_nid(page), - start + off, start + off + 1); count++; } vec >>= 1; @@ -226,11 +221,8 @@ static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata) pages = bdata->node_low_pfn - bdata->node_min_pfn; pages = bootmem_bootmap_pages(pages); count += pages; - while (pages--) { - fixup_zone_present_pages(page_to_nid(page), - page_to_pfn(page), page_to_pfn(page) + 1); + while (pages--) __free_pages_bootmem(page++, 0); - } bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 56b758ae57d..e4eeacae2b9 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -106,7 +106,6 @@ static void get_page_bootmem(unsigned long info, struct page *page, void __ref put_page_bootmem(struct page *page) { unsigned long type; - struct zone *zone; type = (unsigned long) page->lru.next; BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE || @@ -117,12 +116,6 @@ void __ref put_page_bootmem(struct page *page) set_page_private(page, 0); INIT_LIST_HEAD(&page->lru); __free_pages_bootmem(page, 0); - - zone = page_zone(page); - zone_span_writelock(zone); - zone->present_pages++; - zone_span_writeunlock(zone); - totalram_pages++; } } diff --git a/mm/nobootmem.c b/mm/nobootmem.c index 714d5d65047..bd82f6b3141 100644 --- a/mm/nobootmem.c +++ b/mm/nobootmem.c @@ -116,8 +116,6 @@ static unsigned long __init __free_memory_core(phys_addr_t start, return 0; __free_pages_memory(start_pfn, end_pfn); - fixup_zone_present_pages(pfn_to_nid(start >> PAGE_SHIFT), - start_pfn, end_pfn); return end_pfn - start_pfn; } @@ -128,7 +126,6 @@ unsigned long __init free_low_memory_core_early(int nodeid) phys_addr_t start, end, size; u64 i; - reset_zone_present_pages(); for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL) count += __free_memory_core(start, end); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c91598b1b4c..7bb35ac0964 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -6098,37 +6098,3 @@ void dump_page(struct page *page) dump_page_flags(page->flags); mem_cgroup_print_bad_page(page); } - -/* reset zone->present_pages */ -void reset_zone_present_pages(void) -{ - struct zone *z; - int i, nid; - - for_each_node_state(nid, N_HIGH_MEMORY) { - for (i = 0; i < MAX_NR_ZONES; i++) { - z = NODE_DATA(nid)->node_zones + i; - z->present_pages = 0; - } - } -} - -/* calculate zone's present pages in buddy system */ -void fixup_zone_present_pages(int nid, unsigned long start_pfn, - unsigned long end_pfn) -{ - struct zone *z; - unsigned long zone_start_pfn, zone_end_pfn; - int i; - - for (i = 0; i < MAX_NR_ZONES; i++) { - z = NODE_DATA(nid)->node_zones + i; - zone_start_pfn = z->zone_start_pfn; - zone_end_pfn = zone_start_pfn + z->spanned_pages; - - /* if the two regions intersect */ - if (!(zone_start_pfn >= end_pfn || zone_end_pfn <= start_pfn)) - z->present_pages += min(end_pfn, zone_end_pfn) - - max(start_pfn, zone_start_pfn); - } -} -- cgit v1.2.3 From 9d36976fad3008fcc4209789566f7f3e7763f212 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Sat, 17 Nov 2012 05:19:22 +0900 Subject: staging/serqt_usb2: Refactor qt_status_change_check() in serqt_usb2.c Modify qt_status_change_check() and delete qt_status_change(). Signed-off-by: YAMANE Toshiaki Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/serqt_usb2/serqt_usb2.c | 53 ++++++++++++++------------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index f68a855199f..1b3e995d3a2 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -291,33 +291,6 @@ static void qt_interrupt_callback(struct urb *urb) /* FIXME */ } -static int qt_status_change(unsigned int limit, - unsigned char *data, - int i, - struct quatech_port *qt_port, - struct usb_serial_port *port) -{ - void (*fn)(struct quatech_port *, unsigned char); - - if (0x00 == data[i + 2]) { - dev_dbg(&port->dev, "Line status status.\n"); - fn = ProcessLineStatus; - } else { - dev_dbg(&port->dev, "Modem status status.\n"); - fn = ProcessModemStatus; - } - - if (i > limit) { - dev_dbg(&port->dev, - "Illegal escape seuences in received data\n"); - return 0; - } - - (*fn)(qt_port, data[i + 3]); - - return 1; -} - static void qt_status_change_check(struct tty_struct *tty, struct urb *urb, struct quatech_port *qt_port, @@ -334,11 +307,29 @@ static void qt_status_change_check(struct tty_struct *tty, flag = 0; switch (data[i + 2]) { case 0x00: + if (i > (RxCount - 4)) { + dev_dbg(&port->dev, + "Illegal escape seuences in received data\n"); + break; + } + + ProcessLineStatus(qt_port, data[i + 3]); + + i += 3; + flag = 1; + break; + case 0x01: - flag = qt_status_change((RxCount - 4), data, i, - qt_port, port); - if (flag == 1) - i += 3; + if (i > (RxCount - 4)) { + dev_dbg(&port->dev, + "Illegal escape seuences in received data\n"); + break; + } + + ProcessModemStatus(qt_port, data[i + 3]); + + i += 3; + flag = 1; break; case 0xff: -- cgit v1.2.3 From 295c799ae45b3678d9b8d3e845635ed07ce3b66a Mon Sep 17 00:00:00 2001 From: Andy Gross Date: Fri, 16 Nov 2012 13:10:57 -0600 Subject: staging: drm/omap: Fix usage of IS_ERR_OR_NULL and PTR_ERR Return -ENOMEM if dmm_txn_init cannot allocate a refill engine. v2: Fix typing issue seen with newer compilers Signed-off-by: Andy Gross Signed-off-by: Greg Kroah-Hartman --- drivers/staging/omapdrm/omap_dmm_tiler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/omapdrm/omap_dmm_tiler.c b/drivers/staging/omapdrm/omap_dmm_tiler.c index 5c809c05685..59bf43899fc 100644 --- a/drivers/staging/omapdrm/omap_dmm_tiler.c +++ b/drivers/staging/omapdrm/omap_dmm_tiler.c @@ -296,7 +296,7 @@ static int fill(struct tcm_area *area, struct page **pages, txn = dmm_txn_init(omap_dmm, area->tcm); if (IS_ERR_OR_NULL(txn)) - return PTR_ERR(-ENOMEM); + return -ENOMEM; tcm_for_each_slice(slice, *area, area_s) { struct pat_area p_area = { -- cgit v1.2.3 From f4a75d2eb7b1e2206094b901be09adb31ba63681 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 16 Nov 2012 17:42:40 -0800 Subject: Linux 3.7-rc6 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6edac73ee1b..9f6ca124e89 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 7 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc6 NAME = Terrified Chipmunk # *DOCUMENTATION* -- cgit v1.2.3 From 69bcd3bf40228239db91b075f56f9ba511f0bfe1 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Mon, 22 Oct 2012 08:57:00 +0100 Subject: iio: hid-sensors: convert HID_SENSOR_ENUM_BASE_QUIRKS to bool It's non-sense to use tristate for the option, it's bool. Signed-off-by: Kirill A. Shutemov Signed-off-by: Jonathan Cameron --- drivers/iio/common/hid-sensors/Kconfig | 2 +- drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/iio/common/hid-sensors/Kconfig b/drivers/iio/common/hid-sensors/Kconfig index 8e63d81d652..ae10778da7a 100644 --- a/drivers/iio/common/hid-sensors/Kconfig +++ b/drivers/iio/common/hid-sensors/Kconfig @@ -15,7 +15,7 @@ config HID_SENSOR_IIO_COMMON attributes. config HID_SENSOR_ENUM_BASE_QUIRKS - tristate "ENUM base quirks for HID Sensor IIO drivers" + bool "ENUM base quirks for HID Sensor IIO drivers" depends on HID_SENSOR_IIO_COMMON help Say yes here to build support for sensor hub FW using diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c index d4b790d18ef..d60198a6ca2 100644 --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c @@ -36,10 +36,8 @@ static int hid_sensor_data_rdy_trigger_set_state(struct iio_trigger *trig, int state_val; state_val = state ? 1 : 0; -#if (defined CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS) || \ - (defined CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS_MODULE) - ++state_val; -#endif + if (IS_ENABLED(CONFIG_HID_SENSOR_ENUM_BASE_QUIRKS)) + ++state_val; st->data_ready = state; sensor_hub_set_feature(st->hsdev, st->power_state.report_id, st->power_state.index, -- cgit v1.2.3 From e8f45e3341ed8609174f9c21fb47e202f29ab039 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 22 Oct 2012 10:42:00 +0100 Subject: staging:iio:adt7410: Fix adt7410_set_mode return value The function is expected to return the number of bytes consumed and as long as not all bytes have been consumed the function will be called again. Currently the function returns 'ret', which will always be 0 in this case, so we end up in a endless loop since the caller will assume that no bytes have been consumed. So instead return len as it is supposed to. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/adt7410.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c index 5e93d868b3f..6493cd0a48d 100644 --- a/drivers/staging/iio/adc/adt7410.c +++ b/drivers/staging/iio/adc/adt7410.c @@ -181,7 +181,7 @@ static ssize_t adt7410_store_mode(struct device *dev, chip->config = config; - return ret; + return len; } static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, -- cgit v1.2.3 From e3db9ef6eb39ac6d969787bc15756778c2c5ca66 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 21 Oct 2012 11:52:00 +0100 Subject: drivers/iio/industrialio-event.c: eliminate possible double free The function __iio_add_event_config_attrs is only called once, by the function iio_device_register_eventset. If the call fails, iio_device_register_eventset calls __iio_remove_event_config_attrs. There is thus no need for __iio_add_event_config_attrs to also call __iio_remove_event_config_attrs on failure. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @r@ identifier f,free,a; parameter list[n] ps; type T; expression e; @@ f(ps,T a,...) { ... when any when != a = e if(...) { ... free(a); ... return ...; } ... when any } @@ identifier r.f,r.free; expression x,a; expression list[r.n] xs; @@ * x = f(xs,a,...); if (...) { ... free(a); ... return ...; } // Signed-off-by: Julia Lawall Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-event.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 857e6306c5c..261cae00557 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -350,15 +350,10 @@ static inline int __iio_add_event_config_attrs(struct iio_dev *indio_dev) ret = iio_device_add_event_sysfs(indio_dev, &indio_dev->channels[j]); if (ret < 0) - goto error_clear_attrs; + return ret; attrcount += ret; } return attrcount; - -error_clear_attrs: - __iio_remove_event_config_attrs(indio_dev); - - return ret; } static bool iio_check_for_dynamic_events(struct iio_dev *indio_dev) -- cgit v1.2.3 From 95273f8952a7e3a037e139eec0aa99872f086498 Mon Sep 17 00:00:00 2001 From: Derek Basehore Date: Fri, 5 Oct 2012 00:54:00 +0100 Subject: tsl2563: fixed bug with disabling interrupts In tsl_2563_write_interrupt_config and tsl2562_remove, interrupts are not disabled where they should be. This seems to be from a mistake of using |= instead of &= in 2 lines of code. Signed-off-by: Derek Basehore Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/tsl2563.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index 954ca2c172c..3f72543b188 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -652,7 +652,7 @@ static int tsl2563_write_interrupt_config(struct iio_dev *indio_dev, } if (!state && (chip->intr & 0x30)) { - chip->intr |= ~0x30; + chip->intr &= ~0x30; ret = i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | TSL2563_REG_INT, chip->intr); @@ -814,7 +814,7 @@ static int __devexit tsl2563_remove(struct i2c_client *client) if (!chip->int_enabled) cancel_delayed_work(&chip->poweroff_work); /* Ensure that interrupts are disabled - then flush any bottom halves */ - chip->intr |= ~0x30; + chip->intr &= ~0x30; i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | TSL2563_REG_INT, chip->intr); flush_scheduled_work(); -- cgit v1.2.3 From 64ebe955f9447fcecf65360ec3bc332f4ec411b6 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 27 Oct 2012 16:03:00 +0100 Subject: iio: hid-sensor: Return proper error if kmemdup fails Return -ENOMEM instead of 0 if kmemdup fails. Signed-off-by: Axel Lin Signed-off-by: Jonathan Cameron --- drivers/iio/accel/hid-sensor-accel-3d.c | 6 +++--- drivers/iio/gyro/hid-sensor-gyro-3d.c | 6 +++--- drivers/iio/light/hid-sensor-als.c | 5 ++--- drivers/iio/magnetometer/hid-sensor-magn-3d.c | 6 +++--- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index a95cda0e387..e67bb912bd1 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -306,10 +306,10 @@ static int __devinit hid_accel_3d_probe(struct platform_device *pdev) goto error_free_dev; } - channels = kmemdup(accel_3d_channels, - sizeof(accel_3d_channels), - GFP_KERNEL); + channels = kmemdup(accel_3d_channels, sizeof(accel_3d_channels), + GFP_KERNEL); if (!channels) { + ret = -ENOMEM; dev_err(&pdev->dev, "failed to duplicate channels\n"); goto error_free_dev; } diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c index 02ef989b830..4c8b158e40e 100644 --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c @@ -306,10 +306,10 @@ static int __devinit hid_gyro_3d_probe(struct platform_device *pdev) goto error_free_dev; } - channels = kmemdup(gyro_3d_channels, - sizeof(gyro_3d_channels), - GFP_KERNEL); + channels = kmemdup(gyro_3d_channels, sizeof(gyro_3d_channels), + GFP_KERNEL); if (!channels) { + ret = -ENOMEM; dev_err(&pdev->dev, "failed to duplicate channels\n"); goto error_free_dev; } diff --git a/drivers/iio/light/hid-sensor-als.c b/drivers/iio/light/hid-sensor-als.c index 8e1f69844ee..23eeeef64e8 100644 --- a/drivers/iio/light/hid-sensor-als.c +++ b/drivers/iio/light/hid-sensor-als.c @@ -272,10 +272,9 @@ static int __devinit hid_als_probe(struct platform_device *pdev) goto error_free_dev; } - channels = kmemdup(als_channels, - sizeof(als_channels), - GFP_KERNEL); + channels = kmemdup(als_channels, sizeof(als_channels), GFP_KERNEL); if (!channels) { + ret = -ENOMEM; dev_err(&pdev->dev, "failed to duplicate channels\n"); goto error_free_dev; } diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c index d1b5fb74b9b..8e75eb76ccd 100644 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c @@ -307,10 +307,10 @@ static int __devinit hid_magn_3d_probe(struct platform_device *pdev) goto error_free_dev; } - channels = kmemdup(magn_3d_channels, - sizeof(magn_3d_channels), - GFP_KERNEL); + channels = kmemdup(magn_3d_channels, sizeof(magn_3d_channels), + GFP_KERNEL); if (!channels) { + ret = -ENOMEM; dev_err(&pdev->dev, "failed to duplicate channels\n"); goto error_free_dev; } -- cgit v1.2.3 From e41105687b90819d04226ee454e2dd0fc1130810 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Tue, 23 Oct 2012 16:16:23 +0200 Subject: iommu/amd: Update MAINTAINERS entry I have no access to my AMD email address anymore. Update entry in MAINTAINERS to the new address. Signed-off-by: Joerg Roedel --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index bb0b27db673..0f043a72985 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -526,10 +526,10 @@ F: drivers/video/geode/ F: arch/x86/include/asm/geode.h AMD IOMMU (AMD-VI) -M: Joerg Roedel +M: Joerg Roedel L: iommu@lists.linux-foundation.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git -S: Supported +S: Maintained F: drivers/iommu/amd_iommu*.[ch] F: include/linux/amd-iommu.h -- cgit v1.2.3 From c22618a11d1ba2966bd2cfd5e4918ed4f2dad13e Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 14 Nov 2012 22:37:12 +0000 Subject: drivers/of: Constify device_node->name and ->path_component_name Neither of these should ever be changed once set. Make them const and fix up the users that try to modify it in-place. In one case kmalloc+memcpy is replaced with kstrdup() to avoid modifying the string. Build tested with defconfigs on ARM, PowerPC, Sparc, MIPS, x86 among others. Signed-off-by: Grant Likely Acked-by: David S. Miller Cc: Benjamin Herrenschmidt Cc: Julian Calaby --- arch/powerpc/platforms/powermac/pfunc_core.c | 2 +- arch/powerpc/platforms/pseries/reconfig.c | 3 +-- arch/powerpc/sysdev/fsl_pci.c | 2 +- arch/sparc/kernel/pci_impl.h | 2 +- drivers/of/fdt.c | 10 +++++----- include/linux/of.h | 4 ++-- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index b0c3777528a..d588e48dff7 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c @@ -686,7 +686,7 @@ static int pmf_add_functions(struct pmf_device *dev, void *driverdata) int count = 0; for (pp = dev->node->properties; pp != 0; pp = pp->next) { - char *name; + const char *name; if (strncmp(pp->name, PP_PREFIX, plen) != 0) continue; name = pp->name + plen; diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index 39f71fba9b3..2f4668136b2 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c @@ -281,12 +281,11 @@ static struct property *new_property(const char *name, const int length, if (!new) return NULL; - if (!(new->name = kmalloc(strlen(name) + 1, GFP_KERNEL))) + if (!(new->name = kstrdup(name, GFP_KERNEL))) goto cleanup; if (!(new->value = kmalloc(length + 1, GFP_KERNEL))) goto cleanup; - strcpy(new->name, name); memcpy(new->value, value, length); *(((char *)new->value) + length) = 0; new->length = length; diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index ffb93ae9379..01b62a62c63 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -136,7 +136,7 @@ static void __init setup_pci_atmu(struct pci_controller *hose, u32 pcicsrbar = 0, pcicsrbar_sz; u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL | PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP; - char *name = hose->dn->full_name; + const char *name = hose->dn->full_name; const u64 *reg; int len; diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h index 918a2031c8b..5f688531f48 100644 --- a/arch/sparc/kernel/pci_impl.h +++ b/arch/sparc/kernel/pci_impl.h @@ -88,7 +88,7 @@ struct pci_pbm_info { int chip_revision; /* Name used for top-level resources. */ - char *name; + const char *name; /* OBP specific information. */ struct platform_device *op; diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index c2b08dcdbc5..c8be32644c8 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -199,10 +199,10 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl, __alignof__(struct device_node)); if (allnextpp) { + char *fn; memset(np, 0, sizeof(*np)); - np->full_name = ((char *)np) + sizeof(struct device_node); + np->full_name = fn = ((char *)np) + sizeof(*np); if (new_format) { - char *fn = np->full_name; /* rebuild full path for new format */ if (dad && dad->parent) { strcpy(fn, dad->full_name); @@ -216,9 +216,9 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, fn += strlen(fn); } *(fn++) = '/'; - memcpy(fn, pathp, l); - } else - memcpy(np->full_name, pathp, l); + } + memcpy(fn, pathp, l); + prev_pp = &np->properties; **allnextpp = np; *allnextpp = &np->allnext; diff --git a/include/linux/of.h b/include/linux/of.h index b4e50d56fc7..857dde984a6 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -46,7 +46,7 @@ struct device_node { const char *name; const char *type; phandle phandle; - char *full_name; + const char *full_name; struct property *properties; struct property *deadprops; /* removed properties */ @@ -60,7 +60,7 @@ struct device_node { unsigned long _flags; void *data; #if defined(CONFIG_SPARC) - char *path_component_name; + const char *path_component_name; unsigned int unique_id; struct of_irq_controller *irq_trans; #endif -- cgit v1.2.3 From b334b64862efd0eee8d07f2faabbe4b56ee974cd Mon Sep 17 00:00:00 2001 From: Cyril Roelandt Date: Sun, 11 Nov 2012 21:49:30 +0100 Subject: iommu/tegra-smmu.c: fix dentry reference leak in smmu_debugfs_stats_show(). Call to d_find_alias() needs a corresponding dput(). Signed-off-by: Cyril Roelandt Signed-off-by: Joerg Roedel --- drivers/iommu/tegra-smmu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index a649f146d17..c0f7a426626 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -1054,6 +1054,7 @@ static int smmu_debugfs_stats_show(struct seq_file *s, void *v) stats[i], val, offs); } seq_printf(s, "\n"); + dput(dent); return 0; } -- cgit v1.2.3 From 3da4af0affbb797e8ac4c2b4598da0c34b8cc52a Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 13 Nov 2012 10:22:03 -0700 Subject: intel-iommu: Fix lookup in add device We can't assume this device exists, fall back to the bridge itself. Signed-off-by: Alex Williamson Tested-by: Matthew Thode Cc: stable@vger.kernel.org Signed-off-by: Joerg Roedel --- drivers/iommu/intel-iommu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index d4a4cd445ca..0badfa48b32 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4108,7 +4108,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to) static int intel_iommu_add_device(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - struct pci_dev *bridge, *dma_pdev; + struct pci_dev *bridge, *dma_pdev = NULL; struct iommu_group *group; int ret; @@ -4122,7 +4122,7 @@ static int intel_iommu_add_device(struct device *dev) dma_pdev = pci_get_domain_bus_and_slot( pci_domain_nr(pdev->bus), bridge->subordinate->number, 0); - else + if (!dma_pdev) dma_pdev = pci_dev_get(bridge); } else dma_pdev = pci_dev_get(pdev); -- cgit v1.2.3 From 42e2976f131d65555d5c1d6c3d47facc63577814 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 12 Nov 2012 22:09:44 +1100 Subject: xfs: fix attr tree double split corruption In certain circumstances, a double split of an attribute tree is needed to insert or replace an attribute. In rare situations, this can go wrong, leaving the attribute tree corrupted. In this case, the attr being replaced is the last attr in a leaf node, and the replacement is larger so doesn't fit in the same leaf node. When we have the initial condition of a node format attribute btree with two leaves at index 1 and 2. Call them L1 and L2. The leaf L1 is completely full, there is not a single byte of free space in it. L2 is mostly empty. The attribute being replaced - call it X - is the last attribute in L1. The way an attribute replace is executed is that the replacement attribute - call it Y - is first inserted into the tree, but has an INCOMPLETE flag set on it so that list traversals ignore it. Once this transaction is committed, a second transaction it run to atomically mark Y as COMPLETE and X as INCOMPLETE, so that a traversal will now find Y and skip X. Once that transaction is committed, attribute X is then removed. So, the initial condition is: +--------+ +--------+ | L1 | | L2 | | fwd: 2 |---->| fwd: 0 | | bwd: 0 |<----| bwd: 1 | | fsp: 0 | | fsp: N | |--------| |--------| | attr A | | attr 1 | |--------| |--------| | attr B | | attr 2 | |--------| |--------| .......... .......... |--------| |--------| | attr X | | attr n | +--------+ +--------+ So now we go to replace X, and see that L1:fsp = 0 - it is full so we can't insert Y in the same leaf. So we record the the location of attribute X so we can track it for later use, then we split L1 into L1 and L3 and reblance across the two leafs. We end with: +--------+ +--------+ +--------+ | L1 | | L3 | | L2 | | fwd: 3 |---->| fwd: 2 |---->| fwd: 0 | | bwd: 0 |<----| bwd: 1 |<----| bwd: 3 | | fsp: M | | fsp: J | | fsp: N | |--------| |--------| |--------| | attr A | | attr X | | attr 1 | |--------| +--------+ |--------| | attr B | | attr 2 | |--------| |--------| .......... .......... |--------| |--------| | attr W | | attr n | +--------+ +--------+ And we track that the original attribute is now at L3:0. We then try to insert Y into L1 again, and find that there isn't enough room because the new attribute is larger than the old one. Hence we have to split again to make room for Y. We end up with this: +--------+ +--------+ +--------+ +--------+ | L1 | | L4 | | L3 | | L2 | | fwd: 4 |---->| fwd: 3 |---->| fwd: 2 |---->| fwd: 0 | | bwd: 0 |<----| bwd: 1 |<----| bwd: 4 |<----| bwd: 3 | | fsp: M | | fsp: J | | fsp: J | | fsp: N | |--------| |--------| |--------| |--------| | attr A | | attr Y | | attr X | | attr 1 | |--------| + INCOMP + +--------+ |--------| | attr B | +--------+ | attr 2 | |--------| |--------| .......... .......... |--------| |--------| | attr W | | attr n | +--------+ +--------+ And now we have the new (incomplete) attribute @ L4:0, and the original attribute at L3:0. At this point, the first transaction is committed, and we move to the flipping of the flags. This is where we are supposed to end up with this: +--------+ +--------+ +--------+ +--------+ | L1 | | L4 | | L3 | | L2 | | fwd: 4 |---->| fwd: 3 |---->| fwd: 2 |---->| fwd: 0 | | bwd: 0 |<----| bwd: 1 |<----| bwd: 4 |<----| bwd: 3 | | fsp: M | | fsp: J | | fsp: J | | fsp: N | |--------| |--------| |--------| |--------| | attr A | | attr Y | | attr X | | attr 1 | |--------| +--------+ + INCOMP + |--------| | attr B | +--------+ | attr 2 | |--------| |--------| .......... .......... |--------| |--------| | attr W | | attr n | +--------+ +--------+ But that doesn't happen properly - the attribute tracking indexes are not pointing to the right locations. What we end up with is both the old attribute to be removed pointing at L4:0 and the new attribute at L4:1. On a debug kernel, this assert fails like so: XFS: Assertion failed: args->index2 < be16_to_cpu(leaf2->hdr.count), file: fs/xfs/xfs_attr_leaf.c, line: 2725 because the new attribute location does not exist. On a production kernel, this goes unnoticed and the code proceeds ahead merrily and removes L4 because it thinks that is the block that is no longer needed. This leaves the hash index node pointing to entries L1, L4 and L2, but only blocks L1, L3 and L2 to exist. Further, the leaf level sibling list is L1 <-> L4 <-> L2, but L4 is now free space, and so everything is busted. This corruption is caused by the removal of the old attribute triggering a join - it joins everything correctly but then frees the wrong block. xfs_repair will report something like: bad sibling back pointer for block 4 in attribute fork for inode 131 problem with attribute contents in inode 131 would clear attr fork bad nblocks 8 for inode 131, would reset to 3 bad anextents 4 for inode 131, would reset to 0 The problem lies in the assignment of the old/new blocks for tracking purposes when the double leaf split occurs. The first split tries to place the new attribute inside the current leaf (i.e. "inleaf == true") and moves the old attribute (X) to the new block. This sets up the old block/index to L1:X, and newly allocated block to L3:0. It then moves attr X to the new block and tries to insert attr Y at the old index. That fails, so it splits again. With the second split, the rebalance ends up placing the new attr in the second new block - L4:0 - and this is where the code goes wrong. What is does is it sets both the new and old block index to the second new block. Hence it inserts attr Y at the right place (L4:0) but overwrites the current location of the attr to replace that is held in the new block index (currently L3:0). It over writes it with L4:1 - the index we later assert fail on. Hopefully this table will show this in a foramt that is a bit easier to understand: Split old attr index new attr index vanilla patched vanilla patched before 1st L1:26 L1:26 N/A N/A after 1st L3:0 L3:0 L1:26 L1:26 after 2nd L4:0 L3:0 L4:1 L4:0 ^^^^ ^^^^ wrong wrong The fix is surprisingly simple, for all this analysis - just stop the rebalance on the out-of leaf case from overwriting the new attr index - it's already correct for the double split case. Signed-off-by: Dave Chinner Reviewed-by: Mark Tinguely Signed-off-by: Ben Myers --- fs/xfs/xfs_attr_leaf.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index d330111ca73..70eec182977 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -1291,6 +1291,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, leaf2 = blk2->bp->b_addr; ASSERT(leaf1->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); ASSERT(leaf2->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC)); + ASSERT(leaf2->hdr.count == 0); args = state->args; trace_xfs_attr_leaf_rebalance(args); @@ -1361,6 +1362,7 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, * I assert that since all callers pass in an empty * second buffer, this code should never execute. */ + ASSERT(0); /* * Figure the total bytes to be added to the destination leaf. @@ -1422,10 +1424,24 @@ xfs_attr_leaf_rebalance(xfs_da_state_t *state, xfs_da_state_blk_t *blk1, args->index2 = 0; args->blkno2 = blk2->blkno; } else { + /* + * On a double leaf split, the original attr location + * is already stored in blkno2/index2, so don't + * overwrite it overwise we corrupt the tree. + */ blk2->index = blk1->index - be16_to_cpu(leaf1->hdr.count); - args->index = args->index2 = blk2->index; - args->blkno = args->blkno2 = blk2->blkno; + args->index = blk2->index; + args->blkno = blk2->blkno; + if (!state->extravalid) { + /* + * set the new attr location to match the old + * one and let the higher level split code + * decide where in the leaf to place it. + */ + args->index2 = blk2->index; + args->blkno2 = blk2->blkno; + } } } else { ASSERT(state->inleaf == 1); -- cgit v1.2.3 From 3daed8bc3e49b9695ae931b9f472b5b90d1965b3 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 12 Nov 2012 22:09:45 +1100 Subject: xfs: fix broken error handling in xfs_vm_writepage When we shut down the filesystem, it might first be detected in writeback when we are allocating a inode size transaction. This happens after we have moved all the pages into the writeback state and unlocked them. Unfortunately, if we fail to set up the transaction we then abort writeback and try to invalidate the current page. This then triggers are BUG() in block_invalidatepage() because we are trying to invalidate an unlocked page. Fixing this is a bit of a chicken and egg problem - we can't allocate the transaction until we've clustered all the pages into the IO and we know the size of it (i.e. whether the last block of the IO is beyond the current EOF or not). However, we don't want to hold pages locked for long periods of time, especially while we lock other pages to cluster them into the write. To fix this, we need to make a clear delineation in writeback where errors can only be handled by IO completion processing. That is, once we have marked a page for writeback and unlocked it, we have to report errors via IO completion because we've already started the IO. We may not have submitted any IO, but we've changed the page state to indicate that it is under IO so we must now use the IO completion path to report errors. To do this, add an error field to xfs_submit_ioend() to pass it the error that occurred during the building on the ioend chain. When this is non-zero, mark each ioend with the error and call xfs_finish_ioend() directly rather than building bios. This will immediately push the ioends through completion processing with the error that has occurred. Signed-off-by: Dave Chinner Reviewed-by: Mark Tinguely Signed-off-by: Ben Myers --- fs/xfs/xfs_aops.c | 54 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index e562dd43f41..e57e2daa357 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -481,11 +481,17 @@ static inline int bio_add_buffer(struct bio *bio, struct buffer_head *bh) * * The fix is two passes across the ioend list - one to start writeback on the * buffer_heads, and then submit them for I/O on the second pass. + * + * If @fail is non-zero, it means that we have a situation where some part of + * the submission process has failed after we have marked paged for writeback + * and unlocked them. In this situation, we need to fail the ioend chain rather + * than submit it to IO. This typically only happens on a filesystem shutdown. */ STATIC void xfs_submit_ioend( struct writeback_control *wbc, - xfs_ioend_t *ioend) + xfs_ioend_t *ioend, + int fail) { xfs_ioend_t *head = ioend; xfs_ioend_t *next; @@ -506,6 +512,18 @@ xfs_submit_ioend( next = ioend->io_list; bio = NULL; + /* + * If we are failing the IO now, just mark the ioend with an + * error and finish it. This will run IO completion immediately + * as there is only one reference to the ioend at this point in + * time. + */ + if (fail) { + ioend->io_error = -fail; + xfs_finish_ioend(ioend); + continue; + } + for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) { if (!bio) { @@ -1060,7 +1078,18 @@ xfs_vm_writepage( xfs_start_page_writeback(page, 1, count); - if (ioend && imap_valid) { + /* if there is no IO to be submitted for this page, we are done */ + if (!ioend) + return 0; + + ASSERT(iohead); + + /* + * Any errors from this point onwards need tobe reported through the IO + * completion path as we have marked the initial page as under writeback + * and unlocked it. + */ + if (imap_valid) { xfs_off_t end_index; end_index = imap.br_startoff + imap.br_blockcount; @@ -1079,20 +1108,15 @@ xfs_vm_writepage( wbc, end_index); } - if (iohead) { - /* - * Reserve log space if we might write beyond the on-disk - * inode size. - */ - if (ioend->io_type != XFS_IO_UNWRITTEN && - xfs_ioend_is_append(ioend)) { - err = xfs_setfilesize_trans_alloc(ioend); - if (err) - goto error; - } - xfs_submit_ioend(wbc, iohead); - } + /* + * Reserve log space if we might write beyond the on-disk inode size. + */ + err = 0; + if (ioend->io_type != XFS_IO_UNWRITTEN && xfs_ioend_is_append(ioend)) + err = xfs_setfilesize_trans_alloc(ioend); + + xfs_submit_ioend(wbc, iohead, err); return 0; -- cgit v1.2.3 From d69043c42d8c6414fa28ad18d99973aa6c1c2e24 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 12 Nov 2012 22:09:46 +1100 Subject: xfs: drop buffer io reference when a bad bio is built Error handling in xfs_buf_ioapply_map() does not handle IO reference counts correctly. We increment the b_io_remaining count before building the bio, but then fail to decrement it in the failure case. This leads to the buffer never running IO completion and releasing the reference that the IO holds, so at unmount we can leak the buffer. This leak is captured by this assert failure during unmount: XFS: Assertion failed: atomic_read(&pag->pag_ref) == 0, file: fs/xfs/xfs_mount.c, line: 273 This is not a new bug - the b_io_remaining accounting has had this problem for a long, long time - it's just very hard to get a zero length bio being built by this code... Further, the buffer IO error can be overwritten on a multi-segment buffer by subsequent bio completions for partial sections of the buffer. Hence we should only set the buffer error status if the buffer is not already carrying an error status. This ensures that a partial IO error on a multi-segment buffer will not be lost. This part of the problem is a regression, however. cc: Signed-off-by: Dave Chinner Reviewed-by: Mark Tinguely Signed-off-by: Ben Myers --- fs/xfs/xfs_buf.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 933b7930b86..4b0b8dd1b7b 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1197,9 +1197,14 @@ xfs_buf_bio_end_io( { xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private; - xfs_buf_ioerror(bp, -error); + /* + * don't overwrite existing errors - otherwise we can lose errors on + * buffers that require multiple bios to complete. + */ + if (!bp->b_error) + xfs_buf_ioerror(bp, -error); - if (!error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) + if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp)); _xfs_buf_ioend(bp, 1); @@ -1279,6 +1284,11 @@ next_chunk: if (size) goto next_chunk; } else { + /* + * This is guaranteed not to be the last io reference count + * because the caller (xfs_buf_iorequest) holds a count itself. + */ + atomic_dec(&bp->b_io_remaining); xfs_buf_ioerror(bp, EIO); bio_put(bio); } -- cgit v1.2.3 From 55ecd26373bc995c279a5d988ee36c2767e4f3ca Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 8 Nov 2012 18:01:51 +0100 Subject: gpio: pca953x: Register an IRQ domain The PCA953x used to register no IRQ domain, which made it impossible to use it as an interrupt-parent from the device tree. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pca953x.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 9c693ae1795..5ba7e60de94 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,7 @@ struct pca953x_chip { u32 irq_trig_raise; u32 irq_trig_fall; int irq_base; + struct irq_domain *domain; #endif struct i2c_client *client; @@ -333,14 +335,14 @@ static void pca953x_irq_mask(struct irq_data *d) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); - chip->irq_mask &= ~(1 << (d->irq - chip->irq_base)); + chip->irq_mask &= ~(1 << d->hwirq); } static void pca953x_irq_unmask(struct irq_data *d) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); - chip->irq_mask |= 1 << (d->irq - chip->irq_base); + chip->irq_mask |= 1 << d->hwirq; } static void pca953x_irq_bus_lock(struct irq_data *d) @@ -372,8 +374,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) { struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); - u32 level = d->irq - chip->irq_base; - u32 mask = 1 << level; + u32 mask = 1 << d->hwirq; if (!(type & IRQ_TYPE_EDGE_BOTH)) { dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", @@ -454,7 +455,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) do { level = __ffs(pending); - handle_nested_irq(level + chip->irq_base); + handle_nested_irq(irq_find_mapping(chip->domain, level)); pending &= ~(1 << level); } while (pending); @@ -499,6 +500,17 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, if (chip->irq_base < 0) goto out_failed; + chip->domain = irq_domain_add_legacy(client->dev.of_node, + chip->gpio_chip.ngpio, + chip->irq_base, + 0, + &irq_domain_simple_ops, + NULL); + if (!chip->domain) { + ret = -ENODEV; + goto out_irqdesc_free; + } + for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { int irq = lvl + chip->irq_base; @@ -521,7 +533,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, if (ret) { dev_err(&client->dev, "failed to request irq %d\n", client->irq); - goto out_failed; + goto out_irqdesc_free; } chip->gpio_chip.to_irq = pca953x_gpio_to_irq; @@ -529,6 +541,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, return 0; +out_irqdesc_free: + irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio); out_failed: chip->irq_base = -1; return ret; -- cgit v1.2.3 From ed32620ea72889c8a9dda278a960bce01136d9a4 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 8 Nov 2012 18:01:52 +0100 Subject: gpio: pca953x: Add compatible strings to gpio-pca953x driver Even though the device tree binding code was already written, the compatible strings were not yet in the driver. Signed-off-by: Maxime Ripard Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pca953x.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 5ba7e60de94..0c5eaf5f4c9 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -765,9 +765,38 @@ static int pca953x_remove(struct i2c_client *client) return 0; } +static const struct of_device_id pca953x_dt_ids[] = { + { .compatible = "nxp,pca9534", }, + { .compatible = "nxp,pca9535", }, + { .compatible = "nxp,pca9536", }, + { .compatible = "nxp,pca9537", }, + { .compatible = "nxp,pca9538", }, + { .compatible = "nxp,pca9539", }, + { .compatible = "nxp,pca9554", }, + { .compatible = "nxp,pca9555", }, + { .compatible = "nxp,pca9556", }, + { .compatible = "nxp,pca9557", }, + { .compatible = "nxp,pca9574", }, + { .compatible = "nxp,pca9575", }, + + { .compatible = "maxim,max7310", }, + { .compatible = "maxim,max7312", }, + { .compatible = "maxim,max7313", }, + { .compatible = "maxim,max7315", }, + + { .compatible = "ti,pca6107", }, + { .compatible = "ti,tca6408", }, + { .compatible = "ti,tca6416", }, + { .compatible = "ti,tca6424", }, + { } +}; + +MODULE_DEVICE_TABLE(of, pca953x_dt_ids); + static struct i2c_driver pca953x_driver = { .driver = { .name = "pca953x", + .of_match_table = pca953x_dt_ids, }, .probe = pca953x_probe, .remove = pca953x_remove, -- cgit v1.2.3 From 195812e4b6a631e8eaad4046bf6890db4328ea1f Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 9 Nov 2012 11:34:20 +0530 Subject: gpio: tegra: read output value when gpio is set in direction_out Read the output value when gpio is set for the output mode for gpio_get_value(). Reading input value in direction out does not give correct value. Signed-off-by: Laxman Dewangan Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index cfd9b723002..5389be8c2b5 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -134,6 +134,11 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) { + /* If gpio is in output mode then read from the out value */ + if ((tegra_gpio_readl(GPIO_OE(offset)) >> GPIO_BIT(offset)) & 1) + return (tegra_gpio_readl(GPIO_OUT(offset)) >> + GPIO_BIT(offset)) & 0x1; + return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; } -- cgit v1.2.3 From 9859eb99e9212339e2009b98c396b08260276edf Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 13 Nov 2012 10:35:13 +0100 Subject: gpio: twl4030: Use only TWL4030_MODULE_LED for LED configuration Avoid using the TWL4030_MODULE_PWMA/B as module ID. The LEDEN, PWMA ON/OFF and PWMB ON/OFF registers are in a continuous range starting from LED base. This is going to be helpful for further cleanup in the twl stack. No functional changes. Signed-off-by: Peter Ujfalusi Signed-off-by: Linus Walleij --- drivers/gpio/gpio-twl4030.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c index c5f8ca233e1..d2138b0fd4c 100644 --- a/drivers/gpio/gpio-twl4030.c +++ b/drivers/gpio/gpio-twl4030.c @@ -88,11 +88,15 @@ static inline int gpio_twl4030_write(u8 address, u8 data) /*----------------------------------------------------------------------*/ /* - * LED register offsets (use TWL4030_MODULE_{LED,PWMA,PWMB})) + * LED register offsets from TWL_MODULE_LED base * PWMs A and B are dedicated to LEDs A and B, respectively. */ -#define TWL4030_LED_LEDEN 0x0 +#define TWL4030_LED_LEDEN_REG 0x00 +#define TWL4030_PWMAON_REG 0x01 +#define TWL4030_PWMAOFF_REG 0x02 +#define TWL4030_PWMBON_REG 0x03 +#define TWL4030_PWMBOFF_REG 0x04 /* LEDEN bits */ #define LEDEN_LEDAON BIT(0) @@ -104,9 +108,6 @@ static inline int gpio_twl4030_write(u8 address, u8 data) #define LEDEN_PWM_LENGTHA BIT(6) #define LEDEN_PWM_LENGTHB BIT(7) -#define TWL4030_PWMx_PWMxON 0x0 -#define TWL4030_PWMx_PWMxOFF 0x1 - #define PWMxON_LENGTH BIT(7) /*----------------------------------------------------------------------*/ @@ -145,7 +146,7 @@ static void twl4030_led_set_value(int led, int value) else cached_leden |= mask; status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden, - TWL4030_LED_LEDEN); + TWL4030_LED_LEDEN_REG); mutex_unlock(&gpio_lock); } @@ -216,33 +217,33 @@ static int twl_request(struct gpio_chip *chip, unsigned offset) if (offset >= TWL4030_GPIO_MAX) { u8 ledclr_mask = LEDEN_LEDAON | LEDEN_LEDAEXT | LEDEN_LEDAPWM | LEDEN_PWM_LENGTHA; - u8 module = TWL4030_MODULE_PWMA; + u8 reg = TWL4030_PWMAON_REG; offset -= TWL4030_GPIO_MAX; if (offset) { ledclr_mask <<= 1; - module = TWL4030_MODULE_PWMB; + reg = TWL4030_PWMBON_REG; } /* initialize PWM to always-drive */ - status = twl_i2c_write_u8(module, 0x7f, - TWL4030_PWMx_PWMxOFF); + /* Configure PWM OFF register first */ + status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg + 1); if (status < 0) goto done; - status = twl_i2c_write_u8(module, 0x7f, - TWL4030_PWMx_PWMxON); + + /* Followed by PWM ON register */ + status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg); if (status < 0) goto done; /* init LED to not-driven (high) */ - module = TWL4030_MODULE_LED; - status = twl_i2c_read_u8(module, &cached_leden, - TWL4030_LED_LEDEN); + status = twl_i2c_read_u8(TWL4030_MODULE_LED, &cached_leden, + TWL4030_LED_LEDEN_REG); if (status < 0) goto done; cached_leden &= ~ledclr_mask; - status = twl_i2c_write_u8(module, cached_leden, - TWL4030_LED_LEDEN); + status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden, + TWL4030_LED_LEDEN_REG); if (status < 0) goto done; -- cgit v1.2.3 From 8754fccbae661a0020923cffd63e21de36d51e2e Mon Sep 17 00:00:00 2001 From: Roland Stigge Date: Thu, 15 Nov 2012 14:59:40 +0100 Subject: gpio: gpio-max710x: Support device tree probing For probing via device tree, we need to support the case without platform_data. In this case, chip.base is set to -1 for automatic numbering. Signed-off-by: Roland Stigge Acked-by: Wolfram Sang Signed-off-by: Linus Walleij --- drivers/gpio/gpio-max730x.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c index 05e2dac60b3..c4bf86abd4d 100644 --- a/drivers/gpio/gpio-max730x.c +++ b/drivers/gpio/gpio-max730x.c @@ -167,10 +167,6 @@ int __devinit __max730x_probe(struct max7301 *ts) int i, ret; pdata = dev->platform_data; - if (!pdata || !pdata->base) { - dev_err(dev, "incorrect or missing platform data\n"); - return -EINVAL; - } mutex_init(&ts->lock); dev_set_drvdata(dev, ts); @@ -178,7 +174,12 @@ int __devinit __max730x_probe(struct max7301 *ts) /* Power up the chip and disable IRQ output */ ts->write(dev, 0x04, 0x01); - ts->input_pullup_active = pdata->input_pullup_active; + if (pdata) { + ts->input_pullup_active = pdata->input_pullup_active; + ts->chip.base = pdata->base; + } else { + ts->chip.base = -1; + } ts->chip.label = dev->driver->name; ts->chip.direction_input = max7301_direction_input; @@ -186,7 +187,6 @@ int __devinit __max730x_probe(struct max7301 *ts) ts->chip.direction_output = max7301_direction_output; ts->chip.set = max7301_set; - ts->chip.base = pdata->base; ts->chip.ngpio = PIN_NUMBER; ts->chip.can_sleep = 1; ts->chip.dev = dev; -- cgit v1.2.3 From e91337609afdfaa1936c91b519ba7d7e426814cc Mon Sep 17 00:00:00 2001 From: Jamie Lentin Date: Sun, 28 Oct 2012 12:23:24 +0000 Subject: mvebu-gpio: Disable blinking when enabling a GPIO for output The plat-orion GPIO driver would disable any pin blinking whenever using a pin for output. Do the same here, as a blinking LED will continue to blink regardless of what the GPIO pin level is. Signed-off-by: Jamie Lentin Acked-by: Thomas Petazzoni Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mvebu.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index cf7afb9eb61..be65c0451ad 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -92,6 +92,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip) return mvchip->membase + GPIO_OUT_OFF; } +static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip) +{ + return mvchip->membase + GPIO_BLINK_EN_OFF; +} + static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip) { return mvchip->membase + GPIO_IO_CONF_OFF; @@ -206,6 +211,23 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin) return (u >> pin) & 1; } +static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value) +{ + struct mvebu_gpio_chip *mvchip = + container_of(chip, struct mvebu_gpio_chip, chip); + unsigned long flags; + u32 u; + + spin_lock_irqsave(&mvchip->lock, flags); + u = readl_relaxed(mvebu_gpioreg_blink(mvchip)); + if (value) + u |= 1 << pin; + else + u &= ~(1 << pin); + writel_relaxed(u, mvebu_gpioreg_blink(mvchip)); + spin_unlock_irqrestore(&mvchip->lock, flags); +} + static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin) { struct mvebu_gpio_chip *mvchip = @@ -244,6 +266,7 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin, if (ret) return ret; + mvebu_gpio_blink(chip, pin, 0); mvebu_gpio_set(chip, pin, value); spin_lock_irqsave(&mvchip->lock, flags); -- cgit v1.2.3 From cb144fe8e0e70ccb12e93c9c9f010a25b3f2a158 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 1 Nov 2012 11:22:11 +0100 Subject: gpio: adnp: Depend on OF_GPIO instead of OF The driver accesses the of_node field of struct gpio_chip, which is only available if OF_GPIO is selected. This solves a build issue on SPARC which conflicts with OF_GPIO and therefore does not provide this field. Signed-off-by: Thierry Reding Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index f11d8e3b404..47150f5ded0 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -466,7 +466,7 @@ config GPIO_ADP5588_IRQ config GPIO_ADNP tristate "Avionic Design N-bit GPIO expander" - depends on I2C && OF + depends on I2C && OF_GPIO help This option enables support for N GPIOs found on Avionic Design I2C GPIO expanders. The register space will be extended by powers -- cgit v1.2.3 From cbf24fad8e6e97b7cd7dd1099f5b801689dc234a Mon Sep 17 00:00:00 2001 From: "Daniel M. Weeks" Date: Tue, 6 Nov 2012 23:51:05 -0500 Subject: gpio-mcp23s08: Build I2C support even when CONFIG_I2C=m The driver has both SPI and I2C pieces. The appropriate pieces are built based on whether SPI and/or I2C is/are enabled. However, it was only checking if I2C was built-in, never if it was built as a module. This patch checks for either since building both this driver and I2C as modules is possible. Signed-off-by: Daniel M. Weeks Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mcp23s08.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 0f425189de1..ce1c8476007 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -77,7 +77,7 @@ struct mcp23s08_driver_data { /*----------------------------------------------------------------------*/ -#ifdef CONFIG_I2C +#if IS_ENABLED(CONFIG_I2C) static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) { @@ -399,7 +399,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, break; #endif /* CONFIG_SPI_MASTER */ -#ifdef CONFIG_I2C +#if IS_ENABLED(CONFIG_I2C) case MCP_TYPE_008: mcp->ops = &mcp23008_ops; mcp->chip.ngpio = 8; @@ -473,7 +473,7 @@ fail: /*----------------------------------------------------------------------*/ -#ifdef CONFIG_I2C +#if IS_ENABLED(CONFIG_I2C) static int __devinit mcp230xx_probe(struct i2c_client *client, const struct i2c_device_id *id) -- cgit v1.2.3 From 3ea160b3e8f0de8161861995d9901f61192fc0b0 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 16 Nov 2012 08:06:16 -0800 Subject: target: Fix handling of aborted commands - If we stop processing an already-aborted command in target_execute_cmd(), then we need to complete t_transport_stop_comp to wake up the the TMR handling thread, or else it will end up waiting forever. - If we've a already sent an "aborted" status for a command in transport_check_aborted_status() then we should bail out of transport_send_task_abort() to avoid freeing the command twice. Signed-off-by: Roland Dreier Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_transport.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 9097155e9eb..dcecbfb1724 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1819,8 +1819,10 @@ void target_execute_cmd(struct se_cmd *cmd) /* * If the received CDB has aleady been aborted stop processing it here. */ - if (transport_check_aborted_status(cmd, 1)) + if (transport_check_aborted_status(cmd, 1)) { + complete(&cmd->t_transport_stop_comp); return; + } /* * Determine if IOCTL context caller in requesting the stopping of this @@ -3067,7 +3069,7 @@ void transport_send_task_abort(struct se_cmd *cmd) unsigned long flags; spin_lock_irqsave(&cmd->t_state_lock, flags); - if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { + if (cmd->se_cmd_flags & (SCF_SENT_CHECK_CONDITION | SCF_SENT_DELAYED_TAS)) { spin_unlock_irqrestore(&cmd->t_state_lock, flags); return; } -- cgit v1.2.3 From b53bc2819a71099ecfc3d61ba0796b3dcc6be321 Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Fri, 16 Nov 2012 10:45:25 +0530 Subject: gpio: SPEAr: add spi chipselect control driver SPEAr platform provides a provision to control chipselects of ARM PL022 Prime Cell spi controller through its system registers, which otherwise remains under PL022 control which some protocols do not want. This commit intends to provide the spi chipselect control in software over gpiolib interface. spi chip drivers can use the exported gpiolib interface to define their chipselect through DT or platform data. Cc: Grant Likely Signed-off-by: Shiraz Hashim Reviewed-by: Vipin Kumar Acked-by: Arnd Bergmann Signed-off-by: Viresh Kumar Signed-off-by: Linus Walleij --- .../devicetree/bindings/gpio/spear_spics.txt | 50 +++++ arch/arm/plat-spear/Kconfig | 1 + drivers/gpio/Kconfig | 7 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-spear-spics.c | 217 +++++++++++++++++++++ 5 files changed, 276 insertions(+) create mode 100644 Documentation/devicetree/bindings/gpio/spear_spics.txt create mode 100644 drivers/gpio/gpio-spear-spics.c diff --git a/Documentation/devicetree/bindings/gpio/spear_spics.txt b/Documentation/devicetree/bindings/gpio/spear_spics.txt new file mode 100644 index 00000000000..96c37eb1507 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/spear_spics.txt @@ -0,0 +1,50 @@ +=== ST Microelectronics SPEAr SPI CS Driver === + +SPEAr platform provides a provision to control chipselects of ARM PL022 Prime +Cell spi controller through its system registers, which otherwise remains under +PL022 control. If chipselect remain under PL022 control then they would be +released as soon as transfer is over and TxFIFO becomes empty. This is not +desired by some of the device protocols above spi which expect (multiple) +transfers without releasing their chipselects. + +Chipselects can be controlled by software by turning them as GPIOs. SPEAr +provides another interface through system registers through which software can +directly control each PL022 chipselect. Hence, it is natural for SPEAr to export +the control of this interface as gpio. + +Required properties: + + * compatible: should be defined as "st,spear-spics-gpio" + * reg: mentioning address range of spics controller + * st-spics,peripcfg-reg: peripheral configuration register offset + * st-spics,sw-enable-bit: bit offset to enable sw control + * st-spics,cs-value-bit: bit offset to drive chipselect low or high + * st-spics,cs-enable-mask: chip select number bit mask + * st-spics,cs-enable-shift: chip select number program offset + * gpio-controller: Marks the device node as gpio controller + * #gpio-cells: should be 1 and will mention chip select number + +All the above bit offsets are within peripcfg register. + +Example: +------- +spics: spics@e0700000{ + compatible = "st,spear-spics-gpio"; + reg = <0xe0700000 0x1000>; + st-spics,peripcfg-reg = <0x3b0>; + st-spics,sw-enable-bit = <12>; + st-spics,cs-value-bit = <11>; + st-spics,cs-enable-mask = <3>; + st-spics,cs-enable-shift = <8>; + gpio-controller; + #gpio-cells = <2>; +}; + + +spi0: spi@e0100000 { + status = "okay"; + num-cs = <3>; + cs-gpios = <&gpio1 7 0>, <&spics 0>, + <&spics 1>; + ... +} diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig index f8db7b2deb3..87dbd81bdf5 100644 --- a/arch/arm/plat-spear/Kconfig +++ b/arch/arm/plat-spear/Kconfig @@ -12,6 +12,7 @@ config ARCH_SPEAR13XX bool "ST SPEAr13xx with Device Tree" select ARM_GIC select CPU_V7 + select GPIO_SPEAR_SPICS select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 select PINCTRL diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 9e3fb343871..4f592c61599 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -196,6 +196,13 @@ config GPIO_PXA help Say yes here to support the PXA GPIO device +config GPIO_SPEAR_SPICS + bool "ST SPEAr13xx SPI Chip Select as GPIO support" + depends on PLAT_SPEAR + select GENERIC_IRQ_CHIP + help + Say yes here to support ST SPEAr SPI Chip Select as GPIO device + config GPIO_STA2X11 bool "STA2x11/ConneXt GPIO support" depends on MFD_STA2X11 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 1c1b63fcaeb..a268d99f4e4 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -59,6 +59,7 @@ obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o +obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c new file mode 100644 index 00000000000..5f45fc4ed5d --- /dev/null +++ b/drivers/gpio/gpio-spear-spics.c @@ -0,0 +1,217 @@ +/* + * SPEAr platform SPI chipselect abstraction over gpiolib + * + * Copyright (C) 2012 ST Microelectronics + * Shiraz Hashim + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* maximum chipselects */ +#define NUM_OF_GPIO 4 + +/* + * Provision is available on some SPEAr SoCs to control ARM PL022 spi cs + * through system registers. This register lies outside spi (pl022) + * address space into system registers. + * + * It provides control for spi chip select lines so that any chipselect + * (out of 4 possible chipselects in pl022) can be made low to select + * the particular slave. + */ + +/** + * struct spear_spics - represents spi chip select control + * @base: base address + * @perip_cfg: configuration register + * @sw_enable_bit: bit to enable s/w control over chipselects + * @cs_value_bit: bit to program high or low chipselect + * @cs_enable_mask: mask to select bits required to select chipselect + * @cs_enable_shift: bit pos of cs_enable_mask + * @use_count: use count of a spi controller cs lines + * @last_off: stores last offset caller of set_value() + * @chip: gpio_chip abstraction + */ +struct spear_spics { + void __iomem *base; + u32 perip_cfg; + u32 sw_enable_bit; + u32 cs_value_bit; + u32 cs_enable_mask; + u32 cs_enable_shift; + unsigned long use_count; + int last_off; + struct gpio_chip chip; +}; + +/* gpio framework specific routines */ +static int spics_get_value(struct gpio_chip *chip, unsigned offset) +{ + return -ENXIO; +} + +static void spics_set_value(struct gpio_chip *chip, unsigned offset, int value) +{ + struct spear_spics *spics = container_of(chip, struct spear_spics, + chip); + u32 tmp; + + /* select chip select from register */ + tmp = readl_relaxed(spics->base + spics->perip_cfg); + if (spics->last_off != offset) { + spics->last_off = offset; + tmp &= ~(spics->cs_enable_mask << spics->cs_enable_shift); + tmp |= offset << spics->cs_enable_shift; + } + + /* toggle chip select line */ + tmp &= ~(0x1 << spics->cs_value_bit); + tmp |= value << spics->cs_value_bit; + writel_relaxed(tmp, spics->base + spics->perip_cfg); +} + +static int spics_direction_input(struct gpio_chip *chip, unsigned offset) +{ + return -ENXIO; +} + +static int spics_direction_output(struct gpio_chip *chip, unsigned offset, + int value) +{ + spics_set_value(chip, offset, value); + return 0; +} + +static int spics_request(struct gpio_chip *chip, unsigned offset) +{ + struct spear_spics *spics = container_of(chip, struct spear_spics, + chip); + u32 tmp; + + if (!spics->use_count++) { + tmp = readl_relaxed(spics->base + spics->perip_cfg); + tmp |= 0x1 << spics->sw_enable_bit; + tmp |= 0x1 << spics->cs_value_bit; + writel_relaxed(tmp, spics->base + spics->perip_cfg); + } + + return 0; +} + +static void spics_free(struct gpio_chip *chip, unsigned offset) +{ + struct spear_spics *spics = container_of(chip, struct spear_spics, + chip); + u32 tmp; + + if (!--spics->use_count) { + tmp = readl_relaxed(spics->base + spics->perip_cfg); + tmp &= ~(0x1 << spics->sw_enable_bit); + writel_relaxed(tmp, spics->base + spics->perip_cfg); + } +} + +static int spics_gpio_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct spear_spics *spics; + struct resource *res; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n"); + return -EBUSY; + } + + spics = devm_kzalloc(&pdev->dev, sizeof(*spics), GFP_KERNEL); + if (!spics) { + dev_err(&pdev->dev, "memory allocation fail\n"); + return -ENOMEM; + } + + spics->base = devm_request_and_ioremap(&pdev->dev, res); + if (!spics->base) { + dev_err(&pdev->dev, "request and ioremap fail\n"); + return -ENOMEM; + } + + if (of_property_read_u32(np, "st-spics,peripcfg-reg", + &spics->perip_cfg)) + goto err_dt_data; + if (of_property_read_u32(np, "st-spics,sw-enable-bit", + &spics->sw_enable_bit)) + goto err_dt_data; + if (of_property_read_u32(np, "st-spics,cs-value-bit", + &spics->cs_value_bit)) + goto err_dt_data; + if (of_property_read_u32(np, "st-spics,cs-enable-mask", + &spics->cs_enable_mask)) + goto err_dt_data; + if (of_property_read_u32(np, "st-spics,cs-enable-shift", + &spics->cs_enable_shift)) + goto err_dt_data; + + platform_set_drvdata(pdev, spics); + + spics->chip.ngpio = NUM_OF_GPIO; + spics->chip.base = -1; + spics->chip.request = spics_request; + spics->chip.free = spics_free; + spics->chip.direction_input = spics_direction_input; + spics->chip.direction_output = spics_direction_output; + spics->chip.get = spics_get_value; + spics->chip.set = spics_set_value; + spics->chip.label = dev_name(&pdev->dev); + spics->chip.dev = &pdev->dev; + spics->chip.owner = THIS_MODULE; + spics->last_off = -1; + + ret = gpiochip_add(&spics->chip); + if (ret) { + dev_err(&pdev->dev, "unable to add gpio chip\n"); + return ret; + } + + dev_info(&pdev->dev, "spear spics registered\n"); + return 0; + +err_dt_data: + dev_err(&pdev->dev, "DT probe failed\n"); + return -EINVAL; +} + +static const struct of_device_id spics_gpio_of_match[] = { + { .compatible = "st,spear-spics-gpio" }, + {} +}; +MODULE_DEVICE_TABLE(of, spics_gpio_of_match); + +static struct platform_driver spics_gpio_driver = { + .probe = spics_gpio_probe, + .driver = { + .owner = THIS_MODULE, + .name = "spear-spics-gpio", + .of_match_table = spics_gpio_of_match, + }, +}; + +static int __init spics_gpio_init(void) +{ + return platform_driver_register(&spics_gpio_driver); +} +subsys_initcall(spics_gpio_init); + +MODULE_AUTHOR("Shiraz Hashim "); +MODULE_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 34fa78b59c52d1db3513db4c1a999db26b2e9ac2 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sat, 17 Nov 2012 22:27:04 +0100 Subject: m68k: fix sigset_t accessor functions The sigaddset/sigdelset/sigismember functions that are implemented with bitfield insn cannot allow the sigset argument to be placed in a data register since the sigset is wider than 32 bits. Remove the "d" constraint from the asm statements. The effect of the bug is that sending RT signals does not work, the signal number is truncated modulo 32. Signed-off-by: Andreas Schwab Signed-off-by: Geert Uytterhoeven Cc: stable@vger.kernel.org --- arch/m68k/include/asm/signal.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/m68k/include/asm/signal.h b/arch/m68k/include/asm/signal.h index 67e489d8d1b..2df26b57c26 100644 --- a/arch/m68k/include/asm/signal.h +++ b/arch/m68k/include/asm/signal.h @@ -41,7 +41,7 @@ struct k_sigaction { static inline void sigaddset(sigset_t *set, int _sig) { asm ("bfset %0{%1,#1}" - : "+od" (*set) + : "+o" (*set) : "id" ((_sig - 1) ^ 31) : "cc"); } @@ -49,7 +49,7 @@ static inline void sigaddset(sigset_t *set, int _sig) static inline void sigdelset(sigset_t *set, int _sig) { asm ("bfclr %0{%1,#1}" - : "+od" (*set) + : "+o" (*set) : "id" ((_sig - 1) ^ 31) : "cc"); } @@ -65,7 +65,7 @@ static inline int __gen_sigismember(sigset_t *set, int _sig) int ret; asm ("bfextu %1{%2,#1},%0" : "=d" (ret) - : "od" (*set), "id" ((_sig-1) ^ 31) + : "o" (*set), "id" ((_sig-1) ^ 31) : "cc"); return ret; } -- cgit v1.2.3 From e1b69fdf33f63cfa600b992172d7376f9d9ef2e9 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 15 Oct 2012 17:57:36 +0200 Subject: iwlwifi: don't WARN when a non empty queue is disabled This can happen when we shut down suddenly an interface. Cc: stable@vger.kernel.org Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/tx.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 105e3af3c62..79a4ddc002d 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -480,20 +480,12 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - u16 rd_ptr, wr_ptr; - int n_bd = trans_pcie->txq[txq_id].q.n_bd; if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) { WARN_ONCE(1, "queue %d not used", txq_id); return; } - rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1); - wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)); - - WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]", - txq_id, rd_ptr, wr_ptr); - iwl_txq_set_inactive(trans, txq_id); IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); } -- cgit v1.2.3 From e99ddfde6ae0dd2662bb40435696002b590e4057 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 31 Oct 2012 16:35:30 +0100 Subject: ALSA: ua101, usx2y: fix broken MIDI output Commit 88a8516a2128 (ALSA: usbaudio: implement USB autosuspend) added autosuspend code to all files making up the snd-usb-audio driver. However, midi.c is part of snd-usb-lib and is also used by other drivers, not all of which support autosuspend. Thus, calls to usb_autopm_get_interface() could fail, and this unexpected error would result in the MIDI output being completely unusable. Make it work by ignoring the error that is expected with drivers that do not support autosuspend. Reported-by: Colin Fletcher Reported-by: Devin Venable Reported-by: Dr Nick Bailey Reported-by: Jannis Achstetter Reported-by: Rui Nuno Capela Cc: Oliver Neukum Cc: 2.6.39+ Signed-off-by: Clemens Ladisch --- sound/usb/midi.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/usb/midi.c b/sound/usb/midi.c index c83f6143c0e..eeefbce3873 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -148,6 +148,7 @@ struct snd_usb_midi_out_endpoint { struct snd_usb_midi_out_endpoint* ep; struct snd_rawmidi_substream *substream; int active; + bool autopm_reference; uint8_t cable; /* cable number << 4 */ uint8_t state; #define STATE_UNKNOWN 0 @@ -1076,7 +1077,8 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) return -ENXIO; } err = usb_autopm_get_interface(umidi->iface); - if (err < 0) + port->autopm_reference = err >= 0; + if (err < 0 && err != -EACCES) return -EIO; substream->runtime->private_data = port; port->state = STATE_UNKNOWN; @@ -1087,9 +1089,11 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) { struct snd_usb_midi* umidi = substream->rmidi->private_data; + struct usbmidi_out_port *port = substream->runtime->private_data; substream_open(substream, 0); - usb_autopm_put_interface(umidi->iface); + if (port->autopm_reference) + usb_autopm_put_interface(umidi->iface); return 0; } -- cgit v1.2.3 From 3587b1b097d70c2eb9fee95ea7995d13c05f66e5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 18 Nov 2012 19:19:00 +0000 Subject: fanotify: fix FAN_Q_OVERFLOW case of fanotify_read() If the FAN_Q_OVERFLOW bit set in event->mask, the fanotify event metadata will not contain a valid file descriptor, but copy_event_to_user() didn't check for that, and unconditionally does a fd_install() on the file descriptor. Which in turn will cause a BUG_ON() in __fd_install(). Introduced by commit 352e3b249284 ("fanotify: sanitize failure exits in copy_event_to_user()") Mea culpa - missed that path ;-/ Reported-by: Alex Shi Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- fs/notify/fanotify/fanotify_user.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 721d692fa8d..6fcaeb8c902 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -258,7 +258,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, if (ret) goto out_close_fd; - fd_install(fd, f); + if (fd != FAN_NOFD) + fd_install(fd, f); return fanotify_event_metadata.event_len; out_close_fd: -- cgit v1.2.3 From 32b01a366eb5d7d480570fe05d1dc18170387f5f Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 7 Nov 2012 00:33:34 +0800 Subject: pinctrl: at91: provide gpio names Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/pinctrl/pinctrl-at91.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index b9e2cbd2ea7..401fc96f577 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1364,9 +1364,10 @@ static int __devinit at91_gpio_probe(struct platform_device *pdev) struct gpio_chip *chip; struct pinctrl_gpio_range *range; int ret = 0; - int irq; + int irq, i; int alias_idx = of_alias_get_id(np, "gpio"); uint32_t ngpio; + char **names; BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips)); if (gpio_chips[alias_idx]) { @@ -1436,6 +1437,18 @@ static int __devinit at91_gpio_probe(struct platform_device *pdev) chip->ngpio = ngpio; } + names = devm_kzalloc(&pdev->dev, sizeof(char*) * chip->ngpio, GFP_KERNEL); + + if (!names) { + ret = -ENOMEM; + goto clk_err; + } + + for (i = 0; i < chip->ngpio; i++) + names[i] = kasprintf(GFP_KERNEL, "pio%c%d", alias_idx + 'A', i); + + chip->names = (const char*const*)names; + range = &at91_chip->range; range->name = chip->label; range->id = alias_idx; -- cgit v1.2.3 From 7ebd7a3ae0dd6e826767df504f7850d935fc3ee9 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 26 Sep 2012 14:57:45 +0800 Subject: pinctrl: at91 add deglitch, debounce, pull down and schmitt trigger mux option support add : set_deglitch: enable/disable deglitch set_debounce: enable/disable debounce set_pulldown: enable/disable pulldown disable_schmitt_trig: disable schmitt trigger Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- .../bindings/pinctrl/atmel,at91-pinctrl.txt | 9 +- drivers/pinctrl/pinctrl-at91.c | 111 +++++++++++++++++++++ 2 files changed, 118 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt index 20a987e55a2..3a268127b05 100644 --- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt @@ -84,8 +84,13 @@ Required properties for pin configuration node: The PERIPH 0 means gpio. Bits used for CONFIG: -PULL_UP(1 << 0): indicate this pin need a pull up. -MULTIDRIVE(1 << 1): indicate this pin need to be configured as multidrive. +PULL_UP (1 << 0): indicate this pin need a pull up. +MULTIDRIVE (1 << 1): indicate this pin need to be configured as multidrive. +DEGLITCH (1 << 2): indicate this pin need deglitch. +PULL_DOWN (1 << 3): indicate this pin need a pull down. +DIS_SCHMIT (1 << 4): indicate this pin need to disable schmit trigger. +DEBOUNCE (1 << 16): indicate this pin need debounce. +DEBOUNCE_VAL (0x3fff << 17): debounce val. NOTE: Some requirements for using atmel,at91rm9200-pinctrl binding: diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 401fc96f577..0d7e6c3c33a 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -59,6 +59,12 @@ static int gpio_banks; #define PULL_UP (1 << 0) #define MULTI_DRIVE (1 << 1) +#define DEGLITCH (1 << 2) +#define PULL_DOWN (1 << 3) +#define DIS_SCHMIT (1 << 4) +#define DEBOUNCE (1 << 16) +#define DEBOUNCE_VAL_SHIFT 17 +#define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT) /** * struct at91_pmx_func - describes AT91 pinmux functions @@ -122,6 +128,14 @@ struct at91_pin_group { * @mux_B_periph: mux as periph B * @mux_C_periph: mux as periph C * @mux_D_periph: mux as periph D + * @get_deglitch: get deglitch status + * @set_deglitch: enable/disable deglitch + * @get_debounce: get debounce status + * @set_debounce: enable/disable debounce + * @get_pulldown: get pulldown status + * @set_pulldown: enable/disable pulldown + * @get_schmitt_trig: get schmitt trigger status + * @disable_schmitt_trig: disable schmitt trigger * @irq_type: return irq type */ struct at91_pinctrl_mux_ops { @@ -130,6 +144,14 @@ struct at91_pinctrl_mux_ops { void (*mux_B_periph)(void __iomem *pio, unsigned mask); void (*mux_C_periph)(void __iomem *pio, unsigned mask); void (*mux_D_periph)(void __iomem *pio, unsigned mask); + bool (*get_deglitch)(void __iomem *pio, unsigned pin); + void (*set_deglitch)(void __iomem *pio, unsigned mask, bool in_on); + bool (*get_debounce)(void __iomem *pio, unsigned pin, u32 *div); + void (*set_debounce)(void __iomem *pio, unsigned mask, bool in_on, u32 div); + bool (*get_pulldown)(void __iomem *pio, unsigned pin); + void (*set_pulldown)(void __iomem *pio, unsigned mask, bool in_on); + bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin); + void (*disable_schmitt_trig)(void __iomem *pio, unsigned mask); /* irq */ int (*irq_type)(struct irq_data *d, unsigned type); }; @@ -386,10 +408,68 @@ static enum at91_mux at91_mux_get_periph(void __iomem *pio, unsigned mask) return select + 1; } +static bool at91_mux_get_deglitch(void __iomem *pio, unsigned pin) +{ + return (__raw_readl(pio + PIO_IFSR) >> pin) & 0x1; +} + +static void at91_mux_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) +{ + __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); +} + +static void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) +{ + if (is_on) + __raw_writel(mask, pio + PIO_IFSCDR); + at91_mux_set_deglitch(pio, mask, is_on); +} + +static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 *div) +{ + *div = __raw_readl(pio + PIO_SCDR); + + return (__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1; +} + +static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask, + bool is_on, u32 div) +{ + if (is_on) { + __raw_writel(mask, pio + PIO_IFSCER); + __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR); + __raw_writel(mask, pio + PIO_IFER); + } else { + __raw_writel(mask, pio + PIO_IFDR); + } +} + +static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin) +{ + return (__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1; +} + +static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on) +{ + __raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR)); +} + +static void at91_mux_pio3_disable_schmitt_trig(void __iomem *pio, unsigned mask) +{ + __raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT); +} + +static bool at91_mux_pio3_get_schmitt_trig(void __iomem *pio, unsigned pin) +{ + return (__raw_readl(pio + PIO_SCHMITT) >> pin) & 0x1; +} + static struct at91_pinctrl_mux_ops at91rm9200_ops = { .get_periph = at91_mux_get_periph, .mux_A_periph = at91_mux_set_A_periph, .mux_B_periph = at91_mux_set_B_periph, + .get_deglitch = at91_mux_get_deglitch, + .set_deglitch = at91_mux_set_deglitch, .irq_type = gpio_irq_type, }; @@ -399,6 +479,14 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = { .mux_B_periph = at91_mux_pio3_set_B_periph, .mux_C_periph = at91_mux_pio3_set_C_periph, .mux_D_periph = at91_mux_pio3_set_D_periph, + .get_deglitch = at91_mux_get_deglitch, + .set_deglitch = at91_mux_pio3_set_deglitch, + .get_debounce = at91_mux_pio3_get_debounce, + .set_debounce = at91_mux_pio3_set_debounce, + .get_pulldown = at91_mux_pio3_get_pulldown, + .set_pulldown = at91_mux_pio3_set_pulldown, + .get_schmitt_trig = at91_mux_pio3_get_schmitt_trig, + .disable_schmitt_trig = at91_mux_pio3_disable_schmitt_trig, .irq_type = alt_gpio_irq_type, }; @@ -624,6 +712,7 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev, struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); void __iomem *pio; unsigned pin; + int div; dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, *config); pio = pin_to_controller(info, pin_to_bank(pin_id)); @@ -635,6 +724,15 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev, if (at91_mux_get_pullup(pio, pin)) *config |= PULL_UP; + if (info->ops->get_deglitch && info->ops->get_deglitch(pio, pin)) + *config |= DEGLITCH; + if (info->ops->get_debounce && info->ops->get_debounce(pio, pin, &div)) + *config |= DEBOUNCE | (div << DEBOUNCE_VAL_SHIFT); + if (info->ops->get_pulldown && info->ops->get_pulldown(pio, pin)) + *config |= PULL_DOWN; + if (info->ops->get_schmitt_trig && info->ops->get_schmitt_trig(pio, pin)) + *config |= DIS_SCHMIT; + return 0; } @@ -649,8 +747,21 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev, pio = pin_to_controller(info, pin_to_bank(pin_id)); mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK); + if (config & PULL_UP && config & PULL_DOWN) + return -EINVAL; + at91_mux_set_pullup(pio, mask, config & PULL_UP); at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE); + if (info->ops->set_deglitch) + info->ops->set_deglitch(pio, mask, config & DEGLITCH); + if (info->ops->set_debounce) + info->ops->set_debounce(pio, mask, config & DEBOUNCE, + (config & DEBOUNCE_VAL) >> DEBOUNCE_VAL_SHIFT); + if (info->ops->set_pulldown) + info->ops->set_pulldown(pio, mask, config & PULL_DOWN); + if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT) + info->ops->disable_schmitt_trig(pio, mask); + return 0; } -- cgit v1.2.3 From 4113014f2d7bef992ed373c30b6b4ba4be6969ea Mon Sep 17 00:00:00 2001 From: Kelly Doran Date: Thu, 15 Nov 2012 14:37:28 +1000 Subject: drm/nvc0/disp: fix thinko in vblank regression fix.. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 05a909a17ce..15b182c84ce 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -49,13 +49,7 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) if (chan->vblank.crtc != crtc) continue; - if (nv_device(priv)->chipset == 0x50) { - nv_wr32(priv, 0x001704, chan->vblank.channel); - nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); - bar->flush(bar); - nv_wr32(priv, 0x001570, chan->vblank.offset); - nv_wr32(priv, 0x001574, chan->vblank.value); - } else { + if (nv_device(priv)->chipset >= 0xc0) { nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); bar->flush(bar); nv_wr32(priv, 0x06000c, @@ -63,6 +57,17 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) nv_wr32(priv, 0x060010, lower_32_bits(chan->vblank.offset)); nv_wr32(priv, 0x060014, chan->vblank.value); + } else { + nv_wr32(priv, 0x001704, chan->vblank.channel); + nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma); + bar->flush(bar); + if (nv_device(priv)->chipset == 0x50) { + nv_wr32(priv, 0x001570, chan->vblank.offset); + nv_wr32(priv, 0x001574, chan->vblank.value); + } else { + nv_wr32(priv, 0x060010, chan->vblank.offset); + nv_wr32(priv, 0x060014, chan->vblank.value); + } } list_del(&chan->vblank.head); -- cgit v1.2.3 From 1f150b3e7a722ebfc68eec5d83a9fe1ee8d75d71 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 11 Nov 2012 19:58:52 +0100 Subject: drm/nv40: allocate ctxprog with kmalloc Some archs defconfigs have CONFIG_FRAME_WARN set to 1024, which lead to this warning: drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c: warning: the frame size of 1184 bytes is larger than 1024 bytes Reported-by: Geert Uytterhoeven Signed-off-by: Marcin Slusarz Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c | 12 +++++++++--- drivers/gpu/drm/nouveau/core/engine/graph/nv40.c | 4 +++- drivers/gpu/drm/nouveau/core/engine/graph/nv40.h | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c index e45035efb8c..7bbb1e1b7a8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv40.c @@ -669,21 +669,27 @@ nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem) }); } -void +int nv40_grctx_init(struct nouveau_device *device, u32 *size) { - u32 ctxprog[256], i; + u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i; struct nouveau_grctx ctx = { .device = device, .mode = NOUVEAU_GRCTX_PROG, .data = ctxprog, - .ctxprog_max = ARRAY_SIZE(ctxprog) + .ctxprog_max = 256, }; + if (!ctxprog) + return -ENOMEM; + nv40_grctx_generate(&ctx); nv_wr32(device, 0x400324, 0); for (i = 0; i < ctx.ctxprog_len; i++) nv_wr32(device, 0x400328, ctxprog[i]); *size = ctx.ctxvals_pos * 4; + + kfree(ctxprog); + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c index 425001204a8..cc6574eeb80 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c @@ -346,7 +346,9 @@ nv40_graph_init(struct nouveau_object *object) return ret; /* generate and upload context program */ - nv40_grctx_init(nv_device(priv), &priv->size); + ret = nv40_grctx_init(nv_device(priv), &priv->size); + if (ret) + return ret; /* No context present currently */ nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h index d2ac975afc2..7da35a4e797 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h @@ -15,7 +15,7 @@ nv44_graph_class(void *priv) return !(0x0baf & (1 << (device->chipset & 0x0f))); } -void nv40_grctx_init(struct nouveau_device *, u32 *size); +int nv40_grctx_init(struct nouveau_device *, u32 *size); void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *); #endif -- cgit v1.2.3 From bf7e438bcaff4b732f86bb2eb48fc4fee04dc31b Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 11 Nov 2012 20:00:09 +0100 Subject: drm/nouveau: fix crash with noaccel=1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Ortwin Glück Signed-off-by: Marcin Slusarz Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_abi16.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index cc79c796afe..cbf1fc60a38 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -241,6 +241,10 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) if (unlikely(!abi16)) return -ENOMEM; + + if (!drm->channel) + return nouveau_abi16_put(abi16, -ENODEV); + client = nv_client(abi16->client); if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) -- cgit v1.2.3 From d9c390561d1c4e520773e62781bbf89bb6845353 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Fri, 16 Nov 2012 17:47:16 +0100 Subject: drm/nouveau: add missing pll_calc calls Fixes a null pointer dereference when reclocking on my fermi. Signed-off-by: Maarten Lankhorst Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/include/subdev/clock.h | 3 ++- drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c | 19 +++++++++++++++++++ drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h index 39e73b91d36..41b7a6a76f1 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h @@ -54,6 +54,7 @@ int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, int clk, struct nouveau_pll_vals *); int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1, struct nouveau_pll_vals *); - +int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, + int clk, struct nouveau_pll_vals *); #endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c index cc8d7d162d7..9068c98b96f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c @@ -66,6 +66,24 @@ nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq) return ret; } +int +nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info, + int clk, struct nouveau_pll_vals *pv) +{ + int ret, N, M, P; + + ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P); + + if (ret > 0) { + pv->refclk = info->refclk; + pv->N1 = N; + pv->M1 = M; + pv->log2P = P; + } + return ret; +} + + static int nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -80,6 +98,7 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; priv->base.pll_set = nva3_clock_pll_set; + priv->base.pll_calc = nva3_clock_pll_calc; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c index 5ccce0b17bf..f6962c9b6c3 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c @@ -79,6 +79,7 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return ret; priv->base.pll_set = nvc0_clock_pll_set; + priv->base.pll_calc = nva3_clock_pll_calc; return 0; } -- cgit v1.2.3 From 3bb076af2ae571a48465972d5747175cec3564cd Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sat, 17 Nov 2012 21:33:15 +0100 Subject: drm/nouveau/bios: fix DCB v1.5 parsing memcmp->nv_strncmp conversion, in addition to name change, should have inverted the return value. But nv_strncmp does not act like strncmp - it does not check for string terminator, returns true/false instead of -1/0/1 and has different parameters order. Let's rename it to nv_memcmp and let it act like memcmp. Signed-off-by: Marcin Slusarz Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/include/core/object.h | 14 +++++++++----- drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/include/core/object.h b/drivers/gpu/drm/nouveau/core/include/core/object.h index 818feabbf4a..486f1a9217f 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/object.h +++ b/drivers/gpu/drm/nouveau/core/include/core/object.h @@ -175,14 +175,18 @@ nv_mo32(void *obj, u32 addr, u32 mask, u32 data) return temp; } -static inline bool -nv_strncmp(void *obj, u32 addr, u32 len, const char *str) +static inline int +nv_memcmp(void *obj, u32 addr, const char *str, u32 len) { + unsigned char c1, c2; + while (len--) { - if (nv_ro08(obj, addr++) != *(str++)) - return false; + c1 = nv_ro08(obj, addr++); + c2 = *(str++); + if (c1 != c2) + return c1 - c2; } - return true; + return 0; } #endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c index 7d750382a83..c5119715774 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c @@ -64,7 +64,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) } } else if (*ver >= 0x15) { - if (!nv_strncmp(bios, dcb - 7, 7, "DEV_REC")) { + if (!nv_memcmp(bios, dcb - 7, "DEV_REC", 7)) { u16 i2c = nv_ro16(bios, dcb + 2); *hdr = 4; *cnt = (i2c - dcb) / 10; -- cgit v1.2.3 From d9b4fe837d671af5329f32570362c3c0b571c40b Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 23 Oct 2012 10:19:11 +0800 Subject: ARM: at91sam9: add macb pinctrl support Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9260.dtsi | 42 ++++++++++++++++++++++++++++++++++++++ arch/arm/boot/dts/at91sam9263.dtsi | 30 +++++++++++++++++++++++++++ arch/arm/boot/dts/at91sam9g45.dtsi | 30 +++++++++++++++++++++++++++ arch/arm/boot/dts/at91sam9x25.dtsi | 21 +++++++++++++++++++ arch/arm/boot/dts/at91sam9x5.dtsi | 30 +++++++++++++++++++++++++++ 5 files changed, 153 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 9a24ffbb723..36f55e34a43 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -216,6 +216,46 @@ }; }; + macb { + pinctrl_macb_rmii: macb_rmii-0 { + atmel,pins = + <0 12 0x1 0x0 /* PA12 periph A */ + 0 13 0x1 0x0 /* PA13 periph A */ + 0 14 0x1 0x0 /* PA14 periph A */ + 0 15 0x1 0x0 /* PA15 periph A */ + 0 16 0x1 0x0 /* PA16 periph A */ + 0 17 0x1 0x0 /* PA17 periph A */ + 0 18 0x1 0x0 /* PA18 periph A */ + 0 19 0x1 0x0 /* PA19 periph A */ + 0 20 0x1 0x0 /* PA20 periph A */ + 0 21 0x1 0x0>; /* PA21 periph A */ + }; + + pinctrl_macb_rmii_mii: macb_rmii_mii-0 { + atmel,pins = + <0 22 0x2 0x0 /* PA22 periph B */ + 0 23 0x2 0x0 /* PA23 periph B */ + 0 24 0x2 0x0 /* PA24 periph B */ + 0 25 0x2 0x0 /* PA25 periph B */ + 0 26 0x2 0x0 /* PA26 periph B */ + 0 27 0x2 0x0 /* PA27 periph B */ + 0 28 0x2 0x0 /* PA28 periph B */ + 0 29 0x2 0x0>; /* PA29 periph B */ + }; + + pinctrl_macb_rmii_mii_alt: macb_rmii_mii-1 { + atmel,pins = + <0 10 0x2 0x0 /* PA10 periph B */ + 0 11 0x2 0x0 /* PA11 periph B */ + 0 24 0x2 0x0 /* PA24 periph B */ + 0 25 0x2 0x0 /* PA25 periph B */ + 0 26 0x2 0x0 /* PA26 periph B */ + 0 27 0x2 0x0 /* PA27 periph B */ + 0 28 0x2 0x0 /* PA28 periph B */ + 0 29 0x2 0x0>; /* PA29 periph B */ + }; + }; + pioA: gpio@fffff400 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>; @@ -326,6 +366,8 @@ compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xfffc4000 0x100>; interrupts = <21 4 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb_rmii>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 251ccec430a..148b89a50ee 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -163,6 +163,34 @@ }; }; + macb { + pinctrl_macb_rmii: macb_rmii-0 { + atmel,pins = + <2 25 0x2 0x0 /* PC25 periph B */ + 4 21 0x1 0x0 /* PE21 periph A */ + 4 23 0x1 0x0 /* PE23 periph A */ + 4 24 0x1 0x0 /* PE24 periph A */ + 4 25 0x1 0x0 /* PE25 periph A */ + 4 26 0x1 0x0 /* PE26 periph A */ + 4 27 0x1 0x0 /* PE27 periph A */ + 4 28 0x1 0x0 /* PE28 periph A */ + 4 29 0x1 0x0 /* PE29 periph A */ + 4 30 0x1 0x0>; /* PE30 periph A */ + }; + + pinctrl_macb_rmii_mii: macb_rmii_mii-0 { + atmel,pins = + <2 20 0x2 0x0 /* PC20 periph B */ + 2 21 0x2 0x0 /* PC21 periph B */ + 2 22 0x2 0x0 /* PC22 periph B */ + 2 23 0x2 0x0 /* PC23 periph B */ + 2 24 0x2 0x0 /* PC24 periph B */ + 2 25 0x2 0x0 /* PC25 periph B */ + 2 27 0x2 0x0 /* PC27 periph B */ + 4 22 0x2 0x0>; /* PE22 periph B */ + }; + }; + pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff200 0x200>; @@ -260,6 +288,8 @@ compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xfffbc000 0x100>; interrupts = <21 4 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb_rmii>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index c340f6635d8..0ad84b6cd03 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -196,6 +196,34 @@ }; }; + macb { + pinctrl_macb_rmii: macb_rmii-0 { + atmel,pins = + <0 10 0x1 0x0 /* PA10 periph A */ + 0 11 0x1 0x0 /* PA11 periph A */ + 0 12 0x1 0x0 /* PA12 periph A */ + 0 13 0x1 0x0 /* PA13 periph A */ + 0 14 0x1 0x0 /* PA14 periph A */ + 0 15 0x1 0x0 /* PA15 periph A */ + 0 16 0x1 0x0 /* PA16 periph A */ + 0 17 0x1 0x0 /* PA17 periph A */ + 0 18 0x1 0x0 /* PA18 periph A */ + 0 19 0x1 0x0>; /* PA19 periph A */ + }; + + pinctrl_macb_rmii_mii: macb_rmii_mii-0 { + atmel,pins = + <0 6 0x2 0x0 /* PA6 periph B */ + 0 7 0x2 0x0 /* PA7 periph B */ + 0 8 0x2 0x0 /* PA8 periph B */ + 0 9 0x2 0x0 /* PA9 periph B */ + 0 27 0x2 0x0 /* PA27 periph B */ + 0 28 0x2 0x0 /* PA28 periph B */ + 0 29 0x2 0x0 /* PA29 periph B */ + 0 30 0x2 0x0>; /* PA30 periph B */ + }; + }; + pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff200 0x200>; @@ -304,6 +332,8 @@ compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xfffbc000 0x100>; interrupts = <25 4 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb_rmii>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9x25.dtsi b/arch/arm/boot/dts/at91sam9x25.dtsi index 956c65f7c39..54eb33ba6d2 100644 --- a/arch/arm/boot/dts/at91sam9x25.dtsi +++ b/arch/arm/boot/dts/at91sam9x25.dtsi @@ -22,6 +22,27 @@ 0x80000000 0xfffd0000 0xb83fffff /* pioC */ 0x003fffff 0x003f8000 0x00000000 /* pioD */ >; + + macb1 { + pinctrl_macb1_rmii: macb1_rmii-0 { + atmel,pins = + <2 16 0x2 0x0 /* PC16 periph B */ + 2 18 0x2 0x0 /* PC18 periph B */ + 2 19 0x2 0x0 /* PC19 periph B */ + 2 20 0x2 0x0 /* PC20 periph B */ + 2 21 0x2 0x0 /* PC21 periph B */ + 2 27 0x2 0x0 /* PC27 periph B */ + 2 28 0x2 0x0 /* PC28 periph B */ + 2 29 0x2 0x0 /* PC29 periph B */ + 2 30 0x2 0x0 /* PC30 periph B */ + 2 31 0x2 0x0>; /* PC31 periph B */ + }; + }; + }; + + macb1: ethernet@f8030000 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb1_rmii>; }; }; }; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 6a40b777ea4..9fd71592683 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -206,6 +206,34 @@ }; }; + macb0 { + pinctrl_macb0_rmii: macb0_rmii-0 { + atmel,pins = + <1 0 0x1 0x0 /* PB0 periph A */ + 1 1 0x1 0x0 /* PB1 periph A */ + 1 2 0x1 0x0 /* PB2 periph A */ + 1 3 0x1 0x0 /* PB3 periph A */ + 1 4 0x1 0x0 /* PB4 periph A */ + 1 5 0x1 0x0 /* PB5 periph A */ + 1 6 0x1 0x0 /* PB6 periph A */ + 1 7 0x1 0x0 /* PB7 periph A */ + 1 9 0x1 0x0 /* PB9 periph A */ + 1 10 0x1 0x0>; /* PB10 periph A */ + }; + + pinctrl_macb0_rmii_mii: macb0_rmii_mii-0 { + atmel,pins = + <1 8 0x1 0x0 /* PA8 periph A */ + 1 11 0x1 0x0 /* PA11 periph A */ + 1 12 0x1 0x0 /* PA12 periph A */ + 1 13 0x1 0x0 /* PA13 periph A */ + 1 14 0x1 0x0 /* PA14 periph A */ + 1 15 0x1 0x0 /* PA15 periph A */ + 1 16 0x1 0x0 /* PA16 periph A */ + 1 17 0x1 0x0>; /* PA17 periph A */ + }; + }; + pioA: gpio@fffff400 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>; @@ -295,6 +323,8 @@ compatible = "cdns,at32ap7000-macb", "cdns,macb"; reg = <0xf802c000 0x100>; interrupts = <24 4 3>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_macb0_rmii>; status = "disabled"; }; -- cgit v1.2.3 From 9e3129e937e2f178d2a003ea45765e5e63e34665 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 19 Nov 2012 06:40:01 +0800 Subject: ARM: at91: fix usart/uart namimg in pinctrl USART are the full pin uart DBGU the debug Unit UART the two pin uart Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9260.dtsi | 58 ++++++++++++++--------------- arch/arm/boot/dts/at91sam9263.dtsi | 24 ++++++------ arch/arm/boot/dts/at91sam9263ek.dts | 2 +- arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 10 ++--- arch/arm/boot/dts/at91sam9g45.dtsi | 30 +++++++-------- arch/arm/boot/dts/at91sam9m10g45ek.dts | 2 +- arch/arm/boot/dts/at91sam9n12.dtsi | 38 +++++++++---------- arch/arm/boot/dts/at91sam9x5.dtsi | 36 +++++++++--------- 8 files changed, 100 insertions(+), 100 deletions(-) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 36f55e34a43..40bf3298c7f 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -21,8 +21,8 @@ serial2 = &usart1; serial3 = &usart2; serial4 = &usart3; - serial5 = &usart4; - serial6 = &usart5; + serial5 = &uart0; + serial6 = &uart1; gpio0 = &pioA; gpio1 = &pioB; gpio2 = &pioC; @@ -120,88 +120,88 @@ }; }; - uart0 { - pinctrl_uart0: uart0-0 { + usart0 { + pinctrl_usart0: usart0-0 { atmel,pins = <1 4 0x1 0x0 /* PB4 periph A */ 1 5 0x1 0x0>; /* PB5 periph A */ }; - pinctrl_uart0_rts_cts: uart0_rts_cts-0 { + pinctrl_usart0_rts_cts: usart0_rts_cts-0 { atmel,pins = <1 26 0x1 0x0 /* PB26 periph A */ 1 27 0x1 0x0>; /* PB27 periph A */ }; - pinctrl_uart0_dtr_dsr: uart0_dtr_dsr-0 { + pinctrl_usart0_dtr_dsr: usart0_dtr_dsr-0 { atmel,pins = <1 24 0x1 0x0 /* PB24 periph A */ 1 22 0x1 0x0>; /* PB22 periph A */ }; - pinctrl_uart0_dcd: uart0_dcd-0 { + pinctrl_usart0_dcd: usart0_dcd-0 { atmel,pins = <1 23 0x1 0x0>; /* PB23 periph A */ }; - pinctrl_uart0_ri: uart0_ri-0 { + pinctrl_usart0_ri: usart0_ri-0 { atmel,pins = <1 25 0x1 0x0>; /* PB25 periph A */ }; }; - uart1 { - pinctrl_uart1: uart1-0 { + usart1 { + pinctrl_usart1: usart1-0 { atmel,pins = <2 6 0x1 0x1 /* PB6 periph A with pullup */ 2 7 0x1 0x0>; /* PB7 periph A */ }; - pinctrl_uart1_rts_cts: uart1_rts_cts-0 { + pinctrl_usart1_rts_cts: usart1_rts_cts-0 { atmel,pins = <1 28 0x1 0x0 /* PB28 periph A */ 1 29 0x1 0x0>; /* PB29 periph A */ }; }; - uart2 { - pinctrl_uart2: uart2-0 { + usart2 { + pinctrl_usart2: usart2-0 { atmel,pins = <1 8 0x1 0x1 /* PB8 periph A with pullup */ 1 9 0x1 0x0>; /* PB9 periph A */ }; - pinctrl_uart2_rts_cts: uart2_rts_cts-0 { + pinctrl_usart2_rts_cts: usart2_rts_cts-0 { atmel,pins = <0 4 0x1 0x0 /* PA4 periph A */ 0 5 0x1 0x0>; /* PA5 periph A */ }; }; - uart3 { - pinctrl_uart3: uart3-0 { + usart3 { + pinctrl_usart3: usart3-0 { atmel,pins = <2 10 0x1 0x1 /* PB10 periph A with pullup */ 2 11 0x1 0x0>; /* PB11 periph A */ }; - pinctrl_uart3_rts_cts: uart3_rts_cts-0 { + pinctrl_usart3_rts_cts: usart3_rts_cts-0 { atmel,pins = <3 8 0x2 0x0 /* PB8 periph B */ 3 10 0x2 0x0>; /* PB10 periph B */ }; }; - uart4 { - pinctrl_uart4: uart4-0 { + uart0 { + pinctrl_uart0: uart0-0 { atmel,pins = <0 31 0x2 0x1 /* PA31 periph B with pullup */ 0 30 0x2 0x0>; /* PA30 periph B */ }; }; - uart5 { - pinctrl_uart5: uart5-0 { + uart1 { + pinctrl_uart1: uart1-0 { atmel,pins = <2 12 0x1 0x1 /* PB12 periph A with pullup */ 2 13 0x1 0x0>; /* PB13 periph A */ @@ -303,7 +303,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart0>; + pinctrl-0 = <&pinctrl_usart0>; status = "disabled"; }; @@ -314,7 +314,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart1>; + pinctrl-0 = <&pinctrl_usart1>; status = "disabled"; }; @@ -325,7 +325,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart2>; + pinctrl-0 = <&pinctrl_usart2>; status = "disabled"; }; @@ -336,29 +336,29 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart3>; + pinctrl-0 = <&pinctrl_usart3>; status = "disabled"; }; - usart4: serial@fffd4000 { + uart0: serial@fffd4000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffd4000 0x200>; interrupts = <24 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart4>; + pinctrl-0 = <&pinctrl_uart0>; status = "disabled"; }; - usart5: serial@fffd8000 { + uart1: serial@fffd8000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffd8000 0x200>; interrupts = <25 4 5>; atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart5>; + pinctrl-0 = <&pinctrl_uart1>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 148b89a50ee..cf4b59fc8e0 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -113,42 +113,42 @@ }; }; - uart0 { - pinctrl_uart0: uart0-0 { + usart0 { + pinctrl_usart0: usart0-0 { atmel,pins = <0 26 0x1 0x1 /* PA26 periph A with pullup */ 0 27 0x1 0x0>; /* PA27 periph A */ }; - pinctrl_uart0_rts_cts: uart0_rts_cts-0 { + pinctrl_usart0_rts_cts: usart0_rts_cts-0 { atmel,pins = <0 28 0x1 0x0 /* PA28 periph A */ 0 29 0x1 0x0>; /* PA29 periph A */ }; }; - uart1 { - pinctrl_uart1: uart1-0 { + usart1 { + pinctrl_usart1: usart1-0 { atmel,pins = <3 0 0x1 0x1 /* PD0 periph A with pullup */ 3 1 0x1 0x0>; /* PD1 periph A */ }; - pinctrl_uart1_rts_cts: uart1_rts_cts-0 { + pinctrl_usart1_rts_cts: usart1_rts_cts-0 { atmel,pins = <3 7 0x2 0x0 /* PD7 periph B */ 3 8 0x2 0x0>; /* PD8 periph B */ }; }; - uart2 { - pinctrl_uart2: uart2-0 { + usart2 { + pinctrl_usart2: usart2-0 { atmel,pins = <3 2 0x1 0x1 /* PD2 periph A with pullup */ 3 3 0x1 0x0>; /* PD3 periph A */ }; - pinctrl_uart2_rts_cts: uart2_rts_cts-0 { + pinctrl_usart2_rts_cts: usart2_rts_cts-0 { atmel,pins = <3 5 0x2 0x0 /* PD5 periph B */ 4 6 0x2 0x0>; /* PD6 periph B */ @@ -258,7 +258,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart0>; + pinctrl-0 = <&pinctrl_usart0>; status = "disabled"; }; @@ -269,7 +269,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart1>; + pinctrl-0 = <&pinctrl_usart1>; status = "disabled"; }; @@ -280,7 +280,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart2>; + pinctrl-0 = <&pinctrl_usart2>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts index 7cfe9d521f1..34343739727 100644 --- a/arch/arm/boot/dts/at91sam9263ek.dts +++ b/arch/arm/boot/dts/at91sam9263ek.dts @@ -38,7 +38,7 @@ }; usart0: serial@fff8c000 { - pinctrl-0 = <&pinctrl_uart0 &pinctrl_uart0_rts_cts>; + pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts_cts>; status = "okay"; }; diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index e33ab0a88d0..04f048f082e 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -36,11 +36,11 @@ usart0: serial@fffb0000 { pinctrl-0 = - <&pinctrl_uart0 - &pinctrl_uart0_rts_cts - &pinctrl_uart0_dtr_dsr - &pinctrl_uart0_dcd - &pinctrl_uart0_ri>; + <&pinctrl_usart0 + &pinctrl_usart0_rts_cts + &pinctrl_usart0_dtr_dsr + &pinctrl_usart0_dcd + &pinctrl_usart0_ri>; status = "okay"; }; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 0ad84b6cd03..56ce8961526 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -132,14 +132,14 @@ }; }; - uart0 { - pinctrl_uart0: uart0-0 { + usart0 { + pinctrl_usart0: usart0-0 { atmel,pins = <1 19 0x1 0x1 /* PB19 periph A with pullup */ 1 18 0x1 0x0>; /* PB18 periph A */ }; - pinctrl_uart0_rts_cts: uart0_rts_cts-0 { + pinctrl_usart0_rts_cts: usart0_rts_cts-0 { atmel,pins = <1 17 0x2 0x0 /* PB17 periph B */ 1 15 0x2 0x0>; /* PB15 periph B */ @@ -147,41 +147,41 @@ }; uart1 { - pinctrl_uart1: uart1-0 { + pinctrl_usart1: usart1-0 { atmel,pins = <1 4 0x1 0x1 /* PB4 periph A with pullup */ 1 5 0x1 0x0>; /* PB5 periph A */ }; - pinctrl_uart1_rts_cts: uart1_rts_cts-0 { + pinctrl_usart1_rts_cts: usart1_rts_cts-0 { atmel,pins = <3 16 0x1 0x0 /* PD16 periph A */ 3 17 0x1 0x0>; /* PD17 periph A */ }; }; - uart2 { - pinctrl_uart2: uart2-0 { + usart2 { + pinctrl_usart2: usart2-0 { atmel,pins = <1 6 0x1 0x1 /* PB6 periph A with pullup */ 1 7 0x1 0x0>; /* PB7 periph A */ }; - pinctrl_uart2_rts_cts: uart2_rts_cts-0 { + pinctrl_usart2_rts_cts: usart2_rts_cts-0 { atmel,pins = <2 9 0x2 0x0 /* PC9 periph B */ 2 11 0x2 0x0>; /* PC11 periph B */ }; }; - uart3 { - pinctrl_uart3: uart3-0 { + usart3 { + pinctrl_usart3: usart3-0 { atmel,pins = <1 8 0x1 0x1 /* PB9 periph A with pullup */ 1 9 0x1 0x0>; /* PB8 periph A */ }; - pinctrl_uart3_rts_cts: uart3_rts_cts-0 { + pinctrl_usart3_rts_cts: usart3_rts_cts-0 { atmel,pins = <0 23 0x2 0x0 /* PA23 periph B */ 0 24 0x2 0x0>; /* PA24 periph B */ @@ -291,7 +291,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart0>; + pinctrl-0 = <&pinctrl_usart0>; status = "disabled"; }; @@ -302,7 +302,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart1>; + pinctrl-0 = <&pinctrl_usart1>; status = "disabled"; }; @@ -313,7 +313,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart2>; + pinctrl-0 = <&pinctrl_usart2>; status = "disabled"; }; @@ -324,7 +324,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart3>; + pinctrl-0 = <&pinctrl_usart3>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index 6aa28b94190..0d9674b5e6a 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -39,7 +39,7 @@ }; usart1: serial@fff90000 { - pinctrl-0 = <&pinctrl_uart0 &pinctrl_uart1_rts_cts>; + pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>; status = "okay"; }; diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 7b644c5b0be..10547bc52a2 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -125,66 +125,66 @@ }; }; - uart0 { - pinctrl_uart0: uart0-0 { + usart0 { + pinctrl_usart0: usart0-0 { atmel,pins = <0 1 0x1 0x1 /* PA1 periph A with pullup */ 0 0 0x1 0x0>; /* PA0 periph A */ }; - pinctrl_uart0_rts_cts: uart0_rts_cts-0 { + pinctrl_usart0_rts_cts: usart0_rts_cts-0 { atmel,pins = <0 2 0x1 0x0 /* PA2 periph A */ 0 3 0x1 0x0>; /* PA3 periph A */ }; }; - uart1 { - pinctrl_uart1: uart1-0 { + usart1 { + pinctrl_usart1: usart1-0 { atmel,pins = <0 6 0x1 0x1 /* PA6 periph A with pullup */ 0 5 0x1 0x0>; /* PA5 periph A */ }; }; - uart2 { - pinctrl_uart2: uart2-0 { + usart2 { + pinctrl_usart2: usart2-0 { atmel,pins = <0 8 0x1 0x1 /* PA8 periph A with pullup */ 0 7 0x1 0x0>; /* PA7 periph A */ }; - pinctrl_uart2_rts_cts: uart2_rts_cts-0 { + pinctrl_usart2_rts_cts: usart2_rts_cts-0 { atmel,pins = <1 0 0x2 0x0 /* PB0 periph B */ 1 1 0x2 0x0>; /* PB1 periph B */ }; }; - uart3 { - pinctrl_uart3: uart3-0 { + usart3 { + pinctrl_usart3: usart3-0 { atmel,pins = <2 23 0x2 0x1 /* PC23 periph B with pullup */ 2 22 0x2 0x0>; /* PC22 periph B */ }; - pinctrl_uart3_rts_cts: uart3_rts_cts-0 { + pinctrl_usart3_rts_cts: usart3_rts_cts-0 { atmel,pins = <2 24 0x2 0x0 /* PC24 periph B */ 2 25 0x2 0x0>; /* PC25 periph B */ }; }; - usart0 { - pinctrl_usart0: usart0-0 { + uart0 { + pinctrl_uart0: uart0-0 { atmel,pins = <2 9 0x3 0x1 /* PC9 periph C with pullup */ 2 8 0x3 0x0>; /* PC8 periph C */ }; }; - usart1 { - pinctrl_usart1: usart1-0 { + uart1 { + pinctrl_uart1: uart1-0 { atmel,pins = <2 16 0x3 0x1 /* PC17 periph C with pullup */ 2 17 0x3 0x0>; /* PC16 periph C */ @@ -256,7 +256,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart0>; + pinctrl-0 = <&pinctrl_usart0>; status = "disabled"; }; @@ -267,7 +267,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart1>; + pinctrl-0 = <&pinctrl_usart1>; status = "disabled"; }; @@ -278,7 +278,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart2>; + pinctrl-0 = <&pinctrl_usart2>; status = "disabled"; }; @@ -289,7 +289,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart3>; + pinctrl-0 = <&pinctrl_usart3>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 9fd71592683..9dac00693fa 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -126,36 +126,36 @@ }; }; - uart0 { - pinctrl_uart0: uart0-0 { + usart0 { + pinctrl_usart0: usart0-0 { atmel,pins = <0 0 0x1 0x1 /* PA0 periph A with pullup */ 0 1 0x1 0x0>; /* PA1 periph A */ }; - pinctrl_uart0_rts_cts: uart0_rts_cts-0 { + pinctrl_usart0_rts_cts: usart0_rts_cts-0 { atmel,pins = <0 2 0x1 0x0 /* PA2 periph A */ 0 3 0x1 0x0>; /* PA3 periph A */ }; }; - uart1 { - pinctrl_uart1: uart1-0 { + usart1 { + pinctrl_usart1: usart1-0 { atmel,pins = <0 5 0x1 0x1 /* PA5 periph A with pullup */ 0 6 0x1 0x0>; /* PA6 periph A */ }; - pinctrl_uart1_rts_cts: uart1_rts_cts-0 { + pinctrl_usart1_rts_cts: usart1_rts_cts-0 { atmel,pins = <3 27 0x3 0x0 /* PC27 periph C */ 3 28 0x3 0x0>; /* PC28 periph C */ }; }; - uart2 { - pinctrl_uart2: uart2-0 { + usart2 { + pinctrl_usart2: usart2-0 { atmel,pins = <0 7 0x1 0x1 /* PA7 periph A with pullup */ 0 8 0x1 0x0>; /* PA8 periph A */ @@ -168,30 +168,30 @@ }; }; - uart3 { - pinctrl_uart3: uart3-0 { + usart3 { + pinctrl_uart3: usart3-0 { atmel,pins = <3 23 0x2 0x1 /* PC22 periph B with pullup */ 3 23 0x2 0x0>; /* PC23 periph B */ }; - pinctrl_uart3_rts_cts: uart3_rts_cts-0 { + pinctrl_usart3_rts_cts: usart3_rts_cts-0 { atmel,pins = <3 24 0x2 0x0 /* PC24 periph B */ 3 25 0x2 0x0>; /* PC25 periph B */ }; }; - usart0 { - pinctrl_usart0: usart0-0 { + uart0 { + pinctrl_uart0: uart0-0 { atmel,pins = <3 8 0x3 0x0 /* PC8 periph C */ 3 9 0x3 0x1>; /* PC9 periph C with pullup */ }; }; - usart1 { - pinctrl_usart1: usart1-0 { + uart1 { + pinctrl_uart1: uart1-0 { atmel,pins = <3 16 0x3 0x0 /* PC16 periph C */ 3 17 0x3 0x1>; /* PC17 periph C with pullup */ @@ -293,7 +293,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart0>; + pinctrl-0 = <&pinctrl_usart0>; status = "disabled"; }; @@ -304,7 +304,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart1>; + pinctrl-0 = <&pinctrl_usart1>; status = "disabled"; }; @@ -315,7 +315,7 @@ atmel,use-dma-rx; atmel,use-dma-tx; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart2>; + pinctrl-0 = <&pinctrl_usart2>; status = "disabled"; }; -- cgit v1.2.3 From 8495c0da20bc496ac9d5da2b292adb28f61d2713 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Sun, 18 Nov 2012 23:41:50 +0100 Subject: sis900: fix sis900_set_mode call parameters. Leftover of 57d6d456cfb89264f87d24f52640ede23fdf12bd ("sis900: stop using net_device.{base_addr, irq} and convert to __iomem."). It is needed for suspend / resume to work. Signed-off-by: Francois Romieu Tested-by: Jan Janssen Cc: Daniele Venzano Signed-off-by: David S. Miller --- drivers/net/ethernet/sis/sis900.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index fb9f6b38511..edf5edb1314 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c @@ -2479,7 +2479,7 @@ static int sis900_resume(struct pci_dev *pci_dev) netif_start_queue(net_dev); /* Workaround for EDB */ - sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); + sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED); /* Enable all known interrupts by setting the interrupt mask. */ sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE); -- cgit v1.2.3 From c58c0c5acceb8acd3d447483a744e8a4a7c27f26 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 19 Nov 2012 07:30:01 +0800 Subject: ARM: at91: dt: at91sam9260: split rts and cts pinctrl not as we just use the rts and not the rts & cts for rs485 Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9260.dtsi | 40 ++++++++++++++++++++--------- arch/arm/boot/dts/at91sam9263.dtsi | 30 +++++++++++++++------- arch/arm/boot/dts/at91sam9263ek.dts | 5 +++- arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 3 ++- arch/arm/boot/dts/at91sam9g45.dtsi | 40 ++++++++++++++++++++--------- arch/arm/boot/dts/at91sam9m10g45ek.dts | 5 +++- arch/arm/boot/dts/at91sam9n12.dtsi | 30 +++++++++++++++------- arch/arm/boot/dts/at91sam9x5.dtsi | 40 ++++++++++++++++++++--------- 8 files changed, 136 insertions(+), 57 deletions(-) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 40bf3298c7f..a5d94606e15 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -127,10 +127,14 @@ 1 5 0x1 0x0>; /* PB5 periph A */ }; - pinctrl_usart0_rts_cts: usart0_rts_cts-0 { + pinctrl_usart0_rts: usart0_rts-0 { atmel,pins = - <1 26 0x1 0x0 /* PB26 periph A */ - 1 27 0x1 0x0>; /* PB27 periph A */ + <1 26 0x1 0x0>; /* PB26 periph A */ + }; + + pinctrl_usart0_cts: usart0_cts-0 { + atmel,pins = + <1 27 0x1 0x0>; /* PB27 periph A */ }; pinctrl_usart0_dtr_dsr: usart0_dtr_dsr-0 { @@ -157,10 +161,14 @@ 2 7 0x1 0x0>; /* PB7 periph A */ }; - pinctrl_usart1_rts_cts: usart1_rts_cts-0 { + pinctrl_usart1_rts: usart1_rts-0 { + atmel,pins = + <1 28 0x1 0x0>; /* PB28 periph A */ + }; + + pinctrl_usart1_cts: usart1_cts-0 { atmel,pins = - <1 28 0x1 0x0 /* PB28 periph A */ - 1 29 0x1 0x0>; /* PB29 periph A */ + <1 29 0x1 0x0>; /* PB29 periph A */ }; }; @@ -171,10 +179,14 @@ 1 9 0x1 0x0>; /* PB9 periph A */ }; - pinctrl_usart2_rts_cts: usart2_rts_cts-0 { + pinctrl_usart2_rts: usart2_rts-0 { atmel,pins = - <0 4 0x1 0x0 /* PA4 periph A */ - 0 5 0x1 0x0>; /* PA5 periph A */ + <0 4 0x1 0x0>; /* PA4 periph A */ + }; + + pinctrl_usart2_cts: usart2_cts-0 { + atmel,pins = + <0 5 0x1 0x0>; /* PA5 periph A */ }; }; @@ -185,10 +197,14 @@ 2 11 0x1 0x0>; /* PB11 periph A */ }; - pinctrl_usart3_rts_cts: usart3_rts_cts-0 { + pinctrl_usart3_rts: usart3_rts-0 { + atmel,pins = + <3 8 0x2 0x0>; /* PB8 periph B */ + }; + + pinctrl_usart3_cts: usart3_cts-0 { atmel,pins = - <3 8 0x2 0x0 /* PB8 periph B */ - 3 10 0x2 0x0>; /* PB10 periph B */ + <3 10 0x2 0x0>; /* PB10 periph B */ }; }; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index cf4b59fc8e0..a14aa3d1f01 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -120,10 +120,14 @@ 0 27 0x1 0x0>; /* PA27 periph A */ }; - pinctrl_usart0_rts_cts: usart0_rts_cts-0 { + pinctrl_usart0_rts: usart0_rts-0 { atmel,pins = - <0 28 0x1 0x0 /* PA28 periph A */ - 0 29 0x1 0x0>; /* PA29 periph A */ + <0 28 0x1 0x0>; /* PA28 periph A */ + }; + + pinctrl_usart0_cts: usart0_cts-0 { + atmel,pins = + <0 29 0x1 0x0>; /* PA29 periph A */ }; }; @@ -134,10 +138,14 @@ 3 1 0x1 0x0>; /* PD1 periph A */ }; - pinctrl_usart1_rts_cts: usart1_rts_cts-0 { + pinctrl_usart1_rts: usart1_rts-0 { atmel,pins = - <3 7 0x2 0x0 /* PD7 periph B */ - 3 8 0x2 0x0>; /* PD8 periph B */ + <3 7 0x2 0x0>; /* PD7 periph B */ + }; + + pinctrl_usart1_cts: usart1_cts-0 { + atmel,pins = + <3 8 0x2 0x0>; /* PD8 periph B */ }; }; @@ -148,10 +156,14 @@ 3 3 0x1 0x0>; /* PD3 periph A */ }; - pinctrl_usart2_rts_cts: usart2_rts_cts-0 { + pinctrl_usart2_rts: usart2_rts-0 { + atmel,pins = + <3 5 0x2 0x0>; /* PD5 periph B */ + }; + + pinctrl_usart2_cts: usart2_cts-0 { atmel,pins = - <3 5 0x2 0x0 /* PD5 periph B */ - 4 6 0x2 0x0>; /* PD6 periph B */ + <4 6 0x2 0x0>; /* PD6 periph B */ }; }; diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts index 34343739727..e6a57a37156 100644 --- a/arch/arm/boot/dts/at91sam9263ek.dts +++ b/arch/arm/boot/dts/at91sam9263ek.dts @@ -38,7 +38,10 @@ }; usart0: serial@fff8c000 { - pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts_cts>; + pinctrl-0 = < + &pinctrl_usart0 + &pinctrl_usart0_rts + &pinctrl_usart0_cts>; status = "okay"; }; diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index 04f048f082e..59244d9d327 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -37,7 +37,8 @@ usart0: serial@fffb0000 { pinctrl-0 = <&pinctrl_usart0 - &pinctrl_usart0_rts_cts + &pinctrl_usart0_rts + &pinctrl_usart0_cts &pinctrl_usart0_dtr_dsr &pinctrl_usart0_dcd &pinctrl_usart0_ri>; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 56ce8961526..dc9a4ee28bc 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -139,10 +139,14 @@ 1 18 0x1 0x0>; /* PB18 periph A */ }; - pinctrl_usart0_rts_cts: usart0_rts_cts-0 { + pinctrl_usart0_rts: usart0_rts-0 { atmel,pins = - <1 17 0x2 0x0 /* PB17 periph B */ - 1 15 0x2 0x0>; /* PB15 periph B */ + <1 17 0x2 0x0>; /* PB17 periph B */ + }; + + pinctrl_usart0_cts: usart0_cts-0 { + atmel,pins = + <1 15 0x2 0x0>; /* PB15 periph B */ }; }; @@ -153,10 +157,14 @@ 1 5 0x1 0x0>; /* PB5 periph A */ }; - pinctrl_usart1_rts_cts: usart1_rts_cts-0 { + pinctrl_usart1_rts: usart1_rts-0 { + atmel,pins = + <3 16 0x1 0x0>; /* PD16 periph A */ + }; + + pinctrl_usart1_cts: usart1_cts-0 { atmel,pins = - <3 16 0x1 0x0 /* PD16 periph A */ - 3 17 0x1 0x0>; /* PD17 periph A */ + <3 17 0x1 0x0>; /* PD17 periph A */ }; }; @@ -167,10 +175,14 @@ 1 7 0x1 0x0>; /* PB7 periph A */ }; - pinctrl_usart2_rts_cts: usart2_rts_cts-0 { + pinctrl_usart2_rts: usart2_rts-0 { atmel,pins = - <2 9 0x2 0x0 /* PC9 periph B */ - 2 11 0x2 0x0>; /* PC11 periph B */ + <2 9 0x2 0x0>; /* PC9 periph B */ + }; + + pinctrl_usart2_cts: usart2_cts-0 { + atmel,pins = + <2 11 0x2 0x0>; /* PC11 periph B */ }; }; @@ -181,10 +193,14 @@ 1 9 0x1 0x0>; /* PB8 periph A */ }; - pinctrl_usart3_rts_cts: usart3_rts_cts-0 { + pinctrl_usart3_rts: usart3_rts-0 { + atmel,pins = + <0 23 0x2 0x0>; /* PA23 periph B */ + }; + + pinctrl_usart3_cts: usart3_cts-0 { atmel,pins = - <0 23 0x2 0x0 /* PA23 periph B */ - 0 24 0x2 0x0>; /* PA24 periph B */ + <0 24 0x2 0x0>; /* PA24 periph B */ }; }; diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index 0d9674b5e6a..afd586720b1 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -39,7 +39,10 @@ }; usart1: serial@fff90000 { - pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>; + pinctrl-0 = + <&pinctrl_usart1 + &pinctrl_usart1_rts + &pinctrl_usart1_cts>; status = "okay"; }; diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 10547bc52a2..1667937bb2e 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -132,10 +132,14 @@ 0 0 0x1 0x0>; /* PA0 periph A */ }; - pinctrl_usart0_rts_cts: usart0_rts_cts-0 { + pinctrl_usart0_rts: usart0_rts-0 { atmel,pins = - <0 2 0x1 0x0 /* PA2 periph A */ - 0 3 0x1 0x0>; /* PA3 periph A */ + <0 2 0x1 0x0>; /* PA2 periph A */ + }; + + pinctrl_usart0_cts: usart0_cts-0 { + atmel,pins = + <0 3 0x1 0x0>; /* PA3 periph A */ }; }; @@ -154,10 +158,14 @@ 0 7 0x1 0x0>; /* PA7 periph A */ }; - pinctrl_usart2_rts_cts: usart2_rts_cts-0 { + pinctrl_usart2_rts: usart2_rts-0 { atmel,pins = - <1 0 0x2 0x0 /* PB0 periph B */ - 1 1 0x2 0x0>; /* PB1 periph B */ + <1 0 0x2 0x0>; /* PB0 periph B */ + }; + + pinctrl_usart2_cts: usart2_cts-0 { + atmel,pins = + <1 1 0x2 0x0>; /* PB1 periph B */ }; }; @@ -168,10 +176,14 @@ 2 22 0x2 0x0>; /* PC22 periph B */ }; - pinctrl_usart3_rts_cts: usart3_rts_cts-0 { + pinctrl_usart3_rts: usart3_rts-0 { + atmel,pins = + <2 24 0x2 0x0>; /* PC24 periph B */ + }; + + pinctrl_usart3_cts: usart3_cts-0 { atmel,pins = - <2 24 0x2 0x0 /* PC24 periph B */ - 2 25 0x2 0x0>; /* PC25 periph B */ + <2 25 0x2 0x0>; /* PC25 periph B */ }; }; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 9dac00693fa..3642ab1eeaf 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -133,10 +133,14 @@ 0 1 0x1 0x0>; /* PA1 periph A */ }; - pinctrl_usart0_rts_cts: usart0_rts_cts-0 { + pinctrl_usart0_rts: usart0_rts-0 { atmel,pins = - <0 2 0x1 0x0 /* PA2 periph A */ - 0 3 0x1 0x0>; /* PA3 periph A */ + <0 2 0x1 0x0>; /* PA2 periph A */ + }; + + pinctrl_usart0_cts: usart0_cts-0 { + atmel,pins = + <0 3 0x1 0x0>; /* PA3 periph A */ }; }; @@ -147,10 +151,14 @@ 0 6 0x1 0x0>; /* PA6 periph A */ }; - pinctrl_usart1_rts_cts: usart1_rts_cts-0 { + pinctrl_usart1_rts: usart1_rts-0 { + atmel,pins = + <3 27 0x3 0x0>; /* PC27 periph C */ + }; + + pinctrl_usart1_cts: usart1_cts-0 { atmel,pins = - <3 27 0x3 0x0 /* PC27 periph C */ - 3 28 0x3 0x0>; /* PC28 periph C */ + <3 28 0x3 0x0>; /* PC28 periph C */ }; }; @@ -161,10 +169,14 @@ 0 8 0x1 0x0>; /* PA8 periph A */ }; - pinctrl_uart2_rts_cts: uart2_rts_cts-0 { + pinctrl_uart2_rts: uart2_rts-0 { atmel,pins = - <0 0 0x2 0x0 /* PB0 periph B */ - 0 1 0x2 0x0>; /* PB1 periph B */ + <0 0 0x2 0x0>; /* PB0 periph B */ + }; + + pinctrl_uart2_cts: uart2_cts-0 { + atmel,pins = + <0 1 0x2 0x0>; /* PB1 periph B */ }; }; @@ -175,10 +187,14 @@ 3 23 0x2 0x0>; /* PC23 periph B */ }; - pinctrl_usart3_rts_cts: usart3_rts_cts-0 { + pinctrl_usart3_rts: usart3_rts-0 { + atmel,pins = + <3 24 0x2 0x0>; /* PC24 periph B */ + }; + + pinctrl_usart3_cts: usart3_cts-0 { atmel,pins = - <3 24 0x2 0x0 /* PC24 periph B */ - 3 25 0x2 0x0>; /* PC25 periph B */ + <3 25 0x2 0x0>; /* PC25 periph B */ }; }; -- cgit v1.2.3 From ee867d8eab1ffba8ace677eb6b62fba8c45d2e85 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 18 Oct 2012 14:10:21 +0800 Subject: ARM: at91: add Ronetix pm9g45 board support CPU Module with ATMEL AT91SAM9G45 http://www.ronetix.at/pm9g45.html Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/pm9g45.dts | 144 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 arch/arm/boot/dts/pm9g45.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index a9b051a8f70..627b6ad697c 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -19,6 +19,7 @@ dtb-$(CONFIG_ARCH_AT91) += tny_a9g20.dtb dtb-$(CONFIG_ARCH_AT91) += usb_a9g20.dtb # sam9g45 dtb-$(CONFIG_ARCH_AT91) += at91sam9m10g45ek.dtb +dtb-$(CONFIG_ARCH_AT91) += pm9g45.dtb # sam9n12 dtb-$(CONFIG_ARCH_AT91) += at91sam9n12ek.dtb # sam9x5 diff --git a/arch/arm/boot/dts/pm9g45.dts b/arch/arm/boot/dts/pm9g45.dts new file mode 100644 index 00000000000..b0c258dd19e --- /dev/null +++ b/arch/arm/boot/dts/pm9g45.dts @@ -0,0 +1,144 @@ +/* + * pm9g45.dts - Device Tree file for Ronetix pm9g45 board + * + * Copyright (C) 2012 Jean-Christophe PLAGNIOL-VILLARD + * + * Licensed under GPLv2. + */ +/dts-v1/; +/include/ "at91sam9g45.dtsi" + +/ { + model = "Ronetix pm9g45"; + compatible = "ronetix,pm9g45", "atmel,at91sam9g45", "atmel,at91sam9"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x70000000 0x8000000>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + main_clock: clock@0 { + compatible = "atmel,osc", "fixed-clock"; + clock-frequency = <12000000>; + }; + }; + + ahb { + apb { + dbgu: serial@ffffee00 { + status = "okay"; + }; + + pinctrl@fffff200 { + + board { + pinctrl_board_nand: nand0-board { + atmel,pins = + <3 3 0x0 0x1 /* PD3 gpio RDY pin pull_up*/ + 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */ + }; + }; + }; + + macb0: ethernet@fffbc000 { + phy-mode = "rmii"; + status = "okay"; + }; + }; + + nand0: nand@40000000 { + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + pinctrl-0 = <&pinctrl_board_nand>; + + gpios = <&pioD 3 0 + &pioC 14 0 + 0 + >; + + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x20000>; + }; + + barebox@20000 { + label = "barebox"; + reg = <0x20000 0x40000>; + }; + + bareboxenv@60000 { + label = "bareboxenv"; + reg = <0x60000 0x1A0000>; + }; + + kernel@200000 { + label = "bareboxenv2"; + reg = <0x200000 0x300000>; + }; + + kernel@500000 { + label = "root"; + reg = <0x500000 0x400000>; + }; + + data@900000 { + label = "data"; + reg = <0x900000 0x8340000>; + }; + }; + + usb0: ohci@00700000 { + status = "okay"; + num-ports = <2>; + }; + + usb1: ehci@00800000 { + status = "okay"; + }; + }; + + leds { + compatible = "gpio-leds"; + + led0 { + label = "led0"; + gpios = <&pioD 0 1>; + linux,default-trigger = "nand-disk"; + }; + + led1 { + label = "led1"; + gpios = <&pioD 31 0>; + linux,default-trigger = "heartbeat"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + right { + label = "SW4"; + gpios = <&pioE 7 1>; + linux,code = <106>; + }; + + up { + label = "SW3"; + gpios = <&pioE 8 1>; + linux,code = <103>; + }; + }; +}; -- cgit v1.2.3 From 35ed3c7a3dda78e9dd0c75a31290b27520e4a99b Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sun, 28 Oct 2012 18:31:06 +0000 Subject: ARM: AT91: Fix build failure on board-dt We need CONFIG_SOC_AT91SAM9 to get the at91sam926x_timer symbol used in board-dt. Signed-off-by: Joachim Eastwood Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index b1420710193..6d4de486df8 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -502,6 +502,7 @@ comment "Generic Board Type" config MACH_AT91SAM_DT bool "Atmel AT91SAM Evaluation Kits with device-tree support" + depends on SOC_AT91SAM9 select USE_OF help Select this if you want to experiment device-tree with -- cgit v1.2.3 From 454c46df83945602f1cbc86efcfd063c6945d869 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sun, 28 Oct 2012 18:31:07 +0000 Subject: ARM: AT91: Add DT support to AT91RM9200 System Timer Based on AT91 PIT DT patch from Jean-Christophe PLAGNIOL-VILLARD. Signed-off-by: Joachim Eastwood Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- .../devicetree/bindings/arm/atmel-at91.txt | 6 +++ arch/arm/mach-at91/at91rm9200_time.c | 63 +++++++++++++++++++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt index ecc81e36871..8adc9a8d6be 100644 --- a/Documentation/devicetree/bindings/arm/atmel-at91.txt +++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt @@ -7,6 +7,12 @@ PIT Timer required properties: - interrupts: Should contain interrupt for the PIT which is the IRQ line shared across all System Controller members. +System Timer (ST) required properties: +- compatible: Should be "atmel,at91rm9200-st" +- reg: Should contain registers location and length +- interrupts: Should contain interrupt for the ST which is the IRQ line + shared across all System Controller members. + TC/TCLIB Timer required properties: - compatible: Should be "atmel,-pit". can be "at91rm9200" or "at91sam9x5" diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index aaa443b48c9..cafe98836c8 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include #include @@ -91,7 +94,8 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) static struct irqaction at91rm9200_timer_irq = { .name = "at91_tick", .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = at91rm9200_timer_interrupt + .handler = at91rm9200_timer_interrupt, + .irq = NR_IRQS_LEGACY + AT91_ID_SYS, }; static cycle_t read_clk32k(struct clocksource *cs) @@ -179,8 +183,60 @@ static struct clock_event_device clkevt = { void __iomem *at91_st_base; EXPORT_SYMBOL_GPL(at91_st_base); +#ifdef CONFIG_OF +static struct of_device_id at91rm9200_st_timer_ids[] = { + { .compatible = "atmel,at91rm9200-st" }, + { /* sentinel */ } +}; + +static int __init of_at91rm9200_st_init(void) +{ + struct device_node *np; + int ret; + + np = of_find_matching_node(NULL, at91rm9200_st_timer_ids); + if (!np) + goto err; + + at91_st_base = of_iomap(np, 0); + if (!at91_st_base) + goto node_err; + + /* Get the interrupts property */ + ret = irq_of_parse_and_map(np, 0); + if (!ret) + goto ioremap_err; + at91rm9200_timer_irq.irq = ret; + + of_node_put(np); + + return 0; + +ioremap_err: + iounmap(at91_st_base); +node_err: + of_node_put(np); +err: + return -EINVAL; +} +#else +static int __init of_at91rm9200_st_init(void) +{ + return -EINVAL; +} +#endif + void __init at91rm9200_ioremap_st(u32 addr) { +#ifdef CONFIG_OF + struct device_node *np; + + np = of_find_matching_node(NULL, at91rm9200_st_timer_ids); + if (np) { + of_node_put(np); + return; + } +#endif at91_st_base = ioremap(addr, 256); if (!at91_st_base) panic("Impossible to ioremap ST\n"); @@ -191,13 +247,16 @@ void __init at91rm9200_ioremap_st(u32 addr) */ void __init at91rm9200_timer_init(void) { + /* For device tree enabled device: initialize here */ + of_at91rm9200_st_init(); + /* Disable all timer interrupts, and clear any pending ones */ at91_st_write(AT91_ST_IDR, AT91_ST_PITS | AT91_ST_WDOVF | AT91_ST_RTTINC | AT91_ST_ALMS); at91_st_read(AT91_ST_SR); /* Make IRQs happen for the system timer */ - setup_irq(NR_IRQS_LEGACY + AT91_ID_SYS, &at91rm9200_timer_irq); + setup_irq(at91rm9200_timer_irq.irq, &at91rm9200_timer_irq); /* The 32KiHz "Slow Clock" (tick every 30517.58 nanoseconds) is used * directly for the clocksource and all clockevents, after adjusting -- cgit v1.2.3 From 0ac433a719c344bcf29506e2e3f3766ff910b89a Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sun, 28 Oct 2012 18:31:08 +0000 Subject: ARM: AT91: Add usart/tc/pio/ohci DT clock lookup to AT91RM9200 Signed-off-by: Joachim Eastwood Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/at91rm9200.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index a45473425f5..ddf2bc143c7 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -194,6 +194,24 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_ID("pioB", &pioB_clk), CLKDEV_CON_ID("pioC", &pioC_clk), CLKDEV_CON_ID("pioD", &pioD_clk), + /* usart lookup table for DT entries */ + CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), + CLKDEV_CON_DEV_ID("usart", "fffc0000.serial", &usart0_clk), + CLKDEV_CON_DEV_ID("usart", "fffc4000.serial", &usart1_clk), + CLKDEV_CON_DEV_ID("usart", "fffc8000.serial", &usart2_clk), + CLKDEV_CON_DEV_ID("usart", "fffcc000.serial", &usart3_clk), + /* tc lookup table for DT entries */ + CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk), + CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk), + CLKDEV_CON_DEV_ID("t2_clk", "fffa0000.timer", &tc2_clk), + CLKDEV_CON_DEV_ID("t0_clk", "fffa4000.timer", &tc3_clk), + CLKDEV_CON_DEV_ID("t1_clk", "fffa4000.timer", &tc4_clk), + CLKDEV_CON_DEV_ID("t2_clk", "fffa4000.timer", &tc5_clk), + CLKDEV_CON_DEV_ID("hclk", "300000.ohci", &ohci_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioA_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioB_clk), + CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioC_clk), + CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioD_clk), }; static struct clk_lookup usart_clocks_lookups[] = { -- cgit v1.2.3 From 397f8c3ca3fec5906d82656ca23a841763196f22 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sun, 28 Oct 2012 18:31:09 +0000 Subject: ARM: AT91: Add AT91RM9200 DT board Signed-off-by: Joachim Eastwood Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/Kconfig | 8 +++++ arch/arm/mach-at91/Makefile | 1 + arch/arm/mach-at91/board-rm9200-dt.c | 59 ++++++++++++++++++++++++++++++++++++ arch/arm/mach-at91/generic.h | 1 + arch/arm/mach-at91/setup.c | 14 +++++++++ 5 files changed, 83 insertions(+) create mode 100644 arch/arm/mach-at91/board-rm9200-dt.c diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 6d4de486df8..d37dd5c2c64 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -500,6 +500,14 @@ endif comment "Generic Board Type" +config MACH_AT91RM9200_DT + bool "Atmel AT91RM9200 Evaluation Kits with device-tree support" + depends on SOC_AT91RM9200 + select USE_OF + help + Select this if you want to experiment device-tree with + an Atmel RM9200 Evaluation Kit. + config MACH_AT91SAM_DT bool "Atmel AT91SAM Evaluation Kits with device-tree support" depends on SOC_AT91SAM9 diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 3bb7a51efc9..b38a1dcb79b 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -88,6 +88,7 @@ obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o # AT91SAM board with device-tree +obj-$(CONFIG_MACH_AT91RM9200_DT) += board-rm9200-dt.o obj-$(CONFIG_MACH_AT91SAM_DT) += board-dt.o # AT91X40 board-specific support diff --git a/arch/arm/mach-at91/board-rm9200-dt.c b/arch/arm/mach-at91/board-rm9200-dt.c new file mode 100644 index 00000000000..47e91d9706b --- /dev/null +++ b/arch/arm/mach-at91/board-rm9200-dt.c @@ -0,0 +1,59 @@ +/* + * Setup code for AT91RM9200 Evaluation Kits with Device Tree support + * + * Copyright (C) 2011 Atmel, + * 2011 Nicolas Ferre + * 2012 Joachim Eastwood + * + * Licensed under GPLv2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "generic.h" + + +static const struct of_device_id irq_of_match[] __initconst = { + { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, + { /*sentinel*/ } +}; + +static void __init at91rm9200_dt_init_irq(void) +{ + of_irq_init(irq_of_match); +} + +static void __init at91rm9200_dt_device_init(void) +{ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char *at91rm9200_dt_board_compat[] __initdata = { + "atmel,at91rm9200", + NULL +}; + +DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)") + .timer = &at91rm9200_timer, + .map_io = at91_map_io, + .handle_irq = at91_aic_handle_irq, + .init_early = at91rm9200_dt_initialize, + .init_irq = at91rm9200_dt_init_irq, + .init_machine = at91rm9200_dt_device_init, + .dt_compat = at91rm9200_dt_board_compat, +MACHINE_END diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index f4965067765..9bb5ce5fb22 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -20,6 +20,7 @@ extern void __init at91_init_sram(int bank, unsigned long base, extern void __init at91rm9200_set_type(int type); extern void __init at91_initialize(unsigned long main_clock); extern void __init at91x40_initialize(unsigned long main_clock); +extern void __init at91rm9200_dt_initialize(void); extern void __init at91_dt_initialize(void); /* Interrupts */ diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 523daa92be1..e3f1ea4cff0 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -339,6 +339,7 @@ static void at91_dt_rstc(void) } static struct of_device_id ramc_ids[] = { + { .compatible = "atmel,at91rm9200-sdramc" }, { .compatible = "atmel,at91sam9260-sdramc" }, { .compatible = "atmel,at91sam9g45-ddramc" }, { /*sentinel*/ } @@ -437,6 +438,19 @@ end: of_node_put(np); } +void __init at91rm9200_dt_initialize(void) +{ + at91_dt_ramc(); + + /* Init clock subsystem */ + at91_dt_clock_init(); + + /* Register the processor-specific clocks */ + at91_boot_soc.register_clocks(); + + at91_boot_soc.init(); +} + void __init at91_dt_initialize(void) { at91_dt_rstc(); -- cgit v1.2.3 From fe975cf6d0d18b6ae3d39cb96e8bab5fb9f38fb5 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sun, 28 Oct 2012 18:31:10 +0000 Subject: ARM: AT91: Add AT91RM9200 device tree Signed-off-by: Joachim Eastwood Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91rm9200.dtsi | 349 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 349 insertions(+) create mode 100644 arch/arm/boot/dts/at91rm9200.dtsi diff --git a/arch/arm/boot/dts/at91rm9200.dtsi b/arch/arm/boot/dts/at91rm9200.dtsi new file mode 100644 index 00000000000..e154f242c68 --- /dev/null +++ b/arch/arm/boot/dts/at91rm9200.dtsi @@ -0,0 +1,349 @@ +/* + * at91rm9200.dtsi - Device Tree Include file for AT91RM9200 family SoC + * + * Copyright (C) 2011 Atmel, + * 2011 Nicolas Ferre , + * 2012 Joachim Eastwood + * + * Based on at91sam9260.dtsi + * + * Licensed under GPLv2 or later. + */ + +/include/ "skeleton.dtsi" + +/ { + model = "Atmel AT91RM9200 family SoC"; + compatible = "atmel,at91rm9200"; + interrupt-parent = <&aic>; + + aliases { + serial0 = &dbgu; + serial1 = &usart0; + serial2 = &usart1; + serial3 = &usart2; + serial4 = &usart3; + gpio0 = &pioA; + gpio1 = &pioB; + gpio2 = &pioC; + gpio3 = &pioD; + tcb0 = &tcb0; + tcb1 = &tcb1; + }; + cpus { + cpu@0 { + compatible = "arm,arm920t"; + }; + }; + + memory { + reg = <0x20000000 0x04000000>; + }; + + ahb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + apb { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + aic: interrupt-controller@fffff000 { + #interrupt-cells = <3>; + compatible = "atmel,at91rm9200-aic"; + interrupt-controller; + reg = <0xfffff000 0x200>; + atmel,external-irqs = <25 26 27 28 29 30 31>; + }; + + ramc0: ramc@ffffff00 { + compatible = "atmel,at91rm9200-sdramc"; + reg = <0xffffff00 0x100>; + }; + + pmc: pmc@fffffc00 { + compatible = "atmel,at91rm9200-pmc"; + reg = <0xfffffc00 0x100>; + }; + + st: timer@fffffd00 { + compatible = "atmel,at91rm9200-st"; + reg = <0xfffffd00 0x100>; + interrupts = <1 4 7>; + }; + + tcb0: timer@fffa0000 { + compatible = "atmel,at91rm9200-tcb"; + reg = <0xfffa0000 0x100>; + interrupts = <17 4 0 18 4 0 19 4 0>; + }; + + tcb1: timer@fffa4000 { + compatible = "atmel,at91rm9200-tcb"; + reg = <0xfffa4000 0x100>; + interrupts = <20 4 0 21 4 0 22 4 0>; + }; + + pinctrl@fffff400 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "atmel,at91rm9200-pinctrl", "simple-bus"; + ranges = <0xfffff400 0xfffff400 0x800>; + + atmel,mux-mask = < + /* A B */ + 0xffffffff 0xffffffff /* pioA */ + 0xffffffff 0x083fffff /* pioB */ + 0xffff3fff 0x00000000 /* pioC */ + 0x03ff87ff 0x0fffff80 /* pioD */ + >; + + /* shared pinctrl settings */ + dbgu { + pinctrl_dbgu: dbgu-0 { + atmel,pins = + <0 30 0x1 0x0 /* PA30 periph A */ + 0 31 0x1 0x1>; /* PA31 periph with pullup */ + }; + }; + + uart0 { + pinctrl_uart0: uart0-0 { + atmel,pins = + <0 17 0x1 0x0 /* PA17 periph A */ + 0 18 0x1 0x0>; /* PA18 periph A */ + }; + + pinctrl_uart0_rts: uart0_rts-0 { + atmel,pins = + <0 20 0x1 0x0>; /* PA20 periph A */ + }; + + pinctrl_uart0_cts: uart0_cts-0 { + atmel,pins = + <0 21 0x1 0x0>; /* PA21 periph A */ + }; + }; + + uart1 { + pinctrl_uart1: uart1-0 { + atmel,pins = + <1 20 0x1 0x1 /* PB20 periph A with pullup */ + 1 21 0x1 0x0>; /* PB21 periph A */ + }; + + pinctrl_uart1_rts: uart1_rts-0 { + atmel,pins = + <1 24 0x1 0x0>; /* PB24 periph A */ + }; + + pinctrl_uart1_cts: uart1_cts-0 { + atmel,pins = + <1 26 0x1 0x0>; /* PB26 periph A */ + }; + + pinctrl_uart1_dtr_dsr: uart1_dtr_dsr-0 { + atmel,pins = + <1 19 0x1 0x0 /* PB19 periph A */ + 1 25 0x1 0x0>; /* PB25 periph A */ + }; + + pinctrl_uart1_dcd: uart1_dcd-0 { + atmel,pins = + <1 23 0x1 0x0>; /* PB23 periph A */ + }; + + pinctrl_uart1_ri: uart1_ri-0 { + atmel,pins = + <1 18 0x1 0x0>; /* PB18 periph A */ + }; + }; + + uart2 { + pinctrl_uart2: uart2-0 { + atmel,pins = + <0 22 0x1 0x0 /* PA22 periph A */ + 0 23 0x1 0x1>; /* PA23 periph A with pullup */ + }; + + pinctrl_uart2_rts: uart2_rts-0 { + atmel,pins = + <0 30 0x2 0x0>; /* PA30 periph B */ + }; + + pinctrl_uart2_cts: uart2_cts-0 { + atmel,pins = + <0 31 0x2 0x0>; /* PA31 periph B */ + }; + }; + + uart3 { + pinctrl_uart3: uart3-0 { + atmel,pins = + <0 5 0x2 0x1 /* PA5 periph B with pullup */ + 0 6 0x2 0x0>; /* PA6 periph B */ + }; + + pinctrl_uart3_rts: uart3_rts-0 { + atmel,pins = + <1 0 0x2 0x0>; /* PB0 periph B */ + }; + + pinctrl_uart3_cts: uart3_cts-0 { + atmel,pins = + <1 1 0x2 0x0>; /* PB1 periph B */ + }; + }; + + nand { + pinctrl_nand: nand-0 { + atmel,pins = + <2 2 0x0 0x1 /* PC2 gpio RDY pin pull_up */ + 1 1 0x0 0x1>; /* PB1 gpio CD pin pull_up */ + }; + }; + + pioA: gpio@fffff400 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff400 0x200>; + interrupts = <2 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pioB: gpio@fffff600 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff600 0x200>; + interrupts = <3 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pioC: gpio@fffff800 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffff800 0x200>; + interrupts = <4 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pioD: gpio@fffffa00 { + compatible = "atmel,at91rm9200-gpio"; + reg = <0xfffffa00 0x200>; + interrupts = <5 4 1>; + #gpio-cells = <2>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + dbgu: serial@fffff200 { + compatible = "atmel,at91rm9200-usart"; + reg = <0xfffff200 0x200>; + interrupts = <1 4 7>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_dbgu>; + status = "disabled"; + }; + + usart0: serial@fffc0000 { + compatible = "atmel,at91rm9200-usart"; + reg = <0xfffc0000 0x200>; + interrupts = <6 4 5>; + atmel,use-dma-rx; + atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart0>; + status = "disabled"; + }; + + usart1: serial@fffc4000 { + compatible = "atmel,at91rm9200-usart"; + reg = <0xfffc4000 0x200>; + interrupts = <7 4 5>; + atmel,use-dma-rx; + atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "disabled"; + }; + + usart2: serial@fffc8000 { + compatible = "atmel,at91rm9200-usart"; + reg = <0xfffc8000 0x200>; + interrupts = <8 4 5>; + atmel,use-dma-rx; + atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "disabled"; + }; + + usart3: serial@fffcc000 { + compatible = "atmel,at91rm9200-usart"; + reg = <0xfffcc000 0x200>; + interrupts = <23 4 5>; + atmel,use-dma-rx; + atmel,use-dma-tx; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + status = "disabled"; + }; + + usb1: gadget@fffb0000 { + compatible = "atmel,at91rm9200-udc"; + reg = <0xfffb0000 0x4000>; + interrupts = <11 4 2>; + status = "disabled"; + }; + }; + + nand0: nand@40000000 { + compatible = "atmel,at91rm9200-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x40000000 0x10000000>; + atmel,nand-addr-offset = <21>; + atmel,nand-cmd-offset = <22>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_nand>; + nand-ecc-mode = "soft"; + gpios = <&pioC 2 0 + 0 + &pioB 1 0 + >; + status = "disabled"; + }; + + usb0: ohci@00300000 { + compatible = "atmel,at91rm9200-ohci", "usb-ohci"; + reg = <0x00300000 0x100000>; + interrupts = <23 4 2>; + status = "disabled"; + }; + }; + + i2c@0 { + compatible = "i2c-gpio"; + gpios = <&pioA 23 0 /* sda */ + &pioA 24 0 /* scl */ + >; + i2c-gpio,sda-open-drain; + i2c-gpio,scl-open-drain; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; +}; -- cgit v1.2.3 From c84ca7ce3ae5d80622c1cc1cfe21011f9cc15be7 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Sun, 28 Oct 2012 18:31:11 +0000 Subject: ARM: AT91: Add AT91RM9200EK board device tree Signed-off-by: Joachim Eastwood Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/Makefile | 2 + arch/arm/boot/dts/at91rm9200ek.dts | 79 ++++++++++++++++++++++++++++++++++++ arch/arm/mach-at91/board-rm9200-dt.c | 4 +- 3 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 arch/arm/boot/dts/at91rm9200ek.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 627b6ad697c..4a4337b1947 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -1,6 +1,8 @@ ifeq ($(CONFIG_OF),y) # Keep at91 dtb files sorted alphabetically for each SoC +# rm9200 +dtb-$(CONFIG_ARCH_AT91) += at91rm9200ek.dtb # sam9260 dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb dtb-$(CONFIG_ARCH_AT91) += ethernut5.dtb diff --git a/arch/arm/boot/dts/at91rm9200ek.dts b/arch/arm/boot/dts/at91rm9200ek.dts new file mode 100644 index 00000000000..8aa48931e0a --- /dev/null +++ b/arch/arm/boot/dts/at91rm9200ek.dts @@ -0,0 +1,79 @@ +/* + * at91rm9200ek.dts - Device Tree file for Atmel AT91RM9200 evaluation kit + * + * Copyright (C) 2012 Joachim Eastwood + * + * Licensed under GPLv2 only + */ +/dts-v1/; +/include/ "at91rm9200.dtsi" + +/ { + model = "Atmel AT91RM9200 evaluation kit"; + compatible = "atmel,at91rm9200ek", "atmel,at91rm9200"; + + memory { + reg = <0x20000000 0x4000000>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + main_clock: clock@0 { + compatible = "atmel,osc", "fixed-clock"; + clock-frequency = <18432000>; + }; + }; + + ahb { + apb { + dbgu: serial@fffff200 { + status = "okay"; + }; + + usart1: serial@fffc4000 { + pinctrl-0 = + <&pinctrl_uart1 + &pinctrl_uart1_rts + &pinctrl_uart1_cts + &pinctrl_uart1_dtr_dsr + &pinctrl_uart1_dcd + &pinctrl_uart1_ri>; + status = "okay"; + }; + + usb1: gadget@fffb0000 { + atmel,vbus-gpio = <&pioD 4 0>; + status = "okay"; + }; + }; + + usb0: ohci@00300000 { + num-ports = <2>; + status = "okay"; + }; + }; + + leds { + compatible = "gpio-leds"; + + ds2 { + label = "green"; + gpios = <&pioB 0 0x1>; + linux,default-trigger = "mmc0"; + }; + + ds4 { + label = "yellow"; + gpios = <&pioB 1 0x1>; + linux,default-trigger = "heartbeat"; + }; + + ds6 { + label = "red"; + gpios = <&pioB 2 0x1>; + }; + }; +}; diff --git a/arch/arm/mach-at91/board-rm9200-dt.c b/arch/arm/mach-at91/board-rm9200-dt.c index 47e91d9706b..5f9ce3da3fd 100644 --- a/arch/arm/mach-at91/board-rm9200-dt.c +++ b/arch/arm/mach-at91/board-rm9200-dt.c @@ -16,15 +16,13 @@ #include #include -#include -#include - #include #include #include #include #include +#include "at91_aic.h" #include "generic.h" -- cgit v1.2.3 From ad8a15d99cf2c8ab8ac1ab28402c49ec2548358d Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 15 Nov 2012 21:56:27 +0800 Subject: ARM: at91: add Somfy Animeo IP board support Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/animeo_ip.dts | 166 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 arch/arm/boot/dts/animeo_ip.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 4a4337b1947..52c6b46098b 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -4,6 +4,7 @@ ifeq ($(CONFIG_OF),y) # rm9200 dtb-$(CONFIG_ARCH_AT91) += at91rm9200ek.dtb # sam9260 +dtb-$(CONFIG_ARCH_AT91) += animeo_ip.dtb dtb-$(CONFIG_ARCH_AT91) += aks-cdu.dtb dtb-$(CONFIG_ARCH_AT91) += ethernut5.dtb dtb-$(CONFIG_ARCH_AT91) += evk-pro3.dtb diff --git a/arch/arm/boot/dts/animeo_ip.dts b/arch/arm/boot/dts/animeo_ip.dts new file mode 100644 index 00000000000..518baedaae0 --- /dev/null +++ b/arch/arm/boot/dts/animeo_ip.dts @@ -0,0 +1,166 @@ +/* + * animeo_ip.dts - Device Tree file for Somfy Animeo IP Boards + * + * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD + * + * Licensed under GPLv2 only. + */ + +/dts-v1/; +/include/ "at91sam9260.dtsi" + +/ { + model = "Somfy Animeo IP"; + compatible = "somfy,animeo-ip", "atmel,at91sam9260", "atmel,at91sam9"; + + aliases { + serial0 = &usart1; + serial1 = &usart2; + serial2 = &usart0; + serial3 = &dbgu; + serial4 = &usart3; + serial5 = &uart0; + serial6 = &uart1; + }; + + chosen { + linux,stdout-path = &usart2; + }; + + memory { + reg = <0x20000000 0x4000000>; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + main_clock: clock@0 { + compatible = "atmel,osc", "fixed-clock"; + clock-frequency = <18432000>; + }; + }; + + ahb { + apb { + usart0: serial@fffb0000 { + pinctrl-0 = <&pinctrl_usart0 &pinctrl_usart0_rts>; + linux,rs485-enabled-at-boot-time; + status = "okay"; + }; + + usart1: serial@fffb4000 { + pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts>; + linux,rs485-enabled-at-boot-time; + status = "okay"; + }; + + usart2: serial@fffb8000 { + pinctrl-0 = <&pinctrl_usart2>; + status = "okay"; + }; + + macb0: ethernet@fffc4000 { + pinctrl-0 = <&pinctrl_macb_rmii &pinctrl_macb_rmii_mii>; + phy-mode = "mii"; + status = "okay"; + }; + }; + + nand0: nand@40000000 { + nand-bus-width = <8>; + nand-ecc-mode = "soft"; + nand-on-flash-bbt; + status = "okay"; + + at91bootstrap@0 { + label = "at91bootstrap"; + reg = <0x0 0x8000>; + }; + + barebox@8000 { + label = "barebox"; + reg = <0x8000 0x40000>; + }; + + bareboxenv@48000 { + label = "bareboxenv"; + reg = <0x48000 0x8000>; + }; + + user_block@0x50000 { + label = "user_block"; + reg = <0x50000 0xb0000>; + }; + + kernel@100000 { + label = "kernel"; + reg = <0x100000 0x1b0000>; + }; + + root@2b0000 { + label = "root"; + reg = <0x2b0000 0x1D50000>; + }; + }; + + usb0: ohci@00500000 { + num-ports = <2>; + atmel,vbus-gpio = <&pioB 15 1>; + status = "okay"; + }; + }; + + leds { + compatible = "gpio-leds"; + + power_green { + label = "power_green"; + gpios = <&pioC 17 0>; + linux,default-trigger = "heartbeat"; + }; + + power_red { + label = "power_red"; + gpios = <&pioA 2 0>; + }; + + tx_green { + label = "tx_green"; + gpios = <&pioC 19 0>; + }; + + tx_red { + label = "tx_red"; + gpios = <&pioC 18 0>; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + keyswitch_in { + label = "keyswitch_in"; + gpios = <&pioB 1 0>; + linux,code = <28>; + gpio-key,wakeup; + }; + + error_in { + label = "error_in"; + gpios = <&pioB 2 0>; + linux,code = <29>; + gpio-key,wakeup; + }; + + btn { + label = "btn"; + gpios = <&pioC 23 0>; + linux,code = <31>; + gpio-key,wakeup; + }; + }; +}; -- cgit v1.2.3 From fae2ae2a900a5c7bb385fe4075f343e7e2d5daa2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 18 Nov 2012 22:27:03 -0500 Subject: sparc64: not any error from do_sigaltstack() should fail rt_sigreturn() If a signal handler is executed on altstack and another signal comes, we will end up with rt_sigreturn() on return from the second handler getting -EPERM from do_sigaltstack(). It's perfectly OK, since we are not asking to change the settings; in fact, they couldn't have been changed during the second handler execution exactly because we'd been on altstack all along. 64bit sigreturn on sparc treats any error from do_sigaltstack() as "SIGSEGV now"; we need to switch to the same semantics we are using on other architectures. Cc: stable@vger.kernel.org Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/sparc/kernel/signal_64.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 867de2f8189..689e1ba6280 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -295,9 +295,7 @@ void do_rt_sigreturn(struct pt_regs *regs) err |= restore_fpu_state(regs, fpu_save); err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); - err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf); - - if (err) + if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT) goto segv; err |= __get_user(rwin_save, &sf->rwin_save); -- cgit v1.2.3 From c91cb7a75eaf65358aac5ea2b512ac60a9437ff4 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 16 Nov 2012 09:14:12 -0800 Subject: Input: mousedev - move /dev/input/mice to the correct minor When doing conversion to dynamic input numbers I inadvertently moved /dev/input/mice from c,13,63 to c,13,31. We need to fix this so that setups with statically populated /dev continue working. Tested-by: Krzysztof Mazur Tested-by: Pavel Machek Signed-off-by: Dmitry Torokhov --- drivers/input/mousedev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 8f02e3d0e71..4c842c320c2 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -12,8 +12,8 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define MOUSEDEV_MINOR_BASE 32 -#define MOUSEDEV_MINORS 32 -#define MOUSEDEV_MIX 31 +#define MOUSEDEV_MINORS 31 +#define MOUSEDEV_MIX 63 #include #include -- cgit v1.2.3 From e37212aa5df1937bc19c0d0982d216675020a7ca Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Wed, 3 Oct 2012 12:05:00 +0530 Subject: ARM: davinci: dm644x: fix out range signal for ED Fix the video clock setting when custom timings are used with pclock <= 27MHz. Existing video clock selection uses PLL2 mode which results in a 54MHz clock whereas using the MXI mode results in a 27MHz clock (which is the one actually desired). This bug affects the Enhanced Definition (ED) support on DM644x. Without this patch, out-range signals errors are were observed on the TV when viewing ED. An out-of-range signal is often caused when the field rate is above the rate that the television will handle. Signed-off-by: Lad, Prabhakar Signed-off-by: Manjunath Hadli Cc: Sekhar Nori [nsekhar@ti.com: reword commit message based on on-list discussion] Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/dm644x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index cd0c8b1e1ec..14e9947bad6 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -713,8 +713,7 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type, break; case VPBE_ENC_CUSTOM_TIMINGS: if (pclock <= 27000000) { - v |= DM644X_VPSS_MUXSEL_PLL2_MODE | - DM644X_VPSS_DACCLKEN; + v |= DM644X_VPSS_DACCLKEN; writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); } else { /* -- cgit v1.2.3 From c415187b689842e8bb85135c070c822c2505f805 Mon Sep 17 00:00:00 2001 From: Tushar Behera Date: Mon, 19 Nov 2012 10:40:15 +0530 Subject: OMAPFB: Fix possible null pointer dereferencing Commit 952cbaaa9b8beacc425f9aedf370468cbb737a2c (OMAPFB: Change dssdev->manager references) added checks for OMAPFB_WAITFORVSYNC ioctl to verify that the display, output and overlay manager exist. However, the code erroneously uses && for each part, which means that OMAPFB_WAITFORVSYNC may crash the kernel if no display, output or manager is associated with the framebuffer. This patch fixes the issue by using ||. Signed-off-by: Tushar Behera Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 606b89f1235..d630b26a005 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -787,7 +787,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) case OMAPFB_WAITFORVSYNC: DBG("ioctl WAITFORVSYNC\n"); - if (!display && !display->output && !display->output->manager) { + if (!display || !display->output || !display->output->manager) { r = -EINVAL; break; } -- cgit v1.2.3 From 6c8d8b3c69cef1330e0c5cbc2a8b9268024927a0 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 13 Jul 2012 15:44:14 -0400 Subject: x86_32: Return actual stack when requesting sp from regs As x86_32 traps do not save sp when taken in kernel mode, we need to accommodate the sp when requesting to get the register. This affects kprobes. Before: # echo 'p:ftrace sys_read+4 s=%sp' > /debug/tracing/kprobe_events # echo 1 > /debug/tracing/events/kprobes/enable # cat trace sshd-1345 [000] d... 489.117168: ftrace: (sys_read+0x4/0x70) s=b7e96768 sshd-1345 [000] d... 489.117191: ftrace: (sys_read+0x4/0x70) s=b7e96768 cat-1447 [000] d... 489.117392: ftrace: (sys_read+0x4/0x70) s=5a7 cat-1447 [001] d... 489.118023: ftrace: (sys_read+0x4/0x70) s=b77ad05f less-1448 [000] d... 489.118079: ftrace: (sys_read+0x4/0x70) s=b7762e06 less-1448 [000] d... 489.118117: ftrace: (sys_read+0x4/0x70) s=b7764970 After: sshd-1352 [000] d... 362.348016: ftrace: (sys_read+0x4/0x70) s=f3febfa8 sshd-1352 [000] d... 362.348048: ftrace: (sys_read+0x4/0x70) s=f3febfa8 bash-1355 [001] d... 362.348081: ftrace: (sys_read+0x4/0x70) s=f5075fa8 sshd-1352 [000] d... 362.348082: ftrace: (sys_read+0x4/0x70) s=f3febfa8 sshd-1352 [000] d... 362.690950: ftrace: (sys_read+0x4/0x70) s=f3febfa8 bash-1355 [001] d... 362.691033: ftrace: (sys_read+0x4/0x70) s=f5075fa8 Link: http://lkml.kernel.org/r/1342208654.30075.22.camel@gandalf.stny.rr.com Reviewed-by: Masami Hiramatsu Signed-off-by: Steven Rostedt --- arch/x86/include/asm/ptrace.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index dcfde52979c..2233713d029 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -246,6 +246,15 @@ static inline unsigned long regs_get_register(struct pt_regs *regs, { if (unlikely(offset > MAX_REG_OFFSET)) return 0; +#ifdef CONFIG_X86_32 + /* + * Traps from the kernel do not save sp and ss. + * Use the helper function to retrieve sp. + */ + if (offset == offsetof(struct pt_regs, sp) && + regs->cs == __KERNEL_CS) + return kernel_stack_pointer(regs); +#endif return *(unsigned long *)((unsigned long)regs + offset); } -- cgit v1.2.3 From 963f2076e3b4d62e219b3fa60de7b50e335f5783 Mon Sep 17 00:00:00 2001 From: Abhilash Kesavan Date: Mon, 19 Nov 2012 15:48:46 +0530 Subject: i2c: s3c2410: Fix code to free gpios Store the requested gpios so that they can be freed on error/removal. Signed-off-by: Abhilash Kesavan Signed-off-by: Wolfram Sang --- drivers/i2c/busses/i2c-s3c2410.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 3e0335f1fc6..9d902725bac 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -806,6 +806,7 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c) dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio); goto free_gpio; } + i2c->gpios[idx] = gpio; ret = gpio_request(gpio, "i2c-bus"); if (ret) { -- cgit v1.2.3 From 989c3187156ad197ae473fa9d9d506eef9624f12 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Nov 2012 14:14:58 +0100 Subject: ALSA: hda - Fix recursive suspend/resume call When the bus reset is performed during the suspend/resume (including the power-saving too), it calls snd_hda_suspend() and snd_hda_resume() again, and deadlocks eventually. For avoiding the recursive call, add a new flag indicating that the PM is being performed, and don't go to the bus reset mode when it's on. Reported-and-tested-by: Julian Wollrath Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 11 +++++++++-- sound/pci/hda/hda_codec.h | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 70d4848b5cd..cebe2dfdd98 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -228,7 +228,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, } mutex_unlock(&bus->cmd_mutex); snd_hda_power_down(codec); - if (res && *res == -1 && bus->rirb_error) { + if (!codec->in_pm && res && *res == -1 && bus->rirb_error) { if (bus->response_reset) { snd_printd("hda_codec: resetting BUS due to " "fatal communication error\n"); @@ -238,7 +238,7 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, goto again; } /* clear reset-flag when the communication gets recovered */ - if (!err) + if (!err || codec->in_pm) bus->response_reset = 0; return err; } @@ -3616,6 +3616,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) { unsigned int state; + codec->in_pm = 1; + if (codec->patch_ops.suspend) codec->patch_ops.suspend(codec); hda_cleanup_all_streams(codec); @@ -3630,6 +3632,7 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) codec->power_transition = 0; codec->power_jiffies = jiffies; spin_unlock(&codec->power_lock); + codec->in_pm = 0; return state; } @@ -3638,6 +3641,8 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq) */ static void hda_call_codec_resume(struct hda_codec *codec) { + codec->in_pm = 1; + /* set as if powered on for avoiding re-entering the resume * in the resume / power-save sequence */ @@ -3656,6 +3661,8 @@ static void hda_call_codec_resume(struct hda_codec *codec) snd_hda_codec_resume_cache(codec); } snd_hda_jack_report_sync(codec); + + codec->in_pm = 0; snd_hda_power_down(codec); /* flag down before returning */ } #endif /* CONFIG_PM */ diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 507fe8a917b..4f4e545c0f4 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -869,6 +869,7 @@ struct hda_codec { unsigned int power_on :1; /* current (global) power-state */ unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ unsigned int pm_down_notified:1; /* PM notified to controller */ + unsigned int in_pm:1; /* suspend/resume being performed */ int power_transition; /* power-state in transition */ int power_count; /* current (global) power refcount */ struct delayed_work power_work; /* delayed task for powerdown */ -- cgit v1.2.3 From da8fb123b041e487d28f54d3a77a15139cb9e3b9 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sat, 17 Nov 2012 21:20:50 +0530 Subject: ath9k_hw: Fix regression in device reset Commit "ath9k: improve suspend/resume reliability" broke ath9k_htc and bringing up the device would hang indefinitely. Fix this. Cc: stable@vger.kernel.org Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 8e1559aba49..1829b445d0b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1456,7 +1456,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) switch (type) { case ATH9K_RESET_POWER_ON: ret = ath9k_hw_set_reset_power_on(ah); - if (!ret) + if (ret) ah->reset_power_on = true; break; case ATH9K_RESET_WARM: -- cgit v1.2.3 From fd25b4c2f226de818e1d2b71e3e681d28bcaf5ba Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 13 Nov 2012 18:21:22 +0100 Subject: vtime: Remove the underscore prefix invasion Prepending irq-unsafe vtime APIs with underscores was actually a bad idea as the result is a big mess in the API namespace that is even waiting to be further extended. Also these helpers are always called from irq safe callers except kvm. Just provide a vtime_account_system_irqsafe() for this specific case so that we can remove the underscore prefix on other vtime functions. Signed-off-by: Frederic Weisbecker Reviewed-by: Steven Rostedt Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Steven Rostedt Cc: Paul Gortmaker Cc: Tony Luck Cc: Fenghua Yu Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Martin Schwidefsky Cc: Heiko Carstens --- arch/ia64/kernel/time.c | 8 ++++---- arch/powerpc/kernel/time.c | 4 ++-- arch/s390/kernel/vtime.c | 4 ++-- include/linux/kvm_host.h | 4 ++-- include/linux/vtime.h | 8 ++++---- kernel/sched/cputime.c | 12 ++++++------ 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 5e4850305d3..f6388216080 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -106,9 +106,9 @@ void vtime_task_switch(struct task_struct *prev) struct thread_info *ni = task_thread_info(current); if (idle_task(smp_processor_id()) != prev) - __vtime_account_system(prev); + vtime_account_system(prev); else - __vtime_account_idle(prev); + vtime_account_idle(prev); vtime_account_user(prev); @@ -135,14 +135,14 @@ static cputime_t vtime_delta(struct task_struct *tsk) return delta_stime; } -void __vtime_account_system(struct task_struct *tsk) +void vtime_account_system(struct task_struct *tsk) { cputime_t delta = vtime_delta(tsk); account_system_time(tsk, 0, delta, delta); } -void __vtime_account_idle(struct task_struct *tsk) +void vtime_account_idle(struct task_struct *tsk) { account_idle_time(vtime_delta(tsk)); } diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 0db456f30d4..ce4cb772dc7 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -336,7 +336,7 @@ static u64 vtime_delta(struct task_struct *tsk, return delta; } -void __vtime_account_system(struct task_struct *tsk) +void vtime_account_system(struct task_struct *tsk) { u64 delta, sys_scaled, stolen; @@ -346,7 +346,7 @@ void __vtime_account_system(struct task_struct *tsk) account_steal_time(stolen); } -void __vtime_account_idle(struct task_struct *tsk) +void vtime_account_idle(struct task_struct *tsk) { u64 delta, sys_scaled, stolen; diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 783e988c4e1..80d1dbc5d42 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -140,9 +140,9 @@ void vtime_account(struct task_struct *tsk) } EXPORT_SYMBOL_GPL(vtime_account); -void __vtime_account_system(struct task_struct *tsk) +void vtime_account_system(struct task_struct *tsk) __attribute__((alias("vtime_account"))); -EXPORT_SYMBOL_GPL(__vtime_account_system); +EXPORT_SYMBOL_GPL(vtime_account_system); void __kprobes vtime_stop_cpu(void) { diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 0e2212fe478..f17158bdd4f 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -741,7 +741,7 @@ static inline void kvm_guest_enter(void) * This is running in ioctl context so we can avoid * the call to vtime_account() with its unnecessary idle check. */ - vtime_account_system(current); + vtime_account_system_irqsafe(current); current->flags |= PF_VCPU; /* KVM does not hold any references to rcu protected data when it * switches CPU into a guest mode. In fact switching to a guest mode @@ -759,7 +759,7 @@ static inline void kvm_guest_exit(void) * This is running in ioctl context so we can avoid * the call to vtime_account() with its unnecessary idle check. */ - vtime_account_system(current); + vtime_account_system_irqsafe(current); current->flags &= ~PF_VCPU; } diff --git a/include/linux/vtime.h b/include/linux/vtime.h index 0c2a2d30302..5ad13c325de 100644 --- a/include/linux/vtime.h +++ b/include/linux/vtime.h @@ -5,14 +5,14 @@ struct task_struct; #ifdef CONFIG_VIRT_CPU_ACCOUNTING extern void vtime_task_switch(struct task_struct *prev); -extern void __vtime_account_system(struct task_struct *tsk); extern void vtime_account_system(struct task_struct *tsk); -extern void __vtime_account_idle(struct task_struct *tsk); +extern void vtime_account_system_irqsafe(struct task_struct *tsk); +extern void vtime_account_idle(struct task_struct *tsk); extern void vtime_account(struct task_struct *tsk); #else static inline void vtime_task_switch(struct task_struct *prev) { } -static inline void __vtime_account_system(struct task_struct *tsk) { } static inline void vtime_account_system(struct task_struct *tsk) { } +static inline void vtime_account_system_irqsafe(struct task_struct *tsk) { } static inline void vtime_account(struct task_struct *tsk) { } #endif @@ -40,7 +40,7 @@ static inline void vtime_account_irq_enter(struct task_struct *tsk) static inline void vtime_account_irq_exit(struct task_struct *tsk) { /* On hard|softirq exit we always account to hard|softirq cputime */ - __vtime_account_system(tsk); + vtime_account_system(tsk); irqtime_account_irq(tsk); } diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 8d859dae5be..c0aa1ba752e 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -433,20 +433,20 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st) *st = cputime.stime; } -void vtime_account_system(struct task_struct *tsk) +void vtime_account_system_irqsafe(struct task_struct *tsk) { unsigned long flags; local_irq_save(flags); - __vtime_account_system(tsk); + vtime_account_system(tsk); local_irq_restore(flags); } -EXPORT_SYMBOL_GPL(vtime_account_system); +EXPORT_SYMBOL_GPL(vtime_account_system_irqsafe); /* * Archs that account the whole time spent in the idle task * (outside irq) as idle time can rely on this and just implement - * __vtime_account_system() and __vtime_account_idle(). Archs that + * vtime_account_system() and vtime_account_idle(). Archs that * have other meaning of the idle time (s390 only includes the * time spent by the CPU when it's in low power mode) must override * vtime_account(). @@ -459,9 +459,9 @@ void vtime_account(struct task_struct *tsk) local_irq_save(flags); if (in_interrupt() || !is_idle_task(tsk)) - __vtime_account_system(tsk); + vtime_account_system(tsk); else - __vtime_account_idle(tsk); + vtime_account_idle(tsk); local_irq_restore(flags); } -- cgit v1.2.3 From bcebdf846522056a84ba0b0cba5f5413868c9394 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 13 Nov 2012 23:51:06 +0100 Subject: vtime: Explicitly account pending user time on process tick All vtime implementations just flush the user time on process tick. Consolidate that in generic code by calling a user time accounting helper. This avoids an indirect call in ia64 and prepare to also consolidate vtime context switch code. Signed-off-by: Frederic Weisbecker Reviewed-by: Steven Rostedt Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Steven Rostedt Cc: Paul Gortmaker Cc: Tony Luck Cc: Fenghua Yu Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Martin Schwidefsky Cc: Heiko Carstens --- arch/ia64/kernel/time.c | 11 +---------- arch/powerpc/kernel/time.c | 14 +++++++------- arch/s390/kernel/vtime.c | 7 ++++++- include/linux/kernel_stat.h | 8 ++++++++ include/linux/vtime.h | 1 + 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index f6388216080..834c78bd3b5 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -83,7 +83,7 @@ static struct clocksource *itc_clocksource; extern cputime_t cycle_to_cputime(u64 cyc); -static void vtime_account_user(struct task_struct *tsk) +void vtime_account_user(struct task_struct *tsk) { cputime_t delta_utime; struct thread_info *ti = task_thread_info(tsk); @@ -147,15 +147,6 @@ void vtime_account_idle(struct task_struct *tsk) account_idle_time(vtime_delta(tsk)); } -/* - * Called from the timer interrupt handler to charge accumulated user time - * to the current process. Must be called with interrupts disabled. - */ -void account_process_tick(struct task_struct *p, int user_tick) -{ - vtime_account_user(p); -} - #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ static irqreturn_t diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index ce4cb772dc7..a667aaf8584 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -355,15 +355,15 @@ void vtime_account_idle(struct task_struct *tsk) } /* - * Transfer the user and system times accumulated in the paca - * by the exception entry and exit code to the generic process - * user and system time records. + * Transfer the user time accumulated in the paca + * by the exception entry and exit code to the generic + * process user time records. * Must be called with interrupts disabled. - * Assumes that vtime_account() has been called recently - * (i.e. since the last entry from usermode) so that + * Assumes that vtime_account_system/idle() has been called + * recently (i.e. since the last entry from usermode) so that * get_paca()->user_time_scaled is up to date. */ -void account_process_tick(struct task_struct *tsk, int user_tick) +void vtime_account_user(struct task_struct *tsk) { cputime_t utime, utimescaled; @@ -378,7 +378,7 @@ void account_process_tick(struct task_struct *tsk, int user_tick) void vtime_task_switch(struct task_struct *prev) { vtime_account(prev); - account_process_tick(prev, 0); + vtime_account_user(prev); } #else /* ! CONFIG_VIRT_CPU_ACCOUNTING */ diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 80d1dbc5d42..7c6d861a1a4 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -112,7 +112,12 @@ void vtime_task_switch(struct task_struct *prev) S390_lowcore.system_timer = ti->system_timer; } -void account_process_tick(struct task_struct *tsk, int user_tick) +/* + * In s390, accounting pending user time also implies + * accounting system time in order to correctly compute + * the stolen time accounting. + */ +void vtime_account_user(struct task_struct *tsk) { if (do_account_vtime(tsk, HARDIRQ_OFFSET)) virt_timer_expire(); diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 1865b1f2977..66b70780e91 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -127,7 +127,15 @@ extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t) extern void account_steal_time(cputime_t); extern void account_idle_time(cputime_t); +#ifdef CONFIG_VIRT_CPU_ACCOUNTING +static inline void account_process_tick(struct task_struct *tsk, int user) +{ + vtime_account_user(tsk); +} +#else extern void account_process_tick(struct task_struct *, int user); +#endif + extern void account_steal_ticks(unsigned long ticks); extern void account_idle_ticks(unsigned long ticks); diff --git a/include/linux/vtime.h b/include/linux/vtime.h index 5ad13c325de..ae30ab58431 100644 --- a/include/linux/vtime.h +++ b/include/linux/vtime.h @@ -8,6 +8,7 @@ extern void vtime_task_switch(struct task_struct *prev); extern void vtime_account_system(struct task_struct *tsk); extern void vtime_account_system_irqsafe(struct task_struct *tsk); extern void vtime_account_idle(struct task_struct *tsk); +extern void vtime_account_user(struct task_struct *tsk); extern void vtime_account(struct task_struct *tsk); #else static inline void vtime_task_switch(struct task_struct *prev) { } -- cgit v1.2.3 From e3942ba04052364d3c6454103362cafd87456010 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 14 Nov 2012 00:24:25 +0100 Subject: vtime: Consolidate a bit the ctx switch code On ia64 and powerpc, vtime context switch only consists in flushing system and user pending time, plus a few arch housekeeping. Consolidate that into a generic implementation. s390 is a special case because pending user and system time accounting there is hard to dissociate. So it's keeping its own implementation. Signed-off-by: Frederic Weisbecker Reviewed-by: Steven Rostedt Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Steven Rostedt Cc: Paul Gortmaker Cc: Tony Luck Cc: Fenghua Yu Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Martin Schwidefsky Cc: Heiko Carstens --- arch/ia64/include/asm/cputime.h | 2 ++ arch/ia64/kernel/time.c | 9 +-------- arch/powerpc/include/asm/cputime.h | 2 ++ arch/powerpc/kernel/time.c | 6 ------ arch/s390/include/asm/cputime.h | 1 + kernel/sched/cputime.c | 13 +++++++++++++ 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/arch/ia64/include/asm/cputime.h b/arch/ia64/include/asm/cputime.h index 3deac956d32..7fcf7f08ab0 100644 --- a/arch/ia64/include/asm/cputime.h +++ b/arch/ia64/include/asm/cputime.h @@ -103,5 +103,7 @@ static inline void cputime_to_timeval(const cputime_t ct, struct timeval *val) #define cputime64_to_clock_t(__ct) \ cputime_to_clock_t((__force cputime_t)__ct) +extern void arch_vtime_task_switch(struct task_struct *tsk); + #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ #endif /* __IA64_CPUTIME_H */ diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 834c78bd3b5..c9a7d2ebe08 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -100,18 +100,11 @@ void vtime_account_user(struct task_struct *tsk) * accumulated times to the current process, and to prepare accounting on * the next process. */ -void vtime_task_switch(struct task_struct *prev) +void arch_vtime_task_switch(struct task_struct *prev) { struct thread_info *pi = task_thread_info(prev); struct thread_info *ni = task_thread_info(current); - if (idle_task(smp_processor_id()) != prev) - vtime_account_system(prev); - else - vtime_account_idle(prev); - - vtime_account_user(prev); - pi->ac_stamp = ni->ac_stamp; ni->ac_stime = ni->ac_utime = 0; } diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h index 487d46ff68a..483733bd06d 100644 --- a/arch/powerpc/include/asm/cputime.h +++ b/arch/powerpc/include/asm/cputime.h @@ -228,6 +228,8 @@ static inline cputime_t clock_t_to_cputime(const unsigned long clk) #define cputime64_to_clock_t(ct) cputime_to_clock_t((cputime_t)(ct)) +static inline void arch_vtime_task_switch(struct task_struct *tsk) { } + #endif /* __KERNEL__ */ #endif /* CONFIG_VIRT_CPU_ACCOUNTING */ #endif /* __POWERPC_CPUTIME_H */ diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index a667aaf8584..3486cfad4a6 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -375,12 +375,6 @@ void vtime_account_user(struct task_struct *tsk) account_user_time(tsk, utime, utimescaled); } -void vtime_task_switch(struct task_struct *prev) -{ - vtime_account(prev); - vtime_account_user(prev); -} - #else /* ! CONFIG_VIRT_CPU_ACCOUNTING */ #define calc_cputime_factors() #endif diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h index 023d5ae2448..d2ff41370c0 100644 --- a/arch/s390/include/asm/cputime.h +++ b/arch/s390/include/asm/cputime.h @@ -14,6 +14,7 @@ #define __ARCH_HAS_VTIME_ACCOUNT +#define __ARCH_HAS_VTIME_TASK_SWITCH /* We want to use full resolution of the CPU timer: 2**-12 micro-seconds. */ diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index c0aa1ba752e..2e8d34aac97 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -443,6 +443,19 @@ void vtime_account_system_irqsafe(struct task_struct *tsk) } EXPORT_SYMBOL_GPL(vtime_account_system_irqsafe); +#ifndef __ARCH_HAS_VTIME_TASK_SWITCH +void vtime_task_switch(struct task_struct *prev) +{ + if (is_idle_task(prev)) + vtime_account_idle(prev); + else + vtime_account_system(prev); + + vtime_account_user(prev); + arch_vtime_task_switch(prev); +} +#endif + /* * Archs that account the whole time spent in the idle task * (outside irq) as idle time can rely on this and just implement -- cgit v1.2.3 From 1017769bd0073f0a73e066377cd79a10cf0a33ab Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 14 Nov 2012 00:26:54 +0100 Subject: vtime: No need to disable irqs on vtime_account() vtime_account() is only called from irq entry. irqs are always disabled at this point so we can safely remove the irq disabling guards on that function. Signed-off-by: Frederic Weisbecker Reviewed-by: Steven Rostedt Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Steven Rostedt Cc: Paul Gortmaker Cc: Tony Luck Cc: Fenghua Yu Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Martin Schwidefsky Cc: Heiko Carstens --- kernel/sched/cputime.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 2e8d34aac97..80b2fd5a7cf 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -467,16 +467,10 @@ void vtime_task_switch(struct task_struct *prev) #ifndef __ARCH_HAS_VTIME_ACCOUNT void vtime_account(struct task_struct *tsk) { - unsigned long flags; - - local_irq_save(flags); - if (in_interrupt() || !is_idle_task(tsk)) vtime_account_system(tsk); else vtime_account_idle(tsk); - - local_irq_restore(flags); } EXPORT_SYMBOL_GPL(vtime_account); #endif /* __ARCH_HAS_VTIME_ACCOUNT */ -- cgit v1.2.3 From 23e3b24f8f8e74efbd2fb4426692dffb29190d46 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Mon, 19 Nov 2012 12:19:53 +0100 Subject: ARM: at91: add clocks for DT entries Add clocks to clock lookup table for DT entries. Signed-off-by: Ludovic Desroches Acked-by: Arnd Bergmann Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/mach-at91/at91sam9260.c | 1 + arch/arm/mach-at91/at91sam9263.c | 2 ++ arch/arm/mach-at91/at91sam9g45.c | 2 ++ arch/arm/mach-at91/at91sam9n12.c | 1 + arch/arm/mach-at91/at91sam9x5.c | 2 ++ 5 files changed, 8 insertions(+) diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index 7aaa62cef4a..c9e029e44d8 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c @@ -230,6 +230,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t1_clk", "fffdc000.timer", &tc4_clk), CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk), CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &ohci_clk), + CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", &mmc_clk), /* fake hclk clock */ CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), CLKDEV_CON_ID("pioA", &pioA_clk), diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c index 448fce1ada1..ed390f6fa23 100644 --- a/arch/arm/mach-at91/at91sam9263.c +++ b/arch/arm/mach-at91/at91sam9263.c @@ -211,6 +211,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("hclk", "a00000.ohci", &ohci_clk), CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk), CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk), + CLKDEV_CON_DEV_ID("mci_clk", "fff80000.mmc", &mmc0_clk), + CLKDEV_CON_DEV_ID("mci_clk", "fff84000.mmc", &mmc1_clk), CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi_clk), CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk), CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioB_clk), diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index e6dd371d9f5..c5c2acc4bf2 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c @@ -256,6 +256,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk), CLKDEV_CON_DEV_ID("hclk", "700000.ohci", &uhphs_clk), CLKDEV_CON_DEV_ID("ehci_clk", "800000.ehci", &uhphs_clk), + CLKDEV_CON_DEV_ID("mci_clk", "fff80000.mmc", &mmc0_clk), + CLKDEV_CON_DEV_ID("mci_clk", "fffd0000.mmc", &mmc1_clk), CLKDEV_CON_DEV_ID(NULL, "fff84000.i2c", &twi0_clk), CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk), /* fake hclk clock */ diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c index bf8a083a02a..70b3a99244a 100644 --- a/arch/arm/mach-at91/at91sam9n12.c +++ b/arch/arm/mach-at91/at91sam9n12.c @@ -168,6 +168,7 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb_clk), CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb_clk), + CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc_clk), CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma_clk), CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index 56d13a4950a..3c729f0e2d3 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c @@ -229,6 +229,8 @@ static struct clk_lookup periph_clocks_lookups[] = { CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk), CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), + CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc0_clk), + CLKDEV_CON_DEV_ID("mci_clk", "f000c000.mmc", &mmc1_clk), CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk), CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk), CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), -- cgit v1.2.3 From 9873137a7a222fa923257b08d1915fef8df10a93 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Mon, 19 Nov 2012 12:23:36 +0100 Subject: ARM: at91/dts: add nodes for atmel hsmci controllers for atmel SOCs Add mci controller nodes to atmel SOCs. Signed-off-by: Ludovic Desroches Acked-by: Arnd Bergmann Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9260.dtsi | 9 +++++++++ arch/arm/boot/dts/at91sam9263.dtsi | 18 ++++++++++++++++++ arch/arm/boot/dts/at91sam9g45.dtsi | 18 ++++++++++++++++++ arch/arm/boot/dts/at91sam9n12.dtsi | 9 +++++++++ arch/arm/boot/dts/at91sam9x5.dtsi | 18 ++++++++++++++++++ 5 files changed, 72 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index a5d94606e15..d7296d55174 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -403,6 +403,15 @@ status = "disabled"; }; + mmc0: mmc@fffa8000 { + compatible = "atmel,hsmci"; + reg = <0xfffa8000 0x600>; + interrupts = <9 4 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + adc0: adc@fffe0000 { compatible = "atmel,at91sam9260-adc"; reg = <0xfffe0000 0x100>; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index a14aa3d1f01..eae6d167861 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -320,6 +320,24 @@ #size-cells = <0>; status = "disabled"; }; + + mmc0: mmc@fff80000 { + compatible = "atmel,hsmci"; + reg = <0xfff80000 0x600>; + interrupts = <10 4 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + mmc1: mmc@fff84000 { + compatible = "atmel,hsmci"; + reg = <0xfff84000 0x600>; + interrupts = <11 4 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index dc9a4ee28bc..91607d2ea2d 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -407,6 +407,24 @@ trigger-value = <0x6>; }; }; + + mmc0: mmc@fff80000 { + compatible = "atmel,hsmci"; + reg = <0xfff80000 0x600>; + interrupts = <11 4 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + mmc1: mmc@fffd0000 { + compatible = "atmel,hsmci"; + reg = <0xfffd0000 0x600>; + interrupts = <29 4 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 1667937bb2e..8d1fdfad2a9 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -84,6 +84,15 @@ reg = <0xfffffe10 0x10>; }; + mmc0: mmc@f0008000 { + compatible = "atmel,hsmci"; + reg = <0xf0008000 0x600>; + interrupts = <12 4 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + tcb0: timer@f8008000 { compatible = "atmel,at91sam9x5-tcb"; reg = <0xf8008000 0x100>; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 3642ab1eeaf..7f56b07438a 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -293,6 +293,24 @@ }; }; + mmc0: mmc@f0008000 { + compatible = "atmel,hsmci"; + reg = <0xf0008000 0x600>; + interrupts = <12 4 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + mmc1: mmc@f000c000 { + compatible = "atmel,hsmci"; + reg = <0xf000c000 0x600>; + interrupts = <26 4 0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + dbgu: serial@fffff200 { compatible = "atmel,at91sam9260-usart"; reg = <0xfffff200 0x200>; -- cgit v1.2.3 From 4134a4552748dd31b6e410a79e6c09be6e876b73 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Mon, 19 Nov 2012 12:24:02 +0100 Subject: ARM: at91/dts: add nodes for atmel hsmci controllers for atmel boards Add mci controller nodes to atmel boards. Signed-off-by: Ludovic Desroches Acked-by: Arnd Bergmann Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9263ek.dts | 10 ++++++++++ arch/arm/boot/dts/at91sam9g20ek_2mmc.dts | 12 ++++++++++++ arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 9 +++++++++ arch/arm/boot/dts/at91sam9m10g45ek.dts | 19 +++++++++++++++++++ arch/arm/boot/dts/at91sam9n12ek.dts | 9 +++++++++ arch/arm/boot/dts/at91sam9x5ek.dtsi | 18 ++++++++++++++++++ 6 files changed, 77 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts index e6a57a37156..8e319bbd7ae 100644 --- a/arch/arm/boot/dts/at91sam9263ek.dts +++ b/arch/arm/boot/dts/at91sam9263ek.dts @@ -54,6 +54,16 @@ atmel,vbus-gpio = <&pioA 25 0>; status = "okay"; }; + + mmc0: mmc@fff80000 { + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioE 18 0>; + wp-gpios = <&pioE 19 0>; + }; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts b/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts index f1b2e148ac8..684b22982f8 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts +++ b/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts @@ -12,6 +12,18 @@ model = "Atmel at91sam9g20ek 2 mmc"; compatible = "atmel,at91sam9g20ek_2mmc", "atmel,at91sam9g20", "atmel,at91sam9"; + ahb { + apb{ + mmc0: mmc@fffa8000 { + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioC 2 0>; + }; + }; + }; + }; + leds { compatible = "gpio-leds"; diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index 63a0e5ddd0a..0090015a7d5 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -58,6 +58,15 @@ atmel,vbus-gpio = <&pioC 5 0>; status = "okay"; }; + + mmc0: mmc@fffa8000 { + status = "okay"; + slot@1 { + reg = <1>; + bus-width = <4>; + cd-gpios = <&pioC 9 0>; + }; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index afd586720b1..1fc299fe66b 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -58,6 +58,25 @@ i2c1: i2c@fff88000 { status = "okay"; }; + + mmc0: mmc@fff80000 { + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioD 10 0>; + }; + }; + + mmc1: mmc@fffd0000 { + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioD 11 0>; + wp-gpios = <&pioD 29 0>; + }; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts index 912b2c283d6..3d165bc919f 100644 --- a/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/arch/arm/boot/dts/at91sam9n12ek.dts @@ -45,6 +45,15 @@ i2c1: i2c@f8014000 { status = "okay"; }; + + mmc0: mmc@f0008000 { + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioA 7 0>; + }; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi index cc9730c6018..e042b5eaf68 100644 --- a/arch/arm/boot/dts/at91sam9x5ek.dtsi +++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi @@ -18,6 +18,24 @@ ahb { apb { + mmc0: mmc@f0008000 { + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioD 15 0>; + }; + }; + + mmc1: mmc@f000c000 { + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioD 14 0>; + }; + }; + dbgu: serial@fffff200 { status = "okay"; }; -- cgit v1.2.3 From d4fe9ac76d43a2ce5472e0ed19c8e1e29dea0688 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 16 Nov 2012 08:24:17 +0800 Subject: ARM: at91: dt: at91sam9: add mmc pinctrl support Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9260.dtsi | 33 +++++++++++++++++++ arch/arm/boot/dts/at91sam9263.dtsi | 66 ++++++++++++++++++++++++++++++++++++++ arch/arm/boot/dts/at91sam9g45.dtsi | 48 +++++++++++++++++++++++++++ arch/arm/boot/dts/at91sam9n12.dtsi | 24 ++++++++++++++ arch/arm/boot/dts/at91sam9x5.dtsi | 32 ++++++++++++++++++ 5 files changed, 203 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index d7296d55174..b1d3fab60e0 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -272,6 +272,39 @@ }; }; + mmc0 { + pinctrl_mmc0_clk: mmc0_clk-0 { + atmel,pins = + <0 8 0x1 0x0>; /* PA8 periph A */ + }; + + pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 { + atmel,pins = + <0 7 0x1 0x1 /* PA7 periph A with pullup */ + 0 6 0x1 0x1>; /* PA6 periph A with pullup */ + }; + + pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 { + atmel,pins = + <0 9 0x1 0x1 /* PA9 periph A with pullup */ + 0 10 0x1 0x1 /* PA10 periph A with pullup */ + 0 11 0x1 0x1>; /* PA11 periph A with pullup */ + }; + + pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 { + atmel,pins = + <0 1 0x2 0x1 /* PA1 periph B with pullup */ + 0 0 0x2 0x1>; /* PA0 periph B with pullup */ + }; + + pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 { + atmel,pins = + <0 5 0x2 0x1 /* PA5 periph B with pullup */ + 0 4 0x2 0x1 /* PA4 periph B with pullup */ + 0 3 0x2 0x1>; /* PA3 periph B with pullup */ + }; + }; + pioA: gpio@fffff400 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>; diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index eae6d167861..66106eecf1e 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -203,6 +203,72 @@ }; }; + mmc0 { + pinctrl_mmc0_clk: mmc0_clk-0 { + atmel,pins = + <0 12 0x1 0x0>; /* PA12 periph A */ + }; + + pinctrl_mmc0_slot0_cmd_dat0: mmc0_slot0_cmd_dat0-0 { + atmel,pins = + <0 1 0x1 0x1 /* PA1 periph A with pullup */ + 0 0 0x1 0x1>; /* PA0 periph A with pullup */ + }; + + pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 { + atmel,pins = + <0 3 0x1 0x1 /* PA3 periph A with pullup */ + 0 4 0x1 0x1 /* PA4 periph A with pullup */ + 0 5 0x1 0x1>; /* PA5 periph A with pullup */ + }; + + pinctrl_mmc0_slot1_cmd_dat0: mmc0_slot1_cmd_dat0-0 { + atmel,pins = + <0 16 0x1 0x1 /* PA16 periph A with pullup */ + 0 17 0x1 0x1>; /* PA17 periph A with pullup */ + }; + + pinctrl_mmc0_slot1_dat1_3: mmc0_slot1_dat1_3-0 { + atmel,pins = + <0 18 0x1 0x1 /* PA18 periph A with pullup */ + 0 19 0x1 0x1 /* PA19 periph A with pullup */ + 0 20 0x1 0x1>; /* PA20 periph A with pullup */ + }; + }; + + mmc1 { + pinctrl_mmc1_clk: mmc1_clk-0 { + atmel,pins = + <0 6 0x1 0x0>; /* PA6 periph A */ + }; + + pinctrl_mmc1_slot0_cmd_dat0: mmc1_slot0_cmd_dat0-0 { + atmel,pins = + <0 7 0x1 0x1 /* PA7 periph A with pullup */ + 0 8 0x1 0x1>; /* PA8 periph A with pullup */ + }; + + pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 { + atmel,pins = + <0 9 0x1 0x1 /* PA9 periph A with pullup */ + 0 10 0x1 0x1 /* PA10 periph A with pullup */ + 0 11 0x1 0x1>; /* PA11 periph A with pullup */ + }; + + pinctrl_mmc1_slot1_cmd_dat0: mmc1_slot1_cmd_dat0-0 { + atmel,pins = + <0 21 0x1 0x1 /* PA21 periph A with pullup */ + 0 22 0x1 0x1>; /* PA22 periph A with pullup */ + }; + + pinctrl_mmc1_slot1_dat1_3: mmc1_slot1_dat1_3-0 { + atmel,pins = + <0 23 0x1 0x1 /* PA23 periph A with pullup */ + 0 24 0x1 0x1 /* PA24 periph A with pullup */ + 0 25 0x1 0x1>; /* PA25 periph A with pullup */ + }; + }; + pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff200 0x200>; diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 91607d2ea2d..0741caeeced 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -240,6 +240,54 @@ }; }; + mmc0 { + pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 { + atmel,pins = + <0 0 0x1 0x0 /* PA0 periph A */ + 0 1 0x1 0x1 /* PA1 periph A with pullup */ + 0 2 0x1 0x1>; /* PA2 periph A with pullup */ + }; + + pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 { + atmel,pins = + <0 3 0x1 0x1 /* PA3 periph A with pullup */ + 0 4 0x1 0x1 /* PA4 periph A with pullup */ + 0 5 0x1 0x1>; /* PA5 periph A with pullup */ + }; + + pinctrl_mmc0_slot0_dat4_7: mmc0_slot0_dat4_7-0 { + atmel,pins = + <0 6 0x1 0x1 /* PA6 periph A with pullup */ + 0 7 0x1 0x1 /* PA7 periph A with pullup */ + 0 8 0x1 0x1 /* PA8 periph A with pullup */ + 0 9 0x1 0x1>; /* PA9 periph A with pullup */ + }; + }; + + mmc1 { + pinctrl_mmc1_slot0_clk_cmd_dat0: mmc1_slot0_clk_cmd_dat0-0 { + atmel,pins = + <0 31 0x1 0x0 /* PA31 periph A */ + 0 22 0x1 0x1 /* PA22 periph A with pullup */ + 0 23 0x1 0x1>; /* PA23 periph A with pullup */ + }; + + pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 { + atmel,pins = + <0 24 0x1 0x1 /* PA24 periph A with pullup */ + 0 25 0x1 0x1 /* PA25 periph A with pullup */ + 0 26 0x1 0x1>; /* PA26 periph A with pullup */ + }; + + pinctrl_mmc1_slot0_dat4_7: mmc1_slot0_dat4_7-0 { + atmel,pins = + <0 27 0x1 0x1 /* PA27 periph A with pullup */ + 0 28 0x1 0x1 /* PA28 periph A with pullup */ + 0 29 0x1 0x1 /* PA29 periph A with pullup */ + 0 20 0x1 0x1>; /* PA30 periph A with pullup */ + }; + }; + pioA: gpio@fffff200 { compatible = "atmel,at91rm9200-gpio"; reg = <0xfffff200 0x200>; diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 8d1fdfad2a9..e9efb34f437 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -220,6 +220,30 @@ }; }; + mmc0 { + pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 { + atmel,pins = + <0 17 0x1 0x0 /* PA17 periph A */ + 0 16 0x1 0x1 /* PA16 periph A with pullup */ + 0 15 0x1 0x1>; /* PA15 periph A with pullup */ + }; + + pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 { + atmel,pins = + <0 18 0x1 0x1 /* PA18 periph A with pullup */ + 0 19 0x1 0x1 /* PA19 periph A with pullup */ + 0 20 0x1 0x1>; /* PA20 periph A with pullup */ + }; + + pinctrl_mmc0_slot0_dat4_7: mmc0_slot0_dat4_7-0 { + atmel,pins = + <0 11 0x2 0x1 /* PA11 periph B with pullup */ + 0 12 0x2 0x1 /* PA12 periph B with pullup */ + 0 13 0x2 0x1 /* PA13 periph B with pullup */ + 0 14 0x2 0x1>; /* PA14 periph B with pullup */ + }; + }; + pioA: gpio@fffff400 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 7f56b07438a..7ee49e8daf9 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -250,6 +250,38 @@ }; }; + mmc0 { + pinctrl_mmc0_slot0_clk_cmd_dat0: mmc0_slot0_clk_cmd_dat0-0 { + atmel,pins = + <0 17 0x1 0x0 /* PA17 periph A */ + 0 16 0x1 0x1 /* PA16 periph A with pullup */ + 0 15 0x1 0x1>; /* PA15 periph A with pullup */ + }; + + pinctrl_mmc0_slot0_dat1_3: mmc0_slot0_dat1_3-0 { + atmel,pins = + <0 18 0x1 0x1 /* PA18 periph A with pullup */ + 0 19 0x1 0x1 /* PA19 periph A with pullup */ + 0 20 0x1 0x1>; /* PA20 periph A with pullup */ + }; + }; + + mmc1 { + pinctrl_mmc1_slot0_clk_cmd_dat0: mmc1_slot0_clk_cmd_dat0-0 { + atmel,pins = + <0 13 0x2 0x0 /* PA13 periph B */ + 0 12 0x2 0x1 /* PA12 periph B with pullup */ + 0 11 0x2 0x1>; /* PA11 periph B with pullup */ + }; + + pinctrl_mmc1_slot0_dat1_3: mmc1_slot0_dat1_3-0 { + atmel,pins = + <0 2 0x2 0x1 /* PA2 periph B with pullup */ + 0 3 0x2 0x1 /* PA3 periph B with pullup */ + 0 4 0x2 0x1>; /* PA4 periph B with pullup */ + }; + }; + pioA: gpio@fffff400 { compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; reg = <0xfffff400 0x200>; -- cgit v1.2.3 From 199e2edec49b8a24f67afdae61e57cfa6d68bfca Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 20 Nov 2012 00:38:18 +0800 Subject: ARM: at91: dt: add mmc pinctrl for Atmel reference boards Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/at91sam9263ek.dts | 15 +++++++++++++++ arch/arm/boot/dts/at91sam9g20ek_2mmc.dts | 14 ++++++++++++++ arch/arm/boot/dts/at91sam9g20ek_common.dtsi | 14 ++++++++++++++ arch/arm/boot/dts/at91sam9m10g45ek.dts | 25 +++++++++++++++++++++++++ arch/arm/boot/dts/at91sam9n12ek.dts | 13 +++++++++++++ arch/arm/boot/dts/at91sam9x5ek.dtsi | 24 ++++++++++++++++++++++++ 6 files changed, 105 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts index 8e319bbd7ae..1eb08728f52 100644 --- a/arch/arm/boot/dts/at91sam9263ek.dts +++ b/arch/arm/boot/dts/at91sam9263ek.dts @@ -56,6 +56,11 @@ }; mmc0: mmc@fff80000 { + pinctrl-0 = < + &pinctrl_board_mmc0 + &pinctrl_mmc0_clk + &pinctrl_mmc0_slot0_cmd_dat0 + &pinctrl_mmc0_slot0_dat1_3>; status = "okay"; slot@0 { reg = <0>; @@ -64,6 +69,16 @@ wp-gpios = <&pioE 19 0>; }; }; + + pinctrl@fffff200 { + mmc0 { + pinctrl_board_mmc0: mmc0-board { + atmel,pins = + <5 18 0x0 0x5 /* PE18 gpio CD pin pull up and deglitch */ + 5 19 0x0 0x1>; /* PE19 gpio WP pin pull up */ + }; + }; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts b/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts index 684b22982f8..66467b11312 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts +++ b/arch/arm/boot/dts/at91sam9g20ek_2mmc.dts @@ -15,12 +15,26 @@ ahb { apb{ mmc0: mmc@fffa8000 { + /* clk already mux wuth slot0 */ + pinctrl-0 = < + &pinctrl_board_mmc0_slot0 + &pinctrl_mmc0_slot0_cmd_dat0 + &pinctrl_mmc0_slot0_dat1_3>; slot@0 { reg = <0>; bus-width = <4>; cd-gpios = <&pioC 2 0>; }; }; + + pinctrl@fffff400 { + mmc0_slot0 { + pinctrl_board_mmc0_slot0: mmc0_slot0-board { + atmel,pins = + <2 2 0x0 0x5>; /* PC2 gpio CD pin pull up and deglitch */ + }; + }; + }; }; }; diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index 0090015a7d5..32a500a0e48 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -60,6 +60,11 @@ }; mmc0: mmc@fffa8000 { + pinctrl-0 = < + &pinctrl_board_mmc0_slot1 + &pinctrl_mmc0_clk + &pinctrl_mmc0_slot1_cmd_dat0 + &pinctrl_mmc0_slot1_dat1_3>; status = "okay"; slot@1 { reg = <1>; @@ -67,6 +72,15 @@ cd-gpios = <&pioC 9 0>; }; }; + + pinctrl@fffff400 { + mmc0_slot1 { + pinctrl_board_mmc0_slot1: mmc0_slot1-board { + atmel,pins = + <2 9 0x0 0x5>; /* PC9 gpio CD pin pull up and deglitch */ + }; + }; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index 1fc299fe66b..20c31913c27 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts @@ -60,6 +60,10 @@ }; mmc0: mmc@fff80000 { + pinctrl-0 = < + &pinctrl_board_mmc0 + &pinctrl_mmc0_slot0_clk_cmd_dat0 + &pinctrl_mmc0_slot0_dat1_3>; status = "okay"; slot@0 { reg = <0>; @@ -69,6 +73,10 @@ }; mmc1: mmc@fffd0000 { + pinctrl-0 = < + &pinctrl_board_mmc1 + &pinctrl_mmc1_slot0_clk_cmd_dat0 + &pinctrl_mmc1_slot0_dat1_3>; status = "okay"; slot@0 { reg = <0>; @@ -77,6 +85,23 @@ wp-gpios = <&pioD 29 0>; }; }; + + pinctrl@fffff200 { + mmc0 { + pinctrl_board_mmc0: mmc0-board { + atmel,pins = + <3 10 0x0 0x5>; /* PD10 gpio CD pin pull up and deglitch */ + }; + }; + + mmc1 { + pinctrl_board_mmc1: mmc1-board { + atmel,pins = + <3 11 0x0 0x5 /* PD11 gpio CD pin pull up and deglitch */ + 3 29 0x0 0x1>; /* PD29 gpio WP pin pull up */ + }; + }; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts index 3d165bc919f..0376bf4fd66 100644 --- a/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/arch/arm/boot/dts/at91sam9n12ek.dts @@ -47,6 +47,10 @@ }; mmc0: mmc@f0008000 { + pinctrl-0 = < + &pinctrl_board_mmc0 + &pinctrl_mmc0_slot0_clk_cmd_dat0 + &pinctrl_mmc0_slot0_dat1_3>; status = "okay"; slot@0 { reg = <0>; @@ -54,6 +58,15 @@ cd-gpios = <&pioA 7 0>; }; }; + + pinctrl@fffff400 { + mmc0 { + pinctrl_board_mmc0: mmc0-board { + atmel,pins = + <0 7 0x0 0x5>; /* PA7 gpio CD pin pull up and deglitch */ + }; + }; + }; }; nand0: nand@40000000 { diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi index e042b5eaf68..8a7cf1d9cf5 100644 --- a/arch/arm/boot/dts/at91sam9x5ek.dtsi +++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi @@ -19,6 +19,10 @@ ahb { apb { mmc0: mmc@f0008000 { + pinctrl-0 = < + &pinctrl_board_mmc0 + &pinctrl_mmc0_slot0_clk_cmd_dat0 + &pinctrl_mmc0_slot0_dat1_3>; status = "okay"; slot@0 { reg = <0>; @@ -28,6 +32,10 @@ }; mmc1: mmc@f000c000 { + pinctrl-0 = < + &pinctrl_board_mmc1 + &pinctrl_mmc1_slot0_clk_cmd_dat0 + &pinctrl_mmc1_slot0_dat1_3>; status = "okay"; slot@0 { reg = <0>; @@ -60,6 +68,22 @@ i2c2: i2c@f8018000 { status = "okay"; }; + + pinctrl@fffff400 { + mmc0 { + pinctrl_board_mmc0: mmc0-board { + atmel,pins = + <3 15 0x0 0x5>; /* PD15 gpio CD pin pull up and deglitch */ + }; + }; + + mmc1 { + pinctrl_board_mmc1: mmc1-board { + atmel,pins = + <3 14 0x0 0x5>; /* PD14 gpio CD pin pull up and deglitch */ + }; + }; + }; }; usb0: ohci@00600000 { -- cgit v1.2.3 From 301333bc6c78051b257e520ad0f5cf0b6596c4f4 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 15 Nov 2012 21:56:27 +0800 Subject: ARM: at91: Animeo IP: add mmc support Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/animeo_ip.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/animeo_ip.dts b/arch/arm/boot/dts/animeo_ip.dts index 518baedaae0..74d92cd29d8 100644 --- a/arch/arm/boot/dts/animeo_ip.dts +++ b/arch/arm/boot/dts/animeo_ip.dts @@ -66,6 +66,18 @@ phy-mode = "mii"; status = "okay"; }; + + mmc0: mmc@fffa8000 { + pinctrl-0 = <&pinctrl_mmc0_clk + &pinctrl_mmc0_slot1_cmd_dat0 + &pinctrl_mmc0_slot1_dat1_3>; + status = "okay"; + + slot@1 { + reg = <1>; + bus-width = <4>; + }; + }; }; nand0: nand@40000000 { -- cgit v1.2.3 From c12a819e3ad9147acec3f20201fd51144f2244e9 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 20 Nov 2012 00:46:24 +0800 Subject: ARM: at91: pm9g45: add mmc support Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- arch/arm/boot/dts/pm9g45.dts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/arm/boot/dts/pm9g45.dts b/arch/arm/boot/dts/pm9g45.dts index b0c258dd19e..387fedb5898 100644 --- a/arch/arm/boot/dts/pm9g45.dts +++ b/arch/arm/boot/dts/pm9g45.dts @@ -46,12 +46,33 @@ 2 14 0x0 0x1>; /* PC14 gpio enable pin pull_up */ }; }; + + mmc { + pinctrl_board_mmc: mmc0-board { + atmel,pins = + <3 6 0x0 0x5>; /* PD6 gpio CD pin pull_up and deglitch */ + }; + }; + }; + + mmc0: mmc@fff80000 { + pinctrl-0 = < + &pinctrl_board_mmc + &pinctrl_mmc0_slot0_clk_cmd_dat0 + &pinctrl_mmc0_slot0_dat1_3>; + status = "okay"; + slot@0 { + reg = <0>; + bus-width = <4>; + cd-gpios = <&pioD 6 0>; + }; }; macb0: ethernet@fffbc000 { phy-mode = "rmii"; status = "okay"; }; + }; nand0: nand@40000000 { -- cgit v1.2.3 From 2ea3c6a2c779e5a6487d2b436770232162dfbbe3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 19 Nov 2012 20:03:37 +0100 Subject: ALSA: hda - Limit runtime PM support only to known Intel chips We've got a report that the runtime PM may make the codec the unresponsive on AMD platforms. Since the feature has been tested only on the recent Intel platforms, it's safer to limit the support to such devices for now. This patch adds a new DCAPS bit flag indicating the runtime PM support, and mark it for Intel controllers. Reported-and-tested-by: Julian Wollrath Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index cd2dbaf1be7..f9d870e554d 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -556,6 +556,12 @@ enum { #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ +#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ + +/* quirks for Intel PCH */ +#define AZX_DCAPS_INTEL_PCH \ + (AZX_DCAPS_SCH_SNOOP | AZX_DCAPS_BUFSIZE | \ + AZX_DCAPS_COUNT_LPIB_DELAY | AZX_DCAPS_PM_RUNTIME) /* quirks for ATI SB / AMD Hudson */ #define AZX_DCAPS_PRESET_ATI_SB \ @@ -2433,6 +2439,9 @@ static void azx_power_notify(struct hda_bus *bus, bool power_up) { struct azx *chip = bus->private_data; + if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) + return; + if (power_up) pm_runtime_get_sync(&chip->pci->dev); else @@ -2548,7 +2557,8 @@ static int azx_runtime_suspend(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; - if (!power_save_controller) + if (!power_save_controller || + !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) return -EAGAIN; azx_stop_chip(chip); @@ -3429,39 +3439,30 @@ static void __devexit azx_remove(struct pci_dev *pci) static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* CPT */ { PCI_DEVICE(0x8086, 0x1c20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* PBG */ { PCI_DEVICE(0x8086, 0x1d20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE}, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Panther Point */ { PCI_DEVICE(0x8086, 0x1e20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Lynx Point */ { PCI_DEVICE(0x8086, 0x8c20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Lynx Point-LP */ { PCI_DEVICE(0x8086, 0x9c20), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Lynx Point-LP */ { PCI_DEVICE(0x8086, 0x9c21), - .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, /* Haswell */ { PCI_DEVICE(0x8086, 0x0c0c), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, { PCI_DEVICE(0x8086, 0x0d0c), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, /* 5 Series/3400 */ { PCI_DEVICE(0x8086, 0x3b56), - .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY }, + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, /* SCH */ { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | -- cgit v1.2.3 From 3bb3e1fc47aca554e7e2cc4deeddc24750987ac2 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 13 Nov 2012 14:55:52 +0100 Subject: reiserfs: Fix lock ordering during remount When remounting reiserfs dquot_suspend() or dquot_resume() can be called. These functions take dqonoff_mutex which ranks above write lock so we have to drop it before calling into quota code. CC: stable@vger.kernel.org # >= 3.0 Signed-off-by: Jan Kara --- fs/reiserfs/super.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 1078ae17999..5372980ec45 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -1335,7 +1335,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) kfree(qf_names[i]); #endif err = -EINVAL; - goto out_err; + goto out_unlock; } #ifdef CONFIG_QUOTA handle_quota_files(s, qf_names, &qfmt); @@ -1379,7 +1379,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) if (blocks) { err = reiserfs_resize(s, blocks); if (err != 0) - goto out_err; + goto out_unlock; } if (*mount_flags & MS_RDONLY) { @@ -1389,9 +1389,15 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) /* it is read-only already */ goto out_ok; + /* + * Drop write lock. Quota will retake it when needed and lock + * ordering requires calling dquot_suspend() without it. + */ + reiserfs_write_unlock(s); err = dquot_suspend(s, -1); if (err < 0) goto out_err; + reiserfs_write_lock(s); /* try to remount file system with read-only permissions */ if (sb_umount_state(rs) == REISERFS_VALID_FS @@ -1401,7 +1407,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) err = journal_begin(&th, s, 10); if (err) - goto out_err; + goto out_unlock; /* Mounting a rw partition read-only. */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); @@ -1416,7 +1422,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) if (reiserfs_is_journal_aborted(journal)) { err = journal->j_errno; - goto out_err; + goto out_unlock; } handle_data_mode(s, mount_options); @@ -1425,7 +1431,7 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */ err = journal_begin(&th, s, 10); if (err) - goto out_err; + goto out_unlock; /* Mount a partition which is read-only, read-write */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); @@ -1442,10 +1448,16 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg) SB_JOURNAL(s)->j_must_wait = 1; err = journal_end(&th, s, 10); if (err) - goto out_err; + goto out_unlock; if (!(*mount_flags & MS_RDONLY)) { + /* + * Drop write lock. Quota will retake it when needed and lock + * ordering requires calling dquot_resume() without it. + */ + reiserfs_write_unlock(s); dquot_resume(s, -1); + reiserfs_write_lock(s); finish_unfinished(s); reiserfs_xattr_init(s, *mount_flags); } @@ -1455,9 +1467,10 @@ out_ok: reiserfs_write_unlock(s); return 0; +out_unlock: + reiserfs_write_unlock(s); out_err: kfree(new_opts); - reiserfs_write_unlock(s); return err; } -- cgit v1.2.3 From b9e06ef2e8706fe669b51f4364e3aeed58639eb2 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 13 Nov 2012 16:34:17 +0100 Subject: reiserfs: Protect reiserfs_quota_on() with write lock In reiserfs_quota_on() we do quite some work - for example unpacking tail of a quota file. Thus we have to hold write lock until a moment we call back into the quota code. CC: stable@vger.kernel.org # >= 3.0 Signed-off-by: Jan Kara --- fs/reiserfs/super.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 5372980ec45..e59d6ddcc69 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -2216,8 +2216,11 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, struct reiserfs_transaction_handle th; int opt = type == USRQUOTA ? REISERFS_USRQUOTA : REISERFS_GRPQUOTA; - if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt))) - return -EINVAL; + reiserfs_write_lock(sb); + if (!(REISERFS_SB(sb)->s_mount_opt & (1 << opt))) { + err = -EINVAL; + goto out; + } /* Quotafile not on the same filesystem? */ if (path->dentry->d_sb != sb) { @@ -2259,8 +2262,10 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, if (err) goto out; } - err = dquot_quota_on(sb, type, format_id, path); + reiserfs_write_unlock(sb); + return dquot_quota_on(sb, type, format_id, path); out: + reiserfs_write_unlock(sb); return err; } -- cgit v1.2.3 From 361d94a338a3fd0cee6a4ea32bbc427ba228e628 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 13 Nov 2012 18:25:38 +0100 Subject: reiserfs: Protect reiserfs_quota_write() with write lock Calls into reiserfs journalling code and reiserfs_get_block() need to be protected with write lock. We remove write lock around calls to high level quota code in the next patch so these paths would suddently become unprotected. CC: stable@vger.kernel.org # >= 3.0 Signed-off-by: Jan Kara --- fs/reiserfs/super.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index e59d6ddcc69..c101704ece4 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -2338,7 +2338,9 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type, tocopy = sb->s_blocksize - offset < towrite ? sb->s_blocksize - offset : towrite; tmp_bh.b_state = 0; + reiserfs_write_lock(sb); err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE); + reiserfs_write_unlock(sb); if (err) goto out; if (offset || tocopy != sb->s_blocksize) @@ -2354,10 +2356,12 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type, flush_dcache_page(bh->b_page); set_buffer_uptodate(bh); unlock_buffer(bh); + reiserfs_write_lock(sb); reiserfs_prepare_for_journal(sb, bh, 1); journal_mark_dirty(current->journal_info, sb, bh); if (!journal_quota) reiserfs_add_ordered_list(inode, bh); + reiserfs_write_unlock(sb); brelse(bh); offset = 0; towrite -= tocopy; -- cgit v1.2.3 From 7af11686933726e99af22901d622f9e161404e6b Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 13 Nov 2012 17:05:14 +0100 Subject: reiserfs: Move quota calls out of write lock Calls into highlevel quota code cannot happen under the write lock. These calls take dqio_mutex which ranks above write lock. So drop write lock before calling back into quota code. CC: stable@vger.kernel.org # >= 3.0 Signed-off-by: Jan Kara --- fs/reiserfs/inode.c | 10 +++++++--- fs/reiserfs/stree.c | 4 ++++ fs/reiserfs/super.c | 18 ++++++++++++++---- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index f27f01a98aa..d83736fbc26 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1782,8 +1782,9 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, BUG_ON(!th->t_trans_id); - dquot_initialize(inode); + reiserfs_write_unlock(inode->i_sb); err = dquot_alloc_inode(inode); + reiserfs_write_lock(inode->i_sb); if (err) goto out_end_trans; if (!dir->i_nlink) { @@ -1979,8 +1980,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, out_end_trans: journal_end(th, th->t_super, th->t_blocks_allocated); + reiserfs_write_unlock(inode->i_sb); /* Drop can be outside and it needs more credits so it's better to have it outside */ dquot_drop(inode); + reiserfs_write_lock(inode->i_sb); inode->i_flags |= S_NOQUOTA; make_bad_inode(inode); @@ -3103,10 +3106,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) /* must be turned off for recursive notify_change calls */ ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); - depth = reiserfs_write_lock_once(inode->i_sb); if (is_quota_modification(inode, attr)) dquot_initialize(inode); - + depth = reiserfs_write_lock_once(inode->i_sb); if (attr->ia_valid & ATTR_SIZE) { /* version 2 items will be caught by the s_maxbytes check ** done for us in vmtruncate @@ -3170,7 +3172,9 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) error = journal_begin(&th, inode->i_sb, jbegin_count); if (error) goto out; + reiserfs_write_unlock_once(inode->i_sb, depth); error = dquot_transfer(inode, attr); + depth = reiserfs_write_lock_once(inode->i_sb); if (error) { journal_end(&th, inode->i_sb, jbegin_count); goto out; diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index f8afa4b162b..2f40a4c70a4 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c @@ -1968,7 +1968,9 @@ int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct tree key2type(&(key->on_disk_key))); #endif + reiserfs_write_unlock(inode->i_sb); retval = dquot_alloc_space_nodirty(inode, pasted_size); + reiserfs_write_lock(inode->i_sb); if (retval) { pathrelse(search_path); return retval; @@ -2061,9 +2063,11 @@ int reiserfs_insert_item(struct reiserfs_transaction_handle *th, "reiserquota insert_item(): allocating %u id=%u type=%c", quota_bytes, inode->i_uid, head2type(ih)); #endif + reiserfs_write_unlock(inode->i_sb); /* We can't dirty inode here. It would be immediately written but * appropriate stat item isn't inserted yet... */ retval = dquot_alloc_space_nodirty(inode, quota_bytes); + reiserfs_write_lock(inode->i_sb); if (retval) { pathrelse(path); return retval; diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index c101704ece4..418bdc3a57d 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -298,7 +298,9 @@ static int finish_unfinished(struct super_block *s) retval = remove_save_link_only(s, &save_link_key, 0); continue; } + reiserfs_write_unlock(s); dquot_initialize(inode); + reiserfs_write_lock(s); if (truncate && S_ISDIR(inode->i_mode)) { /* We got a truncate request for a dir which is impossible. @@ -2108,13 +2110,15 @@ static int reiserfs_write_dquot(struct dquot *dquot) REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); if (ret) goto out; + reiserfs_write_unlock(dquot->dq_sb); ret = dquot_commit(dquot); + reiserfs_write_lock(dquot->dq_sb); err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); if (!ret && err) ret = err; - out: +out: reiserfs_write_unlock(dquot->dq_sb); return ret; } @@ -2130,13 +2134,15 @@ static int reiserfs_acquire_dquot(struct dquot *dquot) REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); if (ret) goto out; + reiserfs_write_unlock(dquot->dq_sb); ret = dquot_acquire(dquot); + reiserfs_write_lock(dquot->dq_sb); err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb)); if (!ret && err) ret = err; - out: +out: reiserfs_write_unlock(dquot->dq_sb); return ret; } @@ -2150,19 +2156,21 @@ static int reiserfs_release_dquot(struct dquot *dquot) ret = journal_begin(&th, dquot->dq_sb, REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); + reiserfs_write_unlock(dquot->dq_sb); if (ret) { /* Release dquot anyway to avoid endless cycle in dqput() */ dquot_release(dquot); goto out; } ret = dquot_release(dquot); + reiserfs_write_lock(dquot->dq_sb); err = journal_end(&th, dquot->dq_sb, REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb)); if (!ret && err) ret = err; - out: reiserfs_write_unlock(dquot->dq_sb); +out: return ret; } @@ -2187,11 +2195,13 @@ static int reiserfs_write_info(struct super_block *sb, int type) ret = journal_begin(&th, sb, 2); if (ret) goto out; + reiserfs_write_unlock(sb); ret = dquot_commit_info(sb, type); + reiserfs_write_lock(sb); err = journal_end(&th, sb, 2); if (!ret && err) ret = err; - out: +out: reiserfs_write_unlock(sb); return ret; } -- cgit v1.2.3 From ae49eeec785025373e28dc24c8351c6bba688d99 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Thu, 11 Oct 2012 12:28:38 +0200 Subject: ext3: Avoid underflow of in ext3_trim_fs() Currently if len argument in ext3_trim_fs() is smaller than one block, the 'end' variable underflow. Avoid that by returning EINVAL if len is smaller than file system block. Also remove useless unlikely(). Signed-off-by: Lukas Czerner Signed-off-by: Jan Kara --- fs/ext3/balloc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index 7320a66e958..22548f56197 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c @@ -2101,8 +2101,9 @@ int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range) end = start + (range->len >> sb->s_blocksize_bits) - 1; minlen = range->minlen >> sb->s_blocksize_bits; - if (unlikely(minlen > EXT3_BLOCKS_PER_GROUP(sb)) || - unlikely(start >= max_blks)) + if (minlen > EXT3_BLOCKS_PER_GROUP(sb) || + start >= max_blks || + range->len < sb->s_blocksize) return -EINVAL; if (end >= max_blks) end = max_blks - 1; -- cgit v1.2.3 From ca9dfc6cc45a8ae0297188f5fed23af242cc8a8d Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 5 Nov 2012 15:15:24 +0000 Subject: tools: Define a Makefile function to do subdir processing Define a Makefile function that can be called with $(call ...) to wrap the subdir make invocations in tools/Makefile. This will allow us in the next patch to insert bits in there to honour O= flags when called from the top-level Makefile. Signed-off-by: David Howells Cc: Borislav Petkov Cc: Ingo Molnar Cc: Linus Torvalds Cc: Namhyung Kim Cc: Paul Mackerras Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1378.1352379110@warthog.procyon.org.uk Signed-off-by: Arnaldo Carvalho de Melo --- tools/Makefile | 24 ++++++++++++------------ tools/scripts/Makefile.include | 8 ++++++++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/tools/Makefile b/tools/Makefile index 3ae43947a17..1f9a529fe54 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -31,44 +31,44 @@ help: @echo ' clean: a summary clean target to clean _all_ folders' cpupower: FORCE - $(QUIET_SUBDIR0)power/$@/ $(QUIET_SUBDIR1) + $(call descend,power/$@) firewire lguest perf usb virtio vm: FORCE - $(QUIET_SUBDIR0)$@/ $(QUIET_SUBDIR1) + $(call descend,$@) selftests: FORCE - $(QUIET_SUBDIR0)testing/$@/ $(QUIET_SUBDIR1) + $(call descend,testing/$@) turbostat x86_energy_perf_policy: FORCE - $(QUIET_SUBDIR0)power/x86/$@/ $(QUIET_SUBDIR1) + $(call descend,power/x86/$@) cpupower_install: - $(QUIET_SUBDIR0)power/$(@:_install=)/ $(QUIET_SUBDIR1) install + $(call descend,power/$(@:_install=),install) firewire_install lguest_install perf_install usb_install virtio_install vm_install: - $(QUIET_SUBDIR0)$(@:_install=)/ $(QUIET_SUBDIR1) install + $(call descend,$(@:_install=),install) selftests_install: - $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) install + $(call descend,testing/$(@:_clean=),install) turbostat_install x86_energy_perf_policy_install: - $(QUIET_SUBDIR0)power/x86/$(@:_install=)/ $(QUIET_SUBDIR1) install + $(call descend,power/x86/$(@:_install=),install) install: cpupower_install firewire_install lguest_install perf_install \ selftests_install turbostat_install usb_install virtio_install \ vm_install x86_energy_perf_policy_install cpupower_clean: - $(QUIET_SUBDIR0)power/cpupower/ $(QUIET_SUBDIR1) clean + $(call descend,power/cpupower,clean) firewire_clean lguest_clean perf_clean usb_clean virtio_clean vm_clean: - $(QUIET_SUBDIR0)$(@:_clean=)/ $(QUIET_SUBDIR1) clean + $(call descend,$(@:_clean=),clean) selftests_clean: - $(QUIET_SUBDIR0)testing/$(@:_clean=)/ $(QUIET_SUBDIR1) clean + $(call descend,testing/$(@:_clean=),clean) turbostat_clean x86_energy_perf_policy_clean: - $(QUIET_SUBDIR0)power/x86/$(@:_clean=)/ $(QUIET_SUBDIR1) clean + $(call descend,power/x86/$(@:_clean=),clean) clean: cpupower_clean firewire_clean lguest_clean perf_clean selftests_clean \ turbostat_clean usb_clean virtio_clean vm_clean \ diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include index 96ce80a3743..4a9e3176f74 100644 --- a/tools/scripts/Makefile.include +++ b/tools/scripts/Makefile.include @@ -41,6 +41,14 @@ else NO_SUBDIR = : endif +# +# Define a callable command for descending to a new directory +# +# Call by doing: $(call descend,directory[,target]) +# +descend = \ + $(QUIET_SUBDIR0)$(1) $(QUIET_SUBDIR1) $(2) + QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir QUIET_SUBDIR1 = -- cgit v1.2.3 From bf35182ffcd00d8b36d56210ffdac110e5624d7d Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 5 Nov 2012 21:02:08 +0000 Subject: tools: Honour the O= flag when tool build called from a higher Makefile Honour the O= flag that was passed to a higher level Makefile and then passed down as part of a tool build. To make this work, the top-level Makefile passes the original O= flag and subdir=tools to the tools/Makefile, and that in turn passes subdir=$(O)/$(subdir)/foodir when building tool foo in directory $(O)/$(subdir)/foodir (where the intervening slashes aren't added if an element is missing). For example, take perf. This is found in tools/perf/. Assume we're building into directory ~/zebra/, so we pass O=~/zebra to make. Dependening on where we run the build from, we see: make run in dir $(OUTPUT) dir ======================= ================== linux ~/zebra/tools/perf/ linux/tools ~/zebra/perf/ linux/tools/perf ~/zebra/ and if O= is not set, we get: make run in dir $(OUTPUT) dir ======================= ================== linux linux/tools/perf/ linux/tools linux/tools/perf/ linux/tools/perf linux/tools/perf/ The output directories are created by the descend function if they don't already exist. Signed-off-by: David Howells Cc: Borislav Petkov Cc: Ingo Molnar Cc: Linus Torvalds Cc: Namhyung Kim Cc: Paul Mackerras Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/1378.1352379110@warthog.procyon.org.uk Signed-off-by: Arnaldo Carvalho de Melo --- Makefile | 6 ++++-- tools/scripts/Makefile.include | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 42d0e56818e..71dc31e4140 100644 --- a/Makefile +++ b/Makefile @@ -1321,10 +1321,12 @@ kernelversion: # Clear a bunch of variables before executing the submake tools/: FORCE - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/ + $(Q)mkdir -p $(objtree)/tools + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/ tools/%: FORCE - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/ $* + $(Q)mkdir -p $(objtree)/tools + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/ $* # Single targets # --------------------------------------------------------------------------- diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include index 4a9e3176f74..87467b17e05 100644 --- a/tools/scripts/Makefile.include +++ b/tools/scripts/Makefile.include @@ -1,8 +1,11 @@ -ifeq ("$(origin O)", "command line") +ifeq ($(origin O), command line) dummy := $(if $(shell test -d $(O) || echo $(O)),$(error O=$(O) does not exist),) ABSOLUTE_O := $(shell cd $(O) ; pwd) - OUTPUT := $(ABSOLUTE_O)/ + OUTPUT := $(ABSOLUTE_O)/$(if $(subdir),$(subdir)/) COMMAND_O := O=$(ABSOLUTE_O) +ifeq ($(objtree),) + objtree := $(O) +endif endif ifneq ($(OUTPUT),) @@ -47,9 +50,10 @@ endif # Call by doing: $(call descend,directory[,target]) # descend = \ - $(QUIET_SUBDIR0)$(1) $(QUIET_SUBDIR1) $(2) + +mkdir -p $(OUTPUT)$(1) && \ + $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) -QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir +QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir QUIET_SUBDIR1 = ifneq ($(findstring $(MAKEFLAGS),s),s) @@ -64,5 +68,10 @@ ifndef V $(MAKE) $(PRINT_DIR) -C $$subdir QUIET_FLEX = @echo ' ' FLEX $@; QUIET_BISON = @echo ' ' BISON $@; + + descend = \ + @echo ' ' DESCEND $(1); \ + mkdir -p $(OUTPUT)$(1) && \ + $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) endif endif -- cgit v1.2.3 From 2b73f65d114b44b9bc9bd7d229f603e4cd5c1a88 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 13 Nov 2012 14:14:38 -0300 Subject: tools: Pass the target in descend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixing: [acme@sandy linux]$ cd tools [acme@sandy tools]$ make clean DESCEND power/cpupower CC lib/cpufreq.o CC lib/sysfs.o LD libcpupower.so.0.0.0 CC utils/helpers/amd.o utils/helpers/amd.c:7:21: error: pci/pci.h: No such file or directory In file included from utils/helpers/amd.c:9: ./utils/helpers/helpers.h:137: warning: ‘struct pci_access’ declared inside parameter list ./utils/helpers/helpers.h:137: warning: its scope is only this definition or declaration, which is probably not what you want ./utils/helpers/helpers.h:139: warning: ‘struct pci_access’ declared inside parameter list utils/helpers/amd.c: In function ‘amd_pci_get_num_boost_states’: utils/helpers/amd.c:120: warning: passing argument 1 of ‘pci_slot_func_init’ from incompatible pointer type ./utils/helpers/helpers.h:138: note: expected ‘struct pci_access **’ but argument is of type ‘struct pci_access **’ utils/helpers/amd.c:125: warning: implicit declaration of function ‘pci_read_byte’ utils/helpers/amd.c:132: warning: implicit declaration of function ‘pci_cleanup’ make[1]: *** [utils/helpers/amd.o] Error 1 make: *** [cpupower_clean] Error 2 [acme@sandy tools]$ Reported-by: Arnaldo Carvalho de Melo Signed-off-by: David Howells Cc: Borislav Petkov Cc: Ingo Molnar Cc: Linus Torvalds Cc: Namhyung Kim Cc: Paul Mackerras Cc: Thomas Gleixner Link: http://lkml.kernel.org/n/tip-tviyimq6x6nm77sj5lt4t19f@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/scripts/Makefile.include | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include index 87467b17e05..2964b96aa55 100644 --- a/tools/scripts/Makefile.include +++ b/tools/scripts/Makefile.include @@ -51,7 +51,7 @@ endif # descend = \ +mkdir -p $(OUTPUT)$(1) && \ - $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) + $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2) QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir QUIET_SUBDIR1 = @@ -72,6 +72,6 @@ ifndef V descend = \ @echo ' ' DESCEND $(1); \ mkdir -p $(OUTPUT)$(1) && \ - $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) + $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2) endif endif -- cgit v1.2.3 From f2d9cae9ea9e0228f6eb4d4c5ab4f548d0270d1a Mon Sep 17 00:00:00 2001 From: Sukadev Bhattiprolu Date: Wed, 31 Oct 2012 11:21:28 -0700 Subject: perf powerpc: Use uapi/unistd.h to fix build error Use the 'unistd.h' from arch/powerpc/include/uapi to build the perf tool. Signed-off-by: Sukadev Bhattiprolu Acked-by: David Howells Cc: Anton Blanchard Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Robert Richter Cc: linuxppc-dev@ozlabs.org Link: http://lkml.kernel.org/r/20121107191818.GA16211@us.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/perf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/perf.h b/tools/perf/perf.h index c50985eaec4..e2ba8f004d3 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -26,7 +26,7 @@ void get_term_dimensions(struct winsize *ws); #endif #ifdef __powerpc__ -#include "../../arch/powerpc/include/asm/unistd.h" +#include "../../arch/powerpc/include/uapi/asm/unistd.h" #define rmb() asm volatile ("sync" ::: "memory") #define cpu_relax() asm volatile ("" ::: "memory"); #define CPUINFO_PROC "cpu" -- cgit v1.2.3 From d2709c7ce4c513ab7f4ca9a106a930621811f2d3 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 19 Nov 2012 22:21:03 +0000 Subject: perf: Make perf build for x86 with UAPI disintegration applied Make perf build for x86 once the UAPI disintegration patches for that arch have been applied by adding the appropriate -I flags - in the right order - and then converting some #includes that use ../.. notation to find main kernel headerfiles to use and instead. Note that -Iarch/foo/include/uapi is present _before_ -Iarch/foo/include. This makes sure we get the userspace version of the pt_regs struct. Ideally, we wouldn't have the latter -I flag at all, but unfortunately we want asm/svm.h and asm/vmx.h in builtin-kvm.c and these aren't part of the UAPI - at least not for x86. I wonder if the bits outside of the __KERNEL__ guards *should* be transferred there. I note also that perf seems to do its dependency handling manually by listing all the header files it might want to use in LIB_H in the Makefile. Can this be changed to use -MD? Note that to do make this work, we need to export and UAPI disintegrate linux/hw_breakpoint.h, which I think should've been exported previously so that perf can access the bits. We have to do this in the same patch to maintain bisectability. Signed-off-by: David Howells --- include/linux/hw_breakpoint.h | 31 +------------------------------ include/uapi/linux/Kbuild | 1 + include/uapi/linux/hw_breakpoint.h | 30 ++++++++++++++++++++++++++++++ tools/perf/Makefile | 29 ++++++++++++++++++++++++++++- tools/perf/arch/x86/include/perf_regs.h | 2 +- tools/perf/builtin-kvm.c | 6 +++--- tools/perf/builtin-test.c | 2 +- tools/perf/perf.h | 16 +++------------- tools/perf/util/evsel.c | 4 ++-- tools/perf/util/evsel.h | 3 ++- tools/perf/util/header.h | 2 +- tools/perf/util/parse-events-test.c | 2 +- tools/perf/util/parse-events.c | 2 +- tools/perf/util/parse-events.h | 2 +- tools/perf/util/pmu.h | 2 +- tools/perf/util/session.h | 2 +- 16 files changed, 78 insertions(+), 58 deletions(-) create mode 100644 include/uapi/linux/hw_breakpoint.h diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h index 6ae9c631a1b..0464c85e63f 100644 --- a/include/linux/hw_breakpoint.h +++ b/include/linux/hw_breakpoint.h @@ -1,35 +1,8 @@ #ifndef _LINUX_HW_BREAKPOINT_H #define _LINUX_HW_BREAKPOINT_H -enum { - HW_BREAKPOINT_LEN_1 = 1, - HW_BREAKPOINT_LEN_2 = 2, - HW_BREAKPOINT_LEN_4 = 4, - HW_BREAKPOINT_LEN_8 = 8, -}; - -enum { - HW_BREAKPOINT_EMPTY = 0, - HW_BREAKPOINT_R = 1, - HW_BREAKPOINT_W = 2, - HW_BREAKPOINT_RW = HW_BREAKPOINT_R | HW_BREAKPOINT_W, - HW_BREAKPOINT_X = 4, - HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X, -}; - -enum bp_type_idx { - TYPE_INST = 0, -#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS - TYPE_DATA = 0, -#else - TYPE_DATA = 1, -#endif - TYPE_MAX -}; - -#ifdef __KERNEL__ - #include +#include #ifdef CONFIG_HAVE_HW_BREAKPOINT @@ -151,6 +124,4 @@ static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) } #endif /* CONFIG_HAVE_HW_BREAKPOINT */ -#endif /* __KERNEL__ */ - #endif /* _LINUX_HW_BREAKPOINT_H */ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index e194387ef78..19e765fbfef 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -415,3 +415,4 @@ header-y += wireless.h header-y += x25.h header-y += xattr.h header-y += xfrm.h +header-y += hw_breakpoint.h diff --git a/include/uapi/linux/hw_breakpoint.h b/include/uapi/linux/hw_breakpoint.h new file mode 100644 index 00000000000..b04000a2296 --- /dev/null +++ b/include/uapi/linux/hw_breakpoint.h @@ -0,0 +1,30 @@ +#ifndef _UAPI_LINUX_HW_BREAKPOINT_H +#define _UAPI_LINUX_HW_BREAKPOINT_H + +enum { + HW_BREAKPOINT_LEN_1 = 1, + HW_BREAKPOINT_LEN_2 = 2, + HW_BREAKPOINT_LEN_4 = 4, + HW_BREAKPOINT_LEN_8 = 8, +}; + +enum { + HW_BREAKPOINT_EMPTY = 0, + HW_BREAKPOINT_R = 1, + HW_BREAKPOINT_W = 2, + HW_BREAKPOINT_RW = HW_BREAKPOINT_R | HW_BREAKPOINT_W, + HW_BREAKPOINT_X = 4, + HW_BREAKPOINT_INVALID = HW_BREAKPOINT_RW | HW_BREAKPOINT_X, +}; + +enum bp_type_idx { + TYPE_INST = 0, +#ifdef CONFIG_HAVE_MIXED_BREAKPOINTS_REGS + TYPE_DATA = 0, +#else + TYPE_DATA = 1, +#endif + TYPE_MAX +}; + +#endif /* _UAPI_LINUX_HW_BREAKPOINT_H */ diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 00deed4d615..0a619af5be4 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -169,7 +169,34 @@ endif ### --- END CONFIGURATION SECTION --- -BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(shell pwd))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +#$(info Determined 'srctree' to be $(srctree)) +endif + +ifneq ($(objtree),) +#$(info Determined 'objtree' to be $(objtree)) +endif + +ifneq ($(OUTPUT),) +#$(info Determined 'OUTPUT' to be $(OUTPUT)) +endif + +BASIC_CFLAGS = \ + -Iutil/include \ + -Iarch/$(ARCH)/include \ + $(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \ + -I$(srctree)/arch/$(ARCH)/include/uapi \ + -I$(srctree)/arch/$(ARCH)/include \ + $(if $(objtree),-I$(objtree)/include/generated/uapi) \ + -I$(srctree)/include/uapi \ + -I$(srctree)/include \ + -I$(OUTPUT)util \ + -Iutil \ + -I. \ + -I$(TRACE_EVENT_DIR) \ + -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE BASIC_LDFLAGS = # Guard against environment variables diff --git a/tools/perf/arch/x86/include/perf_regs.h b/tools/perf/arch/x86/include/perf_regs.h index 46fc9f15c6b..7fcdcdbee91 100644 --- a/tools/perf/arch/x86/include/perf_regs.h +++ b/tools/perf/arch/x86/include/perf_regs.h @@ -3,7 +3,7 @@ #include #include "../../util/types.h" -#include "../../../../../arch/x86/include/asm/perf_regs.h" +#include #ifndef ARCH_X86_64 #define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 260abc535b5..e013bdb5e24 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -22,9 +22,9 @@ #include #include -#include "../../arch/x86/include/asm/svm.h" -#include "../../arch/x86/include/asm/vmx.h" -#include "../../arch/x86/include/asm/kvm.h" +#include +#include +#include struct event_key { #define INVALID_KEY (~0ULL) diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 484f26cc0c0..5acd6e8e658 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c @@ -15,7 +15,7 @@ #include "util/thread_map.h" #include "util/pmu.h" #include "event-parse.h" -#include "../../include/linux/hw_breakpoint.h" +#include #include diff --git a/tools/perf/perf.h b/tools/perf/perf.h index e2ba8f004d3..238f923f221 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -5,8 +5,9 @@ struct winsize; void get_term_dimensions(struct winsize *ws); +#include + #if defined(__i386__) -#include "../../arch/x86/include/asm/unistd.h" #define rmb() asm volatile("lock; addl $0,0(%%esp)" ::: "memory") #define cpu_relax() asm volatile("rep; nop" ::: "memory"); #define CPUINFO_PROC "model name" @@ -16,7 +17,6 @@ void get_term_dimensions(struct winsize *ws); #endif #if defined(__x86_64__) -#include "../../arch/x86/include/asm/unistd.h" #define rmb() asm volatile("lfence" ::: "memory") #define cpu_relax() asm volatile("rep; nop" ::: "memory"); #define CPUINFO_PROC "model name" @@ -26,20 +26,17 @@ void get_term_dimensions(struct winsize *ws); #endif #ifdef __powerpc__ -#include "../../arch/powerpc/include/uapi/asm/unistd.h" #define rmb() asm volatile ("sync" ::: "memory") #define cpu_relax() asm volatile ("" ::: "memory"); #define CPUINFO_PROC "cpu" #endif #ifdef __s390__ -#include "../../arch/s390/include/asm/unistd.h" #define rmb() asm volatile("bcr 15,0" ::: "memory") #define cpu_relax() asm volatile("" ::: "memory"); #endif #ifdef __sh__ -#include "../../arch/sh/include/asm/unistd.h" #if defined(__SH4A__) || defined(__SH5__) # define rmb() asm volatile("synco" ::: "memory") #else @@ -50,35 +47,30 @@ void get_term_dimensions(struct winsize *ws); #endif #ifdef __hppa__ -#include "../../arch/parisc/include/asm/unistd.h" #define rmb() asm volatile("" ::: "memory") #define cpu_relax() asm volatile("" ::: "memory"); #define CPUINFO_PROC "cpu" #endif #ifdef __sparc__ -#include "../../arch/sparc/include/uapi/asm/unistd.h" #define rmb() asm volatile("":::"memory") #define cpu_relax() asm volatile("":::"memory") #define CPUINFO_PROC "cpu" #endif #ifdef __alpha__ -#include "../../arch/alpha/include/asm/unistd.h" #define rmb() asm volatile("mb" ::: "memory") #define cpu_relax() asm volatile("" ::: "memory") #define CPUINFO_PROC "cpu model" #endif #ifdef __ia64__ -#include "../../arch/ia64/include/asm/unistd.h" #define rmb() asm volatile ("mf" ::: "memory") #define cpu_relax() asm volatile ("hint @pause" ::: "memory") #define CPUINFO_PROC "model name" #endif #ifdef __arm__ -#include "../../arch/arm/include/asm/unistd.h" /* * Use the __kuser_memory_barrier helper in the CPU helper page. See * arch/arm/kernel/entry-armv.S in the kernel source for details. @@ -89,13 +81,11 @@ void get_term_dimensions(struct winsize *ws); #endif #ifdef __aarch64__ -#include "../../arch/arm64/include/asm/unistd.h" #define rmb() asm volatile("dmb ld" ::: "memory") #define cpu_relax() asm volatile("yield" ::: "memory") #endif #ifdef __mips__ -#include "../../arch/mips/include/asm/unistd.h" #define rmb() asm volatile( \ ".set mips2\n\t" \ "sync\n\t" \ @@ -112,7 +102,7 @@ void get_term_dimensions(struct winsize *ws); #include #include -#include "../../include/uapi/linux/perf_event.h" +#include #include "util/types.h" #include diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 618d41140ab..d144d464ce3 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -18,8 +18,8 @@ #include "cpumap.h" #include "thread_map.h" #include "target.h" -#include "../../../include/linux/hw_breakpoint.h" -#include "../../../include/uapi/linux/perf_event.h" +#include +#include #include "perf_regs.h" #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 6f94d6dea00..d99b476ef37 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -3,7 +3,8 @@ #include #include -#include "../../../include/uapi/linux/perf_event.h" +#include +#include #include "types.h" #include "xyarray.h" #include "cgroup.h" diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 879d215cdac..9bc00783f24 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -1,7 +1,7 @@ #ifndef __PERF_HEADER_H #define __PERF_HEADER_H -#include "../../../include/uapi/linux/perf_event.h" +#include #include #include #include "types.h" diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c index 516ecd9ddd6..6ef213b35ec 100644 --- a/tools/perf/util/parse-events-test.c +++ b/tools/perf/util/parse-events-test.c @@ -3,7 +3,7 @@ #include "evsel.h" #include "evlist.h" #include "sysfs.h" -#include "../../../include/linux/hw_breakpoint.h" +#include #define TEST_ASSERT_VAL(text, cond) \ do { \ diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 75c7b0fca6d..6b6d03e93c3 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1,4 +1,4 @@ -#include "../../../include/linux/hw_breakpoint.h" +#include #include "util.h" #include "../perf.h" #include "evlist.h" diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 839230ceb18..2820c407adb 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -7,7 +7,7 @@ #include #include #include "types.h" -#include "../../../include/uapi/linux/perf_event.h" +#include #include "types.h" struct list_head; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 39f3abac774..fdeb8ac7c5d 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -2,7 +2,7 @@ #define __PMU_H #include -#include "../../../include/uapi/linux/perf_event.h" +#include enum { PERF_PMU_FORMAT_VALUE_CONFIG, diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index dd6426163ba..0eae00ad5fe 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -7,7 +7,7 @@ #include "symbol.h" #include "thread.h" #include -#include "../../../include/uapi/linux/perf_event.h" +#include struct sample_queue; struct ip_callchain; -- cgit v1.2.3 From 50d69b5184169caeb85e082f627200da9b0e1677 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Nov 2012 11:48:00 +0000 Subject: iio: Fix iio_buffer_register stub signature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Match the iio_buffer_register stub signature up to the real function and make the second parameter const. This fixes a the following warnings if CONFIG_IIO_BUFFER is disabled: drivers/staging/iio/accel/adis16201_core.c: In function ‘adis16201_probe’: drivers/staging/iio/accel/adis16201_core.c:536: warning: passing argument 2 of ‘iio_buffer_register’ discards qualifiers from pointer target type drivers/staging/iio/accel/adis16203_core.c: In function ‘adis16203_probe’: drivers/staging/iio/accel/adis16203_core.c:468: warning: passing argument 2 of ‘iio_buffer_register’ discards qualifiers from pointer target type drivers/staging/iio/accel/adis16204_core.c: In function ‘adis16204_probe’: drivers/staging/iio/accel/adis16204_core.c:527: warning: passing argument 2 of ‘iio_buffer_register’ discards qualifiers from pointer target type drivers/staging/iio/accel/adis16209_core.c: In function ‘adis16209_probe’: drivers/staging/iio/accel/adis16209_core.c:542: warning: passing argument 2 of ‘iio_buffer_register’ discards qualifiers from pointer target type drivers/staging/iio/accel/adis16240_core.c: In function ‘adis16240_probe’: drivers/staging/iio/accel/adis16240_core.c:588: warning: passing argument 2 of ‘iio_buffer_register’ discards qualifiers from pointer target type Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- include/linux/iio/buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 02704056918..f3eea18fdf4 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -195,7 +195,7 @@ bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev, #else /* CONFIG_IIO_BUFFER */ static inline int iio_buffer_register(struct iio_dev *indio_dev, - struct iio_chan_spec *channels, + const struct iio_chan_spec *channels, int num_channels) { return 0; -- cgit v1.2.3 From 6dc973d4fd29860cf648a56510b8a14410d0451f Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 8 Nov 2012 09:05:00 +0000 Subject: iio: isl29018: fix to return error or 0 in isl29018_write_raw() We had assigned the return value to 'ret' but ignored it when return from isl29018_write_raw(), it's better to return 'ret' instead of 0. dpatch engine is used to auto generate this patch. (https://github.com/weiyj/dpatch) Signed-off-by: Wei Yongjun Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/isl29018.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 3b03f6f5c40..1d5b294d6e6 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -356,7 +356,7 @@ static int isl29018_write_raw(struct iio_dev *indio_dev, } mutex_unlock(&chip->lock); - return 0; + return ret; } static int isl29018_read_raw(struct iio_dev *indio_dev, -- cgit v1.2.3 From ccd2b52f4ac69c34564434fb9e5153abcbc97109 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Nov 2012 13:28:00 +0000 Subject: staging:iio: Add common ADIS library A lot of the devices from the ADIS family use the same methods for accessing registers, sampling data and trigger handling. They also have similar register layout for the control registers. This patch adds a common library for these devices. The library implements functions for reading and writing registers as buffer and trigger management. It also provides a set functions for accessing the control registers and for running the devices internal self-test. Having this common library code will allow us to remove a lot of duplicated code. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/imu/Kconfig | 13 ++ drivers/staging/iio/imu/Makefile | 5 + drivers/staging/iio/imu/adis.c | 338 +++++++++++++++++++++++++++++++++ drivers/staging/iio/imu/adis.h | 178 +++++++++++++++++ drivers/staging/iio/imu/adis_buffer.c | 200 +++++++++++++++++++ drivers/staging/iio/imu/adis_trigger.c | 90 +++++++++ 6 files changed, 824 insertions(+) create mode 100644 drivers/staging/iio/imu/adis.c create mode 100644 drivers/staging/iio/imu/adis.h create mode 100644 drivers/staging/iio/imu/adis_buffer.c create mode 100644 drivers/staging/iio/imu/adis_trigger.c diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig index 2c2f47de263..89b9f2566b8 100644 --- a/drivers/staging/iio/imu/Kconfig +++ b/drivers/staging/iio/imu/Kconfig @@ -15,3 +15,16 @@ config ADIS16400 (adis16400 series also have magnetometers). endmenu + +config IIO_ADIS_LIB + tristate + help + A set of IO helper functions for the Analog Devices ADIS* device family. + +config IIO_ADIS_LIB_BUFFER + bool + select IIO_TRIGGER + select IIO_SW_RING + help + A set of buffer helper functions for the Analog Devices ADIS* device + family. diff --git a/drivers/staging/iio/imu/Makefile b/drivers/staging/iio/imu/Makefile index 3400a13d152..65dafba1e5d 100644 --- a/drivers/staging/iio/imu/Makefile +++ b/drivers/staging/iio/imu/Makefile @@ -5,3 +5,8 @@ adis16400-y := adis16400_core.o adis16400-$(CONFIG_IIO_BUFFER) += adis16400_ring.o adis16400_trigger.o obj-$(CONFIG_ADIS16400) += adis16400.o + +adis_lib-y += adis.o +adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_trigger.o +adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o +obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o diff --git a/drivers/staging/iio/imu/adis.c b/drivers/staging/iio/imu/adis.c new file mode 100644 index 00000000000..0bd21022e4c --- /dev/null +++ b/drivers/staging/iio/imu/adis.c @@ -0,0 +1,338 @@ +/* + * Common library for ADIS16XXX devices + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "adis.h" + +#define ADIS_MSC_CTRL_DATA_RDY_EN BIT(2) +#define ADIS_MSC_CTRL_DATA_RDY_POL_HIGH BIT(1) +#define ADIS_MSC_CTRL_DATA_RDY_DIO2 BIT(0) +#define ADIS_GLOB_CMD_SW_RESET BIT(7) + +/** + * adis_write_reg_8() - Write single byte to a register + * @adis: The adis device + * @reg: The address of the register to be written + * @val: The value to write + */ +int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val) +{ + int ret; + + mutex_lock(&adis->txrx_lock); + adis->tx[0] = ADIS_WRITE_REG(reg); + adis->tx[1] = val; + + ret = spi_write(adis->spi, adis->tx, 2); + mutex_unlock(&adis->txrx_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(adis_write_reg_8); + +/** + * adis_write_reg_16() - Write 2 bytes to a pair of registers + * @adis: The adis device + * @reg: The address of the lower of the two registers + * @val: Value to be written + */ +int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t value) +{ + int ret; + struct spi_message msg; + struct spi_transfer xfers[] = { + { + .tx_buf = adis->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = adis->data->write_delay, + }, { + .tx_buf = adis->tx + 2, + .bits_per_word = 8, + .len = 2, + .delay_usecs = adis->data->write_delay, + }, + }; + + mutex_lock(&adis->txrx_lock); + adis->tx[0] = ADIS_WRITE_REG(reg); + adis->tx[1] = value & 0xff; + adis->tx[2] = ADIS_WRITE_REG(reg + 1); + adis->tx[3] = (value >> 8) & 0xff; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(adis->spi, &msg); + mutex_unlock(&adis->txrx_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(adis_write_reg_16); + +/** + * adis_read_reg_16() - read 2 bytes from a 16-bit register + * @adis: The adis device + * @reg: The address of the lower of the two registers + * @val: The value read back from the device + */ +int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val) +{ + struct spi_message msg; + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = adis->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = adis->data->read_delay, + }, { + .rx_buf = adis->rx, + .bits_per_word = 8, + .len = 2, + .delay_usecs = adis->data->read_delay, + }, + }; + + mutex_lock(&adis->txrx_lock); + adis->tx[0] = ADIS_READ_REG(reg); + adis->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(adis->spi, &msg); + if (ret) { + dev_err(&adis->spi->dev, "Failed to read 16 bit register 0x%02X: %d\n", + reg, ret); + goto error_ret; + } + *val = get_unaligned_be16(adis->rx); + +error_ret: + mutex_unlock(&adis->txrx_lock); + return ret; +} +EXPORT_SYMBOL_GPL(adis_read_reg_16); + +/** + * adis_enable_irq() - Enable or disable data ready IRQ + * @adis: The adis device + * @enable: Whether to enable the IRQ + * + * Returns 0 on success, negative error code otherwise + */ +int adis_enable_irq(struct adis *adis, bool enable) +{ + int ret = 0; + uint16_t msc; + + ret = adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc); + if (ret) + goto error_ret; + + msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH; + msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2; + if (enable) + msc |= ADIS_MSC_CTRL_DATA_RDY_EN; + else + msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN; + + ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc); + +error_ret: + return ret; +} +EXPORT_SYMBOL(adis_enable_irq); + +/** + * adis_check_status() - Check the device for error conditions + * @adis: The adis device + * + * Returns 0 on success, a negative error code otherwise + */ +int adis_check_status(struct adis *adis) +{ + uint16_t status; + int ret; + int i; + + ret = adis_read_reg_16(adis, adis->data->diag_stat_reg, &status); + if (ret < 0) + return ret; + + status &= adis->data->status_error_mask; + + if (status == 0) + return 0; + + for (i = 0; i < 16; ++i) { + if (status & BIT(i)) { + dev_err(&adis->spi->dev, "%s.\n", + adis->data->status_error_msgs[i]); + } + } + + return -EIO; +} +EXPORT_SYMBOL_GPL(adis_check_status); + +/** + * adis_reset() - Reset the device + * @adis: The adis device + * + * Returns 0 on success, a negative error code otherwise + */ +int adis_reset(struct adis *adis) +{ + int ret; + + ret = adis_write_reg_8(adis, adis->data->glob_cmd_reg, + ADIS_GLOB_CMD_SW_RESET); + if (ret) + dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret); + + return ret; +} +EXPORT_SYMBOL_GPL(adis_reset); + +static int adis_self_test(struct adis *adis) +{ + int ret; + + ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, + adis->data->self_test_mask); + if (ret) { + dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n", + ret); + return ret; + } + + msleep(adis->data->startup_delay); + + return adis_check_status(adis); +} + +/** + * adis_inital_startup() - Performs device self-test + * @adis: The adis device + * + * Returns 0 if the device is operational, a negative error code otherwise. + * + * This function should be called early on in the device initialization sequence + * to ensure that the device is in a sane and known state and that it is usable. + */ +int adis_initial_startup(struct adis *adis) +{ + int ret; + + ret = adis_self_test(adis); + if (ret) { + dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n"); + adis_reset(adis); + msleep(adis->data->startup_delay); + ret = adis_self_test(adis); + if (ret) { + dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n"); + return ret; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(adis_initial_startup); + +/** + * adis_single_conversion() - Performs a single sample conversion + * @indio_dev: The IIO device + * @chan: The IIO channel + * @error_mask: Mask for the error bit + * @val: Result of the conversion + * + * Returns IIO_VAL_INT on success, a negative error code otherwise. + * + * The function performs a single conversion on a given channel and post + * processes the value accordingly to the channel spec. If a error_mask is given + * the function will check if the mask is set in the returned raw value. If it + * is set the function will perform a self-check. If the device does not report + * a error bit in the channels raw value set error_mask to 0. + */ +int adis_single_conversion(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned int error_mask, int *val) +{ + struct adis *adis = iio_device_get_drvdata(indio_dev); + uint16_t val16; + int ret; + + mutex_lock(&indio_dev->mlock); + + ret = adis_read_reg_16(adis, chan->address, &val16); + if (ret) + goto err_unlock; + + if (val16 & error_mask) { + ret = adis_check_status(adis); + if (ret) + goto err_unlock; + } + + if (chan->scan_type.sign == 's') + *val = sign_extend32(val16, chan->scan_type.realbits - 1); + else + *val = val16 & ((1 << chan->scan_type.realbits) - 1); + + ret = IIO_VAL_INT; +err_unlock: + mutex_unlock(&indio_dev->mlock); + return ret; +} +EXPORT_SYMBOL_GPL(adis_single_conversion); + +/** + * adis_init() - Initialize adis device structure + * @adis: The adis device + * @indio_dev: The iio device + * @spi: The spi device + * @data: Chip specific data + * + * Returns 0 on success, a negative error code otherwise. + * + * This function must be called, before any other adis helper function may be + * called. + */ +int adis_init(struct adis *adis, struct iio_dev *indio_dev, + struct spi_device *spi, const struct adis_data *data) +{ + mutex_init(&adis->txrx_lock); + adis->spi = spi; + adis->data = data; + iio_device_set_drvdata(indio_dev, adis); + + return adis_enable_irq(adis, false); +} +EXPORT_SYMBOL_GPL(adis_init); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Common library code for ADIS16XXX devices"); diff --git a/drivers/staging/iio/imu/adis.h b/drivers/staging/iio/imu/adis.h new file mode 100644 index 00000000000..c84da7afe14 --- /dev/null +++ b/drivers/staging/iio/imu/adis.h @@ -0,0 +1,178 @@ +/* + * Common library for ADIS16XXX devices + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __IIO_ADIS_H__ +#define __IIO_ADIS_H__ + +#include +#include +#include + +#define ADIS_WRITE_REG(reg) (0x80 | (reg)) +#define ADIS_READ_REG(reg) (reg) + +/** + * struct adis_data - ADIS chip variant specific data + * @read_delay: SPI delay for read operations in us + * @write_delay: SPI delay for write operations in us + * @glob_cmd_reg: Register address of the GLOB_CMD register + * @msc_ctrl_reg: Register address of the MSC_CTRL register + * @diag_stat_reg: Register address of the DIAG_STAT register + * @status_error_msgs: Array of error messgaes + * @status_error_mask: + */ +struct adis_data { + unsigned int read_delay; + unsigned int write_delay; + + unsigned int glob_cmd_reg; + unsigned int msc_ctrl_reg; + unsigned int diag_stat_reg; + + unsigned int self_test_mask; + unsigned int startup_delay; + + const char * const *status_error_msgs; + unsigned int status_error_mask; +}; + +struct adis { + struct spi_device *spi; + struct iio_trigger *trig; + + const struct adis_data *data; + + struct mutex txrx_lock; + struct spi_message msg; + struct spi_transfer *xfer; + void *buffer; + + uint8_t tx[8] ____cacheline_aligned; + uint8_t rx[4]; +}; + +int adis_init(struct adis *adis, struct iio_dev *indio_dev, + struct spi_device *spi, const struct adis_data *data); +int adis_reset(struct adis *adis); + +int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val); +int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t val); +int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val); + +int adis_enable_irq(struct adis *adis, bool enable); +int adis_check_status(struct adis *adis); + +int adis_initial_startup(struct adis *adis); + +int adis_single_conversion(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned int error_mask, + int *val); + +#define ADIS_VOLTAGE_CHAN(addr, si, chan, name, bits) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (chan), \ + .extend_name = name, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .address = (addr), \ + .scan_index = (si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 16, \ + }, \ +} + +#define ADIS_SUPPLY_CHAN(addr, si, bits) \ + ADIS_VOLTAGE_CHAN(addr, si, 0, "supply", bits) + +#define ADIS_AUX_ADC_CHAN(addr, si, bits) \ + ADIS_VOLTAGE_CHAN(addr, si, 1, NULL, bits) + +#define ADIS_TEMP_CHAN(addr, si, bits) { \ + .type = IIO_TEMP, \ + .indexed = 1, \ + .channel = 0, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \ + .address = (addr), \ + .scan_index = (si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 16, \ + }, \ +} + +#define ADIS_MOD_CHAN(_type, mod, addr, si, info, bits) { \ + .type = (_type), \ + .modified = 1, \ + .channel2 = IIO_MOD_ ## mod, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + info, \ + .address = (addr), \ + .scan_index = (si), \ + .scan_type = { \ + .sign = 's', \ + .realbits = (bits), \ + .storagebits = 16, \ + }, \ +} + +#define ADIS_ACCEL_CHAN(mod, addr, si, info, bits) \ + ADIS_MOD_CHAN(IIO_ACCEL, mod, addr, si, info, bits) + +#define ADIS_GYRO_CHAN(mod, addr, si, info, bits) \ + ADIS_MOD_CHAN(IIO_ANGL_VEL, mod, addr, si, info, bits) + +#define ADIS_INCLI_CHAN(mod, addr, si, info, bits) \ + ADIS_MOD_CHAN(IIO_INCLI, mod, addr, si, info, bits) + +#define ADIS_ROT_CHAN(mod, addr, si, info, bits) \ + ADIS_MOD_CHAN(IIO_ROT, mod, addr, si, info, bits) + +#ifdef CONFIG_IIO_ADIS_LIB_BUFFER + +int adis_setup_buffer_and_trigger(struct adis *adis, + struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)); +void adis_cleanup_buffer_and_trigger(struct adis *adis, + struct iio_dev *indio_dev); + +int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); +void adis_remove_trigger(struct adis *adis); + +#else /* CONFIG_IIO_BUFFER */ + +static inline int adis_setup_buffer_and_trigger(struct adis *adis, + struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)) +{ + return 0; +} + +static inline void adis_cleanup_buffer_and_trigger(struct adis *adis, + struct iio_dev *indio_dev) +{ +} + +static inline int adis_probe_trigger(struct adis *adis, + struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis_remove_trigger(struct adis *adis) +{ +} + +#endif /* CONFIG_IIO_BUFFER */ + +#endif diff --git a/drivers/staging/iio/imu/adis_buffer.c b/drivers/staging/iio/imu/adis_buffer.c new file mode 100644 index 00000000000..47bdea09f68 --- /dev/null +++ b/drivers/staging/iio/imu/adis_buffer.c @@ -0,0 +1,200 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include "../ring_sw.h" +#include + +#include "adis.h" + +#define ADIS_MAX_OUTPUTS 12 + +static int adis_read_buffer_data(struct adis *adis, struct iio_dev *indio_dev) +{ + int n_outputs = indio_dev->num_channels; + struct spi_transfer xfers[ADIS_MAX_OUTPUTS + 1]; + struct spi_message msg; + int ret; + int i; + + mutex_lock(&adis->txrx_lock); + + spi_message_init(&msg); + + memset(xfers, 0, sizeof(xfers)); + for (i = 0; i <= n_outputs; i++) { + xfers[i].bits_per_word = 8; + xfers[i].cs_change = 1; + xfers[i].len = 2; + xfers[i].delay_usecs = adis->data->read_delay; + if (i < n_outputs) { + xfers[i].tx_buf = adis->tx + 2 * i; + adis->tx[2 * i] = indio_dev->channels[i].address; + adis->tx[2 * i + 1] = 0; + } + if (i >= 1) + xfers[i].rx_buf = adis->rx + 2 * (i - 1); + spi_message_add_tail(&xfers[i], &msg); + } + + ret = spi_sync(adis->spi, &msg); + if (ret) + dev_err(&adis->spi->dev, "Failed to read data: %d", ret); + + mutex_unlock(&adis->txrx_lock); + + return ret; +} + +static irqreturn_t adis_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct adis *adis = iio_device_get_drvdata(indio_dev); + u16 *data; + int i = 0; + + data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); + if (data == NULL) { + dev_err(&adis->spi->dev, "Failed to allocate memory."); + return -ENOMEM; + } + + if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) + && adis_read_buffer_data(adis, indio_dev) >= 0) + for (; i < bitmap_weight(indio_dev->active_scan_mask, + indio_dev->masklength); i++) + data[i] = be16_to_cpup((__be16 *)&(adis->rx[i*2])); + + /* Guaranteed to be aligned with 8 byte boundary */ + if (indio_dev->scan_timestamp) + *((s64 *)(PTR_ALIGN(data, sizeof(s64)))) = pf->timestamp; + + iio_push_to_buffers(indio_dev, (u8 *)data); + + iio_trigger_notify_done(indio_dev->trig); + kfree(data); + + return IRQ_HANDLED; +} + +static const struct iio_buffer_setup_ops adis_buffer_setup_ops = { + .preenable = &iio_sw_buffer_preenable, + .postenable = &iio_triggered_buffer_postenable, + .predisable = &iio_triggered_buffer_predisable, +}; + +static int adis_buffer_setup(struct iio_dev *indio_dev, + irqreturn_t (*trigger_handler)(int, void *)) +{ + int ret = 0; + struct iio_buffer *buffer; + + if (!trigger_handler) + trigger_handler = &adis_trigger_handler; + + buffer = iio_sw_rb_allocate(indio_dev); + if (!buffer) { + ret = -ENOMEM; + return ret; + } + + indio_dev->buffer = buffer; + indio_dev->setup_ops = &adis_buffer_setup_ops; + + indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, + trigger_handler, + IRQF_ONESHOT, + indio_dev, + "%s_consumer%d", + indio_dev->name, + indio_dev->id); + if (indio_dev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_iio_sw_rb_free; + } + + indio_dev->modes |= INDIO_BUFFER_TRIGGERED; + return 0; + +error_iio_sw_rb_free: + iio_sw_rb_free(indio_dev->buffer); + return ret; +} + +static void adis_buffer_cleanup(struct iio_dev *indio_dev) +{ + iio_dealloc_pollfunc(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->buffer); +} + +/** + * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device + * @adis: The adis device. + * @indio_dev: The IIO device. + * @trigger_handler: Optional trigger handler, may be NULL. + * + * Returns 0 on success, a negative error code otherwise. + * + * This function sets up the buffer and trigger for a adis devices. If + * 'trigger_handler' is NULL the default trigger handler will be used. The + * default trigger handler will simply read the registers assigned to the + * currently active channels. + * + * adis_cleanup_buffer_and_trigger() should be called to free the resources + * allocated by this function. + */ +int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, + irqreturn_t (*trigger_handler)(int, void *)) +{ + int ret; + + ret = adis_buffer_setup(indio_dev, trigger_handler); + if (ret) + return ret; + + ret = iio_buffer_register(indio_dev, + indio_dev->channels, + indio_dev->num_channels); + if (ret) { + dev_err(&adis->spi->dev, "Failed to initialize buffer %d\n", + ret); + goto error_unreg_buffer_funcs; + } + + if (adis->spi->irq) { + ret = adis_probe_trigger(adis, indio_dev); + if (ret) + goto error_uninitialize_buffer; + } + return 0; + +error_uninitialize_buffer: + iio_buffer_unregister(indio_dev); +error_unreg_buffer_funcs: + adis_buffer_cleanup(indio_dev); + return ret; +} +EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); + +/** + * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources + * @adis: The adis device. + * @indio_dev: The IIO device. + * + * Frees resources allocated by adis_setup_buffer_and_trigger() + */ +void adis_cleanup_buffer_and_trigger(struct adis *adis, + struct iio_dev *indio_dev) +{ + if (adis->spi->irq) + adis_remove_trigger(adis); + iio_buffer_unregister(indio_dev); + adis_buffer_cleanup(indio_dev); +} +EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger); diff --git a/drivers/staging/iio/imu/adis_trigger.c b/drivers/staging/iio/imu/adis_trigger.c new file mode 100644 index 00000000000..3e89b2e8370 --- /dev/null +++ b/drivers/staging/iio/imu/adis_trigger.c @@ -0,0 +1,90 @@ +/* + * Common library for ADIS16XXX devices + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include + +#include +#include + +#include "adis.h" + +static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct adis *adis = trig->private_data; + + return adis_enable_irq(adis, state); +} + +static const struct iio_trigger_ops adis_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &adis_data_rdy_trigger_set_state, +}; + +/** + * adis_probe_trigger() - Sets up trigger for a adis device + * @adis: The adis device + * @indio_dev: The IIO device + * + * Returns 0 on success or a negative error code + * + * adis_remove_trigger() should be used to free the trigger. + */ +int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) +{ + int ret; + + adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, + indio_dev->id); + if (adis->trig == NULL) + return -ENOMEM; + + ret = request_irq(adis->spi->irq, + &iio_trigger_generic_data_rdy_poll, + IRQF_TRIGGER_RISING, + indio_dev->name, + adis->trig); + if (ret) + goto error_free_trig; + + adis->trig->dev.parent = &adis->spi->dev; + adis->trig->ops = &adis_trigger_ops; + adis->trig->private_data = adis; + ret = iio_trigger_register(adis->trig); + + indio_dev->trig = adis->trig; + if (ret) + goto error_free_irq; + + return 0; + +error_free_irq: + free_irq(adis->spi->irq, adis->trig); +error_free_trig: + iio_trigger_free(adis->trig); + return ret; +} +EXPORT_SYMBOL_GPL(adis_probe_trigger); + +/** + * adis_remove_trigger() - Remove trigger for a adis devices + * @adis: The adis device + * + * Removes the trigger previously registered with adis_probe_trigger(). + */ +void adis_remove_trigger(struct adis *adis) +{ + iio_trigger_unregister(adis->trig); + free_irq(adis->spi->irq, adis->trig); + iio_trigger_free(adis->trig); +} +EXPORT_SYMBOL_GPL(adis_remove_trigger); -- cgit v1.2.3 From 6d78e862ac55d9c09403a613eae6bf609ad46ee3 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Nov 2012 13:28:00 +0000 Subject: staging:iio:adis16201: Use adis library Use the new adis library for the adis16201 driver. This allows us to completely scrap the adis16201 buffer and trigger code and more than half of the core driver code. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/Kconfig | 4 +- drivers/staging/iio/accel/Makefile | 1 - drivers/staging/iio/accel/adis16201.h | 89 +---- drivers/staging/iio/accel/adis16201_core.c | 465 ++++---------------------- drivers/staging/iio/accel/adis16201_ring.c | 136 -------- drivers/staging/iio/accel/adis16201_trigger.c | 71 ---- 6 files changed, 69 insertions(+), 697 deletions(-) delete mode 100644 drivers/staging/iio/accel/adis16201_ring.c delete mode 100644 drivers/staging/iio/accel/adis16201_trigger.c diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index 5ab71670b70..0e965e50534 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -6,8 +6,8 @@ menu "Accelerometers" config ADIS16201 tristate "Analog Devices ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer" depends on SPI - select IIO_TRIGGER if IIO_BUFFER - select IIO_SW_RING if IIO_BUFFER + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help Say yes here to build support for Analog Devices adis16201 dual-axis digital inclinometer and accelerometer. diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index 95c66661e70..22dbebd83e0 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -3,7 +3,6 @@ # adis16201-y := adis16201_core.o -adis16201-$(CONFIG_IIO_BUFFER) += adis16201_ring.o adis16201_trigger.o obj-$(CONFIG_ADIS16201) += adis16201.o adis16203-y := adis16203_core.o diff --git a/drivers/staging/iio/accel/adis16201.h b/drivers/staging/iio/accel/adis16201.h index 72750f7f3a8..8747de5a980 100644 --- a/drivers/staging/iio/accel/adis16201.h +++ b/drivers/staging/iio/accel/adis16201.h @@ -3,9 +3,6 @@ #define ADIS16201_STARTUP_DELAY 220 /* ms */ -#define ADIS16201_READ_REG(a) a -#define ADIS16201_WRITE_REG(a) ((a) | 0x80) - #define ADIS16201_FLASH_CNT 0x00 /* Flash memory write count */ #define ADIS16201_SUPPLY_OUT 0x02 /* Output, power supply */ #define ADIS16201_XACCL_OUT 0x04 /* Output, x-axis accelerometer */ @@ -36,8 +33,6 @@ #define ADIS16201_DIAG_STAT 0x3C /* Diagnostics, system status register */ #define ADIS16201_GLOB_CMD 0x3E /* Operation, system command register */ -#define ADIS16201_OUTPUTS 7 - /* MSC_CTRL */ #define ADIS16201_MSC_CTRL_SELF_TEST_EN (1 << 8) /* Self-test enable */ #define ADIS16201_MSC_CTRL_DATA_RDY_EN (1 << 2) /* Data-ready enable: 1 = enabled, 0 = disabled */ @@ -47,95 +42,25 @@ /* DIAG_STAT */ #define ADIS16201_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16201_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16201_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */ -#define ADIS16201_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */ -#define ADIS16201_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */ -#define ADIS16201_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 3.15 V */ +#define ADIS16201_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */ +#define ADIS16201_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */ +#define ADIS16201_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */ +#define ADIS16201_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 3.15 V */ /* GLOB_CMD */ #define ADIS16201_GLOB_CMD_SW_RESET (1<<7) #define ADIS16201_GLOB_CMD_FACTORY_CAL (1<<1) -#define ADIS16201_MAX_TX 14 -#define ADIS16201_MAX_RX 14 - #define ADIS16201_ERROR_ACTIVE (1<<14) -/** - * struct adis16201_state - device instance specific data - * @us: actual spi_device - * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16201_state { - struct spi_device *us; - struct iio_trigger *trig; - struct mutex buf_lock; - u8 tx[14] ____cacheline_aligned; - u8 rx[14]; -}; - -int adis16201_set_irq(struct iio_dev *indio_dev, bool enable); - enum adis16201_scan { - ADIS16201_SCAN_SUPPLY, ADIS16201_SCAN_ACC_X, ADIS16201_SCAN_ACC_Y, - ADIS16201_SCAN_AUX_ADC, - ADIS16201_SCAN_TEMP, ADIS16201_SCAN_INCLI_X, ADIS16201_SCAN_INCLI_Y, + ADIS16201_SCAN_SUPPLY, + ADIS16201_SCAN_AUX_ADC, + ADIS16201_SCAN_TEMP, }; -#ifdef CONFIG_IIO_BUFFER -void adis16201_remove_trigger(struct iio_dev *indio_dev); -int adis16201_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16201_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - -int adis16201_configure_ring(struct iio_dev *indio_dev); -void adis16201_unconfigure_ring(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline void adis16201_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16201_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16201_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16201_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16201_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -static inline int adis16201_initialize_ring(struct iio_ring_buffer *ring) -{ - return 0; -} - -static inline void adis16201_uninitialize_ring(struct iio_ring_buffer *ring) -{ -} - -#endif /* CONFIG_IIO_BUFFER */ #endif /* SPI_ADIS16201_H_ */ diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index d2a203a583a..0121501dc63 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -20,256 +20,13 @@ #include #include "adis16201.h" +#include "../imu/adis.h" -enum adis16201_chan { - in_supply, - temp, - accel_x, - accel_y, - incli_x, - incli_y, - in_aux, -}; - -/** - * adis16201_spi_write_reg_8() - write single byte to a register - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16201_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16201_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16201_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16201_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16201_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16201_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16201_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16201_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16201_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16201_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16201_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 20, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 20, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16201_READ_REG(lower_reg_address); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static int adis16201_reset(struct iio_dev *indio_dev) -{ - int ret; - struct adis16201_state *st = iio_priv(indio_dev); - - ret = adis16201_spi_write_reg_8(indio_dev, - ADIS16201_GLOB_CMD, - ADIS16201_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&st->us->dev, "problem resetting device"); - - return ret; -} - -int adis16201_set_irq(struct iio_dev *indio_dev, bool enable) -{ - int ret = 0; - u16 msc; - - ret = adis16201_spi_read_reg_16(indio_dev, ADIS16201_MSC_CTRL, &msc); - if (ret) - goto error_ret; - - msc |= ADIS16201_MSC_CTRL_ACTIVE_HIGH; - msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_DIO1; - if (enable) - msc |= ADIS16201_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_EN; - - ret = adis16201_spi_write_reg_16(indio_dev, ADIS16201_MSC_CTRL, msc); - -error_ret: - return ret; -} - -static int adis16201_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - - ret = adis16201_spi_read_reg_16(indio_dev, - ADIS16201_DIAG_STAT, &status); - if (ret < 0) { - dev_err(&indio_dev->dev, "Reading status failed\n"); - goto error_ret; - } - ret = status & 0xF; - if (ret) - ret = -EFAULT; - - if (status & ADIS16201_DIAG_STAT_SPI_FAIL) - dev_err(&indio_dev->dev, "SPI failure\n"); - if (status & ADIS16201_DIAG_STAT_FLASH_UPT) - dev_err(&indio_dev->dev, "Flash update failed\n"); - if (status & ADIS16201_DIAG_STAT_POWER_HIGH) - dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); - if (status & ADIS16201_DIAG_STAT_POWER_LOW) - dev_err(&indio_dev->dev, "Power supply below 3.15V\n"); - -error_ret: - return ret; -} - -static int adis16201_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16201_spi_write_reg_16(indio_dev, - ADIS16201_MSC_CTRL, - ADIS16201_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - ret = adis16201_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16201_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - struct device *dev = &indio_dev->dev; - - /* Disable IRQ */ - ret = adis16201_set_irq(indio_dev, false); - if (ret) { - dev_err(dev, "disable irq failed"); - goto err_ret; - } - - /* Do self test */ - ret = adis16201_self_test(indio_dev); - if (ret) { - dev_err(dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16201_check_status(indio_dev); - if (ret) { - adis16201_reset(indio_dev); - dev_err(dev, "device not playing ball -> reset"); - msleep(ADIS16201_STARTUP_DELAY); - ret = adis16201_check_status(indio_dev); - if (ret) { - dev_err(dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} - -static u8 adis16201_addresses[7][2] = { - [in_supply] = { ADIS16201_SUPPLY_OUT, }, - [temp] = { ADIS16201_TEMP_OUT }, - [accel_x] = { ADIS16201_XACCL_OUT, ADIS16201_XACCL_OFFS }, - [accel_y] = { ADIS16201_YACCL_OUT, ADIS16201_YACCL_OFFS }, - [in_aux] = { ADIS16201_AUX_ADC }, - [incli_x] = { ADIS16201_XINCL_OUT }, - [incli_y] = { ADIS16201_YINCL_OUT }, +static const u8 adis16201_addresses[] = { + [ADIS16201_SCAN_ACC_X] = ADIS16201_XACCL_OFFS, + [ADIS16201_SCAN_ACC_Y] = ADIS16201_YACCL_OFFS, + [ADIS16201_SCAN_INCLI_X] = ADIS16201_XINCL_OFFS, + [ADIS16201_SCAN_INCLI_Y] = ADIS16201_YINCL_OFFS, }; static int adis16201_read_raw(struct iio_dev *indio_dev, @@ -277,6 +34,7 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { + struct adis *st = iio_priv(indio_dev); int ret; int bits; u8 addr; @@ -284,29 +42,8 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - addr = adis16201_addresses[chan->address][0]; - ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - - if (val16 & ADIS16201_ERROR_ACTIVE) { - ret = adis16201_check_status(indio_dev); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - } - val16 = val16 & ((1 << chan->scan_type.realbits) - 1); - if (chan->scan_type.sign == 's') - val16 = (s16)(val16 << - (16 - chan->scan_type.realbits)) >> - (16 - chan->scan_type.realbits); - *val = val16; - mutex_unlock(&indio_dev->mlock); - return IIO_VAL_INT; + return adis_single_conversion(indio_dev, chan, + ADIS16201_ERROR_ACTIVE, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: @@ -349,8 +86,8 @@ static int adis16201_read_raw(struct iio_dev *indio_dev, return -EINVAL; } mutex_lock(&indio_dev->mlock); - addr = adis16201_addresses[chan->address][1]; - ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16201_addresses[chan->scan_index]; + ret = adis_read_reg_16(st, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -370,6 +107,7 @@ static int adis16201_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct adis *st = iio_priv(indio_dev); int bits; s16 val16; u8 addr; @@ -386,111 +124,24 @@ static int adis16201_write_raw(struct iio_dev *indio_dev, return -EINVAL; } val16 = val & ((1 << bits) - 1); - addr = adis16201_addresses[chan->address][1]; - return adis16201_spi_write_reg_16(indio_dev, addr, val16); + addr = adis16201_addresses[chan->scan_index]; + return adis_write_reg_16(st, addr, val16); } return -EINVAL; } static const struct iio_chan_spec adis16201_channels[] = { - { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_supply, - .scan_index = ADIS16201_SCAN_SUPPLY, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - .address = temp, - .scan_index = ADIS16201_SCAN_TEMP, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = accel_x, - .scan_index = ADIS16201_SCAN_ACC_X, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = accel_y, - .scan_index = ADIS16201_SCAN_ACC_Y, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_aux, - .scan_index = ADIS16201_SCAN_AUX_ADC, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_INCLI, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = incli_x, - .scan_index = ADIS16201_SCAN_INCLI_X, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_INCLI, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = incli_y, - .scan_index = ADIS16201_SCAN_INCLI_Y, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, + ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT, ADIS16201_SCAN_SUPPLY, 12), + ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT, ADIS16201_SCAN_TEMP, 12), + ADIS_ACCEL_CHAN(X, ADIS16201_XACCL_OUT, ADIS16201_SCAN_ACC_X, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + ADIS_ACCEL_CHAN(Y, ADIS16201_YACCL_OUT, ADIS16201_SCAN_ACC_Y, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC, ADIS16201_SCAN_AUX_ADC, 12), + ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT, ADIS16201_SCAN_INCLI_X, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + ADIS_INCLI_CHAN(X, ADIS16201_YINCL_OUT, ADIS16201_SCAN_INCLI_Y, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), IIO_CHAN_SOFT_TIMESTAMP(7) }; @@ -500,10 +151,33 @@ static const struct iio_info adis16201_info = { .driver_module = THIS_MODULE, }; +static const char * const adis16201_status_error_msgs[] = { + [ADIS16201_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16201_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16201_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", + [ADIS16201_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", +}; + +static const struct adis_data adis16201_data = { + .read_delay = 20, + .msc_ctrl_reg = ADIS16201_MSC_CTRL, + .glob_cmd_reg = ADIS16201_GLOB_CMD, + .diag_stat_reg = ADIS16201_DIAG_STAT, + + .self_test_mask = ADIS16201_MSC_CTRL_SELF_TEST_EN, + .startup_delay = ADIS16201_STARTUP_DELAY, + + .status_error_msgs = adis16201_status_error_msgs, + .status_error_mask = BIT(ADIS16201_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16201_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16201_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16201_DIAG_STAT_POWER_LOW_BIT), +}; + static int __devinit adis16201_probe(struct spi_device *spi) { int ret; - struct adis16201_state *st; + struct adis *st; struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ @@ -516,9 +190,6 @@ static int __devinit adis16201_probe(struct spi_device *spi) /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); - indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; indio_dev->info = &adis16201_info; @@ -527,40 +198,25 @@ static int __devinit adis16201_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(adis16201_channels); indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16201_configure_ring(indio_dev); + ret = adis_init(st, indio_dev, spi, &adis16201_data); + if (ret) + goto error_free_dev; + ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) goto error_free_dev; - - ret = iio_buffer_register(indio_dev, - adis16201_channels, - ARRAY_SIZE(adis16201_channels)); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = adis16201_probe_trigger(indio_dev); - if (ret) - goto error_uninitialize_ring; - } /* Get the device into a sane initial state */ - ret = adis16201_initial_setup(indio_dev); + ret = adis_initial_startup(st); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; ret = iio_device_register(indio_dev); if (ret < 0) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; return 0; -error_remove_trigger: - adis16201_remove_trigger(indio_dev); -error_uninitialize_ring: - iio_buffer_unregister(indio_dev); -error_unreg_ring_funcs: - adis16201_unconfigure_ring(indio_dev); +error_cleanup_buffer_trigger: + adis_cleanup_buffer_and_trigger(st, indio_dev); error_free_dev: iio_device_free(indio_dev); error_ret: @@ -570,11 +226,10 @@ error_ret: static int __devexit adis16201_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - adis16201_remove_trigger(indio_dev); - iio_buffer_unregister(indio_dev); - adis16201_unconfigure_ring(indio_dev); + adis_cleanup_buffer_and_trigger(st, indio_dev); iio_device_free(indio_dev); return 0; diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c deleted file mode 100644 index e14ca60092a..00000000000 --- a/drivers/staging/iio/accel/adis16201_ring.c +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include "../ring_sw.h" -#include -#include "adis16201.h" - - -/** - * adis16201_read_ring_data() read data registers which will be placed into ring - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @rx: somewhere to pass back the value read - **/ -static int adis16201_read_ring_data(struct iio_dev *indio_dev, u8 *rx) -{ - struct spi_message msg; - struct adis16201_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[ADIS16201_OUTPUTS + 1]; - int ret; - int i; - - mutex_lock(&st->buf_lock); - - spi_message_init(&msg); - - memset(xfers, 0, sizeof(xfers)); - for (i = 0; i <= ADIS16201_OUTPUTS; i++) { - xfers[i].bits_per_word = 8; - xfers[i].cs_change = 1; - xfers[i].len = 2; - xfers[i].delay_usecs = 20; - if (i < ADIS16201_OUTPUTS) { - xfers[i].tx_buf = st->tx + 2 * i; - st->tx[2 * i] = ADIS16201_READ_REG(ADIS16201_SUPPLY_OUT + - 2 * i); - st->tx[2 * i + 1] = 0; - } - if (i >= 1) - xfers[i].rx_buf = rx + 2 * (i - 1); - spi_message_add_tail(&xfers[i], &msg); - } - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when burst reading"); - - mutex_unlock(&st->buf_lock); - - return ret; -} - -/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device - * specific to be rolled into the core. - */ -static irqreturn_t adis16201_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct adis16201_state *st = iio_priv(indio_dev); - - int i = 0; - s16 *data; - - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (data == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - goto done; - } - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) - && adis16201_read_ring_data(indio_dev, st->rx) >= 0) - for (; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - - iio_push_to_buffers(indio_dev, (u8 *)data); - - kfree(data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -void adis16201_unconfigure_ring(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); -} - -static const struct iio_buffer_setup_ops adis16201_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -int adis16201_configure_ring(struct iio_dev *indio_dev) -{ - int ret = 0; - struct iio_buffer *ring; - - ring = iio_sw_rb_allocate(indio_dev); - if (!ring) { - ret = -ENOMEM; - return ret; - } - indio_dev->buffer = ring; - ring->scan_timestamp = true; - indio_dev->setup_ops = &adis16201_ring_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &adis16201_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "adis16201_consumer%d", - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; -error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->buffer); - return ret; -} diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c deleted file mode 100644 index 96fdabbac20..00000000000 --- a/drivers/staging/iio/accel/adis16201_trigger.c +++ /dev/null @@ -1,71 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include "adis16201.h" - -/** - * adis16201_data_rdy_trigger_set_state() set datardy interrupt state - **/ -static int adis16201_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct iio_dev *indio_dev = trig->private_data; - - dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16201_set_irq(indio_dev, state); -} - -static const struct iio_trigger_ops adis16201_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &adis16201_data_rdy_trigger_set_state, -}; - -int adis16201_probe_trigger(struct iio_dev *indio_dev) -{ - int ret; - struct adis16201_state *st = iio_priv(indio_dev); - - st->trig = iio_trigger_alloc("adis16201-dev%d", indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - ret = request_irq(st->us->irq, - &iio_trigger_generic_data_rdy_poll, - IRQF_TRIGGER_RISING, - "adis16201", - st->trig); - if (ret) - goto error_free_trig; - st->trig->dev.parent = &st->us->dev; - st->trig->ops = &adis16201_trigger_ops; - st->trig->private_data = indio_dev; - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->us->irq, st->trig); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -void adis16201_remove_trigger(struct iio_dev *indio_dev) -{ - struct adis16201_state *state = iio_priv(indio_dev); - - iio_trigger_unregister(state->trig); - free_irq(state->us->irq, state->trig); - iio_trigger_free(state->trig); -} -- cgit v1.2.3 From 3bff7eb06d580f0ea4b0938c0757afc465c8402c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Nov 2012 13:28:00 +0000 Subject: staging:iio:adis16203: Use adis library Use the new adis library for the adis16203 driver. This allows us to completely scrap the adis16203 buffer and trigger code and more than half of the core driver code. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/Kconfig | 4 +- drivers/staging/iio/accel/Makefile | 1 - drivers/staging/iio/accel/adis16203.h | 80 +---- drivers/staging/iio/accel/adis16203_core.c | 425 ++++---------------------- drivers/staging/iio/accel/adis16203_ring.c | 136 --------- drivers/staging/iio/accel/adis16203_trigger.c | 73 ----- 6 files changed, 66 insertions(+), 653 deletions(-) delete mode 100644 drivers/staging/iio/accel/adis16203_ring.c delete mode 100644 drivers/staging/iio/accel/adis16203_trigger.c diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index 0e965e50534..48755a209a3 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -15,8 +15,8 @@ config ADIS16201 config ADIS16203 tristate "Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer" depends on SPI - select IIO_TRIGGER if IIO_BUFFER - select IIO_SW_RING if IIO_BUFFER + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help Say yes here to build support for Analog Devices adis16203 Programmable 360 Degrees Inclinometer. diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index 22dbebd83e0..28746b8fa28 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -6,7 +6,6 @@ adis16201-y := adis16201_core.o obj-$(CONFIG_ADIS16201) += adis16201.o adis16203-y := adis16203_core.o -adis16203-$(CONFIG_IIO_BUFFER) += adis16203_ring.o adis16203_trigger.o obj-$(CONFIG_ADIS16203) += adis16203.o adis16204-y := adis16204_core.o diff --git a/drivers/staging/iio/accel/adis16203.h b/drivers/staging/iio/accel/adis16203.h index 3f96ad3bbd6..acc688d7ea9 100644 --- a/drivers/staging/iio/accel/adis16203.h +++ b/drivers/staging/iio/accel/adis16203.h @@ -3,9 +3,6 @@ #define ADIS16203_STARTUP_DELAY 220 /* ms */ -#define ADIS16203_READ_REG(a) a -#define ADIS16203_WRITE_REG(a) ((a) | 0x80) - #define ADIS16203_FLASH_CNT 0x00 /* Flash memory write count */ #define ADIS16203_SUPPLY_OUT 0x02 /* Output, power supply */ #define ADIS16203_AUX_ADC 0x08 /* Output, auxiliary ADC input */ @@ -27,8 +24,6 @@ #define ADIS16203_DIAG_STAT 0x3C /* Diagnostics, system status register */ #define ADIS16203_GLOB_CMD 0x3E /* Operation, system command register */ -#define ADIS16203_OUTPUTS 5 - /* MSC_CTRL */ #define ADIS16203_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) /* Self-test at power-on: 1 = disabled, 0 = enabled */ #define ADIS16203_MSC_CTRL_REVERSE_ROT_EN (1 << 9) /* Reverses rotation of both inclination outputs */ @@ -40,86 +35,25 @@ /* DIAG_STAT */ #define ADIS16203_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16203_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16203_DIAG_STAT_SELFTEST_FAIL (1<<5) /* Self-test diagnostic error flag */ -#define ADIS16203_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */ -#define ADIS16203_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */ -#define ADIS16203_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */ -#define ADIS16203_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 3.15 V */ +#define ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT 5 /* Self-test diagnostic error flag */ +#define ADIS16203_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */ +#define ADIS16203_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */ +#define ADIS16203_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */ +#define ADIS16203_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 3.15 V */ /* GLOB_CMD */ #define ADIS16203_GLOB_CMD_SW_RESET (1<<7) #define ADIS16203_GLOB_CMD_CLEAR_STAT (1<<4) #define ADIS16203_GLOB_CMD_FACTORY_CAL (1<<1) -#define ADIS16203_MAX_TX 12 -#define ADIS16203_MAX_RX 10 - #define ADIS16203_ERROR_ACTIVE (1<<14) -/** - * struct adis16203_state - device instance specific data - * @us: actual spi_device - * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16203_state { - struct spi_device *us; - struct iio_trigger *trig; - struct mutex buf_lock; - u8 tx[ADIS16203_MAX_TX] ____cacheline_aligned; - u8 rx[ADIS16203_MAX_RX]; -}; - -int adis16203_set_irq(struct iio_dev *indio_dev, bool enable); - enum adis16203_scan { + ADIS16203_SCAN_INCLI_X, + ADIS16203_SCAN_INCLI_Y, ADIS16203_SCAN_SUPPLY, ADIS16203_SCAN_AUX_ADC, ADIS16203_SCAN_TEMP, - ADIS16203_SCAN_INCLI_X, - ADIS16203_SCAN_INCLI_Y, }; -#ifdef CONFIG_IIO_BUFFER -void adis16203_remove_trigger(struct iio_dev *indio_dev); -int adis16203_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16203_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - -int adis16203_configure_ring(struct iio_dev *indio_dev); -void adis16203_unconfigure_ring(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline void adis16203_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16203_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16203_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16203_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16203_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -#endif /* CONFIG_IIO_BUFFER */ #endif /* SPI_ADIS16203_H_ */ diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 7d7c4d28f6f..326b1067543 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -1,7 +1,7 @@ /* * ADIS16203 Programmable Digital Vibration Sensor driver * - * Copyright 2010 Analog Devices Inc. + * Copyright 2030 Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -20,250 +20,12 @@ #include #include "adis16203.h" +#include "../imu/adis.h" -/** - * adis16203_spi_write_reg_8() - write single byte to a register - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16203_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16203_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16203_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16203_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16203_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16203_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16203_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16203_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16203_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16203_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16203_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 20, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 20, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16203_READ_REG(lower_reg_address); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static int adis16203_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - - ret = adis16203_spi_read_reg_16(indio_dev, - ADIS16203_DIAG_STAT, - &status); - if (ret < 0) { - dev_err(&indio_dev->dev, "Reading status failed\n"); - goto error_ret; - } - ret = status & 0x1F; - - if (status & ADIS16203_DIAG_STAT_SELFTEST_FAIL) - dev_err(&indio_dev->dev, "Self test failure\n"); - if (status & ADIS16203_DIAG_STAT_SPI_FAIL) - dev_err(&indio_dev->dev, "SPI failure\n"); - if (status & ADIS16203_DIAG_STAT_FLASH_UPT) - dev_err(&indio_dev->dev, "Flash update failed\n"); - if (status & ADIS16203_DIAG_STAT_POWER_HIGH) - dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); - if (status & ADIS16203_DIAG_STAT_POWER_LOW) - dev_err(&indio_dev->dev, "Power supply below 3.15V\n"); - -error_ret: - return ret; -} - -static int adis16203_reset(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16203_spi_write_reg_8(indio_dev, - ADIS16203_GLOB_CMD, - ADIS16203_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&indio_dev->dev, "problem resetting device"); - - return ret; -} - -int adis16203_set_irq(struct iio_dev *indio_dev, bool enable) -{ - int ret = 0; - u16 msc; - - ret = adis16203_spi_read_reg_16(indio_dev, ADIS16203_MSC_CTRL, &msc); - if (ret) - goto error_ret; - - msc |= ADIS16203_MSC_CTRL_ACTIVE_HIGH; - msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_DIO1; - if (enable) - msc |= ADIS16203_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_EN; +#define DRIVER_NAME "adis16203" - ret = adis16203_spi_write_reg_16(indio_dev, ADIS16203_MSC_CTRL, msc); - -error_ret: - return ret; -} - -static int adis16203_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16203_spi_write_reg_16(indio_dev, - ADIS16203_MSC_CTRL, - ADIS16203_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - adis16203_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16203_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - - /* Disable IRQ */ - ret = adis16203_set_irq(indio_dev, false); - if (ret) { - dev_err(&indio_dev->dev, "disable irq failed"); - goto err_ret; - } - - /* Do self test */ - ret = adis16203_self_test(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16203_check_status(indio_dev); - if (ret) { - adis16203_reset(indio_dev); - dev_err(&indio_dev->dev, "device not playing ball -> reset"); - msleep(ADIS16203_STARTUP_DELAY); - ret = adis16203_check_status(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} - -enum adis16203_chan { - in_supply, - in_aux, - incli_x, - incli_y, - temp, -}; - -static u8 adis16203_addresses[5][2] = { - [in_supply] = { ADIS16203_SUPPLY_OUT }, - [in_aux] = { ADIS16203_AUX_ADC }, - [incli_x] = { ADIS16203_XINCL_OUT, ADIS16203_INCL_NULL}, - [incli_y] = { ADIS16203_YINCL_OUT }, - [temp] = { ADIS16203_TEMP_OUT } +static const u8 adis16203_addresses[] = { + [ADIS16203_SCAN_INCLI_X] = ADIS16203_INCL_NULL, }; static int adis16203_write_raw(struct iio_dev *indio_dev, @@ -272,9 +34,10 @@ static int adis16203_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct adis *st = iio_priv(indio_dev); /* currently only one writable parameter which keeps this simple */ - u8 addr = adis16203_addresses[chan->address][1]; - return adis16203_spi_write_reg_16(indio_dev, addr, val & 0x3FFF); + u8 addr = adis16203_addresses[chan->scan_index]; + return adis_write_reg_16(st, addr, val & 0x3FFF); } static int adis16203_read_raw(struct iio_dev *indio_dev, @@ -282,35 +45,15 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { + struct adis *st = iio_priv(indio_dev); int ret; int bits; u8 addr; s16 val16; switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - addr = adis16203_addresses[chan->address][0]; - ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - - if (val16 & ADIS16203_ERROR_ACTIVE) { - ret = adis16203_check_status(indio_dev); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - } - val16 = val16 & ((1 << chan->scan_type.realbits) - 1); - if (chan->scan_type.sign == 's') - val16 = (s16)(val16 << - (16 - chan->scan_type.realbits)) >> - (16 - chan->scan_type.realbits); - *val = val16; - mutex_unlock(&indio_dev->mlock); - return IIO_VAL_INT; + return adis_single_conversion(indio_dev, chan, + ADIS16203_ERROR_ACTIVE, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: @@ -339,8 +82,8 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_CALIBBIAS: bits = 14; mutex_lock(&indio_dev->mlock); - addr = adis16203_addresses[chan->address][1]; - ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16203_addresses[chan->scan_index]; + ret = adis_read_reg_16(st, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -356,75 +99,13 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, } static const struct iio_chan_spec adis16203_channels[] = { - { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_supply, - .scan_index = ADIS16203_SCAN_SUPPLY, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_aux, - .scan_index = ADIS16203_SCAN_AUX_ADC, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_INCLI, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = incli_x, - .scan_index = ADIS16203_SCAN_INCLI_X, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { /* Fixme: Not what it appears to be - see data sheet */ - .type = IIO_INCLI, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = incli_y, - .scan_index = ADIS16203_SCAN_INCLI_Y, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - .address = temp, - .scan_index = ADIS16203_SCAN_TEMP, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, + ADIS_SUPPLY_CHAN(ADIS16203_SUPPLY_OUT, ADIS16203_SCAN_SUPPLY, 12), + ADIS_AUX_ADC_CHAN(ADIS16203_AUX_ADC, ADIS16203_SCAN_AUX_ADC, 12), + ADIS_INCLI_CHAN(X, ADIS16203_XINCL_OUT, ADIS16203_SCAN_INCLI_X, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + /* Fixme: Not what it appears to be - see data sheet */ + ADIS_INCLI_CHAN(Y, ADIS16203_YINCL_OUT, ADIS16203_SCAN_INCLI_Y, 0, 14), + ADIS_TEMP_CHAN(ADIS16203_TEMP_OUT, ADIS16203_SCAN_TEMP, 12), IIO_CHAN_SOFT_TIMESTAMP(5), }; @@ -434,11 +115,36 @@ static const struct iio_info adis16203_info = { .driver_module = THIS_MODULE, }; +static const char * const adis16203_status_error_msgs[] = { + [ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure", + [ADIS16203_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16203_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16203_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", + [ADIS16203_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", +}; + +static const struct adis_data adis16203_data = { + .read_delay = 20, + .msc_ctrl_reg = ADIS16203_MSC_CTRL, + .glob_cmd_reg = ADIS16203_GLOB_CMD, + .diag_stat_reg = ADIS16203_DIAG_STAT, + + .self_test_mask = ADIS16203_MSC_CTRL_SELF_TEST_EN, + .startup_delay = ADIS16203_STARTUP_DELAY, + + .status_error_msgs = adis16203_status_error_msgs, + .status_error_mask = BIT(ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT) | + BIT(ADIS16203_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16203_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16203_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16203_DIAG_STAT_POWER_LOW_BIT), +}; + static int __devinit adis16203_probe(struct spi_device *spi) { int ret; struct iio_dev *indio_dev; - struct adis16203_state *st; + struct adis *st; /* setup the industrialio driver allocated elements */ indio_dev = iio_device_alloc(sizeof(*st)); @@ -449,8 +155,6 @@ static int __devinit adis16203_probe(struct spi_device *spi) st = iio_priv(indio_dev); /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; @@ -459,41 +163,27 @@ static int __devinit adis16203_probe(struct spi_device *spi) indio_dev->info = &adis16203_info; indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16203_configure_ring(indio_dev); + ret = adis_init(st, indio_dev, spi, &adis16203_data); if (ret) goto error_free_dev; - ret = iio_buffer_register(indio_dev, - adis16203_channels, - ARRAY_SIZE(adis16203_channels)); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = adis16203_probe_trigger(indio_dev); - if (ret) - goto error_uninitialize_ring; - } + ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + if (ret) + goto error_free_dev; /* Get the device into a sane initial state */ - ret = adis16203_initial_setup(indio_dev); + ret = adis_initial_startup(st); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; ret = iio_device_register(indio_dev); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; return 0; -error_remove_trigger: - adis16203_remove_trigger(indio_dev); -error_uninitialize_ring: - iio_buffer_unregister(indio_dev); -error_unreg_ring_funcs: - adis16203_unconfigure_ring(indio_dev); +error_cleanup_buffer_trigger: + adis_cleanup_buffer_and_trigger(st, indio_dev); error_free_dev: iio_device_free(indio_dev); error_ret: @@ -503,11 +193,10 @@ error_ret: static int __devexit adis16203_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - adis16203_remove_trigger(indio_dev); - iio_buffer_unregister(indio_dev); - adis16203_unconfigure_ring(indio_dev); + adis_cleanup_buffer_and_trigger(st, indio_dev); iio_device_free(indio_dev); return 0; diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c deleted file mode 100644 index eba2e285c84..00000000000 --- a/drivers/staging/iio/accel/adis16203_ring.c +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include "../ring_sw.h" -#include -#include "adis16203.h" - -/** - * adis16203_read_ring_data() read data registers which will be placed into ring - * @indio_dev: the IIO device - * @rx: somewhere to pass back the value read - **/ -static int adis16203_read_ring_data(struct iio_dev *indio_dev, u8 *rx) -{ - struct spi_message msg; - struct adis16203_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[ADIS16203_OUTPUTS + 1]; - int ret; - int i; - - mutex_lock(&st->buf_lock); - - spi_message_init(&msg); - - memset(xfers, 0, sizeof(xfers)); - for (i = 0; i <= ADIS16203_OUTPUTS; i++) { - xfers[i].bits_per_word = 8; - xfers[i].cs_change = 1; - xfers[i].len = 2; - xfers[i].delay_usecs = 20; - xfers[i].tx_buf = st->tx + 2 * i; - if (i < 1) /* SUPPLY_OUT: 0x02, AUX_ADC: 0x08 */ - st->tx[2 * i] = ADIS16203_READ_REG(ADIS16203_SUPPLY_OUT + 2 * i); - else - st->tx[2 * i] = ADIS16203_READ_REG(ADIS16203_SUPPLY_OUT + 2 * i + 6); - st->tx[2 * i + 1] = 0; - if (i >= 1) - xfers[i].rx_buf = rx + 2 * (i - 1); - spi_message_add_tail(&xfers[i], &msg); - } - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when burst reading"); - - mutex_unlock(&st->buf_lock); - - return ret; -} - -/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device - * specific to be rolled into the core. - */ -static irqreturn_t adis16203_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct adis16203_state *st = iio_priv(indio_dev); - - int i = 0; - s16 *data; - - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (data == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - goto done; - } - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16203_read_ring_data(indio_dev, st->rx) >= 0) - for (; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - - iio_push_to_buffers(indio_dev, (u8 *)data); - - kfree(data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -void adis16203_unconfigure_ring(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); -} - -static const struct iio_buffer_setup_ops adis16203_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -int adis16203_configure_ring(struct iio_dev *indio_dev) -{ - int ret = 0; - struct iio_buffer *ring; - - ring = iio_sw_rb_allocate(indio_dev); - if (!ring) { - ret = -ENOMEM; - return ret; - } - indio_dev->buffer = ring; - ring->scan_timestamp = true; - indio_dev->setup_ops = &adis16203_ring_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &adis16203_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "adis16203_consumer%d", - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->buffer); - return ret; -} diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c deleted file mode 100644 index b8a04073d6d..00000000000 --- a/drivers/staging/iio/accel/adis16203_trigger.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include "adis16203.h" - -/** - * adis16203_data_rdy_trigger_set_state() set datardy interrupt state - **/ -static int adis16203_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct iio_dev *indio_dev = trig->private_data; - - dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16203_set_irq(indio_dev, state); -} - -static const struct iio_trigger_ops adis16203_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &adis16203_data_rdy_trigger_set_state, -}; - -int adis16203_probe_trigger(struct iio_dev *indio_dev) -{ - int ret; - struct adis16203_state *st = iio_priv(indio_dev); - - st->trig = iio_trigger_alloc("adis16203-dev%d", indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - ret = request_irq(st->us->irq, - &iio_trigger_generic_data_rdy_poll, - IRQF_TRIGGER_RISING, - "adis16203", - st->trig); - if (ret) - goto error_free_trig; - - st->trig->dev.parent = &st->us->dev; - st->trig->ops = &adis16203_trigger_ops; - st->trig->private_data = indio_dev; - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->us->irq, st->trig); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -void adis16203_remove_trigger(struct iio_dev *indio_dev) -{ - struct adis16203_state *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); - free_irq(st->us->irq, st->trig); - iio_trigger_free(st->trig); -} -- cgit v1.2.3 From 5bd22f516e43617edc80c56c9e4c44426aa36a2f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Nov 2012 13:28:00 +0000 Subject: staging:iio:adis16204: Use adis library Use the new adis library for the adis16204 driver. This allows us to completely scrap the adis16204 buffer and trigger code and more than half of the core driver code. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/Kconfig | 4 +- drivers/staging/iio/accel/Makefile | 1 - drivers/staging/iio/accel/adis16204.h | 79 +---- drivers/staging/iio/accel/adis16204_core.c | 451 ++++---------------------- drivers/staging/iio/accel/adis16204_ring.c | 134 -------- drivers/staging/iio/accel/adis16204_trigger.c | 73 ----- 6 files changed, 70 insertions(+), 672 deletions(-) delete mode 100644 drivers/staging/iio/accel/adis16204_ring.c delete mode 100644 drivers/staging/iio/accel/adis16204_trigger.c diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index 48755a209a3..85f8db9c02b 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -24,8 +24,8 @@ config ADIS16203 config ADIS16204 tristate "Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder" depends on SPI - select IIO_TRIGGER if IIO_BUFFER - select IIO_SW_RING if IIO_BUFFER + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help Say yes here to build support for Analog Devices adis16204 Programmable High-g Digital Impact Sensor and Recorder. diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index 28746b8fa28..581a48b27d9 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -9,7 +9,6 @@ adis16203-y := adis16203_core.o obj-$(CONFIG_ADIS16203) += adis16203.o adis16204-y := adis16204_core.o -adis16204-$(CONFIG_IIO_BUFFER) += adis16204_ring.o adis16204_trigger.o obj-$(CONFIG_ADIS16204) += adis16204.o adis16209-y := adis16209_core.o diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h index 7cf4e91f83a..9ff950c1e8d 100644 --- a/drivers/staging/iio/accel/adis16204.h +++ b/drivers/staging/iio/accel/adis16204.h @@ -3,9 +3,6 @@ #define ADIS16204_STARTUP_DELAY 220 /* ms */ -#define ADIS16204_READ_REG(a) a -#define ADIS16204_WRITE_REG(a) ((a) | 0x80) - #define ADIS16204_FLASH_CNT 0x00 /* Flash memory write count */ #define ADIS16204_SUPPLY_OUT 0x02 /* Output, power supply */ #define ADIS16204_XACCL_OUT 0x04 /* Output, x-axis accelerometer */ @@ -35,8 +32,6 @@ #define ADIS16204_DIAG_STAT 0x3C /* Diagnostics, system status register */ #define ADIS16204_GLOB_CMD 0x3E /* Operation, system command register */ -#define ADIS16204_OUTPUTS 5 - /* MSC_CTRL */ #define ADIS16204_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) /* Self-test at power-on: 1 = disabled, 0 = enabled */ #define ADIS16204_MSC_CTRL_SELF_TEST_EN (1 << 8) /* Self-test enable */ @@ -47,87 +42,27 @@ /* DIAG_STAT */ #define ADIS16204_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16204_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ -#define ADIS16204_DIAG_STAT_SELFTEST_FAIL (1<<5) /* Self-test diagnostic error flag: 1 = error condition, +#define ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT 5 /* Self-test diagnostic error flag: 1 = error condition, 0 = normal operation */ -#define ADIS16204_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */ -#define ADIS16204_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */ -#define ADIS16204_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */ -#define ADIS16204_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 2.975 V */ +#define ADIS16204_DIAG_STAT_SPI_FAIL_BIT 3 /* SPI communications failure */ +#define ADIS16204_DIAG_STAT_FLASH_UPT_BIT 2 /* Flash update failure */ +#define ADIS16204_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply above 3.625 V */ +#define ADIS16204_DIAG_STAT_POWER_LOW_BIT 0 /* Power supply below 2.975 V */ /* GLOB_CMD */ #define ADIS16204_GLOB_CMD_SW_RESET (1<<7) #define ADIS16204_GLOB_CMD_CLEAR_STAT (1<<4) #define ADIS16204_GLOB_CMD_FACTORY_CAL (1<<1) -#define ADIS16204_MAX_TX 24 -#define ADIS16204_MAX_RX 24 - #define ADIS16204_ERROR_ACTIVE (1<<14) -/** - * struct adis16204_state - device instance specific data - * @us: actual spi_device - * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16204_state { - struct spi_device *us; - struct iio_trigger *trig; - struct mutex buf_lock; - u8 tx[ADIS16204_MAX_TX] ____cacheline_aligned; - u8 rx[ADIS16204_MAX_RX]; -}; - -int adis16204_set_irq(struct iio_dev *indio_dev, bool enable); - enum adis16204_scan { - ADIS16204_SCAN_SUPPLY, ADIS16204_SCAN_ACC_X, ADIS16204_SCAN_ACC_Y, + ADIS16204_SCAN_ACC_XY, + ADIS16204_SCAN_SUPPLY, ADIS16204_SCAN_AUX_ADC, ADIS16204_SCAN_TEMP, }; -#ifdef CONFIG_IIO_BUFFER -void adis16204_remove_trigger(struct iio_dev *indio_dev); -int adis16204_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16204_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - -int adis16204_configure_ring(struct iio_dev *indio_dev); -void adis16204_unconfigure_ring(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline void adis16204_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16204_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16204_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16204_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16204_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -#endif /* CONFIG_IIO_BUFFER */ #endif /* SPI_ADIS16204_H_ */ diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 9b75a2bc8cb..4f69ead1ae8 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -23,257 +23,14 @@ #include #include "adis16204.h" - -/** - * adis16204_spi_write_reg_8() - write single byte to a register - * @dev: device associated with child of actual device (iio_dev or iio_trig) - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16204_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16204_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16204_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16204_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16204_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16204_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16204_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16204_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16204_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16204_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16204_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 20, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 20, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16204_READ_REG(lower_reg_address); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static int adis16204_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - - ret = adis16204_spi_read_reg_16(indio_dev, - ADIS16204_DIAG_STAT, &status); - if (ret < 0) { - dev_err(&indio_dev->dev, "Reading status failed\n"); - goto error_ret; - } - ret = status & 0x1F; - - if (status & ADIS16204_DIAG_STAT_SELFTEST_FAIL) - dev_err(&indio_dev->dev, "Self test failure\n"); - if (status & ADIS16204_DIAG_STAT_SPI_FAIL) - dev_err(&indio_dev->dev, "SPI failure\n"); - if (status & ADIS16204_DIAG_STAT_FLASH_UPT) - dev_err(&indio_dev->dev, "Flash update failed\n"); - if (status & ADIS16204_DIAG_STAT_POWER_HIGH) - dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); - if (status & ADIS16204_DIAG_STAT_POWER_LOW) - dev_err(&indio_dev->dev, "Power supply below 2.975V\n"); - -error_ret: - return ret; -} - -static int adis16204_reset(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16204_spi_write_reg_8(indio_dev, - ADIS16204_GLOB_CMD, - ADIS16204_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&indio_dev->dev, "problem resetting device"); - - return ret; -} - -int adis16204_set_irq(struct iio_dev *indio_dev, bool enable) -{ - int ret = 0; - u16 msc; - - ret = adis16204_spi_read_reg_16(indio_dev, ADIS16204_MSC_CTRL, &msc); - if (ret) - goto error_ret; - - msc |= ADIS16204_MSC_CTRL_ACTIVE_HIGH; - msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_DIO2; - if (enable) - msc |= ADIS16204_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_EN; - - ret = adis16204_spi_write_reg_16(indio_dev, ADIS16204_MSC_CTRL, msc); - -error_ret: - return ret; -} - -static int adis16204_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16204_spi_write_reg_16(indio_dev, - ADIS16204_MSC_CTRL, - ADIS16204_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - adis16204_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16204_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - - /* Disable IRQ */ - ret = adis16204_set_irq(indio_dev, false); - if (ret) { - dev_err(&indio_dev->dev, "disable irq failed"); - goto err_ret; - } - - /* Do self test */ - ret = adis16204_self_test(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16204_check_status(indio_dev); - if (ret) { - adis16204_reset(indio_dev); - dev_err(&indio_dev->dev, "device not playing ball -> reset"); - msleep(ADIS16204_STARTUP_DELAY); - ret = adis16204_check_status(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} +#include "../imu/adis.h" /* Unique to this driver currently */ -enum adis16204_channel { - in_supply, - in_aux, - temp, - accel_x, - accel_y, - accel_xy, -}; - -static u8 adis16204_addresses[6][3] = { - [in_supply] = { ADIS16204_SUPPLY_OUT }, - [in_aux] = { ADIS16204_AUX_ADC }, - [temp] = { ADIS16204_TEMP_OUT }, - [accel_x] = { ADIS16204_XACCL_OUT, ADIS16204_XACCL_NULL, - ADIS16204_X_PEAK_OUT }, - [accel_y] = { ADIS16204_XACCL_OUT, ADIS16204_YACCL_NULL, - ADIS16204_Y_PEAK_OUT }, - [accel_xy] = { ADIS16204_XY_RSS_OUT, 0, - ADIS16204_XY_PEAK_OUT }, +static const u8 adis16204_addresses[][2] = { + [ADIS16204_SCAN_ACC_X] = { ADIS16204_XACCL_NULL, ADIS16204_X_PEAK_OUT }, + [ADIS16204_SCAN_ACC_Y] = { ADIS16204_YACCL_NULL, ADIS16204_Y_PEAK_OUT }, + [ADIS16204_SCAN_ACC_XY] = { 0, ADIS16204_XY_PEAK_OUT }, }; static int adis16204_read_raw(struct iio_dev *indio_dev, @@ -281,6 +38,7 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { + struct adis *st = iio_priv(indio_dev); int ret; int bits; u8 addr; @@ -289,29 +47,8 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - addr = adis16204_addresses[chan->address][0]; - ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - - if (val16 & ADIS16204_ERROR_ACTIVE) { - ret = adis16204_check_status(indio_dev); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - } - val16 = val16 & ((1 << chan->scan_type.realbits) - 1); - if (chan->scan_type.sign == 's') - val16 = (s16)(val16 << - (16 - chan->scan_type.realbits)) >> - (16 - chan->scan_type.realbits); - *val = val16; - mutex_unlock(&indio_dev->mlock); - return IIO_VAL_INT; + return adis_single_conversion(indio_dev, chan, + ADIS16204_ERROR_ACTIVE, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: @@ -351,14 +88,14 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_PEAK: if (mask == IIO_CHAN_INFO_CALIBBIAS) { bits = 12; - addrind = 1; + addrind = 0; } else { /* PEAK_SEPARATE */ bits = 14; - addrind = 2; + addrind = 1; } mutex_lock(&indio_dev->mlock); - addr = adis16204_addresses[chan->address][addrind]; - ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16204_addresses[chan->scan_index][addrind]; + ret = adis_read_reg_16(st, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -378,6 +115,7 @@ static int adis16204_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct adis *st = iio_priv(indio_dev); int bits; s16 val16; u8 addr; @@ -391,100 +129,25 @@ static int adis16204_write_raw(struct iio_dev *indio_dev, return -EINVAL; } val16 = val & ((1 << bits) - 1); - addr = adis16204_addresses[chan->address][1]; - return adis16204_spi_write_reg_16(indio_dev, addr, val16); + addr = adis16204_addresses[chan->scan_index][1]; + return adis_write_reg_16(st, addr, val16); } return -EINVAL; } static const struct iio_chan_spec adis16204_channels[] = { - { - .type = IIO_VOLTAGE, - .indexed = 1, /* Note was not previously indexed */ - .channel = 0, - .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_supply, - .scan_index = ADIS16204_SCAN_SUPPLY, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_aux, - .scan_index = ADIS16204_SCAN_AUX_ADC, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - .address = temp, - .scan_index = ADIS16204_SCAN_TEMP, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + ADIS_SUPPLY_CHAN(ADIS16204_SUPPLY_OUT, ADIS16204_SCAN_SUPPLY, 12), + ADIS_AUX_ADC_CHAN(ADIS16204_AUX_ADC, ADIS16204_SCAN_AUX_ADC, 12), + ADIS_TEMP_CHAN(ADIS16204_TEMP_OUT, ADIS16204_SCAN_TEMP, 12), + ADIS_ACCEL_CHAN(X, ADIS16204_XACCL_OUT, ADIS16204_SCAN_ACC_X, IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - .address = accel_x, - .scan_index = ADIS16204_SCAN_ACC_X, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 14), + ADIS_ACCEL_CHAN(Y, ADIS16204_YACCL_OUT, ADIS16204_SCAN_ACC_Y, IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - .address = accel_y, - .scan_index = ADIS16204_SCAN_ACC_Y, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 14), + ADIS_ACCEL_CHAN(ROOT_SUM_SQUARED_X_Y, ADIS16204_XY_RSS_OUT, + ADIS16204_SCAN_ACC_XY, IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 14), IIO_CHAN_SOFT_TIMESTAMP(5), - { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_ROOT_SUM_SQUARED_X_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - .address = accel_xy, - .scan_type = { - .sign = 'u', - .realbits = 14, - .storagebits = 16, - }, - } }; static const struct iio_info adis16204_info = { @@ -493,10 +156,35 @@ static const struct iio_info adis16204_info = { .driver_module = THIS_MODULE, }; +static const char * const adis16204_status_error_msgs[] = { + [ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure", + [ADIS16204_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16204_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16204_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", + [ADIS16204_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.975V", +}; + +static const struct adis_data adis16204_data = { + .read_delay = 20, + .msc_ctrl_reg = ADIS16204_MSC_CTRL, + .glob_cmd_reg = ADIS16204_GLOB_CMD, + .diag_stat_reg = ADIS16204_DIAG_STAT, + + .self_test_mask = ADIS16204_MSC_CTRL_SELF_TEST_EN, + .startup_delay = ADIS16204_STARTUP_DELAY, + + .status_error_msgs = adis16204_status_error_msgs, + .status_error_mask = BIT(ADIS16204_DIAG_STAT_SELFTEST_FAIL_BIT) | + BIT(ADIS16204_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16204_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16204_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16204_DIAG_STAT_POWER_LOW_BIT), +}; + static int __devinit adis16204_probe(struct spi_device *spi) { int ret; - struct adis16204_state *st; + struct adis *st; struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ @@ -508,8 +196,6 @@ static int __devinit adis16204_probe(struct spi_device *spi) st = iio_priv(indio_dev); /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; @@ -518,40 +204,26 @@ static int __devinit adis16204_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(adis16204_channels); indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16204_configure_ring(indio_dev); + ret = adis_init(st, indio_dev, spi, &adis16204_data); if (ret) goto error_free_dev; - ret = iio_buffer_register(indio_dev, - adis16204_channels, - 6); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = adis16204_probe_trigger(indio_dev); - if (ret) - goto error_uninitialize_ring; - } + ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); + if (ret) + goto error_free_dev; /* Get the device into a sane initial state */ - ret = adis16204_initial_setup(indio_dev); + ret = adis_initial_startup(st); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; ret = iio_device_register(indio_dev); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; return 0; -error_remove_trigger: - adis16204_remove_trigger(indio_dev); -error_uninitialize_ring: - iio_buffer_unregister(indio_dev); -error_unreg_ring_funcs: - adis16204_unconfigure_ring(indio_dev); +error_cleanup_buffer_trigger: + adis_cleanup_buffer_and_trigger(st, indio_dev); error_free_dev: iio_device_free(indio_dev); error_ret: @@ -561,11 +233,10 @@ error_ret: static int __devexit adis16204_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - adis16204_remove_trigger(indio_dev); - iio_buffer_unregister(indio_dev); - adis16204_unconfigure_ring(indio_dev); + adis_cleanup_buffer_and_trigger(st, indio_dev); iio_device_free(indio_dev); return 0; diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c deleted file mode 100644 index 3611a13836c..00000000000 --- a/drivers/staging/iio/accel/adis16204_ring.c +++ /dev/null @@ -1,134 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include "../ring_sw.h" -#include -#include "adis16204.h" - -/** - * adis16204_read_ring_data() read data registers which will be placed into ring - * @indio_dev: the IIO device - * @rx: somewhere to pass back the value read - **/ -static int adis16204_read_ring_data(struct iio_dev *indio_dev, u8 *rx) -{ - struct spi_message msg; - struct adis16204_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[ADIS16204_OUTPUTS + 1]; - int ret; - int i; - - mutex_lock(&st->buf_lock); - - spi_message_init(&msg); - - memset(xfers, 0, sizeof(xfers)); - for (i = 0; i <= ADIS16204_OUTPUTS; i++) { - xfers[i].bits_per_word = 8; - xfers[i].cs_change = 1; - xfers[i].len = 2; - xfers[i].delay_usecs = 20; - xfers[i].tx_buf = st->tx + 2 * i; - st->tx[2 * i] - = ADIS16204_READ_REG(ADIS16204_SUPPLY_OUT + 2 * i); - st->tx[2 * i + 1] = 0; - if (i >= 1) - xfers[i].rx_buf = rx + 2 * (i - 1); - spi_message_add_tail(&xfers[i], &msg); - } - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when burst reading"); - - mutex_unlock(&st->buf_lock); - - return ret; -} - -/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device - * specific to be rolled into the core. - */ -static irqreturn_t adis16204_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct adis16204_state *st = iio_priv(indio_dev); - int i = 0; - s16 *data; - - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (data == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - goto done; - } - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16204_read_ring_data(indio_dev, st->rx) >= 0) - for (; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - - iio_push_to_buffers(indio_dev, (u8 *)data); - - kfree(data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -void adis16204_unconfigure_ring(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); -} - -static const struct iio_buffer_setup_ops adis16204_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -int adis16204_configure_ring(struct iio_dev *indio_dev) -{ - int ret = 0; - struct iio_buffer *ring; - - ring = iio_sw_rb_allocate(indio_dev); - if (!ring) { - ret = -ENOMEM; - return ret; - } - indio_dev->buffer = ring; - ring->scan_timestamp = true; - indio_dev->setup_ops = &adis16204_ring_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &adis16204_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "%s_consumer%d", - indio_dev->name, - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->buffer); - return ret; -} diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c deleted file mode 100644 index 408a1682368..00000000000 --- a/drivers/staging/iio/accel/adis16204_trigger.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include "adis16204.h" - -/** - * adis16204_data_rdy_trigger_set_state() set datardy interrupt state - **/ -static int adis16204_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct iio_dev *indio_dev = trig->private_data; - - dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16204_set_irq(indio_dev, state); -} - -static const struct iio_trigger_ops adis16204_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &adis16204_data_rdy_trigger_set_state, -}; - -int adis16204_probe_trigger(struct iio_dev *indio_dev) -{ - int ret; - struct adis16204_state *st = iio_priv(indio_dev); - - st->trig = iio_trigger_alloc("adis16204-dev%d", indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - ret = request_irq(st->us->irq, - &iio_trigger_generic_data_rdy_poll, - IRQF_TRIGGER_RISING, - "adis16204", - st->trig); - if (ret) - goto error_free_trig; - - st->trig->dev.parent = &st->us->dev; - st->trig->ops = &adis16204_trigger_ops; - st->trig->private_data = indio_dev; - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->us->irq, st->trig); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -void adis16204_remove_trigger(struct iio_dev *indio_dev) -{ - struct adis16204_state *state = iio_priv(indio_dev); - - iio_trigger_unregister(state->trig); - free_irq(state->us->irq, state->trig); - iio_trigger_free(state->trig); -} -- cgit v1.2.3 From 511fb29e351ae90b0ad7341f3729468003449ac4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Nov 2012 13:28:00 +0000 Subject: staging:iio:adis16209: Use adis library Use the new adis library for the adis16209 driver. This allows us to completely scrap the adis16209 buffer and trigger code and more than half of the core driver code. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/Kconfig | 4 +- drivers/staging/iio/accel/Makefile | 1 - drivers/staging/iio/accel/adis16209.h | 77 +--- drivers/staging/iio/accel/adis16209_core.c | 485 ++++---------------------- drivers/staging/iio/accel/adis16209_ring.c | 134 ------- drivers/staging/iio/accel/adis16209_trigger.c | 72 ---- 6 files changed, 74 insertions(+), 699 deletions(-) delete mode 100644 drivers/staging/iio/accel/adis16209_ring.c delete mode 100644 drivers/staging/iio/accel/adis16209_trigger.c diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index 85f8db9c02b..affa732ef51 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -33,8 +33,8 @@ config ADIS16204 config ADIS16209 tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer" depends on SPI - select IIO_TRIGGER if IIO_BUFFER - select IIO_SW_RING if IIO_BUFFER + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help Say yes here to build support for Analog Devices adis16209 dual-axis digital inclinometer and accelerometer. diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index 581a48b27d9..3cb9c67a29b 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -12,7 +12,6 @@ adis16204-y := adis16204_core.o obj-$(CONFIG_ADIS16204) += adis16204.o adis16209-y := adis16209_core.o -adis16209-$(CONFIG_IIO_BUFFER) += adis16209_ring.o adis16209_trigger.o obj-$(CONFIG_ADIS16209) += adis16209.o adis16220-y := adis16220_core.o diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h index 3c88b86e7b8..ad3945a0629 100644 --- a/drivers/staging/iio/accel/adis16209.h +++ b/drivers/staging/iio/accel/adis16209.h @@ -3,9 +3,6 @@ #define ADIS16209_STARTUP_DELAY 220 /* ms */ -#define ADIS16209_READ_REG(a) a -#define ADIS16209_WRITE_REG(a) ((a) | 0x80) - /* Flash memory write count */ #define ADIS16209_FLASH_CNT 0x00 /* Output, power supply */ @@ -61,8 +58,6 @@ /* Operation, system command register */ #define ADIS16209_GLOB_CMD 0x3E -#define ADIS16209_OUTPUTS 8 - /* MSC_CTRL */ /* Self-test at power-on: 1 = disabled, 0 = enabled */ #define ADIS16209_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) @@ -81,44 +76,23 @@ /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ #define ADIS16209_DIAG_STAT_ALARM1 (1<<8) /* Self-test diagnostic error flag: 1 = error condition, 0 = normal operation */ -#define ADIS16209_DIAG_STAT_SELFTEST_FAIL (1<<5) +#define ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT 5 /* SPI communications failure */ -#define ADIS16209_DIAG_STAT_SPI_FAIL (1<<3) +#define ADIS16209_DIAG_STAT_SPI_FAIL_BIT 3 /* Flash update failure */ -#define ADIS16209_DIAG_STAT_FLASH_UPT (1<<2) +#define ADIS16209_DIAG_STAT_FLASH_UPT_BIT 2 /* Power supply above 3.625 V */ -#define ADIS16209_DIAG_STAT_POWER_HIGH (1<<1) +#define ADIS16209_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply below 3.15 V */ -#define ADIS16209_DIAG_STAT_POWER_LOW (1<<0) +#define ADIS16209_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ #define ADIS16209_GLOB_CMD_SW_RESET (1<<7) #define ADIS16209_GLOB_CMD_CLEAR_STAT (1<<4) #define ADIS16209_GLOB_CMD_FACTORY_CAL (1<<1) -#define ADIS16209_MAX_TX 24 -#define ADIS16209_MAX_RX 24 - #define ADIS16209_ERROR_ACTIVE (1<<14) -/** - * struct adis16209_state - device instance specific data - * @us: actual spi_device - * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16209_state { - struct spi_device *us; - struct iio_trigger *trig; - struct mutex buf_lock; - u8 tx[ADIS16209_MAX_TX] ____cacheline_aligned; - u8 rx[ADIS16209_MAX_RX]; -}; - -int adis16209_set_irq(struct iio_dev *indio_dev, bool enable); - #define ADIS16209_SCAN_SUPPLY 0 #define ADIS16209_SCAN_ACC_X 1 #define ADIS16209_SCAN_ACC_Y 2 @@ -128,45 +102,4 @@ int adis16209_set_irq(struct iio_dev *indio_dev, bool enable); #define ADIS16209_SCAN_INCLI_Y 6 #define ADIS16209_SCAN_ROT 7 -#ifdef CONFIG_IIO_BUFFER - -void adis16209_remove_trigger(struct iio_dev *indio_dev); -int adis16209_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16209_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - -int adis16209_configure_ring(struct iio_dev *indio_dev); -void adis16209_unconfigure_ring(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline void adis16209_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16209_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16209_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16209_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16209_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -#endif /* CONFIG_IIO_BUFFER */ #endif /* SPI_ADIS16209_H_ */ diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index b7a0d5c2bbd..e203e96a566 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -21,258 +21,17 @@ #include #include "adis16209.h" - -/** - * adis16209_spi_write_reg_8() - write single byte to a register - * @indio_dev: iio device associated with actual device - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16209_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16209_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16209_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16209_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio device associated actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16209_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16209_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 30, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 30, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16209_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16209_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16209_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio device associated with device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16209_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16209_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 30, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 30, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16209_READ_REG(lower_reg_address); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, - "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - -static int adis16209_reset(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16209_spi_write_reg_8(indio_dev, - ADIS16209_GLOB_CMD, - ADIS16209_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&indio_dev->dev, "problem resetting device"); - - return ret; -} - -int adis16209_set_irq(struct iio_dev *indio_dev, bool enable) -{ - int ret = 0; - u16 msc; - - ret = adis16209_spi_read_reg_16(indio_dev, ADIS16209_MSC_CTRL, &msc); - if (ret) - goto error_ret; - - msc |= ADIS16209_MSC_CTRL_ACTIVE_HIGH; - msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_DIO2; - if (enable) - msc |= ADIS16209_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_EN; - - ret = adis16209_spi_write_reg_16(indio_dev, ADIS16209_MSC_CTRL, msc); - -error_ret: - return ret; -} - -static int adis16209_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - - ret = adis16209_spi_read_reg_16(indio_dev, - ADIS16209_DIAG_STAT, &status); - if (ret < 0) { - dev_err(&indio_dev->dev, "Reading status failed\n"); - goto error_ret; - } - ret = status & 0x1F; - - if (status & ADIS16209_DIAG_STAT_SELFTEST_FAIL) - dev_err(&indio_dev->dev, "Self test failure\n"); - if (status & ADIS16209_DIAG_STAT_SPI_FAIL) - dev_err(&indio_dev->dev, "SPI failure\n"); - if (status & ADIS16209_DIAG_STAT_FLASH_UPT) - dev_err(&indio_dev->dev, "Flash update failed\n"); - if (status & ADIS16209_DIAG_STAT_POWER_HIGH) - dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); - if (status & ADIS16209_DIAG_STAT_POWER_LOW) - dev_err(&indio_dev->dev, "Power supply below 3.15V\n"); - -error_ret: - return ret; -} - -static int adis16209_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16209_spi_write_reg_16(indio_dev, - ADIS16209_MSC_CTRL, - ADIS16209_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - adis16209_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16209_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - - /* Disable IRQ */ - ret = adis16209_set_irq(indio_dev, false); - if (ret) { - dev_err(&indio_dev->dev, "disable irq failed"); - goto err_ret; - } - - /* Do self test */ - ret = adis16209_self_test(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16209_check_status(indio_dev); - if (ret) { - adis16209_reset(indio_dev); - dev_err(&indio_dev->dev, "device not playing ball -> reset"); - msleep(ADIS16209_STARTUP_DELAY); - ret = adis16209_check_status(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} - -enum adis16209_chan { - in_supply, - temp, - accel_x, - accel_y, - incli_x, - incli_y, - in_aux, - rot, -}; - -static const u8 adis16209_addresses[8][2] = { - [in_supply] = { ADIS16209_SUPPLY_OUT }, - [in_aux] = { ADIS16209_AUX_ADC }, - [accel_x] = { ADIS16209_XACCL_OUT, ADIS16209_XACCL_NULL }, - [accel_y] = { ADIS16209_YACCL_OUT, ADIS16209_YACCL_NULL }, - [incli_x] = { ADIS16209_XINCL_OUT, ADIS16209_XINCL_NULL }, - [incli_y] = { ADIS16209_YINCL_OUT, ADIS16209_YINCL_NULL }, - [rot] = { ADIS16209_ROT_OUT }, - [temp] = { ADIS16209_TEMP_OUT }, +#include "../imu/adis.h" + +static const u8 adis16209_addresses[8][1] = { + [ADIS16209_SCAN_SUPPLY] = { }, + [ADIS16209_SCAN_AUX_ADC] = { }, + [ADIS16209_SCAN_ACC_X] = { ADIS16209_XACCL_NULL }, + [ADIS16209_SCAN_ACC_Y] = { ADIS16209_YACCL_NULL }, + [ADIS16209_SCAN_INCLI_X] = { ADIS16209_XINCL_NULL }, + [ADIS16209_SCAN_INCLI_Y] = { ADIS16209_YINCL_NULL }, + [ADIS16209_SCAN_ROT] = { }, + [ADIS16209_SCAN_TEMP] = { }, }; static int adis16209_write_raw(struct iio_dev *indio_dev, @@ -281,6 +40,7 @@ static int adis16209_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct adis *st = iio_priv(indio_dev); int bits; s16 val16; u8 addr; @@ -295,8 +55,8 @@ static int adis16209_write_raw(struct iio_dev *indio_dev, return -EINVAL; } val16 = val & ((1 << bits) - 1); - addr = adis16209_addresses[chan->address][1]; - return adis16209_spi_write_reg_16(indio_dev, addr, val16); + addr = adis16209_addresses[chan->scan_index][0]; + return adis_write_reg_16(st, addr, val16); } return -EINVAL; } @@ -306,6 +66,7 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { + struct adis *st = iio_priv(indio_dev); int ret; int bits; u8 addr; @@ -313,29 +74,8 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - addr = adis16209_addresses[chan->address][0]; - ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - - if (val16 & ADIS16209_ERROR_ACTIVE) { - ret = adis16209_check_status(indio_dev); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - } - val16 = val16 & ((1 << chan->scan_type.realbits) - 1); - if (chan->scan_type.sign == 's') - val16 = (s16)(val16 << - (16 - chan->scan_type.realbits)) >> - (16 - chan->scan_type.realbits); - *val = val16; - mutex_unlock(&indio_dev->mlock); - return IIO_VAL_INT; + return adis_single_conversion(indio_dev, chan, + ADIS16209_ERROR_ACTIVE, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: @@ -374,8 +114,8 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, return -EINVAL; } mutex_lock(&indio_dev->mlock); - addr = adis16209_addresses[chan->address][1]; - ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16209_addresses[chan->scan_index][0]; + ret = adis_read_reg_16(st, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -390,115 +130,16 @@ static int adis16209_read_raw(struct iio_dev *indio_dev, } static const struct iio_chan_spec adis16209_channels[] = { - { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_supply, - .scan_index = ADIS16209_SCAN_SUPPLY, - .scan_type = { - .sign = 'u', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_TEMP, - .indexed = 0, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - .address = temp, - .scan_index = ADIS16209_SCAN_TEMP, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = accel_x, - .scan_index = ADIS16209_SCAN_ACC_X, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, - .address = accel_y, - .scan_index = ADIS16209_SCAN_ACC_Y, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_aux, - .scan_index = ADIS16209_SCAN_AUX_ADC, - .scan_type = { - .sign = 'u', - .realbits = 12, - .storagebits = 16, - }, - }, { - .type = IIO_INCLI, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = incli_x, - .scan_index = ADIS16209_SCAN_INCLI_X, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_INCLI, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = incli_y, - .scan_index = ADIS16209_SCAN_INCLI_Y, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, { - .type = IIO_ROT, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, - IIO_CHAN_INFO_SCALE_SHARED_BIT, - .address = rot, - .scan_index = ADIS16209_SCAN_ROT, - .scan_type = { - .sign = 's', - .realbits = 14, - .storagebits = 16, - }, - }, + ADIS_SUPPLY_CHAN(ADIS16209_SUPPLY_OUT, ADIS16209_SCAN_SUPPLY, 14), + ADIS_TEMP_CHAN(ADIS16209_TEMP_OUT, ADIS16209_SCAN_TEMP, 12), + ADIS_ACCEL_CHAN(X, ADIS16209_XACCL_OUT, ADIS16209_SCAN_ACC_X, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + ADIS_ACCEL_CHAN(Y, ADIS16209_YACCL_OUT, ADIS16209_SCAN_ACC_Y, + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, 14), + ADIS_AUX_ADC_CHAN(ADIS16209_AUX_ADC, ADIS16209_SCAN_AUX_ADC, 12), + ADIS_INCLI_CHAN(X, ADIS16209_XINCL_OUT, ADIS16209_SCAN_INCLI_X, 0, 14), + ADIS_INCLI_CHAN(Y, ADIS16209_YINCL_OUT, ADIS16209_SCAN_INCLI_Y, 0, 14), + ADIS_ROT_CHAN(X, ADIS16209_ROT_OUT, ADIS16209_SCAN_ROT, 0, 14), IIO_CHAN_SOFT_TIMESTAMP(8) }; @@ -508,10 +149,36 @@ static const struct iio_info adis16209_info = { .driver_module = THIS_MODULE, }; +static const char * const adis16209_status_error_msgs[] = { + [ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure", + [ADIS16209_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16209_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16209_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", + [ADIS16209_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", +}; + +static const struct adis_data adis16209_data = { + .read_delay = 30, + .msc_ctrl_reg = ADIS16209_MSC_CTRL, + .glob_cmd_reg = ADIS16209_GLOB_CMD, + .diag_stat_reg = ADIS16209_DIAG_STAT, + + .self_test_mask = ADIS16209_MSC_CTRL_SELF_TEST_EN, + .startup_delay = ADIS16209_STARTUP_DELAY, + + .status_error_msgs = adis16209_status_error_msgs, + .status_error_mask = BIT(ADIS16209_DIAG_STAT_SELFTEST_FAIL_BIT) | + BIT(ADIS16209_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16209_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16209_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16209_DIAG_STAT_POWER_LOW_BIT), +}; + + static int __devinit adis16209_probe(struct spi_device *spi) { int ret; - struct adis16209_state *st; + struct adis *st; struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ @@ -523,8 +190,6 @@ static int __devinit adis16209_probe(struct spi_device *spi) st = iio_priv(indio_dev); /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; @@ -533,40 +198,25 @@ static int __devinit adis16209_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(adis16209_channels); indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16209_configure_ring(indio_dev); + ret = adis_init(st, indio_dev, spi, &adis16209_data); + if (ret) + goto error_free_dev; + ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) goto error_free_dev; - - ret = iio_buffer_register(indio_dev, - adis16209_channels, - ARRAY_SIZE(adis16209_channels)); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = adis16209_probe_trigger(indio_dev); - if (ret) - goto error_uninitialize_ring; - } /* Get the device into a sane initial state */ - ret = adis16209_initial_setup(indio_dev); + ret = adis_initial_startup(st); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; ret = iio_device_register(indio_dev); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; return 0; -error_remove_trigger: - adis16209_remove_trigger(indio_dev); -error_uninitialize_ring: - iio_buffer_unregister(indio_dev); -error_unreg_ring_funcs: - adis16209_unconfigure_ring(indio_dev); +error_cleanup_buffer_trigger: + adis_cleanup_buffer_and_trigger(st, indio_dev); error_free_dev: iio_device_free(indio_dev); error_ret: @@ -576,11 +226,10 @@ error_ret: static int __devexit adis16209_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - adis16209_remove_trigger(indio_dev); - iio_buffer_unregister(indio_dev); - adis16209_unconfigure_ring(indio_dev); + adis_cleanup_buffer_and_trigger(st, indio_dev); iio_device_free(indio_dev); return 0; diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c deleted file mode 100644 index 6af9a5dbc70..00000000000 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ /dev/null @@ -1,134 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include "../ring_sw.h" -#include -#include "adis16209.h" - -/** - * adis16209_read_ring_data() read data registers which will be placed into ring - * @indio_dev: the IIO device - * @rx: somewhere to pass back the value read - **/ -static int adis16209_read_ring_data(struct iio_dev *indio_dev, u8 *rx) -{ - struct spi_message msg; - struct adis16209_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[ADIS16209_OUTPUTS + 1]; - int ret; - int i; - - mutex_lock(&st->buf_lock); - - spi_message_init(&msg); - - memset(xfers, 0, sizeof(xfers)); - for (i = 0; i <= ADIS16209_OUTPUTS; i++) { - xfers[i].bits_per_word = 8; - xfers[i].cs_change = 1; - xfers[i].len = 2; - xfers[i].delay_usecs = 30; - xfers[i].tx_buf = st->tx + 2 * i; - st->tx[2 * i] - = ADIS16209_READ_REG(ADIS16209_SUPPLY_OUT + 2 * i); - st->tx[2 * i + 1] = 0; - if (i >= 1) - xfers[i].rx_buf = rx + 2 * (i - 1); - spi_message_add_tail(&xfers[i], &msg); - } - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when burst reading"); - - mutex_unlock(&st->buf_lock); - - return ret; -} - -/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device - * specific to be rolled into the core. - */ -static irqreturn_t adis16209_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct adis16209_state *st = iio_priv(indio_dev); - int i = 0; - s16 *data; - - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (data == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - goto done; - } - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16209_read_ring_data(indio_dev, st->rx) >= 0) - for (; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - - iio_push_to_buffers(indio_dev, (u8 *)data); - - kfree(data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -void adis16209_unconfigure_ring(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); -} - -static const struct iio_buffer_setup_ops adis16209_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -int adis16209_configure_ring(struct iio_dev *indio_dev) -{ - int ret = 0; - struct iio_buffer *ring; - - ring = iio_sw_rb_allocate(indio_dev); - if (!ring) { - ret = -ENOMEM; - return ret; - } - indio_dev->buffer = ring; - ring->scan_timestamp = true; - indio_dev->setup_ops = &adis16209_ring_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &adis16209_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "%s_consumer%d", - indio_dev->name, - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->buffer); - return ret; -} diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c deleted file mode 100644 index 112280346eb..00000000000 --- a/drivers/staging/iio/accel/adis16209_trigger.c +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include "adis16209.h" - -/** - * adis16209_data_rdy_trigger_set_state() set datardy interrupt state - **/ -static int adis16209_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct iio_dev *indio_dev = trig->private_data; - - dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16209_set_irq(indio_dev, state); -} - -static const struct iio_trigger_ops adis16209_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &adis16209_data_rdy_trigger_set_state, -}; - -int adis16209_probe_trigger(struct iio_dev *indio_dev) -{ - int ret; - struct adis16209_state *st = iio_priv(indio_dev); - - st->trig = iio_trigger_alloc("adis16209-dev%d", indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - ret = request_irq(st->us->irq, - iio_trigger_generic_data_rdy_poll, - IRQF_TRIGGER_RISING, - "adis16209", - st->trig); - if (ret) - goto error_free_trig; - st->trig->dev.parent = &st->us->dev; - st->trig->ops = &adis16209_trigger_ops; - st->trig->private_data = indio_dev; - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->us->irq, st->trig); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -void adis16209_remove_trigger(struct iio_dev *indio_dev) -{ - struct adis16209_state *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); - free_irq(st->us->irq, st->trig); - iio_trigger_free(st->trig); -} -- cgit v1.2.3 From edcf600912d218a1d8a6378e37b19ecab63abddd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Nov 2012 13:28:00 +0000 Subject: staging:iio:adis16220: Use adis library Use the new adis library for the adis16220 driver. The adis16220 driver is a bit special and so we can only make use of the generic register access and control functions for now. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/adis16220.h | 20 +-- drivers/staging/iio/accel/adis16220_core.c | 280 ++++++----------------------- 2 files changed, 60 insertions(+), 240 deletions(-) diff --git a/drivers/staging/iio/accel/adis16220.h b/drivers/staging/iio/accel/adis16220.h index 024313cf5cf..7cc4d2f3ec2 100644 --- a/drivers/staging/iio/accel/adis16220.h +++ b/drivers/staging/iio/accel/adis16220.h @@ -1,10 +1,9 @@ #ifndef SPI_ADIS16220_H_ #define SPI_ADIS16220_H_ -#define ADIS16220_STARTUP_DELAY 220 /* ms */ +#include "../imu/adis.h" -#define ADIS16220_READ_REG(a) a -#define ADIS16220_WRITE_REG(a) ((a) | 0x80) +#define ADIS16220_STARTUP_DELAY 220 /* ms */ /* Flash memory write count */ #define ADIS16220_FLASH_CNT 0x00 @@ -102,15 +101,15 @@ #define ADIS16220_DIAG_STAT_FLASH_CHK (1<<6) #define ADIS16220_DIAG_STAT_SELF_TEST (1<<5) /* Capture period violation/interruption */ -#define ADIS16220_DIAG_STAT_VIOLATION (1<<4) +#define ADIS16220_DIAG_STAT_VIOLATION_BIT 4 /* SPI communications failure */ -#define ADIS16220_DIAG_STAT_SPI_FAIL (1<<3) +#define ADIS16220_DIAG_STAT_SPI_FAIL_BIT 3 /* Flash update failure */ -#define ADIS16220_DIAG_STAT_FLASH_UPT (1<<2) +#define ADIS16220_DIAG_STAT_FLASH_UPT_BIT 2 /* Power supply above 3.625 V */ -#define ADIS16220_DIAG_STAT_POWER_HIGH (1<<1) +#define ADIS16220_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply below 3.15 V */ -#define ADIS16220_DIAG_STAT_POWER_LOW (1<<0) +#define ADIS16220_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ #define ADIS16220_GLOB_CMD_SW_RESET (1<<7) @@ -125,13 +124,14 @@ /** * struct adis16220_state - device instance specific data - * @us: actual spi_device + * @adis: adis device * @tx: transmit buffer * @rx: receive buffer * @buf_lock: mutex to protect tx and rx **/ struct adis16220_state { - struct spi_device *us; + struct adis adis; + struct mutex buf_lock; u8 tx[ADIS16220_MAX_TX] ____cacheline_aligned; u8 rx[ADIS16220_MAX_RX]; diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index 22807ac8e8f..c39ce622eb6 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -20,136 +20,19 @@ #include "adis16220.h" -/** - * adis16220_spi_write_reg_8() - write single byte to a register - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16220_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16220_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16220_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16220_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16220_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16220_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 35, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 35, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16220_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16220_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16220_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio device associated with child of actual device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16220_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16220_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 35, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 35, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16220_READ_REG(lower_reg_address); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, - "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - static ssize_t adis16220_read_16bit(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adis16220_state *st = iio_priv(indio_dev); ssize_t ret; s16 val = 0; /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); - ret = adis16220_spi_read_reg_16(indio_dev, this_attr->address, + ret = adis_read_reg_16(&st->adis, this_attr->address, (u16 *)&val); mutex_unlock(&indio_dev->mlock); if (ret) @@ -164,13 +47,14 @@ static ssize_t adis16220_write_16bit(struct device *dev, { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + struct adis16220_state *st = iio_priv(indio_dev); int ret; u16 val; ret = kstrtou16(buf, 10, &val); if (ret) goto error_ret; - ret = adis16220_spi_write_reg_16(indio_dev, this_attr->address, val); + ret = adis_write_reg_16(&st->adis, this_attr->address, val); error_ret: return ret ? ret : len; @@ -178,10 +62,11 @@ error_ret: static int adis16220_capture(struct iio_dev *indio_dev) { + struct adis16220_state *st = iio_priv(indio_dev); int ret; - ret = adis16220_spi_write_reg_16(indio_dev, - ADIS16220_GLOB_CMD, - 0xBF08); /* initiates a manual data capture */ + + /* initiates a manual data capture */ + ret = adis_write_reg_16(&st->adis, ADIS16220_GLOB_CMD, 0xBF08); if (ret) dev_err(&indio_dev->dev, "problem beginning capture"); @@ -190,18 +75,6 @@ static int adis16220_capture(struct iio_dev *indio_dev) return ret; } -static int adis16220_reset(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16220_spi_write_reg_8(indio_dev, - ADIS16220_GLOB_CMD, - ADIS16220_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&indio_dev->dev, "problem resetting device"); - - return ret; -} - static ssize_t adis16220_write_capture(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) @@ -222,81 +95,6 @@ static ssize_t adis16220_write_capture(struct device *dev, return len; } -static int adis16220_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - - ret = adis16220_spi_read_reg_16(indio_dev, ADIS16220_DIAG_STAT, - &status); - - if (ret < 0) { - dev_err(&indio_dev->dev, "Reading status failed\n"); - goto error_ret; - } - ret = status & 0x7F; - - if (status & ADIS16220_DIAG_STAT_VIOLATION) - dev_err(&indio_dev->dev, - "Capture period violation/interruption\n"); - if (status & ADIS16220_DIAG_STAT_SPI_FAIL) - dev_err(&indio_dev->dev, "SPI failure\n"); - if (status & ADIS16220_DIAG_STAT_FLASH_UPT) - dev_err(&indio_dev->dev, "Flash update failed\n"); - if (status & ADIS16220_DIAG_STAT_POWER_HIGH) - dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); - if (status & ADIS16220_DIAG_STAT_POWER_LOW) - dev_err(&indio_dev->dev, "Power supply below 3.15V\n"); - -error_ret: - return ret; -} - -static int adis16220_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16220_spi_write_reg_16(indio_dev, - ADIS16220_MSC_CTRL, - ADIS16220_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - adis16220_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16220_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - - /* Do self test */ - ret = adis16220_self_test(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16220_check_status(indio_dev); - if (ret) { - adis16220_reset(indio_dev); - dev_err(&indio_dev->dev, "device not playing ball -> reset"); - msleep(ADIS16220_STARTUP_DELAY); - ret = adis16220_check_status(indio_dev); - if (ret) { - dev_err(&indio_dev->dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} - static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, char *buf, loff_t off, @@ -333,7 +131,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, count = ADIS16220_CAPTURE_SIZE - off; /* write the begin position of capture buffer */ - ret = adis16220_spi_write_reg_16(indio_dev, + ret = adis_write_reg_16(&st->adis, ADIS16220_CAPT_PNTR, off > 1); if (ret) @@ -342,8 +140,9 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, /* read count/2 values from capture buffer */ mutex_lock(&st->buf_lock); + for (i = 0; i < count; i += 2) { - st->tx[i] = ADIS16220_READ_REG(addr); + st->tx[i] = ADIS_READ_REG(addr); st->tx[i + 1] = 0; } xfers[1].len = count; @@ -351,7 +150,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, spi_message_init(&msg); spi_message_add_tail(&xfers[0], &msg); spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); + ret = spi_sync(st->adis.spi, &msg); if (ret) { mutex_unlock(&st->buf_lock); @@ -472,6 +271,8 @@ static int adis16220_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { + struct adis16220_state *st = iio_priv(indio_dev); + const struct adis16220_address_spec *addr; int ret = -EINVAL; int addrind = 0; u16 uval; @@ -516,28 +317,21 @@ static int adis16220_read_raw(struct iio_dev *indio_dev, default: return -EINVAL; } - if (adis16220_addresses[chan->address][addrind].sign) { - ret = adis16220_spi_read_reg_16(indio_dev, - adis16220_addresses[chan - ->address] - [addrind].addr, - &sval); + addr = &adis16220_addresses[chan->address][addrind]; + if (addr->sign) { + ret = adis_read_reg_16(&st->adis, addr->addr, &sval); if (ret) return ret; - bits = adis16220_addresses[chan->address][addrind].bits; + bits = addr->bits; sval &= (1 << bits) - 1; sval = (s16)(sval << (16 - bits)) >> (16 - bits); *val = sval; return IIO_VAL_INT; } else { - ret = adis16220_spi_read_reg_16(indio_dev, - adis16220_addresses[chan - ->address] - [addrind].addr, - &uval); + ret = adis_read_reg_16(&st->adis, addr->addr, &uval); if (ret) return ret; - bits = adis16220_addresses[chan->address][addrind].bits; + bits = addr->bits; uval &= (1 << bits) - 1; *val = uval; return IIO_VAL_INT; @@ -601,6 +395,32 @@ static const struct iio_info adis16220_info = { .read_raw = &adis16220_read_raw, }; +static const char * const adis16220_status_error_msgs[] = { + [ADIS16220_DIAG_STAT_VIOLATION_BIT] = "Capture period violation/interruption", + [ADIS16220_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16220_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16220_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", + [ADIS16220_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 3.15V", +}; + +static const struct adis_data adis16220_data = { + .read_delay = 35, + .write_delay = 35, + .msc_ctrl_reg = ADIS16220_MSC_CTRL, + .glob_cmd_reg = ADIS16220_GLOB_CMD, + .diag_stat_reg = ADIS16220_DIAG_STAT, + + .self_test_mask = ADIS16220_MSC_CTRL_SELF_TEST_EN, + .startup_delay = ADIS16220_STARTUP_DELAY, + + .status_error_msgs = adis16220_status_error_msgs, + .status_error_mask = BIT(ADIS16220_DIAG_STAT_VIOLATION_BIT) | + BIT(ADIS16220_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16220_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16220_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16220_DIAG_STAT_POWER_LOW_BIT), +}; + static int __devinit adis16220_probe(struct spi_device *spi) { int ret; @@ -618,9 +438,6 @@ static int __devinit adis16220_probe(struct spi_device *spi) /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); - indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; indio_dev->info = &adis16220_info; @@ -644,8 +461,11 @@ static int __devinit adis16220_probe(struct spi_device *spi) if (ret) goto error_rm_adc1_bin; + ret = adis_init(&st->adis, indio_dev, spi, &adis16220_data); + if (ret) + goto error_rm_adc2_bin; /* Get the device into a sane initial state */ - ret = adis16220_initial_setup(indio_dev); + ret = adis_initial_startup(&st->adis); if (ret) goto error_rm_adc2_bin; return 0; -- cgit v1.2.3 From 5cb7cb1191fc8fc0fcf9a1cc43b9ed7168c5c44a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Nov 2012 13:28:00 +0000 Subject: staging:iio:adis16240: Use adis library Use the new adis library for the adis16240 driver. This allows us to completely scrap the adis16240 buffer and trigger code and more than half of the core driver code. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/Kconfig | 5 +- drivers/staging/iio/accel/Makefile | 1 - drivers/staging/iio/accel/adis16240.h | 85 +---- drivers/staging/iio/accel/adis16240_core.c | 472 ++++---------------------- drivers/staging/iio/accel/adis16240_ring.c | 132 ------- drivers/staging/iio/accel/adis16240_trigger.c | 73 ---- 6 files changed, 77 insertions(+), 691 deletions(-) delete mode 100644 drivers/staging/iio/accel/adis16240_ring.c delete mode 100644 drivers/staging/iio/accel/adis16240_trigger.c diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index affa732ef51..2b54430f2d9 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -42,6 +42,7 @@ config ADIS16209 config ADIS16220 tristate "Analog Devices ADIS16220 Programmable Digital Vibration Sensor" depends on SPI + select IIO_ADIS_LIB help Say yes here to build support for Analog Devices adis16220 programmable digital vibration sensor. @@ -49,8 +50,8 @@ config ADIS16220 config ADIS16240 tristate "Analog Devices ADIS16240 Programmable Impact Sensor and Recorder" depends on SPI - select IIO_TRIGGER if IIO_BUFFER - select IIO_SW_RING if IIO_BUFFER + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER help Say yes here to build support for Analog Devices adis16240 programmable impact Sensor and recorder. diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index 3cb9c67a29b..8e7ee036851 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -18,7 +18,6 @@ adis16220-y := adis16220_core.o obj-$(CONFIG_ADIS16220) += adis16220.o adis16240-y := adis16240_core.o -adis16240-$(CONFIG_IIO_BUFFER) += adis16240_ring.o adis16240_trigger.o obj-$(CONFIG_ADIS16240) += adis16240.o obj-$(CONFIG_KXSD9) += kxsd9.o diff --git a/drivers/staging/iio/accel/adis16240.h b/drivers/staging/iio/accel/adis16240.h index 3fabcc0b347..d442d49f51f 100644 --- a/drivers/staging/iio/accel/adis16240.h +++ b/drivers/staging/iio/accel/adis16240.h @@ -3,9 +3,6 @@ #define ADIS16240_STARTUP_DELAY 220 /* ms */ -#define ADIS16240_READ_REG(a) a -#define ADIS16240_WRITE_REG(a) ((a) | 0x80) - /* Flash memory write count */ #define ADIS16240_FLASH_CNT 0x00 /* Output, power supply */ @@ -75,8 +72,6 @@ /* System command */ #define ADIS16240_GLOB_CMD 0x4A -#define ADIS16240_OUTPUTS 6 - /* MSC_CTRL */ /* Enables sum-of-squares output (XYZPEAK_OUT) */ #define ADIS16240_MSC_CTRL_XYZPEAK_OUT_EN (1 << 15) @@ -101,17 +96,17 @@ /* Flash test, checksum flag: 1 = mismatch, 0 = match */ #define ADIS16240_DIAG_STAT_CHKSUM (1<<6) /* Power-on, self-test flag: 1 = failure, 0 = pass */ -#define ADIS16240_DIAG_STAT_PWRON_FAIL (1<<5) +#define ADIS16240_DIAG_STAT_PWRON_FAIL_BIT 5 /* Power-on self-test: 1 = in-progress, 0 = complete */ #define ADIS16240_DIAG_STAT_PWRON_BUSY (1<<4) /* SPI communications failure */ -#define ADIS16240_DIAG_STAT_SPI_FAIL (1<<3) +#define ADIS16240_DIAG_STAT_SPI_FAIL_BIT 3 /* Flash update failure */ -#define ADIS16240_DIAG_STAT_FLASH_UPT (1<<2) +#define ADIS16240_DIAG_STAT_FLASH_UPT_BIT 2 /* Power supply above 3.625 V */ -#define ADIS16240_DIAG_STAT_POWER_HIGH (1<<1) +#define ADIS16240_DIAG_STAT_POWER_HIGH_BIT 1 /* Power supply below 3.15 V */ -#define ADIS16240_DIAG_STAT_POWER_LOW (1<<0) +#define ADIS16240_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ #define ADIS16240_GLOB_CMD_RESUME (1<<8) @@ -120,77 +115,15 @@ #define ADIS16240_ERROR_ACTIVE (1<<14) -#define ADIS16240_MAX_TX 24 -#define ADIS16240_MAX_RX 24 - -/** - * struct adis16240_state - device instance specific data - * @us: actual spi_device - * @trig: data ready trigger registered with iio - * @tx: transmit buffer - * @rx: receive buffer - * @buf_lock: mutex to protect tx and rx - **/ -struct adis16240_state { - struct spi_device *us; - struct iio_trigger *trig; - struct mutex buf_lock; - u8 tx[ADIS16240_MAX_TX] ____cacheline_aligned; - u8 rx[ADIS16240_MAX_RX]; -}; - -int adis16240_set_irq(struct iio_dev *indio_dev, bool enable); - /* At the moment triggers are only used for ring buffer * filling. This may change! */ -#define ADIS16240_SCAN_SUPPLY 0 -#define ADIS16240_SCAN_ACC_X 1 -#define ADIS16240_SCAN_ACC_Y 2 -#define ADIS16240_SCAN_ACC_Z 3 +#define ADIS16240_SCAN_ACC_X 0 +#define ADIS16240_SCAN_ACC_Y 1 +#define ADIS16240_SCAN_ACC_Z 2 +#define ADIS16240_SCAN_SUPPLY 3 #define ADIS16240_SCAN_AUX_ADC 4 #define ADIS16240_SCAN_TEMP 5 -#ifdef CONFIG_IIO_BUFFER -void adis16240_remove_trigger(struct iio_dev *indio_dev); -int adis16240_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16240_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - - -int adis16240_configure_ring(struct iio_dev *indio_dev); -void adis16240_unconfigure_ring(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline void adis16240_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16240_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16240_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16240_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16240_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -#endif /* CONFIG_IIO_BUFFER */ #endif /* SPI_ADIS16240_H_ */ diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 289f81963c8..019a31e2203 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -24,128 +24,7 @@ #include #include "adis16240.h" - -static int adis16240_check_status(struct iio_dev *indio_dev); - -/** - * adis16240_spi_write_reg_8() - write single byte to a register - * @indio_dev: iio_dev associated with device - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16240_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16240_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16240_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16240_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio_dev for this device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16240_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16240_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 35, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 35, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16240_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16240_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16240_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio_dev for this device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16240_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16240_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 35, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 35, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16240_READ_REG(lower_reg_address); - st->tx[1] = 0; - st->tx[2] = 0; - st->tx[3] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, - "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} +#include "../imu/adis.h" static ssize_t adis16240_spi_read_signed(struct device *dev, struct device_attribute *attr, @@ -153,18 +32,19 @@ static ssize_t adis16240_spi_read_signed(struct device *dev, unsigned bits) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adis *st = iio_priv(indio_dev); int ret; s16 val = 0; unsigned shift = 16 - bits; struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - ret = adis16240_spi_read_reg_16(indio_dev, + ret = adis_read_reg_16(st, this_attr->address, (u16 *)&val); if (ret) return ret; if (val & ADIS16240_ERROR_ACTIVE) - adis16240_check_status(indio_dev); + adis_check_status(st); val = ((s16)(val << shift) >> shift); return sprintf(buf, "%d\n", val); @@ -185,152 +65,16 @@ static ssize_t adis16240_read_12bit_signed(struct device *dev, return ret; } -static int adis16240_reset(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16240_spi_write_reg_8(indio_dev, - ADIS16240_GLOB_CMD, - ADIS16240_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&indio_dev->dev, "problem resetting device"); - - return ret; -} - -int adis16240_set_irq(struct iio_dev *indio_dev, bool enable) -{ - int ret = 0; - u16 msc; - - ret = adis16240_spi_read_reg_16(indio_dev, - ADIS16240_MSC_CTRL, &msc); - if (ret) - goto error_ret; - - msc |= ADIS16240_MSC_CTRL_ACTIVE_HIGH; - msc &= ~ADIS16240_MSC_CTRL_DATA_RDY_DIO2; - if (enable) - msc |= ADIS16240_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS16240_MSC_CTRL_DATA_RDY_EN; - - ret = adis16240_spi_write_reg_16(indio_dev, - ADIS16240_MSC_CTRL, msc); - -error_ret: - return ret; -} - -static int adis16240_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16240_spi_write_reg_16(indio_dev, - ADIS16240_MSC_CTRL, - ADIS16240_MSC_CTRL_SELF_TEST_EN); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - msleep(ADIS16240_STARTUP_DELAY); - - adis16240_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16240_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - struct device *dev = &indio_dev->dev; - - ret = adis16240_spi_read_reg_16(indio_dev, - ADIS16240_DIAG_STAT, &status); - - if (ret < 0) { - dev_err(dev, "Reading status failed\n"); - goto error_ret; - } - - ret = status & 0x2F; - if (status & ADIS16240_DIAG_STAT_PWRON_FAIL) - dev_err(dev, "Power-on, self-test fail\n"); - if (status & ADIS16240_DIAG_STAT_SPI_FAIL) - dev_err(dev, "SPI failure\n"); - if (status & ADIS16240_DIAG_STAT_FLASH_UPT) - dev_err(dev, "Flash update failed\n"); - if (status & ADIS16240_DIAG_STAT_POWER_HIGH) - dev_err(dev, "Power supply above 3.625V\n"); - if (status & ADIS16240_DIAG_STAT_POWER_LOW) - dev_err(dev, "Power supply below 2.225V\n"); - -error_ret: - return ret; -} - -static int adis16240_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - struct device *dev = &indio_dev->dev; - - /* Disable IRQ */ - ret = adis16240_set_irq(indio_dev, false); - if (ret) { - dev_err(dev, "disable irq failed"); - goto err_ret; - } - - /* Do self test */ - ret = adis16240_self_test(indio_dev); - if (ret) { - dev_err(dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16240_check_status(indio_dev); - if (ret) { - adis16240_reset(indio_dev); - dev_err(dev, "device not playing ball -> reset"); - msleep(ADIS16240_STARTUP_DELAY); - ret = adis16240_check_status(indio_dev); - if (ret) { - dev_err(dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} - static IIO_DEVICE_ATTR(in_accel_xyz_squared_peak_raw, S_IRUGO, adis16240_read_12bit_signed, NULL, ADIS16240_XYZPEAK_OUT); static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("4096"); -enum adis16240_chan { - in_supply, - in_aux, - accel_x, - accel_y, - accel_z, - temp, -}; - -static const u8 adis16240_addresses[6][3] = { - [in_supply] = { ADIS16240_SUPPLY_OUT }, - [in_aux] = { ADIS16240_AUX_ADC }, - [accel_x] = { ADIS16240_XACCL_OUT, ADIS16240_XACCL_OFF, - ADIS16240_XPEAK_OUT }, - [accel_y] = { ADIS16240_YACCL_OUT, ADIS16240_YACCL_OFF, - ADIS16240_YPEAK_OUT }, - [accel_z] = { ADIS16240_ZACCL_OUT, ADIS16240_ZACCL_OFF, - ADIS16240_ZPEAK_OUT }, - [temp] = { ADIS16240_TEMP_OUT }, +static const u8 adis16240_addresses[][2] = { + [ADIS16240_SCAN_ACC_X] = { ADIS16240_XACCL_OFF, ADIS16240_XPEAK_OUT }, + [ADIS16240_SCAN_ACC_Y] = { ADIS16240_YACCL_OFF, ADIS16240_YPEAK_OUT }, + [ADIS16240_SCAN_ACC_Z] = { ADIS16240_ZACCL_OFF, ADIS16240_ZPEAK_OUT }, }; static int adis16240_read_raw(struct iio_dev *indio_dev, @@ -338,6 +82,7 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { + struct adis *st = iio_priv(indio_dev); int ret; int bits; u8 addr; @@ -345,29 +90,8 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - addr = adis16240_addresses[chan->address][0]; - ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - - if (val16 & ADIS16240_ERROR_ACTIVE) { - ret = adis16240_check_status(indio_dev); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - } - val16 = val16 & ((1 << chan->scan_type.realbits) - 1); - if (chan->scan_type.sign == 's') - val16 = (s16)(val16 << - (16 - chan->scan_type.realbits)) >> - (16 - chan->scan_type.realbits); - *val = val16; - mutex_unlock(&indio_dev->mlock); - return IIO_VAL_INT; + return adis_single_conversion(indio_dev, chan, + ADIS16240_ERROR_ACTIVE, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: @@ -400,8 +124,8 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_CALIBBIAS: bits = 10; mutex_lock(&indio_dev->mlock); - addr = adis16240_addresses[chan->address][1]; - ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16240_addresses[chan->scan_index][0]; + ret = adis_read_reg_16(st, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -414,8 +138,8 @@ static int adis16240_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_PEAK: bits = 10; mutex_lock(&indio_dev->mlock); - addr = adis16240_addresses[chan->address][2]; - ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16240_addresses[chan->scan_index][1]; + ret = adis_read_reg_16(st, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -435,104 +159,32 @@ static int adis16240_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct adis *st = iio_priv(indio_dev); int bits = 10; s16 val16; u8 addr; switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: val16 = val & ((1 << bits) - 1); - addr = adis16240_addresses[chan->address][1]; - return adis16240_spi_write_reg_16(indio_dev, addr, val16); + addr = adis16240_addresses[chan->scan_index][0]; + return adis_write_reg_16(st, addr, val16); } return -EINVAL; } static const struct iio_chan_spec adis16240_channels[] = { - { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 0, - .extend_name = "supply", - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = in_supply, - .scan_index = ADIS16240_SCAN_SUPPLY, - .scan_type = { - .sign = 'u', - .realbits = 10, - .storagebits = 16, - }, - }, { - .type = IIO_VOLTAGE, - .indexed = 1, - .channel = 1, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, - .address = in_aux, - .scan_index = ADIS16240_SCAN_AUX_ADC, - .scan_type = { - .sign = 'u', - .realbits = 10, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_X, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | + ADIS_SUPPLY_CHAN(ADIS16240_SUPPLY_OUT, ADIS16240_SCAN_SUPPLY, 10), + ADIS_AUX_ADC_CHAN(ADIS16240_AUX_ADC, ADIS16240_SCAN_AUX_ADC, 10), + ADIS_ACCEL_CHAN(X, ADIS16240_XACCL_OUT, ADIS16240_SCAN_ACC_X, IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - .address = accel_x, - .scan_index = ADIS16240_SCAN_ACC_X, - .scan_type = { - .sign = 's', - .realbits = 10, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_Y, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 10), + ADIS_ACCEL_CHAN(Y, ADIS16240_YACCL_OUT, ADIS16240_SCAN_ACC_Y, IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - .address = accel_y, - .scan_index = ADIS16240_SCAN_ACC_Y, - .scan_type = { - .sign = 's', - .realbits = 10, - .storagebits = 16, - }, - }, { - .type = IIO_ACCEL, - .modified = 1, - .channel2 = IIO_MOD_Z, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 10), + ADIS_ACCEL_CHAN(Z, ADIS16240_ZACCL_OUT, ADIS16240_SCAN_ACC_Z, IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | - IIO_CHAN_INFO_PEAK_SEPARATE_BIT, - .address = accel_z, - .scan_index = ADIS16240_SCAN_ACC_Z, - .scan_type = { - .sign = 's', - .realbits = 10, - .storagebits = 16, - }, - }, { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, - .address = temp, - .scan_index = ADIS16240_SCAN_TEMP, - .scan_type = { - .sign = 'u', - .realbits = 10, - .storagebits = 16, - }, - }, + IIO_CHAN_INFO_PEAK_SEPARATE_BIT, 10), + ADIS_TEMP_CHAN(ADIS16240_TEMP_OUT, ADIS16240_SCAN_TEMP, 10), IIO_CHAN_SOFT_TIMESTAMP(6) }; @@ -553,10 +205,36 @@ static const struct iio_info adis16240_info = { .driver_module = THIS_MODULE, }; +static const char * const adis16240_status_error_msgs[] = { + [ADIS16240_DIAG_STAT_PWRON_FAIL_BIT] = "Power on, self-test failed", + [ADIS16240_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16240_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16240_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V", + [ADIS16240_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 2.225V", +}; + +static const struct adis_data adis16240_data = { + .write_delay = 35, + .read_delay = 35, + .msc_ctrl_reg = ADIS16240_MSC_CTRL, + .glob_cmd_reg = ADIS16240_GLOB_CMD, + .diag_stat_reg = ADIS16240_DIAG_STAT, + + .self_test_mask = ADIS16240_MSC_CTRL_SELF_TEST_EN, + .startup_delay = ADIS16240_STARTUP_DELAY, + + .status_error_msgs = adis16240_status_error_msgs, + .status_error_mask = BIT(ADIS16240_DIAG_STAT_PWRON_FAIL_BIT) | + BIT(ADIS16240_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16240_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16240_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16240_DIAG_STAT_POWER_LOW_BIT), +}; + static int __devinit adis16240_probe(struct spi_device *spi) { int ret; - struct adis16240_state *st; + struct adis *st; struct iio_dev *indio_dev; /* setup the industrialio driver allocated elements */ @@ -569,9 +247,6 @@ static int __devinit adis16240_probe(struct spi_device *spi) /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); - indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; indio_dev->info = &adis16240_info; @@ -579,39 +254,24 @@ static int __devinit adis16240_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(adis16240_channels); indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16240_configure_ring(indio_dev); + ret = adis_init(st, indio_dev, spi, &adis16240_data); + if (ret) + goto error_free_dev; + ret = adis_setup_buffer_and_trigger(st, indio_dev, NULL); if (ret) goto error_free_dev; - - ret = iio_buffer_register(indio_dev, - adis16240_channels, - ARRAY_SIZE(adis16240_channels)); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } - - if (spi->irq) { - ret = adis16240_probe_trigger(indio_dev); - if (ret) - goto error_uninitialize_ring; - } /* Get the device into a sane initial state */ - ret = adis16240_initial_setup(indio_dev); + ret = adis_initial_startup(st); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; ret = iio_device_register(indio_dev); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; return 0; -error_remove_trigger: - adis16240_remove_trigger(indio_dev); -error_uninitialize_ring: - iio_buffer_unregister(indio_dev); -error_unreg_ring_funcs: - adis16240_unconfigure_ring(indio_dev); +error_cleanup_buffer_trigger: + adis_cleanup_buffer_and_trigger(st, indio_dev); error_free_dev: iio_device_free(indio_dev); error_ret: @@ -620,13 +280,11 @@ error_ret: static int __devexit adis16240_remove(struct spi_device *spi) { - struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); - adis16240_remove_trigger(indio_dev); - iio_buffer_unregister(indio_dev); - adis16240_unconfigure_ring(indio_dev); + adis_cleanup_buffer_and_trigger(st, indio_dev); iio_device_free(indio_dev); return 0; diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c deleted file mode 100644 index e2ac8a8c810..00000000000 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ /dev/null @@ -1,132 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include "../ring_sw.h" -#include -#include "adis16240.h" - -/** - * adis16240_read_ring_data() read data registers which will be placed into ring - * @indio_dev: the IIO device - * @rx: somewhere to pass back the value read - **/ -static int adis16240_read_ring_data(struct iio_dev *indio_dev, u8 *rx) -{ - struct spi_message msg; - struct adis16240_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[ADIS16240_OUTPUTS + 1]; - int ret; - int i; - - mutex_lock(&st->buf_lock); - - spi_message_init(&msg); - - memset(xfers, 0, sizeof(xfers)); - for (i = 0; i <= ADIS16240_OUTPUTS; i++) { - xfers[i].bits_per_word = 8; - xfers[i].cs_change = 1; - xfers[i].len = 2; - xfers[i].delay_usecs = 30; - xfers[i].tx_buf = st->tx + 2 * i; - st->tx[2 * i] - = ADIS16240_READ_REG(ADIS16240_SUPPLY_OUT + 2 * i); - st->tx[2 * i + 1] = 0; - if (i >= 1) - xfers[i].rx_buf = rx + 2 * (i - 1); - spi_message_add_tail(&xfers[i], &msg); - } - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when burst reading"); - - mutex_unlock(&st->buf_lock); - - return ret; -} - -static irqreturn_t adis16240_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct adis16240_state *st = iio_priv(indio_dev); - - int i = 0; - s16 *data; - - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (data == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - goto done; - } - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16240_read_ring_data(indio_dev, st->rx) >= 0) - for (; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - - iio_push_to_buffers(indio_dev, (u8 *)data); - - kfree(data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -void adis16240_unconfigure_ring(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); -} - -static const struct iio_buffer_setup_ops adis16240_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -int adis16240_configure_ring(struct iio_dev *indio_dev) -{ - int ret = 0; - struct iio_buffer *ring; - - ring = iio_sw_rb_allocate(indio_dev); - if (!ring) { - ret = -ENOMEM; - return ret; - } - indio_dev->buffer = ring; - ring->scan_timestamp = true; - indio_dev->setup_ops = &adis16240_ring_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &adis16240_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "%s_consumer%d", - indio_dev->name, - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->buffer); - return ret; -} diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c deleted file mode 100644 index f3caf09dcb8..00000000000 --- a/drivers/staging/iio/accel/adis16240_trigger.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include "adis16240.h" - -/** - * adis16240_data_rdy_trigger_set_state() set datardy interrupt state - **/ -static int adis16240_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct iio_dev *indio_dev = trig->private_data; - - dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16240_set_irq(indio_dev, state); -} - -static const struct iio_trigger_ops adis16240_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &adis16240_data_rdy_trigger_set_state, -}; - -int adis16240_probe_trigger(struct iio_dev *indio_dev) -{ - int ret; - struct adis16240_state *st = iio_priv(indio_dev); - - st->trig = iio_trigger_alloc("adis16240-dev%d", indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - ret = request_irq(st->us->irq, - iio_trigger_generic_data_rdy_poll, - IRQF_TRIGGER_RISING, - "adis16240", - st->trig); - if (ret) - goto error_free_trig; - - st->trig->dev.parent = &st->us->dev; - st->trig->ops = &adis16240_trigger_ops; - st->trig->private_data = indio_dev; - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->us->irq, st->trig); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -void adis16240_remove_trigger(struct iio_dev *indio_dev) -{ - struct adis16240_state *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); - free_irq(st->us->irq, st->trig); - iio_trigger_free(st->trig); -} -- cgit v1.2.3 From 9d5e9fdf0f8846e014125f8e57fe5f3e03c8839f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Nov 2012 13:28:00 +0000 Subject: staging:iio:adis16260: Use adis library Use the new adis library for the adis16260 driver. This allows us to completely scrap the adis16260 buffer and trigger code and about half of the core driver code. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/gyro/Makefile | 1 - drivers/staging/iio/gyro/adis16260.h | 84 +---- drivers/staging/iio/gyro/adis16260_core.c | 483 +++++---------------------- drivers/staging/iio/gyro/adis16260_ring.c | 136 -------- drivers/staging/iio/gyro/adis16260_trigger.c | 75 ----- 5 files changed, 94 insertions(+), 685 deletions(-) delete mode 100644 drivers/staging/iio/gyro/adis16260_ring.c delete mode 100644 drivers/staging/iio/gyro/adis16260_trigger.c diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile index 9ba5ec15170..1303569e5c8 100644 --- a/drivers/staging/iio/gyro/Makefile +++ b/drivers/staging/iio/gyro/Makefile @@ -12,7 +12,6 @@ adis16130-y := adis16130_core.o obj-$(CONFIG_ADIS16130) += adis16130.o adis16260-y := adis16260_core.o -adis16260-$(CONFIG_IIO_BUFFER) += adis16260_ring.o adis16260_trigger.o obj-$(CONFIG_ADIS16260) += adis16260.o adis16251-y := adis16251_core.o diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h index 4c4b25129c6..ea5eba205bb 100644 --- a/drivers/staging/iio/gyro/adis16260.h +++ b/drivers/staging/iio/gyro/adis16260.h @@ -1,12 +1,11 @@ #ifndef SPI_ADIS16260_H_ #define SPI_ADIS16260_H_ + #include "adis16260_platform_data.h" +#include "../imu/adis.h" #define ADIS16260_STARTUP_DELAY 220 /* ms */ -#define ADIS16260_READ_REG(a) a -#define ADIS16260_WRITE_REG(a) ((a) | 0x80) - #define ADIS16260_FLASH_CNT 0x00 /* Flash memory write count */ #define ADIS16260_SUPPLY_OUT 0x02 /* Power supply measurement */ #define ADIS16260_GYRO_OUT 0x04 /* X-axis gyroscope output */ @@ -34,8 +33,6 @@ * convert to decimal = 16,265/16,260 */ #define ADIS16260_SERIAL_NUM 0x58 /* Serial number */ -#define ADIS16260_OUTPUTS 5 - #define ADIS16260_ERROR_ACTIVE (1<<14) #define ADIS16260_NEW_DATA (1<<15) @@ -60,13 +57,13 @@ /* DIAG_STAT */ #define ADIS16260_DIAG_STAT_ALARM2 (1<<9) #define ADIS16260_DIAG_STAT_ALARM1 (1<<8) -#define ADIS16260_DIAG_STAT_FLASH_CHK (1<<6) -#define ADIS16260_DIAG_STAT_SELF_TEST (1<<5) -#define ADIS16260_DIAG_STAT_OVERFLOW (1<<4) -#define ADIS16260_DIAG_STAT_SPI_FAIL (1<<3) -#define ADIS16260_DIAG_STAT_FLASH_UPT (1<<2) -#define ADIS16260_DIAG_STAT_POWER_HIGH (1<<1) -#define ADIS16260_DIAG_STAT_POWER_LOW (1<<0) +#define ADIS16260_DIAG_STAT_FLASH_CHK_BIT 6 +#define ADIS16260_DIAG_STAT_SELF_TEST_BIT 5 +#define ADIS16260_DIAG_STAT_OVERFLOW_BIT 4 +#define ADIS16260_DIAG_STAT_SPI_FAIL_BIT 3 +#define ADIS16260_DIAG_STAT_FLASH_UPT_BIT 2 +#define ADIS16260_DIAG_STAT_POWER_HIGH_BIT 1 +#define ADIS16260_DIAG_STAT_POWER_LOW_BIT 0 /* GLOB_CMD */ #define ADIS16260_GLOB_CMD_SW_RESET (1<<7) @@ -75,82 +72,27 @@ #define ADIS16260_GLOB_CMD_FAC_CALIB (1<<1) #define ADIS16260_GLOB_CMD_AUTO_NULL (1<<0) -#define ADIS16260_MAX_TX 24 -#define ADIS16260_MAX_RX 24 - #define ADIS16260_SPI_SLOW (u32)(300 * 1000) #define ADIS16260_SPI_BURST (u32)(1000 * 1000) #define ADIS16260_SPI_FAST (u32)(2000 * 1000) /** * struct adis16260_state - device instance specific data - * @us: actual spi_device - * @trig: data ready trigger registered with iio - * @buf_lock: mutex to protect tx and rx * @negate: negate the scale parameter - * @tx: transmit buffer - * @rx: receive buffer **/ struct adis16260_state { - struct spi_device *us; - struct iio_trigger *trig; - struct mutex buf_lock; - unsigned negate:1; - u8 tx[ADIS16260_MAX_TX] ____cacheline_aligned; - u8 rx[ADIS16260_MAX_RX]; + unsigned negate:1; + struct adis adis; }; -int adis16260_set_irq(struct iio_dev *indio_dev, bool enable); - /* At the moment triggers are only used for ring buffer * filling. This may change! */ -#define ADIS16260_SCAN_SUPPLY 0 -#define ADIS16260_SCAN_GYRO 1 +#define ADIS16260_SCAN_GYRO 0 +#define ADIS16260_SCAN_SUPPLY 1 #define ADIS16260_SCAN_AUX_ADC 2 #define ADIS16260_SCAN_TEMP 3 #define ADIS16260_SCAN_ANGL 4 -#ifdef CONFIG_IIO_BUFFER -void adis16260_remove_trigger(struct iio_dev *indio_dev); -int adis16260_probe_trigger(struct iio_dev *indio_dev); - -ssize_t adis16260_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf); - - -int adis16260_configure_ring(struct iio_dev *indio_dev); -void adis16260_unconfigure_ring(struct iio_dev *indio_dev); - -#else /* CONFIG_IIO_BUFFER */ - -static inline void adis16260_remove_trigger(struct iio_dev *indio_dev) -{ -} - -static inline int adis16260_probe_trigger(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline ssize_t -adis16260_read_data_from_ring(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return 0; -} - -static int adis16260_configure_ring(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis16260_unconfigure_ring(struct iio_dev *indio_dev) -{ -} - -#endif /* CONFIG_IIO_BUFFER */ #endif /* SPI_ADIS16260_H_ */ diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index e822460502b..820547baae3 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -24,132 +24,13 @@ #include "adis16260.h" -static int adis16260_check_status(struct iio_dev *indio_dev); - -/** - * adis16260_spi_write_reg_8() - write single byte to a register - * @indio_dev: iio_dev for the device - * @reg_address: the address of the register to be written - * @val: the value to write - **/ -static int adis16260_spi_write_reg_8(struct iio_dev *indio_dev, - u8 reg_address, - u8 val) -{ - int ret; - struct adis16260_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16260_WRITE_REG(reg_address); - st->tx[1] = val; - - ret = spi_write(st->us, st->tx, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16260_spi_write_reg_16() - write 2 bytes to a pair of registers - * @indio_dev: iio_dev for the device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: value to be written - **/ -static int adis16260_spi_write_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 value) -{ - int ret; - struct spi_message msg; - struct adis16260_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 20, - }, { - .tx_buf = st->tx + 2, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 20, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16260_WRITE_REG(lower_reg_address); - st->tx[1] = value & 0xFF; - st->tx[2] = ADIS16260_WRITE_REG(lower_reg_address + 1); - st->tx[3] = (value >> 8) & 0xFF; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - mutex_unlock(&st->buf_lock); - - return ret; -} - -/** - * adis16260_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @indio_dev: iio_dev for the device - * @reg_address: the address of the lower of the two registers. Second register - * is assumed to have address one greater. - * @val: somewhere to pass back the value read - **/ -static int adis16260_spi_read_reg_16(struct iio_dev *indio_dev, - u8 lower_reg_address, - u16 *val) -{ - struct spi_message msg; - struct adis16260_state *st = iio_priv(indio_dev); - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = 30, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 2, - .delay_usecs = 30, - }, - }; - - mutex_lock(&st->buf_lock); - st->tx[0] = ADIS16260_READ_REG(lower_reg_address); - st->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); - if (ret) { - dev_err(&st->us->dev, - "problem when reading 16 bit register 0x%02X", - lower_reg_address); - goto error_ret; - } - *val = (st->rx[0] << 8) | st->rx[1]; - -error_ret: - mutex_unlock(&st->buf_lock); - return ret; -} - static ssize_t adis16260_read_frequency_available(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct adis16260_state *st = iio_priv(indio_dev); - if (spi_get_device_id(st->us)->driver_data) + if (spi_get_device_id(st->adis.spi)->driver_data) return sprintf(buf, "%s\n", "0.129 ~ 256"); else return sprintf(buf, "%s\n", "256 2048"); @@ -164,13 +45,11 @@ static ssize_t adis16260_read_frequency(struct device *dev, int ret, len = 0; u16 t; int sps; - ret = adis16260_spi_read_reg_16(indio_dev, - ADIS16260_SMPL_PRD, - &t); + ret = adis_read_reg_16(&st->adis, ADIS16260_SMPL_PRD, &t); if (ret) return ret; - if (spi_get_device_id(st->us)->driver_data) /* If an adis16251 */ + if (spi_get_device_id(st->adis.spi)->driver_data) /* If an adis16251 */ sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 8 : 256; else sps = (t & ADIS16260_SMPL_PRD_TIME_BASE) ? 66 : 2048; @@ -197,7 +76,7 @@ static ssize_t adis16260_write_frequency(struct device *dev, return -EINVAL; mutex_lock(&indio_dev->mlock); - if (spi_get_device_id(st->us)) { + if (spi_get_device_id(st->adis.spi)->driver_data) { t = (256 / val); if (t > 0) t--; @@ -209,10 +88,10 @@ static ssize_t adis16260_write_frequency(struct device *dev, t &= ADIS16260_SMPL_PRD_DIV_MASK; } if ((t & ADIS16260_SMPL_PRD_DIV_MASK) >= 0x0A) - st->us->max_speed_hz = ADIS16260_SPI_SLOW; + st->adis.spi->max_speed_hz = ADIS16260_SPI_SLOW; else - st->us->max_speed_hz = ADIS16260_SPI_FAST; - ret = adis16260_spi_write_reg_8(indio_dev, + st->adis.spi->max_speed_hz = ADIS16260_SPI_FAST; + ret = adis_write_reg_8(&st->adis, ADIS16260_SMPL_PRD, t); @@ -221,140 +100,20 @@ static ssize_t adis16260_write_frequency(struct device *dev, return ret ? ret : len; } -static int adis16260_reset(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16260_spi_write_reg_8(indio_dev, - ADIS16260_GLOB_CMD, - ADIS16260_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&indio_dev->dev, "problem resetting device"); - - return ret; -} - -int adis16260_set_irq(struct iio_dev *indio_dev, bool enable) -{ - int ret; - u16 msc; - ret = adis16260_spi_read_reg_16(indio_dev, ADIS16260_MSC_CTRL, &msc); - if (ret) - goto error_ret; - - msc |= ADIS16260_MSC_CTRL_DATA_RDY_POL_HIGH; - if (enable) - msc |= ADIS16260_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS16260_MSC_CTRL_DATA_RDY_EN; - - ret = adis16260_spi_write_reg_16(indio_dev, ADIS16260_MSC_CTRL, msc); - if (ret) - goto error_ret; - -error_ret: - return ret; -} - /* Power down the device */ static int adis16260_stop_device(struct iio_dev *indio_dev) { + struct adis16260_state *st = iio_priv(indio_dev); int ret; u16 val = ADIS16260_SLP_CNT_POWER_OFF; - ret = adis16260_spi_write_reg_16(indio_dev, ADIS16260_SLP_CNT, val); + ret = adis_write_reg_16(&st->adis, ADIS16260_SLP_CNT, val); if (ret) dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT"); return ret; } -static int adis16260_self_test(struct iio_dev *indio_dev) -{ - int ret; - ret = adis16260_spi_write_reg_16(indio_dev, - ADIS16260_MSC_CTRL, - ADIS16260_MSC_CTRL_MEM_TEST); - if (ret) { - dev_err(&indio_dev->dev, "problem starting self test"); - goto err_ret; - } - - adis16260_check_status(indio_dev); - -err_ret: - return ret; -} - -static int adis16260_check_status(struct iio_dev *indio_dev) -{ - u16 status; - int ret; - struct device *dev = &indio_dev->dev; - - ret = adis16260_spi_read_reg_16(indio_dev, - ADIS16260_DIAG_STAT, - &status); - - if (ret < 0) { - dev_err(dev, "Reading status failed\n"); - goto error_ret; - } - ret = status & 0x7F; - if (status & ADIS16260_DIAG_STAT_FLASH_CHK) - dev_err(dev, "Flash checksum error\n"); - if (status & ADIS16260_DIAG_STAT_SELF_TEST) - dev_err(dev, "Self test error\n"); - if (status & ADIS16260_DIAG_STAT_OVERFLOW) - dev_err(dev, "Sensor overrange\n"); - if (status & ADIS16260_DIAG_STAT_SPI_FAIL) - dev_err(dev, "SPI failure\n"); - if (status & ADIS16260_DIAG_STAT_FLASH_UPT) - dev_err(dev, "Flash update failed\n"); - if (status & ADIS16260_DIAG_STAT_POWER_HIGH) - dev_err(dev, "Power supply above 5.25V\n"); - if (status & ADIS16260_DIAG_STAT_POWER_LOW) - dev_err(dev, "Power supply below 4.75V\n"); - -error_ret: - return ret; -} - -static int adis16260_initial_setup(struct iio_dev *indio_dev) -{ - int ret; - struct device *dev = &indio_dev->dev; - - /* Disable IRQ */ - ret = adis16260_set_irq(indio_dev, false); - if (ret) { - dev_err(dev, "disable irq failed"); - goto err_ret; - } - - /* Do self test */ - ret = adis16260_self_test(indio_dev); - if (ret) { - dev_err(dev, "self test failure"); - goto err_ret; - } - - /* Read status register to check the result */ - ret = adis16260_check_status(indio_dev); - if (ret) { - adis16260_reset(indio_dev); - dev_err(dev, "device not playing ball -> reset"); - msleep(ADIS16260_STARTUP_DELAY); - ret = adis16260_check_status(indio_dev); - if (ret) { - dev_err(dev, "giving up"); - goto err_ret; - } - } - -err_ret: - return ret; -} - static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, adis16260_read_frequency, adis16260_write_frequency); @@ -362,100 +121,26 @@ static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, static IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO, adis16260_read_frequency_available, NULL, 0); -enum adis16260_channel { - gyro, - temp, - in_supply, - in_aux, - angle, -}; #define ADIS16260_GYRO_CHANNEL_SET(axis, mod) \ - struct iio_chan_spec adis16260_channels_##axis[] = { \ - { \ - .type = IIO_ANGL_VEL, \ - .modified = 1, \ - .channel2 = mod, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - .address = gyro, \ - .scan_index = ADIS16260_SCAN_GYRO, \ - .scan_type = { \ - .sign = 's', \ - .realbits = 14, \ - .storagebits = 16, \ - }, \ - }, { \ - .type = IIO_ANGL, \ - .modified = 1, \ - .channel2 = mod, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ - .address = angle, \ - .scan_index = ADIS16260_SCAN_ANGL, \ - .scan_type = { \ - .sign = 'u', \ - .realbits = 14, \ - .storagebits = 16, \ - }, \ - }, { \ - .type = IIO_TEMP, \ - .indexed = 1, \ - .channel = 0, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - .address = temp, \ - .scan_index = ADIS16260_SCAN_TEMP, \ - .scan_type = { \ - .sign = 'u', \ - .realbits = 12, \ - .storagebits = 16, \ - }, \ - }, { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = 0, \ - .extend_name = "supply", \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - .address = in_supply, \ - .scan_index = ADIS16260_SCAN_SUPPLY, \ - .scan_type = { \ - .sign = 'u', \ - .realbits = 12, \ - .storagebits = 16, \ - }, \ - }, { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = 1, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - .address = in_aux, \ - .scan_index = ADIS16260_SCAN_AUX_ADC, \ - .scan_type = { \ - .sign = 'u', \ - .realbits = 12, \ - .storagebits = 16, \ - }, \ - }, \ - IIO_CHAN_SOFT_TIMESTAMP(5), \ - } +struct iio_chan_spec adis16260_channels_##axis[] = { \ + ADIS_GYRO_CHAN(mod, ADIS16260_GYRO_OUT, ADIS16260_SCAN_GYRO, \ + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, 14), \ + ADIS_INCLI_CHAN(mod, ADIS16260_ANGL_OUT, ADIS16260_SCAN_ANGL, 0, 14), \ + ADIS_TEMP_CHAN(ADIS16260_TEMP_OUT, ADIS16260_SCAN_TEMP, 12), \ + ADIS_SUPPLY_CHAN(ADIS16260_SUPPLY_OUT, ADIS16260_SCAN_SUPPLY, 12), \ + ADIS_AUX_ADC_CHAN(ADIS16260_AUX_ADC, ADIS16260_SCAN_AUX_ADC, 12), \ + IIO_CHAN_SOFT_TIMESTAMP(5), \ +} -static const ADIS16260_GYRO_CHANNEL_SET(x, IIO_MOD_X); -static const ADIS16260_GYRO_CHANNEL_SET(y, IIO_MOD_Y); -static const ADIS16260_GYRO_CHANNEL_SET(z, IIO_MOD_Z); - -static const u8 adis16260_addresses[5][3] = { - [gyro] = { ADIS16260_GYRO_OUT, - ADIS16260_GYRO_OFF, - ADIS16260_GYRO_SCALE }, - [angle] = { ADIS16260_ANGL_OUT }, - [in_supply] = { ADIS16260_SUPPLY_OUT }, - [in_aux] = { ADIS16260_AUX_ADC }, - [temp] = { ADIS16260_TEMP_OUT }, +static const ADIS16260_GYRO_CHANNEL_SET(x, X); +static const ADIS16260_GYRO_CHANNEL_SET(y, Y); +static const ADIS16260_GYRO_CHANNEL_SET(z, Z); + +static const u8 adis16260_addresses[][2] = { + [ADIS16260_SCAN_GYRO] = { ADIS16260_GYRO_OFF, ADIS16260_GYRO_SCALE }, }; + static int adis16260_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, @@ -469,34 +154,13 @@ static int adis16260_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - addr = adis16260_addresses[chan->address][0]; - ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - - if (val16 & ADIS16260_ERROR_ACTIVE) { - ret = adis16260_check_status(indio_dev); - if (ret) { - mutex_unlock(&indio_dev->mlock); - return ret; - } - } - val16 = val16 & ((1 << chan->scan_type.realbits) - 1); - if (chan->scan_type.sign == 's') - val16 = (s16)(val16 << - (16 - chan->scan_type.realbits)) >> - (16 - chan->scan_type.realbits); - *val = val16; - mutex_unlock(&indio_dev->mlock); - return IIO_VAL_INT; + return adis_single_conversion(indio_dev, chan, + ADIS16260_ERROR_ACTIVE, val); case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_ANGL_VEL: *val = 0; - if (spi_get_device_id(st->us)->driver_data) { + if (spi_get_device_id(st->adis.spi)->driver_data) { /* 0.01832 degree / sec */ *val2 = IIO_DEGREE_TO_RAD(18320); } else { @@ -533,8 +197,8 @@ static int adis16260_read_raw(struct iio_dev *indio_dev, return -EINVAL; } mutex_lock(&indio_dev->mlock); - addr = adis16260_addresses[chan->address][1]; - ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16260_addresses[chan->scan_index][0]; + ret = adis_read_reg_16(&st->adis, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -553,8 +217,8 @@ static int adis16260_read_raw(struct iio_dev *indio_dev, return -EINVAL; } mutex_lock(&indio_dev->mlock); - addr = adis16260_addresses[chan->address][2]; - ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16); + addr = adis16260_addresses[chan->scan_index][1]; + ret = adis_read_reg_16(&st->adis, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); return ret; @@ -572,18 +236,19 @@ static int adis16260_write_raw(struct iio_dev *indio_dev, int val2, long mask) { + struct adis16260_state *st = iio_priv(indio_dev); int bits = 12; s16 val16; u8 addr; switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: val16 = val & ((1 << bits) - 1); - addr = adis16260_addresses[chan->address][1]; - return adis16260_spi_write_reg_16(indio_dev, addr, val16); + addr = adis16260_addresses[chan->scan_index][0]; + return adis_write_reg_16(&st->adis, addr, val16); case IIO_CHAN_INFO_CALIBSCALE: val16 = val & ((1 << bits) - 1); - addr = adis16260_addresses[chan->address][2]; - return adis16260_spi_write_reg_16(indio_dev, addr, val16); + addr = adis16260_addresses[chan->scan_index][1]; + return adis_write_reg_16(&st->adis, addr, val16); } return -EINVAL; } @@ -605,6 +270,36 @@ static const struct iio_info adis16260_info = { .driver_module = THIS_MODULE, }; +static const char * const adis1620_status_error_msgs[] = { + [ADIS16260_DIAG_STAT_FLASH_CHK_BIT] = "Flash checksum error", + [ADIS16260_DIAG_STAT_SELF_TEST_BIT] = "Self test error", + [ADIS16260_DIAG_STAT_OVERFLOW_BIT] = "Sensor overrange", + [ADIS16260_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure", + [ADIS16260_DIAG_STAT_FLASH_UPT_BIT] = "Flash update failed", + [ADIS16260_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 5.25", + [ADIS16260_DIAG_STAT_POWER_LOW_BIT] = "Power supply below 4.75", +}; + +static const struct adis_data adis16260_data = { + .write_delay = 30, + .read_delay = 30, + .msc_ctrl_reg = ADIS16260_MSC_CTRL, + .glob_cmd_reg = ADIS16260_GLOB_CMD, + .diag_stat_reg = ADIS16260_DIAG_STAT, + + .self_test_mask = ADIS16260_MSC_CTRL_MEM_TEST, + .startup_delay = ADIS16260_STARTUP_DELAY, + + .status_error_msgs = adis1620_status_error_msgs, + .status_error_mask = BIT(ADIS16260_DIAG_STAT_FLASH_CHK_BIT) | + BIT(ADIS16260_DIAG_STAT_SELF_TEST_BIT) | + BIT(ADIS16260_DIAG_STAT_OVERFLOW_BIT) | + BIT(ADIS16260_DIAG_STAT_SPI_FAIL_BIT) | + BIT(ADIS16260_DIAG_STAT_FLASH_UPT_BIT) | + BIT(ADIS16260_DIAG_STAT_POWER_HIGH_BIT) | + BIT(ADIS16260_DIAG_STAT_POWER_LOW_BIT), +}; + static int __devinit adis16260_probe(struct spi_device *spi) { int ret; @@ -624,10 +319,7 @@ static int __devinit adis16260_probe(struct spi_device *spi) /* this is only used for removal purposes */ spi_set_drvdata(spi, indio_dev); - st->us = spi; - mutex_init(&st->buf_lock); - - indio_dev->name = spi_get_device_id(st->us)->name; + indio_dev->name = spi_get_device_id(spi)->name; indio_dev->dev.parent = &spi->dev; indio_dev->info = &adis16260_info; indio_dev->num_channels @@ -651,17 +343,14 @@ static int __devinit adis16260_probe(struct spi_device *spi) indio_dev->num_channels = ARRAY_SIZE(adis16260_channels_x); indio_dev->modes = INDIO_DIRECT_MODE; - ret = adis16260_configure_ring(indio_dev); + ret = adis_init(&st->adis, indio_dev, spi, &adis16260_data); + if (ret) + goto error_free_dev; + + ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); if (ret) goto error_free_dev; - ret = iio_buffer_register(indio_dev, - indio_dev->channels, - ARRAY_SIZE(adis16260_channels_x)); - if (ret) { - printk(KERN_ERR "failed to initialize the ring\n"); - goto error_unreg_ring_funcs; - } if (indio_dev->buffer) { /* Set default scan mode */ iio_scan_mask_set(indio_dev, indio_dev->buffer, @@ -675,28 +364,19 @@ static int __devinit adis16260_probe(struct spi_device *spi) iio_scan_mask_set(indio_dev, indio_dev->buffer, ADIS16260_SCAN_ANGL); } - if (spi->irq) { - ret = adis16260_probe_trigger(indio_dev); - if (ret) - goto error_uninitialize_ring; - } /* Get the device into a sane initial state */ - ret = adis16260_initial_setup(indio_dev); + ret = adis_initial_startup(&st->adis); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; ret = iio_device_register(indio_dev); if (ret) - goto error_remove_trigger; + goto error_cleanup_buffer_trigger; return 0; -error_remove_trigger: - adis16260_remove_trigger(indio_dev); -error_uninitialize_ring: - iio_buffer_unregister(indio_dev); -error_unreg_ring_funcs: - adis16260_unconfigure_ring(indio_dev); +error_cleanup_buffer_trigger: + adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); error_free_dev: iio_device_free(indio_dev); error_ret: @@ -706,12 +386,11 @@ error_ret: static int __devexit adis16260_remove(struct spi_device *spi) { struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis16260_state *st = iio_priv(indio_dev); iio_device_unregister(indio_dev); adis16260_stop_device(indio_dev); - adis16260_remove_trigger(indio_dev); - iio_buffer_unregister(indio_dev); - adis16260_unconfigure_ring(indio_dev); + adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); iio_device_free(indio_dev); return 0; diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c deleted file mode 100644 index d6c48f850a9..00000000000 --- a/drivers/staging/iio/gyro/adis16260_ring.c +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include "../ring_sw.h" -#include -#include "adis16260.h" - -/** - * adis16260_read_ring_data() read data registers which will be placed into ring - * @indio_dev: the IIO device - * @rx: somewhere to pass back the value read - **/ -static int adis16260_read_ring_data(struct iio_dev *indio_dev, u8 *rx) -{ - struct spi_message msg; - struct adis16260_state *st = iio_priv(indio_dev); - struct spi_transfer xfers[ADIS16260_OUTPUTS + 1]; - int ret; - int i; - - mutex_lock(&st->buf_lock); - - spi_message_init(&msg); - - memset(xfers, 0, sizeof(xfers)); - for (i = 0; i <= ADIS16260_OUTPUTS; i++) { - xfers[i].bits_per_word = 8; - xfers[i].cs_change = 1; - xfers[i].len = 2; - xfers[i].delay_usecs = 30; - xfers[i].tx_buf = st->tx + 2 * i; - if (i < 2) /* SUPPLY_OUT:0x02 GYRO_OUT:0x04 */ - st->tx[2 * i] - = ADIS16260_READ_REG(ADIS16260_SUPPLY_OUT - + 2 * i); - else /* 0x06 to 0x09 is reserved */ - st->tx[2 * i] - = ADIS16260_READ_REG(ADIS16260_SUPPLY_OUT - + 2 * i + 4); - st->tx[2 * i + 1] = 0; - if (i >= 1) - xfers[i].rx_buf = rx + 2 * (i - 1); - spi_message_add_tail(&xfers[i], &msg); - } - - ret = spi_sync(st->us, &msg); - if (ret) - dev_err(&st->us->dev, "problem when burst reading"); - - mutex_unlock(&st->buf_lock); - - return ret; -} - -static irqreturn_t adis16260_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct adis16260_state *st = iio_priv(indio_dev); - int i = 0; - s16 *data; - - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (data == NULL) { - dev_err(&st->us->dev, "memory alloc failed in ring bh"); - goto done; - } - - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) && - adis16260_read_ring_data(indio_dev, st->rx) >= 0) - for (; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2])); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp; - - iio_push_to_buffers(indio_dev, (u8 *)data); - - kfree(data); -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -void adis16260_unconfigure_ring(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); -} - -static const struct iio_buffer_setup_ops adis16260_ring_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -int adis16260_configure_ring(struct iio_dev *indio_dev) -{ - int ret = 0; - struct iio_buffer *ring; - - ring = iio_sw_rb_allocate(indio_dev); - if (!ring) { - ret = -ENOMEM; - return ret; - } - indio_dev->buffer = ring; - ring->scan_timestamp = true; - indio_dev->setup_ops = &adis16260_ring_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - &adis16260_trigger_handler, - IRQF_ONESHOT, - indio_dev, - "adis16260_consumer%d", - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->buffer); - return ret; -} diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c deleted file mode 100644 index 034559e4d5b..00000000000 --- a/drivers/staging/iio/gyro/adis16260_trigger.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include -#include - -#include -#include -#include "adis16260.h" - -/** - * adis16260_data_rdy_trigger_set_state() set datardy interrupt state - **/ -static int adis16260_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct iio_dev *indio_dev = trig->private_data; - - dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); - return adis16260_set_irq(indio_dev, state); -} - -static const struct iio_trigger_ops adis16260_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &adis16260_data_rdy_trigger_set_state, -}; - -int adis16260_probe_trigger(struct iio_dev *indio_dev) -{ - int ret; - struct adis16260_state *st = iio_priv(indio_dev); - - st->trig = iio_trigger_alloc("%s-dev%d", - spi_get_device_id(st->us)->name, - indio_dev->id); - if (st->trig == NULL) { - ret = -ENOMEM; - goto error_ret; - } - - ret = request_irq(st->us->irq, - &iio_trigger_generic_data_rdy_poll, - IRQF_TRIGGER_RISING, - "adis16260", - st->trig); - if (ret) - goto error_free_trig; - - st->trig->dev.parent = &st->us->dev; - st->trig->ops = &adis16260_trigger_ops; - st->trig->private_data = indio_dev; - ret = iio_trigger_register(st->trig); - - /* select default trigger */ - indio_dev->trig = st->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(st->us->irq, st->trig); -error_free_trig: - iio_trigger_free(st->trig); -error_ret: - return ret; -} - -void adis16260_remove_trigger(struct iio_dev *indio_dev) -{ - struct adis16260_state *st = iio_priv(indio_dev); - - iio_trigger_unregister(st->trig); - free_irq(st->us->irq, st->trig); - iio_trigger_free(st->trig); -} -- cgit v1.2.3 From a458c55c107c5e467ab5b7e471f77ec5868afcb9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Nov 2012 13:28:00 +0000 Subject: staging:iio:adis_lib: Use triggered buffer setup helper function Use the triggered buffer helper functions to setup and tear down the buffer for the adis library instead of doing this manually. This also means that we switch away from the deprecated sw_ring buffer and use the kfifo buffer now instead. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/imu/Kconfig | 3 +- drivers/staging/iio/imu/adis_buffer.c | 78 +++++------------------------------ 2 files changed, 11 insertions(+), 70 deletions(-) diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig index 89b9f2566b8..2c564edeb17 100644 --- a/drivers/staging/iio/imu/Kconfig +++ b/drivers/staging/iio/imu/Kconfig @@ -23,8 +23,7 @@ config IIO_ADIS_LIB config IIO_ADIS_LIB_BUFFER bool - select IIO_TRIGGER - select IIO_SW_RING + select IIO_TRIGGERED_BUFFER help A set of buffer helper functions for the Analog Devices ADIS* device family. diff --git a/drivers/staging/iio/imu/adis_buffer.c b/drivers/staging/iio/imu/adis_buffer.c index 47bdea09f68..0fa8e80a54b 100644 --- a/drivers/staging/iio/imu/adis_buffer.c +++ b/drivers/staging/iio/imu/adis_buffer.c @@ -7,8 +7,8 @@ #include #include -#include "../ring_sw.h" #include +#include #include "adis.h" @@ -83,56 +83,6 @@ static irqreturn_t adis_trigger_handler(int irq, void *p) return IRQ_HANDLED; } -static const struct iio_buffer_setup_ops adis_buffer_setup_ops = { - .preenable = &iio_sw_buffer_preenable, - .postenable = &iio_triggered_buffer_postenable, - .predisable = &iio_triggered_buffer_predisable, -}; - -static int adis_buffer_setup(struct iio_dev *indio_dev, - irqreturn_t (*trigger_handler)(int, void *)) -{ - int ret = 0; - struct iio_buffer *buffer; - - if (!trigger_handler) - trigger_handler = &adis_trigger_handler; - - buffer = iio_sw_rb_allocate(indio_dev); - if (!buffer) { - ret = -ENOMEM; - return ret; - } - - indio_dev->buffer = buffer; - indio_dev->setup_ops = &adis_buffer_setup_ops; - - indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, - trigger_handler, - IRQF_ONESHOT, - indio_dev, - "%s_consumer%d", - indio_dev->name, - indio_dev->id); - if (indio_dev->pollfunc == NULL) { - ret = -ENOMEM; - goto error_iio_sw_rb_free; - } - - indio_dev->modes |= INDIO_BUFFER_TRIGGERED; - return 0; - -error_iio_sw_rb_free: - iio_sw_rb_free(indio_dev->buffer); - return ret; -} - -static void adis_buffer_cleanup(struct iio_dev *indio_dev) -{ - iio_dealloc_pollfunc(indio_dev->pollfunc); - iio_sw_rb_free(indio_dev->buffer); -} - /** * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device * @adis: The adis device. @@ -154,30 +104,23 @@ int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, { int ret; - ret = adis_buffer_setup(indio_dev, trigger_handler); + if (!trigger_handler) + trigger_handler = adis_trigger_handler; + + ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + trigger_handler, NULL); if (ret) return ret; - ret = iio_buffer_register(indio_dev, - indio_dev->channels, - indio_dev->num_channels); - if (ret) { - dev_err(&adis->spi->dev, "Failed to initialize buffer %d\n", - ret); - goto error_unreg_buffer_funcs; - } - if (adis->spi->irq) { ret = adis_probe_trigger(adis, indio_dev); if (ret) - goto error_uninitialize_buffer; + goto error_buffer_cleanup; } return 0; -error_uninitialize_buffer: - iio_buffer_unregister(indio_dev); -error_unreg_buffer_funcs: - adis_buffer_cleanup(indio_dev); +error_buffer_cleanup: + iio_triggered_buffer_cleanup(indio_dev); return ret; } EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); @@ -194,7 +137,6 @@ void adis_cleanup_buffer_and_trigger(struct adis *adis, { if (adis->spi->irq) adis_remove_trigger(adis); - iio_buffer_unregister(indio_dev); - adis_buffer_cleanup(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); } EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger); -- cgit v1.2.3 From aacff892cbd5c6b1904a3906219548a65018d750 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Nov 2012 13:28:00 +0000 Subject: staging:iio:adis: Preallocate transfer message Currently the driver reads out all sample registers of the device and throws away those which it does not need. Furthermore the SPI message is constructed each time the trigger handler is run, although it will be the same each time. This patch preallocates and pre-constructs the SPI message in the "update_scan_mode" callback. Only those register which are actually selected for sampling are included in the message. The patch also gets rid of the conversion of the sample data from big endian to the native endianness and instead marks the channel as big endian in its scan type. This allows to directly push the SPI transfer buffer to the IIO buffer without the need to post-process it. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/adis16201_core.c | 1 + drivers/staging/iio/accel/adis16203_core.c | 1 + drivers/staging/iio/accel/adis16204_core.c | 1 + drivers/staging/iio/accel/adis16209_core.c | 1 + drivers/staging/iio/accel/adis16240_core.c | 1 + drivers/staging/iio/gyro/adis16260_core.c | 1 + drivers/staging/iio/imu/adis.h | 8 ++ drivers/staging/iio/imu/adis_buffer.c | 114 +++++++++++++++++------------ 8 files changed, 80 insertions(+), 48 deletions(-) diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 0121501dc63..833dd6b73bc 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -148,6 +148,7 @@ static const struct iio_chan_spec adis16201_channels[] = { static const struct iio_info adis16201_info = { .read_raw = &adis16201_read_raw, .write_raw = &adis16201_write_raw, + .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index 326b1067543..f631e578fbd 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -112,6 +112,7 @@ static const struct iio_chan_spec adis16203_channels[] = { static const struct iio_info adis16203_info = { .read_raw = &adis16203_read_raw, .write_raw = &adis16203_write_raw, + .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 4f69ead1ae8..dbec841ce30 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -153,6 +153,7 @@ static const struct iio_chan_spec adis16204_channels[] = { static const struct iio_info adis16204_info = { .read_raw = &adis16204_read_raw, .write_raw = &adis16204_write_raw, + .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index e203e96a566..f9f9d582b32 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -146,6 +146,7 @@ static const struct iio_chan_spec adis16209_channels[] = { static const struct iio_info adis16209_info = { .read_raw = &adis16209_read_raw, .write_raw = &adis16209_write_raw, + .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 019a31e2203..3d1a8a9921a 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -202,6 +202,7 @@ static const struct iio_info adis16240_info = { .attrs = &adis16240_attribute_group, .read_raw = &adis16240_read_raw, .write_raw = &adis16240_write_raw, + .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 820547baae3..b988b4f5bdd 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -267,6 +267,7 @@ static const struct iio_info adis16260_info = { .attrs = &adis16260_attribute_group, .read_raw = &adis16260_read_raw, .write_raw = &adis16260_write_raw, + .update_scan_mode = adis_update_scan_mode, .driver_module = THIS_MODULE, }; diff --git a/drivers/staging/iio/imu/adis.h b/drivers/staging/iio/imu/adis.h index c84da7afe14..8c3304d44b9 100644 --- a/drivers/staging/iio/imu/adis.h +++ b/drivers/staging/iio/imu/adis.h @@ -87,6 +87,7 @@ int adis_single_conversion(struct iio_dev *indio_dev, .sign = 'u', \ .realbits = (bits), \ .storagebits = 16, \ + .endianness = IIO_BE, \ }, \ } @@ -109,6 +110,7 @@ int adis_single_conversion(struct iio_dev *indio_dev, .sign = 'u', \ .realbits = (bits), \ .storagebits = 16, \ + .endianness = IIO_BE, \ }, \ } @@ -125,6 +127,7 @@ int adis_single_conversion(struct iio_dev *indio_dev, .sign = 's', \ .realbits = (bits), \ .storagebits = 16, \ + .endianness = IIO_BE, \ }, \ } @@ -150,6 +153,9 @@ void adis_cleanup_buffer_and_trigger(struct adis *adis, int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); void adis_remove_trigger(struct adis *adis); +int adis_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask); + #else /* CONFIG_IIO_BUFFER */ static inline int adis_setup_buffer_and_trigger(struct adis *adis, @@ -173,6 +179,8 @@ static inline void adis_remove_trigger(struct adis *adis) { } +#define adis_update_scan_mode NULL + #endif /* CONFIG_IIO_BUFFER */ #endif diff --git a/drivers/staging/iio/imu/adis_buffer.c b/drivers/staging/iio/imu/adis_buffer.c index 0fa8e80a54b..342758c14d2 100644 --- a/drivers/staging/iio/imu/adis_buffer.c +++ b/drivers/staging/iio/imu/adis_buffer.c @@ -1,3 +1,12 @@ +/* + * Common library for ADIS16XXX devices + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + #include #include #include @@ -12,73 +21,80 @@ #include "adis.h" -#define ADIS_MAX_OUTPUTS 12 - -static int adis_read_buffer_data(struct adis *adis, struct iio_dev *indio_dev) +int adis_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) { - int n_outputs = indio_dev->num_channels; - struct spi_transfer xfers[ADIS_MAX_OUTPUTS + 1]; - struct spi_message msg; - int ret; - int i; - - mutex_lock(&adis->txrx_lock); - - spi_message_init(&msg); - - memset(xfers, 0, sizeof(xfers)); - for (i = 0; i <= n_outputs; i++) { - xfers[i].bits_per_word = 8; - xfers[i].cs_change = 1; - xfers[i].len = 2; - xfers[i].delay_usecs = adis->data->read_delay; - if (i < n_outputs) { - xfers[i].tx_buf = adis->tx + 2 * i; - adis->tx[2 * i] = indio_dev->channels[i].address; - adis->tx[2 * i + 1] = 0; - } - if (i >= 1) - xfers[i].rx_buf = adis->rx + 2 * (i - 1); - spi_message_add_tail(&xfers[i], &msg); - } + struct adis *adis = iio_device_get_drvdata(indio_dev); + const struct iio_chan_spec *chan; + unsigned int scan_count; + unsigned int i, j; + __be16 *tx, *rx; - ret = spi_sync(adis->spi, &msg); - if (ret) - dev_err(&adis->spi->dev, "Failed to read data: %d", ret); + kfree(adis->xfer); + kfree(adis->buffer); - mutex_unlock(&adis->txrx_lock); + scan_count = indio_dev->scan_bytes / 2; - return ret; + adis->xfer = kcalloc(scan_count + 1, sizeof(*adis->xfer), GFP_KERNEL); + if (!adis->xfer) + return -ENOMEM; + + adis->buffer = kzalloc(indio_dev->scan_bytes * 2, GFP_KERNEL); + if (!adis->buffer) + return -ENOMEM; + + rx = adis->buffer; + tx = rx + indio_dev->scan_bytes; + + spi_message_init(&adis->msg); + + for (j = 0; j <= scan_count; j++) { + adis->xfer[j].bits_per_word = 8; + if (j != scan_count) + adis->xfer[j].cs_change = 1; + adis->xfer[j].len = 2; + adis->xfer[j].delay_usecs = adis->data->read_delay; + if (j < scan_count) + adis->xfer[j].tx_buf = &tx[j]; + if (j >= 1) + adis->xfer[j].rx_buf = &rx[j - 1]; + spi_message_add_tail(&adis->xfer[j], &adis->msg); + } + + chan = indio_dev->channels; + for (i = 0; i < indio_dev->num_channels; i++, chan++) { + if (!test_bit(chan->scan_index, scan_mask)) + continue; + *tx++ = cpu_to_be16(chan->address << 8); + } + + return 0; } +EXPORT_SYMBOL_GPL(adis_update_scan_mode); static irqreturn_t adis_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adis *adis = iio_device_get_drvdata(indio_dev); - u16 *data; - int i = 0; + int ret; - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); - if (data == NULL) { - dev_err(&adis->spi->dev, "Failed to allocate memory."); + if (!adis->buffer) return -ENOMEM; - } - if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength) - && adis_read_buffer_data(adis, indio_dev) >= 0) - for (; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - data[i] = be16_to_cpup((__be16 *)&(adis->rx[i*2])); + ret = spi_sync(adis->spi, &adis->msg); + if (ret) + dev_err(&adis->spi->dev, "Failed to read data: %d", ret); /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) - *((s64 *)(PTR_ALIGN(data, sizeof(s64)))) = pf->timestamp; + if (indio_dev->scan_timestamp) { + void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64); + *(s64 *)b = pf->timestamp; + } - iio_push_to_buffers(indio_dev, (u8 *)data); + iio_push_to_buffers(indio_dev, adis->buffer); iio_trigger_notify_done(indio_dev->trig); - kfree(data); return IRQ_HANDLED; } @@ -137,6 +153,8 @@ void adis_cleanup_buffer_and_trigger(struct adis *adis, { if (adis->spi->irq) adis_remove_trigger(adis); + kfree(adis->buffer); + kfree(adis->xfer); iio_triggered_buffer_cleanup(indio_dev); } EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger); -- cgit v1.2.3 From ec04cb048d79cd778c06e28f34395a46d774800d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 13 Nov 2012 13:28:00 +0000 Subject: staging:iio: Move adis library out of staging Now that the adis library no longer depends on the sw_ring buffer implementation we can move it out of staging. While we are at it also sort the entries in the iio Kconfig and Makefile to be in alphabetical order. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/Kconfig | 7 +- drivers/iio/Makefile | 7 +- drivers/iio/imu/Kconfig | 11 + drivers/iio/imu/Makefile | 8 + drivers/iio/imu/adis.c | 337 ++++++++++++++++++++++++++++ drivers/iio/imu/adis_buffer.c | 159 ++++++++++++++ drivers/iio/imu/adis_trigger.c | 89 ++++++++ drivers/staging/iio/accel/adis16201_core.c | 2 +- drivers/staging/iio/accel/adis16203_core.c | 2 +- drivers/staging/iio/accel/adis16204_core.c | 2 +- drivers/staging/iio/accel/adis16209_core.c | 2 +- drivers/staging/iio/accel/adis16220.h | 2 +- drivers/staging/iio/accel/adis16240_core.c | 2 +- drivers/staging/iio/gyro/adis16260.h | 2 +- drivers/staging/iio/imu/Kconfig | 12 - drivers/staging/iio/imu/Makefile | 5 - drivers/staging/iio/imu/adis.c | 338 ----------------------------- drivers/staging/iio/imu/adis.h | 186 ---------------- drivers/staging/iio/imu/adis_buffer.c | 160 -------------- drivers/staging/iio/imu/adis_trigger.c | 90 -------- include/linux/iio/imu/adis.h | 186 ++++++++++++++++ 21 files changed, 805 insertions(+), 804 deletions(-) create mode 100644 drivers/iio/imu/Kconfig create mode 100644 drivers/iio/imu/Makefile create mode 100644 drivers/iio/imu/adis.c create mode 100644 drivers/iio/imu/adis_buffer.c create mode 100644 drivers/iio/imu/adis_trigger.c delete mode 100644 drivers/staging/iio/imu/adis.c delete mode 100644 drivers/staging/iio/imu/adis.h delete mode 100644 drivers/staging/iio/imu/adis_buffer.c delete mode 100644 drivers/staging/iio/imu/adis_trigger.c create mode 100644 include/linux/iio/imu/adis.h diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 65ae734c607..b2f963be399 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -63,11 +63,12 @@ config IIO_CONSUMERS_PER_TRIGGER source "drivers/iio/accel/Kconfig" source "drivers/iio/adc/Kconfig" source "drivers/iio/amplifiers/Kconfig" -source "drivers/iio/light/Kconfig" -source "drivers/iio/frequency/Kconfig" -source "drivers/iio/dac/Kconfig" source "drivers/iio/common/Kconfig" +source "drivers/iio/dac/Kconfig" +source "drivers/iio/frequency/Kconfig" source "drivers/iio/gyro/Kconfig" +source "drivers/iio/imu/Kconfig" +source "drivers/iio/light/Kconfig" source "drivers/iio/magnetometer/Kconfig" endif # IIO diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile index 31d76a07ec6..a0e8cdd67e4 100644 --- a/drivers/iio/Makefile +++ b/drivers/iio/Makefile @@ -14,9 +14,10 @@ obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o obj-y += accel/ obj-y += adc/ obj-y += amplifiers/ -obj-y += light/ -obj-y += frequency/ -obj-y += dac/ obj-y += common/ +obj-y += dac/ obj-y += gyro/ +obj-y += frequency/ +obj-y += imu/ +obj-y += light/ obj-y += magnetometer/ diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig new file mode 100644 index 00000000000..c24410c873c --- /dev/null +++ b/drivers/iio/imu/Kconfig @@ -0,0 +1,11 @@ +config IIO_ADIS_LIB + tristate + help + A set of IO helper functions for the Analog Devices ADIS* device family. + +config IIO_ADIS_LIB_BUFFER + bool + select IIO_TRIGGERED_BUFFER + help + A set of buffer helper functions for the Analog Devices ADIS* device + family. diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile new file mode 100644 index 00000000000..97676ab5723 --- /dev/null +++ b/drivers/iio/imu/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for Inertial Measurement Units +# + +adis_lib-y += adis.o +adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_trigger.o +adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o +obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c new file mode 100644 index 00000000000..8259b774078 --- /dev/null +++ b/drivers/iio/imu/adis.c @@ -0,0 +1,337 @@ +/* + * Common library for ADIS16XXX devices + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define ADIS_MSC_CTRL_DATA_RDY_EN BIT(2) +#define ADIS_MSC_CTRL_DATA_RDY_POL_HIGH BIT(1) +#define ADIS_MSC_CTRL_DATA_RDY_DIO2 BIT(0) +#define ADIS_GLOB_CMD_SW_RESET BIT(7) + +/** + * adis_write_reg_8() - Write single byte to a register + * @adis: The adis device + * @reg: The address of the register to be written + * @val: The value to write + */ +int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val) +{ + int ret; + + mutex_lock(&adis->txrx_lock); + adis->tx[0] = ADIS_WRITE_REG(reg); + adis->tx[1] = val; + + ret = spi_write(adis->spi, adis->tx, 2); + mutex_unlock(&adis->txrx_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(adis_write_reg_8); + +/** + * adis_write_reg_16() - Write 2 bytes to a pair of registers + * @adis: The adis device + * @reg: The address of the lower of the two registers + * @val: Value to be written + */ +int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t value) +{ + int ret; + struct spi_message msg; + struct spi_transfer xfers[] = { + { + .tx_buf = adis->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = adis->data->write_delay, + }, { + .tx_buf = adis->tx + 2, + .bits_per_word = 8, + .len = 2, + .delay_usecs = adis->data->write_delay, + }, + }; + + mutex_lock(&adis->txrx_lock); + adis->tx[0] = ADIS_WRITE_REG(reg); + adis->tx[1] = value & 0xff; + adis->tx[2] = ADIS_WRITE_REG(reg + 1); + adis->tx[3] = (value >> 8) & 0xff; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(adis->spi, &msg); + mutex_unlock(&adis->txrx_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(adis_write_reg_16); + +/** + * adis_read_reg_16() - read 2 bytes from a 16-bit register + * @adis: The adis device + * @reg: The address of the lower of the two registers + * @val: The value read back from the device + */ +int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val) +{ + struct spi_message msg; + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = adis->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = adis->data->read_delay, + }, { + .rx_buf = adis->rx, + .bits_per_word = 8, + .len = 2, + .delay_usecs = adis->data->read_delay, + }, + }; + + mutex_lock(&adis->txrx_lock); + adis->tx[0] = ADIS_READ_REG(reg); + adis->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(adis->spi, &msg); + if (ret) { + dev_err(&adis->spi->dev, "Failed to read 16 bit register 0x%02X: %d\n", + reg, ret); + goto error_ret; + } + *val = get_unaligned_be16(adis->rx); + +error_ret: + mutex_unlock(&adis->txrx_lock); + return ret; +} +EXPORT_SYMBOL_GPL(adis_read_reg_16); + +/** + * adis_enable_irq() - Enable or disable data ready IRQ + * @adis: The adis device + * @enable: Whether to enable the IRQ + * + * Returns 0 on success, negative error code otherwise + */ +int adis_enable_irq(struct adis *adis, bool enable) +{ + int ret = 0; + uint16_t msc; + + ret = adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc); + if (ret) + goto error_ret; + + msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH; + msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2; + if (enable) + msc |= ADIS_MSC_CTRL_DATA_RDY_EN; + else + msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN; + + ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc); + +error_ret: + return ret; +} +EXPORT_SYMBOL(adis_enable_irq); + +/** + * adis_check_status() - Check the device for error conditions + * @adis: The adis device + * + * Returns 0 on success, a negative error code otherwise + */ +int adis_check_status(struct adis *adis) +{ + uint16_t status; + int ret; + int i; + + ret = adis_read_reg_16(adis, adis->data->diag_stat_reg, &status); + if (ret < 0) + return ret; + + status &= adis->data->status_error_mask; + + if (status == 0) + return 0; + + for (i = 0; i < 16; ++i) { + if (status & BIT(i)) { + dev_err(&adis->spi->dev, "%s.\n", + adis->data->status_error_msgs[i]); + } + } + + return -EIO; +} +EXPORT_SYMBOL_GPL(adis_check_status); + +/** + * adis_reset() - Reset the device + * @adis: The adis device + * + * Returns 0 on success, a negative error code otherwise + */ +int adis_reset(struct adis *adis) +{ + int ret; + + ret = adis_write_reg_8(adis, adis->data->glob_cmd_reg, + ADIS_GLOB_CMD_SW_RESET); + if (ret) + dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret); + + return ret; +} +EXPORT_SYMBOL_GPL(adis_reset); + +static int adis_self_test(struct adis *adis) +{ + int ret; + + ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, + adis->data->self_test_mask); + if (ret) { + dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n", + ret); + return ret; + } + + msleep(adis->data->startup_delay); + + return adis_check_status(adis); +} + +/** + * adis_inital_startup() - Performs device self-test + * @adis: The adis device + * + * Returns 0 if the device is operational, a negative error code otherwise. + * + * This function should be called early on in the device initialization sequence + * to ensure that the device is in a sane and known state and that it is usable. + */ +int adis_initial_startup(struct adis *adis) +{ + int ret; + + ret = adis_self_test(adis); + if (ret) { + dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n"); + adis_reset(adis); + msleep(adis->data->startup_delay); + ret = adis_self_test(adis); + if (ret) { + dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n"); + return ret; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(adis_initial_startup); + +/** + * adis_single_conversion() - Performs a single sample conversion + * @indio_dev: The IIO device + * @chan: The IIO channel + * @error_mask: Mask for the error bit + * @val: Result of the conversion + * + * Returns IIO_VAL_INT on success, a negative error code otherwise. + * + * The function performs a single conversion on a given channel and post + * processes the value accordingly to the channel spec. If a error_mask is given + * the function will check if the mask is set in the returned raw value. If it + * is set the function will perform a self-check. If the device does not report + * a error bit in the channels raw value set error_mask to 0. + */ +int adis_single_conversion(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned int error_mask, int *val) +{ + struct adis *adis = iio_device_get_drvdata(indio_dev); + uint16_t val16; + int ret; + + mutex_lock(&indio_dev->mlock); + + ret = adis_read_reg_16(adis, chan->address, &val16); + if (ret) + goto err_unlock; + + if (val16 & error_mask) { + ret = adis_check_status(adis); + if (ret) + goto err_unlock; + } + + if (chan->scan_type.sign == 's') + *val = sign_extend32(val16, chan->scan_type.realbits - 1); + else + *val = val16 & ((1 << chan->scan_type.realbits) - 1); + + ret = IIO_VAL_INT; +err_unlock: + mutex_unlock(&indio_dev->mlock); + return ret; +} +EXPORT_SYMBOL_GPL(adis_single_conversion); + +/** + * adis_init() - Initialize adis device structure + * @adis: The adis device + * @indio_dev: The iio device + * @spi: The spi device + * @data: Chip specific data + * + * Returns 0 on success, a negative error code otherwise. + * + * This function must be called, before any other adis helper function may be + * called. + */ +int adis_init(struct adis *adis, struct iio_dev *indio_dev, + struct spi_device *spi, const struct adis_data *data) +{ + mutex_init(&adis->txrx_lock); + adis->spi = spi; + adis->data = data; + iio_device_set_drvdata(indio_dev, adis); + + return adis_enable_irq(adis, false); +} +EXPORT_SYMBOL_GPL(adis_init); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Common library code for ADIS16XXX devices"); diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c new file mode 100644 index 00000000000..a91b4cbdc73 --- /dev/null +++ b/drivers/iio/imu/adis_buffer.c @@ -0,0 +1,159 @@ +/* + * Common library for ADIS16XXX devices + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +int adis_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct adis *adis = iio_device_get_drvdata(indio_dev); + const struct iio_chan_spec *chan; + unsigned int scan_count; + unsigned int i, j; + __be16 *tx, *rx; + + kfree(adis->xfer); + kfree(adis->buffer); + + scan_count = indio_dev->scan_bytes / 2; + + adis->xfer = kcalloc(scan_count + 1, sizeof(*adis->xfer), GFP_KERNEL); + if (!adis->xfer) + return -ENOMEM; + + adis->buffer = kzalloc(indio_dev->scan_bytes * 2, GFP_KERNEL); + if (!adis->buffer) + return -ENOMEM; + + rx = adis->buffer; + tx = rx + indio_dev->scan_bytes; + + spi_message_init(&adis->msg); + + for (j = 0; j <= scan_count; j++) { + adis->xfer[j].bits_per_word = 8; + if (j != scan_count) + adis->xfer[j].cs_change = 1; + adis->xfer[j].len = 2; + adis->xfer[j].delay_usecs = adis->data->read_delay; + if (j < scan_count) + adis->xfer[j].tx_buf = &tx[j]; + if (j >= 1) + adis->xfer[j].rx_buf = &rx[j - 1]; + spi_message_add_tail(&adis->xfer[j], &adis->msg); + } + + chan = indio_dev->channels; + for (i = 0; i < indio_dev->num_channels; i++, chan++) { + if (!test_bit(chan->scan_index, scan_mask)) + continue; + *tx++ = cpu_to_be16(chan->address << 8); + } + + return 0; +} +EXPORT_SYMBOL_GPL(adis_update_scan_mode); + +static irqreturn_t adis_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct adis *adis = iio_device_get_drvdata(indio_dev); + int ret; + + if (!adis->buffer) + return -ENOMEM; + + ret = spi_sync(adis->spi, &adis->msg); + if (ret) + dev_err(&adis->spi->dev, "Failed to read data: %d", ret); + + /* Guaranteed to be aligned with 8 byte boundary */ + if (indio_dev->scan_timestamp) { + void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64); + *(s64 *)b = pf->timestamp; + } + + iio_push_to_buffers(indio_dev, adis->buffer); + + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +/** + * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device + * @adis: The adis device. + * @indio_dev: The IIO device. + * @trigger_handler: Optional trigger handler, may be NULL. + * + * Returns 0 on success, a negative error code otherwise. + * + * This function sets up the buffer and trigger for a adis devices. If + * 'trigger_handler' is NULL the default trigger handler will be used. The + * default trigger handler will simply read the registers assigned to the + * currently active channels. + * + * adis_cleanup_buffer_and_trigger() should be called to free the resources + * allocated by this function. + */ +int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, + irqreturn_t (*trigger_handler)(int, void *)) +{ + int ret; + + if (!trigger_handler) + trigger_handler = adis_trigger_handler; + + ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, + trigger_handler, NULL); + if (ret) + return ret; + + if (adis->spi->irq) { + ret = adis_probe_trigger(adis, indio_dev); + if (ret) + goto error_buffer_cleanup; + } + return 0; + +error_buffer_cleanup: + iio_triggered_buffer_cleanup(indio_dev); + return ret; +} +EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); + +/** + * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources + * @adis: The adis device. + * @indio_dev: The IIO device. + * + * Frees resources allocated by adis_setup_buffer_and_trigger() + */ +void adis_cleanup_buffer_and_trigger(struct adis *adis, + struct iio_dev *indio_dev) +{ + if (adis->spi->irq) + adis_remove_trigger(adis); + kfree(adis->buffer); + kfree(adis->xfer); + iio_triggered_buffer_cleanup(indio_dev); +} +EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger); diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c new file mode 100644 index 00000000000..5a24c9cac34 --- /dev/null +++ b/drivers/iio/imu/adis_trigger.c @@ -0,0 +1,89 @@ +/* + * Common library for ADIS16XXX devices + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include + +#include +#include +#include + +static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct adis *adis = trig->private_data; + + return adis_enable_irq(adis, state); +} + +static const struct iio_trigger_ops adis_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &adis_data_rdy_trigger_set_state, +}; + +/** + * adis_probe_trigger() - Sets up trigger for a adis device + * @adis: The adis device + * @indio_dev: The IIO device + * + * Returns 0 on success or a negative error code + * + * adis_remove_trigger() should be used to free the trigger. + */ +int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) +{ + int ret; + + adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, + indio_dev->id); + if (adis->trig == NULL) + return -ENOMEM; + + ret = request_irq(adis->spi->irq, + &iio_trigger_generic_data_rdy_poll, + IRQF_TRIGGER_RISING, + indio_dev->name, + adis->trig); + if (ret) + goto error_free_trig; + + adis->trig->dev.parent = &adis->spi->dev; + adis->trig->ops = &adis_trigger_ops; + adis->trig->private_data = adis; + ret = iio_trigger_register(adis->trig); + + indio_dev->trig = adis->trig; + if (ret) + goto error_free_irq; + + return 0; + +error_free_irq: + free_irq(adis->spi->irq, adis->trig); +error_free_trig: + iio_trigger_free(adis->trig); + return ret; +} +EXPORT_SYMBOL_GPL(adis_probe_trigger); + +/** + * adis_remove_trigger() - Remove trigger for a adis devices + * @adis: The adis device + * + * Removes the trigger previously registered with adis_probe_trigger(). + */ +void adis_remove_trigger(struct adis *adis) +{ + iio_trigger_unregister(adis->trig); + free_irq(adis->spi->irq, adis->trig); + iio_trigger_free(adis->trig); +} +EXPORT_SYMBOL_GPL(adis_remove_trigger); diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 833dd6b73bc..ccdc8d23f6a 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -18,9 +18,9 @@ #include #include #include +#include #include "adis16201.h" -#include "../imu/adis.h" static const u8 adis16201_addresses[] = { [ADIS16201_SCAN_ACC_X] = ADIS16201_XACCL_OFFS, diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index f631e578fbd..202985ea353 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -18,9 +18,9 @@ #include #include #include +#include #include "adis16203.h" -#include "../imu/adis.h" #define DRIVER_NAME "adis16203" diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index dbec841ce30..6dafad67cd2 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -21,9 +21,9 @@ #include #include #include +#include #include "adis16204.h" -#include "../imu/adis.h" /* Unique to this driver currently */ diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index f9f9d582b32..d2921c30a8b 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -19,9 +19,9 @@ #include #include #include +#include #include "adis16209.h" -#include "../imu/adis.h" static const u8 adis16209_addresses[8][1] = { [ADIS16209_SCAN_SUPPLY] = { }, diff --git a/drivers/staging/iio/accel/adis16220.h b/drivers/staging/iio/accel/adis16220.h index 7cc4d2f3ec2..a894ad7fb26 100644 --- a/drivers/staging/iio/accel/adis16220.h +++ b/drivers/staging/iio/accel/adis16220.h @@ -1,7 +1,7 @@ #ifndef SPI_ADIS16220_H_ #define SPI_ADIS16220_H_ -#include "../imu/adis.h" +#include #define ADIS16220_STARTUP_DELAY 220 /* ms */ diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 3d1a8a9921a..d098b49cc18 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -22,9 +22,9 @@ #include #include #include +#include #include "adis16240.h" -#include "../imu/adis.h" static ssize_t adis16240_spi_read_signed(struct device *dev, struct device_attribute *attr, diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h index ea5eba205bb..df3c0b7e954 100644 --- a/drivers/staging/iio/gyro/adis16260.h +++ b/drivers/staging/iio/gyro/adis16260.h @@ -2,7 +2,7 @@ #define SPI_ADIS16260_H_ #include "adis16260_platform_data.h" -#include "../imu/adis.h" +#include #define ADIS16260_STARTUP_DELAY 220 /* ms */ diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig index 2c564edeb17..2c2f47de263 100644 --- a/drivers/staging/iio/imu/Kconfig +++ b/drivers/staging/iio/imu/Kconfig @@ -15,15 +15,3 @@ config ADIS16400 (adis16400 series also have magnetometers). endmenu - -config IIO_ADIS_LIB - tristate - help - A set of IO helper functions for the Analog Devices ADIS* device family. - -config IIO_ADIS_LIB_BUFFER - bool - select IIO_TRIGGERED_BUFFER - help - A set of buffer helper functions for the Analog Devices ADIS* device - family. diff --git a/drivers/staging/iio/imu/Makefile b/drivers/staging/iio/imu/Makefile index 65dafba1e5d..3400a13d152 100644 --- a/drivers/staging/iio/imu/Makefile +++ b/drivers/staging/iio/imu/Makefile @@ -5,8 +5,3 @@ adis16400-y := adis16400_core.o adis16400-$(CONFIG_IIO_BUFFER) += adis16400_ring.o adis16400_trigger.o obj-$(CONFIG_ADIS16400) += adis16400.o - -adis_lib-y += adis.o -adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_trigger.o -adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o -obj-$(CONFIG_IIO_ADIS_LIB) += adis_lib.o diff --git a/drivers/staging/iio/imu/adis.c b/drivers/staging/iio/imu/adis.c deleted file mode 100644 index 0bd21022e4c..00000000000 --- a/drivers/staging/iio/imu/adis.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Common library for ADIS16XXX devices - * - * Copyright 2012 Analog Devices Inc. - * Author: Lars-Peter Clausen - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "adis.h" - -#define ADIS_MSC_CTRL_DATA_RDY_EN BIT(2) -#define ADIS_MSC_CTRL_DATA_RDY_POL_HIGH BIT(1) -#define ADIS_MSC_CTRL_DATA_RDY_DIO2 BIT(0) -#define ADIS_GLOB_CMD_SW_RESET BIT(7) - -/** - * adis_write_reg_8() - Write single byte to a register - * @adis: The adis device - * @reg: The address of the register to be written - * @val: The value to write - */ -int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val) -{ - int ret; - - mutex_lock(&adis->txrx_lock); - adis->tx[0] = ADIS_WRITE_REG(reg); - adis->tx[1] = val; - - ret = spi_write(adis->spi, adis->tx, 2); - mutex_unlock(&adis->txrx_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(adis_write_reg_8); - -/** - * adis_write_reg_16() - Write 2 bytes to a pair of registers - * @adis: The adis device - * @reg: The address of the lower of the two registers - * @val: Value to be written - */ -int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t value) -{ - int ret; - struct spi_message msg; - struct spi_transfer xfers[] = { - { - .tx_buf = adis->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = adis->data->write_delay, - }, { - .tx_buf = adis->tx + 2, - .bits_per_word = 8, - .len = 2, - .delay_usecs = adis->data->write_delay, - }, - }; - - mutex_lock(&adis->txrx_lock); - adis->tx[0] = ADIS_WRITE_REG(reg); - adis->tx[1] = value & 0xff; - adis->tx[2] = ADIS_WRITE_REG(reg + 1); - adis->tx[3] = (value >> 8) & 0xff; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(adis->spi, &msg); - mutex_unlock(&adis->txrx_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(adis_write_reg_16); - -/** - * adis_read_reg_16() - read 2 bytes from a 16-bit register - * @adis: The adis device - * @reg: The address of the lower of the two registers - * @val: The value read back from the device - */ -int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val) -{ - struct spi_message msg; - int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = adis->tx, - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .delay_usecs = adis->data->read_delay, - }, { - .rx_buf = adis->rx, - .bits_per_word = 8, - .len = 2, - .delay_usecs = adis->data->read_delay, - }, - }; - - mutex_lock(&adis->txrx_lock); - adis->tx[0] = ADIS_READ_REG(reg); - adis->tx[1] = 0; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(adis->spi, &msg); - if (ret) { - dev_err(&adis->spi->dev, "Failed to read 16 bit register 0x%02X: %d\n", - reg, ret); - goto error_ret; - } - *val = get_unaligned_be16(adis->rx); - -error_ret: - mutex_unlock(&adis->txrx_lock); - return ret; -} -EXPORT_SYMBOL_GPL(adis_read_reg_16); - -/** - * adis_enable_irq() - Enable or disable data ready IRQ - * @adis: The adis device - * @enable: Whether to enable the IRQ - * - * Returns 0 on success, negative error code otherwise - */ -int adis_enable_irq(struct adis *adis, bool enable) -{ - int ret = 0; - uint16_t msc; - - ret = adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc); - if (ret) - goto error_ret; - - msc |= ADIS_MSC_CTRL_DATA_RDY_POL_HIGH; - msc &= ~ADIS_MSC_CTRL_DATA_RDY_DIO2; - if (enable) - msc |= ADIS_MSC_CTRL_DATA_RDY_EN; - else - msc &= ~ADIS_MSC_CTRL_DATA_RDY_EN; - - ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, msc); - -error_ret: - return ret; -} -EXPORT_SYMBOL(adis_enable_irq); - -/** - * adis_check_status() - Check the device for error conditions - * @adis: The adis device - * - * Returns 0 on success, a negative error code otherwise - */ -int adis_check_status(struct adis *adis) -{ - uint16_t status; - int ret; - int i; - - ret = adis_read_reg_16(adis, adis->data->diag_stat_reg, &status); - if (ret < 0) - return ret; - - status &= adis->data->status_error_mask; - - if (status == 0) - return 0; - - for (i = 0; i < 16; ++i) { - if (status & BIT(i)) { - dev_err(&adis->spi->dev, "%s.\n", - adis->data->status_error_msgs[i]); - } - } - - return -EIO; -} -EXPORT_SYMBOL_GPL(adis_check_status); - -/** - * adis_reset() - Reset the device - * @adis: The adis device - * - * Returns 0 on success, a negative error code otherwise - */ -int adis_reset(struct adis *adis) -{ - int ret; - - ret = adis_write_reg_8(adis, adis->data->glob_cmd_reg, - ADIS_GLOB_CMD_SW_RESET); - if (ret) - dev_err(&adis->spi->dev, "Failed to reset device: %d\n", ret); - - return ret; -} -EXPORT_SYMBOL_GPL(adis_reset); - -static int adis_self_test(struct adis *adis) -{ - int ret; - - ret = adis_write_reg_16(adis, adis->data->msc_ctrl_reg, - adis->data->self_test_mask); - if (ret) { - dev_err(&adis->spi->dev, "Failed to initiate self test: %d\n", - ret); - return ret; - } - - msleep(adis->data->startup_delay); - - return adis_check_status(adis); -} - -/** - * adis_inital_startup() - Performs device self-test - * @adis: The adis device - * - * Returns 0 if the device is operational, a negative error code otherwise. - * - * This function should be called early on in the device initialization sequence - * to ensure that the device is in a sane and known state and that it is usable. - */ -int adis_initial_startup(struct adis *adis) -{ - int ret; - - ret = adis_self_test(adis); - if (ret) { - dev_err(&adis->spi->dev, "Self-test failed, trying reset.\n"); - adis_reset(adis); - msleep(adis->data->startup_delay); - ret = adis_self_test(adis); - if (ret) { - dev_err(&adis->spi->dev, "Second self-test failed, giving up.\n"); - return ret; - } - } - - return 0; -} -EXPORT_SYMBOL_GPL(adis_initial_startup); - -/** - * adis_single_conversion() - Performs a single sample conversion - * @indio_dev: The IIO device - * @chan: The IIO channel - * @error_mask: Mask for the error bit - * @val: Result of the conversion - * - * Returns IIO_VAL_INT on success, a negative error code otherwise. - * - * The function performs a single conversion on a given channel and post - * processes the value accordingly to the channel spec. If a error_mask is given - * the function will check if the mask is set in the returned raw value. If it - * is set the function will perform a self-check. If the device does not report - * a error bit in the channels raw value set error_mask to 0. - */ -int adis_single_conversion(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, unsigned int error_mask, int *val) -{ - struct adis *adis = iio_device_get_drvdata(indio_dev); - uint16_t val16; - int ret; - - mutex_lock(&indio_dev->mlock); - - ret = adis_read_reg_16(adis, chan->address, &val16); - if (ret) - goto err_unlock; - - if (val16 & error_mask) { - ret = adis_check_status(adis); - if (ret) - goto err_unlock; - } - - if (chan->scan_type.sign == 's') - *val = sign_extend32(val16, chan->scan_type.realbits - 1); - else - *val = val16 & ((1 << chan->scan_type.realbits) - 1); - - ret = IIO_VAL_INT; -err_unlock: - mutex_unlock(&indio_dev->mlock); - return ret; -} -EXPORT_SYMBOL_GPL(adis_single_conversion); - -/** - * adis_init() - Initialize adis device structure - * @adis: The adis device - * @indio_dev: The iio device - * @spi: The spi device - * @data: Chip specific data - * - * Returns 0 on success, a negative error code otherwise. - * - * This function must be called, before any other adis helper function may be - * called. - */ -int adis_init(struct adis *adis, struct iio_dev *indio_dev, - struct spi_device *spi, const struct adis_data *data) -{ - mutex_init(&adis->txrx_lock); - adis->spi = spi; - adis->data = data; - iio_device_set_drvdata(indio_dev, adis); - - return adis_enable_irq(adis, false); -} -EXPORT_SYMBOL_GPL(adis_init); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Lars-Peter Clausen "); -MODULE_DESCRIPTION("Common library code for ADIS16XXX devices"); diff --git a/drivers/staging/iio/imu/adis.h b/drivers/staging/iio/imu/adis.h deleted file mode 100644 index 8c3304d44b9..00000000000 --- a/drivers/staging/iio/imu/adis.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Common library for ADIS16XXX devices - * - * Copyright 2012 Analog Devices Inc. - * Author: Lars-Peter Clausen - * - * Licensed under the GPL-2 or later. - */ - -#ifndef __IIO_ADIS_H__ -#define __IIO_ADIS_H__ - -#include -#include -#include - -#define ADIS_WRITE_REG(reg) (0x80 | (reg)) -#define ADIS_READ_REG(reg) (reg) - -/** - * struct adis_data - ADIS chip variant specific data - * @read_delay: SPI delay for read operations in us - * @write_delay: SPI delay for write operations in us - * @glob_cmd_reg: Register address of the GLOB_CMD register - * @msc_ctrl_reg: Register address of the MSC_CTRL register - * @diag_stat_reg: Register address of the DIAG_STAT register - * @status_error_msgs: Array of error messgaes - * @status_error_mask: - */ -struct adis_data { - unsigned int read_delay; - unsigned int write_delay; - - unsigned int glob_cmd_reg; - unsigned int msc_ctrl_reg; - unsigned int diag_stat_reg; - - unsigned int self_test_mask; - unsigned int startup_delay; - - const char * const *status_error_msgs; - unsigned int status_error_mask; -}; - -struct adis { - struct spi_device *spi; - struct iio_trigger *trig; - - const struct adis_data *data; - - struct mutex txrx_lock; - struct spi_message msg; - struct spi_transfer *xfer; - void *buffer; - - uint8_t tx[8] ____cacheline_aligned; - uint8_t rx[4]; -}; - -int adis_init(struct adis *adis, struct iio_dev *indio_dev, - struct spi_device *spi, const struct adis_data *data); -int adis_reset(struct adis *adis); - -int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val); -int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t val); -int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val); - -int adis_enable_irq(struct adis *adis, bool enable); -int adis_check_status(struct adis *adis); - -int adis_initial_startup(struct adis *adis); - -int adis_single_conversion(struct iio_dev *indio_dev, - const struct iio_chan_spec *chan, unsigned int error_mask, - int *val); - -#define ADIS_VOLTAGE_CHAN(addr, si, chan, name, bits) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = (chan), \ - .extend_name = name, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - .address = (addr), \ - .scan_index = (si), \ - .scan_type = { \ - .sign = 'u', \ - .realbits = (bits), \ - .storagebits = 16, \ - .endianness = IIO_BE, \ - }, \ -} - -#define ADIS_SUPPLY_CHAN(addr, si, bits) \ - ADIS_VOLTAGE_CHAN(addr, si, 0, "supply", bits) - -#define ADIS_AUX_ADC_CHAN(addr, si, bits) \ - ADIS_VOLTAGE_CHAN(addr, si, 1, NULL, bits) - -#define ADIS_TEMP_CHAN(addr, si, bits) { \ - .type = IIO_TEMP, \ - .indexed = 1, \ - .channel = 0, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \ - .address = (addr), \ - .scan_index = (si), \ - .scan_type = { \ - .sign = 'u', \ - .realbits = (bits), \ - .storagebits = 16, \ - .endianness = IIO_BE, \ - }, \ -} - -#define ADIS_MOD_CHAN(_type, mod, addr, si, info, bits) { \ - .type = (_type), \ - .modified = 1, \ - .channel2 = IIO_MOD_ ## mod, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ - info, \ - .address = (addr), \ - .scan_index = (si), \ - .scan_type = { \ - .sign = 's', \ - .realbits = (bits), \ - .storagebits = 16, \ - .endianness = IIO_BE, \ - }, \ -} - -#define ADIS_ACCEL_CHAN(mod, addr, si, info, bits) \ - ADIS_MOD_CHAN(IIO_ACCEL, mod, addr, si, info, bits) - -#define ADIS_GYRO_CHAN(mod, addr, si, info, bits) \ - ADIS_MOD_CHAN(IIO_ANGL_VEL, mod, addr, si, info, bits) - -#define ADIS_INCLI_CHAN(mod, addr, si, info, bits) \ - ADIS_MOD_CHAN(IIO_INCLI, mod, addr, si, info, bits) - -#define ADIS_ROT_CHAN(mod, addr, si, info, bits) \ - ADIS_MOD_CHAN(IIO_ROT, mod, addr, si, info, bits) - -#ifdef CONFIG_IIO_ADIS_LIB_BUFFER - -int adis_setup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)); -void adis_cleanup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev); - -int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); -void adis_remove_trigger(struct adis *adis); - -int adis_update_scan_mode(struct iio_dev *indio_dev, - const unsigned long *scan_mask); - -#else /* CONFIG_IIO_BUFFER */ - -static inline int adis_setup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)) -{ - return 0; -} - -static inline void adis_cleanup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev) -{ -} - -static inline int adis_probe_trigger(struct adis *adis, - struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void adis_remove_trigger(struct adis *adis) -{ -} - -#define adis_update_scan_mode NULL - -#endif /* CONFIG_IIO_BUFFER */ - -#endif diff --git a/drivers/staging/iio/imu/adis_buffer.c b/drivers/staging/iio/imu/adis_buffer.c deleted file mode 100644 index 342758c14d2..00000000000 --- a/drivers/staging/iio/imu/adis_buffer.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Common library for ADIS16XXX devices - * - * Copyright 2012 Analog Devices Inc. - * Author: Lars-Peter Clausen - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "adis.h" - -int adis_update_scan_mode(struct iio_dev *indio_dev, - const unsigned long *scan_mask) -{ - struct adis *adis = iio_device_get_drvdata(indio_dev); - const struct iio_chan_spec *chan; - unsigned int scan_count; - unsigned int i, j; - __be16 *tx, *rx; - - kfree(adis->xfer); - kfree(adis->buffer); - - scan_count = indio_dev->scan_bytes / 2; - - adis->xfer = kcalloc(scan_count + 1, sizeof(*adis->xfer), GFP_KERNEL); - if (!adis->xfer) - return -ENOMEM; - - adis->buffer = kzalloc(indio_dev->scan_bytes * 2, GFP_KERNEL); - if (!adis->buffer) - return -ENOMEM; - - rx = adis->buffer; - tx = rx + indio_dev->scan_bytes; - - spi_message_init(&adis->msg); - - for (j = 0; j <= scan_count; j++) { - adis->xfer[j].bits_per_word = 8; - if (j != scan_count) - adis->xfer[j].cs_change = 1; - adis->xfer[j].len = 2; - adis->xfer[j].delay_usecs = adis->data->read_delay; - if (j < scan_count) - adis->xfer[j].tx_buf = &tx[j]; - if (j >= 1) - adis->xfer[j].rx_buf = &rx[j - 1]; - spi_message_add_tail(&adis->xfer[j], &adis->msg); - } - - chan = indio_dev->channels; - for (i = 0; i < indio_dev->num_channels; i++, chan++) { - if (!test_bit(chan->scan_index, scan_mask)) - continue; - *tx++ = cpu_to_be16(chan->address << 8); - } - - return 0; -} -EXPORT_SYMBOL_GPL(adis_update_scan_mode); - -static irqreturn_t adis_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct adis *adis = iio_device_get_drvdata(indio_dev); - int ret; - - if (!adis->buffer) - return -ENOMEM; - - ret = spi_sync(adis->spi, &adis->msg); - if (ret) - dev_err(&adis->spi->dev, "Failed to read data: %d", ret); - - /* Guaranteed to be aligned with 8 byte boundary */ - if (indio_dev->scan_timestamp) { - void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64); - *(s64 *)b = pf->timestamp; - } - - iio_push_to_buffers(indio_dev, adis->buffer); - - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -/** - * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device - * @adis: The adis device. - * @indio_dev: The IIO device. - * @trigger_handler: Optional trigger handler, may be NULL. - * - * Returns 0 on success, a negative error code otherwise. - * - * This function sets up the buffer and trigger for a adis devices. If - * 'trigger_handler' is NULL the default trigger handler will be used. The - * default trigger handler will simply read the registers assigned to the - * currently active channels. - * - * adis_cleanup_buffer_and_trigger() should be called to free the resources - * allocated by this function. - */ -int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, - irqreturn_t (*trigger_handler)(int, void *)) -{ - int ret; - - if (!trigger_handler) - trigger_handler = adis_trigger_handler; - - ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - trigger_handler, NULL); - if (ret) - return ret; - - if (adis->spi->irq) { - ret = adis_probe_trigger(adis, indio_dev); - if (ret) - goto error_buffer_cleanup; - } - return 0; - -error_buffer_cleanup: - iio_triggered_buffer_cleanup(indio_dev); - return ret; -} -EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); - -/** - * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources - * @adis: The adis device. - * @indio_dev: The IIO device. - * - * Frees resources allocated by adis_setup_buffer_and_trigger() - */ -void adis_cleanup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev) -{ - if (adis->spi->irq) - adis_remove_trigger(adis); - kfree(adis->buffer); - kfree(adis->xfer); - iio_triggered_buffer_cleanup(indio_dev); -} -EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger); diff --git a/drivers/staging/iio/imu/adis_trigger.c b/drivers/staging/iio/imu/adis_trigger.c deleted file mode 100644 index 3e89b2e8370..00000000000 --- a/drivers/staging/iio/imu/adis_trigger.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Common library for ADIS16XXX devices - * - * Copyright 2012 Analog Devices Inc. - * Author: Lars-Peter Clausen - * - * Licensed under the GPL-2 or later. - */ - -#include -#include -#include -#include - -#include -#include - -#include "adis.h" - -static int adis_data_rdy_trigger_set_state(struct iio_trigger *trig, - bool state) -{ - struct adis *adis = trig->private_data; - - return adis_enable_irq(adis, state); -} - -static const struct iio_trigger_ops adis_trigger_ops = { - .owner = THIS_MODULE, - .set_trigger_state = &adis_data_rdy_trigger_set_state, -}; - -/** - * adis_probe_trigger() - Sets up trigger for a adis device - * @adis: The adis device - * @indio_dev: The IIO device - * - * Returns 0 on success or a negative error code - * - * adis_remove_trigger() should be used to free the trigger. - */ -int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) -{ - int ret; - - adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, - indio_dev->id); - if (adis->trig == NULL) - return -ENOMEM; - - ret = request_irq(adis->spi->irq, - &iio_trigger_generic_data_rdy_poll, - IRQF_TRIGGER_RISING, - indio_dev->name, - adis->trig); - if (ret) - goto error_free_trig; - - adis->trig->dev.parent = &adis->spi->dev; - adis->trig->ops = &adis_trigger_ops; - adis->trig->private_data = adis; - ret = iio_trigger_register(adis->trig); - - indio_dev->trig = adis->trig; - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(adis->spi->irq, adis->trig); -error_free_trig: - iio_trigger_free(adis->trig); - return ret; -} -EXPORT_SYMBOL_GPL(adis_probe_trigger); - -/** - * adis_remove_trigger() - Remove trigger for a adis devices - * @adis: The adis device - * - * Removes the trigger previously registered with adis_probe_trigger(). - */ -void adis_remove_trigger(struct adis *adis) -{ - iio_trigger_unregister(adis->trig); - free_irq(adis->spi->irq, adis->trig); - iio_trigger_free(adis->trig); -} -EXPORT_SYMBOL_GPL(adis_remove_trigger); diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h new file mode 100644 index 00000000000..8c3304d44b9 --- /dev/null +++ b/include/linux/iio/imu/adis.h @@ -0,0 +1,186 @@ +/* + * Common library for ADIS16XXX devices + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __IIO_ADIS_H__ +#define __IIO_ADIS_H__ + +#include +#include +#include + +#define ADIS_WRITE_REG(reg) (0x80 | (reg)) +#define ADIS_READ_REG(reg) (reg) + +/** + * struct adis_data - ADIS chip variant specific data + * @read_delay: SPI delay for read operations in us + * @write_delay: SPI delay for write operations in us + * @glob_cmd_reg: Register address of the GLOB_CMD register + * @msc_ctrl_reg: Register address of the MSC_CTRL register + * @diag_stat_reg: Register address of the DIAG_STAT register + * @status_error_msgs: Array of error messgaes + * @status_error_mask: + */ +struct adis_data { + unsigned int read_delay; + unsigned int write_delay; + + unsigned int glob_cmd_reg; + unsigned int msc_ctrl_reg; + unsigned int diag_stat_reg; + + unsigned int self_test_mask; + unsigned int startup_delay; + + const char * const *status_error_msgs; + unsigned int status_error_mask; +}; + +struct adis { + struct spi_device *spi; + struct iio_trigger *trig; + + const struct adis_data *data; + + struct mutex txrx_lock; + struct spi_message msg; + struct spi_transfer *xfer; + void *buffer; + + uint8_t tx[8] ____cacheline_aligned; + uint8_t rx[4]; +}; + +int adis_init(struct adis *adis, struct iio_dev *indio_dev, + struct spi_device *spi, const struct adis_data *data); +int adis_reset(struct adis *adis); + +int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val); +int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t val); +int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val); + +int adis_enable_irq(struct adis *adis, bool enable); +int adis_check_status(struct adis *adis); + +int adis_initial_startup(struct adis *adis); + +int adis_single_conversion(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned int error_mask, + int *val); + +#define ADIS_VOLTAGE_CHAN(addr, si, chan, name, bits) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (chan), \ + .extend_name = name, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .address = (addr), \ + .scan_index = (si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 16, \ + .endianness = IIO_BE, \ + }, \ +} + +#define ADIS_SUPPLY_CHAN(addr, si, bits) \ + ADIS_VOLTAGE_CHAN(addr, si, 0, "supply", bits) + +#define ADIS_AUX_ADC_CHAN(addr, si, bits) \ + ADIS_VOLTAGE_CHAN(addr, si, 1, NULL, bits) + +#define ADIS_TEMP_CHAN(addr, si, bits) { \ + .type = IIO_TEMP, \ + .indexed = 1, \ + .channel = 0, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \ + .address = (addr), \ + .scan_index = (si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (bits), \ + .storagebits = 16, \ + .endianness = IIO_BE, \ + }, \ +} + +#define ADIS_MOD_CHAN(_type, mod, addr, si, info, bits) { \ + .type = (_type), \ + .modified = 1, \ + .channel2 = IIO_MOD_ ## mod, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + info, \ + .address = (addr), \ + .scan_index = (si), \ + .scan_type = { \ + .sign = 's', \ + .realbits = (bits), \ + .storagebits = 16, \ + .endianness = IIO_BE, \ + }, \ +} + +#define ADIS_ACCEL_CHAN(mod, addr, si, info, bits) \ + ADIS_MOD_CHAN(IIO_ACCEL, mod, addr, si, info, bits) + +#define ADIS_GYRO_CHAN(mod, addr, si, info, bits) \ + ADIS_MOD_CHAN(IIO_ANGL_VEL, mod, addr, si, info, bits) + +#define ADIS_INCLI_CHAN(mod, addr, si, info, bits) \ + ADIS_MOD_CHAN(IIO_INCLI, mod, addr, si, info, bits) + +#define ADIS_ROT_CHAN(mod, addr, si, info, bits) \ + ADIS_MOD_CHAN(IIO_ROT, mod, addr, si, info, bits) + +#ifdef CONFIG_IIO_ADIS_LIB_BUFFER + +int adis_setup_buffer_and_trigger(struct adis *adis, + struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)); +void adis_cleanup_buffer_and_trigger(struct adis *adis, + struct iio_dev *indio_dev); + +int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); +void adis_remove_trigger(struct adis *adis); + +int adis_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask); + +#else /* CONFIG_IIO_BUFFER */ + +static inline int adis_setup_buffer_and_trigger(struct adis *adis, + struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)) +{ + return 0; +} + +static inline void adis_cleanup_buffer_and_trigger(struct adis *adis, + struct iio_dev *indio_dev) +{ +} + +static inline int adis_probe_trigger(struct adis *adis, + struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis_remove_trigger(struct adis *adis) +{ +} + +#define adis_update_scan_mode NULL + +#endif /* CONFIG_IIO_BUFFER */ + +#endif -- cgit v1.2.3 From ca654638f2b4b00f948d2126dd544d2e35d2b880 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 15 Nov 2012 13:15:00 +0000 Subject: staging:iio:ad7298: Do not perform endianness conversion in buffered mode For buffered mode we do not want to perform endianness conversion in the kernel, but rather offload it to user space, since it is not always required to do a conversion at all. It also greatly simplifies the kernel code since no post-processing has to be done and may allow future optimizations like streaming data directly to a storage device or over the network via DMA. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7298.h | 2 +- drivers/staging/iio/adc/ad7298_core.c | 1 + drivers/staging/iio/adc/ad7298_ring.c | 11 +++-------- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h index 18f27872300..0ce9031bec9 100644 --- a/drivers/staging/iio/adc/ad7298.h +++ b/drivers/staging/iio/adc/ad7298.h @@ -48,7 +48,7 @@ struct ad7298_state { * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. */ - unsigned short rx_buf[8] ____cacheline_aligned; + unsigned short rx_buf[12] ____cacheline_aligned; unsigned short tx_buf[2]; }; diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c index 4c75114e7d7..67082ade185 100644 --- a/drivers/staging/iio/adc/ad7298_core.c +++ b/drivers/staging/iio/adc/ad7298_core.c @@ -35,6 +35,7 @@ .sign = 'u', \ .realbits = 12, \ .storagebits = 16, \ + .endianness = IIO_BE, \ }, \ } diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index b3dd514b962..e3877129222 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -76,8 +76,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct ad7298_state *st = iio_priv(indio_dev); s64 time_ns = 0; - __u16 buf[16]; - int b_sent, i; + int b_sent; b_sent = spi_sync(st->spi, &st->ring_msg); if (b_sent) @@ -85,15 +84,11 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) if (indio_dev->scan_timestamp) { time_ns = iio_get_time_ns(); - memcpy((u8 *)buf + indio_dev->scan_bytes - sizeof(s64), + memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64), &time_ns, sizeof(time_ns)); } - for (i = 0; i < bitmap_weight(indio_dev->active_scan_mask, - indio_dev->masklength); i++) - buf[i] = be16_to_cpu(st->rx_buf[i]); - - iio_push_to_buffers(indio_dev, (u8 *)buf); + iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf); done: iio_trigger_notify_done(indio_dev->trig); -- cgit v1.2.3 From 2e334600989384a11ed7ae0dc0e0ca0486ebfaaa Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 15 Nov 2012 13:15:00 +0000 Subject: staging:iio:ad7298: Rework regulator handling Rework the regulator handling of the driver to match more closely what we do in other drivers. Make the regulator non-optional if a external reference is used. Also dispose the option of specifying the reference voltage via platform data. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7298.h | 12 ++++------ drivers/staging/iio/adc/ad7298_core.c | 44 +++++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h index 0ce9031bec9..6523e011361 100644 --- a/drivers/staging/iio/adc/ad7298.h +++ b/drivers/staging/iio/adc/ad7298.h @@ -26,19 +26,17 @@ #define RES_MASK(bits) ((1 << (bits)) - 1) -/* - * TODO: struct ad7298_platform_data needs to go into include/linux/iio - */ - +/** + * struct ad7298_platform_data - Platform data for the ad7298 ADC driver + * @ext_ref: Whether to use an external reference voltage. + **/ struct ad7298_platform_data { - /* External Vref voltage applied */ - u16 vref_mv; + bool ext_ref; }; struct ad7298_state { struct spi_device *spi; struct regulator *reg; - u16 int_vref_mv; unsigned ext_ref; struct spi_transfer ring_xfer[10]; struct spi_transfer scan_single_xfer[3]; diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c index 67082ade185..6dd696f7426 100644 --- a/drivers/staging/iio/adc/ad7298_core.c +++ b/drivers/staging/iio/adc/ad7298_core.c @@ -130,7 +130,7 @@ static int ad7298_read_raw(struct iio_dev *indio_dev, { int ret; struct ad7298_state *st = iio_priv(indio_dev); - unsigned int scale_uv; + int scale_mv; switch (m) { case IIO_CHAN_INFO_RAW: @@ -155,10 +155,17 @@ static int ad7298_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: - scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS; - *val = scale_uv / 1000; - *val2 = (scale_uv % 1000) * 1000; - return IIO_VAL_INT_PLUS_MICRO; + if (st->ext_ref) { + scale_mv = regulator_get_voltage(st->reg); + if (scale_mv < 0) + return scale_mv; + scale_mv /= 1000; + } else { + scale_mv = AD7298_INTREF_mV; + } + *val = scale_mv; + *val2 = chan->scan_type.realbits; + return IIO_VAL_FRACTIONAL_LOG2; case IIO_TEMP: *val = 1; *val2 = 0; @@ -180,16 +187,23 @@ static int __devinit ad7298_probe(struct spi_device *spi) { struct ad7298_platform_data *pdata = spi->dev.platform_data; struct ad7298_state *st; - int ret; struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); + int ret; if (indio_dev == NULL) return -ENOMEM; st = iio_priv(indio_dev); - st->reg = regulator_get(&spi->dev, "vcc"); - if (!IS_ERR(st->reg)) { + if (pdata && pdata->ext_ref) + st->ext_ref = AD7298_EXTREF; + + if (st->ext_ref) { + st->reg = regulator_get(&spi->dev, "vref"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto error_free; + } ret = regulator_enable(st->reg); if (ret) goto error_put_reg; @@ -222,13 +236,6 @@ static int __devinit ad7298_probe(struct spi_device *spi) spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg); spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg); - if (pdata && pdata->vref_mv) { - st->int_vref_mv = pdata->vref_mv; - st->ext_ref = AD7298_EXTREF; - } else { - st->int_vref_mv = AD7298_INTREF_mV; - } - ret = ad7298_register_ring_funcs_and_init(indio_dev); if (ret) goto error_disable_reg; @@ -242,11 +249,12 @@ static int __devinit ad7298_probe(struct spi_device *spi) error_cleanup_ring: ad7298_ring_cleanup(indio_dev); error_disable_reg: - if (!IS_ERR(st->reg)) + if (st->ext_ref) regulator_disable(st->reg); error_put_reg: - if (!IS_ERR(st->reg)) + if (st->ext_ref) regulator_put(st->reg); +error_free: iio_device_free(indio_dev); return ret; @@ -259,7 +267,7 @@ static int __devexit ad7298_remove(struct spi_device *spi) iio_device_unregister(indio_dev); ad7298_ring_cleanup(indio_dev); - if (!IS_ERR(st->reg)) { + if (st->ext_ref) { regulator_disable(st->reg); regulator_put(st->reg); } -- cgit v1.2.3 From 01a10e04f8e099fea3212a70df0b25a8ffd9275f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 15 Nov 2012 13:15:00 +0000 Subject: staging:iio:ad7298: Fix temperature scale and offset The temperature scale and offset depend on the reference voltage, the current formula used in the driver assumes a 2.5V reference. This patch modifies the code to report the unprocessed value for the temperature channel "raw" property and to provide proper "scale" and "offset" properties which depend on the selected reference voltage. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/ad7298_core.c | 51 ++++++++++++++++------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c index 6dd696f7426..b74b76ffcac 100644 --- a/drivers/staging/iio/adc/ad7298_core.c +++ b/drivers/staging/iio/adc/ad7298_core.c @@ -45,7 +45,8 @@ static const struct iio_chan_spec ad7298_channels[] = { .indexed = 1, .channel = 0, .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, .address = AD7298_CH_TEMP, .scan_index = -1, .scan_type = { @@ -80,7 +81,7 @@ static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch) static int ad7298_scan_temp(struct ad7298_state *st, int *val) { - int tmp, ret; + int ret; __be16 buf; buf = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE | @@ -102,24 +103,24 @@ static int ad7298_scan_temp(struct ad7298_state *st, int *val) if (ret) return ret; - tmp = be16_to_cpu(buf) & RES_MASK(AD7298_BITS); + *val = sign_extend32(be16_to_cpu(buf), 11); - /* - * One LSB of the ADC corresponds to 0.25 deg C. - * The temperature reading is in 12-bit twos complement format - */ + return 0; +} + +static int ad7298_get_ref_voltage(struct ad7298_state *st) +{ + int vref; - if (tmp & (1 << (AD7298_BITS - 1))) { - tmp = (4096 - tmp) * 250; - tmp -= (2 * tmp); + if (st->ext_ref) { + vref = regulator_get_voltage(st->reg); + if (vref < 0) + return vref; + return vref / 1000; } else { - tmp *= 250; /* temperature in milli degrees Celsius */ + return AD7298_INTREF_mV; } - - *val = tmp; - - return 0; } static int ad7298_read_raw(struct iio_dev *indio_dev, @@ -130,7 +131,6 @@ static int ad7298_read_raw(struct iio_dev *indio_dev, { int ret; struct ad7298_state *st = iio_priv(indio_dev); - int scale_mv; switch (m) { case IIO_CHAN_INFO_RAW: @@ -155,24 +155,19 @@ static int ad7298_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: switch (chan->type) { case IIO_VOLTAGE: - if (st->ext_ref) { - scale_mv = regulator_get_voltage(st->reg); - if (scale_mv < 0) - return scale_mv; - scale_mv /= 1000; - } else { - scale_mv = AD7298_INTREF_mV; - } - *val = scale_mv; + *val = ad7298_get_ref_voltage(st); *val2 = chan->scan_type.realbits; return IIO_VAL_FRACTIONAL_LOG2; case IIO_TEMP: - *val = 1; - *val2 = 0; - return IIO_VAL_INT_PLUS_MICRO; + *val = ad7298_get_ref_voltage(st); + *val2 = 10; + return IIO_VAL_FRACTIONAL; default: return -EINVAL; } + case IIO_CHAN_INFO_OFFSET: + *val = 1093 - 2732500 / ad7298_get_ref_voltage(st); + return IIO_VAL_INT; } return -EINVAL; } -- cgit v1.2.3 From dc4871adf96573f3ea1672fceb844301dc071a2b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 15 Nov 2012 13:15:00 +0000 Subject: staging:iio:ad7298: Squash everything into one file The recent cleanups have decimated the drivers code size by quite a bit. It is only a few hundred lines in total now. Putting everything into one file also allows to reduce the code size a bit more by removing a few lines of boilerplate code. The only functional change made by this patch is that we now always include buffer support, instead of making it optional. This is more consistent with what we do for other drivers. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/adc/Kconfig | 3 +- drivers/staging/iio/adc/Makefile | 2 - drivers/staging/iio/adc/ad7298.c | 408 ++++++++++++++++++++++++++++++++++ drivers/staging/iio/adc/ad7298.h | 53 ----- drivers/staging/iio/adc/ad7298_core.c | 293 ------------------------ drivers/staging/iio/adc/ad7298_ring.c | 108 --------- 6 files changed, 410 insertions(+), 457 deletions(-) create mode 100644 drivers/staging/iio/adc/ad7298.c delete mode 100644 drivers/staging/iio/adc/ad7298_core.c delete mode 100644 drivers/staging/iio/adc/ad7298_ring.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 0177f1e0230..5086a46b8e9 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -13,7 +13,8 @@ config AD7291 config AD7298 tristate "Analog Devices AD7298 ADC driver" depends on SPI - select IIO_TRIGGERED_BUFFER if IIO_BUFFER + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say yes here to build support for Analog Devices AD7298 8 Channel ADC with temperature sensor. diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 12b4bd32437..4beaa588256 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -12,8 +12,6 @@ ad799x-y := ad799x_core.o ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o obj-$(CONFIG_AD799X) += ad799x.o -ad7298-y := ad7298_core.o -ad7298-$(CONFIG_IIO_BUFFER) += ad7298_ring.o obj-$(CONFIG_AD7298) += ad7298.o obj-$(CONFIG_AD7291) += ad7291.o diff --git a/drivers/staging/iio/adc/ad7298.c b/drivers/staging/iio/adc/ad7298.c new file mode 100644 index 00000000000..2742a9de05d --- /dev/null +++ b/drivers/staging/iio/adc/ad7298.c @@ -0,0 +1,408 @@ +/* + * AD7298 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ad7298.h" + +#define AD7298_WRITE (1 << 15) /* write to the control register */ +#define AD7298_REPEAT (1 << 14) /* repeated conversion enable */ +#define AD7298_CH(x) (1 << (13 - (x))) /* channel select */ +#define AD7298_TSENSE (1 << 5) /* temperature conversion enable */ +#define AD7298_EXTREF (1 << 2) /* external reference enable */ +#define AD7298_TAVG (1 << 1) /* temperature sensor averaging enable */ +#define AD7298_PDD (1 << 0) /* partial power down enable */ + +#define AD7298_MAX_CHAN 8 +#define AD7298_BITS 12 +#define AD7298_STORAGE_BITS 16 +#define AD7298_INTREF_mV 2500 + +#define AD7298_CH_TEMP 9 + +#define RES_MASK(bits) ((1 << (bits)) - 1) + +struct ad7298_state { + struct spi_device *spi; + struct regulator *reg; + unsigned ext_ref; + struct spi_transfer ring_xfer[10]; + struct spi_transfer scan_single_xfer[3]; + struct spi_message ring_msg; + struct spi_message scan_single_msg; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + unsigned short rx_buf[12] ____cacheline_aligned; + unsigned short tx_buf[2]; +}; + +#define AD7298_V_CHAN(index) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = index, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .address = index, \ + .scan_index = index, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + .endianness = IIO_BE, \ + }, \ + } + +static const struct iio_chan_spec ad7298_channels[] = { + { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .address = AD7298_CH_TEMP, + .scan_index = -1, + .scan_type = { + .sign = 's', + .realbits = 32, + .storagebits = 32, + }, + }, + AD7298_V_CHAN(0), + AD7298_V_CHAN(1), + AD7298_V_CHAN(2), + AD7298_V_CHAN(3), + AD7298_V_CHAN(4), + AD7298_V_CHAN(5), + AD7298_V_CHAN(6), + AD7298_V_CHAN(7), + IIO_CHAN_SOFT_TIMESTAMP(8), +}; + +/** + * ad7298_update_scan_mode() setup the spi transfer buffer for the new scan mask + **/ +static int ad7298_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *active_scan_mask) +{ + struct ad7298_state *st = iio_priv(indio_dev); + int i, m; + unsigned short command; + int scan_count; + + /* Now compute overall size */ + scan_count = bitmap_weight(active_scan_mask, indio_dev->masklength); + + command = AD7298_WRITE | st->ext_ref; + + for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1) + if (test_bit(i, active_scan_mask)) + command |= m; + + st->tx_buf[0] = cpu_to_be16(command); + + /* build spi ring message */ + st->ring_xfer[0].tx_buf = &st->tx_buf[0]; + st->ring_xfer[0].len = 2; + st->ring_xfer[0].cs_change = 1; + st->ring_xfer[1].tx_buf = &st->tx_buf[1]; + st->ring_xfer[1].len = 2; + st->ring_xfer[1].cs_change = 1; + + spi_message_init(&st->ring_msg); + spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg); + spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg); + + for (i = 0; i < scan_count; i++) { + st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i]; + st->ring_xfer[i + 2].len = 2; + st->ring_xfer[i + 2].cs_change = 1; + spi_message_add_tail(&st->ring_xfer[i + 2], &st->ring_msg); + } + /* make sure last transfer cs_change is not set */ + st->ring_xfer[i + 1].cs_change = 0; + + return 0; +} + +/** + * ad7298_trigger_handler() bh of trigger launched polling to ring buffer + * + * Currently there is no option in this driver to disable the saving of + * timestamps within the ring. + **/ +static irqreturn_t ad7298_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad7298_state *st = iio_priv(indio_dev); + s64 time_ns = 0; + int b_sent; + + b_sent = spi_sync(st->spi, &st->ring_msg); + if (b_sent) + goto done; + + if (indio_dev->scan_timestamp) { + time_ns = iio_get_time_ns(); + memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64), + &time_ns, sizeof(time_ns)); + } + + iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf); + +done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch) +{ + int ret; + st->tx_buf[0] = cpu_to_be16(AD7298_WRITE | st->ext_ref | + (AD7298_CH(0) >> ch)); + + ret = spi_sync(st->spi, &st->scan_single_msg); + if (ret) + return ret; + + return be16_to_cpu(st->rx_buf[0]); +} + +static int ad7298_scan_temp(struct ad7298_state *st, int *val) +{ + int ret; + __be16 buf; + + buf = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE | + AD7298_TAVG | st->ext_ref); + + ret = spi_write(st->spi, (u8 *)&buf, 2); + if (ret) + return ret; + + buf = cpu_to_be16(0); + + ret = spi_write(st->spi, (u8 *)&buf, 2); + if (ret) + return ret; + + usleep_range(101, 1000); /* sleep > 100us */ + + ret = spi_read(st->spi, (u8 *)&buf, 2); + if (ret) + return ret; + + *val = sign_extend32(be16_to_cpu(buf), 11); + + return 0; +} + +static int ad7298_get_ref_voltage(struct ad7298_state *st) +{ + int vref; + + if (st->ext_ref) { + vref = regulator_get_voltage(st->reg); + if (vref < 0) + return vref; + + return vref / 1000; + } else { + return AD7298_INTREF_mV; + } +} + +static int ad7298_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + int ret; + struct ad7298_state *st = iio_priv(indio_dev); + + switch (m) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&indio_dev->mlock); + if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { + ret = -EBUSY; + } else { + if (chan->address == AD7298_CH_TEMP) + ret = ad7298_scan_temp(st, val); + else + ret = ad7298_scan_direct(st, chan->address); + } + mutex_unlock(&indio_dev->mlock); + + if (ret < 0) + return ret; + + if (chan->address != AD7298_CH_TEMP) + *val = ret & RES_MASK(AD7298_BITS); + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_VOLTAGE: + *val = ad7298_get_ref_voltage(st); + *val2 = chan->scan_type.realbits; + return IIO_VAL_FRACTIONAL_LOG2; + case IIO_TEMP: + *val = ad7298_get_ref_voltage(st); + *val2 = 10; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_OFFSET: + *val = 1093 - 2732500 / ad7298_get_ref_voltage(st); + return IIO_VAL_INT; + } + return -EINVAL; +} + +static const struct iio_info ad7298_info = { + .read_raw = &ad7298_read_raw, + .update_scan_mode = ad7298_update_scan_mode, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad7298_probe(struct spi_device *spi) +{ + struct ad7298_platform_data *pdata = spi->dev.platform_data; + struct ad7298_state *st; + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); + int ret; + + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + if (pdata && pdata->ext_ref) + st->ext_ref = AD7298_EXTREF; + + if (st->ext_ref) { + st->reg = regulator_get(&spi->dev, "vref"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto error_free; + } + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + spi_set_drvdata(spi, indio_dev); + + st->spi = spi; + + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad7298_channels; + indio_dev->num_channels = ARRAY_SIZE(ad7298_channels); + indio_dev->info = &ad7298_info; + + /* Setup default message */ + + st->scan_single_xfer[0].tx_buf = &st->tx_buf[0]; + st->scan_single_xfer[0].len = 2; + st->scan_single_xfer[0].cs_change = 1; + st->scan_single_xfer[1].tx_buf = &st->tx_buf[1]; + st->scan_single_xfer[1].len = 2; + st->scan_single_xfer[1].cs_change = 1; + st->scan_single_xfer[2].rx_buf = &st->rx_buf[0]; + st->scan_single_xfer[2].len = 2; + + spi_message_init(&st->scan_single_msg); + spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg); + spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg); + spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg); + + ret = iio_triggered_buffer_setup(indio_dev, NULL, + &ad7298_trigger_handler, NULL); + if (ret) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_cleanup_ring; + + return 0; + +error_cleanup_ring: + iio_triggered_buffer_cleanup(indio_dev); +error_disable_reg: + if (st->ext_ref) + regulator_disable(st->reg); +error_put_reg: + if (st->ext_ref) + regulator_put(st->reg); +error_free: + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit ad7298_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7298_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + if (st->ext_ref) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad7298_id[] = { + {"ad7298", 0}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad7298_id); + +static struct spi_driver ad7298_driver = { + .driver = { + .name = "ad7298", + .owner = THIS_MODULE, + }, + .probe = ad7298_probe, + .remove = __devexit_p(ad7298_remove), + .id_table = ad7298_id, +}; +module_spi_driver(ad7298_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7298 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h index 6523e011361..c8ac969ec01 100644 --- a/drivers/staging/iio/adc/ad7298.h +++ b/drivers/staging/iio/adc/ad7298.h @@ -9,23 +9,6 @@ #ifndef IIO_ADC_AD7298_H_ #define IIO_ADC_AD7298_H_ -#define AD7298_WRITE (1 << 15) /* write to the control register */ -#define AD7298_REPEAT (1 << 14) /* repeated conversion enable */ -#define AD7298_CH(x) (1 << (13 - (x))) /* channel select */ -#define AD7298_TSENSE (1 << 5) /* temperature conversion enable */ -#define AD7298_EXTREF (1 << 2) /* external reference enable */ -#define AD7298_TAVG (1 << 1) /* temperature sensor averaging enable */ -#define AD7298_PDD (1 << 0) /* partial power down enable */ - -#define AD7298_MAX_CHAN 8 -#define AD7298_BITS 12 -#define AD7298_STORAGE_BITS 16 -#define AD7298_INTREF_mV 2500 - -#define AD7298_CH_TEMP 9 - -#define RES_MASK(bits) ((1 << (bits)) - 1) - /** * struct ad7298_platform_data - Platform data for the ad7298 ADC driver * @ext_ref: Whether to use an external reference voltage. @@ -34,40 +17,4 @@ struct ad7298_platform_data { bool ext_ref; }; -struct ad7298_state { - struct spi_device *spi; - struct regulator *reg; - unsigned ext_ref; - struct spi_transfer ring_xfer[10]; - struct spi_transfer scan_single_xfer[3]; - struct spi_message ring_msg; - struct spi_message scan_single_msg; - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - */ - unsigned short rx_buf[12] ____cacheline_aligned; - unsigned short tx_buf[2]; -}; - -#ifdef CONFIG_IIO_BUFFER -int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev); -void ad7298_ring_cleanup(struct iio_dev *indio_dev); -int ad7298_update_scan_mode(struct iio_dev *indio_dev, - const unsigned long *active_scan_mask); -#else /* CONFIG_IIO_BUFFER */ - -static inline int -ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) -{ - return 0; -} - -static inline void ad7298_ring_cleanup(struct iio_dev *indio_dev) -{ -} - -#define ad7298_update_scan_mode NULL - -#endif /* CONFIG_IIO_BUFFER */ #endif /* IIO_ADC_AD7298_H_ */ diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c deleted file mode 100644 index b74b76ffcac..00000000000 --- a/drivers/staging/iio/adc/ad7298_core.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * AD7298 SPI ADC driver - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "ad7298.h" - -#define AD7298_V_CHAN(index) \ - { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = index, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ - .address = index, \ - .scan_index = index, \ - .scan_type = { \ - .sign = 'u', \ - .realbits = 12, \ - .storagebits = 16, \ - .endianness = IIO_BE, \ - }, \ - } - -static const struct iio_chan_spec ad7298_channels[] = { - { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - .address = AD7298_CH_TEMP, - .scan_index = -1, - .scan_type = { - .sign = 's', - .realbits = 32, - .storagebits = 32, - }, - }, - AD7298_V_CHAN(0), - AD7298_V_CHAN(1), - AD7298_V_CHAN(2), - AD7298_V_CHAN(3), - AD7298_V_CHAN(4), - AD7298_V_CHAN(5), - AD7298_V_CHAN(6), - AD7298_V_CHAN(7), - IIO_CHAN_SOFT_TIMESTAMP(8), -}; - -static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch) -{ - int ret; - st->tx_buf[0] = cpu_to_be16(AD7298_WRITE | st->ext_ref | - (AD7298_CH(0) >> ch)); - - ret = spi_sync(st->spi, &st->scan_single_msg); - if (ret) - return ret; - - return be16_to_cpu(st->rx_buf[0]); -} - -static int ad7298_scan_temp(struct ad7298_state *st, int *val) -{ - int ret; - __be16 buf; - - buf = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE | - AD7298_TAVG | st->ext_ref); - - ret = spi_write(st->spi, (u8 *)&buf, 2); - if (ret) - return ret; - - buf = cpu_to_be16(0); - - ret = spi_write(st->spi, (u8 *)&buf, 2); - if (ret) - return ret; - - usleep_range(101, 1000); /* sleep > 100us */ - - ret = spi_read(st->spi, (u8 *)&buf, 2); - if (ret) - return ret; - - *val = sign_extend32(be16_to_cpu(buf), 11); - - return 0; -} - -static int ad7298_get_ref_voltage(struct ad7298_state *st) -{ - int vref; - - if (st->ext_ref) { - vref = regulator_get_voltage(st->reg); - if (vref < 0) - return vref; - - return vref / 1000; - } else { - return AD7298_INTREF_mV; - } -} - -static int ad7298_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long m) -{ - int ret; - struct ad7298_state *st = iio_priv(indio_dev); - - switch (m) { - case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { - ret = -EBUSY; - } else { - if (chan->address == AD7298_CH_TEMP) - ret = ad7298_scan_temp(st, val); - else - ret = ad7298_scan_direct(st, chan->address); - } - mutex_unlock(&indio_dev->mlock); - - if (ret < 0) - return ret; - - if (chan->address != AD7298_CH_TEMP) - *val = ret & RES_MASK(AD7298_BITS); - - return IIO_VAL_INT; - case IIO_CHAN_INFO_SCALE: - switch (chan->type) { - case IIO_VOLTAGE: - *val = ad7298_get_ref_voltage(st); - *val2 = chan->scan_type.realbits; - return IIO_VAL_FRACTIONAL_LOG2; - case IIO_TEMP: - *val = ad7298_get_ref_voltage(st); - *val2 = 10; - return IIO_VAL_FRACTIONAL; - default: - return -EINVAL; - } - case IIO_CHAN_INFO_OFFSET: - *val = 1093 - 2732500 / ad7298_get_ref_voltage(st); - return IIO_VAL_INT; - } - return -EINVAL; -} - -static const struct iio_info ad7298_info = { - .read_raw = &ad7298_read_raw, - .update_scan_mode = ad7298_update_scan_mode, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad7298_probe(struct spi_device *spi) -{ - struct ad7298_platform_data *pdata = spi->dev.platform_data; - struct ad7298_state *st; - struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); - int ret; - - if (indio_dev == NULL) - return -ENOMEM; - - st = iio_priv(indio_dev); - - if (pdata && pdata->ext_ref) - st->ext_ref = AD7298_EXTREF; - - if (st->ext_ref) { - st->reg = regulator_get(&spi->dev, "vref"); - if (IS_ERR(st->reg)) { - ret = PTR_ERR(st->reg); - goto error_free; - } - ret = regulator_enable(st->reg); - if (ret) - goto error_put_reg; - } - - spi_set_drvdata(spi, indio_dev); - - st->spi = spi; - - indio_dev->name = spi_get_device_id(spi)->name; - indio_dev->dev.parent = &spi->dev; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = ad7298_channels; - indio_dev->num_channels = ARRAY_SIZE(ad7298_channels); - indio_dev->info = &ad7298_info; - - /* Setup default message */ - - st->scan_single_xfer[0].tx_buf = &st->tx_buf[0]; - st->scan_single_xfer[0].len = 2; - st->scan_single_xfer[0].cs_change = 1; - st->scan_single_xfer[1].tx_buf = &st->tx_buf[1]; - st->scan_single_xfer[1].len = 2; - st->scan_single_xfer[1].cs_change = 1; - st->scan_single_xfer[2].rx_buf = &st->rx_buf[0]; - st->scan_single_xfer[2].len = 2; - - spi_message_init(&st->scan_single_msg); - spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg); - spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg); - spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg); - - ret = ad7298_register_ring_funcs_and_init(indio_dev); - if (ret) - goto error_disable_reg; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_ring; - - return 0; - -error_cleanup_ring: - ad7298_ring_cleanup(indio_dev); -error_disable_reg: - if (st->ext_ref) - regulator_disable(st->reg); -error_put_reg: - if (st->ext_ref) - regulator_put(st->reg); -error_free: - iio_device_free(indio_dev); - - return ret; -} - -static int __devexit ad7298_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad7298_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - ad7298_ring_cleanup(indio_dev); - if (st->ext_ref) { - regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_device_free(indio_dev); - - return 0; -} - -static const struct spi_device_id ad7298_id[] = { - {"ad7298", 0}, - {} -}; -MODULE_DEVICE_TABLE(spi, ad7298_id); - -static struct spi_driver ad7298_driver = { - .driver = { - .name = "ad7298", - .owner = THIS_MODULE, - }, - .probe = ad7298_probe, - .remove = __devexit_p(ad7298_remove), - .id_table = ad7298_id, -}; -module_spi_driver(ad7298_driver); - -MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD7298 ADC"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c deleted file mode 100644 index e3877129222..00000000000 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * AD7298 SPI ADC driver - * - * Copyright 2011-2012 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ad7298.h" - -/** - * ad7298_update_scan_mode() setup the spi transfer buffer for the new scan mask - **/ -int ad7298_update_scan_mode(struct iio_dev *indio_dev, - const unsigned long *active_scan_mask) -{ - struct ad7298_state *st = iio_priv(indio_dev); - int i, m; - unsigned short command; - int scan_count; - - /* Now compute overall size */ - scan_count = bitmap_weight(active_scan_mask, indio_dev->masklength); - - command = AD7298_WRITE | st->ext_ref; - - for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1) - if (test_bit(i, active_scan_mask)) - command |= m; - - st->tx_buf[0] = cpu_to_be16(command); - - /* build spi ring message */ - st->ring_xfer[0].tx_buf = &st->tx_buf[0]; - st->ring_xfer[0].len = 2; - st->ring_xfer[0].cs_change = 1; - st->ring_xfer[1].tx_buf = &st->tx_buf[1]; - st->ring_xfer[1].len = 2; - st->ring_xfer[1].cs_change = 1; - - spi_message_init(&st->ring_msg); - spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg); - spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg); - - for (i = 0; i < scan_count; i++) { - st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i]; - st->ring_xfer[i + 2].len = 2; - st->ring_xfer[i + 2].cs_change = 1; - spi_message_add_tail(&st->ring_xfer[i + 2], &st->ring_msg); - } - /* make sure last transfer cs_change is not set */ - st->ring_xfer[i + 1].cs_change = 0; - - return 0; -} - -/** - * ad7298_trigger_handler() bh of trigger launched polling to ring buffer - * - * Currently there is no option in this driver to disable the saving of - * timestamps within the ring. - **/ -static irqreturn_t ad7298_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct ad7298_state *st = iio_priv(indio_dev); - s64 time_ns = 0; - int b_sent; - - b_sent = spi_sync(st->spi, &st->ring_msg); - if (b_sent) - goto done; - - if (indio_dev->scan_timestamp) { - time_ns = iio_get_time_ns(); - memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64), - &time_ns, sizeof(time_ns)); - } - - iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf); - -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev) -{ - return iio_triggered_buffer_setup(indio_dev, NULL, - &ad7298_trigger_handler, NULL); -} - -void ad7298_ring_cleanup(struct iio_dev *indio_dev) -{ - iio_triggered_buffer_cleanup(indio_dev); -} -- cgit v1.2.3 From 709ab36e9559ff5c7df6e6f2d9e3c4a4410f8d49 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 17 Nov 2012 11:42:59 +0000 Subject: staging:iio: Move the ad7298 driver out of staging The driver does not expose any custom API to userspace and none of the standard static code checker tools report any issues, so move it out of staging. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 12 ++ drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ad7298.c | 408 +++++++++++++++++++++++++++++++++++ drivers/staging/iio/adc/Kconfig | 12 -- drivers/staging/iio/adc/Makefile | 2 - drivers/staging/iio/adc/ad7298.c | 408 ----------------------------------- drivers/staging/iio/adc/ad7298.h | 20 -- include/linux/platform_data/ad7298.h | 20 ++ 8 files changed, 441 insertions(+), 442 deletions(-) create mode 100644 drivers/iio/adc/ad7298.c delete mode 100644 drivers/staging/iio/adc/ad7298.c delete mode 100644 drivers/staging/iio/adc/ad7298.h create mode 100644 include/linux/platform_data/ad7298.h diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index ef5200a6850..cd5eed60be2 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -18,6 +18,18 @@ config AD7266 Say yes here to build support for Analog Devices AD7265 and AD7266 ADCs. +config AD7298 + tristate "Analog Devices AD7298 ADC driver" + depends on SPI + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Analog Devices AD7298 + 8 Channel ADC with temperature sensor. + + To compile this driver as a module, choose M here: the + module will be called ad7298. + config AD7791 tristate "Analog Devices AD7791 ADC driver" depends on SPI diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 54ac7bbcd01..3256dc64a46 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o obj-$(CONFIG_AD7266) += ad7266.o +obj-$(CONFIG_AD7298) += ad7298.o obj-$(CONFIG_AD7476) += ad7476.o obj-$(CONFIG_AD7791) += ad7791.o obj-$(CONFIG_AD7887) += ad7887.o diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c new file mode 100644 index 00000000000..441a9a265c1 --- /dev/null +++ b/drivers/iio/adc/ad7298.c @@ -0,0 +1,408 @@ +/* + * AD7298 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#define AD7298_WRITE (1 << 15) /* write to the control register */ +#define AD7298_REPEAT (1 << 14) /* repeated conversion enable */ +#define AD7298_CH(x) (1 << (13 - (x))) /* channel select */ +#define AD7298_TSENSE (1 << 5) /* temperature conversion enable */ +#define AD7298_EXTREF (1 << 2) /* external reference enable */ +#define AD7298_TAVG (1 << 1) /* temperature sensor averaging enable */ +#define AD7298_PDD (1 << 0) /* partial power down enable */ + +#define AD7298_MAX_CHAN 8 +#define AD7298_BITS 12 +#define AD7298_STORAGE_BITS 16 +#define AD7298_INTREF_mV 2500 + +#define AD7298_CH_TEMP 9 + +#define RES_MASK(bits) ((1 << (bits)) - 1) + +struct ad7298_state { + struct spi_device *spi; + struct regulator *reg; + unsigned ext_ref; + struct spi_transfer ring_xfer[10]; + struct spi_transfer scan_single_xfer[3]; + struct spi_message ring_msg; + struct spi_message scan_single_msg; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + unsigned short rx_buf[12] ____cacheline_aligned; + unsigned short tx_buf[2]; +}; + +#define AD7298_V_CHAN(index) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = index, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ + .address = index, \ + .scan_index = index, \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + .endianness = IIO_BE, \ + }, \ + } + +static const struct iio_chan_spec ad7298_channels[] = { + { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, + .address = AD7298_CH_TEMP, + .scan_index = -1, + .scan_type = { + .sign = 's', + .realbits = 32, + .storagebits = 32, + }, + }, + AD7298_V_CHAN(0), + AD7298_V_CHAN(1), + AD7298_V_CHAN(2), + AD7298_V_CHAN(3), + AD7298_V_CHAN(4), + AD7298_V_CHAN(5), + AD7298_V_CHAN(6), + AD7298_V_CHAN(7), + IIO_CHAN_SOFT_TIMESTAMP(8), +}; + +/** + * ad7298_update_scan_mode() setup the spi transfer buffer for the new scan mask + **/ +static int ad7298_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *active_scan_mask) +{ + struct ad7298_state *st = iio_priv(indio_dev); + int i, m; + unsigned short command; + int scan_count; + + /* Now compute overall size */ + scan_count = bitmap_weight(active_scan_mask, indio_dev->masklength); + + command = AD7298_WRITE | st->ext_ref; + + for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1) + if (test_bit(i, active_scan_mask)) + command |= m; + + st->tx_buf[0] = cpu_to_be16(command); + + /* build spi ring message */ + st->ring_xfer[0].tx_buf = &st->tx_buf[0]; + st->ring_xfer[0].len = 2; + st->ring_xfer[0].cs_change = 1; + st->ring_xfer[1].tx_buf = &st->tx_buf[1]; + st->ring_xfer[1].len = 2; + st->ring_xfer[1].cs_change = 1; + + spi_message_init(&st->ring_msg); + spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg); + spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg); + + for (i = 0; i < scan_count; i++) { + st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i]; + st->ring_xfer[i + 2].len = 2; + st->ring_xfer[i + 2].cs_change = 1; + spi_message_add_tail(&st->ring_xfer[i + 2], &st->ring_msg); + } + /* make sure last transfer cs_change is not set */ + st->ring_xfer[i + 1].cs_change = 0; + + return 0; +} + +/** + * ad7298_trigger_handler() bh of trigger launched polling to ring buffer + * + * Currently there is no option in this driver to disable the saving of + * timestamps within the ring. + **/ +static irqreturn_t ad7298_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad7298_state *st = iio_priv(indio_dev); + s64 time_ns = 0; + int b_sent; + + b_sent = spi_sync(st->spi, &st->ring_msg); + if (b_sent) + goto done; + + if (indio_dev->scan_timestamp) { + time_ns = iio_get_time_ns(); + memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64), + &time_ns, sizeof(time_ns)); + } + + iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf); + +done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch) +{ + int ret; + st->tx_buf[0] = cpu_to_be16(AD7298_WRITE | st->ext_ref | + (AD7298_CH(0) >> ch)); + + ret = spi_sync(st->spi, &st->scan_single_msg); + if (ret) + return ret; + + return be16_to_cpu(st->rx_buf[0]); +} + +static int ad7298_scan_temp(struct ad7298_state *st, int *val) +{ + int ret; + __be16 buf; + + buf = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE | + AD7298_TAVG | st->ext_ref); + + ret = spi_write(st->spi, (u8 *)&buf, 2); + if (ret) + return ret; + + buf = cpu_to_be16(0); + + ret = spi_write(st->spi, (u8 *)&buf, 2); + if (ret) + return ret; + + usleep_range(101, 1000); /* sleep > 100us */ + + ret = spi_read(st->spi, (u8 *)&buf, 2); + if (ret) + return ret; + + *val = sign_extend32(be16_to_cpu(buf), 11); + + return 0; +} + +static int ad7298_get_ref_voltage(struct ad7298_state *st) +{ + int vref; + + if (st->ext_ref) { + vref = regulator_get_voltage(st->reg); + if (vref < 0) + return vref; + + return vref / 1000; + } else { + return AD7298_INTREF_mV; + } +} + +static int ad7298_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + int ret; + struct ad7298_state *st = iio_priv(indio_dev); + + switch (m) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&indio_dev->mlock); + if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { + ret = -EBUSY; + } else { + if (chan->address == AD7298_CH_TEMP) + ret = ad7298_scan_temp(st, val); + else + ret = ad7298_scan_direct(st, chan->address); + } + mutex_unlock(&indio_dev->mlock); + + if (ret < 0) + return ret; + + if (chan->address != AD7298_CH_TEMP) + *val = ret & RES_MASK(AD7298_BITS); + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_VOLTAGE: + *val = ad7298_get_ref_voltage(st); + *val2 = chan->scan_type.realbits; + return IIO_VAL_FRACTIONAL_LOG2; + case IIO_TEMP: + *val = ad7298_get_ref_voltage(st); + *val2 = 10; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_OFFSET: + *val = 1093 - 2732500 / ad7298_get_ref_voltage(st); + return IIO_VAL_INT; + } + return -EINVAL; +} + +static const struct iio_info ad7298_info = { + .read_raw = &ad7298_read_raw, + .update_scan_mode = ad7298_update_scan_mode, + .driver_module = THIS_MODULE, +}; + +static int __devinit ad7298_probe(struct spi_device *spi) +{ + struct ad7298_platform_data *pdata = spi->dev.platform_data; + struct ad7298_state *st; + struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); + int ret; + + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + if (pdata && pdata->ext_ref) + st->ext_ref = AD7298_EXTREF; + + if (st->ext_ref) { + st->reg = regulator_get(&spi->dev, "vref"); + if (IS_ERR(st->reg)) { + ret = PTR_ERR(st->reg); + goto error_free; + } + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + spi_set_drvdata(spi, indio_dev); + + st->spi = spi; + + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad7298_channels; + indio_dev->num_channels = ARRAY_SIZE(ad7298_channels); + indio_dev->info = &ad7298_info; + + /* Setup default message */ + + st->scan_single_xfer[0].tx_buf = &st->tx_buf[0]; + st->scan_single_xfer[0].len = 2; + st->scan_single_xfer[0].cs_change = 1; + st->scan_single_xfer[1].tx_buf = &st->tx_buf[1]; + st->scan_single_xfer[1].len = 2; + st->scan_single_xfer[1].cs_change = 1; + st->scan_single_xfer[2].rx_buf = &st->rx_buf[0]; + st->scan_single_xfer[2].len = 2; + + spi_message_init(&st->scan_single_msg); + spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg); + spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg); + spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg); + + ret = iio_triggered_buffer_setup(indio_dev, NULL, + &ad7298_trigger_handler, NULL); + if (ret) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_cleanup_ring; + + return 0; + +error_cleanup_ring: + iio_triggered_buffer_cleanup(indio_dev); +error_disable_reg: + if (st->ext_ref) + regulator_disable(st->reg); +error_put_reg: + if (st->ext_ref) + regulator_put(st->reg); +error_free: + iio_device_free(indio_dev); + + return ret; +} + +static int __devexit ad7298_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7298_state *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); + if (st->ext_ref) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id ad7298_id[] = { + {"ad7298", 0}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad7298_id); + +static struct spi_driver ad7298_driver = { + .driver = { + .name = "ad7298", + .owner = THIS_MODULE, + }, + .probe = ad7298_probe, + .remove = __devexit_p(ad7298_remove), + .id_table = ad7298_id, +}; +module_spi_driver(ad7298_driver); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7298 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 5086a46b8e9..dc8582b95b6 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -10,18 +10,6 @@ config AD7291 Say yes here to build support for Analog Devices AD7291 8 Channel ADC with temperature sensor. -config AD7298 - tristate "Analog Devices AD7298 ADC driver" - depends on SPI - select IIO_BUFFER - select IIO_TRIGGERED_BUFFER - help - Say yes here to build support for Analog Devices AD7298 - 8 Channel ADC with temperature sensor. - - To compile this driver as a module, choose M here: the - module will be called ad7298. - config AD7606 tristate "Analog Devices AD7606 ADC driver" depends on GPIOLIB diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 4beaa588256..7281451a613 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -12,8 +12,6 @@ ad799x-y := ad799x_core.o ad799x-$(CONFIG_AD799X_RING_BUFFER) += ad799x_ring.o obj-$(CONFIG_AD799X) += ad799x.o -obj-$(CONFIG_AD7298) += ad7298.o - obj-$(CONFIG_AD7291) += ad7291.o obj-$(CONFIG_AD7780) += ad7780.o obj-$(CONFIG_AD7793) += ad7793.o diff --git a/drivers/staging/iio/adc/ad7298.c b/drivers/staging/iio/adc/ad7298.c deleted file mode 100644 index 2742a9de05d..00000000000 --- a/drivers/staging/iio/adc/ad7298.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * AD7298 SPI ADC driver - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "ad7298.h" - -#define AD7298_WRITE (1 << 15) /* write to the control register */ -#define AD7298_REPEAT (1 << 14) /* repeated conversion enable */ -#define AD7298_CH(x) (1 << (13 - (x))) /* channel select */ -#define AD7298_TSENSE (1 << 5) /* temperature conversion enable */ -#define AD7298_EXTREF (1 << 2) /* external reference enable */ -#define AD7298_TAVG (1 << 1) /* temperature sensor averaging enable */ -#define AD7298_PDD (1 << 0) /* partial power down enable */ - -#define AD7298_MAX_CHAN 8 -#define AD7298_BITS 12 -#define AD7298_STORAGE_BITS 16 -#define AD7298_INTREF_mV 2500 - -#define AD7298_CH_TEMP 9 - -#define RES_MASK(bits) ((1 << (bits)) - 1) - -struct ad7298_state { - struct spi_device *spi; - struct regulator *reg; - unsigned ext_ref; - struct spi_transfer ring_xfer[10]; - struct spi_transfer scan_single_xfer[3]; - struct spi_message ring_msg; - struct spi_message scan_single_msg; - /* - * DMA (thus cache coherency maintenance) requires the - * transfer buffers to live in their own cache lines. - */ - unsigned short rx_buf[12] ____cacheline_aligned; - unsigned short tx_buf[2]; -}; - -#define AD7298_V_CHAN(index) \ - { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .channel = index, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ - IIO_CHAN_INFO_SCALE_SHARED_BIT, \ - .address = index, \ - .scan_index = index, \ - .scan_type = { \ - .sign = 'u', \ - .realbits = 12, \ - .storagebits = 16, \ - .endianness = IIO_BE, \ - }, \ - } - -static const struct iio_chan_spec ad7298_channels[] = { - { - .type = IIO_TEMP, - .indexed = 1, - .channel = 0, - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | - IIO_CHAN_INFO_SCALE_SEPARATE_BIT | - IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, - .address = AD7298_CH_TEMP, - .scan_index = -1, - .scan_type = { - .sign = 's', - .realbits = 32, - .storagebits = 32, - }, - }, - AD7298_V_CHAN(0), - AD7298_V_CHAN(1), - AD7298_V_CHAN(2), - AD7298_V_CHAN(3), - AD7298_V_CHAN(4), - AD7298_V_CHAN(5), - AD7298_V_CHAN(6), - AD7298_V_CHAN(7), - IIO_CHAN_SOFT_TIMESTAMP(8), -}; - -/** - * ad7298_update_scan_mode() setup the spi transfer buffer for the new scan mask - **/ -static int ad7298_update_scan_mode(struct iio_dev *indio_dev, - const unsigned long *active_scan_mask) -{ - struct ad7298_state *st = iio_priv(indio_dev); - int i, m; - unsigned short command; - int scan_count; - - /* Now compute overall size */ - scan_count = bitmap_weight(active_scan_mask, indio_dev->masklength); - - command = AD7298_WRITE | st->ext_ref; - - for (i = 0, m = AD7298_CH(0); i < AD7298_MAX_CHAN; i++, m >>= 1) - if (test_bit(i, active_scan_mask)) - command |= m; - - st->tx_buf[0] = cpu_to_be16(command); - - /* build spi ring message */ - st->ring_xfer[0].tx_buf = &st->tx_buf[0]; - st->ring_xfer[0].len = 2; - st->ring_xfer[0].cs_change = 1; - st->ring_xfer[1].tx_buf = &st->tx_buf[1]; - st->ring_xfer[1].len = 2; - st->ring_xfer[1].cs_change = 1; - - spi_message_init(&st->ring_msg); - spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg); - spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg); - - for (i = 0; i < scan_count; i++) { - st->ring_xfer[i + 2].rx_buf = &st->rx_buf[i]; - st->ring_xfer[i + 2].len = 2; - st->ring_xfer[i + 2].cs_change = 1; - spi_message_add_tail(&st->ring_xfer[i + 2], &st->ring_msg); - } - /* make sure last transfer cs_change is not set */ - st->ring_xfer[i + 1].cs_change = 0; - - return 0; -} - -/** - * ad7298_trigger_handler() bh of trigger launched polling to ring buffer - * - * Currently there is no option in this driver to disable the saving of - * timestamps within the ring. - **/ -static irqreturn_t ad7298_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct ad7298_state *st = iio_priv(indio_dev); - s64 time_ns = 0; - int b_sent; - - b_sent = spi_sync(st->spi, &st->ring_msg); - if (b_sent) - goto done; - - if (indio_dev->scan_timestamp) { - time_ns = iio_get_time_ns(); - memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64), - &time_ns, sizeof(time_ns)); - } - - iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf); - -done: - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - -static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch) -{ - int ret; - st->tx_buf[0] = cpu_to_be16(AD7298_WRITE | st->ext_ref | - (AD7298_CH(0) >> ch)); - - ret = spi_sync(st->spi, &st->scan_single_msg); - if (ret) - return ret; - - return be16_to_cpu(st->rx_buf[0]); -} - -static int ad7298_scan_temp(struct ad7298_state *st, int *val) -{ - int ret; - __be16 buf; - - buf = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE | - AD7298_TAVG | st->ext_ref); - - ret = spi_write(st->spi, (u8 *)&buf, 2); - if (ret) - return ret; - - buf = cpu_to_be16(0); - - ret = spi_write(st->spi, (u8 *)&buf, 2); - if (ret) - return ret; - - usleep_range(101, 1000); /* sleep > 100us */ - - ret = spi_read(st->spi, (u8 *)&buf, 2); - if (ret) - return ret; - - *val = sign_extend32(be16_to_cpu(buf), 11); - - return 0; -} - -static int ad7298_get_ref_voltage(struct ad7298_state *st) -{ - int vref; - - if (st->ext_ref) { - vref = regulator_get_voltage(st->reg); - if (vref < 0) - return vref; - - return vref / 1000; - } else { - return AD7298_INTREF_mV; - } -} - -static int ad7298_read_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int *val, - int *val2, - long m) -{ - int ret; - struct ad7298_state *st = iio_priv(indio_dev); - - switch (m) { - case IIO_CHAN_INFO_RAW: - mutex_lock(&indio_dev->mlock); - if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) { - ret = -EBUSY; - } else { - if (chan->address == AD7298_CH_TEMP) - ret = ad7298_scan_temp(st, val); - else - ret = ad7298_scan_direct(st, chan->address); - } - mutex_unlock(&indio_dev->mlock); - - if (ret < 0) - return ret; - - if (chan->address != AD7298_CH_TEMP) - *val = ret & RES_MASK(AD7298_BITS); - - return IIO_VAL_INT; - case IIO_CHAN_INFO_SCALE: - switch (chan->type) { - case IIO_VOLTAGE: - *val = ad7298_get_ref_voltage(st); - *val2 = chan->scan_type.realbits; - return IIO_VAL_FRACTIONAL_LOG2; - case IIO_TEMP: - *val = ad7298_get_ref_voltage(st); - *val2 = 10; - return IIO_VAL_FRACTIONAL; - default: - return -EINVAL; - } - case IIO_CHAN_INFO_OFFSET: - *val = 1093 - 2732500 / ad7298_get_ref_voltage(st); - return IIO_VAL_INT; - } - return -EINVAL; -} - -static const struct iio_info ad7298_info = { - .read_raw = &ad7298_read_raw, - .update_scan_mode = ad7298_update_scan_mode, - .driver_module = THIS_MODULE, -}; - -static int __devinit ad7298_probe(struct spi_device *spi) -{ - struct ad7298_platform_data *pdata = spi->dev.platform_data; - struct ad7298_state *st; - struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st)); - int ret; - - if (indio_dev == NULL) - return -ENOMEM; - - st = iio_priv(indio_dev); - - if (pdata && pdata->ext_ref) - st->ext_ref = AD7298_EXTREF; - - if (st->ext_ref) { - st->reg = regulator_get(&spi->dev, "vref"); - if (IS_ERR(st->reg)) { - ret = PTR_ERR(st->reg); - goto error_free; - } - ret = regulator_enable(st->reg); - if (ret) - goto error_put_reg; - } - - spi_set_drvdata(spi, indio_dev); - - st->spi = spi; - - indio_dev->name = spi_get_device_id(spi)->name; - indio_dev->dev.parent = &spi->dev; - indio_dev->modes = INDIO_DIRECT_MODE; - indio_dev->channels = ad7298_channels; - indio_dev->num_channels = ARRAY_SIZE(ad7298_channels); - indio_dev->info = &ad7298_info; - - /* Setup default message */ - - st->scan_single_xfer[0].tx_buf = &st->tx_buf[0]; - st->scan_single_xfer[0].len = 2; - st->scan_single_xfer[0].cs_change = 1; - st->scan_single_xfer[1].tx_buf = &st->tx_buf[1]; - st->scan_single_xfer[1].len = 2; - st->scan_single_xfer[1].cs_change = 1; - st->scan_single_xfer[2].rx_buf = &st->rx_buf[0]; - st->scan_single_xfer[2].len = 2; - - spi_message_init(&st->scan_single_msg); - spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg); - spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg); - spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg); - - ret = iio_triggered_buffer_setup(indio_dev, NULL, - &ad7298_trigger_handler, NULL); - if (ret) - goto error_disable_reg; - - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_ring; - - return 0; - -error_cleanup_ring: - iio_triggered_buffer_cleanup(indio_dev); -error_disable_reg: - if (st->ext_ref) - regulator_disable(st->reg); -error_put_reg: - if (st->ext_ref) - regulator_put(st->reg); -error_free: - iio_device_free(indio_dev); - - return ret; -} - -static int __devexit ad7298_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct ad7298_state *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - iio_triggered_buffer_cleanup(indio_dev); - if (st->ext_ref) { - regulator_disable(st->reg); - regulator_put(st->reg); - } - iio_device_free(indio_dev); - - return 0; -} - -static const struct spi_device_id ad7298_id[] = { - {"ad7298", 0}, - {} -}; -MODULE_DEVICE_TABLE(spi, ad7298_id); - -static struct spi_driver ad7298_driver = { - .driver = { - .name = "ad7298", - .owner = THIS_MODULE, - }, - .probe = ad7298_probe, - .remove = __devexit_p(ad7298_remove), - .id_table = ad7298_id, -}; -module_spi_driver(ad7298_driver); - -MODULE_AUTHOR("Michael Hennerich "); -MODULE_DESCRIPTION("Analog Devices AD7298 ADC"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7298.h b/drivers/staging/iio/adc/ad7298.h deleted file mode 100644 index c8ac969ec01..00000000000 --- a/drivers/staging/iio/adc/ad7298.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * AD7298 SPI ADC driver - * - * Copyright 2011 Analog Devices Inc. - * - * Licensed under the GPL-2. - */ - -#ifndef IIO_ADC_AD7298_H_ -#define IIO_ADC_AD7298_H_ - -/** - * struct ad7298_platform_data - Platform data for the ad7298 ADC driver - * @ext_ref: Whether to use an external reference voltage. - **/ -struct ad7298_platform_data { - bool ext_ref; -}; - -#endif /* IIO_ADC_AD7298_H_ */ diff --git a/include/linux/platform_data/ad7298.h b/include/linux/platform_data/ad7298.h new file mode 100644 index 00000000000..fbf8adf1363 --- /dev/null +++ b/include/linux/platform_data/ad7298.h @@ -0,0 +1,20 @@ +/* + * AD7298 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef __LINUX_PLATFORM_DATA_AD7298_H__ +#define __LINUX_PLATFORM_DATA_AD7298_H__ + +/** + * struct ad7298_platform_data - Platform data for the ad7298 ADC driver + * @ext_ref: Whether to use an external reference voltage. + **/ +struct ad7298_platform_data { + bool ext_ref; +}; + +#endif /* IIO_ADC_AD7298_H_ */ -- cgit v1.2.3 From 16a78e9fed5e8baa8480ae3413f4328c4537c599 Mon Sep 17 00:00:00 2001 From: Thierry Escande Date: Fri, 12 Oct 2012 15:25:43 +0200 Subject: NFC: Fix nfc_llcp_local chained list insertion list_add was called with swapped parameters Signed-off-by: Thierry Escande Signed-off-by: Samuel Ortiz --- net/nfc/llcp/llcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index cc10d073c33..9e8f4b2801f 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -1210,7 +1210,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) local->remote_miu = LLCP_DEFAULT_MIU; local->remote_lto = LLCP_DEFAULT_LTO; - list_add(&llcp_devices, &local->list); + list_add(&local->list, &llcp_devices); return 0; } -- cgit v1.2.3 From 60ad07ab6bc86f48b6ebda1788d79ca5f88d824c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Thu, 25 Oct 2012 17:29:45 +0200 Subject: NFC: pn533: Fix missing lock while operating on commands list In pn533_wq_cmd command was removed from list without cmd_lock held (race with pn533_send_cmd_frame_async) which could lead to list corruption. Delete command from list before releasing lock. Signed-off-by: Szymon Janc Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 97c440a8cd6..328f2b66491 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -698,13 +698,14 @@ static void pn533_wq_cmd(struct work_struct *work) cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue); + list_del(&cmd->queue); + mutex_unlock(&dev->cmd_lock); __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame, cmd->in_frame_len, cmd->cmd_complete, cmd->arg, cmd->flags); - list_del(&cmd->queue); kfree(cmd); } -- cgit v1.2.3 From 770f750bc2b8312489c8e45306f551d08a319d3c Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 29 Oct 2012 14:04:43 +0100 Subject: NFC: pn533: Fix use after free cmd was freed in pn533_dep_link_up regardless of pn533_send_cmd_frame_async return code. Cmd is passed as argument to pn533_in_dep_link_up_complete callback and should be freed there. Signed-off-by: Szymon Janc Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 328f2b66491..84a2e77ab5d 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1820,12 +1820,8 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, dev->in_maxlen, pn533_in_dep_link_up_complete, cmd, GFP_KERNEL); - if (rc) - goto out; - - -out: - kfree(cmd); + if (rc < 0) + kfree(cmd); return rc; } -- cgit v1.2.3 From 70418e6efcf4f8652cc08e3f2ab8ae35f0948fd9 Mon Sep 17 00:00:00 2001 From: Waldemar Rymarkiewicz Date: Thu, 11 Oct 2012 14:04:00 +0200 Subject: NFC: pn533: Fix mem leak in pn533_in_dep_link_up cmd is allocated in pn533_dep_link_up and passed as an arg to pn533_send_cmd_frame_async together with a complete cb. arg is passed to the cb and must be kfreed there. Signed-off-by: Waldemar Rymarkiewicz Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 84a2e77ab5d..807bbb8e82d 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -1679,11 +1679,14 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) { - struct pn533_cmd_jump_dep *cmd; struct pn533_cmd_jump_dep_response *resp; struct nfc_target nfc_target; u8 target_gt_len; int rc; + struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg; + u8 active = cmd->active; + + kfree(arg); if (params_len == -ENOENT) { nfc_dev_dbg(&dev->interface->dev, ""); @@ -1705,7 +1708,6 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, } resp = (struct pn533_cmd_jump_dep_response *) params; - cmd = (struct pn533_cmd_jump_dep *) arg; rc = resp->status & PN533_CMD_RET_MASK; if (rc != PN533_CMD_RET_SUCCESS) { nfc_dev_err(&dev->interface->dev, @@ -1735,7 +1737,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, if (rc == 0) rc = nfc_dep_link_is_up(dev->nfc_dev, dev->nfc_dev->targets[0].idx, - !cmd->active, NFC_RF_INITIATOR); + !active, NFC_RF_INITIATOR); return 0; } -- cgit v1.2.3 From 5b412fd11c918171c98a253d8a3484afa9f69ca5 Mon Sep 17 00:00:00 2001 From: Thierry Escande Date: Thu, 15 Nov 2012 18:24:28 +0100 Subject: NFC: Fix pn533 target mode memory leak In target mode, sent sk_buff were not freed in pn533_tm_send_complete Signed-off-by: Thierry Escande Signed-off-by: Samuel Ortiz --- drivers/nfc/pn533.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index 807bbb8e82d..30ae18a03a9 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c @@ -2077,8 +2077,12 @@ error: static int pn533_tm_send_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) { + struct sk_buff *skb_out = arg; + nfc_dev_dbg(&dev->interface->dev, "%s", __func__); + dev_kfree_skb(skb_out); + if (params_len < 0) { nfc_dev_err(&dev->interface->dev, "Error %d when sending data", @@ -2116,7 +2120,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, dev->in_maxlen, pn533_tm_send_complete, - NULL, GFP_KERNEL); + skb, GFP_KERNEL); if (rc) { nfc_dev_err(&dev->interface->dev, "Error %d when trying to send data", rc); -- cgit v1.2.3 From ab05613a0646dcc11049692d54bae76ca9ffa910 Mon Sep 17 00:00:00 2001 From: majianpeng Date: Tue, 6 Nov 2012 17:13:44 +0800 Subject: md: Reassigned the parameters if read_seqretry returned true in func md_is_badblock. This bug was introduced by commit(v3.0-rc7-126-g2230dfe). So fix is suitable for 3.0.y thru 3.6.y. Cc: stable@vger.kernel.org Signed-off-by: Jianpeng Ma Signed-off-by: NeilBrown --- drivers/md/md.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 9ab768acfb6..14db6abb2c4 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7936,9 +7936,9 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, sector_t *first_bad, int *bad_sectors) { int hi; - int lo = 0; + int lo; u64 *p = bb->page; - int rv = 0; + int rv; sector_t target = s + sectors; unsigned seq; @@ -7953,7 +7953,8 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors, retry: seq = read_seqbegin(&bb->lock); - + lo = 0; + rv = 0; hi = bb->count; /* Binary search between lo and hi for 'target' -- cgit v1.2.3 From 35f9ac2dcec8f79d7059ce174fd7b7ee3290d620 Mon Sep 17 00:00:00 2001 From: majianpeng Date: Thu, 8 Nov 2012 08:56:27 +0800 Subject: md: Avoid write invalid address if read_seqretry returned true. If read_seqretry returned true and bbp was changed, it will write invalid address which can cause some serious problem. This bug was introduced by commit v3.0-rc7-130-g2699b67. So fix is suitable for 3.0.y thru 3.6.y. Reported-by: zhuwenfeng@kedacom.com Tested-by: zhuwenfeng@kedacom.com Cc: stable@vger.kernel.org Signed-off-by: Jianpeng Ma Signed-off-by: NeilBrown --- drivers/md/md.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 14db6abb2c4..4c7d880a60a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1817,10 +1817,10 @@ retry: memset(bbp, 0xff, PAGE_SIZE); for (i = 0 ; i < bb->count ; i++) { - u64 internal_bb = *p++; + u64 internal_bb = p[i]; u64 store_bb = ((BB_OFFSET(internal_bb) << 10) | BB_LEN(internal_bb)); - *bbp++ = cpu_to_le64(store_bb); + bbp[i] = cpu_to_le64(store_bb); } bb->changed = 0; if (read_seqretry(&bb->lock, seq)) -- cgit v1.2.3 From 5eff3c439d3478ba9e8ba5f8c0aaf6e6fadb6e58 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 19 Nov 2012 10:47:48 +1100 Subject: md: make sure everything is freed when dm-raid stops an array. md_stop() would stop an array, but not free various attached data structures. For internal arrays, these are freed later in do_md_stop() or mddev_put(), but they don't apply for dm-raid arrays. So get md_stop() to free them, and only all it from dm-raid. For internal arrays we now call __md_stop. Reported-by: majianpeng Signed-off-by: NeilBrown --- drivers/md/md.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 4c7d880a60a..61200717687 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5294,7 +5294,7 @@ void md_stop_writes(struct mddev *mddev) } EXPORT_SYMBOL_GPL(md_stop_writes); -void md_stop(struct mddev *mddev) +static void __md_stop(struct mddev *mddev) { mddev->ready = 0; mddev->pers->stop(mddev); @@ -5304,6 +5304,18 @@ void md_stop(struct mddev *mddev) mddev->pers = NULL; clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); } + +void md_stop(struct mddev *mddev) +{ + /* stop the array and free an attached data structures. + * This is called from dm-raid + */ + __md_stop(mddev); + bitmap_destroy(mddev); + if (mddev->bio_set) + bioset_free(mddev->bio_set); +} + EXPORT_SYMBOL_GPL(md_stop); static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) @@ -5364,7 +5376,7 @@ static int do_md_stop(struct mddev * mddev, int mode, set_disk_ro(disk, 0); __md_stop_writes(mddev); - md_stop(mddev); + __md_stop(mddev); mddev->queue->merge_bvec_fn = NULL; mddev->queue->backing_dev_info.congested_fn = NULL; -- cgit v1.2.3 From 3272dd9b0fe4bc09321219ab65dc5eda3e82445c Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 16 Nov 2012 00:33:59 +0000 Subject: of/net/mdio-gpio: Fix pdev->id issue when using devicetrees. When the mdio-gpio driver is probed via device trees, the platform device id is set as -1, However the pdev->id is re-used as bus-id for while creating mdio gpio bus. So For device tree case the mdio-gpio bus name appears as "gpio-ffffffff" where as for non-device tree case the bus name appears as "gpio-" Which means the bus_id is fixed in device tree case, so we can't have two mdio gpio buses via device trees. Assigning a logical bus number via device tree solves the problem and the bus name is much consistent with non-device tree bus name. Without this patch 1. we can't support two mdio-gpio buses via device trees. 2. we should always pass gpio-ffffffff as bus name to phy_connect, very different to non-device tree bus name. So, setting up the bus_id via aliases from device tree is the right solution and other drivers do similar thing. Signed-off-by: Srinivas Kandagatla Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/mdio-gpio.txt | 9 ++++++++- drivers/net/phy/mdio-gpio.c | 11 +++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/net/mdio-gpio.txt b/Documentation/devicetree/bindings/net/mdio-gpio.txt index bc954952901..c79bab02536 100644 --- a/Documentation/devicetree/bindings/net/mdio-gpio.txt +++ b/Documentation/devicetree/bindings/net/mdio-gpio.txt @@ -8,9 +8,16 @@ gpios property as described in section VIII.1 in the following order: MDC, MDIO. +Note: Each gpio-mdio bus should have an alias correctly numbered in "aliases" +node. + Example: -mdio { +aliases { + mdio-gpio0 = <&mdio0>; +}; + +mdio0: mdio { compatible = "virtual,mdio-gpio"; #address-cells = <1>; #size-cells = <0>; diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 899274f2f9b..2ed1140df3e 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -185,17 +185,20 @@ static int __devinit mdio_gpio_probe(struct platform_device *pdev) { struct mdio_gpio_platform_data *pdata; struct mii_bus *new_bus; - int ret; + int ret, bus_id; - if (pdev->dev.of_node) + if (pdev->dev.of_node) { pdata = mdio_gpio_of_get_data(pdev); - else + bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio"); + } else { pdata = pdev->dev.platform_data; + bus_id = pdev->id; + } if (!pdata) return -ENODEV; - new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); + new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, bus_id); if (!new_bus) return -ENODEV; -- cgit v1.2.3 From d7895052d97cde63b34e5185da28052384fa8564 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 21 Aug 2012 15:35:32 +0530 Subject: PM / devfreq: Use devm_* functions in exynos4_bus.c devm_* functions are device managed functions and make cleanup code simpler and smaller. devm_kzalloc and devm_regulator_get functions are used. Signed-off-by: Sachin Kamat [renamed the patch title by MyungJoo Ham] Signed-off-by: MyungJoo Ham --- drivers/devfreq/exynos4_bus.c | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c index 88ddc77a9bb..68145316c49 100644 --- a/drivers/devfreq/exynos4_bus.c +++ b/drivers/devfreq/exynos4_bus.c @@ -987,7 +987,7 @@ static __devinit int exynos4_busfreq_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; int err = 0; - data = kzalloc(sizeof(struct busfreq_data), GFP_KERNEL); + data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data), GFP_KERNEL); if (data == NULL) { dev_err(dev, "Cannot allocate memory.\n"); return -ENOMEM; @@ -1012,22 +1012,18 @@ static __devinit int exynos4_busfreq_probe(struct platform_device *pdev) err = -EINVAL; } if (err) - goto err_regulator; + return err; - data->vdd_int = regulator_get(dev, "vdd_int"); + data->vdd_int = devm_regulator_get(dev, "vdd_int"); if (IS_ERR(data->vdd_int)) { dev_err(dev, "Cannot get the regulator \"vdd_int\"\n"); - err = PTR_ERR(data->vdd_int); - goto err_regulator; + return PTR_ERR(data->vdd_int); } if (data->type == TYPE_BUSF_EXYNOS4x12) { - data->vdd_mif = regulator_get(dev, "vdd_mif"); + data->vdd_mif = devm_regulator_get(dev, "vdd_mif"); if (IS_ERR(data->vdd_mif)) { dev_err(dev, "Cannot get the regulator \"vdd_mif\"\n"); - err = PTR_ERR(data->vdd_mif); - regulator_put(data->vdd_int); - goto err_regulator; - + return PTR_ERR(data->vdd_mif); } } @@ -1035,8 +1031,7 @@ static __devinit int exynos4_busfreq_probe(struct platform_device *pdev) if (IS_ERR(opp)) { dev_err(dev, "Invalid initial frequency %lu kHz.\n", exynos4_devfreq_profile.initial_freq); - err = PTR_ERR(opp); - goto err_opp_add; + return PTR_ERR(opp); } data->curr_opp = opp; @@ -1046,29 +1041,19 @@ static __devinit int exynos4_busfreq_probe(struct platform_device *pdev) data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile, &devfreq_simple_ondemand, NULL); - if (IS_ERR(data->devfreq)) { - err = PTR_ERR(data->devfreq); - goto err_opp_add; - } + if (IS_ERR(data->devfreq)) + return PTR_ERR(data->devfreq); devfreq_register_opp_notifier(dev, data->devfreq); err = register_pm_notifier(&data->pm_notifier); if (err) { dev_err(dev, "Failed to setup pm notifier\n"); - goto err_devfreq_add; + devfreq_remove_device(data->devfreq); + return err; } return 0; -err_devfreq_add: - devfreq_remove_device(data->devfreq); -err_opp_add: - if (data->vdd_mif) - regulator_put(data->vdd_mif); - regulator_put(data->vdd_int); -err_regulator: - kfree(data); - return err; } static __devexit int exynos4_busfreq_remove(struct platform_device *pdev) @@ -1077,10 +1062,6 @@ static __devexit int exynos4_busfreq_remove(struct platform_device *pdev) unregister_pm_notifier(&data->pm_notifier); devfreq_remove_device(data->devfreq); - regulator_put(data->vdd_int); - if (data->vdd_mif) - regulator_put(data->vdd_mif); - kfree(data); return 0; } -- cgit v1.2.3 From e09651fcc295a7dc802f38d9494f5b860dd90bca Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 29 Oct 2012 08:02:23 -0500 Subject: PM / devfreq: documentation cleanups for devfreq header struct parameters need to have ':' in documentation for scripts/kernel-doc to parse appropriately. Fix the errors reported by: ./scripts/kernel-doc include/linux/devfreq.h >/dev/null Cc: Rajagopal Venkat Cc: MyungJoo Ham Cc: Kyungmin Park Cc: "Rafael J. Wysocki" Cc: Kevin Hilman Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nishanth Menon Acked-by: Randy Dunlap Acked-by: MyungJoo Ham Signed-off-by: MyungJoo Ham --- include/linux/devfreq.h | 54 ++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 7e2e2ea4a70..1461fb2355a 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -25,12 +25,12 @@ struct devfreq; * struct devfreq_dev_status - Data given from devfreq user device to * governors. Represents the performance * statistics. - * @total_time The total time represented by this instance of + * @total_time: The total time represented by this instance of * devfreq_dev_status - * @busy_time The time that the device was working among the + * @busy_time: The time that the device was working among the * total_time. - * @current_frequency The operating frequency. - * @private_data An entry not specified by the devfreq framework. + * @current_frequency: The operating frequency. + * @private_data: An entry not specified by the devfreq framework. * A device and a specific governor may have their * own protocol with private_data. However, because * this is governor-specific, a governor using this @@ -54,21 +54,21 @@ struct devfreq_dev_status { /** * struct devfreq_dev_profile - Devfreq's user device profile - * @initial_freq The operating frequency when devfreq_add_device() is + * @initial_freq: The operating frequency when devfreq_add_device() is * called. - * @polling_ms The polling interval in ms. 0 disables polling. - * @target The device should set its operating frequency at + * @polling_ms: The polling interval in ms. 0 disables polling. + * @target: The device should set its operating frequency at * freq or lowest-upper-than-freq value. If freq is * higher than any operable frequency, set maximum. * Before returning, target function should set * freq at the current frequency. * The "flags" parameter's possible values are * explained above with "DEVFREQ_FLAG_*" macros. - * @get_dev_status The device should provide the current performance + * @get_dev_status: The device should provide the current performance * status to devfreq, which is used by governors. - * @get_cur_freq The device should provide the current frequency + * @get_cur_freq: The device should provide the current frequency * at which it is operating. - * @exit An optional callback that is called when devfreq + * @exit: An optional callback that is called when devfreq * is removing the devfreq object due to error or * from devfreq_remove_device() call. If the user * has registered devfreq->nb at a notifier-head, @@ -87,14 +87,14 @@ struct devfreq_dev_profile { /** * struct devfreq_governor - Devfreq policy governor - * @name Governor's name - * @get_target_freq Returns desired operating frequency for the device. + * @name: Governor's name + * @get_target_freq: Returns desired operating frequency for the device. * Basically, get_target_freq will run * devfreq_dev_profile.get_dev_status() to get the * status of the device (load = busy_time / total_time). * If no_central_polling is set, this callback is called * only with update_devfreq() notified by OPP. - * @event_handler Callback for devfreq core framework to notify events + * @event_handler: Callback for devfreq core framework to notify events * to governors. Events include per device governor * init and exit, opp changes out of devfreq, suspend * and resume of per device devfreq during device idle. @@ -110,23 +110,23 @@ struct devfreq_governor { /** * struct devfreq - Device devfreq structure - * @node list node - contains the devices with devfreq that have been + * @node: list node - contains the devices with devfreq that have been * registered. - * @lock a mutex to protect accessing devfreq. - * @dev device registered by devfreq class. dev.parent is the device + * @lock: a mutex to protect accessing devfreq. + * @dev: device registered by devfreq class. dev.parent is the device * using devfreq. - * @profile device-specific devfreq profile - * @governor method how to choose frequency based on the usage. - * @nb notifier block used to notify devfreq object that it should + * @profile: device-specific devfreq profile + * @governor: method how to choose frequency based on the usage. + * @nb: notifier block used to notify devfreq object that it should * reevaluate operable frequencies. Devfreq users may use * devfreq.nb to the corresponding register notifier call chain. - * @work delayed work for load monitoring. - * @previous_freq previously configured frequency value. - * @data Private data of the governor. The devfreq framework does not + * @work: delayed work for load monitoring. + * @previous_freq: previously configured frequency value. + * @data: Private data of the governor. The devfreq framework does not * touch this. - * @min_freq Limit minimum frequency requested by user (0: none) - * @max_freq Limit maximum frequency requested by user (0: none) - * @stop_polling devfreq polling status of a device. + * @min_freq: Limit minimum frequency requested by user (0: none) + * @max_freq: Limit maximum frequency requested by user (0: none) + * @stop_polling: devfreq polling status of a device. * * This structure stores the devfreq information for a give device. * @@ -186,9 +186,9 @@ extern const struct devfreq_governor devfreq_simple_ondemand; /** * struct devfreq_simple_ondemand_data - void *data fed to struct devfreq * and devfreq_add_device - * @ upthreshold If the load is over this value, the frequency jumps. + * @upthreshold: If the load is over this value, the frequency jumps. * Specify 0 to use the default. Valid value = 0 to 100. - * @ downdifferential If the load is under upthreshold - downdifferential, + * @downdifferential: If the load is under upthreshold - downdifferential, * the governor may consider slowing the frequency down. * Specify 0 to use the default. Valid value = 0 to 100. * downdifferential < upthreshold must hold. -- cgit v1.2.3 From d287de855f97c56ca7146ff627e652bd7cd64f3f Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 25 Oct 2012 19:48:59 -0500 Subject: PM / devfreq: Add sysfs node to expose available frequencies devfreq governors such as ondemand are controlled by a min and max frequency, while governors like userspace governor allow us to set a specific frequency. However, for the same specific device, depending on the SoC, the available frequencies can vary. So expose the available frequencies as a snapshot over sysfs to allow informed decisions. This was inspired by cpufreq framework's equivalent for similar usage sysfs node: scaling_available_frequencies. Cc: Rajagopal Venkat Cc: MyungJoo Ham Cc: Kyungmin Park Cc: "Rafael J. Wysocki" Cc: Kevin Hilman Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nishanth Menon Signed-off-by: MyungJoo Ham --- Documentation/ABI/testing/sysfs-class-devfreq | 9 ++++++++ drivers/devfreq/devfreq.c | 32 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index e6cf08e6734..e672ccb02e7 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -51,3 +51,12 @@ Description: The /sys/class/devfreq/.../userspace/set_freq shows and sets the requested frequency for the devfreq object if userspace governor is in effect. + +What: /sys/class/devfreq/.../available_frequencies +Date: October 2012 +Contact: Nishanth Menon +Description: + The /sys/class/devfreq/.../available_frequencies shows + the available frequencies of the corresponding devfreq object. + This is a snapshot of available frequencies and not limited + by the min/max frequency restrictions. diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 789af4ff5c9..c44e562bdfe 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -570,9 +570,41 @@ static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq); } +static ssize_t show_available_freqs(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct devfreq *df = to_devfreq(d); + struct device *dev = df->dev.parent; + struct opp *opp; + ssize_t count = 0; + unsigned long freq = 0; + + rcu_read_lock(); + do { + opp = opp_find_freq_ceil(dev, &freq); + if (IS_ERR(opp)) + break; + + count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), + "%lu ", freq); + freq++; + } while (1); + rcu_read_unlock(); + + /* Truncate the trailing space */ + if (count) + count--; + + count += sprintf(&buf[count], "\n"); + + return count; +} + static struct device_attribute devfreq_attrs[] = { __ATTR(governor, S_IRUGO, show_governor, NULL), __ATTR(cur_freq, S_IRUGO, show_freq, NULL), + __ATTR(available_frequencies, S_IRUGO, show_available_freqs, NULL), __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, store_polling_interval), -- cgit v1.2.3 From e552bbaf5b987f57c43e6981a452b8a3c700b1ae Mon Sep 17 00:00:00 2001 From: Jonghwa Lee Date: Thu, 23 Aug 2012 20:00:46 +0900 Subject: PM / devfreq: Add sysfs node for representing frequency transition information. This patch adds sysfs node which can be used to get information of frequency transition. It represents transition table which contains total number of transition of each freqeuncy state and time spent. It is inspired CPUFREQ's status driver. Signed-off-by: Jonghwa Lee [Added Documentation/ABI entry, updated kernel-doc, and resolved merge conflict] Signed-off-by: MyungJoo Ham --- Documentation/ABI/testing/sysfs-class-devfreq | 11 +++ drivers/devfreq/devfreq.c | 101 ++++++++++++++++++++++++++ include/linux/devfreq.h | 15 ++++ 3 files changed, 127 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index e672ccb02e7..40f98a9428d 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -44,6 +44,17 @@ Description: (/sys/class/devfreq/.../central_polling is 0), this value may be useless. +What: /sys/class/devfreq/.../trans_stat +Date: October 2012 +Contact: MyungJoo Ham +Descrtiption: + This ABI shows the statistics of devfreq behavior on a + specific device. It shows the time spent in each state and + the number of transitions between states. + In order to activate this ABI, the devfreq target device + driver should provide the list of available frequencies + with its profile. + What: /sys/class/devfreq/.../userspace/set_freq Date: September 2011 Contact: MyungJoo Ham diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index c44e562bdfe..bf6de38190c 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -66,6 +66,51 @@ static struct devfreq *find_device_devfreq(struct device *dev) return ERR_PTR(-ENODEV); } +/** + * devfreq_get_freq_level() - Lookup freq_table for the frequency + * @devfreq: the devfreq instance + * @freq: the target frequency + */ +static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq) +{ + int lev; + + for (lev = 0; lev < devfreq->profile->max_state; lev++) + if (freq == devfreq->profile->freq_table[lev]) + return lev; + + return -EINVAL; +} + +/** + * devfreq_update_status() - Update statistics of devfreq behavior + * @devfreq: the devfreq instance + * @freq: the update target frequency + */ +static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) +{ + int lev, prev_lev; + unsigned long cur_time; + + lev = devfreq_get_freq_level(devfreq, freq); + if (lev < 0) + return lev; + + cur_time = jiffies; + devfreq->time_in_state[lev] += + cur_time - devfreq->last_stat_updated; + if (freq != devfreq->previous_freq) { + prev_lev = devfreq_get_freq_level(devfreq, + devfreq->previous_freq); + devfreq->trans_table[(prev_lev * + devfreq->profile->max_state) + lev]++; + devfreq->total_trans++; + } + devfreq->last_stat_updated = cur_time; + + return 0; +} + /* Load monitoring helper functions for governors use */ /** @@ -112,6 +157,11 @@ int update_devfreq(struct devfreq *devfreq) if (err) return err; + if (devfreq->profile->freq_table) + if (devfreq_update_status(devfreq, freq)) + dev_err(&devfreq->dev, + "Couldn't update frequency transition information.\n"); + devfreq->previous_freq = freq; return err; } @@ -378,6 +428,15 @@ struct devfreq *devfreq_add_device(struct device *dev, devfreq->data = data; devfreq->nb.notifier_call = devfreq_notifier_call; + devfreq->trans_table = devm_kzalloc(dev, sizeof(unsigned int) * + devfreq->profile->max_state * + devfreq->profile->max_state, + GFP_KERNEL); + devfreq->time_in_state = devm_kzalloc(dev, sizeof(unsigned int) * + devfreq->profile->max_state, + GFP_KERNEL); + devfreq->last_stat_updated = jiffies; + dev_set_name(&devfreq->dev, dev_name(dev)); err = device_register(&devfreq->dev); if (err) { @@ -601,6 +660,47 @@ static ssize_t show_available_freqs(struct device *d, return count; } +static ssize_t show_trans_table(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct devfreq *devfreq = to_devfreq(dev); + ssize_t len; + int i, j, err; + unsigned int max_state = devfreq->profile->max_state; + + err = devfreq_update_status(devfreq, devfreq->previous_freq); + if (err) + return 0; + + len = sprintf(buf, " From : To\n"); + len += sprintf(buf + len, " :"); + for (i = 0; i < max_state; i++) + len += sprintf(buf + len, "%8u", + devfreq->profile->freq_table[i]); + + len += sprintf(buf + len, " time(ms)\n"); + + for (i = 0; i < max_state; i++) { + if (devfreq->profile->freq_table[i] + == devfreq->previous_freq) { + len += sprintf(buf + len, "*"); + } else { + len += sprintf(buf + len, " "); + } + len += sprintf(buf + len, "%8u:", + devfreq->profile->freq_table[i]); + for (j = 0; j < max_state; j++) + len += sprintf(buf + len, "%8u", + devfreq->trans_table[(i * max_state) + j]); + len += sprintf(buf + len, "%10u\n", + jiffies_to_msecs(devfreq->time_in_state[i])); + } + + len += sprintf(buf + len, "Total transition : %u\n", + devfreq->total_trans); + return len; +} + static struct device_attribute devfreq_attrs[] = { __ATTR(governor, S_IRUGO, show_governor, NULL), __ATTR(cur_freq, S_IRUGO, show_freq, NULL), @@ -610,6 +710,7 @@ static struct device_attribute devfreq_attrs[] = { store_polling_interval), __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq), __ATTR(max_freq, S_IRUGO | S_IWUSR, show_max_freq, store_max_freq), + __ATTR(trans_stat, S_IRUGO, show_trans_table, NULL), { }, }; diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 1461fb2355a..bc35c4aee6a 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -73,6 +73,8 @@ struct devfreq_dev_status { * from devfreq_remove_device() call. If the user * has registered devfreq->nb at a notifier-head, * this is the time to unregister it. + * @freq_table: Optional list of frequencies to support statistics. + * @max_state: The size of freq_table. */ struct devfreq_dev_profile { unsigned long initial_freq; @@ -83,6 +85,9 @@ struct devfreq_dev_profile { struct devfreq_dev_status *stat); int (*get_cur_freq)(struct device *dev, unsigned long *freq); void (*exit)(struct device *dev); + + unsigned int *freq_table; + unsigned int max_state; }; /** @@ -127,6 +132,10 @@ struct devfreq_governor { * @min_freq: Limit minimum frequency requested by user (0: none) * @max_freq: Limit maximum frequency requested by user (0: none) * @stop_polling: devfreq polling status of a device. + * @total_trans: Number of devfreq transitions + * @trans_table: Statistics of devfreq transitions + * @time_in_state: Statistics of devfreq states + * @last_stat_updated: The last time stat updated * * This structure stores the devfreq information for a give device. * @@ -153,6 +162,12 @@ struct devfreq { unsigned long min_freq; unsigned long max_freq; bool stop_polling; + + /* information for device freqeuncy transition */ + unsigned int total_trans; + unsigned int *trans_table; + unsigned long *time_in_state; + unsigned long last_stat_updated; }; #if defined(CONFIG_PM_DEVFREQ) -- cgit v1.2.3 From 2df5021fa9738905e8b1ab92fa0cd685430f54da Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 29 Oct 2012 15:01:42 -0500 Subject: PM / devfreq: export update_devfreq Allow update_devfreq to be used by devfreq governor built as modules Cc: Rajagopal Venkat Cc: MyungJoo Ham Cc: Kyungmin Park Cc: "Rafael J. Wysocki" Cc: Kevin Hilman Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nishanth Menon Acked-by: MyungJoo Ham Signed-off-by: MyungJoo Ham --- drivers/devfreq/devfreq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index bf6de38190c..e0002c5cbad 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -165,6 +165,7 @@ int update_devfreq(struct devfreq *devfreq) devfreq->previous_freq = freq; return err; } +EXPORT_SYMBOL(update_devfreq); /** * devfreq_monitor() - Periodically poll devfreq objects. -- cgit v1.2.3 From 4ac6875eeb97a49bad7bc8d56b5ec935904fc6e7 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 19 Nov 2012 13:11:26 +1100 Subject: md/raid5: round discard alignment up to power of 2. blkdev_issue_discard currently assumes that the granularity is a power of 2. So in raid5, round the chosen number up to avoid embarrassment. Cc: Shaohua Li Signed-off-by: NeilBrown --- drivers/md/raid5.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index c5439dce029..baea94f0670 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -5529,6 +5529,10 @@ static int run(struct mddev *mddev) * discard data disk but write parity disk */ stripe = stripe * PAGE_SIZE; + /* Round up to power of 2, as discard handling + * currently assumes that */ + while ((stripe-1) & stripe) + stripe = (stripe | (stripe-1)) + 1; mddev->queue->limits.discard_alignment = stripe; mddev->queue->limits.discard_granularity = stripe; /* -- cgit v1.2.3 From 3aa173b8db200bb96354481acc0a5b9e123119fe Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 29 Oct 2012 15:01:43 -0500 Subject: PM / devfreq: provide hooks for governors to be registered Add devfreq_add_governor and devfreq_remove_governor which can be invoked by governors to register with devfreq. This sets up the stage to dynamically switch governors and allow governors to be dynamically loaded as well. Cc: Rajagopal Venkat Cc: MyungJoo Ham Cc: Kyungmin Park Cc: "Rafael J. Wysocki" Cc: Kevin Hilman Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nishanth Menon Acked-by: MyungJoo Ham --- drivers/devfreq/devfreq.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/devfreq/governor.h | 4 ++ include/linux/devfreq.h | 3 ++ 3 files changed, 98 insertions(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index e0002c5cbad..679ac424472 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -36,6 +36,8 @@ static struct class *devfreq_class; */ static struct workqueue_struct *devfreq_wq; +/* The list of all device-devfreq governors */ +static LIST_HEAD(devfreq_governor_list); /* The list of all device-devfreq */ static LIST_HEAD(devfreq_list); static DEFINE_MUTEX(devfreq_list_lock); @@ -111,6 +113,32 @@ static int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) return 0; } +/** + * find_devfreq_governor() - find devfreq governor from name + * @name: name of the governor + * + * Search the list of devfreq governors and return the matched + * governor's pointer. devfreq_list_lock should be held by the caller. + */ +static struct devfreq_governor *find_devfreq_governor(const char *name) +{ + struct devfreq_governor *tmp_governor; + + if (unlikely(IS_ERR_OR_NULL(name))) { + pr_err("DEVFREQ: %s: Invalid parameters\n", __func__); + return ERR_PTR(-EINVAL); + } + WARN(!mutex_is_locked(&devfreq_list_lock), + "devfreq_list_lock must be locked."); + + list_for_each_entry(tmp_governor, &devfreq_governor_list, node) { + if (!strncmp(tmp_governor->name, name, DEVFREQ_NAME_LEN)) + return tmp_governor; + } + + return ERR_PTR(-ENODEV); +} + /* Load monitoring helper functions for governors use */ /** @@ -515,6 +543,69 @@ int devfreq_resume_device(struct devfreq *devfreq) } EXPORT_SYMBOL(devfreq_resume_device); +/** + * devfreq_add_governor() - Add devfreq governor + * @governor: the devfreq governor to be added + */ +int devfreq_add_governor(struct devfreq_governor *governor) +{ + struct devfreq_governor *g; + int err = 0; + + if (!governor) { + pr_err("%s: Invalid parameters.\n", __func__); + return -EINVAL; + } + + mutex_lock(&devfreq_list_lock); + g = find_devfreq_governor(governor->name); + if (!IS_ERR(g)) { + pr_err("%s: governor %s already registered\n", __func__, + g->name); + err = -EINVAL; + goto err_out; + } + + list_add(&governor->node, &devfreq_governor_list); + +err_out: + mutex_unlock(&devfreq_list_lock); + + return err; +} +EXPORT_SYMBOL(devfreq_add_governor); + +/** + * devfreq_remove_device() - Remove devfreq feature from a device. + * @governor: the devfreq governor to be removed + */ +int devfreq_remove_governor(struct devfreq_governor *governor) +{ + struct devfreq_governor *g; + int err = 0; + + if (!governor) { + pr_err("%s: Invalid parameters.\n", __func__); + return -EINVAL; + } + + mutex_lock(&devfreq_list_lock); + g = find_devfreq_governor(governor->name); + if (IS_ERR(g)) { + pr_err("%s: governor %s not registered\n", __func__, + g->name); + err = -EINVAL; + goto err_out; + } + + list_del(&governor->node); +err_out: + mutex_unlock(&devfreq_list_lock); + + return err; +} +EXPORT_SYMBOL(devfreq_remove_governor); + static ssize_t show_governor(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/devfreq/governor.h b/drivers/devfreq/governor.h index 26432ac0a39..fad7d632197 100644 --- a/drivers/devfreq/governor.h +++ b/drivers/devfreq/governor.h @@ -34,4 +34,8 @@ extern void devfreq_monitor_suspend(struct devfreq *devfreq); extern void devfreq_monitor_resume(struct devfreq *devfreq); extern void devfreq_interval_update(struct devfreq *devfreq, unsigned int *delay); + +extern int devfreq_add_governor(struct devfreq_governor *governor); +extern int devfreq_remove_governor(struct devfreq_governor *governor); + #endif /* _GOVERNOR_H */ diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index bc35c4aee6a..6484a3f8dda 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -92,6 +92,7 @@ struct devfreq_dev_profile { /** * struct devfreq_governor - Devfreq policy governor + * @node: list node - contains registered devfreq governors * @name: Governor's name * @get_target_freq: Returns desired operating frequency for the device. * Basically, get_target_freq will run @@ -107,6 +108,8 @@ struct devfreq_dev_profile { * Note that the callbacks are called with devfreq->lock locked by devfreq. */ struct devfreq_governor { + struct list_head node; + const char name[DEVFREQ_NAME_LEN]; int (*get_target_freq)(struct devfreq *this, unsigned long *freq); int (*event_handler)(struct devfreq *devfreq, -- cgit v1.2.3 From 83116e66a232184f733ecf09a41817cf893ede98 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 29 Oct 2012 15:01:44 -0500 Subject: PM / devfreq: register governors with devfreq framework With the new registration functions, governors can be now registered with devfreq framework. NOTE: generates 'discards qualifiers from pointer target type' build warnings, which the next patche in this series fixes Cc: Rajagopal Venkat Cc: MyungJoo Ham Cc: Kyungmin Park Cc: "Rafael J. Wysocki" Cc: Kevin Hilman Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nishanth Menon Acked-by: MyungJoo Ham Signed-off-by: MyungJoo Ham --- drivers/devfreq/governor_performance.c | 18 ++++++++++++++++++ drivers/devfreq/governor_powersave.c | 18 ++++++++++++++++++ drivers/devfreq/governor_simpleondemand.c | 18 ++++++++++++++++++ drivers/devfreq/governor_userspace.c | 18 ++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c index eea3f9bd789..db8ff77dbed 100644 --- a/drivers/devfreq/governor_performance.c +++ b/drivers/devfreq/governor_performance.c @@ -45,3 +45,21 @@ const struct devfreq_governor devfreq_performance = { .get_target_freq = devfreq_performance_func, .event_handler = devfreq_performance_handler, }; + +static int __init devfreq_performance_init(void) +{ + return devfreq_add_governor(&devfreq_performance); +} +subsys_initcall(devfreq_performance_init); + +static void __exit devfreq_performance_exit(void) +{ + int ret; + + ret = devfreq_remove_governor(&devfreq_performance); + if (ret) + pr_err("%s: failed remove governor %d\n", __func__, ret); + + return; +} +module_exit(devfreq_performance_exit); diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c index 2868d98ed3e..30f0fca8d63 100644 --- a/drivers/devfreq/governor_powersave.c +++ b/drivers/devfreq/governor_powersave.c @@ -42,3 +42,21 @@ const struct devfreq_governor devfreq_powersave = { .get_target_freq = devfreq_powersave_func, .event_handler = devfreq_powersave_handler, }; + +static int __init devfreq_powersave_init(void) +{ + return devfreq_add_governor(&devfreq_powersave); +} +subsys_initcall(devfreq_powersave_init); + +static void __exit devfreq_powersave_exit(void) +{ + int ret; + + ret = devfreq_remove_governor(&devfreq_powersave); + if (ret) + pr_err("%s: failed remove governor %d\n", __func__, ret); + + return; +} +module_exit(devfreq_powersave_exit); diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index b5cf0fb24ef..85f9ed531b1 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -125,3 +125,21 @@ const struct devfreq_governor devfreq_simple_ondemand = { .get_target_freq = devfreq_simple_ondemand_func, .event_handler = devfreq_simple_ondemand_handler, }; + +static int __init devfreq_simple_ondemand_init(void) +{ + return devfreq_add_governor(&devfreq_simple_ondemand); +} +subsys_initcall(devfreq_simple_ondemand_init); + +static void __exit devfreq_simple_ondemand_exit(void) +{ + int ret; + + ret = devfreq_remove_governor(&devfreq_simple_ondemand); + if (ret) + pr_err("%s: failed remove governor %d\n", __func__, ret); + + return; +} +module_exit(devfreq_simple_ondemand_exit); diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c index 7067555bd44..110f178fec0 100644 --- a/drivers/devfreq/governor_userspace.c +++ b/drivers/devfreq/governor_userspace.c @@ -140,3 +140,21 @@ const struct devfreq_governor devfreq_userspace = { .get_target_freq = devfreq_userspace_func, .event_handler = devfreq_userspace_handler, }; + +static int __init devfreq_userspace_init(void) +{ + return devfreq_add_governor(&devfreq_userspace); +} +subsys_initcall(devfreq_userspace_init); + +static void __exit devfreq_userspace_exit(void) +{ + int ret; + + ret = devfreq_remove_governor(&devfreq_userspace); + if (ret) + pr_err("%s: failed remove governor %d\n", __func__, ret); + + return; +} +module_exit(devfreq_userspace_exit); -- cgit v1.2.3 From 1b5c1be2c88e8445a20fa1929e26c37e7ca8c926 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 29 Oct 2012 15:01:45 -0500 Subject: PM / devfreq: map devfreq drivers to governor using name Allow devfreq drivers to register a preferred governor name and when the devfreq governor loads itself at a later point required drivers are managed appropriately, at the time of unload of a devfreq governor, stop managing those drivers as well. Since the governor structures do not need to be exposed anymore, remove the definitions and make them static NOTE: devfreq_list_lock is now used to protect governor start and stop - as this allows us to protect governors and devfreq with the proper dependencies as needed. As part of this change, change the registration of exynos bus driver to request for ondemand using the governor name. Cc: Rajagopal Venkat Cc: MyungJoo Ham Cc: Kyungmin Park Cc: "Rafael J. Wysocki" Cc: Kevin Hilman Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nishanth Menon [Merge conflict resolved by MyungJoo Ham] Signed-off-by: MyungJoo Ham --- drivers/devfreq/devfreq.c | 95 ++++++++++++++++++++++++++++--- drivers/devfreq/exynos4_bus.c | 2 +- drivers/devfreq/governor_performance.c | 2 +- drivers/devfreq/governor_powersave.c | 2 +- drivers/devfreq/governor_simpleondemand.c | 2 +- drivers/devfreq/governor_userspace.c | 2 +- include/linux/devfreq.h | 21 ++----- 7 files changed, 96 insertions(+), 30 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 679ac424472..0d7be03d561 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -159,6 +159,9 @@ int update_devfreq(struct devfreq *devfreq) return -EINVAL; } + if (!devfreq->governor) + return -EINVAL; + /* Reevaluate the proper frequency */ err = devfreq->governor->get_target_freq(devfreq, &freq); if (err) @@ -379,7 +382,9 @@ static void _remove_devfreq(struct devfreq *devfreq, bool skip) list_del(&devfreq->node); mutex_unlock(&devfreq_list_lock); - devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_STOP, NULL); + if (devfreq->governor) + devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_STOP, NULL); if (devfreq->profile->exit) devfreq->profile->exit(devfreq->dev.parent); @@ -412,19 +417,20 @@ static void devfreq_dev_release(struct device *dev) * devfreq_add_device() - Add devfreq feature to the device * @dev: the device to add devfreq feature. * @profile: device-specific profile to run devfreq. - * @governor: the policy to choose frequency. + * @governor_name: name of the policy to choose frequency. * @data: private data for the governor. The devfreq framework does not * touch this value. */ struct devfreq *devfreq_add_device(struct device *dev, struct devfreq_dev_profile *profile, - const struct devfreq_governor *governor, + const char *governor_name, void *data) { struct devfreq *devfreq; + struct devfreq_governor *governor; int err = 0; - if (!dev || !profile || !governor) { + if (!dev || !profile || !governor_name) { dev_err(dev, "%s: Invalid parameters.\n", __func__); return ERR_PTR(-EINVAL); } @@ -452,7 +458,7 @@ struct devfreq *devfreq_add_device(struct device *dev, devfreq->dev.class = devfreq_class; devfreq->dev.release = devfreq_dev_release; devfreq->profile = profile; - devfreq->governor = governor; + strncpy(devfreq->governor_name, governor_name, DEVFREQ_NAME_LEN); devfreq->previous_freq = profile->initial_freq; devfreq->data = data; devfreq->nb.notifier_call = devfreq_notifier_call; @@ -478,10 +484,14 @@ struct devfreq *devfreq_add_device(struct device *dev, mutex_lock(&devfreq_list_lock); list_add(&devfreq->node, &devfreq_list); - mutex_unlock(&devfreq_list_lock); - err = devfreq->governor->event_handler(devfreq, - DEVFREQ_GOV_START, NULL); + governor = find_devfreq_governor(devfreq->governor_name); + if (!IS_ERR(governor)) + devfreq->governor = governor; + if (devfreq->governor) + err = devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_START, NULL); + mutex_unlock(&devfreq_list_lock); if (err) { dev_err(dev, "%s: Unable to start governor for the device\n", __func__); @@ -524,6 +534,9 @@ int devfreq_suspend_device(struct devfreq *devfreq) if (!devfreq) return -EINVAL; + if (!devfreq->governor) + return 0; + return devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_SUSPEND, NULL); } @@ -538,6 +551,9 @@ int devfreq_resume_device(struct devfreq *devfreq) if (!devfreq) return -EINVAL; + if (!devfreq->governor) + return 0; + return devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_RESUME, NULL); } @@ -550,6 +566,7 @@ EXPORT_SYMBOL(devfreq_resume_device); int devfreq_add_governor(struct devfreq_governor *governor) { struct devfreq_governor *g; + struct devfreq *devfreq; int err = 0; if (!governor) { @@ -568,6 +585,38 @@ int devfreq_add_governor(struct devfreq_governor *governor) list_add(&governor->node, &devfreq_governor_list); + list_for_each_entry(devfreq, &devfreq_list, node) { + int ret = 0; + struct device *dev = devfreq->dev.parent; + + if (!strncmp(devfreq->governor_name, governor->name, + DEVFREQ_NAME_LEN)) { + /* The following should never occur */ + if (devfreq->governor) { + dev_warn(dev, + "%s: Governor %s already present\n", + __func__, devfreq->governor->name); + ret = devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_STOP, NULL); + if (ret) { + dev_warn(dev, + "%s: Governor %s stop = %d\n", + __func__, + devfreq->governor->name, ret); + } + /* Fall through */ + } + devfreq->governor = governor; + ret = devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_START, NULL); + if (ret) { + dev_warn(dev, "%s: Governor %s start=%d\n", + __func__, devfreq->governor->name, + ret); + } + } + } + err_out: mutex_unlock(&devfreq_list_lock); @@ -582,6 +631,7 @@ EXPORT_SYMBOL(devfreq_add_governor); int devfreq_remove_governor(struct devfreq_governor *governor) { struct devfreq_governor *g; + struct devfreq *devfreq; int err = 0; if (!governor) { @@ -597,6 +647,29 @@ int devfreq_remove_governor(struct devfreq_governor *governor) err = -EINVAL; goto err_out; } + list_for_each_entry(devfreq, &devfreq_list, node) { + int ret; + struct device *dev = devfreq->dev.parent; + + if (!strncmp(devfreq->governor_name, governor->name, + DEVFREQ_NAME_LEN)) { + /* we should have a devfreq governor! */ + if (!devfreq->governor) { + dev_warn(dev, "%s: Governor %s NOT present\n", + __func__, governor->name); + continue; + /* Fall through */ + } + ret = devfreq->governor->event_handler(devfreq, + DEVFREQ_GOV_STOP, NULL); + if (ret) { + dev_warn(dev, "%s: Governor %s stop=%d\n", + __func__, devfreq->governor->name, + ret); + } + devfreq->governor = NULL; + } + } list_del(&governor->node); err_out: @@ -609,6 +682,9 @@ EXPORT_SYMBOL(devfreq_remove_governor); static ssize_t show_governor(struct device *dev, struct device_attribute *attr, char *buf) { + if (!to_devfreq(dev)->governor) + return -EINVAL; + return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name); } @@ -645,6 +721,9 @@ static ssize_t store_polling_interval(struct device *dev, unsigned int value; int ret; + if (!df->governor) + return -EINVAL; + ret = sscanf(buf, "%u", &value); if (ret != 1) return -EINVAL; diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c index 68145316c49..b8ac28497b3 100644 --- a/drivers/devfreq/exynos4_bus.c +++ b/drivers/devfreq/exynos4_bus.c @@ -1040,7 +1040,7 @@ static __devinit int exynos4_busfreq_probe(struct platform_device *pdev) busfreq_mon_reset(data); data->devfreq = devfreq_add_device(dev, &exynos4_devfreq_profile, - &devfreq_simple_ondemand, NULL); + "simple_ondemand", NULL); if (IS_ERR(data->devfreq)) return PTR_ERR(data->devfreq); diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c index db8ff77dbed..865a3695691 100644 --- a/drivers/devfreq/governor_performance.c +++ b/drivers/devfreq/governor_performance.c @@ -40,7 +40,7 @@ static int devfreq_performance_handler(struct devfreq *devfreq, return ret; } -const struct devfreq_governor devfreq_performance = { +static struct devfreq_governor devfreq_performance = { .name = "performance", .get_target_freq = devfreq_performance_func, .event_handler = devfreq_performance_handler, diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c index 30f0fca8d63..8612c0f96b7 100644 --- a/drivers/devfreq/governor_powersave.c +++ b/drivers/devfreq/governor_powersave.c @@ -37,7 +37,7 @@ static int devfreq_powersave_handler(struct devfreq *devfreq, return ret; } -const struct devfreq_governor devfreq_powersave = { +static struct devfreq_governor devfreq_powersave = { .name = "powersave", .get_target_freq = devfreq_powersave_func, .event_handler = devfreq_powersave_handler, diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index 85f9ed531b1..a870a24bb56 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -120,7 +120,7 @@ static int devfreq_simple_ondemand_handler(struct devfreq *devfreq, return 0; } -const struct devfreq_governor devfreq_simple_ondemand = { +static struct devfreq_governor devfreq_simple_ondemand = { .name = "simple_ondemand", .get_target_freq = devfreq_simple_ondemand_func, .event_handler = devfreq_simple_ondemand_handler, diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c index 110f178fec0..34fb80f50cf 100644 --- a/drivers/devfreq/governor_userspace.c +++ b/drivers/devfreq/governor_userspace.c @@ -135,7 +135,7 @@ static int devfreq_userspace_handler(struct devfreq *devfreq, return ret; } -const struct devfreq_governor devfreq_userspace = { +static struct devfreq_governor devfreq_userspace = { .name = "userspace", .get_target_freq = devfreq_userspace_func, .event_handler = devfreq_userspace_handler, diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 6484a3f8dda..235248cb2c9 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -125,6 +125,7 @@ struct devfreq_governor { * using devfreq. * @profile: device-specific devfreq profile * @governor: method how to choose frequency based on the usage. + * @governor_name: devfreq governor name for use with this devfreq * @nb: notifier block used to notify devfreq object that it should * reevaluate operable frequencies. Devfreq users may use * devfreq.nb to the corresponding register notifier call chain. @@ -155,6 +156,7 @@ struct devfreq { struct device dev; struct devfreq_dev_profile *profile; const struct devfreq_governor *governor; + char governor_name[DEVFREQ_NAME_LEN]; struct notifier_block nb; struct delayed_work work; @@ -176,7 +178,7 @@ struct devfreq { #if defined(CONFIG_PM_DEVFREQ) extern struct devfreq *devfreq_add_device(struct device *dev, struct devfreq_dev_profile *profile, - const struct devfreq_governor *governor, + const char *governor_name, void *data); extern int devfreq_remove_device(struct devfreq *devfreq); extern int devfreq_suspend_device(struct devfreq *devfreq); @@ -190,17 +192,7 @@ extern int devfreq_register_opp_notifier(struct device *dev, extern int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq); -#ifdef CONFIG_DEVFREQ_GOV_POWERSAVE -extern const struct devfreq_governor devfreq_powersave; -#endif -#ifdef CONFIG_DEVFREQ_GOV_PERFORMANCE -extern const struct devfreq_governor devfreq_performance; -#endif -#ifdef CONFIG_DEVFREQ_GOV_USERSPACE -extern const struct devfreq_governor devfreq_userspace; -#endif #ifdef CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND -extern const struct devfreq_governor devfreq_simple_ondemand; /** * struct devfreq_simple_ondemand_data - void *data fed to struct devfreq * and devfreq_add_device @@ -223,7 +215,7 @@ struct devfreq_simple_ondemand_data { #else /* !CONFIG_PM_DEVFREQ */ static struct devfreq *devfreq_add_device(struct device *dev, struct devfreq_dev_profile *profile, - struct devfreq_governor *governor, + const char *governor_name, void *data) { return NULL; @@ -262,11 +254,6 @@ static int devfreq_unregister_opp_notifier(struct device *dev, return -EINVAL; } -#define devfreq_powersave NULL -#define devfreq_performance NULL -#define devfreq_userspace NULL -#define devfreq_simple_ondemand NULL - #endif /* CONFIG_PM_DEVFREQ */ #endif /* __LINUX_DEVFREQ_H__ */ -- cgit v1.2.3 From eff607fdb1f787da1fedf46ab6e64adc2afd1c5a Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 29 Oct 2012 15:01:46 -0500 Subject: PM / devfreq: governors: add GPL module license and allow module build Add GPL module license and remove the static build restrictions for building governors. This allows governors now to be loaded on a need basis and reloaded independently of kernel build Cc: Rajagopal Venkat Cc: MyungJoo Ham Cc: Kyungmin Park Cc: "Rafael J. Wysocki" Cc: Kevin Hilman Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nishanth Menon Acked-by: MyungJoo Ham Signed-off-by: MyungJoo Ham --- drivers/devfreq/Kconfig | 8 ++++---- drivers/devfreq/governor_performance.c | 2 ++ drivers/devfreq/governor_powersave.c | 2 ++ drivers/devfreq/governor_simpleondemand.c | 2 ++ drivers/devfreq/governor_userspace.c | 2 ++ 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index f6b0a6e2ea5..0f079be1330 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -30,7 +30,7 @@ if PM_DEVFREQ comment "DEVFREQ Governors" config DEVFREQ_GOV_SIMPLE_ONDEMAND - bool "Simple Ondemand" + tristate "Simple Ondemand" help Chooses frequency based on the recent load on the device. Works similar as ONDEMAND governor of CPUFREQ does. A device with @@ -39,7 +39,7 @@ config DEVFREQ_GOV_SIMPLE_ONDEMAND values to the governor with data field at devfreq_add_device(). config DEVFREQ_GOV_PERFORMANCE - bool "Performance" + tristate "Performance" help Sets the frequency at the maximum available frequency. This governor always returns UINT_MAX as frequency so that @@ -47,7 +47,7 @@ config DEVFREQ_GOV_PERFORMANCE at any time. config DEVFREQ_GOV_POWERSAVE - bool "Powersave" + tristate "Powersave" help Sets the frequency at the minimum available frequency. This governor always returns 0 as frequency so that @@ -55,7 +55,7 @@ config DEVFREQ_GOV_POWERSAVE at any time. config DEVFREQ_GOV_USERSPACE - bool "Userspace" + tristate "Userspace" help Sets the frequency at the user specified one. This governor returns the user configured frequency if there diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c index 865a3695691..c72f942f30a 100644 --- a/drivers/devfreq/governor_performance.c +++ b/drivers/devfreq/governor_performance.c @@ -10,6 +10,7 @@ */ #include +#include #include "governor.h" static int devfreq_performance_func(struct devfreq *df, @@ -63,3 +64,4 @@ static void __exit devfreq_performance_exit(void) return; } module_exit(devfreq_performance_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c index 8612c0f96b7..0c6bed567e6 100644 --- a/drivers/devfreq/governor_powersave.c +++ b/drivers/devfreq/governor_powersave.c @@ -10,6 +10,7 @@ */ #include +#include #include "governor.h" static int devfreq_powersave_func(struct devfreq *df, @@ -60,3 +61,4 @@ static void __exit devfreq_powersave_exit(void) return; } module_exit(devfreq_powersave_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index a870a24bb56..0720ba84ca9 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include "governor.h" @@ -143,3 +144,4 @@ static void __exit devfreq_simple_ondemand_exit(void) return; } module_exit(devfreq_simple_ondemand_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c index 34fb80f50cf..35de6e83c1f 100644 --- a/drivers/devfreq/governor_userspace.c +++ b/drivers/devfreq/governor_userspace.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "governor.h" struct userspace_data { @@ -158,3 +159,4 @@ static void __exit devfreq_userspace_exit(void) return; } module_exit(devfreq_userspace_exit); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 0359d1afe4013d1a216908b6be4c6695a1db6fd6 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 29 Oct 2012 15:01:47 -0500 Subject: PM / devfreq: allow sysfs governor node to switch governor This allows us to select governor runtime from the default configuration without having to rebuild kernel or the devfreq driver using the sysfs node: /sys/class/devfreq/.../governor cat of the governor will return valid governor and an echo 'governor_name'>governor will switch governor Cc: Rajagopal Venkat Cc: MyungJoo Ham Cc: Kyungmin Park Cc: "Rafael J. Wysocki" Cc: Kevin Hilman Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nishanth Menon Acked-by: MyungJoo Ham Signed-off-by: MyungJoo Ham --- Documentation/ABI/testing/sysfs-class-devfreq | 2 +- drivers/devfreq/devfreq.c | 45 ++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 40f98a9428d..66876debca1 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -11,7 +11,7 @@ What: /sys/class/devfreq/.../governor Date: September 2011 Contact: MyungJoo Ham Description: - The /sys/class/devfreq/.../governor shows the name of the + The /sys/class/devfreq/.../governor show or set the name of the governor used by the corresponding devfreq object. What: /sys/class/devfreq/.../cur_freq diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 0d7be03d561..ff960f084c1 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -688,6 +688,49 @@ static ssize_t show_governor(struct device *dev, return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name); } +static ssize_t store_governor(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct devfreq *df = to_devfreq(dev); + int ret; + char str_governor[DEVFREQ_NAME_LEN + 1]; + struct devfreq_governor *governor; + + ret = sscanf(buf, "%" __stringify(DEVFREQ_NAME_LEN) "s", str_governor); + if (ret != 1) + return -EINVAL; + + mutex_lock(&devfreq_list_lock); + governor = find_devfreq_governor(str_governor); + if (IS_ERR(governor)) { + ret = PTR_ERR(governor); + goto out; + } + if (df->governor == governor) + goto out; + + if (df->governor) { + ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL); + if (ret) { + dev_warn(dev, "%s: Governor %s not stopped(%d)\n", + __func__, df->governor->name, ret); + goto out; + } + } + df->governor = governor; + strncpy(df->governor_name, governor->name, DEVFREQ_NAME_LEN); + ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL); + if (ret) + dev_warn(dev, "%s: Governor %s not started(%d)\n", + __func__, df->governor->name, ret); +out: + mutex_unlock(&devfreq_list_lock); + + if (!ret) + ret = count; + return ret; +} + static ssize_t show_freq(struct device *dev, struct device_attribute *attr, char *buf) { @@ -873,7 +916,7 @@ static ssize_t show_trans_table(struct device *dev, struct device_attribute *att } static struct device_attribute devfreq_attrs[] = { - __ATTR(governor, S_IRUGO, show_governor, NULL), + __ATTR(governor, S_IRUGO | S_IWUSR, show_governor, store_governor), __ATTR(cur_freq, S_IRUGO, show_freq, NULL), __ATTR(available_frequencies, S_IRUGO, show_available_freqs, NULL), __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), -- cgit v1.2.3 From 50a5b33e0159f8783ef617cdb9d5fbb6a3955b6f Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 29 Oct 2012 15:01:48 -0500 Subject: PM / devfreq: Add sysfs node to expose available governors Now that governor list can be variable, knowing the available governors is useful to be able to select a governor using relevant sysfs node. Cc: Rajagopal Venkat Cc: MyungJoo Ham Cc: Kyungmin Park Cc: "Rafael J. Wysocki" Cc: Kevin Hilman Cc: linux-pm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nishanth Menon Signed-off-by: MyungJoo Ham --- Documentation/ABI/testing/sysfs-class-devfreq | 7 +++++++ drivers/devfreq/devfreq.c | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 66876debca1..0ba6ea2f89d 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -71,3 +71,10 @@ Description: the available frequencies of the corresponding devfreq object. This is a snapshot of available frequencies and not limited by the min/max frequency restrictions. + +What: /sys/class/devfreq/.../available_governors +Date: October 2012 +Contact: Nishanth Menon +Description: + The /sys/class/devfreq/.../available_governors shows + currently available governors in the system. diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index ff960f084c1..45e053e5b13 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -730,6 +730,27 @@ out: ret = count; return ret; } +static ssize_t show_available_governors(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct devfreq_governor *tmp_governor; + ssize_t count = 0; + + mutex_lock(&devfreq_list_lock); + list_for_each_entry(tmp_governor, &devfreq_governor_list, node) + count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), + "%s ", tmp_governor->name); + mutex_unlock(&devfreq_list_lock); + + /* Truncate the trailing space */ + if (count) + count--; + + count += sprintf(&buf[count], "\n"); + + return count; +} static ssize_t show_freq(struct device *dev, struct device_attribute *attr, char *buf) @@ -917,6 +938,7 @@ static ssize_t show_trans_table(struct device *dev, struct device_attribute *att static struct device_attribute devfreq_attrs[] = { __ATTR(governor, S_IRUGO | S_IWUSR, show_governor, store_governor), + __ATTR(available_governors, S_IRUGO, show_available_governors, NULL), __ATTR(cur_freq, S_IRUGO, show_freq, NULL), __ATTR(available_frequencies, S_IRUGO, show_available_freqs, NULL), __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), -- cgit v1.2.3 From dce9dc3a24f03b054dae02ef5cf1df7e97a8f558 Mon Sep 17 00:00:00 2001 From: Sangho Yi Date: Sat, 20 Oct 2012 01:16:34 +0900 Subject: PM / devfreq: exynos4_bus.c: Fixed an alignment of the func call args. I fixed the following check item (via checkpatch.pl --strict option): CHECK: Alignment should match open parenthesis Signed-off-by: Sangho Yi [Merge conflict resolved] Signed-off-by: MyungJoo Ham --- drivers/devfreq/exynos4_bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c index b8ac28497b3..74183720871 100644 --- a/drivers/devfreq/exynos4_bus.c +++ b/drivers/devfreq/exynos4_bus.c @@ -1030,7 +1030,7 @@ static __devinit int exynos4_busfreq_probe(struct platform_device *pdev) opp = opp_find_freq_floor(dev, &exynos4_devfreq_profile.initial_freq); if (IS_ERR(opp)) { dev_err(dev, "Invalid initial frequency %lu kHz.\n", - exynos4_devfreq_profile.initial_freq); + exynos4_devfreq_profile.initial_freq); return PTR_ERR(opp); } data->curr_opp = opp; -- cgit v1.2.3 From 78a3c5ab1749cb78eb06b581c3c13d8e027bef40 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 31 Oct 2012 15:54:37 +0100 Subject: mfd: twl-core: Fix chip ID for the twl6030-pwm module The correct chip id is 1 since the PWM module is on address 0x49. With the current TWL6030_MODULE_ID1 the kernel will crash early since we have: #define TWL6030_MODULE_ID1 0x0E and static struct twl_client twl_modules[4]; Down in the stack we try to get the module by: struct twl_client *twl = &twl_modules[chip]; Which is obviously going to do nasty things. Signed-off-by: Peter Ujfalusi Acked-by: Tero Kristo Signed-off-by: Samuel Ortiz --- drivers/mfd/twl-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 4ae64232020..a071a8643a4 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -671,7 +671,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base, } if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) { - child = add_child(TWL6030_MODULE_ID1, "twl6030-pwm", NULL, 0, + child = add_child(SUB_CHIP_ID1, "twl6030-pwm", NULL, 0, false, 0, 0); if (IS_ERR(child)) return PTR_ERR(child); -- cgit v1.2.3 From 91280e755a43fd2a6a20bfeab3a571321de68b76 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 20 Nov 2012 20:39:28 +0900 Subject: ARM: EXYNOS: PL330 MDMA1 fix for revision 0 of Exynos4210 SOC Commit 8214513 ("ARM: EXYNOS: fix address for EXYNOS4 MDMA1") changed EXYNOS specific setup of PL330 DMA engine to use 'non-secure' mdma1 address instead of 'secure' one (from 0x12840000 to 0x12850000) to fix issue with some Exynos4212 SOCs. Unfortunately it brakes PL330 setup for revision 0 of Exynos4210 SOC (mdma1 device cannot be found at 'non-secure' address): [ 0.566245] dma-pl330 dma-pl330.2: PERIPH_ID 0x0, PCELL_ID 0x0 ! [ 0.566278] dma-pl330: probe of dma-pl330.2 failed with error -22 Fix it by using 'secure' mdma1 address on Exynos4210 revision 0 SOC. Reviewed-by: Tomasz Figa Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Kyungmin Park Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/dma.c | 3 +++ arch/arm/mach-exynos/include/mach/map.h | 1 + 2 files changed, 4 insertions(+) diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c index 21d568b3b14..87e07d6fc61 100644 --- a/arch/arm/mach-exynos/dma.c +++ b/arch/arm/mach-exynos/dma.c @@ -275,6 +275,9 @@ static int __init exynos_dma_init(void) exynos_pdma1_pdata.nr_valid_peri = ARRAY_SIZE(exynos4210_pdma1_peri); exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri; + + if (samsung_rev() == EXYNOS4210_REV_0) + exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1; } else if (soc_is_exynos4212() || soc_is_exynos4412()) { exynos_pdma0_pdata.nr_valid_peri = ARRAY_SIZE(exynos4212_pdma0_peri); diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index 8480849affb..ed4da4544cd 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h @@ -90,6 +90,7 @@ #define EXYNOS4_PA_MDMA0 0x10810000 #define EXYNOS4_PA_MDMA1 0x12850000 +#define EXYNOS4_PA_S_MDMA1 0x12840000 #define EXYNOS4_PA_PDMA0 0x12680000 #define EXYNOS4_PA_PDMA1 0x12690000 #define EXYNOS5_PA_MDMA0 0x10800000 -- cgit v1.2.3 From d591ad8dcf32b8a71b63041d22a46dd8caf05041 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 20 Nov 2012 13:46:17 +0900 Subject: mfd: wm5102: Update register patch for latest evaluation Latest evaluation of the device has provided some revisions to the configuration. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/wm5102-tables.c | 519 +------------------------------------------- 1 file changed, 1 insertion(+), 518 deletions(-) diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c index 01b9255ed63..14490cc785d 100644 --- a/drivers/mfd/wm5102-tables.c +++ b/drivers/mfd/wm5102-tables.c @@ -43,6 +43,7 @@ static const struct reg_default wm5102_reva_patch[] = { { 0x479, 0x0A30 }, { 0x47B, 0x0810 }, { 0x47D, 0x0510 }, + { 0x4D1, 0x017F }, { 0x500, 0x000D }, { 0x507, 0x1820 }, { 0x508, 0x1820 }, @@ -52,524 +53,6 @@ static const struct reg_default wm5102_reva_patch[] = { { 0x580, 0x000D }, { 0x587, 0x1820 }, { 0x588, 0x1820 }, - { 0x101, 0x8140 }, - { 0x3000, 0x2225 }, - { 0x3001, 0x3a03 }, - { 0x3002, 0x0225 }, - { 0x3003, 0x0801 }, - { 0x3004, 0x6249 }, - { 0x3005, 0x0c04 }, - { 0x3006, 0x0225 }, - { 0x3007, 0x5901 }, - { 0x3008, 0xe249 }, - { 0x3009, 0x030d }, - { 0x300a, 0x0249 }, - { 0x300b, 0x2c01 }, - { 0x300c, 0xe249 }, - { 0x300d, 0x4342 }, - { 0x300e, 0xe249 }, - { 0x300f, 0x73c0 }, - { 0x3010, 0x4249 }, - { 0x3011, 0x0c00 }, - { 0x3012, 0x0225 }, - { 0x3013, 0x1f01 }, - { 0x3014, 0x0225 }, - { 0x3015, 0x1e01 }, - { 0x3016, 0x0225 }, - { 0x3017, 0xfa00 }, - { 0x3018, 0x0000 }, - { 0x3019, 0xf000 }, - { 0x301a, 0x0000 }, - { 0x301b, 0xf000 }, - { 0x301c, 0x0000 }, - { 0x301d, 0xf000 }, - { 0x301e, 0x0000 }, - { 0x301f, 0xf000 }, - { 0x3020, 0x0000 }, - { 0x3021, 0xf000 }, - { 0x3022, 0x0000 }, - { 0x3023, 0xf000 }, - { 0x3024, 0x0000 }, - { 0x3025, 0xf000 }, - { 0x3026, 0x0000 }, - { 0x3027, 0xf000 }, - { 0x3028, 0x0000 }, - { 0x3029, 0xf000 }, - { 0x302a, 0x0000 }, - { 0x302b, 0xf000 }, - { 0x302c, 0x0000 }, - { 0x302d, 0xf000 }, - { 0x302e, 0x0000 }, - { 0x302f, 0xf000 }, - { 0x3030, 0x0225 }, - { 0x3031, 0x1a01 }, - { 0x3032, 0x0225 }, - { 0x3033, 0x1e00 }, - { 0x3034, 0x0225 }, - { 0x3035, 0x1f00 }, - { 0x3036, 0x6225 }, - { 0x3037, 0xf800 }, - { 0x3038, 0x0000 }, - { 0x3039, 0xf000 }, - { 0x303a, 0x0000 }, - { 0x303b, 0xf000 }, - { 0x303c, 0x0000 }, - { 0x303d, 0xf000 }, - { 0x303e, 0x0000 }, - { 0x303f, 0xf000 }, - { 0x3040, 0x2226 }, - { 0x3041, 0x3a03 }, - { 0x3042, 0x0226 }, - { 0x3043, 0x0801 }, - { 0x3044, 0x6249 }, - { 0x3045, 0x0c06 }, - { 0x3046, 0x0226 }, - { 0x3047, 0x5901 }, - { 0x3048, 0xe249 }, - { 0x3049, 0x030d }, - { 0x304a, 0x0249 }, - { 0x304b, 0x2c01 }, - { 0x304c, 0xe249 }, - { 0x304d, 0x4342 }, - { 0x304e, 0xe249 }, - { 0x304f, 0x73c0 }, - { 0x3050, 0x4249 }, - { 0x3051, 0x0c00 }, - { 0x3052, 0x0226 }, - { 0x3053, 0x1f01 }, - { 0x3054, 0x0226 }, - { 0x3055, 0x1e01 }, - { 0x3056, 0x0226 }, - { 0x3057, 0xfa00 }, - { 0x3058, 0x0000 }, - { 0x3059, 0xf000 }, - { 0x305a, 0x0000 }, - { 0x305b, 0xf000 }, - { 0x305c, 0x0000 }, - { 0x305d, 0xf000 }, - { 0x305e, 0x0000 }, - { 0x305f, 0xf000 }, - { 0x3060, 0x0000 }, - { 0x3061, 0xf000 }, - { 0x3062, 0x0000 }, - { 0x3063, 0xf000 }, - { 0x3064, 0x0000 }, - { 0x3065, 0xf000 }, - { 0x3066, 0x0000 }, - { 0x3067, 0xf000 }, - { 0x3068, 0x0000 }, - { 0x3069, 0xf000 }, - { 0x306a, 0x0000 }, - { 0x306b, 0xf000 }, - { 0x306c, 0x0000 }, - { 0x306d, 0xf000 }, - { 0x306e, 0x0000 }, - { 0x306f, 0xf000 }, - { 0x3070, 0x0226 }, - { 0x3071, 0x1a01 }, - { 0x3072, 0x0226 }, - { 0x3073, 0x1e00 }, - { 0x3074, 0x0226 }, - { 0x3075, 0x1f00 }, - { 0x3076, 0x6226 }, - { 0x3077, 0xf800 }, - { 0x3078, 0x0000 }, - { 0x3079, 0xf000 }, - { 0x307a, 0x0000 }, - { 0x307b, 0xf000 }, - { 0x307c, 0x0000 }, - { 0x307d, 0xf000 }, - { 0x307e, 0x0000 }, - { 0x307f, 0xf000 }, - { 0x3080, 0x2227 }, - { 0x3081, 0x3a03 }, - { 0x3082, 0x0227 }, - { 0x3083, 0x0801 }, - { 0x3084, 0x6255 }, - { 0x3085, 0x0c04 }, - { 0x3086, 0x0227 }, - { 0x3087, 0x5901 }, - { 0x3088, 0xe255 }, - { 0x3089, 0x030d }, - { 0x308a, 0x0255 }, - { 0x308b, 0x2c01 }, - { 0x308c, 0xe255 }, - { 0x308d, 0x4342 }, - { 0x308e, 0xe255 }, - { 0x308f, 0x73c0 }, - { 0x3090, 0x4255 }, - { 0x3091, 0x0c00 }, - { 0x3092, 0x0227 }, - { 0x3093, 0x1f01 }, - { 0x3094, 0x0227 }, - { 0x3095, 0x1e01 }, - { 0x3096, 0x0227 }, - { 0x3097, 0xfa00 }, - { 0x3098, 0x0000 }, - { 0x3099, 0xf000 }, - { 0x309a, 0x0000 }, - { 0x309b, 0xf000 }, - { 0x309c, 0x0000 }, - { 0x309d, 0xf000 }, - { 0x309e, 0x0000 }, - { 0x309f, 0xf000 }, - { 0x30a0, 0x0000 }, - { 0x30a1, 0xf000 }, - { 0x30a2, 0x0000 }, - { 0x30a3, 0xf000 }, - { 0x30a4, 0x0000 }, - { 0x30a5, 0xf000 }, - { 0x30a6, 0x0000 }, - { 0x30a7, 0xf000 }, - { 0x30a8, 0x0000 }, - { 0x30a9, 0xf000 }, - { 0x30aa, 0x0000 }, - { 0x30ab, 0xf000 }, - { 0x30ac, 0x0000 }, - { 0x30ad, 0xf000 }, - { 0x30ae, 0x0000 }, - { 0x30af, 0xf000 }, - { 0x30b0, 0x0227 }, - { 0x30b1, 0x1a01 }, - { 0x30b2, 0x0227 }, - { 0x30b3, 0x1e00 }, - { 0x30b4, 0x0227 }, - { 0x30b5, 0x1f00 }, - { 0x30b6, 0x6227 }, - { 0x30b7, 0xf800 }, - { 0x30b8, 0x0000 }, - { 0x30b9, 0xf000 }, - { 0x30ba, 0x0000 }, - { 0x30bb, 0xf000 }, - { 0x30bc, 0x0000 }, - { 0x30bd, 0xf000 }, - { 0x30be, 0x0000 }, - { 0x30bf, 0xf000 }, - { 0x30c0, 0x2228 }, - { 0x30c1, 0x3a03 }, - { 0x30c2, 0x0228 }, - { 0x30c3, 0x0801 }, - { 0x30c4, 0x6255 }, - { 0x30c5, 0x0c06 }, - { 0x30c6, 0x0228 }, - { 0x30c7, 0x5901 }, - { 0x30c8, 0xe255 }, - { 0x30c9, 0x030d }, - { 0x30ca, 0x0255 }, - { 0x30cb, 0x2c01 }, - { 0x30cc, 0xe255 }, - { 0x30cd, 0x4342 }, - { 0x30ce, 0xe255 }, - { 0x30cf, 0x73c0 }, - { 0x30d0, 0x4255 }, - { 0x30d1, 0x0c00 }, - { 0x30d2, 0x0228 }, - { 0x30d3, 0x1f01 }, - { 0x30d4, 0x0228 }, - { 0x30d5, 0x1e01 }, - { 0x30d6, 0x0228 }, - { 0x30d7, 0xfa00 }, - { 0x30d8, 0x0000 }, - { 0x30d9, 0xf000 }, - { 0x30da, 0x0000 }, - { 0x30db, 0xf000 }, - { 0x30dc, 0x0000 }, - { 0x30dd, 0xf000 }, - { 0x30de, 0x0000 }, - { 0x30df, 0xf000 }, - { 0x30e0, 0x0000 }, - { 0x30e1, 0xf000 }, - { 0x30e2, 0x0000 }, - { 0x30e3, 0xf000 }, - { 0x30e4, 0x0000 }, - { 0x30e5, 0xf000 }, - { 0x30e6, 0x0000 }, - { 0x30e7, 0xf000 }, - { 0x30e8, 0x0000 }, - { 0x30e9, 0xf000 }, - { 0x30ea, 0x0000 }, - { 0x30eb, 0xf000 }, - { 0x30ec, 0x0000 }, - { 0x30ed, 0xf000 }, - { 0x30ee, 0x0000 }, - { 0x30ef, 0xf000 }, - { 0x30f0, 0x0228 }, - { 0x30f1, 0x1a01 }, - { 0x30f2, 0x0228 }, - { 0x30f3, 0x1e00 }, - { 0x30f4, 0x0228 }, - { 0x30f5, 0x1f00 }, - { 0x30f6, 0x6228 }, - { 0x30f7, 0xf800 }, - { 0x30f8, 0x0000 }, - { 0x30f9, 0xf000 }, - { 0x30fa, 0x0000 }, - { 0x30fb, 0xf000 }, - { 0x30fc, 0x0000 }, - { 0x30fd, 0xf000 }, - { 0x30fe, 0x0000 }, - { 0x30ff, 0xf000 }, - { 0x3100, 0x222b }, - { 0x3101, 0x3a03 }, - { 0x3102, 0x222b }, - { 0x3103, 0x5803 }, - { 0x3104, 0xe26f }, - { 0x3105, 0x030d }, - { 0x3106, 0x626f }, - { 0x3107, 0x2c01 }, - { 0x3108, 0xe26f }, - { 0x3109, 0x4342 }, - { 0x310a, 0xe26f }, - { 0x310b, 0x73c0 }, - { 0x310c, 0x026f }, - { 0x310d, 0x0c00 }, - { 0x310e, 0x022b }, - { 0x310f, 0x1f01 }, - { 0x3110, 0x022b }, - { 0x3111, 0x1e01 }, - { 0x3112, 0x022b }, - { 0x3113, 0xfa00 }, - { 0x3114, 0x0000 }, - { 0x3115, 0xf000 }, - { 0x3116, 0x0000 }, - { 0x3117, 0xf000 }, - { 0x3118, 0x0000 }, - { 0x3119, 0xf000 }, - { 0x311a, 0x0000 }, - { 0x311b, 0xf000 }, - { 0x311c, 0x0000 }, - { 0x311d, 0xf000 }, - { 0x311e, 0x0000 }, - { 0x311f, 0xf000 }, - { 0x3120, 0x022b }, - { 0x3121, 0x0a01 }, - { 0x3122, 0x022b }, - { 0x3123, 0x1e00 }, - { 0x3124, 0x022b }, - { 0x3125, 0x1f00 }, - { 0x3126, 0x622b }, - { 0x3127, 0xf800 }, - { 0x3128, 0x0000 }, - { 0x3129, 0xf000 }, - { 0x312a, 0x0000 }, - { 0x312b, 0xf000 }, - { 0x312c, 0x0000 }, - { 0x312d, 0xf000 }, - { 0x312e, 0x0000 }, - { 0x312f, 0xf000 }, - { 0x3130, 0x0000 }, - { 0x3131, 0xf000 }, - { 0x3132, 0x0000 }, - { 0x3133, 0xf000 }, - { 0x3134, 0x0000 }, - { 0x3135, 0xf000 }, - { 0x3136, 0x0000 }, - { 0x3137, 0xf000 }, - { 0x3138, 0x0000 }, - { 0x3139, 0xf000 }, - { 0x313a, 0x0000 }, - { 0x313b, 0xf000 }, - { 0x313c, 0x0000 }, - { 0x313d, 0xf000 }, - { 0x313e, 0x0000 }, - { 0x313f, 0xf000 }, - { 0x3140, 0x0000 }, - { 0x3141, 0xf000 }, - { 0x3142, 0x0000 }, - { 0x3143, 0xf000 }, - { 0x3144, 0x0000 }, - { 0x3145, 0xf000 }, - { 0x3146, 0x0000 }, - { 0x3147, 0xf000 }, - { 0x3148, 0x0000 }, - { 0x3149, 0xf000 }, - { 0x314a, 0x0000 }, - { 0x314b, 0xf000 }, - { 0x314c, 0x0000 }, - { 0x314d, 0xf000 }, - { 0x314e, 0x0000 }, - { 0x314f, 0xf000 }, - { 0x3150, 0x0000 }, - { 0x3151, 0xf000 }, - { 0x3152, 0x0000 }, - { 0x3153, 0xf000 }, - { 0x3154, 0x0000 }, - { 0x3155, 0xf000 }, - { 0x3156, 0x0000 }, - { 0x3157, 0xf000 }, - { 0x3158, 0x0000 }, - { 0x3159, 0xf000 }, - { 0x315a, 0x0000 }, - { 0x315b, 0xf000 }, - { 0x315c, 0x0000 }, - { 0x315d, 0xf000 }, - { 0x315e, 0x0000 }, - { 0x315f, 0xf000 }, - { 0x3160, 0x0000 }, - { 0x3161, 0xf000 }, - { 0x3162, 0x0000 }, - { 0x3163, 0xf000 }, - { 0x3164, 0x0000 }, - { 0x3165, 0xf000 }, - { 0x3166, 0x0000 }, - { 0x3167, 0xf000 }, - { 0x3168, 0x0000 }, - { 0x3169, 0xf000 }, - { 0x316a, 0x0000 }, - { 0x316b, 0xf000 }, - { 0x316c, 0x0000 }, - { 0x316d, 0xf000 }, - { 0x316e, 0x0000 }, - { 0x316f, 0xf000 }, - { 0x3170, 0x0000 }, - { 0x3171, 0xf000 }, - { 0x3172, 0x0000 }, - { 0x3173, 0xf000 }, - { 0x3174, 0x0000 }, - { 0x3175, 0xf000 }, - { 0x3176, 0x0000 }, - { 0x3177, 0xf000 }, - { 0x3178, 0x0000 }, - { 0x3179, 0xf000 }, - { 0x317a, 0x0000 }, - { 0x317b, 0xf000 }, - { 0x317c, 0x0000 }, - { 0x317d, 0xf000 }, - { 0x317e, 0x0000 }, - { 0x317f, 0xf000 }, - { 0x3180, 0x2001 }, - { 0x3181, 0xf101 }, - { 0x3182, 0x0000 }, - { 0x3183, 0xf000 }, - { 0x3184, 0x0000 }, - { 0x3185, 0xf000 }, - { 0x3186, 0x0000 }, - { 0x3187, 0xf000 }, - { 0x3188, 0x0000 }, - { 0x3189, 0xf000 }, - { 0x318a, 0x0000 }, - { 0x318b, 0xf000 }, - { 0x318c, 0x0000 }, - { 0x318d, 0xf000 }, - { 0x318e, 0x0000 }, - { 0x318f, 0xf000 }, - { 0x3190, 0x0000 }, - { 0x3191, 0xf000 }, - { 0x3192, 0x0000 }, - { 0x3193, 0xf000 }, - { 0x3194, 0x0000 }, - { 0x3195, 0xf000 }, - { 0x3196, 0x0000 }, - { 0x3197, 0xf000 }, - { 0x3198, 0x0000 }, - { 0x3199, 0xf000 }, - { 0x319a, 0x0000 }, - { 0x319b, 0xf000 }, - { 0x319c, 0x0000 }, - { 0x319d, 0xf000 }, - { 0x319e, 0x0000 }, - { 0x319f, 0xf000 }, - { 0x31a0, 0x0000 }, - { 0x31a1, 0xf000 }, - { 0x31a2, 0x0000 }, - { 0x31a3, 0xf000 }, - { 0x31a4, 0x0000 }, - { 0x31a5, 0xf000 }, - { 0x31a6, 0x0000 }, - { 0x31a7, 0xf000 }, - { 0x31a8, 0x0000 }, - { 0x31a9, 0xf000 }, - { 0x31aa, 0x0000 }, - { 0x31ab, 0xf000 }, - { 0x31ac, 0x0000 }, - { 0x31ad, 0xf000 }, - { 0x31ae, 0x0000 }, - { 0x31af, 0xf000 }, - { 0x31b0, 0x0000 }, - { 0x31b1, 0xf000 }, - { 0x31b2, 0x0000 }, - { 0x31b3, 0xf000 }, - { 0x31b4, 0x0000 }, - { 0x31b5, 0xf000 }, - { 0x31b6, 0x0000 }, - { 0x31b7, 0xf000 }, - { 0x31b8, 0x0000 }, - { 0x31b9, 0xf000 }, - { 0x31ba, 0x0000 }, - { 0x31bb, 0xf000 }, - { 0x31bc, 0x0000 }, - { 0x31bd, 0xf000 }, - { 0x31be, 0x0000 }, - { 0x31bf, 0xf000 }, - { 0x31c0, 0x0000 }, - { 0x31c1, 0xf000 }, - { 0x31c2, 0x0000 }, - { 0x31c3, 0xf000 }, - { 0x31c4, 0x0000 }, - { 0x31c5, 0xf000 }, - { 0x31c6, 0x0000 }, - { 0x31c7, 0xf000 }, - { 0x31c8, 0x0000 }, - { 0x31c9, 0xf000 }, - { 0x31ca, 0x0000 }, - { 0x31cb, 0xf000 }, - { 0x31cc, 0x0000 }, - { 0x31cd, 0xf000 }, - { 0x31ce, 0x0000 }, - { 0x31cf, 0xf000 }, - { 0x31d0, 0x0000 }, - { 0x31d1, 0xf000 }, - { 0x31d2, 0x0000 }, - { 0x31d3, 0xf000 }, - { 0x31d4, 0x0000 }, - { 0x31d5, 0xf000 }, - { 0x31d6, 0x0000 }, - { 0x31d7, 0xf000 }, - { 0x31d8, 0x0000 }, - { 0x31d9, 0xf000 }, - { 0x31da, 0x0000 }, - { 0x31db, 0xf000 }, - { 0x31dc, 0x0000 }, - { 0x31dd, 0xf000 }, - { 0x31de, 0x0000 }, - { 0x31df, 0xf000 }, - { 0x31e0, 0x0000 }, - { 0x31e1, 0xf000 }, - { 0x31e2, 0x0000 }, - { 0x31e3, 0xf000 }, - { 0x31e4, 0x0000 }, - { 0x31e5, 0xf000 }, - { 0x31e6, 0x0000 }, - { 0x31e7, 0xf000 }, - { 0x31e8, 0x0000 }, - { 0x31e9, 0xf000 }, - { 0x31ea, 0x0000 }, - { 0x31eb, 0xf000 }, - { 0x31ec, 0x0000 }, - { 0x31ed, 0xf000 }, - { 0x31ee, 0x0000 }, - { 0x31ef, 0xf000 }, - { 0x31f0, 0x0000 }, - { 0x31f1, 0xf000 }, - { 0x31f2, 0x0000 }, - { 0x31f3, 0xf000 }, - { 0x31f4, 0x0000 }, - { 0x31f5, 0xf000 }, - { 0x31f6, 0x0000 }, - { 0x31f7, 0xf000 }, - { 0x31f8, 0x0000 }, - { 0x31f9, 0xf000 }, - { 0x31fa, 0x0000 }, - { 0x31fb, 0xf000 }, - { 0x31fc, 0x0000 }, - { 0x31fd, 0xf000 }, - { 0x31fe, 0x0000 }, - { 0x31ff, 0xf000 }, - { 0x024d, 0xff50 }, - { 0x0252, 0xff50 }, - { 0x0259, 0x0112 }, - { 0x025e, 0x0112 }, - { 0x101, 0x0304 }, { 0x80, 0x0000 }, }; -- cgit v1.2.3 From 944b058258da8a40c13300f374dbfc2617a9190d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 20 Nov 2012 13:46:18 +0900 Subject: mfd: wm5110: Disable control interface error report for WM5110 rev B It can misreport. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/arizona-irq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index ef0f2d001df..b1b00917740 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c @@ -178,6 +178,7 @@ int arizona_irq_init(struct arizona *arizona) switch (arizona->rev) { case 0: + case 1: ctrlif_error = false; break; default: -- cgit v1.2.3 From 78566afd8647654b2fb11c3ae13b3d8fe96a8cfe Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 20 Nov 2012 13:46:19 +0900 Subject: mfd: arizona: Use correct array for ARRAY_SIZE in mfd_add_devices call wm5102_devs array was used for ARRAY_SIZE whilst adding the wm5110 devices. This change corrects this to get the size from the wm5110_devs array. As both arrays are the same size no issues should have been caused by this bug. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/arizona-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 1b48f209480..166254bba4c 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -520,7 +520,7 @@ int __devinit arizona_dev_init(struct arizona *arizona) break; case WM5110: ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, - ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); + ARRAY_SIZE(wm5110_devs), NULL, 0, NULL); break; } -- cgit v1.2.3 From 3ebef34d5cf658752d000001d2a6a5defe8cf3a9 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 20 Nov 2012 13:46:20 +0900 Subject: mfd: arizona: Correctly report when AIF2/AIF1 is underclocked In the interrupt handler for an underclocked event, whilst checking for the source of the interrupt, AIF3 was checked twice and AIF1 was not checked. This change correctly checks the AIF1 underclocked bit and reports the correct error messages for all cases. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/arizona-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 166254bba4c..202bf55c3cc 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -96,11 +96,11 @@ static irqreturn_t arizona_underclocked(int irq, void *data) return IRQ_NONE; } - if (val & ARIZONA_AIF3_UNDERCLOCKED_STS) - dev_err(arizona->dev, "AIF3 underclocked\n"); if (val & ARIZONA_AIF3_UNDERCLOCKED_STS) dev_err(arizona->dev, "AIF3 underclocked\n"); if (val & ARIZONA_AIF2_UNDERCLOCKED_STS) + dev_err(arizona->dev, "AIF2 underclocked\n"); + if (val & ARIZONA_AIF1_UNDERCLOCKED_STS) dev_err(arizona->dev, "AIF1 underclocked\n"); if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS) dev_err(arizona->dev, "ISRC2 underclocked\n"); -- cgit v1.2.3 From 46b9d13aaec19dfbd5882a999e8ed85fc97a751e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 20 Nov 2012 14:49:10 +0900 Subject: mfd: arizona: Sync regcache after reset In the absence of a physical reset line the chip is reset by writing the first register, which is done after the register patch has been applied. This patch synchronises the register cache after the reset to preserve any register changes that had been applied. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/arizona-core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 202bf55c3cc..f4f9bf84bc7 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -415,11 +415,19 @@ int __devinit arizona_dev_init(struct arizona *arizona) /* If we have a /RESET GPIO we'll already be reset */ if (!arizona->pdata.reset) { + regcache_mark_dirty(arizona->regmap); + ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err_reset; } + + ret = regcache_sync(arizona->regmap); + if (ret != 0) { + dev_err(dev, "Failed to sync device: %d\n", ret); + goto err_reset; + } } ret = arizona_wait_for_boot(arizona); -- cgit v1.2.3 From 8c8a4b610b537b64326f4eea261984f12f8da073 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 20 Nov 2012 14:23:18 +0200 Subject: KVM: Retire as maintainer After six and a half years of writing and maintaining KVM, it is time to move to new things. Update my MAINTAINERS entry to reflect that. Signed-off-by: Avi Kivity --- CREDITS | 5 +++++ MAINTAINERS | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CREDITS b/CREDITS index d8fe12a9421..2346b09ca8b 100644 --- a/CREDITS +++ b/CREDITS @@ -1823,6 +1823,11 @@ S: Kattreinstr 38 S: D-64295 S: Germany +N: Avi Kivity +E: avi.kivity@gmail.com +D: Kernel-based Virtual Machine (KVM) +S: Ra'annana, Israel + N: Andi Kleen E: andi@firstfloor.org U: http://www.halobates.de diff --git a/MAINTAINERS b/MAINTAINERS index bb0b27db673..6b5b0b7ea72 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4280,7 +4280,6 @@ F: include/linux/lockd/ F: include/linux/sunrpc/ KERNEL VIRTUAL MACHINE (KVM) -M: Avi Kivity M: Marcelo Tosatti L: kvm@vger.kernel.org W: http://kvm.qumranet.com -- cgit v1.2.3 From 484cbfd2a36fd2e32942cd9dff0cb2492b2be607 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Tue, 20 Nov 2012 14:37:24 +0200 Subject: KVM: taking co-maintenance Updating MAINTAINERS file. Signed-off-by: Gleb Natapov Signed-off-by: Avi Kivity --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6b5b0b7ea72..b2733604eb0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4281,6 +4281,7 @@ F: include/linux/sunrpc/ KERNEL VIRTUAL MACHINE (KVM) M: Marcelo Tosatti +M: Gleb Natapov L: kvm@vger.kernel.org W: http://kvm.qumranet.com S: Supported -- cgit v1.2.3 From 1b2852b152be5150fbef7b585388ec43cf6f4415 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Mon, 19 Nov 2012 17:00:24 +0100 Subject: vtime: Warn if irqs aren't disabled on system time accounting APIs System time accounting APIs such as vtime_account_system() and vtime_account_idle() need to be irqsafe. Current callers include irq entry, exit and kvm, all of which have been checked against that requirement. Now it's better to grow that with an automatic check in case we have further callers or we missed something. Suggested-by: Steven Rostedt Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Thomas Gleixner Cc: Steven Rostedt Cc: Paul Gortmaker Cc: Tony Luck Cc: Fenghua Yu Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Martin Schwidefsky Cc: Heiko Carstens --- arch/ia64/kernel/time.c | 2 ++ arch/powerpc/kernel/time.c | 2 ++ arch/s390/kernel/vtime.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index c9a7d2ebe08..b1995efbfd2 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -119,6 +119,8 @@ static cputime_t vtime_delta(struct task_struct *tsk) cputime_t delta_stime; __u64 now; + WARN_ON_ONCE(!irqs_disabled()); + now = ia64_get_itc(); delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp)); diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 3486cfad4a6..b3b14352b05 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -297,6 +297,8 @@ static u64 vtime_delta(struct task_struct *tsk, u64 now, nowscaled, deltascaled; u64 udelta, delta, user_scaled; + WARN_ON_ONCE(!irqs_disabled()); + now = mftb(); nowscaled = read_spurr(now); get_paca()->system_time += now - get_paca()->starttime; diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 7c6d861a1a4..e84b8b68444 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -132,6 +132,8 @@ void vtime_account(struct task_struct *tsk) struct thread_info *ti = task_thread_info(tsk); u64 timer, system; + WARN_ON_ONCE(!irqs_disabled()); + timer = S390_lowcore.last_update_timer; S390_lowcore.last_update_timer = get_vtimer(); S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; -- cgit v1.2.3 From e506d6fde50e0a737234892eda31708692bdda29 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 13 Nov 2012 17:24:43 +0100 Subject: drm/i915: disable cloning on sdvo After the recent pile of disable-cloning patches, e.g. commit e3b86d6941c7e5f90be05d986fce1fcb40c68d6b Author: Egbert Eich Date: Sat Oct 13 14:30:15 2012 +0200 DRM/i915: Don't clone SDVO LVDS with analog and a bug report from Chris Wilson indicating that cloning doesn't even work for DVI-SDVO and native VGA, let's just disable cloning on sdvo encoders completely. v2: Update the comment in the code as discussed with Paulo Zanoni. Reviewed-by: Paulo Zanoni Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=29259 Tested-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sdvo.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index c600fb06e25..a6ac0b41696 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2201,7 +2201,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; intel_sdvo->is_hdmi = true; } - intel_sdvo->base.cloneable = true; intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); if (intel_sdvo->is_hdmi) @@ -2232,7 +2231,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) intel_sdvo->is_tv = true; intel_sdvo->base.needs_tv_clock = true; - intel_sdvo->base.cloneable = false; intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); @@ -2275,8 +2273,6 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; } - intel_sdvo->base.cloneable = true; - intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); return true; @@ -2307,9 +2303,6 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; } - /* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */ - intel_sdvo->base.cloneable = false; - intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) goto err; @@ -2721,6 +2714,16 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) goto err_output; } + /* + * Cloning SDVO with anything is often impossible, since the SDVO + * encoder can request a special input timing mode. And even if that's + * not the case we have evidence that cloning a plain unscaled mode with + * VGA doesn't really work. Furthermore the cloning flags are way too + * simplistic anyway to express such constraints, so just give up on + * cloning for SDVO encoders. + */ + intel_sdvo->base.cloneable = false; + /* Only enable the hotplug irq if we need it, to work around noisy * hotplug lines. */ -- cgit v1.2.3 From 804cc4a0ad3a896ca295f771a28c6eb36ced7903 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 19 Nov 2012 09:11:27 -0500 Subject: drm/radeon: properly track the crtc not_enabled case evergreen_mc_stop() The save struct is not initialized previously so explicitly mark the crtcs as not used when they are not in use. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/evergreen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index af31f829f4a..219942c660d 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1330,6 +1330,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav break; udelay(1); } + } else { + save->crtc_enabled[i] = false; } } -- cgit v1.2.3 From 45171002b01b2e2ec4f991eca81ffd8430fd0aec Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Mon, 19 Nov 2012 21:17:31 +0100 Subject: radeon: add AGPMode 1 quirk for RV250 The Intel 82855PM host bridge / Mobility FireGL 9000 RV250 combination in an (outdated) ThinkPad T41 needs AGPMode 1 for suspend/resume (under KMS, that is). So add a quirk for it. (Change R250 to RV250 in comment for preceding quirk too.) Signed-off-by: Paul Bolle Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_agp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index 10ea17a6b2a..42433344cb1 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c @@ -69,9 +69,12 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = { /* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/ { PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59, PCI_VENDOR_ID_DELL, 0x00e3, 2}, - /* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */ + /* Intel 82852/82855 host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 (lp #296617) */ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66, PCI_VENDOR_ID_DELL, 0x0149, 1}, + /* Intel 82855PM host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 for suspend/resume */ + { PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66, + PCI_VENDOR_ID_IBM, 0x0531, 1}, /* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */ { PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50, 0x1025, 0x0061, 1}, -- cgit v1.2.3 From 78026a6fde8f7b0ca77c059da11f476d69dfde3b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 20 Nov 2012 13:36:00 +0000 Subject: iio:imu:adis: Add debugfs register access support Provide a IIO debugfs register access function for the ADIS library. This function can be used by individual drivers to allow raw register access via debugfs. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/imu/adis.c | 23 +++++++++++++++++++++++ include/linux/iio/imu/adis.h | 11 +++++++++++ 2 files changed, 34 insertions(+) diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c index 8259b774078..28d4df2fe76 100644 --- a/drivers/iio/imu/adis.c +++ b/drivers/iio/imu/adis.c @@ -135,6 +135,29 @@ error_ret: } EXPORT_SYMBOL_GPL(adis_read_reg_16); +#ifdef CONFIG_DEBUG_FS + +int adis_debugfs_reg_access(struct iio_dev *indio_dev, + unsigned int reg, unsigned int writeval, unsigned int *readval) +{ + struct adis *adis = iio_device_get_drvdata(indio_dev); + + if (readval) { + uint16_t val16; + int ret; + + ret = adis_read_reg_16(adis, reg, &val16); + *readval = val16; + + return ret; + } else { + return adis_write_reg_16(adis, reg, writeval); + } +} +EXPORT_SYMBOL(adis_debugfs_reg_access); + +#endif + /** * adis_enable_irq() - Enable or disable data ready IRQ * @adis: The adis device diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index 8c3304d44b9..fce7bc3ba0b 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -183,4 +183,15 @@ static inline void adis_remove_trigger(struct adis *adis) #endif /* CONFIG_IIO_BUFFER */ +#ifdef CONFIG_DEBUG_FS + +int adis_debugfs_reg_access(struct iio_dev *indio_dev, + unsigned int reg, unsigned int writeval, unsigned int *readval); + +#else + +#define adis_debugfs_reg_access NULL + +#endif + #endif -- cgit v1.2.3 From da9da01d9199b5bb15289d0859053c9aa3a34ac0 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 20 Nov 2012 06:31:57 +0000 Subject: ne2000: add the right platform device Without this udev doesn't have a way to key the ne device to the platform device. Signed-off-by: Alan Cox Signed-off-by: David S. Miller --- drivers/net/ethernet/8390/ne.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c index d04911d33b6..47618e50535 100644 --- a/drivers/net/ethernet/8390/ne.c +++ b/drivers/net/ethernet/8390/ne.c @@ -813,6 +813,7 @@ static int __init ne_drv_probe(struct platform_device *pdev) dev->irq = irq[this_dev]; dev->mem_end = bad[this_dev]; } + SET_NETDEV_DEV(dev, &pdev->dev); err = do_ne_probe(dev); if (err) { free_netdev(dev); -- cgit v1.2.3 From 57a1228a06b7a5939a8b0078a92b44fa30855bcb Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 20 Nov 2012 13:36:00 +0000 Subject: iio:imu:adis: Add support for 32bit registers Some of the newer generation devices from the ADIS16XXX family have 32bit wide register which spans two 16bit wide registers. This patch adds support for reading and writing a 32bit wide register. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/imu/adis.c | 145 +++++++++++++++++++++++++++--------------- drivers/iio/imu/adis_buffer.c | 2 + include/linux/iio/imu/adis.h | 81 +++++++++++++++++++++-- 3 files changed, 171 insertions(+), 57 deletions(-) diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c index 28d4df2fe76..280a49584ad 100644 --- a/drivers/iio/imu/adis.c +++ b/drivers/iio/imu/adis.c @@ -27,36 +27,10 @@ #define ADIS_MSC_CTRL_DATA_RDY_DIO2 BIT(0) #define ADIS_GLOB_CMD_SW_RESET BIT(7) -/** - * adis_write_reg_8() - Write single byte to a register - * @adis: The adis device - * @reg: The address of the register to be written - * @val: The value to write - */ -int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val) -{ - int ret; - - mutex_lock(&adis->txrx_lock); - adis->tx[0] = ADIS_WRITE_REG(reg); - adis->tx[1] = val; - - ret = spi_write(adis->spi, adis->tx, 2); - mutex_unlock(&adis->txrx_lock); - - return ret; -} -EXPORT_SYMBOL_GPL(adis_write_reg_8); - -/** - * adis_write_reg_16() - Write 2 bytes to a pair of registers - * @adis: The adis device - * @reg: The address of the lower of the two registers - * @val: Value to be written - */ -int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t value) +int adis_write_reg(struct adis *adis, unsigned int reg, + unsigned int value, unsigned int size) { - int ret; + int ret, i; struct spi_message msg; struct spi_transfer xfers[] = { { @@ -69,33 +43,69 @@ int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t value) .tx_buf = adis->tx + 2, .bits_per_word = 8, .len = 2, + .cs_change = 1, + .delay_usecs = adis->data->write_delay, + }, { + .tx_buf = adis->tx + 4, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = adis->data->write_delay, + }, { + .tx_buf = adis->tx + 6, + .bits_per_word = 8, + .len = 2, .delay_usecs = adis->data->write_delay, }, }; mutex_lock(&adis->txrx_lock); - adis->tx[0] = ADIS_WRITE_REG(reg); - adis->tx[1] = value & 0xff; - adis->tx[2] = ADIS_WRITE_REG(reg + 1); - adis->tx[3] = (value >> 8) & 0xff; spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); + switch (size) { + case 4: + adis->tx[6] = ADIS_WRITE_REG(reg + 3); + adis->tx[7] = (value >> 24) & 0xff; + adis->tx[4] = ADIS_WRITE_REG(reg + 2); + adis->tx[5] = (value >> 16) & 0xff; + case 2: + adis->tx[2] = ADIS_WRITE_REG(reg + 1); + adis->tx[3] = (value >> 8) & 0xff; + case 1: + adis->tx[0] = ADIS_WRITE_REG(reg); + adis->tx[1] = value & 0xff; + break; + default: + ret = -EINVAL; + goto out_unlock; + } + + xfers[size - 1].cs_change = 0; + + for (i = 0; i < size; i++) + spi_message_add_tail(&xfers[i], &msg); + ret = spi_sync(adis->spi, &msg); + if (ret) { + dev_err(&adis->spi->dev, "Failed to write register 0x%02X: %d\n", + reg, ret); + } + +out_unlock: mutex_unlock(&adis->txrx_lock); return ret; } -EXPORT_SYMBOL_GPL(adis_write_reg_16); +EXPORT_SYMBOL_GPL(adis_write_reg); /** - * adis_read_reg_16() - read 2 bytes from a 16-bit register + * adis_read_reg() - read 2 bytes from a 16-bit register * @adis: The adis device * @reg: The address of the lower of the two registers * @val: The value read back from the device */ -int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val) +int adis_read_reg(struct adis *adis, unsigned int reg, + unsigned int *val, unsigned int size) { struct spi_message msg; int ret; @@ -107,33 +117,61 @@ int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val) .cs_change = 1, .delay_usecs = adis->data->read_delay, }, { + .tx_buf = adis->tx + 2, .rx_buf = adis->rx, .bits_per_word = 8, .len = 2, + .cs_change = 1, + .delay_usecs = adis->data->read_delay, + }, { + .rx_buf = adis->rx + 2, + .bits_per_word = 8, + .len = 2, .delay_usecs = adis->data->read_delay, }, }; mutex_lock(&adis->txrx_lock); - adis->tx[0] = ADIS_READ_REG(reg); - adis->tx[1] = 0; - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); + + switch (size) { + case 4: + adis->tx[0] = ADIS_READ_REG(reg + 2); + adis->tx[1] = 0; + spi_message_add_tail(&xfers[0], &msg); + case 2: + adis->tx[2] = ADIS_READ_REG(reg); + adis->tx[3] = 0; + spi_message_add_tail(&xfers[1], &msg); + spi_message_add_tail(&xfers[2], &msg); + break; + default: + ret = -EINVAL; + goto out_unlock; + } + ret = spi_sync(adis->spi, &msg); if (ret) { - dev_err(&adis->spi->dev, "Failed to read 16 bit register 0x%02X: %d\n", + dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n", reg, ret); - goto error_ret; + goto out_unlock; } - *val = get_unaligned_be16(adis->rx); -error_ret: + switch (size) { + case 4: + *val = get_unaligned_be32(adis->rx); + break; + case 2: + *val = get_unaligned_be16(adis->rx + 2); + break; + } + +out_unlock: mutex_unlock(&adis->txrx_lock); + return ret; } -EXPORT_SYMBOL_GPL(adis_read_reg_16); +EXPORT_SYMBOL_GPL(adis_read_reg); #ifdef CONFIG_DEBUG_FS @@ -304,25 +342,26 @@ int adis_single_conversion(struct iio_dev *indio_dev, const struct iio_chan_spec *chan, unsigned int error_mask, int *val) { struct adis *adis = iio_device_get_drvdata(indio_dev); - uint16_t val16; + unsigned int uval; int ret; mutex_lock(&indio_dev->mlock); - ret = adis_read_reg_16(adis, chan->address, &val16); + ret = adis_read_reg(adis, chan->address, &uval, + chan->scan_type.storagebits / 8); if (ret) goto err_unlock; - if (val16 & error_mask) { + if (uval & error_mask) { ret = adis_check_status(adis); if (ret) goto err_unlock; } if (chan->scan_type.sign == 's') - *val = sign_extend32(val16, chan->scan_type.realbits - 1); + *val = sign_extend32(uval, chan->scan_type.realbits - 1); else - *val = val16 & ((1 << chan->scan_type.realbits) - 1); + *val = uval & ((1 << chan->scan_type.realbits) - 1); ret = IIO_VAL_INT; err_unlock: diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c index a91b4cbdc73..785713349e9 100644 --- a/drivers/iio/imu/adis_buffer.c +++ b/drivers/iio/imu/adis_buffer.c @@ -64,6 +64,8 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, for (i = 0; i < indio_dev->num_channels; i++, chan++) { if (!test_bit(chan->scan_index, scan_mask)) continue; + if (chan->scan_type.storagebits == 32) + *tx++ = cpu_to_be16((chan->address + 2) << 8); *tx++ = cpu_to_be16(chan->address << 8); } diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index fce7bc3ba0b..6402a08c0e6 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -53,7 +53,7 @@ struct adis { struct spi_transfer *xfer; void *buffer; - uint8_t tx[8] ____cacheline_aligned; + uint8_t tx[10] ____cacheline_aligned; uint8_t rx[4]; }; @@ -61,9 +61,82 @@ int adis_init(struct adis *adis, struct iio_dev *indio_dev, struct spi_device *spi, const struct adis_data *data); int adis_reset(struct adis *adis); -int adis_write_reg_8(struct adis *adis, unsigned int reg, uint8_t val); -int adis_write_reg_16(struct adis *adis, unsigned int reg, uint16_t val); -int adis_read_reg_16(struct adis *adis, unsigned int reg, uint16_t *val); +int adis_write_reg(struct adis *adis, unsigned int reg, + unsigned int val, unsigned int size); +int adis_read_reg(struct adis *adis, unsigned int reg, + unsigned int *val, unsigned int size); + +/** + * adis_write_reg_8() - Write single byte to a register + * @adis: The adis device + * @reg: The address of the register to be written + * @value: The value to write + */ +static inline int adis_write_reg_8(struct adis *adis, unsigned int reg, + uint8_t val) +{ + return adis_write_reg(adis, reg, val, 1); +} + +/** + * adis_write_reg_16() - Write 2 bytes to a pair of registers + * @adis: The adis device + * @reg: The address of the lower of the two registers + * @value: Value to be written + */ +static inline int adis_write_reg_16(struct adis *adis, unsigned int reg, + uint16_t val) +{ + return adis_write_reg(adis, reg, val, 2); +} + +/** + * adis_write_reg_32() - write 4 bytes to four registers + * @adis: The adis device + * @reg: The address of the lower of the four register + * @value: Value to be written + */ +static inline int adis_write_reg_32(struct adis *adis, unsigned int reg, + uint32_t val) +{ + return adis_write_reg(adis, reg, val, 4); +} + +/** + * adis_read_reg_16() - read 2 bytes from a 16-bit register + * @adis: The adis device + * @reg: The address of the lower of the two registers + * @val: The value read back from the device + */ +static inline int adis_read_reg_16(struct adis *adis, unsigned int reg, + uint16_t *val) +{ + unsigned int tmp; + int ret; + + ret = adis_read_reg(adis, reg, &tmp, 2); + *val = tmp; + + return ret; +} + +/** + * adis_read_reg_32() - read 4 bytes from a 32-bit register + * @adis: The adis device + * @reg: The address of the lower of the two registers + * @val: The value read back from the device + */ +static inline int adis_read_reg_32(struct adis *adis, unsigned int reg, + uint32_t *val) +{ + unsigned int tmp; + int ret; + + ret = adis_read_reg(adis, reg, &tmp, 4); + *val = tmp; + + return ret; +} int adis_enable_irq(struct adis *adis, bool enable); int adis_check_status(struct adis *adis); -- cgit v1.2.3 From 1a4901177574083c35fafc24c4d151c2a7c7647c Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Sat, 17 Nov 2012 20:25:09 +0000 Subject: ixp4xx_eth: avoid calling dma_pool_create() with NULL dev Use &port->netdev->dev instead of NULL since dma_pool_create() doesn't allow NULL dev. Signed-off-by: Xi Wang Cc: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/ethernet/xscale/ixp4xx_eth.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index 98934bdf6ac..477d6729b17 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c @@ -1102,10 +1102,12 @@ static int init_queues(struct port *port) { int i; - if (!ports_open) - if (!(dma_pool = dma_pool_create(DRV_NAME, NULL, - POOL_ALLOC_SIZE, 32, 0))) + if (!ports_open) { + dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev, + POOL_ALLOC_SIZE, 32, 0); + if (!dma_pool) return -ENOMEM; + } if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, &port->desc_tab_phys))) -- cgit v1.2.3 From 3e2f61cd7a4e7642dcac4371734426e572f10370 Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Sat, 17 Nov 2012 20:25:10 +0000 Subject: ixp4xx_hss: avoid calling dma_pool_create() with NULL dev Use &port->netdev->dev instead of NULL since dma_pool_create() doesn't allow NULL dev. Signed-off-by: Xi Wang Cc: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/wan/ixp4xx_hss.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index 3f575afd8cf..e9a3da588e9 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c @@ -969,10 +969,12 @@ static int init_hdlc_queues(struct port *port) { int i; - if (!ports_open) - if (!(dma_pool = dma_pool_create(DRV_NAME, NULL, - POOL_ALLOC_SIZE, 32, 0))) + if (!ports_open) { + dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev, + POOL_ALLOC_SIZE, 32, 0); + if (!dma_pool) return -ENOMEM; + } if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL, &port->desc_tab_phys))) -- cgit v1.2.3 From b4dd006760d671337b62532277b0296bcee8dfd4 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 20 Nov 2012 15:14:51 -0500 Subject: ipv6: fix inet6_csk_update_pmtu() return value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case of error, inet6_csk_update_pmtu() should consistently return NULL. Bug added in commit 35ad9b9cf7d8a (ipv6: Add helper inet6_csk_update_pmtu().) Reported-by: Lluís Batlle i Rossell Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/inet6_connection_sock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index c4f934176ca..30647857a37 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -252,6 +252,7 @@ struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu) return NULL; dst->ops->update_pmtu(dst, sk, NULL, mtu); - return inet6_csk_route_socket(sk, &fl6); + dst = inet6_csk_route_socket(sk, &fl6); + return IS_ERR(dst) ? NULL : dst; } EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu); -- cgit v1.2.3 From caaa8c6339ccefee6e834c4a8b0bec7e721e7357 Mon Sep 17 00:00:00 2001 From: Cesar Eduardo Barros Date: Sat, 27 Oct 2012 20:34:15 -0200 Subject: x86: remove dummy long from EFI stub Commit 2e064b1 (x86, efi: Fix issue of overlapping .reloc section for EFI_STUB) removed a dummy reloc added by commit 291f363 (x86, efi: EFI boot stub support), but forgot to remove the dummy long used by that reloc. Reviewed-by: Jordan Justen Tested-by: Lee G Rosenbaum Cc: "H. Peter Anvin" Cc: Thomas Gleixner Cc: Ingo Molnar Signed-off-by: Cesar Eduardo Barros Signed-off-by: Matt Fleming --- arch/x86/boot/header.S | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 2a017441b8b..8c132a625b9 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -476,6 +476,3 @@ die: setup_corrupt: .byte 7 .string "No setup signature found...\n" - - .data -dummy: .long 0 -- cgit v1.2.3 From 2355a62bcbdcc4b567425bab036bfab6ade87eed Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Tue, 20 Nov 2012 09:59:11 +0000 Subject: irda: sir_dev: Fix copy/paste typo Signed-off-by: Alexander Shiyan Signed-off-by: David S. Miller --- drivers/net/irda/sir_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 5039f08f5a5..43e9ab4f4d7 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -222,7 +222,7 @@ static void sirdev_config_fsm(struct work_struct *work) break; case SIRDEV_STATE_DONGLE_SPEED: - if (dev->dongle_drv->reset) { + if (dev->dongle_drv->set_speed) { ret = dev->dongle_drv->set_speed(dev, fsm->param); if (ret < 0) { fsm->result = ret; -- cgit v1.2.3 From aecb55be41b1bab432e81d550ebce010e7d178c6 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Tue, 20 Nov 2012 10:23:13 +0000 Subject: net: fix build failure in xilinx Commit 71c6c837 (drivers/net: fix tasklet misuse issue) introduced a build failure in the xilinx driver. axienet_dma_err_handler isn't declared before its use in axienet_open. This patch provides the prototype before axienet_open. Cc: Xiaotian Feng Signed-off-by: Jeff Mahoney Signed-off-by: David S. Miller --- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 77e6db9dcfe..a788501e978 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -894,6 +894,8 @@ out: return IRQ_HANDLED; } +static void axienet_dma_err_handler(unsigned long data); + /** * axienet_open - Driver open routine. * @ndev: Pointer to net_device structure -- cgit v1.2.3 From 0f905a43ce955b638139bd84486194770a6a2c08 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 20 Nov 2012 13:07:46 +0000 Subject: x86, efi: Fix processor-specific memcpy() build error Building for Athlon/Duron/K7 results in the following build error, arch/x86/boot/compressed/eboot.o: In function `__constant_memcpy3d': eboot.c:(.text+0x385): undefined reference to `_mmx_memcpy' arch/x86/boot/compressed/eboot.o: In function `efi_main': eboot.c:(.text+0x1a22): undefined reference to `_mmx_memcpy' because the boot stub code doesn't link with the kernel proper, and therefore doesn't have access to the 3DNow version of memcpy. So, follow the example of misc.c and #undef memcpy so that we use the version provided by misc.c. See https://bugzilla.kernel.org/show_bug.cgi?id=50391 Reported-by: Al Viro Reported-by: Ryan Underwood Cc: H. Peter Anvin Cc: stable@vger.kernel.org Signed-off-by: Matt Fleming --- arch/x86/boot/compressed/eboot.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index c760e073963..e87b0cac14b 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -12,6 +12,8 @@ #include #include +#undef memcpy /* Use memcpy from misc.c */ + #include "eboot.h" static efi_system_table_t *sys_table; -- cgit v1.2.3 From 9caed0d9d6db12cb6d81ba68d5bc98432d6b4711 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 20 Nov 2012 13:36:00 +0000 Subject: iio:gyro: Add support for the ADIS16136 gyroscope This patch adds support for the ADIS16133, ADIS16135, ADIS16136 single channel gyroscopes. The main difference between them is the sensor precision. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/gyro/Kconfig | 9 + drivers/iio/gyro/Makefile | 1 + drivers/iio/gyro/adis16136.c | 581 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 591 insertions(+) create mode 100644 drivers/iio/gyro/adis16136.c diff --git a/drivers/iio/gyro/Kconfig b/drivers/iio/gyro/Kconfig index 21e27e2fc68..48ed1483ff2 100644 --- a/drivers/iio/gyro/Kconfig +++ b/drivers/iio/gyro/Kconfig @@ -3,6 +3,15 @@ # menu "Digital gyroscope sensors" +config ADIS16136 + tristate "Analog devices ADIS16136 and similar gyroscopes driver" + depends on SPI_MASTER + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER + help + Say yes here to build support for the Analog Devices ADIS16133, ADIS16135, + ADIS16136 gyroscope devices. + config HID_SENSOR_GYRO_3D depends on HID_SENSOR_HUB select IIO_BUFFER diff --git a/drivers/iio/gyro/Makefile b/drivers/iio/gyro/Makefile index 8a895d9fcbc..702a058907e 100644 --- a/drivers/iio/gyro/Makefile +++ b/drivers/iio/gyro/Makefile @@ -2,4 +2,5 @@ # Makefile for industrial I/O gyroscope sensor drivers # +obj-$(CONFIG_ADIS16136) += adis16136.o obj-$(CONFIG_HID_SENSOR_GYRO_3D) += hid-sensor-gyro-3d.o diff --git a/drivers/iio/gyro/adis16136.c b/drivers/iio/gyro/adis16136.c new file mode 100644 index 00000000000..05486dfd721 --- /dev/null +++ b/drivers/iio/gyro/adis16136.c @@ -0,0 +1,581 @@ +/* + * ADIS16133/ADIS16135/ADIS16136 gyroscope driver + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen + * + * Licensed under the GPL-2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define ADIS16136_REG_FLASH_CNT 0x00 +#define ADIS16136_REG_TEMP_OUT 0x02 +#define ADIS16136_REG_GYRO_OUT2 0x04 +#define ADIS16136_REG_GYRO_OUT 0x06 +#define ADIS16136_REG_GYRO_OFF2 0x08 +#define ADIS16136_REG_GYRO_OFF 0x0A +#define ADIS16136_REG_ALM_MAG1 0x10 +#define ADIS16136_REG_ALM_MAG2 0x12 +#define ADIS16136_REG_ALM_SAMPL1 0x14 +#define ADIS16136_REG_ALM_SAMPL2 0x16 +#define ADIS16136_REG_ALM_CTRL 0x18 +#define ADIS16136_REG_GPIO_CTRL 0x1A +#define ADIS16136_REG_MSC_CTRL 0x1C +#define ADIS16136_REG_SMPL_PRD 0x1E +#define ADIS16136_REG_AVG_CNT 0x20 +#define ADIS16136_REG_DEC_RATE 0x22 +#define ADIS16136_REG_SLP_CTRL 0x24 +#define ADIS16136_REG_DIAG_STAT 0x26 +#define ADIS16136_REG_GLOB_CMD 0x28 +#define ADIS16136_REG_LOT1 0x32 +#define ADIS16136_REG_LOT2 0x34 +#define ADIS16136_REG_LOT3 0x36 +#define ADIS16136_REG_PROD_ID 0x38 +#define ADIS16136_REG_SERIAL_NUM 0x3A + +#define ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL 2 +#define ADIS16136_DIAG_STAT_SPI_FAIL 3 +#define ADIS16136_DIAG_STAT_SELF_TEST_FAIL 5 +#define ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL 6 + +#define ADIS16136_MSC_CTRL_MEMORY_TEST BIT(11) +#define ADIS16136_MSC_CTRL_SELF_TEST BIT(10) + +struct adis16136_chip_info { + unsigned int precision; + unsigned int fullscale; +}; + +struct adis16136 { + const struct adis16136_chip_info *chip_info; + + struct adis adis; +}; + +#ifdef CONFIG_DEBUG_FS + +static ssize_t adis16136_show_serial(struct file *file, + char __user *userbuf, size_t count, loff_t *ppos) +{ + struct adis16136 *adis16136 = file->private_data; + uint16_t lot1, lot2, lot3, serial; + char buf[20]; + size_t len; + int ret; + + ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SERIAL_NUM, + &serial); + if (ret < 0) + return ret; + + ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT1, &lot1); + if (ret < 0) + return ret; + + ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT2, &lot2); + if (ret < 0) + return ret; + + ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_LOT3, &lot3); + if (ret < 0) + return ret; + + len = snprintf(buf, sizeof(buf), "%.4x%.4x%.4x-%.4x\n", lot1, lot2, + lot3, serial); + + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} + +static const struct file_operations adis16136_serial_fops = { + .open = simple_open, + .read = adis16136_show_serial, + .llseek = default_llseek, + .owner = THIS_MODULE, +}; + +static int adis16136_show_product_id(void *arg, u64 *val) +{ + struct adis16136 *adis16136 = arg; + u16 prod_id; + int ret; + + ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_PROD_ID, + &prod_id); + if (ret < 0) + return ret; + + *val = prod_id; + + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(adis16136_product_id_fops, + adis16136_show_product_id, NULL, "%llu\n"); + +static int adis16136_show_flash_count(void *arg, u64 *val) +{ + struct adis16136 *adis16136 = arg; + uint16_t flash_count; + int ret; + + ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_FLASH_CNT, + &flash_count); + if (ret < 0) + return ret; + + *val = flash_count; + + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(adis16136_flash_count_fops, + adis16136_show_flash_count, NULL, "%lld\n"); + +static int adis16136_debugfs_init(struct iio_dev *indio_dev) +{ + struct adis16136 *adis16136 = iio_priv(indio_dev); + + debugfs_create_file("serial_number", 0400, indio_dev->debugfs_dentry, + adis16136, &adis16136_serial_fops); + debugfs_create_file("product_id", 0400, indio_dev->debugfs_dentry, + adis16136, &adis16136_product_id_fops); + debugfs_create_file("flash_count", 0400, indio_dev->debugfs_dentry, + adis16136, &adis16136_flash_count_fops); + + return 0; +} + +#else + +static int adis16136_debugfs_init(struct iio_dev *indio_dev) +{ + return 0; +} + +#endif + +static int adis16136_set_freq(struct adis16136 *adis16136, unsigned int freq) +{ + unsigned int t; + + t = 32768 / freq; + if (t < 0xf) + t = 0xf; + else if (t > 0xffff) + t = 0xffff; + else + t--; + + return adis_write_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, t); +} + +static int adis16136_get_freq(struct adis16136 *adis16136, unsigned int *freq) +{ + uint16_t t; + int ret; + + ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_SMPL_PRD, &t); + if (ret < 0) + return ret; + + *freq = 32768 / (t + 1); + + return 0; +} + +static ssize_t adis16136_write_frequency(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adis16136 *adis16136 = iio_priv(indio_dev); + long val; + int ret; + + ret = kstrtol(buf, 10, &val); + if (ret) + return ret; + + if (val == 0) + return -EINVAL; + + ret = adis16136_set_freq(adis16136, val); + + return ret ? ret : len; +} + +static ssize_t adis16136_read_frequency(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adis16136 *adis16136 = iio_priv(indio_dev); + unsigned int freq; + int ret; + + ret = adis16136_get_freq(adis16136, &freq); + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", freq); +} + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + adis16136_read_frequency, + adis16136_write_frequency); + +static const unsigned adis16136_3db_divisors[] = { + [0] = 2, /* Special case */ + [1] = 6, + [2] = 12, + [3] = 25, + [4] = 50, + [5] = 100, + [6] = 200, + [7] = 200, /* Not a valid setting */ +}; + +static int adis16136_set_filter(struct iio_dev *indio_dev, int val) +{ + struct adis16136 *adis16136 = iio_priv(indio_dev); + unsigned int freq; + int i, ret; + + ret = adis16136_get_freq(adis16136, &freq); + if (ret < 0) + return ret; + + for (i = ARRAY_SIZE(adis16136_3db_divisors) - 1; i >= 1; i--) { + if (freq / adis16136_3db_divisors[i] >= val) + break; + } + + return adis_write_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, i); +} + +static int adis16136_get_filter(struct iio_dev *indio_dev, int *val) +{ + struct adis16136 *adis16136 = iio_priv(indio_dev); + unsigned int freq; + uint16_t val16; + int ret; + + mutex_lock(&indio_dev->mlock); + + ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_AVG_CNT, &val16); + if (ret < 0) + goto err_unlock; + + ret = adis16136_get_freq(adis16136, &freq); + if (ret < 0) + goto err_unlock; + + *val = freq / adis16136_3db_divisors[val16 & 0x07]; + +err_unlock: + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : IIO_VAL_INT; +} + +static int adis16136_read_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *val, int *val2, long info) +{ + struct adis16136 *adis16136 = iio_priv(indio_dev); + uint32_t val32; + int ret; + + switch (info) { + case IIO_CHAN_INFO_RAW: + return adis_single_conversion(indio_dev, chan, 0, val); + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_ANGL_VEL: + *val = adis16136->chip_info->precision; + *val2 = (adis16136->chip_info->fullscale << 16); + return IIO_VAL_FRACTIONAL; + case IIO_TEMP: + *val = 10; + *val2 = 697000; /* 0.010697 degree Celsius */ + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_CALIBBIAS: + ret = adis_read_reg_32(&adis16136->adis, + ADIS16136_REG_GYRO_OFF2, &val32); + if (ret < 0) + return ret; + + *val = sign_extend32(val32, 31); + + return IIO_VAL_INT; + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + return adis16136_get_filter(indio_dev, val); + default: + return -EINVAL; + } +} + +static int adis16136_write_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int val, int val2, long info) +{ + struct adis16136 *adis16136 = iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_CALIBBIAS: + return adis_write_reg_32(&adis16136->adis, + ADIS16136_REG_GYRO_OFF2, val); + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + return adis16136_set_filter(indio_dev, val); + default: + break; + } + + return -EINVAL; +} + +enum { + ADIS16136_SCAN_GYRO, + ADIS16136_SCAN_TEMP, +}; + +static const struct iio_chan_spec adis16136_channels[] = { + { + .type = IIO_ANGL_VEL, + .modified = 1, + .channel2 = IIO_MOD_X, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SHARED_BIT | + IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT, + .address = ADIS16136_REG_GYRO_OUT2, + .scan_index = ADIS16136_SCAN_GYRO, + .scan_type = { + .sign = 's', + .realbits = 32, + .storagebits = 32, + .endianness = IIO_BE, + }, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, + .address = ADIS16136_REG_TEMP_OUT, + .scan_index = ADIS16136_SCAN_TEMP, + .scan_type = { + .sign = 's', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_BE, + }, + }, + IIO_CHAN_SOFT_TIMESTAMP(2), +}; + +static struct attribute *adis16136_attributes[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16136_attribute_group = { + .attrs = adis16136_attributes, +}; + +static const struct iio_info adis16136_info = { + .driver_module = THIS_MODULE, + .attrs = &adis16136_attribute_group, + .read_raw = &adis16136_read_raw, + .write_raw = &adis16136_write_raw, + .update_scan_mode = adis_update_scan_mode, + .debugfs_reg_access = adis_debugfs_reg_access, +}; + +static int adis16136_stop_device(struct iio_dev *indio_dev) +{ + struct adis16136 *adis16136 = iio_priv(indio_dev); + int ret; + + ret = adis_write_reg_16(&adis16136->adis, ADIS16136_REG_SLP_CTRL, 0xff); + if (ret) + dev_err(&indio_dev->dev, + "Could not power down device: %d\n", ret); + + return ret; +} + +static int adis16136_initial_setup(struct iio_dev *indio_dev) +{ + struct adis16136 *adis16136 = iio_priv(indio_dev); + unsigned int device_id; + uint16_t prod_id; + int ret; + + ret = adis_initial_startup(&adis16136->adis); + if (ret) + return ret; + + ret = adis_read_reg_16(&adis16136->adis, ADIS16136_REG_PROD_ID, + &prod_id); + if (ret) + return ret; + + sscanf(indio_dev->name, "adis%u\n", &device_id); + + if (prod_id != device_id) + dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.", + device_id, prod_id); + + return 0; +} + +static const char * const adis16136_status_error_msgs[] = { + [ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL] = "Flash update failed", + [ADIS16136_DIAG_STAT_SPI_FAIL] = "SPI failure", + [ADIS16136_DIAG_STAT_SELF_TEST_FAIL] = "Self test error", + [ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL] = "Flash checksum error", +}; + +static const struct adis_data adis16136_data = { + .diag_stat_reg = ADIS16136_REG_DIAG_STAT, + .glob_cmd_reg = ADIS16136_REG_GLOB_CMD, + .msc_ctrl_reg = ADIS16136_REG_MSC_CTRL, + + .self_test_mask = ADIS16136_MSC_CTRL_SELF_TEST, + .startup_delay = 80, + + .read_delay = 10, + .write_delay = 10, + + .status_error_msgs = adis16136_status_error_msgs, + .status_error_mask = BIT(ADIS16136_DIAG_STAT_FLASH_UPDATE_FAIL) | + BIT(ADIS16136_DIAG_STAT_SPI_FAIL) | + BIT(ADIS16136_DIAG_STAT_SELF_TEST_FAIL) | + BIT(ADIS16136_DIAG_STAT_FLASH_CHKSUM_FAIL), +}; + +enum adis16136_id { + ID_ADIS16133, + ID_ADIS16135, + ID_ADIS16136, +}; + +static const struct adis16136_chip_info adis16136_chip_info[] = { + [ID_ADIS16133] = { + .precision = IIO_DEGREE_TO_RAD(1200), + .fullscale = 24000, + }, + [ID_ADIS16135] = { + .precision = IIO_DEGREE_TO_RAD(300), + .fullscale = 24000, + }, + [ID_ADIS16136] = { + .precision = IIO_DEGREE_TO_RAD(450), + .fullscale = 24623, + }, +}; + +static int adis16136_probe(struct spi_device *spi) +{ + const struct spi_device_id *id = spi_get_device_id(spi); + struct adis16136 *adis16136; + struct iio_dev *indio_dev; + int ret; + + indio_dev = iio_device_alloc(sizeof(*adis16136)); + if (indio_dev == NULL) + return -ENOMEM; + + spi_set_drvdata(spi, indio_dev); + + adis16136 = iio_priv(indio_dev); + + adis16136->chip_info = &adis16136_chip_info[id->driver_data]; + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->channels = adis16136_channels; + indio_dev->num_channels = ARRAY_SIZE(adis16136_channels); + indio_dev->info = &adis16136_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis_init(&adis16136->adis, indio_dev, spi, &adis16136_data); + if (ret) + goto error_free_dev; + + ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL); + if (ret) + goto error_free_dev; + + ret = adis16136_initial_setup(indio_dev); + if (ret) + goto error_cleanup_buffer; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_stop_device; + + adis16136_debugfs_init(indio_dev); + + return 0; + +error_stop_device: + adis16136_stop_device(indio_dev); +error_cleanup_buffer: + adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); +error_free_dev: + iio_device_free(indio_dev); + return ret; +} + +static int adis16136_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis16136 *adis16136 = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + adis16136_stop_device(indio_dev); + + adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev); + + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id adis16136_ids[] = { + { "adis16133", ID_ADIS16133 }, + { "adis16135", ID_ADIS16135 }, + { "adis16136", ID_ADIS16136 }, + { } +}; +MODULE_DEVICE_TABLE(spi, adis16136_ids); + +static struct spi_driver adis16136_driver = { + .driver = { + .name = "adis16136", + .owner = THIS_MODULE, + }, + .id_table = adis16136_ids, + .probe = adis16136_probe, + .remove = adis16136_remove, +}; +module_spi_driver(adis16136_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Analog Devices ADIS16133/ADIS16135/ADIS16136 gyroscope driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 484a0bf091c93c379e6524a17bb037c33c898e01 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 20 Nov 2012 13:36:00 +0000 Subject: iio:imu:adis: Add paging support Some of the newer generation devices from the ADIS16XXX series have more registers than what can be supported with the current register addressing scheme. These devices implement register paging to support a larger register range. Each page is 128 registers large and the currently active page can be selected via register 0x00 in each page. This patch implements transparent paging inside the common adis library. The register read/write interface stays the same and when a register is accessed the library automatically switches to the correct page if it is not already selected. The page number is encoded in the upper bits of the register number, e.g. register 0x5 of page 1 is 0x85. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/imu/adis.c | 70 +++++++++++++++++++++++++++++++++---------- drivers/iio/imu/adis_buffer.c | 15 ++++++++++ include/linux/iio/imu/adis.h | 10 +++++-- 3 files changed, 77 insertions(+), 18 deletions(-) diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c index 280a49584ad..c4ea04ffa60 100644 --- a/drivers/iio/imu/adis.c +++ b/drivers/iio/imu/adis.c @@ -30,6 +30,7 @@ int adis_write_reg(struct adis *adis, unsigned int reg, unsigned int value, unsigned int size) { + unsigned int page = reg / ADIS_PAGE_SIZE; int ret, i; struct spi_message msg; struct spi_transfer xfers[] = { @@ -56,39 +57,53 @@ int adis_write_reg(struct adis *adis, unsigned int reg, .bits_per_word = 8, .len = 2, .delay_usecs = adis->data->write_delay, + }, { + .tx_buf = adis->tx + 8, + .bits_per_word = 8, + .len = 2, + .delay_usecs = adis->data->write_delay, }, }; mutex_lock(&adis->txrx_lock); spi_message_init(&msg); + + if (adis->current_page != page) { + adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID); + adis->tx[1] = page; + spi_message_add_tail(&xfers[0], &msg); + } + switch (size) { case 4: - adis->tx[6] = ADIS_WRITE_REG(reg + 3); - adis->tx[7] = (value >> 24) & 0xff; - adis->tx[4] = ADIS_WRITE_REG(reg + 2); - adis->tx[5] = (value >> 16) & 0xff; + adis->tx[8] = ADIS_WRITE_REG(reg + 3); + adis->tx[9] = (value >> 24) & 0xff; + adis->tx[6] = ADIS_WRITE_REG(reg + 2); + adis->tx[7] = (value >> 16) & 0xff; case 2: - adis->tx[2] = ADIS_WRITE_REG(reg + 1); - adis->tx[3] = (value >> 8) & 0xff; + adis->tx[4] = ADIS_WRITE_REG(reg + 1); + adis->tx[5] = (value >> 8) & 0xff; case 1: - adis->tx[0] = ADIS_WRITE_REG(reg); - adis->tx[1] = value & 0xff; + adis->tx[2] = ADIS_WRITE_REG(reg); + adis->tx[3] = value & 0xff; break; default: ret = -EINVAL; goto out_unlock; } - xfers[size - 1].cs_change = 0; + xfers[size].cs_change = 0; - for (i = 0; i < size; i++) + for (i = 1; i <= size; i++) spi_message_add_tail(&xfers[i], &msg); ret = spi_sync(adis->spi, &msg); if (ret) { dev_err(&adis->spi->dev, "Failed to write register 0x%02X: %d\n", reg, ret); + } else { + adis->current_page = page; } out_unlock: @@ -107,6 +122,7 @@ EXPORT_SYMBOL_GPL(adis_write_reg); int adis_read_reg(struct adis *adis, unsigned int reg, unsigned int *val, unsigned int size) { + unsigned int page = reg / ADIS_PAGE_SIZE; struct spi_message msg; int ret; struct spi_transfer xfers[] = { @@ -115,9 +131,15 @@ int adis_read_reg(struct adis *adis, unsigned int reg, .bits_per_word = 8, .len = 2, .cs_change = 1, - .delay_usecs = adis->data->read_delay, + .delay_usecs = adis->data->write_delay, }, { .tx_buf = adis->tx + 2, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = adis->data->read_delay, + }, { + .tx_buf = adis->tx + 4, .rx_buf = adis->rx, .bits_per_word = 8, .len = 2, @@ -134,16 +156,22 @@ int adis_read_reg(struct adis *adis, unsigned int reg, mutex_lock(&adis->txrx_lock); spi_message_init(&msg); + if (adis->current_page != page) { + adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID); + adis->tx[1] = page; + spi_message_add_tail(&xfers[0], &msg); + } + switch (size) { case 4: - adis->tx[0] = ADIS_READ_REG(reg + 2); - adis->tx[1] = 0; - spi_message_add_tail(&xfers[0], &msg); - case 2: - adis->tx[2] = ADIS_READ_REG(reg); + adis->tx[2] = ADIS_READ_REG(reg + 2); adis->tx[3] = 0; spi_message_add_tail(&xfers[1], &msg); + case 2: + adis->tx[4] = ADIS_READ_REG(reg); + adis->tx[5] = 0; spi_message_add_tail(&xfers[2], &msg); + spi_message_add_tail(&xfers[3], &msg); break; default: ret = -EINVAL; @@ -155,6 +183,8 @@ int adis_read_reg(struct adis *adis, unsigned int reg, dev_err(&adis->spi->dev, "Failed to read register 0x%02X: %d\n", reg, ret); goto out_unlock; + } else { + adis->current_page = page; } switch (size) { @@ -390,6 +420,14 @@ int adis_init(struct adis *adis, struct iio_dev *indio_dev, adis->data = data; iio_device_set_drvdata(indio_dev, adis); + if (data->has_paging) { + /* Need to set the page before first read/write */ + adis->current_page = -1; + } else { + /* Page will always be 0 */ + adis->current_page = 0; + } + return adis_enable_irq(adis, false); } EXPORT_SYMBOL_GPL(adis_init); diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c index 785713349e9..99d8e0b0dd3 100644 --- a/drivers/iio/imu/adis_buffer.c +++ b/drivers/iio/imu/adis_buffer.c @@ -83,10 +83,25 @@ static irqreturn_t adis_trigger_handler(int irq, void *p) if (!adis->buffer) return -ENOMEM; + if (adis->data->has_paging) { + mutex_lock(&adis->txrx_lock); + if (adis->current_page != 0) { + adis->tx[0] = ADIS_WRITE_REG(ADIS_REG_PAGE_ID); + adis->tx[1] = 0; + spi_write(adis->spi, adis->tx, 2); + } + } + ret = spi_sync(adis->spi, &adis->msg); if (ret) dev_err(&adis->spi->dev, "Failed to read data: %d", ret); + + if (adis->data->has_paging) { + adis->current_page = 0; + mutex_unlock(&adis->txrx_lock); + } + /* Guaranteed to be aligned with 8 byte boundary */ if (indio_dev->scan_timestamp) { void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64); diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index 6402a08c0e6..e82cd0827e9 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -14,8 +14,11 @@ #include #include -#define ADIS_WRITE_REG(reg) (0x80 | (reg)) -#define ADIS_READ_REG(reg) (reg) +#define ADIS_WRITE_REG(reg) ((0x80 | (reg))) +#define ADIS_READ_REG(reg) ((reg) & 0x7f) + +#define ADIS_PAGE_SIZE 0x80 +#define ADIS_REG_PAGE_ID 0x00 /** * struct adis_data - ADIS chip variant specific data @@ -40,6 +43,8 @@ struct adis_data { const char * const *status_error_msgs; unsigned int status_error_mask; + + bool has_paging; }; struct adis { @@ -51,6 +56,7 @@ struct adis { struct mutex txrx_lock; struct spi_message msg; struct spi_transfer *xfer; + unsigned int current_page; void *buffer; uint8_t tx[10] ____cacheline_aligned; -- cgit v1.2.3 From c4f0c6936762ecd6b453275611a785dfdee0d417 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 20 Nov 2012 13:36:00 +0000 Subject: iio: Add pressure channel type This patch adds support for a new IIO channel type for pressure measurements. This can for example be used for barometric pressure sensors. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio | 24 ++++++++++++++++++++++++ drivers/iio/industrialio-core.c | 1 + include/linux/iio/types.h | 1 + 3 files changed, 26 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 2f06d40fe07..2e33dc6b234 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -189,6 +189,14 @@ Description: A computed peak value based on the sum squared magnitude of the underlying value in the specified directions. +What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_raw +What: /sys/bus/iio/devices/iio:deviceX/in_pressure_raw +KernelVersion: 3.8 +Contact: linux-iio@vger.kernel.org +Description: + Raw pressure measurement from channel Y. Units after + application of scale and offset are kilopascal. + What: /sys/bus/iio/devices/iio:deviceX/in_accel_offset What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_offset What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_offset @@ -197,6 +205,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_offset What: /sys/bus/iio/devices/iio:deviceX/in_voltage_offset What: /sys/bus/iio/devices/iio:deviceX/in_tempY_offset What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset +What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset +What: /sys/bus/iio/devices/iio:deviceX/in_pressure_offset KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -226,6 +236,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_magn_scale What: /sys/bus/iio/devices/iio:deviceX/in_magn_x_scale What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale What: /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale +What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale +What: /sys/bus/iio/devices/iio:deviceX/in_pressure_scale KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -245,6 +257,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibbias What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibbias What: /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibbias What: /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibbias +What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_calibbias +What: /sys/bus/iio/devices/iio:deviceX/in_pressure_calibbias KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -262,6 +276,8 @@ What /sys/bus/iio/devices/iio:deviceX/in_anglvel_y_calibscale What /sys/bus/iio/devices/iio:deviceX/in_anglvel_z_calibscale what /sys/bus/iio/devices/iio:deviceX/in_illuminance0_calibscale what /sys/bus/iio/devices/iio:deviceX/in_proximity0_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_calibscale +What: /sys/bus/iio/devices/iio:deviceX/in_pressure_calibscale KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -275,6 +291,8 @@ What: /sys/.../iio:deviceX/in_voltage-voltage_scale_available What: /sys/.../iio:deviceX/out_voltageX_scale_available What: /sys/.../iio:deviceX/out_altvoltageX_scale_available What: /sys/.../iio:deviceX/in_capacitance_scale_available +What: /sys/.../iio:deviceX/in_pressure_scale_available +What: /sys/.../iio:deviceX/in_pressureY_scale_available KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -694,6 +712,8 @@ What: /sys/.../buffer/scan_elements/in_voltageY_en What: /sys/.../buffer/scan_elements/in_voltageY-voltageZ_en What: /sys/.../buffer/scan_elements/in_incli_x_en What: /sys/.../buffer/scan_elements/in_incli_y_en +What: /sys/.../buffer/scan_elements/in_pressureY_en +What: /sys/.../buffer/scan_elements/in_pressure_en KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -707,6 +727,8 @@ What: /sys/.../buffer/scan_elements/in_voltageY_type What: /sys/.../buffer/scan_elements/in_voltage_type What: /sys/.../buffer/scan_elements/in_voltageY_supply_type What: /sys/.../buffer/scan_elements/in_timestamp_type +What: /sys/.../buffer/scan_elements/in_pressureY_type +What: /sys/.../buffer/scan_elements/in_pressure_type KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: @@ -751,6 +773,8 @@ What: /sys/.../buffer/scan_elements/in_magn_z_index What: /sys/.../buffer/scan_elements/in_incli_x_index What: /sys/.../buffer/scan_elements/in_incli_y_index What: /sys/.../buffer/scan_elements/in_timestamp_index +What: /sys/.../buffer/scan_elements/in_pressureY_index +What: /sys/.../buffer/scan_elements/in_pressure_index KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 060a4045be8..3dccd6c3a88 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -65,6 +65,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_CAPACITANCE] = "capacitance", [IIO_ALTVOLTAGE] = "altvoltage", [IIO_CCT] = "cct", + [IIO_PRESSURE] = "pressure", }; static const char * const iio_modifier_names[] = { diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index 87b196a2d69..88bf0f0d27b 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -28,6 +28,7 @@ enum iio_chan_type { IIO_CAPACITANCE, IIO_ALTVOLTAGE, IIO_CCT, + IIO_PRESSURE, }; enum iio_modifier { -- cgit v1.2.3 From 6807d7211327dbdd8df3692f3d26ca711514ba71 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 20 Nov 2012 13:36:00 +0000 Subject: iio: Factor out fixed point number parsing into its own function Factor out the code for parsing fixed point numbers into its own function and make this function globally available. This allows us to reuse the code to parse fixed point numbers in individual IIO drivers. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-core.c | 98 ++++++++++++++++++++++++++--------------- include/linux/iio/iio.h | 3 ++ 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 3dccd6c3a88..8848f16c547 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -408,6 +408,64 @@ static ssize_t iio_read_channel_info(struct device *dev, } } +/** + * iio_str_to_fixpoint() - Parse a fixed-point number from a string + * @str: The string to parse + * @fract_mult: Multiplier for the first decimal place, should be a power of 10 + * @integer: The integer part of the number + * @fract: The fractional part of the number + * + * Returns 0 on success, or a negative error code if the string could not be + * parsed. + */ +int iio_str_to_fixpoint(const char *str, int fract_mult, + int *integer, int *fract) +{ + int i = 0, f = 0; + bool integer_part = true, negative = false; + + if (str[0] == '-') { + negative = true; + str++; + } else if (str[0] == '+') { + str++; + } + + while (*str) { + if ('0' <= *str && *str <= '9') { + if (integer_part) { + i = i * 10 + *str - '0'; + } else { + f += fract_mult * (*str - '0'); + fract_mult /= 10; + } + } else if (*str == '\n') { + if (*(str + 1) == '\0') + break; + else + return -EINVAL; + } else if (*str == '.' && integer_part) { + integer_part = false; + } else { + return -EINVAL; + } + str++; + } + + if (negative) { + if (i) + i = -i; + else + f = -f; + } + + *integer = i; + *fract = f; + + return 0; +} +EXPORT_SYMBOL_GPL(iio_str_to_fixpoint); + static ssize_t iio_write_channel_info(struct device *dev, struct device_attribute *attr, const char *buf, @@ -415,8 +473,8 @@ static ssize_t iio_write_channel_info(struct device *dev, { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int ret, integer = 0, fract = 0, fract_mult = 100000; - bool integer_part = true, negative = false; + int ret, fract_mult = 100000; + int integer, fract; /* Assumes decimal - precision based on number of digits */ if (!indio_dev->info->write_raw) @@ -435,39 +493,9 @@ static ssize_t iio_write_channel_info(struct device *dev, return -EINVAL; } - if (buf[0] == '-') { - negative = true; - buf++; - } else if (buf[0] == '+') { - buf++; - } - - while (*buf) { - if ('0' <= *buf && *buf <= '9') { - if (integer_part) - integer = integer*10 + *buf - '0'; - else { - fract += fract_mult*(*buf - '0'); - fract_mult /= 10; - } - } else if (*buf == '\n') { - if (*(buf + 1) == '\0') - break; - else - return -EINVAL; - } else if (*buf == '.' && integer_part) { - integer_part = false; - } else { - return -EINVAL; - } - buf++; - } - if (negative) { - if (integer) - integer = -integer; - else - fract = -fract; - } + ret = iio_str_to_fixpoint(buf, fract_mult, &integer, &fract); + if (ret) + return ret; ret = indio_dev->info->write_raw(indio_dev, this_attr->c, integer, fract, this_attr->address); diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index adca93a999a..da8c776ba0b 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -620,6 +620,9 @@ static inline struct dentry *iio_get_debugfs_dentry(struct iio_dev *indio_dev) }; #endif +int iio_str_to_fixpoint(const char *str, int fract_mult, int *integer, + int *fract); + /** * IIO_DEGREE_TO_RAD() - Convert degree to rad * @deg: A value in degree -- cgit v1.2.3 From 2f3abe6cbb6c963ac790b40936b6761c9f0497b4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 20 Nov 2012 13:36:00 +0000 Subject: iio:imu: Add support for the ADIS16480 and similar IMUs This patch adds support for the ADIS16375, ADIS16480, ADIS16485, ADIS16488 6 degree to 10 degree of freedom IMUs. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/imu/Kconfig | 16 + drivers/iio/imu/Makefile | 2 + drivers/iio/imu/adis.c | 3 + drivers/iio/imu/adis16480.c | 925 +++++++++++++++++++++++++++++++++++++++++++ include/linux/iio/imu/adis.h | 4 + 5 files changed, 950 insertions(+) create mode 100644 drivers/iio/imu/adis16480.c diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig index c24410c873c..3d79a40e916 100644 --- a/drivers/iio/imu/Kconfig +++ b/drivers/iio/imu/Kconfig @@ -1,3 +1,19 @@ +# +# IIO imu drivers configuration +# +menu "Inertial measurement units" + +config ADIS16480 + tristate "Analog Devices ADIS16480 and similar IMU driver" + depends on SPI + select IIO_ADIS_LIB + select IIO_ADIS_LIB_BUFFER if IIO_BUFFER + help + Say yes here to build support for Analog Devices ADIS16375, ADIS16480, + ADIS16485, ADIS16488 inertial sensors. + +endmenu + config IIO_ADIS_LIB tristate help diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile index 97676ab5723..cfe57638f6f 100644 --- a/drivers/iio/imu/Makefile +++ b/drivers/iio/imu/Makefile @@ -2,6 +2,8 @@ # Makefile for Inertial Measurement Units # +obj-$(CONFIG_ADIS16480) += adis16480.o + adis_lib-y += adis.o adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_trigger.o adis_lib-$(CONFIG_IIO_ADIS_LIB_BUFFER) += adis_buffer.o diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c index c4ea04ffa60..911255d41c1 100644 --- a/drivers/iio/imu/adis.c +++ b/drivers/iio/imu/adis.c @@ -238,6 +238,9 @@ int adis_enable_irq(struct adis *adis, bool enable) int ret = 0; uint16_t msc; + if (adis->data->enable_irq) + return adis->data->enable_irq(adis, enable); + ret = adis_read_reg_16(adis, adis->data->msc_ctrl_reg, &msc); if (ret) goto error_ret; diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c new file mode 100644 index 00000000000..a080b351501 --- /dev/null +++ b/drivers/iio/imu/adis16480.c @@ -0,0 +1,925 @@ +/* + * ADIS16480 and similar IMUs driver + * + * Copyright 2012 Analog Devices 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define ADIS16480_PAGE_SIZE 0x80 + +#define ADIS16480_REG(page, reg) ((page) * ADIS16480_PAGE_SIZE + (reg)) + +#define ADIS16480_REG_PAGE_ID 0x00 /* Same address on each page */ +#define ADIS16480_REG_SEQ_CNT ADIS16480_REG(0x00, 0x06) +#define ADIS16480_REG_SYS_E_FLA ADIS16480_REG(0x00, 0x08) +#define ADIS16480_REG_DIAG_STS ADIS16480_REG(0x00, 0x0A) +#define ADIS16480_REG_ALM_STS ADIS16480_REG(0x00, 0x0C) +#define ADIS16480_REG_TEMP_OUT ADIS16480_REG(0x00, 0x0E) +#define ADIS16480_REG_X_GYRO_OUT ADIS16480_REG(0x00, 0x10) +#define ADIS16480_REG_Y_GYRO_OUT ADIS16480_REG(0x00, 0x14) +#define ADIS16480_REG_Z_GYRO_OUT ADIS16480_REG(0x00, 0x18) +#define ADIS16480_REG_X_ACCEL_OUT ADIS16480_REG(0x00, 0x1C) +#define ADIS16480_REG_Y_ACCEL_OUT ADIS16480_REG(0x00, 0x20) +#define ADIS16480_REG_Z_ACCEL_OUT ADIS16480_REG(0x00, 0x24) +#define ADIS16480_REG_X_MAGN_OUT ADIS16480_REG(0x00, 0x28) +#define ADIS16480_REG_Y_MAGN_OUT ADIS16480_REG(0x00, 0x2A) +#define ADIS16480_REG_Z_MAGN_OUT ADIS16480_REG(0x00, 0x2C) +#define ADIS16480_REG_BAROM_OUT ADIS16480_REG(0x00, 0x2E) +#define ADIS16480_REG_X_DELTAANG_OUT ADIS16480_REG(0x00, 0x40) +#define ADIS16480_REG_Y_DELTAANG_OUT ADIS16480_REG(0x00, 0x44) +#define ADIS16480_REG_Z_DELTAANG_OUT ADIS16480_REG(0x00, 0x48) +#define ADIS16480_REG_X_DELTAVEL_OUT ADIS16480_REG(0x00, 0x4C) +#define ADIS16480_REG_Y_DELTAVEL_OUT ADIS16480_REG(0x00, 0x50) +#define ADIS16480_REG_Z_DELTAVEL_OUT ADIS16480_REG(0x00, 0x54) +#define ADIS16480_REG_PROD_ID ADIS16480_REG(0x00, 0x7E) + +#define ADIS16480_REG_X_GYRO_SCALE ADIS16480_REG(0x02, 0x04) +#define ADIS16480_REG_Y_GYRO_SCALE ADIS16480_REG(0x02, 0x06) +#define ADIS16480_REG_Z_GYRO_SCALE ADIS16480_REG(0x02, 0x08) +#define ADIS16480_REG_X_ACCEL_SCALE ADIS16480_REG(0x02, 0x0A) +#define ADIS16480_REG_Y_ACCEL_SCALE ADIS16480_REG(0x02, 0x0C) +#define ADIS16480_REG_Z_ACCEL_SCALE ADIS16480_REG(0x02, 0x0E) +#define ADIS16480_REG_X_GYRO_BIAS ADIS16480_REG(0x02, 0x10) +#define ADIS16480_REG_Y_GYRO_BIAS ADIS16480_REG(0x02, 0x14) +#define ADIS16480_REG_Z_GYRO_BIAS ADIS16480_REG(0x02, 0x18) +#define ADIS16480_REG_X_ACCEL_BIAS ADIS16480_REG(0x02, 0x1C) +#define ADIS16480_REG_Y_ACCEL_BIAS ADIS16480_REG(0x02, 0x20) +#define ADIS16480_REG_Z_ACCEL_BIAS ADIS16480_REG(0x02, 0x24) +#define ADIS16480_REG_X_HARD_IRON ADIS16480_REG(0x02, 0x28) +#define ADIS16480_REG_Y_HARD_IRON ADIS16480_REG(0x02, 0x2A) +#define ADIS16480_REG_Z_HARD_IRON ADIS16480_REG(0x02, 0x2C) +#define ADIS16480_REG_BAROM_BIAS ADIS16480_REG(0x02, 0x40) +#define ADIS16480_REG_FLASH_CNT ADIS16480_REG(0x02, 0x7C) + +#define ADIS16480_REG_GLOB_CMD ADIS16480_REG(0x03, 0x02) +#define ADIS16480_REG_FNCTIO_CTRL ADIS16480_REG(0x03, 0x06) +#define ADIS16480_REG_GPIO_CTRL ADIS16480_REG(0x03, 0x08) +#define ADIS16480_REG_CONFIG ADIS16480_REG(0x03, 0x0A) +#define ADIS16480_REG_DEC_RATE ADIS16480_REG(0x03, 0x0C) +#define ADIS16480_REG_SLP_CNT ADIS16480_REG(0x03, 0x10) +#define ADIS16480_REG_FILTER_BNK0 ADIS16480_REG(0x03, 0x16) +#define ADIS16480_REG_FILTER_BNK1 ADIS16480_REG(0x03, 0x18) +#define ADIS16480_REG_ALM_CNFG0 ADIS16480_REG(0x03, 0x20) +#define ADIS16480_REG_ALM_CNFG1 ADIS16480_REG(0x03, 0x22) +#define ADIS16480_REG_ALM_CNFG2 ADIS16480_REG(0x03, 0x24) +#define ADIS16480_REG_XG_ALM_MAGN ADIS16480_REG(0x03, 0x28) +#define ADIS16480_REG_YG_ALM_MAGN ADIS16480_REG(0x03, 0x2A) +#define ADIS16480_REG_ZG_ALM_MAGN ADIS16480_REG(0x03, 0x2C) +#define ADIS16480_REG_XA_ALM_MAGN ADIS16480_REG(0x03, 0x2E) +#define ADIS16480_REG_YA_ALM_MAGN ADIS16480_REG(0x03, 0x30) +#define ADIS16480_REG_ZA_ALM_MAGN ADIS16480_REG(0x03, 0x32) +#define ADIS16480_REG_XM_ALM_MAGN ADIS16480_REG(0x03, 0x34) +#define ADIS16480_REG_YM_ALM_MAGN ADIS16480_REG(0x03, 0x36) +#define ADIS16480_REG_ZM_ALM_MAGN ADIS16480_REG(0x03, 0x38) +#define ADIS16480_REG_BR_ALM_MAGN ADIS16480_REG(0x03, 0x3A) +#define ADIS16480_REG_FIRM_REV ADIS16480_REG(0x03, 0x78) +#define ADIS16480_REG_FIRM_DM ADIS16480_REG(0x03, 0x7A) +#define ADIS16480_REG_FIRM_Y ADIS16480_REG(0x03, 0x7C) + +#define ADIS16480_REG_SERIAL_NUM ADIS16480_REG(0x04, 0x20) + +/* Each filter coefficent bank spans two pages */ +#define ADIS16480_FIR_COEF(page) (x < 60 ? ADIS16480_REG(page, (x) + 8) : \ + ADIS16480_REG((page) + 1, (x) - 60 + 8)) +#define ADIS16480_FIR_COEF_A(x) ADIS16480_FIR_COEF(0x05, (x)) +#define ADIS16480_FIR_COEF_B(x) ADIS16480_FIR_COEF(0x07, (x)) +#define ADIS16480_FIR_COEF_C(x) ADIS16480_FIR_COEF(0x09, (x)) +#define ADIS16480_FIR_COEF_D(x) ADIS16480_FIR_COEF(0x0B, (x)) + +struct adis16480_chip_info { + unsigned int num_channels; + const struct iio_chan_spec *channels; +}; + +struct adis16480 { + const struct adis16480_chip_info *chip_info; + + struct adis adis; +}; + +#ifdef CONFIG_DEBUG_FS + +static ssize_t adis16480_show_firmware_revision(struct file *file, + char __user *userbuf, size_t count, loff_t *ppos) +{ + struct adis16480 *adis16480 = file->private_data; + char buf[6]; + size_t len; + u16 rev; + int ret; + + ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_FIRM_REV, &rev); + if (ret < 0) + return ret; + + len = snprintf(buf, sizeof(buf), "%x.%x\n", rev >> 8, rev & 0xff); + + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} + +static const struct file_operations adis16480_firmware_revision_fops = { + .open = simple_open, + .read = adis16480_show_firmware_revision, + .llseek = default_llseek, + .owner = THIS_MODULE, +}; + +static ssize_t adis16480_show_firmware_date(struct file *file, + char __user *userbuf, size_t count, loff_t *ppos) +{ + struct adis16480 *adis16480 = file->private_data; + u16 md, year; + char buf[12]; + size_t len; + int ret; + + ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_FIRM_Y, &year); + if (ret < 0) + return ret; + + ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_FIRM_DM, &md); + if (ret < 0) + return ret; + + len = snprintf(buf, sizeof(buf), "%.2x-%.2x-%.4x\n", + md >> 8, md & 0xff, year); + + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} + +static const struct file_operations adis16480_firmware_date_fops = { + .open = simple_open, + .read = adis16480_show_firmware_date, + .llseek = default_llseek, + .owner = THIS_MODULE, +}; + +static int adis16480_show_serial_number(void *arg, u64 *val) +{ + struct adis16480 *adis16480 = arg; + u16 serial; + int ret; + + ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_SERIAL_NUM, + &serial); + if (ret < 0) + return ret; + + *val = serial; + + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(adis16480_serial_number_fops, + adis16480_show_serial_number, NULL, "0x%.4llx\n"); + +static int adis16480_show_product_id(void *arg, u64 *val) +{ + struct adis16480 *adis16480 = arg; + u16 prod_id; + int ret; + + ret = adis_read_reg_16(&adis16480->adis, ADIS16480_REG_PROD_ID, + &prod_id); + if (ret < 0) + return ret; + + *val = prod_id; + + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(adis16480_product_id_fops, + adis16480_show_product_id, NULL, "%llu\n"); + +static int adis16480_show_flash_count(void *arg, u64 *val) +{ + struct adis16480 *adis16480 = arg; + u32 flash_count; + int ret; + + ret = adis_read_reg_32(&adis16480->adis, ADIS16480_REG_FLASH_CNT, + &flash_count); + if (ret < 0) + return ret; + + *val = flash_count; + + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(adis16480_flash_count_fops, + adis16480_show_flash_count, NULL, "%lld\n"); + +static int adis16480_debugfs_init(struct iio_dev *indio_dev) +{ + struct adis16480 *adis16480 = iio_priv(indio_dev); + + debugfs_create_file("firmware_revision", 0400, + indio_dev->debugfs_dentry, adis16480, + &adis16480_firmware_revision_fops); + debugfs_create_file("firmware_date", 0400, indio_dev->debugfs_dentry, + adis16480, &adis16480_firmware_date_fops); + debugfs_create_file("serial_number", 0400, indio_dev->debugfs_dentry, + adis16480, &adis16480_serial_number_fops); + debugfs_create_file("product_id", 0400, indio_dev->debugfs_dentry, + adis16480, &adis16480_product_id_fops); + debugfs_create_file("flash_count", 0400, indio_dev->debugfs_dentry, + adis16480, &adis16480_flash_count_fops); + + return 0; +} + +#else + +static int adis16480_debugfs_init(struct iio_dev *indio_dev) +{ + return 0; +} + +#endif + +static int adis16480_set_freq(struct adis16480 *st, unsigned int freq) +{ + unsigned int t; + + t = 2460000 / freq; + if (t > 2048) + t = 2048; + + if (t != 0) + t--; + + return adis_write_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, t); +} + +static int adis16480_get_freq(struct adis16480 *st, unsigned int *freq) +{ + uint16_t t; + int ret; + + ret = adis_read_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, &t); + if (ret < 0) + return ret; + + *freq = 2460000 / (t + 1); + + return 0; +} + +static ssize_t adis16480_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adis16480 *st = iio_priv(indio_dev); + unsigned int freq; + int ret; + + ret = adis16480_get_freq(st, &freq); + if (ret < 0) + return ret; + + return sprintf(buf, "%d.%.3d\n", freq / 1000, freq % 1000); +} + +static ssize_t adis16480_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct adis16480 *st = iio_priv(indio_dev); + int freq_int, freq_fract; + long val; + int ret; + + ret = iio_str_to_fixpoint(buf, 100, &freq_int, &freq_fract); + if (ret) + return ret; + + val = freq_int * 1000 + freq_fract; + + if (val <= 0) + return -EINVAL; + + ret = adis16480_set_freq(st, val); + + return ret ? ret : len; +} + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + adis16480_read_frequency, + adis16480_write_frequency); + +enum { + ADIS16480_SCAN_GYRO_X, + ADIS16480_SCAN_GYRO_Y, + ADIS16480_SCAN_GYRO_Z, + ADIS16480_SCAN_ACCEL_X, + ADIS16480_SCAN_ACCEL_Y, + ADIS16480_SCAN_ACCEL_Z, + ADIS16480_SCAN_MAGN_X, + ADIS16480_SCAN_MAGN_Y, + ADIS16480_SCAN_MAGN_Z, + ADIS16480_SCAN_BARO, + ADIS16480_SCAN_TEMP, +}; + +static const unsigned int adis16480_calibbias_regs[] = { + [ADIS16480_SCAN_GYRO_X] = ADIS16480_REG_X_GYRO_BIAS, + [ADIS16480_SCAN_GYRO_Y] = ADIS16480_REG_Y_GYRO_BIAS, + [ADIS16480_SCAN_GYRO_Z] = ADIS16480_REG_Z_GYRO_BIAS, + [ADIS16480_SCAN_ACCEL_X] = ADIS16480_REG_X_ACCEL_BIAS, + [ADIS16480_SCAN_ACCEL_Y] = ADIS16480_REG_Y_ACCEL_BIAS, + [ADIS16480_SCAN_ACCEL_Z] = ADIS16480_REG_Z_ACCEL_BIAS, + [ADIS16480_SCAN_MAGN_X] = ADIS16480_REG_X_HARD_IRON, + [ADIS16480_SCAN_MAGN_Y] = ADIS16480_REG_Y_HARD_IRON, + [ADIS16480_SCAN_MAGN_Z] = ADIS16480_REG_Z_HARD_IRON, + [ADIS16480_SCAN_BARO] = ADIS16480_REG_BAROM_BIAS, +}; + +static const unsigned int adis16480_calibscale_regs[] = { + [ADIS16480_SCAN_GYRO_X] = ADIS16480_REG_X_GYRO_SCALE, + [ADIS16480_SCAN_GYRO_Y] = ADIS16480_REG_Y_GYRO_SCALE, + [ADIS16480_SCAN_GYRO_Z] = ADIS16480_REG_Z_GYRO_SCALE, + [ADIS16480_SCAN_ACCEL_X] = ADIS16480_REG_X_ACCEL_SCALE, + [ADIS16480_SCAN_ACCEL_Y] = ADIS16480_REG_Y_ACCEL_SCALE, + [ADIS16480_SCAN_ACCEL_Z] = ADIS16480_REG_Z_ACCEL_SCALE, +}; + +static int adis16480_set_calibbias(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int bias) +{ + unsigned int reg = adis16480_calibbias_regs[chan->scan_index]; + struct adis16480 *st = iio_priv(indio_dev); + + switch (chan->type) { + case IIO_MAGN: + case IIO_PRESSURE: + if (bias < -0x8000 || bias >= 0x8000) + return -EINVAL; + return adis_write_reg_16(&st->adis, reg, bias); + case IIO_ANGL_VEL: + case IIO_ACCEL: + return adis_write_reg_32(&st->adis, reg, bias); + default: + break; + } + + return -EINVAL; +} + +static int adis16480_get_calibbias(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *bias) +{ + unsigned int reg = adis16480_calibbias_regs[chan->scan_index]; + struct adis16480 *st = iio_priv(indio_dev); + uint16_t val16; + uint32_t val32; + int ret; + + switch (chan->type) { + case IIO_MAGN: + case IIO_PRESSURE: + ret = adis_read_reg_16(&st->adis, reg, &val16); + *bias = sign_extend32(val16, 15); + break; + case IIO_ANGL_VEL: + case IIO_ACCEL: + ret = adis_read_reg_32(&st->adis, reg, &val32); + *bias = sign_extend32(val32, 31); + break; + default: + ret = -EINVAL; + } + + if (ret < 0) + return ret; + + return IIO_VAL_INT; +} + +static int adis16480_set_calibscale(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int scale) +{ + unsigned int reg = adis16480_calibscale_regs[chan->scan_index]; + struct adis16480 *st = iio_priv(indio_dev); + + if (scale < -0x8000 || scale >= 0x8000) + return -EINVAL; + + return adis_write_reg_16(&st->adis, reg, scale); +} + +static int adis16480_get_calibscale(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *scale) +{ + unsigned int reg = adis16480_calibscale_regs[chan->scan_index]; + struct adis16480 *st = iio_priv(indio_dev); + uint16_t val16; + int ret; + + ret = adis_read_reg_16(&st->adis, reg, &val16); + if (ret < 0) + return ret; + + *scale = sign_extend32(val16, 15); + return IIO_VAL_INT; +} + +static const unsigned int adis16480_def_filter_freqs[] = { + 310, + 55, + 275, + 63, +}; + +static const unsigned int ad16480_filter_data[][2] = { + [ADIS16480_SCAN_GYRO_X] = { ADIS16480_REG_FILTER_BNK0, 0 }, + [ADIS16480_SCAN_GYRO_Y] = { ADIS16480_REG_FILTER_BNK0, 3 }, + [ADIS16480_SCAN_GYRO_Z] = { ADIS16480_REG_FILTER_BNK0, 6 }, + [ADIS16480_SCAN_ACCEL_X] = { ADIS16480_REG_FILTER_BNK0, 9 }, + [ADIS16480_SCAN_ACCEL_Y] = { ADIS16480_REG_FILTER_BNK0, 12 }, + [ADIS16480_SCAN_ACCEL_Z] = { ADIS16480_REG_FILTER_BNK1, 0 }, + [ADIS16480_SCAN_MAGN_X] = { ADIS16480_REG_FILTER_BNK1, 3 }, + [ADIS16480_SCAN_MAGN_Y] = { ADIS16480_REG_FILTER_BNK1, 6 }, + [ADIS16480_SCAN_MAGN_Z] = { ADIS16480_REG_FILTER_BNK1, 9 }, +}; + +static int adis16480_get_filter_freq(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *freq) +{ + struct adis16480 *st = iio_priv(indio_dev); + unsigned int enable_mask, offset, reg; + uint16_t val; + int ret; + + reg = ad16480_filter_data[chan->scan_index][0]; + offset = ad16480_filter_data[chan->scan_index][1]; + enable_mask = BIT(offset + 2); + + ret = adis_read_reg_16(&st->adis, reg, &val); + if (ret < 0) + return ret; + + if (!(val & enable_mask)) + *freq = 0; + else + *freq = adis16480_def_filter_freqs[(val >> offset) & 0x3]; + + return IIO_VAL_INT; +} + +static int adis16480_set_filter_freq(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, unsigned int freq) +{ + struct adis16480 *st = iio_priv(indio_dev); + unsigned int enable_mask, offset, reg; + unsigned int diff, best_diff; + unsigned int i, best_freq; + uint16_t val; + int ret; + + reg = ad16480_filter_data[chan->scan_index][0]; + offset = ad16480_filter_data[chan->scan_index][1]; + enable_mask = BIT(offset + 2); + + ret = adis_read_reg_16(&st->adis, reg, &val); + if (ret < 0) + return ret; + + if (freq == 0) { + val &= ~enable_mask; + } else { + best_freq = 0; + best_diff = 310; + for (i = 0; i < ARRAY_SIZE(adis16480_def_filter_freqs); i++) { + if (adis16480_def_filter_freqs[i] >= freq) { + diff = adis16480_def_filter_freqs[i] - freq; + if (diff < best_diff) { + best_diff = diff; + best_freq = i; + } + } + } + + val &= ~(0x3 << offset); + val |= best_freq << offset; + val |= enable_mask; + } + + return adis_write_reg_16(&st->adis, reg, val); +} + +static int adis16480_read_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *val, int *val2, long info) +{ + switch (info) { + case IIO_CHAN_INFO_RAW: + return adis_single_conversion(indio_dev, chan, 0, val); + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_ANGL_VEL: + *val = 0; + *val2 = IIO_DEGREE_TO_RAD(20000); /* 0.02 degree/sec */ + return IIO_VAL_INT_PLUS_MICRO; + case IIO_ACCEL: + *val = 0; + *val2 = IIO_G_TO_M_S_2(800); /* 0.8 mg */ + return IIO_VAL_INT_PLUS_MICRO; + case IIO_MAGN: + *val = 0; + *val2 = 100; /* 0.0001 gauss */ + return IIO_VAL_INT_PLUS_MICRO; + case IIO_TEMP: + *val = 5; + *val2 = 650000; /* 5.65 milli degree Celsius */ + return IIO_VAL_INT_PLUS_MICRO; + case IIO_PRESSURE: + *val = 0; + *val2 = 4000; /* 40ubar = 0.004 kPa */ + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_OFFSET: + /* Only the temperature channel has a offset */ + *val = 4425; /* 25 degree Celsius = 0x0000 */ + return IIO_VAL_INT; + case IIO_CHAN_INFO_CALIBBIAS: + return adis16480_get_calibbias(indio_dev, chan, val); + case IIO_CHAN_INFO_CALIBSCALE: + return adis16480_get_calibscale(indio_dev, chan, val); + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + return adis16480_get_filter_freq(indio_dev, chan, val); + default: + return -EINVAL; + } +} + +static int adis16480_write_raw(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int val, int val2, long info) +{ + switch (info) { + case IIO_CHAN_INFO_CALIBBIAS: + return adis16480_set_calibbias(indio_dev, chan, val); + case IIO_CHAN_INFO_CALIBSCALE: + return adis16480_set_calibscale(indio_dev, chan, val); + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: + return adis16480_set_filter_freq(indio_dev, chan, val); + default: + return -EINVAL; + } +} + +#define ADIS16480_MOD_CHANNEL(_type, _mod, _address, _si, _info, _bits) \ + { \ + .type = (_type), \ + .modified = 1, \ + .channel2 = (_mod), \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + _info, \ + .address = (_address), \ + .scan_index = (_si), \ + .scan_type = { \ + .sign = 's', \ + .realbits = (_bits), \ + .storagebits = (_bits), \ + .endianness = IIO_BE, \ + }, \ + } + +#define ADIS16480_GYRO_CHANNEL(_mod) \ + ADIS16480_MOD_CHANNEL(IIO_ANGL_VEL, IIO_MOD_ ## _mod, \ + ADIS16480_REG_ ## _mod ## _GYRO_OUT, ADIS16480_SCAN_GYRO_ ## _mod, \ + IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, \ + 32) + +#define ADIS16480_ACCEL_CHANNEL(_mod) \ + ADIS16480_MOD_CHANNEL(IIO_ACCEL, IIO_MOD_ ## _mod, \ + ADIS16480_REG_ ## _mod ## _ACCEL_OUT, ADIS16480_SCAN_ACCEL_ ## _mod, \ + IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT, \ + 32) + +#define ADIS16480_MAGN_CHANNEL(_mod) \ + ADIS16480_MOD_CHANNEL(IIO_MAGN, IIO_MOD_ ## _mod, \ + ADIS16480_REG_ ## _mod ## _MAGN_OUT, ADIS16480_SCAN_MAGN_ ## _mod, \ + IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SEPARATE_BIT, \ + 16) + +#define ADIS16480_PRESSURE_CHANNEL() \ + { \ + .type = IIO_PRESSURE, \ + .indexed = 1, \ + .channel = 0, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ + .address = ADIS16480_REG_BAROM_OUT, \ + .scan_index = ADIS16480_SCAN_BARO, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 32, \ + .storagebits = 32, \ + .endianness = IIO_BE, \ + }, \ + } + +#define ADIS16480_TEMP_CHANNEL() { \ + .type = IIO_TEMP, \ + .indexed = 1, \ + .channel = 0, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \ + .address = ADIS16480_REG_TEMP_OUT, \ + .scan_index = ADIS16480_SCAN_TEMP, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .endianness = IIO_BE, \ + }, \ + } + +static const struct iio_chan_spec adis16480_channels[] = { + ADIS16480_GYRO_CHANNEL(X), + ADIS16480_GYRO_CHANNEL(Y), + ADIS16480_GYRO_CHANNEL(Z), + ADIS16480_ACCEL_CHANNEL(X), + ADIS16480_ACCEL_CHANNEL(Y), + ADIS16480_ACCEL_CHANNEL(Z), + ADIS16480_MAGN_CHANNEL(X), + ADIS16480_MAGN_CHANNEL(Y), + ADIS16480_MAGN_CHANNEL(Z), + ADIS16480_PRESSURE_CHANNEL(), + ADIS16480_TEMP_CHANNEL(), + IIO_CHAN_SOFT_TIMESTAMP(11) +}; + +static const struct iio_chan_spec adis16485_channels[] = { + ADIS16480_GYRO_CHANNEL(X), + ADIS16480_GYRO_CHANNEL(Y), + ADIS16480_GYRO_CHANNEL(Z), + ADIS16480_ACCEL_CHANNEL(X), + ADIS16480_ACCEL_CHANNEL(Y), + ADIS16480_ACCEL_CHANNEL(Z), + ADIS16480_TEMP_CHANNEL(), + IIO_CHAN_SOFT_TIMESTAMP(7) +}; + +enum adis16480_variant { + ADIS16375, + ADIS16480, + ADIS16485, + ADIS16488, +}; + +static const struct adis16480_chip_info adis16480_chip_info[] = { + [ADIS16375] = { + .channels = adis16485_channels, + .num_channels = ARRAY_SIZE(adis16485_channels), + }, + [ADIS16480] = { + .channels = adis16480_channels, + .num_channels = ARRAY_SIZE(adis16480_channels), + }, + [ADIS16485] = { + .channels = adis16485_channels, + .num_channels = ARRAY_SIZE(adis16485_channels), + }, + [ADIS16488] = { + .channels = adis16480_channels, + .num_channels = ARRAY_SIZE(adis16480_channels), + }, +}; + +static struct attribute *adis16480_attributes[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16480_attribute_group = { + .attrs = adis16480_attributes, +}; + +static const struct iio_info adis16480_info = { + .attrs = &adis16480_attribute_group, + .read_raw = &adis16480_read_raw, + .write_raw = &adis16480_write_raw, + .update_scan_mode = adis_update_scan_mode, + .driver_module = THIS_MODULE, +}; + +static int adis16480_stop_device(struct iio_dev *indio_dev) +{ + struct adis16480 *st = iio_priv(indio_dev); + int ret; + + ret = adis_write_reg_16(&st->adis, ADIS16480_REG_SLP_CNT, BIT(9)); + if (ret) + dev_err(&indio_dev->dev, + "Could not power down device: %d\n", ret); + + return ret; +} + +static int adis16480_enable_irq(struct adis *adis, bool enable) +{ + return adis_write_reg_16(adis, ADIS16480_REG_FNCTIO_CTRL, + enable ? BIT(3) : 0); +} + +static int adis16480_initial_setup(struct iio_dev *indio_dev) +{ + struct adis16480 *st = iio_priv(indio_dev); + uint16_t prod_id; + unsigned int device_id; + int ret; + + adis_reset(&st->adis); + msleep(70); + + ret = adis_write_reg_16(&st->adis, ADIS16480_REG_GLOB_CMD, BIT(1)); + if (ret) + return ret; + msleep(30); + + ret = adis_check_status(&st->adis); + if (ret) + return ret; + + ret = adis_read_reg_16(&st->adis, ADIS16480_REG_PROD_ID, &prod_id); + if (ret) + return ret; + + sscanf(indio_dev->name, "adis%u\n", &device_id); + + if (prod_id != device_id) + dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.", + device_id, prod_id); + + return 0; +} + +#define ADIS16480_DIAG_STAT_XGYRO_FAIL 0 +#define ADIS16480_DIAG_STAT_YGYRO_FAIL 1 +#define ADIS16480_DIAG_STAT_ZGYRO_FAIL 2 +#define ADIS16480_DIAG_STAT_XACCL_FAIL 3 +#define ADIS16480_DIAG_STAT_YACCL_FAIL 4 +#define ADIS16480_DIAG_STAT_ZACCL_FAIL 5 +#define ADIS16480_DIAG_STAT_XMAGN_FAIL 8 +#define ADIS16480_DIAG_STAT_YMAGN_FAIL 9 +#define ADIS16480_DIAG_STAT_ZMAGN_FAIL 10 +#define ADIS16480_DIAG_STAT_BARO_FAIL 11 + +static const char * const adis16480_status_error_msgs[] = { + [ADIS16480_DIAG_STAT_XGYRO_FAIL] = "X-axis gyroscope self-test failure", + [ADIS16480_DIAG_STAT_YGYRO_FAIL] = "Y-axis gyroscope self-test failure", + [ADIS16480_DIAG_STAT_ZGYRO_FAIL] = "Z-axis gyroscope self-test failure", + [ADIS16480_DIAG_STAT_XACCL_FAIL] = "X-axis accelerometer self-test failure", + [ADIS16480_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure", + [ADIS16480_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure", + [ADIS16480_DIAG_STAT_XMAGN_FAIL] = "X-axis magnetometer self-test failure", + [ADIS16480_DIAG_STAT_YMAGN_FAIL] = "Y-axis magnetometer self-test failure", + [ADIS16480_DIAG_STAT_ZMAGN_FAIL] = "Z-axis magnetometer self-test failure", + [ADIS16480_DIAG_STAT_BARO_FAIL] = "Barometer self-test failure", +}; + +static const struct adis_data adis16480_data = { + .diag_stat_reg = ADIS16480_REG_DIAG_STS, + .glob_cmd_reg = ADIS16480_REG_GLOB_CMD, + .has_paging = true, + + .read_delay = 5, + .write_delay = 5, + + .status_error_msgs = adis16480_status_error_msgs, + .status_error_mask = BIT(ADIS16480_DIAG_STAT_XGYRO_FAIL) | + BIT(ADIS16480_DIAG_STAT_YGYRO_FAIL) | + BIT(ADIS16480_DIAG_STAT_ZGYRO_FAIL) | + BIT(ADIS16480_DIAG_STAT_XACCL_FAIL) | + BIT(ADIS16480_DIAG_STAT_YACCL_FAIL) | + BIT(ADIS16480_DIAG_STAT_ZACCL_FAIL) | + BIT(ADIS16480_DIAG_STAT_XMAGN_FAIL) | + BIT(ADIS16480_DIAG_STAT_YMAGN_FAIL) | + BIT(ADIS16480_DIAG_STAT_ZMAGN_FAIL) | + BIT(ADIS16480_DIAG_STAT_BARO_FAIL), + + .enable_irq = adis16480_enable_irq, +}; + +static int adis16480_probe(struct spi_device *spi) +{ + const struct spi_device_id *id = spi_get_device_id(spi); + struct iio_dev *indio_dev; + struct adis16480 *st; + int ret; + + indio_dev = iio_device_alloc(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + spi_set_drvdata(spi, indio_dev); + + st = iio_priv(indio_dev); + + st->chip_info = &adis16480_chip_info[id->driver_data]; + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->channels = st->chip_info->channels; + indio_dev->num_channels = st->chip_info->num_channels; + indio_dev->info = &adis16480_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis_init(&st->adis, indio_dev, spi, &adis16480_data); + if (ret) + goto error_free_dev; + + ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); + if (ret) + goto error_free_dev; + + ret = adis16480_initial_setup(indio_dev); + if (ret) + goto error_cleanup_buffer; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_stop_device; + + adis16480_debugfs_init(indio_dev); + + return 0; + +error_stop_device: + adis16480_stop_device(indio_dev); +error_cleanup_buffer: + adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); +error_free_dev: + iio_device_free(indio_dev); + return ret; +} + +static int adis16480_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adis16480 *st = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + adis16480_stop_device(indio_dev); + + adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); + + iio_device_free(indio_dev); + + return 0; +} + +static const struct spi_device_id adis16480_ids[] = { + { "adis16375", ADIS16375 }, + { "adis16480", ADIS16480 }, + { "adis16485", ADIS16485 }, + { "adis16488", ADIS16488 }, + { } +}; +MODULE_DEVICE_TABLE(spi, adis16480_ids); + +static struct spi_driver adis16480_driver = { + .driver = { + .name = "adis16480", + .owner = THIS_MODULE, + }, + .id_table = adis16480_ids, + .probe = adis16480_probe, + .remove = adis16480_remove, +}; +module_spi_driver(adis16480_driver); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Analog Devices ADIS16480 IMU driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index e82cd0827e9..ff781dca2e9 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -20,6 +20,8 @@ #define ADIS_PAGE_SIZE 0x80 #define ADIS_REG_PAGE_ID 0x00 +struct adis; + /** * struct adis_data - ADIS chip variant specific data * @read_delay: SPI delay for read operations in us @@ -44,6 +46,8 @@ struct adis_data { const char * const *status_error_msgs; unsigned int status_error_mask; + int (*enable_irq)(struct adis *adis, bool enable); + bool has_paging; }; -- cgit v1.2.3 From f3fd0c8a7fc1e4f3107a09a75e622781d3007b56 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 21 Nov 2012 00:21:39 +0100 Subject: ACPI: Allow ACPI handles of devices to be initialized in advance Currently, the ACPI handles of devices are initialized from within device_add(), by acpi_bind_one() called from acpi_platform_notify() which first uses the .find_device() routine provided by the device's bus type to find the matching device node in the ACPI namespace. This is a source of some computational overhead and, moreover, the correctness of the result depends on the implementation of .find_device() which is known to fail occasionally for some bus types (e.g. PCI). In some cases, however, the corresponding ACPI device node is known already before calling device_add() for the given struct device object and the whole .find_device() dance in acpi_platform_notify() is then simply unnecessary. For this reason, make it possible to initialize the ACPI handles of devices before calling device_add() for them. Modify acpi_platform_notify() to call acpi_bind_one() in advance to check the device's existing ACPI handle and skip the .find_device() search if that is successful. Change acpi_bind_one() accordingly. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg --- drivers/acpi/glue.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 2f3849aedc9..3e75d6e5a46 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -130,46 +130,59 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) { struct acpi_device *acpi_dev; acpi_status status; - struct acpi_device_physical_node *physical_node; + struct acpi_device_physical_node *physical_node, *pn; char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2]; int retval = -EINVAL; if (dev->acpi_handle) { - dev_warn(dev, "Drivers changed 'acpi_handle'\n"); - return -EINVAL; + if (handle) { + dev_warn(dev, "ACPI handle is already set\n"); + return -EINVAL; + } else { + handle = dev->acpi_handle; + } } + if (!handle) + return -EINVAL; get_device(dev); status = acpi_bus_get_device(handle, &acpi_dev); if (ACPI_FAILURE(status)) goto err; - physical_node = kzalloc(sizeof(struct acpi_device_physical_node), - GFP_KERNEL); + physical_node = kzalloc(sizeof(*physical_node), GFP_KERNEL); if (!physical_node) { retval = -ENOMEM; goto err; } mutex_lock(&acpi_dev->physical_node_lock); + + /* Sanity check. */ + list_for_each_entry(pn, &acpi_dev->physical_node_list, node) + if (pn->dev == dev) { + dev_warn(dev, "Already associated with ACPI node\n"); + goto err_free; + } + /* allocate physical node id according to physical_node_id_bitmap */ physical_node->node_id = find_first_zero_bit(acpi_dev->physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE); if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) { retval = -ENOSPC; - mutex_unlock(&acpi_dev->physical_node_lock); - kfree(physical_node); - goto err; + goto err_free; } set_bit(physical_node->node_id, acpi_dev->physical_node_id_bitmap); physical_node->dev = dev; list_add_tail(&physical_node->node, &acpi_dev->physical_node_list); acpi_dev->physical_node_count++; + mutex_unlock(&acpi_dev->physical_node_lock); - dev->acpi_handle = handle; + if (!dev->acpi_handle) + dev->acpi_handle = handle; if (!physical_node->node_id) strcpy(physical_node_name, PHYSICAL_NODE_STRING); @@ -187,8 +200,14 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) return 0; err: + dev->acpi_handle = NULL; put_device(dev); return retval; + + err_free: + mutex_unlock(&acpi_dev->physical_node_lock); + kfree(physical_node); + goto err; } static int acpi_unbind_one(struct device *dev) @@ -247,6 +266,10 @@ static int acpi_platform_notify(struct device *dev) acpi_handle handle; int ret = -EINVAL; + ret = acpi_bind_one(dev, NULL); + if (!ret) + goto out; + if (!dev->bus || !dev->parent) { /* bridge devices genernally haven't bus or parent */ ret = acpi_find_bridge_device(dev, &handle); @@ -260,10 +283,11 @@ static int acpi_platform_notify(struct device *dev) } if ((ret = type->find_device(dev, &handle)) != 0) DBG("Can't get handler for %s\n", dev_name(dev)); - end: + end: if (!ret) acpi_bind_one(dev, handle); + out: #if ACPI_GLUE_DEBUG if (!ret) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; -- cgit v1.2.3 From 95f8a082b9b1ead0c2859f2a7b1ac91ff63d8765 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 21 Nov 2012 00:21:50 +0100 Subject: ACPI / driver core: Introduce struct acpi_dev_node and related macros To avoid adding an ACPI handle pointer to struct device on architectures that don't use ACPI, or generally when CONFIG_ACPI is not set, in which cases that pointer is useless, define struct acpi_dev_node that will contain the handle pointer if CONFIG_ACPI is set and will be empty otherwise and use it to represent the ACPI device node field in struct device. In addition to that define macros for reading and setting the ACPI handle of a device that don't generate code when CONFIG_ACPI is unset. Modify the ACPI subsystem to use those macros instead of referring to the given device's ACPI handle directly. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg Acked-by: Greg Kroah-Hartman --- drivers/acpi/glue.c | 16 ++++++++-------- drivers/acpi/scan.c | 4 ++-- include/acpi/acpi_bus.h | 2 +- include/linux/device.h | 18 ++++++++++++++++-- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 3e75d6e5a46..01551840d23 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -134,12 +134,12 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2]; int retval = -EINVAL; - if (dev->acpi_handle) { + if (ACPI_HANDLE(dev)) { if (handle) { dev_warn(dev, "ACPI handle is already set\n"); return -EINVAL; } else { - handle = dev->acpi_handle; + handle = ACPI_HANDLE(dev); } } if (!handle) @@ -181,8 +181,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) mutex_unlock(&acpi_dev->physical_node_lock); - if (!dev->acpi_handle) - dev->acpi_handle = handle; + if (!ACPI_HANDLE(dev)) + ACPI_HANDLE_SET(dev, acpi_dev->handle); if (!physical_node->node_id) strcpy(physical_node_name, PHYSICAL_NODE_STRING); @@ -200,7 +200,7 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) return 0; err: - dev->acpi_handle = NULL; + ACPI_HANDLE_SET(dev, NULL); put_device(dev); return retval; @@ -217,10 +217,10 @@ static int acpi_unbind_one(struct device *dev) acpi_status status; struct list_head *node, *next; - if (!dev->acpi_handle) + if (!ACPI_HANDLE(dev)) return 0; - status = acpi_bus_get_device(dev->acpi_handle, &acpi_dev); + status = acpi_bus_get_device(ACPI_HANDLE(dev), &acpi_dev); if (ACPI_FAILURE(status)) goto err; @@ -246,7 +246,7 @@ static int acpi_unbind_one(struct device *dev) sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name); sysfs_remove_link(&dev->kobj, "firmware_node"); - dev->acpi_handle = NULL; + ACPI_HANDLE_SET(dev, NULL); /* acpi_bind_one increase refcnt by one */ put_device(dev); kfree(entry); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index d842569395a..e92ca67d0e4 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -386,8 +386,8 @@ const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids, { struct acpi_device *adev; - if (!ids || !dev->acpi_handle - || ACPI_FAILURE(acpi_bus_get_device(dev->acpi_handle, &adev))) + if (!ids || !ACPI_HANDLE(dev) + || ACPI_FAILURE(acpi_bus_get_device(ACPI_HANDLE(dev), &adev))) return NULL; return __acpi_match_device(adev, ids); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index bb1537c5e67..d1659904f2a 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -410,7 +410,7 @@ acpi_handle acpi_get_child(acpi_handle, u64); int acpi_is_root_bridge(acpi_handle); acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); -#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->acpi_handle)) +#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev)) int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state); int acpi_disable_wakeup_device_power(struct acpi_device *dev); diff --git a/include/linux/device.h b/include/linux/device.h index cc3aee57a46..05292e48834 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -578,6 +578,12 @@ struct device_dma_parameters { unsigned long segment_boundary_mask; }; +struct acpi_dev_node { +#ifdef CONFIG_ACPI + void *handle; +#endif +}; + /** * struct device - The basic device structure * @parent: The device's "parent" device, the device to which it is attached. @@ -618,7 +624,7 @@ struct device_dma_parameters { * @dma_mem: Internal for coherent mem override. * @archdata: For arch-specific additions. * @of_node: Associated device tree node. - * @acpi_handle: Associated ACPI device node's namespace handle. + * @acpi_node: Associated ACPI device node. * @devt: For creating the sysfs "dev". * @id: device instance * @devres_lock: Spinlock to protect the resource of the device. @@ -683,7 +689,7 @@ struct device { struct dev_archdata archdata; struct device_node *of_node; /* associated device tree node */ - void *acpi_handle; /* associated ACPI device node */ + struct acpi_dev_node acpi_node; /* associated ACPI device node */ dev_t devt; /* dev_t, creates the sysfs "dev" */ u32 id; /* device instance */ @@ -704,6 +710,14 @@ static inline struct device *kobj_to_dev(struct kobject *kobj) return container_of(kobj, struct device, kobj); } +#ifdef CONFIG_ACPI +#define ACPI_HANDLE(dev) ((dev)->acpi_node.handle) +#define ACPI_HANDLE_SET(dev, _handle_) (dev)->acpi_node.handle = (_handle_) +#else +#define ACPI_HANDLE(dev) (NULL) +#define ACPI_HANDLE_SET(dev, _handle_) do { } while (0) +#endif + /* Get the wakeup routines, which depend on struct device */ #include -- cgit v1.2.3 From 863f9f30e6c1e30cb19a0cd17c5cf8879257dfd7 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 21 Nov 2012 00:21:59 +0100 Subject: ACPI / platform: Initialize ACPI handles of platform devices in advance The current platform device creation and registration code in acpi_create_platform_device() is quite convoluted. This function takes an ACPI device node as an argument and eventually calls platform_device_register_resndata() to create and register a platform device object on the basis of the information contained in that code. However, it doesn't associate the new platform device with the ACPI node directly, but instead it relies on acpi_platform_notify(), called from within device_add(), to find that ACPI node again with the help of acpi_platform_find_device() and acpi_platform_match() and then attach the new platform device to it. This causes an additional ACPI namespace walk to happen and is clearly suboptimal. Use the observation that it is now possible to initialize the ACPI handle of a device before calling device_add() for it to make this code more straightforward. Namely, add a new field to struct platform_device_info allowing us to pass the ACPI handle of interest to platform_device_register_full(), which will then use it to initialize the new device's ACPI handle before registering it. This will cause acpi_platform_notify() to use the ACPI handle from the device structure directly instead of using the .find_device() routine provided by the device's bus type. In consequence, acpi_platform_bus, acpi_platform_find_device(), and acpi_platform_match() are not necessary any more, so remove them. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mika Westerberg Acked-by: Greg Kroah-Hartman --- drivers/acpi/acpi_platform.c | 76 ++++++----------------------------------- drivers/base/platform.c | 2 ++ include/linux/platform_device.h | 1 + 3 files changed, 13 insertions(+), 66 deletions(-) diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 7ac20d8b8f0..b7df9b197bc 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -33,7 +33,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) { struct platform_device *pdev = NULL; struct acpi_device *acpi_parent; - struct device *parent = NULL; + struct platform_device_info pdevinfo; struct resource_list_entry *rentry; struct list_head resource_list; struct resource *resources; @@ -60,11 +60,13 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) acpi_dev_free_resource_list(&resource_list); + memset(&pdevinfo, 0, sizeof(pdevinfo)); /* * If the ACPI node has a parent and that parent has a physical device * attached to it, that physical device should be the parent of the * platform device we are about to create. */ + pdevinfo.parent = NULL; acpi_parent = adev->parent; if (acpi_parent) { struct acpi_device_physical_node *entry; @@ -76,12 +78,16 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) entry = list_first_entry(list, struct acpi_device_physical_node, node); - parent = entry->dev; + pdevinfo.parent = entry->dev; } mutex_unlock(&acpi_parent->physical_node_lock); } - pdev = platform_device_register_resndata(parent, dev_name(&adev->dev), - -1, resources, count, NULL, 0); + pdevinfo.name = dev_name(&adev->dev); + pdevinfo.id = -1; + pdevinfo.res = resources; + pdevinfo.num_res = count; + pdevinfo.acpi_node.handle = adev->handle; + pdev = platform_device_register_full(&pdevinfo); if (IS_ERR(pdev)) { dev_err(&adev->dev, "platform device creation failed: %ld\n", PTR_ERR(pdev)); @@ -94,65 +100,3 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) kfree(resources); return pdev; } - -static acpi_status acpi_platform_match(acpi_handle handle, u32 depth, - void *data, void **return_value) -{ - struct platform_device *pdev = data; - struct acpi_device *adev; - acpi_status status; - - status = acpi_bus_get_device(handle, &adev); - if (ACPI_FAILURE(status)) - return status; - - /* Skip ACPI devices that have physical device attached */ - if (adev->physical_node_count) - return AE_OK; - - if (!strcmp(dev_name(&pdev->dev), dev_name(&adev->dev))) { - *(acpi_handle *)return_value = handle; - return AE_CTRL_TERMINATE; - } - - return AE_OK; -} - -static int acpi_platform_find_device(struct device *dev, acpi_handle *handle) -{ - struct platform_device *pdev = to_platform_device(dev); - char *name, *tmp, *hid; - - /* - * The platform device is named using the ACPI device name - * _HID:INSTANCE so we strip the INSTANCE out in order to find the - * correct device using its _HID. - */ - name = kstrdup(dev_name(dev), GFP_KERNEL); - if (!name) - return -ENOMEM; - - tmp = name; - hid = strsep(&tmp, ":"); - if (!hid) { - kfree(name); - return -ENODEV; - } - - *handle = NULL; - acpi_get_devices(hid, acpi_platform_match, pdev, handle); - - kfree(name); - return *handle ? 0 : -ENODEV; -} - -static struct acpi_bus_type acpi_platform_bus = { - .bus = &platform_bus_type, - .find_device = acpi_platform_find_device, -}; - -static int __init acpi_platform_init(void) -{ - return register_acpi_bus_type(&acpi_platform_bus); -} -arch_initcall(acpi_platform_init); diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 7de29ebfce7..49fd96e2346 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -437,6 +437,7 @@ struct platform_device *platform_device_register_full( goto err_alloc; pdev->dev.parent = pdevinfo->parent; + ACPI_HANDLE_SET(&pdev->dev, pdevinfo->acpi_node.handle); if (pdevinfo->dma_mask) { /* @@ -467,6 +468,7 @@ struct platform_device *platform_device_register_full( ret = platform_device_add(pdev); if (ret) { err: + ACPI_HANDLE_SET(&pdev->dev, NULL); kfree(pdev->dev.dma_mask); err_alloc: diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 5711e9525a2..a9ded9a3c17 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -55,6 +55,7 @@ extern int platform_add_devices(struct platform_device **, int); struct platform_device_info { struct device *parent; + struct acpi_dev_node acpi_node; const char *name; int id; -- cgit v1.2.3 From ce2650d40dff23f2c6f9718bb3ec63e12c5c7f27 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 21 Nov 2012 01:18:30 +0100 Subject: cpufreq: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/longhaul.c | 2 +- drivers/cpufreq/powernow-k8.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 53ddbc760af..8d7ebb286e6 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -946,7 +946,7 @@ static struct cpufreq_driver longhaul_driver = { .target = longhaul_target, .get = longhaul_get, .init = longhaul_cpu_init, - .exit = __devexit_p(longhaul_cpu_exit), + .exit = longhaul_cpu_exit, .name = "longhaul", .owner = THIS_MODULE, .attr = longhaul_attr, diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index e3ebb4fa2c3..1fd0c8a48ed 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -1242,7 +1242,7 @@ static struct cpufreq_driver cpufreq_amd64_driver = { .target = powernowk8_target, .bios_limit = acpi_processor_get_bios_limit, .init = powernowk8_cpu_init, - .exit = __devexit_p(powernowk8_cpu_exit), + .exit = powernowk8_cpu_exit, .get = powernowk8_get, .name = "powernow-k8", .owner = THIS_MODULE, -- cgit v1.2.3 From c5fa4ab5ab417d8d7bd658957ce7b7e6ef0cdaf3 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 21 Nov 2012 01:18:40 +0100 Subject: cpufreq: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq-cpu0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index e9158278c71..52bf36d599f 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -174,7 +174,7 @@ static struct cpufreq_driver cpu0_cpufreq_driver = { .attr = cpu0_cpufreq_attr, }; -static int __devinit cpu0_cpufreq_driver_init(void) +static int cpu0_cpufreq_driver_init(void) { struct device_node *np; int ret; -- cgit v1.2.3 From c0e61cb151f2ff8edd02af23b2bd49f625288124 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 21 Nov 2012 01:18:49 +0100 Subject: cpufreq: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/longhaul.c | 2 +- drivers/cpufreq/powernow-k8.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 8d7ebb286e6..f1fa500ac10 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -930,7 +930,7 @@ static int __cpuinit longhaul_cpu_init(struct cpufreq_policy *policy) return 0; } -static int __devexit longhaul_cpu_exit(struct cpufreq_policy *policy) +static int longhaul_cpu_exit(struct cpufreq_policy *policy) { cpufreq_frequency_table_put_attr(policy->cpu); return 0; diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 1fd0c8a48ed..056faf6af1a 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -1186,7 +1186,7 @@ err_out: return -ENODEV; } -static int __devexit powernowk8_cpu_exit(struct cpufreq_policy *pol) +static int powernowk8_cpu_exit(struct cpufreq_policy *pol) { struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); -- cgit v1.2.3 From ae6a5d37725853325a2b3460165fbc5613ce2916 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 20 Nov 2012 12:17:51 +0000 Subject: ASoC: kirkwood-dma: fix use of virt_to_phys() This is part of a patch found in Rabeeh Khoury's git tree for the cubox. You can not use virt_to_phys() on the address returned from dma_alloc_coherent(); it may not be part of the kernel direct-mapped memory. Fix this to use the DMA address instead. Signed-off-by: Russell King Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index b9f16598324..afe19306625 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -178,7 +178,7 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream) } dram = mv_mbus_dram_info(); - addr = virt_to_phys(substream->dma_buffer.area); + addr = substream->dma_buffer.addr; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { prdata->play_stream = substream; kirkwood_dma_conf_mbus_windows(priv->io, -- cgit v1.2.3 From 25ec6bbb63e7eec905d94ccb59cdd54cf22ee618 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 20 Nov 2012 12:18:11 +0000 Subject: ASoC: kirkwood-dma: don't ignore other irq causes on error Ignoring the real cause of the interrupt is not a good idea; this behaviour has been observed to bring Dove platforms to silently lockup. Instead, on error fall through to the normal interrupt processing. This is especially important on Dove platforms as errors are handled separately, and allows us to clear down the real cause of the interrupt. Signed-off-by: Russell King Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-dma.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index afe19306625..2ba08148655 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -71,7 +71,6 @@ static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id) printk(KERN_WARNING "%s: got err interrupt 0x%lx\n", __func__, cause); writel(cause, priv->io + KIRKWOOD_ERR_CAUSE); - return IRQ_HANDLED; } /* we've enabled only bytes interrupts ... */ -- cgit v1.2.3 From 2424d458108e275ca736dabc792ee9b6733994c5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 20 Nov 2012 12:18:32 +0000 Subject: ASoC: kirkwood-i2s: fix DCO lock detection This is part of a patch found in Rabeeh Khoury's git tree for the cubox, which is further attributed to Sebastian Hesselbrath. Rather than masking the KIRKWOOD_DCO_SPCR_STATUS register contents against the registers virtual address, let's actually use the bit definition for the locked status, as required in the documentation. Signed-off-by: Russell King Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-i2s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 542538d10ab..485af80923d 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -95,7 +95,7 @@ static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate) do { cpu_relax(); value = readl(io + KIRKWOOD_DCO_SPCR_STATUS); - value &= KIRKWOOD_DCO_SPCR_STATUS; + value &= KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK; } while (value == 0); } -- cgit v1.2.3 From 982b604bc56a3da874e489051fc7adb49b1eba65 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 20 Nov 2012 12:18:52 +0000 Subject: ASoC: kirkwood-i2s: fix DMA underruns Stress testing the driver with multiple start/stop events causes kirkwood-dma to report underrun errors (which used to cause the kernel to lock up solidly). This is because kirkwood-i2s is not respecting the restrictions imposed on clearing the 'pause' bit. Follow what the spec says; the busy bit must be read as being clear twice before the pause bit can be released. This solves the underruns. However, it has been noticed that the busy bit occasionally does not clear itself, hence the waiting is bounded to 5ms maximum to avoid a new reason for the kernel to lockup. Signed-off-by: Russell King Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-i2s.c | 67 ++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 485af80923d..826306dfb72 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -180,67 +180,76 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); - unsigned long value; - - /* - * specs says KIRKWOOD_PLAYCTL must be read 2 times before - * changing it. So read 1 time here and 1 later. - */ - value = readl(priv->io + KIRKWOOD_PLAYCTL); + uint32_t ctl, value; + + ctl = readl(priv->io + KIRKWOOD_PLAYCTL); + if (ctl & KIRKWOOD_PLAYCTL_PAUSE) { + unsigned timeout = 5000; + /* + * The Armada510 spec says that if we enter pause mode, the + * busy bit must be read back as clear _twice_. Make sure + * we respect that otherwise we get DMA underruns. + */ + do { + value = ctl; + ctl = readl(priv->io + KIRKWOOD_PLAYCTL); + if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)) + break; + udelay(1); + } while (timeout--); + + if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY) + dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n", + ctl); + } switch (cmd) { case SNDRV_PCM_TRIGGER_START: /* stop audio, enable interrupts */ - value = readl(priv->io + KIRKWOOD_PLAYCTL); - value |= KIRKWOOD_PLAYCTL_PAUSE; - writel(value, priv->io + KIRKWOOD_PLAYCTL); + ctl |= KIRKWOOD_PLAYCTL_PAUSE; + writel(ctl, priv->io + KIRKWOOD_PLAYCTL); value = readl(priv->io + KIRKWOOD_INT_MASK); value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); /* configure audio & enable i2s playback */ - value = readl(priv->io + KIRKWOOD_PLAYCTL); - value &= ~KIRKWOOD_PLAYCTL_BURST_MASK; - value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE + ctl &= ~KIRKWOOD_PLAYCTL_BURST_MASK; + ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE | KIRKWOOD_PLAYCTL_SPDIF_EN); if (priv->burst == 32) - value |= KIRKWOOD_PLAYCTL_BURST_32; + ctl |= KIRKWOOD_PLAYCTL_BURST_32; else - value |= KIRKWOOD_PLAYCTL_BURST_128; - value |= KIRKWOOD_PLAYCTL_I2S_EN; - writel(value, priv->io + KIRKWOOD_PLAYCTL); + ctl |= KIRKWOOD_PLAYCTL_BURST_128; + ctl |= KIRKWOOD_PLAYCTL_I2S_EN; + writel(ctl, priv->io + KIRKWOOD_PLAYCTL); break; case SNDRV_PCM_TRIGGER_STOP: /* stop audio, disable interrupts */ - value = readl(priv->io + KIRKWOOD_PLAYCTL); - value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; - writel(value, priv->io + KIRKWOOD_PLAYCTL); + ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; + writel(ctl, priv->io + KIRKWOOD_PLAYCTL); value = readl(priv->io + KIRKWOOD_INT_MASK); value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); /* disable all playbacks */ - value = readl(priv->io + KIRKWOOD_PLAYCTL); - value &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN); - writel(value, priv->io + KIRKWOOD_PLAYCTL); + ctl &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN); + writel(ctl, priv->io + KIRKWOOD_PLAYCTL); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: - value = readl(priv->io + KIRKWOOD_PLAYCTL); - value |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; - writel(value, priv->io + KIRKWOOD_PLAYCTL); + ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; + writel(ctl, priv->io + KIRKWOOD_PLAYCTL); break; case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - value = readl(priv->io + KIRKWOOD_PLAYCTL); - value &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE); - writel(value, priv->io + KIRKWOOD_PLAYCTL); + ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE); + writel(ctl, priv->io + KIRKWOOD_PLAYCTL); break; default: -- cgit v1.2.3 From 3ccdf5bbdf5f2488e4a36692d055ba9c43ae6717 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 20 Nov 2012 12:19:13 +0000 Subject: ASoC: kirkwood-i2s: more pause-mode fixes Don't even momentarily set the pause status when starting the channel; if we do, we should check the busy bit to ensure that we comply with the spec. In any case, it isn't necessary; we will not active on a START event so there is no need to pause the DMA. Signed-off-by: Russell King Signed-off-by: Mark Brown --- sound/soc/kirkwood/kirkwood-i2s.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 826306dfb72..1d5db484d2d 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -205,10 +205,6 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: - /* stop audio, enable interrupts */ - ctl |= KIRKWOOD_PLAYCTL_PAUSE; - writel(ctl, priv->io + KIRKWOOD_PLAYCTL); - value = readl(priv->io + KIRKWOOD_INT_MASK); value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); @@ -269,11 +265,6 @@ static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: - /* stop audio, enable interrupts */ - value = readl(priv->io + KIRKWOOD_RECCTL); - value |= KIRKWOOD_RECCTL_PAUSE; - writel(value, priv->io + KIRKWOOD_RECCTL); - value = readl(priv->io + KIRKWOOD_INT_MASK); value |= KIRKWOOD_INT_CAUSE_REC_BYTES; writel(value, priv->io + KIRKWOOD_INT_MASK); -- cgit v1.2.3 From 68fa965dd923177eafad49b7a0045fc610917341 Mon Sep 17 00:00:00 2001 From: Mats Petersson Date: Fri, 16 Nov 2012 18:36:49 +0000 Subject: xen/privcmd: Correctly return success from IOCTL_PRIVCMD_MMAPBATCH This is a regression introduced by ceb90fa0 (xen/privcmd: add PRIVCMD_MMAPBATCH_V2 ioctl). It broke xentrace as it used xc_map_foreign() instead of xc_map_foreign_bulk(). Most code-paths prefer the MMAPBATCH_V2, so this wasn't very obvious that it broke. The return value is set early on to -EINVAL, and if all goes well, the "set top bits of the MFN's" never gets called, so the return value is still EINVAL when the function gets to the end, causing the caller to think it went wrong (which it didn't!) Now also including Andres "move the ret = -EINVAL into the error handling path, as this avoids other similar errors in future. Signed-off-by: Mats Petersson Acked-by: Andres Lagar-Cavilla Acked-by: David Vrabel Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/privcmd.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 8adb9cc267f..71f5c459b08 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -361,13 +361,13 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version) down_write(&mm->mmap_sem); vma = find_vma(mm, m.addr); - ret = -EINVAL; if (!vma || vma->vm_ops != &privcmd_vm_ops || (m.addr != vma->vm_start) || ((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) || !privcmd_enforce_singleshot_mapping(vma)) { up_write(&mm->mmap_sem); + ret = -EINVAL; goto out; } @@ -383,12 +383,16 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version) up_write(&mm->mmap_sem); - if (state.global_error && (version == 1)) { - /* Write back errors in second pass. */ - state.user_mfn = (xen_pfn_t *)m.arr; - state.err = err_array; - ret = traverse_pages(m.num, sizeof(xen_pfn_t), - &pagelist, mmap_return_errors_v1, &state); + if (version == 1) { + if (state.global_error) { + /* Write back errors in second pass. */ + state.user_mfn = (xen_pfn_t *)m.arr; + state.err = err_array; + ret = traverse_pages(m.num, sizeof(xen_pfn_t), + &pagelist, mmap_return_errors_v1, &state); + } else + ret = 0; + } else if (version == 2) { ret = __copy_to_user(m.err, err_array, m.num * sizeof(int)); if (ret) -- cgit v1.2.3 From e55b0829cbace88f4b50036432a12146d22cd106 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 12 Nov 2012 18:30:49 -0200 Subject: of: fdt: Constify 'pathp' Constify 'pathp' in order to get rid of the following warning: drivers/of/fdt.c:491:10: warning: assignment discards 'const' qualifier from pointer target type [enabled by default] Signed-off-by: Fabio Estevam [Rob Herring: also constify np and lp] Signed-off-by: Rob Herring --- drivers/of/fdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index c8be32644c8..135b8083212 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -460,7 +460,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, do { u32 tag = be32_to_cpup((__be32 *)p); - char *pathp; + const char *pathp; p += 4; if (tag == OF_DT_END_NODE) { @@ -488,7 +488,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, pathp = (char *)p; p = ALIGN(p + strlen(pathp) + 1, 4); if ((*pathp) == '/') { - char *lp, *np; + const char *lp, *np; for (lp = NULL, np = pathp; *np; np++) if ((*np) == '/') lp = np+1; -- cgit v1.2.3 From 6872a3173501f16aee5ce160359d1bb513d06a59 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 13 Nov 2012 14:12:05 +0000 Subject: of: Add vendor prefix for Synopsys Inc. This patch adds a device tree vendor prefix for Synopsys Inc. Signed-off-by: Srinivas Kandagatla Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index ff41e401901..bea1e9a0388 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -46,6 +46,7 @@ schindler Schindler sil Silicon Image simtek sirf SiRF Technology, Inc. +snps Synopsys, Inc. st STMicroelectronics stericsson ST-Ericsson ti Texas Instruments -- cgit v1.2.3 From 0fca5deafeac764c2ab0d37c2409fdd0962d5724 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 16 Nov 2012 15:14:38 +0000 Subject: of/fdt: NULL-terminate the root node path Commit 509b7455 (of/fdt: Don't copy garbage after "/" in root node path) sets the path length to 0 to ignore any garbage after "/" in the root node path. This has the side effect of also ignoring '\0' at the end of the root node path. This patch sets the ignores the garbage by setting the last character to '\0' and length to 1. Signed-off-by: Catalin Marinas Cc: Benjamin Herrenschmidt Signed-off-by: Rob Herring --- drivers/of/fdt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 135b8083212..e36ff40011f 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -186,7 +186,8 @@ static unsigned long unflatten_dt_node(struct boot_param_header *blob, */ fpsize = 1; allocl = 2; - l = 0; + l = 1; + *pathp = '\0'; } else { /* account for '/' and path size minus terminal 0 * already in 'l' -- cgit v1.2.3 From ae8c4209af2cec065fef15d200a42a04130799f7 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 19 Nov 2012 15:34:43 -0700 Subject: of: Add vendor prefix for Asahi Kasei Corp. Their stock ticker is 3407.T which wouldn't make a good DT vendor prefix. Use the company name initials instead. Signed-off-by: Stephen Warren Signed-off-by: Rob Herring --- Documentation/devicetree/bindings/vendor-prefixes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index bea1e9a0388..98271503f00 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -5,6 +5,7 @@ using them to avoid name-space collisions. ad Avionic Design GmbH adi Analog Devices, Inc. +ak Asahi Kasei Corp. amcc Applied Micro Circuits Corporation (APM, formally AMCC) apm Applied Micro Circuits Corporation (APM) arm ARM Ltd. -- cgit v1.2.3 From 9846210b1ec9bbaa30022d6d8af7e55ef67ccb45 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 19 Nov 2012 15:34:44 -0700 Subject: ARM: tegra: seaboard: add missing DT vendor prefixes A couple devices' DT compatible values only contained the device name without any vendor prefix. Add the missing vendor prefixes. Signed-off-by: Stephen Warren Signed-off-by: Rob Herring --- arch/arm/boot/dts/tegra20-seaboard.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts index f0ba901676a..a20d4ff3fb3 100644 --- a/arch/arm/boot/dts/tegra20-seaboard.dts +++ b/arch/arm/boot/dts/tegra20-seaboard.dts @@ -523,12 +523,12 @@ }; temperature-sensor@4c { - compatible = "nct1008"; + compatible = "onnn,nct1008"; reg = <0x4c>; }; magnetometer@c { - compatible = "ak8975"; + compatible = "ak,ak8975"; reg = <0xc>; interrupt-parent = <&gpio>; interrupts = <109 0x04>; /* gpio PN5 */ -- cgit v1.2.3 From be193249b4178158c0f697cb452b2bbf0cb16361 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 20 Nov 2012 10:15:19 +0530 Subject: dt: add helper function to read u8 & u16 variables & arrays This adds following helper routines: - of_property_read_u8_array() - of_property_read_u16_array() - of_property_read_u8() - of_property_read_u16() This expects arrays from DT to be passed as: - u8 array: property = /bits/ 8 <0x50 0x60 0x70>; - u16 array: property = /bits/ 16 <0x5000 0x6000 0x7000>; Signed-off-by: Viresh Kumar Reviewed-by: Stephen Warren Signed-off-by: Rob Herring --- drivers/of/base.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/of.h | 30 +++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/drivers/of/base.c b/drivers/of/base.c index af3b22ac762..f564e3107b3 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -670,6 +670,82 @@ struct device_node *of_find_node_by_phandle(phandle handle) } EXPORT_SYMBOL(of_find_node_by_phandle); +/** + * of_property_read_u8_array - Find and read an array of u8 from a property. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @out_value: pointer to return value, modified only if return value is 0. + * @sz: number of array elements to read + * + * Search for a property in a device node and read 8-bit value(s) from + * it. Returns 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + * + * dts entry of array should be like: + * property = /bits/ 8 <0x50 0x60 0x70>; + * + * The out_value is modified only if a valid u8 value can be decoded. + */ +int of_property_read_u8_array(const struct device_node *np, + const char *propname, u8 *out_values, size_t sz) +{ + struct property *prop = of_find_property(np, propname, NULL); + const u8 *val; + + if (!prop) + return -EINVAL; + if (!prop->value) + return -ENODATA; + if ((sz * sizeof(*out_values)) > prop->length) + return -EOVERFLOW; + + val = prop->value; + while (sz--) + *out_values++ = *val++; + return 0; +} +EXPORT_SYMBOL_GPL(of_property_read_u8_array); + +/** + * of_property_read_u16_array - Find and read an array of u16 from a property. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @out_value: pointer to return value, modified only if return value is 0. + * @sz: number of array elements to read + * + * Search for a property in a device node and read 16-bit value(s) from + * it. Returns 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + * + * dts entry of array should be like: + * property = /bits/ 16 <0x5000 0x6000 0x7000>; + * + * The out_value is modified only if a valid u16 value can be decoded. + */ +int of_property_read_u16_array(const struct device_node *np, + const char *propname, u16 *out_values, size_t sz) +{ + struct property *prop = of_find_property(np, propname, NULL); + const __be16 *val; + + if (!prop) + return -EINVAL; + if (!prop->value) + return -ENODATA; + if ((sz * sizeof(*out_values)) > prop->length) + return -EOVERFLOW; + + val = prop->value; + while (sz--) + *out_values++ = be16_to_cpup(val++); + return 0; +} +EXPORT_SYMBOL_GPL(of_property_read_u16_array); + /** * of_property_read_u32_array - Find and read an array of 32 bit integers * from a property. @@ -677,6 +753,7 @@ EXPORT_SYMBOL(of_find_node_by_phandle); * @np: device node from which the property value is to be read. * @propname: name of the property to be searched. * @out_value: pointer to return value, modified only if return value is 0. + * @sz: number of array elements to read * * Search for a property in a device node and read 32-bit value(s) from * it. Returns 0 on success, -EINVAL if the property does not exist, diff --git a/include/linux/of.h b/include/linux/of.h index 857dde984a6..ab1af0e1465 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -223,6 +223,10 @@ extern struct device_node *of_find_node_with_property( extern struct property *of_find_property(const struct device_node *np, const char *name, int *lenp); +extern int of_property_read_u8_array(const struct device_node *np, + const char *propname, u8 *out_values, size_t sz); +extern int of_property_read_u16_array(const struct device_node *np, + const char *propname, u16 *out_values, size_t sz); extern int of_property_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, @@ -364,6 +368,18 @@ static inline struct device_node *of_find_compatible_node( return NULL; } +static inline int of_property_read_u8_array(const struct device_node *np, + const char *propname, u8 *out_values, size_t sz) +{ + return -ENOSYS; +} + +static inline int of_property_read_u16_array(const struct device_node *np, + const char *propname, u16 *out_values, size_t sz) +{ + return -ENOSYS; +} + static inline int of_property_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, size_t sz) @@ -470,6 +486,20 @@ static inline bool of_property_read_bool(const struct device_node *np, return prop ? true : false; } +static inline int of_property_read_u8(const struct device_node *np, + const char *propname, + u8 *out_value) +{ + return of_property_read_u8_array(np, propname, out_value, 1); +} + +static inline int of_property_read_u16(const struct device_node *np, + const char *propname, + u16 *out_value) +{ + return of_property_read_u16_array(np, propname, out_value, 1); +} + static inline int of_property_read_u32(const struct device_node *np, const char *propname, u32 *out_value) -- cgit v1.2.3 From 50c8af4cf98fd97d6779f244215154e4c89699c7 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 20 Nov 2012 16:12:20 -0700 Subject: of: introduce for_each_matching_node_and_match() The following pattern of code is tempting: for_each_matching_node(np, table) { match = of_match_node(table, np); However, this results in iterating over table twice; the second time inside of_match_node(). The implementation of for_each_matching_node() already found the match, so this is redundant. Invent new function of_find_matching_node_and_match() and macro for_each_matching_node_and_match() to remove the double iteration, thus transforming the above code to: for_each_matching_node_and_match(np, table, &match) Signed-off-by: Stephen Warren Signed-off-by: Rob Herring --- drivers/of/base.c | 18 +++++++++++++----- include/linux/of.h | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index f564e3107b3..0ceb26a1605 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -594,27 +594,35 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches, EXPORT_SYMBOL(of_match_node); /** - * of_find_matching_node - Find a node based on an of_device_id match - * table. + * of_find_matching_node_and_match - Find a node based on an of_device_id + * match table. * @from: The node to start searching from or NULL, the node * you pass will not be searched, only the next one * will; typically, you pass what the previous call * returned. of_node_put() will be called on it * @matches: array of of device match structures to search in + * @match Updated to point at the matches entry which matched * * Returns a node pointer with refcount incremented, use * of_node_put() on it when done. */ -struct device_node *of_find_matching_node(struct device_node *from, - const struct of_device_id *matches) +struct device_node *of_find_matching_node_and_match(struct device_node *from, + const struct of_device_id *matches, + const struct of_device_id **match) { struct device_node *np; + if (match) + *match = NULL; + read_lock(&devtree_lock); np = from ? from->allnext : allnodes; for (; np; np = np->allnext) { - if (of_match_node(matches, np) && of_node_get(np)) + if (of_match_node(matches, np) && of_node_get(np)) { + if (match) + *match = matches; break; + } } of_node_put(from); read_unlock(&devtree_lock); diff --git a/include/linux/of.h b/include/linux/of.h index ab1af0e1465..13e0aacb4d9 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -179,11 +179,22 @@ extern struct device_node *of_find_compatible_node(struct device_node *from, #define for_each_compatible_node(dn, type, compatible) \ for (dn = of_find_compatible_node(NULL, type, compatible); dn; \ dn = of_find_compatible_node(dn, type, compatible)) -extern struct device_node *of_find_matching_node(struct device_node *from, - const struct of_device_id *matches); +extern struct device_node *of_find_matching_node_and_match( + struct device_node *from, + const struct of_device_id *matches, + const struct of_device_id **match); +static inline struct device_node *of_find_matching_node( + struct device_node *from, + const struct of_device_id *matches) +{ + return of_find_matching_node_and_match(from, matches, NULL); +} #define for_each_matching_node(dn, matches) \ for (dn = of_find_matching_node(NULL, matches); dn; \ dn = of_find_matching_node(dn, matches)) +#define for_each_matching_node_and_match(dn, matches, match) \ + for (dn = of_find_matching_node_and_match(NULL, matches, match); \ + dn; dn = of_find_matching_node_and_match(dn, matches, match)) extern struct device_node *of_find_node_by_path(const char *path); extern struct device_node *of_find_node_by_phandle(phandle handle); extern struct device_node *of_get_parent(const struct device_node *node); -- cgit v1.2.3 From 1022623842cb72ee4d0dbf02f6937f38c92c3f41 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Mon, 3 Sep 2012 20:54:48 +0200 Subject: x86-32: Fix invalid stack address while in softirq In 32 bit the stack address provided by kernel_stack_pointer() may point to an invalid range causing NULL pointer access or page faults while in NMI (see trace below). This happens if called in softirq context and if the stack is empty. The address at ®s->sp is then out of range. Fixing this by checking if regs and ®s->sp are in the same stack context. Otherwise return the previous stack pointer stored in struct thread_info. If that address is invalid too, return address of regs. BUG: unable to handle kernel NULL pointer dereference at 0000000a IP: [] print_context_stack+0x6e/0x8d *pde = 00000000 Oops: 0000 [#1] SMP Modules linked in: Pid: 4434, comm: perl Not tainted 3.6.0-rc3-oprofile-i386-standard-g4411a05 #4 Hewlett-Packard HP xw9400 Workstation/0A1Ch EIP: 0060:[] EFLAGS: 00010093 CPU: 0 EIP is at print_context_stack+0x6e/0x8d EAX: ffffe000 EBX: 0000000a ECX: f4435f94 EDX: 0000000a ESI: f4435f94 EDI: f4435f94 EBP: f5409ec0 ESP: f5409ea0 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 CR0: 8005003b CR2: 0000000a CR3: 34ac9000 CR4: 000007d0 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 Process perl (pid: 4434, ti=f5408000 task=f5637850 task.ti=f4434000) Stack: 000003e8 ffffe000 00001ffc f4e39b00 00000000 0000000a f4435f94 c155198c f5409ef0 c1003723 c155198c f5409f04 00000000 f5409edc 00000000 00000000 f5409ee8 f4435f94 f5409fc4 00000001 f5409f1c c12dce1c 00000000 c155198c Call Trace: [] dump_trace+0x7b/0xa1 [] x86_backtrace+0x40/0x88 [] ? oprofile_add_sample+0x56/0x84 [] oprofile_add_sample+0x75/0x84 [] op_amd_check_ctrs+0x46/0x260 [] profile_exceptions_notify+0x23/0x4c [] nmi_handle+0x31/0x4a [] ? ftrace_define_fields_irq_handler_entry+0x45/0x45 [] do_nmi+0xa0/0x2ff [] ? ftrace_define_fields_irq_handler_entry+0x45/0x45 [] nmi_stack_correct+0x28/0x2d [] ? ftrace_define_fields_irq_handler_entry+0x45/0x45 [] ? do_softirq+0x4b/0x7f [] irq_exit+0x35/0x5b [] smp_apic_timer_interrupt+0x6c/0x7a [] apic_timer_interrupt+0x2a/0x30 Code: 89 fe eb 08 31 c9 8b 45 0c ff 55 ec 83 c3 04 83 7d 10 00 74 0c 3b 5d 10 73 26 3b 5d e4 73 0c eb 1f 3b 5d f0 76 1a 3b 5d e8 73 15 <8b> 13 89 d0 89 55 e0 e8 ad 42 03 00 85 c0 8b 55 e0 75 a6 eb cc EIP: [] print_context_stack+0x6e/0x8d SS:ESP 0068:f5409ea0 CR2: 000000000000000a ---[ end trace 62afee3481b00012 ]--- Kernel panic - not syncing: Fatal exception in interrupt V2: * add comments to kernel_stack_pointer() * always return a valid stack address by falling back to the address of regs Reported-by: Yang Wei Cc: Signed-off-by: Robert Richter Link: http://lkml.kernel.org/r/20120912135059.GZ8285@erda.amd.com Signed-off-by: H. Peter Anvin Cc: Jun Zhang --- arch/x86/include/asm/ptrace.h | 15 ++++----------- arch/x86/kernel/ptrace.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index dcfde52979c..19f16ebaf4f 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -205,21 +205,14 @@ static inline bool user_64bit_mode(struct pt_regs *regs) } #endif -/* - * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode - * when it traps. The previous stack will be directly underneath the saved - * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. - * - * This is valid only for kernel mode traps. - */ -static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) -{ #ifdef CONFIG_X86_32 - return (unsigned long)(®s->sp); +extern unsigned long kernel_stack_pointer(struct pt_regs *regs); #else +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ return regs->sp; -#endif } +#endif #define GET_IP(regs) ((regs)->ip) #define GET_FP(regs) ((regs)->bp) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index b00b33a1839..2484e331a64 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -166,6 +166,34 @@ static inline bool invalid_selector(u16 value) #define FLAG_MASK FLAG_MASK_32 +/* + * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode + * when it traps. The previous stack will be directly underneath the saved + * registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'. + * + * Now, if the stack is empty, '®s->sp' is out of range. In this + * case we try to take the previous stack. To always return a non-null + * stack pointer we fall back to regs as stack if no previous stack + * exists. + * + * This is valid only for kernel mode traps. + */ +unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ + unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1); + unsigned long sp = (unsigned long)®s->sp; + struct thread_info *tinfo; + + if (context == (sp & ~(THREAD_SIZE - 1))) + return sp; + + tinfo = (struct thread_info *)context; + if (tinfo->previous_esp) + return tinfo->previous_esp; + + return (unsigned long)regs; +} + static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) { BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0); -- cgit v1.2.3 From cb57a2b4cff7edf2a4e32c0163200e9434807e0a Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 20 Nov 2012 22:21:02 -0800 Subject: x86-32: Export kernel_stack_pointer() for modules Modules, in particular oprofile (and possibly other similar tools) need kernel_stack_pointer(), so export it using EXPORT_SYMBOL_GPL(). Cc: Yang Wei Cc: Robert Richter Cc: Jun Zhang Cc: Link: http://lkml.kernel.org/r/20120912135059.GZ8285@erda.amd.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/ptrace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 2484e331a64..5e0596b0632 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -193,6 +194,7 @@ unsigned long kernel_stack_pointer(struct pt_regs *regs) return (unsigned long)regs; } +EXPORT_SYMBOL_GPL(kernel_stack_pointer); static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno) { -- cgit v1.2.3 From 36c46ca4f322a7bf89aad5462a3a1f61713edce7 Mon Sep 17 00:00:00 2001 From: Boris Ostrovsky Date: Thu, 15 Nov 2012 13:41:50 -0500 Subject: x86, microcode, AMD: Add support for family 16h processors Add valid patch size for family 16h processors. [ hpa: promoting to urgent/stable since it is hw enabling and trivial ] Signed-off-by: Boris Ostrovsky Acked-by: Andreas Herrmann Link: http://lkml.kernel.org/r/1353004910-2204-1-git-send-email-boris.ostrovsky@amd.com Signed-off-by: H. Peter Anvin Cc: --- arch/x86/kernel/microcode_amd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c index b3e67ba55b7..efdec7cd8e0 100644 --- a/arch/x86/kernel/microcode_amd.c +++ b/arch/x86/kernel/microcode_amd.c @@ -190,6 +190,7 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, #define F1XH_MPB_MAX_SIZE 2048 #define F14H_MPB_MAX_SIZE 1824 #define F15H_MPB_MAX_SIZE 4096 +#define F16H_MPB_MAX_SIZE 3458 switch (c->x86) { case 0x14: @@ -198,6 +199,9 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size, case 0x15: max_size = F15H_MPB_MAX_SIZE; break; + case 0x16: + max_size = F16H_MPB_MAX_SIZE; + break; default: max_size = F1XH_MPB_MAX_SIZE; break; -- cgit v1.2.3 From ee4eb87be2c3f69c2c4d9f1c1d98e363a7ad18ab Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 2 Nov 2012 11:18:39 +0000 Subject: x86-64: Fix ordering of CFI directives and recent ASM_CLAC additions While these got added in the right place everywhere else, entry_64.S is the odd one where they ended up before the initial CFI directive(s). In order to cover the full code ranges, the CFI directive must be first, though. Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/5093BA1F02000078000A600E@nat28.tlf.novell.com Signed-off-by: H. Peter Anvin --- arch/x86/kernel/entry_64.S | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index b51b2c7ee51..1328fe49a3f 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -995,8 +995,8 @@ END(interrupt) */ .p2align CONFIG_X86_L1_CACHE_SHIFT common_interrupt: - ASM_CLAC XCPT_FRAME + ASM_CLAC addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */ interrupt do_IRQ /* 0(%rsp): old_rsp-ARGOFFSET */ @@ -1135,8 +1135,8 @@ END(common_interrupt) */ .macro apicinterrupt num sym do_sym ENTRY(\sym) - ASM_CLAC INTR_FRAME + ASM_CLAC pushq_cfi $~(\num) .Lcommon_\sym: interrupt \do_sym @@ -1190,8 +1190,8 @@ apicinterrupt IRQ_WORK_VECTOR \ */ .macro zeroentry sym do_sym ENTRY(\sym) - ASM_CLAC INTR_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ subq $ORIG_RAX-R15, %rsp @@ -1208,8 +1208,8 @@ END(\sym) .macro paranoidzeroentry sym do_sym ENTRY(\sym) - ASM_CLAC INTR_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ subq $ORIG_RAX-R15, %rsp @@ -1227,8 +1227,8 @@ END(\sym) #define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8) .macro paranoidzeroentry_ist sym do_sym ist ENTRY(\sym) - ASM_CLAC INTR_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */ subq $ORIG_RAX-R15, %rsp @@ -1247,8 +1247,8 @@ END(\sym) .macro errorentry sym do_sym ENTRY(\sym) - ASM_CLAC XCPT_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME subq $ORIG_RAX-R15, %rsp CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 @@ -1266,8 +1266,8 @@ END(\sym) /* error code is on the stack already */ .macro paranoiderrorentry sym do_sym ENTRY(\sym) - ASM_CLAC XCPT_FRAME + ASM_CLAC PARAVIRT_ADJUST_EXCEPTION_FRAME subq $ORIG_RAX-R15, %rsp CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15 -- cgit v1.2.3 From 3f0f8670608766ef26a178d4e80cad3ce030fecc Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 12:40:15 +0100 Subject: gpiolib: let gpiochip_add_pin_range() specify offset Like with commit 3c739ad0df5eb41cd7adad879eda6aa09879eb76 it is not always enough to specify all the pins of a gpio_chip from offset zero to be added to a pin map range, since the mapping from GPIO to pin controller may not be linear at all, but need to be broken into a few consecutive sub-ranges or 1-pin entries for complicated cases. The ranges may also be sparse. This alters the signature of the function to accept offsets into both the GPIO-chip local pinspace and the pin controller local pinspace. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 12 ++++++++++++ drivers/gpio/gpiolib.c | 32 +++++++++++++++++++++++++++++--- include/asm-generic/gpio.h | 6 ++++-- include/linux/gpio.h | 3 ++- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index a40cd84c5c1..d542a141811 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -238,8 +238,20 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) if (!pctldev) break; + /* + * This assumes that the n GPIO pins are consecutive in the + * GPIO number space, and that the pins are also consecutive + * in their local number space. Currently it is not possible + * to add different ranges for one and the same GPIO chip, + * as the code assumes that we have one consecutive range + * on both, mapping 1-to-1. + * + * TODO: make the OF bindings handle multiple sparse ranges + * on the same GPIO chip. + */ ret = gpiochip_add_pin_range(chip, pinctrl_dev_get_name(pctldev), + 0, /* offset in gpiochip */ pinspec.args[0], pinspec.args[1]); diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index c5f650095fa..6d13bea4778 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1187,24 +1187,45 @@ EXPORT_SYMBOL_GPL(gpiochip_find); #ifdef CONFIG_PINCTRL +/** + * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping + * @chip: the gpiochip to add the range for + * @pinctrl_name: the dev_name() of the pin controller to map to + * @offset: the start offset in the current gpio_chip number space + * @pin_base: the start offset in the pin controller number space + * @npins: the number of pins from the offset of each pin space (GPIO and + * pin controller) to accumulate in this range + */ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins) + unsigned int offset, unsigned int pin_base, + unsigned int npins) { struct gpio_pin_range *pin_range; - pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), GFP_KERNEL); + pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); if (!pin_range) { pr_err("%s: GPIO chip: failed to allocate pin ranges\n", chip->label); return -ENOMEM; } + /* Use local offset as range ID */ + pin_range->range.id = offset; + pin_range->range.gc = chip; pin_range->range.name = chip->label; - pin_range->range.base = chip->base; + pin_range->range.base = chip->base + offset; pin_range->range.pin_base = pin_base; pin_range->range.npins = npins; pin_range->pctldev = find_pinctrl_and_add_gpio_range(pinctl_name, &pin_range->range); + if (!pin_range->pctldev) { + pr_err("%s: GPIO chip: could not create pin range\n", + chip->label); + kfree(pin_range); + } + pr_debug("%s: GPIO chip: created GPIO range %d->%d ==> PIN %d->%d\n", + chip->label, offset, offset + npins - 1, + pin_base, pin_base + npins - 1); list_add_tail(&pin_range->node, &chip->pin_ranges); @@ -1212,6 +1233,10 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, } EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); +/** + * gpiochip_remove_pin_ranges() - remove all the GPIO <-> pin mappings + * @chip: the chip to remove all the mappings for + */ void gpiochip_remove_pin_ranges(struct gpio_chip *chip) { struct gpio_pin_range *pin_range, *tmp; @@ -1220,6 +1245,7 @@ void gpiochip_remove_pin_ranges(struct gpio_chip *chip) list_del(&pin_range->node); pinctrl_remove_gpio_range(pin_range->pctldev, &pin_range->range); + kfree(pin_range); } } EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges); diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 2b84fc32fae..ec58fdbddb5 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -283,14 +283,16 @@ struct gpio_pin_range { }; int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins); + unsigned int offset, unsigned int pin_base, + unsigned int npins); void gpiochip_remove_pin_ranges(struct gpio_chip *chip); #else static inline int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins) + unsigned int offset, unsigned int pin_base, + unsigned int npins) { return 0; } diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 7ba2762abbc..99861c65dd8 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -233,7 +233,8 @@ static inline int irq_to_gpio(unsigned irq) static inline int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int pin_base, unsigned int npins) + unsigned int offset, unsigned int pin_base, + unsigned int npins) { WARN_ON(1); return -EINVAL; -- cgit v1.2.3 From 192c369c6165dff233f22aa70209a92b030d233d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 14:03:37 +0100 Subject: gpiolib: rename find_pinctrl_* Rename the function find_pinctrl_and_add_gpio_range() to pinctrl_find_and_add_gpio_range() so as to be consistent with the rest of the functions. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 2 +- drivers/pinctrl/core.c | 4 ++-- include/linux/pinctrl/pinctrl.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 6d13bea4778..a59d13d746c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1216,7 +1216,7 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, pin_range->range.base = chip->base + offset; pin_range->range.pin_base = pin_base; pin_range->range.npins = npins; - pin_range->pctldev = find_pinctrl_and_add_gpio_range(pinctl_name, + pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, &pin_range->range); if (!pin_range->pctldev) { pr_err("%s: GPIO chip: could not create pin range\n", diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 71db586b2af..15f5ac864f1 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -345,7 +345,7 @@ void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, } EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges); -struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname, +struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, struct pinctrl_gpio_range *range) { struct pinctrl_dev *pctldev = get_pinctrl_dev_from_devname(devname); @@ -356,7 +356,7 @@ struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname, pinctrl_add_gpio_range(pctldev, range); return pctldev; } -EXPORT_SYMBOL_GPL(find_pinctrl_and_add_gpio_range); +EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range); /** * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 4a58428bc79..7dee9acbd27 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -137,7 +137,7 @@ extern void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, extern void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range); -extern struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname, +extern struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, struct pinctrl_gpio_range *range); #ifdef CONFIG_OF -- cgit v1.2.3 From dfa9751548444caadda2d6de1a2b67e05b34c2aa Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 14:54:18 +0100 Subject: pinctrl: make range registration defer properly This makes the pinctrl_find_and_add_gpio_range() return -EPROBE_DEFER if the range hosting pin controller cannot be located. We may assume that the common case for why adding a range fails is that the targe pin controller device has not probed yet. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 15f5ac864f1..33af811a6a3 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -350,8 +350,13 @@ struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, { struct pinctrl_dev *pctldev = get_pinctrl_dev_from_devname(devname); + /* + * If we can't find this device, let's assume that is because + * it has not probed yet, so the driver trying to register this + * range need to defer probing. + */ if (!pctldev) - return NULL; + return ERR_PTR(-EPROBE_DEFER); pinctrl_add_gpio_range(pctldev, range); return pctldev; -- cgit v1.2.3 From 8f23ca1a73a096f21e6618d8e23df613daa5e532 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 14:56:25 +0100 Subject: gpiolib: return any error code from range creation If we try to create a range for a certain GPIO chip and the target pin controller is not yet available it may return a probe deferral error code, so handle this all the way our by checking the error code. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index a59d13d746c..317ff0440e2 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1218,10 +1218,11 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, pin_range->range.npins = npins; pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, &pin_range->range); - if (!pin_range->pctldev) { + if (IS_ERR(pin_range->pctldev)) { pr_err("%s: GPIO chip: could not create pin range\n", chip->label); kfree(pin_range); + return PTR_ERR(pin_range->pctldev); } pr_debug("%s: GPIO chip: created GPIO range %d->%d ==> PIN %d->%d\n", chip->label, offset, offset + npins - 1, -- cgit v1.2.3 From 9afbefb227792a3c195085d662050dcca748f521 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 14:25:07 +0100 Subject: pinctrl: add function to retrieve range from pin This adds a function to the pinctrl core to retrieve the GPIO range associated with a certain pin for a certain controller. This is needed when a pinctrl driver want to look up the corresponding struct gpio_chip for a certain pin. As the GPIO drivers can now create these ranges themselves, the pinctrl driver no longer knows about all its associated GPIO chips. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 24 ++++++++++++++++++++++++ include/linux/pinctrl/pinctrl.h | 3 +++ 2 files changed, 27 insertions(+) diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 33af811a6a3..5cdee8669ea 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -363,6 +363,30 @@ struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, } EXPORT_SYMBOL_GPL(pinctrl_find_and_add_gpio_range); +/** + * pinctrl_find_gpio_range_from_pin() - locate the GPIO range for a pin + * @pctldev: the pin controller device to look in + * @pin: a controller-local number to find the range for + */ +struct pinctrl_gpio_range * +pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev, + unsigned int pin) +{ + struct pinctrl_gpio_range *range = NULL; + + /* Loop over the ranges */ + list_for_each_entry(range, &pctldev->gpio_ranges, node) { + /* Check if we're in the valid range */ + if (pin >= range->pin_base && + pin < range->pin_base + range->npins) { + return range; + } + } + + return NULL; +} +EXPORT_SYMBOL_GPL(pinctrl_find_gpio_range_from_pin); + /** * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller * @pctldev: pin controller device to remove the range from diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 7dee9acbd27..04d6700d99a 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -139,6 +139,9 @@ extern void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, extern struct pinctrl_dev *pinctrl_find_and_add_gpio_range(const char *devname, struct pinctrl_gpio_range *range); +extern struct pinctrl_gpio_range * +pinctrl_find_gpio_range_from_pin(struct pinctrl_dev *pctldev, + unsigned int pin); #ifdef CONFIG_OF extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np); -- cgit v1.2.3 From 387923c585ac68ff51e6bf673807438b5e5fdaf3 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 14:28:07 +0100 Subject: pinctrl/u300/coh901: let the gpio_chip register the range Instead of having the pinctrl driver register the GPIO range for the gpio_chip, making it necessary to instantiate the pin controller from the GPIO driver and pass the GPIO chip as platform data, now let the GPIO chip driver register it's own ranges and have the pinctrl driver look up the GPIO chip from the pinctrl core as necessary. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-coh901.c | 47 ++++++++++++++++++++++++++++++++-- drivers/pinctrl/pinctrl-u300.c | 55 +++------------------------------------- 2 files changed, 49 insertions(+), 53 deletions(-) diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index 1144dcdf2da..04574308ea8 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -658,6 +658,36 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio) } } +/* + * Here we map a GPIO in the local gpio_chip pin space to a pin in + * the local pinctrl pin space. The pin controller used is + * pinctrl-u300. + */ +struct coh901_pinpair { + unsigned int offset; + unsigned int pin_base; +}; + +#define COH901_PINRANGE(a, b) { .offset = a, .pin_base = b } + +static struct coh901_pinpair coh901_pintable[] = { + COH901_PINRANGE(10, 426), + COH901_PINRANGE(11, 180), + COH901_PINRANGE(12, 165), /* MS/MMC card insertion */ + COH901_PINRANGE(13, 179), + COH901_PINRANGE(14, 178), + COH901_PINRANGE(16, 194), + COH901_PINRANGE(17, 193), + COH901_PINRANGE(18, 192), + COH901_PINRANGE(19, 191), + COH901_PINRANGE(20, 186), + COH901_PINRANGE(21, 185), + COH901_PINRANGE(22, 184), + COH901_PINRANGE(23, 183), + COH901_PINRANGE(24, 182), + COH901_PINRANGE(25, 181), +}; + static int __init u300_gpio_probe(struct platform_device *pdev) { struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); @@ -786,16 +816,29 @@ static int __init u300_gpio_probe(struct platform_device *pdev) goto err_no_chip; } - /* Spawn pin controller device as child of the GPIO, pass gpio chip */ - plat->pinctrl_device->dev.platform_data = &gpio->chip; + /* Spawn pin controller device as child of the GPIO */ err = platform_device_register(plat->pinctrl_device); if (err) goto err_no_pinctrl; + /* + * Add pinctrl pin ranges, the pin controller must be registered + * at this point + */ + for (i = 0; i < ARRAY_SIZE(coh901_pintable); i++) { + struct coh901_pinpair *p = &coh901_pintable[i]; + + err = gpiochip_add_pin_range(&gpio->chip, "pinctrl-u300", + p->offset, p->pin_base, 1); + if (err) + goto err_no_range; + } + platform_set_drvdata(pdev, gpio); return 0; +err_no_range: err_no_pinctrl: err = gpiochip_remove(&gpio->chip); err_no_chip: diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index d756cce588f..b84de03ed54 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c @@ -1011,51 +1011,11 @@ static struct pinmux_ops u300_pmx_ops = { .disable = u300_pmx_disable, }; -/* - * GPIO ranges handled by the application-side COH901XXX GPIO controller - * Very many pins can be converted into GPIO pins, but we only list those - * that are useful in practice to cut down on tables. - */ -#define U300_GPIO_RANGE(a, b, c) { .name = "COH901XXX", .id = a, .base= a, \ - .pin_base = b, .npins = c } - -static struct pinctrl_gpio_range u300_gpio_ranges[] = { - U300_GPIO_RANGE(10, 426, 1), - U300_GPIO_RANGE(11, 180, 1), - U300_GPIO_RANGE(12, 165, 1), /* MS/MMC card insertion */ - U300_GPIO_RANGE(13, 179, 1), - U300_GPIO_RANGE(14, 178, 1), - U300_GPIO_RANGE(16, 194, 1), - U300_GPIO_RANGE(17, 193, 1), - U300_GPIO_RANGE(18, 192, 1), - U300_GPIO_RANGE(19, 191, 1), - U300_GPIO_RANGE(20, 186, 1), - U300_GPIO_RANGE(21, 185, 1), - U300_GPIO_RANGE(22, 184, 1), - U300_GPIO_RANGE(23, 183, 1), - U300_GPIO_RANGE(24, 182, 1), - U300_GPIO_RANGE(25, 181, 1), -}; - -static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) { - struct pinctrl_gpio_range *range; - - range = &u300_gpio_ranges[i]; - if (pin >= range->pin_base && - pin <= (range->pin_base + range->npins - 1)) - return range; - } - return NULL; -} - static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { - struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); + struct pinctrl_gpio_range *range = + pinctrl_find_gpio_range_from_pin(pctldev, pin); /* We get config for those pins we CAN get it for and that's it */ if (!range) @@ -1069,7 +1029,8 @@ static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, unsigned long config) { - struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); + struct pinctrl_gpio_range *range = + pinctrl_find_gpio_range_from_pin(pctldev, pin); int ret; if (!range) @@ -1105,8 +1066,6 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) { struct u300_pmx *upmx; struct resource *res; - struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev); - int i; /* Create state holders etc for this driver */ upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); @@ -1129,12 +1088,6 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) return -EINVAL; } - /* We will handle a range of GPIO pins */ - for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) { - u300_gpio_ranges[i].gc = gpio_chip; - pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); - } - platform_set_drvdata(pdev, upmx); dev_info(&pdev->dev, "initialized U300 pin control driver\n"); -- cgit v1.2.3 From 8604ac34eb19f7b02f8cf22c787fe30d96ad2651 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 14:42:47 +0100 Subject: pinctrl/u300/coh901: stop spawning pinctrl from GPIO Let's stop spawning the pinctrl driver from the GPIO driver, we have these two mechanisms broken apart now, and they can each probe in isolation. If the GPIO driver cannot find its pin controller (pinctrl-u300), the pin controller core will tell it to defer probing. Reviewed-by: Stephen Warren Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- arch/arm/mach-u300/core.c | 2 +- drivers/pinctrl/pinctrl-coh901.c | 6 ------ include/linux/platform_data/pinctrl-coh901.h | 2 -- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index ce2de0d6f2e..ece8a2dfb81 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1445,7 +1445,6 @@ static struct platform_device pinctrl_device = { static struct u300_gpio_platform u300_gpio_plat = { .ports = 7, .gpio_base = 0, - .pinctrl_device = &pinctrl_device, }; static struct platform_device gpio_device = { @@ -1589,6 +1588,7 @@ static struct platform_device *platform_devs[] __initdata = { &i2c1_device, &keypad_device, &rtc_device, + &pinctrl_device, &gpio_device, &nand_device, &wdog_device, diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index 04574308ea8..fbb37154471 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -816,11 +816,6 @@ static int __init u300_gpio_probe(struct platform_device *pdev) goto err_no_chip; } - /* Spawn pin controller device as child of the GPIO */ - err = platform_device_register(plat->pinctrl_device); - if (err) - goto err_no_pinctrl; - /* * Add pinctrl pin ranges, the pin controller must be registered * at this point @@ -839,7 +834,6 @@ static int __init u300_gpio_probe(struct platform_device *pdev) return 0; err_no_range: -err_no_pinctrl: err = gpiochip_remove(&gpio->chip); err_no_chip: err_no_domain: diff --git a/include/linux/platform_data/pinctrl-coh901.h b/include/linux/platform_data/pinctrl-coh901.h index 27a23b318ce..dfbc65d1048 100644 --- a/include/linux/platform_data/pinctrl-coh901.h +++ b/include/linux/platform_data/pinctrl-coh901.h @@ -13,12 +13,10 @@ * struct u300_gpio_platform - U300 GPIO platform data * @ports: number of GPIO block ports * @gpio_base: first GPIO number for this block (use a free range) - * @pinctrl_device: pin control device to spawn as child */ struct u300_gpio_platform { u8 ports; int gpio_base; - struct platform_device *pinctrl_device; }; #endif /* __MACH_U300_GPIO_U300_H */ -- cgit v1.2.3 From 2ccb0bcfb0dd2001b1a40048c1e407cd9a78bd3d Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 15 Nov 2012 16:36:33 +0800 Subject: pinctrl: generic: add input schmitt disable parameter In Marvell PXA/MMP silicons, input schmitt disable value is 0x40, not 0. So append new config parameter -- input schmitt disable. Signed-off-by: Haojian Zhuang Signed-off-by: Linus Walleij --- drivers/pinctrl/pinconf-generic.c | 1 + include/linux/pinctrl/pinconf-generic.h | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index 33fbaeaa65d..833a3645815 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -41,6 +41,7 @@ struct pin_config_item conf_items[] = { PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL), PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL), PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL), + PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT_DISABLE, "input schmitt disabled", NULL), PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL), PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"), PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"), diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h index 4f0abb9f1c0..47a1bdd8887 100644 --- a/include/linux/pinctrl/pinconf-generic.h +++ b/include/linux/pinctrl/pinconf-generic.h @@ -46,11 +46,11 @@ * @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source * (open emitter). Sending this config will enabale open drain mode, the * argument is ignored. + * @PIN_CONFIG_INPUT_SCHMITT_DISABLE: disable schmitt-trigger mode on the pin. * @PIN_CONFIG_INPUT_SCHMITT: this will configure an input pin to run in * schmitt-trigger mode. If the schmitt-trigger has adjustable hysteresis, * the threshold value is given on a custom format as argument when - * setting pins to this mode. The argument zero turns the schmitt trigger - * off. + * setting pins to this mode. * @PIN_CONFIG_INPUT_DEBOUNCE: this will configure the pin to debounce mode, * which means it will wait for signals to settle when reading inputs. The * argument gives the debounce time on a custom format. Setting the @@ -74,6 +74,7 @@ enum pin_config_param { PIN_CONFIG_DRIVE_PUSH_PULL, PIN_CONFIG_DRIVE_OPEN_DRAIN, PIN_CONFIG_DRIVE_OPEN_SOURCE, + PIN_CONFIG_INPUT_SCHMITT_DISABLE, PIN_CONFIG_INPUT_SCHMITT, PIN_CONFIG_INPUT_DEBOUNCE, PIN_CONFIG_POWER_SOURCE, -- cgit v1.2.3 From 2e8b2eab94c35d83bb7da71c63b4695f32ddca88 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 15 Nov 2012 16:36:31 +0800 Subject: pinctrl: single: support gpio request and free Marvell's PXA/MMP silicon also match the behavior of pinctrl-single. Each pin binds to one register. A lot of pins could be configured as gpio. GPIO range is defined as a child node of pinmux in .dtsi file. If those pins are with the same gpio function configuration in the pinmux register, they could be defined in the same GPIO range. For this new child node, two properties are used. reg = pinctrl-single,gpio: Signed-off-by: Haojian Zhuang Acked-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 80 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 145025f5008..e8dbb94494d 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -30,6 +30,7 @@ #define PCS_MUX_BITS_NAME "pinctrl-single,bits" #define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1) #define PCS_OFF_DISABLED ~0U +#define PCS_MAX_GPIO_VALUES 2 /** * struct pcs_pingroup - pingroups for a function @@ -76,6 +77,16 @@ struct pcs_function { struct list_head node; }; +/** + * struct pcs_gpio_range - pinctrl gpio range + * @range: subrange of the GPIO number space + * @gpio_func: gpio function value in the pinmux register + */ +struct pcs_gpio_range { + struct pinctrl_gpio_range range; + int gpio_func; +}; + /** * struct pcs_data - wrapper for data needed by pinctrl framework * @pa: pindesc array @@ -403,9 +414,26 @@ static void pcs_disable(struct pinctrl_dev *pctldev, unsigned fselector, } static int pcs_request_gpio(struct pinctrl_dev *pctldev, - struct pinctrl_gpio_range *range, unsigned offset) + struct pinctrl_gpio_range *range, unsigned pin) { - return -ENOTSUPP; + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_gpio_range *gpio = NULL; + int end, mux_bytes; + unsigned data; + + gpio = container_of(range, struct pcs_gpio_range, range); + end = range->pin_base + range->npins - 1; + if (pin < range->pin_base || pin > end) { + dev_err(pctldev->dev, + "pin %d isn't in the range of %d to %d\n", + pin, range->pin_base, end); + return -EINVAL; + } + mux_bytes = pcs->width / BITS_PER_BYTE; + data = pcs->read(pcs->base + pin * mux_bytes) & ~pcs->fmask; + data |= gpio->gpio_func; + pcs->write(data, pcs->base + pin * mux_bytes); + return 0; } static struct pinmux_ops pcs_pinmux_ops = { @@ -879,6 +907,50 @@ static void pcs_free_resources(struct pcs_device *pcs) static struct of_device_id pcs_of_match[]; +static int __devinit pcs_add_gpio_range(struct device_node *node, + struct pcs_device *pcs) +{ + struct pcs_gpio_range *gpio; + struct device_node *child; + struct resource r; + const char name[] = "pinctrl-single"; + u32 gpiores[PCS_MAX_GPIO_VALUES]; + int ret, i = 0, mux_bytes = 0; + + for_each_child_of_node(node, child) { + ret = of_address_to_resource(child, 0, &r); + if (ret < 0) + continue; + memset(gpiores, 0, sizeof(u32) * PCS_MAX_GPIO_VALUES); + ret = of_property_read_u32_array(child, "pinctrl-single,gpio", + gpiores, PCS_MAX_GPIO_VALUES); + if (ret < 0) + continue; + gpio = devm_kzalloc(pcs->dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) { + dev_err(pcs->dev, "failed to allocate pcs gpio\n"); + return -ENOMEM; + } + gpio->range.name = devm_kzalloc(pcs->dev, sizeof(name), + GFP_KERNEL); + if (!gpio->range.name) { + dev_err(pcs->dev, "failed to allocate range name\n"); + return -ENOMEM; + } + memcpy((char *)gpio->range.name, name, sizeof(name)); + + gpio->range.id = i++; + gpio->range.base = gpiores[0]; + gpio->gpio_func = gpiores[1]; + mux_bytes = pcs->width / BITS_PER_BYTE; + gpio->range.pin_base = (r.start - pcs->res->start) / mux_bytes; + gpio->range.npins = (r.end - r.start) / mux_bytes + 1; + + pinctrl_add_gpio_range(pcs->pctl, &gpio->range); + } + return 0; +} + static int __devinit pcs_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -975,6 +1047,10 @@ static int __devinit pcs_probe(struct platform_device *pdev) goto free; } + ret = pcs_add_gpio_range(np, pcs); + if (ret < 0) + goto free; + dev_info(pcs->dev, "%i pins at pa %p size %u\n", pcs->desc.npins, pcs->base, pcs->size); -- cgit v1.2.3 From af02dde8a609d8d071c4b31a82df811a55690a4a Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 21 Nov 2012 08:57:58 +0100 Subject: ALSA: hda - Add support for Realtek ALC292 We found a new codec ID 292, and that just a simple quirk would enable sound output/input on this ALC292 chip. BugLink: https://bugs.launchpad.net/bugs/1081466 Cc: stable@vger.kernel.org Tested-by: Acelan Kao Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 68fd49294b2..ad68d223f8a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7065,6 +7065,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, + { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, -- cgit v1.2.3 From 316511c0134acec8f4ea730bd1897c7a1124a7c1 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 21 Nov 2012 08:48:09 +0100 Subject: gpiolib: rename pin range arguments To be crystal clear on what the arguments mean in this funtion dealing with both GPIO and PIN ranges with confusing naming, we now have gpio_offset and pin_offset and we are on the clear that these are offsets into the specific GPIO and pin controller respectively. The GPIO chip itself will of course keep track of the base offset into the global GPIO number space. Reviewed-by: Viresh Kumar Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 19 ++++++++++--------- include/asm-generic/gpio.h | 4 ++-- include/linux/gpio.h | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 317ff0440e2..26e27c1fecb 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1191,13 +1191,13 @@ EXPORT_SYMBOL_GPL(gpiochip_find); * gpiochip_add_pin_range() - add a range for GPIO <-> pin mapping * @chip: the gpiochip to add the range for * @pinctrl_name: the dev_name() of the pin controller to map to - * @offset: the start offset in the current gpio_chip number space - * @pin_base: the start offset in the pin controller number space + * @gpio_offset: the start offset in the current gpio_chip number space + * @pin_offset: the start offset in the pin controller number space * @npins: the number of pins from the offset of each pin space (GPIO and * pin controller) to accumulate in this range */ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int offset, unsigned int pin_base, + unsigned int gpio_offset, unsigned int pin_offset, unsigned int npins) { struct gpio_pin_range *pin_range; @@ -1210,11 +1210,11 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, } /* Use local offset as range ID */ - pin_range->range.id = offset; + pin_range->range.id = gpio_offset; pin_range->range.gc = chip; pin_range->range.name = chip->label; - pin_range->range.base = chip->base + offset; - pin_range->range.pin_base = pin_base; + pin_range->range.base = chip->base + gpio_offset; + pin_range->range.pin_base = pin_offset; pin_range->range.npins = npins; pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, &pin_range->range); @@ -1224,9 +1224,10 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, kfree(pin_range); return PTR_ERR(pin_range->pctldev); } - pr_debug("%s: GPIO chip: created GPIO range %d->%d ==> PIN %d->%d\n", - chip->label, offset, offset + npins - 1, - pin_base, pin_base + npins - 1); + pr_debug("GPIO chip %s: created GPIO range %d->%d ==> %s PIN %d->%d\n", + chip->label, gpio_offset, gpio_offset + npins - 1, + pinctl_name, + pin_offset, pin_offset + npins - 1); list_add_tail(&pin_range->node, &chip->pin_ranges); diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index ec58fdbddb5..9fd3093d855 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -283,7 +283,7 @@ struct gpio_pin_range { }; int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int offset, unsigned int pin_base, + unsigned int gpio_offset, unsigned int pin_offset, unsigned int npins); void gpiochip_remove_pin_ranges(struct gpio_chip *chip); @@ -291,7 +291,7 @@ void gpiochip_remove_pin_ranges(struct gpio_chip *chip); static inline int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int offset, unsigned int pin_base, + unsigned int gpio_offset, unsigned int pin_offset, unsigned int npins) { return 0; diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 99861c65dd8..bfe66562153 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -233,7 +233,7 @@ static inline int irq_to_gpio(unsigned irq) static inline int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, - unsigned int offset, unsigned int pin_base, + unsigned int gpio_offset, unsigned int pin_offset, unsigned int npins) { WARN_ON(1); -- cgit v1.2.3 From b4d4b1f087b9d4d730eb70f24032395d7cd7e591 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 21 Nov 2012 14:33:56 +0800 Subject: gpiolib: Fix use after free in gpiochip_add_pin_range This is introduced by commit 9ab6e988 "gpiolib: return any error code from range creation". Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 26e27c1fecb..58b9838801c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1201,6 +1201,7 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, unsigned int npins) { struct gpio_pin_range *pin_range; + int ret; pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); if (!pin_range) { @@ -1219,10 +1220,11 @@ int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, pin_range->pctldev = pinctrl_find_and_add_gpio_range(pinctl_name, &pin_range->range); if (IS_ERR(pin_range->pctldev)) { + ret = PTR_ERR(pin_range->pctldev); pr_err("%s: GPIO chip: could not create pin range\n", chip->label); kfree(pin_range); - return PTR_ERR(pin_range->pctldev); + return ret; } pr_debug("GPIO chip %s: created GPIO range %d->%d ==> %s PIN %d->%d\n", chip->label, gpio_offset, gpio_offset + npins - 1, -- cgit v1.2.3 From 34c3d1926bdaf45d3a891dd577482abcdd9faa34 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 21 Nov 2012 10:03:10 +0100 Subject: ALSA: hda - Cirrus: Correctly clear line_out_pins when moving to speaker If this array is not cleared, the jack related code later might fail to create "Internal Speaker Phantom Jack" on Dell Inspiron 3420 and Dell Vostro 2420. BugLink: https://bugs.launchpad.net/bugs/1076840 Cc: stable@vger.kernel.org (3.6+) Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_cirrus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index d5f3a26d608..3bcb6717235 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -466,6 +466,7 @@ static int parse_output(struct hda_codec *codec) memcpy(cfg->speaker_pins, cfg->line_out_pins, sizeof(cfg->speaker_pins)); cfg->line_outs = 0; + memset(cfg->line_out_pins, 0, sizeof(cfg->line_out_pins)); } return 0; -- cgit v1.2.3 From 5edd0b946a0afeb1d0364a3654328b046fb818a2 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 20 Nov 2012 16:31:25 +0200 Subject: iwlwifi: fix the basic CCK rates calculation Fix a copy paste error in iwl_calc_basic_rates which leads to a wrong calculation of CCK basic rates. Cc: stable@vger.kernel.org Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/rxon.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index 10896393e5a..2830ea29050 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c @@ -1012,12 +1012,12 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv, * As a consequence, it's not as complicated as it sounds, just add * any lower rates to the ACK rate bitmap. */ - if (IWL_RATE_11M_INDEX < lowest_present_ofdm) - ofdm |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; - if (IWL_RATE_5M_INDEX < lowest_present_ofdm) - ofdm |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; - if (IWL_RATE_2M_INDEX < lowest_present_ofdm) - ofdm |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_11M_INDEX < lowest_present_cck) + cck |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_5M_INDEX < lowest_present_cck) + cck |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_2M_INDEX < lowest_present_cck) + cck |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; /* 1M already there or needed so always add */ cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE; -- cgit v1.2.3 From 88a693b5c1287be4da937699cb82068ce9db0135 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 8 Nov 2012 16:09:27 -0800 Subject: selinux: fix sel_netnode_insert() suspicious rcu dereference =============================== [ INFO: suspicious RCU usage. ] 3.5.0-rc1+ #63 Not tainted ------------------------------- security/selinux/netnode.c:178 suspicious rcu_dereference_check() usage! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 0 1 lock held by trinity-child1/8750: #0: (sel_netnode_lock){+.....}, at: [] sel_netnode_sid+0x16a/0x3e0 stack backtrace: Pid: 8750, comm: trinity-child1 Not tainted 3.5.0-rc1+ #63 Call Trace: [] lockdep_rcu_suspicious+0xfd/0x130 [] sel_netnode_sid+0x3b1/0x3e0 [] ? sel_netnode_find+0x1a0/0x1a0 [] selinux_socket_bind+0xf6/0x2c0 [] ? trace_hardirqs_off+0xd/0x10 [] ? lock_release_holdtime.part.9+0x15/0x1a0 [] ? lock_hrtimer_base+0x31/0x60 [] security_socket_bind+0x16/0x20 [] sys_bind+0x7a/0x100 [] ? sysret_check+0x22/0x5d [] ? trace_hardirqs_on_caller+0x10d/0x1a0 [] ? trace_hardirqs_on_thunk+0x3a/0x3f [] system_call_fastpath+0x16/0x1b This patch below does what Paul McKenney suggested in the previous thread. Signed-off-by: Dave Jones Reviewed-by: Paul E. McKenney Acked-by: Paul Moore Cc: Eric Paris Cc: Signed-off-by: Andrew Morton Signed-off-by: James Morris --- security/selinux/netnode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c index 28f911cdd7c..c5454c0477c 100644 --- a/security/selinux/netnode.c +++ b/security/selinux/netnode.c @@ -174,7 +174,8 @@ static void sel_netnode_insert(struct sel_netnode *node) if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) { struct sel_netnode *tail; tail = list_entry( - rcu_dereference(sel_netnode_hash[idx].list.prev), + rcu_dereference_protected(sel_netnode_hash[idx].list.prev, + lockdep_is_held(&sel_netnode_lock)), struct sel_netnode, list); list_del_rcu(&tail->list); kfree_rcu(tail, rcu); -- cgit v1.2.3 From 70b9b24d4d240ff5f6087bca4013c6969af275ab Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 22 Nov 2012 00:11:09 +0900 Subject: ARM: S3C24XX: Fix potential NULL pointer dereference error chan->end is tested for being NULL. However in the event that it is NULL, the subsequent assignment statement would lead to NULL pointer dereference. Thus dereferencing it only when it is not NULL. Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/plat-s3c24xx/dma.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index db98e7021f0..0abd1c46988 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c @@ -473,12 +473,13 @@ int s3c2410_dma_enqueue(enum dma_ch channel, void *id, pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n", chan->number, __func__, buf); - if (chan->end == NULL) + if (chan->end == NULL) { pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n", chan->number, __func__, chan); - - chan->end->next = buf; - chan->end = buf; + } else { + chan->end->next = buf; + chan->end = buf; + } } /* if necessary, update the next buffer field */ -- cgit v1.2.3 From 07c121149cb30405b37ceae3cd29e5b6b6e65cc0 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 15 Nov 2012 22:51:56 +0100 Subject: Documentation: Move common leds properties description to separate file. There are several drivers that use LEDs and depend on exactly the same device tree binding. However, the binding documentation has simply been cut-and-paste into each of the binding documents. Rather than continue to duplicate it, this patch adds a common led binding document that all can reference. Signed-off-by: Marek Belisko Reviewed-by: Stephen Warren Signed-off-by: Grant Likely --- Documentation/devicetree/bindings/gpio/led.txt | 14 ++++---------- Documentation/devicetree/bindings/leds/common.txt | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 Documentation/devicetree/bindings/leds/common.txt diff --git a/Documentation/devicetree/bindings/gpio/led.txt b/Documentation/devicetree/bindings/gpio/led.txt index edc83c1c0d5..df1b3080f6b 100644 --- a/Documentation/devicetree/bindings/gpio/led.txt +++ b/Documentation/devicetree/bindings/gpio/led.txt @@ -10,16 +10,10 @@ LED sub-node properties: - gpios : Should specify the LED's GPIO, see "gpios property" in Documentation/devicetree/bindings/gpio/gpio.txt. Active low LEDs should be indicated using flags in the GPIO specifier. -- label : (optional) The label for this LED. If omitted, the label is - taken from the node name (excluding the unit address). -- linux,default-trigger : (optional) This parameter, if present, is a - string defining the trigger assigned to the LED. Current triggers are: - "backlight" - LED will act as a back-light, controlled by the framebuffer - system - "default-on" - LED will turn on, but see "default-state" below - "heartbeat" - LED "double" flashes at a load average based rate - "ide-disk" - LED indicates disk activity - "timer" - LED flashes at a fixed, configurable rate +- label : (optional) + see Documentation/devicetree/bindings/leds/common.txt +- linux,default-trigger : (optional) + see Documentation/devicetree/bindings/leds/common.txt - default-state: (optional) The initial state of the LED. Valid values are "on", "off", and "keep". If the LED is already on or off and the default-state property is set the to same value, then no diff --git a/Documentation/devicetree/bindings/leds/common.txt b/Documentation/devicetree/bindings/leds/common.txt new file mode 100644 index 00000000000..2d88816dd55 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/common.txt @@ -0,0 +1,23 @@ +Common leds properties. + +Optional properties for child nodes: +- label : The label for this LED. If omitted, the label is + taken from the node name (excluding the unit address). + +- linux,default-trigger : This parameter, if present, is a + string defining the trigger assigned to the LED. Current triggers are: + "backlight" - LED will act as a back-light, controlled by the framebuffer + system + "default-on" - LED will turn on (but for leds-gpio see "default-state" + property in Documentation/devicetree/bindings/gpio/led.txt) + "heartbeat" - LED "double" flashes at a load average based rate + "ide-disk" - LED indicates disk activity + "timer" - LED flashes at a fixed, configurable rate + +Examples: + +system-status { + label = "Status"; + linux,default-trigger = "heartbeat"; + ... +}; -- cgit v1.2.3 From 4f3be1cfa8422c93271dcdb59f223f6c84c70804 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 16 Nov 2012 15:53:14 +0900 Subject: script: dtc: clean generated files Fix "make distclean" to clean up generated dtc files. Without this patch the following files are left around: - dtc-lexer.lex.c - dtc-parser.tab.c - dtc-parser.tab.h Signed-off-by: Magnus Damm Reviewed-by: Simon Horman Signed-off-by: Grant Likely --- scripts/dtc/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile index 6d1c6bb9f22..2a48022c41e 100644 --- a/scripts/dtc/Makefile +++ b/scripts/dtc/Makefile @@ -27,3 +27,5 @@ HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC) # dependencies on generated files need to be listed explicitly $(obj)/dtc-lexer.lex.o: $(obj)/dtc-parser.tab.h +# generated files need to be cleaned explicitly +clean-files := dtc-lexer.lex.c dtc-parser.tab.c dtc-parser.tab.h -- cgit v1.2.3 From 155dd0c2f7c24c1531a90229f1c749cebf3f21f7 Mon Sep 17 00:00:00 2001 From: "Chaiken, Alison" Date: Thu, 15 Nov 2012 23:32:51 +0000 Subject: Documentation: correct of_platform_populate() argument list The documentation doesn't match the actual function prototype. This is a trivial patch to fix it. Signed-off-by: Alison Chaiken Acked-by: Arnd Bergmann Signed-off-by: Grant Likely --- Documentation/devicetree/usage-model.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/usage-model.txt b/Documentation/devicetree/usage-model.txt index dca90fe22a9..ef9d06c9f8f 100644 --- a/Documentation/devicetree/usage-model.txt +++ b/Documentation/devicetree/usage-model.txt @@ -347,7 +347,7 @@ later), which will happily live at the base of the Linux /sys/devices tree. Therefore, if a DT node is at the root of the tree, then it really probably is best registered as a platform_device. -Linux board support code calls of_platform_populate(NULL, NULL, NULL) +Linux board support code calls of_platform_populate(NULL, NULL, NULL, NULL) to kick off discovery of devices at the root of the tree. The parameters are all NULL because when starting from the root of the tree, there is no need to provide a starting node (the first NULL), a -- cgit v1.2.3 From 8b41669ceba0c2d4c09d69ccb9a3458953dae784 Mon Sep 17 00:00:00 2001 From: Kalle Jokiniemi Date: Tue, 16 Oct 2012 17:59:35 +0300 Subject: mfd: twl4030: Fix chained irq handling on resume from suspend The irqs are enabled one-by-one in pm core resume_noirq phase. This leads to situation where the twl4030 primary interrupt handler (PIH) is enabled before the chained secondary handlers (SIH). As the PIH cannot clear the pending interrupt, and SIHs have not been enabled yet, a flood of interrupts hangs the device. Fixed the issue by setting the SIH irqs with IRQF_EARLY_RESUME flags, so they get enabled before the PIH. Signed-off-by: Kalle Jokiniemi Acked-by: Kevin Hilman Signed-off-by: Samuel Ortiz --- drivers/mfd/twl4030-irq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index ad733d76207..cdd1173ed4e 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -672,7 +672,8 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base) irq = sih_mod + twl4030_irq_base; irq_set_handler_data(irq, agent); agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name); - status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0, + status = request_threaded_irq(irq, NULL, handle_twl4030_sih, + IRQF_EARLY_RESUME, agent->irq_name ?: sih->name, NULL); dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name, -- cgit v1.2.3 From f36c374782e40a3812f729838b5b80d2ce601725 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 21 Nov 2012 02:02:16 +0000 Subject: xen/netfront: handle compound page fragments on transmit An SKB paged fragment can consist of a compound page with order > 0. However the netchannel protocol deals only in PAGE_SIZE frames. Handle this in xennet_make_frags by iterating over the frames which make up the page. This is the netfront equivalent to 6a8ed462f16b for netback. Signed-off-by: Ian Campbell Cc: netdev@vger.kernel.org Cc: xen-devel@lists.xen.org Cc: Eric Dumazet Cc: Konrad Rzeszutek Wilk Cc: ANNIE LI Cc: Sander Eikelenboom Cc: Stefan Bader Acked-by: Eric Dumazet Acked-by: Konrad Rzeszutek Wilk Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 98 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 21 deletions(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index caa011008cd..fc24eb9b394 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -452,29 +452,85 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev, /* Grant backend access to each skb fragment page. */ for (i = 0; i < frags; i++) { skb_frag_t *frag = skb_shinfo(skb)->frags + i; + struct page *page = skb_frag_page(frag); - tx->flags |= XEN_NETTXF_more_data; + len = skb_frag_size(frag); + offset = frag->page_offset; - id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs); - np->tx_skbs[id].skb = skb_get(skb); - tx = RING_GET_REQUEST(&np->tx, prod++); - tx->id = id; - ref = gnttab_claim_grant_reference(&np->gref_tx_head); - BUG_ON((signed short)ref < 0); + /* Data must not cross a page boundary. */ + BUG_ON(len + offset > PAGE_SIZE<xbdev->otherend_id, - mfn, GNTMAP_readonly); + /* Skip unused frames from start of page */ + page += offset >> PAGE_SHIFT; + offset &= ~PAGE_MASK; - tx->gref = np->grant_tx_ref[id] = ref; - tx->offset = frag->page_offset; - tx->size = skb_frag_size(frag); - tx->flags = 0; + while (len > 0) { + unsigned long bytes; + + BUG_ON(offset >= PAGE_SIZE); + + bytes = PAGE_SIZE - offset; + if (bytes > len) + bytes = len; + + tx->flags |= XEN_NETTXF_more_data; + + id = get_id_from_freelist(&np->tx_skb_freelist, + np->tx_skbs); + np->tx_skbs[id].skb = skb_get(skb); + tx = RING_GET_REQUEST(&np->tx, prod++); + tx->id = id; + ref = gnttab_claim_grant_reference(&np->gref_tx_head); + BUG_ON((signed short)ref < 0); + + mfn = pfn_to_mfn(page_to_pfn(page)); + gnttab_grant_foreign_access_ref(ref, + np->xbdev->otherend_id, + mfn, GNTMAP_readonly); + + tx->gref = np->grant_tx_ref[id] = ref; + tx->offset = offset; + tx->size = bytes; + tx->flags = 0; + + offset += bytes; + len -= bytes; + + /* Next frame */ + if (offset == PAGE_SIZE && len) { + BUG_ON(!PageCompound(page)); + page++; + offset = 0; + } + } } np->tx.req_prod_pvt = prod; } +/* + * Count how many ring slots are required to send the frags of this + * skb. Each frag might be a compound page. + */ +static int xennet_count_skb_frag_slots(struct sk_buff *skb) +{ + int i, frags = skb_shinfo(skb)->nr_frags; + int pages = 0; + + for (i = 0; i < frags; i++) { + skb_frag_t *frag = skb_shinfo(skb)->frags + i; + unsigned long size = skb_frag_size(frag); + unsigned long offset = frag->page_offset; + + /* Skip unused frames from start of page */ + offset &= ~PAGE_MASK; + + pages += PFN_UP(offset + size); + } + + return pages; +} + static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned short id; @@ -487,23 +543,23 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) grant_ref_t ref; unsigned long mfn; int notify; - int frags = skb_shinfo(skb)->nr_frags; + int slots; unsigned int offset = offset_in_page(data); unsigned int len = skb_headlen(skb); unsigned long flags; - frags += DIV_ROUND_UP(offset + len, PAGE_SIZE); - if (unlikely(frags > MAX_SKB_FRAGS + 1)) { - printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n", - frags); - dump_stack(); + slots = DIV_ROUND_UP(offset + len, PAGE_SIZE) + + xennet_count_skb_frag_slots(skb); + if (unlikely(slots > MAX_SKB_FRAGS + 1)) { + net_alert_ratelimited( + "xennet: skb rides the rocket: %d slots\n", slots); goto drop; } spin_lock_irqsave(&np->tx_lock, flags); if (unlikely(!netif_carrier_ok(dev) || - (frags > 1 && !xennet_can_sg(dev)) || + (slots > 1 && !xennet_can_sg(dev)) || netif_needs_gso(skb, netif_skb_features(skb)))) { spin_unlock_irqrestore(&np->tx_lock, flags); goto drop; -- cgit v1.2.3 From 0e376bd0b791ac6ac6bdb051492df0769c840848 Mon Sep 17 00:00:00 2001 From: Sarveshwar Bandi Date: Wed, 21 Nov 2012 04:35:03 +0000 Subject: bonding: Bonding driver does not consider the gso_max_size/gso_max_segs setting of slave devices. Patch sets the lowest gso_max_size and gso_max_segs values of the slave devices during enslave and detach. Signed-off-by: Sarveshwar Bandi Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b2530b00212..5f5b69f37d2 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1379,6 +1379,8 @@ static void bond_compute_features(struct bonding *bond) struct net_device *bond_dev = bond->dev; netdev_features_t vlan_features = BOND_VLAN_FEATURES; unsigned short max_hard_header_len = ETH_HLEN; + unsigned int gso_max_size = GSO_MAX_SIZE; + u16 gso_max_segs = GSO_MAX_SEGS; int i; unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE; @@ -1394,11 +1396,16 @@ static void bond_compute_features(struct bonding *bond) dst_release_flag &= slave->dev->priv_flags; if (slave->dev->hard_header_len > max_hard_header_len) max_hard_header_len = slave->dev->hard_header_len; + + gso_max_size = min(gso_max_size, slave->dev->gso_max_size); + gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs); } done: bond_dev->vlan_features = vlan_features; bond_dev->hard_header_len = max_hard_header_len; + bond_dev->gso_max_segs = gso_max_segs; + netif_set_gso_max_size(bond_dev, gso_max_size); flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE; bond_dev->priv_flags = flags | dst_release_flag; -- cgit v1.2.3 From 916492b1e1a186260951831c53a53d8a448dc026 Mon Sep 17 00:00:00 2001 From: Chun-Yi Lee Date: Wed, 21 Nov 2012 11:26:09 +0000 Subject: sign-file: fix the perl warning message when extracting ASN.1 There have the following warning message when running modules install for sign ko files: # make modules_install ... INSTALL drivers/input/touchscreen/pcap_ts.ko Found = in conditional, should be == at scripts/sign-file line 164. Found = in conditional, should be == at scripts/sign-file line 161. Found = in conditional, should be == at scripts/sign-file line 159. This patch change replace '=' by '==' in elsif conditions for avoid the above warning messages. Signed-off-by: Chun-Yi Lee Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- scripts/sign-file | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/sign-file b/scripts/sign-file index 87ca59d36e7..974a20b661b 100755 --- a/scripts/sign-file +++ b/scripts/sign-file @@ -156,12 +156,12 @@ sub asn1_extract($$@) if ($l == 0x1) { $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)); - } elsif ($l = 0x2) { + } elsif ($l == 0x2) { $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2)); - } elsif ($l = 0x3) { + } elsif ($l == 0x3) { $len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16; $len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2)); - } elsif ($l = 0x4) { + } elsif ($l == 0x4) { $len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4)); } else { die $x509, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n"; -- cgit v1.2.3 From 403f43c937d24832b18524f65415c0bbba6b5064 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 21 Nov 2012 02:34:45 +0000 Subject: team: bcast: convert return value of team_dev_queue_xmit() to bool correctly The thing is that team_dev_queue_xmit() returns NET_XMIT_* or -E*. bc_trasmit() should return true in case all went well. So use ! to get correct retval from team_dev_queue_xmit() result. This bug caused iface statistics to be badly computed. This bug was introduced by: team: add broadcast mode (5fc889911a99043a97da1daa0d010ad72cbc3042) Reported-by: Dan Carpenter Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team_mode_broadcast.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/team/team_mode_broadcast.c b/drivers/net/team/team_mode_broadcast.c index 9db0171e936..c5db428e73f 100644 --- a/drivers/net/team/team_mode_broadcast.c +++ b/drivers/net/team/team_mode_broadcast.c @@ -29,8 +29,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) if (last) { skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2) { - ret = team_dev_queue_xmit(team, last, - skb2); + ret = !team_dev_queue_xmit(team, last, + skb2); if (!sum_ret) sum_ret = ret; } @@ -39,7 +39,7 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb) } } if (last) { - ret = team_dev_queue_xmit(team, last, skb); + ret = !team_dev_queue_xmit(team, last, skb); if (!sum_ret) sum_ret = ret; } -- cgit v1.2.3 From be7fd3b86ad2f2a8db58decc15d2274b0c89c23b Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Wed, 21 Nov 2012 18:24:26 +0000 Subject: iio:adc:ad7298 make the tx and rx buffers __be16 These buffers are a little interesting in that their content may have variable endianness, but all but one element will definitely be big endian. Reported-by: kbuild test robot Signed-off-by: Jonathan Cameron Acked-by: Lars-Peter Clausen --- drivers/iio/adc/ad7298.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/ad7298.c b/drivers/iio/adc/ad7298.c index 441a9a265c1..2364807a5d6 100644 --- a/drivers/iio/adc/ad7298.c +++ b/drivers/iio/adc/ad7298.c @@ -54,8 +54,8 @@ struct ad7298_state { * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines. */ - unsigned short rx_buf[12] ____cacheline_aligned; - unsigned short tx_buf[2]; + __be16 rx_buf[12] ____cacheline_aligned; + __be16 tx_buf[2]; }; #define AD7298_V_CHAN(index) \ -- cgit v1.2.3 From 5d3df935426271016b895aecaa247101b4bfa35e Mon Sep 17 00:00:00 2001 From: Russell King - ARM Linux Date: Sun, 18 Nov 2012 16:29:44 +0000 Subject: Dove: Attempt to fix PMU/RTC interrupts Fix the acknowledgement of PMU interrupts on Dove: some Dove hardware has not been sensibly designed so that interrupts can be handled in a race free manner. The PMU is one such instance. The pending (aka 'cause') register is a bunch of RW bits, meaning that these bits can be both cleared and set by software (confirmed on the Armada-510 on the cubox.) Hardware sets the appropriate bit when an interrupt is asserted, and software is required to clear the bits which are to be processed. If we write ~(1 << bit), then we end up asserting every other interrupt except the one we're processing. So, we need to do a read-modify-write cycle to clear the asserted bit. However, any interrupts which occur in the middle of this cycle will also be written back as zero, which will also clear the new interrupts. The upshot of this is: there is _no_ way to safely clear down interrupts in this register (and other similarly behaving interrupt pending registers on this device.) The patch below at least stops us creating new interrupts. Signed-off-by: Russell King Cc: stable@vger.kernel.org Signed-off-by: Jason Cooper --- arch/arm/mach-dove/irq.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c index 087711524e8..bc4344aa100 100644 --- a/arch/arm/mach-dove/irq.c +++ b/arch/arm/mach-dove/irq.c @@ -46,8 +46,20 @@ static void pmu_irq_ack(struct irq_data *d) int pin = irq_to_pmu(d->irq); u32 u; + /* + * The PMU mask register is not RW0C: it is RW. This means that + * the bits take whatever value is written to them; if you write + * a '1', you will set the interrupt. + * + * Unfortunately this means there is NO race free way to clear + * these interrupts. + * + * So, let's structure the code so that the window is as small as + * possible. + */ u = ~(1 << (pin & 31)); - writel(u, PMU_INTERRUPT_CAUSE); + u &= readl_relaxed(PMU_INTERRUPT_CAUSE); + writel_relaxed(u, PMU_INTERRUPT_CAUSE); } static struct irq_chip pmu_irq_chip = { -- cgit v1.2.3 From d356cf5a74afa32b40decca3c9dd88bc3cd63eb5 Mon Sep 17 00:00:00 2001 From: Russell King - ARM Linux Date: Sun, 18 Nov 2012 16:39:32 +0000 Subject: Dove: Fix irq_to_pmu() PMU interrupts start at IRQ_DOVE_PMU_START, not IRQ_DOVE_PMU_START + 1. Fix the condition. (It may have been less likely to occur had the code been written "if (irq >= IRQ_DOVE_PMU_START" which imho is the easier to understand notation, and matches the normal way of thinking about these things.) Signed-off-by: Russell King Cc: stable@vger.kernel.org Signed-off-by: Jason Cooper --- arch/arm/mach-dove/include/mach/pm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-dove/include/mach/pm.h b/arch/arm/mach-dove/include/mach/pm.h index 7bcd0dfce4b..b47f7503868 100644 --- a/arch/arm/mach-dove/include/mach/pm.h +++ b/arch/arm/mach-dove/include/mach/pm.h @@ -63,7 +63,7 @@ static inline int pmu_to_irq(int pin) static inline int irq_to_pmu(int irq) { - if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS) + if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS) return irq - IRQ_DOVE_PMU_START; return -EINVAL; -- cgit v1.2.3 From 1dc831bf53fddcc6443f74a39e72db5bcea4f15d Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Wed, 21 Nov 2012 00:19:06 -0700 Subject: ARM: Kirkwood: Update PCI-E fixup - The code relies on rc_pci_fixup being called, which only happens when CONFIG_PCI_QUIRKS is enabled, so add that to Kconfig. Omitting this causes a booting failure with a non-obvious cause. - Update rc_pci_fixup to set the class properly, copying the more modern style from other places - Correct the rc_pci_fixup comment Signed-off-by: Jason Gunthorpe Cc: stable@vger.kernel.org Signed-off-by: Jason Cooper --- arch/arm/Kconfig | 1 + arch/arm/mach-kirkwood/pcie.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ade7e924bef..9759fec0b70 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -547,6 +547,7 @@ config ARCH_KIRKWOOD select CPU_FEROCEON select GENERIC_CLOCKEVENTS select PCI + select PCI_QUIRKS select PLAT_ORION_LEGACY help Support for the following Marvell Kirkwood series SoCs: diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index ec544918b12..74fc5a074fc 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -207,14 +207,19 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) return 1; } +/* + * The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it + * is operating as a root complex this needs to be switched to + * PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on + * the device. Decoding setup is handled by the orion code. + */ static void __devinit rc_pci_fixup(struct pci_dev *dev) { - /* - * Prevent enumeration of root complex. - */ if (dev->bus->parent == NULL && dev->devfn == 0) { int i; + dev->class &= 0xff; + dev->class |= PCI_CLASS_BRIDGE_HOST << 8; for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { dev->resource[i].start = 0; dev->resource[i].end = 0; -- cgit v1.2.3 From 401301ccdf516fa4b3b90216414a2a15fb826208 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 22:39:31 +0100 Subject: clk: add GPLv2 headers to the Versatile clock files The GPLv2 headers were missing and the subsystem maintainer likes them so put them in. I am the copyright holder, so explicitly licensing these under the GPLv2. Reported-by: Mike Turquette Signed-off-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/clk/versatile/clk-icst.c | 6 ++++++ drivers/clk/versatile/clk-integrator.c | 10 +++++++++- drivers/clk/versatile/clk-realview.c | 8 ++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index f555b50a5fa..23d2d7ea1be 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c @@ -3,6 +3,12 @@ * We wrap the custom interface from into the generic * clock framework. * + * Copyright (C) 2012 Linus Walleij + * + * 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. + * * TODO: when all ARM reference designs are migrated to generic clocks, the * ICST clock code from the ARM tree should probably be merged into this * file. diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c index a5053921bf7..3c816ae17c1 100644 --- a/drivers/clk/versatile/clk-integrator.c +++ b/drivers/clk/versatile/clk-integrator.c @@ -1,8 +1,16 @@ +/* + * Clock driver for the ARM Integrator/AP and Integrator/CP boards + * Copyright (C) 2012 Linus Walleij + * + * 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. + */ +#include #include #include #include #include -#include #include #include diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c index e21a99cef37..fd2dbdbc269 100644 --- a/drivers/clk/versatile/clk-realview.c +++ b/drivers/clk/versatile/clk-realview.c @@ -1,3 +1,11 @@ +/* + * Clock driver for the ARM RealView boards + * Copyright (C) 2012 Linus Walleij + * + * 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. + */ #include #include #include -- cgit v1.2.3 From 7a9ad671ac0a0ec2fc86887a9416f837c0cfb801 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 23:01:04 +0100 Subject: clk: make ICST driver handle the VCO registers It turns out that all platforms using the ICST VCO are really just touching two registers, and in the same way as well: one register with the VCO configuration as such, and one lock register that makes it possible to write to the VCO. Factor this register read/write into the ICST driver so we can reuse it in the IM-PD1 driver. Signed-off-by: Linus Walleij Signed-off-by: Mike Turquette --- drivers/clk/versatile/clk-icst.c | 60 +++++++++++++++++++++++++++++----- drivers/clk/versatile/clk-icst.h | 14 ++++++-- drivers/clk/versatile/clk-integrator.c | 45 +++---------------------- drivers/clk/versatile/clk-realview.c | 57 ++++++++------------------------ 4 files changed, 81 insertions(+), 95 deletions(-) diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index 23d2d7ea1be..67ccf4aa727 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c @@ -17,33 +17,74 @@ #include #include #include +#include #include "clk-icst.h" /** * struct clk_icst - ICST VCO clock wrapper * @hw: corresponding clock hardware entry + * @vcoreg: VCO register address + * @lockreg: VCO lock register address * @params: parameters for this ICST instance * @rate: current rate - * @setvco: function to commit ICST settings to hardware */ struct clk_icst { struct clk_hw hw; + void __iomem *vcoreg; + void __iomem *lockreg; const struct icst_params *params; unsigned long rate; - struct icst_vco (*getvco)(void); - void (*setvco)(struct icst_vco); }; #define to_icst(_hw) container_of(_hw, struct clk_icst, hw) +/** + * vco_get() - get ICST VCO settings from a certain register + * @vcoreg: register containing the VCO settings + */ +static struct icst_vco vco_get(void __iomem *vcoreg) +{ + u32 val; + struct icst_vco vco; + + val = readl(vcoreg); + vco.v = val & 0x1ff; + vco.r = (val >> 9) & 0x7f; + vco.s = (val >> 16) & 03; + return vco; +} + +/** + * vco_set() - commit changes to an ICST VCO + * @locreg: register to poke to unlock the VCO for writing + * @vcoreg: register containing the VCO settings + * @vco: ICST VCO parameters to commit + */ +static void vco_set(void __iomem *lockreg, + void __iomem *vcoreg, + struct icst_vco vco) +{ + u32 val; + + val = readl(vcoreg) & ~0x7ffff; + val |= vco.v | (vco.r << 9) | (vco.s << 16); + + /* This magic unlocks the VCO so it can be controlled */ + writel(0xa05f, lockreg); + writel(val, vcoreg); + /* This locks the VCO again */ + writel(0, lockreg); +} + + static unsigned long icst_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_icst *icst = to_icst(hw); struct icst_vco vco; - vco = icst->getvco(); + vco = vco_get(icst->vcoreg); icst->rate = icst_hz(icst->params, vco); return icst->rate; } @@ -66,7 +107,7 @@ static int icst_set_rate(struct clk_hw *hw, unsigned long rate, vco = icst_hz_to_vco(icst->params, rate); icst->rate = icst_hz(icst->params, vco); - icst->setvco(vco); + vco_set(icst->vcoreg, icst->lockreg, vco); return 0; } @@ -76,8 +117,9 @@ static const struct clk_ops icst_ops = { .set_rate = icst_set_rate, }; -struct clk * __init icst_clk_register(struct device *dev, - const struct clk_icst_desc *desc) +struct clk *icst_clk_register(struct device *dev, + const struct clk_icst_desc *desc, + void __iomem *base) { struct clk *clk; struct clk_icst *icst; @@ -95,8 +137,8 @@ struct clk * __init icst_clk_register(struct device *dev, init.num_parents = 0; icst->hw.init = &init; icst->params = desc->params; - icst->getvco = desc->getvco; - icst->setvco = desc->setvco; + icst->vcoreg = base + desc->vco_offset; + icst->lockreg = base + desc->lock_offset; clk = clk_register(dev, &icst->hw); if (IS_ERR(clk)) diff --git a/drivers/clk/versatile/clk-icst.h b/drivers/clk/versatile/clk-icst.h index 71b4c56c141..dad51b6ffd0 100644 --- a/drivers/clk/versatile/clk-icst.h +++ b/drivers/clk/versatile/clk-icst.h @@ -1,10 +1,18 @@ #include +/** + * struct clk_icst_desc - descriptor for the ICST VCO + * @params: ICST parameters + * @vco_offset: offset to the ICST VCO from the provided memory base + * @lock_offset: offset to the ICST VCO locking register from the provided + * memory base + */ struct clk_icst_desc { const struct icst_params *params; - struct icst_vco (*getvco)(void); - void (*setvco)(struct icst_vco); + u32 vco_offset; + u32 lock_offset; }; struct clk *icst_clk_register(struct device *dev, - const struct clk_icst_desc *desc); + const struct clk_icst_desc *desc, + void __iomem *base); diff --git a/drivers/clk/versatile/clk-integrator.c b/drivers/clk/versatile/clk-integrator.c index 3c816ae17c1..08593b4ee2c 100644 --- a/drivers/clk/versatile/clk-integrator.c +++ b/drivers/clk/versatile/clk-integrator.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include @@ -22,42 +22,6 @@ * Inspired by portions of: * plat-versatile/clock.c and plat-versatile/include/plat/clock.h */ -#define CM_LOCK (__io_address(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET) -#define CM_AUXOSC (__io_address(INTEGRATOR_HDR_BASE)+0x1c) - -/** - * cp_auxvco_get() - get ICST VCO settings for the Integrator/CP - * @vco: ICST VCO parameters to update with hardware status - */ -static struct icst_vco cp_auxvco_get(void) -{ - u32 val; - struct icst_vco vco; - - val = readl(CM_AUXOSC); - vco.v = val & 0x1ff; - vco.r = (val >> 9) & 0x7f; - vco.s = (val >> 16) & 03; - return vco; -} - -/** - * cp_auxvco_set() - commit changes to Integrator/CP ICST VCO - * @vco: ICST VCO parameters to commit - */ -static void cp_auxvco_set(struct icst_vco vco) -{ - u32 val; - - val = readl(CM_AUXOSC) & ~0x7ffff; - val |= vco.v | (vco.r << 9) | (vco.s << 16); - - /* This magic unlocks the CM VCO so it can be controlled */ - writel(0xa05f, CM_LOCK); - writel(val, CM_AUXOSC); - /* This locks the CM again */ - writel(0, CM_LOCK); -} static const struct icst_params cp_auxvco_params = { .ref = 24000000, @@ -73,8 +37,8 @@ static const struct icst_params cp_auxvco_params = { static const struct clk_icst_desc __initdata cp_icst_desc = { .params = &cp_auxvco_params, - .getvco = cp_auxvco_get, - .setvco = cp_auxvco_set, + .vco_offset = 0x1c, + .lock_offset = INTEGRATOR_HDR_LOCK_OFFSET, }; /* @@ -114,6 +78,7 @@ void __init integrator_clk_init(bool is_cp) clk_register_clkdev(clk, NULL, "sp804"); /* ICST VCO clock used on the Integrator/CP CLCD */ - clk = icst_clk_register(NULL, &cp_icst_desc); + clk = icst_clk_register(NULL, &cp_icst_desc, + __io_address(INTEGRATOR_HDR_BASE)); clk_register_clkdev(clk, NULL, "clcd"); } diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c index fd2dbdbc269..cda07e70a40 100644 --- a/drivers/clk/versatile/clk-realview.c +++ b/drivers/clk/versatile/clk-realview.c @@ -21,38 +21,6 @@ * Implementation of the ARM RealView clock trees. */ -static void __iomem *sys_lock; -static void __iomem *sys_vcoreg; - -/** - * realview_oscvco_get() - get ICST OSC settings for the RealView - */ -static struct icst_vco realview_oscvco_get(void) -{ - u32 val; - struct icst_vco vco; - - val = readl(sys_vcoreg); - vco.v = val & 0x1ff; - vco.r = (val >> 9) & 0x7f; - vco.s = (val >> 16) & 03; - return vco; -} - -static void realview_oscvco_set(struct icst_vco vco) -{ - u32 val; - - val = readl(sys_vcoreg) & ~0x7ffff; - val |= vco.v | (vco.r << 9) | (vco.s << 16); - - /* This magic unlocks the CM VCO so it can be controlled */ - writel(0xa05f, sys_lock); - writel(val, sys_vcoreg); - /* This locks the CM again */ - writel(0, sys_lock); -} - static const struct icst_params realview_oscvco_params = { .ref = 24000000, .vco_max = ICST307_VCO_MAX, @@ -65,10 +33,16 @@ static const struct icst_params realview_oscvco_params = { .idx2s = icst307_idx2s, }; -static const struct clk_icst_desc __initdata realview_icst_desc = { +static const struct clk_icst_desc __initdata realview_osc0_desc = { .params = &realview_oscvco_params, - .getvco = realview_oscvco_get, - .setvco = realview_oscvco_set, + .vco_offset = REALVIEW_SYS_OSC0_OFFSET, + .lock_offset = REALVIEW_SYS_LOCK_OFFSET, +}; + +static const struct clk_icst_desc __initdata realview_osc4_desc = { + .params = &realview_oscvco_params, + .vco_offset = REALVIEW_SYS_OSC4_OFFSET, + .lock_offset = REALVIEW_SYS_LOCK_OFFSET, }; /* @@ -78,13 +52,6 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) { struct clk *clk; - sys_lock = sysbase + REALVIEW_SYS_LOCK_OFFSET; - if (is_pb1176) - sys_vcoreg = sysbase + REALVIEW_SYS_OSC0_OFFSET; - else - sys_vcoreg = sysbase + REALVIEW_SYS_OSC4_OFFSET; - - /* APB clock dummy */ clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); clk_register_clkdev(clk, "apb_pclk", NULL); @@ -116,7 +83,11 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) clk_register_clkdev(clk, NULL, "sp804"); /* ICST VCO clock */ - clk = icst_clk_register(NULL, &realview_icst_desc); + if (is_pb1176) + clk = icst_clk_register(NULL, &realview_osc0_desc, sysbase); + else + clk = icst_clk_register(NULL, &realview_osc4_desc, sysbase); + clk_register_clkdev(clk, NULL, "dev:clcd"); clk_register_clkdev(clk, NULL, "issp:clcd"); } -- cgit v1.2.3 From 70ee65771424829fd092a1df9afcc7e24c94004b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 20 Nov 2012 22:39:49 +0100 Subject: clk: move IM-PD1 clocks to drivers/clk The ARM IM-PD1 add-on module has a few clock of its own, let's move also these down to the drivers/clk/versatile driver dir and get rid of any remaining oldschool Integrator clocks. Signed-off-by: Linus Walleij Signed-off-by: Mike Turquette --- arch/arm/mach-integrator/impd1.c | 69 +------------------- drivers/clk/versatile/Makefile | 1 + drivers/clk/versatile/clk-impd1.c | 97 ++++++++++++++++++++++++++++ include/linux/platform_data/clk-integrator.h | 2 + 4 files changed, 103 insertions(+), 66 deletions(-) create mode 100644 drivers/clk/versatile/clk-impd1.c diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index e428f3ab15c..b3d86d7081a 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -21,10 +21,9 @@ #include #include #include +#include #include -#include -#include #include #include #include @@ -36,45 +35,6 @@ MODULE_PARM_DESC(lmid, "logic module stack position"); struct impd1_module { void __iomem *base; - struct clk vcos[2]; - struct clk_lookup *clks[3]; -}; - -static const struct icst_params impd1_vco_params = { - .ref = 24000000, /* 24 MHz */ - .vco_max = ICST525_VCO_MAX_3V, - .vco_min = ICST525_VCO_MIN, - .vd_min = 12, - .vd_max = 519, - .rd_min = 3, - .rd_max = 120, - .s2div = icst525_s2div, - .idx2s = icst525_idx2s, -}; - -static void impd1_setvco(struct clk *clk, struct icst_vco vco) -{ - struct impd1_module *impd1 = clk->data; - u32 val = vco.v | (vco.r << 9) | (vco.s << 16); - - writel(0xa05f, impd1->base + IMPD1_LOCK); - writel(val, clk->vcoreg); - writel(0, impd1->base + IMPD1_LOCK); - -#ifdef DEBUG - vco.v = val & 0x1ff; - vco.r = (val >> 9) & 0x7f; - vco.s = (val >> 16) & 7; - - pr_debug("IM-PD1: VCO%d clock is %ld Hz\n", - vconr, icst525_hz(&impd1_vco_params, vco)); -#endif -} - -static const struct clk_ops impd1_clk_ops = { - .round = icst_clk_round, - .set = icst_clk_set, - .setvco = impd1_setvco, }; void impd1_tweak_control(struct device *dev, u32 mask, u32 val) @@ -344,10 +304,6 @@ static struct impd1_device impd1_devs[] = { } }; -static struct clk fixed_14745600 = { - .rate = 14745600, -}; - static int impd1_probe(struct lm_device *dev) { struct impd1_module *impd1; @@ -376,23 +332,7 @@ static int impd1_probe(struct lm_device *dev) printk("IM-PD1 found at 0x%08lx\n", (unsigned long)dev->resource.start); - for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++) { - impd1->vcos[i].ops = &impd1_clk_ops, - impd1->vcos[i].owner = THIS_MODULE, - impd1->vcos[i].params = &impd1_vco_params, - impd1->vcos[i].data = impd1; - } - impd1->vcos[0].vcoreg = impd1->base + IMPD1_OSC1; - impd1->vcos[1].vcoreg = impd1->base + IMPD1_OSC2; - - impd1->clks[0] = clkdev_alloc(&impd1->vcos[0], NULL, "lm%x:01000", - dev->id); - impd1->clks[1] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00100", - dev->id); - impd1->clks[2] = clkdev_alloc(&fixed_14745600, NULL, "lm%x:00200", - dev->id); - for (i = 0; i < ARRAY_SIZE(impd1->clks); i++) - clkdev_add(impd1->clks[i]); + integrator_impd1_clk_init(impd1->base, dev->id); for (i = 0; i < ARRAY_SIZE(impd1_devs); i++) { struct impd1_device *idev = impd1_devs + i; @@ -431,12 +371,9 @@ static int impd1_remove_one(struct device *dev, void *data) static void impd1_remove(struct lm_device *dev) { struct impd1_module *impd1 = lm_get_drvdata(dev); - int i; device_for_each_child(&dev->dev, NULL, impd1_remove_one); - - for (i = 0; i < ARRAY_SIZE(impd1->clks); i++) - clkdev_drop(impd1->clks[i]); + integrator_impd1_clk_exit(dev->id); lm_set_drvdata(dev, NULL); diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile index c776053e5bb..ec3b88fe3e6 100644 --- a/drivers/clk/versatile/Makefile +++ b/drivers/clk/versatile/Makefile @@ -1,6 +1,7 @@ # Makefile for Versatile-specific clocks obj-$(CONFIG_ICST) += clk-icst.o obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o +obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o obj-$(CONFIG_ARCH_VEXPRESS) += clk-vexpress.o obj-$(CONFIG_VEXPRESS_CONFIG) += clk-vexpress-osc.o diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c new file mode 100644 index 00000000000..369139af2a3 --- /dev/null +++ b/drivers/clk/versatile/clk-impd1.c @@ -0,0 +1,97 @@ +/* + * Clock driver for the ARM Integrator/IM-PD1 board + * Copyright (C) 2012 Linus Walleij + * + * 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. + */ +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-icst.h" + +struct impd1_clk { + struct clk *vcoclk; + struct clk *uartclk; + struct clk_lookup *clks[3]; +}; + +static struct impd1_clk impd1_clks[4]; + +/* + * There are two VCO's on the IM-PD1 but only one is used by the + * kernel, that is why we are only implementing the control of + * IMPD1_OSC1 here. + */ + +static const struct icst_params impd1_vco_params = { + .ref = 24000000, /* 24 MHz */ + .vco_max = ICST525_VCO_MAX_3V, + .vco_min = ICST525_VCO_MIN, + .vd_min = 12, + .vd_max = 519, + .rd_min = 3, + .rd_max = 120, + .s2div = icst525_s2div, + .idx2s = icst525_idx2s, +}; + +static const struct clk_icst_desc impd1_icst1_desc = { + .params = &impd1_vco_params, + .vco_offset = IMPD1_OSC1, + .lock_offset = IMPD1_LOCK, +}; + +/** + * integrator_impd1_clk_init() - set up the integrator clock tree + * @base: base address of the logic module (LM) + * @id: the ID of this LM + */ +void integrator_impd1_clk_init(void __iomem *base, unsigned int id) +{ + struct impd1_clk *imc; + struct clk *clk; + int i; + + if (id > 3) { + pr_crit("no more than 4 LMs can be attached\n"); + return; + } + imc = &impd1_clks[id]; + + clk = icst_clk_register(NULL, &impd1_icst1_desc, base); + imc->vcoclk = clk; + imc->clks[0] = clkdev_alloc(clk, NULL, "lm%x:01000", id); + + /* UART reference clock */ + clk = clk_register_fixed_rate(NULL, "uartclk", NULL, CLK_IS_ROOT, + 14745600); + imc->uartclk = clk; + imc->clks[1] = clkdev_alloc(clk, NULL, "lm%x:00100", id); + imc->clks[2] = clkdev_alloc(clk, NULL, "lm%x:00200", id); + + for (i = 0; i < ARRAY_SIZE(imc->clks); i++) + clkdev_add(imc->clks[i]); +} + +void integrator_impd1_clk_exit(unsigned int id) +{ + int i; + struct impd1_clk *imc; + + if (id > 3) + return; + imc = &impd1_clks[id]; + + for (i = 0; i < ARRAY_SIZE(imc->clks); i++) + clkdev_drop(imc->clks[i]); + clk_unregister(imc->uartclk); + clk_unregister(imc->vcoclk); +} diff --git a/include/linux/platform_data/clk-integrator.h b/include/linux/platform_data/clk-integrator.h index 83fe9c283bb..280edac9d0a 100644 --- a/include/linux/platform_data/clk-integrator.h +++ b/include/linux/platform_data/clk-integrator.h @@ -1 +1,3 @@ void integrator_clk_init(bool is_cp); +void integrator_impd1_clk_init(void __iomem *base, unsigned int id); +void integrator_impd1_clk_exit(unsigned int id); -- cgit v1.2.3 From 809396474f41fb6e7e676e298d79856c5e02d755 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 16 Oct 2012 05:46:21 -0300 Subject: [media] adv7604: cleanup references Signed-off-by: Mats Randgaard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 109bc9b12e7..75a8395b899 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -1123,7 +1123,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd, adv7604_fill_optional_dv_timings_fields(sd, timings); } else { /* find format - * Since LCVS values are inaccurate (REF_03, page 275-276), + * Since LCVS values are inaccurate [REF_03, p. 275-276], * stdi2dv_timings() is called with lcvs +-1 if the first attempt fails. */ if (!stdi2dv_timings(sd, &stdi, timings)) @@ -1712,9 +1712,9 @@ static int adv7604_core_init(struct v4l2_subdev *sd) cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); /* HDMI free run */ cp_write(sd, 0xf3, 0xdc); /* Low threshold to enter/exit free run mode */ cp_write(sd, 0xf9, 0x23); /* STDI ch. 1 - LCVS change threshold - - ADI recommended setting [REF_01 c. 2.3.3] */ + ADI recommended setting [REF_01, c. 2.3.3] */ cp_write(sd, 0x45, 0x23); /* STDI ch. 2 - LCVS change threshold - - ADI recommended setting [REF_01 c. 2.3.3] */ + ADI recommended setting [REF_01, c. 2.3.3] */ cp_write(sd, 0xc9, 0x2d); /* use prim_mode and vid_std as free run resolution for digital formats */ -- cgit v1.2.3 From 6b0d5d344a78d43957a9f49c549b6f3aa2dc2082 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 16 Oct 2012 06:40:45 -0300 Subject: [media] adv7604: Replace prim_mode by mode Changes the way the primary mode is handled: - Remove it from platform_data since it doesn't belong there. - Add a new mode enum for use with s_routing. - Collapse the two HDMI modes into one HDMI mode: when setting up the timings manually we do not need to select HDMI_COMP mode. That's only needed when selecting a preset. This patch prepares for the next step where we switch to using the presets where available. Signed-off-by: Mats Randgaard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 78 +++++++++++++++++---------------------------- include/media/adv7604.h | 21 ++++++------ 2 files changed, 39 insertions(+), 60 deletions(-) diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 75a8395b899..74a18c0fc10 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -53,8 +53,7 @@ MODULE_LICENSE("GPL"); /* ADV7604 system clock frequency */ #define ADV7604_fsc (28636360) -#define DIGITAL_INPUT ((state->prim_mode == ADV7604_PRIM_MODE_HDMI_COMP) || \ - (state->prim_mode == ADV7604_PRIM_MODE_HDMI_GR)) +#define DIGITAL_INPUT (state->mode == ADV7604_MODE_HDMI) /* ********************************************************************** @@ -68,7 +67,7 @@ struct adv7604_state { struct v4l2_subdev sd; struct media_pad pad; struct v4l2_ctrl_handler hdl; - enum adv7604_prim_mode prim_mode; + enum adv7604_mode mode; struct v4l2_dv_timings timings; u8 edid[256]; unsigned edid_blocks; @@ -738,12 +737,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) switch (state->rgb_quantization_range) { case V4L2_DV_RGB_RANGE_AUTO: /* automatic */ - if ((hdmi_read(sd, 0x05) & 0x80) || - (state->prim_mode == ADV7604_PRIM_MODE_COMP) || - (state->prim_mode == ADV7604_PRIM_MODE_RGB)) { - /* receiving HDMI or analog signal */ - io_write_and_or(sd, 0x02, 0x0f, 0xf0); - } else { + if (DIGITAL_INPUT && !(hdmi_read(sd, 0x05) & 0x80)) { /* receiving DVI-D signal */ /* ADV7604 selects RGB limited range regardless of @@ -756,6 +750,9 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd) /* RGB full range (0-255) */ io_write_and_or(sd, 0x02, 0x0f, 0x10); } + } else { + /* receiving HDMI or analog signal, set automode */ + io_write_and_or(sd, 0x02, 0x0f, 0xf0); } break; case V4L2_DV_RGB_RANGE_LIMITED: @@ -1203,24 +1200,25 @@ static int adv7604_g_dv_timings(struct v4l2_subdev *sd, return 0; } -static void enable_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) +static void enable_input(struct v4l2_subdev *sd) { - switch (prim_mode) { - case ADV7604_PRIM_MODE_COMP: - case ADV7604_PRIM_MODE_RGB: + struct adv7604_state *state = to_state(sd); + + switch (state->mode) { + case ADV7604_MODE_COMP: + case ADV7604_MODE_GR: /* enable */ io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */ break; - case ADV7604_PRIM_MODE_HDMI_COMP: - case ADV7604_PRIM_MODE_HDMI_GR: + case ADV7604_MODE_HDMI: /* enable */ hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */ hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */ io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */ break; default: - v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", - __func__, prim_mode); + v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", + __func__, state->mode); break; } } @@ -1233,11 +1231,13 @@ static void disable_input(struct v4l2_subdev *sd) hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */ } -static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode) +static void select_input(struct v4l2_subdev *sd) { - switch (prim_mode) { - case ADV7604_PRIM_MODE_COMP: - case ADV7604_PRIM_MODE_RGB: + struct adv7604_state *state = to_state(sd); + + switch (state->mode) { + case ADV7604_MODE_COMP: + case ADV7604_MODE_GR: /* set mode and select free run resolution */ io_write(sd, 0x00, 0x07); /* video std */ io_write(sd, 0x01, 0x02); /* prim mode */ @@ -1271,13 +1271,10 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */ break; - case ADV7604_PRIM_MODE_HDMI_COMP: - case ADV7604_PRIM_MODE_HDMI_GR: + case ADV7604_MODE_HDMI: /* set mode and select free run resolution */ - /* video std */ - io_write(sd, 0x00, - (prim_mode == ADV7604_PRIM_MODE_HDMI_GR) ? 0x02 : 0x1e); - io_write(sd, 0x01, prim_mode); /* prim mode */ + io_write(sd, 0x00, 0x02); /* video std */ + io_write(sd, 0x01, 0x06); /* prim mode */ /* disable embedded syncs for auto graphics mode */ cp_write_and_or(sd, 0x81, 0xef, 0x00); @@ -1309,7 +1306,8 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod break; default: - v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", __func__, prim_mode); + v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", + __func__, state->mode); break; } } @@ -1321,26 +1319,13 @@ static int adv7604_s_routing(struct v4l2_subdev *sd, v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input); - switch (input) { - case 0: - /* TODO select HDMI_COMP or HDMI_GR */ - state->prim_mode = ADV7604_PRIM_MODE_HDMI_COMP; - break; - case 1: - state->prim_mode = ADV7604_PRIM_MODE_RGB; - break; - case 2: - state->prim_mode = ADV7604_PRIM_MODE_COMP; - break; - default: - return -EINVAL; - } + state->mode = input; disable_input(sd); - select_input(sd, state->prim_mode); + select_input(sd); - enable_input(sd, state->prim_mode); + enable_input(sd); return 0; } @@ -1724,11 +1709,6 @@ static int adv7604_core_init(struct v4l2_subdev *sd) afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */ io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4); - state->prim_mode = pdata->prim_mode; - select_input(sd, pdata->prim_mode); - - enable_input(sd, pdata->prim_mode); - /* interrupts */ io_write(sd, 0x40, 0xc2); /* Configure INT1 */ io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */ diff --git a/include/media/adv7604.h b/include/media/adv7604.h index 171b957db74..dc004bc926c 100644 --- a/include/media/adv7604.h +++ b/include/media/adv7604.h @@ -40,14 +40,6 @@ enum adv7604_op_ch_sel { ADV7604_OP_CH_SEL_RBG = 5, }; -/* Primary mode (IO register 0x01, [3:0]) */ -enum adv7604_prim_mode { - ADV7604_PRIM_MODE_COMP = 1, - ADV7604_PRIM_MODE_RGB = 2, - ADV7604_PRIM_MODE_HDMI_COMP = 5, - ADV7604_PRIM_MODE_HDMI_GR = 6, -}; - /* Input Color Space (IO register 0x02, [7:4]) */ enum adv7604_inp_color_space { ADV7604_INP_COLOR_SPACE_LIM_RGB = 0, @@ -103,9 +95,6 @@ struct adv7604_platform_data { /* Bus rotation and reordering */ enum adv7604_op_ch_sel op_ch_sel; - /* Primary mode */ - enum adv7604_prim_mode prim_mode; - /* Select output format */ enum adv7604_op_format_sel op_format_sel; @@ -142,6 +131,16 @@ struct adv7604_platform_data { u8 i2c_vdp; }; +/* + * Mode of operation. + * This is used as the input argument of the s_routing video op. + */ +enum adv7604_mode { + ADV7604_MODE_COMP, + ADV7604_MODE_GR, + ADV7604_MODE_HDMI, +}; + #define V4L2_CID_ADV_RX_ANALOG_SAMPLING_PHASE (V4L2_CID_DV_CLASS_BASE + 0x1000) #define V4L2_CID_ADV_RX_FREE_RUN_COLOR_MANUAL (V4L2_CID_DV_CLASS_BASE + 0x1001) #define V4L2_CID_ADV_RX_FREE_RUN_COLOR (V4L2_CID_DV_CLASS_BASE + 0x1002) -- cgit v1.2.3 From df2449aba4749fb8d04c3c1bbfad5cf8863c323b Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Sat, 10 Nov 2012 12:13:40 +0530 Subject: CLK: SPEAr: Fix dev_id & con_id for multiple clocks dev_id & con_id names of multiple clocks are incorrect. This patch fixes these names with the names that come via DT. Signed-off-by: Rajeev Kumar Signed-off-by: Shiraz Hashim Signed-off-by: Bhavna Yadav Signed-off-by: Vipul Kumar Samar Signed-off-by: Deepak Sikri Signed-off-by: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/spear1310_clock.c | 30 +++++++++++++------------- drivers/clk/spear/spear1340_clock.c | 42 +++++++++++++++++++------------------ drivers/clk/spear/spear3xx_clock.c | 12 ++++++----- drivers/clk/spear/spear6xx_clock.c | 6 ++++-- 4 files changed, 49 insertions(+), 41 deletions(-) diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index 0fcec2aae19..f13b1d23b4a 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -401,7 +401,7 @@ void __init spear1310_clk_init(void) clk = clk_register_gate(NULL, "rtc-spear", "osc_32k_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_RTC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "fc900000.rtc"); + clk_register_clkdev(clk, NULL, "e0580000.rtc"); /* clock derived from 24 or 25 MHz osc clk */ /* vco-pll */ @@ -615,7 +615,7 @@ void __init spear1310_clk_init(void) ARRAY_SIZE(gmac_phy_parents), 0, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_GMAC_PHY_CLK_SHIFT, SPEAR1310_GMAC_PHY_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, NULL, "stmmacphy.0"); + clk_register_clkdev(clk, "stmmacphy.0", NULL); /* clcd */ clk = clk_register_mux(NULL, "clcd_syn_mclk", clcd_synth_parents, @@ -638,7 +638,7 @@ void __init spear1310_clk_init(void) clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mclk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CLCD_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, "clcd_clk", NULL); + clk_register_clkdev(clk, NULL, "e1000000.clcd"); /* i2s */ clk = clk_register_mux(NULL, "i2s_src_mclk", i2s_src_parents, @@ -705,35 +705,37 @@ void __init spear1310_clk_init(void) clk = clk_register_gate(NULL, "usbh0_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UHC0_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, "usbh.0_clk", NULL); + clk_register_clkdev(clk, NULL, "e4000000.ohci"); + clk_register_clkdev(clk, NULL, "e4800000.ehci"); clk = clk_register_gate(NULL, "usbh1_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UHC1_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, "usbh.1_clk", NULL); + clk_register_clkdev(clk, NULL, "e5000000.ohci"); + clk_register_clkdev(clk, NULL, "e5800000.ehci"); clk = clk_register_gate(NULL, "uoc_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UOC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "uoc"); + clk_register_clkdev(clk, NULL, "e3800000.otg"); clk = clk_register_gate(NULL, "pcie_sata_0_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_0_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "dw_pcie.0"); - clk_register_clkdev(clk, NULL, "ahci.0"); + clk_register_clkdev(clk, NULL, "b1000000.ahci"); clk = clk_register_gate(NULL, "pcie_sata_1_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_1_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "dw_pcie.1"); - clk_register_clkdev(clk, NULL, "ahci.1"); + clk_register_clkdev(clk, NULL, "b1800000.ahci"); clk = clk_register_gate(NULL, "pcie_sata_2_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_PCIE_SATA_2_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "dw_pcie.2"); - clk_register_clkdev(clk, NULL, "ahci.2"); + clk_register_clkdev(clk, NULL, "b4000000.ahci"); clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_SYSRAM0_CLK_ENB, 0, @@ -754,7 +756,7 @@ void __init spear1310_clk_init(void) clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_ADC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "adc_clk"); + clk_register_clkdev(clk, NULL, "e0080000.adc"); /* clock derived from apb clk */ clk = clk_register_gate(NULL, "ssp0_clk", "apb_clk", 0, @@ -916,15 +918,15 @@ void __init spear1310_clk_init(void) SPEAR1310_RAS_CTRL_REG1, SPEAR1310_SMII_RGMII_PHY_CLK_SHIFT, SPEAR1310_PHY_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, NULL, "stmmacphy.1"); - clk_register_clkdev(clk, NULL, "stmmacphy.2"); - clk_register_clkdev(clk, NULL, "stmmacphy.4"); + clk_register_clkdev(clk, "stmmacphy.1", NULL); + clk_register_clkdev(clk, "stmmacphy.2", NULL); + clk_register_clkdev(clk, "stmmacphy.4", NULL); clk = clk_register_mux(NULL, "rmii_phy_mclk", rmii_phy_parents, ARRAY_SIZE(rmii_phy_parents), 0, SPEAR1310_RAS_CTRL_REG1, SPEAR1310_RMII_PHY_CLK_SHIFT, SPEAR1310_PHY_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, NULL, "stmmacphy.3"); + clk_register_clkdev(clk, "stmmacphy.3", NULL); clk = clk_register_mux(NULL, "uart1_mclk", uart_parents, ARRAY_SIZE(uart_parents), 0, SPEAR1310_RAS_CTRL_REG0, diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index 2352cee7f64..dae2ba60a8f 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -425,7 +425,7 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "rtc-spear", "osc_32k_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_RTC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "fc900000.rtc"); + clk_register_clkdev(clk, NULL, "e0580000.rtc"); /* clock derived from 24 or 25 MHz osc clk */ /* vco-pll */ @@ -499,7 +499,7 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "thermal_gclk", "thermal_clk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_THSENS_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "spear_thermal"); + clk_register_clkdev(clk, NULL, "e07008c4.thermal"); /* clock derived from pll4 clk */ clk = clk_register_fixed_factor(NULL, "ddr_clk", "pll4_clk", 0, 1, @@ -659,7 +659,7 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_C3_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "c3"); + clk_register_clkdev(clk, NULL, "e1800000.c3"); /* gmac */ clk = clk_register_mux(NULL, "phy_input_mclk", gmac_phy_input_parents, @@ -679,7 +679,7 @@ void __init spear1340_clk_init(void) ARRAY_SIZE(gmac_phy_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_GMAC_PHY_CLK_SHIFT, SPEAR1340_GMAC_PHY_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, NULL, "stmmacphy.0"); + clk_register_clkdev(clk, "stmmacphy.0", NULL); /* clcd */ clk = clk_register_mux(NULL, "clcd_syn_mclk", clcd_synth_parents, @@ -702,7 +702,7 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mclk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CLCD_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, "clcd_clk", NULL); + clk_register_clkdev(clk, NULL, "e1000000.clcd"); /* i2s */ clk = clk_register_mux(NULL, "i2s_src_mclk", i2s_src_parents, @@ -769,23 +769,25 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "usbh0_clk", "ahb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UHC0_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, "usbh.0_clk", NULL); + clk_register_clkdev(clk, NULL, "e4000000.ohci"); + clk_register_clkdev(clk, NULL, "e4800000.ehci"); clk = clk_register_gate(NULL, "usbh1_clk", "ahb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UHC1_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, "usbh.1_clk", NULL); + clk_register_clkdev(clk, NULL, "e5000000.ohci"); + clk_register_clkdev(clk, NULL, "e5800000.ehci"); clk = clk_register_gate(NULL, "uoc_clk", "ahb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UOC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "uoc"); + clk_register_clkdev(clk, NULL, "e3800000.otg"); clk = clk_register_gate(NULL, "pcie_sata_clk", "ahb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_PCIE_SATA_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "dw_pcie"); - clk_register_clkdev(clk, NULL, "ahci"); + clk_register_clkdev(clk, NULL, "b1000000.ahci"); clk = clk_register_gate(NULL, "sysram0_clk", "ahb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_SYSRAM0_CLK_ENB, 0, @@ -806,7 +808,7 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_ADC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "adc_clk"); + clk_register_clkdev(clk, NULL, "e0080000.adc"); /* clock derived from apb clk */ clk = clk_register_gate(NULL, "ssp_clk", "apb_clk", 0, @@ -827,12 +829,12 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "i2s_play_clk", "apb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_I2S_PLAY_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "b2400000.i2s"); + clk_register_clkdev(clk, NULL, "b2400000.i2s-play"); clk = clk_register_gate(NULL, "i2s_rec_clk", "apb_clk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_I2S_REC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "b2000000.i2s"); + clk_register_clkdev(clk, NULL, "b2000000.i2s-rec"); clk = clk_register_gate(NULL, "kbd_clk", "apb_clk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_KBD_CLK_ENB, 0, @@ -896,7 +898,7 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "spdif_out_clk", "spdif_out_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_OUT_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "spdif-out"); + clk_register_clkdev(clk, NULL, "d0000000.spdif-out"); clk = clk_register_mux(NULL, "spdif_in_mclk", spdif_in_parents, ARRAY_SIZE(spdif_in_parents), 0, @@ -907,7 +909,7 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "spdif_in_clk", "spdif_in_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_IN_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "spdif-in"); + clk_register_clkdev(clk, NULL, "d0100000.spdif-in"); clk = clk_register_gate(NULL, "acp_clk", "acp_mclk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_ACP_CLK_ENB, 0, @@ -917,7 +919,7 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "plgpio_clk", "plgpio_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PLGPIO_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "plgpio"); + clk_register_clkdev(clk, NULL, "e2800000.gpio"); clk = clk_register_gate(NULL, "video_dec_clk", "video_dec_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_DEC_CLK_ENB, @@ -937,25 +939,25 @@ void __init spear1340_clk_init(void) clk = clk_register_gate(NULL, "cam0_clk", "cam0_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM0_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "spear_camif.0"); + clk_register_clkdev(clk, NULL, "d0200000.cam0"); clk = clk_register_gate(NULL, "cam1_clk", "cam1_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM1_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "spear_camif.1"); + clk_register_clkdev(clk, NULL, "d0300000.cam1"); clk = clk_register_gate(NULL, "cam2_clk", "cam2_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM2_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "spear_camif.2"); + clk_register_clkdev(clk, NULL, "d0400000.cam2"); clk = clk_register_gate(NULL, "cam3_clk", "cam3_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM3_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "spear_camif.3"); + clk_register_clkdev(clk, NULL, "d0500000.cam3"); clk = clk_register_gate(NULL, "pwm_clk", "pwm_mclk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PWM_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "pwm"); + clk_register_clkdev(clk, NULL, "e0180000.pwm"); } diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index 59049cf81a7..417f9373461 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -255,7 +255,7 @@ static void __init spear320_clk_init(void) clk = clk_register_fixed_factor(NULL, "pwm_clk", "ras_ahb_clk", 0, 1, 1); - clk_register_clkdev(clk, "pwm", NULL); + clk_register_clkdev(clk, NULL, "a8000000.pwm"); clk = clk_register_fixed_factor(NULL, "ssp1_clk", "ras_ahb_clk", 0, 1, 1); @@ -275,7 +275,7 @@ static void __init spear320_clk_init(void) clk = clk_register_fixed_factor(NULL, "i2s_clk", "ras_apb_clk", 0, 1, 1); - clk_register_clkdev(clk, NULL, "i2s"); + clk_register_clkdev(clk, NULL, "a9400000.i2s"); clk = clk_register_mux(NULL, "i2s_ref_clk", i2s_ref_parents, ARRAY_SIZE(i2s_ref_parents), 0, SPEAR320_CONTROL_REG, @@ -486,7 +486,9 @@ void __init spear3xx_clk_init(void) /* clock derived from pll3 clk */ clk = clk_register_gate(NULL, "usbh_clk", "pll3_clk", 0, PERIP1_CLK_ENB, USBH_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, "usbh_clk", NULL); + clk_register_clkdev(clk, NULL, "e1800000.ehci"); + clk_register_clkdev(clk, NULL, "e1900000.ohci"); + clk_register_clkdev(clk, NULL, "e2100000.ohci"); clk = clk_register_fixed_factor(NULL, "usbh.0_clk", "usbh_clk", 0, 1, 1); @@ -498,7 +500,7 @@ void __init spear3xx_clk_init(void) clk = clk_register_gate(NULL, "usbd_clk", "pll3_clk", 0, PERIP1_CLK_ENB, USBD_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "designware_udc"); + clk_register_clkdev(clk, NULL, "e1100000.usbd"); /* clock derived from ahb clk */ clk = clk_register_fixed_factor(NULL, "ahbmult2_clk", "ahb_clk", 0, 2, @@ -546,7 +548,7 @@ void __init spear3xx_clk_init(void) /* clock derived from apb clk */ clk = clk_register_gate(NULL, "adc_clk", "apb_clk", 0, PERIP1_CLK_ENB, ADC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "adc"); + clk_register_clkdev(clk, NULL, "d0080000.adc"); clk = clk_register_gate(NULL, "gpio0_clk", "apb_clk", 0, PERIP1_CLK_ENB, GPIO_CLK_ENB, 0, &_lock); diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index a98d0866f54..c7fa67c7c0a 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -261,11 +261,13 @@ void __init spear6xx_clk_init(void) /* clock derived from pll3 clk */ clk = clk_register_gate(NULL, "usbh0_clk", "pll3_clk", 0, PERIP1_CLK_ENB, USBH0_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "usbh.0_clk"); + clk_register_clkdev(clk, NULL, "e1800000.ehci"); + clk_register_clkdev(clk, NULL, "e1900000.ohci"); clk = clk_register_gate(NULL, "usbh1_clk", "pll3_clk", 0, PERIP1_CLK_ENB, USBH1_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "usbh.1_clk"); + clk_register_clkdev(clk, NULL, "e2000000.ehci"); + clk_register_clkdev(clk, NULL, "e2100000.ohci"); clk = clk_register_gate(NULL, "usbd_clk", "pll3_clk", 0, PERIP1_CLK_ENB, USBD_CLK_ENB, 0, &_lock); -- cgit v1.2.3 From e0b9c2109b4686c343514823469013150d28b4c0 Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Sat, 10 Nov 2012 12:13:41 +0530 Subject: CLK: SPEAr13xx: Fix mux clock names This patch updates mux clock names of multiple clocks. It updates _clk with _mclk to make it more readable. Signed-off-by: Shiraz Hashim Signed-off-by: Rajeev Kumar Signed-off-by: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/spear1310_clock.c | 4 ++-- drivers/clk/spear/spear1340_clock.c | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index f13b1d23b4a..2f1cb7165bc 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -633,7 +633,7 @@ void __init spear1310_clk_init(void) ARRAY_SIZE(clcd_pixel_parents), 0, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_CLCD_CLK_SHIFT, SPEAR1310_CLCD_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "clcd_pixel_clk", NULL); + clk_register_clkdev(clk, "clcd_pixel_mclk", NULL); clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mclk", 0, SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CLCD_CLK_ENB, 0, @@ -645,7 +645,7 @@ void __init spear1310_clk_init(void) ARRAY_SIZE(i2s_src_parents), 0, SPEAR1310_I2S_CLK_CFG, SPEAR1310_I2S_SRC_CLK_SHIFT, SPEAR1310_I2S_SRC_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2s_src_clk", NULL); + clk_register_clkdev(clk, "i2s_src_mclk", NULL); clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", 0, SPEAR1310_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl, diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index dae2ba60a8f..4733d996599 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -521,7 +521,7 @@ void __init spear1340_clk_init(void) ARRAY_SIZE(sys_parents), 0, SPEAR1340_SYS_CLK_CTRL, SPEAR1340_SCLK_SRC_SEL_SHIFT, SPEAR1340_SCLK_SRC_SEL_MASK, 0, &_lock); - clk_register_clkdev(clk, "sys_clk", NULL); + clk_register_clkdev(clk, "sys_mclk", NULL); clk = clk_register_fixed_factor(NULL, "cpu_clk", "sys_mclk", 0, 1, 2); @@ -697,7 +697,7 @@ void __init spear1340_clk_init(void) ARRAY_SIZE(clcd_pixel_parents), 0, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_CLCD_CLK_SHIFT, SPEAR1340_CLCD_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "clcd_pixel_clk", NULL); + clk_register_clkdev(clk, "clcd_pixel_mclk", NULL); clk = clk_register_gate(NULL, "clcd_clk", "clcd_pixel_mclk", 0, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CLCD_CLK_ENB, 0, @@ -709,7 +709,7 @@ void __init spear1340_clk_init(void) ARRAY_SIZE(i2s_src_parents), 0, SPEAR1340_I2S_CLK_CFG, SPEAR1340_I2S_SRC_CLK_SHIFT, SPEAR1340_I2S_SRC_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2s_src_clk", NULL); + clk_register_clkdev(clk, "i2s_src_mclk", NULL); clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", 0, SPEAR1340_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl, @@ -720,7 +720,7 @@ void __init spear1340_clk_init(void) ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1340_I2S_CLK_CFG, SPEAR1340_I2S_REF_SHIFT, SPEAR1340_I2S_REF_SEL_MASK, 0, &_lock); - clk_register_clkdev(clk, "i2s_ref_clk", NULL); + clk_register_clkdev(clk, "i2s_ref_mclk", NULL); clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mclk", 0, SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_I2S_REF_PAD_CLK_ENB, @@ -846,30 +846,30 @@ void __init spear1340_clk_init(void) ARRAY_SIZE(gen_synth0_1_parents), 0, SPEAR1340_PLL_CFG, SPEAR1340_GEN_SYNT0_1_CLK_SHIFT, SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gen_syn0_1_clk", NULL); + clk_register_clkdev(clk, "gen_syn0_1_mclk", NULL); clk = clk_register_mux(NULL, "gen_syn2_3_mclk", gen_synth2_3_parents, ARRAY_SIZE(gen_synth2_3_parents), 0, SPEAR1340_PLL_CFG, SPEAR1340_GEN_SYNT2_3_CLK_SHIFT, SPEAR1340_GEN_SYNT_CLK_MASK, 0, &_lock); - clk_register_clkdev(clk, "gen_syn2_3_clk", NULL); + clk_register_clkdev(clk, "gen_syn2_3_mclk", NULL); - clk = clk_register_frac("gen_syn0_clk", "gen_syn0_1_clk", 0, + clk = clk_register_frac("gen_syn0_clk", "gen_syn0_1_mclk", 0, SPEAR1340_GEN_CLK_SYNT0, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); clk_register_clkdev(clk, "gen_syn0_clk", NULL); - clk = clk_register_frac("gen_syn1_clk", "gen_syn0_1_clk", 0, + clk = clk_register_frac("gen_syn1_clk", "gen_syn0_1_mclk", 0, SPEAR1340_GEN_CLK_SYNT1, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); clk_register_clkdev(clk, "gen_syn1_clk", NULL); - clk = clk_register_frac("gen_syn2_clk", "gen_syn2_3_clk", 0, + clk = clk_register_frac("gen_syn2_clk", "gen_syn2_3_mclk", 0, SPEAR1340_GEN_CLK_SYNT2, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); clk_register_clkdev(clk, "gen_syn2_clk", NULL); - clk = clk_register_frac("gen_syn3_clk", "gen_syn2_3_clk", 0, + clk = clk_register_frac("gen_syn3_clk", "gen_syn2_3_mclk", 0, SPEAR1340_GEN_CLK_SYNT3, gen_rtbl, ARRAY_SIZE(gen_rtbl), &_lock); clk_register_clkdev(clk, "gen_syn3_clk", NULL); -- cgit v1.2.3 From 463f9e209ca69d52344479544d1e52c02f2e6918 Mon Sep 17 00:00:00 2001 From: Shiraz Hashim Date: Sat, 10 Nov 2012 12:13:42 +0530 Subject: CLK: SPEAr13xx: fix parent names of multiple clocks This patch fixes parent names of multiple clocks. Signed-off-by: Shiraz Hashim Signed-off-by: Vipul Kumar Samar Signed-off-by: Rajeev Kumar Signed-off-by: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/spear1310_clock.c | 2 +- drivers/clk/spear/spear1340_clock.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index 2f1cb7165bc..e84b1fbb583 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -664,7 +664,7 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "i2s_ref_pad_clk", NULL); clk = clk_register_aux("i2s_sclk_clk", "i2s_sclk_gclk", - "i2s_ref_pad_clk", 0, SPEAR1310_I2S_CLK_CFG, + "i2s_ref_mclk", 0, SPEAR1310_I2S_CLK_CFG, &i2s_sclk_masks, i2s_sclk_rtbl, ARRAY_SIZE(i2s_sclk_rtbl), &_lock, &clk1); clk_register_clkdev(clk, "i2s_sclk_clk", NULL); diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index 4733d996599..020431ac163 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -370,7 +370,7 @@ static struct frac_rate_tbl gen_rtbl[] = { /* clock parents */ static const char *vco_parents[] = { "osc_24m_clk", "osc_25m_clk", }; static const char *sys_parents[] = { "pll1_clk", "pll1_clk", "pll1_clk", - "pll1_clk", "sys_synth_clk", "sys_synth_clk", "pll2_clk", "pll3_clk", }; + "pll1_clk", "sys_syn_clk", "sys_syn_clk", "pll2_clk", "pll3_clk", }; static const char *ahb_parents[] = { "cpu_div3_clk", "amba_syn_clk", }; static const char *gpt_parents[] = { "osc_24m_clk", "apb_clk", }; static const char *uart0_parents[] = { "pll5_clk", "osc_24m_clk", @@ -391,7 +391,7 @@ static const char *spdif_in_parents[] = { "pll2_clk", "gen_syn3_clk", }; static const char *gen_synth0_1_parents[] = { "vco1div4_clk", "vco3div2_clk", "pll3_clk", }; -static const char *gen_synth2_3_parents[] = { "vco1div4_clk", "vco3div2_clk", +static const char *gen_synth2_3_parents[] = { "vco1div4_clk", "vco2div2_clk", "pll2_clk", }; void __init spear1340_clk_init(void) @@ -956,7 +956,7 @@ void __init spear1340_clk_init(void) &_lock); clk_register_clkdev(clk, NULL, "d0500000.cam3"); - clk = clk_register_gate(NULL, "pwm_clk", "pwm_mclk", 0, + clk = clk_register_gate(NULL, "pwm_clk", "ahb_clk", 0, SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PWM_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "e0180000.pwm"); -- cgit v1.2.3 From 1249979242db10d2fe1793f26e7658d94b7bf6dc Mon Sep 17 00:00:00 2001 From: Vipul Kumar Samar Date: Sat, 10 Nov 2012 12:13:43 +0530 Subject: CLK: SPEAr: Set CLK_SET_RATE_PARENT for few clocks Flag CLK_SET_RATE_PARENT is required for a clock, where we want to propagate clk_set_rate to its parent. This patch adds this to multiple clocks. Signed-off-by: Vipul Kumar Samar Signed-off-by: Shiraz Hashim Signed-off-by: Rajeev Kumar Signed-off-by: Vijay Kumar Mishra Signed-off-by: Vijay Kumar Mishra Signed-off-by: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/clk-aux-synth.c | 3 +- drivers/clk/spear/spear1310_clock.c | 49 +++++++-------- drivers/clk/spear/spear1340_clock.c | 73 +++++++++++----------- drivers/clk/spear/spear3xx_clock.c | 119 ++++++++++++++++++++---------------- drivers/clk/spear/spear6xx_clock.c | 3 +- 5 files changed, 133 insertions(+), 114 deletions(-) diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c index 6756e7c3bc0..bdfb4421c64 100644 --- a/drivers/clk/spear/clk-aux-synth.c +++ b/drivers/clk/spear/clk-aux-synth.c @@ -179,7 +179,8 @@ struct clk *clk_register_aux(const char *aux_name, const char *gate_name, if (gate_name) { struct clk *tgate_clk; - tgate_clk = clk_register_gate(NULL, gate_name, aux_name, 0, reg, + tgate_clk = clk_register_gate(NULL, gate_name, aux_name, + CLK_SET_RATE_PARENT, reg, aux->masks->enable_bit, 0, lock); if (IS_ERR_OR_NULL(tgate_clk)) goto free_aux; diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index e84b1fbb583..2809b670e22 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -483,7 +483,8 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "ddr_clk", NULL); /* clock derived from pll1 clk */ - clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", 0, 1, 2); + clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", + CLK_SET_RATE_PARENT, 1, 2); clk_register_clkdev(clk, "cpu_clk", NULL); clk = clk_register_fixed_factor(NULL, "wdt_clk", "cpu_clk", 0, 1, @@ -547,14 +548,14 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk1, "uart_syn_gclk", NULL); clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents, - ARRAY_SIZE(uart0_parents), 0, SPEAR1310_PERIP_CLK_CFG, - SPEAR1310_UART_CLK_SHIFT, SPEAR1310_UART_CLK_MASK, 0, - &_lock); + ARRAY_SIZE(uart0_parents), CLK_SET_RATE_PARENT, + SPEAR1310_PERIP_CLK_CFG, SPEAR1310_UART_CLK_SHIFT, + SPEAR1310_UART_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "uart0_mclk", NULL); - clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", 0, - SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_UART_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", + CLK_SET_RATE_PARENT, SPEAR1310_PERIP1_CLK_ENB, + SPEAR1310_UART_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "e0000000.serial"); clk = clk_register_aux("sdhci_syn_clk", "sdhci_syn_gclk", @@ -563,9 +564,9 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "sdhci_syn_clk", NULL); clk_register_clkdev(clk1, "sdhci_syn_gclk", NULL); - clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", 0, - SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_SDHCI_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", + CLK_SET_RATE_PARENT, SPEAR1310_PERIP1_CLK_ENB, + SPEAR1310_SDHCI_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "b3000000.sdhci"); clk = clk_register_aux("cfxd_syn_clk", "cfxd_syn_gclk", "vco1div2_clk", @@ -574,9 +575,9 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "cfxd_syn_clk", NULL); clk_register_clkdev(clk1, "cfxd_syn_gclk", NULL); - clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", 0, - SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_CFXD_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", + CLK_SET_RATE_PARENT, SPEAR1310_PERIP1_CLK_ENB, + SPEAR1310_CFXD_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "b2800000.cf"); clk_register_clkdev(clk, NULL, "arasan_xd"); @@ -587,9 +588,9 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk1, "c3_syn_gclk", NULL); clk = clk_register_mux(NULL, "c3_mclk", c3_parents, - ARRAY_SIZE(c3_parents), 0, SPEAR1310_PERIP_CLK_CFG, - SPEAR1310_C3_CLK_SHIFT, SPEAR1310_C3_CLK_MASK, 0, - &_lock); + ARRAY_SIZE(c3_parents), CLK_SET_RATE_PARENT, + SPEAR1310_PERIP_CLK_CFG, SPEAR1310_C3_CLK_SHIFT, + SPEAR1310_C3_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "c3_mclk", NULL); clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", 0, @@ -630,7 +631,7 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "clcd_syn_clk", NULL); clk = clk_register_mux(NULL, "clcd_pixel_mclk", clcd_pixel_parents, - ARRAY_SIZE(clcd_pixel_parents), 0, + ARRAY_SIZE(clcd_pixel_parents), CLK_SET_RATE_PARENT, SPEAR1310_PERIP_CLK_CFG, SPEAR1310_CLCD_CLK_SHIFT, SPEAR1310_CLCD_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "clcd_pixel_mclk", NULL); @@ -653,10 +654,10 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "i2s_prs1_clk", NULL); clk = clk_register_mux(NULL, "i2s_ref_mclk", i2s_ref_parents, - ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1310_I2S_CLK_CFG, - SPEAR1310_I2S_REF_SHIFT, SPEAR1310_I2S_REF_SEL_MASK, 0, - &_lock); - clk_register_clkdev(clk, "i2s_ref_clk", NULL); + ARRAY_SIZE(i2s_ref_parents), CLK_SET_RATE_PARENT, + SPEAR1310_I2S_CLK_CFG, SPEAR1310_I2S_REF_SHIFT, + SPEAR1310_I2S_REF_SEL_MASK, 0, &_lock); + clk_register_clkdev(clk, "i2s_ref_mclk", NULL); clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mclk", 0, SPEAR1310_PERIP2_CLK_ENB, SPEAR1310_I2S_REF_PAD_CLK_ENB, @@ -753,9 +754,9 @@ void __init spear1310_clk_init(void) clk_register_clkdev(clk, "adc_syn_clk", NULL); clk_register_clkdev(clk1, "adc_syn_gclk", NULL); - clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", 0, - SPEAR1310_PERIP1_CLK_ENB, SPEAR1310_ADC_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", + CLK_SET_RATE_PARENT, SPEAR1310_PERIP1_CLK_ENB, + SPEAR1310_ADC_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "e0080000.adc"); /* clock derived from apb clk */ diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index 020431ac163..aa5ed435fba 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -594,14 +594,14 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk1, "uart0_syn_gclk", NULL); clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents, - ARRAY_SIZE(uart0_parents), 0, SPEAR1340_PERIP_CLK_CFG, - SPEAR1340_UART0_CLK_SHIFT, SPEAR1340_UART_CLK_MASK, 0, - &_lock); + ARRAY_SIZE(uart0_parents), CLK_SET_RATE_PARENT, + SPEAR1340_PERIP_CLK_CFG, SPEAR1340_UART0_CLK_SHIFT, + SPEAR1340_UART_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "uart0_mclk", NULL); - clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", 0, - SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_UART0_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "uart0_clk", "uart0_mclk", + CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB, + SPEAR1340_UART0_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "e0000000.serial"); clk = clk_register_aux("uart1_syn_clk", "uart1_syn_gclk", @@ -627,9 +627,9 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, "sdhci_syn_clk", NULL); clk_register_clkdev(clk1, "sdhci_syn_gclk", NULL); - clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", 0, - SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_SDHCI_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "sdhci_clk", "sdhci_syn_gclk", + CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB, + SPEAR1340_SDHCI_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "b3000000.sdhci"); clk = clk_register_aux("cfxd_syn_clk", "cfxd_syn_gclk", "vco1div2_clk", @@ -638,9 +638,9 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, "cfxd_syn_clk", NULL); clk_register_clkdev(clk1, "cfxd_syn_gclk", NULL); - clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", 0, - SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_CFXD_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "cfxd_clk", "cfxd_syn_gclk", + CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB, + SPEAR1340_CFXD_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "b2800000.cf"); clk_register_clkdev(clk, NULL, "arasan_xd"); @@ -651,12 +651,12 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk1, "c3_syn_gclk", NULL); clk = clk_register_mux(NULL, "c3_mclk", c3_parents, - ARRAY_SIZE(c3_parents), 0, SPEAR1340_PERIP_CLK_CFG, - SPEAR1340_C3_CLK_SHIFT, SPEAR1340_C3_CLK_MASK, 0, - &_lock); + ARRAY_SIZE(c3_parents), CLK_SET_RATE_PARENT, + SPEAR1340_PERIP_CLK_CFG, SPEAR1340_C3_CLK_SHIFT, + SPEAR1340_C3_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "c3_mclk", NULL); - clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", 0, + clk = clk_register_gate(NULL, "c3_clk", "c3_mclk", CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_C3_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "e1800000.c3"); @@ -694,7 +694,7 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, "clcd_syn_clk", NULL); clk = clk_register_mux(NULL, "clcd_pixel_mclk", clcd_pixel_parents, - ARRAY_SIZE(clcd_pixel_parents), 0, + ARRAY_SIZE(clcd_pixel_parents), CLK_SET_RATE_PARENT, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_CLCD_CLK_SHIFT, SPEAR1340_CLCD_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "clcd_pixel_mclk", NULL); @@ -711,15 +711,16 @@ void __init spear1340_clk_init(void) 0, &_lock); clk_register_clkdev(clk, "i2s_src_mclk", NULL); - clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", 0, - SPEAR1340_I2S_CLK_CFG, &i2s_prs1_masks, i2s_prs1_rtbl, + clk = clk_register_aux("i2s_prs1_clk", NULL, "i2s_src_mclk", + CLK_SET_RATE_PARENT, SPEAR1340_I2S_CLK_CFG, + &i2s_prs1_masks, i2s_prs1_rtbl, ARRAY_SIZE(i2s_prs1_rtbl), &_lock, NULL); clk_register_clkdev(clk, "i2s_prs1_clk", NULL); clk = clk_register_mux(NULL, "i2s_ref_mclk", i2s_ref_parents, - ARRAY_SIZE(i2s_ref_parents), 0, SPEAR1340_I2S_CLK_CFG, - SPEAR1340_I2S_REF_SHIFT, SPEAR1340_I2S_REF_SEL_MASK, 0, - &_lock); + ARRAY_SIZE(i2s_ref_parents), CLK_SET_RATE_PARENT, + SPEAR1340_I2S_CLK_CFG, SPEAR1340_I2S_REF_SHIFT, + SPEAR1340_I2S_REF_SEL_MASK, 0, &_lock); clk_register_clkdev(clk, "i2s_ref_mclk", NULL); clk = clk_register_gate(NULL, "i2s_ref_pad_clk", "i2s_ref_mclk", 0, @@ -805,9 +806,9 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, "adc_syn_clk", NULL); clk_register_clkdev(clk1, "adc_syn_gclk", NULL); - clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", 0, - SPEAR1340_PERIP1_CLK_ENB, SPEAR1340_ADC_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "adc_clk", "adc_syn_gclk", + CLK_SET_RATE_PARENT, SPEAR1340_PERIP1_CLK_ENB, + SPEAR1340_ADC_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "e0080000.adc"); /* clock derived from apb clk */ @@ -874,9 +875,9 @@ void __init spear1340_clk_init(void) &_lock); clk_register_clkdev(clk, "gen_syn3_clk", NULL); - clk = clk_register_gate(NULL, "mali_clk", "gen_syn3_clk", 0, - SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_MALI_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "mali_clk", "gen_syn3_clk", + CLK_SET_RATE_PARENT, SPEAR1340_PERIP3_CLK_ENB, + SPEAR1340_MALI_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "mali"); clk = clk_register_gate(NULL, "cec0_clk", "ahb_clk", 0, @@ -890,25 +891,25 @@ void __init spear1340_clk_init(void) clk_register_clkdev(clk, NULL, "spear_cec.1"); clk = clk_register_mux(NULL, "spdif_out_mclk", spdif_out_parents, - ARRAY_SIZE(spdif_out_parents), 0, + ARRAY_SIZE(spdif_out_parents), CLK_SET_RATE_PARENT, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_OUT_CLK_SHIFT, SPEAR1340_SPDIF_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "spdif_out_mclk", NULL); - clk = clk_register_gate(NULL, "spdif_out_clk", "spdif_out_mclk", 0, - SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_OUT_CLK_ENB, - 0, &_lock); + clk = clk_register_gate(NULL, "spdif_out_clk", "spdif_out_mclk", + CLK_SET_RATE_PARENT, SPEAR1340_PERIP3_CLK_ENB, + SPEAR1340_SPDIF_OUT_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "d0000000.spdif-out"); clk = clk_register_mux(NULL, "spdif_in_mclk", spdif_in_parents, - ARRAY_SIZE(spdif_in_parents), 0, + ARRAY_SIZE(spdif_in_parents), CLK_SET_RATE_PARENT, SPEAR1340_PERIP_CLK_CFG, SPEAR1340_SPDIF_IN_CLK_SHIFT, SPEAR1340_SPDIF_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "spdif_in_mclk", NULL); - clk = clk_register_gate(NULL, "spdif_in_clk", "spdif_in_mclk", 0, - SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_SPDIF_IN_CLK_ENB, 0, - &_lock); + clk = clk_register_gate(NULL, "spdif_in_clk", "spdif_in_mclk", + CLK_SET_RATE_PARENT, SPEAR1340_PERIP3_CLK_ENB, + SPEAR1340_SPDIF_IN_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, NULL, "d0100000.spdif-in"); clk = clk_register_gate(NULL, "acp_clk", "acp_mclk", 0, diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index 417f9373461..4c89b143e24 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -278,23 +278,26 @@ static void __init spear320_clk_init(void) clk_register_clkdev(clk, NULL, "a9400000.i2s"); clk = clk_register_mux(NULL, "i2s_ref_clk", i2s_ref_parents, - ARRAY_SIZE(i2s_ref_parents), 0, SPEAR320_CONTROL_REG, - I2S_REF_PCLK_SHIFT, I2S_REF_PCLK_MASK, 0, &_lock); + ARRAY_SIZE(i2s_ref_parents), CLK_SET_RATE_PARENT, + SPEAR320_CONTROL_REG, I2S_REF_PCLK_SHIFT, + I2S_REF_PCLK_MASK, 0, &_lock); clk_register_clkdev(clk, "i2s_ref_clk", NULL); - clk = clk_register_fixed_factor(NULL, "i2s_sclk", "i2s_ref_clk", 0, 1, + clk = clk_register_fixed_factor(NULL, "i2s_sclk", "i2s_ref_clk", + CLK_SET_RATE_PARENT, 1, 4); clk_register_clkdev(clk, "i2s_sclk", NULL); clk = clk_register_mux(NULL, "rs485_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG, - SPEAR320_RS485_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, - &_lock); + ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, + SPEAR320_EXT_CTRL_REG, SPEAR320_RS485_PCLK_SHIFT, + SPEAR320_UARTX_PCLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "a9300000.serial"); clk = clk_register_mux(NULL, "sdhci_clk", sdhci_parents, - ARRAY_SIZE(sdhci_parents), 0, SPEAR320_CONTROL_REG, - SDHCI_PCLK_SHIFT, SDHCI_PCLK_MASK, 0, &_lock); + ARRAY_SIZE(sdhci_parents), CLK_SET_RATE_PARENT, + SPEAR320_CONTROL_REG, SDHCI_PCLK_SHIFT, SDHCI_PCLK_MASK, + 0, &_lock); clk_register_clkdev(clk, NULL, "70000000.sdhci"); clk = clk_register_mux(NULL, "smii_pclk", smii0_parents, @@ -306,38 +309,39 @@ static void __init spear320_clk_init(void) clk_register_clkdev(clk, NULL, "smii"); clk = clk_register_mux(NULL, "uart1_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), 0, SPEAR320_CONTROL_REG, - UART1_PCLK_SHIFT, UART1_PCLK_MASK, 0, &_lock); + ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, + SPEAR320_CONTROL_REG, UART1_PCLK_SHIFT, UART1_PCLK_MASK, + 0, &_lock); clk_register_clkdev(clk, NULL, "a3000000.serial"); clk = clk_register_mux(NULL, "uart2_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG, - SPEAR320_UART2_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, - &_lock); + ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, + SPEAR320_EXT_CTRL_REG, SPEAR320_UART2_PCLK_SHIFT, + SPEAR320_UARTX_PCLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "a4000000.serial"); clk = clk_register_mux(NULL, "uart3_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG, - SPEAR320_UART3_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, - &_lock); + ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, + SPEAR320_EXT_CTRL_REG, SPEAR320_UART3_PCLK_SHIFT, + SPEAR320_UARTX_PCLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "a9100000.serial"); clk = clk_register_mux(NULL, "uart4_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG, - SPEAR320_UART4_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, - &_lock); + ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, + SPEAR320_EXT_CTRL_REG, SPEAR320_UART4_PCLK_SHIFT, + SPEAR320_UARTX_PCLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "a9200000.serial"); clk = clk_register_mux(NULL, "uart5_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG, - SPEAR320_UART5_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, - &_lock); + ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, + SPEAR320_EXT_CTRL_REG, SPEAR320_UART5_PCLK_SHIFT, + SPEAR320_UARTX_PCLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "60000000.serial"); clk = clk_register_mux(NULL, "uart6_clk", uartx_parents, - ARRAY_SIZE(uartx_parents), 0, SPEAR320_EXT_CTRL_REG, - SPEAR320_UART6_PCLK_SHIFT, SPEAR320_UARTX_PCLK_MASK, 0, - &_lock); + ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, + SPEAR320_EXT_CTRL_REG, SPEAR320_UART6_PCLK_SHIFT, + SPEAR320_UARTX_PCLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "60100000.serial"); } #else @@ -386,7 +390,8 @@ void __init spear3xx_clk_init(void) clk_register_clkdev(clk1, "pll2_clk", NULL); /* clock derived from pll1 clk */ - clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", 0, 1, 1); + clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", + CLK_SET_RATE_PARENT, 1, 1); clk_register_clkdev(clk, "cpu_clk", NULL); clk = clk_register_divider(NULL, "ahb_clk", "pll1_clk", @@ -401,12 +406,14 @@ void __init spear3xx_clk_init(void) clk_register_clkdev(clk1, "uart_syn_gclk", NULL); clk = clk_register_mux(NULL, "uart0_mclk", uart0_parents, - ARRAY_SIZE(uart0_parents), 0, PERIP_CLK_CFG, - UART_CLK_SHIFT, UART_CLK_MASK, 0, &_lock); + ARRAY_SIZE(uart0_parents), CLK_SET_RATE_PARENT, + PERIP_CLK_CFG, UART_CLK_SHIFT, UART_CLK_MASK, 0, + &_lock); clk_register_clkdev(clk, "uart0_mclk", NULL); - clk = clk_register_gate(NULL, "uart0", "uart0_mclk", 0, PERIP1_CLK_ENB, - UART_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "uart0", "uart0_mclk", + CLK_SET_RATE_PARENT, PERIP1_CLK_ENB, UART_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, NULL, "d0000000.serial"); clk = clk_register_aux("firda_syn_clk", "firda_syn_gclk", "pll1_clk", 0, @@ -416,40 +423,44 @@ void __init spear3xx_clk_init(void) clk_register_clkdev(clk1, "firda_syn_gclk", NULL); clk = clk_register_mux(NULL, "firda_mclk", firda_parents, - ARRAY_SIZE(firda_parents), 0, PERIP_CLK_CFG, - FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, &_lock); + ARRAY_SIZE(firda_parents), CLK_SET_RATE_PARENT, + PERIP_CLK_CFG, FIRDA_CLK_SHIFT, FIRDA_CLK_MASK, 0, + &_lock); clk_register_clkdev(clk, "firda_mclk", NULL); - clk = clk_register_gate(NULL, "firda_clk", "firda_mclk", 0, - PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "firda_clk", "firda_mclk", + CLK_SET_RATE_PARENT, PERIP1_CLK_ENB, FIRDA_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, NULL, "firda"); /* gpt clocks */ clk_register_gpt("gpt0_syn_clk", "pll1_clk", 0, PRSC0_CLK_CFG, gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); clk = clk_register_mux(NULL, "gpt0_clk", gpt0_parents, - ARRAY_SIZE(gpt0_parents), 0, PERIP_CLK_CFG, - GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); + ARRAY_SIZE(gpt0_parents), CLK_SET_RATE_PARENT, + PERIP_CLK_CFG, GPT0_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, NULL, "gpt0"); clk_register_gpt("gpt1_syn_clk", "pll1_clk", 0, PRSC1_CLK_CFG, gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); clk = clk_register_mux(NULL, "gpt1_mclk", gpt1_parents, - ARRAY_SIZE(gpt1_parents), 0, PERIP_CLK_CFG, - GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); + ARRAY_SIZE(gpt1_parents), CLK_SET_RATE_PARENT, + PERIP_CLK_CFG, GPT1_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "gpt1_mclk", NULL); - clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", 0, - PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "gpt1_clk", "gpt1_mclk", + CLK_SET_RATE_PARENT, PERIP1_CLK_ENB, GPT1_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, NULL, "gpt1"); clk_register_gpt("gpt2_syn_clk", "pll1_clk", 0, PRSC2_CLK_CFG, gpt_rtbl, ARRAY_SIZE(gpt_rtbl), &_lock); clk = clk_register_mux(NULL, "gpt2_mclk", gpt2_parents, - ARRAY_SIZE(gpt2_parents), 0, PERIP_CLK_CFG, - GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); + ARRAY_SIZE(gpt2_parents), CLK_SET_RATE_PARENT, + PERIP_CLK_CFG, GPT2_CLK_SHIFT, GPT_CLK_MASK, 0, &_lock); clk_register_clkdev(clk, "gpt2_mclk", NULL); - clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", 0, - PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "gpt2_clk", "gpt2_mclk", + CLK_SET_RATE_PARENT, PERIP1_CLK_ENB, GPT2_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, NULL, "gpt2"); /* general synths clocks */ @@ -587,20 +598,24 @@ void __init spear3xx_clk_init(void) RAS_CLK_ENB, RAS_48M_CLK_ENB, 0, &_lock); clk_register_clkdev(clk, "ras_pll3_clk", NULL); - clk = clk_register_gate(NULL, "ras_syn0_gclk", "gen0_syn_gclk", 0, - RAS_CLK_ENB, RAS_SYNT0_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "ras_syn0_gclk", "gen0_syn_gclk", + CLK_SET_RATE_PARENT, RAS_CLK_ENB, RAS_SYNT0_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, "ras_syn0_gclk", NULL); - clk = clk_register_gate(NULL, "ras_syn1_gclk", "gen1_syn_gclk", 0, - RAS_CLK_ENB, RAS_SYNT1_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "ras_syn1_gclk", "gen1_syn_gclk", + CLK_SET_RATE_PARENT, RAS_CLK_ENB, RAS_SYNT1_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, "ras_syn1_gclk", NULL); - clk = clk_register_gate(NULL, "ras_syn2_gclk", "gen2_syn_gclk", 0, - RAS_CLK_ENB, RAS_SYNT2_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "ras_syn2_gclk", "gen2_syn_gclk", + CLK_SET_RATE_PARENT, RAS_CLK_ENB, RAS_SYNT2_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, "ras_syn2_gclk", NULL); - clk = clk_register_gate(NULL, "ras_syn3_gclk", "gen3_syn_gclk", 0, - RAS_CLK_ENB, RAS_SYNT3_CLK_ENB, 0, &_lock); + clk = clk_register_gate(NULL, "ras_syn3_gclk", "gen3_syn_gclk", + CLK_SET_RATE_PARENT, RAS_CLK_ENB, RAS_SYNT3_CLK_ENB, 0, + &_lock); clk_register_clkdev(clk, "ras_syn3_gclk", NULL); if (of_machine_is_compatible("st,spear300")) diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index c7fa67c7c0a..e8d2b3109b3 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -156,7 +156,8 @@ void __init spear6xx_clk_init(void) clk_register_clkdev(clk, NULL, "wdt"); /* clock derived from pll1 clk */ - clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", 0, 1, 1); + clk = clk_register_fixed_factor(NULL, "cpu_clk", "pll1_clk", + CLK_SET_RATE_PARENT, 1, 1); clk_register_clkdev(clk, "cpu_clk", NULL); clk = clk_register_divider(NULL, "ahb_clk", "pll1_clk", -- cgit v1.2.3 From cd4b519aa5bdce92fcacc1d4bbe0fa16b4e16144 Mon Sep 17 00:00:00 2001 From: Vipul Kumar Samar Date: Sat, 10 Nov 2012 12:13:44 +0530 Subject: CLK: SPEAr: Add missing clocks This patch adds missing clocks: twd and macb. Signed-off-by: Vipul Kumar Samar Signed-off-by: Deepak Sikri Signed-off-by: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/spear1310_clock.c | 4 ++++ drivers/clk/spear/spear1340_clock.c | 4 ++++ drivers/clk/spear/spear3xx_clock.c | 8 ++++++++ 3 files changed, 16 insertions(+) diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index 2809b670e22..b64d51153a7 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -491,6 +491,10 @@ void __init spear1310_clk_init(void) 2); clk_register_clkdev(clk, NULL, "ec800620.wdt"); + clk = clk_register_fixed_factor(NULL, "smp_twd_clk", "cpu_clk", 0, 1, + 2); + clk_register_clkdev(clk, NULL, "smp_twd"); + clk = clk_register_fixed_factor(NULL, "ahb_clk", "pll1_clk", 0, 1, 6); clk_register_clkdev(clk, "ahb_clk", NULL); diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index aa5ed435fba..8f00533959a 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -535,6 +535,10 @@ void __init spear1340_clk_init(void) 2); clk_register_clkdev(clk, NULL, "ec800620.wdt"); + clk = clk_register_fixed_factor(NULL, "smp_twd_clk", "cpu_clk", 0, 1, + 2); + clk_register_clkdev(clk, NULL, "smp_twd"); + clk = clk_register_mux(NULL, "ahb_clk", ahb_parents, ARRAY_SIZE(ahb_parents), 0, SPEAR1340_SYS_CLK_CTRL, SPEAR1340_HCLK_SRC_SEL_SHIFT, diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index 4c89b143e24..ff35ebca1d8 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -288,6 +288,14 @@ static void __init spear320_clk_init(void) 4); clk_register_clkdev(clk, "i2s_sclk", NULL); + clk = clk_register_fixed_factor(NULL, "macb1_clk", "ras_apb_clk", 0, 1, + 1); + clk_register_clkdev(clk, "hclk", "aa000000.eth"); + + clk = clk_register_fixed_factor(NULL, "macb2_clk", "ras_apb_clk", 0, 1, + 1); + clk_register_clkdev(clk, "hclk", "ab000000.eth"); + clk = clk_register_mux(NULL, "rs485_clk", uartx_parents, ARRAY_SIZE(uartx_parents), CLK_SET_RATE_PARENT, SPEAR320_EXT_CTRL_REG, SPEAR320_RS485_PCLK_SHIFT, -- cgit v1.2.3 From ef0fd0a207c00b09449f33724322ba762d822d97 Mon Sep 17 00:00:00 2001 From: Deepak Sikri Date: Sat, 10 Nov 2012 12:13:45 +0530 Subject: CLK: SPEAr: Update clock rate table This patch updates the existing rate tables with new frequencies. Signed-off-by: Deepak Sikri Signed-off-by: Vipul Kumar Samar Signed-off-by: Rajeev Kumar Signed-off-by: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/spear1310_clock.c | 14 ++++++ drivers/clk/spear/spear1340_clock.c | 89 ++++++++++++++++++++++++++++--------- drivers/clk/spear/spear3xx_clock.c | 6 +++ drivers/clk/spear/spear6xx_clock.c | 1 + 4 files changed, 89 insertions(+), 21 deletions(-) diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index b64d51153a7..bc7f37e131c 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -313,6 +313,20 @@ static struct aux_clk_masks i2s_sclk_masks = { /* i2s prs1 aux rate configuration table, in ascending order of rates */ static struct aux_rate_tbl i2s_prs1_rtbl[] = { /* For parent clk = 49.152 MHz */ + {.xscale = 1, .yscale = 12, .eq = 0}, /* 2.048 MHz, smp freq = 8Khz */ + {.xscale = 11, .yscale = 96, .eq = 0}, /* 2.816 MHz, smp freq = 11Khz */ + {.xscale = 1, .yscale = 6, .eq = 0}, /* 4.096 MHz, smp freq = 16Khz */ + {.xscale = 11, .yscale = 48, .eq = 0}, /* 5.632 MHz, smp freq = 22Khz */ + + /* + * with parent clk = 49.152, freq gen is 8.192 MHz, smp freq = 32Khz + * with parent clk = 12.288, freq gen is 2.048 MHz, smp freq = 8Khz + */ + {.xscale = 1, .yscale = 3, .eq = 0}, + + /* For parent clk = 49.152 MHz */ + {.xscale = 17, .yscale = 37, .eq = 0}, /* 11.289 MHz, smp freq = 44Khz*/ + {.xscale = 1, .yscale = 2, .eq = 0}, /* 12.288 MHz */ }; diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index 8f00533959a..d4de680bf51 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -190,6 +190,7 @@ static struct pll_rate_tbl pll4_rtbl[] = { * different values of vco1div2 */ static struct frac_rate_tbl amba_synth_rtbl[] = { + {.div = 0x073A8}, /* for vco1div2 = 600 MHz */ {.div = 0x06062}, /* for vco1div2 = 500 MHz */ {.div = 0x04D1B}, /* for vco1div2 = 400 MHz */ {.div = 0x04000}, /* for vco1div2 = 332 MHz */ @@ -220,6 +221,12 @@ static struct frac_rate_tbl amba_synth_rtbl[] = { * 500 400 200 0x02800 * 500 500 250 0x02000 * -------------------------------------------------------------------- + * 600 200 100 0x06000 + * 600 250 125 0x04CCE + * 600 332 166 0x039D5 + * 600 400 200 0x03000 + * 600 500 250 0x02666 + * -------------------------------------------------------------------- * 664 200 100 0x06a38 * 664 250 125 0x054FD * 664 332 166 0x04000 @@ -238,28 +245,50 @@ static struct frac_rate_tbl sys_synth_rtbl[] = { {.div = 0x08000}, {.div = 0x06a38}, {.div = 0x06666}, + {.div = 0x06000}, {.div = 0x054FD}, {.div = 0x05000}, {.div = 0x04D18}, + {.div = 0x04CCE}, {.div = 0x04000}, + {.div = 0x039D5}, {.div = 0x0351E}, {.div = 0x03333}, {.div = 0x03031}, + {.div = 0x03000}, {.div = 0x02A7E}, {.div = 0x02800}, {.div = 0x0268D}, + {.div = 0x02666}, {.div = 0x02000}, }; /* aux rate configuration table, in ascending order of rates */ static struct aux_rate_tbl aux_rtbl[] = { - /* For VCO1div2 = 500 MHz */ - {.xscale = 10, .yscale = 204, .eq = 0}, /* 12.29 MHz */ - {.xscale = 4, .yscale = 21, .eq = 0}, /* 48 MHz */ - {.xscale = 2, .yscale = 6, .eq = 0}, /* 83 MHz */ - {.xscale = 2, .yscale = 4, .eq = 0}, /* 125 MHz */ - {.xscale = 1, .yscale = 3, .eq = 1}, /* 166 MHz */ - {.xscale = 1, .yscale = 2, .eq = 1}, /* 250 MHz */ + /* 12.29MHz for vic1div2=600MHz and 10.24MHz for VCO1div2=500MHz */ + {.xscale = 5, .yscale = 122, .eq = 0}, + /* 14.70MHz for vic1div2=600MHz and 12.29MHz for VCO1div2=500MHz */ + {.xscale = 10, .yscale = 204, .eq = 0}, + /* 48MHz for vic1div2=600MHz and 40 MHz for VCO1div2=500MHz */ + {.xscale = 4, .yscale = 25, .eq = 0}, + /* 57.14MHz for vic1div2=600MHz and 48 MHz for VCO1div2=500MHz */ + {.xscale = 4, .yscale = 21, .eq = 0}, + /* 83.33MHz for vic1div2=600MHz and 69.44MHz for VCO1div2=500MHz */ + {.xscale = 5, .yscale = 18, .eq = 0}, + /* 100MHz for vic1div2=600MHz and 83.33 MHz for VCO1div2=500MHz */ + {.xscale = 2, .yscale = 6, .eq = 0}, + /* 125MHz for vic1div2=600MHz and 104.1MHz for VCO1div2=500MHz */ + {.xscale = 5, .yscale = 12, .eq = 0}, + /* 150MHz for vic1div2=600MHz and 125MHz for VCO1div2=500MHz */ + {.xscale = 2, .yscale = 4, .eq = 0}, + /* 166MHz for vic1div2=600MHz and 138.88MHz for VCO1div2=500MHz */ + {.xscale = 5, .yscale = 18, .eq = 1}, + /* 200MHz for vic1div2=600MHz and 166MHz for VCO1div2=500MHz */ + {.xscale = 1, .yscale = 3, .eq = 1}, + /* 250MHz for vic1div2=600MHz and 208.33MHz for VCO1div2=500MHz */ + {.xscale = 5, .yscale = 12, .eq = 1}, + /* 300MHz for vic1div2=600MHz and 250MHz for VCO1div2=500MHz */ + {.xscale = 1, .yscale = 2, .eq = 1}, }; /* gmac rate configuration table, in ascending order of rates */ @@ -273,16 +302,23 @@ static struct aux_rate_tbl gmac_rtbl[] = { /* clcd rate configuration table, in ascending order of rates */ static struct frac_rate_tbl clcd_rtbl[] = { + {.div = 0x18000}, /* 25 Mhz , for vc01div4 = 300 MHz*/ + {.div = 0x1638E}, /* 27 Mhz , for vc01div4 = 300 MHz*/ {.div = 0x14000}, /* 25 Mhz , for vc01div4 = 250 MHz*/ {.div = 0x1284B}, /* 27 Mhz , for vc01div4 = 250 MHz*/ {.div = 0x0D8D3}, /* 58 Mhz , for vco1div4 = 393 MHz */ {.div = 0x0B72C}, /* 58 Mhz , for vco1div4 = 332 MHz */ + {.div = 0x0A584}, /* 58 Mhz , for vco1div4 = 300 MHz */ + {.div = 0x093B1}, /* 65 Mhz , for vc01div4 = 300 MHz*/ {.div = 0x089EE}, /* 58 Mhz , for vc01div4 = 250 MHz*/ + {.div = 0x081BA}, /* 74 Mhz , for vc01div4 = 300 MHz*/ {.div = 0x07BA0}, /* 65 Mhz , for vc01div4 = 250 MHz*/ {.div = 0x06f1C}, /* 72 Mhz , for vc01div4 = 250 MHz*/ {.div = 0x06E58}, /* 58 Mhz , for vco1div4 = 200 MHz */ {.div = 0x06c1B}, /* 74 Mhz , for vc01div4 = 250 MHz*/ + {.div = 0x058E3}, /* 108 Mhz , for vc01div4 = 300 MHz*/ {.div = 0x04A12}, /* 108 Mhz , for vc01div4 = 250 MHz*/ + {.div = 0x040A5}, /* 148.5 Mhz , for vc01div4 = 300 MHz*/ {.div = 0x0378E}, /* 144 Mhz , for vc01div4 = 250 MHz*/ {.div = 0x0360D}, /* 148 Mhz , for vc01div4 = 250 MHz*/ {.div = 0x035E0}, /* 148.5 MHz, for vc01div4 = 250 MHz*/ @@ -351,20 +387,31 @@ static struct aux_rate_tbl adc_rtbl[] = { /* General synth rate configuration table, in ascending order of rates */ static struct frac_rate_tbl gen_rtbl[] = { - /* For vco1div4 = 250 MHz */ - {.div = 0x1624E}, /* 22.5792 MHz */ - {.div = 0x14585}, /* 24.576 MHz */ - {.div = 0x14000}, /* 25 MHz */ - {.div = 0x0B127}, /* 45.1584 MHz */ - {.div = 0x0A000}, /* 50 MHz */ - {.div = 0x061A8}, /* 81.92 MHz */ - {.div = 0x05000}, /* 100 MHz */ - {.div = 0x02800}, /* 200 MHz */ - {.div = 0x02620}, /* 210 MHz */ - {.div = 0x02460}, /* 220 MHz */ - {.div = 0x022C0}, /* 230 MHz */ - {.div = 0x02160}, /* 240 MHz */ - {.div = 0x02000}, /* 250 MHz */ + {.div = 0x1A92B}, /* 22.5792 MHz for vco1div4=300 MHz*/ + {.div = 0x186A0}, /* 24.576 MHz for vco1div4=300 MHz*/ + {.div = 0x18000}, /* 25 MHz for vco1div4=300 MHz*/ + {.div = 0x1624E}, /* 22.5792 MHz for vco1div4=250 MHz*/ + {.div = 0x14585}, /* 24.576 MHz for vco1div4=250 MHz*/ + {.div = 0x14000}, /* 25 MHz for vco1div4=250 MHz*/ + {.div = 0x0D495}, /* 45.1584 MHz for vco1div4=300 MHz*/ + {.div = 0x0C000}, /* 50 MHz for vco1div4=300 MHz*/ + {.div = 0x0B127}, /* 45.1584 MHz for vco1div4=250 MHz*/ + {.div = 0x0A000}, /* 50 MHz for vco1div4=250 MHz*/ + {.div = 0x07530}, /* 81.92 MHz for vco1div4=300 MHz*/ + {.div = 0x061A8}, /* 81.92 MHz for vco1div4=250 MHz*/ + {.div = 0x06000}, /* 100 MHz for vco1div4=300 MHz*/ + {.div = 0x05000}, /* 100 MHz for vco1div4=250 MHz*/ + {.div = 0x03000}, /* 200 MHz for vco1div4=300 MHz*/ + {.div = 0x02DB6}, /* 210 MHz for vco1div4=300 MHz*/ + {.div = 0x02BA2}, /* 220 MHz for vco1div4=300 MHz*/ + {.div = 0x029BD}, /* 230 MHz for vco1div4=300 MHz*/ + {.div = 0x02800}, /* 200 MHz for vco1div4=250 MHz*/ + {.div = 0x02666}, /* 250 MHz for vco1div4=300 MHz*/ + {.div = 0x02620}, /* 210 MHz for vco1div4=250 MHz*/ + {.div = 0x02460}, /* 220 MHz for vco1div4=250 MHz*/ + {.div = 0x022C0}, /* 230 MHz for vco1div4=250 MHz*/ + {.div = 0x02160}, /* 240 MHz for vco1div4=250 MHz*/ + {.div = 0x02000}, /* 250 MHz for vco1div4=250 MHz*/ }; /* clock parents */ diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index ff35ebca1d8..a07c067fe96 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -107,6 +107,12 @@ static struct pll_rate_tbl pll_rtbl[] = { /* aux rate configuration table, in ascending order of rates */ static struct aux_rate_tbl aux_rtbl[] = { /* For PLL1 = 332 MHz */ + {.xscale = 1, .yscale = 81, .eq = 0}, /* 2.049 MHz */ + {.xscale = 1, .yscale = 59, .eq = 0}, /* 2.822 MHz */ + {.xscale = 2, .yscale = 81, .eq = 0}, /* 4.098 MHz */ + {.xscale = 3, .yscale = 89, .eq = 0}, /* 5.644 MHz */ + {.xscale = 4, .yscale = 81, .eq = 0}, /* 8.197 MHz */ + {.xscale = 4, .yscale = 59, .eq = 0}, /* 11.254 MHz */ {.xscale = 2, .yscale = 27, .eq = 0}, /* 12.296 MHz */ {.xscale = 2, .yscale = 8, .eq = 0}, /* 41.5 MHz */ {.xscale = 2, .yscale = 4, .eq = 0}, /* 83 MHz */ diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index e8d2b3109b3..8a81770be4c 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -92,6 +92,7 @@ static struct pll_rate_tbl pll_rtbl[] = { /* aux rate configuration table, in ascending order of rates */ static struct aux_rate_tbl aux_rtbl[] = { /* For PLL1 = 332 MHz */ + {.xscale = 2, .yscale = 27, .eq = 0}, /* 12.296 MHz */ {.xscale = 2, .yscale = 8, .eq = 0}, /* 41.5 MHz */ {.xscale = 2, .yscale = 4, .eq = 0}, /* 83 MHz */ {.xscale = 1, .yscale = 2, .eq = 1}, /* 166 MHz */ -- cgit v1.2.3 From 1b2d4ad585d5bfb57603aed08e8fab99069e16e7 Mon Sep 17 00:00:00 2001 From: Deepak Sikri Date: Sat, 10 Nov 2012 12:13:46 +0530 Subject: CLK: SPEAr: Correct index scanning done for clock synths The patch corrects the case when the rate table is being scanned for a given frequency, and the search frequency is beyond the maximum frequency indexed in the table. By default, the system should be set at max frequency present in the rate table. This patch correctly returns the corresponding index value. Signed-off-by: Deepak Sikri Signed-off-by: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/clk.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/clk/spear/clk.c b/drivers/clk/spear/clk.c index 7cd63788d54..628b6d5ed3d 100644 --- a/drivers/clk/spear/clk.c +++ b/drivers/clk/spear/clk.c @@ -32,5 +32,8 @@ long clk_round_rate_index(struct clk_hw *hw, unsigned long drate, } } + if ((*index) == rtbl_cnt) + (*index)--; + return rate; } -- cgit v1.2.3 From b70e6d009a88e09805152597e02f3d97a1d6ee99 Mon Sep 17 00:00:00 2001 From: Vipul Kumar Samar Date: Sat, 10 Nov 2012 12:13:47 +0530 Subject: CLK: SPEAr: Remove unused dummy apb_pclk Dummy clocks were added for ARM platforms, so that clk_get() for interface clk doesn't fail for amba devices from amba_probe(). Because there is no amba device for SPEAr that doesn't have a valid clock with dev_id for SPEAr, we don't need these dummy clocks. Hence, remove them. Signed-off-by: Vipul Kumar Samar Signed-off-by: Viresh Kumar Signed-off-by: Mike Turquette --- drivers/clk/spear/spear1310_clock.c | 3 --- drivers/clk/spear/spear1340_clock.c | 3 --- drivers/clk/spear/spear3xx_clock.c | 3 --- drivers/clk/spear/spear6xx_clock.c | 3 --- 4 files changed, 12 deletions(-) diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index bc7f37e131c..147e25f0040 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -388,9 +388,6 @@ void __init spear1310_clk_init(void) { struct clk *clk, *clk1; - clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); - clk_register_clkdev(clk, "apb_pclk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index d4de680bf51..82abea366b7 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -445,9 +445,6 @@ void __init spear1340_clk_init(void) { struct clk *clk, *clk1; - clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); - clk_register_clkdev(clk, "apb_pclk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index a07c067fe96..33d3ac588da 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -366,9 +366,6 @@ void __init spear3xx_clk_init(void) { struct clk *clk, *clk1; - clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); - clk_register_clkdev(clk, "apb_pclk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index 8a81770be4c..e862a333ad3 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -119,9 +119,6 @@ void __init spear6xx_clk_init(void) { struct clk *clk, *clk1; - clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); - clk_register_clkdev(clk, "apb_pclk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); -- cgit v1.2.3 From ccbd5bc448ec782af7d1f3f68bd450c9c38015a0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 16 Oct 2012 10:02:05 -0300 Subject: [media] adv7604: use presets where possible Use predefined video timings (prim_mode/vid_std) when available as recommended by Analog Devices (http://ez.analog.com/message/48267#48267). Also remove 720p30 support since the ADV7604 can't handle that. (http://ez.analog.com/message/61488#61488) Signed-off-by: Mats Randgaard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 275 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 219 insertions(+), 56 deletions(-) diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 74a18c0fc10..88b7984a418 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -105,7 +105,6 @@ static const struct v4l2_dv_timings adv7604_timings[] = { V4L2_DV_BT_CEA_720X576P50, V4L2_DV_BT_CEA_1280X720P24, V4L2_DV_BT_CEA_1280X720P25, - V4L2_DV_BT_CEA_1280X720P30, V4L2_DV_BT_CEA_1280X720P50, V4L2_DV_BT_CEA_1280X720P60, V4L2_DV_BT_CEA_1920X1080P24, @@ -114,6 +113,7 @@ static const struct v4l2_dv_timings adv7604_timings[] = { V4L2_DV_BT_CEA_1920X1080P50, V4L2_DV_BT_CEA_1920X1080P60, + /* sorted by DMT ID */ V4L2_DV_BT_DMT_640X350P85, V4L2_DV_BT_DMT_640X400P85, V4L2_DV_BT_DMT_720X400P85, @@ -163,6 +163,89 @@ static const struct v4l2_dv_timings adv7604_timings[] = { { }, }; +struct adv7604_video_standards { + struct v4l2_dv_timings timings; + u8 vid_std; + u8 v_freq; +}; + +/* sorted by number of lines */ +static const struct adv7604_video_standards adv7604_prim_mode_comp[] = { + /* { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, TODO flickering */ + { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 }, + { V4L2_DV_BT_CEA_1280X720P50, 0x19, 0x01 }, + { V4L2_DV_BT_CEA_1280X720P60, 0x19, 0x00 }, + { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 }, + { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 }, + { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 }, + { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 }, + { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 }, + /* TODO add 1920x1080P60_RB (CVT timing) */ + { }, +}; + +/* sorted by number of lines */ +static const struct adv7604_video_standards adv7604_prim_mode_gr[] = { + { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 }, + { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 }, + { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 }, + { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 }, + { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 }, + { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 }, + { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 }, + { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 }, + { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 }, + { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 }, + { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 }, + { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 }, + { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 }, + { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 }, + { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 }, + { V4L2_DV_BT_DMT_1360X768P60, 0x12, 0x00 }, + { V4L2_DV_BT_DMT_1366X768P60, 0x13, 0x00 }, + { V4L2_DV_BT_DMT_1400X1050P60, 0x14, 0x00 }, + { V4L2_DV_BT_DMT_1400X1050P75, 0x15, 0x00 }, + { V4L2_DV_BT_DMT_1600X1200P60, 0x16, 0x00 }, /* TODO not tested */ + /* TODO add 1600X1200P60_RB (not a DMT timing) */ + { V4L2_DV_BT_DMT_1680X1050P60, 0x18, 0x00 }, + { V4L2_DV_BT_DMT_1920X1200P60_RB, 0x19, 0x00 }, /* TODO not tested */ + { }, +}; + +/* sorted by number of lines */ +static const struct adv7604_video_standards adv7604_prim_mode_hdmi_comp[] = { + { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, + { V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 }, + { V4L2_DV_BT_CEA_1280X720P50, 0x13, 0x01 }, + { V4L2_DV_BT_CEA_1280X720P60, 0x13, 0x00 }, + { V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 }, + { V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 }, + { V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 }, + { V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 }, + { V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 }, + { }, +}; + +/* sorted by number of lines */ +static const struct adv7604_video_standards adv7604_prim_mode_hdmi_gr[] = { + { V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 }, + { V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 }, + { V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 }, + { V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 }, + { V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 }, + { V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 }, + { V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 }, + { V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 }, + { V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 }, + { V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 }, + { V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 }, + { V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 }, + { V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 }, + { V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 }, + { V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 }, + { }, +}; + /* ----------------------------------------------------------------------- */ static inline struct adv7604_state *to_state(struct v4l2_subdev *sd) @@ -671,64 +754,144 @@ static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd) ((io_read(sd, 0x6f) & 0x10) >> 4)); } -static void configure_free_run(struct v4l2_subdev *sd, const struct v4l2_bt_timings *timings) +static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd, + u8 prim_mode, + const struct adv7604_video_standards *predef_vid_timings, + const struct v4l2_dv_timings *timings) +{ + struct adv7604_state *state = to_state(sd); + int i; + + for (i = 0; predef_vid_timings[i].timings.bt.width; i++) { + if (!v4l_match_dv_timings(timings, &predef_vid_timings[i].timings, + DIGITAL_INPUT ? 250000 : 1000000)) + continue; + io_write(sd, 0x00, predef_vid_timings[i].vid_std); /* video std */ + io_write(sd, 0x01, (predef_vid_timings[i].v_freq << 4) + + prim_mode); /* v_freq and prim mode */ + return 0; + } + + return -1; +} + +static int configure_predefined_video_timings(struct v4l2_subdev *sd, + struct v4l2_dv_timings *timings) { + struct adv7604_state *state = to_state(sd); + int err; + + v4l2_dbg(1, debug, sd, "%s", __func__); + + /* reset to default values */ + io_write(sd, 0x16, 0x43); + io_write(sd, 0x17, 0x5a); + /* disable embedded syncs for auto graphics mode */ + cp_write_and_or(sd, 0x81, 0xef, 0x00); + cp_write(sd, 0x8f, 0x00); + cp_write(sd, 0x90, 0x00); + cp_write(sd, 0xa2, 0x00); + cp_write(sd, 0xa3, 0x00); + cp_write(sd, 0xa4, 0x00); + cp_write(sd, 0xa5, 0x00); + cp_write(sd, 0xa6, 0x00); + cp_write(sd, 0xa7, 0x00); + cp_write(sd, 0xab, 0x00); + cp_write(sd, 0xac, 0x00); + + switch (state->mode) { + case ADV7604_MODE_COMP: + case ADV7604_MODE_GR: + err = find_and_set_predefined_video_timings(sd, + 0x01, adv7604_prim_mode_comp, timings); + if (err) + err = find_and_set_predefined_video_timings(sd, + 0x02, adv7604_prim_mode_gr, timings); + break; + case ADV7604_MODE_HDMI: + err = find_and_set_predefined_video_timings(sd, + 0x05, adv7604_prim_mode_hdmi_comp, timings); + if (err) + err = find_and_set_predefined_video_timings(sd, + 0x06, adv7604_prim_mode_hdmi_gr, timings); + break; + default: + v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", + __func__, state->mode); + err = -1; + break; + } + + + return err; +} + +static void configure_custom_video_timings(struct v4l2_subdev *sd, + const struct v4l2_bt_timings *bt) +{ + struct adv7604_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - u32 width = htotal(timings); - u32 height = vtotal(timings); - u16 ch1_fr_ll = (((u32)timings->pixelclock / 100) > 0) ? - ((width * (ADV7604_fsc / 100)) / ((u32)timings->pixelclock / 100)) : 0; + u32 width = htotal(bt); + u32 height = vtotal(bt); + u16 cp_start_sav = bt->hsync + bt->hbackporch - 4; + u16 cp_start_eav = width - bt->hfrontporch; + u16 cp_start_vbi = height - bt->vfrontporch; + u16 cp_end_vbi = bt->vsync + bt->vbackporch; + u16 ch1_fr_ll = (((u32)bt->pixelclock / 100) > 0) ? + ((width * (ADV7604_fsc / 100)) / ((u32)bt->pixelclock / 100)) : 0; + const u8 pll[2] = { + 0xc0 | ((width >> 8) & 0x1f), + width & 0xff + }; v4l2_dbg(2, debug, sd, "%s\n", __func__); - cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); /* CH1_FR_LL */ - cp_write(sd, 0x90, ch1_fr_ll & 0xff); /* CH1_FR_LL */ - cp_write(sd, 0xab, (height >> 4) & 0xff); /* CP_LCOUNT_MAX */ - cp_write(sd, 0xac, (height & 0x0f) << 4); /* CP_LCOUNT_MAX */ - /* TODO support interlaced */ - cp_write(sd, 0x91, 0x10); /* INTERLACED */ - - /* Should only be set in auto-graphics mode [REF_02 p. 91-92] */ - if ((io_read(sd, 0x00) == 0x07) && (io_read(sd, 0x01) == 0x02)) { - u16 cp_start_sav, cp_start_eav, cp_start_vbi, cp_end_vbi; - const u8 pll[2] = { - (0xc0 | ((width >> 8) & 0x1f)), - (width & 0xff) - }; + switch (state->mode) { + case ADV7604_MODE_COMP: + case ADV7604_MODE_GR: + /* auto graphics */ + io_write(sd, 0x00, 0x07); /* video std */ + io_write(sd, 0x01, 0x02); /* prim mode */ + /* enable embedded syncs for auto graphics mode */ + cp_write_and_or(sd, 0x81, 0xef, 0x10); + /* Should only be set in auto-graphics mode [REF_02, p. 91-92] */ /* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */ /* IO-map reg. 0x16 and 0x17 should be written in sequence */ if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) { v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n"); - return; + break; } /* active video - horizontal timing */ - cp_start_sav = timings->hsync + timings->hbackporch - 4; - cp_start_eav = width - timings->hfrontporch; cp_write(sd, 0xa2, (cp_start_sav >> 4) & 0xff); - cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | ((cp_start_eav >> 8) & 0x0f)); + cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | + ((cp_start_eav >> 8) & 0x0f)); cp_write(sd, 0xa4, cp_start_eav & 0xff); /* active video - vertical timing */ - cp_start_vbi = height - timings->vfrontporch; - cp_end_vbi = timings->vsync + timings->vbackporch; cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff); - cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | ((cp_end_vbi >> 8) & 0xf)); + cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | + ((cp_end_vbi >> 8) & 0xf)); cp_write(sd, 0xa7, cp_end_vbi & 0xff); - } else { - /* reset to default values */ - io_write(sd, 0x16, 0x43); - io_write(sd, 0x17, 0x5a); - cp_write(sd, 0xa2, 0x00); - cp_write(sd, 0xa3, 0x00); - cp_write(sd, 0xa4, 0x00); - cp_write(sd, 0xa5, 0x00); - cp_write(sd, 0xa6, 0x00); - cp_write(sd, 0xa7, 0x00); + break; + case ADV7604_MODE_HDMI: + /* set default prim_mode/vid_std for HDMI + accoring to [REF_03, c. 4.2] */ + io_write(sd, 0x00, 0x02); /* video std */ + io_write(sd, 0x01, 0x06); /* prim mode */ + break; + default: + v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n", + __func__, state->mode); + break; } -} + cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); + cp_write(sd, 0x90, ch1_fr_ll & 0xff); + cp_write(sd, 0xab, (height >> 4) & 0xff); + cp_write(sd, 0xac, (height & 0x0f) << 4); +} static void set_rgb_quantization_range(struct v4l2_subdev *sd) { @@ -964,8 +1127,10 @@ static int stdi2dv_timings(struct v4l2_subdev *sd, state->aspect_ratio, timings)) return 0; - v4l2_dbg(2, debug, sd, "%s: No format candidate found for lcf=%d, bl = %d\n", - __func__, stdi->lcf, stdi->bl); + v4l2_dbg(2, debug, sd, + "%s: No format candidate found for lcvs = %d, lcf=%d, bl = %d, %chsync, %cvsync\n", + __func__, stdi->lcvs, stdi->lcf, stdi->bl, + stdi->hs_pol, stdi->vs_pol); return -1; } @@ -1163,6 +1328,7 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd, { struct adv7604_state *state = to_state(sd); struct v4l2_bt_timings *bt; + int err; if (!timings) return -EINVAL; @@ -1175,12 +1341,20 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd, __func__, (u32)bt->pixelclock); return -ERANGE; } + adv7604_fill_optional_dv_timings_fields(sd, timings); state->timings = *timings; - /* freerun */ - configure_free_run(sd, bt); + cp_write(sd, 0x91, bt->interlaced ? 0x50 : 0x10); + + /* Use prim_mode and vid_std when available */ + err = configure_predefined_video_timings(sd, timings); + if (err) { + /* custom settings when the video format + does not have prim_mode/vid_std */ + configure_custom_video_timings(sd, bt); + } set_rgb_quantization_range(sd); @@ -1238,12 +1412,6 @@ static void select_input(struct v4l2_subdev *sd) switch (state->mode) { case ADV7604_MODE_COMP: case ADV7604_MODE_GR: - /* set mode and select free run resolution */ - io_write(sd, 0x00, 0x07); /* video std */ - io_write(sd, 0x01, 0x02); /* prim mode */ - /* enable embedded syncs for auto graphics mode */ - cp_write_and_or(sd, 0x81, 0xef, 0x10); - /* reset ADI recommended settings for HDMI: */ /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */ @@ -1272,12 +1440,6 @@ static void select_input(struct v4l2_subdev *sd) break; case ADV7604_MODE_HDMI: - /* set mode and select free run resolution */ - io_write(sd, 0x00, 0x02); /* video std */ - io_write(sd, 0x01, 0x06); /* prim mode */ - /* disable embedded syncs for auto graphics mode */ - cp_write_and_or(sd, 0x81, 0xef, 0x00); - /* set ADI recommended settings for HDMI: */ /* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */ hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */ @@ -1534,8 +1696,9 @@ static int adv7604_log_status(struct v4l2_subdev *sd) v4l2_info(sd, "CP locked: %s\n", no_lock_cp(sd) ? "false" : "true"); v4l2_info(sd, "CP free run: %s\n", (!!(cp_read(sd, 0xff) & 0x10) ? "on" : "off")); - v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x\n", - io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f); + v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x, v_freq = 0x%x\n", + io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f, + (io_read(sd, 0x01) & 0x70) >> 4); v4l2_info(sd, "-----Video Timings-----\n"); if (read_stdi(sd, &stdi)) -- cgit v1.2.3 From cf9afb1dafaf1ffeffbb4acdb5adf255e8a2aa76 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 16 Oct 2012 10:12:55 -0300 Subject: [media] adv7604: restart STDI once if format is not found The STDI block may measure wrong values, especially for lcvs and lcf. If the driver can not find any valid timing, the STDI block is restarted to measure the video timings again. The function will return an error, but the restart of STDI will generate a new STDI interrupt and the format detection process will restart. Signed-off-by: Mats Randgaard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7604.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c index 88b7984a418..05f8950f6f9 100644 --- a/drivers/media/i2c/adv7604.c +++ b/drivers/media/i2c/adv7604.c @@ -76,6 +76,7 @@ struct adv7604_state { struct workqueue_struct *work_queues; struct delayed_work delayed_work_enable_hotplug; bool connector_hdmi; + bool restart_stdi_once; /* i2c clients */ struct i2c_client *i2c_avlink; @@ -1297,9 +1298,31 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd, stdi.lcvs -= 2; v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs); if (stdi2dv_timings(sd, &stdi, timings)) { + /* + * The STDI block may measure wrong values, especially + * for lcvs and lcf. If the driver can not find any + * valid timing, the STDI block is restarted to measure + * the video timings again. The function will return an + * error, but the restart of STDI will generate a new + * STDI interrupt and the format detection process will + * restart. + */ + if (state->restart_stdi_once) { + v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__); + /* TODO restart STDI for Sync Channel 2 */ + /* enter one-shot mode */ + cp_write_and_or(sd, 0x86, 0xf9, 0x00); + /* trigger STDI restart */ + cp_write_and_or(sd, 0x86, 0xf9, 0x04); + /* reset to continuous mode */ + cp_write_and_or(sd, 0x86, 0xf9, 0x02); + state->restart_stdi_once = false; + return -ENOLINK; + } v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__); return -ERANGE; } + state->restart_stdi_once = true; } found: @@ -2026,6 +2049,7 @@ static int adv7604_probe(struct i2c_client *client, v4l2_err(sd, "failed to create all i2c clients\n"); goto err_i2c; } + state->restart_stdi_once = true; /* work queues */ state->work_queues = create_singlethread_workqueue(client->name); -- cgit v1.2.3 From 99ba2fd297ed475dc6782e9029d4da041a85706a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 19 Nov 2012 10:19:46 -0200 Subject: w1: mxc_w1: Adapt the clock name to the new clock framework With the new i.mx clock framework the mxc_w1 clock is registered as: clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0"); So we do not need to pass "owire" string and can use NULL instead. While at it, also fix the clock error handling code. Acked-by: Sascha Hauer Acked-by: Evgeniy Polyakov Signed-off-by: Fabio Estevam ----- Changes since v2: - Add Ack's Changes since v1: - Fix clock error handling drivers/w1/masters/mxc_w1.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/mxc_w1.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c index 1cc61a700fa..12c1ab844d8 100644 --- a/drivers/w1/masters/mxc_w1.c +++ b/drivers/w1/masters/mxc_w1.c @@ -117,9 +117,9 @@ static int __devinit mxc_w1_probe(struct platform_device *pdev) if (!mdev) return -ENOMEM; - mdev->clk = clk_get(&pdev->dev, "owire"); - if (!mdev->clk) { - err = -ENODEV; + mdev->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(mdev->clk)) { + err = PTR_ERR(mdev->clk); goto failed_clk; } -- cgit v1.2.3 From fd21bfcc2d6e8b7fef20f05deef318b0ab7f8004 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 19 Nov 2012 10:19:48 -0200 Subject: w1: mxc_w1: Convert to platform driver Using module_platform_driver() makes the code smaller and cleaner. Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/mxc_w1.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c index 12c1ab844d8..3fb6c2480d2 100644 --- a/drivers/w1/masters/mxc_w1.c +++ b/drivers/w1/masters/mxc_w1.c @@ -191,21 +191,9 @@ static struct platform_driver mxc_w1_driver = { .name = "mxc_w1", }, .probe = mxc_w1_probe, - .remove = mxc_w1_remove, + .remove = __devexit_p(mxc_w1_remove), }; - -static int __init mxc_w1_init(void) -{ - return platform_driver_register(&mxc_w1_driver); -} - -static void mxc_w1_exit(void) -{ - platform_driver_unregister(&mxc_w1_driver); -} - -module_init(mxc_w1_init); -module_exit(mxc_w1_exit); +module_platform_driver(mxc_w1_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Freescale Semiconductors Inc"); -- cgit v1.2.3 From 128485daadc53ff0570132c0c3ed70a6f0610bf6 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 19 Nov 2012 10:19:47 -0200 Subject: w1: mxc_w1: Fix comment We are dealing with mxc_w1 registers. While at it use dev_err() instead. Signed-off-by: Fabio Estevam Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/mxc_w1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c index 3fb6c2480d2..53f89fa3bde 100644 --- a/drivers/w1/masters/mxc_w1.c +++ b/drivers/w1/masters/mxc_w1.c @@ -134,7 +134,7 @@ static int __devinit mxc_w1_probe(struct platform_device *pdev) mdev->regs = ioremap(res->start, resource_size(res)); if (!mdev->regs) { - printk(KERN_ERR "Cannot map frame buffer registers\n"); + dev_err(&pdev->dev, "Cannot map mxc_w1 registers\n"); goto failed_ioremap; } -- cgit v1.2.3 From f91a66c97b38a504827803bb93f83a7b85e50e5a Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:21:14 -0500 Subject: w1: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Cc: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/matrox_w1.c | 2 +- drivers/w1/masters/omap_hdq.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/w1/masters/matrox_w1.c b/drivers/w1/masters/matrox_w1.c index f667c26b219..0a3c423a0c9 100644 --- a/drivers/w1/masters/matrox_w1.c +++ b/drivers/w1/masters/matrox_w1.c @@ -55,7 +55,7 @@ static struct pci_driver matrox_w1_pci_driver = { .name = "matrox_w1", .id_table = matrox_w1_tbl, .probe = matrox_w1_probe, - .remove = __devexit_p(matrox_w1_remove), + .remove = matrox_w1_remove, }; /* diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index ca8e60bb2f9..652ca7f207e 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -74,7 +74,7 @@ static int __devexit omap_hdq_remove(struct platform_device *pdev); static struct platform_driver omap_hdq_driver = { .probe = omap_hdq_probe, - .remove = __devexit_p(omap_hdq_remove), + .remove = omap_hdq_remove, .driver = { .name = "omap_hdq", }, -- cgit v1.2.3 From 479e2bcecdf19ae44940d38248a3e2f9fd8f2c44 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:21:43 -0500 Subject: w1: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Cc: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/matrox_w1.c | 4 ++-- drivers/w1/masters/mxc_w1.c | 2 +- drivers/w1/masters/omap_hdq.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/w1/masters/matrox_w1.c b/drivers/w1/masters/matrox_w1.c index 0a3c423a0c9..1197f7ec54f 100644 --- a/drivers/w1/masters/matrox_w1.c +++ b/drivers/w1/masters/matrox_w1.c @@ -48,7 +48,7 @@ static struct pci_device_id matrox_w1_tbl[] = { }; MODULE_DEVICE_TABLE(pci, matrox_w1_tbl); -static int __devinit matrox_w1_probe(struct pci_dev *, const struct pci_device_id *); +static int matrox_w1_probe(struct pci_dev *, const struct pci_device_id *); static void __devexit matrox_w1_remove(struct pci_dev *); static struct pci_driver matrox_w1_pci_driver = { @@ -152,7 +152,7 @@ static void matrox_w1_hw_init(struct matrox_device *dev) matrox_w1_write_reg(dev, MATROX_GET_CONTROL, 0x00); } -static int __devinit matrox_w1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int matrox_w1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct matrox_device *dev; int err; diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c index 53f89fa3bde..23d39175749 100644 --- a/drivers/w1/masters/mxc_w1.c +++ b/drivers/w1/masters/mxc_w1.c @@ -103,7 +103,7 @@ static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit) return ((__raw_readb(ctrl_addr)) >> 3) & 0x1; } -static int __devinit mxc_w1_probe(struct platform_device *pdev) +static int mxc_w1_probe(struct platform_device *pdev) { struct mxc_w1_device *mdev; struct resource *res; diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 652ca7f207e..d3bdcc320ed 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -69,7 +69,7 @@ struct hdq_data { int init_trans; }; -static int __devinit omap_hdq_probe(struct platform_device *pdev); +static int omap_hdq_probe(struct platform_device *pdev); static int __devexit omap_hdq_remove(struct platform_device *pdev); static struct platform_driver omap_hdq_driver = { @@ -537,7 +537,7 @@ static void omap_w1_write_byte(void *_hdq, u8 byte) } } -static int __devinit omap_hdq_probe(struct platform_device *pdev) +static int omap_hdq_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct hdq_data *hdq_data; -- cgit v1.2.3 From 82849a93aad04c5a438d811081341b245fdade8c Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:26:23 -0500 Subject: w1: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Cc: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/matrox_w1.c | 4 ++-- drivers/w1/masters/mxc_w1.c | 2 +- drivers/w1/masters/omap_hdq.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/w1/masters/matrox_w1.c b/drivers/w1/masters/matrox_w1.c index 1197f7ec54f..d8667b0212d 100644 --- a/drivers/w1/masters/matrox_w1.c +++ b/drivers/w1/masters/matrox_w1.c @@ -49,7 +49,7 @@ static struct pci_device_id matrox_w1_tbl[] = { MODULE_DEVICE_TABLE(pci, matrox_w1_tbl); static int matrox_w1_probe(struct pci_dev *, const struct pci_device_id *); -static void __devexit matrox_w1_remove(struct pci_dev *); +static void matrox_w1_remove(struct pci_dev *); static struct pci_driver matrox_w1_pci_driver = { .name = "matrox_w1", @@ -220,7 +220,7 @@ err_out_free_device: return err; } -static void __devexit matrox_w1_remove(struct pci_dev *pdev) +static void matrox_w1_remove(struct pci_dev *pdev) { struct matrox_device *dev = pci_get_drvdata(pdev); diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c index 23d39175749..d338b56ea2f 100644 --- a/drivers/w1/masters/mxc_w1.c +++ b/drivers/w1/masters/mxc_w1.c @@ -167,7 +167,7 @@ failed_clk: /* * disassociate the w1 device from the driver */ -static int __devexit mxc_w1_remove(struct platform_device *pdev) +static int mxc_w1_remove(struct platform_device *pdev) { struct mxc_w1_device *mdev = platform_get_drvdata(pdev); struct resource *res; diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index d3bdcc320ed..184dbce4abd 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c @@ -70,7 +70,7 @@ struct hdq_data { }; static int omap_hdq_probe(struct platform_device *pdev); -static int __devexit omap_hdq_remove(struct platform_device *pdev); +static int omap_hdq_remove(struct platform_device *pdev); static struct platform_driver omap_hdq_driver = { .probe = omap_hdq_probe, @@ -613,7 +613,7 @@ err_w1: return ret; } -static int __devexit omap_hdq_remove(struct platform_device *pdev) +static int omap_hdq_remove(struct platform_device *pdev) { struct hdq_data *hdq_data = platform_get_drvdata(pdev); -- cgit v1.2.3 From 2c9e9fdc0b2d55886609f0503fb91f96dfec6948 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:19:15 -0500 Subject: w1: remove CONFIG_HOTPLUG ifdefs Remove conditional code based on CONFIG_HOTPLUG being false. It's always on now in preparation of it going away as an option. Signed-off-by: Bill Pemberton Cc: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/w1.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 1a574370d2c..7994d933f04 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -551,7 +551,6 @@ void w1_destroy_master_attributes(struct w1_master *master) sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group); } -#ifdef CONFIG_HOTPLUG static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) { struct w1_master *md = NULL; @@ -587,12 +586,6 @@ static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) end: return err; } -#else -static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - return 0; -} -#endif static int __w1_attach_slave_device(struct w1_slave *sl) { -- cgit v1.2.3 From 5bd647144151082f0e8beb58741e27e6dbd23827 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 18 Nov 2012 15:13:14 +0200 Subject: mei: compact code for mei bus message creation 1. replace boilerplate code for filling up the bus message header with a common wrapper function 2. shorten variable names and use temporal variables to save some screen space Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/init.c | 78 ++++++++++++++++------------------- drivers/misc/mei/interface.c | 75 +++++++++++++--------------------- drivers/misc/mei/interrupt.c | 96 ++++++++++++++++++-------------------------- drivers/misc/mei/mei_dev.h | 11 +++++ 4 files changed, 112 insertions(+), 148 deletions(-) diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 4fcb0bb2c9f..02784af1d1a 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -43,6 +43,7 @@ const char *mei_dev_state_str(int state) } + /** * mei_io_list_flush - removes list entry belonging to cl. * @@ -331,25 +332,20 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) void mei_host_start_message(struct mei_device *dev) { struct mei_msg_hdr *mei_hdr; - struct hbm_host_version_request *host_start_req; + struct hbm_host_version_request *start_req; + const size_t len = sizeof(struct hbm_host_version_request); + + mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); /* host start message */ - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_host_version_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - host_start_req = - (struct hbm_host_version_request *) &dev->wr_msg_buf[1]; - memset(host_start_req, 0, sizeof(struct hbm_host_version_request)); - host_start_req->hbm_cmd = HOST_START_REQ_CMD; - host_start_req->host_version.major_version = HBM_MAJOR_VERSION; - host_start_req->host_version.minor_version = HBM_MINOR_VERSION; + start_req = (struct hbm_host_version_request *)&dev->wr_msg_buf[1]; + memset(start_req, 0, len); + start_req->hbm_cmd = HOST_START_REQ_CMD; + start_req->host_version.major_version = HBM_MAJOR_VERSION; + start_req->host_version.minor_version = HBM_MINOR_VERSION; + dev->recvd_msg = false; - if (mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req, - mei_hdr->length)) { + if (mei_write_message(dev, mei_hdr, (unsigned char *)start_req, len)) { dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n"); dev->dev_state = MEI_DEV_RESETING; mei_reset(dev, 1); @@ -369,20 +365,16 @@ void mei_host_start_message(struct mei_device *dev) void mei_host_enum_clients_message(struct mei_device *dev) { struct mei_msg_hdr *mei_hdr; - struct hbm_host_enum_request *host_enum_req; - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; + struct hbm_host_enum_request *enum_req; + const size_t len = sizeof(struct hbm_host_enum_request); /* enumerate clients */ - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_host_enum_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1]; - memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request)); - host_enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; - if (mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req, - mei_hdr->length)) { + mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); + + enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1]; + memset(enum_req, 0, sizeof(struct hbm_host_enum_request)); + enum_req->hbm_cmd = HOST_ENUM_REQ_CMD; + + if (mei_write_message(dev, mei_hdr, (unsigned char *)enum_req, len)) { dev->dev_state = MEI_DEV_RESETING; dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); mei_reset(dev, 1); @@ -443,33 +435,31 @@ void mei_allocate_me_clients_storage(struct mei_device *dev) */ int mei_host_client_properties(struct mei_device *dev) { - struct mei_msg_hdr *mei_header; - struct hbm_props_request *host_cli_req; + + struct mei_msg_hdr *mei_hdr; + struct hbm_props_request *prop_req; + const size_t len = sizeof(struct hbm_props_request); + int b; u8 client_num = dev->me_client_presentation_num; + prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1]; + b = dev->me_client_index; b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b); if (b < MEI_CLIENTS_MAX) { dev->me_clients[client_num].client_id = b; dev->me_clients[client_num].mei_flow_ctrl_creds = 0; - mei_header = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; - mei_header->host_addr = 0; - mei_header->me_addr = 0; - mei_header->length = sizeof(struct hbm_props_request); - mei_header->msg_complete = 1; - mei_header->reserved = 0; + mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); - host_cli_req = (struct hbm_props_request *)&dev->wr_msg_buf[1]; - memset(host_cli_req, 0, sizeof(struct hbm_props_request)); + memset(prop_req, 0, sizeof(struct hbm_props_request)); - host_cli_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; - host_cli_req->address = b; + prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; + prop_req->address = b; - if (mei_write_message(dev, mei_header, - (unsigned char *)host_cli_req, - mei_header->length)) { + if (mei_write_message(dev, mei_hdr, + (unsigned char *)prop_req, len)) { dev->dev_state = MEI_DEV_RESETING; dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); mei_reset(dev, 1); diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c index 6b50cf0253e..8de85478596 100644 --- a/drivers/misc/mei/interface.c +++ b/drivers/misc/mei/interface.c @@ -292,28 +292,23 @@ int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl) int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl) { struct mei_msg_hdr *mei_hdr; - struct hbm_flow_control *mei_flow_control; - - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_flow_control); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - mei_flow_control = (struct hbm_flow_control *) &dev->wr_msg_buf[1]; - memset(mei_flow_control, 0, sizeof(*mei_flow_control)); - mei_flow_control->host_addr = cl->host_client_id; - mei_flow_control->me_addr = cl->me_client_id; - mei_flow_control->hbm_cmd = MEI_FLOW_CONTROL_CMD; - memset(mei_flow_control->reserved, 0, - sizeof(mei_flow_control->reserved)); + struct hbm_flow_control *flow_ctrl; + const size_t len = sizeof(struct hbm_flow_control); + + mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); + + flow_ctrl = (struct hbm_flow_control *)&dev->wr_msg_buf[1]; + memset(flow_ctrl, 0, len); + flow_ctrl->hbm_cmd = MEI_FLOW_CONTROL_CMD; + flow_ctrl->host_addr = cl->host_client_id; + flow_ctrl->me_addr = cl->me_client_id; + /* FIXME: reserved !? */ + memset(flow_ctrl->reserved, 0, sizeof(flow_ctrl->reserved)); dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n", cl->host_client_id, cl->me_client_id); return mei_write_message(dev, mei_hdr, - (unsigned char *) mei_flow_control, - sizeof(struct hbm_flow_control)); + (unsigned char *) flow_ctrl, len); } /** @@ -353,23 +348,18 @@ int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) { struct mei_msg_hdr *mei_hdr; struct hbm_client_connect_request *req; + const size_t len = sizeof(struct hbm_client_connect_request); - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_client_connect_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; + mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); req = (struct hbm_client_connect_request *)&dev->wr_msg_buf[1]; - memset(req, 0, sizeof(*req)); + memset(req, 0, len); + req->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD; req->host_addr = cl->host_client_id; req->me_addr = cl->me_client_id; - req->hbm_cmd = CLIENT_DISCONNECT_REQ_CMD; req->reserved = 0; - return mei_write_message(dev, mei_hdr, (unsigned char *)req, - sizeof(struct hbm_client_connect_request)); + return mei_write_message(dev, mei_hdr, (unsigned char *)req, len); } /** @@ -383,23 +373,16 @@ int mei_disconnect(struct mei_device *dev, struct mei_cl *cl) int mei_connect(struct mei_device *dev, struct mei_cl *cl) { struct mei_msg_hdr *mei_hdr; - struct hbm_client_connect_request *mei_cli_connect; - - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_client_connect_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - mei_cli_connect = - (struct hbm_client_connect_request *) &dev->wr_msg_buf[1]; - mei_cli_connect->host_addr = cl->host_client_id; - mei_cli_connect->me_addr = cl->me_client_id; - mei_cli_connect->hbm_cmd = CLIENT_CONNECT_REQ_CMD; - mei_cli_connect->reserved = 0; + struct hbm_client_connect_request *req; + const size_t len = sizeof(struct hbm_client_connect_request); - return mei_write_message(dev, mei_hdr, - (unsigned char *) mei_cli_connect, - sizeof(struct hbm_client_connect_request)); + mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); + + req = (struct hbm_client_connect_request *) &dev->wr_msg_buf[1]; + req->hbm_cmd = CLIENT_CONNECT_REQ_CMD; + req->host_addr = cl->host_client_id; + req->me_addr = cl->me_client_id; + req->reserved = 0; + + return mei_write_message(dev, mei_hdr, (unsigned char *) req, len); } diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index f8821015f3f..14becc0d556 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -429,39 +429,30 @@ static int same_disconn_addr(struct mei_cl *cl, static void mei_client_disconnect_request(struct mei_device *dev, struct hbm_client_connect_request *disconnect_req) { - struct mei_msg_hdr *mei_hdr; struct hbm_client_connect_response *disconnect_res; - struct mei_cl *cl_pos = NULL; - struct mei_cl *cl_next = NULL; + struct mei_cl *pos, *next; + const size_t len = sizeof(struct hbm_client_connect_response); - list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) { - if (same_disconn_addr(cl_pos, disconnect_req)) { + list_for_each_entry_safe(pos, next, &dev->file_list, link) { + if (same_disconn_addr(pos, disconnect_req)) { dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n", disconnect_req->host_addr, disconnect_req->me_addr); - cl_pos->state = MEI_FILE_DISCONNECTED; - cl_pos->timer_count = 0; - if (cl_pos == &dev->wd_cl) + pos->state = MEI_FILE_DISCONNECTED; + pos->timer_count = 0; + if (pos == &dev->wd_cl) dev->wd_pending = false; - else if (cl_pos == &dev->iamthif_cl) + else if (pos == &dev->iamthif_cl) dev->iamthif_timer = 0; /* prepare disconnect response */ - mei_hdr = - (struct mei_msg_hdr *) &dev->ext_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = - sizeof(struct hbm_client_connect_response); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - + (void)mei_hbm_hdr(&dev->ext_msg_buf[0], len); disconnect_res = (struct hbm_client_connect_response *) &dev->ext_msg_buf[1]; - disconnect_res->host_addr = cl_pos->host_client_id; - disconnect_res->me_addr = cl_pos->me_client_id; disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD; + disconnect_res->host_addr = pos->host_client_id; + disconnect_res->me_addr = pos->me_client_id; disconnect_res->status = 0; dev->extra_write_index = 2; break; @@ -469,7 +460,6 @@ static void mei_client_disconnect_request(struct mei_device *dev, } } - /** * mei_irq_thread_read_bus_message - bottom half read routine after ISR to * handle the read bus message cmd processing. @@ -488,7 +478,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, struct hbm_flow_control *flow_control; struct hbm_props_response *props_res; struct hbm_host_enum_response *enum_res; - struct hbm_host_stop_request *host_stop_req; + struct hbm_host_stop_request *stop_req; int res; @@ -514,26 +504,20 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, return; } } else { + u32 *buf = dev->wr_msg_buf; + const size_t len = sizeof(struct hbm_host_stop_request); + dev->version = version_res->me_max_version; + /* send stop message */ - mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_host_stop_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - - host_stop_req = (struct hbm_host_stop_request *) - &dev->wr_msg_buf[1]; - - memset(host_stop_req, - 0, - sizeof(struct hbm_host_stop_request)); - host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD; - host_stop_req->reason = DRIVER_STOP_REQUEST; + mei_hdr = mei_hbm_hdr(&buf[0], len); + stop_req = (struct hbm_host_stop_request *)&buf[1]; + memset(stop_req, 0, len); + stop_req->hbm_cmd = HOST_STOP_REQ_CMD; + stop_req->reason = DRIVER_STOP_REQUEST; + mei_write_message(dev, mei_hdr, - (unsigned char *) (host_stop_req), - mei_hdr->length); + (unsigned char *)stop_req, len); dev_dbg(&dev->pdev->dev, "version mismatch.\n"); return; } @@ -543,16 +527,14 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, break; case CLIENT_CONNECT_RES_CMD: - connect_res = - (struct hbm_client_connect_response *) mei_msg; + connect_res = (struct hbm_client_connect_response *) mei_msg; mei_client_connect_response(dev, connect_res); dev_dbg(&dev->pdev->dev, "client connect response message received.\n"); wake_up(&dev->wait_recvd_msg); break; case CLIENT_DISCONNECT_RES_CMD: - disconnect_res = - (struct hbm_client_connect_response *) mei_msg; + disconnect_res = (struct hbm_client_connect_response *) mei_msg; mei_client_disconnect_response(dev, disconnect_res); dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n"); wake_up(&dev->wait_recvd_msg); @@ -658,23 +640,21 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, break; case ME_STOP_REQ_CMD: - /* prepare stop request */ - mei_hdr = (struct mei_msg_hdr *) &dev->ext_msg_buf[0]; - mei_hdr->host_addr = 0; - mei_hdr->me_addr = 0; - mei_hdr->length = sizeof(struct hbm_host_stop_request); - mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - host_stop_req = - (struct hbm_host_stop_request *) &dev->ext_msg_buf[1]; - memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request)); - host_stop_req->hbm_cmd = HOST_STOP_REQ_CMD; - host_stop_req->reason = DRIVER_STOP_REQUEST; - host_stop_req->reserved[0] = 0; - host_stop_req->reserved[1] = 0; + { + /* prepare stop request: sent in next interrupt event */ + + u32 *buf = dev->ext_msg_buf; + const size_t len = sizeof(struct hbm_host_stop_request); + + mei_hdr = mei_hbm_hdr(&buf[0], len); + stop_req = (struct hbm_host_stop_request *)&buf[1]; + memset(stop_req, 0, len); + stop_req->hbm_cmd = HOST_STOP_REQ_CMD; + stop_req->reason = DRIVER_STOP_REQUEST; + dev->extra_write_index = 2; break; - + } default: BUG(); break; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index aaee666577b..e511b84ff4c 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -491,4 +491,15 @@ void mei_csr_clear_his(struct mei_device *dev); void mei_enable_interrupts(struct mei_device *dev); void mei_disable_interrupts(struct mei_device *dev); +static inline struct mei_msg_hdr *mei_hbm_hdr(u32 *buf, size_t length) +{ + struct mei_msg_hdr *hdr = (struct mei_msg_hdr *)buf; + hdr->host_addr = 0; + hdr->me_addr = 0; + hdr->length = length; + hdr->msg_complete = 1; + hdr->reserved = 0; + return hdr; +} + #endif -- cgit v1.2.3 From 5fb54fb456f77128f817ab3491d6b131bec480b5 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 18 Nov 2012 15:13:15 +0200 Subject: mei: use structured buffer for extra write buffer The structure of the message is static so we don't have to use and cast the buffer. We can also drop extra_write_index variable as this information can be extracted directly from the message header Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/init.c | 2 +- drivers/misc/mei/interrupt.c | 36 ++++++++++++++---------------------- drivers/misc/mei/mei_dev.h | 11 +++++++---- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 02784af1d1a..49600d6e372 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -288,7 +288,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) mei_me_cl_unlink(dev, &dev->iamthif_cl); mei_amthif_reset_params(dev); - dev->extra_write_index = 0; + memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg)); } dev->me_clients_num = 0; diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 14becc0d556..92246465ea1 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -446,15 +446,14 @@ static void mei_client_disconnect_request(struct mei_device *dev, dev->iamthif_timer = 0; /* prepare disconnect response */ - (void)mei_hbm_hdr(&dev->ext_msg_buf[0], len); + (void)mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len); disconnect_res = (struct hbm_client_connect_response *) - &dev->ext_msg_buf[1]; + &dev->wr_ext_msg.data; disconnect_res->hbm_cmd = CLIENT_DISCONNECT_RES_CMD; disconnect_res->host_addr = pos->host_client_id; disconnect_res->me_addr = pos->me_client_id; disconnect_res->status = 0; - dev->extra_write_index = 2; break; } } @@ -643,16 +642,13 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, { /* prepare stop request: sent in next interrupt event */ - u32 *buf = dev->ext_msg_buf; const size_t len = sizeof(struct hbm_host_stop_request); - mei_hdr = mei_hbm_hdr(&buf[0], len); - stop_req = (struct hbm_host_stop_request *)&buf[1]; + mei_hdr = mei_hbm_hdr((u32 *)&dev->wr_ext_msg.hdr, len); + stop_req = (struct hbm_host_stop_request *)&dev->wr_ext_msg.data; memset(stop_req, 0, len); stop_req->hbm_cmd = HOST_STOP_REQ_CMD; stop_req->reason = DRIVER_STOP_REQUEST; - - dev->extra_write_index = 2; break; } default: @@ -988,15 +984,11 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, wake_up_interruptible(&dev->wait_stop_wd); } - if (dev->extra_write_index) { - dev_dbg(&dev->pdev->dev, "extra_write_index =%d.\n", - dev->extra_write_index); - mei_write_message(dev, - (struct mei_msg_hdr *) &dev->ext_msg_buf[0], - (unsigned char *) &dev->ext_msg_buf[1], - (dev->extra_write_index - 1) * sizeof(u32)); - *slots -= dev->extra_write_index; - dev->extra_write_index = 0; + if (dev->wr_ext_msg.hdr.length) { + mei_write_message(dev, &dev->wr_ext_msg.hdr, + dev->wr_ext_msg.data, dev->wr_ext_msg.hdr.length); + *slots -= mei_data2slots(dev->wr_ext_msg.hdr.length); + dev->wr_ext_msg.hdr.length = 0; } if (dev->dev_state == MEI_DEV_ENABLED) { if (dev->wd_pending && @@ -1263,11 +1255,11 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) } /* check slots available for reading */ slots = mei_count_full_read_slots(dev); - dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n", - slots, dev->extra_write_index); - while (slots > 0 && !dev->extra_write_index) { - dev_dbg(&dev->pdev->dev, "slots =%08x extra_write_index =%08x.\n", - slots, dev->extra_write_index); + while (slots > 0) { + /* we have urgent data to send so break the read */ + if (dev->wr_ext_msg.hdr.length) + break; + dev_dbg(&dev->pdev->dev, "slots =%08x\n", slots); dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n"); rets = mei_irq_thread_read_handler(&complete_list, dev, &slots); if (rets) diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index e511b84ff4c..2a38e95e5de 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -192,8 +192,9 @@ struct mei_cl { }; /** - * struct mei_deive - MEI private device struct + * struct mei_device - MEI private device struct * @hbuf_depth - depth of host(write) buffer + * @wr_ext_msg - buffer for hbm control responses (set in read cycle) */ struct mei_device { struct pci_dev *pdev; /* pointer to pci device struct */ @@ -244,11 +245,13 @@ struct mei_device { u16 init_clients_timer; bool need_reset; - u32 extra_write_index; unsigned char rd_msg_buf[MEI_RD_MSG_BUF_SIZE]; /* control messages */ - u32 wr_msg_buf[128]; /* used for control messages */ - u32 ext_msg_buf[8]; /* for control responses */ u32 rd_msg_hdr; + u32 wr_msg_buf[128]; /* used for control messages */ + struct { + struct mei_msg_hdr hdr; + unsigned char data[4]; /* All HBM messages are 4 bytes */ + } wr_ext_msg; /* for control responses */ struct hbm_version version; -- cgit v1.2.3 From ea3b5fb710c6d0b61f4bfbbc48b34b99b9c89bae Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 18 Nov 2012 15:13:16 +0200 Subject: mei: streamline write complete flow function Rename the function _mei_irq_thread_cmpl to mei_irq_thread_write_complete to make clear it deals with writing. Remove cl from the parameter list as it can be extracted from cb block. Extract the common flow from if statements and document the logic properly Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 113 ++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 70 deletions(-) diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 92246465ea1..85e272258ff 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -734,90 +734,63 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots, } /** - * _mei_irq_thread_cmpl - processes completed and no-iamthif operation. + * mei_irq_thread_write_complete - write messages to device. * * @dev: the device structure. * @slots: free slots. - * @cb_pos: callback block. - * @cl: private data of the file object. + * @cb: callback block. * @cmpl_list: complete list. * * returns 0, OK; otherwise, error. */ -static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_cl_cb *cmpl_list) +static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots, + struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) { struct mei_msg_hdr *mei_hdr; + struct mei_cl *cl = cb->cl; + size_t len = cb->request_buffer.size - cb->buf_idx; + size_t msg_slots = mei_data2slots(len); + + mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; + mei_hdr->host_addr = cl->host_client_id; + mei_hdr->me_addr = cl->me_client_id; + mei_hdr->reserved = 0; - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - (cb_pos->request_buffer.size - cb_pos->buf_idx))) { - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = cb_pos->request_buffer.size - cb_pos->buf_idx; + if (*slots >= msg_slots) { + mei_hdr->length = len; mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; - dev_dbg(&dev->pdev->dev, "cb_pos->request_buffer.size =%d" - "mei_hdr->msg_complete = %d\n", - cb_pos->request_buffer.size, - mei_hdr->msg_complete); - dev_dbg(&dev->pdev->dev, "cb_pos->buf_idx =%lu\n", - cb_pos->buf_idx); - dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", - mei_hdr->length); - *slots -= mei_data2slots(mei_hdr->length); - if (mei_write_message(dev, mei_hdr, - (unsigned char *) - (cb_pos->request_buffer.data + - cb_pos->buf_idx), - mei_hdr->length)) { - cl->status = -ENODEV; - list_move_tail(&cb_pos->list, &cmpl_list->list); - return -ENODEV; - } else { - if (mei_flow_ctrl_reduce(dev, cl)) - return -ENODEV; - cl->status = 0; - cb_pos->buf_idx += mei_hdr->length; - list_move_tail(&cb_pos->list, &dev->write_waiting_list.list); - } + /* Split the message only if we can write the whole host buffer */ } else if (*slots == dev->hbuf_depth) { - /* buffer is still empty */ - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = - (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); + msg_slots = *slots; + len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); + mei_hdr->length = len; mei_hdr->msg_complete = 0; - mei_hdr->reserved = 0; - *slots -= mei_data2slots(mei_hdr->length); - if (mei_write_message(dev, mei_hdr, - (unsigned char *) - (cb_pos->request_buffer.data + - cb_pos->buf_idx), - mei_hdr->length)) { - cl->status = -ENODEV; - list_move_tail(&cb_pos->list, &cmpl_list->list); - return -ENODEV; - } else { - cb_pos->buf_idx += mei_hdr->length; - dev_dbg(&dev->pdev->dev, - "cb_pos->request_buffer.size =%d" - " mei_hdr->msg_complete = %d\n", - cb_pos->request_buffer.size, - mei_hdr->msg_complete); - dev_dbg(&dev->pdev->dev, "cb_pos->buf_idx =%lu\n", - cb_pos->buf_idx); - dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", - mei_hdr->length); - } - return -EMSGSIZE; } else { - return -EBADMSG; + /* wait for next time the host buffer is empty */ + return 0; } + dev_dbg(&dev->pdev->dev, "buf: size = %d idx = %lu\n", + cb->request_buffer.size, cb->buf_idx); + dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n", + mei_hdr->length, mei_hdr->msg_complete); + + *slots -= msg_slots; + if (mei_write_message(dev, mei_hdr, + cb->request_buffer.data + cb->buf_idx, len)) { + cl->status = -ENODEV; + list_move_tail(&cb->list, &cmpl_list->list); + return -ENODEV; + } + + if (mei_flow_ctrl_reduce(dev, cl)) + return -ENODEV; + + cl->status = 0; + cb->buf_idx += mei_hdr->length; + if (mei_hdr->msg_complete) + list_move_tail(&cb->list, &dev->write_waiting_list.list); + return 0; } @@ -1059,8 +1032,8 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, cl->host_client_id); continue; } - ret = _mei_irq_thread_cmpl(dev, slots, pos, - cl, cmpl_list); + ret = mei_irq_thread_write_complete(dev, slots, pos, + cmpl_list); if (ret) return ret; -- cgit v1.2.3 From 24c656e55f3985b6f5c0e2264243f7076f376193 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 18 Nov 2012 15:13:17 +0200 Subject: mei: streamline amthif write complete function Rename the function mei_amthif_irq_process_completed to mei_amthif_irq_write_complete Remove cl from the parameter list as it can be extracted from cb block. Extract the common flow from if statements and document the logic properly Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/amthif.c | 98 ++++++++++++++++++++------------------------ drivers/misc/mei/interrupt.c | 4 +- drivers/misc/mei/mei_dev.h | 6 +-- 3 files changed, 48 insertions(+), 60 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 095d0595a49..18794aea606 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -431,74 +431,64 @@ unsigned int mei_amthif_poll(struct mei_device *dev, * * returns 0, OK; otherwise, error. */ -int mei_amthif_irq_process_completed(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_cl_cb *cmpl_list) +int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, + struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list) { struct mei_msg_hdr *mei_hdr; + struct mei_cl *cl = cb->cl; + size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index; + size_t msg_slots = mei_data2slots(len); - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + - dev->iamthif_msg_buf_size - - dev->iamthif_msg_buf_index)) { - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = dev->iamthif_msg_buf_size - - dev->iamthif_msg_buf_index; + mei_hdr = (struct mei_msg_hdr *)&dev->wr_msg_buf[0]; + mei_hdr->host_addr = cl->host_client_id; + mei_hdr->me_addr = cl->me_client_id; + mei_hdr->reserved = 0; + + if (*slots >= msg_slots) { + mei_hdr->length = len; mei_hdr->msg_complete = 1; - mei_hdr->reserved = 0; + /* Split the message only if we can write the whole host buffer */ + } else if (*slots == dev->hbuf_depth) { + msg_slots = *slots; + len = (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); + mei_hdr->length = len; + mei_hdr->msg_complete = 0; + } else { + /* wait for next time the host buffer is empty */ + return 0; + } - *slots -= mei_data2slots(mei_hdr->length); + dev_dbg(&dev->pdev->dev, "msg: len = %d complete = %d\n", + mei_hdr->length, mei_hdr->msg_complete); - if (mei_write_message(dev, mei_hdr, - (dev->iamthif_msg_buf + - dev->iamthif_msg_buf_index), - mei_hdr->length)) { + *slots -= msg_slots; + if (mei_write_message(dev, mei_hdr, + dev->iamthif_msg_buf + dev->iamthif_msg_buf_index, + mei_hdr->length)) { dev->iamthif_state = MEI_IAMTHIF_IDLE; cl->status = -ENODEV; - list_del(&cb_pos->list); + list_del(&cb->list); return -ENODEV; - } else { - if (mei_flow_ctrl_reduce(dev, cl)) - return -ENODEV; - dev->iamthif_msg_buf_index += mei_hdr->length; - cb_pos->buf_idx = dev->iamthif_msg_buf_index; - cl->status = 0; - dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; - dev->iamthif_flow_control_pending = true; - /* save iamthif cb sent to amthi client */ - dev->iamthif_current_cb = cb_pos; - list_move_tail(&cb_pos->list, - &dev->write_waiting_list.list); + } - } - } else if (*slots == dev->hbuf_depth) { - /* buffer is still empty */ - mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0]; - mei_hdr->host_addr = cl->host_client_id; - mei_hdr->me_addr = cl->me_client_id; - mei_hdr->length = - (*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr); - mei_hdr->msg_complete = 0; - mei_hdr->reserved = 0; + if (mei_flow_ctrl_reduce(dev, cl)) + return -ENODEV; - *slots -= mei_data2slots(mei_hdr->length); + dev->iamthif_msg_buf_index += mei_hdr->length; + cl->status = 0; - if (mei_write_message(dev, mei_hdr, - (dev->iamthif_msg_buf + - dev->iamthif_msg_buf_index), - mei_hdr->length)) { - cl->status = -ENODEV; - list_del(&cb_pos->list); - } else { - dev->iamthif_msg_buf_index += mei_hdr->length; - } - return -EMSGSIZE; - } else { - return -EBADMSG; + if (mei_hdr->msg_complete) { + dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL; + dev->iamthif_flow_control_pending = true; + + /* save iamthif cb sent to amthi client */ + cb->buf_idx = dev->iamthif_msg_buf_index; + dev->iamthif_current_cb = cb; + + list_move_tail(&cb->list, &dev->write_waiting_list.list); } + return 0; } diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 85e272258ff..d30db38d618 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -1046,8 +1046,8 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, cl->host_client_id); continue; } - ret = mei_amthif_irq_process_completed(dev, slots, pos, - cl, cmpl_list); + ret = mei_amthif_irq_write_complete(dev, slots, + pos, cmpl_list); if (ret) return ret; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 2a38e95e5de..17d00aae74e 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -407,10 +407,8 @@ void mei_amthif_run_next_cmd(struct mei_device *dev); int mei_amthif_read_message(struct mei_cl_cb *complete_list, struct mei_device *dev, struct mei_msg_hdr *mei_hdr); -int mei_amthif_irq_process_completed(struct mei_device *dev, s32 *slots, - struct mei_cl_cb *cb_pos, - struct mei_cl *cl, - struct mei_cl_cb *cmpl_list); +int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots, + struct mei_cl_cb *cb, struct mei_cl_cb *cmpl_list); void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb); int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list, -- cgit v1.2.3 From 9a84d616980215d1d9222173c60329b57680483b Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 18 Nov 2012 15:13:18 +0200 Subject: mei: don't mix read and write slots Do not pass read slots pointer into function mei_irq_thread_write_handler, the write slots management is handled internally in the write handler Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index d30db38d618..cccb63a8c00 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -901,27 +901,27 @@ end: * mei_irq_thread_write_handler - bottom half write routine after * ISR to handle the write processing. * - * @cmpl_list: An instance of our list structure * @dev: the device structure - * @slots: slots to write. + * @cmpl_list: An instance of our list structure * * returns 0 on success, <0 on failure. */ -static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, - struct mei_device *dev, s32 *slots) +static int mei_irq_thread_write_handler(struct mei_device *dev, + struct mei_cl_cb *cmpl_list) { struct mei_cl *cl; struct mei_cl_cb *pos = NULL, *next = NULL; struct mei_cl_cb *list; + s32 slots; int ret; if (!mei_hbuf_is_empty(dev)) { dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); return 0; } - *slots = mei_hbuf_empty_slots(dev); - if (*slots <= 0) + slots = mei_hbuf_empty_slots(dev); + if (slots <= 0) return -EMSGSIZE; /* complete all waiting for write CB */ @@ -945,7 +945,7 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, if (cl == &dev->iamthif_cl) { dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n"); if (dev->iamthif_flow_control_pending) { - ret = mei_amthif_irq_read(dev, slots); + ret = mei_amthif_irq_read(dev, &slots); if (ret) return ret; } @@ -960,7 +960,7 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, if (dev->wr_ext_msg.hdr.length) { mei_write_message(dev, &dev->wr_ext_msg.hdr, dev->wr_ext_msg.data, dev->wr_ext_msg.hdr.length); - *slots -= mei_data2slots(dev->wr_ext_msg.hdr.length); + slots -= mei_data2slots(dev->wr_ext_msg.hdr.length); dev->wr_ext_msg.hdr.length = 0; } if (dev->dev_state == MEI_DEV_ENABLED) { @@ -974,9 +974,9 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, dev->wd_pending = false; if (dev->wd_state == MEI_WD_RUNNING) - *slots -= mei_data2slots(MEI_WD_START_MSG_SIZE); + slots -= mei_data2slots(MEI_WD_START_MSG_SIZE); else - *slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE); + slots -= mei_data2slots(MEI_WD_STOP_MSG_SIZE); } } @@ -991,14 +991,16 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, switch (pos->fop_type) { case MEI_FOP_CLOSE: /* send disconnect message */ - ret = _mei_irq_thread_close(dev, slots, pos, cl, cmpl_list); + ret = _mei_irq_thread_close(dev, &slots, pos, + cl, cmpl_list); if (ret) return ret; break; case MEI_FOP_READ: /* send flow control message */ - ret = _mei_irq_thread_read(dev, slots, pos, cl, cmpl_list); + ret = _mei_irq_thread_read(dev, &slots, pos, + cl, cmpl_list); if (ret) return ret; @@ -1007,7 +1009,8 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, /* connect message */ if (mei_other_client_is_connecting(dev, cl)) continue; - ret = _mei_irq_thread_ioctl(dev, slots, pos, cl, cmpl_list); + ret = _mei_irq_thread_ioctl(dev, &slots, pos, + cl, cmpl_list); if (ret) return ret; @@ -1032,7 +1035,7 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, cl->host_client_id); continue; } - ret = mei_irq_thread_write_complete(dev, slots, pos, + ret = mei_irq_thread_write_complete(dev, &slots, pos, cmpl_list); if (ret) return ret; @@ -1046,7 +1049,7 @@ static int mei_irq_thread_write_handler(struct mei_cl_cb *cmpl_list, cl->host_client_id); continue; } - ret = mei_amthif_irq_write_complete(dev, slots, + ret = mei_amthif_irq_write_complete(dev, &slots, pos, cmpl_list); if (ret) return ret; @@ -1238,7 +1241,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) if (rets) goto end; } - rets = mei_irq_thread_write_handler(&complete_list, dev, &slots); + rets = mei_irq_thread_write_handler(dev, &complete_list); end: dev_dbg(&dev->pdev->dev, "end of bottom half function.\n"); dev->host_hw_state = mei_hcsr_read(dev); -- cgit v1.2.3 From be9d87a790765bcc85d8bdab8a9be31cf7457b28 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 18 Nov 2012 15:13:19 +0200 Subject: mei: simplify write complete loop in irq handler extract the common, hence non conditional code from the if-else statment Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index cccb63a8c00..e5aa0ed3b8e 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -1027,34 +1027,21 @@ static int mei_irq_thread_write_handler(struct mei_device *dev, cl = pos->cl; if (cl == NULL) continue; + if (mei_flow_ctrl_creds(dev, cl) <= 0) { + dev_dbg(&dev->pdev->dev, + "No flow control credentials for client %d, not sending.\n", + cl->host_client_id); + continue; + } - if (cl != &dev->iamthif_cl) { - if (mei_flow_ctrl_creds(dev, cl) <= 0) { - dev_dbg(&dev->pdev->dev, - "No flow control credentials for client %d, not sending.\n", - cl->host_client_id); - continue; - } - ret = mei_irq_thread_write_complete(dev, &slots, pos, - cmpl_list); - if (ret) - return ret; - - } else if (cl == &dev->iamthif_cl) { - /* IAMTHIF IOCTL */ - dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n"); - if (mei_flow_ctrl_creds(dev, cl) <= 0) { - dev_dbg(&dev->pdev->dev, - "No flow control credentials for amthi client %d.\n", - cl->host_client_id); - continue; - } + if (cl == &dev->iamthif_cl) ret = mei_amthif_irq_write_complete(dev, &slots, pos, cmpl_list); - if (ret) - return ret; - - } + else + ret = mei_irq_thread_write_complete(dev, &slots, pos, + cmpl_list); + if (ret) + return ret; } return 0; -- cgit v1.2.3 From c1174c0edf546805a0ebc10d5d6154edbb56e1cf Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Sun, 18 Nov 2012 15:13:20 +0200 Subject: mei: Simplify the ME client enumeration code After enumerating all ME clients we call the client init functions for all matching UUIDs from a separate context. This remove the hackish cascading client initialisation process that was interleaving properties and connection command replies. Signed-off-by: Samuel Ortiz Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/init.c | 99 +++++++++++++++++++++++++++++--------------- drivers/misc/mei/interrupt.c | 75 ++++++++++----------------------- drivers/misc/mei/main.c | 2 + drivers/misc/mei/mei_dev.h | 5 ++- 4 files changed, 95 insertions(+), 86 deletions(-) diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 49600d6e372..a54cd5567ca 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -423,54 +423,87 @@ void mei_allocate_me_clients_storage(struct mei_device *dev) dev->me_clients = clients; return ; } -/** - * host_client_properties - reads properties for client - * - * @dev: the device structure - * - * returns: - * < 0 - Error. - * = 0 - no more clients. - * = 1 - still have clients to send properties request. - */ -int mei_host_client_properties(struct mei_device *dev) + +void mei_host_client_init(struct work_struct *work) +{ + struct mei_device *dev = container_of(work, + struct mei_device, init_work); + struct mei_client_properties *client_props; + int i; + + mutex_lock(&dev->device_lock); + + bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX); + dev->open_handle_count = 0; + + /* + * Reserving the first three client IDs + * 0: Reserved for MEI Bus Message communications + * 1: Reserved for Watchdog + * 2: Reserved for AMTHI + */ + bitmap_set(dev->host_clients_map, 0, 3); + + for (i = 0; i < dev->me_clients_num; i++) { + client_props = &dev->me_clients[i].props; + + if (!uuid_le_cmp(client_props->protocol_name, mei_amthi_guid)) + mei_amthif_host_init(dev); + else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid)) + mei_wd_host_init(dev); + } + + dev->dev_state = MEI_DEV_ENABLED; + + mutex_unlock(&dev->device_lock); +} + +int mei_host_client_enumerate(struct mei_device *dev) { struct mei_msg_hdr *mei_hdr; struct hbm_props_request *prop_req; const size_t len = sizeof(struct hbm_props_request); + unsigned long next_client_index; + u8 client_num; - int b; - u8 client_num = dev->me_client_presentation_num; - prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1]; + client_num = dev->me_client_presentation_num; - b = dev->me_client_index; - b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b); - if (b < MEI_CLIENTS_MAX) { - dev->me_clients[client_num].client_id = b; - dev->me_clients[client_num].mei_flow_ctrl_creds = 0; - mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); + next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, + dev->me_client_index); + /* We got all client properties */ + if (next_client_index == MEI_CLIENTS_MAX) { + schedule_work(&dev->init_work); - memset(prop_req, 0, sizeof(struct hbm_props_request)); + return 0; + } - prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; - prop_req->address = b; + dev->me_clients[client_num].client_id = next_client_index; + dev->me_clients[client_num].mei_flow_ctrl_creds = 0; + + mei_hdr = mei_hbm_hdr(&dev->wr_msg_buf[0], len); + prop_req = (struct hbm_props_request *)&dev->wr_msg_buf[1]; + + memset(prop_req, 0, sizeof(struct hbm_props_request)); - if (mei_write_message(dev, mei_hdr, - (unsigned char *)prop_req, len)) { - dev->dev_state = MEI_DEV_RESETING; - dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n"); - mei_reset(dev, 1); - return -EIO; - } - dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; - dev->me_client_index = b; - return 1; + prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD; + prop_req->address = next_client_index; + + if (mei_write_message(dev, mei_hdr, (unsigned char *) prop_req, + mei_hdr->length)) { + dev->dev_state = MEI_DEV_RESETING; + dev_err(&dev->pdev->dev, "Properties request command failed\n"); + mei_reset(dev, 1); + + return -EIO; } + dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT; + dev->me_client_index = next_client_index; + return 0; } diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index e5aa0ed3b8e..04fa2134615 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -252,8 +252,6 @@ static void mei_client_connect_response(struct mei_device *dev, dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n"); mei_watchdog_register(dev); - /* next step in the state maching */ - mei_amthif_host_init(dev); return; } @@ -470,6 +468,7 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, struct mei_msg_hdr *mei_hdr) { struct mei_bus_message *mei_msg; + struct mei_me_client *me_client; struct hbm_host_version_response *version_res; struct hbm_client_connect_response *connect_res; struct hbm_client_connect_response *disconnect_res; @@ -478,8 +477,6 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, struct hbm_props_response *props_res; struct hbm_host_enum_response *enum_res; struct hbm_host_stop_request *stop_req; - int res; - /* read the message to our buffer */ BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf)); @@ -547,64 +544,37 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, case HOST_CLIENT_PROPERTIES_RES_CMD: props_res = (struct hbm_props_response *)mei_msg; + me_client = &dev->me_clients[dev->me_client_presentation_num]; + if (props_res->status || !dev->me_clients) { dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n"); mei_reset(dev, 1); return; } - if (dev->me_clients[dev->me_client_presentation_num] - .client_id == props_res->address) { - dev->me_clients[dev->me_client_presentation_num].props - = props_res->client_properties; + if (me_client->client_id != props_res->address) { + dev_err(&dev->pdev->dev, + "Host client properties reply mismatch\n"); + mei_reset(dev, 1); - if (dev->dev_state == MEI_DEV_INIT_CLIENTS && - dev->init_clients_state == - MEI_CLIENT_PROPERTIES_MESSAGE) { - dev->me_client_index++; - dev->me_client_presentation_num++; - - /** Send Client Properties request **/ - res = mei_host_client_properties(dev); - if (res < 0) { - dev_dbg(&dev->pdev->dev, "mei_host_client_properties() failed"); - return; - } else if (!res) { - /* - * No more clients to send to. - * Clear Map for indicating now ME clients - * with associated host client - */ - bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX); - dev->open_handle_count = 0; - - /* - * Reserving the first three client IDs - * Client Id 0 - Reserved for MEI Bus Message communications - * Client Id 1 - Reserved for Watchdog - * Client ID 2 - Reserved for AMTHI - */ - bitmap_set(dev->host_clients_map, 0, 3); - dev->dev_state = MEI_DEV_ENABLED; - - /* if wd initialization fails, initialization the AMTHI client, - * otherwise the AMTHI client will be initialized after the WD client connect response - * will be received - */ - if (mei_wd_host_init(dev)) - mei_amthif_host_init(dev); - } + return; + } - } else { - dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message"); - mei_reset(dev, 1); - return; - } - } else { - dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message for wrong client ID\n"); + if (dev->dev_state != MEI_DEV_INIT_CLIENTS || + dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) { + dev_err(&dev->pdev->dev, + "Unexpected client properties reply\n"); mei_reset(dev, 1); + return; } + + me_client->props = props_res->client_properties; + dev->me_client_index++; + dev->me_client_presentation_num++; + + mei_host_client_enumerate(dev); + break; case HOST_ENUM_RES_CMD: @@ -618,7 +588,8 @@ static void mei_irq_thread_read_bus_message(struct mei_device *dev, mei_allocate_me_clients_storage(dev); dev->init_clients_state = MEI_CLIENT_PROPERTIES_MESSAGE; - mei_host_client_properties(dev); + + mei_host_client_enumerate(dev); } else { dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n"); mei_reset(dev, 1); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 251aafff549..7c9c381e5c9 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -829,6 +829,8 @@ static int __devinit mei_probe(struct pci_dev *pdev, goto disable_msi; } INIT_DELAYED_WORK(&dev->timer_work, mei_timer); + INIT_WORK(&dev->init_work, mei_host_client_init); + if (mei_hw_init(dev)) { dev_err(&pdev->dev, "init hw failure.\n"); err = -ENODEV; diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 17d00aae74e..25da04549d0 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -287,6 +287,8 @@ struct mei_device { bool iamthif_flow_control_pending; bool iamthif_ioctl; bool iamthif_canceled; + + struct work_struct init_work; }; static inline unsigned long mei_secs_to_jiffies(unsigned long sec) @@ -363,7 +365,8 @@ static inline bool mei_cl_cmp_id(const struct mei_cl *cl1, */ void mei_host_start_message(struct mei_device *dev); void mei_host_enum_clients_message(struct mei_device *dev); -int mei_host_client_properties(struct mei_device *dev); +int mei_host_client_enumerate(struct mei_device *dev); +void mei_host_client_init(struct work_struct *work); /* * MEI interrupt functions prototype -- cgit v1.2.3 From 9306a8b0c29e11d823b258f5796353a4fe3e3be3 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:20:25 -0500 Subject: mei: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Cc: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 7c9c381e5c9..f432b8d7e19 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -1023,8 +1023,8 @@ static struct pci_driver mei_driver = { .name = KBUILD_MODNAME, .id_table = mei_pci_tbl, .probe = mei_probe, - .remove = __devexit_p(mei_remove), - .shutdown = __devexit_p(mei_remove), + .remove = mei_remove, + .shutdown = mei_remove, .driver.pm = MEI_PM_OPS, }; -- cgit v1.2.3 From 989623c7d687d3996d5676a6e1474dc7f01bf158 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 21 Nov 2012 12:46:40 -0800 Subject: hv: hv_balloon: mark a function static This resolves the following sparse warning: drivers/hv/hv_balloon.c:548:6: sparse: symbol 'free_balloon_pages' was not declared. Should it be static? Reported-by: Xie ChanglongX Cc: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_balloon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c index bbc497373aa..f6c0011a033 100644 --- a/drivers/hv/hv_balloon.c +++ b/drivers/hv/hv_balloon.c @@ -545,7 +545,7 @@ static void post_status(struct hv_dynmem_device *dm) -void free_balloon_pages(struct hv_dynmem_device *dm, +static void free_balloon_pages(struct hv_dynmem_device *dm, union dm_mem_page_range *range_array) { int num_pages = range_array->finfo.page_cnt; -- cgit v1.2.3 From 2d6bed9ca93e98685bc5038d686984fd449cd978 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:21:23 -0500 Subject: drivers/misc: remove use of __devexit_p MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Cc: "Michał Mirosław" Cc: Wolfram Sang Cc: Eric Piel Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ad525x_dpot-i2c.c | 2 +- drivers/misc/ad525x_dpot-spi.c | 2 +- drivers/misc/apds9802als.c | 2 +- drivers/misc/apds990x.c | 2 +- drivers/misc/atmel-ssc.c | 2 +- drivers/misc/bh1770glc.c | 2 +- drivers/misc/bh1780gli.c | 2 +- drivers/misc/bmp085-i2c.c | 2 +- drivers/misc/bmp085-spi.c | 2 +- drivers/misc/cb710/core.c | 2 +- drivers/misc/eeprom/at24.c | 2 +- drivers/misc/eeprom/at25.c | 2 +- drivers/misc/eeprom/eeprom_93xx46.c | 2 +- drivers/misc/fsa9480.c | 2 +- drivers/misc/hpilo.c | 2 +- drivers/misc/ibmasm/module.c | 2 +- drivers/misc/ioc4.c | 2 +- drivers/misc/isl29003.c | 2 +- drivers/misc/lis3lv02d/lis3lv02d_i2c.c | 2 +- drivers/misc/lis3lv02d/lis3lv02d_spi.c | 2 +- drivers/misc/pch_phub.c | 2 +- drivers/misc/phantom.c | 2 +- drivers/misc/pti.c | 2 +- drivers/misc/ti_dac7512.c | 2 +- drivers/misc/tsl2550.c | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index 820826270b6..7254a98a89f 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -109,7 +109,7 @@ static struct i2c_driver ad_dpot_i2c_driver = { .owner = THIS_MODULE, }, .probe = ad_dpot_i2c_probe, - .remove = __devexit_p(ad_dpot_i2c_remove), + .remove = ad_dpot_i2c_remove, .id_table = ad_dpot_id, }; diff --git a/drivers/misc/ad525x_dpot-spi.c b/drivers/misc/ad525x_dpot-spi.c index f62317540d0..67e3073c2a6 100644 --- a/drivers/misc/ad525x_dpot-spi.c +++ b/drivers/misc/ad525x_dpot-spi.c @@ -131,7 +131,7 @@ static struct spi_driver ad_dpot_spi_driver = { .owner = THIS_MODULE, }, .probe = ad_dpot_spi_probe, - .remove = __devexit_p(ad_dpot_spi_remove), + .remove = ad_dpot_spi_remove, .id_table = ad_dpot_spi_id, }; diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index 94923d25991..0132d15a995 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c @@ -326,7 +326,7 @@ static struct i2c_driver apds9802als_driver = { .pm = APDS9802ALS_PM_OPS, }, .probe = apds9802als_probe, - .remove = __devexit_p(apds9802als_remove), + .remove = apds9802als_remove, .suspend = apds9802als_suspend, .resume = apds9802als_resume, .id_table = apds9802als_id, diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c index ee74244aa03..f955d546f2d 100644 --- a/drivers/misc/apds990x.c +++ b/drivers/misc/apds990x.c @@ -1275,7 +1275,7 @@ static struct i2c_driver apds990x_driver = { .pm = &apds990x_pm_ops, }, .probe = apds990x_probe, - .remove = __devexit_p(apds990x_remove), + .remove = apds990x_remove, .id_table = apds990x_id, }; diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index 5bb18778107..191c2ce9d5e 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c @@ -152,7 +152,7 @@ static int __devexit ssc_remove(struct platform_device *pdev) } static struct platform_driver ssc_driver = { - .remove = __devexit_p(ssc_remove), + .remove = ssc_remove, .driver = { .name = "ssc", .owner = THIS_MODULE, diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c index 3d56ae7ef8d..c4b65e26a76 100644 --- a/drivers/misc/bh1770glc.c +++ b/drivers/misc/bh1770glc.c @@ -1395,7 +1395,7 @@ static struct i2c_driver bh1770_driver = { .pm = &bh1770_pm_ops, }, .probe = bh1770_probe, - .remove = __devexit_p(bh1770_remove), + .remove = bh1770_remove, .id_table = bh1770_id, }; diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c index f1f9877f3fd..54f6f39f990 100644 --- a/drivers/misc/bh1780gli.c +++ b/drivers/misc/bh1780gli.c @@ -248,7 +248,7 @@ static const struct i2c_device_id bh1780_id[] = { static struct i2c_driver bh1780_driver = { .probe = bh1780_probe, - .remove = __devexit_p(bh1780_remove), + .remove = bh1780_remove, .id_table = bh1780_id, .driver = { .name = "bh1780", diff --git a/drivers/misc/bmp085-i2c.c b/drivers/misc/bmp085-i2c.c index a4f33c995ea..08cd7958c14 100644 --- a/drivers/misc/bmp085-i2c.c +++ b/drivers/misc/bmp085-i2c.c @@ -71,7 +71,7 @@ static struct i2c_driver bmp085_i2c_driver = { }, .id_table = bmp085_id, .probe = bmp085_i2c_probe, - .remove = __devexit_p(bmp085_i2c_remove), + .remove = bmp085_i2c_remove, .detect = bmp085_i2c_detect, .address_list = normal_i2c diff --git a/drivers/misc/bmp085-spi.c b/drivers/misc/bmp085-spi.c index 5e982af9973..ed34885a6b3 100644 --- a/drivers/misc/bmp085-spi.c +++ b/drivers/misc/bmp085-spi.c @@ -70,7 +70,7 @@ static struct spi_driver bmp085_spi_driver = { }, .id_table = bmp085_id, .probe = bmp085_spi_probe, - .remove = __devexit_p(bmp085_spi_remove) + .remove = bmp085_spi_remove }; module_spi_driver(bmp085_spi_driver); diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c index 9d5eed75466..489c468cf96 100644 --- a/drivers/misc/cb710/core.c +++ b/drivers/misc/cb710/core.c @@ -332,7 +332,7 @@ static struct pci_driver cb710_driver = { .name = KBUILD_MODNAME, .id_table = cb710_pci_tbl, .probe = cb710_probe, - .remove = __devexit_p(cb710_remove_one), + .remove = cb710_remove_one, #ifdef CONFIG_PM .suspend = cb710_suspend, .resume = cb710_resume, diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index ab1ad41786d..3c36997bdac 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -680,7 +680,7 @@ static struct i2c_driver at24_driver = { .owner = THIS_MODULE, }, .probe = at24_probe, - .remove = __devexit_p(at24_remove), + .remove = at24_remove, .id_table = at24_ids, }; diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 4ed93dd5411..fcb237e9bb1 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -477,7 +477,7 @@ static struct spi_driver at25_driver = { .owner = THIS_MODULE, }, .probe = at25_probe, - .remove = __devexit_p(at25_remove), + .remove = at25_remove, }; module_spi_driver(at25_driver); diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index ce3fe3633dd..3dc14eafc5c 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -389,7 +389,7 @@ static struct spi_driver eeprom_93xx46_driver = { .owner = THIS_MODULE, }, .probe = eeprom_93xx46_probe, - .remove = __devexit_p(eeprom_93xx46_remove), + .remove = eeprom_93xx46_remove, }; module_spi_driver(eeprom_93xx46_driver); diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c index ac96c3a4034..38b52b90167 100644 --- a/drivers/misc/fsa9480.c +++ b/drivers/misc/fsa9480.c @@ -533,7 +533,7 @@ static struct i2c_driver fsa9480_i2c_driver = { .name = "fsa9480", }, .probe = fsa9480_probe, - .remove = __devexit_p(fsa9480_remove), + .remove = fsa9480_remove, .resume = fsa9480_resume, .suspend = fsa9480_suspend, .id_table = fsa9480_id, diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index b362d938e92..47a9ce6b16f 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -859,7 +859,7 @@ static struct pci_driver ilo_driver = { .name = ILO_NAME, .id_table = ilo_devices, .probe = ilo_probe, - .remove = __devexit_p(ilo_remove), + .remove = ilo_remove, }; static int __init ilo_init(void) diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c index 168d8008f46..f34a92fd679 100644 --- a/drivers/misc/ibmasm/module.c +++ b/drivers/misc/ibmasm/module.c @@ -198,7 +198,7 @@ static struct pci_driver ibmasm_driver = { .name = DRIVER_NAME, .id_table = ibmasm_pci_table, .probe = ibmasm_init_one, - .remove = __devexit_p(ibmasm_remove_one), + .remove = ibmasm_remove_one, }; static void __exit ibmasm_exit (void) diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index 6a7710603a9..794a7e002c8 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c @@ -466,7 +466,7 @@ static struct pci_driver ioc4_driver = { .name = "IOC4", .id_table = ioc4_id_table, .probe = ioc4_probe, - .remove = __devexit_p(ioc4_remove), + .remove = ioc4_remove, }; MODULE_DEVICE_TABLE(pci, ioc4_id_table); diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c index eb5de2e210d..bef5307296f 100644 --- a/drivers/misc/isl29003.c +++ b/drivers/misc/isl29003.c @@ -451,7 +451,7 @@ static struct i2c_driver isl29003_driver = { .suspend = isl29003_suspend, .resume = isl29003_resume, .probe = isl29003_probe, - .remove = __devexit_p(isl29003_remove), + .remove = isl29003_remove, .id_table = isl29003_id, }; diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index 60ec8689d6e..403804c8612 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c @@ -280,7 +280,7 @@ static struct i2c_driver lis3lv02d_i2c_driver = { .of_match_table = of_match_ptr(lis3lv02d_i2c_dt_ids), }, .probe = lis3lv02d_i2c_probe, - .remove = __devexit_p(lis3lv02d_i2c_remove), + .remove = lis3lv02d_i2c_remove, .id_table = lis3lv02d_id, }; diff --git a/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c index ccb6475fa05..0e415c31e03 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_spi.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_spi.c @@ -144,7 +144,7 @@ static struct spi_driver lis302dl_spi_driver = { .of_match_table = of_match_ptr(lis302dl_spi_dt_ids), }, .probe = lis302dl_spi_probe, - .remove = __devexit_p(lis302dl_spi_remove), + .remove = lis302dl_spi_remove, }; module_spi_driver(lis302dl_spi_driver); diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index c9f20dae185..5581774393c 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -888,7 +888,7 @@ static struct pci_driver pch_phub_driver = { .name = "pch_phub", .id_table = pch_phub_pcidev_id, .probe = pch_phub_probe, - .remove = __devexit_p(pch_phub_remove), + .remove = pch_phub_remove, .suspend = pch_phub_suspend, .resume = pch_phub_resume }; diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index 21b28fc6d91..79038e9ced0 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c @@ -499,7 +499,7 @@ static struct pci_driver phantom_pci_driver = { .name = "phantom", .id_table = phantom_pci_tbl, .probe = phantom_probe, - .remove = __devexit_p(phantom_remove), + .remove = phantom_remove, .suspend = phantom_suspend, .resume = phantom_resume }; diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index 4999b34b7a6..3c5d74638ea 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -901,7 +901,7 @@ static struct pci_driver pti_pci_driver = { .name = PCINAME, .id_table = pci_ids, .probe = pti_pci_probe, - .remove = __devexit_p(pti_pci_remove), + .remove = pti_pci_remove, }; /** diff --git a/drivers/misc/ti_dac7512.c b/drivers/misc/ti_dac7512.c index 5acbba120de..85989ca7ad2 100644 --- a/drivers/misc/ti_dac7512.c +++ b/drivers/misc/ti_dac7512.c @@ -79,7 +79,7 @@ static struct spi_driver dac7512_driver = { .owner = THIS_MODULE, }, .probe = dac7512_probe, - .remove = __devexit_p(dac7512_remove), + .remove = dac7512_remove, }; module_spi_driver(dac7512_driver); diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c index 0beb298a17d..09ffb0b705f 100644 --- a/drivers/misc/tsl2550.c +++ b/drivers/misc/tsl2550.c @@ -450,7 +450,7 @@ static struct i2c_driver tsl2550_driver = { .suspend = tsl2550_suspend, .resume = tsl2550_resume, .probe = tsl2550_probe, - .remove = __devexit_p(tsl2550_remove), + .remove = tsl2550_remove, .id_table = tsl2550_id, }; -- cgit v1.2.3 From 80c8ae289266529445fad030fabf5fcf01ccda0d Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:23:05 -0500 Subject: misc: remove use of __devinit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Cc: "Michał Mirosław" Cc: Eric Piel Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ad525x_dpot-i2c.c | 2 +- drivers/misc/ad525x_dpot-spi.c | 2 +- drivers/misc/ad525x_dpot.c | 4 ++-- drivers/misc/apds990x.c | 2 +- drivers/misc/bh1770glc.c | 2 +- drivers/misc/bh1780gli.c | 2 +- drivers/misc/bmp085-i2c.c | 2 +- drivers/misc/bmp085-spi.c | 2 +- drivers/misc/bmp085.c | 2 +- drivers/misc/cb710/core.c | 6 +++--- drivers/misc/cs5535-mfgpt.c | 6 +++--- drivers/misc/eeprom/eeprom_93xx46.c | 2 +- drivers/misc/fsa9480.c | 2 +- drivers/misc/hpilo.c | 4 ++-- drivers/misc/ibmasm/module.c | 2 +- drivers/misc/ioc4.c | 6 +++--- drivers/misc/isl29003.c | 2 +- drivers/misc/lis3lv02d/lis3lv02d_i2c.c | 2 +- drivers/misc/lis3lv02d/lis3lv02d_spi.c | 2 +- drivers/misc/mei/main.c | 4 ++-- drivers/misc/pch_phub.c | 2 +- drivers/misc/phantom.c | 4 ++-- drivers/misc/pti.c | 2 +- drivers/misc/spear13xx_pcie_gadget.c | 2 +- drivers/misc/ti_dac7512.c | 2 +- drivers/misc/tsl2550.c | 2 +- 26 files changed, 36 insertions(+), 36 deletions(-) diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index 7254a98a89f..c7bc84df4bd 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -51,7 +51,7 @@ static const struct ad_dpot_bus_ops bops = { .write_r8d16 = write_r8d16, }; -static int __devinit ad_dpot_i2c_probe(struct i2c_client *client, +static int ad_dpot_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ad_dpot_bus_data bdata = { diff --git a/drivers/misc/ad525x_dpot-spi.c b/drivers/misc/ad525x_dpot-spi.c index 67e3073c2a6..240c59870e7 100644 --- a/drivers/misc/ad525x_dpot-spi.c +++ b/drivers/misc/ad525x_dpot-spi.c @@ -75,7 +75,7 @@ static const struct ad_dpot_bus_ops bops = { .write_r8d8 = write16, .write_r8d16 = write24, }; -static int __devinit ad_dpot_spi_probe(struct spi_device *spi) +static int ad_dpot_spi_probe(struct spi_device *spi) { struct ad_dpot_bus_data bdata = { .client = spi, diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index 6938f1be664..8f99e8e3f0a 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -641,7 +641,7 @@ static const struct attribute_group ad525x_group_commands = { .attrs = ad525x_attributes_commands, }; -__devinit int ad_dpot_add_files(struct device *dev, +int ad_dpot_add_files(struct device *dev, unsigned features, unsigned rdac) { int err = sysfs_create_file(&dev->kobj, @@ -685,7 +685,7 @@ inline void ad_dpot_remove_files(struct device *dev, } } -int __devinit ad_dpot_probe(struct device *dev, +int ad_dpot_probe(struct device *dev, struct ad_dpot_bus_data *bdata, unsigned long devid, const char *name) { diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c index f955d546f2d..b2aaf3f0445 100644 --- a/drivers/misc/apds990x.c +++ b/drivers/misc/apds990x.c @@ -1047,7 +1047,7 @@ static struct attribute_group apds990x_attribute_group[] = { {.attrs = sysfs_attrs_ctrl }, }; -static int __devinit apds990x_probe(struct i2c_client *client, +static int apds990x_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct apds990x_chip *chip; diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c index c4b65e26a76..003e8d9ab8a 100644 --- a/drivers/misc/bh1770glc.c +++ b/drivers/misc/bh1770glc.c @@ -1162,7 +1162,7 @@ static struct attribute_group bh1770_attribute_group = { .attrs = sysfs_attrs }; -static int __devinit bh1770_probe(struct i2c_client *client, +static int bh1770_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct bh1770_chip *chip; diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c index 54f6f39f990..3004904d23d 100644 --- a/drivers/misc/bh1780gli.c +++ b/drivers/misc/bh1780gli.c @@ -144,7 +144,7 @@ static const struct attribute_group bh1780_attr_group = { .attrs = bh1780_attributes, }; -static int __devinit bh1780_probe(struct i2c_client *client, +static int bh1780_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret; diff --git a/drivers/misc/bmp085-i2c.c b/drivers/misc/bmp085-i2c.c index 08cd7958c14..3abfcecf842 100644 --- a/drivers/misc/bmp085-i2c.c +++ b/drivers/misc/bmp085-i2c.c @@ -36,7 +36,7 @@ static int bmp085_i2c_detect(struct i2c_client *client, return bmp085_detect(&client->dev); } -static int __devinit bmp085_i2c_probe(struct i2c_client *client, +static int bmp085_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err; diff --git a/drivers/misc/bmp085-spi.c b/drivers/misc/bmp085-spi.c index ed34885a6b3..d6a52659cf2 100644 --- a/drivers/misc/bmp085-spi.c +++ b/drivers/misc/bmp085-spi.c @@ -22,7 +22,7 @@ #include #include "bmp085.h" -static int __devinit bmp085_spi_probe(struct spi_device *client) +static int bmp085_spi_probe(struct spi_device *client) { int err; struct regmap *regmap; diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c index 62e418293b7..849e2fed4da 100644 --- a/drivers/misc/bmp085.c +++ b/drivers/misc/bmp085.c @@ -420,7 +420,7 @@ struct regmap_config bmp085_regmap_config = { }; EXPORT_SYMBOL_GPL(bmp085_regmap_config); -__devinit int bmp085_probe(struct device *dev, struct regmap *regmap) +int bmp085_probe(struct device *dev, struct regmap *regmap) { struct bmp085_data *data; int err = 0; diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c index 489c468cf96..4fc9c37cd20 100644 --- a/drivers/misc/cb710/core.c +++ b/drivers/misc/cb710/core.c @@ -30,7 +30,7 @@ void cb710_pci_update_config_reg(struct pci_dev *pdev, EXPORT_SYMBOL_GPL(cb710_pci_update_config_reg); /* Some magic writes based on Windows driver init code */ -static int __devinit cb710_pci_configure(struct pci_dev *pdev) +static int cb710_pci_configure(struct pci_dev *pdev) { unsigned int devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0); struct pci_dev *pdev0; @@ -96,7 +96,7 @@ static void cb710_release_slot(struct device *dev) #endif } -static int __devinit cb710_register_slot(struct cb710_chip *chip, +static int cb710_register_slot(struct cb710_chip *chip, unsigned slot_mask, unsigned io_offset, const char *name) { int nr = chip->slots; @@ -201,7 +201,7 @@ static int cb710_resume(struct pci_dev *pdev) #endif /* CONFIG_PM */ -static int __devinit cb710_probe(struct pci_dev *pdev, +static int cb710_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct cb710_chip *chip; diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c index f505a40a8f4..9858f36dad8 100644 --- a/drivers/misc/cs5535-mfgpt.c +++ b/drivers/misc/cs5535-mfgpt.c @@ -246,7 +246,7 @@ EXPORT_SYMBOL_GPL(cs5535_mfgpt_write); * Jordan tells me that he and Mitch once played w/ it, but it's unclear * what the results of that were (and they experienced some instability). */ -static void __devinit reset_all_timers(void) +static void reset_all_timers(void) { uint32_t val, dummy; @@ -262,7 +262,7 @@ static void __devinit reset_all_timers(void) * In other cases (such as with VSAless OpenFirmware), the system firmware * leaves timers available for us to use. */ -static int __devinit scan_timers(struct cs5535_mfgpt_chip *mfgpt) +static int scan_timers(struct cs5535_mfgpt_chip *mfgpt) { struct cs5535_mfgpt_timer timer = { .chip = mfgpt }; unsigned long flags; @@ -289,7 +289,7 @@ static int __devinit scan_timers(struct cs5535_mfgpt_chip *mfgpt) return timers; } -static int __devinit cs5535_mfgpt_probe(struct platform_device *pdev) +static int cs5535_mfgpt_probe(struct platform_device *pdev) { struct resource *res; int err = -EIO, t; diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index 3dc14eafc5c..3dd9005fd0e 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -309,7 +309,7 @@ static ssize_t eeprom_93xx46_store_erase(struct device *dev, } static DEVICE_ATTR(erase, S_IWUSR, NULL, eeprom_93xx46_store_erase); -static int __devinit eeprom_93xx46_probe(struct spi_device *spi) +static int eeprom_93xx46_probe(struct spi_device *spi) { struct eeprom_93xx46_platform_data *pd; struct eeprom_93xx46_dev *edev; diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c index 38b52b90167..2baa52f07c7 100644 --- a/drivers/misc/fsa9480.c +++ b/drivers/misc/fsa9480.c @@ -407,7 +407,7 @@ static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw) return 0; } -static int __devinit fsa9480_probe(struct i2c_client *client, +static int fsa9480_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 47a9ce6b16f..621c7a37339 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -686,7 +686,7 @@ static void ilo_unmap_device(struct pci_dev *pdev, struct ilo_hwinfo *hw) pci_iounmap(pdev, hw->mmio_vaddr); } -static int __devinit ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw) +static int ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw) { int error = -ENOMEM; @@ -751,7 +751,7 @@ static void ilo_remove(struct pci_dev *pdev) ilo_hwdev[(minor / max_ccb)] = 0; } -static int __devinit ilo_probe(struct pci_dev *pdev, +static int ilo_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int devnum, minor, start, error = 0; diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c index f34a92fd679..380e4298ada 100644 --- a/drivers/misc/ibmasm/module.c +++ b/drivers/misc/ibmasm/module.c @@ -62,7 +62,7 @@ module_param(ibmasm_debug, int , S_IRUGO | S_IWUSR); MODULE_PARM_DESC(ibmasm_debug, " Set debug mode on or off"); -static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id) +static int ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { int result; struct service_processor *sp; diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index 794a7e002c8..3ef92dca547 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c @@ -139,7 +139,7 @@ ioc4_unregister_submodule(struct ioc4_submodule *is) * even though the following code utilizes external interrupt registers * to perform the speed calculation. */ -static void __devinit +static void ioc4_clock_calibrate(struct ioc4_driver_data *idd) { union ioc4_int_out int_out; @@ -231,7 +231,7 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd) * on the same PCI bus at slot number 3 to differentiate IO9 from IO10. * If neither is present, it's a PCI-RT. */ -static unsigned int __devinit +static unsigned int ioc4_variant(struct ioc4_driver_data *idd) { struct pci_dev *pdev = NULL; @@ -279,7 +279,7 @@ ioc4_load_modules(struct work_struct *work) static DECLARE_WORK(ioc4_load_modules_work, ioc4_load_modules); /* Adds a new instance of an IOC4 card */ -static int __devinit +static int ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) { struct ioc4_driver_data *idd; diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c index bef5307296f..9fd4c0c6e59 100644 --- a/drivers/misc/isl29003.c +++ b/drivers/misc/isl29003.c @@ -365,7 +365,7 @@ static int isl29003_init_client(struct i2c_client *client) * I2C layer */ -static int __devinit isl29003_probe(struct i2c_client *client, +static int isl29003_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index 403804c8612..66f0483efb0 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c @@ -114,7 +114,7 @@ static struct of_device_id lis3lv02d_i2c_dt_ids[] = { MODULE_DEVICE_TABLE(of, lis3lv02d_i2c_dt_ids); #endif -static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, +static int lis3lv02d_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; diff --git a/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c index 0e415c31e03..66a751d2ed5 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_spi.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_spi.c @@ -69,7 +69,7 @@ static struct of_device_id lis302dl_spi_dt_ids[] = { MODULE_DEVICE_TABLE(of, lis302dl_spi_dt_ids); #endif -static int __devinit lis302dl_spi_probe(struct spi_device *spi) +static int lis302dl_spi_probe(struct spi_device *spi) { int ret; diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index f432b8d7e19..4782c582ae3 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -743,7 +743,7 @@ static struct miscdevice mei_misc_device = { * * returns true if ME Interface is valid, false otherwise */ -static bool __devinit mei_quirk_probe(struct pci_dev *pdev, +static bool mei_quirk_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { u32 reg; @@ -765,7 +765,7 @@ static bool __devinit mei_quirk_probe(struct pci_dev *pdev, * * returns 0 on success, <0 on failure. */ -static int __devinit mei_probe(struct pci_dev *pdev, +static int mei_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct mei_device *dev; diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index 5581774393c..3896cff2579 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -666,7 +666,7 @@ static struct bin_attribute pch_bin_attr = { .write = pch_phub_bin_write, }; -static int __devinit pch_phub_probe(struct pci_dev *pdev, +static int pch_phub_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int retval; diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index 79038e9ced0..394150df2af 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c @@ -324,7 +324,7 @@ static irqreturn_t phantom_isr(int irq, void *data) * Init and deinit driver */ -static unsigned int __devinit phantom_get_free(void) +static unsigned int phantom_get_free(void) { unsigned int i; @@ -335,7 +335,7 @@ static unsigned int __devinit phantom_get_free(void) return i; } -static int __devinit phantom_probe(struct pci_dev *pdev, +static int phantom_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) { struct phantom_device *pht; diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index 3c5d74638ea..e1a898e97f7 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -796,7 +796,7 @@ static const struct tty_port_operations tty_port_ops = { * 0 for success * otherwise, error */ -static int __devinit pti_pci_probe(struct pci_dev *pdev, +static int pti_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned int a; diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c index 123ed98eec3..7850320462f 100644 --- a/drivers/misc/spear13xx_pcie_gadget.c +++ b/drivers/misc/spear13xx_pcie_gadget.c @@ -711,7 +711,7 @@ static void spear13xx_pcie_device_init(struct spear_pcie_gadget_config *config) spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1); } -static int __devinit spear_pcie_gadget_probe(struct platform_device *pdev) +static int spear_pcie_gadget_probe(struct platform_device *pdev) { struct resource *res0, *res1; unsigned int status = 0; diff --git a/drivers/misc/ti_dac7512.c b/drivers/misc/ti_dac7512.c index 85989ca7ad2..1222f86dfda 100644 --- a/drivers/misc/ti_dac7512.c +++ b/drivers/misc/ti_dac7512.c @@ -54,7 +54,7 @@ static const struct attribute_group dac7512_attr_group = { .attrs = dac7512_attributes, }; -static int __devinit dac7512_probe(struct spi_device *spi) +static int dac7512_probe(struct spi_device *spi) { int ret; diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c index 09ffb0b705f..18bce70b30f 100644 --- a/drivers/misc/tsl2550.c +++ b/drivers/misc/tsl2550.c @@ -347,7 +347,7 @@ static int tsl2550_init_client(struct i2c_client *client) */ static struct i2c_driver tsl2550_driver; -static int __devinit tsl2550_probe(struct i2c_client *client, +static int tsl2550_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); -- cgit v1.2.3 From 2c68506412e96d0e306be6057e824478a2deccbd Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:24:38 -0500 Subject: misc: remove use of __devinitdata CONFIG_HOTPLUG is going away as an option so __devinitdata is no longer needed. Signed-off-by: Bill Pemberton Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/misc/phantom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index 394150df2af..035776342a4 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c @@ -487,7 +487,7 @@ static int phantom_resume(struct pci_dev *pdev) #define phantom_resume NULL #endif -static struct pci_device_id phantom_pci_tbl[] __devinitdata = { +static struct pci_device_id phantom_pci_tbl[] = { { .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_9050, .subvendor = PCI_VENDOR_ID_PLX, .subdevice = PCI_DEVICE_ID_PLX_9050, .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 }, -- cgit v1.2.3 From b328bfec519875851c4b3d95cd22371aad0a657e Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:25:10 -0500 Subject: misc: remove use of __devinitconst CONFIG_HOTPLUG is going away as an option so __devinitconst is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/misc/pti.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index e1a898e97f7..37d4b5ef9dc 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -76,7 +76,7 @@ struct pti_dev { */ static DEFINE_MUTEX(alloclock); -static const struct pci_device_id pci_ids[] __devinitconst = { +static const struct pci_device_id pci_ids[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)}, {0} }; -- cgit v1.2.3 From 486a5c28c2e7d6a80c393ac7d612b77d80447b84 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:26:02 -0500 Subject: misc: remove use of __devexit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Cc: "Michał Mirosław" Cc: Wolfram Sang Cc: Eric Piel Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ad525x_dpot-i2c.c | 2 +- drivers/misc/ad525x_dpot-spi.c | 2 +- drivers/misc/apds9802als.c | 2 +- drivers/misc/apds990x.c | 2 +- drivers/misc/atmel-ssc.c | 2 +- drivers/misc/bh1770glc.c | 2 +- drivers/misc/bh1780gli.c | 2 +- drivers/misc/cb710/core.c | 2 +- drivers/misc/eeprom/at24.c | 2 +- drivers/misc/eeprom/at25.c | 2 +- drivers/misc/eeprom/eeprom_93xx46.c | 2 +- drivers/misc/fsa9480.c | 2 +- drivers/misc/ibmasm/module.c | 2 +- drivers/misc/ioc4.c | 2 +- drivers/misc/isl29003.c | 2 +- drivers/misc/lis3lv02d/lis3lv02d_i2c.c | 2 +- drivers/misc/lis3lv02d/lis3lv02d_spi.c | 2 +- drivers/misc/mei/main.c | 2 +- drivers/misc/pch_phub.c | 2 +- drivers/misc/phantom.c | 2 +- drivers/misc/pti.c | 2 +- drivers/misc/spear13xx_pcie_gadget.c | 2 +- drivers/misc/ti_dac7512.c | 2 +- drivers/misc/tsl2550.c | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index c7bc84df4bd..705b881e186 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -68,7 +68,7 @@ static int ad_dpot_i2c_probe(struct i2c_client *client, return ad_dpot_probe(&client->dev, &bdata, id->driver_data, id->name); } -static int __devexit ad_dpot_i2c_remove(struct i2c_client *client) +static int ad_dpot_i2c_remove(struct i2c_client *client) { return ad_dpot_remove(&client->dev); } diff --git a/drivers/misc/ad525x_dpot-spi.c b/drivers/misc/ad525x_dpot-spi.c index 240c59870e7..9da04ede04f 100644 --- a/drivers/misc/ad525x_dpot-spi.c +++ b/drivers/misc/ad525x_dpot-spi.c @@ -87,7 +87,7 @@ static int ad_dpot_spi_probe(struct spi_device *spi) spi_get_device_id(spi)->name); } -static int __devexit ad_dpot_spi_remove(struct spi_device *spi) +static int ad_dpot_spi_remove(struct spi_device *spi) { return ad_dpot_remove(&spi->dev); } diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index 0132d15a995..d648b089302 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c @@ -254,7 +254,7 @@ als_error1: return res; } -static int __devexit apds9802als_remove(struct i2c_client *client) +static int apds9802als_remove(struct i2c_client *client) { struct als_data *data = i2c_get_clientdata(client); diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c index b2aaf3f0445..0e67f8263cd 100644 --- a/drivers/misc/apds990x.c +++ b/drivers/misc/apds990x.c @@ -1181,7 +1181,7 @@ fail1: return err; } -static int __devexit apds990x_remove(struct i2c_client *client) +static int apds990x_remove(struct i2c_client *client) { struct apds990x_chip *chip = i2c_get_clientdata(client); diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c index 191c2ce9d5e..c58f9abcb35 100644 --- a/drivers/misc/atmel-ssc.c +++ b/drivers/misc/atmel-ssc.c @@ -137,7 +137,7 @@ out: return retval; } -static int __devexit ssc_remove(struct platform_device *pdev) +static int ssc_remove(struct platform_device *pdev) { struct ssc_device *ssc = platform_get_drvdata(pdev); diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c index 003e8d9ab8a..2ed8fc3be7e 100644 --- a/drivers/misc/bh1770glc.c +++ b/drivers/misc/bh1770glc.c @@ -1285,7 +1285,7 @@ fail1: return err; } -static int __devexit bh1770_remove(struct i2c_client *client) +static int bh1770_remove(struct i2c_client *client) { struct bh1770_chip *chip = i2c_get_clientdata(client); diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c index 3004904d23d..cf03d0abf33 100644 --- a/drivers/misc/bh1780gli.c +++ b/drivers/misc/bh1780gli.c @@ -185,7 +185,7 @@ err_op_failed: return ret; } -static int __devexit bh1780_remove(struct i2c_client *client) +static int bh1780_remove(struct i2c_client *client) { struct bh1780_data *ddata; diff --git a/drivers/misc/cb710/core.c b/drivers/misc/cb710/core.c index 4fc9c37cd20..2e50f811ff5 100644 --- a/drivers/misc/cb710/core.c +++ b/drivers/misc/cb710/core.c @@ -305,7 +305,7 @@ unreg_mmc: return err; } -static void __devexit cb710_remove_one(struct pci_dev *pdev) +static void cb710_remove_one(struct pci_dev *pdev) { struct cb710_chip *chip = pci_get_drvdata(pdev); unsigned long flags; diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 3c36997bdac..2baeec56edf 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -656,7 +656,7 @@ err_out: return err; } -static int __devexit at24_remove(struct i2c_client *client) +static int at24_remove(struct i2c_client *client) { struct at24_data *at24; int i; diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index fcb237e9bb1..b08cf8a0878 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -459,7 +459,7 @@ fail: return err; } -static int __devexit at25_remove(struct spi_device *spi) +static int at25_remove(struct spi_device *spi) { struct at25_data *at25; diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index 3dd9005fd0e..a6b5d5e7348 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -370,7 +370,7 @@ fail: return err; } -static int __devexit eeprom_93xx46_remove(struct spi_device *spi) +static int eeprom_93xx46_remove(struct spi_device *spi) { struct eeprom_93xx46_dev *edev = dev_get_drvdata(&spi->dev); diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c index 2baa52f07c7..e8cbb1c59f4 100644 --- a/drivers/misc/fsa9480.c +++ b/drivers/misc/fsa9480.c @@ -462,7 +462,7 @@ fail1: return ret; } -static int __devexit fsa9480_remove(struct i2c_client *client) +static int fsa9480_remove(struct i2c_client *client) { struct fsa9480_usbsw *usbsw = i2c_get_clientdata(client); if (client->irq) diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c index 380e4298ada..0346d87c5fe 100644 --- a/drivers/misc/ibmasm/module.c +++ b/drivers/misc/ibmasm/module.c @@ -163,7 +163,7 @@ error_resources: return result; } -static void __devexit ibmasm_remove_one(struct pci_dev *pdev) +static void ibmasm_remove_one(struct pci_dev *pdev) { struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev); diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index 3ef92dca547..06f6ad29cef 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c @@ -415,7 +415,7 @@ out: } /* Removes a particular instance of an IOC4 card. */ -static void __devexit +static void ioc4_remove(struct pci_dev *pdev) { struct ioc4_submodule *is; diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c index 9fd4c0c6e59..29b306c6bdb 100644 --- a/drivers/misc/isl29003.c +++ b/drivers/misc/isl29003.c @@ -401,7 +401,7 @@ exit_kfree: return err; } -static int __devexit isl29003_remove(struct i2c_client *client) +static int isl29003_remove(struct i2c_client *client) { sysfs_remove_group(&client->dev.kobj, &isl29003_attr_group); isl29003_set_power_state(client, 0); diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index 66f0483efb0..7c97550240f 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c @@ -191,7 +191,7 @@ fail: return ret; } -static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client) +static int lis3lv02d_i2c_remove(struct i2c_client *client) { struct lis3lv02d *lis3 = i2c_get_clientdata(client); struct lis3lv02d_platform_data *pdata = client->dev.platform_data; diff --git a/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c index 66a751d2ed5..9aa2bd2a71a 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_spi.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_spi.c @@ -100,7 +100,7 @@ static int lis302dl_spi_probe(struct spi_device *spi) return lis3lv02d_init_device(&lis3_dev); } -static int __devexit lis302dl_spi_remove(struct spi_device *spi) +static int lis302dl_spi_remove(struct spi_device *spi) { struct lis3lv02d *lis3 = spi_get_drvdata(spi); lis3lv02d_joystick_disable(lis3); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 4782c582ae3..43fb52ff98a 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -882,7 +882,7 @@ end: * mei_remove is called by the PCI subsystem to alert the driver * that it should release a PCI device. */ -static void __devexit mei_remove(struct pci_dev *pdev) +static void mei_remove(struct pci_dev *pdev) { struct mei_device *dev; diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index 3896cff2579..931e635aa49 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -819,7 +819,7 @@ err_pci_enable_dev: return ret; } -static void __devexit pch_phub_remove(struct pci_dev *pdev) +static void pch_phub_remove(struct pci_dev *pdev) { struct pch_phub_reg *chip = pci_get_drvdata(pdev); diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index 035776342a4..68b7c773d2c 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c @@ -435,7 +435,7 @@ err: return retval; } -static void __devexit phantom_remove(struct pci_dev *pdev) +static void phantom_remove(struct pci_dev *pdev) { struct phantom_device *pht = pci_get_drvdata(pdev); unsigned int minor = MINOR(pht->cdev.dev); diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index 37d4b5ef9dc..7003031c918 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -879,7 +879,7 @@ err: * PCI bus. * @pdev: variable containing pci info of PTI. */ -static void __devexit pti_pci_remove(struct pci_dev *pdev) +static void pti_pci_remove(struct pci_dev *pdev) { struct pti_dev *drv_data = pci_get_drvdata(pdev); diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c index 7850320462f..7deb25dc86a 100644 --- a/drivers/misc/spear13xx_pcie_gadget.c +++ b/drivers/misc/spear13xx_pcie_gadget.c @@ -853,7 +853,7 @@ err_rel_res0: return status; } -static int __devexit spear_pcie_gadget_remove(struct platform_device *pdev) +static int spear_pcie_gadget_remove(struct platform_device *pdev) { struct resource *res0, *res1; static struct pcie_gadget_target *target; diff --git a/drivers/misc/ti_dac7512.c b/drivers/misc/ti_dac7512.c index 1222f86dfda..1d86407189e 100644 --- a/drivers/misc/ti_dac7512.c +++ b/drivers/misc/ti_dac7512.c @@ -67,7 +67,7 @@ static int dac7512_probe(struct spi_device *spi) return sysfs_create_group(&spi->dev.kobj, &dac7512_attr_group); } -static int __devexit dac7512_remove(struct spi_device *spi) +static int dac7512_remove(struct spi_device *spi) { sysfs_remove_group(&spi->dev.kobj, &dac7512_attr_group); return 0; diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c index 18bce70b30f..1e7bc0eb081 100644 --- a/drivers/misc/tsl2550.c +++ b/drivers/misc/tsl2550.c @@ -405,7 +405,7 @@ exit: return err; } -static int __devexit tsl2550_remove(struct i2c_client *client) +static int tsl2550_remove(struct i2c_client *client) { sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group); -- cgit v1.2.3 From 4dde2d2f3a3b09d282eb399d24fb261ae50425ef Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:19:58 -0500 Subject: char: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Cc: Mattia Dongili Cc: platform-driver-x86@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/char/sonypi.c | 2 +- drivers/char/tb0219.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 9b4f0116ff2..34f0db34fcd 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1491,7 +1491,7 @@ static struct platform_driver sonypi_driver = { .pm = SONYPI_PM, }, .probe = sonypi_probe, - .remove = __devexit_p(sonypi_remove), + .remove = sonypi_remove, .shutdown = sonypi_shutdown, }; diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index ad264185eb1..6bfe2af844e 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c @@ -334,7 +334,7 @@ static struct platform_device *tb0219_platform_device; static struct platform_driver tb0219_device_driver = { .probe = tb0219_probe, - .remove = __devexit_p(tb0219_remove), + .remove = tb0219_remove, .driver = { .name = "TB0219", .owner = THIS_MODULE, -- cgit v1.2.3 From 2223cbec33ef3a26e7678be89de75cb60c4c257b Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:22:51 -0500 Subject: char: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Cc: Geoff Levand Cc: Mattia Dongili Cc: Amit Shah Cc: openipmi-developer@lists.sourceforge.net Cc: linuxppc-dev@lists.ozlabs.org Cc: cbe-oss-dev@lists.ozlabs.org Cc: platform-driver-x86@vger.kernel.org Cc: virtualization@lists.linux-foundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/char/ipmi/ipmi_si_intf.c | 24 ++++++++++++------------ drivers/char/ps3flash.c | 2 +- drivers/char/sonypi.c | 10 +++++----- drivers/char/tb0219.c | 2 +- drivers/char/virtio_console.c | 2 +- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 6 +++--- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 32a6c7e256b..1a465a4974f 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -1836,7 +1836,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) return rv; } -static int __devinit hardcode_find_bmc(void) +static int hardcode_find_bmc(void) { int ret = -ENODEV; int i; @@ -2023,7 +2023,7 @@ struct SPMITable { s8 spmi_id[1]; /* A '\0' terminated array starts here. */ }; -static int __devinit try_init_spmi(struct SPMITable *spmi) +static int try_init_spmi(struct SPMITable *spmi) { struct smi_info *info; @@ -2106,7 +2106,7 @@ static int __devinit try_init_spmi(struct SPMITable *spmi) return 0; } -static void __devinit spmi_find_bmc(void) +static void spmi_find_bmc(void) { acpi_status status; struct SPMITable *spmi; @@ -2128,7 +2128,7 @@ static void __devinit spmi_find_bmc(void) } } -static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, +static int ipmi_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { struct acpi_device *acpi_dev; @@ -2258,7 +2258,7 @@ struct dmi_ipmi_data { u8 slave_addr; }; -static int __devinit decode_dmi(const struct dmi_header *dm, +static int decode_dmi(const struct dmi_header *dm, struct dmi_ipmi_data *dmi) { const u8 *data = (const u8 *)dm; @@ -2320,7 +2320,7 @@ static int __devinit decode_dmi(const struct dmi_header *dm, return 0; } -static void __devinit try_init_dmi(struct dmi_ipmi_data *ipmi_data) +static void try_init_dmi(struct dmi_ipmi_data *ipmi_data) { struct smi_info *info; @@ -2388,7 +2388,7 @@ static void __devinit try_init_dmi(struct dmi_ipmi_data *ipmi_data) kfree(info); } -static void __devinit dmi_find_bmc(void) +static void dmi_find_bmc(void) { const struct dmi_device *dev = NULL; struct dmi_ipmi_data data; @@ -2424,7 +2424,7 @@ static void ipmi_pci_cleanup(struct smi_info *info) pci_disable_device(pdev); } -static int __devinit ipmi_pci_probe_regspacing(struct smi_info *info) +static int ipmi_pci_probe_regspacing(struct smi_info *info) { if (info->si_type == SI_KCS) { unsigned char status; @@ -2456,7 +2456,7 @@ static int __devinit ipmi_pci_probe_regspacing(struct smi_info *info) return DEFAULT_REGSPACING; } -static int __devinit ipmi_pci_probe(struct pci_dev *pdev, +static int ipmi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int rv; @@ -2551,7 +2551,7 @@ static struct pci_driver ipmi_pci_driver = { #endif /* CONFIG_PCI */ static struct of_device_id ipmi_match[]; -static int __devinit ipmi_probe(struct platform_device *dev) +static int ipmi_probe(struct platform_device *dev) { #ifdef CONFIG_OF const struct of_device_id *match; @@ -3059,7 +3059,7 @@ static __devinitdata struct ipmi_default_vals { .port = 0 } }; -static void __devinit default_find_bmc(void) +static void default_find_bmc(void) { struct smi_info *info; int i; @@ -3359,7 +3359,7 @@ static int try_smi_init(struct smi_info *new_smi) return rv; } -static int __devinit init_ipmi_si(void) +static int init_ipmi_si(void) { int i; char *str; diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c index 6abdde4da2b..588063ac951 100644 --- a/drivers/char/ps3flash.c +++ b/drivers/char/ps3flash.c @@ -363,7 +363,7 @@ static struct miscdevice ps3flash_misc = { .fops = &ps3flash_fops, }; -static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev) +static int ps3flash_probe(struct ps3_system_bus_device *_dev) { struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); struct ps3flash_private *priv; diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 34f0db34fcd..861efa48c69 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1164,7 +1164,7 @@ static struct acpi_driver sonypi_acpi_driver = { }; #endif -static int __devinit sonypi_create_input_devices(struct platform_device *pdev) +static int sonypi_create_input_devices(struct platform_device *pdev) { struct input_dev *jog_dev; struct input_dev *key_dev; @@ -1225,7 +1225,7 @@ static int __devinit sonypi_create_input_devices(struct platform_device *pdev) return error; } -static int __devinit sonypi_setup_ioports(struct sonypi_device *dev, +static int sonypi_setup_ioports(struct sonypi_device *dev, const struct sonypi_ioport_list *ioport_list) { /* try to detect if sony-laptop is being used and thus @@ -1265,7 +1265,7 @@ static int __devinit sonypi_setup_ioports(struct sonypi_device *dev, return -EBUSY; } -static int __devinit sonypi_setup_irq(struct sonypi_device *dev, +static int sonypi_setup_irq(struct sonypi_device *dev, const struct sonypi_irq_list *irq_list) { while (irq_list->irq) { @@ -1282,7 +1282,7 @@ static int __devinit sonypi_setup_irq(struct sonypi_device *dev, return -EBUSY; } -static void __devinit sonypi_display_info(void) +static void sonypi_display_info(void) { printk(KERN_INFO "sonypi: detected type%d model, " "verbose = %d, fnkeyinit = %s, camera = %s, " @@ -1304,7 +1304,7 @@ static void __devinit sonypi_display_info(void) sonypi_misc_device.minor); } -static int __devinit sonypi_probe(struct platform_device *dev) +static int sonypi_probe(struct platform_device *dev) { const struct sonypi_ioport_list *ioport_list; const struct sonypi_irq_list *irq_list; diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index 6bfe2af844e..76e3aea27ff 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c @@ -284,7 +284,7 @@ static void tb0219_pci_irq_init(void) vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, IRQ_LEVEL_LOW); } -static int __devinit tb0219_probe(struct platform_device *dev) +static int tb0219_probe(struct platform_device *dev) { int retval; diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 8ab9c3d4bf1..90493d4ead1 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1846,7 +1846,7 @@ static void remove_controlq_data(struct ports_device *portdev) * config space to see how many ports the host has spawned. We * initialize each port found. */ -static int __devinit virtcons_probe(struct virtio_device *vdev) +static int virtcons_probe(struct virtio_device *vdev) { struct ports_device *portdev; int err; diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 2c5d15beea3..547ed74e3d1 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -595,7 +595,7 @@ static const struct file_operations hwicap_fops = { .llseek = noop_llseek, }; -static int __devinit hwicap_setup(struct device *dev, int id, +static int hwicap_setup(struct device *dev, int id, const struct resource *regs_res, const struct hwicap_driver_config *config, const struct config_registers *config_regs) @@ -740,7 +740,7 @@ static int __devexit hwicap_remove(struct device *dev) } #ifdef CONFIG_OF -static int __devinit hwicap_of_probe(struct platform_device *op, +static int hwicap_of_probe(struct platform_device *op, const struct hwicap_driver_config *config) { struct resource res; @@ -786,7 +786,7 @@ static inline int hwicap_of_probe(struct platform_device *op, #endif /* CONFIG_OF */ static const struct of_device_id __devinitconst hwicap_of_match[]; -static int __devinit hwicap_drv_probe(struct platform_device *pdev) +static int hwicap_drv_probe(struct platform_device *pdev) { const struct of_device_id *match; struct resource *res; -- cgit v1.2.3 From 0bbed20e0518f6b9d46b7fe2bd044e3398a6dc40 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:24:36 -0500 Subject: char: remove use of __devinitdata CONFIG_HOTPLUG is going away as an option so __devinitdata is no longer needed. Signed-off-by: Bill Pemberton Cc: David Airlie Cc: Kent Yoder Cc: Rajiv Andrade Cc: Marcel Selhorst Cc: Sirrix AG Cc: openipmi-developer@lists.sourceforge.net Cc: tpmdd-devel@lists.sourceforge.net Signed-off-by: Greg Kroah-Hartman --- drivers/char/agp/ali-agp.c | 2 +- drivers/char/agp/amd-k7-agp.c | 2 +- drivers/char/agp/ati-agp.c | 2 +- drivers/char/agp/sis-agp.c | 6 +++--- drivers/char/agp/uninorth-agp.c | 2 +- drivers/char/agp/via-agp.c | 2 +- drivers/char/hw_random/n2-drv.c | 2 +- drivers/char/ipmi/ipmi_si_intf.c | 2 +- drivers/char/tpm/tpm_ibmvtpm.c | 2 +- drivers/char/tpm/tpm_tis.c | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index fd793519ea2..9c022df134a 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c @@ -249,7 +249,7 @@ static const struct agp_bridge_driver ali_m1541_bridge = { }; -static struct agp_device_ids ali_agp_device_ids[] __devinitdata = +static struct agp_device_ids ali_agp_device_ids[] = { { .device_id = PCI_DEVICE_ID_AL_M1541, diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index f7e88787af9..3c7a2653f16 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -388,7 +388,7 @@ static const struct agp_bridge_driver amd_irongate_driver = { .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; -static struct agp_device_ids amd_agp_device_ids[] __devinitdata = +static struct agp_device_ids amd_agp_device_ids[] = { { .device_id = PCI_DEVICE_ID_AMD_FE_GATE_7006, diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index dc30e224349..d1c4c234071 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -445,7 +445,7 @@ static const struct agp_bridge_driver ati_generic_bridge = { }; -static struct agp_device_ids ati_agp_device_ids[] __devinitdata = +static struct agp_device_ids ati_agp_device_ids[] = { { .device_id = PCI_DEVICE_ID_ATI_RS100, diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index 08704ae5395..c93c9e5ee2c 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c @@ -17,8 +17,8 @@ #define PCI_DEVICE_ID_SI_662 0x0662 #define PCI_DEVICE_ID_SI_671 0x0671 -static bool __devinitdata agp_sis_force_delay = 0; -static int __devinitdata agp_sis_agp_spec = -1; +static bool agp_sis_force_delay = 0; +static int agp_sis_agp_spec = -1; static int sis_fetch_size(void) { @@ -148,7 +148,7 @@ static struct agp_bridge_driver sis_driver = { }; // chipsets that require the 'delay hack' -static int sis_broken_chipsets[] __devinitdata = { +static int sis_broken_chipsets[] = { PCI_DEVICE_ID_SI_648, PCI_DEVICE_ID_SI_746, 0 // terminator diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index a32c492baf5..af02da4da9e 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -557,7 +557,7 @@ const struct agp_bridge_driver u3_agp_driver = { .needs_scratch_page = true, }; -static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = { +static struct agp_device_ids uninorth_agp_device_ids[] = { { .device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP, .chipset_name = "UniNorth", diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 8bc38493740..97706834bae 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c @@ -224,7 +224,7 @@ static const struct agp_bridge_driver via_driver = { .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; -static struct agp_device_ids via_agp_device_ids[] __devinitdata = +static struct agp_device_ids via_agp_device_ids[] = { { .device_id = PCI_DEVICE_ID_VIA_82C597_0, diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index ebd48f0135d..fd57d8a9faf 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -25,7 +25,7 @@ #define DRV_MODULE_VERSION "0.2" #define DRV_MODULE_RELDATE "July 27, 2011" -static char version[] __devinitdata = +static char version[] = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 1a465a4974f..e55a7ad8ef1 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -3047,7 +3047,7 @@ static inline void wait_for_timer_and_thread(struct smi_info *smi_info) } } -static __devinitdata struct ipmi_default_vals +static struct ipmi_default_vals { int type; int port; diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index efc4ab36a9d..3b032dbb9de 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -32,7 +32,7 @@ static const char tpm_ibmvtpm_driver_name[] = "tpm_ibmvtpm"; -static struct vio_device_id tpm_ibmvtpm_device_table[] __devinitdata = { +static struct vio_device_id tpm_ibmvtpm_device_table[] = { { "IBM,vtpm", "IBM,vtpm"}, { "", "" } }; diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 6bdf2671254..25fee274bdb 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -769,7 +769,7 @@ static int tpm_tis_pnp_resume(struct pnp_dev *dev) return ret; } -static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { +static struct pnp_device_id tpm_pnp_tbl[] = { {"PNP0C31", 0}, /* TPM */ {"ATM1200", 0}, /* Atmel */ {"IFX0102", 0}, /* Infineon */ -- cgit v1.2.3 From aa89ed9e369b345ef3737c56e7c8934af2df4aa6 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:25:02 -0500 Subject: char: remove use of __devinitconst CONFIG_HOTPLUG is going away as an option so __devinitconst is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/char/mbcs.c | 2 +- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c index f74e892711d..e5d3e3f7a49 100644 --- a/drivers/char/mbcs.c +++ b/drivers/char/mbcs.c @@ -799,7 +799,7 @@ static int mbcs_remove(struct cx_dev *dev) return 0; } -static const struct cx_device_id __devinitconst mbcs_id_table[] = { +static const struct cx_device_id mbcs_id_table[] = { { .part_num = MBCS_PART_NUM, .mfg_num = MBCS_MFG_NUM, diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 547ed74e3d1..d10085f9a0d 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -785,7 +785,7 @@ static inline int hwicap_of_probe(struct platform_device *op, } #endif /* CONFIG_OF */ -static const struct of_device_id __devinitconst hwicap_of_match[]; +static const struct of_device_id hwicap_of_match[]; static int hwicap_drv_probe(struct platform_device *pdev) { const struct of_device_id *match; @@ -829,7 +829,7 @@ static int __devexit hwicap_drv_remove(struct platform_device *pdev) #ifdef CONFIG_OF /* Match table for device tree binding */ -static const struct of_device_id __devinitconst hwicap_of_match[] = { +static const struct of_device_id hwicap_of_match[] = { { .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config}, { .compatible = "xlnx,xps-hwicap-1.00.a", .data = &fifo_icap_config}, {}, -- cgit v1.2.3 From 39af33fc458543fd6daaf154e109eba22ab89a8f Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:26:26 -0500 Subject: char: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Cc: David Airlie Cc: Olof Johansson Cc: Mattia Dongili Cc: Kent Yoder Cc: Rajiv Andrade Cc: Marcel Selhorst Cc: Sirrix AG Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-arm-kernel@lists.infradead.org Cc: openipmi-developer@lists.sourceforge.net Cc: platform-driver-x86@vger.kernel.org Cc: tpmdd-devel@lists.sourceforge.net Signed-off-by: Greg Kroah-Hartman --- drivers/char/agp/ali-agp.c | 2 +- drivers/char/agp/amd-k7-agp.c | 2 +- drivers/char/agp/amd64-agp.c | 2 +- drivers/char/agp/ati-agp.c | 2 +- drivers/char/agp/efficeon-agp.c | 2 +- drivers/char/agp/i460-agp.c | 2 +- drivers/char/agp/intel-agp.c | 2 +- drivers/char/agp/nvidia-agp.c | 2 +- drivers/char/agp/sgi-agp.c | 2 +- drivers/char/agp/sis-agp.c | 2 +- drivers/char/agp/sworks-agp.c | 2 +- drivers/char/agp/uninorth-agp.c | 2 +- drivers/char/agp/via-agp.c | 2 +- drivers/char/hw_random/atmel-rng.c | 2 +- drivers/char/hw_random/bcm63xx-rng.c | 2 +- drivers/char/hw_random/exynos-rng.c | 2 +- drivers/char/hw_random/n2-drv.c | 2 +- drivers/char/hw_random/pasemi-rng.c | 2 +- drivers/char/hw_random/picoxcell-rng.c | 2 +- drivers/char/hw_random/ppc4xx-rng.c | 2 +- drivers/char/hw_random/timeriomem-rng.c | 2 +- drivers/char/hw_random/virtio-rng.c | 2 +- drivers/char/ipmi/ipmi_si_intf.c | 6 +++--- drivers/char/sonypi.c | 2 +- drivers/char/tb0219.c | 2 +- drivers/char/tpm/tpm_i2c_infineon.c | 2 +- drivers/char/tpm/tpm_ibmvtpm.c | 2 +- drivers/char/tpm/tpm_infineon.c | 2 +- drivers/char/tpm/tpm_tis.c | 2 +- drivers/char/xilinx_hwicap/xilinx_hwicap.c | 4 ++-- 30 files changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 9c022df134a..478493543b3 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c @@ -374,7 +374,7 @@ found: return agp_add_bridge(bridge); } -static void __devexit agp_ali_remove(struct pci_dev *pdev) +static void agp_ali_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index 3c7a2653f16..1b2101160e9 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -480,7 +480,7 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_amdk7_remove(struct pci_dev *pdev) +static void agp_amdk7_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 444f8b6ab41..061d46209b1 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -579,7 +579,7 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev, return 0; } -static void __devexit agp_amd64_remove(struct pci_dev *pdev) +static void agp_amd64_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index d1c4c234071..ed0433576e7 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -533,7 +533,7 @@ found: return agp_add_bridge(bridge); } -static void __devexit agp_ati_remove(struct pci_dev *pdev) +static void agp_ati_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index d607f53d8af..55f3e33a309 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c @@ -407,7 +407,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_efficeon_remove(struct pci_dev *pdev) +static void agp_efficeon_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index 75b763cb3ea..d328b662e50 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c @@ -611,7 +611,7 @@ static int __devinit agp_intel_i460_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_intel_i460_remove(struct pci_dev *pdev) +static void agp_intel_i460_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index b130df0a195..f3a8f52b5a0 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -819,7 +819,7 @@ found_gmch: return err; } -static void __devexit agp_intel_remove(struct pci_dev *pdev) +static void agp_intel_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index b9734a97818..66e0868000f 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c @@ -388,7 +388,7 @@ static int __devinit agp_nvidia_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_nvidia_remove(struct pci_dev *pdev) +static void agp_nvidia_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index 3a5af2f9b01..a18791d7718 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c @@ -327,7 +327,7 @@ static int __devinit agp_sgi_init(void) return 0; } -static void __devexit agp_sgi_cleanup(void) +static void agp_sgi_cleanup(void) { kfree(sgi_tioca_agp_bridges); sgi_tioca_agp_bridges = NULL; diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index c93c9e5ee2c..93d1d31f9d0 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c @@ -211,7 +211,7 @@ static int __devinit agp_sis_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_sis_remove(struct pci_dev *pdev) +static void agp_sis_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index f02f9b07fd4..26020fb8d7a 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c @@ -518,7 +518,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_serverworks_remove(struct pci_dev *pdev) +static void agp_serverworks_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index af02da4da9e..011967ad3ee 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -663,7 +663,7 @@ static int __devinit agp_uninorth_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_uninorth_remove(struct pci_dev *pdev) +static void agp_uninorth_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 97706834bae..6818595bb86 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c @@ -485,7 +485,7 @@ static int __devinit agp_via_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_via_remove(struct pci_dev *pdev) +static void agp_via_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index 731c9046cf7..5a4a6e70478 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c @@ -98,7 +98,7 @@ err_enable: return ret; } -static int __devexit atmel_trng_remove(struct platform_device *pdev) +static int atmel_trng_remove(struct platform_device *pdev) { struct atmel_trng *trng = platform_get_drvdata(pdev); diff --git a/drivers/char/hw_random/bcm63xx-rng.c b/drivers/char/hw_random/bcm63xx-rng.c index aec6a4277ca..ae95bcb18d4 100644 --- a/drivers/char/hw_random/bcm63xx-rng.c +++ b/drivers/char/hw_random/bcm63xx-rng.c @@ -145,7 +145,7 @@ out: return ret; } -static int __devexit bcm63xx_rng_remove(struct platform_device *pdev) +static int bcm63xx_rng_remove(struct platform_device *pdev) { struct hwrng *rng = platform_get_drvdata(pdev); struct bcm63xx_rng_priv *priv = to_rng_priv(rng); diff --git a/drivers/char/hw_random/exynos-rng.c b/drivers/char/hw_random/exynos-rng.c index 232ba9ce579..bdc852ea763 100644 --- a/drivers/char/hw_random/exynos-rng.c +++ b/drivers/char/hw_random/exynos-rng.c @@ -134,7 +134,7 @@ static int __devinit exynos_rng_probe(struct platform_device *pdev) return hwrng_register(&exynos_rng->rng); } -static int __devexit exynos_rng_remove(struct platform_device *pdev) +static int exynos_rng_remove(struct platform_device *pdev) { struct exynos_rng *exynos_rng = platform_get_drvdata(pdev); diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index fd57d8a9faf..d68a72a08b5 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -719,7 +719,7 @@ out: return err; } -static int __devexit n2rng_remove(struct platform_device *op) +static int n2rng_remove(struct platform_device *op) { struct n2rng *np = dev_get_drvdata(&op->dev); diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index 3a632673aed..a1f70407cc9 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -122,7 +122,7 @@ static int __devinit rng_probe(struct platform_device *ofdev) return err; } -static int __devexit rng_remove(struct platform_device *dev) +static int rng_remove(struct platform_device *dev) { void __iomem *rng_regs = (void __iomem *)pasemi_rng.priv; diff --git a/drivers/char/hw_random/picoxcell-rng.c b/drivers/char/hw_random/picoxcell-rng.c index 97bd891422c..d4b24c1dd48 100644 --- a/drivers/char/hw_random/picoxcell-rng.c +++ b/drivers/char/hw_random/picoxcell-rng.c @@ -151,7 +151,7 @@ err_enable: return ret; } -static int __devexit picoxcell_trng_remove(struct platform_device *pdev) +static int picoxcell_trng_remove(struct platform_device *pdev) { hwrng_unregister(&picoxcell_trng); clk_disable(rng_clk); diff --git a/drivers/char/hw_random/ppc4xx-rng.c b/drivers/char/hw_random/ppc4xx-rng.c index c51762c1303..af6506a69cd 100644 --- a/drivers/char/hw_random/ppc4xx-rng.c +++ b/drivers/char/hw_random/ppc4xx-rng.c @@ -111,7 +111,7 @@ static int __devinit ppc4xx_rng_probe(struct platform_device *dev) return err; } -static int __devexit ppc4xx_rng_remove(struct platform_device *dev) +static int ppc4xx_rng_remove(struct platform_device *dev) { void __iomem *rng_regs = (void __iomem *) ppc4xx_rng.priv; diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c index f1a1618db1f..3a1abc9417e 100644 --- a/drivers/char/hw_random/timeriomem-rng.c +++ b/drivers/char/hw_random/timeriomem-rng.c @@ -130,7 +130,7 @@ failed: return ret; } -static int __devexit timeriomem_rng_remove(struct platform_device *pdev) +static int timeriomem_rng_remove(struct platform_device *pdev) { del_timer_sync(&timeriomem_rng_timer); hwrng_unregister(&timeriomem_rng_ops); diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 5708299507d..621f595f1a9 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -119,7 +119,7 @@ static int virtrng_probe(struct virtio_device *vdev) return probe_common(vdev); } -static void __devexit virtrng_remove(struct virtio_device *vdev) +static void virtrng_remove(struct virtio_device *vdev) { remove_common(vdev); } diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index e55a7ad8ef1..20ab5b3a891 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2228,7 +2228,7 @@ err_free: return -EINVAL; } -static void __devexit ipmi_pnp_remove(struct pnp_dev *dev) +static void ipmi_pnp_remove(struct pnp_dev *dev) { struct smi_info *info = pnp_get_drvdata(dev); @@ -2529,7 +2529,7 @@ static int ipmi_pci_probe(struct pci_dev *pdev, return 0; } -static void __devexit ipmi_pci_remove(struct pci_dev *pdev) +static void ipmi_pci_remove(struct pci_dev *pdev) { struct smi_info *info = pci_get_drvdata(pdev); cleanup_one_si(info); @@ -2635,7 +2635,7 @@ static int ipmi_probe(struct platform_device *dev) return 0; } -static int __devexit ipmi_remove(struct platform_device *dev) +static int ipmi_remove(struct platform_device *dev) { #ifdef CONFIG_OF cleanup_one_si(dev_get_drvdata(&dev->dev)); diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 861efa48c69..d780295a147 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1428,7 +1428,7 @@ static int sonypi_probe(struct platform_device *dev) return error; } -static int __devexit sonypi_remove(struct platform_device *dev) +static int sonypi_remove(struct platform_device *dev) { sonypi_disable(); diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index 76e3aea27ff..34c63f85104 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c @@ -318,7 +318,7 @@ static int tb0219_probe(struct platform_device *dev) return 0; } -static int __devexit tb0219_remove(struct platform_device *dev) +static int tb0219_remove(struct platform_device *dev) { _machine_restart = old_machine_restart; diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index 5a831aec9d4..78983b77caf 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c @@ -656,7 +656,7 @@ static int __devinit tpm_tis_i2c_probe(struct i2c_client *client, return rc; } -static int __devexit tpm_tis_i2c_remove(struct i2c_client *client) +static int tpm_tis_i2c_remove(struct i2c_client *client) { struct tpm_chip *chip = tpm_dev.chip; release_locality(chip, chip->vendor.locality, 1); diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 3b032dbb9de..5a72f39d962 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -267,7 +267,7 @@ static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm) * Return value: * 0 */ -static int __devexit tpm_ibmvtpm_remove(struct vio_dev *vdev) +static int tpm_ibmvtpm_remove(struct vio_dev *vdev) { struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev); int rc = 0; diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 3251a44e8ce..4dd5f8acecd 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c @@ -594,7 +594,7 @@ err_last: return rc; } -static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) +static void tpm_inf_pnp_remove(struct pnp_dev *dev) { struct tpm_chip *chip = pnp_get_drvdata(dev); diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 25fee274bdb..a599cc267fc 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -783,7 +783,7 @@ static struct pnp_device_id tpm_pnp_tbl[] = { }; MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); -static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev) +static void tpm_tis_pnp_remove(struct pnp_dev *dev) { struct tpm_chip *chip = pnp_get_drvdata(dev); diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index d10085f9a0d..5224da5202d 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -717,7 +717,7 @@ static struct hwicap_driver_config fifo_icap_config = { .reset = fifo_icap_reset, }; -static int __devexit hwicap_remove(struct device *dev) +static int hwicap_remove(struct device *dev) { struct hwicap_drvdata *drvdata; @@ -822,7 +822,7 @@ static int hwicap_drv_probe(struct platform_device *pdev) &buffer_icap_config, regs); } -static int __devexit hwicap_drv_remove(struct platform_device *pdev) +static int hwicap_drv_remove(struct platform_device *pdev) { return hwicap_remove(&pdev->dev); } -- cgit v1.2.3 From d3cec81fc929b6edc43bd42725929685359adef7 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Wed, 21 Nov 2012 12:53:43 -0800 Subject: firmware: remove last vestiges of dabusb dabusb was removed with commit dae86ccbc3 ("[media] dabusb: remove obsolete driver"), so remove the last vestiges of firmware and documentation. Signed-off-by: Tim Gardner Cc: Rob Landley Cc: Paul Gortmaker Cc: Ben Hutchings Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- Documentation/devices.txt | 3 - firmware/Makefile | 1 - firmware/dabusb/bitstream.bin.ihex | 761 ------------------------------------- firmware/dabusb/firmware.HEX | 649 ------------------------------- 4 files changed, 1414 deletions(-) delete mode 100644 firmware/dabusb/bitstream.bin.ihex delete mode 100644 firmware/dabusb/firmware.HEX diff --git a/Documentation/devices.txt b/Documentation/devices.txt index b6251cca926..08f01e79c41 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -2561,9 +2561,6 @@ Your cooperation is appreciated. 192 = /dev/usb/yurex1 First USB Yurex device ... 209 = /dev/usb/yurex16 16th USB Yurex device - 240 = /dev/usb/dabusb0 First daubusb device - ... - 243 = /dev/usb/dabusb3 Fourth dabusb device 180 block USB block devices 0 = /dev/uba First USB block device diff --git a/firmware/Makefile b/firmware/Makefile index eeb14030d8a..cbb09ce9730 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -97,7 +97,6 @@ fw-shipped-$(CONFIG_TEHUTI) += tehuti/bdx.bin fw-shipped-$(CONFIG_TIGON3) += tigon/tg3.bin tigon/tg3_tso.bin \ tigon/tg3_tso5.bin fw-shipped-$(CONFIG_TYPHOON) += 3com/typhoon.bin -fw-shipped-$(CONFIG_USB_DABUSB) += dabusb/firmware.fw dabusb/bitstream.bin fw-shipped-$(CONFIG_USB_EMI26) += emi26/loader.fw emi26/firmware.fw \ emi26/bitstream.fw fw-shipped-$(CONFIG_USB_EMI62) += emi62/loader.fw emi62/bitstream.fw \ diff --git a/firmware/dabusb/bitstream.bin.ihex b/firmware/dabusb/bitstream.bin.ihex deleted file mode 100644 index 5021a4b1e63..00000000000 --- a/firmware/dabusb/bitstream.bin.ihex +++ /dev/null @@ -1,761 +0,0 @@ -:1000000000090FF00FF00FF00FF000000161000D7C -:1000100064616275736274722E6E63640062000BB9 -:10002000733130786C76713130300063000B3139C8 -:1000300039392F30392F32340064000931303A34E5 -:10004000323A3436006500002EC0FF20175F9F5BF8 -:10005000FEFBBBB7BBBBFBBFAFEFFBDFB7FBFB7F61 -:10006000BFB7EFF2FFFBFEFFFFEFFFFEFFBFFFFF9B -:10007000FFFFAFFFFAFFFFFFC9FFFFFFDFFFFFFF3B -:10008000FFFFFFFFFFFFFFFFFFFFFFFBFFA3FFFBE4 -:10009000FEFFBFEFE3FEFFBFE3FEFFBF6FFBF6FF18 -:1000A000BFFF47FFFF9FEEF9FECF9FEFFBCF9BEE19 -:1000B000F8FEEF8FEEFBFE0BFFFFFFFFFFFFFFFFE2 -:1000C000FFFFBFFFFFFBFFFFBFFFFFFC17FFFFFFAF -:1000D000FFFFFF7FFFFFFF7FFFFFFBFFFF7FFFFFB4 -:1000E000FC3FFFFFFFFFFFFFFFFFFFFBFFFFFFFFE7 -:1000F000FFFFFFFFFFFE5FFFFFFDFFFFDBFFFDFFD9 -:1001000077FFFDFFFFDFFEFDFFFFF2FFFFFFFFFFB9 -:10011000FFFDFFFFFFFDFFFFFFFFFFFFFFFFFFE111 -:100120007FFFFFFFFFFFFFFFFFFFFFFFFF3FFFFF1F -:10013000FFFFFFFFE3FFFFFFFFFFFFFFFFFFFFBF2B -:10014000FFFEFFFFFFFFFFFFFF67FFFFFFFFFFFF58 -:100150007FFFFFFF7FFFFFFFFFFFDFFFFFFF2FFF9F -:10016000F3FDFF7FDEF7FDFF7FF77DFF7FDFF7BD4C -:10017000FF7FFF1FFFEFFBFEFFBFEFFBFEFFEFFB6D -:10018000FEFFBFEFFBFEFFFF3FFE7F9FE7F9FE7F15 -:100190009FE7FA7F9FE7F9FE7F9FE7FFFC7FBFBFE6 -:1001A000EFFBFEFFBFEFFBB7BFEFFBFEFFBFEFFBB9 -:1001B000FFE0FDF9FE7F9FE7F9FE7F9DF9FE7D9D43 -:1001C000E7F9FE7F9FEDEDFFFDFF7FDFF7FDFF7F8E -:1001D000DFFDFF7FDFF7FDFF7FDFFF9BFFEFFBFE14 -:1001E000FBBFEFBBFEFFAFBBBEFFBFEFFBFEFFFFE2 -:1001F000B7BFDBF6BDBF6BDBF6F9BF5BD6F9BF6FF0 -:10020000DBF6FDBFFF0EFFFFFFFF5FFFF7FFFF7F86 -:10021000F7BDFFFFFFFFFFFFFFDF9FFFFFFFFEFFB9 -:10022000FFEFFEFEFFFF77FFFBFBFFFFFFFFF83F47 -:10023000FFFDFFFFFFFDFFFFFFFFFFFFFFFFFFFFD2 -:10024000FFFFFFF47FFFFEFDBEFFDFFEFFFFEF7F3E -:10025000FFCFFFCFFFFFFFDFE6FFFF7FDFF7DD7F91 -:100260007FDFF7FF7FDFD7FDFF7FDFF7FFCDFFF2F7 -:10027000FFFF4F7FF4FFFFFFE7EFFFFFFFFFFFFFF1 -:10028000FFFFBBFFEFFFFEFFFFFFEFFFFFEFFFFBF7 -:10029000FFFFFFFFFFFFFF65EFFFFF7FFFFDEFFFAA -:1002A000FFFFFEFFFFFFFFFFFFFFFFFECFDFFEFFB1 -:1002B000FFFBFFFFFFFFF3FFFFFFFFFFFFFFFFFF5E -:1002C000FEDFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F -:1002D000FFFFFFFFFFFEBFFFFFFFE37FFFFFFFFF0B -:1002E000FFFFEFEBFFFEBFFFEBFFFC7FFFFFFFEE2B -:1002F000FFFFFFFFFFFFDDFFD6FFFDBFFFFBFFFEA0 -:10030000FDFFFFFDEFFFFFFFFFFFFFDEFFFFFFFF32 -:10031000FFFFBFFFFDFF7FBFFF5FDFFFFFBF77FF77 -:10032000FFFF7FD7FFFFFFFFFFC3FFFFFFFFDFEFF1 -:10033000FFFFFEFBFFFFDFBFFFFFFFFFEDFFB7FF8C -:10034000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD -:10035000FFFFFFAF7FFFFFFFFFFFFFFFFFFFFFFF7D -:10036000FFFFFFFFFFFFFFFFDFBFDFF3FDFBFF5BD3 -:10037000FDFFBFEFF7FFFF7DFFFFFFFFF83BFFBF74 -:100380006FFFFEFFBFFFEB7DFFEFFBFEFFFFFFFFF9 -:10039000FFF27FFCFF3FDFEDFEFFFFFFFFEF5FF7A8 -:1003A000B5FFEFFFFFFFE03F9F9EFFFFEFFFDFFF87 -:1003B000BF5FBFCFF3FFFFFFFFFFFF69AF33FDFF5D -:1003C000FBFFFFFFFFFCFF7FD9FFDFFFFFFFFFF514 -:1003D000A3DF6EDEFFFFBDFFFFFEFFFFFFFEE7FDB9 -:1003E000FFFFFFF9EFC6FEB7ADE5F9FFFFFFCFFF57 -:1003F000FFFFCDFB7FFFFFFFF9F60FDFECCF7FFFA5 -:10040000FB7FFFFFFFFDFFFEF9FD7FFF7FFFF95B35 -:10041000FF73DCFD7BDFFFFFFF7BFFFFF753D6FFA2 -:10042000FFFFFFD89FFEFFEF7FEEFFFFFFFBEDED2D -:10043000FDFFFEFFFFFB7FFFE27FFF6FD857F7FF57 -:10044000FFFFDFFFE8FFFFFDFFFFFC7FFFE4FFFB97 -:10045000EFFBFEDFB7EDFFFEDF7FFFFE7FB7FFFFA5 -:10046000FFFF89FFFFCFF3FE7FFFEFFFFE7E7FFBE5 -:10047000FFFFFFFFFFFFFFF1FFEB7AD5BF6FDBBE92 -:10048000FDB7D8F6E5BF6FFBFEF5BD7E06FFDFF7D3 -:10049000FBF6FF3FFFDBFFFF6FFBF7FFFFFFFBFEFE -:1004A000F7AFFFB7EDEFF7FEFFFFDFFFFEFFEFFF58 -:1004B000FFFFFFBFF7FC1FEEFBFEBDFF7F5FD7FD19 -:1004C000FB43FFFFFDFF5FFFF7FFF93FFFCFF3FDAA -:1004D000F77EEFA7F9FE8FA7E9F37E9FFBF8FFFFFA -:1004E0003FFD7F5FDFFDFFFF5FFFFD5FFFFF7FFDE4 -:1004F0007FFD9FFFE0FFFAF8BE6F9FE6F8BE3F9AD0 -:10050000F9BE6F9FE2F9FE6F9FF9FFF5FD7FCFDF28 -:10051000FDFD7FFFF5FFFFFFF7F5FD0FDBFFD3FFCD -:10052000EBFAFFFFBFFFFAFFFFCBFBFEFFFFEBFA8B -:10053000FEFFFFB7FFFFFFFFBFFFDFF5FFFFD7FFA6 -:10054000FFFFDFD7F5FF7FFE4FFFFDFF7F7FFFAD92 -:10055000EBFBFFADFFFFFFFFAFEBFBFFFC0DFFFF72 -:10056000DFD2FDFFFFFDF6FFFF7FFFFF1FFFFFFF55 -:10057000FFFB3F7DEB32FEBF2FEBFAAEBDE0FA7E14 -:10058000BFADEBFAFEBFF57FFFDEFEE3FBFFFFFF33 -:10059000DFEF4FDFFF7FDFFFF7FFFFF87FFFFFEFAA -:1005A000FBFFFFFFEFFFFFDFEDFBDFFFBFFFFFFF05 -:1005B00081FFFFFFFF3FFFFFFFFFFEDDFEEFFDFFBF -:1005C000FFFBFEF7FF93FDFB7EFFFE87E9FF7FB396 -:1005D0009FFEFEFFAFFDFE7E3FFE67FFFFF7FFFFC2 -:1005E000FCF7DFFDFF7FFFFF7F6DFFFFFEFFFF2FAB -:1005F000FFBFFFFFEEFFBEFFFFFEFFEFFFFFFEFFAF -:10060000EFFFFFFA5FFFFFFBFFFFEFFFFBFEFDFFCA -:10061000FEFFFBFFFFFF7FFFFEBFDFFFFBFFFFF7DC -:10062000FCFDFFFFFFFFFF7FFFFFFFFFFFF27FFFEC -:10063000FFFFFF7FFFFFFFFFF3FFFFFFEFFBFFFF6A -:10064000FFDFE2FFFFFBFFFFFFFFFFFFFBE7FFFD19 -:10065000FFFFFFBFFFFFFFEDEFFDFFFFDFD7F5FD62 -:100660007F5DFDFF7FDF97F4FD7B5FFFC9FFFBFE32 -:10067000FFBFFF5FFFFFF7FFEFFDFFEFFFFFFFFF94 -:10068000FFF7FFD7FD7D7FFFFFFFFFEFDFF7FDFFE8 -:10069000BBFFFF7FFFFEE3FFF9FE7FBFEFFBFEFF27 -:1006A000BFF9FEFF9FEFF9FEFFBFF3DAFF37CDF38F -:1006B0007CDF37CDF37F37CDF37CDF37CCF37F5A48 -:1006C000BDF6FDBF6FDBF6FDBF6FDEFDBF6FDBF676 -:1006D000FDBF6FFEF16FEB7ADEB7ADEB7ADEB7AF41 -:1006E0007ADEB7ADEB7ADEB7FF7EFFFECDB36CDB13 -:1006F00036CDB36CDECDB36CDB36CDB36CDFC9BFAA -:10070000F7BDEF7A9EA7A9EA7AB7BDEA7BDEA7BD5F -:10071000CA728D91FFEFFBFEFFBFEFFBFEF7EFFB11 -:10072000FEFFBFEFFBFEFFFE87FFF6FDBF6FDBF6B0 -:10073000FDBF6FF6FDBF6FDBF6FDBF6FFE4FFFBF66 -:10074000EFBBEEFBBEEFBBEFBEEFBBEEFBBEEFBB06 -:10075000EFFC5FFFFFFF3FCFF3FCFF3FCFFCFF3F0E -:10076000CFF3FCFF3FCFFD9FFEBFAFEBFAFEBFAF65 -:10077000EBFEBFAFEBFAFEBFAFEBFFE16FFDFF7F1C -:10078000DFF7FDFF7FDFFDFF7FDFF7FDFF7FDFFF8F -:100790007ABFFBFEDFB7EDFB7EDFB7FB7EDFB7ED99 -:1007A000FB7EDFB7FFC9FFFFBFEFFBFEFFBFEFFB25 -:1007B000FFBFEFFBFEFFBFEEFBFEBBFFFEFFBFEF89 -:1007C000FBFEFFBFEFFEFFBFEFFBFEFF3FCFFFE7EC -:1007D000FEFFF5FD775DD735DD77D7F5CD7B5DD7AE -:1007E000F5DD77FE27FFFF8BE2F8BE2F8BE2F9AF36 -:1007F0008BE2F8BE2F8BE2F9FE1FFF5FD7F5FD7F7E -:100800005FD7F5FF5FD7F5FD7F5FD7F5FFFA3FFEB6 -:10081000BFAFEBFAFEBFAFEBECBFAFEBFAFEBFAF83 -:10082000EBFFFE7FFD7FFFFFFFFFFFFFFFFFFFFFEF -:10083000FFFFFFFFFFFFFFE6FFFADFF7FDFF7FDFB0 -:10084000F7FCFFDFF7FDFF7FDFF7FDFFF5FFFFFFA1 -:10085000FFFFFFFFFFFFFBFFFFFFFFFFFFFFFFFFAC -:10086000FF02FFFEBFABEBFABEBF23EBDE1FAFEA1A -:10087000FAFEAFAFEBFD97FFF3FC7B1FCFF1FC7FE0 -:100880001FF1FC771FCDF1FCFF1FFE87FFAFEFFAD2 -:10089000FEFFAFEFFAFDBF2BFB7EBFBFEBFBFBFB09 -:1008A000DFFFFBF7FFFF7FF7F7FFFDDFFEFCDFFF5A -:1008B000DFFFFDFFDABFFFBBEFFBF9FFBEEFFBFB86 -:1008C000BFEFFBFEFFBFEFFBFFF77FFDD7FFFF7F13 -:1008D000FFFFFFFEF7FFFEFFF7FFFF7FFFFFECFFCD -:1008E000FFFEDFBFFFFBFEFFBB68AE1FAEFBFBFFE3 -:1008F000FFBFFFD5FF7FFFFFF7FEFEFFBFEF9FFDAE -:100900007FFFCBFFFFDFFFFFBBF7BFFFFFFFFFDF77 -:10091000FFBFFBFFFFFFDE3FFFFFFFFFFFA7FFFF64 -:10092000FFFFEFFF7FFBFDFB7FFFFFFFFFCFF37CB0 -:10093000FF7F8D7FFFFFFFFFFBFFF7FBFEFDFFFF4C -:10094000FFFFF7FDFF7FFD1FFDFFFFFFFFBFDFFF85 -:10095000FFFE5CFF6DFF7FABE7F1FFFD9FFFFFAD8B -:10096000EB7A3F1FFFFFFEBFAFF3DEF5FF8FFBDF2C -:10097000E67FFFDFF3FDFF7EFFFFFFFFFFFDF7F3E5 -:100980007FDFF7EFFFF63F9FDFFFFFEEFFFFEFFB9D -:10099000FFFFF9FBFE4FBFEFBBFF69AFAFFCFF3FAF -:1009A000DDFFFCBF8FFFFDF3BFED9EFCBF6FF5D3F6 -:1009B000DFFFDBD6F5EFFDFEFFB9FF1FD2A9AFFFCA -:1009C000DBF7BFEF46FFFFADEB7ADFEFF7FF7FF717 -:1009D0009FEDFF7FFFADEB7FF56FFFFDFBD6F4F7DB -:1009E000FBF97E7FFF5FC2FEBFFDFB33DFF95BFFDC -:1009F000FFDD677DCFEFDBECFF77DDF7FDFFFFDE8F -:100A0000A7BFD49FFFFFBFEFFEFFDFEFBBFFFFEFEE -:100A1000EBFAFFEFBDFBFFE27FFFDFDFF7FDBFBBC0 -:100A200073F7FD7FDFDEF7BFEADBF6FFD6FFFF6679 -:100A3000FFBEFFBF6BD9F6DFFFFB7E7FB77EFFFEF9 -:100A4000FFCDFFFE7FFFFCFD3FFBFBF7FFFFFBF64B -:100A50007DFE7FFFFCFFB9FFF9FAFEBFAF5BD6ED6D -:100A6000AD7BF6F9BFEFF8FAFEBFFEE6FFFFF7FD3C -:100A7000FF7FBFEFF3FFFF6FF7FEFFFFF7FDFEF70E -:100A8000EFFFFBEFFB7EDEFEFFBFFFFEFFFFFBFF86 -:100A9000FFEFFB6FFC1FFEE7FFFFFFEFFFD3B4BBD1 -:100AA000FFFFFDBF6FE3FEFFBFFCBFF7CFF7FDFF0A -:100AB0002FDFABEAFFDFE7EA9AAFEFFBFEFFF53F80 -:100AC000FD7EFFD7F5FBFFFDF7FF7FFEF7FDFFD7AC -:100AD000FFD77FEE7FFA79FE2F8BE6F9FE3F9EF976 -:100AE000BE2F0BE7F9FE2F9FFDFFFE7D7F5FD7FF37 -:100AF000FF7FFFFDFF7F5F97FFFD7F5FFFE3FFFF4E -:100B0000FAFEBFAFFBFBFFFFCFEBFEBFAFFFFAFE6E -:100B1000BFFF87FFFFF5FFFFFFFFFDFF7FFFFFFF29 -:100B2000FBFFFFF5FFFFFE0FFFFDEBFFFFF7FFEF02 -:100B30007BDFFEFFFFDFF7FDEB7FDFFF5FFFFFFFE8 -:100B4000FFFDBFFF7EFABFC7DBF7BD3FFBFFF6FF30 -:100B5000FAAFFFEBFAFE3F2FEAFA3EADC9BAF6ADA7 -:100B6000AFEBFAF6BFFE7FFFFFFDFFF17F3FCFF156 -:100B7000EFFF7FFFBCDFDFF7DDFFE07FFFFFFEFF62 -:100B8000FAECBB7F5FFFFBECFFEFB7FFF7FFFFB5B2 -:100B9000FFFF7FFFFFFFEEDF5FDFDEFFAEE777FFE8 -:100BA000FFDFF7FFE3FFFABBFEFFAFFDFBFEBFABCE -:100BB000F9FEFFBF7FBFFEBDFED7FF9FFDFFBEEF6B -:100BC000FFEEFDBB5BEFFF7FEFFFEFFF7FFF4FFF10 -:100BD000EFFBBCFCFFFFFFFEFEFDFAFEFBFFFDF39B -:100BE000FBFFF85FFFFFD7F5FDDFEFFFF3DC5FCE24 -:100BF000F5BDFFFFD7FFFFF93FFFDFF7FFFEFFFD6A -:100C0000FFFBFFF7B97DFEDFFFFFFFFFF97FFFFE70 -:100C1000FFFF7FFFFEFFFFF7F6FFBFF1F8FFFFFFCB -:100C2000FFE0FFFFFFFFF9FFFFFFFFFFEFEFFFFF19 -:100C30009BFB7FFFFFFFC1FFDFFF3F5FD7BFEFBB26 -:100C4000DEEEFF7FDFFFFEF57FDFFF99FFFFFAFF9C -:100C5000BFFDEB7AFFB7FEFEFFFFEFFFFFFDBFFF1B -:100C600097FFFDF7FF7FF7FFFFFD5FFEF3F9DFDF83 -:100C7000FFFFFCFFFF83FFFFFEFF9EECFBEEFF9FED -:100C8000BFEFFFFEED7BFFFFFFF15AFFFFFDFF7C93 -:100C9000693BDFFF7F1FDFFFFDBAFFFFFBFF5BBD8F -:100CA000FFFFFFFFD7B6EDE9FFD6BD6F5FFBFFEF9C -:100CB000FF5FFEF66FFFFFFFFFF7EB7ADFFF9F7F1F -:100CC0007FFFB7FFFFFEDFFF6CFFFBFFBB6FEBFE9D -:100CD000CCF7A5FA5CF575BBB7DFFE6F5FC5BFFD4E -:100CE0007BFEFF95E729CF4FF591EE6BDFEFFD54CB -:100CF000F5BDB1FFEFEEFBBEBFAFFEDEBD6FDAF2BA -:100D0000FFAFBEFFFFFD7EA7FFF7FFBFEF7BF6FD46 -:100D1000BD4AF28585BF5BFEB5FDFAFF4FFFFEDFE2 -:100D2000FFEDFFBFFFBF7FFEFFB76DFFF7BFBFEF58 -:100D3000FD1FFFFE7DFF67FFFFFF3F7FFEBFFFE759 -:100D4000DFE7FFEF6BFC1FFFBFEFFBFEDEBFAFFA7D -:100D5000FFB6EFF9FEFF8FEFDBEFAB6FFBFEFFFFA0 -:100D6000EFFDFF7FFFFFDEFFFFEFFFFFFF3FFF6CA9 -:100D7000FFBFFBFFFEFFFBFEDFFFFFEFFFFFBFFF3D -:100D8000FFFEFBFFD57FFFFFEFFBFFFFBFEF43B58C -:100D9000FD6FCFD6BE3F7FDBFEC3FFFDFFAFEBFB9A -:100DA000FCFF3EEFE8FABDCDAAFEFE7DCFFFB7FF08 -:100DB000F7FFFFFFFDFF75CD52D7FDFBF7DDFBEF22 -:100DC000EBFFFF4FFFBF9FE7F9FC7F8BC3F9AF8FAE -:100DD000E7E9BE7F9FE6F9FC5FFFFFF7FDFF7A5F63 -:100DE000D7EDFFFFD7FFDD7FE7FFFCFFFC3FFFFFF5 -:100DF000FFFBFFFEBFAFFFFDFFEFFFEBFFFFFFFFBE -:100E0000FFF77FFF7FDFFFFDFD7FFEF7FD7FDFFF49 -:100E1000FDFFFFDFFBFFEEFFFBFFF7FDFF7ADFF5D6 -:100E2000FDFADFF7FCFF7FDFBFEDFFC9FFDFFFBF8C -:100E30002FFBFFBCADFFF7FFFFEFD3FF7DBF6FFFC1 -:100E4000FAFFFEBFAEEAFABEADA5EBCEBFA7EB5AE6 -:100E5000DEBDAF6BFD57FFFFF47F1F7FFDFF7F36C9 -:100E6000F0DF79FFFFFFF7FDBFFF87FFFBF3FCFF1C -:100E7000FFFFFF7EFFBFDFFFFFFFFFFFFDBFF89F0C -:100E8000FFFFFFFFBFFFFFFDF7FCBDFFFEFFFFFF02 -:100E9000FFFFFBF9BFFFFFEBE2FEFFBFEFA9BA2F99 -:100EA000EBF9FE77DFF7FFFFF97FFFFF7FEFD7FF5B -:100EB000FDFFFBF5FFBF6FDFFFFFFDFFFFF0FFFF53 -:100EC000FF3FCFFFBAEE9BBFEED7FECDEFFFDFBFF8 -:100ED000FFFFC5FFFFFD7F4FFDF6D9FF4FD6FDBFDA -:100EE0006EFFFFF47FFF7F8BFFFFFFFFF7FFF9FE31 -:100EF00037FFD9FBF5AFFDFFFFFBFFFF07FFFFFF4C -:100F0000FBF7FFFDFF7CFA7E4FFCDF1DC7FFFFFFF5 -:100F1000FFAEFFFFFFFFFDFBFFFFFEFEFCFF7F7F3D -:100F2000BFEFFEFFFFFF5FFDFFFFFFFD6F5AD77BA7 -:100F3000BE5FFE39FFF7FFF7FDFEAA1FFFFFFFFFB1 -:100F4000FEFEABAFFDFEBFFFF7FF7FFE8FE3FBEEC4 -:100F50007FFFFFFFFFEBFBFFFDBFEFDFFFFFFFFFAB -:100F6000FFFFFFFBE43FFFDFFFFFFFFFF3EFBBFBF4 -:100F7000BFEFBBFFD7BFFFFFFF29AFF7FFFFFBFFAF -:100F8000FBE6FF0FFB3FDF0FFFAFFFFFFFF5C3DF08 -:100F90005FFFFFFFFE6BCABEBCFF9FF2BFFFFEFA02 -:100FA000FFFFEF16FFFFFFFFFFFCDF97FD79FF3725 -:100FB000E77FFFFFB5FFFFF62FFFFDFBFEFFFFFD05 -:100FC0005F575FFFDB52DFFFFDBFFFFFFCDBFF7BF7 -:100FD000B5FD7FFF719C6EFFF635A59BFFFFFDFF02 -:100FE000FFDB9E7FFEEFFBFFFFBDEFFFDEB7F94BA0 -:100FF000FFF5EFFFFFFFE87EFFEADFF7FFFD695B2C -:10100000FC9FEF78D6FFEBEFFFFFFFE8FFFFEDFF60 -:10101000FFFFFFE3F9F6BFFFFFFEDFFF7FFFFFFFEC -:10102000D1FFFFE7FFFFFFFFE7F9FFBF7FD9FFFD1C -:10103000FE7FFFFEFFF9FFFBD6DFBFEF5BD6FFBFF2 -:10104000FBF6FFBFEFF8F6DDBEFE16FFBFEFFFFEBB -:10105000FFBFEFFFFFFF6FFBFFFFFF6FF3FFF7EF38 -:10106000FBFFBFFFEFFEFFBFFFFFFFBEBFFFEFFFB6 -:101070007FEFFFFD17FB7BFFFFFD7FDBF6F47FFAC1 -:10108000FEF5BFEBE3F7FFFFE9BFFFAFF7FDF37E30 -:101090008FA3EAFFCBF3EEFFBFEFF7F9FFFE7FFF71 -:1010A000FFFFFFF5FBF6FFF52FFEFBD7BFFFBEDF0F -:1010B0009FFFF0FFFFF9FE7F8FA3F8FE6F9FF9F609 -:1010C0002F9FE7F9FE2F9FE1FFFFFF7FDFF7F5FD81 -:1010D0007F7FF5FF9F5FFBFEFF7FFFFFCBFFFFFBE7 -:1010E000FEFFBFAFFBFEFFDFFEFEBFF7FFFFFFFF10 -:1010F000FFC7FFFFFDFF7FDDF7FDFFFFD7FFFD7F90 -:10110000FFFBFDFFFFFEEF7FFDEFFBFEFBFDFF7F23 -:10111000DFFDFF7ADFF7FDFFFFFFFF1FFFFFD3F7C4 -:10112000FFFF6FDBFFFFEFCBF4FFFFFFFFFFFFFED3 -:1011300029FFE8DA769FAF6ADAFE35EBDAD6BFAB85 -:10114000EB7ADEBFD77FFFFEFFBFEFFDDF77BFFD8E -:1011500037EFFFEFFF3FFFFFFFFE7FFFFFFFF77E51 -:10116000DFFFFFFFFAB77FFFFFFEFFFFFFFF89FFF3 -:10117000FFFFFFFFFFFFFFFFFF9FFBFFFFFFE7FFFB -:10118000FFFFFFAAFFABFBFAEFBFFFDFFA7BB9FE61 -:10119000FEFFFDFFF7FE3FFFB7FFF7EEFF7FEFFF1C -:1011A000FF7FFF1FFBFFBFFBFEFFBDFFFF2FFFBF4A -:1011B000FF7FDFFAFFFFFCEEF5F3BEFB0FEFF3BEA0 -:1011C000EFFC5FFF5AFFF7DFFFFFFED5FC5FFBF28E -:1011D000FFFF2FBBF3FFFFBFFFEFFFEFFFFFFFFF9F -:1011E000BFFFFFFD7BFFDFB9FFFBFFD87FFFFFFFE6 -:1011F000FBFFFC7F1FBFE0DFF7EFFFFD7FFEDFFFA0 -:10120000E0FFFFFDEFFBFFFEF7DFFFEB5FFFF7FF08 -:10121000FFFFFFBFFFFDFFFDFFFFFFF7FDFF3BDC13 -:10122000FD6D7B5F57F5FD7F5FFFB1FFEBFFFFFFBC -:10123000FBFBFEFFBFFBBEFFBFEFFBFEFFAFFEF7FA -:10124000DFDFFFFFFF7FCFF3F8FFD7FBFF5FBFF7C5 -:10125000FBFF7FFE23FFFFFE7FF3FFFBFEFFFFF39D -:10126000FFFFF5F9FF3FFFFFF09AFFBE7FFFFCF99C -:10127000FFFDAFEBFEBFFFCFF3FE7FFFFF5BBDFFC8 -:10128000BCEBFFD7D4AFAFFDFFCFF7FDFF7FDFF79C -:10129000FDFEFF6FFFFBFFFFFFFD7F5EFDBFDBF687 -:1012A000FDBF6FFBEEFDFF7AFFFAFBFF3FFBB75F71 -:1012B000D6F71F71DC771DC731DC77DFF9BFF55B2F -:1012C000F4D79DAEFFBFFDBFDBF6FDBF6FDBF6FEC3 -:1012D0003D81FFEBFEFEFEFFEB7ADF7D777DF5794A -:1012E000DF57DDF57D7EE6FFD63FBF7FFFD4F53FBC -:1012F000BFFBBEEFB3EEFB9EEFBBFE8BFFFEDFB787 -:10130000EDFFF7FDFEFFEFBBEEFFBEEFBBEEEBFC2C -:101310001FFFFFFDFFE7FFF7FDFFEFFEFFBFEFFB46 -:10132000FEFFBFEBFA1FFFB7EF5BFEFFAFEBDDE7A2 -:10133000DE779DE779DE779DBFE66FFFFEFFBFEFAB -:10134000FBFEFDBF6FF6FDBF6FDBF6FDBFFF7EFF4F -:10135000FFFBFEFEFFEFFBFDEF7EF7BDEF7BDEF751 -:10136000BDEFFFD5FFBFFFEFFEFFFC3F0FE7FE7FA6 -:101370009FE7F9FE7F9FE7FEF3FFFEDFADDF67EE3D -:10138000FBBFEFFEFFBFEFFBFEFFBFEFFF23FFFF43 -:10139000FFFF7FFFF3BCDBFEFBFFFBBEF7FBFF7F26 -:1013A000DFFFCFFBFF9FE3F9BE3F8FE779FF9DE7AC -:1013B000F9FE7F9FE7F9FE5FFFCFF7FFFFFFDFF743 -:1013C000FE7FE7F9FE7FFFFFFBFEFFFFBFFFBFBF12 -:1013D000FFFEFFBFEFFFFDFFFFFFFFFFFFF7FDFF7A -:1013E000FF3FFFBFFFF7FFFF7FDFFFFFFFFFFFFFB5 -:1013F000FFFFFFFFFFE8EFFF5FF7BFF9FEDFB7FD7D -:10140000FFDFF7FDFF7FDFF7FDFFDDFFF2FFBFFF2F -:10141000FFBFFFFF2FF2FFBF2F7BD2F7BF2FFFBB16 -:10142000FFEE8FAFEBFAFE3FA769CE8FA4EAFAEE8C -:10143000B7AEEBFDC7FFF7F7FFFFFFFFFF7F3EF300 -:1014400074FF3F4FFFE7FF3FFEA7FFFFDFF7B7FF48 -:10145000F7FFBAEF37EBFBFEBFFBFEF3FFF9DFFF51 -:10146000BFFFFFFFBFFFFFFFFDDFFFFDFFFFFBFE35 -:10147000FDFFFBBFFE3FEDFFDFBE3DA7FBFA3FE6F2 -:10148000E1FEFE3FEFE3DFF57FFEFF7EFFFFFFFFA4 -:10149000EF6FF6FF7DEFD7DEFF7DEFFFF2FFFFFF7F -:1014A000FFFFFF7BDEFBE6EEEF376EF37EEB37EF01 -:1014B000FFC1FFFEFFF7EFFFFFFFBF3FD2DFBF2FF0 -:1014C0007BE2FFFE3BBDDBFFFEFFFFFFFFFFEFFE0A -:1014D000FFFBFFFFBFFFFBDFFFBFFFB7FFFFBFEF5C -:1014E000FFFFFFFFFFFF0FFF7FFF1FEFF1FDFFF685 -:1014F000AFFFFFFFFFFFEFFFFFFFFE9FFFFFFF7745 -:10150000EFF7FBFFFE5FFFFFBFCFFBF7DDF7F5FF58 -:101510005FD5F5FD7F5FD7F5FFFB0FFFFFA9EA7AE7 -:10152000FFAF8FFEDFAFEFFBFEFFBFEFFBDFE55F3F -:10153000FFFFFFFFFFBD57FFFF6F77BFF7FBFF7F89 -:10154000BFF7FFFCBFFF9FFFFFEFFFFEFFFFFF1F87 -:10155000CFFFFCFFFFFFFFFB65AFF37CFF3FDFFF2B -:10156000FDE9FE7FE7FFFE7FFFFFFFFFFDE3DFFBFF -:10157000DBF6FDEF5BFBFFDFFCFF3FDFF3FDFF7FF3 -:10158000DFEF66FFDFADEB7ADEF7F7E7D9FD9F67A8 -:10159000D9F67D9FE7DFF547FD655BD6F4FEFFEFEB -:1015A000FF6DF6DDB76DDB76DCB77DFA9BF66D9DE2 -:1015B0006759DFF7DDFFEBFEBFAFEBFAFEBFAFE32E -:1015C000D19FFFBDBFEFFEF7BFBFF7D77FDDF79D10 -:1015D000DF7FDFF7FFE07FFDC1DFF7FDC77F7FFB28 -:1015E000FFBBECFB3EFFBFECFBFFD87FBF6CFFBE39 -:1015F000FFBFEDFFEFFEFBBFEFFBFEFFBFEEFFC542 -:10160000FFAF6FFFFCFD3FE7FFFEFFEFFBFEFFBFFD -:10161000EFFBFEBF89FEFABAFEBFAFFBF6F5D97D40 -:101620009765D9745D9765D3FED6FFBFF7FDFF7F41 -:10163000BFCFFBFEFFEFFBFEFFBFEFFBFFF68FFB15 -:10164000FFEFFB7EDBFEFFBEEFEEFBBEEFBBEEFB74 -:10165000BEFFFFDFFF43FFFFFBEF5FB7FE7FE7F952 -:10166000FE7F9FE7F9FE7FF9BFFEAF77FDFF2FAF4B -:10167000A7FEFFEFFBFEFFBFEFFBFEFFF17FEFDFFB -:10168000FF97F5EFFFDFFFFFBFFFBFFFFFFEFFFF8D -:10169000FFE0FFFFF9FE2F8BE3F8BE779FF9DA77C3 -:1016A0009DE779DE779FDDFFFDFD7F5FD7FDFF7F43 -:1016B000E7FE7F97E7FBFEFFBFEFFFABFFEFFAFE12 -:1016C000BFAFFFFAFFFFDFFFFBFFF7FDFF7FDFFF8D -:1016D00067FFF7F5FFFFFFDFFDFFFFFFFFFFFFFFE6 -:1016E000FFFFFFFFFFEFFFBDEBFFFFF7ADEBFFDFFE -:1016F000FDFF3FDFF7FDFF7FDFFF5FFFF7FFFFFD30 -:10170000BFFFCBF4FF7FD3F7FD3F7FD3F7FFFC3F55 -:10171000FFEAFABEAFABEBBAF4956B52D4AD2F4AE9 -:10172000D2F6BFD27FF73FFFFFF37FFFFFF7FFBA8D -:10173000DFFBFDFFBFFFFBFFF87FEAFFFEFEDFFFE1 -:10174000F7FF7FBBFFFFBFDFFBFFFFBFFFB17FFFE7 -:10175000FBEFFFFFFFFFFFBFCFFEFFFFEFFFF7FF36 -:10176000FFFFF1FF69BEFABFAFE2FFFEFDAFF3FE80 -:10177000FFBFEFFBFCFFFF07FD95DBDF7FDFAFFF68 -:10178000F7AF36FEBF65EBF6FE9F6FFE07FFCFFF9C -:10179000F8FEFFCFFFF6FAE7FBFEFFBBEDF9FFFF18 -:1017A000FF5FFFFFFF75FFEF7EFDE0E85ED3E5F929 -:1017B0003E5FD7F7FFFA2FFBFFFFFFFFFEFFFF7F24 -:1017C0007FD7F57D5F57D5F5EFFFF37FFC7FFFC730 -:1017D000F1FFFF1FCFB0FF3FCFF3FCFF3FCEFFE491 -:1017E000FFDF7FFEF7BBFFFFDFEFEEFFBFEFFBFE8C -:1017F000BFBFEFFFD1FFFFFFFDFBFFFDFFFB9FE939 -:10180000FE7F9FE7F9FE7FBFFFB3FFFFF7FFFFAF4C -:10181000F7FFB63FEBFAFEBFAFEBFAFEBFFEA7FF46 -:10182000FFFFFFFFF7FFFFFFFE9FF7F9FF7F9FE737 -:10183000FFFFFEAF6FFFFFFF9FFFDFFF7D5FDDFF5D -:10184000FBBFE7BBFFFBDF6D5F7EFFFFFFFFFFFF1F -:10185000EBF7FFE7EFF7FFFF7FFFF7FFFC8FFFEFEF -:10186000FDFEFFBEF4F27DD7CFFF3FFFFFFFFFFF7E -:10187000FFCF6BFFBF3FFBF2FC7FEBFF9FFAFFFF49 -:101880003FFFF3FFFFFD70F7FFFFBFFFFBD7FEF544 -:1018900077FF15DD77FDFF7FDFF7FBCDBFFFFDFF96 -:1018A000FFDF37CDF9ECFEEFBBF4FB3F4FB3FFFD9D -:1018B000CBFFE97E549FE54BB7FFDD7DC771DD7738 -:1018C0005DD775CD7FD6FFD3F6F93F6D95AF7FFE1F -:1018D000FFEFFBFEFFBFEFFBFEF6C7FFAD7BCAFFCE -:1018E000BFBFEFFDE3DFB7EDFB7EDF37EDE3FBDFEF -:1018F000FF525C15FDCF7FDFFEEFEFFBFEFFBFEC7D -:101900007BFEFFFE3E7FDAF7FDFF7FFFFFFBEFBBB5 -:101910006FFBFEFFBFEFFBFFF77DFFD8FFFDBF7F33 -:10192000FBFFFF9FFBFE7F9FE7F9FE7F9FEA7FF6AD -:10193000BFBD6A5AF6E5BF775F6DDD775DD775DDB0 -:1019400077FFA5BFCFFBFFFFBFCFFBFDFFBFF3FEC0 -:10195000FFBFEFFBFEFFFDABFFBFBFFFFBFF7FEF56 -:10196000FFBEFBEEFBBEEFBBEEFBBFFFB5FFD0BC87 -:10197000FD2F4BF7FFFF9FF9FE7F9FE7F9FE7F9F4B -:10198000FA8FFDABFADABFAFB3FDFFBFFBFEFFBFBF -:10199000EFFBFEF7BFFF9FFF77F7BDFD77DFFF7E11 -:1019A000DFEDBBFEFFBEEFFBFEFFFA3FFFBE6F8F1A -:1019B000E6F9FE7F9FC7FE7F9FE7F9FE7F9FE7FB6B -:1019C0007FFF7FCFFFFDFFFFDFFBAFBFEFFFFEFF1E -:1019D0009FEFFBFFFCFFFBFEFFFFFFFFFEFFFFF79C -:1019E000FFFFFFFFFFFFFFFFFFF5FFFFFF3FDFF7F9 -:1019F000FFFF7FEFFEFFBFFFFBFFFFBFEFFFB37FE8 -:101A0000FF7B5EF7FDFF7B7FF7FF7FDFF7FDFF7F4B -:101A1000DFF7FF17FFFFFF7FFFFFDDF6FCBFCBF215 -:101A2000BCBF2FCBF2FCBFFE8FFFFA7EBFA7EBDA65 -:101A3000FCBFAF7AFEBFAFEAFAFEBFAFF4DFFEFF36 -:101A4000F33C7F3EFFCFF8BF8FE3F8FE3F8FE7E820 -:101A5000FFFC9FFFFFCFEBB3E7FB7BF3FEFFCFDB8A -:101A6000FBFBBF6F6FDFEC7FFFFFF7FDFDFFFFFFAD -:101A7000FFB2BFFFDEFDBDEFFBF6DFEAE7DBFEBB3B -:101A8000FFEBFBBF9F8FE8FE3F8FA3F8FE3F8FFF6A -:101A9000F87EFDFD7FFFFBCDFFFDFF5FEFFDFFFF4C -:101AA000DFF7FDFFBE90FFFFEEFF3FBFF3BBFEB7CA -:101AB000ABFAFEAFADEAFADEABFF63FFFEF2FFB3B7 -:101AC000FFDFEE7DFF03F1F43F1FC3F1EC7FFE6FFC -:101AD000FFFBFBFF9FFFBFFF7B5FFDFFDFF7FDFD10 -:101AE0007F7FDFFECFFBFFFFAFFBFF1FEFA5FDBF3B -:101AF000DFFB7DFFBFDFFBFFFD3BFFFFFFFFFFFDC8 -:101B0000AFF3FFFB7FBFD7FBBF7FBBF7FFF87FFFC4 -:101B1000FA5FD7FFDF7FEFFFFF7FDBF7FDFF7FDFA0 -:101B2000B7FBECFFFFF7BFEFFDFCFBFFEFF0FE3F65 -:101B30008FE3F8FE3F8FEF8DFFFFEF7FBFFFFBFFCF -:101B4000DBBFFFFFFFFFFFFFFFFFFFEFD8FF2E7F91 -:101B5000BEEFFE6EFFBFF9FFFFF3FFFFFFFFFFFFCA -:101B6000FC66BE47F37FDFFE879FFFFFFFFFE7FFB7 -:101B7000FFFFFFFFFFD66F7CFB4FD2FFFD2BFEFF69 -:101B8000FFFD5FD7D5F57DFFFFFFBF9BFFFFDFB7F1 -:101B9000FFFFDFFF3FCFFE7FBFEFFBFCFF3FFFD923 -:101BA000BFFE97EC8FB7FE9B7DFDB7DD771DC7713C -:101BB000DD775DD7F36FFD3F73DDAFFD7AFFFFAFDC -:101BC000FEFDBFEFFBFEFFBFEF667FFFFFBFBFFF66 -:101BD000FBFFF7DFFDFB7DDFB7CDF37C5F3F913F80 -:101BE000FF3DEF7BFFFCFFCAEFFEFFBDEFFB1EE7F3 -:101BF000BBEC7FB3FFFD9FFFFFFEFFFF7FBFFBFE40 -:101C0000FFBFEFFBEEFBBFDF67FFFFBFEFDBFFBCFC -:101C1000FE7FFBFF9FEFF9FE7F9FE7F9FE87FFEE58 -:101C2000FBBEE5BFEFF9D765F7DDE77DDF775DD771 -:101C30007FF89BFEFFBFEFFBFFFFBFEFFBFF7FCFF8 -:101C4000F3FCFFBFEFFFDB3FEFFBFEFFDFFFFEFB21 -:101C5000BBEFBFEFBBEEFBBEEFBBFFFC7FFD3B5B13 -:101C6000D6E5FD4FC3FBFFBFEFFBFEFFBFEFFBFF62 -:101C7000B4FFFABC8FB2E9D22ECFFBFFBFEFFBFE61 -:101C8000FFBFEFFBFFECFFFDFD7FDFF7E4DF5FFF52 -:101C9000FFFBFFFFFFFFFFFFFFFFC3FFEFE6F8FEC5 -:101CA0003F8B83F9FE7FE7F9FE7F9FE7F9FE7F1701 -:101CB000FDFFFFFF7F5FF72CFFFFFFFE7FFFE7F9D0 -:101CC000FE7F9FFE2FFFFFEFFFFEBFEFADFFFF7F09 -:101CD000FFFFFFFFFFFFFFFFFEDFFFDFFFFDFD7FD9 -:101CE000DFF7FFFFFFFFFFFFFFFFFFFFFFFA3FFEF2 -:101CF000F7FDEF7AFFB1BDFF7FF7FDFF7FDFF7FD57 -:101D0000FF7FF327FFDFFFDDFFFC9BFFCBFCBF2F37 -:101D1000CBF2FCBF2FC9FFDEFFDFAFEBDAFEBBAFBC -:101D2000EBF8F7AFE8FAFEBFAFEBF2FFFDFFFFEF16 -:101D3000BDD7BFFFFFDE8FB8DE378DA378DA3F8FC8 -:101D4000FFA1FFFFFBFBFFFFFFFFA7BDFB76FDBF72 -:101D5000EFDBFEBBBFFE277FFFFEFEFDF5FFEFF5CD -:101D6000DF1FE7FDFF7FDFF7FDFFFFCDFDAEFFFAD1 -:101D70003E3FABFDF87E8FE3F8FE3E8FE3F8FFFEBB -:101D80001FEFDFBFFEDEDFD9FFDFBCFFFF7FFFEF0E -:101D9000FD7FDFF7F93FFEFFFF6FFEDEBFF7EDEAE5 -:101DA000FD8F83F8EA3F8FEFFFF47FFFEFEF7BF3C8 -:101DB000F15FFFFFF13B7FDFF7FDFFFFFFFFE0FF7C -:101DC000FFFFF7FF6FFF7FFFFFF7DEF7BFEFFBF7C8 -:101DD000FDFFFFF5FAFFFFFBE7FFF3F87FF3DFFFFF -:101DE000FFFFFFFFFFFF1FEFBBFFFFFFFFFFFFFD39 -:101DF000FF7FFF9FFFFFFFFFFFFFFFCFFF37FFFFCB -:101E00007FDF775DE7FCFFBFF7F5FBFFFFD7F5FB53 -:101E1000FFFF45FD7FEAFDBEBFDFF7FFFFDBFBFEF7 -:101E2000FFBFEFFFFFFFFB5F7FFFFEFFFFFFFFFF37 -:101E3000FFFEFFEFFDFF7FDFFFEFFBF80FF3FFF982 -:101E40002EFBFEFCF3EFFFFFBFFFFBE7FFFE7EFF75 -:101E5000C06BCFFF34DFF1FDFFEFFFFFFFDFF7FDCA -:101E6000CF7F9CFDFD6CF7FFF6FDEB2B9FFFFCFE8B -:101E70007EFFFFFFFFD7F3F7FFFBE1BFFFEB7ADE4B -:101E8000D7FBFFF9FEFFFFF3DE7FFDE77FFFFDBB22 -:101E9000FFFF7ECCF6AF5F7FFEF47DF7FDBB6EDB10 -:101EA000B7FFF7DF66FFFFF73DCFDEBDFFFFDEDBED -:101EB0008DF77EDFB7EF7FFFF687FFFFEFFEDEBF18 -:101EC000FFFFFFBBEFFDFF7BDEF73FFFBFFBDBFF4D -:101ED000F2B6FDBD7FE7FFFFFF6FF7FFFFFFFE7765 -:101EE000FFBFF8AFFFDFBFFFBF7FFBFFFFFFDBFEE2 -:101EF000FFBFFFFAFFFDFFF67FFF9FFFFF3FEFF8F9 -:101F0000EE7E9FBAFEBF8FEFFEFEF9FFFA7FFE7EE8 -:101F1000BFAFFB96FD9FEF5E65BEEF5BB6FFBEE316 -:101F2000FFB5BFFFFDFF7FFFEFDFFEFFBFFBFEFF43 -:101F3000BFCFFFFFFFFD9BFFFEFBFEDFFF7FFFF735 -:101F4000FEFFDFFBFBFEFFFFFFFFFFB7FEFAFFAB6D -:101F5000EFFFFDB57B7FFBF7FDFFFFDDFFEF8FFFA1 -:101F60002FFFFB7CFF3FDF73EBFE3FFFEFFBFEFF2E -:101F7000EFFDFFBFFD0FFFFFFFF5F9FF7FD7FDFF6F -:101F8000DFFFF7FBFF7FBFFFFFF09FFFFE7F8BE3CD -:101F9000F9DE279BE6BE7F9BC3F8DE7F9DE7FE7FD1 -:101FA000FFFF5FD7FFFFFF4FFBFFFF7FFFAFFF9FED -:101FB0007FFBFFE8FFFFFEBFAFFFFFFEBFEFF7FFB6 -:101FC000BFFFFFFFFFFFF7FFFCFFFFFD7FFFFFFFEE -:101FD000FD3FCFFFFFFFFFF7FFFD7FFFFF93FFFFF9 -:101FE0007ADFF7FFFF7B7FB7EFFFFFFDBFFDFBFF52 -:101FF000F7FFD7FFFFFFFC9F6FCBFFF4BBDFD6FDE2 -:10200000BF2FD3F7FFDFFFCFFFFABEBDAF6ADABE47 -:10201000BBAB3ABE2DAEEBDAF63FADF5DDFFCFF14F -:10202000FFF97FFF73FEFFCFC3F4F72FF3FFFCFF31 -:102030007C1FFF3F4FFF7EFFEFBDF6FEFF2BEFDC67 -:10204000FBFDFFFBFFEA7BFFFFFFFFFFFBF7DFFF6F -:10205000E37DFFB7FFBFFFFFDFFFF8FFBFFFBFEB71 -:10206000E7FAFE3DBFE9FCBFFFFAFBFEFFFFFFD929 -:10207000FFFFFFF67FFFF67DFFDFCFFDBFFBEF7EAB -:10208000FF7FFFFFD3FFFDFBFFFBFFFFFFEFFFBF66 -:10209000FEFFF7EFFFFFFFFBFF87FFFDFFFFFFFFE7 -:1020A0007BFEFFFE3BF7F7FF3FFFFFFFFFFF0FFF4A -:1020B000FFFFFFFBFFFFFFF7FFFFADFFFEF7FFFF97 -:1020C0005FFFFFDFFFFDFFF5FFDFFFBDFFE9FFC79C -:1020D000F3FFFFF7FFF3FFF83BFFFF7BDFBFFBEFF3 -:1020E000FBFFFBF7F7BBFFFFFFFFFBFFFE7FF37F6D -:1020F0005EB7BFFD7FFFF97FFBFFEBFD7F7FFFEF4B -:10210000FBE03FFEBFBFDFFF7EFFF7FFFFFEBFFF2D -:10211000DB78FFFFFFEEA1BFF5DEFBF7FFFBFFFF64 -:10212000FFFFFBFFFFD7FFFFFFFFEFF0FFFFFFF316 -:10213000F7FFEFFFE7CFFFFBFFEFFFFF9F9FEFFCF6 -:1021400016BFFEF3E4FFFFC6FFE7FFFFFDFFBFFF83 -:10215000FF3FFFBFD6AF7FFE6B7E7FFFAFFFFFBFAE -:10216000FF5FFFFEFFFFFEFFFFBDDBFFFE5FF2FF35 -:10217000FF5FFFFFFFFFFFFFEF7FFFFFFFFFDEBF00 -:10218000FFFFEFFB77FEBD7F5FFFFFFFDF6FEDFF20 -:10219000FDFF7FFD6FFFFF77DACFFD5FFFBFFFFF22 -:1021A000DF7FFFFBFFFFFFFF667FFFFEBFE7BFFA9A -:1021B000FFFEFFFFFFDFFF59EFFFEFFB7F89FFFF10 -:1021C000E9FF6FFFF5FFFFFFFFFF7FF2F7FFFFEF74 -:1021D000F87FFBFFFDFFFFD9FFEFBBFFFFFFBFEF66 -:1021E000DEFFFF9F7FDFFFF7FFFFFFFFDFFFFFAF98 -:1021F000FFFFF73FEB9FFE7F9E7F9FFE87FFEDDB9C -:1022000056FFBFAF0BD2FFEFDB6E7DBD6FF8FE3F19 -:10221000FA5BFFFDBFEFFFBF6FDBE6FFFF3FFFDFB6 -:10222000FEFFFFFFFFDA3FFFFBFEFEFFFFDFF7BD14 -:10223000FFFDFFFEFFFBFFFFFFFFF15FFD9FDFFDE7 -:10224000FFFD7FFFFFFFFF76FAFFFF7FE3F8FFAEA2 -:10225000FFFB7E9D73FFFA7FDFFFFF7FFFFBCDFF5C -:102260007FEFFBFFFDFFF77F7FEFFFEDFFFFFFB588 -:10227000FFBFFFBFFDEFDBF7FF93FFEFE2F9BE7F8C -:102280008BE7F9FE6BE7F9FE7F9FE7F9FE7F47FFDB -:10229000FFFDFF9FFFD7FFFFFFFFF5FF9FFFF7FE4B -:1022A000FFBFFE6FFFFFFBFFFFFFAFFFFFFF7FFBE7 -:1022B000FFFEFFFFFFFFFFFDDFFFFFF7FFFFFFDF79 -:1022C000FFFFFF5FFFFFFFFF5FFBFEFFF837FFFF32 -:1022D000EFFF7FFEBFFFFFFEBFFFFF7FFFBFFDFFE2 -:1022E0007FFA7FFFFF6FFFFF7DFFCFFFFFFF4FFFF5 -:1022F000F2FFFFFFFFFFFABFFFAEEBFAFEBBADEB55 -:10230000FAF7AF6BFAF6BF25E9F27F45FFFFFDF75D -:10231000F7BFFFDFFFFFBFFBFFDFF3FFF73FCFFF9D -:10232000A1FFFFBFE7FFFF7FFF3DFFFFFFF7FF2F8D -:10233000FFFBF57FFE57FFFFFFFFFFFFFFFFFFF7EC -:102340003FFFFEFFFFFFFDFEF7EEAFFEEEE7FAFFF9 -:10235000FE9DF95EFEFFEBFFFFDFA7FFFFFFFCDB4B -:10236000FFFFFF7EFBFFFFEFFBFDFFDBFFFFFFEF4C -:10237000FFFFFFFDBFFEBFFF6F7FFFF7FFFFF9FF0E -:10238000F7FFBFDEF7FFFFFFFA7FFDBF5FFFFFBF75 -:10239000FFEDFFF7BFFFFFEFFFDFFFFFFFE6FFFBF4 -:1023A0007FFFFFFFFFFFF7FFFFFFFFFFFFFFEBFFD9 -:1023B000FDFFF5FFF67FDFBDCFFFFFFFFFDFFFFF74 -:1023C000FFF9FFFFFFFFFFE3FFEEBFFF7DEFFEFF23 -:1023D000FFFFBFFFFFFFFFFEFFFFFFFFE7FFB5AE01 -:1023E000FFFFB6FEBFFFFFBFFFFFFFFFFFFFFFFFC7 -:1023F000FF27FFEFFE7FDFFF7EFFFFFFFFFFFFFFF7 -:10240000FFFFFDFFF7F99FFF5FFFFFFFFFFFFF7F6C -:10241000FFFFFEFFFFFFFFFFFFFFFF0FFFE7BFFE16 -:10242000FFBFFFFFFFFFFCBFFFFFFEFFFFFFFFC47B -:102430006BFF291FFBAFFFFFFFFFFFEF1BFEFFFC42 -:102440006FFFFFFD6AF7D7F5BFFFFEFFFFFFFFFF3E -:10245000FEBFFFFFFAFFFFF7FBDDBFFFE7FFFFFF58 -:10246000FFFFFFFFFFFD7FFFFFF5FFFFF7FDB3EF6E -:10247000FD7E5DFFFDFFFFFFFD7FD2F5FB7ECBB74D -:10248000FFFFFFC6FFFDEE63FFFFFFFFFFF6FD65E9 -:102490005BDFFFD5FFFFFFF6E7BFF7A9FFFFEDFF0B -:1024A000FFFFFFFFEBFFFFFFAFFFFFFFF81BFFE3A7 -:1024B000D0BFFFE1FFFFFFFFFFD7FFFFFF5FFFFF81 -:1024C000FFFFAFFFDB76BFFF7FFFBFEFFEFFBFEF7A -:1024D000FBFEFFFFFFBFF27FFF9FFEBDFE7FFFFF02 -:1024E000FFFFFFFFFFFFFFFFFFF73FEC7FF695BB0E -:1024F000EFF8FEFCBF2FDAFCBF2FCBF2FCBFEFFFE3 -:10250000A9BFCFFBFFFFFFFEDDB76DF6D9B66D9B10 -:1025100076D9BFFBFDA3FFBFEFFFEFFFFFFF7FDF1C -:10252000FDEF7BDEF7FDEF7FFFFF05FFFAFE7FEF9C -:10253000E3FFFFFD7FFFFFFFFF5FFFFFFD7FFBAFBF -:10254000FF63C8FFBFEFFFFFFA7FFFFFFFFE9FF7AC -:10255000FFFABFFE9FFB7FFFFFEFD7FFFFF5FFFFF7 -:10256000FFFFFD7FFFFFBFFFF9BFFFBE279FE7F91A -:10257000FE7F8BE7FE7F9FE2F9FE7F9FE7F17FFF03 -:10258000FFFFFBFEFFFFFFD7FFFFFFFFF5FFFFFF92 -:10259000D7FFFAFFFEFFFFFFFDFFFFFFAFF7FFFFD3 -:1025A000FFEBFFFFFFAFFFC4FFF7FFFFEFFFFFFFF2 -:1025B000FF5FFFFFFFFFD7FFFFFFFFFFEBFFFB7A90 -:1025C000DFF7FDFFFFFEBFFFFF7FFFAFFFFFFFF75E -:1025D000EFE3FFDDD2FFDFFFFFF2FCBFCBF6FDBF75 -:1025E0002FCBFF7FDFDEAFFFDAEEBFAFE9FAF4BD3E -:1025F000AF5AAEBBAB6BDADEBFADD75EFFFFBFFC41 -:10260000FFDFFDFFFFFFFFDFF7FFFFFFFFFDFFFA2B -:102610001FFFFEFBEFBFFDFFFDBD77FFFFFFFF9D2F -:10262000EFFFFFFFEF7DFFFBFEEFFFFFFFFFFFF779 -:10263000FFFFFFFFFFFFFFEEBFE4FBFFFE3FFEFFDC -:10264000FFFFFFAFEAFEBFAFEBFAFEFFFFFF55F65D -:10265000FFFEF7FF7FFFEBF75FC5FD7F5FD7F5FF5D -:102660006FFBFF8AFFFFFFFFEBFFFFFFFFFBBFBF1B -:10267000EFFBFFFFFFFFFBFF77DFFBFFFD7FEFFFC0 -:10268000FFFFBF7FFFDFBFFFFBFFFFFFFEEFDFFFAF -:10269000FEFF9FEF7DFFF7FF7FFFFFDFF7FDFFEFFF -:1026A000DFFFDFFFFFFFFFFFFFFFFFFFFDFFFFFB80 -:1026B000FDFFBFDFD1FFF83BFFFFFFFFFFFFFFFF85 -:1026C0007EDBFDFF77DBB77DBFFBFFF87FED7B5E39 -:1026D000FFFEFFFF4FD7FD7FDFD7F5FF7FFFFFFF37 -:1026E000F23FFEFFBFFFFFFFFFBFEFFEFF3BEEFF2E -:1026F000FCEFFFFFFF85FFFDFEFFF5FFFFFEFFDFA5 -:10270000FBFF5FBFFFFDFFFFFFFFA8FFFF9F9EFFD7 -:10271000FFFF7FF3FFFFCFFFF7FDFF7FFFFFFC16FB -:10272000BFCFA3E5EF7FFFF3E4FFCF93FCFF3FCFE5 -:10273000FFFFFFD60F7DBF6EFBF4FCAF6DDB77B7FD -:102740006DDBF6FDBFFFFFFFBF9BFADEB7B7EDF90C -:102750007EB7ACEBD6B3ADEB7ADFFFFFFFD8BFFFA0 -:10276000B7ED9F6FDDF768DB37B36CDB36CDB37F3A -:10277000FF7FF56FFDEF793DF793E47A9EADEA7A3E -:102780009EF7BDEFFFFFFF767FFBC6FFBBEFDAFED4 -:10279000FDBFFBFEFFBFEFFBFFFFFBFFA5FFFDAB98 -:1027A0006F78DE178F79DFFDFF7FDFF7FDFFFFFB1F -:1027B000FFFBFFEFFBEFFBFEFFBBDAF3EF3BCEF3DC -:1027C000BCEF3FCFDFFFB7FFFFFFCF73FFBFEFFFD0 -:1027D000F3FF3FCFF3FCFF3DCF9FFE07FFAFEBFEC4 -:1027E000FDBFEFEBFAFFAFEBFAFEBFAFFBFE3FFB27 -:1027F0009BFF7FDFFFF3FEFFDEF7BF7BDEF7BDEF62 -:102800007BFEFFFFDF3FFEFFB7FFEFF7FFBFEDFEF1 -:10281000DFB7EDFB7EDFFFFFFFFD5FEFEBFAFEF5BD -:10282000BF6FFFFFFFFFFFFFFFFFFFFEF8FFA8FFE7 -:10283000FFBFEFFB6AFBB7EFFBFFBFEFFBFEFFBF86 -:10284000EFFBFFE0FFFFFD7F5CD77DDFF35CF5CDA5 -:10285000735ED7B5FD7FEFFFDBFFFFE2F8BE2F8F82 -:10286000E7F8BE6BE2F8BE2F8BE2F9FE7FE7FFD7F9 -:10287000F5FD7FFFF7F5FD7FD7F5FD7F5FD7F5FF0E -:10288000FFFF8FFFAFEBFAFFFFBFEBFAFF2FEBFA73 -:10289000FEBFAFEBFFFFFE5FFF5FFFFFFDFFFFD758 -:1028A000FFFFFFFFFFFFFFFFFFFFFFFFBFFEB7FDC3 -:1028B000FF7EDFF7ADFF7FF7FDFF7FDFF7FDFF7FD7 -:1028C000F67FFFFFFFDBF6FCAFFFFFFFFFF7FFFF29 -:1028D000FFFFFFFFFFECBFFFAFEBFAF6AB8FEBFAAA -:1028E000F7A5EBFABEBFAFEBFAFF6DFFFF7FDF335B -:1028F000DDFF7FFEF7FC7FFBFFFFFFFFFFFFFFA970 -:10290000FFFDFFFFFEFFFFDFFFFFEFEFFDFF7FFF9C -:10291000FFFFFFFEA7FFFFFF77DFF7FD9F7FFE773B -:10292000EFFFFFFFFFFFFFFFFFAFBFAFFFF9BEBF2E -:102930008FFBFEFEEFFBFEFFBFEFFBFFFFFDDF6F38 -:10294000EFFF7FFFBFBFDFFFFCFFDFF7FDEF7FDFA4 -:10295000FFFFFF3FF6FFCFFFDBFBF7FFEB7AFFFF49 -:10296000FFBFEFFBFFFFFFFE6DFDFF5FFBFFFFF70C -:10297000FF5FF5FFFFFFFFFFFFFFFFFFF8FFFBFF1C -:10298000FFFDFFFFFFFFE7F6BFFFFFFFFFFBFFFFBE -:10299000FFC9FFFFFFBDFFBFAFEFEF3FD1FC7FFBE4 -:1029A000C7FFFFFFFFFFE3FFFFFFFFFDFFFF77FF15 -:1029B000DFB7FDF7FDF7FFFFFFFFFF57FFF7A5FDAF -:1029C0003FDFBFBFFE7FFFFFFFDFFAFDFFFFFFFE20 -:1029D00087FFE9FFFEEFBFEFFEFEFFEFFFFFFFFF08 -:1029E000FFFFFFFFFA9FFF3FFFFDFD57DFFDF3FFF6 -:1029F000DFFDFF5FDFF5FDFFFFF98FFFFFFFEE7FDC -:102A0000FFFFBF5EFEECFB3F7F9FEFF9FFFFCD6B4B -:102A1000FFFFFFC5F3FCFA38FFAF3FEE7F9FFFD902 -:102A2000FFFFFD7AF7FFF3FFAF6FDBF2B9E9FBFFC2 -:102A3000FFFFFEFFFFEFFFFBC5BFFFEFFF5EB7AD80 -:102A4000CD797CFFFFFFFFFFFFFFFFFFFD93FFEF4F -:102A5000EAFEBFEF5BD2CDF56D77DFF7FDFF7FDFDD -:102A6000FFFF66FFD5657D5F759D657FD6FB4FFFD8 -:102A7000FFFFFFFFFFFFF6C7FFBFEFFAFEFFBFEB51 -:102A8000FFDFFF7EFFFFEFFD7ED7FF78DFFF5FDF19 -:102A9000F5BF7FDFC5FF3FF67EFF0FEFF23EBFFFC2 -:102AA000FB3FFFFB7FFFB3FEFBF6FDFFDAF7FDFF09 -:102AB0007FDFF7BFFFFA7FFFFFFFFF9FFFF3DCF928 -:102AC000BFCEE7F9FE7F9FE7FFFFE27FFEFFBFEF8C -:102AD000EBFAFF9F671EFF8FE7F8FE7F8FEFFFBDCA -:102AE000BFFFFBFFFFDFF7FFFCFFBFFFFFFFFFFFA5 -:102AF000FFFFFFFDB3FFFFEFFFFFBFEDFFFBEEFEAC -:102B0000FFFFEFFFFEFFFFFFFFB5FFB7FDFD6EFF0D -:102B1000FFFEFD2FD8FEBF8FEBF9FE3FFFFACFFF80 -:102B2000E7D9FABFDF77FCFB3FABFEFFBFEFFBFE51 -:102B3000FFFFEE1FFFDFF7FFFFFF5F9735BF5EFE72 -:102B4000BFEFFFF7FDFFFFFABFFFBE6F9FE7F8BEC5 -:102B50002F8B66947D9DE7F9FE7F9FE7F17FFFFF56 -:102B6000FFF7F5FD7F5FFBFD9EFFFBFEFFFFEFFF25 -:102B7000FFA0FFFFFFBFEFEBFAFEBFB7F7F7FFFFC6 -:102B8000FDFFFFFFFFFFDDFFFDFFFFFFD7FFFFFFA3 -:102B90007FF5FFFFEFFFFFFFBFFFFFABFEFBFEFF79 -:102BA000F7AFFFFFDEF7EB5FDFF7FDFF7FDFFFFF34 -:102BB000B3FFC9FEFFFFFFFFD6FFFFCBFFFFDFFF25 -:102BC000FFFFFFFFFC8FFFBABEBFAFEB78FEB7ADD4 -:102BD0003AFEB7AFEB7AFEBFAFFF9FFFFFDFFCFF10 -:102BE000FFFEC3FEFFFF33FCFFBFDFF3FFFFBB9F12 -:102BF000FFFFFFEBDFFFFFAFF76FF9BFEFFDFFFF59 -:102C0000FFFFFFE37FFFFFFFFBFFFFBFFDFBF7FFC2 -:102C1000DFF7FFFEEF5FBDFFFAFFF8FFBFAFFBFE80 -:102C2000FE3FEFE8FFDFF3FDFFFFFFFFFFEDFFFBE0 -:102C3000FDFFAFFFFFFEFEBFDBFFFFFFBFFFDFFFBC -:102C4000FDFFCBFFFFFFFFFFBF6FFF7FB7B3FFFFAE -:102C5000DFFFFBEFFFFFFF07FFFBFFFFFFEDFFF5D0 -:102C60007CFF7FFEFFFFEFCFFFFBFFFF2FFFFFFF8C -:102C7000FFF3FFFBFFFEFFFFFFFFFFFFBFFFFFFFB5 -:102C8000FD1BFFFFFFFFFFFFFFFFFE7CFFFFFFFFBE -:102C9000EFFFFFFFFFFBBF7FFDFFFFFFFFFFFFFF1A -:102CA000DBFFFFFFFFFFFFFDFFFFF07FFFFFFFFFE9 -:102CB000FFFFFFFFFFFBFFDFFFFFFFFFFFFDBFFE8B -:102CC0007FFFFFFFFFFFFFFFFFEFFEFFBFFFFFFFE5 -:102CD000FFFFEFFAB5FFFFFFF7F7FFFFFFFFDFFB97 -:102CE000FCFFFFFEFF7FDFBFFFCBBFF9FE7F9FE74B -:102CF000F9FE7F97E1FE799FE7FDFE7FDFFE37FF5C -:102D0000FBDEDEBDEFF3FEFBAFEBFEFFFFCFFFFE12 -:102D1000FFBFFF8FFFEFFBFEFFBFE7F95E7FEFFB1B -:102D2000DAFFBFEFFBFEFFFD1FFFFFFFFFFFFFDF2F -:102D3000FFFF7FFFFFF7FB7FFFFFFFFFFC3FFFBFB2 -:102D4000EFFBFEFFBFEF7B7FBFEFFBFEFFB5EFFBAF -:102D5000BFFA7FFCFF3FCFF3FCFF3FCFBCFF3FEF4D -:102D6000F3FCFE3FCFFFEEEFFBFEFFBFEFFB6AD7AA -:102D7000B7FBF8FFB7EFBAFEFFBF7FE9FFF97E5F51 -:102D800097E5F9FE7FBFF97E5F9FE5FBFE5FB7FF2A -:102D9000A3FFF7FDFF7FDFF7FDFF5EF77DFF77DF26 -:102DA000F7FDFF7FFFD7FFFFFFFFFFFFFDDFFB7F8B -:102DB000FFFFEFFFFEFBFFFFBFFE8FFFDFF7FDFD15 -:102DC0007FDFF7FD3EDFF5BDFF7FDFF7FDF7FF9FFC -:102DD000FFFFFFFFFFFFFFFFFFFDFFBEFFFFFFFF46 -:102DE000FFFFFFFD3FFFDFF7FDFF7FDFF7FDFFCFB9 -:102DF00077FCFF5FDFF7FDFFF47FFFFFFFFFFFFFC3 -:102E0000FFFFFFFFFFFFFFFFFFFDFFFFFFEEFFFFE5 -:102E1000FFFFFFFFFFFFFFFFEDFBFFFFBFFFFFFF18 -:102E2000FFFFE9FFFFFFFFFFFFFBFFFFFFD3FFFFF8 -:102E3000BF3FFBFFFFFFFBF3FFFFFFFFFFFFFFFFB6 -:102E4000FFFFFFFFFFFEFFF7FFFFFFFF17FFFFFF83 -:102E5000DFFFFDFFFFFFFFFFDFDFFFFDFFFFDFF70E -:102E6000FF4FFFFFFFFFFFFFFFFFFFFEFFFFFFFD25 -:102E7000FFFFFFFFFEFF9FFFFFFFFFFFFFFFFFFFC3 -:102E8000FDFFFFFFFFFF7FFFFFFF7A3FFFFFFFFF19 -:102E9000FFFFFF7FFFFFFFFFFFFFFFFFFFFFFFF2CF -:102EA0007FFFFBFEFFBFEFF8FEFFBFFBFEFF8FECD7 -:102EB000FBFEFFBFF8F7FEFFBFEFFBFEFDBFCFEC51 -:102EC000FF3FEFDBF8FFBFCFFFF9FFFFBFFFFBFFC7 -:102ED000FFFFEFFBDFFFFFFFFFFFBFFFFFFFBBFFBA -:102EE000EFFBFEEFBFEEEBFBFEFFEFFEEEBFFEEBF8 -:102EF000FFEFFF17FF7EEBBBFEBFBEFBEF5BF7BD37 -:0A2F0000FBCFBFBFBBFB7ECCEFFF91 -:00000001FF - - * Copyright (C) 1999 BayCom GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that redistributions of source - * code retain the above copyright notice and this comment without - * modification. diff --git a/firmware/dabusb/firmware.HEX b/firmware/dabusb/firmware.HEX deleted file mode 100644 index 7c258df2b0a..00000000000 --- a/firmware/dabusb/firmware.HEX +++ /dev/null @@ -1,649 +0,0 @@ -:02000000215786 -:0300030002016691 -:03000B0002016689 -:0300130002016681 -:03001B0002016679 -:0300230002016671 -:03002B0002016669 -:0300330002030FB6 -:03003B0002016659 -:03004300020100B7 -:03004B0002016649 -:0300530002016641 -:03005B000204BDDF -:0300630002016730 -:03010000020C5A94 -:030104000201ED08 -:030108000202519F -:03010C0002027C70 -:030110000202E404 -:0101140032B8 -:0101180032B4 -:03011C000205FDDC -:03012000020000DA -:03012400020000D6 -:0301280002043C92 -:03012C0002046A60 -:03013000020000CA -:03013400020000C6 -:03013800020000C2 -:03013C00020000BE -:03014000020000BA -:03014400020000B6 -:03014800020000B2 -:03014C00020000AE -:03015000020000AA -:03015400020000A6 -:0A01570075817FE5826003020161FB -:0501610012076F21648C -:010166003266 -:0E016700C0D0C086C082C083C0E0907F97E009 -:0E0175004480F0907F69F0F0F0F0F0F0F0F0D0 -:0E018300F0F0F0F0F0F0F0F0F0F0F0F0F0F04E -:0E019100F0F0F0F0F0F0F0F0F0F0907F97E07A -:03019F00557FF099 -:0E01A200907F9AE030E423907F68F0F0F0F058 -:0E01B000F0F0F0F0F0F0F0F0F0F0F0F0F0F021 -:0E01BE00F0F0F0F0F0F0F0F0F0F0F0F0F0F013 -:0E01CC00E5D8C2E3F5D8D0E0D083D082D0864B -:0301DA00D0D03250 -:0801DD0075860090FFC37C054C -:0701E500A3E582458370F9D8 -:0101EC0022F0 -:0E01ED00C0E0C0F0C082C083C002C003C0D01A -:0E01FB0075D000C086758600E591C2E4F591CE -:0D020900908800E0F541907FAB7402F0900A -:090216007FAB7402F0E5326021B7 -:04021F007A007B00E6 -:0B022300C3EA9418EB64809480501232 -:0E022E00907F69F0F0F0F0F0F0F0F00ABA0006 -:02023C00010BB4 -:02023E0080E35B -:02024000D08666 -:0E024200D0D0D003D002D083D082D0F0D0E054 -:01025000327B -:0E025100C0E0C0F0C082C083C0D075D000C035 -:0E025F0086758600E591C2E4F591907FAB7440 -:04026D0004F0D08643 -:0B027100D0D0D083D082D0F0D0E0329B -:0E027C00C0E0C0F0C082C083C002C003C00456 -:0E028A00C005C006C007C000C001C0D075D0BE -:0D02980000C086758600E591C2E4F59190E6 -:0C02A5007FAB7408F0756E00756F0212DC -:0602B1001144757039755F -:0602B700710C75720212C9 -:0C02BD001175907FD6E4F075D820D08633 -:0E02C900D0D0D001D000D007D006D005D00490 -:0D02D700D003D002D083D082D0F0D0E0322E -:0E02E400C0E0C0F0C082C083C0D075D000C0A2 -:0E02F20086758600E591C2E4F591907FAB74AD -:0403000010F0D086A3 -:0B030400D0D0D083D082D0F0D0E03207 -:0E030F00C0E0C0F0C082C083C002C003C004C2 -:0E031D00C005C006C007C000C001C0D075D02A -:0C032B0000C086758600756E00756F02BC -:0703370012114475704075BE -:06033E00710C7572021241 -:0E0344001175907FD67402F0907FD67406F08B -:0503520075D810D086F3 -:0E035700D0D0D001D000D007D006D005D00401 -:0D036500D003D002D083D082D0F0D0E0329F -:0D037200907FA57480F0907FA6749AF01221 -:0C037F00101B907FA6E542F012101B90AE -:0D038B007FA6E543F012101B907FA5744083 -:01039800F074 -:010399002241 -:0D039A00907FA57480F0907FA6749AF012F9 -:0C03A700101B907FA6E544F012101B9084 -:0C03B3007FA6E545F012101B907FA6E528 -:0B03BF0046F012101B907FA57440F068 -:0103CA002210 -:0A03CB0075440275450075460012E6 -:0903D500039A75420375430012FE -:0203DE000372A8 -:0103E00022FA -:0C03E100908800E536F09088007410252C -:0903ED0036F01201DD75420175C4 -:0903F600431812037275440275EC -:0903FF00450075460012039A75D1 -:08040800420375434412037224 -:0104100022C9 -:0E041100C0E0C0F0C082C083C0D075D000C073 -:0E041F0086758600E591C2E4F591907FAA747F -:04042D0002F0D08683 -:0B043100D0D0D083D082D0F0D0E032D9 -:0E043C00C0E0C0F0C082C083C0D075D000C048 -:0E044A0086758600E591C2E4F591907FA97455 -:0704580004F0753001D086AD -:0B045F00D0D0D083D082D0F0D0E032AB -:0E046A00C0E0C0F0C082C083C0D075D000C01A -:0E04780086758600E591C2E4F591907FAA7426 -:0704860004F0753101D0867E -:0B048D00D0D0D083D082D0F0D0E0327D -:0E049800C0E0C0F0C082C083C0D075D000C0EC -:0C04A60086758600E591C2E5F591D086D0 -:0B04B200D0D0D083D082D0F0D0E03258 -:0E04BD00C0E0C0F0C082C083C0D075D000C0C7 -:0C04CB0086758600E591C2E7F591D086A9 -:0B04D700D0D0D083D082D0F0D0E03233 -:0C04E200907FEAE0FA8A20907F96E4F018 -:0104EE0022EB -:0704EF00907FEAE0FA8A2188 -:0104F60022E3 -:0E04F700901713E0FA901715E0FB74802AFAB4 -:0E05050074802BFBEA0303543FFCEAC423542A -:0E0513001FFA2CFAEB0303543FFCEBC42354F5 -:0B0521001FFB2CFB90170AE0FC60029F -:02052C007A0053 -:07052E0090170CE0FC6002D5 -:020535007B0049 -:0B053700EA2BFCC313F53A7544028B5D -:07054200458A4612039A7579 -:090549006E08756F001211447573 -:040552007047757108 -:080556000C757202121175858B -:05055E003A731211A028 -:010563002275 -:0E056400907F96E0FA907F9674806502F0908A -:0E0572007FEBE0FA907FEAE0FB907FEFE0FC89 -:0E0580003395E0FD8C057C00907FEEE0FE33AD -:0E058E0095E0FFEC2EFCED3FFD907FE9E0FED6 -:05059C00BE0102800316 -:0305A1000205F957 -:0605A400BC0121BD001E98 -:0E05AA00EAC40354F8FCEB25E0FD2C2400FC11 -:0E05B800E43417FD907EC0E0FE8C828D83F04F -:0205C600803182 -:0E05C800EAC40354F8FAEB25E0FB2AFA2400FB -:0E05D600FBE43417FC907EC0E0FD8B828C832A -:0E05E400F074012A2400FAE43417FB907EC163 -:0705F200E0FC8A828B83F01C -:0305F90075380151 -:0105FC0022DC -:0E05FD00C0E0C0F0C082C083C002C003C004D2 -:0E060B00C005C006C007C000C001C0D075D039 -:0D06190000C086758600E591C2E4F5919061 -:0D0626007FAA7401F0120564753700D086BC -:0E063300D0D0D001D000D007D006D005D00422 -:0D064100D003D002D083D082D0F0D0E032C0 -:0E064E00907FEBE0FA907FEAE0FB907FEEE019 -:0E065C00FC3395E0FD907F96E0FE907F967453 -:0E066A00806506F0907F007401F0EAC403542E -:0E067800F8FEEB25E0FB2EFE2400FBE4341719 -:0E068600FF8B828F83E0FB74012E2400FEE4C4 -:0E0694003417FF8E828F83E0FE907FE9E0FF37 -:0306A200BF810A0B -:0A06A500907F00EBF0907F01EEF073 -:0806AF00907FE9E0FBBB821A19 -:0306B700BA010C79 -:0C06BA00907F00E4F0907F01E4F0800BE2 -:0B06C600907F00E4F0907F0174B5F01D -:0806D100907FE9E0FBBB831BF5 -:0306D900BA010D56 -:0D06DC00907F007401F0907F01E4F0800B2E -:0B06E900907F00E4F0907F017412F09D -:0806F400907FE9E0FBBB841CD0 -:0306FC00BA010D33 -:0D06FF00907F007401F0907F01E4F0800C0A -:0C070C00907F007480F0907F017401F079 -:05071800907FB5ECF03C -:01071D0022B9 -:0C071E0075360D908800741DF0756B801E -:0A072A00756C3C1210E2756B8075CF -:090734006C0F1210E2756B807568 -:09073D006C061210E2756B807568 -:070746006C011210E27A00C1 -:03074D00BAFF00F0 -:02075000500A4D -:0A075200C0021201DDD0020A80F19E -:0A075C00756B80756C3C1210E2759D -:080766006B80756C0F1210E2AC -:01076E002268 -:0E076F00907FA1E4F0907FAF7401F0907F9234 -:0E077D007402F0758E3175892175880075C87B -:0E078B0000758D4075984075C04075870075EB -:0907990020007521007522007595 -:0507A200230075470073 -:0707A700C3E5479420501147 -:0D07AE00E5472400F582E43417F583E4F0FC -:0407BB00054780E886 -:0907BF00E4F540F53FE4F53CF5DA -:0707C8003BE4F53EF53D7531 -:0B07CF003200753700753900907F93F1 -:0E07DA00743CF0907F9C74FFF0907F967480CA -:0E07E800F0907F947470F0907F9D748FF0906D -:0E07F6007F97E4F0907F9574C2F0907F987426 -:0E08040028F0907F9E7428F0907FF0E4F09032 -:0E0812007FF1E4F0907FF2E4F0907FF3E4F0E9 -:0E082000907FF4E4F0907FF5E4F0907FF6E432 -:0E082E00F0907FF7E4F0907FF8E4F0907FF90F -:0E083C007438F0907FFA74A0F0907FFB74A0E7 -:0E084A00F0907FFC74A0F0907FFD74A0F09001 -:0E0858007FFE74A0F0907FFF74A0F0907FE010 -:0E0866007403F0907FE17401F0907FDD7480E8 -:0B087400F012124312071E7A007B00F6 -:09087F00C3EA941EEB940050172B -:0C088800908800E0F54790880BE0F547F1 -:09089400907F68F00ABA00010B24 -:02089D0080E0F9 -:0C089F001203E1907FD6E4F07A007B00A9 -:0D08AB008A048B05C3EA94E0EB942E501AEA -:0E08B800C002C003C004C0051201DDD005D08F -:0A08C60004D003D0020ABA00010BAF -:0208D00080D9CD -:0D08D200907FD67402F0907FD67406F090EF -:0E08DF007FDE7405F0907FDF7405F0907FAC33 -:0E08ED00E4F0907FAD7405F075A88075F810EA -:0D08FB00907FAE740BF0907FE27488F09057 -:0C0908007FAB7408F075E81175320175C2 -:0C0914003100753000C004C0051204F76B -:0A092000D005D004753400753501D0 -:0D092A00907FAE7403F08C02BA00028003CF -:03093700020A3F72 -:0C093A00853334907F9D748FF0907F9780 -:0E0946007408F0907F9D7488F0907F9AE0FA1C -:0C09540074055AF533907F9D748FF0906D -:0D0960007F977402F0907F9D7482F0E53364 -:0D096D0025E0FA907F9AE05405FB4AF5332F -:02097A00600C0F -:0C097C00907F96E0FA907F9674804AF01D -:0B098800756E00756F00C004C0051202 -:0E0993001144D005D004901713E0FA74802AA6 -:0609A100FAE533B404295D -:0309A700BAA000F3 -:0209AA005024D7 -:0D09AC00901713E004FB0B901713EBF09075 -:0E09B9001713E0FB901715F0C002C004C00534 -:0909C7001204F7D005D004D0029F -:0509D000E533B402262E -:0609D500C374049A5020D7 -:0D09DB00901713E0FA1A1A901713EAF09023 -:0D09E8001713E0FA901715F0C004C00512B7 -:0609F50004F7D005D00458 -:0509FB00E533B4081D06 -:040A0000E534701950 -:0A0A040074012535540FF5358535D2 -:0C0A0E0075757600C004C0051213FED000 -:030A1A0005D00400 -:050A1D00E533B4011DEA -:040A2200E53470192E -:0A0A2600E53524FF540FF535853542 -:0C0A300075757600C004C0051213FED0DE -:030A3C0005D004DE -:0E0A3F00C004C0051201DDD005D004907F96E2 -:0E0A4D00E0FA907F96747F5AF0907F977408BD -:0A0A5B00F0C3EC9400ED9402400893 -:080A6500907F96E0FA20E608FC -:080A6D00C3E49C74089D5013C2 -:0E0A7500907F96E0FA907F9674406502F07CC8 -:050A8300007D0080056C -:050A88000CBC00010D93 -:050A8D00E538B4010E84 -:0D0A9200C004C0051204F7D005D00475386B -:010A9F000056 -:070AA000E531700302092A91 -:0A0AA700907FC9E0FA7003020C2DE5 -:0E0AB100907F96E0FA907F9674806502F09038 -:090ABF007DC0E0FABA2C028003AC -:030AC800020B36E8 -:050ACB007532007B0004 -:030AD000BB640004 -:020AD300501CB5 -:0E0AD500C002C003C004C0051201DDD005D070 -:0D0AE30004D003D00290880FE0F5470B808F -:010AF000DF26 -:0D0AF100C002C004C00512071E1203E1126E -:0C0AFE0004F7D005D004D002756E00751E -:0D0B0A006F01C002C004C005121144D005E7 -:090B1700D004D00275704D757117 -:0B0B20000C757202C002C004C0051278 -:0B0B2B001175D005D004D002020C2D83 -:030B3600BA2A3B9D -:0D0B3900907F987420F0C002C004C0051227 -:0E0B460001DDD005D004D002907F987428F015 -:020B54007B0024 -:030B5600BB0A00D7 -:050B59004003020C2D19 -:0E0B5E00C002C003C004C0051201DDD005D0E6 -:080B6C0004D003D0020B80E26B -:030B7400BA2B1A7F -:080B7700907FC9E0FBBB4012B6 -:0E0B7F00C002C004C005121205D005D004D07B -:040B8D0002020C2D27 -:030B9100BA101F78 -:0E0B9400907F96E0FB907F9674806503F0C022 -:0E0BA20002C004C00512103DD005D004D002E0 -:030BB000020C2D07 -:030BB300BA111262 -:0E0BB600C002C004C00512106AD005D004D0E1 -:040BC40002020C2DF0 -:030BC800BA12124C -:0E0BCB00C002C004C00512108FD005D004D0A7 -:040BD90002020C2DDB -:030BDD00BA130B3D -:0B0BE000907DC1E0FB908800F0804297 -:030BEB00BA141128 -:0E0BEE00C002C004C0051211DDD005D004D035 -:030BFC0002802E46 -:030BFF00BA151D07 -:0C0C0200907DC1E0F575907DC2E0F576B4 -:0E0C0E00C002C004C0051213FED005D004D0F1 -:030C1C0002800E45 -:030C1F00BA160BF7 -:0B0C2200C004C0051213A3D005D004CD -:0B0C2D00907FC9E4F075310002092A35 -:010C38002299 -:070C3900535550454E4400E5 -:070C4000524553554D4500DC -:060C470020566F6C200036 -:0D0C4D004441425553422076312E30300094 -:0E0C5A00C0E0C0F0C082C083C002C003C0046E -:0E0C6800C005C006C007C000C001C0D075D0D6 -:0D0C760000C086758600E591C2E4F59190FE -:0E0C83007FAB7401F0907FE8E0FA907FE9E02B -:060C9100FBBB0002800322 -:030C9700020D3813 -:030C9A00BA801409 -:0E0C9D00907F007401F0907F01E4F0907FB52D -:060CAB007402F0020ECD00 -:050CB100BA820280037D -:030CB600020D1D0F -:080CB900907FECE0FCBC01009F -:020CC1004021D0 -:060CC300C374079C401BF6 -:0E0CC900EC24FF25E0FD24C6F582E4347FF51F -:0D0CD70083E0FD530501907F00EDF0802BC0 -:030CE400BC8100D0 -:020CE7004021AA -:060CE900C374879C401B50 -:0E0CEF00EC247F25E0FC24B6F582E4347FF58A -:0D0CFD0083E0FC530401907F00ECF08005C3 -:050D0A00907F00E4F001 -:0E0D0F00907F01E4F0907FB57402F0020ECDEB -:050D1D00BA8102800311 -:030D2200020EC5F9 -:0E0D2500907F00E4F0907F01E4F0907FB574C1 -:050D330002F0020ECDEC -:030D3800BB012DCF -:060D3B00BA0003020ECD18 -:030D4100BA0211E2 -:0D0D4400755900C002C003120EF0D003D09C -:040D510002020ECDBF -:050D5500BA2102800339 -:030D5A00020ECDB9 -:0B0D5D00753701907FC5E4F0020ECD59 -:030D6800BB031FAB -:060D6B00BA0003020ECDE8 -:050D7100BA020280033C -:030D7600020ECD9D -:0D0D7900755901C002C003120EF0D003D066 -:040D860002020ECD8A -:030D8A00BB065451 -:050D8D00BA80028003A2 -:030D9200020EC589 -:080D9500907FEBE0FCBC0115AE -:0C0D9D007CFB7D0F8D067F00907FD4EE64 -:090DA900F0907FD5ECF0020ECDB4 -:0A0DB200907FEBE0FCBC020280031E -:030DBC00020EC55F -:0A0DBF00907FEAE0FCBC0002800314 -:030DC900020EC552 -:0C0DCC007C3B7D0F8D067F00907FD4EEF5 -:090DD800F0907FD5ECF0020ECD85 -:060DE100BB0703020EC572 -:030DE700BB081036 -:0D0DEA00AC48907F00ECF0907FB57401F0F4 -:030DF700020ECD1C -:030DFA00BB093101 -:050DFD00BA00028003B2 -:030E0200020EC518 -:0E0E0500907FEAE0FCC374019C5003020EC50E -:080E1300907FEAE0FCBC000A3C -:0A0E1B00901721E4F0901722E4F094 -:090E2500907FEAE0F548020ECDD1 -:030E2E00BB0A27D5 -:050E3100BA81028003FC -:030E3600020EC5E4 -:0E0E3900907FECE0FA2420FAE43417FC8A8261 -:0E0E47008C83E0FA907F00F0907FB57401F08C -:030E5500020ECDBD -:050E5800BB0B0280034A -:030E5D00020EA9D9 -:0D0E6000901720E4F0907FECE0FABA011A40 -:080E6D00907FEDE0FABA0012DB -:0E0E7500907FEAE0FA901721F0C0031204E229 -:040E8300D0038046D2 -:080E8700907FECE0FABA023E94 -:080E8F00907FEDE0FABA003695 -:0D0E9700C0031204EFD003907FEAE0FA9050 -:050EA4001722F080247C -:050EA900BB12028017DE -:050EAE00BB8102800D74 -:050EB300BB8302800872 -:050EB800BB8202800373 -:030EBD00BB8405EE -:050EC00012064E80083F -:080EC500907FB47403F0800675 -:060ECD00907FB47402F0F6 -:020ED300D086C7 -:0E0ED500D0D0D001D000D007D006D005D00478 -:0D0EE300D003D002D083D082D0F0D0E03216 -:0B0EF000907FECE0F55AC39401401D18 -:070EFB00C37407955A40166D -:0D0F0200E55A24FF25E0FA24C6F582E43408 -:090F0F007FF583AA59EAF0802263 -:070F1800C3E55A9481401B60 -:070F1F00C37487955A4014CA -:0D0F2600E55A24FF25E0FA24B6F582E434F4 -:070F33007FF583AA59EAF0E3 -:010F3A002294 -:0E0F3B000902BA000301004000090400000092 -:0E0F49000101000009240100013D0001010C1E -:0E0F570024020110070002030000000D240612 -:0E0F650003010215000300030000092403022B -:0E0F7300010100010009240304020300030031 -:0E0F8100092403050306000100090401000015 -:0E0F8F00010200000904010101010200000737 -:0E0F9D002401020101000B24020102021001D6 -:0E0FAB0080BB00090588050001010000072534 -:0E0FB900010000000009040200020000000018 -:0E0FC7000705820240000007050202400000FC -:0E0FD50009040201030000000007058202402B -:0E0FE30000000705020240000009058905A074 -:0A0FF1000101000000FFFFFFFF00F8 -:0E0FFB00120100010000004047059999000115 -:0E10090000000001000000000000000902BA13 -:0410170000030100D1 -:02101B007A0059 -:03101D00BA050011 -:02102000501767 -:08102200907FA5E0FB30E00522 -:05102A00900001800DA3 -:0A102F00C0021201DDD0020A80E4C5 -:0310390090000123 -:01103C002291 -:0E103D00907DC1E0F9A3E0FAA3E0FB7C007D0A -:04104B007EEB6012C6 -:0E104F0089828A83E0A3A982AA838C828D8382 -:04105D00F00CDBEECA -:08106100907DC3E0907FB9F01F -:011069002264 -:0E106A00907DC1E0F9A3E0FAA3E0FB7CC47D19 -:041078007DEB60E5C7 -:0E107C008C828D83E00C89828A83F0A3A98286 -:04108A00AA83DBEE6C -:01108E00223F -:0E108F00907FA57480F00586907DC1E00586F7 -:0E109D00A3F012101B907FA60586A3A3E0F916 -:0510AB006016A305869C -:0D10B000907FA60586E0A30586F0C0011222 -:0610BD00101BD001D9ED6B -:0610C300907FA57440F0CF -:0110C9002204 -:0810CA009088027401F07A0025 -:0310D200BAFF0062 -:0210D500500ABF -:0A10D700C0021201DDD0020A80F110 -:0110E10022EC -:0510E200E56BB4C0083D -:0810E700908803E56CF080061F -:0610EF00908802E56CF0A0 -:0410F5007A007B0002 -:0B10F900C3EA9432EB6480948050073F -:051104000ABA00010B16 -:0211090080EE76 -:01110B0022C1 -:0A110C00908803E56DF005397A00C4 -:03111600BA2800F4 -:02111900500381 -:03111B000A80F84F -:05111E00E539B41008E2 -:0811230090880274C0F0800EF8 -:05112B00E539B42009C4 -:091130009088027480F07539000A -:021139007A003A -:03113B00BA2800CF -:02113E0050035C -:031140000A80F82A -:011143002289 -:04114400E56F6002F1 -:0211480080071E -:07114A007A007539008005F1 -:051151007A4075391021 -:09115600E56E2AFAE56E2539F573 -:0A115F003990880274802AF07A00AB -:08116900C3EA648094A850035E -:031171000A80F5FC -:011174002258 -:06117500AA70AB71AC7220 -:0C117B008A828B838CF01214EEFD601849 -:0D1187008D6DC002C003C00412110CD00415 -:09119400D003D0020ABA00010BDD -:02119D0080DCF4 -:01119F00222D -:0D11A000E573C4540FFA53020FC374099A8B -:0211AD005006EA -:0611AF0074372AFB8004E6 -:0411B50074302AFB6D -:0C11B9008B6DC00312110CD003AA7353FD -:0811C500020FC374099A5006E1 -:0611CD0074372AFB8004C8 -:0411D30074302AFB4F -:0511D7008B6D12110CEC -:0111DC0022F0 -:0711DD00907DC3E0FA600FF2 -:0C11E400907DC1E0F56E907DC2E0F56FDB -:0311F00012114495 -:0C11F300907DFFE4F07570C475717D758F -:0511FF007201121175E0 -:0112040022C7 -:021205007A0469 -:03120700BA4000EA -:02120A0050365C -:0E120C00EA24C0F582E4347DF583E0FB7C002B -:03121A00BC08000D -:02121D0050205F -:06121F008B05ED30E70B2A -:0B122500907F967442F074C3F08008C4 -:08123000907F96E4F07481F058 -:07123800EB25E0FB0C80DB5D -:03123F000A80C55D -:011242002289 -:041243007A007BEFC3 -:03124700BA1000DA -:02124A00502032 -:0E124C0074112BFB2400FCE43418FD8C828D01 -:0E125A0083E4F0EA2400F582E43419F583E41D -:04126800F00A80DB2D -:01126C00225F -:0E126D0074F82400F58274033484F583E4F0F1 -:0E127B0074F92400F58274033484F583E4F0E2 -:0E12890074FA2400F58274033484F583E4F0D3 -:0E12970074FB2400F58274033484F583E4F0C4 -:0E12A50074FF2400F58274033484F583E4F0B2 -:0112B3002218 -:0E12B4001203CB12126D7AC07B877C0174018D -:0E12C2002AFDE43BFE8C078A828B838CF0743D -:0E12D000011214BF2DFAE43EFB8F048D828EB6 -:0E12DE00838FF074061214BF74012AFDE43BE6 -:0E12EC00FE8C078A828B838CF0E41214BF7490 -:0E12FA00012DFAE43EFB8F048D828E838FF06F -:0E130800740B1214BF74012AFDE43BFE8C0727 -:0E1316008A828B838CF074081214BF74012D30 -:0E132400FAE43EFB8F048D828E838FF07401FD -:0E1332001214BF2AFDE43BFE8C078A828B83D7 -:0E1340008CF0E41214BF74012DFAE43EFB8F12 -:0E134E00048D828E838FF074031214BF7D0015 -:03135C00BD0600CB -:02135F0050122A -:0B1361008A828B838CF00ABA00010B1B -:07136C00E41214BF0D80E93B -:0D1373008A828B838CF0E5741214BF74F92C -:0E1380002400F58274033484F583740FF07436 -:0E138E00FE2400F58274033484F5837401F0AC -:06139C001203E11204F748 -:0113A2002228 -:0D13A300907DC1E0FA2400FBE43419FC90B9 -:0E13B0007DC2E0FD8B828C83F075F011EAA403 -:0313BE00FA7B00B7 -:0313C100BB10005E -:0213C4005024B3 -:0E13C600EA2400FCE43418FDEB2CFCE43DFDB1 -:0E13D40074042B24C0F582E4347DF583E0FE22 -:0813E2008C828D83F00B80D793 -:0E13EA00EA2400FAE43418FB74102AF582E4B9 -:0513F8003BF583E4F069 -:0113FD0022CD -:0413FE00E57660022E -:02140200801652 -:0C140400740F5575FA8A752400F582E417 -:0A1410003419F583E0F5741212B4EC -:0A141A001210CA756E00756F001203 -:0614240011447570B9755A -:06142A007114757202123C -:0B1430001175E576B402047401800120 -:01143B00E4CC -:03143C00FA700F34 -:0C143F0074012575F573C0021211A0D0D5 -:03144B0002800A12 -:0A144E00857573C0021211A0D002D0 -:0C145800756E00756F01C002121144D0C7 -:0414640002EA701A0E -:0D14680075F011E575A4FA2400FAE43418BB -:09147500FB8A708B717572011283 -:04147E00117580362E -:021482007A00EE -:03148400BA10009B -:02148700502FE4 -:0D148900EA2400F582E43419F583E0FBE568 -:0414960075B5031B0A -:0E149A0075F011EAA4FB2400FBE43418FC8B6F -:0914A800708C71757201C0021212 -:0414B1001175D002DF -:0314B5000A80CCDE -:0114B8002211 -:0614B90050726F67200075 -:0E14BF00C8C0E0C8C0E0E5F0600B14600F1478 -:0714CD00601114601280158C -:0714D400D0E0A882F6800EB3 -:0514DB00D0E0F08009E3 -:0414E000D0E08005D3 -:0514E400D0E0A882F237 -:0414E900C8D0E0C8BF -:0114ED0022DC -:0E14EE00C8C0E0E5F0600D14600F14600F142C -:0614FC00601074FF800F78 -:05150200A882E6800A4A -:03150700E080077A -:04150A00E4938003E3 -:03150E00A882E2CE -:04151100F8D0E0C866 -:0115150022B3 -:00000001FF - - * Copyright (C) 1999 BayCom GmbH - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that redistributions of source - * code retain the above copyright notice and this comment without - * modification. -- cgit v1.2.3 From c4f4925439f13a243aecfb36c693613603c0bfbd Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 20 Nov 2012 23:00:10 -0800 Subject: Input: ads7846 - enable pendown GPIO debounce time setting Some platforms need the pendown GPIO debounce time setting programmed. Since the pendown GPIO is handled by the driver, the debounce time should also be handled along with the pendown GPIO request. Signed-off-by: Igor Grinberg Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 6 +++++- include/linux/spi/ads7846.h | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index f02028ec3db..78e5d9ab0ba 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -955,7 +955,8 @@ static int ads7846_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume); -static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts) +static int __devinit ads7846_setup_pendown(struct spi_device *spi, + struct ads7846 *ts) { struct ads7846_platform_data *pdata = spi->dev.platform_data; int err; @@ -981,6 +982,9 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784 ts->gpio_pendown = pdata->gpio_pendown; + if (pdata->gpio_pendown_debounce) + gpio_set_debounce(pdata->gpio_pendown, + pdata->gpio_pendown_debounce); } else { dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); return -EINVAL; diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index c64de9dd763..2f694f3846a 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -46,8 +46,9 @@ struct ads7846_platform_data { u16 debounce_rep; /* additional consecutive good readings * required after the first two */ int gpio_pendown; /* the GPIO used to decide the pendown - * state if get_pendown_state == NULL - */ + * state if get_pendown_state == NULL */ + int gpio_pendown_debounce; /* platform specific debounce time for + * the gpio_pendown */ int (*get_pendown_state)(void); int (*filter_init) (const struct ads7846_platform_data *pdata, void **filter_data); -- cgit v1.2.3 From 0a0d62857366d8a6531e7fed1c3ccdd9a2b5b40b Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Tue, 20 Nov 2012 23:00:51 -0800 Subject: ARM - OMAP: ads7846: fix pendown debounce setting Commit 97ee9f01 (ARM: OMAP: fix the ads7846 init code) have enabled the pendown GPIO debounce time setting by the below sequence: gpio_request_one() gpio_set_debounce() gpio_free() It also revealed a bug in the OMAP GPIO handling code which prevented the GPIO debounce clock to be disabled and CORE transition to low power states. Commit c9c55d9 (gpio/omap: fix off-mode bug: clear debounce settings on free/reset) fixes the OMAP GPIO handling code by making sure that the GPIO debounce clock gets disabled if no GPIO is requested from current bank. While fixing the OMAP GPIO handling code (in the right way), the above commit makes the gpio_request->set_debounce->free sequence invalid as after freeing the GPIO, the debounce settings are lost. Fix the debounce settings by moving the debounce initialization to the actual GPIO requesting code - the ads7846 driver. Signed-off-by: Igor Grinberg Acked-by: Tony Lindgren Signed-off-by: Dmitry Torokhov --- arch/arm/mach-omap2/common-board-devices.c | 34 ++++++++++++++++++------------ 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-omap2/common-board-devices.c b/arch/arm/mach-omap2/common-board-devices.c index 48daac2581b..84551f205e4 100644 --- a/arch/arm/mach-omap2/common-board-devices.c +++ b/arch/arm/mach-omap2/common-board-devices.c @@ -64,30 +64,36 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce, struct spi_board_info *spi_bi = &ads7846_spi_board_info; int err; - err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); - if (err) { - pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); - return; - } + /* + * If a board defines get_pendown_state() function, request the pendown + * GPIO and set the GPIO debounce time. + * If a board does not define the get_pendown_state() function, then + * the ads7846 driver will setup the pendown GPIO itself. + */ + if (board_pdata && board_pdata->get_pendown_state) { + err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown"); + if (err) { + pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err); + return; + } - if (gpio_debounce) - gpio_set_debounce(gpio_pendown, gpio_debounce); + if (gpio_debounce) + gpio_set_debounce(gpio_pendown, gpio_debounce); + + gpio_export(gpio_pendown, 0); + } spi_bi->bus_num = bus_num; spi_bi->irq = gpio_to_irq(gpio_pendown); + ads7846_config.gpio_pendown = gpio_pendown; + if (board_pdata) { board_pdata->gpio_pendown = gpio_pendown; + board_pdata->gpio_pendown_debounce = gpio_debounce; spi_bi->platform_data = board_pdata; - if (board_pdata->get_pendown_state) - gpio_export(gpio_pendown, 0); - } else { - ads7846_config.gpio_pendown = gpio_pendown; } - if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state)) - gpio_free(gpio_pendown); - spi_register_board_info(&ads7846_spi_board_info, 1); } #else -- cgit v1.2.3 From 2bd6a021e887c675116ff8cdacc3af49999a2224 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:19:16 -0500 Subject: usb-core: remove CONFIG_HOTPLUG ifdefs Remove conditional code based on CONFIG_HOTPLUG being false. It's always on now in preparation of it going away as an option. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 25 ------------------------- drivers/usb/core/message.c | 9 --------- drivers/usb/core/usb.c | 9 --------- drivers/usb/serial/bus.c | 10 ---------- 4 files changed, 53 deletions(-) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 6056db7af41..88dde95b679 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -32,8 +32,6 @@ #include "usb.h" -#ifdef CONFIG_HOTPLUG - /* * Adds a new dynamic USBdevice ID to this driver, * and cause the driver to probe for all devices again. @@ -194,20 +192,6 @@ static void usb_free_dynids(struct usb_driver *usb_drv) } spin_unlock(&usb_drv->dynids.lock); } -#else -static inline int usb_create_newid_files(struct usb_driver *usb_drv) -{ - return 0; -} - -static void usb_remove_newid_files(struct usb_driver *usb_drv) -{ -} - -static inline void usb_free_dynids(struct usb_driver *usb_drv) -{ -} -#endif static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf, struct usb_driver *drv) @@ -790,7 +774,6 @@ static int usb_device_match(struct device *dev, struct device_driver *drv) return 0; } -#ifdef CONFIG_HOTPLUG static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; @@ -832,14 +815,6 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } -#else - -static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - return -ENODEV; -} -#endif /* CONFIG_HOTPLUG */ - /** * usb_register_device_driver - register a USB device (not interface) driver * @new_udriver: USB operations for the device driver diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index a557658f322..73c5d1a0413 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1540,7 +1540,6 @@ static void usb_release_interface(struct device *dev) kfree(intf); } -#ifdef CONFIG_HOTPLUG static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; @@ -1575,14 +1574,6 @@ static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } -#else - -static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - return -ENODEV; -} -#endif /* CONFIG_HOTPLUG */ - struct device_type usb_if_device_type = { .name = "usb_interface", .release = usb_release_interface, diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 7d3de09a82e..f81b9257273 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -233,7 +233,6 @@ static void usb_release_dev(struct device *dev) kfree(udev); } -#ifdef CONFIG_HOTPLUG static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env) { struct usb_device *usb_dev; @@ -249,14 +248,6 @@ static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } -#else - -static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - return -ENODEV; -} -#endif /* CONFIG_HOTPLUG */ - #ifdef CONFIG_PM /* USB device Power-Management thunks. diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index c15f2e7cefc..37decb13d7e 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -121,7 +121,6 @@ static int usb_serial_device_remove(struct device *dev) return retval; } -#ifdef CONFIG_HOTPLUG static ssize_t store_new_id(struct device_driver *driver, const char *buf, size_t count) { @@ -159,15 +158,6 @@ static void free_dynids(struct usb_serial_driver *drv) spin_unlock(&drv->dynids.lock); } -#else -static struct driver_attribute drv_attrs[] = { - __ATTR_NULL, -}; -static inline void free_dynids(struct usb_serial_driver *drv) -{ -} -#endif - struct bus_type usb_serial_bus_type = { .name = "usb-serial", .match = usb_serial_device_match, -- cgit v1.2.3 From 7690417db5085f0de03aa70b8ca01b0118e8a1b4 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:21:08 -0500 Subject: usb: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Cc: Peter Korsgaard Cc: Alexander Shishkin Acked-by: Felipe Balbi Cc: Li Yang Cc: Alan Stern Cc: Wan ZongShun Cc: Ben Dooks Cc: Kukjin Kim Acked-by: Nicolas Ferre Acked-by: Peter Korsgaard Signed-off-by: Greg Kroah-Hartman --- drivers/usb/c67x00/c67x00-drv.c | 2 +- drivers/usb/chipidea/ci13xxx_imx.c | 2 +- drivers/usb/chipidea/ci13xxx_msm.c | 2 +- drivers/usb/chipidea/ci13xxx_pci.c | 2 +- drivers/usb/chipidea/core.c | 2 +- drivers/usb/chipidea/usbmisc_imx6q.c | 2 +- drivers/usb/dwc3/core.c | 2 +- drivers/usb/dwc3/dwc3-exynos.c | 2 +- drivers/usb/dwc3/dwc3-omap.c | 2 +- drivers/usb/dwc3/dwc3-pci.c | 2 +- drivers/usb/gadget/bcm63xx_udc.c | 2 +- drivers/usb/gadget/fsl_qe_udc.c | 2 +- drivers/usb/gadget/hid.c | 2 +- drivers/usb/gadget/lpc32xx_udc.c | 2 +- drivers/usb/gadget/net2272.c | 4 ++-- drivers/usb/gadget/omap_udc.c | 2 +- drivers/usb/gadget/s3c-hsotg.c | 2 +- drivers/usb/host/bcma-hcd.c | 2 +- drivers/usb/host/ehci-atmel.c | 2 +- drivers/usb/host/ehci-msm.c | 2 +- drivers/usb/host/ehci-platform.c | 2 +- drivers/usb/host/ehci-s5p.c | 2 +- drivers/usb/host/ehci-w90x900.c | 2 +- drivers/usb/host/fhci-hcd.c | 2 +- drivers/usb/host/fsl-mph-dr-of.c | 2 +- drivers/usb/host/isp1362-hcd.c | 2 +- drivers/usb/host/isp1760-if.c | 2 +- drivers/usb/host/ohci-at91.c | 2 +- drivers/usb/host/ohci-exynos.c | 2 +- drivers/usb/host/ohci-jz4740.c | 2 +- drivers/usb/host/ohci-omap3.c | 2 +- drivers/usb/host/ohci-platform.c | 2 +- drivers/usb/host/ohci-s3c2410.c | 2 +- drivers/usb/host/ohci-tmio.c | 2 +- drivers/usb/host/r8a66597-hcd.c | 2 +- drivers/usb/host/sl811-hcd.c | 2 +- drivers/usb/host/ssb-hcd.c | 2 +- drivers/usb/host/u132-hcd.c | 2 +- drivers/usb/musb/am35x.c | 2 +- drivers/usb/musb/da8xx.c | 2 +- drivers/usb/musb/davinci.c | 2 +- drivers/usb/musb/musb_core.c | 2 +- drivers/usb/musb/musb_dsps.c | 2 +- drivers/usb/musb/omap2430.c | 2 +- drivers/usb/musb/tusb6010.c | 2 +- drivers/usb/musb/ux500.c | 2 +- drivers/usb/otg/ab8500-usb.c | 2 +- drivers/usb/otg/fsl_otg.c | 2 +- drivers/usb/otg/msm_otg.c | 2 +- drivers/usb/otg/mxs-phy.c | 2 +- drivers/usb/otg/nop-usb-xceiv.c | 2 +- drivers/usb/phy/mv_u3d_phy.c | 2 +- drivers/usb/phy/omap-usb2.c | 2 +- drivers/usb/phy/rcar-phy.c | 2 +- drivers/usb/renesas_usbhs/common.c | 2 +- 55 files changed, 56 insertions(+), 56 deletions(-) diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c index 6f3b6e26739..855d538752c 100644 --- a/drivers/usb/c67x00/c67x00-drv.c +++ b/drivers/usb/c67x00/c67x00-drv.c @@ -219,7 +219,7 @@ static int __devexit c67x00_drv_remove(struct platform_device *pdev) static struct platform_driver c67x00_driver = { .probe = c67x00_drv_probe, - .remove = __devexit_p(c67x00_drv_remove), + .remove = c67x00_drv_remove, .driver = { .owner = THIS_MODULE, .name = "c67x00", diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c index 0f5ca4bea17..565973035ca 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.c +++ b/drivers/usb/chipidea/ci13xxx_imx.c @@ -252,7 +252,7 @@ MODULE_DEVICE_TABLE(of, ci13xxx_imx_dt_ids); static struct platform_driver ci13xxx_imx_driver = { .probe = ci13xxx_imx_probe, - .remove = __devexit_p(ci13xxx_imx_remove), + .remove = ci13xxx_imx_remove, .driver = { .name = "imx_usb", .owner = THIS_MODULE, diff --git a/drivers/usb/chipidea/ci13xxx_msm.c b/drivers/usb/chipidea/ci13xxx_msm.c index b01feb3be92..406c5af2da5 100644 --- a/drivers/usb/chipidea/ci13xxx_msm.c +++ b/drivers/usb/chipidea/ci13xxx_msm.c @@ -89,7 +89,7 @@ static int __devexit ci13xxx_msm_remove(struct platform_device *pdev) static struct platform_driver ci13xxx_msm_driver = { .probe = ci13xxx_msm_probe, - .remove = __devexit_p(ci13xxx_msm_remove), + .remove = ci13xxx_msm_remove, .driver = { .name = "msm_hsusb", }, }; diff --git a/drivers/usb/chipidea/ci13xxx_pci.c b/drivers/usb/chipidea/ci13xxx_pci.c index 918e14971f2..e1cb2fb2ef3 100644 --- a/drivers/usb/chipidea/ci13xxx_pci.c +++ b/drivers/usb/chipidea/ci13xxx_pci.c @@ -147,7 +147,7 @@ static struct pci_driver ci13xxx_pci_driver = { .name = UDC_DRIVER_NAME, .id_table = ci13xxx_pci_id_table, .probe = ci13xxx_pci_probe, - .remove = __devexit_p(ci13xxx_pci_remove), + .remove = ci13xxx_pci_remove, }; module_pci_driver(ci13xxx_pci_driver); diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index f69d029b460..46f23f226ae 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -523,7 +523,7 @@ static int __devexit ci_hdrc_remove(struct platform_device *pdev) static struct platform_driver ci_hdrc_driver = { .probe = ci_hdrc_probe, - .remove = __devexit_p(ci_hdrc_remove), + .remove = ci_hdrc_remove, .driver = { .name = "ci_hdrc", }, diff --git a/drivers/usb/chipidea/usbmisc_imx6q.c b/drivers/usb/chipidea/usbmisc_imx6q.c index 416e3fc58fd..81238a46729 100644 --- a/drivers/usb/chipidea/usbmisc_imx6q.c +++ b/drivers/usb/chipidea/usbmisc_imx6q.c @@ -136,7 +136,7 @@ static int __devexit usbmisc_imx6q_remove(struct platform_device *pdev) static struct platform_driver usbmisc_imx6q_driver = { .probe = usbmisc_imx6q_probe, - .remove = __devexit_p(usbmisc_imx6q_remove), + .remove = usbmisc_imx6q_remove, .driver = { .name = "usbmisc_imx6q", .owner = THIS_MODULE, diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 516d4007dfc..cc5dac11d30 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -583,7 +583,7 @@ static int __devexit dwc3_remove(struct platform_device *pdev) static struct platform_driver dwc3_driver = { .probe = dwc3_probe, - .remove = __devexit_p(dwc3_remove), + .remove = dwc3_remove, .driver = { .name = "dwc3", }, diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index dc35c5476f3..19a98184e58 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -196,7 +196,7 @@ MODULE_DEVICE_TABLE(of, exynos_dwc3_match); static struct platform_driver dwc3_exynos_driver = { .probe = dwc3_exynos_probe, - .remove = __devexit_p(dwc3_exynos_remove), + .remove = dwc3_exynos_remove, .driver = { .name = "exynos-dwc3", .of_match_table = of_match_ptr(exynos_dwc3_match), diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 900d435f41d..afbc6e99188 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -441,7 +441,7 @@ MODULE_DEVICE_TABLE(of, of_dwc3_matach); static struct platform_driver dwc3_omap_driver = { .probe = dwc3_omap_probe, - .remove = __devexit_p(dwc3_omap_remove), + .remove = dwc3_omap_remove, .driver = { .name = "omap-dwc3", .of_match_table = of_dwc3_matach, diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 13962597f3f..b3eeec7c6bc 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -218,7 +218,7 @@ static struct pci_driver dwc3_pci_driver = { .name = "dwc3-pci", .id_table = dwc3_pci_id_table, .probe = dwc3_pci_probe, - .remove = __devexit_p(dwc3_pci_remove), + .remove = dwc3_pci_remove, }; MODULE_AUTHOR("Felipe Balbi "); diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c index 9ca792224cd..b44e43641d5 100644 --- a/drivers/usb/gadget/bcm63xx_udc.c +++ b/drivers/usb/gadget/bcm63xx_udc.c @@ -2450,7 +2450,7 @@ static int __devexit bcm63xx_udc_remove(struct platform_device *pdev) static struct platform_driver bcm63xx_udc_driver = { .probe = bcm63xx_udc_probe, - .remove = __devexit_p(bcm63xx_udc_remove), + .remove = bcm63xx_udc_remove, .driver = { .name = DRV_MODULE_NAME, .owner = THIS_MODULE, diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index b09452d6f33..21db1f71d4c 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2735,7 +2735,7 @@ static struct platform_driver udc_driver = { .of_match_table = qe_udc_match, }, .probe = qe_udc_probe, - .remove = __devexit_p(qe_udc_remove), + .remove = qe_udc_remove, #ifdef CONFIG_PM .suspend = qe_udc_suspend, .resume = qe_udc_resume, diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 74130f6c12c..33deed6e794 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -229,7 +229,7 @@ static __refdata struct usb_composite_driver hidg_driver = { }; static struct platform_driver hidg_plat_driver = { - .remove = __devexit_p(hidg_plat_driver_remove), + .remove = hidg_plat_driver_remove, .driver = { .owner = THIS_MODULE, .name = "hidg", diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index d1cf1f4db16..52ad15ce44a 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -3447,7 +3447,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_udc_of_match); #endif static struct platform_driver lpc32xx_udc_driver = { - .remove = __devexit_p(lpc32xx_udc_remove), + .remove = lpc32xx_udc_remove, .shutdown = lpc32xx_udc_shutdown, .suspend = lpc32xx_udc_suspend, .resume = lpc32xx_udc_resume, diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index c009263a47e..26c305321c4 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -2575,7 +2575,7 @@ static struct pci_driver net2272_pci_driver = { .id_table = pci_ids, .probe = net2272_pci_probe, - .remove = __devexit_p(net2272_pci_remove), + .remove = net2272_pci_remove, }; static int net2272_pci_register(void) @@ -2678,7 +2678,7 @@ net2272_plat_remove(struct platform_device *pdev) static struct platform_driver net2272_plat_driver = { .probe = net2272_plat_probe, - .remove = __devexit_p(net2272_plat_remove), + .remove = net2272_plat_remove, .driver = { .name = driver_name, .owner = THIS_MODULE, diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 2a4749c3eb3..b5605ddfbd6 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -3060,7 +3060,7 @@ static int omap_udc_resume(struct platform_device *dev) static struct platform_driver udc_driver = { .probe = omap_udc_probe, - .remove = __devexit_p(omap_udc_remove), + .remove = omap_udc_remove, .suspend = omap_udc_suspend, .resume = omap_udc_resume, .driver = { diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 6f696ee8b81..9fd6e5fdc35 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -3708,7 +3708,7 @@ static struct platform_driver s3c_hsotg_driver = { .owner = THIS_MODULE, }, .probe = s3c_hsotg_probe, - .remove = __devexit_p(s3c_hsotg_remove), + .remove = s3c_hsotg_remove, .suspend = s3c_hsotg_suspend, .resume = s3c_hsotg_resume, }; diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index 443da21d73c..f5143a066ad 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c @@ -316,7 +316,7 @@ static struct bcma_driver bcma_hcd_driver = { .name = KBUILD_MODNAME, .id_table = bcma_hcd_table, .probe = bcma_hcd_probe, - .remove = __devexit_p(bcma_hcd_remove), + .remove = bcma_hcd_remove, .shutdown = bcma_hcd_shutdown, .suspend = bcma_hcd_suspend, .resume = bcma_hcd_resume, diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index d23321ec0e4..33f798ec1c7 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -207,7 +207,7 @@ MODULE_DEVICE_TABLE(of, atmel_ehci_dt_ids); static struct platform_driver ehci_atmel_driver = { .probe = ehci_atmel_drv_probe, - .remove = __devexit_p(ehci_atmel_drv_remove), + .remove = ehci_atmel_drv_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "atmel-ehci", diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 7fa1ba4de78..e0acfd589a8 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -220,7 +220,7 @@ static const struct dev_pm_ops ehci_msm_dev_pm_ops = { static struct platform_driver ehci_msm_driver = { .probe = ehci_msm_probe, - .remove = __devexit_p(ehci_msm_remove), + .remove = ehci_msm_remove, .driver = { .name = "msm_hsusb_host", .pm = &ehci_msm_dev_pm_ops, diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index f14c542b142..b807648876b 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -196,7 +196,7 @@ static const struct dev_pm_ops ehci_platform_pm_ops = { static struct platform_driver ehci_platform_driver = { .id_table = ehci_platform_table, .probe = ehci_platform_probe, - .remove = __devexit_p(ehci_platform_remove), + .remove = ehci_platform_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index abc178d21fe..f90a8815f4a 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c @@ -274,7 +274,7 @@ MODULE_DEVICE_TABLE(of, exynos_ehci_match); static struct platform_driver s5p_ehci_driver = { .probe = s5p_ehci_probe, - .remove = __devexit_p(s5p_ehci_remove), + .remove = s5p_ehci_remove, .shutdown = s5p_ehci_shutdown, .driver = { .name = "s5p-ehci", diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index fdd7c4873cf..7bcb8b2863d 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -166,7 +166,7 @@ static int __devexit ehci_w90x900_remove(struct platform_device *pdev) static struct platform_driver ehci_hcd_w90x900_driver = { .probe = ehci_w90x900_probe, - .remove = __devexit_p(ehci_w90x900_remove), + .remove = ehci_w90x900_remove, .driver = { .name = "w90x900-ehci", .owner = THIS_MODULE, diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 7da1a26bed2..92f4b99a3ab 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -821,7 +821,7 @@ static struct platform_driver of_fhci_driver = { .of_match_table = of_fhci_match, }, .probe = of_fhci_probe, - .remove = __devexit_p(of_fhci_remove), + .remove = of_fhci_remove, }; module_platform_driver(of_fhci_driver); diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 1e771292383..3a5c82f6723 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -336,7 +336,7 @@ static struct platform_driver fsl_usb2_mph_dr_driver = { .of_match_table = fsl_usb2_mph_dr_of_match, }, .probe = fsl_usb2_mph_dr_of_probe, - .remove = __devexit_p(fsl_usb2_mph_dr_of_remove), + .remove = fsl_usb2_mph_dr_of_remove, }; module_platform_driver(fsl_usb2_mph_dr_driver); diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 256326322cf..1ad9d200722 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -2856,7 +2856,7 @@ static int isp1362_resume(struct platform_device *pdev) static struct platform_driver isp1362_driver = { .probe = isp1362_probe, - .remove = __devexit_p(isp1362_remove), + .remove = isp1362_remove, .suspend = isp1362_suspend, .resume = isp1362_resume, diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 958379f9de7..5fb3caee770 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -432,7 +432,7 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev) static struct platform_driver isp1760_plat_driver = { .probe = isp1760_plat_probe, - .remove = __devexit_p(isp1760_plat_remove), + .remove = isp1760_plat_remove, .driver = { .name = "isp1760", }, diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 908d84af1dd..e4480029bc0 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -717,7 +717,7 @@ MODULE_ALIAS("platform:at91_ohci"); static struct platform_driver ohci_hcd_at91_driver = { .probe = ohci_hcd_at91_drv_probe, - .remove = __devexit_p(ohci_hcd_at91_drv_remove), + .remove = ohci_hcd_at91_drv_remove, .shutdown = usb_hcd_platform_shutdown, .suspend = ohci_hcd_at91_drv_suspend, .resume = ohci_hcd_at91_drv_resume, diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index 6a30fc5bec9..2f673e872b7 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -275,7 +275,7 @@ MODULE_DEVICE_TABLE(of, exynos_ohci_match); static struct platform_driver exynos_ohci_driver = { .probe = exynos_ohci_probe, - .remove = __devexit_p(exynos_ohci_remove), + .remove = exynos_ohci_remove, .shutdown = exynos_ohci_shutdown, .driver = { .name = "exynos-ohci", diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c index 931d588c3fb..b4921b71355 100644 --- a/drivers/usb/host/ohci-jz4740.c +++ b/drivers/usb/host/ohci-jz4740.c @@ -266,7 +266,7 @@ static __devexit int jz4740_ohci_remove(struct platform_device *pdev) static struct platform_driver ohci_hcd_jz4740_driver = { .probe = jz4740_ohci_probe, - .remove = __devexit_p(jz4740_ohci_remove), + .remove = jz4740_ohci_remove, .driver = { .name = "jz4740-ohci", .owner = THIS_MODULE, diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c index 1b8133b6e45..6bee6f191c8 100644 --- a/drivers/usb/host/ohci-omap3.c +++ b/drivers/usb/host/ohci-omap3.c @@ -232,7 +232,7 @@ static void ohci_hcd_omap3_shutdown(struct platform_device *pdev) static struct platform_driver ohci_hcd_omap3_driver = { .probe = ohci_hcd_omap3_probe, - .remove = __devexit_p(ohci_hcd_omap3_remove), + .remove = ohci_hcd_omap3_remove, .shutdown = ohci_hcd_omap3_shutdown, .driver = { .name = "ohci-omap3", diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index bda4e0bb8ab..ffe6c980847 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -214,7 +214,7 @@ static const struct dev_pm_ops ohci_platform_pm_ops = { static struct platform_driver ohci_platform_driver = { .id_table = ohci_platform_table, .probe = ohci_platform_probe, - .remove = __devexit_p(ohci_platform_remove), + .remove = ohci_platform_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index e84190f25c6..5c5c017850d 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -524,7 +524,7 @@ static const struct dev_pm_ops ohci_hcd_s3c2410_pm_ops = { static struct platform_driver ohci_hcd_s3c2410_driver = { .probe = ohci_hcd_s3c2410_drv_probe, - .remove = __devexit_p(ohci_hcd_s3c2410_drv_remove), + .remove = ohci_hcd_s3c2410_drv_remove, .shutdown = usb_hcd_platform_shutdown, .driver = { .owner = THIS_MODULE, diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index 2c9ab8f126d..94c6c550a95 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c @@ -363,7 +363,7 @@ static int ohci_hcd_tmio_drv_resume(struct platform_device *dev) static struct platform_driver ohci_hcd_tmio_driver = { .probe = ohci_hcd_tmio_drv_probe, - .remove = __devexit_p(ohci_hcd_tmio_drv_remove), + .remove = ohci_hcd_tmio_drv_remove, .shutdown = usb_hcd_platform_shutdown, .suspend = ohci_hcd_tmio_drv_suspend, .resume = ohci_hcd_tmio_drv_resume, diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index b3eea0ba97a..4e0436fc334 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2532,7 +2532,7 @@ clean_up: static struct platform_driver r8a66597_driver = { .probe = r8a66597_probe, - .remove = __devexit_p(r8a66597_remove), + .remove = r8a66597_remove, .driver = { .name = (char *) hcd_name, .owner = THIS_MODULE, diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 619b05f42d4..15f20de3e05 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1808,7 +1808,7 @@ sl811h_resume(struct platform_device *dev) /* this driver is exported so sl811_cs can depend on it */ struct platform_driver sl811h_driver = { .probe = sl811h_probe, - .remove = __devexit_p(sl811h_remove), + .remove = sl811h_remove, .suspend = sl811h_suspend, .resume = sl811h_resume, diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c index c2a29faba07..4dc9a09dc34 100644 --- a/drivers/usb/host/ssb-hcd.c +++ b/drivers/usb/host/ssb-hcd.c @@ -261,7 +261,7 @@ static struct ssb_driver ssb_hcd_driver = { .name = KBUILD_MODNAME, .id_table = ssb_hcd_table, .probe = ssb_hcd_probe, - .remove = __devexit_p(ssb_hcd_remove), + .remove = ssb_hcd_remove, .shutdown = ssb_hcd_shutdown, .suspend = ssb_hcd_suspend, .resume = ssb_hcd_resume, diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index dbbd1ba2522..8836898d64d 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -3212,7 +3212,7 @@ static int u132_resume(struct platform_device *pdev) */ static struct platform_driver u132_platform_driver = { .probe = u132_probe, - .remove = __devexit_p(u132_remove), + .remove = u132_remove, .suspend = u132_suspend, .resume = u132_resume, .driver = { diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 3baccf76541..49e8ce7ec26 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -629,7 +629,7 @@ static struct dev_pm_ops am35x_pm_ops = { static struct platform_driver am35x_driver = { .probe = am35x_probe, - .remove = __devexit_p(am35x_remove), + .remove = am35x_remove, .driver = { .name = "musb-am35x", .pm = DEV_PM_OPS, diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 67b8ae704e9..51ace9bf73d 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -569,7 +569,7 @@ static int __devexit da8xx_remove(struct platform_device *pdev) static struct platform_driver da8xx_driver = { .probe = da8xx_probe, - .remove = __devexit_p(da8xx_remove), + .remove = da8xx_remove, .driver = { .name = "musb-da8xx", }, diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index b3c0a943950..e01087b44e0 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -601,7 +601,7 @@ static int __devexit davinci_remove(struct platform_device *pdev) static struct platform_driver davinci_driver = { .probe = davinci_probe, - .remove = __devexit_p(davinci_remove), + .remove = davinci_remove, .driver = { .name = "musb-davinci", }, diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 774d8154a28..69cfa18bb2d 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2288,7 +2288,7 @@ static struct platform_driver musb_driver = { .pm = MUSB_DEV_PM_OPS, }, .probe = musb_probe, - .remove = __devexit_p(musb_remove), + .remove = musb_remove, .shutdown = musb_shutdown, }; diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index b108473e4d5..80e2b03965c 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -767,7 +767,7 @@ MODULE_DEVICE_TABLE(of, musb_dsps_of_match); static struct platform_driver dsps_usbss_driver = { .probe = dsps_probe, - .remove = __devexit_p(dsps_remove), + .remove = dsps_remove, .driver = { .name = "musb-dsps", .pm = &dsps_pm_ops, diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 32f531e7a2e..1150b4b6a09 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -674,7 +674,7 @@ MODULE_DEVICE_TABLE(of, omap2430_id_table); static struct platform_driver omap2430_driver = { .probe = omap2430_probe, - .remove = __devexit_p(omap2430_remove), + .remove = omap2430_remove, .driver = { .name = "musb-omap2430", .pm = DEV_PM_OPS, diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 812719b683d..b816517d8cb 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1227,7 +1227,7 @@ static int __devexit tusb_remove(struct platform_device *pdev) static struct platform_driver tusb_driver = { .probe = tusb_probe, - .remove = __devexit_p(tusb_remove), + .remove = tusb_remove, .driver = { .name = "musb-tusb", }, diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 286f1be6594..1d815578dde 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -216,7 +216,7 @@ static const struct dev_pm_ops ux500_pm_ops = { static struct platform_driver ux500_driver = { .probe = ux500_probe, - .remove = __devexit_p(ux500_remove), + .remove = ux500_remove, .driver = { .name = "musb-ux500", .pm = DEV_PM_OPS, diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c index ae8ad561f08..62ea0c23c45 100644 --- a/drivers/usb/otg/ab8500-usb.c +++ b/drivers/usb/otg/ab8500-usb.c @@ -571,7 +571,7 @@ static int __devexit ab8500_usb_remove(struct platform_device *pdev) static struct platform_driver ab8500_usb_driver = { .probe = ab8500_usb_probe, - .remove = __devexit_p(ab8500_usb_remove), + .remove = ab8500_usb_remove, .driver = { .name = "ab8500-usb", .owner = THIS_MODULE, diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c index c19d1d7173a..77dad188d2d 100644 --- a/drivers/usb/otg/fsl_otg.c +++ b/drivers/usb/otg/fsl_otg.c @@ -1169,7 +1169,7 @@ static int __devexit fsl_otg_remove(struct platform_device *pdev) struct platform_driver fsl_otg_driver = { .probe = fsl_otg_probe, - .remove = __devexit_p(fsl_otg_remove), + .remove = fsl_otg_remove, .driver = { .name = driver_name, .owner = THIS_MODULE, diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c index 9f5fc906041..eef0dd276e1 100644 --- a/drivers/usb/otg/msm_otg.c +++ b/drivers/usb/otg/msm_otg.c @@ -1746,7 +1746,7 @@ static const struct dev_pm_ops msm_otg_dev_pm_ops = { #endif static struct platform_driver msm_otg_driver = { - .remove = __devexit_p(msm_otg_remove), + .remove = msm_otg_remove, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c index 9a3caeecc50..001fdde12d7 100644 --- a/drivers/usb/otg/mxs-phy.c +++ b/drivers/usb/otg/mxs-phy.c @@ -164,7 +164,7 @@ MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids); static struct platform_driver mxs_phy_driver = { .probe = mxs_phy_probe, - .remove = __devexit_p(mxs_phy_remove), + .remove = mxs_phy_remove, .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index e52e35e7ada..0502c240591 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -156,7 +156,7 @@ static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev) static struct platform_driver nop_usb_xceiv_driver = { .probe = nop_usb_xceiv_probe, - .remove = __devexit_p(nop_usb_xceiv_remove), + .remove = nop_usb_xceiv_remove, .driver = { .name = "nop_usb_xceiv", .owner = THIS_MODULE, diff --git a/drivers/usb/phy/mv_u3d_phy.c b/drivers/usb/phy/mv_u3d_phy.c index 9f1c5d3c60e..80cf57ef550 100644 --- a/drivers/usb/phy/mv_u3d_phy.c +++ b/drivers/usb/phy/mv_u3d_phy.c @@ -331,7 +331,7 @@ static int __exit mv_u3d_phy_remove(struct platform_device *pdev) static struct platform_driver mv_u3d_phy_driver = { .probe = mv_u3d_phy_probe, - .remove = __devexit_p(mv_u3d_phy_remove), + .remove = mv_u3d_phy_remove, .driver = { .name = "mv-u3d-phy", .owner = THIS_MODULE, diff --git a/drivers/usb/phy/omap-usb2.c b/drivers/usb/phy/omap-usb2.c index 15ab3d6f2e8..f1ed872dd96 100644 --- a/drivers/usb/phy/omap-usb2.c +++ b/drivers/usb/phy/omap-usb2.c @@ -254,7 +254,7 @@ MODULE_DEVICE_TABLE(of, omap_usb2_id_table); static struct platform_driver omap_usb2_driver = { .probe = omap_usb2_probe, - .remove = __devexit_p(omap_usb2_remove), + .remove = omap_usb2_remove, .driver = { .name = "omap-usb2", .owner = THIS_MODULE, diff --git a/drivers/usb/phy/rcar-phy.c b/drivers/usb/phy/rcar-phy.c index 792f505d630..703a29586a7 100644 --- a/drivers/usb/phy/rcar-phy.c +++ b/drivers/usb/phy/rcar-phy.c @@ -210,7 +210,7 @@ static struct platform_driver rcar_usb_phy_driver = { .name = "rcar_usb_phy", }, .probe = rcar_usb_phy_probe, - .remove = __devexit_p(rcar_usb_phy_remove), + .remove = rcar_usb_phy_remove, }; module_platform_driver(rcar_usb_phy_driver); diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 3bf922ab045..2aa7c1a38ce 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -636,7 +636,7 @@ static struct platform_driver renesas_usbhs_driver = { .pm = &usbhsc_pm_ops, }, .probe = usbhs_probe, - .remove = __devexit_p(usbhs_remove), + .remove = usbhs_remove, }; module_platform_driver(renesas_usbhs_driver); -- cgit v1.2.3 From 41ac7b3ab7fe1d6175839947a877fdf95cbd2211 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:21:48 -0500 Subject: usb: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Cc: Peter Korsgaard Cc: Alexander Shishkin Acked-by: Felipe Balbi Cc: Li Yang Acked-by: Alan Stern Cc: Geoff Levand Cc: Wan ZongShun Cc: Olav Kongas Cc: Lennert Buytenhek Cc: Ben Dooks Cc: Kukjin Kim Acked-by: Nicolas Ferre Signed-off-by: Greg Kroah-Hartman --- drivers/usb/c67x00/c67x00-drv.c | 2 +- drivers/usb/chipidea/ci13xxx_imx.c | 2 +- drivers/usb/chipidea/ci13xxx_msm.c | 2 +- drivers/usb/chipidea/ci13xxx_pci.c | 2 +- drivers/usb/chipidea/core.c | 2 +- drivers/usb/chipidea/usbmisc_imx6q.c | 2 +- drivers/usb/dwc3/core.c | 11 +++++------ drivers/usb/dwc3/debugfs.c | 2 +- drivers/usb/dwc3/dwc3-exynos.c | 4 ++-- drivers/usb/dwc3/dwc3-omap.c | 4 ++-- drivers/usb/dwc3/dwc3-pci.c | 4 ++-- drivers/usb/dwc3/gadget.c | 4 ++-- drivers/usb/gadget/at91_udc.c | 4 ++-- drivers/usb/gadget/bcm63xx_udc.c | 2 +- drivers/usb/gadget/f_uac2.c | 2 +- drivers/usb/gadget/fsl_qe_udc.c | 8 ++++---- drivers/usb/gadget/mv_udc_core.c | 2 +- drivers/usb/gadget/net2272.c | 13 ++++++------- drivers/usb/gadget/omap_udc.c | 6 +++--- drivers/usb/gadget/s3c-hsotg.c | 6 +++--- drivers/usb/gadget/s3c-hsudc.c | 2 +- drivers/usb/host/bcma-hcd.c | 9 ++++----- drivers/usb/host/ehci-atmel.c | 2 +- drivers/usb/host/ehci-grlib.c | 2 +- drivers/usb/host/ehci-orion.c | 4 ++-- drivers/usb/host/ehci-platform.c | 2 +- drivers/usb/host/ehci-ppc-of.c | 4 ++-- drivers/usb/host/ehci-ps3.c | 2 +- drivers/usb/host/ehci-s5p.c | 2 +- drivers/usb/host/ehci-w90x900.c | 4 ++-- drivers/usb/host/ehci-xilinx-of.c | 2 +- drivers/usb/host/fhci-hcd.c | 2 +- drivers/usb/host/fsl-mph-dr-of.c | 8 ++++---- drivers/usb/host/imx21-hcd.c | 2 +- drivers/usb/host/isp116x-hcd.c | 2 +- drivers/usb/host/isp1362-hcd.c | 2 +- drivers/usb/host/isp1760-if.c | 4 ++-- drivers/usb/host/ohci-at91.c | 12 ++++++------ drivers/usb/host/ohci-ep93xx.c | 2 +- drivers/usb/host/ohci-exynos.c | 2 +- drivers/usb/host/ohci-jz4740.c | 2 +- drivers/usb/host/ohci-nxp.c | 4 ++-- drivers/usb/host/ohci-octeon.c | 2 +- drivers/usb/host/ohci-omap3.c | 2 +- drivers/usb/host/ohci-pci.c | 2 +- drivers/usb/host/ohci-platform.c | 2 +- drivers/usb/host/ohci-ppc-of.c | 4 ++-- drivers/usb/host/ohci-ps3.c | 4 ++-- drivers/usb/host/ohci-pxa27x.c | 6 +++--- drivers/usb/host/ohci-s3c2410.c | 2 +- drivers/usb/host/ohci-sa1111.c | 2 +- drivers/usb/host/ohci-spear.c | 2 +- drivers/usb/host/ohci-tmio.c | 2 +- drivers/usb/host/pci-quirks.c | 14 +++++++------- drivers/usb/host/r8a66597-hcd.c | 2 +- drivers/usb/host/sl811-hcd.c | 2 +- drivers/usb/host/ssb-hcd.c | 11 +++++------ drivers/usb/host/u132-hcd.c | 2 +- drivers/usb/host/uhci-grlib.c | 2 +- drivers/usb/host/uhci-platform.c | 2 +- drivers/usb/musb/am35x.c | 2 +- drivers/usb/musb/blackfin.c | 2 +- drivers/usb/musb/cppi_dma.c | 3 +-- drivers/usb/musb/da8xx.c | 2 +- drivers/usb/musb/davinci.c | 2 +- drivers/usb/musb/musb_core.c | 15 +++++++-------- drivers/usb/musb/musb_debugfs.c | 2 +- drivers/usb/musb/musb_dma.h | 3 +-- drivers/usb/musb/musb_dsps.c | 4 ++-- drivers/usb/musb/musb_gadget.c | 6 +++--- drivers/usb/musb/musbhsdma.c | 3 +-- drivers/usb/musb/omap2430.c | 2 +- drivers/usb/musb/tusb6010.c | 2 +- drivers/usb/musb/tusb6010_omap.c | 3 +-- drivers/usb/musb/ux500.c | 2 +- drivers/usb/musb/ux500_dma.c | 3 +-- drivers/usb/otg/ab8500-usb.c | 2 +- drivers/usb/otg/fsl_otg.c | 2 +- drivers/usb/otg/isp1301_omap.c | 2 +- drivers/usb/otg/nop-usb-xceiv.c | 2 +- drivers/usb/otg/twl4030-usb.c | 2 +- drivers/usb/otg/twl6030-usb.c | 2 +- drivers/usb/phy/mv_u3d_phy.c | 2 +- drivers/usb/phy/omap-usb2.c | 2 +- drivers/usb/phy/rcar-phy.c | 2 +- 85 files changed, 145 insertions(+), 155 deletions(-) diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c index 855d538752c..21913dfeecc 100644 --- a/drivers/usb/c67x00/c67x00-drv.c +++ b/drivers/usb/c67x00/c67x00-drv.c @@ -116,7 +116,7 @@ static irqreturn_t c67x00_irq(int irq, void *__dev) /* ------------------------------------------------------------------------- */ -static int __devinit c67x00_drv_probe(struct platform_device *pdev) +static int c67x00_drv_probe(struct platform_device *pdev) { struct c67x00_device *c67x00; struct c67x00_platform_data *pdata; diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c index 565973035ca..424bff91352 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.c +++ b/drivers/usb/chipidea/ci13xxx_imx.c @@ -93,7 +93,7 @@ static struct ci13xxx_platform_data ci13xxx_imx_platdata __devinitdata = { .capoffset = DEF_CAPOFFSET, }; -static int __devinit ci13xxx_imx_probe(struct platform_device *pdev) +static int ci13xxx_imx_probe(struct platform_device *pdev) { struct ci13xxx_imx_data *data; struct platform_device *plat_ci, *phy_pdev; diff --git a/drivers/usb/chipidea/ci13xxx_msm.c b/drivers/usb/chipidea/ci13xxx_msm.c index 406c5af2da5..e8a8ba36b10 100644 --- a/drivers/usb/chipidea/ci13xxx_msm.c +++ b/drivers/usb/chipidea/ci13xxx_msm.c @@ -55,7 +55,7 @@ static struct ci13xxx_platform_data ci13xxx_msm_platdata = { .notify_event = ci13xxx_msm_notify_event, }; -static int __devinit ci13xxx_msm_probe(struct platform_device *pdev) +static int ci13xxx_msm_probe(struct platform_device *pdev) { struct platform_device *plat_ci; diff --git a/drivers/usb/chipidea/ci13xxx_pci.c b/drivers/usb/chipidea/ci13xxx_pci.c index e1cb2fb2ef3..cb7eb3ede5e 100644 --- a/drivers/usb/chipidea/ci13xxx_pci.c +++ b/drivers/usb/chipidea/ci13xxx_pci.c @@ -48,7 +48,7 @@ struct ci13xxx_platform_data penwell_pci_platdata = { * Allocates basic PCI resources for this USB device controller, and then * invokes the udc_probe() method to start the UDC associated with it */ -static int __devinit ci13xxx_pci_probe(struct pci_dev *pdev, +static int ci13xxx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct ci13xxx_platform_data *platdata = (void *)id->driver_data; diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 46f23f226ae..7f9c0d21c89 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -390,7 +390,7 @@ void ci13xxx_remove_device(struct platform_device *pdev) } EXPORT_SYMBOL_GPL(ci13xxx_remove_device); -static int __devinit ci_hdrc_probe(struct platform_device *pdev) +static int ci_hdrc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ci13xxx *ci; diff --git a/drivers/usb/chipidea/usbmisc_imx6q.c b/drivers/usb/chipidea/usbmisc_imx6q.c index 81238a46729..ee6fa872f93 100644 --- a/drivers/usb/chipidea/usbmisc_imx6q.c +++ b/drivers/usb/chipidea/usbmisc_imx6q.c @@ -82,7 +82,7 @@ static const struct of_device_id usbmisc_imx6q_dt_ids[] = { { /* sentinel */ } }; -static int __devinit usbmisc_imx6q_probe(struct platform_device *pdev) +static int usbmisc_imx6q_probe(struct platform_device *pdev) { struct resource *res; struct imx6q_usbmisc *data; diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index cc5dac11d30..71610800cd8 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -140,8 +140,7 @@ static void dwc3_free_one_event_buffer(struct dwc3 *dwc, * Returns a pointer to the allocated event buffer structure on success * otherwise ERR_PTR(errno). */ -static struct dwc3_event_buffer *__devinit -dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length) +static struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned length) { struct dwc3_event_buffer *evt; @@ -183,7 +182,7 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc) * Returns 0 on success otherwise negative errno. In the error case, dwc * may contain some buffers allocated but not all which were requested. */ -static int __devinit dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) +static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) { int num; int i; @@ -260,7 +259,7 @@ static void dwc3_event_buffers_cleanup(struct dwc3 *dwc) } } -static void __devinit dwc3_cache_hwparams(struct dwc3 *dwc) +static void dwc3_cache_hwparams(struct dwc3 *dwc) { struct dwc3_hwparams *parms = &dwc->hwparams; @@ -281,7 +280,7 @@ static void __devinit dwc3_cache_hwparams(struct dwc3 *dwc) * * Returns 0 on success otherwise negative errno. */ -static int __devinit dwc3_core_init(struct dwc3 *dwc) +static int dwc3_core_init(struct dwc3 *dwc) { unsigned long timeout; u32 reg; @@ -360,7 +359,7 @@ static void dwc3_core_exit(struct dwc3 *dwc) #define DWC3_ALIGN_MASK (16 - 1) -static int __devinit dwc3_probe(struct platform_device *pdev) +static int dwc3_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; struct resource *res; diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index d4a30f11872..33ae98c5278 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -652,7 +652,7 @@ static const struct file_operations dwc3_link_state_fops = { .release = single_release, }; -int __devinit dwc3_debugfs_init(struct dwc3 *dwc) +int dwc3_debugfs_init(struct dwc3 *dwc) { struct dentry *root; struct dentry *file; diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index 19a98184e58..d43f0760ca6 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -34,7 +34,7 @@ struct dwc3_exynos { struct clk *clk; }; -static int __devinit dwc3_exynos_register_phys(struct dwc3_exynos *exynos) +static int dwc3_exynos_register_phys(struct dwc3_exynos *exynos) { struct nop_usb_xceiv_platform_data pdata; struct platform_device *pdev; @@ -90,7 +90,7 @@ err1: static u64 dwc3_exynos_dma_mask = DMA_BIT_MASK(32); -static int __devinit dwc3_exynos_probe(struct platform_device *pdev) +static int dwc3_exynos_probe(struct platform_device *pdev) { struct platform_device *dwc3; struct dwc3_exynos *exynos; diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index afbc6e99188..e114bb58ccf 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -157,7 +157,7 @@ static inline void dwc3_omap_writel(void __iomem *base, u32 offset, u32 value) writel(value, base + offset); } -static int __devinit dwc3_omap_register_phys(struct dwc3_omap *omap) +static int dwc3_omap_register_phys(struct dwc3_omap *omap) { struct nop_usb_xceiv_platform_data pdata; struct platform_device *pdev; @@ -262,7 +262,7 @@ static irqreturn_t dwc3_omap_interrupt(int irq, void *_omap) return IRQ_HANDLED; } -static int __devinit dwc3_omap_probe(struct platform_device *pdev) +static int dwc3_omap_probe(struct platform_device *pdev) { struct dwc3_omap_data *pdata = pdev->dev.platform_data; struct device_node *node = pdev->dev.of_node; diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index b3eeec7c6bc..68e389b589d 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -58,7 +58,7 @@ struct dwc3_pci { struct platform_device *usb3_phy; }; -static int __devinit dwc3_pci_register_phys(struct dwc3_pci *glue) +static int dwc3_pci_register_phys(struct dwc3_pci *glue) { struct nop_usb_xceiv_platform_data pdata; struct platform_device *pdev; @@ -112,7 +112,7 @@ err1: return ret; } -static int __devinit dwc3_pci_probe(struct pci_dev *pci, +static int dwc3_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) { struct resource res[2]; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 7b7deddf6a5..2e43b332aae 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1579,7 +1579,7 @@ static const struct usb_gadget_ops dwc3_gadget_ops = { /* -------------------------------------------------------------------------- */ -static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc) +static int dwc3_gadget_init_endpoints(struct dwc3 *dwc) { struct dwc3_ep *dep; u8 epnum; @@ -2374,7 +2374,7 @@ static irqreturn_t dwc3_interrupt(int irq, void *_dwc) * * Returns 0 on success otherwise negative errno. */ -int __devinit dwc3_gadget_init(struct dwc3 *dwc) +int dwc3_gadget_init(struct dwc3 *dwc) { u32 reg; int ret; diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 89d90b5fb78..e6135faabc3 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -1673,7 +1673,7 @@ static void at91udc_shutdown(struct platform_device *dev) spin_unlock_irqrestore(&udc->lock, flags); } -static void __devinit at91udc_of_init(struct at91_udc *udc, +static void at91udc_of_init(struct at91_udc *udc, struct device_node *np) { struct at91_udc_data *board = &udc->board; @@ -1693,7 +1693,7 @@ static void __devinit at91udc_of_init(struct at91_udc *udc, board->pullup_active_low = (flags & OF_GPIO_ACTIVE_LOW) ? 1 : 0; } -static int __devinit at91udc_probe(struct platform_device *pdev) +static int at91udc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct at91_udc *udc; diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c index b44e43641d5..18eff74e336 100644 --- a/drivers/usb/gadget/bcm63xx_udc.c +++ b/drivers/usb/gadget/bcm63xx_udc.c @@ -2323,7 +2323,7 @@ static void bcm63xx_udc_gadget_release(struct device *dev) * Note that platform data is required, because pd.port_no varies from chip * to chip and is used to switch the correct USB port to device mode. */ -static int __devinit bcm63xx_udc_probe(struct platform_device *pdev) +static int bcm63xx_udc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct bcm63xx_usbd_platform_data *pd = dev->platform_data; diff --git a/drivers/usb/gadget/f_uac2.c b/drivers/usb/gadget/f_uac2.c index 91396a1683e..d7da258fa3f 100644 --- a/drivers/usb/gadget/f_uac2.c +++ b/drivers/usb/gadget/f_uac2.c @@ -402,7 +402,7 @@ static struct snd_pcm_ops uac2_pcm_ops = { .prepare = uac2_pcm_null, }; -static int __devinit snd_uac2_probe(struct platform_device *pdev) +static int snd_uac2_probe(struct platform_device *pdev) { struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev); struct snd_card *card; diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 21db1f71d4c..8ad04a0b9e7 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2347,7 +2347,7 @@ static int fsl_qe_stop(struct usb_gadget *gadget, } /* udc structure's alloc and setup, include ep-param alloc */ -static struct qe_udc __devinit *qe_udc_config(struct platform_device *ofdev) +static struct qe_udc *qe_udc_config(struct platform_device *ofdev) { struct qe_udc *udc; struct device_node *np = ofdev->dev.of_node; @@ -2402,7 +2402,7 @@ cleanup: } /* USB Controller register init */ -static int __devinit qe_udc_reg_init(struct qe_udc *udc) +static int qe_udc_reg_init(struct qe_udc *udc) { struct usb_ctlr __iomem *qe_usbregs; qe_usbregs = udc->usb_regs; @@ -2420,7 +2420,7 @@ static int __devinit qe_udc_reg_init(struct qe_udc *udc) return 0; } -static int __devinit qe_ep_config(struct qe_udc *udc, unsigned char pipe_num) +static int qe_ep_config(struct qe_udc *udc, unsigned char pipe_num) { struct qe_ep *ep = &udc->eps[pipe_num]; @@ -2473,7 +2473,7 @@ static void qe_udc_release(struct device *dev) /* Driver probe functions */ static const struct of_device_id qe_udc_match[]; -static int __devinit qe_udc_probe(struct platform_device *ofdev) +static int qe_udc_probe(struct platform_device *ofdev) { struct qe_udc *udc; const struct of_device_id *match; diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index ea45224f78c..24196492ae2 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2188,7 +2188,7 @@ static int __devexit mv_udc_remove(struct platform_device *dev) return 0; } -static int __devinit mv_udc_probe(struct platform_device *dev) +static int mv_udc_probe(struct platform_device *dev) { struct mv_usb_platform_data *pdata = dev->dev.platform_data; struct mv_udc *udc; diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index 26c305321c4..f0103dd2a10 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -2215,8 +2215,7 @@ net2272_remove(struct net2272 *dev) dev_info(dev->dev, "unbind\n"); } -static struct net2272 * __devinit -net2272_probe_init(struct device *dev, unsigned int irq) +static struct net2272 *net2272_probe_init(struct device *dev, unsigned int irq) { struct net2272 *ret; @@ -2246,7 +2245,7 @@ net2272_probe_init(struct device *dev, unsigned int irq) return ret; } -static int __devinit +static int net2272_probe_fin(struct net2272 *dev, unsigned int irqflags) { int ret; @@ -2306,7 +2305,7 @@ err_add_udc: * don't respond over USB until a gadget driver binds to us */ -static int __devinit +static int net2272_rdk1_probe(struct pci_dev *pdev, struct net2272 *dev) { unsigned long resource, len, tmp; @@ -2389,7 +2388,7 @@ net2272_rdk1_probe(struct pci_dev *pdev, struct net2272 *dev) return ret; } -static int __devinit +static int net2272_rdk2_probe(struct pci_dev *pdev, struct net2272 *dev) { unsigned long resource, len; @@ -2447,7 +2446,7 @@ net2272_rdk2_probe(struct pci_dev *pdev, struct net2272 *dev) return ret; } -static int __devinit +static int net2272_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct net2272 *dev; @@ -2595,7 +2594,7 @@ static inline void net2272_pci_unregister(void) { } /*---------------------------------------------------------------------------*/ -static int __devinit +static int net2272_plat_probe(struct platform_device *pdev) { struct net2272 *dev; diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index b5605ddfbd6..cbc07c117af 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2506,7 +2506,7 @@ static inline void remove_proc_file(void) {} * UDC_SYSCON_1.CFG_LOCK is set can now work. We won't use that * capability yet though. */ -static unsigned __devinit +static unsigned omap_ep_setup(char *name, u8 addr, u8 type, unsigned buf, unsigned maxp, int dbuf) { @@ -2624,7 +2624,7 @@ static void omap_udc_release(struct device *dev) udc = NULL; } -static int __devinit +static int omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) { unsigned tmp, buf; @@ -2761,7 +2761,7 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) return 0; } -static int __devinit omap_udc_probe(struct platform_device *pdev) +static int omap_udc_probe(struct platform_device *pdev) { int status = -ENODEV; int hmc; diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 9fd6e5fdc35..6fdb1bd98e9 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -3072,7 +3072,7 @@ static struct usb_gadget_ops s3c_hsotg_gadget_ops = { * creation) to give to the gadget driver. Setup the endpoint name, any * direction information and other state that may be required. */ -static void __devinit s3c_hsotg_initep(struct s3c_hsotg *hsotg, +static void s3c_hsotg_initep(struct s3c_hsotg *hsotg, struct s3c_hsotg_ep *hs_ep, int epnum) { @@ -3414,7 +3414,7 @@ static const struct file_operations ep_fops = { * with the same name as the device itself, in case we end up * with multiple blocks in future systems. */ -static void __devinit s3c_hsotg_create_debug(struct s3c_hsotg *hsotg) +static void s3c_hsotg_create_debug(struct s3c_hsotg *hsotg) { struct dentry *root; unsigned epidx; @@ -3490,7 +3490,7 @@ static void s3c_hsotg_release(struct device *dev) * @pdev: The platform information for the driver */ -static int __devinit s3c_hsotg_probe(struct platform_device *pdev) +static int s3c_hsotg_probe(struct platform_device *pdev) { struct s3c_hsotg_plat *plat = pdev->dev.platform_data; struct device *dev = &pdev->dev; diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index d8e785d4ad5..52379b11f08 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -1261,7 +1261,7 @@ static struct usb_gadget_ops s3c_hsudc_gadget_ops = { .vbus_draw = s3c_hsudc_vbus_draw, }; -static int __devinit s3c_hsudc_probe(struct platform_device *pdev) +static int s3c_hsudc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct resource *res; diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index f5143a066ad..8c83ed90acb 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c @@ -54,7 +54,7 @@ static int bcma_wait_bits(struct bcma_device *dev, u16 reg, u32 bitmask, return -ETIMEDOUT; } -static void __devinit bcma_hcd_4716wa(struct bcma_device *dev) +static void bcma_hcd_4716wa(struct bcma_device *dev) { #ifdef CONFIG_BCMA_DRIVER_MIPS /* Work around for 4716 failures. */ @@ -88,7 +88,7 @@ static void __devinit bcma_hcd_4716wa(struct bcma_device *dev) } /* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */ -static void __devinit bcma_hcd_init_chip(struct bcma_device *dev) +static void bcma_hcd_init_chip(struct bcma_device *dev) { u32 tmp; @@ -165,8 +165,7 @@ static const struct usb_ehci_pdata ehci_pdata = { static const struct usb_ohci_pdata ohci_pdata = { }; -static struct platform_device * __devinit -bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr) +static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr) { struct platform_device *hci_dev; struct resource hci_res[2]; @@ -212,7 +211,7 @@ err_alloc: return ERR_PTR(ret); } -static int __devinit bcma_hcd_probe(struct bcma_device *dev) +static int bcma_hcd_probe(struct bcma_device *dev) { int err; u16 chipid_top; diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 33f798ec1c7..96bf00d3261 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -97,7 +97,7 @@ static const struct hc_driver ehci_atmel_hc_driver = { static u64 at91_ehci_dma_mask = DMA_BIT_MASK(32); -static int __devinit ehci_atmel_drv_probe(struct platform_device *pdev) +static int ehci_atmel_drv_probe(struct platform_device *pdev) { struct usb_hcd *hcd; const struct hc_driver *driver = &ehci_atmel_hc_driver; diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c index da4269550fb..1fc89292f5d 100644 --- a/drivers/usb/host/ehci-grlib.c +++ b/drivers/usb/host/ehci-grlib.c @@ -82,7 +82,7 @@ static const struct hc_driver ehci_grlib_hc_driver = { }; -static int __devinit ehci_hcd_grlib_probe(struct platform_device *op) +static int ehci_hcd_grlib_probe(struct platform_device *op) { struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 96da679bece..f74794c9315 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -146,7 +146,7 @@ static const struct hc_driver ehci_orion_hc_driver = { .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, }; -static void __devinit +static void ehci_orion_conf_mbus_windows(struct usb_hcd *hcd, const struct mbus_dram_target_info *dram) { @@ -167,7 +167,7 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd, } } -static int __devinit ehci_orion_drv_probe(struct platform_device *pdev) +static int ehci_orion_drv_probe(struct platform_device *pdev) { struct orion_ehci_data *pd = pdev->dev.platform_data; const struct mbus_dram_target_info *dram; diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index b807648876b..615cba016a6 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -61,7 +61,7 @@ static const struct ehci_driver_overrides platform_overrides __initdata = { .reset = ehci_platform_reset, }; -static int __devinit ehci_platform_probe(struct platform_device *dev) +static int ehci_platform_probe(struct platform_device *dev) { struct usb_hcd *hcd; struct resource *res_mem; diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index fa937d05a02..45aceefd0c2 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -71,7 +71,7 @@ static const struct hc_driver ehci_ppc_of_hc_driver = { * Fix: Enable Break Memory Transfer (BMT) in INSNREG3 */ #define PPC440EPX_EHCI0_INSREG_BMT (0x1 << 0) -static int __devinit +static int ppc44x_enable_bmt(struct device_node *dn) { __iomem u32 *insreg_virt; @@ -87,7 +87,7 @@ ppc44x_enable_bmt(struct device_node *dn) } -static int __devinit ehci_hcd_ppc_of_probe(struct platform_device *op) +static int ehci_hcd_ppc_of_probe(struct platform_device *op) { struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 45a356e9f13..df5925a4f0d 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c @@ -93,7 +93,7 @@ static const struct hc_driver ps3_ehci_hc_driver = { .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, }; -static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev) +static int ps3_ehci_probe(struct ps3_system_bus_device *dev) { int result; struct usb_hcd *hcd; diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index f90a8815f4a..2cf19d1ab4b 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c @@ -85,7 +85,7 @@ static void s5p_setup_vbus_gpio(struct platform_device *pdev) static u64 ehci_s5p_dma_mask = DMA_BIT_MASK(32); -static int __devinit s5p_ehci_probe(struct platform_device *pdev) +static int s5p_ehci_probe(struct platform_device *pdev) { struct s5p_ehci_platdata *pdata; struct s5p_ehci_hcd *s5p_ehci; diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index 7bcb8b2863d..bf8d462c26a 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -18,7 +18,7 @@ #define PHY0_CTR (0xA4) #define PHY1_CTR (0xA8) -static int __devinit usb_w90x900_probe(const struct hc_driver *driver, +static int usb_w90x900_probe(const struct hc_driver *driver, struct platform_device *pdev) { struct usb_hcd *hcd; @@ -147,7 +147,7 @@ static const struct hc_driver ehci_w90x900_hc_driver = { .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, }; -static int __devinit ehci_w90x900_probe(struct platform_device *pdev) +static int ehci_w90x900_probe(struct platform_device *pdev) { if (usb_disabled()) return -ENODEV; diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index 6a3f921a5d7..4f285e8e404 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -125,7 +125,7 @@ static const struct hc_driver ehci_xilinx_of_hc_driver = { * as HS only or HS/FS only, it checks the configuration in the device tree * entry, and sets an appropriate value for hcd->has_tt. */ -static int __devinit ehci_hcd_xilinx_of_probe(struct platform_device *op) +static int ehci_hcd_xilinx_of_probe(struct platform_device *op) { struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 92f4b99a3ab..618f143748a 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -561,7 +561,7 @@ static const struct hc_driver fhci_driver = { .hub_control = fhci_hub_control, }; -static int __devinit of_fhci_probe(struct platform_device *ofdev) +static int of_fhci_probe(struct platform_device *ofdev) { struct device *dev = &ofdev->dev; struct device_node *node = dev->of_node; diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 3a5c82f6723..dc0aeba35c9 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -42,7 +42,7 @@ struct fsl_usb2_dev_data dr_mode_data[] __devinitdata = { }, }; -struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_node *np) +struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np) { const unsigned char *prop; int i; @@ -59,7 +59,7 @@ struct fsl_usb2_dev_data * __devinit get_dr_mode_data(struct device_node *np) return &dr_mode_data[0]; /* mode not specified, use host */ } -static enum fsl_usb2_phy_modes __devinit determine_usb_phy(const char *phy_type) +static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type) { if (!phy_type) return FSL_USB2_PHY_NONE; @@ -75,7 +75,7 @@ static enum fsl_usb2_phy_modes __devinit determine_usb_phy(const char *phy_type) return FSL_USB2_PHY_NONE; } -struct platform_device * __devinit fsl_usb2_device_register( +struct platform_device *fsl_usb2_device_register( struct platform_device *ofdev, struct fsl_usb2_platform_data *pdata, const char *name, int id) @@ -154,7 +154,7 @@ static int usb_get_ver_info(struct device_node *np) return ver; } -static int __devinit fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) +static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; struct platform_device *usb_dev; diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index f19e2690c23..bd6a7447ccc 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1680,7 +1680,7 @@ static int imx21_hc_reset(struct usb_hcd *hcd) return 0; } -static int __devinit imx21_hc_start(struct usb_hcd *hcd) +static int imx21_hc_start(struct usb_hcd *hcd) { struct imx21 *imx21 = hcd_to_imx21(hcd); unsigned long flags; diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 9e65e3091c8..b64e661618b 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -1557,7 +1557,7 @@ static int isp116x_remove(struct platform_device *pdev) return 0; } -static int __devinit isp116x_probe(struct platform_device *pdev) +static int isp116x_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct isp116x *isp116x; diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 1ad9d200722..5f8b63ce4be 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -2680,7 +2680,7 @@ static int __devexit isp1362_remove(struct platform_device *pdev) return 0; } -static int __devinit isp1362_probe(struct platform_device *pdev) +static int isp1362_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct isp1362_hcd *isp1362_hcd; diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 5fb3caee770..d752a4c4281 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -172,7 +172,7 @@ static struct platform_driver isp1760_of_driver = { #endif #ifdef CONFIG_PCI -static int __devinit isp1761_pci_probe(struct pci_dev *dev, +static int isp1761_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { u8 latency, limit; @@ -346,7 +346,7 @@ static struct pci_driver isp1761_pci_driver = { }; #endif -static int __devinit isp1760_plat_probe(struct platform_device *pdev) +static int isp1760_plat_probe(struct platform_device *pdev) { int ret = 0; struct usb_hcd *hcd; diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index e4480029bc0..ff94a7479a7 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -108,7 +108,7 @@ static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_dev * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. */ -static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver, +static int usb_hcd_at91_probe(const struct hc_driver *driver, struct platform_device *pdev) { int retval; @@ -222,7 +222,7 @@ static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd, /*-------------------------------------------------------------------------*/ -static int __devinit +static int ohci_at91_reset (struct usb_hcd *hcd) { struct at91_usbh_data *board = hcd->self.controller->platform_data; @@ -236,7 +236,7 @@ ohci_at91_reset (struct usb_hcd *hcd) return 0; } -static int __devinit +static int ohci_at91_start (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); @@ -506,7 +506,7 @@ MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids); static u64 at91_ohci_dma_mask = DMA_BIT_MASK(32); -static int __devinit ohci_at91_of_init(struct platform_device *pdev) +static int ohci_at91_of_init(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; int i, gpio; @@ -548,7 +548,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev) return 0; } #else -static int __devinit ohci_at91_of_init(struct platform_device *pdev) +static int ohci_at91_of_init(struct platform_device *pdev) { return 0; } @@ -556,7 +556,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ -static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev) +static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) { struct at91_usbh_data *pdata; int i; diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index a982f04ed78..8704e9fa5a8 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -107,7 +107,7 @@ static void usb_hcd_ep93xx_remove(struct usb_hcd *hcd, usb_put_hcd(hcd); } -static int __devinit ohci_ep93xx_start(struct usb_hcd *hcd) +static int ohci_ep93xx_start(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); int ret; diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index 2f673e872b7..1288cdb3137 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -76,7 +76,7 @@ static const struct hc_driver exynos_ohci_hc_driver = { static u64 ohci_exynos_dma_mask = DMA_BIT_MASK(32); -static int __devinit exynos_ohci_probe(struct platform_device *pdev) +static int exynos_ohci_probe(struct platform_device *pdev) { struct exynos4_ohci_platdata *pdata; struct exynos_ohci_hcd *exynos_ohci; diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c index b4921b71355..59feb873813 100644 --- a/drivers/usb/host/ohci-jz4740.c +++ b/drivers/usb/host/ohci-jz4740.c @@ -145,7 +145,7 @@ static const struct hc_driver ohci_jz4740_hc_driver = { }; -static __devinit int jz4740_ohci_probe(struct platform_device *pdev) +static int jz4740_ohci_probe(struct platform_device *pdev) { int ret; struct usb_hcd *hcd; diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index e068f034cb9..2344040c16d 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c @@ -147,7 +147,7 @@ static void nxp_stop_hc(void) __raw_writel(tmp, USB_OTG_STAT_CONTROL); } -static int __devinit ohci_nxp_start(struct usb_hcd *hcd) +static int ohci_nxp_start(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); int ret; @@ -205,7 +205,7 @@ static const struct hc_driver ohci_nxp_hc_driver = { .start_port_reset = ohci_start_port_reset, }; -static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) +static int usb_hcd_nxp_probe(struct platform_device *pdev) { struct usb_hcd *hcd = 0; struct ohci_hcd *ohci; diff --git a/drivers/usb/host/ohci-octeon.c b/drivers/usb/host/ohci-octeon.c index d469bf9b9e5..d44430d009f 100644 --- a/drivers/usb/host/ohci-octeon.c +++ b/drivers/usb/host/ohci-octeon.c @@ -42,7 +42,7 @@ static void ohci_octeon_hw_stop(void) octeon2_usb_clocks_stop(); } -static int __devinit ohci_octeon_start(struct usb_hcd *hcd) +static int ohci_octeon_start(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); int ret; diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c index 6bee6f191c8..b2398aa6c7a 100644 --- a/drivers/usb/host/ohci-omap3.c +++ b/drivers/usb/host/ohci-omap3.c @@ -125,7 +125,7 @@ static const struct hc_driver ohci_omap3_hc_driver = { * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. */ -static int __devinit ohci_hcd_omap3_probe(struct platform_device *pdev) +static int ohci_hcd_omap3_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct usb_hcd *hcd = NULL; diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 6afa7dc4e4c..951514ef446 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -270,7 +270,7 @@ static int ohci_pci_reset (struct usb_hcd *hcd) } -static int __devinit ohci_pci_start (struct usb_hcd *hcd) +static int ohci_pci_start (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); int ret; diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index ffe6c980847..c3f76fa8d7d 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -83,7 +83,7 @@ static const struct hc_driver ohci_platform_hc_driver = { .start_port_reset = ohci_start_port_reset, }; -static int __devinit ohci_platform_probe(struct platform_device *dev) +static int ohci_platform_probe(struct platform_device *dev) { struct usb_hcd *hcd; struct resource *res_mem; diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index e27d5ae2b9e..64c2ed9ff95 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -19,7 +19,7 @@ #include -static int __devinit +static int ohci_ppc_of_start(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); @@ -81,7 +81,7 @@ static const struct hc_driver ohci_ppc_of_hc_driver = { }; -static int __devinit ohci_hcd_ppc_of_probe(struct platform_device *op) +static int ohci_hcd_ppc_of_probe(struct platform_device *op) { struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c index 2ee1d8d713d..7d35cd9e286 100644 --- a/drivers/usb/host/ohci-ps3.c +++ b/drivers/usb/host/ohci-ps3.c @@ -30,7 +30,7 @@ static int ps3_ohci_hc_reset(struct usb_hcd *hcd) return ohci_init(ohci); } -static int __devinit ps3_ohci_hc_start(struct usb_hcd *hcd) +static int ps3_ohci_hc_start(struct usb_hcd *hcd) { int result; struct ohci_hcd *ohci = hcd_to_ohci(hcd); @@ -76,7 +76,7 @@ static const struct hc_driver ps3_ohci_hc_driver = { #endif }; -static int __devinit ps3_ohci_probe(struct ps3_system_bus_device *dev) +static int ps3_ohci_probe(struct ps3_system_bus_device *dev) { int result; struct usb_hcd *hcd; diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 156d289d3bb..efe71f3ca47 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -284,7 +284,7 @@ MODULE_DEVICE_TABLE(of, pxa_ohci_dt_ids); static u64 pxa_ohci_dma_mask = DMA_BIT_MASK(32); -static int __devinit ohci_pxa_of_init(struct platform_device *pdev) +static int ohci_pxa_of_init(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct pxaohci_platform_data *pdata; @@ -330,7 +330,7 @@ static int __devinit ohci_pxa_of_init(struct platform_device *pdev) return 0; } #else -static int __devinit ohci_pxa_of_init(struct platform_device *pdev) +static int ohci_pxa_of_init(struct platform_device *pdev) { return 0; } @@ -471,7 +471,7 @@ void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev) /*-------------------------------------------------------------------------*/ -static int __devinit +static int ohci_pxa27x_start (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 5c5c017850d..4f29e0b086b 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -458,7 +458,7 @@ static const struct hc_driver ohci_s3c2410_hc_driver = { /* device driver */ -static int __devinit ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev) +static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev) { return usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev); } diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index b6cc9252092..17b2a7dad77 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -63,7 +63,7 @@ static int ohci_sa1111_reset(struct usb_hcd *hcd) return ohci_init(ohci); } -static int __devinit ohci_sa1111_start(struct usb_hcd *hcd) +static int ohci_sa1111_start(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); int ret; diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index c69725d9f0c..b7fc2fc56c8 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -33,7 +33,7 @@ static void spear_stop_ohci(struct spear_ohci *ohci) clk_disable_unprepare(ohci->clk); } -static int __devinit ohci_spear_start(struct usb_hcd *hcd) +static int ohci_spear_start(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); int ret; diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index 94c6c550a95..5996a3b0a4d 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c @@ -184,7 +184,7 @@ static const struct hc_driver ohci_tmio_hc_driver = { /*-------------------------------------------------------------------------*/ static struct platform_driver ohci_hcd_tmio_driver; -static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev) +static int ohci_hcd_tmio_drv_probe(struct platform_device *dev) { const struct mfd_cell *cell = mfd_get_cell(dev); struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0); diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 39f9e4a9a2d..a018e706c0e 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -443,7 +443,7 @@ static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask) #define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO) #define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY) -static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) +static void quirk_usb_handoff_uhci(struct pci_dev *pdev) { unsigned long base = 0; int i; @@ -461,12 +461,12 @@ static void __devinit quirk_usb_handoff_uhci(struct pci_dev *pdev) uhci_check_and_reset_hc(pdev, base); } -static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx) +static int mmio_resource_enabled(struct pci_dev *pdev, int idx) { return pci_resource_start(pdev, idx) && mmio_enabled(pdev); } -static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) +static void quirk_usb_handoff_ohci(struct pci_dev *pdev) { void __iomem *base; u32 control; @@ -558,7 +558,7 @@ static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = { { } }; -static void __devinit ehci_bios_handoff(struct pci_dev *pdev, +static void ehci_bios_handoff(struct pci_dev *pdev, void __iomem *op_reg_base, u32 cap, u8 offset) { @@ -626,7 +626,7 @@ static void __devinit ehci_bios_handoff(struct pci_dev *pdev, writel(0, op_reg_base + EHCI_CONFIGFLAG); } -static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) +static void quirk_usb_disable_ehci(struct pci_dev *pdev) { void __iomem *base, *op_reg_base; u32 hcc_params, cap, val; @@ -841,7 +841,7 @@ EXPORT_SYMBOL_GPL(usb_disable_xhci_ports); * and then waits 5 seconds for the BIOS to hand over control. * If we timeout, assume the BIOS is broken and take control anyway. */ -static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) +static void quirk_usb_handoff_xhci(struct pci_dev *pdev) { void __iomem *base; int ext_cap_offset; @@ -941,7 +941,7 @@ hc_init: iounmap(base); } -static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) +static void quirk_usb_early_handoff(struct pci_dev *pdev) { /* Skip Netlogic mips SoC's internal PCI USB controller. * This device does not need/support EHCI/OHCI handoff diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 4e0436fc334..e97dfad526f 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2405,7 +2405,7 @@ static int __devexit r8a66597_remove(struct platform_device *pdev) return 0; } -static int __devinit r8a66597_probe(struct platform_device *pdev) +static int r8a66597_probe(struct platform_device *pdev) { char clk_name[8]; struct resource *res = NULL, *ires; diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 15f20de3e05..782127d9dfc 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1618,7 +1618,7 @@ sl811h_remove(struct platform_device *dev) return 0; } -static int __devinit +static int sl811h_probe(struct platform_device *dev) { struct usb_hcd *hcd; diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c index 4dc9a09dc34..79aa95832b2 100644 --- a/drivers/usb/host/ssb-hcd.c +++ b/drivers/usb/host/ssb-hcd.c @@ -39,7 +39,7 @@ struct ssb_hcd_device { u32 enable_flags; }; -static void __devinit ssb_hcd_5354wa(struct ssb_device *dev) +static void ssb_hcd_5354wa(struct ssb_device *dev) { #ifdef CONFIG_SSB_DRIVER_MIPS /* Work around for 5354 failures */ @@ -53,7 +53,7 @@ static void __devinit ssb_hcd_5354wa(struct ssb_device *dev) #endif } -static void __devinit ssb_hcd_usb20wa(struct ssb_device *dev) +static void ssb_hcd_usb20wa(struct ssb_device *dev) { if (dev->id.coreid == SSB_DEV_USB20_HOST) { /* @@ -80,7 +80,7 @@ static void __devinit ssb_hcd_usb20wa(struct ssb_device *dev) } /* based on arch/mips/brcm-boards/bcm947xx/pcibios.c */ -static u32 __devinit ssb_hcd_init_chip(struct ssb_device *dev) +static u32 ssb_hcd_init_chip(struct ssb_device *dev) { u32 flags = 0; @@ -101,8 +101,7 @@ static const struct usb_ehci_pdata ehci_pdata = { static const struct usb_ohci_pdata ohci_pdata = { }; -static struct platform_device * __devinit -ssb_hcd_create_pdev(struct ssb_device *dev, bool ohci, u32 addr, u32 len) +static struct platform_device *ssb_hcd_create_pdev(struct ssb_device *dev, bool ohci, u32 addr, u32 len) { struct platform_device *hci_dev; struct resource hci_res[2]; @@ -148,7 +147,7 @@ err_alloc: return ERR_PTR(ret); } -static int __devinit ssb_hcd_probe(struct ssb_device *dev, +static int ssb_hcd_probe(struct ssb_device *dev, const struct ssb_device_id *id) { int err, tmp; diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 8836898d64d..8bf78e652a8 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -3084,7 +3084,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) mutex_unlock(&u132->sw_lock); } -static int __devinit u132_probe(struct platform_device *pdev) +static int u132_probe(struct platform_device *pdev) { struct usb_hcd *hcd; int retval; diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c index f7a62138e3e..511bfc46dd7 100644 --- a/drivers/usb/host/uhci-grlib.c +++ b/drivers/usb/host/uhci-grlib.c @@ -85,7 +85,7 @@ static const struct hc_driver uhci_grlib_hc_driver = { }; -static int __devinit uhci_hcd_grlib_probe(struct platform_device *op) +static int uhci_hcd_grlib_probe(struct platform_device *op) { struct device_node *dn = op->dev.of_node; struct usb_hcd *hcd; diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index 68ebf20e151..8c4dace4b14 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c @@ -62,7 +62,7 @@ static const struct hc_driver uhci_platform_hc_driver = { static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32); -static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev) +static int uhci_hcd_platform_probe(struct platform_device *pdev) { struct usb_hcd *hcd; struct uhci_hcd *uhci; diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 49e8ce7ec26..a27bb851567 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -455,7 +455,7 @@ static const struct musb_platform_ops am35x_ops = { static u64 am35x_dmamask = DMA_BIT_MASK(32); -static int __devinit am35x_probe(struct platform_device *pdev) +static int am35x_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 7e4d60a4172..12beb0e3114 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -448,7 +448,7 @@ static const struct musb_platform_ops bfin_ops = { static u64 bfin_dmamask = DMA_BIT_MASK(32); -static int __devinit bfin_probe(struct platform_device *pdev) +static int bfin_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index 3a6c2fd1f91..0968dd7a859 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c @@ -1317,8 +1317,7 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) EXPORT_SYMBOL_GPL(cppi_interrupt); /* Instantiate a software object representing a DMA controller. */ -struct dma_controller *__devinit -dma_controller_create(struct musb *musb, void __iomem *mregs) +struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *mregs) { struct cppi *controller; struct device *dev = musb->controller; diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 51ace9bf73d..c4fb235985b 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -471,7 +471,7 @@ static const struct musb_platform_ops da8xx_ops = { static u64 da8xx_dmamask = DMA_BIT_MASK(32); -static int __devinit da8xx_probe(struct platform_device *pdev) +static int da8xx_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index e01087b44e0..8877c1a7dbb 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -504,7 +504,7 @@ static const struct musb_platform_ops davinci_ops = { static u64 davinci_dmamask = DMA_BIT_MASK(32); -static int __devinit davinci_probe(struct platform_device *pdev) +static int davinci_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 69cfa18bb2d..f17a3e79dbe 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1163,7 +1163,7 @@ static struct musb_fifo_cfg __devinitdata mode_5_cfg[] = { * * returns negative errno or offset for next fifo. */ -static int __devinit +static int fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, const struct musb_fifo_cfg *cfg, u16 offset) { @@ -1238,7 +1238,7 @@ static struct musb_fifo_cfg __devinitdata ep0_cfg = { .style = FIFO_RXTX, .maxpacket = 64, }; -static int __devinit ep_config_from_table(struct musb *musb) +static int ep_config_from_table(struct musb *musb) { const struct musb_fifo_cfg *cfg; unsigned i, n; @@ -1329,7 +1329,7 @@ done: * ep_config_from_hw - when MUSB_C_DYNFIFO_DEF is false * @param musb the controller */ -static int __devinit ep_config_from_hw(struct musb *musb) +static int ep_config_from_hw(struct musb *musb) { u8 epnum = 0; struct musb_hw_ep *hw_ep; @@ -1376,7 +1376,7 @@ enum { MUSB_CONTROLLER_MHDRC, MUSB_CONTROLLER_HDRC, }; /* Initialize MUSB (M)HDRC part of the USB hardware subsystem; * configure endpoints, or take their config from silicon */ -static int __devinit musb_core_init(u16 musb_type, struct musb *musb) +static int musb_core_init(u16 musb_type, struct musb *musb) { u8 reg; char *type; @@ -1759,8 +1759,7 @@ static void musb_irq_work(struct work_struct *data) * Init support */ -static struct musb *__devinit -allocate_instance(struct device *dev, +static struct musb *allocate_instance(struct device *dev, struct musb_hdrc_config *config, void __iomem *mbase) { struct musb *musb; @@ -1835,7 +1834,7 @@ static void musb_free(struct musb *musb) * @ctrl: virtual address of controller registers, * not yet corrected for platform-specific offsets */ -static int __devinit +static int musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) { int status; @@ -2010,7 +2009,7 @@ fail0: /* all implementations (PCI bridge to FPGA, VLYNQ, etc) should just * bridge to a platform device; this driver then suffices. */ -static int __devinit musb_probe(struct platform_device *pdev) +static int musb_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; int irq = platform_get_irq_byname(pdev, "mc"); diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index 1d6e8af94c0..4c216790e86 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -233,7 +233,7 @@ static const struct file_operations musb_test_mode_fops = { .release = single_release, }; -int __devinit musb_init_debugfs(struct musb *musb) +int musb_init_debugfs(struct musb *musb) { struct dentry *root; struct dentry *file; diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h index 24d39210d4a..1b6b827b769 100644 --- a/drivers/usb/musb/musb_dma.h +++ b/drivers/usb/musb/musb_dma.h @@ -178,8 +178,7 @@ struct dma_controller { extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit); -extern struct dma_controller *__devinit -dma_controller_create(struct musb *, void __iomem *); +extern struct dma_controller *dma_controller_create(struct musb *, void __iomem *); extern void dma_controller_destroy(struct dma_controller *); diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 80e2b03965c..f8affd7a30c 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -479,7 +479,7 @@ static struct musb_platform_ops dsps_ops = { static u64 musb_dmamask = DMA_BIT_MASK(32); -static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) +static int dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) { struct device *dev = glue->dev; struct platform_device *pdev = to_platform_device(dev); @@ -592,7 +592,7 @@ err0: return ret; } -static int __devinit dsps_probe(struct platform_device *pdev) +static int dsps_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; const struct of_device_id *match; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 4f23b12a3ae..876787438c2 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1787,7 +1787,7 @@ static void musb_gadget_release(struct device *dev) } -static void __devinit +static void init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) { struct musb_hw_ep *hw_ep = musb->endpoints + epnum; @@ -1824,7 +1824,7 @@ init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) * Initialize the endpoints exposed to peripheral drivers, with backlinks * to the rest of the driver state. */ -static inline void __devinit musb_g_init_endpoints(struct musb *musb) +static inline void musb_g_init_endpoints(struct musb *musb) { u8 epnum; struct musb_hw_ep *hw_ep; @@ -1857,7 +1857,7 @@ static inline void __devinit musb_g_init_endpoints(struct musb *musb) /* called once during driver setup to initialize and link into * the driver model; memory is zeroed. */ -int __devinit musb_gadget_setup(struct musb *musb) +int musb_gadget_setup(struct musb *musb) { int status; diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 0fc6ca6bc60..3d1fd52a15a 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -380,8 +380,7 @@ void dma_controller_destroy(struct dma_controller *c) kfree(controller); } -struct dma_controller *__devinit -dma_controller_create(struct musb *musb, void __iomem *base) +struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *base) { struct musb_dma_controller *controller; struct device *dev = musb->controller; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 1150b4b6a09..06850f22739 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -490,7 +490,7 @@ static const struct musb_platform_ops omap2430_ops = { static u64 omap2430_dmamask = DMA_BIT_MASK(32); -static int __devinit omap2430_probe(struct platform_device *pdev) +static int omap2430_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct omap_musb_board_data *data; diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index b816517d8cb..a03b7befd2e 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1153,7 +1153,7 @@ static const struct musb_platform_ops tusb_ops = { static u64 tusb_dmamask = DMA_BIT_MASK(32); -static int __devinit tusb_probe(struct platform_device *pdev) +static int tusb_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index 7a62b95dac2..2c46d42e661 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c @@ -661,8 +661,7 @@ void dma_controller_destroy(struct dma_controller *c) kfree(tusb_dma); } -struct dma_controller *__devinit -dma_controller_create(struct musb *musb, void __iomem *base) +struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *base) { void __iomem *tbase = musb->ctrl_base; struct tusb_omap_dma *tusb_dma; diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 1d815578dde..6b12001eb88 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -81,7 +81,7 @@ static const struct musb_platform_ops ux500_ops = { .exit = ux500_musb_exit, }; -static int __devinit ux500_probe(struct platform_device *pdev) +static int ux500_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index f1059e725ea..039e567dd3b 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -364,8 +364,7 @@ void dma_controller_destroy(struct dma_controller *c) kfree(controller); } -struct dma_controller *__devinit -dma_controller_create(struct musb *musb, void __iomem *base) +struct dma_controller *dma_controller_create(struct musb *musb, void __iomem *base) { struct ux500_dma_controller *controller; struct platform_device *pdev = to_platform_device(musb->controller); diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c index 62ea0c23c45..f0ba931f0d5 100644 --- a/drivers/usb/otg/ab8500-usb.c +++ b/drivers/usb/otg/ab8500-usb.c @@ -468,7 +468,7 @@ static int ab8500_usb_v2_res_setup(struct platform_device *pdev, return 0; } -static int __devinit ab8500_usb_probe(struct platform_device *pdev) +static int ab8500_usb_probe(struct platform_device *pdev) { struct ab8500_usb *ab; struct usb_otg *otg; diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c index 77dad188d2d..2b9a83856a5 100644 --- a/drivers/usb/otg/fsl_otg.c +++ b/drivers/usb/otg/fsl_otg.c @@ -1110,7 +1110,7 @@ static const struct file_operations otg_fops = { .release = fsl_otg_release, }; -static int __devinit fsl_otg_probe(struct platform_device *pdev) +static int fsl_otg_probe(struct platform_device *pdev) { int ret; diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index ceee2119bff..af9cb11626b 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c @@ -1493,7 +1493,7 @@ isp1301_start_hnp(struct usb_otg *otg) /*-------------------------------------------------------------------------*/ -static int __devinit +static int isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { int status; diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 0502c240591..28f70e21ad6 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -93,7 +93,7 @@ static int nop_set_host(struct usb_otg *otg, struct usb_bus *host) return 0; } -static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) +static int nop_usb_xceiv_probe(struct platform_device *pdev) { struct nop_usb_xceiv_platform_data *pdata = pdev->dev.platform_data; struct nop_usb_xceiv *nop; diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 11b2a1203d4..0a701938ab5 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c @@ -575,7 +575,7 @@ static int twl4030_set_host(struct usb_otg *otg, struct usb_bus *host) return 0; } -static int __devinit twl4030_usb_probe(struct platform_device *pdev) +static int twl4030_usb_probe(struct platform_device *pdev) { struct twl4030_usb_data *pdata = pdev->dev.platform_data; struct twl4030_usb *twl; diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index fcadef7864f..8cd6cf49bdb 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -310,7 +310,7 @@ static int twl6030_set_vbus(struct phy_companion *comparator, bool enabled) return 0; } -static int __devinit twl6030_usb_probe(struct platform_device *pdev) +static int twl6030_usb_probe(struct platform_device *pdev) { u32 ret; struct twl6030_usb *twl; diff --git a/drivers/usb/phy/mv_u3d_phy.c b/drivers/usb/phy/mv_u3d_phy.c index 80cf57ef550..eaddbe3d430 100644 --- a/drivers/usb/phy/mv_u3d_phy.c +++ b/drivers/usb/phy/mv_u3d_phy.c @@ -262,7 +262,7 @@ calstart: return 0; } -static int __devinit mv_u3d_phy_probe(struct platform_device *pdev) +static int mv_u3d_phy_probe(struct platform_device *pdev) { struct mv_u3d_phy *mv_u3d_phy; struct mv_usb_platform_data *pdata; diff --git a/drivers/usb/phy/omap-usb2.c b/drivers/usb/phy/omap-usb2.c index f1ed872dd96..c10fb8b1fdb 100644 --- a/drivers/usb/phy/omap-usb2.c +++ b/drivers/usb/phy/omap-usb2.c @@ -141,7 +141,7 @@ static int omap_usb2_suspend(struct usb_phy *x, int suspend) return 0; } -static int __devinit omap_usb2_probe(struct platform_device *pdev) +static int omap_usb2_probe(struct platform_device *pdev) { struct omap_usb *phy; struct usb_otg *otg; diff --git a/drivers/usb/phy/rcar-phy.c b/drivers/usb/phy/rcar-phy.c index 703a29586a7..84ac2a77de7 100644 --- a/drivers/usb/phy/rcar-phy.c +++ b/drivers/usb/phy/rcar-phy.c @@ -142,7 +142,7 @@ static void rcar_usb_phy_shutdown(struct usb_phy *phy) spin_unlock_irqrestore(&priv->lock, flags); } -static int __devinit rcar_usb_phy_probe(struct platform_device *pdev) +static int rcar_usb_phy_probe(struct platform_device *pdev) { struct rcar_usb_phy_priv *priv; struct resource *res0, *res1; -- cgit v1.2.3 From d3608b6dafc570bb671c3338288eb2523f8cd52a Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:24:34 -0500 Subject: usb: remove use of __devinitdata CONFIG_HOTPLUG is going away as an option so __devinitdata is no longer needed. Signed-off-by: Bill Pemberton Cc: Alexander Shishkin Acked-by: Felipe Balbi Cc: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/ci13xxx_imx.c | 2 +- drivers/usb/gadget/net2272.c | 2 +- drivers/usb/host/ehci-spear.c | 2 +- drivers/usb/host/ehci-tegra.c | 2 +- drivers/usb/host/fsl-mph-dr-of.c | 2 +- drivers/usb/host/ohci-spear.c | 2 +- drivers/usb/musb/musb_core.c | 22 +++++++++++----------- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c index 424bff91352..126978038f7 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.c +++ b/drivers/usb/chipidea/ci13xxx_imx.c @@ -85,7 +85,7 @@ EXPORT_SYMBOL_GPL(usbmisc_get_init_data); /* End of common functions shared by usbmisc drivers*/ -static struct ci13xxx_platform_data ci13xxx_imx_platdata __devinitdata = { +static struct ci13xxx_platform_data ci13xxx_imx_platdata = { .name = "ci13xxx_imx", .flags = CI13XXX_REQUIRE_TRANSCEIVER | CI13XXX_PULLUP_ON_VBUS | diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index f0103dd2a10..a20acc14e69 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -2548,7 +2548,7 @@ net2272_pci_remove(struct pci_dev *pdev) } /* Table of matching PCI IDs */ -static struct pci_device_id __devinitdata pci_ids[] = { +static struct pci_device_id pci_ids[] = { { /* RDK 1 card */ .class = ((PCI_CLASS_BRIDGE_OTHER << 8) | 0xfe), .class_mask = 0, diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c index 3fadff8f8d3..466c1bb5b96 100644 --- a/drivers/usb/host/ehci-spear.c +++ b/drivers/usb/host/ehci-spear.c @@ -199,7 +199,7 @@ static int spear_ehci_hcd_drv_remove(struct platform_device *pdev) return 0; } -static struct of_device_id spear_ehci_id_table[] __devinitdata = { +static struct of_device_id spear_ehci_id_table[] = { { .compatible = "st,spear600-ehci", }, { }, }; diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index ef0a6ef7875..acf17556bd8 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -805,7 +805,7 @@ static void tegra_ehci_hcd_shutdown(struct platform_device *pdev) hcd->driver->shutdown(hcd); } -static struct of_device_id tegra_ehci_of_match[] __devinitdata = { +static struct of_device_id tegra_ehci_of_match[] = { { .compatible = "nvidia,tegra20-ehci", }, { }, }; diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index dc0aeba35c9..5faf796fc6c 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -24,7 +24,7 @@ struct fsl_usb2_dev_data { enum fsl_usb2_operating_modes op_mode; /* operating mode */ }; -struct fsl_usb2_dev_data dr_mode_data[] __devinitdata = { +struct fsl_usb2_dev_data dr_mode_data[] = { { .dr_mode = "host", .drivers = { "fsl-ehci", NULL, NULL, }, diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index b7fc2fc56c8..9020bf0e2ec 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -216,7 +216,7 @@ static int spear_ohci_hcd_drv_resume(struct platform_device *dev) } #endif -static struct of_device_id spear_ohci_id_table[] __devinitdata = { +static struct of_device_id spear_ohci_id_table[] = { { .compatible = "st,spear600-ohci", }, { }, }; diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index f17a3e79dbe..a332bb81aa3 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1040,12 +1040,12 @@ static void musb_shutdown(struct platform_device *pdev) || defined(CONFIG_USB_MUSB_AM35X_MODULE) \ || defined(CONFIG_USB_MUSB_DSPS) \ || defined(CONFIG_USB_MUSB_DSPS_MODULE) -static ushort __devinitdata fifo_mode = 4; +static ushort fifo_mode = 4; #elif defined(CONFIG_USB_MUSB_UX500) \ || defined(CONFIG_USB_MUSB_UX500_MODULE) -static ushort __devinitdata fifo_mode = 5; +static ushort fifo_mode = 5; #else -static ushort __devinitdata fifo_mode = 2; +static ushort fifo_mode = 2; #endif /* "modprobe ... fifo_mode=1" etc */ @@ -1058,7 +1058,7 @@ MODULE_PARM_DESC(fifo_mode, "initial endpoint configuration"); */ /* mode 0 - fits in 2KB */ -static struct musb_fifo_cfg __devinitdata mode_0_cfg[] = { +static struct musb_fifo_cfg mode_0_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, }, @@ -1067,7 +1067,7 @@ static struct musb_fifo_cfg __devinitdata mode_0_cfg[] = { }; /* mode 1 - fits in 4KB */ -static struct musb_fifo_cfg __devinitdata mode_1_cfg[] = { +static struct musb_fifo_cfg mode_1_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, }, { .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, .mode = BUF_DOUBLE, }, @@ -1076,7 +1076,7 @@ static struct musb_fifo_cfg __devinitdata mode_1_cfg[] = { }; /* mode 2 - fits in 4KB */ -static struct musb_fifo_cfg __devinitdata mode_2_cfg[] = { +static struct musb_fifo_cfg mode_2_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, @@ -1086,7 +1086,7 @@ static struct musb_fifo_cfg __devinitdata mode_2_cfg[] = { }; /* mode 3 - fits in 4KB */ -static struct musb_fifo_cfg __devinitdata mode_3_cfg[] = { +static struct musb_fifo_cfg mode_3_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, @@ -1096,7 +1096,7 @@ static struct musb_fifo_cfg __devinitdata mode_3_cfg[] = { }; /* mode 4 - fits in 16KB */ -static struct musb_fifo_cfg __devinitdata mode_4_cfg[] = { +static struct musb_fifo_cfg mode_4_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, @@ -1127,7 +1127,7 @@ static struct musb_fifo_cfg __devinitdata mode_4_cfg[] = { }; /* mode 5 - fits in 8KB */ -static struct musb_fifo_cfg __devinitdata mode_5_cfg[] = { +static struct musb_fifo_cfg mode_5_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, @@ -1234,7 +1234,7 @@ fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, return offset + (maxpacket << ((c_size & MUSB_FIFOSZ_DPB) ? 1 : 0)); } -static struct musb_fifo_cfg __devinitdata ep0_cfg = { +static struct musb_fifo_cfg ep0_cfg = { .style = FIFO_RXTX, .maxpacket = 64, }; @@ -1578,7 +1578,7 @@ irqreturn_t musb_interrupt(struct musb *musb) EXPORT_SYMBOL_GPL(musb_interrupt); #ifndef CONFIG_MUSB_PIO_ONLY -static bool __devinitdata use_dma = 1; +static bool use_dma = 1; /* "modprobe ... use_dma=0" etc */ module_param(use_dma, bool, 0); -- cgit v1.2.3 From 2f82686e8c261d96d07bb1594d987cd6d5c64af6 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:25:20 -0500 Subject: usb: remove use of __devinitconst CONFIG_HOTPLUG is going away as an option so __devinitconst is no longer needed. Signed-off-by: Bill Pemberton Cc: Li Yang Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_qe_udc.c | 2 +- drivers/usb/host/bcma-hcd.c | 2 +- drivers/usb/host/pci-quirks.c | 2 +- drivers/usb/host/ssb-hcd.c | 2 +- drivers/usb/musb/musb_dsps.c | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 8ad04a0b9e7..b13bc73f56b 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2710,7 +2710,7 @@ static int __devexit qe_udc_remove(struct platform_device *ofdev) } /*-------------------------------------------------------------------------*/ -static const struct of_device_id qe_udc_match[] __devinitconst = { +static const struct of_device_id qe_udc_match[] = { { .compatible = "fsl,mpc8323-qe-usb", .data = (void *)PORT_QE, diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index 8c83ed90acb..649780b480b 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c @@ -305,7 +305,7 @@ static int bcma_hcd_resume(struct bcma_device *dev) #define bcma_hcd_resume NULL #endif /* CONFIG_PM */ -static const struct bcma_device_id bcma_hcd_table[] __devinitconst = { +static const struct bcma_device_id bcma_hcd_table[] = { BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_USB20_HOST, BCMA_ANY_REV, BCMA_ANY_CLASS), BCMA_CORETABLE_END }; diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index a018e706c0e..15cfb06769e 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -533,7 +533,7 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) iounmap(base); } -static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = { +static const struct dmi_system_id ehci_dmi_nohandoff_table[] = { { /* Pegatron Lucid (ExoPC) */ .matches = { diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c index 79aa95832b2..bdb9d7055da 100644 --- a/drivers/usb/host/ssb-hcd.c +++ b/drivers/usb/host/ssb-hcd.c @@ -248,7 +248,7 @@ static int ssb_hcd_resume(struct ssb_device *dev) #define ssb_hcd_resume NULL #endif /* CONFIG_PM */ -static const struct ssb_device_id ssb_hcd_table[] __devinitconst = { +static const struct ssb_device_id ssb_hcd_table[] = { SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV), SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV), SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB20_HOST, SSB_ANY_REV), diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index f8affd7a30c..605cd59d149 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -716,7 +716,7 @@ static int dsps_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(dsps_pm_ops, dsps_suspend, dsps_resume); -static const struct dsps_musb_wrapper ti81xx_driver_data __devinitconst = { +static const struct dsps_musb_wrapper ti81xx_driver_data = { .revision = 0x00, .control = 0x14, .status = 0x18, @@ -747,7 +747,7 @@ static const struct dsps_musb_wrapper ti81xx_driver_data __devinitconst = { .instances = 1, }; -static const struct platform_device_id musb_dsps_id_table[] __devinitconst = { +static const struct platform_device_id musb_dsps_id_table[] = { { .name = "musb-ti81xx", .driver_data = (kernel_ulong_t) &ti81xx_driver_data, @@ -757,7 +757,7 @@ static const struct platform_device_id musb_dsps_id_table[] __devinitconst = { MODULE_DEVICE_TABLE(platform, musb_dsps_id_table); #ifdef CONFIG_OF -static const struct of_device_id musb_dsps_of_match[] __devinitconst = { +static const struct of_device_id musb_dsps_of_match[] = { { .compatible = "ti,musb-am33xx", .data = (void *) &ti81xx_driver_data, }, { }, -- cgit v1.2.3 From fb4e98ab63433c4d3a1588ea91c73f1cd7ebaa00 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:26:20 -0500 Subject: usb: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Cc: Peter Korsgaard Cc: Alexander Shishkin Acked-by: Felipe Balbi Cc: Li Yang Cc: Alan Stern Cc: Wan ZongShun Cc: Ben Dooks Cc: Kukjin Kim Signed-off-by: Greg Kroah-Hartman --- drivers/usb/c67x00/c67x00-drv.c | 2 +- drivers/usb/chipidea/ci13xxx_imx.c | 2 +- drivers/usb/chipidea/ci13xxx_msm.c | 2 +- drivers/usb/chipidea/ci13xxx_pci.c | 2 +- drivers/usb/chipidea/core.c | 2 +- drivers/usb/chipidea/usbmisc_imx6q.c | 2 +- drivers/usb/dwc3/core.c | 2 +- drivers/usb/dwc3/debugfs.c | 2 +- drivers/usb/dwc3/dwc3-exynos.c | 2 +- drivers/usb/dwc3/dwc3-omap.c | 2 +- drivers/usb/dwc3/dwc3-pci.c | 2 +- drivers/usb/gadget/bcm63xx_udc.c | 2 +- drivers/usb/gadget/fsl_qe_udc.c | 2 +- drivers/usb/gadget/hid.c | 2 +- drivers/usb/gadget/lpc32xx_udc.c | 2 +- drivers/usb/gadget/mv_u3d_core.c | 2 +- drivers/usb/gadget/mv_udc_core.c | 2 +- drivers/usb/gadget/net2272.c | 10 +++++----- drivers/usb/gadget/omap_udc.c | 2 +- drivers/usb/gadget/s3c-hsotg.c | 4 ++-- drivers/usb/host/bcma-hcd.c | 2 +- drivers/usb/host/ehci-atmel.c | 2 +- drivers/usb/host/ehci-msm.c | 2 +- drivers/usb/host/ehci-platform.c | 2 +- drivers/usb/host/ehci-s5p.c | 2 +- drivers/usb/host/ehci-w90x900.c | 2 +- drivers/usb/host/fhci-hcd.c | 4 ++-- drivers/usb/host/fsl-mph-dr-of.c | 4 ++-- drivers/usb/host/isp1362-hcd.c | 2 +- drivers/usb/host/isp1760-if.c | 2 +- drivers/usb/host/ohci-at91.c | 6 +++--- drivers/usb/host/ohci-exynos.c | 2 +- drivers/usb/host/ohci-jz4740.c | 2 +- drivers/usb/host/ohci-omap3.c | 2 +- drivers/usb/host/ohci-platform.c | 2 +- drivers/usb/host/ohci-s3c2410.c | 2 +- drivers/usb/host/ohci-tmio.c | 2 +- drivers/usb/host/r8a66597-hcd.c | 2 +- drivers/usb/host/sl811-hcd.c | 2 +- drivers/usb/host/ssb-hcd.c | 4 ++-- drivers/usb/host/u132-hcd.c | 2 +- drivers/usb/musb/am35x.c | 2 +- drivers/usb/musb/blackfin.c | 2 +- drivers/usb/musb/da8xx.c | 2 +- drivers/usb/musb/davinci.c | 2 +- drivers/usb/musb/musb_core.c | 2 +- drivers/usb/musb/musb_dsps.c | 2 +- drivers/usb/musb/omap2430.c | 2 +- drivers/usb/musb/tusb6010.c | 2 +- drivers/usb/musb/ux500.c | 2 +- drivers/usb/otg/ab8500-usb.c | 2 +- drivers/usb/otg/fsl_otg.c | 2 +- drivers/usb/otg/msm_otg.c | 2 +- drivers/usb/otg/mxs-phy.c | 2 +- drivers/usb/otg/nop-usb-xceiv.c | 2 +- drivers/usb/phy/omap-usb2.c | 2 +- drivers/usb/phy/rcar-phy.c | 2 +- drivers/usb/renesas_usbhs/common.c | 2 +- 58 files changed, 68 insertions(+), 68 deletions(-) diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c index 21913dfeecc..fe815ecd557 100644 --- a/drivers/usb/c67x00/c67x00-drv.c +++ b/drivers/usb/c67x00/c67x00-drv.c @@ -191,7 +191,7 @@ static int c67x00_drv_probe(struct platform_device *pdev) return ret; } -static int __devexit c67x00_drv_remove(struct platform_device *pdev) +static int c67x00_drv_remove(struct platform_device *pdev) { struct c67x00_device *c67x00 = platform_get_drvdata(pdev); struct resource *res; diff --git a/drivers/usb/chipidea/ci13xxx_imx.c b/drivers/usb/chipidea/ci13xxx_imx.c index 126978038f7..8c291220be7 100644 --- a/drivers/usb/chipidea/ci13xxx_imx.c +++ b/drivers/usb/chipidea/ci13xxx_imx.c @@ -220,7 +220,7 @@ put_np: return ret; } -static int __devexit ci13xxx_imx_remove(struct platform_device *pdev) +static int ci13xxx_imx_remove(struct platform_device *pdev) { struct ci13xxx_imx_data *data = platform_get_drvdata(pdev); diff --git a/drivers/usb/chipidea/ci13xxx_msm.c b/drivers/usb/chipidea/ci13xxx_msm.c index e8a8ba36b10..7d16681fd3d 100644 --- a/drivers/usb/chipidea/ci13xxx_msm.c +++ b/drivers/usb/chipidea/ci13xxx_msm.c @@ -77,7 +77,7 @@ static int ci13xxx_msm_probe(struct platform_device *pdev) return 0; } -static int __devexit ci13xxx_msm_remove(struct platform_device *pdev) +static int ci13xxx_msm_remove(struct platform_device *pdev) { struct platform_device *plat_ci = platform_get_drvdata(pdev); diff --git a/drivers/usb/chipidea/ci13xxx_pci.c b/drivers/usb/chipidea/ci13xxx_pci.c index cb7eb3ede5e..9b227e39299 100644 --- a/drivers/usb/chipidea/ci13xxx_pci.c +++ b/drivers/usb/chipidea/ci13xxx_pci.c @@ -107,7 +107,7 @@ static int ci13xxx_pci_probe(struct pci_dev *pdev, * first invoking the udc_remove() and then releases * all PCI resources allocated for this USB device controller */ -static void __devexit ci13xxx_pci_remove(struct pci_dev *pdev) +static void ci13xxx_pci_remove(struct pci_dev *pdev) { struct platform_device *plat_ci = pci_get_drvdata(pdev); diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 7f9c0d21c89..5a4a5eca419 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -508,7 +508,7 @@ rm_wq: return ret; } -static int __devexit ci_hdrc_remove(struct platform_device *pdev) +static int ci_hdrc_remove(struct platform_device *pdev) { struct ci13xxx *ci = platform_get_drvdata(pdev); diff --git a/drivers/usb/chipidea/usbmisc_imx6q.c b/drivers/usb/chipidea/usbmisc_imx6q.c index ee6fa872f93..845efe29e6b 100644 --- a/drivers/usb/chipidea/usbmisc_imx6q.c +++ b/drivers/usb/chipidea/usbmisc_imx6q.c @@ -127,7 +127,7 @@ static int usbmisc_imx6q_probe(struct platform_device *pdev) return 0; } -static int __devexit usbmisc_imx6q_remove(struct platform_device *pdev) +static int usbmisc_imx6q_remove(struct platform_device *pdev) { usbmisc_unset_ops(&imx6q_usbmisc_ops); clk_disable_unprepare(usbmisc->clk); diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 71610800cd8..3a4004a620a 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -547,7 +547,7 @@ err0: return ret; } -static int __devexit dwc3_remove(struct platform_device *pdev) +static int dwc3_remove(struct platform_device *pdev) { struct dwc3 *dwc = platform_get_drvdata(pdev); struct resource *res; diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 33ae98c5278..92604b4f971 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -703,7 +703,7 @@ err0: return ret; } -void __devexit dwc3_debugfs_exit(struct dwc3 *dwc) +void dwc3_debugfs_exit(struct dwc3 *dwc) { debugfs_remove_recursive(dwc->root); dwc->root = NULL; diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index d43f0760ca6..aae5328ac77 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -170,7 +170,7 @@ err0: return ret; } -static int __devexit dwc3_exynos_remove(struct platform_device *pdev) +static int dwc3_exynos_remove(struct platform_device *pdev) { struct dwc3_exynos *exynos = platform_get_drvdata(pdev); diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index e114bb58ccf..f31867fd257 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -421,7 +421,7 @@ err2: return ret; } -static int __devexit dwc3_omap_remove(struct platform_device *pdev) +static int dwc3_omap_remove(struct platform_device *pdev) { struct dwc3_omap *omap = platform_get_drvdata(pdev); diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 68e389b589d..7d70f44567d 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -194,7 +194,7 @@ err1: return ret; } -static void __devexit dwc3_pci_remove(struct pci_dev *pci) +static void dwc3_pci_remove(struct pci_dev *pci) { struct dwc3_pci *glue = pci_get_drvdata(pci); diff --git a/drivers/usb/gadget/bcm63xx_udc.c b/drivers/usb/gadget/bcm63xx_udc.c index 18eff74e336..47a49931361 100644 --- a/drivers/usb/gadget/bcm63xx_udc.c +++ b/drivers/usb/gadget/bcm63xx_udc.c @@ -2433,7 +2433,7 @@ out_uninit: * bcm63xx_udc_remove - Remove the device from the system. * @pdev: Platform device struct from the bcm63xx BSP code. */ -static int __devexit bcm63xx_udc_remove(struct platform_device *pdev) +static int bcm63xx_udc_remove(struct platform_device *pdev) { struct bcm63xx_udc *udc = platform_get_drvdata(pdev); diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index b13bc73f56b..ec50f18c889 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2651,7 +2651,7 @@ static int qe_udc_resume(struct platform_device *dev) } #endif -static int __devexit qe_udc_remove(struct platform_device *ofdev) +static int qe_udc_remove(struct platform_device *ofdev) { struct qe_udc *udc = dev_get_drvdata(&ofdev->dev); struct qe_ep *ep; diff --git a/drivers/usb/gadget/hid.c b/drivers/usb/gadget/hid.c index 33deed6e794..c36260ea8bf 100644 --- a/drivers/usb/gadget/hid.c +++ b/drivers/usb/gadget/hid.c @@ -203,7 +203,7 @@ static int __init hidg_plat_driver_probe(struct platform_device *pdev) return 0; } -static int __devexit hidg_plat_driver_remove(struct platform_device *pdev) +static int hidg_plat_driver_remove(struct platform_device *pdev) { struct hidg_func_node *e, *n; diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index 52ad15ce44a..dd1c9b1fe52 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -3352,7 +3352,7 @@ phy_fail: return retval; } -static int __devexit lpc32xx_udc_remove(struct platform_device *pdev) +static int lpc32xx_udc_remove(struct platform_device *pdev) { struct lpc32xx_udc *udc = platform_get_drvdata(pdev); diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c index 8cfd5b028db..b5cea273c95 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/mv_u3d_core.c @@ -1763,7 +1763,7 @@ static void mv_u3d_gadget_release(struct device *dev) dev_dbg(dev, "%s\n", __func__); } -static __devexit int mv_u3d_remove(struct platform_device *dev) +static int mv_u3d_remove(struct platform_device *dev) { struct mv_u3d *u3d = platform_get_drvdata(dev); diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 24196492ae2..379aac7b82f 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2128,7 +2128,7 @@ static void gadget_release(struct device *_dev) complete(udc->done); } -static int __devexit mv_udc_remove(struct platform_device *dev) +static int mv_udc_remove(struct platform_device *dev) { struct mv_udc *udc = the_controller; int clk_i; diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index a20acc14e69..d226058e3b8 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -2193,7 +2193,7 @@ net2272_gadget_release(struct device *_dev) /*---------------------------------------------------------------------------*/ -static void __devexit +static void net2272_remove(struct net2272 *dev) { usb_del_gadget_udc(&dev->gadget); @@ -2488,7 +2488,7 @@ net2272_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return ret; } -static void __devexit +static void net2272_rdk1_remove(struct pci_dev *pdev, struct net2272 *dev) { int i; @@ -2510,7 +2510,7 @@ net2272_rdk1_remove(struct pci_dev *pdev, struct net2272 *dev) } } -static void __devexit +static void net2272_rdk2_remove(struct pci_dev *pdev, struct net2272 *dev) { int i; @@ -2529,7 +2529,7 @@ net2272_rdk2_remove(struct pci_dev *pdev, struct net2272 *dev) pci_resource_len(pdev, i)); } -static void __devexit +static void net2272_pci_remove(struct pci_dev *pdev) { struct net2272 *dev = pci_get_drvdata(pdev); @@ -2660,7 +2660,7 @@ net2272_plat_probe(struct platform_device *pdev) return ret; } -static int __devexit +static int net2272_plat_remove(struct platform_device *pdev) { struct net2272 *dev = platform_get_drvdata(pdev); diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index cbc07c117af..9412bf53b86 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -2974,7 +2974,7 @@ cleanup0: return status; } -static int __devexit omap_udc_remove(struct platform_device *pdev) +static int omap_udc_remove(struct platform_device *pdev) { DECLARE_COMPLETION_ONSTACK(done); diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index 6fdb1bd98e9..141971d9051 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -3460,7 +3460,7 @@ static void s3c_hsotg_create_debug(struct s3c_hsotg *hsotg) * * Cleanup (remove) the debugfs files for use on module exit. */ -static void __devexit s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg) +static void s3c_hsotg_delete_debug(struct s3c_hsotg *hsotg) { unsigned epidx; @@ -3675,7 +3675,7 @@ err_clk: * s3c_hsotg_remove - remove function for hsotg driver * @pdev: The platform information for the driver */ -static int __devexit s3c_hsotg_remove(struct platform_device *pdev) +static int s3c_hsotg_remove(struct platform_device *pdev) { struct s3c_hsotg *hsotg = platform_get_drvdata(pdev); diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index 649780b480b..df13d425e9c 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c @@ -265,7 +265,7 @@ err_free_usb_dev: return err; } -static void __devexit bcma_hcd_remove(struct bcma_device *dev) +static void bcma_hcd_remove(struct bcma_device *dev) { struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev); struct platform_device *ohci_dev = usb_dev->ohci_dev; diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 96bf00d3261..27639487f7a 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -182,7 +182,7 @@ fail_create_hcd: return retval; } -static int __devexit ehci_atmel_drv_remove(struct platform_device *pdev) +static int ehci_atmel_drv_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index e0acfd589a8..88a49c87e74 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -173,7 +173,7 @@ put_hcd: return ret; } -static int __devexit ehci_msm_remove(struct platform_device *pdev) +static int ehci_msm_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index 615cba016a6..58fa0c90c7c 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -126,7 +126,7 @@ err_power: return err; } -static int __devexit ehci_platform_remove(struct platform_device *dev) +static int ehci_platform_remove(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct usb_ehci_pdata *pdata = dev->dev.platform_data; diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index 2cf19d1ab4b..319dcfaa873 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c @@ -189,7 +189,7 @@ fail_clk: return err; } -static int __devexit s5p_ehci_remove(struct platform_device *pdev) +static int s5p_ehci_remove(struct platform_device *pdev) { struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev); diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index bf8d462c26a..59e0e24c753 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -155,7 +155,7 @@ static int ehci_w90x900_probe(struct platform_device *pdev) return usb_w90x900_probe(&ehci_w90x900_hc_driver, pdev); } -static int __devexit ehci_w90x900_remove(struct platform_device *pdev) +static int ehci_w90x900_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 618f143748a..0b46542591f 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -780,7 +780,7 @@ err_regs: return ret; } -static int __devexit fhci_remove(struct device *dev) +static int fhci_remove(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct fhci_hcd *fhci = hcd_to_fhci(hcd); @@ -803,7 +803,7 @@ static int __devexit fhci_remove(struct device *dev) return 0; } -static int __devexit of_fhci_remove(struct platform_device *ofdev) +static int of_fhci_remove(struct platform_device *ofdev) { return fhci_remove(&ofdev->dev); } diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 5faf796fc6c..5105127c1d4 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -224,13 +224,13 @@ static int fsl_usb2_mph_dr_of_probe(struct platform_device *ofdev) return 0; } -static int __devexit __unregister_subdev(struct device *dev, void *d) +static int __unregister_subdev(struct device *dev, void *d) { platform_device_unregister(to_platform_device(dev)); return 0; } -static int __devexit fsl_usb2_mph_dr_of_remove(struct platform_device *ofdev) +static int fsl_usb2_mph_dr_of_remove(struct platform_device *ofdev) { device_for_each_child(&ofdev->dev, NULL, __unregister_subdev); return 0; diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 5f8b63ce4be..974480c516f 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -2645,7 +2645,7 @@ static struct hc_driver isp1362_hc_driver = { /*-------------------------------------------------------------------------*/ -static int __devexit isp1362_remove(struct platform_device *pdev) +static int isp1362_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index d752a4c4281..bbb791bd761 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -413,7 +413,7 @@ out: return ret; } -static int __devexit isp1760_plat_remove(struct platform_device *pdev) +static int isp1760_plat_remove(struct platform_device *pdev) { struct resource *mem_res; resource_size_t mem_size; diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index ff94a7479a7..221850a8c25 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -94,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ -static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); +static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -203,7 +203,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, * context, "rmmod" or something similar. * */ -static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd, +static void usb_hcd_at91_remove(struct usb_hcd *hcd, struct platform_device *pdev) { usb_remove_hcd(hcd); @@ -641,7 +641,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev); } -static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev) +static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) { struct at91_usbh_data *pdata = pdev->dev.platform_data; int i; diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index 1288cdb3137..aa3b8844bb9 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -175,7 +175,7 @@ fail_clk: return err; } -static int __devexit exynos_ohci_remove(struct platform_device *pdev) +static int exynos_ohci_remove(struct platform_device *pdev) { struct exynos4_ohci_platdata *pdata = pdev->dev.platform_data; struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c index 59feb873813..8062bb9dea1 100644 --- a/drivers/usb/host/ohci-jz4740.c +++ b/drivers/usb/host/ohci-jz4740.c @@ -239,7 +239,7 @@ err_free: return ret; } -static __devexit int jz4740_ohci_remove(struct platform_device *pdev) +static int jz4740_ohci_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct jz4740_ohci_hcd *jz4740_ohci = hcd_to_jz4740_hcd(hcd); diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c index b2398aa6c7a..4382af3a45f 100644 --- a/drivers/usb/host/ohci-omap3.c +++ b/drivers/usb/host/ohci-omap3.c @@ -209,7 +209,7 @@ err_io: * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. */ -static int __devexit ohci_hcd_omap3_remove(struct platform_device *pdev) +static int ohci_hcd_omap3_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct usb_hcd *hcd = dev_get_drvdata(dev); diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index c3f76fa8d7d..084503b03fc 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -149,7 +149,7 @@ err_power: return err; } -static int __devexit ohci_platform_remove(struct platform_device *dev) +static int ohci_platform_remove(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct usb_ohci_pdata *pdata = dev->dev.platform_data; diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 4f29e0b086b..ad0f5526960 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -463,7 +463,7 @@ static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev) return usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev); } -static int __devexit ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev) +static int ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index 5996a3b0a4d..d370245a4ee 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c @@ -271,7 +271,7 @@ err_usb_create_hcd: return ret; } -static int __devexit ohci_hcd_tmio_drv_remove(struct platform_device *dev) +static int ohci_hcd_tmio_drv_remove(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); struct tmio_hcd *tmio = hcd_to_tmio(hcd); diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index e97dfad526f..a6fd8f5371d 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2391,7 +2391,7 @@ static const struct dev_pm_ops r8a66597_dev_pm_ops = { #define R8A66597_DEV_PM_OPS NULL #endif -static int __devexit r8a66597_remove(struct platform_device *pdev) +static int r8a66597_remove(struct platform_device *pdev) { struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev); struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597); diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 782127d9dfc..d62f0404baa 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -1595,7 +1595,7 @@ static struct hc_driver sl811h_hc_driver = { /*-------------------------------------------------------------------------*/ -static int __devexit +static int sl811h_remove(struct platform_device *dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c index bdb9d7055da..74af2c6287d 100644 --- a/drivers/usb/host/ssb-hcd.c +++ b/drivers/usb/host/ssb-hcd.c @@ -206,7 +206,7 @@ err_free_usb_dev: return err; } -static void __devexit ssb_hcd_remove(struct ssb_device *dev) +static void ssb_hcd_remove(struct ssb_device *dev) { struct ssb_hcd_device *usb_dev = ssb_get_drvdata(dev); struct platform_device *ohci_dev = usb_dev->ohci_dev; @@ -220,7 +220,7 @@ static void __devexit ssb_hcd_remove(struct ssb_device *dev) ssb_device_disable(dev, 0); } -static void __devexit ssb_hcd_shutdown(struct ssb_device *dev) +static void ssb_hcd_shutdown(struct ssb_device *dev) { ssb_device_disable(dev, 0); } diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 8bf78e652a8..5efdffe3236 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -2990,7 +2990,7 @@ static struct hc_driver u132_hc_driver = { * synchronously - but instead should immediately stop activity to the * device and asynchronously call usb_remove_hcd() */ -static int __devexit u132_remove(struct platform_device *pdev) +static int u132_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); if (hcd) { diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index a27bb851567..3d1c71b50f7 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -560,7 +560,7 @@ err0: return ret; } -static int __devexit am35x_remove(struct platform_device *pdev) +static int am35x_remove(struct platform_device *pdev) { struct am35x_glue *glue = platform_get_drvdata(pdev); diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 12beb0e3114..14dab9f9b3d 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -510,7 +510,7 @@ err0: return ret; } -static int __devexit bfin_remove(struct platform_device *pdev) +static int bfin_remove(struct platform_device *pdev) { struct bfin_glue *glue = platform_get_drvdata(pdev); diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index c4fb235985b..97996af2646 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -555,7 +555,7 @@ err0: return ret; } -static int __devexit da8xx_remove(struct platform_device *pdev) +static int da8xx_remove(struct platform_device *pdev) { struct da8xx_glue *glue = platform_get_drvdata(pdev); diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 8877c1a7dbb..b1c01cad28b 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -587,7 +587,7 @@ err0: return ret; } -static int __devexit davinci_remove(struct platform_device *pdev) +static int davinci_remove(struct platform_device *pdev) { struct davinci_glue *glue = platform_get_drvdata(pdev); diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index a332bb81aa3..57cc9c6eaa9 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2034,7 +2034,7 @@ static int musb_probe(struct platform_device *pdev) return status; } -static int __devexit musb_remove(struct platform_device *pdev) +static int musb_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct musb *musb = dev_to_musb(dev); diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 605cd59d149..9a975aa0dee 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -668,7 +668,7 @@ err1: err0: return ret; } -static int __devexit dsps_remove(struct platform_device *pdev) +static int dsps_remove(struct platform_device *pdev) { struct dsps_glue *glue = platform_get_drvdata(pdev); const struct dsps_musb_wrapper *wrp = glue->wrp; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 06850f22739..da00af46079 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -605,7 +605,7 @@ err0: return ret; } -static int __devexit omap2430_remove(struct platform_device *pdev) +static int omap2430_remove(struct platform_device *pdev) { struct omap2430_glue *glue = platform_get_drvdata(pdev); diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index a03b7befd2e..8bde6fc5eb7 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1215,7 +1215,7 @@ err0: return ret; } -static int __devexit tusb_remove(struct platform_device *pdev) +static int tusb_remove(struct platform_device *pdev) { struct tusb6010_glue *glue = platform_get_drvdata(pdev); diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 6b12001eb88..a27ca1a9c99 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -163,7 +163,7 @@ err0: return ret; } -static int __devexit ux500_remove(struct platform_device *pdev) +static int ux500_remove(struct platform_device *pdev) { struct ux500_glue *glue = platform_get_drvdata(pdev); diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c index f0ba931f0d5..2d86f26a018 100644 --- a/drivers/usb/otg/ab8500-usb.c +++ b/drivers/usb/otg/ab8500-usb.c @@ -546,7 +546,7 @@ fail0: return err; } -static int __devexit ab8500_usb_remove(struct platform_device *pdev) +static int ab8500_usb_remove(struct platform_device *pdev) { struct ab8500_usb *ab = platform_get_drvdata(pdev); diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c index 2b9a83856a5..d16adb41eb2 100644 --- a/drivers/usb/otg/fsl_otg.c +++ b/drivers/usb/otg/fsl_otg.c @@ -1144,7 +1144,7 @@ static int fsl_otg_probe(struct platform_device *pdev) return ret; } -static int __devexit fsl_otg_remove(struct platform_device *pdev) +static int fsl_otg_remove(struct platform_device *pdev) { struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c index eef0dd276e1..3b9f0d95113 100644 --- a/drivers/usb/otg/msm_otg.c +++ b/drivers/usb/otg/msm_otg.c @@ -1606,7 +1606,7 @@ free_motg: return ret; } -static int __devexit msm_otg_remove(struct platform_device *pdev) +static int msm_otg_remove(struct platform_device *pdev) { struct msm_otg *motg = platform_get_drvdata(pdev); struct usb_phy *phy = &motg->phy; diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c index 001fdde12d7..76302720055 100644 --- a/drivers/usb/otg/mxs-phy.c +++ b/drivers/usb/otg/mxs-phy.c @@ -149,7 +149,7 @@ static int mxs_phy_probe(struct platform_device *pdev) return 0; } -static int __devexit mxs_phy_remove(struct platform_device *pdev) +static int mxs_phy_remove(struct platform_device *pdev) { platform_set_drvdata(pdev, NULL); diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c index 28f70e21ad6..a3ce24b94a7 100644 --- a/drivers/usb/otg/nop-usb-xceiv.c +++ b/drivers/usb/otg/nop-usb-xceiv.c @@ -141,7 +141,7 @@ exit: return err; } -static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev) +static int nop_usb_xceiv_remove(struct platform_device *pdev) { struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); diff --git a/drivers/usb/phy/omap-usb2.c b/drivers/usb/phy/omap-usb2.c index c10fb8b1fdb..26ae8f49225 100644 --- a/drivers/usb/phy/omap-usb2.c +++ b/drivers/usb/phy/omap-usb2.c @@ -199,7 +199,7 @@ static int omap_usb2_probe(struct platform_device *pdev) return 0; } -static int __devexit omap_usb2_remove(struct platform_device *pdev) +static int omap_usb2_remove(struct platform_device *pdev) { struct omap_usb *phy = platform_get_drvdata(pdev); diff --git a/drivers/usb/phy/rcar-phy.c b/drivers/usb/phy/rcar-phy.c index 84ac2a77de7..a35681b0c50 100644 --- a/drivers/usb/phy/rcar-phy.c +++ b/drivers/usb/phy/rcar-phy.c @@ -196,7 +196,7 @@ static int rcar_usb_phy_probe(struct platform_device *pdev) return ret; } -static int __devexit rcar_usb_phy_remove(struct platform_device *pdev) +static int rcar_usb_phy_remove(struct platform_device *pdev) { struct rcar_usb_phy_priv *priv = platform_get_drvdata(pdev); diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 2aa7c1a38ce..38bce046f4d 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -556,7 +556,7 @@ probe_end_pipe_exit: return ret; } -static int __devexit usbhs_remove(struct platform_device *pdev) +static int usbhs_remove(struct platform_device *pdev) { struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; -- cgit v1.2.3 From 564e69893c63cefe4bcbdeda4f940bf68b6b4491 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 17 Nov 2012 18:06:11 +0300 Subject: USB: usbtest: prevent a divide by zero bug If param->length is zero, then this could lead to a divide by zero bug later in the function when we do: size %= max; Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usbtest.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index f10bd970d50..7667b12f2ff 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -423,6 +423,9 @@ alloc_sglist(int nents, int max, int vary) unsigned i; unsigned size = max; + if (max == 0) + return NULL; + sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL); if (!sg) return NULL; -- cgit v1.2.3 From c058f7ab94143dfa2286e496019b7ad0b95502ac Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 21 Nov 2012 11:01:19 +0530 Subject: USB: core: Free the allocated memory before exiting on error 'new_interfaces' should be freed to avoid memory leak. Cc: Sarah Sharp Signed-off-by: Sachin Kamat Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 73c5d1a0413..131f73649b6 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1786,7 +1786,8 @@ free_interfaces: if (dev->actconfig && usb_disable_lpm(dev)) { dev_err(&dev->dev, "%s Failed to disable LPM\n.", __func__); mutex_unlock(hcd->bandwidth_mutex); - return -ENOMEM; + ret = -ENOMEM; + goto free_interfaces; } ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); if (ret < 0) { -- cgit v1.2.3 From f38c46021aaa0871a96bd922ccbcc9d61c4ae49e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:21 +0100 Subject: USB: opticon: remove redundant bulk urb fill The private bulk in urb is set up at open and does not need to be reinitialised at every resubmit. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 6aba731d486..cb8674ec5fb 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -135,11 +135,6 @@ exit: /* Continue trying to always read if we should */ if (!priv->throttled) { - usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev, - usb_rcvbulkpipe(priv->udev, - priv->bulk_address), - priv->bulk_in_buffer, priv->buffer_size, - opticon_read_bulk_callback, priv); result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); if (result) dev_err(&port->dev, -- cgit v1.2.3 From 0b8718a264f58b096753e29f7e04f188bf64938e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:22 +0100 Subject: USB: opticon: move private urb initialisation to attach There no need to reinitialise the private urb at every open. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index cb8674ec5fb..8c66471f3bf 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -184,13 +184,6 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) /* Clear RTS line */ send_control_msg(port, CONTROL_RTS, 0); - /* Setup the read URB and start reading from the device */ - usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev, - usb_rcvbulkpipe(priv->udev, - priv->bulk_address), - priv->bulk_in_buffer, priv->buffer_size, - opticon_read_bulk_callback, priv); - /* clear the halt status of the enpoint */ usb_clear_halt(priv->udev, priv->bulk_read_urb->pipe); @@ -530,6 +523,12 @@ static int opticon_startup(struct usb_serial *serial) goto error; } + usb_fill_bulk_urb(priv->bulk_read_urb, serial->dev, + usb_rcvbulkpipe(serial->dev, + priv->bulk_address), + priv->bulk_in_buffer, priv->buffer_size, + opticon_read_bulk_callback, priv); + usb_set_serial_data(serial, priv); return 0; -- cgit v1.2.3 From e29a7738c531ba33a70cbf78809fb3dc5a0a42db Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:23 +0100 Subject: USB: opticon: use port device for error and debug Use port rather than interface device to report port related errors and debug information. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 8c66471f3bf..bcb8ad84a74 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -76,11 +76,11 @@ static void opticon_read_bulk_callback(struct urb *urb) case -ENOENT: case -ESHUTDOWN: /* this urb is terminated, clean up */ - dev_dbg(&priv->udev->dev, "%s - urb shutting down with status: %d\n", + dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n", __func__, status); return; default: - dev_dbg(&priv->udev->dev, "%s - nonzero urb status received: %d\n", + dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n", __func__, status); goto exit; } @@ -118,14 +118,14 @@ static void opticon_read_bulk_callback(struct urb *urb) priv->cts = true; spin_unlock_irqrestore(&priv->lock, flags); } else { - dev_dbg(&priv->udev->dev, + dev_dbg(&port->dev, "Unknown data packet received from the device:" " %2x %2x\n", data[0], data[1]); } } } else { - dev_dbg(&priv->udev->dev, + dev_dbg(&port->dev, "Improper amount of data received from the device, " "%d bytes", urb->actual_length); } @@ -219,7 +219,8 @@ static void opticon_write_control_callback(struct urb *urb) kfree(urb->setup_packet); if (status) - dev_dbg(&priv->udev->dev, "%s - nonzero write bulk status received: %d\n", + dev_dbg(&priv->port->dev, + "%s - non-zero urb status received: %d\n", __func__, status); spin_lock_irqsave(&priv->lock, flags); -- cgit v1.2.3 From 3157fad9ad6dbc97ee0ba2d6ada256370841c77a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:24 +0100 Subject: USB: opticon: remove private serial-device data Remove usb-serial-device field from private data as it can be accessed from the usb-serial-port structure. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index bcb8ad84a74..f81ffb01931 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -40,7 +40,6 @@ MODULE_DEVICE_TABLE(usb, id_table); /* This structure holds all of the individual device information */ struct opticon_private { - struct usb_device *udev; struct usb_serial *serial; struct usb_serial_port *port; unsigned char *bulk_in_buffer; @@ -185,7 +184,7 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) send_control_msg(port, CONTROL_RTS, 0); /* clear the halt status of the enpoint */ - usb_clear_halt(priv->udev, priv->bulk_read_urb->pipe); + usb_clear_halt(port->serial->dev, priv->bulk_read_urb->pipe); result = usb_submit_urb(priv->bulk_read_urb, GFP_KERNEL); if (result) @@ -487,7 +486,6 @@ static int opticon_startup(struct usb_serial *serial) spin_lock_init(&priv->lock); priv->serial = serial; priv->port = serial->port[0]; - priv->udev = serial->dev; priv->outstanding_urbs = 0; /* Init the outstanding urbs */ /* find our bulk endpoint */ @@ -501,14 +499,14 @@ static int opticon_startup(struct usb_serial *serial) priv->bulk_read_urb = usb_alloc_urb(0, GFP_KERNEL); if (!priv->bulk_read_urb) { - dev_err(&priv->udev->dev, "out of memory\n"); + dev_err(&serial->dev->dev, "out of memory\n"); goto error; } priv->buffer_size = usb_endpoint_maxp(endpoint) * 2; priv->bulk_in_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); if (!priv->bulk_in_buffer) { - dev_err(&priv->udev->dev, "out of memory\n"); + dev_err(&serial->dev->dev, "out of memory\n"); goto error; } @@ -519,7 +517,7 @@ static int opticon_startup(struct usb_serial *serial) } if (!bulk_in_found) { - dev_err(&priv->udev->dev, + dev_err(&serial->dev->dev, "Error - the proper endpoints were not found!\n"); goto error; } -- cgit v1.2.3 From b0f4765ae0f095bdc3d090937e72a198dee5cd39 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:25 +0100 Subject: USB: opticon: remove redundant initialisation Remove redundant zero-initialisation of outstanding-urbs field in kzalloced struct. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index f81ffb01931..2fc3dfc57f4 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -486,7 +486,6 @@ static int opticon_startup(struct usb_serial *serial) spin_lock_init(&priv->lock); priv->serial = serial; priv->port = serial->port[0]; - priv->outstanding_urbs = 0; /* Init the outstanding urbs */ /* find our bulk endpoint */ intf = serial->interface->altsetting; -- cgit v1.2.3 From 37203d6f1d0bef0c0943f3d853efdccb3246e7a6 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:26 +0100 Subject: USB: opticon: remove private usb-serial data Remove redundant usb-serial field from private data. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 2fc3dfc57f4..a515c5fda8a 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -40,7 +40,6 @@ MODULE_DEVICE_TABLE(usb, id_table); /* This structure holds all of the individual device information */ struct opticon_private { - struct usb_serial *serial; struct usb_serial_port *port; unsigned char *bulk_in_buffer; struct urb *bulk_read_urb; @@ -438,7 +437,7 @@ static int get_serial_info(struct opticon_private *priv, /* fake emulate a 16550 uart to make userspace code happy */ tmp.type = PORT_16550A; - tmp.line = priv->serial->minor; + tmp.line = priv->port->serial->minor; tmp.port = 0; tmp.irq = 0; tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; @@ -484,7 +483,6 @@ static int opticon_startup(struct usb_serial *serial) return -ENOMEM; } spin_lock_init(&priv->lock); - priv->serial = serial; priv->port = serial->port[0]; /* find our bulk endpoint */ -- cgit v1.2.3 From a0a5fd92a4d62506cb5c6fa64fb25653dda2cf09 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:27 +0100 Subject: USB: opticon: simplify bulk-in discovery in attach Remove custom end-point iteration which has already been taken care of by usb-serial core. The first bulk-in endpoint found will be associated with the first port. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 49 +++++++++++++++----------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index a515c5fda8a..e275abb9a1e 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -471,10 +471,12 @@ static int opticon_ioctl(struct tty_struct *tty, static int opticon_startup(struct usb_serial *serial) { struct opticon_private *priv; - struct usb_host_interface *intf; - int i; int retval = -ENOMEM; - bool bulk_in_found = false; + + if (!serial->num_bulk_in) { + dev_err(&serial->dev->dev, "no bulk in endpoint\n"); + return -ENODEV; + } /* create our private serial structure */ priv = kzalloc(sizeof(*priv), GFP_KERNEL); @@ -485,40 +487,21 @@ static int opticon_startup(struct usb_serial *serial) spin_lock_init(&priv->lock); priv->port = serial->port[0]; - /* find our bulk endpoint */ - intf = serial->interface->altsetting; - for (i = 0; i < intf->desc.bNumEndpoints; ++i) { - struct usb_endpoint_descriptor *endpoint; - - endpoint = &intf->endpoint[i].desc; - if (!usb_endpoint_is_bulk_in(endpoint)) - continue; - - priv->bulk_read_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->bulk_read_urb) { - dev_err(&serial->dev->dev, "out of memory\n"); - goto error; - } - - priv->buffer_size = usb_endpoint_maxp(endpoint) * 2; - priv->bulk_in_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); - if (!priv->bulk_in_buffer) { - dev_err(&serial->dev->dev, "out of memory\n"); - goto error; - } - - priv->bulk_address = endpoint->bEndpointAddress; - - bulk_in_found = true; - break; - } + priv->bulk_read_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!priv->bulk_read_urb) { + dev_err(&serial->dev->dev, "out of memory\n"); + goto error; + } - if (!bulk_in_found) { - dev_err(&serial->dev->dev, - "Error - the proper endpoints were not found!\n"); + priv->buffer_size = 2 * priv->port->bulk_in_size; + priv->bulk_in_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); + if (!priv->bulk_in_buffer) { + dev_err(&serial->dev->dev, "out of memory\n"); goto error; } + priv->bulk_address = priv->port->bulk_in_endpointAddress; + usb_fill_bulk_urb(priv->bulk_read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, priv->bulk_address), -- cgit v1.2.3 From 70f9bf65a4413cb3c7405b2078efb8b27acc7222 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:28 +0100 Subject: USB: opticon: move read-urb deallocation to release Move read-urb deallocation from disconnect to release. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index e275abb9a1e..77700b0720c 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -523,13 +523,13 @@ static void opticon_disconnect(struct usb_serial *serial) struct opticon_private *priv = usb_get_serial_data(serial); usb_kill_urb(priv->bulk_read_urb); - usb_free_urb(priv->bulk_read_urb); } static void opticon_release(struct usb_serial *serial) { struct opticon_private *priv = usb_get_serial_data(serial); + usb_free_urb(priv->bulk_read_urb); kfree(priv->bulk_in_buffer); kfree(priv); } -- cgit v1.2.3 From 2a2c511ca62c87ead992bff0e3cd43a32b28e6e0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:29 +0100 Subject: USB: opticon: remove disconnect Remove disconnect and its redundant read-urb kill which is already taken care of in close. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 77700b0720c..2fb71d8c3a9 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -518,13 +518,6 @@ error: return retval; } -static void opticon_disconnect(struct usb_serial *serial) -{ - struct opticon_private *priv = usb_get_serial_data(serial); - - usb_kill_urb(priv->bulk_read_urb); -} - static void opticon_release(struct usb_serial *serial) { struct opticon_private *priv = usb_get_serial_data(serial); @@ -570,7 +563,6 @@ static struct usb_serial_driver opticon_device = { .close = opticon_close, .write = opticon_write, .write_room = opticon_write_room, - .disconnect = opticon_disconnect, .release = opticon_release, .throttle = opticon_throttle, .unthrottle = opticon_unthrottle, -- cgit v1.2.3 From 70d25eeeba1b7e471fc4e05ad0d8c451aab3cf5e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:30 +0100 Subject: USB: opticon: make private data port specific Make private data port specific and move allocation and deallocation to port_probe and port_remove. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 69 ++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 2fb71d8c3a9..0178cc748c0 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -168,7 +168,7 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) { - struct opticon_private *priv = usb_get_serial_data(port->serial); + struct opticon_private *priv = usb_get_serial_port_data(port); unsigned long flags; int result = 0; @@ -198,7 +198,7 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) static void opticon_close(struct usb_serial_port *port) { - struct opticon_private *priv = usb_get_serial_data(port->serial); + struct opticon_private *priv = usb_get_serial_port_data(port); /* shutdown our urbs */ usb_kill_urb(priv->bulk_read_urb); @@ -231,7 +231,7 @@ static void opticon_write_control_callback(struct urb *urb) static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count) { - struct opticon_private *priv = usb_get_serial_data(port->serial); + struct opticon_private *priv = usb_get_serial_port_data(port); struct usb_serial *serial = port->serial; struct urb *urb; unsigned char *buffer; @@ -318,7 +318,7 @@ error_no_buffer: static int opticon_write_room(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_data(port->serial); + struct opticon_private *priv = usb_get_serial_port_data(port); unsigned long flags; /* @@ -340,7 +340,7 @@ static int opticon_write_room(struct tty_struct *tty) static void opticon_throttle(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_data(port->serial); + struct opticon_private *priv = usb_get_serial_port_data(port); unsigned long flags; spin_lock_irqsave(&priv->lock, flags); @@ -352,7 +352,7 @@ static void opticon_throttle(struct tty_struct *tty) static void opticon_unthrottle(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_data(port->serial); + struct opticon_private *priv = usb_get_serial_port_data(port); unsigned long flags; int result, was_throttled; @@ -374,7 +374,7 @@ static void opticon_unthrottle(struct tty_struct *tty) static int opticon_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_data(port->serial); + struct opticon_private *priv = usb_get_serial_port_data(port); unsigned long flags; int result = 0; @@ -394,7 +394,7 @@ static int opticon_tiocmset(struct tty_struct *tty, { struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = port->serial; - struct opticon_private *priv = usb_get_serial_data(port->serial); + struct opticon_private *priv = usb_get_serial_port_data(port); unsigned long flags; bool rts; bool changed = false; @@ -455,7 +455,7 @@ static int opticon_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_data(port->serial); + struct opticon_private *priv = usb_get_serial_port_data(port); dev_dbg(&port->dev, "%s - port %d, cmd = 0x%x\n", __func__, port->number, cmd); @@ -470,37 +470,37 @@ static int opticon_ioctl(struct tty_struct *tty, static int opticon_startup(struct usb_serial *serial) { - struct opticon_private *priv; - int retval = -ENOMEM; - if (!serial->num_bulk_in) { dev_err(&serial->dev->dev, "no bulk in endpoint\n"); return -ENODEV; } - /* create our private serial structure */ + return 0; +} + +static int opticon_port_probe(struct usb_serial_port *port) +{ + struct usb_serial *serial = port->serial; + struct opticon_private *priv; + int retval = -ENOMEM; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (priv == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); + if (!priv) return -ENOMEM; - } + spin_lock_init(&priv->lock); - priv->port = serial->port[0]; + priv->port = port; priv->bulk_read_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->bulk_read_urb) { - dev_err(&serial->dev->dev, "out of memory\n"); + if (!priv->bulk_read_urb) goto error; - } - priv->buffer_size = 2 * priv->port->bulk_in_size; + priv->buffer_size = 2 * port->bulk_in_size; priv->bulk_in_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); - if (!priv->bulk_in_buffer) { - dev_err(&serial->dev->dev, "out of memory\n"); + if (!priv->bulk_in_buffer) goto error; - } - priv->bulk_address = priv->port->bulk_in_endpointAddress; + priv->bulk_address = port->bulk_in_endpointAddress; usb_fill_bulk_urb(priv->bulk_read_urb, serial->dev, usb_rcvbulkpipe(serial->dev, @@ -508,9 +508,9 @@ static int opticon_startup(struct usb_serial *serial) priv->bulk_in_buffer, priv->buffer_size, opticon_read_bulk_callback, priv); - usb_set_serial_data(serial, priv); - return 0; + usb_set_serial_port_data(port, priv); + return 0; error: usb_free_urb(priv->bulk_read_urb); kfree(priv->bulk_in_buffer); @@ -518,18 +518,22 @@ error: return retval; } -static void opticon_release(struct usb_serial *serial) +static int opticon_port_remove(struct usb_serial_port *port) { - struct opticon_private *priv = usb_get_serial_data(serial); + struct opticon_private *priv = usb_get_serial_port_data(port); usb_free_urb(priv->bulk_read_urb); kfree(priv->bulk_in_buffer); kfree(priv); + + return 0; } static int opticon_suspend(struct usb_serial *serial, pm_message_t message) { - struct opticon_private *priv = usb_get_serial_data(serial); + struct opticon_private *priv; + + priv = usb_get_serial_port_data(serial->port[0]); usb_kill_urb(priv->bulk_read_urb); return 0; @@ -537,8 +541,8 @@ static int opticon_suspend(struct usb_serial *serial, pm_message_t message) static int opticon_resume(struct usb_serial *serial) { - struct opticon_private *priv = usb_get_serial_data(serial); struct usb_serial_port *port = serial->port[0]; + struct opticon_private *priv = usb_get_serial_port_data(port); int result; mutex_lock(&port->port.mutex); @@ -559,11 +563,12 @@ static struct usb_serial_driver opticon_device = { .id_table = id_table, .num_ports = 1, .attach = opticon_startup, + .port_probe = opticon_port_probe, + .port_remove = opticon_port_remove, .open = opticon_open, .close = opticon_close, .write = opticon_write, .write_room = opticon_write_room, - .release = opticon_release, .throttle = opticon_throttle, .unthrottle = opticon_unthrottle, .ioctl = opticon_ioctl, -- cgit v1.2.3 From 56be1a17d76d8517fe56e0e3da63d1d203b45d1e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:31 +0100 Subject: USB: opticon: pass port to get_serial_info Pass port rather then private data to get_serial_info, which only used the private data to access the port. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 0178cc748c0..92f56e476f2 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -425,7 +425,7 @@ static int opticon_tiocmset(struct tty_struct *tty, return ret; } -static int get_serial_info(struct opticon_private *priv, +static int get_serial_info(struct usb_serial_port *port, struct serial_struct __user *serial) { struct serial_struct tmp; @@ -437,7 +437,7 @@ static int get_serial_info(struct opticon_private *priv, /* fake emulate a 16550 uart to make userspace code happy */ tmp.type = PORT_16550A; - tmp.line = priv->port->serial->minor; + tmp.line = port->serial->minor; tmp.port = 0; tmp.irq = 0; tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; @@ -455,13 +455,12 @@ static int opticon_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_port_data(port); dev_dbg(&port->dev, "%s - port %d, cmd = 0x%x\n", __func__, port->number, cmd); switch (cmd) { case TIOCGSERIAL: - return get_serial_info(priv, + return get_serial_info(port, (struct serial_struct __user *)arg); } -- cgit v1.2.3 From e32d82bcdb78f502f58d0b078395ed3864aaa223 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:32 +0100 Subject: USB: opticon: use port as urb context Use port rather than private data as urb context, as the latter may be accessed as port data, and remove the port field from the private data. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 92f56e476f2..2c9137c9573 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -40,7 +40,6 @@ MODULE_DEVICE_TABLE(usb, id_table); /* This structure holds all of the individual device information */ struct opticon_private { - struct usb_serial_port *port; unsigned char *bulk_in_buffer; struct urb *bulk_read_urb; int buffer_size; @@ -57,9 +56,9 @@ struct opticon_private { static void opticon_read_bulk_callback(struct urb *urb) { - struct opticon_private *priv = urb->context; + struct usb_serial_port *port = urb->context; + struct opticon_private *priv = usb_get_serial_port_data(port); unsigned char *data = urb->transfer_buffer; - struct usb_serial_port *port = priv->port; int status = urb->status; struct tty_struct *tty; int result; @@ -175,7 +174,6 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) spin_lock_irqsave(&priv->lock, flags); priv->throttled = false; priv->actually_throttled = false; - priv->port = port; priv->rts = false; spin_unlock_irqrestore(&priv->lock, flags); @@ -206,7 +204,8 @@ static void opticon_close(struct usb_serial_port *port) static void opticon_write_control_callback(struct urb *urb) { - struct opticon_private *priv = urb->context; + struct usb_serial_port *port = urb->context; + struct opticon_private *priv = usb_get_serial_port_data(port); int status = urb->status; unsigned long flags; @@ -217,7 +216,7 @@ static void opticon_write_control_callback(struct urb *urb) kfree(urb->setup_packet); if (status) - dev_dbg(&priv->port->dev, + dev_dbg(&port->dev, "%s - non-zero urb status received: %d\n", __func__, status); @@ -225,7 +224,7 @@ static void opticon_write_control_callback(struct urb *urb) --priv->outstanding_urbs; spin_unlock_irqrestore(&priv->lock, flags); - usb_serial_port_softint(priv->port); + usb_serial_port_softint(port); } static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, @@ -285,7 +284,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, usb_fill_control_urb(urb, serial->dev, usb_sndctrlpipe(serial->dev, 0), (unsigned char *)dr, buffer, count, - opticon_write_control_callback, priv); + opticon_write_control_callback, port); /* send it down the pipe */ status = usb_submit_urb(urb, GFP_ATOMIC); @@ -488,7 +487,6 @@ static int opticon_port_probe(struct usb_serial_port *port) return -ENOMEM; spin_lock_init(&priv->lock); - priv->port = port; priv->bulk_read_urb = usb_alloc_urb(0, GFP_KERNEL); if (!priv->bulk_read_urb) @@ -505,7 +503,7 @@ static int opticon_port_probe(struct usb_serial_port *port) usb_rcvbulkpipe(serial->dev, priv->bulk_address), priv->bulk_in_buffer, priv->buffer_size, - opticon_read_bulk_callback, priv); + opticon_read_bulk_callback, port); usb_set_serial_port_data(port, priv); -- cgit v1.2.3 From 333396fc703860e19eadcdc67def9caa4f3154f4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:33 +0100 Subject: USB: opticon: increase bulk-in size Use 256 byte bulk-in buffers rather than double end-point sized ones. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 2c9137c9573..543d8c79b02 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -492,7 +492,7 @@ static int opticon_port_probe(struct usb_serial_port *port) if (!priv->bulk_read_urb) goto error; - priv->buffer_size = 2 * port->bulk_in_size; + priv->buffer_size = port->bulk_in_size; priv->bulk_in_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); if (!priv->bulk_in_buffer) goto error; @@ -559,6 +559,7 @@ static struct usb_serial_driver opticon_device = { }, .id_table = id_table, .num_ports = 1, + .bulk_in_size = 256, .attach = opticon_startup, .port_probe = opticon_port_probe, .port_remove = opticon_port_remove, -- cgit v1.2.3 From 5ad473492ada0ab05bcf15791b7a41c587d831c7 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:34 +0100 Subject: USB: opticon: use usb-serial bulk-in urb Use the bulk-in urb provided by usb-serial core rather than allocating a private one. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 543d8c79b02..36fdab7b016 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -40,10 +40,7 @@ MODULE_DEVICE_TABLE(usb, id_table); /* This structure holds all of the individual device information */ struct opticon_private { - unsigned char *bulk_in_buffer; struct urb *bulk_read_urb; - int buffer_size; - u8 bulk_address; spinlock_t lock; /* protects the following flags */ bool throttled; bool actually_throttled; @@ -478,49 +475,24 @@ static int opticon_startup(struct usb_serial *serial) static int opticon_port_probe(struct usb_serial_port *port) { - struct usb_serial *serial = port->serial; struct opticon_private *priv; - int retval = -ENOMEM; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; spin_lock_init(&priv->lock); - - priv->bulk_read_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!priv->bulk_read_urb) - goto error; - - priv->buffer_size = port->bulk_in_size; - priv->bulk_in_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); - if (!priv->bulk_in_buffer) - goto error; - - priv->bulk_address = port->bulk_in_endpointAddress; - - usb_fill_bulk_urb(priv->bulk_read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, - priv->bulk_address), - priv->bulk_in_buffer, priv->buffer_size, - opticon_read_bulk_callback, port); + priv->bulk_read_urb = port->read_urbs[0]; usb_set_serial_port_data(port, priv); return 0; -error: - usb_free_urb(priv->bulk_read_urb); - kfree(priv->bulk_in_buffer); - kfree(priv); - return retval; } static int opticon_port_remove(struct usb_serial_port *port) { struct opticon_private *priv = usb_get_serial_port_data(port); - usb_free_urb(priv->bulk_read_urb); - kfree(priv->bulk_in_buffer); kfree(priv); return 0; @@ -574,6 +546,7 @@ static struct usb_serial_driver opticon_device = { .tiocmset = opticon_tiocmset, .suspend = opticon_suspend, .resume = opticon_resume, + .read_bulk_callback = opticon_read_bulk_callback, }; static struct usb_serial_driver * const serial_drivers[] = { -- cgit v1.2.3 From 32802077ce90ba955a9c50c6b27e6e6015a907bf Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:35 +0100 Subject: USB: opticon: refactor reab-urb processing Refactor and clean up read-urb processing. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 105 ++++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 46 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 36fdab7b016..8d6ece048f0 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -50,6 +50,64 @@ struct opticon_private { }; +static void opticon_process_data_packet(struct usb_serial_port *port, + const unsigned char *buf, size_t len) +{ + struct tty_struct *tty; + + tty = tty_port_tty_get(&port->port); + if (!tty) + return; + + tty_insert_flip_string(tty, buf, len); + tty_flip_buffer_push(tty); + tty_kref_put(tty); +} + +static void opticon_process_status_packet(struct usb_serial_port *port, + const unsigned char *buf, size_t len) +{ + struct opticon_private *priv = usb_get_serial_port_data(port); + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (buf[0] == 0x00) + priv->cts = false; + else + priv->cts = true; + spin_unlock_irqrestore(&priv->lock, flags); +} + +static void opticon_process_read_urb(struct urb *urb) +{ + struct usb_serial_port *port = urb->context; + const unsigned char *hdr = urb->transfer_buffer; + const unsigned char *data = hdr + 2; + size_t data_len = urb->actual_length - 2; + + if (urb->actual_length <= 2) { + dev_dbg(&port->dev, "malformed packet received: %d bytes\n", + urb->actual_length); + return; + } + /* + * Data from the device comes with a 2 byte header: + * + * <0x00><0x00>data... + * This is real data to be sent to the tty layer + * <0x00><0x01>level + * This is a CTS level change, the third byte is the CTS + * value (0 for low, 1 for high). + */ + if ((hdr[0] == 0x00) && (hdr[1] == 0x00)) { + opticon_process_data_packet(port, data, data_len); + } else if ((hdr[0] == 0x00) && (hdr[1] == 0x01)) { + opticon_process_status_packet(port, data, data_len); + } else { + dev_dbg(&port->dev, "unknown packet received: %02x %02x\n", + hdr[0], hdr[1]); + } +} static void opticon_read_bulk_callback(struct urb *urb) { @@ -57,10 +115,7 @@ static void opticon_read_bulk_callback(struct urb *urb) struct opticon_private *priv = usb_get_serial_port_data(port); unsigned char *data = urb->transfer_buffer; int status = urb->status; - struct tty_struct *tty; int result; - int data_length; - unsigned long flags; switch (status) { case 0: @@ -81,49 +136,7 @@ static void opticon_read_bulk_callback(struct urb *urb) usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); - if (urb->actual_length > 2) { - data_length = urb->actual_length - 2; - - /* - * Data from the device comes with a 2 byte header: - * - * <0x00><0x00>data... - * This is real data to be sent to the tty layer - * <0x00><0x01)level - * This is a CTS level change, the third byte is the CTS - * value (0 for low, 1 for high). - */ - if ((data[0] == 0x00) && (data[1] == 0x00)) { - /* real data, send it to the tty layer */ - tty = tty_port_tty_get(&port->port); - if (tty) { - tty_insert_flip_string(tty, data + 2, - data_length); - tty_flip_buffer_push(tty); - tty_kref_put(tty); - } - } else { - if ((data[0] == 0x00) && (data[1] == 0x01)) { - spin_lock_irqsave(&priv->lock, flags); - /* CTS status information package */ - if (data[2] == 0x00) - priv->cts = false; - else - priv->cts = true; - spin_unlock_irqrestore(&priv->lock, flags); - } else { - dev_dbg(&port->dev, - "Unknown data packet received from the device:" - " %2x %2x\n", - data[0], data[1]); - } - } - } else { - dev_dbg(&port->dev, - "Improper amount of data received from the device, " - "%d bytes", urb->actual_length); - } - + opticon_process_read_urb(urb); exit: spin_lock(&priv->lock); -- cgit v1.2.3 From 7a6ee2b02751a58b7a59a37483379ba9cddacc92 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Sun, 18 Nov 2012 13:23:36 +0100 Subject: USB: opticon: switch to generic read implementation Switch to the more efficient generic read implementation. Note that the generic implementation is not required to hold the tty port mutex during resume due to the read-urb free mask and write start flag. Note also that the generic resume implementation will call generic write start if there is a bulk-out end-point, but that nothing will be submitted as the write fifo is not used and is empty. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/opticon.c | 141 ++++--------------------------------------- 1 file changed, 11 insertions(+), 130 deletions(-) diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 8d6ece048f0..c6bfb83efb1 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -1,6 +1,7 @@ /* * Opticon USB barcode to serial driver * + * Copyright (C) 2011 - 2012 Johan Hovold * Copyright (C) 2011 Martin Jansen * Copyright (C) 2008 - 2009 Greg Kroah-Hartman * Copyright (C) 2008 - 2009 Novell Inc. @@ -40,10 +41,7 @@ MODULE_DEVICE_TABLE(usb, id_table); /* This structure holds all of the individual device information */ struct opticon_private { - struct urb *bulk_read_urb; spinlock_t lock; /* protects the following flags */ - bool throttled; - bool actually_throttled; bool rts; bool cts; int outstanding_urbs; @@ -109,49 +107,6 @@ static void opticon_process_read_urb(struct urb *urb) } } -static void opticon_read_bulk_callback(struct urb *urb) -{ - struct usb_serial_port *port = urb->context; - struct opticon_private *priv = usb_get_serial_port_data(port); - unsigned char *data = urb->transfer_buffer; - int status = urb->status; - int result; - - switch (status) { - case 0: - /* success */ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - /* this urb is terminated, clean up */ - dev_dbg(&port->dev, "%s - urb shutting down with status: %d\n", - __func__, status); - return; - default: - dev_dbg(&port->dev, "%s - nonzero urb status received: %d\n", - __func__, status); - goto exit; - } - - usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); - - opticon_process_read_urb(urb); -exit: - spin_lock(&priv->lock); - - /* Continue trying to always read if we should */ - if (!priv->throttled) { - result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); - if (result) - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", - __func__, result); - } else - priv->actually_throttled = true; - spin_unlock(&priv->lock); -} - static int send_control_msg(struct usb_serial_port *port, u8 requesttype, u8 val) { @@ -179,11 +134,9 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) { struct opticon_private *priv = usb_get_serial_port_data(port); unsigned long flags; - int result = 0; + int res; spin_lock_irqsave(&priv->lock, flags); - priv->throttled = false; - priv->actually_throttled = false; priv->rts = false; spin_unlock_irqrestore(&priv->lock, flags); @@ -191,25 +144,17 @@ static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port) send_control_msg(port, CONTROL_RTS, 0); /* clear the halt status of the enpoint */ - usb_clear_halt(port->serial->dev, priv->bulk_read_urb->pipe); + usb_clear_halt(port->serial->dev, port->read_urb->pipe); + + res = usb_serial_generic_open(tty, port); + if (!res) + return res; - result = usb_submit_urb(priv->bulk_read_urb, GFP_KERNEL); - if (result) - dev_err(&port->dev, - "%s - failed resubmitting read urb, error %d\n", - __func__, result); /* Request CTS line state, sometimes during opening the current * CTS state can be missed. */ send_control_msg(port, RESEND_CTS_STATE, 1); - return result; -} -static void opticon_close(struct usb_serial_port *port) -{ - struct opticon_private *priv = usb_get_serial_port_data(port); - - /* shutdown our urbs */ - usb_kill_urb(priv->bulk_read_urb); + return res; } static void opticon_write_control_callback(struct urb *urb) @@ -346,40 +291,6 @@ static int opticon_write_room(struct tty_struct *tty) return 2048; } -static void opticon_throttle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - - spin_lock_irqsave(&priv->lock, flags); - priv->throttled = true; - spin_unlock_irqrestore(&priv->lock, flags); -} - - -static void opticon_unthrottle(struct tty_struct *tty) -{ - struct usb_serial_port *port = tty->driver_data; - struct opticon_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - int result, was_throttled; - - spin_lock_irqsave(&priv->lock, flags); - priv->throttled = false; - was_throttled = priv->actually_throttled; - priv->actually_throttled = false; - spin_unlock_irqrestore(&priv->lock, flags); - - if (was_throttled) { - result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); - if (result) - dev_err(&port->dev, - "%s - failed submitting read urb, error %d\n", - __func__, result); - } -} - static int opticon_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; @@ -495,7 +406,6 @@ static int opticon_port_probe(struct usb_serial_port *port) return -ENOMEM; spin_lock_init(&priv->lock); - priv->bulk_read_urb = port->read_urbs[0]; usb_set_serial_port_data(port, priv); @@ -511,32 +421,6 @@ static int opticon_port_remove(struct usb_serial_port *port) return 0; } -static int opticon_suspend(struct usb_serial *serial, pm_message_t message) -{ - struct opticon_private *priv; - - priv = usb_get_serial_port_data(serial->port[0]); - - usb_kill_urb(priv->bulk_read_urb); - return 0; -} - -static int opticon_resume(struct usb_serial *serial) -{ - struct usb_serial_port *port = serial->port[0]; - struct opticon_private *priv = usb_get_serial_port_data(port); - int result; - - mutex_lock(&port->port.mutex); - /* This is protected by the port mutex against close/open */ - if (test_bit(ASYNCB_INITIALIZED, &port->port.flags)) - result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO); - else - result = 0; - mutex_unlock(&port->port.mutex); - return result; -} - static struct usb_serial_driver opticon_device = { .driver = { .owner = THIS_MODULE, @@ -549,17 +433,14 @@ static struct usb_serial_driver opticon_device = { .port_probe = opticon_port_probe, .port_remove = opticon_port_remove, .open = opticon_open, - .close = opticon_close, .write = opticon_write, .write_room = opticon_write_room, - .throttle = opticon_throttle, - .unthrottle = opticon_unthrottle, + .throttle = usb_serial_generic_throttle, + .unthrottle = usb_serial_generic_unthrottle, .ioctl = opticon_ioctl, .tiocmget = opticon_tiocmget, .tiocmset = opticon_tiocmset, - .suspend = opticon_suspend, - .resume = opticon_resume, - .read_bulk_callback = opticon_read_bulk_callback, + .process_read_urb = opticon_process_read_urb, }; static struct usb_serial_driver * const serial_drivers[] = { -- cgit v1.2.3 From 31b6a1048b7292efff8b5b53ae3d9d29adde385e Mon Sep 17 00:00:00 2001 From: "li.rui27@zte.com.cn" Date: Tue, 20 Nov 2012 14:31:47 +0800 Subject: USB: add new zte 3g-dongle's pid to option.c Cc: stable Signed-off-by: Rui li Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index ed660564f0c..15365f97e37 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -883,6 +883,10 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0135, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0136, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0137, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0139, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) }, @@ -903,20 +907,34 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0189, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0196, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0197, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0199, 0xff, 0xff, 0xff), /* ZTE MF820S */ .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0200, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0201, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0254, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */ .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0265, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0284, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0317, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0330, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0395, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1021, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, @@ -1096,6 +1114,10 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1301, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1302, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1303, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1333, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), -- cgit v1.2.3 From 5a59509b4753c281d3003eb996c8137bef62e5a9 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:21:07 -0500 Subject: uio: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Cc: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_pruss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c index 33a7a273b45..d877d643433 100644 --- a/drivers/uio/uio_pruss.c +++ b/drivers/uio/uio_pruss.c @@ -220,7 +220,7 @@ static int __devexit pruss_remove(struct platform_device *dev) static struct platform_driver pruss_driver = { .probe = pruss_probe, - .remove = __devexit_p(pruss_remove), + .remove = pruss_remove, .driver = { .name = DRV_NAME, .owner = THIS_MODULE, -- cgit v1.2.3 From b17b75bb524c6c0dfa5ee4a33591b8a7dcc034d2 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:21:49 -0500 Subject: uio: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Cc: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_aec.c | 2 +- drivers/uio/uio_cif.c | 2 +- drivers/uio/uio_netx.c | 2 +- drivers/uio/uio_pci_generic.c | 2 +- drivers/uio/uio_pruss.c | 2 +- drivers/uio/uio_sercos3.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/uio/uio_aec.c b/drivers/uio/uio_aec.c index 72b22d44e8b..1548982db58 100644 --- a/drivers/uio/uio_aec.c +++ b/drivers/uio/uio_aec.c @@ -78,7 +78,7 @@ static void print_board_data(struct pci_dev *pdev, struct uio_info *i) ioread8(i->priv + 0x07)); } -static int __devinit probe(struct pci_dev *pdev, const struct pci_device_id *id) +static int probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct uio_info *info; int ret; diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c index a84a451159e..674783f785e 100644 --- a/drivers/uio/uio_cif.c +++ b/drivers/uio/uio_cif.c @@ -40,7 +40,7 @@ static irqreturn_t hilscher_handler(int irq, struct uio_info *dev_info) return IRQ_HANDLED; } -static int __devinit hilscher_pci_probe(struct pci_dev *dev, +static int hilscher_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct uio_info *info; diff --git a/drivers/uio/uio_netx.c b/drivers/uio/uio_netx.c index a879fd5741f..6a4ba5e83e3 100644 --- a/drivers/uio/uio_netx.c +++ b/drivers/uio/uio_netx.c @@ -48,7 +48,7 @@ static irqreturn_t netx_handler(int irq, struct uio_info *dev_info) return IRQ_HANDLED; } -static int __devinit netx_pci_probe(struct pci_dev *dev, +static int netx_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct uio_info *info; diff --git a/drivers/uio/uio_pci_generic.c b/drivers/uio/uio_pci_generic.c index 0bd08ef2b39..14aa10c1f6d 100644 --- a/drivers/uio/uio_pci_generic.c +++ b/drivers/uio/uio_pci_generic.c @@ -53,7 +53,7 @@ static irqreturn_t irqhandler(int irq, struct uio_info *info) return IRQ_HANDLED; } -static int __devinit probe(struct pci_dev *pdev, +static int probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct uio_pci_generic_dev *gdev; diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c index d877d643433..098d3d00817 100644 --- a/drivers/uio/uio_pruss.c +++ b/drivers/uio/uio_pruss.c @@ -112,7 +112,7 @@ static void pruss_cleanup(struct platform_device *dev, kfree(gdev); } -static int __devinit pruss_probe(struct platform_device *dev) +static int pruss_probe(struct platform_device *dev) { struct uio_info *p; struct uio_pruss_dev *gdev; diff --git a/drivers/uio/uio_sercos3.c b/drivers/uio/uio_sercos3.c index a187fa14c5c..2e87808711c 100644 --- a/drivers/uio/uio_sercos3.c +++ b/drivers/uio/uio_sercos3.c @@ -116,7 +116,7 @@ static int sercos3_setup_iomem(struct pci_dev *dev, struct uio_info *info, return 0; } -static int __devinit sercos3_pci_probe(struct pci_dev *dev, +static int sercos3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct uio_info *info; -- cgit v1.2.3 From d46f743822ee6e890a6e7971e089a020e6c0000a Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:24:33 -0500 Subject: uio: remove use of __devinitdata CONFIG_HOTPLUG is going away as an option so __devinitdata is no longer needed. Signed-off-by: Bill Pemberton Cc: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_cif.c | 2 +- drivers/uio/uio_sercos3.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/uio/uio_cif.c b/drivers/uio/uio_cif.c index 674783f785e..7dd6fc60539 100644 --- a/drivers/uio/uio_cif.c +++ b/drivers/uio/uio_cif.c @@ -112,7 +112,7 @@ static void hilscher_pci_remove(struct pci_dev *dev) kfree (info); } -static struct pci_device_id hilscher_pci_ids[] __devinitdata = { +static struct pci_device_id hilscher_pci_ids[] = { { .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_9030, diff --git a/drivers/uio/uio_sercos3.c b/drivers/uio/uio_sercos3.c index 2e87808711c..81a10a56312 100644 --- a/drivers/uio/uio_sercos3.c +++ b/drivers/uio/uio_sercos3.c @@ -197,7 +197,7 @@ static void sercos3_pci_remove(struct pci_dev *dev) kfree(info); } -static struct pci_device_id sercos3_pci_ids[] __devinitdata = { +static struct pci_device_id sercos3_pci_ids[] = { { .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_9030, -- cgit v1.2.3 From 9b96c3124b66a959ba061dbca339944a81686cd2 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:26:19 -0500 Subject: uio: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Cc: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_pruss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c index 098d3d00817..cce0f78341c 100644 --- a/drivers/uio/uio_pruss.c +++ b/drivers/uio/uio_pruss.c @@ -209,7 +209,7 @@ out_free: return ret; } -static int __devexit pruss_remove(struct platform_device *dev) +static int pruss_remove(struct platform_device *dev) { struct uio_pruss_dev *gdev = platform_get_drvdata(dev); -- cgit v1.2.3 From 24fce61b0b7f1bc94970036db1f1d65b0770d168 Mon Sep 17 00:00:00 2001 From: Damian Hobson-Garcia Date: Fri, 16 Nov 2012 14:46:09 +0900 Subject: drivers: uio_dmem_genirq: Don't mix address spaces for dynamic region vaddr Assigning the virtual address returned from dma_alloc_coherent to the the internal_addr element of uioinfo produces the following sparse errors since internal_addr is a void __iomem * and dma_alloc_coherent returns void *. + drivers/uio/uio_dmem_genirq.c:65:39: sparse: incorrect type in assignment (different address spaces) drivers/uio/uio_dmem_genirq.c:65:39: expected void [noderef] *internal_addr drivers/uio/uio_dmem_genirq.c:65:39: got void *[assigned] addr + drivers/uio/uio_dmem_genirq.c:93:17: sparse: incorrect type in argument 3 (different address spaces) drivers/uio/uio_dmem_genirq.c:93:17: expected void *vaddr drivers/uio/uio_dmem_genirq.c:93:17: got void [noderef] *internal_addr Store the void * in the driver's private data instead. Reported-by: Fengguang Wu Signed-off-by: Damian Hobson-Garcia Cc: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_dmem_genirq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c index 4d4dd008c8b..d8bbe0783cd 100644 --- a/drivers/uio/uio_dmem_genirq.c +++ b/drivers/uio/uio_dmem_genirq.c @@ -37,6 +37,7 @@ struct uio_dmem_genirq_platdata { struct platform_device *pdev; unsigned int dmem_region_start; unsigned int num_dmem_regions; + void *dmem_region_vaddr[MAX_UIO_MAPS]; struct mutex alloc_lock; unsigned int refcnt; }; @@ -46,6 +47,7 @@ static int uio_dmem_genirq_open(struct uio_info *info, struct inode *inode) struct uio_dmem_genirq_platdata *priv = info->priv; struct uio_mem *uiomem; int ret = 0; + int dmem_region = priv->dmem_region_start; uiomem = &priv->uioinfo->mem[priv->dmem_region_start]; @@ -61,8 +63,7 @@ static int uio_dmem_genirq_open(struct uio_info *info, struct inode *inode) ret = -ENOMEM; break; } - - uiomem->internal_addr = addr; + priv->dmem_region_vaddr[dmem_region++] = addr; ++uiomem; } priv->refcnt++; @@ -77,6 +78,7 @@ static int uio_dmem_genirq_release(struct uio_info *info, struct inode *inode) { struct uio_dmem_genirq_platdata *priv = info->priv; struct uio_mem *uiomem; + int dmem_region = priv->dmem_region_start; /* Tell the Runtime PM code that the device has become idle */ pm_runtime_put_sync(&priv->pdev->dev); @@ -91,7 +93,8 @@ static int uio_dmem_genirq_release(struct uio_info *info, struct inode *inode) break; dma_free_coherent(&priv->pdev->dev, uiomem->size, - uiomem->internal_addr, uiomem->addr); + priv->dmem_region_vaddr[dmem_region++], + uiomem->addr); uiomem->addr = DMA_ERROR_CODE; ++uiomem; } -- cgit v1.2.3 From 87c4d1a7dce956b86e34329ed1b11a751ba9a8ea Mon Sep 17 00:00:00 2001 From: Damian Hobson-Garcia Date: Fri, 16 Nov 2012 14:46:10 +0900 Subject: drivers: uio_dmem_genirq: Don't use DMA_ERROR_CODE to indicate unmapped regions DMA_ERROR_CODE is not defined on all architectures and is architecture specific. Instead, use the constant, ~0 to indicate unmapped regions. Reported-by: Fengguang Wu Reported-by: Geert Uytterhoeven Signed-off-by: Damian Hobson-Garcia Cc: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman --- Documentation/DocBook/uio-howto.tmpl | 2 +- drivers/uio/uio_dmem_genirq.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl index fdbf86fcfcc..ddb05e98af0 100644 --- a/Documentation/DocBook/uio-howto.tmpl +++ b/Documentation/DocBook/uio-howto.tmpl @@ -771,7 +771,7 @@ framework to set up sysfs files for this region. Simply leave it alone. /sys/class/uio/uioX/maps/mapY/*. The dynmaic memory regions will be freed when the UIO device file is closed. When no processes are holding the device file open, the address - returned to userspace is DMA_ERROR_CODE. + returned to userspace is ~0. diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c index d8bbe0783cd..7be8d0421ca 100644 --- a/drivers/uio/uio_dmem_genirq.c +++ b/drivers/uio/uio_dmem_genirq.c @@ -29,6 +29,7 @@ #include #define DRIVER_NAME "uio_dmem_genirq" +#define DMEM_MAP_ERROR (~0) struct uio_dmem_genirq_platdata { struct uio_info *uioinfo; @@ -60,6 +61,7 @@ static int uio_dmem_genirq_open(struct uio_info *info, struct inode *inode) addr = dma_alloc_coherent(&priv->pdev->dev, uiomem->size, (dma_addr_t *)&uiomem->addr, GFP_KERNEL); if (!addr) { + uiomem->addr = DMEM_MAP_ERROR; ret = -ENOMEM; break; } @@ -95,7 +97,7 @@ static int uio_dmem_genirq_release(struct uio_info *info, struct inode *inode) dma_free_coherent(&priv->pdev->dev, uiomem->size, priv->dmem_region_vaddr[dmem_region++], uiomem->addr); - uiomem->addr = DMA_ERROR_CODE; + uiomem->addr = DMEM_MAP_ERROR; ++uiomem; } @@ -238,7 +240,7 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev) break; } uiomem->memtype = UIO_MEM_PHYS; - uiomem->addr = DMA_ERROR_CODE; + uiomem->addr = DMEM_MAP_ERROR; uiomem->size = pdata->dynamic_region_sizes[i]; ++uiomem; } -- cgit v1.2.3 From 439926c81c01f31f9ffa7af7bf2d242b7f794f3c Mon Sep 17 00:00:00 2001 From: Damian Hobson-Garcia Date: Fri, 16 Nov 2012 14:46:11 +0900 Subject: drivers: uio_dmem_genirq: Allow partial success when opening device The uio device should not fail on open just because one memory allocation fails. The device might export several regions, the failure of some of which may or may not be a problem for the user space driver. Failing regions will remain unmapped, and successful regions will be mapped and exported to user space. Also deals with the case where failing to map a region after successfully allocating others would not unmap the successfully allocated regions before dying. Signed-off-by: Damian Hobson-Garcia Cc: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_dmem_genirq.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c index 7be8d0421ca..bbdf92559e3 100644 --- a/drivers/uio/uio_dmem_genirq.c +++ b/drivers/uio/uio_dmem_genirq.c @@ -62,8 +62,6 @@ static int uio_dmem_genirq_open(struct uio_info *info, struct inode *inode) (dma_addr_t *)&uiomem->addr, GFP_KERNEL); if (!addr) { uiomem->addr = DMEM_MAP_ERROR; - ret = -ENOMEM; - break; } priv->dmem_region_vaddr[dmem_region++] = addr; ++uiomem; @@ -93,11 +91,13 @@ static int uio_dmem_genirq_release(struct uio_info *info, struct inode *inode) while (!priv->refcnt && uiomem < &priv->uioinfo->mem[MAX_UIO_MAPS]) { if (!uiomem->size) break; - - dma_free_coherent(&priv->pdev->dev, uiomem->size, - priv->dmem_region_vaddr[dmem_region++], - uiomem->addr); + if (priv->dmem_region_vaddr[dmem_region]) { + dma_free_coherent(&priv->pdev->dev, uiomem->size, + priv->dmem_region_vaddr[dmem_region], + uiomem->addr); + } uiomem->addr = DMEM_MAP_ERROR; + ++dmem_region; ++uiomem; } -- cgit v1.2.3 From d5185c4eb3a022f7e7a435238c2b0b885e6b4821 Mon Sep 17 00:00:00 2001 From: Damian Hobson-Garcia Date: Fri, 16 Nov 2012 14:46:12 +0900 Subject: drivers: uio: Only allocate new private data when probing device tree node The same condition should be used both when allocating and freeing the driver private data. When dev.of_node is non NULL, allocate a new private data structure, otherwise use the values from the platform data. Reported-by: Fengguang Wu Signed-off-by: Damian Hobson-Garcia Cc: "Hans J. Koch" Signed-off-by: Greg Kroah-Hartman --- drivers/uio/uio_dmem_genirq.c | 2 +- drivers/uio/uio_pdrv_genirq.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c index bbdf92559e3..252434c9ea9 100644 --- a/drivers/uio/uio_dmem_genirq.c +++ b/drivers/uio/uio_dmem_genirq.c @@ -153,7 +153,7 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev) int ret = -EINVAL; int i; - if (!uioinfo) { + if (pdev->dev.of_node) { int irq; /* alloc uioinfo for one device */ diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c index ac988ce62f2..c122bca669b 100644 --- a/drivers/uio/uio_pdrv_genirq.c +++ b/drivers/uio/uio_pdrv_genirq.c @@ -102,7 +102,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev) int ret = -EINVAL; int i; - if (!uioinfo) { + if (pdev->dev.of_node) { int irq; /* alloc uioinfo for one device */ -- cgit v1.2.3 From 43f971ebca027fa62b306b8651de31a6bf41a2f7 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 20 Nov 2012 14:26:58 +0530 Subject: staging: ozwpan: Include oz_events_clear() conditionally oz_events_clear() is referenced only when CONFIG_DEBUG_FS is defined. Move the definition too under this flag. Signed-off-by: Sachin Kamat Acked-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozevent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ozwpan/ozevent.c b/drivers/staging/ozwpan/ozevent.c index a48498bd9b5..50578ba0061 100644 --- a/drivers/staging/ozwpan/ozevent.c +++ b/drivers/staging/ozwpan/ozevent.c @@ -79,6 +79,7 @@ void oz_event_log2(u8 evt, u8 ctx1, u16 ctx2, void *ctx3, unsigned ctx4) /*------------------------------------------------------------------------------ * Context: process */ +#ifdef CONFIG_DEBUG_FS static void oz_events_clear(struct oz_evtdev *dev) { unsigned long irqstate; @@ -88,7 +89,6 @@ static void oz_events_clear(struct oz_evtdev *dev) dev->missed_events = 0; spin_unlock_irqrestore(&dev->lock, irqstate); } -#ifdef CONFIG_DEBUG_FS /*------------------------------------------------------------------------------ * Context: process */ -- cgit v1.2.3 From b150718ecb6468d2de1ff593c402ec257dd80c8c Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 20 Nov 2012 17:10:08 +0530 Subject: staging: ozwpan: Remove redundant null check before kfree in ozpd.c kfree on NULL pointer is a no-op. Signed-off-by: Sachin Kamat Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozpd.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 0b3648ce968..118a4db74de 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -402,8 +402,7 @@ static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f) f = 0; } spin_unlock_bh(&pd->tx_frame_lock); - if (f) - kfree(f); + kfree(f); } /*------------------------------------------------------------------------------ * Context: softirq-serialized @@ -737,8 +736,7 @@ int oz_isoc_stream_create(struct oz_pd *pd, u8 ep_num) st = 0; } spin_unlock_bh(&pd->stream_lock); - if (st) - kfree(st); + kfree(st); return 0; } /*------------------------------------------------------------------------------ -- cgit v1.2.3 From ba34efba7ab0eed43aca254738c0446af644fb15 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 20 Nov 2012 17:10:09 +0530 Subject: staging: ozwpan: Remove redundant null check before kfree in ozproto.c kfree on NULL pointer is a no-op. Signed-off-by: Sachin Kamat Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozproto.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index cfb5160d1eb..e00a53915da 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -566,8 +566,7 @@ static void oz_protocol_timer(unsigned long arg) } spin_unlock_bh(&g_polling_lock); oz_pd_put(pd); - if (t) - kfree(t); + kfree(t); t = t2; } while (t); g_timer_state = OZ_TIMER_IDLE; -- cgit v1.2.3 From 7010157b088b4748aff592321bee6ac8388e300f Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 20 Nov 2012 17:10:10 +0530 Subject: staging: ozwpan: Remove redundant null check before kfree in ozhcd.c kfree on NULL pointer is a no-op. Signed-off-by: Sachin Kamat Signed-off-by: Rupesh Gujare Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozhcd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 33c0009b308..b2d77df2a52 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -278,8 +278,7 @@ static void oz_free_urb_link(struct oz_urb_link *urbl) g_link_pool_size++; } spin_unlock_irqrestore(&g_link_lock, irq_state); - if (urbl) - kfree(urbl); + kfree(urbl); } } /*------------------------------------------------------------------------------ -- cgit v1.2.3 From 01fd5732deb0e60528bae16d0e30ef0fb943e9c9 Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Tue, 20 Nov 2012 16:44:10 +0200 Subject: staging: wlags49_h2: wl_if.h: fixes macro styling issues This commit sorts out macro styling issues that were indicated by the checkpatch.pl script, Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_if.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wlags49_h2/wl_if.h b/drivers/staging/wlags49_h2/wl_if.h index 6d66dabf032..d070e47fdac 100644 --- a/drivers/staging/wlags49_h2/wl_if.h +++ b/drivers/staging/wlags49_h2/wl_if.h @@ -121,7 +121,7 @@ #define MAX_RTS_BYTES 2347 #define MAX_RATES 8 -#define MEGABIT 1024*1024 +#define MEGABIT (1024 * 1024) #define HCF_FAILURE 0xFF #define UIL_FAILURE 0xFF @@ -154,15 +154,15 @@ UIL_FUN_GET_INFO UIL_FUN_PUT_INFO */ -#define SIOCSIWNETNAME SIOCDEVPRIVATE+1 -#define SIOCGIWNETNAME SIOCDEVPRIVATE+2 -#define SIOCSIWSTANAME SIOCDEVPRIVATE+3 -#define SIOCGIWSTANAME SIOCDEVPRIVATE+4 -#define SIOCSIWPORTTYPE SIOCDEVPRIVATE+5 -#define SIOCGIWPORTTYPE SIOCDEVPRIVATE+6 +#define SIOCSIWNETNAME (SIOCDEVPRIVATE + 1) +#define SIOCGIWNETNAME (SIOCDEVPRIVATE + 2) +#define SIOCSIWSTANAME (SIOCDEVPRIVATE + 3) +#define SIOCGIWSTANAME (SIOCDEVPRIVATE + 4) +#define SIOCSIWPORTTYPE (SIOCDEVPRIVATE + 5) +#define SIOCGIWPORTTYPE (SIOCDEVPRIVATE + 6) /* IOCTL code for the RTS interface */ -#define WL_IOCTL_RTS SIOCDEVPRIVATE+7 +#define WL_IOCTL_RTS (SIOCDEVPRIVATE + 7) /* IOCTL subcodes for WL_IOCTL_RTS */ #define WL_IOCTL_RTS_READ 1 -- cgit v1.2.3 From 3d09d2054d2dc78b6a4b3584c8095492d6dbdbb9 Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Tue, 20 Nov 2012 16:44:54 +0200 Subject: staging: wlags49_h2: wl_if.h: fixes tab indentation This commit sorts out the tab & space indentation problems that were reported by the checkpatch.pl tool. Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_if.h | 70 +++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/staging/wlags49_h2/wl_if.h b/drivers/staging/wlags49_h2/wl_if.h index d070e47fdac..5c6b2b55059 100644 --- a/drivers/staging/wlags49_h2/wl_if.h +++ b/drivers/staging/wlags49_h2/wl_if.h @@ -71,7 +71,7 @@ #define MAX_LTV_BUF_SIZE (512 - (sizeof(hcf_16) * 2)) #define HCF_TALLIES_SIZE (sizeof(CFG_HERMES_TALLIES_STRCT) + \ - (sizeof(hcf_16) * 2)) + (sizeof(hcf_16) * 2)) #define HCF_MAX_MULTICAST 16 #define HCF_MAX_NAME_LEN 32 @@ -176,57 +176,57 @@ UIL_FUN_PUT_INFO ******************************************************************************/ typedef struct { - __u16 length; - __u8 name[HCF_MAX_NAME_LEN]; + __u16 length; + __u8 name[HCF_MAX_NAME_LEN]; } wvName_t; typedef struct { - hcf_16 len; - hcf_16 typ; - union - { - hcf_8 u8[MAX_LTV_BUF_SIZE / sizeof(hcf_8)]; - hcf_16 u16[MAX_LTV_BUF_SIZE / sizeof(hcf_16)]; - hcf_32 u32[MAX_LTV_BUF_SIZE / sizeof(hcf_32)]; - } u; + hcf_16 len; + hcf_16 typ; + union + { + hcf_8 u8[MAX_LTV_BUF_SIZE / sizeof(hcf_8)]; + hcf_16 u16[MAX_LTV_BUF_SIZE / sizeof(hcf_16)]; + hcf_32 u32[MAX_LTV_BUF_SIZE / sizeof(hcf_32)]; + } u; } ltv_t; struct uilreq { - union - { - char ifrn_name[IFNAMSIZ]; - } ifr_ifrn; - - IFBP hcfCtx; - __u8 command; - __u8 result; - - /* The data field in this structure is typically an LTV of some type. The - len field is the size of the buffer in bytes, as opposed to words (like - the L-field in the LTV */ - __u16 len; - void *data; + union + { + char ifrn_name[IFNAMSIZ]; + } ifr_ifrn; + + IFBP hcfCtx; + __u8 command; + __u8 result; + + /* The data field in this structure is typically an LTV of some type. The + len field is the size of the buffer in bytes, as opposed to words (like + the L-field in the LTV */ + __u16 len; + void *data; }; struct rtsreq { - union - { - char ifrn_name[IFNAMSIZ]; - } - ifr_ifrn; - - __u16 typ; - __u16 reg; - __u16 len; - __u16 *data; + union + { + char ifrn_name[IFNAMSIZ]; + } + ifr_ifrn; + + __u16 typ; + __u16 reg; + __u16 len; + __u16 *data; }; -- cgit v1.2.3 From 38a4450635308c96bf3df20d6a2a6033afc40d32 Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Tue, 20 Nov 2012 16:44:55 +0200 Subject: staging: wlags49_h2: wl_if.h: fixes spaces-before-tabs issue This commit fixes a spaces-before-tabs problem that was reported by the checkpatch.pl tool. Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_if.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wlags49_h2/wl_if.h b/drivers/staging/wlags49_h2/wl_if.h index 5c6b2b55059..d1fdf82037f 100644 --- a/drivers/staging/wlags49_h2/wl_if.h +++ b/drivers/staging/wlags49_h2/wl_if.h @@ -75,7 +75,7 @@ #define HCF_MAX_MULTICAST 16 #define HCF_MAX_NAME_LEN 32 -#define MAX_LINE_SIZE 256 +#define MAX_LINE_SIZE 256 #define HCF_NUM_IO_PORTS 0x80 #define TX_TIMEOUT ((800 * HZ) / 1000) -- cgit v1.2.3 From 74a9369024bb939032a0676eab36cce514cb65fa Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Tue, 20 Nov 2012 16:44:56 +0200 Subject: staging: wlags49_h2: wl_if.h: fixes 80 char line length issues This commit sorts out 80+ char line length issues that were reported by the checkpatch.pl tool. Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_if.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/wlags49_h2/wl_if.h b/drivers/staging/wlags49_h2/wl_if.h index d1fdf82037f..61193b30337 100644 --- a/drivers/staging/wlags49_h2/wl_if.h +++ b/drivers/staging/wlags49_h2/wl_if.h @@ -104,7 +104,8 @@ #define HCF_MAX_NOISE_LEVEL HCF_MAX_SIGNAL_LEVEL #define HCF_0DBM_OFFSET (HCF_MAX_SIGNAL_LEVEL + 1) #define HCF_MIN_COMM_QUALITY 0 -#define HCF_MAX_COMM_QUALITY (HCF_MAX_SIGNAL_LEVEL - HCF_MIN_NOISE_LEVEL + 1) +#define HCF_MAX_COMM_QUALITY (HCF_MAX_SIGNAL_LEVEL - \ + HCF_MIN_NOISE_LEVEL + 1) /* For encryption (WEP) */ @@ -207,9 +208,9 @@ struct uilreq __u8 command; __u8 result; - /* The data field in this structure is typically an LTV of some type. The - len field is the size of the buffer in bytes, as opposed to words (like - the L-field in the LTV */ + /* The data field in this structure is typically an LTV of some type. + The len field is the size of the buffer in bytes, as opposed to words + (like the L-field in the LTV */ __u16 len; void *data; }; -- cgit v1.2.3 From 5aeb6fcbab02f54e6976acd020999c20e22735bc Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Tue, 20 Nov 2012 16:44:57 +0200 Subject: staging: wlags49_h2: wl_if.h: fixes brace placement This commit fixes incorrect brace placement, as reported by the checkpatch.pl tool. Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_if.h | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/staging/wlags49_h2/wl_if.h b/drivers/staging/wlags49_h2/wl_if.h index 61193b30337..351d29b821e 100644 --- a/drivers/staging/wlags49_h2/wl_if.h +++ b/drivers/staging/wlags49_h2/wl_if.h @@ -175,20 +175,17 @@ UIL_FUN_PUT_INFO /******************************************************************************* * STRUCTURE DEFINITIONS ******************************************************************************/ -typedef struct -{ +typedef struct { __u16 length; __u8 name[HCF_MAX_NAME_LEN]; } wvName_t; -typedef struct -{ +typedef struct { hcf_16 len; hcf_16 typ; - union - { + union { hcf_8 u8[MAX_LTV_BUF_SIZE / sizeof(hcf_8)]; hcf_16 u16[MAX_LTV_BUF_SIZE / sizeof(hcf_16)]; hcf_32 u32[MAX_LTV_BUF_SIZE / sizeof(hcf_32)]; @@ -197,10 +194,8 @@ typedef struct ltv_t; -struct uilreq -{ - union - { +struct uilreq { + union { char ifrn_name[IFNAMSIZ]; } ifr_ifrn; @@ -216,10 +211,8 @@ struct uilreq }; -struct rtsreq -{ - union - { +struct rtsreq { + union { char ifrn_name[IFNAMSIZ]; } ifr_ifrn; -- cgit v1.2.3 From 0da7da721a80d169e02c5eb730247df6aec56e9b Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Tue, 20 Nov 2012 16:44:58 +0200 Subject: staging: wlags49_h2: wl_if.h: gets rid of C99 // comments This commit converts all C99 // comments to standard /* */ comments Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_if.h | 39 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/drivers/staging/wlags49_h2/wl_if.h b/drivers/staging/wlags49_h2/wl_if.h index 351d29b821e..425d3733b36 100644 --- a/drivers/staging/wlags49_h2/wl_if.h +++ b/drivers/staging/wlags49_h2/wl_if.h @@ -80,24 +80,17 @@ #define TX_TIMEOUT ((800 * HZ) / 1000) -//#define HCF_MIN_COMM_QUALITY 0 -//#define HCF_MAX_COMM_QUALITY 92 -//#define HCF_MIN_SIGNAL_LEVEL 47 -//#define HCF_MAX_SIGNAL_LEVEL 138 -//#define HCF_MIN_NOISE_LEVEL 47 -//#define HCF_MAX_NOISE_LEVEL 138 -//#define HCF_0DBM_OFFSET 149 - -// PE1DNN -// Better data from the real world. Not scientific but empirical data gathered -// from a Thomson Speedtouch 110 which is identified as: -// PCMCIA Info: "Agere Systems" "Wireless PC Card Model 0110" -// Manufacture ID: 0156,0003 -// Lowest measurment for noise floor seen is value 54 -// Highest signal strength in close proximity to the AP seen is value 118 -// Very good must be around 100 (otherwise its never "full scale" -// All other constants are derrived from these. This makes the signal gauge -// work for me... +/* PE1DNN + * Better data from the real world. Not scientific but empirical data gathered + * from a Thomson Speedtouch 110 which is identified as: + * PCMCIA Info: "Agere Systems" "Wireless PC Card Model 0110" + * Manufacture ID: 0156,0003 + * Lowest measurment for noise floor seen is value 54 + * Highest signal strength in close proximity to the AP seen is value 118 + * Very good must be around 100 (otherwise its never "full scale" + * All other constants are derrived from these. This makes the signal gauge + * work for me... + */ #define HCF_MIN_SIGNAL_LEVEL 54 #define HCF_MAX_SIGNAL_LEVEL 100 #define HCF_MIN_NOISE_LEVEL HCF_MIN_SIGNAL_LEVEL @@ -109,8 +102,8 @@ /* For encryption (WEP) */ -#define MIN_KEY_SIZE 5 // 40 bits RC4 - WEP -#define MAX_KEY_SIZE 13 // 104 bits +#define MIN_KEY_SIZE 5 /* 40 bits RC4 - WEP */ +#define MAX_KEY_SIZE 13 /* 104 bits */ #define MAX_KEYS 4 #define RADIO_CHANNELS 14 @@ -126,8 +119,8 @@ #define HCF_FAILURE 0xFF #define UIL_FAILURE 0xFF -#define CFG_UIL_CONNECT 0xA123 // Define differently? -#define CFG_UIL_CONNECT_ACK_CODE 0x5653435A // VSCZ +#define CFG_UIL_CONNECT 0xA123 /* Define differently? */ +#define CFG_UIL_CONNECT_ACK_CODE 0x5653435A /* VSCZ */ #define WVLAN2_UIL_CONNECTED (0x01L << 0) #define WVLAN2_UIL_BUSY (0x01L << 1) @@ -224,5 +217,5 @@ struct rtsreq { }; -#endif // __WAVELAN2_IF_H__ +#endif /* __WAVELAN2_IF_H__ */ -- cgit v1.2.3 From bfdc409770a3700c08712983c7bfbddec45401e5 Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Tue, 20 Nov 2012 16:44:59 +0200 Subject: staging: wlags49_h2: ap_h2.c: fixes spaces-before-tabs problems This commit sorts out a few instances of spaces before tabs, as reported by the checkpatch.pl tool. Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/ap_h2.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wlags49_h2/ap_h2.c b/drivers/staging/wlags49_h2/ap_h2.c index eb8244c4d6f..e524153e925 100644 --- a/drivers/staging/wlags49_h2/ap_h2.c +++ b/drivers/staging/wlags49_h2/ap_h2.c @@ -25,10 +25,10 @@ */ -#include "hcfcfg.h" /* to get hcf_16 etc defined as well as */ +#include "hcfcfg.h" /* to get hcf_16 etc defined as well as */ /* possible settings which inluence mdd.h or dhf.h */ -#include "mdd.h" /* to get COMP_ID_STA etc defined */ -#include "dhf.h" /* used to be "fhfmem.h", to get memblock,plugrecord, */ +#include "mdd.h" /* to get COMP_ID_STA etc defined */ +#include "dhf.h" /* used to be "fhfmem.h", to get memblock,plugrecord, */ static const hcf_8 fw_image_1_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3301,7 +3301,7 @@ static const CFG_RANGE20_STRCT fw_image_infocompat[] = { COMP_ROLE_SUPL, COMP_ID_APF, { - { 2, 2, 4 } /* variant, bottom, top */ + { 2, 2, 4 } /* variant, bottom, top */ } }, { 3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)), @@ -3309,9 +3309,9 @@ static const CFG_RANGE20_STRCT fw_image_infocompat[] = { COMP_ROLE_ACT, COMP_ID_MFI, { - { 4, 6, 7 }, /* variant, bottom, top */ - { 5, 6, 7 }, /* variant, bottom, top */ - { 6, 6, 7 } /* variant, bottom, top */ + { 4, 6, 7 }, /* variant, bottom, top */ + { 5, 6, 7 }, /* variant, bottom, top */ + { 6, 6, 7 } /* variant, bottom, top */ } }, { 3 + ((20 * sizeof(CFG_RANGE_SPEC_STRCT)) / sizeof(hcf_16)), @@ -3319,7 +3319,7 @@ static const CFG_RANGE20_STRCT fw_image_infocompat[] = { COMP_ROLE_ACT, COMP_ID_CFI, { - { 2, 1, 2 } /* variant, bottom, top */ + { 2, 1, 2 } /* variant, bottom, top */ } }, { 0000, 0000, 0000, 0000, { { 0000, 0000, 0000 } } } /* endsentinel */ -- cgit v1.2.3 From 1a65e204961969fa967a9aed6e8bab5d9ac66717 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:19:34 -0500 Subject: staging: wlags49_h2: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed, remove it. This also changes the syntax for the initialization of the wl_driver struct to match convention. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_pci.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c index a09c3ac793a..687b29895d4 100644 --- a/drivers/staging/wlags49_h2/wl_pci.c +++ b/drivers/staging/wlags49_h2/wl_pci.c @@ -160,14 +160,13 @@ void wl_pci_dma_hcf_reclaim_rx( struct wl_private *lp ); /******************************************************************************* * PCI module function registration ******************************************************************************/ -static struct pci_driver wl_driver = -{ - name: MODULE_NAME, - id_table: wl_pci_tbl, - probe: wl_pci_probe, - remove: __devexit_p(wl_pci_remove), - suspend: NULL, - resume: NULL, +static struct pci_driver wl_driver = { + .name = MODULE_NAME, + .id_table = wl_pci_tbl, + .probe = wl_pci_probe, + .remove = wl_pci_remove, + .suspend = NULL, + .resume = NULL }; /******************************************************************************* -- cgit v1.2.3 From a7d712aa3a0395ea142d85622205db342ea6b6cd Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:21:53 -0500 Subject: staging: wlags49_h2: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c index 687b29895d4..84b24204e4a 100644 --- a/drivers/staging/wlags49_h2/wl_pci.c +++ b/drivers/staging/wlags49_h2/wl_pci.c @@ -124,7 +124,7 @@ MODULE_DEVICE_TABLE(pci, wl_pci_tbl); /******************************************************************************* * function prototypes ******************************************************************************/ -int __devinit wl_pci_probe( struct pci_dev *pdev, +int wl_pci_probe( struct pci_dev *pdev, const struct pci_device_id *ent ); void __devexit wl_pci_remove(struct pci_dev *pdev); int wl_pci_setup( struct pci_dev *pdev ); @@ -398,7 +398,7 @@ int wl_adapter_is_open( struct net_device *dev ) * errno value otherwise * ******************************************************************************/ -int __devinit wl_pci_probe( struct pci_dev *pdev, +int wl_pci_probe( struct pci_dev *pdev, const struct pci_device_id *ent ) { int result; -- cgit v1.2.3 From cea69a149a496da70a6b66c5ed988043aabaae3a Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:24:47 -0500 Subject: staging: wlags49_h2: remove use of __devinitdata CONFIG_HOTPLUG is going away as an option so __devinitdata is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c index 84b24204e4a..38bb63ca0af 100644 --- a/drivers/staging/wlags49_h2/wl_pci.c +++ b/drivers/staging/wlags49_h2/wl_pci.c @@ -111,7 +111,7 @@ extern dbg_info_t *DbgInfo; #endif // DBG /* define the PCI device Table Cardname and id tables */ -static struct pci_device_id wl_pci_tbl[] __devinitdata = { +static struct pci_device_id wl_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_0), }, { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_1), }, { PCI_DEVICE(PCI_VENDOR_ID_WL_LKM, PCI_DEVICE_ID_WL_LKM_2), }, -- cgit v1.2.3 From a1fc9d87a1061299950a0dc9dac595ab6293ff13 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:26:54 -0500 Subject: staging: wlags49_h2: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c index 38bb63ca0af..6226e5eebf3 100644 --- a/drivers/staging/wlags49_h2/wl_pci.c +++ b/drivers/staging/wlags49_h2/wl_pci.c @@ -126,7 +126,7 @@ MODULE_DEVICE_TABLE(pci, wl_pci_tbl); ******************************************************************************/ int wl_pci_probe( struct pci_dev *pdev, const struct pci_device_id *ent ); -void __devexit wl_pci_remove(struct pci_dev *pdev); +void wl_pci_remove(struct pci_dev *pdev); int wl_pci_setup( struct pci_dev *pdev ); void wl_pci_enable_cardbus_interrupts( struct pci_dev *pdev ); @@ -435,7 +435,7 @@ int wl_pci_probe( struct pci_dev *pdev, * N/A * ******************************************************************************/ -void __devexit wl_pci_remove(struct pci_dev *pdev) +void wl_pci_remove(struct pci_dev *pdev) { struct net_device *dev = NULL; /*------------------------------------------------------------------------*/ -- cgit v1.2.3 From 596c5dd302aad8dea6be12d32d5dfa5d2f72673d Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:26:57 -0500 Subject: staging: et131x: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Acked-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 5f15a2e175b..8bfe756e040 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -4034,7 +4034,7 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, * PCI subsystem detects that a PCI device which matches the information * contained in the pci_device_id table has been removed. */ -static void __devexit et131x_pci_remove(struct pci_dev *pdev) +static void et131x_pci_remove(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct et131x_adapter *adapter = netdev_priv(netdev); -- cgit v1.2.3 From fe5c49b3325e38dd350fc3ceaf30b8f8a3f136b8 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:22:12 -0500 Subject: staging: et131x: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Acked-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 8bfe756e040..d017e67d2ff 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -4897,7 +4897,7 @@ static const struct net_device_ops et131x_netdev_ops = { * contained in the pci_device_id table. This routine is the equivalent to * a device insertion routine. */ -static int __devinit et131x_pci_setup(struct pci_dev *pdev, +static int et131x_pci_setup(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *netdev; -- cgit v1.2.3 From 0b5e4092241eb4015a91e01d9aca32c214ea8b50 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:20:50 -0500 Subject: staging: et131x: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Cc: devel@driverdev.osuosl.org Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index d017e67d2ff..525a7cbec1c 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -5099,7 +5099,7 @@ static struct pci_driver et131x_driver = { .name = DRIVER_NAME, .id_table = et131x_pci_table, .probe = et131x_pci_setup, - .remove = __devexit_p(et131x_pci_remove), + .remove = et131x_pci_remove, .driver.pm = ET131X_PM_OPS, }; -- cgit v1.2.3 From 15ffde4d36c30d81cd04a154960608486a1464f4 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Fri, 16 Nov 2012 10:47:37 +0000 Subject: staging: et131x: Refactor et131x_isr() to remove indenting By negating a 'status' variable check in et131x_isr(), we can remove the indenting of a large block of code, increasing the readability. This patch does exactly that. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 295 +++++++++++++++++++--------------------- 1 file changed, 141 insertions(+), 154 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 525a7cbec1c..82ed113f444 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -4234,182 +4234,169 @@ static void et131x_isr_handler(struct work_struct *work) status &= 0xffffffd7; - if (status) { - /* Handle the TXDMA Error interrupt */ - if (status & ET_INTR_TXDMA_ERR) { - u32 txdma_err; + if (!status) + goto out; - /* Following read also clears the register (COR) */ - txdma_err = readl(&iomem->txdma.tx_dma_error); + /* Handle the TXDMA Error interrupt */ + if (status & ET_INTR_TXDMA_ERR) { + u32 txdma_err; - dev_warn(&adapter->pdev->dev, - "TXDMA_ERR interrupt, error = %d\n", - txdma_err); - } + /* Following read also clears the register (COR) */ + txdma_err = readl(&iomem->txdma.tx_dma_error); - /* Handle Free Buffer Ring 0 and 1 Low interrupt */ - if (status & - (ET_INTR_RXDMA_FB_R0_LOW | ET_INTR_RXDMA_FB_R1_LOW)) { - /* - * This indicates the number of unused buffers in - * RXDMA free buffer ring 0 is <= the limit you - * programmed. Free buffer resources need to be - * returned. Free buffers are consumed as packets - * are passed from the network to the host. The host - * becomes aware of the packets from the contents of - * the packet status ring. This ring is queried when - * the packet done interrupt occurs. Packets are then - * passed to the OS. When the OS is done with the - * packets the resources can be returned to the - * ET1310 for re-use. This interrupt is one method of - * returning resources. - */ - - /* If the user has flow control on, then we will - * send a pause packet, otherwise just exit - */ - if (adapter->flowcontrol == FLOW_TXONLY || - adapter->flowcontrol == FLOW_BOTH) { - u32 pm_csr; + dev_warn(&adapter->pdev->dev, + "TXDMA_ERR interrupt, error = %d\n", + txdma_err); + } - /* Tell the device to send a pause packet via - * the back pressure register (bp req and - * bp xon/xoff) - */ - pm_csr = readl(&iomem->global.pm_csr); - if (!et1310_in_phy_coma(adapter)) - writel(3, &iomem->txmac.bp_ctrl); - } - } + /* Handle Free Buffer Ring 0 and 1 Low interrupt */ + if (status & (ET_INTR_RXDMA_FB_R0_LOW | ET_INTR_RXDMA_FB_R1_LOW)) { + /* + * This indicates the number of unused buffers in RXDMA free + * buffer ring 0 is <= the limit you programmed. Free buffer + * resources need to be returned. Free buffers are consumed as + * packets are passed from the network to the host. The host + * becomes aware of the packets from the contents of the packet + * status ring. This ring is queried when the packet done + * interrupt occurs. Packets are then passed to the OS. When + * the OS is done with the packets the resources can be + * returned to the ET1310 for re-use. This interrupt is one + * method of returning resources. + */ - /* Handle Packet Status Ring Low Interrupt */ - if (status & ET_INTR_RXDMA_STAT_LOW) { + /* + * If the user has flow control on, then we will + * send a pause packet, otherwise just exit + */ + if (adapter->flowcontrol == FLOW_TXONLY || + adapter->flowcontrol == FLOW_BOTH) { + u32 pm_csr; /* - * Same idea as with the two Free Buffer Rings. - * Packets going from the network to the host each - * consume a free buffer resource and a packet status - * resource. These resoures are passed to the OS. - * When the OS is done with the resources, they need - * to be returned to the ET1310. This is one method - * of returning the resources. + * Tell the device to send a pause packet via the back + * pressure register (bp req and bp xon/xoff) */ + pm_csr = readl(&iomem->global.pm_csr); + if (!et1310_in_phy_coma(adapter)) + writel(3, &iomem->txmac.bp_ctrl); } + } - /* Handle RXDMA Error Interrupt */ - if (status & ET_INTR_RXDMA_ERR) { - /* - * The rxdma_error interrupt is sent when a time-out - * on a request issued by the JAGCore has occurred or - * a completion is returned with an un-successful - * status. In both cases the request is considered - * complete. The JAGCore will automatically re-try the - * request in question. Normally information on events - * like these are sent to the host using the "Advanced - * Error Reporting" capability. This interrupt is - * another way of getting similar information. The - * only thing required is to clear the interrupt by - * reading the ISR in the global resources. The - * JAGCore will do a re-try on the request. Normally - * you should never see this interrupt. If you start - * to see this interrupt occurring frequently then - * something bad has occurred. A reset might be the - * thing to do. - */ - /* TRAP();*/ + /* Handle Packet Status Ring Low Interrupt */ + if (status & ET_INTR_RXDMA_STAT_LOW) { + /* + * Same idea as with the two Free Buffer Rings. Packets going + * from the network to the host each consume a free buffer + * resource and a packet status resource. These resoures are + * passed to the OS. When the OS is done with the resources, + * they need to be returned to the ET1310. This is one method + * of returning the resources. + */ + } - dev_warn(&adapter->pdev->dev, - "RxDMA_ERR interrupt, error %x\n", - readl(&iomem->txmac.tx_test)); - } + /* Handle RXDMA Error Interrupt */ + if (status & ET_INTR_RXDMA_ERR) { + /* + * The rxdma_error interrupt is sent when a time-out on a + * request issued by the JAGCore has occurred or a completion is + * returned with an un-successful status. In both cases the + * request is considered complete. The JAGCore will + * automatically re-try the request in question. Normally + * information on events like these are sent to the host using + * the "Advanced Error Reporting" capability. This interrupt is + * another way of getting similar information. The only thing + * required is to clear the interrupt by reading the ISR in the + * global resources. The JAGCore will do a re-try on the + * request. Normally you should never see this interrupt. If + * you start to see this interrupt occurring frequently then + * something bad has occurred. A reset might be the thing to do. + */ + /* TRAP();*/ - /* Handle the Wake on LAN Event */ - if (status & ET_INTR_WOL) { - /* - * This is a secondary interrupt for wake on LAN. - * The driver should never see this, if it does, - * something serious is wrong. We will TRAP the - * message when we are in DBG mode, otherwise we - * will ignore it. - */ - dev_err(&adapter->pdev->dev, "WAKE_ON_LAN interrupt\n"); - } + dev_warn(&adapter->pdev->dev, + "RxDMA_ERR interrupt, error %x\n", + readl(&iomem->txmac.tx_test)); + } - /* Let's move on to the TxMac */ - if (status & ET_INTR_TXMAC) { - u32 err = readl(&iomem->txmac.err); + /* Handle the Wake on LAN Event */ + if (status & ET_INTR_WOL) { + /* + * This is a secondary interrupt for wake on LAN. The driver + * should never see this, if it does, something serious is + * wrong. We will TRAP the message when we are in DBG mode, + * otherwise we will ignore it. + */ + dev_err(&adapter->pdev->dev, "WAKE_ON_LAN interrupt\n"); + } - /* - * When any of the errors occur and TXMAC generates - * an interrupt to report these errors, it usually - * means that TXMAC has detected an error in the data - * stream retrieved from the on-chip Tx Q. All of - * these errors are catastrophic and TXMAC won't be - * able to recover data when these errors occur. In - * a nutshell, the whole Tx path will have to be reset - * and re-configured afterwards. - */ - dev_warn(&adapter->pdev->dev, - "TXMAC interrupt, error 0x%08x\n", - err); + /* Let's move on to the TxMac */ + if (status & ET_INTR_TXMAC) { + u32 err = readl(&iomem->txmac.err); - /* If we are debugging, we want to see this error, - * otherwise we just want the device to be reset and - * continue - */ - } + /* + * When any of the errors occur and TXMAC generates an + * interrupt to report these errors, it usually means that + * TXMAC has detected an error in the data stream retrieved + * from the on-chip Tx Q. All of these errors are catastrophic + * and TXMAC won't be able to recover data when these errors + * occur. In a nutshell, the whole Tx path will have to be reset + * and re-configured afterwards. + */ + dev_warn(&adapter->pdev->dev, + "TXMAC interrupt, error 0x%08x\n", + err); - /* Handle RXMAC Interrupt */ - if (status & ET_INTR_RXMAC) { - /* - * These interrupts are catastrophic to the device, - * what we need to do is disable the interrupts and - * set the flag to cause us to reset so we can solve - * this issue. - */ - /* MP_SET_FLAG( adapter, - fMP_ADAPTER_HARDWARE_ERROR); */ + /* + * If we are debugging, we want to see this error, otherwise we + * just want the device to be reset and continue + */ + } - dev_warn(&adapter->pdev->dev, - "RXMAC interrupt, error 0x%08x. Requesting reset\n", - readl(&iomem->rxmac.err_reg)); + /* Handle RXMAC Interrupt */ + if (status & ET_INTR_RXMAC) { + /* + * These interrupts are catastrophic to the device, what we need + * to do is disable the interrupts and set the flag to cause us + * to reset so we can solve this issue. + */ + /* MP_SET_FLAG( adapter, fMP_ADAPTER_HARDWARE_ERROR); */ - dev_warn(&adapter->pdev->dev, - "Enable 0x%08x, Diag 0x%08x\n", - readl(&iomem->rxmac.ctrl), - readl(&iomem->rxmac.rxq_diag)); + dev_warn(&adapter->pdev->dev, + "RXMAC interrupt, error 0x%08x. Requesting reset\n", + readl(&iomem->rxmac.err_reg)); - /* - * If we are debugging, we want to see this error, - * otherwise we just want the device to be reset and - * continue - */ - } + dev_warn(&adapter->pdev->dev, + "Enable 0x%08x, Diag 0x%08x\n", + readl(&iomem->rxmac.ctrl), + readl(&iomem->rxmac.rxq_diag)); - /* Handle MAC_STAT Interrupt */ - if (status & ET_INTR_MAC_STAT) { - /* - * This means at least one of the un-masked counters - * in the MAC_STAT block has rolled over. Use this - * to maintain the top, software managed bits of the - * counter(s). - */ - et1310_handle_macstat_interrupt(adapter); - } + /* + * If we are debugging, we want to see this error, otherwise we + * just want the device to be reset and continue + */ + } - /* Handle SLV Timeout Interrupt */ - if (status & ET_INTR_SLV_TIMEOUT) { - /* - * This means a timeout has occurred on a read or - * write request to one of the JAGCore registers. The - * Global Resources block has terminated the request - * and on a read request, returned a "fake" value. - * The most likely reasons are: Bad Address or the - * addressed module is in a power-down state and - * can't respond. - */ - } + /* Handle MAC_STAT Interrupt */ + if (status & ET_INTR_MAC_STAT) { + /* + * This means at least one of the un-masked counters in the + * MAC_STAT block has rolled over. Use this to maintain the top, + * software managed bits of the counter(s). + */ + et1310_handle_macstat_interrupt(adapter); } + + /* Handle SLV Timeout Interrupt */ + if (status & ET_INTR_SLV_TIMEOUT) { + /* + * This means a timeout has occurred on a read or write request + * to one of the JAGCore registers. The Global Resources block + * has terminated the request and on a read request, returned a + * "fake" value. The most likely reasons are: Bad Address or the + * addressed module is in a power-down state and can't respond. + */ + } +out: et131x_enable_interrupts(adapter); } -- cgit v1.2.3 From 1a2bd6b257592cc05e9dd3d36e5810466a075fc3 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Fri, 16 Nov 2012 10:47:38 +0000 Subject: staging: et131x: Remove alignment offset padding on DMA buffer allocation/free This padding was used to align buffers to a 4k boundary when returned from dma_alloc_coherent(). As the buffers are already 4k aligned, and the alignment no longer performed, the padding is not needed. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 82ed113f444..c411d13baa2 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -2291,8 +2291,7 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) for (id = 0; id < NUM_FBRS; id++) { /* Allocate an area of memory for Free Buffer Ring */ - bufsize = (sizeof(struct fbr_desc) * - rx_ring->fbr[id]->num_entries) + 0xfff; + bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries); rx_ring->fbr[id]->ring_virtaddr = dma_alloc_coherent(&adapter->pdev->dev, bufsize, @@ -2463,8 +2462,7 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) } bufsize = - (sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries) + - 0xfff; + sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries; dma_free_coherent(&adapter->pdev->dev, bufsize, rx_ring->fbr[id]->ring_virtaddr, -- cgit v1.2.3 From 823bb2e8e1df99a28977f212975562b30f8dfd5e Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Fri, 16 Nov 2012 10:47:39 +0000 Subject: staging: et131x: Reduce indenting in et131x_rx_dma_memory_free() This change negates an 'if' statement, allowing a large block of code to be un-indented, making the code more readable. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index c411d13baa2..9ccd9b7f2fb 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -2443,33 +2443,33 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) /* Free Free Buffer Rings */ for (id = 0; id < NUM_FBRS; id++) { - if (rx_ring->fbr[id]->ring_virtaddr) { - /* First the packet memory */ - for (index = 0; index < - (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); - index++) { - if (rx_ring->fbr[id]->mem_virtaddrs[index]) { + if (!rx_ring->fbr[id]->ring_virtaddr) + continue; - bufsize = (rx_ring->fbr[id]->buffsize * FBR_CHUNKS); + /* First the packet memory */ + for (index = 0; + index < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); + index++) { + if (rx_ring->fbr[id]->mem_virtaddrs[index]) { + bufsize = rx_ring->fbr[id]->buffsize * FBR_CHUNKS; - dma_free_coherent(&adapter->pdev->dev, - bufsize, - rx_ring->fbr[id]->mem_virtaddrs[index], - rx_ring->fbr[id]->mem_physaddrs[index]); + dma_free_coherent(&adapter->pdev->dev, + bufsize, + rx_ring->fbr[id]->mem_virtaddrs[index], + rx_ring->fbr[id]->mem_physaddrs[index]); - rx_ring->fbr[id]->mem_virtaddrs[index] = NULL; - } + rx_ring->fbr[id]->mem_virtaddrs[index] = NULL; } + } - bufsize = - sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries; + bufsize = + sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries; - dma_free_coherent(&adapter->pdev->dev, bufsize, - rx_ring->fbr[id]->ring_virtaddr, - rx_ring->fbr[id]->ring_physaddr); + dma_free_coherent(&adapter->pdev->dev, bufsize, + rx_ring->fbr[id]->ring_virtaddr, + rx_ring->fbr[id]->ring_physaddr); - rx_ring->fbr[id]->ring_virtaddr = NULL; - } + rx_ring->fbr[id]->ring_virtaddr = NULL; } /* Free Packet Status Ring */ -- cgit v1.2.3 From 9967bd4842b39eaf632f77028fdd798775fd9686 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Fri, 16 Nov 2012 10:47:40 +0000 Subject: staging: et131x: Remove incorrect comments regarding alignment A previous change removed code that aligned memory returned from dma_alloc_coherent() to a 4k boundary, which was not necessary. Some comments regarding this alignment still exist, so remove them as they no longer apply. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 9ccd9b7f2fb..703a874996a 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -2310,13 +2310,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) for (i = 0; i < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); i++) { dma_addr_t fbr_tmp_physaddr; - /* This code allocates an area of memory big enough for - * N free buffers + (buffer_size - 1) so that the - * buffers can be aligned on 4k boundaries. If each - * buffer were aligned to a buffer_size boundary, the - * effect would be to double the size of FBR0. By - * allocating N buffers at once, we reduce this overhead - */ rx_ring->fbr[id]->mem_virtaddrs[i] = dma_alloc_coherent( &adapter->pdev->dev, fbr_chunksize, &rx_ring->fbr[id]->mem_physaddrs[i], @@ -2901,9 +2894,6 @@ static int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) return -ENOMEM; } - /* Allocate enough memory for the Tx descriptor ring, and allocate - * some extra so that the ring can be aligned on a 4k boundary. - */ desc_size = (sizeof(struct tx_desc) * NUM_DESC_PER_RING_TX); tx_ring->tx_desc_ring = (struct tx_desc *) dma_alloc_coherent(&adapter->pdev->dev, -- cgit v1.2.3 From d959df0a4940e3c07be992279b9439626b23083f Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Fri, 16 Nov 2012 10:47:41 +0000 Subject: staging: et131x: Replace kmem_cache use with plain kmalloc/kfree The use of a kmem_cache was noted as being unusual in the TODO. Replace the kmem_cache with kmalloc/kfree so that the code is less suprising. Also tidy up the mess that was the et131x_init_recv() out of memory error path. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/README | 1 - drivers/staging/et131x/et131x.c | 79 ++++++++++------------------------------- 2 files changed, 19 insertions(+), 61 deletions(-) diff --git a/drivers/staging/et131x/README b/drivers/staging/et131x/README index 474a6f58f8d..38537d4c4e1 100644 --- a/drivers/staging/et131x/README +++ b/drivers/staging/et131x/README @@ -8,7 +8,6 @@ Note, the powermanagement options were removed from the vendor provided driver as they did not build properly at the time. TODO: - - Use of kmem_cache seems a bit unusual - some rx packets have CRC/code/frame errors Please send patches to: diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index 703a874996a..f5f8b1d9739 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -143,7 +143,6 @@ MODULE_DESCRIPTION("10/100/1000 Base-T Ethernet Driver for the ET1310 by Agere S #define fMP_DEST_BROAD 0x00000002 /* MP_ADAPTER flags */ -#define fMP_ADAPTER_RECV_LOOKASIDE 0x00000004 #define fMP_ADAPTER_INTERRUPT_IN_USE 0x00000008 /* MP_SHARED flags */ @@ -184,7 +183,6 @@ MODULE_DESCRIPTION("10/100/1000 Base-T Ethernet Driver for the ET1310 by Agere S #define NIC_DEFAULT_NUM_RFD 1024 #define NUM_FBRS 2 -#define NIC_MIN_NUM_RFD 64 #define NUM_PACKETS_HANDLED 256 #define ALCATEL_MULTICAST_PKT 0x01000000 @@ -316,9 +314,6 @@ struct rx_ring { u32 num_rfd; bool unfinished_receives; - - /* lookaside lists */ - struct kmem_cache *recv_lookaside; }; /* TX defines */ @@ -2384,21 +2379,6 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) rx_ring->num_rfd = NIC_DEFAULT_NUM_RFD; pr_info("PRS %llx\n", (unsigned long long)rx_ring->rx_status_bus); - /* Recv - * kmem_cache_create initializes a lookaside list. After successful - * creation, nonpaged fixed-size blocks can be allocated from and - * freed to the lookaside list. - * RFDs will be allocated from this pool. - */ - rx_ring->recv_lookaside = kmem_cache_create(adapter->netdev->name, - sizeof(struct rfd), - 0, - SLAB_CACHE_DMA | - SLAB_HWCACHE_ALIGN, - NULL); - - adapter->flags |= fMP_ADAPTER_RECV_LOOKASIDE; - /* The RFDs are going to be put on lists later on, so initialize the * lists now. */ @@ -2431,7 +2411,7 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) list_del(&rfd->list_node); rfd->skb = NULL; - kmem_cache_free(adapter->rx_ring.recv_lookaside, rfd); + kfree(rfd); } /* Free Free Buffer Rings */ @@ -2485,12 +2465,6 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) rx_ring->rx_status_block = NULL; } - /* Destroy the lookaside (RFD) pool */ - if (adapter->flags & fMP_ADAPTER_RECV_LOOKASIDE) { - kmem_cache_destroy(rx_ring->recv_lookaside); - adapter->flags &= ~fMP_ADAPTER_RECV_LOOKASIDE; - } - /* Free the FBR Lookup Table */ kfree(rx_ring->fbr[0]); kfree(rx_ring->fbr[1]); @@ -2507,8 +2481,7 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) */ static int et131x_init_recv(struct et131x_adapter *adapter) { - int status = -ENOMEM; - struct rfd *rfd = NULL; + struct rfd *rfd; u32 rfdct; u32 numrfd = 0; struct rx_ring *rx_ring; @@ -2518,14 +2491,11 @@ static int et131x_init_recv(struct et131x_adapter *adapter) /* Setup each RFD */ for (rfdct = 0; rfdct < rx_ring->num_rfd; rfdct++) { - rfd = kmem_cache_alloc(rx_ring->recv_lookaside, - GFP_ATOMIC | GFP_DMA); + rfd = kzalloc(sizeof(struct rfd), GFP_ATOMIC | GFP_DMA); if (!rfd) { - dev_err(&adapter->pdev->dev, - "Couldn't alloc RFD out of kmem_cache\n"); - status = -ENOMEM; - continue; + dev_err(&adapter->pdev->dev, "Couldn't alloc RFD\n"); + return -ENOMEM; } rfd->skb = NULL; @@ -2538,17 +2508,7 @@ static int et131x_init_recv(struct et131x_adapter *adapter) numrfd++; } - if (numrfd > NIC_MIN_NUM_RFD) - status = 0; - - rx_ring->num_rfd = numrfd; - - if (status != 0) { - kmem_cache_free(rx_ring->recv_lookaside, rfd); - dev_err(&adapter->pdev->dev, - "Allocation problems in et131x_init_recv\n"); - } - return status; + return 0; } /** @@ -3778,6 +3738,17 @@ static void et131x_error_timer_handler(unsigned long data) mod_timer(&adapter->error_timer, jiffies + TX_ERROR_PERIOD * HZ / 1000); } +/** + * et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx + * @adapter: pointer to our private adapter structure + */ +static void et131x_adapter_memory_free(struct et131x_adapter *adapter) +{ + /* Free DMA memory */ + et131x_tx_dma_memory_free(adapter); + et131x_rx_dma_memory_free(adapter); +} + /** * et131x_adapter_memory_alloc * @adapter: pointer to our private adapter structure @@ -3808,26 +3779,14 @@ static int et131x_adapter_memory_alloc(struct et131x_adapter *adapter) /* Init receive data structures */ status = et131x_init_recv(adapter); - if (status != 0) { + if (status) { dev_err(&adapter->pdev->dev, "et131x_init_recv FAILED\n"); - et131x_tx_dma_memory_free(adapter); - et131x_rx_dma_memory_free(adapter); + et131x_adapter_memory_free(adapter); } return status; } -/** - * et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx - * @adapter: pointer to our private adapter structure - */ -static void et131x_adapter_memory_free(struct et131x_adapter *adapter) -{ - /* Free DMA memory */ - et131x_tx_dma_memory_free(adapter); - et131x_rx_dma_memory_free(adapter); -} - static void et131x_adjust_link(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); -- cgit v1.2.3 From 3781683e5c992d6850c4f231e30465e705b2ded2 Mon Sep 17 00:00:00 2001 From: Mark Einon Date: Fri, 16 Nov 2012 10:47:42 +0000 Subject: staging: et131x: Removing final checkpatch errors, all line >80 chars Trivial Whitespace changes only. No checkpatch errors exist in et131x after this change. Signed-off-by: Mark Einon Signed-off-by: Greg Kroah-Hartman --- drivers/staging/et131x/et131x.c | 45 ++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/drivers/staging/et131x/et131x.c b/drivers/staging/et131x/et131x.c index f5f8b1d9739..84bbcd48e26 100644 --- a/drivers/staging/et131x/et131x.c +++ b/drivers/staging/et131x/et131x.c @@ -1870,8 +1870,10 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) } /* Now's the best time to initialize FBR contents */ - fbr_entry = (struct fbr_desc *) rx_local->fbr[id]->ring_virtaddr; - for (entry = 0; entry < rx_local->fbr[id]->num_entries; entry++) { + fbr_entry = + (struct fbr_desc *) rx_local->fbr[id]->ring_virtaddr; + for (entry = 0; + entry < rx_local->fbr[id]->num_entries; entry++) { fbr_entry->addr_hi = rx_local->fbr[id]->bus_high[entry]; fbr_entry->addr_lo = rx_local->fbr[id]->bus_low[entry]; fbr_entry->word2 = entry; @@ -1881,8 +1883,10 @@ static void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) /* Set the address and parameters of Free buffer ring 1 and 0 * into the 1310's registers */ - writel(upper_32_bits(rx_local->fbr[id]->ring_physaddr), base_hi); - writel(lower_32_bits(rx_local->fbr[id]->ring_physaddr), base_lo); + writel(upper_32_bits(rx_local->fbr[id]->ring_physaddr), + base_hi); + writel(lower_32_bits(rx_local->fbr[id]->ring_physaddr), + base_lo); writel(rx_local->fbr[id]->num_entries - 1, num_des); writel(ET_DMA10_WRAP, full_offset); @@ -2286,7 +2290,8 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) for (id = 0; id < NUM_FBRS; id++) { /* Allocate an area of memory for Free Buffer Ring */ - bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries); + bufsize = + (sizeof(struct fbr_desc) * rx_ring->fbr[id]->num_entries); rx_ring->fbr[id]->ring_virtaddr = dma_alloc_coherent(&adapter->pdev->dev, bufsize, @@ -2302,7 +2307,8 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) for (id = 0; id < NUM_FBRS; id++) { fbr_chunksize = (FBR_CHUNKS * rx_ring->fbr[id]->buffsize); - for (i = 0; i < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); i++) { + for (i = 0; + i < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); i++) { dma_addr_t fbr_tmp_physaddr; rx_ring->fbr[id]->mem_virtaddrs[i] = dma_alloc_coherent( @@ -2424,7 +2430,8 @@ static void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) index < (rx_ring->fbr[id]->num_entries / FBR_CHUNKS); index++) { if (rx_ring->fbr[id]->mem_virtaddrs[index]) { - bufsize = rx_ring->fbr[id]->buffsize * FBR_CHUNKS; + bufsize = + rx_ring->fbr[id]->buffsize * FBR_CHUNKS; dma_free_coherent(&adapter->pdev->dev, bufsize, @@ -2558,7 +2565,8 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) else offset = &rx_dma->fbr1_full_offset; - next = (struct fbr_desc *) (rx_local->fbr[ring_index]->ring_virtaddr) + + next = (struct fbr_desc *) + (rx_local->fbr[ring_index]->ring_virtaddr) + INDEX10(rx_local->fbr[ring_index]->local_full); /* Handle the Free Buffer Ring advancement here. Write @@ -2569,9 +2577,10 @@ static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) next->addr_lo = rx_local->fbr[ring_index]->bus_low[buff_index]; next->word2 = buff_index; - writel(bump_free_buff_ring(&rx_local->fbr[ring_index]->local_full, - rx_local->fbr[ring_index]->num_entries - 1), - offset); + writel(bump_free_buff_ring( + &rx_local->fbr[ring_index]->local_full, + rx_local->fbr[ring_index]->num_entries - 1), + offset); spin_unlock_irqrestore(&adapter->fbr_lock, flags); } else { @@ -2980,19 +2989,19 @@ static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) } else { desc[frag].len_vlan = skb_headlen(skb) / 2; dma_addr = dma_map_single(&adapter->pdev->dev, - skb->data, - (skb_headlen(skb) / 2), - DMA_TO_DEVICE); + skb->data, + (skb_headlen(skb) / 2), + DMA_TO_DEVICE); desc[frag].addr_lo = lower_32_bits(dma_addr); desc[frag].addr_hi = upper_32_bits(dma_addr); frag++; desc[frag].len_vlan = skb_headlen(skb) / 2; dma_addr = dma_map_single(&adapter->pdev->dev, - skb->data + - (skb_headlen(skb) / 2), - (skb_headlen(skb) / 2), - DMA_TO_DEVICE); + skb->data + + (skb_headlen(skb) / 2), + (skb_headlen(skb) / 2), + DMA_TO_DEVICE); desc[frag].addr_lo = lower_32_bits(dma_addr); desc[frag].addr_hi = upper_32_bits(dma_addr); frag++; -- cgit v1.2.3 From 5b7f7ab839a30c528ecb004bb56f3f03d9fe5dc0 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:09:55 +0900 Subject: staging/rtl8187se: Fix spacing coding style in r8180_dm.h The following errors fixed. -ERROR: "foo * bar" should be "foo *bar" Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_dm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_dm.h b/drivers/staging/rtl8187se/r8180_dm.h index b7758254ad7..732c06ac102 100644 --- a/drivers/staging/rtl8187se/r8180_dm.h +++ b/drivers/staging/rtl8187se/r8180_dm.h @@ -13,10 +13,10 @@ bool CheckDig(struct net_device *dev); bool CheckHighPower(struct net_device *dev); void rtl8180_hw_dig_wq(struct work_struct *work); void rtl8180_tx_pw_wq(struct work_struct *work); -void rtl8180_rate_adapter(struct work_struct * work); +void rtl8180_rate_adapter(struct work_struct *work); void TxPwrTracking87SE(struct net_device *dev); bool CheckTxPwrTracking(struct net_device *dev); -void rtl8180_rate_adapter(struct work_struct * work); +void rtl8180_rate_adapter(struct work_struct *work); void timer_rate_adaptive(unsigned long data); -- cgit v1.2.3 From a16f3eb1f2f48fb352d4541329f47f647cd65e96 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:10:42 +0900 Subject: staging/rtl8187se: Fix include file issue in ieee80211/ieee80211_crypt.c The following warnings fixed. - WARNING: Use #include instead of - WARNING: Use #include instead of Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c index b3882ae9d97..934b91598f2 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c @@ -15,8 +15,8 @@ #include #include #include -#include -#include +#include +#include #include "ieee80211.h" -- cgit v1.2.3 From 3bba8b9657f5bc2af70ee3af31e758485e310909 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:10:57 +0900 Subject: staging/rtl8187se: Use pr_ printks in ieee80211/ieee80211_crypt.c The following warnings fixed. - WARNING: Prefer netdev_dbg(netdev, ... then dev_dbg(dev, ... then pr_debug(... to printk(KERN_DEBUG ... and add pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c index 934b91598f2..623245c8cb2 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c @@ -11,6 +11,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + //#include #include #include @@ -66,8 +68,7 @@ void ieee80211_crypt_deinit_handler(unsigned long data) spin_lock_irqsave(&ieee->lock, flags); ieee80211_crypt_deinit_entries(ieee, 0); if (!list_empty(&ieee->crypt_deinit_list)) { - printk(KERN_DEBUG "%s: entries remaining in delayed crypt " - "deletion list\n", ieee->dev->name); + pr_debug("entries remaining in delayed crypt deletion list\n"); ieee->crypt_deinit_timer.expires = jiffies + HZ; add_timer(&ieee->crypt_deinit_timer); } @@ -118,8 +119,7 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) list_add(&alg->list, &hcrypt->algs); spin_unlock_irqrestore(&hcrypt->lock, flags); - printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n", - ops->name); + pr_debug("registered algorithm '%s'\n", ops->name); return 0; } @@ -146,8 +146,7 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) spin_unlock_irqrestore(&hcrypt->lock, flags); if (del_alg) { - printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " - "'%s'\n", ops->name); + pr_debug("unregistered algorithm '%s'\n", ops->name); kfree(del_alg); } @@ -234,9 +233,8 @@ void ieee80211_crypto_deinit(void) alg = list_entry(ptr, struct ieee80211_crypto_alg, list); if (alg) { list_del(ptr); - printk(KERN_DEBUG - "ieee80211_crypt: unregistered algorithm '%s' (deinit)\n", - alg->ops->name); + pr_debug("unregistered algorithm '%s' (deinit)\n", + alg->ops->name); kfree(alg); } } -- cgit v1.2.3 From 18637d934d50b828b766f4317408083a8a12f054 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:11:12 +0900 Subject: staging/rtl8187se: Fix spacing coding style in ieee80211/ieee80211_crypt.c The following errors fixed. -ERROR: "foo * bar" should be "foo *bar" Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c index 623245c8cb2..694eae3d4fd 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c @@ -154,7 +154,7 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) } -struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name) +struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name) { unsigned long flags; struct list_head *ptr; @@ -181,7 +181,7 @@ struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name) } -static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; } +static void *ieee80211_crypt_null_init(int keyidx) { return (void *) 1; } static void ieee80211_crypt_null_deinit(void *priv) {} static struct ieee80211_crypto_ops ieee80211_crypt_null = { -- cgit v1.2.3 From 29deac403ff4650848a66a45a909bfbbc694a9a9 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:11:25 +0900 Subject: staging/rtl8187se: Fix spacing coding style in ieee80211/ieee80211_crypt.h The following error fixed. -ERROR: "foo * bar" should be "foo *bar" Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h index b58a3bcc0dc..0b4ea431982 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h @@ -77,7 +77,7 @@ struct ieee80211_crypt_data { int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); -struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name); +struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name); void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int); void ieee80211_crypt_deinit_handler(unsigned long); void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, -- cgit v1.2.3 From 39550d282342357e1d4227b4bc5b94fb9b1ab975 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:11:40 +0900 Subject: staging/rtl8187se: Fix include file issue in ieee80211/ieee80211_module.c The following warning fixed. - WARNING: Use #include instead of Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c index 9422573bfea..0ed4c93f3c8 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include -- cgit v1.2.3 From 3c304fe63bdd8bfebfcc9196467cd787355bd4d5 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:11:54 +0900 Subject: staging/rtl8187se: Use netdev_ printks in ieee80211/ieee80211_module.c The following warning fixed. - WARNING: Prefer netdev_warn(netdev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_module.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c index 0ed4c93f3c8..66b4833a503 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c @@ -69,8 +69,7 @@ static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) MAX_NETWORK_COUNT, sizeof(struct ieee80211_network), GFP_KERNEL); if (!ieee->networks) { - printk(KERN_WARNING "%s: Out of memory allocating beacons\n", - ieee->dev->name); + netdev_warn(ieee->dev, "Out of memory allocating beacons\n"); return -ENOMEM; } -- cgit v1.2.3 From e3b9b6cf1b37522990246ac98267ecfe4bc25222 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:12:11 +0900 Subject: staging/rtl8187se: Fix spacing coding style in ieee80211/ieee80211_module.c The following errors and warnings fixed. - ERROR: space required after that ',' (ctx:VxV) - ERROR: code indent should use tabs where possible - WARNING: please, no space before tabs - WARNING: please, no spaces at the start of a line - WARNING: suspect code indent for conditional statements (8, 10) Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_module.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c index 66b4833a503..4358c4b0ca6 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c @@ -99,7 +99,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv) { struct ieee80211_device *ieee; struct net_device *dev; - int i,err; + int i, err; IEEE80211_DEBUG_INFO("Initializing...\n"); @@ -139,11 +139,11 @@ struct net_device *alloc_ieee80211(int sizeof_priv) spin_lock_init(&ieee->wpax_suitlist_lock); ieee->wpax_type_set = 0; - ieee->wpa_enabled = 0; - ieee->tkip_countermeasures = 0; - ieee->drop_unencrypted = 0; - ieee->privacy_invoked = 0; - ieee->ieee802_1x = 1; + ieee->wpa_enabled = 0; + ieee->tkip_countermeasures = 0; + ieee->drop_unencrypted = 0; + ieee->privacy_invoked = 0; + ieee->ieee802_1x = 1; ieee->raw_tx = 0; ieee80211_softmac_init(ieee); @@ -152,9 +152,9 @@ struct net_device *alloc_ieee80211(int sizeof_priv) INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]); for (i = 0; i < 17; i++) { - ieee->last_rxseq_num[i] = -1; - ieee->last_rxfrag_num[i] = -1; - ieee->last_packet_time[i] = 0; + ieee->last_rxseq_num[i] = -1; + ieee->last_rxfrag_num[i] = -1; + ieee->last_packet_time[i] = 0; } //These function were added to load crypte module autoly ieee80211_tkip_null(); -- cgit v1.2.3 From 8433b143244099a5789c3d3a874e43aef1fd1902 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:12:25 +0900 Subject: staging/rtl8187se: Fix include file issue in ieee80211/ieee80211_crypt_ccmp.c The following warnings fixed. - WARNING: Use #include instead of Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c index 6aaaa2fd57f..f95967538d3 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include "ieee80211.h" -- cgit v1.2.3 From 5bd6e9e0c7e87a5199c9fef3ef852f04898d0de2 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:12:39 +0900 Subject: staging/rtl8187se: Fix spacing coding style in ieee80211/ieee80211_crypt_ccmp.c The following errors fixed. -ERROR: "foo * bar" should be "foo *bar" Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c index f95967538d3..5465b09832f 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c @@ -64,7 +64,7 @@ void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm, crypto_cipher_encrypt_one((void *)tfm, ct, pt); } -static void * ieee80211_ccmp_init(int key_idx) +static void *ieee80211_ccmp_init(int key_idx) { struct ieee80211_ccmp_data *priv; @@ -415,7 +415,7 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv) } -static char * ieee80211_ccmp_print_stats(char *p, void *priv) +static char *ieee80211_ccmp_print_stats(char *p, void *priv) { struct ieee80211_ccmp_data *ccmp = priv; p += sprintf(p, "key[%d] alg=CCMP key_set=%d " -- cgit v1.2.3 From d6f272c25a6b37d2d62b55962f528d6f9b104188 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:12:52 +0900 Subject: staging/rtl8187se: Use pr_ printks in ieee80211/ieee80211_crypt_ccmp.c The following warnings fixed. - WARNING: Prefer netdev_dbg(netdev, ... then dev_dbg(dev, ... then pr_debug(... to printk(KERN_DEBUG ... and add pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- .../rtl8187se/ieee80211/ieee80211_crypt_ccmp.c | 26 ++++++++++------------ 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c index 5465b09832f..40217b7867d 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c @@ -9,6 +9,8 @@ * more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + //#include #include #include @@ -75,8 +77,7 @@ static void *ieee80211_ccmp_init(int key_idx) priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tfm)) { - printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate " - "crypto API aes\n"); + pr_debug("could not allocate crypto API aes\n"); priv->tfm = NULL; goto fail; } @@ -282,23 +283,22 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) keyidx = pos[3]; if (!(keyidx & (1 << 5))) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet without ExtIV" - " flag from %pM\n", hdr->addr2); + pr_debug("received packet without ExtIV flag from %pM\n", + hdr->addr2); } key->dot11RSNAStatsCCMPFormatErrors++; return -2; } keyidx >>= 6; if (key->key_idx != keyidx) { - printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame " - "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv); + pr_debug("RX tkey->key_idx=%d frame keyidx=%d priv=%p\n", + key->key_idx, keyidx, priv); return -6; } if (!key->key_set) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: received packet from %pM" - " with keyid=%d that does not have a configured" - " key\n", hdr->addr2, keyidx); + pr_debug("received packet from %pM with keyid=%d that does not have a configured key\n", + hdr->addr2, keyidx); } return -3; } @@ -313,9 +313,8 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: replay detected: STA=%pM" - " previous PN %pm received PN %pm\n", - hdr->addr2, key->rx_pn, pn); + pr_debug("replay detected: STA=%pM previous PN %pm received PN %pm\n", + hdr->addr2, key->rx_pn, pn); } key->dot11RSNAStatsCCMPReplays++; return -4; @@ -342,8 +341,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { if (net_ratelimit()) { - printk(KERN_DEBUG "CCMP: decrypt failed: STA=" - "%pM\n", hdr->addr2); + pr_debug("decrypt failed: STA=%pM\n", hdr->addr2); } key->dot11RSNAStatsCCMPDecryptErrors++; return -5; -- cgit v1.2.3 From 937afb70a09d87afa07831bc5ba951a1b8fb3c9b Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:13:05 +0900 Subject: staging/rtl8187se: Fix spacing coding style in ieee80211/ieee80211_crypt_ccmp.c The following error and warning fixed. - ERROR: code indent should use tabs where possible - WARNING: braces {} are not necessary for single statement blocks Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c index 40217b7867d..f5949e89e5c 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c @@ -129,7 +129,7 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, /* qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && (WLAN_FC_GET_STYPE(fc) & 0x08)); - */ + */ // fixed by David :2006.9.6 qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && (WLAN_FC_GET_STYPE(fc) & 0x80)); @@ -340,9 +340,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { - if (net_ratelimit()) { + if (net_ratelimit()) pr_debug("decrypt failed: STA=%pM\n", hdr->addr2); - } + key->dot11RSNAStatsCCMPDecryptErrors++; return -5; } -- cgit v1.2.3 From 4de389bd055033d2841761ce48b6a4aaab7b5c58 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:13:17 +0900 Subject: staging/rtl8187se: Fix include file issue in ieee80211/ieee80211_crypt_wep.c The following warning fixed. - WARNING: Use #include instead of Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c index 58f3eeb2143..c0effee1e69 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include "ieee80211.h" -- cgit v1.2.3 From 98319002a2bb8e1d2d59a863bc852fbd87cf6ad8 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:13:32 +0900 Subject: staging/rtl8187se: Fix spacing coding style in ieee80211/ieee80211_crypt_wep.c The following errors fixed. -ERROR: "foo * bar" should be "foo *bar" Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c index c0effee1e69..725408592ae 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c @@ -40,7 +40,7 @@ struct prism2_wep_data { }; -static void * prism2_wep_init(int keyidx) +static void *prism2_wep_init(int keyidx) { struct prism2_wep_data *priv; @@ -248,7 +248,7 @@ static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) } -static char * prism2_wep_print_stats(char *p, void *priv) +static char *prism2_wep_print_stats(char *p, void *priv) { struct prism2_wep_data *wep = priv; p += sprintf(p, "key[%d] alg=WEP len=%d\n", -- cgit v1.2.3 From e10fbca9536398efa0d7ced0b099deca5dff0eeb Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:13:46 +0900 Subject: staging/rtl8187se: Use pr_ printks in ieee80211/ieee80211_crypt_wep.c The following warnings fixed. - WARNING: Prefer netdev_dbg(netdev, ... then dev_dbg(dev, ... then pr_debug(... to printk(KERN_DEBUG ... and add pr_fmt. Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c index 725408592ae..bb9a0781e20 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c @@ -9,6 +9,8 @@ * more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + //#include #include #include @@ -50,15 +52,13 @@ static void *prism2_wep_init(int keyidx) priv->key_idx = keyidx; priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm)) { - printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " - "crypto API arc4\n"); + pr_debug("could not allocate crypto API arc4\n"); priv->tx_tfm = NULL; goto fail; } priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm)) { - printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " - "crypto API arc4\n"); + pr_debug("could not allocate crypto API arc4\n"); priv->rx_tfm = NULL; goto fail; } -- cgit v1.2.3 From 0ef68ab4dd8d16c10e7b36796f11b6a209acc1de Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Tue, 20 Nov 2012 21:13:59 +0900 Subject: staging/rtl8187se: Fix spacing coding style in ieee80211/ieee80211_crypt_wep.c The following errors and warnings fixed. - ERROR: code indent should use tabs where possible - WARNING: please, no spaces at the start of a line Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c index bb9a0781e20..bba77141d9a 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c @@ -217,7 +217,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) memmove(skb->data + 4, skb->data, hdr_len); skb_pull(skb, 4); skb_trim(skb, skb->len - 4); - return 0; + return 0; } @@ -289,5 +289,5 @@ void ieee80211_crypto_wep_exit(void) void ieee80211_wep_null(void) { // printk("============>%s()\n", __func__); - return; + return; } -- cgit v1.2.3 From 545bb52ccd8008c113a002b7f7d5165aa6da5ee3 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 21 Nov 2012 05:16:37 +0900 Subject: staging/rtl8187se: Use netdev_ printks in r8185b_init.c The following warnings fixed. - WARNING: Prefer netdev_err(netdev, ... then dev_err(dev, ... then pr_err(... to printk(KERN_ERR ... - WARNING: Prefer netdev_info(netdev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ... Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8185b_init.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 5c454fa861c..28611c2f26e 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -223,9 +223,10 @@ static bool HwHSSIThreeWire(struct net_device *dev, udelay(10); } if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) { - printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:" - " %#X RE|WE bits are not clear!!\n", u1bTmp); - return false; + netdev_err(dev, + "HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", + u1bTmp); + return false; } /* RTL8187S HSSI Read/Write Function */ @@ -419,7 +420,7 @@ void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) if (u4bRF23 == 0x818 && u4bRF24 == 0x70C) { d_cut = 1; - printk(KERN_INFO "rtl8187se: card type changed from C- to D-cut\n"); + netdev_info(dev, "card type changed from C- to D-cut\n"); } /* Page0 : reg0-reg15 */ -- cgit v1.2.3 From 167989ba2eeff882a6e5afd74c409661cdbf3fc9 Mon Sep 17 00:00:00 2001 From: YAMANE Toshiaki Date: Wed, 21 Nov 2012 05:17:13 +0900 Subject: staging/rtl8187se: Fix spacing coding style in r8185b_init.c The following errors and warnings fixed. - ERROR: space prohibited after that open parenthesis '(' - ERROR: space prohibited before that close parenthesis ')' - ERROR: space required before the open parenthesis '(' - WARNING: braces {} are not necessary for any arm of this statement Signed-off-by: YAMANE Toshiaki Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8185b_init.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c index 28611c2f26e..f1db9e401c8 100644 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ b/drivers/staging/rtl8187se/r8185b_init.c @@ -1056,13 +1056,13 @@ void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode) ieee->mode = (WIRELESS_MODE)btWirelessMode; /* 3. Change related setting. */ - if( ieee->mode == WIRELESS_MODE_A ) { + if (ieee->mode == WIRELESS_MODE_A) DMESG("WIRELESS_MODE_A\n"); - } else if( ieee->mode == WIRELESS_MODE_B ) { + else if (ieee->mode == WIRELESS_MODE_B) DMESG("WIRELESS_MODE_B\n"); - } else if( ieee->mode == WIRELESS_MODE_G ) { + else if (ieee->mode == WIRELESS_MODE_G) DMESG("WIRELESS_MODE_G\n"); - } + ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting); } -- cgit v1.2.3 From 90c1076509496a2e728d3749c8115dc8c57be9dd Mon Sep 17 00:00:00 2001 From: MAACHE Mehdi Date: Wed, 21 Nov 2012 15:18:29 +0100 Subject: Staging: rtl8187se: remove check for IW_ENCODE_DISABLED The original code had a no-op stub where it checked if IW_ENCODE_DISABLED and did nothing. Then in a cleanup patch we accidentally turned the check on. That was: de171bd6ff "Staging: rtl8187se: r8180_wx: fixed a lot of checkpatch.pl issues". The check should just be removed. Signed-off-by: Mehdi MAACHE Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_wx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c index 52f63d75d24..156b7588229 100644 --- a/drivers/staging/rtl8187se/r8180_wx.c +++ b/drivers/staging/rtl8187se/r8180_wx.c @@ -59,8 +59,6 @@ int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info, if (priv->ieee80211->bHwRadioOff) return 0; - if (erq->flags & IW_ENCODE_DISABLED) - if (erq->length > 0) { u32* tkey = (u32*) key; priv->key0[0] = tkey[0]; -- cgit v1.2.3 From 435c78dfb8bfacbb378cb6b929c06667281be325 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:20:56 -0500 Subject: staging: rtl8187se: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 6a27836f989..ca097e45064 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -149,7 +149,7 @@ static struct pci_driver rtl8180_pci_driver = { .name = RTL8180_MODULE_NAME, .id_table = rtl8180_pci_id_tbl, .probe = rtl8180_pci_probe, - .remove = __devexit_p(rtl8180_pci_remove), + .remove = rtl8180_pci_remove, .suspend = rtl8180_suspend, .resume = rtl8180_resume, .shutdown = rtl8180_shutdown, -- cgit v1.2.3 From c08561c5cffa7053aeb47aac6d39bb1fa38f0248 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:20:58 -0500 Subject: staging: rtl8192e: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index f68df241f78..3d636c34574 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -99,7 +99,7 @@ static struct pci_driver rtl8192_pci_driver = { .name = DRV_NAME, /* Driver name */ .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */ .probe = rtl8192_pci_probe, /* probe fn */ - .remove = __devexit_p(rtl8192_pci_disconnect), /* remove fn */ + .remove = rtl8192_pci_disconnect, /* remove fn */ .suspend = rtl8192E_suspend, /* PM suspend fn */ .resume = rtl8192E_resume, /* PM resume fn */ }; -- cgit v1.2.3 From 2579452a6deff806d06f5ebb7ae1e8d51c39c9d3 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:22:04 -0500 Subject: staging: rtl8192u: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 5a2fab9fa77..12572fa3a36 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -144,7 +144,7 @@ MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default"); MODULE_PARM_DESC(hwwep," Try to use hardware security support. "); MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI"); -static int __devinit rtl8192_usb_probe(struct usb_interface *intf, +static int rtl8192_usb_probe(struct usb_interface *intf, const struct usb_device_id *id); static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf); @@ -5739,7 +5739,7 @@ static const struct net_device_ops rtl8192_netdev_ops = { ---------------------------- USB_STUFF--------------------------- *****************************************************************************/ -static int __devinit rtl8192_usb_probe(struct usb_interface *intf, +static int rtl8192_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { // unsigned long ioaddr = 0; -- cgit v1.2.3 From c506fff1ff06cca59a2c5dfef6fad3357eb0908e Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:22:05 -0500 Subject: staging: rtl8192e: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 3d636c34574..7f0f802c5d5 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -91,7 +91,7 @@ static struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = { MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl); -static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, +static int rtl8192_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev); @@ -2846,7 +2846,7 @@ static const struct net_device_ops rtl8192_netdev_ops = { .ndo_start_xmit = rtllib_xmit, }; -static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, +static int rtl8192_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { unsigned long ioaddr = 0; -- cgit v1.2.3 From 19fc6b57db3f1522259363d88b1908dc814e0aa5 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:22:08 -0500 Subject: staging: rtl8187se: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index ca097e45064..3527ff73332 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -74,7 +74,7 @@ module_param(hwwep, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support. Still broken and not available on all cards"); -static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, +static int rtl8180_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); static void __devexit rtl8180_pci_remove(struct pci_dev *pdev); @@ -3175,7 +3175,7 @@ static const struct net_device_ops rtl8180_netdev_ops = { .ndo_start_xmit = ieee80211_rtl_xmit, }; -static int __devinit rtl8180_pci_probe(struct pci_dev *pdev, +static int rtl8180_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { unsigned long ioaddr = 0; -- cgit v1.2.3 From 7df813d56f7364eac9a39f7bee2143b79a56203e Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:24:44 -0500 Subject: staging: rtl8187se: remove use of __devinitdata CONFIG_HOTPLUG is going away as an option so __devinitdata is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index 3527ff73332..a6520cfbc7e 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -44,7 +44,7 @@ #include "ieee80211/dot11d.h" -static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = { +static struct pci_device_id rtl8180_pci_id_tbl[] = { { .vendor = PCI_VENDOR_ID_REALTEK, .device = 0x8199, -- cgit v1.2.3 From 83f5789c1023983a564a64be671a95618ea7cc69 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:24:45 -0500 Subject: staging: rtl8192e: remove use of __devinitdata CONFIG_HOTPLUG is going away as an option so __devinitdata is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 7f0f802c5d5..95a154b930c 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -82,7 +82,7 @@ static struct rtl819x_ops rtl819xp_ops = { .RxCheckStuckHandler = rtl8192_HalRxCheckStuck, }; -static struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = { +static struct pci_device_id rtl8192_pci_id_tbl[] = { {RTL_PCI_DEVICE(0x10ec, 0x8192, rtl819xp_ops)}, {RTL_PCI_DEVICE(0x07aa, 0x0044, rtl819xp_ops)}, {RTL_PCI_DEVICE(0x07aa, 0x0047, rtl819xp_ops)}, -- cgit v1.2.3 From ea7e9f2a49aa570a08bfb211bf218c98abd6a4c2 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:26:44 -0500 Subject: staging: rtl8187se: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8187se/r8180_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index a6520cfbc7e..c46b59a8197 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -77,7 +77,7 @@ MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support. Still broken and not static int rtl8180_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); -static void __devexit rtl8180_pci_remove(struct pci_dev *pdev); +static void rtl8180_pci_remove(struct pci_dev *pdev); static void rtl8180_shutdown(struct pci_dev *pdev) { @@ -3288,7 +3288,7 @@ fail_free: return ret; } -static void __devexit rtl8180_pci_remove(struct pci_dev *pdev) +static void rtl8180_pci_remove(struct pci_dev *pdev) { struct r8180_priv *priv; struct net_device *dev = pci_get_drvdata(pdev); -- cgit v1.2.3 From 1387b461af6a5802a79bbeaed048c732a05f3735 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:26:45 -0500 Subject: staging: rtl8192e: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/rtl8192e/rtl_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 95a154b930c..1a70f324552 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -93,7 +93,7 @@ MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl); static int rtl8192_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); -static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev); +static void rtl8192_pci_disconnect(struct pci_dev *pdev); static struct pci_driver rtl8192_pci_driver = { .name = DRV_NAME, /* Driver name */ @@ -2982,7 +2982,7 @@ err_pci_disable: return err; } -static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) +static void rtl8192_pci_disconnect(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct r8192_priv *priv ; -- cgit v1.2.3 From a4a557e3d44f509a807e80334f012b36ba6894c6 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:26:46 -0500 Subject: staging: rtl8192u: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 12572fa3a36..56367f23112 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -146,7 +146,7 @@ MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI"); static int rtl8192_usb_probe(struct usb_interface *intf, const struct usb_device_id *id); -static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf); +static void rtl8192_usb_disconnect(struct usb_interface *intf); static struct usb_driver rtl8192_usb_driver = { @@ -5826,7 +5826,7 @@ void rtl8192_cancel_deferred_work(struct r8192_priv* priv) } -static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf) +static void rtl8192_usb_disconnect(struct usb_interface *intf) { struct net_device *dev = usb_get_intfdata(intf); -- cgit v1.2.3 From a547e5e0d8b85ccc640756eb40b3dd6b33796cf8 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sat, 17 Nov 2012 16:43:25 +0900 Subject: staging: dgrp: Fix typo in dgrp driver Correct spelling typo in staging/dgrp driver Signed-off-by: Masanari Iida Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgrp/dgrp_net_ops.c | 6 +++--- drivers/staging/dgrp/dgrp_tty.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index 0788357fd3c..8185a57d31c 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c @@ -2495,7 +2495,7 @@ data: /* * Fabricate and insert a data packet header to - * preceed the remaining data when it comes in. + * preced the remaining data when it comes in. */ if (remain < plen) { @@ -2664,7 +2664,7 @@ data: } /* - * Handle delayed response arrival preceeding + * Handle delayed response arrival preceding * the open response we are waiting for. */ @@ -3502,7 +3502,7 @@ void dgrp_poll_handler(unsigned long arg) /* * Decrement statistics. These are only for use with * KME, so don't worry that the operations are done - * unlocked, and so the results are occassionally wrong. + * unlocked, and so the results are occasionally wrong. */ nd->nd_read_count -= (nd->nd_read_count + diff --git a/drivers/staging/dgrp/dgrp_tty.c b/drivers/staging/dgrp/dgrp_tty.c index 0db4c0514f6..e3fa6eac53c 100644 --- a/drivers/staging/dgrp/dgrp_tty.c +++ b/drivers/staging/dgrp/dgrp_tty.c @@ -432,7 +432,7 @@ static void drp_param(struct ch_struct *ch) /* * From the POSIX.1 spec (7.1.2.6): "If {_POSIX_VDISABLE} * is defined for the terminal device file, and the value - * of one of the changable special control characters (see + * of one of the changeable special control characters (see * 7.1.1.9) is {_POSIX_VDISABLE}, that function shall be * disabled, that is, no input data shall be recognized as * the disabled special character." @@ -2699,7 +2699,7 @@ static int dgrp_tty_ioctl(struct tty_struct *tty, unsigned int cmd, - looking at the tty_ioctl code, these command all call our tty_set_termios at the driver's end, when a TCSETA* is sent, it is expecting the tty to have a termio structure, - NOT a termios stucture. These two structures differ in size + NOT a termios structure. These two structures differ in size and the tty_ioctl code does a conversion before processing them both. - we should treat the TCSETAW TCSETAF ioctls the same, and let the tty_ioctl code do the conversion stuff. @@ -2996,7 +2996,7 @@ static void dgrp_tty_start(struct tty_struct *tty) } /* - * Stop the reciever + * Stop the receiver */ static void dgrp_tty_input_stop(struct tty_struct *tty) { -- cgit v1.2.3 From 876ab79055019e248508cfd0dee7caa3c0c831ed Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Wed, 21 Nov 2012 23:12:12 +0100 Subject: ACPI / PM: Add Sony Vaio VPCEB1S1E to nonvs blacklist. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sony Vaio VPCEB1S1E does not resume correctly without acpi_sleep=nonvs, so add it to the ACPI sleep blacklist. References: https://bugzilla.kernel.org/show_bug.cgi?id=48781 Reported-by: Sébastien Wilmet Cc: Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sleep.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 8640782944c..1463c56092c 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -534,6 +534,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { }, { .callback = init_nvs_nosave, + .ident = "Sony Vaio VPCEB1S1E", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1S1E"), + }, + }, + { + .callback = init_nvs_nosave, .ident = "Sony Vaio VGN-FW520F", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), -- cgit v1.2.3 From b59bc2fbb4bb67e486c40cdb6a306c06acbaec06 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 21 Nov 2012 23:13:09 +0100 Subject: ACPI: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Rafael J. Wysocki --- drivers/acpi/apei/ghes.c | 2 +- drivers/acpi/hed.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 1599566ed1f..da93c003e95 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -994,7 +994,7 @@ err: return rc; } -static int __devexit ghes_remove(struct platform_device *ghes_dev) +static int ghes_remove(struct platform_device *ghes_dev) { struct ghes *ghes; struct acpi_hest_generic *generic; diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c index 20a0f2c3ca3..b514e81e8cf 100644 --- a/drivers/acpi/hed.c +++ b/drivers/acpi/hed.c @@ -70,7 +70,7 @@ static int __devinit acpi_hed_add(struct acpi_device *device) return 0; } -static int __devexit acpi_hed_remove(struct acpi_device *device, int type) +static int acpi_hed_remove(struct acpi_device *device, int type) { hed_handle = NULL; return 0; -- cgit v1.2.3 From 971b5e56537bf59d56086bd2472bffa8414555d3 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 20 Nov 2012 11:08:56 +0000 Subject: staging: comedi: me_daq: remove broken workaround for PLX bug The PLX PCI 9050 interface chip has a bug where its local configuration registers accessible through PCI BAR 0 and/or PCI BAR 1 (depending on settings loaded from a serial EEPROM or local bus processor) are unreadable (always read 0 instead of the true register values) if the base address starts on an odd multiple of 0x80 (i.e. has bit 7 set to 1). The "me_daq" driver attempts to work around this by writing to the PCI config space to swap the addresses assigned to PCI BAR 0 and PCI BAR 5 (which has been initially configured by serial EEPROM load as a spare region of the same length as the PCI BAR 0 region). (If the PCI BAR 5 region is absent, it attempts to reduce the PCI BAR 0 address by 0x80, which is likely to cause havoc for some other device, but that case shouldn't be reachable in practice.) The workaround in the driver is ineffective because it has already ioremapped the memory from `pci_resource_start(pcidev, 0)` *before* it does the workaround, so after swapping PCI BAR 0 and PCI BAR 5, this memory will end up accessing whatever onboard registers PCI BAR 5 was linked to instead of the local configuration registers. It also leaves the addresses in the physical PCI BAR registers set differently to the resource start addresses recorded in the `struct pci_dev`. The workaround could be fixed by ioremapping `pci_resource_start(pcidev, 5)` if the PCI BAR addresses were physically swapped (and the fallback workaround of subtracting 0x80 from the base address should really be removed altogether). However, it's not really worth it. This sort of thing should be worked around in "drivers/pci/quirks.c" by ensuring that PCI BAR 0 and/or PCI BAR 1 do not end up on an odd multiple of 0x80 bytes. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/me_daq.c | 46 --------------------------------- 1 file changed, 46 deletions(-) diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index b1fd74c3a61..22cf0f1e547 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -486,48 +486,6 @@ static int me_reset(struct comedi_device *dev) return 0; } -static int me_plx_bug_check(struct comedi_device *dev, - struct pci_dev *pcidev) -{ - resource_size_t plx_regbase_tmp = pci_resource_start(pcidev, 0); - resource_size_t swap_regbase_tmp = pci_resource_start(pcidev, 5); - resource_size_t regbase_tmp; - int ret; - - if (!swap_regbase_tmp) - dev_err(dev->class_dev, "Swap not present\n"); - - if (plx_regbase_tmp & 0x0080) { - dev_err(dev->class_dev, "PLX-Bug detected\n"); - - if (swap_regbase_tmp) { - regbase_tmp = plx_regbase_tmp; - plx_regbase_tmp = swap_regbase_tmp; - swap_regbase_tmp = regbase_tmp; - - ret = pci_write_config_dword(pcidev, - PCI_BASE_ADDRESS_0, - plx_regbase_tmp); - if (ret != PCIBIOS_SUCCESSFUL) - return -EIO; - - ret = pci_write_config_dword(pcidev, - PCI_BASE_ADDRESS_5, - swap_regbase_tmp); - if (ret != PCIBIOS_SUCCESSFUL) - return -EIO; - } else { - plx_regbase_tmp -= 0x80; - ret = pci_write_config_dword(pcidev, - PCI_BASE_ADDRESS_0, - plx_regbase_tmp); - if (ret != PCIBIOS_SUCCESSFUL) - return -EIO; - } - } - return 0; -} - static const void *me_find_boardinfo(struct comedi_device *dev, struct pci_dev *pcidev) { @@ -572,10 +530,6 @@ static int __devinit me_auto_attach(struct comedi_device *dev, if (!dev_private->plx_regbase) return -ENOMEM; - ret = me_plx_bug_check(dev, pcidev); - if (ret) - return ret; - dev_private->me_regbase = ioremap(pci_resource_start(pcidev, 2), pci_resource_len(pcidev, 2)); if (!dev_private->me_regbase) -- cgit v1.2.3 From ef5b7c69b7a1b8b8744a6168b6ff02900f81b6ca Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 22 Nov 2012 09:13:36 +1100 Subject: md/raid5: move resolving of reconstruct_state earlier in stripe_handle. The chunk of code in stripe_handle which responds to a *_result value in reconstruct_state is really the completion of some processing that happened outside of handle_stripe (possibly asynchronously) and so should be one of the first things done in handle_stripe(). After the next patch it will be important that it happens before handle_stripe_clean_event(), as that will clear some dev->flags bit that this code tests. Signed-off-by: NeilBrown --- drivers/md/raid5.c | 68 +++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index baea94f0670..0fb988556ee 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3490,40 +3490,6 @@ static void handle_stripe(struct stripe_head *sh) handle_failed_sync(conf, sh, &s); } - /* - * might be able to return some write requests if the parity blocks - * are safe, or on a failed drive - */ - pdev = &sh->dev[sh->pd_idx]; - s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) - || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); - qdev = &sh->dev[sh->qd_idx]; - s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) - || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) - || conf->level < 6; - - if (s.written && - (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) - && !test_bit(R5_LOCKED, &pdev->flags) - && (test_bit(R5_UPTODATE, &pdev->flags) || - test_bit(R5_Discard, &pdev->flags))))) && - (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) - && !test_bit(R5_LOCKED, &qdev->flags) - && (test_bit(R5_UPTODATE, &qdev->flags) || - test_bit(R5_Discard, &qdev->flags)))))) - handle_stripe_clean_event(conf, sh, disks, &s.return_bi); - - /* Now we might consider reading some blocks, either to check/generate - * parity, or to satisfy requests - * or to load a block that is being partially written. - */ - if (s.to_read || s.non_overwrite - || (conf->level == 6 && s.to_write && s.failed) - || (s.syncing && (s.uptodate + s.compute < disks)) - || s.replacing - || s.expanding) - handle_stripe_fill(sh, &s, disks); - /* Now we check to see if any write operations have recently * completed */ @@ -3561,6 +3527,40 @@ static void handle_stripe(struct stripe_head *sh) s.dec_preread_active = 1; } + /* + * might be able to return some write requests if the parity blocks + * are safe, or on a failed drive + */ + pdev = &sh->dev[sh->pd_idx]; + s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx) + || (s.failed >= 2 && s.failed_num[1] == sh->pd_idx); + qdev = &sh->dev[sh->qd_idx]; + s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx) + || (s.failed >= 2 && s.failed_num[1] == sh->qd_idx) + || conf->level < 6; + + if (s.written && + (s.p_failed || ((test_bit(R5_Insync, &pdev->flags) + && !test_bit(R5_LOCKED, &pdev->flags) + && (test_bit(R5_UPTODATE, &pdev->flags) || + test_bit(R5_Discard, &pdev->flags))))) && + (s.q_failed || ((test_bit(R5_Insync, &qdev->flags) + && !test_bit(R5_LOCKED, &qdev->flags) + && (test_bit(R5_UPTODATE, &qdev->flags) || + test_bit(R5_Discard, &qdev->flags)))))) + handle_stripe_clean_event(conf, sh, disks, &s.return_bi); + + /* Now we might consider reading some blocks, either to check/generate + * parity, or to satisfy requests + * or to load a block that is being partially written. + */ + if (s.to_read || s.non_overwrite + || (conf->level == 6 && s.to_write && s.failed) + || (s.syncing && (s.uptodate + s.compute < disks)) + || s.replacing + || s.expanding) + handle_stripe_fill(sh, &s, disks); + /* Now to consider new write requests and what else, if anything * should be read. We do not handle new writes when: * 1/ A 'write' operation (copy+xor) is already in flight. -- cgit v1.2.3 From ca64cae96037de16e4af92678814f5d4bf0c1c65 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 21 Nov 2012 16:33:40 +1100 Subject: md/raid5: Make sure we clear R5_Discard when discard is finished. commit 9e44476851e91c86c98eb92b9bc27fb801f89072 MD: raid5 avoid unnecessary zero page for trim change raid5 to clear R5_Discard when the complete request is handled rather than when submitting the per-device discard request. However it did not clear R5_Discard for the parity device. This means that if the stripe_head was reused before it expired from the cache, the setting would be wrong and a hang would result. Also if the R5_Uptodate bit happens to be set, R5_Discard again won't be cleared. But R5_Uptodate really should be clear at this point. So make sure R5_Discard is cleared in all cases, and clear R5_Uptodate when a 'discard' completes. Signed-off-by: NeilBrown --- drivers/md/raid5.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 0fb988556ee..a4502686e7a 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2774,10 +2774,12 @@ static void handle_stripe_clean_event(struct r5conf *conf, dev = &sh->dev[i]; if (!test_bit(R5_LOCKED, &dev->flags) && (test_bit(R5_UPTODATE, &dev->flags) || - test_and_clear_bit(R5_Discard, &dev->flags))) { + test_bit(R5_Discard, &dev->flags))) { /* We can return any write requests */ struct bio *wbi, *wbi2; pr_debug("Return write for disc %d\n", i); + if (test_and_clear_bit(R5_Discard, &dev->flags)) + clear_bit(R5_UPTODATE, &dev->flags); wbi = dev->written; dev->written = NULL; while (wbi && wbi->bi_sector < @@ -2795,7 +2797,8 @@ static void handle_stripe_clean_event(struct r5conf *conf, !test_bit(STRIPE_DEGRADED, &sh->state), 0); } - } + } else if (test_bit(R5_Discard, &sh->dev[i].flags)) + clear_bit(R5_Discard, &sh->dev[i].flags); if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) if (atomic_dec_and_test(&conf->pending_full_writes)) -- cgit v1.2.3 From a471eace7baa40cdf16d3f26b2f78ddce613ca8f Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:21:37 -0500 Subject: staging: comedi: remove use of __devexit_p CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255_pci.c | 2 +- drivers/staging/comedi/drivers/addi_apci_035.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1500.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1516.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1564.c | 2 +- drivers/staging/comedi/drivers/addi_apci_16xx.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1710.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3501.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 2 +- drivers/staging/comedi/drivers/adl_pci6208.c | 2 +- drivers/staging/comedi/drivers/adl_pci7x3x.c | 2 +- drivers/staging/comedi/drivers/adl_pci8164.c | 2 +- drivers/staging/comedi/drivers/adl_pci9111.c | 2 +- drivers/staging/comedi/drivers/adl_pci9118.c | 2 +- drivers/staging/comedi/drivers/adv_pci1710.c | 2 +- drivers/staging/comedi/drivers/adv_pci1723.c | 2 +- drivers/staging/comedi/drivers/adv_pci_dio.c | 2 +- drivers/staging/comedi/drivers/amplc_dio200.c | 2 +- drivers/staging/comedi/drivers/amplc_pc236.c | 2 +- drivers/staging/comedi/drivers/amplc_pc263.c | 2 +- drivers/staging/comedi/drivers/amplc_pci224.c | 2 +- drivers/staging/comedi/drivers/amplc_pci230.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas64.c | 2 +- drivers/staging/comedi/drivers/cb_pcidda.c | 2 +- drivers/staging/comedi/drivers/cb_pcimdas.c | 2 +- drivers/staging/comedi/drivers/cb_pcimdda.c | 2 +- drivers/staging/comedi/drivers/contec_pci_dio.c | 2 +- drivers/staging/comedi/drivers/daqboard2000.c | 2 +- drivers/staging/comedi/drivers/das08.c | 2 +- drivers/staging/comedi/drivers/dt3000.c | 2 +- drivers/staging/comedi/drivers/dyna_pci10xx.c | 2 +- drivers/staging/comedi/drivers/gsc_hpdi.c | 2 +- drivers/staging/comedi/drivers/icp_multi.c | 2 +- drivers/staging/comedi/drivers/jr3_pci.c | 2 +- drivers/staging/comedi/drivers/ke_counter.c | 2 +- drivers/staging/comedi/drivers/me4000.c | 2 +- drivers/staging/comedi/drivers/me_daq.c | 2 +- drivers/staging/comedi/drivers/ni_6527.c | 2 +- drivers/staging/comedi/drivers/ni_65xx.c | 2 +- drivers/staging/comedi/drivers/ni_660x.c | 2 +- drivers/staging/comedi/drivers/ni_670x.c | 2 +- drivers/staging/comedi/drivers/ni_labpc.c | 2 +- drivers/staging/comedi/drivers/ni_pcidio.c | 2 +- drivers/staging/comedi/drivers/ni_pcimio.c | 2 +- drivers/staging/comedi/drivers/rtd520.c | 2 +- drivers/staging/comedi/drivers/s626.c | 2 +- drivers/staging/comedi/drivers/skel.c | 2 +- 53 files changed, 53 insertions(+), 53 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 71ad619d9c6..c897d39f6b2 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -342,7 +342,7 @@ static struct pci_driver pci_8255_pci_driver = { .name = "8255_pci", .id_table = pci_8255_pci_table, .probe = pci_8255_pci_probe, - .remove = __devexit_p(pci_8255_pci_remove), + .remove = pci_8255_pci_remove, }; module_comedi_pci_driver(pci_8255_driver, pci_8255_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 3055fc2e0a7..489d151fc03 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -68,7 +68,7 @@ static struct pci_driver apci035_pci_driver = { .name = "addi_apci_035", .id_table = apci035_pci_table, .probe = apci035_pci_probe, - .remove = __devexit_p(apci035_pci_remove), + .remove = apci035_pci_remove, }; module_comedi_pci_driver(apci035_driver, apci035_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 0f47113ee0b..9c2e7f745d6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -390,7 +390,7 @@ static struct pci_driver apci1032_pci_driver = { .name = "addi_apci_1032", .id_table = apci1032_pci_table, .probe = apci1032_pci_probe, - .remove = __devexit_p(apci1032_pci_remove), + .remove = apci1032_pci_remove, }; module_comedi_pci_driver(apci1032_driver, apci1032_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 8528b27f77e..67f145d9281 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -68,7 +68,7 @@ static struct pci_driver apci1500_pci_driver = { .name = "addi_apci_1500", .id_table = apci1500_pci_table, .probe = apci1500_pci_probe, - .remove = __devexit_p(apci1500_pci_remove), + .remove = apci1500_pci_remove, }; module_comedi_pci_driver(apci1500_driver, apci1500_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index e6aa5226014..086445f558f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -340,7 +340,7 @@ static struct pci_driver apci1516_pci_driver = { .name = "addi_apci_1516", .id_table = apci1516_pci_table, .probe = apci1516_pci_probe, - .remove = __devexit_p(apci1516_pci_remove), + .remove = apci1516_pci_remove, }; module_comedi_pci_driver(apci1516_driver, apci1516_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 926fa088392..1d51233ca78 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -65,7 +65,7 @@ static struct pci_driver apci1564_pci_driver = { .name = "addi_apci_1564", .id_table = apci1564_pci_table, .probe = apci1564_pci_probe, - .remove = __devexit_p(apci1564_pci_remove), + .remove = apci1564_pci_remove, }; module_comedi_pci_driver(apci1564_driver, apci1564_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 170d576761a..07d7c9a5d6d 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -68,7 +68,7 @@ static struct pci_driver apci16xx_pci_driver = { .name = "addi_apci_16xx", .id_table = apci16xx_pci_table, .probe = apci16xx_pci_probe, - .remove = __devexit_p(apci16xx_pci_remove), + .remove = apci16xx_pci_remove, }; module_comedi_pci_driver(apci16xx_driver, apci16xx_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 485f8214516..5d263364dbc 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -143,7 +143,7 @@ static struct pci_driver apci1710_pci_driver = { .name = "addi_apci_1710", .id_table = apci1710_pci_table, .probe = apci1710_pci_probe, - .remove = __devexit_p(apci1710_pci_remove), + .remove = apci1710_pci_remove, }; module_comedi_pci_driver(apci1710_driver, apci1710_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index 7758de3146e..a80bf018b76 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -62,7 +62,7 @@ static struct pci_driver apci2032_pci_driver = { .name = "addi_apci_2032", .id_table = apci2032_pci_table, .probe = apci2032_pci_probe, - .remove = __devexit_p(apci2032_pci_remove), + .remove = apci2032_pci_remove, }; module_comedi_pci_driver(apci2032_driver, apci2032_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 3041009915f..9271cfe1b23 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -60,7 +60,7 @@ static struct pci_driver apci2200_pci_driver = { .name = "addi_apci_2200", .id_table = apci2200_pci_table, .probe = apci2200_pci_probe, - .remove = __devexit_p(apci2200_pci_remove), + .remove = apci2200_pci_remove, }; module_comedi_pci_driver(apci2200_driver, apci2200_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 34aab504d35..77a9fe933f0 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -267,7 +267,7 @@ static struct pci_driver apci3120_pci_driver = { .name = "addi_apci_3120", .id_table = apci3120_pci_table, .probe = apci3120_pci_probe, - .remove = __devexit_p(apci3120_pci_remove), + .remove = apci3120_pci_remove, }; module_comedi_pci_driver(apci3120_driver, apci3120_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index e95141dabbd..59120cf88db 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -115,6 +115,6 @@ static struct pci_driver apci3200_pci_driver = { .name = "addi_apci_3200", .id_table = apci3200_pci_table, .probe = apci3200_pci_probe, - .remove = __devexit_p(apci3200_pci_remove), + .remove = apci3200_pci_remove, }; module_comedi_pci_driver(apci3200_driver, apci3200_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 4c60167be2f..530d352e4b6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -66,7 +66,7 @@ static struct pci_driver apci3501_pci_driver = { .name = "addi_apci_3501", .id_table = apci3501_pci_table, .probe = apci3501_pci_probe, - .remove = __devexit_p(apci3501_pci_remove), + .remove = apci3501_pci_remove, }; module_comedi_pci_driver(apci3501_driver, apci3501_pci_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index cc3938124cd..4a3e346c359 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -790,7 +790,7 @@ static struct pci_driver apci3xxx_pci_driver = { .name = "addi_apci_3xxx", .id_table = apci3xxx_pci_table, .probe = apci3xxx_pci_probe, - .remove = __devexit_p(apci3xxx_pci_remove), + .remove = apci3xxx_pci_remove, }; module_comedi_pci_driver(apci3xxx_driver, apci3xxx_pci_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 73fd9750327..67d7ba1e36b 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -286,7 +286,7 @@ static struct pci_driver adl_pci6208_pci_driver = { .name = "adl_pci6208", .id_table = adl_pci6208_pci_table, .probe = adl_pci6208_pci_probe, - .remove = __devexit_p(adl_pci6208_pci_remove), + .remove = adl_pci6208_pci_remove, }; module_comedi_pci_driver(adl_pci6208_driver, adl_pci6208_pci_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index be01b202197..9ac356b6201 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -322,7 +322,7 @@ static struct pci_driver adl_pci7x3x_pci_driver = { .name = "adl_pci7x3x", .id_table = adl_pci7x3x_pci_table, .probe = adl_pci7x3x_pci_probe, - .remove = __devexit_p(adl_pci7x3x_pci_remove), + .remove = adl_pci7x3x_pci_remove, }; module_comedi_pci_driver(adl_pci7x3x_driver, adl_pci7x3x_pci_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index 41993ec436f..d5eb68b4f00 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -313,7 +313,7 @@ static struct pci_driver adl_pci8164_pci_driver = { .name = "adl_pci8164", .id_table = adl_pci8164_pci_table, .probe = adl_pci8164_pci_probe, - .remove = __devexit_p(adl_pci8164_pci_remove), + .remove = adl_pci8164_pci_remove, }; module_comedi_pci_driver(adl_pci8164_driver, adl_pci8164_pci_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 570ccc676cc..1fac2f71b2a 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -979,7 +979,7 @@ static struct pci_driver adl_pci9111_pci_driver = { .name = "adl_pci9111", .id_table = pci9111_pci_table, .probe = pci9111_pci_probe, - .remove = __devexit_p(pci9111_pci_remove), + .remove = pci9111_pci_remove, }; module_comedi_pci_driver(adl_pci9111_driver, adl_pci9111_pci_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index a6b21cb61da..c7d0f33e143 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -2240,7 +2240,7 @@ static struct pci_driver adl_pci9118_pci_driver = { .name = "adl_pci9118", .id_table = adl_pci9118_pci_table, .probe = adl_pci9118_pci_probe, - .remove = __devexit_p(adl_pci9118_pci_remove), + .remove = adl_pci9118_pci_remove, }; module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver); diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index bdfa9051f4f..59c1d843a08 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1421,7 +1421,7 @@ static struct pci_driver adv_pci1710_pci_driver = { .name = "adv_pci1710", .id_table = adv_pci1710_pci_table, .probe = adv_pci1710_pci_probe, - .remove = __devexit_p(adv_pci1710_pci_remove), + .remove = adv_pci1710_pci_remove, }; module_comedi_pci_driver(adv_pci1710_driver, adv_pci1710_pci_driver); diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 490e4347f11..70e017bfa06 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -342,7 +342,7 @@ static struct pci_driver adv_pci1723_pci_driver = { .name = "adv_pci1723", .id_table = adv_pci1723_pci_table, .probe = adv_pci1723_pci_probe, - .remove = __devexit_p(adv_pci1723_pci_remove), + .remove = adv_pci1723_pci_remove, }; module_comedi_pci_driver(adv_pci1723_driver, adv_pci1723_pci_driver); diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index bb69c0d71ce..9e75006c9e7 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1234,7 +1234,7 @@ static struct pci_driver adv_pci_dio_pci_driver = { .name = "adv_pci_dio", .id_table = adv_pci_dio_pci_table, .probe = adv_pci_dio_pci_probe, - .remove = __devexit_p(adv_pci_dio_pci_remove), + .remove = adv_pci_dio_pci_remove, }; module_comedi_pci_driver(adv_pci_dio_driver, adv_pci_dio_pci_driver); diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 57c618b4e98..909acf89f4f 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -2088,7 +2088,7 @@ static struct pci_driver amplc_dio200_pci_driver = { .name = DIO200_DRIVER_NAME, .id_table = dio200_pci_table, .probe = &lc_dio200_pci_probe, - .remove = __devexit_p(&lc_dio200_pci_remove) + .remove = &lc_dio200_pci_remove }; module_comedi_pci_driver(amplc_dio200_driver, amplc_dio200_pci_driver); #else diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index d460b243f37..09e096c6b6b 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -623,7 +623,7 @@ static struct pci_driver amplc_pc236_pci_driver = { .name = PC236_DRIVER_NAME, .id_table = pc236_pci_table, .probe = &lc_pc236_pci_probe, - .remove = __devexit_p(&lc_pc236_pci_remove) + .remove = &lc_pc236_pci_remove }; module_comedi_pci_driver(amplc_pc236_driver, amplc_pc236_pci_driver); diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index dc9504914e2..c041716efb0 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -381,7 +381,7 @@ static struct pci_driver amplc_pc263_pci_driver = { .name = PC263_DRIVER_NAME, .id_table = pc263_pci_table, .probe = &lc_pc263_pci_probe, - .remove = __devexit_p(&lc_pc263_pci_remove) + .remove = &lc_pc263_pci_remove }; module_comedi_pci_driver(amplc_pc263_driver, amplc_pc263_pci_driver); #else diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 0b901d5d269..1713a666075 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1528,7 +1528,7 @@ static struct pci_driver amplc_pci224_pci_driver = { .name = "amplc_pci224", .id_table = amplc_pci224_pci_table, .probe = amplc_pci224_pci_probe, - .remove = __devexit_p(amplc_pci224_pci_remove), + .remove = amplc_pci224_pci_remove, }; module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver); diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 7cc48ec1d5f..d0ea0699252 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2879,7 +2879,7 @@ static struct pci_driver amplc_pci230_pci_driver = { .name = "amplc_pci230", .id_table = amplc_pci230_pci_table, .probe = amplc_pci230_pci_probe, - .remove = __devexit_p(amplc_pci230_pci_remove) + .remove = amplc_pci230_pci_remove }; module_comedi_pci_driver(amplc_pci230_driver, amplc_pci230_pci_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 9c45e85ec30..857a8d63c9f 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1654,7 +1654,7 @@ static struct pci_driver cb_pcidas_pci_driver = { .name = "cb_pcidas", .id_table = cb_pcidas_pci_table, .probe = cb_pcidas_pci_probe, - .remove = __devexit_p(cb_pcidas_pci_remove) + .remove = cb_pcidas_pci_remove }; module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 17813aa6bb2..ea2e1e78066 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -4253,7 +4253,7 @@ static struct pci_driver cb_pcidas64_pci_driver = { .name = "cb_pcidas64", .id_table = cb_pcidas64_pci_table, .probe = cb_pcidas64_pci_probe, - .remove = __devexit_p(cb_pcidas64_pci_remove), + .remove = cb_pcidas64_pci_remove, }; module_comedi_pci_driver(cb_pcidas64_driver, cb_pcidas64_pci_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 083bd8636ef..f1a603b0023 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -458,7 +458,7 @@ static struct pci_driver cb_pcidda_pci_driver = { .name = "cb_pcidda", .id_table = cb_pcidda_pci_table, .probe = cb_pcidda_pci_probe, - .remove = __devexit_p(cb_pcidda_pci_remove), + .remove = cb_pcidda_pci_remove, }; module_comedi_pci_driver(cb_pcidda_driver, cb_pcidda_pci_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index f75873740bc..f171cf9ffd1 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -314,7 +314,7 @@ static struct pci_driver cb_pcimdas_pci_driver = { .name = "cb_pcimdas", .id_table = cb_pcimdas_pci_table, .probe = cb_pcimdas_pci_probe, - .remove = __devexit_p(cb_pcimdas_pci_remove), + .remove = cb_pcimdas_pci_remove, }; module_comedi_pci_driver(cb_pcimdas_driver, cb_pcimdas_pci_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 89c70385330..78e2ba3f1f2 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -237,7 +237,7 @@ static struct pci_driver cb_pcimdda_driver_pci_driver = { .name = "cb_pcimdda", .id_table = cb_pcimdda_pci_table, .probe = cb_pcimdda_pci_probe, - .remove = __devexit_p(cb_pcimdda_pci_remove), + .remove = cb_pcimdda_pci_remove, }; module_comedi_pci_driver(cb_pcimdda_driver, cb_pcimdda_driver_pci_driver); diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index c06b7b682f7..3c0ca852d01 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -145,7 +145,7 @@ static struct pci_driver contec_pci_dio_pci_driver = { .name = "contec_pci_dio", .id_table = contec_pci_dio_pci_table, .probe = contec_pci_dio_pci_probe, - .remove = __devexit_p(contec_pci_dio_pci_remove), + .remove = contec_pci_dio_pci_remove, }; module_comedi_pci_driver(contec_pci_dio_driver, contec_pci_dio_pci_driver); diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index c5aa6b8d8f7..c0fd3b15815 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -814,7 +814,7 @@ static struct pci_driver daqboard2000_pci_driver = { .name = "daqboard2000", .id_table = daqboard2000_pci_table, .probe = daqboard2000_pci_probe, - .remove = __devexit_p(daqboard2000_pci_remove), + .remove = daqboard2000_pci_remove, }; module_comedi_pci_driver(daqboard2000_driver, daqboard2000_pci_driver); diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index cc654542a6d..88f78a0efb2 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -900,7 +900,7 @@ static struct pci_driver das08_pci_driver = { .id_table = das08_pci_table, .name = DRV_NAME, .probe = &das08_pci_probe, - .remove = __devexit_p(&das08_pci_remove) + .remove = &das08_pci_remove }; #endif /* DO_PCI */ diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index f6d4ebd6cb5..b61004b422a 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -877,7 +877,7 @@ static struct pci_driver dt3000_pci_driver = { .name = "dt3000", .id_table = dt3000_pci_table, .probe = dt3000_pci_probe, - .remove = __devexit_p(dt3000_pci_remove), + .remove = dt3000_pci_remove, }; module_comedi_pci_driver(dt3000_driver, dt3000_pci_driver); diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 363b09d217e..8736ef97f3b 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -291,7 +291,7 @@ static struct pci_driver dyna_pci10xx_pci_driver = { .name = "dyna_pci10xx", .id_table = dyna_pci10xx_pci_table, .probe = dyna_pci10xx_pci_probe, - .remove = __devexit_p(dyna_pci10xx_pci_remove), + .remove = dyna_pci10xx_pci_remove, }; module_comedi_pci_driver(dyna_pci10xx_driver, dyna_pci10xx_pci_driver); diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index eb3cb80ff2a..98926469e69 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -962,7 +962,7 @@ static struct pci_driver gsc_hpdi_pci_driver = { .name = "gsc_hpdi", .id_table = gsc_hpdi_pci_table, .probe = gsc_hpdi_pci_probe, - .remove = __devexit_p(gsc_hpdi_pci_remove) + .remove = gsc_hpdi_pci_remove }; module_comedi_pci_driver(gsc_hpdi_driver, gsc_hpdi_pci_driver); diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index e7bb6031e54..ee9b4082588 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -638,7 +638,7 @@ static struct pci_driver icp_multi_pci_driver = { .name = "icp_multi", .id_table = icp_multi_pci_table, .probe = icp_multi_pci_probe, - .remove = __devexit_p(icp_multi_pci_remove), + .remove = icp_multi_pci_remove, }; module_comedi_pci_driver(icp_multi_driver, icp_multi_pci_driver); diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 65d65fe23d6..ad24b7310ea 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -863,7 +863,7 @@ static struct pci_driver jr3_pci_pci_driver = { .name = "jr3_pci", .id_table = jr3_pci_pci_table, .probe = jr3_pci_pci_probe, - .remove = __devexit_p(jr3_pci_pci_remove), + .remove = jr3_pci_pci_remove, }; module_comedi_pci_driver(jr3_pci_driver, jr3_pci_pci_driver); diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index a59a12b4f19..63c3a1af7e5 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -167,7 +167,7 @@ static struct pci_driver ke_counter_pci_driver = { .name = "ke_counter", .id_table = ke_counter_pci_table, .probe = ke_counter_pci_probe, - .remove = __devexit_p(ke_counter_pci_remove), + .remove = ke_counter_pci_remove, }; module_comedi_pci_driver(ke_counter_driver, ke_counter_pci_driver); diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index a489a6548e7..07594c579b1 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1761,7 +1761,7 @@ static struct pci_driver me4000_pci_driver = { .name = "me4000", .id_table = me4000_pci_table, .probe = me4000_pci_probe, - .remove = __devexit_p(me4000_pci_remove), + .remove = me4000_pci_remove, }; module_comedi_pci_driver(me4000_driver, me4000_pci_driver); diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 22cf0f1e547..b6482dd2a82 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -635,7 +635,7 @@ static struct pci_driver me_daq_pci_driver = { .name = "me_daq", .id_table = me_daq_pci_table, .probe = me_daq_pci_probe, - .remove = __devexit_p(me_daq_pci_remove), + .remove = me_daq_pci_remove, }; module_comedi_pci_driver(me_daq_driver, me_daq_pci_driver); diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 24102d1aa82..7ecebb75fe5 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -461,7 +461,7 @@ static struct pci_driver ni6527_pci_driver = { .name = DRIVER_NAME, .id_table = ni6527_pci_table, .probe = ni6527_pci_probe, - .remove = __devexit_p(ni6527_pci_remove) + .remove = ni6527_pci_remove }; module_comedi_pci_driver(ni6527_driver, ni6527_pci_driver); diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 8318081c89b..d2204c2cebe 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -797,7 +797,7 @@ static struct pci_driver ni_65xx_pci_driver = { .name = "ni_65xx", .id_table = ni_65xx_pci_table, .probe = ni_65xx_pci_probe, - .remove = __devexit_p(ni_65xx_pci_remove) + .remove = ni_65xx_pci_remove }; module_comedi_pci_driver(ni_65xx_driver, ni_65xx_pci_driver); diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index d1561c72e2d..aaf4fe771ee 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1345,7 +1345,7 @@ static struct pci_driver ni_660x_pci_driver = { .name = "ni_660x", .id_table = ni_660x_pci_table, .probe = ni_660x_pci_probe, - .remove = __devexit_p(ni_660x_pci_remove), + .remove = ni_660x_pci_remove, }; module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver); diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 7a72131b935..5080eca0b9e 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -325,7 +325,7 @@ static struct pci_driver ni_670x_pci_driver = { .name = "ni_670x", .id_table = ni_670x_pci_table, .probe = ni_670x_pci_probe, - .remove = __devexit_p(ni_670x_pci_remove), + .remove = ni_670x_pci_remove, }; module_comedi_pci_driver(ni_670x_driver, ni_670x_pci_driver); diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index b56039bea6a..b2e565bf3df 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -2125,7 +2125,7 @@ static struct pci_driver labpc_pci_driver = { .name = DRV_NAME, .id_table = labpc_pci_table, .probe = labpc_pci_probe, - .remove = __devexit_p(labpc_pci_remove) + .remove = labpc_pci_remove }; module_comedi_pci_driver(labpc_driver, labpc_pci_driver); #else diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 5d442b09c67..f4dd5df0d7e 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1241,7 +1241,7 @@ static struct pci_driver ni_pcidio_pci_driver = { .name = "ni_pcidio", .id_table = ni_pcidio_pci_table, .probe = ni_pcidio_pci_probe, - .remove = __devexit_p(ni_pcidio_pci_remove), + .remove = ni_pcidio_pci_remove, }; module_comedi_pci_driver(ni_pcidio_driver, ni_pcidio_pci_driver); diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 65e1896c077..597a2d3c4a6 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1858,7 +1858,7 @@ static struct pci_driver ni_pcimio_pci_driver = { .name = "ni_pcimio", .id_table = ni_pcimio_pci_table, .probe = ni_pcimio_pci_probe, - .remove = __devexit_p(ni_pcimio_pci_remove) + .remove = ni_pcimio_pci_remove }; module_comedi_pci_driver(ni_pcimio_driver, ni_pcimio_pci_driver); diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 5b31e60ffb5..83edc3e85e8 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1436,7 +1436,7 @@ static struct pci_driver rtd520_pci_driver = { .name = "rtd520", .id_table = rtd520_pci_table, .probe = rtd520_pci_probe, - .remove = __devexit_p(rtd520_pci_remove), + .remove = rtd520_pci_remove, }; module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver); diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index e32b54f4bfc..30686e2b8a7 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2857,7 +2857,7 @@ static struct pci_driver s626_pci_driver = { .name = "s626", .id_table = s626_pci_table, .probe = s626_pci_probe, - .remove = __devexit_p(s626_pci_remove), + .remove = s626_pci_remove, }; module_comedi_pci_driver(s626_driver, s626_pci_driver); diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index deb0bfaf0a3..98c1868ab03 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -719,7 +719,7 @@ static void __devexit skel_pci_remove(struct pci_dev *dev) static struct pci_driver skel_pci_driver = { .id_table = skel_pci_table, .probe = &skel_pci_probe, - .remove = __devexit_p(&skel_pci_remove) + .remove = &skel_pci_remove }; module_comedi_pci_driver(skel_driver, skel_pci_driver); #else -- cgit v1.2.3 From a690b7e535f2f97a3a05ee570715abeb60a8910f Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:21:58 -0500 Subject: staging: comedi: remove use of __devinit CONFIG_HOTPLUG is going away as an option so __devinit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255_pci.c | 4 ++-- drivers/staging/comedi/drivers/addi-data/addi_common.c | 2 +- drivers/staging/comedi/drivers/addi_apci_035.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1032.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_1500.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1516.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_1564.c | 2 +- drivers/staging/comedi/drivers/addi_apci_16xx.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1710.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_2032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3120.c | 4 ++-- drivers/staging/comedi/drivers/addi_apci_3200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3501.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 2 +- drivers/staging/comedi/drivers/adl_pci6208.c | 4 ++-- drivers/staging/comedi/drivers/adl_pci7x3x.c | 4 ++-- drivers/staging/comedi/drivers/adl_pci8164.c | 4 ++-- drivers/staging/comedi/drivers/adl_pci9111.c | 4 ++-- drivers/staging/comedi/drivers/adl_pci9118.c | 4 ++-- drivers/staging/comedi/drivers/adv_pci1710.c | 4 ++-- drivers/staging/comedi/drivers/adv_pci1723.c | 4 ++-- drivers/staging/comedi/drivers/adv_pci_dio.c | 4 ++-- drivers/staging/comedi/drivers/amplc_dio200.c | 4 ++-- drivers/staging/comedi/drivers/amplc_pc236.c | 4 ++-- drivers/staging/comedi/drivers/amplc_pc263.c | 4 ++-- drivers/staging/comedi/drivers/amplc_pci224.c | 4 ++-- drivers/staging/comedi/drivers/amplc_pci230.c | 4 ++-- drivers/staging/comedi/drivers/cb_pcidas.c | 4 ++-- drivers/staging/comedi/drivers/cb_pcidas64.c | 4 ++-- drivers/staging/comedi/drivers/cb_pcidda.c | 4 ++-- drivers/staging/comedi/drivers/cb_pcimdas.c | 4 ++-- drivers/staging/comedi/drivers/cb_pcimdda.c | 4 ++-- drivers/staging/comedi/drivers/contec_pci_dio.c | 4 ++-- drivers/staging/comedi/drivers/daqboard2000.c | 4 ++-- drivers/staging/comedi/drivers/das08.c | 4 ++-- drivers/staging/comedi/drivers/dt3000.c | 4 ++-- drivers/staging/comedi/drivers/dyna_pci10xx.c | 4 ++-- drivers/staging/comedi/drivers/gsc_hpdi.c | 4 ++-- drivers/staging/comedi/drivers/icp_multi.c | 4 ++-- drivers/staging/comedi/drivers/jr3_pci.c | 4 ++-- drivers/staging/comedi/drivers/ke_counter.c | 4 ++-- drivers/staging/comedi/drivers/me4000.c | 4 ++-- drivers/staging/comedi/drivers/me_daq.c | 4 ++-- drivers/staging/comedi/drivers/ni_6527.c | 4 ++-- drivers/staging/comedi/drivers/ni_65xx.c | 4 ++-- drivers/staging/comedi/drivers/ni_660x.c | 4 ++-- drivers/staging/comedi/drivers/ni_670x.c | 4 ++-- drivers/staging/comedi/drivers/ni_labpc.c | 4 ++-- drivers/staging/comedi/drivers/ni_pcidio.c | 4 ++-- drivers/staging/comedi/drivers/ni_pcimio.c | 4 ++-- drivers/staging/comedi/drivers/rtd520.c | 4 ++-- drivers/staging/comedi/drivers/s626.c | 4 ++-- drivers/staging/comedi/drivers/skel.c | 8 ++------ 54 files changed, 98 insertions(+), 102 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index c897d39f6b2..448f18d7560 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -213,7 +213,7 @@ static const void *pci_8255_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit pci_8255_auto_attach(struct comedi_device *dev, +static int pci_8255_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -308,7 +308,7 @@ static struct comedi_driver pci_8255_driver = { .detach = pci_8255_detach, }; -static int __devinit pci_8255_pci_probe(struct pci_dev *dev, +static int pci_8255_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &pci_8255_driver); diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 8c0fbf43a7e..90cc43263ae 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -93,7 +93,7 @@ static const void *addi_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit addi_auto_attach(struct comedi_device *dev, +static int addi_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 489d151fc03..8e5e5faae4f 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -47,7 +47,7 @@ static struct comedi_driver apci035_driver = { .offset = sizeof(struct addi_board), }; -static int __devinit apci035_pci_probe(struct pci_dev *dev, +static int apci035_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci035_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 9c2e7f745d6..15b660bc1a2 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -285,7 +285,7 @@ static int apci1032_di_insn_bits(struct comedi_device *dev, return insn->n; } -static int __devinit apci1032_auto_attach(struct comedi_device *dev, +static int apci1032_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -369,7 +369,7 @@ static struct comedi_driver apci1032_driver = { .detach = apci1032_detach, }; -static int __devinit apci1032_pci_probe(struct pci_dev *dev, +static int apci1032_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci1032_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 67f145d9281..80115ccb6c7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -47,7 +47,7 @@ static struct comedi_driver apci1500_driver = { .offset = sizeof(struct addi_board), }; -static int __devinit apci1500_pci_probe(struct pci_dev *dev, +static int apci1500_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci1500_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index 086445f558f..ac32e9fa98e 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -225,7 +225,7 @@ static const void *apci1516_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit apci1516_auto_attach(struct comedi_device *dev, +static int apci1516_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -317,7 +317,7 @@ static struct comedi_driver apci1516_driver = { .detach = apci1516_detach, }; -static int __devinit apci1516_pci_probe(struct pci_dev *dev, +static int apci1516_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci1516_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 1d51233ca78..d03579a1659 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -44,7 +44,7 @@ static struct comedi_driver apci1564_driver = { .offset = sizeof(struct addi_board), }; -static int __devinit apci1564_pci_probe(struct pci_dev *dev, +static int apci1564_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci1564_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 07d7c9a5d6d..05457875308 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -46,7 +46,7 @@ static struct comedi_driver apci16xx_driver = { .offset = sizeof(struct addi_board), }; -static int __devinit apci16xx_pci_probe(struct pci_dev *dev, +static int apci16xx_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci16xx_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 5d263364dbc..1c9ed4785d0 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -52,7 +52,7 @@ static const void *apci1710_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit apci1710_auto_attach(struct comedi_device *dev, +static int apci1710_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -122,7 +122,7 @@ static struct comedi_driver apci1710_driver = { .detach = apci1710_detach, }; -static int __devinit apci1710_pci_probe(struct pci_dev *dev, +static int apci1710_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci1710_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index a80bf018b76..f60720546e3 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -41,7 +41,7 @@ static struct comedi_driver apci2032_driver = { .offset = sizeof(struct addi_board), }; -static int __devinit apci2032_pci_probe(struct pci_dev *dev, +static int apci2032_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci2032_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index 9271cfe1b23..b931e17e3f5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -39,7 +39,7 @@ static struct comedi_driver apci2200_driver = { .offset = sizeof(struct addi_board), }; -static int __devinit apci2200_pci_probe(struct pci_dev *dev, +static int apci2200_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci2200_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 77a9fe933f0..86e34c406e8 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -60,7 +60,7 @@ static const void *apci3120_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit apci3120_auto_attach(struct comedi_device *dev, +static int apci3120_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -245,7 +245,7 @@ static struct comedi_driver apci3120_driver = { .detach = apci3120_detach, }; -static int __devinit apci3120_pci_probe(struct pci_dev *dev, +static int apci3120_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci3120_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index 59120cf88db..bce297308a5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -100,7 +100,7 @@ static struct comedi_driver apci3200_driver = { .offset = sizeof(struct addi_board), }; -static int __devinit apci3200_pci_probe(struct pci_dev *dev, +static int apci3200_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci3200_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index 530d352e4b6..cff8ff16b0b 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -51,7 +51,7 @@ static struct comedi_driver apci3501_driver = { .offset = sizeof(struct addi_board), }; -static int __devinit apci3501_pci_probe(struct pci_dev *dev, +static int apci3501_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci3501_driver); diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index 4a3e346c359..c4fa11df47c 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -745,7 +745,7 @@ static struct comedi_driver apci3xxx_driver = { .offset = sizeof(struct addi_board), }; -static int __devinit apci3xxx_pci_probe(struct pci_dev *dev, +static int apci3xxx_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &apci3xxx_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index 67d7ba1e36b..d7ba5e32202 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -174,7 +174,7 @@ static const void *pci6208_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit pci6208_auto_attach(struct comedi_device *dev, +static int pci6208_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -264,7 +264,7 @@ static struct comedi_driver adl_pci6208_driver = { .detach = pci6208_detach, }; -static int __devinit adl_pci6208_pci_probe(struct pci_dev *dev, +static int adl_pci6208_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adl_pci6208_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index 9ac356b6201..e94f0db1663 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -168,7 +168,7 @@ static const void *adl_pci7x3x_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit adl_pci7x3x_auto_attach(struct comedi_device *dev, +static int adl_pci7x3x_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -296,7 +296,7 @@ static struct comedi_driver adl_pci7x3x_driver = { .detach = adl_pci7x3x_detach, }; -static int __devinit adl_pci7x3x_pci_probe(struct pci_dev *dev, +static int adl_pci7x3x_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adl_pci7x3x_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index d5eb68b4f00..c8135fefe19 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -212,7 +212,7 @@ static int adl_pci8164_insn_write_buf1(struct comedi_device *dev, return 2; } -static int __devinit adl_pci8164_auto_attach(struct comedi_device *dev, +static int adl_pci8164_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -292,7 +292,7 @@ static struct comedi_driver adl_pci8164_driver = { .detach = adl_pci8164_detach, }; -static int __devinit adl_pci8164_pci_probe(struct pci_dev *dev, +static int adl_pci8164_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adl_pci8164_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 1fac2f71b2a..d084db8fe09 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -856,7 +856,7 @@ static int pci9111_reset(struct comedi_device *dev) return 0; } -static int __devinit pci9111_auto_attach(struct comedi_device *dev, +static int pci9111_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -957,7 +957,7 @@ static struct comedi_driver adl_pci9111_driver = { .detach = pci9111_detach, }; -static int __devinit pci9111_pci_probe(struct pci_dev *dev, +static int pci9111_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adl_pci9111_driver); diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index c7d0f33e143..c35b25d2978 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -2155,7 +2155,7 @@ static int pci9118_attach(struct comedi_device *dev, softsshdelay, hw_err_mask); } -static int __devinit pci9118_auto_attach(struct comedi_device *dev, +static int pci9118_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -2219,7 +2219,7 @@ static struct comedi_driver adl_pci9118_driver = { .offset = sizeof(struct boardtype), }; -static int __devinit adl_pci9118_pci_probe(struct pci_dev *dev, +static int adl_pci9118_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adl_pci9118_driver); diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 59c1d843a08..b67bb23f63c 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1233,7 +1233,7 @@ static const void *pci1710_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit pci1710_auto_attach(struct comedi_device *dev, +static int pci1710_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -1396,7 +1396,7 @@ static struct comedi_driver adv_pci1710_driver = { .detach = pci1710_detach, }; -static int __devinit adv_pci1710_pci_probe(struct pci_dev *dev, +static int adv_pci1710_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adv_pci1710_driver); diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 70e017bfa06..03afdd647f4 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -232,7 +232,7 @@ static int pci1723_dio_insn_bits(struct comedi_device *dev, return insn->n; } -static int __devinit pci1723_auto_attach(struct comedi_device *dev, +static int pci1723_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -321,7 +321,7 @@ static struct comedi_driver adv_pci1723_driver = { .detach = pci1723_detach, }; -static int __devinit adv_pci1723_pci_probe(struct pci_dev *dev, +static int adv_pci1723_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adv_pci1723_driver); diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 9e75006c9e7..2ab42c91ad2 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1090,7 +1090,7 @@ static const void *pci_dio_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit pci_dio_auto_attach(struct comedi_device *dev, +static int pci_dio_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -1200,7 +1200,7 @@ static struct comedi_driver adv_pci_dio_driver = { .detach = pci_dio_detach, }; -static int __devinit adv_pci_dio_pci_probe(struct pci_dev *dev, +static int adv_pci_dio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &adv_pci_dio_driver); diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 909acf89f4f..4fd28e3dd80 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -1925,7 +1925,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) * comedi_pci_auto_config(). dev->board_ptr is NULL on entry. * There should be a board entry matching the supplied PCI device. */ -static int __devinit dio200_auto_attach(struct comedi_device *dev, +static int dio200_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pci_dev = comedi_to_pci_dev(dev); @@ -2072,7 +2072,7 @@ static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { MODULE_DEVICE_TABLE(pci, dio200_pci_table); -static int __devinit amplc_dio200_pci_probe(struct pci_dev *dev, +static int amplc_dio200_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 09e096c6b6b..156dd6f0d7e 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -526,7 +526,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it) * comedi_pci_auto_config(). dev->board_ptr is NULL on entry. * There should be a board entry matching the supplied PCI device. */ -static int __devinit pc236_auto_attach(struct comedi_device *dev, +static int pc236_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pci_dev = comedi_to_pci_dev(dev); @@ -608,7 +608,7 @@ static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = { MODULE_DEVICE_TABLE(pci, pc236_pci_table); -static int __devinit amplc_pc236_pci_probe(struct pci_dev *dev, +static int amplc_pc236_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &lc_pc236_driver); diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index c041716efb0..ec60e81f712 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -296,7 +296,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it) * comedi_pci_auto_config(). dev->board_ptr is NULL on entry. * There should be a board entry matching the supplied PCI device. */ -static int __devinit pc263_auto_attach(struct comedi_device *dev, +static int pc263_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pci_dev; @@ -365,7 +365,7 @@ static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = { }; MODULE_DEVICE_TABLE(pci, pc263_pci_table); -static int __devinit amplc_pc263_pci_probe(struct pci_dev *dev, +static int amplc_pc263_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 1713a666075..b1b56bab828 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1438,7 +1438,7 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) return pci224_attach_common(dev, pci_dev, it->options); } -static int __devinit +static int pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pci_dev = comedi_to_pci_dev(dev); @@ -1505,7 +1505,7 @@ static struct comedi_driver amplc_pci224_driver = { .num_names = ARRAY_SIZE(pci224_boards), }; -static int __devinit amplc_pci224_pci_probe(struct pci_dev *dev, +static int amplc_pci224_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index d0ea0699252..c16a45a83bb 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2801,7 +2801,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) return pci230_attach_common(dev, pci_dev); } -static int __devinit pci230_auto_attach(struct comedi_device *dev, +static int pci230_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pci_dev = comedi_to_pci_dev(dev); @@ -2857,7 +2857,7 @@ static struct comedi_driver amplc_pci230_driver = { .num_names = ARRAY_SIZE(pci230_boards), }; -static int __devinit amplc_pci230_pci_probe(struct pci_dev *dev, +static int amplc_pci230_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &lc_pci230_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 857a8d63c9f..87201c4a90e 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1436,7 +1436,7 @@ static const void *cb_pcidas_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit cb_pcidas_auto_attach(struct comedi_device *dev, +static int cb_pcidas_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -1626,7 +1626,7 @@ static struct comedi_driver cb_pcidas_driver = { .detach = cb_pcidas_detach, }; -static int __devinit cb_pcidas_pci_probe(struct pci_dev *dev, +static int cb_pcidas_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &cb_pcidas_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index ea2e1e78066..14019b3dbaf 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -4043,7 +4043,7 @@ static const struct pcidas64_board return NULL; } -static int __devinit auto_attach(struct comedi_device *dev, +static int auto_attach(struct comedi_device *dev, unsigned long context_unused) { const struct pcidas64_board *thisboard; @@ -4214,7 +4214,7 @@ static struct comedi_driver cb_pcidas64_driver = { .detach = detach, }; -static int __devinit cb_pcidas64_pci_probe(struct pci_dev *dev, +static int cb_pcidas64_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &cb_pcidas64_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index f1a603b0023..07e98d2da16 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -349,7 +349,7 @@ static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit cb_pcidda_auto_attach(struct comedi_device *dev, +static int cb_pcidda_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -432,7 +432,7 @@ static struct comedi_driver cb_pcidda_driver = { .detach = cb_pcidda_detach, }; -static int __devinit cb_pcidda_pci_probe(struct pci_dev *dev, +static int cb_pcidda_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &cb_pcidda_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index f171cf9ffd1..01404939b4e 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -205,7 +205,7 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, return i; } -static int __devinit cb_pcimdas_auto_attach(struct comedi_device *dev, +static int cb_pcimdas_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -293,7 +293,7 @@ static struct comedi_driver cb_pcimdas_driver = { .detach = cb_pcimdas_detach, }; -static int __devinit cb_pcimdas_pci_probe(struct pci_dev *dev, +static int cb_pcimdas_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &cb_pcimdas_driver); diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 78e2ba3f1f2..12eda8e8acf 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -151,7 +151,7 @@ static int cb_pcimdda_ao_rinsn(struct comedi_device *dev, return insn->n; } -static int __devinit cb_pcimdda_auto_attach(struct comedi_device *dev, +static int cb_pcimdda_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -216,7 +216,7 @@ static struct comedi_driver cb_pcimdda_driver = { .detach = cb_pcimdda_detach, }; -static int __devinit cb_pcimdda_pci_probe(struct pci_dev *dev, +static int cb_pcimdda_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &cb_pcimdda_driver); diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 3c0ca852d01..0e38f48257b 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -68,7 +68,7 @@ static int contec_di_insn_bits(struct comedi_device *dev, return insn->n; } -static int __devinit contec_auto_attach(struct comedi_device *dev, +static int contec_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -124,7 +124,7 @@ static struct comedi_driver contec_pci_dio_driver = { .detach = contec_detach, }; -static int __devinit contec_pci_dio_pci_probe(struct pci_dev *dev, +static int contec_pci_dio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &contec_pci_dio_driver); diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index c0fd3b15815..fcabfbe15cb 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -688,7 +688,7 @@ static const void *daqboard2000_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit daqboard2000_auto_attach(struct comedi_device *dev, +static int daqboard2000_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -793,7 +793,7 @@ static struct comedi_driver daqboard2000_driver = { .detach = daqboard2000_detach, }; -static int __devinit daqboard2000_pci_probe(struct pci_dev *dev, +static int daqboard2000_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &daqboard2000_driver); diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 88f78a0efb2..af595bef601 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -774,7 +774,7 @@ das08_find_pci_board(struct pci_dev *pdev) } /* only called in the PCI probe path, via comedi_pci_auto_config() */ -static int __devinit __maybe_unused +static int __maybe_unused das08_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pdev; @@ -885,7 +885,7 @@ static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = { MODULE_DEVICE_TABLE(pci, das08_pci_table); -static int __devinit das08_pci_probe(struct pci_dev *dev, +static int das08_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &das08_driver); diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index b61004b422a..80d01a0c7b1 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -728,7 +728,7 @@ static const void *dt3000_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit dt3000_auto_attach(struct comedi_device *dev, +static int dt3000_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -850,7 +850,7 @@ static struct comedi_driver dt3000_driver = { .detach = dt3000_detach, }; -static int __devinit dt3000_pci_probe(struct pci_dev *dev, +static int dt3000_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &dt3000_driver); diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index 8736ef97f3b..cb973196780 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -177,7 +177,7 @@ static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev, return insn->n; } -static int __devinit dyna_pci10xx_auto_attach(struct comedi_device *dev, +static int dyna_pci10xx_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -270,7 +270,7 @@ static struct comedi_driver dyna_pci10xx_driver = { .detach = dyna_pci10xx_detach, }; -static int __devinit dyna_pci10xx_pci_probe(struct pci_dev *dev, +static int dyna_pci10xx_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &dyna_pci10xx_driver); diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 98926469e69..25708bcefcf 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -474,7 +474,7 @@ static const struct hpdi_board *hpdi_find_board(struct pci_dev *pcidev) return NULL; } -static int __devinit hpdi_auto_attach(struct comedi_device *dev, +static int hpdi_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -940,7 +940,7 @@ static struct comedi_driver gsc_hpdi_driver = { .detach = hpdi_detach, }; -static int __devinit gsc_hpdi_pci_probe(struct pci_dev *dev, +static int gsc_hpdi_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &gsc_hpdi_driver); diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index ee9b4082588..99e77ce0429 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -494,7 +494,7 @@ static int icp_multi_reset(struct comedi_device *dev) return 0; } -static int __devinit icp_multi_auto_attach(struct comedi_device *dev, +static int icp_multi_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -617,7 +617,7 @@ static struct comedi_driver icp_multi_driver = { .detach = icp_multi_detach, }; -static int __devinit icp_multi_pci_probe(struct pci_dev *dev, +static int icp_multi_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &icp_multi_driver); diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index ad24b7310ea..815b7ef49b0 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -657,7 +657,7 @@ static void jr3_pci_poll_dev(unsigned long data) add_timer(&devpriv->timer); } -static int __devinit jr3_pci_auto_attach(struct comedi_device *dev, +static int jr3_pci_auto_attach(struct comedi_device *dev, unsigned long context_unused) { int result; @@ -838,7 +838,7 @@ static struct comedi_driver jr3_pci_driver = { .detach = jr3_pci_detach, }; -static int __devinit jr3_pci_pci_probe(struct pci_dev *dev, +static int jr3_pci_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &jr3_pci_driver); diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index 63c3a1af7e5..dcce7bb826d 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -87,7 +87,7 @@ static int cnt_rinsn(struct comedi_device *dev, return 1; } -static int __devinit cnt_auto_attach(struct comedi_device *dev, +static int cnt_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -146,7 +146,7 @@ static struct comedi_driver ke_counter_driver = { .detach = cnt_detach, }; -static int __devinit ke_counter_pci_probe(struct pci_dev *dev, +static int ke_counter_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ke_counter_driver); diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 07594c579b1..f1a561551c0 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1563,7 +1563,7 @@ static const void *me4000_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit me4000_auto_attach(struct comedi_device *dev, +static int me4000_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -1728,7 +1728,7 @@ static struct comedi_driver me4000_driver = { .detach = me4000_detach, }; -static int __devinit me4000_pci_probe(struct pci_dev *dev, +static int me4000_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &me4000_driver); diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index b6482dd2a82..8cbde12b0ec 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -500,7 +500,7 @@ static const void *me_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit me_auto_attach(struct comedi_device *dev, +static int me_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -613,7 +613,7 @@ static struct comedi_driver me_daq_driver = { .detach = me_detach, }; -static int __devinit me_daq_pci_probe(struct pci_dev *dev, +static int me_daq_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &me_daq_driver); diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index 7ecebb75fe5..c90a5ab4705 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -341,7 +341,7 @@ ni6527_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit ni6527_auto_attach(struct comedi_device *dev, +static int ni6527_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -446,7 +446,7 @@ static struct comedi_driver ni6527_driver = { .detach = ni6527_detach, }; -static int __devinit ni6527_pci_probe(struct pci_dev *dev, +static int ni6527_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ni6527_driver); diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index d2204c2cebe..ec733976cd3 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -611,7 +611,7 @@ ni_65xx_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit ni_65xx_auto_attach(struct comedi_device *dev, +static int ni_65xx_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -782,7 +782,7 @@ static struct comedi_driver ni_65xx_driver = { .detach = ni_65xx_detach, }; -static int __devinit ni_65xx_pci_probe(struct pci_dev *dev, +static int ni_65xx_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ni_65xx_driver); diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index aaf4fe771ee..58c9341fe2c 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1166,7 +1166,7 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev, return insn->n; } -static int __devinit ni_660x_auto_attach(struct comedi_device *dev, +static int ni_660x_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -1321,7 +1321,7 @@ static struct comedi_driver ni_660x_driver = { .detach = ni_660x_detach, }; -static int __devinit ni_660x_pci_probe(struct pci_dev *dev, +static int ni_660x_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ni_660x_driver); diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 5080eca0b9e..718f8fe172c 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -201,7 +201,7 @@ ni_670x_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit ni_670x_auto_attach(struct comedi_device *dev, +static int ni_670x_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -303,7 +303,7 @@ static struct comedi_driver ni_670x_driver = { .detach = ni_670x_detach, }; -static int __devinit ni_670x_pci_probe(struct pci_dev *dev, +static int ni_670x_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ni_670x_driver); diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index b2e565bf3df..96164254962 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -696,7 +696,7 @@ labpc_pci_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit labpc_auto_attach(struct comedi_device *dev, +static int labpc_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -2110,7 +2110,7 @@ static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = { }; MODULE_DEVICE_TABLE(pci, labpc_pci_table); -static int __devinit labpc_pci_probe(struct pci_dev *dev, +static int labpc_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &labpc_driver); diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index f4dd5df0d7e..c13e822604f 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1106,7 +1106,7 @@ nidio_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit nidio_auto_attach(struct comedi_device *dev, +static int nidio_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -1218,7 +1218,7 @@ static struct comedi_driver ni_pcidio_driver = { .detach = nidio_detach, }; -static int __devinit ni_pcidio_pci_probe(struct pci_dev *dev, +static int ni_pcidio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ni_pcidio_driver); diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 597a2d3c4a6..4497860a12e 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1620,7 +1620,7 @@ pcimio_find_boardinfo(struct pci_dev *pcidev) return NULL; } -static int __devinit pcimio_auto_attach(struct comedi_device *dev, +static int pcimio_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -1785,7 +1785,7 @@ static struct comedi_driver ni_pcimio_driver = { .detach = pcimio_detach, }; -static int __devinit ni_pcimio_pci_probe(struct pci_dev *dev, +static int ni_pcimio_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &ni_pcimio_driver); diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 83edc3e85e8..790eafe79e5 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1272,7 +1272,7 @@ static const void *rtd_find_boardinfo(struct comedi_device *dev, return NULL; } -static int __devinit rtd_auto_attach(struct comedi_device *dev, +static int rtd_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -1414,7 +1414,7 @@ static struct comedi_driver rtd520_driver = { .detach = rtd_detach, }; -static int __devinit rtd520_pci_probe(struct pci_dev *dev, +static int rtd520_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &rtd520_driver); diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 30686e2b8a7..18f3b18a8c5 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2657,7 +2657,7 @@ static void s626_initialize(struct comedi_device *dev) /* writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER); */ } -static int __devinit s626_auto_attach(struct comedi_device *dev, +static int s626_auto_attach(struct comedi_device *dev, unsigned long context_unused) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -2830,7 +2830,7 @@ static struct comedi_driver s626_driver = { .detach = s626_detach, }; -static int __devinit s626_pci_probe(struct pci_dev *dev, +static int s626_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &s626_driver); diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index 98c1868ab03..bbf673f419e 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -541,16 +541,12 @@ static int skel_attach(struct comedi_device *dev, struct comedi_devconfig *it) * comedi_usb_auto_config(), etc.) to handle devices that can be attached * to the Comedi core automatically without the COMEDI_DEVCONFIG ioctl. * - * For PCI devices, comedi_pci_auto_config() is usually called directly from - * the struct pci_driver probe() function, so this _auto_attach() function - * can be tagged __devinit. - * * The context parameter is usually unused, but if the driver called * comedi_auto_config() directly instead of the comedi_pci_auto_config() * wrapper function, this will be a copy of the context passed to * comedi_auto_config(). */ -static int __devinit skel_auto_attach(struct comedi_device *dev, +static int skel_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); @@ -705,7 +701,7 @@ static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = { }; MODULE_DEVICE_TABLE(pci, skel_pci_table); -static int __devinit skel_pci_probe(struct pci_dev *dev, +static int skel_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { return comedi_pci_auto_config(dev, &skel_driver); -- cgit v1.2.3 From 53b800198592b0ff96577ecc5f116f7d902a4362 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Mon, 19 Nov 2012 13:26:36 -0500 Subject: staging: comedi: remove use of __devexit CONFIG_HOTPLUG is going away as an option so __devexit is no longer needed. Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255_pci.c | 2 +- drivers/staging/comedi/drivers/addi_apci_035.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1500.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1516.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1564.c | 2 +- drivers/staging/comedi/drivers/addi_apci_16xx.c | 2 +- drivers/staging/comedi/drivers/addi_apci_1710.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2032.c | 2 +- drivers/staging/comedi/drivers/addi_apci_2200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3120.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3200.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3501.c | 2 +- drivers/staging/comedi/drivers/addi_apci_3xxx.c | 2 +- drivers/staging/comedi/drivers/adl_pci6208.c | 2 +- drivers/staging/comedi/drivers/adl_pci7x3x.c | 2 +- drivers/staging/comedi/drivers/adl_pci8164.c | 2 +- drivers/staging/comedi/drivers/adl_pci9111.c | 2 +- drivers/staging/comedi/drivers/adl_pci9118.c | 2 +- drivers/staging/comedi/drivers/adv_pci1710.c | 2 +- drivers/staging/comedi/drivers/adv_pci1723.c | 2 +- drivers/staging/comedi/drivers/adv_pci_dio.c | 2 +- drivers/staging/comedi/drivers/amplc_dio200.c | 2 +- drivers/staging/comedi/drivers/amplc_pc236.c | 2 +- drivers/staging/comedi/drivers/amplc_pc263.c | 2 +- drivers/staging/comedi/drivers/amplc_pci224.c | 2 +- drivers/staging/comedi/drivers/amplc_pci230.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas.c | 2 +- drivers/staging/comedi/drivers/cb_pcidas64.c | 2 +- drivers/staging/comedi/drivers/cb_pcidda.c | 2 +- drivers/staging/comedi/drivers/cb_pcimdas.c | 2 +- drivers/staging/comedi/drivers/cb_pcimdda.c | 2 +- drivers/staging/comedi/drivers/contec_pci_dio.c | 2 +- drivers/staging/comedi/drivers/daqboard2000.c | 2 +- drivers/staging/comedi/drivers/das08.c | 2 +- drivers/staging/comedi/drivers/dt3000.c | 2 +- drivers/staging/comedi/drivers/dyna_pci10xx.c | 2 +- drivers/staging/comedi/drivers/gsc_hpdi.c | 2 +- drivers/staging/comedi/drivers/icp_multi.c | 2 +- drivers/staging/comedi/drivers/jr3_pci.c | 2 +- drivers/staging/comedi/drivers/ke_counter.c | 2 +- drivers/staging/comedi/drivers/me4000.c | 2 +- drivers/staging/comedi/drivers/me_daq.c | 2 +- drivers/staging/comedi/drivers/ni_6527.c | 2 +- drivers/staging/comedi/drivers/ni_65xx.c | 2 +- drivers/staging/comedi/drivers/ni_660x.c | 2 +- drivers/staging/comedi/drivers/ni_670x.c | 2 +- drivers/staging/comedi/drivers/ni_labpc.c | 2 +- drivers/staging/comedi/drivers/ni_pcidio.c | 2 +- drivers/staging/comedi/drivers/ni_pcimio.c | 2 +- drivers/staging/comedi/drivers/rtd520.c | 2 +- drivers/staging/comedi/drivers/s626.c | 2 +- drivers/staging/comedi/drivers/skel.c | 2 +- 53 files changed, 53 insertions(+), 53 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 448f18d7560..e0a79521f35 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -314,7 +314,7 @@ static int pci_8255_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &pci_8255_driver); } -static void __devexit pci_8255_pci_remove(struct pci_dev *dev) +static void pci_8255_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c index 8e5e5faae4f..c981d4b1cc7 100644 --- a/drivers/staging/comedi/drivers/addi_apci_035.c +++ b/drivers/staging/comedi/drivers/addi_apci_035.c @@ -53,7 +53,7 @@ static int apci035_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci035_driver); } -static void __devexit apci035_pci_remove(struct pci_dev *dev) +static void apci035_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c index 15b660bc1a2..7f9424205a6 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1032.c +++ b/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -375,7 +375,7 @@ static int apci1032_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1032_driver); } -static void __devexit apci1032_pci_remove(struct pci_dev *dev) +static void apci1032_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c index 80115ccb6c7..8e686a9b811 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1500.c +++ b/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -53,7 +53,7 @@ static int apci1500_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1500_driver); } -static void __devexit apci1500_pci_remove(struct pci_dev *dev) +static void apci1500_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c index ac32e9fa98e..8fef04b4d19 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1516.c +++ b/drivers/staging/comedi/drivers/addi_apci_1516.c @@ -323,7 +323,7 @@ static int apci1516_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1516_driver); } -static void __devexit apci1516_pci_remove(struct pci_dev *dev) +static void apci1516_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index d03579a1659..513e536f292 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -50,7 +50,7 @@ static int apci1564_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1564_driver); } -static void __devexit apci1564_pci_remove(struct pci_dev *dev) +static void apci1564_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c index 05457875308..ab9a96ac818 100644 --- a/drivers/staging/comedi/drivers/addi_apci_16xx.c +++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c @@ -52,7 +52,7 @@ static int apci16xx_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci16xx_driver); } -static void __devexit apci16xx_pci_remove(struct pci_dev *dev) +static void apci16xx_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c index 1c9ed4785d0..152e7ef9b17 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1710.c +++ b/drivers/staging/comedi/drivers/addi_apci_1710.c @@ -128,7 +128,7 @@ static int apci1710_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci1710_driver); } -static void __devexit apci1710_pci_remove(struct pci_dev *dev) +static void apci1710_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c index f60720546e3..459e90013ea 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2032.c +++ b/drivers/staging/comedi/drivers/addi_apci_2032.c @@ -47,7 +47,7 @@ static int apci2032_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci2032_driver); } -static void __devexit apci2032_pci_remove(struct pci_dev *dev) +static void apci2032_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c index b931e17e3f5..7c2c5db0121 100644 --- a/drivers/staging/comedi/drivers/addi_apci_2200.c +++ b/drivers/staging/comedi/drivers/addi_apci_2200.c @@ -45,7 +45,7 @@ static int apci2200_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci2200_driver); } -static void __devexit apci2200_pci_remove(struct pci_dev *dev) +static void apci2200_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 86e34c406e8..fec2962affc 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -251,7 +251,7 @@ static int apci3120_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3120_driver); } -static void __devexit apci3120_pci_remove(struct pci_dev *dev) +static void apci3120_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c index bce297308a5..9085b774b48 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3200.c +++ b/drivers/staging/comedi/drivers/addi_apci_3200.c @@ -106,7 +106,7 @@ static int apci3200_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3200_driver); } -static void __devexit apci3200_pci_remove(struct pci_dev *dev) +static void apci3200_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c index cff8ff16b0b..ed297deb863 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3501.c +++ b/drivers/staging/comedi/drivers/addi_apci_3501.c @@ -57,7 +57,7 @@ static int apci3501_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3501_driver); } -static void __devexit apci3501_pci_remove(struct pci_dev *dev) +static void apci3501_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c index c4fa11df47c..1562347ed64 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c +++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c @@ -751,7 +751,7 @@ static int apci3xxx_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &apci3xxx_driver); } -static void __devexit apci3xxx_pci_remove(struct pci_dev *dev) +static void apci3xxx_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c index d7ba5e32202..9a56eed3910 100644 --- a/drivers/staging/comedi/drivers/adl_pci6208.c +++ b/drivers/staging/comedi/drivers/adl_pci6208.c @@ -270,7 +270,7 @@ static int adl_pci6208_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &adl_pci6208_driver); } -static void __devexit adl_pci6208_pci_remove(struct pci_dev *dev) +static void adl_pci6208_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c b/drivers/staging/comedi/drivers/adl_pci7x3x.c index e94f0db1663..772edc02f5c 100644 --- a/drivers/staging/comedi/drivers/adl_pci7x3x.c +++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c @@ -302,7 +302,7 @@ static int adl_pci7x3x_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &adl_pci7x3x_driver); } -static void __devexit adl_pci7x3x_pci_remove(struct pci_dev *dev) +static void adl_pci7x3x_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c index c8135fefe19..4dd9d707a79 100644 --- a/drivers/staging/comedi/drivers/adl_pci8164.c +++ b/drivers/staging/comedi/drivers/adl_pci8164.c @@ -298,7 +298,7 @@ static int adl_pci8164_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &adl_pci8164_driver); } -static void __devexit adl_pci8164_pci_remove(struct pci_dev *dev) +static void adl_pci8164_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index d084db8fe09..a339b9dd27c 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -963,7 +963,7 @@ static int pci9111_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &adl_pci9111_driver); } -static void __devexit pci9111_pci_remove(struct pci_dev *dev) +static void pci9111_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index c35b25d2978..b6dda809bd1 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -2225,7 +2225,7 @@ static int adl_pci9118_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &adl_pci9118_driver); } -static void __devexit adl_pci9118_pci_remove(struct pci_dev *dev) +static void adl_pci9118_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index b67bb23f63c..a6fd8c2c16c 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c @@ -1402,7 +1402,7 @@ static int adv_pci1710_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &adv_pci1710_driver); } -static void __devexit adv_pci1710_pci_remove(struct pci_dev *dev) +static void adv_pci1710_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index 03afdd647f4..5af73146dd8 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c @@ -327,7 +327,7 @@ static int adv_pci1723_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &adv_pci1723_driver); } -static void __devexit adv_pci1723_pci_remove(struct pci_dev *dev) +static void adv_pci1723_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 2ab42c91ad2..05a663e970c 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1206,7 +1206,7 @@ static int adv_pci_dio_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &adv_pci_dio_driver); } -static void __devexit adv_pci_dio_pci_remove(struct pci_dev *dev) +static void adv_pci_dio_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 4fd28e3dd80..5f309ba88a1 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -2079,7 +2079,7 @@ static int amplc_dio200_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &lc_dio200_driver); } -static void __devexit amplc_dio200_pci_remove(struct pci_dev *dev) +static void amplc_dio200_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index 156dd6f0d7e..28983541957 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c @@ -614,7 +614,7 @@ static int amplc_pc236_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &lc_pc236_driver); } -static void __devexit amplc_pc236_pci_remove(struct pci_dev *dev) +static void amplc_pc236_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index ec60e81f712..dfbff77cd79 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c @@ -372,7 +372,7 @@ static int amplc_pc263_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &lc_pc263_driver); } -static void __devexit amplc_pc263_pci_remove(struct pci_dev *dev) +static void amplc_pc263_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index b1b56bab828..6e2566a2dd5 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1512,7 +1512,7 @@ static int amplc_pci224_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &lc_pci224_driver); } -static void __devexit amplc_pci224_pci_remove(struct pci_dev *dev) +static void amplc_pci224_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index c16a45a83bb..366c68be56b 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2863,7 +2863,7 @@ static int amplc_pci230_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &lc_pci230_driver); } -static void __devexit amplc_pci230_pci_remove(struct pci_dev *dev) +static void amplc_pci230_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 87201c4a90e..aed68639cc9 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1632,7 +1632,7 @@ static int cb_pcidas_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &cb_pcidas_driver); } -static void __devexit cb_pcidas_pci_remove(struct pci_dev *dev) +static void cb_pcidas_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 14019b3dbaf..d72b46cc06b 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -4220,7 +4220,7 @@ static int cb_pcidas64_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &cb_pcidas64_driver); } -static void __devexit cb_pcidas64_pci_remove(struct pci_dev *dev) +static void cb_pcidas64_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 07e98d2da16..7c6029a8c3e 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -438,7 +438,7 @@ static int cb_pcidda_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &cb_pcidda_driver); } -static void __devexit cb_pcidda_pci_remove(struct pci_dev *dev) +static void cb_pcidda_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index 01404939b4e..b43a5f80ac2 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -299,7 +299,7 @@ static int cb_pcimdas_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &cb_pcimdas_driver); } -static void __devexit cb_pcimdas_pci_remove(struct pci_dev *dev) +static void cb_pcimdas_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 12eda8e8acf..699b84f54cc 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -222,7 +222,7 @@ static int cb_pcimdda_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &cb_pcimdda_driver); } -static void __devexit cb_pcimdda_pci_remove(struct pci_dev *dev) +static void cb_pcimdda_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c index 0e38f48257b..1a18fa37bfd 100644 --- a/drivers/staging/comedi/drivers/contec_pci_dio.c +++ b/drivers/staging/comedi/drivers/contec_pci_dio.c @@ -130,7 +130,7 @@ static int contec_pci_dio_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &contec_pci_dio_driver); } -static void __devexit contec_pci_dio_pci_remove(struct pci_dev *dev) +static void contec_pci_dio_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index fcabfbe15cb..992e557e6ae 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -799,7 +799,7 @@ static int daqboard2000_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &daqboard2000_driver); } -static void __devexit daqboard2000_pci_remove(struct pci_dev *dev) +static void daqboard2000_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index af595bef601..b15e05808cb 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -891,7 +891,7 @@ static int das08_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &das08_driver); } -static void __devexit das08_pci_remove(struct pci_dev *dev) +static void das08_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index 80d01a0c7b1..960da8debe1 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c @@ -856,7 +856,7 @@ static int dt3000_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &dt3000_driver); } -static void __devexit dt3000_pci_remove(struct pci_dev *dev) +static void dt3000_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c b/drivers/staging/comedi/drivers/dyna_pci10xx.c index cb973196780..8497a36db7d 100644 --- a/drivers/staging/comedi/drivers/dyna_pci10xx.c +++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c @@ -276,7 +276,7 @@ static int dyna_pci10xx_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &dyna_pci10xx_driver); } -static void __devexit dyna_pci10xx_pci_remove(struct pci_dev *dev) +static void dyna_pci10xx_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c index 25708bcefcf..154598f6d5e 100644 --- a/drivers/staging/comedi/drivers/gsc_hpdi.c +++ b/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -946,7 +946,7 @@ static int gsc_hpdi_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &gsc_hpdi_driver); } -static void __devexit gsc_hpdi_pci_remove(struct pci_dev *dev) +static void gsc_hpdi_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c index 99e77ce0429..a91a448ba0f 100644 --- a/drivers/staging/comedi/drivers/icp_multi.c +++ b/drivers/staging/comedi/drivers/icp_multi.c @@ -623,7 +623,7 @@ static int icp_multi_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &icp_multi_driver); } -static void __devexit icp_multi_pci_remove(struct pci_dev *dev) +static void icp_multi_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 815b7ef49b0..c756a35ce31 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -844,7 +844,7 @@ static int jr3_pci_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &jr3_pci_driver); } -static void __devexit jr3_pci_pci_remove(struct pci_dev *dev) +static void jr3_pci_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c index dcce7bb826d..19c94282ac3 100644 --- a/drivers/staging/comedi/drivers/ke_counter.c +++ b/drivers/staging/comedi/drivers/ke_counter.c @@ -152,7 +152,7 @@ static int ke_counter_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ke_counter_driver); } -static void __devexit ke_counter_pci_remove(struct pci_dev *dev) +static void ke_counter_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index f1a561551c0..3c4b0228e8d 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -1734,7 +1734,7 @@ static int me4000_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &me4000_driver); } -static void __devexit me4000_pci_remove(struct pci_dev *dev) +static void me4000_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c index 8cbde12b0ec..ce8e3d3f135 100644 --- a/drivers/staging/comedi/drivers/me_daq.c +++ b/drivers/staging/comedi/drivers/me_daq.c @@ -619,7 +619,7 @@ static int me_daq_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &me_daq_driver); } -static void __devexit me_daq_pci_remove(struct pci_dev *dev) +static void me_daq_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c index c90a5ab4705..5196b460ce1 100644 --- a/drivers/staging/comedi/drivers/ni_6527.c +++ b/drivers/staging/comedi/drivers/ni_6527.c @@ -452,7 +452,7 @@ static int ni6527_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni6527_driver); } -static void __devexit ni6527_pci_remove(struct pci_dev *dev) +static void ni6527_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index ec733976cd3..8ef80fd6175 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -788,7 +788,7 @@ static int ni_65xx_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_65xx_driver); } -static void __devexit ni_65xx_pci_remove(struct pci_dev *dev) +static void ni_65xx_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c index 58c9341fe2c..26baf9c96ff 100644 --- a/drivers/staging/comedi/drivers/ni_660x.c +++ b/drivers/staging/comedi/drivers/ni_660x.c @@ -1327,7 +1327,7 @@ static int ni_660x_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_660x_driver); } -static void __devexit ni_660x_pci_remove(struct pci_dev *dev) +static void ni_660x_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c index 718f8fe172c..272caeb6ece 100644 --- a/drivers/staging/comedi/drivers/ni_670x.c +++ b/drivers/staging/comedi/drivers/ni_670x.c @@ -309,7 +309,7 @@ static int ni_670x_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_670x_driver); } -static void __devexit ni_670x_pci_remove(struct pci_dev *dev) +static void ni_670x_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 96164254962..d29c4d761ba 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -2116,7 +2116,7 @@ static int labpc_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &labpc_driver); } -static void __devexit labpc_pci_remove(struct pci_dev *dev) +static void labpc_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index c13e822604f..084ebea33ab 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -1224,7 +1224,7 @@ static int ni_pcidio_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_pcidio_driver); } -static void __devexit ni_pcidio_pci_remove(struct pci_dev *dev) +static void ni_pcidio_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c index 4497860a12e..aaac0b2cc9e 100644 --- a/drivers/staging/comedi/drivers/ni_pcimio.c +++ b/drivers/staging/comedi/drivers/ni_pcimio.c @@ -1791,7 +1791,7 @@ static int ni_pcimio_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &ni_pcimio_driver); } -static void __devexit ni_pcimio_pci_remove(struct pci_dev *dev) +static void ni_pcimio_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 790eafe79e5..8d7c948a919 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -1420,7 +1420,7 @@ static int rtd520_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &rtd520_driver); } -static void __devexit rtd520_pci_remove(struct pci_dev *dev) +static void rtd520_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 18f3b18a8c5..6dc1d281286 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -2836,7 +2836,7 @@ static int s626_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &s626_driver); } -static void __devexit s626_pci_remove(struct pci_dev *dev) +static void s626_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c index bbf673f419e..e2d79700a61 100644 --- a/drivers/staging/comedi/drivers/skel.c +++ b/drivers/staging/comedi/drivers/skel.c @@ -707,7 +707,7 @@ static int skel_pci_probe(struct pci_dev *dev, return comedi_pci_auto_config(dev, &skel_driver); } -static void __devexit skel_pci_remove(struct pci_dev *dev) +static void skel_pci_remove(struct pci_dev *dev) { comedi_pci_auto_unconfig(dev); } -- cgit v1.2.3 From 30aeee29f6dd1716c383636a98c87ffa886f2e1d Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 20 Nov 2012 14:07:16 +0530 Subject: staging: drm/imx: Remove duplicate inclusion of linux/videodev2.h linux/videodev2.h was included twice. Signed-off-by: Sachin Kamat Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap2/board-overo.c | 1 - drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c index b700685762b..56277a04713 100644 --- a/arch/arm/mach-omap2/board-overo.c +++ b/arch/arm/mach-omap2/board-overo.c @@ -45,7 +45,6 @@ #include #include -#include "common.h" #include